diff --git a/.mailmap b/.mailmap index e1cf6bb85d33..40b4db2b2d60 100644 --- a/.mailmap +++ b/.mailmap @@ -210,10 +210,16 @@ Daniel Borkmann Daniel Borkmann Daniel Borkmann Daniel Borkmann +Daniel Lezcano +Daniel Lezcano +Daniel Lezcano +Daniel Lezcano Daniel Thompson +Daniele Alessandrelli Danilo Krummrich David Brownell David Collins +David Gow David Heidelberg David Hildenbrand David Rheinsberg @@ -321,6 +327,7 @@ Henrik Rydberg Herbert Xu Huacai Chen Huacai Chen +Ignat Korchagin Ike Panhc J. Bruce Fields J. Bruce Fields @@ -348,6 +355,7 @@ Jarkko Sakkinen Jason Gunthorpe Jason Gunthorpe Jason Gunthorpe +Jason Xing Javi Merino Jayachandran C @@ -396,6 +404,7 @@ Jiri Slaby Jisheng Zhang Jisheng Zhang Jishnu Prakash +Joe Damato Joel Granados Johan Hovold Johan Hovold @@ -490,7 +499,8 @@ Lior David Loic Poulain Loic Poulain Lorenzo Pieralisi -Lorenzo Stoakes +Lorenzo Stoakes +Lorenzo Stoakes Luca Ceresoli Luca Weiss Lucas De Marchi @@ -876,6 +886,7 @@ Vivien Didelot Vlad Dogaru Vladimir Davydov Vladimir Davydov +Vlastimil Babka WangYuli WangYuli Weiwen Hu @@ -890,7 +901,8 @@ Yanteng Si Ying Huang Yixun Lan Yixun Lan -Yosry Ahmed +Yosry Ahmed +Yosry Ahmed Yu-Chun Lin Yusuke Goda Zack Rusin diff --git a/CREDITS b/CREDITS index f7e480057630..9091bac3d2da 100644 --- a/CREDITS +++ b/CREDITS @@ -1242,6 +1242,10 @@ N: Veaceslav Falico E: vfalico@gmail.com D: Co-maintainer and co-author of the network bonding driver. +N: Thomas Falcon +E: tlfalcon@linux.ibm.com +D: Initial author of the IBM ibmvnic network driver + N: János Farkas E: chexum@shadow.banki.hu D: romfs, various (mostly networking) fixes @@ -2415,6 +2419,10 @@ S: Am Muehlenweg 38 S: D53424 Remagen S: Germany +N: Jonathan Lemon +E: jonathan.lemon@gmail.com +D: OpenCompute PTP clock driver (ptp_ocp) + N: Colin Leroy E: colin@colino.net W: http://www.geekounet.org/ @@ -3492,7 +3500,8 @@ S: Brazil N: Stephen Rothwell E: sfr@canb.auug.org.au W: http://www.canb.auug.org.au/~sfr -P: 1024/BD8C7805 CD A4 9D 01 10 6E 7E 3B 91 88 FA D9 C8 40 AA 02 +P: 4096R/5AD24211C060D1C8 D41C A3ED 5B30 275C F5A0 1B05 5AD2 4211 C060 D1C8 +D: Created linux-next and maintained it 2008-2026 D: Boot/setup/build work for setup > 2K D: Author, APM driver D: Directory notification diff --git a/Documentation/ABI/stable/sysfs-driver-dma-idxd b/Documentation/ABI/stable/sysfs-driver-dma-idxd index 4a355e6747ae..08d030159f09 100644 --- a/Documentation/ABI/stable/sysfs-driver-dma-idxd +++ b/Documentation/ABI/stable/sysfs-driver-dma-idxd @@ -136,6 +136,21 @@ Description: The last executed device administrative command's status/error. Also last configuration error overloaded. Writing to it will clear the status. +What: /sys/bus/dsa/devices/dsa/dsacaps +Date: April 5, 2026 +KernelVersion: 6.20.0 +Contact: dmaengine@vger.kernel.org +Description: The DSA3 specification introduces three new capability + registers: dsacap[0-2]. User components (e.g., configuration + libraries and workload applications) require this information + to properly utilize the DSA3 features. + This includes SGL capability support, Enabling hardware-specific + optimizations, Configuring memory, etc. + The output format is ',,' where each + DSA cap value is a 64 bit hex value. + This attribute should only be visible on DSA devices of version + 3 or later. + What: /sys/bus/dsa/devices/dsa/iaa_cap Date: Sept 14, 2022 KernelVersion: 6.0.0 diff --git a/Documentation/ABI/stable/sysfs-driver-speakup b/Documentation/ABI/stable/sysfs-driver-speakup index bcb6831aa114..8b508b4a7a00 100644 --- a/Documentation/ABI/stable/sysfs-driver-speakup +++ b/Documentation/ABI/stable/sysfs-driver-speakup @@ -23,8 +23,7 @@ What: /sys/accessibility/speakup/bleep_time KernelVersion: 2.6 Contact: speakup@linux-speakup.org Description: This controls the duration of the PC speaker beeps speakup - produces. - TODO: What are the units? Jiffies? + produces, in milliseconds. What: /sys/accessibility/speakup/cursor_time KernelVersion: 2.6 diff --git a/Documentation/ABI/testing/configfs-tsm-report b/Documentation/ABI/testing/configfs-tsm-report index 534408bc1408..7a6a5045a7d5 100644 --- a/Documentation/ABI/testing/configfs-tsm-report +++ b/Documentation/ABI/testing/configfs-tsm-report @@ -17,6 +17,12 @@ Description: where the implementation is conveyed via the @provider attribute. + This interface fails reads and sets errno to EFBIG when the + report generated by @provider exceeds the configfs-tsm-report + internal maximums. Contact the platform provider for the + compatible security module, driver, and attestation library + combination. + What: /sys/kernel/config/tsm/report/$name/auxblob Date: October, 2023 KernelVersion: v6.7 @@ -31,6 +37,9 @@ Description: Standardization v2.03 Section 4.1.8.1 MSG_REPORT_REQ. https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/specifications/56421.pdf + See "EFBIG" comment in the @outblob description for potential + error conditions. + What: /sys/kernel/config/tsm/report/$name/manifestblob Date: January, 2024 KernelVersion: v6.10 @@ -43,6 +52,9 @@ Description: See 'service_provider' for information on the format of the manifest blob. + See "EFBIG" comment in the @outblob description for potential + error conditions. + What: /sys/kernel/config/tsm/report/$name/provider Date: September, 2023 KernelVersion: v6.7 @@ -61,6 +73,10 @@ Description: Library Revision 0.8 Appendix 4,5 https://download.01.org/intel-sgx/latest/dcap-latest/linux/docs/Intel_TDX_DCAP_Quoting_Library_API.pdf + Intel TDX platforms with DICE-based attestation use CBOR Web Token + (CWT) format for the Quote payload. This is indicated by the Quote + size exceeding 8KB. + What: /sys/kernel/config/tsm/report/$name/generation Date: September, 2023 KernelVersion: v6.7 diff --git a/Documentation/ABI/testing/configfs-usb-gadget-midi b/Documentation/ABI/testing/configfs-usb-gadget-midi index 07389cddd51a..d6bd67bb91fc 100644 --- a/Documentation/ABI/testing/configfs-usb-gadget-midi +++ b/Documentation/ABI/testing/configfs-usb-gadget-midi @@ -4,11 +4,12 @@ KernelVersion: 3.19 Description: The attributes: - ========== ==================================== - index index value for the USB MIDI adapter - id ID string for the USB MIDI adapter - buflen MIDI buffer length - qlen USB read request queue length - in_ports number of MIDI input ports - out_ports number of MIDI output ports - ========== ==================================== + ================ ==================================== + index index value for the USB MIDI adapter + id ID string for the USB MIDI adapter + buflen MIDI buffer length + qlen USB read request queue length + in_ports number of MIDI input ports + out_ports number of MIDI output ports + interface_string USB AudioControl interface string + ================ ==================================== diff --git a/Documentation/ABI/testing/sysfs-block-zram b/Documentation/ABI/testing/sysfs-block-zram index e538d4850d61..64c03010e951 100644 --- a/Documentation/ABI/testing/sysfs-block-zram +++ b/Documentation/ABI/testing/sysfs-block-zram @@ -151,11 +151,11 @@ Description: The algorithm_params file is write-only and is used to setup compression algorithm parameters. -What: /sys/block/zram/writeback_compressed +What: /sys/block/zram/compressed_writeback Date: Decemeber 2025 Contact: Richard Chang Description: - The writeback_compressed device atrribute toggles compressed + The compressed_writeback device atrribute toggles compressed writeback feature. What: /sys/block/zram/writeback_batch_size diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source b/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source index 321e3ee1fc9d..c8c58914116e 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source @@ -1,7 +1,7 @@ What: /sys/bus/coresight/devices/dummy_source/enable_source Date: Dec 2024 KernelVersion: 6.14 -Contact: Mao Jinlong +Contact: Mao Jinlong Description: (RW) Enable/disable tracing of dummy source. A sink should be activated before enabling the source. The path of coresight components linking the source to the sink is configured and managed automatically by the @@ -10,7 +10,7 @@ Description: (RW) Enable/disable tracing of dummy source. A sink should be activ What: /sys/bus/coresight/devices/dummy_source/traceid Date: Dec 2024 KernelVersion: 6.14 -Contact: Mao Jinlong +Contact: Mao Jinlong Description: (R) Show the trace ID that will appear in the trace stream coming from this trace entity. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda new file mode 100644 index 000000000000..650431feae45 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda @@ -0,0 +1,69 @@ +What: /sys/bus/coresight/devices//trig_async_enable +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger synchronization sequence interface. + +What: /sys/bus/coresight/devices//trig_flag_ts_enable +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger FLAG packet request interface. + +What: /sys/bus/coresight/devices//trig_freq_enable +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable cross trigger FREQ packet request interface. + +What: /sys/bus/coresight/devices//freq_ts_enable +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Enable/disable the timestamp for all FREQ packets. + +What: /sys/bus/coresight/devices//cmbchan_mode +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Configure the CMB/MCMB channel mode for all enabled ports. + Value 0 means raw channel mapping mode. Value 1 means channel pair marking mode. + +What: /sys/bus/coresight/devices//global_flush_req +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Set global (all ports) flush request bit. The bit remains set until a + global flush request sequence completes. + +What: /sys/bus/coresight/devices//syncr_mode +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Set mode the of the syncr counter. + mode 0 - COUNT[11:0] value represents the approximate number of bytes moved between two ASYNC packet requests + mode 1 - the bits COUNT[11:7] are used as a power of 2. for example, we could insert an async packet every 8K + data by writing a value 13 to the COUNT[11:7] field. + +What: /sys/bus/coresight/devices//syncr_count +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Set value the of the syncr counter. + Range: 0-4095 + +What: /sys/bus/coresight/devices//port_flush_req +Date: December 2025 +KernelVersion: 6.20 +Contact: Jinlong Mao , Tao Zhang , Jie Gan +Description: + (RW) Configure the bit i to requests a flush operation of port i on the TPDA. + The requested bit(s) remain set until the flush request completes. diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm index 98f1c6545027..f8016df64532 100644 --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm @@ -1,7 +1,7 @@ What: /sys/bus/coresight/devices//integration_test Date: January 2023 KernelVersion: 6.2 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Run integration test for tpdm. Integration test will generate test data for tpdm. It can help to make @@ -15,7 +15,7 @@ Description: What: /sys/bus/coresight/devices//reset_dataset Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Reset the dataset of the tpdm. @@ -25,7 +25,7 @@ Description: What: /sys/bus/coresight/devices//dsb_trig_type Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the trigger type of the DSB for tpdm. @@ -36,7 +36,7 @@ Description: What: /sys/bus/coresight/devices//dsb_trig_ts Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the trigger timestamp of the DSB for tpdm. @@ -47,7 +47,7 @@ Description: What: /sys/bus/coresight/devices//dsb_mode Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the programming mode of the DSB for tpdm. @@ -61,7 +61,7 @@ Description: What: /sys/bus/coresight/devices//dsb_edge/ctrl_idx Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the index number of the edge detection for the DSB subunit TPDM. Since there are at most 256 edge detections, this @@ -70,7 +70,7 @@ Description: What: /sys/bus/coresight/devices//dsb_edge/ctrl_val Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: Write a data to control the edge detection corresponding to the index number. Before writing data to this sysfs file, @@ -86,7 +86,7 @@ Description: What: /sys/bus/coresight/devices//dsb_edge/ctrl_mask Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: Write a data to mask the edge detection corresponding to the index number. Before writing data to this sysfs file, "ctrl_idx" should @@ -98,21 +98,21 @@ Description: What: /sys/bus/coresight/devices//dsb_edge/edcr[0:15] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: Read a set of the edge control value of the DSB in TPDM. What: /sys/bus/coresight/devices//dsb_edge/edcmr[0:7] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: Read a set of the edge control mask of the DSB in TPDM. What: /sys/bus/coresight/devices//dsb_trig_patt/xpr[0:7] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the value of the trigger pattern for the DSB subunit TPDM. @@ -120,7 +120,7 @@ Description: What: /sys/bus/coresight/devices//dsb_trig_patt/xpmr[0:7] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the mask of the trigger pattern for the DSB subunit TPDM. @@ -128,21 +128,21 @@ Description: What: /sys/bus/coresight/devices//dsb_patt/tpr[0:7] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the value of the pattern for the DSB subunit TPDM. What: /sys/bus/coresight/devices//dsb_patt/tpmr[0:7] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the mask of the pattern for the DSB subunit TPDM. What: /sys/bus/coresight/devices//dsb_patt/enable_ts Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Set the pattern timestamp of DSB tpdm. Read the pattern timestamp of DSB tpdm. @@ -154,7 +154,7 @@ Description: What: /sys/bus/coresight/devices//dsb_patt/set_type Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Set the pattern type of DSB tpdm. Read the pattern type of DSB tpdm. @@ -166,7 +166,7 @@ Description: What: /sys/bus/coresight/devices//dsb_msr/msr[0:31] Date: March 2023 KernelVersion: 6.7 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the MSR(mux select register) for the DSB subunit TPDM. @@ -174,7 +174,7 @@ Description: What: /sys/bus/coresight/devices//cmb_mode Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Set the data collection mode of CMB tpdm. Continuous change creates CMB data set elements on every CMBCLK edge. Trace-on-change creates CMB data set elements only when a new @@ -188,7 +188,7 @@ Description: (Write) Set the data collection mode of CMB tpdm. Continuous What: /sys/bus/coresight/devices//cmb_trig_patt/xpr[0:1] Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the value of the trigger pattern for the CMB subunit TPDM. @@ -196,7 +196,7 @@ Description: What: /sys/bus/coresight/devices//cmb_trig_patt/xpmr[0:1] Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the mask of the trigger pattern for the CMB subunit TPDM. @@ -204,21 +204,21 @@ Description: What: /sys/bus/coresight/devices//dsb_patt/tpr[0:1] Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the value of the pattern for the CMB subunit TPDM. What: /sys/bus/coresight/devices//dsb_patt/tpmr[0:1] Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the mask of the pattern for the CMB subunit TPDM. What: /sys/bus/coresight/devices//cmb_patt/enable_ts Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (Write) Set the pattern timestamp of CMB tpdm. Read the pattern timestamp of CMB tpdm. @@ -230,7 +230,7 @@ Description: What: /sys/bus/coresight/devices//cmb_trig_ts Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the trigger timestamp of the CMB for tpdm. @@ -241,7 +241,7 @@ Description: What: /sys/bus/coresight/devices//cmb_ts_all Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Read or write the status of timestamp upon all interface. Only value 0 and 1 can be written to this node. Set this node to 1 to request @@ -253,7 +253,7 @@ Description: What: /sys/bus/coresight/devices//cmb_msr/msr[0:31] Date: January 2024 KernelVersion: 6.9 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the MSR(mux select register) for the CMB subunit TPDM. @@ -261,7 +261,7 @@ Description: What: /sys/bus/coresight/devices//mcmb_trig_lane Date: Feb 2025 KernelVersion 6.15 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get which lane participates in the output pattern match cross trigger mechanism for the MCMB subunit TPDM. @@ -269,7 +269,7 @@ Description: What: /sys/bus/coresight/devices//mcmb_lanes_select Date: Feb 2025 KernelVersion 6.15 -Contact: Jinlong Mao (QUIC) , Tao Zhang (QUIC) +Contact: Jinlong Mao , Tao Zhang Description: (RW) Set/Get the enablement of the individual lane. diff --git a/Documentation/ABI/testing/sysfs-bus-iio-cros-ec b/Documentation/ABI/testing/sysfs-bus-iio-cros-ec index 9e3926243797..3de1dfc98389 100644 --- a/Documentation/ABI/testing/sysfs-bus-iio-cros-ec +++ b/Documentation/ABI/testing/sysfs-bus-iio-cros-ec @@ -3,9 +3,12 @@ Date: July 2015 KernelVersion: 4.7 Contact: linux-iio@vger.kernel.org Description: - Writing '1' will perform a FOC (Fast Online Calibration). The - corresponding calibration offsets can be read from `*_calibbias` - entries. + Writing '1' either perform a FOC (Fast Online Calibration) or + enter calibration mode. + Writing '0` exits calibration mode. It is a NOP for FOC enabled + sensors. + The corresponding calibration offsets can be read from `*_calibbias` + entries. What: /sys/bus/iio/devices/iio:deviceX/id Date: September 2017 diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd index fc82aa4e54b0..d10e6de3adb2 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd +++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd @@ -85,3 +85,45 @@ Description: up to 5000. The default value is 64 ms. This polling interval is used while DbC is enabled but has no active data transfers. + +What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_serial +Date: January 2026 +Contact: Łukasz Bartosik +Description: + The dbc_serial attribute allows to change the serial number + string descriptor presented by the debug device when a host + requests a string descriptor with iSerialNumber index. + Index is found in the iSerialNumber field in the device + descriptor. + Value can only be changed while debug capability (DbC) is in + disabled state to prevent USB device descriptor change while + connected to a USB host. + The default value is "0001". + The field length can be from 1 to 126 characters. + +What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_product +Date: January 2026 +Contact: Łukasz Bartosik +Description: + The dbc_product attribute allows to change the product string + descriptor presented by the debug device when a host requests + a string descriptor with iProduct index. + Index is found in the iProduct field in the device descriptor. + Value can only be changed while debug capability (DbC) is in + disabled state to prevent USB device descriptor change while + connected to a USB host. + The default value is "Linux USB Debug Target". + The field length can be from 1 to 126 characters. + +What: /sys/bus/pci/drivers/xhci_hcd/.../dbc_manufacturer +Date: January 2026 +Contact: Łukasz Bartosik +Description: + The dbc_manufacturer attribute allows to change the manufacturer + string descriptor presented by the debug device when a host + requests a string descriptor with iManufacturer index. + Value can only be changed while debug capability (DbC) is in + disabled state to prevent USB device descriptor change while + connected to a USB host. + The default value is "Linux Foundation". + The field length can be from 1 to 126 characters. diff --git a/Documentation/ABI/testing/sysfs-class-spi-eeprom b/Documentation/ABI/testing/sysfs-class-spi-eeprom index 1ff757982079..f4bc7d9454cf 100644 --- a/Documentation/ABI/testing/sysfs-class-spi-eeprom +++ b/Documentation/ABI/testing/sysfs-class-spi-eeprom @@ -17,3 +17,14 @@ Description: from the device. This is a read-only attribute. + +What: /sys/class/spi_master/spi/spi./jedec_id +Date: January 2026 +KernelVersion: 6.19 +Contact: Patrick Wicki +Description: + Contains the raw JEDEC ID bytes returned by the RDID (0x9f) command. The + bytes are exposed as a hex string in big-endian order as read from the + device. + + This is a read-only attribute. diff --git a/Documentation/ABI/testing/sysfs-class-typec b/Documentation/ABI/testing/sysfs-class-typec index 38e101c17a00..737b76828b50 100644 --- a/Documentation/ABI/testing/sysfs-class-typec +++ b/Documentation/ABI/testing/sysfs-class-typec @@ -162,6 +162,17 @@ Description: Lists the supported USB Modes. The default USB mode that is used - usb3 (USB 3.2) - usb4 (USB4) +What: /sys/class/typec///priority +Date: July 2025 +Contact: Andrei Kuchynski +Description: + Displays and allows setting the priority for a specific alternate mode. + The priority is an integer in the range 0-255. A lower numerical value + indicates a higher priority (0 is the highest). + If the new value is already in use by another mode, the priority of the + conflicting mode and any subsequent modes will be incremented until they + are all unique. + USB Type-C partner devices (eg. /sys/class/typec/port0-partner/) What: /sys/class/typec/-partner/accessory_mode diff --git a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop index eaeb659793d2..2df70792968f 100644 --- a/Documentation/ABI/testing/sysfs-driver-uniwill-laptop +++ b/Documentation/ABI/testing/sysfs-driver-uniwill-laptop @@ -1,4 +1,4 @@ -What: /sys/bus/platform/devices/INOU0000:XX/fn_lock_toggle_enable +What: /sys/bus/platform/devices/INOU0000:XX/fn_lock Date: November 2025 KernelVersion: 6.19 Contact: Armin Wolf @@ -8,15 +8,15 @@ Description: Reading this file returns the current enable status of the FN lock functionality. -What: /sys/bus/platform/devices/INOU0000:XX/super_key_toggle_enable +What: /sys/bus/platform/devices/INOU0000:XX/super_key_enable Date: November 2025 KernelVersion: 6.19 Contact: Armin Wolf Description: - Allows userspace applications to enable/disable the super key functionality - of the integrated keyboard by writing "1"/"0" into this file. + Allows userspace applications to enable/disable the super key of the integrated + keyboard by writing "1"/"0" into this file. - Reading this file returns the current enable status of the super key functionality. + Reading this file returns the current enable status of the super key. What: /sys/bus/platform/devices/INOU0000:XX/touchpad_toggle_enable Date: November 2025 diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 770470e0598b..c1d2b3fd9c65 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -520,7 +520,7 @@ What: /sys/fs/f2fs//ckpt_thread_ioprio Date: January 2021 Contact: "Daeho Jeong" Description: Give a way to change checkpoint merge daemon's io priority. - Its default value is "be,3", which means "BE" I/O class and + Its default value is "rt,3", which means "RT" I/O class and I/O priority "3". We can select the class between "rt" and "be", and set the I/O priority within valid range of it. "," delimiter is necessary in between I/O class and priority number. @@ -732,7 +732,7 @@ Description: Support configuring fault injection type, should be FAULT_TRUNCATE 0x00000400 FAULT_READ_IO 0x00000800 FAULT_CHECKPOINT 0x00001000 - FAULT_DISCARD 0x00002000 + FAULT_DISCARD 0x00002000 (obsolete) FAULT_WRITE_IO 0x00004000 FAULT_SLAB_ALLOC 0x00008000 FAULT_DQUOT_INIT 0x00010000 @@ -741,8 +741,10 @@ Description: Support configuring fault injection type, should be FAULT_BLKADDR_CONSISTENCE 0x00080000 FAULT_NO_SEGMENT 0x00100000 FAULT_INCONSISTENT_FOOTER 0x00200000 - FAULT_TIMEOUT 0x00400000 (1000ms) + FAULT_ATOMIC_TIMEOUT 0x00400000 (1000ms) FAULT_VMALLOC 0x00800000 + FAULT_LOCK_TIMEOUT 0x01000000 (1000ms) + FAULT_SKIP_WRITE 0x02000000 =========================== ========== What: /sys/fs/f2fs//discard_io_aware_gran @@ -939,3 +941,57 @@ Description: Controls write priority in multi-devices setups. A value of 0 means allocate_section_policy = 1 Prioritize writing to section before allocate_section_hint allocate_section_policy = 2 Prioritize writing to section after allocate_section_hint =========================== ========================================================== + +What: /sys/fs/f2fs//max_lock_elapsed_time +Date: December 2025 +Contact: "Chao Yu" +Description: This is a threshold, once a thread enters critical region that lock covers, total + elapsed time exceeds this threshold, f2fs will print tracepoint to dump information + of related context. This sysfs entry can be used to control the value of threshold, + by default, the value is 500 ms. + +What: /sys/fs/f2fs//inject_timeout_type +Date: December 2025 +Contact: "Chao Yu" +Description: This sysfs entry can be used to change type of injected timeout: + ========== =============================== + Flag_Value Flag_Description + ========== =============================== + 0x00000000 No timeout (default) + 0x00000001 Simulate running time + 0x00000002 Simulate IO type sleep time + 0x00000003 Simulate Non-IO type sleep time + 0x00000004 Simulate runnable time + ========== =============================== + +What: /sys/fs/f2fs//adjust_lock_priority +Date: January 2026 +Contact: "Chao Yu" +Description: This sysfs entry can be used to enable/disable to adjust priority for task + which is in critical region covered by lock. + ========== ================== + Flag_Value Flag_Description + ========== ================== + 0x00000000 Disabled (default) + 0x00000001 cp_rwsem + 0x00000002 node_change + 0x00000004 node_write + 0x00000008 gc_lock + 0x00000010 cp_global + 0x00000020 io_rwsem + ========== ================== + +What: /sys/fs/f2fs//lock_duration_priority +Date: January 2026 +Contact: "Chao Yu" +Description: f2fs can tune priority of thread which has entered into critical region covered by + f2fs rwsemphore lock. This sysfs entry can be used to control priority value, the + range is [100,139], by default the value is 120. + +What: /sys/fs/f2fs//critical_task_priority +Date: February 2026 +Contact: "Chao Yu" +Description: It can be used to tune priority of f2fs critical task, e.g. f2fs_ckpt, f2fs_gc + threads, limitation as below: + - it requires user has CAP_SYS_NICE capability. + - the range is [100, 139], by default the value is 100. diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentation/admin-guide/blockdev/zram.rst index 94bb7f2245ee..451fa00d3004 100644 --- a/Documentation/admin-guide/blockdev/zram.rst +++ b/Documentation/admin-guide/blockdev/zram.rst @@ -216,7 +216,7 @@ writeback_limit WO specifies the maximum amount of write IO zram writeback_limit_enable RW show and set writeback_limit feature writeback_batch_size RW show and set maximum number of in-flight writeback operations -writeback_compressed RW show and set compressed writeback feature +compressed_writeback RW show and set compressed writeback feature comp_algorithm RW show and change the compression algorithm algorithm_params WO setup compression algorithm parameters compact WO trigger memory compaction @@ -439,11 +439,11 @@ budget in next setting is user's job. By default zram stores written back pages in decompressed (raw) form, which means that writeback operation involves decompression of the page before writing it to the backing device. This behavior can be changed by enabling -`writeback_compressed` feature, which causes zram to write compressed pages +`compressed_writeback` feature, which causes zram to write compressed pages to the backing device, thus avoiding decompression overhead. To enable this feature, execute:: - $ echo yes > /sys/block/zramX/writeback_compressed + $ echo yes > /sys/block/zramX/compressed_writeback Note that this feature should be configured before the `zramX` device is initialized. diff --git a/Documentation/admin-guide/bootconfig.rst b/Documentation/admin-guide/bootconfig.rst index 7a86042c9b6d..f712758472d5 100644 --- a/Documentation/admin-guide/bootconfig.rst +++ b/Documentation/admin-guide/bootconfig.rst @@ -20,18 +20,26 @@ Config File Syntax The boot config syntax is a simple structured key-value. Each key consists of dot-connected-words, and key and value are connected by ``=``. The value -has to be terminated by semi-colon (``;``) or newline (``\n``). -For array value, array entries are separated by comma (``,``). :: - - KEY[.WORD[...]] = VALUE[, VALUE2[...]][;] - -Unlike the kernel command line syntax, spaces are OK around the comma and ``=``. +string has to be terminated by the following delimiters described below. Each key word must contain only alphabets, numbers, dash (``-``) or underscore (``_``). And each value only contains printable characters or spaces except for delimiters such as semi-colon (``;``), new-line (``\n``), comma (``,``), hash (``#``) and closing brace (``}``). +If the ``=`` is followed by whitespace up to one of these delimiters, the +key is assigned an empty value. + +For arrays, the array values are comma (``,``) separated, and comments and +line breaks with newline (``\n``) are allowed between array values for +readability. Thus the first entry of the array must be on the same line as +the key.:: + + KEY[.WORD[...]] = VALUE[, VALUE2[...]][;] + +Unlike the kernel command line syntax, white spaces (including tabs) are +ignored around the comma and ``=``. + If you want to use those delimiters in a value, you can use either double- quotes (``"VALUE"``) or single-quotes (``'VALUE'``) to quote it. Note that you can not escape these quotes. @@ -138,8 +146,8 @@ This is parsed as below:: foo = value bar = 1, 2, 3 -Note that you can not put a comment between value and delimiter(``,`` or -``;``). This means following config has a syntax error :: +Note that you can NOT put a comment or a newline between value and delimiter +(``,`` or ``;``). This means following config has a syntax error :: key = 1 # comment ,2 diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt index c480f230aa4a..440633642fea 100644 --- a/Documentation/admin-guide/devices.txt +++ b/Documentation/admin-guide/devices.txt @@ -352,7 +352,7 @@ 216 = /dev/fujitsu/apanel Fujitsu/Siemens application panel 217 = /dev/ni/natmotn National Instruments Motion 218 = /dev/kchuid Inter-process chuid control - 219 = /dev/modems/mwave MWave modem firmware upload + 219 = 220 = /dev/mptctl Message passing technology (MPT) control 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver 222 = /dev/mvista/hasi Montavista PICMG high availability diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index c6b9b2e74321..03a550630644 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -74,6 +74,7 @@ TPM TPM drivers are enabled. UMS USB Mass Storage support is enabled. USB USB support is enabled. + NVME NVMe support is enabled USBHID USB Human Interface Device support is enabled. V4L Video For Linux support is enabled. VGA The VGA console has been enabled. @@ -4661,7 +4662,7 @@ Kernel parameters nosmt [KNL,MIPS,PPC,EARLY] Disable symmetric multithreading (SMT). Equivalent to smt=1. - [KNL,X86,PPC,S390] Disable symmetric multithreading (SMT). + [KNL,LOONGARCH,X86,PPC,S390] Disable symmetric multithreading (SMT). nosmt=force: Force disable SMT, cannot be undone via the sysfs control file. @@ -4787,6 +4788,18 @@ Kernel parameters This can be set from sysctl after boot. See Documentation/admin-guide/sysctl/vm.rst for details. + nvme.quirks= [NVME] A list of quirk entries to augment the built-in + nvme quirk list. List entries are separated by a + '-' character. + Each entry has the form VendorID:ProductID:quirk_names. + The IDs are 4-digits hex numbers and quirk_names is a + list of quirk names separated by commas. A quirk name + can be prefixed by '^', meaning that the specified + quirk must be disabled. + + Example: + nvme.quirks=7710:2267:bogus_nid,^identify_cns-9900:7711:broken_msi + ohci1394_dma=early [HW,EARLY] enable debugging via the ohci1394 driver. See Documentation/core-api/debugging-via-ohci1394.rst for more info. @@ -8183,6 +8196,9 @@ Kernel parameters p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT (Reduce timeout of the SET_ADDRESS request from 5000 ms to 500 ms); + q = USB_QUIRK_FORCE_ONE_CONFIG (Device + claims zero configurations, + forcing to 1); Example: quirks=0781:5580:bk,0a5c:5834:gij usbhid.mousepoll= diff --git a/Documentation/admin-guide/laptops/toshiba_haps.rst b/Documentation/admin-guide/laptops/toshiba_haps.rst index d28b6c3f2849..0226225b82e1 100644 --- a/Documentation/admin-guide/laptops/toshiba_haps.rst +++ b/Documentation/admin-guide/laptops/toshiba_haps.rst @@ -43,7 +43,7 @@ RSSS Shuts down the HDD protection interface for a few seconds, ==== ===================================================================== Note: - The presence of Solid State Drives (SSD) can make this driver to fail loading, + The presence of Solid State Drives (SSD) can cause this driver to fail loading, given the fact that such drives have no movable parts, and thus, not requiring any "protection" as well as failing during the evaluation of the _STA method found under this device. diff --git a/Documentation/admin-guide/laptops/uniwill-laptop.rst b/Documentation/admin-guide/laptops/uniwill-laptop.rst index a16baf15516b..aff5f57a6bd4 100644 --- a/Documentation/admin-guide/laptops/uniwill-laptop.rst +++ b/Documentation/admin-guide/laptops/uniwill-laptop.rst @@ -24,7 +24,7 @@ Keyboard settings The ``uniwill-laptop`` driver allows the user to enable/disable: - - the FN and super key lock functionality of the integrated keyboard + - the FN lock and super key of the integrated keyboard - the touchpad toggle functionality of the integrated touchpad See Documentation/ABI/testing/sysfs-driver-uniwill-laptop for details. diff --git a/Documentation/admin-guide/pm/intel_idle.rst b/Documentation/admin-guide/pm/intel_idle.rst index ed6f055d4b14..188d52cd26e8 100644 --- a/Documentation/admin-guide/pm/intel_idle.rst +++ b/Documentation/admin-guide/pm/intel_idle.rst @@ -260,6 +260,17 @@ mode to off when the CPU is in any one of the available idle states. This may help performance of a sibling CPU at the expense of a slightly higher wakeup latency for the idle CPU. +The ``table`` argument allows customization of idle state latency and target +residency. The syntax is a comma-separated list of ``name:latency:residency`` +entries, where ``name`` is the idle state name, ``latency`` is the exit latency +in microseconds, and ``residency`` is the target residency in microseconds. It +is not necessary to specify all idle states; only those to be customized. For +example, ``C1:1:3,C6:50:100`` sets the exit latency and target residency for +C1 and C6 to 1/3 and 50/100 microseconds, respectively. Remaining idle states +keep their default values. The driver verifies that deeper idle states have +higher latency and target residency than shallower ones. Also, target +residency cannot be smaller than exit latency. If any of these conditions is +not met, the driver ignores the entire ``table`` parameter. .. _intel-idle-core-and-package-idle-states: diff --git a/Documentation/admin-guide/sysctl/net.rst b/Documentation/admin-guide/sysctl/net.rst index 19408da2390b..3b2ad61995d4 100644 --- a/Documentation/admin-guide/sysctl/net.rst +++ b/Documentation/admin-guide/sysctl/net.rst @@ -40,8 +40,8 @@ Table : Subdirectories in /proc/sys/net bridge Bridging rose X.25 PLP layer core General parameter tipc TIPC ethernet Ethernet protocol unix Unix domain sockets - ipv4 IP version 4 x25 X.25 protocol - ipv6 IP version 6 + ipv4 IP version 4 vsock VSOCK sockets + ipv6 IP version 6 x25 X.25 protocol ========= =================== = ========== =================== 1. /proc/sys/net/core - Network core options @@ -551,3 +551,54 @@ originally may have been issued in the correct sequential order. If named_timeout is nonzero, failed topology updates will be placed on a defer queue until another event arrives that clears the error, or until the timeout expires. Value is in milliseconds. + +6. /proc/sys/net/vsock - VSOCK sockets +-------------------------------------- + +VSOCK sockets (AF_VSOCK) provide communication between virtual machines and +their hosts. The behavior of VSOCK sockets in a network namespace is determined +by the namespace's mode (``global`` or ``local``), which controls how CIDs +(Context IDs) are allocated and how sockets interact across namespaces. + +ns_mode +------- + +Read-only. Reports the current namespace's mode, set at namespace creation +and immutable thereafter. + +Values: + + - ``global`` - the namespace shares system-wide CID allocation and + its sockets can reach any VM or socket in any global namespace. + Sockets in this namespace cannot reach sockets in local + namespaces. + - ``local`` - the namespace has private CID allocation and its + sockets can only connect to VMs or sockets within the same + namespace. + +The init_net mode is always ``global``. + +child_ns_mode +------------- + +Controls what mode newly created child namespaces will inherit. At namespace +creation, ``ns_mode`` is inherited from the parent's ``child_ns_mode``. The +initial value matches the namespace's own ``ns_mode``. + +Values: + + - ``global`` - child namespaces will share system-wide CID allocation + and their sockets will be able to reach any VM or socket in any + global namespace. + - ``local`` - child namespaces will have private CID allocation and + their sockets will only be able to connect within their own + namespace. + +The first write to ``child_ns_mode`` locks its value. Subsequent writes of the +same value succeed, but writing a different value returns ``-EBUSY``. + +Changing ``child_ns_mode`` only affects namespaces created after the change; +it does not modify the current namespace or any existing children. + +A namespace with ``ns_mode`` set to ``local`` cannot change +``child_ns_mode`` to ``global`` (returns ``-EPERM``). diff --git a/Documentation/admin-guide/thunderbolt.rst b/Documentation/admin-guide/thunderbolt.rst index 07303c1346fb..89df26553aa0 100644 --- a/Documentation/admin-guide/thunderbolt.rst +++ b/Documentation/admin-guide/thunderbolt.rst @@ -370,7 +370,7 @@ is built-in to the kernel image, there is no need to do anything. The driver will create one virtual ethernet interface per Thunderbolt port which are named like ``thunderbolt0`` and so on. From this point -you can either use standard userspace tools like ``ifconfig`` to +you can either use standard userspace tools like ``ip`` to configure the interface or let your GUI handle it automatically. Forcing power diff --git a/Documentation/core-api/rbtree.rst b/Documentation/core-api/rbtree.rst index ed1a9fbc779e..cce80e19087b 100644 --- a/Documentation/core-api/rbtree.rst +++ b/Documentation/core-api/rbtree.rst @@ -197,7 +197,7 @@ Cached rbtrees -------------- Computing the leftmost (smallest) node is quite a common task for binary -search trees, such as for traversals or users relying on a the particular +search trees, such as for traversals or users relying on the particular order for their own logic. To this end, users can use 'struct rb_root_cached' to optimize O(logN) rb_first() calls to a simple pointer fetch avoiding potentially expensive tree iterations. This is done at negligible runtime @@ -255,7 +255,7 @@ affected subtrees. When erasing a node, the user must call rb_erase_augmented() instead of rb_erase(). rb_erase_augmented() calls back into user provided functions -to updated the augmented information on affected subtrees. +to update the augmented information on affected subtrees. In both cases, the callbacks are provided through struct rb_augment_callbacks. 3 callbacks must be defined: @@ -293,7 +293,7 @@ way making it possible to do efficient lookup and exact match. This "extra information" stored in each node is the maximum hi (max_hi) value among all the nodes that are its descendants. This -information can be maintained at each node just be looking at the node +information can be maintained at each node just by looking at the node and its immediate children. And this will be used in O(log n) lookup for lowest match (lowest start address among all possible matches) with something like:: diff --git a/Documentation/dev-tools/coccinelle.rst b/Documentation/dev-tools/coccinelle.rst index 6e70a1e9a3c0..c714780d458a 100644 --- a/Documentation/dev-tools/coccinelle.rst +++ b/Documentation/dev-tools/coccinelle.rst @@ -127,6 +127,18 @@ To enable verbose messages set the V= variable, for example:: make coccicheck MODE=report V=1 +By default, coccicheck will print debug logs to stdout and redirect stderr to +/dev/null. This can make coccicheck output difficult to read and understand. +Debug and error messages can instead be written to a debug file instead by +setting the ``DEBUG_FILE`` variable:: + + make coccicheck MODE=report DEBUG_FILE="cocci.log" + +Coccinelle cannot overwrite a debug file. Instead of repeatedly deleting a log +file, you could include the datetime in the debug file name:: + + make coccicheck MODE=report DEBUG_FILE="cocci-$(date -Iseconds).log" + Coccinelle parallelization -------------------------- @@ -208,11 +220,10 @@ include options matching the options used when we compile the kernel. You can learn what these options are by using V=1; you could then manually run Coccinelle with debug options added. -Alternatively you can debug running Coccinelle against SmPL patches -by asking for stderr to be redirected to stderr. By default stderr -is redirected to /dev/null; if you'd like to capture stderr you -can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For -instance:: +An easier approach to debug running Coccinelle against SmPL patches is to ask +coccicheck to redirect stderr to a debug file. As mentioned in the examples, by +default stderr is redirected to /dev/null; if you'd like to capture stderr you +can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For instance:: rm -f cocci.err make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml index ed091dc0c10a..206681ccaa4c 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-sink.yaml @@ -31,7 +31,7 @@ maintainers: - Mike Leach - Suzuki K Poulose - James Clark - - Mao Jinlong + - Mao Jinlong - Hao Zhang properties: diff --git a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml index 78337be42b55..0b1e12ae95c3 100644 --- a/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml +++ b/Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml @@ -30,7 +30,7 @@ maintainers: - Mike Leach - Suzuki K Poulose - James Clark - - Mao Jinlong + - Mao Jinlong - Hao Zhang properties: diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index c969c16c21ef..e002f87361ad 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -7,9 +7,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: CoreSight TMC Control Unit maintainers: - - Yuanfang Zhang - - Mao Jinlong - - Jie Gan + - Yuanfang Zhang + - Mao Jinlong + - Jie Gan description: | The Trace Memory Controller(TMC) is used for Embedded Trace Buffer(ETB), @@ -26,8 +26,13 @@ description: | properties: compatible: - enum: - - qcom,sa8775p-ctcu + oneOf: + - items: + - enum: + - qcom,qcs8300-ctcu + - const: qcom,sa8775p-ctcu + - enum: + - qcom,sa8775p-ctcu reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml new file mode 100644 index 000000000000..8936bb7c3e8e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/qcom,coresight-itnoc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Interconnect Trace Network On Chip - ITNOC + +maintainers: + - Yuanfang Zhang + +description: + The Interconnect TNOC is a CoreSight graph link that forwards trace data + from a subsystem to the Aggregator TNOC. Compared to Aggregator TNOC, it + does not have aggregation and ATID functionality. + +properties: + $nodename: + pattern: "^itnoc(@[0-9a-f]+)?$" + + compatible: + const: qcom,coresight-itnoc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: apb + + in-ports: + $ref: /schemas/graph.yaml#/properties/ports + + patternProperties: + '^port(@[0-9a-f]{1,2})?$': + description: Input connections from CoreSight Trace Bus + $ref: /schemas/graph.yaml#/properties/port + + out-ports: + $ref: /schemas/graph.yaml#/properties/ports + additionalProperties: false + + properties: + port: + description: out connections to aggregator TNOC + $ref: /schemas/graph.yaml#/properties/port + +required: + - compatible + - reg + - clocks + - clock-names + - in-ports + - out-ports + +additionalProperties: false + +examples: + - | + itnoc@109ac000 { + compatible = "qcom,coresight-itnoc"; + reg = <0x109ac000 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tn_ic_in_tpdm_dcc: endpoint { + remote-endpoint = <&tpdm_dcc_out_tn_ic>; + }; + }; + }; + + out-ports { + port { + tn_ic_out_tnoc_aggr: endpoint { + /* to Aggregator TNOC input */ + remote-endpoint = <&tn_ag_in_tn_ic>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml index ffe613efeabe..e3a32f30551c 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-remote-etm.yaml @@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Coresight Remote ETM(Embedded Trace Macrocell) maintainers: - - Jinlong Mao - - Tao Zhang + - Jinlong Mao + - Tao Zhang description: Support for ETM trace collection on remote processor using coresight diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tnoc.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tnoc.yaml index 9d1c93a9ade3..ef648a15b806 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tnoc.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tnoc.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Qualcomm Trace Network On Chip - TNOC maintainers: - - Yuanfang Zhang + - Yuanfang Zhang description: > The Trace Network On Chip (TNOC) is an integration hierarchy hardware diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml index a48c9ac3eaa9..70d297b054c3 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpda.yaml @@ -33,8 +33,8 @@ description: | to sink. maintainers: - - Mao Jinlong - - Tao Zhang + - Mao Jinlong + - Tao Zhang # Need a custom select here or 'arm,primecell' will match on lots of nodes select: diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml index c349306f0d52..152403f548c3 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml @@ -19,8 +19,8 @@ description: | sources and send it to a TPDA for packetization, timestamping, and funneling. maintainers: - - Mao Jinlong - - Tao Zhang + - Mao Jinlong + - Tao Zhang # Need a custom select here or 'arm,primecell' will match on lots of nodes select: diff --git a/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml new file mode 100644 index 000000000000..55bb73707d58 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,t7-peripherals-clkc.yaml @@ -0,0 +1,116 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,t7-peripherals-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic T7 Peripherals Clock Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Xianwei Zhao + - Jian Hu + +properties: + compatible: + const: amlogic,t7-peripherals-clkc + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + minItems: 14 + items: + - description: input oscillator + - description: input sys clk + - description: input fixed pll + - description: input fclk div 2 + - description: input fclk div 2p5 + - description: input fclk div 3 + - description: input fclk div 4 + - description: input fclk div 5 + - description: input fclk div 7 + - description: input hifi pll + - description: input gp0 pll + - description: input gp1 pll + - description: input mpll1 + - description: input mpll2 + - description: external input rmii oscillator (optional) + - description: input video pll0 (optional) + - description: external pad input for rtc (optional) + + clock-names: + minItems: 14 + items: + - const: xtal + - const: sys + - const: fix + - const: fdiv2 + - const: fdiv2p5 + - const: fdiv3 + - const: fdiv4 + - const: fdiv5 + - const: fdiv7 + - const: hifi + - const: gp0 + - const: gp1 + - const: mpll1 + - const: mpll2 + - const: ext_rmii + - const: vid_pll0 + - const: ext_rtc + +required: + - compatible + - '#clock-cells' + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clkc_periphs:clock-controller@0 { + compatible = "amlogic,t7-peripherals-clkc"; + reg = <0 0x0 0 0x1c8>; + #clock-cells = <1>; + clocks = <&xtal>, + <&scmi_clk 13>, + <&scmi_clk 16>, + <&scmi_clk 18>, + <&scmi_clk 20>, + <&scmi_clk 22>, + <&scmi_clk 24>, + <&scmi_clk 26>, + <&scmi_clk 28>, + <&hifi 1>, + <&gp0 1>, + <&gp1 1>, + <&mpll 4>, + <&mpll 6>; + clock-names = "xtal", + "sys", + "fix", + "fdiv2", + "fdiv2p5", + "fdiv3", + "fdiv4", + "fdiv5", + "fdiv7", + "hifi", + "gp0", + "gp1", + "mpll1", + "mpll2"; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml new file mode 100644 index 000000000000..49c61f65deff --- /dev/null +++ b/Documentation/devicetree/bindings/clock/amlogic,t7-pll-clkc.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/amlogic,t7-pll-clkc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic T7 PLL Clock Control Controller + +maintainers: + - Neil Armstrong + - Jerome Brunet + - Jian Hu + - Xianwei Zhao + +properties: + compatible: + enum: + - amlogic,t7-gp0-pll + - amlogic,t7-gp1-pll + - amlogic,t7-hifi-pll + - amlogic,t7-pcie-pll + - amlogic,t7-mpll + - amlogic,t7-hdmi-pll + - amlogic,t7-mclk-pll + + reg: + maxItems: 1 + + '#clock-cells': + const: 1 + + clocks: + items: + - description: mclk pll input oscillator gate + - description: oscillator input clock source for mclk_sel_0 + - description: fixed input clock source for mclk_sel_0 + minItems: 1 + + clock-names: + items: + - const: in0 + - const: in1 + - const: in2 + minItems: 1 + +required: + - compatible + - '#clock-cells' + - reg + - clocks + - clock-names + +allOf: + - if: + properties: + compatible: + contains: + const: amlogic,t7-mclk-pll + + then: + properties: + clocks: + minItems: 3 + + clock-names: + minItems: 3 + + - if: + properties: + compatible: + contains: + enum: + - amlogic,t7-gp0-pll + - amlogic,t7-gp1--pll + - amlogic,t7-hifi-pll + - amlogic,t7-pcie-pll + - amlogic,t7-mpll + - amlogic,t7-hdmi-pll + + then: + properties: + clocks: + maxItems: 1 + + clock-names: + maxItems: 1 + +additionalProperties: false + +examples: + - | + apb { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@8080 { + compatible = "amlogic,t7-gp0-pll"; + reg = <0 0x8080 0 0x20>; + clocks = <&scmi_clk 2>; + clock-names = "in0"; + #clock-cells = <1>; + }; + + clock-controller@8300 { + compatible = "amlogic,t7-mclk-pll"; + reg = <0 0x8300 0 0x18>; + clocks = <&scmi_clk 2>, + <&xtal>, + <&scmi_clk 31>; + clock-names = "in0", "in1", "in2"; + #clock-cells = <1>; + }; + }; diff --git a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml index 6193c87511fa..5122c5827718 100644 --- a/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +++ b/Documentation/devicetree/bindings/clock/google,gs101-clock.yaml @@ -53,6 +53,11 @@ properties: reg: maxItems: 1 + samsung,sysreg: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle to system registers interface. + required: - compatible - "#clock-cells" @@ -185,6 +190,18 @@ allOf: - const: bus - const: ip + - if: + properties: + compatible: + contains: + const: google,gs101-cmu-top + then: + properties: + samsung,sysreg: false + else: + required: + - samsung,sysreg + additionalProperties: false examples: @@ -194,7 +211,7 @@ examples: cmu_top: clock-controller@1e080000 { compatible = "google,gs101-cmu-top"; - reg = <0x1e080000 0x8000>; + reg = <0x1e080000 0x10000>; #clock-cells = <1>; clocks = <&ext_24_5m>; clock-names = "oscclk"; diff --git a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml index 9c3913f9092c..c77111d10f90 100644 --- a/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml +++ b/Documentation/devicetree/bindings/clock/mediatek,mt7622-pciesys.yaml @@ -14,11 +14,9 @@ maintainers: properties: compatible: - oneOf: - - items: - - const: mediatek,mt7622-pciesys - - const: syscon - - const: mediatek,mt7629-pciesys + enum: + - mediatek,mt7622-pciesys + - mediatek,mt7629-pciesys reg: maxItems: 1 @@ -40,7 +38,7 @@ additionalProperties: false examples: - | clock-controller@1a100800 { - compatible = "mediatek,mt7622-pciesys", "syscon"; + compatible = "mediatek,mt7622-pciesys"; reg = <0x1a100800 0x1000>; #clock-cells = <1>; #reset-cells = <1>; diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml index f1770360798f..9a6b50527c42 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-ccc.yaml @@ -17,7 +17,11 @@ description: | properties: compatible: - const: microchip,mpfs-ccc + oneOf: + - items: + - const: microchip,pic64gx-ccc + - const: microchip,mpfs-ccc + - const: microchip,mpfs-ccc reg: items: diff --git a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml index ee4f31596d97..a23703c281d1 100644 --- a/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml +++ b/Documentation/devicetree/bindings/clock/microchip,mpfs-clkcfg.yaml @@ -19,7 +19,11 @@ description: | properties: compatible: - const: microchip,mpfs-clkcfg + oneOf: + - items: + - const: microchip,pic64gx-clkcfg + - const: microchip,mpfs-clkcfg + - const: microchip,mpfs-clkcfg reg: oneOf: @@ -69,6 +73,16 @@ required: - clocks - '#clock-cells' +if: + properties: + compatible: + contains: + const: microchip,pic64gx-clkcfg +then: + properties: + reg: + maxItems: 1 + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml index f2e37f439d28..ced3118c8580 100644 --- a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8953.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/clock/qcom,gcc-msm8953.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Global Clock & Reset Controller on MSM8953 +title: Qualcomm Global Clock & Reset Controller on MSM8937, MSM8940, MSM8953 and SDM439 maintainers: - Adam Skladowski @@ -13,7 +13,7 @@ maintainers: description: | Qualcomm global clock control module provides the clocks, resets and power - domains on MSM8937 or MSM8953. + domains on MSM8937, MSM8940, MSM8953 or SDM439. See also:: include/dt-bindings/clock/qcom,gcc-msm8917.h @@ -23,7 +23,9 @@ properties: compatible: enum: - qcom,gcc-msm8937 + - qcom,gcc-msm8940 - qcom,gcc-msm8953 + - qcom,gcc-sdm439 clocks: items: diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml new file mode 100644 index 000000000000..5490a975f3db --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,kaanapali-gxclkctl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Graphics power domain Controller on Kaanapali + +maintainers: + - Taniya Das + +description: | + Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and + Power domains (GDSC). This module provides the power domains control + of gxclkctl on Qualcomm SoCs which helps the recovery of Graphics subsystem. + + See also: + include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h + +properties: + compatible: + enum: + - qcom,kaanapali-gxclkctl + + power-domains: + description: + Power domains required for the clock controller to operate + items: + - description: GFX power domain + - description: GMXC power domain + - description: GPUCC(CX) power domain + + '#power-domain-cells': + const: 1 + + reg: + maxItems: 1 + +required: + - compatible + - reg + - power-domains + - '#power-domain-cells' + +unevaluatedProperties: false + +examples: + - | + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@3d64000 { + compatible = "qcom,kaanapali-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc 0>; + #power-domain-cells = <1>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index c1e06f39431e..8492a7ef7324 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml @@ -9,23 +9,32 @@ title: Qualcomm Camera Clock & Reset Controller on SM8450 maintainers: - Vladimir Zapolskiy - Jagadeesh Kona + - Taniya Das description: | Qualcomm camera clock control module provides the clocks, resets and power domains on SM8450. See also: + include/dt-bindings/clock/qcom,kaanapali-camcc.h + include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h + include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h + include/dt-bindings/clock/qcom,sm8750-camcc.h properties: compatible: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sm8450-camcc - qcom,sm8475-camcc - qcom,sm8550-camcc - qcom,sm8650-camcc + - qcom,sm8750-cambistmclkcc + - qcom,sm8750-camcc clocks: items: @@ -63,6 +72,8 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc - qcom,sc8280xp-camcc - qcom,sm8450-camcc - qcom,sm8550-camcc diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 44380f6f8136..6feaa32569f9 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml @@ -14,6 +14,7 @@ description: | domains on Qualcomm SoCs. See also:: + include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h include/dt-bindings/clock/qcom,sar2130p-gpucc.h include/dt-bindings/clock/qcom,sm4450-gpucc.h @@ -26,6 +27,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-gpucc - qcom,milos-gpucc - qcom,sar2130p-gpucc - qcom,sm4450-gpucc diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index b31bd8335529..e6beebd6a36e 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8450. See also: + include/dt-bindings/clock/qcom,kaanapali-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -22,6 +23,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc - qcom,sm8550-videocc @@ -61,6 +63,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-videocc - qcom,sm8450-videocc - qcom,sm8550-videocc - qcom,sm8750-videocc diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml index 30e4b4631575..591ce91b8d54 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8550-dispcc.yaml @@ -15,6 +15,7 @@ description: | domains on SM8550, SM8650, SM8750 and few other platforms. See also: + - include/dt-bindings/clock/qcom,kaanapali-dispcc.h - include/dt-bindings/clock/qcom,sm8550-dispcc.h - include/dt-bindings/clock/qcom,sm8650-dispcc.h - include/dt-bindings/clock/qcom,sm8750-dispcc.h @@ -23,6 +24,7 @@ description: | properties: compatible: enum: + - qcom,kaanapali-dispcc - qcom,sar2130p-dispcc - qcom,sm8550-dispcc - qcom,sm8650-dispcc diff --git a/Documentation/devicetree/bindings/clock/renesas,9series.yaml b/Documentation/devicetree/bindings/clock/renesas,9series.yaml index af6319697b1c..a85f78ce2970 100644 --- a/Documentation/devicetree/bindings/clock/renesas,9series.yaml +++ b/Documentation/devicetree/bindings/clock/renesas,9series.yaml @@ -62,7 +62,7 @@ properties: description: Output clock down spread in pcm (1/1000 of percent) patternProperties: - "^DIF[0-19]$": + "^DIF1?[0-9]$": type: object description: Description of one of the outputs (DIF0..DIF19). @@ -107,6 +107,15 @@ examples: DIF0 { renesas,slew-rate = <3000000>; }; + + /* Not present on 9FGV0241, used for DT validation only */ + DIF2 { + renesas,slew-rate = <2000000>; + }; + + DIF19 { + renesas,slew-rate = <3000000>; + }; }; }; diff --git a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml index 5bf905f88a1a..1318720193b3 100644 --- a/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml +++ b/Documentation/devicetree/bindings/clock/samsung,exynosautov920-clock.yaml @@ -40,6 +40,7 @@ properties: - samsung,exynosautov920-cmu-hsi2 - samsung,exynosautov920-cmu-m2m - samsung,exynosautov920-cmu-mfc + - samsung,exynosautov920-cmu-mfd - samsung,exynosautov920-cmu-misc - samsung,exynosautov920-cmu-peric0 - samsung,exynosautov920-cmu-peric1 @@ -268,6 +269,24 @@ allOf: - const: mfc - const: wfd + - if: + properties: + compatible: + contains: + const: samsung,exynosautov920-cmu-mfd + + then: + properties: + clocks: + items: + - description: External reference clock (38.4 MHz) + - description: CMU_MFD NOC clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: noc + required: - compatible - "#clock-cells" diff --git a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml index 06bafd68c00a..cddf6a56dac0 100644 --- a/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml +++ b/Documentation/devicetree/bindings/clock/spacemit,k1-pll.yaml @@ -4,14 +4,16 @@ $id: http://devicetree.org/schemas/clock/spacemit,k1-pll.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: SpacemiT K1 PLL +title: SpacemiT K1/K3 PLL maintainers: - Haylen Chu properties: compatible: - const: spacemit,k1-pll + enum: + - spacemit,k1-pll + - spacemit,k3-pll reg: maxItems: 1 @@ -28,7 +30,8 @@ properties: "#clock-cells": const: 1 description: - See for valid indices. + For K1 SoC, check for valid indices. + For K3 SoC, check for valid indices. required: - compatible diff --git a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml index ebda78db87a6..02ddfaab5f56 100644 --- a/Documentation/devicetree/bindings/display/msm/dp-controller.yaml +++ b/Documentation/devicetree/bindings/display/msm/dp-controller.yaml @@ -253,7 +253,6 @@ allOf: enum: # these platforms support 2 streams MST on some interfaces, # others are SST only - - qcom,glymur-dp - qcom,sc8280xp-dp - qcom,x1e80100-dp then: @@ -310,6 +309,26 @@ allOf: minItems: 6 maxItems: 8 + - if: + properties: + compatible: + contains: + enum: + # these platforms support 2 streams MST on some interfaces, + # others are SST only, but all controllers have 4 ports + - qcom,glymur-dp + then: + properties: + reg: + minItems: 9 + maxItems: 9 + clocks: + minItems: 5 + maxItems: 6 + clocks-names: + minItems: 5 + maxItems: 6 + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml index 2329ed96e6cb..64dde43373ac 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,glymur-mdss.yaml @@ -176,13 +176,17 @@ examples: }; }; - displayport-controller@ae90000 { + displayport-controller@af54000 { compatible = "qcom,glymur-dp"; - reg = <0xae90000 0x200>, - <0xae90200 0x200>, - <0xae90400 0x600>, - <0xae91000 0x400>, - <0xae91400 0x400>; + reg = <0xaf54000 0x200>, + <0xaf54200 0x200>, + <0xaf55000 0xc00>, + <0xaf56000 0x400>, + <0xaf57000 0x400>, + <0xaf58000 0x400>, + <0xaf59000 0x400>, + <0xaf5a000 0x600>, + <0xaf5b000 0x600>; interrupt-parent = <&mdss>; interrupts = <12>; diff --git a/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml b/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml index d55fda9a523e..a38c2261ef1a 100644 --- a/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml +++ b/Documentation/devicetree/bindings/display/msm/qcom,sm8750-mdss.yaml @@ -10,7 +10,7 @@ maintainers: - Krzysztof Kozlowski description: - SM8650 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like + SM8750 MSM Mobile Display Subsystem(MDSS), which encapsulates sub-blocks like DPU display controller, DSI and DP interfaces etc. $ref: /schemas/display/msm/mdss-common.yaml# diff --git a/Documentation/devicetree/bindings/dma/arm-pl08x.yaml b/Documentation/devicetree/bindings/dma/arm-pl08x.yaml index ab25ae63d2c3..beab36ac583f 100644 --- a/Documentation/devicetree/bindings/dma/arm-pl08x.yaml +++ b/Documentation/devicetree/bindings/dma/arm-pl08x.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/dma/arm-pl08x.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: ARM PrimeCells PL080 and PL081 and derivatives DMA controller +title: ARM PrimeCell PL080 and PL081 and derivatives DMA controller maintainers: - Vinod Koul diff --git a/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml b/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml index 73fc13b902b3..197efb19b07a 100644 --- a/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml +++ b/Documentation/devicetree/bindings/dma/atmel,sama5d4-dma.yaml @@ -33,7 +33,9 @@ properties: - microchip,sam9x7-dma - const: atmel,sama5d4-dma - items: - - const: microchip,sama7d65-dma + - enum: + - microchip,lan9691-dma + - microchip,sama7d65-dma - const: microchip,sama7g5-dma "#dma-cells": diff --git a/Documentation/devicetree/bindings/dma/mediatek,uart-dma.yaml b/Documentation/devicetree/bindings/dma/mediatek,uart-dma.yaml index dab468a88942..3708518fe7fc 100644 --- a/Documentation/devicetree/bindings/dma/mediatek,uart-dma.yaml +++ b/Documentation/devicetree/bindings/dma/mediatek,uart-dma.yaml @@ -7,6 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: MediaTek UART APDMA controller maintainers: + - AngeloGioacchino Del Regno - Long Cheng description: | @@ -23,11 +24,29 @@ properties: - enum: - mediatek,mt2712-uart-dma - mediatek,mt6795-uart-dma + - mediatek,mt8173-uart-dma + - mediatek,mt8183-uart-dma - mediatek,mt8365-uart-dma - mediatek,mt8516-uart-dma - const: mediatek,mt6577-uart-dma + - items: + - enum: + - mediatek,mt7988-uart-dma + - mediatek,mt8186-uart-dma + - mediatek,mt8188-uart-dma + - mediatek,mt8192-uart-dma + - mediatek,mt8195-uart-dma + - const: mediatek,mt6835-uart-dma + - items: + - enum: + - mediatek,mt6991-uart-dma + - mediatek,mt8196-uart-dma + - const: mediatek,mt6985-uart-dma - enum: - mediatek,mt6577-uart-dma + - mediatek,mt6795-uart-dma + - mediatek,mt6835-uart-dma + - mediatek,mt6985-uart-dma reg: minItems: 1 @@ -58,6 +77,7 @@ properties: mediatek,dma-33bits: type: boolean + deprecated: true description: Enable 33-bits UART APDMA support required: diff --git a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml index bbe4da2a1105..fde1df035ad1 100644 --- a/Documentation/devicetree/bindings/dma/qcom,gpi.yaml +++ b/Documentation/devicetree/bindings/dma/qcom,gpi.yaml @@ -24,6 +24,8 @@ properties: - qcom,sm6350-gpi-dma - items: - enum: + - qcom,glymur-gpi-dma + - qcom,kaanapali-gpi-dma - qcom,milos-gpi-dma - qcom,qcm2290-gpi-dma - qcom,qcs8300-gpi-dma @@ -58,7 +60,7 @@ properties: description: Interrupt lines for each GPI instance minItems: 1 - maxItems: 13 + maxItems: 16 "#dma-cells": const: 3 diff --git a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml index f891cfcc48c7..d137b9cbaee9 100644 --- a/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/renesas,rz-dmac.yaml @@ -24,6 +24,7 @@ properties: - items: - enum: - renesas,r9a09g047-dmac # RZ/G3E + - renesas,r9a09g056-dmac # RZ/V2N - const: renesas,r9a09g057-dmac - const: renesas,r9a09g057-dmac # RZ/V2H(P) diff --git a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml index a393a33c8908..216cda21c538 100644 --- a/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml +++ b/Documentation/devicetree/bindings/dma/snps,dw-axi-dmac.yaml @@ -17,11 +17,15 @@ allOf: properties: compatible: - enum: - - snps,axi-dma-1.01a - - intel,kmb-axi-dma - - starfive,jh7110-axi-dma - - starfive,jh8100-axi-dma + oneOf: + - enum: + - snps,axi-dma-1.01a + - intel,kmb-axi-dma + - starfive,jh7110-axi-dma + - starfive,jh8100-axi-dma + - items: + - const: altr,agilex5-axi-dma + - const: snps,axi-dma-1.01a reg: minItems: 1 diff --git a/Documentation/devicetree/bindings/eeprom/at24.yaml b/Documentation/devicetree/bindings/eeprom/at24.yaml index c21282634780..ef88f46928a4 100644 --- a/Documentation/devicetree/bindings/eeprom/at24.yaml +++ b/Documentation/devicetree/bindings/eeprom/at24.yaml @@ -116,6 +116,7 @@ properties: - const: atmel,24c02 - items: - enum: + - belling,bl24c04a - giantec,gt24c04a - onnn,cat24c04 - onnn,cat24c05 @@ -124,6 +125,7 @@ properties: - items: - enum: - belling,bl24c16a + - belling,bl24c16f - renesas,r1ex24016 - const: atmel,24c16 - items: @@ -132,6 +134,7 @@ properties: - items: - enum: - belling,bl24s64 + - giantec,gt24p64a - onnn,n24s64b - puya,p24c64f - const: atmel,24c64 @@ -139,6 +142,7 @@ properties: - enum: - giantec,gt24p128e - giantec,gt24p128f + - puya,p24c128f - renesas,r1ex24128 - samsung,s524ad0xd1 - const: atmel,24c128 diff --git a/Documentation/devicetree/bindings/goldfish/events.txt b/Documentation/devicetree/bindings/goldfish/events.txt deleted file mode 100644 index 5babf46317a4..000000000000 --- a/Documentation/devicetree/bindings/goldfish/events.txt +++ /dev/null @@ -1,17 +0,0 @@ -Android Goldfish Events Keypad - -Android goldfish events keypad device generated by android emulator. - -Required properties: - -- compatible : should contain "google,goldfish-events-keypad" to match emulator -- reg : -- interrupts : - -Example: - - goldfish-events@9040000 { - compatible = "google,goldfish-events-keypad"; - reg = <0x9040000 0x1000>; - interrupts = <0x5>; - }; diff --git a/Documentation/devicetree/bindings/goldfish/pipe.txt b/Documentation/devicetree/bindings/goldfish/pipe.txt deleted file mode 100644 index 5637ce701788..000000000000 --- a/Documentation/devicetree/bindings/goldfish/pipe.txt +++ /dev/null @@ -1,17 +0,0 @@ -Android Goldfish QEMU Pipe - -Android pipe virtual device generated by android emulator. - -Required properties: - -- compatible : should contain "google,android-pipe" to match emulator -- reg : -- interrupts : - -Example: - - android_pipe@a010000 { - compatible = "google,android-pipe"; - reg = ; - interrupts = <0x12>; - }; diff --git a/Documentation/devicetree/bindings/goldfish/tty.txt b/Documentation/devicetree/bindings/goldfish/tty.txt deleted file mode 100644 index 82648278da77..000000000000 --- a/Documentation/devicetree/bindings/goldfish/tty.txt +++ /dev/null @@ -1,17 +0,0 @@ -Android Goldfish TTY - -Android goldfish tty device generated by android emulator. - -Required properties: - -- compatible : should contain "google,goldfish-tty" to match emulator -- reg : -- interrupts : - -Example: - - goldfish_tty@1f004000 { - compatible = "google,goldfish-tty"; - reg = <0x1f004000 0x1000>; - interrupts = <0xc>; - }; diff --git a/Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml b/Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml index 966b221b6caa..5803a1770cad 100644 --- a/Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml +++ b/Documentation/devicetree/bindings/hwmon/kontron,sl28cpld-hwmon.yaml @@ -16,7 +16,6 @@ description: | properties: compatible: enum: - - kontron,sa67mcu-hwmon - kontron,sl28cpld-fan reg: diff --git a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml index e61cdb5b16ef..c83674c3183b 100644 --- a/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/atmel,at91sam-i2c.yaml @@ -26,6 +26,7 @@ properties: - microchip,sam9x60-i2c - items: - enum: + - microchip,lan9691-i2c - microchip,sama7d65-i2c - microchip,sama7g5-i2c - microchip,sam9x7-i2c diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml index 3562ce0c0f7e..ecd5783f001b 100644 --- a/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml +++ b/Documentation/devicetree/bindings/i2c/i2c-mt65xx.yaml @@ -54,6 +54,7 @@ properties: - enum: - mediatek,mt6878-i2c - mediatek,mt6991-i2c + - mediatek,mt8189-i2c - mediatek,mt8196-i2c - const: mediatek,mt8188-i2c - items: diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml index a3fe1eea6aec..399a09409e07 100644 --- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml +++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml @@ -28,6 +28,7 @@ properties: - enum: - qcom,kaanapali-cci - qcom,qcm2290-cci + - qcom,qcs8300-cci - qcom,sa8775p-cci - qcom,sc7280-cci - qcom,sc8280xp-cci @@ -133,6 +134,7 @@ allOf: enum: - qcom,kaanapali-cci - qcom,qcm2290-cci + - qcom,qcs8300-cci - qcom,sm8750-cci then: properties: diff --git a/Documentation/devicetree/bindings/i2c/silabs,cp2112.yaml b/Documentation/devicetree/bindings/i2c/silabs,cp2112.yaml new file mode 100644 index 000000000000..a204adfe57b3 --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/silabs,cp2112.yaml @@ -0,0 +1,100 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/silabs,cp2112.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: CP2112 HID USB to SMBus/I2C Bridge + +maintainers: + - Danny Kaehn + +description: + The CP2112 is a USB HID device which includes an integrated I2C controller + and 8 GPIO pins. Its GPIO pins can each be configured as inputs, open-drain + outputs, or push-pull outputs. + +properties: + compatible: + const: usb10c4,ea90 + + reg: + maxItems: 1 + description: The USB port number + + interrupt-controller: true + "#interrupt-cells": + const: 2 + + gpio-controller: true + "#gpio-cells": + const: 2 + + gpio-line-names: + minItems: 1 + maxItems: 8 + + i2c: + description: The SMBus/I2C controller node for the CP2112 + $ref: /schemas/i2c/i2c-controller.yaml# + unevaluatedProperties: false + + properties: + clock-frequency: + minimum: 10000 + default: 100000 + maximum: 400000 + +patternProperties: + "-hog(-[0-9]+)?$": + type: object + + required: + - gpio-hog + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + #include + + usb { + #address-cells = <1>; + #size-cells = <0>; + + cp2112: device@1 { + compatible = "usb10c4,ea90"; + reg = <1>; + + gpio-controller; + interrupt-controller; + #interrupt-cells = <2>; + #gpio-cells = <2>; + gpio-line-names = "CP2112_SDA", "CP2112_SCL", "TEST2", + "TEST3","TEST4", "TEST5", "TEST6"; + + fan-rst-hog { + gpio-hog; + gpios = <7 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "FAN_RST"; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + sda-gpios = <&cp2112 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&cp2112 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + temp@48 { + compatible = "national,lm75"; + reg = <0x48>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml index 914200188809..082fdc2e69ea 100644 --- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml @@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Synopsys DesignWare APB I2C Controller maintainers: - - Jarkko Nikula + - Mika Westerberg allOf: - $ref: /schemas/i2c/i2c-controller.yaml# diff --git a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml index b7220fff2235..5896fb120501 100644 --- a/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/spacemit,k1-i2c.yaml @@ -41,6 +41,9 @@ properties: default: 400000 maximum: 3300000 + resets: + maxItems: 1 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml new file mode 100644 index 000000000000..eeb148081663 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright 2025 Analog Devices Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4062.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4062 ADC family device driver + +maintainers: + - Jorge Marques + +description: | + Analog Devices AD4062 Single Channel Precision SAR ADC family + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4060.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4062.pdf + +properties: + compatible: + enum: + - adi,ad4060 + - adi,ad4062 + + reg: + maxItems: 1 + + interrupts: + description: + Two pins are available that can be configured as either a general purpose + digital output, device enable signal (used to synchronise other parts of + the signal chain with ADC sampling), device ready (GP1 only) or various + interrupt signals. If intended for use as a GPIO or device enable, will not + present here. + minItems: 1 + items: + - description: + GP0 pin, cannot be configured as DEV_RDY. + - description: + GP1 pin, can be configured to any setting. + + interrupt-names: + minItems: 1 + items: + - const: gp0 + - const: gp1 + + gpio-controller: + description: + Marks the device node as a GPIO controller. GPs not listed as interrupts + are exposed as a GPO. + + '#gpio-cells': + const: 2 + description: + The first cell is the GPIO number and the second cell specifies + GPIO flags, as defined in . + + vdd-supply: + description: Analog power supply. + + vio-supply: + description: Digital interface logic power supply. + + ref-supply: + description: + Reference voltage to set the ADC full-scale range. If not present, + vdd-supply is used as the reference voltage. + +required: + - compatible + - reg + - vdd-supply + - vio-supply + +allOf: + - $ref: /schemas/i3c/i3c.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + + i3c { + #address-cells = <3>; + #size-cells = <0>; + + adc@0,2ee007c0000 { + reg = <0x0 0x2ee 0x7c0000>; + vdd-supply = <&vdd>; + vio-supply = <&vio>; + ref-supply = <&ref>; + + interrupt-parent = <&gpio>; + interrupts = <0 0 IRQ_TYPE_EDGE_RISING>, + <0 1 IRQ_TYPE_EDGE_FALLING>; + interrupt-names = "gp0", "gp1"; + }; + }; + + - | + #include + #include + + i3c { + #address-cells = <3>; + #size-cells = <0>; + + adc@0,2ee007c0000 { + reg = <0x0 0x2ee 0x7c0000>; + vdd-supply = <&vdd>; + vio-supply = <&vio>; + ref-supply = <&ref>; + + gpio-controller; + #gpio-cells = <2>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml new file mode 100644 index 000000000000..ea6d7e026419 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml @@ -0,0 +1,191 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/adi,ad4134.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices AD4134 ADC + +maintainers: + - Marcelo Schmitt + +description: | + The AD4134 is a quad channel, low noise, simultaneous sampling, precision + analog-to-digital converter (ADC). + Specifications can be found at: + https://www.analog.com/media/en/technical-documentation/data-sheets/ad4134.pdf + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - adi,ad4134 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 50000000 + + avdd5-supply: + description: A 5V supply that powers the chip's analog circuitry. + + dvdd5-supply: + description: A 5V supply that powers the chip's digital circuitry. + + iovdd-supply: + description: + A 1.8V supply that sets the logic levels for the digital interface pins. + + refin-supply: + description: + A 4.096V or 5V supply that serves as reference for ADC conversions. + + avdd1v8-supply: + description: A 1.8V supply used by the analog circuitry. + + dvdd1v8-supply: + description: A 1.8V supply used by the digital circuitry. + + clkvdd-supply: + description: A 1.8V supply for the chip's clock management circuit. + + ldoin-supply: + description: + A 2.6V to 5.5V supply that generates 1.8V for AVDD1V8, DVDD1V8, and CLKVDD + pins. + + clocks: + maxItems: 1 + description: + Required external clock source. Can specify either a crystal or CMOS clock + source. If an external crystal is set, connect the CLKSEL pin to IOVDD. + Otherwise, connect the CLKSEL pin to IOGND and the external CMOS clock + signal to the XTAL2/CLKIN pin. + + clock-names: + enum: + - xtal + - clkin + default: clkin + + '#clock-cells': + const: 0 + + clock-output-names: + maxItems: 1 + + regulators: + type: object + description: + list of regulators provided by this controller. + + properties: + vcm-output: + $ref: /schemas/regulator/regulator.yaml# + type: object + unevaluatedProperties: false + + additionalProperties: false + + reset-gpios: + maxItems: 1 + + powerdown-gpios: + description: + Active low GPIO connected to the /PDN pin. Forces the device into full + power-down mode when brought low. Pull this input to IOVDD for normal + operation. + maxItems: 1 + + odr-gpios: + description: + GPIO connected to ODR pin. Used to sample ADC data in minimum I/O mode. + maxItems: 1 + + adi,asrc-mode: + $ref: /schemas/types.yaml#/definitions/string + description: + Asynchronous Sample Rate Converter (ASRC) operation mode control input. + Describes whether the MODE pin is set to a high level (for master mode + operation) or to a low level (for slave mode operation). + enum: [ high, low ] + default: low + + adi,dclkio: + description: + DCLK pin I/O direction control for when the device operates in Pin Control + Slave Mode or in SPI Control Mode. Describes if DEC0/DCLKIO pin is at a + high level (which configures DCLK as an output) or to set to a low level + (configuring DCLK for input). + enum: [ out, in ] + default: in + + adi,dclkmode: + description: + DCLK mode control for when the device operates in Pin Control Slave Mode + or in SPI Control Mode. Describes whether the DEC1/DCLKMODE pin is set to + a high level (configuring the DCLK to operate in free running mode) or + to a low level (to configure DCLK to operate in gated mode). + enum: [ free-running, gated ] + default: gated + +required: + - compatible + - reg + - avdd5-supply + - dvdd5-supply + - iovdd-supply + - refin-supply + - clocks + - clock-names + +oneOf: + - required: + - ldoin-supply + - required: + - avdd1v8-supply + - dvdd1v8-supply + - clkvdd-supply + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "adi,ad4134"; + reg = <0>; + + spi-max-frequency = <1000000>; + + reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>; + odr-gpios = <&gpio0 87 GPIO_ACTIVE_HIGH>; + powerdown-gpios = <&gpio0 88 GPIO_ACTIVE_LOW>; + + clocks = <&sys_clk>; + clock-names = "clkin"; + + avdd5-supply = <&avdd5>; + dvdd5-supply = <&dvdd5>; + iovdd-supply = <&iovdd>; + refin-supply = <&refin>; + avdd1v8-supply = <&avdd1v8>; + dvdd1v8-supply = <&dvdd1v8>; + clkvdd-supply = <&clkvdd>; + + regulators { + vcm_reg: vcm-output { + regulator-name = "ad4134-vcm"; + }; + }; + + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml index c06d0fc791d3..dfa2d7fa9fb3 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml @@ -4,18 +4,26 @@ $id: http://devicetree.org/schemas/iio/adc/adi,ad7768-1.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Analog Devices AD7768-1 ADC device driver +title: Analog Devices AD7768-1 ADC family maintainers: - Michael Hennerich description: | - Datasheet at: - https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf + Analog Devices AD7768-1 24-Bit Single Channel Low Power sigma-delta ADC family + + https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-1.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7767-1.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7768-1.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/adaq7769-1.pdf properties: compatible: - const: adi,ad7768-1 + enum: + - adi,ad7768-1 + - adi,adaq7767-1 + - adi,adaq7768-1 + - adi,adaq7769-1 reg: maxItems: 1 @@ -58,6 +66,25 @@ properties: description: ADC reference voltage supply + adi,aaf-gain-bp: + description: | + Specifies the gain applied by the Analog Anti-Aliasing Filter (AAF) + to the ADC input in basis points (one hundredth of a percent). + The hardware gain is determined by which input pin(s) the signal goes + through into the AAF. The possible connections are: + * For the ADAQ7767-1: Input connected to IN1±, IN2± or IN3±. + * For the ADAQ7769-1: OUT_PGA pin connected to IN1_AAF+, IN2_AAF+, + or IN3_AAF+. + enum: [1430, 3640, 10000] + default: 10000 + + pga-gpios: + description: + GAIN 0, GAIN1 and GAIN2 pins for gain selection. For devices that have + PGA configuration input pins, pga-gpios must be defined. + minItems: 3 + maxItems: 3 + adi,sync-in-gpios: maxItems: 1 description: @@ -147,6 +174,35 @@ patternProperties: allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# + # AAF Gain property only applies to ADAQ7767-1 and ADAQ7769-1 devices + - if: + properties: + compatible: + contains: + enum: + - adi,adaq7767-1 + - adi,adaq7769-1 + then: + required: + - adi,aaf-gain-bp + else: + properties: + adi,aaf-gain-bp: false + + - if: + properties: + compatible: + contains: + enum: + - adi,adaq7768-1 + - adi,adaq7769-1 + then: + required: + - pga-gpios + else: + properties: + pga-gpios: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml index 2606c0c5dfc6..5acfb0eef4d5 100644 --- a/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml +++ b/Documentation/devicetree/bindings/iio/adc/adi,ad9467.yaml @@ -18,6 +18,7 @@ description: | All the parts support the register map described by Application Note AN-877 https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf + https://www.analog.com/media/en/technical-documentation/data-sheets/AD9211.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD9265.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD9434.pdf https://www.analog.com/media/en/technical-documentation/data-sheets/AD9467.pdf @@ -25,6 +26,7 @@ description: | properties: compatible: enum: + - adi,ad9211 - adi,ad9265 - adi,ad9434 - adi,ad9467 diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml index 509bfb1007c4..249101b55cf4 100644 --- a/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml +++ b/Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml @@ -44,6 +44,9 @@ properties: Input clock used to derive the sample clock. Expected to be the SoC's APB clock. + interrupts: + maxItems: 1 + resets: maxItems: 1 diff --git a/Documentation/devicetree/bindings/iio/adc/nxp,s32g2-sar-adc.yaml b/Documentation/devicetree/bindings/iio/adc/nxp,s32g2-sar-adc.yaml new file mode 100644 index 000000000000..ec258f224df8 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/nxp,s32g2-sar-adc.yaml @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/nxp,s32g2-sar-adc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP Successive Approximation ADC + +description: + The NXP SAR ADC provides fast and accurate analog-to-digital + conversion using the Successive Approximation Register (SAR) method. + It has 12-bit resolution with 8 input channels. Conversions can be + launched in software or using hardware triggers. It supports + continuous and one-shot modes with separate registers. + +maintainers: + - Daniel Lezcano + +properties: + compatible: + oneOf: + - const: nxp,s32g2-sar-adc + - items: + - const: nxp,s32g3-sar-adc + - const: nxp,s32g2-sar-adc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + dmas: + maxItems: 1 + + dma-names: + const: rx + +required: + - compatible + - reg + - interrupts + - clocks + - dmas + - dma-names + +additionalProperties: false + +examples: + - | + #include + + adc@401f8000 { + compatible = "nxp,s32g2-sar-adc"; + reg = <0x401f8000 0x1000>; + interrupts = ; + clocks = <&clks 0x41>; + dmas = <&edma0 0 32>; + dma-names = "rx"; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml new file mode 100644 index 000000000000..81ee024be2e3 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml @@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads1018.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI ADS1018/ADS1118 SPI analog to digital converter + +maintainers: + - Kurt Borja + +description: | + The ADS1018/ADS1118 is a precision, low-power, 12-bit/16-bit, analog to + digital converter (ADC). It integrates a programmable gain amplifier (PGA), + internal voltage reference, oscillator and high-accuracy temperature sensor. + + Datasheets: + - ADS1018: https://www.ti.com/lit/ds/symlink/ads1018.pdf + - ADS1118: https://www.ti.com/lit/ds/symlink/ads1118.pdf + +properties: + compatible: + enum: + - ti,ads1018 + - ti,ads1118 + + reg: + maxItems: 1 + + vdd-supply: true + + spi-max-frequency: + maximum: 4000000 + + spi-cpha: true + + interrupts: + description: DOUT/DRDY (Data Out/Data Ready) line. + maxItems: 1 + + drdy-gpios: + description: + Extra GPIO line connected to DOUT/DRDY (Data Out/Data Ready). This allows + distinguishing between interrupts triggered by the data-ready signal and + interrupts triggered by an SPI transfer. + maxItems: 1 + + '#io-channel-cells': + const: 1 + +required: + - compatible + - reg + - vdd-supply + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads1118"; + reg = <0>; + + spi-max-frequency = <4000000>; + spi-cpha; + + vdd-supply = <&vdd_3v3_reg>; + + interrupts-extended = <&gpio 14 IRQ_TYPE_EDGE_FALLING>; + drdy-gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/adc/ti,ads131m02.yaml b/Documentation/devicetree/bindings/iio/adc/ti,ads131m02.yaml new file mode 100644 index 000000000000..5d52bb7dd5d4 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/ti,ads131m02.yaml @@ -0,0 +1,208 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/adc/ti,ads131m02.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments ADS131M0x 2-, 3-, 4-, 6- and 8-Channel ADCs + +maintainers: + - Oleksij Rempel + +description: | + The ADS131M0x are a family of multichannel, simultaneous sampling, + 24-bit, delta-sigma, analog-to-digital converters (ADCs) with a + built-in programmable gain amplifier (PGA) and internal reference. + Communication with the ADC chip is via SPI. + + Datasheets: + - ADS131M02: https://www.ti.com/lit/ds/symlink/ads131m02.pdf + - ADS131M03: https://www.ti.com/lit/ds/symlink/ads131m03.pdf + - ADS131M04: https://www.ti.com/lit/ds/symlink/ads131m04.pdf + - ADS131M06: https://www.ti.com/lit/ds/symlink/ads131m06.pdf + - ADS131M08: https://www.ti.com/lit/ds/symlink/ads131m08.pdf + +properties: + compatible: + enum: + - ti,ads131m02 + - ti,ads131m03 + - ti,ads131m04 + - ti,ads131m06 + - ti,ads131m08 + + reg: + description: SPI chip select number. + + clocks: + description: + Phandle to the external clock source required by the ADC's CLKIN pin. + The datasheet recommends specific frequencies based on the desired power + mode (e.g., 8.192 MHz for High-Resolution mode). + maxItems: 1 + + avdd-supply: + description: Analog power supply (AVDD). + + dvdd-supply: + description: Digital power supply (DVDD). + + interrupts: + description: DRDY (Data Ready) output signal. + maxItems: 1 + + reset-gpios: + description: Optional RESET signal. + maxItems: 1 + + clock-names: + description: + Indicates if a crystal oscillator (XTAL) or CMOS signal is connected + (CLKIN). Note that XTAL mode is only supported on ADS131M06 and ADS131M08. + enum: [xtal, clkin] + + refin-supply: + description: Optional external reference supply (REFIN). + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - avdd-supply + - dvdd-supply + +patternProperties: + "^channel@[0-7]$": + type: object + $ref: /schemas/iio/adc/adc.yaml# + description: Properties for a single ADC channel. + + properties: + reg: + description: The channel index (0-7). + minimum: 0 + maximum: 7 # Max channels on ADS131M08 + + label: true + + required: + - reg + + unevaluatedProperties: false + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + + - if: + # 20-pin devices: M02, M03, M04 + # These do not support XTAL or REFIN. + properties: + compatible: + enum: + - ti,ads131m02 + - ti,ads131m03 + - ti,ads131m04 + then: + properties: + clock-names: + const: clkin + refin-supply: false + + - if: + # ADS131M02: 2 channels max (0-1) + properties: + compatible: + contains: + const: ti,ads131m02 + then: + patternProperties: + "^channel@[0-1]$": + properties: + reg: + maximum: 1 + "^channel@[2-7]$": false + + - if: + # ADS131M03: 3 channels max (0-2) + properties: + compatible: + contains: + const: ti,ads131m03 + then: + patternProperties: + "^channel@[0-2]$": + properties: + reg: + maximum: 2 + "^channel@[3-7]$": false + + - if: + # ADS131M04: 4 channels max (0-3) + properties: + compatible: + contains: + const: ti,ads131m04 + then: + patternProperties: + "^channel@[0-3]$": + properties: + reg: + maximum: 3 + "^channel@[4-7]$": false + + - if: + # ADS131M06: 6 channels max (0-5) + properties: + compatible: + contains: + const: ti,ads131m06 + then: + patternProperties: + "^channel@[0-5]$": + properties: + reg: + maximum: 5 + "^channel@[6-7]$": false + +unevaluatedProperties: false + +examples: + - | + #include + + spi1 { + #address-cells = <1>; + #size-cells = <0>; + + adc@0 { + compatible = "ti,ads131m02"; + reg = <0>; + spi-max-frequency = <8000000>; + + clocks = <&rcc CK_MCO2>; + clock-names = "clkin"; + + avdd-supply = <&vdd_ana>; + dvdd-supply = <&vdd_dig>; + + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + label = "input_voltage"; + }; + + channel@1 { + reg = <1>; + label = "input_current"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml new file mode 100644 index 000000000000..6b8491d18139 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,adl8113.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/amplifiers/adi,adl8113.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices ADL8113 Low Noise Amplifier with integrated bypass switches + +maintainers: + - Antoniu Miclaus + +description: | + The ADL8113 is a 10MHz to 12GHz Low Noise Amplifier with integrated bypass + switches controlled by two GPIO pins (VA and VB). The device supports four + operation modes: + - Internal Amplifier: VA=0, VB=0 - Signal passes through the internal LNA + - Internal Bypass: VA=1, VB=1 - Signal bypasses through internal path + - External Bypass A: VA=0, VB=1 - Signal routes from RFIN to OUT_A and from IN_A to RFOUT + - External Bypass B: VA=1, VB=0 - Signal routes from RFIN to OUT_B and from IN_B to RFOUT + + https://www.analog.com/en/products/adl8113.html + +properties: + compatible: + const: adi,adl8113 + + vdd1-supply: true + + vdd2-supply: true + + vss2-supply: true + + ctrl-gpios: + items: + - description: VA control pin + - description: VB control pin + + adi,external-bypass-a-gain-db: + description: + Gain in dB of external amplifier connected to bypass path A (OUT_A/IN_A). + When specified, this gain value becomes selectable via the hardwaregain + attribute and automatically routes through the external A path. + + adi,external-bypass-b-gain-db: + description: + Gain in dB of external amplifier connected to bypass path B (OUT_B/IN_B). + When specified, this gain value becomes selectable via the hardwaregain + attribute and automatically routes through the external B path. + +required: + - compatible + - ctrl-gpios + - vdd1-supply + - vdd2-supply + - vss2-supply + +additionalProperties: false + +examples: + - | + #include + + /* Basic configuration with only internal paths */ + amplifier { + compatible = "adi,adl8113"; + ctrl-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>, + <&gpio 23 GPIO_ACTIVE_HIGH>; + vdd1-supply = <&vdd1_5v>; + vdd2-supply = <&vdd2_3v3>; + vss2-supply = <&vss2_neg>; + }; + + - | + #include + + /* Configuration with external bypass amplifiers */ + amplifier { + compatible = "adi,adl8113"; + ctrl-gpios = <&gpio 24 GPIO_ACTIVE_HIGH>, + <&gpio 25 GPIO_ACTIVE_HIGH>; + vdd1-supply = <&vdd1_5v>; + vdd2-supply = <&vdd2_3v3>; + vss2-supply = <&vss2_neg>; + adi,external-bypass-a-gain-db = <20>; /* 20dB external amp on path A */ + adi,external-bypass-b-gain-db = <6>; /* 6dB external amp on path B */ + }; +... diff --git a/Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml b/Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml new file mode 100644 index 000000000000..93d95f6b4c08 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/adi,max22007.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Analog Devices MAX22007 DAC + +maintainers: + - Janani Sunil + +description: + The MAX22007 is a quad-channel, 12-bit digital-to-analog converter (DAC) + with integrated precision output amplifiers and current output capability. + Each channel can be independently configured for voltage or current output. + Datasheet available at https://www.analog.com/en/products/max22007.html + +$ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + const: adi,max22007 + + reg: + maxItems: 1 + + spi-max-frequency: + maximum: 500000 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + vdd-supply: + description: Low-Voltage Power Supply from +2.7V to +5.5V. + + hvdd-supply: + description: + Positive High-Voltage Power Supply from +8V to (HVSS +24V) for + the Output Channels. + + hvss-supply: + description: + Optional Negative High-Voltage Power Supply from -2V to 0V for the Output + Channels. For most applications HVSS can be connected to GND (0V), but for + applications requiring output down to true 0V or 0mA, connect to a -2V supply. + + reset-gpios: + maxItems: 1 + description: + Active low GPIO. + +patternProperties: + "^channel@[0-3]$": + $ref: /schemas/iio/dac/dac.yaml# + type: object + description: + Represents the external channels which are connected to the DAC. + + properties: + reg: + description: Channel number + items: + minimum: 0 + maximum: 3 + + adi,ch-func: + description: + Channel output type. Use CH_FUNC_VOLTAGE_OUTPUT for voltage + output or CH_FUNC_CURRENT_OUTPUT for current output. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [1, 2] + + required: + - reg + - adi,ch-func + + unevaluatedProperties: false + +required: + - compatible + - reg + - vdd-supply + - hvdd-supply + +unevaluatedProperties: false + +examples: + - | + #include + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + dac@0 { + compatible = "adi,max22007"; + reg = <0>; + spi-max-frequency = <500000>; + reset-gpios = <&gpio 19 GPIO_ACTIVE_LOW>; + vdd-supply = <&vdd_reg>; + hvdd-supply = <&hvdd_reg>; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + adi,ch-func = ; + }; + + channel@1 { + reg = <1>; + adi,ch-func = ; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml b/Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml new file mode 100644 index 000000000000..d2466aa6bda2 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml @@ -0,0 +1,302 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/dac/microchip,mcp47feb02.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families + +maintainers: + - Ariana Lazar + +description: | + Datasheet for MCP47FEB01, MCP47FEB11, MCP47FEB21, MCP47FEB02, MCP47FEB12, + MCP47FEB22 can be found here: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf + Datasheet for MCP47FVB01, MCP47FVB11, MCP47FVB21, MCP47FVB02, MCP47FVB12, + MCP47FVB22 can be found here: + https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf + Datasheet for MCP47FEB04, MCP47FEB14, MCP47FEB24, MCP47FEB08, MCP47FEB18, + MCP47FEB28, MCP47FVB04, MCP47FVB14, MCP47FVB24, MCP47FVB08, MCP47FVB18, + MCP47FVB28 can be found here: + https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf + + +------------+--------------+-------------+-------------+------------+ + | Device | Resolution | Channels | Vref number | Memory | + |------------|--------------|-------------|-------------|------------| + | MCP47FEB01 | 8-bit | 1 | 1 | EEPROM | + | MCP47FEB11 | 10-bit | 1 | 1 | EEPROM | + | MCP47FEB21 | 12-bit | 1 | 1 | EEPROM | + |------------|--------------|-------------|-------------|------------| + | MCP47FEB02 | 8-bit | 2 | 1 | EEPROM | + | MCP47FEB12 | 10-bit | 2 | 1 | EEPROM | + | MCP47FEB22 | 12-bit | 2 | 1 | EEPROM | + |------------|--------------|-------------|-------------|------------| + | MCP47FVB01 | 8-bit | 1 | 1 | RAM | + | MCP47FVB11 | 10-bit | 1 | 1 | RAM | + | MCP47FVB21 | 12-bit | 1 | 1 | RAM | + |------------|--------------|-------------|-------------|------------| + | MCP47FVB02 | 8-bit | 2 | 1 | RAM | + | MCP47FVB12 | 10-bit | 2 | 1 | RAM | + | MCP47FVB22 | 12-bit | 2 | 1 | RAM | + |------------|--------------|-------------|-------------|------------| + | MCP47FVB04 | 8-bit | 4 | 2 | RAM | + | MCP47FVB14 | 10-bit | 4 | 2 | RAM | + | MCP47FVB24 | 12-bit | 4 | 2 | RAM | + |------------|--------------|-------------|-------------|------------| + | MCP47FVB08 | 8-bit | 8 | 2 | RAM | + | MCP47FVB18 | 10-bit | 8 | 2 | RAM | + | MCP47FVB28 | 12-bit | 8 | 2 | RAM | + |------------|--------------|-------------|-------------|------------| + | MCP47FEB04 | 8-bit | 4 | 2 | EEPROM | + | MCP47FEB14 | 10-bit | 4 | 2 | EEPROM | + | MCP47FEB24 | 12-bit | 4 | 2 | EEPROM | + |------------|--------------|-------------|-------------|------------| + | MCP47FEB08 | 8-bit | 8 | 2 | EEPROM | + | MCP47FEB18 | 10-bit | 8 | 2 | EEPROM | + | MCP47FEB28 | 12-bit | 8 | 2 | EEPROM | + +------------+--------------+-------------+-------------+------------+ + +properties: + compatible: + enum: + - microchip,mcp47feb01 + - microchip,mcp47feb11 + - microchip,mcp47feb21 + - microchip,mcp47feb02 + - microchip,mcp47feb12 + - microchip,mcp47feb22 + - microchip,mcp47fvb01 + - microchip,mcp47fvb11 + - microchip,mcp47fvb21 + - microchip,mcp47fvb02 + - microchip,mcp47fvb12 + - microchip,mcp47fvb22 + - microchip,mcp47fvb04 + - microchip,mcp47fvb14 + - microchip,mcp47fvb24 + - microchip,mcp47fvb08 + - microchip,mcp47fvb18 + - microchip,mcp47fvb28 + - microchip,mcp47feb04 + - microchip,mcp47feb14 + - microchip,mcp47feb24 + - microchip,mcp47feb08 + - microchip,mcp47feb18 + - microchip,mcp47feb28 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + vdd-supply: + description: + Provides power to the chip and it could be used as reference voltage. The + voltage is used to calculate scale. For parts without EEPROM at powerup + this will be the selected as voltage reference. + + vref-supply: + description: | + Vref pin (it could be found as Vref0 into the datasheet) may be used as a + voltage reference when this supply is specified. The internal reference + will be taken into account for voltage reference besides VDD if this supply + does not exist. + + This supply will be voltage reference for the following outputs: + - for single-channel device: Vout0; + - for dual-channel device: Vout0, Vout1; + - for quad-channel device: Vout0, Vout2; + - for octal-channel device: Vout0, Vout2, Vout6, Vout8; + + vref1-supply: + description: | + Vref1 pin may be used as a voltage reference when this supply is specified. + The internal reference will be taken into account for voltage reference + beside VDD if this supply does not exist. + + This supply will be voltage reference for the following outputs: + - for quad-channel device: Vout1, Vout3; + - for octal-channel device: Vout1, Vout3, Vout5, Vout7; + + lat-gpios: + description: + LAT pin to be used as a hardware trigger to synchronously update the DAC + channels. The pin is active Low. It could be also found as LAT0 in + datasheet. + maxItems: 1 + + lat1-gpios: + description: + LAT1 pin to be used as a hardware trigger to synchronously update the odd + DAC channels on devices with 4 and 8 channels. The pin is active Low. + maxItems: 1 + + microchip,vref-buffered: + type: boolean + description: + Enable buffering of the external Vref/Vref0 pin in cases where the + external reference voltage does not have sufficient current capability in + order not to drop it’s voltage when connected to the internal resistor + ladder circuit. + + microchip,vref1-buffered: + type: boolean + description: + Enable buffering of the external Vref1 pin in cases where the external + reference voltage does not have sufficient current capability in order not + to drop it’s voltage when connected to the internal resistor ladder + circuit. + +patternProperties: + "^channel@[0-7]$": + $ref: dac.yaml + type: object + description: Voltage output channel. + + properties: + reg: + description: The channel number. + minItems: 1 + maxItems: 8 + + label: + description: Unique name to identify which channel this is. + + required: + - reg + + unevaluatedProperties: false + +required: + - compatible + - reg + - vdd-supply + +allOf: + - if: + properties: + compatible: + contains: + enum: + - microchip,mcp47feb01 + - microchip,mcp47feb11 + - microchip,mcp47feb21 + - microchip,mcp47fvb01 + - microchip,mcp47fvb11 + - microchip,mcp47fvb21 + then: + properties: + lat1-gpios: false + vref1-supply: false + microchip,vref1-buffered: false + channel@0: + properties: + reg: + const: 0 + patternProperties: + "^channel@[1-7]$": false + - if: + properties: + compatible: + contains: + enum: + - microchip,mcp47feb02 + - microchip,mcp47feb12 + - microchip,mcp47feb22 + - microchip,mcp47fvb02 + - microchip,mcp47fvb12 + - microchip,mcp47fvb22 + then: + properties: + lat1-gpios: false + vref1-supply: false + microchip,vref1-buffered: false + patternProperties: + "^channel@[0-1]$": + properties: + reg: + enum: [0, 1] + "^channel@[2-7]$": false + - if: + properties: + compatible: + contains: + enum: + - microchip,mcp47fvb04 + - microchip,mcp47fvb14 + - microchip,mcp47fvb24 + - microchip,mcp47feb04 + - microchip,mcp47feb14 + - microchip,mcp47feb24 + then: + patternProperties: + "^channel@[0-3]$": + properties: + reg: + enum: [0, 1, 2, 3] + "^channel@[4-7]$": false + - if: + properties: + compatible: + contains: + enum: + - microchip,mcp47fvb08 + - microchip,mcp47fvb18 + - microchip,mcp47fvb28 + - microchip,mcp47feb08 + - microchip,mcp47feb18 + - microchip,mcp47feb28 + then: + patternProperties: + "^channel@[0-7]$": + properties: + reg: + enum: [0, 1, 2, 3, 4, 5, 6, 7] + - if: + not: + required: + - vref-supply + then: + properties: + microchip,vref-buffered: false + - if: + not: + required: + - vref1-supply + then: + properties: + microchip,vref1-buffered: false + +additionalProperties: false + +examples: + - | + i2c { + + #address-cells = <1>; + #size-cells = <0>; + dac@0 { + compatible = "microchip,mcp47feb02"; + reg = <0>; + vdd-supply = <&vdac_vdd>; + vref-supply = <&vref_reg>; + + #address-cells = <1>; + #size-cells = <0>; + channel@0 { + reg = <0>; + label = "Adjustable_voltage_ch0"; + }; + + channel@1 { + reg = <0x1>; + label = "Adjustable_voltage_ch1"; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml b/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml index 5f950ee9aec7..be69b9c68e74 100644 --- a/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml +++ b/Documentation/devicetree/bindings/iio/frequency/adi,adf4377.yaml @@ -40,6 +40,12 @@ properties: items: - const: ref_in + '#clock-cells': + const: 0 + + clock-output-names: + maxItems: 1 + chip-enable-gpios: description: GPIO that controls the Chip Enable Pin. @@ -97,6 +103,8 @@ examples: spi-max-frequency = <10000000>; clocks = <&adf4377_ref_in>; clock-names = "ref_in"; + #clock-cells = <0>; + clock-output-names = "adf4377"; }; }; ... diff --git a/Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml b/Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml new file mode 100644 index 000000000000..e82897ffac3b --- /dev/null +++ b/Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml @@ -0,0 +1,132 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/pressure/honeywell,abp2030pa.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Honeywell abp2030pa pressure sensor + +maintainers: + - Petre Rodan + +description: | + Honeywell pressure sensor of model abp2030pa. + + This sensor has an I2C and SPI interface. + + There are many models with different pressure ranges available. The vendor + calls them "ABP2 series". All of them have an identical programming model and + differ in the pressure range and measurement unit. + + To support different models one needs to specify its pressure triplet. + + For custom silicon chips not covered by the Honeywell ABP2 series datasheet, + the pressure values can be specified manually via honeywell,pmin-pascal and + honeywell,pmax-pascal. + + Specifications about the devices can be found at: + https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/basic-abp2-series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf + +properties: + compatible: + const: honeywell,abp2030pa + + reg: + maxItems: 1 + + interrupts: + description: + Optional interrupt for indicating end of conversion. + SPI variants of ABP2 chips do not provide this feature. + maxItems: 1 + + honeywell,pressure-triplet: + description: | + Case-sensitive five character string that defines pressure range, unit + and type as part of the device nomenclature. In the unlikely case of a + custom chip, unset and provide pmin-pascal and pmax-pascal instead. + enum: [001BA, 1.6BA, 2.5BA, 004BA, 006BA, 008BA, 010BA, 012BA, 001BD, + 1.6BD, 2.5BD, 004BD, 001BG, 1.6BG, 2.5BG, 004BG, 006BG, 008BG, + 010BG, 012BG, 001GG, 1.2GG, 100KA, 160KA, 250KA, 001KD, 1.6KD, + 2.5KD, 004KD, 006KD, 010KD, 016KD, 025KD, 040KD, 060KD, 100KD, + 160KD, 250KD, 400KD, 001KG, 1.6KG, 2.5KG, 004KG, 006KG, 010KG, + 016KG, 025KG, 040KG, 060KG, 100KG, 160KG, 250KG, 400KG, 600KG, + 800KG, 250LD, 600LD, 600LG, 2.5MD, 006MD, 010MD, 016MD, 025MD, + 040MD, 060MD, 100MD, 160MD, 250MD, 400MD, 600MD, 006MG, 010MG, + 016MG, 025MG, 040MG, 060MG, 100MG, 160MG, 250MG, 400MG, 600MG, + 001ND, 002ND, 004ND, 005ND, 010ND, 020ND, 030ND, 002NG, 004NG, + 005NG, 010NG, 020NG, 030NG, 015PA, 030PA, 060PA, 100PA, 150PA, + 175PA, 001PD, 005PD, 015PD, 030PD, 060PD, 001PG, 005PG, 015PG, + 030PG, 060PG, 100PG, 150PG, 175PG] + $ref: /schemas/types.yaml#/definitions/string + + honeywell,pmin-pascal: + description: + Minimum pressure value the sensor can measure in pascal. + + honeywell,pmax-pascal: + description: + Maximum pressure value the sensor can measure in pascal. + + spi-max-frequency: + maximum: 800000 + + vdd-supply: true + +required: + - compatible + - reg + - vdd-supply + +oneOf: + - required: + - honeywell,pressure-triplet + - required: + - honeywell,pmin-pascal + - honeywell,pmax-pascal + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml + - if: + required: + - honeywell,pressure-triplet + then: + properties: + honeywell,pmin-pascal: false + honeywell,pmax-pascal: false + +additionalProperties: false + +examples: + - | + #include + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pressure@18 { + compatible = "honeywell,abp2030pa"; + reg = <0x18>; + interrupt-parent = <&gpio3>; + interrupts = <21 IRQ_TYPE_EDGE_RISING>; + + honeywell,pressure-triplet = "001BA"; + vdd-supply = <&vcc_3v3>; + }; + }; + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + pressure@0 { + compatible = "honeywell,abp2030pa"; + reg = <0>; + spi-max-frequency = <800000>; + + honeywell,pressure-triplet = "001PD"; + vdd-supply = <&vcc_3v3>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/iio/proximity/rfdigital,rfd77402.yaml b/Documentation/devicetree/bindings/iio/proximity/rfdigital,rfd77402.yaml new file mode 100644 index 000000000000..1ef6326b209e --- /dev/null +++ b/Documentation/devicetree/bindings/iio/proximity/rfdigital,rfd77402.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/proximity/rfdigital,rfd77402.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RF Digital RFD77402 ToF sensor + +maintainers: + - Shrikant Raskar + +description: + The RF Digital RFD77402 is a Time-of-Flight (ToF) proximity and distance + sensor providing up to 200 mm range measurement over an I2C interface. + +properties: + compatible: + const: rfdigital,rfd77402 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + description: + Interrupt asserted when a new distance measurement is available. + + vdd-supply: + description: Regulator that provides power to the sensor. + +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | + #include + i2c { + #address-cells = <1>; + #size-cells = <0>; + + proximity@4c { + compatible = "rfdigital,rfd77402"; + reg = <0x4c>; + vdd-supply = <&vdd_3v3>; + interrupt-parent = <&gpio>; + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/input/focaltech,ft8112.yaml b/Documentation/devicetree/bindings/input/focaltech,ft8112.yaml new file mode 100644 index 000000000000..197f30b14d45 --- /dev/null +++ b/Documentation/devicetree/bindings/input/focaltech,ft8112.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/focaltech,ft8112.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: FocalTech FT8112 touchscreen controller + +maintainers: + - Daniel Peng + +description: + Supports the FocalTech FT8112 touchscreen controller. + This touchscreen controller uses the i2c-hid protocol with a reset GPIO. + +allOf: + - $ref: /schemas/input/touchscreen/touchscreen.yaml# + +properties: + compatible: + enum: + - focaltech,ft8112 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + panel: true + + reset-gpios: + maxItems: 1 + + vcc33-supply: true + + vccio-supply: true + +required: + - compatible + - reg + - interrupts + - vcc33-supply + +additionalProperties: false + +examples: + - | + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@38 { + compatible = "focaltech,ft8112"; + reg = <0x38>; + + interrupt-parent = <&pio>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + + reset-gpios = <&pio 126 GPIO_ACTIVE_LOW>; + vcc33-supply = <&pp3300_tchscr_x>; + }; + }; diff --git a/Documentation/devicetree/bindings/input/google,goldfish-events-keypad.yaml b/Documentation/devicetree/bindings/input/google,goldfish-events-keypad.yaml new file mode 100644 index 000000000000..4e3a010a70c5 --- /dev/null +++ b/Documentation/devicetree/bindings/input/google,goldfish-events-keypad.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/google,goldfish-events-keypad.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Android Goldfish Events Keypad + +maintainers: + - Kuan-Wei Chiu + +allOf: + - $ref: input.yaml# + +description: + Android goldfish events keypad device generated by android emulator. + +properties: + compatible: + const: google,goldfish-events-keypad + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + keypad@9040000 { + compatible = "google,goldfish-events-keypad"; + reg = <0x9040000 0x1000>; + interrupts = <5>; + }; diff --git a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml index f978cf965a4d..f2543d6faefd 100644 --- a/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml +++ b/Documentation/devicetree/bindings/input/qcom,pm8941-pwrkey.yaml @@ -12,11 +12,18 @@ maintainers: properties: compatible: - enum: - - qcom,pm8941-pwrkey - - qcom,pm8941-resin - - qcom,pmk8350-pwrkey - - qcom,pmk8350-resin + oneOf: + - enum: + - qcom,pm8941-pwrkey + - qcom,pm8941-resin + - qcom,pmk8350-pwrkey + - qcom,pmk8350-resin + - items: + - const: qcom,pmm8654au-pwrkey + - const: qcom,pmk8350-pwrkey + - items: + - const: qcom,pmm8654au-resin + - const: qcom,pmk8350-resin interrupts: maxItems: 1 diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml index 7d3edb58f72d..6f90522de8c0 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml @@ -39,6 +39,7 @@ properties: - edt,edt-ft5406 - edt,edt-ft5506 - evervision,ev-ft5726 + - focaltech,ft3518 - focaltech,ft5426 - focaltech,ft5452 - focaltech,ft6236 diff --git a/Documentation/devicetree/bindings/input/touchscreen/ilitek,ili210x.yaml b/Documentation/devicetree/bindings/input/touchscreen/ilitek,ili210x.yaml new file mode 100644 index 000000000000..c47d7752a194 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/ilitek,ili210x.yaml @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/touchscreen/ilitek,ili210x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Ilitek ILI21xx/ILI251x V3/V6 touch screen controller with i2c interface + +maintainers: + - Frank Li + - Marek Vasut + +properties: + compatible: + enum: + - ilitek,ili210x + - ilitek,ili2117 + - ilitek,ili2120 + - ilitek,ili251x + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + wakeup-source: true + +required: + - compatible + - reg + +allOf: + - $ref: touchscreen.yaml + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@41 { + compatible = "ilitek,ili2120"; + reg = <0x41>; + }; + }; diff --git a/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml b/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml index 0ef79343bf9a..dfaffbc398d3 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/imagis,ist3038c.yaml @@ -55,7 +55,9 @@ allOf: properties: compatible: contains: - const: imagis,ist3032c + enum: + - imagis,ist3032c + - imagis,ist3038 then: properties: linux,keycodes: false diff --git a/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml b/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml index e7ee7a0d74c4..978afaa4fcef 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/sitronix,st1232.yaml @@ -14,9 +14,13 @@ allOf: properties: compatible: - enum: - - sitronix,st1232 - - sitronix,st1633 + oneOf: + - enum: + - sitronix,st1232 + - sitronix,st1633 + - items: + - const: sitronix,st1624 + - const: sitronix,st1633 reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml b/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml index a595df3ea802..d9cb53e86512 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml @@ -53,6 +53,9 @@ properties: how much time to wait (in milliseconds) before reading again the values from the tsc2007. + "#io-channel-cells": + const: 1 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml index fa27c6754ca4..6441d21223ca 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml +++ b/Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml @@ -23,9 +23,6 @@ properties: # Hynitron cstxxx series touchscreen controller - hynitron,cst340 # Ilitek I2C Touchscreen Controller - - ilitek,ili210x - - ilitek,ili2117 - - ilitek,ili2120 - ilitek,ili2130 - ilitek,ili2131 - ilitek,ili2132 @@ -33,7 +30,6 @@ properties: - ilitek,ili2322 - ilitek,ili2323 - ilitek,ili2326 - - ilitek,ili251x - ilitek,ili2520 - ilitek,ili2521 # MAXI MAX11801 Resistive touch screen controller with i2c interface diff --git a/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml b/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml index 017c8478b2a7..1fb8ccb558fb 100644 --- a/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml +++ b/Documentation/devicetree/bindings/interconnect/mediatek,mt8183-emi.yaml @@ -40,6 +40,7 @@ properties: enum: - mediatek,mt8183-emi - mediatek,mt8195-emi + - mediatek,mt8196-emi '#interconnect-cells': const: 1 diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 17b09292000e..ce79521bb1ef 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -25,6 +25,7 @@ properties: - const: qcom,msm8998-bwmon # BWMON v4 - items: - enum: + - qcom,glymur-cpu-bwmon - qcom,kaanapali-cpu-bwmon - qcom,qcm2290-cpu-bwmon - qcom,qcs615-cpu-bwmon diff --git a/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml index 9d762b2a1fcf..e06404828824 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,qcs615-rpmh.yaml @@ -27,7 +27,6 @@ properties: - qcom,qcs615-config-noc - qcom,qcs615-dc-noc - qcom,qcs615-gem-noc - - qcom,qcs615-ipa-virt - qcom,qcs615-mc-virt - qcom,qcs615-mmss-noc - qcom,qcs615-system-noc @@ -46,7 +45,6 @@ allOf: contains: enum: - qcom,qcs615-camnoc-virt - - qcom,qcs615-ipa-virt - qcom,qcs615-mc-virt then: properties: diff --git a/Documentation/devicetree/bindings/leds/ams,as3668.yaml b/Documentation/devicetree/bindings/leds/ams,as3668.yaml new file mode 100644 index 000000000000..d1d73782da55 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ams,as3668.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ams,as3668.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Osram 4-channel i2c LED driver + +maintainers: + - Lukas Timmermann + +description: + This IC can drive up to four separate LEDs. + Having four channels suggests it could be used with a single RGBW LED. + +properties: + compatible: + const: ams,as3668 + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^led@[0-3]$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + maxItems: 1 + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@42 { + compatible = "ams,as3668"; + reg = <0x42>; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0x0>; + function = LED_FUNCTION_STATUS; + color = ; + }; + + led@1 { + reg = <0x1>; + function = LED_FUNCTION_STATUS; + color = ; + }; + }; + }; + diff --git a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml index a8490781011d..a54448cfdb38 100644 --- a/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml +++ b/Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml @@ -98,8 +98,8 @@ properties: description: | Over-voltage protection limit. This property is for WLED4 only. $ref: /schemas/types.yaml#/definitions/uint32 - enum: [ 18100, 19600, 29600, 31100 ] - default: 29600 + minimum: 17800 + maximum: 31100 qcom,num-strings: description: | @@ -239,6 +239,26 @@ allOf: minimum: 0 maximum: 4095 + - if: + properties: + compatible: + contains: + enum: + - qcom,pmi8950-wled + - qcom,pmi8994-wled + + then: + properties: + qcom,ovp-millivolt: + enum: [ 17800, 19400, 29500, 31000 ] + default: 29500 + + else: + properties: + qcom,ovp-millivolt: + enum: [ 18100, 19600, 29600, 31100 ] + default: 29600 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml index bb40bb9e036e..7bfc3d807aca 100644 --- a/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml +++ b/Documentation/devicetree/bindings/leds/leds-class-multicolor.yaml @@ -21,7 +21,7 @@ description: | properties: $nodename: - pattern: "^multi-led(@[0-9a-f])?$" + pattern: "^multi-led(@[0-9a-f]|-[0-9]+)?$" color: description: | diff --git a/Documentation/devicetree/bindings/leds/leds-is31fl32xx.txt b/Documentation/devicetree/bindings/leds/leds-is31fl32xx.txt index 926c2117942c..7082ed186dd9 100644 --- a/Documentation/devicetree/bindings/leds/leds-is31fl32xx.txt +++ b/Documentation/devicetree/bindings/leds/leds-is31fl32xx.txt @@ -10,6 +10,7 @@ Required properties: issi,is31fl3235 issi,is31fl3218 issi,is31fl3216 + issi,is31fl3293 si-en,sn3218 si-en,sn3216 - reg: I2C slave address diff --git a/Documentation/devicetree/bindings/leds/leds-lm3697.txt b/Documentation/devicetree/bindings/leds/leds-lm3697.txt deleted file mode 100644 index 221b37b6049b..000000000000 --- a/Documentation/devicetree/bindings/leds/leds-lm3697.txt +++ /dev/null @@ -1,73 +0,0 @@ -* Texas Instruments - LM3697 Highly Efficient White LED Driver - -The LM3697 11-bit LED driver provides high- -performance backlight dimming for 1, 2, or 3 series -LED strings while delivering up to 90% efficiency. - -This device is suitable for display and keypad lighting - -Required properties: - - compatible: - "ti,lm3697" - - reg : I2C slave address - - #address-cells : 1 - - #size-cells : 0 - -Optional properties: - - enable-gpios : GPIO pin to enable/disable the device - - vled-supply : LED supply - -Required child properties: - - reg : 0 - LED is Controlled by bank A - 1 - LED is Controlled by bank B - - led-sources : Indicates which HVLED string is associated to which - control bank. This is a zero based property so - HVLED1 = 0, HVLED2 = 1, HVLED3 = 2. - Additional information is contained - in Documentation/devicetree/bindings/leds/common.txt - -Optional child properties: - - ti,brightness-resolution - see Documentation/devicetree/bindings/mfd/ti-lmu.txt - - ramp-up-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt - - ramp-down-us: see Documentation/devicetree/bindings/mfd/ti-lmu.txt - - label : see Documentation/devicetree/bindings/leds/common.txt - - linux,default-trigger : - see Documentation/devicetree/bindings/leds/common.txt - -Example: - -HVLED string 1 and 3 are controlled by control bank A and HVLED 2 string is -controlled by control bank B. - -led-controller@36 { - compatible = "ti,lm3697"; - #address-cells = <1>; - #size-cells = <0>; - reg = <0x36>; - - enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; - vled-supply = <&vbatt>; - - led@0 { - reg = <0>; - led-sources = <0 2>; - ti,brightness-resolution = <2047>; - ramp-up-us = <5000>; - ramp-down-us = <1000>; - label = "white:first_backlight_cluster"; - linux,default-trigger = "backlight"; - }; - - led@1 { - reg = <1>; - led-sources = <1>; - ti,brightness-resolution = <255>; - ramp-up-us = <500>; - ramp-down-us = <1000>; - label = "white:second_backlight_cluster"; - linux,default-trigger = "backlight"; - }; -} - -For more product information please see the link below: -https://www.ti.com/lit/ds/symlink/lm3697.pdf diff --git a/Documentation/devicetree/bindings/leds/leds-lp5860.yaml b/Documentation/devicetree/bindings/leds/leds-lp5860.yaml new file mode 100644 index 000000000000..1ccba4854159 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/leds-lp5860.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/leds-lp5860.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: LED driver for LP5860 RGB LED from Texas Instruments. + +maintainers: + - Steffen Trumtrar + +description: | + The LP5860 is multi-channel, I2C and SPI RGB LED Driver that can group RGB LEDs + into a LED group or control them individually. + + For more product information please see the link below: + https://www.ti.com/lit/ds/symlink/lp5860.pdf + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + enum: + - ti,lp5860 + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + '^multi-led@[0-9a-f]+$': + type: object + $ref: leds-class-multicolor.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 0 + maximum: 198 + description: + This property denotes the LED module number that is used + for the child node. + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + patternProperties: + "^led@[0-9a-f]+$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + maxItems: 1 + + required: + - reg + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@0 { + compatible = "ti,lp5860"; + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + + multi-led@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0>; + color = ; + + led@0 { + reg = <0x0>; + color = ; + }; + + led@1 { + reg = <0x1>; + color = ; + }; + + led@2 { + reg = <0x2>; + color = ; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml index c4b7e57b2518..3da0fe532e74 100644 --- a/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml +++ b/Documentation/devicetree/bindings/leds/leds-qcom-lpg.yaml @@ -43,6 +43,7 @@ properties: - items: - enum: - qcom,pm8550-pwm + - qcom,pmh0101-pwm - const: qcom,pm8350c-pwm - items: - enum: diff --git a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml index 05250aefd385..3bfa24ff58cd 100644 --- a/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml +++ b/Documentation/devicetree/bindings/leds/qcom,spmi-flash-led.yaml @@ -29,6 +29,7 @@ properties: - qcom,pm8150l-flash-led - qcom,pm8350c-flash-led - qcom,pm8550-flash-led + - qcom,pmh0101-flash-led - qcom,pmi8998-flash-led - const: qcom,spmi-flash-led diff --git a/Documentation/devicetree/bindings/leds/ti,lm3697.yaml b/Documentation/devicetree/bindings/leds/ti,lm3697.yaml new file mode 100644 index 000000000000..a9f839470a84 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ti,lm3697.yaml @@ -0,0 +1,125 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ti,lm3697.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LM3697 Highly Efficient White LED Driver + +maintainers: + - Dan Murphy + +description: > + The LM3697 11-bit LED driver provides high-performance backlight dimming for + 1, 2, or 3 series LED strings while delivering up to 90% efficiency. + + This device is suitable for display and keypad lighting. + +properties: + compatible: + const: ti,lm3697 + + reg: + maxItems: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + + enable-gpios: + description: GPIO pin to enable or disable the device. + maxItems: 1 + + vled-supply: + description: LED supply for the device. + +patternProperties: + '^led@[01]$': + description: LED control bank nodes. + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + description: Control bank selection (0 = bank A, 1 = bank B). + maximum: 1 + + led-sources: + description: > + HVLED strings associated with this control bank: + + 0 - HVLED1 + 1 - HVLED2 + 2 - HVLED3 + minItems: 1 + maxItems: 3 + items: + maximum: 2 + + ti,brightness-resolution: + description: Brightness resolution for the LED string. + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 2047 + + ramp-up-us: + description: Ramp-up time in microseconds. + minimum: 117 + maximum: 2048 + + ramp-down-us: + description: Ramp-down time in microseconds. + minimum: 117 + maximum: 2048 + + required: + - reg + - led-sources + +required: + - compatible + - reg + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@36 { + compatible = "ti,lm3697"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + + enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>; + vled-supply = <&vbatt>; + + led@0 { + reg = <0>; + led-sources = <0 2>; + ti,brightness-resolution = <2047>; + ramp-up-us = <500>; + ramp-down-us = <1000>; + label = "white:first_backlight_cluster"; + linux,default-trigger = "backlight"; + }; + + led@1 { + reg = <1>; + led-sources = <1>; + ti,brightness-resolution = <255>; + ramp-up-us = <500>; + ramp-down-us = <1000>; + label = "white:second_backlight_cluster"; + linux,default-trigger = "backlight"; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/leds/ti,lp5812.yaml b/Documentation/devicetree/bindings/leds/ti,lp5812.yaml new file mode 100644 index 000000000000..de34bff441c7 --- /dev/null +++ b/Documentation/devicetree/bindings/leds/ti,lp5812.yaml @@ -0,0 +1,246 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/ti,lp5812.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI LP5812 4x3 Matrix RGB LED Driver with Autonomous Control + +maintainers: + - Nam Tran + +description: | + The LP5812 is a 4x3 matrix RGB LED driver with I2C interface + and autonomous animation engine control. + For more product information please see the link below: + https://www.ti.com/product/LP5812#tech-docs + +properties: + compatible: + const: ti,lp5812 + + reg: + maxItems: 1 + + ti,scan-mode: + description: | + Selects the LED scan mode of the LP5812. The device supports + three modes: + - Direct-drive mode (by default if 'ti,scan-mode' is omitted) + drives up to 4 LEDs directly by internal current sinks (LED0-LED3). + - TCM-drive mode ("tcm::") drives up to 12 LEDs + (4 RGB) using 1-4 scan multiplexing. The specifies the number + of scans (1-4), and defines the scan order of the outputs. + - Mix-drive mode ("mix:::") combines + direct-drive and TCM-drive outputs. The specifies the number + of scans, selects the direct-drive outputs, and + defines the scan order. + $ref: /schemas/types.yaml#/definitions/string + pattern: '^(tcm|mix):[1-4](:[0-3]){1,4}$' + + vcc-supply: + description: Regulator providing power to the 'VCC' pin. + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^led@[0-3]$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 0 + maximum: 3 + + required: + - reg + + "^multi-led@[4-7]$": + type: object + $ref: leds-class-multicolor.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 4 + maximum: 7 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + + patternProperties: + "^led@[4-9a-f]$": + type: object + $ref: common.yaml# + unevaluatedProperties: false + + properties: + reg: + minimum: 4 + maximum: 15 + + required: + - reg + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + led-controller@1b { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,lp5812"; + reg = <0x1b>; + ti,scan-mode = "tcm:4:0:1:2:3"; + vcc-supply = <&vdd_3v3_reg>; + + led@0 { + reg = <0x0>; + label = "LED0"; + led-max-microamp = <25500>; + }; + + led@1 { + reg = <0x1>; + label = "LED1"; + led-max-microamp = <25500>; + }; + + led@2 { + reg = <0x2>; + label = "LED2"; + led-max-microamp = <25500>; + }; + + led@3 { + reg = <0x3>; + label = "LED3"; + led-max-microamp = <25500>; + }; + + multi-led@4 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x4>; + color = ; + label = "LED_A"; + + led@4 { + reg = <0x4>; + color = ; + led-max-microamp = <25500>; + }; + + led@5 { + reg = <0x5>; + color = ; + led-max-microamp = <25500>; + }; + + led@6 { + reg = <0x6>; + color = ; + led-max-microamp = <25500>; + }; + }; + + multi-led@5 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x5>; + color = ; + label = "LED_B"; + + led@7 { + reg = <0x7>; + color = ; + led-max-microamp = <25500>; + }; + + led@8 { + reg = <0x8>; + color = ; + led-max-microamp = <25500>; + }; + + led@9 { + reg = <0x9>; + color = ; + led-max-microamp = <25500>; + }; + }; + + multi-led@6 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x6>; + color = ; + label = "LED_C"; + + led@a { + reg = <0xa>; + color = ; + led-max-microamp = <25500>; + }; + + led@b { + reg = <0xb>; + color = ; + led-max-microamp = <25500>; + }; + + led@c { + reg = <0xc>; + color = ; + led-max-microamp = <25500>; + }; + }; + + multi-led@7 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0x7>; + color = ; + label = "LED_D"; + + led@d { + reg = <0xd>; + color = ; + led-max-microamp = <25500>; + }; + + led@e { + reg = <0xe>; + color = ; + led-max-microamp = <25500>; + }; + + led@f { + reg = <0xf>; + color = ; + led-max-microamp = <25500>; + }; + }; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml new file mode 100644 index 000000000000..7b1c5165e64e --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/mediatek,mt8196-vcp-mbox.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/mediatek,mt8196-vcp-mbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek Video Companion Processor (VCP) mailbox + +maintainers: + - Jjian Zhou + +description: + The MTK VCP mailbox enables the SoC to communicate with the VCP by passing + messages through 64 32-bit wide registers. It has 32 interrupt vectors in + either direction for signalling purposes. + +properties: + compatible: + enum: + - mediatek,mt8196-vcp-mbox + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#mbox-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + mailbox@31b80000 { + compatible = "mediatek,mt8196-vcp-mbox"; + reg = <0x31b80000 0x1000>; + interrupts = ; + #mbox-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml index 1332aab9a888..5f2ec74c1b29 100644 --- a/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml @@ -11,7 +11,11 @@ maintainers: properties: compatible: - const: microchip,mpfs-mailbox + oneOf: + - items: + - const: microchip,pic64gx-mailbox + - const: microchip,mpfs-mailbox + - const: microchip,mpfs-mailbox reg: oneOf: diff --git a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml index b526f9c0c272..bf6ab4e7050c 100644 --- a/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/sprd-mailbox.yaml @@ -16,6 +16,7 @@ properties: enum: - sprd,sc9860-mailbox - sprd,sc9863a-mailbox + - sprd,ums9230-mailbox reg: items: diff --git a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml index 04d6473d666f..a5205ee5ad0f 100644 --- a/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/xlnx,zynqmp-ipi-mailbox.yaml @@ -11,6 +11,17 @@ description: | messaging between two Xilinx Zynq UltraScale+ MPSoC IPI agents. Each IPI agent owns registers used for notification and buffers for message. + For Versal devices, there are two types of IPI channels: + - Buffered channels: Support message passing and require the "msg" + register region to be present on both the host and remote IPI agents. + - Buffer-less channels: Support notification only and do not require the + "msg" register region. For these channels, the "msg" region should be + omitted. + + For message passing, both the host and remote IPI agents must define the "msg" + register region. If either agent omits the "msg" region, only notification + based communication is possible. + +-------------------------------------+ | Xilinx ZynqMP IPI Controller | +-------------------------------------+ diff --git a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml index da1887d7a8fe..a87f31fce019 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml +++ b/Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml @@ -130,6 +130,23 @@ patternProperties: - description: silicon id information registers - description: unique chip id registers + '^smp-memram@[0-9a-f]+$': + description: Memory region used for the AST2600's custom SMP bringup protocol + type: object + additionalProperties: false + + properties: + compatible: + const: aspeed,ast2600-smpmem + + reg: + description: The SMP memory region + maxItems: 1 + + required: + - compatible + - reg + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml index 4aa36903e755..dfee8707bac2 100644 --- a/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml +++ b/Documentation/devicetree/bindings/mfd/atmel,hlcdc.yaml @@ -25,6 +25,7 @@ properties: - atmel,sama5d4-hlcdc - microchip,sam9x60-hlcdc - microchip,sam9x75-xlcdc + - microchip,sama7d65-xlcdc reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml index c7d6cf96796c..5e5dec2f6564 100644 --- a/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml +++ b/Documentation/devicetree/bindings/mfd/atmel,sama5d2-flexcom.yaml @@ -20,6 +20,7 @@ properties: - const: atmel,sama5d2-flexcom - items: - enum: + - microchip,lan9691-flexcom - microchip,sam9x7-flexcom - microchip,sama7d65-flexcom - microchip,sama7g5-flexcom diff --git a/Documentation/devicetree/bindings/mfd/bitmain,bm1880-sctrl.yaml b/Documentation/devicetree/bindings/mfd/bitmain,bm1880-sctrl.yaml new file mode 100644 index 000000000000..3cdc90ba421b --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/bitmain,bm1880-sctrl.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/bitmain,bm1880-sctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Bitmain BM1880 System Controller + +maintainers: + - Manivannan Sadhasivam + +properties: + compatible: + items: + - const: bitmain,bm1880-sctrl + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + ranges: true + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + +patternProperties: + '^pinctrl@[0-9a-f]+$': + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: bitmain,bm1880-pinctrl + + '^clock-controller@[0-9a-f]+$': + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: bitmain,bm1880-clk + + '^reset-controller@[0-9a-f]+$': + type: object + additionalProperties: true + + properties: + compatible: + contains: + const: bitmain,bm1880-reset + +required: + - compatible + - reg + - ranges + - '#address-cells' + - '#size-cells' + +additionalProperties: false +... diff --git a/Documentation/devicetree/bindings/mfd/da9055.txt b/Documentation/devicetree/bindings/mfd/da9055.txt index 131a53283e17..d3099bf56002 100644 --- a/Documentation/devicetree/bindings/mfd/da9055.txt +++ b/Documentation/devicetree/bindings/mfd/da9055.txt @@ -15,7 +15,7 @@ The CODEC device in DA9055 has a separate, configurable I2C address and so is instantiated separately from the PMIC. For details on accompanying CODEC I2C device, see the following: -Documentation/devicetree/bindings/sound/da9055.txt +Documentation/devicetree/bindings/sound/trivial-codec.yaml ====== diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml index 6a89b479d10f..05c121b0cb3d 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt6397.yaml @@ -90,6 +90,7 @@ properties: - enum: - mediatek,mt6323-regulator - mediatek,mt6328-regulator + - mediatek,mt6331-regulator - mediatek,mt6358-regulator - mediatek,mt6359-regulator - mediatek,mt6397-regulator diff --git a/Documentation/devicetree/bindings/mfd/mediatek,mt8195-scpsys.yaml b/Documentation/devicetree/bindings/mfd/mediatek,mt8195-scpsys.yaml index 1cb9d6797b92..4cafa381979b 100644 --- a/Documentation/devicetree/bindings/mfd/mediatek,mt8195-scpsys.yaml +++ b/Documentation/devicetree/bindings/mfd/mediatek,mt8195-scpsys.yaml @@ -19,6 +19,7 @@ properties: compatible: items: - enum: + - mediatek,mt6795-scpsys - mediatek,mt6893-scpsys - mediatek,mt8167-scpsys - mediatek,mt8173-scpsys diff --git a/Documentation/devicetree/bindings/mfd/nxp,lpc3220-scb.yaml b/Documentation/devicetree/bindings/mfd/nxp,lpc3220-scb.yaml new file mode 100644 index 000000000000..b993dd15135a --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/nxp,lpc3220-scb.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/nxp,lpc3220-scb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP LPC32xx System Control Block + +maintainers: + - Vladimir Zapolskiy + +description: + NXP LPC32xx SoC series have a System Control Block, which serves for + a multitude of purposes including clock management, DMA muxes, storing + SoC unique ID etc. + +properties: + compatible: + items: + - enum: + - nxp,lpc3220-scb + - const: syscon + - const: simple-mfd + + reg: + maxItems: 1 + + ranges: true + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + +patternProperties: + "^clock-controller@[0-9a-f]+$": + $ref: /schemas/clock/nxp,lpc3220-clk.yaml# + + "^dma-router@[0-9a-f]+$": + $ref: /schemas/dma/nxp,lpc3220-dmamux.yaml# + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + +additionalProperties: false + +examples: + - | + syscon@400040000 { + compatible = "nxp,lpc3220-scb", "syscon", "simple-mfd"; + reg = <0x40004000 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x40004000 0x1000>; + + clock-controller@0 { + compatible = "nxp,lpc3220-clk"; + reg = <0x0 0x114>; + clocks = <&xtal_32k>, <&xtal>; + clock-names = "xtal_32k", "xtal"; + #clock-cells = <1>; + }; + + dma-router@78 { + compatible = "nxp,lpc3220-dmamux"; + reg = <0x78 0x8>; + dma-masters = <&dma>; + #dma-cells = <3>; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml index 65c80e3b4500..e5931d18d998 100644 --- a/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/qcom,spmi-pmic.yaml @@ -77,8 +77,12 @@ properties: - qcom,pmc8180 - qcom,pmc8180c - qcom,pmc8380 + - qcom,pmcx0102 - qcom,pmd8028 - qcom,pmd9635 + - qcom,pmh0101 + - qcom,pmh0104 + - qcom,pmh0110 - qcom,pmi632 - qcom,pmi8950 - qcom,pmi8962 @@ -89,6 +93,7 @@ properties: - qcom,pmk8002 - qcom,pmk8350 - qcom,pmk8550 + - qcom,pmk8850 - qcom,pmm8155au - qcom,pmm8654au - qcom,pmp8074 @@ -101,6 +106,7 @@ properties: - qcom,pmx75 - qcom,smb2351 - qcom,smb2360 + - qcom,smb2370 - const: qcom,spmi-pmic reg: diff --git a/Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml b/Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml index 5454d9403cad..12e738b1270a 100644 --- a/Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml +++ b/Documentation/devicetree/bindings/mfd/qnap,ts433-mcu.yaml @@ -16,6 +16,7 @@ description: properties: compatible: enum: + - qnap,ts133-mcu - qnap,ts233-mcu - qnap,ts433-mcu diff --git a/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml b/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml new file mode 100644 index 000000000000..7c71447200ba --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/rockchip,rk801.yaml @@ -0,0 +1,197 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/rockchip,rk801.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RK801 Power Management Integrated Circuit + +maintainers: + - Joseph Chen + +description: | + Rockchip RK801 series PMIC. This device consists of an i2c controlled MFD + that includes multiple switchable regulators. + +properties: + compatible: + enum: + - rockchip,rk801 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + system-power-controller: + type: boolean + description: + Telling whether or not this PMIC is controlling the system power. + + wakeup-source: + type: boolean + description: + Device can be used as a wakeup source. + + vcc1-supply: + description: + The input supply for dcdc1. + + vcc2-supply: + description: + The input supply for dcdc2. + + vcc3-supply: + description: + The input supply for dcdc3. + + vcc4-supply: + description: + The input supply for dcdc4. + + vcc5-supply: + description: + The input supply for ldo1. + + vcc6-supply: + description: + The input supply for ldo2. + + vcc7-supply: + description: + The input supply for switch. + + regulators: + type: object + patternProperties: + "^(dcdc[1-4]|ldo[1-2]|switch)$": + type: object + $ref: /schemas/regulator/regulator.yaml# + unevaluatedProperties: false + additionalProperties: false + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + #include + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + rk801: pmic@27 { + compatible = "rockchip,rk801"; + reg = <0x27>; + interrupt-parent = <&gpio0>; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_int_l>; + system-power-controller; + wakeup-source; + + vcc1-supply = <&vcc_sys>; + vcc2-supply = <&vcc_sys>; + vcc3-supply = <&vcc_sys>; + vcc4-supply = <&vcc_sys>; + vcc5-supply = <&vcc3v3_sys>; + vcc6-supply = <&vcc3v3_sys>; + vcc7-supply = <&vcc3v3_sys>; + + regulators { + vdd_cpu: dcdc1 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-off-in-suspend; + regulator-suspend-microvolt = <950000>; + }; + }; + + vcc3v3_sys: dcdc2 { + regulator-name = "vcc3v3_sys"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vcc_ddr: dcdc3 { + regulator-name = "vcc_ddr"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-on-in-suspend; + }; + }; + + vdd_logic: dcdc4 { + regulator-name = "vdd_logic"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = <0x1>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-mode = <0x2>; + regulator-off-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vdd0v9_sys: ldo1 { + regulator-name = "vdd0v9_sys"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <900000>; + }; + }; + + vcc_1v8: ldo2 { + regulator-name = "vcc_1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_3v3: switch { + regulator-name = "vcc_3v3"; + regulator-boot-on; + regulator-always-on; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index 55efb83b1495..e57add2bacd3 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml @@ -102,6 +102,8 @@ select: - mstar,msc313-pmsleep - nuvoton,ma35d1-sys - nuvoton,wpcm450-shm + - nxp,s32g2-gpr + - nxp,s32g3-gpr - qcom,apq8064-mmss-sfpb - qcom,apq8064-sps-sic - rockchip,px30-qos @@ -195,6 +197,7 @@ properties: - mediatek,mt2701-pctl-a-syscfg - mediatek,mt2712-pctl-a-syscfg - mediatek,mt6397-pctl-pmic-syscfg + - mediatek,mt7981-topmisc - mediatek,mt7988-topmisc - mediatek,mt8135-pctl-a-syscfg - mediatek,mt8135-pctl-b-syscfg @@ -212,6 +215,8 @@ properties: - mstar,msc313-pmsleep - nuvoton,ma35d1-sys - nuvoton,wpcm450-shm + - nxp,s32g2-gpr + - nxp,s32g3-gpr - qcom,apq8064-mmss-sfpb - qcom,apq8064-sps-sic - rockchip,px30-qos diff --git a/Documentation/devicetree/bindings/misc/google,android-pipe.yaml b/Documentation/devicetree/bindings/misc/google,android-pipe.yaml new file mode 100644 index 000000000000..9e8046fd358d --- /dev/null +++ b/Documentation/devicetree/bindings/misc/google,android-pipe.yaml @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/misc/google,android-pipe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Android Goldfish QEMU Pipe + +maintainers: + - Kuan-Wei Chiu + +description: + Android QEMU pipe virtual device generated by Android emulator. + +properties: + compatible: + const: google,android-pipe + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + pipe@ff018000 { + compatible = "google,android-pipe"; + reg = <0xff018000 0x2000>; + interrupts = <18>; + }; diff --git a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml index 3f6199fc9ae6..d8e47db677cc 100644 --- a/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml +++ b/Documentation/devicetree/bindings/misc/qcom,fastrpc.yaml @@ -18,7 +18,9 @@ description: | properties: compatible: - const: qcom,fastrpc + enum: + - qcom,kaanapali-fastrpc + - qcom,fastrpc label: enum: diff --git a/Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml b/Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml index ec0c2168e4b9..6bcfff970117 100644 --- a/Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml +++ b/Documentation/devicetree/bindings/net/can/nxp,sja1000.yaml @@ -87,6 +87,7 @@ required: allOf: - $ref: can-controller.yaml# + - $ref: /schemas/memory-controllers/mc-peripheral-props.yaml - if: properties: compatible: diff --git a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml index 7d1612acca48..839513d4b499 100644 --- a/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml +++ b/Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml @@ -55,6 +55,7 @@ properties: - qcom,sm8450-qfprom - qcom,sm8550-qfprom - qcom,sm8650-qfprom + - qcom,sm8750-qfprom - qcom,x1e80100-qfprom - const: qcom,qfprom diff --git a/Documentation/devicetree/bindings/phy/apple,atcphy.yaml b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml new file mode 100644 index 000000000000..0acac7e3ee67 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/apple,atcphy.yaml @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/apple,atcphy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Apple Type-C PHY (ATCPHY) + +maintainers: + - Sven Peter + +description: > + The Apple Type-C PHY (ATCPHY) is a combined PHY for USB 2.0, USB 3.x, + USB4/Thunderbolt, and DisplayPort connectivity via Type-C ports found in + Apple Silicon SoCs. + + The PHY handles muxing between these different protocols and also provides the + reset controller for the attached DWC3 USB controller. + + It is designed for USB4 operation and does not handle individual differential + pairs as distinct DisplayPort lanes. Any reference to lane in this binding + hence refers to two differential pairs (RX and TX) as used in USB terminology. + + In order to correctly setup these lanes for the various modes calibration + values copied from Apple's firmware and converted to the format described + below by our bootloader m1n1 are required. Without these only USB2 operation + is possible. + +allOf: + - $ref: /schemas/usb/usb-switch.yaml# + +$defs: + apple,tunable: + $ref: /schemas/types.yaml#/definitions/uint32-matrix + items: + items: + - description: Register offset + - description: Mask to be applied to the register value + - description: Bits to be set after applying the mask + description: > + List of (register offset, mask, value) tuples copied from Apple's Device + Tree by our bootloader m1n1 and used to configure the PHY. These values + even vary for a single product/device and likely contain calibration + values determined by Apple at manufacturing time. + Unless otherwise noted these tunables are always applied to the core + register region. + +properties: + compatible: + oneOf: + - items: + - enum: + - apple,t6000-atcphy + - apple,t6020-atcphy + - apple,t8112-atcphy + - const: apple,t8103-atcphy + - const: apple,t8103-atcphy + + reg: + items: + - description: Common controls for all PHYs (USB2/3/4, DisplayPort, TBT) + - description: DisplayPort Alternate Mode PHY specific controls + - description: Type-C PHY AXI to Apple Fabric interconnect controls + - description: USB2 PHY specific controls + - description: USB3 PIPE interface controls + + reg-names: + items: + - const: core + - const: lpdptx + - const: axi2af + - const: usb2phy + - const: pipehandler + + "#phy-cells": + const: 1 + + "#reset-cells": + const: 0 + + mode-switch: true + orientation-switch: true + + power-domains: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: Outgoing connection to the SS port of the Type-C connector. + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: Incoming endpoint from the USB3 controller. + + port@2: + $ref: /schemas/graph.yaml#/properties/port + description: Incoming endpoint from the DisplayPort controller. + + port@3: + $ref: /schemas/graph.yaml#/properties/port + description: Incoming endpoint from the USB4/Thunderbolt controller. + + apple,tunable-common-a: + $ref: "#/$defs/apple,tunable" + description: > + Common tunables required for all modes, applied before tunable-axi2af. + + apple,tunable-axi2af: + $ref: "#/$defs/apple,tunable" + description: > + AXI to Apple Fabric tunables, required for all modes. Unlike all other + tunables these are applied to the axi2af region. + + apple,tunable-common-b: + $ref: "#/$defs/apple,tunable" + description: > + Common tunables required for all modes, applied after tunable-axi2af. + + apple,tunable-lane0-usb: + $ref: "#/$defs/apple,tunable" + description: USB3 tunables for lane 0. + + apple,tunable-lane1-usb: + $ref: "#/$defs/apple,tunable" + description: USB3 tunables for lane 1. + + apple,tunable-lane0-cio: + $ref: "#/$defs/apple,tunable" + description: USB4/Thunderbolt ("Converged IO") tunables for lane 0. + + apple,tunable-lane1-cio: + $ref: "#/$defs/apple,tunable" + description: USB4/Thunderbolt ("Converged IO") tunables for lane 1. + + apple,tunable-lane0-dp: + $ref: "#/$defs/apple,tunable" + description: > + DisplayPort tunables for lane 0. + + Note that lane here refers to a USB RX and TX pair re-used for DisplayPort + and not to an individual DisplayPort differential lane. + + apple,tunable-lane1-dp: + $ref: "#/$defs/apple,tunable" + description: > + DisplayPort tunables for lane 1. + + Note that lane here refers to a USB RX and TX pair re-used for DisplayPort + and not to an individual DisplayPort differential lane. + +required: + - compatible + - reg + - reg-names + - "#phy-cells" + - "#reset-cells" + - orientation-switch + - mode-switch + - power-domains + - ports + +additionalProperties: false + +examples: + - | + phy@83000000 { + compatible = "apple,t8103-atcphy"; + reg = <0x83000000 0x4c000>, + <0x83050000 0x8000>, + <0x80000000 0x4000>, + <0x82a90000 0x4000>, + <0x82a84000 0x4000>; + reg-names = "core", "lpdptx", "axi2af", "usb2phy", + "pipehandler"; + + #phy-cells = <1>; + #reset-cells = <0>; + + orientation-switch; + mode-switch; + power-domains = <&ps_atc0_usb>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + remote-endpoint = <&typec_connector_ss>; + }; + }; + + port@1 { + reg = <1>; + + endpoint { + remote-endpoint = <&dwc3_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + endpoint { + remote-endpoint = <&dcp_dp_out>; + }; + }; + + port@3 { + reg = <3>; + + endpoint { + remote-endpoint = <&acio_tbt_out>; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml index ff9f9ca0f19c..e96229c2f8fb 100644 --- a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml @@ -20,6 +20,32 @@ properties: "#phy-cells": const: 1 + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +patternProperties: + "^phy@[0-7]$": + type: object + description: SerDes lane (single RX/TX differential pair) + + properties: + reg: + minimum: 0 + maximum: 7 + description: Lane index as seen in register map + + "#phy-cells": + const: 0 + + required: + - reg + - "#phy-cells" + + additionalProperties: false + required: - compatible - reg @@ -32,9 +58,52 @@ examples: soc { #address-cells = <2>; #size-cells = <2>; - serdes_1: phy@1ea0000 { + + serdes@1ea0000 { compatible = "fsl,lynx-28g"; reg = <0x0 0x1ea0000 0x0 0x1e30>; + #address-cells = <1>; + #size-cells = <0>; #phy-cells = <1>; + + phy@0 { + reg = <0>; + #phy-cells = <0>; + }; + + phy@1 { + reg = <1>; + #phy-cells = <0>; + }; + + phy@2 { + reg = <2>; + #phy-cells = <0>; + }; + + phy@3 { + reg = <3>; + #phy-cells = <0>; + }; + + phy@4 { + reg = <4>; + #phy-cells = <0>; + }; + + phy@5 { + reg = <5>; + #phy-cells = <0>; + }; + + phy@6 { + reg = <6>; + #phy-cells = <0>; + }; + + phy@7 { + reg = <7>; + #phy-cells = <0>; + }; }; }; diff --git a/Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml b/Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml new file mode 100644 index 000000000000..427e2e3425f6 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml @@ -0,0 +1,133 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (C) 2025, Google LLC +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/google,lga-usb-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Google Tensor Series G5 (Laguna) USB PHY + +maintainers: + - Roy Luo + +description: + Describes the USB PHY interfaces integrated with the DWC3 USB controller on + Google Tensor SoCs, starting with the G5 generation (laguna). + Two specific PHY IPs from Synopsys are integrated, including eUSB 2.0 PHY IP + and USB3.2/DisplayPort combo PHY IP. + +properties: + compatible: + const: google,lga-usb-phy + + reg: + items: + - description: USB3.2/DisplayPort combo PHY core registers. + - description: USB3.2/DisplayPort combo PHY Type-C Assist registers. + - description: eUSB 2.0 PHY core registers. + - description: Top-level wrapper registers for the integrated PHYs. + + reg-names: + items: + - const: usb3_core + - const: usb3_tca + - const: usb2_core + - const: usbdp_top + + "#phy-cells": + description: | + The phandle's argument in the PHY specifier selects one of the three + following PHY interfaces. + - 0 for USB high-speed. + - 1 for USB super-speed. + - 2 for DisplayPort. + const: 1 + + clocks: + items: + - description: USB2 PHY clock. + - description: USB2 PHY APB clock. + - description: USB3.2/DisplayPort combo PHY clock. + - description: USB3.2/DisplayPort combo PHY firmware clock. + + clock-names: + items: + - const: usb2 + - const: usb2_apb + - const: usb3 + - const: usb3_fw + + resets: + items: + - description: USB2 PHY reset. + - description: USB2 PHY APB reset. + - description: USB3.2/DisplayPort combo PHY reset. + + reset-names: + items: + - const: usb2 + - const: usb2_apb + - const: usb3 + + power-domains: + maxItems: 1 + + orientation-switch: + type: boolean + description: + Indicates the PHY as a handler of USB Type-C orientation changes + + google,usb-cfg-csr: + description: + A phandle to a syscon node used to access the USB configuration + registers. These registers are the top-level wrapper of the USB + subsystem and provide control and status for the integrated USB + controller and USB PHY. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to the syscon node. + - description: USB2 PHY configuration register offset. + +required: + - compatible + - reg + - reg-names + - "#phy-cells" + - clocks + - clock-names + - resets + - reset-names + - power-domains + - orientation-switch + - google,usb-cfg-csr + +additionalProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + usb-phy@c410000 { + compatible = "google,lga-usb-phy"; + reg = <0 0x0c410000 0 0x20000>, + <0 0x0c430000 0 0x1000>, + <0 0x0c440000 0 0x10000>, + <0 0x0c637000 0 0xa0>; + reg-names = "usb3_core", "usb3_tca", "usb2_core", "usbdp_top"; + #phy-cells = <1>; + clocks = <&hsion_usb2_phy_clk>, <&hsion_u2phy_apb_clk>, + <&hsion_usb3_phy_clk>, <&hsion_usb3_phy_fw_clk>; + clock-names = "usb2", "usb2_apb", "usb3", "usb3_fw"; + resets = <&hsion_resets_usb2_phy>, + <&hsion_resets_u2phy_apb>, + <&hsion_resets_usb3_phy>; + reset-names = "usb2", "usb2_apb", "usb3"; + power-domains = <&hsio_n_usb_pd>; + orientation-switch; + google,usb-cfg-csr = <&usb_cfg_csr 0x14>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml index eb97181cbb95..4a1daae3d8d4 100644 --- a/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,edp-phy.yaml @@ -18,6 +18,7 @@ properties: compatible: oneOf: - enum: + - qcom,glymur-dp-phy - qcom,sa8775p-edp-phy - qcom,sc7280-edp-phy - qcom,sc8180x-edp-phy @@ -37,12 +38,15 @@ properties: - description: PLL register block clocks: - maxItems: 2 + minItems: 2 + maxItems: 3 clock-names: + minItems: 2 items: - const: aux - const: cfg_ahb + - const: ref "#clock-cells": const: 1 @@ -64,6 +68,30 @@ required: - "#clock-cells" - "#phy-cells" +allOf: + - if: + properties: + compatible: + enum: + - qcom,glymur-dp-phy + - qcom,x1e80100-dp-phy + then: + properties: + clocks: + minItems: 3 + maxItems: 3 + clock-names: + minItems: 3 + maxItems: 3 + else: + properties: + clocks: + minItems: 2 + maxItems: 2 + clock-names: + minItems: 2 + maxItems: 2 + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml index c84c62d0e8cb..cd6b84213a7c 100644 --- a/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,m31-eusb2-phy.yaml @@ -15,9 +15,13 @@ description: properties: compatible: - items: - - enum: - - qcom,sm8750-m31-eusb2-phy + oneOf: + - items: + - enum: + - qcom,glymur-m31-eusb2-phy + - qcom,kaanapali-m31-eusb2-phy + - const: qcom,sm8750-m31-eusb2-phy + - const: qcom,sm8750-m31-eusb2-phy reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml new file mode 100644 index 000000000000..efb465c71c1b --- /dev/null +++ b/Documentation/devicetree/bindings/phy/qcom,qcs615-qmp-usb3dp-phy.yaml @@ -0,0 +1,111 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/qcom,qcs615-qmp-usb3dp-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm QMP USB3-DP PHY controller (DP, QCS615) + +maintainers: + - Xiangxu Yin + +description: + The QMP PHY controller supports physical layer functionality for both USB3 + and DisplayPort over USB-C. While it enables mode switching between USB3 and + DisplayPort, but does not support combo mode. + +properties: + compatible: + enum: + - qcom,qcs615-qmp-usb3-dp-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 4 + + clock-names: + items: + - const: aux + - const: ref + - const: cfg_ahb + - const: pipe + + resets: + maxItems: 2 + + reset-names: + items: + - const: phy_phy + - const: dp_phy + + vdda-phy-supply: true + + vdda-pll-supply: true + + "#clock-cells": + const: 1 + description: + See include/dt-bindings/phy/phy-qcom-qmp.h + + "#phy-cells": + const: 1 + description: + See include/dt-bindings/phy/phy-qcom-qmp.h + + qcom,tcsr-reg: + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to TCSR hardware block + - description: offset of the VLS CLAMP register + - description: offset of the PHY mode register + description: Clamp and PHY mode register present in the TCSR + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - vdda-phy-supply + - vdda-pll-supply + - "#clock-cells" + - "#phy-cells" + - qcom,tcsr-reg + +additionalProperties: false + +examples: + - | + #include + #include + + phy@88e8000 { + compatible = "qcom,qcs615-qmp-usb3-dp-phy"; + reg = <0x88e8000 0x2000>; + + clocks = <&gcc GCC_USB2_SEC_PHY_AUX_CLK>, + <&gcc GCC_USB3_SEC_CLKREF_CLK>, + <&gcc GCC_AHB2PHY_WEST_CLK>, + <&gcc GCC_USB2_SEC_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "cfg_ahb", + "pipe"; + + resets = <&gcc GCC_USB3PHY_PHY_SEC_BCR>, + <&gcc GCC_USB3_DP_PHY_SEC_BCR>; + reset-names = "phy_phy", + "dp_phy"; + + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l12a>; + + #clock-cells = <1>; + #phy-cells = <1>; + + qcom,tcsr-reg = <&tcsr 0xbff0 0xb24c>; + }; diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml index f5068df20cfe..3a35120a77ec 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-pcie-phy.yaml @@ -16,7 +16,9 @@ description: properties: compatible: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,qcs615-qmp-gen3x1-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy @@ -146,6 +148,7 @@ allOf: compatible: contains: enum: + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,qcs615-qmp-gen3x1-pcie-phy - qcom,sar2130p-qmp-gen3x2-pcie-phy - qcom,sc8180x-qmp-pcie-phy @@ -178,6 +181,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy - qcom,qcs8300-qmp-gen4x2-pcie-phy - qcom,sa8775p-qmp-gen4x2-pcie-phy @@ -202,7 +206,9 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-gen4x2-pcie-phy - qcom,glymur-qmp-gen5x4-pcie-phy + - qcom,kaanapali-qmp-gen3x2-pcie-phy - qcom,sm8550-qmp-gen4x2-pcie-phy - qcom,sm8650-qmp-gen4x2-pcie-phy - qcom,x1e80100-qmp-gen3x2-pcie-phy diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml index fba7b2549dde..a1731b08c9d1 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-ufs-phy.yaml @@ -20,6 +20,10 @@ properties: - enum: - qcom,qcs615-qmp-ufs-phy - const: qcom,sm6115-qmp-ufs-phy + - items: + - enum: + - qcom,x1e80100-qmp-ufs-phy + - const: qcom,sm8550-qmp-ufs-phy - items: - enum: - qcom,qcs8300-qmp-ufs-phy @@ -29,6 +33,7 @@ properties: - qcom,kaanapali-qmp-ufs-phy - const: qcom,sm8750-qmp-ufs-phy - enum: + - qcom,milos-qmp-ufs-phy - qcom,msm8996-qmp-ufs-phy - qcom,msm8998-qmp-ufs-phy - qcom,sa8775p-qmp-ufs-phy @@ -98,6 +103,7 @@ allOf: compatible: contains: enum: + - qcom,milos-qmp-ufs-phy - qcom,msm8998-qmp-ufs-phy - qcom,sa8775p-qmp-ufs-phy - qcom,sc7180-qmp-ufs-phy diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml index 863a1a446739..623c2f8c7d22 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb3-uni-phy.yaml @@ -16,6 +16,7 @@ description: properties: compatible: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,ipq5424-qmp-usb3-phy - qcom,ipq6018-qmp-usb3-phy - qcom,ipq8074-qmp-usb3-phy @@ -61,6 +62,8 @@ properties: vdda-pll-supply: true + refgen-supply: true + "#clock-cells": const: 0 @@ -113,6 +116,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,qcs8300-qmp-usb3-uni-phy - qcom,qdu1000-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy @@ -156,6 +160,7 @@ allOf: compatible: contains: enum: + - qcom,glymur-qmp-usb3-uni-phy - qcom,sa8775p-qmp-usb3-uni-phy - qcom,sc8180x-qmp-usb3-uni-phy - qcom,sc8280xp-qmp-usb3-uni-phy @@ -164,6 +169,19 @@ allOf: required: - power-domains + - if: + properties: + compatible: + contains: + enum: + - qcom,glymur-qmp-usb3-uni-phy + then: + required: + - refgen-supply + else: + properties: + refgen-supply: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml index e0ec45b96bf5..3d537b7f9985 100644 --- a/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,sc8280xp-qmp-usb43dp-phy.yaml @@ -15,22 +15,28 @@ description: properties: compatible: - enum: - - qcom,sar2130p-qmp-usb3-dp-phy - - qcom,sc7180-qmp-usb3-dp-phy - - qcom,sc7280-qmp-usb3-dp-phy - - qcom,sc8180x-qmp-usb3-dp-phy - - qcom,sc8280xp-qmp-usb43dp-phy - - qcom,sdm845-qmp-usb3-dp-phy - - qcom,sm6350-qmp-usb3-dp-phy - - qcom,sm8150-qmp-usb3-dp-phy - - qcom,sm8250-qmp-usb3-dp-phy - - qcom,sm8350-qmp-usb3-dp-phy - - qcom,sm8450-qmp-usb3-dp-phy - - qcom,sm8550-qmp-usb3-dp-phy - - qcom,sm8650-qmp-usb3-dp-phy - - qcom,sm8750-qmp-usb3-dp-phy - - qcom,x1e80100-qmp-usb3-dp-phy + oneOf: + - items: + - enum: + - qcom,kaanapali-qmp-usb3-dp-phy + - const: qcom,sm8750-qmp-usb3-dp-phy + - enum: + - qcom,glymur-qmp-usb3-dp-phy + - qcom,sar2130p-qmp-usb3-dp-phy + - qcom,sc7180-qmp-usb3-dp-phy + - qcom,sc7280-qmp-usb3-dp-phy + - qcom,sc8180x-qmp-usb3-dp-phy + - qcom,sc8280xp-qmp-usb43dp-phy + - qcom,sdm845-qmp-usb3-dp-phy + - qcom,sm6350-qmp-usb3-dp-phy + - qcom,sm8150-qmp-usb3-dp-phy + - qcom,sm8250-qmp-usb3-dp-phy + - qcom,sm8350-qmp-usb3-dp-phy + - qcom,sm8450-qmp-usb3-dp-phy + - qcom,sm8550-qmp-usb3-dp-phy + - qcom,sm8650-qmp-usb3-dp-phy + - qcom,sm8750-qmp-usb3-dp-phy + - qcom,x1e80100-qmp-usb3-dp-phy reg: maxItems: 1 @@ -63,6 +69,8 @@ properties: vdda-pll-supply: true + refgen-supply: true + "#clock-cells": const: 1 description: @@ -194,14 +202,16 @@ allOf: - if: properties: compatible: - enum: - - qcom,sar2130p-qmp-usb3-dp-phy - - qcom,sc8280xp-qmp-usb43dp-phy - - qcom,sm6350-qmp-usb3-dp-phy - - qcom,sm8550-qmp-usb3-dp-phy - - qcom,sm8650-qmp-usb3-dp-phy - - qcom,sm8750-qmp-usb3-dp-phy - - qcom,x1e80100-qmp-usb3-dp-phy + contains: + enum: + - qcom,glymur-qmp-usb3-dp-phy + - qcom,sar2130p-qmp-usb3-dp-phy + - qcom,sc8280xp-qmp-usb43dp-phy + - qcom,sm6350-qmp-usb3-dp-phy + - qcom,sm8550-qmp-usb3-dp-phy + - qcom,sm8650-qmp-usb3-dp-phy + - qcom,sm8750-qmp-usb3-dp-phy + - qcom,x1e80100-qmp-usb3-dp-phy then: required: - power-domains @@ -209,6 +219,18 @@ allOf: properties: power-domains: false + - if: + properties: + compatible: + enum: + - qcom,glymur-qmp-usb3-dp-phy + then: + required: + - refgen-supply + else: + properties: + refgen-supply: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml index 5bf0d6c9c025..f29fc335f3f5 100644 --- a/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml +++ b/Documentation/devicetree/bindings/phy/qcom,snps-eusb2-repeater.yaml @@ -24,6 +24,7 @@ properties: - qcom,pm8550b-eusb2-repeater - qcom,pmiv0104-eusb2-repeater - qcom,smb2360-eusb2-repeater + - qcom,smb2370-eusb2-repeater reg: maxItems: 1 @@ -59,6 +60,14 @@ properties: minimum: 0 maximum: 7 + qcom,squelch-detector-bp: + description: + This adjusts the voltage level for the threshold used to detect valid + high-speed data. + minimum: -6000 + maximum: 1000 + multipleOf: 1000 + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml index b86dc7a291a4..6d97e038a927 100644 --- a/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml +++ b/Documentation/devicetree/bindings/phy/renesas,rzg3e-usb3-phy.yaml @@ -11,7 +11,14 @@ maintainers: properties: compatible: - const: renesas,r9a09g047-usb3-phy + oneOf: + - const: renesas,r9a09g047-usb3-phy # RZ/G3E + + - items: + - enum: + - renesas,r9a09g056-usb3-phy # RZ/V2N + - renesas,r9a09g057-usb3-phy # RZ/V2H(P) + - const: renesas,r9a09g047-usb3-phy reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml index 2bbec8702a1e..9740e5b335f9 100644 --- a/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml +++ b/Documentation/devicetree/bindings/phy/renesas,usb2-phy.yaml @@ -41,7 +41,9 @@ properties: - const: renesas,rzg2l-usb2-phy - items: - - const: renesas,usb2-phy-r9a09g056 # RZ/V2N + - enum: + - renesas,usb2-phy-r9a09g047 # RZ/G3E + - renesas,usb2-phy-r9a09g056 # RZ/V2N - const: renesas,usb2-phy-r9a09g057 - const: renesas,usb2-phy-r9a09g077 # RZ/T2H @@ -89,6 +91,12 @@ properties: Phandle to a regulator that provides power to the VBUS. This regulator will be managed during the PHY power on/off sequence. + vbus-regulator: + $ref: /schemas/regulator/regulator.yaml# + description: USB VBUS internal regulator + type: object + unevaluatedProperties: false + renesas,no-otg-pins: $ref: /schemas/types.yaml#/definitions/flag description: | @@ -96,6 +104,11 @@ properties: dr_mode: true + mux-states: + description: + phandle to a mux controller node that select the source for USB VBUS. + maxItems: 1 + if: properties: compatible: diff --git a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml index d70ffeb6e824..2b20c0a5e509 100644 --- a/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml +++ b/Documentation/devicetree/bindings/phy/samsung,ufs-phy.yaml @@ -36,6 +36,9 @@ properties: minItems: 1 maxItems: 4 + power-domains: + maxItems: 1 + samsung,pmu-syscon: $ref: /schemas/types.yaml#/definitions/phandle-array maxItems: 1 diff --git a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml index ea1135c91fb7..4562e0468f4f 100644 --- a/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml +++ b/Documentation/devicetree/bindings/phy/samsung,usb3-drd-phy.yaml @@ -34,6 +34,9 @@ properties: - samsung,exynos7870-usbdrd-phy - samsung,exynos850-usbdrd-phy - samsung,exynos990-usbdrd-phy + - samsung,exynosautov920-usb31drd-combo-ssphy + - samsung,exynosautov920-usbdrd-combo-hsphy + - samsung,exynosautov920-usbdrd-phy clocks: minItems: 1 @@ -51,6 +54,9 @@ properties: settings register. For Exynos5420 this is given as 'sclk_usbphy30' in the CMU. It's not needed for Exynos2200. + power-domains: + maxItems: 1 + "#phy-cells": const: 1 @@ -110,6 +116,15 @@ properties: vddh-usbdp-supply: description: VDDh power supply for the USB DP phy. + dvdd-supply: + description: 0.75V power supply for the USB phy. + + vdd18-supply: + description: 1.8V power supply for the USB phy. + + vdd33-supply: + description: 3.3V power supply for the USB phy. + required: - compatible - clocks @@ -221,6 +236,9 @@ allOf: - samsung,exynos7870-usbdrd-phy - samsung,exynos850-usbdrd-phy - samsung,exynos990-usbdrd-phy + - samsung,exynosautov920-usb31drd-combo-ssphy + - samsung,exynosautov920-usbdrd-combo-hsphy + - samsung,exynosautov920-usbdrd-phy then: properties: clocks: @@ -238,6 +256,39 @@ allOf: reg-names: maxItems: 1 + - if: + properties: + compatible: + contains: + enum: + - samsung,exynosautov920-usb31drd-combo-ssphy + - samsung,exynosautov920-usbdrd-combo-hsphy + - samsung,exynosautov920-usbdrd-phy + then: + required: + - dvdd-supply + - vdd18-supply + + else: + properties: + dvdd-supply: false + vdd18-supply: false + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynosautov920-usbdrd-combo-hsphy + - samsung,exynosautov920-usbdrd-phy + then: + required: + - vdd33-supply + + else: + properties: + vdd33-supply: false + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml new file mode 100644 index 000000000000..b59476cd78b5 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-combo-phy.yaml @@ -0,0 +1,114 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/spacemit,k1-combo-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 PCIe/USB3 Combo PHY + +maintainers: + - Alex Elder + +description: > + Of the three PHYs on the SpacemiT K1 SoC capable of being used for + PCIe, one is a combo PHY that can also be configured for use by a + USB 3 controller. Using PCIe or USB 3 is a board design decision. + + The combo PHY is also the only PCIe PHY that is able to determine + PCIe calibration values to use, and this must be determined before + the other two PCIe PHYs can be used. This calibration must be + performed with the combo PHY in PCIe mode, and is this is done + when the combo PHY is probed. + + The combo PHY uses an external oscillator as a reference clock. + During normal operation, the PCIe or USB port driver is responsible + for ensuring all other clocks needed by a PHY are enabled, and all + resets affecting the PHY are deasserted. However, for the combo + PHY to perform calibration independent of whether it's later used + for PCIe or USB, all PCIe mode clocks and resets must be defined. + +properties: + compatible: + const: spacemit,k1-combo-phy + + reg: + items: + - description: PHY control registers + + clocks: + items: + - description: External oscillator used by the PHY PLL + - description: DWC PCIe Data Bus Interface (DBI) clock + - description: DWC PCIe application AXI-bus Master interface clock + - description: DWC PCIe application AXI-bus slave interface clock + + clock-names: + items: + - const: refclk + - const: dbi + - const: mstr + - const: slv + + resets: + items: + - description: PHY reset; remains deasserted after initialization + - description: DWC PCIe Data Bus Interface (DBI) reset + - description: DWC PCIe application AXI-bus Master interface reset + - description: DWC PCIe application AXI-bus slave interface reset + + reset-names: + items: + - const: phy + - const: dbi + - const: mstr + - const: slv + + spacemit,apmu: + description: + A phandle that refers to the APMU system controller, whose + regmap is used in setting the mode + $ref: /schemas/types.yaml#/definitions/phandle + + "#phy-cells": + const: 1 + description: + The argument value (PHY_TYPE_PCIE or PHY_TYPE_USB3) determines + whether the PHY operates in PCIe or USB3 mode. + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - spacemit,apmu + - "#phy-cells" + +additionalProperties: false + +examples: + - | + #include + phy@c0b10000 { + compatible = "spacemit,k1-combo-phy"; + reg = <0xc0b10000 0x1000>; + clocks = <&vctcxo_24m>, + <&syscon_apmu CLK_PCIE0_DBI>, + <&syscon_apmu CLK_PCIE0_MASTER>, + <&syscon_apmu CLK_PCIE0_SLAVE>; + clock-names = "refclk", + "dbi", + "mstr", + "slv"; + resets = <&syscon_apmu RESET_PCIE0_GLOBAL>, + <&syscon_apmu RESET_PCIE0_DBI>, + <&syscon_apmu RESET_PCIE0_MASTER>, + <&syscon_apmu RESET_PCIE0_SLAVE>; + reset-names = "phy", + "dbi", + "mstr", + "slv"; + spacemit,apmu = <&syscon_apmu>; + #phy-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml new file mode 100644 index 000000000000..019b28349be7 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/spacemit,k1-pcie-phy.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/spacemit,k1-pcie-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 PCIe PHY + +maintainers: + - Alex Elder + +description: > + Two PHYs on the SpacemiT K1 SoC used for only for PCIe. These + PHYs must be configured using calibration values that are + determined by a third "combo PHY". The combo PHY determines + these calibration values during probe so they can be used for + the two PCIe-only PHYs. + + The PHY uses an external oscillator as a reference clock. During + normal operation, the PCIe host driver is responsible for ensuring + all other clocks needed by a PHY are enabled, and all resets + affecting the PHY are deasserted. + +properties: + compatible: + const: spacemit,k1-pcie-phy + + reg: + items: + - description: PHY control registers + + clocks: + items: + - description: External oscillator used by the PHY PLL + + clock-names: + const: refclk + + resets: + items: + - description: PHY reset; remains deasserted after initialization + + reset-names: + const: phy + + "#phy-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - "#phy-cells" + +additionalProperties: false + +examples: + - | + #include + phy@c0c10000 { + compatible = "spacemit,k1-pcie-phy"; + reg = <0xc0c10000 0x1000>; + clocks = <&vctcxo_24m>; + clock-names = "refclk"; + resets = <&syscon_apmu RESET_PCIE1_GLOBAL>; + reset-names = "phy"; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml new file mode 100644 index 000000000000..43eaca90d88c --- /dev/null +++ b/Documentation/devicetree/bindings/phy/spacemit,usb2-phy.yaml @@ -0,0 +1,40 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/spacemit,usb2-phy.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: SpacemiT K1 SoC USB 2.0 PHY + +maintainers: + - Ze Huang + +properties: + compatible: + const: spacemit,k1-usb2-phy + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + "#phy-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - "#phy-cells" + +additionalProperties: false + +examples: + - | + usb-phy@c09c0000 { + compatible = "spacemit,k1-usb2-phy"; + reg = <0xc09c0000 0x200>; + clocks = <&syscon_apmu 15>; + #phy-cells = <0>; + }; diff --git a/Documentation/devicetree/bindings/phy/ti,control-phy-otghs.yaml b/Documentation/devicetree/bindings/phy/ti,control-phy-otghs.yaml new file mode 100644 index 000000000000..4ecb1611ee65 --- /dev/null +++ b/Documentation/devicetree/bindings/phy/ti,control-phy-otghs.yaml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/ti,control-phy-otghs.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI OMAP Control PHY Module + +maintainers: + - Roger Quadros + +description: + The TI OMAP Control PHY module is a hardware block within the system + control module (SCM) of Texas Instruments OMAP SoCs. It provides + centralized control over power, configuration, and auxiliary features + for multiple on-chip PHYs. This module is essential for proper PHY + operation in power-constrained embedded systems. + +properties: + $nodename: + pattern: "^phy@[0-9a-f]+$" + + compatible: + enum: + - ti,control-phy-otghs + - ti,control-phy-pcie + - ti,control-phy-pipe3 + - ti,control-phy-usb2 + - ti,control-phy-usb2-am437 + - ti,control-phy-usb2-dra7 + + reg: + minItems: 1 + maxItems: 3 + + reg-names: + minItems: 1 + maxItems: 3 + items: + enum: [otghs_control, power, pcie_pcs, control_sma] + +allOf: + - if: + properties: + compatible: + contains: + enum: + - ti,control-phy-otghs + then: + properties: + reg-names: + const: otghs_control + + - if: + properties: + compatible: + contains: + enum: + - ti,control-phy-pcie + then: + properties: + reg: + minItems: 3 + + reg-names: + items: + - const: power + - const: pcie_pcs + - const: control_sma + + - if: + properties: + compatible: + contains: + enum: + - ti,control-phy-usb2 + - ti,control-phy-usb2-dra7 + - ti,control-phy-usb2-am437 + - ti,control-phy-pipe3 + then: + properties: + reg-names: + const: power + +required: + - reg + - compatible + - reg-names + +unevaluatedProperties: false + +examples: + - | + phy@4a00233c { + compatible = "ti,control-phy-otghs"; + reg = <0x4a00233c 0x4>; + reg-names = "otghs_control"; + }; +... diff --git a/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml new file mode 100644 index 000000000000..84f538aa587c --- /dev/null +++ b/Documentation/devicetree/bindings/phy/ti,phy-usb3.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/phy/ti,phy-usb3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI PIPE3 PHY Module + +maintainers: + - Roger Quadros + +description: + The TI PIPE3 PHY is a high-speed SerDes (Serializer/Deserializer) + transceiver integrated in OMAP5, DRA7xx/AM57xx, and similar SoCs. + It supports multiple protocols (USB3, SATA, PCIe) using the PIPE3 + interface standard, which defines a common physical layer for + high-speed serial interfaces. + +properties: + $nodename: + pattern: "^(pcie-phy|usb3-phy|phy)@[0-9a-f]+$" + + compatible: + enum: + - ti,omap-usb3 + - ti,phy-pipe3-pcie + - ti,phy-pipe3-sata + - ti,phy-usb3 + + reg: + minItems: 2 + maxItems: 3 + + reg-names: + minItems: 2 + items: + - const: phy_rx + - const: phy_tx + - const: pll_ctrl + + "#phy-cells": + const: 0 + + clocks: + minItems: 2 + maxItems: 7 + + clock-names: + minItems: 2 + maxItems: 7 + items: + enum: [wkupclk, sysclk, refclk, dpll_ref, + dpll_ref_m2, phy-div, div-clk] + + syscon-phy-power: + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + items: + items: + - description: Phandle to the system control module + - description: Register offset controlling PHY power + + syscon-pllreset: + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + items: + items: + - description: Phandle to the system control module + - description: Register offset of CTRL_CORE_SMA_SW_0 + + syscon-pcs: + $ref: /schemas/types.yaml#/definitions/phandle-array + maxItems: 1 + items: + items: + - description: Phandle to the system control module + - description: Register offset for PCS delay programming + + ctrl-module: + $ref: /schemas/types.yaml#/definitions/phandle + description: + Phandle of control module for PHY power on. + deprecated: true + +allOf: + - if: + properties: + compatible: + contains: + const: ti,phy-pipe3-sata + then: + properties: + syscon-pllreset: true + else: + properties: + syscon-pllreset: false + +required: + - reg + - compatible + - reg-names + - "#phy-cells" + - clocks + - clock-names + +unevaluatedProperties: false + +examples: + - | + /* TI PIPE3 USB3 PHY */ + usb3-phy@4a084400 { + compatible = "ti,phy-usb3"; + reg = <0x4a084400 0x80>, + <0x4a084800 0x64>, + <0x4a084c00 0x40>; + reg-names = "phy_rx", "phy_tx", "pll_ctrl"; + #phy-cells = <0>; + clocks = <&usb_phy_cm_clk32k>, + <&sys_clkin>, + <&usb_otg_ss_refclk960m>; + clock-names = "wkupclk", "sysclk", "refclk"; + ctrl-module = <&omap_control_usb>; + }; + + - | + /* TI PIPE3 SATA PHY */ + phy@4a096000 { + compatible = "ti,phy-pipe3-sata"; + reg = <0x4a096000 0x80>, /* phy_rx */ + <0x4a096400 0x64>, /* phy_tx */ + <0x4a096800 0x40>; /* pll_ctrl */ + reg-names = "phy_rx", "phy_tx", "pll_ctrl"; + clocks = <&sys_clkin1>, <&sata_ref_clk>; + clock-names = "sysclk", "refclk"; + syscon-pllreset = <&scm_conf 0x3fc>; + #phy-cells = <0>; + }; +... diff --git a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml index c686d06f5f56..9f5c37ca6496 100644 --- a/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml +++ b/Documentation/devicetree/bindings/phy/ti,tcan104x-can.yaml @@ -20,6 +20,9 @@ properties: - microchip,ata6561 - ti,tcan1051 - const: ti,tcan1042 + - items: + - const: ti,tcan1046 + - const: nxp,tja1048 - enum: - ti,tcan1042 - ti,tcan1043 diff --git a/Documentation/devicetree/bindings/phy/ti-phy.txt b/Documentation/devicetree/bindings/phy/ti-phy.txt deleted file mode 100644 index 7c7936b89f2c..000000000000 --- a/Documentation/devicetree/bindings/phy/ti-phy.txt +++ /dev/null @@ -1,98 +0,0 @@ -TI PHY: DT DOCUMENTATION FOR PHYs in TI PLATFORMs - -OMAP CONTROL PHY - -Required properties: - - compatible: Should be one of - "ti,control-phy-otghs" - if it has otghs_control mailbox register as on OMAP4. - "ti,control-phy-usb2" - if it has Power down bit in control_dev_conf register - e.g. USB2_PHY on OMAP5. - "ti,control-phy-pipe3" - if it has DPLL and individual Rx & Tx power control - e.g. USB3 PHY and SATA PHY on OMAP5. - "ti,control-phy-pcie" - for pcie to support external clock for pcie and to - set PCS delay value. - e.g. PCIE PHY in DRA7x - "ti,control-phy-usb2-dra7" - if it has power down register like USB2 PHY on - DRA7 platform. - "ti,control-phy-usb2-am437" - if it has power down register like USB2 PHY on - AM437 platform. - - reg : register ranges as listed in the reg-names property - - reg-names: "otghs_control" for control-phy-otghs - "power", "pcie_pcs" and "control_sma" for control-phy-pcie - "power" for all other types - -omap_control_usb: omap-control-usb@4a002300 { - compatible = "ti,control-phy-otghs"; - reg = <0x4a00233c 0x4>; - reg-names = "otghs_control"; -}; - -TI PIPE3 PHY - -Required properties: - - compatible: Should be "ti,phy-usb3", "ti,phy-pipe3-sata" or - "ti,phy-pipe3-pcie. "ti,omap-usb3" is deprecated. - - reg : Address and length of the register set for the device. - - reg-names: The names of the register addresses corresponding to the registers - filled in "reg". - - #phy-cells: determine the number of cells that should be given in the - phandle while referencing this phy. - - clocks: a list of phandles and clock-specifier pairs, one for each entry in - clock-names. - - clock-names: should include: - * "wkupclk" - wakeup clock. - * "sysclk" - system clock. - * "refclk" - reference clock. - * "dpll_ref" - external dpll ref clk - * "dpll_ref_m2" - external dpll ref clk - * "phy-div" - divider for apll - * "div-clk" - apll clock - -Optional properties: - - id: If there are multiple instance of the same type, in order to - differentiate between each instance "id" can be used (e.g., multi-lane PCIe - PHY). If "id" is not provided, it is set to default value of '1'. - - syscon-pllreset: Handle to system control region that contains the - CTRL_CORE_SMA_SW_0 register and register offset to the CTRL_CORE_SMA_SW_0 - register that contains the SATA_PLL_SOFT_RESET bit. Only valid for sata_phy. - - syscon-pcs : phandle/offset pair. Phandle to the system control module and the - register offset to write the PCS delay value. - -Deprecated properties: - - ctrl-module : phandle of the control module used by PHY driver to power on - the PHY. - -Recommended properties: - - syscon-phy-power : phandle/offset pair. Phandle to the system control - module and the register offset to power on/off the PHY. - -This is usually a subnode of ocp2scp to which it is connected. - -usb3phy@4a084400 { - compatible = "ti,phy-usb3"; - reg = <0x4a084400 0x80>, - <0x4a084800 0x64>, - <0x4a084c00 0x40>; - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_usb>; - #phy-cells = <0>; - clocks = <&usb_phy_cm_clk32k>, - <&sys_clkin>, - <&usb_otg_ss_refclk960m>; - clock-names = "wkupclk", - "sysclk", - "refclk"; -}; - -sata_phy: phy@4a096000 { - compatible = "ti,phy-pipe3-sata"; - reg = <0x4A096000 0x80>, /* phy_rx */ - <0x4A096400 0x64>, /* phy_tx */ - <0x4A096800 0x40>; /* pll_ctrl */ - reg-names = "phy_rx", "phy_tx", "pll_ctrl"; - ctrl-module = <&omap_control_sata>; - clocks = <&sys_clkin1>, <&sata_ref_clk>; - clock-names = "sysclk", "refclk"; - syscon-pllreset = <&scm_conf 0x3fc>; - #phy-cells = <0>; -}; diff --git a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml index 990b78765427..45b7a0b6c626 100644 --- a/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/allwinner,sun4i-a10-pinctrl.yaml @@ -106,7 +106,7 @@ patternProperties: # the pin numbers then, # - Finally, the name will end with either -pin or pins. - "^([rs]-)?(([a-z0-9]{3,}|[a-oq-z][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$": + "^([rs]-)?(([a-z0-9]{3,}|[a-oq-z0-9][a-z0-9]*?)?-)+?(p[a-ilm][0-9]*?-)??pins?$": type: object properties: diff --git a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml index 005d95a9e4d6..ec9848192351 100644 --- a/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml +++ b/Documentation/devicetree/bindings/pinctrl/intel,pinctrl-keembay.yaml @@ -33,7 +33,7 @@ properties: interrupts: description: Specifies the interrupt lines to be used by the controller. - Each interrupt line is shared by upto 4 GPIO lines. + Each interrupt line is shared by up to 4 GPIO lines. maxItems: 8 interrupt-controller: true diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml new file mode 100644 index 000000000000..fe05196160f4 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml @@ -0,0 +1,109 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip Polarfire SoC MSSIO pinctrl + +maintainers: + - Conor Dooley + +properties: + compatible: + oneOf: + - const: microchip,mpfs-pinctrl-mssio + - items: + - const: microchip,pic64gx-pinctrl-mssio + - const: microchip,mpfs-pinctrl-mssio + + reg: + maxItems: 1 + + pinctrl-use-default: true + +patternProperties: + '-cfg$': + type: object + additionalProperties: false + + patternProperties: + '-pins$': + type: object + additionalProperties: false + + allOf: + - $ref: pincfg-node.yaml# + - $ref: pinmux-node.yaml# + + properties: + pins: + description: + The list of IOs that properties in the pincfg node apply to. + + function: + description: + A string containing the name of the function to mux for these + pins. The "reserved" function tristates a pin. + enum: [ sd, emmc, qspi, spi, usb, uart, i2c, can, mdio, misc + reserved, gpio, fabric-test, tied-low, tied-high, tristate ] + + bias-bus-hold: true + bias-disable: true + bias-pull-down: true + bias-pull-up: true + input-schmitt-enable: true + low-power-enable: true + + drive-strength: + enum: [ 2, 4, 6, 8, 10, 12, 16, 20 ] + + power-source: + description: + Which bank voltage to use. This cannot differ for pins in a + given bank, the whole bank uses the same voltage. + enum: [ 1200000, 1500000, 1800000, 2500000, 3300000 ] + + microchip,clamp-diode: + $ref: /schemas/types.yaml#/definitions/flag + description: + Reflects the "Clamp Diode" setting in the MSS Configurator for + this pin. This setting controls whether or not input voltage + clamping should be enabled. + + microchip,ibufmd: + $ref: /schemas/types.yaml#/definitions/uint32 + default: 0 + description: + Reflects the "IBUFMD" bits in the MSS Configurator output files + for this pin. + + required: + - pins + - function + - power-source + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + pinctrl@204 { + compatible = "microchip,mpfs-pinctrl-mssio"; + reg = <0x204 0x7c>; + + ikrd-spi1-cfg { + spi1-pins { + pins = <30>, <31>, <32>, <33>; + function = "spi"; + bias-pull-up; + drive-strength = <8>; + power-source = <3300000>; + microchip,ibufmd = <0x1>; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml index fa47732d7cef..9fbbafcdc063 100644 --- a/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml +++ b/Documentation/devicetree/bindings/pinctrl/microchip,sparx5-sgpio.yaml @@ -21,10 +21,15 @@ properties: pattern: '^gpio@[0-9a-f]+$' compatible: - enum: - - microchip,sparx5-sgpio - - mscc,ocelot-sgpio - - mscc,luton-sgpio + oneOf: + - enum: + - microchip,sparx5-sgpio + - mscc,ocelot-sgpio + - mscc,luton-sgpio + - items: + - enum: + - microchip,lan9691-sgpio + - const: microchip,sparx5-sgpio '#address-cells': const: 1 @@ -80,7 +85,12 @@ patternProperties: type: object properties: compatible: - const: microchip,sparx5-sgpio-bank + oneOf: + - items: + - enum: + - microchip,lan9691-sgpio-bank + - const: microchip,sparx5-sgpio-bank + - const: microchip,sparx5-sgpio-bank reg: description: | diff --git a/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.yaml index 31bc30a81752..930955caacd1 100644 --- a/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/mscc,ocelot-pinctrl.yaml @@ -14,6 +14,7 @@ properties: compatible: oneOf: - enum: + - microchip,lan96455f-pinctrl - microchip,lan966x-pinctrl - microchip,lan9691-pinctrl - microchip,sparx5-pinctrl @@ -30,6 +31,11 @@ properties: - microchip,lan9693-pinctrl - microchip,lan9692-pinctrl - const: microchip,lan9691-pinctrl + - items: + - enum: + - microchip,lan96457f-pinctrl + - microchip,lan96459f-pinctrl + - const: microchip,lan96455f-pinctrl reg: items: diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,glymur-tlmm.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,glymur-tlmm.yaml index d2b0cfeffb50..2836a1a10579 100644 --- a/Documentation/devicetree/bindings/pinctrl/qcom,glymur-tlmm.yaml +++ b/Documentation/devicetree/bindings/pinctrl/qcom,glymur-tlmm.yaml @@ -10,14 +10,16 @@ maintainers: - Bjorn Andersson description: - Top Level Mode Multiplexer pin controller in Qualcomm Glymur SoC. + Top Level Mode Multiplexer pin controller in Qualcomm Glymur and Mahua SoC. allOf: - $ref: /schemas/pinctrl/qcom,tlmm-common.yaml# properties: compatible: - const: qcom,glymur-tlmm + enum: + - qcom,glymur-tlmm + - qcom,mahua-tlmm reg: maxItems: 1 diff --git a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml index 36d665971484..f049013a4e0c 100644 --- a/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/renesas,r9a09g077-pinctrl.yaml @@ -49,6 +49,17 @@ properties: gpio-ranges: maxItems: 1 + interrupt-controller: true + + '#interrupt-cells': + const: 2 + description: + The first cell contains the global GPIO port index, constructed using the + RZT2H_GPIO() helper macro from + and the second cell is used to specify the flag. + E.g. "interrupts = ;" if P08_6 is + being used as an interrupt. + clocks: maxItems: 1 @@ -139,6 +150,8 @@ examples: gpio-controller; #gpio-cells = <2>; gpio-ranges = <&pinctrl 0 0 288>; + interrupt-controller; + #interrupt-cells = <2>; power-domains = <&cpg>; serial0-pins { diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml index f3c433015b12..2b88f25e80a6 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl-wakeup-interrupt.yaml @@ -48,6 +48,7 @@ properties: - enum: - google,gs101-wakeup-eint - samsung,exynos2200-wakeup-eint + - samsung,exynos9610-wakeup-eint - samsung,exynos9810-wakeup-eint - samsung,exynos990-wakeup-eint - samsung,exynosautov9-wakeup-eint diff --git a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml index ddc5e2efff21..7b006009ca0e 100644 --- a/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/samsung,pinctrl.yaml @@ -55,6 +55,7 @@ properties: - samsung,exynos850-pinctrl - samsung,exynos8890-pinctrl - samsung,exynos8895-pinctrl + - samsung,exynos9610-pinctrl - samsung,exynos9810-pinctrl - samsung,exynos990-pinctrl - samsung,exynosautov9-pinctrl diff --git a/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml index d80e88aa07b4..3e734aeb01cc 100644 --- a/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/spacemit,k1-pinctrl.yaml @@ -11,7 +11,9 @@ maintainers: properties: compatible: - const: spacemit,k1-pinctrl + enum: + - spacemit,k1-pinctrl + - spacemit,k3-pinctrl reg: items: @@ -30,6 +32,10 @@ properties: resets: maxItems: 1 + spacemit,apbc: + $ref: /schemas/types.yaml#/definitions/phandle + description: Phandle to syscon that access the protected register + patternProperties: '-cfg$': type: object @@ -72,10 +78,20 @@ patternProperties: enum: [ 0, 1 ] drive-strength: - description: | - typical current when output high level. - 1.8V output: 11, 21, 32, 42 (mA) - 3.3V output: 7, 10, 13, 16, 19, 23, 26, 29 (mA) + description: + typical current (in mA) when the output at high level. + anyOf: + - enum: [ 11, 21, 32, 42 ] + description: For K1 SoC, 1.8V voltage output + + - enum: [ 7, 10, 13, 16, 19, 23, 26, 29 ] + description: For K1 SoC, 3.3V voltage output + + - enum: [ 2, 4, 6, 7, 9, 11, 13, 14, 21, 23, 25, 26, 28, 30, 31, 33 ] + description: For K3 SoC, 1.8V voltage output + + - enum: [ 3, 5, 7, 9, 11, 13, 15, 17, 25, 27, 29, 31, 33, 35, 37, 38 ] + description: For K3 SoC, 3.3V voltage output input-schmitt: description: | @@ -126,6 +142,7 @@ examples: clocks = <&syscon_apbc 42>, <&syscon_apbc 94>; clock-names = "func", "bus"; + spacemit,apbc = <&syscon_apbc>; uart0_2_cfg: uart0-2-cfg { uart0-2-pins { diff --git a/Documentation/devicetree/bindings/powerpc/fsl/fsl,mpc83xx.yaml b/Documentation/devicetree/bindings/powerpc/fsl/fsl,mpc83xx.yaml new file mode 100644 index 000000000000..9e37d155c582 --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/fsl/fsl,mpc83xx.yaml @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/powerpc/fsl/fsl,mpc83xx.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale PowerQUICC II Pro (MPC83xx) platforms + +maintainers: + - J. Neuschäfer + +properties: + $nodename: + const: '/' + compatible: + oneOf: + - description: MPC83xx Reference Design Boards + items: + - enum: + - fsl,mpc8308rdb + - fsl,mpc8315erdb + - fsl,mpc8360rdk + - fsl,mpc8377rdb + - fsl,mpc8377wlan + - fsl,mpc8378rdb + - fsl,mpc8379rdb + + - description: MPC8313E Reference Design Board + items: + - const: MPC8313ERDB + - const: MPC831xRDB + - const: MPC83xxRDB + + - description: MPC8323E Reference Design Board + items: + - const: MPC8323ERDB + - const: MPC832xRDB + - const: MPC83xxRDB + + - description: MPC8349E-mITX(-GP) Reference Design Platform + items: + - enum: + - MPC8349EMITX + - MPC8349EMITXGP + - const: MPC834xMITX + - const: MPC83xxMITX + + - description: Keymile KMETER1 board + const: keymile,KMETER1 + + - description: MPC8308 P1M board + const: denx,mpc8308_p1m + +patternProperties: + "^soc@.*$": + type: object + properties: + compatible: + oneOf: + - items: + - enum: + - fsl,mpc8315-immr + - fsl,mpc8308-immr + - const: simple-bus + - items: + - const: fsl,mpc8360-immr + - const: fsl,immr + - const: fsl,soc + - const: simple-bus + - const: simple-bus + +additionalProperties: true + +examples: + - | + / { + compatible = "fsl,mpc8315erdb"; + model = "MPC8315E-RDB"; + #address-cells = <1>; + #size-cells = <1>; + + soc@e0000000 { + compatible = "fsl,mpc8315-immr", "simple-bus"; + reg = <0xe0000000 0x00000200>; + #address-cells = <1>; + #size-cells = <1>; + device_type = "soc"; + ranges = <0 0xe0000000 0x00100000>; + bus-frequency = <0>; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml b/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml index d6b3b5a5c0b3..fe4ac9350ba0 100644 --- a/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/mt6359-regulator.yaml @@ -287,7 +287,7 @@ examples: regulator-max-microvolt = <1700000>; }; mt6359_vrfck_1_ldo_reg: ldo_vrfck_1 { - regulator-name = "vrfck"; + regulator-name = "vrfck_1"; regulator-min-microvolt = <1240000>; regulator-max-microvolt = <1600000>; }; @@ -309,7 +309,7 @@ examples: regulator-max-microvolt = <3300000>; }; mt6359_vemc_1_ldo_reg: ldo_vemc_1 { - regulator-name = "vemc"; + regulator-name = "vemc_1"; regulator-min-microvolt = <2500000>; regulator-max-microvolt = <3300000>; }; diff --git a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml index 57d75acb0b5e..ce8ec0119469 100644 --- a/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml +++ b/Documentation/devicetree/bindings/remoteproc/fsl,imx-rproc.yaml @@ -28,6 +28,7 @@ properties: - fsl,imx8qxp-cm4 - fsl,imx8ulp-cm33 - fsl,imx93-cm33 + - fsl,imx95-cm7 clocks: maxItems: 1 diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml index 137f95028313..16a245fe2738 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,adsp.yaml @@ -32,6 +32,8 @@ properties: reg: maxItems: 1 + cx-supply: true + px-supply: description: Phandle to the PX regulator @@ -159,6 +161,9 @@ allOf: items: - const: lcx - const: lmx + else: + properties: + cx-supply: false - if: properties: diff --git a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml index 2dd479cf4821..11b056d6a480 100644 --- a/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml +++ b/Documentation/devicetree/bindings/remoteproc/qcom,sm8550-pas.yaml @@ -187,7 +187,6 @@ allOf: enum: - qcom,sm8550-adsp-pas - qcom,sm8650-adsp-pas - - qcom,sm8750-adsp-pas - qcom,x1e80100-adsp-pas then: properties: diff --git a/Documentation/devicetree/bindings/remoteproc/ti,hsm-m4fss.yaml b/Documentation/devicetree/bindings/remoteproc/ti,hsm-m4fss.yaml new file mode 100644 index 000000000000..9244e60acee3 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/ti,hsm-m4fss.yaml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/remoteproc/ti,hsm-m4fss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI K3 HSM M4F processor subsystems + +maintainers: + - Beleswar Padhi + +description: | + Some K3 family SoCs have a HSM (High Security Module) M4F core in the + Wakeup Voltage Domain which could be used to run secure services like + Authentication. Some of those are J721S2, J784S4, J722S, AM62X. + +$ref: /schemas/arm/keystone/ti,k3-sci-common.yaml# + +properties: + compatible: + enum: + - ti,hsm-m4fss + + reg: + items: + - description: SRAM0_0 internal memory region + - description: SRAM0_1 internal memory region + - description: SRAM1 internal memory region + + reg-names: + items: + - const: sram0_0 + - const: sram0_1 + - const: sram1 + + resets: + maxItems: 1 + + firmware-name: + maxItems: 1 + +required: + - compatible + - reg + - reg-names + - resets + - firmware-name + - ti,sci + - ti,sci-dev-id + - ti,sci-proc-ids + +unevaluatedProperties: false + +examples: + - | + soc { + #address-cells = <2>; + #size-cells = <2>; + + remoteproc@43c00000 { + compatible = "ti,hsm-m4fss"; + reg = <0x00 0x43c00000 0x00 0x20000>, + <0x00 0x43c20000 0x00 0x10000>, + <0x00 0x43c30000 0x00 0x10000>; + reg-names = "sram0_0", "sram0_1", "sram1"; + resets = <&k3_reset 225 1>; + firmware-name = "hsm.bin"; + ti,sci = <&sms>; + ti,sci-dev-id = <225>; + ti,sci-proc-ids = <0x80 0xff>; + }; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt index 463a97c11eff..91f0a3b0c0b2 100644 --- a/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt +++ b/Documentation/devicetree/bindings/remoteproc/ti,keystone-rproc.txt @@ -66,7 +66,7 @@ The following are the mandatory properties: - kick-gpios: Should specify the gpio device needed for the virtio IPC stack. This will be used to interrupt the remote processor. The gpio device to be used is as per the bindings in, - Documentation/devicetree/bindings/gpio/gpio-dsp-keystone.txt + Documentation/devicetree/bindings/gpio/ti,keystone-dsp-gpio.yaml SoC-specific Required properties: --------------------------------- diff --git a/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt b/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt deleted file mode 100644 index 45750ff3112d..000000000000 --- a/Documentation/devicetree/bindings/rtc/cpcap-rtc.txt +++ /dev/null @@ -1,18 +0,0 @@ -Motorola CPCAP PMIC RTC ------------------------ - -This module is part of the CPCAP. For more details about the whole -chip see Documentation/devicetree/bindings/mfd/motorola-cpcap.txt. - -Requires node properties: -- compatible: should contain "motorola,cpcap-rtc" -- interrupts: An interrupt specifier for alarm and 1 Hz irq - -Example: - -&cpcap { - cpcap_rtc: rtc { - compatible = "motorola,cpcap-rtc"; - interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>; - }; -}; diff --git a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml index f89c1f660aee..aac91c79ffdb 100644 --- a/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml +++ b/Documentation/devicetree/bindings/rtc/loongson,rtc.yaml @@ -23,6 +23,7 @@ properties: - loongson,ls1b-rtc - loongson,ls1c-rtc - loongson,ls7a-rtc + - loongson,ls2k0300-rtc - loongson,ls2k1000-rtc - items: - enum: @@ -42,6 +43,18 @@ required: unevaluatedProperties: false +if: + properties: + compatible: + contains: + enum: + - loongson,ls1c-rtc + - loongson,ls2k0300-rtc + +then: + properties: + interrupts: false + examples: - | #include diff --git a/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml b/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml new file mode 100644 index 000000000000..bf2efd432a23 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/motorola,cpcap-rtc.yaml @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/rtc/motorola,cpcap-rtc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Motorola CPCAP PMIC RTC + +maintainers: + - Svyatoslav Ryhel + +description: + This module is part of the Motorola CPCAP MFD device. For more details + see Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml. The + RTC is represented as a sub-node of the PMIC node on the device tree. + +properties: + compatible: + const: motorola,cpcap-rtc + + interrupts: + items: + - description: alarm interrupt + - description: 1 Hz interrupt + +required: + - compatible + - interrupts + +additionalProperties: false + +... diff --git a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml index ccb1638c35b9..988bb9fa8143 100644 --- a/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml +++ b/Documentation/devicetree/bindings/rtc/renesas,rz-rtca3.yaml @@ -14,6 +14,7 @@ properties: items: - enum: - renesas,r9a08g045-rtca3 # RZ/G3S + - renesas,r9a09g056-rtca3 # RZ/V2N - renesas,r9a09g057-rtca3 # RZ/V2H - const: renesas,rz-rtca3 @@ -82,7 +83,9 @@ allOf: properties: compatible: contains: - const: renesas,r9a09g057-rtca3 + enum: + - renesas,r9a09g056-rtca3 + - renesas,r9a09g057-rtca3 then: properties: resets: diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index 167ddcbd8800..73851f19330d 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -160,6 +160,7 @@ properties: - enum: - mrvl,mmp-uart - spacemit,k1-uart + - spacemit,k3-uart - const: intel,xscale-uart - items: - enum: diff --git a/Documentation/devicetree/bindings/serial/google,goldfish-tty.yaml b/Documentation/devicetree/bindings/serial/google,goldfish-tty.yaml new file mode 100644 index 000000000000..0626ce58740c --- /dev/null +++ b/Documentation/devicetree/bindings/serial/google,goldfish-tty.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/serial/google,goldfish-tty.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Google Goldfish TTY + +maintainers: + - Kuan-Wei Chiu + +allOf: + - $ref: /schemas/serial/serial.yaml# + +description: + Android goldfish TTY device generated by Android emulator. + +properties: + compatible: + const: google,goldfish-tty + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +unevaluatedProperties: false + +examples: + - | + serial@1f004000 { + compatible = "google,goldfish-tty"; + reg = <0x1f004000 0x1000>; + interrupts = <12>; + }; diff --git a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml index 6b1f827a335b..e059b14775eb 100644 --- a/Documentation/devicetree/bindings/serial/renesas,rsci.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,rsci.yaml @@ -10,46 +10,78 @@ maintainers: - Geert Uytterhoeven - Lad Prabhakar -allOf: - - $ref: serial.yaml# - properties: compatible: oneOf: - - items: - - const: renesas,r9a09g087-rsci # RZ/N2H - - const: renesas,r9a09g077-rsci # RZ/T2H + - enum: + - renesas,r9a09g047-rsci # RZ/G3E + - renesas,r9a09g077-rsci # RZ/T2H - items: + - enum: + - renesas,r9a09g056-rsci # RZ/V2N + - renesas,r9a09g057-rsci # RZ/V2H(P) + - const: renesas,r9a09g047-rsci + + - items: + - const: renesas,r9a09g087-rsci # RZ/N2H - const: renesas,r9a09g077-rsci # RZ/T2H reg: maxItems: 1 interrupts: + minItems: 4 items: - description: Error interrupt - description: Receive buffer full interrupt - description: Transmit buffer empty interrupt - description: Transmit end interrupt + - description: Active edge detection interrupt + - description: Break field detection interrupt interrupt-names: + minItems: 4 items: - const: eri - const: rxi - const: txi - const: tei + - const: aed + - const: bfd clocks: minItems: 2 - maxItems: 3 + maxItems: 6 clock-names: - minItems: 2 + oneOf: + - items: + - const: operation + - const: bus + - const: sck # optional external clock input + + minItems: 2 + + - items: + - const: pclk + - const: tclk + - const: tclk_div4 + - const: tclk_div16 + - const: tclk_div64 + - const: sck # optional external clock input + + minItems: 5 + + resets: items: - - const: operation - - const: bus - - const: sck # optional external clock input + - description: Input for resetting the APB clock + - description: Input for resetting TCLK + + reset-names: + items: + - const: presetn + - const: tresetn power-domains: maxItems: 1 @@ -62,6 +94,57 @@ required: - clock-names - power-domains +allOf: + - $ref: serial.yaml# + + - if: + properties: + compatible: + contains: + const: renesas,r9a09g077-rsci + then: + properties: + interrupts: + maxItems: 4 + + interrupt-names: + maxItems: 4 + + clocks: + minItems: 2 + maxItems: 3 + + clock-names: + minItems: 2 + maxItems: 3 + + resets: false + + - if: + properties: + compatible: + contains: + const: renesas,r9a09g047-rsci + then: + properties: + interrupts: + minItems: 6 + + interrupt-names: + minItems: 6 + + clocks: + minItems: 5 + maxItems: 6 + + clock-names: + minItems: 5 + maxItems: 6 + + required: + - resets + - reset-names + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/serial/renesas,scif.yaml b/Documentation/devicetree/bindings/serial/renesas,scif.yaml index 72483bc3274d..82f54446835e 100644 --- a/Documentation/devicetree/bindings/serial/renesas,scif.yaml +++ b/Documentation/devicetree/bindings/serial/renesas,scif.yaml @@ -12,15 +12,16 @@ maintainers: properties: compatible: oneOf: + - enum: + - renesas,scif-r7s9210 # RZ/A2 + - renesas,scif-r9a07g044 # RZ/G2{L,LC} + - renesas,scif-r9a09g057 # RZ/V2H(P) + - items: - enum: - renesas,scif-r7s72100 # RZ/A1H - const: renesas,scif # generic SCIF compatible UART - - items: - - enum: - - renesas,scif-r7s9210 # RZ/A2 - - items: - enum: - renesas,scif-r8a7778 # R-Car M1 @@ -76,19 +77,14 @@ properties: - const: renesas,rcar-gen5-scif # R-Car Gen5 - const: renesas,scif # generic SCIF compatible UART - - items: - - enum: - - renesas,scif-r9a07g044 # RZ/G2{L,LC} - - items: - enum: - renesas,scif-r9a07g043 # RZ/G2UL and RZ/Five - renesas,scif-r9a07g054 # RZ/V2L - renesas,scif-r9a08g045 # RZ/G3S + - renesas,scif-r9a08g046 # RZ/G3L - const: renesas,scif-r9a07g044 # RZ/G2{L,LC} fallback - - const: renesas,scif-r9a09g057 # RZ/V2H(P) - - items: - enum: - renesas,scif-r9a09g047 # RZ/G3E diff --git a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml index 39987f722411..44e4a50c3155 100644 --- a/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/microchip/microchip,mpfs-mss-top-sysreg.yaml @@ -42,6 +42,10 @@ properties: type: object $ref: /schemas/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml + pinctrl@204: + type: object + $ref: /schemas/pinctrl/microchip,mpfs-pinctrl-mssio.yaml + required: - compatible - reg diff --git a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml index 5e1e155510b3..9c63dbcd4d77 100644 --- a/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml +++ b/Documentation/devicetree/bindings/soc/samsung/samsung,exynos-sysreg.yaml @@ -15,6 +15,7 @@ properties: - items: - enum: - google,gs101-apm-sysreg + - google,gs101-dpu-sysreg - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg - google,gs101-misc-sysreg @@ -92,6 +93,7 @@ allOf: compatible: contains: enum: + - google,gs101-dpu-sysreg - google,gs101-hsi0-sysreg - google,gs101-hsi2-sysreg - google,gs101-misc-sysreg diff --git a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml index f0c6feb99be3..d3a7c93c3c54 100644 --- a/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml +++ b/Documentation/devicetree/bindings/soc/spacemit/spacemit,k1-syscon.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/soc/spacemit/spacemit,k1-syscon.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: SpacemiT K1 SoC System Controller +title: SpacemiT K1/K3 SoC System Controller maintainers: - Haylen Chu @@ -22,6 +22,10 @@ properties: - spacemit,k1-syscon-rcpu - spacemit,k1-syscon-rcpu2 - spacemit,k1-syscon-apbc2 + - spacemit,k3-syscon-apbc + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-dciu + - spacemit,k3-syscon-mpmu reg: maxItems: 1 @@ -39,7 +43,8 @@ properties: "#clock-cells": const: 1 description: - See for valid indices. + For K1 SoC, check for valid indices. + For K3 SoC, check for valid indices. "#power-domain-cells": const: 1 @@ -66,6 +71,8 @@ allOf: enum: - spacemit,k1-syscon-apmu - spacemit,k1-syscon-mpmu + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-mpmu then: required: - "#power-domain-cells" @@ -80,6 +87,9 @@ allOf: - spacemit,k1-syscon-apbc - spacemit,k1-syscon-apmu - spacemit,k1-syscon-mpmu + - spacemit,k3-syscon-apbc + - spacemit,k3-syscon-apmu + - spacemit,k3-syscon-mpmu then: required: - clocks diff --git a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml index 1fdbeecc5eff..3a3313ea0890 100644 --- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml +++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak4458.yaml @@ -21,10 +21,10 @@ properties: reg: maxItems: 1 - avdd-supply: + AVDD-supply: description: Analog power supply - dvdd-supply: + DVDD-supply: description: Digital power supply reset-gpios: @@ -60,7 +60,7 @@ allOf: properties: dsd-path: false -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml b/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml index d3d494ae8abf..18919d9112a3 100644 --- a/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml +++ b/Documentation/devicetree/bindings/sound/asahi-kasei,ak5558.yaml @@ -19,10 +19,10 @@ properties: reg: maxItems: 1 - avdd-supply: + AVDD-supply: description: A 1.8V supply that powers up the AVDD pin. - dvdd-supply: + DVDD-supply: description: A 1.2V supply that powers up the DVDD pin. reset-gpios: @@ -32,7 +32,10 @@ required: - compatible - reg -additionalProperties: false +allOf: + - $ref: dai-common.yaml# + +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml index da89523ccf5f..92bc3ef56f2c 100644 --- a/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra-audio-graph-card.yaml @@ -23,6 +23,7 @@ properties: enum: - nvidia,tegra210-audio-graph-card - nvidia,tegra186-audio-graph-card + - nvidia,tegra238-audio-graph-card - nvidia,tegra264-audio-graph-card clocks: diff --git a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml index e4cdbf2202b9..1394f78281fc 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml +++ b/Documentation/devicetree/bindings/sound/renesas,rz-ssi.yaml @@ -20,6 +20,7 @@ properties: - renesas,r9a07g044-ssi # RZ/G2{L,LC} - renesas,r9a07g054-ssi # RZ/V2L - renesas,r9a08g045-ssi # RZ/G3S + - renesas,r9a08g046-ssi # RZ/G3L - const: renesas,rz-ssi reg: diff --git a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml index 003023729fb8..9447a2f371b5 100644 --- a/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml +++ b/Documentation/devicetree/bindings/soundwire/qcom,soundwire.yaml @@ -27,6 +27,7 @@ properties: - items: - enum: - qcom,soundwire-v2.1.0 + - qcom,soundwire-v2.2.0 - const: qcom,soundwire-v2.0.0 reg: diff --git a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml index a6067030c5ed..6af4ff233158 100644 --- a/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml +++ b/Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml @@ -6,9 +6,6 @@ $schema: http://devicetree.org/meta-schemas/core.yaml# title: Allwinner A31 SPI Controller -allOf: - - $ref: spi-controller.yaml - maintainers: - Chen-Yu Tsai - Maxime Ripard @@ -82,11 +79,11 @@ patternProperties: spi-rx-bus-width: items: - - const: 1 + enum: [0, 1, 2, 4] spi-tx-bus-width: items: - - const: 1 + enum: [0, 1, 2, 4] required: - compatible @@ -95,6 +92,28 @@ required: - clocks - clock-names +allOf: + - $ref: spi-controller.yaml + - if: + not: + properties: + compatible: + contains: + enum: + - allwinner,sun50i-r329-spi + - allwinner,sun55i-a523-spi + then: + patternProperties: + "^.*@[0-9a-f]+": + properties: + spi-rx-bus-width: + items: + enum: [0, 1] + + spi-tx-bus-width: + items: + enum: [0, 1] + unevaluatedProperties: false examples: diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml index 81838577cf9c..8ebebcebca16 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml @@ -22,21 +22,6 @@ allOf: properties: reg: minItems: 2 - - if: - properties: - compatible: - contains: - enum: - - baikal,bt1-sys-ssi - then: - properties: - mux-controls: - maxItems: 1 - required: - - mux-controls - else: - required: - - interrupts - if: properties: compatible: @@ -75,10 +60,6 @@ properties: const: intel,mountevans-imc-ssi - description: AMD Pensando Elba SoC SPI Controller const: amd,pensando-elba-spi - - description: Baikal-T1 SPI Controller - const: baikal,bt1-ssi - - description: Baikal-T1 System Boot SPI Controller - const: baikal,bt1-sys-ssi - description: Canaan Kendryte K210 SoS SPI Controller const: canaan,k210-spi - description: Renesas RZ/N1 SPI Controller @@ -170,6 +151,7 @@ required: - "#address-cells" - "#size-cells" - clocks + - interrupts examples: - | @@ -190,15 +172,4 @@ examples: rx-sample-delay-ns = <7>; }; }; - - | - spi@1f040100 { - compatible = "baikal,bt1-sys-ssi"; - reg = <0x1f040100 0x900>, - <0x1c000000 0x1000000>; - #address-cells = <1>; - #size-cells = <0>; - mux-controls = <&boot_mux>; - clocks = <&ccu_sys>; - clock-names = "ssi_clk"; - }; ... diff --git a/Documentation/devicetree/bindings/spmi/mediatek,mt8196-spmi.yaml b/Documentation/devicetree/bindings/spmi/mediatek,mt8196-spmi.yaml new file mode 100644 index 000000000000..7a534f0a1d87 --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/mediatek,mt8196-spmi.yaml @@ -0,0 +1,138 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/mediatek,mt8196-spmi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT8196 SPMI 2.0 Controller + +maintainers: + - Hsin-Hsiung Wang + - AngeloGioacchino Del Regno + +description: + The MediaTek MT8196 SoC features a SPMI version 2.0 compliant controller, + with internal wrapping arbitration logic to allow for multiple on-chip + devices to control up to two SPMI buses. + The main arbiter also acts as an interrupt controller, arbitering also + the interrupts coming from SPMI-connected devices into each of the nested + interrupt controllers from any of the present SPMI buses. + +properties: + compatible: + oneOf: + - enum: + - mediatek,mt8196-spmi + - items: + - enum: + - mediatek,mt6991-spmi + - const: mediatek,mt8196-spmi + + ranges: true + + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + +patternProperties: + "^spmi@[a-f0-9]+$": + type: object + $ref: /schemas/spmi/spmi.yaml + unevaluatedProperties: false + + properties: + reg: + items: + - description: controller interface registers + - description: spmi master controller registers + + reg-names: + items: + - const: pmif + - const: spmimst + + clocks: + items: + - description: controller interface system clock + - description: controller interface timer clock + - description: spmi controller master clock + + clock-names: + items: + - const: pmif_sys_ck + - const: pmif_tmr_ck + - const: spmimst_clk_mux + + interrupts: + maxItems: 1 + + interrupt-names: + const: rcs + + interrupt-controller: true + + "#interrupt-cells": + const: 3 + description: | + cell 1: slave ID for the requested interrupt (0-15) + cell 2: the requested peripheral interrupt (0-7) + cell 3: interrupt flags indicating level-sense information, + as defined in dt-bindings/interrupt-controller/irq.h + required: + - reg + - reg-names + - clocks + - clock-names + - interrupts + - interrupt-names + - interrupt-controller + - "#interrupt-cells" + +required: + - compatible + - ranges + - '#address-cells' + - '#size-cells' + +additionalProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + spmi-arbiter@1c018000 { + compatible = "mediatek,mt8196-spmi"; + ranges = <0 0 0x1c018000 0x4900>; + #address-cells = <1>; + #size-cells = <1>; + + spmi@0 { + reg = <0 0x900>, <0x4800 0x100>; + reg-names = "pmif", "spmimst"; + interrupts-extended = <&pio 292 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "rcs"; + interrupt-controller; + #interrupt-cells = <3>; + clocks = <&pmif_sys>, <&pmif_tmr>, <&spmi_mst>; + clock-names = "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux"; + }; + + spmi@2000 { + reg = <0x2000 0x900>, <0x4000 0x100>; + reg-names = "pmif", "spmimst"; + interrupts-extended = <&pio 291 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "rcs"; + interrupt-controller; + #interrupt-cells = <3>; + clocks = <&pmif_sys>, <&pmif_tmr>, <&spmi_mst>; + clock-names = "pmif_sys_ck", "pmif_tmr_ck", "spmimst_clk_mux"; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml index 7f0be0ac644a..dc61d88008a9 100644 --- a/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml +++ b/Documentation/devicetree/bindings/spmi/mtk,spmi-mtk-pmif.yaml @@ -26,6 +26,7 @@ properties: - enum: - mediatek,mt8186-spmi - mediatek,mt8188-spmi + - mediatek,mt8189-spmi - const: mediatek,mt8195-spmi reg: diff --git a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml new file mode 100644 index 000000000000..3b5005b96c6d --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml @@ -0,0 +1,150 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/qcom,glymur-spmi-pmic-arb.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. Glymur SPMI Controller (PMIC Arbiter v8) + +maintainers: + - David Collins + +description: | + The Glymur SPMI PMIC Arbiter implements HW version 8 and it's an SPMI + controller with wrapping arbitration logic to allow for multiple on-chip + devices to control up to 4 SPMI separate buses. + + The PMIC Arbiter can also act as an interrupt controller, providing interrupts + to slave devices. + +allOf: + - $ref: /schemas/spmi/qcom,spmi-pmic-arb-common.yaml + +properties: + compatible: + oneOf: + - items: + - enum: + - qcom,kaanapali-spmi-pmic-arb + - const: qcom,glymur-spmi-pmic-arb + - enum: + - qcom,glymur-spmi-pmic-arb + + reg: + items: + - description: core registers + - description: tx-channel per virtual slave registers + - description: rx-channel (called observer) per virtual slave registers + - description: channel to PMIC peripheral mapping registers + + reg-names: + items: + - const: core + - const: chnls + - const: obsrvr + - const: chnl_map + + ranges: true + + '#address-cells': + const: 2 + + '#size-cells': + const: 2 + +patternProperties: + "^spmi@[a-f0-9]+$": + type: object + $ref: /schemas/spmi/spmi.yaml + unevaluatedProperties: false + + properties: + reg: + items: + - description: configuration registers + - description: interrupt controller registers + - description: channel owner EE mapping registers + + reg-names: + items: + - const: cnfg + - const: intr + - const: chnl_owner + + interrupts: + maxItems: 1 + + interrupt-names: + const: periph_irq + + interrupt-controller: true + + '#interrupt-cells': + const: 4 + description: | + cell 1: slave ID for the requested interrupt (0-15) + cell 2: peripheral ID for requested interrupt (0-255) + cell 3: the requested peripheral interrupt (0-7) + cell 4: interrupt flags indicating level-sense information, + as defined in dt-bindings/interrupt-controller/irq.h + +required: + - compatible + - reg-names + +unevaluatedProperties: false + +examples: + - | + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + arbiter@c400000 { + compatible = "qcom,glymur-spmi-pmic-arb"; + reg = <0x0 0xc400000 0x0 0x3000>, + <0x0 0xc900000 0x0 0x400000>, + <0x0 0xc4c0000 0x0 0x400000>, + <0x0 0xc403000 0x0 0x8000>; + reg-names = "core", "chnls", "obsrvr", "chnl_map"; + + qcom,ee = <0>; + qcom,channel = <0>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + spmi@c426000 { + reg = <0x0 0xc426000 0x0 0x4000>, + <0x0 0xc8c0000 0x0 0x10000>, + <0x0 0xc42a000 0x0 0x8000>; + reg-names = "cnfg", "intr", "chnl_owner"; + + interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + + #address-cells = <2>; + #size-cells = <0>; + }; + + spmi@c437000 { + reg = <0x0 0xc437000 0x0 0x4000>, + <0x0 0xc8d0000 0x0 0x10000>, + <0x0 0xc43b000 0x0 0x8000>; + reg-names = "cnfg", "intr", "chnl_owner"; + + interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + + #address-cells = <2>; + #size-cells = <0>; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml new file mode 100644 index 000000000000..8c38ed145e74 --- /dev/null +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb-common.yaml @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spmi/qcom,spmi-pmic-arb-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Technologies, Inc. SPMI Controller (common) + +maintainers: + - David Collins + +description: | + This defines some common properties used to define Qualcomm SPMI controllers + for PMIC arbiter. + +properties: + qcom,ee: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: + indicates the active Execution Environment identifier + + qcom,channel: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 5 + description: + which of the PMIC Arb provided channels to use for accesses + +required: + - qcom,ee + - qcom,channel + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml index 51daf1b847a9..d0c683dd5284 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,spmi-pmic-arb.yaml @@ -19,6 +19,7 @@ description: | allOf: - $ref: spmi.yaml + - $ref: qcom,spmi-pmic-arb-common.yaml properties: compatible: @@ -71,20 +72,6 @@ properties: '#size-cells': true - qcom,ee: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - indicates the active Execution Environment identifier - - qcom,channel: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - which of the PMIC Arb provided channels to use for accesses - qcom,bus-id: $ref: /schemas/types.yaml#/definitions/uint32 minimum: 0 @@ -97,8 +84,6 @@ properties: required: - compatible - reg-names - - qcom,ee - - qcom,channel unevaluatedProperties: false diff --git a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml index 7c3cc20a80d6..08369fdd2161 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,x1e80100-spmi-pmic-arb.yaml @@ -17,6 +17,9 @@ description: | The PMIC Arbiter can also act as an interrupt controller, providing interrupts to slave devices. +allOf: + - $ref: qcom,spmi-pmic-arb-common.yaml + properties: compatible: oneOf: @@ -45,20 +48,6 @@ properties: '#size-cells': const: 2 - qcom,ee: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - indicates the active Execution Environment identifier - - qcom,channel: - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 5 - description: > - which of the PMIC Arb provided channels to use for accesses - patternProperties: "^spmi@[a-f0-9]+$": type: object @@ -96,10 +85,8 @@ patternProperties: required: - compatible - reg-names - - qcom,ee - - qcom,channel -additionalProperties: false +unevaluatedProperties: false examples: - | diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 406fe1277b66..a482aeadcd44 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml @@ -237,6 +237,10 @@ properties: - meas,tsys01 # MEMSIC magnetometer - memsic,mmc35240 + # MEMSIC 3-axis magnetometer + - memsic,mmc5603 + # MEMSIC 3-axis magnetometer (Support I3C HDR) + - memsic,mmc5633 # MEMSIC 3-axis accelerometer - memsic,mxc4005 # MEMSIC 2-axis 8-bit digital accelerometer diff --git a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml index 7f22f9c031b2..b8bac2cce949 100644 --- a/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml +++ b/Documentation/devicetree/bindings/usb/aspeed,usb-vhub.yaml @@ -17,8 +17,8 @@ description: |+ Supported number of devices and endpoints vary depending on hardware revisions. AST2400 and AST2500 Virtual Hub supports 5 downstream devices - and 15 generic endpoints, while AST2600 Virtual Hub supports 7 downstream - devices and 21 generic endpoints. + and 15 generic endpoints, while AST2600 and AST2700 Virtual Hub supports + 7 downstream devices and 21 generic endpoints. properties: compatible: @@ -26,6 +26,7 @@ properties: - aspeed,ast2400-usb-vhub - aspeed,ast2500-usb-vhub - aspeed,ast2600-usb-vhub + - aspeed,ast2700-usb-vhub reg: maxItems: 1 @@ -33,6 +34,9 @@ properties: clocks: maxItems: 1 + resets: + maxItems: 1 + interrupts: maxItems: 1 @@ -107,6 +111,20 @@ required: - aspeed,vhub-downstream-ports - aspeed,vhub-generic-endpoints +if: + properties: + compatible: + contains: + const: aspeed,ast2700-usb-vhub + +then: + required: + - resets + +else: + properties: + resets: false + additionalProperties: false examples: diff --git a/Documentation/devicetree/bindings/usb/generic-ehci.yaml b/Documentation/devicetree/bindings/usb/generic-ehci.yaml index 4e84bead0232..601f097c09a6 100644 --- a/Documentation/devicetree/bindings/usb/generic-ehci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ehci.yaml @@ -93,6 +93,8 @@ properties: minItems: 1 maxItems: 2 + dma-coherent: true + interrupts: maxItems: 1 diff --git a/Documentation/devicetree/bindings/usb/generic-ohci.yaml b/Documentation/devicetree/bindings/usb/generic-ohci.yaml index 3ee1586fc8b9..961cbf85eeb5 100644 --- a/Documentation/devicetree/bindings/usb/generic-ohci.yaml +++ b/Documentation/devicetree/bindings/usb/generic-ohci.yaml @@ -64,6 +64,8 @@ properties: reg: maxItems: 1 + dma-coherent: true + interrupts: maxItems: 1 diff --git a/Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml b/Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml new file mode 100644 index 000000000000..95be84c843f5 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml @@ -0,0 +1,140 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright (c) 2025, Google LLC +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/google,lga-dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Google Tensor Series G5 (Laguna) DWC3 USB SoC Controller + +maintainers: + - Roy Luo + +description: + Describes the DWC3 USB controller block implemented on Google Tensor SoCs, + starting with the G5 generation (laguna). Based on Synopsys DWC3 IP, the + controller features Dual-Role Device single port with hibernation add-on. + +properties: + compatible: + const: google,lga-dwc3 + + reg: + items: + - description: Core DWC3 IP registers. + + interrupts: + items: + - description: Core DWC3 interrupt. + - description: High speed power management event for remote wakeup. + - description: Super speed power management event for remote wakeup. + + interrupt-names: + items: + - const: core + - const: hs_pme + - const: ss_pme + + clocks: + items: + - description: Non-sticky module clock. + - description: Sticky module clock. + + clock-names: + items: + - const: non_sticky + - const: sticky + + resets: + items: + - description: Non-sticky module reset. + - description: Sticky module reset. + - description: DRD bus reset. + - description: Top-level reset. + + reset-names: + items: + - const: non_sticky + - const: sticky + - const: drd_bus + - const: top + + power-domains: + items: + - description: Power switchable domain, the child of top domain. + Turning it on puts the controller into full power state, + turning it off puts the controller into power gated state. + - description: Top domain, the parent of power switchable domain. + Turning it on puts the controller into power gated state, + turning it off completely shuts off the controller. + + power-domain-names: + items: + - const: psw + - const: top + + iommus: + maxItems: 1 + + google,usb-cfg-csr: + description: + A phandle to a syscon node used to access the USB configuration + registers. These registers are the top-level wrapper of the USB + subsystem and provide control and status for the integrated USB + controller and USB PHY. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to the syscon node. + - description: USB host controller configuration register offset. + - description: USB custom interrrupts control register offset. + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - resets + - reset-names + - power-domains + - power-domain-names + - google,usb-cfg-csr + +allOf: + - $ref: snps,dwc3-common.yaml# + +unevaluatedProperties: false + +examples: + - | + #include + #include + soc { + #address-cells = <2>; + #size-cells = <2>; + + usb@c400000 { + compatible = "google,lga-dwc3"; + reg = <0 0x0c400000 0 0xd060>; + interrupts = , + , + ; + interrupt-names = "core", "hs_pme", "ss_pme"; + clocks = <&hsion_usbc_non_sticky_clk>, <&hsion_usbc_sticky_clk>; + clock-names = "non_sticky", "sticky"; + resets = <&hsion_resets_usbc_non_sticky>, <&hsion_resets_usbc_sticky>, + <&hsion_resets_usb_drd_bus>, <&hsion_resets_usb_top>; + reset-names = "non_sticky", "sticky", "drd_bus", "top"; + power-domains = <&hsio_n_usb_psw>, <&hsio_n_usb>; + power-domain-names = "psw", "top"; + phys = <&usb_phy 0>; + phy-names = "usb2-phy"; + snps,quirk-frame-length-adjustment = <0x20>; + snps,gfladj-refclk-lpm-sel-quirk; + snps,incr-burst-type-adjustment = <4>; + google,usb-cfg-csr = <&usb_cfg_csr 0x0 0x20>; + }; + }; +... diff --git a/Documentation/devicetree/bindings/usb/microchip,lan9691-dwc3.yaml b/Documentation/devicetree/bindings/usb/microchip,lan9691-dwc3.yaml new file mode 100644 index 000000000000..08113eac74b8 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/microchip,lan9691-dwc3.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/microchip,lan9691-dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip LAN969x SuperSpeed DWC3 USB SoC controller + +maintainers: + - Robert Marko + +select: + properties: + compatible: + contains: + enum: + - microchip,lan9691-dwc3 + required: + - compatible + +properties: + compatible: + items: + - enum: + - microchip,lan9691-dwc3 + - const: snps,dwc3 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: Gated USB DRD clock + - description: Controller reference clock + + clock-names: + items: + - const: bus_early + - const: ref + +unevaluatedProperties: false + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +allOf: + - $ref: snps,dwc3.yaml# + +examples: + - | + #include + + usb@300000 { + compatible = "microchip,lan9691-dwc3", "snps,dwc3"; + reg = <0x300000 0x80000>; + interrupts = ; + clocks = <&clks 12>, <&clks 11>; + clock-names = "bus_early", "ref"; + }; diff --git a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml index 0b8b90dd1951..dc74e70f1b92 100644 --- a/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml +++ b/Documentation/devicetree/bindings/usb/renesas,usbhs.yaml @@ -27,6 +27,7 @@ properties: - renesas,usbhs-r9a07g044 # RZ/G2{L,LC} - renesas,usbhs-r9a07g054 # RZ/V2L - renesas,usbhs-r9a08g045 # RZ/G3S + - renesas,usbhs-r9a09g047 # RZ/G3E - renesas,usbhs-r9a09g056 # RZ/V2N - renesas,usbhs-r9a09g057 # RZ/V2H(P) - const: renesas,rzg2l-usbhs diff --git a/Documentation/devicetree/bindings/usb/socionext,uniphier-dwc3.yaml b/Documentation/devicetree/bindings/usb/socionext,uniphier-dwc3.yaml new file mode 100644 index 000000000000..2b253339c199 --- /dev/null +++ b/Documentation/devicetree/bindings/usb/socionext,uniphier-dwc3.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/socionext,uniphier-dwc3.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Socionext Uniphier SuperSpeed DWC3 USB SoC controller + +maintainers: + - Kunihiko Hayashi + - Masami Hiramatsu + +select: + properties: + compatible: + contains: + const: socionext,uniphier-dwc3 + required: + - compatible + +properties: + compatible: + items: + - const: socionext,uniphier-dwc3 + - const: snps,dwc3 + + reg: + maxItems: 1 + + interrupts: + minItems: 1 + items: + - description: Host or single combined interrupt + - description: Peripheral interrupt + + interrupt-names: + minItems: 1 + items: + - enum: + - dwc_usb3 + - host + - const: peripheral + + clocks: + maxItems: 3 + + clock-names: + items: + - const: ref + - const: bus_early + - const: suspend + + phys: + description: 1 to 4 HighSpeed PHYs followed by 1 or 2 SuperSpeed PHYs + minItems: 1 + maxItems: 6 + + resets: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - phys + +unevaluatedProperties: false + +allOf: + - $ref: snps,dwc3.yaml# + +examples: + - | + #include + + usb@65a00000 { + compatible = "socionext,uniphier-dwc3", "snps,dwc3"; + reg = <0x65a00000 0xcd00>; + interrupt-names = "dwc_usb3"; + interrupts = ; + clock-names = "ref", "bus_early", "suspend"; + clocks = <&sys_clk 12>, <&sys_clk 12>, <&sys_clk 12>; + resets = <&usb0_rst 15>; + phys = <&usb0_hsphy0>, <&usb0_hsphy1>, + <&usb0_ssphy0>, <&usb0_ssphy1>; + dr_mode = "host"; + }; diff --git a/Documentation/devicetree/bindings/usb/wch,ch334.yaml b/Documentation/devicetree/bindings/usb/wch,ch334.yaml new file mode 100644 index 000000000000..2fdca14dc1de --- /dev/null +++ b/Documentation/devicetree/bindings/usb/wch,ch334.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/usb/wch,ch334.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: WCH CH334/CH335 USB 2.0 Hub Controller + +maintainers: + - Chaoyi Chen + +allOf: + - $ref: usb-hub.yaml# + +properties: + compatible: + enum: + - usb1a86,8091 + + reg: true + + reset-gpios: + description: GPIO controlling the RESET# pin. + + vdd33-supply: + description: + The regulator that provides 3.3V core power to the hub. + + v5-supply: + description: + The regulator that provides 3.3V or 5V power to the hub. + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + patternProperties: + '^port@': + $ref: /schemas/graph.yaml#/properties/port + + properties: + reg: + minimum: 1 + maximum: 4 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include + usb { + #address-cells = <1>; + #size-cells = <0>; + + hub: hub@1 { + compatible = "usb1a86,8091"; + reg = <1>; + reset-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + v5-supply = <&vcc_3v3>; + vdd33-supply = <&vcc_3v3>; + }; + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index edbce100cae4..ee7fd3cfe203 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1373,6 +1373,8 @@ patternProperties: description: Revolution Robotics, Inc. (Revotics) "^rex,.*": description: iMX6 Rex Project + "^rfdigital,.*": + description: RF Digital Corporation "^richtek,.*": description: Richtek Technology Corporation "^ricoh,.*": diff --git a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt deleted file mode 100644 index a384ff5b3ce8..000000000000 --- a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.txt +++ /dev/null @@ -1,25 +0,0 @@ -* Freescale mpc8xxx watchdog driver (For 83xx, 86xx and 8xx) - -Required properties: -- compatible: Shall contain one of the following: - "mpc83xx_wdt" for an mpc83xx - "fsl,mpc8610-wdt" for an mpc86xx - "fsl,mpc823-wdt" for an mpc8xx -- reg: base physical address and length of the area hosting the - watchdog registers. - On the 83xx, "Watchdog Timer Registers" area: <0x200 0x100> - On the 86xx, "Watchdog Timer Registers" area: <0xe4000 0x100> - On the 8xx, "General System Interface Unit" area: <0x0 0x10> - -Optional properties: -- reg: additional physical address and length (4) of location of the - Reset Status Register (called RSTRSCR on the mpc86xx) - On the 83xx, it is located at offset 0x910 - On the 86xx, it is located at offset 0xe0094 - On the 8xx, it is located at offset 0x288 - -Example: - WDT: watchdog@0 { - compatible = "fsl,mpc823-wdt"; - reg = <0x0 0x10 0x288 0x4>; - }; diff --git a/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml new file mode 100644 index 000000000000..67ad4f1eda8d --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/mpc8xxx-wdt.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/mpc8xxx-wdt.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale MPC8xxx watchdog timer (For 83xx, 86xx and 8xx) + +maintainers: + - J. Neuschäfer + +properties: + compatible: + enum: + - mpc83xx_wdt # for an mpc83xx + - fsl,mpc8610-wdt # for an mpc86xx + - fsl,mpc823-wdt # for an mpc8xx + + device_type: + const: watchdog + + reg: + minItems: 1 + items: + - description: | + Base physical address and length of the area hosting the watchdog + registers. + + On the 83xx, "Watchdog Timer Registers" area: <0x200 0x100> + On the 86xx, "Watchdog Timer Registers" area: <0xe4000 0x100> + On the 8xx, "General System Interface Unit" area: <0x0 0x10> + + - description: | + Additional optional physical address and length (4) of location of + the Reset Status Register (called RSTRSCR on the mpc86xx) + + On the 83xx, it is located at offset 0x910 + On the 86xx, it is located at offset 0xe0094 + On the 8xx, it is located at offset 0x288 + +required: + - compatible + - reg + +allOf: + - $ref: watchdog.yaml# + +additionalProperties: false + +examples: + - | + watchdog@0 { + compatible = "fsl,mpc823-wdt"; + reg = <0x0 0x10 0x288 0x4>; + }; + + - | + watchdog@200 { + compatible = "mpc83xx_wdt"; + reg = <0x200 0x100>; + device_type = "watchdog"; + }; + +... diff --git a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml index f2c4bc900e5f..9f861045b71e 100644 --- a/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/qcom-wdt.yaml @@ -17,6 +17,7 @@ properties: oneOf: - items: - enum: + - qcom,apss-wdt-glymur - qcom,kpss-wdt-ipq4019 - qcom,apss-wdt-ipq5018 - qcom,apss-wdt-ipq5332 diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml index 53fc64f5b56d..41aee1655b0c 100644 --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml @@ -19,7 +19,6 @@ properties: oneOf: - enum: - google,gs101-wdt # for Google gs101 - - samsung,s3c2410-wdt # for S3C2410 - samsung,s3c6410-wdt # for S3C6410, S5PV210 and Exynos4 - samsung,exynos5250-wdt # for Exynos5250 - samsung,exynos5420-wdt # for Exynos5420 @@ -49,6 +48,7 @@ properties: samsung,cluster-index: $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] description: Index of CPU cluster on which watchdog is running (in case of Exynos850, Exynos990 or Google gs101). @@ -74,24 +74,7 @@ allOf: contains: enum: - google,gs101-wdt - - samsung,exynos5250-wdt - - samsung,exynos5420-wdt - - samsung,exynos7-wdt - samsung,exynos850-wdt - - samsung,exynos990-wdt - - samsung,exynosautov9-wdt - - samsung,exynosautov920-wdt - then: - required: - - samsung,syscon-phandle - - if: - properties: - compatible: - contains: - enum: - - google,gs101-wdt - - samsung,exynos850-wdt - - samsung,exynos990-wdt - samsung,exynosautov9-wdt - samsung,exynosautov920-wdt then: @@ -105,10 +88,40 @@ allOf: - const: watchdog - const: watchdog_src samsung,cluster-index: - enum: [0, 1, 2] + enum: [0, 1] required: - samsung,cluster-index - else: + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos990-wdt + then: + properties: + clocks: + items: + - description: Bus clock, used for register interface + - description: Source clock (driving watchdog counter) + clock-names: + items: + - const: watchdog + - const: watchdog_src + required: + - samsung,cluster-index + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: + - samsung,exynos5250-wdt + - samsung,exynos5420-wdt + - samsung,exynos7-wdt + then: properties: clocks: items: @@ -117,6 +130,25 @@ allOf: items: - const: watchdog samsung,cluster-index: false + required: + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: + - samsung,s3c6410-wdt + then: + properties: + clocks: + items: + - description: Bus clock, which is also a source clock + clock-names: + items: + - const: watchdog + samsung,cluster-index: false + samsung,syscon-phandle: false unevaluatedProperties: false diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst index 1594598b3317..f4ed98f701c9 100644 --- a/Documentation/driver-api/dmaengine/provider.rst +++ b/Documentation/driver-api/dmaengine/provider.rst @@ -411,7 +411,7 @@ supported. - This structure can be initialized using the function ``dma_async_tx_descriptor_init``. - - You'll also need to set two fields in this structure: + - You'll also need to set following fields in this structure: - flags: TODO: Can it be modified by the driver itself, or @@ -421,6 +421,9 @@ supported. that is supposed to push the current transaction descriptor to a pending queue, waiting for issue_pending to be called. + - phys: Physical address of the descriptor which is used later by + the dma engine to read the descriptor and initiate transfer. + - In this structure the function pointer callback_result can be initialized in order for the submitter to be notified that a transaction has completed. In the earlier code the function pointer diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 0198ac65e874..7d2b897d66fa 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst @@ -408,7 +408,6 @@ PINCTRL devm_pinctrl_get_select() devm_pinctrl_register() devm_pinctrl_register_and_init() - devm_pinctrl_unregister() POWER devm_reboot_mode_register() diff --git a/Documentation/filesystems/f2fs.rst b/Documentation/filesystems/f2fs.rst index cb90d1ae82d0..7e4031631286 100644 --- a/Documentation/filesystems/f2fs.rst +++ b/Documentation/filesystems/f2fs.rst @@ -206,7 +206,7 @@ fault_type=%d Support configuring fault injection type, should be FAULT_TRUNCATE 0x00000400 FAULT_READ_IO 0x00000800 FAULT_CHECKPOINT 0x00001000 - FAULT_DISCARD 0x00002000 + FAULT_DISCARD 0x00002000 (obsolete) FAULT_WRITE_IO 0x00004000 FAULT_SLAB_ALLOC 0x00008000 FAULT_DQUOT_INIT 0x00010000 @@ -215,8 +215,10 @@ fault_type=%d Support configuring fault injection type, should be FAULT_BLKADDR_CONSISTENCE 0x00080000 FAULT_NO_SEGMENT 0x00100000 FAULT_INCONSISTENT_FOOTER 0x00200000 - FAULT_TIMEOUT 0x00400000 (1000ms) + FAULT_ATOMIC_TIMEOUT 0x00400000 (1000ms) FAULT_VMALLOC 0x00800000 + FAULT_LOCK_TIMEOUT 0x01000000 (1000ms) + FAULT_SKIP_WRITE 0x02000000 =========================== ========== mode=%s Control block allocation mode which supports "adaptive" and "lfs". In "lfs" mode, there should be no random @@ -1033,3 +1035,46 @@ the reserved space back to F2FS for its own use. So, the key idea is, user can do any file operations on /dev/vdc, and reclaim the space after the use, while the space is counted as /data. That doesn't require modifying partition size and filesystem format. + +Per-file Read-Only Large Folio Support +-------------------------------------- + +F2FS implements large folio support on the read path to leverage high-order +page allocation for significant performance gains. To minimize code complexity, +this support is currently excluded from the write path, which requires handling +complex optimizations such as compression and block allocation modes. + +This optional feature is triggered only when a file's immutable bit is set. +Consequently, F2FS will return EOPNOTSUPP if a user attempts to open a cached +file with write permissions, even immediately after clearing the bit. Write +access is only restored once the cached inode is dropped. The usage flow is +demonstrated below: + +.. code-block:: + + # f2fs_io setflags immutable /data/testfile_read_seq + + /* flush and reload the inode to enable the large folio */ + # sync && echo 3 > /proc/sys/vm/drop_caches + + /* mmap(MAP_POPULATE) + mlock() */ + # f2fs_io read 128 0 1024 mmap 1 0 /data/testfile_read_seq + + /* mmap() + fadvise(POSIX_FADV_WILLNEED) + mlock() */ + # f2fs_io read 128 0 1024 fadvise 1 0 /data/testfile_read_seq + + /* mmap() + mlock2(MLOCK_ONFAULT) + madvise(MADV_POPULATE_READ) */ + # f2fs_io read 128 0 1024 madvise 1 0 /data/testfile_read_seq + + # f2fs_io clearflags immutable /data/testfile_read_seq + + # f2fs_io write 1 0 1 zero buffered /data/testfile_read_seq + Failed to open /mnt/test/test: Operation not supported + + /* flush and reload the inode to disable the large folio */ + # sync && echo 3 > /proc/sys/vm/drop_caches + + # f2fs_io write 1 0 1 zero buffered /data/testfile_read_seq + Written 4096 bytes with pattern = zero, total_time = 29 us, max_latency = 28 us + + # rm /data/testfile_read_seq diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst index 412cf11e3298..22b49b295d1f 100644 --- a/Documentation/filesystems/fsverity.rst +++ b/Documentation/filesystems/fsverity.rst @@ -341,6 +341,22 @@ the file has fs-verity enabled. This can perform better than FS_IOC_GETFLAGS and FS_IOC_MEASURE_VERITY because it doesn't require opening the file, and opening verity files can be expensive. +FS_IOC_FSGETXATTR +----------------- + +Since Linux v7.0, the FS_IOC_FSGETXATTR ioctl sets FS_XFLAG_VERITY (0x00020000) +in the returned flags when the file has verity enabled. Note that this attribute +cannot be set with FS_IOC_FSSETXATTR as enabling verity requires input +parameters. See FS_IOC_ENABLE_VERITY. + +file_getattr +------------ + +Since Linux v7.0, the file_getattr() syscall sets FS_XFLAG_VERITY (0x00020000) +in the returned flags when the file has verity enabled. Note that this attribute +cannot be set with file_setattr() as enabling verity requires input parameters. +See FS_IOC_ENABLE_VERITY. + .. _accessing_verity_files: Accessing verity files diff --git a/Documentation/filesystems/overlayfs.rst b/Documentation/filesystems/overlayfs.rst index ab989807a2cb..af5a69f87da4 100644 --- a/Documentation/filesystems/overlayfs.rst +++ b/Documentation/filesystems/overlayfs.rst @@ -753,9 +753,9 @@ Note: the mount options index=off,nfs_export=on are conflicting for a read-write mount and will result in an error. Note: the mount option uuid=off can be used to replace UUID of the underlying -filesystem in file handles with null, and effectively disable UUID checks. This +filesystem in file handles with null, in order to relax the UUID checks. This can be useful in case the underlying disk is copied and the UUID of this copy -is changed. This is only applicable if all lower/upper/work directories are on +is changed. This is only applicable if all lower directories are on the same filesystem, otherwise it will fallback to normal behaviour. @@ -769,7 +769,7 @@ controlled by the "uuid" mount option, which supports these values: UUID of overlayfs is null. fsid is taken from upper most filesystem. - "off": UUID of overlayfs is null. fsid is taken from upper most filesystem. - UUID of underlying layers is ignored. + UUID of underlying layers is ignored and null used instead. - "on": UUID of overlayfs is generated and used to report a unique fsid. UUID is stored in xattr "trusted.overlay.uuid", making overlayfs fsid diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst index 79e2c3008289..52ff1d19405b 100644 --- a/Documentation/filesystems/porting.rst +++ b/Documentation/filesystems/porting.rst @@ -1351,3 +1351,13 @@ and do_rmdir()) are gone; they are replaced with non-consuming analogues (filename_renameat2(), etc.) Callers are adjusted - responsibility for dropping the filenames belongs to them now. + +--- + +**mandatory** + +readlink_copy() now requires link length as the 4th argument. Said length needs +to match what strlen() would return if it was ran on the string. + +However, if the string is freely accessible for the duration of inode's +lifetime, consider using inode_set_cached_link() instead. diff --git a/Documentation/hwmon/emc1403.rst b/Documentation/hwmon/emc1403.rst index 57f833b1a800..77060d515323 100644 --- a/Documentation/hwmon/emc1403.rst +++ b/Documentation/hwmon/emc1403.rst @@ -57,7 +57,7 @@ Supported chips: - https://ww1.microchip.com/downloads/en/DeviceDoc/EMC1438%20DS%20Rev.%201.0%20(04-29-10).pdf Author: - Kalhan Trisal Description diff --git a/Documentation/hwmon/index.rst b/Documentation/hwmon/index.rst index d91dbb20c7dc..b2ca8513cfcd 100644 --- a/Documentation/hwmon/index.rst +++ b/Documentation/hwmon/index.rst @@ -220,7 +220,6 @@ Hardware Monitoring Kernel Drivers q54sj108a2 qnap-mcu-hwmon raspberrypi-hwmon - sa67 sbrmi sbtsi_temp sch5627 diff --git a/Documentation/hwmon/sa67.rst b/Documentation/hwmon/sa67.rst deleted file mode 100644 index 029c7c169b7f..000000000000 --- a/Documentation/hwmon/sa67.rst +++ /dev/null @@ -1,41 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0-only - -Kernel driver sa67mcu -===================== - -Supported chips: - - * Kontron sa67mcu - - Prefix: 'sa67mcu' - - Datasheet: not available - -Authors: Michael Walle - -Description ------------ - -The sa67mcu is a board management controller which also exposes a hardware -monitoring controller. - -The controller has two voltage and one temperature sensor. The values are -hold in two 8 bit registers to form one 16 bit value. Reading the lower byte -will also capture the high byte to make the access atomic. The unit of the -volatge sensors are 1mV and the unit of the temperature sensor is 0.1degC. - -Sysfs entries -------------- - -The following attributes are supported. - -======================= ======================================================== -in0_label "VDDIN" -in0_input Measured VDDIN voltage. - -in1_label "VDD_RTC" -in1_input Measured VDD_RTC voltage. - -temp1_input MCU temperature. Roughly the board temperature. -======================= ======================================================== - diff --git a/Documentation/iio/ad4062.rst b/Documentation/iio/ad4062.rst new file mode 100644 index 000000000000..d77287836430 --- /dev/null +++ b/Documentation/iio/ad4062.rst @@ -0,0 +1,148 @@ +.. SPDX-License-Identifier: GPL-2.0-only + +============= +AD4062 driver +============= + +ADC driver for Analog Devices Inc. AD4060/AD4062 devices. The module name is +``ad4062``. + +Supported devices +================= + +The following chips are supported by this driver: + +* `AD4060 `_ +* `AD4062 `_ + +Wiring modes +============ + +The ADC is interfaced through an I3C bus, and contains two programmable GPIOs. + +The ADC convert-start happens on the SDA rising edge of the I3C stop (P) bit +at the end of the read command. + +The two programmable GPIOS are optional and have a role assigned if present in +the devicetree ``interrupt-names`` property: + +- GP0: Is assigned the role of Threshold Either signal. +- GP1: Is assigned the role of Data Ready signal. + +If the property ``gpio-controller`` is present in the devicetree, then the GPO +not present in the ``interrupt-names`` is exposed as a GPO. + +Device attributes +================= + +The ADC contains only one channel with following attributes: + +.. list-table:: Channel attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``in_voltage_calibscale`` + - Sets the gain scaling factor that the hardware applies to the sample, + to compensate for system gain error. + * - ``in_voltage_oversampling_ratio`` + - Sets device's burst averaging mode to over sample using the + internal sample rate. Value 1 disable the burst averaging mode. + * - ``in_voltage_oversampling_ratio_available`` + - List of available oversampling values. + * - ``in_voltage_raw`` + - Returns the raw ADC voltage value. + * - ``in_voltage_scale`` + - Returns the channel scale in reference to the reference voltage + ``ref-supply`` or ``vdd-supply`` if the former not present. + +Also contain the following device attributes: + +.. list-table:: Device attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``sampling_frequency`` + - Sets the duration of a single scan, used in the burst averaging mode. + The duration is described by ``(n_avg - 1) / fosc + tconv``, where + ``n_avg`` is the oversampling ratio, ``fosc`` is the internal sample + rate and ``tconv`` is the ADC conversion time. + * - ``sampling_frequency_available`` + - Lists the available sampling frequencies, computed on the current + oversampling ratio. If the ratio is 1, the frequency is ``1/tconv``. + +Interrupts +========== + +The interrupts are mapped through the ``interrupt-names`` and ``interrupts`` +properties. + +The ``interrupt-names`` ``gp0`` entry sets the role of Threshold signal, and +entry ``gp1`` the role of Data Ready signal. + +If each is not present, the driver fallback to enabling the same role as an +I3C IBI. + +Low-power mode +============== + +The device enters low-power mode on idle to save power. Enabling an event puts +the device out of the low-power since the ADC autonomously samples to assert +the event condition. + +IIO trigger support +=================== + +An IIO trigger ``ad4062-devX`` is registered by the driver to be used by the +same device, to capture samples to a software buffer. It is required to attach +the trigger to the device by setting the ``current_trigger`` before enabling +and reading the buffer. + +The acquisition is sequential and bounded by the protocol timings, software +latency and internal timings, the sample rate is not configurable. The burst +averaging mode does impact the effective sample rate, since it increases the +internal timing to output a single sample. + +Threshold events +================ + +The ADC supports a monitoring mode to raise threshold events. The driver +supports a single interrupt for both rising and falling readings. + +The feature is enabled/disabled by setting ``thresh_either_en``. During monitor +mode, the device continuously operates in autonomous mode. Any register access +puts the device back in configuration mode, due to this, any access disables +monitor mode. + +The following event attributes are available: + +.. list-table:: Event attributes + :header-rows: 1 + + * - Attribute + - Description + * - ``sampling_frequency`` + - Frequency used in the monitoring mode, sets the device internal sample + rate when the mode is activated. + * - ``sampling_frequency_available`` + - List of available sample rates. + * - ``thresh_either_en`` + - Enable monitoring mode. + * - ``thresh_falling_hysteresis`` + - Set the hysteresis value for the minimum threshold. + * - ``thresh_falling_value`` + - Set the minimum threshold value. + * - ``thresh_rising_hysteresis`` + - Set the hysteresis value for the maximum threshold. + * - ``thresh_rising_value`` + - Set the maximum threshold value. + +GPO controller support +====================== + +The device supports using GP0 and GP1 as GPOs. If the devicetree contains the +node ``gpio-controller```, the device is marked as a GPIO controller and the +GPs not listed in ``interrupt-names`` are exposed as a GPO. The GPIO index +matches the pin name, so if GP0 is not exposed but GP1 is, index 0 is masked +out and only index 1 can be set. diff --git a/Documentation/iio/index.rst b/Documentation/iio/index.rst index 315ae37d6fd4..ba3e609c6a13 100644 --- a/Documentation/iio/index.rst +++ b/Documentation/iio/index.rst @@ -22,6 +22,7 @@ Industrial I/O Kernel Drivers ad3552r ad4000 ad4030 + ad4062 ad4695 ad7191 ad7380 diff --git a/Documentation/leds/index.rst b/Documentation/leds/index.rst index 76fae171039c..bebf44004278 100644 --- a/Documentation/leds/index.rst +++ b/Documentation/leds/index.rst @@ -25,6 +25,7 @@ LEDs leds-lp5523 leds-lp5562 leds-lp55xx + leds-lp5812 leds-mlxcpld leds-mt6370-rgb leds-sc27xx diff --git a/Documentation/leds/leds-lp5812.rst b/Documentation/leds/leds-lp5812.rst new file mode 100644 index 000000000000..c2a6368d5149 --- /dev/null +++ b/Documentation/leds/leds-lp5812.rst @@ -0,0 +1,50 @@ +.. SPDX-License-Identifier: GPL-2.0 + +======================== +Kernel driver for lp5812 +======================== + +* TI/National Semiconductor LP5812 LED Driver +* Datasheet: https://www.ti.com/product/LP5812#tech-docs + +Authors: Jared Zhou + +Description +=========== + +The LP5812 is a 4x3 matrix LED driver with support for both manual and +autonomous animation control. This driver provides sysfs interfaces to +control and configure the LP5812 device and its LED channels. + +Sysfs Interface +=============== + +This driver uses the standard multicolor LED class interfaces defined +in Documentation/ABI/testing/sysfs-class-led-multicolor.rst. + +Each LP5812 LED output appears under ``/sys/class/leds/`` with its +assigned label (for example ``LED_A``). + +The following attributes are exposed: + - multi_intensity: Per-channel RGB intensity control + - brightness: Standard brightness control (0-255) + +Autonomous Control Modes +======================== + +The driver also supports autonomous control through pattern configuration +(e.g., direct, tcmscan, or mixscan modes) defined in the device tree. +When configured, the LP5812 can generate transitions and color effects +without CPU intervention. + +Refer to the device tree binding document for valid mode strings and +configuration examples. + +Example Usage +============= + +To control LED_A:: + # Set RGB intensity (R=50, G=50, B=50) + echo 50 50 50 > /sys/class/leds/LED_A/multi_intensity + # Set overall brightness to maximum + echo 255 > /sys/class/leds/LED_A/brightness diff --git a/Documentation/misc-devices/oxsemi-tornado.rst b/Documentation/misc-devices/oxsemi-tornado.rst index b33351bef6cf..fe2e5f726c2b 100644 --- a/Documentation/misc-devices/oxsemi-tornado.rst +++ b/Documentation/misc-devices/oxsemi-tornado.rst @@ -89,31 +89,7 @@ With the baud base set to 15625000 and the unsigned 16-bit UART_DIV_MAX limitation imposed by ``serial8250_get_baud_rate`` standard baud rates below 300bps become unavailable in the regular way, e.g. the rate of 200bps requires the baud base to be divided by 78125 and that is beyond -the unsigned 16-bit range. The historic spd_cust feature can still be -used by encoding the values for, the prescaler, the oversampling rate -and the clock divisor (DLM/DLL) as follows to obtain such rates if so -required: - -:: - - 31 29 28 20 19 16 15 0 - +-----+-----------------+-------+-------------------------------+ - |0 0 0| CPR2:CPR | TCR | DLM:DLL | - +-----+-----------------+-------+-------------------------------+ - -Use a value such encoded for the ``custom_divisor`` field along with the -ASYNC_SPD_CUST flag set in the ``flags`` field in ``struct serial_struct`` -passed with the TIOCSSERIAL ioctl(2), such as with the setserial(8) -utility and its ``divisor`` and ``spd_cust`` parameters, and then select -the baud rate of 38400bps. Note that the value of 0 in TCR sets the -oversampling rate to 16 and prescaler values below 1 in CPR2/CPR are -clamped by the driver to 1. - -For example the value of 0x1f4004e2 will set CPR2/CPR, TCR and DLM/DLL -respectively to 0x1f4, 0x0 and 0x04e2, choosing the prescaler value, -the oversampling rate and the clock divisor of 62.500, 16 and 1250 -respectively. These parameters will set the baud rate for the serial -port to 62500000 / 62.500 / 1250 / 16 = 50bps. +the unsigned 16-bit range. Maciej W. Rozycki diff --git a/Documentation/mm/page_tables.rst b/Documentation/mm/page_tables.rst index e7c69cc32493..126c87628250 100644 --- a/Documentation/mm/page_tables.rst +++ b/Documentation/mm/page_tables.rst @@ -26,9 +26,9 @@ Physical memory address 0 will be *pfn 0* and the highest pfn will be the last page of physical memory the external address bus of the CPU can address. -With a page granularity of 4KB and a address range of 32 bits, pfn 0 is at +With a page granularity of 4KB and an address range of 32 bits, pfn 0 is at address 0x00000000, pfn 1 is at address 0x00001000, pfn 2 is at 0x00002000 -and so on until we reach pfn 0xfffff at 0xfffff000. With 16KB pages pfs are +and so on until we reach pfn 0xfffff at 0xfffff000. With 16KB pages pfns are at 0x00004000, 0x00008000 ... 0xffffc000 and pfn goes from 0 to 0x3ffff. As you can see, with 4KB pages the page base address uses bits 12-31 of the @@ -38,8 +38,8 @@ address, and this is why `PAGE_SHIFT` in this case is defined as 12 and Over time a deeper hierarchy has been developed in response to increasing memory sizes. When Linux was created, 4KB pages and a single page table called `swapper_pg_dir` with 1024 entries was used, covering 4MB which coincided with -the fact that Torvald's first computer had 4MB of physical memory. Entries in -this single table were referred to as *PTE*:s - page table entries. +the fact that Torvalds's first computer had 4MB of physical memory. Entries in +this single table were referred to as *PTEs* - page table entries. The software page table hierarchy reflects the fact that page table hardware has become hierarchical and that in turn is done to save page table memory and @@ -212,7 +212,7 @@ threshold. Additionally, page faults may be also caused by code bugs or by maliciously crafted addresses that the CPU is instructed to access. A thread of a process could use instructions to address (non-shared) memory which does not belong to -its own address space, or could try to execute an instruction that want to write +its own address space, or could try to execute an instruction that wants to write to a read-only location. If the above-mentioned conditions happen in user-space, the kernel sends a @@ -277,5 +277,5 @@ To conclude this high altitude view of how Linux handles page faults, let's add that the page faults handler can be disabled and enabled respectively with `pagefault_disable()` and `pagefault_enable()`. -Several code path make use of the latter two functions because they need to +Several code paths make use of the latter two functions because they need to disable traps into the page faults handler, mostly to prevent deadlocks. diff --git a/Documentation/netlink/specs/nfsd.yaml b/Documentation/netlink/specs/nfsd.yaml index badb2fe57c98..f87b5a05e5e9 100644 --- a/Documentation/netlink/specs/nfsd.yaml +++ b/Documentation/netlink/specs/nfsd.yaml @@ -152,7 +152,7 @@ operations: - compound-ops - name: threads-set - doc: set the number of running threads + doc: set the maximum number of running threads attribute-set: server flags: [admin-perm] do: @@ -165,7 +165,7 @@ operations: - min-threads - name: threads-get - doc: get the number of running threads + doc: get the maximum number of running threads attribute-set: server do: reply: diff --git a/Documentation/networking/ip-sysctl.rst b/Documentation/networking/ip-sysctl.rst index 28c7e4f5ecf9..6921d8594b84 100644 --- a/Documentation/networking/ip-sysctl.rst +++ b/Documentation/networking/ip-sysctl.rst @@ -3234,12 +3234,13 @@ enhanced_dad - BOOLEAN =========== ratelimit - INTEGER - Limit the maximal rates for sending ICMPv6 messages. + Limit the maximal rates for sending ICMPv6 messages to a particular + peer. 0 to disable any limiting, - otherwise the minimal space between responses in milliseconds. + otherwise the space between responses in milliseconds. - Default: 1000 + Default: 100 ratemask - list of comma separated ranges For ICMPv6 message types matching the ranges in the ratemask, limit diff --git a/Documentation/process/maintainer-pgp-guide.rst b/Documentation/process/maintainer-pgp-guide.rst index 2e4da3de25d4..bfe877a1a7e4 100644 --- a/Documentation/process/maintainer-pgp-guide.rst +++ b/Documentation/process/maintainer-pgp-guide.rst @@ -1,3 +1,5 @@ +.. SPDX-License-Identifier: GPL-2.0 + .. _pgpguide: =========================== @@ -864,7 +866,7 @@ don't already have them):: If you have a kernel.org account, then you should `add the kernel.org UID to your key`_ to make WKD more useful to other kernel developers. -.. _`add the kernel.org UID to your key`: https://korg.wiki.kernel.org/userdoc/mail#adding_a_kernelorg_uid_to_your_pgp_key +.. _`add the kernel.org UID to your key`: https://korg.docs.kernel.org/mail.html#adding-a-kernel-org-uid-to-your-pgp-key Web of Trust (WOT) vs. Trust on First Use (TOFU) ------------------------------------------------ diff --git a/Documentation/process/programming-language.rst b/Documentation/process/programming-language.rst index f39d1d3dd9ce..c18e307ccb56 100644 --- a/Documentation/process/programming-language.rst +++ b/Documentation/process/programming-language.rst @@ -3,10 +3,10 @@ Programming Language ==================== -The kernel is written in the C programming language [c-language]_. -More precisely, the kernel is typically compiled with ``gcc`` [gcc]_ +The Linux kernel is written in the C programming language [c-language]_. +More precisely, it is typically compiled with ``gcc`` [gcc]_ under ``-std=gnu11`` [gcc-c-dialect-options]_: the GNU dialect of ISO C11. -``clang`` [clang]_ is also supported, see docs on +``clang`` [clang]_ is also supported; see documentation on :ref:`Building Linux with Clang/LLVM `. This dialect contains many extensions to the language [gnu-extensions]_, diff --git a/Documentation/scheduler/sched-ext.rst b/Documentation/scheduler/sched-ext.rst index 9e2882d937b4..d74c2c2b9ef3 100644 --- a/Documentation/scheduler/sched-ext.rst +++ b/Documentation/scheduler/sched-ext.rst @@ -43,7 +43,6 @@ options should be enabled to use sched_ext: CONFIG_DEBUG_INFO_BTF=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_BPF_JIT_DEFAULT_ON=y - CONFIG_PAHOLE_HAS_BTF_TAG=y sched_ext is used only when the BPF scheduler is loaded and running. @@ -58,7 +57,8 @@ in ``ops->flags``, all ``SCHED_NORMAL``, ``SCHED_BATCH``, ``SCHED_IDLE``, and However, when the BPF scheduler is loaded and ``SCX_OPS_SWITCH_PARTIAL`` is set in ``ops->flags``, only tasks with the ``SCHED_EXT`` policy are scheduled by sched_ext, while tasks with ``SCHED_NORMAL``, ``SCHED_BATCH`` and -``SCHED_IDLE`` policies are scheduled by the fair-class scheduler. +``SCHED_IDLE`` policies are scheduled by the fair-class scheduler which has +higher sched_class precedence than ``SCHED_EXT``. Terminating the sched_ext scheduler program, triggering `SysRq-S`, or detection of any internal error including stalled runnable tasks aborts the @@ -345,6 +345,8 @@ Where to Look The functions prefixed with ``scx_bpf_`` can be called from the BPF scheduler. +* ``kernel/sched/ext_idle.c`` contains the built-in idle CPU selection policy. + * ``tools/sched_ext/`` hosts example BPF scheduler implementations. * ``scx_simple[.bpf].c``: Minimal global FIFO scheduler example using a @@ -353,13 +355,35 @@ Where to Look * ``scx_qmap[.bpf].c``: A multi-level FIFO scheduler supporting five levels of priority implemented with ``BPF_MAP_TYPE_QUEUE``. + * ``scx_central[.bpf].c``: A central FIFO scheduler where all scheduling + decisions are made on one CPU, demonstrating ``LOCAL_ON`` dispatching, + tickless operation, and kthread preemption. + + * ``scx_cpu0[.bpf].c``: A scheduler that queues all tasks to a shared DSQ + and only dispatches them on CPU0 in FIFO order. Useful for testing bypass + behavior. + + * ``scx_flatcg[.bpf].c``: A flattened cgroup hierarchy scheduler + implementing hierarchical weight-based cgroup CPU control by compounding + each cgroup's share at every level into a single flat scheduling layer. + + * ``scx_pair[.bpf].c``: A core-scheduling example that always makes + sibling CPU pairs execute tasks from the same CPU cgroup. + + * ``scx_sdt[.bpf].c``: A variation of ``scx_simple`` demonstrating BPF + arena memory management for per-task data. + + * ``scx_userland[.bpf].c``: A minimal scheduler demonstrating user space + scheduling. Tasks with CPU affinity are direct-dispatched in FIFO order; + all others are scheduled in user space by a simple vruntime scheduler. + ABI Instability =============== The APIs provided by sched_ext to BPF schedulers programs have no stability guarantees. This includes the ops table callbacks and constants defined in ``include/linux/sched/ext.h``, as well as the ``scx_bpf_`` kfuncs defined in -``kernel/sched/ext.c``. +``kernel/sched/ext.c`` and ``kernel/sched/ext_idle.c``. While we will attempt to provide a relatively stable API surface when possible, they are subject to change without warning between kernel diff --git a/Documentation/sound/alsa-configuration.rst b/Documentation/sound/alsa-configuration.rst index 0a4eaa7d66dd..55b845d38236 100644 --- a/Documentation/sound/alsa-configuration.rst +++ b/Documentation/sound/alsa-configuration.rst @@ -2372,6 +2372,10 @@ quirk_flags audible volume * bit 25: ``mixer_capture_min_mute`` Similar to bit 24 but for capture streams + * bit 26: ``skip_iface_setup`` + Skip the probe-time interface setup (usb_set_interface, + init_pitch, init_sample_rate); redundant with + snd_usb_endpoint_prepare() at stream-open time This module supports multiple devices, autoprobe and hotplugging. diff --git a/Documentation/trace/coresight/coresight.rst b/Documentation/trace/coresight/coresight.rst index 806699871b80..d461de4e067e 100644 --- a/Documentation/trace/coresight/coresight.rst +++ b/Documentation/trace/coresight/coresight.rst @@ -613,8 +613,20 @@ They are also listed in the folder /sys/bus/event_source/devices/cs_etm/format/ - Session local version of the system wide setting: :ref:`ETM_MODE_RETURNSTACK ` * - timestamp - - Session local version of the system wide setting: :ref:`ETMv4_MODE_TIMESTAMP - ` + - Controls generation and interval of timestamps. + + 0 = off, 1 = minimum interval .. 15 = maximum interval. + + Values 1 - 14 use a counter that decrements every cycle to generate a + timestamp on underflow. The reload value for the counter is 2 ^ (interval + - 1). If the value is 1 then the reload value is 1, if the value is 11 + then the reload value is 1024 etc. + + Setting the maximum interval (15) will disable the counter generated + timestamps, freeing the counter resource, leaving only ones emitted when + a SYNC packet is generated. The sync interval is controlled with + TRCSYNCPR.PERIOD which is every 4096 bytes of trace by default. + * - cc_threshold - Cycle count threshold value. If nothing is provided here or the provided value is 0, then the default value i.e 0x100 will be used. If provided value is less than minimum cycles threshold diff --git a/Documentation/trace/ftrace.rst b/Documentation/trace/ftrace.rst index d1f313a5f4ad..b9efb148a5c2 100644 --- a/Documentation/trace/ftrace.rst +++ b/Documentation/trace/ftrace.rst @@ -684,6 +684,22 @@ of ftrace. Here is a list of some of the key files: See events.rst for more information. + show_event_filters: + + A list of events that have filters. This shows the + system/event pair along with the filter that is attached to + the event. + + See events.rst for more information. + + show_event_triggers: + + A list of events that have triggers. This shows the + system/event pair along with the trigger that is attached to + the event. + + See events.rst for more information. + available_events: A list of events that can be enabled in tracing. @@ -1290,6 +1306,15 @@ Here are the available options: This will be useful if you want to find out which hashed value is corresponding to the real value in trace log. + bitmask-list + When enabled, bitmasks are displayed as a human-readable list of + ranges (e.g., 0,2-5,7) using the printk "%*pbl" format specifier. + When disabled (the default), bitmasks are displayed in the + traditional hexadecimal bitmap representation. The list format is + particularly useful for tracing CPU masks and other large bitmasks + where individual bit positions are more meaningful than their + hexadecimal encoding. + record-cmd When any event or tracer is enabled, a hook is enabled in the sched_switch trace point to fill comm cache diff --git a/Documentation/usb/gadget-testing.rst b/Documentation/usb/gadget-testing.rst index 5f90af1fb573..a6e8292f320a 100644 --- a/Documentation/usb/gadget-testing.rst +++ b/Documentation/usb/gadget-testing.rst @@ -368,14 +368,15 @@ Function-specific configfs interface The function name to use when creating the function directory is "midi". The MIDI function provides these attributes in its function directory: - =============== ==================================== - buflen MIDI buffer length - id ID string for the USB MIDI adapter - in_ports number of MIDI input ports - index index value for the USB MIDI adapter - out_ports number of MIDI output ports - qlen USB read request queue length - =============== ==================================== + ================ ==================================== + buflen MIDI buffer length + id ID string for the USB MIDI adapter + in_ports number of MIDI input ports + index index value for the USB MIDI adapter + out_ports number of MIDI output ports + qlen USB read request queue length + interface_string USB AudioControl interface string + ================ ==================================== Testing the MIDI function ------------------------- @@ -686,6 +687,7 @@ The SOURCESINK function provides these attributes in its function directory: isoc_mult 0..2 (hs/ss only) isoc_maxburst 0..15 (ss only) bulk_buflen buffer length + bulk_maxburst 0..15 (ss only) bulk_qlen depth of queue for bulk iso_qlen depth of queue for iso =============== ================================== diff --git a/Documentation/userspace-api/ioctl/ioctl-number.rst b/Documentation/userspace-api/ioctl/ioctl-number.rst index b5c6447455fd..331223761fff 100644 --- a/Documentation/userspace-api/ioctl/ioctl-number.rst +++ b/Documentation/userspace-api/ioctl/ioctl-number.rst @@ -397,7 +397,6 @@ Code Seq# Include File Comments 0xCD 01 linux/reiserfs_fs.h Dead since 6.13 0xCE 01-02 uapi/linux/cxl_mem.h Compute Express Link Memory Devices 0xCF 02 fs/smb/client/cifs_ioctl.h -0xDB 00-0F drivers/char/mwave/mwavepub.h 0xDD 00-3F ZFCP device driver see drivers/s390/scsi/ 0xE5 00-3F linux/fuse.h diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst index fc5736839edd..032516783e96 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -1396,7 +1396,10 @@ or its flags may be modified, but it may not be resized. Memory for the region is taken starting at the address denoted by the field userspace_addr, which must point at user addressable memory for the entire memory slot size. Any object may back this memory, including -anonymous memory, ordinary files, and hugetlbfs. +anonymous memory, ordinary files, and hugetlbfs. Changes in the backing +of the memory region are automatically reflected into the guest. +For example, an mmap() that affects the region will be made visible +immediately. Another example is madvise(MADV_DROP). On architectures that support a form of address tagging, userspace_addr must be an untagged address. @@ -1412,11 +1415,6 @@ use it. The latter can be set, if KVM_CAP_READONLY_MEM capability allows it, to make a new slot read-only. In this case, writes to this memory will be posted to userspace as KVM_EXIT_MMIO exits. -When the KVM_CAP_SYNC_MMU capability is available, changes in the backing of -the memory region are automatically reflected into the guest. For example, an -mmap() that affects the region will be made visible immediately. Another -example is madvise(MADV_DROP). - For TDX guest, deleting/moving memory region loses guest memory contents. Read only region isn't supported. Only as-id 0 is supported. @@ -8437,115 +8435,123 @@ KVM_CHECK_EXTENSION. The valid bits in cap.args[0] are: -=================================== ============================================ - KVM_X86_QUIRK_LINT0_REENABLED By default, the reset value for the LVT - LINT0 register is 0x700 (APIC_MODE_EXTINT). - When this quirk is disabled, the reset value - is 0x10000 (APIC_LVT_MASKED). +======================================== ================================================ +KVM_X86_QUIRK_LINT0_REENABLED By default, the reset value for the LVT + LINT0 register is 0x700 (APIC_MODE_EXTINT). + When this quirk is disabled, the reset value + is 0x10000 (APIC_LVT_MASKED). - KVM_X86_QUIRK_CD_NW_CLEARED By default, KVM clears CR0.CD and CR0.NW on - AMD CPUs to workaround buggy guest firmware - that runs in perpetuity with CR0.CD, i.e. - with caches in "no fill" mode. +KVM_X86_QUIRK_CD_NW_CLEARED By default, KVM clears CR0.CD and CR0.NW on + AMD CPUs to workaround buggy guest firmware + that runs in perpetuity with CR0.CD, i.e. + with caches in "no fill" mode. - When this quirk is disabled, KVM does not - change the value of CR0.CD and CR0.NW. + When this quirk is disabled, KVM does not + change the value of CR0.CD and CR0.NW. - KVM_X86_QUIRK_LAPIC_MMIO_HOLE By default, the MMIO LAPIC interface is - available even when configured for x2APIC - mode. When this quirk is disabled, KVM - disables the MMIO LAPIC interface if the - LAPIC is in x2APIC mode. +KVM_X86_QUIRK_LAPIC_MMIO_HOLE By default, the MMIO LAPIC interface is + available even when configured for x2APIC + mode. When this quirk is disabled, KVM + disables the MMIO LAPIC interface if the + LAPIC is in x2APIC mode. - KVM_X86_QUIRK_OUT_7E_INC_RIP By default, KVM pre-increments %rip before - exiting to userspace for an OUT instruction - to port 0x7e. When this quirk is disabled, - KVM does not pre-increment %rip before - exiting to userspace. +KVM_X86_QUIRK_OUT_7E_INC_RIP By default, KVM pre-increments %rip before + exiting to userspace for an OUT instruction + to port 0x7e. When this quirk is disabled, + KVM does not pre-increment %rip before + exiting to userspace. - KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT When this quirk is disabled, KVM sets - CPUID.01H:ECX[bit 3] (MONITOR/MWAIT) if - IA32_MISC_ENABLE[bit 18] (MWAIT) is set. - Additionally, when this quirk is disabled, - KVM clears CPUID.01H:ECX[bit 3] if - IA32_MISC_ENABLE[bit 18] is cleared. +KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT When this quirk is disabled, KVM sets + CPUID.01H:ECX[bit 3] (MONITOR/MWAIT) if + IA32_MISC_ENABLE[bit 18] (MWAIT) is set. + Additionally, when this quirk is disabled, + KVM clears CPUID.01H:ECX[bit 3] if + IA32_MISC_ENABLE[bit 18] is cleared. - KVM_X86_QUIRK_FIX_HYPERCALL_INSN By default, KVM rewrites guest - VMMCALL/VMCALL instructions to match the - vendor's hypercall instruction for the - system. When this quirk is disabled, KVM - will no longer rewrite invalid guest - hypercall instructions. Executing the - incorrect hypercall instruction will - generate a #UD within the guest. +KVM_X86_QUIRK_FIX_HYPERCALL_INSN By default, KVM rewrites guest + VMMCALL/VMCALL instructions to match the + vendor's hypercall instruction for the + system. When this quirk is disabled, KVM + will no longer rewrite invalid guest + hypercall instructions. Executing the + incorrect hypercall instruction will + generate a #UD within the guest. -KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if - they are intercepted) as NOPs regardless of - whether or not MONITOR/MWAIT are supported - according to guest CPUID. When this quirk - is disabled and KVM_X86_DISABLE_EXITS_MWAIT - is not set (MONITOR/MWAIT are intercepted), - KVM will inject a #UD on MONITOR/MWAIT if - they're unsupported per guest CPUID. Note, - KVM will modify MONITOR/MWAIT support in - guest CPUID on writes to MISC_ENABLE if - KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is - disabled. +KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if + they are intercepted) as NOPs regardless of + whether or not MONITOR/MWAIT are supported + according to guest CPUID. When this quirk + is disabled and KVM_X86_DISABLE_EXITS_MWAIT + is not set (MONITOR/MWAIT are intercepted), + KVM will inject a #UD on MONITOR/MWAIT if + they're unsupported per guest CPUID. Note, + KVM will modify MONITOR/MWAIT support in + guest CPUID on writes to MISC_ENABLE if + KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is + disabled. -KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM - invalidates all SPTEs in all memslots and - address spaces when a memslot is deleted or - moved. When this quirk is disabled (or the - VM type isn't KVM_X86_DEFAULT_VM), KVM only - ensures the backing memory of the deleted - or moved memslot isn't reachable, i.e KVM - _may_ invalidate only SPTEs related to the - memslot. +KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM + invalidates all SPTEs in all memslots and + address spaces when a memslot is deleted or + moved. When this quirk is disabled (or the + VM type isn't KVM_X86_DEFAULT_VM), KVM only + ensures the backing memory of the deleted + or moved memslot isn't reachable, i.e KVM + _may_ invalidate only SPTEs related to the + memslot. -KVM_X86_QUIRK_STUFF_FEATURE_MSRS By default, at vCPU creation, KVM sets the - vCPU's MSR_IA32_PERF_CAPABILITIES (0x345), - MSR_IA32_ARCH_CAPABILITIES (0x10a), - MSR_PLATFORM_INFO (0xce), and all VMX MSRs - (0x480..0x492) to the maximal capabilities - supported by KVM. KVM also sets - MSR_IA32_UCODE_REV (0x8b) to an arbitrary - value (which is different for Intel vs. - AMD). Lastly, when guest CPUID is set (by - userspace), KVM modifies select VMX MSR - fields to force consistency between guest - CPUID and L2's effective ISA. When this - quirk is disabled, KVM zeroes the vCPU's MSR - values (with two exceptions, see below), - i.e. treats the feature MSRs like CPUID - leaves and gives userspace full control of - the vCPU model definition. This quirk does - not affect VMX MSRs CR0/CR4_FIXED1 (0x487 - and 0x489), as KVM does now allow them to - be set by userspace (KVM sets them based on - guest CPUID, for safety purposes). +KVM_X86_QUIRK_STUFF_FEATURE_MSRS By default, at vCPU creation, KVM sets the + vCPU's MSR_IA32_PERF_CAPABILITIES (0x345), + MSR_IA32_ARCH_CAPABILITIES (0x10a), + MSR_PLATFORM_INFO (0xce), and all VMX MSRs + (0x480..0x492) to the maximal capabilities + supported by KVM. KVM also sets + MSR_IA32_UCODE_REV (0x8b) to an arbitrary + value (which is different for Intel vs. + AMD). Lastly, when guest CPUID is set (by + userspace), KVM modifies select VMX MSR + fields to force consistency between guest + CPUID and L2's effective ISA. When this + quirk is disabled, KVM zeroes the vCPU's MSR + values (with two exceptions, see below), + i.e. treats the feature MSRs like CPUID + leaves and gives userspace full control of + the vCPU model definition. This quirk does + not affect VMX MSRs CR0/CR4_FIXED1 (0x487 + and 0x489), as KVM does now allow them to + be set by userspace (KVM sets them based on + guest CPUID, for safety purposes). -KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores - guest PAT and forces the effective memory - type to WB in EPT. The quirk is not available - on Intel platforms which are incapable of - safely honoring guest PAT (i.e., without CPU - self-snoop, KVM always ignores guest PAT and - forces effective memory type to WB). It is - also ignored on AMD platforms or, on Intel, - when a VM has non-coherent DMA devices - assigned; KVM always honors guest PAT in - such case. The quirk is needed to avoid - slowdowns on certain Intel Xeon platforms - (e.g. ICX, SPR) where self-snoop feature is - supported but UC is slow enough to cause - issues with some older guests that use - UC instead of WC to map the video RAM. - Userspace can disable the quirk to honor - guest PAT if it knows that there is no such - guest software, for example if it does not - expose a bochs graphics device (which is - known to have had a buggy driver). -=================================== ============================================ +KVM_X86_QUIRK_IGNORE_GUEST_PAT By default, on Intel platforms, KVM ignores + guest PAT and forces the effective memory + type to WB in EPT. The quirk is not available + on Intel platforms which are incapable of + safely honoring guest PAT (i.e., without CPU + self-snoop, KVM always ignores guest PAT and + forces effective memory type to WB). It is + also ignored on AMD platforms or, on Intel, + when a VM has non-coherent DMA devices + assigned; KVM always honors guest PAT in + such case. The quirk is needed to avoid + slowdowns on certain Intel Xeon platforms + (e.g. ICX, SPR) where self-snoop feature is + supported but UC is slow enough to cause + issues with some older guests that use + UC instead of WC to map the video RAM. + Userspace can disable the quirk to honor + guest PAT if it knows that there is no such + guest software, for example if it does not + expose a bochs graphics device (which is + known to have had a buggy driver). + +KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM By default, KVM relaxes the consistency + check for GUEST_IA32_DEBUGCTL in vmcs12 + to allow FREEZE_IN_SMM to be set. When + this quirk is disabled, KVM requires this + bit to be cleared. Note that the vmcs02 + bit is still completely controlled by the + host, regardless of the quirk setting. +======================================== ================================================ 7.32 KVM_CAP_MAX_VCPU_ID ------------------------ diff --git a/Documentation/virt/kvm/locking.rst b/Documentation/virt/kvm/locking.rst index ae8bce7fecbe..662231e958a0 100644 --- a/Documentation/virt/kvm/locking.rst +++ b/Documentation/virt/kvm/locking.rst @@ -17,6 +17,8 @@ The acquisition orders for mutexes are as follows: - kvm->lock is taken outside kvm->slots_lock and kvm->irq_lock +- vcpu->mutex is taken outside kvm->slots_lock and kvm->slots_arch_lock + - kvm->slots_lock is taken outside kvm->irq_lock, though acquiring them together is quite rare. diff --git a/Documentation/watchdog/watchdog-kernel-api.rst b/Documentation/watchdog/watchdog-kernel-api.rst index 243231fe4c0a..5649c54cf6fb 100644 --- a/Documentation/watchdog/watchdog-kernel-api.rst +++ b/Documentation/watchdog/watchdog-kernel-api.rst @@ -293,7 +293,7 @@ To initialize the timeout field, the following function can be used:: extern int watchdog_init_timeout(struct watchdog_device *wdd, unsigned int timeout_parm, - struct device *dev); + const struct device *dev); The watchdog_init_timeout function allows you to initialize the timeout field using the module timeout parameter or by retrieving the timeout-sec property from diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 0a0119edfa82..773241ed9986 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst @@ -209,13 +209,6 @@ iTCO_wdt: ------------------------------------------------- -iTCO_vendor_support: - vendorsupport: - iTCO vendor specific support mode, default=0 (none), - 1=SuperMicro Pent3, 2=SuperMicro Pent4+, 911=Broken SMI BIOS - -------------------------------------------------- - ib700wdt: timeout: Watchdog timeout in seconds. 0<= timeout <=30, default=30. diff --git a/MAINTAINERS b/MAINTAINERS index bacaec38aaf1..d7241695df96 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -993,10 +993,8 @@ F: Documentation/devicetree/bindings/thermal/amazon,al-thermal.yaml F: drivers/thermal/thermal_mmio.c AMAZON ETHERNET DRIVERS -M: Shay Agroskin M: Arthur Kiyanovski -R: David Arinzon -R: Saeed Bishara +M: David Arinzon L: netdev@vger.kernel.org S: Maintained F: Documentation/networking/device_drivers/ethernet/amazon/ena.rst @@ -1292,7 +1290,6 @@ F: include/trace/events/amdxdna.h F: include/uapi/drm/amdxdna_accel.h AMD XGBE DRIVER -M: "Shyam Sundar S K" M: Raju Rangoju L: netdev@vger.kernel.org S: Maintained @@ -1444,6 +1441,14 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad4030.yaml F: Documentation/iio/ad4030.rst F: drivers/iio/adc/ad4030.c +ANALOG DEVICES INC AD4062 DRIVER +M: Jorge Marques +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4062.yaml +F: Documentation/iio/ad4062.rst +F: drivers/iio/adc/ad4062.c + ANALOG DEVICES INC AD4080 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org @@ -1461,6 +1466,14 @@ F: Documentation/ABI/testing/sysfs-bus-iio-adc-ad4130 F: Documentation/devicetree/bindings/iio/adc/adi,ad4130.yaml F: drivers/iio/adc/ad4130.c +ANALOG DEVICES INC AD4134 DRIVER +M: Marcelo Schmitt +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ad4134.yaml +F: drivers/iio/adc/ad4134.c + ANALOG DEVICES INC AD4170-4 DRIVER M: Marcelo Schmitt L: linux-iio@vger.kernel.org @@ -1605,6 +1618,14 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml F: drivers/iio/dac/ad9739a.c +ANALOG DEVICES INC MAX22007 DRIVER +M: Janani Sunil +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/dac/adi,max22007.yaml +F: drivers/iio/dac/max22007.c + ANALOG DEVICES INC ADA4250 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org @@ -1613,6 +1634,14 @@ W: https://ez.analog.com/linux-software-drivers F: Documentation/devicetree/bindings/iio/amplifiers/adi,ada4250.yaml F: drivers/iio/amplifiers/ada4250.c +ANALOG DEVICES INC ADE9000 DRIVER +M: Antoniu Miclaus +L: linux-iio@vger.kernel.org +S: Supported +W: https://ez.analog.com/linux-software-drivers +F: Documentation/devicetree/bindings/iio/adc/adi,ade9000.yaml +F: drivers/iio/adc/ade9000.c + ANALOG DEVICES INC ADF4377 DRIVER M: Antoniu Miclaus L: linux-iio@vger.kernel.org @@ -2488,6 +2517,7 @@ F: Documentation/devicetree/bindings/nvme/apple,nvme-ans.yaml F: Documentation/devicetree/bindings/nvmem/apple,efuses.yaml F: Documentation/devicetree/bindings/nvmem/apple,spmi-nvmem.yaml F: Documentation/devicetree/bindings/pci/apple,pcie.yaml +F: Documentation/devicetree/bindings/phy/apple,atcphy.yaml F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml F: Documentation/devicetree/bindings/power/apple* F: Documentation/devicetree/bindings/power/reset/apple,smc-reboot.yaml @@ -2516,6 +2546,7 @@ F: drivers/mfd/macsmc.c F: drivers/nvme/host/apple.c F: drivers/nvmem/apple-efuses.c F: drivers/nvmem/apple-spmi-nvmem.c +F: drivers/phy/apple/ F: drivers/pinctrl/pinctrl-apple-gpio.c F: drivers/power/reset/macsmc-reboot.c F: drivers/pwm/pwm-apple.c @@ -3806,6 +3837,13 @@ L: linux-leds@vger.kernel.org S: Maintained F: drivers/leds/flash/leds-as3645a.c +AS3668 LED DRIVER +M: Lukas Timmermann +L: linux-leds@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/leds/ams,as3668.yaml +F: drivers/leds/leds-as3668.c + ASAHI KASEI AK7375 LENS VOICE COIL DRIVER M: Tianshu Qiu L: linux-media@vger.kernel.org @@ -3856,6 +3894,15 @@ L: rust-for-linux@vger.kernel.org S: Maintained F: drivers/net/phy/ax88796b_rust.rs +ARM/ASPEED CLOCK SUPPORT +M: Ryan Chen +R: Joel Stanley +L: linux-clk@vger.kernel.org +L: linux-aspeed@lists.ozlabs.org +S: Maintained +F: Documentation/devicetree/bindings/mfd/aspeed,ast2x00-scu.yaml +F: drivers/clk/aspeed/ + ASPEED CRYPTO DRIVER M: Neal Liu L: linux-aspeed@lists.ozlabs.org (moderated for non-subscribers) @@ -3975,7 +4022,7 @@ F: drivers/hwmon/asus_wmi_sensors.c ASYMMETRIC KEYS M: David Howells M: Lukas Wunner -M: Ignat Korchagin +M: Ignat Korchagin L: keyrings@vger.kernel.org L: linux-crypto@vger.kernel.org S: Maintained @@ -3988,7 +4035,7 @@ F: include/linux/verification.h ASYMMETRIC KEYS - ECDSA M: Lukas Wunner -M: Ignat Korchagin +M: Ignat Korchagin R: Stefan Berger L: linux-crypto@vger.kernel.org S: Maintained @@ -3998,14 +4045,14 @@ F: include/crypto/ecc* ASYMMETRIC KEYS - GOST M: Lukas Wunner -M: Ignat Korchagin +M: Ignat Korchagin L: linux-crypto@vger.kernel.org S: Odd fixes F: crypto/ecrdsa* ASYMMETRIC KEYS - RSA M: Lukas Wunner -M: Ignat Korchagin +M: Ignat Korchagin L: linux-crypto@vger.kernel.org S: Maintained F: crypto/rsa* @@ -4568,7 +4615,6 @@ F: drivers/bluetooth/ BLUETOOTH SUBSYSTEM M: Marcel Holtmann -M: Johan Hedberg M: Luiz Augusto von Dentz L: linux-bluetooth@vger.kernel.org S: Supported @@ -5734,6 +5780,7 @@ F: include/trace/events/capability.h F: include/uapi/linux/capability.h F: kernel/capability.c F: security/commoncap.c +F: security/commoncap_test.c CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER M: Kevin Tsai @@ -6162,20 +6209,20 @@ F: drivers/scsi/fnic/ CISCO SCSI HBA DRIVER M: Karan Tilak Kumar +M: Narsimhulu Musini M: Sesidhar Baddela L: linux-scsi@vger.kernel.org S: Supported F: drivers/scsi/snic/ CISCO VIC ETHERNET NIC DRIVER -M: Christian Benvenuti M: Satish Kharat S: Maintained F: drivers/net/ethernet/cisco/enic/ CISCO VIC LOW LATENCY NIC DRIVER -M: Christian Benvenuti M: Nelson Escobar +M: Satish Kharat S: Supported F: drivers/infiniband/hw/usnic/ @@ -6229,7 +6276,7 @@ S: Maintained F: include/linux/clk.h CLOCKSOURCE, CLOCKEVENT DRIVERS -M: Daniel Lezcano +M: Daniel Lezcano M: Thomas Gleixner L: linux-kernel@vger.kernel.org S: Supported @@ -6618,7 +6665,7 @@ F: rust/kernel/cpu.rs CPU IDLE TIME MANAGEMENT FRAMEWORK M: "Rafael J. Wysocki" -M: Daniel Lezcano +M: Daniel Lezcano R: Christian Loehle L: linux-pm@vger.kernel.org S: Maintained @@ -6648,7 +6695,7 @@ F: arch/x86/kernel/msr.c CPUIDLE DRIVER - ARM BIG LITTLE M: Lorenzo Pieralisi -M: Daniel Lezcano +M: Daniel Lezcano L: linux-pm@vger.kernel.org L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained @@ -6656,7 +6703,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git F: drivers/cpuidle/cpuidle-big_little.c CPUIDLE DRIVER - ARM EXYNOS -M: Daniel Lezcano +M: Daniel Lezcano M: Kukjin Kim R: Krzysztof Kozlowski L: linux-pm@vger.kernel.org @@ -7491,6 +7538,7 @@ K: \bdma_(?:buf|fence|resv)\b DMA GENERIC OFFLOAD ENGINE SUBSYSTEM M: Vinod Koul +R: Frank Li L: dmaengine@vger.kernel.org S: Maintained Q: https://patchwork.kernel.org/project/linux-dmaengine/list/ @@ -8578,9 +8626,8 @@ F: drivers/gpu/drm/lima/ F: include/uapi/drm/lima_drm.h DRM DRIVERS FOR LOONGSON -M: Sui Jingfeng L: dri-devel@lists.freedesktop.org -S: Supported +S: Orphan T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/loongson/ @@ -9586,6 +9633,7 @@ F: security/integrity/evm/ EXTENSIBLE FIRMWARE INTERFACE (EFI) M: Ard Biesheuvel +R: Ilias Apalodimas L: linux-efi@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git @@ -10119,8 +10167,8 @@ F: drivers/i2c/busses/i2c-cpm.c FREESCALE IMX / MXC FEC DRIVER M: Wei Fang +R: Frank Li R: Shenwei Wang -R: Clark Wang L: imx@lists.linux.dev L: netdev@vger.kernel.org S: Maintained @@ -10398,6 +10446,7 @@ T: git https://git.kernel.org/pub/scm/fs/fsverity/linux.git F: Documentation/filesystems/fsverity.rst F: fs/verity/ F: include/linux/fsverity.h +F: include/trace/events/fsverity.h F: include/uapi/linux/fsverity.h FT260 FTDI USB-HID TO I2C BRIDGE DRIVER @@ -10431,7 +10480,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git F: Documentation/trace/ftrace* F: arch/*/*/*/*ftrace* F: arch/*/*/*ftrace* -F: include/*/ftrace.h +F: include/*/*ftrace* F: kernel/trace/fgraph.c F: kernel/trace/ftrace* F: samples/ftrace @@ -10808,11 +10857,15 @@ S: Maintained P: Documentation/process/maintainer-soc-clean-dts.rst C: irc://irc.oftc.net/pixel6-kernel-dev F: Documentation/devicetree/bindings/clock/google,gs101-clock.yaml +F: Documentation/devicetree/bindings/phy/google,lga-usb-phy.yaml F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml +F: Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml F: arch/arm64/boot/dts/exynos/google/ F: drivers/clk/samsung/clk-gs101.c +F: drivers/phy/phy-google-usb.c F: drivers/soc/samsung/gs101-pmu.c F: drivers/phy/samsung/phy-gs101-ufs.c +F: drivers/usb/dwc3/dwc3-google.c F: include/dt-bindings/clock/google,gs101* K: [gG]oogle.?[tT]ensor @@ -11394,7 +11447,7 @@ HIMAX HX83112B TOUCHSCREEN SUPPORT M: Job Noorman L: linux-input@vger.kernel.org S: Maintained -F: Documentation/devicetree/bindings/input/touchscreen/himax,hx83112b.yaml +F: Documentation/devicetree/bindings/input/touchscreen/trivial-touch.yaml F: drivers/input/touchscreen/himax_hx83112b.c HIMAX HX852X TOUCHSCREEN DRIVER @@ -11602,6 +11655,13 @@ F: lib/test_hmm* F: mm/hmm* F: tools/testing/selftests/mm/*hmm* +HONEYWELL ABP2030PA PRESSURE SENSOR SERIES IIO DRIVER +M: Petre Rodan +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/pressure/honeywell,abp2030pa.yaml +F: drivers/iio/pressure/abp2030pa* + HONEYWELL HSC030PA PRESSURE SENSOR SERIES IIO DRIVER M: Petre Rodan L: linux-iio@vger.kernel.org @@ -11781,6 +11841,7 @@ F: include/linux/memory-failure.h F: include/trace/events/memory-failure.h F: mm/hwpoison-inject.c F: mm/memory-failure.c +F: tools/testing/selftests/mm/memory-failure.c HYCON HY46XX TOUCHSCREEN SUPPORT M: Giulio Benetti @@ -11858,16 +11919,6 @@ F: include/uapi/linux/hyperv.h F: net/vmw_vsock/hyperv_transport.c F: tools/hv/ -HYPER-V FRAMEBUFFER DRIVER -M: "K. Y. Srinivasan" -M: Haiyang Zhang -M: Wei Liu -M: Dexuan Cui -L: linux-hyperv@vger.kernel.org -S: Obsolete -T: git git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux.git -F: drivers/video/fbdev/hyperv_fb.c - HYPERBUS SUPPORT M: Vignesh Raghavendra R: Tudor Ambarus @@ -12161,7 +12212,6 @@ IBM Power SRIOV Virtual NIC Device Driver M: Haren Myneni M: Rick Lindsley R: Nick Child -R: Thomas Falcon L: netdev@vger.kernel.org S: Maintained F: drivers/net/ethernet/ibm/ibmvnic.* @@ -13082,8 +13132,9 @@ S: Orphan F: drivers/ptp/ptp_dfl_tod.c INTEL QUADRATURE ENCODER PERIPHERAL DRIVER -M: Jarkko Nikula +M: Ilpo Järvinen L: linux-iio@vger.kernel.org +S: Supported F: drivers/counter/intel-qep.c INTEL SCU DRIVERS @@ -13886,7 +13937,7 @@ F: fs/smb/server/ KERNEL UNIT TESTING FRAMEWORK (KUnit) M: Brendan Higgins -M: David Gow +M: David Gow R: Rae Moar L: linux-kselftest@vger.kernel.org L: kunit-dev@googlegroups.com @@ -14355,9 +14406,9 @@ LANTIQ PEF2256 DRIVER M: Herve Codina S: Maintained F: Documentation/devicetree/bindings/net/lantiq,pef2256.yaml -F: drivers/net/wan/framer/pef2256/ +F: drivers/net/wan/framer/ F: drivers/pinctrl/pinctrl-pef2256.c -F: include/linux/framer/pef2256.h +F: include/linux/framer/ LASI 53c700 driver for PARISC M: "James E.J. Bottomley" @@ -14706,7 +14757,7 @@ F: drivers/misc/lis3lv02d/ F: drivers/platform/x86/hp/hp_accel.c LIST KUNIT TEST -M: David Gow +M: David Gow L: linux-kselftest@vger.kernel.org L: kunit-dev@googlegroups.com S: Maintained @@ -15319,10 +15370,8 @@ F: drivers/crypto/marvell/ F: include/linux/soc/marvell/octeontx2/ MARVELL GIGABIT ETHERNET DRIVERS (skge/sky2) -M: Mirko Lindner -M: Stephen Hemminger L: netdev@vger.kernel.org -S: Odd fixes +S: Orphan F: drivers/net/ethernet/marvell/sk* MARVELL LIBERTAS WIRELESS DRIVER @@ -15419,7 +15468,6 @@ MARVELL OCTEONTX2 RVU ADMIN FUNCTION DRIVER M: Sunil Goutham M: Linu Cherian M: Geetha sowjanya -M: Jerin Jacob M: hariprasad M: Subbaraya Sundeep L: netdev@vger.kernel.org @@ -15434,7 +15482,7 @@ S: Supported F: drivers/perf/marvell_pem_pmu.c MARVELL PRESTERA ETHERNET SWITCH DRIVER -M: Taras Chornyi +M: Elad Nachman S: Supported W: https://github.com/Marvell-switching/switchdev-prestera F: drivers/net/ethernet/marvell/prestera/ @@ -15777,6 +15825,13 @@ F: Documentation/ABI/testing/sysfs-bus-iio-potentiometer-mcp4531 F: drivers/iio/potentiometer/mcp4018.c F: drivers/iio/potentiometer/mcp4531.c +MCP47FEB02 MICROCHIP DAC DRIVER +M: Ariana Lazar +L: linux-iio@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml +F: drivers/iio/dac/mcp47feb02.c + MCP4821 DAC DRIVER M: Anshul Dalal L: linux-iio@vger.kernel.org @@ -16101,7 +16156,6 @@ F: drivers/dma/mediatek/ MEDIATEK ETHERNET DRIVER M: Felix Fietkau -M: Sean Wang M: Lorenzo Bianconi L: netdev@vger.kernel.org S: Maintained @@ -16294,8 +16348,6 @@ F: include/soc/mediatek/smi.h MEDIATEK SWITCH DRIVER M: Chester A. Unal M: Daniel Golle -M: DENG Qingfang -M: Sean Wang L: netdev@vger.kernel.org S: Maintained F: drivers/net/dsa/mt7530-mdio.c @@ -16305,7 +16357,6 @@ F: net/dsa/tag_mtk.c MEDIATEK T7XX 5G WWAN MODEM DRIVER M: Chandrashekar Devegowda -R: Chiranjeevi Rapolu R: Liu Haijun R: Ricardo Martinez L: netdev@vger.kernel.org @@ -16590,9 +16641,9 @@ F: mm/balloon.c MEMORY MANAGEMENT - CORE M: Andrew Morton M: David Hildenbrand -R: Lorenzo Stoakes +R: Lorenzo Stoakes R: Liam R. Howlett -R: Vlastimil Babka +R: Vlastimil Babka R: Mike Rapoport R: Suren Baghdasaryan R: Michal Hocko @@ -16720,9 +16771,9 @@ F: mm/workingset.c MEMORY MANAGEMENT - MISC M: Andrew Morton M: David Hildenbrand -R: Lorenzo Stoakes +R: Lorenzo Stoakes R: Liam R. Howlett -R: Vlastimil Babka +R: Vlastimil Babka R: Mike Rapoport R: Suren Baghdasaryan R: Michal Hocko @@ -16777,7 +16828,7 @@ F: mm/oom_kill.c MEMORY MANAGEMENT - PAGE ALLOCATOR M: Andrew Morton -M: Vlastimil Babka +M: Vlastimil Babka R: Suren Baghdasaryan R: Michal Hocko R: Brendan Jackman @@ -16811,7 +16862,7 @@ R: David Hildenbrand R: Michal Hocko R: Qi Zheng R: Shakeel Butt -R: Lorenzo Stoakes +R: Lorenzo Stoakes L: linux-mm@kvack.org S: Maintained F: mm/vmscan.c @@ -16820,10 +16871,10 @@ F: mm/workingset.c MEMORY MANAGEMENT - RMAP (REVERSE MAPPING) M: Andrew Morton M: David Hildenbrand -M: Lorenzo Stoakes +M: Lorenzo Stoakes R: Rik van Riel R: Liam R. Howlett -R: Vlastimil Babka +R: Vlastimil Babka R: Harry Yoo R: Jann Horn L: linux-mm@kvack.org @@ -16865,7 +16916,7 @@ F: mm/swapfile.c MEMORY MANAGEMENT - THP (TRANSPARENT HUGE PAGE) M: Andrew Morton M: David Hildenbrand -M: Lorenzo Stoakes +M: Lorenzo Stoakes R: Zi Yan R: Baolin Wang R: Liam R. Howlett @@ -16905,7 +16956,7 @@ F: tools/testing/selftests/mm/uffd-*.[ch] MEMORY MANAGEMENT - RUST M: Alice Ryhl -R: Lorenzo Stoakes +R: Lorenzo Stoakes R: Liam R. Howlett L: linux-mm@kvack.org L: rust-for-linux@vger.kernel.org @@ -16921,8 +16972,8 @@ F: rust/kernel/page.rs MEMORY MAPPING M: Andrew Morton M: Liam R. Howlett -M: Lorenzo Stoakes -R: Vlastimil Babka +M: Lorenzo Stoakes +R: Vlastimil Babka R: Jann Horn R: Pedro Falcato L: linux-mm@kvack.org @@ -16951,8 +17002,8 @@ MEMORY MAPPING - LOCKING M: Andrew Morton M: Suren Baghdasaryan M: Liam R. Howlett -M: Lorenzo Stoakes -R: Vlastimil Babka +M: Lorenzo Stoakes +R: Vlastimil Babka R: Shakeel Butt L: linux-mm@kvack.org S: Maintained @@ -16966,9 +17017,9 @@ F: mm/mmap_lock.c MEMORY MAPPING - MADVISE (MEMORY ADVICE) M: Andrew Morton M: Liam R. Howlett -M: Lorenzo Stoakes +M: Lorenzo Stoakes M: David Hildenbrand -R: Vlastimil Babka +R: Vlastimil Babka R: Jann Horn L: linux-mm@kvack.org S: Maintained @@ -17611,6 +17662,7 @@ F: Documentation/arch/mips/ F: arch/mips/ F: drivers/platform/mips/ F: include/dt-bindings/mips/ +F: include/linux/platform_data/pic32.h MIPS BOSTON DEVELOPMENT BOARD M: Paul Burton @@ -19162,8 +19214,6 @@ F: tools/objtool/ OCELOT ETHERNET SWITCH DRIVER M: Vladimir Oltean -M: Claudiu Manoil -M: Alexandre Belloni M: UNGLinuxDriver@microchip.com L: netdev@vger.kernel.org S: Supported @@ -19749,7 +19799,6 @@ F: arch/*/boot/dts/ F: include/dt-bindings/ OPENCOMPUTE PTP CLOCK DRIVER -M: Jonathan Lemon M: Vadim Fedorenko L: netdev@vger.kernel.org S: Maintained @@ -20057,9 +20106,8 @@ F: Documentation/devicetree/bindings/pci/marvell,armada-3700-pcie.yaml F: drivers/pci/controller/pci-aardvark.c PCI DRIVER FOR ALTERA PCIE IP -M: Joyce Ooi L: linux-pci@vger.kernel.org -S: Supported +S: Orphan F: Documentation/devicetree/bindings/pci/altr,pcie-root-port.yaml F: drivers/pci/controller/pcie-altera.c @@ -20304,9 +20352,8 @@ S: Supported F: Documentation/PCI/pci-error-recovery.rst PCI MSI DRIVER FOR ALTERA MSI IP -M: Joyce Ooi L: linux-pci@vger.kernel.org -S: Supported +S: Orphan F: Documentation/devicetree/bindings/interrupt-controller/altr,msi-controller.yaml F: drivers/pci/controller/pcie-altera-msi.c @@ -20444,7 +20491,7 @@ F: Documentation/devicetree/bindings/pci/hisilicon,kirin-pcie.yaml F: drivers/pci/controller/dwc/pcie-kirin.c PCIE DRIVER FOR HISILICON STB -M: Shawn Guo +M: Shawn Guo L: linux-pci@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/hisilicon-histb-pcie.txt @@ -21393,9 +21440,8 @@ S: Supported F: drivers/scsi/qedi/ QLOGIC QL4xxx ETHERNET DRIVER -M: Manish Chopra L: netdev@vger.kernel.org -S: Maintained +S: Orphan F: drivers/net/ethernet/qlogic/qed/ F: drivers/net/ethernet/qlogic/qede/ F: include/linux/qed/ @@ -21630,7 +21676,7 @@ S: Maintained F: drivers/net/ethernet/qualcomm/emac/ QUALCOMM ETHQOS ETHERNET DRIVER -M: Vinod Koul +M: Mohd Ayaan Anwar L: netdev@vger.kernel.org L: linux-arm-msm@vger.kernel.org S: Maintained @@ -21890,7 +21936,7 @@ F: drivers/media/radio/radio-tea5777.c RADOS BLOCK DEVICE (RBD) M: Ilya Dryomov -R: Dongsheng Yang +R: Dongsheng Yang L: ceph-devel@vger.kernel.org S: Supported W: http://ceph.com/ @@ -22219,6 +22265,16 @@ L: linux-wireless@vger.kernel.org S: Orphan F: drivers/net/wireless/rsi/ +RELAY +M: Andrew Morton +M: Jens Axboe +M: Jason Xing +L: linux-kernel@vger.kernel.org +S: Maintained +F: Documentation/filesystems/relay.rst +F: include/linux/relay.h +F: kernel/relay.c + REGISTER MAP ABSTRACTION M: Mark Brown L: linux-kernel@vger.kernel.org @@ -22665,6 +22721,7 @@ F: Documentation/devicetree/bindings/i2c/microchip,corei2c.yaml F: Documentation/devicetree/bindings/mailbox/microchip,mpfs-mailbox.yaml F: Documentation/devicetree/bindings/net/can/microchip,mpfs-can.yaml F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-iomux0.yaml +F: Documentation/devicetree/bindings/pinctrl/microchip,mpfs-pinctrl-mssio.yaml F: Documentation/devicetree/bindings/pinctrl/microchip,pic64gx-pinctrl-gpio2.yaml F: Documentation/devicetree/bindings/pwm/microchip,corepwm.yaml F: Documentation/devicetree/bindings/riscv/microchip.yaml @@ -22679,8 +22736,9 @@ F: drivers/gpio/gpio-mpfs.c F: drivers/i2c/busses/i2c-microchip-corei2c.c F: drivers/mailbox/mailbox-mpfs.c F: drivers/pci/controller/plda/pcie-microchip-host.c -F: drivers/pinctrl/pinctrl-mpfs-iomux0.c -F: drivers/pinctrl/pinctrl-pic64gx-gpio2.c +F: drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c +F: drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c +F: drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c F: drivers/pwm/pwm-microchip-core.c F: drivers/reset/reset-mpfs.c F: drivers/rtc/rtc-mpfs.c @@ -23106,8 +23164,8 @@ K: \b(?i:rust)\b RUST [ALLOC] M: Danilo Krummrich -R: Lorenzo Stoakes -R: Vlastimil Babka +R: Lorenzo Stoakes +R: Vlastimil Babka R: Liam R. Howlett R: Uladzislau Rezki L: rust-for-linux@vger.kernel.org @@ -24270,7 +24328,6 @@ F: Documentation/devicetree/bindings/interrupt-controller/kontron,sl28cpld-intc. F: Documentation/devicetree/bindings/pwm/kontron,sl28cpld-pwm.yaml F: Documentation/devicetree/bindings/watchdog/kontron,sl28cpld-wdt.yaml F: drivers/gpio/gpio-sl28cpld.c -F: drivers/hwmon/sa67mcu-hwmon.c F: drivers/hwmon/sl28cpld-hwmon.c F: drivers/irqchip/irq-sl28cpld.c F: drivers/pwm/pwm-sl28cpld.c @@ -24283,12 +24340,13 @@ F: Documentation/devicetree/bindings/nvmem/layouts/kontron,sl28-vpd.yaml F: drivers/nvmem/layouts/sl28vpd.c SLAB ALLOCATOR -M: Vlastimil Babka +M: Vlastimil Babka +M: Harry Yoo M: Andrew Morton +R: Hao Li R: Christoph Lameter R: David Rientjes R: Roman Gushchin -R: Harry Yoo L: linux-mm@kvack.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/vbabka/slab.git @@ -25250,6 +25308,7 @@ STATIC BRANCH/CALL M: Peter Zijlstra M: Josh Poimboeuf M: Jason Baron +M: Alice Ryhl R: Steven Rostedt R: Ard Biesheuvel S: Supported @@ -25261,6 +25320,9 @@ F: include/linux/jump_label*.h F: include/linux/static_call*.h F: kernel/jump_label.c F: kernel/static_call*.c +F: rust/helpers/jump_label.c +F: rust/kernel/generated_arch_static_branch_asm.rs.S +F: rust/kernel/jump_label.rs STI AUDIO (ASoC) DRIVERS M: Arnaud Pouliquen @@ -25695,6 +25757,7 @@ F: include/net/pkt_cls.h F: include/net/pkt_sched.h F: include/net/sch_priv.h F: include/net/tc_act/ +F: include/net/tc_wrapper.h F: include/uapi/linux/pkt_cls.h F: include/uapi/linux/pkt_sched.h F: include/uapi/linux/tc_act/ @@ -26087,6 +26150,17 @@ S: Supported F: Documentation/devicetree/bindings/iio/dac/ti,dac7612.yaml F: drivers/iio/dac/ti-dac7612.c +TEXAS INSTRUMENTS' LP5812 RGB LED DRIVER +M: Nam Tran +L: linux-leds@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/leds/ti,lp5812.yaml +F: Documentation/leds/leds-lp5812.rst +F: drivers/leds/rgb/Kconfig +F: drivers/leds/rgb/Makefile +F: drivers/leds/rgb/leds-lp5812.c +F: drivers/leds/rgb/leds-lp5812.h + TEXAS INSTRUMENTS' LB8864 LED BACKLIGHT DRIVER M: Alexander Sverdlin L: linux-leds@vger.kernel.org @@ -26135,7 +26209,7 @@ F: drivers/media/radio/radio-raremono.c THERMAL M: Rafael J. Wysocki -M: Daniel Lezcano +M: Daniel Lezcano R: Zhang Rui R: Lukasz Luba L: linux-pm@vger.kernel.org @@ -26165,7 +26239,7 @@ F: drivers/thermal/amlogic_thermal.c THERMAL/CPU_COOLING M: Amit Daniel Kachhap -M: Daniel Lezcano +M: Daniel Lezcano M: Viresh Kumar R: Lukasz Luba L: linux-pm@vger.kernel.org @@ -26261,6 +26335,13 @@ S: Maintained F: Documentation/devicetree/bindings/iio/adc/ti,ads1119.yaml F: drivers/iio/adc/ti-ads1119.c +TI ADS1018 ADC DRIVER +M: Kurt Borja +L: linux-iio@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/iio/adc/ti,ads1018.yaml +F: drivers/iio/adc/ti-ads1018.c + TI ADS7924 ADC DRIVER M: Hugo Villeneuve L: linux-iio@vger.kernel.org @@ -26727,6 +26808,17 @@ F: scripts/tracing/ F: scripts/tracepoint-update.c F: tools/testing/selftests/ftrace/ +TRACING [RUST] +M: Alice Ryhl +M: Steven Rostedt +R: Masami Hiramatsu +R: Mathieu Desnoyers +L: linux-trace-kernel@vger.kernel.org +L: rust-for-linux@vger.kernel.org +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git +F: rust/kernel/tracepoint.rs + TRACING MMIO ACCESSES (MMIOTRACE) M: Steven Rostedt M: Masami Hiramatsu @@ -29086,7 +29178,7 @@ K: zstd ZSWAP COMPRESSED SWAP CACHING M: Johannes Weiner -M: Yosry Ahmed +M: Yosry Ahmed M: Nhat Pham R: Chengming Zhou L: linux-mm@kvack.org diff --git a/Makefile b/Makefile index 13107aa0a5fb..c9b7bee102e8 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 -VERSION = 6 -PATCHLEVEL = 19 +VERSION = 7 +PATCHLEVEL = 0 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = -rc4 NAME = Baby Opossum Posse # *DOCUMENTATION* @@ -476,6 +476,7 @@ KBUILD_USERLDFLAGS := $(USERLDFLAGS) export rust_common_flags := --edition=2021 \ -Zbinary_dep_depinfo=y \ -Astable_features \ + -Aunused_features \ -Dnon_ascii_idents \ -Dunsafe_op_in_unsafe_fn \ -Wmissing_docs \ @@ -1113,6 +1114,9 @@ KBUILD_CFLAGS += -fno-builtin-wcslen # change __FILE__ to the relative path to the source directory ifdef building_out_of_srctree KBUILD_CPPFLAGS += -fmacro-prefix-map=$(srcroot)/= +ifeq ($(call rustc-option-yn, --remap-path-scope=macro),y) +KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= --remap-path-scope=macro +endif endif # include additional Makefiles when needed @@ -1497,6 +1501,15 @@ ifneq ($(wildcard $(resolve_btfids_O)),) $(Q)$(MAKE) -sC $(srctree)/tools/bpf/resolve_btfids O=$(resolve_btfids_O) clean endif +PHONY += objtool_clean objtool_mrproper + +objtool_O = $(abspath $(objtree))/tools/objtool + +objtool_clean objtool_mrproper: +ifneq ($(wildcard $(objtool_O)),) + $(Q)$(MAKE) -sC $(abs_srctree)/tools/objtool O=$(objtool_O) srctree=$(abs_srctree) $(patsubst objtool_%,%,$@) +endif + tools/: FORCE $(Q)mkdir -p $(objtree)/tools $(Q)$(MAKE) O=$(abspath $(objtree)) subdir=tools -C $(srctree)/tools/ @@ -1666,7 +1679,7 @@ vmlinuxclean: $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean $(Q)$(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) clean) -clean: archclean vmlinuxclean resolve_btfids_clean +clean: archclean vmlinuxclean resolve_btfids_clean objtool_clean # mrproper - Delete all generated files, including .config # @@ -1677,7 +1690,7 @@ PHONY += $(mrproper-dirs) mrproper $(mrproper-dirs): $(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@) -mrproper: clean $(mrproper-dirs) +mrproper: clean objtool_mrproper $(mrproper-dirs) $(call cmd,rmfiles) @find . $(RCS_FIND_IGNORE) \ \( -name '*.rmeta' \) \ diff --git a/arch/alpha/kernel/core_marvel.c b/arch/alpha/kernel/core_marvel.c index d38f4d6759e4..92e3312e786e 100644 --- a/arch/alpha/kernel/core_marvel.c +++ b/arch/alpha/kernel/core_marvel.c @@ -861,7 +861,7 @@ marvel_agp_setup(alpha_agp_info *agp) if (!alpha_agpgart_size) return -ENOMEM; - aper = kmalloc(sizeof(*aper), GFP_KERNEL); + aper = kmalloc_obj(*aper); if (aper == NULL) return -ENOMEM; aper->arena = agp->hose->sg_pci; @@ -1059,7 +1059,7 @@ marvel_agp_info(void) /* * Allocate the info structure. */ - agp = kmalloc(sizeof(*agp), GFP_KERNEL); + agp = kmalloc_obj(*agp); if (!agp) return NULL; diff --git a/arch/alpha/kernel/core_titan.c b/arch/alpha/kernel/core_titan.c index 77f5d68ed04b..6b6b9e6d631f 100644 --- a/arch/alpha/kernel/core_titan.c +++ b/arch/alpha/kernel/core_titan.c @@ -594,7 +594,7 @@ titan_agp_setup(alpha_agp_info *agp) if (!alpha_agpgart_size) return -ENOMEM; - aper = kmalloc(sizeof(struct titan_agp_aperture), GFP_KERNEL); + aper = kmalloc_obj(struct titan_agp_aperture); if (aper == NULL) return -ENOMEM; @@ -760,7 +760,7 @@ titan_agp_info(void) /* * Allocate the info structure. */ - agp = kmalloc(sizeof(*agp), GFP_KERNEL); + agp = kmalloc_obj(*agp); if (!agp) return NULL; diff --git a/arch/alpha/kernel/module.c b/arch/alpha/kernel/module.c index cbefa5a77384..548d1591cfa9 100644 --- a/arch/alpha/kernel/module.c +++ b/arch/alpha/kernel/module.c @@ -46,7 +46,7 @@ process_reloc_for_got(Elf64_Rela *rela, goto found_entry; } - g = kmalloc (sizeof (*g), GFP_KERNEL); + g = kmalloc_obj(*g); g->next = chains[r_sym].next; g->r_addend = r_addend; g->got_offset = *poffset; @@ -93,7 +93,7 @@ module_frob_arch_sections(Elf64_Ehdr *hdr, Elf64_Shdr *sechdrs, } nsyms = symtab->sh_size / sizeof(Elf64_Sym); - chains = kcalloc(nsyms, sizeof(struct got_entry), GFP_KERNEL); + chains = kzalloc_objs(struct got_entry, nsyms); if (!chains) { printk(KERN_ERR "module %s: no memory for symbol chain buffer\n", diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 8e9b4ac86b7e..51a8a4c4572a 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c @@ -220,7 +220,7 @@ static void pdev_save_srm_config(struct pci_dev *dev) printed = 1; } - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kmalloc_obj(*tmp); if (!tmp) { printk(KERN_ERR "%s: kmalloc() failed!\n", __func__); return; diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index f0af444a69a4..4cbcfb1852d5 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -392,7 +392,7 @@ register_cpus(void) int i; for_each_possible_cpu(i) { - struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct cpu *p = kzalloc_obj(*p); if (!p) return -ENOMEM; register_cpu(p, i); diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S index 2efa7dfc798a..2d136c63db16 100644 --- a/arch/alpha/kernel/vmlinux.lds.S +++ b/arch/alpha/kernel/vmlinux.lds.S @@ -71,6 +71,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/arc/kernel/unwind.c b/arch/arc/kernel/unwind.c index 789cfb9ea14e..6fdc751f906e 100644 --- a/arch/arc/kernel/unwind.c +++ b/arch/arc/kernel/unwind.c @@ -366,7 +366,7 @@ void *unwind_add_table(struct module *module, const void *table_start, if (table_size <= 0) return NULL; - table = kmalloc(sizeof(*table), GFP_KERNEL); + table = kmalloc_obj(*table); if (!table) return NULL; diff --git a/arch/arc/kernel/vmlinux.lds.S b/arch/arc/kernel/vmlinux.lds.S index 61a1b2b96e1d..6af63084ff28 100644 --- a/arch/arc/kernel/vmlinux.lds.S +++ b/arch/arc/kernel/vmlinux.lds.S @@ -123,6 +123,7 @@ SECTIONS _end = . ; STABS_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/arc/net/bpf_jit_core.c b/arch/arc/net/bpf_jit_core.c index e3628922c24a..1421eeced0f5 100644 --- a/arch/arc/net/bpf_jit_core.c +++ b/arch/arc/net/bpf_jit_core.c @@ -1140,7 +1140,7 @@ static int jit_prepare_final_mem_alloc(struct jit_context *ctx) } if (ctx->need_extra_pass) { - ctx->jit_data = kzalloc(sizeof(*ctx->jit_data), GFP_KERNEL); + ctx->jit_data = kzalloc_obj(*ctx->jit_data); if (!ctx->jit_data) return -ENOMEM; } diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index fc9b5b7016c3..ec33376f8e2b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -6,6 +6,7 @@ config ARM select ARCH_CORRECT_STACKTRACE_ON_KRETPROBE if HAVE_KRETPROBES && FRAME_POINTER && !ARM_UNWIND select ARCH_HAS_BINFMT_FLAT select ARCH_HAS_CACHE_LINE_SIZE if OF + select ARCH_HAS_CC_CAN_LINK select ARCH_HAS_CPU_CACHE_ALIASING select ARCH_HAS_CPU_FINALIZE_INIT if MMU select ARCH_HAS_CURRENT_STACK_POINTER @@ -1716,6 +1717,18 @@ config KERNEL_MODE_NEON endmenu +config ARCH_CC_CAN_LINK + bool + default $(cc_can_link_user,-mlittle-endian) if CPU_LITTLE_ENDIAN + default $(cc_can_link_user,-mbig-endian -mbe8) if CPU_ENDIAN_BE8 + default $(cc_can_link_user,-mbig-endian -mbe32) if CPU_ENDIAN_BE32 + +config ARCH_USERFLAGS + string + default "-mlittle-endian" if CPU_LITTLE_ENDIAN + default "-mbig-endian -mbe8" if CPU_ENDIAN_BE8 + default "-mbig-endian -mbe32" if CPU_ENDIAN_BE32 + menu "Power management options" source "kernel/power/Kconfig" diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S index d411abd4310e..2d916647df03 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.S +++ b/arch/arm/boot/compressed/vmlinux.lds.S @@ -21,6 +21,7 @@ SECTIONS COMMON_DISCARDS *(.ARM.exidx*) *(.ARM.extab*) + *(.modinfo) *(.note.*) *(.rel.*) *(.printk_index) diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c index cb6ef449b987..55e360452828 100644 --- a/arch/arm/common/locomo.c +++ b/arch/arm/common/locomo.c @@ -222,7 +222,7 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info) struct locomo_dev *dev; int ret; - dev = kzalloc(sizeof(struct locomo_dev), GFP_KERNEL); + dev = kzalloc_obj(struct locomo_dev); if (!dev) { ret = -ENOMEM; goto out; @@ -277,7 +277,7 @@ static int locomo_suspend(struct platform_device *dev, pm_message_t state) struct locomo_save_data *save; unsigned long flags; - save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL); + save = kmalloc_obj(struct locomo_save_data); if (!save) return -ENOMEM; @@ -360,7 +360,7 @@ __locomo_probe(struct device *me, struct resource *mem, int irq) unsigned long r; int i, ret = -ENODEV; - lchip = kzalloc(sizeof(struct locomo), GFP_KERNEL); + lchip = kzalloc_obj(struct locomo); if (!lchip) return -ENOMEM; diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 04ff75dcc20e..449c8bb86453 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c @@ -737,7 +737,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, unsigned i; int ret; - dev = kzalloc(sizeof(struct sa1111_dev), GFP_KERNEL); + dev = kzalloc_obj(struct sa1111_dev); if (!dev) { ret = -ENOMEM; goto err_alloc; @@ -969,7 +969,7 @@ static int sa1111_suspend_noirq(struct device *dev) unsigned int val; void __iomem *base; - save = kmalloc(sizeof(struct sa1111_save_data), GFP_KERNEL); + save = kmalloc_obj(struct sa1111_save_data); if (!save) return -ENOMEM; sachip->saved_state = save; diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index dddb73c96826..90474994757c 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c @@ -185,7 +185,7 @@ static int scoop_probe(struct platform_device *pdev) if (!mem) return -EINVAL; - devptr = kzalloc(sizeof(struct scoop_dev), GFP_KERNEL); + devptr = kzalloc_obj(struct scoop_dev); if (!devptr) return -ENOMEM; diff --git a/arch/arm/kernel/atags_proc.c b/arch/arm/kernel/atags_proc.c index cd09f8ab93e3..8411fbfbcb8b 100644 --- a/arch/arm/kernel/atags_proc.c +++ b/arch/arm/kernel/atags_proc.c @@ -54,7 +54,7 @@ static int __init init_atags_procfs(void) WARN_ON(tag->hdr.tag != ATAG_NONE); - b = kmalloc(struct_size(b, data, size), GFP_KERNEL); + b = kmalloc_flex(*b, data, size); if (!b) goto nomem; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 50999886a8b5..4e8e89a26ca3 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -108,7 +108,7 @@ static unsigned long get_arch_pgd(pgd_t *pgd) static int secondary_biglittle_prepare(unsigned int cpu) { if (!cpu_vtable[cpu]) - cpu_vtable[cpu] = kzalloc(sizeof(*cpu_vtable[cpu]), GFP_KERNEL); + cpu_vtable[cpu] = kzalloc_obj(*cpu_vtable[cpu]); return cpu_vtable[cpu] ? 0 : -ENOMEM; } diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index 2944721e82a2..3d7f7fcf2d87 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -349,7 +349,7 @@ asmlinkage long sys_oabi_semtimedop(int semid, return -E2BIG; if (nsops < 1 || nsops > SEMOPM) return -EINVAL; - sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); + sops = kvmalloc_objs(*sops, nsops); if (!sops) return -ENOMEM; err = 0; diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c index f60547dadc93..c91cb0e1585e 100644 --- a/arch/arm/kernel/unwind.c +++ b/arch/arm/kernel/unwind.c @@ -574,7 +574,7 @@ struct unwind_table *unwind_table_add(unsigned long start, unsigned long size, unsigned long text_size) { unsigned long flags; - struct unwind_table *tab = kmalloc(sizeof(*tab), GFP_KERNEL); + struct unwind_table *tab = kmalloc_obj(*tab); pr_debug("%s(%08lx, %08lx, %08lx, %08lx)\n", __func__, start, size, text_addr, text_size); diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c index 0108f33d6bed..e306d0c5a21c 100644 --- a/arch/arm/kernel/vdso.c +++ b/arch/arm/kernel/vdso.c @@ -179,8 +179,7 @@ static int __init vdso_init(void) text_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; /* Allocate the VDSO text pagelist */ - vdso_text_pagelist = kcalloc(text_pages, sizeof(struct page *), - GFP_KERNEL); + vdso_text_pagelist = kzalloc_objs(struct page *, text_pages); if (vdso_text_pagelist == NULL) return -ENOMEM; diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index f2e8d4fac068..5afb725998ec 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -154,6 +154,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ARM_DETAILS ARM_ASSERTS diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index d592a203f9c6..c07843c3c53d 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S @@ -153,6 +153,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ARM_DETAILS ARM_ASSERTS diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index 6521ab3d24fa..e1b336624883 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c @@ -262,7 +262,7 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) { struct resource *res; - res = kcalloc(2, sizeof(struct resource), GFP_KERNEL); + res = kzalloc_objs(struct resource, 2); if (!res) { printk("out of memory for root bus resources"); return 0; diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index 21cf9a358b90..1cb7d674bc81 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -84,7 +84,7 @@ static int __init ebsa285_leds_init(void) for (i = 0; i < ARRAY_SIZE(ebsa285_leds); i++) { struct ebsa285_led *led; - led = kzalloc(sizeof(*led), GFP_KERNEL); + led = kzalloc_obj(*led); if (!led) break; diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 5f7265b1b34c..c024eefd4978 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -727,7 +727,7 @@ static int __init netwinder_leds_init(void) for (i = 0; i < ARRAY_SIZE(netwinder_leds); i++) { struct netwinder_led *led; - led = kzalloc(sizeof(*led), GFP_KERNEL); + led = kzalloc_obj(*led); if (!led) break; diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 94e4f4a2f73f..b71467c48b87 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -477,7 +477,7 @@ static int imx_mmdc_perf_init(struct platform_device *pdev, void __iomem *mmdc_b char *name; int ret; - pmu_mmdc = kzalloc(sizeof(*pmu_mmdc), GFP_KERNEL); + pmu_mmdc = kzalloc_obj(*pmu_mmdc); if (!pmu_mmdc) { pr_err("failed to allocate PMU device!\n"); return -ENOMEM; diff --git a/arch/arm/mach-mvebu/board-v7.c b/arch/arm/mach-mvebu/board-v7.c index 04ad651d13a0..a0740ab0dca9 100644 --- a/arch/arm/mach-mvebu/board-v7.c +++ b/arch/arm/mach-mvebu/board-v7.c @@ -127,7 +127,7 @@ static void __init i2c_quirk(void) for_each_compatible_node(np, NULL, "marvell,mv78230-i2c") { struct property *new_compat; - new_compat = kzalloc(sizeof(*new_compat), GFP_KERNEL); + new_compat = kzalloc_obj(*new_compat); new_compat->name = kstrdup("compatible", GFP_KERNEL); new_compat->length = sizeof("marvell,mv78230-a0-i2c"); diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index a6b621ff0b87..fa2c1e1aeb96 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -190,7 +190,7 @@ static void __init armada_375_380_coherency_init(struct device_node *np) for_each_compatible_node(cache_dn, NULL, "arm,pl310-cache") { struct property *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); p->name = kstrdup("arm,io-coherent", GFP_KERNEL); of_add_property(cache_dn, p); } diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.c b/arch/arm/mach-mvebu/mvebu-soc-id.c index f436c7b8c7ae..850ed3ea3cc4 100644 --- a/arch/arm/mach-mvebu/mvebu-soc-id.c +++ b/arch/arm/mach-mvebu/mvebu-soc-id.c @@ -154,7 +154,7 @@ static int __init mvebu_soc_device(void) if (!is_id_valid) return 0; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 6e017fa306c8..f639d5004351 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -387,7 +387,7 @@ static void __init mxs_machine_init(void) const u32 *ocotp = mxs_get_ocotp(); int ret; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return; diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index 756966cb715f..e5d102887c22 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -319,7 +319,7 @@ static int __init omap1_system_dma_init(void) goto exit_iounmap; } - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { ret = -ENOMEM; goto exit_iounmap; diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c index 37863bdce9ea..b6cce510c343 100644 --- a/arch/arm/mach-omap1/mcbsp.c +++ b/arch/arm/mach-omap1/mcbsp.c @@ -294,8 +294,7 @@ static void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, { int i; - omap_mcbsp_devices = kcalloc(size, sizeof(struct platform_device *), - GFP_KERNEL); + omap_mcbsp_devices = kzalloc_objs(struct platform_device *, size); if (!omap_mcbsp_devices) { printk(KERN_ERR "Could not register McBSP devices\n"); return; diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 81a912c1145a..399e6d840986 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -125,7 +125,7 @@ static int __init omap1_dm_timer_init(void) goto err_free_pdev; } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) { ret = -ENOMEM; goto err_free_pdata; diff --git a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c index 96c5cdc718c8..2b04e422b46c 100644 --- a/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c +++ b/arch/arm/mach-omap2/clkt2xxx_virt_prcm_set.c @@ -237,7 +237,7 @@ void omap2xxx_clkt_vps_init(void) omap2xxx_clkt_vps_late_init(); omap2xxx_clkt_vps_check_bootloader_rates(); - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) return; init.name = "virt_prcm_set"; diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 7f387706368a..43f5944850e6 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -787,7 +787,7 @@ void __init omap_soc_device_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return; diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 9c8a85198e16..3b48fb20afe4 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -99,7 +99,7 @@ static struct powerdomain *_get_pwrdm(struct device *dev) return NULL; } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (entry) { entry->dev = dev; entry->pwrdm = pwrdm; diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index 800980057373..79db4c49ffc9 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -156,7 +156,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev) !omap_hwmod_parse_module_range(NULL, node, &res)) return -ENODEV; - hwmods = kcalloc(oh_cnt, sizeof(struct omap_hwmod *), GFP_KERNEL); + hwmods = kzalloc_objs(struct omap_hwmod *, oh_cnt); if (!hwmods) { ret = -ENOMEM; goto odbfd_exit; @@ -309,7 +309,7 @@ static struct omap_device *omap_device_alloc(struct platform_device *pdev, int i; struct omap_hwmod **hwmods; - od = kzalloc(sizeof(struct omap_device), GFP_KERNEL); + od = kzalloc_obj(struct omap_device); if (!od) goto oda_exit1; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 111677878d9c..974107ff18b4 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3392,7 +3392,7 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, void __iomem *regs = NULL; unsigned long flags; - sysc = kzalloc(sizeof(*sysc), GFP_KERNEL); + sysc = kzalloc_obj(*sysc); if (!sysc) return -ENOMEM; @@ -3422,7 +3422,7 @@ static int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh, } if (list_empty(&oh->slave_ports)) { - oi = kzalloc(sizeof(*oi), GFP_KERNEL); + oi = kzalloc_obj(*oi); if (!oi) goto out_free_class; @@ -3525,7 +3525,7 @@ int omap_hwmod_init_module(struct device *dev, oh = _lookup(data->name); if (!oh) { - oh = kzalloc(sizeof(*oh), GFP_KERNEL); + oh = kzalloc_obj(*oh); if (!oh) return -ENOMEM; @@ -3536,7 +3536,7 @@ int omap_hwmod_init_module(struct device *dev, /* Unused, can be handled by PRM driver handling resets */ oh->prcm.omap4.flags = HWMOD_OMAP4_NO_CONTEXT_LOSS_BIT; - oh->class = kzalloc(sizeof(*oh->class), GFP_KERNEL); + oh->class = kzalloc_obj(*oh->class); if (!oh->class) { kfree(oh); return -ENOMEM; diff --git a/arch/arm/mach-omap2/pm33xx-core.c b/arch/arm/mach-omap2/pm33xx-core.c index 4abb86dc98fd..865b5251ef67 100644 --- a/arch/arm/mach-omap2/pm33xx-core.c +++ b/arch/arm/mach-omap2/pm33xx-core.c @@ -410,7 +410,7 @@ static int __init amx3_idle_init(struct device_node *cpu_node, int cpu) state_count++; } - idle_states = kcalloc(state_count, sizeof(*idle_states), GFP_KERNEL); + idle_states = kzalloc_objs(*idle_states, state_count); if (!idle_states) return -ENOMEM; diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 68975771e633..9992549c7336 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -410,7 +410,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) if (!pwrdm->pwrsts) return 0; - pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); + pwrst = kmalloc_obj(struct power_state, GFP_ATOMIC); if (!pwrst) return -ENOMEM; pwrst->pwrdm = pwrdm; diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 37b168119fe4..554352e9e1c6 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -132,7 +132,7 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused) !strncmp(pwrdm->name, "l4per", 5)) pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_OFF); - pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC); + pwrst = kmalloc_obj(struct power_state, GFP_ATOMIC); if (!pwrst) return -ENOMEM; diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index d2133423b0c9..758d90e0340b 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -39,7 +39,7 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, while (volt_data[count].volt_nominal) count++; - nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL); + nvalue_table = kzalloc_objs(*nvalue_table, count); if (!nvalue_table) return; diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 3313bc5a63ea..06f5320036b1 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c @@ -169,7 +169,7 @@ static int __init pcie_setup(struct pci_sys_data *sys) /* * Request resources. */ - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) panic("pcie_setup unable to alloc resources"); @@ -490,7 +490,7 @@ static int __init pci_setup(struct pci_sys_data *sys) /* * Request resources */ - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) panic("pci_setup unable to alloc resources"); diff --git a/arch/arm/mach-rpc/ecard.c b/arch/arm/mach-rpc/ecard.c index 2cde4c83b7f9..972465840548 100644 --- a/arch/arm/mach-rpc/ecard.c +++ b/arch/arm/mach-rpc/ecard.c @@ -692,7 +692,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot) unsigned long base; int i; - ec = kzalloc(sizeof(ecard_t), GFP_KERNEL); + ec = kzalloc_obj(ecard_t); if (!ec) { ec = ERR_PTR(-ENOMEM); goto nomem; diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c index e8691921c69a..eafeb38502af 100644 --- a/arch/arm/mach-sa1100/clock.c +++ b/arch/arm/mach-sa1100/clock.c @@ -107,7 +107,7 @@ int __init sa11xx_clk_init(void) clk_hw_register_clkdev(hw, "OSTIMER0", NULL); - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) return -ENOMEM; hw->init = &clk_mpll_init_data; @@ -129,7 +129,7 @@ int __init sa11xx_clk_init(void) FAlnMsk(TUCR_TSEL), 0, &tucr_lock); clk_set_rate(hw->clk, 3686400); - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) return -ENOMEM; hw->init = &clk_gpio27_init_data; diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 5383a26f5116..99ff55e8131d 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -321,7 +321,7 @@ int __init sa11x0_register_fixed_regulator(int n, { struct regulator_init_data *id; - cfg->init_data = id = kzalloc(sizeof(*cfg->init_data), GFP_KERNEL); + cfg->init_data = id = kzalloc_obj(*cfg->init_data); if (!cfg->init_data) return -ENOMEM; diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 88fe79f0a4ed..9e8a3284a6cf 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -276,7 +276,7 @@ static int neponset_probe(struct platform_device *dev) goto err_alloc; } - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { ret = -ENOMEM; goto err_alloc; diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 117e7b07995b..4277ba5b3ae0 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -164,7 +164,7 @@ static int __init rcar_gen2_regulator_quirk(void) if (ret) /* Skip invalid entry and continue */ continue; - quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); + quirk = kzalloc_obj(*quirk); if (!quirk) { ret = -ENOMEM; of_node_put(np); diff --git a/arch/arm/mach-versatile/spc.c b/arch/arm/mach-versatile/spc.c index 2d27777a00d3..7c3191aa3e12 100644 --- a/arch/arm/mach-versatile/spc.c +++ b/arch/arm/mach-versatile/spc.c @@ -395,7 +395,7 @@ static int ve_spc_populate_opps(uint32_t cluster) uint32_t data = 0, off, ret, idx; struct ve_spc_opp *opps; - opps = kcalloc(MAX_OPPS, sizeof(*opps), GFP_KERNEL); + opps = kzalloc_objs(*opps, MAX_OPPS); if (!opps) return -ENOMEM; @@ -442,7 +442,7 @@ static int ve_init_opp_table(struct device *cpu_dev) int __init ve_spc_init(void __iomem *baseaddr, u32 a15_clusid, int irq) { int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -525,7 +525,7 @@ static struct clk *ve_spc_clk_register(struct device *cpu_dev) struct clk_init_data init; struct clk_spc *spc; - spc = kzalloc(sizeof(*spc), GFP_KERNEL); + spc = kzalloc_obj(*spc); if (!spc) return ERR_PTR(-ENOMEM); diff --git a/arch/arm/mach-versatile/versatile.c b/arch/arm/mach-versatile/versatile.c index f0c80d4663ca..581c97dc4ed2 100644 --- a/arch/arm/mach-versatile/versatile.c +++ b/arch/arm/mach-versatile/versatile.c @@ -142,7 +142,7 @@ static void __init versatile_dt_pci_init(void) goto out_put_node; } - newprop = kzalloc(sizeof(*newprop), GFP_KERNEL); + newprop = kzalloc_obj(*newprop); if (!newprop) goto out_put_node; diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 15e8a321a713..f181a287d53d 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -108,7 +108,7 @@ static void __init zynq_init_machine(void) struct soc_device *soc_dev; struct device *parent = NULL; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) goto out; diff --git a/arch/arm/mm/cache-l2x0-pmu.c b/arch/arm/mm/cache-l2x0-pmu.c index 93ef0502b7ff..3d9caf7464bf 100644 --- a/arch/arm/mm/cache-l2x0-pmu.c +++ b/arch/arm/mm/cache-l2x0-pmu.c @@ -507,7 +507,7 @@ static __init int l2x0_pmu_init(void) if (!l2x0_base) return 0; - l2x0_pmu = kzalloc(sizeof(*l2x0_pmu), GFP_KERNEL); + l2x0_pmu = kzalloc_obj(*l2x0_pmu); if (!l2x0_pmu) { pr_warn("Unable to allocate L2x0 PMU\n"); return -ENOMEM; diff --git a/arch/arm/mm/cache-uniphier.c b/arch/arm/mm/cache-uniphier.c index 84a2f17ff32d..06e99ea1a221 100644 --- a/arch/arm/mm/cache-uniphier.c +++ b/arch/arm/mm/cache-uniphier.c @@ -342,7 +342,7 @@ static int __init __uniphier_cache_init(struct device_node *np, return -EINVAL; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index a4c765d24692..f304037d1c34 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -558,8 +558,8 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, } #endif - buf = kzalloc(sizeof(*buf), - gfp & ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM)); + buf = kzalloc_obj(*buf, + gfp & ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM)); if (!buf) return NULL; @@ -1504,7 +1504,7 @@ arm_iommu_create_mapping(struct device *dev, dma_addr_t base, u64 size) bitmap_size = PAGE_SIZE; } - mapping = kzalloc(sizeof(struct dma_iommu_mapping), GFP_KERNEL); + mapping = kzalloc_obj(struct dma_iommu_mapping); if (!mapping) goto err; diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c index 4eb81b7ed03a..447945836c3f 100644 --- a/arch/arm/mm/pgd.c +++ b/arch/arm/mm/pgd.c @@ -17,7 +17,7 @@ #include "mm.h" #ifdef CONFIG_ARM_LPAE -#define _pgd_alloc(mm) kmalloc_array(PTRS_PER_PGD, sizeof(pgd_t), GFP_KERNEL | __GFP_ZERO) +#define _pgd_alloc(mm) kmalloc_objs(pgd_t, PTRS_PER_PGD, GFP_KERNEL | __GFP_ZERO) #define _pgd_free(mm, pgd) kfree(pgd) #else #define _pgd_alloc(mm) __pgd_alloc(mm, 2) diff --git a/arch/arm/mm/physaddr.c b/arch/arm/mm/physaddr.c index 3f263c840ebc..1a37ebfacbba 100644 --- a/arch/arm/mm/physaddr.c +++ b/arch/arm/mm/physaddr.c @@ -38,7 +38,7 @@ static inline bool __virt_addr_valid(unsigned long x) phys_addr_t __virt_to_phys(unsigned long x) { WARN(!__virt_addr_valid(x), - "virt_to_phys used for non-linear address: %pK (%pS)\n", + "virt_to_phys used for non-linear address: %px (%pS)\n", (void *)x, (void *)x); return __virt_to_phys_nodebug(x); diff --git a/arch/arm/probes/kprobes/test-core.c b/arch/arm/probes/kprobes/test-core.c index 171c7076b89f..7a2baa135f0f 100644 --- a/arch/arm/probes/kprobes/test-core.c +++ b/arch/arm/probes/kprobes/test-core.c @@ -763,9 +763,8 @@ static int coverage_start_fn(const struct decode_header *h, void *args) static int coverage_start(const union decode_item *table) { - coverage.base = kmalloc_array(MAX_COVERAGE_ENTRIES, - sizeof(struct coverage_entry), - GFP_KERNEL); + coverage.base = kmalloc_objs(struct coverage_entry, + MAX_COVERAGE_ENTRIES); coverage.num_entries = 0; coverage.nesting = 0; return table_iter(table, coverage_start_fn, &coverage); diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c index 8655bc3d3634..4feed2c2498d 100644 --- a/arch/arm/xen/enlighten.c +++ b/arch/arm/xen/enlighten.c @@ -339,7 +339,7 @@ int __init arch_xen_unpopulated_init(struct resource **res) return -EINVAL; } - regs = kcalloc(nr_reg, sizeof(*regs), GFP_KERNEL); + regs = kzalloc_objs(*regs, nr_reg); if (!regs) { of_node_put(np); return -ENOMEM; @@ -383,7 +383,7 @@ int __init arch_xen_unpopulated_init(struct resource **res) start = regs[i - 1].end + 1; end = regs[i].start - 1; - tmp_res = kzalloc(sizeof(*tmp_res), GFP_KERNEL); + tmp_res = kzalloc_obj(*tmp_res); if (!tmp_res) { rc = -ENOMEM; goto err; diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c index 9da57a5b81c7..d911d91d5832 100644 --- a/arch/arm/xen/p2m.c +++ b/arch/arm/xen/p2m.c @@ -176,7 +176,7 @@ bool __set_phys_to_machine_multi(unsigned long pfn, return true; } - p2m_entry = kzalloc(sizeof(*p2m_entry), GFP_NOWAIT); + p2m_entry = kzalloc_obj(*p2m_entry, GFP_NOWAIT); if (!p2m_entry) return false; diff --git a/arch/arm64/include/asm/cmpxchg.h b/arch/arm64/include/asm/cmpxchg.h index d7a540736741..6cf3cd6873f5 100644 --- a/arch/arm64/include/asm/cmpxchg.h +++ b/arch/arm64/include/asm/cmpxchg.h @@ -91,8 +91,9 @@ __XCHG_GEN(_mb) #define __xchg_wrapper(sfx, ptr, x) \ ({ \ __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __arch_xchg##sfx((unsigned long)(x), (ptr), sizeof(*(ptr))); \ + __ret = (__force __typeof__(*(ptr))) \ + __arch_xchg##sfx((__force unsigned long)(x), (ptr), \ + sizeof(*(ptr))); \ __ret; \ }) @@ -175,9 +176,10 @@ __CMPXCHG_GEN(_mb) #define __cmpxchg_wrapper(sfx, ptr, o, n) \ ({ \ __typeof__(*(ptr)) __ret; \ - __ret = (__typeof__(*(ptr))) \ - __cmpxchg##sfx((ptr), (unsigned long)(o), \ - (unsigned long)(n), sizeof(*(ptr))); \ + __ret = (__force __typeof__(*(ptr))) \ + __cmpxchg##sfx((ptr), (__force unsigned long)(o), \ + (__force unsigned long)(n), \ + sizeof(*(ptr))); \ __ret; \ }) diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h index 83e03abbb2ca..8cbd1e96fd50 100644 --- a/arch/arm64/include/asm/io.h +++ b/arch/arm64/include/asm/io.h @@ -264,19 +264,33 @@ __iowrite64_copy(void __iomem *to, const void *from, size_t count) typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size, pgprot_t *prot); int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook); +void __iomem *__ioremap_prot(phys_addr_t phys, size_t size, pgprot_t prot); +static inline void __iomem *ioremap_prot(phys_addr_t phys, size_t size, + pgprot_t user_prot) +{ + pgprot_t prot; + ptdesc_t user_prot_val = pgprot_val(user_prot); + + if (WARN_ON_ONCE(!(user_prot_val & PTE_USER))) + return NULL; + + prot = __pgprot_modify(PAGE_KERNEL, PTE_ATTRINDX_MASK, + user_prot_val & PTE_ATTRINDX_MASK); + return __ioremap_prot(phys, size, prot); +} #define ioremap_prot ioremap_prot -#define _PAGE_IOREMAP PROT_DEVICE_nGnRE - +#define ioremap(addr, size) \ + __ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRE)) #define ioremap_wc(addr, size) \ - ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC)) + __ioremap_prot((addr), (size), __pgprot(PROT_NORMAL_NC)) #define ioremap_np(addr, size) \ - ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE)) + __ioremap_prot((addr), (size), __pgprot(PROT_DEVICE_nGnRnE)) #define ioremap_encrypted(addr, size) \ - ioremap_prot((addr), (size), PAGE_KERNEL) + __ioremap_prot((addr), (size), PAGE_KERNEL) /* * io{read,write}{16,32,64}be() macros @@ -297,7 +311,7 @@ static inline void __iomem *ioremap_cache(phys_addr_t addr, size_t size) if (pfn_is_map_memory(__phys_to_pfn(addr))) return (void __iomem *)__phys_to_virt(addr); - return ioremap_prot(addr, size, __pgprot(PROT_NORMAL)); + return __ioremap_prot(addr, size, __pgprot(PROT_NORMAL)); } /* diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 5d5a3bbdb95e..70cb9cfd760a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -784,6 +784,9 @@ struct kvm_host_data { /* Number of debug breakpoints/watchpoints for this CPU (minus 1) */ unsigned int debug_brps; unsigned int debug_wrps; + + /* Last vgic_irq part of the AP list recorded in an LR */ + struct vgic_irq *last_lr_irq; }; struct kvm_host_psci_config { @@ -1616,7 +1619,8 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val); (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP)) #define kvm_has_s1poe(k) \ - (kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) + (system_supports_poe() && \ + kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP)) #define kvm_has_ras(k) \ (kvm_has_feat((k), ID_AA64PFR0_EL1, RAS, IMP)) diff --git a/arch/arm64/include/asm/kvm_nested.h b/arch/arm64/include/asm/kvm_nested.h index 905c658057a4..091544e6af44 100644 --- a/arch/arm64/include/asm/kvm_nested.h +++ b/arch/arm64/include/asm/kvm_nested.h @@ -397,6 +397,8 @@ int kvm_vcpu_allocate_vncr_tlb(struct kvm_vcpu *vcpu); int kvm_handle_vncr_abort(struct kvm_vcpu *vcpu); void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val); +u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime); + #define vncr_fixmap(c) \ ({ \ u32 __c = (c); \ diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index d27e8872fe3c..f560e6420267 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -50,11 +50,11 @@ #define _PAGE_DEFAULT (_PROT_DEFAULT | PTE_ATTRINDX(MT_NORMAL)) -#define _PAGE_KERNEL (PROT_NORMAL) -#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY) -#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY) -#define _PAGE_KERNEL_EXEC (PROT_NORMAL & ~PTE_PXN) -#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT) +#define _PAGE_KERNEL (PROT_NORMAL | PTE_DIRTY) +#define _PAGE_KERNEL_RO ((PROT_NORMAL & ~PTE_WRITE) | PTE_RDONLY | PTE_DIRTY) +#define _PAGE_KERNEL_ROX ((PROT_NORMAL & ~(PTE_WRITE | PTE_PXN)) | PTE_RDONLY | PTE_DIRTY) +#define _PAGE_KERNEL_EXEC ((PROT_NORMAL & ~PTE_PXN) | PTE_DIRTY) +#define _PAGE_KERNEL_EXEC_CONT ((PROT_NORMAL & ~PTE_PXN) | PTE_CONT | PTE_DIRTY) #define _PAGE_SHARED (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_UXN | PTE_WRITE) #define _PAGE_SHARED_EXEC (_PAGE_DEFAULT | PTE_USER | PTE_RDONLY | PTE_NG | PTE_PXN | PTE_WRITE) @@ -164,9 +164,6 @@ static inline bool __pure lpa2_is_enabled(void) #define _PAGE_GCS (_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_WRITE | PTE_USER) #define _PAGE_GCS_RO (_PAGE_DEFAULT | PTE_NG | PTE_UXN | PTE_USER) -#define PAGE_GCS __pgprot(_PAGE_GCS) -#define PAGE_GCS_RO __pgprot(_PAGE_GCS_RO) - #define PIE_E0 ( \ PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS), PIE_GCS) | \ PIRx_ELx_PERM_PREP(pte_pi_index(_PAGE_GCS_RO), PIE_R) | \ diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h index d94445b4f3df..b3e58735c49b 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -144,8 +144,6 @@ static inline pteval_t __phys_to_pte_val(phys_addr_t phys) __pte(__phys_to_pte_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)) #define pte_none(pte) (!pte_val(pte)) -#define __pte_clear(mm, addr, ptep) \ - __set_pte(ptep, __pte(0)) #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) /* @@ -1284,6 +1282,13 @@ static inline bool pud_user_accessible_page(pud_t pud, unsigned long addr) /* * Atomic pte/pmd modifications. */ + +static inline void __pte_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + __set_pte(ptep, __pte(0)); +} + static inline int __ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) @@ -1648,10 +1653,10 @@ extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr, extern pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned int nr, int full); -extern int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep); -extern int contpte_ptep_clear_flush_young(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep); +int contpte_test_and_clear_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, unsigned int nr); +int contpte_clear_flush_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, unsigned int nr); extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned int nr); extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma, @@ -1823,7 +1828,7 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, if (likely(!pte_valid_cont(orig_pte))) return __ptep_test_and_clear_young(vma, addr, ptep); - return contpte_ptep_test_and_clear_young(vma, addr, ptep); + return contpte_test_and_clear_young_ptes(vma, addr, ptep, 1); } #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH @@ -1835,7 +1840,18 @@ static inline int ptep_clear_flush_young(struct vm_area_struct *vma, if (likely(!pte_valid_cont(orig_pte))) return __ptep_clear_flush_young(vma, addr, ptep); - return contpte_ptep_clear_flush_young(vma, addr, ptep); + return contpte_clear_flush_young_ptes(vma, addr, ptep, 1); +} + +#define clear_flush_young_ptes clear_flush_young_ptes +static inline int clear_flush_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + unsigned int nr) +{ + if (likely(nr == 1 && !pte_cont(__ptep_get(ptep)))) + return __ptep_clear_flush_young(vma, addr, ptep); + + return contpte_clear_flush_young_ptes(vma, addr, ptep, nr); } #define wrprotect_ptes wrprotect_ptes diff --git a/arch/arm64/include/asm/runtime-const.h b/arch/arm64/include/asm/runtime-const.h index be5915669d23..c3dbd3ae68f6 100644 --- a/arch/arm64/include/asm/runtime-const.h +++ b/arch/arm64/include/asm/runtime-const.h @@ -2,6 +2,10 @@ #ifndef _ASM_RUNTIME_CONST_H #define _ASM_RUNTIME_CONST_H +#ifdef MODULE + #error "Cannot use runtime-const infrastructure from modules" +#endif + #include /* Sigh. You can still run arm64 in BE mode */ diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h index a2d65d7d6aae..1416e652612b 100644 --- a/arch/arm64/include/asm/tlbflush.h +++ b/arch/arm64/include/asm/tlbflush.h @@ -31,19 +31,11 @@ */ #define __TLBI_0(op, arg) asm (ARM64_ASM_PREAMBLE \ "tlbi " #op "\n" \ - ALTERNATIVE("nop\n nop", \ - "dsb ish\n tlbi " #op, \ - ARM64_WORKAROUND_REPEAT_TLBI, \ - CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \ : : ) #define __TLBI_1(op, arg) asm (ARM64_ASM_PREAMBLE \ - "tlbi " #op ", %0\n" \ - ALTERNATIVE("nop\n nop", \ - "dsb ish\n tlbi " #op ", %0", \ - ARM64_WORKAROUND_REPEAT_TLBI, \ - CONFIG_ARM64_WORKAROUND_REPEAT_TLBI) \ - : : "r" (arg)) + "tlbi " #op ", %x0\n" \ + : : "rZ" (arg)) #define __TLBI_N(op, arg, n, ...) __TLBI_##n(op, arg) @@ -181,6 +173,34 @@ static inline unsigned long get_trans_granule(void) (__pages >> (5 * (scale) + 1)) - 1; \ }) +#define __repeat_tlbi_sync(op, arg...) \ +do { \ + if (!alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) \ + break; \ + __tlbi(op, ##arg); \ + dsb(ish); \ +} while (0) + +/* + * Complete broadcast TLB maintenance issued by the host which invalidates + * stage 1 information in the host's own translation regime. + */ +static inline void __tlbi_sync_s1ish(void) +{ + dsb(ish); + __repeat_tlbi_sync(vale1is, 0); +} + +/* + * Complete broadcast TLB maintenance issued by hyp code which invalidates + * stage 1 translation information in any translation regime. + */ +static inline void __tlbi_sync_s1ish_hyp(void) +{ + dsb(ish); + __repeat_tlbi_sync(vale2is, 0); +} + /* * TLB Invalidation * ================ @@ -279,7 +299,7 @@ static inline void flush_tlb_all(void) { dsb(ishst); __tlbi(vmalle1is); - dsb(ish); + __tlbi_sync_s1ish(); isb(); } @@ -291,7 +311,7 @@ static inline void flush_tlb_mm(struct mm_struct *mm) asid = __TLBI_VADDR(0, ASID(mm)); __tlbi(aside1is, asid); __tlbi_user(aside1is, asid); - dsb(ish); + __tlbi_sync_s1ish(); mmu_notifier_arch_invalidate_secondary_tlbs(mm, 0, -1UL); } @@ -345,20 +365,11 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) { flush_tlb_page_nosync(vma, uaddr); - dsb(ish); + __tlbi_sync_s1ish(); } static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm) { - /* - * TLB flush deferral is not required on systems which are affected by - * ARM64_WORKAROUND_REPEAT_TLBI, as __tlbi()/__tlbi_user() implementation - * will have two consecutive TLBI instructions with a dsb(ish) in between - * defeating the purpose (i.e save overall 'dsb ish' cost). - */ - if (alternative_has_cap_unlikely(ARM64_WORKAROUND_REPEAT_TLBI)) - return false; - return true; } @@ -374,7 +385,7 @@ static inline bool arch_tlbbatch_should_defer(struct mm_struct *mm) */ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch) { - dsb(ish); + __tlbi_sync_s1ish(); } /* @@ -509,7 +520,7 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma, { __flush_tlb_range_nosync(vma->vm_mm, start, end, stride, last_level, tlb_level); - dsb(ish); + __tlbi_sync_s1ish(); } static inline void local_flush_tlb_contpte(struct vm_area_struct *vma, @@ -557,7 +568,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end dsb(ishst); __flush_tlb_range_op(vaale1is, start, pages, stride, 0, TLBI_TTL_UNKNOWN, false, lpa2_is_enabled()); - dsb(ish); + __tlbi_sync_s1ish(); isb(); } @@ -571,7 +582,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr) dsb(ishst); __tlbi(vaae1is, addr); - dsb(ish); + __tlbi_sync_s1ish(); isb(); } diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index af90128cfed5..a9d884fd1d00 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -377,7 +377,7 @@ void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) prot = __acpi_get_writethrough_mem_attribute(); } } - return ioremap_prot(phys, size, prot); + return __ioremap_prot(phys, size, prot); } /* diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index c31f8e17732a..32c2dbcc0c64 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -2345,6 +2345,15 @@ static bool can_trap_icv_dir_el1(const struct arm64_cpu_capabilities *entry, !is_midr_in_range_list(has_vgic_v3)) return false; + /* + * pKVM prevents late onlining of CPUs. This means that whatever + * state the capability is in after deprivilege cannot be affected + * by a new CPU booting -- this is garanteed to be a CPU we have + * already seen, and the cap is therefore unchanged. + */ + if (system_capabilities_finalized() && is_protected_kvm_enabled()) + return cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR); + if (is_kernel_in_hyp_mode()) res.a1 = read_sysreg_s(SYS_ICH_VTR_EL2); else diff --git a/arch/arm64/kernel/machine_kexec_file.c b/arch/arm64/kernel/machine_kexec_file.c index 410060ebd86d..fba260ad87a9 100644 --- a/arch/arm64/kernel/machine_kexec_file.c +++ b/arch/arm64/kernel/machine_kexec_file.c @@ -52,7 +52,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) for_each_mem_range(i, &start, &end) nr_ranges++; - cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL); + cmem = kmalloc_flex(*cmem, ranges, nr_ranges); if (!cmem) return -ENOMEM; diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 4a609e9b65de..b9d4998c97ef 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c @@ -37,7 +37,7 @@ __do_compat_cache_op(unsigned long start, unsigned long end) * We pick the reserved-ASID to minimise the impact. */ __tlbi(aside1is, __TLBI_VADDR(0, 0)); - dsb(ish); + __tlbi_sync_s1ish(); } ret = caches_clean_inval_user_pou(start, start + chunk); diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c index 3fe1faab0362..b32f13358fbb 100644 --- a/arch/arm64/kernel/topology.c +++ b/arch/arm64/kernel/topology.c @@ -400,16 +400,25 @@ static inline int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val) { /* - * Abort call on counterless CPU or when interrupts are - * disabled - can lead to deadlock in smp sync call. + * Abort call on counterless CPU. */ if (!cpu_has_amu_feat(cpu)) return -EOPNOTSUPP; - if (WARN_ON_ONCE(irqs_disabled())) - return -EPERM; - - smp_call_function_single(cpu, func, val, 1); + if (irqs_disabled()) { + /* + * When IRQs are disabled (tick path: sched_tick -> + * topology_scale_freq_tick or cppc_scale_freq_tick), only local + * CPU counter reads are allowed. Remote CPU counter read would + * require smp_call_function_single() which is unsafe with IRQs + * disabled. + */ + if (WARN_ON_ONCE(cpu != smp_processor_id())) + return -EPERM; + func(val); + } else { + smp_call_function_single(cpu, func, val, 1); + } return 0; } diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c index 78ddf6bdecad..592dd8668de4 100644 --- a/arch/arm64/kernel/vdso.c +++ b/arch/arm64/kernel/vdso.c @@ -81,9 +81,7 @@ static int __init __vdso_init(enum vdso_abi abi) vdso_info[abi].vdso_code_start) >> PAGE_SHIFT; - vdso_pagelist = kcalloc(vdso_info[abi].vdso_pages, - sizeof(struct page *), - GFP_KERNEL); + vdso_pagelist = kzalloc_objs(struct page *, vdso_info[abi].vdso_pages); if (vdso_pagelist == NULL) return -ENOMEM; diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index ad6133b89e7a..2964aad0362e 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -349,6 +349,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS HEAD_SYMBOLS diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index 4f803fd1c99a..7d1f22fd490b 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -21,7 +21,6 @@ menuconfig KVM bool "Kernel-based Virtual Machine (KVM) support" select KVM_COMMON select KVM_GENERIC_HARDWARE_ENABLING - select KVM_GENERIC_MMU_NOTIFIER select HAVE_KVM_CPU_RELAX_INTERCEPT select KVM_MMIO select KVM_GENERIC_DIRTYLOG_READ_PROTECT diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 94d5b0b99fd1..410ffd41fd73 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -358,7 +358,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) break; case KVM_CAP_IOEVENTFD: case KVM_CAP_USER_MEMORY: - case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: case KVM_CAP_ONE_REG: case KVM_CAP_ARM_PSCI: @@ -854,8 +853,8 @@ static void kvm_init_mpidr_data(struct kvm *kvm) * iterative method. Single vcpu VMs do not need this either. */ if (struct_size(data, cmpidr_to_idx, nr_entries) <= PAGE_SIZE) - data = kzalloc(struct_size(data, cmpidr_to_idx, nr_entries), - GFP_KERNEL_ACCOUNT); + data = kzalloc_flex(*data, cmpidr_to_idx, nr_entries, + GFP_KERNEL_ACCOUNT); if (!data) goto out; diff --git a/arch/arm64/kvm/at.c b/arch/arm64/kvm/at.c index 885bd5bb2f41..c5c5644b1878 100644 --- a/arch/arm64/kvm/at.c +++ b/arch/arm64/kvm/at.c @@ -540,31 +540,8 @@ static int walk_s1(struct kvm_vcpu *vcpu, struct s1_walk_info *wi, wr->pa |= va & GENMASK_ULL(va_bottom - 1, 0); wr->nG = (wi->regime != TR_EL2) && (desc & PTE_NG); - if (wr->nG) { - u64 asid_ttbr, tcr; - - switch (wi->regime) { - case TR_EL10: - tcr = vcpu_read_sys_reg(vcpu, TCR_EL1); - asid_ttbr = ((tcr & TCR_A1) ? - vcpu_read_sys_reg(vcpu, TTBR1_EL1) : - vcpu_read_sys_reg(vcpu, TTBR0_EL1)); - break; - case TR_EL20: - tcr = vcpu_read_sys_reg(vcpu, TCR_EL2); - asid_ttbr = ((tcr & TCR_A1) ? - vcpu_read_sys_reg(vcpu, TTBR1_EL2) : - vcpu_read_sys_reg(vcpu, TTBR0_EL2)); - break; - default: - BUG(); - } - - wr->asid = FIELD_GET(TTBR_ASID_MASK, asid_ttbr); - if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) || - !(tcr & TCR_ASID16)) - wr->asid &= GENMASK(7, 0); - } + if (wr->nG) + wr->asid = get_asid_by_regime(vcpu, wi->regime); return 0; @@ -1527,8 +1504,6 @@ int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr) fail = true; } - isb(); - if (!fail) par = read_sysreg_par(); diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c index 1c87699fd886..332c453b87cf 100644 --- a/arch/arm64/kvm/guest.c +++ b/arch/arm64/kvm/guest.c @@ -29,7 +29,7 @@ #include "trace.h" -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS() }; @@ -42,7 +42,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, hvc_exit_stat), STATS_DESC_COUNTER(VCPU, wfe_exit_stat), diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 38f66a56a766..d815265bd374 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -518,7 +518,7 @@ static int host_stage2_adjust_range(u64 addr, struct kvm_mem_range *range) granule = kvm_granule_size(level); cur.start = ALIGN_DOWN(addr, granule); cur.end = cur.start + granule; - if (!range_included(&cur, range)) + if (!range_included(&cur, range) && level < KVM_PGTABLE_LAST_LEVEL) continue; *range = cur; return 0; diff --git a/arch/arm64/kvm/hyp/nvhe/mm.c b/arch/arm64/kvm/hyp/nvhe/mm.c index ae8391baebc3..218976287d3f 100644 --- a/arch/arm64/kvm/hyp/nvhe/mm.c +++ b/arch/arm64/kvm/hyp/nvhe/mm.c @@ -271,7 +271,7 @@ static void fixmap_clear_slot(struct hyp_fixmap_slot *slot) */ dsb(ishst); __tlbi_level(vale2is, __TLBI_VADDR(addr, 0), level); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); } diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 8e29d7734a15..2f029bfe4755 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -342,6 +342,7 @@ static void pkvm_init_features_from_host(struct pkvm_hyp_vm *hyp_vm, const struc /* No restrictions for non-protected VMs. */ if (!kvm_vm_is_protected(kvm)) { hyp_vm->kvm.arch.flags = host_arch_flags; + hyp_vm->kvm.arch.flags &= ~BIT_ULL(KVM_ARCH_FLAG_ID_REGS_INITIALIZED); bitmap_copy(kvm->arch.vcpu_features, host_kvm->arch.vcpu_features, @@ -391,7 +392,7 @@ static void unpin_host_sve_state(struct pkvm_hyp_vcpu *hyp_vcpu) if (!vcpu_has_feature(&hyp_vcpu->vcpu, KVM_ARM_VCPU_SVE)) return; - sve_state = kern_hyp_va(hyp_vcpu->vcpu.arch.sve_state); + sve_state = hyp_vcpu->vcpu.arch.sve_state; hyp_unpin_shared_mem(sve_state, sve_state + vcpu_sve_state_size(&hyp_vcpu->vcpu)); } @@ -471,6 +472,35 @@ static int pkvm_vcpu_init_sve(struct pkvm_hyp_vcpu *hyp_vcpu, struct kvm_vcpu *h return ret; } +static int vm_copy_id_regs(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + struct pkvm_hyp_vm *hyp_vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu); + const struct kvm *host_kvm = hyp_vm->host_kvm; + struct kvm *kvm = &hyp_vm->kvm; + + if (!test_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &host_kvm->arch.flags)) + return -EINVAL; + + if (test_and_set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags)) + return 0; + + memcpy(kvm->arch.id_regs, host_kvm->arch.id_regs, sizeof(kvm->arch.id_regs)); + + return 0; +} + +static int pkvm_vcpu_init_sysregs(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + int ret = 0; + + if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) + kvm_init_pvm_id_regs(&hyp_vcpu->vcpu); + else + ret = vm_copy_id_regs(hyp_vcpu); + + return ret; +} + static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu, struct pkvm_hyp_vm *hyp_vm, struct kvm_vcpu *host_vcpu) @@ -490,8 +520,9 @@ static int init_pkvm_hyp_vcpu(struct pkvm_hyp_vcpu *hyp_vcpu, hyp_vcpu->vcpu.arch.cflags = READ_ONCE(host_vcpu->arch.cflags); hyp_vcpu->vcpu.arch.mp_state.mp_state = KVM_MP_STATE_STOPPED; - if (pkvm_hyp_vcpu_is_protected(hyp_vcpu)) - kvm_init_pvm_id_regs(&hyp_vcpu->vcpu); + ret = pkvm_vcpu_init_sysregs(hyp_vcpu); + if (ret) + goto done; ret = pkvm_vcpu_init_traps(hyp_vcpu); if (ret) diff --git a/arch/arm64/kvm/hyp/nvhe/tlb.c b/arch/arm64/kvm/hyp/nvhe/tlb.c index 48da9ca9763f..3dc1ce0d27fe 100644 --- a/arch/arm64/kvm/hyp/nvhe/tlb.c +++ b/arch/arm64/kvm/hyp/nvhe/tlb.c @@ -169,7 +169,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, */ dsb(ish); __tlbi(vmalle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -226,7 +226,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu, dsb(ish); __tlbi(vmalle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -240,7 +240,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) enter_vmid_context(mmu, &cxt, false); __tlbi(vmalls12e1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -266,5 +266,5 @@ void __kvm_flush_vm_context(void) /* Same remark as in enter_vmid_context() */ dsb(ish); __tlbi(alle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); } diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c index 0e4ddd28ef5d..9b480f947da2 100644 --- a/arch/arm64/kvm/hyp/pgtable.c +++ b/arch/arm64/kvm/hyp/pgtable.c @@ -501,7 +501,7 @@ static int hyp_unmap_walker(const struct kvm_pgtable_visit_ctx *ctx, *unmapped += granule; } - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); mm_ops->put_page(ctx->ptep); diff --git a/arch/arm64/kvm/hyp/vhe/tlb.c b/arch/arm64/kvm/hyp/vhe/tlb.c index ec2569818629..35855dadfb1b 100644 --- a/arch/arm64/kvm/hyp/vhe/tlb.c +++ b/arch/arm64/kvm/hyp/vhe/tlb.c @@ -115,7 +115,7 @@ void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, */ dsb(ish); __tlbi(vmalle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -176,7 +176,7 @@ void __kvm_tlb_flush_vmid_range(struct kvm_s2_mmu *mmu, dsb(ish); __tlbi(vmalle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -192,7 +192,7 @@ void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu) enter_vmid_context(mmu, &cxt); __tlbi(vmalls12e1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); exit_vmid_context(&cxt); @@ -217,7 +217,7 @@ void __kvm_flush_vm_context(void) { dsb(ishst); __tlbi(alle1is); - dsb(ish); + __tlbi_sync_s1ish_hyp(); } /* @@ -358,7 +358,7 @@ int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding) default: ret = -EINVAL; } - dsb(ish); + __tlbi_sync_s1ish_hyp(); isb(); if (mmu) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index 8c5d259810b2..17d64a1e11e5 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -487,7 +487,7 @@ static int share_pfn_hyp(u64 pfn) goto unlock; } - this = kzalloc(sizeof(*this), GFP_KERNEL); + this = kzalloc_obj(*this); if (!this) { ret = -ENOMEM; goto unlock; @@ -978,7 +978,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t if (err) return err; - pgt = kzalloc(sizeof(*pgt), GFP_KERNEL_ACCOUNT); + pgt = kzalloc_obj(*pgt, GFP_KERNEL_ACCOUNT); if (!pgt) return -ENOMEM; @@ -1155,7 +1155,8 @@ int topup_hyp_memcache(struct kvm_hyp_memcache *mc, unsigned long min_pages) return 0; if (!mc->mapping) { - mc->mapping = kzalloc(sizeof(struct pkvm_mapping), GFP_KERNEL_ACCOUNT); + mc->mapping = kzalloc_obj(struct pkvm_mapping, + GFP_KERNEL_ACCOUNT); if (!mc->mapping) return -ENOMEM; } @@ -1750,17 +1751,16 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, force_pte = (max_map_size == PAGE_SIZE); vma_pagesize = min_t(long, vma_pagesize, max_map_size); + vma_shift = __ffs(vma_pagesize); } /* - * Both the canonical IPA and fault IPA must be hugepage-aligned to - * ensure we find the right PFN and lay down the mapping in the right - * place. + * Both the canonical IPA and fault IPA must be aligned to the + * mapping size to ensure we find the right PFN and lay down the + * mapping in the right place. */ - if (vma_pagesize == PMD_SIZE || vma_pagesize == PUD_SIZE) { - fault_ipa &= ~(vma_pagesize - 1); - ipa &= ~(vma_pagesize - 1); - } + fault_ipa = ALIGN_DOWN(fault_ipa, vma_pagesize); + ipa = ALIGN_DOWN(ipa, vma_pagesize); gfn = ipa >> PAGE_SHIFT; mte_allowed = kvm_vma_mte_allowed(vma); @@ -1838,10 +1838,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, if (exec_fault && s2_force_noncacheable) ret = -ENOEXEC; - if (ret) { - kvm_release_page_unused(page); - return ret; - } + if (ret) + goto out_put_page; /* * Guest performs atomic/exclusive operations on memory with unsupported @@ -1851,7 +1849,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, */ if (esr_fsc_is_excl_atomic_fault(kvm_vcpu_get_esr(vcpu))) { kvm_inject_dabt_excl_atomic(vcpu, kvm_vcpu_get_hfar(vcpu)); - return 1; + ret = 1; + goto out_put_page; } if (nested) @@ -1937,6 +1936,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, mark_page_dirty_in_slot(kvm, memslot, gfn); return ret != -EAGAIN ? ret : 0; + +out_put_page: + kvm_release_page_unused(page); + return ret; } /* Resolve the access fault by making the page young again. */ @@ -2328,7 +2331,7 @@ int __init kvm_mmu_init(u32 hyp_va_bits) goto out; } - hyp_pgtable = kzalloc(sizeof(*hyp_pgtable), GFP_KERNEL); + hyp_pgtable = kzalloc_obj(*hyp_pgtable); if (!hyp_pgtable) { kvm_err("Hyp mode page-table not allocated\n"); err = -ENOMEM; diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index eeea5e692370..2c43097248b2 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -152,31 +152,31 @@ static int get_ia_size(struct s2_walk_info *wi) return 64 - wi->t0sz; } -static int check_base_s2_limits(struct s2_walk_info *wi, +static int check_base_s2_limits(struct kvm_vcpu *vcpu, struct s2_walk_info *wi, int level, int input_size, int stride) { - int start_size, ia_size; + int start_size, pa_max; - ia_size = get_ia_size(wi); + pa_max = kvm_get_pa_bits(vcpu->kvm); /* Check translation limits */ switch (BIT(wi->pgshift)) { case SZ_64K: - if (level == 0 || (level == 1 && ia_size <= 42)) + if (level == 0 || (level == 1 && pa_max <= 42)) return -EFAULT; break; case SZ_16K: - if (level == 0 || (level == 1 && ia_size <= 40)) + if (level == 0 || (level == 1 && pa_max <= 40)) return -EFAULT; break; case SZ_4K: - if (level < 0 || (level == 0 && ia_size <= 42)) + if (level < 0 || (level == 0 && pa_max <= 42)) return -EFAULT; break; } /* Check input size limits */ - if (input_size > ia_size) + if (input_size > pa_max) return -EFAULT; /* Check number of entries in starting level table */ @@ -269,16 +269,19 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa, if (input_size > 48 || input_size < 25) return -EFAULT; - ret = check_base_s2_limits(wi, level, input_size, stride); - if (WARN_ON(ret)) + ret = check_base_s2_limits(vcpu, wi, level, input_size, stride); + if (WARN_ON(ret)) { + out->esr = compute_fsc(0, ESR_ELx_FSC_FAULT); return ret; + } base_lower_bound = 3 + input_size - ((3 - level) * stride + wi->pgshift); base_addr = wi->baddr & GENMASK_ULL(47, base_lower_bound); if (check_output_size(wi, base_addr)) { - out->esr = compute_fsc(level, ESR_ELx_FSC_ADDRSZ); + /* R_BFHQH */ + out->esr = compute_fsc(0, ESR_ELx_FSC_ADDRSZ); return 1; } @@ -293,8 +296,10 @@ static int walk_nested_s2_pgd(struct kvm_vcpu *vcpu, phys_addr_t ipa, paddr = base_addr | index; ret = read_guest_s2_desc(vcpu, paddr, &desc, wi); - if (ret < 0) + if (ret < 0) { + out->esr = ESR_ELx_FSC_SEA_TTW(level); return ret; + } new_desc = desc; @@ -854,6 +859,33 @@ int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2) return kvm_inject_nested_sync(vcpu, esr_el2); } +u16 get_asid_by_regime(struct kvm_vcpu *vcpu, enum trans_regime regime) +{ + enum vcpu_sysreg ttbr_elx; + u64 tcr; + u16 asid; + + switch (regime) { + case TR_EL10: + tcr = vcpu_read_sys_reg(vcpu, TCR_EL1); + ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL1 : TTBR0_EL1; + break; + case TR_EL20: + tcr = vcpu_read_sys_reg(vcpu, TCR_EL2); + ttbr_elx = (tcr & TCR_A1) ? TTBR1_EL2 : TTBR0_EL2; + break; + default: + BUG(); + } + + asid = FIELD_GET(TTBRx_EL1_ASID, vcpu_read_sys_reg(vcpu, ttbr_elx)); + if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) || + !(tcr & TCR_ASID16)) + asid &= GENMASK(7, 0); + + return asid; +} + static void invalidate_vncr(struct vncr_tlb *vt) { vt->valid = false; @@ -1154,9 +1186,6 @@ void kvm_arch_flush_shadow_all(struct kvm *kvm) { int i; - if (!kvm->arch.nested_mmus_size) - return; - for (i = 0; i < kvm->arch.nested_mmus_size; i++) { struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; @@ -1215,8 +1244,8 @@ int kvm_vcpu_allocate_vncr_tlb(struct kvm_vcpu *vcpu) if (!kvm_has_feat(vcpu->kvm, ID_AA64MMFR4_EL1, NV_frac, NV2_ONLY)) return 0; - vcpu->arch.vncr_tlb = kzalloc(sizeof(*vcpu->arch.vncr_tlb), - GFP_KERNEL_ACCOUNT); + vcpu->arch.vncr_tlb = kzalloc_obj(*vcpu->arch.vncr_tlb, + GFP_KERNEL_ACCOUNT); if (!vcpu->arch.vncr_tlb) return -ENOMEM; @@ -1336,20 +1365,8 @@ static bool kvm_vncr_tlb_lookup(struct kvm_vcpu *vcpu) if (read_vncr_el2(vcpu) != vt->gva) return false; - if (vt->wr.nG) { - u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2); - u64 ttbr = ((tcr & TCR_A1) ? - vcpu_read_sys_reg(vcpu, TTBR1_EL2) : - vcpu_read_sys_reg(vcpu, TTBR0_EL2)); - u16 asid; - - asid = FIELD_GET(TTBR_ASID_MASK, ttbr); - if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) || - !(tcr & TCR_ASID16)) - asid &= GENMASK(7, 0); - - return asid == vt->wr.asid; - } + if (vt->wr.nG) + return get_asid_by_regime(vcpu, TR_EL20) == vt->wr.asid; return true; } @@ -1452,21 +1469,8 @@ static void kvm_map_l1_vncr(struct kvm_vcpu *vcpu) if (read_vncr_el2(vcpu) != vt->gva) return; - if (vt->wr.nG) { - u64 tcr = vcpu_read_sys_reg(vcpu, TCR_EL2); - u64 ttbr = ((tcr & TCR_A1) ? - vcpu_read_sys_reg(vcpu, TTBR1_EL2) : - vcpu_read_sys_reg(vcpu, TTBR0_EL2)); - u16 asid; - - asid = FIELD_GET(TTBR_ASID_MASK, ttbr); - if (!kvm_has_feat_enum(vcpu->kvm, ID_AA64MMFR0_EL1, ASIDBITS, 16) || - !(tcr & TCR_ASID16)) - asid &= GENMASK(7, 0); - - if (asid != vt->wr.asid) - return; - } + if (vt->wr.nG && get_asid_by_regime(vcpu, TR_EL20) != vt->wr.asid) + return; vt->cpu = smp_processor_id(); @@ -1704,8 +1708,8 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu) if (kvm->arch.sysreg_masks) goto out; - kvm->arch.sysreg_masks = kzalloc(sizeof(*(kvm->arch.sysreg_masks)), - GFP_KERNEL_ACCOUNT); + kvm->arch.sysreg_masks = kzalloc_obj(*(kvm->arch.sysreg_masks), + GFP_KERNEL_ACCOUNT); if (!kvm->arch.sysreg_masks) return -ENOMEM; diff --git a/arch/arm64/kvm/pmu-emul.c b/arch/arm64/kvm/pmu-emul.c index b03dbda7f1ab..93cc9bbb5cec 100644 --- a/arch/arm64/kvm/pmu-emul.c +++ b/arch/arm64/kvm/pmu-emul.c @@ -797,7 +797,7 @@ void kvm_host_pmu_init(struct arm_pmu *pmu) guard(mutex)(&arm_pmus_lock); - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return; diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c index 6cbe018fd6fd..6a8836207a79 100644 --- a/arch/arm64/kvm/ptdump.c +++ b/arch/arm64/kvm/ptdump.c @@ -119,7 +119,7 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm) struct kvm_pgtable *pgtable = mmu->pgt; int ret; - st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT); + st = kzalloc_obj(struct kvm_ptdump_guest_state, GFP_KERNEL_ACCOUNT); if (!st) return ERR_PTR(-ENOMEM); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index a7cd0badc20c..1b4cacb6e918 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1816,6 +1816,9 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, ID_AA64MMFR3_EL1_SCTLRX | ID_AA64MMFR3_EL1_S1POE | ID_AA64MMFR3_EL1_S1PIE; + + if (!system_supports_poe()) + val &= ~ID_AA64MMFR3_EL1_S1POE; break; case SYS_ID_MMFR4_EL1: val &= ~ID_MMFR4_EL1_CCIDX; diff --git a/arch/arm64/kvm/vgic/vgic-debug.c b/arch/arm64/kvm/vgic/vgic-debug.c index 2c6776a1779b..8046f9e9719b 100644 --- a/arch/arm64/kvm/vgic/vgic-debug.c +++ b/arch/arm64/kvm/vgic/vgic-debug.c @@ -104,7 +104,7 @@ static void *vgic_debug_start(struct seq_file *s, loff_t *pos) struct kvm *kvm = s->private; struct vgic_state_iter *iter; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return ERR_PTR(-ENOMEM); @@ -375,7 +375,7 @@ static void *vgic_its_debug_start(struct seq_file *s, loff_t *pos) if (!dev) return NULL; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return ERR_PTR(-ENOMEM); diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 86c149537493..e9b8b5fc480c 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -143,23 +143,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) kvm->arch.vgic.in_kernel = true; kvm->arch.vgic.vgic_model = type; kvm->arch.vgic.implementation_rev = KVM_VGIC_IMP_REV_LATEST; - - kvm_for_each_vcpu(i, vcpu, kvm) { - ret = vgic_allocate_private_irqs_locked(vcpu, type); - if (ret) - break; - } - - if (ret) { - kvm_for_each_vcpu(i, vcpu, kvm) { - struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; - kfree(vgic_cpu->private_irqs); - vgic_cpu->private_irqs = NULL; - } - - goto out_unlock; - } - kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; aa64pfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC; @@ -176,6 +159,23 @@ int kvm_vgic_create(struct kvm *kvm, u32 type) kvm_set_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1, aa64pfr0); kvm_set_vm_id_reg(kvm, SYS_ID_PFR1_EL1, pfr1); + kvm_for_each_vcpu(i, vcpu, kvm) { + ret = vgic_allocate_private_irqs_locked(vcpu, type); + if (ret) + break; + } + + if (ret) { + kvm_for_each_vcpu(i, vcpu, kvm) { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + kfree(vgic_cpu->private_irqs); + vgic_cpu->private_irqs = NULL; + } + + kvm->arch.vgic.vgic_model = 0; + goto out_unlock; + } + if (type == KVM_DEV_TYPE_ARM_VGIC_V3) kvm->arch.vgic.nassgicap = system_supports_direct_sgis(); @@ -199,7 +199,7 @@ static int kvm_vgic_dist_init(struct kvm *kvm, unsigned int nr_spis) int i; dist->active_spis = (atomic_t)ATOMIC_INIT(0); - dist->spis = kcalloc(nr_spis, sizeof(struct vgic_irq), GFP_KERNEL_ACCOUNT); + dist->spis = kzalloc_objs(struct vgic_irq, nr_spis, GFP_KERNEL_ACCOUNT); if (!dist->spis) return -ENOMEM; @@ -269,9 +269,9 @@ static int vgic_allocate_private_irqs_locked(struct kvm_vcpu *vcpu, u32 type) if (vgic_cpu->private_irqs) return 0; - vgic_cpu->private_irqs = kcalloc(VGIC_NR_PRIVATE_IRQS, - sizeof(struct vgic_irq), - GFP_KERNEL_ACCOUNT); + vgic_cpu->private_irqs = kzalloc_objs(struct vgic_irq, + VGIC_NR_PRIVATE_IRQS, + GFP_KERNEL_ACCOUNT); if (!vgic_cpu->private_irqs) return -ENOMEM; @@ -654,7 +654,7 @@ static struct gic_kvm_info *gic_kvm_info; void __init vgic_set_kvm_info(const struct gic_kvm_info *info) { BUG_ON(gic_kvm_info != NULL); - gic_kvm_info = kmalloc(sizeof(*info), GFP_KERNEL); + gic_kvm_info = kmalloc_obj(*gic_kvm_info); if (gic_kvm_info) *gic_kvm_info = *info; } diff --git a/arch/arm64/kvm/vgic/vgic-irqfd.c b/arch/arm64/kvm/vgic/vgic-irqfd.c index c314c016659a..b9b86e3a6c86 100644 --- a/arch/arm64/kvm/vgic/vgic-irqfd.c +++ b/arch/arm64/kvm/vgic/vgic-irqfd.c @@ -140,7 +140,7 @@ int kvm_vgic_setup_default_irq_routing(struct kvm *kvm) u32 nr = dist->nr_spis; int i, ret; - entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL_ACCOUNT); + entries = kzalloc_objs(*entries, nr, GFP_KERNEL_ACCOUNT); if (!entries) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic-its.c b/arch/arm64/kvm/vgic/vgic-its.c index 3f1c4b10fed9..2ea9f1c7ebcd 100644 --- a/arch/arm64/kvm/vgic/vgic-its.c +++ b/arch/arm64/kvm/vgic/vgic-its.c @@ -85,7 +85,7 @@ static struct vgic_irq *vgic_add_lpi(struct kvm *kvm, u32 intid, if (irq) return irq; - irq = kzalloc(sizeof(struct vgic_irq), GFP_KERNEL_ACCOUNT); + irq = kzalloc_obj(struct vgic_irq, GFP_KERNEL_ACCOUNT); if (!irq) return ERR_PTR(-ENOMEM); @@ -960,7 +960,7 @@ static int vgic_its_alloc_collection(struct vgic_its *its, { struct its_collection *collection; - collection = kzalloc(sizeof(*collection), GFP_KERNEL_ACCOUNT); + collection = kzalloc_obj(*collection, GFP_KERNEL_ACCOUNT); if (!collection) return -ENOMEM; @@ -1004,7 +1004,7 @@ static struct its_ite *vgic_its_alloc_ite(struct its_device *device, { struct its_ite *ite; - ite = kzalloc(sizeof(*ite), GFP_KERNEL_ACCOUNT); + ite = kzalloc_obj(*ite, GFP_KERNEL_ACCOUNT); if (!ite) return ERR_PTR(-ENOMEM); @@ -1131,7 +1131,7 @@ static struct its_device *vgic_its_alloc_device(struct vgic_its *its, { struct its_device *device; - device = kzalloc(sizeof(*device), GFP_KERNEL_ACCOUNT); + device = kzalloc_obj(*device, GFP_KERNEL_ACCOUNT); if (!device) return ERR_PTR(-ENOMEM); @@ -1846,7 +1846,7 @@ static int vgic_its_create(struct kvm_device *dev, u32 type) if (type != KVM_DEV_TYPE_ARM_VGIC_ITS) return -ENODEV; - its = kzalloc(sizeof(struct vgic_its), GFP_KERNEL_ACCOUNT); + its = kzalloc_obj(struct vgic_its, GFP_KERNEL_ACCOUNT); if (!its) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic-mmio-v3.c b/arch/arm64/kvm/vgic/vgic-mmio-v3.c index 70d50c77e5dc..89edb84d1ac6 100644 --- a/arch/arm64/kvm/vgic/vgic-mmio-v3.c +++ b/arch/arm64/kvm/vgic/vgic-mmio-v3.c @@ -929,7 +929,7 @@ static int vgic_v3_alloc_redist_region(struct kvm *kvm, uint32_t index, if (vgic_v3_rdist_overlap(kvm, base, size)) return -EINVAL; - rdreg = kzalloc(sizeof(*rdreg), GFP_KERNEL_ACCOUNT); + rdreg = kzalloc_obj(*rdreg, GFP_KERNEL_ACCOUNT); if (!rdreg) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic-v2.c b/arch/arm64/kvm/vgic/vgic-v2.c index 585491fbda80..cafa3cb32bda 100644 --- a/arch/arm64/kvm/vgic/vgic-v2.c +++ b/arch/arm64/kvm/vgic/vgic-v2.c @@ -115,7 +115,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_v2_cpu_if *cpuif = &vgic_cpu->vgic_v2; u32 eoicount = FIELD_GET(GICH_HCR_EOICOUNT, cpuif->vgic_hcr); - struct vgic_irq *irq; + struct vgic_irq *irq = *host_data_ptr(last_lr_irq); DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); @@ -123,7 +123,7 @@ void vgic_v2_fold_lr_state(struct kvm_vcpu *vcpu) vgic_v2_fold_lr(vcpu, cpuif->vgic_lr[lr]); /* See the GICv3 equivalent for the EOIcount handling rationale */ - list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + list_for_each_entry_continue(irq, &vgic_cpu->ap_list_head, ap_list) { u32 lr; if (!eoicount) { diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 386ddf69a9c5..6a355eca1934 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -148,7 +148,7 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; struct vgic_v3_cpu_if *cpuif = &vgic_cpu->vgic_v3; u32 eoicount = FIELD_GET(ICH_HCR_EL2_EOIcount, cpuif->vgic_hcr); - struct vgic_irq *irq; + struct vgic_irq *irq = *host_data_ptr(last_lr_irq); DEBUG_SPINLOCK_BUG_ON(!irqs_disabled()); @@ -158,12 +158,12 @@ void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu) /* * EOIMode=0: use EOIcount to emulate deactivation. We are * guaranteed to deactivate in reverse order of the activation, so - * just pick one active interrupt after the other in the ap_list, - * and replay the deactivation as if the CPU was doing it. We also - * rely on priority drop to have taken place, and the list to be - * sorted by priority. + * just pick one active interrupt after the other in the tail part + * of the ap_list, past the LRs, and replay the deactivation as if + * the CPU was doing it. We also rely on priority drop to have taken + * place, and the list to be sorted by priority. */ - list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { + list_for_each_entry_continue(irq, &vgic_cpu->ap_list_head, ap_list) { u64 lr; /* diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index 09c3e9eb23f8..ed236f083f0d 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -256,8 +256,8 @@ int vgic_v4_init(struct kvm *kvm) nr_vcpus = atomic_read(&kvm->online_vcpus); - dist->its_vm.vpes = kcalloc(nr_vcpus, sizeof(*dist->its_vm.vpes), - GFP_KERNEL_ACCOUNT); + dist->its_vm.vpes = kzalloc_objs(*dist->its_vm.vpes, nr_vcpus, + GFP_KERNEL_ACCOUNT); if (!dist->its_vm.vpes) return -ENOMEM; diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c index 430aa98888fd..e22b79cfff96 100644 --- a/arch/arm64/kvm/vgic/vgic.c +++ b/arch/arm64/kvm/vgic/vgic.c @@ -814,6 +814,9 @@ static void vgic_prune_ap_list(struct kvm_vcpu *vcpu) static inline void vgic_fold_lr_state(struct kvm_vcpu *vcpu) { + if (!*host_data_ptr(last_lr_irq)) + return; + if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_fold_lr_state(vcpu); else @@ -960,10 +963,13 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu) if (irqs_outside_lrs(&als)) vgic_sort_ap_list(vcpu); + *host_data_ptr(last_lr_irq) = NULL; + list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list) { scoped_guard(raw_spinlock, &irq->irq_lock) { if (likely(vgic_target_oracle(irq) == vcpu)) { vgic_populate_lr(vcpu, irq, count++); + *host_data_ptr(last_lr_irq) = irq; } } diff --git a/arch/arm64/lib/delay.c b/arch/arm64/lib/delay.c index cb2062e7e234..e278e060e78a 100644 --- a/arch/arm64/lib/delay.c +++ b/arch/arm64/lib/delay.c @@ -23,9 +23,24 @@ static inline unsigned long xloops_to_cycles(unsigned long xloops) return (xloops * loops_per_jiffy * HZ) >> 32; } +/* + * Force the use of CNTVCT_EL0 in order to have the same base as WFxT. + * This avoids some annoying issues when CNTVOFF_EL2 is not reset 0 on a + * KVM host running at EL1 until we do a vcpu_put() on the vcpu. When + * running at EL2, the effective offset is always 0. + * + * Note that userspace cannot change the offset behind our back either, + * as the vcpu mutex is held as long as KVM_RUN is in progress. + */ +static cycles_t notrace __delay_cycles(void) +{ + guard(preempt_notrace)(); + return __arch_counter_get_cntvct_stable(); +} + void __delay(unsigned long cycles) { - cycles_t start = get_cycles(); + cycles_t start = __delay_cycles(); if (alternative_has_cap_unlikely(ARM64_HAS_WFXT)) { u64 end = start + cycles; @@ -35,17 +50,17 @@ void __delay(unsigned long cycles) * early, use a WFET loop to complete the delay. */ wfit(end); - while ((get_cycles() - start) < cycles) + while ((__delay_cycles() - start) < cycles) wfet(end); } else if (arch_timer_evtstrm_available()) { const cycles_t timer_evt_period = USECS_TO_CYCLES(ARCH_TIMER_EVT_STREAM_PERIOD_US); - while ((get_cycles() - start + timer_evt_period) < cycles) + while ((__delay_cycles() - start + timer_evt_period) < cycles) wfe(); } - while ((get_cycles() - start) < cycles) + while ((__delay_cycles() - start) < cycles) cpu_relax(); } EXPORT_SYMBOL(__delay); diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c index 589bcf878938..1519d090d5ea 100644 --- a/arch/arm64/mm/contpte.c +++ b/arch/arm64/mm/contpte.c @@ -26,6 +26,26 @@ static inline pte_t *contpte_align_down(pte_t *ptep) return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES); } +static inline pte_t *contpte_align_addr_ptep(unsigned long *start, + unsigned long *end, pte_t *ptep, + unsigned int nr) +{ + /* + * Note: caller must ensure these nr PTEs are consecutive (present) + * PTEs that map consecutive pages of the same large folio within a + * single VMA and a single page table. + */ + if (pte_cont(__ptep_get(ptep + nr - 1))) + *end = ALIGN(*end, CONT_PTE_SIZE); + + if (pte_cont(__ptep_get(ptep))) { + *start = ALIGN_DOWN(*start, CONT_PTE_SIZE); + ptep = contpte_align_down(ptep); + } + + return ptep; +} + static void contpte_try_unfold_partial(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned int nr) { @@ -488,8 +508,9 @@ pte_t contpte_get_and_clear_full_ptes(struct mm_struct *mm, } EXPORT_SYMBOL_GPL(contpte_get_and_clear_full_ptes); -int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) +int contpte_test_and_clear_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + unsigned int nr) { /* * ptep_clear_flush_young() technically requires us to clear the access @@ -498,41 +519,45 @@ int contpte_ptep_test_and_clear_young(struct vm_area_struct *vma, * contig range when the range is covered by a single folio, we can get * away with clearing young for the whole contig range here, so we avoid * having to unfold. + * + * The 'nr' means consecutive (present) PTEs that map consecutive pages + * of the same large folio in a single VMA and a single page table. */ + unsigned long end = addr + nr * PAGE_SIZE; int young = 0; - int i; - ptep = contpte_align_down(ptep); - addr = ALIGN_DOWN(addr, CONT_PTE_SIZE); - - for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) + ptep = contpte_align_addr_ptep(&addr, &end, ptep, nr); + for (; addr != end; ptep++, addr += PAGE_SIZE) young |= __ptep_test_and_clear_young(vma, addr, ptep); return young; } -EXPORT_SYMBOL_GPL(contpte_ptep_test_and_clear_young); +EXPORT_SYMBOL_GPL(contpte_test_and_clear_young_ptes); -int contpte_ptep_clear_flush_young(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) +int contpte_clear_flush_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + unsigned int nr) { int young; - young = contpte_ptep_test_and_clear_young(vma, addr, ptep); + young = contpte_test_and_clear_young_ptes(vma, addr, ptep, nr); if (young) { + unsigned long end = addr + nr * PAGE_SIZE; + + contpte_align_addr_ptep(&addr, &end, ptep, nr); /* * See comment in __ptep_clear_flush_young(); same rationale for * eliding the trailing DSB applies here. */ - addr = ALIGN_DOWN(addr, CONT_PTE_SIZE); - __flush_tlb_range_nosync(vma->vm_mm, addr, addr + CONT_PTE_SIZE, + __flush_tlb_range_nosync(vma->vm_mm, addr, end, PAGE_SIZE, true, 3); } return young; } -EXPORT_SYMBOL_GPL(contpte_ptep_clear_flush_young); +EXPORT_SYMBOL_GPL(contpte_clear_flush_young_ptes); void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned int nr) @@ -569,18 +594,32 @@ void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma, unsigned long start = addr; unsigned long end = start + nr * PAGE_SIZE; - if (pte_cont(__ptep_get(ptep + nr - 1))) - end = ALIGN(end, CONT_PTE_SIZE); - - if (pte_cont(__ptep_get(ptep))) { - start = ALIGN_DOWN(start, CONT_PTE_SIZE); - ptep = contpte_align_down(ptep); - } - + ptep = contpte_align_addr_ptep(&start, &end, ptep, nr); __clear_young_dirty_ptes(vma, start, ptep, (end - start) / PAGE_SIZE, flags); } EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes); +static bool contpte_all_subptes_match_access_flags(pte_t *ptep, pte_t entry) +{ + pte_t *cont_ptep = contpte_align_down(ptep); + /* + * PFNs differ per sub-PTE. Match only bits consumed by + * __ptep_set_access_flags(): AF, DIRTY and write permission. + */ + const pteval_t cmp_mask = PTE_RDONLY | PTE_AF | PTE_WRITE | PTE_DIRTY; + pteval_t entry_cmp = pte_val(entry) & cmp_mask; + int i; + + for (i = 0; i < CONT_PTES; i++) { + pteval_t pte_cmp = pte_val(__ptep_get(cont_ptep + i)) & cmp_mask; + + if (pte_cmp != entry_cmp) + return false; + } + + return true; +} + int contpte_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t entry, int dirty) @@ -590,13 +629,37 @@ int contpte_ptep_set_access_flags(struct vm_area_struct *vma, int i; /* - * Gather the access/dirty bits for the contiguous range. If nothing has - * changed, its a noop. + * Check whether all sub-PTEs in the CONT block already match the + * requested access flags/write permission, using raw per-PTE values + * rather than the gathered ptep_get() view. + * + * __ptep_set_access_flags() can update AF, dirty and write + * permission, but only to make the mapping more permissive. + * + * ptep_get() gathers AF/dirty state across the whole CONT block, + * which is correct for a CPU with FEAT_HAFDBS. But page-table + * walkers that evaluate each descriptor individually (e.g. a CPU + * without DBM support, or an SMMU without HTTU, or with HA/HD + * disabled in CD.TCR) can keep faulting on the target sub-PTE if + * only a sibling has been updated. Gathering can therefore cause + * false no-ops when only a sibling has been updated: + * - write faults: target still has PTE_RDONLY (needs PTE_RDONLY cleared) + * - read faults: target still lacks PTE_AF + * + * Per Arm ARM (DDI 0487) D8.7.1, any sub-PTE in a CONT range may + * become the effective cached translation, so all entries must have + * consistent attributes. Check the full CONT block before returning + * no-op, and when any sub-PTE mismatches, proceed to update the whole + * range. */ - orig_pte = pte_mknoncont(ptep_get(ptep)); - if (pte_val(orig_pte) == pte_val(entry)) + if (contpte_all_subptes_match_access_flags(ptep, entry)) return 0; + /* + * Use raw target pte (not gathered) for write-bit unfold decision. + */ + orig_pte = pte_mknoncont(__ptep_get(ptep)); + /* * We can fix up access/dirty bits without having to unfold the contig * range. But if the write bit is changing, we must unfold. diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c index b12cbed9b5ad..6eef48ef6278 100644 --- a/arch/arm64/mm/ioremap.c +++ b/arch/arm64/mm/ioremap.c @@ -14,8 +14,8 @@ int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook) return 0; } -void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, - pgprot_t pgprot) +void __iomem *__ioremap_prot(phys_addr_t phys_addr, size_t size, + pgprot_t pgprot) { unsigned long last_addr = phys_addr + size - 1; @@ -39,7 +39,7 @@ void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, return generic_ioremap_prot(phys_addr, size, pgprot); } -EXPORT_SYMBOL(ioremap_prot); +EXPORT_SYMBOL(__ioremap_prot); /* * Must be called after early_fixmap_init diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c index 08ee177432c2..92b2f5097a96 100644 --- a/arch/arm64/mm/mmap.c +++ b/arch/arm64/mm/mmap.c @@ -34,6 +34,8 @@ static pgprot_t protection_map[16] __ro_after_init = { [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED_EXEC }; +static ptdesc_t gcs_page_prot __ro_after_init = _PAGE_GCS_RO; + /* * You really shouldn't be using read() or write() on /dev/mem. This might go * away in the future. @@ -73,9 +75,11 @@ static int __init adjust_protection_map(void) protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY; } - if (lpa2_is_enabled()) + if (lpa2_is_enabled()) { for (int i = 0; i < ARRAY_SIZE(protection_map); i++) pgprot_val(protection_map[i]) &= ~PTE_SHARED; + gcs_page_prot &= ~PTE_SHARED; + } return 0; } @@ -87,7 +91,11 @@ pgprot_t vm_get_page_prot(vm_flags_t vm_flags) /* Short circuit GCS to avoid bloating the table. */ if (system_supports_gcs() && (vm_flags & VM_SHADOW_STACK)) { - prot = _PAGE_GCS_RO; + /* Honour mprotect(PROT_NONE) on shadow stack mappings */ + if (vm_flags & VM_ACCESS_FLAGS) + prot = gcs_page_prot; + else + prot = pgprot_val(protection_map[VM_NONE]); } else { prot = pgprot_val(protection_map[vm_flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)]); diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index 7a530ea4f5ae..adf84962d579 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -2040,7 +2040,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; @@ -2078,7 +2078,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; - ctx.offset = kvcalloc(prog->len + 1, sizeof(int), GFP_KERNEL); + ctx.offset = kvzalloc_objs(int, prog->len + 1); if (ctx.offset == NULL) { prog = orig_prog; goto out_off; @@ -2119,7 +2119,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) extable_offset = round_up(prog_size + PLT_TARGET_SIZE, extable_align); image_size = extable_offset + extable_size; ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr, - sizeof(u32), &header, &image_ptr, + sizeof(u64), &header, &image_ptr, jit_fill_hole); if (!ro_header) { prog = orig_prog; diff --git a/arch/csky/kernel/vdso.c b/arch/csky/kernel/vdso.c index c54d019d66bc..6886c0b3f60b 100644 --- a/arch/csky/kernel/vdso.c +++ b/arch/csky/kernel/vdso.c @@ -20,7 +20,7 @@ static int __init vdso_init(void) vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT; vdso_pagelist = - kcalloc(vdso_pages, sizeof(struct page *), GFP_KERNEL); + kzalloc_objs(struct page *, vdso_pages); if (unlikely(vdso_pagelist == NULL)) { pr_err("vdso: pagelist allocation failed\n"); return -ENOMEM; diff --git a/arch/csky/kernel/vmlinux.lds.S b/arch/csky/kernel/vmlinux.lds.S index d718961786d2..81943981b3af 100644 --- a/arch/csky/kernel/vmlinux.lds.S +++ b/arch/csky/kernel/vmlinux.lds.S @@ -109,6 +109,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S index 1150b77fa281..aae22283b5e0 100644 --- a/arch/hexagon/kernel/vmlinux.lds.S +++ b/arch/hexagon/kernel/vmlinux.lds.S @@ -62,6 +62,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS .hexagon.attributes 0 : { *(.hexagon.attributes) } diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 92f716cccac4..d211c6572b0a 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -114,6 +114,7 @@ config LOONGARCH select GENERIC_TIME_VSYSCALL select GPIOLIB select HAS_IOPORT + select HAVE_ALIGNED_STRUCT_PAGE select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_BITREVERSE select HAVE_ARCH_JUMP_LABEL @@ -130,6 +131,8 @@ config LOONGARCH select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_USERFAULTFD_MINOR if USERFAULTFD select HAVE_ASM_MODVERSIONS + select HAVE_CMPXCHG_DOUBLE + select HAVE_CMPXCHG_LOCAL select HAVE_CONTEXT_TRACKING_USER select HAVE_C_RECORDMCOUNT select HAVE_DEBUG_KMEMLEAK @@ -183,6 +186,7 @@ config LOONGARCH select HAVE_SYSCALL_TRACEPOINTS select HAVE_TIF_NOHZ select HAVE_VIRT_CPU_ACCOUNTING_GEN + select HOTPLUG_SMT if HOTPLUG_CPU select IRQ_FORCED_THREADING select IRQ_LOONGARCH_CPU select LOCK_MM_AND_FIND_VMA diff --git a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts index 018ed904352a..7ace54c84244 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500-ref.dts +++ b/arch/loongarch/boot/dts/loongson-2k0500-ref.dts @@ -41,6 +41,25 @@ linux,cma { }; }; +&apbdma0 { + status = "okay"; +}; + +&nand { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + nand@0 { + reg = <0>; + label = "ls2k0500-nand"; + nand-use-soft-ecc-engine; + nand-ecc-algo = "bch"; + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + }; +}; + &apbdma3 { status = "okay"; }; diff --git a/arch/loongarch/boot/dts/loongson-2k0500.dtsi b/arch/loongarch/boot/dts/loongson-2k0500.dtsi index e759fae77dcf..1b502064df11 100644 --- a/arch/loongarch/boot/dts/loongson-2k0500.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k0500.dtsi @@ -84,7 +84,7 @@ clk: clock-controller@1fe10400 { clock-names = "ref_100m"; }; - dma-controller@1fe10c00 { + apbdma0: dma-controller@1fe10c00 { compatible = "loongson,ls2k0500-apbdma", "loongson,ls2k1000-apbdma"; reg = <0 0x1fe10c00 0 0x8>; interrupt-parent = <&eiointc>; @@ -172,6 +172,16 @@ eiointc: interrupt-controller@1fe11600 { interrupts = <3>; }; + nand: nand-controller@1ff58000 { + compatible = "loongson,ls2k0500-nand-controller"; + reg = <0 0x1ff58000 0 0x24>, + <0 0x1ff58040 0 0x4>; + reg-names = "nand", "nand-dma"; + dmas = <&apbdma0 0>; + dma-names = "rxtx"; + status = "disabled"; + }; + pwm@1ff5c000 { compatible = "loongson,ls2k0500-pwm", "loongson,ls7a-pwm"; reg = <0x0 0x1ff5c000 0x0 0x10>; diff --git a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts index d9a452ada5d7..51b8e53cb608 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000-ref.dts +++ b/arch/loongarch/boot/dts/loongson-2k1000-ref.dts @@ -48,6 +48,28 @@ fan0: pwm-fan { }; }; +&apbdma0 { + status = "okay"; +}; + +&nand { + status = "okay"; + + pinctrl-0 = <&nand_pins_default>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + nand@0 { + reg = <0>; + label = "ls2k1000-nand"; + nand-use-soft-ecc-engine; + nand-ecc-algo = "bch"; + nand-ecc-strength = <8>; + nand-ecc-step-size = <512>; + }; +}; + &apbdma1 { status = "okay"; }; diff --git a/arch/loongarch/boot/dts/loongson-2k1000.dtsi b/arch/loongarch/boot/dts/loongson-2k1000.dtsi index be4f7d119660..ab6a55937e9e 100644 --- a/arch/loongarch/boot/dts/loongson-2k1000.dtsi +++ b/arch/loongarch/boot/dts/loongson-2k1000.dtsi @@ -248,7 +248,7 @@ tsensor: thermal-sensor@1fe01500 { #thermal-sensor-cells = <1>; }; - dma-controller@1fe00c00 { + apbdma0: dma-controller@1fe00c00 { compatible = "loongson,ls2k1000-apbdma"; reg = <0x0 0x1fe00c00 0x0 0x8>; interrupt-parent = <&liointc1>; @@ -364,6 +364,17 @@ pwm@1fe22030 { status = "disabled"; }; + nand: nand-controller@1fe26000 { + compatible = "loongson,ls2k1000-nand-controller"; + reg = <0 0x1fe26000 0 0x24>, + <0 0x1fe26040 0 0x4>, + <0 0x1fe00438 0 0x8>; + reg-names = "nand", "nand-dma", "dma-config"; + dmas = <&apbdma0 0>; + dma-names = "rxtx"; + status = "disabled"; + }; + pmc: power-management@1fe27000 { compatible = "loongson,ls2k1000-pmc", "loongson,ls2k0500-pmc", "syscon"; reg = <0x0 0x1fe27000 0x0 0x58>; diff --git a/arch/loongarch/include/asm/cmpxchg.h b/arch/loongarch/include/asm/cmpxchg.h index 0494c2ab553e..58cabab6d90d 100644 --- a/arch/loongarch/include/asm/cmpxchg.h +++ b/arch/loongarch/include/asm/cmpxchg.h @@ -8,6 +8,7 @@ #include #include #include +#include #define __xchg_amo_asm(amswap_db, m, val) \ ({ \ @@ -236,6 +237,59 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, unsigned int BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ arch_cmpxchg((ptr), (o), (n)); \ }) + +union __u128_halves { + u128 full; + struct { + u64 low; + u64 high; + }; +}; + +#define system_has_cmpxchg128() cpu_opt(LOONGARCH_CPU_SCQ) + +#define __arch_cmpxchg128(ptr, old, new, llsc_mb) \ +({ \ + union __u128_halves __old, __new, __ret; \ + volatile u64 *__ptr = (volatile u64 *)(ptr); \ + \ + __old.full = (old); \ + __new.full = (new); \ + \ + __asm__ __volatile__( \ + "1: ll.d %0, %3 # 128-bit cmpxchg low \n" \ + llsc_mb \ + " ld.d %1, %4 # 128-bit cmpxchg high \n" \ + " move $t0, %0 \n" \ + " move $t1, %1 \n" \ + " bne %0, %z5, 2f \n" \ + " bne %1, %z6, 2f \n" \ + " move $t0, %z7 \n" \ + " move $t1, %z8 \n" \ + "2: sc.q $t0, $t1, %2 \n" \ + " beqz $t0, 1b \n" \ + llsc_mb \ + : "=&r" (__ret.low), "=&r" (__ret.high) \ + : "r" (__ptr), \ + "ZC" (__ptr[0]), "m" (__ptr[1]), \ + "Jr" (__old.low), "Jr" (__old.high), \ + "Jr" (__new.low), "Jr" (__new.high) \ + : "t0", "t1", "memory"); \ + \ + __ret.full; \ +}) + +#define arch_cmpxchg128(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 16); \ + __arch_cmpxchg128(ptr, o, n, __WEAK_LLSC_MB); \ +}) + +#define arch_cmpxchg128_local(ptr, o, n) \ +({ \ + BUILD_BUG_ON(sizeof(*(ptr)) != 16); \ + __arch_cmpxchg128(ptr, o, n, ""); \ +}) #else #include #define arch_cmpxchg64_local(ptr, o, n) __generic_cmpxchg64_local((ptr), (o), (n)) diff --git a/arch/loongarch/include/asm/cpu-features.h b/arch/loongarch/include/asm/cpu-features.h index 3745d991a99a..8eefe7a2098b 100644 --- a/arch/loongarch/include/asm/cpu-features.h +++ b/arch/loongarch/include/asm/cpu-features.h @@ -35,6 +35,7 @@ */ #define cpu_has_cpucfg cpu_opt(LOONGARCH_CPU_CPUCFG) #define cpu_has_lam cpu_opt(LOONGARCH_CPU_LAM) +#define cpu_has_scq cpu_opt(LOONGARCH_CPU_SCQ) #define cpu_has_ual cpu_opt(LOONGARCH_CPU_UAL) #define cpu_has_fpu cpu_opt(LOONGARCH_CPU_FPU) #define cpu_has_lsx cpu_opt(LOONGARCH_CPU_LSX) diff --git a/arch/loongarch/include/asm/cpu.h b/arch/loongarch/include/asm/cpu.h index f3efb00b6141..1e60ab264cd0 100644 --- a/arch/loongarch/include/asm/cpu.h +++ b/arch/loongarch/include/asm/cpu.h @@ -95,39 +95,41 @@ static inline char *id_to_core_name(unsigned int id) */ #define CPU_FEATURE_CPUCFG 0 /* CPU has CPUCFG */ #define CPU_FEATURE_LAM 1 /* CPU has Atomic instructions */ -#define CPU_FEATURE_UAL 2 /* CPU supports unaligned access */ -#define CPU_FEATURE_FPU 3 /* CPU has FPU */ -#define CPU_FEATURE_LSX 4 /* CPU has LSX (128-bit SIMD) */ -#define CPU_FEATURE_LASX 5 /* CPU has LASX (256-bit SIMD) */ -#define CPU_FEATURE_CRC32 6 /* CPU has CRC32 instructions */ -#define CPU_FEATURE_COMPLEX 7 /* CPU has Complex instructions */ -#define CPU_FEATURE_CRYPTO 8 /* CPU has Crypto instructions */ -#define CPU_FEATURE_LVZ 9 /* CPU has Virtualization extension */ -#define CPU_FEATURE_LBT_X86 10 /* CPU has X86 Binary Translation */ -#define CPU_FEATURE_LBT_ARM 11 /* CPU has ARM Binary Translation */ -#define CPU_FEATURE_LBT_MIPS 12 /* CPU has MIPS Binary Translation */ -#define CPU_FEATURE_TLB 13 /* CPU has TLB */ -#define CPU_FEATURE_CSR 14 /* CPU has CSR */ -#define CPU_FEATURE_IOCSR 15 /* CPU has IOCSR */ -#define CPU_FEATURE_WATCH 16 /* CPU has watchpoint registers */ -#define CPU_FEATURE_VINT 17 /* CPU has vectored interrupts */ -#define CPU_FEATURE_CSRIPI 18 /* CPU has CSR-IPI */ -#define CPU_FEATURE_EXTIOI 19 /* CPU has EXT-IOI */ -#define CPU_FEATURE_PREFETCH 20 /* CPU has prefetch instructions */ -#define CPU_FEATURE_PMP 21 /* CPU has perfermance counter */ -#define CPU_FEATURE_SCALEFREQ 22 /* CPU supports cpufreq scaling */ -#define CPU_FEATURE_FLATMODE 23 /* CPU has flat mode */ -#define CPU_FEATURE_EIODECODE 24 /* CPU has EXTIOI interrupt pin decode mode */ -#define CPU_FEATURE_GUESTID 25 /* CPU has GuestID feature */ -#define CPU_FEATURE_HYPERVISOR 26 /* CPU has hypervisor (running in VM) */ -#define CPU_FEATURE_PTW 27 /* CPU has hardware page table walker */ -#define CPU_FEATURE_LSPW 28 /* CPU has LSPW (lddir/ldpte instructions) */ -#define CPU_FEATURE_MSGINT 29 /* CPU has MSG interrupt */ -#define CPU_FEATURE_AVECINT 30 /* CPU has AVEC interrupt */ -#define CPU_FEATURE_REDIRECTINT 31 /* CPU has interrupt remapping */ +#define CPU_FEATURE_SCQ 2 /* CPU has SC.Q instruction */ +#define CPU_FEATURE_UAL 3 /* CPU supports unaligned access */ +#define CPU_FEATURE_FPU 4 /* CPU has FPU */ +#define CPU_FEATURE_LSX 5 /* CPU has LSX (128-bit SIMD) */ +#define CPU_FEATURE_LASX 6 /* CPU has LASX (256-bit SIMD) */ +#define CPU_FEATURE_CRC32 7 /* CPU has CRC32 instructions */ +#define CPU_FEATURE_COMPLEX 8 /* CPU has Complex instructions */ +#define CPU_FEATURE_CRYPTO 9 /* CPU has Crypto instructions */ +#define CPU_FEATURE_LVZ 10 /* CPU has Virtualization extension */ +#define CPU_FEATURE_LBT_X86 11 /* CPU has X86 Binary Translation */ +#define CPU_FEATURE_LBT_ARM 12 /* CPU has ARM Binary Translation */ +#define CPU_FEATURE_LBT_MIPS 13 /* CPU has MIPS Binary Translation */ +#define CPU_FEATURE_TLB 14 /* CPU has TLB */ +#define CPU_FEATURE_CSR 15 /* CPU has CSR */ +#define CPU_FEATURE_IOCSR 16 /* CPU has IOCSR */ +#define CPU_FEATURE_WATCH 17 /* CPU has watchpoint registers */ +#define CPU_FEATURE_VINT 18 /* CPU has vectored interrupts */ +#define CPU_FEATURE_CSRIPI 19 /* CPU has CSR-IPI */ +#define CPU_FEATURE_EXTIOI 20 /* CPU has EXT-IOI */ +#define CPU_FEATURE_PREFETCH 21 /* CPU has prefetch instructions */ +#define CPU_FEATURE_PMP 22 /* CPU has perfermance counter */ +#define CPU_FEATURE_SCALEFREQ 23 /* CPU supports cpufreq scaling */ +#define CPU_FEATURE_FLATMODE 24 /* CPU has flat mode */ +#define CPU_FEATURE_EIODECODE 25 /* CPU has EXTIOI interrupt pin decode mode */ +#define CPU_FEATURE_GUESTID 26 /* CPU has GuestID feature */ +#define CPU_FEATURE_HYPERVISOR 27 /* CPU has hypervisor (running in VM) */ +#define CPU_FEATURE_PTW 28 /* CPU has hardware page table walker */ +#define CPU_FEATURE_LSPW 29 /* CPU has LSPW (lddir/ldpte instructions) */ +#define CPU_FEATURE_MSGINT 30 /* CPU has MSG interrupt */ +#define CPU_FEATURE_AVECINT 31 /* CPU has AVEC interrupt */ +#define CPU_FEATURE_REDIRECTINT 32 /* CPU has interrupt remapping */ #define LOONGARCH_CPU_CPUCFG BIT_ULL(CPU_FEATURE_CPUCFG) #define LOONGARCH_CPU_LAM BIT_ULL(CPU_FEATURE_LAM) +#define LOONGARCH_CPU_SCQ BIT_ULL(CPU_FEATURE_SCQ) #define LOONGARCH_CPU_UAL BIT_ULL(CPU_FEATURE_UAL) #define LOONGARCH_CPU_FPU BIT_ULL(CPU_FEATURE_FPU) #define LOONGARCH_CPU_LSX BIT_ULL(CPU_FEATURE_LSX) diff --git a/arch/loongarch/include/asm/setup.h b/arch/loongarch/include/asm/setup.h index 3c2fb16b11b6..f81375e5e89c 100644 --- a/arch/loongarch/include/asm/setup.h +++ b/arch/loongarch/include/asm/setup.h @@ -7,6 +7,7 @@ #define _LOONGARCH_SETUP_H #include +#include #include #include @@ -14,6 +15,8 @@ extern unsigned long eentry; extern unsigned long tlbrentry; +extern unsigned long pcpu_handlers[NR_CPUS]; +extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; extern char init_command_line[COMMAND_LINE_SIZE]; extern void tlb_init(int cpu); extern void cpu_cache_init(void); diff --git a/arch/loongarch/include/asm/topology.h b/arch/loongarch/include/asm/topology.h index f06e7ff25bb7..6b79d6183085 100644 --- a/arch/loongarch/include/asm/topology.h +++ b/arch/loongarch/include/asm/topology.h @@ -12,7 +12,7 @@ extern cpumask_t cpus_on_node[]; -#define cpumask_of_node(node) (&cpus_on_node[node]) +#define cpumask_of_node(node) ((node) == NUMA_NO_NODE ? cpu_all_mask : &cpus_on_node[node]) struct pci_bus; extern int pcibus_to_node(struct pci_bus *); diff --git a/arch/loongarch/include/asm/unistd.h b/arch/loongarch/include/asm/unistd.h index e2c0f3d86c7b..e7649c158248 100644 --- a/arch/loongarch/include/asm/unistd.h +++ b/arch/loongarch/include/asm/unistd.h @@ -10,5 +10,6 @@ #define __ARCH_WANT_NEW_STAT #define __ARCH_WANT_SYS_CLONE +#define __ARCH_WANT_MEMFD_SECRET #define NR_syscalls (__NR_syscalls) diff --git a/arch/loongarch/include/uapi/asm/hwcap.h b/arch/loongarch/include/uapi/asm/hwcap.h index 2b34e56cfa9e..49519b4362c6 100644 --- a/arch/loongarch/include/uapi/asm/hwcap.h +++ b/arch/loongarch/include/uapi/asm/hwcap.h @@ -18,5 +18,6 @@ #define HWCAP_LOONGARCH_LBT_MIPS (1 << 12) #define HWCAP_LOONGARCH_PTW (1 << 13) #define HWCAP_LOONGARCH_LSPW (1 << 14) +#define HWCAP_LOONGARCH_SCQ (1 << 15) #endif /* _UAPI_ASM_HWCAP_H */ diff --git a/arch/loongarch/kernel/Makefile.syscalls b/arch/loongarch/kernel/Makefile.syscalls index cd46c2b69c7f..06f160502537 100644 --- a/arch/loongarch/kernel/Makefile.syscalls +++ b/arch/loongarch/kernel/Makefile.syscalls @@ -1,5 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -# No special ABIs on loongarch so far -syscall_abis_32 += -syscall_abis_64 += +syscall_abis_32 += memfd_secret +syscall_abis_64 += memfd_secret diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c index 08a227034042..657bbae6c1c7 100644 --- a/arch/loongarch/kernel/cpu-probe.c +++ b/arch/loongarch/kernel/cpu-probe.c @@ -177,6 +177,10 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c) c->options |= LOONGARCH_CPU_LAM; elf_hwcap |= HWCAP_LOONGARCH_LAM; } + if (config & CPUCFG2_SCQ) { + c->options |= LOONGARCH_CPU_SCQ; + elf_hwcap |= HWCAP_LOONGARCH_SCQ; + } if (config & CPUCFG2_FP) { c->options |= LOONGARCH_CPU_FPU; elf_hwcap |= HWCAP_LOONGARCH_FPU; diff --git a/arch/loongarch/kernel/kgdb.c b/arch/loongarch/kernel/kgdb.c index 7be5b4c0c900..17664a6043b1 100644 --- a/arch/loongarch/kernel/kgdb.c +++ b/arch/loongarch/kernel/kgdb.c @@ -697,7 +697,7 @@ void kgdb_arch_late(void) continue; breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL, NULL); - if (IS_ERR((void * __force)breakinfo[i].pev)) { + if (IS_ERR_PCPU(breakinfo[i].pev)) { pr_err("kgdb: Could not allocate hw breakpoints.\n"); breakinfo[i].pev = NULL; return; diff --git a/arch/loongarch/kernel/machine_kexec_file.c b/arch/loongarch/kernel/machine_kexec_file.c index fb57026f5f25..5584b798ba46 100644 --- a/arch/loongarch/kernel/machine_kexec_file.c +++ b/arch/loongarch/kernel/machine_kexec_file.c @@ -68,7 +68,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) for_each_mem_range(i, &start, &end) nr_ranges++; - cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL); + cmem = kmalloc_flex(*cmem, ranges, nr_ranges); if (!cmem) return -ENOMEM; diff --git a/arch/loongarch/kernel/proc.c b/arch/loongarch/kernel/proc.c index a8800d20e11b..a8127e83da65 100644 --- a/arch/loongarch/kernel/proc.c +++ b/arch/loongarch/kernel/proc.c @@ -50,32 +50,49 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, "Address Sizes\t\t: %d bits physical, %d bits virtual\n", cpu_pabits + 1, cpu_vabits + 1); - seq_printf(m, "ISA\t\t\t:"); + seq_puts(m, "ISA\t\t\t:"); if (isa & LOONGARCH_CPU_ISA_LA32R) - seq_printf(m, " loongarch32r"); + seq_puts(m, " loongarch32r"); if (isa & LOONGARCH_CPU_ISA_LA32S) - seq_printf(m, " loongarch32s"); + seq_puts(m, " loongarch32s"); if (isa & LOONGARCH_CPU_ISA_LA64) - seq_printf(m, " loongarch64"); - seq_printf(m, "\n"); + seq_puts(m, " loongarch64"); + seq_puts(m, "\n"); - seq_printf(m, "Features\t\t:"); - if (cpu_has_cpucfg) seq_printf(m, " cpucfg"); - if (cpu_has_lam) seq_printf(m, " lam"); - if (cpu_has_ual) seq_printf(m, " ual"); - if (cpu_has_fpu) seq_printf(m, " fpu"); - if (cpu_has_lsx) seq_printf(m, " lsx"); - if (cpu_has_lasx) seq_printf(m, " lasx"); - if (cpu_has_crc32) seq_printf(m, " crc32"); - if (cpu_has_complex) seq_printf(m, " complex"); - if (cpu_has_crypto) seq_printf(m, " crypto"); - if (cpu_has_ptw) seq_printf(m, " ptw"); - if (cpu_has_lspw) seq_printf(m, " lspw"); - if (cpu_has_lvz) seq_printf(m, " lvz"); - if (cpu_has_lbt_x86) seq_printf(m, " lbt_x86"); - if (cpu_has_lbt_arm) seq_printf(m, " lbt_arm"); - if (cpu_has_lbt_mips) seq_printf(m, " lbt_mips"); - seq_printf(m, "\n"); + seq_puts(m, "Features\t\t:"); + if (cpu_has_cpucfg) + seq_puts(m, " cpucfg"); + if (cpu_has_lam) + seq_puts(m, " lam"); + if (cpu_has_scq) + seq_puts(m, " scq"); + if (cpu_has_ual) + seq_puts(m, " ual"); + if (cpu_has_fpu) + seq_puts(m, " fpu"); + if (cpu_has_lsx) + seq_puts(m, " lsx"); + if (cpu_has_lasx) + seq_puts(m, " lasx"); + if (cpu_has_crc32) + seq_puts(m, " crc32"); + if (cpu_has_complex) + seq_puts(m, " complex"); + if (cpu_has_crypto) + seq_puts(m, " crypto"); + if (cpu_has_ptw) + seq_puts(m, " ptw"); + if (cpu_has_lspw) + seq_puts(m, " lspw"); + if (cpu_has_lvz) + seq_puts(m, " lvz"); + if (cpu_has_lbt_x86) + seq_puts(m, " lbt_x86"); + if (cpu_has_lbt_arm) + seq_puts(m, " lbt_arm"); + if (cpu_has_lbt_mips) + seq_puts(m, " lbt_mips"); + seq_puts(m, "\n"); seq_printf(m, "Hardware Watchpoint\t: %s", str_yes_no(cpu_has_watch)); if (cpu_has_watch) { @@ -83,7 +100,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) cpu_data[n].watch_ireg_count, cpu_data[n].watch_dreg_count); } - seq_printf(m, "\n\n"); + seq_puts(m, "\n\n"); return 0; } diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index d6a1ff0e16f1..839b23edee87 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -413,6 +413,7 @@ static void __init arch_mem_init(char **cmdline_p) PFN_UP(__pa_symbol(&__nosave_end))); memblock_dump_all(); + memblock_set_bottom_up(false); early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn)); } @@ -469,7 +470,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, unsigned long vaddr; struct logic_pio_hwaddr *range; - range = kzalloc(sizeof(*range), GFP_ATOMIC); + range = kzalloc_obj(*range, GFP_ATOMIC); if (!range) return -ENOMEM; diff --git a/arch/loongarch/kernel/smp.c b/arch/loongarch/kernel/smp.c index 8b2fcb3fb874..64a048f1b880 100644 --- a/arch/loongarch/kernel/smp.c +++ b/arch/loongarch/kernel/smp.c @@ -365,16 +365,29 @@ void __init loongson_smp_setup(void) void __init loongson_prepare_cpus(unsigned int max_cpus) { int i = 0; + int threads_per_core = 0; parse_acpi_topology(); cpu_data[0].global_id = cpu_logical_map(0); + if (!pptt_enabled) + threads_per_core = 1; + else { + for_each_possible_cpu(i) { + if (cpu_to_node(i) != 0) + continue; + if (cpus_are_siblings(0, i)) + threads_per_core++; + } + } + for (i = 0; i < loongson_sysconf.nr_cpus; i++) { set_cpu_present(i, true); csr_mail_send(0, __cpu_logical_map[i], 0); } per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + cpu_smt_set_num_threads(threads_per_core, threads_per_core); } /* diff --git a/arch/loongarch/kernel/unwind_orc.c b/arch/loongarch/kernel/unwind_orc.c index 8a6e3429a860..9cfb5bb1991f 100644 --- a/arch/loongarch/kernel/unwind_orc.c +++ b/arch/loongarch/kernel/unwind_orc.c @@ -350,7 +350,21 @@ EXPORT_SYMBOL_GPL(unwind_start); static inline unsigned long bt_address(unsigned long ra) { - extern unsigned long eentry; +#if defined(CONFIG_NUMA) && !defined(CONFIG_PREEMPT_RT) + int cpu; + int vec_sz = sizeof(exception_handlers); + + for_each_possible_cpu(cpu) { + if (!pcpu_handlers[cpu]) + continue; + + if (ra >= pcpu_handlers[cpu] && + ra < pcpu_handlers[cpu] + vec_sz) { + ra = ra + eentry - pcpu_handlers[cpu]; + break; + } + } +#endif if (ra >= eentry && ra < eentry + EXCCODE_INT_END * VECSIZE) { unsigned long func; @@ -494,7 +508,7 @@ bool unwind_next_frame(struct unwind_state *state) state->pc = bt_address(pc); if (!state->pc) { - pr_err("cannot find unwind pc at %p\n", (void *)pc); + pr_err("cannot find unwind pc at %px\n", (void *)pc); goto err; } diff --git a/arch/loongarch/kernel/unwind_prologue.c b/arch/loongarch/kernel/unwind_prologue.c index 729e775bd40d..da07acad7973 100644 --- a/arch/loongarch/kernel/unwind_prologue.c +++ b/arch/loongarch/kernel/unwind_prologue.c @@ -23,10 +23,6 @@ extern const int unwind_hint_lasx; extern const int unwind_hint_lbt; extern const int unwind_hint_ri; extern const int unwind_hint_watch; -extern unsigned long eentry; -#ifdef CONFIG_NUMA -extern unsigned long pcpu_handlers[NR_CPUS]; -#endif static inline bool scan_handlers(unsigned long entry_offset) { @@ -65,7 +61,7 @@ static inline bool scan_handlers(unsigned long entry_offset) static inline bool fix_exception(unsigned long pc) { -#ifdef CONFIG_NUMA +#if defined(CONFIG_NUMA) && !defined(CONFIG_PREEMPT_RT) int cpu; for_each_possible_cpu(cpu) { diff --git a/arch/loongarch/kernel/vdso.c b/arch/loongarch/kernel/vdso.c index dee1a15d7f4c..0aa10cadb959 100644 --- a/arch/loongarch/kernel/vdso.c +++ b/arch/loongarch/kernel/vdso.c @@ -52,7 +52,7 @@ static int __init init_vdso(void) vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start); vdso_info.code_mapping.pages = - kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL); + kzalloc_objs(struct page *, vdso_info.size / PAGE_SIZE); if (!vdso_info.code_mapping.pages) return -ENOMEM; diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S index 08ea921cdec1..d0e1377a041d 100644 --- a/arch/loongarch/kernel/vmlinux.lds.S +++ b/arch/loongarch/kernel/vmlinux.lds.S @@ -147,6 +147,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS #ifdef CONFIG_EFI_STUB diff --git a/arch/loongarch/kvm/Kconfig b/arch/loongarch/kvm/Kconfig index ed4f724db774..8e5213609975 100644 --- a/arch/loongarch/kvm/Kconfig +++ b/arch/loongarch/kvm/Kconfig @@ -28,7 +28,6 @@ config KVM select KVM_COMMON select KVM_GENERIC_DIRTYLOG_READ_PROTECT select KVM_GENERIC_HARDWARE_ENABLING - select KVM_GENERIC_MMU_NOTIFIER select KVM_MMIO select VIRT_XFER_TO_GUEST_WORK select SCHED_INFO diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index e498a3f1e136..d2acb4d09e73 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -622,7 +622,7 @@ static int kvm_eiointc_create(struct kvm_device *dev, u32 type) if (kvm->arch.eiointc) return -EINVAL; - s = kzalloc(sizeof(struct loongarch_eiointc), GFP_KERNEL); + s = kzalloc_obj(struct loongarch_eiointc); if (!s) return -ENOMEM; diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c index 6a044a74c095..1f6ebbd0af5c 100644 --- a/arch/loongarch/kvm/intc/ipi.c +++ b/arch/loongarch/kvm/intc/ipi.c @@ -409,7 +409,7 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type) return -EINVAL; } - s = kzalloc(sizeof(struct loongarch_ipi), GFP_KERNEL); + s = kzalloc_obj(struct loongarch_ipi); if (!s) return -ENOMEM; diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c index a175f52fcf7f..dd7e7f8d53db 100644 --- a/arch/loongarch/kvm/intc/pch_pic.c +++ b/arch/loongarch/kvm/intc/pch_pic.c @@ -402,7 +402,7 @@ static int kvm_setup_default_irq_routing(struct kvm *kvm) u32 nr = KVM_IRQCHIP_NUM_PINS; struct kvm_irq_routing_entry *entries; - entries = kcalloc(nr, sizeof(*entries), GFP_KERNEL); + entries = kzalloc_objs(*entries, nr); if (!entries) return -ENOMEM; @@ -432,7 +432,7 @@ static int kvm_pch_pic_create(struct kvm_device *dev, u32 type) if (ret) return -ENOMEM; - s = kzalloc(sizeof(struct loongarch_pch_pic), GFP_KERNEL); + s = kzalloc_obj(struct loongarch_pch_pic); if (!s) return -ENOMEM; diff --git a/arch/loongarch/kvm/main.c b/arch/loongarch/kvm/main.c index ac38d0f19dd3..2c593ac7892f 100644 --- a/arch/loongarch/kvm/main.c +++ b/arch/loongarch/kvm/main.c @@ -358,7 +358,7 @@ static int kvm_loongarch_env_init(void) return -ENOMEM; } - kvm_loongarch_ops = kzalloc(sizeof(*kvm_loongarch_ops), GFP_KERNEL); + kvm_loongarch_ops = kzalloc_obj(*kvm_loongarch_ops); if (!kvm_loongarch_ops) { free_percpu(vmcs); vmcs = NULL; diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 550c0d05666a..8ffd50a470e6 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -14,7 +14,7 @@ #define CREATE_TRACE_POINTS #include "trace.h" -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, int_exits), STATS_DESC_COUNTER(VCPU, idle_exits), @@ -1547,7 +1547,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) vcpu->arch.handle_exit = kvm_handle_exit; vcpu->arch.guest_eentry = (unsigned long)kvm_loongarch_ops->exc_entry; - vcpu->arch.csr = kzalloc(sizeof(struct loongarch_csrs), GFP_KERNEL); + vcpu->arch.csr = kzalloc_obj(struct loongarch_csrs); if (!vcpu->arch.csr) return -ENOMEM; diff --git a/arch/loongarch/kvm/vm.c b/arch/loongarch/kvm/vm.c index 9681ade890c6..17b3d5b36cfc 100644 --- a/arch/loongarch/kvm/vm.c +++ b/arch/loongarch/kvm/vm.c @@ -10,7 +10,7 @@ #include #include -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_ICOUNTER(VM, pages), STATS_DESC_ICOUNTER(VM, hugepages), @@ -68,7 +68,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) if (!kvm->arch.pgd) return -ENOMEM; - kvm->arch.phyid_map = kvzalloc(sizeof(struct kvm_phyid_map), GFP_KERNEL_ACCOUNT); + kvm->arch.phyid_map = kvzalloc_obj(struct kvm_phyid_map, + GFP_KERNEL_ACCOUNT); if (!kvm->arch.phyid_map) { free_page((unsigned long)kvm->arch.pgd); kvm->arch.pgd = NULL; @@ -117,7 +118,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ONE_REG: case KVM_CAP_ENABLE_CAP: case KVM_CAP_READONLY_MEM: - case KVM_CAP_SYNC_MMU: case KVM_CAP_IMMEDIATE_EXIT: case KVM_CAP_IOEVENTFD: case KVM_CAP_MP_STATE: diff --git a/arch/loongarch/mm/kasan_init.c b/arch/loongarch/mm/kasan_init.c index 170da98ad4f5..0fc02ca06457 100644 --- a/arch/loongarch/mm/kasan_init.c +++ b/arch/loongarch/mm/kasan_init.c @@ -40,39 +40,43 @@ static pgd_t kasan_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); #define __pte_none(early, pte) (early ? pte_none(pte) : \ ((pte_val(pte) & _PFN_MASK) == (unsigned long)__pa(kasan_early_shadow_page))) +static void *mem_to_shadow(const void *addr) +{ + unsigned long offset = 0; + unsigned long maddr = (unsigned long)addr; + unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; + + if (maddr >= FIXADDR_START) + return (void *)(kasan_early_shadow_page); + + maddr &= XRANGE_SHADOW_MASK; + switch (xrange) { + case XKPRANGE_CC_SEG: + offset = XKPRANGE_CC_SHADOW_OFFSET; + break; + case XKPRANGE_UC_SEG: + offset = XKPRANGE_UC_SHADOW_OFFSET; + break; + case XKPRANGE_WC_SEG: + offset = XKPRANGE_WC_SHADOW_OFFSET; + break; + case XKVRANGE_VC_SEG: + offset = XKVRANGE_VC_SHADOW_OFFSET; + break; + default: + WARN_ON(1); + return NULL; + } + + return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); +} + void *kasan_mem_to_shadow(const void *addr) { - if (!kasan_enabled()) { + if (kasan_enabled()) + return mem_to_shadow(addr); + else return (void *)(kasan_early_shadow_page); - } else { - unsigned long maddr = (unsigned long)addr; - unsigned long xrange = (maddr >> XRANGE_SHIFT) & 0xffff; - unsigned long offset = 0; - - if (maddr >= FIXADDR_START) - return (void *)(kasan_early_shadow_page); - - maddr &= XRANGE_SHADOW_MASK; - switch (xrange) { - case XKPRANGE_CC_SEG: - offset = XKPRANGE_CC_SHADOW_OFFSET; - break; - case XKPRANGE_UC_SEG: - offset = XKPRANGE_UC_SHADOW_OFFSET; - break; - case XKPRANGE_WC_SEG: - offset = XKPRANGE_WC_SHADOW_OFFSET; - break; - case XKVRANGE_VC_SEG: - offset = XKVRANGE_VC_SHADOW_OFFSET; - break; - default: - WARN_ON(1); - return NULL; - } - - return (void *)((maddr >> KASAN_SHADOW_SCALE_SHIFT) + offset); - } } const void *kasan_shadow_to_mem(const void *shadow_addr) @@ -293,11 +297,8 @@ void __init kasan_init(void) /* Maps everything to a single page of zeroes */ kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE, true); - kasan_populate_early_shadow(kasan_mem_to_shadow((void *)VMALLOC_START), - kasan_mem_to_shadow((void *)KFENCE_AREA_END)); - - /* Enable KASAN here before kasan_mem_to_shadow(). */ - kasan_init_generic(); + kasan_populate_early_shadow(mem_to_shadow((void *)VMALLOC_START), + mem_to_shadow((void *)KFENCE_AREA_END)); /* Populate the linear mapping */ for_each_mem_range(i, &pa_start, &pa_end) { @@ -307,13 +308,13 @@ void __init kasan_init(void) if (start >= end) break; - kasan_map_populate((unsigned long)kasan_mem_to_shadow(start), - (unsigned long)kasan_mem_to_shadow(end), NUMA_NO_NODE); + kasan_map_populate((unsigned long)mem_to_shadow(start), + (unsigned long)mem_to_shadow(end), NUMA_NO_NODE); } /* Populate modules mapping */ - kasan_map_populate((unsigned long)kasan_mem_to_shadow((void *)MODULES_VADDR), - (unsigned long)kasan_mem_to_shadow((void *)MODULES_END), NUMA_NO_NODE); + kasan_map_populate((unsigned long)mem_to_shadow((void *)MODULES_VADDR), + (unsigned long)mem_to_shadow((void *)MODULES_END), NUMA_NO_NODE); /* * KAsan may reuse the contents of kasan_early_shadow_pte directly, so we * should make sure that it maps the zero page read-only. @@ -328,4 +329,5 @@ void __init kasan_init(void) /* At this point kasan is fully initialized. Enable error messages */ init_task.kasan_depth = 0; + kasan_init_generic(); } diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c index 6a3c91b9cacd..aaf7d685cc2a 100644 --- a/arch/loongarch/mm/tlb.c +++ b/arch/loongarch/mm/tlb.c @@ -202,7 +202,7 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep local_irq_restore(flags); } -static void setup_ptwalker(void) +static void __no_sanitize_address setup_ptwalker(void) { unsigned long pwctl0, pwctl1; unsigned long pgd_i = 0, pgd_w = 0; @@ -262,7 +262,6 @@ static void output_pgtable_bits_defines(void) #ifdef CONFIG_NUMA unsigned long pcpu_handlers[NR_CPUS]; #endif -extern long exception_handlers[VECSIZE * 128 / sizeof(long)]; static void setup_tlb_handler(int cpu) { diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c index 3b63bc5b99d9..3bd89f55960d 100644 --- a/arch/loongarch/net/bpf_jit.c +++ b/arch/loongarch/net/bpf_jit.c @@ -17,6 +17,7 @@ #define LOONGARCH_BPF_FENTRY_NBYTES (LOONGARCH_LONG_JUMP_NINSNS * 4) #define REG_TCC LOONGARCH_GPR_A6 +#define REG_ARENA LOONGARCH_GPR_S6 /* For storing arena_vm_start */ #define BPF_TAIL_CALL_CNT_PTR_STACK_OFF(stack) (round_up(stack, 16) - 80) static const int regmap[] = { @@ -136,6 +137,9 @@ static void build_prologue(struct jit_ctx *ctx) /* To store tcc and tcc_ptr */ stack_adjust += sizeof(long) * 2; + if (ctx->arena_vm_start) + stack_adjust += 8; + stack_adjust = round_up(stack_adjust, 16); stack_adjust += bpf_stack_adjust; @@ -178,6 +182,11 @@ static void build_prologue(struct jit_ctx *ctx) store_offset -= sizeof(long); emit_insn(ctx, std, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, store_offset); + if (ctx->arena_vm_start) { + store_offset -= sizeof(long); + emit_insn(ctx, std, REG_ARENA, LOONGARCH_GPR_SP, store_offset); + } + prepare_bpf_tail_call_cnt(ctx, &store_offset); emit_insn(ctx, addid, LOONGARCH_GPR_FP, LOONGARCH_GPR_SP, stack_adjust); @@ -186,6 +195,9 @@ static void build_prologue(struct jit_ctx *ctx) emit_insn(ctx, addid, regmap[BPF_REG_FP], LOONGARCH_GPR_SP, bpf_stack_adjust); ctx->stack_size = stack_adjust; + + if (ctx->arena_vm_start) + move_imm(ctx, REG_ARENA, ctx->arena_vm_start, false); } static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) @@ -217,6 +229,11 @@ static void __build_epilogue(struct jit_ctx *ctx, bool is_tail_call) load_offset -= sizeof(long); emit_insn(ctx, ldd, LOONGARCH_GPR_S5, LOONGARCH_GPR_SP, load_offset); + if (ctx->arena_vm_start) { + load_offset -= sizeof(long); + emit_insn(ctx, ldd, REG_ARENA, LOONGARCH_GPR_SP, load_offset); + } + /* * When push into the stack, follow the order of tcc then tcc_ptr. * When pop from the stack, first pop tcc_ptr then followed by tcc. @@ -442,6 +459,7 @@ static bool is_signed_bpf_cond(u8 cond) #define BPF_FIXUP_REG_MASK GENMASK(31, 27) #define BPF_FIXUP_OFFSET_MASK GENMASK(26, 0) +#define REG_DONT_CLEAR_MARKER 0 bool ex_handler_bpf(const struct exception_table_entry *ex, struct pt_regs *regs) @@ -449,7 +467,8 @@ bool ex_handler_bpf(const struct exception_table_entry *ex, int dst_reg = FIELD_GET(BPF_FIXUP_REG_MASK, ex->fixup); off_t offset = FIELD_GET(BPF_FIXUP_OFFSET_MASK, ex->fixup); - regs->regs[dst_reg] = 0; + if (dst_reg != REG_DONT_CLEAR_MARKER) + regs->regs[dst_reg] = 0; regs->csr_era = (unsigned long)&ex->fixup - offset; return true; @@ -461,28 +480,33 @@ static int add_exception_handler(const struct bpf_insn *insn, int dst_reg) { unsigned long pc; - off_t offset; + off_t ins_offset, fixup_offset; struct exception_table_entry *ex; - if (!ctx->image || !ctx->prog->aux->extable) + if (!ctx->image || !ctx->ro_image || !ctx->prog->aux->extable) return 0; if (BPF_MODE(insn->code) != BPF_PROBE_MEM && - BPF_MODE(insn->code) != BPF_PROBE_MEMSX) + BPF_MODE(insn->code) != BPF_PROBE_MEMSX && + BPF_MODE(insn->code) != BPF_PROBE_MEM32) return 0; if (WARN_ON_ONCE(ctx->num_exentries >= ctx->prog->aux->num_exentries)) return -EINVAL; ex = &ctx->prog->aux->extable[ctx->num_exentries]; - pc = (unsigned long)&ctx->image[ctx->idx - 1]; + pc = (unsigned long)&ctx->ro_image[ctx->idx - 1]; - offset = pc - (long)&ex->insn; - if (WARN_ON_ONCE(offset >= 0 || offset < INT_MIN)) + /* + * This is the relative offset of the instruction that may fault from + * the exception table itself. This will be written to the exception + * table and if this instruction faults, the destination register will + * be set to '0' and the execution will jump to the next instruction. + */ + ins_offset = pc - (long)&ex->insn; + if (WARN_ON_ONCE(ins_offset >= 0 || ins_offset < INT_MIN)) return -ERANGE; - ex->insn = offset; - /* * Since the extable follows the program, the fixup offset is always * negative and limited to BPF_JIT_REGION_SIZE. Store a positive value @@ -490,13 +514,23 @@ static int add_exception_handler(const struct bpf_insn *insn, * bits. We don't need to worry about buildtime or runtime sort * modifying the upper bits because the table is already sorted, and * isn't part of the main exception table. + * + * The fixup_offset is set to the next instruction from the instruction + * that may fault. The execution will jump to this after handling the fault. */ - offset = (long)&ex->fixup - (pc + LOONGARCH_INSN_SIZE); - if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, offset)) + fixup_offset = (long)&ex->fixup - (pc + LOONGARCH_INSN_SIZE); + if (!FIELD_FIT(BPF_FIXUP_OFFSET_MASK, fixup_offset)) return -ERANGE; + /* + * The offsets above have been calculated using the RO buffer but we + * need to use the R/W buffer for writes. Switch ex to rw buffer for writing. + */ + ex = (void *)ctx->image + ((void *)ex - (void *)ctx->ro_image); + ex->insn = ins_offset; + ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, fixup_offset) | + FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg); ex->type = EX_TYPE_BPF; - ex->fixup = FIELD_PREP(BPF_FIXUP_OFFSET_MASK, offset) | FIELD_PREP(BPF_FIXUP_REG_MASK, dst_reg); ctx->num_exentries++; @@ -514,8 +548,9 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext const u8 cond = BPF_OP(code); const u8 t1 = LOONGARCH_GPR_T1; const u8 t2 = LOONGARCH_GPR_T2; - const u8 src = regmap[insn->src_reg]; - const u8 dst = regmap[insn->dst_reg]; + const u8 t3 = LOONGARCH_GPR_T3; + u8 src = regmap[insn->src_reg]; + u8 dst = regmap[insn->dst_reg]; const s16 off = insn->off; const s32 imm = insn->imm; const bool is32 = BPF_CLASS(insn->code) == BPF_ALU || BPF_CLASS(insn->code) == BPF_JMP32; @@ -524,6 +559,15 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext /* dst = src */ case BPF_ALU | BPF_MOV | BPF_X: case BPF_ALU64 | BPF_MOV | BPF_X: + if (insn_is_cast_user(insn)) { + move_reg(ctx, t1, src); + emit_zext_32(ctx, t1, true); + move_imm(ctx, dst, (ctx->user_vm_start >> 32) << 32, false); + emit_insn(ctx, beq, t1, LOONGARCH_GPR_ZERO, 1); + emit_insn(ctx, or, t1, dst, t1); + move_reg(ctx, dst, t1); + break; + } switch (off) { case 0: move_reg(ctx, dst, src); @@ -1021,8 +1065,19 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext case BPF_LDX | BPF_PROBE_MEMSX | BPF_B: case BPF_LDX | BPF_PROBE_MEMSX | BPF_H: case BPF_LDX | BPF_PROBE_MEMSX | BPF_W: - sign_extend = BPF_MODE(insn->code) == BPF_MEMSX || - BPF_MODE(insn->code) == BPF_PROBE_MEMSX; + /* LDX | PROBE_MEM32: dst = *(unsigned size *)(src + REG_ARENA + off) */ + case BPF_LDX | BPF_PROBE_MEM32 | BPF_B: + case BPF_LDX | BPF_PROBE_MEM32 | BPF_H: + case BPF_LDX | BPF_PROBE_MEM32 | BPF_W: + case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW: + sign_extend = BPF_MODE(code) == BPF_MEMSX || + BPF_MODE(code) == BPF_PROBE_MEMSX; + + if (BPF_MODE(code) == BPF_PROBE_MEM32) { + emit_insn(ctx, addd, t2, src, REG_ARENA); + src = t2; + } + switch (BPF_SIZE(code)) { case BPF_B: if (is_signed_imm12(off)) { @@ -1082,6 +1137,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext case BPF_ST | BPF_MEM | BPF_H: case BPF_ST | BPF_MEM | BPF_W: case BPF_ST | BPF_MEM | BPF_DW: + /* ST | PROBE_MEM32: *(size *)(dst + REG_ARENA + off) = imm */ + case BPF_ST | BPF_PROBE_MEM32 | BPF_B: + case BPF_ST | BPF_PROBE_MEM32 | BPF_H: + case BPF_ST | BPF_PROBE_MEM32 | BPF_W: + case BPF_ST | BPF_PROBE_MEM32 | BPF_DW: + if (BPF_MODE(code) == BPF_PROBE_MEM32) { + emit_insn(ctx, addd, t3, dst, REG_ARENA); + dst = t3; + } + switch (BPF_SIZE(code)) { case BPF_B: move_imm(ctx, t1, imm, is32); @@ -1124,6 +1189,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext } break; } + + ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER); + if (ret) + return ret; break; /* *(size *)(dst + off) = src */ @@ -1131,6 +1200,16 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext case BPF_STX | BPF_MEM | BPF_H: case BPF_STX | BPF_MEM | BPF_W: case BPF_STX | BPF_MEM | BPF_DW: + /* STX | PROBE_MEM32: *(size *)(dst + REG_ARENA + off) = src */ + case BPF_STX | BPF_PROBE_MEM32 | BPF_B: + case BPF_STX | BPF_PROBE_MEM32 | BPF_H: + case BPF_STX | BPF_PROBE_MEM32 | BPF_W: + case BPF_STX | BPF_PROBE_MEM32 | BPF_DW: + if (BPF_MODE(code) == BPF_PROBE_MEM32) { + emit_insn(ctx, addd, t2, dst, REG_ARENA); + dst = t2; + } + switch (BPF_SIZE(code)) { case BPF_B: if (is_signed_imm12(off)) { @@ -1169,6 +1248,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext } break; } + + ret = add_exception_handler(insn, ctx, REG_DONT_CLEAR_MARKER); + if (ret) + return ret; break; case BPF_STX | BPF_ATOMIC | BPF_W: @@ -1829,11 +1912,12 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags, struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) { bool tmp_blinded = false, extra_pass = false; - u8 *image_ptr; + u8 *image_ptr, *ro_image_ptr; int image_size, prog_size, extable_size; struct jit_ctx ctx; struct jit_data *jit_data; struct bpf_binary_header *header; + struct bpf_binary_header *ro_header; struct bpf_prog *tmp, *orig_prog = prog; /* @@ -1859,7 +1943,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; @@ -1868,8 +1952,10 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) } if (jit_data->ctx.offset) { ctx = jit_data->ctx; - image_ptr = jit_data->image; + ro_header = jit_data->ro_header; + ro_image_ptr = (void *)ctx.ro_image; header = jit_data->header; + image_ptr = (void *)header + ((void *)ro_image_ptr - (void *)ro_header); extra_pass = true; prog_size = sizeof(u32) * ctx.idx; goto skip_init_ctx; @@ -1877,6 +1963,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) memset(&ctx, 0, sizeof(ctx)); ctx.prog = prog; + ctx.arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena); + ctx.user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena); ctx.offset = kvcalloc(prog->len + 1, sizeof(u32), GFP_KERNEL); if (ctx.offset == NULL) { @@ -1903,17 +1991,25 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog_size = sizeof(u32) * ctx.idx; image_size = prog_size + extable_size; /* Now we know the size of the structure to make */ - header = bpf_jit_binary_alloc(image_size, &image_ptr, - sizeof(u32), jit_fill_hole); - if (header == NULL) { + ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr, sizeof(u32), + &header, &image_ptr, jit_fill_hole); + if (!ro_header) { prog = orig_prog; goto out_offset; } /* 2. Now, the actual pass to generate final JIT code */ + /* + * Use the image (RW) for writing the JITed instructions. But also save + * the ro_image (RX) for calculating the offsets in the image. The RW + * image will be later copied to the RX image from where the program will + * run. The bpf_jit_binary_pack_finalize() will do this copy in the final + * step. + */ ctx.image = (union loongarch_instruction *)image_ptr; + ctx.ro_image = (union loongarch_instruction *)ro_image_ptr; if (extable_size) - prog->aux->extable = (void *)image_ptr + prog_size; + prog->aux->extable = (void *)ro_image_ptr + prog_size; skip_init_ctx: ctx.idx = 0; @@ -1921,48 +2017,47 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) build_prologue(&ctx); if (build_body(&ctx, extra_pass)) { - bpf_jit_binary_free(header); prog = orig_prog; - goto out_offset; + goto out_free; } build_epilogue(&ctx); /* 3. Extra pass to validate JITed code */ if (validate_ctx(&ctx)) { - bpf_jit_binary_free(header); prog = orig_prog; - goto out_offset; + goto out_free; } /* And we're done */ if (bpf_jit_enable > 1) bpf_jit_dump(prog->len, prog_size, 2, ctx.image); - /* Update the icache */ - flush_icache_range((unsigned long)header, (unsigned long)(ctx.image + ctx.idx)); - if (!prog->is_func || extra_pass) { - int err; - if (extra_pass && ctx.idx != jit_data->ctx.idx) { pr_err_once("multi-func JIT bug %d != %d\n", ctx.idx, jit_data->ctx.idx); goto out_free; } - err = bpf_jit_binary_lock_ro(header); - if (err) { - pr_err_once("bpf_jit_binary_lock_ro() returned %d\n", - err); + if (WARN_ON(bpf_jit_binary_pack_finalize(ro_header, header))) { + /* ro_header has been freed */ + ro_header = NULL; + prog = orig_prog; goto out_free; } + /* + * The instructions have now been copied to the ROX region from + * where they will execute. Now the data cache has to be cleaned + * to the PoU and the I-cache has to be invalidated for the VAs. + */ + bpf_flush_icache(ro_header, ctx.ro_image + ctx.idx); } else { jit_data->ctx = ctx; - jit_data->image = image_ptr; jit_data->header = header; + jit_data->ro_header = ro_header; } prog->jited = 1; prog->jited_len = prog_size; - prog->bpf_func = (void *)ctx.image; + prog->bpf_func = (void *)ctx.ro_image; if (!prog->is_func || extra_pass) { int i; @@ -1982,17 +2077,39 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) if (tmp_blinded) bpf_jit_prog_release_other(prog, prog == orig_prog ? tmp : orig_prog); - return prog; out_free: - bpf_jit_binary_free(header); - prog->bpf_func = NULL; - prog->jited = 0; - prog->jited_len = 0; + if (header) { + bpf_arch_text_copy(&ro_header->size, &header->size, sizeof(header->size)); + bpf_jit_binary_pack_free(ro_header, header); + } goto out_offset; } +void bpf_jit_free(struct bpf_prog *prog) +{ + if (prog->jited) { + struct jit_data *jit_data = prog->aux->jit_data; + struct bpf_binary_header *hdr; + + /* + * If we fail the final pass of JIT (from jit_subprogs), the + * program may not be finalized yet. Call finalize here before + * freeing it. + */ + if (jit_data) { + bpf_jit_binary_pack_finalize(jit_data->ro_header, jit_data->header); + kfree(jit_data); + } + hdr = bpf_jit_binary_pack_hdr(prog); + bpf_jit_binary_pack_free(hdr, NULL); + WARN_ON_ONCE(!bpf_prog_kallsyms_verify_off(prog)); + } + + bpf_prog_unlock_free(prog); +} + bool bpf_jit_bypass_spec_v1(void) { return true; @@ -2003,6 +2120,11 @@ bool bpf_jit_bypass_spec_v4(void) return true; } +bool bpf_jit_supports_arena(void) +{ + return true; +} + /* Indicate the JIT backend supports mixing bpf2bpf and tailcalls. */ bool bpf_jit_supports_subprog_tailcalls(void) { diff --git a/arch/loongarch/net/bpf_jit.h b/arch/loongarch/net/bpf_jit.h index 75b6330030a9..a8e29be35fa8 100644 --- a/arch/loongarch/net/bpf_jit.h +++ b/arch/loongarch/net/bpf_jit.h @@ -20,11 +20,13 @@ struct jit_ctx { union loongarch_instruction *image; union loongarch_instruction *ro_image; u32 stack_size; + u64 arena_vm_start; + u64 user_vm_start; }; struct jit_data { struct bpf_binary_header *header; - u8 *image; + struct bpf_binary_header *ro_header; struct jit_ctx ctx; }; diff --git a/arch/loongarch/pci/acpi.c b/arch/loongarch/pci/acpi.c index 50c9016641a4..0dde3ddcd544 100644 --- a/arch/loongarch/pci/acpi.c +++ b/arch/loongarch/pci/acpi.c @@ -101,7 +101,7 @@ static struct pci_config_window *arch_pci_ecam_create(struct device *dev, if (busr->start > busr->end) return ERR_PTR(-EINVAL); - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return ERR_PTR(-ENOMEM); @@ -199,13 +199,13 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) int domain = root->segment; int busnum = root->secondary.start; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { pr_warn("pci_bus %04x:%02x: ignored (out of memory)\n", domain, busnum); return NULL; } - root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL); + root_ops = kzalloc_obj(*root_ops); if (!root_ops) { kfree(info); return NULL; diff --git a/arch/m68k/68000/ucsimm.c b/arch/m68k/68000/ucsimm.c index c54fde75eae8..6b84e826040f 100644 --- a/arch/m68k/68000/ucsimm.c +++ b/arch/m68k/68000/ucsimm.c @@ -9,6 +9,7 @@ * for more details. */ #include +#include #include #include #include @@ -31,7 +32,7 @@ void __init init_ucsimm(char *command, int size) pr_info("uCsimm/uCdimm hwaddr %pM\n", p); p = getbenv("APPEND"); if (p) - strcpy(p, command); + strscpy(p, command, size); else command[0] = 0; } diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index a537953bc10c..19a7bfefb5d7 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c @@ -47,7 +47,7 @@ void *amiga_chip_alloc(unsigned long size, const char *name) struct resource *res; void *p; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) return NULL; diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index 922e53bcb853..82b31321f61c 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -161,7 +161,7 @@ void *atari_stram_alloc(unsigned long size, const char *owner) /* round up */ size = PAGE_ALIGN(size); - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) return NULL; diff --git a/arch/m68k/configs/amcore_defconfig b/arch/m68k/configs/amcore_defconfig index 88832e9cd7cb..f310b5dacfd8 100644 --- a/arch/m68k/configs/amcore_defconfig +++ b/arch/m68k/configs/amcore_defconfig @@ -61,7 +61,6 @@ CONFIG_SERIAL_MCF_BAUDRATE=115200 CONFIG_SERIAL_MCF_CONSOLE=y # CONFIG_HW_RANDOM is not set CONFIG_I2C=y -# CONFIG_I2C_COMPAT is not set CONFIG_I2C_CHARDEV=y # CONFIG_I2C_HELPER_AUTO is not set CONFIG_I2C_IMX=y @@ -83,7 +82,6 @@ CONFIG_ROMFS_BACKED_BY_BOTH=y CONFIG_PRINTK_TIME=y # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_PANIC_ON_OOPS=y -# CONFIG_SCHED_DEBUG is not set # CONFIG_DEBUG_BUGVERBOSE is not set # CONFIG_CRYPTO_ECHAINIV is not set # CONFIG_CRYPTO_HW is not set diff --git a/arch/m68k/configs/m5475evb_defconfig b/arch/m68k/configs/m5475evb_defconfig index 2473dc30228e..9be4dae84ebf 100644 --- a/arch/m68k/configs/m5475evb_defconfig +++ b/arch/m68k/configs/m5475evb_defconfig @@ -46,6 +46,5 @@ CONFIG_EXT2_FS=y # CONFIG_PROC_PAGE_MONITOR is not set CONFIG_ROMFS_FS=y CONFIG_ROMFS_BACKED_BY_MTD=y -# CONFIG_SCHED_DEBUG is not set CONFIG_BOOTPARAM=y CONFIG_BOOTPARAM_STRING="root=/dev/mtdblock0" diff --git a/arch/m68k/configs/stmark2_defconfig b/arch/m68k/configs/stmark2_defconfig index f9ecb1dcc060..515d9b208b10 100644 --- a/arch/m68k/configs/stmark2_defconfig +++ b/arch/m68k/configs/stmark2_defconfig @@ -90,4 +90,3 @@ CONFIG_PRINTK_TIME=y # CONFIG_SECTION_MISMATCH_WARN_ONLY is not set CONFIG_SLUB_DEBUG_ON=y CONFIG_PANIC_ON_OOPS=y -# CONFIG_SCHED_DEBUG is not set diff --git a/arch/m68k/emu/nfblock.c b/arch/m68k/emu/nfblock.c index 94a4fadc651a..93536cf2a38e 100644 --- a/arch/m68k/emu/nfblock.c +++ b/arch/m68k/emu/nfblock.c @@ -112,7 +112,7 @@ static int __init nfhd_init_one(int id, u32 blocks, u32 bsize) return -EINVAL; } - dev = kmalloc(sizeof(struct nfhd_device), GFP_KERNEL); + dev = kmalloc_obj(struct nfhd_device); if (!dev) goto out; diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds index 2624fc18c131..45d7f4b0177b 100644 --- a/arch/m68k/kernel/vmlinux-nommu.lds +++ b/arch/m68k/kernel/vmlinux-nommu.lds @@ -85,6 +85,7 @@ SECTIONS { _end = .; STABS_DEBUG + MODINFO ELF_DETAILS /* Sections to be discarded */ diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 1ccdd04ae462..7326586afe15 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds @@ -58,6 +58,7 @@ SECTIONS _end = . ; STABS_DEBUG + MODINFO ELF_DETAILS /* Sections to be discarded */ diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index f13ddcc2af5c..1b19fef201fb 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds @@ -51,6 +51,7 @@ __init_begin = .; _end = . ; STABS_DEBUG + MODINFO ELF_DETAILS /* Sections to be discarded */ diff --git a/arch/m68k/lib/memmove.c b/arch/m68k/lib/memmove.c index 6519f7f349f6..e33f00b02e4c 100644 --- a/arch/m68k/lib/memmove.c +++ b/arch/m68k/lib/memmove.c @@ -24,6 +24,15 @@ void *memmove(void *dest, const void *src, size_t n) src = csrc; n--; } +#if defined(CONFIG_M68000) + if ((long)src & 1) { + char *cdest = dest; + const char *csrc = src; + for (; n; n--) + *cdest++ = *csrc++; + return xdest; + } +#endif if (n > 2 && (long)dest & 2) { short *sdest = dest; const short *ssrc = src; @@ -66,6 +75,15 @@ void *memmove(void *dest, const void *src, size_t n) src = csrc; n--; } +#if defined(CONFIG_M68000) + if ((long)src & 1) { + char *cdest = dest; + const char *csrc = src; + for (; n; n--) + *--cdest = *--csrc; + return xdest; + } +#endif if (n > 2 && (long)dest & 2) { short *sdest = dest; const short *ssrc = src; diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c index 7594a945732b..6167999402b1 100644 --- a/arch/m68k/mm/kmap.c +++ b/arch/m68k/mm/kmap.c @@ -110,7 +110,7 @@ static struct vm_struct *get_io_area(unsigned long size) unsigned long addr; struct vm_struct **p, *tmp, *area; - area = kmalloc(sizeof(*area), GFP_KERNEL); + area = kmalloc_obj(*area); if (!area) return NULL; addr = KMAP_START; diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c0c94e26ce39..e48b62b4dc48 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -4,6 +4,7 @@ config MIPS default y select ARCH_32BIT_OFF_T if !64BIT select ARCH_BINFMT_ELF_STATE if MIPS_FP_SUPPORT + select ARCH_HAS_CC_CAN_LINK select ARCH_HAS_CPU_CACHE_ALIASING select ARCH_HAS_CPU_FINALIZE_INIT select ARCH_HAS_CURRENT_STACK_POINTER @@ -1409,7 +1410,6 @@ config CPU_LOONGSON32 select CPU_MIPS32 select CPU_MIPSR2 select CPU_HAS_PREFETCH - select CPU_HAS_LOAD_STORE_LR select CPU_SUPPORTS_32BIT_KERNEL select CPU_SUPPORTS_HIGHMEM select CPU_SUPPORTS_CPUFREQ @@ -3127,6 +3127,33 @@ config CC_HAS_MNO_BRANCH_LIKELY config CC_HAS_BROKEN_INLINE_COMPAT_BRANCH def_bool y if CC_IS_CLANG +config ARCH_CC_CAN_LINK_N32 + bool + default $(cc_can_link_user,-mabi=n32 -EL) if MIPS32_N32 && CPU_LITTLE_ENDIAN + default $(cc_can_link_user,-mabi=n32 -EB) if MIPS32_N32 && CPU_BIG_ENDIAN + +config ARCH_CC_CAN_LINK_N64 + bool + default $(cc_can_link_user,-mabi=64 -EL) if 64BIT && CPU_LITTLE_ENDIAN + default $(cc_can_link_user,-mabi=64 -EB) if 64BIT && CPU_BIG_ENDIAN + +config ARCH_CC_CAN_LINK_O32 + bool + default $(cc_can_link_user,-mabi=32 -EL) if (32BIT || MIPS32_O32) && CPU_LITTLE_ENDIAN + default $(cc_can_link_user,-mabi=32 -EB) if (32BIT || MIPS32_O32) && CPU_BIG_ENDIAN + +config ARCH_CC_CAN_LINK + def_bool ARCH_CC_CAN_LINK_N32 || ARCH_CC_CAN_LINK_N64 || ARCH_CC_CAN_LINK_O32 + +config ARCH_USERFLAGS + string + default "-mabi=n32 -EL" if ARCH_CC_CAN_LINK_N32 && CPU_LITTLE_ENDIAN + default "-mabi=n32 -EB" if ARCH_CC_CAN_LINK_N32 && CPU_BIG_ENDIAN + default "-mabi=64 -EL" if ARCH_CC_CAN_LINK_N64 && CPU_LITTLE_ENDIAN + default "-mabi=64 -EB" if ARCH_CC_CAN_LINK_N64 && CPU_BIG_ENDIAN + default "-mabi=32 -EL" if ARCH_CC_CAN_LINK_O32 && CPU_LITTLE_ENDIAN + default "-mabi=32 -EB" if ARCH_CC_CAN_LINK_O32 && CPU_BIG_ENDIAN + menu "Power management options" config ARCH_HIBERNATION_POSSIBLE diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index 551b0d21d9dc..62a7304ff35f 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c @@ -154,7 +154,7 @@ static struct clk __init *alchemy_clk_setup_cpu(const char *parent_name, struct clk_hw *h; struct clk *clk; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -249,7 +249,7 @@ static struct clk __init *alchemy_clk_setup_aux(const char *parent_name, struct clk *c; struct alchemy_auxpll_clk *a; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return ERR_PTR(-ENOMEM); @@ -775,7 +775,7 @@ static int __init alchemy_clk_init_fgens(int ctype) } id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; - a = kcalloc(6, sizeof(*a), GFP_KERNEL); + a = kzalloc_objs(*a, 6); if (!a) return -ENOMEM; @@ -996,7 +996,7 @@ static int __init alchemy_clk_setup_imux(int ctype) return -ENODEV; } - a = kcalloc(6, sizeof(*a), GFP_KERNEL); + a = kzalloc_objs(*a, 6); if (!a) return -ENOMEM; diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 6c2c2010bbae..b441d6f3f5ae 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c @@ -310,7 +310,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, * If kmalloc fails, it is caught below same * as a channel not available. */ - ctp = kmalloc(sizeof(chan_tab_t), GFP_ATOMIC); + ctp = kmalloc_obj(chan_tab_t, GFP_ATOMIC); chan_tab_ptr[i] = ctp; break; } @@ -412,8 +412,8 @@ u32 au1xxx_dbdma_ring_alloc(u32 chanid, int entries) * and if we try that first we are likely to not waste larger * slabs of memory. */ - desc_base = (u32)kmalloc_array(entries, sizeof(au1x_ddma_desc_t), - GFP_KERNEL|GFP_DMA); + desc_base = (u32) kmalloc_objs(au1x_ddma_desc_t, entries, + GFP_KERNEL | GFP_DMA); if (desc_base == 0) return 0; @@ -1057,7 +1057,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) { int ret; - dbdev_tab = kcalloc(DBDEV_TAB_SIZE, sizeof(dbdev_tab_t), GFP_KERNEL); + dbdev_tab = kzalloc_objs(dbdev_tab_t, DBDEV_TAB_SIZE); if (!dbdev_tab) return -ENOMEM; diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index da74cae6b43a..02bf02164752 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c @@ -202,10 +202,10 @@ static unsigned long alchemy_ehci_data[][2] __initdata = { static int __init _new_usbres(struct resource **r, struct platform_device **d) { - *r = kcalloc(2, sizeof(struct resource), GFP_KERNEL); + *r = kzalloc_objs(struct resource, 2); if (!*r) return -ENOMEM; - *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL); + *d = kzalloc_obj(struct platform_device); if (!*d) { kfree(*r); return -ENOMEM; diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c index 754bdd2ca630..46262c823fcb 100644 --- a/arch/mips/alchemy/devboards/platform.c +++ b/arch/mips/alchemy/devboards/platform.c @@ -87,7 +87,7 @@ int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, if (stschg_irq) cnt++; - sr = kcalloc(cnt, sizeof(struct resource), GFP_KERNEL); + sr = kzalloc_objs(struct resource, cnt); if (!sr) return -ENOMEM; @@ -162,15 +162,15 @@ int __init db1x_register_norflash(unsigned long size, int width, return -EINVAL; ret = -ENOMEM; - parts = kcalloc(5, sizeof(struct mtd_partition), GFP_KERNEL); + parts = kzalloc_objs(struct mtd_partition, 5); if (!parts) goto out; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) goto out1; - pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL); + pfd = kzalloc_obj(struct physmap_flash_data); if (!pfd) goto out2; diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 38ed61b4bd96..5b0504e3771c 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -187,7 +187,7 @@ static struct device * __init bcm47xx_setup_device(void) struct device *dev; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi index ee71045883e7..6dee85909f5a 100644 --- a/arch/mips/boot/dts/loongson/ls7a-pch.dtsi +++ b/arch/mips/boot/dts/loongson/ls7a-pch.dtsi @@ -199,7 +199,8 @@ gmac@3,0 { <13 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_lpi"; interrupt-parent = <&pic>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; + phy-handle = <&phy0>; mdio { #address-cells = <1>; #size-cells = <0>; @@ -222,7 +223,8 @@ gmac@3,1 { <15 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "macirq", "eth_lpi"; interrupt-parent = <&pic>; - phy-mode = "rgmii"; + phy-mode = "rgmii-id"; + phy-handle = <&phy1>; mdio { #address-cells = <1>; #size-cells = <0>; diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c index 5c3de175ef5b..900cda918a9a 100644 --- a/arch/mips/cavium-octeon/octeon-irq.c +++ b/arch/mips/cavium-octeon/octeon-irq.c @@ -100,7 +100,7 @@ static int octeon_irq_set_ciu_mapping(int irq, int line, int bit, int gpio_line, { struct octeon_ciu_chip_data *cd; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) return -ENOMEM; @@ -1462,7 +1462,7 @@ static int __init octeon_irq_init_ciu( struct irq_domain *ciu_domain = NULL; struct octeon_irq_ciu_domain_data *dd; - dd = kzalloc(sizeof(*dd), GFP_KERNEL); + dd = kzalloc_obj(*dd); if (!dd) return -ENOMEM; @@ -1633,7 +1633,7 @@ static int __init octeon_irq_init_gpio( return -EINVAL; } - gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL); + gpiod = kzalloc_obj(*gpiod); if (gpiod) { /* gpio domain host_data is the base hwirq number. */ gpiod->base_hwirq = base_hwirq; @@ -2223,7 +2223,7 @@ static int octeon_irq_cib_map(struct irq_domain *d, return -EINVAL; } - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) return -ENOMEM; @@ -2304,7 +2304,7 @@ static int __init octeon_irq_init_cib(struct device_node *ciu_node, return -EINVAL; } - host_data = kzalloc(sizeof(*host_data), GFP_KERNEL); + host_data = kzalloc_obj(*host_data); if (!host_data) return -ENOMEM; raw_spin_lock_init(&host_data->lock); diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson.h b/arch/mips/include/asm/mach-loongson2ef/loongson.h index 4a098fb10232..0e586787eb87 100644 --- a/arch/mips/include/asm/mach-loongson2ef/loongson.h +++ b/arch/mips/include/asm/mach-loongson2ef/loongson.h @@ -324,4 +324,10 @@ extern unsigned long _loongson_addrwincfg_base; #endif /* ! CONFIG_CPU_SUPPORTS_ADDRWINCFG */ +#ifdef CONFIG_PCI +void loongson2ef_pcibios_init(void); +#else +static inline void loongson2ef_pcibios_init(void) { } +#endif + #endif /* __ASM_MACH_LOONGSON2EF_LOONGSON_H */ diff --git a/arch/mips/include/asm/mach-loongson64/topology.h b/arch/mips/include/asm/mach-loongson64/topology.h index 3414a1fd1783..89bb4deab98a 100644 --- a/arch/mips/include/asm/mach-loongson64/topology.h +++ b/arch/mips/include/asm/mach-loongson64/topology.h @@ -7,7 +7,7 @@ #define cpu_to_node(cpu) (cpu_logical_map(cpu) >> 2) extern cpumask_t __node_cpumask[]; -#define cpumask_of_node(node) (&__node_cpumask[node]) +#define cpumask_of_node(node) ((node) == NUMA_NO_NODE ? cpu_all_mask : &__node_cpumask[node]) struct pci_bus; extern int pcibus_to_node(struct pci_bus *); diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index ba0f62d8eff5..37dea772fd78 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -72,7 +72,7 @@ static int apply_r_mips_hi16(struct module *me, u32 *location, Elf_Addr v, * the carry we need to add. Save the information, and let LO16 do the * actual relocation. */ - n = kmalloc(sizeof *n, GFP_KERNEL); + n = kmalloc_obj(*n); if (!n) return -ENOMEM; diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c index 7f1c136ad850..59833210542f 100644 --- a/arch/mips/kernel/relocate.c +++ b/arch/mips/kernel/relocate.c @@ -420,7 +420,20 @@ void *__init relocate_kernel(void) goto out; /* The current thread is now within the relocated image */ +#ifndef CONFIG_CC_IS_CLANG __current_thread_info = RELOCATED(&init_thread_union); +#else + /* + * LLVM may wrongly restore $gp ($28) in epilog even if it's + * intentionally modified. Work around this by using inline + * assembly to assign $gp. $gp couldn't be listed as output or + * clobber, or LLVM will still restore its original value. + * See also LLVM upstream issue + * https://github.com/llvm/llvm-project/issues/176546 + */ + asm volatile("move $28, %0" : : + "r" (RELOCATED(&init_thread_union))); +#endif /* Return the new kernel's entry point */ kernel_entry = RELOCATED(start_kernel); diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 22d4f9ff3ae2..b01ebaace48e 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c @@ -341,9 +341,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) /* Allocate cluster boot configuration structs */ nclusters = mips_cps_numclusters(); - mips_cps_cluster_bootcfg = kcalloc(nclusters, - sizeof(*mips_cps_cluster_bootcfg), - GFP_KERNEL); + mips_cps_cluster_bootcfg = kzalloc_objs(*mips_cps_cluster_bootcfg, + nclusters); if (!mips_cps_cluster_bootcfg) goto err_out; @@ -353,8 +352,7 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) for (cl = 0; cl < nclusters; cl++) { /* Allocate core boot configuration structs */ ncores = mips_cps_numcores(cl); - core_bootcfg = kcalloc(ncores, sizeof(*core_bootcfg), - GFP_KERNEL); + core_bootcfg = kzalloc_objs(*core_bootcfg, ncores); if (!core_bootcfg) goto err_out; mips_cps_cluster_bootcfg[cl].core_config = core_bootcfg; @@ -369,9 +367,8 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) for (c = 0; c < ncores; c++) { int v; core_vpes = core_vpe_count(cl, c); - core_bootcfg[c].vpe_config = kcalloc(core_vpes, - sizeof(*core_bootcfg[c].vpe_config), - GFP_KERNEL); + core_bootcfg[c].vpe_config = kzalloc_objs(*core_bootcfg[c].vpe_config, + core_vpes); for (v = 0; v < core_vpes; v++) cpumask_set_cpu(nvpe++, &mips_cps_cluster_bootcfg[cl].cpumask); if (!core_bootcfg[c].vpe_config) diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2b708fac8d2c..579b2cc1995a 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S @@ -217,6 +217,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS /* These must appear regardless of . */ diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 2b67c44adab9..b05ee21a1d67 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c @@ -94,7 +94,7 @@ struct vpe *alloc_vpe(int minor) { struct vpe *v; - v = kzalloc(sizeof(struct vpe), GFP_KERNEL); + v = kzalloc_obj(struct vpe); if (v == NULL) goto out; @@ -115,7 +115,7 @@ struct tc *alloc_tc(int index) { struct tc *tc; - tc = kzalloc(sizeof(struct tc), GFP_KERNEL); + tc = kzalloc_obj(struct tc); if (tc == NULL) goto out; @@ -318,7 +318,7 @@ static int apply_r_mips_hi16(struct module *me, uint32_t *location, * the carry we need to add. Save the information, and let LO16 do the * actual relocation. */ - n = kmalloc(sizeof(*n), GFP_KERNEL); + n = kmalloc_obj(*n); if (!n) return -ENOMEM; diff --git a/arch/mips/kvm/Kconfig b/arch/mips/kvm/Kconfig index cc13cc35f208..b1b9a1d67758 100644 --- a/arch/mips/kvm/Kconfig +++ b/arch/mips/kvm/Kconfig @@ -23,7 +23,6 @@ config KVM select KVM_COMMON select KVM_GENERIC_DIRTYLOG_READ_PROTECT select KVM_MMIO - select KVM_GENERIC_MMU_NOTIFIER select KVM_GENERIC_HARDWARE_ENABLING select HAVE_KVM_READONLY_MEM help diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index b0fb92fda4d4..a53abbba43ea 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -38,7 +38,7 @@ #define VECTORSPACING 0x100 /* for EI/VI mode */ #endif -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS() }; @@ -51,7 +51,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, wait_exits), STATS_DESC_COUNTER(VCPU, cache_exits), @@ -1035,7 +1035,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) case KVM_CAP_ONE_REG: case KVM_CAP_ENABLE_CAP: case KVM_CAP_READONLY_MEM: - case KVM_CAP_SYNC_MMU: case KVM_CAP_IMMEDIATE_EXIT: r = 1; break; diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c index 577e6e6309a6..139a65c42a78 100644 --- a/arch/mips/lantiq/falcon/sysctrl.c +++ b/arch/mips/lantiq/falcon/sysctrl.c @@ -161,7 +161,7 @@ static void falcon_gpe_enable(void) static inline void clkdev_add_sys(const char *dev, unsigned int module, unsigned int bits) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = kzalloc_obj(struct clk); if (!clk) return; diff --git a/arch/mips/lantiq/xway/gptu.c b/arch/mips/lantiq/xway/gptu.c index 484c9e3000c1..cbf0639cb3d6 100644 --- a/arch/mips/lantiq/xway/gptu.c +++ b/arch/mips/lantiq/xway/gptu.c @@ -121,7 +121,7 @@ static void gptu_disable(struct clk *clk) static inline void clkdev_add_gptu(struct device *dev, const char *con, unsigned int timer) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = kzalloc_obj(struct clk); if (!clk) return; diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c index d9aa80afdf9d..dd187726e3b2 100644 --- a/arch/mips/lantiq/xway/sysctrl.c +++ b/arch/mips/lantiq/xway/sysctrl.c @@ -331,7 +331,7 @@ static int clkout_enable(struct clk *clk) static void clkdev_add_pmu(const char *dev, const char *con, bool deactivate, unsigned int module, unsigned int bits) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = kzalloc_obj(struct clk); if (!clk) return; @@ -356,7 +356,7 @@ static void clkdev_add_pmu(const char *dev, const char *con, bool deactivate, static void clkdev_add_cgu(const char *dev, const char *con, unsigned int bits) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = kzalloc_obj(struct clk); if (!clk) return; @@ -374,8 +374,8 @@ static unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0}; static void clkdev_add_pci(void) { - struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); - struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL); + struct clk *clk = kzalloc_obj(struct clk); + struct clk *clk_ext = kzalloc_obj(struct clk); /* main pci clock */ if (clk) { @@ -423,7 +423,7 @@ static void clkdev_add_clkout(void) continue; sprintf(name, "clkout%d", i); - clk = kzalloc(sizeof(struct clk), GFP_KERNEL); + clk = kzalloc_obj(struct clk); if (!clk) { kfree(name); continue; diff --git a/arch/mips/loongson2ef/common/pci.c b/arch/mips/loongson2ef/common/pci.c index 7d9ea51e8c01..0f11392104bf 100644 --- a/arch/mips/loongson2ef/common/pci.c +++ b/arch/mips/loongson2ef/common/pci.c @@ -17,7 +17,7 @@ static struct resource loongson_pci_mem_resource = { static struct resource loongson_pci_io_resource = { .name = "pci io space", - .start = LOONGSON_PCI_IO_START, + .start = 0x00000000UL, /* See loongson2ef_pcibios_init(). */ .end = IO_SPACE_LIMIT, .flags = IORESOURCE_IO, }; @@ -73,15 +73,19 @@ static void __init setup_pcimap(void) #endif } -static int __init pcibios_init(void) +void __init loongson2ef_pcibios_init(void) { setup_pcimap(); + /* + * ISA-mode only IDE controllers have a hard dependency on ISA IO ports. + * + * Claim them by setting PCI IO space to start at 0x00000000, and set + * PCIBIOS_MIN_IO to prevent non-legacy PCI devices from touching + * reserved regions. + */ + PCIBIOS_MIN_IO = LOONGSON_PCI_IO_START; + loongson_pci_controller.io_map_base = mips_io_port_base; register_pci_controller(&loongson_pci_controller); - - - return 0; } - -arch_initcall(pcibios_init); diff --git a/arch/mips/loongson2ef/common/setup.c b/arch/mips/loongson2ef/common/setup.c index 4fd27f4f90ed..a639e35acce5 100644 --- a/arch/mips/loongson2ef/common/setup.c +++ b/arch/mips/loongson2ef/common/setup.c @@ -27,4 +27,5 @@ EXPORT_SYMBOL(__wbflush); void __init plat_mem_setup(void) { + loongson2ef_pcibios_init(); } diff --git a/arch/mips/loongson64/env.c b/arch/mips/loongson64/env.c index be8d2ad10750..11ddf02d6a15 100644 --- a/arch/mips/loongson64/env.c +++ b/arch/mips/loongson64/env.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,101 @@ void __init prom_dtb_init_env(void) loongson_fdt_blob = (void *)fw_arg2; } +static int __init lefi_fixup_fdt_serial(void *fdt, u64 uart_addr, u32 uart_clk) +{ + int node, len, depth = -1; + const fdt64_t *reg; + fdt32_t *clk; + + for (node = fdt_next_node(fdt, -1, &depth); + node >= 0 && depth >= 0; + node = fdt_next_node(fdt, node, &depth)) { + reg = fdt_getprop(fdt, node, "reg", &len); + if (!reg || len <= 8 || fdt64_ld(reg) != uart_addr) + continue; + + clk = fdt_getprop_w(fdt, node, "clock-frequency", &len); + if (!clk) { + pr_warn("UART 0x%llx misses clock-frequency property\n", + uart_addr); + return -ENOENT; + } else if (len != 4) { + pr_warn("UART 0x%llx has invalid clock-frequency property\n", + uart_addr); + return -EINVAL; + } + + fdt32_st(clk, uart_clk); + + return 0; + } + + return -ENODEV; +} + +static void __init lefi_fixup_fdt(struct system_loongson *system) +{ + static unsigned char fdt_buf[16 << 10] __initdata; + struct uart_device *uartdev; + bool is_loongson64g; + u64 uart_base; + int ret, i; + + ret = fdt_open_into(loongson_fdt_blob, fdt_buf, sizeof(fdt_buf)); + if (ret) { + pr_err("Failed to open FDT to fix up\n"); + return; + } + + is_loongson64g = (read_c0_prid() & PRID_IMP_MASK) == PRID_IMP_LOONGSON_64G; + + for (i = 0; i < system->nr_uarts; i++) { + uartdev = &system->uarts[i]; + + ret = lefi_fixup_fdt_serial(fdt_buf, uartdev->uart_base, + uartdev->uartclk); + /* + * LOONGSON64G's CPU serials are mapped to two different + * addresses, one full-featured but differs from + * previous generations, one fully compatible with them. + * + * It's unspecified that which mapping should uart_base refer + * to, thus we should try fixing up with both. + */ + if (ret == -ENODEV && is_loongson64g) { + switch (uartdev->uart_base) { + case 0x1fe00100: + uart_base = 0x1fe001e0; + break; + case 0x1fe00110: + uart_base = 0x1fe001e8; + break; + case 0x1fe001e0: + uart_base = 0x1fe00100; + break; + case 0x1fe001e8: + uart_base = 0x1fe00110; + break; + default: + pr_err("Unexpected UART address 0x%llx passed by firmware\n", + uartdev->uart_base); + ret = -EINVAL; + goto err_fixup; + } + + ret = lefi_fixup_fdt_serial(fdt_buf, uart_base, + uartdev->uartclk); + } + +err_fixup: + if (ret) + pr_err("Couldn't fix up FDT node for UART 0x%llx\n", + uartdev->uart_base); + } + + loongson_fdt_blob = fdt_buf; +} + void __init prom_lefi_init_env(void) { struct boot_params *boot_p; @@ -237,4 +333,6 @@ void __init prom_lefi_init_env(void) if (!loongson_fdt_blob) pr_err("Failed to determine built-in Loongson64 dtb\n"); + else + lefi_fixup_fdt(esys); } diff --git a/arch/mips/loongson64/init.c b/arch/mips/loongson64/init.c index b9f90f33fc9a..5f73f8663ab2 100644 --- a/arch/mips/loongson64/init.c +++ b/arch/mips/loongson64/init.c @@ -156,7 +156,7 @@ static int __init add_legacy_isa_io(struct fwnode_handle *fwnode, resource_size_ struct logic_pio_hwaddr *range; unsigned long vaddr; - range = kzalloc(sizeof(*range), GFP_ATOMIC); + range = kzalloc_obj(*range, GFP_ATOMIC); if (!range) return -ENOMEM; diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 6bfee0f71803..19175171905e 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c @@ -380,7 +380,7 @@ static int alchemy_pci_probe(struct platform_device *pdev) goto out; } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { dev_err(&pdev->dev, "no memory for pcictl context\n"); ret = -ENOMEM; diff --git a/arch/mips/pci/pci-xtalk-bridge.c b/arch/mips/pci/pci-xtalk-bridge.c index e00c38620d14..cf115abb54e0 100644 --- a/arch/mips/pci/pci-xtalk-bridge.c +++ b/arch/mips/pci/pci-xtalk-bridge.c @@ -341,7 +341,7 @@ static int bridge_domain_alloc(struct irq_domain *domain, unsigned int virq, if (nr_irqs > 1 || !info) return -EINVAL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/arch/mips/pic32/common/reset.c b/arch/mips/pic32/common/reset.c index a5fd7a8e2800..230db4bad1dd 100644 --- a/arch/mips/pic32/common/reset.c +++ b/arch/mips/pic32/common/reset.c @@ -4,9 +4,10 @@ * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. */ #include +#include +#include #include #include -#include #define PIC32_RSWRST 0x10 diff --git a/arch/mips/pic32/pic32mzda/config.c b/arch/mips/pic32/pic32mzda/config.c index 73be5689e0df..fc21cbc11f7d 100644 --- a/arch/mips/pic32/pic32mzda/config.c +++ b/arch/mips/pic32/pic32mzda/config.c @@ -5,10 +5,9 @@ */ #include #include +#include #include -#include - #include "pic32mzda.h" #define PIC32_CFGCON 0x0000 diff --git a/arch/mips/pic32/pic32mzda/early_clk.c b/arch/mips/pic32/pic32mzda/early_clk.c index 6001e507d8e3..21a9f6687f6d 100644 --- a/arch/mips/pic32/pic32mzda/early_clk.c +++ b/arch/mips/pic32/pic32mzda/early_clk.c @@ -3,7 +3,8 @@ * Joshua Henderson * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. */ -#include +#include +#include #include "pic32mzda.h" diff --git a/arch/mips/pic32/pic32mzda/early_console.c b/arch/mips/pic32/pic32mzda/early_console.c index 3cd1b408fa1c..1b7631d12d1f 100644 --- a/arch/mips/pic32/pic32mzda/early_console.c +++ b/arch/mips/pic32/pic32mzda/early_console.c @@ -3,7 +3,8 @@ * Joshua Henderson * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. */ -#include +#include +#include #include #include diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index 672249a13a09..c5f1ebce006f 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -198,7 +198,7 @@ static int __init mt7620_soc_dev_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/mips/ralink/mt7621.c b/arch/mips/ralink/mt7621.c index 5a9fd3fe41d7..a4bdda8541c0 100644 --- a/arch/mips/ralink/mt7621.c +++ b/arch/mips/ralink/mt7621.c @@ -144,7 +144,7 @@ static int __init mt7621_soc_dev_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/mips/ralink/rt288x.c b/arch/mips/ralink/rt288x.c index ce8b5b6025bb..19bb81eba57a 100644 --- a/arch/mips/ralink/rt288x.c +++ b/arch/mips/ralink/rt288x.c @@ -68,7 +68,7 @@ static int __init rt2880_soc_dev_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/mips/ralink/rt305x.c b/arch/mips/ralink/rt305x.c index 1f422470b029..ed4159135ed9 100644 --- a/arch/mips/ralink/rt305x.c +++ b/arch/mips/ralink/rt305x.c @@ -171,7 +171,7 @@ static int __init rt305x_soc_dev_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/mips/ralink/rt3883.c b/arch/mips/ralink/rt3883.c index 21ce00da5758..98aee412f532 100644 --- a/arch/mips/ralink/rt3883.c +++ b/arch/mips/ralink/rt3883.c @@ -68,7 +68,7 @@ static int __init rt3883_soc_dev_init(void) struct soc_device *soc_dev; struct soc_device_attribute *soc_dev_attr; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 8ecb56be81ac..4f027efbf27b 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c @@ -213,11 +213,12 @@ static struct platform_device rb532_wdt = { static struct plat_serial8250_port rb532_uart_res[] = { { .type = PORT_16550A, - .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), + .mapbase = REGBASE + UART0BASE, + .mapsize = 0x1000, .irq = UART0_IRQ, .regshift = 2, .iotype = UPIO_MEM, - .flags = UPF_BOOT_AUTOCONF, + .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, }, { .flags = 0, diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index 19b70928d6dc..9eec8842ffb7 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c @@ -361,7 +361,7 @@ static void ip22_check_gio(int slotno, unsigned long addr, int irq) } printk(KERN_INFO "GIO: slot %d : %s (id %x)\n", slotno, name, id); - gio_dev = kzalloc(sizeof *gio_dev, GFP_KERNEL); + gio_dev = kzalloc_obj(*gio_dev); if (!gio_dev) return; gio_dev->name = name; diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 20ef663af16e..7e5aa04c6695 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c @@ -129,7 +129,7 @@ static int hub_domain_alloc(struct irq_domain *domain, unsigned int virq, if (nr_irqs > 1 || !info) return -EINVAL; - hd = kzalloc(sizeof(*hd), GFP_KERNEL); + hd = kzalloc_obj(*hd); if (!hd) return -ENOMEM; diff --git a/arch/mips/sgi-ip27/ip27-xtalk.c b/arch/mips/sgi-ip27/ip27-xtalk.c index 5143d1cf8984..10834880c261 100644 --- a/arch/mips/sgi-ip27/ip27-xtalk.c +++ b/arch/mips/sgi-ip27/ip27-xtalk.c @@ -34,7 +34,7 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) offset = NODE_OFFSET(nasid); - wd = kzalloc(sizeof(*wd), GFP_KERNEL); + wd = kzalloc_obj(*wd); if (!wd) { pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); return; @@ -69,7 +69,7 @@ static void bridge_platform_create(nasid_t nasid, int widget, int masterwid) /* platform_device_add_data() duplicates the data */ kfree(wd); - bd = kzalloc(sizeof(*bd), GFP_KERNEL); + bd = kzalloc_obj(*bd); if (!bd) { pr_warn("xtalk:n%d/%x bridge create out of memory\n", nasid, widget); goto err_unregister_pdev_wd; diff --git a/arch/mips/sgi-ip30/ip30-irq.c b/arch/mips/sgi-ip30/ip30-irq.c index 9fb905e2cf14..4b21b7b6ffe1 100644 --- a/arch/mips/sgi-ip30/ip30-irq.c +++ b/arch/mips/sgi-ip30/ip30-irq.c @@ -209,7 +209,7 @@ static int heart_domain_alloc(struct irq_domain *domain, unsigned int virq, if (nr_irqs > 1 || !info) return -EINVAL; - hd = kzalloc(sizeof(*hd), GFP_KERNEL); + hd = kzalloc_obj(*hd); if (!hd) return -ENOMEM; diff --git a/arch/mips/sgi-ip30/ip30-xtalk.c b/arch/mips/sgi-ip30/ip30-xtalk.c index d798ee8c998c..1e14d59a5787 100644 --- a/arch/mips/sgi-ip30/ip30-xtalk.c +++ b/arch/mips/sgi-ip30/ip30-xtalk.c @@ -44,7 +44,7 @@ static void bridge_platform_create(int widget, int masterwid) struct platform_device *pdev_bd; struct resource w1_res; - wd = kzalloc(sizeof(*wd), GFP_KERNEL); + wd = kzalloc_obj(*wd); if (!wd) { pr_warn("xtalk:%x bridge create out of memory\n", widget); return; @@ -79,7 +79,7 @@ static void bridge_platform_create(int widget, int masterwid) /* platform_device_add_data() duplicates the data */ kfree(wd); - bd = kzalloc(sizeof(*bd), GFP_KERNEL); + bd = kzalloc_obj(*bd); if (!bd) { pr_warn("xtalk:%x bridge create out of memory\n", widget); goto err_unregister_pdev_wd; diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index d9249f5a632e..a52082878e8c 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -120,7 +120,7 @@ txx9_alloc_pci_controller(struct pci_controller *pcic, int min_size = 0x10000; if (!pcic) { - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; new->r_mem[0].name = "PCI mem"; diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index 03f8a3a95637..6c5025806914 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c @@ -648,7 +648,7 @@ void __init txx9_iocled_init(unsigned long baseaddr, if (!deftriggers) deftriggers = default_triggers; - iocled = kzalloc(sizeof(*iocled), GFP_KERNEL); + iocled = kzalloc_obj(*iocled); if (!iocled) return; iocled->mmioaddr = ioremap(baseaddr, 1); @@ -822,7 +822,7 @@ void __init txx9_sramc_init(struct resource *r) err = subsys_system_register(&txx9_sramc_subsys, NULL); if (err) return; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return; size = resource_size(r); diff --git a/arch/nios2/kernel/vmlinux.lds.S b/arch/nios2/kernel/vmlinux.lds.S index 37b958055064..206f92445bfa 100644 --- a/arch/nios2/kernel/vmlinux.lds.S +++ b/arch/nios2/kernel/vmlinux.lds.S @@ -57,6 +57,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/nios2/platform/platform.c b/arch/nios2/platform/platform.c index 9737a87121fa..7948f063f55d 100644 --- a/arch/nios2/platform/platform.c +++ b/arch/nios2/platform/platform.c @@ -28,7 +28,7 @@ static int __init nios2_soc_device_init(void) struct soc_device_attribute *soc_dev_attr; const char *machine; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (soc_dev_attr) { machine = of_flat_dt_get_machine_name(); if (machine) diff --git a/arch/openrisc/kernel/vmlinux.lds.S b/arch/openrisc/kernel/vmlinux.lds.S index 049bff45f612..9b29c3211774 100644 --- a/arch/openrisc/kernel/vmlinux.lds.S +++ b/arch/openrisc/kernel/vmlinux.lds.S @@ -101,6 +101,7 @@ SECTIONS /* Throw in the debugging sections */ STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS /* Sections to be discarded -- must be last */ diff --git a/arch/parisc/boot/compressed/vmlinux.lds.S b/arch/parisc/boot/compressed/vmlinux.lds.S index ab7b43990857..87d24cc824b6 100644 --- a/arch/parisc/boot/compressed/vmlinux.lds.S +++ b/arch/parisc/boot/compressed/vmlinux.lds.S @@ -90,6 +90,7 @@ SECTIONS /* Sections to be discarded */ DISCARDS /DISCARD/ : { + *(.modinfo) #ifdef CONFIG_64BIT /* temporary hack until binutils is fixed to not emit these * for static binaries diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h index 2c139a4dbf4b..17afe7a59edf 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h @@ -85,7 +85,7 @@ extern void __update_cache(pte_t pte); printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e)) /* This is the size of the initially mapped kernel memory */ -#if defined(CONFIG_64BIT) +#if defined(CONFIG_64BIT) || defined(CONFIG_KALLSYMS) #define KERNEL_INITIAL_ORDER 26 /* 1<<26 = 64MB */ #else #define KERNEL_INITIAL_ORDER 25 /* 1<<25 = 32MB */ diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 7707158a7840..bc47bbe3026e 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -418,7 +418,7 @@ static void setup_bus_id(struct parisc_device *padev) static struct parisc_device * __init create_tree_node(char id, struct device *parent) { - struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct parisc_device *dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 96e0264ac961..9188c8d87437 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S @@ -56,6 +56,7 @@ ENTRY(parisc_kernel_start) .import __bss_start,data .import __bss_stop,data + .import __end,data load32 PA(__bss_start),%r3 load32 PA(__bss_stop),%r4 @@ -149,7 +150,11 @@ $cpu_ok: * everything ... it will get remapped correctly later */ ldo 0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */ load32 (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ - load32 PA(pg0),%r1 + load32 PA(_end),%r1 + SHRREG %r1,PAGE_SHIFT,%r1 /* %r1 is PFN count for _end symbol */ + cmpb,<<,n %r11,%r1,1f + copy %r1,%r11 /* %r1 PFN count smaller than %r11 */ +1: load32 PA(pg0),%r1 $pgt_fill_loop: STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1) diff --git a/arch/parisc/kernel/inventory.c b/arch/parisc/kernel/inventory.c index 05798355cff4..103f58dac948 100644 --- a/arch/parisc/kernel/inventory.c +++ b/arch/parisc/kernel/inventory.c @@ -193,7 +193,7 @@ pat_query_module(ulong pcell_loc, ulong mod_index) long status; /* PDC return value status */ struct parisc_device *dev; - pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + pa_pdc_cell = kmalloc_obj(*pa_pdc_cell); if (!pa_pdc_cell) panic("couldn't allocate memory for PDC_PAT_CELL!"); @@ -536,7 +536,7 @@ add_system_map_addresses(struct parisc_device *dev, int num_addrs, long status; struct pdc_system_map_addr_info addr_result; - dev->addr = kmalloc_array(num_addrs, sizeof(*dev->addr), GFP_KERNEL); + dev->addr = kmalloc_objs(*dev->addr, num_addrs); if(!dev->addr) { printk(KERN_ERR "%s %s(): memory allocation failure\n", __FILE__, __func__); diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c index beb30c5de097..d09be22babdb 100644 --- a/arch/parisc/kernel/processor.c +++ b/arch/parisc/kernel/processor.c @@ -110,7 +110,7 @@ static int __init processor_probe(struct parisc_device *dev) unsigned long bytecnt; pdc_pat_cell_mod_maddr_block_t *pa_pdc_cell; - pa_pdc_cell = kmalloc(sizeof (*pa_pdc_cell), GFP_KERNEL); + pa_pdc_cell = kmalloc_obj(*pa_pdc_cell); if (!pa_pdc_cell) panic("couldn't allocate memory for PDC_PAT_CELL!"); diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c index ace483b6f19a..d3e17a7a8901 100644 --- a/arch/parisc/kernel/setup.c +++ b/arch/parisc/kernel/setup.c @@ -120,14 +120,6 @@ void __init setup_arch(char **cmdline_p) #endif printk(KERN_CONT ".\n"); - /* - * Check if initial kernel page mappings are sufficient. - * panic early if not, else we may access kernel functions - * and variables which can't be reached. - */ - if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE) - panic("KERNEL_INITIAL_ORDER too small!"); - #ifdef CONFIG_64BIT if(parisc_narrow_firmware) { printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n"); @@ -279,6 +271,18 @@ void __init start_parisc(void) int ret, cpunum; struct pdc_coproc_cfg coproc_cfg; + /* + * Check if initial kernel page mapping is sufficient. + * Print warning if not, because we may access kernel functions and + * variables which can't be reached yet through the initial mappings. + * Note that the panic() and printk() functions are not functional + * yet, so we need to use direct iodc() firmware calls instead. + */ + const char warn1[] = "CRITICAL: Kernel may crash because " + "KERNEL_INITIAL_ORDER is too small.\n"; + if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE) + pdc_iodc_print(warn1, sizeof(warn1) - 1); + /* check QEMU/SeaBIOS marker in PAGE0 */ running_on_qemu = (memcmp(&PAGE0->pad0, "SeaBIOS", 8) == 0); diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 7ac88ff13d3c..32103a270a8e 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c @@ -157,7 +157,7 @@ unwind_table_add(const char *name, unsigned long base_addr, unwind_table_sort(s, e); - table = kmalloc(sizeof(struct unwind_table), GFP_USER); + table = kmalloc_obj(struct unwind_table, GFP_USER); if (table == NULL) return NULL; unwind_table_init(table, name, base_addr, gp, start, end); @@ -408,7 +408,7 @@ void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct struct pt_regs *r = &t->thread.regs; struct pt_regs *r2; - r2 = kmalloc(sizeof(struct pt_regs), GFP_ATOMIC); + r2 = kmalloc_obj(struct pt_regs, GFP_ATOMIC); if (!r2) return; *r2 = *r; diff --git a/arch/parisc/kernel/vdso.c b/arch/parisc/kernel/vdso.c index c5cbfce7a84c..54c18574424a 100644 --- a/arch/parisc/kernel/vdso.c +++ b/arch/parisc/kernel/vdso.c @@ -102,7 +102,7 @@ static struct page ** __init vdso_setup_pages(void *start, void *end) struct page **pagelist; int i; - pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + pagelist = kzalloc_objs(struct page *, pages + 1); if (!pagelist) panic("%s: Cannot allocate page list for VDSO", __func__); for (i = 0; i < pages; i++) diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index b445e47903cf..0ca93d6d7235 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S @@ -165,6 +165,7 @@ SECTIONS _end = . ; STABS_DEBUG + MODINFO ELF_DETAILS .note 0 : { *(.note) } diff --git a/arch/parisc/net/bpf_jit_core.c b/arch/parisc/net/bpf_jit_core.c index 06cbcd6fe87b..a5eb6b51e27a 100644 --- a/arch/parisc/net/bpf_jit_core.c +++ b/arch/parisc/net/bpf_jit_core.c @@ -63,7 +63,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; @@ -80,7 +80,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) } ctx->prog = prog; - ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + ctx->offset = kzalloc_objs(int, prog->len); if (!ctx->offset) { prog = orig_prog; goto out_offset; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index ad7a2fe63a2a..10240cb80904 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -573,8 +573,8 @@ config ARCH_USING_PATCHABLE_FUNCTION_ENTRY depends on FUNCTION_TRACER && (PPC32 || PPC64_ELF_ABI_V2) depends on $(cc-option,-fpatchable-function-entry=2) def_bool y if PPC32 - def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN - def_bool $(success,$(srctree)/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh $(CC) -mbig-endian) if PPC64 && CPU_BIG_ENDIAN + def_bool $(success,$(srctree)/arch/powerpc/tools/check-fpatchable-function-entry.sh $(CC) $(CLANG_FLAGS) -mlittle-endian) if PPC64 && CPU_LITTLE_ENDIAN + def_bool $(success,$(srctree)/arch/powerpc/tools/check-fpatchable-function-entry.sh $(CC) -mbig-endian) if PPC64 && CPU_BIG_ENDIAN config PPC_FTRACE_OUT_OF_LINE def_bool PPC64 && ARCH_USING_PATCHABLE_FUNCTION_ENTRY diff --git a/arch/powerpc/boot/dts/asp834x-redboot.dts b/arch/powerpc/boot/dts/asp834x-redboot.dts index 33ddb17d1876..c541bd367983 100644 --- a/arch/powerpc/boot/dts/asp834x-redboot.dts +++ b/arch/powerpc/boot/dts/asp834x-redboot.dts @@ -37,7 +37,7 @@ PowerPC,8347@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x8000000>; // 128MB at 0 }; diff --git a/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi b/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi deleted file mode 100644 index 9cffccf4e07e..000000000000 --- a/arch/powerpc/boot/dts/fsl/interlaken-lac-portals.dtsi +++ /dev/null @@ -1,156 +0,0 @@ -/* T4240 Interlaken LAC Portal device tree stub with 24 portals. - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#address-cells = <0x1>; -#size-cells = <0x1>; -compatible = "fsl,interlaken-lac-portals"; - -lportal0: lac-portal@0 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x0 0x1000>; -}; - -lportal1: lac-portal@1000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x1000 0x1000>; -}; - -lportal2: lac-portal@2000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x2000 0x1000>; -}; - -lportal3: lac-portal@3000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x3000 0x1000>; -}; - -lportal4: lac-portal@4000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x4000 0x1000>; -}; - -lportal5: lac-portal@5000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x5000 0x1000>; -}; - -lportal6: lac-portal@6000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x6000 0x1000>; -}; - -lportal7: lac-portal@7000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x7000 0x1000>; -}; - -lportal8: lac-portal@8000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x8000 0x1000>; -}; - -lportal9: lac-portal@9000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x9000 0x1000>; -}; - -lportal10: lac-portal@A000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xA000 0x1000>; -}; - -lportal11: lac-portal@B000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xB000 0x1000>; -}; - -lportal12: lac-portal@C000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xC000 0x1000>; -}; - -lportal13: lac-portal@D000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xD000 0x1000>; -}; - -lportal14: lac-portal@E000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xE000 0x1000>; -}; - -lportal15: lac-portal@F000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0xF000 0x1000>; -}; - -lportal16: lac-portal@10000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x10000 0x1000>; -}; - -lportal17: lac-portal@11000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x11000 0x1000>; -}; - -lportal18: lac-portal@1200 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x12000 0x1000>; -}; - -lportal19: lac-portal@13000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x13000 0x1000>; -}; - -lportal20: lac-portal@14000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x14000 0x1000>; -}; - -lportal21: lac-portal@15000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x15000 0x1000>; -}; - -lportal22: lac-portal@16000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x16000 0x1000>; -}; - -lportal23: lac-portal@17000 { - compatible = "fsl,interlaken-lac-portal-v1.0"; - reg = <0x17000 0x1000>; -}; diff --git a/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi b/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi deleted file mode 100644 index e8208720ac0e..000000000000 --- a/arch/powerpc/boot/dts/fsl/interlaken-lac.dtsi +++ /dev/null @@ -1,45 +0,0 @@ -/* - * T4 Interlaken Look-aside Controller (LAC) device tree stub - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -lac: lac@229000 { - compatible = "fsl,interlaken-lac"; - reg = <0x229000 0x1000>; - interrupts = <16 2 1 18>; -}; - -lac-hv@228000 { - compatible = "fsl,interlaken-lac-hv"; - reg = <0x228000 0x1000>; - fsl,non-hv-node = <&lac>; -}; diff --git a/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi b/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi deleted file mode 100644 index 1cf0b77b1efe..000000000000 --- a/arch/powerpc/boot/dts/fsl/pq3-mpic-message-B.dtsi +++ /dev/null @@ -1,43 +0,0 @@ -/* - * PQ3 MPIC Message (Group B) device tree stub [ controller @ offset 0x42400 ] - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -message@42400 { - compatible = "fsl,mpic-v3.1-msgr"; - reg = <0x42400 0x200>; - interrupts = < - 0xb4 2 0 0 - 0xb5 2 0 0 - 0xb6 2 0 0 - 0xb7 2 0 0>; -}; diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi deleted file mode 100644 index 71eb75e82c2e..000000000000 --- a/arch/powerpc/boot/dts/fsl/qoriq-fman3-0-10g-1-best-effort.dtsi +++ /dev/null @@ -1,80 +0,0 @@ -/* - * QorIQ FMan v3 1g port #1 device tree stub [ controller @ offset 0x400000 ] - * - * Copyright 2012 - 2015 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -fman@400000 { - fman0_rx_0x09: port@89000 { - cell-index = <0x9>; - compatible = "fsl,fman-v3-port-rx"; - reg = <0x89000 0x1000>; - fsl,fman-10g-port; - fsl,fman-best-effort-port; - }; - - fman0_tx_0x29: port@a9000 { - cell-index = <0x29>; - compatible = "fsl,fman-v3-port-tx"; - reg = <0xa9000 0x1000>; - fsl,fman-10g-port; - fsl,fman-best-effort-port; - }; - - ethernet@e2000 { - cell-index = <1>; - compatible = "fsl,fman-memac"; - reg = <0xe2000 0x1000>; - fsl,fman-ports = <&fman0_rx_0x09 &fman0_tx_0x29>; - ptp-timer = <&ptp_timer0>; - pcsphy-handle = <&pcsphy1>, <&qsgmiia_pcs1>; - pcs-handle-names = "sgmii", "qsgmii"; - }; - - mdio@e1000 { - qsgmiia_pcs1: ethernet-pcs@1 { - compatible = "fsl,lynx-pcs"; - reg = <1>; - }; - }; - - mdio@e3000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; - reg = <0xe3000 0x1000>; - fsl,erratum-a011043; /* must ignore read errors */ - - pcsphy1: ethernet-phy@0 { - reg = <0x0>; - }; - }; -}; diff --git a/arch/powerpc/boot/dts/mpc8308_p1m.dts b/arch/powerpc/boot/dts/mpc8308_p1m.dts index 2638555afcc4..41f917f97dab 100644 --- a/arch/powerpc/boot/dts/mpc8308_p1m.dts +++ b/arch/powerpc/boot/dts/mpc8308_p1m.dts @@ -37,7 +37,7 @@ PowerPC,8308@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB at 0 }; diff --git a/arch/powerpc/boot/dts/mpc8308rdb.dts b/arch/powerpc/boot/dts/mpc8308rdb.dts index af2ed8380a86..39ed26fba410 100644 --- a/arch/powerpc/boot/dts/mpc8308rdb.dts +++ b/arch/powerpc/boot/dts/mpc8308rdb.dts @@ -38,7 +38,7 @@ PowerPC,8308@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB at 0 }; diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts index 09508b4c8c73..c9fe4dabc80a 100644 --- a/arch/powerpc/boot/dts/mpc8313erdb.dts +++ b/arch/powerpc/boot/dts/mpc8313erdb.dts @@ -6,6 +6,7 @@ */ /dts-v1/; +#include / { model = "MPC8313ERDB"; @@ -38,7 +39,7 @@ PowerPC,8313@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB at 0 }; @@ -48,7 +49,7 @@ localbus@e0005000 { #size-cells = <1>; compatible = "fsl,mpc8313-elbc", "fsl,elbc", "simple-bus"; reg = <0xe0005000 0x1000>; - interrupts = <77 0x8>; + interrupts = <77 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; // CS0 and CS1 are swapped when @@ -118,7 +119,7 @@ i2c@3000 { cell-index = <0>; compatible = "fsl-i2c"; reg = <0x3000 0x100>; - interrupts = <14 0x8>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; dfsrr; rtc@68 { @@ -131,7 +132,7 @@ crypto@30000 { compatible = "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; - interrupts = <11 0x8>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; fsl,num-channels = <1>; fsl,channel-fifo-len = <24>; @@ -146,7 +147,7 @@ i2c@3100 { cell-index = <1>; compatible = "fsl-i2c"; reg = <0x3100 0x100>; - interrupts = <15 0x8>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; dfsrr; }; @@ -155,7 +156,7 @@ spi@7000 { cell-index = <0>; compatible = "fsl,spi"; reg = <0x7000 0x1000>; - interrupts = <16 0x8>; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; mode = "cpu"; }; @@ -167,7 +168,7 @@ usb@23000 { #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&ipic>; - interrupts = <38 0x8>; + interrupts = <38 IRQ_TYPE_LEVEL_LOW>; phy_type = "utmi_wide"; sleep = <&pmc 0x00300000>; }; @@ -175,7 +176,8 @@ usb@23000 { ptp_clock@24E00 { compatible = "fsl,etsec-ptp"; reg = <0x24E00 0xB0>; - interrupts = <12 0x8 13 0x8>; + interrupts = <12 IRQ_TYPE_LEVEL_LOW>, + <13 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = < &ipic >; fsl,tclk-period = <10>; fsl,tmr-prsc = <100>; @@ -197,7 +199,9 @@ enet0: ethernet@24000 { compatible = "gianfar"; reg = <0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <37 0x8 36 0x8 35 0x8>; + interrupts = <37 IRQ_TYPE_LEVEL_LOW>, + <36 IRQ_TYPE_LEVEL_LOW>, + <35 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; tbi-handle = < &tbi0 >; /* Vitesse 7385 isn't on the MDIO bus */ @@ -211,7 +215,7 @@ mdio@520 { reg = <0x520 0x20>; phy4: ethernet-phy@4 { interrupt-parent = <&ipic>; - interrupts = <20 0x8>; + interrupts = <20 IRQ_TYPE_LEVEL_LOW>; reg = <0x4>; }; tbi0: tbi-phy@11 { @@ -231,7 +235,9 @@ enet1: ethernet@25000 { reg = <0x25000 0x1000>; ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <34 0x8 33 0x8 32 0x8>; + interrupts = <34 IRQ_TYPE_LEVEL_LOW>, + <33 IRQ_TYPE_LEVEL_LOW>, + <32 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; tbi-handle = < &tbi1 >; phy-handle = < &phy4 >; @@ -259,7 +265,7 @@ serial0: serial@4500 { compatible = "fsl,ns16550", "ns16550"; reg = <0x4500 0x100>; clock-frequency = <0>; - interrupts = <9 0x8>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; @@ -269,15 +275,12 @@ serial1: serial@4600 { compatible = "fsl,ns16550", "ns16550"; reg = <0x4600 0x100>; clock-frequency = <0>; - interrupts = <10 0x8>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; /* IPIC - * interrupts cell = - * sense values match linux IORESOURCE_IRQ_* defines: - * sense == 8: Level, low assertion - * sense == 2: Edge, high-to-low change + * interrupts cell = */ ipic: pic@700 { interrupt-controller; @@ -290,7 +293,7 @@ ipic: pic@700 { pmc: power@b00 { compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc"; reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 8>; + interrupts = <80 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; fsl,mpc8313-wakeup-timer = <>m1>; @@ -306,14 +309,20 @@ pmc: power@b00 { gtm1: timer@500 { compatible = "fsl,mpc8313-gtm", "fsl,gtm"; reg = <0x500 0x100>; - interrupts = <90 8 78 8 84 8 72 8>; + interrupts = <90 IRQ_TYPE_LEVEL_LOW>, + <78 IRQ_TYPE_LEVEL_LOW>, + <84 IRQ_TYPE_LEVEL_LOW>, + <72 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; timer@600 { compatible = "fsl,mpc8313-gtm", "fsl,gtm"; reg = <0x600 0x100>; - interrupts = <91 8 79 8 85 8 73 8>; + interrupts = <91 IRQ_TYPE_LEVEL_LOW>, + <79 IRQ_TYPE_LEVEL_LOW>, + <85 IRQ_TYPE_LEVEL_LOW>, + <73 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; }; @@ -341,7 +350,7 @@ pci0: pci@e0008500 { 0x7800 0x0 0x0 0x3 &ipic 17 0x8 0x7800 0x0 0x0 0x4 &ipic 18 0x8>; interrupt-parent = <&ipic>; - interrupts = <66 0x8>; + interrupts = <66 IRQ_TYPE_LEVEL_LOW>; bus-range = <0x0 0x0>; ranges = <0x02000000 0x0 0x90000000 0x90000000 0x0 0x10000000 0x42000000 0x0 0x80000000 0x80000000 0x0 0x10000000 @@ -363,14 +372,14 @@ dma@82a8 { reg = <0xe00082a8 4>; ranges = <0 0xe0008100 0x1a8>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; dma-channel@0 { compatible = "fsl,mpc8313-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x28>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; cell-index = <0>; }; @@ -379,7 +388,7 @@ dma-channel@80 { "fsl,elo-dma-channel"; reg = <0x80 0x28>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; cell-index = <1>; }; @@ -388,7 +397,7 @@ dma-channel@100 { "fsl,elo-dma-channel"; reg = <0x100 0x28>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; cell-index = <2>; }; @@ -397,7 +406,7 @@ dma-channel@180 { "fsl,elo-dma-channel"; reg = <0x180 0x28>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; cell-index = <3>; }; }; diff --git a/arch/powerpc/boot/dts/mpc8315erdb.dts b/arch/powerpc/boot/dts/mpc8315erdb.dts index a8f68d6e50b0..7ba1159f8803 100644 --- a/arch/powerpc/boot/dts/mpc8315erdb.dts +++ b/arch/powerpc/boot/dts/mpc8315erdb.dts @@ -40,7 +40,7 @@ PowerPC,8315@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x08000000>; // 128MB at 0 }; @@ -50,7 +50,7 @@ localbus@e0005000 { #size-cells = <1>; compatible = "fsl,mpc8315-elbc", "fsl,elbc", "simple-bus"; reg = <0xe0005000 0x1000>; - interrupts = <77 0x8>; + interrupts = <77 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; // CS0 and CS1 are swapped when @@ -112,7 +112,7 @@ i2c@3000 { cell-index = <0>; compatible = "fsl-i2c"; reg = <0x3000 0x100>; - interrupts = <14 0x8>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; dfsrr; rtc@68 { @@ -133,8 +133,10 @@ spi@7000 { cell-index = <0>; compatible = "fsl,spi"; reg = <0x7000 0x1000>; - interrupts = <16 0x8>; + interrupts = <16 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; + #address-cells = <1>; + #size-cells = <0>; mode = "cpu"; }; @@ -145,35 +147,35 @@ dma@82a8 { reg = <0x82a8 4>; ranges = <0 0x8100 0x1a8>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; cell-index = <0>; dma-channel@0 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0 0x80>; cell-index = <0>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; }; dma-channel@80 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x80 0x80>; cell-index = <1>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; }; dma-channel@100 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x100 0x80>; cell-index = <2>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; }; dma-channel@180 { compatible = "fsl,mpc8315-dma-channel", "fsl,elo-dma-channel"; reg = <0x180 0x28>; cell-index = <3>; interrupt-parent = <&ipic>; - interrupts = <71 8>; + interrupts = <71 IRQ_TYPE_LEVEL_LOW>; }; }; @@ -183,7 +185,7 @@ usb@23000 { #address-cells = <1>; #size-cells = <0>; interrupt-parent = <&ipic>; - interrupts = <38 0x8>; + interrupts = <38 IRQ_TYPE_LEVEL_LOW>; phy_type = "utmi"; }; @@ -197,7 +199,9 @@ enet0: ethernet@24000 { reg = <0x24000 0x1000>; ranges = <0x0 0x24000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <32 0x8 33 0x8 34 0x8>; + interrupts = <32 IRQ_TYPE_LEVEL_LOW>, + <33 IRQ_TYPE_LEVEL_LOW>, + <34 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; tbi-handle = <&tbi0>; phy-handle = < &phy0 >; @@ -238,7 +242,9 @@ enet1: ethernet@25000 { reg = <0x25000 0x1000>; ranges = <0x0 0x25000 0x1000>; local-mac-address = [ 00 00 00 00 00 00 ]; - interrupts = <35 0x8 36 0x8 37 0x8>; + interrupts = <35 IRQ_TYPE_LEVEL_LOW>, + <36 IRQ_TYPE_LEVEL_LOW>, + <37 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; tbi-handle = <&tbi1>; phy-handle = < &phy1 >; @@ -263,7 +269,7 @@ serial0: serial@4500 { compatible = "fsl,ns16550", "ns16550"; reg = <0x4500 0x100>; clock-frequency = <133333333>; - interrupts = <9 0x8>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; @@ -273,7 +279,7 @@ serial1: serial@4600 { compatible = "fsl,ns16550", "ns16550"; reg = <0x4600 0x100>; clock-frequency = <133333333>; - interrupts = <10 0x8>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; @@ -282,7 +288,7 @@ crypto@30000 { "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0"; reg = <0x30000 0x10000>; - interrupts = <11 0x8>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; fsl,num-channels = <4>; fsl,channel-fifo-len = <24>; @@ -294,7 +300,7 @@ sata@18000 { compatible = "fsl,mpc8315-sata", "fsl,pq-sata"; reg = <0x18000 0x1000>; cell-index = <1>; - interrupts = <44 0x8>; + interrupts = <44 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; @@ -302,14 +308,17 @@ sata@19000 { compatible = "fsl,mpc8315-sata", "fsl,pq-sata"; reg = <0x19000 0x1000>; cell-index = <2>; - interrupts = <45 0x8>; + interrupts = <45 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; }; gtm1: timer@500 { compatible = "fsl,mpc8315-gtm", "fsl,gtm"; reg = <0x500 0x100>; - interrupts = <90 8 78 8 84 8 72 8>; + interrupts = <90 IRQ_TYPE_LEVEL_LOW>, + <78 IRQ_TYPE_LEVEL_LOW>, + <84 IRQ_TYPE_LEVEL_LOW>, + <72 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; clock-frequency = <133333333>; }; @@ -317,16 +326,16 @@ gtm1: timer@500 { timer@600 { compatible = "fsl,mpc8315-gtm", "fsl,gtm"; reg = <0x600 0x100>; - interrupts = <91 8 79 8 85 8 73 8>; + interrupts = <91 IRQ_TYPE_LEVEL_LOW>, + <79 IRQ_TYPE_LEVEL_LOW>, + <85 IRQ_TYPE_LEVEL_LOW>, + <73 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; clock-frequency = <133333333>; }; /* IPIC - * interrupts cell = - * sense values match linux IORESOURCE_IRQ_* defines: - * sense == 8: Level, low assertion - * sense == 2: Edge, high-to-low change + * interrupts cell = */ ipic: interrupt-controller@700 { interrupt-controller; @@ -340,14 +349,14 @@ ipic-msi@7c0 { compatible = "fsl,ipic-msi"; reg = <0x7c0 0x40>; msi-available-ranges = <0 0x100>; - interrupts = <0x43 0x8 - 0x4 0x8 - 0x51 0x8 - 0x52 0x8 - 0x56 0x8 - 0x57 0x8 - 0x58 0x8 - 0x59 0x8>; + interrupts = <0x43 IRQ_TYPE_LEVEL_LOW + 0x4 IRQ_TYPE_LEVEL_LOW + 0x51 IRQ_TYPE_LEVEL_LOW + 0x52 IRQ_TYPE_LEVEL_LOW + 0x56 IRQ_TYPE_LEVEL_LOW + 0x57 IRQ_TYPE_LEVEL_LOW + 0x58 IRQ_TYPE_LEVEL_LOW + 0x59 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = < &ipic >; }; @@ -355,7 +364,7 @@ pmc: power@b00 { compatible = "fsl,mpc8315-pmc", "fsl,mpc8313-pmc", "fsl,mpc8349-pmc"; reg = <0xb00 0x100 0xa00 0x100>; - interrupts = <80 8>; + interrupts = <80 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; fsl,mpc8313-wakeup-timer = <>m1>; }; @@ -374,24 +383,24 @@ pci0: pci@e0008500 { interrupt-map-mask = <0xf800 0x0 0x0 0x7>; interrupt-map = < /* IDSEL 0x0E -mini PCI */ - 0x7000 0x0 0x0 0x1 &ipic 18 0x8 - 0x7000 0x0 0x0 0x2 &ipic 18 0x8 - 0x7000 0x0 0x0 0x3 &ipic 18 0x8 - 0x7000 0x0 0x0 0x4 &ipic 18 0x8 + 0x7000 0x0 0x0 0x1 &ipic 18 IRQ_TYPE_LEVEL_LOW + 0x7000 0x0 0x0 0x2 &ipic 18 IRQ_TYPE_LEVEL_LOW + 0x7000 0x0 0x0 0x3 &ipic 18 IRQ_TYPE_LEVEL_LOW + 0x7000 0x0 0x0 0x4 &ipic 18 IRQ_TYPE_LEVEL_LOW /* IDSEL 0x0F -mini PCI */ - 0x7800 0x0 0x0 0x1 &ipic 17 0x8 - 0x7800 0x0 0x0 0x2 &ipic 17 0x8 - 0x7800 0x0 0x0 0x3 &ipic 17 0x8 - 0x7800 0x0 0x0 0x4 &ipic 17 0x8 + 0x7800 0x0 0x0 0x1 &ipic 17 IRQ_TYPE_LEVEL_LOW + 0x7800 0x0 0x0 0x2 &ipic 17 IRQ_TYPE_LEVEL_LOW + 0x7800 0x0 0x0 0x3 &ipic 17 IRQ_TYPE_LEVEL_LOW + 0x7800 0x0 0x0 0x4 &ipic 17 IRQ_TYPE_LEVEL_LOW /* IDSEL 0x10 - PCI slot */ - 0x8000 0x0 0x0 0x1 &ipic 48 0x8 - 0x8000 0x0 0x0 0x2 &ipic 17 0x8 - 0x8000 0x0 0x0 0x3 &ipic 48 0x8 - 0x8000 0x0 0x0 0x4 &ipic 17 0x8>; + 0x8000 0x0 0x0 0x1 &ipic 48 IRQ_TYPE_LEVEL_LOW + 0x8000 0x0 0x0 0x2 &ipic 17 IRQ_TYPE_LEVEL_LOW + 0x8000 0x0 0x0 0x3 &ipic 48 IRQ_TYPE_LEVEL_LOW + 0x8000 0x0 0x0 0x4 &ipic 17 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&ipic>; - interrupts = <66 0x8>; + interrupts = <66 IRQ_TYPE_LEVEL_LOW>; bus-range = <0x0 0x0>; ranges = <0x02000000 0 0x90000000 0x90000000 0 0x10000000 0x42000000 0 0x80000000 0x80000000 0 0x10000000 @@ -417,10 +426,10 @@ pci1: pcie@e0009000 { 0x01000000 0 0x00000000 0xb1000000 0 0x00800000>; bus-range = <0 255>; interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 1 8 - 0 0 0 2 &ipic 1 8 - 0 0 0 3 &ipic 1 8 - 0 0 0 4 &ipic 1 8>; + interrupt-map = <0 0 0 1 &ipic 1 IRQ_TYPE_LEVEL_LOW + 0 0 0 2 &ipic 1 IRQ_TYPE_LEVEL_LOW + 0 0 0 3 &ipic 1 IRQ_TYPE_LEVEL_LOW + 0 0 0 4 &ipic 1 IRQ_TYPE_LEVEL_LOW>; clock-frequency = <0>; pcie@0 { @@ -448,10 +457,10 @@ pci2: pcie@e000a000 { 0x01000000 0 0x00000000 0xd1000000 0 0x00800000>; bus-range = <0 255>; interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = <0 0 0 1 &ipic 2 8 - 0 0 0 2 &ipic 2 8 - 0 0 0 3 &ipic 2 8 - 0 0 0 4 &ipic 2 8>; + interrupt-map = <0 0 0 1 &ipic 2 IRQ_TYPE_LEVEL_LOW + 0 0 0 2 &ipic 2 IRQ_TYPE_LEVEL_LOW + 0 0 0 3 &ipic 2 IRQ_TYPE_LEVEL_LOW + 0 0 0 4 &ipic 2 IRQ_TYPE_LEVEL_LOW>; clock-frequency = <0>; pcie@0 { @@ -471,12 +480,12 @@ pcie@0 { leds { compatible = "gpio-leds"; - pwr { + led-pwr { gpios = <&mcu_pio 0 0>; default-state = "on"; }; - hdd { + led-hdd { gpios = <&mcu_pio 1 0>; linux,default-trigger = "disk-activity"; }; diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts index ba7caaf98fd5..06f134490d95 100644 --- a/arch/powerpc/boot/dts/mpc832x_rdb.dts +++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts @@ -38,7 +38,7 @@ PowerPC,8323@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x04000000>; }; diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts index 13f17232ba83..12d33cb55b72 100644 --- a/arch/powerpc/boot/dts/mpc8349emitx.dts +++ b/arch/powerpc/boot/dts/mpc8349emitx.dts @@ -39,7 +39,7 @@ PowerPC,8349@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x10000000>; }; diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts index eae0afd5abbc..2998a233a790 100644 --- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts +++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts @@ -37,7 +37,7 @@ PowerPC,8349@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x10000000>; }; diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts index f137ccb8cfde..fb311a7eb9f2 100644 --- a/arch/powerpc/boot/dts/mpc8377_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts @@ -39,7 +39,7 @@ PowerPC,8377@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x10000000>; // 256MB at 0 }; diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts index ce254dd74dd0..f736a15cceff 100644 --- a/arch/powerpc/boot/dts/mpc8377_wlan.dts +++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts @@ -40,7 +40,7 @@ PowerPC,8377@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x20000000>; // 512MB at 0 }; diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts index 19e5473d4161..32c49622b404 100644 --- a/arch/powerpc/boot/dts/mpc8378_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts @@ -39,7 +39,7 @@ PowerPC,8378@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x10000000>; // 256MB at 0 }; diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts index 61519acca228..07deb89c5a9b 100644 --- a/arch/powerpc/boot/dts/mpc8379_rdb.dts +++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts @@ -37,7 +37,7 @@ PowerPC,8379@0 { }; }; - memory { + memory@0 { device_type = "memory"; reg = <0x00000000 0x10000000>; // 256MB at 0 }; diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h index 2d71e4b7cd09..496ecc65ac25 100644 --- a/arch/powerpc/include/asm/nohash/32/pgtable.h +++ b/arch/powerpc/include/asm/nohash/32/pgtable.h @@ -120,10 +120,8 @@ #if defined(CONFIG_44x) #include -#elif defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT) -#include #elif defined(CONFIG_PPC_85xx) -#include +#include #elif defined(CONFIG_PPC_8xx) #include #endif diff --git a/arch/powerpc/include/asm/nohash/32/pte-85xx.h b/arch/powerpc/include/asm/nohash/32/pte-85xx.h deleted file mode 100644 index 14d64b4f3f14..000000000000 --- a/arch/powerpc/include/asm/nohash/32/pte-85xx.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ASM_POWERPC_NOHASH_32_PTE_85xx_H -#define _ASM_POWERPC_NOHASH_32_PTE_85xx_H -#ifdef __KERNEL__ - -/* PTE bit definitions for Freescale BookE SW loaded TLB MMU based - * processors - * - MMU Assist Register 3: - - 32 33 34 35 36 ... 50 51 52 53 54 55 56 57 58 59 60 61 62 63 - RPN...................... 0 0 U0 U1 U2 U3 UX SX UW SW UR SR - - - PRESENT *must* be in the bottom two bits because swap PTEs use - the top 30 bits. - -*/ - -/* Definitions for FSL Book-E Cores */ -#define _PAGE_READ 0x00001 /* H: Read permission (SR) */ -#define _PAGE_PRESENT 0x00002 /* S: PTE contains a translation */ -#define _PAGE_WRITE 0x00004 /* S: Write permission (SW) */ -#define _PAGE_DIRTY 0x00008 /* S: Page dirty */ -#define _PAGE_EXEC 0x00010 /* H: SX permission */ -#define _PAGE_ACCESSED 0x00020 /* S: Page referenced */ - -#define _PAGE_ENDIAN 0x00040 /* H: E bit */ -#define _PAGE_GUARDED 0x00080 /* H: G bit */ -#define _PAGE_COHERENT 0x00100 /* H: M bit */ -#define _PAGE_NO_CACHE 0x00200 /* H: I bit */ -#define _PAGE_WRITETHRU 0x00400 /* H: W bit */ -#define _PAGE_SPECIAL 0x00800 /* S: Special page */ - -#define _PMD_PRESENT 0 -#define _PMD_PRESENT_MASK (PAGE_MASK) -#define _PMD_BAD (~PAGE_MASK) -#define _PMD_USER 0 - -#define _PTE_NONE_MASK 0 - -#define PTE_WIMGE_SHIFT (6) - -/* - * We define 2 sets of base prot bits, one for basic pages (ie, - * cacheable kernel and user pages) and one for non cacheable - * pages. We always set _PAGE_COHERENT when SMP is enabled or - * the processor might need it for DMA coherency. - */ -#define _PAGE_BASE_NC (_PAGE_PRESENT | _PAGE_ACCESSED) -#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC) -#define _PAGE_BASE (_PAGE_BASE_NC | _PAGE_COHERENT) -#else -#define _PAGE_BASE (_PAGE_BASE_NC) -#endif - -#include - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_NOHASH_32_PTE_FSL_85xx_H */ diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h index f3086e39e7d2..e8dec885b6e4 100644 --- a/arch/powerpc/include/asm/pgtable-types.h +++ b/arch/powerpc/include/asm/pgtable-types.h @@ -49,7 +49,7 @@ static inline unsigned long pud_val(pud_t x) #endif /* CONFIG_PPC64 */ /* PGD level */ -#if defined(CONFIG_PPC_85xx) && defined(CONFIG_PTE_64BIT) +#if defined(CONFIG_PPC_85xx) typedef struct { unsigned long long pgd; } pgd_t; static inline unsigned long long pgd_val(pgd_t x) diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index ba1d878c3f40..17e63244e885 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -15,6 +15,9 @@ #define TASK_SIZE_MAX TASK_SIZE_USER64 #endif +/* Threshold above which VMX copy path is used */ +#define VMX_COPY_THRESHOLD 3328 + #include /* @@ -255,7 +258,7 @@ __gus_failed: \ ".section .fixup,\"ax\"\n" \ "4: li %0,%3\n" \ " li %1,0\n" \ - " li %1+1,0\n" \ + " li %L1,0\n" \ " b 3b\n" \ ".previous\n" \ EX_TABLE(1b, 4b) \ @@ -326,40 +329,62 @@ do { \ extern unsigned long __copy_tofrom_user(void __user *to, const void __user *from, unsigned long size); -#ifdef __powerpc64__ +unsigned long __copy_tofrom_user_base(void __user *to, + const void __user *from, unsigned long size); + +unsigned long __copy_tofrom_user_power7_vmx(void __user *to, + const void __user *from, unsigned long size); + +static __always_inline bool will_use_vmx(unsigned long n) +{ + return IS_ENABLED(CONFIG_ALTIVEC) && cpu_has_feature(CPU_FTR_VMX_COPY) && + n > VMX_COPY_THRESHOLD; +} + +static __always_inline unsigned long +raw_copy_tofrom_user(void __user *to, const void __user *from, + unsigned long n, unsigned long dir) +{ + unsigned long ret; + + if (will_use_vmx(n) && enter_vmx_usercopy()) { + allow_user_access(to, dir); + ret = __copy_tofrom_user_power7_vmx(to, from, n); + prevent_user_access(dir); + exit_vmx_usercopy(); + + if (unlikely(ret)) { + allow_user_access(to, dir); + ret = __copy_tofrom_user_base(to, from, n); + prevent_user_access(dir); + } + return ret; + } + + allow_user_access(to, dir); + ret = __copy_tofrom_user(to, from, n); + prevent_user_access(dir); + return ret; +} + +#ifdef CONFIG_PPC64 static inline unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) { - unsigned long ret; - barrier_nospec(); - allow_user_access(to, KUAP_READ_WRITE); - ret = __copy_tofrom_user(to, from, n); - prevent_user_access(KUAP_READ_WRITE); - return ret; + return raw_copy_tofrom_user(to, from, n, KUAP_READ_WRITE); } -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ -static inline unsigned long raw_copy_from_user(void *to, - const void __user *from, unsigned long n) +static inline unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n) { - unsigned long ret; - - allow_user_access(NULL, KUAP_READ); - ret = __copy_tofrom_user((__force void __user *)to, from, n); - prevent_user_access(KUAP_READ); - return ret; + return raw_copy_tofrom_user((__force void __user *)to, from, n, KUAP_READ); } static inline unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n) { - unsigned long ret; - - allow_user_access(to, KUAP_WRITE); - ret = __copy_tofrom_user(to, (__force const void __user *)from, n); - prevent_user_access(KUAP_WRITE); - return ret; + return raw_copy_tofrom_user(to, (__force const void __user *)from, n, KUAP_WRITE); } unsigned long __arch_clear_user(void __user *addr, unsigned long size); diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 0fcc463b02e2..90d51d9b3ed2 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -157,7 +157,7 @@ static struct cache *new_cache(int type, int level, { struct cache *cache; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (cache) cache_init(cache, type, level, ofnode, group_id); @@ -540,7 +540,7 @@ static struct cache_dir *cacheinfo_create_cache_dir(unsigned int cpu_id) if (!kobj) goto err; - cache_dir = kzalloc(sizeof(*cache_dir), GFP_KERNEL); + cache_dir = kzalloc_obj(*cache_dir); if (!cache_dir) goto err; @@ -788,7 +788,7 @@ static void cacheinfo_create_index_dir(struct cache *cache, int index, struct cache_index_dir *index_dir; int rc; - index_dir = kzalloc(sizeof(*index_dir), GFP_KERNEL); + index_dir = kzalloc_obj(*index_dir); if (!index_dir) return; diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index 2f9dbf8ad2ee..57e5382f790a 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -138,7 +138,7 @@ eeh_addr_cache_insert(struct pci_dev *dev, resource_size_t alo, return piar; } } - piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC); + piar = kzalloc_obj(struct pci_io_addr_range, GFP_ATOMIC); if (!piar) return NULL; diff --git a/arch/powerpc/kernel/eeh_event.c b/arch/powerpc/kernel/eeh_event.c index c23a454af08a..279c1ceccd6d 100644 --- a/arch/powerpc/kernel/eeh_event.c +++ b/arch/powerpc/kernel/eeh_event.c @@ -104,7 +104,7 @@ int __eeh_send_failure_event(struct eeh_pe *pe) unsigned long flags; struct eeh_event *event; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) { pr_err("EEH: out of memory, event not handled\n"); return -ENOMEM; diff --git a/arch/powerpc/kernel/head_85xx.S b/arch/powerpc/kernel/head_85xx.S index f9a73fae6464..8867596d35ad 100644 --- a/arch/powerpc/kernel/head_85xx.S +++ b/arch/powerpc/kernel/head_85xx.S @@ -305,7 +305,6 @@ set_ivor: * r12 is pointer to the pte * r10 is the pshift from the PGD, if we're a hugepage */ -#ifdef CONFIG_PTE_64BIT #ifdef CONFIG_HUGETLB_PAGE #define FIND_PTE \ rlwinm r12, r13, 14, 18, 28; /* Compute pgdir/pmd offset */ \ @@ -329,15 +328,6 @@ set_ivor: rlwimi r12, r13, 23, 20, 28; /* Compute pte address */ \ lwz r11, 4(r12); /* Get pte entry */ #endif /* HUGEPAGE */ -#else /* !PTE_64BIT */ -#define FIND_PTE \ - rlwimi r11, r13, 12, 20, 29; /* Create L1 (pgdir/pmd) address */ \ - lwz r11, 0(r11); /* Get L1 entry */ \ - rlwinm. r12, r11, 0, 0, 19; /* Extract L2 (pte) base address */ \ - beq 2f; /* Bail if no table */ \ - rlwimi r12, r13, 22, 20, 29; /* Compute PTE address */ \ - lwz r11, 0(r12); /* Get Linux PTE */ -#endif /* * Interrupt vector entry code @@ -473,21 +463,15 @@ END_BTB_FLUSH_SECTION 4: FIND_PTE -#ifdef CONFIG_PTE_64BIT li r13,_PAGE_PRESENT|_PAGE_BAP_SR oris r13,r13,_PAGE_ACCESSED@h -#else - li r13,_PAGE_PRESENT|_PAGE_READ|_PAGE_ACCESSED -#endif andc. r13,r13,r11 /* Check permission */ -#ifdef CONFIG_PTE_64BIT #ifdef CONFIG_SMP subf r13,r11,r12 /* create false data dep */ lwzx r13,r11,r13 /* Get upper pte bits */ #else lwz r13,0(r12) /* Get upper pte bits */ -#endif #endif bne 2f /* Bail if permission/valid mismatch */ @@ -552,12 +536,8 @@ END_BTB_FLUSH_SECTION FIND_PTE /* Make up the required permissions for kernel code */ -#ifdef CONFIG_PTE_64BIT li r13,_PAGE_PRESENT | _PAGE_BAP_SX oris r13,r13,_PAGE_ACCESSED@h -#else - li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -#endif b 4f /* Get the PGD for the current thread */ @@ -573,23 +553,17 @@ END_BTB_FLUSH_SECTION FIND_PTE /* Make up the required permissions for user code */ -#ifdef CONFIG_PTE_64BIT li r13,_PAGE_PRESENT | _PAGE_BAP_UX oris r13,r13,_PAGE_ACCESSED@h -#else - li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC -#endif 4: andc. r13,r13,r11 /* Check permission */ -#ifdef CONFIG_PTE_64BIT #ifdef CONFIG_SMP subf r13,r11,r12 /* create false data dep */ lwzx r13,r11,r13 /* Get upper pte bits */ #else lwz r13,0(r12) /* Get upper pte bits */ -#endif #endif bne 2f /* Bail if permission mismatch */ @@ -683,7 +657,7 @@ interrupt_end: * r10 - tsize encoding (if HUGETLB_PAGE) or available to use * r11 - TLB (info from Linux PTE) * r12 - available to use - * r13 - upper bits of PTE (if PTE_64BIT) or available to use + * r13 - upper bits of PTE * CR5 - results of addr >= PAGE_OFFSET * MAS0, MAS1 - loaded with proper value when we get here * MAS2, MAS3 - will need additional info from Linux PTE @@ -751,7 +725,6 @@ finish_tlb_load: * here we (properly should) assume have the appropriate value. */ finish_tlb_load_cont: -#ifdef CONFIG_PTE_64BIT rlwinm r12, r11, 32-2, 26, 31 /* Move in perm bits */ andi. r10, r11, _PAGE_DIRTY bne 1f @@ -764,26 +737,9 @@ BEGIN_MMU_FTR_SECTION srwi r10, r13, 12 /* grab RPN[12:31] */ mtspr SPRN_MAS7, r10 END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS) -#else - li r10, (_PAGE_EXEC | _PAGE_READ) - mr r13, r11 - rlwimi r10, r11, 31, 29, 29 /* extract _PAGE_DIRTY into SW */ - and r12, r11, r10 - mcrf cr0, cr5 /* Test for user page */ - slwi r10, r12, 1 - or r10, r10, r12 - rlwinm r10, r10, 0, ~_PAGE_EXEC /* Clear SX on user pages */ - isellt r12, r10, r12 - rlwimi r13, r12, 0, 20, 31 /* Get RPN from PTE, merge w/ perms */ - mtspr SPRN_MAS3, r13 -#endif mfspr r12, SPRN_MAS2 -#ifdef CONFIG_PTE_64BIT rlwimi r12, r11, 32-19, 27, 31 /* extract WIMGE from pte */ -#else - rlwimi r12, r11, 26, 27, 31 /* extract WIMGE from pte */ -#endif #ifdef CONFIG_HUGETLB_PAGE beq 6, 3f /* don't mask if page isn't huge */ li r13, 1 diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 0ce71310b7d9..d122e8447831 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1159,7 +1159,7 @@ spapr_tce_platform_iommu_attach_dev(struct iommu_domain *platform_domain, struct device *dev, struct iommu_domain *old) { - struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + struct iommu_domain *domain = iommu_driver_get_domain_for_dev(dev); struct iommu_table_group *table_group; struct iommu_group *grp; diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index f9c6568a9137..42b29324287c 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -890,7 +890,7 @@ loff_t __init nvram_create_partition(const char *name, int sig, return -ENOSPC; /* Create our OS partition */ - new_part = kzalloc(sizeof(*new_part), GFP_KERNEL); + new_part = kzalloc_obj(*new_part); if (!new_part) { pr_err("%s: kmalloc failed\n", __func__); return -ENOMEM; @@ -1030,7 +1030,7 @@ int __init nvram_scan_partitions(void) "detected: 0-length partition\n"); goto out; } - tmp_part = kmalloc(sizeof(*tmp_part), GFP_KERNEL); + tmp_part = kmalloc_obj(*tmp_part); err = -ENOMEM; if (!tmp_part) { printk(KERN_ERR "nvram_scan_partitions: kmalloc failed\n"); diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index eac84d687b53..a7a2fb605971 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -125,7 +125,7 @@ struct pci_controller *pcibios_alloc_controller(struct device_node *dev) { struct pci_controller *phb; - phb = kzalloc(sizeof(struct pci_controller), GFP_KERNEL); + phb = kzalloc_obj(struct pci_controller); if (phb == NULL) return NULL; @@ -432,7 +432,7 @@ static int pci_read_irq_line(struct pci_dev *pci_dev) struct pci_intx_virq *vi, *vitmp; /* Preallocate vi as rewind is complex if this fails after mapping */ - vi = kzalloc(sizeof(struct pci_intx_virq), GFP_KERNEL); + vi = kzalloc_obj(struct pci_intx_virq); if (!vi) return -1; @@ -1368,7 +1368,7 @@ static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) if (!(hose->io_resource.flags & IORESOURCE_IO)) goto no_io; offset = (unsigned long)hose->io_base_virt - _IO_BASE; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); BUG_ON(res == NULL); res->name = "Legacy IO"; res->flags = IORESOURCE_IO; @@ -1396,7 +1396,7 @@ static void __init pcibios_reserve_legacy_regions(struct pci_bus *bus) } if (i >= 3) return; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); BUG_ON(res == NULL); res->name = "Legacy VGA memory"; res->flags = IORESOURCE_MEM; diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c index 38561d6a2079..a7b664befed2 100644 --- a/arch/powerpc/kernel/pci_dn.c +++ b/arch/powerpc/kernel/pci_dn.c @@ -130,7 +130,7 @@ static struct eeh_dev *eeh_dev_init(struct pci_dn *pdn) struct eeh_dev *edev; /* Allocate EEH device */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) return NULL; @@ -154,7 +154,7 @@ static struct pci_dn *add_one_sriov_vf_pdn(struct pci_dn *parent, if (!parent) return NULL; - pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + pdn = kzalloc_obj(*pdn); if (!pdn) return NULL; @@ -290,7 +290,7 @@ struct pci_dn *pci_add_device_node_info(struct pci_controller *hose, struct eeh_dev *edev; #endif - pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + pdn = kzalloc_obj(*pdn); if (pdn == NULL) return NULL; dn->data = pdn; diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 756043dd06e9..fb9fbf0d1796 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -212,6 +212,13 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->error_state = pci_channel_io_normal; dev->dma_mask = 0xffffffff; + /* + * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit + * if MSI (rather than MSI-X) capability does not have + * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver. + */ + dev->msi_addr_mask = DMA_BIT_MASK(64); + /* Early fixups, before probing the BARs */ pci_fixup_device(pci_fixup_early, dev); diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 827c958677f8..f26e80cbc615 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -2893,7 +2893,8 @@ static void __init fixup_device_tree_pmac(void) for (node = 0; prom_next_node(&node); ) { type[0] = '\0'; prom_getprop(node, "device_type", type, sizeof(type)); - if (prom_strcmp(type, "escc") && prom_strcmp(type, "i2s")) + if (prom_strcmp(type, "escc") && prom_strcmp(type, "i2s") && + prom_strcmp(type, "media-bay")) continue; if (prom_getproplen(node, "#size-cells") != PROM_ERROR) diff --git a/arch/powerpc/kernel/secvar-sysfs.c b/arch/powerpc/kernel/secvar-sysfs.c index 4111b21962eb..395399bbab2c 100644 --- a/arch/powerpc/kernel/secvar-sysfs.c +++ b/arch/powerpc/kernel/secvar-sysfs.c @@ -151,7 +151,7 @@ static __init int add_var(const char *name) struct kobject *kobj; int rc; - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + kobj = kzalloc_obj(*kobj); if (!kobj) return -ENOMEM; diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index cb5b73adc250..b1761909c23f 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -995,15 +994,6 @@ void __init setup_arch(char **cmdline_p) initmem_init(); - /* - * Reserve large chunks of memory for use by CMA for kdump, fadump, KVM and - * hugetlb. These must be called after initmem_init(), so that - * pageblock_order is initialised. - */ - fadump_cma_init(); - kdump_cma_reserve(); - kvm_cma_reserve(); - early_memtest(min_low_pfn << PAGE_SHIFT, max_low_pfn << PAGE_SHIFT); if (ppc_md.setup_arch) diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c index 21c39355b25e..e6377ff08be9 100644 --- a/arch/powerpc/kernel/smp-tbsync.c +++ b/arch/powerpc/kernel/smp-tbsync.c @@ -117,7 +117,7 @@ void smp_generic_give_timebase(void) pr_debug("Software timebase sync\n"); /* if this fails then this kernel won't work anyway... */ - tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL ); + tbsync = kzalloc_obj(*tbsync); mb(); running = 1; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index cad3358fa4c3..3467f86fd78f 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -1172,7 +1172,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) * Assumption: if boot_cpuid doesn't have a chip-id, then no * other CPUs, will also not have chip-id. */ - chip_id_lookup_table = kcalloc(idx, sizeof(int), GFP_KERNEL); + chip_id_lookup_table = kzalloc_objs(int, idx); if (chip_id_lookup_table) memset(chip_id_lookup_table, -1, sizeof(int) * idx); } diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 841d077e2825..1b2f293e7dcb 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -37,11 +37,29 @@ unsigned long ftrace_call_adjust(unsigned long addr) if (addr >= (unsigned long)__exittext_begin && addr < (unsigned long)__exittext_end) return 0; - if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY) && - !IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { - addr += MCOUNT_INSN_SIZE; - if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS)) + if (IS_ENABLED(CONFIG_ARCH_USING_PATCHABLE_FUNCTION_ENTRY)) { + if (!IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { addr += MCOUNT_INSN_SIZE; + if (IS_ENABLED(CONFIG_DYNAMIC_FTRACE_WITH_CALL_OPS)) + addr += MCOUNT_INSN_SIZE; + } else if (IS_ENABLED(CONFIG_CC_IS_CLANG) && IS_ENABLED(CONFIG_PPC64)) { + /* + * addr points to global entry point though the NOP was emitted at local + * entry point due to https://github.com/llvm/llvm-project/issues/163706 + * Handle that here with ppc_function_entry() for kernel symbols while + * adjusting module addresses in the else case, by looking for the below + * module global entry point sequence: + * ld r2, -8(r12) + * add r2, r2, r12 + */ + if (is_kernel_text(addr) || is_kernel_inittext(addr)) + addr = ppc_function_entry((void *)addr); + else if ((ppc_inst_val(ppc_inst_read((u32 *)addr)) == + PPC_RAW_LD(_R2, _R12, -8)) && + (ppc_inst_val(ppc_inst_read((u32 *)(addr+4))) == + PPC_RAW_ADD(_R2, _R2, _R12))) + addr += 8; + } } return addr; diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index ab7c4cc80943..d3ef251048c9 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -245,7 +245,7 @@ static struct page ** __init vdso_setup_pages(void *start, void *end) struct page **pagelist; int pages = (end - start) >> PAGE_SHIFT; - pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + pagelist = kzalloc_objs(struct page *, pages + 1); if (!pagelist) panic("%s: Cannot allocate page list for VDSO", __func__); diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index 15850296c0a9..8fc11d6565bf 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -397,6 +397,7 @@ SECTIONS _end = . ; DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c index 104c05520bf0..dc44f11be353 100644 --- a/arch/powerpc/kexec/core.c +++ b/arch/powerpc/kexec/core.c @@ -23,6 +23,7 @@ #include #define cpu_to_be_ulong __PASTE(cpu_to_be, BITS_PER_LONG) +#define __be_word __PASTE(__be, BITS_PER_LONG) #ifdef CONFIG_CRASH_DUMP void machine_crash_shutdown(struct pt_regs *regs) @@ -146,25 +147,25 @@ int __init overlaps_crashkernel(unsigned long start, unsigned long size) } /* Values we need to export to the second kernel via the device tree. */ -static phys_addr_t crashk_base; -static phys_addr_t crashk_size; -static unsigned long long mem_limit; +static __be_word crashk_base; +static __be_word crashk_size; +static __be_word mem_limit; static struct property crashk_base_prop = { .name = "linux,crashkernel-base", - .length = sizeof(phys_addr_t), + .length = sizeof(__be_word), .value = &crashk_base }; static struct property crashk_size_prop = { .name = "linux,crashkernel-size", - .length = sizeof(phys_addr_t), + .length = sizeof(__be_word), .value = &crashk_size, }; static struct property memory_limit_prop = { .name = "linux,memory-limit", - .length = sizeof(unsigned long long), + .length = sizeof(__be_word), .value = &mem_limit, }; @@ -193,11 +194,11 @@ static void __init export_crashk_values(struct device_node *node) } #endif /* CONFIG_CRASH_RESERVE */ -static phys_addr_t kernel_end; +static __be_word kernel_end; static struct property kernel_end_prop = { .name = "linux,kernel-end", - .length = sizeof(phys_addr_t), + .length = sizeof(__be_word), .value = &kernel_end, }; diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index e7ef8b2a2554..5f6d50e4c3d4 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -450,6 +450,11 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf) kbuf->buffer = headers; kbuf->mem = KEXEC_BUF_MEM_UNKNOWN; kbuf->bufsz = headers_sz; + + /* + * Account for extra space required to accommodate additional memory + * ranges in elfcorehdr due to memory hotplug events. + */ kbuf->memsz = headers_sz + kdump_extra_elfcorehdr_size(cmem); kbuf->top_down = false; @@ -460,7 +465,14 @@ static int load_elfcorehdr_segment(struct kimage *image, struct kexec_buf *kbuf) } image->elf_load_addr = kbuf->mem; - image->elf_headers_sz = headers_sz; + + /* + * If CONFIG_CRASH_HOTPLUG is enabled, the elfcorehdr kexec segment + * memsz can be larger than bufsz. Always initialize elf_headers_sz + * with memsz. This ensures the correct size is reserved for elfcorehdr + * memory in the FDT prepared for kdump. + */ + image->elf_headers_sz = kbuf->memsz; image->elf_headers = headers; out: kfree(cmem); diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index c9a2d50ff1b0..9a0d1c1aca6c 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -38,7 +38,6 @@ config KVM_BOOK3S_64_HANDLER config KVM_BOOK3S_PR_POSSIBLE bool select KVM_MMIO - select KVM_GENERIC_MMU_NOTIFIER config KVM_BOOK3S_HV_POSSIBLE bool @@ -81,7 +80,6 @@ config KVM_BOOK3S_64_HV tristate "KVM for POWER7 and later using hypervisor mode in host" depends on KVM_BOOK3S_64 && PPC_POWERNV select KVM_BOOK3S_HV_POSSIBLE - select KVM_GENERIC_MMU_NOTIFIER select KVM_BOOK3S_HV_PMU select CMA help @@ -203,7 +201,6 @@ config KVM_E500V2 depends on !CONTEXT_TRACKING_USER select KVM select KVM_MMIO - select KVM_GENERIC_MMU_NOTIFIER help Support running unmodified E500 guest kernels in virtual machines on E500v2 host processors. @@ -220,7 +217,6 @@ config KVM_E500MC select KVM select KVM_MMIO select KVM_BOOKE_HV - select KVM_GENERIC_MMU_NOTIFIER help Support running unmodified E500MC/E5500/E6500 guest kernels in virtual machines on E500MC/E5500/E6500 host processors. diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index d79c5d1098c0..2efbe05caed7 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -38,7 +38,7 @@ /* #define EXIT_DEBUG */ -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_ICOUNTER(VM, num_2M_pages), STATS_DESC_ICOUNTER(VM, num_1G_pages) @@ -53,7 +53,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, sum_exits), STATS_DESC_COUNTER(VCPU, mmio_exits), diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index f305395cf26e..2ccb3d138f46 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c @@ -1494,7 +1494,7 @@ int kvm_vm_ioctl_resize_hpt_prepare(struct kvm *kvm, /* start new resize */ - resize = kzalloc(sizeof(*resize), GFP_KERNEL); + resize = kzalloc_obj(*resize); if (!resize) { ret = -ENOMEM; goto out; @@ -1943,7 +1943,7 @@ int kvm_vm_ioctl_get_htab_fd(struct kvm *kvm, struct kvm_get_htab_fd *ghf) /* reject flags we don't recognize */ if (ghf->flags & ~(KVM_GET_HTAB_BOLTED_ONLY | KVM_GET_HTAB_WRITE)) return -EINVAL; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; kvm_get_kvm(kvm); @@ -1985,7 +1985,7 @@ static int debugfs_htab_open(struct inode *inode, struct file *file) struct kvm *kvm = inode->i_private; struct debugfs_htab_state *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index b3e6e73d6a08..933fc7cb9afc 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -1256,7 +1256,7 @@ static int debugfs_radix_open(struct inode *inode, struct file *file) struct kvm *kvm = inode->i_private; struct debugfs_radix_state *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 742aa58a7c7e..c5f3f5b29d89 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -178,7 +178,7 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd, } rcu_read_unlock(); - stit = kzalloc(sizeof(*stit), GFP_KERNEL); + stit = kzalloc_obj(*stit); if (!stit) { iommu_tce_table_put(tbl); return -ENOMEM; @@ -305,7 +305,7 @@ int kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, return ret; ret = -ENOMEM; - stt = kzalloc(struct_size(stt, pages, npages), GFP_KERNEL | __GFP_NOWARN); + stt = kzalloc_flex(*stt, pages, npages, GFP_KERNEL | __GFP_NOWARN); if (!stt) goto fail_acct; diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 7667563fb9ff..08e5816fdd61 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -2790,7 +2790,7 @@ static struct kvmppc_vcore *kvmppc_vcore_create(struct kvm *kvm, int id) { struct kvmppc_vcore *vcore; - vcore = kzalloc(sizeof(struct kvmppc_vcore), GFP_KERNEL); + vcore = kzalloc_obj(struct kvmppc_vcore); if (vcore == NULL) return NULL; @@ -2842,7 +2842,7 @@ static int debugfs_timings_open(struct inode *inode, struct file *file) struct kvm_vcpu *vcpu = inode->i_private; struct debugfs_timings_state *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; @@ -5637,7 +5637,7 @@ void kvmppc_alloc_host_rm_ops(void) if (kvmppc_host_rm_ops_hv != NULL) return; - ops = kzalloc(sizeof(struct kvmppc_host_rm_ops), GFP_KERNEL); + ops = kzalloc_obj(struct kvmppc_host_rm_ops); if (!ops) return; @@ -5960,7 +5960,7 @@ void kvmppc_free_pimap(struct kvm *kvm) static struct kvmppc_passthru_irqmap *kvmppc_alloc_pimap(void) { - return kzalloc(sizeof(struct kvmppc_passthru_irqmap), GFP_KERNEL); + return kzalloc_obj(struct kvmppc_passthru_irqmap); } static int kvmppc_set_passthru_irq(struct kvm *kvm, int host_irq, int guest_gsi) diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index 5f8c2321cfb5..22e616662255 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -726,7 +726,7 @@ static struct kvm_nested_guest *kvmhv_alloc_nested(struct kvm *kvm, unsigned int struct kvm_nested_guest *gp; long shadow_lpid; - gp = kzalloc(sizeof(*gp), GFP_KERNEL); + gp = kzalloc_obj(*gp); if (!gp) return NULL; gp->l1_host = kvm; @@ -1671,7 +1671,7 @@ static long int __kvmhv_nested_page_fault(struct kvm_vcpu *vcpu, /* 4. Insert the pte into our shadow_pgtable */ - n_rmap = kzalloc(sizeof(*n_rmap), GFP_KERNEL); + n_rmap = kzalloc_obj(*n_rmap); if (!n_rmap) return RESUME_GUEST; /* Let the guest try again */ n_rmap->rmap = (n_gpa & RMAP_NESTED_GPA_MASK) | diff --git a/arch/powerpc/kvm/book3s_hv_uvmem.c b/arch/powerpc/kvm/book3s_hv_uvmem.c index 7cf9310de0ec..5fbb95d90e99 100644 --- a/arch/powerpc/kvm/book3s_hv_uvmem.c +++ b/arch/powerpc/kvm/book3s_hv_uvmem.c @@ -249,7 +249,7 @@ int kvmppc_uvmem_slot_init(struct kvm *kvm, const struct kvm_memory_slot *slot) { struct kvmppc_uvmem_slot *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; p->pfns = vcalloc(slot->npages, sizeof(*p->pfns)); @@ -711,7 +711,7 @@ static struct page *kvmppc_uvmem_get_page(unsigned long gpa, struct kvm *kvm) bitmap_set(kvmppc_uvmem_bitmap, bit, 1); spin_unlock(&kvmppc_uvmem_bitmap_lock); - pvt = kzalloc(sizeof(*pvt), GFP_KERNEL); + pvt = kzalloc_obj(*pvt); if (!pvt) goto out_clear; diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 83bcdc80ce51..2ba2dd26a7ea 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c @@ -1738,8 +1738,7 @@ static int kvmppc_core_vcpu_create_pr(struct kvm_vcpu *vcpu) vcpu->arch.book3s = vcpu_book3s; #ifdef CONFIG_KVM_BOOK3S_32_HANDLER - vcpu->arch.shadow_vcpu = - kzalloc(sizeof(*vcpu->arch.shadow_vcpu), GFP_KERNEL); + vcpu->arch.shadow_vcpu = kzalloc_obj(*vcpu->arch.shadow_vcpu); if (!vcpu->arch.shadow_vcpu) goto free_vcpu3s; #endif diff --git a/arch/powerpc/kvm/book3s_rtas.c b/arch/powerpc/kvm/book3s_rtas.c index 6808bda0dbc1..0507715d0fdd 100644 --- a/arch/powerpc/kvm/book3s_rtas.c +++ b/arch/powerpc/kvm/book3s_rtas.c @@ -183,7 +183,7 @@ static int rtas_token_define(struct kvm *kvm, char *name, u64 token) if (!found) return -ENOENT; - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) return -ENOMEM; diff --git a/arch/powerpc/kvm/book3s_xics.c b/arch/powerpc/kvm/book3s_xics.c index 589a8f257120..74a44fa702b0 100644 --- a/arch/powerpc/kvm/book3s_xics.c +++ b/arch/powerpc/kvm/book3s_xics.c @@ -1037,7 +1037,7 @@ static struct kvmppc_ics *kvmppc_xics_create_ics(struct kvm *kvm, goto out; /* Create the ICS */ - ics = kzalloc(sizeof(struct kvmppc_ics), GFP_KERNEL); + ics = kzalloc_obj(struct kvmppc_ics); if (!ics) goto out; @@ -1069,7 +1069,7 @@ static int kvmppc_xics_create_icp(struct kvm_vcpu *vcpu, unsigned long server_nu if (kvmppc_xics_find_server(vcpu->kvm, server_num)) return -EEXIST; - icp = kzalloc(sizeof(struct kvmppc_icp), GFP_KERNEL); + icp = kzalloc_obj(struct kvmppc_icp); if (!icp) return -ENOMEM; @@ -1388,7 +1388,7 @@ static struct kvmppc_xics *kvmppc_xics_get_device(struct kvm *kvm) struct kvmppc_xics *xics = *kvm_xics_device; if (!xics) { - xics = kzalloc(sizeof(*xics), GFP_KERNEL); + xics = kzalloc_obj(*xics); *kvm_xics_device = xics; } else { memset(xics, 0, sizeof(*xics)); diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 89a1b8c21ab4..1d67237783b7 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c @@ -1924,7 +1924,7 @@ int kvmppc_xive_connect_vcpu(struct kvm_device *dev, if (r) goto bail; - xc = kzalloc(sizeof(*xc), GFP_KERNEL); + xc = kzalloc_obj(*xc); if (!xc) { r = -ENOMEM; goto bail; @@ -2276,7 +2276,7 @@ struct kvmppc_xive_src_block *kvmppc_xive_create_src_block( goto out; /* Create the ICS */ - sb = kzalloc(sizeof(*sb), GFP_KERNEL); + sb = kzalloc_obj(*sb); if (!sb) goto out; @@ -2719,7 +2719,7 @@ struct kvmppc_xive *kvmppc_xive_get_device(struct kvm *kvm, u32 type) struct kvmppc_xive *xive = *kvm_xive_device; if (!xive) { - xive = kzalloc(sizeof(*xive), GFP_KERNEL); + xive = kzalloc_obj(*xive); *kvm_xive_device = xive; } else { memset(xive, 0, sizeof(*xive)); diff --git a/arch/powerpc/kvm/book3s_xive_native.c b/arch/powerpc/kvm/book3s_xive_native.c index d9bf1bc3ff61..728b5606dd14 100644 --- a/arch/powerpc/kvm/book3s_xive_native.c +++ b/arch/powerpc/kvm/book3s_xive_native.c @@ -145,7 +145,7 @@ int kvmppc_xive_native_connect_vcpu(struct kvm_device *dev, if (rc) goto bail; - xc = kzalloc(sizeof(*xc), GFP_KERNEL); + xc = kzalloc_obj(*xc); if (!xc) { rc = -ENOMEM; goto bail; diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 3401b96be475..f3ddb24ece74 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -36,7 +36,7 @@ unsigned long kvmppc_booke_handlers; -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_ICOUNTER(VM, num_2M_pages), STATS_DESC_ICOUNTER(VM, num_1G_pages) @@ -51,7 +51,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, sum_exits), STATS_DESC_COUNTER(VCPU, mmio_exits), diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index b0f695428733..c58a5a5fb64c 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -119,7 +119,7 @@ static inline void local_sid_destroy_all(void) static void *kvmppc_e500_id_table_alloc(struct kvmppc_vcpu_e500 *vcpu_e500) { - vcpu_e500->idt = kzalloc(sizeof(struct vcpu_id_table), GFP_KERNEL); + vcpu_e500->idt = kzalloc_obj(struct vcpu_id_table); return vcpu_e500->idt; } diff --git a/arch/powerpc/kvm/e500.h b/arch/powerpc/kvm/e500.h index f9acf866c709..e4469ad73a2e 100644 --- a/arch/powerpc/kvm/e500.h +++ b/arch/powerpc/kvm/e500.h @@ -39,15 +39,11 @@ enum vcpu_ftr { /* bits [6-5] MAS2_X1 and MAS2_X0 and [4-0] bits for WIMGE */ #define E500_TLB_MAS2_ATTR (0x7f) -struct tlbe_ref { +struct tlbe_priv { kvm_pfn_t pfn; /* valid only for TLB0, except briefly */ unsigned int flags; /* E500_TLB_* */ }; -struct tlbe_priv { - struct tlbe_ref ref; -}; - #ifdef CONFIG_KVM_E500V2 struct vcpu_id_table; #endif diff --git a/arch/powerpc/kvm/e500_mmu.c b/arch/powerpc/kvm/e500_mmu.c index e131fbecdcc4..75ed1496ead5 100644 --- a/arch/powerpc/kvm/e500_mmu.c +++ b/arch/powerpc/kvm/e500_mmu.c @@ -772,7 +772,7 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, num_pages = DIV_ROUND_UP(cfg->array + array_len - 1, PAGE_SIZE) - cfg->array / PAGE_SIZE; - pages = kmalloc_array(num_pages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, num_pages); if (!pages) return -ENOMEM; @@ -792,13 +792,13 @@ int kvm_vcpu_ioctl_config_tlb(struct kvm_vcpu *vcpu, goto put_pages; } - privs[0] = kcalloc(params.tlb_sizes[0], sizeof(*privs[0]), GFP_KERNEL); + privs[0] = kzalloc_objs(*privs[0], params.tlb_sizes[0]); if (!privs[0]) { ret = -ENOMEM; goto put_pages; } - privs[1] = kcalloc(params.tlb_sizes[1], sizeof(*privs[1]), GFP_KERNEL); + privs[1] = kzalloc_objs(*privs[1], params.tlb_sizes[1]); if (!privs[1]) { ret = -ENOMEM; goto free_privs_first; @@ -912,25 +912,21 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500) vcpu_e500->gtlb_params[1].ways = KVM_E500_TLB1_SIZE; vcpu_e500->gtlb_params[1].sets = 1; - vcpu_e500->gtlb_arch = kmalloc_array(KVM_E500_TLB0_SIZE + - KVM_E500_TLB1_SIZE, - sizeof(*vcpu_e500->gtlb_arch), - GFP_KERNEL); + vcpu_e500->gtlb_arch = kmalloc_objs(*vcpu_e500->gtlb_arch, + KVM_E500_TLB0_SIZE + KVM_E500_TLB1_SIZE); if (!vcpu_e500->gtlb_arch) return -ENOMEM; vcpu_e500->gtlb_offset[0] = 0; vcpu_e500->gtlb_offset[1] = KVM_E500_TLB0_SIZE; - vcpu_e500->gtlb_priv[0] = kcalloc(vcpu_e500->gtlb_params[0].entries, - sizeof(struct tlbe_ref), - GFP_KERNEL); + vcpu_e500->gtlb_priv[0] = kzalloc_objs(struct tlbe_priv, + vcpu_e500->gtlb_params[0].entries); if (!vcpu_e500->gtlb_priv[0]) goto free_vcpu; - vcpu_e500->gtlb_priv[1] = kcalloc(vcpu_e500->gtlb_params[1].entries, - sizeof(struct tlbe_ref), - GFP_KERNEL); + vcpu_e500->gtlb_priv[1] = kzalloc_objs(struct tlbe_priv, + vcpu_e500->gtlb_params[1].entries); if (!vcpu_e500->gtlb_priv[1]) goto free_vcpu; diff --git a/arch/powerpc/kvm/e500_mmu_host.c b/arch/powerpc/kvm/e500_mmu_host.c index 06caf8bbbe2b..37e0d3d9e244 100644 --- a/arch/powerpc/kvm/e500_mmu_host.c +++ b/arch/powerpc/kvm/e500_mmu_host.c @@ -189,16 +189,16 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, { struct kvm_book3e_206_tlb_entry *gtlbe = get_entry(vcpu_e500, tlbsel, esel); - struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[tlbsel][esel].ref; + struct tlbe_priv *tlbe = &vcpu_e500->gtlb_priv[tlbsel][esel]; /* Don't bother with unmapped entries */ - if (!(ref->flags & E500_TLB_VALID)) { - WARN(ref->flags & (E500_TLB_BITMAP | E500_TLB_TLB0), - "%s: flags %x\n", __func__, ref->flags); + if (!(tlbe->flags & E500_TLB_VALID)) { + WARN(tlbe->flags & (E500_TLB_BITMAP | E500_TLB_TLB0), + "%s: flags %x\n", __func__, tlbe->flags); WARN_ON(tlbsel == 1 && vcpu_e500->g2h_tlb1_map[esel]); } - if (tlbsel == 1 && ref->flags & E500_TLB_BITMAP) { + if (tlbsel == 1 && tlbe->flags & E500_TLB_BITMAP) { u64 tmp = vcpu_e500->g2h_tlb1_map[esel]; int hw_tlb_indx; unsigned long flags; @@ -216,28 +216,28 @@ void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel, } mb(); vcpu_e500->g2h_tlb1_map[esel] = 0; - ref->flags &= ~(E500_TLB_BITMAP | E500_TLB_VALID); + tlbe->flags &= ~(E500_TLB_BITMAP | E500_TLB_VALID); local_irq_restore(flags); } - if (tlbsel == 1 && ref->flags & E500_TLB_TLB0) { + if (tlbsel == 1 && tlbe->flags & E500_TLB_TLB0) { /* * TLB1 entry is backed by 4k pages. This should happen * rarely and is not worth optimizing. Invalidate everything. */ kvmppc_e500_tlbil_all(vcpu_e500); - ref->flags &= ~(E500_TLB_TLB0 | E500_TLB_VALID); + tlbe->flags &= ~(E500_TLB_TLB0 | E500_TLB_VALID); } /* * If TLB entry is still valid then it's a TLB0 entry, and thus * backed by at most one host tlbe per shadow pid */ - if (ref->flags & E500_TLB_VALID) + if (tlbe->flags & E500_TLB_VALID) kvmppc_e500_tlbil_one(vcpu_e500, gtlbe); /* Mark the TLB as not backed by the host anymore */ - ref->flags = 0; + tlbe->flags = 0; } static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe) @@ -245,26 +245,26 @@ static inline int tlbe_is_writable(struct kvm_book3e_206_tlb_entry *tlbe) return tlbe->mas7_3 & (MAS3_SW|MAS3_UW); } -static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref, - struct kvm_book3e_206_tlb_entry *gtlbe, - kvm_pfn_t pfn, unsigned int wimg, - bool writable) +static inline void kvmppc_e500_tlbe_setup(struct tlbe_priv *tlbe, + struct kvm_book3e_206_tlb_entry *gtlbe, + kvm_pfn_t pfn, unsigned int wimg, + bool writable) { - ref->pfn = pfn; - ref->flags = E500_TLB_VALID; + tlbe->pfn = pfn; + tlbe->flags = E500_TLB_VALID; if (writable) - ref->flags |= E500_TLB_WRITABLE; + tlbe->flags |= E500_TLB_WRITABLE; /* Use guest supplied MAS2_G and MAS2_E */ - ref->flags |= (gtlbe->mas2 & MAS2_ATTRIB_MASK) | wimg; + tlbe->flags |= (gtlbe->mas2 & MAS2_ATTRIB_MASK) | wimg; } -static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref) +static inline void kvmppc_e500_tlbe_release(struct tlbe_priv *tlbe) { - if (ref->flags & E500_TLB_VALID) { + if (tlbe->flags & E500_TLB_VALID) { /* FIXME: don't log bogus pfn for TLB1 */ - trace_kvm_booke206_ref_release(ref->pfn, ref->flags); - ref->flags = 0; + trace_kvm_booke206_ref_release(tlbe->pfn, tlbe->flags); + tlbe->flags = 0; } } @@ -284,11 +284,8 @@ static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500) int i; for (tlbsel = 0; tlbsel <= 1; tlbsel++) { - for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) { - struct tlbe_ref *ref = - &vcpu_e500->gtlb_priv[tlbsel][i].ref; - kvmppc_e500_ref_release(ref); - } + for (i = 0; i < vcpu_e500->gtlb_params[tlbsel].entries; i++) + kvmppc_e500_tlbe_release(&vcpu_e500->gtlb_priv[tlbsel][i]); } } @@ -304,18 +301,18 @@ void kvmppc_core_flush_tlb(struct kvm_vcpu *vcpu) static void kvmppc_e500_setup_stlbe( struct kvm_vcpu *vcpu, struct kvm_book3e_206_tlb_entry *gtlbe, - int tsize, struct tlbe_ref *ref, u64 gvaddr, + int tsize, struct tlbe_priv *tlbe, u64 gvaddr, struct kvm_book3e_206_tlb_entry *stlbe) { - kvm_pfn_t pfn = ref->pfn; + kvm_pfn_t pfn = tlbe->pfn; u32 pr = vcpu->arch.shared->msr & MSR_PR; - bool writable = !!(ref->flags & E500_TLB_WRITABLE); + bool writable = !!(tlbe->flags & E500_TLB_WRITABLE); - BUG_ON(!(ref->flags & E500_TLB_VALID)); + BUG_ON(!(tlbe->flags & E500_TLB_VALID)); /* Force IPROT=0 for all guest mappings. */ stlbe->mas1 = MAS1_TSIZE(tsize) | get_tlb_sts(gtlbe) | MAS1_VALID; - stlbe->mas2 = (gvaddr & MAS2_EPN) | (ref->flags & E500_TLB_MAS2_ATTR); + stlbe->mas2 = (gvaddr & MAS2_EPN) | (tlbe->flags & E500_TLB_MAS2_ATTR); stlbe->mas7_3 = ((u64)pfn << PAGE_SHIFT) | e500_shadow_mas3_attrib(gtlbe->mas7_3, writable, pr); } @@ -323,7 +320,7 @@ static void kvmppc_e500_setup_stlbe( static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, int tlbsel, struct kvm_book3e_206_tlb_entry *stlbe, - struct tlbe_ref *ref) + struct tlbe_priv *tlbe) { struct kvm_memory_slot *slot; unsigned int psize; @@ -455,9 +452,9 @@ static inline int kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, } } - kvmppc_e500_ref_setup(ref, gtlbe, pfn, wimg, writable); + kvmppc_e500_tlbe_setup(tlbe, gtlbe, pfn, wimg, writable); kvmppc_e500_setup_stlbe(&vcpu_e500->vcpu, gtlbe, tsize, - ref, gvaddr, stlbe); + tlbe, gvaddr, stlbe); writable = tlbe_is_writable(stlbe); /* Clear i-cache for new pages */ @@ -474,17 +471,17 @@ static int kvmppc_e500_tlb0_map(struct kvmppc_vcpu_e500 *vcpu_e500, int esel, struct kvm_book3e_206_tlb_entry *stlbe) { struct kvm_book3e_206_tlb_entry *gtlbe; - struct tlbe_ref *ref; + struct tlbe_priv *tlbe; int stlbsel = 0; int sesel = 0; int r; gtlbe = get_entry(vcpu_e500, 0, esel); - ref = &vcpu_e500->gtlb_priv[0][esel].ref; + tlbe = &vcpu_e500->gtlb_priv[0][esel]; r = kvmppc_e500_shadow_map(vcpu_e500, get_tlb_eaddr(gtlbe), get_tlb_raddr(gtlbe) >> PAGE_SHIFT, - gtlbe, 0, stlbe, ref); + gtlbe, 0, stlbe, tlbe); if (r) return r; @@ -494,7 +491,7 @@ static int kvmppc_e500_tlb0_map(struct kvmppc_vcpu_e500 *vcpu_e500, int esel, } static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500, - struct tlbe_ref *ref, + struct tlbe_priv *tlbe, int esel) { unsigned int sesel = vcpu_e500->host_tlb1_nv++; @@ -507,10 +504,10 @@ static int kvmppc_e500_tlb1_map_tlb1(struct kvmppc_vcpu_e500 *vcpu_e500, vcpu_e500->g2h_tlb1_map[idx] &= ~(1ULL << sesel); } - vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_BITMAP; + vcpu_e500->gtlb_priv[1][esel].flags |= E500_TLB_BITMAP; vcpu_e500->g2h_tlb1_map[esel] |= (u64)1 << sesel; vcpu_e500->h2g_tlb1_rmap[sesel] = esel + 1; - WARN_ON(!(ref->flags & E500_TLB_VALID)); + WARN_ON(!(tlbe->flags & E500_TLB_VALID)); return sesel; } @@ -522,24 +519,24 @@ static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, u64 gvaddr, gfn_t gfn, struct kvm_book3e_206_tlb_entry *gtlbe, struct kvm_book3e_206_tlb_entry *stlbe, int esel) { - struct tlbe_ref *ref = &vcpu_e500->gtlb_priv[1][esel].ref; + struct tlbe_priv *tlbe = &vcpu_e500->gtlb_priv[1][esel]; int sesel; int r; r = kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, stlbe, - ref); + tlbe); if (r) return r; /* Use TLB0 when we can only map a page with 4k */ if (get_tlb_tsize(stlbe) == BOOK3E_PAGESZ_4K) { - vcpu_e500->gtlb_priv[1][esel].ref.flags |= E500_TLB_TLB0; + vcpu_e500->gtlb_priv[1][esel].flags |= E500_TLB_TLB0; write_stlbe(vcpu_e500, gtlbe, stlbe, 0, 0); return 0; } /* Otherwise map into TLB1 */ - sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, ref, esel); + sesel = kvmppc_e500_tlb1_map_tlb1(vcpu_e500, tlbe, esel); write_stlbe(vcpu_e500, gtlbe, stlbe, 1, sesel); return 0; @@ -561,11 +558,11 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr, priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; /* Triggers after clear_tlb_privs or on initial mapping */ - if (!(priv->ref.flags & E500_TLB_VALID)) { + if (!(priv->flags & E500_TLB_VALID)) { kvmppc_e500_tlb0_map(vcpu_e500, esel, &stlbe); } else { kvmppc_e500_setup_stlbe(vcpu, gtlbe, BOOK3E_PAGESZ_4K, - &priv->ref, eaddr, &stlbe); + priv, eaddr, &stlbe); write_stlbe(vcpu_e500, gtlbe, &stlbe, 0, 0); } break; diff --git a/arch/powerpc/kvm/guest-state-buffer.c b/arch/powerpc/kvm/guest-state-buffer.c index 871cf60ddeb6..42843eca6727 100644 --- a/arch/powerpc/kvm/guest-state-buffer.c +++ b/arch/powerpc/kvm/guest-state-buffer.c @@ -28,7 +28,7 @@ struct kvmppc_gs_buff *kvmppc_gsb_new(size_t size, unsigned long guest_id, { struct kvmppc_gs_buff *gsb; - gsb = kzalloc(sizeof(*gsb), flags); + gsb = kzalloc_obj(*gsb, flags); if (!gsb) return NULL; @@ -540,7 +540,7 @@ struct kvmppc_gs_msg *kvmppc_gsm_new(struct kvmppc_gs_msg_ops *ops, void *data, { struct kvmppc_gs_msg *gsm; - gsm = kzalloc(sizeof(*gsm), gfp_flags); + gsm = kzalloc_obj(*gsm, gfp_flags); if (!gsm) return NULL; diff --git a/arch/powerpc/kvm/mpic.c b/arch/powerpc/kvm/mpic.c index 23e9c2bd9f27..3070f36d9fb8 100644 --- a/arch/powerpc/kvm/mpic.c +++ b/arch/powerpc/kvm/mpic.c @@ -1642,7 +1642,7 @@ static int mpic_set_default_irq_routing(struct openpic *opp) struct kvm_irq_routing_entry *routing; /* Create a nop default map, so that dereferencing it still works */ - routing = kzalloc((sizeof(*routing)), GFP_KERNEL); + routing = kzalloc_obj(*routing); if (!routing) return -ENOMEM; @@ -1661,7 +1661,7 @@ static int mpic_create(struct kvm_device *dev, u32 type) if (dev->kvm->arch.mpic) return -EINVAL; - opp = kzalloc(sizeof(struct openpic), GFP_KERNEL); + opp = kzalloc_obj(struct openpic); if (!opp) return -ENOMEM; diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 9a89a6d98f97..00302399fc37 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -623,12 +623,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) r = !!(hv_enabled && kvmppc_hv_ops->enable_nested && !kvmppc_hv_ops->enable_nested(NULL)); break; -#endif - case KVM_CAP_SYNC_MMU: - BUILD_BUG_ON(!IS_ENABLED(CONFIG_KVM_GENERIC_MMU_NOTIFIER)); - r = 1; - break; -#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE case KVM_CAP_PPC_HTAB_FD: r = hv_enabled; break; diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S index 9af969d2cc0c..25a99108caff 100644 --- a/arch/powerpc/lib/copyuser_64.S +++ b/arch/powerpc/lib/copyuser_64.S @@ -562,3 +562,4 @@ exc; std r10,32(3) li r5,4096 b .Ldst_aligned EXPORT_SYMBOL(__copy_tofrom_user) +EXPORT_SYMBOL(__copy_tofrom_user_base) diff --git a/arch/powerpc/lib/copyuser_power7.S b/arch/powerpc/lib/copyuser_power7.S index 8474c682a178..17dbcfbae25f 100644 --- a/arch/powerpc/lib/copyuser_power7.S +++ b/arch/powerpc/lib/copyuser_power7.S @@ -5,13 +5,9 @@ * * Author: Anton Blanchard */ +#include #include -#ifndef SELFTEST_CASE -/* 0 == don't use VMX, 1 == use VMX */ -#define SELFTEST_CASE 0 -#endif - #ifdef __BIG_ENDIAN__ #define LVS(VRT,RA,RB) lvsl VRT,RA,RB #define VPERM(VRT,VRA,VRB,VRC) vperm VRT,VRA,VRB,VRC @@ -47,10 +43,14 @@ ld r15,STK_REG(R15)(r1) ld r14,STK_REG(R14)(r1) .Ldo_err3: - bl CFUNC(exit_vmx_usercopy) + ld r6,STK_REG(R31)(r1) /* original destination pointer */ + ld r5,STK_REG(R29)(r1) /* original number of bytes */ + subf r7,r6,r3 /* #bytes copied */ + subf r3,r7,r5 /* #bytes not copied in r3 */ ld r0,STACKFRAMESIZE+16(r1) mtlr r0 - b .Lexit + addi r1,r1,STACKFRAMESIZE + blr #endif /* CONFIG_ALTIVEC */ .Ldo_err2: @@ -74,7 +74,6 @@ _GLOBAL(__copy_tofrom_user_power7) cmpldi r5,16 - cmpldi cr1,r5,3328 std r3,-STACKFRAMESIZE+STK_REG(R31)(r1) std r4,-STACKFRAMESIZE+STK_REG(R30)(r1) @@ -82,12 +81,6 @@ _GLOBAL(__copy_tofrom_user_power7) blt .Lshort_copy -#ifdef CONFIG_ALTIVEC -test_feature = SELFTEST_CASE -BEGIN_FTR_SECTION - bgt cr1,.Lvmx_copy -END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) -#endif .Lnonvmx_copy: /* Get the source 8B aligned */ @@ -263,23 +256,14 @@ err1; stb r0,0(r3) 15: li r3,0 blr -.Lunwind_stack_nonvmx_copy: - addi r1,r1,STACKFRAMESIZE - b .Lnonvmx_copy - -.Lvmx_copy: #ifdef CONFIG_ALTIVEC +_GLOBAL(__copy_tofrom_user_power7_vmx) mflr r0 std r0,16(r1) stdu r1,-STACKFRAMESIZE(r1) - bl CFUNC(enter_vmx_usercopy) - cmpwi cr1,r3,0 - ld r0,STACKFRAMESIZE+16(r1) - ld r3,STK_REG(R31)(r1) - ld r4,STK_REG(R30)(r1) - ld r5,STK_REG(R29)(r1) - mtlr r0 + std r3,STK_REG(R31)(r1) + std r5,STK_REG(R29)(r1) /* * We prefetch both the source and destination using enhanced touch * instructions. We use a stream ID of 0 for the load side and @@ -300,8 +284,6 @@ err1; stb r0,0(r3) DCBT_SETUP_STREAMS(r6, r7, r9, r10, r8) - beq cr1,.Lunwind_stack_nonvmx_copy - /* * If source and destination are not relatively aligned we use a * slower permute loop. @@ -478,7 +460,8 @@ err3; lbz r0,0(r4) err3; stb r0,0(r3) 15: addi r1,r1,STACKFRAMESIZE - b CFUNC(exit_vmx_usercopy) /* tail call optimise */ + li r3,0 + blr .Lvmx_unaligned_copy: /* Get the destination 16B aligned */ @@ -681,5 +664,7 @@ err3; lbz r0,0(r4) err3; stb r0,0(r3) 15: addi r1,r1,STACKFRAMESIZE - b CFUNC(exit_vmx_usercopy) /* tail call optimise */ + li r3,0 + blr +EXPORT_SYMBOL(__copy_tofrom_user_power7_vmx) #endif /* CONFIG_ALTIVEC */ diff --git a/arch/powerpc/lib/rheap.c b/arch/powerpc/lib/rheap.c index 6aa774aa5b16..d6d72719801b 100644 --- a/arch/powerpc/lib/rheap.c +++ b/arch/powerpc/lib/rheap.c @@ -54,7 +54,7 @@ static int grow(rh_info_t * info, int max_blocks) new_blocks = max_blocks - info->max_blocks; - block = kmalloc_array(max_blocks, sizeof(rh_block_t), GFP_ATOMIC); + block = kmalloc_objs(rh_block_t, max_blocks, GFP_ATOMIC); if (block == NULL) return -ENOMEM; @@ -258,7 +258,7 @@ rh_info_t *rh_create(unsigned int alignment) if ((alignment & (alignment - 1)) != 0) return ERR_PTR(-EINVAL); - info = kmalloc(sizeof(*info), GFP_ATOMIC); + info = kmalloc_obj(*info, GFP_ATOMIC); if (info == NULL) return ERR_PTR(-ENOMEM); diff --git a/arch/powerpc/lib/vmx-helper.c b/arch/powerpc/lib/vmx-helper.c index 54340912398f..554b248002b4 100644 --- a/arch/powerpc/lib/vmx-helper.c +++ b/arch/powerpc/lib/vmx-helper.c @@ -27,6 +27,7 @@ int enter_vmx_usercopy(void) return 1; } +EXPORT_SYMBOL(enter_vmx_usercopy); /* * This function must return 0 because we tail call optimise when calling @@ -49,6 +50,7 @@ int exit_vmx_usercopy(void) set_dec(1); return 0; } +EXPORT_SYMBOL(exit_vmx_usercopy); int enter_vmx_ops(void) { diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c index c0e8d597e4cb..60d00c9e7f19 100644 --- a/arch/powerpc/mm/book3s64/iommu_api.c +++ b/arch/powerpc/mm/book3s64/iommu_api.c @@ -70,7 +70,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, locked_entries = entries; } - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) { ret = -ENOMEM; goto unlock_exit; diff --git a/arch/powerpc/mm/book3s64/mmu_context.c b/arch/powerpc/mm/book3s64/mmu_context.c index fb9dcf9ca599..2fe787e6c2dc 100644 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@ -96,8 +96,7 @@ static int hash__init_new_context(struct mm_struct *mm) { int index; - mm->context.hash_context = kmalloc(sizeof(struct hash_mm_context), - GFP_KERNEL); + mm->context.hash_context = kmalloc_obj(struct hash_mm_context); if (!mm->context.hash_context) return -ENOMEM; @@ -124,8 +123,7 @@ static int hash__init_new_context(struct mm_struct *mm) #ifdef CONFIG_PPC_SUBPAGE_PROT /* inherit subpage prot details if we have one. */ if (current->mm->context.hash_context->spt) { - mm->context.hash_context->spt = kmalloc(sizeof(struct subpage_prot_table), - GFP_KERNEL); + mm->context.hash_context->spt = kmalloc_obj(struct subpage_prot_table); if (!mm->context.hash_context->spt) { kfree(mm->context.hash_context); return -ENOMEM; diff --git a/arch/powerpc/mm/book3s64/subpage_prot.c b/arch/powerpc/mm/book3s64/subpage_prot.c index 07c47673bba2..37d47282c368 100644 --- a/arch/powerpc/mm/book3s64/subpage_prot.c +++ b/arch/powerpc/mm/book3s64/subpage_prot.c @@ -221,7 +221,7 @@ SYSCALL_DEFINE3(subpage_prot, unsigned long, addr, * Allocate subpage prot table if not already done. * Do this with mmap_lock held */ - spt = kzalloc(sizeof(struct subpage_prot_table), GFP_KERNEL); + spt = kzalloc_obj(struct subpage_prot_table); if (!spt) { err = -ENOMEM; goto out; diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index 8dd7b340d51f..f168ff5a2b30 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c @@ -41,7 +41,7 @@ static struct property *clone_property(struct property *prop, u32 prop_sz) { struct property *new_prop; - new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); + new_prop = kzalloc_obj(*new_prop); if (!new_prop) return NULL; @@ -430,8 +430,7 @@ static void __init init_drmem_v1_lmbs(const __be32 *prop) if (drmem_info->n_lmbs == 0) return; - drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb), - GFP_KERNEL); + drmem_info->lmbs = kzalloc_objs(*lmb, drmem_info->n_lmbs); if (!drmem_info->lmbs) return; @@ -458,8 +457,7 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop) drmem_info->n_lmbs += dr_cell.seq_lmbs; } - drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb), - GFP_KERNEL); + drmem_info->lmbs = kzalloc_objs(*lmb, drmem_info->n_lmbs); if (!drmem_info->lmbs) return; diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 29bf347f6012..b7982d0243d4 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -30,6 +30,10 @@ #include #include +#include +#include +#include + #include unsigned long long memory_limit __initdata; @@ -268,6 +272,16 @@ void __init paging_init(void) void __init arch_mm_preinit(void) { + + /* + * Reserve large chunks of memory for use by CMA for kdump, fadump, KVM + * and hugetlb. These must be called after pageblock_order is + * initialised. + */ + fadump_cma_init(); + kdump_cma_reserve(); + kvm_cma_reserve(); + /* * book3s is limited to 16 page sizes due to encoding this in * a 4-bit field for slices. @@ -318,7 +332,7 @@ static int __init add_system_ram_resources(void) for_each_mem_range(i, &start, &end) { struct resource *res; - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); WARN_ON(!res); if (res) { diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index 82bbf63f0e57..7354e1d72f79 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h @@ -81,9 +81,6 @@ #ifdef CONFIG_PPC64 -/* for gpr non volatile registers BPG_REG_6 to 10 */ -#define BPF_PPC_STACK_SAVE (6 * 8) - /* If dummy pass (!image), account for maximum possible instructions */ #define PPC_LI64(d, i) do { \ if (!image) \ @@ -219,8 +216,6 @@ int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass, struct codegen_context *ctx, int insn_idx, int jmp_off, int dst_reg, u32 code); - -int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx); #endif #endif diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index b75dd53584d5..a62a9a92b7b5 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -165,7 +165,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) jit_data = fp->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { fp = org_fp; goto out; @@ -450,7 +450,7 @@ bool bpf_jit_supports_subprog_tailcalls(void) bool bpf_jit_supports_kfunc_call(void) { - return true; + return IS_ENABLED(CONFIG_PPC64); } bool bpf_jit_supports_arena(void) @@ -638,19 +638,12 @@ static int invoke_bpf_mod_ret(u32 *image, u32 *ro_image, struct codegen_context * for the traced function (BPF subprog/callee) to fetch it. */ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_context *ctx, - int func_frame_offset, - int bpf_dummy_frame_size, int r4_off) + int bpf_frame_size, int r4_off) { if (IS_ENABLED(CONFIG_PPC64)) { - /* See Generated stack layout */ - int tailcallinfo_offset = BPF_PPC_TAILCALL; - - /* - * func_frame_offset = ...(1) - * bpf_dummy_frame_size + trampoline_frame_size - */ - EMIT(PPC_RAW_LD(_R4, _R1, func_frame_offset)); - EMIT(PPC_RAW_LD(_R3, _R4, -tailcallinfo_offset)); + EMIT(PPC_RAW_LD(_R4, _R1, bpf_frame_size)); + /* Refer to trampoline's Generated stack layout */ + EMIT(PPC_RAW_LD(_R3, _R4, -BPF_PPC_TAILCALL)); /* * Setting the tail_call_info in trampoline's frame @@ -658,22 +651,14 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_conte */ EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT)); PPC_BCC_CONST_SHORT(COND_GT, 8); - EMIT(PPC_RAW_ADDI(_R3, _R4, bpf_jit_stack_tailcallinfo_offset(ctx))); + EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL)); + /* - * From ...(1) above: - * trampoline_frame_bottom = ...(2) - * func_frame_offset - bpf_dummy_frame_size - * - * Using ...(2) derived above: - * trampoline_tail_call_info_offset = ...(3) - * trampoline_frame_bottom - tailcallinfo_offset - * - * From ...(3): - * Use trampoline_tail_call_info_offset to write reference of main's - * tail_call_info in trampoline frame. + * Trampoline's tail_call_info is at the same offset, as that of + * any bpf program, with reference to previous frame. Update the + * address of main's tail_call_info in trampoline frame. */ - EMIT(PPC_RAW_STL(_R3, _R1, (func_frame_offset - bpf_dummy_frame_size) - - tailcallinfo_offset)); + EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size - BPF_PPC_TAILCALL)); } else { /* See bpf_jit_stack_offsetof() and BPF_PPC_TC */ EMIT(PPC_RAW_LL(_R4, _R1, r4_off)); @@ -681,7 +666,7 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_conte } static void bpf_trampoline_restore_tail_call_cnt(u32 *image, struct codegen_context *ctx, - int func_frame_offset, int r4_off) + int bpf_frame_size, int r4_off) { if (IS_ENABLED(CONFIG_PPC32)) { /* @@ -692,12 +677,12 @@ static void bpf_trampoline_restore_tail_call_cnt(u32 *image, struct codegen_cont } } -static void bpf_trampoline_save_args(u32 *image, struct codegen_context *ctx, int func_frame_offset, - int nr_regs, int regs_off) +static void bpf_trampoline_save_args(u32 *image, struct codegen_context *ctx, + int bpf_frame_size, int nr_regs, int regs_off) { int param_save_area_offset; - param_save_area_offset = func_frame_offset; /* the two frames we alloted */ + param_save_area_offset = bpf_frame_size; param_save_area_offset += STACK_FRAME_MIN_SIZE; /* param save area is past frame header */ for (int i = 0; i < nr_regs; i++) { @@ -720,11 +705,11 @@ static void bpf_trampoline_restore_args_regs(u32 *image, struct codegen_context /* Used when we call into the traced function. Replicate parameter save area */ static void bpf_trampoline_restore_args_stack(u32 *image, struct codegen_context *ctx, - int func_frame_offset, int nr_regs, int regs_off) + int bpf_frame_size, int nr_regs, int regs_off) { int param_save_area_offset; - param_save_area_offset = func_frame_offset; /* the two frames we alloted */ + param_save_area_offset = bpf_frame_size; param_save_area_offset += STACK_FRAME_MIN_SIZE; /* param save area is past frame header */ for (int i = 8; i < nr_regs; i++) { @@ -741,10 +726,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im void *func_addr) { int regs_off, nregs_off, ip_off, run_ctx_off, retval_off, nvr_off, alt_lr_off, r4_off = 0; - int i, ret, nr_regs, bpf_frame_size = 0, bpf_dummy_frame_size = 0, func_frame_offset; struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; + int i, ret, nr_regs, retaddr_off, bpf_frame_size = 0; struct codegen_context codegen_ctx, *ctx; u32 *image = (u32 *)rw_image; ppc_inst_t branch_insn; @@ -770,24 +755,19 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im * Generated stack layout: * * func prev back chain [ back chain ] - * [ ] - * bpf prog redzone/tailcallcnt [ ... ] 64 bytes (64-bit powerpc) - * [ ] -- - * LR save area [ r0 save (64-bit) ] | header - * [ r0 save (32-bit) ] | - * dummy frame for unwind [ back chain 1 ] -- * [ tail_call_info ] optional - 64-bit powerpc * [ padding ] align stack frame * r4_off [ r4 (tailcallcnt) ] optional - 32-bit powerpc * alt_lr_off [ real lr (ool stub)] optional - actual lr + * retaddr_off [ return address ] * [ r26 ] * nvr_off [ r25 ] nvr save area * retval_off [ return value ] * [ reg argN ] * [ ... ] - * regs_off [ reg_arg1 ] prog ctx context - * nregs_off [ args count ] - * ip_off [ traced function ] + * regs_off [ reg_arg1 ] prog_ctx + * nregs_off [ args count ] ((u64 *)prog_ctx)[-1] + * ip_off [ traced function ] ((u64 *)prog_ctx)[-2] * [ ... ] * run_ctx_off [ bpf_tramp_run_ctx ] * [ reg argN ] @@ -843,6 +823,10 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im nvr_off = bpf_frame_size; bpf_frame_size += 2 * SZL; + /* Save area for return address */ + retaddr_off = bpf_frame_size; + bpf_frame_size += SZL; + /* Optional save area for actual LR in case of ool ftrace */ if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { alt_lr_off = bpf_frame_size; @@ -869,16 +853,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im /* Padding to align stack frame, if any */ bpf_frame_size = round_up(bpf_frame_size, SZL * 2); - /* Dummy frame size for proper unwind - includes 64-bytes red zone for 64-bit powerpc */ - bpf_dummy_frame_size = STACK_FRAME_MIN_SIZE + 64; - - /* Offset to the traced function's stack frame */ - func_frame_offset = bpf_dummy_frame_size + bpf_frame_size; - - /* Create dummy frame for unwind, store original return value */ + /* Store original return value */ EMIT(PPC_RAW_STL(_R0, _R1, PPC_LR_STKOFF)); - /* Protect red zone where tail call count goes */ - EMIT(PPC_RAW_STLU(_R1, _R1, -bpf_dummy_frame_size)); /* Create our stack frame */ EMIT(PPC_RAW_STLU(_R1, _R1, -bpf_frame_size)); @@ -893,34 +869,44 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im if (IS_ENABLED(CONFIG_PPC32) && nr_regs < 2) EMIT(PPC_RAW_STL(_R4, _R1, r4_off)); - bpf_trampoline_save_args(image, ctx, func_frame_offset, nr_regs, regs_off); + bpf_trampoline_save_args(image, ctx, bpf_frame_size, nr_regs, regs_off); - /* Save our return address */ + /* Save our LR/return address */ EMIT(PPC_RAW_MFLR(_R3)); if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) EMIT(PPC_RAW_STL(_R3, _R1, alt_lr_off)); else - EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF)); + EMIT(PPC_RAW_STL(_R3, _R1, retaddr_off)); /* - * Save ip address of the traced function. - * We could recover this from LR, but we will need to address for OOL trampoline, - * and optional GEP area. + * Derive IP address of the traced function. + * In case of CONFIG_PPC_FTRACE_OUT_OF_LINE or BPF program, LR points to the instruction + * after the 'bl' instruction in the OOL stub. Refer to ftrace_init_ool_stub() and + * bpf_arch_text_poke() for OOL stub of kernel functions and bpf programs respectively. + * Relevant stub sequence: + * + * bl + * LR (R3) => mtlr r0 + * b + * + * Recover kernel function/bpf program address from the unconditional + * branch instruction at the end of OOL stub. */ if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) || flags & BPF_TRAMP_F_IP_ARG) { EMIT(PPC_RAW_LWZ(_R4, _R3, 4)); EMIT(PPC_RAW_SLWI(_R4, _R4, 6)); EMIT(PPC_RAW_SRAWI(_R4, _R4, 6)); EMIT(PPC_RAW_ADD(_R3, _R3, _R4)); - EMIT(PPC_RAW_ADDI(_R3, _R3, 4)); } if (flags & BPF_TRAMP_F_IP_ARG) EMIT(PPC_RAW_STL(_R3, _R1, ip_off)); - if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) - /* Fake our LR for unwind */ - EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF)); + if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { + /* Fake our LR for BPF_TRAMP_F_CALL_ORIG case */ + EMIT(PPC_RAW_ADDI(_R3, _R3, 4)); + EMIT(PPC_RAW_STL(_R3, _R1, retaddr_off)); + } /* Save function arg count -- see bpf_get_func_arg_cnt() */ EMIT(PPC_RAW_LI(_R3, nr_regs)); @@ -958,20 +944,19 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im /* Call the traced function */ if (flags & BPF_TRAMP_F_CALL_ORIG) { /* - * The address in LR save area points to the correct point in the original function + * retaddr on trampoline stack points to the correct point in the original function * with both PPC_FTRACE_OUT_OF_LINE as well as with traditional ftrace instruction * sequence */ - EMIT(PPC_RAW_LL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF)); + EMIT(PPC_RAW_LL(_R3, _R1, retaddr_off)); EMIT(PPC_RAW_MTCTR(_R3)); /* Replicate tail_call_cnt before calling the original BPF prog */ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) - bpf_trampoline_setup_tail_call_info(image, ctx, func_frame_offset, - bpf_dummy_frame_size, r4_off); + bpf_trampoline_setup_tail_call_info(image, ctx, bpf_frame_size, r4_off); /* Restore args */ - bpf_trampoline_restore_args_stack(image, ctx, func_frame_offset, nr_regs, regs_off); + bpf_trampoline_restore_args_stack(image, ctx, bpf_frame_size, nr_regs, regs_off); /* Restore TOC for 64-bit */ if (IS_ENABLED(CONFIG_PPC64_ELF_ABI_V2) && !IS_ENABLED(CONFIG_PPC_KERNEL_PCREL)) @@ -985,7 +970,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im /* Restore updated tail_call_cnt */ if (flags & BPF_TRAMP_F_TAIL_CALL_CTX) - bpf_trampoline_restore_tail_call_cnt(image, ctx, func_frame_offset, r4_off); + bpf_trampoline_restore_tail_call_cnt(image, ctx, bpf_frame_size, r4_off); /* Reserve space to patch branch instruction to skip fexit progs */ if (ro_image) /* image is NULL for dummy pass */ @@ -1037,7 +1022,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im EMIT(PPC_RAW_LD(_R2, _R1, 24)); if (flags & BPF_TRAMP_F_SKIP_FRAME) { /* Skip the traced function and return to parent */ - EMIT(PPC_RAW_ADDI(_R1, _R1, func_frame_offset)); + EMIT(PPC_RAW_ADDI(_R1, _R1, bpf_frame_size)); EMIT(PPC_RAW_LL(_R0, _R1, PPC_LR_STKOFF)); EMIT(PPC_RAW_MTLR(_R0)); EMIT(PPC_RAW_BLR()); @@ -1045,13 +1030,13 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { EMIT(PPC_RAW_LL(_R0, _R1, alt_lr_off)); EMIT(PPC_RAW_MTLR(_R0)); - EMIT(PPC_RAW_ADDI(_R1, _R1, func_frame_offset)); + EMIT(PPC_RAW_ADDI(_R1, _R1, bpf_frame_size)); EMIT(PPC_RAW_LL(_R0, _R1, PPC_LR_STKOFF)); EMIT(PPC_RAW_BLR()); } else { - EMIT(PPC_RAW_LL(_R0, _R1, bpf_frame_size + PPC_LR_STKOFF)); + EMIT(PPC_RAW_LL(_R0, _R1, retaddr_off)); EMIT(PPC_RAW_MTCTR(_R0)); - EMIT(PPC_RAW_ADDI(_R1, _R1, func_frame_offset)); + EMIT(PPC_RAW_ADDI(_R1, _R1, bpf_frame_size)); EMIT(PPC_RAW_LL(_R0, _R1, PPC_LR_STKOFF)); EMIT(PPC_RAW_MTLR(_R0)); EMIT(PPC_RAW_BCTR()); diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index b1a3945ccc9f..c5e26d231cd5 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c @@ -32,23 +32,27 @@ * * [ prev sp ] <------------- * [ tail_call_info ] 8 | - * [ nv gpr save area ] 6*8 + (12*8) | + * [ nv gpr save area ] (6 * 8) | + * [ addl. nv gpr save area] (12 * 8) | <--- exception boundary/callback program * [ local_tmp_var ] 24 | * fp (r31) --> [ ebpf stack space ] upto 512 | * [ frame header ] 32/112 | * sp (r1) ---> [ stack pointer ] -------------- * - * Additional (12*8) in 'nv gpr save area' only in case of - * exception boundary. + * Additional (12 * 8) in 'nv gpr save area' only in case of + * exception boundary/callback. */ +/* BPF non-volatile registers save area size */ +#define BPF_PPC_STACK_SAVE (6 * 8) + /* for bpf JIT code internal usage */ #define BPF_PPC_STACK_LOCALS 24 /* * for additional non volatile registers(r14-r25) to be saved * at exception boundary */ -#define BPF_PPC_EXC_STACK_SAVE (12*8) +#define BPF_PPC_EXC_STACK_SAVE (12 * 8) /* stack frame excluding BPF stack, ensure this is quadword aligned */ #define BPF_PPC_STACKFRAME (STACK_FRAME_MIN_SIZE + \ @@ -125,12 +129,13 @@ static inline bool bpf_has_stack_frame(struct codegen_context *ctx) * [ ... ] | * sp (r1) ---> [ stack pointer ] -------------- * [ tail_call_info ] 8 - * [ nv gpr save area ] 6*8 + (12*8) + * [ nv gpr save area ] (6 * 8) + * [ addl. nv gpr save area] (12 * 8) <--- exception boundary/callback program * [ local_tmp_var ] 24 * [ unused red zone ] 224 * - * Additional (12*8) in 'nv gpr save area' only in case of - * exception boundary. + * Additional (12 * 8) in 'nv gpr save area' only in case of + * exception boundary/callback. */ static int bpf_jit_stack_local(struct codegen_context *ctx) { @@ -148,7 +153,7 @@ static int bpf_jit_stack_local(struct codegen_context *ctx) } } -int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx) +static int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx) { return bpf_jit_stack_local(ctx) + BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE; } @@ -237,10 +242,6 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx) if (bpf_has_stack_frame(ctx) && !ctx->exception_cb) { /* - * exception_cb uses boundary frame after stack walk. - * It can simply use redzone, this optimization reduces - * stack walk loop by one level. - * * We need a stack frame, but we don't necessarily need to * save/restore LR unless we call other functions */ @@ -284,6 +285,22 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx) * program(main prog) as third arg */ EMIT(PPC_RAW_MR(_R1, _R5)); + /* + * Exception callback reuses the stack frame of exception boundary. + * But BPF stack depth of exception callback and exception boundary + * don't have to be same. If BPF stack depth is different, adjust the + * stack frame size considering BPF stack depth of exception callback. + * The non-volatile register save area remains unchanged. These non- + * volatile registers are restored in exception callback's epilogue. + */ + EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R5, 0)); + EMIT(PPC_RAW_SUB(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_1), _R1)); + EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2), + -BPF_PPC_EXC_STACKFRAME)); + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), ctx->stack_size)); + PPC_BCC_CONST_SHORT(COND_EQ, 12); + EMIT(PPC_RAW_MR(_R1, bpf_to_ppc(TMP_REG_1))); + EMIT(PPC_RAW_STDU(_R1, _R1, -(BPF_PPC_EXC_STACKFRAME + ctx->stack_size))); } /* @@ -482,6 +499,83 @@ int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context * return 0; } +static int zero_extend(u32 *image, struct codegen_context *ctx, u32 src_reg, u32 dst_reg, u32 size) +{ + switch (size) { + case 1: + /* zero-extend 8 bits into 64 bits */ + EMIT(PPC_RAW_RLDICL(dst_reg, src_reg, 0, 56)); + return 0; + case 2: + /* zero-extend 16 bits into 64 bits */ + EMIT(PPC_RAW_RLDICL(dst_reg, src_reg, 0, 48)); + return 0; + case 4: + /* zero-extend 32 bits into 64 bits */ + EMIT(PPC_RAW_RLDICL(dst_reg, src_reg, 0, 32)); + fallthrough; + case 8: + /* Nothing to do */ + return 0; + default: + return -1; + } +} + +static int sign_extend(u32 *image, struct codegen_context *ctx, u32 src_reg, u32 dst_reg, u32 size) +{ + switch (size) { + case 1: + /* sign-extend 8 bits into 64 bits */ + EMIT(PPC_RAW_EXTSB(dst_reg, src_reg)); + return 0; + case 2: + /* sign-extend 16 bits into 64 bits */ + EMIT(PPC_RAW_EXTSH(dst_reg, src_reg)); + return 0; + case 4: + /* sign-extend 32 bits into 64 bits */ + EMIT(PPC_RAW_EXTSW(dst_reg, src_reg)); + fallthrough; + case 8: + /* Nothing to do */ + return 0; + default: + return -1; + } +} + +/* + * Handle powerpc ABI expectations from caller: + * - Unsigned arguments are zero-extended. + * - Signed arguments are sign-extended. + */ +static int prepare_for_kfunc_call(const struct bpf_prog *fp, u32 *image, + struct codegen_context *ctx, + const struct bpf_insn *insn) +{ + const struct btf_func_model *m = bpf_jit_find_kfunc_model(fp, insn); + int i; + + if (!m) + return -1; + + for (i = 0; i < m->nr_args; i++) { + /* Note that BPF ABI only allows up to 5 args for kfuncs */ + u32 reg = bpf_to_ppc(BPF_REG_1 + i), size = m->arg_size[i]; + + if (!(m->arg_flags[i] & BTF_FMODEL_SIGNED_ARG)) { + if (zero_extend(image, ctx, reg, reg, size)) + return -1; + } else { + if (sign_extend(image, ctx, reg, reg, size)) + return -1; + } + } + + return 0; +} + static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 out) { /* @@ -522,9 +616,30 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o /* * tail_call_info++; <- Actual value of tcc here + * Writeback this updated value only if tailcall succeeds. */ EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_1), 1)); + /* prog = array->ptrs[index]; */ + EMIT(PPC_RAW_MULI(bpf_to_ppc(TMP_REG_2), b2p_index, 8)); + EMIT(PPC_RAW_ADD(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2), b2p_bpf_array)); + EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2), + offsetof(struct bpf_array, ptrs))); + + /* + * if (prog == NULL) + * goto out; + */ + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), 0)); + PPC_BCC_SHORT(COND_EQ, out); + + /* goto *(prog->bpf_func + prologue_size); */ + EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2), + offsetof(struct bpf_prog, bpf_func))); + EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_2), bpf_to_ppc(TMP_REG_2), + FUNCTION_DESCR_SIZE + bpf_tailcall_prologue_size)); + EMIT(PPC_RAW_MTCTR(bpf_to_ppc(TMP_REG_2))); + /* * Before writing updated tail_call_info, distinguish if current frame * is storing a reference to tail_call_info or actual tcc value in @@ -539,24 +654,6 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o /* Writeback updated value to tail_call_info */ EMIT(PPC_RAW_STD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), 0)); - /* prog = array->ptrs[index]; */ - EMIT(PPC_RAW_MULI(bpf_to_ppc(TMP_REG_1), b2p_index, 8)); - EMIT(PPC_RAW_ADD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_1), b2p_bpf_array)); - EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_1), offsetof(struct bpf_array, ptrs))); - - /* - * if (prog == NULL) - * goto out; - */ - EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), 0)); - PPC_BCC_SHORT(COND_EQ, out); - - /* goto *(prog->bpf_func + prologue_size); */ - EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_1), offsetof(struct bpf_prog, bpf_func))); - EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_1), - FUNCTION_DESCR_SIZE + bpf_tailcall_prologue_size)); - EMIT(PPC_RAW_MTCTR(bpf_to_ppc(TMP_REG_1))); - /* tear down stack, restore NVRs, ... */ bpf_jit_emit_common_epilogue(image, ctx); @@ -1123,14 +1220,16 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code /* special mov32 for zext */ EMIT(PPC_RAW_RLWINM(dst_reg, dst_reg, 0, 0, 31)); break; - } else if (off == 8) { - EMIT(PPC_RAW_EXTSB(dst_reg, src_reg)); - } else if (off == 16) { - EMIT(PPC_RAW_EXTSH(dst_reg, src_reg)); - } else if (off == 32) { - EMIT(PPC_RAW_EXTSW(dst_reg, src_reg)); - } else if (dst_reg != src_reg) - EMIT(PPC_RAW_MR(dst_reg, src_reg)); + } + if (off == 0) { + /* MOV */ + if (dst_reg != src_reg) + EMIT(PPC_RAW_MR(dst_reg, src_reg)); + } else { + /* MOVSX: dst = (s8,s16,s32)src (off = 8,16,32) */ + if (sign_extend(image, ctx, src_reg, dst_reg, off / 8)) + return -1; + } goto bpf_alu32_trunc; case BPF_ALU | BPF_MOV | BPF_K: /* (u32) dst = imm */ case BPF_ALU64 | BPF_MOV | BPF_K: /* dst = (s64) imm */ @@ -1598,6 +1697,12 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code if (ret < 0) return ret; + /* Take care of powerpc ABI requirements before kfunc call */ + if (insn[i].src_reg == BPF_PSEUDO_KFUNC_CALL) { + if (prepare_for_kfunc_call(fp, image, ctx, &insn[i])) + return -1; + } + ret = bpf_jit_emit_func_call_rel(image, fimage, ctx, func_addr); if (ret) return ret; diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c index 26aa26482c9a..992cc5c98214 100644 --- a/arch/powerpc/perf/callchain.c +++ b/arch/powerpc/perf/callchain.c @@ -103,6 +103,11 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) { + perf_callchain_store(entry, perf_arch_instruction_pointer(regs)); + + if (!current->mm) + return; + if (!is_32bit_task()) perf_callchain_user_64(entry, regs); else diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c index ddcc2d8aa64a..0de21c5d272c 100644 --- a/arch/powerpc/perf/callchain_32.c +++ b/arch/powerpc/perf/callchain_32.c @@ -142,7 +142,6 @@ void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry, next_ip = perf_arch_instruction_pointer(regs); lr = regs->link; sp = regs->gpr[1]; - perf_callchain_store(entry, next_ip); while (entry->nr < entry->max_stack) { fp = (unsigned int __user *) (unsigned long) sp; diff --git a/arch/powerpc/perf/callchain_64.c b/arch/powerpc/perf/callchain_64.c index 115d1c105e8a..30fb61c5f0cb 100644 --- a/arch/powerpc/perf/callchain_64.c +++ b/arch/powerpc/perf/callchain_64.c @@ -77,7 +77,6 @@ void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry, next_ip = perf_arch_instruction_pointer(regs); lr = regs->link; sp = regs->gpr[1]; - perf_callchain_store(entry, next_ip); while (entry->nr < entry->max_stack) { fp = (unsigned long __user *) sp; diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index e42677cc254a..243c0a1c8cda 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -451,7 +451,7 @@ static ssize_t coresperchip_show(struct device *dev, static struct attribute *device_str_attr_create_(char *name, char *str) { - struct dev_ext_attribute *attr = kzalloc(sizeof(*attr), GFP_KERNEL); + struct dev_ext_attribute *attr = kzalloc_obj(*attr); if (!attr) return NULL; @@ -647,7 +647,7 @@ static int event_uniq_add(struct rb_root *root, const char *name, int nl, } } - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; @@ -905,21 +905,19 @@ static int create_events_from_catalog(struct attribute ***events_, pr_warn("event buffer ended before listed # of events were parsed (got %zu, wanted %zu, junk %zu)\n", event_idx_last, event_entry_count, junk_events); - events = kmalloc_array(attr_max + 1, sizeof(*events), GFP_KERNEL); + events = kmalloc_objs(*events, attr_max + 1); if (!events) { ret = -ENOMEM; goto e_event_data; } - event_descs = kmalloc_array(event_idx + 1, sizeof(*event_descs), - GFP_KERNEL); + event_descs = kmalloc_objs(*event_descs, event_idx + 1); if (!event_descs) { ret = -ENOMEM; goto e_event_attrs; } - event_long_descs = kmalloc_array(event_idx + 1, - sizeof(*event_long_descs), GFP_KERNEL); + event_long_descs = kmalloc_objs(*event_long_descs, event_idx + 1); if (!event_long_descs) { ret = -ENOMEM; goto e_event_descs; diff --git a/arch/powerpc/perf/hv-gpci.c b/arch/powerpc/perf/hv-gpci.c index 241551d1282f..5cac2cf3bd1e 100644 --- a/arch/powerpc/perf/hv-gpci.c +++ b/arch/powerpc/perf/hv-gpci.c @@ -910,7 +910,7 @@ static struct device_attribute *sysinfo_device_attr_create(int * attribute array, only for valid return types. */ if (!ret || ret == H_AUTHORITY || ret == H_PARAMETER) { - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return NULL; diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 8664a7d297ad..c1563b4eaa94 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -136,7 +136,7 @@ static struct attribute *device_str_attr_create(const char *name, const char *st { struct perf_pmu_events_attr *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return NULL; sysfs_attr_init(&attr->attr.attr); @@ -257,7 +257,7 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) of_property_read_u32(node, "reg", &base_reg); /* Allocate memory for the events */ - pmu->events = kcalloc(ct, sizeof(struct imc_events), GFP_KERNEL); + pmu->events = kzalloc_objs(struct imc_events, ct); if (!pmu->events) { of_node_put(pmu_events); return -ENOMEM; @@ -274,7 +274,7 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) of_node_put(pmu_events); /* Allocate memory for attribute group */ - attr_group = kzalloc(sizeof(*attr_group), GFP_KERNEL); + attr_group = kzalloc_obj(*attr_group); if (!attr_group) { imc_free_events(pmu->events, ct); return -ENOMEM; @@ -288,7 +288,7 @@ static int update_events_in_group(struct device_node *node, struct imc_pmu *pmu) * So allocate three times the "ct" (this includes event, event_scale and * event_unit). */ - attrs = kcalloc(((ct * 3) + 1), sizeof(struct attribute *), GFP_KERNEL); + attrs = kzalloc_objs(struct attribute *, ((ct * 3) + 1)); if (!attrs) { kfree(attr_group); imc_free_events(pmu->events, ct); @@ -1527,8 +1527,7 @@ static int init_nest_pmu_ref(void) { int nid, i, cpu; - nest_imc_refc = kcalloc(num_possible_nodes(), sizeof(*nest_imc_refc), - GFP_KERNEL); + nest_imc_refc = kzalloc_objs(*nest_imc_refc, num_possible_nodes()); if (!nest_imc_refc) return -ENOMEM; @@ -1699,9 +1698,8 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, /* Needed for hotplug/migration */ if (!per_nest_pmu_arr) { - per_nest_pmu_arr = kcalloc(get_max_nest_dev() + 1, - sizeof(struct imc_pmu *), - GFP_KERNEL); + per_nest_pmu_arr = kzalloc_objs(struct imc_pmu *, + get_max_nest_dev() + 1); if (!per_nest_pmu_arr) goto err; } @@ -1714,14 +1712,12 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, goto err; nr_cores = DIV_ROUND_UP(num_possible_cpus(), threads_per_core); - pmu_ptr->mem_info = kcalloc(nr_cores, sizeof(struct imc_mem_info), - GFP_KERNEL); + pmu_ptr->mem_info = kzalloc_objs(struct imc_mem_info, nr_cores); if (!pmu_ptr->mem_info) goto err; - core_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref), - GFP_KERNEL); + core_imc_refc = kzalloc_objs(struct imc_pmu_ref, nr_cores); if (!core_imc_refc) { kfree(pmu_ptr->mem_info); @@ -1754,8 +1750,7 @@ static int imc_mem_init(struct imc_pmu *pmu_ptr, struct device_node *parent, return -ENOMEM; nr_cores = DIV_ROUND_UP(num_possible_cpus(), threads_per_core); - trace_imc_refc = kcalloc(nr_cores, sizeof(struct imc_pmu_ref), - GFP_KERNEL); + trace_imc_refc = kzalloc_objs(struct imc_pmu_ref, nr_cores); if (!trace_imc_refc) return -ENOMEM; diff --git a/arch/powerpc/perf/vpa-dtl.c b/arch/powerpc/perf/vpa-dtl.c index 3c1d1c28deb9..3e3d65b6c796 100644 --- a/arch/powerpc/perf/vpa-dtl.c +++ b/arch/powerpc/perf/vpa-dtl.c @@ -523,7 +523,7 @@ static void *vpa_dtl_setup_aux(struct perf_event *event, void **pages, if (!buf) return NULL; - pglist = kcalloc(nr_pages, sizeof(*pglist), GFP_KERNEL); + pglist = kzalloc_objs(*pglist, nr_pages); if (!pglist) return NULL; diff --git a/arch/powerpc/platforms/44x/hsta_msi.c b/arch/powerpc/platforms/44x/hsta_msi.c index c6bd846b0d65..0f61bd446ce2 100644 --- a/arch/powerpc/platforms/44x/hsta_msi.c +++ b/arch/powerpc/platforms/44x/hsta_msi.c @@ -151,8 +151,7 @@ static int hsta_msi_probe(struct platform_device *pdev) if (ret) goto out; - ppc4xx_hsta_msi.irq_map = kmalloc_array(irq_count, sizeof(int), - GFP_KERNEL); + ppc4xx_hsta_msi.irq_map = kmalloc_objs(int, irq_count); if (!ppc4xx_hsta_msi.irq_map) { ret = -ENOMEM; goto out1; diff --git a/arch/powerpc/platforms/44x/pci.c b/arch/powerpc/platforms/44x/pci.c index 364aeb86ab64..e454b48fa9db 100644 --- a/arch/powerpc/platforms/44x/pci.c +++ b/arch/powerpc/platforms/44x/pci.c @@ -1339,8 +1339,7 @@ static int __init ppc4xx_pciex_check_core_init(struct device_node *np) count = ppc4xx_pciex_hwops->core_init(np); if (count > 0) { ppc4xx_pciex_ports = - kcalloc(count, sizeof(struct ppc4xx_pciex_port), - GFP_KERNEL); + kzalloc_objs(struct ppc4xx_pciex_port, count); if (ppc4xx_pciex_ports) { ppc4xx_pciex_port_count = count; return 0; diff --git a/arch/powerpc/platforms/44x/uic.c b/arch/powerpc/platforms/44x/uic.c index 85daf841fd3f..cf4fc5263c89 100644 --- a/arch/powerpc/platforms/44x/uic.c +++ b/arch/powerpc/platforms/44x/uic.c @@ -233,7 +233,7 @@ static struct uic * __init uic_init_one(struct device_node *node) BUG_ON(! of_device_is_compatible(node, "ibm,uic")); - uic = kzalloc(sizeof(*uic), GFP_KERNEL); + uic = kzalloc_obj(*uic); if (! uic) return NULL; /* FIXME: panic? */ diff --git a/arch/powerpc/platforms/83xx/km83xx.c b/arch/powerpc/platforms/83xx/km83xx.c index 2b5d187d9b62..9ef8fb39dd1b 100644 --- a/arch/powerpc/platforms/83xx/km83xx.c +++ b/arch/powerpc/platforms/83xx/km83xx.c @@ -155,8 +155,8 @@ machine_device_initcall(mpc83xx_km, mpc83xx_declare_of_platform_devices); /* list of the supported boards */ static char *board[] __initdata = { - "Keymile,KMETER1", - "Keymile,kmpbec8321", + "keymile,KMETER1", + "keymile,kmpbec8321", NULL }; diff --git a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c index 80d944f29288..9b693594a5f7 100644 --- a/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c +++ b/arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c @@ -146,7 +146,7 @@ static int mcu_probe(struct i2c_client *client) struct mcu *mcu; int ret; - mcu = kzalloc(sizeof(*mcu), GFP_KERNEL); + mcu = kzalloc_obj(*mcu); if (!mcu) return -ENOMEM; diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index f399917c17bd..bac02c83bb3e 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -276,7 +276,7 @@ config PPC_BOOK3S config PPC_E500 select FSL_EMB_PERFMON bool - select ARCH_SUPPORTS_HUGETLBFS if PHYS_64BIT || PPC64 + select ARCH_SUPPORTS_HUGETLBFS select PPC_SMP_MUXED_IPI select PPC_DOORBELL select PPC_KUEP @@ -337,7 +337,7 @@ config BOOKE config PTE_64BIT bool depends on 44x || PPC_E500 || PPC_86xx - default y if PHYS_64BIT + default y if PPC_E500 || PHYS_64BIT config PHYS_64BIT bool 'Large physical address support' if PPC_E500 || PPC_86xx diff --git a/arch/powerpc/platforms/book3s/vas-api.c b/arch/powerpc/platforms/book3s/vas-api.c index 49b15e7a8265..ea4ffa63f043 100644 --- a/arch/powerpc/platforms/book3s/vas-api.c +++ b/arch/powerpc/platforms/book3s/vas-api.c @@ -266,7 +266,7 @@ static int coproc_open(struct inode *inode, struct file *fp) { struct coproc_instance *cp_inst; - cp_inst = kzalloc(sizeof(*cp_inst), GFP_KERNEL); + cp_inst = kzalloc_obj(*cp_inst); if (!cp_inst) return -ENOMEM; diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 3c8624870967..0ec7b3bdda56 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -558,7 +558,7 @@ static int __init create_spu(void *data) unsigned long flags; ret = -ENOMEM; - spu = kzalloc(sizeof (*spu), GFP_KERNEL); + spu = kzalloc_obj(*spu); if (!spu) goto out; diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 7a39cc414f09..44377dfff1f8 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c @@ -26,7 +26,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang) { struct spu_context *ctx; - ctx = kzalloc(sizeof *ctx, GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) goto out; /* Binding to physical processor deferred diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index ce839783c0df..10fa9b844fcc 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -47,7 +47,7 @@ static int spufs_attr_open(struct inode *inode, struct file *file, { struct spufs_attr *attr; - attr = kmalloc(sizeof(*attr), GFP_KERNEL); + attr = kmalloc_obj(*attr); if (!attr) return -ENOMEM; @@ -2281,8 +2281,8 @@ static int spufs_switch_log_open(struct inode *inode, struct file *file) goto out; } - ctx->switch_log = kmalloc(struct_size(ctx->switch_log, log, - SWITCH_LOG_BUFSIZE), GFP_KERNEL); + ctx->switch_log = kmalloc_flex(*ctx->switch_log, log, + SWITCH_LOG_BUFSIZE); if (!ctx->switch_log) { rc = -ENOMEM; diff --git a/arch/powerpc/platforms/cell/spufs/gang.c b/arch/powerpc/platforms/cell/spufs/gang.c index 2c2999de6bfa..572c4bf8e512 100644 --- a/arch/powerpc/platforms/cell/spufs/gang.c +++ b/arch/powerpc/platforms/cell/spufs/gang.c @@ -16,7 +16,7 @@ struct spu_gang *alloc_spu_gang(void) { struct spu_gang *gang; - gang = kzalloc(sizeof *gang, GFP_KERNEL); + gang = kzalloc_obj(*gang); if (!gang) goto out; diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 577a00c25217..2b54afb31529 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -727,11 +727,11 @@ static int spufs_init_fs_context(struct fs_context *fc) struct spufs_fs_context *ctx; struct spufs_sb_info *sbi; - ctx = kzalloc(sizeof(struct spufs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct spufs_fs_context); if (!ctx) goto nomem; - sbi = kzalloc(sizeof(struct spufs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct spufs_sb_info); if (!sbi) goto nomem_ctx; diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 8e7ed010bfde..c52af883e01c 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -1082,7 +1082,7 @@ int __init spu_sched_init(void) struct proc_dir_entry *entry; int err = -ENOMEM, i; - spu_prio = kzalloc(sizeof(struct spu_prio_array), GFP_KERNEL); + spu_prio = kzalloc_obj(struct spu_prio_array); if (!spu_prio) goto out; diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c index e4538d471256..9b7bc8efe8f7 100644 --- a/arch/powerpc/platforms/pasemi/gpio_mdio.c +++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c @@ -214,7 +214,7 @@ static int gpio_mdio_probe(struct platform_device *ofdev) int err; err = -ENOMEM; - priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); + priv = kzalloc_obj(struct gpio_priv); if (!priv) goto out; diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 02474e27df9b..73b7f4e8c047 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c @@ -489,7 +489,7 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) const u32 *psteps, *prate, *addrp; u32 steps; - host = kzalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc_obj(*host); if (host == NULL) { printk(KERN_ERR "low_i2c: Can't allocate host for %pOF\n", np); @@ -569,7 +569,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, { struct pmac_i2c_bus *bus; - bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL); + bus = kzalloc_obj(struct pmac_i2c_bus); if (bus == NULL) return; @@ -1254,7 +1254,7 @@ static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args) * near OOM that need to be resolved, the allocator itself should * probably make GFP_NOIO implicit during suspend */ - inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL); + inst = kzalloc_obj(struct pmac_i2c_pf_inst); if (inst == NULL) { pmac_i2c_close(bus); return NULL; diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 22741ddfd5b2..c76b9d501d3a 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -644,7 +644,7 @@ static int pmf_add_function_prop(struct pmf_device *dev, void *driverdata, while (length >= 12) { /* Allocate a structure */ - func = kzalloc(sizeof(*func), GFP_KERNEL); + func = kzalloc_obj(*func); if (func == NULL) goto bail; kref_init(&func->ref); @@ -720,7 +720,7 @@ int pmf_register_driver(struct device_node *np, return -EBUSY; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { DBG("pmf: no memory !\n"); return -ENOMEM; diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index e4f4e907f6e3..6cd461f82968 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -1336,8 +1336,7 @@ static int __init pnv_parse_cpuidle_dt(void) nr_idle_states = of_property_count_u32_elems(np, "ibm,cpu-idle-state-flags"); - pnv_idle_states = kcalloc(nr_idle_states, sizeof(*pnv_idle_states), - GFP_KERNEL); + pnv_idle_states = kzalloc_objs(*pnv_idle_states, nr_idle_states); temp_u32 = kcalloc(nr_idle_states, sizeof(u32), GFP_KERNEL); temp_u64 = kcalloc(nr_idle_states, sizeof(u64), GFP_KERNEL); temp_string = kcalloc(nr_idle_states, sizeof(char *), GFP_KERNEL); diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 2ea30b343354..6aa578e6348d 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -133,8 +133,7 @@ static int memtrace_init_regions_runtime(u64 size) u32 nid; u64 m; - memtrace_array = kcalloc(num_online_nodes(), - sizeof(struct memtrace_entry), GFP_KERNEL); + memtrace_array = kzalloc_objs(struct memtrace_entry, num_online_nodes()); if (!memtrace_array) { pr_err("Failed to allocate memtrace_array\n"); return -EINVAL; diff --git a/arch/powerpc/platforms/powernv/ocxl.c b/arch/powerpc/platforms/powernv/ocxl.c index f8139948348e..6192caaf85e6 100644 --- a/arch/powerpc/platforms/powernv/ocxl.c +++ b/arch/powerpc/platforms/powernv/ocxl.c @@ -149,7 +149,7 @@ static struct npu_link *find_link(struct pci_dev *dev) } /* link doesn't exist yet. Allocate one */ - link = kzalloc(sizeof(struct npu_link), GFP_KERNEL); + link = kzalloc_obj(struct npu_link); if (!link) return NULL; link->domain = pci_domain_nr(dev->bus); @@ -439,7 +439,7 @@ int pnv_ocxl_spa_setup(struct pci_dev *dev, void *spa_mem, int PE_mask, u32 bdfn; int rc; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/arch/powerpc/platforms/powernv/opal-async.c b/arch/powerpc/platforms/powernv/opal-async.c index c094fdf5825c..6560c024bfd2 100644 --- a/arch/powerpc/platforms/powernv/opal-async.c +++ b/arch/powerpc/platforms/powernv/opal-async.c @@ -265,8 +265,8 @@ int __init opal_async_comp_init(void) } opal_max_async_tokens = be32_to_cpup(async); - opal_async_tokens = kcalloc(opal_max_async_tokens, - sizeof(*opal_async_tokens), GFP_KERNEL); + opal_async_tokens = kzalloc_objs(*opal_async_tokens, + opal_max_async_tokens); if (!opal_async_tokens) { err = -ENOMEM; goto out_opal_node; diff --git a/arch/powerpc/platforms/powernv/opal-core.c b/arch/powerpc/platforms/powernv/opal-core.c index 784602a48afb..e76e462f55f6 100644 --- a/arch/powerpc/platforms/powernv/opal-core.c +++ b/arch/powerpc/platforms/powernv/opal-core.c @@ -81,7 +81,7 @@ bool kernel_initiated; static struct opalcore * __init get_new_element(void) { - return kzalloc(sizeof(struct opalcore), GFP_KERNEL); + return kzalloc_obj(struct opalcore); } static inline int is_opalcore_usable(void) @@ -497,7 +497,7 @@ static void __init opalcore_config_init(void) opalc_cpu_metadata = __va(addr); /* Allocate memory for config buffer */ - oc_conf = kzalloc(sizeof(struct opalcore_config), GFP_KERNEL); + oc_conf = kzalloc_obj(struct opalcore_config); if (oc_conf == NULL) goto error_out; diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c index cc3cc9ddf9d1..2e4bffa74163 100644 --- a/arch/powerpc/platforms/powernv/opal-dump.c +++ b/arch/powerpc/platforms/powernv/opal-dump.c @@ -329,7 +329,7 @@ static void create_dump_obj(uint32_t id, size_t size, uint32_t type) struct dump_obj *dump; int rc; - dump = kzalloc(sizeof(*dump), GFP_KERNEL); + dump = kzalloc_obj(*dump); if (!dump) return; diff --git a/arch/powerpc/platforms/powernv/opal-elog.c b/arch/powerpc/platforms/powernv/opal-elog.c index c3fc5d258146..2b8331922ab9 100644 --- a/arch/powerpc/platforms/powernv/opal-elog.c +++ b/arch/powerpc/platforms/powernv/opal-elog.c @@ -190,7 +190,7 @@ static void create_elog_obj(uint64_t id, size_t size, uint64_t type) struct elog_obj *elog; int rc; - elog = kzalloc(sizeof(*elog), GFP_KERNEL); + elog = kzalloc_obj(*elog); if (!elog) return; diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index f0c1830deb51..182719995d05 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -342,7 +342,7 @@ static int opal_handle_hmi_event(struct notifier_block *nb, hmi_evt = (struct OpalHMIEvent *)&hmi_msg->params[0]; /* Delay the logging of HMI events to workqueue. */ - msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC); + msg_node = kzalloc_obj(*msg_node, GFP_ATOMIC); if (!msg_node) { pr_err("HMI: out of memory, Opal message event not handled\n"); return -ENOMEM; diff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c index 828fc4d88471..b3fd5c648dea 100644 --- a/arch/powerpc/platforms/powernv/opal-imc.c +++ b/arch/powerpc/platforms/powernv/opal-imc.c @@ -108,8 +108,7 @@ static int imc_get_mem_addr_nest(struct device_node *node, nr_chips)) goto error; - pmu_ptr->mem_info = kcalloc(nr_chips + 1, sizeof(*pmu_ptr->mem_info), - GFP_KERNEL); + pmu_ptr->mem_info = kzalloc_objs(*pmu_ptr->mem_info, nr_chips + 1); if (!pmu_ptr->mem_info) goto error; @@ -146,7 +145,7 @@ static struct imc_pmu *imc_pmu_create(struct device_node *parent, int pmu_index, return NULL; /* memory for pmu */ - pmu_ptr = kzalloc(sizeof(*pmu_ptr), GFP_KERNEL); + pmu_ptr = kzalloc_obj(*pmu_ptr); if (!pmu_ptr) return NULL; diff --git a/arch/powerpc/platforms/powernv/opal-irqchip.c b/arch/powerpc/platforms/powernv/opal-irqchip.c index e180bd8e1400..fc0a1eae59c5 100644 --- a/arch/powerpc/platforms/powernv/opal-irqchip.c +++ b/arch/powerpc/platforms/powernv/opal-irqchip.c @@ -221,7 +221,7 @@ int __init opal_event_init(void) opal_irq_count, old_style ? "old" : "new"); /* Allocate an IRQ resources array */ - opal_irqs = kcalloc(opal_irq_count, sizeof(struct resource), GFP_KERNEL); + opal_irqs = kzalloc_objs(struct resource, opal_irq_count); if (WARN_ON(!opal_irqs)) { rc = -ENOMEM; goto out; diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c index 8a7f39e106bd..2bb326b58ff8 100644 --- a/arch/powerpc/platforms/powernv/opal-lpc.c +++ b/arch/powerpc/platforms/powernv/opal-lpc.c @@ -355,7 +355,7 @@ static int opal_lpc_debugfs_create_type(struct dentry *folder, enum OpalLPCAddressType type) { struct lpc_debugfs_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; entry->lpc_type = type; diff --git a/arch/powerpc/platforms/powernv/opal-memory-errors.c b/arch/powerpc/platforms/powernv/opal-memory-errors.c index a1754a28265d..54815882d7c0 100644 --- a/arch/powerpc/platforms/powernv/opal-memory-errors.c +++ b/arch/powerpc/platforms/powernv/opal-memory-errors.c @@ -93,7 +93,7 @@ static int opal_memory_err_event(struct notifier_block *nb, if (msg_type != OPAL_MSG_MEM_ERR) return 0; - msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC); + msg_node = kzalloc_obj(*msg_node, GFP_ATOMIC); if (!msg_node) { pr_err("MEMORY_ERROR: out of memory, Opal message event not" "handled\n"); diff --git a/arch/powerpc/platforms/powernv/opal-powercap.c b/arch/powerpc/platforms/powernv/opal-powercap.c index ea917266aa17..9bb73cb42a65 100644 --- a/arch/powerpc/platforms/powernv/opal-powercap.c +++ b/arch/powerpc/platforms/powernv/opal-powercap.c @@ -150,8 +150,7 @@ void __init opal_powercap_init(void) return; } - pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps), - GFP_KERNEL); + pcaps = kzalloc_objs(*pcaps, of_get_child_count(powercap)); if (!pcaps) goto out_put_powercap; @@ -182,13 +181,11 @@ void __init opal_powercap_init(void) has_cur = true; } - pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr), - GFP_KERNEL); + pcaps[i].pattrs = kzalloc_objs(struct powercap_attr, j); if (!pcaps[i].pattrs) goto out_pcaps_pattrs; - pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *), - GFP_KERNEL); + pcaps[i].pg.attrs = kzalloc_objs(struct attribute *, j + 1); if (!pcaps[i].pg.attrs) { kfree(pcaps[i].pattrs); goto out_pcaps_pattrs; diff --git a/arch/powerpc/platforms/powernv/opal-psr.c b/arch/powerpc/platforms/powernv/opal-psr.c index 6441e17b6996..24d0a894d965 100644 --- a/arch/powerpc/platforms/powernv/opal-psr.c +++ b/arch/powerpc/platforms/powernv/opal-psr.c @@ -132,8 +132,7 @@ void __init opal_psr_init(void) return; } - psr_attrs = kcalloc(of_get_child_count(psr), sizeof(*psr_attrs), - GFP_KERNEL); + psr_attrs = kzalloc_objs(*psr_attrs, of_get_child_count(psr)); if (!psr_attrs) goto out_put_psr; diff --git a/arch/powerpc/platforms/powernv/opal-sensor-groups.c b/arch/powerpc/platforms/powernv/opal-sensor-groups.c index 9944376b115c..87fd6d7769e9 100644 --- a/arch/powerpc/platforms/powernv/opal-sensor-groups.c +++ b/arch/powerpc/platforms/powernv/opal-sensor-groups.c @@ -168,7 +168,7 @@ void __init opal_sensor_groups_init(void) return; } - sgs = kcalloc(of_get_child_count(sg), sizeof(*sgs), GFP_KERNEL); + sgs = kzalloc_objs(*sgs, of_get_child_count(sg)); if (!sgs) goto out_sg_put; @@ -190,14 +190,11 @@ void __init opal_sensor_groups_init(void) if (!nr_attrs) continue; - sgs[i].sgattrs = kcalloc(nr_attrs, sizeof(*sgs[i].sgattrs), - GFP_KERNEL); + sgs[i].sgattrs = kzalloc_objs(*sgs[i].sgattrs, nr_attrs); if (!sgs[i].sgattrs) goto out_sgs_sgattrs; - sgs[i].sg.attrs = kcalloc(nr_attrs + 1, - sizeof(*sgs[i].sg.attrs), - GFP_KERNEL); + sgs[i].sg.attrs = kzalloc_objs(*sgs[i].sg.attrs, nr_attrs + 1); if (!sgs[i].sg.attrs) { kfree(sgs[i].sgattrs); diff --git a/arch/powerpc/platforms/powernv/opal-sysparam.c b/arch/powerpc/platforms/powernv/opal-sysparam.c index a12312afe4ef..7fe6433517ca 100644 --- a/arch/powerpc/platforms/powernv/opal-sysparam.c +++ b/arch/powerpc/platforms/powernv/opal-sysparam.c @@ -222,7 +222,7 @@ void __init opal_sys_param_init(void) goto out_free_perm; } - attr = kcalloc(count, sizeof(*attr), GFP_KERNEL); + attr = kzalloc_objs(*attr, count); if (!attr) { pr_err("SYSPARAM: Failed to allocate memory for parameter " "attributes\n"); diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c index 748c2b97fa53..2ad5787a922f 100644 --- a/arch/powerpc/platforms/powernv/opal-xscom.c +++ b/arch/powerpc/platforms/powernv/opal-xscom.c @@ -158,7 +158,7 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn, struct scom_debug_entry *ent; struct dentry *dir; - ent = kzalloc(sizeof(*ent), GFP_KERNEL); + ent = kzalloc_obj(*ent); if (!ent) return -ENOMEM; diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 09bd93464b4f..1946dbdc9fa1 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -251,7 +251,7 @@ static void queue_replay_msg(void *msg) struct opal_msg_node *msg_node; if (msg_list_size < OPAL_MSG_QUEUE_MAX) { - msg_node = kzalloc(sizeof(*msg_node), GFP_ATOMIC); + msg_node = kzalloc_obj(*msg_node, GFP_ATOMIC); if (msg_node) { INIT_LIST_HEAD(&msg_node->list); memcpy(&msg_node->msg, msg, sizeof(struct opal_msg)); @@ -801,7 +801,7 @@ static int opal_add_one_export(struct kobject *parent, const char *export_name, if (rc) goto out; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) { rc = -ENOMEM; goto out; diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 1c78fdfb7b03..885392f4cd94 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2522,7 +2522,7 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np, phb_id = be64_to_cpup(prop64); pr_debug(" PHB-ID : 0x%016llx\n", phb_id); - phb = kzalloc(sizeof(*phb), GFP_KERNEL); + phb = kzalloc_obj(*phb); if (!phb) panic("%s: Failed to allocate %zu bytes\n", __func__, sizeof(*phb)); diff --git a/arch/powerpc/platforms/powernv/pci-sriov.c b/arch/powerpc/platforms/powernv/pci-sriov.c index cc7b1dd54ac6..7105a573aec4 100644 --- a/arch/powerpc/platforms/powernv/pci-sriov.c +++ b/arch/powerpc/platforms/powernv/pci-sriov.c @@ -149,7 +149,7 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev) struct pnv_iov_data *iov; int mul; - iov = kzalloc(sizeof(*iov), GFP_KERNEL); + iov = kzalloc_obj(*iov); if (!iov) goto disable_iov; pdev->dev.archdata.iov_data = iov; diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c index 196aa70fe043..7a4c38cd6a82 100644 --- a/arch/powerpc/platforms/powernv/rng.c +++ b/arch/powerpc/platforms/powernv/rng.c @@ -120,7 +120,7 @@ static __init int rng_create(struct device_node *dn) struct resource res; unsigned long val; - rng = kzalloc(sizeof(*rng), GFP_KERNEL); + rng = kzalloc_obj(*rng); if (!rng) return -ENOMEM; diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index 5147df3a18ac..9f093176b8db 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -543,7 +543,7 @@ static struct pnv_vas_window *vas_window_alloc(struct vas_instance *vinst) if (winid < 0) return ERR_PTR(winid); - window = kzalloc(sizeof(*window), GFP_KERNEL); + window = kzalloc_obj(*window); if (!window) goto out_free; diff --git a/arch/powerpc/platforms/powernv/vas.c b/arch/powerpc/platforms/powernv/vas.c index 9c9650319f3b..815684c2b56e 100644 --- a/arch/powerpc/platforms/powernv/vas.c +++ b/arch/powerpc/platforms/powernv/vas.c @@ -74,7 +74,7 @@ static int init_vas_instance(struct platform_device *pdev) return -ENODEV; } - vinst = kzalloc(sizeof(*vinst), GFP_KERNEL); + vinst = kzalloc_obj(*vinst); if (!vinst) return -ENOMEM; diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index 22d91ac424dd..12c473768c39 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -31,7 +31,7 @@ static int __init ps3_register_lpm_devices(void) pr_debug(" -> %s:%d\n", __func__, __LINE__); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; @@ -126,7 +126,7 @@ static int __init ps3_setup_gelic_device( BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB); BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_GELIC); - p = kzalloc(sizeof(struct layout), GFP_KERNEL); + p = kzalloc_obj(struct layout); if (!p) { result = -ENOMEM; @@ -197,7 +197,7 @@ static int __init ps3_setup_uhc_device( BUG_ON(repo->bus_type != PS3_BUS_TYPE_SB); BUG_ON(repo->dev_type != PS3_DEV_TYPE_SB_USB); - p = kzalloc(sizeof(struct layout), GFP_KERNEL); + p = kzalloc_obj(struct layout); if (!p) { result = -ENOMEM; @@ -294,7 +294,7 @@ static int __init ps3_setup_vuart_device(enum ps3_match_id match_id, pr_debug(" -> %s:%d: match_id %u, port %u\n", __func__, __LINE__, match_id, port_number); - p = kzalloc(sizeof(struct layout), GFP_KERNEL); + p = kzalloc_obj(struct layout); if (!p) return -ENOMEM; @@ -344,7 +344,7 @@ static int ps3_setup_storage_dev(const struct ps3_repository_device *repo, repo->dev_index, repo->dev_type, port, blk_size, num_blocks, num_regions); - p = kzalloc(struct_size(p, regions, num_regions), GFP_KERNEL); + p = kzalloc_flex(*p, regions, num_regions); if (!p) { result = -ENOMEM; goto fail_malloc; @@ -447,7 +447,7 @@ static int __init ps3_register_sound_devices(void) pr_debug(" -> %s:%d\n", __func__, __LINE__); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; @@ -481,7 +481,7 @@ static int __init ps3_register_graphics_devices(void) pr_debug(" -> %s:%d\n", __func__, __LINE__); - p = kzalloc(sizeof(struct layout), GFP_KERNEL); + p = kzalloc_obj(struct layout); if (!p) return -ENOMEM; @@ -516,7 +516,7 @@ static int __init ps3_register_ramdisk_device(void) pr_debug(" -> %s:%d\n", __func__, __LINE__); - p = kzalloc(sizeof(struct layout), GFP_KERNEL); + p = kzalloc_obj(struct layout); if (!p) return -ENOMEM; @@ -783,7 +783,7 @@ static int ps3_probe_thread(void *data) pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); - local = kzalloc(sizeof(*local), GFP_KERNEL); + local = kzalloc_obj(*local); if (!local) return -ENOMEM; diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 1326de55fda6..20fc5b68faee 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -516,7 +516,7 @@ static int dma_sb_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, int result; struct dma_chunk *c; - c = kzalloc(sizeof(*c), GFP_ATOMIC); + c = kzalloc_obj(*c, GFP_ATOMIC); if (!c) { result = -ENOMEM; goto fail_alloc; @@ -561,7 +561,7 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr, DBG(KERN_ERR "%s: phy=%#lx, lpar%#lx, len=%#lx\n", __func__, phys_addr, ps3_mm_phys_to_lpar(phys_addr), len); - c = kzalloc(sizeof(*c), GFP_ATOMIC); + c = kzalloc_obj(*c, GFP_ATOMIC); if (!c) { result = -ENOMEM; goto fail_alloc; diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c index 61b37c9400b2..10ab256b675c 100644 --- a/arch/powerpc/platforms/ps3/spu.c +++ b/arch/powerpc/platforms/ps3/spu.c @@ -336,8 +336,7 @@ static int __init ps3_create_spu(struct spu *spu, void *data) pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number); - spu->pdata = kzalloc(sizeof(struct spu_pdata), - GFP_KERNEL); + spu->pdata = kzalloc_obj(struct spu_pdata); if (!spu->pdata) { result = -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 979487da6522..a7c451c2507d 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -53,7 +53,7 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa) char *name; char *value; - prop = kzalloc(sizeof(*prop), GFP_KERNEL); + prop = kzalloc_obj(*prop); if (!prop) return NULL; @@ -80,7 +80,7 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa) struct device_node *dn; const char *name; - dn = kzalloc(sizeof(*dn), GFP_KERNEL); + dn = kzalloc_obj(*dn); if (!dn) return NULL; @@ -633,7 +633,7 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog) if (!hp_errlog_copy) return; - work = kmalloc(sizeof(struct pseries_hp_work), GFP_ATOMIC); + work = kmalloc_obj(struct pseries_hp_work, GFP_ATOMIC); if (work) { INIT_WORK((struct work_struct *)work, pseries_hp_work_fn); work->errlog = hp_errlog_copy; diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 38dc4f7c9296..b2f14db59034 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -33,7 +33,7 @@ static struct property *dlpar_clone_property(struct property *prop, { struct property *new_prop; - new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); + new_prop = kzalloc_obj(*new_prop); if (!new_prop) return NULL; diff --git a/arch/powerpc/platforms/pseries/hvcserver.c b/arch/powerpc/platforms/pseries/hvcserver.c index d48c9c7ce10f..80e310a45f14 100644 --- a/arch/powerpc/platforms/pseries/hvcserver.c +++ b/arch/powerpc/platforms/pseries/hvcserver.c @@ -160,8 +160,8 @@ int hvcs_get_partner_info(uint32_t unit_address, struct list_head *head, /* This is a very small struct and will be freed soon in * hvcs_free_partner_info(). */ - next_partner_info = kmalloc(sizeof(struct hvcs_partner_info), - GFP_ATOMIC); + next_partner_info = kmalloc_obj(struct hvcs_partner_info, + GFP_ATOMIC); if (!next_partner_info) { printk(KERN_WARNING "HVCONSOLE: kmalloc() failed to" diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 5497b130e026..3e1f915fe4f6 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -1000,7 +1000,7 @@ static void copy_property(struct device_node *pdn, const char *from, const char if (!src) return; - dst = kzalloc(sizeof(*dst), GFP_KERNEL); + dst = kzalloc_obj(*dst); if (!dst) return; @@ -1089,7 +1089,7 @@ static struct dma_win *ddw_list_new_entry(struct device_node *pdn, { struct dma_win *window; - window = kzalloc(sizeof(*window), GFP_KERNEL); + window = kzalloc_obj(*window); if (!window) return NULL; @@ -1409,12 +1409,12 @@ static struct property *ddw_property_create(const char *propname, u32 liobn, u64 struct dynamic_dma_window_prop *ddwprop; struct property *win64; - win64 = kzalloc(sizeof(*win64), GFP_KERNEL); + win64 = kzalloc_obj(*win64); if (!win64) return NULL; win64->name = kstrdup(propname, GFP_KERNEL); - ddwprop = kzalloc(sizeof(*ddwprop), GFP_KERNEL); + ddwprop = kzalloc_obj(*ddwprop); win64->value = ddwprop; win64->length = sizeof(*ddwprop); if (!win64->name || !win64->value) { @@ -1760,7 +1760,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas if (default_win_removed || limited_addr_enabled) reset_dma_window(dev, pdn); - fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); + fpdn = kzalloc_obj(*fpdn); if (!fpdn) goto out_unlock; fpdn->pdn = pdn; @@ -2235,7 +2235,7 @@ static long spapr_tce_create_table(struct iommu_table_group *table_group, int nu __remove_dma_window(pdn, ddw_avail, create.liobn); out_failed: - fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); + fpdn = kzalloc_obj(*fpdn); if (!fpdn) goto out_unlock; fpdn->pdn = pdn; @@ -2322,7 +2322,7 @@ static long spapr_tce_unset_window(struct iommu_table_group *table_group, int nu goto out_unlock; out_failed: - fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); + fpdn = kzalloc_obj(*fpdn); if (!fpdn) goto out_unlock; fpdn->pdn = pdn; diff --git a/arch/powerpc/platforms/pseries/lparcfg.c b/arch/powerpc/platforms/pseries/lparcfg.c index 6554537984fb..8821c378bfff 100644 --- a/arch/powerpc/platforms/pseries/lparcfg.c +++ b/arch/powerpc/platforms/pseries/lparcfg.c @@ -146,7 +146,7 @@ static void show_gpci_data(struct seq_file *m) unsigned int affinity_score; long ret; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (buf == NULL) return; diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 95fe802ccdfd..b5c2abd12432 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -146,7 +146,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop, new_prop->value = new_data; new_prop->length += vd; } else { - new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); + new_prop = kzalloc_obj(*new_prop); if (!new_prop) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index 4cd70a8201f1..8285b9a29fbf 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -441,7 +441,7 @@ static int pseries_msi_ops_prepare(struct irq_domain *domain, struct device *dev int ret; struct pseries_msi_device *pseries_dev __free(kfree) - = kmalloc(sizeof(*pseries_dev), GFP_KERNEL); + = kmalloc_obj(*pseries_dev); if (!pseries_dev) return -ENOMEM; @@ -605,7 +605,7 @@ static int pseries_irq_domain_alloc(struct irq_domain *domain, unsigned int virq &pseries_msi_irq_chip, pseries_dev); } - pseries_dev->msi_used++; + pseries_dev->msi_used += nr_irqs; return 0; out: diff --git a/arch/powerpc/platforms/pseries/papr-hvpipe.c b/arch/powerpc/platforms/pseries/papr-hvpipe.c index dd7b668799d9..14ae480d060a 100644 --- a/arch/powerpc/platforms/pseries/papr-hvpipe.c +++ b/arch/powerpc/platforms/pseries/papr-hvpipe.c @@ -495,7 +495,7 @@ static int papr_hvpipe_dev_create_handle(u32 srcID) } spin_unlock(&hvpipe_src_list_lock); - src_info = kzalloc(sizeof(*src_info), GFP_KERNEL_ACCOUNT); + src_info = kzalloc_obj(*src_info, GFP_KERNEL_ACCOUNT); if (!src_info) return -ENOMEM; @@ -762,7 +762,7 @@ static int __init papr_hvpipe_init(void) !rtas_function_implemented(RTAS_FN_IBM_RECEIVE_HVPIPE_MSG)) return -ENODEV; - papr_hvpipe_work = kzalloc(sizeof(struct work_struct), GFP_ATOMIC); + papr_hvpipe_work = kzalloc_obj(struct work_struct, GFP_ATOMIC); if (!papr_hvpipe_work) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/papr-phy-attest.c b/arch/powerpc/platforms/pseries/papr-phy-attest.c index 1907f2411567..20a0e1581302 100644 --- a/arch/powerpc/platforms/pseries/papr-phy-attest.c +++ b/arch/powerpc/platforms/pseries/papr-phy-attest.c @@ -225,7 +225,7 @@ static long papr_phy_attest_create_handle(struct papr_phy_attest_io_block __user /* * Freed in phy_attest_sequence_end(). */ - params = kzalloc(sizeof(*params), GFP_KERNEL_ACCOUNT); + params = kzalloc_obj(*params, GFP_KERNEL_ACCOUNT); if (!params) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/papr-platform-dump.c b/arch/powerpc/platforms/pseries/papr-platform-dump.c index be633c9a0e75..fb7ea84bf98a 100644 --- a/arch/powerpc/platforms/pseries/papr-platform-dump.c +++ b/arch/powerpc/platforms/pseries/papr-platform-dump.c @@ -321,8 +321,8 @@ static long papr_platform_dump_create_handle(u64 dump_tag) } } - params = kzalloc(sizeof(struct ibm_platform_dump_params), - GFP_KERNEL_ACCOUNT); + params = kzalloc_obj(struct ibm_platform_dump_params, + GFP_KERNEL_ACCOUNT); if (!params) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/papr-rtas-common.c b/arch/powerpc/platforms/pseries/papr-rtas-common.c index 1630e0cd210c..6bf4d1f15000 100644 --- a/arch/powerpc/platforms/pseries/papr-rtas-common.c +++ b/arch/powerpc/platforms/pseries/papr-rtas-common.c @@ -83,7 +83,7 @@ papr_rtas_blob_generate(struct papr_rtas_sequence *seq) size_t len; int err = 0; - blob = kzalloc(sizeof(*blob), GFP_KERNEL_ACCOUNT); + blob = kzalloc_obj(*blob, GFP_KERNEL_ACCOUNT); if (!blob) return NULL; diff --git a/arch/powerpc/platforms/pseries/papr-sysparm.c b/arch/powerpc/platforms/pseries/papr-sysparm.c index 7063ce8884e4..fdff151ed8bb 100644 --- a/arch/powerpc/platforms/pseries/papr-sysparm.c +++ b/arch/powerpc/platforms/pseries/papr-sysparm.c @@ -19,7 +19,7 @@ struct papr_sysparm_buf *papr_sysparm_buf_alloc(void) { - struct papr_sysparm_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); + struct papr_sysparm_buf *buf = kzalloc_obj(*buf); return buf; } diff --git a/arch/powerpc/platforms/pseries/papr_platform_attributes.c b/arch/powerpc/platforms/pseries/papr_platform_attributes.c index eea2041b270b..c6159870de0e 100644 --- a/arch/powerpc/platforms/pseries/papr_platform_attributes.c +++ b/arch/powerpc/platforms/pseries/papr_platform_attributes.c @@ -295,7 +295,7 @@ static int __init papr_init(void) goto out_free_esi_buf; } - papr_groups = kcalloc(num_attrs, sizeof(*papr_groups), GFP_KERNEL); + papr_groups = kzalloc_objs(*papr_groups, num_attrs); if (!papr_groups) goto out_free_esi_buf; @@ -313,9 +313,8 @@ static int __init papr_init(void) /* Allocate the groups before registering */ for (idx = 0; idx < num_attrs; idx++) { - papr_groups[idx].pg.attrs = kcalloc(KOBJ_MAX_ATTRS + 1, - sizeof(*papr_groups[idx].pg.attrs), - GFP_KERNEL); + papr_groups[idx].pg.attrs = kzalloc_objs(*papr_groups[idx].pg.attrs, + KOBJ_MAX_ATTRS + 1); if (!papr_groups[idx].pg.attrs) goto out_pgattrs; diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index f7c9271bda58..63eca4ebb5e5 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -445,7 +445,7 @@ static void papr_scm_pmu_register(struct papr_scm_priv *p) struct nvdimm_pmu *nd_pmu; int rc, nodeid; - nd_pmu = kzalloc(sizeof(*nd_pmu), GFP_KERNEL); + nd_pmu = kzalloc_obj(*nd_pmu); if (!nd_pmu) { rc = -ENOMEM; goto pmu_err_print; @@ -1398,7 +1398,7 @@ static int papr_scm_probe(struct platform_device *pdev) */ update_numa_distance(dn); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index 6dbc73eb2ca2..84e4ffe957a8 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -141,9 +141,7 @@ static int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) } pdn = pci_get_pdn(pdev); - pdn->pe_num_map = kmalloc_array(num_vfs, - sizeof(*pdn->pe_num_map), - GFP_KERNEL); + pdn->pe_num_map = kmalloc_objs(*pdn->pe_num_map, num_vfs); if (!pdn->pe_num_map) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c index 599bd2c78514..7faebcffc9df 100644 --- a/arch/powerpc/platforms/pseries/reconfig.c +++ b/arch/powerpc/platforms/pseries/reconfig.c @@ -25,7 +25,7 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist struct device_node *np; int err = -ENOMEM; - np = kzalloc(sizeof(*np), GFP_KERNEL); + np = kzalloc_obj(*np); if (!np) goto out_err; @@ -168,7 +168,7 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length static struct property *new_property(const char *name, const int length, const unsigned char *value, struct property *last) { - struct property *new = kzalloc(sizeof(*new), GFP_KERNEL); + struct property *new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/arch/powerpc/platforms/pseries/vas-sysfs.c b/arch/powerpc/platforms/pseries/vas-sysfs.c index 9e05a0e99cad..4f6fbbb672ae 100644 --- a/arch/powerpc/platforms/pseries/vas-sysfs.c +++ b/arch/powerpc/platforms/pseries/vas-sysfs.c @@ -202,7 +202,7 @@ int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps) int ret = 0; char *name; - centry = kzalloc(sizeof(*centry), GFP_KERNEL); + centry = kzalloc_obj(*centry); if (!centry) return -ENOMEM; diff --git a/arch/powerpc/platforms/pseries/vas.c b/arch/powerpc/platforms/pseries/vas.c index c25eb1a38185..ceb0a8788c0a 100644 --- a/arch/powerpc/platforms/pseries/vas.c +++ b/arch/powerpc/platforms/pseries/vas.c @@ -324,7 +324,7 @@ static struct vas_window *vas_allocate_window(int vas_id, u64 flags, struct pseries_vas_window *txwin; int rc; - txwin = kzalloc(sizeof(*txwin), GFP_KERNEL); + txwin = kzalloc_obj(*txwin); if (!txwin) return ERR_PTR(-ENOMEM); @@ -1087,7 +1087,7 @@ static int __init pseries_vas_init(void) return -ENOTSUPP; } - hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL); + hv_caps = kmalloc_obj(*hv_caps); if (!hv_caps) return -ENOMEM; /* diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 18cffac5468f..08e2add48adb 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -744,8 +744,7 @@ static int vio_cmo_bus_probe(struct vio_dev *viodev) viodev->cmo.desired = VIO_CMO_MIN_ENT; size = VIO_CMO_MIN_ENT; - dev_ent = kmalloc(sizeof(struct vio_cmo_dev_entry), - GFP_KERNEL); + dev_ent = kmalloc_obj(struct vio_cmo_dev_entry); if (!dev_ent) return -ENOMEM; @@ -1165,7 +1164,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) if (!dma_window) return NULL; - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (tbl == NULL) return NULL; @@ -1376,7 +1375,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) } /* allocate a vio_dev for this node */ - viodev = kzalloc(sizeof(struct vio_dev), GFP_KERNEL); + viodev = kzalloc_obj(struct vio_dev); if (viodev == NULL) { pr_warn("%s: allocation failure for VIO device.\n", __func__); return NULL; diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c index b6f9774038e1..02411b0cf46f 100644 --- a/arch/powerpc/sysdev/ehv_pic.c +++ b/arch/powerpc/sysdev/ehv_pic.c @@ -263,7 +263,7 @@ void __init ehv_pic_init(void) return; } - ehv_pic = kzalloc(sizeof(struct ehv_pic), GFP_KERNEL); + ehv_pic = kzalloc_obj(struct ehv_pic); if (!ehv_pic) { of_node_put(np); return; diff --git a/arch/powerpc/sysdev/fsl_gtm.c b/arch/powerpc/sysdev/fsl_gtm.c index 3dabc9621810..87fe47f41a39 100644 --- a/arch/powerpc/sysdev/fsl_gtm.c +++ b/arch/powerpc/sysdev/fsl_gtm.c @@ -382,7 +382,7 @@ static int __init fsl_gtm_init(void) const u32 *clock; int size; - gtm = kzalloc(sizeof(*gtm), GFP_KERNEL); + gtm = kzalloc_obj(*gtm); if (!gtm) { pr_err("%pOF: unable to allocate memory\n", np); diff --git a/arch/powerpc/sysdev/fsl_lbc.c b/arch/powerpc/sysdev/fsl_lbc.c index 7ed07232a69a..839cf5adc7d9 100644 --- a/arch/powerpc/sysdev/fsl_lbc.c +++ b/arch/powerpc/sysdev/fsl_lbc.c @@ -283,7 +283,7 @@ static int fsl_lbc_ctrl_probe(struct platform_device *dev) return -EFAULT; } - fsl_lbc_ctrl_dev = kzalloc(sizeof(*fsl_lbc_ctrl_dev), GFP_KERNEL); + fsl_lbc_ctrl_dev = kzalloc_obj(*fsl_lbc_ctrl_dev); if (!fsl_lbc_ctrl_dev) return -ENOMEM; @@ -363,7 +363,7 @@ static int fsl_lbc_syscore_suspend(void *data) if (!lbc) goto out; - ctrl->saved_regs = kmalloc(sizeof(struct fsl_lbc_regs), GFP_KERNEL); + ctrl->saved_regs = kmalloc_obj(struct fsl_lbc_regs); if (!ctrl->saved_regs) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c index 06d9101a5d49..f9e64f54dc14 100644 --- a/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c +++ b/arch/powerpc/sysdev/fsl_mpic_timer_wakeup.c @@ -111,7 +111,7 @@ static int __init fsl_wakeup_sys_init(void) struct device *dev_root; int ret = -EINVAL; - fsl_wakeup = kzalloc(sizeof(struct fsl_mpic_timer_wakeup), GFP_KERNEL); + fsl_wakeup = kzalloc_obj(struct fsl_mpic_timer_wakeup); if (!fsl_wakeup) return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index 2a007bfb038d..5dbc78713193 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -361,7 +361,7 @@ static int fsl_msi_setup_hwirq(struct fsl_msi *msi, struct platform_device *dev, return 0; } - cascade_data = kzalloc(sizeof(struct fsl_msi_cascade_data), GFP_KERNEL); + cascade_data = kzalloc_obj(struct fsl_msi_cascade_data); if (!cascade_data) { dev_err(&dev->dev, "No memory for MSI cascade data\n"); return -ENOMEM; @@ -405,7 +405,7 @@ static int fsl_of_msi_probe(struct platform_device *dev) printk(KERN_DEBUG "Setting up Freescale MSI support\n"); - msi = kzalloc(sizeof(struct fsl_msi), GFP_KERNEL); + msi = kzalloc_obj(struct fsl_msi); if (!msi) { dev_err(&dev->dev, "No memory for MSI structure\n"); return -ENOMEM; diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c index 4e501654cb41..600f83cea1cd 100644 --- a/arch/powerpc/sysdev/fsl_pci.c +++ b/arch/powerpc/sysdev/fsl_pci.c @@ -767,7 +767,7 @@ static int __init mpc83xx_pcie_setup(struct pci_controller *hose, u32 cfg_bar; int ret = -ENOMEM; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return ret; diff --git a/arch/powerpc/sysdev/fsl_rio.c b/arch/powerpc/sysdev/fsl_rio.c index f9b214b299e7..eb55dabb4748 100644 --- a/arch/powerpc/sysdev/fsl_rio.c +++ b/arch/powerpc/sysdev/fsl_rio.c @@ -470,7 +470,7 @@ static int fsl_rio_setup(struct platform_device *dev) goto err_rio_regs; } - ops = kzalloc(sizeof(struct rio_ops), GFP_KERNEL); + ops = kzalloc_obj(struct rio_ops); if (!ops) { rc = -ENOMEM; goto err_ops; @@ -517,7 +517,7 @@ static int fsl_rio_setup(struct platform_device *dev) rc = -ENODEV; goto err_dbell; } - dbell = kzalloc(sizeof(struct fsl_rio_dbell), GFP_KERNEL); + dbell = kzalloc_obj(struct fsl_rio_dbell); if (!(dbell)) { dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_dbell'\n"); rc = -ENOMEM; @@ -543,7 +543,7 @@ static int fsl_rio_setup(struct platform_device *dev) rc = -ENODEV; goto err_pw; } - pw = kzalloc(sizeof(struct fsl_rio_pw), GFP_KERNEL); + pw = kzalloc_obj(struct fsl_rio_pw); if (!(pw)) { dev_err(&dev->dev, "Can't alloc memory for 'fsl_rio_pw'\n"); rc = -ENOMEM; @@ -580,7 +580,7 @@ static int fsl_rio_setup(struct platform_device *dev) dev_info(&dev->dev, "%pOF: LAW %pR\n", np, &res); - port = kzalloc(sizeof(struct rio_mport), GFP_KERNEL); + port = kzalloc_obj(struct rio_mport); if (!port) continue; @@ -593,7 +593,7 @@ static int fsl_rio_setup(struct platform_device *dev) i = *port_index - 1; port->index = (unsigned char)i; - priv = kzalloc(sizeof(struct rio_priv), GFP_KERNEL); + priv = kzalloc_obj(struct rio_priv); if (!priv) { dev_err(&dev->dev, "Can't alloc memory for 'priv'\n"); kfree(port); diff --git a/arch/powerpc/sysdev/fsl_rmu.c b/arch/powerpc/sysdev/fsl_rmu.c index f956591cb64e..4f2afd021e3c 100644 --- a/arch/powerpc/sysdev/fsl_rmu.c +++ b/arch/powerpc/sysdev/fsl_rmu.c @@ -1079,7 +1079,7 @@ int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node) return -EINVAL; } - rmu = kzalloc(sizeof(struct fsl_rmu), GFP_KERNEL); + rmu = kzalloc_obj(struct fsl_rmu); if (!rmu) return -ENOMEM; diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c index 290ba8427239..77e6f23c5f52 100644 --- a/arch/powerpc/sysdev/ipic.c +++ b/arch/powerpc/sysdev/ipic.c @@ -707,7 +707,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags) if (ret) return NULL; - ipic = kzalloc(sizeof(*ipic), GFP_KERNEL); + ipic = kzalloc_obj(*ipic); if (ipic == NULL) return NULL; diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 67e51998d1ae..257886ec3f70 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -547,7 +547,7 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic) printk(KERN_INFO "mpic: Setting up HT PICs workarounds for U3/U4\n"); /* Allocate fixups array */ - mpic->fixups = kcalloc(128, sizeof(*mpic->fixups), GFP_KERNEL); + mpic->fixups = kzalloc_objs(*mpic->fixups, 128); BUG_ON(mpic->fixups == NULL); /* Init spinlock */ @@ -1273,7 +1273,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic_tm_chip.flags |= IRQCHIP_SKIP_SET_WAKE; } - mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); + mpic = kzalloc_obj(struct mpic); if (mpic == NULL) goto err_of_node_put; @@ -1639,9 +1639,7 @@ void __init mpic_init(struct mpic *mpic) #ifdef CONFIG_PM /* allocate memory to save mpic state */ - mpic->save_data = kmalloc_array(mpic->num_sources, - sizeof(*mpic->save_data), - GFP_KERNEL); + mpic->save_data = kmalloc_objs(*mpic->save_data, mpic->num_sources); BUG_ON(mpic->save_data == NULL); #endif diff --git a/arch/powerpc/sysdev/mpic_msgr.c b/arch/powerpc/sysdev/mpic_msgr.c index 7b449cc51aef..26f62ae5f671 100644 --- a/arch/powerpc/sysdev/mpic_msgr.c +++ b/arch/powerpc/sysdev/mpic_msgr.c @@ -188,8 +188,7 @@ static int mpic_msgr_probe(struct platform_device *dev) dev_info(&dev->dev, "Found %d message registers\n", mpic_msgr_count); - mpic_msgrs = kcalloc(mpic_msgr_count, sizeof(*mpic_msgrs), - GFP_KERNEL); + mpic_msgrs = kzalloc_objs(*mpic_msgrs, mpic_msgr_count); if (!mpic_msgrs) { dev_err(&dev->dev, "No memory for message register blocks\n"); @@ -227,7 +226,7 @@ static int mpic_msgr_probe(struct platform_device *dev) struct mpic_msgr *msgr; unsigned int reg_number; - msgr = kzalloc(sizeof(struct mpic_msgr), GFP_KERNEL); + msgr = kzalloc_obj(struct mpic_msgr); if (!msgr) { dev_err(&dev->dev, "No memory for message register\n"); return -ENOMEM; diff --git a/arch/powerpc/sysdev/mpic_timer.c b/arch/powerpc/sysdev/mpic_timer.c index 60f5b3934b51..10acf9988016 100644 --- a/arch/powerpc/sysdev/mpic_timer.c +++ b/arch/powerpc/sysdev/mpic_timer.c @@ -464,7 +464,7 @@ static void __init timer_group_init(struct device_node *np) unsigned int i = 0; int ret; - priv = kzalloc(sizeof(struct timer_group_priv), GFP_KERNEL); + priv = kzalloc_obj(struct timer_group_priv); if (!priv) { pr_err("%pOF: cannot allocate memory for group.\n", np); return; diff --git a/arch/powerpc/sysdev/of_rtc.c b/arch/powerpc/sysdev/of_rtc.c index 2211937d3788..ab0d6be0fc97 100644 --- a/arch/powerpc/sysdev/of_rtc.c +++ b/arch/powerpc/sysdev/of_rtc.c @@ -33,7 +33,7 @@ void __init of_instantiate_rtc(void) of_rtc_table[i].compatible) { struct resource *res; - res = kmalloc(sizeof(*res), GFP_KERNEL); + res = kmalloc_obj(*res); if (!res) { printk(KERN_ERR "OF RTC: Out of memory " "allocating resource structure for %pOF\n", diff --git a/arch/powerpc/sysdev/xics/ics-native.c b/arch/powerpc/sysdev/xics/ics-native.c index 112c8a1e8159..0b0d07db6998 100644 --- a/arch/powerpc/sysdev/xics/ics-native.c +++ b/arch/powerpc/sysdev/xics/ics-native.c @@ -186,7 +186,7 @@ static int __init ics_native_add_one(struct device_node *np) u32 ranges[2]; int rc, count; - ics = kzalloc(sizeof(struct ics_native), GFP_KERNEL); + ics = kzalloc_obj(struct ics_native); if (!ics) return -ENOMEM; ics->node = of_node_get(np); diff --git a/arch/powerpc/sysdev/xive/common.c b/arch/powerpc/sysdev/xive/common.c index 8d0123b0ae84..e1a4f8a97393 100644 --- a/arch/powerpc/sysdev/xive/common.c +++ b/arch/powerpc/sysdev/xive/common.c @@ -1016,7 +1016,7 @@ static struct xive_irq_data *xive_irq_alloc_data(unsigned int virq, irq_hw_numbe struct xive_irq_data *xd; int rc; - xd = kzalloc(sizeof(struct xive_irq_data), GFP_KERNEL); + xd = kzalloc_obj(struct xive_irq_data); if (!xd) return ERR_PTR(-ENOMEM); rc = xive_ops->populate_irq_data(hw, xd); @@ -1144,7 +1144,8 @@ static int __init xive_init_ipis(void) if (!ipi_domain) goto out_free_fwnode; - xive_ipis = kcalloc(nr_node_ids, sizeof(*xive_ipis), GFP_KERNEL | __GFP_NOFAIL); + xive_ipis = kzalloc_objs(*xive_ipis, nr_node_ids, + GFP_KERNEL | __GFP_NOFAIL); if (!xive_ipis) goto out_free_domain; diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 5aedbe3e8e6a..61f8a8acf81f 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -52,7 +52,7 @@ static int __init xive_irq_bitmap_add(int base, int count) { struct xive_irq_bitmap *xibm; - xibm = kzalloc(sizeof(*xibm), GFP_KERNEL); + xibm = kzalloc_obj(*xibm); if (!xibm) return -ENOMEM; diff --git a/arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh b/arch/powerpc/tools/check-fpatchable-function-entry.sh similarity index 100% rename from arch/powerpc/tools/gcc-check-fpatchable-function-entry.sh rename to arch/powerpc/tools/check-fpatchable-function-entry.sh diff --git a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh index bac186bdf64a..9218d43aeb54 100755 --- a/arch/powerpc/tools/ftrace-gen-ool-stubs.sh +++ b/arch/powerpc/tools/ftrace-gen-ool-stubs.sh @@ -15,9 +15,9 @@ if [ -z "$is_64bit" ]; then RELOCATION=R_PPC_ADDR32 fi -num_ool_stubs_total=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | +num_ool_stubs_total=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | grep -c "$RELOCATION") -num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries "$vmlinux_o" | +num_ool_stubs_inittext=$($objdump -r -j __patchable_function_entries -d "$vmlinux_o" | grep -e ".init.text" -e ".text.startup" | grep -c "$RELOCATION") num_ool_stubs_text=$((num_ool_stubs_total - num_ool_stubs_inittext)) diff --git a/arch/riscv/kernel/hibernate.c b/arch/riscv/kernel/hibernate.c index 671b686c0158..982843828adb 100644 --- a/arch/riscv/kernel/hibernate.c +++ b/arch/riscv/kernel/hibernate.c @@ -415,7 +415,7 @@ int hibernate_resume_nonboot_cpu_disable(void) static int __init riscv_hibernate_init(void) { - hibernate_cpu_context = kzalloc(sizeof(*hibernate_cpu_context), GFP_KERNEL); + hibernate_cpu_context = kzalloc_obj(*hibernate_cpu_context); if (WARN_ON(!hibernate_cpu_context)) return -ENOMEM; diff --git a/arch/riscv/kernel/machine_kexec_file.c b/arch/riscv/kernel/machine_kexec_file.c index dd9d92a96517..54e2d9552e93 100644 --- a/arch/riscv/kernel/machine_kexec_file.c +++ b/arch/riscv/kernel/machine_kexec_file.c @@ -64,7 +64,7 @@ static int prepare_elf_headers(void **addr, unsigned long *sz) nr_ranges = 1; /* For exclusion of crashkernel region */ walk_system_ram_res(0, -1, &nr_ranges, get_nr_ram_ranges_callback); - cmem = kmalloc(struct_size(cmem, ranges, nr_ranges), GFP_KERNEL); + cmem = kmalloc_flex(*cmem, ranges, nr_ranges); if (!cmem) return -ENOMEM; diff --git a/arch/riscv/kernel/module.c b/arch/riscv/kernel/module.c index 7f6147c18033..1961135689db 100644 --- a/arch/riscv/kernel/module.c +++ b/arch/riscv/kernel/module.c @@ -663,7 +663,7 @@ static int add_relocation_to_accumulate(struct module *me, int type, struct used_bucket *bucket; unsigned long hash; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -697,7 +697,7 @@ static int add_relocation_to_accumulate(struct module *me, int type, * relocation_entry. */ if (!found) { - rel_head = kmalloc(sizeof(*rel_head), GFP_KERNEL); + rel_head = kmalloc_obj(*rel_head); if (!rel_head) { kfree(entry); @@ -709,7 +709,7 @@ static int add_relocation_to_accumulate(struct module *me, int type, INIT_HLIST_NODE(&rel_head->node); if (!current_head->first) { bucket = - kmalloc(sizeof(struct used_bucket), GFP_KERNEL); + kmalloc_obj(struct used_bucket); if (!bucket) { kfree(entry); @@ -753,9 +753,8 @@ initialize_relocation_hashtable(unsigned int num_relocations, hashtable_size <<= should_double_size; /* Number of relocations may be large, so kvmalloc it */ - *relocation_hashtable = kvmalloc_array(hashtable_size, - sizeof(**relocation_hashtable), - GFP_KERNEL); + *relocation_hashtable = kvmalloc_objs(**relocation_hashtable, + hashtable_size); if (!*relocation_hashtable) return 0; diff --git a/arch/riscv/kernel/tests/kprobes/test-kprobes.c b/arch/riscv/kernel/tests/kprobes/test-kprobes.c index 664535ca0a98..027424a3ff7b 100644 --- a/arch/riscv/kernel/tests/kprobes/test-kprobes.c +++ b/arch/riscv/kernel/tests/kprobes/test-kprobes.c @@ -20,7 +20,7 @@ static void test_kprobe_riscv(struct kunit *test) while (test_kprobes_addresses[num_kprobe]) num_kprobe++; - kp = kcalloc(num_kprobe, sizeof(*kp), GFP_KERNEL); + kp = kzalloc_objs(*kp, num_kprobe); KUNIT_EXPECT_TRUE(test, kp); if (!kp) return; diff --git a/arch/riscv/kernel/unaligned_access_speed.c b/arch/riscv/kernel/unaligned_access_speed.c index 70b5e6927620..b36a6a56f404 100644 --- a/arch/riscv/kernel/unaligned_access_speed.c +++ b/arch/riscv/kernel/unaligned_access_speed.c @@ -139,7 +139,7 @@ static void __init check_unaligned_access_speed_all_cpus(void) { unsigned int cpu; unsigned int cpu_count = num_possible_cpus(); - struct page **bufs = kcalloc(cpu_count, sizeof(*bufs), GFP_KERNEL); + struct page **bufs = kzalloc_objs(*bufs, cpu_count); if (!bufs) { pr_warn("Allocation failure, not measuring misaligned performance\n"); diff --git a/arch/riscv/kernel/vdso.c b/arch/riscv/kernel/vdso.c index 43f70198ac3c..9c2f5e442338 100644 --- a/arch/riscv/kernel/vdso.c +++ b/arch/riscv/kernel/vdso.c @@ -55,9 +55,7 @@ static void __init __vdso_init(struct __vdso_info *vdso_info) vdso_info->vdso_code_start) >> PAGE_SHIFT; - vdso_pagelist = kcalloc(vdso_info->vdso_pages, - sizeof(struct page *), - GFP_KERNEL); + vdso_pagelist = kzalloc_objs(struct page *, vdso_info->vdso_pages); if (vdso_pagelist == NULL) panic("vDSO kcalloc failed!\n"); diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 61bd5ba6680a..997f9eb3b22b 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -170,6 +170,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS .riscv.attributes 0 : { *(.riscv.attributes) } diff --git a/arch/riscv/kvm/Kconfig b/arch/riscv/kvm/Kconfig index 77379f77840a..ec2cee0a39e0 100644 --- a/arch/riscv/kvm/Kconfig +++ b/arch/riscv/kvm/Kconfig @@ -30,7 +30,6 @@ config KVM select KVM_GENERIC_HARDWARE_ENABLING select KVM_MMIO select VIRT_XFER_TO_GUEST_WORK - select KVM_GENERIC_MMU_NOTIFIER select SCHED_INFO select GUEST_PERF_EVENTS if PERF_EVENTS help diff --git a/arch/riscv/kvm/aia.c b/arch/riscv/kvm/aia.c index cac3c2b51d72..5ec503288555 100644 --- a/arch/riscv/kvm/aia.c +++ b/arch/riscv/kvm/aia.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -182,9 +183,14 @@ int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu, unsigned long *out_val) { struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long)) + if (!riscv_isa_extension_available(vcpu->arch.isa, SSAIA)) return -ENOENT; + if (reg_num >= regs_max) + return -ENOENT; + + reg_num = array_index_nospec(reg_num, regs_max); *out_val = 0; if (kvm_riscv_aia_available()) @@ -198,9 +204,14 @@ int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu, unsigned long val) { struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long)) + if (!riscv_isa_extension_available(vcpu->arch.isa, SSAIA)) return -ENOENT; + if (reg_num >= regs_max) + return -ENOENT; + + reg_num = array_index_nospec(reg_num, regs_max); if (kvm_riscv_aia_available()) { ((unsigned long *)csr)[reg_num] = val; diff --git a/arch/riscv/kvm/aia_aplic.c b/arch/riscv/kvm/aia_aplic.c index f59d1c0c8c43..3464f3351df7 100644 --- a/arch/riscv/kvm/aia_aplic.c +++ b/arch/riscv/kvm/aia_aplic.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,7 @@ static u32 aplic_read_sourcecfg(struct aplic *aplic, u32 irq) if (!irq || aplic->nr_irqs <= irq) return 0; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); ret = irqd->sourcecfg; @@ -61,7 +62,7 @@ static void aplic_write_sourcecfg(struct aplic *aplic, u32 irq, u32 val) if (!irq || aplic->nr_irqs <= irq) return; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; if (val & APLIC_SOURCECFG_D) val = 0; @@ -81,7 +82,7 @@ static u32 aplic_read_target(struct aplic *aplic, u32 irq) if (!irq || aplic->nr_irqs <= irq) return 0; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); ret = irqd->target; @@ -97,7 +98,7 @@ static void aplic_write_target(struct aplic *aplic, u32 irq, u32 val) if (!irq || aplic->nr_irqs <= irq) return; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; val &= APLIC_TARGET_EIID_MASK | (APLIC_TARGET_HART_IDX_MASK << APLIC_TARGET_HART_IDX_SHIFT) | @@ -116,7 +117,7 @@ static bool aplic_read_pending(struct aplic *aplic, u32 irq) if (!irq || aplic->nr_irqs <= irq) return false; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); ret = (irqd->state & APLIC_IRQ_STATE_PENDING) ? true : false; @@ -132,7 +133,7 @@ static void aplic_write_pending(struct aplic *aplic, u32 irq, bool pending) if (!irq || aplic->nr_irqs <= irq) return; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); @@ -170,7 +171,7 @@ static bool aplic_read_enabled(struct aplic *aplic, u32 irq) if (!irq || aplic->nr_irqs <= irq) return false; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); ret = (irqd->state & APLIC_IRQ_STATE_ENABLED) ? true : false; @@ -186,7 +187,7 @@ static void aplic_write_enabled(struct aplic *aplic, u32 irq, bool enabled) if (!irq || aplic->nr_irqs <= irq) return; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); if (enabled) @@ -205,7 +206,7 @@ static bool aplic_read_input(struct aplic *aplic, u32 irq) if (!irq || aplic->nr_irqs <= irq) return false; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); @@ -254,7 +255,7 @@ static void aplic_update_irq_range(struct kvm *kvm, u32 first, u32 last) for (irq = first; irq <= last; irq++) { if (!irq || aplic->nr_irqs <= irq) continue; - irqd = &aplic->irqs[irq]; + irqd = &aplic->irqs[array_index_nospec(irq, aplic->nr_irqs)]; raw_spin_lock_irqsave(&irqd->lock, flags); @@ -283,7 +284,7 @@ int kvm_riscv_aia_aplic_inject(struct kvm *kvm, u32 source, bool level) if (!aplic || !source || (aplic->nr_irqs <= source)) return -ENODEV; - irqd = &aplic->irqs[source]; + irqd = &aplic->irqs[array_index_nospec(source, aplic->nr_irqs)]; ie = (aplic->domaincfg & APLIC_DOMAINCFG_IE) ? true : false; raw_spin_lock_irqsave(&irqd->lock, flags); @@ -580,7 +581,7 @@ int kvm_riscv_aia_aplic_init(struct kvm *kvm) return 0; /* Allocate APLIC global state */ - aplic = kzalloc(sizeof(*aplic), GFP_KERNEL); + aplic = kzalloc_obj(*aplic); if (!aplic) return -ENOMEM; kvm->arch.aia.aplic_state = aplic; @@ -588,8 +589,7 @@ int kvm_riscv_aia_aplic_init(struct kvm *kvm) /* Setup APLIC IRQs */ aplic->nr_irqs = kvm->arch.aia.nr_sources + 1; aplic->nr_words = DIV_ROUND_UP(aplic->nr_irqs, 32); - aplic->irqs = kcalloc(aplic->nr_irqs, - sizeof(*aplic->irqs), GFP_KERNEL); + aplic->irqs = kzalloc_objs(*aplic->irqs, aplic->nr_irqs); if (!aplic->irqs) { ret = -ENOMEM; goto fail_free_aplic; diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c index b195a93add1c..49c71d3cdb00 100644 --- a/arch/riscv/kvm/aia_device.c +++ b/arch/riscv/kvm/aia_device.c @@ -11,6 +11,7 @@ #include #include #include +#include static int aia_create(struct kvm_device *dev, u32 type) { @@ -22,6 +23,9 @@ static int aia_create(struct kvm_device *dev, u32 type) if (irqchip_in_kernel(kvm)) return -EEXIST; + if (!riscv_isa_extension_available(NULL, SSAIA)) + return -ENODEV; + ret = -EBUSY; if (kvm_trylock_all_vcpus(kvm)) return ret; @@ -437,7 +441,7 @@ static int aia_get_attr(struct kvm_device *dev, struct kvm_device_attr *attr) static int aia_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { - int nr_vcpus; + int nr_vcpus, r = -ENXIO; switch (attr->group) { case KVM_DEV_RISCV_AIA_GRP_CONFIG: @@ -466,12 +470,18 @@ static int aia_has_attr(struct kvm_device *dev, struct kvm_device_attr *attr) } break; case KVM_DEV_RISCV_AIA_GRP_APLIC: - return kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr); + mutex_lock(&dev->kvm->lock); + r = kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr); + mutex_unlock(&dev->kvm->lock); + break; case KVM_DEV_RISCV_AIA_GRP_IMSIC: - return kvm_riscv_aia_imsic_has_attr(dev->kvm, attr->attr); + mutex_lock(&dev->kvm->lock); + r = kvm_riscv_aia_imsic_has_attr(dev->kvm, attr->attr); + mutex_unlock(&dev->kvm->lock); + break; } - return -ENXIO; + return r; } struct kvm_device_ops kvm_riscv_aia_device_ops = { diff --git a/arch/riscv/kvm/aia_imsic.c b/arch/riscv/kvm/aia_imsic.c index 60da5fa155a6..8786f52cf65a 100644 --- a/arch/riscv/kvm/aia_imsic.c +++ b/arch/riscv/kvm/aia_imsic.c @@ -908,6 +908,10 @@ int kvm_riscv_vcpu_aia_imsic_rmw(struct kvm_vcpu *vcpu, unsigned long isel, int r, rc = KVM_INSN_CONTINUE_NEXT_SEPC; struct imsic *imsic = vcpu->arch.aia_context.imsic_state; + /* If IMSIC vCPU state not initialized then forward to user space */ + if (!imsic) + return KVM_INSN_EXIT_TO_USER_SPACE; + if (isel == KVM_RISCV_AIA_IMSIC_TOPEI) { /* Read pending and enabled interrupt with highest priority */ topei = imsic_mrif_topei(imsic->swfile, imsic->nr_eix, @@ -1095,7 +1099,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu) return -EINVAL; /* Allocate IMSIC context */ - imsic = kzalloc(sizeof(*imsic), GFP_KERNEL); + imsic = kzalloc_obj(*imsic); if (!imsic) return -ENOMEM; vcpu->arch.aia_context.imsic_state = imsic; diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c index 0b75eb2a1820..088d33ba90ed 100644 --- a/arch/riscv/kvm/mmu.c +++ b/arch/riscv/kvm/mmu.c @@ -245,6 +245,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) { struct kvm_gstage gstage; + bool mmu_locked; if (!kvm->arch.pgd) return false; @@ -253,9 +254,12 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) gstage.flags = 0; gstage.vmid = READ_ONCE(kvm->arch.vmid.vmid); gstage.pgd = kvm->arch.pgd; + mmu_locked = spin_trylock(&kvm->mmu_lock); kvm_riscv_gstage_unmap_range(&gstage, range->start << PAGE_SHIFT, (range->end - range->start) << PAGE_SHIFT, range->may_block); + if (mmu_locked) + spin_unlock(&kvm->mmu_lock); return false; } @@ -535,7 +539,7 @@ int kvm_riscv_mmu_map(struct kvm_vcpu *vcpu, struct kvm_memory_slot *memslot, goto out_unlock; /* Check if we are backed by a THP and thus use block mapping if possible */ - if (vma_pagesize == PAGE_SIZE) + if (!logging && (vma_pagesize == PAGE_SIZE)) vma_pagesize = transparent_hugepage_adjust(kvm, memslot, hva, &hfn, &gpa); if (writable) { diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index a55a95da54d0..fdd99ac1e714 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -24,7 +24,7 @@ #define CREATE_TRACE_POINTS #include "trace.h" -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, ecall_exit_stat), STATS_DESC_COUNTER(VCPU, wfi_exit_stat), diff --git a/arch/riscv/kvm/vcpu_fp.c b/arch/riscv/kvm/vcpu_fp.c index 030904d82b58..bd5a9e7e7165 100644 --- a/arch/riscv/kvm/vcpu_fp.c +++ b/arch/riscv/kvm/vcpu_fp.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -93,9 +94,11 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu, if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr)) reg_val = &cntx->fp.f.fcsr; else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) && - reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) + reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) { + reg_num = array_index_nospec(reg_num, + ARRAY_SIZE(cntx->fp.f.f)); reg_val = &cntx->fp.f.f[reg_num]; - else + } else return -ENOENT; } else if ((rtype == KVM_REG_RISCV_FP_D) && riscv_isa_extension_available(vcpu->arch.isa, d)) { @@ -107,6 +110,8 @@ int kvm_riscv_vcpu_get_reg_fp(struct kvm_vcpu *vcpu, reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) { if (KVM_REG_SIZE(reg->id) != sizeof(u64)) return -EINVAL; + reg_num = array_index_nospec(reg_num, + ARRAY_SIZE(cntx->fp.d.f)); reg_val = &cntx->fp.d.f[reg_num]; } else return -ENOENT; @@ -138,9 +143,11 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu, if (reg_num == KVM_REG_RISCV_FP_F_REG(fcsr)) reg_val = &cntx->fp.f.fcsr; else if ((KVM_REG_RISCV_FP_F_REG(f[0]) <= reg_num) && - reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) + reg_num <= KVM_REG_RISCV_FP_F_REG(f[31])) { + reg_num = array_index_nospec(reg_num, + ARRAY_SIZE(cntx->fp.f.f)); reg_val = &cntx->fp.f.f[reg_num]; - else + } else return -ENOENT; } else if ((rtype == KVM_REG_RISCV_FP_D) && riscv_isa_extension_available(vcpu->arch.isa, d)) { @@ -152,6 +159,8 @@ int kvm_riscv_vcpu_set_reg_fp(struct kvm_vcpu *vcpu, reg_num <= KVM_REG_RISCV_FP_D_REG(f[31])) { if (KVM_REG_SIZE(reg->id) != sizeof(u64)) return -EINVAL; + reg_num = array_index_nospec(reg_num, + ARRAY_SIZE(cntx->fp.d.f)); reg_val = &cntx->fp.d.f[reg_num]; } else return -ENOENT; diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index e7ab6cb00646..45ecc0082e90 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -127,6 +128,7 @@ static int kvm_riscv_vcpu_isa_check_host(unsigned long kvm_ext, unsigned long *g kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr)) return -ENOENT; + kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr)); *guest_ext = kvm_isa_ext_arr[kvm_ext]; switch (*guest_ext) { case RISCV_ISA_EXT_SMNPM: @@ -443,13 +445,16 @@ static int kvm_riscv_vcpu_get_reg_core(struct kvm_vcpu *vcpu, unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_RISCV_CORE); + unsigned long regs_max = sizeof(struct kvm_riscv_core) / sizeof(unsigned long); unsigned long reg_val; if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long)) return -EINVAL; - if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long)) + if (reg_num >= regs_max) return -ENOENT; + reg_num = array_index_nospec(reg_num, regs_max); + if (reg_num == KVM_REG_RISCV_CORE_REG(regs.pc)) reg_val = cntx->sepc; else if (KVM_REG_RISCV_CORE_REG(regs.pc) < reg_num && @@ -476,13 +481,16 @@ static int kvm_riscv_vcpu_set_reg_core(struct kvm_vcpu *vcpu, unsigned long reg_num = reg->id & ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_RISCV_CORE); + unsigned long regs_max = sizeof(struct kvm_riscv_core) / sizeof(unsigned long); unsigned long reg_val; if (KVM_REG_SIZE(reg->id) != sizeof(unsigned long)) return -EINVAL; - if (reg_num >= sizeof(struct kvm_riscv_core) / sizeof(unsigned long)) + if (reg_num >= regs_max) return -ENOENT; + reg_num = array_index_nospec(reg_num, regs_max); + if (copy_from_user(®_val, uaddr, KVM_REG_SIZE(reg->id))) return -EFAULT; @@ -507,10 +515,13 @@ static int kvm_riscv_vcpu_general_get_csr(struct kvm_vcpu *vcpu, unsigned long *out_val) { struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long)) + if (reg_num >= regs_max) return -ENOENT; + reg_num = array_index_nospec(reg_num, regs_max); + if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) { kvm_riscv_vcpu_flush_interrupts(vcpu); *out_val = (csr->hvip >> VSIP_TO_HVIP_SHIFT) & VSIP_VALID_MASK; @@ -526,10 +537,13 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu, unsigned long reg_val) { struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_csr) / sizeof(unsigned long)) + if (reg_num >= regs_max) return -ENOENT; + reg_num = array_index_nospec(reg_num, regs_max); + if (reg_num == KVM_REG_RISCV_CSR_REG(sip)) { reg_val &= VSIP_VALID_MASK; reg_val <<= VSIP_TO_HVIP_SHIFT; @@ -548,10 +562,15 @@ static inline int kvm_riscv_vcpu_smstateen_set_csr(struct kvm_vcpu *vcpu, unsigned long reg_val) { struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / - sizeof(unsigned long)) - return -EINVAL; + if (!riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) + return -ENOENT; + if (reg_num >= regs_max) + return -ENOENT; + + reg_num = array_index_nospec(reg_num, regs_max); ((unsigned long *)csr)[reg_num] = reg_val; return 0; @@ -562,10 +581,15 @@ static int kvm_riscv_vcpu_smstateen_get_csr(struct kvm_vcpu *vcpu, unsigned long *out_val) { struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + unsigned long regs_max = sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long); - if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / - sizeof(unsigned long)) - return -EINVAL; + if (!riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) + return -ENOENT; + if (reg_num >= regs_max) + return -ENOENT; + + reg_num = array_index_nospec(reg_num, regs_max); *out_val = ((unsigned long *)csr)[reg_num]; return 0; @@ -595,10 +619,7 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val); break; case KVM_REG_RISCV_CSR_SMSTATEEN: - rc = -EINVAL; - if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) - rc = kvm_riscv_vcpu_smstateen_get_csr(vcpu, reg_num, - ®_val); + rc = kvm_riscv_vcpu_smstateen_get_csr(vcpu, reg_num, ®_val); break; default: rc = -ENOENT; @@ -640,10 +661,7 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu, rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val); break; case KVM_REG_RISCV_CSR_SMSTATEEN: - rc = -EINVAL; - if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) - rc = kvm_riscv_vcpu_smstateen_set_csr(vcpu, reg_num, - reg_val); + rc = kvm_riscv_vcpu_smstateen_set_csr(vcpu, reg_num, reg_val); break; default: rc = -ENOENT; diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c index 4d8d5e9aa53d..e873430e596b 100644 --- a/arch/riscv/kvm/vcpu_pmu.c +++ b/arch/riscv/kvm/vcpu_pmu.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -87,7 +88,8 @@ static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc) static u64 kvm_pmu_get_perf_event_hw_config(u32 sbi_event_code) { - return hw_event_perf_map[sbi_event_code]; + return hw_event_perf_map[array_index_nospec(sbi_event_code, + SBI_PMU_HW_GENERAL_MAX)]; } static u64 kvm_pmu_get_perf_event_cache_config(u32 sbi_event_code) @@ -218,6 +220,7 @@ static int pmu_fw_ctr_read_hi(struct kvm_vcpu *vcpu, unsigned long cidx, return -EINVAL; } + cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS); pmc = &kvpmu->pmc[cidx]; if (pmc->cinfo.type != SBI_PMU_CTR_TYPE_FW) @@ -244,6 +247,7 @@ static int pmu_ctr_read(struct kvm_vcpu *vcpu, unsigned long cidx, return -EINVAL; } + cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS); pmc = &kvpmu->pmc[cidx]; if (pmc->cinfo.type == SBI_PMU_CTR_TYPE_FW) { @@ -520,11 +524,12 @@ int kvm_riscv_vcpu_pmu_ctr_info(struct kvm_vcpu *vcpu, unsigned long cidx, { struct kvm_pmu *kvpmu = vcpu_to_pmu(vcpu); - if (cidx > RISCV_KVM_MAX_COUNTERS || cidx == 1) { + if (cidx >= RISCV_KVM_MAX_COUNTERS || cidx == 1) { retdata->err_val = SBI_ERR_INVALID_PARAM; return 0; } + cidx = array_index_nospec(cidx, RISCV_KVM_MAX_COUNTERS); retdata->out_val = kvpmu->pmc[cidx].cinfo.value; return 0; @@ -559,7 +564,8 @@ int kvm_riscv_vcpu_pmu_ctr_start(struct kvm_vcpu *vcpu, unsigned long ctr_base, } /* Start the counters that have been configured and requested by the guest */ for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) { - pmc_index = i + ctr_base; + pmc_index = array_index_nospec(i + ctr_base, + RISCV_KVM_MAX_COUNTERS); if (!test_bit(pmc_index, kvpmu->pmc_in_use)) continue; /* The guest started the counter again. Reset the overflow status */ @@ -630,7 +636,8 @@ int kvm_riscv_vcpu_pmu_ctr_stop(struct kvm_vcpu *vcpu, unsigned long ctr_base, /* Stop the counters that have been configured and requested by the guest */ for_each_set_bit(i, &ctr_mask, RISCV_MAX_COUNTERS) { - pmc_index = i + ctr_base; + pmc_index = array_index_nospec(i + ctr_base, + RISCV_KVM_MAX_COUNTERS); if (!test_bit(pmc_index, kvpmu->pmc_in_use)) continue; pmc = &kvpmu->pmc[pmc_index]; @@ -761,6 +768,7 @@ int kvm_riscv_vcpu_pmu_ctr_cfg_match(struct kvm_vcpu *vcpu, unsigned long ctr_ba } } + ctr_idx = array_index_nospec(ctr_idx, RISCV_KVM_MAX_COUNTERS); pmc = &kvpmu->pmc[ctr_idx]; pmc->idx = ctr_idx; diff --git a/arch/riscv/kvm/vcpu_sbi_fwft.c b/arch/riscv/kvm/vcpu_sbi_fwft.c index 62cc9c3d5759..2eab15339694 100644 --- a/arch/riscv/kvm/vcpu_sbi_fwft.c +++ b/arch/riscv/kvm/vcpu_sbi_fwft.c @@ -352,8 +352,8 @@ static int kvm_sbi_ext_fwft_init(struct kvm_vcpu *vcpu) struct kvm_sbi_fwft_config *conf; int i; - fwft->configs = kcalloc(ARRAY_SIZE(features), sizeof(struct kvm_sbi_fwft_config), - GFP_KERNEL); + fwft->configs = kzalloc_objs(struct kvm_sbi_fwft_config, + ARRAY_SIZE(features)); if (!fwft->configs) return -ENOMEM; diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c index 66d91ae6e9b2..13c63ae1a78b 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c @@ -13,7 +13,7 @@ #include #include -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS() }; static_assert(ARRAY_SIZE(kvm_vm_stats_desc) == @@ -95,7 +95,7 @@ int kvm_riscv_setup_default_irq_routing(struct kvm *kvm, u32 lines) struct kvm_irq_routing_entry *ents; int i, rc; - ents = kcalloc(lines, sizeof(*ents), GFP_KERNEL); + ents = kzalloc_objs(*ents, lines); if (!ents) return -ENOMEM; @@ -181,7 +181,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) break; case KVM_CAP_IOEVENTFD: case KVM_CAP_USER_MEMORY: - case KVM_CAP_SYNC_MMU: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: case KVM_CAP_ONE_REG: case KVM_CAP_READONLY_MEM: diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 37888abee70c..2f1109dbf105 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -926,6 +926,14 @@ static void restore_stack_args(int nr_stack_args, int args_off, int stk_arg_off, } } +static void emit_store_stack_imm64(u8 reg, int stack_off, u64 imm64, + struct rv_jit_context *ctx) +{ + /* Load imm64 into reg and store it at [FP + stack_off]. */ + emit_imm(reg, (s64)imm64, ctx); + emit_sd(RV_REG_FP, stack_off, reg, ctx); +} + static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_off, int run_ctx_off, bool save_ret, struct rv_jit_context *ctx) { @@ -933,12 +941,10 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of struct bpf_prog *p = l->link.prog; int cookie_off = offsetof(struct bpf_tramp_run_ctx, bpf_cookie); - if (l->cookie) { - emit_imm(RV_REG_T1, l->cookie, ctx); - emit_sd(RV_REG_FP, -run_ctx_off + cookie_off, RV_REG_T1, ctx); - } else { + if (l->cookie) + emit_store_stack_imm64(RV_REG_T1, -run_ctx_off + cookie_off, l->cookie, ctx); + else emit_sd(RV_REG_FP, -run_ctx_off + cookie_off, RV_REG_ZERO, ctx); - } /* arg1: prog */ emit_imm(RV_REG_A0, (const s64)p, ctx); @@ -990,6 +996,29 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of return ret; } +static int invoke_bpf(struct bpf_tramp_links *tl, int args_off, int retval_off, + int run_ctx_off, int func_meta_off, bool save_ret, u64 func_meta, + int cookie_off, struct rv_jit_context *ctx) +{ + int i, cur_cookie = (cookie_off - args_off) / 8; + + for (i = 0; i < tl->nr_links; i++) { + int err; + + if (bpf_prog_calls_session_cookie(tl->links[i])) { + u64 meta = func_meta | ((u64)cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT); + + emit_store_stack_imm64(RV_REG_T1, -func_meta_off, meta, ctx); + cur_cookie--; + } + err = invoke_bpf_prog(tl->links[i], args_off, retval_off, run_ctx_off, + save_ret, ctx); + if (err) + return err; + } + return 0; +} + static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, const struct btf_func_model *m, struct bpf_tramp_links *tlinks, @@ -999,13 +1028,15 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, int i, ret, offset; int *branches_off = NULL; int stack_size = 0, nr_arg_slots = 0; - int retval_off, args_off, nregs_off, ip_off, run_ctx_off, sreg_off, stk_arg_off; + int retval_off, args_off, func_meta_off, ip_off, run_ctx_off, sreg_off, stk_arg_off; + int cookie_off, cookie_cnt; struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY]; struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT]; struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN]; bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT; void *orig_call = func_addr; bool save_ret; + u64 func_meta; u32 insn; /* Two types of generated trampoline stack layout: @@ -1036,10 +1067,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, * [ ... ] * FP - args_off [ arg1 ] * - * FP - nregs_off [ regs count ] + * FP - func_meta_off [ regs count, etc ] * * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG * + * [ stack cookie N ] + * [ ... ] + * FP - cookie_off [ stack cookie 1 ] + * * FP - run_ctx_off [ bpf_tramp_run_ctx ] * * FP - sreg_off [ callee saved reg ] @@ -1071,14 +1106,20 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, stack_size += nr_arg_slots * 8; args_off = stack_size; + /* function metadata, such as regs count */ stack_size += 8; - nregs_off = stack_size; + func_meta_off = stack_size; if (flags & BPF_TRAMP_F_IP_ARG) { stack_size += 8; ip_off = stack_size; } + cookie_cnt = bpf_fsession_cookie_cnt(tlinks); + /* room for session cookies */ + stack_size += cookie_cnt * 8; + cookie_off = stack_size; + stack_size += round_up(sizeof(struct bpf_tramp_run_ctx), 8); run_ctx_off = stack_size; @@ -1123,16 +1164,22 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, emit_sd(RV_REG_FP, -sreg_off, RV_REG_S1, ctx); /* store ip address of the traced function */ - if (flags & BPF_TRAMP_F_IP_ARG) { - emit_imm(RV_REG_T1, (const s64)func_addr, ctx); - emit_sd(RV_REG_FP, -ip_off, RV_REG_T1, ctx); - } + if (flags & BPF_TRAMP_F_IP_ARG) + emit_store_stack_imm64(RV_REG_T1, -ip_off, (u64)func_addr, ctx); - emit_li(RV_REG_T1, nr_arg_slots, ctx); - emit_sd(RV_REG_FP, -nregs_off, RV_REG_T1, ctx); + func_meta = nr_arg_slots; + emit_store_stack_imm64(RV_REG_T1, -func_meta_off, func_meta, ctx); store_args(nr_arg_slots, args_off, ctx); + if (bpf_fsession_cnt(tlinks)) { + /* clear all session cookies' value */ + for (i = 0; i < cookie_cnt; i++) + emit_sd(RV_REG_FP, -cookie_off + 8 * i, RV_REG_ZERO, ctx); + /* clear return value to make sure fentry always get 0 */ + emit_sd(RV_REG_FP, -retval_off, RV_REG_ZERO, ctx); + } + if (flags & BPF_TRAMP_F_CALL_ORIG) { emit_imm(RV_REG_A0, ctx->insns ? (const s64)im : RV_MAX_COUNT_IMM, ctx); ret = emit_call((const u64)__bpf_tramp_enter, true, ctx); @@ -1140,15 +1187,15 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, return ret; } - for (i = 0; i < fentry->nr_links; i++) { - ret = invoke_bpf_prog(fentry->links[i], args_off, retval_off, run_ctx_off, - flags & BPF_TRAMP_F_RET_FENTRY_RET, ctx); + if (fentry->nr_links) { + ret = invoke_bpf(fentry, args_off, retval_off, run_ctx_off, func_meta_off, + flags & BPF_TRAMP_F_RET_FENTRY_RET, func_meta, cookie_off, ctx); if (ret) return ret; } if (fmod_ret->nr_links) { - branches_off = kcalloc(fmod_ret->nr_links, sizeof(int), GFP_KERNEL); + branches_off = kzalloc_objs(int, fmod_ret->nr_links); if (!branches_off) return -ENOMEM; @@ -1189,9 +1236,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, *(u32 *)(ctx->insns + branches_off[i]) = insn; } - for (i = 0; i < fexit->nr_links; i++) { - ret = invoke_bpf_prog(fexit->links[i], args_off, retval_off, - run_ctx_off, false, ctx); + /* set "is_return" flag for fsession */ + func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT); + if (bpf_fsession_cnt(tlinks)) + emit_store_stack_imm64(RV_REG_T1, -func_meta_off, func_meta, ctx); + + if (fexit->nr_links) { + ret = invoke_bpf(fexit, args_off, retval_off, run_ctx_off, func_meta_off, + false, func_meta, cookie_off, ctx); if (ret) goto out; } @@ -2091,3 +2143,8 @@ bool bpf_jit_inlines_helper_call(s32 imm) return false; } } + +bool bpf_jit_supports_fsession(void) +{ + return true; +} diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c index f6ca5cfa6b2f..b3581e926436 100644 --- a/arch/riscv/net/bpf_jit_core.c +++ b/arch/riscv/net/bpf_jit_core.c @@ -63,7 +63,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; @@ -82,7 +82,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena); ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena); ctx->prog = prog; - ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); + ctx->offset = kzalloc_objs(int, prog->len); if (!ctx->offset) { prog = orig_prog; goto out_offset; diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c2c7bf974397..edc927d9e85a 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -279,6 +279,7 @@ config S390 select SPARSE_IRQ select SWIOTLB select SYSCTL_EXCEPTION_TRACE + select SYSTEM_DATA_VERIFICATION if KEXEC_SIG select THREAD_INFO_IN_TASK select TRACE_IRQFLAGS_SUPPORT select TTY @@ -313,7 +314,7 @@ config ARCH_SUPPORTS_KEXEC_FILE def_bool y config ARCH_SUPPORTS_KEXEC_SIG - def_bool MODULE_SIG_FORMAT + def_bool y config ARCH_SUPPORTS_KEXEC_PURGATORY def_bool y diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index feb43db63f30..edbedbb2a773 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -140,7 +140,7 @@ int appldata_diag(char record_nr, u16 function, unsigned long buffer, struct appldata_product_id *id; int rc; - parm_list = kmalloc(sizeof(*parm_list), GFP_KERNEL); + parm_list = kmalloc_obj(*parm_list); id = kmemdup(&appldata_id, sizeof(appldata_id), GFP_KERNEL); rc = -ENOMEM; if (parm_list && id) { @@ -350,7 +350,7 @@ int appldata_register_ops(struct appldata_ops *ops) if (ops->size > APPLDATA_MAX_REC_SIZE) return -EINVAL; - ops->ctl_table = kcalloc(1, sizeof(struct ctl_table), GFP_KERNEL); + ops->ctl_table = kzalloc_objs(struct ctl_table, 1); if (!ops->ctl_table) return -ENOMEM; diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index fc608f9b79ab..659af5545a38 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -130,7 +130,7 @@ static int __init appldata_mem_init(void) { int ret; - ops.data = kzalloc(sizeof(struct appldata_mem_data), GFP_KERNEL); + ops.data = kzalloc_obj(struct appldata_mem_data); if (!ops.data) return -ENOMEM; diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index 59c282ca002f..972f6d592c32 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/arch/s390/appldata/appldata_net_sum.c @@ -132,7 +132,7 @@ static int __init appldata_net_init(void) { int ret; - ops.data = kzalloc(sizeof(struct appldata_net_sum_data), GFP_KERNEL); + ops.data = kzalloc_obj(struct appldata_net_sum_data); if (!ops.data) return -ENOMEM; diff --git a/arch/s390/hypfs/hypfs_dbfs.c b/arch/s390/hypfs/hypfs_dbfs.c index 41a0d2066fa0..25a59c048857 100644 --- a/arch/s390/hypfs/hypfs_dbfs.c +++ b/arch/s390/hypfs/hypfs_dbfs.c @@ -16,7 +16,7 @@ static struct hypfs_dbfs_data *hypfs_dbfs_data_alloc(struct hypfs_dbfs_file *f) { struct hypfs_dbfs_data *data; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return NULL; data->dbfs_file = f; diff --git a/arch/s390/hypfs/hypfs_diag0c.c b/arch/s390/hypfs/hypfs_diag0c.c index 61220e717af0..8f726e6558a8 100644 --- a/arch/s390/hypfs/hypfs_diag0c.c +++ b/arch/s390/hypfs/hypfs_diag0c.c @@ -35,13 +35,12 @@ static void *diag0c_store(unsigned int *count) cpus_read_lock(); cpu_count = num_online_cpus(); - cpu_vec = kmalloc_array(num_possible_cpus(), sizeof(*cpu_vec), - GFP_KERNEL); + cpu_vec = kmalloc_objs(*cpu_vec, num_possible_cpus()); if (!cpu_vec) goto fail_unlock_cpus; /* Note: Diag 0c needs 8 byte alignment and real storage */ - diag0c_data = kzalloc(struct_size(diag0c_data, entry, cpu_count), - GFP_KERNEL | GFP_DMA); + diag0c_data = kzalloc_flex(*diag0c_data, entry, cpu_count, + GFP_KERNEL | GFP_DMA); if (!diag0c_data) goto fail_kfree_cpu_vec; i = 0; diff --git a/arch/s390/hypfs/hypfs_sprp.c b/arch/s390/hypfs/hypfs_sprp.c index a72576221cab..08042d3a9d56 100644 --- a/arch/s390/hypfs/hypfs_sprp.c +++ b/arch/s390/hypfs/hypfs_sprp.c @@ -74,7 +74,7 @@ static int __hypfs_sprp_ioctl(void __user *user_area) rc = -ENOMEM; data = (void *)get_zeroed_page(GFP_KERNEL); - diag304 = kzalloc(sizeof(*diag304), GFP_KERNEL); + diag304 = kzalloc_obj(*diag304); if (!data || !diag304) goto out; diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 3a47c2e24b6e..559b011e6880 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -292,7 +292,7 @@ static int hypfs_init_fs_context(struct fs_context *fc) { struct hypfs_sb_info *sbi; - sbi = kzalloc(sizeof(struct hypfs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct hypfs_sb_info); if (!sbi) return -ENOMEM; diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index 6375276d94ea..c5440b3ee53d 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -45,7 +45,7 @@ typedef struct debug_info { struct debug_info *next; struct debug_info *prev; refcount_t ref_count; - spinlock_t lock; + raw_spinlock_t lock; int level; int nr_areas; int pages_per_area; @@ -440,7 +440,7 @@ static int VNAME(var, active_entries)[EARLY_AREAS] __initdata .next = NULL, \ .prev = NULL, \ .ref_count = REFCOUNT_INIT(1), \ - .lock = __SPIN_LOCK_UNLOCKED(var.lock), \ + .lock = __RAW_SPIN_LOCK_UNLOCKED(var.lock), \ .level = DEBUG_DEFAULT_LEVEL, \ .nr_areas = EARLY_AREAS, \ .pages_per_area = EARLY_PAGES, \ diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h index e5000ee6cdc6..06e1ec2afd5a 100644 --- a/arch/s390/include/asm/idals.h +++ b/arch/s390/include/asm/idals.h @@ -94,7 +94,7 @@ static inline int set_normalized_cda(struct ccw1 *ccw, void *vaddr) return -EINVAL; nridaws = idal_nr_words(vaddr, ccw->count); if (nridaws > 0) { - idal = kcalloc(nridaws, sizeof(*idal), GFP_ATOMIC | GFP_DMA); + idal = kzalloc_objs(*idal, nridaws, GFP_ATOMIC | GFP_DMA); if (!idal) return -ENOMEM; idal_create_words(idal, vaddr, ccw->count); @@ -137,7 +137,7 @@ static inline struct idal_buffer *idal_buffer_alloc(size_t size, int page_order) nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_SHIFT; nr_chunks = (PAGE_SIZE << page_order) >> IDA_SIZE_SHIFT; - ib = kmalloc(struct_size(ib, data, nr_ptrs), GFP_DMA | GFP_KERNEL); + ib = kmalloc_flex(*ib, data, nr_ptrs, GFP_DMA | GFP_KERNEL); if (!ib) return ERR_PTR(-ENOMEM); ib->size = size; @@ -195,7 +195,7 @@ static inline struct idal_buffer **idal_buffer_array_alloc(size_t size, int page int i; count = (size + CCW_MAX_BYTE_COUNT - 1) / CCW_MAX_BYTE_COUNT; - ibs = kmalloc_array(count + 1, sizeof(*ibs), GFP_KERNEL); + ibs = kmalloc_objs(*ibs, count + 1); for (i = 0; i < count; i++) { /* Determine size for the current idal buffer */ ib_size = min(size, CCW_MAX_BYTE_COUNT); diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h index 09f763b9eb40..32536ee34aa0 100644 --- a/arch/s390/include/asm/idle.h +++ b/arch/s390/include/asm/idle.h @@ -19,9 +19,9 @@ struct s390_idle_data { unsigned long mt_cycles_enter[8]; }; +DECLARE_PER_CPU(struct s390_idle_data, s390_idle); + extern struct device_attribute dev_attr_idle_count; extern struct device_attribute dev_attr_idle_time_us; -void psw_idle(struct s390_idle_data *data, unsigned long psw_mask); - #endif /* _S390_IDLE_H */ diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index cc187afa07b3..78195ee5e99f 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -159,7 +159,7 @@ static __always_inline void __stackleak_poison(unsigned long erase_low, " j 4f\n" "3: mvc 8(1,%[addr]),0(%[addr])\n" "4:" - : [addr] "+&a" (erase_low), [count] "+&d" (count), [tmp] "=&a" (tmp) + : [addr] "+&a" (erase_low), [count] "+&a" (count), [tmp] "=&a" (tmp) : [poison] "d" (poison) : "memory", "cc" ); diff --git a/arch/s390/include/asm/vtime.h b/arch/s390/include/asm/vtime.h index 9d25fb35a042..b1db75d14e9d 100644 --- a/arch/s390/include/asm/vtime.h +++ b/arch/s390/include/asm/vtime.h @@ -2,6 +2,12 @@ #ifndef _S390_VTIME_H #define _S390_VTIME_H +#include +#include +#include + +DECLARE_PER_CPU(u64, mt_cycles[8]); + static inline void update_timer_sys(void) { struct lowcore *lc = get_lowcore(); @@ -20,4 +26,32 @@ static inline void update_timer_mcck(void) lc->last_update_timer = lc->mcck_enter_timer; } +static inline void update_timer_idle(void) +{ + struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); + struct lowcore *lc = get_lowcore(); + u64 cycles_new[8]; + int i, mtid; + + mtid = smp_cpu_mtid; + if (mtid) { + stcctm(MT_DIAG, mtid, cycles_new); + for (i = 0; i < mtid; i++) + __this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]); + } + /* + * This is a bit subtle: Forward last_update_clock so it excludes idle + * time. For correct steal time calculation in do_account_vtime() add + * passed wall time before idle_enter to steal_timer: + * During the passed wall time before idle_enter CPU time may have + * been accounted to system, hardirq, softirq, etc. lowcore fields. + * The accounted CPU times will be subtracted again from steal_timer + * when accumulated steal time is calculated in do_account_vtime(). + */ + lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock; + lc->last_update_clock = lc->int_clock; + lc->system_timer += lc->last_update_timer - idle->timer_idle_enter; + lc->last_update_timer = lc->sys_enter_timer; +} + #endif /* _S390_VTIME_H */ diff --git a/arch/s390/kernel/cert_store.c b/arch/s390/kernel/cert_store.c index c217a5e64094..dc1992a675de 100644 --- a/arch/s390/kernel/cert_store.c +++ b/arch/s390/kernel/cert_store.c @@ -322,7 +322,7 @@ static int invalidate_keyring_keys(struct key *keyring) keyring_payload_len = key_type_keyring.read(keyring, NULL, 0); num_keys = keyring_payload_len / sizeof(key_serial_t); - key_array = kcalloc(num_keys, sizeof(key_serial_t), GFP_KERNEL); + key_array = kzalloc_objs(key_serial_t, num_keys); if (!key_array) return -ENOMEM; diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 71cdb6845dd7..31430e9bcfdd 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -181,14 +181,13 @@ static debug_entry_t ***debug_areas_alloc(int pages_per_area, int nr_areas) debug_entry_t ***areas; int i, j; - areas = kmalloc_array(nr_areas, sizeof(debug_entry_t **), GFP_KERNEL); + areas = kmalloc_objs(debug_entry_t **, nr_areas); if (!areas) goto fail_malloc_areas; for (i = 0; i < nr_areas; i++) { /* GFP_NOWARN to avoid user triggerable WARN, we handle fails */ - areas[i] = kmalloc_array(pages_per_area, - sizeof(debug_entry_t *), - GFP_KERNEL | __GFP_NOWARN); + areas[i] = kmalloc_objs(debug_entry_t *, pages_per_area, + GFP_KERNEL | __GFP_NOWARN); if (!areas[i]) goto fail_malloc_areas2; for (j = 0; j < pages_per_area; j++) { @@ -225,13 +224,13 @@ static debug_info_t *debug_info_alloc(const char *name, int pages_per_area, debug_info_t *rc; /* alloc everything */ - rc = kmalloc(sizeof(debug_info_t), GFP_KERNEL); + rc = kmalloc_obj(debug_info_t); if (!rc) goto fail_malloc_rc; - rc->active_entries = kcalloc(nr_areas, sizeof(int), GFP_KERNEL); + rc->active_entries = kzalloc_objs(int, nr_areas); if (!rc->active_entries) goto fail_malloc_active_entries; - rc->active_pages = kcalloc(nr_areas, sizeof(int), GFP_KERNEL); + rc->active_pages = kzalloc_objs(int, nr_areas); if (!rc->active_pages) goto fail_malloc_active_pages; if ((mode == ALL_AREAS) && (pages_per_area != 0)) { @@ -243,7 +242,7 @@ static debug_info_t *debug_info_alloc(const char *name, int pages_per_area, } /* initialize members */ - spin_lock_init(&rc->lock); + raw_spin_lock_init(&rc->lock); rc->pages_per_area = pages_per_area; rc->nr_areas = nr_areas; rc->active_area = 0; @@ -333,7 +332,7 @@ static debug_info_t *debug_info_copy(debug_info_t *in, int mode) do { rc = debug_info_alloc(in->name, in->pages_per_area, in->nr_areas, in->buf_size, in->level, mode); - spin_lock_irqsave(&in->lock, flags); + raw_spin_lock_irqsave(&in->lock, flags); if (!rc) goto out; /* has something changed in the meantime ? */ @@ -341,7 +340,7 @@ static debug_info_t *debug_info_copy(debug_info_t *in, int mode) (rc->nr_areas == in->nr_areas)) { break; } - spin_unlock_irqrestore(&in->lock, flags); + raw_spin_unlock_irqrestore(&in->lock, flags); debug_info_free(rc); } while (1); @@ -356,7 +355,7 @@ static debug_info_t *debug_info_copy(debug_info_t *in, int mode) } rc->active_area = in->active_area; out: - spin_unlock_irqrestore(&in->lock, flags); + raw_spin_unlock_irqrestore(&in->lock, flags); return rc; } @@ -631,7 +630,7 @@ static file_private_info_t *debug_file_private_alloc(debug_info_t *debug_info, if (!debug_info_snapshot) return NULL; - p_info = kmalloc(sizeof(file_private_info_t), GFP_KERNEL); + p_info = kmalloc_obj(file_private_info_t); if (!p_info) { debug_info_free(debug_info_snapshot); return NULL; @@ -879,20 +878,20 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas) pr_err("Registering debug feature %s failed\n", id->name); /* Clear pointers to prevent tracing into released initdata. */ - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); id->areas = NULL; id->active_pages = NULL; id->active_entries = NULL; - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); return; } /* Replace static trace area with dynamic copy. */ - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); debug_events_append(copy, id); debug_areas_swap(id, copy); - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); /* Clear pointers to initdata and discard copy. */ copy->areas = NULL; @@ -966,11 +965,11 @@ static int debug_set_size(debug_info_t *id, int nr_areas, int pages_per_area) return -ENOMEM; } - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); debug_events_append(new_id, id); debug_areas_swap(new_id, id); + raw_spin_unlock_irqrestore(&id->lock, flags); debug_info_free(new_id); - spin_unlock_irqrestore(&id->lock, flags); pr_info("%s: set new size (%i pages)\n", id->name, pages_per_area); return 0; @@ -1000,9 +999,9 @@ void debug_set_level(debug_info_t *id, int new_level) return; } - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); id->level = new_level; - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); } EXPORT_SYMBOL(debug_set_level); @@ -1184,10 +1183,10 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf, if (!debug_active || !id->areas) return NULL; if (debug_critical) { - if (!spin_trylock_irqsave(&id->lock, flags)) + if (!raw_spin_trylock_irqsave(&id->lock, flags)) return NULL; } else { - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); } do { active = get_active_entry(id); @@ -1199,7 +1198,7 @@ debug_entry_t *debug_event_common(debug_info_t *id, int level, const void *buf, buf += id->buf_size; } while (len > 0); - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); return active; } EXPORT_SYMBOL(debug_event_common); @@ -1217,10 +1216,10 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level, if (!debug_active || !id->areas) return NULL; if (debug_critical) { - if (!spin_trylock_irqsave(&id->lock, flags)) + if (!raw_spin_trylock_irqsave(&id->lock, flags)) return NULL; } else { - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); } do { active = get_active_entry(id); @@ -1232,7 +1231,7 @@ debug_entry_t *debug_exception_common(debug_info_t *id, int level, buf += id->buf_size; } while (len > 0); - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); return active; } EXPORT_SYMBOL(debug_exception_common); @@ -1267,10 +1266,10 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, numargs = debug_count_numargs(string); if (debug_critical) { - if (!spin_trylock_irqsave(&id->lock, flags)) + if (!raw_spin_trylock_irqsave(&id->lock, flags)) return NULL; } else { - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); } active = get_active_entry(id); curr_event = (debug_sprintf_entry_t *) DEBUG_DATA(active); @@ -1280,7 +1279,7 @@ debug_entry_t *__debug_sprintf_event(debug_info_t *id, int level, char *string, curr_event->args[idx] = va_arg(ap, long); va_end(ap); debug_finish_entry(id, active, level, 0); - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); return active; } @@ -1303,10 +1302,10 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri numargs = debug_count_numargs(string); if (debug_critical) { - if (!spin_trylock_irqsave(&id->lock, flags)) + if (!raw_spin_trylock_irqsave(&id->lock, flags)) return NULL; } else { - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); } active = get_active_entry(id); curr_event = (debug_sprintf_entry_t *)DEBUG_DATA(active); @@ -1316,7 +1315,7 @@ debug_entry_t *__debug_sprintf_exception(debug_info_t *id, int level, char *stri curr_event->args[idx] = va_arg(ap, long); va_end(ap); debug_finish_entry(id, active, level, 1); - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); return active; } @@ -1350,7 +1349,7 @@ int debug_register_view(debug_info_t *id, struct debug_view *view) mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); pde = debugfs_create_file(view->name, mode, id->debugfs_root_entry, id, &debug_file_ops); - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (!id->views[i]) break; @@ -1361,7 +1360,7 @@ int debug_register_view(debug_info_t *id, struct debug_view *view) id->views[i] = view; id->debugfs_entries[i] = pde; } - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); if (rc) { pr_err("Registering view %s/%s would exceed the maximum " "number of views %i\n", id->name, view->name, i); @@ -1391,7 +1390,7 @@ int debug_unregister_view(debug_info_t *id, struct debug_view *view) if (!id) goto out; - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); for (i = 0; i < DEBUG_MAX_VIEWS; i++) { if (id->views[i] == view) break; @@ -1403,7 +1402,7 @@ int debug_unregister_view(debug_info_t *id, struct debug_view *view) id->views[i] = NULL; id->debugfs_entries[i] = NULL; } - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); debugfs_remove(dentry); out: return rc; @@ -1557,7 +1556,7 @@ static void debug_flush(debug_info_t *id, int area) if (!id || !id->areas) return; - spin_lock_irqsave(&id->lock, flags); + raw_spin_lock_irqsave(&id->lock, flags); if (area == DEBUG_FLUSH_ALL) { id->active_area = 0; memset(id->active_entries, 0, id->nr_areas * sizeof(int)); @@ -1572,7 +1571,7 @@ static void debug_flush(debug_info_t *id, int area) for (i = 0; i < id->pages_per_area; i++) memset(id->areas[area][i], 0, PAGE_SIZE); } - spin_unlock_irqrestore(&id->lock, flags); + raw_spin_unlock_irqrestore(&id->lock, flags); } /* diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index dd55cc6bbc28..fb67b4abe68c 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h @@ -56,8 +56,6 @@ long sys_s390_pci_mmio_write(unsigned long, const void __user *, size_t); long sys_s390_pci_mmio_read(unsigned long, void __user *, size_t); long sys_s390_sthyi(unsigned long function_code, void __user *buffer, u64 __user *return_code, unsigned long flags); -DECLARE_PER_CPU(u64, mt_cycles[8]); - unsigned long stack_alloc(void); void stack_free(unsigned long stack); diff --git a/arch/s390/kernel/guarded_storage.c b/arch/s390/kernel/guarded_storage.c index cf26d7a37425..cab8ac25a010 100644 --- a/arch/s390/kernel/guarded_storage.c +++ b/arch/s390/kernel/guarded_storage.c @@ -24,7 +24,7 @@ static int gs_enable(void) struct gs_cb *gs_cb; if (!current->thread.gs_cb) { - gs_cb = kzalloc(sizeof(*gs_cb), GFP_KERNEL); + gs_cb = kzalloc_obj(*gs_cb); if (!gs_cb) return -ENOMEM; gs_cb->gsd = 25; @@ -55,7 +55,7 @@ static int gs_set_bc_cb(struct gs_cb __user *u_gs_cb) gs_cb = current->thread.gs_bc_cb; if (!gs_cb) { - gs_cb = kzalloc(sizeof(*gs_cb), GFP_KERNEL); + gs_cb = kzalloc_obj(*gs_cb); if (!gs_cb) return -ENOMEM; current->thread.gs_bc_cb = gs_cb; diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c index 39cb8d0ae348..1f1b06b6b4ef 100644 --- a/arch/s390/kernel/idle.c +++ b/arch/s390/kernel/idle.c @@ -15,37 +15,22 @@ #include #include #include +#include #include #include -#include "entry.h" -static DEFINE_PER_CPU(struct s390_idle_data, s390_idle); +DEFINE_PER_CPU(struct s390_idle_data, s390_idle); void account_idle_time_irq(void) { struct s390_idle_data *idle = this_cpu_ptr(&s390_idle); - struct lowcore *lc = get_lowcore(); unsigned long idle_time; - u64 cycles_new[8]; - int i; - if (smp_cpu_mtid) { - stcctm(MT_DIAG, smp_cpu_mtid, cycles_new); - for (i = 0; i < smp_cpu_mtid; i++) - this_cpu_add(mt_cycles[i], cycles_new[i] - idle->mt_cycles_enter[i]); - } - - idle_time = lc->int_clock - idle->clock_idle_enter; - - lc->steal_timer += idle->clock_idle_enter - lc->last_update_clock; - lc->last_update_clock = lc->int_clock; - - lc->system_timer += lc->last_update_timer - idle->timer_idle_enter; - lc->last_update_timer = lc->sys_enter_timer; + idle_time = get_lowcore()->int_clock - idle->clock_idle_enter; /* Account time spent with enabled wait psw loaded as idle time. */ - WRITE_ONCE(idle->idle_time, READ_ONCE(idle->idle_time) + idle_time); - WRITE_ONCE(idle->idle_count, READ_ONCE(idle->idle_count) + 1); + __atomic64_add(idle_time, &idle->idle_time); + __atomic64_add_const(1, &idle->idle_count); account_idle_time(cputime_to_nsecs(idle_time)); } diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index dcdc7e274848..049c557c452f 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c @@ -2377,7 +2377,7 @@ void __init setup_ipl(void) atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); } -void s390_reset_system(void) +void __no_stack_protector s390_reset_system(void) { /* Disable prefixing */ set_prefix(0); diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index bdf9c7cb5685..d10a17e6531d 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c @@ -146,6 +146,10 @@ void noinstr do_io_irq(struct pt_regs *regs) struct pt_regs *old_regs = set_irq_regs(regs); bool from_idle; + from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT); + if (from_idle) + update_timer_idle(); + irq_enter_rcu(); if (user_mode(regs)) { @@ -154,7 +158,6 @@ void noinstr do_io_irq(struct pt_regs *regs) current->thread.last_break = regs->last_break; } - from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT); if (from_idle) account_idle_time_irq(); @@ -182,6 +185,10 @@ void noinstr do_ext_irq(struct pt_regs *regs) struct pt_regs *old_regs = set_irq_regs(regs); bool from_idle; + from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT); + if (from_idle) + update_timer_idle(); + irq_enter_rcu(); if (user_mode(regs)) { @@ -194,7 +201,6 @@ void noinstr do_ext_irq(struct pt_regs *regs) regs->int_parm = get_lowcore()->ext_params; regs->int_parm_long = get_lowcore()->ext_params2; - from_idle = test_and_clear_cpu_flag(CIF_ENABLED_WAIT); if (from_idle) account_idle_time_irq(); @@ -312,7 +318,7 @@ int register_external_irq(u16 code, ext_int_handler_t handler) unsigned long flags; int index; - p = kmalloc(sizeof(*p), GFP_ATOMIC); + p = kmalloc_obj(*p, GFP_ATOMIC); if (!p) return -ENOMEM; p->code = code; diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index 94fa44776d0c..4a30c10ae63b 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c @@ -154,7 +154,7 @@ static void os_info_old_init(void) goto fail; if (addr == 0 || addr % PAGE_SIZE) goto fail; - os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL); + os_info_old = kzalloc_obj(*os_info_old); if (!os_info_old) goto fail; if (copy_oldmem_kernel(os_info_old, addr, sizeof(*os_info_old))) diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c index 408ab93112bf..7aa655664ecc 100644 --- a/arch/s390/kernel/perf_cpum_cf.c +++ b/arch/s390/kernel/perf_cpum_cf.c @@ -252,7 +252,7 @@ static int cpum_cf_alloc_cpu(int cpu) cpuhw = p->cpucf; if (!cpuhw) { - cpuhw = kzalloc(sizeof(*cpuhw), GFP_KERNEL); + cpuhw = kzalloc_obj(*cpuhw); if (cpuhw) { p->cpucf = cpuhw; refcount_set(&cpuhw->refcnt, 1); @@ -1616,7 +1616,7 @@ static long cfset_ioctl_start(unsigned long arg, struct file *file) if (!start.counter_sets) return -EINVAL; /* No counter set at all? */ - preq = kzalloc(sizeof(*preq), GFP_KERNEL); + preq = kzalloc_obj(*preq); if (!preq) return -ENOMEM; cpumask_clear(&preq->mask); diff --git a/arch/s390/kernel/perf_cpum_cf_events.c b/arch/s390/kernel/perf_cpum_cf_events.c index 7ace1f9e4ccf..ad8c32f0aaed 100644 --- a/arch/s390/kernel/perf_cpum_cf_events.c +++ b/arch/s390/kernel/perf_cpum_cf_events.c @@ -976,7 +976,7 @@ static __init struct attribute **merge_attr(struct attribute **a, j++; j++; - new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL); + new = kmalloc_objs(struct attribute *, j); if (!new) return NULL; j = 0; diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index e8bd19ac82c7..c92c29de725e 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -1609,7 +1609,7 @@ static void *aux_buffer_setup(struct perf_event *event, void **pages, } /* Allocate aux_buffer struct for the event */ - aux = kzalloc(sizeof(struct aux_buffer), GFP_KERNEL); + aux = kzalloc_obj(struct aux_buffer); if (!aux) goto no_aux; sfb = &aux->sfb; diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c index 810f5b6c5e01..86f71a3d1ef2 100644 --- a/arch/s390/kernel/perf_pai.c +++ b/arch/s390/kernel/perf_pai.c @@ -252,7 +252,7 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) cpump = mp->mapptr; if (!cpump) { /* Paicrypt_map allocated? */ rc = -ENOMEM; - cpump = kzalloc(sizeof(*cpump), GFP_KERNEL); + cpump = kzalloc_obj(*cpump); if (!cpump) goto undo; /* Allocate memory for counter page and counter extraction. @@ -281,9 +281,8 @@ static int pai_alloc_cpu(struct perf_event *event, int cpu) cpump->paiext_cb = kzalloc(PAIE1_CB_SZ, GFP_KERNEL); need_paiext_cb = true; } - cpump->save = kvmalloc_array(pai_pmu[idx].num_avail + 1, - sizeof(struct pai_userdata), - GFP_KERNEL); + cpump->save = kvmalloc_objs(struct pai_userdata, + pai_pmu[idx].num_avail + 1); if (!cpump->area || !cpump->save || (need_paiext_cb && !cpump->paiext_cb)) { pai_free(mp); @@ -315,7 +314,7 @@ static int pai_alloc(struct perf_event *event) struct cpumask *maskptr; int cpu, rc = -ENOMEM; - maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL); + maskptr = kzalloc_obj(*maskptr); if (!maskptr) goto out; @@ -1070,7 +1069,7 @@ static struct attribute * __init attr_event_init_one(int num, { struct perf_pmu_events_attr *pa; - pa = kzalloc(sizeof(*pa), GFP_KERNEL); + pa = kzalloc_obj(*pa); if (!pa) return NULL; @@ -1089,7 +1088,7 @@ static struct attribute ** __init attr_event_init(struct pai_pmu *p) struct attribute **attrs; unsigned int i; - attrs = kmalloc_array(min_attr + 1, sizeof(*attrs), GFP_KERNEL | __GFP_ZERO); + attrs = kmalloc_objs(*attrs, min_attr + 1, GFP_KERNEL | __GFP_ZERO); if (!attrs) goto out; for (i = 0; i < min_attr; i++) { diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index ceaa1726e328..125ca4c4e30c 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -749,7 +749,7 @@ static int s390_gs_cb_set(struct task_struct *target, if (!cpu_has_gs()) return -ENODEV; if (!target->thread.gs_cb) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; } @@ -800,7 +800,7 @@ static int s390_gs_bc_set(struct task_struct *target, if (!cpu_has_gs()) return -ENODEV; if (!data) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; target->thread.gs_bc_cb = data; @@ -861,7 +861,7 @@ static int s390_runtime_instr_set(struct task_struct *target, return -ENODEV; if (!target->thread.ri_cb) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; } diff --git a/arch/s390/kernel/runtime_instr.c b/arch/s390/kernel/runtime_instr.c index 1788a5454b6f..928bff8fcd4a 100644 --- a/arch/s390/kernel/runtime_instr.c +++ b/arch/s390/kernel/runtime_instr.c @@ -83,7 +83,7 @@ SYSCALL_DEFINE2(s390_runtime_instr, int, command, int, signum) return -EINVAL; if (!current->thread.ri_cb) { - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc_obj(*cb); if (!cb) return -ENOMEM; } else { diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index b7429f30afc1..50bb499cf3e5 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -1145,13 +1145,13 @@ int __ref smp_rescan_cpus(bool early) struct sclp_core_info *info; int nr; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; smp_get_core_info(info, 0); nr = __smp_rescan_cpus(info, early); kfree(info); - if (nr) + if (nr && !early) topology_schedule_update(); return 0; } diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index a27a90a199be..0fe616c49fcc 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -132,7 +132,7 @@ static struct page ** __init vdso_setup_pages(void *start, void *end) struct page **pagelist; int i; - pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + pagelist = kzalloc_objs(struct page *, pages + 1); if (!pagelist) panic("%s: Cannot allocate page list for VDSO", __func__); for (i = 0; i < pages; i++) diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 53bcbb91bb9b..2b62395e35bf 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -221,6 +221,7 @@ SECTIONS /* Debugging sections. */ STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS /* diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 234a0ba30510..bf48744d0912 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -48,8 +48,7 @@ static inline void set_vtimer(u64 expires) static inline int virt_timer_forward(u64 elapsed) { - BUG_ON(!irqs_disabled()); - + lockdep_assert_irqs_disabled(); if (list_empty(&virt_timer_list)) return 0; elapsed = atomic64_add_return(elapsed, &virt_timer_elapsed); @@ -137,23 +136,16 @@ static int do_account_vtime(struct task_struct *tsk) lc->system_timer += timer; /* Update MT utilization calculation */ - if (smp_cpu_mtid && - time_after64(jiffies_64, this_cpu_read(mt_scaling_jiffies))) + if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies))) update_mt_scaling(); /* Calculate cputime delta */ - user = update_tsk_timer(&tsk->thread.user_timer, - READ_ONCE(lc->user_timer)); - guest = update_tsk_timer(&tsk->thread.guest_timer, - READ_ONCE(lc->guest_timer)); - system = update_tsk_timer(&tsk->thread.system_timer, - READ_ONCE(lc->system_timer)); - hardirq = update_tsk_timer(&tsk->thread.hardirq_timer, - READ_ONCE(lc->hardirq_timer)); - softirq = update_tsk_timer(&tsk->thread.softirq_timer, - READ_ONCE(lc->softirq_timer)); - lc->steal_timer += - clock - user - guest - system - hardirq - softirq; + user = update_tsk_timer(&tsk->thread.user_timer, lc->user_timer); + guest = update_tsk_timer(&tsk->thread.guest_timer, lc->guest_timer); + system = update_tsk_timer(&tsk->thread.system_timer, lc->system_timer); + hardirq = update_tsk_timer(&tsk->thread.hardirq_timer, lc->hardirq_timer); + softirq = update_tsk_timer(&tsk->thread.softirq_timer, lc->softirq_timer); + lc->steal_timer += clock - user - guest - system - hardirq - softirq; /* Push account value */ if (user) { @@ -225,10 +217,6 @@ static u64 vtime_delta(void) return timer - lc->last_update_timer; } -/* - * Update process times based on virtual cpu times stored by entry.S - * to the lowcore fields user_timer, system_timer & steal_clock. - */ void vtime_account_kernel(struct task_struct *tsk) { struct lowcore *lc = get_lowcore(); @@ -238,27 +226,17 @@ void vtime_account_kernel(struct task_struct *tsk) lc->guest_timer += delta; else lc->system_timer += delta; - - virt_timer_forward(delta); } EXPORT_SYMBOL_GPL(vtime_account_kernel); void vtime_account_softirq(struct task_struct *tsk) { - u64 delta = vtime_delta(); - - get_lowcore()->softirq_timer += delta; - - virt_timer_forward(delta); + get_lowcore()->softirq_timer += vtime_delta(); } void vtime_account_hardirq(struct task_struct *tsk) { - u64 delta = vtime_delta(); - - get_lowcore()->hardirq_timer += delta; - - virt_timer_forward(delta); + get_lowcore()->hardirq_timer += vtime_delta(); } /* diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index 917ac740513e..5b835bc6a194 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig @@ -28,9 +28,7 @@ config KVM select HAVE_KVM_INVALID_WAKEUPS select HAVE_KVM_NO_POLL select KVM_VFIO - select MMU_NOTIFIER select VIRT_XFER_TO_GUEST_WORK - select KVM_GENERIC_MMU_NOTIFIER select KVM_MMU_LOCKLESS_AGING help Support hosting paravirtualized guest machines using the SIE diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c index 129dc55a4a0d..670404d4fa44 100644 --- a/arch/s390/kvm/dat.c +++ b/arch/s390/kvm/dat.c @@ -45,7 +45,7 @@ int kvm_s390_mmu_cache_topup(struct kvm_s390_mmu_cache *mc) mc->pts[mc->n_pts] = o; } for ( ; mc->n_rmaps < KVM_S390_MMU_CACHE_N_RMAPS; mc->n_rmaps++) { - o = kzalloc(sizeof(*mc->rmaps[0]), GFP_KERNEL_ACCOUNT); + o = kzalloc_obj(*mc->rmaps[0], GFP_KERNEL_ACCOUNT); if (!o) return -ENOMEM; mc->rmaps[mc->n_rmaps] = o; diff --git a/arch/s390/kvm/dat.h b/arch/s390/kvm/dat.h index 8c7ae07dcc28..123e11dcd70d 100644 --- a/arch/s390/kvm/dat.h +++ b/arch/s390/kvm/dat.h @@ -572,7 +572,7 @@ static inline struct vsie_rmap *kvm_s390_mmu_cache_alloc_rmap(struct kvm_s390_mm { if (mc->n_rmaps) return mc->rmaps[--mc->n_rmaps]; - return kzalloc(sizeof(struct vsie_rmap), GFP_KVM_S390_MMU_CACHE); + return kzalloc_obj(struct vsie_rmap, GFP_KVM_S390_MMU_CACHE); } static inline struct crst_table *crste_table_start(union crste *crstep) @@ -920,7 +920,7 @@ static inline struct kvm_s390_mmu_cache *kvm_s390_new_mmu_cache(void) { struct kvm_s390_mmu_cache *mc __free(kvm_s390_mmu_cache) = NULL; - mc = kzalloc(sizeof(*mc), GFP_KERNEL_ACCOUNT); + mc = kzalloc_obj(*mc, GFP_KERNEL_ACCOUNT); if (mc && !kvm_s390_mmu_cache_topup(mc)) return_ptr(mc); return NULL; diff --git a/arch/s390/kvm/gmap.c b/arch/s390/kvm/gmap.c index 26cd2b208b6f..ef0c6ebfdde2 100644 --- a/arch/s390/kvm/gmap.c +++ b/arch/s390/kvm/gmap.c @@ -57,7 +57,7 @@ struct gmap *gmap_new(struct kvm *kvm, gfn_t limit) type = gmap_limit_to_type(limit); - gmap = kzalloc(sizeof(*gmap), GFP_KERNEL_ACCOUNT); + gmap = kzalloc_obj(*gmap, GFP_KERNEL_ACCOUNT); if (!gmap) return NULL; INIT_LIST_HEAD(&gmap->children); @@ -918,7 +918,7 @@ int gmap_insert_rmap(struct gmap *sg, gfn_t p_gfn, gfn_t r_gfn, int level) KVM_BUG_ON(!is_shadow(sg), sg->kvm); lockdep_assert_held(&sg->host_to_rmap_lock); - rmap = kzalloc(sizeof(*rmap), GFP_ATOMIC); + rmap = kzalloc_obj(*rmap, GFP_ATOMIC); if (!rmap) return -ENOMEM; diff --git a/arch/s390/kvm/guestdbg.c b/arch/s390/kvm/guestdbg.c index 80879fc73c90..69835e1d4f20 100644 --- a/arch/s390/kvm/guestdbg.c +++ b/arch/s390/kvm/guestdbg.c @@ -232,18 +232,14 @@ int kvm_s390_import_bp_data(struct kvm_vcpu *vcpu, } if (nr_wp > 0) { - wp_info = kmalloc_array(nr_wp, - sizeof(*wp_info), - GFP_KERNEL_ACCOUNT); + wp_info = kmalloc_objs(*wp_info, nr_wp, GFP_KERNEL_ACCOUNT); if (!wp_info) { ret = -ENOMEM; goto error; } } if (nr_bp > 0) { - bp_info = kmalloc_array(nr_bp, - sizeof(*bp_info), - GFP_KERNEL_ACCOUNT); + bp_info = kmalloc_objs(*bp_info, nr_bp, GFP_KERNEL_ACCOUNT); if (!bp_info) { ret = -ENOMEM; goto error; diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 1c2bb5cd7e12..18932a65ca68 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -1749,7 +1749,7 @@ struct kvm_s390_interrupt_info *kvm_s390_get_io_int(struct kvm *kvm, goto out; } gisa_out: - tmp_inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); + tmp_inti = kzalloc_obj(*inti, GFP_KERNEL_ACCOUNT); if (tmp_inti) { tmp_inti->type = KVM_S390_INT_IO(1, 0, 0, 0); tmp_inti->io.io_int_word = isc_to_int_word(isc); @@ -1968,7 +1968,7 @@ int kvm_s390_inject_vm(struct kvm *kvm, struct kvm_s390_interrupt_info *inti; int rc; - inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); + inti = kzalloc_obj(*inti, GFP_KERNEL_ACCOUNT); if (!inti) return -ENOMEM; @@ -2374,7 +2374,7 @@ static int enqueue_floating_irq(struct kvm_device *dev, return -EINVAL; while (len >= sizeof(struct kvm_s390_irq)) { - inti = kzalloc(sizeof(*inti), GFP_KERNEL_ACCOUNT); + inti = kzalloc_obj(*inti, GFP_KERNEL_ACCOUNT); if (!inti) return -ENOMEM; @@ -2422,7 +2422,7 @@ static int register_io_adapter(struct kvm_device *dev, if (dev->kvm->arch.adapters[adapter_info.id] != NULL) return -EINVAL; - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL_ACCOUNT); + adapter = kzalloc_obj(*adapter, GFP_KERNEL_ACCOUNT); if (!adapter) return -ENOMEM; diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index de645025db0f..3eb60aa932ec 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -65,7 +65,7 @@ #define VCPU_IRQS_MAX_BUF (sizeof(struct kvm_s390_irq) * \ (KVM_MAX_VCPUS + LOCAL_IRQS)) -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_COUNTER(VM, inject_io), STATS_DESC_COUNTER(VM, inject_float_mchk), @@ -91,7 +91,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, exit_userspace), STATS_DESC_COUNTER(VCPU, exit_null), @@ -601,7 +601,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) switch (ext) { case KVM_CAP_S390_PSW: case KVM_CAP_S390_GMAP: - case KVM_CAP_SYNC_MMU: #ifdef CONFIG_KVM_S390_UCONTROL case KVM_CAP_S390_UCONTROL: #endif @@ -1418,7 +1417,7 @@ static int kvm_s390_set_processor(struct kvm *kvm, struct kvm_device_attr *attr) ret = -EBUSY; goto out; } - proc = kzalloc(sizeof(*proc), GFP_KERNEL_ACCOUNT); + proc = kzalloc_obj(*proc, GFP_KERNEL_ACCOUNT); if (!proc) { ret = -ENOMEM; goto out; @@ -1618,7 +1617,7 @@ static int kvm_s390_get_processor(struct kvm *kvm, struct kvm_device_attr *attr) struct kvm_s390_vm_cpu_processor *proc; int ret = 0; - proc = kzalloc(sizeof(*proc), GFP_KERNEL_ACCOUNT); + proc = kzalloc_obj(*proc, GFP_KERNEL_ACCOUNT); if (!proc) { ret = -ENOMEM; goto out; @@ -1646,7 +1645,7 @@ static int kvm_s390_get_machine(struct kvm *kvm, struct kvm_device_attr *attr) struct kvm_s390_vm_cpu_machine *mach; int ret = 0; - mach = kzalloc(sizeof(*mach), GFP_KERNEL_ACCOUNT); + mach = kzalloc_obj(*mach, GFP_KERNEL_ACCOUNT); if (!mach) { ret = -ENOMEM; goto out; diff --git a/arch/s390/kvm/pci.c b/arch/s390/kvm/pci.c index 8c40154ff50f..86d93e8dddae 100644 --- a/arch/s390/kvm/pci.c +++ b/arch/s390/kvm/pci.c @@ -54,7 +54,7 @@ static int zpci_setup_aipb(u8 nisc) struct page *page; int size, rc; - zpci_aipb = kzalloc(sizeof(union zpci_sic_iib), GFP_KERNEL); + zpci_aipb = kzalloc_obj(union zpci_sic_iib); if (!zpci_aipb) return -ENOMEM; @@ -126,8 +126,7 @@ int kvm_s390_pci_aen_init(u8 nisc) return -EPERM; mutex_lock(&aift->aift_lock); - aift->kzdev = kcalloc(ZPCI_NR_DEVICES, sizeof(struct kvm_zdev *), - GFP_KERNEL); + aift->kzdev = kzalloc_objs(struct kvm_zdev *, ZPCI_NR_DEVICES); if (!aift->kzdev) { rc = -ENOMEM; goto unlock; @@ -404,7 +403,7 @@ static int kvm_s390_pci_dev_open(struct zpci_dev *zdev) { struct kvm_zdev *kzdev; - kzdev = kzalloc(sizeof(struct kvm_zdev), GFP_KERNEL); + kzdev = kzalloc_obj(struct kvm_zdev); if (!kzdev) return -ENOMEM; @@ -666,7 +665,7 @@ int __init kvm_s390_pci_init(void) if (!kvm_s390_pci_interp_allowed()) return 0; - aift = kzalloc(sizeof(struct zpci_aift), GFP_KERNEL); + aift = kzalloc_obj(struct zpci_aift); if (!aift) return -ENOMEM; diff --git a/arch/s390/kvm/pv.c b/arch/s390/kvm/pv.c index 461b413c76a3..c2dafd812a3b 100644 --- a/arch/s390/kvm/pv.c +++ b/arch/s390/kvm/pv.c @@ -466,7 +466,7 @@ int kvm_s390_pv_set_aside(struct kvm *kvm, u16 *rc, u16 *rrc) if (kvm->arch.gmap->asce.dt == TABLE_TYPE_SEGMENT) return -EINVAL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/arch/s390/lib/xor.c b/arch/s390/lib/xor.c index 1721b73b7803..5363e4c2462d 100644 --- a/arch/s390/lib/xor.c +++ b/arch/s390/lib/xor.c @@ -28,8 +28,8 @@ static void xor_xc_2(unsigned long bytes, unsigned long * __restrict p1, " j 3f\n" "2: xc 0(1,%1),0(%2)\n" "3:" - : : "d" (bytes), "a" (p1), "a" (p2) - : "0", "cc", "memory"); + : "+a" (bytes), "+a" (p1), "+a" (p2) + : : "0", "cc", "memory"); } static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1, @@ -54,7 +54,7 @@ static void xor_xc_3(unsigned long bytes, unsigned long * __restrict p1, "2: xc 0(1,%1),0(%2)\n" "3: xc 0(1,%1),0(%3)\n" "4:" - : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3) + : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3) : : "0", "cc", "memory"); } @@ -85,7 +85,7 @@ static void xor_xc_4(unsigned long bytes, unsigned long * __restrict p1, "3: xc 0(1,%1),0(%3)\n" "4: xc 0(1,%1),0(%4)\n" "5:" - : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4) + : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4) : : "0", "cc", "memory"); } @@ -96,7 +96,6 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, const unsigned long * __restrict p5) { asm volatile( - " larl 1,2f\n" " aghi %0,-1\n" " jm 6f\n" " srlg 0,%0,8\n" @@ -122,7 +121,7 @@ static void xor_xc_5(unsigned long bytes, unsigned long * __restrict p1, "4: xc 0(1,%1),0(%4)\n" "5: xc 0(1,%1),0(%5)\n" "6:" - : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4), + : "+a" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4), "+a" (p5) : : "0", "cc", "memory"); } diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 6cc33c705de2..1c3a1eed4381 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -171,8 +171,8 @@ query_segment_type (struct dcss_segment *seg) struct qout64 *qout; struct qin64 *qin; - qin = kmalloc(sizeof(*qin), GFP_KERNEL | GFP_DMA); - qout = kmalloc(sizeof(*qout), GFP_KERNEL | GFP_DMA); + qin = kmalloc_obj(*qin, GFP_KERNEL | GFP_DMA); + qout = kmalloc_obj(*qout, GFP_KERNEL | GFP_DMA); if ((qin == NULL) || (qout == NULL)) { rc = -ENOMEM; goto out_free; @@ -302,7 +302,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long start_addr = end_addr = 0; segtype = -1; - seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA); + seg = kmalloc_obj(*seg, GFP_KERNEL | GFP_DMA); if (seg == NULL) { rc = -ENOMEM; goto out; @@ -317,7 +317,7 @@ __segment_load (char *name, int do_nonshared, unsigned long *addr, unsigned long goto out_free; } - seg->res = kzalloc(sizeof(struct resource), GFP_KERNEL); + seg->res = kzalloc_obj(struct resource); if (seg->res == NULL) { rc = -ENOMEM; goto out_free; diff --git a/arch/s390/mm/pfault.c b/arch/s390/mm/pfault.c index 2f829448c719..6ecd6b0a22a8 100644 --- a/arch/s390/mm/pfault.c +++ b/arch/s390/mm/pfault.c @@ -62,7 +62,7 @@ int __pfault_init(void) "0: nopr %%r7\n" EX_TABLE(0b, 0b) : [rc] "+d" (rc) - : [refbk] "a" (&pfault_init_refbk), "m" (pfault_init_refbk) + : [refbk] "a" (virt_to_phys(&pfault_init_refbk)), "m" (pfault_init_refbk) : "cc"); return rc; } @@ -84,7 +84,7 @@ void __pfault_fini(void) "0: nopr %%r7\n" EX_TABLE(0b, 0b) : - : [refbk] "a" (&pfault_fini_refbk), "m" (pfault_fini_refbk) + : [refbk] "a" (virt_to_phys(&pfault_fini_refbk)), "m" (pfault_fini_refbk) : "cc"); } diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c index 579461d471bb..bf92964246eb 100644 --- a/arch/s390/net/bpf_jit_comp.c +++ b/arch/s390/net/bpf_jit_comp.c @@ -2323,7 +2323,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) jit_data = fp->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { fp = orig_fp; goto out; diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 97bab20bc163..2a430722cbe4 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c @@ -523,7 +523,7 @@ static struct resource *__alloc_res(struct zpci_dev *zdev, unsigned long start, { struct resource *r; - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) return NULL; @@ -824,7 +824,7 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state) struct zpci_dev *zdev; int rc; - zdev = kzalloc(sizeof(*zdev), GFP_KERNEL); + zdev = kzalloc_obj(*zdev); if (!zdev) return ERR_PTR(-ENOMEM); @@ -1073,8 +1073,7 @@ static int zpci_mem_init(void) if (!zdev_fmb_cache) goto error_fmb; - zpci_iomap_start = kcalloc(ZPCI_IOMAP_ENTRIES, - sizeof(*zpci_iomap_start), GFP_KERNEL); + zpci_iomap_start = kzalloc_objs(*zpci_iomap_start, ZPCI_IOMAP_ENTRIES); if (!zpci_iomap_start) goto error_iomap; diff --git a/arch/s390/pci/pci_bus.c b/arch/s390/pci/pci_bus.c index 42a13e451f64..36a4807285fa 100644 --- a/arch/s390/pci/pci_bus.c +++ b/arch/s390/pci/pci_bus.c @@ -315,7 +315,7 @@ static struct zpci_bus *zpci_bus_alloc(int topo, bool topo_is_tid) { struct zpci_bus *zbus; - zbus = kzalloc(sizeof(*zbus), GFP_KERNEL); + zbus = kzalloc_obj(*zbus); if (!zbus) return NULL; diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c index e9dd45f3c09d..9c9ed3d8d959 100644 --- a/arch/s390/pci/pci_irq.c +++ b/arch/s390/pci/pci_irq.c @@ -563,8 +563,7 @@ static int __init zpci_directed_irq_init(void) iib.diib.disb_addr = virt_to_phys(zpci_sbv->vector); zpci_set_irq_ctrl(SIC_IRQ_MODE_DIRECT, 0, &iib); - zpci_ibv = kcalloc(num_possible_cpus(), sizeof(*zpci_ibv), - GFP_KERNEL); + zpci_ibv = kzalloc_objs(*zpci_ibv, num_possible_cpus()); if (!zpci_ibv) return -ENOMEM; @@ -590,7 +589,7 @@ static int __init zpci_directed_irq_init(void) static int __init zpci_floating_irq_init(void) { - zpci_ibv = kcalloc(ZPCI_NR_DEVICES, sizeof(*zpci_ibv), GFP_KERNEL); + zpci_ibv = kzalloc_objs(*zpci_ibv, ZPCI_NR_DEVICES); if (!zpci_ibv) return -ENOMEM; diff --git a/arch/sh/configs/dreamcast_defconfig b/arch/sh/configs/dreamcast_defconfig index 4573d5d64989..dd58797e8298 100644 --- a/arch/sh/configs/dreamcast_defconfig +++ b/arch/sh/configs/dreamcast_defconfig @@ -60,8 +60,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set # CONFIG_DNOTIFY is not set CONFIG_PROC_KCORE=y CONFIG_TMPFS=y diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 458115d83184..e751933ac840 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig @@ -78,8 +78,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=y CONFIG_SND_SEQUENCER=y diff --git a/arch/sh/configs/kfr2r09_defconfig b/arch/sh/configs/kfr2r09_defconfig index d80e83e7ec38..056ba52600f9 100644 --- a/arch/sh/configs/kfr2r09_defconfig +++ b/arch/sh/configs/kfr2r09_defconfig @@ -66,8 +66,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_CLUT224 is not set CONFIG_USB_GADGET=y CONFIG_USB_CDC_COMPOSITE=m CONFIG_MMC=y diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index 7cdaa909ffd6..1d9d543eef4c 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -71,8 +71,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_CLUT224 is not set CONFIG_USB_GADGET=y CONFIG_USB_GADGET_M66592=y CONFIG_USB_G_SERIAL=m diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index 0c54ab2b06e6..745490d4807f 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -50,8 +50,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=m CONFIG_SND_YMFPCI=m diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index 3173b616b2cb..cd90f5354459 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -55,8 +55,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=m CONFIG_SND_YMFPCI=m diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index 8ca46d704c8b..9b4f8f3a1fdf 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig @@ -79,8 +79,6 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SND=m # CONFIG_SND_DRIVERS is not set diff --git a/arch/sh/configs/se7780_defconfig b/arch/sh/configs/se7780_defconfig index 12463b766120..13fa6a59b8f1 100644 --- a/arch/sh/configs/se7780_defconfig +++ b/arch/sh/configs/se7780_defconfig @@ -66,8 +66,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set CONFIG_SOUND=y CONFIG_SOUND_PRIME=y CONFIG_HID_A4TECH=y diff --git a/arch/sh/configs/sh7785lcr_defconfig b/arch/sh/configs/sh7785lcr_defconfig index 2fcf50d8c820..8738c590d5a0 100644 --- a/arch/sh/configs/sh7785lcr_defconfig +++ b/arch/sh/configs/sh7785lcr_defconfig @@ -60,9 +60,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set -# CONFIG_LOGO_SUPERH_CLUT224 is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig index f51ff6b1ec38..e7924db29b69 100644 --- a/arch/sh/configs/urquell_defconfig +++ b/arch/sh/configs/urquell_defconfig @@ -86,9 +86,6 @@ CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set -# CONFIG_LOGO_SUPERH_MONO is not set -# CONFIG_LOGO_SUPERH_VGA16 is not set -# CONFIG_LOGO_SUPERH_CLUT224 is not set CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index 5b2c1fd254d7..3778c6a363ec 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c @@ -153,8 +153,7 @@ static int __init dmabrg_init(void) unsigned long or; int ret; - dmabrg_handlers = kcalloc(10, sizeof(struct dmabrg_handler), - GFP_KERNEL); + dmabrg_handlers = kzalloc_objs(struct dmabrg_handler, 10); if (!dmabrg_handlers) return -ENOMEM; diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c index 42103038a7d0..e55ef3c16a0f 100644 --- a/arch/sh/drivers/heartbeat.c +++ b/arch/sh/drivers/heartbeat.c @@ -91,7 +91,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev) if (pdev->dev.platform_data) { hd = pdev->dev.platform_data; } else { - hd = kzalloc(sizeof(struct heartbeat_data), GFP_KERNEL); + hd = kzalloc_obj(struct heartbeat_data); if (unlikely(!hd)) return -ENOMEM; } diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index a78b9a935585..cbbb94d41fd0 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -558,8 +558,7 @@ static int __init sh7786_pcie_init(void) if (unlikely(nr_ports == 0)) return -ENODEV; - sh7786_pcie_ports = kcalloc(nr_ports, sizeof(struct sh7786_pcie_port), - GFP_KERNEL); + sh7786_pcie_ports = kzalloc_objs(struct sh7786_pcie_port, nr_ports); if (unlikely(!sh7786_pcie_ports)) return -ENOMEM; diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c index 443cc6fd26a8..a39e2edd4dcb 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -46,7 +46,7 @@ static int switch_drv_probe(struct platform_device *pdev) struct push_switch *psw; int ret, irq; - psw = kzalloc(sizeof(struct push_switch), GFP_KERNEL); + psw = kzalloc_obj(struct push_switch); if (unlikely(!psw)) return -ENOMEM; diff --git a/arch/sh/kernel/cpu/sh4/sq.c b/arch/sh/kernel/cpu/sh4/sq.c index d289e99dc118..908a8e09113b 100644 --- a/arch/sh/kernel/cpu/sh4/sq.c +++ b/arch/sh/kernel/cpu/sh4/sq.c @@ -342,7 +342,7 @@ static int sq_dev_add(struct device *dev, struct subsys_interface *sif) struct kobject *kobj; int error; - sq_kobject[cpu] = kzalloc(sizeof(struct kobject), GFP_KERNEL); + sq_kobject[cpu] = kzalloc_obj(struct kobject); if (unlikely(!sq_kobject[cpu])) return -ENOMEM; diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c index a1b54bedc929..edcf3b172284 100644 --- a/arch/sh/kernel/dwarf.c +++ b/arch/sh/kernel/dwarf.c @@ -741,7 +741,7 @@ static int dwarf_parse_cie(void *entry, void *p, unsigned long len, unsigned long flags; int count; - cie = kzalloc(sizeof(*cie), GFP_KERNEL); + cie = kzalloc_obj(*cie); if (!cie) return -ENOMEM; @@ -874,7 +874,7 @@ static int dwarf_parse_fde(void *entry, u32 entry_type, int count; void *p = start; - fde = kzalloc(sizeof(*fde), GFP_KERNEL); + fde = kzalloc_obj(*fde); if (!fde) return -ENOMEM; diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index 008c30289eaa..169c63fb3c1d 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S @@ -89,6 +89,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c index a1a6485c9183..16b45d172fb0 100644 --- a/arch/sparc/kernel/central.c +++ b/arch/sparc/kernel/central.c @@ -63,7 +63,7 @@ static int clock_board_calc_nslots(struct clock_board *p) static int clock_board_probe(struct platform_device *op) { - struct clock_board *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct clock_board *p = kzalloc_obj(*p); int err = -ENOMEM; if (!p) { @@ -159,7 +159,7 @@ static struct platform_driver clock_board_driver = { static int fhc_probe(struct platform_device *op) { - struct fhc *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct fhc *p = kzalloc_obj(*p); int err = -ENOMEM; u32 reg; diff --git a/arch/sparc/kernel/chmc.c b/arch/sparc/kernel/chmc.c index d4c74d6b2e1b..d935177b6953 100644 --- a/arch/sparc/kernel/chmc.c +++ b/arch/sparc/kernel/chmc.c @@ -417,7 +417,7 @@ static int jbusmc_probe(struct platform_device *op) num_mem_regs = len / sizeof(*mem_regs); err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { printk(KERN_ERR PFX "Cannot allocate struct jbusmc.\n"); goto out; @@ -718,7 +718,7 @@ static int chmc_probe(struct platform_device *op) } err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { printk(KERN_ERR PFX "Could not allocate struct chmc.\n"); goto out; diff --git a/arch/sparc/kernel/cpumap.c b/arch/sparc/kernel/cpumap.c index 8fcf2d8c6bd2..d51ff010176c 100644 --- a/arch/sparc/kernel/cpumap.c +++ b/arch/sparc/kernel/cpumap.c @@ -194,7 +194,7 @@ static struct cpuinfo_tree *build_cpuinfo_tree(void) n = enumerate_cpuinfo_nodes(tmp_level); - new_tree = kzalloc(struct_size(new_tree, nodes, n), GFP_ATOMIC); + new_tree = kzalloc_flex(*new_tree, nodes, n, GFP_ATOMIC); if (!new_tree) return NULL; diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c index f7fc6f2af2f2..b34db8125bba 100644 --- a/arch/sparc/kernel/ds.c +++ b/arch/sparc/kernel/ds.c @@ -1175,7 +1175,7 @@ static int ds_probe(struct vio_dev *vdev, const struct vio_device_id *id) if (ds_version_printed++ == 0) printk(KERN_INFO "%s", version); - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); err = -ENOMEM; if (!dp) goto out_err; diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c index 46ef88bc9c26..7613ab0ffb89 100644 --- a/arch/sparc/kernel/iommu.c +++ b/arch/sparc/kernel/iommu.c @@ -312,6 +312,8 @@ static dma_addr_t dma_4u_map_phys(struct device *dev, phys_addr_t phys, if (direction != DMA_TO_DEVICE) iopte_protection |= IOPTE_WRITE; + phys &= IO_PAGE_MASK; + for (i = 0; i < npages; i++, base++, phys += IO_PAGE_SIZE) iopte_val(*base) = iopte_protection | phys; diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 5ebca5c7af1e..cbc0680a4642 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -238,7 +238,7 @@ unsigned long sparc_dma_alloc_resource(struct device *dev, size_t len) { struct resource *res; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return 0; res->name = dev->of_node->full_name; diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index ded463c82abd..c5466a9fd560 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c @@ -628,7 +628,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) if (unlikely(handler_data)) goto out; - handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct irq_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n"); prom_halt(); @@ -654,7 +654,7 @@ static unsigned int sun4v_build_common(u32 devhandle, unsigned int devino, if (!irq) goto out; - data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC); + data = kzalloc_obj(struct irq_handler_data, GFP_ATOMIC); if (unlikely(!data)) { pr_err("IRQ handler data allocation failed.\n"); irq_free(irq); diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c index 7f3cdb6f644d..826fe8ed0289 100644 --- a/arch/sparc/kernel/ldc.c +++ b/arch/sparc/kernel/ldc.c @@ -1171,7 +1171,7 @@ struct ldc_channel *ldc_alloc(unsigned long id, mssbuf = NULL; - lp = kzalloc(sizeof(*lp), GFP_KERNEL); + lp = kzalloc_obj(*lp); err = -ENOMEM; if (!lp) goto out_err; diff --git a/arch/sparc/kernel/leon_pci_grpci2.c b/arch/sparc/kernel/leon_pci_grpci2.c index 9f662340b5b2..c1cbdf88146c 100644 --- a/arch/sparc/kernel/leon_pci_grpci2.c +++ b/arch/sparc/kernel/leon_pci_grpci2.c @@ -721,7 +721,7 @@ static int grpci2_of_probe(struct platform_device *ofdev) goto err1; } - priv = grpci2priv = kzalloc(sizeof(struct grpci2_priv), GFP_KERNEL); + priv = grpci2priv = kzalloc_obj(struct grpci2_priv); if (grpci2priv == NULL) { err = -ENOMEM; goto err1; diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c index 284a4cafa432..b62b1d0291a4 100644 --- a/arch/sparc/kernel/of_device_32.c +++ b/arch/sparc/kernel/of_device_32.c @@ -340,7 +340,7 @@ static void __init build_device_resources(struct platform_device *op, static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc_obj(*op); const struct linux_prom_irqs *intr; struct dev_archdata *sd; int len, i; diff --git a/arch/sparc/kernel/of_device_64.c b/arch/sparc/kernel/of_device_64.c index f53092b07b9e..0b87eb629a62 100644 --- a/arch/sparc/kernel/of_device_64.c +++ b/arch/sparc/kernel/of_device_64.c @@ -633,7 +633,7 @@ static unsigned int __init build_one_device_irq(struct platform_device *op, static struct platform_device * __init scan_one_device(struct device_node *dp, struct device *parent) { - struct platform_device *op = kzalloc(sizeof(*op), GFP_KERNEL); + struct platform_device *op = kzalloc_obj(*op); const unsigned int *irq; struct dev_archdata *sd; int len, i; diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index b290107170e9..1603d50fdcad 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c @@ -355,6 +355,13 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm, dev->error_state = pci_channel_io_normal; dev->dma_mask = 0xffffffff; + /* + * Assume 64-bit addresses for MSI initially. Will be changed to 32-bit + * if MSI (rather than MSI-X) capability does not have + * PCI_MSI_FLAGS_64BIT. Can also be overridden by driver. + */ + dev->msi_addr_mask = DMA_BIT_MASK(64); + if (of_node_name_eq(node, "pci")) { /* a PCI-PCI bridge */ dev->hdr_type = PCI_HEADER_TYPE_BRIDGE; @@ -650,7 +657,7 @@ static void pci_claim_legacy_resources(struct pci_dev *dev) if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) return; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return; diff --git a/arch/sparc/kernel/pci_common.c b/arch/sparc/kernel/pci_common.c index 2576f4f31309..0eafcb2d88ce 100644 --- a/arch/sparc/kernel/pci_common.c +++ b/arch/sparc/kernel/pci_common.c @@ -336,7 +336,7 @@ static void pci_register_iommu_region(struct pci_pbm_info *pbm) NULL); if (vdma) { - struct resource *rp = kzalloc(sizeof(*rp), GFP_KERNEL); + struct resource *rp = kzalloc_obj(*rp); if (!rp) { pr_info("%s: Cannot allocate IOMMU resource.\n", diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c index 0b91bde80fdc..c35a8e3c1eae 100644 --- a/arch/sparc/kernel/pci_fire.c +++ b/arch/sparc/kernel/pci_fire.c @@ -468,13 +468,13 @@ static int fire_probe(struct platform_device *op) portid = of_getintprop_default(dp, "portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbminfo.\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c index 1efc98305ec7..199ab73f84af 100644 --- a/arch/sparc/kernel/pci_psycho.c +++ b/arch/sparc/kernel/pci_psycho.c @@ -519,7 +519,7 @@ static int psycho_probe(struct platform_device *op) upa_portid = of_getintprop_default(dp, "upa-portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; @@ -529,7 +529,7 @@ static int psycho_probe(struct platform_device *op) if (pbm->sibling) { iommu = pbm->sibling->iommu; } else { - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c index a84598568300..1109d5b344eb 100644 --- a/arch/sparc/kernel/pci_sabre.c +++ b/arch/sparc/kernel/pci_sabre.c @@ -482,13 +482,13 @@ static int sabre_probe(struct platform_device *op) } err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; } - iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + iommu = kzalloc_obj(*iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM iommu.\n"); goto out_free_controller; diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c index 93cd9e5a8099..4348ca2c4a3f 100644 --- a/arch/sparc/kernel/pci_schizo.c +++ b/arch/sparc/kernel/pci_schizo.c @@ -1426,7 +1426,7 @@ static int __schizo_init(struct platform_device *op, unsigned long chip_type) portid = of_getintprop_default(dp, "portid", 0xff); err = -ENOMEM; - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Cannot allocate pci_pbm_info.\n"); goto out_err; @@ -1434,7 +1434,7 @@ static int __schizo_init(struct platform_device *op, unsigned long chip_type) pbm->sibling = schizo_find_sibling(portid, chip_type); - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Cannot allocate PBM A iommu.\n"); goto out_free_pbm; diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c index 791f0a76665f..61f14b4c8f90 100644 --- a/arch/sparc/kernel/pci_sun4v.c +++ b/arch/sparc/kernel/pci_sun4v.c @@ -410,6 +410,8 @@ static dma_addr_t dma_4v_map_phys(struct device *dev, phys_addr_t phys, iommu_batch_start(dev, prot, entry); + phys &= IO_PAGE_MASK; + for (i = 0; i < npages; i++, phys += IO_PAGE_SIZE) { long err = iommu_batch_add(phys, mask); if (unlikely(err < 0L)) @@ -754,7 +756,7 @@ static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm) unsigned long order; unsigned long err; - iotsb = kzalloc(sizeof(*iotsb), GFP_KERNEL); + iotsb = kzalloc_obj(*iotsb); if (!iotsb) { err = -ENOMEM; goto out_err; @@ -1292,13 +1294,13 @@ static int pci_sun4v_probe(struct platform_device *op) iommu_batch_initialized = 1; } - pbm = kzalloc(sizeof(*pbm), GFP_KERNEL); + pbm = kzalloc_obj(*pbm); if (!pbm) { printk(KERN_ERR PFX "Could not allocate pci_pbm_info\n"); goto out_err; } - iommu = kzalloc(sizeof(struct iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct iommu); if (!iommu) { printk(KERN_ERR PFX "Could not allocate pbm iommu\n"); goto out_free_controller; @@ -1307,7 +1309,7 @@ static int pci_sun4v_probe(struct platform_device *op) pbm->iommu = iommu; iommu->atu = NULL; if (hv_atu) { - atu = kzalloc(sizeof(*atu), GFP_KERNEL); + atu = kzalloc_obj(*atu); if (!atu) pr_err(PFX "Could not allocate atu\n"); else diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index d7c911724435..4cd32ccc5191 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -466,7 +466,7 @@ static int pdev_to_pnode(struct linux_pbm_info *pbm, struct pci_dev *pdev) static inline struct pcidev_cookie *pci_devcookie_alloc(void) { - return kmalloc(sizeof(struct pcidev_cookie), GFP_ATOMIC); + return kmalloc_obj(struct pcidev_cookie, GFP_ATOMIC); } static void pcic_map_pci_device(struct linux_pcic *pcic, diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c index 0bababf6f2bc..bb2794ce7aad 100644 --- a/arch/sparc/kernel/sbus.c +++ b/arch/sparc/kernel/sbus.c @@ -556,8 +556,8 @@ static void __init sbus_iommu_init(struct platform_device *op) } regs = pr->phys_addr; - iommu = kzalloc(sizeof(*iommu), GFP_ATOMIC); - strbuf = kzalloc(sizeof(*strbuf), GFP_ATOMIC); + iommu = kzalloc_obj(*iommu, GFP_ATOMIC); + strbuf = kzalloc_obj(*strbuf, GFP_ATOMIC); if (!iommu || !strbuf) goto fatal_memory_error; diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c index 704375c061e7..1b0db16cd37b 100644 --- a/arch/sparc/kernel/setup_32.c +++ b/arch/sparc/kernel/setup_32.c @@ -388,7 +388,7 @@ static int __init topology_init(void) err = 0; for_each_online_cpu(i) { - struct cpu *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct cpu *p = kzalloc_obj(*p); if (!p) err = -ENOMEM; else diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 5cbd6ed5ef6f..371460e34484 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c @@ -297,8 +297,7 @@ static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg, unsigned long hv_err; int i; - hdesc = kzalloc(struct_size(hdesc, maps, num_kernel_image_mappings), - GFP_KERNEL); + hdesc = kzalloc_flex(*hdesc, maps, num_kernel_image_mappings); if (!hdesc) { printk(KERN_ERR "ldom_startcpu_cpuid: Cannot allocate " "hvtramp_descr.\n"); diff --git a/arch/sparc/kernel/starfire.c b/arch/sparc/kernel/starfire.c index b8cd57d9182b..d8ee9a69ae31 100644 --- a/arch/sparc/kernel/starfire.c +++ b/arch/sparc/kernel/starfire.c @@ -50,7 +50,7 @@ void starfire_hookup(int upaid) struct starfire_irqinfo *p; unsigned long treg_base, hwmid, i; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) { prom_printf("starfire_hookup: No memory, this is insane.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c index 9a137c70e8d1..95683ecdc590 100644 --- a/arch/sparc/kernel/sun4d_irq.c +++ b/arch/sparc/kernel/sun4d_irq.c @@ -304,7 +304,7 @@ static unsigned int _sun4d_build_device_irq(unsigned int real_irq, if (unlikely(handler_data)) goto err_out; - handler_data = kzalloc(sizeof(struct sun4d_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct sun4d_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(sun4d_handler_data) failed.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sun4m_irq.c b/arch/sparc/kernel/sun4m_irq.c index 1079638986b5..fe8cfb1cdd3a 100644 --- a/arch/sparc/kernel/sun4m_irq.c +++ b/arch/sparc/kernel/sun4m_irq.c @@ -268,7 +268,7 @@ static unsigned int sun4m_build_device_irq(struct platform_device *op, if (unlikely(handler_data)) goto out; - handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC); + handler_data = kzalloc_obj(struct sun4m_handler_data, GFP_ATOMIC); if (unlikely(!handler_data)) { prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n"); prom_halt(); diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index dbf118b40601..ecefcffcf7b1 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -647,8 +647,7 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, } if (!current_thread_info()->utraps) { current_thread_info()->utraps = - kcalloc(UT_TRAP_INSTRUCTION_31 + 1, sizeof(long), - GFP_KERNEL); + kzalloc_objs(long, UT_TRAP_INSTRUCTION_31 + 1); if (!current_thread_info()->utraps) return -ENOMEM; current_thread_info()->utraps[0] = 1; @@ -658,9 +657,7 @@ SYSCALL_DEFINE5(utrap_install, utrap_entry_t, type, unsigned long *p = current_thread_info()->utraps; current_thread_info()->utraps = - kmalloc_array(UT_TRAP_INSTRUCTION_31 + 1, - sizeof(long), - GFP_KERNEL); + kmalloc_objs(long, UT_TRAP_INSTRUCTION_31 + 1); if (!current_thread_info()->utraps) { current_thread_info()->utraps = p; return -ENOMEM; diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 8c7dd72ef334..8b4f55047716 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -325,7 +325,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, return NULL; } - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) { printk(KERN_ERR "VIO: Could not allocate vio_dev\n"); return NULL; diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index f1b86eb30340..7ea510d9b42f 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S @@ -191,6 +191,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 3c3a6607fa51..f46394c46a76 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -3070,7 +3070,7 @@ static int __init report_memory(void) kernel_lds_init(); for (i = 0; i < pavail_ents; i++) { - res = kzalloc(sizeof(struct resource), GFP_KERNEL); + res = kzalloc_obj(struct resource); if (!res) { pr_warn("Failed to allocate source.\n"); diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index d409cb450de4..2b5e40cc9d58 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -44,7 +44,7 @@ static void __init iounit_iommu_init(struct platform_device *op) iopte_t __iomem *xpt; iopte_t __iomem *xptend; - iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); + iounit = kzalloc_obj(struct iounit_struct, GFP_ATOMIC); if (!iounit) { prom_printf("SUN4D: Cannot alloc iounit, halting.\n"); prom_halt(); diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index f48adf62724a..df0eb99a4175 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -64,7 +64,7 @@ static void __init sbus_iommu_init(struct platform_device *op) unsigned long base; unsigned long tmp; - iommu = kmalloc(sizeof(struct iommu_struct), GFP_KERNEL); + iommu = kmalloc_obj(struct iommu_struct); if (!iommu) { prom_printf("Unable to allocate iommu structure\n"); prom_halt(); diff --git a/arch/sparc/net/bpf_jit_comp_64.c b/arch/sparc/net/bpf_jit_comp_64.c index 73bf0aea8baf..b23d1c645ae5 100644 --- a/arch/sparc/net/bpf_jit_comp_64.c +++ b/arch/sparc/net/bpf_jit_comp_64.c @@ -1505,7 +1505,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; diff --git a/arch/sparc/vdso/vma.c b/arch/sparc/vdso/vma.c index bab7a59575e8..c454689ce5fa 100644 --- a/arch/sparc/vdso/vma.c +++ b/arch/sparc/vdso/vma.c @@ -266,7 +266,7 @@ static int __init init_vdso_image(const struct vdso_image *image, if (WARN_ON(image->size % PAGE_SIZE != 0)) goto oom; - cpp = kcalloc(cnpages, sizeof(struct page *), GFP_KERNEL); + cpp = kzalloc_objs(struct page *, cnpages); vdso_mapping->pages = cpp; if (!cpp) @@ -288,7 +288,7 @@ static int __init init_vdso_image(const struct vdso_image *image, dnpages = (sizeof(struct vvar_data) / PAGE_SIZE) + 1; if (WARN_ON(dnpages != 1)) goto oom; - dpp = kcalloc(dnpages, sizeof(struct page *), GFP_KERNEL); + dpp = kzalloc_objs(struct page *, dnpages); vvar_mapping.pages = dpp; if (!dpp) diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 26442db7d608..db2bb032be30 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -504,7 +504,7 @@ static struct chan *parse_chan(struct line *line, char *str, int device, return NULL; } - chan = kmalloc(sizeof(*chan), GFP_ATOMIC); + chan = kmalloc_obj(*chan, GFP_ATOMIC); if (chan == NULL) { *error_out = "Memory allocation failed"; return NULL; diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c index 0ac149de1ac0..7ce98f148eb3 100644 --- a/arch/um/drivers/hostaudio_kern.c +++ b/arch/um/drivers/hostaudio_kern.c @@ -186,7 +186,7 @@ static int hostaudio_open(struct inode *inode, struct file *file) kernel_param_unlock(THIS_MODULE); #endif - state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); + state = kmalloc_obj(struct hostaudio_state); if (state == NULL) return -ENOMEM; @@ -247,7 +247,7 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file) printk(KERN_DEBUG "hostmixer: open called (host: %s)\n", mixer); #endif - state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); + state = kmalloc_obj(struct hostmixer_state); if (state == NULL) return -ENOMEM; diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 43d8959cc746..c851a592809c 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -672,7 +672,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_port *port, { struct winch *winch; - winch = kmalloc(sizeof(*winch), GFP_KERNEL); + winch = kmalloc_obj(*winch); if (winch == NULL) { printk(KERN_ERR "register_winch_irq - kmalloc failed\n"); goto cleanup; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index ff4bda95b9c7..e2a9e8879f58 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -87,7 +87,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) if (req.cmd->context == MCONSOLE_INTR) (*req.cmd->handler)(&req); else { - new = kmalloc(sizeof(*new), GFP_NOWAIT); + new = kmalloc_obj(*new, GFP_NOWAIT); if (new == NULL) mconsole_reply(&req, "Out of memory", 1, 0); else { diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index a4508470df78..7b3ff4af1db6 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -88,7 +88,7 @@ static int port_accept(struct port_list *port) goto out; } - conn = kmalloc(sizeof(*conn), GFP_ATOMIC); + conn = kmalloc_obj(*conn, GFP_ATOMIC); if (conn == NULL) { printk(KERN_ERR "port_accept : failed to allocate " "connection\n"); @@ -170,7 +170,7 @@ void *port_data(int port_num) if (port->port == port_num) goto found; } - port = kmalloc(sizeof(struct port_list), GFP_KERNEL); + port = kmalloc_obj(struct port_list); if (port == NULL) { printk(KERN_ERR "Allocation of port list failed\n"); goto out; @@ -202,7 +202,7 @@ void *port_data(int port_num) list_add(&port->list, &ports); found: - dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); + dev = kmalloc_obj(struct port_dev); if (dev == NULL) { printk(KERN_ERR "Allocation of port device entry failed\n"); goto out; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 37455e74d314..20fc33300a95 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -69,11 +69,11 @@ struct io_thread_req { }; -static struct io_thread_req * (*irq_req_buffer)[]; +static struct io_thread_req **irq_req_buffer; static struct io_thread_req *irq_remainder; static int irq_remainder_size; -static struct io_thread_req * (*io_req_buffer)[]; +static struct io_thread_req **io_req_buffer; static struct io_thread_req *io_remainder; static int io_remainder_size; @@ -398,7 +398,7 @@ static int thread_fd = -1; static int bulk_req_safe_read( int fd, - struct io_thread_req * (*request_buffer)[], + struct io_thread_req **request_buffer, struct io_thread_req **remainder, int *remainder_size, int max_recs @@ -465,7 +465,7 @@ static irqreturn_t ubd_intr(int irq, void *dev) &irq_remainder, &irq_remainder_size, UBD_REQ_BUFFER_SIZE)) >= 0) { for (i = 0; i < len / sizeof(struct io_thread_req *); i++) - ubd_end_request((*irq_req_buffer)[i]); + ubd_end_request(irq_req_buffer[i]); } if (len < 0 && len != -EAGAIN) @@ -1069,20 +1069,16 @@ static int __init ubd_init(void) if (register_blkdev(UBD_MAJOR, "ubd")) return -1; - irq_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, - sizeof(struct io_thread_req *), - GFP_KERNEL - ); + irq_req_buffer = kmalloc_objs(struct io_thread_req *, + UBD_REQ_BUFFER_SIZE); irq_remainder = 0; if (irq_req_buffer == NULL) { printk(KERN_ERR "Failed to initialize ubd buffering\n"); return -ENOMEM; } - io_req_buffer = kmalloc_array(UBD_REQ_BUFFER_SIZE, - sizeof(struct io_thread_req *), - GFP_KERNEL - ); + io_req_buffer = kmalloc_objs(struct io_thread_req *, + UBD_REQ_BUFFER_SIZE); io_remainder = 0; @@ -1516,7 +1512,7 @@ void *io_thread(void *arg) } for (count = 0; count < n/sizeof(struct io_thread_req *); count++) { - struct io_thread_req *req = (*io_req_buffer)[count]; + struct io_thread_req *req = io_req_buffer[count]; int i; io_count++; diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 28cfe1c700f0..2cc90055499a 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -515,7 +515,7 @@ static struct vector_queue *create_queue( struct iovec *iov; struct mmsghdr *mmsg_vector; - result = kmalloc(sizeof(struct vector_queue), GFP_KERNEL); + result = kmalloc_obj(struct vector_queue); if (result == NULL) return NULL; result->max_depth = max_size; @@ -544,15 +544,9 @@ static struct vector_queue *create_queue( result->max_iov_frags = num_extra_frags; for (i = 0; i < max_size; i++) { if (vp->header_size > 0) - iov = kmalloc_array(3 + num_extra_frags, - sizeof(struct iovec), - GFP_KERNEL - ); + iov = kmalloc_objs(struct iovec, 3 + num_extra_frags); else - iov = kmalloc_array(2 + num_extra_frags, - sizeof(struct iovec), - GFP_KERNEL - ); + iov = kmalloc_objs(struct iovec, 2 + num_extra_frags); if (iov == NULL) goto out_fail; mmsg_vector->msg_hdr.msg_iov = iov; @@ -1385,7 +1379,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev, kfree(vp->bpf->filter); vp->bpf->filter = NULL; } else { - vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC); + vp->bpf = kmalloc_obj(struct sock_fprog, GFP_ATOMIC); if (vp->bpf == NULL) { netdev_err(dev, "failed to allocate memory for firmware\n"); goto flash_fail; @@ -1587,7 +1581,7 @@ static void vector_eth_configure( struct vector_private *vp; int err; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (device == NULL) { pr_err("Failed to allocate struct vector_device for vec%d\n", n); return; diff --git a/arch/um/drivers/vector_transports.c b/arch/um/drivers/vector_transports.c index 0794d23f07cb..ddd127ee9678 100644 --- a/arch/um/drivers/vector_transports.c +++ b/arch/um/drivers/vector_transports.c @@ -245,7 +245,7 @@ static int build_gre_transport_data(struct vector_private *vp) int temp_rx; int temp_tx; - vp->transport_data = kmalloc(sizeof(struct uml_gre_data), GFP_KERNEL); + vp->transport_data = kmalloc_obj(struct uml_gre_data); if (vp->transport_data == NULL) return -ENOMEM; td = vp->transport_data; @@ -307,8 +307,7 @@ static int build_l2tpv3_transport_data(struct vector_private *vp) unsigned long temp_rx; unsigned long temp_tx; - vp->transport_data = kmalloc( - sizeof(struct uml_l2tpv3_data), GFP_KERNEL); + vp->transport_data = kmalloc_obj(struct uml_l2tpv3_data); if (vp->transport_data == NULL) return -ENOMEM; diff --git a/arch/um/drivers/vfio_kern.c b/arch/um/drivers/vfio_kern.c index 915812a79bfc..e6dab473cde4 100644 --- a/arch/um/drivers/vfio_kern.c +++ b/arch/um/drivers/vfio_kern.c @@ -107,7 +107,7 @@ static int uml_vfio_open_group(int group_id) } } - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; @@ -514,9 +514,8 @@ static void uml_vfio_open_device(struct uml_vfio_device *dev) goto teardown_udev; } - dev->intr_ctx = kmalloc_array(dev->udev.irq_count, - sizeof(struct uml_vfio_intr_ctx), - GFP_KERNEL); + dev->intr_ctx = kmalloc_objs(struct uml_vfio_intr_ctx, + dev->udev.irq_count); if (!dev->intr_ctx) { pr_err("Failed to allocate interrupt context (%s)\n", dev->name); @@ -600,7 +599,7 @@ static struct uml_vfio_device *uml_vfio_add_device(const char *device) if (uml_vfio_find_device(device)) return ERR_PTR(-EEXIST); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/arch/um/drivers/virtio_pcidev.c b/arch/um/drivers/virtio_pcidev.c index f9b4b6f7582c..2bf5a645db45 100644 --- a/arch/um/drivers/virtio_pcidev.c +++ b/arch/um/drivers/virtio_pcidev.c @@ -537,7 +537,7 @@ static int virtio_pcidev_virtio_probe(struct virtio_device *vdev) struct virtio_pcidev_device *dev; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index c24da0cf1627..7425a8548141 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c @@ -965,7 +965,7 @@ static struct virtqueue *vu_setup_vq(struct virtio_device *vdev, int num = MAX_SUPPORTED_QUEUE_SIZE; int rc; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { rc = -ENOMEM; goto error_kzalloc; @@ -1217,7 +1217,7 @@ static int virtio_uml_probe(struct platform_device *pdev) return PTR_ERR(pdata); } - vu_dev = kzalloc(sizeof(*vu_dev), GFP_KERNEL); + vu_dev = kzalloc_obj(*vu_dev); if (!vu_dev) return -ENOMEM; diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index 3971252cb1a6..d630cb19e14a 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -45,7 +45,7 @@ int xterm_fd(int socket, int *pid_out) struct xterm_wait *data; int err, ret; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (data == NULL) { printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); return -ENOMEM; diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index a36b7918a011..ad3cefeff2ac 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -172,6 +172,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index f4b13f15a9c1..5929d498b65f 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -326,7 +326,7 @@ static int activate_fd(int irq, int fd, enum um_irq_type type, void *dev_id, /* don't restore interrupts */ raw_spin_unlock(&irq_lock); - new = kzalloc(sizeof(*irq_entry), GFP_ATOMIC); + new = kzalloc_obj(*irq_entry, GFP_ATOMIC); if (!new) { local_irq_restore(flags); return -ENOMEM; diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index a409d4b66114..30aa24348d60 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -113,6 +113,7 @@ SECTIONS STABS_DEBUG DWARF_DEBUG + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 68f9d7a1683b..b8b2b7bea1d3 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -113,6 +113,7 @@ vmlinux-objs-$(CONFIG_EFI_SBAT) += $(obj)/sbat.o ifdef CONFIG_EFI_SBAT $(obj)/sbat.o: $(CONFIG_EFI_SBAT_FILE) +AFLAGS_sbat.o += -I $(srctree) endif $(obj)/vmlinux: $(vmlinux-objs-y) $(vmlinux-libs-y) FORCE diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c index c8c1464b3a56..e468476e9e4a 100644 --- a/arch/x86/boot/compressed/sev.c +++ b/arch/x86/boot/compressed/sev.c @@ -28,17 +28,17 @@ #include "sev.h" static struct ghcb boot_ghcb_page __aligned(PAGE_SIZE); -struct ghcb *boot_ghcb; +struct ghcb *boot_ghcb __section(".data"); #undef __init #define __init #define __BOOT_COMPRESSED -u8 snp_vmpl; -u16 ghcb_version; +u8 snp_vmpl __section(".data"); +u16 ghcb_version __section(".data"); -u64 boot_svsm_caa_pa; +u64 boot_svsm_caa_pa __section(".data"); /* Include code for early handlers */ #include "../../boot/startup/sev-shared.c" @@ -188,6 +188,7 @@ bool sev_es_check_ghcb_fault(unsigned long address) MSR_AMD64_SNP_RESERVED_BIT13 | \ MSR_AMD64_SNP_RESERVED_BIT15 | \ MSR_AMD64_SNP_SECURE_AVIC | \ + MSR_AMD64_SNP_RESERVED_BITS19_22 | \ MSR_AMD64_SNP_RESERVED_MASK) #ifdef CONFIG_AMD_SECURE_AVIC diff --git a/arch/x86/boot/compressed/vmlinux.lds.S b/arch/x86/boot/compressed/vmlinux.lds.S index 587ce3e7c504..e0b152715d9c 100644 --- a/arch/x86/boot/compressed/vmlinux.lds.S +++ b/arch/x86/boot/compressed/vmlinux.lds.S @@ -88,7 +88,7 @@ SECTIONS /DISCARD/ : { *(.dynamic) *(.dynsym) *(.dynstr) *(.dynbss) *(.hash) *(.gnu.hash) - *(.note.*) + *(.note.*) *(.modinfo) } .got.plt (INFO) : { diff --git a/arch/x86/boot/startup/sev-shared.c b/arch/x86/boot/startup/sev-shared.c index a0fa8bb2b945..d9ac3a929d33 100644 --- a/arch/x86/boot/startup/sev-shared.c +++ b/arch/x86/boot/startup/sev-shared.c @@ -31,7 +31,7 @@ static u32 cpuid_std_range_max __ro_after_init; static u32 cpuid_hyp_range_max __ro_after_init; static u32 cpuid_ext_range_max __ro_after_init; -bool sev_snp_needs_sfw; +bool sev_snp_needs_sfw __section(".data"); void __noreturn sev_es_terminate(unsigned int set, unsigned int reason) diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c index 1b86f48c7e84..7ed3da998489 100644 --- a/arch/x86/coco/sev/core.c +++ b/arch/x86/coco/sev/core.c @@ -89,6 +89,7 @@ static const char * const sev_status_feat_names[] = { [MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt", [MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt", [MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC", + [MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT] = "IBPBOnEntry", }; /* @@ -1542,7 +1543,7 @@ static struct aesgcm_ctx *snp_init_crypto(u8 *key, size_t keylen) { struct aesgcm_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -1590,7 +1591,7 @@ struct snp_msg_desc *snp_msg_alloc(void) BUILD_BUG_ON(sizeof(struct snp_guest_msg) > PAGE_SIZE); - mdesc = kzalloc(sizeof(struct snp_msg_desc), GFP_KERNEL); + mdesc = kzalloc_obj(struct snp_msg_desc); if (!mdesc) return ERR_PTR(-ENOMEM); @@ -1945,7 +1946,7 @@ static int __init snp_get_tsc_info(void) struct snp_guest_req req = {}; int rc = -ENOMEM; - tsc_req = kzalloc(sizeof(*tsc_req), GFP_KERNEL); + tsc_req = kzalloc_obj(*tsc_req); if (!tsc_req) return rc; diff --git a/arch/x86/entry/entry_fred.c b/arch/x86/entry/entry_fred.c index a9b72997103d..88c757ac8ccd 100644 --- a/arch/x86/entry/entry_fred.c +++ b/arch/x86/entry/entry_fred.c @@ -160,8 +160,6 @@ void __init fred_complete_exception_setup(void) static noinstr void fred_extint(struct pt_regs *regs) { unsigned int vector = regs->fred_ss.vector; - unsigned int index = array_index_nospec(vector - FIRST_SYSTEM_VECTOR, - NR_SYSTEM_VECTORS); if (WARN_ON_ONCE(vector < FIRST_EXTERNAL_VECTOR)) return; @@ -170,7 +168,8 @@ static noinstr void fred_extint(struct pt_regs *regs) irqentry_state_t state = irqentry_enter(regs); instrumentation_begin(); - sysvec_table[index](regs); + sysvec_table[array_index_nospec(vector - FIRST_SYSTEM_VECTOR, + NR_SYSTEM_VECTORS)](regs); instrumentation_end(); irqentry_exit(regs, state); } else { diff --git a/arch/x86/entry/vdso/vdso32/sigreturn.S b/arch/x86/entry/vdso/vdso32/sigreturn.S index b433353bc8e3..b33fcc501ba3 100644 --- a/arch/x86/entry/vdso/vdso32/sigreturn.S +++ b/arch/x86/entry/vdso/vdso32/sigreturn.S @@ -35,9 +35,38 @@ #endif .endm +/* + * WARNING: + * + * A bug in the libgcc unwinder as of at least gcc 15.2 (2026) means that + * the unwinder fails to recognize the signal frame flag. + * + * There is a hacky legacy fallback path in libgcc which ends up + * getting invoked instead. It happens to work as long as BOTH of the + * following conditions are true: + * + * 1. There is at least one byte before the each of the sigreturn + * functions which falls outside any function. This is enforced by + * an explicit nop instruction before the ALIGN. + * 2. The code sequences between the entry point up to and including + * the int $0x80 below need to match EXACTLY. Do not change them + * in any way. The exact byte sequences are: + * + * __kernel_sigreturn: + * 0: 58 pop %eax + * 1: b8 77 00 00 00 mov $0x77,%eax + * 6: cd 80 int $0x80 + * + * __kernel_rt_sigreturn: + * 0: b8 ad 00 00 00 mov $0xad,%eax + * 5: cd 80 int $0x80 + * + * For details, see: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124050 + */ .text .globl __kernel_sigreturn .type __kernel_sigreturn,@function + nop /* libgcc hack: see comment above */ ALIGN __kernel_sigreturn: STARTPROC_SIGNAL_FRAME IA32_SIGFRAME_sigcontext @@ -52,6 +81,7 @@ SYM_INNER_LABEL(vdso32_sigreturn_landing_pad, SYM_L_GLOBAL) .globl __kernel_rt_sigreturn .type __kernel_rt_sigreturn,@function + nop /* libgcc hack: see comment above */ ALIGN __kernel_rt_sigreturn: STARTPROC_SIGNAL_FRAME IA32_RT_SIGFRAME_sigcontext diff --git a/arch/x86/events/amd/iommu.c b/arch/x86/events/amd/iommu.c index a721da9987dd..07b110e8418a 100644 --- a/arch/x86/events/amd/iommu.c +++ b/arch/x86/events/amd/iommu.c @@ -387,7 +387,7 @@ static __init int _init_events_attrs(void) while (amd_iommu_v2_event_descs[i].attr.attr.name) i++; - attrs = kcalloc(i + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, i + 1); if (!attrs) return -ENOMEM; @@ -422,7 +422,7 @@ static __init int init_one_iommu(unsigned int idx) struct perf_amd_iommu *perf_iommu; int ret; - perf_iommu = kzalloc(sizeof(struct perf_amd_iommu), GFP_KERNEL); + perf_iommu = kzalloc_obj(struct perf_amd_iommu); if (!perf_iommu) return -ENOMEM; diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c index 9293ce50574d..dd956cfcadef 100644 --- a/arch/x86/events/amd/uncore.c +++ b/arch/x86/events/amd/uncore.c @@ -726,7 +726,7 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu) goto done; /* No grouping, single instance for a system */ - uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL); + uncore->pmus = kzalloc_obj(*uncore->pmus); if (!uncore->pmus) goto done; @@ -860,7 +860,7 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu) goto done; /* No grouping, single instance for a system */ - uncore->pmus = kzalloc(sizeof(*uncore->pmus), GFP_KERNEL); + uncore->pmus = kzalloc_obj(*uncore->pmus); if (!uncore->pmus) goto done; diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index d4468efbdcd9..03ce1bc7ef2e 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -2389,7 +2389,7 @@ static struct cpu_hw_events *allocate_fake_cpuc(struct pmu *event_pmu) struct cpu_hw_events *cpuc; int cpu; - cpuc = kzalloc(sizeof(*cpuc), GFP_KERNEL); + cpuc = kzalloc_obj(*cpuc); if (!cpuc) return ERR_PTR(-ENOMEM); cpuc->is_fake = 1; diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index f3ae1f8ee3cd..cf3a4fe06ff2 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c @@ -7378,9 +7378,8 @@ static __always_inline int intel_pmu_init_hybrid(enum hybrid_pmu_type pmus) int idx = 0, bit; x86_pmu.num_hybrid_pmus = hweight_long(pmus_mask); - x86_pmu.hybrid_pmu = kcalloc(x86_pmu.num_hybrid_pmus, - sizeof(struct x86_hybrid_pmu), - GFP_KERNEL); + x86_pmu.hybrid_pmu = kzalloc_objs(struct x86_hybrid_pmu, + x86_pmu.num_hybrid_pmus); if (!x86_pmu.hybrid_pmu) return -ENOMEM; diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c index 4684649109d9..786bd51a0d89 100644 --- a/arch/x86/events/intel/uncore.c +++ b/arch/x86/events/intel/uncore.c @@ -107,7 +107,7 @@ struct pci2phy_map *__find_pci2phy_map(int segment) if (!alloc) { raw_spin_unlock(&pci2phy_map_lock); - alloc = kmalloc(sizeof(struct pci2phy_map), GFP_KERNEL); + alloc = kmalloc_obj(struct pci2phy_map); raw_spin_lock(&pci2phy_map_lock); if (!alloc) @@ -990,7 +990,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type) size_t size; int i, j; - pmus = kcalloc(type->num_boxes, sizeof(*pmus), GFP_KERNEL); + pmus = kzalloc_objs(*pmus, type->num_boxes); if (!pmus) return -ENOMEM; @@ -1016,8 +1016,7 @@ static int __init uncore_type_init(struct intel_uncore_type *type) } *attr_group; for (i = 0; type->event_descs[i].attr.attr.name; i++); - attr_group = kzalloc(struct_size(attr_group, attrs, i + 1), - GFP_KERNEL); + attr_group = kzalloc_flex(*attr_group, attrs, i + 1); if (!attr_group) goto err; diff --git a/arch/x86/events/intel/uncore_discovery.c b/arch/x86/events/intel/uncore_discovery.c index b46575254dbe..12e259a988dd 100644 --- a/arch/x86/events/intel/uncore_discovery.c +++ b/arch/x86/events/intel/uncore_discovery.c @@ -68,7 +68,7 @@ add_uncore_discovery_type(struct uncore_unit_discovery *unit) return NULL; } - type = kzalloc(sizeof(struct intel_uncore_discovery_type), GFP_KERNEL); + type = kzalloc_obj(struct intel_uncore_discovery_type); if (!type) return NULL; @@ -215,7 +215,7 @@ uncore_insert_box_info(struct uncore_unit_discovery *unit, return; } - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return; @@ -744,8 +744,8 @@ intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra struct rb_node *node; int i = 0; - uncores = kcalloc(num_discovered_types[type_id] + num_extra + 1, - sizeof(struct intel_uncore_type *), GFP_KERNEL); + uncores = kzalloc_objs(struct intel_uncore_type *, + num_discovered_types[type_id] + num_extra + 1); if (!uncores) return empty_uncore; @@ -754,7 +754,7 @@ intel_uncore_generic_init_uncores(enum uncore_access_type type_id, int num_extra if (type->access_type != type_id) continue; - uncore = kzalloc(sizeof(struct intel_uncore_type), GFP_KERNEL); + uncore = kzalloc_obj(struct intel_uncore_type); if (!uncore) break; diff --git a/arch/x86/events/intel/uncore_snbep.c b/arch/x86/events/intel/uncore_snbep.c index 7ca0429c4004..0a1d08136cc1 100644 --- a/arch/x86/events/intel/uncore_snbep.c +++ b/arch/x86/events/intel/uncore_snbep.c @@ -3748,12 +3748,12 @@ static int pmu_alloc_topology(struct intel_uncore_type *type, int topology_type) if (!type->num_boxes) return -EPERM; - topology = kcalloc(uncore_max_dies(), sizeof(*topology), GFP_KERNEL); + topology = kzalloc_objs(*topology, uncore_max_dies()); if (!topology) goto err; for (die = 0; die < uncore_max_dies(); die++) { - topology[die] = kcalloc(type->num_boxes, sizeof(**topology), GFP_KERNEL); + topology[die] = kzalloc_objs(**topology, type->num_boxes); if (!topology[die]) goto clear; for (idx = 0; idx < type->num_boxes; idx++) { @@ -3882,11 +3882,11 @@ pmu_set_mapping(struct intel_uncore_type *type, struct attribute_group *ag, goto clear_topology; /* One more for NULL. */ - attrs = kcalloc((uncore_max_dies() + 1), sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, (uncore_max_dies() + 1)); if (!attrs) goto clear_topology; - eas = kcalloc(uncore_max_dies(), sizeof(*eas), GFP_KERNEL); + eas = kzalloc_objs(*eas, uncore_max_dies()); if (!eas) goto clear_attrs; @@ -6411,7 +6411,7 @@ static void spr_update_device_location(int type_id) } else return; - root = kzalloc(sizeof(struct rb_root), GFP_KERNEL); + root = kzalloc_obj(struct rb_root); if (!root) { type->num_boxes = 0; return; @@ -6424,7 +6424,7 @@ static void spr_update_device_location(int type_id) if (die < 0) continue; - unit = kzalloc(sizeof(*unit), GFP_KERNEL); + unit = kzalloc_obj(*unit); if (!unit) continue; unit->die = die; @@ -6497,6 +6497,32 @@ static struct intel_uncore_type gnr_uncore_ubox = { .attr_update = uncore_alias_groups, }; +static struct uncore_event_desc gnr_uncore_imc_events[] = { + INTEL_UNCORE_EVENT_DESC(clockticks, "event=0x01,umask=0x00"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0, "event=0x05,umask=0xcf"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch0.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1, "event=0x06,umask=0xcf"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(cas_count_read_sch1.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0, "event=0x05,umask=0xf0"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch0.unit, "MiB"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1, "event=0x06,umask=0xf0"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1.scale, "6.103515625e-5"), + INTEL_UNCORE_EVENT_DESC(cas_count_write_sch1.unit, "MiB"), + { /* end: all zeroes */ }, +}; + +static struct intel_uncore_type gnr_uncore_imc = { + SPR_UNCORE_MMIO_COMMON_FORMAT(), + .name = "imc", + .fixed_ctr_bits = 48, + .fixed_ctr = SNR_IMC_MMIO_PMON_FIXED_CTR, + .fixed_ctl = SNR_IMC_MMIO_PMON_FIXED_CTL, + .event_descs = gnr_uncore_imc_events, +}; + static struct intel_uncore_type gnr_uncore_pciex8 = { SPR_UNCORE_PCI_COMMON_FORMAT(), .name = "pciex8", @@ -6544,7 +6570,7 @@ static struct intel_uncore_type *gnr_uncores[UNCORE_GNR_NUM_UNCORE_TYPES] = { NULL, &spr_uncore_pcu, &gnr_uncore_ubox, - &spr_uncore_imc, + &gnr_uncore_imc, NULL, &gnr_uncore_upi, NULL, diff --git a/arch/x86/events/rapl.c b/arch/x86/events/rapl.c index defd86137f12..8ed03c32f560 100644 --- a/arch/x86/events/rapl.c +++ b/arch/x86/events/rapl.c @@ -704,7 +704,7 @@ static int __init init_rapl_pmu(struct rapl_pmus *rapl_pmus) int idx; for (idx = 0; idx < rapl_pmus->nr_rapl_pmu; idx++) { - rapl_pmu = kzalloc(sizeof(*rapl_pmu), GFP_KERNEL); + rapl_pmu = kzalloc_obj(*rapl_pmu); if (!rapl_pmu) goto free; @@ -742,7 +742,7 @@ static int __init init_rapl_pmus(struct rapl_pmus **rapl_pmus_ptr, int rapl_pmu_ else if (rapl_pmu_scope != PERF_PMU_SCOPE_PKG) return -EINVAL; - rapl_pmus = kzalloc(struct_size(rapl_pmus, rapl_pmu, nr_rapl_pmu), GFP_KERNEL); + rapl_pmus = kzalloc_flex(*rapl_pmus, rapl_pmu, nr_rapl_pmu); if (!rapl_pmus) return -ENOMEM; diff --git a/arch/x86/hyperv/hv_crash.c b/arch/x86/hyperv/hv_crash.c index a78e4fed5720..92da1b4f2e73 100644 --- a/arch/x86/hyperv/hv_crash.c +++ b/arch/x86/hyperv/hv_crash.c @@ -279,7 +279,6 @@ static void hv_notify_prepare_hyp(void) static noinline __noclone void crash_nmi_callback(struct pt_regs *regs) { struct hv_input_disable_hyp_ex *input; - u64 status; int msecs = 1000, ccpu = smp_processor_id(); if (ccpu == 0) { @@ -313,7 +312,7 @@ static noinline __noclone void crash_nmi_callback(struct pt_regs *regs) input->rip = trampoline_pa; input->arg = devirt_arg; - status = hv_do_hypercall(HVCALL_DISABLE_HYP_EX, input, NULL); + (void)hv_do_hypercall(HVCALL_DISABLE_HYP_EX, input, NULL); hv_panic_timeout_reboot(); } diff --git a/arch/x86/hyperv/hv_init.c b/arch/x86/hyperv/hv_init.c index 14de43f4bc6c..323adc93f2dc 100644 --- a/arch/x86/hyperv/hv_init.c +++ b/arch/x86/hyperv/hv_init.c @@ -103,9 +103,9 @@ static int hyperv_init_ghcb(void) */ rdmsrq(MSR_AMD64_SEV_ES_GHCB, ghcb_gpa); - /* Mask out vTOM bit. ioremap_cache() maps decrypted */ + /* Mask out vTOM bit and map as decrypted */ ghcb_gpa &= ~ms_hyperv.shared_gpa_boundary; - ghcb_va = (void *)ioremap_cache(ghcb_gpa, HV_HYP_PAGE_SIZE); + ghcb_va = memremap(ghcb_gpa, HV_HYP_PAGE_SIZE, MEMREMAP_WB | MEMREMAP_DEC); if (!ghcb_va) return -ENOMEM; @@ -277,7 +277,7 @@ static int hv_cpu_die(unsigned int cpu) if (hv_ghcb_pg) { ghcb_va = (void **)this_cpu_ptr(hv_ghcb_pg); if (*ghcb_va) - iounmap(*ghcb_va); + memunmap(*ghcb_va); *ghcb_va = NULL; } @@ -467,9 +467,7 @@ void __init hyperv_init(void) if (hv_isolation_type_tdx()) hv_vp_assist_page = NULL; else - hv_vp_assist_page = kcalloc(nr_cpu_ids, - sizeof(*hv_vp_assist_page), - GFP_KERNEL); + hv_vp_assist_page = kzalloc_objs(*hv_vp_assist_page, nr_cpu_ids); if (!hv_vp_assist_page) { ms_hyperv.hints &= ~HV_X64_ENLIGHTENED_VMCS_RECOMMENDED; @@ -558,7 +556,6 @@ void __init hyperv_init(void) memunmap(src); hv_remap_tsc_clocksource(); - hv_root_crash_init(); hv_sleep_notifiers_register(); } else { hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg); @@ -567,6 +564,9 @@ void __init hyperv_init(void) hv_set_hypercall_pg(hv_hypercall_pg); + if (hv_root_partition()) /* after set hypercall pg */ + hv_root_crash_init(); + skip_hypercall_pg_init: /* * hyperv_init() is called before LAPIC is initialized: see @@ -633,9 +633,13 @@ void hyperv_cleanup(void) hv_ivm_msr_write(HV_X64_MSR_GUEST_OS_ID, 0); /* - * Reset hypercall page reference before reset the page, - * let hypercall operations fail safely rather than - * panic the kernel for using invalid hypercall page + * Reset hv_hypercall_pg before resetting it in the hypervisor. + * hv_set_hypercall_pg(NULL) is not used because at this point in the + * panic path other CPUs have been stopped, causing static_call_update() + * to hang. So resetting hv_hypercall_pg to cause hypercalls to fail + * cleanly is only operative on 32-bit builds. But this is OK as it is + * just a preventative measure to ease detecting a hypercall being made + * after this point, which shouldn't be happening anyway. */ hv_hypercall_pg = NULL; diff --git a/arch/x86/hyperv/hv_vtl.c b/arch/x86/hyperv/hv_vtl.c index c0edaed0efb3..9b6a9bc4ab76 100644 --- a/arch/x86/hyperv/hv_vtl.c +++ b/arch/x86/hyperv/hv_vtl.c @@ -110,7 +110,7 @@ static void hv_vtl_ap_entry(void) static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) { - u64 status; + u64 status, rsp, rip; int ret = 0; struct hv_enable_vp_vtl *input; unsigned long irq_flags; @@ -123,9 +123,11 @@ static int hv_vtl_bringup_vcpu(u32 target_vp_index, int cpu, u64 eip_ignored) struct desc_struct *gdt; struct task_struct *idle = idle_thread_get(cpu); - u64 rsp = (unsigned long)idle->thread.sp; + if (IS_ERR(idle)) + return PTR_ERR(idle); - u64 rip = (u64)&hv_vtl_ap_entry; + rsp = (unsigned long)idle->thread.sp; + rip = (u64)&hv_vtl_ap_entry; native_store_gdt(&gdt_ptr); store_idt(&idt_ptr); diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c index c3ba12b1bc07..365e364268d9 100644 --- a/arch/x86/hyperv/irqdomain.c +++ b/arch/x86/hyperv/irqdomain.c @@ -248,7 +248,7 @@ static void hv_irq_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) return; } - stored_entry = kzalloc(sizeof(*stored_entry), GFP_ATOMIC); + stored_entry = kzalloc_obj(*stored_entry, GFP_ATOMIC); if (!stored_entry) { pr_debug("%s: failed to allocate chip data\n", __func__); return; diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c index 651771534cae..2ce4dfe53472 100644 --- a/arch/x86/hyperv/ivm.c +++ b/arch/x86/hyperv/ivm.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #ifdef CONFIG_AMD_MEM_ENCRYPT @@ -315,16 +316,16 @@ int hv_snp_boot_ap(u32 apic_id, unsigned long start_ip, unsigned int cpu) vmsa->gdtr.base = gdtr.address; vmsa->gdtr.limit = gdtr.size; - asm volatile("movl %%es, %%eax;" : "=a" (vmsa->es.selector)); + savesegment(es, vmsa->es.selector); hv_populate_vmcb_seg(vmsa->es, vmsa->gdtr.base); - asm volatile("movl %%cs, %%eax;" : "=a" (vmsa->cs.selector)); + savesegment(cs, vmsa->cs.selector); hv_populate_vmcb_seg(vmsa->cs, vmsa->gdtr.base); - asm volatile("movl %%ss, %%eax;" : "=a" (vmsa->ss.selector)); + savesegment(ss, vmsa->ss.selector); hv_populate_vmcb_seg(vmsa->ss, vmsa->gdtr.base); - asm volatile("movl %%ds, %%eax;" : "=a" (vmsa->ds.selector)); + savesegment(ds, vmsa->ds.selector); hv_populate_vmcb_seg(vmsa->ds, vmsa->gdtr.base); vmsa->efer = native_read_msr(MSR_EFER); @@ -391,7 +392,7 @@ u64 hv_snp_hypercall(u64 control, u64 param1, u64 param2) register u64 __r8 asm("r8") = param2; asm volatile("vmmcall" - : "=a" (hv_status), ASM_CALL_CONSTRAINT, + : "=a" (hv_status), "+c" (control), "+d" (param1), "+r" (__r8) : : "cc", "memory", "r9", "r10", "r11"); @@ -530,7 +531,7 @@ static int hv_list_enc_add(const u64 *pfn_list, int count) raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); /* No adjacent region found -- create a new one */ - ent = kzalloc(sizeof(struct hv_enc_pfn_region), GFP_KERNEL); + ent = kzalloc_obj(struct hv_enc_pfn_region); if (!ent) return -ENOMEM; @@ -597,7 +598,7 @@ static int hv_list_enc_remove(const u64 *pfn_list, int count) unlock_split: raw_spin_unlock_irqrestore(&hv_list_enc_lock, flags); - ent = kzalloc(sizeof(struct hv_enc_pfn_region), GFP_KERNEL); + ent = kzalloc_obj(struct hv_enc_pfn_region); if (!ent) return -ENOMEM; diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h index 9b4e04690e1a..80c1696d8d59 100644 --- a/arch/x86/include/asm/bug.h +++ b/arch/x86/include/asm/bug.h @@ -7,7 +7,7 @@ #include #include -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct bug_entry; extern void __WARN_trap(struct bug_entry *bug, ...); #endif @@ -137,7 +137,7 @@ do { \ #ifdef HAVE_ARCH_BUG_FORMAT_ARGS -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include DECLARE_STATIC_CALL(WARN_trap, __WARN_trap); @@ -153,7 +153,7 @@ struct arch_va_list { struct sysv_va_list args; }; extern void *__warn_args(struct arch_va_list *args, struct pt_regs *regs); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #define __WARN_bug_entry(flags, format) ({ \ struct bug_entry *bug; \ diff --git a/arch/x86/include/asm/cfi.h b/arch/x86/include/asm/cfi.h index c40b9ebc1fb4..ab3fbbd947ed 100644 --- a/arch/x86/include/asm/cfi.h +++ b/arch/x86/include/asm/cfi.h @@ -111,6 +111,12 @@ extern bhi_thunk __bhi_args_end[]; struct pt_regs; +#ifdef CONFIG_CALL_PADDING +#define CFI_OFFSET (CONFIG_FUNCTION_PADDING_CFI+5) +#else +#define CFI_OFFSET 5 +#endif + #ifdef CONFIG_CFI enum bug_trap_type handle_cfi_failure(struct pt_regs *regs); #define __bpfcall @@ -119,11 +125,9 @@ static inline int cfi_get_offset(void) { switch (cfi_mode) { case CFI_FINEIBT: - return 16; + return /* fineibt_prefix_size */ 16; case CFI_KCFI: - if (IS_ENABLED(CONFIG_CALL_PADDING)) - return 16; - return 5; + return CFI_OFFSET; default: return 0; } diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index f227a70ac91f..51b4cdbea061 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -138,7 +138,7 @@ extern void __init efi_apply_memmap_quirks(void); extern int __init efi_reuse_config(u64 tables, int nr_tables); extern void efi_delete_dummy_variable(void); extern void efi_crash_gracefully_on_page_fault(unsigned long phys_addr); -extern void efi_free_boot_services(void); +extern void efi_unmap_boot_services(void); void arch_efi_call_virt_setup(void); void arch_efi_call_virt_teardown(void); diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h index a1193e9d65f2..462754b0bf8a 100644 --- a/arch/x86/include/asm/irqflags.h +++ b/arch/x86/include/asm/irqflags.h @@ -77,7 +77,7 @@ static __always_inline void native_local_irq_restore(unsigned long flags) #endif #ifndef CONFIG_PARAVIRT -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* * Used in the idle loop; sti takes one instruction cycle * to complete: @@ -95,7 +95,7 @@ static __always_inline void halt(void) { native_halt(); } -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* CONFIG_PARAVIRT */ #ifdef CONFIG_PARAVIRT_XXL diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index ff07c45e3c73..6e4e3ef9b8c7 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2485,7 +2485,8 @@ int memslot_rmap_alloc(struct kvm_memory_slot *slot, unsigned long npages); KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS | \ KVM_X86_QUIRK_SLOT_ZAP_ALL | \ KVM_X86_QUIRK_STUFF_FEATURE_MSRS | \ - KVM_X86_QUIRK_IGNORE_GUEST_PAT) + KVM_X86_QUIRK_IGNORE_GUEST_PAT | \ + KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM) #define KVM_X86_CONDITIONAL_QUIRKS \ (KVM_X86_QUIRK_CD_NW_CLEARED | \ diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h index 9d38ae744a2e..a7294656ad90 100644 --- a/arch/x86/include/asm/linkage.h +++ b/arch/x86/include/asm/linkage.h @@ -68,7 +68,7 @@ * Depending on -fpatchable-function-entry=N,N usage (CONFIG_CALL_PADDING) the * CFI symbol layout changes. * - * Without CALL_THUNKS: + * Without CALL_PADDING: * * .align FUNCTION_ALIGNMENT * __cfi_##name: @@ -77,7 +77,7 @@ * .long __kcfi_typeid_##name * name: * - * With CALL_THUNKS: + * With CALL_PADDING: * * .align FUNCTION_ALIGNMENT * __cfi_##name: diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index da5275d8eda6..6673601246b3 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h @@ -740,7 +740,10 @@ #define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT) #define MSR_AMD64_SNP_SECURE_AVIC_BIT 18 #define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT) -#define MSR_AMD64_SNP_RESV_BIT 19 +#define MSR_AMD64_SNP_RESERVED_BITS19_22 GENMASK_ULL(22, 19) +#define MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT 23 +#define MSR_AMD64_SNP_IBPB_ON_ENTRY BIT_ULL(MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT) +#define MSR_AMD64_SNP_RESV_BIT 24 #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT) #define MSR_AMD64_SAVIC_CONTROL 0xc0010138 #define MSR_AMD64_SAVIC_EN_BIT 0 diff --git a/arch/x86/include/asm/numa.h b/arch/x86/include/asm/numa.h index 53ba39ce010c..a9063f332fa6 100644 --- a/arch/x86/include/asm/numa.h +++ b/arch/x86/include/asm/numa.h @@ -22,6 +22,7 @@ extern int numa_off; */ extern s16 __apicid_to_node[MAX_LOCAL_APIC]; extern nodemask_t numa_nodes_parsed __initdata; +extern nodemask_t numa_phys_nodes_parsed __initdata; static inline void set_apicid_to_node(int apicid, s16 node) { @@ -48,6 +49,7 @@ extern void __init init_cpu_to_node(void); extern void numa_add_cpu(unsigned int cpu); extern void numa_remove_cpu(unsigned int cpu); extern void init_gi_nodes(void); +extern int num_phys_nodes(void); #else /* CONFIG_NUMA */ static inline void numa_set_node(int cpu, int node) { } static inline void numa_clear_node(int cpu) { } @@ -55,6 +57,10 @@ static inline void init_cpu_to_node(void) { } static inline void numa_add_cpu(unsigned int cpu) { } static inline void numa_remove_cpu(unsigned int cpu) { } static inline void init_gi_nodes(void) { } +static inline int num_phys_nodes(void) +{ + return 1; +} #endif /* CONFIG_NUMA */ #ifdef CONFIG_DEBUG_PER_CPU_MAPS diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index c55058f3d75e..409981468cba 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -20,7 +20,7 @@ #define PER_CPU_VAR(var) __percpu(var)__percpu_rel -#else /* !__ASSEMBLY__: */ +#else /* !__ASSEMBLER__: */ #include #include diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h index f06e5d6a2747..ce45882ccd07 100644 --- a/arch/x86/include/asm/pgtable_64.h +++ b/arch/x86/include/asm/pgtable_64.h @@ -19,10 +19,8 @@ extern p4d_t level4_kernel_pgt[512]; extern p4d_t level4_ident_pgt[512]; extern pud_t level3_kernel_pgt[512]; -extern pud_t level3_ident_pgt[512]; extern pmd_t level2_kernel_pgt[512]; extern pmd_t level2_fixmap_pgt[512]; -extern pmd_t level2_ident_pgt[512]; extern pte_t level1_fixmap_pgt[512 * FIXMAP_PMD_NUM]; extern pgd_t init_top_pgt[]; diff --git a/arch/x86/include/asm/runtime-const.h b/arch/x86/include/asm/runtime-const.h index e5a13dc8816e..4cd94fdcb45e 100644 --- a/arch/x86/include/asm/runtime-const.h +++ b/arch/x86/include/asm/runtime-const.h @@ -6,7 +6,7 @@ #error "Cannot use runtime-const infrastructure from modules" #endif -#ifdef __ASSEMBLY__ +#ifdef __ASSEMBLER__ .macro RUNTIME_CONST_PTR sym reg movq $0x0123456789abcdef, %\reg @@ -16,7 +16,7 @@ .popsection .endm -#else /* __ASSEMBLY__ */ +#else /* __ASSEMBLER__ */ #define runtime_const_ptr(sym) ({ \ typeof(sym) __ret; \ @@ -74,5 +74,5 @@ static inline void runtime_const_fixup(void (*fn)(void *, unsigned long), } } -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 1fadf0cf520c..0ba9bdb99871 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h @@ -155,6 +155,7 @@ extern unsigned int __max_logical_packages; extern unsigned int __max_threads_per_core; extern unsigned int __num_threads_per_package; extern unsigned int __num_cores_per_package; +extern unsigned int __num_nodes_per_package; const char *get_topology_cpu_type_name(struct cpuinfo_x86 *c); enum x86_topology_cpu_type get_topology_cpu_type(struct cpuinfo_x86 *c); @@ -179,6 +180,11 @@ static inline unsigned int topology_num_threads_per_package(void) return __num_threads_per_package; } +static inline unsigned int topology_num_nodes_per_package(void) +{ + return __num_nodes_per_package; +} + #ifdef CONFIG_X86_LOCAL_APIC int topology_get_logical_id(u32 apicid, enum x86_topology_domains at_level); #else diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h index 869b88061801..3f24cc472ce9 100644 --- a/arch/x86/include/asm/traps.h +++ b/arch/x86/include/asm/traps.h @@ -25,6 +25,8 @@ extern int ibt_selftest_noendbr(void); void handle_invalid_op(struct pt_regs *regs); #endif +noinstr bool handle_bug(struct pt_regs *regs); + static inline int get_si_code(unsigned long condition) { if (condition & DR_STEP) diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h index 846a63215ce1..0d4538fa6c31 100644 --- a/arch/x86/include/uapi/asm/kvm.h +++ b/arch/x86/include/uapi/asm/kvm.h @@ -476,6 +476,7 @@ struct kvm_sync_regs { #define KVM_X86_QUIRK_SLOT_ZAP_ALL (1 << 7) #define KVM_X86_QUIRK_STUFF_FEATURE_MSRS (1 << 8) #define KVM_X86_QUIRK_IGNORE_GUEST_PAT (1 << 9) +#define KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM (1 << 10) #define KVM_STATE_NESTED_FORMAT_VMX 0 #define KVM_STATE_NESTED_FORMAT_SVM 1 diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 693b59b2f7d0..e87da25d1236 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c @@ -1182,7 +1182,7 @@ void __init_or_module noinline apply_seal_endbr(s32 *start, s32 *end) poison_endbr(addr); if (IS_ENABLED(CONFIG_FINEIBT)) - poison_cfi(addr - 16); + poison_cfi(addr - CFI_OFFSET); } } @@ -1389,6 +1389,8 @@ extern u8 fineibt_preamble_end[]; #define fineibt_preamble_ud 0x13 #define fineibt_preamble_hash 5 +#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE) + /* * : * 0: b8 78 56 34 12 mov $0x12345678, %eax @@ -1634,7 +1636,7 @@ static int cfi_rewrite_preamble(s32 *start, s32 *end) * have determined there are no indirect calls to it and we * don't need no CFI either. */ - if (!is_endbr(addr + 16)) + if (!is_endbr(addr + CFI_OFFSET)) continue; hash = decode_preamble_hash(addr, &arity); @@ -1642,6 +1644,15 @@ static int cfi_rewrite_preamble(s32 *start, s32 *end) addr, addr, 5, addr)) return -EINVAL; + /* + * FineIBT relies on being at func-16, so if the preamble is + * actually larger than that, place it the tail end. + * + * NOTE: this is possible with things like DEBUG_CALL_THUNKS + * and DEBUG_FORCE_FUNCTION_ALIGN_64B. + */ + addr += CFI_OFFSET - fineibt_prefix_size; + text_poke_early(addr, fineibt_preamble_start, fineibt_preamble_size); WARN_ON(*(u32 *)(addr + fineibt_preamble_hash) != 0x12345678); text_poke_early(addr + fineibt_preamble_hash, &hash, 4); @@ -1664,10 +1675,10 @@ static void cfi_rewrite_endbr(s32 *start, s32 *end) for (s = start; s < end; s++) { void *addr = (void *)s + *s; - if (!exact_endbr(addr + 16)) + if (!exact_endbr(addr + CFI_OFFSET)) continue; - poison_endbr(addr + 16); + poison_endbr(addr + CFI_OFFSET); } } @@ -1772,7 +1783,8 @@ static void __apply_fineibt(s32 *start_retpoline, s32 *end_retpoline, if (FINEIBT_WARN(fineibt_preamble_size, 20) || FINEIBT_WARN(fineibt_preamble_bhi + fineibt_bhi1_size, 20) || FINEIBT_WARN(fineibt_caller_size, 14) || - FINEIBT_WARN(fineibt_paranoid_size, 20)) + FINEIBT_WARN(fineibt_paranoid_size, 20) || + WARN_ON_ONCE(CFI_OFFSET < fineibt_prefix_size)) return; if (cfi_mode == CFI_AUTO) { @@ -1885,6 +1897,11 @@ static void poison_cfi(void *addr) */ switch (cfi_mode) { case CFI_FINEIBT: + /* + * FineIBT preamble is at func-16. + */ + addr += CFI_OFFSET - fineibt_prefix_size; + /* * FineIBT prefix should start with an ENDBR. */ @@ -1923,8 +1940,6 @@ static void poison_cfi(void *addr) } } -#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE) - /* * When regs->ip points to a 0xD6 byte in the FineIBT preamble, * return true and fill out target and type. @@ -2160,7 +2175,7 @@ void __init_or_module alternatives_smp_module_add(struct module *mod, /* Don't bother remembering, we'll never have to undo it. */ goto smp_unlock; - smp = kzalloc(sizeof(*smp), GFP_KERNEL); + smp = kzalloc_obj(*smp); if (NULL == smp) /* we'll run the (safe but slow) SMP code then ... */ goto unlock; diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c index c1acead6227a..5d364540673d 100644 --- a/arch/x86/kernel/amd_nb.c +++ b/arch/x86/kernel/amd_nb.c @@ -68,7 +68,7 @@ static int amd_cache_northbridges(void) amd_northbridges.num = amd_num_nodes(); - nb = kcalloc(amd_northbridges.num, sizeof(struct amd_northbridge), GFP_KERNEL); + nb = kzalloc_objs(struct amd_northbridge, amd_northbridges.num); if (!nb) return -ENOMEM; diff --git a/arch/x86/kernel/amd_node.c b/arch/x86/kernel/amd_node.c index 3d0a4768d603..0be01725a2a4 100644 --- a/arch/x86/kernel/amd_node.c +++ b/arch/x86/kernel/amd_node.c @@ -282,7 +282,7 @@ static int __init amd_smn_init(void) return -ENODEV; num_nodes = amd_num_nodes(); - amd_roots = kcalloc(num_nodes, sizeof(*amd_roots), GFP_KERNEL); + amd_roots = kzalloc_objs(*amd_roots, num_nodes); if (!amd_roots) return -ENOMEM; diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index d93f87f29d03..961714e6adae 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -1894,6 +1894,7 @@ void __init check_x2apic(void) static inline void try_to_enable_x2apic(int remap_mode) { } static inline void __x2apic_enable(void) { } +static inline void __x2apic_disable(void) { } #endif /* !CONFIG_X86_X2APIC */ void __init enable_IR_x2apic(void) @@ -2456,6 +2457,11 @@ static void lapic_resume(void *data) if (x2apic_mode) { __x2apic_enable(); } else { + if (x2apic_enabled()) { + pr_warn_once("x2apic: re-enabled by firmware during resume. Disabling\n"); + __x2apic_disable(); + } + /* * Make sure the APICBASE points to the right address * diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 28f934f05a85..352ed5558cbc 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -2876,7 +2876,7 @@ int mp_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, if (irq_resolve_mapping(domain, (irq_hw_number_t)pin)) return -EEXIST; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index 3175d7c134e9..a57c026fb58a 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1576,7 +1576,7 @@ static int do_open(struct inode *inode, struct file *filp) { struct apm_user *as; - as = kmalloc(sizeof(*as), GFP_KERNEL); + as = kmalloc_obj(*as); if (as == NULL) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/amd_cache_disable.c b/arch/x86/kernel/cpu/amd_cache_disable.c index 8843b9557aea..9ab460bc11a2 100644 --- a/arch/x86/kernel/cpu/amd_cache_disable.c +++ b/arch/x86/kernel/cpu/amd_cache_disable.c @@ -255,7 +255,7 @@ static void init_amd_l3_attrs(void) if (amd_nb_has_feature(AMD_NB_L3_PARTITIONING)) n += 1; - amd_l3_attrs = kcalloc(n, sizeof(*amd_l3_attrs), GFP_KERNEL); + amd_l3_attrs = kzalloc_objs(*amd_l3_attrs, n); if (!amd_l3_attrs) return; diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 1c3261cae40c..a8ff4376c286 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -95,6 +95,9 @@ EXPORT_SYMBOL(__max_dies_per_package); unsigned int __max_logical_packages __ro_after_init = 1; EXPORT_SYMBOL(__max_logical_packages); +unsigned int __num_nodes_per_package __ro_after_init = 1; +EXPORT_SYMBOL(__num_nodes_per_package); + unsigned int __num_cores_per_package __ro_after_init = 1; EXPORT_SYMBOL(__num_cores_per_package); diff --git a/arch/x86/kernel/cpu/mce/amd.c b/arch/x86/kernel/cpu/mce/amd.c index 3f1dda355307..da13c1e37f87 100644 --- a/arch/x86/kernel/cpu/mce/amd.c +++ b/arch/x86/kernel/cpu/mce/amd.c @@ -1088,7 +1088,7 @@ static int allocate_threshold_blocks(unsigned int cpu, struct threshold_bank *tb (high & MASK_LOCKED_HI)) goto recurse; - b = kzalloc(sizeof(struct threshold_block), GFP_KERNEL); + b = kzalloc_obj(struct threshold_block); if (!b) return -ENOMEM; @@ -1147,7 +1147,7 @@ static int threshold_create_bank(struct threshold_bank **bp, unsigned int cpu, if (!dev) return -ENODEV; - b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL); + b = kzalloc_obj(struct threshold_bank); if (!b) { err = -ENOMEM; goto out; @@ -1250,7 +1250,7 @@ void mce_threshold_create_device(unsigned int cpu) return; numbanks = this_cpu_read(mce_num_banks); - bp = kcalloc(numbanks, sizeof(*bp), GFP_KERNEL); + bp = kzalloc_objs(*bp, numbanks); if (!bp) return; diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c index 34440021e8cf..8dd424ac5de8 100644 --- a/arch/x86/kernel/cpu/mce/core.c +++ b/arch/x86/kernel/cpu/mce/core.c @@ -2692,7 +2692,7 @@ static int mce_device_create(unsigned int cpu) if (dev) return 0; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; dev->id = cpu; diff --git a/arch/x86/kernel/cpu/mce/dev-mcelog.c b/arch/x86/kernel/cpu/mce/dev-mcelog.c index 8d023239ce18..053555206d81 100644 --- a/arch/x86/kernel/cpu/mce/dev-mcelog.c +++ b/arch/x86/kernel/cpu/mce/dev-mcelog.c @@ -338,7 +338,7 @@ static __init int dev_mcelog_init_device(void) int err; mce_log_len = max(MCE_LOG_MIN_LEN, num_online_cpus()); - mcelog = kzalloc(struct_size(mcelog, entry, mce_log_len), GFP_KERNEL); + mcelog = kzalloc_flex(*mcelog, entry, mce_log_len); if (!mcelog) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c index caa0f595abcf..e533881284a1 100644 --- a/arch/x86/kernel/cpu/microcode/amd.c +++ b/arch/x86/kernel/cpu/microcode/amd.c @@ -1086,7 +1086,7 @@ static int verify_and_add_patch(u8 family, u8 *fw, unsigned int leftover, if (ret) return ret; - patch = kzalloc(sizeof(*patch), GFP_KERNEL); + patch = kzalloc_obj(*patch); if (!patch) { pr_err("Patch allocation failure.\n"); return -EINVAL; diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index 579fb2c64cfd..89a2eb8a0722 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c @@ -478,6 +478,28 @@ int hv_get_hypervisor_version(union hv_hypervisor_version_info *info) } EXPORT_SYMBOL_GPL(hv_get_hypervisor_version); +/* + * Reserved vectors hard coded in the hypervisor. If used outside, the hypervisor + * will either crash or hang or attempt to break into debugger. + */ +static void hv_reserve_irq_vectors(void) +{ + #define HYPERV_DBG_FASTFAIL_VECTOR 0x29 + #define HYPERV_DBG_ASSERT_VECTOR 0x2C + #define HYPERV_DBG_SERVICE_VECTOR 0x2D + + if (cpu_feature_enabled(X86_FEATURE_FRED)) + return; + + if (test_and_set_bit(HYPERV_DBG_ASSERT_VECTOR, system_vectors) || + test_and_set_bit(HYPERV_DBG_SERVICE_VECTOR, system_vectors) || + test_and_set_bit(HYPERV_DBG_FASTFAIL_VECTOR, system_vectors)) + BUG(); + + pr_info("Hyper-V: reserve vectors: %d %d %d\n", HYPERV_DBG_ASSERT_VECTOR, + HYPERV_DBG_SERVICE_VECTOR, HYPERV_DBG_FASTFAIL_VECTOR); +} + static void __init ms_hyperv_init_platform(void) { int hv_max_functions_eax, eax; @@ -510,6 +532,9 @@ static void __init ms_hyperv_init_platform(void) hv_identify_partition_type(); + if (hv_root_partition()) + hv_reserve_irq_vectors(); + if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC)) ms_hyperv.hints |= HV_DEPRECATING_AEOI_RECOMMENDED; diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c index 0863733858dc..3a8317060732 100644 --- a/arch/x86/kernel/cpu/mtrr/generic.c +++ b/arch/x86/kernel/cpu/mtrr/generic.c @@ -410,7 +410,7 @@ void __init mtrr_copy_map(void) mutex_lock(&mtrr_mutex); - cache_map = kcalloc(new_size, sizeof(*cache_map), GFP_KERNEL); + cache_map = kzalloc_objs(*cache_map, new_size); if (cache_map) { memmove(cache_map, init_cache_map, cache_map_n * sizeof(*cache_map)); diff --git a/arch/x86/kernel/cpu/mtrr/legacy.c b/arch/x86/kernel/cpu/mtrr/legacy.c index 2415ffaaf02c..ca1209cdea5f 100644 --- a/arch/x86/kernel/cpu/mtrr/legacy.c +++ b/arch/x86/kernel/cpu/mtrr/legacy.c @@ -80,7 +80,7 @@ static struct syscore mtrr_syscore = { void mtrr_register_syscore(void) { - mtrr_value = kcalloc(num_var_ranges, sizeof(*mtrr_value), GFP_KERNEL); + mtrr_value = kzalloc_objs(*mtrr_value, num_var_ranges); /* * The CPU has no MTRR and seems to not support SMP. They have diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index e6a154240b8d..9bd87bae4983 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -364,7 +364,7 @@ void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d) msr_clear_bit(MSR_RMID_SNC_CONFIG, 0); } -/* CPU models that support MSR_RMID_SNC_CONFIG */ +/* CPU models that support SNC and MSR_RMID_SNC_CONFIG */ static const struct x86_cpu_id snc_cpu_ids[] __initconst = { X86_MATCH_VFM(INTEL_ICELAKE_X, 0), X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, 0), @@ -375,40 +375,14 @@ static const struct x86_cpu_id snc_cpu_ids[] __initconst = { {} }; -/* - * There isn't a simple hardware bit that indicates whether a CPU is running - * in Sub-NUMA Cluster (SNC) mode. Infer the state by comparing the - * number of CPUs sharing the L3 cache with CPU0 to the number of CPUs in - * the same NUMA node as CPU0. - * It is not possible to accurately determine SNC state if the system is - * booted with a maxcpus=N parameter. That distorts the ratio of SNC nodes - * to L3 caches. It will be OK if system is booted with hyperthreading - * disabled (since this doesn't affect the ratio). - */ static __init int snc_get_config(void) { - struct cacheinfo *ci = get_cpu_cacheinfo_level(0, RESCTRL_L3_CACHE); - const cpumask_t *node0_cpumask; - int cpus_per_node, cpus_per_l3; - int ret; + int ret = topology_num_nodes_per_package(); - if (!x86_match_cpu(snc_cpu_ids) || !ci) + if (ret > 1 && !x86_match_cpu(snc_cpu_ids)) { + pr_warn("CoD enabled system? Resctrl not supported\n"); return 1; - - cpus_read_lock(); - if (num_online_cpus() != num_present_cpus()) - pr_warn("Some CPUs offline, SNC detection may be incorrect\n"); - cpus_read_unlock(); - - node0_cpumask = cpumask_of_node(cpu_to_node(0)); - - cpus_per_node = cpumask_weight(node0_cpumask); - cpus_per_l3 = cpumask_weight(&ci->shared_cpu_map); - - if (!cpus_per_node || !cpus_per_l3) - return 1; - - ret = cpus_per_l3 / cpus_per_node; + } /* sanity check: Only valid results are 1, 2, 3, 4, 6 */ switch (ret) { diff --git a/arch/x86/kernel/cpu/sgx/driver.c b/arch/x86/kernel/cpu/sgx/driver.c index a42c7180900b..473619741bc4 100644 --- a/arch/x86/kernel/cpu/sgx/driver.c +++ b/arch/x86/kernel/cpu/sgx/driver.c @@ -19,7 +19,7 @@ static int __sgx_open(struct inode *inode, struct file *file) struct sgx_encl *encl; int ret; - encl = kzalloc(sizeof(*encl), GFP_KERNEL); + encl = kzalloc_obj(*encl); if (!encl) return -ENOMEM; diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c index cf149b9f4916..ac60ebde5d9b 100644 --- a/arch/x86/kernel/cpu/sgx/encl.c +++ b/arch/x86/kernel/cpu/sgx/encl.c @@ -854,7 +854,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm) if (sgx_encl_find_mm(encl, mm)) return 0; - encl_mm = kzalloc(sizeof(*encl_mm), GFP_KERNEL); + encl_mm = kzalloc_obj(*encl_mm); if (!encl_mm) return -ENOMEM; @@ -1163,7 +1163,7 @@ struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl, struct sgx_encl_page *encl_page; unsigned long prot; - encl_page = kzalloc(sizeof(*encl_page), GFP_KERNEL); + encl_page = kzalloc_obj(*encl_page); if (!encl_page) return ERR_PTR(-ENOMEM); diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index 9322a9287dc7..c236a8ac78a8 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -27,7 +27,7 @@ struct sgx_va_page *sgx_encl_grow(struct sgx_encl *encl, bool reclaim) (SGX_ENCL_PAGE_VA_OFFSET_MASK >> 3) + 1); if (!(encl->page_cnt % SGX_VA_SLOT_COUNT)) { - va_page = kzalloc(sizeof(*va_page), GFP_KERNEL); + va_page = kzalloc_obj(*va_page); if (!va_page) return ERR_PTR(-ENOMEM); @@ -83,7 +83,7 @@ static int sgx_encl_create(struct sgx_encl *encl, struct sgx_secs *secs) encl_size = secs->size + PAGE_SIZE; backing = shmem_file_setup("SGX backing", encl_size + (encl_size >> 5), - VM_NORESERVE); + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(backing)) { ret = PTR_ERR(backing); goto err_out_shrink; diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c index dc73194416ac..38b7fd2f63be 100644 --- a/arch/x86/kernel/cpu/sgx/main.c +++ b/arch/x86/kernel/cpu/sgx/main.c @@ -798,7 +798,7 @@ static bool __init sgx_page_cache_init(void) int nid; int i; - sgx_numa_nodes = kmalloc_array(num_possible_nodes(), sizeof(*sgx_numa_nodes), GFP_KERNEL); + sgx_numa_nodes = kmalloc_objs(*sgx_numa_nodes, num_possible_nodes()); if (!sgx_numa_nodes) return false; diff --git a/arch/x86/kernel/cpu/sgx/virt.c b/arch/x86/kernel/cpu/sgx/virt.c index 8de1f1a755f2..db6806c40483 100644 --- a/arch/x86/kernel/cpu/sgx/virt.c +++ b/arch/x86/kernel/cpu/sgx/virt.c @@ -264,7 +264,7 @@ static int __sgx_vepc_open(struct inode *inode, struct file *file) { struct sgx_vepc *vepc; - vepc = kzalloc(sizeof(struct sgx_vepc), GFP_KERNEL); + vepc = kzalloc_obj(struct sgx_vepc); if (!vepc) return -ENOMEM; mutex_init(&vepc->lock); diff --git a/arch/x86/kernel/cpu/topology.c b/arch/x86/kernel/cpu/topology.c index 23190a786d31..eafcb1fc185a 100644 --- a/arch/x86/kernel/cpu/topology.c +++ b/arch/x86/kernel/cpu/topology.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "cpu.h" @@ -492,11 +493,19 @@ void __init topology_init_possible_cpus(void) set_nr_cpu_ids(allowed); cnta = domain_weight(TOPO_PKG_DOMAIN); - cntb = domain_weight(TOPO_DIE_DOMAIN); __max_logical_packages = cnta; + + pr_info("Max. logical packages: %3u\n", __max_logical_packages); + + cntb = num_phys_nodes(); + __num_nodes_per_package = DIV_ROUND_UP(cntb, cnta); + + pr_info("Max. logical nodes: %3u\n", cntb); + pr_info("Num. nodes per package:%3u\n", __num_nodes_per_package); + + cntb = domain_weight(TOPO_DIE_DOMAIN); __max_dies_per_package = 1U << (get_count_order(cntb) - get_count_order(cnta)); - pr_info("Max. logical packages: %3u\n", cnta); pr_info("Max. logical dies: %3u\n", cntb); pr_info("Max. dies per package: %3u\n", __max_dies_per_package); diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S index 21816b48537c..85d4a5094f6b 100644 --- a/arch/x86/kernel/head_64.S +++ b/arch/x86/kernel/head_64.S @@ -616,38 +616,10 @@ SYM_DATA(early_recursion_flag, .long 0) .data -#if defined(CONFIG_XEN_PV) || defined(CONFIG_PVH) -SYM_DATA_START_PTI_ALIGNED(init_top_pgt) - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC - .org init_top_pgt + L4_PAGE_OFFSET*8, 0 - .quad level3_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC - .org init_top_pgt + L4_START_KERNEL*8, 0 - /* (2^48-(2*1024*1024*1024))/(2^39) = 511 */ - .quad level3_kernel_pgt - __START_KERNEL_map + _PAGE_TABLE_NOENC - .fill PTI_USER_PGD_FILL,8,0 -SYM_DATA_END(init_top_pgt) - -SYM_DATA_START_PAGE_ALIGNED(level3_ident_pgt) - .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC - .fill 511, 8, 0 -SYM_DATA_END(level3_ident_pgt) -SYM_DATA_START_PAGE_ALIGNED(level2_ident_pgt) - /* - * Since I easily can, map the first 1G. - * Don't set NX because code runs from these pages. - * - * Note: This sets _PAGE_GLOBAL despite whether - * the CPU supports it or it is enabled. But, - * the CPU should ignore the bit. - */ - PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) -SYM_DATA_END(level2_ident_pgt) -#else SYM_DATA_START_PTI_ALIGNED(init_top_pgt) .fill 512,8,0 .fill PTI_USER_PGD_FILL,8,0 SYM_DATA_END(init_top_pgt) -#endif SYM_DATA_START_PAGE_ALIGNED(level4_kernel_pgt) .fill 511,8,0 diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index d6387dde3ff9..610590e83445 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c @@ -544,7 +544,7 @@ static struct irq_domain *hpet_create_irq_domain(int hpet_id) if (x86_vector_domain == NULL) return NULL; - domain_info = kzalloc(sizeof(*domain_info), GFP_KERNEL); + domain_info = kzalloc_obj(*domain_info); if (!domain_info) return NULL; @@ -1038,7 +1038,7 @@ int __init hpet_enable(void) if (IS_ENABLED(CONFIG_HPET_EMULATE_RTC) && channels < 2) goto out_nohpet; - hc = kcalloc(channels, sizeof(*hc), GFP_KERNEL); + hc = kzalloc_objs(*hc, channels); if (!hc) { pr_warn("Disabling HPET.\n"); goto out_nohpet; diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index ff40f09ad911..2b9de8e1a090 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -90,7 +90,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) /* No point to allocate a bitmap just to clear permissions */ if (!turn_on) return 0; - iobm = kmalloc(sizeof(*iobm), GFP_KERNEL); + iobm = kmalloc_obj(*iobm); if (!iobm) return -ENOMEM; diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index e2e89bebcbc3..e14ace32009f 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c @@ -102,7 +102,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) pa_data = boot_params.hdr.setup_data; while (pa_data) { - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmalloc_obj(*node); if (!node) { error = -ENOMEM; goto err_dir; diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c index 7508d0ccc740..5630c7dca1f3 100644 --- a/arch/x86/kernel/kexec-bzimage64.c +++ b/arch/x86/kernel/kexec-bzimage64.c @@ -193,6 +193,13 @@ setup_efi_state(struct boot_params *params, unsigned long params_load_addr, struct efi_info *current_ei = &boot_params.efi_info; struct efi_info *ei = ¶ms->efi_info; + if (!params->acpi_rsdp_addr) { + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + params->acpi_rsdp_addr = efi.acpi20; + else if (efi.acpi != EFI_INVALID_TABLE_ADDR) + params->acpi_rsdp_addr = efi.acpi; + } + if (!efi_enabled(EFI_RUNTIME_SERVICES)) return 0; @@ -675,7 +682,7 @@ static void *bzImage64_load(struct kimage *image, char *kernel, goto out_free_params; /* Allocate loader specific data */ - ldata = kzalloc(sizeof(struct bzimage64_data), GFP_KERNEL); + ldata = kzalloc_obj(struct bzimage64_data); if (!ldata) { ret = -ENOMEM; goto out_free_params; diff --git a/arch/x86/kernel/ksysfs.c b/arch/x86/kernel/ksysfs.c index d547de9b3ed8..1a6e1f89f294 100644 --- a/arch/x86/kernel/ksysfs.c +++ b/arch/x86/kernel/ksysfs.c @@ -344,7 +344,7 @@ static int __init create_setup_data_nodes(struct kobject *parent) if (ret) goto out_setup_data_kobj; - kobjp = kmalloc_array(nr, sizeof(*kobjp), GFP_KERNEL); + kobjp = kmalloc_objs(*kobjp, nr); if (!kobjp) { ret = -ENOMEM; goto out_setup_data_kobj; diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 26ab6f8e36df..3bc062363814 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -226,7 +226,7 @@ static void kvm_async_pf_task_wake(u32 token) */ if (!dummy) { raw_spin_unlock(&b->lock); - dummy = kzalloc(sizeof(*dummy), GFP_ATOMIC); + dummy = kzalloc_obj(*dummy, GFP_ATOMIC); /* * Continue looping on allocation failure, eventually diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 0f19ef355f5f..40c5bf97dd5c 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c @@ -154,7 +154,7 @@ static struct ldt_struct *alloc_ldt_struct(unsigned int num_entries) if (num_entries > LDT_ENTRIES) return NULL; - new_ldt = kmalloc(sizeof(struct ldt_struct), GFP_KERNEL_ACCOUNT); + new_ldt = kmalloc_obj(struct ldt_struct, GFP_KERNEL_ACCOUNT); if (!new_ldt) return NULL; diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 5cd6950ab672..294a8ea60298 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -468,13 +468,6 @@ static int x86_cluster_flags(void) } #endif -/* - * Set if a package/die has multiple NUMA nodes inside. - * AMD Magny-Cours, Intel Cluster-on-Die, and Intel - * Sub-NUMA Clustering have this. - */ -static bool x86_has_numa_in_package; - static struct sched_domain_topology_level x86_topology[] = { SDTL_INIT(tl_smt_mask, cpu_smt_flags, SMT), #ifdef CONFIG_SCHED_CLUSTER @@ -496,7 +489,7 @@ static void __init build_sched_topology(void) * PKG domain since the NUMA domains will auto-magically create the * right spanning domains based on the SLIT. */ - if (x86_has_numa_in_package) { + if (topology_num_nodes_per_package() > 1) { unsigned int pkgdom = ARRAY_SIZE(x86_topology) - 2; memset(&x86_topology[pkgdom], 0, sizeof(x86_topology[pkgdom])); @@ -513,33 +506,149 @@ static void __init build_sched_topology(void) } #ifdef CONFIG_NUMA -static int sched_avg_remote_distance; -static int avg_remote_numa_distance(void) +/* + * Test if the on-trace cluster at (N,N) is symmetric. + * Uses upper triangle iteration to avoid obvious duplicates. + */ +static bool slit_cluster_symmetric(int N) { - int i, j; - int distance, nr_remote, total_distance; + int u = topology_num_nodes_per_package(); - if (sched_avg_remote_distance > 0) - return sched_avg_remote_distance; - - nr_remote = 0; - total_distance = 0; - for_each_node_state(i, N_CPU) { - for_each_node_state(j, N_CPU) { - distance = node_distance(i, j); - - if (distance >= REMOTE_DISTANCE) { - nr_remote++; - total_distance += distance; - } + for (int k = 0; k < u; k++) { + for (int l = k; l < u; l++) { + if (node_distance(N + k, N + l) != + node_distance(N + l, N + k)) + return false; } } - if (nr_remote) - sched_avg_remote_distance = total_distance / nr_remote; - else - sched_avg_remote_distance = REMOTE_DISTANCE; - return sched_avg_remote_distance; + return true; +} + +/* + * Return the package-id of the cluster, or ~0 if indeterminate. + * Each node in the on-trace cluster should have the same package-id. + */ +static u32 slit_cluster_package(int N) +{ + int u = topology_num_nodes_per_package(); + u32 pkg_id = ~0; + + for (int n = 0; n < u; n++) { + const struct cpumask *cpus = cpumask_of_node(N + n); + int cpu; + + for_each_cpu(cpu, cpus) { + u32 id = topology_logical_package_id(cpu); + + if (pkg_id == ~0) + pkg_id = id; + if (pkg_id != id) + return ~0; + } + } + + return pkg_id; +} + +/* + * Validate the SLIT table is of the form expected for SNC, specifically: + * + * - each on-trace cluster should be symmetric, + * - each on-trace cluster should have a unique package-id. + * + * If you NUMA_EMU on top of SNC, you get to keep the pieces. + */ +static bool slit_validate(void) +{ + int u = topology_num_nodes_per_package(); + u32 pkg_id, prev_pkg_id = ~0; + + for (int pkg = 0; pkg < topology_max_packages(); pkg++) { + int n = pkg * u; + + /* + * Ensure the on-trace cluster is symmetric and each cluster + * has a different package id. + */ + if (!slit_cluster_symmetric(n)) + return false; + pkg_id = slit_cluster_package(n); + if (pkg_id == ~0) + return false; + if (pkg && pkg_id == prev_pkg_id) + return false; + + prev_pkg_id = pkg_id; + } + + return true; +} + +/* + * Compute a sanitized SLIT table for SNC; notably SNC-3 can end up with + * asymmetric off-trace clusters, reflecting physical assymmetries. However + * this leads to 'unfortunate' sched_domain configurations. + * + * For example dual socket GNR with SNC-3: + * + * node distances: + * node 0 1 2 3 4 5 + * 0: 10 15 17 21 28 26 + * 1: 15 10 15 23 26 23 + * 2: 17 15 10 26 23 21 + * 3: 21 28 26 10 15 17 + * 4: 23 26 23 15 10 15 + * 5: 26 23 21 17 15 10 + * + * Fix things up by averaging out the off-trace clusters; resulting in: + * + * node 0 1 2 3 4 5 + * 0: 10 15 17 24 24 24 + * 1: 15 10 15 24 24 24 + * 2: 17 15 10 24 24 24 + * 3: 24 24 24 10 15 17 + * 4: 24 24 24 15 10 15 + * 5: 24 24 24 17 15 10 + */ +static int slit_cluster_distance(int i, int j) +{ + static int slit_valid = -1; + int u = topology_num_nodes_per_package(); + long d = 0; + int x, y; + + if (slit_valid < 0) { + slit_valid = slit_validate(); + if (!slit_valid) + pr_err(FW_BUG "SLIT table doesn't have the expected form for SNC -- fixup disabled!\n"); + else + pr_info("Fixing up SNC SLIT table.\n"); + } + + /* + * Is this a unit cluster on the trace? + */ + if ((i / u) == (j / u) || !slit_valid) + return node_distance(i, j); + + /* + * Off-trace cluster. + * + * Notably average out the symmetric pair of off-trace clusters to + * ensure the resulting SLIT table is symmetric. + */ + x = i - (i % u); + y = j - (j % u); + + for (i = x; i < x + u; i++) { + for (j = y; j < y + u; j++) { + d += node_distance(i, j); + d += node_distance(j, i); + } + } + + return d / (2*u*u); } int arch_sched_node_distance(int from, int to) @@ -549,34 +658,14 @@ int arch_sched_node_distance(int from, int to) switch (boot_cpu_data.x86_vfm) { case INTEL_GRANITERAPIDS_X: case INTEL_ATOM_DARKMONT_X: - - if (!x86_has_numa_in_package || topology_max_packages() == 1 || - d < REMOTE_DISTANCE) + if (topology_max_packages() == 1 || + topology_num_nodes_per_package() < 3) return d; /* - * With SNC enabled, there could be too many levels of remote - * NUMA node distances, creating NUMA domain levels - * including local nodes and partial remote nodes. - * - * Trim finer distance tuning for NUMA nodes in remote package - * for the purpose of building sched domains. Group NUMA nodes - * in the remote package in the same sched group. - * Simplify NUMA domains and avoid extra NUMA levels including - * different remote NUMA nodes and local nodes. - * - * GNR and CWF don't expect systems with more than 2 packages - * and more than 2 hops between packages. Single average remote - * distance won't be appropriate if there are more than 2 - * packages as average distance to different remote packages - * could be different. + * Handle SNC-3 asymmetries. */ - WARN_ONCE(topology_max_packages() > 2, - "sched: Expect only up to 2 packages for GNR or CWF, " - "but saw %d packages when building sched domains.", - topology_max_packages()); - - d = avg_remote_numa_distance(); + return slit_cluster_distance(from, to); } return d; } @@ -606,7 +695,7 @@ void set_cpu_sibling_map(int cpu) o = &cpu_data(i); if (match_pkg(c, o) && !topology_same_node(c, o)) - x86_has_numa_in_package = true; + WARN_ON_ONCE(topology_num_nodes_per_package() == 1); if ((i == cpu) || (has_smt && match_smt(c, o))) link_mask(topology_sibling_cpumask, cpu, i); diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 5a6a772e0a6c..4dbff8ef9b1c 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -397,7 +397,7 @@ static inline void handle_invalid_op(struct pt_regs *regs) ILL_ILLOPN, error_get_trap_addr(regs)); } -static noinstr bool handle_bug(struct pt_regs *regs) +noinstr bool handle_bug(struct pt_regs *regs) { unsigned long addr = regs->ip; bool handled = false; diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c index 619dddf54424..ebb1baf1eb1d 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c @@ -696,7 +696,7 @@ static struct uprobe_trampoline *create_uprobe_trampoline(unsigned long vaddr) if (IS_ERR_VALUE(vaddr)) return NULL; - tramp = kzalloc(sizeof(*tramp), GFP_KERNEL); + tramp = kzalloc_obj(*tramp); if (unlikely(!tramp)) return NULL; diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index e6cc84143f3e..b4c1cabc7a4b 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c @@ -232,7 +232,7 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus) } if (!vm86) { - if (!(vm86 = kzalloc(sizeof(*vm86), GFP_KERNEL))) + if (!(vm86 = kzalloc_obj(*vm86))) return -ENOMEM; tsk->thread.vm86 = vm86; } diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 3a24a3fc55f5..4711a35e706c 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S @@ -427,6 +427,7 @@ SECTIONS .llvm_bb_addr_map : { *(.llvm_bb_addr_map) } #endif + MODINFO ELF_DETAILS DISCARDS diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index d916bd766c94..801bf9e520db 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -20,7 +20,6 @@ if VIRTUALIZATION config KVM_X86 def_tristate KVM if (KVM_INTEL != n || KVM_AMD != n) select KVM_COMMON - select KVM_GENERIC_MMU_NOTIFIER select KVM_ELIDE_TLB_FLUSH_IF_YOUNG select KVM_MMU_LOCKLESS_AGING select HAVE_KVM_IRQCHIP diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 7fe4e58a6ebf..8137927e7387 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c @@ -602,7 +602,7 @@ int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu, if (IS_ERR(e)) return PTR_ERR(e); - e2 = kvmalloc_array(cpuid->nent, sizeof(*e2), GFP_KERNEL_ACCOUNT); + e2 = kvmalloc_objs(*e2, cpuid->nent, GFP_KERNEL_ACCOUNT); if (!e2) { r = -ENOMEM; goto out_free_cpuid; @@ -776,7 +776,10 @@ do { \ #define SYNTHESIZED_F(name) \ ({ \ kvm_cpu_cap_synthesized |= feature_bit(name); \ - F(name); \ + \ + BUILD_BUG_ON(X86_FEATURE_##name >= MAX_CPU_FEATURES); \ + if (boot_cpu_has(X86_FEATURE_##name)) \ + F(name); \ }) /* @@ -1991,7 +1994,7 @@ int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid, if (sanity_check_entries(entries, cpuid->nent, type)) return -EINVAL; - array.entries = kvcalloc(cpuid->nent, sizeof(struct kvm_cpuid_entry2), GFP_KERNEL); + array.entries = kvzalloc_objs(struct kvm_cpuid_entry2, cpuid->nent); if (!array.entries) return -ENOMEM; diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c index 49bf744ca8e3..9b140bbdc1d8 100644 --- a/arch/x86/kvm/hyperv.c +++ b/arch/x86/kvm/hyperv.c @@ -968,7 +968,7 @@ int kvm_hv_vcpu_init(struct kvm_vcpu *vcpu) if (hv_vcpu) return 0; - hv_vcpu = kzalloc(sizeof(struct kvm_vcpu_hv), GFP_KERNEL_ACCOUNT); + hv_vcpu = kzalloc_obj(struct kvm_vcpu_hv, GFP_KERNEL_ACCOUNT); if (!hv_vcpu) return -ENOMEM; @@ -1981,16 +1981,17 @@ int kvm_hv_vcpu_flush_tlb(struct kvm_vcpu *vcpu) if (entries[i] == KVM_HV_TLB_FLUSHALL_ENTRY) goto out_flush_all; - if (is_noncanonical_invlpg_address(entries[i], vcpu)) - continue; - /* * Lower 12 bits of 'address' encode the number of additional * pages to flush. */ gva = entries[i] & PAGE_MASK; - for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) + for (j = 0; j < (entries[i] & ~PAGE_MASK) + 1; j++) { + if (is_noncanonical_invlpg_address(gva + j * PAGE_SIZE, vcpu)) + continue; + kvm_x86_call(flush_tlb_gva)(vcpu, gva + j * PAGE_SIZE); + } ++vcpu->stat.tlb_flush; } diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 850972deac8e..1982b0077ddd 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -740,7 +740,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags) pid_t pid_nr; int ret; - pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL_ACCOUNT); + pit = kzalloc_obj(struct kvm_pit, GFP_KERNEL_ACCOUNT); if (!pit) return NULL; diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 2ac7f1678c46..59e28c45d7dc 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -587,7 +587,7 @@ int kvm_pic_init(struct kvm *kvm) struct kvm_pic *s; int ret; - s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL_ACCOUNT); + s = kzalloc_obj(struct kvm_pic, GFP_KERNEL_ACCOUNT); if (!s) return -ENOMEM; spin_lock_init(&s->lock); diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index a38a8e2ac70b..eed96ff6e722 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c @@ -321,7 +321,8 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, idx = srcu_read_lock(&kvm->irq_srcu); gsi = kvm_irq_map_chip_pin(kvm, irqchip, pin); if (gsi != -1) - hlist_for_each_entry_rcu(kimn, &ioapic->mask_notifier_list, link) + hlist_for_each_entry_srcu(kimn, &ioapic->mask_notifier_list, link, + srcu_read_lock_held(&kvm->irq_srcu)) if (kimn->irq == gsi) kimn->func(kimn, mask); srcu_read_unlock(&kvm->irq_srcu, idx); @@ -717,7 +718,7 @@ int kvm_ioapic_init(struct kvm *kvm) struct kvm_ioapic *ioapic; int ret; - ioapic = kzalloc(sizeof(struct kvm_ioapic), GFP_KERNEL_ACCOUNT); + ioapic = kzalloc_obj(struct kvm_ioapic, GFP_KERNEL_ACCOUNT); if (!ioapic) return -ENOMEM; spin_lock_init(&ioapic->lock); diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 2332a258de91..9381c58d4c85 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -3058,7 +3058,7 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) return 0; } - apic = kzalloc(sizeof(*apic), GFP_KERNEL_ACCOUNT); + apic = kzalloc_obj(*apic, GFP_KERNEL_ACCOUNT); if (!apic) goto nomem; diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c index 3911ac9bddfd..b922a8b00057 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3971,7 +3971,7 @@ static int kvm_mmu_alloc_page_hash(struct kvm *kvm) if (kvm->arch.mmu_page_hash) return 0; - h = kvcalloc(KVM_NUM_MMU_PAGES, sizeof(*h), GFP_KERNEL_ACCOUNT); + h = kvzalloc_objs(*h, KVM_NUM_MMU_PAGES, GFP_KERNEL_ACCOUNT); if (!h) return -ENOMEM; diff --git a/arch/x86/kvm/svm/avic.c b/arch/x86/kvm/svm/avic.c index f92214b1a938..f7ec7914e3c4 100644 --- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -189,12 +189,12 @@ static void avic_activate_vmcb(struct vcpu_svm *svm) struct kvm_vcpu *vcpu = &svm->vcpu; vmcb->control.int_ctl &= ~(AVIC_ENABLE_MASK | X2APIC_MODE_MASK); - vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK; vmcb->control.avic_physical_id |= avic_get_max_physical_id(vcpu); - vmcb->control.int_ctl |= AVIC_ENABLE_MASK; + svm_clr_intercept(svm, INTERCEPT_CR8_WRITE); + /* * Note: KVM supports hybrid-AVIC mode, where KVM emulates x2APIC MSR * accesses, while interrupt injection to a running vCPU can be @@ -226,6 +226,9 @@ static void avic_deactivate_vmcb(struct vcpu_svm *svm) vmcb->control.int_ctl &= ~(AVIC_ENABLE_MASK | X2APIC_MODE_MASK); vmcb->control.avic_physical_id &= ~AVIC_PHYSICAL_MAX_INDEX_MASK; + if (!sev_es_guest(svm->vcpu.kvm)) + svm_set_intercept(svm, INTERCEPT_CR8_WRITE); + /* * If running nested and the guest uses its own MSR bitmap, there * is no need to update L0's msr bitmap @@ -368,7 +371,7 @@ void avic_init_vmcb(struct vcpu_svm *svm, struct vmcb *vmcb) vmcb->control.avic_physical_id = __sme_set(__pa(kvm_svm->avic_physical_id_table)); vmcb->control.avic_vapic_bar = APIC_DEFAULT_PHYS_BASE; - if (kvm_apicv_activated(svm->vcpu.kvm)) + if (kvm_vcpu_apicv_active(&svm->vcpu)) avic_activate_vmcb(svm); else avic_deactivate_vmcb(svm); diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c index de90b104a0dd..b36c33255bed 100644 --- a/arch/x86/kvm/svm/nested.c +++ b/arch/x86/kvm/svm/nested.c @@ -418,6 +418,15 @@ static bool nested_vmcb_check_controls(struct kvm_vcpu *vcpu) return __nested_vmcb_check_controls(vcpu, ctl); } +int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu) +{ + if (!nested_vmcb_check_save(vcpu) || + !nested_vmcb_check_controls(vcpu)) + return -EINVAL; + + return 0; +} + /* * If a feature is not advertised to L1, clear the corresponding vmcb12 * intercept. @@ -1028,8 +1037,7 @@ int nested_svm_vmrun(struct kvm_vcpu *vcpu) nested_copy_vmcb_control_to_cache(svm, &vmcb12->control); nested_copy_vmcb_save_to_cache(svm, &vmcb12->save); - if (!nested_vmcb_check_save(vcpu) || - !nested_vmcb_check_controls(vcpu)) { + if (nested_svm_check_cached_vmcb12(vcpu) < 0) { vmcb12->control.exit_code = SVM_EXIT_ERR; vmcb12->control.exit_info_1 = 0; vmcb12->control.exit_info_2 = 0; @@ -1781,7 +1789,7 @@ static int svm_get_nested_state(struct kvm_vcpu *vcpu, if (clear_user(user_vmcb, KVM_STATE_NESTED_SVM_VMCB_SIZE)) return -EFAULT; - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kzalloc_obj(*ctl); if (!ctl) return -ENOMEM; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index ea515cf41168..3f9c1aa39a0a 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -2512,7 +2512,7 @@ static int snp_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp) if (ret) return ret; - data = kzalloc(sizeof(*data), GFP_KERNEL_ACCOUNT); + data = kzalloc_obj(*data, GFP_KERNEL_ACCOUNT); if (!data) return -ENOMEM; @@ -2711,7 +2711,7 @@ int sev_mem_enc_register_region(struct kvm *kvm, if (range->addr > ULONG_MAX || range->size > ULONG_MAX) return -EINVAL; - region = kzalloc(sizeof(*region), GFP_KERNEL_ACCOUNT); + region = kzalloc_obj(*region, GFP_KERNEL_ACCOUNT); if (!region) return -ENOMEM; diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 8f8bc863e214..e6477affac9a 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -1077,8 +1077,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu, bool init_event) svm_set_intercept(svm, INTERCEPT_CR0_WRITE); svm_set_intercept(svm, INTERCEPT_CR3_WRITE); svm_set_intercept(svm, INTERCEPT_CR4_WRITE); - if (!kvm_vcpu_apicv_active(vcpu)) - svm_set_intercept(svm, INTERCEPT_CR8_WRITE); + svm_set_intercept(svm, INTERCEPT_CR8_WRITE); set_dr_intercepts(svm); @@ -1189,7 +1188,7 @@ static void init_vmcb(struct kvm_vcpu *vcpu, bool init_event) if (guest_cpu_cap_has(vcpu, X86_FEATURE_ERAPS)) svm->vmcb->control.erap_ctl |= ERAP_CONTROL_ALLOW_LARGER_RAP; - if (kvm_vcpu_apicv_active(vcpu)) + if (enable_apicv && irqchip_in_kernel(vcpu->kvm)) avic_init_vmcb(svm, vmcb); if (vnmi) @@ -2674,9 +2673,11 @@ static int dr_interception(struct kvm_vcpu *vcpu) static int cr8_write_interception(struct kvm_vcpu *vcpu) { + u8 cr8_prev = kvm_get_cr8(vcpu); int r; - u8 cr8_prev = kvm_get_cr8(vcpu); + WARN_ON_ONCE(kvm_vcpu_apicv_active(vcpu)); + /* instruction emulation calls kvm_set_cr8() */ r = cr_interception(vcpu); if (lapic_in_kernel(vcpu)) @@ -4879,11 +4880,15 @@ static int svm_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram) vmcb12 = map.hva; nested_copy_vmcb_control_to_cache(svm, &vmcb12->control); nested_copy_vmcb_save_to_cache(svm, &vmcb12->save); - ret = enter_svm_guest_mode(vcpu, smram64->svm_guest_vmcb_gpa, vmcb12, false); - if (ret) + if (nested_svm_check_cached_vmcb12(vcpu) < 0) goto unmap_save; + if (enter_svm_guest_mode(vcpu, smram64->svm_guest_vmcb_gpa, + vmcb12, false) != 0) + goto unmap_save; + + ret = 0; svm->nested.nested_run_pending = 1; unmap_save: diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index ebd7b36b1ceb..6942e6b0eda6 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -797,6 +797,7 @@ static inline int nested_svm_simple_vmexit(struct vcpu_svm *svm, u32 exit_code) int nested_svm_exit_handled(struct vcpu_svm *svm); int nested_svm_check_permissions(struct kvm_vcpu *vcpu); +int nested_svm_check_cached_vmcb12(struct kvm_vcpu *vcpu); int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr, bool has_error_code, u32 error_code); int nested_svm_exit_special(struct vcpu_svm *svm); diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index 248635da6766..937aeb474af7 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -3300,10 +3300,24 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu, if (CC(vmcs12->guest_cr4 & X86_CR4_CET && !(vmcs12->guest_cr0 & X86_CR0_WP))) return -EINVAL; - if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) && - (CC(!kvm_dr7_valid(vmcs12->guest_dr7)) || - CC(!vmx_is_valid_debugctl(vcpu, vmcs12->guest_ia32_debugctl, false)))) - return -EINVAL; + if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_DEBUG_CONTROLS) { + u64 debugctl = vmcs12->guest_ia32_debugctl; + + /* + * FREEZE_IN_SMM is not virtualized, but allow L1 to set it in + * vmcs12's DEBUGCTL under a quirk for backwards compatibility. + * Note that the quirk only relaxes the consistency check. The + * vmcc02 bit is still under the control of the host. In + * particular, if a host administrator decides to clear the bit, + * then L1 has no say in the matter. + */ + if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_VMCS12_ALLOW_FREEZE_IN_SMM)) + debugctl &= ~DEBUGCTLMSR_FREEZE_IN_SMM; + + if (CC(!kvm_dr7_valid(vmcs12->guest_dr7)) || + CC(!vmx_is_valid_debugctl(vcpu, debugctl, false))) + return -EINVAL; + } if ((vmcs12->vm_entry_controls & VM_ENTRY_LOAD_IA32_PAT) && CC(!kvm_pat_valid(vmcs12->guest_ia32_pat))) @@ -6842,13 +6856,34 @@ void vmx_leave_nested(struct kvm_vcpu *vcpu) free_nested(vcpu); } +int nested_vmx_check_restored_vmcs12(struct kvm_vcpu *vcpu) +{ + enum vm_entry_failure_code ignored; + struct vmcs12 *vmcs12 = get_vmcs12(vcpu); + + if (nested_cpu_has_shadow_vmcs(vmcs12) && + vmcs12->vmcs_link_pointer != INVALID_GPA) { + struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu); + + if (shadow_vmcs12->hdr.revision_id != VMCS12_REVISION || + !shadow_vmcs12->hdr.shadow_vmcs) + return -EINVAL; + } + + if (nested_vmx_check_controls(vcpu, vmcs12) || + nested_vmx_check_host_state(vcpu, vmcs12) || + nested_vmx_check_guest_state(vcpu, vmcs12, &ignored)) + return -EINVAL; + + return 0; +} + static int vmx_set_nested_state(struct kvm_vcpu *vcpu, struct kvm_nested_state __user *user_kvm_nested_state, struct kvm_nested_state *kvm_state) { struct vcpu_vmx *vmx = to_vmx(vcpu); struct vmcs12 *vmcs12; - enum vm_entry_failure_code ignored; struct kvm_vmx_nested_state_data __user *user_vmx_nested_state = &user_kvm_nested_state->data.vmx[0]; int ret; @@ -6979,25 +7014,20 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, vmx->nested.mtf_pending = !!(kvm_state->flags & KVM_STATE_NESTED_MTF_PENDING); - ret = -EINVAL; if (nested_cpu_has_shadow_vmcs(vmcs12) && vmcs12->vmcs_link_pointer != INVALID_GPA) { struct vmcs12 *shadow_vmcs12 = get_shadow_vmcs12(vcpu); + ret = -EINVAL; if (kvm_state->size < sizeof(*kvm_state) + sizeof(user_vmx_nested_state->vmcs12) + sizeof(*shadow_vmcs12)) goto error_guest_mode; + ret = -EFAULT; if (copy_from_user(shadow_vmcs12, user_vmx_nested_state->shadow_vmcs12, - sizeof(*shadow_vmcs12))) { - ret = -EFAULT; - goto error_guest_mode; - } - - if (shadow_vmcs12->hdr.revision_id != VMCS12_REVISION || - !shadow_vmcs12->hdr.shadow_vmcs) + sizeof(*shadow_vmcs12))) goto error_guest_mode; } @@ -7008,9 +7038,8 @@ static int vmx_set_nested_state(struct kvm_vcpu *vcpu, kvm_state->hdr.vmx.preemption_timer_deadline; } - if (nested_vmx_check_controls(vcpu, vmcs12) || - nested_vmx_check_host_state(vcpu, vmcs12) || - nested_vmx_check_guest_state(vcpu, vmcs12, &ignored)) + ret = nested_vmx_check_restored_vmcs12(vcpu); + if (ret < 0) goto error_guest_mode; vmx->nested.dirty_vmcs12 = true; diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h index b844c5d59025..213a448104af 100644 --- a/arch/x86/kvm/vmx/nested.h +++ b/arch/x86/kvm/vmx/nested.h @@ -22,6 +22,7 @@ void nested_vmx_setup_ctls_msrs(struct vmcs_config *vmcs_conf, u32 ept_caps); void nested_vmx_hardware_unsetup(void); __init int nested_vmx_hardware_setup(int (*exit_handlers[])(struct kvm_vcpu *)); void nested_vmx_set_vmcs_shadowing_bitmap(void); +int nested_vmx_check_restored_vmcs12(struct kvm_vcpu *vcpu); void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu); enum nvmx_vmentry_status nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry); diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c index 5df9d32d2058..c5065f84b78b 100644 --- a/arch/x86/kvm/vmx/tdx.c +++ b/arch/x86/kvm/vmx/tdx.c @@ -2218,8 +2218,7 @@ static int tdx_get_capabilities(struct kvm_tdx_cmd *cmd) if (nr_user_entries < td_conf->num_cpuid_config) return -E2BIG; - caps = kzalloc(struct_size(caps, cpuid.entries, - td_conf->num_cpuid_config), GFP_KERNEL); + caps = kzalloc_flex(*caps, cpuid.entries, td_conf->num_cpuid_config); if (!caps) return -ENOMEM; @@ -2407,8 +2406,8 @@ static int __tdx_td_init(struct kvm *kvm, struct td_params *td_params, kvm_tdx->td.tdcs_nr_pages = tdx_sysinfo->td_ctrl.tdcs_base_size / PAGE_SIZE; /* TDVPS = TDVPR(4K page) + TDCX(multiple 4K pages), -1 for TDVPR. */ kvm_tdx->td.tdcx_nr_pages = tdx_sysinfo->td_ctrl.tdvps_base_size / PAGE_SIZE - 1; - tdcs_pages = kcalloc(kvm_tdx->td.tdcs_nr_pages, sizeof(*kvm_tdx->td.tdcs_pages), - GFP_KERNEL); + tdcs_pages = kzalloc_objs(*kvm_tdx->td.tdcs_pages, + kvm_tdx->td.tdcs_nr_pages); if (!tdcs_pages) goto free_tdr; @@ -2743,7 +2742,7 @@ static int tdx_td_init(struct kvm *kvm, struct kvm_tdx_cmd *cmd) goto out; } - td_params = kzalloc(sizeof(struct td_params), GFP_KERNEL); + td_params = kzalloc_obj(struct td_params); if (!td_params) { ret = -ENOMEM; goto out; diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 967b58a8ab9d..8b24e682535b 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -1149,7 +1149,7 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, } vmx_add_auto_msr(&m->guest, msr, guest_val, VM_ENTRY_MSR_LOAD_COUNT, kvm); - vmx_add_auto_msr(&m->guest, msr, host_val, VM_EXIT_MSR_LOAD_COUNT, kvm); + vmx_add_auto_msr(&m->host, msr, host_val, VM_EXIT_MSR_LOAD_COUNT, kvm); } static bool update_transition_efer(struct vcpu_vmx *vmx) @@ -8528,9 +8528,13 @@ int vmx_leave_smm(struct kvm_vcpu *vcpu, const union kvm_smram *smram) } if (vmx->nested.smm.guest_mode) { + /* Triple fault if the state is invalid. */ + if (nested_vmx_check_restored_vmcs12(vcpu) < 0) + return 1; + ret = nested_vmx_enter_non_root_mode(vcpu, false); - if (ret) - return ret; + if (ret != NVMX_VMENTRY_SUCCESS) + return 1; vmx->nested.nested_run_pending = 1; vmx->nested.smm.guest_mode = false; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 391f4a5ce6dd..fd1c4a36b593 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -243,7 +243,7 @@ EXPORT_SYMBOL_FOR_KVM_INTERNAL(enable_ipiv); bool __read_mostly enable_device_posted_irqs = true; EXPORT_SYMBOL_FOR_KVM_INTERNAL(enable_device_posted_irqs); -const struct _kvm_stats_desc kvm_vm_stats_desc[] = { +const struct kvm_stats_desc kvm_vm_stats_desc[] = { KVM_GENERIC_VM_STATS(), STATS_DESC_COUNTER(VM, mmu_shadow_zapped), STATS_DESC_COUNTER(VM, mmu_pte_write), @@ -269,7 +269,7 @@ const struct kvm_stats_header kvm_vm_stats_header = { sizeof(kvm_vm_stats_desc), }; -const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = { +const struct kvm_stats_desc kvm_vcpu_stats_desc[] = { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, pf_taken), STATS_DESC_COUNTER(VCPU, pf_fixed), @@ -4805,7 +4805,6 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) #endif case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: - case KVM_CAP_SYNC_MMU: case KVM_CAP_USER_NMI: case KVM_CAP_IRQ_INJECT_STATUS: case KVM_CAP_IOEVENTFD: @@ -6208,7 +6207,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r = -EINVAL; if (!lapic_in_kernel(vcpu)) goto out; - u.lapic = kzalloc(sizeof(struct kvm_lapic_state), GFP_KERNEL); + u.lapic = kzalloc_obj(struct kvm_lapic_state); r = -ENOMEM; if (!u.lapic) @@ -6410,7 +6409,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, if (vcpu->arch.guest_fpu.uabi_size > sizeof(struct kvm_xsave)) break; - u.xsave = kzalloc(sizeof(struct kvm_xsave), GFP_KERNEL); + u.xsave = kzalloc_obj(struct kvm_xsave); r = -ENOMEM; if (!u.xsave) break; @@ -6459,7 +6458,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, } case KVM_GET_XCRS: { - u.xcrs = kzalloc(sizeof(struct kvm_xcrs), GFP_KERNEL); + u.xcrs = kzalloc_obj(struct kvm_xcrs); r = -ENOMEM; if (!u.xcrs) break; @@ -6619,7 +6618,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp, vcpu->arch.guest_state_protected) goto out; - u.sregs2 = kzalloc(sizeof(struct kvm_sregs2), GFP_KERNEL); + u.sregs2 = kzalloc_obj(struct kvm_sregs2); r = -ENOMEM; if (!u.sregs2) goto out; @@ -6994,7 +6993,7 @@ static struct kvm_x86_msr_filter *kvm_alloc_msr_filter(bool default_allow) { struct kvm_x86_msr_filter *msr_filter; - msr_filter = kzalloc(sizeof(*msr_filter), GFP_KERNEL_ACCOUNT); + msr_filter = kzalloc_obj(*msr_filter, GFP_KERNEL_ACCOUNT); if (!msr_filter) return NULL; diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c index 28eeb1b2a16c..91fd3673c09a 100644 --- a/arch/x86/kvm/xen.c +++ b/arch/x86/kvm/xen.c @@ -1514,8 +1514,7 @@ static bool kvm_xen_schedop_poll(struct kvm_vcpu *vcpu, bool longmode, return true; } - ports = kmalloc_array(sched_poll.nr_ports, - sizeof(*ports), GFP_KERNEL); + ports = kmalloc_objs(*ports, sched_poll.nr_ports); if (!ports) { *r = -ENOMEM; return true; @@ -2116,7 +2115,7 @@ static int kvm_xen_eventfd_assign(struct kvm *kvm, struct evtchnfd *evtchnfd; int ret = -EINVAL; - evtchnfd = kzalloc(sizeof(struct evtchnfd), GFP_KERNEL); + evtchnfd = kzalloc_obj(struct evtchnfd); if (!evtchnfd) return -ENOMEM; @@ -2214,7 +2213,7 @@ static int kvm_xen_eventfd_reset(struct kvm *kvm) idr_for_each_entry(&kvm->arch.xen.evtchn_ports, evtchnfd, i) n++; - all_evtchnfds = kmalloc_array(n, sizeof(struct evtchnfd *), GFP_KERNEL); + all_evtchnfds = kmalloc_objs(struct evtchnfd *, n); if (!all_evtchnfds) { mutex_unlock(&kvm->arch.xen.xen_lock); return -ENOMEM; diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 2fdc1f1f5adb..6b9ff1c6cafa 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -411,14 +411,11 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr) return; if (trapnr == X86_TRAP_UD) { - if (report_bug(regs->ip, regs) == BUG_TRAP_TYPE_WARN) { - /* Skip the ud2. */ - regs->ip += LEN_UD2; + if (handle_bug(regs)) return; - } /* - * If this was a BUG and report_bug returns or if this + * If this was a BUG and handle_bug returns or if this * was just a normal #UD, we want to continue onward and * crash. */ diff --git a/arch/x86/mm/kmmio.c b/arch/x86/mm/kmmio.c index 9f82019179e1..6ac981cec652 100644 --- a/arch/x86/mm/kmmio.c +++ b/arch/x86/mm/kmmio.c @@ -387,7 +387,7 @@ static int add_kmmio_fault_page(unsigned long addr) return 0; } - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return -1; @@ -562,7 +562,7 @@ void unregister_kmmio_probe(struct kmmio_probe *p) if (!release_list) return; - drelease = kmalloc(sizeof(*drelease), GFP_ATOMIC); + drelease = kmalloc_obj(*drelease, GFP_ATOMIC); if (!drelease) { pr_crit("leaking kmmio_fault_page objects.\n"); return; diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c index c3317f0650d8..265ad1a0ae0a 100644 --- a/arch/x86/mm/mmio-mod.c +++ b/arch/x86/mm/mmio-mod.c @@ -220,7 +220,7 @@ static void ioremap_trace_core(resource_size_t offset, unsigned long size, void __iomem *addr) { static atomic_t next_id; - struct remap_trace *trace = kmalloc(sizeof(*trace), GFP_KERNEL); + struct remap_trace *trace = kmalloc_obj(*trace); /* These are page-unaligned. */ struct mmiotrace_map map = { .phys = offset, diff --git a/arch/x86/mm/numa.c b/arch/x86/mm/numa.c index 7a97327140df..99d0a9332c14 100644 --- a/arch/x86/mm/numa.c +++ b/arch/x86/mm/numa.c @@ -48,6 +48,8 @@ s16 __apicid_to_node[MAX_LOCAL_APIC] = { [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE }; +nodemask_t numa_phys_nodes_parsed __initdata; + int numa_cpu_node(int cpu) { u32 apicid = early_per_cpu(x86_cpu_to_apicid, cpu); @@ -57,6 +59,11 @@ int numa_cpu_node(int cpu) return NUMA_NO_NODE; } +int __init num_phys_nodes(void) +{ + return bitmap_weight(numa_phys_nodes_parsed.bits, MAX_NUMNODES); +} + cpumask_var_t node_to_cpumask_map[MAX_NUMNODES]; EXPORT_SYMBOL(node_to_cpumask_map); @@ -210,6 +217,7 @@ static int __init dummy_numa_init(void) 0LLU, PFN_PHYS(max_pfn) - 1); node_set(0, numa_nodes_parsed); + node_set(0, numa_phys_nodes_parsed); numa_add_memblk(0, 0, PFN_PHYS(max_pfn)); return 0; diff --git a/arch/x86/mm/pat/memtype.c b/arch/x86/mm/pat/memtype.c index 8a3d9722f602..cf94fb561310 100644 --- a/arch/x86/mm/pat/memtype.c +++ b/arch/x86/mm/pat/memtype.c @@ -574,7 +574,7 @@ int memtype_reserve(u64 start, u64 end, enum page_cache_mode req_type, return -EINVAL; } - entry_new = kzalloc(sizeof(struct memtype), GFP_KERNEL); + entry_new = kzalloc_obj(struct memtype); if (!entry_new) return -ENOMEM; @@ -966,7 +966,7 @@ static struct memtype *memtype_get_idx(loff_t pos) struct memtype *entry_print; int ret; - entry_print = kzalloc(sizeof(struct memtype), GFP_KERNEL); + entry_print = kzalloc_obj(struct memtype); if (!entry_print) return NULL; diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 6f8e0f21c710..44ca66651756 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c @@ -57,6 +57,7 @@ acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa) } set_apicid_to_node(apic_id, node); node_set(node, numa_nodes_parsed); + node_set(node, numa_phys_nodes_parsed); pr_debug("SRAT: PXM %u -> APIC 0x%04x -> Node %u\n", pxm, apic_id, node); } @@ -97,6 +98,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) set_apicid_to_node(apic_id, node); node_set(node, numa_nodes_parsed); + node_set(node, numa_phys_nodes_parsed); pr_debug("SRAT: PXM %u -> APIC 0x%02x -> Node %u\n", pxm, apic_id, node); } diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index 070ba80e39d7..e9b78040d703 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -438,17 +438,8 @@ static void emit_kcfi(u8 **pprog, u32 hash) EMIT1_off32(0xb8, hash); /* movl $hash, %eax */ #ifdef CONFIG_CALL_PADDING - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); - EMIT1(0x90); + for (int i = 0; i < CONFIG_FUNCTION_PADDING_CFI; i++) + EMIT1(0x90); #endif EMIT_ENDBR(); @@ -3758,7 +3749,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) jit_data = prog->aux->jit_data; if (!jit_data) { - jit_data = kzalloc(sizeof(*jit_data), GFP_KERNEL); + jit_data = kzalloc_obj(*jit_data); if (!jit_data) { prog = orig_prog; goto out; @@ -3794,7 +3785,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) padding = true; goto skip_init_addrs; } - addrs = kvmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL); + addrs = kvmalloc_objs(*addrs, prog->len + 1); if (!addrs) { prog = orig_prog; goto out_addrs; diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c index de0f9e5f9f73..dda423025c3d 100644 --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -2545,7 +2545,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) prog = tmp; } - addrs = kmalloc_array(prog->len, sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc_objs(*addrs, prog->len); if (!addrs) { prog = orig_prog; goto out; diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0c316bae1726..7cd5388edc75 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -562,7 +562,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) } else { struct pci_root_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) dev_err(&root->device->dev, "pci_bus %04x:%02x: ignored (out of memory)\n", diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c index e4a525e59eaf..0e165149d0e9 100644 --- a/arch/x86/pci/bus_numa.c +++ b/arch/x86/pci/bus_numa.c @@ -72,7 +72,7 @@ struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max, { struct pci_root_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return info; @@ -132,7 +132,7 @@ void update_res(struct pci_root_info *info, resource_size_t start, addit: /* need to add that */ - root_res = kzalloc(sizeof(*root_res), GFP_KERNEL); + root_res = kzalloc_obj(*root_res); if (!root_res) return; diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index ddb798603201..63105b29fbf5 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c @@ -461,7 +461,7 @@ void pcibios_scan_root(int busnum) struct pci_sysdata *sd; LIST_HEAD(resources); - sd = kzalloc(sizeof(*sd), GFP_KERNEL); + sd = kzalloc_obj(*sd); if (!sd) { printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum); return; diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 25076a5acd96..b301c6c8df75 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c @@ -771,7 +771,7 @@ static void pci_amd_enable_64bit_bar(struct pci_dev *dev) if (i == 8) return; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return; diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index f2f4a5d50b27..c4ec39ad276b 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c @@ -81,7 +81,7 @@ pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr) map = pcibios_fwaddrmap_lookup(dev); if (!map) { spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return; diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 1f4522325920..acdb8dcaeb52 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -77,7 +77,7 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start, if (addr == 0) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index b8755cde2419..6818515a501b 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -173,7 +173,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) if (type == PCI_CAP_ID_MSI && nvec > 1) return 1; - v = kcalloc(max(1, nvec), sizeof(int), GFP_KERNEL); + v = kzalloc_objs(int, max(1, nvec)); if (!v) return -ENOMEM; diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index d00c6de7f3b7..d84c6020dda1 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c @@ -836,7 +836,7 @@ static void __init __efi_enter_virtual_mode(void) } efi_check_for_embedded_firmwares(); - efi_free_boot_services(); + efi_unmap_boot_services(); if (!efi_is_mixed()) efi_native_runtime_setup(); diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 553f330198f2..35caa5746115 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -341,7 +341,7 @@ void __init efi_reserve_boot_services(void) /* * Because the following memblock_reserve() is paired - * with memblock_free_late() for this region in + * with free_reserved_area() for this region in * efi_free_boot_services(), we must be extremely * careful not to reserve, and subsequently free, * critical regions of memory (like the kernel image) or @@ -404,17 +404,33 @@ static void __init efi_unmap_pages(efi_memory_desc_t *md) pr_err("Failed to unmap VA mapping for 0x%llx\n", va); } -void __init efi_free_boot_services(void) +struct efi_freeable_range { + u64 start; + u64 end; +}; + +static struct efi_freeable_range *ranges_to_free; + +void __init efi_unmap_boot_services(void) { struct efi_memory_map_data data = { 0 }; efi_memory_desc_t *md; int num_entries = 0; + int idx = 0; + size_t sz; void *new, *new_md; /* Keep all regions for /sys/kernel/debug/efi */ if (efi_enabled(EFI_DBG)) return; + sz = sizeof(*ranges_to_free) * efi.memmap.nr_map + 1; + ranges_to_free = kzalloc(sz, GFP_KERNEL); + if (!ranges_to_free) { + pr_err("Failed to allocate storage for freeable EFI regions\n"); + return; + } + for_each_efi_memory_desc(md) { unsigned long long start = md->phys_addr; unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; @@ -471,7 +487,15 @@ void __init efi_free_boot_services(void) start = SZ_1M; } - memblock_free_late(start, size); + /* + * With CONFIG_DEFERRED_STRUCT_PAGE_INIT parts of the memory + * map are still not initialized and we can't reliably free + * memory here. + * Queue the ranges to free at a later point. + */ + ranges_to_free[idx].start = start; + ranges_to_free[idx].end = start + size; + idx++; } if (!num_entries) @@ -512,6 +536,31 @@ void __init efi_free_boot_services(void) } } +static int __init efi_free_boot_services(void) +{ + struct efi_freeable_range *range = ranges_to_free; + unsigned long freed = 0; + + if (!ranges_to_free) + return 0; + + while (range->start) { + void *start = phys_to_virt(range->start); + void *end = phys_to_virt(range->end); + + free_reserved_area(start, end, -1, NULL); + freed += (end - start); + range++; + } + kfree(ranges_to_free); + + if (freed) + pr_info("Freeing EFI boot services memory: %ldK\n", freed / SZ_1K); + + return 0; +} +arch_initcall(efi_free_boot_services); + /* * A number of config table entries get remapped to virtual addresses * after entering EFI virtual mode. However, the kexec kernel requires diff --git a/arch/x86/platform/efi/runtime-map.c b/arch/x86/platform/efi/runtime-map.c index a6f02cef3ca2..053ff161eb9a 100644 --- a/arch/x86/platform/efi/runtime-map.c +++ b/arch/x86/platform/efi/runtime-map.c @@ -114,7 +114,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr, return ERR_PTR(-ENOMEM); } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { kset_unregister(map_kset); map_kset = NULL; @@ -166,7 +166,7 @@ static int __init efi_runtime_map_init(void) if (!efi_enabled(EFI_MEMMAP) || !efi_kobj) return 0; - map_entries = kcalloc(efi.memmap.nr_map, sizeof(entry), GFP_KERNEL); + map_entries = kzalloc_objs(entry, efi.memmap.nr_map); if (!map_entries) { ret = -ENOMEM; goto out; diff --git a/arch/x86/platform/geode/geode-common.c b/arch/x86/platform/geode/geode-common.c index 8fd78e60bf15..05189c5f7d2a 100644 --- a/arch/x86/platform/geode/geode-common.c +++ b/arch/x86/platform/geode/geode-common.c @@ -113,7 +113,7 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds, return -EINVAL; } - swnodes = kcalloc(n_leds, sizeof(*swnodes), GFP_KERNEL); + swnodes = kzalloc_objs(*swnodes, n_leds); if (!swnodes) return -ENOMEM; @@ -121,7 +121,7 @@ int __init geode_create_leds(const char *label, const struct geode_led *leds, * Each LED is represented by 3 properties: "gpios", * "linux,default-trigger", and am empty terminator. */ - props = kcalloc(n_leds * 3, sizeof(*props), GFP_KERNEL); + props = kzalloc_objs(*props, n_leds * 3); if (!props) { err = -ENOMEM; goto err_free_swnodes; diff --git a/arch/x86/platform/pvh/enlighten.c b/arch/x86/platform/pvh/enlighten.c index 2263885d16ba..f2053cbe9b0c 100644 --- a/arch/x86/platform/pvh/enlighten.c +++ b/arch/x86/platform/pvh/enlighten.c @@ -25,11 +25,6 @@ struct hvm_start_info __initdata pvh_start_info; const unsigned int __initconst pvh_start_info_sz = sizeof(pvh_start_info); -static u64 __init pvh_get_root_pointer(void) -{ - return pvh_start_info.rsdp_paddr; -} - /* * Xen guests are able to obtain the memory map from the hypervisor via the * HYPERVISOR_memory_op hypercall. @@ -95,7 +90,7 @@ static void __init init_pvh_bootparams(bool xen_guest) pvh_bootparams.hdr.version = (2 << 8) | 12; pvh_bootparams.hdr.type_of_loader = ((xen_guest ? 0x9 : 0xb) << 4) | 0; - x86_init.acpi.get_root_pointer = pvh_get_root_pointer; + pvh_bootparams.acpi_rsdp_addr = pvh_start_info.rsdp_paddr; } /* diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index 916441f5e85c..702f30eaf9c4 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -394,7 +394,7 @@ static int msr_build_context(const u32 *msr_id, const int num) total_num = saved_msrs->num + num; - msr_array = kmalloc_array(total_num, sizeof(struct saved_msr), GFP_KERNEL); + msr_array = kmalloc_objs(struct saved_msr, total_num); if (!msr_array) { pr_err("x86/pm: Can not allocate memory to save/restore MSRs during suspend.\n"); return -ENOMEM; diff --git a/arch/x86/virt/svm/sev.c b/arch/x86/virt/svm/sev.c index ee643a6cd691..a4f3a364fb65 100644 --- a/arch/x86/virt/svm/sev.c +++ b/arch/x86/virt/svm/sev.c @@ -313,7 +313,7 @@ static bool __init alloc_rmp_segment_desc(u64 segment_pa, u64 segment_size, u64 return false; } - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) { memunmap(rmp_segment); return false; diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c index 5ce4ebe99774..8b8e165a2001 100644 --- a/arch/x86/virt/vmx/tdx/tdx.c +++ b/arch/x86/virt/vmx/tdx/tdx.c @@ -194,7 +194,7 @@ static int add_tdx_memblock(struct list_head *tmb_list, unsigned long start_pfn, { struct tdx_memblock *tmb; - tmb = kmalloc(sizeof(*tmb), GFP_KERNEL); + tmb = kmalloc_obj(*tmb); if (!tmb) return -ENOMEM; diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 6e459e47cafd..eaad22b47206 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -392,7 +392,7 @@ static void __init xen_init_capabilities(void) /* * Xen PV would need some work to support PCID: CR3 handling as well - * as xen_flush_tlb_others() would need updating. + * as xen_flush_tlb_multi() would need updating. */ setup_clear_cpu_cap(X86_FEATURE_PCID); diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c index 1e681bf62561..5f4060b5a40d 100644 --- a/arch/x86/xen/grant-table.c +++ b/arch/x86/xen/grant-table.c @@ -101,7 +101,7 @@ static int gnttab_apply(pte_t *pte, unsigned long addr, void *data) static int arch_gnttab_valloc(struct gnttab_vm_area *area, unsigned nr_frames) { - area->ptes = kmalloc_array(nr_frames, sizeof(*area->ptes), GFP_KERNEL); + area->ptes = kmalloc_objs(*area->ptes, nr_frames); if (area->ptes == NULL) return -ENOMEM; area->area = get_vm_area(PAGE_SIZE * nr_frames, VM_IOREMAP); diff --git a/arch/x86/xen/mmu_pv.c b/arch/x86/xen/mmu_pv.c index 963154feae06..c80d0058efd1 100644 --- a/arch/x86/xen/mmu_pv.c +++ b/arch/x86/xen/mmu_pv.c @@ -105,6 +105,9 @@ pte_t xen_make_pte_init(pteval_t pte); static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss; #endif +static pud_t level3_ident_pgt[PTRS_PER_PUD] __page_aligned_bss; +static pmd_t level2_ident_pgt[PTRS_PER_PMD] __page_aligned_bss; + /* * Protects atomic reservation decrease/increase against concurrent increases. * Also protects non-atomic updates of current_pages and balloon lists. @@ -509,6 +512,9 @@ static pgd_t *xen_get_user_pgd(pgd_t *pgd) unsigned offset = pgd - pgd_page; pgd_t *user_ptr = NULL; + if (!static_branch_likely(&xen_struct_pages_ready)) + return NULL; + if (offset < pgd_index(USER_LIMIT)) { struct page *page = virt_to_page(pgd_page); user_ptr = (pgd_t *)page->private; @@ -1098,7 +1104,8 @@ static void __init xen_cleanmfnmap_free_pgtbl(void *pgtbl, bool unpin) if (unpin) pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(pa)); - ClearPagePinned(virt_to_page(__va(pa))); + if (static_branch_likely(&xen_struct_pages_ready)) + ClearPagePinned(virt_to_page(__va(pa))); xen_free_ro_pages(pa, PAGE_SIZE); } @@ -1773,6 +1780,12 @@ void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn) /* Zap identity mapping */ init_top_pgt[0] = __pgd(0); + init_top_pgt[pgd_index(__PAGE_OFFSET_BASE_L4)].pgd = + __pa_symbol(level3_ident_pgt) + _KERNPG_TABLE_NOENC; + init_top_pgt[pgd_index(__START_KERNEL_map)].pgd = + __pa_symbol(level3_kernel_pgt) + _PAGE_TABLE_NOENC; + level3_ident_pgt[0].pud = __pa_symbol(level2_ident_pgt) + _KERNPG_TABLE_NOENC; + /* Pre-constructed entries are in pfn, so convert to mfn */ /* L4[273] -> level3_ident_pgt */ /* L4[511] -> level3_kernel_pgt */ diff --git a/arch/x86/xen/smp_pv.c b/arch/x86/xen/smp_pv.c index c40f326f0c3a..db9b8e222b38 100644 --- a/arch/x86/xen/smp_pv.c +++ b/arch/x86/xen/smp_pv.c @@ -230,7 +230,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle) if (cpumask_test_and_set_cpu(cpu, xen_cpu_initialized_map)) return 0; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (ctxt == NULL) { cpumask_clear_cpu(cpu, xen_cpu_initialized_map); return -ENOMEM; diff --git a/arch/xtensa/kernel/align.S b/arch/xtensa/kernel/align.S index ee97edce2300..f2d0d831ce43 100644 --- a/arch/xtensa/kernel/align.S +++ b/arch/xtensa/kernel/align.S @@ -21,6 +21,9 @@ #include #include #include +#ifdef CONFIG_MMU +#include +#endif #if XCHAL_UNALIGNED_LOAD_EXCEPTION || defined CONFIG_XTENSA_LOAD_STORE #define LOAD_EXCEPTION_HANDLER @@ -185,8 +188,11 @@ ENTRY(fast_load_store) #ifdef CONFIG_MMU /* l32e can't be used here even when it's available. */ - /* TODO access_ok(a3) could be used here */ - j .Linvalid_instruction + rsr a6, ps + bbci.l a6, PS_UM_BIT, 1f # kernel mode + movi a5, 8 + access_ok a3, a5, a6, a2, .Linvalid_instruction +1: #endif l32i a5, a3, 0 l32i a6, a3, 4 diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index ff0600a0584c..b80d54b2ea34 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -123,7 +123,7 @@ static int tie_get(struct task_struct *target, int ret; struct pt_regs *regs = task_pt_regs(target); struct thread_info *ti = task_thread_info(target); - elf_xtregs_t *newregs = kzalloc(sizeof(elf_xtregs_t), GFP_KERNEL); + elf_xtregs_t *newregs = kzalloc_obj(elf_xtregs_t); if (!newregs) return -ENOMEM; @@ -156,7 +156,7 @@ static int tie_set(struct task_struct *target, int ret; struct pt_regs *regs = task_pt_regs(target); struct thread_info *ti = task_thread_info(target); - elf_xtregs_t *newregs = kzalloc(sizeof(elf_xtregs_t), GFP_KERNEL); + elf_xtregs_t *newregs = kzalloc_obj(elf_xtregs_t); if (!newregs) return -ENOMEM; diff --git a/arch/xtensa/platforms/iss/simdisk.c b/arch/xtensa/platforms/iss/simdisk.c index 3cafc8feddee..7c7a2aa749f8 100644 --- a/arch/xtensa/platforms/iss/simdisk.c +++ b/arch/xtensa/platforms/iss/simdisk.c @@ -320,7 +320,7 @@ static int __init simdisk_init(void) if (simdisk_count > MAX_SIMDISK_COUNT) simdisk_count = MAX_SIMDISK_COUNT; - sddev = kmalloc_array(simdisk_count, sizeof(*sddev), GFP_KERNEL); + sddev = kmalloc_objs(*sddev, simdisk_count); if (sddev == NULL) goto out_unregister; diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index 6a75fe1c7a5c..ac83b0668764 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c @@ -494,7 +494,7 @@ static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp) { struct bfq_group_data *bgd; - bgd = kzalloc(sizeof(*bgd), gfp); + bgd = kzalloc_obj(*bgd, gfp); if (!bgd) return NULL; diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c index b180ce583951..141c602d5e85 100644 --- a/block/bfq-iosched.c +++ b/block/bfq-iosched.c @@ -606,7 +606,7 @@ static bool bfqq_request_over_limit(struct bfq_data *bfqd, spin_unlock_irq(&bfqd->lock); if (entities != inline_entities) kfree(entities); - entities = kmalloc_array(depth, sizeof(*entities), GFP_NOIO); + entities = kmalloc_objs(*entities, depth, GFP_NOIO); if (!entities) return false; alloc_depth = depth; @@ -938,8 +938,8 @@ void bfq_weights_tree_add(struct bfq_queue *bfqq) } } - bfqq->weight_counter = kzalloc(sizeof(struct bfq_weight_counter), - GFP_ATOMIC); + bfqq->weight_counter = kzalloc_obj(struct bfq_weight_counter, + GFP_ATOMIC); /* * In the unlucky event of an allocation failure, we just diff --git a/block/bio-integrity.c b/block/bio-integrity.c index 09eeaf6e74b8..20f5d301d32d 100644 --- a/block/bio-integrity.c +++ b/block/bio-integrity.c @@ -97,7 +97,7 @@ struct bio_integrity_payload *bio_integrity_alloc(struct bio *bio, if (WARN_ON_ONCE(bio_has_crypt_ctx(bio))) return ERR_PTR(-EOPNOTSUPP); - bia = kmalloc(struct_size(bia, bvecs, nr_vecs), gfp_mask); + bia = kmalloc_flex(*bia, bvecs, nr_vecs, gfp_mask); if (unlikely(!bia)) return ERR_PTR(-ENOMEM); bio_integrity_init(bio, &bia->bip, bia->bvecs, nr_vecs); @@ -322,7 +322,7 @@ int bio_integrity_map_user(struct bio *bio, struct iov_iter *iter) if (nr_vecs > BIO_MAX_VECS) return -E2BIG; if (nr_vecs > UIO_FASTIOV) { - bvec = kcalloc(nr_vecs, sizeof(*bvec), GFP_KERNEL); + bvec = kzalloc_objs(*bvec, nr_vecs); if (!bvec) return -ENOMEM; pages = NULL; diff --git a/block/bio.c b/block/bio.c index b291b9aaeee1..d80d5d26804e 100644 --- a/block/bio.c +++ b/block/bio.c @@ -84,7 +84,7 @@ static DEFINE_XARRAY(bio_slabs); static struct bio_slab *create_bio_slab(unsigned int size) { - struct bio_slab *bslab = kzalloc(sizeof(*bslab), GFP_KERNEL); + struct bio_slab *bslab = kzalloc_obj(*bslab); if (!bslab) return NULL; @@ -1382,8 +1382,10 @@ static int bio_iov_iter_bounce_read(struct bio *bio, struct iov_iter *iter) ret = iov_iter_extract_bvecs(iter, bio->bi_io_vec + 1, len, &bio->bi_vcnt, bio->bi_max_vecs - 1, 0); if (ret <= 0) { - if (!bio->bi_vcnt) + if (!bio->bi_vcnt) { + folio_put(folio); return ret; + } break; } len -= ret; diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 3cffb68ba5d8..b70096497d38 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1417,7 +1417,7 @@ blkcg_css_alloc(struct cgroup_subsys_state *parent_css) if (!parent_css) { blkcg = &blkcg_root; } else { - blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL); + blkcg = kzalloc_obj(*blkcg); if (!blkcg) goto unlock; } diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c index a331b061dbf4..61f595410832 100644 --- a/block/blk-crypto-fallback.c +++ b/block/blk-crypto-fallback.c @@ -546,8 +546,7 @@ static int blk_crypto_fallback_init(void) goto out; /* Dynamic allocation is needed because of lockdep_register_key(). */ - blk_crypto_fallback_profile = - kzalloc(sizeof(*blk_crypto_fallback_profile), GFP_KERNEL); + blk_crypto_fallback_profile = kzalloc_obj(*blk_crypto_fallback_profile); if (!blk_crypto_fallback_profile) { err = -ENOMEM; goto fail_free_bioset; @@ -574,9 +573,8 @@ static int blk_crypto_fallback_init(void) if (!blk_crypto_wq) goto fail_destroy_profile; - blk_crypto_keyslots = kcalloc(blk_crypto_num_keyslots, - sizeof(blk_crypto_keyslots[0]), - GFP_KERNEL); + blk_crypto_keyslots = kzalloc_objs(blk_crypto_keyslots[0], + blk_crypto_num_keyslots); if (!blk_crypto_keyslots) goto fail_free_wq; diff --git a/block/blk-crypto-profile.c b/block/blk-crypto-profile.c index 81918f6e0cae..4ac74443687a 100644 --- a/block/blk-crypto-profile.c +++ b/block/blk-crypto-profile.c @@ -93,8 +93,7 @@ int blk_crypto_profile_init(struct blk_crypto_profile *profile, /* Initialize keyslot management data. */ - profile->slots = kvcalloc(num_slots, sizeof(profile->slots[0]), - GFP_KERNEL); + profile->slots = kvzalloc_objs(profile->slots[0], num_slots); if (!profile->slots) goto err_destroy; @@ -121,8 +120,7 @@ int blk_crypto_profile_init(struct blk_crypto_profile *profile, profile->log_slot_ht_size = ilog2(slot_hashtable_size); profile->slot_hashtable = - kvmalloc_array(slot_hashtable_size, - sizeof(profile->slot_hashtable[0]), GFP_KERNEL); + kvmalloc_objs(profile->slot_hashtable[0], slot_hashtable_size); if (!profile->slot_hashtable) goto err_destroy; for (i = 0; i < slot_hashtable_size; i++) diff --git a/block/blk-crypto-sysfs.c b/block/blk-crypto-sysfs.c index e832f403f200..ea7a0b85a46f 100644 --- a/block/blk-crypto-sysfs.c +++ b/block/blk-crypto-sysfs.c @@ -170,7 +170,7 @@ int blk_crypto_sysfs_register(struct gendisk *disk) if (!q->crypto_profile) return 0; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return -ENOMEM; obj->profile = q->crypto_profile; diff --git a/block/blk-iocost.c b/block/blk-iocost.c index ef543d163d46..d145db61e5c3 100644 --- a/block/blk-iocost.c +++ b/block/blk-iocost.c @@ -2882,7 +2882,7 @@ static int blk_iocost_init(struct gendisk *disk) struct ioc *ioc; int i, cpu, ret; - ioc = kzalloc(sizeof(*ioc), GFP_KERNEL); + ioc = kzalloc_obj(*ioc); if (!ioc) return -ENOMEM; @@ -2946,7 +2946,7 @@ static struct blkcg_policy_data *ioc_cpd_alloc(gfp_t gfp) { struct ioc_cgrp *iocc; - iocc = kzalloc(sizeof(struct ioc_cgrp), gfp); + iocc = kzalloc_obj(struct ioc_cgrp, gfp); if (!iocc) return NULL; diff --git a/block/blk-iolatency.c b/block/blk-iolatency.c index f7434278cd29..53e8dd2dfa8a 100644 --- a/block/blk-iolatency.c +++ b/block/blk-iolatency.c @@ -760,7 +760,7 @@ static int blk_iolatency_init(struct gendisk *disk) struct blk_iolatency *blkiolat; int ret; - blkiolat = kzalloc(sizeof(*blkiolat), GFP_KERNEL); + blkiolat = kzalloc_obj(*blkiolat); if (!blkiolat) return -ENOMEM; diff --git a/block/blk-ioprio.c b/block/blk-ioprio.c index 13659dc15c3f..8fa8bca35062 100644 --- a/block/blk-ioprio.c +++ b/block/blk-ioprio.c @@ -99,7 +99,7 @@ static struct blkcg_policy_data *ioprio_alloc_cpd(gfp_t gfp) { struct ioprio_blkcg *blkcg; - blkcg = kzalloc(sizeof(*blkcg), gfp); + blkcg = kzalloc_obj(*blkcg, gfp); if (!blkcg) return NULL; blkcg->prio_policy = POLICY_NO_CHANGE; diff --git a/block/blk-lib.c b/block/blk-lib.c index 0be3acdc3eb5..3213afc7f0d5 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -60,7 +60,7 @@ struct bio *blk_alloc_discard_bio(struct block_device *bdev, return bio; } -int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, +void __blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, struct bio **biop) { struct bio *bio; @@ -68,7 +68,6 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, while ((bio = blk_alloc_discard_bio(bdev, §or, &nr_sects, gfp_mask))) *biop = bio_chain_and_submit(*biop, bio); - return 0; } EXPORT_SYMBOL(__blkdev_issue_discard); diff --git a/block/blk-map.c b/block/blk-map.c index 4533094d9458..768549f19f97 100644 --- a/block/blk-map.c +++ b/block/blk-map.c @@ -26,7 +26,7 @@ static struct bio_map_data *bio_alloc_map_data(struct iov_iter *data, if (data->nr_segs > UIO_MAXIOV) return NULL; - bmd = kmalloc(struct_size(bmd, iov, data->nr_segs), gfp_mask); + bmd = kmalloc_flex(*bmd, iov, data->nr_segs, gfp_mask); if (!bmd) return NULL; bmd->iter = *data; @@ -398,8 +398,7 @@ static struct bio *bio_copy_kern(struct request *rq, void *data, unsigned int le if (op_is_write(op)) memcpy(page_address(page), p, bytes); - if (bio_add_page(bio, page, bytes, 0) < bytes) - break; + __bio_add_page(bio, page, bytes, 0); len -= bytes; p += bytes; diff --git a/block/blk-mq-debugfs.c b/block/blk-mq-debugfs.c index faeaa1fc86a7..28167c9baa55 100644 --- a/block/blk-mq-debugfs.c +++ b/block/blk-mq-debugfs.c @@ -613,11 +613,6 @@ static void debugfs_create_files(struct request_queue *q, struct dentry *parent, const struct blk_mq_debugfs_attr *attr) { lockdep_assert_held(&q->debugfs_mutex); - /* - * Creating new debugfs entries with queue freezed has the risk of - * deadlock. - */ - WARN_ON_ONCE(q->mq_freeze_depth != 0); /* * debugfs_mutex should not be nested under other locks that can be * grabbed while queue is frozen. @@ -693,12 +688,13 @@ void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx) void blk_mq_debugfs_register_hctxs(struct request_queue *q) { struct blk_mq_hw_ctx *hctx; + unsigned int memflags; unsigned long i; - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); queue_for_each_hw_ctx(q, hctx, i) blk_mq_debugfs_register_hctx(q, hctx); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); } void blk_mq_debugfs_unregister_hctxs(struct request_queue *q) diff --git a/block/blk-mq-dma.c b/block/blk-mq-dma.c index 3c87779cdc19..bfdb9ed70741 100644 --- a/block/blk-mq-dma.c +++ b/block/blk-mq-dma.c @@ -121,17 +121,20 @@ static bool blk_rq_dma_map_iova(struct request *req, struct device *dma_dev, error = dma_iova_link(dma_dev, state, vec->paddr, mapped, vec->len, dir, attrs); if (error) - break; + goto out_unlink; mapped += vec->len; } while (blk_map_iter_next(req, &iter->iter, vec)); error = dma_iova_sync(dma_dev, state, 0, mapped); - if (error) { - iter->status = errno_to_blk_status(error); - return false; - } + if (error) + goto out_unlink; return true; + +out_unlink: + dma_iova_destroy(dma_dev, state, mapped, dir, attrs); + iter->status = errno_to_blk_status(error); + return false; } static inline void blk_rq_map_iter_init(struct request *rq, diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index e26898128a7e..0a00f5a76f5a 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c @@ -390,13 +390,14 @@ static void blk_mq_sched_tags_teardown(struct request_queue *q, unsigned int fla void blk_mq_sched_reg_debugfs(struct request_queue *q) { struct blk_mq_hw_ctx *hctx; + unsigned int memflags; unsigned long i; - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); blk_mq_debugfs_register_sched(q); queue_for_each_hw_ctx(q, hctx, i) blk_mq_debugfs_register_sched_hctx(q, hctx); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); } void blk_mq_sched_unreg_debugfs(struct request_queue *q) @@ -404,11 +405,11 @@ void blk_mq_sched_unreg_debugfs(struct request_queue *q) struct blk_mq_hw_ctx *hctx; unsigned long i; - mutex_lock(&q->debugfs_mutex); + blk_debugfs_lock_nomemsave(q); queue_for_each_hw_ctx(q, hctx, i) blk_mq_debugfs_unregister_sched_hctx(hctx); blk_mq_debugfs_unregister_sched(q); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock_nomemrestore(q); } void blk_mq_free_sched_tags(struct elevator_tags *et, @@ -488,7 +489,7 @@ int blk_mq_alloc_sched_ctx_batch(struct xarray *elv_tbl, lockdep_assert_held_write(&set->update_nr_hwq_lock); list_for_each_entry(q, &set->tag_list, tag_set_list) { - ctx = kzalloc(sizeof(struct elv_change_ctx), GFP_KERNEL); + ctx = kzalloc_obj(struct elv_change_ctx); if (!ctx) return -ENOMEM; @@ -513,7 +514,7 @@ struct elevator_tags *blk_mq_alloc_sched_tags(struct blk_mq_tag_set *set, else nr_tags = nr_hw_queues; - et = kmalloc(struct_size(et, tags, nr_tags), gfp); + et = kmalloc_flex(*et, tags, nr_tags, gfp); if (!et) return NULL; diff --git a/block/blk-mq.c b/block/blk-mq.c index d5602ff62c7c..3da2215b2912 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -4362,7 +4362,7 @@ static int blk_mq_alloc_ctxs(struct request_queue *q) struct blk_mq_ctxs *ctxs; int cpu; - ctxs = kzalloc(sizeof(*ctxs), GFP_KERNEL); + ctxs = kzalloc_obj(*ctxs); if (!ctxs) return -ENOMEM; @@ -4793,38 +4793,45 @@ static void blk_mq_update_queue_map(struct blk_mq_tag_set *set) } } -static int blk_mq_realloc_tag_set_tags(struct blk_mq_tag_set *set, - int new_nr_hw_queues) +static struct blk_mq_tags **blk_mq_prealloc_tag_set_tags( + struct blk_mq_tag_set *set, + int new_nr_hw_queues) { struct blk_mq_tags **new_tags; int i; if (set->nr_hw_queues >= new_nr_hw_queues) - goto done; + return NULL; new_tags = kcalloc_node(new_nr_hw_queues, sizeof(struct blk_mq_tags *), GFP_KERNEL, set->numa_node); if (!new_tags) - return -ENOMEM; + return ERR_PTR(-ENOMEM); if (set->tags) memcpy(new_tags, set->tags, set->nr_hw_queues * sizeof(*set->tags)); - kfree(set->tags); - set->tags = new_tags; for (i = set->nr_hw_queues; i < new_nr_hw_queues; i++) { - if (!__blk_mq_alloc_map_and_rqs(set, i)) { - while (--i >= set->nr_hw_queues) - __blk_mq_free_map_and_rqs(set, i); - return -ENOMEM; + if (blk_mq_is_shared_tags(set->flags)) { + new_tags[i] = set->shared_tags; + } else { + new_tags[i] = blk_mq_alloc_map_and_rqs(set, i, + set->queue_depth); + if (!new_tags[i]) + goto out_unwind; } cond_resched(); } -done: - set->nr_hw_queues = new_nr_hw_queues; - return 0; + return new_tags; +out_unwind: + while (--i >= set->nr_hw_queues) { + if (!blk_mq_is_shared_tags(set->flags)) + blk_mq_free_map_and_rqs(set, new_tags[i], i); + } + kfree(new_tags); + return ERR_PTR(-ENOMEM); } /* @@ -4879,7 +4886,7 @@ int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set) set->nr_hw_queues = nr_cpu_ids; if (set->flags & BLK_MQ_F_BLOCKING) { - set->srcu = kmalloc(sizeof(*set->srcu), GFP_KERNEL); + set->srcu = kmalloc_obj(*set->srcu); if (!set->srcu) return -ENOMEM; ret = init_srcu_struct(set->srcu); @@ -5113,6 +5120,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, unsigned int memflags; int i; struct xarray elv_tbl; + struct blk_mq_tags **new_tags; bool queues_frozen = false; lockdep_assert_held(&set->tag_list_lock); @@ -5147,11 +5155,18 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set, if (blk_mq_elv_switch_none(q, &elv_tbl)) goto switch_back; + new_tags = blk_mq_prealloc_tag_set_tags(set, nr_hw_queues); + if (IS_ERR(new_tags)) + goto switch_back; + list_for_each_entry(q, &set->tag_list, tag_set_list) blk_mq_freeze_queue_nomemsave(q); queues_frozen = true; - if (blk_mq_realloc_tag_set_tags(set, nr_hw_queues) < 0) - goto switch_back; + if (new_tags) { + kfree(set->tags); + set->tags = new_tags; + } + set->nr_hw_queues = nr_hw_queues; fallback: blk_mq_update_queue_map(set); diff --git a/block/blk-stat.c b/block/blk-stat.c index 682a8ddb1173..de126e1ea5ac 100644 --- a/block/blk-stat.c +++ b/block/blk-stat.c @@ -103,12 +103,11 @@ blk_stat_alloc_callback(void (*timer_fn)(struct blk_stat_callback *), { struct blk_stat_callback *cb; - cb = kmalloc(sizeof(*cb), GFP_KERNEL); + cb = kmalloc_obj(*cb); if (!cb) return NULL; - cb->stat = kmalloc_array(buckets, sizeof(struct blk_rq_stat), - GFP_KERNEL); + cb->stat = kmalloc_objs(struct blk_rq_stat, buckets); if (!cb->stat) { kfree(cb); return NULL; @@ -207,7 +206,7 @@ struct blk_queue_stats *blk_alloc_queue_stats(void) { struct blk_queue_stats *stats; - stats = kmalloc(sizeof(*stats), GFP_KERNEL); + stats = kmalloc_obj(*stats); if (!stats) return NULL; diff --git a/block/blk-stat.h b/block/blk-stat.h index 9e05bf18d1be..cc5b66e7ee60 100644 --- a/block/blk-stat.h +++ b/block/blk-stat.h @@ -17,7 +17,7 @@ * timer fires, @cpu_stat is flushed to @stat and @timer_fn is invoked. */ struct blk_stat_callback { - /* + /** * @list: RCU list of callbacks for a &struct request_queue. */ struct list_head list; @@ -50,7 +50,7 @@ struct blk_stat_callback { struct blk_rq_stat *stat; /** - * @fn: Callback function. + * @timer_fn: Callback function. */ void (*timer_fn)(struct blk_stat_callback *); @@ -59,6 +59,9 @@ struct blk_stat_callback { */ void *data; + /** + * @rcu: rcu list head + */ struct rcu_head rcu; }; @@ -126,6 +129,8 @@ void blk_stat_free_callback(struct blk_stat_callback *cb); * blk_stat_is_active() - Check if a block statistics callback is currently * gathering statistics. * @cb: The callback. + * + * Returns: %true iff the callback is active. */ static inline bool blk_stat_is_active(struct blk_stat_callback *cb) { diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 003aa684e854..55a1bbfef7d4 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c @@ -78,8 +78,14 @@ queue_requests_store(struct gendisk *disk, const char *page, size_t count) /* * Serialize updating nr_requests with concurrent queue_requests_store() * and switching elevator. + * + * Use trylock to avoid circular lock dependency with kernfs active + * reference during concurrent disk deletion: + * update_nr_hwq_lock -> kn->active (via del_gendisk -> kobject_del) + * kn->active -> update_nr_hwq_lock (via this sysfs write path) */ - down_write(&set->update_nr_hwq_lock); + if (!down_write_trylock(&set->update_nr_hwq_lock)) + return -EBUSY; if (nr == q->nr_requests) goto unlock; @@ -892,13 +898,13 @@ static void blk_debugfs_remove(struct gendisk *disk) { struct request_queue *q = disk->queue; - mutex_lock(&q->debugfs_mutex); + blk_debugfs_lock_nomemsave(q); blk_trace_shutdown(q); debugfs_remove_recursive(q->debugfs_dir); q->debugfs_dir = NULL; q->sched_debugfs_dir = NULL; q->rqos_debugfs_dir = NULL; - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock_nomemrestore(q); } /** @@ -908,6 +914,7 @@ static void blk_debugfs_remove(struct gendisk *disk) int blk_register_queue(struct gendisk *disk) { struct request_queue *q = disk->queue; + unsigned int memflags; int ret; ret = kobject_add(&disk->queue_kobj, &disk_to_dev(disk)->kobj, "queue"); @@ -921,11 +928,11 @@ int blk_register_queue(struct gendisk *disk) } mutex_lock(&q->sysfs_lock); - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); q->debugfs_dir = debugfs_create_dir(disk->disk_name, blk_debugfs_root); if (queue_is_mq(q)) blk_mq_debugfs_register(q); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); ret = disk_register_independent_access_ranges(disk); if (ret) diff --git a/block/blk-wbt.c b/block/blk-wbt.c index 1415f2bf8611..33006edfccd4 100644 --- a/block/blk-wbt.c +++ b/block/blk-wbt.c @@ -713,7 +713,7 @@ static int wbt_data_dir(const struct request *rq) static struct rq_wb *wbt_alloc(void) { - struct rq_wb *rwb = kzalloc(sizeof(*rwb), GFP_KERNEL); + struct rq_wb *rwb = kzalloc_obj(*rwb); if (!rwb) return NULL; @@ -776,6 +776,7 @@ void wbt_init_enable_default(struct gendisk *disk) { struct request_queue *q = disk->queue; struct rq_wb *rwb; + unsigned int memflags; if (!__wbt_enable_default(disk)) return; @@ -789,9 +790,9 @@ void wbt_init_enable_default(struct gendisk *disk) return; } - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); blk_mq_debugfs_register_rq_qos(q); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); } static u64 wbt_default_latency_nsec(struct request_queue *q) @@ -1015,9 +1016,10 @@ int wbt_set_lat(struct gendisk *disk, s64 val) blk_mq_unquiesce_queue(q); out: blk_mq_unfreeze_queue(q, memflags); - mutex_lock(&q->debugfs_mutex); + + memflags = blk_debugfs_lock(q); blk_mq_debugfs_register_rq_qos(q); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); return ret; } diff --git a/block/blk-zoned.c b/block/blk-zoned.c index 846b8844f04a..9d1dd6ccfad7 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -1804,8 +1804,8 @@ static int disk_alloc_zone_resources(struct gendisk *disk, min(ilog2(pool_size) + 1, BLK_ZONE_WPLUG_MAX_HASH_BITS); disk->zone_wplugs_hash = - kcalloc(disk_zone_wplugs_hash_size(disk), - sizeof(struct hlist_head), GFP_KERNEL); + kzalloc_objs(struct hlist_head, + disk_zone_wplugs_hash_size(disk)); if (!disk->zone_wplugs_hash) return -ENOMEM; diff --git a/block/blk.h b/block/blk.h index a6b1de509733..f6053e9dd2aa 100644 --- a/block/blk.h +++ b/block/blk.h @@ -729,4 +729,35 @@ static inline void blk_unfreeze_release_lock(struct request_queue *q) } #endif +/* + * debugfs directory and file creation can trigger fs reclaim, which can enter + * back into the block layer request_queue. This can cause deadlock if the + * queue is frozen. Use NOIO context together with debugfs_mutex to prevent fs + * reclaim from triggering block I/O. + */ +static inline void blk_debugfs_lock_nomemsave(struct request_queue *q) +{ + mutex_lock(&q->debugfs_mutex); +} + +static inline void blk_debugfs_unlock_nomemrestore(struct request_queue *q) +{ + mutex_unlock(&q->debugfs_mutex); +} + +static inline unsigned int __must_check blk_debugfs_lock(struct request_queue *q) +{ + unsigned int memflags = memalloc_noio_save(); + + blk_debugfs_lock_nomemsave(q); + return memflags; +} + +static inline void blk_debugfs_unlock(struct request_queue *q, + unsigned int memflags) +{ + blk_debugfs_unlock_nomemrestore(q); + memalloc_noio_restore(memflags); +} + #endif /* BLK_INTERNAL_H */ diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 9ceb5d0832f5..20cd0ef3c394 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -368,7 +368,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, struct request_queue *q; int ret = -ENOMEM; - bset = kzalloc(sizeof(*bset), GFP_KERNEL); + bset = kzalloc_obj(*bset); if (!bset) return ERR_PTR(-ENOMEM); diff --git a/block/bsg.c b/block/bsg.c index 72157a59b788..e0af6206ed28 100644 --- a/block/bsg.c +++ b/block/bsg.c @@ -192,7 +192,7 @@ struct bsg_device *bsg_register_queue(struct request_queue *q, struct bsg_device *bd; int ret; - bd = kzalloc(sizeof(*bd), GFP_KERNEL); + bd = kzalloc_obj(*bd); if (!bd) return ERR_PTR(-ENOMEM); bd->max_queue = BSG_DEFAULT_CMDS; diff --git a/block/disk-events.c b/block/disk-events.c index 2f697224386a..9f9f9f8a2d6b 100644 --- a/block/disk-events.c +++ b/block/disk-events.c @@ -436,7 +436,7 @@ int disk_alloc_events(struct gendisk *disk) if (!disk->fops->check_events || !disk->events) return 0; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) { pr_warn("%s: failed to initialize events\n", disk->disk_name); return -ENOMEM; diff --git a/block/elevator.c b/block/elevator.c index ebe2a1fcf011..3bcd37c2aa34 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -807,7 +807,16 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf, elv_iosched_load_module(ctx.name); ctx.type = elevator_find_get(ctx.name); - down_read(&set->update_nr_hwq_lock); + /* + * Use trylock to avoid circular lock dependency with kernfs active + * reference during concurrent disk deletion: + * update_nr_hwq_lock -> kn->active (via del_gendisk -> kobject_del) + * kn->active -> update_nr_hwq_lock (via this sysfs write path) + */ + if (!down_read_trylock(&set->update_nr_hwq_lock)) { + ret = -EBUSY; + goto out; + } if (!blk_queue_no_elv_switch(q)) { ret = elevator_change(q, &ctx); if (!ret) @@ -817,6 +826,7 @@ ssize_t elv_iosched_store(struct gendisk *disk, const char *buf, } up_read(&set->update_nr_hwq_lock); +out: if (ctx.type) elevator_put(ctx.type); return ret; diff --git a/block/fops.c b/block/fops.c index 4d32785b31d9..bb6642b45937 100644 --- a/block/fops.c +++ b/block/fops.c @@ -65,8 +65,7 @@ static ssize_t __blkdev_direct_IO_simple(struct kiocb *iocb, if (nr_pages <= DIO_INLINE_BIO_VECS) vecs = inline_vecs; else { - vecs = kmalloc_array(nr_pages, sizeof(struct bio_vec), - GFP_KERNEL); + vecs = kmalloc_objs(struct bio_vec, nr_pages); if (!vecs) return -ENOMEM; } diff --git a/block/genhd.c b/block/genhd.c index 69c75117ba2c..7d6854fd28e9 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -264,7 +264,7 @@ int __register_blkdev(unsigned int major, const char *name, goto out; } - p = kmalloc(sizeof(struct blk_major_name), GFP_KERNEL); + p = kmalloc_obj(struct blk_major_name); if (p == NULL) { ret = -ENOMEM; goto out; @@ -914,7 +914,7 @@ static void *disk_seqf_start(struct seq_file *seqf, loff_t *pos) struct class_dev_iter *iter; struct device *dev; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return ERR_PTR(-ENOMEM); diff --git a/block/holder.c b/block/holder.c index 791091a7eac2..267beb3dc7a7 100644 --- a/block/holder.c +++ b/block/holder.c @@ -92,7 +92,7 @@ int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) goto out_unlock; } - holder = kzalloc(sizeof(*holder), GFP_KERNEL); + holder = kzalloc_obj(*holder); if (!holder) { ret = -ENOMEM; goto out_unlock; diff --git a/block/ioctl.c b/block/ioctl.c index fd48f82f9f03..0b04661ac809 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -318,7 +318,13 @@ int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode, EXPORT_SYMBOL(blkdev_compat_ptr_ioctl); #endif -static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode) +enum pr_direction { + PR_IN, /* read from device */ + PR_OUT, /* write to device */ +}; + +static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode, + enum pr_direction dir) { /* no sense to make reservations for partitions */ if (bdev_is_partition(bdev)) @@ -326,11 +332,17 @@ static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode) if (capable(CAP_SYS_ADMIN)) return true; + /* - * Only allow unprivileged reservations if the file descriptor is open - * for writing. + * Only allow unprivileged reservation _out_ commands if the file + * descriptor is open for writing. Allow reservation _in_ commands if + * the file descriptor is open for reading since they do not modify the + * device. */ - return mode & BLK_OPEN_WRITE; + if (dir == PR_IN) + return mode & BLK_OPEN_READ; + else + return mode & BLK_OPEN_WRITE; } static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode, @@ -339,7 +351,7 @@ static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode, const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; struct pr_registration reg; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_register) return -EOPNOTSUPP; @@ -357,7 +369,7 @@ static int blkdev_pr_reserve(struct block_device *bdev, blk_mode_t mode, const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; struct pr_reservation rsv; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_reserve) return -EOPNOTSUPP; @@ -375,7 +387,7 @@ static int blkdev_pr_release(struct block_device *bdev, blk_mode_t mode, const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; struct pr_reservation rsv; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_release) return -EOPNOTSUPP; @@ -393,7 +405,7 @@ static int blkdev_pr_preempt(struct block_device *bdev, blk_mode_t mode, const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; struct pr_preempt p; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_preempt) return -EOPNOTSUPP; @@ -411,7 +423,7 @@ static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode, const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; struct pr_clear c; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_OUT)) return -EPERM; if (!ops || !ops->pr_clear) return -EOPNOTSUPP; @@ -434,7 +446,7 @@ static int blkdev_pr_read_keys(struct block_device *bdev, blk_mode_t mode, size_t keys_copy_len; int ret; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_IN)) return -EPERM; if (!ops || !ops->pr_read_keys) return -EOPNOTSUPP; @@ -486,7 +498,7 @@ static int blkdev_pr_read_reservation(struct block_device *bdev, struct pr_read_reservation out = {}; int ret; - if (!blkdev_pr_allowed(bdev, mode)) + if (!blkdev_pr_allowed(bdev, mode, PR_IN)) return -EPERM; if (!ops || !ops->pr_read_reservation) return -EOPNOTSUPP; diff --git a/block/partitions/aix.c b/block/partitions/aix.c index 85f4b967565e..a886cefbefbb 100644 --- a/block/partitions/aix.c +++ b/block/partitions/aix.c @@ -199,7 +199,7 @@ int aix_partition(struct parsed_partitions *state) numlvs = be16_to_cpu(p->numlvs); put_dev_sector(sect); } - lvip = kcalloc(state->limit, sizeof(struct lv_info), GFP_KERNEL); + lvip = kzalloc_objs(struct lv_info, state->limit); if (!lvip) return 0; if (numlvs && (d = read_part_sector(state, vgda_sector + 1, §))) { diff --git a/block/partitions/cmdline.c b/block/partitions/cmdline.c index da3e719d8e51..a2b1870c3fd4 100644 --- a/block/partitions/cmdline.c +++ b/block/partitions/cmdline.c @@ -46,7 +46,7 @@ static int parse_subpart(struct cmdline_subpart **subpart, char *partdef) *subpart = NULL; - new_subpart = kzalloc(sizeof(struct cmdline_subpart), GFP_KERNEL); + new_subpart = kzalloc_obj(struct cmdline_subpart); if (!new_subpart) return -ENOMEM; @@ -122,7 +122,7 @@ static int parse_parts(struct cmdline_parts **parts, char *bdevdef) *parts = NULL; - newparts = kzalloc(sizeof(struct cmdline_parts), GFP_KERNEL); + newparts = kzalloc_obj(struct cmdline_parts); if (!newparts) return -ENOMEM; diff --git a/block/partitions/core.c b/block/partitions/core.c index 079057ab535a..740228750aaf 100644 --- a/block/partitions/core.c +++ b/block/partitions/core.c @@ -94,7 +94,7 @@ static struct parsed_partitions *allocate_partitions(struct gendisk *hd) struct parsed_partitions *state; int nr = DISK_MAX_PARTS; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/block/partitions/efi.c b/block/partitions/efi.c index 638261e9f2fb..75474fb3848e 100644 --- a/block/partitions/efi.c +++ b/block/partitions/efi.c @@ -595,7 +595,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt, lastlba = last_lba(state->disk); if (!force_gpt) { /* This will be added to the EFI Spec. per Intel after v1.02. */ - legacymbr = kzalloc(sizeof(*legacymbr), GFP_KERNEL); + legacymbr = kzalloc_obj(*legacymbr); if (!legacymbr) goto fail; diff --git a/block/partitions/ibm.c b/block/partitions/ibm.c index 631291fbb356..9311ad5fb95d 100644 --- a/block/partitions/ibm.c +++ b/block/partitions/ibm.c @@ -347,13 +347,13 @@ int ibm_partition(struct parsed_partitions *state) nr_sectors = bdev_nr_sectors(bdev); if (nr_sectors == 0) goto out_symbol; - info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); + info = kmalloc_obj(dasd_information2_t); if (info == NULL) goto out_symbol; - geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); + geo = kmalloc_obj(struct hd_geometry); if (geo == NULL) goto out_nogeo; - label = kmalloc(sizeof(union label_t), GFP_KERNEL); + label = kmalloc_obj(union label_t); if (label == NULL) goto out_nolab; /* set start if not filled by getgeo function e.g. virtblk */ diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c index 2bd42fedb907..776b4ad95091 100644 --- a/block/partitions/ldm.c +++ b/block/partitions/ldm.c @@ -273,8 +273,8 @@ static bool ldm_validate_privheads(struct parsed_partitions *state, BUG_ON (!state || !ph1); - ph[1] = kmalloc (sizeof (*ph[1]), GFP_KERNEL); - ph[2] = kmalloc (sizeof (*ph[2]), GFP_KERNEL); + ph[1] = kmalloc_obj(*ph[1]); + ph[2] = kmalloc_obj(*ph[2]); if (!ph[1] || !ph[2]) { ldm_crit ("Out of memory."); goto out; @@ -362,7 +362,7 @@ static bool ldm_validate_tocblocks(struct parsed_partitions *state, BUG_ON(!state || !ldb); ph = &ldb->ph; tb[0] = &ldb->toc; - tb[1] = kmalloc_array(3, sizeof(*tb[1]), GFP_KERNEL); + tb[1] = kmalloc_objs(*tb[1], 3); if (!tb[1]) { ldm_crit("Out of memory."); goto err; @@ -1158,7 +1158,7 @@ static bool ldm_ldmdb_add (u8 *data, int len, struct ldmdb *ldb) BUG_ON (!data || !ldb); - vb = kmalloc (sizeof (*vb), GFP_KERNEL); + vb = kmalloc_obj(*vb); if (!vb) { ldm_crit ("Out of memory."); return false; @@ -1438,7 +1438,7 @@ int ldm_partition(struct parsed_partitions *state) if (!ldm_validate_partition_table(state)) return 0; - ldb = kmalloc (sizeof (*ldb), GFP_KERNEL); + ldb = kmalloc_obj(*ldb); if (!ldb) { ldm_crit ("Out of memory."); goto out; diff --git a/block/sed-opal.c b/block/sed-opal.c index 23a19c92d791..3ded1ca723ca 100644 --- a/block/sed-opal.c +++ b/block/sed-opal.c @@ -2512,7 +2512,7 @@ struct opal_dev *init_opal_dev(void *data, sec_send_recv *send_recv) { struct opal_dev *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc_obj(*dev); if (!dev) return NULL; @@ -2719,7 +2719,7 @@ static int opal_save(struct opal_dev *dev, struct opal_lock_unlock *lk_unlk) { struct opal_suspend_data *suspend; - suspend = kzalloc(sizeof(*suspend), GFP_KERNEL); + suspend = kzalloc_obj(*suspend); if (!suspend) return -ENOMEM; diff --git a/certs/blacklist.c b/certs/blacklist.c index 11fc858b2921..fa561c12eabf 100644 --- a/certs/blacklist.c +++ b/certs/blacklist.c @@ -328,7 +328,7 @@ static int __init blacklist_init(void) if (register_key_type(&key_type_blacklist) < 0) panic("Can't allocate system blacklist key type\n"); - restriction = kzalloc(sizeof(*restriction), GFP_KERNEL); + restriction = kzalloc_obj(*restriction); if (!restriction) panic("Can't allocate blacklist keyring restriction\n"); restriction->check = restrict_link_for_blacklist; diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 9de610bf1f4b..e0761436ec7f 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -140,7 +140,7 @@ static __init struct key_restriction *get_builtin_and_secondary_restriction(void { struct key_restriction *restriction; - restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + restriction = kzalloc_obj(struct key_restriction); if (!restriction) panic("Can't allocate secondary trusted keyring restriction\n"); diff --git a/crypto/Kconfig b/crypto/Kconfig index e2b4106ac961..b4bb85e8e226 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -876,8 +876,6 @@ config CRYPTO_BLAKE2B - blake2b-384 - blake2b-512 - Used by the btrfs filesystem. - See https://blake2.net for further information. config CRYPTO_CMAC @@ -965,7 +963,6 @@ config CRYPTO_SHA256 10118-3), including HMAC support. This is required for IPsec AH (XFRM_AH) and IPsec ESP (XFRM_ESP). - Used by the btrfs filesystem, Ceph, NFS, and SMB. config CRYPTO_SHA512 tristate "SHA-384 and SHA-512" @@ -1039,8 +1036,6 @@ config CRYPTO_XXHASH Extremely fast, working at speeds close to RAM limits. - Used by the btrfs filesystem. - endmenu menu "CRCs (cyclic redundancy checks)" @@ -1058,8 +1053,6 @@ config CRYPTO_CRC32C on Communications, Vol. 41, No. 6, June 1993, selected for use with iSCSI. - Used by btrfs, ext4, jbd2, NVMeoF/TCP, and iSCSI. - config CRYPTO_CRC32 tristate "CRC32" select CRYPTO_HASH @@ -1067,8 +1060,6 @@ config CRYPTO_CRC32 help CRC32 CRC algorithm (IEEE 802.3) - Used by RoCEv2 and f2fs. - endmenu menu "Compression" diff --git a/crypto/af_alg.c b/crypto/af_alg.c index e468714f539d..0bb609fbec7d 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -70,7 +70,7 @@ int af_alg_register_type(const struct af_alg_type *type) goto unlock; } - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmalloc_obj(*node); err = -ENOMEM; if (!node) goto unlock; diff --git a/crypto/algboss.c b/crypto/algboss.c index 846f586889ee..8b936cae6608 100644 --- a/crypto/algboss.c +++ b/crypto/algboss.c @@ -84,7 +84,7 @@ static int cryptomgr_schedule_probe(struct crypto_larval *larval) if (!try_module_get(THIS_MODULE)) goto err; - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) goto err_put_module; @@ -195,7 +195,7 @@ static int cryptomgr_schedule_test(struct crypto_alg *alg) if (!try_module_get(THIS_MODULE)) goto err; - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) goto err_put_module; diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index 1a86e40c8372..a9fb492e929a 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -202,7 +202,7 @@ static void *rng_bind(const char *name, u32 type, u32 mask) struct rng_parent_ctx *pctx; struct crypto_rng *rng; - pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); + pctx = kzalloc_obj(*pctx); if (!pctx) return ERR_PTR(-ENOMEM); diff --git a/crypto/api.c b/crypto/api.c index 05629644a688..74e17d5049c9 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -105,7 +105,7 @@ struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask) { struct crypto_larval *larval; - larval = kzalloc(sizeof(*larval), GFP_KERNEL); + larval = kzalloc_obj(*larval); if (!larval) return ERR_PTR(-ENOMEM); diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 1dae2232fe9a..e50bd9b3e27b 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig @@ -27,6 +27,7 @@ config X509_CERTIFICATE_PARSER tristate "X.509 certificate parser" depends on ASYMMETRIC_PUBLIC_KEY_SUBTYPE select ASN1 + select CRYPTO_LIB_SHA256 select OID_REGISTRY help This option provides support for parsing X.509 format blobs for key diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index 1f1d92547dfc..16a7ae16593c 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -486,7 +486,7 @@ static struct key_restriction *asymmetric_restriction_alloc( struct key *key) { struct key_restriction *keyres = - kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + kzalloc_obj(struct key_restriction); if (!keyres) return ERR_PTR(-ENOMEM); diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index db1c90ca6fc1..6e3ffdac83ac 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c @@ -133,17 +133,16 @@ struct pkcs7_message *pkcs7_parse_message(const void *data, size_t datalen) struct pkcs7_message *msg = ERR_PTR(-ENOMEM); int ret; - ctx = kzalloc(sizeof(struct pkcs7_parse_context), GFP_KERNEL); + ctx = kzalloc_obj(struct pkcs7_parse_context); if (!ctx) goto out_no_ctx; - ctx->msg = kzalloc(sizeof(struct pkcs7_message), GFP_KERNEL); + ctx->msg = kzalloc_obj(struct pkcs7_message); if (!ctx->msg) goto out_no_msg; - ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); + ctx->sinfo = kzalloc_obj(struct pkcs7_signed_info); if (!ctx->sinfo) goto out_no_sinfo; - ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature), - GFP_KERNEL); + ctx->sinfo->sig = kzalloc_obj(struct public_key_signature); if (!ctx->sinfo->sig) goto out_no_sig; @@ -729,11 +728,10 @@ int pkcs7_note_signed_info(void *context, size_t hdrlen, sinfo->index = ++ctx->sinfo_index; *ctx->ppsinfo = sinfo; ctx->ppsinfo = &sinfo->next; - ctx->sinfo = kzalloc(sizeof(struct pkcs7_signed_info), GFP_KERNEL); + ctx->sinfo = kzalloc_obj(struct pkcs7_signed_info); if (!ctx->sinfo) return -ENOMEM; - ctx->sinfo->sig = kzalloc(sizeof(struct public_key_signature), - GFP_KERNEL); + ctx->sinfo->sig = kzalloc_obj(struct public_key_signature); if (!ctx->sinfo->sig) return -ENOMEM; return 0; diff --git a/crypto/asymmetric_keys/pkcs8_parser.c b/crypto/asymmetric_keys/pkcs8_parser.c index 105dcce27f71..9dd1c181789a 100644 --- a/crypto/asymmetric_keys/pkcs8_parser.c +++ b/crypto/asymmetric_keys/pkcs8_parser.c @@ -103,7 +103,7 @@ static struct public_key *pkcs8_parse(const void *data, size_t datalen) memset(&ctx, 0, sizeof(ctx)); ret = -ENOMEM; - ctx.pub = kzalloc(sizeof(struct public_key), GFP_KERNEL); + ctx.pub = kzalloc_obj(struct public_key); if (!ctx.pub) goto error; diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 2fe094f5caf3..37e4fb9da106 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -65,16 +65,16 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) struct asymmetric_key_id *kid; long ret; - cert = kzalloc(sizeof(struct x509_certificate), GFP_KERNEL); + cert = kzalloc_obj(struct x509_certificate); if (!cert) return ERR_PTR(-ENOMEM); - cert->pub = kzalloc(sizeof(struct public_key), GFP_KERNEL); + cert->pub = kzalloc_obj(struct public_key); if (!cert->pub) return ERR_PTR(-ENOMEM); - cert->sig = kzalloc(sizeof(struct public_key_signature), GFP_KERNEL); + cert->sig = kzalloc_obj(struct public_key_signature); if (!cert->sig) return ERR_PTR(-ENOMEM); - ctx = kzalloc(sizeof(struct x509_parse_context), GFP_KERNEL); + ctx = kzalloc_obj(struct x509_parse_context); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index b695e59fd9e4..25cf8ac7f257 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -210,7 +210,7 @@ static int x509_key_preparse(struct key_preparsed_payload *prep) p = bin2hex(p, q, srlen); *p = 0; - kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL); + kids = kmalloc_obj(struct asymmetric_key_ids); if (!kids) return -ENOMEM; kids->id[0] = cert->id; diff --git a/crypto/deflate.c b/crypto/deflate.c index a3e1fff55661..46fc7def8d4c 100644 --- a/crypto/deflate.c +++ b/crypto/deflate.c @@ -40,7 +40,7 @@ static void *deflate_alloc_stream(void) DEFLATE_DEF_MEMLEVEL)); struct deflate_stream *ctx; - ctx = kvmalloc(struct_size(ctx, workspace, size), GFP_KERNEL); + ctx = kvmalloc_flex(*ctx, workspace, size); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/crypto/drbg.c b/crypto/drbg.c index 5e7ed5f5c192..1ed209e5d5dd 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -1522,7 +1522,7 @@ static int drbg_init_sym_kernel(struct drbg_state *drbg) unsigned int alignmask; char ctr_name[CRYPTO_MAX_ALG_NAME]; - aeskey = kzalloc(sizeof(*aeskey), GFP_KERNEL); + aeskey = kzalloc_obj(*aeskey); if (!aeskey) return -ENOMEM; drbg->priv_data = aeskey; @@ -1761,7 +1761,7 @@ static inline int __init drbg_healthcheck_sanity(void) drbg_convert_tfm_core("drbg_nopr_hmac_sha512", &coreref, &pr); #endif - drbg = kzalloc(sizeof(struct drbg_state), GFP_KERNEL); + drbg = kzalloc_obj(struct drbg_state); if (!drbg) return -ENOMEM; diff --git a/crypto/ecc.c b/crypto/ecc.c index 2808b3d5f483..08150b14e17e 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -98,7 +98,7 @@ struct ecc_point *ecc_alloc_point(unsigned int ndigits) if (!ndigits) return NULL; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return NULL; diff --git a/crypto/gcm.c b/crypto/gcm.c index 97716482bed0..e1e878d37410 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -1098,7 +1098,7 @@ static int __init crypto_gcm_module_init(void) { int err; - gcm_zeroes = kzalloc(sizeof(*gcm_zeroes), GFP_KERNEL); + gcm_zeroes = kzalloc_obj(*gcm_zeroes); if (!gcm_zeroes) return -ENOMEM; diff --git a/crypto/simd.c b/crypto/simd.c index 2a7549e280ca..f71c4a334c7d 100644 --- a/crypto/simd.c +++ b/crypto/simd.c @@ -145,7 +145,7 @@ struct simd_skcipher_alg *simd_skcipher_create_compat(struct skcipher_alg *ialg, struct skcipher_alg *alg; int err; - salg = kzalloc(sizeof(*salg), GFP_KERNEL); + salg = kzalloc_obj(*salg); if (!salg) { salg = ERR_PTR(-ENOMEM); goto out; @@ -370,7 +370,7 @@ static struct simd_aead_alg *simd_aead_create_compat(struct aead_alg *ialg, struct aead_alg *alg; int err; - salg = kzalloc(sizeof(*salg), GFP_KERNEL); + salg = kzalloc_obj(*salg); if (!salg) { salg = ERR_PTR(-ENOMEM); goto out; diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 62fef100e599..aded37546137 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -180,7 +180,7 @@ static int test_mb_aead_jiffies(struct test_mb_aead_data *data, int enc, int ret = 0; int *rc; - rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL); + rc = kzalloc_objs(*rc, num_mb); if (!rc) return -ENOMEM; @@ -207,7 +207,7 @@ static int test_mb_aead_cycles(struct test_mb_aead_data *data, int enc, int i; int *rc; - rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL); + rc = kzalloc_objs(*rc, num_mb); if (!rc) return -ENOMEM; @@ -270,7 +270,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, else e = "decryption"; - data = kcalloc(num_mb, sizeof(*data), GFP_KERNEL); + data = kzalloc_objs(*data, num_mb); if (!data) goto out_free_iv; @@ -997,7 +997,7 @@ static int test_mb_acipher_jiffies(struct test_mb_skcipher_data *data, int enc, int ret = 0; int *rc; - rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL); + rc = kzalloc_objs(*rc, num_mb); if (!rc) return -ENOMEM; @@ -1024,7 +1024,7 @@ static int test_mb_acipher_cycles(struct test_mb_skcipher_data *data, int enc, int i; int *rc; - rc = kcalloc(num_mb, sizeof(*rc), GFP_KERNEL); + rc = kzalloc_objs(*rc, num_mb); if (!rc) return -ENOMEM; @@ -1075,7 +1075,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, else e = "decryption"; - data = kcalloc(num_mb, sizeof(*data), GFP_KERNEL); + data = kzalloc_objs(*data, num_mb); if (!data) return; diff --git a/crypto/testmgr.c b/crypto/testmgr.c index b940721447fa..4985411dedae 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -739,7 +739,7 @@ static struct cipher_test_sglists *alloc_cipher_test_sglists(void) { struct cipher_test_sglists *tsgls; - tsgls = kmalloc(sizeof(*tsgls), GFP_KERNEL); + tsgls = kmalloc_obj(*tsgls); if (!tsgls) return NULL; @@ -1796,7 +1796,7 @@ static int test_hash_vs_generic_impl(const char *generic_driver, return err; } - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) { err = -ENOMEM; goto out; @@ -1941,7 +1941,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs, if (err) goto out; - tsgl = kmalloc(sizeof(*tsgl), GFP_KERNEL); + tsgl = kmalloc_obj(*tsgl); if (!tsgl || init_test_sglist(tsgl) != 0) { pr_err("alg: hash: failed to allocate test buffers for %s\n", driver); @@ -2598,7 +2598,7 @@ static int test_aead_slow(const struct alg_test_desc *test_desc, if (noslowtests) return 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; init_rnd_state(&ctx->rng); @@ -3106,7 +3106,7 @@ static int test_skcipher_vs_generic_impl(const char *generic_driver, return err; } - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) { err = -ENOMEM; goto out; @@ -4132,7 +4132,7 @@ static const struct alg_test_desc alg_test_descs[] = { .fips_allowed = 1, }, { .alg = "authenc(hmac(sha224),cbc(aes))", - .generic_driver = "authenc(hmac-sha224-lib,cbc(aes-generic))", + .generic_driver = "authenc(hmac-sha224-lib,cbc(aes-lib))", .test = alg_test_aead, .suite = { .aead = __VECS(hmac_sha224_aes_cbc_tv_temp) @@ -4194,7 +4194,7 @@ static const struct alg_test_desc alg_test_descs[] = { .fips_allowed = 1, }, { .alg = "authenc(hmac(sha384),cbc(aes))", - .generic_driver = "authenc(hmac-sha384-lib,cbc(aes-generic))", + .generic_driver = "authenc(hmac-sha384-lib,cbc(aes-lib))", .test = alg_test_aead, .suite = { .aead = __VECS(hmac_sha384_aes_cbc_tv_temp) diff --git a/crypto/zstd.c b/crypto/zstd.c index cbbd0413751a..556f5d2bdd5f 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -44,7 +44,7 @@ static void *zstd_alloc_stream(void) if (!wksp_size) return ERR_PTR(-EINVAL); - ctx = kvmalloc(struct_size(ctx, wksp, wksp_size), GFP_KERNEL); + ctx = kvmalloc_flex(*ctx, wksp, wksp_size); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/Makefile b/drivers/Makefile index ccc05f1eae3e..53fbd2e0acdd 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -10,7 +10,7 @@ obj-y += cache/ obj-y += irqchip/ obj-y += bus/ -obj-$(CONFIG_GENERIC_PHY) += phy/ +obj-y += phy/ # GPIO must come after pinctrl as gpios may need to mux pins etc obj-$(CONFIG_PINCTRL) += pinctrl/ diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c index 37d05f2e986f..c0d348884f74 100644 --- a/drivers/accel/amdxdna/aie2_ctx.c +++ b/drivers/accel/amdxdna/aie2_ctx.c @@ -23,9 +23,9 @@ #include "amdxdna_pci_drv.h" #include "amdxdna_pm.h" -static bool force_cmdlist; +static bool force_cmdlist = true; module_param(force_cmdlist, bool, 0600); -MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default false)"); +MODULE_PARM_DESC(force_cmdlist, "Force use command list (Default true)"); #define HWCTX_MAX_TIMEOUT 60000 /* milliseconds */ @@ -53,6 +53,7 @@ static void aie2_hwctx_stop(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwct { drm_sched_stop(&hwctx->priv->sched, bad_job); aie2_destroy_context(xdna->dev_handle, hwctx); + drm_sched_start(&hwctx->priv->sched, 0); } static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hwctx) @@ -80,7 +81,6 @@ static int aie2_hwctx_restart(struct amdxdna_dev *xdna, struct amdxdna_hwctx *hw } out: - drm_sched_start(&hwctx->priv->sched, 0); XDNA_DBG(xdna, "%s restarted, ret %d", hwctx->name, ret); return ret; } @@ -165,7 +165,6 @@ aie2_sched_notify(struct amdxdna_sched_job *job) trace_xdna_job(&job->base, job->hwctx->name, "signaled fence", job->seq); - amdxdna_pm_suspend_put(job->hwctx->client->xdna); job->hwctx->priv->completed++; dma_fence_signal(fence); @@ -186,13 +185,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) cmd_abo = job->cmd_bo; if (unlikely(job->job_timeout)) { - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); + amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT); ret = -EINVAL; goto out; } if (unlikely(!data) || unlikely(size != sizeof(u32))) { - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT); ret = -EINVAL; goto out; } @@ -202,7 +201,7 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) if (status == AIE2_STATUS_SUCCESS) amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_COMPLETED); else - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR); + amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ERROR); out: aie2_sched_notify(job); @@ -244,13 +243,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) cmd_abo = job->cmd_bo; if (unlikely(job->job_timeout)) { - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); + amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_TIMEOUT); ret = -EINVAL; goto out; } if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) { - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + amdxdna_cmd_set_error(cmd_abo, job, 0, ERT_CMD_STATE_ABORT); ret = -EINVAL; goto out; } @@ -270,19 +269,12 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) fail_cmd_idx, fail_cmd_status); if (fail_cmd_status == AIE2_STATUS_SUCCESS) { - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ABORT); ret = -EINVAL; - goto out; + } else { + amdxdna_cmd_set_error(cmd_abo, job, fail_cmd_idx, ERT_CMD_STATE_ERROR); } - amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ERROR); - if (amdxdna_cmd_get_op(cmd_abo) == ERT_CMD_CHAIN) { - struct amdxdna_cmd_chain *cc = amdxdna_cmd_get_payload(cmd_abo, NULL); - - cc->error_index = fail_cmd_idx; - if (cc->error_index >= cc->command_count) - cc->error_index = 0; - } out: aie2_sched_notify(job); return ret; @@ -306,10 +298,6 @@ aie2_sched_job_run(struct drm_sched_job *sched_job) kref_get(&job->refcnt); fence = dma_fence_get(job->fence); - ret = amdxdna_pm_resume_get(hwctx->client->xdna); - if (ret) - goto out; - if (job->drv_cmd) { switch (job->drv_cmd->opcode) { case SYNC_DEBUG_BO: @@ -336,7 +324,6 @@ aie2_sched_job_run(struct drm_sched_job *sched_job) out: if (ret) { - amdxdna_pm_suspend_put(hwctx->client->xdna); dma_fence_put(job->fence); aie2_job_put(job); mmput(job->mm); @@ -464,7 +451,7 @@ static int aie2_alloc_resource(struct amdxdna_hwctx *hwctx) return aie2_create_context(xdna->dev_handle, hwctx); } - xrs_req = kzalloc(sizeof(*xrs_req), GFP_KERNEL); + xrs_req = kzalloc_obj(*xrs_req); if (!xrs_req) return -ENOMEM; @@ -497,7 +484,7 @@ static void aie2_release_resource(struct amdxdna_hwctx *hwctx) if (AIE2_FEATURE_ON(xdna->dev_handle, AIE2_TEMPORAL_ONLY)) { ret = aie2_destroy_context(xdna->dev_handle, hwctx); - if (ret) + if (ret && ret != -ENODEV) XDNA_ERR(xdna, "Destroy temporal only context failed, ret %d", ret); } else { ret = xrs_release_resource(xdna->xrs_hdl, (uintptr_t)hwctx); @@ -559,7 +546,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) struct amdxdna_gem_obj *heap; int i, ret; - priv = kzalloc(sizeof(*hwctx->priv), GFP_KERNEL); + priv = kzalloc_obj(*hwctx->priv); if (!priv) return -ENOMEM; hwctx->priv = priv; @@ -629,7 +616,7 @@ int aie2_hwctx_init(struct amdxdna_hwctx *hwctx) goto free_entity; } - ret = amdxdna_pm_resume_get(xdna); + ret = amdxdna_pm_resume_get_locked(xdna); if (ret) goto free_col_list; @@ -760,7 +747,7 @@ static int aie2_hwctx_cu_config(struct amdxdna_hwctx *hwctx, void *buf, u32 size if (!hwctx->cus) return -ENOMEM; - ret = amdxdna_pm_resume_get(xdna); + ret = amdxdna_pm_resume_get_locked(xdna); if (ret) goto free_cus; @@ -1070,6 +1057,8 @@ void aie2_hmm_invalidate(struct amdxdna_gem_obj *abo, ret = dma_resv_wait_timeout(gobj->resv, DMA_RESV_USAGE_BOOKKEEP, true, MAX_SCHEDULE_TIMEOUT); - if (!ret || ret == -ERESTARTSYS) + if (!ret) XDNA_ERR(xdna, "Failed to wait for bo, ret %ld", ret); + else if (ret == -ERESTARTSYS) + XDNA_DBG(xdna, "Wait for bo interrupted by signal"); } diff --git a/drivers/accel/amdxdna/aie2_error.c b/drivers/accel/amdxdna/aie2_error.c index 5e82df2b7cf6..9f0ea1d9c05f 100644 --- a/drivers/accel/amdxdna/aie2_error.c +++ b/drivers/accel/amdxdna/aie2_error.c @@ -350,7 +350,7 @@ int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev) struct async_events *events; int i, ret; - events = kzalloc(struct_size(events, event, total_col), GFP_KERNEL); + events = kzalloc_flex(*events, event, total_col); if (!events) return -ENOMEM; diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c index 7d7dcfeaf794..ffcf3be79e23 100644 --- a/drivers/accel/amdxdna/aie2_message.c +++ b/drivers/accel/amdxdna/aie2_message.c @@ -40,11 +40,8 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, return -ENODEV; ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg); - if (ret == -ETIME) { - xdna_mailbox_stop_channel(ndev->mgmt_chann); - xdna_mailbox_destroy_channel(ndev->mgmt_chann); - ndev->mgmt_chann = NULL; - } + if (ret == -ETIME) + aie2_destroy_mgmt_chann(ndev); if (!ret && *hdl->status != AIE2_STATUS_SUCCESS) { XDNA_ERR(xdna, "command opcode 0x%x failed, status 0x%x", @@ -216,8 +213,10 @@ static int aie2_destroy_context_req(struct amdxdna_dev_hdl *ndev, u32 id) req.context_id = id; ret = aie2_send_mgmt_msg_wait(ndev, &msg); - if (ret) + if (ret && ret != -ENODEV) XDNA_WARN(xdna, "Destroy context failed, ret %d", ret); + else if (ret == -ENODEV) + XDNA_DBG(xdna, "Destroy context: device already stopped"); return ret; } @@ -294,13 +293,20 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct } intr_reg = i2x.mb_head_ptr_reg + 4; - hwctx->priv->mbox_chann = xdna_mailbox_create_channel(ndev->mbox, &x2i, &i2x, - intr_reg, ret); + hwctx->priv->mbox_chann = xdna_mailbox_alloc_channel(ndev->mbox); if (!hwctx->priv->mbox_chann) { XDNA_ERR(xdna, "Not able to create channel"); ret = -EINVAL; goto del_ctx_req; } + + ret = xdna_mailbox_start_channel(hwctx->priv->mbox_chann, &x2i, &i2x, + intr_reg, ret); + if (ret) { + XDNA_ERR(xdna, "Not able to create channel"); + ret = -EINVAL; + goto free_channel; + } ndev->hwctx_num++; XDNA_DBG(xdna, "Mailbox channel irq: %d, msix_id: %d", ret, resp.msix_id); @@ -308,6 +314,8 @@ int aie2_create_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwct return 0; +free_channel: + xdna_mailbox_free_channel(hwctx->priv->mbox_chann); del_ctx_req: aie2_destroy_context_req(ndev, hwctx->fw_ctx_id); return ret; @@ -318,9 +326,12 @@ int aie2_destroy_context(struct amdxdna_dev_hdl *ndev, struct amdxdna_hwctx *hwc struct amdxdna_dev *xdna = ndev->xdna; int ret; + if (!hwctx->priv->mbox_chann) + return 0; + xdna_mailbox_stop_channel(hwctx->priv->mbox_chann); ret = aie2_destroy_context_req(ndev, hwctx->fw_ctx_id); - xdna_mailbox_destroy_channel(hwctx->priv->mbox_chann); + xdna_mailbox_free_channel(hwctx->priv->mbox_chann); XDNA_DBG(xdna, "Destroyed fw ctx %d", hwctx->fw_ctx_id); hwctx->priv->mbox_chann = NULL; hwctx->fw_ctx_id = -1; @@ -694,11 +705,11 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz u32 cmd_len; void *cmd; - memset(npu_slot, 0, sizeof(*npu_slot)); cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); if (*size < sizeof(*npu_slot) + cmd_len) return -EINVAL; + memset(npu_slot, 0, sizeof(*npu_slot)); npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); if (npu_slot->cu_idx == INVALID_CU_IDX) return -EINVAL; @@ -719,7 +730,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si u32 cmd_len; u32 arg_sz; - memset(npu_slot, 0, sizeof(*npu_slot)); sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); arg_sz = cmd_len - sizeof(*sn); if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE) @@ -728,6 +738,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si if (*size < sizeof(*npu_slot) + arg_sz) return -EINVAL; + memset(npu_slot, 0, sizeof(*npu_slot)); npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); if (npu_slot->cu_idx == INVALID_CU_IDX) return -EINVAL; @@ -751,7 +762,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t u32 cmd_len; u32 arg_sz; - memset(npu_slot, 0, sizeof(*npu_slot)); pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); arg_sz = cmd_len - sizeof(*pd); if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) @@ -760,6 +770,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t if (*size < sizeof(*npu_slot) + arg_sz) return -EINVAL; + memset(npu_slot, 0, sizeof(*npu_slot)); npu_slot->cu_idx = amdxdna_cmd_get_cu_idx(cmd_bo); if (npu_slot->cu_idx == INVALID_CU_IDX) return -EINVAL; @@ -787,7 +798,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si u32 cmd_len; u32 arg_sz; - memset(npu_slot, 0, sizeof(*npu_slot)); pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len); arg_sz = cmd_len - sizeof(*pd); if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE) @@ -796,6 +806,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si if (*size < sizeof(*npu_slot) + arg_sz) return -EINVAL; + memset(npu_slot, 0, sizeof(*npu_slot)); npu_slot->type = EXEC_NPU_TYPE_ELF; npu_slot->inst_buf_addr = pd->inst_buf; npu_slot->save_buf_addr = pd->save_buf; @@ -909,6 +920,20 @@ void aie2_msg_init(struct amdxdna_dev_hdl *ndev) ndev->exec_msg_ops = &legacy_exec_message_ops; } +void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev) +{ + struct amdxdna_dev *xdna = ndev->xdna; + + drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); + + if (!ndev->mgmt_chann) + return; + + xdna_mailbox_stop_channel(ndev->mgmt_chann); + xdna_mailbox_free_channel(ndev->mgmt_chann); + ndev->mgmt_chann = NULL; +} + static inline struct amdxdna_gem_obj * aie2_cmdlist_get_cmd_buf(struct amdxdna_sched_job *job) { diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c index f70ccf0f3c01..4924a9da55b6 100644 --- a/drivers/accel/amdxdna/aie2_pci.c +++ b/drivers/accel/amdxdna/aie2_pci.c @@ -32,6 +32,11 @@ static int aie2_max_col = XRS_MAX_COL; module_param(aie2_max_col, uint, 0600); MODULE_PARM_DESC(aie2_max_col, "Maximum column could be used"); +static char *npu_fw[] = { + "npu_7.sbin", + "npu.sbin" +}; + /* * The management mailbox channel is allocated by firmware. * The related register and ring buffer information is on SRAM BAR. @@ -323,10 +328,9 @@ static void aie2_hw_stop(struct amdxdna_dev *xdna) return; } + aie2_runtime_cfg(ndev, AIE2_RT_CFG_CLK_GATING, NULL); aie2_mgmt_fw_fini(ndev); - xdna_mailbox_stop_channel(ndev->mgmt_chann); - xdna_mailbox_destroy_channel(ndev->mgmt_chann); - ndev->mgmt_chann = NULL; + aie2_destroy_mgmt_chann(ndev); drmm_kfree(&xdna->ddev, ndev->mbox); ndev->mbox = NULL; aie2_psp_stop(ndev->psp_hdl); @@ -357,10 +361,29 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) } pci_set_master(pdev); + mbox_res.ringbuf_base = ndev->sram_base; + mbox_res.ringbuf_size = pci_resource_len(pdev, xdna->dev_info->sram_bar); + mbox_res.mbox_base = ndev->mbox_base; + mbox_res.mbox_size = MBOX_SIZE(ndev); + mbox_res.name = "xdna_mailbox"; + ndev->mbox = xdnam_mailbox_create(&xdna->ddev, &mbox_res); + if (!ndev->mbox) { + XDNA_ERR(xdna, "failed to create mailbox device"); + ret = -ENODEV; + goto disable_dev; + } + + ndev->mgmt_chann = xdna_mailbox_alloc_channel(ndev->mbox); + if (!ndev->mgmt_chann) { + XDNA_ERR(xdna, "failed to alloc channel"); + ret = -ENODEV; + goto disable_dev; + } + ret = aie2_smu_init(ndev); if (ret) { XDNA_ERR(xdna, "failed to init smu, ret %d", ret); - goto disable_dev; + goto free_channel; } ret = aie2_psp_start(ndev->psp_hdl); @@ -375,18 +398,6 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) goto stop_psp; } - mbox_res.ringbuf_base = ndev->sram_base; - mbox_res.ringbuf_size = pci_resource_len(pdev, xdna->dev_info->sram_bar); - mbox_res.mbox_base = ndev->mbox_base; - mbox_res.mbox_size = MBOX_SIZE(ndev); - mbox_res.name = "xdna_mailbox"; - ndev->mbox = xdnam_mailbox_create(&xdna->ddev, &mbox_res); - if (!ndev->mbox) { - XDNA_ERR(xdna, "failed to create mailbox device"); - ret = -ENODEV; - goto stop_psp; - } - mgmt_mb_irq = pci_irq_vector(pdev, ndev->mgmt_chan_idx); if (mgmt_mb_irq < 0) { ret = mgmt_mb_irq; @@ -395,52 +406,55 @@ static int aie2_hw_start(struct amdxdna_dev *xdna) } xdna_mailbox_intr_reg = ndev->mgmt_i2x.mb_head_ptr_reg + 4; - ndev->mgmt_chann = xdna_mailbox_create_channel(ndev->mbox, - &ndev->mgmt_x2i, - &ndev->mgmt_i2x, - xdna_mailbox_intr_reg, - mgmt_mb_irq); - if (!ndev->mgmt_chann) { - XDNA_ERR(xdna, "failed to create management mailbox channel"); + ret = xdna_mailbox_start_channel(ndev->mgmt_chann, + &ndev->mgmt_x2i, + &ndev->mgmt_i2x, + xdna_mailbox_intr_reg, + mgmt_mb_irq); + if (ret) { + XDNA_ERR(xdna, "failed to start management mailbox channel"); ret = -EINVAL; goto stop_psp; } - ret = aie2_pm_init(ndev); - if (ret) { - XDNA_ERR(xdna, "failed to init pm, ret %d", ret); - goto destroy_mgmt_chann; - } - ret = aie2_mgmt_fw_init(ndev); if (ret) { XDNA_ERR(xdna, "initial mgmt firmware failed, ret %d", ret); - goto destroy_mgmt_chann; + goto stop_fw; + } + + ret = aie2_pm_init(ndev); + if (ret) { + XDNA_ERR(xdna, "failed to init pm, ret %d", ret); + goto stop_fw; } ret = aie2_mgmt_fw_query(ndev); if (ret) { XDNA_ERR(xdna, "failed to query fw, ret %d", ret); - goto destroy_mgmt_chann; + goto stop_fw; } ret = aie2_error_async_events_alloc(ndev); if (ret) { XDNA_ERR(xdna, "Allocate async events failed, ret %d", ret); - goto destroy_mgmt_chann; + goto stop_fw; } ndev->dev_status = AIE2_DEV_START; return 0; -destroy_mgmt_chann: +stop_fw: + aie2_suspend_fw(ndev); xdna_mailbox_stop_channel(ndev->mgmt_chann); - xdna_mailbox_destroy_channel(ndev->mgmt_chann); stop_psp: aie2_psp_stop(ndev->psp_hdl); fini_smu: aie2_smu_fini(ndev); +free_channel: + xdna_mailbox_free_channel(ndev->mgmt_chann); + ndev->mgmt_chann = NULL; disable_dev: pci_disable_device(pdev); @@ -451,7 +465,6 @@ static int aie2_hw_suspend(struct amdxdna_dev *xdna) { struct amdxdna_client *client; - guard(mutex)(&xdna->dev_lock); list_for_each_entry(client, &xdna->client_list, node) aie2_hwctx_suspend(client); @@ -489,6 +502,7 @@ static int aie2_init(struct amdxdna_dev *xdna) struct psp_config psp_conf; const struct firmware *fw; unsigned long bars = 0; + char *fw_full_path; int i, nvec, ret; if (!hypervisor_is_type(X86_HYPER_NATIVE)) { @@ -503,7 +517,19 @@ static int aie2_init(struct amdxdna_dev *xdna) ndev->priv = xdna->dev_info->dev_priv; ndev->xdna = xdna; - ret = request_firmware(&fw, ndev->priv->fw_path, &pdev->dev); + for (i = 0; i < ARRAY_SIZE(npu_fw); i++) { + fw_full_path = kasprintf(GFP_KERNEL, "%s%s", ndev->priv->fw_path, npu_fw[i]); + if (!fw_full_path) + return -ENOMEM; + + ret = firmware_request_nowarn(&fw, fw_full_path, &pdev->dev); + kfree(fw_full_path); + if (!ret) { + XDNA_INFO(xdna, "Load firmware %s%s", ndev->priv->fw_path, npu_fw[i]); + break; + } + } + if (ret) { XDNA_ERR(xdna, "failed to request_firmware %s, ret %d", ndev->priv->fw_path, ret); @@ -653,7 +679,7 @@ static int aie2_get_aie_metadata(struct amdxdna_client *client, int ret = 0; ndev = xdna->dev_handle; - meta = kzalloc(sizeof(*meta), GFP_KERNEL); + meta = kzalloc_obj(*meta); if (!meta) return -ENOMEM; @@ -748,7 +774,7 @@ static int aie2_get_clock_metadata(struct amdxdna_client *client, int ret = 0; ndev = xdna->dev_handle; - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) return -ENOMEM; @@ -775,7 +801,7 @@ static int aie2_hwctx_status_cb(struct amdxdna_hwctx *hwctx, void *arg) if (!array_args->num_element) return -EINVAL; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -951,7 +977,7 @@ static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_i if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; - ret = amdxdna_pm_resume_get(xdna); + ret = amdxdna_pm_resume_get_locked(xdna); if (ret) goto dev_exit; @@ -1044,7 +1070,7 @@ static int aie2_get_array(struct amdxdna_client *client, if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; - ret = amdxdna_pm_resume_get(xdna); + ret = amdxdna_pm_resume_get_locked(xdna); if (ret) goto dev_exit; @@ -1134,7 +1160,7 @@ static int aie2_set_state(struct amdxdna_client *client, if (!drm_dev_enter(&xdna->ddev, &idx)) return -ENODEV; - ret = amdxdna_pm_resume_get(xdna); + ret = amdxdna_pm_resume_get_locked(xdna); if (ret) goto dev_exit; diff --git a/drivers/accel/amdxdna/aie2_pci.h b/drivers/accel/amdxdna/aie2_pci.h index b20a3661078c..e72311c77996 100644 --- a/drivers/accel/amdxdna/aie2_pci.h +++ b/drivers/accel/amdxdna/aie2_pci.h @@ -303,6 +303,7 @@ int aie2_get_array_async_error(struct amdxdna_dev_hdl *ndev, /* aie2_message.c */ void aie2_msg_init(struct amdxdna_dev_hdl *ndev); +void aie2_destroy_mgmt_chann(struct amdxdna_dev_hdl *ndev); int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev); int aie2_resume_fw(struct amdxdna_dev_hdl *ndev); int aie2_set_runtime_cfg(struct amdxdna_dev_hdl *ndev, u32 type, u64 value); diff --git a/drivers/accel/amdxdna/aie2_pm.c b/drivers/accel/amdxdna/aie2_pm.c index 579b8be13b18..29bd4403a94d 100644 --- a/drivers/accel/amdxdna/aie2_pm.c +++ b/drivers/accel/amdxdna/aie2_pm.c @@ -31,7 +31,7 @@ int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) { int ret; - ret = amdxdna_pm_resume_get(ndev->xdna); + ret = amdxdna_pm_resume_get_locked(ndev->xdna); if (ret) return ret; diff --git a/drivers/accel/amdxdna/aie2_solver.c b/drivers/accel/amdxdna/aie2_solver.c index 2013d1f13aae..3611e3268d79 100644 --- a/drivers/accel/amdxdna/aie2_solver.c +++ b/drivers/accel/amdxdna/aie2_solver.c @@ -197,7 +197,7 @@ static int get_free_partition(struct solver_state *xrs, if (i == snode->cols_len) return -ENODEV; - pt_node = kzalloc(sizeof(*pt_node), GFP_KERNEL); + pt_node = kzalloc_obj(*pt_node); if (!pt_node) return -ENOMEM; @@ -266,7 +266,7 @@ static struct solver_node *create_solver_node(struct solver_state *xrs, struct solver_node *node; int ret; - node = kzalloc(struct_size(node, start_cols, cdop->cols_len), GFP_KERNEL); + node = kzalloc_flex(*node, start_cols, cdop->cols_len); if (!node) return ERR_PTR(-ENOMEM); diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c index d17aef89a0ad..838430903a3e 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.c +++ b/drivers/accel/amdxdna/amdxdna_ctx.c @@ -17,6 +17,7 @@ #include "amdxdna_ctx.h" #include "amdxdna_gem.h" #include "amdxdna_pci_drv.h" +#include "amdxdna_pm.h" #define MAX_HWCTX_ID 255 #define MAX_ARG_COUNT 4095 @@ -50,7 +51,7 @@ static struct dma_fence *amdxdna_fence_create(struct amdxdna_hwctx *hwctx) { struct amdxdna_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; @@ -104,7 +105,10 @@ void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size) if (size) { count = FIELD_GET(AMDXDNA_CMD_COUNT, cmd->header); - if (unlikely(count <= num_masks)) { + if (unlikely(count <= num_masks || + count * sizeof(u32) + + offsetof(struct amdxdna_cmd, data[0]) > + abo->mem.size)) { *size = 0; return NULL; } @@ -132,6 +136,33 @@ u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo) return INVALID_CU_IDX; } +int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo, + struct amdxdna_sched_job *job, u32 cmd_idx, + enum ert_cmd_state error_state) +{ + struct amdxdna_client *client = job->hwctx->client; + struct amdxdna_cmd *cmd = abo->mem.kva; + struct amdxdna_cmd_chain *cc = NULL; + + cmd->header &= ~AMDXDNA_CMD_STATE; + cmd->header |= FIELD_PREP(AMDXDNA_CMD_STATE, error_state); + + if (amdxdna_cmd_get_op(abo) == ERT_CMD_CHAIN) { + cc = amdxdna_cmd_get_payload(abo, NULL); + cc->error_index = (cmd_idx < cc->command_count) ? cmd_idx : 0; + abo = amdxdna_gem_get_obj(client, cc->data[0], AMDXDNA_BO_CMD); + if (!abo) + return -EINVAL; + cmd = abo->mem.kva; + } + + memset(cmd->data, 0xff, abo->mem.size - sizeof(*cmd)); + if (cc) + amdxdna_gem_put_obj(abo); + + return 0; +} + /* * This should be called in close() and remove(). DO NOT call in other syscalls. * This guarantee that when hwctx and resources will be released, if user @@ -161,7 +192,7 @@ int amdxdna_drm_create_hwctx_ioctl(struct drm_device *dev, void *data, struct dr if (args->ext || args->ext_flags) return -EINVAL; - hwctx = kzalloc(sizeof(*hwctx), GFP_KERNEL); + hwctx = kzalloc_obj(*hwctx); if (!hwctx) return -ENOMEM; @@ -266,9 +297,9 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr struct amdxdna_drm_config_hwctx *args = data; struct amdxdna_dev *xdna = to_xdna_dev(dev); struct amdxdna_hwctx *hwctx; - int ret, idx; u32 buf_size; void *buf; + int ret; u64 val; if (XDNA_MBZ_DBG(xdna, &args->pad, sizeof(args->pad))) @@ -310,20 +341,17 @@ int amdxdna_drm_config_hwctx_ioctl(struct drm_device *dev, void *data, struct dr return -EINVAL; } - mutex_lock(&xdna->dev_lock); - idx = srcu_read_lock(&client->hwctx_srcu); + guard(mutex)(&xdna->dev_lock); hwctx = xa_load(&client->hwctx_xa, args->handle); if (!hwctx) { XDNA_DBG(xdna, "PID %d failed to get hwctx %d", client->pid, args->handle); ret = -EINVAL; - goto unlock_srcu; + goto free_buf; } ret = xdna->dev_info->ops->hwctx_config(hwctx, args->param_type, val, buf, buf_size); -unlock_srcu: - srcu_read_unlock(&client->hwctx_srcu, idx); - mutex_unlock(&xdna->dev_lock); +free_buf: kfree(buf); return ret; } @@ -334,7 +362,7 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl) struct amdxdna_hwctx *hwctx; struct amdxdna_gem_obj *abo; struct drm_gem_object *gobj; - int ret, idx; + int ret; if (!xdna->dev_info->ops->hwctx_sync_debug_bo) return -EOPNOTSUPP; @@ -345,17 +373,15 @@ int amdxdna_hwctx_sync_debug_bo(struct amdxdna_client *client, u32 debug_bo_hdl) abo = to_xdna_obj(gobj); guard(mutex)(&xdna->dev_lock); - idx = srcu_read_lock(&client->hwctx_srcu); hwctx = xa_load(&client->hwctx_xa, abo->assigned_hwctx); if (!hwctx) { ret = -EINVAL; - goto unlock_srcu; + goto put_obj; } ret = xdna->dev_info->ops->hwctx_sync_debug_bo(hwctx, debug_bo_hdl); -unlock_srcu: - srcu_read_unlock(&client->hwctx_srcu, idx); +put_obj: drm_gem_object_put(gobj); return ret; } @@ -420,6 +446,7 @@ amdxdna_arg_bos_lookup(struct amdxdna_client *client, void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job) { trace_amdxdna_debug_point(job->hwctx->name, job->seq, "job release"); + amdxdna_pm_suspend_put(job->hwctx->client->xdna); amdxdna_arg_bos_put(job); amdxdna_gem_put_obj(job->cmd_bo); dma_fence_put(job->fence); @@ -436,7 +463,7 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, int ret, idx; XDNA_DBG(xdna, "Command BO hdl %d, Arg BO count %d", cmd_bo_hdl, arg_bo_cnt); - job = kzalloc(struct_size(job, bos, arg_bo_cnt), GFP_KERNEL); + job = kzalloc_flex(*job, bos, arg_bo_cnt); if (!job) return -ENOMEM; @@ -457,6 +484,12 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, goto cmd_put; } + ret = amdxdna_pm_resume_get(xdna); + if (ret) { + XDNA_ERR(xdna, "Resume failed, ret %d", ret); + goto put_bos; + } + idx = srcu_read_lock(&client->hwctx_srcu); hwctx = xa_load(&client->hwctx_xa, hwctx_hdl); if (!hwctx) { @@ -497,6 +530,8 @@ int amdxdna_cmd_submit(struct amdxdna_client *client, dma_fence_put(job->fence); unlock_srcu: srcu_read_unlock(&client->hwctx_srcu, idx); + amdxdna_pm_suspend_put(xdna); +put_bos: amdxdna_arg_bos_put(job); cmd_put: amdxdna_gem_put_obj(job->cmd_bo); diff --git a/drivers/accel/amdxdna/amdxdna_ctx.h b/drivers/accel/amdxdna/amdxdna_ctx.h index 16c85f08f03c..fbdf9d000871 100644 --- a/drivers/accel/amdxdna/amdxdna_ctx.h +++ b/drivers/accel/amdxdna/amdxdna_ctx.h @@ -167,6 +167,9 @@ amdxdna_cmd_get_state(struct amdxdna_gem_obj *abo) void *amdxdna_cmd_get_payload(struct amdxdna_gem_obj *abo, u32 *size); u32 amdxdna_cmd_get_cu_idx(struct amdxdna_gem_obj *abo); +int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo, + struct amdxdna_sched_job *job, u32 cmd_idx, + enum ert_cmd_state error_state); void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job); void amdxdna_hwctx_remove_all(struct amdxdna_client *client); diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c index dfa916eeb2d9..d60db49ead71 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -21,8 +21,6 @@ #include "amdxdna_pci_drv.h" #include "amdxdna_ubuf.h" -#define XDNA_MAX_CMD_BO_SIZE SZ_32K - MODULE_IMPORT_NS("DMA_BUF"); static int @@ -205,13 +203,12 @@ static int amdxdna_hmm_register(struct amdxdna_gem_obj *abo, if (!xdna->dev_info->ops->hmm_invalidate) return 0; - mapp = kzalloc(sizeof(*mapp), GFP_KERNEL); + mapp = kzalloc_obj(*mapp); if (!mapp) return -ENOMEM; nr_pages = (PAGE_ALIGN(addr + len) - (addr & PAGE_MASK)) >> PAGE_SHIFT; - mapp->range.hmm_pfns = kvcalloc(nr_pages, sizeof(*mapp->range.hmm_pfns), - GFP_KERNEL); + mapp->range.hmm_pfns = kvzalloc_objs(*mapp->range.hmm_pfns, nr_pages); if (!mapp->range.hmm_pfns) { ret = -ENOMEM; goto free_map; @@ -499,7 +496,7 @@ amdxdna_gem_create_obj(struct drm_device *dev, size_t size) { struct amdxdna_gem_obj *abo; - abo = kzalloc(sizeof(*abo), GFP_KERNEL); + abo = kzalloc_obj(*abo); if (!abo) return ERR_PTR(-ENOMEM); @@ -746,12 +743,6 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, { struct amdxdna_dev *xdna = to_xdna_dev(dev); struct amdxdna_gem_obj *abo; - int ret; - - if (args->size > XDNA_MAX_CMD_BO_SIZE) { - XDNA_ERR(xdna, "Command bo size 0x%llx too large", args->size); - return ERR_PTR(-EINVAL); - } if (args->size < sizeof(struct amdxdna_cmd)) { XDNA_DBG(xdna, "Command BO size 0x%llx too small", args->size); @@ -765,17 +756,7 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, abo->type = AMDXDNA_BO_CMD; abo->client = filp->driver_priv; - ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); - if (ret) { - XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret); - goto release_obj; - } - return abo; - -release_obj: - drm_gem_object_put(to_gobj(abo)); - return ERR_PTR(ret); } int amdxdna_drm_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) @@ -872,6 +853,7 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client, struct amdxdna_dev *xdna = client->xdna; struct amdxdna_gem_obj *abo; struct drm_gem_object *gobj; + int ret; gobj = drm_gem_object_lookup(client->filp, bo_hdl); if (!gobj) { @@ -880,9 +862,26 @@ struct amdxdna_gem_obj *amdxdna_gem_get_obj(struct amdxdna_client *client, } abo = to_xdna_obj(gobj); - if (bo_type == AMDXDNA_BO_INVALID || abo->type == bo_type) + if (bo_type != AMDXDNA_BO_INVALID && abo->type != bo_type) + goto put_obj; + + if (bo_type != AMDXDNA_BO_CMD || abo->mem.kva) return abo; + if (abo->mem.size > SZ_32K) { + XDNA_ERR(xdna, "Cmd bo is too big %ld", abo->mem.size); + goto put_obj; + } + + ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); + if (ret) { + XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret); + goto put_obj; + } + + return abo; + +put_obj: drm_gem_object_put(gobj); return NULL; } diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.c b/drivers/accel/amdxdna/amdxdna_mailbox.c index 469242ed8224..46d844a73a94 100644 --- a/drivers/accel/amdxdna/amdxdna_mailbox.c +++ b/drivers/accel/amdxdna/amdxdna_mailbox.c @@ -460,26 +460,49 @@ int xdna_mailbox_send_msg(struct mailbox_channel *mb_chann, return ret; } -struct mailbox_channel * -xdna_mailbox_create_channel(struct mailbox *mb, - const struct xdna_mailbox_chann_res *x2i, - const struct xdna_mailbox_chann_res *i2x, - u32 iohub_int_addr, - int mb_irq) +struct mailbox_channel *xdna_mailbox_alloc_channel(struct mailbox *mb) { struct mailbox_channel *mb_chann; + + mb_chann = kzalloc_obj(*mb_chann); + if (!mb_chann) + return NULL; + + INIT_WORK(&mb_chann->rx_work, mailbox_rx_worker); + mb_chann->work_q = create_singlethread_workqueue(MAILBOX_NAME); + if (!mb_chann->work_q) { + MB_ERR(mb_chann, "Create workqueue failed"); + goto free_chann; + } + mb_chann->mb = mb; + + return mb_chann; + +free_chann: + kfree(mb_chann); + return NULL; +} + +void xdna_mailbox_free_channel(struct mailbox_channel *mb_chann) +{ + destroy_workqueue(mb_chann->work_q); + kfree(mb_chann); +} + +int +xdna_mailbox_start_channel(struct mailbox_channel *mb_chann, + const struct xdna_mailbox_chann_res *x2i, + const struct xdna_mailbox_chann_res *i2x, + u32 iohub_int_addr, + int mb_irq) +{ int ret; if (!is_power_of_2(x2i->rb_size) || !is_power_of_2(i2x->rb_size)) { pr_err("Ring buf size must be power of 2"); - return NULL; + return -EINVAL; } - mb_chann = kzalloc(sizeof(*mb_chann), GFP_KERNEL); - if (!mb_chann) - return NULL; - - mb_chann->mb = mb; mb_chann->msix_irq = mb_irq; mb_chann->iohub_int_addr = iohub_int_addr; memcpy(&mb_chann->res[CHAN_RES_X2I], x2i, sizeof(*x2i)); @@ -489,61 +512,37 @@ xdna_mailbox_create_channel(struct mailbox *mb, mb_chann->x2i_tail = mailbox_get_tailptr(mb_chann, CHAN_RES_X2I); mb_chann->i2x_head = mailbox_get_headptr(mb_chann, CHAN_RES_I2X); - INIT_WORK(&mb_chann->rx_work, mailbox_rx_worker); - mb_chann->work_q = create_singlethread_workqueue(MAILBOX_NAME); - if (!mb_chann->work_q) { - MB_ERR(mb_chann, "Create workqueue failed"); - goto free_and_out; - } - /* Everything look good. Time to enable irq handler */ ret = request_irq(mb_irq, mailbox_irq_handler, 0, MAILBOX_NAME, mb_chann); if (ret) { MB_ERR(mb_chann, "Failed to request irq %d ret %d", mb_irq, ret); - goto destroy_wq; + return ret; } mb_chann->bad_state = false; mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0); - MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq); - return mb_chann; - -destroy_wq: - destroy_workqueue(mb_chann->work_q); -free_and_out: - kfree(mb_chann); - return NULL; -} - -int xdna_mailbox_destroy_channel(struct mailbox_channel *mb_chann) -{ - struct mailbox_msg *mb_msg; - unsigned long msg_id; - - MB_DBG(mb_chann, "IRQ disabled and RX work cancelled"); - free_irq(mb_chann->msix_irq, mb_chann); - destroy_workqueue(mb_chann->work_q); - /* We can clean up and release resources */ - - xa_for_each(&mb_chann->chan_xa, msg_id, mb_msg) - mailbox_release_msg(mb_chann, mb_msg); - - xa_destroy(&mb_chann->chan_xa); - - MB_DBG(mb_chann, "Mailbox channel destroyed, irq: %d", mb_chann->msix_irq); - kfree(mb_chann); + MB_DBG(mb_chann, "Mailbox channel started (irq: %d)", mb_chann->msix_irq); return 0; } void xdna_mailbox_stop_channel(struct mailbox_channel *mb_chann) { + struct mailbox_msg *mb_msg; + unsigned long msg_id; + /* Disable an irq and wait. This might sleep. */ - disable_irq(mb_chann->msix_irq); + free_irq(mb_chann->msix_irq, mb_chann); /* Cancel RX work and wait for it to finish */ - cancel_work_sync(&mb_chann->rx_work); - MB_DBG(mb_chann, "IRQ disabled and RX work cancelled"); + drain_workqueue(mb_chann->work_q); + + /* We can clean up and release resources */ + xa_for_each(&mb_chann->chan_xa, msg_id, mb_msg) + mailbox_release_msg(mb_chann, mb_msg); + xa_destroy(&mb_chann->chan_xa); + + MB_DBG(mb_chann, "Mailbox channel stopped, irq: %d", mb_chann->msix_irq); } struct mailbox *xdnam_mailbox_create(struct drm_device *ddev, diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.h b/drivers/accel/amdxdna/amdxdna_mailbox.h index ea367f2fb738..8b1e00945da4 100644 --- a/drivers/accel/amdxdna/amdxdna_mailbox.h +++ b/drivers/accel/amdxdna/amdxdna_mailbox.h @@ -74,9 +74,16 @@ struct mailbox *xdnam_mailbox_create(struct drm_device *ddev, const struct xdna_mailbox_res *res); /* - * xdna_mailbox_create_channel() -- Create a mailbox channel instance + * xdna_mailbox_alloc_channel() -- alloc a mailbox channel * - * @mailbox: the handle return from xdna_mailbox_create() + * @mb: mailbox handle + */ +struct mailbox_channel *xdna_mailbox_alloc_channel(struct mailbox *mb); + +/* + * xdna_mailbox_start_channel() -- start a mailbox channel instance + * + * @mb_chann: the handle return from xdna_mailbox_alloc_channel() * @x2i: host to firmware mailbox resources * @i2x: firmware to host mailbox resources * @xdna_mailbox_intr_reg: register addr of MSI-X interrupt @@ -84,28 +91,24 @@ struct mailbox *xdnam_mailbox_create(struct drm_device *ddev, * * Return: If success, return a handle of mailbox channel. Otherwise, return NULL. */ -struct mailbox_channel * -xdna_mailbox_create_channel(struct mailbox *mailbox, - const struct xdna_mailbox_chann_res *x2i, - const struct xdna_mailbox_chann_res *i2x, - u32 xdna_mailbox_intr_reg, - int mb_irq); +int +xdna_mailbox_start_channel(struct mailbox_channel *mb_chann, + const struct xdna_mailbox_chann_res *x2i, + const struct xdna_mailbox_chann_res *i2x, + u32 xdna_mailbox_intr_reg, + int mb_irq); /* - * xdna_mailbox_destroy_channel() -- destroy mailbox channel + * xdna_mailbox_free_channel() -- free mailbox channel * * @mailbox_chann: the handle return from xdna_mailbox_create_channel() - * - * Return: if success, return 0. otherwise return error code */ -int xdna_mailbox_destroy_channel(struct mailbox_channel *mailbox_chann); +void xdna_mailbox_free_channel(struct mailbox_channel *mailbox_chann); /* * xdna_mailbox_stop_channel() -- stop mailbox channel * * @mailbox_chann: the handle return from xdna_mailbox_create_channel() - * - * Return: if success, return 0. otherwise return error code */ void xdna_mailbox_stop_channel(struct mailbox_channel *mailbox_chann); diff --git a/drivers/accel/amdxdna/amdxdna_pci_drv.c b/drivers/accel/amdxdna/amdxdna_pci_drv.c index fdefd9ec2066..a4384593bdcc 100644 --- a/drivers/accel/amdxdna/amdxdna_pci_drv.c +++ b/drivers/accel/amdxdna/amdxdna_pci_drv.c @@ -23,6 +23,9 @@ MODULE_FIRMWARE("amdnpu/1502_00/npu.sbin"); MODULE_FIRMWARE("amdnpu/17f0_10/npu.sbin"); MODULE_FIRMWARE("amdnpu/17f0_11/npu.sbin"); MODULE_FIRMWARE("amdnpu/17f0_20/npu.sbin"); +MODULE_FIRMWARE("amdnpu/1502_00/npu_7.sbin"); +MODULE_FIRMWARE("amdnpu/17f0_10/npu_7.sbin"); +MODULE_FIRMWARE("amdnpu/17f0_11/npu_7.sbin"); /* * 0.0: Initial version @@ -63,7 +66,7 @@ static int amdxdna_drm_open(struct drm_device *ddev, struct drm_file *filp) struct amdxdna_client *client; int ret; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; diff --git a/drivers/accel/amdxdna/amdxdna_pm.c b/drivers/accel/amdxdna/amdxdna_pm.c index d024d480521c..b1fafddd7ad5 100644 --- a/drivers/accel/amdxdna/amdxdna_pm.c +++ b/drivers/accel/amdxdna/amdxdna_pm.c @@ -16,6 +16,7 @@ int amdxdna_pm_suspend(struct device *dev) struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev)); int ret = -EOPNOTSUPP; + guard(mutex)(&xdna->dev_lock); if (xdna->dev_info->ops->suspend) ret = xdna->dev_info->ops->suspend(xdna); @@ -28,6 +29,7 @@ int amdxdna_pm_resume(struct device *dev) struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev)); int ret = -EOPNOTSUPP; + guard(mutex)(&xdna->dev_lock); if (xdna->dev_info->ops->resume) ret = xdna->dev_info->ops->resume(xdna); diff --git a/drivers/accel/amdxdna/amdxdna_pm.h b/drivers/accel/amdxdna/amdxdna_pm.h index 77b2d6e45570..3d26b973e0e3 100644 --- a/drivers/accel/amdxdna/amdxdna_pm.h +++ b/drivers/accel/amdxdna/amdxdna_pm.h @@ -15,4 +15,15 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna); void amdxdna_pm_init(struct amdxdna_dev *xdna); void amdxdna_pm_fini(struct amdxdna_dev *xdna); +static inline int amdxdna_pm_resume_get_locked(struct amdxdna_dev *xdna) +{ + int ret; + + mutex_unlock(&xdna->dev_lock); + ret = amdxdna_pm_resume_get(xdna); + mutex_lock(&xdna->dev_lock); + + return ret; +} + #endif /* _AMDXDNA_PM_H_ */ diff --git a/drivers/accel/amdxdna/amdxdna_ubuf.c b/drivers/accel/amdxdna/amdxdna_ubuf.c index 9e3b3b055caa..fb71d6e3f44d 100644 --- a/drivers/accel/amdxdna/amdxdna_ubuf.c +++ b/drivers/accel/amdxdna/amdxdna_ubuf.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -27,7 +28,7 @@ static struct sg_table *amdxdna_ubuf_map(struct dma_buf_attachment *attach, struct sg_table *sg; int ret; - sg = kzalloc(sizeof(*sg), GFP_KERNEL); + sg = kzalloc_obj(*sg); if (!sg) return ERR_PTR(-ENOMEM); @@ -147,7 +148,7 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, if (!can_do_mlock()) return ERR_PTR(-EPERM); - ubuf = kzalloc(sizeof(*ubuf), GFP_KERNEL); + ubuf = kzalloc_obj(*ubuf); if (!ubuf) return ERR_PTR(-ENOMEM); @@ -155,7 +156,7 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, ubuf->mm = current->mm; mmgrab(ubuf->mm); - va_ent = kvcalloc(num_entries, sizeof(*va_ent), GFP_KERNEL); + va_ent = kvzalloc_objs(*va_ent, num_entries); if (!va_ent) { ret = -ENOMEM; goto free_ubuf; @@ -176,7 +177,10 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, goto free_ent; } - exp_info.size += va_ent[i].len; + if (check_add_overflow(exp_info.size, va_ent[i].len, &exp_info.size)) { + ret = -EINVAL; + goto free_ent; + } } ubuf->nr_pages = exp_info.size >> PAGE_SHIFT; @@ -189,7 +193,7 @@ struct dma_buf *amdxdna_get_ubuf(struct drm_device *dev, goto sub_pin_cnt; } - ubuf->pages = kvmalloc_array(ubuf->nr_pages, sizeof(*ubuf->pages), GFP_KERNEL); + ubuf->pages = kvmalloc_objs(*ubuf->pages, ubuf->nr_pages); if (!ubuf->pages) { ret = -ENOMEM; goto sub_pin_cnt; diff --git a/drivers/accel/amdxdna/npu1_regs.c b/drivers/accel/amdxdna/npu1_regs.c index 6f36a27b5a02..1320e924e548 100644 --- a/drivers/accel/amdxdna/npu1_regs.c +++ b/drivers/accel/amdxdna/npu1_regs.c @@ -67,12 +67,12 @@ const struct dpm_clk_freq npu1_dpm_clk_table[] = { static const struct aie2_fw_feature_tbl npu1_fw_feature_table[] = { { .major = 5, .min_minor = 7 }, - { .features = BIT_U64(AIE2_NPU_COMMAND), .min_minor = 8 }, + { .features = BIT_U64(AIE2_NPU_COMMAND), .major = 5, .min_minor = 8 }, { 0 } }; static const struct amdxdna_dev_priv npu1_dev_priv = { - .fw_path = "amdnpu/1502_00/npu.sbin", + .fw_path = "amdnpu/1502_00/", .rt_config = npu1_default_rt_cfg, .dpm_clk_tbl = npu1_dpm_clk_table, .fw_feature_tbl = npu1_fw_feature_table, diff --git a/drivers/accel/amdxdna/npu4_regs.c b/drivers/accel/amdxdna/npu4_regs.c index a8d6f76dde5f..ce25eef5fc34 100644 --- a/drivers/accel/amdxdna/npu4_regs.c +++ b/drivers/accel/amdxdna/npu4_regs.c @@ -98,7 +98,7 @@ const struct aie2_fw_feature_tbl npu4_fw_feature_table[] = { }; static const struct amdxdna_dev_priv npu4_dev_priv = { - .fw_path = "amdnpu/17f0_10/npu.sbin", + .fw_path = "amdnpu/17f0_10/", .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, .fw_feature_tbl = npu4_fw_feature_table, diff --git a/drivers/accel/amdxdna/npu5_regs.c b/drivers/accel/amdxdna/npu5_regs.c index c0a35cfd886c..c0ac5daf32ee 100644 --- a/drivers/accel/amdxdna/npu5_regs.c +++ b/drivers/accel/amdxdna/npu5_regs.c @@ -63,7 +63,7 @@ #define NPU5_SRAM_BAR_BASE MMNPU_APERTURE1_BASE static const struct amdxdna_dev_priv npu5_dev_priv = { - .fw_path = "amdnpu/17f0_11/npu.sbin", + .fw_path = "amdnpu/17f0_11/", .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, .fw_feature_tbl = npu4_fw_feature_table, diff --git a/drivers/accel/amdxdna/npu6_regs.c b/drivers/accel/amdxdna/npu6_regs.c index 1fb07df99186..ce591ed0d483 100644 --- a/drivers/accel/amdxdna/npu6_regs.c +++ b/drivers/accel/amdxdna/npu6_regs.c @@ -63,7 +63,7 @@ #define NPU6_SRAM_BAR_BASE MMNPU_APERTURE1_BASE static const struct amdxdna_dev_priv npu6_dev_priv = { - .fw_path = "amdnpu/17f0_10/npu.sbin", + .fw_path = "amdnpu/17f0_10/", .rt_config = npu4_default_rt_cfg, .dpm_clk_tbl = npu4_dpm_clk_table, .fw_feature_tbl = npu4_fw_feature_table, diff --git a/drivers/accel/ethosu/ethosu_drv.c b/drivers/accel/ethosu/ethosu_drv.c index e05a69bf5574..9992193d7338 100644 --- a/drivers/accel/ethosu/ethosu_drv.c +++ b/drivers/accel/ethosu/ethosu_drv.c @@ -144,7 +144,7 @@ static int ethosu_open(struct drm_device *ddev, struct drm_file *file) if (!try_module_get(THIS_MODULE)) return -EINVAL; - struct ethosu_file_priv __free(kfree) *priv = kzalloc(sizeof(*priv), GFP_KERNEL); + struct ethosu_file_priv __free(kfree) *priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto err_put_mod; diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c index 473b5f5d7514..7994e7073903 100644 --- a/drivers/accel/ethosu/ethosu_gem.c +++ b/drivers/accel/ethosu/ethosu_gem.c @@ -50,7 +50,7 @@ struct drm_gem_object *ethosu_gem_create_object(struct drm_device *ddev, size_t { struct ethosu_gem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); @@ -154,7 +154,7 @@ static void cmd_state_init(struct cmd_state *st) static u64 cmd_to_addr(u32 *cmd) { - return ((u64)((cmd[0] & 0xff0000) << 16)) | cmd[1]; + return (((u64)cmd[0] & 0xff0000) << 16) | cmd[1]; } static u64 dma_length(struct ethosu_validated_cmdstream_info *info, @@ -245,11 +245,14 @@ static int calc_sizes(struct drm_device *ddev, ((st->ifm.stride_kernel >> 1) & 0x1) + 1; u32 stride_x = ((st->ifm.stride_kernel >> 5) & 0x2) + (st->ifm.stride_kernel & 0x1) + 1; - u32 ifm_height = st->ofm.height[2] * stride_y + + s32 ifm_height = st->ofm.height[2] * stride_y + st->ifm.height[2] - (st->ifm.pad_top + st->ifm.pad_bottom); - u32 ifm_width = st->ofm.width * stride_x + + s32 ifm_width = st->ofm.width * stride_x + st->ifm.width - (st->ifm.pad_left + st->ifm.pad_right); + if (ifm_height < 0 || ifm_width < 0) + return -EINVAL; + len = feat_matrix_length(info, &st->ifm, ifm_width, ifm_height, st->ifm.depth); dev_dbg(ddev->dev, "op %d: IFM:%d:0x%llx-0x%llx\n", @@ -352,7 +355,7 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, struct ethosu_gem_object *bo, u32 size) { - struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc(sizeof(*info), GFP_KERNEL); + struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc_obj(*info); struct ethosu_device *edev = to_ethosu_device(ddev); u32 *bocmds = bo->base.vaddr; struct cmd_state st; @@ -417,7 +420,10 @@ static int ethosu_gem_cmdstream_copy_and_validate(struct drm_device *ddev, return ret; break; case NPU_OP_ELEMENTWISE: - use_ifm2 = !((st.ifm2.broadcast == 8) || (param == 5) || + use_scale = ethosu_is_u65(edev) ? + (st.ifm2.broadcast & 0x80) : + (st.ifm2.broadcast == 8); + use_ifm2 = !(use_scale || (param == 5) || (param == 6) || (param == 7) || (param == 0x24)); use_ifm = st.ifm.broadcast != 8; ret = calc_sizes_elemwise(ddev, info, cmd, &st, use_ifm, use_ifm2); diff --git a/drivers/accel/ethosu/ethosu_job.c b/drivers/accel/ethosu/ethosu_job.c index 26e7a2f64d71..ec85f4156744 100644 --- a/drivers/accel/ethosu/ethosu_job.c +++ b/drivers/accel/ethosu/ethosu_job.c @@ -143,17 +143,10 @@ static int ethosu_job_push(struct ethosu_job *job) return ret; } -static void ethosu_job_cleanup(struct kref *ref) +static void ethosu_job_err_cleanup(struct ethosu_job *job) { - struct ethosu_job *job = container_of(ref, struct ethosu_job, - refcount); unsigned int i; - pm_runtime_put_autosuspend(job->dev->base.dev); - - dma_fence_put(job->done_fence); - dma_fence_put(job->inference_done_fence); - for (i = 0; i < job->region_cnt; i++) drm_gem_object_put(job->region_bo[i]); @@ -162,6 +155,19 @@ static void ethosu_job_cleanup(struct kref *ref) kfree(job); } +static void ethosu_job_cleanup(struct kref *ref) +{ + struct ethosu_job *job = container_of(ref, struct ethosu_job, + refcount); + + pm_runtime_put_autosuspend(job->dev->base.dev); + + dma_fence_put(job->done_fence); + dma_fence_put(job->inference_done_fence); + + ethosu_job_err_cleanup(job); +} + static void ethosu_job_put(struct ethosu_job *job) { kref_put(&job->refcount, ethosu_job_cleanup); @@ -375,7 +381,7 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file if (edev->npu_info.sram_size < job->sram_size) return -EINVAL; - ejob = kzalloc(sizeof(*ejob), GFP_KERNEL); + ejob = kzalloc_obj(*ejob); if (!ejob) return -ENOMEM; @@ -384,7 +390,7 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file ejob->dev = edev; ejob->sram_size = job->sram_size; - ejob->done_fence = kzalloc(sizeof(*ejob->done_fence), GFP_KERNEL); + ejob->done_fence = kzalloc_obj(*ejob->done_fence); if (!ejob->done_fence) { ret = -ENOMEM; goto out_cleanup_job; @@ -454,12 +460,16 @@ static int ethosu_ioctl_submit_job(struct drm_device *dev, struct drm_file *file } } ret = ethosu_job_push(ejob); + if (!ret) { + ethosu_job_put(ejob); + return 0; + } out_cleanup_job: if (ret) drm_sched_job_cleanup(&ejob->base); out_put_job: - ethosu_job_put(ejob); + ethosu_job_err_cleanup(ejob); return ret; } @@ -476,7 +486,7 @@ int ethosu_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *fil } struct drm_ethosu_job __free(kvfree) *jobs = - kvmalloc_array(args->job_count, sizeof(*jobs), GFP_KERNEL); + kvmalloc_objs(*jobs, args->job_count); if (!jobs) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/command_buffer.c b/drivers/accel/habanalabs/common/command_buffer.c index 0f0d295116e7..e929db8bc023 100644 --- a/drivers/accel/habanalabs/common/command_buffer.c +++ b/drivers/accel/habanalabs/common/command_buffer.c @@ -116,10 +116,10 @@ static struct hl_cb *hl_cb_alloc(struct hl_device *hdev, u32 cb_size, * and must use GFP_ATOMIC for all memory allocations. */ if (ctx_id == HL_KERNEL_ASID_ID && !hdev->disabled) - cb = kzalloc(sizeof(*cb), GFP_ATOMIC); + cb = kzalloc_obj(*cb, GFP_ATOMIC); if (!cb) - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc_obj(*cb); if (!cb) return NULL; diff --git a/drivers/accel/habanalabs/common/command_submission.c b/drivers/accel/habanalabs/common/command_submission.c index dee487724918..ba4257bda77b 100644 --- a/drivers/accel/habanalabs/common/command_submission.c +++ b/drivers/accel/habanalabs/common/command_submission.c @@ -907,9 +907,9 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, cntr = &hdev->aggregated_cs_counters; - cs = kzalloc(sizeof(*cs), GFP_ATOMIC); + cs = kzalloc_obj(*cs, GFP_ATOMIC); if (!cs) - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) { atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); @@ -936,9 +936,9 @@ static int allocate_cs(struct hl_device *hdev, struct hl_ctx *ctx, kref_init(&cs->refcount); spin_lock_init(&cs->job_lock); - cs_cmpl = kzalloc(sizeof(*cs_cmpl), GFP_ATOMIC); + cs_cmpl = kzalloc_obj(*cs_cmpl, GFP_ATOMIC); if (!cs_cmpl) - cs_cmpl = kzalloc(sizeof(*cs_cmpl), GFP_KERNEL); + cs_cmpl = kzalloc_obj(*cs_cmpl); if (!cs_cmpl) { atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); @@ -1302,9 +1302,9 @@ struct hl_cs_job *hl_cs_allocate_job(struct hl_device *hdev, { struct hl_cs_job *job; - job = kzalloc(sizeof(*job), GFP_ATOMIC); + job = kzalloc_obj(*job, GFP_ATOMIC); if (!job) - job = kzalloc(sizeof(*job), GFP_KERNEL); + job = kzalloc_obj(*job); if (!job) return NULL; @@ -1420,11 +1420,9 @@ static int hl_cs_copy_chunk_array(struct hl_device *hdev, return -EINVAL; } - *cs_chunk_array = kmalloc_array(num_chunks, sizeof(**cs_chunk_array), - GFP_ATOMIC); + *cs_chunk_array = kmalloc_objs(**cs_chunk_array, num_chunks, GFP_ATOMIC); if (!*cs_chunk_array) - *cs_chunk_array = kmalloc_array(num_chunks, - sizeof(**cs_chunk_array), GFP_KERNEL); + *cs_chunk_array = kmalloc_objs(**cs_chunk_array, num_chunks); if (!*cs_chunk_array) { atomic64_inc(&ctx->cs_counters.out_of_mem_drop_cnt); atomic64_inc(&hdev->aggregated_cs_counters.out_of_mem_drop_cnt); @@ -2040,7 +2038,7 @@ static int cs_ioctl_reserve_signals(struct hl_fpriv *hpriv, prop = &hdev->kernel_queues[q_idx].sync_stream_prop; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) { rc = -ENOMEM; goto out; @@ -3053,7 +3051,7 @@ static int hl_multi_cs_wait_ioctl(struct hl_fpriv *hpriv, void *data) } /* allocate array for the fences */ - fence_arr = kmalloc_array(seq_arr_len, sizeof(struct hl_fence *), GFP_KERNEL); + fence_arr = kmalloc_objs(struct hl_fence *, seq_arr_len); if (!fence_arr) { rc = -ENOMEM; goto free_seq_arr; @@ -3412,7 +3410,7 @@ static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx, goto put_cq_cb; } - pend = kzalloc(sizeof(*pend), GFP_KERNEL); + pend = kzalloc_obj(*pend); if (!pend) { rc = -ENOMEM; goto put_cq_cb; @@ -3521,7 +3519,7 @@ static int _hl_interrupt_wait_ioctl_user_addr(struct hl_device *hdev, struct hl_ hl_ctx_get(ctx); - pend = kzalloc(sizeof(*pend), GFP_KERNEL); + pend = kzalloc_obj(*pend); if (!pend) { hl_ctx_put(ctx); return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/context.c b/drivers/accel/habanalabs/common/context.c index 9f212b17611a..69c68b187bb7 100644 --- a/drivers/accel/habanalabs/common/context.c +++ b/drivers/accel/habanalabs/common/context.c @@ -155,7 +155,7 @@ int hl_ctx_create(struct hl_device *hdev, struct hl_fpriv *hpriv) struct hl_ctx *ctx; int rc; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto out_err; @@ -209,9 +209,8 @@ int hl_ctx_init(struct hl_device *hdev, struct hl_ctx *ctx, bool is_kernel_ctx) spin_lock_init(&ctx->cs_lock); atomic_set(&ctx->thread_ctx_switch_token, 1); ctx->thread_ctx_switch_wait_token = 0; - ctx->cs_pending = kcalloc(hdev->asic_prop.max_pending_cs, - sizeof(struct hl_fence *), - GFP_KERNEL); + ctx->cs_pending = kzalloc_objs(struct hl_fence *, + hdev->asic_prop.max_pending_cs); if (!ctx->cs_pending) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/debugfs.c b/drivers/accel/habanalabs/common/debugfs.c index 5f0820b19ccb..1d5e29fc6463 100644 --- a/drivers/accel/habanalabs/common/debugfs.c +++ b/drivers/accel/habanalabs/common/debugfs.c @@ -2052,7 +2052,7 @@ int hl_debugfs_device_init(struct hl_device *hdev) int count = ARRAY_SIZE(hl_debugfs_list); dev_entry->hdev = hdev; - dev_entry->entry_arr = kmalloc_array(count, sizeof(struct hl_debugfs_entry), GFP_KERNEL); + dev_entry->entry_arr = kmalloc_objs(struct hl_debugfs_entry, count); if (!dev_entry->entry_arr) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/decoder.c b/drivers/accel/habanalabs/common/decoder.c index c03a6da45d00..e4802f30c08a 100644 --- a/drivers/accel/habanalabs/common/decoder.c +++ b/drivers/accel/habanalabs/common/decoder.c @@ -98,7 +98,7 @@ int hl_dec_init(struct hl_device *hdev) if (!prop->max_dec) return 0; - hdev->dec = kcalloc(prop->max_dec, sizeof(struct hl_dec), GFP_KERNEL); + hdev->dec = kzalloc_objs(struct hl_dec, prop->max_dec); if (!hdev->dec) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/device.c b/drivers/accel/habanalabs/common/device.c index 999c92d7036e..09b27bac3a31 100644 --- a/drivers/accel/habanalabs/common/device.c +++ b/drivers/accel/habanalabs/common/device.c @@ -722,7 +722,7 @@ static int device_init_cdev(struct hl_device *hdev, const struct class *class, cdev_init(cdev, fops); cdev->owner = THIS_MODULE; - *dev = kzalloc(sizeof(**dev), GFP_KERNEL); + *dev = kzalloc_obj(**dev); if (!*dev) return -ENOMEM; @@ -892,9 +892,8 @@ static int device_early_init(struct hl_device *hdev) goto early_fini; if (hdev->asic_prop.completion_queues_count) { - hdev->cq_wq = kcalloc(hdev->asic_prop.completion_queues_count, - sizeof(struct workqueue_struct *), - GFP_KERNEL); + hdev->cq_wq = kzalloc_objs(struct workqueue_struct *, + hdev->asic_prop.completion_queues_count); if (!hdev->cq_wq) { rc = -ENOMEM; goto asid_fini; @@ -945,7 +944,7 @@ static int device_early_init(struct hl_device *hdev) goto free_ts_free_wq; } - hdev->hl_chip_info = kzalloc(sizeof(struct hwmon_chip_info), GFP_KERNEL); + hdev->hl_chip_info = kzalloc_obj(struct hwmon_chip_info); if (!hdev->hl_chip_info) { rc = -ENOMEM; goto free_prefetch_wq; @@ -1851,8 +1850,7 @@ int hl_device_reset(struct hl_device *hdev, u32 flags) } /* Allocate the kernel context */ - hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), - GFP_KERNEL); + hdev->kernel_ctx = kzalloc_obj(*hdev->kernel_ctx); if (!hdev->kernel_ctx) { rc = -ENOMEM; hl_mmu_fini(hdev); @@ -2159,8 +2157,8 @@ int hl_device_init(struct hl_device *hdev) hdev->asic_prop.user_interrupt_count; if (user_interrupt_cnt) { - hdev->user_interrupt = kcalloc(user_interrupt_cnt, sizeof(*hdev->user_interrupt), - GFP_KERNEL); + hdev->user_interrupt = kzalloc_objs(*hdev->user_interrupt, + user_interrupt_cnt); if (!hdev->user_interrupt) { rc = -ENOMEM; goto early_fini; @@ -2226,9 +2224,8 @@ int hl_device_init(struct hl_device *hdev) * passed as arguments to request_irq */ if (cq_cnt) { - hdev->completion_queue = kcalloc(cq_cnt, - sizeof(*hdev->completion_queue), - GFP_KERNEL); + hdev->completion_queue = kzalloc_objs(*hdev->completion_queue, + cq_cnt); if (!hdev->completion_queue) { dev_err(hdev->dev, @@ -2249,8 +2246,8 @@ int hl_device_init(struct hl_device *hdev) hdev->completion_queue[i].cq_idx = i; } - hdev->shadow_cs_queue = kcalloc(hdev->asic_prop.max_pending_cs, - sizeof(struct hl_cs *), GFP_KERNEL); + hdev->shadow_cs_queue = kzalloc_objs(struct hl_cs *, + hdev->asic_prop.max_pending_cs); if (!hdev->shadow_cs_queue) { rc = -ENOMEM; goto cq_fini; @@ -2275,7 +2272,7 @@ int hl_device_init(struct hl_device *hdev) } /* Allocate the kernel context */ - hdev->kernel_ctx = kzalloc(sizeof(*hdev->kernel_ctx), GFP_KERNEL); + hdev->kernel_ctx = kzalloc_obj(*hdev->kernel_ctx); if (!hdev->kernel_ctx) { rc = -ENOMEM; goto mmu_fini; diff --git a/drivers/accel/habanalabs/common/firmware_if.c b/drivers/accel/habanalabs/common/firmware_if.c index eeb6b2a80fc7..c8f1e252241d 100644 --- a/drivers/accel/habanalabs/common/firmware_if.c +++ b/drivers/accel/habanalabs/common/firmware_if.c @@ -2681,7 +2681,7 @@ static int hl_fw_dynamic_send_msg(struct hl_device *hdev, struct lkd_msg_comms *msg; int rc; - msg = kzalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc_obj(*msg); if (!msg) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/habanalabs_drv.c b/drivers/accel/habanalabs/common/habanalabs_drv.c index 0035748f3228..483e1ad9fc41 100644 --- a/drivers/accel/habanalabs/common/habanalabs_drv.c +++ b/drivers/accel/habanalabs/common/habanalabs_drv.c @@ -181,7 +181,7 @@ int hl_device_open(struct drm_device *ddev, struct drm_file *file_priv) struct hl_fpriv *hpriv; int rc; - hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); + hpriv = kzalloc_obj(*hpriv); if (!hpriv) return -ENOMEM; @@ -291,7 +291,7 @@ int hl_device_open_ctrl(struct inode *inode, struct file *filp) return -ENXIO; } - hpriv = kzalloc(sizeof(*hpriv), GFP_KERNEL); + hpriv = kzalloc_obj(*hpriv); if (!hpriv) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/habanalabs_ioctl.c b/drivers/accel/habanalabs/common/habanalabs_ioctl.c index fdfdabc85e54..fef542afe035 100644 --- a/drivers/accel/habanalabs/common/habanalabs_ioctl.c +++ b/drivers/accel/habanalabs/common/habanalabs_ioctl.c @@ -201,7 +201,7 @@ static int debug_coresight(struct hl_device *hdev, struct hl_ctx *ctx, struct hl void *input = NULL, *output = NULL; int rc; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -682,11 +682,11 @@ static int sec_attest_info(struct hl_fpriv *hpriv, struct hl_info_args *args) if ((!max_size) || (!out)) return -EINVAL; - sec_attest_info = kmalloc(sizeof(*sec_attest_info), GFP_KERNEL); + sec_attest_info = kmalloc_obj(*sec_attest_info); if (!sec_attest_info) return -ENOMEM; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { rc = -ENOMEM; goto free_sec_attest_info; @@ -731,11 +731,11 @@ static int dev_info_signed(struct hl_fpriv *hpriv, struct hl_info_args *args) if ((!max_size) || (!out)) return -EINVAL; - dev_info_signed = kzalloc(sizeof(*dev_info_signed), GFP_KERNEL); + dev_info_signed = kzalloc_obj(*dev_info_signed); if (!dev_info_signed) return -ENOMEM; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { rc = -ENOMEM; goto free_dev_info_signed; diff --git a/drivers/accel/habanalabs/common/hldio.c b/drivers/accel/habanalabs/common/hldio.c index 083ae5610875..c33c817a962a 100644 --- a/drivers/accel/habanalabs/common/hldio.c +++ b/drivers/accel/habanalabs/common/hldio.c @@ -308,7 +308,7 @@ int hl_dio_ssd2hl(struct hl_device *hdev, struct hl_ctx *ctx, int fd, dev_dbg(hdev->dev, "SSD2HL fd=%d va=%#llx len=%#lx\n", fd, device_va, len_bytes); - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kzalloc_obj(*io); if (!io) { rc = -ENOMEM; goto out; diff --git a/drivers/accel/habanalabs/common/hw_queue.c b/drivers/accel/habanalabs/common/hw_queue.c index 3d04a7507cce..4232f374dfc3 100644 --- a/drivers/accel/habanalabs/common/hw_queue.c +++ b/drivers/accel/habanalabs/common/hw_queue.c @@ -837,7 +837,7 @@ static int ext_and_cpu_queue_init(struct hl_device *hdev, struct hl_hw_queue *q, q->kernel_address = p; - q->shadow_queue = kmalloc_array(HL_QUEUE_LENGTH, sizeof(struct hl_cs_job *), GFP_KERNEL); + q->shadow_queue = kmalloc_objs(struct hl_cs_job *, HL_QUEUE_LENGTH); if (!q->shadow_queue) { dev_err(hdev->dev, "Failed to allocate shadow queue for H/W queue %d\n", @@ -1082,8 +1082,8 @@ int hl_hw_queues_create(struct hl_device *hdev) struct hl_hw_queue *q; int i, rc, q_ready_cnt; - hdev->kernel_queues = kcalloc(asic->max_queues, - sizeof(*hdev->kernel_queues), GFP_KERNEL); + hdev->kernel_queues = kzalloc_objs(*hdev->kernel_queues, + asic->max_queues); if (!hdev->kernel_queues) { dev_err(hdev->dev, "Not enough memory for H/W queues\n"); diff --git a/drivers/accel/habanalabs/common/hwmon.c b/drivers/accel/habanalabs/common/hwmon.c index 52d1e6bf10dc..768604d2392d 100644 --- a/drivers/accel/habanalabs/common/hwmon.c +++ b/drivers/accel/habanalabs/common/hwmon.c @@ -195,15 +195,15 @@ int hl_build_hwmon_channel_info(struct hl_device *hdev, struct cpucp_sensor *sen curr_arr[sensors_by_type_next_index[type]++] = flags; } - channels_info = kcalloc(num_active_sensor_types + 1, sizeof(struct hwmon_channel_info *), - GFP_KERNEL); + channels_info = kzalloc_objs(struct hwmon_channel_info *, + num_active_sensor_types + 1); if (!channels_info) { rc = -ENOMEM; goto channels_info_array_err; } for (i = 0 ; i < num_active_sensor_types ; i++) { - channels_info[i] = kzalloc(sizeof(*channels_info[i]), GFP_KERNEL); + channels_info[i] = kzalloc_obj(*channels_info[i]); if (!channels_info[i]) { rc = -ENOMEM; goto channel_info_err; diff --git a/drivers/accel/habanalabs/common/irq.c b/drivers/accel/habanalabs/common/irq.c index 7c9f2f6a2870..023dd3f1c82c 100644 --- a/drivers/accel/habanalabs/common/irq.c +++ b/drivers/accel/habanalabs/common/irq.c @@ -267,7 +267,7 @@ static int handle_registration_node(struct hl_device *hdev, struct hl_user_pendi if (!(*free_list)) { /* Alloc/Init the timestamp registration free objects list */ - *free_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); + *free_list = kmalloc_obj(struct list_head, GFP_ATOMIC); if (!(*free_list)) return -ENOMEM; @@ -283,14 +283,16 @@ static int handle_registration_node(struct hl_device *hdev, struct hl_user_pendi intr->interrupt_id); if (!(*dynamic_alloc_list)) { - *dynamic_alloc_list = kmalloc(sizeof(struct list_head), GFP_ATOMIC); + *dynamic_alloc_list = kmalloc_obj(struct list_head, + GFP_ATOMIC); if (!(*dynamic_alloc_list)) return -ENOMEM; INIT_LIST_HEAD(*dynamic_alloc_list); } - free_node = kmalloc(sizeof(struct timestamp_reg_free_node), GFP_ATOMIC); + free_node = kmalloc_obj(struct timestamp_reg_free_node, + GFP_ATOMIC); if (!free_node) return -ENOMEM; @@ -344,7 +346,7 @@ static void handle_user_interrupt_ts_list(struct hl_device *hdev, struct hl_user * and move nodes hanged on the free list back to the interrupt ts list * we always alloc the job of the WQ at the beginning. */ - job = kmalloc(sizeof(*job), GFP_ATOMIC); + job = kmalloc_obj(*job, GFP_ATOMIC); if (!job) return; @@ -542,7 +544,7 @@ irqreturn_t hl_irq_handler_eq(int irq, void *arg) goto skip_irq; } - handle_eqe_work = kmalloc(sizeof(*handle_eqe_work), GFP_ATOMIC); + handle_eqe_work = kmalloc_obj(*handle_eqe_work, GFP_ATOMIC); if (handle_eqe_work) { INIT_WORK(&handle_eqe_work->eq_work, irq_handle_eqe); handle_eqe_work->hdev = hdev; diff --git a/drivers/accel/habanalabs/common/memory.c b/drivers/accel/habanalabs/common/memory.c index 633db4bff46f..361cff577381 100644 --- a/drivers/accel/habanalabs/common/memory.c +++ b/drivers/accel/habanalabs/common/memory.c @@ -125,7 +125,7 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args, } } - phys_pg_pack = kzalloc(sizeof(*phys_pg_pack), GFP_KERNEL); + phys_pg_pack = kzalloc_obj(*phys_pg_pack); if (!phys_pg_pack) { rc = -ENOMEM; goto pages_pack_err; @@ -228,7 +228,7 @@ static int dma_map_host_va(struct hl_device *hdev, u64 addr, u64 size, struct hl_userptr *userptr; int rc; - userptr = kzalloc(sizeof(*userptr), GFP_KERNEL); + userptr = kzalloc_obj(*userptr); if (!userptr) { rc = -ENOMEM; goto userptr_err; @@ -501,7 +501,7 @@ static int add_va_block_locked(struct hl_device *hdev, res = va_block; } - va_block = kmalloc(sizeof(*va_block), GFP_KERNEL); + va_block = kmalloc_obj(*va_block); if (!va_block) return -ENOMEM; @@ -850,7 +850,7 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx, dma_addr_t dma_addr; int rc, i, j; - phys_pg_pack = kzalloc(sizeof(*phys_pg_pack), GFP_KERNEL); + phys_pg_pack = kzalloc_obj(*phys_pg_pack); if (!phys_pg_pack) return -ENOMEM; @@ -1152,7 +1152,7 @@ static int map_device_va(struct hl_ctx *ctx, struct hl_mem_in *args, u64 *device goto shared_err; } - hnode = kzalloc(sizeof(*hnode), GFP_KERNEL); + hnode = kzalloc_obj(*hnode); if (!hnode) { rc = -ENOMEM; goto hnode_err; @@ -1482,7 +1482,7 @@ int hl_hw_block_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma) return -EINVAL; } - lnode = kzalloc(sizeof(*lnode), GFP_KERNEL); + lnode = kzalloc_obj(*lnode); if (!lnode) return -ENOMEM; @@ -1553,7 +1553,7 @@ static struct sg_table *alloc_sgt_from_device_pages(struct hl_device *hdev, u64 return ERR_PTR(-EINVAL); } - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); @@ -2046,7 +2046,7 @@ static int export_dmabuf_from_addr(struct hl_ctx *ctx, u64 addr, u64 size, u64 o return -EINVAL; } - hl_dmabuf = kzalloc(sizeof(*hl_dmabuf), GFP_KERNEL); + hl_dmabuf = kzalloc_obj(*hl_dmabuf); if (!hl_dmabuf) return -ENOMEM; @@ -2116,7 +2116,7 @@ static int hl_ts_alloc_buf(struct hl_mmap_mem_buf *buf, gfp_t gfp, void *args) num_elements = *(u32 *)args; - ts_buff = kzalloc(sizeof(*ts_buff), gfp); + ts_buff = kzalloc_obj(*ts_buff, gfp); if (!ts_buff) return -ENOMEM; @@ -2323,7 +2323,7 @@ static int get_user_memory(struct hl_device *hdev, u64 addr, u64 size, return -EFAULT; } - userptr->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + userptr->pages = kvmalloc_objs(struct page *, npages); if (!userptr->pages) return -ENOMEM; @@ -2395,7 +2395,7 @@ int hl_pin_host_memory(struct hl_device *hdev, u64 addr, u64 size, } userptr->pid = current->pid; - userptr->sgt = kzalloc(sizeof(*userptr->sgt), GFP_KERNEL); + userptr->sgt = kzalloc_obj(*userptr->sgt); if (!userptr->sgt) return -ENOMEM; @@ -2611,7 +2611,7 @@ static int vm_ctx_init_with_ranges(struct hl_ctx *ctx, for (i = 0 ; i < HL_VA_RANGE_TYPE_MAX ; i++) { ctx->va_range[i] = - kzalloc(sizeof(struct hl_va_range), GFP_KERNEL); + kzalloc_obj(struct hl_va_range); if (!ctx->va_range[i]) { rc = -ENOMEM; goto free_va_range; diff --git a/drivers/accel/habanalabs/common/memory_mgr.c b/drivers/accel/habanalabs/common/memory_mgr.c index 4401beb99e42..9fdd34acf389 100644 --- a/drivers/accel/habanalabs/common/memory_mgr.c +++ b/drivers/accel/habanalabs/common/memory_mgr.c @@ -152,7 +152,7 @@ hl_mmap_mem_buf_alloc(struct hl_mem_mgr *mmg, struct hl_mmap_mem_buf *buf; int rc; - buf = kzalloc(sizeof(*buf), gfp); + buf = kzalloc_obj(*buf, gfp); if (!buf) return NULL; diff --git a/drivers/accel/habanalabs/common/mmu/mmu.c b/drivers/accel/habanalabs/common/mmu/mmu.c index 79823facce7f..6c7c4ff8a8a9 100644 --- a/drivers/accel/habanalabs/common/mmu/mmu.c +++ b/drivers/accel/habanalabs/common/mmu/mmu.c @@ -697,7 +697,7 @@ int hl_mmu_prefetch_cache_range(struct hl_ctx *ctx, u32 flags, u32 asid, u64 va, { struct hl_prefetch_work *handle_prefetch_work; - handle_prefetch_work = kmalloc(sizeof(*handle_prefetch_work), GFP_KERNEL); + handle_prefetch_work = kmalloc_obj(*handle_prefetch_work); if (!handle_prefetch_work) return -ENOMEM; @@ -843,7 +843,7 @@ int hl_mmu_hr_init(struct hl_device *hdev, struct hl_mmu_hr_priv *hr_priv, u32 h return -ENOMEM; } - hr_priv->mmu_asid_hop0 = kvcalloc(prop->max_asid, sizeof(struct pgt_info), GFP_KERNEL); + hr_priv->mmu_asid_hop0 = kvzalloc_objs(struct pgt_info, prop->max_asid); if (ZERO_OR_NULL_PTR(hr_priv->mmu_asid_hop0)) { dev_err(hdev->dev, "Failed to allocate hr-mmu hop0 table\n"); rc = -ENOMEM; @@ -1071,7 +1071,7 @@ struct pgt_info *hl_mmu_hr_alloc_hop(struct hl_ctx *ctx, struct hl_mmu_hr_priv * void *virt_addr; int i, retry = 1; - pgt_info = kmalloc(sizeof(*pgt_info), GFP_KERNEL); + pgt_info = kmalloc_obj(*pgt_info); if (!pgt_info) return NULL; @@ -1325,7 +1325,7 @@ u64 hl_mmu_dr_alloc_hop(struct hl_ctx *ctx) struct pgt_info *pgt_info; u64 phys_addr, shadow_addr; - pgt_info = kmalloc(sizeof(*pgt_info), GFP_KERNEL); + pgt_info = kmalloc_obj(*pgt_info); if (!pgt_info) return ULLONG_MAX; diff --git a/drivers/accel/habanalabs/common/security.c b/drivers/accel/habanalabs/common/security.c index 5402a3cd0491..abe5ed0d405a 100644 --- a/drivers/accel/habanalabs/common/security.c +++ b/drivers/accel/habanalabs/common/security.c @@ -312,9 +312,7 @@ int hl_init_pb_with_mask(struct hl_device *hdev, u32 num_dcores, int i, j; struct hl_block_glbl_sec *glbl_sec; - glbl_sec = kcalloc(blocks_array_size, - sizeof(struct hl_block_glbl_sec), - GFP_KERNEL); + glbl_sec = kzalloc_objs(struct hl_block_glbl_sec, blocks_array_size); if (!glbl_sec) return -ENOMEM; @@ -393,9 +391,7 @@ int hl_init_pb_ranges_with_mask(struct hl_device *hdev, u32 num_dcores, int i, j, rc = 0; struct hl_block_glbl_sec *glbl_sec; - glbl_sec = kcalloc(blocks_array_size, - sizeof(struct hl_block_glbl_sec), - GFP_KERNEL); + glbl_sec = kzalloc_objs(struct hl_block_glbl_sec, blocks_array_size); if (!glbl_sec) return -ENOMEM; @@ -476,9 +472,7 @@ int hl_init_pb_single_dcore(struct hl_device *hdev, u32 dcore_offset, int i, rc = 0; struct hl_block_glbl_sec *glbl_sec; - glbl_sec = kcalloc(blocks_array_size, - sizeof(struct hl_block_glbl_sec), - GFP_KERNEL); + glbl_sec = kzalloc_objs(struct hl_block_glbl_sec, blocks_array_size); if (!glbl_sec) return -ENOMEM; @@ -524,9 +518,7 @@ int hl_init_pb_ranges_single_dcore(struct hl_device *hdev, u32 dcore_offset, int i; struct hl_block_glbl_sec *glbl_sec; - glbl_sec = kcalloc(blocks_array_size, - sizeof(struct hl_block_glbl_sec), - GFP_KERNEL); + glbl_sec = kzalloc_objs(struct hl_block_glbl_sec, blocks_array_size); if (!glbl_sec) return -ENOMEM; diff --git a/drivers/accel/habanalabs/common/state_dump.c b/drivers/accel/habanalabs/common/state_dump.c index 3a9931f24259..1c70a363a328 100644 --- a/drivers/accel/habanalabs/common/state_dump.c +++ b/drivers/accel/habanalabs/common/state_dump.c @@ -400,7 +400,7 @@ static int hl_state_dump_print_syncs(struct hl_device *hdev, u32 index; int rc = 0; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return -ENOMEM; diff --git a/drivers/accel/habanalabs/gaudi/gaudi.c b/drivers/accel/habanalabs/gaudi/gaudi.c index 34771d75da9d..5ddb38aaff7a 100644 --- a/drivers/accel/habanalabs/gaudi/gaudi.c +++ b/drivers/accel/habanalabs/gaudi/gaudi.c @@ -539,9 +539,8 @@ static int gaudi_set_fixed_properties(struct hl_device *hdev) int i; prop->max_queues = GAUDI_QUEUE_ID_SIZE; - prop->hw_queues_props = kcalloc(prop->max_queues, - sizeof(struct hw_queue_properties), - GFP_KERNEL); + prop->hw_queues_props = kzalloc_objs(struct hw_queue_properties, + prop->max_queues); if (!prop->hw_queues_props) return -ENOMEM; @@ -1853,7 +1852,7 @@ static int gaudi_sw_init(struct hl_device *hdev) int rc; /* Allocate device structure */ - gaudi = kzalloc(sizeof(*gaudi), GFP_KERNEL); + gaudi = kzalloc_obj(*gaudi); if (!gaudi) return -ENOMEM; @@ -4906,7 +4905,7 @@ static int gaudi_pin_memory_before_cs(struct hl_device *hdev, parser->job_userptr_list, &userptr)) goto already_pinned; - userptr = kzalloc(sizeof(*userptr), GFP_KERNEL); + userptr = kzalloc_obj(*userptr); if (!userptr) return -ENOMEM; @@ -8843,7 +8842,7 @@ static int gaudi_add_sync_to_engine_map_entry( reg_value -= lower_32_bits(CFG_BASE); /* create a new hash entry */ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; entry->engine_type = engine_type; diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c b/drivers/accel/habanalabs/gaudi2/gaudi2.c index b8c0689dba64..5d9c6f0698b7 100644 --- a/drivers/accel/habanalabs/gaudi2/gaudi2.c +++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c @@ -2762,8 +2762,8 @@ static int gaudi2_set_fixed_properties(struct hl_device *hdev) int i, rc; prop->max_queues = GAUDI2_QUEUE_ID_SIZE; - prop->hw_queues_props = kcalloc(prop->max_queues, sizeof(struct hw_queue_properties), - GFP_KERNEL); + prop->hw_queues_props = kzalloc_objs(struct hw_queue_properties, + prop->max_queues); if (!prop->hw_queues_props) return -ENOMEM; @@ -3943,8 +3943,8 @@ static int gaudi2_special_blocks_config(struct hl_device *hdev) /* Configure Special blocks */ prop->glbl_err_max_cause_num = GAUDI2_GLBL_ERR_MAX_CAUSE_NUM; prop->num_of_special_blocks = ARRAY_SIZE(gaudi2_special_blocks); - prop->special_blocks = kmalloc_array(prop->num_of_special_blocks, - sizeof(*prop->special_blocks), GFP_KERNEL); + prop->special_blocks = kmalloc_objs(*prop->special_blocks, + prop->num_of_special_blocks); if (!prop->special_blocks) return -ENOMEM; @@ -3958,8 +3958,8 @@ static int gaudi2_special_blocks_config(struct hl_device *hdev) if (ARRAY_SIZE(gaudi2_iterator_skip_block_types)) { prop->skip_special_blocks_cfg.block_types = - kmalloc_array(ARRAY_SIZE(gaudi2_iterator_skip_block_types), - sizeof(gaudi2_iterator_skip_block_types[0]), GFP_KERNEL); + kmalloc_objs(gaudi2_iterator_skip_block_types[0], + ARRAY_SIZE(gaudi2_iterator_skip_block_types)); if (!prop->skip_special_blocks_cfg.block_types) { rc = -ENOMEM; goto free_special_blocks; @@ -3974,8 +3974,8 @@ static int gaudi2_special_blocks_config(struct hl_device *hdev) if (ARRAY_SIZE(gaudi2_iterator_skip_block_ranges)) { prop->skip_special_blocks_cfg.block_ranges = - kmalloc_array(ARRAY_SIZE(gaudi2_iterator_skip_block_ranges), - sizeof(gaudi2_iterator_skip_block_ranges[0]), GFP_KERNEL); + kmalloc_objs(gaudi2_iterator_skip_block_ranges[0], + ARRAY_SIZE(gaudi2_iterator_skip_block_ranges)); if (!prop->skip_special_blocks_cfg.block_ranges) { rc = -ENOMEM; goto free_skip_special_blocks_types; @@ -4054,7 +4054,7 @@ static int gaudi2_sw_init(struct hl_device *hdev) int i, rc; /* Allocate device structure */ - gaudi2 = kzalloc(sizeof(*gaudi2), GFP_KERNEL); + gaudi2 = kzalloc_obj(*gaudi2); if (!gaudi2) return -ENOMEM; diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c index 307ccb912ccd..ea3a0e57c836 100644 --- a/drivers/accel/habanalabs/gaudi2/gaudi2_security.c +++ b/drivers/accel/habanalabs/gaudi2/gaudi2_security.c @@ -2620,7 +2620,7 @@ static int gaudi2_init_pb_tpc(struct hl_device *hdev) block_array_size = ARRAY_SIZE(gaudi2_pb_dcr0_tpc0); - glbl_sec = kcalloc(block_array_size, sizeof(struct hl_block_glbl_sec), GFP_KERNEL); + glbl_sec = kzalloc_objs(struct hl_block_glbl_sec, block_array_size); if (!glbl_sec) return -ENOMEM; diff --git a/drivers/accel/habanalabs/goya/goya.c b/drivers/accel/habanalabs/goya/goya.c index 84768e306269..bf12702e0a69 100644 --- a/drivers/accel/habanalabs/goya/goya.c +++ b/drivers/accel/habanalabs/goya/goya.c @@ -363,9 +363,8 @@ int goya_set_fixed_properties(struct hl_device *hdev) int i; prop->max_queues = GOYA_QUEUE_ID_SIZE; - prop->hw_queues_props = kcalloc(prop->max_queues, - sizeof(struct hw_queue_properties), - GFP_KERNEL); + prop->hw_queues_props = kzalloc_objs(struct hw_queue_properties, + prop->max_queues); if (!prop->hw_queues_props) return -ENOMEM; @@ -970,7 +969,7 @@ static int goya_sw_init(struct hl_device *hdev) int rc; /* Allocate device structure */ - goya = kzalloc(sizeof(*goya), GFP_KERNEL); + goya = kzalloc_obj(*goya); if (!goya) return -ENOMEM; @@ -1031,7 +1030,7 @@ static int goya_sw_init(struct hl_device *hdev) hdev->asic_funcs->set_pci_memory_regions(hdev); - goya->goya_work = kmalloc(sizeof(struct goya_work_freq), GFP_KERNEL); + goya->goya_work = kmalloc_obj(struct goya_work_freq); if (!goya->goya_work) { rc = -ENOMEM; goto free_cpu_accessible_dma_pool; @@ -3336,7 +3335,7 @@ static int goya_pin_memory_before_cs(struct hl_device *hdev, parser->job_userptr_list, &userptr)) goto already_pinned; - userptr = kzalloc(sizeof(*userptr), GFP_KERNEL); + userptr = kzalloc_obj(*userptr); if (!userptr) return -ENOMEM; diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 8ffda57459df..5900a40c7a78 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -237,7 +237,7 @@ static int ivpu_open(struct drm_device *dev, struct drm_file *file) if (!drm_dev_enter(dev, &idx)) return -ENODEV; - file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); + file_priv = kzalloc_obj(*file_priv); if (!file_priv) { ret = -ENOMEM; goto err_dev_exit; diff --git a/drivers/accel/ivpu/ivpu_gem_userptr.c b/drivers/accel/ivpu/ivpu_gem_userptr.c index 25ba606164c0..7cbf3a4cdc73 100644 --- a/drivers/accel/ivpu/ivpu_gem_userptr.c +++ b/drivers/accel/ivpu/ivpu_gem_userptr.c @@ -77,7 +77,7 @@ ivpu_create_userptr_dmabuf(struct ivpu_device *vdev, void __user *user_ptr, if (!(flags & DRM_IVPU_BO_READ_ONLY)) gup_flags |= FOLL_WRITE; - pages = kvmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, nr_pages); if (!pages) return ERR_PTR(-ENOMEM); @@ -94,7 +94,7 @@ ivpu_create_userptr_dmabuf(struct ivpu_device *vdev, void __user *user_ptr, goto unpin_pages; } - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto unpin_pages; diff --git a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h index 421242acb184..fc0ee8d637f9 100644 --- a/drivers/accel/ivpu/ivpu_hw_40xx_reg.h +++ b/drivers/accel/ivpu/ivpu_hw_40xx_reg.h @@ -121,12 +121,6 @@ #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY 0x0003006cu #define VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY_STATUS_DLY_MASK GENMASK(7, 0) -#define VPU_40XX_HOST_SS_AON_RETENTION0 0x0003000cu -#define VPU_40XX_HOST_SS_AON_RETENTION1 0x00030010u -#define VPU_40XX_HOST_SS_AON_RETENTION2 0x00030014u -#define VPU_40XX_HOST_SS_AON_RETENTION3 0x00030018u -#define VPU_40XX_HOST_SS_AON_RETENTION4 0x0003001cu - #define VPU_40XX_HOST_SS_AON_IDLE_GEN 0x00030200u #define VPU_40XX_HOST_SS_AON_IDLE_GEN_EN_MASK BIT_MASK(0) #define VPU_40XX_HOST_SS_AON_IDLE_GEN_HW_PG_EN_MASK BIT_MASK(1) diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index 959984c54341..37f95a0551ed 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -931,7 +931,6 @@ static int soc_cpu_boot_40xx(struct ivpu_device *vdev) static int soc_cpu_boot_60xx(struct ivpu_device *vdev) { - REGV_WR64(VPU_40XX_HOST_SS_AON_RETENTION1, vdev->fw->mem_bp->vpu_addr); soc_cpu_set_entry_point_40xx(vdev, vdev->fw->cold_boot_entry_point); return 0; diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 1f13bf95b2b3..f47df092bb0d 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -142,7 +142,7 @@ ivpu_ipc_rx_msg_add(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons, lockdep_assert_held(&ipc->cons_lock); - rx_msg = kzalloc(sizeof(*rx_msg), GFP_ATOMIC); + rx_msg = kzalloc_obj(*rx_msg, GFP_ATOMIC); if (!rx_msg) { ivpu_ipc_rx_mark_free(vdev, ipc_hdr, jsm_msg); return; diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index 4f8564e2878a..fe02b7bd465b 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -98,7 +98,7 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv) struct ivpu_device *vdev = file_priv->vdev; struct ivpu_cmdq *cmdq; - cmdq = kzalloc(sizeof(*cmdq), GFP_KERNEL); + cmdq = kzalloc_obj(*cmdq); if (!cmdq) return NULL; @@ -491,7 +491,7 @@ static struct dma_fence *ivpu_fence_create(struct ivpu_device *vdev) { struct ivpu_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; @@ -525,7 +525,7 @@ ivpu_job_create(struct ivpu_file_priv *file_priv, u32 engine_idx, u32 bo_count) struct ivpu_device *vdev = file_priv->vdev; struct ivpu_job *job; - job = kzalloc(struct_size(job, bos, bo_count), GFP_KERNEL); + job = kzalloc_flex(*job, bos, bo_count); if (!job) return NULL; diff --git a/drivers/accel/ivpu/ivpu_ms.c b/drivers/accel/ivpu/ivpu_ms.c index 1d9c1cb17924..be43851f5f32 100644 --- a/drivers/accel/ivpu/ivpu_ms.c +++ b/drivers/accel/ivpu/ivpu_ms.c @@ -59,7 +59,7 @@ int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *fil goto unlock; } - ms = kzalloc(sizeof(*ms), GFP_KERNEL); + ms = kzalloc_obj(*ms); if (!ms) { ret = -ENOMEM; goto unlock; diff --git a/drivers/accel/qaic/mhi_controller.c b/drivers/accel/qaic/mhi_controller.c index 13a14c6c6168..4d787f77ce41 100644 --- a/drivers/accel/qaic/mhi_controller.c +++ b/drivers/accel/qaic/mhi_controller.c @@ -39,7 +39,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -55,7 +54,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -71,7 +69,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -87,7 +84,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -103,7 +99,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -119,7 +114,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -135,7 +129,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -151,7 +144,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -167,7 +159,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -183,7 +174,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -199,7 +189,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -215,7 +204,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -231,7 +219,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -247,7 +234,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -263,7 +249,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -279,7 +264,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -295,7 +279,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -311,7 +294,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -327,7 +309,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -343,7 +324,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -359,7 +339,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -375,7 +354,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -391,7 +369,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -407,7 +384,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -423,7 +399,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -439,7 +414,6 @@ static const struct mhi_channel_config aic100_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, .wake_capable = false, }, }; @@ -458,7 +432,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -474,7 +447,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -490,7 +462,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -506,7 +477,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -522,7 +492,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -538,7 +507,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -554,7 +522,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -570,7 +537,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -586,7 +552,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -602,7 +567,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -618,7 +582,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -634,7 +597,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -650,7 +612,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -666,7 +627,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -682,7 +642,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -698,7 +657,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -714,7 +672,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, .wake_capable = false, }, { @@ -730,7 +687,6 @@ static const struct mhi_channel_config aic200_channels[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, .wake_capable = false, }, }; diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c index 428d8f65bff3..f698d5dfd326 100644 --- a/drivers/accel/qaic/qaic_control.c +++ b/drivers/accel/qaic/qaic_control.c @@ -423,7 +423,8 @@ static int find_and_map_user_pages(struct qaic_device *qdev, nr_pages = need_pages; while (1) { - page_list = kmalloc_array(nr_pages, sizeof(*page_list), GFP_KERNEL | __GFP_NOWARN); + page_list = kmalloc_objs(*page_list, nr_pages, + GFP_KERNEL | __GFP_NOWARN); if (!page_list) { nr_pages = nr_pages / 2; if (!nr_pages) @@ -442,7 +443,7 @@ static int find_and_map_user_pages(struct qaic_device *qdev, goto put_pages; } - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto put_pages; @@ -581,7 +582,7 @@ static int encode_dma(struct qaic_device *qdev, void *trans, struct wrapper_list QAIC_MANAGE_WIRE_MSG_LENGTH) return -ENOMEM; - xfer = kmalloc(sizeof(*xfer), GFP_KERNEL); + xfer = kmalloc_obj(*xfer); if (!xfer) return -ENOMEM; @@ -1165,7 +1166,7 @@ static struct wrapper_list *alloc_wrapper_list(void) { struct wrapper_list *wrappers; - wrappers = kmalloc(sizeof(*wrappers), GFP_KERNEL); + wrappers = kmalloc_obj(*wrappers); if (!wrappers) return NULL; INIT_LIST_HEAD(&wrappers->list); @@ -1457,7 +1458,7 @@ void qaic_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_resu return; } - resp = kmalloc(sizeof(*resp), GFP_ATOMIC); + resp = kmalloc_obj(*resp, GFP_ATOMIC); if (!resp) { kfree(msg); return; diff --git a/drivers/accel/qaic/qaic_data.c b/drivers/accel/qaic/qaic_data.c index 60cb4d65d48e..95300c2f7d8a 100644 --- a/drivers/accel/qaic/qaic_data.c +++ b/drivers/accel/qaic/qaic_data.c @@ -213,7 +213,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl goto out; } - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto out; @@ -399,13 +399,13 @@ static int qaic_map_one_slice(struct qaic_device *qdev, struct qaic_bo *bo, if (ret) goto out; - slice = kmalloc(sizeof(*slice), GFP_KERNEL); + slice = kmalloc_obj(*slice); if (!slice) { ret = -ENOMEM; goto free_sgt; } - slice->reqs = kvcalloc(sgt->nents, sizeof(*slice->reqs), GFP_KERNEL); + slice->reqs = kvzalloc_objs(*slice->reqs, sgt->nents); if (!slice->reqs) { ret = -ENOMEM; goto free_slice; @@ -507,7 +507,7 @@ static int create_sgt(struct qaic_device *qdev, struct sg_table **sgt_out, u64 s i++; } - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto free_partial_alloc; @@ -653,7 +653,7 @@ static struct sg_table *qaic_get_sg_table(struct drm_gem_object *obj) sgt_in = bo->sgt; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); @@ -697,7 +697,7 @@ static struct qaic_bo *qaic_alloc_init_bo(void) { struct qaic_bo *bo; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); diff --git a/drivers/accel/qaic/qaic_drv.c b/drivers/accel/qaic/qaic_drv.c index 4c70bd949d53..63fb8c7b4abc 100644 --- a/drivers/accel/qaic/qaic_drv.c +++ b/drivers/accel/qaic/qaic_drv.c @@ -152,7 +152,7 @@ static int qaic_open(struct drm_device *dev, struct drm_file *file) goto dev_unlock; } - usr = kmalloc(sizeof(*usr), GFP_KERNEL); + usr = kmalloc_obj(*usr); if (!usr) { ret = -ENOMEM; goto dev_unlock; diff --git a/drivers/accel/qaic/qaic_ras.c b/drivers/accel/qaic/qaic_ras.c index f1d52a710136..cc0b75461e1a 100644 --- a/drivers/accel/qaic/qaic_ras.c +++ b/drivers/accel/qaic/qaic_ras.c @@ -556,7 +556,7 @@ static int qaic_ras_mhi_probe(struct mhi_device *mhi_dev, const struct mhi_devic if (ret) return ret; - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) { mhi_unprepare_from_transfer(mhi_dev); return -ENOMEM; diff --git a/drivers/accel/qaic/qaic_ssr.c b/drivers/accel/qaic/qaic_ssr.c index 9b662d690371..a5bb6078824b 100644 --- a/drivers/accel/qaic/qaic_ssr.c +++ b/drivers/accel/qaic/qaic_ssr.c @@ -260,7 +260,7 @@ static int send_xfer_done(struct qaic_device *qdev, void *resp, u32 dbc_id) struct ssr_debug_transfer_done *xfer_done; int ret; - xfer_done = kmalloc(sizeof(*xfer_done), GFP_KERNEL); + xfer_done = kmalloc_obj(*xfer_done); if (!xfer_done) { ret = -ENOMEM; goto out; @@ -450,14 +450,14 @@ static struct ssr_dump_info *alloc_dump_info(struct qaic_device *qdev, } /* Allocate SSR crashdump book keeping structure */ - dump_info = kzalloc(sizeof(*dump_info), GFP_KERNEL); + dump_info = kzalloc_obj(*dump_info); if (!dump_info) { ret = -ENOMEM; goto out; } /* Buffer used to send MEMORY READ request to device via MHI */ - dump_info->read_buf_req = kzalloc(sizeof(*dump_info->read_buf_req), GFP_KERNEL); + dump_info->read_buf_req = kzalloc_obj(*dump_info->read_buf_req); if (!dump_info->read_buf_req) { ret = -ENOMEM; goto free_dump_info; @@ -490,7 +490,7 @@ static int dbg_xfer_info_rsp(struct qaic_device *qdev, struct dma_bridge_chan *d struct ssr_crashdump *ssr_crash = NULL; int ret = 0, ret2; - debug_rsp = kmalloc(sizeof(*debug_rsp), GFP_KERNEL); + debug_rsp = kmalloc_obj(*debug_rsp); if (!debug_rsp) return -ENOMEM; @@ -640,7 +640,7 @@ static void ssr_worker(struct work_struct *work) break; } - event_rsp = kmalloc(sizeof(*event_rsp), GFP_KERNEL); + event_rsp = kmalloc_obj(*event_rsp); if (!event_rsp) break; diff --git a/drivers/accel/qaic/qaic_timesync.c b/drivers/accel/qaic/qaic_timesync.c index 8af2475f4f36..939462b9958d 100644 --- a/drivers/accel/qaic/qaic_timesync.c +++ b/drivers/accel/qaic/qaic_timesync.c @@ -185,7 +185,7 @@ static int qaic_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_devi struct timer_list *timer; int ret; - mqtsdev = kzalloc(sizeof(*mqtsdev), GFP_KERNEL); + mqtsdev = kzalloc_obj(*mqtsdev); if (!mqtsdev) { ret = -ENOMEM; goto out; @@ -196,7 +196,7 @@ static int qaic_timesync_probe(struct mhi_device *mhi_dev, const struct mhi_devi mqtsdev->qdev = qdev; mqtsdev->dev = &qdev->pdev->dev; - mqtsdev->sync_msg = kzalloc(sizeof(*mqtsdev->sync_msg), GFP_KERNEL); + mqtsdev->sync_msg = kzalloc_obj(*mqtsdev->sync_msg); if (!mqtsdev->sync_msg) { ret = -ENOMEM; goto free_mqts_dev; @@ -275,7 +275,7 @@ static void qaic_boot_timesync_worker(struct work_struct *work) switch (data.hdr.msg_type) { case QAIC_TS_CMD_TO_HOST: - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) break; @@ -304,7 +304,7 @@ static int qaic_boot_timesync_queue_resp(struct mhi_device *mhi_dev, struct qaic struct qts_resp *resp; int ret; - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) return -ENOMEM; diff --git a/drivers/accel/rocket/rocket_drv.c b/drivers/accel/rocket/rocket_drv.c index e4cb2efeb55a..8bbbce594883 100644 --- a/drivers/accel/rocket/rocket_drv.c +++ b/drivers/accel/rocket/rocket_drv.c @@ -38,7 +38,7 @@ rocket_iommu_domain_destroy(struct kref *kref) static struct rocket_iommu_domain* rocket_iommu_domain_create(struct device *dev) { - struct rocket_iommu_domain *domain = kmalloc(sizeof(*domain), GFP_KERNEL); + struct rocket_iommu_domain *domain = kmalloc_obj(*domain); void *err; if (!domain) @@ -79,7 +79,7 @@ rocket_open(struct drm_device *dev, struct drm_file *file) if (!try_module_get(THIS_MODULE)) return -EINVAL; - rocket_priv = kzalloc(sizeof(*rocket_priv), GFP_KERNEL); + rocket_priv = kzalloc_obj(*rocket_priv); if (!rocket_priv) { ret = -ENOMEM; goto err_put_mod; diff --git a/drivers/accel/rocket/rocket_gem.c b/drivers/accel/rocket/rocket_gem.c index 624c4ecf5a34..b6a385d2edfc 100644 --- a/drivers/accel/rocket/rocket_gem.c +++ b/drivers/accel/rocket/rocket_gem.c @@ -48,7 +48,7 @@ struct drm_gem_object *rocket_gem_create_object(struct drm_device *dev, size_t s { struct rocket_gem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/accel/rocket/rocket_job.c b/drivers/accel/rocket/rocket_job.c index acd606160dc9..ac51bff39833 100644 --- a/drivers/accel/rocket/rocket_job.c +++ b/drivers/accel/rocket/rocket_job.c @@ -45,7 +45,7 @@ static struct dma_fence *rocket_fence_create(struct rocket_core *core) { struct dma_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return ERR_PTR(-ENOMEM); @@ -71,7 +71,7 @@ rocket_copy_tasks(struct drm_device *dev, if (!rjob->task_count) return 0; - rjob->tasks = kvmalloc_array(job->task_count, sizeof(*rjob->tasks), GFP_KERNEL); + rjob->tasks = kvmalloc_objs(*rjob->tasks, job->task_count); if (!rjob->tasks) { drm_dbg(dev, "Failed to allocate task array\n"); return -ENOMEM; @@ -496,9 +496,8 @@ void rocket_job_fini(struct rocket_core *core) int rocket_job_open(struct rocket_file_priv *rocket_priv) { struct rocket_device *rdev = rocket_priv->rdev; - struct drm_gpu_scheduler **scheds = kmalloc_array(rdev->num_cores, - sizeof(*scheds), - GFP_KERNEL); + struct drm_gpu_scheduler **scheds = kmalloc_objs(*scheds, + rdev->num_cores); unsigned int core; int ret; @@ -543,7 +542,7 @@ static int rocket_ioctl_submit_job(struct drm_device *dev, struct drm_file *file if (job->task_count == 0) return -EINVAL; - rjob = kzalloc(sizeof(*rjob), GFP_KERNEL); + rjob = kzalloc_obj(*rjob); if (!rjob) return -ENOMEM; @@ -610,7 +609,7 @@ int rocket_ioctl_submit(struct drm_device *dev, void *data, struct drm_file *fil return -EINVAL; } - jobs = kvmalloc_array(args->job_count, sizeof(*jobs), GFP_KERNEL); + jobs = kvmalloc_objs(*jobs, args->job_count); if (!jobs) { drm_dbg(dev, "Failed to allocate incoming job array\n"); return -ENOMEM; diff --git a/drivers/accessibility/speakup/main.c b/drivers/accessibility/speakup/main.c index e68cf1d83787..78a77dd789a2 100644 --- a/drivers/accessibility/speakup/main.c +++ b/drivers/accessibility/speakup/main.c @@ -1353,8 +1353,8 @@ static int speakup_allocate(struct vc_data *vc, gfp_t gfp_flags) vc_num = vc->vc_num; if (!speakup_console[vc_num]) { - speakup_console[vc_num] = kzalloc(sizeof(*speakup_console[0]), - gfp_flags); + speakup_console[vc_num] = kzalloc_obj(*speakup_console[0], + gfp_flags); if (!speakup_console[vc_num]) return -ENOMEM; speakup_date(vc); diff --git a/drivers/accessibility/speakup/spk_ttyio.c b/drivers/accessibility/speakup/spk_ttyio.c index 4c0a6e1f019d..6bff78e3d872 100644 --- a/drivers/accessibility/speakup/spk_ttyio.c +++ b/drivers/accessibility/speakup/spk_ttyio.c @@ -55,7 +55,7 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) if (!tty->ops->write) return -EOPNOTSUPP; - ldisc_data = kmalloc(sizeof(*ldisc_data), GFP_KERNEL); + ldisc_data = kmalloc_obj(*ldisc_data); if (!ldisc_data) return -ENOMEM; diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index df0ff0764d0d..6f4b545f7377 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -9,6 +9,7 @@ config ARCH_SUPPORTS_ACPI menuconfig ACPI bool "ACPI (Advanced Configuration and Power Interface) Support" depends on ARCH_SUPPORTS_ACPI + select AUXILIARY_BUS select PNP select NLS select CRC32 diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 1f69be8f51a2..c5d77c3cb4bc 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -208,7 +208,7 @@ static int acpi_ac_probe(struct platform_device *pdev) struct acpi_ac *ac; int result; - ac = kzalloc(sizeof(struct acpi_ac), GFP_KERNEL); + ac = kzalloc_obj(struct acpi_ac); if (!ac) return -ENOMEM; diff --git a/drivers/acpi/acpi_apd.c b/drivers/acpi/acpi_apd.c index 49539f7528c6..bed0791c17fc 100644 --- a/drivers/acpi/acpi_apd.c +++ b/drivers/acpi/acpi_apd.c @@ -202,7 +202,7 @@ static int acpi_apd_create_device(struct acpi_device *adev, return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1; } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return -ENOMEM; diff --git a/drivers/acpi/acpi_configfs.c b/drivers/acpi/acpi_configfs.c index c970792b11a4..12ffec795803 100644 --- a/drivers/acpi/acpi_configfs.c +++ b/drivers/acpi/acpi_configfs.c @@ -210,7 +210,7 @@ static struct config_item *acpi_table_make_item(struct config_group *group, { struct acpi_table *table; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return ERR_PTR(-ENOMEM); diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index 5fba4dab5d08..8f1aeae8b72e 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -117,7 +117,7 @@ ipmi_dev_alloc(int iface, struct device *dev, acpi_handle handle) int err; struct ipmi_user *user; - ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL); + ipmi_device = kzalloc_obj(*ipmi_device); if (!ipmi_device) return NULL; @@ -197,7 +197,7 @@ static struct acpi_ipmi_msg *ipmi_msg_alloc(void) if (!ipmi) return NULL; - ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL); + ipmi_msg = kzalloc_obj(struct acpi_ipmi_msg); if (!ipmi_msg) { acpi_ipmi_dev_put(ipmi); return NULL; diff --git a/drivers/acpi/acpi_lpat.c b/drivers/acpi/acpi_lpat.c index 851f67c96097..6141c9070eca 100644 --- a/drivers/acpi/acpi_lpat.c +++ b/drivers/acpi/acpi_lpat.c @@ -104,7 +104,7 @@ struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle (obj_p->package.count % 2) || (obj_p->package.count < 4)) goto out; - lpat = kcalloc(obj_p->package.count, sizeof(int), GFP_KERNEL); + lpat = kzalloc_objs(int, obj_p->package.count); if (!lpat) goto out; @@ -117,7 +117,7 @@ struct acpi_lpat_conversion_table *acpi_lpat_get_conversion_table(acpi_handle lpat[i] = (s64)obj_e->integer.value; } - lpat_table = kzalloc(sizeof(*lpat_table), GFP_KERNEL); + lpat_table = kzalloc_obj(*lpat_table); if (!lpat_table) { kfree(lpat); goto out; diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index d0c1a71007d0..02a472fa85fc 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -80,7 +80,7 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) } } - new = kzalloc(sizeof(struct acpi_memory_info), GFP_KERNEL); + new = kzalloc_obj(struct acpi_memory_info); if (!new) return AE_ERROR; @@ -290,7 +290,7 @@ static int acpi_memory_device_add(struct acpi_device *device, if (!device) return -EINVAL; - mem_device = kzalloc(sizeof(struct acpi_memory_device), GFP_KERNEL); + mem_device = kzalloc_obj(struct acpi_memory_device); if (!mem_device) return -ENOMEM; diff --git a/drivers/acpi/acpi_mrrm.c b/drivers/acpi/acpi_mrrm.c index 6d69554c940e..e99cbda83452 100644 --- a/drivers/acpi/acpi_mrrm.c +++ b/drivers/acpi/acpi_mrrm.c @@ -81,8 +81,8 @@ static __init int acpi_parse_mrrm(struct acpi_table_header *table) return -EINVAL; } - mrrm_mem_range_entry = kmalloc_array(mre_count, sizeof(*mrrm_mem_range_entry), - GFP_KERNEL | __GFP_ZERO); + mrrm_mem_range_entry = kmalloc_objs(*mrrm_mem_range_entry, mre_count, + GFP_KERNEL | __GFP_ZERO); if (!mrrm_mem_range_entry) return -ENOMEM; @@ -161,7 +161,7 @@ static __init int add_boot_memory_ranges(void) if (!pkobj) return -ENOMEM; - kobjs = kcalloc(mrrm_mem_entry_num, sizeof(*kobjs), GFP_KERNEL); + kobjs = kzalloc_objs(*kobjs, mrrm_mem_entry_num); if (!kobjs) { kobject_put(pkobj); return -ENOMEM; diff --git a/drivers/acpi/acpi_pcc.c b/drivers/acpi/acpi_pcc.c index e3f302b9dee5..438c67189511 100644 --- a/drivers/acpi/acpi_pcc.c +++ b/drivers/acpi/acpi_pcc.c @@ -54,7 +54,7 @@ acpi_pcc_address_space_setup(acpi_handle region_handle, u32 function, struct pcc_mbox_chan *pcc_chan; acpi_status ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return AE_NO_MEMORY; diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 0ec1afc744f5..a09636a4168e 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -135,7 +135,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, } } - if (adev->device_type == ACPI_BUS_TYPE_DEVICE && !adev->pnp.type.backlight) { + if (adev->device_type == ACPI_BUS_TYPE_DEVICE) { LIST_HEAD(resource_list); count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); @@ -145,7 +145,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, if (count > 0) { struct resource_entry *rentry; - resources = kcalloc(count, sizeof(*resources), GFP_KERNEL); + resources = kzalloc_objs(*resources, count); if (!resources) { acpi_dev_free_resource_list(&resource_list); return ERR_PTR(-ENOMEM); diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c index 85096ce7b658..b34a48068a8d 100644 --- a/drivers/acpi/acpi_processor.c +++ b/drivers/acpi/acpi_processor.c @@ -428,7 +428,7 @@ static int acpi_processor_add(struct acpi_device *device, if (!acpi_device_is_enabled(device)) return -ENODEV; - pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL); + pr = kzalloc_obj(struct acpi_processor); if (!pr) return -ENOMEM; diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video.c index 69469757b965..adbaf0226c90 100644 --- a/drivers/acpi/acpi_video.c +++ b/drivers/acpi/acpi_video.c @@ -9,6 +9,7 @@ #define pr_fmt(fmt) "ACPI: video: " fmt +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -77,8 +77,9 @@ static int register_count; static DEFINE_MUTEX(register_count_mutex); static DEFINE_MUTEX(video_list_lock); static LIST_HEAD(video_bus_head); -static int acpi_video_bus_probe(struct platform_device *pdev); -static void acpi_video_bus_remove(struct platform_device *pdev); +static int acpi_video_bus_probe(struct auxiliary_device *aux_dev, + const struct auxiliary_device_id *id); +static void acpi_video_bus_remove(struct auxiliary_device *aux); static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data); /* @@ -93,19 +94,16 @@ enum acpi_video_level_idx { ACPI_VIDEO_FIRST_LEVEL, /* actual supported levels begin here */ }; -static const struct acpi_device_id video_device_ids[] = { - {ACPI_VIDEO_HID, 0}, - {"", 0}, +static const struct auxiliary_device_id video_bus_auxiliary_id_table[] = { + { .name = "acpi.video_bus" }, + {}, }; -MODULE_DEVICE_TABLE(acpi, video_device_ids); +MODULE_DEVICE_TABLE(auxiliary, video_bus_auxiliary_id_table); -static struct platform_driver acpi_video_bus = { +static struct auxiliary_driver acpi_video_bus = { .probe = acpi_video_bus_probe, .remove = acpi_video_bus_remove, - .driver = { - .name = "acpi-video", - .acpi_match_table = video_device_ids, - }, + .id_table = video_bus_auxiliary_id_table, }; struct acpi_video_bus_flags { @@ -825,7 +823,7 @@ int acpi_video_get_levels(struct acpi_device *device, goto out; } - br = kzalloc(sizeof(*br), GFP_KERNEL); + br = kzalloc_obj(*br); if (!br) { result = -ENOMEM; goto out; @@ -836,9 +834,8 @@ int acpi_video_get_levels(struct acpi_device *device, * in order to account for buggy BIOS which don't export the first two * special levels (see below) */ - br->levels = kmalloc_array(obj->package.count + ACPI_VIDEO_FIRST_LEVEL, - sizeof(*br->levels), - GFP_KERNEL); + br->levels = kmalloc_objs(*br->levels, + obj->package.count + ACPI_VIDEO_FIRST_LEVEL); if (!br->levels) { result = -ENOMEM; goto out_free; @@ -1141,7 +1138,7 @@ static int acpi_video_bus_get_one_device(struct acpi_device *device, void *arg) if (acpi_get_local_u64_address(device->handle, &device_id)) goto exit; - data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); + data = kzalloc_obj(struct acpi_video_device); if (!data) { dev_dbg(&device->dev, "Cannot attach\n"); return -ENOMEM; @@ -1330,9 +1327,8 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) acpi_handle_debug(video->device->handle, "Found %d video heads in _DOD\n", dod->package.count); - active_list = kcalloc(1 + dod->package.count, - sizeof(struct acpi_video_enumerated_device), - GFP_KERNEL); + active_list = kzalloc_objs(struct acpi_video_enumerated_device, + 1 + dod->package.count); if (!active_list) { status = -ENOMEM; goto out; @@ -1887,7 +1883,7 @@ static void acpi_video_dev_add_notify_handler(struct acpi_video_device *device) } static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video, - struct platform_device *pdev) + struct device *parent) { struct input_dev *input; struct acpi_video_device *dev; @@ -1910,7 +1906,7 @@ static int acpi_video_bus_add_notify_handler(struct acpi_video_bus *video, input->phys = video->phys; input->id.bustype = BUS_HOST; input->id.product = 0x06; - input->dev.parent = &pdev->dev; + input->dev.parent = parent; input->evbit[0] = BIT(EV_KEY); set_bit(KEY_SWITCHVIDEOMODE, input->keybit); set_bit(KEY_VIDEO_NEXT, input->keybit); @@ -1982,9 +1978,10 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video) static int instance; -static int acpi_video_bus_probe(struct platform_device *pdev) +static int acpi_video_bus_probe(struct auxiliary_device *aux_dev, + const struct auxiliary_device_id *id_unused) { - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev); struct acpi_video_bus *video; bool auto_detect; int error; @@ -2004,7 +2001,7 @@ static int acpi_video_bus_probe(struct platform_device *pdev) return -ENODEV; } - video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); + video = kzalloc_obj(struct acpi_video_bus); if (!video) return -ENOMEM; @@ -2021,7 +2018,7 @@ static int acpi_video_bus_probe(struct platform_device *pdev) instance++; } - platform_set_drvdata(pdev, video); + auxiliary_set_drvdata(aux_dev, video); video->device = device; strscpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); @@ -2070,7 +2067,7 @@ static int acpi_video_bus_probe(struct platform_device *pdev) !auto_detect) acpi_video_bus_register_backlight(video); - error = acpi_video_bus_add_notify_handler(video, pdev); + error = acpi_video_bus_add_notify_handler(video, &aux_dev->dev); if (error) goto err_del; @@ -2098,10 +2095,10 @@ static int acpi_video_bus_probe(struct platform_device *pdev) return error; } -static void acpi_video_bus_remove(struct platform_device *pdev) +static void acpi_video_bus_remove(struct auxiliary_device *aux_dev) { - struct acpi_video_bus *video = platform_get_drvdata(pdev); - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); + struct acpi_video_bus *video = auxiliary_get_drvdata(aux_dev); + struct acpi_device *device = ACPI_COMPANION(&aux_dev->dev); acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, acpi_video_bus_notify); @@ -2116,6 +2113,7 @@ static void acpi_video_bus_remove(struct platform_device *pdev) kfree(video->attached_array); kfree(video); + device->driver_data = NULL; } static int __init is_i740(struct pci_dev *dev) @@ -2164,7 +2162,7 @@ int acpi_video_register(void) dmi_check_system(video_dmi_table); - ret = platform_driver_register(&acpi_video_bus); + ret = auxiliary_driver_register(&acpi_video_bus); if (ret) goto leave; @@ -2184,7 +2182,7 @@ void acpi_video_unregister(void) { mutex_lock(®ister_count_mutex); if (register_count) { - platform_driver_unregister(&acpi_video_bus); + auxiliary_driver_unregister(&acpi_video_bus); register_count = 0; may_report_brightness_keys = false; } diff --git a/drivers/acpi/acpi_watchdog.c b/drivers/acpi/acpi_watchdog.c index 709993c535d1..c04f242a6aa2 100644 --- a/drivers/acpi/acpi_watchdog.c +++ b/drivers/acpi/acpi_watchdog.c @@ -166,7 +166,7 @@ void __init acpi_watchdog_init(void) } } - resources = kcalloc(nresources, sizeof(*resources), GFP_KERNEL); + resources = kzalloc_objs(*resources, nresources); if (!resources) goto fail_free_resource_list; diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 5f70b196e0aa..6c9b5bf7d392 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -379,8 +379,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { {{"_CPC", METHOD_0ARGS, METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Ints/Bufs) */ - PACKAGE_INFO(ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER, 0, - 0, 0, 0), + PACKAGE_INFO(ACPI_PTYPE1_VAR, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER | + ACPI_RTYPE_PACKAGE, 0, 0, 0, 0), {{"_CR3", METHOD_0ARGS, /* ACPI 6.0 */ METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 9c84f3da7c09..7a06d30bd40e 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -316,7 +316,7 @@ static int apei_res_add(struct list_head *res_list, if (res_ins) list_add(&res_ins->list, res_list); else { - res_ins = kmalloc(sizeof(*res_ins), GFP_KERNEL); + res_ins = kmalloc_obj(*res_ins); if (!res_ins) return -ENOMEM; res_ins->start = start; @@ -345,7 +345,7 @@ static int apei_res_sub(struct list_head *res_list1, break; } else if (res1->end > res2->end && res1->start < res2->start) { - res = kmalloc(sizeof(*res), GFP_KERNEL); + res = kmalloc_obj(*res); if (!res) return -ENOMEM; res->start = res2->end; diff --git a/drivers/acpi/apei/einj-core.c b/drivers/acpi/apei/einj-core.c index f5bfdffe1e43..a9248af078f6 100644 --- a/drivers/acpi/apei/einj-core.c +++ b/drivers/acpi/apei/einj-core.c @@ -1021,7 +1021,7 @@ static bool setup_einjv2_component_files(void) { char name[32]; - syndrome_data = kcalloc(max_nr_components, sizeof(syndrome_data[0]), GFP_KERNEL); + syndrome_data = kzalloc_objs(syndrome_data[0], max_nr_components); if (!syndrome_data) return false; diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index f96aede5d9a3..8acd2742bb27 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -272,7 +272,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) unsigned int error_block_length; int rc; - ghes = kzalloc(sizeof(*ghes), GFP_KERNEL); + ghes = kzalloc_obj(*ghes); if (!ghes) return ERR_PTR(-ENOMEM); diff --git a/drivers/acpi/arm64/ffh.c b/drivers/acpi/arm64/ffh.c index 877edc6557e9..04380bab193d 100644 --- a/drivers/acpi/arm64/ffh.c +++ b/drivers/acpi/arm64/ffh.c @@ -33,7 +33,7 @@ int acpi_ffh_address_space_arch_setup(void *handler_ctxt, void **region_ctxt) return -EOPNOTSUPP; } - ffh_ctxt = kzalloc(sizeof(*ffh_ctxt), GFP_KERNEL); + ffh_ctxt = kzalloc_obj(*ffh_ctxt); if (!ffh_ctxt) return -ENOMEM; diff --git a/drivers/acpi/arm64/iort.c b/drivers/acpi/arm64/iort.c index ed827b2fc437..af7a9b2fd5bc 100644 --- a/drivers/acpi/arm64/iort.c +++ b/drivers/acpi/arm64/iort.c @@ -56,7 +56,7 @@ static inline int iort_set_fwnode(struct acpi_iort_node *iort_node, { struct iort_fwnode *np; - np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC); + np = kzalloc_obj(struct iort_fwnode, GFP_ATOMIC); if (WARN_ON(!np)) return -ENOMEM; @@ -165,7 +165,7 @@ int iort_register_domain_token(int trans_id, phys_addr_t base, { struct iort_its_msi_chip *its_msi_chip; - its_msi_chip = kzalloc(sizeof(*its_msi_chip), GFP_KERNEL); + its_msi_chip = kzalloc_obj(*its_msi_chip); if (!its_msi_chip) return -ENOMEM; @@ -938,7 +938,7 @@ static struct iommu_iort_rmr_data *iort_rmr_alloc( u32 *sids_copy; u64 addr = rmr_desc->base_address, size = rmr_desc->length; - rmr_data = kmalloc(sizeof(*rmr_data), GFP_KERNEL); + rmr_data = kmalloc_obj(*rmr_data); if (!rmr_data) return NULL; @@ -1942,7 +1942,7 @@ static int __init iort_add_platform_device(struct acpi_iort_node *node, count = ops->dev_count_resources(node); - r = kcalloc(count, sizeof(*r), GFP_KERNEL); + r = kzalloc_objs(*r, count); if (!r) { ret = -ENOMEM; goto dev_put; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 3bbddd6f622c..8fbad8bc4650 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -1066,9 +1066,6 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) struct acpi_device *device = battery->device; struct power_supply *old; - if (!battery) - return; - guard(mutex)(&battery->update_lock); old = battery->bat; @@ -1274,13 +1271,9 @@ static int acpi_battery_probe(struct platform_device *pdev) static void acpi_battery_remove(struct platform_device *pdev) { - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); struct acpi_battery *battery = platform_get_drvdata(pdev); - if (!device || !battery) - return; - - acpi_dev_remove_notify_handler(device, ACPI_ALL_NOTIFY, + acpi_dev_remove_notify_handler(battery->device, ACPI_ALL_NOTIFY, acpi_battery_notify); device_init_wakeup(&pdev->dev, false); diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index b899b8745fed..97b05246efab 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -170,7 +170,7 @@ static struct platform_driver acpi_button_driver = { struct acpi_button { struct acpi_device *adev; - struct platform_device *pdev; + struct device *dev; /* physical button device */ unsigned int type; struct input_dev *input; char phys[32]; /* for input device */ @@ -398,7 +398,7 @@ static int acpi_lid_update_state(struct acpi_button *button, return state; if (state && signal_wakeup) - acpi_pm_wakeup_event(&button->pdev->dev); + acpi_pm_wakeup_event(button->dev); return acpi_lid_notify_state(button, state); } @@ -455,7 +455,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) return; } - acpi_pm_wakeup_event(&button->pdev->dev); + acpi_pm_wakeup_event(button->dev); if (button->suspended || event == ACPI_BUTTON_NOTIFY_WAKE) return; @@ -544,13 +544,13 @@ static int acpi_button_probe(struct platform_device *pdev) lid_init_state == ACPI_BUTTON_LID_INIT_DISABLED) return -ENODEV; - button = kzalloc(sizeof(struct acpi_button), GFP_KERNEL); + button = kzalloc_obj(struct acpi_button); if (!button) return -ENOMEM; platform_set_drvdata(pdev, button); - button->pdev = pdev; + button->dev = &pdev->dev; button->adev = device; button->input = input = input_allocate_device(); if (!input) { @@ -625,6 +625,8 @@ static int acpi_button_probe(struct platform_device *pdev) goto err_remove_fs; } + device_init_wakeup(button->dev, true); + switch (device->device_type) { case ACPI_BUS_TYPE_POWER_BUTTON: status = acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, @@ -655,11 +657,11 @@ static int acpi_button_probe(struct platform_device *pdev) lid_device = device; } - device_init_wakeup(&pdev->dev, true); pr_info("%s [%s]\n", name, acpi_device_bid(device)); return 0; err_input_unregister: + device_init_wakeup(button->dev, false); input_unregister_device(input); err_remove_fs: acpi_button_remove_fs(button); @@ -670,10 +672,10 @@ static int acpi_button_probe(struct platform_device *pdev) static void acpi_button_remove(struct platform_device *pdev) { - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); struct acpi_button *button = platform_get_drvdata(pdev); + struct acpi_device *adev = button->adev; - switch (device->device_type) { + switch (adev->device_type) { case ACPI_BUS_TYPE_POWER_BUTTON: acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON, acpi_button_event); @@ -683,7 +685,7 @@ static void acpi_button_remove(struct platform_device *pdev) acpi_button_event); break; default: - acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, + acpi_remove_notify_handler(adev->handle, ACPI_DEVICE_NOTIFY, button->type == ACPI_BUTTON_TYPE_LID ? acpi_lid_notify : acpi_button_notify); @@ -691,6 +693,8 @@ static void acpi_button_remove(struct platform_device *pdev) } acpi_os_wait_events_complete(); + device_init_wakeup(button->dev, false); + acpi_button_remove_fs(button); input_unregister_device(button->input); kfree(button); diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5b7e3b9ae370..f138a433554a 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -52,7 +52,7 @@ static int container_device_attach(struct acpi_device *adev, if (adev->flags.is_dock_station) return 0; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return -ENOMEM; diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index a09bdabaa804..f0e513e9ed5d 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -362,7 +362,7 @@ static int send_pcc_cmd(int pcc_ss_id, u16 cmd) end: if (cmd == CMD_WRITE) { if (unlikely(ret)) { - for_each_possible_cpu(i) { + for_each_online_cpu(i) { struct cpc_desc *desc = per_cpu(cpc_desc_ptr, i); if (!desc) @@ -524,7 +524,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; - for_each_possible_cpu(i) { + for_each_online_cpu(i) { if (i == cpu) continue; @@ -636,8 +636,7 @@ static int pcc_data_alloc(int pcc_ss_id) if (pcc_data[pcc_ss_id]) { pcc_data[pcc_ss_id]->refcount++; } else { - pcc_data[pcc_ss_id] = kzalloc(sizeof(struct cppc_pcc_data), - GFP_KERNEL); + pcc_data[pcc_ss_id] = kzalloc_obj(struct cppc_pcc_data); if (!pcc_data[pcc_ss_id]) return -ENOMEM; pcc_data[pcc_ss_id]->refcount++; @@ -712,7 +711,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) out_obj = (union acpi_object *) output.pointer; - cpc_ptr = kzalloc(sizeof(struct cpc_desc), GFP_KERNEL); + cpc_ptr = kzalloc_obj(struct cpc_desc); if (!cpc_ptr) { ret = -ENOMEM; goto out_buf_free; diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index f2579611e0a5..aa55ecfc2923 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -1456,15 +1456,6 @@ int acpi_dev_pm_attach(struct device *dev, bool power_on) if (!adev || !acpi_match_device_ids(adev, special_pm_ids)) return 0; - /* - * Skip devices whose ACPI companions don't support power management and - * don't have a wakeup GPE. - */ - if (!acpi_device_power_manageable(adev) && !acpi_device_can_wakeup(adev)) { - dev_dbg(dev, "No ACPI power management or wakeup GPE\n"); - return 0; - } - /* * Only attach the power domain to the first device if the * companion is shared by multiple. This is to prevent doing power diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 34affbda295e..d7f3a8912e6a 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -73,7 +73,7 @@ static int add_dock_dependent_device(struct dock_station *ds, { struct dock_dependent_device *dd; - dd = kzalloc(sizeof(*dd), GFP_KERNEL); + dd = kzalloc_obj(*dd); if (!dd) return -ENOMEM; diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 197970339edc..5f63ed120a2c 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -1100,7 +1100,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, if (!handle && !func) return -EINVAL; - handler = kzalloc(sizeof(*handler), GFP_KERNEL); + handler = kzalloc_obj(*handler); if (!handler) return -ENOMEM; @@ -1177,7 +1177,7 @@ static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) struct acpi_ec_query *q; struct transaction *t; - q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); + q = kzalloc_obj(struct acpi_ec_query); if (!q) return NULL; @@ -1422,7 +1422,7 @@ static void acpi_ec_free(struct acpi_ec *ec) static struct acpi_ec *acpi_ec_alloc(void) { - struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL); + struct acpi_ec *ec = kzalloc_obj(struct acpi_ec); if (!ec) return NULL; @@ -1754,12 +1754,10 @@ static int acpi_ec_probe(struct platform_device *pdev) static void acpi_ec_remove(struct platform_device *pdev) { - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); struct acpi_ec *ec = platform_get_drvdata(pdev); release_region(ec->data_addr, 1); release_region(ec->command_addr, 1); - device->driver_data = NULL; if (ec != boot_ec) { ec_remove_handlers(ec); acpi_ec_free(ec); diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index a194f30876c5..b1776809279d 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -246,7 +246,7 @@ int acpi_bind_one(struct device *dev, struct acpi_device *acpi_dev) acpi_dev_get(acpi_dev); get_device(dev); - physical_node = kzalloc(sizeof(*physical_node), GFP_KERNEL); + physical_node = kzalloc_obj(*physical_node); if (!physical_node) { retval = -ENOMEM; goto err; diff --git a/drivers/acpi/ioapic.c b/drivers/acpi/ioapic.c index 6677955b4a8e..533ddd75922b 100644 --- a/drivers/acpi/ioapic.c +++ b/drivers/acpi/ioapic.c @@ -120,7 +120,7 @@ static acpi_status handle_ioapic_add(acpi_handle handle, u32 lvl, goto exit; } - ioapic = kzalloc(sizeof(*ioapic), GFP_KERNEL); + ioapic = kzalloc_obj(*ioapic); if (!ioapic) { pr_err("cannot allocate memory for new IOAPIC\n"); goto exit; diff --git a/drivers/acpi/mipi-disco-img.c b/drivers/acpi/mipi-disco-img.c index 5b85989f96be..ea4bffe3c02d 100644 --- a/drivers/acpi/mipi-disco-img.c +++ b/drivers/acpi/mipi-disco-img.c @@ -91,8 +91,7 @@ static acpi_status parse_csi2_resource(struct acpi_resource *res, void *context) return AE_OK; } - conn = kmalloc(struct_size(conn, remote_name, csi2_res_src_length + 1), - GFP_KERNEL); + conn = kmalloc_flex(*conn, remote_name, csi2_res_src_length + 1); if (!conn) return AE_OK; @@ -111,7 +110,7 @@ static struct crs_csi2 *acpi_mipi_add_crs_csi2(acpi_handle handle, { struct crs_csi2 *csi2; - csi2 = kzalloc(sizeof(*csi2), GFP_KERNEL); + csi2 = kzalloc_obj(*csi2); if (!csi2) return NULL; diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c index e19aba02b800..d13264fb9e02 100644 --- a/drivers/acpi/nfit/core.c +++ b/drivers/acpi/nfit/core.c @@ -2271,9 +2271,9 @@ static int acpi_nfit_init_interleave_set(struct acpi_nfit_desc *acpi_desc, { u16 nr = ndr_desc->num_mappings; struct nfit_set_info2 *info2 __free(kfree) = - kcalloc(nr, sizeof(*info2), GFP_KERNEL); + kzalloc_objs(*info2, nr); struct nfit_set_info *info __free(kfree) = - kcalloc(nr, sizeof(*info), GFP_KERNEL); + kzalloc_objs(*info, nr); struct device *dev = acpi_desc->dev; struct nd_interleave_set *nd_set; int i; diff --git a/drivers/acpi/numa/hmat.c b/drivers/acpi/numa/hmat.c index 77a81627aaef..9792dc394756 100644 --- a/drivers/acpi/numa/hmat.c +++ b/drivers/acpi/numa/hmat.c @@ -202,7 +202,7 @@ static __init void alloc_memory_initiator(unsigned int cpu_pxm) if (initiator) return; - initiator = kzalloc(sizeof(*initiator), GFP_KERNEL); + initiator = kzalloc_obj(*initiator); if (!initiator) return; @@ -217,7 +217,7 @@ static __init struct memory_target *alloc_target(unsigned int mem_pxm) target = find_mem_target(mem_pxm); if (!target) { - target = kzalloc(sizeof(*target), GFP_KERNEL); + target = kzalloc_obj(*target); if (!target) return NULL; target->memory_pxm = mem_pxm; @@ -371,7 +371,7 @@ static __init void hmat_add_locality(struct acpi_hmat_locality *hmat_loc) { struct memory_locality *loc; - loc = kzalloc(sizeof(*loc), GFP_KERNEL); + loc = kzalloc_obj(*loc); if (!loc) { pr_notice_once("Failed to allocate HMAT locality\n"); return; @@ -502,7 +502,7 @@ static __init int hmat_parse_cache(union acpi_subtable_headers *header, if (!target) return 0; - tcache = kzalloc(sizeof(*tcache), GFP_KERNEL); + tcache = kzalloc_obj(*tcache); if (!tcache) { pr_notice_once("Failed to allocate HMAT cache info\n"); return 0; diff --git a/drivers/acpi/nvs.c b/drivers/acpi/nvs.c index a2b11069e792..6eaad7dd0241 100644 --- a/drivers/acpi/nvs.c +++ b/drivers/acpi/nvs.c @@ -39,7 +39,7 @@ int acpi_nvs_register(__u64 start, __u64 size) { struct nvs_region *region; - region = kmalloc(sizeof(*region), GFP_KERNEL); + region = kmalloc_obj(*region); if (!region) return -ENOMEM; region->phys_start = start; @@ -102,7 +102,7 @@ static int suspend_nvs_register(unsigned long start, unsigned long size) while (size > 0) { unsigned int nr_bytes; - entry = kzalloc(sizeof(struct nvs_page), GFP_KERNEL); + entry = kzalloc_obj(struct nvs_page); if (!entry) goto Error; diff --git a/drivers/acpi/osi.c b/drivers/acpi/osi.c index f2c943b934be..9470f1830ff5 100644 --- a/drivers/acpi/osi.c +++ b/drivers/acpi/osi.c @@ -389,6 +389,19 @@ static const struct dmi_system_id acpi_osi_dmi_table[] __initconst = { }, }, + /* + * The screen backlight turns off during udev device creation + * when returning true for _OSI("Windows 2009") + */ + { + .callback = dmi_disable_osi_win7, + .ident = "Acer Aspire One D255", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_NAME, "AOD255"), + }, + }, + /* * The wireless hotkey does not work on those machines when * returning true for _OSI("Windows 2012") diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 05393a7315fe..62b9c83d4f20 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -344,7 +344,7 @@ void __iomem __ref goto out; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { mutex_unlock(&acpi_ioremap_lock); return NULL; @@ -1117,7 +1117,7 @@ acpi_status acpi_os_execute(acpi_execute_type type, * having a static work_struct. */ - dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); + dpc = kzalloc_obj(struct acpi_os_dpc, GFP_ATOMIC); if (!dpc) return AE_NO_MEMORY; @@ -1197,7 +1197,7 @@ acpi_status acpi_hotplug_schedule(struct acpi_device *adev, u32 src) "Scheduling hotplug event %u for deferred handling\n", src); - hpw = kmalloc(sizeof(*hpw), GFP_KERNEL); + hpw = kmalloc_obj(*hpw); if (!hpw) return AE_NO_MEMORY; @@ -1681,7 +1681,7 @@ acpi_status __init acpi_os_initialize(void) * Use acpi_os_map_generic_address to pre-map the reset * register if it's in system memory. */ - void *rv; + void __iomem *rv; rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register); pr_debug("%s: Reset register mapping %s\n", __func__, diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index c416942ff3e2..8558f0ef64e3 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -147,7 +147,7 @@ static int acpi_pci_irq_check_entry(acpi_handle handle, struct pci_dev *dev, prt->pin + 1 != pin) return -ENODEV; - entry = kzalloc(sizeof(struct acpi_prt_entry), GFP_KERNEL); + entry = kzalloc_obj(struct acpi_prt_entry); if (!entry) return -ENOMEM; diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index b91b039a3d20..45bdfd06bd21 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c @@ -720,7 +720,7 @@ static int acpi_pci_link_add(struct acpi_device *device, int result; int i; - link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL); + link = kzalloc_obj(struct acpi_pci_link); if (!link) return -ENOMEM; diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index 58e10a980114..0782a5d839bf 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -304,7 +304,7 @@ static __init int pci_mcfg_parse(struct acpi_table_header *header) mcfg = (struct acpi_table_mcfg *)header; mptr = (struct acpi_mcfg_allocation *) &mcfg[1]; - arr = kcalloc(n, sizeof(*arr), GFP_KERNEL); + arr = kzalloc_objs(*arr, n); if (!arr) return -ENOMEM; diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 9d7f85dadc48..4a882e939525 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -648,7 +648,7 @@ static int acpi_pci_root_add(struct acpi_device *device, bool hotadd = system_state == SYSTEM_RUNNING; const char *acpi_hid; - root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL); + root = kzalloc_obj(struct acpi_pci_root); if (!root) return -ENOMEM; diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index 15234b65ea22..33a123074071 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c @@ -104,7 +104,7 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) return AE_OK; } - slot = kmalloc(sizeof(*slot), GFP_KERNEL); + slot = kmalloc_obj(*slot); if (!slot) return AE_OK; diff --git a/drivers/acpi/platform_profile.c b/drivers/acpi/platform_profile.c index ea04a8c69215..79d2e92e5c28 100644 --- a/drivers/acpi/platform_profile.c +++ b/drivers/acpi/platform_profile.c @@ -560,8 +560,7 @@ struct device *platform_profile_register(struct device *dev, const char *name, !ops->profile_set || !ops->probe)) return ERR_PTR(-EINVAL); - struct platform_profile_handler *pprof __free(kfree) = kzalloc( - sizeof(*pprof), GFP_KERNEL); + struct platform_profile_handler *pprof __free(kfree) = kzalloc_obj(*pprof); if (!pprof) return ERR_PTR(-ENOMEM); diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 361a7721a6a8..4611159ee734 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -104,7 +104,7 @@ static int acpi_power_resources_list_add(acpi_handle handle, if (!resource || !list) return -EINVAL; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -265,7 +265,7 @@ acpi_power_resource_add_dependent(struct acpi_power_resource *resource, goto unlock; } - dep = kzalloc(sizeof(*dep), GFP_KERNEL); + dep = kzalloc_obj(*dep); if (!dep) { ret = -ENOMEM; goto unlock; @@ -945,7 +945,7 @@ struct acpi_device *acpi_add_power_resource(acpi_handle handle) if (device) return device; - resource = kzalloc(sizeof(*resource), GFP_KERNEL); + resource = kzalloc_obj(*resource); if (!resource) return NULL; @@ -1113,6 +1113,19 @@ static const struct dmi_system_id dmi_leave_unused_power_resources_on[] = { DMI_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"), }, }, + { + /* + * THUNDEROBOT ZERO laptop: Due to its SSDT table bug, power + * resource 'PXP' will be shut down on initialization, making + * the NVMe #2 and the NVIDIA dGPU both unavailable (they're + * both controlled by 'PXP'). + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "THUNDEROBOT"), + DMI_MATCH(DMI_PRODUCT_NAME, "ZERO"), + } + + }, {} }; diff --git a/drivers/acpi/prmt.c b/drivers/acpi/prmt.c index 7b8b5d2015ec..7f5851371e5f 100644 --- a/drivers/acpi/prmt.c +++ b/drivers/acpi/prmt.c @@ -135,7 +135,7 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) goto parse_prmt_out4; memmove(tm->mmio_info, temp_mmio, mmio_range_size); } else { - tm->mmio_info = kmalloc(sizeof(*tm->mmio_info), GFP_KERNEL); + tm->mmio_info = kmalloc_obj(*tm->mmio_info); if (!tm->mmio_info) goto parse_prmt_out2; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index 81f372c64074..f6c72e3a2be1 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -910,7 +910,7 @@ static int acpi_processor_evaluate_lpi(acpi_handle handle, goto end; } - lpi_state = kcalloc(pkg_count, sizeof(*lpi_state), GFP_KERNEL); + lpi_state = kzalloc_objs(*lpi_state, pkg_count); if (!lpi_state) { ret = -ENOMEM; goto end; @@ -1417,7 +1417,7 @@ void acpi_processor_power_init(struct acpi_processor *pr) if (!pr->flags.power) return; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return; diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c index 994091bd52de..a46bd9876b11 100644 --- a/drivers/acpi/processor_pdc.c +++ b/drivers/acpi/processor_pdc.c @@ -32,11 +32,11 @@ static struct acpi_object_list *acpi_processor_alloc_pdc(void) u32 *buf; /* allocate and initialize pdc. It will be used later. */ - obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL); + obj_list = kmalloc_obj(struct acpi_object_list); if (!obj_list) goto out; - obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL); + obj = kmalloc_obj(union acpi_object); if (!obj) { kfree(obj_list); goto out; diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 8972446b7162..fdf55c285c9a 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -341,9 +341,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) pr->performance->state_count = pss->package.count; pr->performance->states = - kmalloc_array(pss->package.count, - sizeof(struct acpi_processor_px), - GFP_KERNEL); + kmalloc_objs(struct acpi_processor_px, pss->package.count); if (!pr->performance->states) { result = -ENOMEM; goto end; diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index f9c2bc1d4a3a..c0f92b93747d 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -512,9 +512,7 @@ static int acpi_processor_get_throttling_states(struct acpi_processor *pr) pr->throttling.state_count = tss->package.count; pr->throttling.states_tss = - kmalloc_array(tss->package.count, - sizeof(struct acpi_processor_tx_tss), - GFP_KERNEL); + kmalloc_objs(struct acpi_processor_tx_tss, tss->package.count); if (!pr->throttling.states_tss) { result = -ENOMEM; goto end; diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index 18e90067d567..8ee5a1f0eb48 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -89,7 +89,7 @@ static bool acpi_nondev_subnode_extract(union acpi_object *desc, if (acpi_graph_ignore_port(handle)) return false; - dn = kzalloc(sizeof(*dn), GFP_KERNEL); + dn = kzalloc_obj(*dn); if (!dn) return false; @@ -383,7 +383,7 @@ acpi_data_add_props(struct acpi_device_data *data, const guid_t *guid, { struct acpi_device_properties *props; - props = kzalloc(sizeof(*props), GFP_KERNEL); + props = kzalloc_obj(*props); if (props) { INIT_LIST_HEAD(&props->list); props->guid = guid; diff --git a/drivers/acpi/riscv/irq.c b/drivers/acpi/riscv/irq.c index d9a2154d6c6a..9b88d0993e88 100644 --- a/drivers/acpi/riscv/irq.c +++ b/drivers/acpi/riscv/irq.c @@ -136,7 +136,7 @@ static int __init riscv_acpi_register_ext_intc(u32 gsi_base, u32 nr_irqs, u32 nr { struct riscv_ext_intc_list *ext_intc_element, *node, *prev; - ext_intc_element = kzalloc(sizeof(*ext_intc_element), GFP_KERNEL); + ext_intc_element = kzalloc_obj(*ext_intc_element); if (!ext_intc_element) return -ENOMEM; @@ -342,7 +342,8 @@ static u32 riscv_acpi_add_prt_dep(acpi_handle handle) if (entry->source[0]) { acpi_get_handle(handle, entry->source, &link_handle); dep_devices.count = 1; - dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); + dep_devices.handles = kzalloc_objs(*dep_devices.handles, + 1); if (!dep_devices.handles) { acpi_handle_err(handle, "failed to allocate memory\n"); continue; @@ -353,7 +354,8 @@ static u32 riscv_acpi_add_prt_dep(acpi_handle handle) } else { gsi_handle = riscv_acpi_get_gsi_handle(entry->source_index); dep_devices.count = 1; - dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); + dep_devices.handles = kzalloc_objs(*dep_devices.handles, + 1); if (!dep_devices.handles) { acpi_handle_err(handle, "failed to allocate memory\n"); continue; @@ -382,7 +384,7 @@ static u32 riscv_acpi_add_irq_dep(acpi_handle handle) riscv_acpi_irq_get_dep(handle, i, &gsi_handle); i++) { dep_devices.count = 1; - dep_devices.handles = kcalloc(1, sizeof(*dep_devices.handles), GFP_KERNEL); + dep_devices.handles = kzalloc_objs(*dep_devices.handles, 1); if (!dep_devices.handles) { acpi_handle_err(handle, "failed to allocate memory\n"); continue; diff --git a/drivers/acpi/riscv/rimt.c b/drivers/acpi/riscv/rimt.c index 7f423405e5ef..229c4a0d47a3 100644 --- a/drivers/acpi/riscv/rimt.c +++ b/drivers/acpi/riscv/rimt.c @@ -45,7 +45,7 @@ static int rimt_set_fwnode(struct acpi_rimt_node *rimt_node, { struct rimt_fwnode *np; - np = kzalloc(sizeof(*np), GFP_ATOMIC); + np = kzalloc_obj(*np, GFP_ATOMIC); if (WARN_ON(!np)) return -ENOMEM; diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 85160e475c97..bbd3938f7b52 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -636,7 +636,7 @@ static int acpi_sbs_probe(struct platform_device *pdev) int result = 0; int id; - sbs = kzalloc(sizeof(struct acpi_sbs), GFP_KERNEL); + sbs = kzalloc_obj(struct acpi_sbs); if (!sbs) { result = -ENOMEM; goto end; diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index 7fc8ae7396d3..36850831910b 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c @@ -254,7 +254,7 @@ static int acpi_smbus_hc_probe(struct platform_device *pdev) strscpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME); strscpy(acpi_device_class(device), ACPI_SMB_HC_CLASS); - hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL); + hc = kzalloc_obj(struct acpi_smb_hc); if (!hc) return -ENOMEM; mutex_init(&hc->lock); @@ -275,13 +275,11 @@ static int acpi_smbus_hc_probe(struct platform_device *pdev) static void acpi_smbus_hc_remove(struct platform_device *pdev) { - struct acpi_device *device = ACPI_COMPANION(&pdev->dev); struct acpi_smb_hc *hc = platform_get_drvdata(pdev); acpi_ec_remove_query_handler(hc->ec, hc->query_bit); acpi_os_wait_events_complete(); kfree(hc); - device->driver_data = NULL; } module_platform_driver(acpi_smb_hc_driver); diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 565a84a7d7bc..e8cdbdb46fdb 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -6,6 +6,7 @@ #define pr_fmt(fmt) "ACPI: " fmt #include +#include #include #include #include @@ -757,8 +758,7 @@ int acpi_device_add(struct acpi_device *device) if (result) goto err_unlock; } else { - acpi_device_bus_id = kzalloc(sizeof(*acpi_device_bus_id), - GFP_KERNEL); + acpi_device_bus_id = kzalloc_obj(*acpi_device_bus_id); if (!acpi_device_bus_id) { result = -ENOMEM; goto err_unlock; @@ -1330,7 +1330,7 @@ static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id) { struct acpi_hardware_id *id; - id = kmalloc(sizeof(*id), GFP_KERNEL); + id = kmalloc_obj(*id); if (!id) return; @@ -1568,7 +1568,7 @@ int acpi_dma_get_range(struct device *dev, const struct bus_dma_region **map) ret = acpi_dev_get_dma_resources(adev, &list); if (ret > 0) { - r = kcalloc(ret + 1, sizeof(*r), GFP_KERNEL); + r = kzalloc_objs(*r, ret + 1); if (!r) { ret = -ENOMEM; goto out; @@ -1863,7 +1863,7 @@ static int acpi_add_single_object(struct acpi_device **child, bool release_dep_lock = false; int result; - device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL); + device = kzalloc_obj(struct acpi_device); if (!device) return -ENOMEM; @@ -2028,7 +2028,7 @@ int acpi_scan_add_dep(acpi_handle handle, struct acpi_handle_list *dep_devices) if (skip) continue; - dep = kzalloc(sizeof(*dep), GFP_KERNEL); + dep = kzalloc_obj(*dep); if (!dep) continue; @@ -2193,6 +2193,44 @@ static acpi_status acpi_bus_check_add_2(acpi_handle handle, u32 lvl_not_used, return acpi_bus_check_add(handle, false, (struct acpi_device **)ret_p); } +static void acpi_video_bus_device_release(struct device *dev) +{ + struct auxiliary_device *aux_dev = to_auxiliary_dev(dev); + + kfree(aux_dev); +} + +static void acpi_create_video_bus_device(struct acpi_device *adev, + struct acpi_device *parent) +{ + struct auxiliary_device *aux_dev; + static unsigned int aux_dev_id; + + aux_dev = kzalloc_obj(*aux_dev); + if (!aux_dev) + return; + + aux_dev->id = aux_dev_id++; + aux_dev->name = "video_bus"; + aux_dev->dev.parent = acpi_get_first_physical_node(parent); + if (!aux_dev->dev.parent) + goto err; + + aux_dev->dev.release = acpi_video_bus_device_release; + + if (auxiliary_device_init(aux_dev)) + goto err; + + ACPI_COMPANION_SET(&aux_dev->dev, adev); + if (__auxiliary_device_add(aux_dev, "acpi")) + auxiliary_device_uninit(aux_dev); + + return; + +err: + kfree(aux_dev); +} + struct acpi_scan_system_dev { struct list_head node; struct acpi_device *adev; @@ -2225,11 +2263,17 @@ static void acpi_default_enumeration(struct acpi_device *device) * other device objects have been processed and PCI has claimed * BARs in case there are resource conflicts. */ - sd = kmalloc(sizeof(*sd), GFP_KERNEL); + sd = kmalloc_obj(*sd); if (sd) { sd->adev = device; list_add_tail(&sd->node, &acpi_scan_system_dev_list); } + } else if (device->pnp.type.backlight) { + struct acpi_device *parent; + + parent = acpi_dev_parent(device); + if (parent) + acpi_create_video_bus_device(device, parent); } else { /* For a regular device object, create a platform device. */ acpi_create_platform_device(device, NULL); @@ -2899,7 +2943,7 @@ void acpi_scan_table_notify(void) if (!acpi_scan_initialized) return; - work = kmalloc(sizeof(*work), GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) return; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 66ec81e306d4..132a9df98471 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -386,6 +386,14 @@ static const struct dmi_system_id acpisleep_dmi_table[] __initconst = { DMI_MATCH(DMI_PRODUCT_NAME, "80E1"), }, }, + { + .callback = init_nvs_save_s3, + .ident = "Lenovo G70-35", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "80Q5"), + }, + }, /* * ThinkPad X1 Tablet(2016) cannot do suspend-to-idle using * the Low Power S0 Idle firmware interface (see diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 1bd2f555e673..a625de3c3c8b 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -385,7 +385,7 @@ acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context) switch (event) { case ACPI_TABLE_EVENT_INSTALL: - table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL); + table_attr = kzalloc_obj(*table_attr); if (!table_attr) return AE_NO_MEMORY; @@ -491,7 +491,7 @@ static int acpi_table_data_init(struct acpi_table_header *th) for (i = 0; i < NUM_ACPI_DATA_OBJS; i++) { if (ACPI_COMPARE_NAMESEG(th->signature, acpi_data_objs[i].name)) { - data_attr = kzalloc(sizeof(*data_attr), GFP_KERNEL); + data_attr = kzalloc_obj(*data_attr); if (!data_attr) return -ENOMEM; sysfs_attr_init(&data_attr->attr.attr); @@ -532,7 +532,7 @@ static int acpi_tables_sysfs_init(void) if (ACPI_FAILURE(status)) continue; - table_attr = kzalloc(sizeof(*table_attr), GFP_KERNEL); + table_attr = kzalloc_obj(*table_attr); if (!table_attr) return -ENOMEM; @@ -864,11 +864,11 @@ void acpi_irq_stats_init(void) num_gpes = acpi_current_gpe_count; num_counters = num_gpes + ACPI_NUM_FIXED_EVENTS + NUM_COUNTERS_EXTRA; - all_attrs = kcalloc(num_counters + 1, sizeof(*all_attrs), GFP_KERNEL); + all_attrs = kzalloc_objs(*all_attrs, num_counters + 1); if (all_attrs == NULL) return; - all_counters = kcalloc(num_counters, sizeof(*all_counters), GFP_KERNEL); + all_counters = kzalloc_objs(*all_counters, num_counters); if (all_counters == NULL) goto fail; @@ -876,7 +876,7 @@ void acpi_irq_stats_init(void) if (ACPI_FAILURE(status)) goto fail; - counter_attrs = kcalloc(num_counters, sizeof(*counter_attrs), GFP_KERNEL); + counter_attrs = kzalloc_objs(*counter_attrs, num_counters); if (counter_attrs == NULL) goto fail; diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index e9d3ab18b404..64356b004a57 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -792,7 +792,7 @@ static int acpi_thermal_probe(struct platform_device *pdev) if (!device) return -EINVAL; - tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); + tz = kzalloc_obj(struct acpi_thermal); if (!tz) return -ENOMEM; diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 526563a0d188..6ab27e4826d1 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c @@ -365,7 +365,7 @@ bool acpi_evaluate_reference(acpi_handle handle, acpi_string pathname, goto err; list->count = package->package.count; - list->handles = kcalloc(list->count, sizeof(*list->handles), GFP_KERNEL); + list->handles = kzalloc_objs(*list->handles, list->count); if (!list->handles) goto err_clear; diff --git a/drivers/acpi/viot.c b/drivers/acpi/viot.c index c13a20365c2c..c05fcc060e63 100644 --- a/drivers/acpi/viot.c +++ b/drivers/acpi/viot.c @@ -142,7 +142,7 @@ static struct viot_iommu * __init viot_get_iommu(unsigned int offset) if (viot_check_bounds(hdr)) return NULL; - viommu = kzalloc(sizeof(*viommu), GFP_KERNEL); + viommu = kzalloc_obj(*viommu); if (!viommu) return NULL; @@ -193,7 +193,7 @@ static int __init viot_parse_node(const struct acpi_viot_header *hdr) hdr->type == ACPI_VIOT_NODE_VIRTIO_IOMMU_MMIO) return 0; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index ff6dc957bc11..0cbee0f06f0d 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -120,7 +120,7 @@ int acpi_register_wakeup_handler(int wake_irq, bool (*wakeup)(void *context), if (!acpi_sci_irq_valid() || wake_irq != acpi_sci_irq) return 0; - handler = kmalloc(sizeof(*handler), GFP_KERNEL); + handler = kmalloc_obj(*handler); if (!handler) return -ENOMEM; diff --git a/drivers/acpi/x86/lpss.c b/drivers/acpi/x86/lpss.c index 1dcb80ab0d23..0171eef00484 100644 --- a/drivers/acpi/x86/lpss.c +++ b/drivers/acpi/x86/lpss.c @@ -623,7 +623,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev, if (!dev_desc) return -EINVAL; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return -ENOMEM; diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c index b43d10f986a2..b6b1dd76a06b 100644 --- a/drivers/acpi/x86/s2idle.c +++ b/drivers/acpi/x86/s2idle.c @@ -129,9 +129,8 @@ static void lpi_device_get_constraints_amd(void) goto free_acpi_buffer; } - lpi_constraints_table = kcalloc(package->package.count, - sizeof(*lpi_constraints_table), - GFP_KERNEL); + lpi_constraints_table = kzalloc_objs(*lpi_constraints_table, + package->package.count); if (!lpi_constraints_table) goto free_acpi_buffer; @@ -209,9 +208,8 @@ static void lpi_device_get_constraints(void) if (!out_obj) return; - lpi_constraints_table = kcalloc(out_obj->package.count, - sizeof(*lpi_constraints_table), - GFP_KERNEL); + lpi_constraints_table = kzalloc_objs(*lpi_constraints_table, + out_obj->package.count); if (!lpi_constraints_table) goto free_acpi_buffer; diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c index 4ee30c2897a2..418951639f51 100644 --- a/drivers/acpi/x86/utils.c +++ b/drivers/acpi/x86/utils.c @@ -81,6 +81,18 @@ static const struct override_status_id override_status_ids[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), }), + /* + * Lenovo Yoga Book uses PWM2 for touch keyboard backlight control. + * It needs to be enabled only for the Android device version (YB1-X90* + * aka YETI-11); the Windows version (YB1-X91*) uses ACPI control + * methods. + */ + PRESENT_ENTRY_HID("80862289", "2", INTEL_ATOM_AIRMONT, { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "YETI-11"), + }), + /* * The INT0002 device is necessary to clear wakeup interrupt sources * on Cherry Trail devices, without it we get nobody cared IRQ msgs. diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 952c45ca6e48..6d479caf89cb 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -611,7 +611,7 @@ struct amba_device *amba_device_alloc(const char *name, resource_size_t base, { struct amba_device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev) { amba_device_initialize(dev, name); dev->res.start = base; diff --git a/drivers/android/binder.c b/drivers/android/binder.c index bd780d88b468..21f91d9f2fbc 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -795,7 +795,7 @@ static struct binder_node *binder_new_node(struct binder_proc *proc, struct flat_binder_object *fp) { struct binder_node *node; - struct binder_node *new_node = kzalloc(sizeof(*node), GFP_KERNEL); + struct binder_node *new_node = kzalloc_obj(*node); if (!new_node) return NULL; @@ -1469,7 +1469,7 @@ static int binder_inc_ref_for_node(struct binder_proc *proc, ref = binder_get_ref_for_node_olocked(proc, node, NULL); if (!ref) { binder_proc_unlock(proc); - new_ref = kzalloc(sizeof(*ref), GFP_KERNEL); + new_ref = kzalloc_obj(*ref); if (!new_ref) return -ENOMEM; binder_proc_lock(proc); @@ -2009,7 +2009,7 @@ static void binder_deferred_fd_close(int fd) { struct binder_task_work_cb *twcb; - twcb = kzalloc(sizeof(*twcb), GFP_KERNEL); + twcb = kzalloc_obj(*twcb); if (!twcb) return; init_task_work(&twcb->twork, binder_do_fd_close); @@ -2386,7 +2386,7 @@ static int binder_translate_fd(u32 fd, binder_size_t fd_offset, * of the fd in the target needs to be done from a * target thread. */ - fixup = kzalloc(sizeof(*fixup), GFP_KERNEL); + fixup = kzalloc_obj(*fixup); if (!fixup) { ret = -ENOMEM; goto err_alloc; @@ -2579,7 +2579,7 @@ static void binder_cleanup_deferred_txn_lists(struct list_head *sgc_head, static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset, const void __user *sender_uaddr, size_t length) { - struct binder_sg_copy *bc = kzalloc(sizeof(*bc), GFP_KERNEL); + struct binder_sg_copy *bc = kzalloc_obj(*bc); if (!bc) return -ENOMEM; @@ -2622,7 +2622,7 @@ static int binder_defer_copy(struct list_head *sgc_head, binder_size_t offset, static int binder_add_fixup(struct list_head *pf_head, binder_size_t offset, binder_uintptr_t fixup, size_t skip_size) { - struct binder_ptr_fixup *pf = kzalloc(sizeof(*pf), GFP_KERNEL); + struct binder_ptr_fixup *pf = kzalloc_obj(*pf); struct binder_ptr_fixup *tmppf; if (!pf) @@ -3101,7 +3101,7 @@ static void binder_transaction(struct binder_proc *proc, binder_set_extended_error(&thread->ee, t_debug_id, BR_OK, 0); binder_inner_proc_unlock(proc); - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) { binder_txn_error("%d:%d cannot allocate transaction\n", thread->pid, proc->pid); @@ -3320,7 +3320,7 @@ static void binder_transaction(struct binder_proc *proc, e->to_thread = target_thread->pid; e->to_proc = target_proc->pid; - tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL); + tcomplete = kzalloc_obj(*tcomplete); if (tcomplete == NULL) { binder_txn_error("%d:%d cannot allocate work for transaction\n", thread->pid, proc->pid); @@ -3926,7 +3926,7 @@ binder_request_freeze_notification(struct binder_proc *proc, struct binder_ref_freeze *freeze; struct binder_ref *ref; - freeze = kzalloc(sizeof(*freeze), GFP_KERNEL); + freeze = kzalloc_obj(*freeze); if (!freeze) return -ENOMEM; binder_proc_lock(proc); @@ -4394,7 +4394,7 @@ static int binder_thread_write(struct binder_proc *proc, * Allocate memory for death notification * before taking lock */ - death = kzalloc(sizeof(*death), GFP_KERNEL); + death = kzalloc_obj(*death); if (death == NULL) { WARN_ON(thread->return_error.cmd != BR_OK); @@ -4523,7 +4523,7 @@ static int binder_thread_write(struct binder_proc *proc, } } binder_debug(BINDER_DEBUG_DEAD_BINDER, - "%d:%d BC_DEAD_BINDER_DONE %016llx found %pK\n", + "%d:%d BC_DEAD_BINDER_DONE %016llx found %p\n", proc->pid, thread->pid, (u64)cookie, death); if (death == NULL) { @@ -5293,7 +5293,7 @@ static struct binder_thread *binder_get_thread(struct binder_proc *proc) thread = binder_get_thread_ilocked(proc, NULL); binder_inner_proc_unlock(proc); if (!thread) { - new_thread = kzalloc(sizeof(*thread), GFP_KERNEL); + new_thread = kzalloc_obj(*thread); if (new_thread == NULL) return NULL; binder_inner_proc_lock(proc); @@ -5902,9 +5902,8 @@ static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) goto err; } - target_procs = kcalloc(target_procs_count, - sizeof(struct binder_proc *), - GFP_KERNEL); + target_procs = kzalloc_objs(struct binder_proc *, + target_procs_count); if (!target_procs) { mutex_unlock(&binder_procs_lock); @@ -6061,7 +6060,7 @@ static int binder_open(struct inode *nodp, struct file *filp) binder_debug(BINDER_DEBUG_OPEN_CLOSE, "%s: %d:%d\n", __func__, current->tgid, current->pid); - proc = kzalloc(sizeof(*proc), GFP_KERNEL); + proc = kzalloc_obj(*proc); if (proc == NULL) return -ENOMEM; @@ -7065,7 +7064,7 @@ static int __init init_binder_device(const char *name) int ret; struct binder_device *binder_device; - binder_device = kzalloc(sizeof(*binder_device), GFP_KERNEL); + binder_device = kzalloc_obj(*binder_device); if (!binder_device) return -ENOMEM; diff --git a/drivers/android/binder/context.rs b/drivers/android/binder/context.rs index 3d135ec03ca7..9cf437c025a2 100644 --- a/drivers/android/binder/context.rs +++ b/drivers/android/binder/context.rs @@ -3,8 +3,8 @@ // Copyright (C) 2025 Google LLC. use kernel::{ - error::Error, - list::{List, ListArc, ListLinks}, + alloc::kvec::KVVec, + error::code::*, prelude::*, security, str::{CStr, CString}, @@ -17,22 +17,19 @@ kernel::sync::global_lock! { // SAFETY: We call `init` in the module initializer, so it's initialized before first use. pub(crate) unsafe(uninit) static CONTEXTS: Mutex = ContextList { - list: List::new(), + contexts: KVVec::new(), }; } pub(crate) struct ContextList { - list: List, + contexts: KVVec>, } -pub(crate) fn get_all_contexts() -> Result>> { +pub(crate) fn get_all_contexts() -> Result>> { let lock = CONTEXTS.lock(); - - let count = lock.list.iter().count(); - - let mut ctxs = KVec::with_capacity(count, GFP_KERNEL)?; - for ctx in &lock.list { - ctxs.push(Arc::from(ctx), GFP_KERNEL)?; + let mut ctxs = KVVec::with_capacity(lock.contexts.len(), GFP_KERNEL)?; + for ctx in lock.contexts.iter() { + ctxs.push(ctx.clone(), GFP_KERNEL)?; } Ok(ctxs) } @@ -42,7 +39,7 @@ pub(crate) fn get_all_contexts() -> Result>> { struct Manager { node: Option, uid: Option, - all_procs: List, + all_procs: KVVec>, } /// There is one context per binder file (/dev/binder, /dev/hwbinder, etc) @@ -51,28 +48,16 @@ pub(crate) struct Context { #[pin] manager: Mutex, pub(crate) name: CString, - #[pin] - links: ListLinks, -} - -kernel::list::impl_list_arc_safe! { - impl ListArcSafe<0> for Context { untracked; } -} -kernel::list::impl_list_item! { - impl ListItem<0> for Context { - using ListLinks { self.links }; - } } impl Context { pub(crate) fn new(name: &CStr) -> Result> { let name = CString::try_from(name)?; - let list_ctx = ListArc::pin_init::( + let ctx = Arc::pin_init( try_pin_init!(Context { name, - links <- ListLinks::new(), manager <- kernel::new_mutex!(Manager { - all_procs: List::new(), + all_procs: KVVec::new(), node: None, uid: None, }, "Context::manager"), @@ -80,8 +65,7 @@ pub(crate) fn new(name: &CStr) -> Result> { GFP_KERNEL, )?; - let ctx = list_ctx.clone_arc(); - CONTEXTS.lock().list.push_back(list_ctx); + CONTEXTS.lock().contexts.push(ctx.clone(), GFP_KERNEL)?; Ok(ctx) } @@ -89,27 +73,27 @@ pub(crate) fn new(name: &CStr) -> Result> { /// Called when the file for this context is unlinked. /// /// No-op if called twice. - pub(crate) fn deregister(&self) { - // SAFETY: We never add the context to any other linked list than this one, so it is either - // in this list, or not in any list. - unsafe { CONTEXTS.lock().list.remove(self) }; + pub(crate) fn deregister(self: &Arc) { + // Safe removal using retain + CONTEXTS.lock().contexts.retain(|c| !Arc::ptr_eq(c, self)); } - pub(crate) fn register_process(self: &Arc, proc: ListArc) { + pub(crate) fn register_process(self: &Arc, proc: Arc) -> Result { if !Arc::ptr_eq(self, &proc.ctx) { pr_err!("Context::register_process called on the wrong context."); - return; + return Err(EINVAL); } - self.manager.lock().all_procs.push_back(proc); + self.manager.lock().all_procs.push(proc, GFP_KERNEL)?; + Ok(()) } - pub(crate) fn deregister_process(self: &Arc, proc: &Process) { + pub(crate) fn deregister_process(self: &Arc, proc: &Arc) { if !Arc::ptr_eq(self, &proc.ctx) { pr_err!("Context::deregister_process called on the wrong context."); return; } - // SAFETY: We just checked that this is the right list. - unsafe { self.manager.lock().all_procs.remove(proc) }; + let mut manager = self.manager.lock(); + manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc)); } pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { @@ -154,27 +138,27 @@ pub(crate) fn for_each_proc(&self, mut func: F) { let lock = self.manager.lock(); for proc in &lock.all_procs { - func(&proc); + func(proc); } } - pub(crate) fn get_all_procs(&self) -> Result>> { + pub(crate) fn get_all_procs(&self) -> Result>> { let lock = self.manager.lock(); - let count = lock.all_procs.iter().count(); - - let mut procs = KVec::with_capacity(count, GFP_KERNEL)?; - for proc in &lock.all_procs { - procs.push(Arc::from(proc), GFP_KERNEL)?; + let mut procs = KVVec::with_capacity(lock.all_procs.len(), GFP_KERNEL)?; + for proc in lock.all_procs.iter() { + procs.push(Arc::clone(proc), GFP_KERNEL)?; } Ok(procs) } - pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result>> { - let orig = self.get_all_procs()?; - let mut backing = KVec::with_capacity(orig.len(), GFP_KERNEL)?; - for proc in orig.into_iter().filter(|proc| proc.task.pid() == pid) { - backing.push(proc, GFP_KERNEL)?; + pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result>> { + let lock = self.manager.lock(); + let mut matching_procs = KVVec::new(); + for proc in lock.all_procs.iter() { + if proc.task.pid() == pid { + matching_procs.push(Arc::clone(proc), GFP_KERNEL)?; + } } - Ok(backing) + Ok(matching_procs) } } diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs index c26d113ede96..69f757ff7461 100644 --- a/drivers/android/binder/node.rs +++ b/drivers/android/binder/node.rs @@ -178,6 +178,14 @@ struct NodeInner { refs: List, } +use kernel::bindings::rb_node_layout; +use mem::offset_of; +pub(crate) const NODE_LAYOUT: rb_node_layout = rb_node_layout { + arc_offset: Arc::::DATA_OFFSET + offset_of!(DTRWrap, wrapped), + debug_id: offset_of!(Node, debug_id), + ptr: offset_of!(Node, ptr), +}; + #[pin_data] pub(crate) struct Node { pub(crate) debug_id: usize, diff --git a/drivers/android/binder/page_range.rs b/drivers/android/binder/page_range.rs index fdd97112ef5c..9dfc154e5dd4 100644 --- a/drivers/android/binder/page_range.rs +++ b/drivers/android/binder/page_range.rs @@ -142,6 +142,30 @@ pub(crate) struct ShrinkablePageRange { _pin: PhantomPinned, } +// We do not define any ops. For now, used only to check identity of vmas. +static BINDER_VM_OPS: bindings::vm_operations_struct = pin_init::zeroed(); + +// To ensure that we do not accidentally install pages into or zap pages from the wrong vma, we +// check its vm_ops and private data before using it. +fn check_vma(vma: &virt::VmaRef, owner: *const ShrinkablePageRange) -> Option<&virt::VmaMixedMap> { + // SAFETY: Just reading the vm_ops pointer of any active vma is safe. + let vm_ops = unsafe { (*vma.as_ptr()).vm_ops }; + if !ptr::eq(vm_ops, &BINDER_VM_OPS) { + return None; + } + + // SAFETY: Reading the vm_private_data pointer of a binder-owned vma is safe. + let vm_private_data = unsafe { (*vma.as_ptr()).vm_private_data }; + // The ShrinkablePageRange is only dropped when the Process is dropped, which only happens once + // the file's ->release handler is invoked, which means the ShrinkablePageRange outlives any + // VMA associated with it, so there can't be any false positives due to pointer reuse here. + if !ptr::eq(vm_private_data, owner.cast()) { + return None; + } + + vma.as_mixedmap_vma() +} + struct Inner { /// Array of pages. /// @@ -308,6 +332,18 @@ pub(crate) fn register_with_vma(&self, vma: &virt::VmaNew) -> Result { inner.size = num_pages; inner.vma_addr = vma.start(); + // This pointer is only used for comparison - it's not dereferenced. + // + // SAFETY: We own the vma, and we don't use any methods on VmaNew that rely on + // `vm_private_data`. + unsafe { + (*vma.as_ptr()).vm_private_data = ptr::from_ref(self).cast_mut().cast::() + }; + + // SAFETY: We own the vma, and we don't use any methods on VmaNew that rely on + // `vm_ops`. + unsafe { (*vma.as_ptr()).vm_ops = &BINDER_VM_OPS }; + Ok(num_pages) } @@ -399,22 +435,25 @@ unsafe fn use_page_slow(&self, i: usize) -> Result<()> { // // Using `mmput_async` avoids this, because then the `mm` cleanup is instead queued to a // workqueue. - MmWithUser::into_mmput_async(self.mm.mmget_not_zero().ok_or(ESRCH)?) - .mmap_read_lock() - .vma_lookup(vma_addr) - .ok_or(ESRCH)? - .as_mixedmap_vma() - .ok_or(ESRCH)? - .vm_insert_page(user_page_addr, &new_page) - .inspect_err(|err| { - pr_warn!( - "Failed to vm_insert_page({}): vma_addr:{} i:{} err:{:?}", - user_page_addr, - vma_addr, - i, - err - ) - })?; + let mm = MmWithUser::into_mmput_async(self.mm.mmget_not_zero().ok_or(ESRCH)?); + { + let vma_read; + let mmap_read; + let vma = if let Some(ret) = mm.lock_vma_under_rcu(vma_addr) { + vma_read = ret; + check_vma(&vma_read, self) + } else { + mmap_read = mm.mmap_read_lock(); + mmap_read + .vma_lookup(vma_addr) + .and_then(|vma| check_vma(vma, self)) + }; + + match vma { + Some(vma) => vma.vm_insert_page(user_page_addr, &new_page)?, + None => return Err(ESRCH), + } + } let inner = self.lock.lock(); @@ -667,12 +706,15 @@ fn drop(self: Pin<&mut Self>) { let mmap_read; let mm_mutex; let vma_addr; + let range_ptr; { // CAST: The `list_head` field is first in `PageInfo`. let info = item as *mut PageInfo; // SAFETY: The `range` field of `PageInfo` is immutable. - let range = unsafe { &*((*info).range) }; + range_ptr = unsafe { (*info).range }; + // SAFETY: The `range` outlives its `PageInfo` values. + let range = unsafe { &*range_ptr }; mm = match range.mm.mmget_not_zero() { Some(mm) => MmWithUser::into_mmput_async(mm), @@ -717,9 +759,11 @@ fn drop(self: Pin<&mut Self>) { // SAFETY: The lru lock is locked when this method is called. unsafe { bindings::spin_unlock(&raw mut (*lru).lock) }; - if let Some(vma) = mmap_read.vma_lookup(vma_addr) { - let user_page_addr = vma_addr + (page_index << PAGE_SHIFT); - vma.zap_page_range_single(user_page_addr, PAGE_SIZE); + if let Some(unchecked_vma) = mmap_read.vma_lookup(vma_addr) { + if let Some(vma) = check_vma(unchecked_vma, range_ptr) { + let user_page_addr = vma_addr + (page_index << PAGE_SHIFT); + vma.zap_page_range_single(user_page_addr, PAGE_SIZE); + } } drop(mmap_read); diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs index 132055b4790f..f06498129aa9 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -28,11 +28,11 @@ seq_print, sync::poll::PollTable, sync::{ + aref::ARef, lock::{spinlock::SpinLockBackend, Guard}, Arc, ArcBorrow, CondVar, CondVarTimeoutResult, Mutex, SpinLock, UniqueArc, }, task::Task, - types::ARef, uaccess::{UserSlice, UserSliceReader}, uapi, workqueue::{self, Work}, @@ -418,6 +418,13 @@ fn new() -> Self { } } +use core::mem::offset_of; +use kernel::bindings::rb_process_layout; +pub(crate) const PROCESS_LAYOUT: rb_process_layout = rb_process_layout { + arc_offset: Arc::::DATA_OFFSET, + task: offset_of!(Process, task), +}; + /// A process using binder. /// /// Strictly speaking, there can be multiple of these per process. There is one for each binder fd @@ -496,7 +503,7 @@ fn run(me: Arc) { impl Process { fn new(ctx: Arc, cred: ARef) -> Result> { let current = kernel::current!(); - let list_process = ListArc::pin_init::( + let process = Arc::pin_init::( try_pin_init!(Process { ctx, cred, @@ -512,8 +519,7 @@ fn new(ctx: Arc, cred: ARef) -> Result> { GFP_KERNEL, )?; - let process = list_process.clone_arc(); - process.ctx.register_process(list_process); + process.ctx.register_process(process.clone())?; Ok(process) } @@ -1289,7 +1295,8 @@ pub(crate) fn clear_death(&self, reader: &mut UserSliceReader, thread: &Thread) } pub(crate) fn dead_binder_done(&self, cookie: u64, thread: &Thread) { - if let Some(death) = self.inner.lock().pull_delivered_death(cookie) { + let death = self.inner.lock().pull_delivered_death(cookie); + if let Some(death) = death { death.set_notification_done(thread); } } diff --git a/drivers/android/binder/range_alloc/array.rs b/drivers/android/binder/range_alloc/array.rs index 07e1dec2ce63..ada1d1b4302e 100644 --- a/drivers/android/binder/range_alloc/array.rs +++ b/drivers/android/binder/range_alloc/array.rs @@ -118,7 +118,7 @@ pub(crate) fn reserve_new( size: usize, is_oneway: bool, pid: Pid, - ) -> Result { + ) -> Result<(usize, bool)> { // Compute new value of free_oneway_space, which is set only on success. let new_oneway_space = if is_oneway { match self.free_oneway_space.checked_sub(size) { @@ -146,7 +146,38 @@ pub(crate) fn reserve_new( .ok() .unwrap(); - Ok(insert_at_offset) + // Start detecting spammers once we have less than 20% + // of async space left (which is less than 10% of total + // buffer size). + // + // (This will short-circuit, so `low_oneway_space` is + // only called when necessary.) + let oneway_spam_detected = + is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); + + Ok((insert_at_offset, oneway_spam_detected)) + } + + /// Find the amount and size of buffers allocated by the current caller. + /// + /// The idea is that once we cross the threshold, whoever is responsible + /// for the low async space is likely to try to send another async transaction, + /// and at some point we'll catch them in the act. This is more efficient + /// than keeping a map per pid. + fn low_oneway_space(&self, calling_pid: Pid) -> bool { + let mut total_alloc_size = 0; + let mut num_buffers = 0; + + // Warn if this pid has more than 50 transactions, or more than 50% of + // async space (which is 25% of total buffer size). Oneway spam is only + // detected when the threshold is exceeded. + for range in &self.ranges { + if range.state.is_oneway() && range.state.pid() == calling_pid { + total_alloc_size += range.size; + num_buffers += 1; + } + } + num_buffers > 50 || total_alloc_size > self.size / 4 } pub(crate) fn reservation_abort(&mut self, offset: usize) -> Result { diff --git a/drivers/android/binder/range_alloc/mod.rs b/drivers/android/binder/range_alloc/mod.rs index 2301e2bc1a1f..1f4734468ff1 100644 --- a/drivers/android/binder/range_alloc/mod.rs +++ b/drivers/android/binder/range_alloc/mod.rs @@ -188,11 +188,11 @@ pub(crate) fn reserve_new(&mut self, mut args: ReserveNewArgs) -> Result { - let offset = + let (offset, oneway_spam_detected) = array.reserve_new(args.debug_id, args.size, args.is_oneway, args.pid)?; Ok(ReserveNew::Success(ReserveNewSuccess { offset, - oneway_spam_detected: false, + oneway_spam_detected, _empty_array_alloc: args.empty_array_alloc, _new_tree_alloc: args.new_tree_alloc, _tree_alloc: args.tree_alloc, diff --git a/drivers/android/binder/range_alloc/tree.rs b/drivers/android/binder/range_alloc/tree.rs index 838fdd2b47ea..48796fcdb362 100644 --- a/drivers/android/binder/range_alloc/tree.rs +++ b/drivers/android/binder/range_alloc/tree.rs @@ -164,15 +164,6 @@ pub(crate) fn reserve_new( self.free_oneway_space }; - // Start detecting spammers once we have less than 20% - // of async space left (which is less than 10% of total - // buffer size). - // - // (This will short-circut, so `low_oneway_space` is - // only called when necessary.) - let oneway_spam_detected = - is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); - let (found_size, found_off, tree_node, free_tree_node) = match self.find_best_match(size) { None => { pr_warn!("ENOSPC from range_alloc.reserve_new - size: {}", size); @@ -203,6 +194,15 @@ pub(crate) fn reserve_new( self.free_tree.insert(free_tree_node); } + // Start detecting spammers once we have less than 20% + // of async space left (which is less than 10% of total + // buffer size). + // + // (This will short-circuit, so `low_oneway_space` is + // only called when necessary.) + let oneway_spam_detected = + is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); + Ok((found_off, oneway_spam_detected)) } diff --git a/drivers/android/binder/rust_binder.h b/drivers/android/binder/rust_binder.h index 31806890ed1a..d2284726c025 100644 --- a/drivers/android/binder/rust_binder.h +++ b/drivers/android/binder/rust_binder.h @@ -20,4 +20,83 @@ struct inode; struct dentry *rust_binderfs_create_proc_file(struct inode *nodp, int pid); void rust_binderfs_remove_file(struct dentry *dentry); +/* + * The internal data types in the Rust Binder driver are opaque to C, so we use + * void pointer typedefs for these types. + */ + +typedef void *rust_binder_transaction; +typedef void *rust_binder_process; +typedef void *rust_binder_node; + +struct rb_process_layout { + size_t arc_offset; + size_t task; +}; + +struct rb_transaction_layout { + size_t debug_id; + size_t code; + size_t flags; + size_t from_thread; + size_t to_proc; + size_t target_node; +}; + +struct rb_node_layout { + size_t arc_offset; + size_t debug_id; + size_t ptr; +}; + +struct rust_binder_layout { + struct rb_transaction_layout t; + struct rb_process_layout p; + struct rb_node_layout n; +}; + +extern const struct rust_binder_layout RUST_BINDER_LAYOUT; + +static inline size_t rust_binder_transaction_debug_id(rust_binder_transaction t) +{ + return *(size_t *) (t + RUST_BINDER_LAYOUT.t.debug_id); +} + +static inline u32 rust_binder_transaction_code(rust_binder_transaction t) +{ + return *(u32 *) (t + RUST_BINDER_LAYOUT.t.code); +} + +static inline u32 rust_binder_transaction_flags(rust_binder_transaction t) +{ + return *(u32 *) (t + RUST_BINDER_LAYOUT.t.flags); +} + +// Nullable! +static inline rust_binder_node rust_binder_transaction_target_node(rust_binder_transaction t) +{ + void *p = *(void **) (t + RUST_BINDER_LAYOUT.t.target_node); + + if (p) + p = p + RUST_BINDER_LAYOUT.n.arc_offset; + return p; +} + +static inline rust_binder_process rust_binder_transaction_to_proc(rust_binder_transaction t) +{ + void *p = *(void **) (t + RUST_BINDER_LAYOUT.t.to_proc); + + return p + RUST_BINDER_LAYOUT.p.arc_offset; +} + +static inline struct task_struct *rust_binder_process_task(rust_binder_process t) +{ + return *(struct task_struct **) (t + RUST_BINDER_LAYOUT.p.task); +} + +static inline size_t rust_binder_node_debug_id(rust_binder_node t) +{ + return *(size_t *) (t + RUST_BINDER_LAYOUT.n.debug_id); +} + #endif diff --git a/drivers/android/binder/rust_binder_events.h b/drivers/android/binder/rust_binder_events.h index 2f3efbf9dba6..8ad785c6bd0f 100644 --- a/drivers/android/binder/rust_binder_events.h +++ b/drivers/android/binder/rust_binder_events.h @@ -30,6 +30,36 @@ TRACE_EVENT(rust_binder_ioctl, TP_printk("cmd=0x%x arg=0x%lx", __entry->cmd, __entry->arg) ); +TRACE_EVENT(rust_binder_transaction, + TP_PROTO(bool reply, rust_binder_transaction t, struct task_struct *thread), + TP_ARGS(reply, t, thread), + TP_STRUCT__entry( + __field(int, debug_id) + __field(int, target_node) + __field(int, to_proc) + __field(int, to_thread) + __field(int, reply) + __field(unsigned int, code) + __field(unsigned int, flags) + ), + TP_fast_assign( + rust_binder_process to = rust_binder_transaction_to_proc(t); + rust_binder_node target_node = rust_binder_transaction_target_node(t); + + __entry->debug_id = rust_binder_transaction_debug_id(t); + __entry->target_node = target_node ? rust_binder_node_debug_id(target_node) : 0; + __entry->to_proc = rust_binder_process_task(to)->pid; + __entry->to_thread = thread ? thread->pid : 0; + __entry->reply = reply; + __entry->code = rust_binder_transaction_code(t); + __entry->flags = rust_binder_transaction_flags(t); + ), + TP_printk("transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x code=0x%x", + __entry->debug_id, __entry->target_node, + __entry->to_proc, __entry->to_thread, + __entry->reply, __entry->flags, __entry->code) +); + #endif /* _RUST_BINDER_TRACE_H */ /* This part must be outside protection */ diff --git a/drivers/android/binder/rust_binder_main.rs b/drivers/android/binder/rust_binder_main.rs index 47bfb114cabb..aa5f2a75adb4 100644 --- a/drivers/android/binder/rust_binder_main.rs +++ b/drivers/android/binder/rust_binder_main.rs @@ -87,6 +87,14 @@ fn default() -> Self { license: "GPL", } +use kernel::bindings::rust_binder_layout; +#[no_mangle] +static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout { + t: transaction::TRANSACTION_LAYOUT, + p: process::PROCESS_LAYOUT, + n: node::NODE_LAYOUT, +}; + fn next_debug_id() -> usize { static NEXT_DEBUG_ID: Atomic = Atomic::new(0); @@ -286,7 +294,7 @@ fn init(_module: &'static kernel::ThisModule) -> Result { pr_warn!("Loaded Rust Binder."); - BINDER_SHRINKER.register(kernel::c_str!("android-binder"))?; + BINDER_SHRINKER.register(c"android-binder")?; // SAFETY: The module is being loaded, so we can initialize binderfs. unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? }; @@ -312,7 +320,7 @@ unsafe impl Sync for AssertSync {} owner: THIS_MODULE.as_ptr(), poll: Some(rust_binder_poll), unlocked_ioctl: Some(rust_binder_ioctl), - compat_ioctl: Some(bindings::compat_ptr_ioctl), + compat_ioctl: bindings::compat_ptr_ioctl, mmap: Some(rust_binder_mmap), open: Some(rust_binder_open), release: Some(rust_binder_release), diff --git a/drivers/android/binder/rust_binderfs.c b/drivers/android/binder/rust_binderfs.c index 5c1319d80036..ade1c4d92499 100644 --- a/drivers/android/binder/rust_binderfs.c +++ b/drivers/android/binder/rust_binderfs.c @@ -145,7 +145,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, mutex_unlock(&binderfs_minors_mutex); ret = -ENOMEM; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) goto err; @@ -387,7 +387,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) bool use_reserve = true; #endif - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return -ENOMEM; @@ -642,7 +642,7 @@ static int binderfs_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_op = &binderfs_super_ops; sb->s_time_gran = 1; - sb->s_fs_info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL); + sb->s_fs_info = kzalloc_obj(struct binderfs_info); if (!sb->s_fs_info) return -ENOMEM; info = sb->s_fs_info; @@ -721,7 +721,7 @@ static int binderfs_init_fs_context(struct fs_context *fc) { struct binderfs_mount_opts *ctx; - ctx = kzalloc(sizeof(struct binderfs_mount_opts), GFP_KERNEL); + ctx = kzalloc_obj(struct binderfs_mount_opts); if (!ctx) return -ENOMEM; diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs index 1f1709a6a77a..c004214b1662 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -17,9 +17,8 @@ seq_print, sync::atomic::{ordering::Relaxed, Atomic}, sync::poll::{PollCondVar, PollTable}, - sync::{Arc, SpinLock}, + sync::{aref::ARef, Arc, SpinLock}, task::Task, - types::ARef, uaccess::UserSlice, uapi, }; @@ -1016,12 +1015,9 @@ pub(crate) fn copy_transaction_data( // Copy offsets if there are any. if offsets_size > 0 { - { - let mut reader = - UserSlice::new(UserPtr::from_addr(trd_data_ptr.offsets as _), offsets_size) - .reader(); - alloc.copy_into(&mut reader, aligned_data_size, offsets_size)?; - } + let mut offsets_reader = + UserSlice::new(UserPtr::from_addr(trd_data_ptr.offsets as _), offsets_size) + .reader(); let offsets_start = aligned_data_size; let offsets_end = aligned_data_size + offsets_size; @@ -1042,11 +1038,9 @@ pub(crate) fn copy_transaction_data( .step_by(size_of::()) .enumerate() { - let offset: usize = view - .alloc - .read::(index_offset)? - .try_into() - .map_err(|_| EINVAL)?; + let offset = offsets_reader.read::()?; + view.alloc.write(index_offset, &offset)?; + let offset: usize = offset.try_into().map_err(|_| EINVAL)?; if offset < end_of_previous_object || !is_aligned(offset, size_of::()) { pr_warn!("Got transaction with invalid offset."); @@ -1146,6 +1140,7 @@ fn deliver_single_reply( transaction: &DArc, ) -> bool { if let Ok(transaction) = &reply { + crate::trace::trace_transaction(true, transaction, Some(&self.task)); transaction.set_outstanding(&mut self.process.inner.lock()); } diff --git a/drivers/android/binder/trace.rs b/drivers/android/binder/trace.rs index af0e4392805e..9839901c7151 100644 --- a/drivers/android/binder/trace.rs +++ b/drivers/android/binder/trace.rs @@ -2,11 +2,21 @@ // Copyright (C) 2025 Google LLC. +use crate::transaction::Transaction; + +use kernel::bindings::{rust_binder_transaction, task_struct}; use kernel::ffi::{c_uint, c_ulong}; +use kernel::task::Task; use kernel::tracepoint::declare_trace; declare_trace! { unsafe fn rust_binder_ioctl(cmd: c_uint, arg: c_ulong); + unsafe fn rust_binder_transaction(reply: bool, t: rust_binder_transaction, thread: *mut task_struct); +} + +#[inline] +fn raw_transaction(t: &Transaction) -> rust_binder_transaction { + t as *const Transaction as rust_binder_transaction } #[inline] @@ -14,3 +24,14 @@ pub(crate) fn trace_ioctl(cmd: u32, arg: usize) { // SAFETY: Always safe to call. unsafe { rust_binder_ioctl(cmd, arg as c_ulong) } } + +#[inline] +pub(crate) fn trace_transaction(reply: bool, t: &Transaction, thread: Option<&Task>) { + let thread = match thread { + Some(thread) => thread.as_ptr(), + None => core::ptr::null_mut(), + }; + // SAFETY: The raw transaction is valid for the duration of this call. The thread pointer is + // valid or null. + unsafe { rust_binder_transaction(reply, raw_transaction(t), thread) } +} diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs index 2273a8e9d01c..75e6f5fbaaae 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -24,6 +24,17 @@ BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead, }; +use core::mem::offset_of; +use kernel::bindings::rb_transaction_layout; +pub(crate) const TRANSACTION_LAYOUT: rb_transaction_layout = rb_transaction_layout { + debug_id: offset_of!(Transaction, debug_id), + code: offset_of!(Transaction, code), + flags: offset_of!(Transaction, flags), + from_thread: offset_of!(Transaction, from), + to_proc: offset_of!(Transaction, to), + target_node: offset_of!(Transaction, target_node), +}; + #[pin_data(PinnedDrop)] pub(crate) struct Transaction { pub(crate) debug_id: usize, @@ -249,6 +260,7 @@ pub(crate) fn submit(self: DLArc) -> BinderResult { if oneway { if let Some(target_node) = self.target_node.clone() { + crate::trace::trace_transaction(false, &self, None); if process_inner.is_frozen.is_frozen() { process_inner.async_recv = true; if self.flags & TF_UPDATE_TXN != 0 { @@ -286,11 +298,13 @@ pub(crate) fn submit(self: DLArc) -> BinderResult { } let res = if let Some(thread) = self.find_target_thread() { + crate::trace::trace_transaction(false, &self, Some(&thread.task)); match thread.push_work(self) { PushWorkRes::Ok => Ok(()), PushWorkRes::FailedDead(me) => Err((BinderError::new_dead(), me)), } } else { + crate::trace::trace_transaction(false, &self, None); process_inner.push_work(self) }; drop(process_inner); diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 145ed5f14cdb..241f16a9b63d 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -81,7 +81,7 @@ static void binder_insert_free_buffer(struct binder_alloc *alloc, new_buffer_size = binder_alloc_buffer_size(alloc, new_buffer); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: add free buffer, size %zd, at %pK\n", + "%d: add free buffer, size %zd, at %p\n", alloc->pid, new_buffer_size, new_buffer); while (*p) { @@ -289,7 +289,7 @@ static struct page *binder_page_alloc(struct binder_alloc *alloc, return NULL; /* allocate and install shrinker metadata under page->private */ - mdata = kzalloc(sizeof(*mdata), GFP_KERNEL); + mdata = kzalloc_obj(*mdata); if (!mdata) { __free_page(page); return NULL; @@ -572,7 +572,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( } binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_alloc_buf size %zd got buffer %pK size %zd\n", + "%d: binder_alloc_buf size %zd got buffer %p size %zd\n", alloc->pid, size, buffer, buffer_size); /* @@ -672,7 +672,7 @@ struct binder_buffer *binder_alloc_new_buf(struct binder_alloc *alloc, } /* Preallocate the next buffer */ - next = kzalloc(sizeof(*next), GFP_KERNEL); + next = kzalloc_obj(*next); if (!next) return ERR_PTR(-ENOMEM); @@ -748,7 +748,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, ALIGN(buffer->extra_buffers_size, sizeof(void *)); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, - "%d: binder_free_buf %pK size %zd buffer_size %zd\n", + "%d: binder_free_buf %p size %zd buffer_size %zd\n", alloc->pid, buffer, size, buffer_size); BUG_ON(buffer->free); @@ -916,16 +916,15 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, alloc->vm_start = vma->vm_start; - alloc->pages = kvcalloc(alloc->buffer_size / PAGE_SIZE, - sizeof(alloc->pages[0]), - GFP_KERNEL); + alloc->pages = kvzalloc_objs(alloc->pages[0], + alloc->buffer_size / PAGE_SIZE); if (!alloc->pages) { ret = -ENOMEM; failure_string = "alloc page array"; goto err_alloc_pages_failed; } - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) { ret = -ENOMEM; failure_string = "alloc buffer struct"; diff --git a/drivers/android/binderfs.c b/drivers/android/binderfs.c index 9f8a18c88d66..361d69f756f5 100644 --- a/drivers/android/binderfs.c +++ b/drivers/android/binderfs.c @@ -145,7 +145,7 @@ static int binderfs_binder_device_create(struct inode *ref_inode, mutex_unlock(&binderfs_minors_mutex); ret = -ENOMEM; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) goto err; @@ -396,7 +396,7 @@ static int binderfs_binder_ctl_create(struct super_block *sb) bool use_reserve = true; #endif - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return -ENOMEM; @@ -638,7 +638,7 @@ static int binderfs_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_op = &binderfs_super_ops; sb->s_time_gran = 1; - sb->s_fs_info = kzalloc(sizeof(struct binderfs_info), GFP_KERNEL); + sb->s_fs_info = kzalloc_obj(struct binderfs_info); if (!sb->s_fs_info) return -ENOMEM; info = sb->s_fs_info; @@ -717,7 +717,7 @@ static int binderfs_init_fs_context(struct fs_context *fc) { struct binderfs_mount_opts *ctx; - ctx = kzalloc(sizeof(struct binderfs_mount_opts), GFP_KERNEL); + ctx = kzalloc_obj(struct binderfs_mount_opts); if (!ctx) return -ENOMEM; diff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c index 91d44302eac9..f37247e7a5cb 100644 --- a/drivers/ata/libahci_platform.c +++ b/drivers/ata/libahci_platform.c @@ -594,7 +594,7 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev, * We cannot use devm_ here, since ahci_platform_put_resources() uses * target_pwrs after devm_ have freed memory */ - hpriv->target_pwrs = kcalloc(hpriv->nports, sizeof(*hpriv->target_pwrs), GFP_KERNEL); + hpriv->target_pwrs = kzalloc_objs(*hpriv->target_pwrs, hpriv->nports); if (!hpriv->target_pwrs) { rc = -ENOMEM; goto err_out; diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 15e18d50dcc6..4433f626246b 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -194,7 +194,7 @@ void ata_acpi_bind_port(struct ata_port *ap) if (!adev || adev->hp) return; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return; @@ -236,7 +236,7 @@ void ata_acpi_bind_dev(struct ata_device *dev) if (!adev || adev->hp) return; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return; diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index beb6984b379a..6c4e567b6582 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2557,7 +2557,7 @@ static int ata_dev_init_cdl_resources(struct ata_device *dev) unsigned int err_mask; if (!cdl) { - cdl = kzalloc(sizeof(*cdl), GFP_KERNEL); + cdl = kzalloc_obj(*cdl); if (!cdl) return -ENOMEM; dev->cdl = cdl; @@ -2832,7 +2832,7 @@ static void ata_dev_config_cpr(struct ata_device *dev) if (!nr_cpr) goto out; - cpr_log = kzalloc(struct_size(cpr_log, cpr, nr_cpr), GFP_KERNEL); + cpr_log = kzalloc_flex(*cpr_log, cpr, nr_cpr); if (!cpr_log) goto out; @@ -4189,6 +4189,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { ATA_QUIRK_FIRMWARE_WARN }, /* Seagate disks with LPM issues */ + { "ST1000DM010-2EP102", NULL, ATA_QUIRK_NOLPM }, { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM }, /* drives which fail FPDMA_AA activation (some may freeze afterwards) @@ -4231,6 +4232,7 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { /* Devices that do not need bridging limits applied */ { "MTRON MSP-SATA*", NULL, ATA_QUIRK_BRIDGE_OK }, { "BUFFALO HD-QSU2/R5", NULL, ATA_QUIRK_BRIDGE_OK }, + { "QEMU HARDDISK", "2.5+", ATA_QUIRK_BRIDGE_OK }, /* Devices which aren't very happy with higher link speeds */ { "WD My Book", NULL, ATA_QUIRK_1_5_GBPS }, @@ -5638,7 +5640,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) struct ata_port *ap; int id; - ap = kzalloc(sizeof(*ap), GFP_KERNEL); + ap = kzalloc_obj(*ap); if (!ap) return NULL; @@ -6269,10 +6271,6 @@ static void ata_port_detach(struct ata_port *ap) } } - /* Make sure the deferred qc work finished. */ - cancel_work_sync(&ap->deferred_qc_work); - WARN_ON(ap->deferred_qc); - /* Tell EH to disable all devices */ ap->pflags |= ATA_PFLAG_UNLOADING; ata_port_schedule_eh(ap); @@ -6283,9 +6281,11 @@ static void ata_port_detach(struct ata_port *ap) /* wait till EH commits suicide */ ata_port_wait_eh(ap); - /* it better be dead now */ + /* It better be dead now and not have any remaining deferred qc. */ WARN_ON(!(ap->pflags & ATA_PFLAG_UNLOADED)); + WARN_ON(ap->deferred_qc); + cancel_work_sync(&ap->deferred_qc_work); cancel_delayed_work_sync(&ap->hotplug_task); cancel_delayed_work_sync(&ap->scsi_rescan_task); @@ -6714,7 +6714,7 @@ static void __init ata_parse_force_param(void) if (*p == ',') size++; - ata_force_tbl = kcalloc(size, sizeof(ata_force_tbl[0]), GFP_KERNEL); + ata_force_tbl = kzalloc_objs(ata_force_tbl[0], size); if (!ata_force_tbl) { printk(KERN_WARNING "ata: failed to extend force table, " "libata.force ignored\n"); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 72a22b6c9682..23be85418b3b 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -640,12 +640,29 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, set_host_byte(scmd, DID_OK); ata_qc_for_each_raw(ap, qc, i) { - if (qc->flags & ATA_QCFLAG_ACTIVE && - qc->scsicmd == scmd) + if (qc->scsicmd != scmd) + continue; + if ((qc->flags & ATA_QCFLAG_ACTIVE) || + qc == ap->deferred_qc) break; } - if (i < ATA_MAX_QUEUE) { + if (i < ATA_MAX_QUEUE && qc == ap->deferred_qc) { + /* + * This is a deferred command that timed out while + * waiting for the command queue to drain. Since the qc + * is not active yet (deferred_qc is still set, so the + * deferred qc work has not issued the command yet), + * simply signal the timeout by finishing the SCSI + * command and clear the deferred qc to prevent the + * deferred qc work from issuing this qc. + */ + WARN_ON_ONCE(qc->flags & ATA_QCFLAG_ACTIVE); + ap->deferred_qc = NULL; + cancel_work(&ap->deferred_qc_work); + set_host_byte(scmd, DID_TIME_OUT); + scsi_eh_finish_cmd(scmd, &ap->eh_done_q); + } else if (i < ATA_MAX_QUEUE) { /* the scmd has an associated qc */ if (!(qc->flags & ATA_QCFLAG_EH)) { /* which hasn't failed yet, timeout */ diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c index 57023324a56f..e3adc008fed1 100644 --- a/drivers/ata/libata-pmp.c +++ b/drivers/ata/libata-pmp.c @@ -339,8 +339,8 @@ static int sata_pmp_init_links (struct ata_port *ap, int nr_ports) int i, err; if (!pmp_link) { - pmp_link = kcalloc(SATA_PMP_MAX_PORTS, sizeof(pmp_link[0]), - GFP_NOIO); + pmp_link = kzalloc_objs(pmp_link[0], SATA_PMP_MAX_PORTS, + GFP_NOIO); if (!pmp_link) return -ENOMEM; diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index 04e1e774645e..b9d635088f5f 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -849,7 +849,7 @@ int ata_slave_link_init(struct ata_port *ap) WARN_ON(ap->slave_link); WARN_ON(ap->flags & ATA_FLAG_PMP); - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index c0dd75a0287c..ad798e5246b4 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -1699,6 +1699,7 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap) scmd = qc->scsicmd; ap->deferred_qc = NULL; + cancel_work(&ap->deferred_qc_work); ata_qc_free(qc); scmd->result = (DID_SOFT_ERROR << 16); scsi_done(scmd); diff --git a/drivers/ata/libata-transport.c b/drivers/ata/libata-transport.c index 62415fe67a11..2099d94c4f68 100644 --- a/drivers/ata/libata-transport.c +++ b/drivers/ata/libata-transport.c @@ -758,7 +758,7 @@ struct scsi_transport_template *ata_attach_transport(void) struct ata_internal *i; int count; - i = kzalloc(sizeof(struct ata_internal), GFP_KERNEL); + i = kzalloc_obj(struct ata_internal); if (!i) return NULL; diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c index 799531218ea2..414e7c63bd85 100644 --- a/drivers/ata/libata-zpodd.c +++ b/drivers/ata/libata-zpodd.c @@ -274,7 +274,7 @@ void zpodd_init(struct ata_device *dev) if (mech_type == ODD_MECH_TYPE_UNSUPPORTED) return; - zpodd = kzalloc(sizeof(struct zpodd), GFP_KERNEL); + zpodd = kzalloc_obj(struct zpodd); if (!zpodd) return; diff --git a/drivers/ata/pata_parport/pata_parport.c b/drivers/ata/pata_parport/pata_parport.c index 22bd3ff6b7ae..a5b959891cb7 100644 --- a/drivers/ata/pata_parport/pata_parport.c +++ b/drivers/ata/pata_parport/pata_parport.c @@ -511,7 +511,7 @@ static struct pi_adapter *pi_init_one(struct parport *parport, if (id < 0) return NULL; - pi = kzalloc(sizeof(struct pi_adapter), GFP_KERNEL); + pi = kzalloc_obj(struct pi_adapter); if (!pi) { ida_free(&pata_parport_bus_dev_ids, id); return NULL; diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 7a4f59202156..64cb544903d8 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -850,7 +850,7 @@ static int sata_dwc_port_start(struct ata_port *ap) } /* Allocate Port Struct */ - hsdevp = kzalloc(sizeof(*hsdevp), GFP_KERNEL); + hsdevp = kzalloc_obj(*hsdevp); if (!hsdevp) { err = -ENOMEM; goto CLEANUP; diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 84da8d6ef28e..be829fcc584d 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -706,7 +706,7 @@ static int sata_fsl_port_start(struct ata_port *ap) void __iomem *hcr_base = host_priv->hcr_base; u32 temp; - pp = kzalloc(sizeof(*pp), GFP_KERNEL); + pp = kzalloc_obj(*pp); if (!pp) return -ENOMEM; @@ -1451,7 +1451,7 @@ static int sata_fsl_probe(struct platform_device *ofdev) dev_dbg(&ofdev->dev, "@reset i/o = 0x%x\n", ioread32(csr_base + TRANSCFG)); - host_priv = kzalloc(sizeof(struct sata_fsl_host_priv), GFP_KERNEL); + host_priv = kzalloc_obj(struct sata_fsl_host_priv); if (!host_priv) goto error_exit_with_cleanup; diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 8157925af824..c8d00537d236 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -148,8 +148,7 @@ static int __init adummy_init(void) printk(KERN_ERR "adummy: version %s\n", DRV_VERSION); - adummy_dev = kzalloc(sizeof(struct adummy_dev), - GFP_KERNEL); + adummy_dev = kzalloc_obj(struct adummy_dev); if (!adummy_dev) { printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n"); err = -ENOMEM; diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index fa3c76a2b49d..96719851ae2a 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -375,7 +375,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result) struct atmtcp_dev_data *dev_data; struct atm_dev *dev; - dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL); + dev_data = kmalloc_obj(*dev_data); if (!dev_data) return -ENOMEM; diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 3011cf1a84a9..12cb3aa588bc 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -1845,9 +1845,8 @@ static int eni_start(struct atm_dev *dev) /* initialize memory management */ buffer_mem = eni_dev->mem - (buf - eni_dev->ram); eni_dev->free_list_size = buffer_mem/MID_MIN_BUF_SIZE/2; - eni_dev->free_list = kmalloc_array(eni_dev->free_list_size + 1, - sizeof(*eni_dev->free_list), - GFP_KERNEL); + eni_dev->free_list = kmalloc_objs(*eni_dev->free_list, + eni_dev->free_list_size + 1); if (!eni_dev->free_list) { printk(KERN_ERR DEV_LABEL "(itf %d): couldn't get free page\n", dev->number); @@ -1925,7 +1924,7 @@ static int eni_open(struct atm_vcc *vcc) DPRINTK(DEV_LABEL "(itf %d): open %d.%d\n",vcc->dev->number,vcc->vpi, vcc->vci); if (!test_bit(ATM_VF_PARTIAL,&vcc->flags)) { - eni_vcc = kmalloc(sizeof(struct eni_vcc),GFP_KERNEL); + eni_vcc = kmalloc_obj(struct eni_vcc); if (!eni_vcc) return -ENOMEM; vcc->dev_data = eni_vcc; eni_vcc->tx = NULL; /* for eni_close after open_rx */ @@ -2229,7 +2228,7 @@ static int eni_init_one(struct pci_dev *pci_dev, goto err_disable; rc = -ENOMEM; - eni_dev = kmalloc(sizeof(struct eni_dev), GFP_KERNEL); + eni_dev = kmalloc_obj(struct eni_dev); if (!eni_dev) goto err_disable; diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index f62e38571440..2423eed506c1 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -373,6 +373,10 @@ fore200e_shutdown(struct fore200e* fore200e) fallthrough; case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); +#ifdef FORE200E_USE_TASKLET + tasklet_kill(&fore200e->tx_tasklet); + tasklet_kill(&fore200e->rx_tasklet); +#endif fallthrough; case FORE200E_STATE_ALLOC_BUF: @@ -1327,7 +1331,7 @@ fore200e_open(struct atm_vcc *vcc) spin_unlock_irqrestore(&fore200e->q_lock, flags); - fore200e_vcc = kzalloc(sizeof(struct fore200e_vcc), GFP_ATOMIC); + fore200e_vcc = kzalloc_obj(struct fore200e_vcc, GFP_ATOMIC); if (fore200e_vcc == NULL) { vc_map->vcc = NULL; return -ENOMEM; @@ -1672,7 +1676,7 @@ fore200e_getstats(struct fore200e* fore200e) u32 stats_dma_addr; if (fore200e->stats == NULL) { - fore200e->stats = kzalloc(sizeof(struct stats), GFP_KERNEL); + fore200e->stats = kzalloc_obj(struct stats); if (fore200e->stats == NULL) return -ENOMEM; } @@ -1951,7 +1955,7 @@ static int fore200e_irq_request(struct fore200e *fore200e) static int fore200e_get_esi(struct fore200e *fore200e) { - struct prom_data* prom = kzalloc(sizeof(struct prom_data), GFP_KERNEL); + struct prom_data* prom = kzalloc_obj(struct prom_data); int ok, i; if (!prom) @@ -1996,8 +2000,7 @@ static int fore200e_alloc_rx_buf(struct fore200e *fore200e) DPRINTK(2, "rx buffers %d / %d are being allocated\n", scheme, magn); /* allocate the array of receive buffers */ - buffer = bsq->buffer = kcalloc(nbr, sizeof(struct buffer), - GFP_KERNEL); + buffer = bsq->buffer = kzalloc_objs(struct buffer, nbr); if (buffer == NULL) return -ENOMEM; @@ -2525,7 +2528,7 @@ static int fore200e_sba_probe(struct platform_device *op) static int index = 0; int err; - fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); + fore200e = kzalloc_obj(struct fore200e); if (!fore200e) return -ENOMEM; @@ -2593,7 +2596,7 @@ static int fore200e_pca_detect(struct pci_dev *pci_dev, goto out; } - fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); + fore200e = kzalloc_obj(struct fore200e); if (fore200e == NULL) { err = -ENOMEM; goto out_disable; diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 92a041d5387b..bb9cb00f9585 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -372,8 +372,7 @@ static int he_init_one(struct pci_dev *pci_dev, } pci_set_drvdata(pci_dev, atm_dev); - he_dev = kzalloc(sizeof(struct he_dev), - GFP_KERNEL); + he_dev = kzalloc_obj(struct he_dev); if (!he_dev) { err = -ENOMEM; goto init_one_failure; @@ -787,9 +786,7 @@ static int he_init_group(struct he_dev *he_dev, int group) } /* rbpl_virt 64-bit pointers */ - he_dev->rbpl_virt = kmalloc_array(RBPL_TABLE_SIZE, - sizeof(*he_dev->rbpl_virt), - GFP_KERNEL); + he_dev->rbpl_virt = kmalloc_objs(*he_dev->rbpl_virt, RBPL_TABLE_SIZE); if (!he_dev->rbpl_virt) { hprintk("unable to allocate rbpl virt table\n"); goto out_free_rbpl_table; @@ -2132,7 +2129,7 @@ he_open(struct atm_vcc *vcc) cid = he_mkcid(he_dev, vpi, vci); - he_vcc = kmalloc(sizeof(struct he_vcc), GFP_ATOMIC); + he_vcc = kmalloc_obj(struct he_vcc, GFP_ATOMIC); if (he_vcc == NULL) { hprintk("unable to allocate he_vcc during open\n"); return -ENOMEM; diff --git a/drivers/atm/idt77105.c b/drivers/atm/idt77105.c index e6a300203e6c..4bbcca7f77c8 100644 --- a/drivers/atm/idt77105.c +++ b/drivers/atm/idt77105.c @@ -262,7 +262,7 @@ static int idt77105_start(struct atm_dev *dev) { unsigned long flags; - if (!(dev->phy_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL))) + if (!(dev->phy_data = kmalloc_obj(struct idt77105_priv))) return -ENOMEM; PRIV(dev)->dev = dev; spin_lock_irqsave(&idt77105_priv_lock, flags); diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 888695ccc2a7..7f8aaf5e6e43 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -638,7 +638,7 @@ alloc_scq(struct idt77252_dev *card, int class) { struct scq_info *scq; - scq = kzalloc(sizeof(struct scq_info), GFP_KERNEL); + scq = kzalloc_obj(struct scq_info); if (!scq) return NULL; scq->base = dma_alloc_coherent(&card->pcidev->dev, SCQ_SIZE, @@ -2116,7 +2116,7 @@ idt77252_init_est(struct vc_map *vc, int pcr) { struct rate_estimator *est; - est = kzalloc(sizeof(struct rate_estimator), GFP_KERNEL); + est = kzalloc_obj(struct rate_estimator); if (!est) return NULL; est->maxcps = pcr < 0 ? -pcr : pcr; @@ -2424,7 +2424,7 @@ idt77252_open(struct atm_vcc *vcc) index = VPCI2VC(card, vpi, vci); if (!card->vcs[index]) { - card->vcs[index] = kzalloc(sizeof(struct vc_map), GFP_KERNEL); + card->vcs[index] = kzalloc_obj(struct vc_map); if (!card->vcs[index]) { printk("%s: can't alloc vc in open()\n", card->name); mutex_unlock(&card->mutex); @@ -2855,7 +2855,7 @@ open_card_oam(struct idt77252_dev *card) for (vci = 3; vci < 5; vci++) { index = VPCI2VC(card, vpi, vci); - vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL); + vc = kzalloc_obj(struct vc_map); if (!vc) { printk("%s: can't alloc vc\n", card->name); return -ENOMEM; @@ -2923,7 +2923,7 @@ open_card_ubr0(struct idt77252_dev *card) { struct vc_map *vc; - vc = kzalloc(sizeof(struct vc_map), GFP_KERNEL); + vc = kzalloc_obj(struct vc_map); if (!vc) { printk("%s: can't alloc vc\n", card->name); return -ENOMEM; @@ -3621,7 +3621,7 @@ static int idt77252_init_one(struct pci_dev *pcidev, goto err_out_disable_pdev; } - card = kzalloc(sizeof(struct idt77252_dev), GFP_KERNEL); + card = kzalloc_obj(struct idt77252_dev); if (!card) { printk("idt77252-%d: can't allocate private data\n", index); err = -ENOMEM; diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 301e697e22ad..0d38e93772c2 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -114,7 +114,7 @@ static void ia_enque_head_rtn_q (IARTN_Q *que, IARTN_Q * data) } static int ia_enque_rtn_q (IARTN_Q *que, struct desc_tbl_t data) { - IARTN_Q *entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + IARTN_Q *entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; entry->data = data; @@ -1978,9 +1978,7 @@ static int tx_init(struct atm_dev *dev) buf_desc_ptr++; tx_pkt_start += iadev->tx_buf_sz; } - iadev->tx_buf = kmalloc_array(iadev->num_tx_desc, - sizeof(*iadev->tx_buf), - GFP_KERNEL); + iadev->tx_buf = kmalloc_objs(*iadev->tx_buf, iadev->num_tx_desc); if (!iadev->tx_buf) { printk(KERN_ERR DEV_LABEL " couldn't get mem\n"); goto err_free_dle; @@ -1989,7 +1987,7 @@ static int tx_init(struct atm_dev *dev) { struct cpcs_trailer *cpcs; - cpcs = kmalloc(sizeof(*cpcs), GFP_KERNEL|GFP_DMA); + cpcs = kmalloc_obj(*cpcs, GFP_KERNEL | GFP_DMA); if(!cpcs) { printk(KERN_ERR DEV_LABEL " couldn't get freepage\n"); goto err_free_tx_bufs; @@ -2000,9 +1998,7 @@ static int tx_init(struct atm_dev *dev) sizeof(*cpcs), DMA_TO_DEVICE); } - iadev->desc_tbl = kmalloc_array(iadev->num_tx_desc, - sizeof(*iadev->desc_tbl), - GFP_KERNEL); + iadev->desc_tbl = kmalloc_objs(*iadev->desc_tbl, iadev->num_tx_desc); if (!iadev->desc_tbl) { printk(KERN_ERR DEV_LABEL " couldn't get mem\n"); goto err_free_all_tx_bufs; @@ -2130,9 +2126,7 @@ static int tx_init(struct atm_dev *dev) memset((caddr_t)(iadev->seg_ram+i), 0, iadev->num_vc*4); vc = (struct main_vc *)iadev->MAIN_VC_TABLE_ADDR; evc = (struct ext_vc *)iadev->EXT_VC_TABLE_ADDR; - iadev->testTable = kmalloc_array(iadev->num_vc, - sizeof(*iadev->testTable), - GFP_KERNEL); + iadev->testTable = kmalloc_objs(*iadev->testTable, iadev->num_vc); if (!iadev->testTable) { printk("Get freepage failed\n"); goto err_free_desc_tbl; @@ -2141,8 +2135,7 @@ static int tx_init(struct atm_dev *dev) { memset((caddr_t)vc, 0, sizeof(*vc)); memset((caddr_t)evc, 0, sizeof(*evc)); - iadev->testTable[i] = kmalloc(sizeof(struct testTable_t), - GFP_KERNEL); + iadev->testTable[i] = kmalloc_obj(struct testTable_t); if (!iadev->testTable[i]) goto err_free_test_tables; iadev->testTable[i]->lastTime = 0; @@ -2712,7 +2705,7 @@ static int ia_open(struct atm_vcc *vcc) vcc->dev->number, vcc->vpi, vcc->vci);) /* Device dependent initialization */ - ia_vcc = kmalloc(sizeof(*ia_vcc), GFP_KERNEL); + ia_vcc = kmalloc_obj(*ia_vcc); if (!ia_vcc) return -ENOMEM; vcc->dev_data = ia_vcc; @@ -2798,7 +2791,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg) rfredn_t *rfL; if (!capable(CAP_NET_ADMIN)) return -EPERM; - regs_local = kmalloc(sizeof(*regs_local), GFP_KERNEL); + regs_local = kmalloc_obj(*regs_local); if (!regs_local) return -ENOMEM; ffL = ®s_local->ffredn; rfL = ®s_local->rfredn; @@ -3168,7 +3161,7 @@ static int ia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) IADEV *iadev; int ret; - iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); + iadev = kzalloc_obj(*iadev); if (!iadev) { ret = -ENOMEM; goto err_out; diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 0dfa2cdc897c..d6af999a9ebb 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -1464,7 +1464,7 @@ static inline void vcc_table_deallocate(const struct lanai_dev *lanai) static inline struct lanai_vcc *new_lanai_vcc(void) { struct lanai_vcc *lvcc; - lvcc = kzalloc(sizeof(*lvcc), GFP_KERNEL); + lvcc = kzalloc_obj(*lvcc); if (likely(lvcc != NULL)) { skb_queue_head_init(&lvcc->tx.backlog); #ifdef DEBUG @@ -2555,7 +2555,7 @@ static int lanai_init_one(struct pci_dev *pci, struct atm_dev *atmdev; int result; - lanai = kzalloc(sizeof(*lanai), GFP_KERNEL); + lanai = kzalloc_obj(*lanai); if (lanai == NULL) { printk(KERN_ERR DEV_LABEL ": couldn't allocate dev_data structure!\n"); diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index bc8dbba77b87..24e51343df15 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -373,7 +373,7 @@ static int ns_init_card(int i, struct pci_dev *pcidev) return error; } - card = kmalloc(sizeof(*card), GFP_KERNEL); + card = kmalloc_obj(*card); if (!card) { printk ("nicstar%d: can't allocate memory for device structure.\n", @@ -867,7 +867,7 @@ static scq_info *get_scq(ns_dev *card, int size, u32 scd) if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) return NULL; - scq = kmalloc(sizeof(*scq), GFP_KERNEL); + scq = kmalloc_obj(*scq); if (!scq) return NULL; scq->org = dma_alloc_coherent(&card->pcidev->dev, @@ -876,8 +876,7 @@ static scq_info *get_scq(ns_dev *card, int size, u32 scd) kfree(scq); return NULL; } - scq->skb = kcalloc(size / NS_SCQE_SIZE, sizeof(*scq->skb), - GFP_KERNEL); + scq->skb = kzalloc_objs(*scq->skb, size / NS_SCQE_SIZE); if (!scq->skb) { dma_free_coherent(&card->pcidev->dev, 2 * size, scq->org, scq->dma); diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index d3c30a28c410..24c764664c24 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c @@ -1196,7 +1196,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) uint32_t data32; struct solos_card *card; - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) return -ENOMEM; diff --git a/drivers/atm/suni.c b/drivers/atm/suni.c index 7d0fa729c2fe..bb588c98216d 100644 --- a/drivers/atm/suni.c +++ b/drivers/atm/suni.c @@ -367,7 +367,7 @@ int suni_init(struct atm_dev *dev) { unsigned char mri; - if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL))) + if (!(dev->phy_data = kmalloc_obj(struct suni_priv))) return -ENOMEM; PRIV(dev)->dev = dev; diff --git a/drivers/auxdisplay/hd44780.c b/drivers/auxdisplay/hd44780.c index cef42656c4b0..b046513987b5 100644 --- a/drivers/auxdisplay/hd44780.c +++ b/drivers/auxdisplay/hd44780.c @@ -226,7 +226,7 @@ static int hd44780_probe(struct platform_device *pdev) if (!lcd) return -ENOMEM; - hd = kzalloc(sizeof(*hd), GFP_KERNEL); + hd = kzalloc_obj(*hd); if (!hd) goto fail2; diff --git a/drivers/auxdisplay/line-display.c b/drivers/auxdisplay/line-display.c index 4e22373fcc1a..81b4aac65807 100644 --- a/drivers/auxdisplay/line-display.c +++ b/drivers/auxdisplay/line-display.c @@ -56,7 +56,7 @@ static int create_attachment(struct device *dev, struct linedisp *linedisp, bool { struct linedisp_attachment *attachment; - attachment = kzalloc(sizeof(*attachment), GFP_KERNEL); + attachment = kzalloc_obj(*attachment); if (!attachment) return -ENOMEM; @@ -390,7 +390,7 @@ static int linedisp_init_map(struct linedisp *linedisp) if (err < 0) return err; - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) return -ENOMEM; diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index 958c0e31e84a..d8854cf15268 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c @@ -1428,7 +1428,7 @@ static struct logical_input *panel_bind_key(const char *name, const char *press, { struct logical_input *key; - key = kzalloc(sizeof(*key), GFP_KERNEL); + key = kzalloc_obj(*key); if (!key) return NULL; diff --git a/drivers/base/arch_topology.c b/drivers/base/arch_topology.c index c0ef6ea9c111..8c5e47c28d9a 100644 --- a/drivers/base/arch_topology.c +++ b/drivers/base/arch_topology.c @@ -892,7 +892,7 @@ __weak int __init parse_acpi_topology(void) hetero_id = find_acpi_cpu_topology_hetero_id(cpu); entry = xa_load(&hetero_cpu, hetero_id); if (!entry) { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); WARN_ON_ONCE(!entry); if (entry) { diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index 72adbacc6554..4ad26b8dd6a5 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c @@ -153,7 +153,7 @@ attribute_container_add_device(struct device *dev, if (!cont->match(cont, dev)) continue; - ic = kzalloc(sizeof(*ic), GFP_KERNEL); + ic = kzalloc_obj(*ic); if (!ic) { dev_err(dev, "failed to allocate class container\n"); continue; diff --git a/drivers/base/auxiliary.c b/drivers/base/auxiliary.c index 04bdbff4dbe5..9fd3820d1f8a 100644 --- a/drivers/base/auxiliary.c +++ b/drivers/base/auxiliary.c @@ -420,7 +420,7 @@ struct auxiliary_device *auxiliary_device_create(struct device *dev, struct auxiliary_device *auxdev; int ret; - auxdev = kzalloc(sizeof(*auxdev), GFP_KERNEL); + auxdev = kzalloc_obj(*auxdev); if (!auxdev) return NULL; diff --git a/drivers/base/auxiliary_sysfs.c b/drivers/base/auxiliary_sysfs.c index 754f21730afd..dea7f46f7dd0 100644 --- a/drivers/base/auxiliary_sysfs.c +++ b/drivers/base/auxiliary_sysfs.c @@ -63,7 +63,7 @@ int auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq) if (ret) return ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/base/base.h b/drivers/base/base.h index 8c2175820da9..1af95ac68b77 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -179,19 +179,10 @@ void device_release_driver_internal(struct device *dev, const struct device_driv void driver_detach(const struct device_driver *drv); void driver_deferred_probe_del(struct device *dev); void device_set_deferred_probe_reason(const struct device *dev, struct va_format *vaf); -static inline int driver_match_device_locked(const struct device_driver *drv, - struct device *dev) -{ - device_lock_assert(dev); - - return drv->bus->match ? drv->bus->match(dev, drv) : 1; -} - static inline int driver_match_device(const struct device_driver *drv, struct device *dev) { - guard(device)(dev); - return driver_match_device_locked(drv, dev); + return drv->bus->match ? drv->bus->match(dev, drv) : 1; } static inline void dev_sync_state(struct device *dev) @@ -302,3 +293,12 @@ static inline int devtmpfs_delete_node(struct device *dev) { return 0; } void software_node_notify(struct device *dev); void software_node_notify_remove(struct device *dev); + +#ifdef CONFIG_PINCTRL +int pinctrl_bind_pins(struct device *dev); +#else +static inline int pinctrl_bind_pins(struct device *dev) +{ + return 0; +} +#endif /* CONFIG_PINCTRL */ diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 9eb7771706f0..bb61d8adbab1 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -696,7 +696,7 @@ int bus_add_driver(struct device_driver *drv) */ pr_debug("bus: '%s': add driver %s\n", sp->bus->name, drv->name); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { error = -ENOMEM; goto out_put_bus; @@ -897,7 +897,7 @@ int bus_register(const struct bus_type *bus) struct kobject *bus_kobj; struct lock_class_key *key; - priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); + priv = kzalloc_obj(struct subsys_private); if (!priv) return -ENOMEM; @@ -1263,7 +1263,7 @@ static int subsys_register(const struct bus_type *subsys, goto err_sp; } - dev = kzalloc(sizeof(struct device), GFP_KERNEL); + dev = kzalloc_obj(struct device); if (!dev) { err = -ENOMEM; goto err_dev; diff --git a/drivers/base/cacheinfo.c b/drivers/base/cacheinfo.c index 613410705a47..391ac5e3d2f5 100644 --- a/drivers/base/cacheinfo.c +++ b/drivers/base/cacheinfo.c @@ -510,7 +510,8 @@ int __weak populate_cache_leaves(unsigned int cpu) static inline int allocate_cache_info(int cpu) { - per_cpu_cacheinfo(cpu) = kcalloc(cache_leaves(cpu), sizeof(struct cacheinfo), GFP_ATOMIC); + per_cpu_cacheinfo(cpu) = kzalloc_objs(struct cacheinfo, + cache_leaves(cpu), GFP_ATOMIC); if (!per_cpu_cacheinfo(cpu)) { cache_leaves(cpu) = 0; return -ENOMEM; @@ -882,8 +883,8 @@ static int cpu_cache_sysfs_init(unsigned int cpu) return PTR_ERR(per_cpu_cache_dev(cpu)); /* Allocate all required memory */ - per_cpu_index_dev(cpu) = kcalloc(cache_leaves(cpu), - sizeof(struct device *), GFP_KERNEL); + per_cpu_index_dev(cpu) = kzalloc_objs(struct device *, + cache_leaves(cpu)); if (unlikely(per_cpu_index_dev(cpu) == NULL)) goto err_out; diff --git a/drivers/base/class.c b/drivers/base/class.c index 2526c57d924e..827fc7adacc7 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -194,7 +194,7 @@ int class_register(const struct class *cls) return -EINVAL; } - cp = kzalloc(sizeof(*cp), GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return -ENOMEM; klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); @@ -268,7 +268,7 @@ struct class *class_create(const char *name) struct class *cls; int retval; - cls = kzalloc(sizeof(*cls), GFP_KERNEL); + cls = kzalloc_obj(*cls); if (!cls) { retval = -ENOMEM; goto error; @@ -573,7 +573,7 @@ struct class_compat *class_compat_register(const char *name) { struct class_compat *cls; - cls = kmalloc(sizeof(struct class_compat), GFP_KERNEL); + cls = kmalloc_obj(struct class_compat); if (!cls) return NULL; cls->kobj = kobject_create_and_add(name, &class_kset->kobj); diff --git a/drivers/base/component.c b/drivers/base/component.c index 024ad9471b8a..655d68deb590 100644 --- a/drivers/base/component.c +++ b/drivers/base/component.c @@ -363,7 +363,7 @@ static int component_match_realloc(struct component_match *match, size_t num) if (match->alloc == num) return 0; - new = kmalloc_array(num, sizeof(*new), GFP_KERNEL); + new = kmalloc_objs(*new, num); if (!new) return -ENOMEM; @@ -521,7 +521,7 @@ int component_master_add_with_match(struct device *parent, if (ret) return ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; @@ -732,7 +732,7 @@ static int __component_add(struct device *dev, const struct component_ops *ops, struct component *component; int ret; - component = kzalloc(sizeof(*component), GFP_KERNEL); + component = kzalloc_obj(*component); if (!component) return -ENOMEM; diff --git a/drivers/base/core.c b/drivers/base/core.c index f599a1384eec..791f9e444df8 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -76,7 +76,7 @@ static int __fwnode_link_add(struct fwnode_handle *con, return 0; } - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; @@ -844,7 +844,7 @@ struct device_link *device_link_add(struct device *consumer, goto out; } - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) goto out; @@ -2748,7 +2748,7 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, if (!kset->uevent_ops->filter(&dev->kobj)) goto out; - env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); + env = kzalloc_obj(struct kobj_uevent_env); if (!env) return -ENOMEM; @@ -3220,7 +3220,7 @@ static struct kobject *class_dir_create_and_add(struct subsys_private *sp, struct class_dir *dir; int retval; - dir = kzalloc(sizeof(*dir), GFP_KERNEL); + dir = kzalloc_obj(*dir); if (!dir) return ERR_PTR(-ENOMEM); @@ -3531,7 +3531,7 @@ static void device_remove_sys_dev_entry(struct device *dev) static int device_private_init(struct device *dev) { - dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL); + dev->p = kzalloc_obj(*dev->p); if (!dev->p) return -ENOMEM; dev->p->device = dev; @@ -4278,7 +4278,7 @@ struct device *__root_device_register(const char *name, struct module *owner) struct root_device *root; int err = -ENOMEM; - root = kzalloc(sizeof(struct root_device), GFP_KERNEL); + root = kzalloc_obj(struct root_device); if (!root) return ERR_PTR(err); @@ -4350,7 +4350,7 @@ device_create_groups_vargs(const struct class *class, struct device *parent, if (IS_ERR_OR_NULL(class)) goto error; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { retval = -ENOMEM; goto error; diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 3e3fa031e605..875abdc9942e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -466,7 +466,7 @@ __cpu_device_create(struct device *parent, void *drvdata, struct device *dev = NULL; int retval = -ENOMEM; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto error; diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 0354f209529c..bea8da5f8a3a 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -928,7 +928,7 @@ static int __device_attach_driver(struct device_driver *drv, void *_data) bool async_allowed; int ret; - ret = driver_match_device_locked(drv, dev); + ret = driver_match_device(drv, dev); if (ret == 0) { /* no match */ return 0; diff --git a/drivers/base/devcoredump.c b/drivers/base/devcoredump.c index 55bdc7f5e59d..7e4a491bf15e 100644 --- a/drivers/base/devcoredump.c +++ b/drivers/base/devcoredump.c @@ -381,7 +381,7 @@ void dev_coredumpm_timeout(struct device *dev, struct module *owner, if (!try_module_get(owner)) goto free; - devcd = kzalloc(sizeof(*devcd), gfp); + devcd = kzalloc_obj(*devcd, gfp); if (!devcd) goto put_module; diff --git a/drivers/base/devres.c b/drivers/base/devres.c index f54db6d138ab..171750c1f691 100644 --- a/drivers/base/devres.c +++ b/drivers/base/devres.c @@ -554,7 +554,7 @@ void *devres_open_group(struct device *dev, void *id, gfp_t gfp) struct devres_group *grp; unsigned long flags; - grp = kmalloc(sizeof(*grp), gfp); + grp = kmalloc_obj(*grp, gfp); if (unlikely(!grp)) return NULL; diff --git a/drivers/base/faux.c b/drivers/base/faux.c index 23d725817232..fb3e42f21362 100644 --- a/drivers/base/faux.c +++ b/drivers/base/faux.c @@ -133,7 +133,7 @@ struct faux_device *faux_device_create_with_groups(const char *name, struct device *dev; int ret; - faux_obj = kzalloc(sizeof(*faux_obj), GFP_KERNEL); + faux_obj = kzalloc_obj(*faux_obj); if (!faux_obj) return NULL; @@ -234,7 +234,7 @@ int __init faux_bus_init(void) { int ret; - faux_bus_root = kzalloc(sizeof(*faux_bus_root), GFP_KERNEL); + faux_bus_root = kzalloc_obj(*faux_bus_root); if (!faux_bus_root) return -ENOMEM; diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 4ebdca9e4da4..a11b30dda23b 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -127,7 +127,7 @@ static struct fw_priv *__allocate_fw_priv(const char *fw_name, if (offset != 0 && !(opt_flags & FW_OPT_PARTIAL)) return NULL; - fw_priv = kzalloc(sizeof(*fw_priv), GFP_ATOMIC); + fw_priv = kzalloc_obj(*fw_priv, GFP_ATOMIC); if (!fw_priv) return NULL; @@ -747,7 +747,7 @@ _request_firmware_prepare(struct firmware **firmware_p, const char *name, struct fw_priv *fw_priv; int ret; - *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL); + *firmware_p = firmware = kzalloc_obj(*firmware); if (!firmware) { dev_err(device, "%s: kmalloc(struct firmware) failed\n", __func__); @@ -1165,7 +1165,7 @@ static int _request_firmware_nowait( { struct firmware_work *fw_work; - fw_work = kzalloc(sizeof(struct firmware_work), gfp); + fw_work = kzalloc_obj(struct firmware_work, gfp); if (!fw_work) return -ENOMEM; @@ -1338,7 +1338,7 @@ static struct fw_cache_entry *alloc_fw_cache_entry(const char *name) { struct fw_cache_entry *fce; - fce = kzalloc(sizeof(*fce), GFP_ATOMIC); + fce = kzalloc_obj(*fce, GFP_ATOMIC); if (!fce) goto exit; diff --git a/drivers/base/firmware_loader/sysfs.c b/drivers/base/firmware_loader/sysfs.c index 92e91050f96a..29a10d2ad537 100644 --- a/drivers/base/firmware_loader/sysfs.c +++ b/drivers/base/firmware_loader/sysfs.c @@ -405,7 +405,7 @@ fw_create_instance(struct firmware *firmware, const char *fw_name, struct fw_sysfs *fw_sysfs; struct device *f_dev; - fw_sysfs = kzalloc(sizeof(*fw_sysfs), GFP_KERNEL); + fw_sysfs = kzalloc_obj(*fw_sysfs); if (!fw_sysfs) { fw_sysfs = ERR_PTR(-ENOMEM); goto exit; diff --git a/drivers/base/firmware_loader/sysfs_upload.c b/drivers/base/firmware_loader/sysfs_upload.c index c3797b93c5f5..f59a7856934c 100644 --- a/drivers/base/firmware_loader/sysfs_upload.c +++ b/drivers/base/firmware_loader/sysfs_upload.c @@ -315,13 +315,13 @@ firmware_upload_register(struct module *module, struct device *parent, if (!try_module_get(module)) return ERR_PTR(-EFAULT); - fw_upload = kzalloc(sizeof(*fw_upload), GFP_KERNEL); + fw_upload = kzalloc_obj(*fw_upload); if (!fw_upload) { ret = -ENOMEM; goto exit_module_put; } - fw_upload_priv = kzalloc(sizeof(*fw_upload_priv), GFP_KERNEL); + fw_upload_priv = kzalloc_obj(*fw_upload_priv); if (!fw_upload_priv) { ret = -ENOMEM; goto free_fw_upload; diff --git a/drivers/base/isa.c b/drivers/base/isa.c index bfd9215c9070..fd076cc63cb6 100644 --- a/drivers/base/isa.c +++ b/drivers/base/isa.c @@ -125,7 +125,7 @@ int isa_register_driver(struct isa_driver *isa_driver, unsigned int ndev) for (id = 0; id < ndev; id++) { struct isa_dev *isa_dev; - isa_dev = kzalloc(sizeof *isa_dev, GFP_KERNEL); + isa_dev = kzalloc_obj(*isa_dev); if (!isa_dev) { error = -ENOMEM; break; diff --git a/drivers/base/map.c b/drivers/base/map.c index 83aeb09ca161..bde415f93d67 100644 --- a/drivers/base/map.c +++ b/drivers/base/map.c @@ -41,7 +41,7 @@ int kobj_map(struct kobj_map *domain, dev_t dev, unsigned long range, if (n > 255) n = 255; - p = kmalloc_array(n, sizeof(struct probe), GFP_KERNEL); + p = kmalloc_objs(struct probe, n); if (p == NULL) return -ENOMEM; @@ -134,8 +134,8 @@ struct kobject *kobj_lookup(struct kobj_map *domain, dev_t dev, int *index) struct kobj_map *kobj_map_init(kobj_probe_t *base_probe, struct mutex *lock) { - struct kobj_map *p = kmalloc(sizeof(struct kobj_map), GFP_KERNEL); - struct probe *base = kzalloc(sizeof(*base), GFP_KERNEL); + struct kobj_map *p = kmalloc_obj(struct kobj_map); + struct probe *base = kzalloc_obj(*base); int i; if ((p == NULL) || (base == NULL)) { diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 751f248ca4a8..a3091924918b 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -800,7 +800,7 @@ static int add_memory_block(unsigned long block_id, int nid, unsigned long state put_device(&mem->dev); return -EEXIST; } - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return -ENOMEM; @@ -1078,7 +1078,7 @@ static int memory_group_register(struct memory_group group) if (!node_possible(group.nid)) return -EINVAL; - new_group = kzalloc(sizeof(group), GFP_KERNEL); + new_group = kzalloc_obj(group); if (!new_group) return -ENOMEM; *new_group = group; diff --git a/drivers/base/node.c b/drivers/base/node.c index 00cf4532f121..d7647d077b66 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -158,7 +158,7 @@ static struct node_access_nodes *node_init_node_access(struct node *node, if (access_node->access == access) return access_node; - access_node = kzalloc(sizeof(*access_node), GFP_KERNEL); + access_node = kzalloc_obj(*access_node); if (!access_node) return NULL; @@ -340,7 +340,7 @@ static void node_init_cache_dev(struct node *node) { struct device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return; @@ -389,7 +389,7 @@ void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs) if (!node->cache_dev) return; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return; @@ -875,7 +875,7 @@ int register_node(int nid) int cpu; struct node *node; - node = kzalloc(sizeof(struct node), GFP_KERNEL); + node = kzalloc_obj(struct node); if (!node) return -ENOMEM; diff --git a/drivers/base/physical_location.c b/drivers/base/physical_location.c index a5539e294d4d..2e723fff6e8a 100644 --- a/drivers/base/physical_location.c +++ b/drivers/base/physical_location.c @@ -21,8 +21,7 @@ bool dev_add_physical_location(struct device *dev) if (!acpi_get_physical_device_location(ACPI_HANDLE(dev), &pld)) return false; - dev->physical_location = - kzalloc(sizeof(*dev->physical_location), GFP_KERNEL); + dev->physical_location = kzalloc_obj(*dev->physical_location); if (!dev->physical_location) { ACPI_FREE(pld); return false; diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index c22864458511..6e250272c843 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -14,6 +14,8 @@ #include #include +#include "base.h" + /** * pinctrl_bind_pins() - called by the device core before probe * @dev: the device that is just about to probe diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index b69bcb37c830..59bb37e8244c 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c @@ -201,7 +201,7 @@ static int __pm_clk_add(struct device *dev, const char *con_id, if (!psd) return -EINVAL; - ce = kzalloc(sizeof(*ce), GFP_KERNEL); + ce = kzalloc_obj(*ce); if (!ce) return -ENOMEM; @@ -282,7 +282,7 @@ int of_pm_clk_add_clks(struct device *dev) if (count <= 0) return -ENODEV; - clks = kcalloc(count, sizeof(*clks), GFP_KERNEL); + clks = kzalloc_objs(*clks, count); if (!clks) return -ENOMEM; diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index 6ecf9ce4a4e6..9bef9248a705 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c @@ -27,7 +27,7 @@ int dev_pm_get_subsys_data(struct device *dev) { struct pm_subsys_data *psd; - psd = kzalloc(sizeof(*psd), GFP_KERNEL); + psd = kzalloc_obj(*psd); if (!psd) return -ENOMEM; @@ -222,7 +222,7 @@ int dev_pm_domain_attach_list(struct device *dev, if (num_pds <= 0) return 0; - pds = kzalloc(sizeof(*pds), GFP_KERNEL); + pds = kzalloc_obj(*pds); if (!pds) return -ENOMEM; diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index ff393cba7649..9b69827cb0d0 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -198,11 +198,11 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) struct pm_qos_constraints *c; struct blocking_notifier_head *n; - qos = kzalloc(sizeof(*qos), GFP_KERNEL); + qos = kzalloc_obj(*qos); if (!qos) return -ENOMEM; - n = kcalloc(3, sizeof(*n), GFP_KERNEL); + n = kzalloc_objs(*n, 3); if (!n) { kfree(qos); return -ENOMEM; @@ -704,7 +704,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!device_is_registered(dev) || value < 0) return -EINVAL; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -780,7 +780,7 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (!device_is_registered(dev)) return -EINVAL; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -919,7 +919,7 @@ int dev_pm_qos_update_user_latency_tolerance(struct device *dev, s32 val) ret = -EINVAL; goto out; } - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) { ret = -ENOMEM; goto out; diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index c0809d18fc54..ad23f0fa5d1a 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -55,7 +55,7 @@ int dev_pm_set_wake_irq(struct device *dev, int irq) if (irq < 0) return -EINVAL; - wirq = kzalloc(sizeof(*wirq), GFP_KERNEL); + wirq = kzalloc_obj(*wirq); if (!wirq) return -ENOMEM; @@ -179,7 +179,7 @@ static int __dev_pm_set_dedicated_wake_irq(struct device *dev, int irq, unsigned if (irq < 0) return -EINVAL; - wirq = kzalloc(sizeof(*wirq), GFP_KERNEL); + wirq = kzalloc_obj(*wirq); if (!wirq) return -ENOMEM; @@ -273,8 +273,10 @@ EXPORT_SYMBOL_GPL(dev_pm_set_dedicated_wake_irq_reverse); * otherwise try to disable already disabled wakeirq. The wake-up interrupt * starts disabled with IRQ_NOAUTOEN set. * - * Should be only called from rpm_suspend() and rpm_resume() path. - * Caller must hold &dev->power.lock to change wirq->status + * Should be called from rpm_suspend(), rpm_resume(), + * pm_runtime_force_suspend() or pm_runtime_force_resume(). + * Caller must hold &dev->power.lock or disable runtime PM to change + * wirq->status. */ void dev_pm_enable_wake_irq_check(struct device *dev, bool can_change_status) @@ -306,7 +308,8 @@ void dev_pm_enable_wake_irq_check(struct device *dev, * @cond_disable: if set, also check WAKE_IRQ_DEDICATED_REVERSE * * Disables wake-up interrupt conditionally based on status. - * Should be only called from rpm_suspend() and rpm_resume() path. + * Should be called from rpm_suspend(), rpm_resume(), + * pm_runtime_force_suspend() or pm_runtime_force_resume(). */ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) { @@ -332,7 +335,7 @@ void dev_pm_disable_wake_irq_check(struct device *dev, bool cond_disable) * enable wake IRQ after running ->runtime_suspend() which depends on * WAKE_IRQ_DEDICATED_REVERSE. * - * Should be only called from rpm_suspend() path. + * Should be called from rpm_suspend() or pm_runtime_force_suspend(). */ void dev_pm_enable_wake_irq_complete(struct device *dev) { diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index e69033d16fba..b8e48a023bf0 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -83,7 +83,7 @@ static struct wakeup_source *wakeup_source_create(const char *name) const char *ws_name; int id; - ws = kzalloc(sizeof(*ws), GFP_KERNEL); + ws = kzalloc_obj(*ws); if (!ws) goto err_ws; diff --git a/drivers/base/power/wakeup_stats.c b/drivers/base/power/wakeup_stats.c index 3ffd427248e8..308f8bde9aa3 100644 --- a/drivers/base/power/wakeup_stats.c +++ b/drivers/base/power/wakeup_stats.c @@ -141,7 +141,7 @@ static struct device *wakeup_source_device_create(struct device *parent, struct device *dev = NULL; int retval; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { retval = -ENOMEM; goto error; diff --git a/drivers/base/property.c b/drivers/base/property.c index 6a63860579dd..8d9a34be57fb 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -797,7 +797,18 @@ struct fwnode_handle * fwnode_get_next_child_node(const struct fwnode_handle *fwnode, struct fwnode_handle *child) { - return fwnode_call_ptr_op(fwnode, get_next_child_node, child); + struct fwnode_handle *next; + + if (IS_ERR_OR_NULL(fwnode)) + return NULL; + + /* Try to find a child in primary fwnode */ + next = fwnode_call_ptr_op(fwnode, get_next_child_node, child); + if (next) + return next; + + /* When no more children in primary, continue with secondary */ + return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child); } EXPORT_SYMBOL_GPL(fwnode_get_next_child_node); @@ -841,19 +852,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node); struct fwnode_handle *device_get_next_child_node(const struct device *dev, struct fwnode_handle *child) { - const struct fwnode_handle *fwnode = dev_fwnode(dev); - struct fwnode_handle *next; - - if (IS_ERR_OR_NULL(fwnode)) - return NULL; - - /* Try to find a child in primary fwnode */ - next = fwnode_get_next_child_node(fwnode, child); - if (next) - return next; - - /* When no more children in primary, continue with secondary */ - return fwnode_get_next_child_node(fwnode->secondary, child); + return fwnode_get_next_child_node(dev_fwnode(dev), child); } EXPORT_SYMBOL_GPL(device_get_next_child_node); diff --git a/drivers/base/regmap/regcache-flat.c b/drivers/base/regmap/regcache-flat.c index c924817e19b1..025e6749bb24 100644 --- a/drivers/base/regmap/regcache-flat.c +++ b/drivers/base/regmap/regcache-flat.c @@ -36,7 +36,7 @@ static int regcache_flat_init(struct regmap *map) return -EINVAL; cache_size = regcache_flat_get_index(map, map->max_register) + 1; - cache = kzalloc(struct_size(cache, data, cache_size), map->alloc_flags); + cache = kzalloc_flex(*cache, data, cache_size, map->alloc_flags); if (!cache) return -ENOMEM; diff --git a/drivers/base/regmap/regcache-maple.c b/drivers/base/regmap/regcache-maple.c index 4134a77ae1d6..49ba7282e4b8 100644 --- a/drivers/base/regmap/regcache-maple.c +++ b/drivers/base/regmap/regcache-maple.c @@ -294,7 +294,7 @@ static int regcache_maple_init(struct regmap *map) { struct maple_tree *mt; - mt = kmalloc(sizeof(*mt), map->alloc_flags); + mt = kmalloc_obj(*mt, map->alloc_flags); if (!mt) return -ENOMEM; map->cache = mt; diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 3344b82c3799..a69e8b4c359b 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c @@ -185,7 +185,7 @@ static int regcache_rbtree_init(struct regmap *map) { struct regcache_rbtree_ctx *rbtree_ctx; - map->cache = kmalloc(sizeof *rbtree_ctx, map->alloc_flags); + map->cache = kmalloc_obj(*rbtree_ctx, map->alloc_flags); if (!map->cache) return -ENOMEM; @@ -320,7 +320,7 @@ regcache_rbtree_node_alloc(struct regmap *map, unsigned int reg) const struct regmap_range *range; int i; - rbnode = kzalloc(sizeof(*rbnode), map->alloc_flags); + rbnode = kzalloc_obj(*rbnode, map->alloc_flags); if (!rbnode) return NULL; diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index d596526dccbb..a35f2b20298b 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -66,8 +66,7 @@ static int regcache_hw_init(struct regmap *map) } map->num_reg_defaults = count; - map->reg_defaults = kmalloc_array(count, sizeof(struct reg_default), - GFP_KERNEL); + map->reg_defaults = kmalloc_objs(struct reg_default, count); if (!map->reg_defaults) return -ENOMEM; diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index c9b4c04b1cf6..5a46ce5fee72 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c @@ -130,7 +130,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, /* No cache entry? Start a new one */ if (!c) { - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) { regmap_debugfs_free_dump_cache(map); mutex_unlock(&map->cache_lock); @@ -555,7 +555,7 @@ void regmap_debugfs_init(struct regmap *map) /* If we don't have the debugfs root yet, postpone init */ if (!regmap_debugfs_root) { struct regmap_debugfs_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return; node->map = map; diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 6112d942499b..07234d415b51 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -706,7 +706,7 @@ int regmap_add_irq_chip_fwnode(struct fwnode_handle *fwnode, } } - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) return -ENOMEM; diff --git a/drivers/base/regmap/regmap-kunit.c b/drivers/base/regmap/regmap-kunit.c index 6d8279de3ff2..2999d9c185d5 100644 --- a/drivers/base/regmap/regmap-kunit.c +++ b/drivers/base/regmap/regmap-kunit.c @@ -211,7 +211,7 @@ static struct regmap *gen_regmap(struct kunit *test, get_random_bytes(buf, size); - *data = kzalloc(sizeof(**data), GFP_KERNEL); + *data = kzalloc_obj(**data); if (!(*data)) goto out_free; (*data)->vals = buf; @@ -1759,7 +1759,7 @@ static struct regmap *gen_raw_regmap(struct kunit *test, get_random_bytes(buf, size); - *data = kzalloc(sizeof(**data), GFP_KERNEL); + *data = kzalloc_obj(**data); if (!(*data)) goto out_free; (*data)->vals = (void *)buf; diff --git a/drivers/base/regmap/regmap-mmio.c b/drivers/base/regmap/regmap-mmio.c index 29e5f3175301..1de2278fa572 100644 --- a/drivers/base/regmap/regmap-mmio.c +++ b/drivers/base/regmap/regmap-mmio.c @@ -430,7 +430,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, if (config->use_relaxed_mmio && config->io_port) return ERR_PTR(-EINVAL); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/base/regmap/regmap-ram.c b/drivers/base/regmap/regmap-ram.c index 4e5b4518ce4d..0272d53fead1 100644 --- a/drivers/base/regmap/regmap-ram.c +++ b/drivers/base/regmap/regmap-ram.c @@ -66,13 +66,11 @@ struct regmap *__regmap_init_ram(struct device *dev, return ERR_PTR(-EINVAL); } - data->read = kcalloc(config->max_register + 1, sizeof(bool), - GFP_KERNEL); + data->read = kzalloc_objs(bool, config->max_register + 1); if (!data->read) return ERR_PTR(-ENOMEM); - data->written = kcalloc(config->max_register + 1, sizeof(bool), - GFP_KERNEL); + data->written = kzalloc_objs(bool, config->max_register + 1); if (!data->written) return ERR_PTR(-ENOMEM); diff --git a/drivers/base/regmap/regmap-raw-ram.c b/drivers/base/regmap/regmap-raw-ram.c index 76c98814fb8a..60d6e95cdd1b 100644 --- a/drivers/base/regmap/regmap-raw-ram.c +++ b/drivers/base/regmap/regmap-raw-ram.c @@ -123,13 +123,11 @@ struct regmap *__regmap_init_raw_ram(struct device *dev, return ERR_PTR(-EINVAL); } - data->read = kcalloc(config->max_register + 1, sizeof(bool), - GFP_KERNEL); + data->read = kzalloc_objs(bool, config->max_register + 1); if (!data->read) return ERR_PTR(-ENOMEM); - data->written = kcalloc(config->max_register + 1, sizeof(bool), - GFP_KERNEL); + data->written = kzalloc_objs(bool, config->max_register + 1); if (!data->written) return ERR_PTR(-ENOMEM); diff --git a/drivers/base/regmap/regmap-spi-avmm.c b/drivers/base/regmap/regmap-spi-avmm.c index d86a06cadcdb..692108cbc152 100644 --- a/drivers/base/regmap/regmap-spi-avmm.c +++ b/drivers/base/regmap/regmap-spi-avmm.c @@ -630,7 +630,7 @@ spi_avmm_bridge_ctx_gen(struct spi_device *spi) return ERR_PTR(-EINVAL); } - br = kzalloc(sizeof(*br), GFP_KERNEL); + br = kzalloc_obj(*br); if (!br) return ERR_PTR(-ENOMEM); diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 14b1d88997cb..b9fec387997e 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -81,7 +81,7 @@ static struct regmap_async *regmap_spi_async_alloc(void) { struct regmap_async_spi *async_spi; - async_spi = kzalloc(sizeof(*async_spi), GFP_KERNEL); + async_spi = kzalloc_obj(*async_spi); if (!async_spi) return NULL; diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 4231e9d4b8ff..607c1246d994 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -689,7 +689,7 @@ struct regmap *__regmap_init(struct device *dev, if (!config) goto err; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { ret = -ENOMEM; goto err; @@ -1117,7 +1117,7 @@ struct regmap *__regmap_init(struct device *dev, } } - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (new == NULL) { ret = -ENOMEM; goto err_range; @@ -1274,7 +1274,7 @@ int regmap_field_bulk_alloc(struct regmap *regmap, struct regmap_field *rf; int i; - rf = kcalloc(num_fields, sizeof(*rf), GFP_KERNEL); + rf = kzalloc_objs(*rf, num_fields); if (!rf) return -ENOMEM; @@ -1384,7 +1384,7 @@ EXPORT_SYMBOL_GPL(devm_regmap_field_free); struct regmap_field *regmap_field_alloc(struct regmap *regmap, struct reg_field reg_field) { - struct regmap_field *rm_field = kzalloc(sizeof(*rm_field), GFP_KERNEL); + struct regmap_field *rm_field = kzalloc_obj(*rm_field); if (!rm_field) return ERR_PTR(-ENOMEM); diff --git a/drivers/base/soc.c b/drivers/base/soc.c index 282c38aece0d..c8d3db9daa2f 100644 --- a/drivers/base/soc.c +++ b/drivers/base/soc.c @@ -140,13 +140,13 @@ struct soc_device *soc_device_register(struct soc_device_attribute *soc_dev_attr return NULL; } - soc_dev = kzalloc(sizeof(*soc_dev), GFP_KERNEL); + soc_dev = kzalloc_obj(*soc_dev); if (!soc_dev) { ret = -ENOMEM; goto out1; } - soc_attr_groups = kcalloc(3, sizeof(*soc_attr_groups), GFP_KERNEL); + soc_attr_groups = kzalloc_objs(*soc_attr_groups, 3); if (!soc_attr_groups) { ret = -ENOMEM; goto out2; diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c index 16a8301c25d6..51320837f3a9 100644 --- a/drivers/base/swnode.c +++ b/drivers/base/swnode.c @@ -332,7 +332,7 @@ property_entries_dup(const struct property_entry *properties) while (properties[n].name) n++; - p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL); + p = kzalloc_objs(*p, n + 1); if (!p) return ERR_PTR(-ENOMEM); @@ -758,7 +758,7 @@ static struct software_node *software_node_alloc(const struct property_entry *pr if (IS_ERR(props)) return ERR_CAST(props); - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) { property_entries_free(props); return ERR_PTR(-ENOMEM); @@ -805,7 +805,7 @@ swnode_register(const struct software_node *node, struct swnode *parent, struct swnode *swnode; int ret; - swnode = kzalloc(sizeof(*swnode), GFP_KERNEL); + swnode = kzalloc_obj(*swnode); if (!swnode) return ERR_PTR(-ENOMEM); diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index 8540052d37c5..f121be2ed813 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c @@ -399,7 +399,7 @@ void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) return; } - pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL); + pc_host = kzalloc_obj(*pc_host); if (!pc_host) { bcma_err(bus, "can not allocate memory"); return; diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 960632197b05..3dc2985063f1 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c @@ -165,7 +165,7 @@ static int bcma_host_pci_probe(struct pci_dev *dev, u32 val; /* Alloc */ - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) goto out; diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index 26d12a7e6ca0..84742408a59c 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c @@ -479,7 +479,7 @@ int bcma_bus_scan(struct bcma_bus *bus) while (eromptr < eromend) { struct bcma_device *other_core; - struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL); + struct bcma_device *core = kzalloc_obj(*core); if (!core) { err = -ENOMEM; goto out; diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index a9affb7c264d..a4744a30a8af 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -211,7 +211,7 @@ newtframe(struct aoedev *d, struct aoetgt *t) if (list_empty(&t->ffree)) { if (t->falloc >= NSKBPOOLMAX*2) return NULL; - f = kcalloc(1, sizeof(*f), GFP_ATOMIC); + f = kzalloc_objs(*f, 1, GFP_ATOMIC); if (f == NULL) return NULL; t->falloc++; @@ -1431,7 +1431,7 @@ grow_targets(struct aoedev *d) oldn = d->ntargets; newn = oldn * 2; - tt = kcalloc(newn, sizeof(*d->targets), GFP_ATOMIC); + tt = kzalloc_objs(*d->targets, newn, GFP_ATOMIC); if (!tt) return NULL; memmove(tt, d->targets, sizeof(*d->targets) * oldn); @@ -1458,7 +1458,7 @@ addtgt(struct aoedev *d, char *addr, ulong nframes) if (!tt) goto nomem; } - t = kzalloc(sizeof(*t), GFP_ATOMIC); + t = kzalloc_obj(*t, GFP_ATOMIC); if (!t) goto nomem; t->nframes = nframes; @@ -1699,17 +1699,17 @@ aoecmd_init(void) ncpus = num_online_cpus(); - iocq = kcalloc(ncpus, sizeof(struct iocq_ktio), GFP_KERNEL); + iocq = kzalloc_objs(struct iocq_ktio, ncpus); if (!iocq) return -ENOMEM; - kts = kcalloc(ncpus, sizeof(struct ktstate), GFP_KERNEL); + kts = kzalloc_objs(struct ktstate, ncpus); if (!kts) { ret = -ENOMEM; goto kts_fail; } - ktiowq = kcalloc(ncpus, sizeof(wait_queue_head_t), GFP_KERNEL); + ktiowq = kzalloc_objs(wait_queue_head_t, ncpus); if (!ktiowq) { ret = -ENOMEM; goto ktiowq_fail; diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index 3a240755045b..6e8b3807c1c8 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -471,10 +471,10 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc) } if (d || !do_alloc || minor_get(&sysminor, maj, min) < 0) goto out; - d = kcalloc(1, sizeof *d, GFP_ATOMIC); + d = kzalloc_objs(*d, 1, GFP_ATOMIC); if (!d) goto out; - d->targets = kcalloc(NTARGETS, sizeof(*d->targets), GFP_ATOMIC); + d->targets = kzalloc_objs(*d->targets, NTARGETS, GFP_ATOMIC); if (!d->targets) { kfree(d); d = NULL; diff --git a/drivers/block/brd.c b/drivers/block/brd.c index a5104cf96609..00cc8122068f 100644 --- a/drivers/block/brd.c +++ b/drivers/block/brd.c @@ -272,7 +272,7 @@ static struct brd_device *brd_find_or_alloc_device(int i) } } - brd = kzalloc(sizeof(*brd), GFP_KERNEL); + brd = kzalloc_obj(*brd); if (!brd) { mutex_unlock(&brd_devices_mutex); return ERR_PTR(-ENOMEM); diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 742b2908ff68..b3dbf6c76e98 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c @@ -483,38 +483,20 @@ void drbd_al_begin_io(struct drbd_device *device, struct drbd_interval *i) int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i) { - struct lru_cache *al = device->act_log; /* for bios crossing activity log extent boundaries, * we may need to activate two extents in one go */ unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); - unsigned nr_al_extents; - unsigned available_update_slots; unsigned enr; - D_ASSERT(device, first <= last); - - nr_al_extents = 1 + last - first; /* worst case: all touched extends are cold. */ - available_update_slots = min(al->nr_elements - al->used, - al->max_pending_changes - al->pending_changes); - - /* We want all necessary updates for a given request within the same transaction - * We could first check how many updates are *actually* needed, - * and use that instead of the worst-case nr_al_extents */ - if (available_update_slots < nr_al_extents) { - /* Too many activity log extents are currently "hot". - * - * If we have accumulated pending changes already, - * we made progress. - * - * If we cannot get even a single pending change through, - * stop the fast path until we made some progress, - * or requests to "cold" extents could be starved. */ - if (!al->pending_changes) - __set_bit(__LC_STARVING, &device->act_log->flags); - return -ENOBUFS; + if (i->partially_in_al_next_enr) { + D_ASSERT(device, first < i->partially_in_al_next_enr); + D_ASSERT(device, last >= i->partially_in_al_next_enr); + first = i->partially_in_al_next_enr; } + D_ASSERT(device, first <= last); + /* Is resync active in this area? */ for (enr = first; enr <= last; enr++) { struct lc_element *tmp; @@ -529,14 +511,21 @@ int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval * } } - /* Checkout the refcounts. - * Given that we checked for available elements and update slots above, - * this has to be successful. */ + /* Try to checkout the refcounts. */ for (enr = first; enr <= last; enr++) { struct lc_element *al_ext; al_ext = lc_get_cumulative(device->act_log, enr); - if (!al_ext) - drbd_info(device, "LOGIC BUG for enr=%u\n", enr); + + if (!al_ext) { + /* Did not work. We may have exhausted the possible + * changes per transaction. Or raced with someone + * "locking" it against changes. + * Remember where to continue from. + */ + if (enr > first) + i->partially_in_al_next_enr = enr; + return -ENOBUFS; + } } return 0; } @@ -556,7 +545,11 @@ void drbd_al_complete_io(struct drbd_device *device, struct drbd_interval *i) for (enr = first; enr <= last; enr++) { extent = lc_find(device->act_log, enr); - if (!extent) { + /* Yes, this masks a bug elsewhere. However, during normal + * operation this is harmless, so no need to crash the kernel + * by the BUG_ON(refcount == 0) in lc_put(). + */ + if (!extent || extent->refcnt == 0) { drbd_err(device, "al_complete_io() called on inactive extent %u\n", enr); continue; } diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index d90fa3e7f4cf..65ea6ec66bfd 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c @@ -434,7 +434,7 @@ int drbd_bm_init(struct drbd_device *device) { struct drbd_bitmap *b = device->bitmap; WARN_ON(b != NULL); - b = kzalloc(sizeof(struct drbd_bitmap), GFP_KERNEL); + b = kzalloc_obj(struct drbd_bitmap); if (!b) return -ENOMEM; spin_lock_init(&b->bm_lock); @@ -1078,7 +1078,7 @@ static int bm_rw(struct drbd_device *device, const unsigned int flags, unsigned * as we submit copies of pages anyways. */ - ctx = kmalloc(sizeof(struct drbd_bm_aio_ctx), GFP_NOIO); + ctx = kmalloc_obj(struct drbd_bm_aio_ctx, GFP_NOIO); if (!ctx) return -ENOMEM; diff --git a/drivers/block/drbd/drbd_interval.h b/drivers/block/drbd/drbd_interval.h index 366489b72fe9..5d3213b81eed 100644 --- a/drivers/block/drbd/drbd_interval.h +++ b/drivers/block/drbd/drbd_interval.h @@ -8,12 +8,15 @@ struct drbd_interval { struct rb_node rb; sector_t sector; /* start sector of the interval */ - unsigned int size; /* size in bytes */ sector_t end; /* highest interval end in subtree */ + unsigned int size; /* size in bytes */ unsigned int local:1 /* local or remote request? */; unsigned int waiting:1; /* someone is waiting for completion */ unsigned int completed:1; /* this has been completed already; * ignore for conflict detection */ + + /* to resume a partially successful drbd_al_begin_io_nonblock(); */ + unsigned int partially_in_al_next_enr; }; static inline void drbd_clear_interval(struct drbd_interval *i) diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index c73376886e7a..200d464e984b 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -732,9 +733,9 @@ int drbd_send_sync_param(struct drbd_peer_device *peer_device) } if (apv >= 88) - strcpy(p->verify_alg, nc->verify_alg); + strscpy(p->verify_alg, nc->verify_alg); if (apv >= 89) - strcpy(p->csums_alg, nc->csums_alg); + strscpy(p->csums_alg, nc->csums_alg); rcu_read_unlock(); return drbd_send_command(peer_device, sock, cmd, size, NULL, 0); @@ -745,6 +746,7 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm struct drbd_socket *sock; struct p_protocol *p; struct net_conf *nc; + size_t integrity_alg_len; int size, cf; sock = &connection->data; @@ -762,8 +764,10 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm } size = sizeof(*p); - if (connection->agreed_pro_version >= 87) - size += strlen(nc->integrity_alg) + 1; + if (connection->agreed_pro_version >= 87) { + integrity_alg_len = strlen(nc->integrity_alg) + 1; + size += integrity_alg_len; + } p->protocol = cpu_to_be32(nc->wire_protocol); p->after_sb_0p = cpu_to_be32(nc->after_sb_0p); @@ -778,7 +782,7 @@ int __drbd_send_protocol(struct drbd_connection *connection, enum drbd_packet cm p->conn_flags = cpu_to_be32(cf); if (connection->agreed_pro_version >= 87) - strcpy(p->integrity_alg, nc->integrity_alg); + strscpy(p->integrity_alg, nc->integrity_alg, integrity_alg_len); rcu_read_unlock(); return __conn_send_command(connection, sock, cmd, size, NULL, 0); @@ -2510,7 +2514,7 @@ struct drbd_resource *drbd_create_resource(const char *name) { struct drbd_resource *resource; - resource = kzalloc(sizeof(struct drbd_resource), GFP_KERNEL); + resource = kzalloc_obj(struct drbd_resource); if (!resource) goto fail; resource->name = kstrdup(name, GFP_KERNEL); @@ -2543,7 +2547,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) struct drbd_resource *resource; struct drbd_connection *connection; - connection = kzalloc(sizeof(struct drbd_connection), GFP_KERNEL); + connection = kzalloc_obj(struct drbd_connection); if (!connection) return NULL; @@ -2552,7 +2556,7 @@ struct drbd_connection *conn_create(const char *name, struct res_opts *res_opts) if (drbd_alloc_socket(&connection->meta)) goto fail; - connection->current_epoch = kzalloc(sizeof(struct drbd_epoch), GFP_KERNEL); + connection->current_epoch = kzalloc_obj(struct drbd_epoch); if (!connection->current_epoch) goto fail; @@ -2659,9 +2663,6 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig * connect. */ .max_hw_sectors = DRBD_MAX_BIO_SIZE_SAFE >> 8, - .features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA | - BLK_FEAT_ROTATIONAL | - BLK_FEAT_STABLE_WRITES, }; device = minor_to_device(minor); @@ -2669,7 +2670,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig return ERR_MINOR_OR_VOLUME_EXISTS; /* GFP_KERNEL, we are outside of all write-out paths */ - device = kzalloc(sizeof(struct drbd_device), GFP_KERNEL); + device = kzalloc_obj(struct drbd_device); if (!device) return ERR_NOMEM; kref_init(&device->kref); @@ -2728,7 +2729,7 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig INIT_LIST_HEAD(&device->peer_devices); INIT_LIST_HEAD(&device->pending_bitmap_io); for_each_connection(connection, resource) { - peer_device = kzalloc(sizeof(struct drbd_peer_device), GFP_KERNEL); + peer_device = kzalloc_obj(struct drbd_peer_device); if (!peer_device) goto out_idr_remove_from_resource; peer_device->connection = connection; diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 91f3b8afb63c..e201f0087a0f 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -1296,6 +1296,8 @@ void drbd_reconsider_queue_parameters(struct drbd_device *device, lim.max_segments = drbd_backing_dev_max_segments(device); } else { lim.max_segments = BLK_MAX_SEGMENTS; + lim.features = BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA | + BLK_FEAT_ROTATIONAL | BLK_FEAT_STABLE_WRITES; } lim.max_hw_sectors = new >> SECTOR_SHIFT; @@ -1318,8 +1320,24 @@ void drbd_reconsider_queue_parameters(struct drbd_device *device, lim.max_hw_discard_sectors = 0; } - if (bdev) + if (bdev) { blk_stack_limits(&lim, &b->limits, 0); + /* + * blk_set_stacking_limits() cleared the features, and + * blk_stack_limits() may or may not have inherited + * BLK_FEAT_STABLE_WRITES from the backing device. + * + * DRBD always requires stable writes because: + * 1. The same bio data is read for both local disk I/O and + * network transmission. If the page changes mid-flight, + * the local and remote copies could diverge. + * 2. When data integrity is enabled, DRBD calculates a + * checksum before sending the data. If the page changes + * between checksum calculation and transmission, the + * receiver will detect a checksum mismatch. + */ + lim.features |= BLK_FEAT_STABLE_WRITES; + } /* * If we can handle "zeroes" efficiently on the protocol, we want to do @@ -1518,7 +1536,7 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info) goto out; } - new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL); + new_disk_conf = kmalloc_obj(struct disk_conf); if (!new_disk_conf) { retcode = ERR_NOMEM; goto fail; @@ -1767,14 +1785,14 @@ int drbd_adm_attach(struct sk_buff *skb, struct genl_info *info) atomic_set(&device->rs_pending_cnt, 0); /* allocation not in the IO path, drbdsetup context */ - nbc = kzalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); + nbc = kzalloc_obj(struct drbd_backing_dev); if (!nbc) { retcode = ERR_NOMEM; goto fail; } spin_lock_init(&nbc->md.uuid_lock); - new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL); + new_disk_conf = kzalloc_obj(struct disk_conf); if (!new_disk_conf) { retcode = ERR_NOMEM; goto fail; @@ -2372,7 +2390,7 @@ int drbd_adm_net_opts(struct sk_buff *skb, struct genl_info *info) connection = adm_ctx.connection; mutex_lock(&adm_ctx.resource->adm_mutex); - new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL); + new_net_conf = kzalloc_obj(struct net_conf); if (!new_net_conf) { retcode = ERR_NOMEM; goto out; @@ -2552,7 +2570,7 @@ int drbd_adm_connect(struct sk_buff *skb, struct genl_info *info) } /* allocation not in the IO path, drbdsetup / netlink process context */ - new_net_conf = kzalloc(sizeof(*new_net_conf), GFP_KERNEL); + new_net_conf = kzalloc_obj(*new_net_conf); if (!new_net_conf) { retcode = ERR_NOMEM; goto fail; @@ -2822,7 +2840,7 @@ int drbd_adm_resize(struct sk_buff *skb, struct genl_info *info) u_size = rcu_dereference(device->ldev->disk_conf)->disk_size; rcu_read_unlock(); if (u_size != (sector_t)rs.resize_size) { - new_disk_conf = kmalloc(sizeof(struct disk_conf), GFP_KERNEL); + new_disk_conf = kmalloc_obj(struct disk_conf); if (!new_disk_conf) { retcode = ERR_NOMEM; goto fail_ldev; diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 3de919b6f0e1..58b95bf4bdca 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c @@ -1095,7 +1095,7 @@ static void submit_one_flush(struct drbd_device *device, struct issue_flush_cont { struct bio *bio = bio_alloc(device->ldev->backing_bdev, 0, REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO); - struct one_flush_context *octx = kmalloc(sizeof(*octx), GFP_NOIO); + struct one_flush_context *octx = kmalloc_obj(*octx, GFP_NOIO); if (!octx) { drbd_warn(device, "Could not allocate a octx, CANNOT ISSUE FLUSH\n"); @@ -1592,7 +1592,7 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf /* receiver context, in the writeout path of the other node. * avoid potential distributed deadlock */ - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); + epoch = kmalloc_obj(struct drbd_epoch, GFP_NOIO); if (epoch) break; else @@ -1605,7 +1605,7 @@ static int receive_Barrier(struct drbd_connection *connection, struct packet_inf drbd_flush(connection); if (atomic_read(&connection->current_epoch->epoch_size)) { - epoch = kmalloc(sizeof(struct drbd_epoch), GFP_NOIO); + epoch = kmalloc_obj(struct drbd_epoch, GFP_NOIO); if (epoch) break; } @@ -3547,7 +3547,7 @@ static int receive_protocol(struct drbd_connection *connection, struct packet_in } } - new_net_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL); + new_net_conf = kmalloc_obj(struct net_conf); if (!new_net_conf) goto disconnect; @@ -3708,7 +3708,7 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i mutex_lock(&connection->resource->conf_update); old_net_conf = peer_device->connection->net_conf; if (get_ldev(device)) { - new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL); + new_disk_conf = kzalloc_obj(struct disk_conf); if (!new_disk_conf) { put_ldev(device); mutex_unlock(&connection->resource->conf_update); @@ -3794,21 +3794,21 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i } if (verify_tfm || csums_tfm) { - new_net_conf = kzalloc(sizeof(struct net_conf), GFP_KERNEL); + new_net_conf = kzalloc_obj(struct net_conf); if (!new_net_conf) goto disconnect; *new_net_conf = *old_net_conf; if (verify_tfm) { - strcpy(new_net_conf->verify_alg, p->verify_alg); + strscpy(new_net_conf->verify_alg, p->verify_alg); new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1; crypto_free_shash(peer_device->connection->verify_tfm); peer_device->connection->verify_tfm = verify_tfm; drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg); } if (csums_tfm) { - strcpy(new_net_conf->csums_alg, p->csums_alg); + strscpy(new_net_conf->csums_alg, p->csums_alg); new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1; crypto_free_shash(peer_device->connection->csums_tfm); peer_device->connection->csums_tfm = csums_tfm; @@ -3932,7 +3932,7 @@ static int receive_sizes(struct drbd_connection *connection, struct packet_info if (my_usize != p_usize) { struct disk_conf *old_disk_conf, *new_disk_conf = NULL; - new_disk_conf = kzalloc(sizeof(struct disk_conf), GFP_KERNEL); + new_disk_conf = kzalloc_obj(struct disk_conf); if (!new_disk_conf) { put_ldev(device); return -ENOMEM; @@ -5692,7 +5692,7 @@ static int got_OVResult(struct drbd_connection *connection, struct packet_info * drbd_advance_rs_marks(peer_device, device->ov_left); if (device->ov_left == 0) { - dw = kmalloc(sizeof(*dw), GFP_NOIO); + dw = kmalloc_obj(*dw, GFP_NOIO); if (dw) { dw->w.cb = w_ov_finished; dw->device = device; diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c index d15826f6ee81..70f75ef07945 100644 --- a/drivers/block/drbd/drbd_req.c +++ b/drivers/block/drbd/drbd_req.c @@ -621,7 +621,8 @@ int __req_mod(struct drbd_request *req, enum drbd_req_event what, break; case READ_COMPLETED_WITH_ERROR: - drbd_set_out_of_sync(peer_device, req->i.sector, req->i.size); + drbd_set_out_of_sync(first_peer_device(device), + req->i.sector, req->i.size); drbd_report_io_error(device, req); __drbd_chk_io_error(device, DRBD_READ_ERROR); fallthrough; diff --git a/drivers/block/drbd/drbd_state.c b/drivers/block/drbd/drbd_state.c index c2b6c4d9729d..adcba7f1d8ea 100644 --- a/drivers/block/drbd/drbd_state.c +++ b/drivers/block/drbd/drbd_state.c @@ -1468,7 +1468,7 @@ _drbd_set_state(struct drbd_device *device, union drbd_state ns, ns.disk > D_NEGOTIATING) device->last_reattach_jif = jiffies; - ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); + ascw = kmalloc_obj(*ascw, GFP_ATOMIC); if (ascw) { ascw->os = os; ascw->ns = ns; @@ -2351,7 +2351,7 @@ _conn_request_state(struct drbd_connection *connection, union drbd_state mask, u conn_pr_state_change(connection, os, ns_max, flags); remember_new_state(state_change); - acscw = kmalloc(sizeof(*acscw), GFP_ATOMIC); + acscw = kmalloc_obj(*acscw, GFP_ATOMIC); if (acscw) { acscw->oc = os.conn; acscw->ns_min = ns_min; diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index dea3e79d044f..0697f99fed18 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c @@ -483,7 +483,7 @@ struct fifo_buffer *fifo_alloc(unsigned int fifo_size) { struct fifo_buffer *fb; - fb = kzalloc(struct_size(fb, values, fifo_size), GFP_NOIO); + fb = kzalloc_flex(*fb, values, fifo_size, GFP_NOIO); if (!fb) return NULL; @@ -871,7 +871,7 @@ int drbd_resync_finished(struct drbd_peer_device *peer_device) * is not finished by now). Retry in 100ms. */ schedule_timeout_interruptible(HZ / 10); - dw = kmalloc(sizeof(struct drbd_device_work), GFP_ATOMIC); + dw = kmalloc_obj(struct drbd_device_work, GFP_ATOMIC); if (dw) { dw->w.cb = w_resync_finished; dw->device = device; diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 98789a5297f2..0000913f7efc 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -355,8 +355,7 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd, if (rq->bio != rq->biotail) { - bvec = kmalloc_array(nr_bvec, sizeof(struct bio_vec), - GFP_NOIO); + bvec = kmalloc_objs(struct bio_vec, nr_bvec, GFP_NOIO); if (!bvec) return -EIO; cmd->bvec = bvec; @@ -823,7 +822,7 @@ static void loop_queue_work(struct loop_device *lo, struct loop_cmd *cmd) if (worker) goto queue_work; - worker = kzalloc(sizeof(struct loop_worker), GFP_NOWAIT); + worker = kzalloc_obj(struct loop_worker, GFP_NOWAIT); /* * In the event we cannot allocate a worker, just queue on the * rootcg worker and issue the I/O as the rootcg @@ -2010,7 +2009,7 @@ static int loop_add(int i) int err; err = -ENOMEM; - lo = kzalloc(sizeof(*lo), GFP_KERNEL); + lo = kzalloc_obj(*lo); if (!lo) goto out; lo->worker_tree = RB_ROOT; diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index f6c33b21f69e..fe63f3c55d0d 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -307,7 +307,7 @@ static void nbd_mark_nsock_dead(struct nbd_device *nbd, struct nbd_sock *nsock, { if (!nsock->dead && notify && !nbd_disconnected(nbd->config)) { struct link_dead_args *args; - args = kmalloc(sizeof(struct link_dead_args), GFP_NOIO); + args = kmalloc_obj(struct link_dead_args, GFP_NOIO); if (args) { INIT_WORK(&args->work, nbd_dead_link_work); args->index = nbd->index; @@ -1274,7 +1274,7 @@ static int nbd_add_socket(struct nbd_device *nbd, unsigned long arg, goto put_socket; } - nsock = kzalloc(sizeof(*nsock), GFP_KERNEL); + nsock = kzalloc_obj(*nsock); if (!nsock) { err = -ENOMEM; goto put_socket; @@ -1322,7 +1322,7 @@ static int nbd_reconnect_socket(struct nbd_device *nbd, unsigned long arg) if (!sock) return err; - args = kzalloc(sizeof(*args), GFP_KERNEL); + args = kzalloc_obj(*args); if (!args) { sockfd_put(sock); return -ENOMEM; @@ -1510,7 +1510,7 @@ static int nbd_start_device(struct nbd_device *nbd) for (i = 0; i < num_connections; i++) { struct recv_thread_args *args; - args = kzalloc(sizeof(*args), GFP_KERNEL); + args = kzalloc_obj(*args); if (!args) { sock_shutdown(nbd); /* @@ -1677,7 +1677,7 @@ static int nbd_alloc_and_init_config(struct nbd_device *nbd) if (!try_module_get(THIS_MODULE)) return -ENODEV; - config = kzalloc(sizeof(struct nbd_config), GFP_NOFS); + config = kzalloc_obj(struct nbd_config, GFP_NOFS); if (!config) { module_put(THIS_MODULE); return -ENOMEM; @@ -1916,7 +1916,7 @@ static struct nbd_device *nbd_dev_add(int index, unsigned int refs) struct gendisk *disk; int err = -ENOMEM; - nbd = kzalloc(sizeof(struct nbd_device), GFP_KERNEL); + nbd = kzalloc_obj(struct nbd_device); if (!nbd) goto out; diff --git a/drivers/block/null_blk/main.c b/drivers/block/null_blk/main.c index 740a8ac42075..f8c0fd57e041 100644 --- a/drivers/block/null_blk/main.c +++ b/drivers/block/null_blk/main.c @@ -778,7 +778,7 @@ static struct nullb_device *null_alloc_dev(void) { struct nullb_device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -867,7 +867,7 @@ static struct nullb_page *null_alloc_page(void) { struct nullb_page *t_page; - t_page = kmalloc(sizeof(struct nullb_page), GFP_NOIO); + t_page = kmalloc_obj(struct nullb_page, GFP_NOIO); if (!t_page) return NULL; @@ -1818,8 +1818,7 @@ static int setup_queues(struct nullb *nullb) if (g_poll_queues) nqueues += g_poll_queues; - nullb->queues = kcalloc(nqueues, sizeof(struct nullb_queue), - GFP_KERNEL); + nullb->queues = kzalloc_objs(struct nullb_queue, nqueues); if (!nullb->queues) return -ENOMEM; diff --git a/drivers/block/null_blk/zoned.c b/drivers/block/null_blk/zoned.c index 0ada35dc0989..384bdce6a9b7 100644 --- a/drivers/block/null_blk/zoned.c +++ b/drivers/block/null_blk/zoned.c @@ -91,8 +91,8 @@ int null_init_zoned_dev(struct nullb_device *dev, dev->nr_zones = round_up(dev_capacity_sects, dev->zone_size_sects) >> ilog2(dev->zone_size_sects); - dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct nullb_zone), - GFP_KERNEL | __GFP_ZERO); + dev->zones = kvmalloc_objs(struct nullb_zone, dev->nr_zones, + GFP_KERNEL | __GFP_ZERO); if (!dev->zones) return -ENOMEM; diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c index 8892f218a814..700dd0552cd7 100644 --- a/drivers/block/ps3disk.c +++ b/drivers/block/ps3disk.c @@ -416,7 +416,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev) __set_bit(devidx, &ps3disk_mask); mutex_unlock(&ps3disk_mask_mutex); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { error = -ENOMEM; goto fail; diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c index bdcf083b45e2..41cc8cefea01 100644 --- a/drivers/block/ps3vram.c +++ b/drivers/block/ps3vram.c @@ -401,9 +401,7 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev) priv->cache.page_count = CACHE_PAGE_COUNT; priv->cache.page_size = CACHE_PAGE_SIZE; - priv->cache.tags = kcalloc(CACHE_PAGE_COUNT, - sizeof(struct ps3vram_tag), - GFP_KERNEL); + priv->cache.tags = kzalloc_objs(struct ps3vram_tag, CACHE_PAGE_COUNT); if (!priv->cache.tags) return -ENOMEM; @@ -613,7 +611,7 @@ static int ps3vram_probe(struct ps3_system_bus_device *dev) reports_size, xdr_lpar; char *rest; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { error = -ENOMEM; goto fail; diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 8f441eb8b192..e7da06200c1e 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -707,7 +707,7 @@ static struct rbd_client *rbd_client_create(struct ceph_options *ceph_opts) int ret = -ENOMEM; dout("%s:\n", __func__); - rbdc = kmalloc(sizeof(struct rbd_client), GFP_KERNEL); + rbdc = kmalloc_obj(struct rbd_client); if (!rbdc) goto out_opt; @@ -2572,9 +2572,9 @@ static int rbd_img_fill_request(struct rbd_img_request *img_req, } for_each_obj_request(img_req, obj_req) { - obj_req->bvec_pos.bvecs = kmalloc_array(obj_req->bvec_count, - sizeof(*obj_req->bvec_pos.bvecs), - GFP_NOIO); + obj_req->bvec_pos.bvecs = kmalloc_objs(*obj_req->bvec_pos.bvecs, + obj_req->bvec_count, + GFP_NOIO); if (!obj_req->bvec_pos.bvecs) return -ENOMEM; } @@ -3078,9 +3078,9 @@ static int setup_copyup_bvecs(struct rbd_obj_request *obj_req, u64 obj_overlap) rbd_assert(!obj_req->copyup_bvecs); obj_req->copyup_bvec_count = calc_pages_for(0, obj_overlap); - obj_req->copyup_bvecs = kcalloc(obj_req->copyup_bvec_count, - sizeof(*obj_req->copyup_bvecs), - GFP_NOIO); + obj_req->copyup_bvecs = kzalloc_objs(*obj_req->copyup_bvecs, + obj_req->copyup_bvec_count, + GFP_NOIO); if (!obj_req->copyup_bvecs) return -ENOMEM; @@ -5289,7 +5289,7 @@ static struct rbd_spec *rbd_spec_alloc(void) { struct rbd_spec *spec; - spec = kzalloc(sizeof (*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return NULL; @@ -5352,7 +5352,7 @@ static struct rbd_device *__rbd_dev_create(struct rbd_spec *spec) { struct rbd_device *rbd_dev; - rbd_dev = kzalloc(sizeof(*rbd_dev), GFP_KERNEL); + rbd_dev = kzalloc_obj(*rbd_dev); if (!rbd_dev) return NULL; @@ -6509,7 +6509,7 @@ static int rbd_add_parse_args(const char *buf, /* Initialize all rbd options to the defaults */ - pctx.opts = kzalloc(sizeof(*pctx.opts), GFP_KERNEL); + pctx.opts = kzalloc_obj(*pctx.opts); if (!pctx.opts) goto out_mem; diff --git a/drivers/block/rnbd/rnbd-clt-sysfs.c b/drivers/block/rnbd/rnbd-clt-sysfs.c index 144aea1466a4..eb485e4c12e2 100644 --- a/drivers/block/rnbd/rnbd-clt-sysfs.c +++ b/drivers/block/rnbd/rnbd-clt-sysfs.c @@ -591,7 +591,7 @@ static ssize_t rnbd_clt_map_device_store(struct kobject *kobj, opt.dest_port = &port_nr; opt.access_mode = &access_mode; opt.nr_poll_queues = &nr_poll_queues; - addrs = kcalloc(ARRAY_SIZE(paths) * 2, sizeof(*addrs), GFP_KERNEL); + addrs = kzalloc_objs(*addrs, ARRAY_SIZE(paths) * 2); if (!addrs) return -ENOMEM; diff --git a/drivers/block/rnbd/rnbd-clt.c b/drivers/block/rnbd/rnbd-clt.c index 757df2896aeb..4d6725a0035e 100644 --- a/drivers/block/rnbd/rnbd-clt.c +++ b/drivers/block/rnbd/rnbd-clt.c @@ -324,7 +324,7 @@ static struct rnbd_iu *rnbd_get_iu(struct rnbd_clt_session *sess, struct rnbd_iu *iu; struct rtrs_permit *permit; - iu = kzalloc(sizeof(*iu), GFP_KERNEL); + iu = kzalloc_obj(*iu); if (!iu) return NULL; @@ -541,7 +541,7 @@ static int send_msg_open(struct rnbd_clt_dev *dev, enum wait_type wait) }; int err, errno; - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); if (!rsp) return -ENOMEM; @@ -587,7 +587,7 @@ static int send_msg_sess_info(struct rnbd_clt_session *sess, enum wait_type wait }; int err, errno; - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); if (!rsp) return -ENOMEM; @@ -1417,9 +1417,8 @@ static struct rnbd_clt_dev *init_dev(struct rnbd_clt_session *sess, * nr_cpu_ids: the number of softirq queues * nr_poll_queues: the number of polling queues */ - dev->hw_queues = kcalloc(nr_cpu_ids + nr_poll_queues, - sizeof(*dev->hw_queues), - GFP_KERNEL); + dev->hw_queues = kzalloc_objs(*dev->hw_queues, + nr_cpu_ids + nr_poll_queues); if (!dev->hw_queues) { ret = -ENOMEM; goto out_alloc; @@ -1565,7 +1564,7 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname, goto put_dev; } - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); if (!rsp) { ret = -ENOMEM; goto del_dev; diff --git a/drivers/block/rnbd/rnbd-srv.c b/drivers/block/rnbd/rnbd-srv.c index 7eeb321d6140..10e8c438bb43 100644 --- a/drivers/block/rnbd/rnbd-srv.c +++ b/drivers/block/rnbd/rnbd-srv.c @@ -128,7 +128,7 @@ static int process_rdma(struct rnbd_srv_session *srv_sess, trace_process_rdma(srv_sess, msg, id, datalen, usrlen); - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -287,7 +287,7 @@ static int create_sess(struct rtrs_srv_sess *rtrs) return err; } - srv_sess = kzalloc(sizeof(*srv_sess), GFP_KERNEL); + srv_sess = kzalloc_obj(*srv_sess); if (!srv_sess) return -ENOMEM; @@ -422,7 +422,7 @@ static struct rnbd_srv_sess_dev struct rnbd_srv_sess_dev *sess_dev; int error; - sess_dev = kzalloc(sizeof(*sess_dev), GFP_KERNEL); + sess_dev = kzalloc_obj(*sess_dev); if (!sess_dev) return ERR_PTR(-ENOMEM); @@ -441,7 +441,7 @@ static struct rnbd_srv_dev *rnbd_srv_init_srv_dev(struct block_device *bdev) { struct rnbd_srv_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index db1fe9772a4d..020bd9f1a7b6 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -992,7 +992,7 @@ static int vdc_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto err_out_release_mdesc; } - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) { err = -ENOMEM; goto err_out_release_mdesc; diff --git a/drivers/block/swim.c b/drivers/block/swim.c index 416015947ae6..0ccc12a72388 100644 --- a/drivers/block/swim.c +++ b/drivers/block/swim.c @@ -896,7 +896,7 @@ static int swim_probe(struct platform_device *dev) /* set platform driver data */ - swd = kzalloc(sizeof(struct swim_priv), GFP_KERNEL); + swd = kzalloc_obj(struct swim_priv); if (!swd) { ret = -ENOMEM; goto out_release_io; diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index c13cda58a7c6..63aeb7a76a8c 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -710,7 +710,7 @@ static DEFINE_MUTEX(ublk_ctl_mutex); static struct ublk_batch_fetch_cmd * ublk_batch_alloc_fcmd(struct io_uring_cmd *cmd) { - struct ublk_batch_fetch_cmd *fcmd = kzalloc(sizeof(*fcmd), GFP_NOIO); + struct ublk_batch_fetch_cmd *fcmd = kzalloc_obj(*fcmd, GFP_NOIO); if (fcmd) { fcmd->cmd = cmd; @@ -3255,7 +3255,8 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, unsigned int issue_flags) { /* May point to userspace-mapped memory */ - const struct ublksrv_io_cmd *ub_src = io_uring_sqe_cmd(cmd->sqe); + const struct ublksrv_io_cmd *ub_src = io_uring_sqe_cmd(cmd->sqe, + struct ublksrv_io_cmd); u16 buf_idx = UBLK_INVALID_BUF_IDX; struct ublk_device *ub = cmd->file->private_data; struct ublk_queue *ubq; @@ -3833,7 +3834,8 @@ static int ublk_validate_batch_fetch_cmd(struct ublk_batch_io_data *data) static int ublk_handle_non_batch_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) { - const struct ublksrv_io_cmd *ub_cmd = io_uring_sqe_cmd(cmd->sqe); + const struct ublksrv_io_cmd *ub_cmd = io_uring_sqe_cmd(cmd->sqe, + struct ublksrv_io_cmd); struct ublk_device *ub = cmd->file->private_data; unsigned tag = READ_ONCE(ub_cmd->tag); unsigned q_id = READ_ONCE(ub_cmd->q_id); @@ -3862,7 +3864,8 @@ static int ublk_handle_non_batch_cmd(struct io_uring_cmd *cmd, static int ublk_ch_batch_io_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) { - const struct ublk_batch_io *uc = io_uring_sqe_cmd(cmd->sqe); + const struct ublk_batch_io *uc = io_uring_sqe_cmd(cmd->sqe, + struct ublk_batch_io); struct ublk_device *ub = cmd->file->private_data; struct ublk_batch_io_data data = { .ub = ub, @@ -4440,7 +4443,9 @@ static int ublk_ctrl_start_dev(struct ublk_device *ub, /* Skip partition scan if disabled by user */ if (ub->dev_info.flags & UBLK_F_NO_AUTO_PART_SCAN) { - clear_bit(GD_SUPPRESS_PART_SCAN, &disk->state); + /* Not clear for unprivileged daemons, see comment above */ + if (!ub->unprivileged_daemons) + clear_bit(GD_SUPPRESS_PART_SCAN, &disk->state); } else { /* Schedule async partition scan for trusted daemons */ if (!ub->unprivileged_daemons) @@ -4610,7 +4615,7 @@ static int ublk_ctrl_add_dev(const struct ublksrv_ctrl_cmd *header) goto out_unlock; ret = -ENOMEM; - ub = kzalloc(struct_size(ub, queues, info.nr_hw_queues), GFP_KERNEL); + ub = kzalloc_flex(*ub, queues, info.nr_hw_queues); if (!ub) goto out_unlock; mutex_init(&ub->mutex); @@ -5003,15 +5008,22 @@ static int ublk_ctrl_get_features(const struct ublksrv_ctrl_cmd *header) return 0; } -static void ublk_ctrl_set_size(struct ublk_device *ub, const struct ublksrv_ctrl_cmd *header) +static int ublk_ctrl_set_size(struct ublk_device *ub, const struct ublksrv_ctrl_cmd *header) { struct ublk_param_basic *p = &ub->params.basic; u64 new_size = header->data[0]; + int ret = 0; mutex_lock(&ub->mutex); + if (!ub->ub_disk) { + ret = -ENODEV; + goto out; + } p->dev_sectors = new_size; set_capacity_and_notify(ub->ub_disk, p->dev_sectors); +out: mutex_unlock(&ub->mutex); + return ret; } struct count_busy { @@ -5253,7 +5265,8 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) { /* May point to userspace-mapped memory */ - const struct ublksrv_ctrl_cmd *ub_src = io_uring_sqe_cmd(cmd->sqe); + const struct ublksrv_ctrl_cmd *ub_src = io_uring_sqe128_cmd(cmd->sqe, + struct ublksrv_ctrl_cmd); struct ublksrv_ctrl_cmd header; struct ublk_device *ub = NULL; u32 cmd_op = cmd->cmd_op; @@ -5331,8 +5344,7 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, ret = ublk_ctrl_end_recovery(ub, &header); break; case UBLK_CMD_UPDATE_SIZE: - ublk_ctrl_set_size(ub, &header); - ret = 0; + ret = ublk_ctrl_set_size(ub, &header); break; case UBLK_CMD_QUIESCE_DEV: ret = ublk_ctrl_quiesce_dev(ub, &header); diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 357434bdae99..b1c9a27fe00f 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -168,7 +168,7 @@ static int virtblk_setup_discard_write_zeroes_erase(struct request *req, bool un if (unmap) flags |= VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP; - range = kmalloc_array(segments, sizeof(*range), GFP_ATOMIC); + range = kmalloc_objs(*range, segments, GFP_ATOMIC); if (!range) return -ENOMEM; @@ -991,12 +991,12 @@ static int init_vq(struct virtio_blk *vblk) vblk->io_queues[HCTX_TYPE_READ], vblk->io_queues[HCTX_TYPE_POLL]); - vblk->vqs = kmalloc_array(num_vqs, sizeof(*vblk->vqs), GFP_KERNEL); + vblk->vqs = kmalloc_objs(*vblk->vqs, num_vqs); if (!vblk->vqs) return -ENOMEM; - vqs_info = kcalloc(num_vqs, sizeof(*vqs_info), GFP_KERNEL); - vqs = kmalloc_array(num_vqs, sizeof(*vqs), GFP_KERNEL); + vqs_info = kzalloc_objs(*vqs_info, num_vqs); + vqs = kmalloc_objs(*vqs, num_vqs); if (!vqs_info || !vqs) { err = -ENOMEM; goto out; @@ -1455,7 +1455,7 @@ static int virtblk_probe(struct virtio_device *vdev) goto out; index = err; - vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); + vdev->priv = vblk = kmalloc_obj(*vblk); if (!vblk) { err = -ENOMEM; goto out_free_index; diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index a7c2b04ab943..7871099bc0d4 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -846,8 +846,7 @@ static int xen_blkbk_map(struct xen_blkif_ring *ring, * We are using persistent grants, the grant is * not mapped but we might have room for it. */ - persistent_gnt = kmalloc(sizeof(struct persistent_gnt), - GFP_KERNEL); + persistent_gnt = kmalloc_obj(struct persistent_gnt); if (!persistent_gnt) { /* * If we don't have enough memory to diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 0621878940ae..4b865ef800b1 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -131,8 +131,7 @@ static int xen_blkif_alloc_rings(struct xen_blkif *blkif) { unsigned int r; - blkif->rings = kcalloc(blkif->nr_rings, sizeof(struct xen_blkif_ring), - GFP_KERNEL); + blkif->rings = kzalloc_objs(struct xen_blkif_ring, blkif->nr_rings); if (!blkif->rings) return -ENOMEM; @@ -628,8 +627,7 @@ static int xen_blkbk_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { int err; - struct backend_info *be = kzalloc(sizeof(struct backend_info), - GFP_KERNEL); + struct backend_info *be = kzalloc_obj(struct backend_info); /* match the pr_debug in xen_blkbk_remove */ pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); @@ -1010,18 +1008,17 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) err = -ENOMEM; for (i = 0; i < nr_grefs * XEN_BLKIF_REQS_PER_PAGE; i++) { - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) goto fail; list_add_tail(&req->free_list, &ring->pending_free); for (j = 0; j < MAX_INDIRECT_SEGMENTS; j++) { - req->segments[j] = kzalloc(sizeof(*req->segments[0]), GFP_KERNEL); + req->segments[j] = kzalloc_obj(*req->segments[0]); if (!req->segments[j]) goto fail; } for (j = 0; j < MAX_INDIRECT_PAGES; j++) { - req->indirect_pages[j] = kzalloc(sizeof(*req->indirect_pages[0]), - GFP_KERNEL); + req->indirect_pages[j] = kzalloc_obj(*req->indirect_pages[0]); if (!req->indirect_pages[j]) goto fail; } diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 04fc6b552c04..f765970578f9 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -314,7 +314,7 @@ static int fill_grant_buffer(struct blkfront_ring_info *rinfo, int num) int i = 0; while (i < num) { - gnt_list_entry = kzalloc(sizeof(struct grant), GFP_NOIO); + gnt_list_entry = kzalloc_obj(struct grant, GFP_NOIO); if (!gnt_list_entry) goto out_of_memory; @@ -1980,7 +1980,7 @@ static int blkfront_probe(struct xenbus_device *dev, } kfree(type); } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); return -ENOMEM; @@ -2207,17 +2207,13 @@ static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo) for (i = 0; i < BLK_RING_SIZE(info); i++) { rinfo->shadow[i].grants_used = - kvcalloc(grants, - sizeof(rinfo->shadow[i].grants_used[0]), - GFP_KERNEL); - rinfo->shadow[i].sg = kvcalloc(psegs, - sizeof(rinfo->shadow[i].sg[0]), - GFP_KERNEL); + kvzalloc_objs(rinfo->shadow[i].grants_used[0], grants); + rinfo->shadow[i].sg = kvzalloc_objs(rinfo->shadow[i].sg[0], + psegs); if (info->max_indirect_segments) rinfo->shadow[i].indirect_grants = - kvcalloc(INDIRECT_GREFS(grants), - sizeof(rinfo->shadow[i].indirect_grants[0]), - GFP_KERNEL); + kvzalloc_objs(rinfo->shadow[i].indirect_grants[0], + INDIRECT_GREFS(grants)); if ((rinfo->shadow[i].grants_used == NULL) || (rinfo->shadow[i].sg == NULL) || (info->max_indirect_segments && diff --git a/drivers/block/z2ram.c b/drivers/block/z2ram.c index 8c1c7f4211eb..b216cba1c3bf 100644 --- a/drivers/block/z2ram.c +++ b/drivers/block/z2ram.c @@ -187,8 +187,7 @@ static int z2_open(struct gendisk *disk, blk_mode_t mode) (unsigned long)z_remap_nocache_nonser(paddr, size); #endif z2ram_map = - kmalloc_array(size / Z2RAM_CHUNKSIZE, - sizeof(z2ram_map[0]), GFP_KERNEL); + kmalloc_objs(z2ram_map[0], size / Z2RAM_CHUNKSIZE); if (z2ram_map == NULL) { printk(KERN_ERR DEVICE_NAME ": cannot get mem for z2ram_map\n"); diff --git a/drivers/block/zloop.c b/drivers/block/zloop.c index 8e334f5025fc..51c043342127 100644 --- a/drivers/block/zloop.c +++ b/drivers/block/zloop.c @@ -492,7 +492,7 @@ static void zloop_rw(struct zloop_cmd *cmd) if (rq->bio != rq->biotail) { struct bio_vec *bvec; - cmd->bvec = kmalloc_array(nr_bvec, sizeof(*cmd->bvec), GFP_NOIO); + cmd->bvec = kmalloc_objs(*cmd->bvec, nr_bvec, GFP_NOIO); if (!cmd->bvec) { ret = -EIO; goto unlock; @@ -542,6 +542,21 @@ static void zloop_rw(struct zloop_cmd *cmd) zloop_put_cmd(cmd); } +/* + * Sync the entire FS containing the zone files instead of walking all files. + */ +static int zloop_flush(struct zloop_device *zlo) +{ + struct super_block *sb = file_inode(zlo->data_dir)->i_sb; + int ret; + + down_read(&sb->s_umount); + ret = sync_filesystem(sb); + up_read(&sb->s_umount); + + return ret; +} + static void zloop_handle_cmd(struct zloop_cmd *cmd) { struct request *rq = blk_mq_rq_from_pdu(cmd); @@ -562,11 +577,7 @@ static void zloop_handle_cmd(struct zloop_cmd *cmd) zloop_rw(cmd); return; case REQ_OP_FLUSH: - /* - * Sync the entire FS containing the zone files instead of - * walking all files - */ - cmd->ret = sync_filesystem(file_inode(zlo->data_dir)->i_sb); + cmd->ret = zloop_flush(zlo); break; case REQ_OP_ZONE_RESET: cmd->ret = zloop_reset_zone(zlo, rq_zone_no(rq)); @@ -981,7 +992,8 @@ static int zloop_ctl_add(struct zloop_options *opts) struct queue_limits lim = { .max_hw_sectors = SZ_1M >> SECTOR_SHIFT, .chunk_sectors = opts->zone_size, - .features = BLK_FEAT_ZONED, + .features = BLK_FEAT_ZONED | BLK_FEAT_WRITE_CACHE, + }; unsigned int nr_zones, i, j; struct zloop_device *zlo; @@ -997,7 +1009,7 @@ static int zloop_ctl_add(struct zloop_options *opts) goto out; } - zlo = kvzalloc(struct_size(zlo, zones, nr_zones), GFP_KERNEL); + zlo = kvzalloc_flex(*zlo, zones, nr_zones); if (!zlo) { ret = -ENOMEM; goto out; @@ -1162,7 +1174,12 @@ static int zloop_ctl_remove(struct zloop_options *opts) int ret; if (!(opts->mask & ZLOOP_OPT_ID)) { - pr_err("No ID specified\n"); + pr_err("No ID specified for remove\n"); + return -EINVAL; + } + + if (opts->mask & ~ZLOOP_OPT_ID) { + pr_err("Invalid option specified for remove\n"); return -EINVAL; } diff --git a/drivers/block/zram/backend_deflate.c b/drivers/block/zram/backend_deflate.c index b75016e0e654..f92a52a720d1 100644 --- a/drivers/block/zram/backend_deflate.c +++ b/drivers/block/zram/backend_deflate.c @@ -54,7 +54,7 @@ static int deflate_create(struct zcomp_params *params, struct zcomp_ctx *ctx) size_t sz; int ret; - zctx = kzalloc(sizeof(*zctx), GFP_KERNEL); + zctx = kzalloc_obj(*zctx); if (!zctx) return -ENOMEM; diff --git a/drivers/block/zram/backend_lz4.c b/drivers/block/zram/backend_lz4.c index daccd60857eb..04e186614760 100644 --- a/drivers/block/zram/backend_lz4.c +++ b/drivers/block/zram/backend_lz4.c @@ -41,7 +41,7 @@ static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx) { struct lz4_ctx *zctx; - zctx = kzalloc(sizeof(*zctx), GFP_KERNEL); + zctx = kzalloc_obj(*zctx); if (!zctx) return -ENOMEM; @@ -51,11 +51,11 @@ static int lz4_create(struct zcomp_params *params, struct zcomp_ctx *ctx) if (!zctx->mem) goto error; } else { - zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL); + zctx->dstrm = kzalloc_obj(*zctx->dstrm); if (!zctx->dstrm) goto error; - zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL); + zctx->cstrm = kzalloc_obj(*zctx->cstrm); if (!zctx->cstrm) goto error; } diff --git a/drivers/block/zram/backend_lz4hc.c b/drivers/block/zram/backend_lz4hc.c index 9e8a35dfa56d..f6a336acfe20 100644 --- a/drivers/block/zram/backend_lz4hc.c +++ b/drivers/block/zram/backend_lz4hc.c @@ -41,7 +41,7 @@ static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx) { struct lz4hc_ctx *zctx; - zctx = kzalloc(sizeof(*zctx), GFP_KERNEL); + zctx = kzalloc_obj(*zctx); if (!zctx) return -ENOMEM; @@ -51,11 +51,11 @@ static int lz4hc_create(struct zcomp_params *params, struct zcomp_ctx *ctx) if (!zctx->mem) goto error; } else { - zctx->dstrm = kzalloc(sizeof(*zctx->dstrm), GFP_KERNEL); + zctx->dstrm = kzalloc_obj(*zctx->dstrm); if (!zctx->dstrm) goto error; - zctx->cstrm = kzalloc(sizeof(*zctx->cstrm), GFP_KERNEL); + zctx->cstrm = kzalloc_obj(*zctx->cstrm); if (!zctx->cstrm) goto error; } diff --git a/drivers/block/zram/backend_zstd.c b/drivers/block/zram/backend_zstd.c index 81defb98ed09..d00b548056dc 100644 --- a/drivers/block/zram/backend_zstd.c +++ b/drivers/block/zram/backend_zstd.c @@ -53,7 +53,7 @@ static int zstd_setup_params(struct zcomp_params *params) zstd_compression_parameters prm; struct zstd_params *zp; - zp = kzalloc(sizeof(*zp), GFP_KERNEL); + zp = kzalloc_obj(*zp); if (!zp) return -ENOMEM; @@ -122,7 +122,7 @@ static int zstd_create(struct zcomp_params *params, struct zcomp_ctx *ctx) zstd_parameters prm; size_t sz; - zctx = kzalloc(sizeof(*zctx), GFP_KERNEL); + zctx = kzalloc_obj(*zctx); if (!zctx) return -ENOMEM; diff --git a/drivers/block/zram/zcomp.c b/drivers/block/zram/zcomp.c index b1bd1daa0060..a771a8ecc540 100644 --- a/drivers/block/zram/zcomp.c +++ b/drivers/block/zram/zcomp.c @@ -238,7 +238,7 @@ struct zcomp *zcomp_create(const char *alg, struct zcomp_params *params) */ BUILD_BUG_ON(ARRAY_SIZE(backends) <= 1); - comp = kzalloc(sizeof(struct zcomp), GFP_KERNEL); + comp = kzalloc_obj(struct zcomp); if (!comp) return ERR_PTR(-ENOMEM); diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c index 61d3e2c74901..a324ede6206d 100644 --- a/drivers/block/zram/zram_drv.c +++ b/drivers/block/zram/zram_drv.c @@ -250,7 +250,7 @@ static struct zram_pp_ctl *init_pp_ctl(void) struct zram_pp_ctl *ctl; u32 idx; - ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kmalloc_obj(*ctl); if (!ctl) return NULL; @@ -297,7 +297,7 @@ static bool place_pp_slot(struct zram *zram, struct zram_pp_ctl *ctl, struct zram_pp_slot *pps; u32 bid; - pps = kmalloc(sizeof(*pps), GFP_NOIO | __GFP_NOWARN); + pps = kmalloc_obj(*pps, GFP_NOIO | __GFP_NOWARN); if (!pps) return false; @@ -549,7 +549,7 @@ static ssize_t bd_stat_show(struct device *dev, struct device_attribute *attr, return ret; } -static ssize_t writeback_compressed_store(struct device *dev, +static ssize_t compressed_writeback_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { @@ -564,12 +564,12 @@ static ssize_t writeback_compressed_store(struct device *dev, return -EBUSY; } - zram->wb_compressed = val; + zram->compressed_wb = val; return len; } -static ssize_t writeback_compressed_show(struct device *dev, +static ssize_t compressed_writeback_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -577,7 +577,7 @@ static ssize_t writeback_compressed_show(struct device *dev, struct zram *zram = dev_to_zram(dev); guard(rwsem_read)(&zram->dev_lock); - val = zram->wb_compressed; + val = zram->compressed_wb; return sysfs_emit(buf, "%d\n", val); } @@ -855,7 +855,7 @@ static struct zram_wb_ctl *init_wb_ctl(struct zram *zram) struct zram_wb_ctl *wb_ctl; int i; - wb_ctl = kmalloc(sizeof(*wb_ctl), GFP_KERNEL); + wb_ctl = kmalloc_obj(*wb_ctl); if (!wb_ctl) return NULL; @@ -875,7 +875,7 @@ static struct zram_wb_ctl *init_wb_ctl(struct zram *zram) * writeback can still proceed, even if there is only one * request on the idle list. */ - req = kzalloc(sizeof(*req), GFP_KERNEL | __GFP_NOWARN); + req = kzalloc_obj(*req, GFP_KERNEL | __GFP_NOWARN); if (!req) break; @@ -946,7 +946,7 @@ static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req) goto out; } - if (zram->wb_compressed) { + if (zram->compressed_wb) { /* * ZRAM_WB slots get freed, we need to preserve data required * for read decompression. @@ -960,7 +960,7 @@ static int zram_writeback_complete(struct zram *zram, struct zram_wb_req *req) set_slot_flag(zram, index, ZRAM_WB); set_slot_handle(zram, index, req->blk_idx); - if (zram->wb_compressed) { + if (zram->compressed_wb) { if (huge) set_slot_flag(zram, index, ZRAM_HUGE); set_slot_size(zram, index, size); @@ -1100,7 +1100,7 @@ static int zram_writeback_slots(struct zram *zram, */ if (!test_slot_flag(zram, index, ZRAM_PP_SLOT)) goto next; - if (zram->wb_compressed) + if (zram->compressed_wb) err = read_from_zspool_raw(zram, req->page, index); else err = read_from_zspool(zram, req->page, index); @@ -1429,7 +1429,7 @@ static void zram_async_read_endio(struct bio *bio) * * Keep the existing behavior for now. */ - if (zram->wb_compressed == false) { + if (zram->compressed_wb == false) { /* No decompression needed, complete the parent IO */ bio_endio(req->parent); bio_put(bio); @@ -1452,7 +1452,7 @@ static void read_from_bdev_async(struct zram *zram, struct page *page, struct zram_rb_req *req; struct bio *bio; - req = kmalloc(sizeof(*req), GFP_NOIO); + req = kmalloc_obj(*req, GFP_NOIO); if (!req) return; @@ -1508,7 +1508,7 @@ static int read_from_bdev_sync(struct zram *zram, struct page *page, u32 index, flush_work(&req.work); destroy_work_on_stack(&req.work); - if (req.error || zram->wb_compressed == false) + if (req.error || zram->compressed_wb == false) return req.error; return decompress_bdev_page(zram, page, index); @@ -3007,7 +3007,7 @@ static DEVICE_ATTR_WO(writeback); static DEVICE_ATTR_RW(writeback_limit); static DEVICE_ATTR_RW(writeback_limit_enable); static DEVICE_ATTR_RW(writeback_batch_size); -static DEVICE_ATTR_RW(writeback_compressed); +static DEVICE_ATTR_RW(compressed_writeback); #endif #ifdef CONFIG_ZRAM_MULTI_COMP static DEVICE_ATTR_RW(recomp_algorithm); @@ -3031,7 +3031,7 @@ static struct attribute *zram_disk_attrs[] = { &dev_attr_writeback_limit.attr, &dev_attr_writeback_limit_enable.attr, &dev_attr_writeback_batch_size.attr, - &dev_attr_writeback_compressed.attr, + &dev_attr_compressed_writeback.attr, #endif &dev_attr_io_stat.attr, &dev_attr_mm_stat.attr, @@ -3079,7 +3079,7 @@ static int zram_add(void) struct zram *zram; int ret, device_id; - zram = kzalloc(sizeof(struct zram), GFP_KERNEL); + zram = kzalloc_obj(struct zram); if (!zram) return -ENOMEM; @@ -3091,7 +3091,7 @@ static int zram_add(void) init_rwsem(&zram->dev_lock); #ifdef CONFIG_ZRAM_WRITEBACK zram->wb_batch_size = 32; - zram->wb_compressed = false; + zram->compressed_wb = false; #endif /* gendisk structure */ diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h index 515a72d9c06f..f0de8f8218f5 100644 --- a/drivers/block/zram/zram_drv.h +++ b/drivers/block/zram/zram_drv.h @@ -133,7 +133,7 @@ struct zram { #ifdef CONFIG_ZRAM_WRITEBACK struct file *backing_dev; bool wb_limit_enable; - bool wb_compressed; + bool compressed_wb; u32 wb_batch_size; u64 bd_wb_limit; struct block_device *bdev; diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index e305d04aac9d..2ae38a321c4b 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c @@ -284,7 +284,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb) switch (hci_skb_pkt_type(skb)) { case HCI_COMMAND_PKT: - dr = kmalloc(sizeof(*dr), GFP_KERNEL); + dr = kmalloc_obj(*dr); if (!dr) { usb_free_urb(urb); return -ENOMEM; diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 9d29ab811f80..246b6205c5e0 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -871,7 +871,7 @@ struct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read, bt_dev_info(hdev, "regmap: Init R%x-W%x region", opcode_read, opcode_write); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c index eaf5de46a702..37b744e35bc4 100644 --- a/drivers/bluetooth/btintel_pcie.c +++ b/drivers/bluetooth/btintel_pcie.c @@ -1665,7 +1665,7 @@ static int btintel_pcie_setup_txq_bufs(struct btintel_pcie_data *data, struct data_buf *buf; /* Allocate the same number of buffers as the descriptor */ - txq->bufs = kmalloc_array(txq->count, sizeof(*buf), GFP_KERNEL); + txq->bufs = kmalloc_objs(*buf, txq->count); if (!txq->bufs) return -ENOMEM; @@ -1709,7 +1709,7 @@ static int btintel_pcie_setup_rxq_bufs(struct btintel_pcie_data *data, struct data_buf *buf; /* Allocate the same number of buffers as the descriptor */ - rxq->bufs = kmalloc_array(rxq->count, sizeof(*buf), GFP_KERNEL); + rxq->bufs = kmalloc_objs(*buf, rxq->count); if (!rxq->bufs) return -ENOMEM; @@ -2191,7 +2191,7 @@ btintel_pcie_get_recovery(struct pci_dev *pdev, struct device *dev) return data; } - data = kzalloc(struct_size(data, name, name_len), GFP_ATOMIC); + data = kzalloc_flex(*data, name, name_len, GFP_ATOMIC); if (!data) return NULL; @@ -2306,7 +2306,7 @@ static void btintel_pcie_reset(struct hci_dev *hdev) if (test_and_set_bit(BTINTEL_PCIE_RECOVERY_IN_PROGRESS, &data->flags)) return; - removal = kzalloc(sizeof(*removal), GFP_ATOMIC); + removal = kzalloc_obj(*removal, GFP_ATOMIC); if (!removal) return; diff --git a/drivers/bluetooth/btmrvl_debugfs.c b/drivers/bluetooth/btmrvl_debugfs.c index 32329a2e526f..9b3e768c09f4 100644 --- a/drivers/bluetooth/btmrvl_debugfs.c +++ b/drivers/bluetooth/btmrvl_debugfs.c @@ -144,7 +144,7 @@ void btmrvl_debugfs_init(struct hci_dev *hdev) if (!hdev->debugfs) return; - dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); + dbg = kzalloc_obj(*dbg); priv->debugfs_data = dbg; if (!dbg) { diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index e26b07a9387d..d6f0ad0b4b6e 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c @@ -710,13 +710,13 @@ struct btmrvl_private *btmrvl_add_card(void *card) { struct btmrvl_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { BT_ERR("Can not allocate priv"); goto err_priv; } - priv->adapter = kzalloc(sizeof(*priv->adapter), GFP_KERNEL); + priv->adapter = kzalloc_obj(*priv->adapter); if (!priv->adapter) { BT_ERR("Allocate buffer for btmrvl_adapter failed!"); goto err_adapter; diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c index a8c520dc09e1..fa7533578f85 100644 --- a/drivers/bluetooth/btmtk.c +++ b/drivers/bluetooth/btmtk.c @@ -537,7 +537,7 @@ static int btmtk_usb_submit_wmt_recv_urb(struct hci_dev *hdev) if (!urb) return -ENOMEM; - dr = kmalloc(sizeof(*dr), GFP_KERNEL); + dr = kmalloc_obj(*dr); if (!dr) { usb_free_urb(urb); return -ENOMEM; diff --git a/drivers/bluetooth/btrsi.c b/drivers/bluetooth/btrsi.c index 6c1f584c8a33..c68dd2fba01c 100644 --- a/drivers/bluetooth/btrsi.c +++ b/drivers/bluetooth/btrsi.c @@ -112,7 +112,7 @@ static int rsi_hci_attach(void *priv, struct rsi_proto_ops *ops) struct hci_dev *hdev; int err = 0; - h_adapter = kzalloc(sizeof(*h_adapter), GFP_KERNEL); + h_adapter = kzalloc_obj(*h_adapter); if (!h_adapter) return -ENOMEM; diff --git a/drivers/bluetooth/btrtl.c b/drivers/bluetooth/btrtl.c index 5603b282f9bc..62f9d4df3a4f 100644 --- a/drivers/bluetooth/btrtl.c +++ b/drivers/bluetooth/btrtl.c @@ -524,7 +524,7 @@ static int btrtl_parse_section(struct hci_dev *hdev, break; } - subsec = kzalloc(sizeof(*subsec), GFP_KERNEL); + subsec = kzalloc_obj(*subsec); if (!subsec) return -ENOMEM; subsec->opcode = opcode; @@ -828,7 +828,7 @@ static int rtl_download_firmware(struct hci_dev *hdev, struct sk_buff *skb; struct hci_rp_read_local_version *rp; - dl_cmd = kmalloc(sizeof(*dl_cmd), GFP_KERNEL); + dl_cmd = kmalloc_obj(*dl_cmd); if (!dl_cmd) return -ENOMEM; @@ -1077,7 +1077,7 @@ struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev, u8 key_id; u8 reg_val[2]; - btrtl_dev = kzalloc(sizeof(*btrtl_dev), GFP_KERNEL); + btrtl_dev = kzalloc_obj(*btrtl_dev); if (!btrtl_dev) { ret = -ENOMEM; goto err_alloc; diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index fcec8e589e81..a1c5eb993e47 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2071,7 +2071,7 @@ static struct urb *alloc_ctrl_urb(struct hci_dev *hdev, struct sk_buff *skb) if (!urb) return ERR_PTR(-ENOMEM); - dr = kmalloc(sizeof(*dr), GFP_KERNEL); + dr = kmalloc_obj(*dr); if (!dr) { usb_free_urb(urb); return ERR_PTR(-ENOMEM); @@ -4059,7 +4059,7 @@ static int btusb_probe(struct usb_interface *intf, return -ENODEV; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/bluetooth/hci_ag6xx.c b/drivers/bluetooth/hci_ag6xx.c index 94588676510f..3729d956782d 100644 --- a/drivers/bluetooth/hci_ag6xx.c +++ b/drivers/bluetooth/hci_ag6xx.c @@ -36,7 +36,7 @@ static int ag6xx_open(struct hci_uart *hu) BT_DBG("hu %p", hu); - ag6xx = kzalloc(sizeof(*ag6xx), GFP_KERNEL); + ag6xx = kzalloc_obj(*ag6xx); if (!ag6xx) return -ENOMEM; diff --git a/drivers/bluetooth/hci_aml.c b/drivers/bluetooth/hci_aml.c index b1f32c5a8a3f..959d9e67b669 100644 --- a/drivers/bluetooth/hci_aml.c +++ b/drivers/bluetooth/hci_aml.c @@ -541,7 +541,7 @@ static int aml_open(struct hci_uart *hu) return -EOPNOTSUPP; } - aml_data = kzalloc(sizeof(*aml_data), GFP_KERNEL); + aml_data = kzalloc_obj(*aml_data); if (!aml_data) return -ENOMEM; @@ -677,13 +677,6 @@ static const struct hci_uart_proto aml_hci_proto = { .dequeue = aml_dequeue, }; -static void aml_device_driver_shutdown(struct device *dev) -{ - struct aml_serdev *amldev = dev_get_drvdata(dev); - - aml_power_off(amldev); -} - static int aml_serdev_probe(struct serdev_device *serdev) { struct aml_serdev *amldev; @@ -714,6 +707,13 @@ static void aml_serdev_remove(struct serdev_device *serdev) hci_uart_unregister_device(&amldev->serdev_hu); } +static void aml_serdev_shutdown(struct serdev_device *serdev) +{ + struct aml_serdev *amldev = serdev_device_get_drvdata(serdev); + + aml_power_off(amldev); +} + static const struct aml_device_data data_w155s2 = { .iccm_offset = 256 * 1024, }; @@ -732,10 +732,10 @@ MODULE_DEVICE_TABLE(of, aml_bluetooth_of_match); static struct serdev_device_driver aml_serdev_driver = { .probe = aml_serdev_probe, .remove = aml_serdev_remove, + .shutdown = aml_serdev_shutdown, .driver = { .name = "hci_uart_aml", .of_match_table = aml_bluetooth_of_match, - .shutdown = aml_device_driver_shutdown, }, }; diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 8d2b5e7f0d6a..fa679ad0acdf 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -101,7 +101,7 @@ static int ath_open(struct hci_uart *hu) if (!hci_uart_has_flow_control(hu)) return -EOPNOTSUPP; - ath = kzalloc(sizeof(*ath), GFP_KERNEL); + ath = kzalloc_obj(*ath); if (!ath) return -ENOMEM; diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 9286a5f40f55..1a4fc3882fd2 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -448,7 +448,7 @@ static int bcm_open(struct hci_uart *hu) if (!hci_uart_has_flow_control(hu)) return -EOPNOTSUPP; - bcm = kzalloc(sizeof(*bcm), GFP_KERNEL); + bcm = kzalloc_obj(*bcm); if (!bcm) return -ENOMEM; diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 591abe6d63dd..b386f91d8b46 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -716,7 +716,7 @@ static int bcsp_open(struct hci_uart *hu) BT_DBG("hu %p", hu); - bcsp = kzalloc(sizeof(*bcsp), GFP_KERNEL); + bcsp = kzalloc_obj(*bcsp); if (!bcsp) return -ENOMEM; diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index ec017df8572c..07cc2a79a77b 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -44,7 +44,7 @@ static int h4_open(struct hci_uart *hu) BT_DBG("hu %p", hu); - h4 = kzalloc(sizeof(*h4), GFP_KERNEL); + h4 = kzalloc_obj(*h4); if (!h4) return -ENOMEM; diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c index 96e20a66ecd1..cfdf75dc2847 100644 --- a/drivers/bluetooth/hci_h5.c +++ b/drivers/bluetooth/hci_h5.c @@ -222,7 +222,7 @@ static int h5_open(struct hci_uart *hu) if (hu->serdev) { h5 = serdev_device_get_drvdata(hu->serdev); } else { - h5 = kzalloc(sizeof(*h5), GFP_KERNEL); + h5 = kzalloc_obj(*h5); if (!h5) return -ENOMEM; } @@ -1069,7 +1069,7 @@ static int h5_btrtl_resume(struct h5 *h5) if (test_bit(H5_WAKEUP_DISABLE, &h5->flags)) { struct h5_btrtl_reprobe *reprobe; - reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL); + reprobe = kzalloc_obj(*reprobe); if (!reprobe) return -ENOMEM; diff --git a/drivers/bluetooth/hci_intel.c b/drivers/bluetooth/hci_intel.c index f7570c2eaa46..c31105b91e47 100644 --- a/drivers/bluetooth/hci_intel.c +++ b/drivers/bluetooth/hci_intel.c @@ -384,7 +384,7 @@ static int intel_open(struct hci_uart *hu) if (!hci_uart_has_flow_control(hu)) return -EOPNOTSUPP; - intel = kzalloc(sizeof(*intel), GFP_KERNEL); + intel = kzalloc_obj(*intel); if (!intel) return -ENOMEM; diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 2b28515de92c..71c1997a0f73 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -491,7 +491,7 @@ static int hci_uart_tty_open(struct tty_struct *tty) if (tty->ops->write == NULL) return -EOPNOTSUPP; - hu = kzalloc(sizeof(*hu), GFP_KERNEL); + hu = kzalloc_obj(*hu); if (!hu) { BT_ERR("Can't allocate control structure"); return -ENFILE; diff --git a/drivers/bluetooth/hci_ll.c b/drivers/bluetooth/hci_ll.c index 6f4e25917b86..91acf24f1ef5 100644 --- a/drivers/bluetooth/hci_ll.c +++ b/drivers/bluetooth/hci_ll.c @@ -114,7 +114,7 @@ static int ll_open(struct hci_uart *hu) BT_DBG("hu %p", hu); - ll = kzalloc(sizeof(*ll), GFP_KERNEL); + ll = kzalloc_obj(*ll); if (!ll) return -ENOMEM; diff --git a/drivers/bluetooth/hci_mrvl.c b/drivers/bluetooth/hci_mrvl.c index 8767522ec4c6..516b8f74c434 100644 --- a/drivers/bluetooth/hci_mrvl.c +++ b/drivers/bluetooth/hci_mrvl.c @@ -64,7 +64,7 @@ static int mrvl_open(struct hci_uart *hu) if (!hci_uart_has_flow_control(hu)) return -EOPNOTSUPP; - mrvl = kzalloc(sizeof(*mrvl), GFP_KERNEL); + mrvl = kzalloc_obj(*mrvl); if (!mrvl) return -ENOMEM; diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c index 51309f5b5714..bb9f002aa85e 100644 --- a/drivers/bluetooth/hci_qca.c +++ b/drivers/bluetooth/hci_qca.c @@ -585,7 +585,7 @@ static int qca_open(struct hci_uart *hu) if (!hci_uart_has_flow_control(hu)) return -EOPNOTSUPP; - qca = kzalloc(sizeof(*qca), GFP_KERNEL); + qca = kzalloc_obj(*qca); if (!qca) return -ENOMEM; @@ -1057,7 +1057,7 @@ static void qca_controller_memdump(struct work_struct *work) } if (!qca_memdump) { - qca_memdump = kzalloc(sizeof(*qca_memdump), GFP_ATOMIC); + qca_memdump = kzalloc_obj(*qca_memdump, GFP_ATOMIC); if (!qca_memdump) { mutex_unlock(&qca->hci_memdump_lock); return; @@ -2046,19 +2046,23 @@ static int qca_setup(struct hci_uart *hu) } out: - if (ret && retries < MAX_INIT_RETRIES) { - bt_dev_warn(hdev, "Retry BT power ON:%d", retries); + if (ret) { qca_power_shutdown(hu); - if (hu->serdev) { - serdev_device_close(hu->serdev); - ret = serdev_device_open(hu->serdev); - if (ret) { - bt_dev_err(hdev, "failed to open port"); - return ret; + + if (retries < MAX_INIT_RETRIES) { + bt_dev_warn(hdev, "Retry BT power ON:%d", retries); + if (hu->serdev) { + serdev_device_close(hu->serdev); + ret = serdev_device_open(hu->serdev); + if (ret) { + bt_dev_err(hdev, "failed to open port"); + return ret; + } } + retries++; + goto retry; } - retries++; - goto retry; + return ret; } /* Setup bdaddr */ @@ -2570,11 +2574,10 @@ static void qca_serdev_remove(struct serdev_device *serdev) hci_uart_unregister_device(&qcadev->serdev_hu); } -static void qca_serdev_shutdown(struct device *dev) +static void qca_serdev_shutdown(struct serdev_device *serdev) { int ret; int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS); - struct serdev_device *serdev = to_serdev_device(dev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev); struct hci_uart *hu = &qcadev->serdev_hu; struct hci_dev *hdev = hu->hdev; @@ -2796,11 +2799,11 @@ static void hciqca_coredump(struct device *dev) static struct serdev_device_driver qca_serdev_driver = { .probe = qca_serdev_probe, .remove = qca_serdev_remove, + .shutdown = qca_serdev_shutdown, .driver = { .name = "hci_uart_qca", .of_match_table = of_match_ptr(qca_bluetooth_of_match), .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), - .shutdown = qca_serdev_shutdown, .pm = &qca_pm_ops, #ifdef CONFIG_DEV_COREDUMP .coredump = hciqca_coredump, diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 2fef08254d78..2762eacf7f20 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -640,7 +640,7 @@ static int vhci_open(struct inode *inode, struct file *file) { struct vhci_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c index 6f1a37e85c6a..76d61af8a275 100644 --- a/drivers/bluetooth/virtio_bt.c +++ b/drivers/bluetooth/virtio_bt.c @@ -275,7 +275,7 @@ static int virtbt_probe(struct virtio_device *vdev) return -EINVAL; } - vbt = kzalloc(sizeof(*vbt), GFP_KERNEL); + vbt = kzalloc_obj(*vbt); if (!vbt) return -ENOMEM; diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index b8184a903583..7f2baf057128 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c @@ -451,7 +451,7 @@ static int cci_probe_ports(struct device_node *np) nb_cci_ports = cci_config->nb_ace + cci_config->nb_ace_lite; - ports = kcalloc(nb_cci_ports, sizeof(*ports), GFP_KERNEL); + ports = kzalloc_objs(*ports, nb_cci_ports); if (!ports) return -ENOMEM; diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 007223549887..c117745cf206 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c @@ -432,10 +432,9 @@ const struct device_type fsl_mc_bus_dpdmai_type = { }; EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdmai_type); -const struct device_type fsl_mc_bus_dpdbg_type = { +static const struct device_type fsl_mc_bus_dpdbg_type = { .name = "fsl_mc_bus_dpdbg" }; -EXPORT_SYMBOL_GPL(fsl_mc_bus_dpdbg_type); static const struct device_type *fsl_mc_get_device_type(const char *type) { @@ -673,8 +672,7 @@ static int fsl_mc_device_get_mmio_regions(struct fsl_mc_device *mc_dev, return -EINVAL; } - regions = kmalloc_array(obj_desc->region_count, - sizeof(regions[0]), GFP_KERNEL); + regions = kmalloc_objs(regions[0], obj_desc->region_count); if (!regions) return -ENOMEM; @@ -789,7 +787,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, /* * Allocate an MC bus device object: */ - mc_bus = kzalloc(sizeof(*mc_bus), GFP_KERNEL); + mc_bus = kzalloc_obj(*mc_bus); if (!mc_bus) return -ENOMEM; @@ -799,7 +797,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, /* * Allocate a regular fsl_mc_device object: */ - mc_dev = kzalloc(sizeof(*mc_dev), GFP_KERNEL); + mc_dev = kzalloc_obj(*mc_dev); if (!mc_dev) return -ENOMEM; } diff --git a/drivers/bus/fsl-mc/fsl-mc-uapi.c b/drivers/bus/fsl-mc/fsl-mc-uapi.c index 823969e4159c..aaa14f17aef4 100644 --- a/drivers/bus/fsl-mc/fsl-mc-uapi.c +++ b/drivers/bus/fsl-mc/fsl-mc-uapi.c @@ -483,7 +483,7 @@ static int fsl_mc_uapi_dev_open(struct inode *inode, struct file *filep) struct fsl_mc_bus *mc_bus; int error; - priv_data = kzalloc(sizeof(*priv_data), GFP_KERNEL); + priv_data = kzalloc_obj(*priv_data); if (!priv_data) return -ENOMEM; diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 3c208b5c8446..e3d0a3cbaf94 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -963,7 +963,7 @@ static void mhi_ep_process_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl, { struct mhi_ep_state_transition *item; - item = kzalloc(sizeof(*item), GFP_ATOMIC); + item = kzalloc_obj(*item, GFP_ATOMIC); if (!item) return; @@ -1136,9 +1136,8 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) mhi_ep_mmio_mask_interrupts(mhi_cntrl); mhi_ep_mmio_init(mhi_cntrl); - mhi_cntrl->mhi_event = kcalloc(mhi_cntrl->event_rings, - sizeof(*mhi_cntrl->mhi_event), - GFP_KERNEL); + mhi_cntrl->mhi_event = kzalloc_objs(*mhi_cntrl->mhi_event, + mhi_cntrl->event_rings); if (!mhi_cntrl->mhi_event) return -ENOMEM; @@ -1276,7 +1275,7 @@ static struct mhi_ep_device *mhi_ep_alloc_device(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_device *mhi_dev; struct device *dev; - mhi_dev = kzalloc(sizeof(*mhi_dev), GFP_KERNEL); + mhi_dev = kzalloc_obj(*mhi_dev); if (!mhi_dev) return ERR_PTR(-ENOMEM); @@ -1400,8 +1399,8 @@ static int mhi_ep_chan_init(struct mhi_ep_cntrl *mhi_cntrl, * Allocate max_channels supported by the MHI endpoint and populate * only the defined channels */ - mhi_cntrl->mhi_chan = kcalloc(mhi_cntrl->max_chan, sizeof(*mhi_cntrl->mhi_chan), - GFP_KERNEL); + mhi_cntrl->mhi_chan = kzalloc_objs(*mhi_cntrl->mhi_chan, + mhi_cntrl->max_chan); if (!mhi_cntrl->mhi_chan) return -ENOMEM; @@ -1460,7 +1459,7 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, if (ret) return ret; - mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); + mhi_cntrl->mhi_cmd = kzalloc_objs(*mhi_cntrl->mhi_cmd, NR_OF_CMD_RINGS); if (!mhi_cntrl->mhi_cmd) { ret = -ENOMEM; goto err_free_ch; @@ -1596,7 +1595,7 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_unregister_controller); -static int mhi_ep_driver_probe(struct device *dev) +static int mhi_ep_probe(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); @@ -1609,7 +1608,7 @@ static int mhi_ep_driver_probe(struct device *dev) return mhi_drv->probe(mhi_dev, mhi_dev->id); } -static int mhi_ep_driver_remove(struct device *dev) +static void mhi_ep_remove(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); struct mhi_ep_driver *mhi_drv = to_mhi_ep_driver(dev->driver); @@ -1619,7 +1618,7 @@ static int mhi_ep_driver_remove(struct device *dev) /* Skip if it is a controller device */ if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) - return 0; + return; /* Disconnect the channels associated with the driver */ for (dir = 0; dir < 2; dir++) { @@ -1643,8 +1642,6 @@ static int mhi_ep_driver_remove(struct device *dev) /* Remove the client driver now */ mhi_drv->remove(mhi_dev); - - return 0; } int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner) @@ -1660,8 +1657,6 @@ int __mhi_ep_driver_register(struct mhi_ep_driver *mhi_drv, struct module *owner driver->bus = &mhi_ep_bus_type; driver->owner = owner; - driver->probe = mhi_ep_driver_probe; - driver->remove = mhi_ep_driver_remove; return driver_register(driver); } @@ -1708,6 +1703,8 @@ const struct bus_type mhi_ep_bus_type = { .dev_name = "mhi_ep", .match = mhi_ep_match, .uevent = mhi_ep_uevent, + .probe = mhi_ep_probe, + .remove = mhi_ep_remove, }; static int __init mhi_ep_init(void) diff --git a/drivers/bus/mhi/ep/ring.c b/drivers/bus/mhi/ep/ring.c index 26357ee68dee..9375b16ff2a5 100644 --- a/drivers/bus/mhi/ep/ring.c +++ b/drivers/bus/mhi/ep/ring.c @@ -205,7 +205,8 @@ int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring, ring->wr_offset = mhi_ep_ring_addr2offset(ring, le64_to_cpu(val)); /* Allocate ring cache memory for holding the copy of host ring */ - ring->ring_cache = kcalloc(ring->ring_size, sizeof(struct mhi_ring_element), GFP_KERNEL); + ring->ring_cache = kzalloc_objs(struct mhi_ring_element, + ring->ring_size); if (!ring->ring_cache) return -ENOMEM; diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 205d83ac069f..f16a1e67a667 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -333,12 +333,12 @@ static int mhi_alloc_bhi_buffer(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; - img_info = kzalloc(sizeof(*img_info), GFP_KERNEL); + img_info = kzalloc_obj(*img_info); if (!img_info) return -ENOMEM; /* Allocate memory for entry */ - img_info->mhi_buf = kzalloc(sizeof(*img_info->mhi_buf), GFP_KERNEL); + img_info->mhi_buf = kzalloc_obj(*img_info->mhi_buf); if (!img_info->mhi_buf) goto error_alloc_mhi_buf; @@ -375,13 +375,12 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; - img_info = kzalloc(sizeof(*img_info), GFP_KERNEL); + img_info = kzalloc_obj(*img_info); if (!img_info) return -ENOMEM; /* Allocate memory for entries */ - img_info->mhi_buf = kcalloc(segments, sizeof(*img_info->mhi_buf), - GFP_KERNEL); + img_info->mhi_buf = kzalloc_objs(*img_info->mhi_buf, segments); if (!img_info->mhi_buf) goto error_alloc_mhi_buf; @@ -584,6 +583,16 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) * device transitioning into MHI READY state */ if (fw_load_type == MHI_FW_LOAD_FBC) { + /* + * Some FW combine two separate ELF images (SBL + WLAN FW) in a single + * file. Hence, check for the existence of the second ELF header after + * SBL. If present, load the second image separately. + */ + if (!memcmp(fw_data + mhi_cntrl->sbl_size, ELFMAG, SELFMAG)) { + fw_data += mhi_cntrl->sbl_size; + fw_sz -= mhi_cntrl->sbl_size; + } + ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); if (ret) { release_firmware(firmware); diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index 099be8dd1900..0a728ca2c494 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -313,7 +313,7 @@ static int mhi_init_dev_ctxt(struct mhi_controller *mhi_cntrl) atomic_set(&mhi_cntrl->dev_wake, 0); atomic_set(&mhi_cntrl->pending_pkts, 0); - mhi_ctxt = kzalloc(sizeof(*mhi_ctxt), GFP_KERNEL); + mhi_ctxt = kzalloc_obj(*mhi_ctxt); if (!mhi_ctxt) return -ENOMEM; @@ -699,8 +699,7 @@ static int parse_ev_cfg(struct mhi_controller *mhi_cntrl, num = config->num_events; mhi_cntrl->total_ev_rings = num; - mhi_cntrl->mhi_event = kcalloc(num, sizeof(*mhi_cntrl->mhi_event), - GFP_KERNEL); + mhi_cntrl->mhi_event = kzalloc_objs(*mhi_cntrl->mhi_event, num); if (!mhi_cntrl->mhi_event) return -ENOMEM; @@ -841,18 +840,8 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, mhi_chan->lpm_notify = ch_cfg->lpm_notify; mhi_chan->offload_ch = ch_cfg->offload_channel; mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch; - mhi_chan->pre_alloc = ch_cfg->auto_queue; mhi_chan->wake_capable = ch_cfg->wake_capable; - /* - * If MHI host allocates buffers, then the channel direction - * should be DMA_FROM_DEVICE - */ - if (mhi_chan->pre_alloc && mhi_chan->dir != DMA_FROM_DEVICE) { - dev_err(dev, "Invalid channel configuration\n"); - goto error_chan_cfg; - } - /* * Bi-directional and direction less channel must be an * offload channel @@ -948,8 +937,7 @@ int mhi_register_controller(struct mhi_controller *mhi_cntrl, if (ret) return -EINVAL; - mhi_cntrl->mhi_cmd = kcalloc(NR_OF_CMD_RINGS, - sizeof(*mhi_cntrl->mhi_cmd), GFP_KERNEL); + mhi_cntrl->mhi_cmd = kzalloc_objs(*mhi_cntrl->mhi_cmd, NR_OF_CMD_RINGS); if (!mhi_cntrl->mhi_cmd) { ret = -ENOMEM; goto err_free_event; @@ -1105,7 +1093,7 @@ struct mhi_controller *mhi_alloc_controller(void) { struct mhi_controller *mhi_cntrl; - mhi_cntrl = kzalloc(sizeof(*mhi_cntrl), GFP_KERNEL); + mhi_cntrl = kzalloc_obj(*mhi_cntrl); return mhi_cntrl; } @@ -1242,7 +1230,7 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl) struct mhi_device *mhi_dev; struct device *dev; - mhi_dev = kzalloc(sizeof(*mhi_dev), GFP_KERNEL); + mhi_dev = kzalloc_obj(*mhi_dev); if (!mhi_dev) return ERR_PTR(-ENOMEM); @@ -1265,7 +1253,7 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl) return mhi_dev; } -static int mhi_driver_probe(struct device *dev) +static int mhi_probe(struct device *dev) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; @@ -1341,7 +1329,7 @@ static int mhi_driver_probe(struct device *dev) return ret; } -static int mhi_driver_remove(struct device *dev) +static void mhi_remove(struct device *dev) { struct mhi_device *mhi_dev = to_mhi_device(dev); struct mhi_driver *mhi_drv = to_mhi_driver(dev->driver); @@ -1355,7 +1343,7 @@ static int mhi_driver_remove(struct device *dev) /* Skip if it is a controller device */ if (mhi_dev->dev_type == MHI_DEVICE_CONTROLLER) - return 0; + return; /* Reset both channels */ for (dir = 0; dir < 2; dir++) { @@ -1407,8 +1395,6 @@ static int mhi_driver_remove(struct device *dev) while (mhi_dev->dev_wake) mhi_device_put(mhi_dev); - - return 0; } int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner) @@ -1420,8 +1406,6 @@ int __mhi_driver_register(struct mhi_driver *mhi_drv, struct module *owner) driver->bus = &mhi_bus_type; driver->owner = owner; - driver->probe = mhi_driver_probe; - driver->remove = mhi_driver_remove; return driver_register(driver); } @@ -1468,6 +1452,8 @@ const struct bus_type mhi_bus_type = { .dev_name = "mhi", .match = mhi_match, .uevent = mhi_uevent, + .probe = mhi_probe, + .remove = mhi_remove, .dev_groups = mhi_dev_groups, }; diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 7937bb1f742c..7b0ee5e3a12d 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -286,7 +286,6 @@ struct mhi_chan { bool lpm_notify; bool configured; bool offload_ch; - bool pre_alloc; bool wake_capable; }; @@ -389,8 +388,6 @@ int mhi_rddm_prepare(struct mhi_controller *mhi_cntrl, struct image_info *img_info); void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl); -/* Automatically allocate and queue inbound buffers */ -#define MHI_CH_INBOUND_ALLOC_BUFS BIT(0) int mhi_init_chan_ctxt(struct mhi_controller *mhi_cntrl, struct mhi_chan *mhi_chan); void mhi_deinit_chan_ctxt(struct mhi_controller *mhi_cntrl, diff --git a/drivers/bus/mhi/host/main.c b/drivers/bus/mhi/host/main.c index 861551274319..53c0ffe30070 100644 --- a/drivers/bus/mhi/host/main.c +++ b/drivers/bus/mhi/host/main.c @@ -664,23 +664,6 @@ static int parse_xfer_event(struct mhi_controller *mhi_cntrl, mhi_cntrl->runtime_put(mhi_cntrl); } - /* - * Recycle the buffer if buffer is pre-allocated, - * if there is an error, not much we can do apart - * from dropping the packet - */ - if (mhi_chan->pre_alloc) { - if (mhi_queue_buf(mhi_chan->mhi_dev, - mhi_chan->dir, - buf_info->cb_buf, - buf_info->len, MHI_EOT)) { - dev_err(dev, - "Error recycling buffer for chan:%d\n", - mhi_chan->chan); - kfree(buf_info->cb_buf); - } - } - read_lock_bh(&mhi_chan->lock); } break; @@ -1177,17 +1160,12 @@ static int mhi_queue(struct mhi_device *mhi_dev, struct mhi_buf_info *buf_info, int mhi_queue_skb(struct mhi_device *mhi_dev, enum dma_data_direction dir, struct sk_buff *skb, size_t len, enum mhi_flags mflags) { - struct mhi_chan *mhi_chan = (dir == DMA_TO_DEVICE) ? mhi_dev->ul_chan : - mhi_dev->dl_chan; struct mhi_buf_info buf_info = { }; buf_info.v_addr = skb->data; buf_info.cb_buf = skb; buf_info.len = len; - if (unlikely(mhi_chan->pre_alloc)) - return -EINVAL; - return mhi_queue(mhi_dev, &buf_info, dir, mflags); } EXPORT_SYMBOL_GPL(mhi_queue_skb); @@ -1472,45 +1450,6 @@ static int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, if (ret) goto error_pm_state; - if (mhi_chan->dir == DMA_FROM_DEVICE) - mhi_chan->pre_alloc = !!(flags & MHI_CH_INBOUND_ALLOC_BUFS); - - /* Pre-allocate buffer for xfer ring */ - if (mhi_chan->pre_alloc) { - int nr_el = get_nr_avail_ring_elements(mhi_cntrl, - &mhi_chan->tre_ring); - size_t len = mhi_cntrl->buffer_len; - - while (nr_el--) { - void *buf; - struct mhi_buf_info info = { }; - - buf = kmalloc(len, GFP_KERNEL); - if (!buf) { - ret = -ENOMEM; - goto error_pre_alloc; - } - - /* Prepare transfer descriptors */ - info.v_addr = buf; - info.cb_buf = buf; - info.len = len; - ret = mhi_gen_tre(mhi_cntrl, mhi_chan, &info, MHI_EOT); - if (ret) { - kfree(buf); - goto error_pre_alloc; - } - } - - read_lock_bh(&mhi_cntrl->pm_lock); - if (MHI_DB_ACCESS_VALID(mhi_cntrl)) { - read_lock_irq(&mhi_chan->lock); - mhi_ring_chan_db(mhi_cntrl, mhi_chan); - read_unlock_irq(&mhi_chan->lock); - } - read_unlock_bh(&mhi_cntrl->pm_lock); - } - mutex_unlock(&mhi_chan->mutex); return 0; @@ -1522,12 +1461,6 @@ static int mhi_prepare_channel(struct mhi_controller *mhi_cntrl, error_init_chan: mutex_unlock(&mhi_chan->mutex); - return ret; - -error_pre_alloc: - mutex_unlock(&mhi_chan->mutex); - mhi_unprepare_channel(mhi_cntrl, mhi_chan); - return ret; } @@ -1600,12 +1533,8 @@ static void mhi_reset_data_chan(struct mhi_controller *mhi_cntrl, mhi_del_ring_element(mhi_cntrl, buf_ring); mhi_del_ring_element(mhi_cntrl, tre_ring); - if (mhi_chan->pre_alloc) { - kfree(buf_info->cb_buf); - } else { - result.buf_addr = buf_info->cb_buf; - mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); - } + result.buf_addr = buf_info->cb_buf; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); } } @@ -1666,12 +1595,6 @@ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev) } EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer); -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev) -{ - return __mhi_prepare_for_transfer(mhi_dev, MHI_CH_INBOUND_ALLOC_BUFS); -} -EXPORT_SYMBOL_GPL(mhi_prepare_for_transfer_autoqueue); - void mhi_unprepare_from_transfer(struct mhi_device *mhi_dev) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index e3bc737313a2..0884a384b77f 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -94,22 +94,6 @@ struct mhi_pci_dev_info { .doorbell_mode_switch = false, \ } -#define MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(ch_num, ch_name, el_count, ev_ring) \ - { \ - .num = ch_num, \ - .name = ch_name, \ - .num_elements = el_count, \ - .event_ring = ev_ring, \ - .dir = DMA_FROM_DEVICE, \ - .ee_mask = BIT(MHI_EE_AMSS), \ - .pollcfg = 0, \ - .doorbell = MHI_DB_BRST_DISABLE, \ - .lpm_notify = false, \ - .offload_channel = false, \ - .doorbell_mode_switch = false, \ - .auto_queue = true, \ - } - #define MHI_EVENT_CONFIG_CTRL(ev_ring, el_count) \ { \ .num_elements = el_count, \ @@ -329,7 +313,7 @@ static const struct mhi_channel_config modem_qcom_v1_mhi_channels[] = { MHI_CHANNEL_CONFIG_UL(14, "QMI", 4, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 4, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 8, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 8, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 8, 0), MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), MHI_CHANNEL_CONFIG_UL(46, "IP_SW0", 64, 2), @@ -762,7 +746,7 @@ static const struct mhi_channel_config mhi_telit_fn980_hw_v1_channels[] = { MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), MHI_CHANNEL_CONFIG_UL(20, "IPCR", 16, 0), - MHI_CHANNEL_CONFIG_DL_AUTOQUEUE(21, "IPCR", 16, 0), + MHI_CHANNEL_CONFIG_DL(21, "IPCR", 16, 0), MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 1), MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 2), }; diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index b4ef115189b5..f799503c8f36 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -764,7 +764,7 @@ static void mhi_pm_sys_error_transition(struct mhi_controller *mhi_cntrl) int mhi_queue_state_transition(struct mhi_controller *mhi_cntrl, enum dev_st_transition state) { - struct state_transition *item = kmalloc(sizeof(*item), GFP_ATOMIC); + struct state_transition *item = kmalloc_obj(*item, GFP_ATOMIC); unsigned long flags; if (!item) diff --git a/drivers/bus/mips_cdmm.c b/drivers/bus/mips_cdmm.c index 12dd32fd0b62..9804921dfe3d 100644 --- a/drivers/bus/mips_cdmm.c +++ b/drivers/bus/mips_cdmm.c @@ -306,7 +306,7 @@ static struct mips_cdmm_bus *mips_cdmm_get_bus(void) bus = *bus_p; /* Attempt allocation if NULL */ if (unlikely(!bus)) { - bus = kzalloc(sizeof(*bus), GFP_ATOMIC); + bus = kzalloc_obj(*bus, GFP_ATOMIC); if (unlikely(!bus)) bus = ERR_PTR(-ENOMEM); else @@ -541,7 +541,7 @@ static void mips_cdmm_bus_discover(struct mips_cdmm_bus *bus) (drb + size + 1) * CDMM_DRB_SIZE - 1, type, rev); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) break; diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c index 5a53bfab470a..0d68c1a9f493 100644 --- a/drivers/bus/moxtet.c +++ b/drivers/bus/moxtet.c @@ -145,7 +145,7 @@ moxtet_alloc_device(struct moxtet *moxtet) if (!get_device(moxtet->dev)) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { put_device(moxtet->dev); return NULL; diff --git a/drivers/bus/omap_l3_smx.c b/drivers/bus/omap_l3_smx.c index 7f0a8f8b3f4c..ee260c1fc087 100644 --- a/drivers/bus/omap_l3_smx.c +++ b/drivers/bus/omap_l3_smx.c @@ -215,7 +215,7 @@ static int omap3_l3_probe(struct platform_device *pdev) struct resource *res; int ret; - l3 = kzalloc(sizeof(*l3), GFP_KERNEL); + l3 = kzalloc_obj(*l3); if (!l3) return -ENOMEM; diff --git a/drivers/bus/stm32_firewall.c b/drivers/bus/stm32_firewall.c index 2fc9761dadec..7e7afe8007db 100644 --- a/drivers/bus/stm32_firewall.c +++ b/drivers/bus/stm32_firewall.c @@ -260,7 +260,7 @@ int stm32_firewall_populate_bus(struct stm32_firewall_controller *firewall_contr return -EINVAL; } - firewalls = kcalloc(len, sizeof(*firewalls), GFP_KERNEL); + firewalls = kzalloc_objs(*firewalls, len); if (!firewalls) { of_node_put(child); return -ENOMEM; diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index 82735c58be11..b4f2c64ac181 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -205,7 +205,7 @@ static struct sunxi_rsb_device *sunxi_rsb_device_create(struct sunxi_rsb *rsb, int err; struct sunxi_rsb_device *rdev; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); @@ -477,7 +477,7 @@ static struct sunxi_rsb_ctx *regmap_sunxi_rsb_init_ctx(struct sunxi_rsb_device * return ERR_PTR(-EINVAL); } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c index 610354ce7f8f..a5b9507de37c 100644 --- a/drivers/bus/ti-sysc.c +++ b/drivers/bus/ti-sysc.c @@ -354,7 +354,7 @@ static int sysc_add_named_clock_from_child(struct sysc *ddata, * limit for clk_get(). If cl ever needs to be freed, it should be done * with clkdev_drop(). */ - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return -ENOMEM; @@ -2470,7 +2470,7 @@ static void sysc_add_restored(struct sysc *ddata) { struct sysc_module *restored_module; - restored_module = kzalloc(sizeof(*restored_module), GFP_KERNEL); + restored_module = kzalloc_obj(*restored_module); if (!restored_module) return; @@ -2953,7 +2953,7 @@ static int sysc_add_disabled(unsigned long base) { struct sysc_address *disabled_module; - disabled_module = kzalloc(sizeof(*disabled_module), GFP_KERNEL); + disabled_module = kzalloc_obj(*disabled_module); if (!disabled_module) return -ENOMEM; @@ -2984,7 +2984,7 @@ static int sysc_init_static_data(struct sysc *ddata) if (sysc_soc) return 0; - sysc_soc = kzalloc(sizeof(*sysc_soc), GFP_KERNEL); + sysc_soc = kzalloc_obj(*sysc_soc); if (!sysc_soc) return -ENOMEM; diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c index 64ee920721ee..adaf5bd2b36d 100644 --- a/drivers/bus/vexpress-config.c +++ b/drivers/bus/vexpress-config.c @@ -284,7 +284,7 @@ static struct regmap *vexpress_syscfg_regmap_init(struct device *dev, val = energy_quirk; } - func = kzalloc(struct_size(func, template, num), GFP_KERNEL); + func = kzalloc_flex(*func, template, num); if (!func) return ERR_PTR(-ENOMEM); diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 31ba1f8c1f78..fc049612d6dc 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1318,7 +1318,7 @@ static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot) if (cdi->sanyo_slot) return CDS_NO_INFO; - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) return -ENOMEM; @@ -1347,7 +1347,7 @@ int cdrom_number_of_slots(struct cdrom_device_info *cdi) /* cdrom_read_mech_status requires a valid value for capacity: */ cdi->capacity = 0; - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) return -ENOMEM; @@ -1406,7 +1406,7 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) return cdrom_load_unload(cdi, -1); } - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) return -ENOMEM; @@ -2311,7 +2311,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, /* Prevent arg from speculatively bypassing the length check */ arg = array_index_nospec(arg, cdi->capacity); - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/cdrom/gdrom.c b/drivers/cdrom/gdrom.c index 85aceab5eac6..4ba4dd06cbf4 100644 --- a/drivers/cdrom/gdrom.c +++ b/drivers/cdrom/gdrom.c @@ -227,7 +227,7 @@ static char gdrom_execute_diagnostic(void) static int gdrom_preparedisk_cmd(void) { struct packet_command *spin_command; - spin_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL); + spin_command = kzalloc_obj(struct packet_command); if (!spin_command) return -ENOMEM; spin_command->cmd[0] = 0x70; @@ -261,7 +261,7 @@ static int gdrom_readtoc_cmd(struct gdromtoc *toc, int session) struct packet_command *toc_command; int err = 0; - toc_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL); + toc_command = kzalloc_obj(struct packet_command); if (!toc_command) return -ENOMEM; tocsize = sizeof(struct gdromtoc); @@ -415,7 +415,7 @@ static int gdrom_getsense(short *bufstring) int sense_key; int err = -EIO; - sense_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL); + sense_command = kzalloc_obj(struct packet_command); if (!sense_command) return -ENOMEM; sense_command->cmd[0] = 0x13; @@ -574,7 +574,7 @@ static blk_status_t gdrom_readdisk_dma(struct request *req) struct packet_command *read_command; unsigned long timeout; - read_command = kzalloc(sizeof(struct packet_command), GFP_KERNEL); + read_command = kzalloc_obj(struct packet_command); if (!read_command) return BLK_STS_RESOURCE; @@ -656,7 +656,7 @@ static int gdrom_outputversion(void) int err = -ENOMEM; /* query device ID */ - id = kzalloc(sizeof(struct gdrom_id), GFP_KERNEL); + id = kzalloc_obj(struct gdrom_id); if (!id) return err; gdrom_identifydevice(id); @@ -769,7 +769,7 @@ static int probe_gdrom(struct platform_device *devptr) pr_info("Registered with major number %d\n", gdrom_major); /* Specify basic properties of drive */ - gd.cd_info = kzalloc(sizeof(struct cdrom_device_info), GFP_KERNEL); + gd.cd_info = kzalloc_obj(struct cdrom_device_info); if (!gd.cd_info) { err = -ENOMEM; goto probe_fail_no_mem; @@ -803,7 +803,7 @@ static int probe_gdrom(struct platform_device *devptr) if (err) goto probe_fail_free_irqs; - gd.toc = kzalloc(sizeof(struct gdromtoc), GFP_KERNEL); + gd.toc = kzalloc_obj(struct gdromtoc); if (!gd.toc) { err = -ENOMEM; goto probe_fail_free_irqs; diff --git a/drivers/cdx/cdx.c b/drivers/cdx/cdx.c index 588dd12e8105..9196dc50a48d 100644 --- a/drivers/cdx/cdx.c +++ b/drivers/cdx/cdx.c @@ -789,7 +789,7 @@ int cdx_device_add(struct cdx_dev_params *dev_params) struct cdx_device *cdx_dev; int ret, i; - cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); + cdx_dev = kzalloc_obj(*cdx_dev); if (!cdx_dev) return -ENOMEM; @@ -876,7 +876,7 @@ struct device *cdx_bus_add(struct cdx_controller *cdx, u8 bus_num) struct cdx_device *cdx_dev; int ret; - cdx_dev = kzalloc(sizeof(*cdx_dev), GFP_KERNEL); + cdx_dev = kzalloc_obj(*cdx_dev); if (!cdx_dev) return NULL; diff --git a/drivers/cdx/controller/cdx_controller.c b/drivers/cdx/controller/cdx_controller.c index 280f207735da..280bb7490c0f 100644 --- a/drivers/cdx/controller/cdx_controller.c +++ b/drivers/cdx/controller/cdx_controller.c @@ -168,7 +168,7 @@ static int xlnx_cdx_probe(struct platform_device *pdev) struct cdx_mcdi *cdx_mcdi; int ret; - cdx_mcdi = kzalloc(sizeof(*cdx_mcdi), GFP_KERNEL); + cdx_mcdi = kzalloc_obj(*cdx_mcdi); if (!cdx_mcdi) return -ENOMEM; @@ -181,7 +181,7 @@ static int xlnx_cdx_probe(struct platform_device *pdev) goto mcdi_init_fail; } - cdx = kzalloc(sizeof(*cdx), GFP_KERNEL); + cdx = kzalloc_obj(*cdx); if (!cdx) { ret = -ENOMEM; goto cdx_alloc_fail; diff --git a/drivers/cdx/controller/mcdi.c b/drivers/cdx/controller/mcdi.c index 2e82ffc18d89..34a07d6f41a0 100644 --- a/drivers/cdx/controller/mcdi.c +++ b/drivers/cdx/controller/mcdi.c @@ -118,7 +118,7 @@ int cdx_mcdi_init(struct cdx_mcdi *cdx) struct cdx_mcdi_iface *mcdi; int rc = -ENOMEM; - cdx->mcdi = kzalloc(sizeof(*cdx->mcdi), GFP_KERNEL); + cdx->mcdi = kzalloc_obj(*cdx->mcdi); if (!cdx->mcdi) goto fail; @@ -456,11 +456,11 @@ static int cdx_mcdi_rpc_sync(struct cdx_mcdi *cdx, unsigned int cmd, if (outlen_actual) *outlen_actual = 0; - wait_data = kmalloc(sizeof(*wait_data), GFP_KERNEL); + wait_data = kmalloc_obj(*wait_data); if (!wait_data) return -ENOMEM; - cmd_item = kmalloc(sizeof(*cmd_item), GFP_KERNEL); + cmd_item = kmalloc_obj(*cmd_item); if (!cmd_item) { kfree(wait_data); return -ENOMEM; diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d2cfc584e202..2a3a37b2cf3c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -249,32 +249,6 @@ config SONYPI To compile this driver as a module, choose M here: the module will be called sonypi. -config MWAVE - tristate "ACP Modem (Mwave) support" - depends on X86 && TTY - select SERIAL_8250 - help - The ACP modem (Mwave) for Linux is a WinModem. It is composed of a - kernel driver and a user level application. Together these components - support direct attachment to public switched telephone networks (PSTNs) - and support selected world wide countries. - - This version of the ACP Modem driver supports the IBM Thinkpad 600E, - 600, and 770 that include on board ACP modem hardware. - - The modem also supports the standard communications port interface - (ttySx) and is compatible with the Hayes AT Command Set. - - The user level application needed to use this driver can be found at - the IBM Linux Technology Center (LTC) web site: - . - - If you own one of the above IBM Thinkpads which has the Mwave chipset - in it, say Y. - - To compile this driver as a module, choose M here: the - module will be called mwave. - config SCx200_GPIO tristate "NatSemi SCx200 GPIO Support" depends on SCx200 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 1291369b9126..47bdc882797a 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_PC8736x_GPIO) += pc8736x_gpio.o obj-$(CONFIG_NSC_GPIO) += nsc_gpio.o obj-$(CONFIG_TELCLOCK) += tlclk.o -obj-$(CONFIG_MWAVE) += mwave/ obj-y += agp/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 795c8c9ff680..898ff30ffd46 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -85,13 +85,12 @@ static int amd_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kcalloc(nr_tables + 1, sizeof(struct amd_page_map *), - GFP_KERNEL); + tables = kzalloc_objs(struct amd_page_map *, nr_tables + 1); if (tables == NULL) return -ENOMEM; for (i = 0; i < nr_tables; i++) { - entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL); + entry = kzalloc_obj(struct amd_page_map); tables[i] = entry; if (entry == NULL) { retval = -ENOMEM; diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index f7871afe08cf..485b02fc9b18 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -112,13 +112,12 @@ static int ati_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kcalloc(nr_tables + 1, sizeof(struct ati_page_map *), - GFP_KERNEL); + tables = kzalloc_objs(struct ati_page_map *, nr_tables + 1); if (tables == NULL) return -ENOMEM; for (i = 0; i < nr_tables; i++) { - entry = kzalloc(sizeof(struct ati_page_map), GFP_KERNEL); + entry = kzalloc_obj(struct ati_page_map); tables[i] = entry; if (entry == NULL) { retval = -ENOMEM; diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 1776afd3ee07..4d920ca534a4 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c @@ -238,7 +238,7 @@ struct agp_bridge_data *agp_alloc_bridge(void) { struct agp_bridge_data *bridge; - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return NULL; diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 3ffbb1c80c5c..41752ed2b075 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -101,7 +101,7 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) if (INT_MAX/sizeof(struct page *) < num_agp_pages) return NULL; - new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); + new = kzalloc_obj(struct agp_memory); if (new == NULL) return NULL; @@ -127,7 +127,7 @@ struct agp_memory *agp_create_memory(int scratch_pages) { struct agp_memory *new; - new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); + new = kzalloc_obj(struct agp_memory); if (new == NULL) return NULL; diff --git a/drivers/char/agp/isoch.c b/drivers/char/agp/isoch.c index 7ecf20a6d19c..698182609b92 100644 --- a/drivers/char/agp/isoch.c +++ b/drivers/char/agp/isoch.c @@ -92,7 +92,7 @@ static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge, * We'll work with an array of isoch_data's (one for each * device in dev_list) throughout this function. */ - master = kmalloc_array(ndevs, sizeof(*master), GFP_KERNEL); + master = kmalloc_objs(*master, ndevs); if (master == NULL) { ret = -ENOMEM; goto get_out; @@ -333,7 +333,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) * Allocate a head for our AGP 3.5 device list * (multiple AGP v3 devices are allowed behind a single bridge). */ - if ((dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL)) == NULL) { + if ((dev_list = kmalloc_obj(*dev_list)) == NULL) { ret = -ENOMEM; goto get_out; } @@ -362,7 +362,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge) case 0x0300: /* Display controller */ case 0x0400: /* Multimedia controller */ - if ((cur = kmalloc(sizeof(*cur), GFP_KERNEL)) == NULL) { + if ((cur = kmalloc_obj(*cur)) == NULL) { ret = -ENOMEM; goto free_and_exit; } diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 0ab7562d17c9..8f6781c2701a 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -96,13 +96,12 @@ static int serverworks_create_gatt_pages(int nr_tables) int retval = 0; int i; - tables = kcalloc(nr_tables + 1, sizeof(struct serverworks_page_map *), - GFP_KERNEL); + tables = kzalloc_objs(struct serverworks_page_map *, nr_tables + 1); if (tables == NULL) return -ENOMEM; for (i = 0; i < nr_tables; i++) { - entry = kzalloc(sizeof(struct serverworks_page_map), GFP_KERNEL); + entry = kzalloc_obj(struct serverworks_page_map); if (entry == NULL) { retval = -ENOMEM; break; diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index b8d7115b8c9e..08175fe2f530 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -404,9 +404,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) if (table == NULL) return -ENOMEM; - uninorth_priv.pages_arr = kmalloc_array(1 << page_order, - sizeof(struct page *), - GFP_KERNEL); + uninorth_priv.pages_arr = kmalloc_objs(struct page *, 1 << page_order); if (uninorth_priv.pages_arr == NULL) goto enomem; diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c index 4aa5d1c76f83..389874f44967 100644 --- a/drivers/char/apm-emulation.c +++ b/drivers/char/apm-emulation.c @@ -343,7 +343,7 @@ static int apm_open(struct inode * inode, struct file * filp) { struct apm_user *as; - as = kzalloc(sizeof(*as), GFP_KERNEL); + as = kzalloc_obj(*as); if (as) { /* * XXX - this is a tiny bit broken, when we consider BSD diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 837109ef6766..98e9327bf65d 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c @@ -186,8 +186,7 @@ static int bsr_add_node(struct device_node *bn) num_bsr_devs = bsr_bytes_len / sizeof(u32); for (i = 0 ; i < num_bsr_devs; i++) { - struct bsr_dev *cur = kzalloc(sizeof(struct bsr_dev), - GFP_KERNEL); + struct bsr_dev *cur = kzalloc_obj(struct bsr_dev); struct resource res; int result; diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index 4f5ccd3a1f56..60dd09a56f50 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -823,8 +823,7 @@ int hpet_alloc(struct hpet_data *hdp) return 0; } - hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs), - GFP_KERNEL); + hpetp = kzalloc_flex(*hpetp, hp_dev, hdp->hd_nirqs); if (!hpetp) return -ENOMEM; diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index 9a24d19236dc..332d594bdf70 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c @@ -154,7 +154,7 @@ static int __init amd_rng_mod_init(void) goto put_dev; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { err = -ENOMEM; goto put_dev; diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index 159baf00a867..1b21d58e1768 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c @@ -107,7 +107,7 @@ static int __init geode_rng_init(void) return err; found: - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { err = -ENOMEM; goto put_dev; diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 7b171cb3b825..d24e747203c1 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -346,7 +346,7 @@ static int __init intel_rng_mod_init(void) goto fwh_done; } - intel_rng_hw = kmalloc(sizeof(*intel_rng_hw), GFP_KERNEL); + intel_rng_hw = kmalloc_obj(*intel_rng_hw); if (!intel_rng_hw) { pci_dev_put(dev); goto out; diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index eb80a031c7be..0ce02d7e5048 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -134,7 +134,7 @@ static int probe_common(struct virtio_device *vdev) int err, index; struct virtrng_info *vi = NULL; - vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL); + vi = kzalloc_obj(struct virtrng_info); if (!vi) return -ENOMEM; diff --git a/drivers/char/ipmi/ipmb_dev_int.c b/drivers/char/ipmi/ipmb_dev_int.c index ee2bdc7ed0da..2fe1d205ce4e 100644 --- a/drivers/char/ipmi/ipmb_dev_int.c +++ b/drivers/char/ipmi/ipmb_dev_int.c @@ -208,7 +208,7 @@ static void ipmb_handle_request(struct ipmb_dev *ipmb_dev) REQUEST_QUEUE_MAX_LEN) return; - queue_elem = kmalloc(sizeof(*queue_elem), GFP_ATOMIC); + queue_elem = kmalloc_obj(*queue_elem, GFP_ATOMIC); if (!queue_elem) return; diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index e6ba35b71f10..38d0f1bc10b0 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -90,7 +90,7 @@ static int ipmi_open(struct inode *inode, struct file *file) int rv; struct ipmi_file_private *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -813,7 +813,7 @@ static void ipmi_new_smi(int if_num, struct device *device) dev_t dev = MKDEV(ipmi_major, if_num); struct ipmi_reg_list *entry; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { pr_err("ipmi_devintf: Unable to create the ipmi class device link\n"); return; diff --git a/drivers/char/ipmi/ipmi_dmi.c b/drivers/char/ipmi/ipmi_dmi.c index bbf7029e224b..505e32911c34 100644 --- a/drivers/char/ipmi/ipmi_dmi.c +++ b/drivers/char/ipmi/ipmi_dmi.c @@ -74,7 +74,7 @@ static void __init dmi_add_platform_ipmi(unsigned long base_addr, p.slave_addr = slave_addr; p.addr_source = SI_SMBIOS; - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) { pr_warn("Could not allocate dmi info\n"); } else { diff --git a/drivers/char/ipmi/ipmi_ipmb.c b/drivers/char/ipmi/ipmi_ipmb.c index 3a51e58b2487..28818952a7a4 100644 --- a/drivers/char/ipmi/ipmi_ipmb.c +++ b/drivers/char/ipmi/ipmi_ipmb.c @@ -202,11 +202,16 @@ static int ipmi_ipmb_slave_cb(struct i2c_client *client, break; case I2C_SLAVE_READ_REQUESTED: + *val = 0xff; + ipmi_ipmb_check_msg_done(iidev); + break; + case I2C_SLAVE_STOP: ipmi_ipmb_check_msg_done(iidev); break; case I2C_SLAVE_READ_PROCESSED: + *val = 0xff; break; } diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 3f48fc6ab596..c41f51c82edd 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -602,6 +602,22 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf, static int __scan_channels(struct ipmi_smi *intf, struct ipmi_device_id *id, bool rescan); +static void ipmi_lock_xmit_msgs(struct ipmi_smi *intf, int run_to_completion, + unsigned long *flags) +{ + if (run_to_completion) + return; + spin_lock_irqsave(&intf->xmit_msgs_lock, *flags); +} + +static void ipmi_unlock_xmit_msgs(struct ipmi_smi *intf, int run_to_completion, + unsigned long *flags) +{ + if (run_to_completion) + return; + spin_unlock_irqrestore(&intf->xmit_msgs_lock, *flags); +} + static void free_ipmi_user(struct kref *ref) { struct ipmi_user *user = container_of(ref, struct ipmi_user, refcount); @@ -761,13 +777,11 @@ int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) list_for_each_entry(intf, &ipmi_interfaces, link) count++; if (count > 0) { - interfaces = kmalloc_array(count, sizeof(*interfaces), - GFP_KERNEL); + interfaces = kmalloc_objs(*interfaces, count); if (!interfaces) { rv = -ENOMEM; } else { - devices = kmalloc_array(count, sizeof(*devices), - GFP_KERNEL); + devices = kmalloc_objs(*devices, count); if (!devices) { kfree(interfaces); interfaces = NULL; @@ -1686,7 +1700,7 @@ int ipmi_register_for_cmd(struct ipmi_user *user, if (!user) return -ENODEV; - rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL); + rcvr = kmalloc_obj(*rcvr); if (!rcvr) { rv = -ENOMEM; goto out_release; @@ -1871,21 +1885,32 @@ static struct ipmi_smi_msg *smi_add_send_msg(struct ipmi_smi *intf, return smi_msg; } -static void smi_send(struct ipmi_smi *intf, +static int smi_send(struct ipmi_smi *intf, const struct ipmi_smi_handlers *handlers, struct ipmi_smi_msg *smi_msg, int priority) { int run_to_completion = READ_ONCE(intf->run_to_completion); unsigned long flags = 0; + int rv = 0; - if (!run_to_completion) - spin_lock_irqsave(&intf->xmit_msgs_lock, flags); + ipmi_lock_xmit_msgs(intf, run_to_completion, &flags); smi_msg = smi_add_send_msg(intf, smi_msg, priority); - if (!run_to_completion) - spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); + ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags); - if (smi_msg) - handlers->sender(intf->send_info, smi_msg); + if (smi_msg) { + rv = handlers->sender(intf->send_info, smi_msg); + if (rv) { + ipmi_lock_xmit_msgs(intf, run_to_completion, &flags); + intf->curr_msg = NULL; + ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags); + /* + * Something may have been added to the transmit + * queue, so schedule a check for that. + */ + queue_work(system_wq, &intf->smi_work); + } + } + return rv; } static bool is_maintenance_mode_cmd(struct kernel_ipmi_msg *msg) @@ -2298,6 +2323,7 @@ static int i_ipmi_request(struct ipmi_user *user, struct ipmi_recv_msg *recv_msg; int run_to_completion = READ_ONCE(intf->run_to_completion); int rv = 0; + bool in_seq_table = false; if (supplied_recv) { recv_msg = supplied_recv; @@ -2351,33 +2377,50 @@ static int i_ipmi_request(struct ipmi_user *user, rv = i_ipmi_req_ipmb(intf, addr, msgid, msg, smi_msg, recv_msg, source_address, source_lun, retries, retry_time_ms); + in_seq_table = true; } else if (is_ipmb_direct_addr(addr)) { rv = i_ipmi_req_ipmb_direct(intf, addr, msgid, msg, smi_msg, recv_msg, source_lun); } else if (is_lan_addr(addr)) { rv = i_ipmi_req_lan(intf, addr, msgid, msg, smi_msg, recv_msg, source_lun, retries, retry_time_ms); + in_seq_table = true; } else { - /* Unknown address type. */ + /* Unknown address type. */ ipmi_inc_stat(intf, sent_invalid_commands); rv = -EINVAL; } - if (rv) { + if (!rv) { + dev_dbg(intf->si_dev, "Send: %*ph\n", + smi_msg->data_size, smi_msg->data); + + rv = smi_send(intf, intf->handlers, smi_msg, priority); + if (rv != IPMI_CC_NO_ERROR) + /* smi_send() returns an IPMI err, return a Linux one. */ + rv = -EIO; + if (rv && in_seq_table) { + /* + * If it's in the sequence table, it will be + * retried later, so ignore errors. + */ + rv = 0; + /* But we need to fix the timeout. */ + intf_start_seq_timer(intf, smi_msg->msgid); + ipmi_free_smi_msg(smi_msg); + smi_msg = NULL; + } + } out_err: + if (!run_to_completion) + mutex_unlock(&intf->users_mutex); + + if (rv) { if (!supplied_smi) ipmi_free_smi_msg(smi_msg); if (!supplied_recv) ipmi_free_recv_msg(recv_msg); - } else { - dev_dbg(intf->si_dev, "Send: %*ph\n", - smi_msg->data_size, smi_msg->data); - - smi_send(intf, intf->handlers, smi_msg, priority); } - if (!run_to_completion) - mutex_unlock(&intf->users_mutex); - return rv; } @@ -3146,7 +3189,7 @@ static int __ipmi_bmc_register(struct ipmi_smi *intf, bmc->id.product_id, bmc->id.device_id); } else { - bmc = kzalloc(sizeof(*bmc), GFP_KERNEL); + bmc = kzalloc_obj(*bmc); if (!bmc) { rv = -ENOMEM; goto out; @@ -3582,7 +3625,7 @@ int ipmi_add_smi(struct module *owner, if (rv) return rv; - intf = kzalloc(sizeof(*intf), GFP_KERNEL); + intf = kzalloc_obj(*intf); if (!intf) return -ENOMEM; @@ -3951,12 +3994,12 @@ static int handle_ipmb_get_msg_cmd(struct ipmi_smi *intf, dev_dbg(intf->si_dev, "Invalid command: %*ph\n", msg->data_size, msg->data); - smi_send(intf, intf->handlers, msg, 0); - /* - * We used the message, so return the value that - * causes it to not be freed or queued. - */ - rv = -1; + if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR) + /* + * We used the message, so return the value that + * causes it to not be freed or queued. + */ + rv = -1; } else if (!IS_ERR(recv_msg)) { /* Extract the source address from the data. */ ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr; @@ -4030,12 +4073,12 @@ static int handle_ipmb_direct_rcv_cmd(struct ipmi_smi *intf, msg->data[4] = IPMI_INVALID_CMD_COMPLETION_CODE; msg->data_size = 5; - smi_send(intf, intf->handlers, msg, 0); - /* - * We used the message, so return the value that - * causes it to not be freed or queued. - */ - rv = -1; + if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR) + /* + * We used the message, so return the value that + * causes it to not be freed or queued. + */ + rv = -1; } else if (!IS_ERR(recv_msg)) { /* Extract the source address from the data. */ daddr = (struct ipmi_ipmb_direct_addr *)&recv_msg->addr; @@ -4175,7 +4218,7 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, struct ipmi_smi_msg *msg) { struct cmd_rcvr *rcvr; - int rv = 0; + int rv = 0; /* Free by default */ unsigned char netfn; unsigned char cmd; unsigned char chan; @@ -4228,12 +4271,12 @@ static int handle_lan_get_msg_cmd(struct ipmi_smi *intf, dev_dbg(intf->si_dev, "Invalid command: %*ph\n", msg->data_size, msg->data); - smi_send(intf, intf->handlers, msg, 0); - /* - * We used the message, so return the value that - * causes it to not be freed or queued. - */ - rv = -1; + if (smi_send(intf, intf->handlers, msg, 0) == IPMI_CC_NO_ERROR) + /* + * We used the message, so return the value that + * causes it to not be freed or queued. + */ + rv = -1; } else if (!IS_ERR(recv_msg)) { /* Extract the source address from the data. */ lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr; @@ -4826,8 +4869,7 @@ static void smi_work(struct work_struct *t) * message delivery. */ restart: - if (!run_to_completion) - spin_lock_irqsave(&intf->xmit_msgs_lock, flags); + ipmi_lock_xmit_msgs(intf, run_to_completion, &flags); if (intf->curr_msg == NULL && !intf->in_shutdown) { struct list_head *entry = NULL; @@ -4843,8 +4885,7 @@ static void smi_work(struct work_struct *t) intf->curr_msg = newmsg; } } - if (!run_to_completion) - spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); + ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags); if (newmsg) { cc = intf->handlers->sender(intf->send_info, newmsg); @@ -4852,8 +4893,11 @@ static void smi_work(struct work_struct *t) if (newmsg->recv_msg) deliver_err_response(intf, newmsg->recv_msg, cc); - else - ipmi_free_smi_msg(newmsg); + ipmi_lock_xmit_msgs(intf, run_to_completion, &flags); + intf->curr_msg = NULL; + ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags); + ipmi_free_smi_msg(newmsg); + newmsg = NULL; goto restart; } } @@ -4921,16 +4965,14 @@ void ipmi_smi_msg_received(struct ipmi_smi *intf, spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, flags); - if (!run_to_completion) - spin_lock_irqsave(&intf->xmit_msgs_lock, flags); + ipmi_lock_xmit_msgs(intf, run_to_completion, &flags); /* * We can get an asynchronous event or receive message in addition * to commands we send. */ if (msg == intf->curr_msg) intf->curr_msg = NULL; - if (!run_to_completion) - spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags); + ipmi_unlock_xmit_msgs(intf, run_to_completion, &flags); if (run_to_completion) smi_work(&intf->smi_work); @@ -5043,7 +5085,12 @@ static void check_msg_timeout(struct ipmi_smi *intf, struct seq_table *ent, ipmi_inc_stat(intf, retransmitted_ipmb_commands); - smi_send(intf, intf->handlers, smi_msg, 0); + /* If this fails we'll retry later or timeout. */ + if (smi_send(intf, intf->handlers, smi_msg, 0) != IPMI_CC_NO_ERROR) { + /* But fix the timeout. */ + intf_start_seq_timer(intf, smi_msg->msgid); + ipmi_free_smi_msg(smi_msg); + } } else ipmi_free_smi_msg(smi_msg); @@ -5195,7 +5242,7 @@ static void free_smi_msg(struct ipmi_smi_msg *msg) struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) { struct ipmi_smi_msg *rv; - rv = kmalloc(sizeof(struct ipmi_smi_msg), GFP_ATOMIC); + rv = kmalloc_obj(struct ipmi_smi_msg, GFP_ATOMIC); if (rv) { rv->done = free_smi_msg; rv->recv_msg = NULL; @@ -5225,7 +5272,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(struct ipmi_user *user) } } - rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC); + rv = kmalloc_obj(struct ipmi_recv_msg, GFP_ATOMIC); if (!rv) { if (user) atomic_dec(&user->nr_msgs); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 5459ffdde8dc..4a9e9de4d684 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -809,6 +809,12 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info, */ return_hosed_msg(smi_info, IPMI_BUS_ERR); } + if (smi_info->waiting_msg != NULL) { + /* Also handle if there was a message waiting. */ + smi_info->curr_msg = smi_info->waiting_msg; + smi_info->waiting_msg = NULL; + return_hosed_msg(smi_info, IPMI_BUS_ERR); + } smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_HOSED); goto out; } @@ -918,9 +924,14 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg) { struct smi_info *smi_info = send_info; unsigned long flags; + int rv = IPMI_CC_NO_ERROR; debug_timestamp(smi_info, "Enqueue"); + /* + * Check here for run to completion mode. A check under lock is + * later. + */ if (smi_info->si_state == SI_HOSED) return IPMI_BUS_ERR; @@ -934,18 +945,15 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg) } spin_lock_irqsave(&smi_info->si_lock, flags); - /* - * The following two lines don't need to be under the lock for - * the lock's sake, but they do need SMP memory barriers to - * avoid getting things out of order. We are already claiming - * the lock, anyway, so just do it under the lock to avoid the - * ordering problem. - */ - BUG_ON(smi_info->waiting_msg); - smi_info->waiting_msg = msg; - check_start_timer_thread(smi_info); + if (smi_info->si_state == SI_HOSED) { + rv = IPMI_BUS_ERR; + } else { + BUG_ON(smi_info->waiting_msg); + smi_info->waiting_msg = msg; + check_start_timer_thread(smi_info); + } spin_unlock_irqrestore(&smi_info->si_lock, flags); - return IPMI_CC_NO_ERROR; + return rv; } static void set_run_to_completion(void *send_info, bool i_run_to_completion) @@ -1113,7 +1121,9 @@ static void smi_timeout(struct timer_list *t) * SI_USEC_PER_JIFFY); smi_result = smi_event_handler(smi_info, time_diff); - if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) { + if (smi_info->si_state == SI_HOSED) { + timeout = jiffies + SI_TIMEOUT_HOSED; + } else if ((smi_info->io.irq) && (!smi_info->interrupt_disabled)) { /* Running with interrupts, only do long timeouts. */ timeout = jiffies + SI_TIMEOUT_JIFFIES; smi_inc_stat(smi_info, long_timeouts); @@ -1914,7 +1924,7 @@ int ipmi_si_add_smi(struct si_sm_io *io) } } - new_smi = kzalloc(sizeof(*new_smi), GFP_KERNEL); + new_smi = kzalloc_obj(*new_smi); if (!new_smi) return -ENOMEM; spin_lock_init(&new_smi->si_lock); @@ -2226,7 +2236,8 @@ static void wait_msg_processed(struct smi_info *smi_info) unsigned long jiffies_now; long time_diff; - while (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL)) { + while (smi_info->si_state != SI_HOSED && + (smi_info->curr_msg || (smi_info->si_state != SI_NORMAL))) { jiffies_now = jiffies; time_diff = (((long)jiffies_now - (long)smi_info->last_timeout_jiffies) * SI_USEC_PER_JIFFY); diff --git a/drivers/char/ipmi/ipmi_si_ls2k.c b/drivers/char/ipmi/ipmi_si_ls2k.c index 45442c257efd..4c1da80f256c 100644 --- a/drivers/char/ipmi/ipmi_si_ls2k.c +++ b/drivers/char/ipmi/ipmi_si_ls2k.c @@ -168,7 +168,7 @@ static void ipmi_ls2k_remove(struct platform_device *pdev) ipmi_si_remove_by_dev(&pdev->dev); } -struct platform_driver ipmi_ls2k_platform_driver = { +static struct platform_driver ipmi_ls2k_platform_driver = { .driver = { .name = "ls2k-ipmi-si", }, diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c index ef1582a029f4..37a5cb5c53f1 100644 --- a/drivers/char/ipmi/ipmi_ssif.c +++ b/drivers/char/ipmi/ipmi_ssif.c @@ -1602,7 +1602,7 @@ static int ssif_add_infos(struct i2c_client *client) { struct ssif_addr_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->addr_src = SI_ACPI; @@ -1667,7 +1667,7 @@ static int ssif_probe(struct i2c_client *client) return -ENOMEM; } - ssif_info = kzalloc(sizeof(*ssif_info), GFP_KERNEL); + ssif_info = kzalloc_obj(*ssif_info); if (!ssif_info) { kfree(resp); mutex_unlock(&ssif_infos_mutex); @@ -1948,7 +1948,7 @@ static int new_ssif_client(int addr, char *adapter_name, goto out_unlock; } - addr_info = kzalloc(sizeof(*addr_info), GFP_KERNEL); + addr_info = kzalloc_obj(*addr_info); if (!addr_info) { rv = -ENOMEM; goto out_unlock; diff --git a/drivers/char/ipmi/kcs_bmc_serio.c b/drivers/char/ipmi/kcs_bmc_serio.c index 1793358be782..1a95d6f258ea 100644 --- a/drivers/char/ipmi/kcs_bmc_serio.c +++ b/drivers/char/ipmi/kcs_bmc_serio.c @@ -77,7 +77,7 @@ static int kcs_bmc_serio_add_device(struct kcs_bmc_device *kcs_bmc) return -ENOMEM; /* Use kzalloc() as the allocation is cleaned up with kfree() via serio_unregister_port() */ - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 52039fae1594..cca4529431f8 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -306,7 +306,7 @@ static unsigned zero_mmap_capabilities(struct file *file) /* can't do an in-place private mapping if there's no MMU */ static inline int private_mapping_ok(struct vm_area_desc *desc) { - return is_nommu_shared_mapping(desc->vm_flags); + return is_nommu_shared_vma_flags(&desc->vma_flags); } #else @@ -360,7 +360,7 @@ static int mmap_mem_prepare(struct vm_area_desc *desc) desc->vm_ops = &mmap_mem_ops; - /* Remap-pfn-range will mark the range VM_IO. */ + /* Remap-pfn-range will mark the range with the I/O flag. */ mmap_action_remap_full(desc, desc->pgoff); /* We filter remap errors to -EAGAIN. */ desc->action.error_hook = mmap_filter_error; @@ -520,7 +520,7 @@ static int mmap_zero_prepare(struct vm_area_desc *desc) #ifndef CONFIG_MMU return -ENOSYS; #endif - if (desc->vm_flags & VM_SHARED) + if (vma_desc_test_flags(desc, VMA_SHARED_BIT)) return shmem_zero_setup_desc(desc); desc->action.success_hook = mmap_zero_private_success; diff --git a/drivers/char/misc_minor_kunit.c b/drivers/char/misc_minor_kunit.c index 6fc8b05169c5..e930c78e1ef9 100644 --- a/drivers/char/misc_minor_kunit.c +++ b/drivers/char/misc_minor_kunit.c @@ -166,7 +166,7 @@ static void __init miscdev_test_can_open(struct kunit *test, struct miscdevice * KUNIT_FAIL(test, "failed to create node\n"); filp = filp_open(devname, O_RDONLY, 0); - if (IS_ERR_OR_NULL(filp)) + if (IS_ERR(filp)) KUNIT_FAIL(test, "failed to open misc device: %ld\n", PTR_ERR(filp)); else fput(filp); diff --git a/drivers/char/mwave/3780i.c b/drivers/char/mwave/3780i.c deleted file mode 100644 index 90f93cefb21c..000000000000 --- a/drivers/char/mwave/3780i.c +++ /dev/null @@ -1,536 +0,0 @@ -/* -* -* 3780i.c -- helper routines for the 3780i DSP -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#define pr_fmt(fmt) "3780i: " fmt - -#include -#include -#include -#include -#include -#include /* cond_resched() */ - -#include -#include -#include -#include "smapi.h" -#include "mwavedd.h" -#include "3780i.h" - -static DEFINE_SPINLOCK(dsp_lock); - -static void PaceMsaAccess(unsigned short usDspBaseIO) -{ - cond_resched(); - udelay(100); - cond_resched(); -} - -unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, - unsigned long ulMsaAddr) -{ - unsigned long flags; - unsigned short val; - - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); - val = InWordDsp(DSP_MsaDataDSISHigh); - spin_unlock_irqrestore(&dsp_lock, flags); - - return val; -} - -void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, - unsigned long ulMsaAddr, unsigned short usValue) -{ - unsigned long flags; - - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulMsaAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulMsaAddr >> 16)); - OutWordDsp(DSP_MsaDataDSISHigh, usValue); - spin_unlock_irqrestore(&dsp_lock, flags); -} - -static void dsp3780I_WriteGenCfg(unsigned short usDspBaseIO, unsigned uIndex, - unsigned char ucValue) -{ - DSP_ISA_SLAVE_CONTROL rSlaveControl; - DSP_ISA_SLAVE_CONTROL rSlaveControl_Save; - - MKBYTE(rSlaveControl) = InByteDsp(DSP_IsaSlaveControl); - - rSlaveControl_Save = rSlaveControl; - rSlaveControl.ConfigMode = true; - - OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl)); - OutByteDsp(DSP_ConfigAddress, (unsigned char) uIndex); - OutByteDsp(DSP_ConfigData, ucValue); - OutByteDsp(DSP_IsaSlaveControl, MKBYTE(rSlaveControl_Save)); -} - -int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings, - unsigned short *pIrqMap, - unsigned short *pDmaMap) -{ - unsigned long flags; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - int i; - DSP_UART_CFG_1 rUartCfg1; - DSP_UART_CFG_2 rUartCfg2; - DSP_HBRIDGE_CFG_1 rHBridgeCfg1; - DSP_HBRIDGE_CFG_2 rHBridgeCfg2; - DSP_BUSMASTER_CFG_1 rBusmasterCfg1; - DSP_BUSMASTER_CFG_2 rBusmasterCfg2; - DSP_ISA_PROT_CFG rIsaProtCfg; - DSP_POWER_MGMT_CFG rPowerMgmtCfg; - DSP_HBUS_TIMER_CFG rHBusTimerCfg; - DSP_LBUS_TIMEOUT_DISABLE rLBusTimeoutDisable; - DSP_CHIP_RESET rChipReset; - DSP_CLOCK_CONTROL_1 rClockControl1; - DSP_CLOCK_CONTROL_2 rClockControl2; - DSP_ISA_SLAVE_CONTROL rSlaveControl; - DSP_HBRIDGE_CONTROL rHBridgeControl; - unsigned short tval; - - if (!pSettings->bDSPEnabled) { - pr_err("%s: Error: DSP not enabled. Aborting.\n", __func__); - return -EIO; - } - - if (pSettings->bModemEnabled) { - rUartCfg1.Reserved = rUartCfg2.Reserved = 0; - rUartCfg1.IrqActiveLow = pSettings->bUartIrqActiveLow; - rUartCfg1.IrqPulse = pSettings->bUartIrqPulse; - rUartCfg1.Irq = - (unsigned char) pIrqMap[pSettings->usUartIrq]; - switch (pSettings->usUartBaseIO) { - case 0x03F8: - rUartCfg1.BaseIO = 0; - break; - case 0x02F8: - rUartCfg1.BaseIO = 1; - break; - case 0x03E8: - rUartCfg1.BaseIO = 2; - break; - case 0x02E8: - rUartCfg1.BaseIO = 3; - break; - } - rUartCfg2.Enable = true; - } - - rHBridgeCfg1.Reserved = rHBridgeCfg2.Reserved = 0; - rHBridgeCfg1.IrqActiveLow = pSettings->bDspIrqActiveLow; - rHBridgeCfg1.IrqPulse = pSettings->bDspIrqPulse; - rHBridgeCfg1.Irq = (unsigned char) pIrqMap[pSettings->usDspIrq]; - rHBridgeCfg1.AccessMode = 1; - rHBridgeCfg2.Enable = true; - - - rBusmasterCfg2.Reserved = 0; - rBusmasterCfg1.Dma = (unsigned char) pDmaMap[pSettings->usDspDma]; - rBusmasterCfg1.NumTransfers = - (unsigned char) pSettings->usNumTransfers; - rBusmasterCfg1.ReRequest = (unsigned char) pSettings->usReRequest; - rBusmasterCfg1.MEMCS16 = pSettings->bEnableMEMCS16; - rBusmasterCfg2.IsaMemCmdWidth = - (unsigned char) pSettings->usIsaMemCmdWidth; - - - rIsaProtCfg.Reserved = 0; - rIsaProtCfg.GateIOCHRDY = pSettings->bGateIOCHRDY; - - rPowerMgmtCfg.Reserved = 0; - rPowerMgmtCfg.Enable = pSettings->bEnablePwrMgmt; - - rHBusTimerCfg.LoadValue = - (unsigned char) pSettings->usHBusTimerLoadValue; - - rLBusTimeoutDisable.Reserved = 0; - rLBusTimeoutDisable.DisableTimeout = - pSettings->bDisableLBusTimeout; - - MKWORD(rChipReset) = ~pSettings->usChipletEnable; - - rClockControl1.Reserved1 = rClockControl1.Reserved2 = 0; - rClockControl1.N_Divisor = pSettings->usN_Divisor; - rClockControl1.M_Multiplier = pSettings->usM_Multiplier; - - rClockControl2.Reserved = 0; - rClockControl2.PllBypass = pSettings->bPllBypass; - - /* Issue a soft reset to the chip */ - /* Note: Since we may be coming in with 3780i clocks suspended, we must keep - * soft-reset active for 10ms. - */ - rSlaveControl.ClockControl = 0; - rSlaveControl.SoftReset = true; - rSlaveControl.ConfigMode = false; - rSlaveControl.Reserved = 0; - - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); - MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); - - for (i = 0; i < 11; i++) - udelay(2000); - - rSlaveControl.SoftReset = false; - OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); - - MKWORD(tval) = InWordDsp(DSP_IsaSlaveControl); - - /* Program our general configuration registers */ - WriteGenCfg(DSP_HBridgeCfg1Index, MKBYTE(rHBridgeCfg1)); - WriteGenCfg(DSP_HBridgeCfg2Index, MKBYTE(rHBridgeCfg2)); - WriteGenCfg(DSP_BusMasterCfg1Index, MKBYTE(rBusmasterCfg1)); - WriteGenCfg(DSP_BusMasterCfg2Index, MKBYTE(rBusmasterCfg2)); - WriteGenCfg(DSP_IsaProtCfgIndex, MKBYTE(rIsaProtCfg)); - WriteGenCfg(DSP_PowerMgCfgIndex, MKBYTE(rPowerMgmtCfg)); - WriteGenCfg(DSP_HBusTimerCfgIndex, MKBYTE(rHBusTimerCfg)); - - if (pSettings->bModemEnabled) { - WriteGenCfg(DSP_UartCfg1Index, MKBYTE(rUartCfg1)); - WriteGenCfg(DSP_UartCfg2Index, MKBYTE(rUartCfg2)); - } - - - rHBridgeControl.EnableDspInt = false; - rHBridgeControl.MemAutoInc = true; - rHBridgeControl.IoAutoInc = false; - rHBridgeControl.DiagnosticMode = false; - - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); - spin_unlock_irqrestore(&dsp_lock, flags); - WriteMsaCfg(DSP_LBusTimeoutDisable, MKWORD(rLBusTimeoutDisable)); - WriteMsaCfg(DSP_ClockControl_1, MKWORD(rClockControl1)); - WriteMsaCfg(DSP_ClockControl_2, MKWORD(rClockControl2)); - WriteMsaCfg(DSP_ChipReset, MKWORD(rChipReset)); - - ReadMsaCfg(DSP_ChipID); - - return 0; -} - -int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings) -{ - unsigned long flags; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - DSP_ISA_SLAVE_CONTROL rSlaveControl; - - rSlaveControl.ClockControl = 0; - rSlaveControl.SoftReset = true; - rSlaveControl.ConfigMode = false; - rSlaveControl.Reserved = 0; - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); - - udelay(5); - - rSlaveControl.ClockControl = 1; - OutWordDsp(DSP_IsaSlaveControl, MKWORD(rSlaveControl)); - spin_unlock_irqrestore(&dsp_lock, flags); - - udelay(5); - - return 0; -} - -int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings) -{ - unsigned long flags; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - DSP_BOOT_DOMAIN rBootDomain; - DSP_HBRIDGE_CONTROL rHBridgeControl; - - spin_lock_irqsave(&dsp_lock, flags); - /* Mask DSP to PC interrupt */ - MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); - - rHBridgeControl.EnableDspInt = false; - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Reset the core via the boot domain register */ - rBootDomain.ResetCore = true; - rBootDomain.Halt = true; - rBootDomain.NMI = true; - rBootDomain.Reserved = 0; - - WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); - - /* Reset all the chiplets and then reactivate them */ - WriteMsaCfg(DSP_ChipReset, 0xFFFF); - udelay(5); - WriteMsaCfg(DSP_ChipReset, - (unsigned short) (~pSettings->usChipletEnable)); - - return 0; -} - - -int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings) -{ - unsigned long flags; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - DSP_BOOT_DOMAIN rBootDomain; - DSP_HBRIDGE_CONTROL rHBridgeControl; - - /* Transition the core to a running state */ - rBootDomain.ResetCore = true; - rBootDomain.Halt = false; - rBootDomain.NMI = true; - rBootDomain.Reserved = 0; - WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); - - udelay(5); - - rBootDomain.ResetCore = false; - WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); - udelay(5); - - rBootDomain.NMI = false; - WriteMsaCfg(DSP_MspBootDomain, MKWORD(rBootDomain)); - udelay(5); - - /* Enable DSP to PC interrupt */ - spin_lock_irqsave(&dsp_lock, flags); - MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); - rHBridgeControl.EnableDspInt = true; - - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); - spin_unlock_irqrestore(&dsp_lock, flags); - - return 0; -} - - -int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr) -{ - unsigned long flags; - unsigned short __user *pusBuffer = pvBuffer; - unsigned short val; - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Transfer the memory block */ - while (uCount-- != 0) { - spin_lock_irqsave(&dsp_lock, flags); - val = InWordDsp(DSP_MsaDataDSISHigh); - spin_unlock_irqrestore(&dsp_lock, flags); - if(put_user(val, pusBuffer++)) - return -EFAULT; - - PaceMsaAccess(usDspBaseIO); - } - - return 0; -} - -int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, - void __user *pvBuffer, unsigned uCount, - unsigned long ulDSPAddr) -{ - unsigned long flags; - unsigned short __user *pusBuffer = pvBuffer; - unsigned short val; - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Transfer the memory block */ - while (uCount-- != 0) { - spin_lock_irqsave(&dsp_lock, flags); - val = InWordDsp(DSP_ReadAndClear); - spin_unlock_irqrestore(&dsp_lock, flags); - if(put_user(val, pusBuffer++)) - return -EFAULT; - - PaceMsaAccess(usDspBaseIO); - } - - return 0; -} - - -int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr) -{ - unsigned long flags; - unsigned short __user *pusBuffer = pvBuffer; - - /* Set the initial MSA address. No adjustments need to be made to data store addresses */ - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Transfer the memory block */ - while (uCount-- != 0) { - unsigned short val; - if(get_user(val, pusBuffer++)) - return -EFAULT; - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaDataDSISHigh, val); - spin_unlock_irqrestore(&dsp_lock, flags); - - PaceMsaAccess(usDspBaseIO); - } - - return 0; -} - - -int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr) -{ - unsigned long flags; - unsigned short __user *pusBuffer = pvBuffer; - - /* - * Set the initial MSA address. To convert from an instruction store - * address to an MSA address - * shift the address two bits to the left and set bit 22 - */ - ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Transfer the memory block */ - while (uCount-- != 0) { - unsigned short val_lo, val_hi; - spin_lock_irqsave(&dsp_lock, flags); - val_lo = InWordDsp(DSP_MsaDataISLow); - val_hi = InWordDsp(DSP_MsaDataDSISHigh); - spin_unlock_irqrestore(&dsp_lock, flags); - if(put_user(val_lo, pusBuffer++)) - return -EFAULT; - if(put_user(val_hi, pusBuffer++)) - return -EFAULT; - - PaceMsaAccess(usDspBaseIO); - - } - - return 0; -} - - -int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr) -{ - unsigned long flags; - unsigned short __user *pusBuffer = pvBuffer; - - /* - * Set the initial MSA address. To convert from an instruction store - * address to an MSA address - * shift the address two bits to the left and set bit 22 - */ - ulDSPAddr = (ulDSPAddr << 2) | (1 << 22); - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaAddrLow, (unsigned short) ulDSPAddr); - OutWordDsp(DSP_MsaAddrHigh, (unsigned short) (ulDSPAddr >> 16)); - spin_unlock_irqrestore(&dsp_lock, flags); - - /* Transfer the memory block */ - while (uCount-- != 0) { - unsigned short val_lo, val_hi; - if(get_user(val_lo, pusBuffer++)) - return -EFAULT; - if(get_user(val_hi, pusBuffer++)) - return -EFAULT; - spin_lock_irqsave(&dsp_lock, flags); - OutWordDsp(DSP_MsaDataISLow, val_lo); - OutWordDsp(DSP_MsaDataDSISHigh, val_hi); - spin_unlock_irqrestore(&dsp_lock, flags); - - PaceMsaAccess(usDspBaseIO); - } - - return 0; -} - - -int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, - unsigned short *pusIPCSource) -{ - unsigned long flags; - DSP_HBRIDGE_CONTROL rHBridgeControl; - - /* - * Disable DSP to PC interrupts, read the interrupt register, - * clear the pending IPC bits, and reenable DSP to PC interrupts - */ - spin_lock_irqsave(&dsp_lock, flags); - MKWORD(rHBridgeControl) = InWordDsp(DSP_HBridgeControl); - rHBridgeControl.EnableDspInt = false; - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); - - *pusIPCSource = InWordDsp(DSP_Interrupt); - OutWordDsp(DSP_Interrupt, (unsigned short) ~(*pusIPCSource)); - - rHBridgeControl.EnableDspInt = true; - OutWordDsp(DSP_HBridgeControl, MKWORD(rHBridgeControl)); - spin_unlock_irqrestore(&dsp_lock, flags); - - return 0; -} diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h deleted file mode 100644 index 53dafceb20e0..000000000000 --- a/drivers/char/mwave/3780i.h +++ /dev/null @@ -1,358 +0,0 @@ -/* -* -* 3780i.h -- declarations for 3780i.c -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#ifndef _LINUX_3780I_H -#define _LINUX_3780I_H - -#include - -/* DSP I/O port offsets and definitions */ -#define DSP_IsaSlaveControl 0x0000 /* ISA slave control register */ -#define DSP_IsaSlaveStatus 0x0001 /* ISA slave status register */ -#define DSP_ConfigAddress 0x0002 /* General config address register */ -#define DSP_ConfigData 0x0003 /* General config data register */ -#define DSP_HBridgeControl 0x0002 /* HBridge control register */ -#define DSP_MsaAddrLow 0x0004 /* MSP System Address, low word */ -#define DSP_MsaAddrHigh 0x0006 /* MSP System Address, high word */ -#define DSP_MsaDataDSISHigh 0x0008 /* MSA data register: d-store word or high byte of i-store */ -#define DSP_MsaDataISLow 0x000A /* MSA data register: low word of i-store */ -#define DSP_ReadAndClear 0x000C /* MSA read and clear data register */ -#define DSP_Interrupt 0x000E /* Interrupt register (IPC source) */ - -typedef struct { - unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ - unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ - unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ - unsigned short Reserved:13; /* 0: Reserved */ -} DSP_ISA_SLAVE_CONTROL; - - -typedef struct { - unsigned short EnableDspInt:1; /* RW: Enable DSP to X86 ISA interrupt 0=mask it, 1=enable it */ - unsigned short MemAutoInc:1; /* RW: Memory address auto increment, 0=disable, 1=enable */ - unsigned short IoAutoInc:1; /* RW: I/O address auto increment, 0=disable, 1=enable */ - unsigned short DiagnosticMode:1; /* RW: Disgnostic mode 0=nromal, 1=diagnostic mode */ - unsigned short IsaPacingTimer:12; /* R: ISA access pacing timer: count of core cycles stolen */ -} DSP_HBRIDGE_CONTROL; - - -/* DSP register indexes used with the configuration register address (index) register */ -#define DSP_UartCfg1Index 0x0003 /* UART config register 1 */ -#define DSP_UartCfg2Index 0x0004 /* UART config register 2 */ -#define DSP_HBridgeCfg1Index 0x0007 /* HBridge config register 1 */ -#define DSP_HBridgeCfg2Index 0x0008 /* HBridge config register 2 */ -#define DSP_BusMasterCfg1Index 0x0009 /* ISA bus master config register 1 */ -#define DSP_BusMasterCfg2Index 0x000A /* ISA bus master config register 2 */ -#define DSP_IsaProtCfgIndex 0x000F /* ISA protocol control register */ -#define DSP_PowerMgCfgIndex 0x0010 /* Low poser suspend/resume enable */ -#define DSP_HBusTimerCfgIndex 0x0011 /* HBUS timer load value */ - -typedef struct { - unsigned char IrqActiveLow:1; /* RW: IRQ active high or low: 0=high, 1=low */ - unsigned char IrqPulse:1; /* RW: IRQ pulse or level: 0=level, 1=pulse */ - unsigned char Irq:3; /* RW: IRQ selection */ - unsigned char BaseIO:2; /* RW: Base I/O selection */ - unsigned char Reserved:1; /* 0: Reserved */ -} DSP_UART_CFG_1; - -typedef struct { - unsigned char Enable:1; /* RW: Enable I/O and IRQ: 0=false, 1=true */ - unsigned char Reserved:7; /* 0: Reserved */ -} DSP_UART_CFG_2; - -typedef struct { - unsigned char IrqActiveLow:1; /* RW: IRQ active high=0 or low=1 */ - unsigned char IrqPulse:1; /* RW: IRQ pulse=1 or level=0 */ - unsigned char Irq:3; /* RW: IRQ selection */ - unsigned char AccessMode:1; /* RW: 16-bit register access method 0=byte, 1=word */ - unsigned char Reserved:2; /* 0: Reserved */ -} DSP_HBRIDGE_CFG_1; - -typedef struct { - unsigned char Enable:1; /* RW: enable I/O and IRQ: 0=false, 1=true */ - unsigned char Reserved:7; /* 0: Reserved */ -} DSP_HBRIDGE_CFG_2; - - -typedef struct { - unsigned char Dma:3; /* RW: DMA channel selection */ - unsigned char NumTransfers:2; /* RW: Maximum # of transfers once being granted the ISA bus */ - unsigned char ReRequest:2; /* RW: Minimum delay between releasing the ISA bus and requesting it again */ - unsigned char MEMCS16:1; /* RW: ISA signal MEMCS16: 0=disabled, 1=enabled */ -} DSP_BUSMASTER_CFG_1; - -typedef struct { - unsigned char IsaMemCmdWidth:2; /* RW: ISA memory command width */ - unsigned char Reserved:6; /* 0: Reserved */ -} DSP_BUSMASTER_CFG_2; - - -typedef struct { - unsigned char GateIOCHRDY:1; /* RW: Enable IOCHRDY gating: 0=false, 1=true */ - unsigned char Reserved:7; /* 0: Reserved */ -} DSP_ISA_PROT_CFG; - -typedef struct { - unsigned char Enable:1; /* RW: Enable low power suspend/resume 0=false, 1=true */ - unsigned char Reserved:7; /* 0: Reserved */ -} DSP_POWER_MGMT_CFG; - -typedef struct { - unsigned char LoadValue:8; /* RW: HBUS timer load value */ -} DSP_HBUS_TIMER_CFG; - - - -/* DSP registers that exist in MSA I/O space */ -#define DSP_ChipID 0x80000000 -#define DSP_MspBootDomain 0x80000580 -#define DSP_LBusTimeoutDisable 0x80000580 -#define DSP_ClockControl_1 0x8000058A -#define DSP_ClockControl_2 0x8000058C -#define DSP_ChipReset 0x80000588 -#define DSP_GpioModeControl_15_8 0x80000082 -#define DSP_GpioDriverEnable_15_8 0x80000076 -#define DSP_GpioOutputData_15_8 0x80000072 - -typedef struct { - unsigned short NMI:1; /* RW: non maskable interrupt */ - unsigned short Halt:1; /* RW: Halt MSP clock */ - unsigned short ResetCore:1; /* RW: Reset MSP core interface */ - unsigned short Reserved:13; /* 0: Reserved */ -} DSP_BOOT_DOMAIN; - -typedef struct { - unsigned short DisableTimeout:1; /* RW: Disable LBus timeout */ - unsigned short Reserved:15; /* 0: Reserved */ -} DSP_LBUS_TIMEOUT_DISABLE; - -typedef struct { - unsigned short Memory:1; /* RW: Reset memory interface */ - unsigned short SerialPort1:1; /* RW: Reset serial port 1 interface */ - unsigned short SerialPort2:1; /* RW: Reset serial port 2 interface */ - unsigned short SerialPort3:1; /* RW: Reset serial port 3 interface */ - unsigned short Gpio:1; /* RW: Reset GPIO interface */ - unsigned short Dma:1; /* RW: Reset DMA interface */ - unsigned short SoundBlaster:1; /* RW: Reset soundblaster interface */ - unsigned short Uart:1; /* RW: Reset UART interface */ - unsigned short Midi:1; /* RW: Reset MIDI interface */ - unsigned short IsaMaster:1; /* RW: Reset ISA master interface */ - unsigned short Reserved:6; /* 0: Reserved */ -} DSP_CHIP_RESET; - -typedef struct { - unsigned short N_Divisor:6; /* RW: (N) PLL output clock divisor */ - unsigned short Reserved1:2; /* 0: reserved */ - unsigned short M_Multiplier:6; /* RW: (M) PLL feedback clock multiplier */ - unsigned short Reserved2:2; /* 0: reserved */ -} DSP_CLOCK_CONTROL_1; - -typedef struct { - unsigned short PllBypass:1; /* RW: PLL Bypass */ - unsigned short Reserved:15; /* 0: Reserved */ -} DSP_CLOCK_CONTROL_2; - -typedef struct { - unsigned short Latch8:1; - unsigned short Latch9:1; - unsigned short Latch10:1; - unsigned short Latch11:1; - unsigned short Latch12:1; - unsigned short Latch13:1; - unsigned short Latch14:1; - unsigned short Latch15:1; - unsigned short Mask8:1; - unsigned short Mask9:1; - unsigned short Mask10:1; - unsigned short Mask11:1; - unsigned short Mask12:1; - unsigned short Mask13:1; - unsigned short Mask14:1; - unsigned short Mask15:1; -} DSP_GPIO_OUTPUT_DATA_15_8; - -typedef struct { - unsigned short Enable8:1; - unsigned short Enable9:1; - unsigned short Enable10:1; - unsigned short Enable11:1; - unsigned short Enable12:1; - unsigned short Enable13:1; - unsigned short Enable14:1; - unsigned short Enable15:1; - unsigned short Mask8:1; - unsigned short Mask9:1; - unsigned short Mask10:1; - unsigned short Mask11:1; - unsigned short Mask12:1; - unsigned short Mask13:1; - unsigned short Mask14:1; - unsigned short Mask15:1; -} DSP_GPIO_DRIVER_ENABLE_15_8; - -typedef struct { - unsigned short GpioMode8:2; - unsigned short GpioMode9:2; - unsigned short GpioMode10:2; - unsigned short GpioMode11:2; - unsigned short GpioMode12:2; - unsigned short GpioMode13:2; - unsigned short GpioMode14:2; - unsigned short GpioMode15:2; -} DSP_GPIO_MODE_15_8; - -/* Component masks that are defined in dspmgr.h */ -#define MW_ADC_MASK 0x0001 -#define MW_AIC2_MASK 0x0006 -#define MW_MIDI_MASK 0x0008 -#define MW_CDDAC_MASK 0x8001 -#define MW_AIC1_MASK 0xE006 -#define MW_UART_MASK 0xE00A -#define MW_ACI_MASK 0xE00B - -/* -* Definition of 3780i configuration structure. Unless otherwise stated, -* these values are provided as input to the 3780i support layer. At present, -* the only values maintained by the 3780i support layer are the saved UART -* registers. -*/ -struct dsp_3780i_config_settings { - - /* Location of base configuration register */ - unsigned short usBaseConfigIO; - - /* Enables for various DSP components */ - int bDSPEnabled; - int bModemEnabled; - int bInterruptClaimed; - - /* IRQ, DMA, and Base I/O addresses for various DSP components */ - unsigned short usDspIrq; - unsigned short usDspDma; - unsigned short usDspBaseIO; - unsigned short usUartIrq; - unsigned short usUartBaseIO; - - /* IRQ modes for various DSP components */ - int bDspIrqActiveLow; - int bUartIrqActiveLow; - int bDspIrqPulse; - int bUartIrqPulse; - - /* Card abilities */ - unsigned uIps; - unsigned uDStoreSize; - unsigned uIStoreSize; - unsigned uDmaBandwidth; - - /* Adapter specific 3780i settings */ - unsigned short usNumTransfers; - unsigned short usReRequest; - int bEnableMEMCS16; - unsigned short usIsaMemCmdWidth; - int bGateIOCHRDY; - int bEnablePwrMgmt; - unsigned short usHBusTimerLoadValue; - int bDisableLBusTimeout; - unsigned short usN_Divisor; - unsigned short usM_Multiplier; - int bPllBypass; - unsigned short usChipletEnable; /* Used with the chip reset register to enable specific chiplets */ - - /* Saved UART registers. These are maintained by the 3780i support layer. */ - int bUartSaved; /* True after a successful save of the UART registers */ - unsigned char ucIER; /* Interrupt enable register */ - unsigned char ucFCR; /* FIFO control register */ - unsigned char ucLCR; /* Line control register */ - unsigned char ucMCR; /* Modem control register */ - unsigned char ucSCR; /* Scratch register */ - unsigned char ucDLL; /* Divisor latch, low byte */ - unsigned char ucDLM; /* Divisor latch, high byte */ -}; - - -/* 3780i support functions */ -int dsp3780I_EnableDSP(struct dsp_3780i_config_settings *pSettings, - unsigned short *pIrqMap, - unsigned short *pDmaMap); -int dsp3780I_DisableDSP(struct dsp_3780i_config_settings *pSettings); -int dsp3780I_Reset(struct dsp_3780i_config_settings *pSettings); -int dsp3780I_Run(struct dsp_3780i_config_settings *pSettings); -int dsp3780I_ReadDStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_ReadAndClearDStore(unsigned short usDspBaseIO, - void __user *pvBuffer, unsigned uCount, - unsigned long ulDSPAddr); -int dsp3780I_WriteDStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_ReadIStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr); -int dsp3780I_WriteIStore(unsigned short usDspBaseIO, void __user *pvBuffer, - unsigned uCount, unsigned long ulDSPAddr); -unsigned short dsp3780I_ReadMsaCfg(unsigned short usDspBaseIO, - unsigned long ulMsaAddr); -void dsp3780I_WriteMsaCfg(unsigned short usDspBaseIO, - unsigned long ulMsaAddr, unsigned short usValue); -int dsp3780I_GetIPCSource(unsigned short usDspBaseIO, - unsigned short *pusIPCSource); - -/* I/O port access macros */ -#define MKWORD(var) (*((unsigned short *)(&var))) -#define MKBYTE(var) (*((unsigned char *)(&var))) - -#define WriteMsaCfg(addr,value) dsp3780I_WriteMsaCfg(usDspBaseIO,addr,value) -#define ReadMsaCfg(addr) dsp3780I_ReadMsaCfg(usDspBaseIO,addr) -#define WriteGenCfg(index,value) dsp3780I_WriteGenCfg(usDspBaseIO,index,value) -#define ReadGenCfg(index) dsp3780I_ReadGenCfg(usDspBaseIO,index) - -#define InWordDsp(index) inw(usDspBaseIO+index) -#define InByteDsp(index) inb(usDspBaseIO+index) -#define OutWordDsp(index,value) outw(value,usDspBaseIO+index) -#define OutByteDsp(index,value) outb(value,usDspBaseIO+index) - -#endif diff --git a/drivers/char/mwave/Makefile b/drivers/char/mwave/Makefile deleted file mode 100644 index e56c1a375535..000000000000 --- a/drivers/char/mwave/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for ACP Modem (Mwave). -# -# See the README file in this directory for more info. -# - -obj-$(CONFIG_MWAVE) += mwave.o - -mwave-y := mwavedd.o smapi.o tp3780i.o 3780i.o diff --git a/drivers/char/mwave/README b/drivers/char/mwave/README deleted file mode 100644 index 6224aa814c62..000000000000 --- a/drivers/char/mwave/README +++ /dev/null @@ -1,37 +0,0 @@ -Module options --------------- - -The mwave module takes the following options. Note that these options -are not saved by the BIOS and so do not persist after unload and reload. - - mwave_3780i_irq=5/7/10/11/15 - If the dsp irq has not been setup and stored in bios by the - thinkpad configuration utility then this parameter allows the - irq used by the dsp to be configured. - - mwave_3780i_io=0x130/0x350/0x0070/0xDB0 - If the dsp io range has not been setup and stored in bios by the - thinkpad configuration utility then this parameter allows the - io range used by the dsp to be configured. - - mwave_uart_irq=3/4 - If the mwave's uart irq has not been setup and stored in bios by the - thinkpad configuration utility then this parameter allows the - irq used by the mwave uart to be configured. - - mwave_uart_io=0x3f8/0x2f8/0x3E8/0x2E8 - If the uart io range has not been setup and stored in bios by the - thinkpad configuration utility then this parameter allows the - io range used by the mwave uart to be configured. - -Example to enable the 3780i DSP using ttyS1 resources: - - insmod mwave mwave_3780i_irq=10 mwave_3780i_io=0x0130 mwave_uart_irq=3 mwave_uart_io=0x2f8 - -Accessing the driver --------------------- - -You must also create a node for the driver: - mkdir -p /dev/modems - mknod --mode=660 /dev/modems/mwave c 10 219 - diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c deleted file mode 100644 index 640a9cb0dd8d..000000000000 --- a/drivers/char/mwave/mwavedd.c +++ /dev/null @@ -1,432 +0,0 @@ -/* -* -* mwavedd.c -- mwave device driver -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#define pr_fmt(fmt) "mwavedd: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "smapi.h" -#include "mwavedd.h" -#include "3780i.h" -#include "tp3780i.h" - -MODULE_DESCRIPTION("3780i Advanced Communications Processor (Mwave) driver"); -MODULE_AUTHOR("Mike Sullivan and Paul Schroeder"); -MODULE_LICENSE("GPL"); - -/* -* These parameters support the setting of MWave resources. Note that no -* checks are made against other devices (ie. superio) for conflicts. -* We'll depend on users using the tpctl utility to do that for now -*/ -static DEFINE_MUTEX(mwave_mutex); -int mwave_3780i_irq = 0; -int mwave_3780i_io = 0; -int mwave_uart_irq = 0; -int mwave_uart_io = 0; -module_param_hw(mwave_3780i_irq, int, irq, 0); -module_param_hw(mwave_3780i_io, int, ioport, 0); -module_param_hw(mwave_uart_irq, int, irq, 0); -module_param_hw(mwave_uart_io, int, ioport, 0); - -struct mwave_device_data mwave_s_mdd; - -static long mwave_ioctl(struct file *file, unsigned int iocmd, - unsigned long ioarg) -{ - unsigned int retval = 0; - struct mwave_device_data *pDrvData = &mwave_s_mdd; - void __user *arg = (void __user *)ioarg; - - switch (iocmd) { - - case IOCTL_MW_RESET: - mutex_lock(&mwave_mutex); - retval = tp3780I_ResetDSP(&pDrvData->rBDData); - mutex_unlock(&mwave_mutex); - break; - - case IOCTL_MW_RUN: - mutex_lock(&mwave_mutex); - retval = tp3780I_StartDSP(&pDrvData->rBDData); - mutex_unlock(&mwave_mutex); - break; - - case IOCTL_MW_DSP_ABILITIES: { - struct mw_abilities rAbilities; - - mutex_lock(&mwave_mutex); - retval = tp3780I_QueryAbilities(&pDrvData->rBDData, - &rAbilities); - mutex_unlock(&mwave_mutex); - if (retval == 0) { - if (copy_to_user(arg, &rAbilities, sizeof(rAbilities))) - return -EFAULT; - } - } - break; - - case IOCTL_MW_READ_DATA: - case IOCTL_MW_READCLEAR_DATA: { - struct mw_readwrite rReadData; - unsigned short __user *pusBuffer = NULL; - - if( copy_from_user(&rReadData, arg, - sizeof(struct mw_readwrite)) ) - return -EFAULT; - pusBuffer = (unsigned short __user *) (rReadData.pBuf); - - mutex_lock(&mwave_mutex); - retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, - iocmd, - pusBuffer, - rReadData.ulDataLength, - rReadData.usDspAddress); - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_READ_INST: { - struct mw_readwrite rReadData; - unsigned short __user *pusBuffer = NULL; - - if (copy_from_user(&rReadData, arg, sizeof(rReadData))) - return -EFAULT; - pusBuffer = (unsigned short __user *) (rReadData.pBuf); - - mutex_lock(&mwave_mutex); - retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, - iocmd, pusBuffer, - rReadData.ulDataLength / 2, - rReadData.usDspAddress); - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_WRITE_DATA: { - struct mw_readwrite rWriteData; - unsigned short __user *pusBuffer = NULL; - - if (copy_from_user(&rWriteData, arg, sizeof(rWriteData))) - return -EFAULT; - pusBuffer = (unsigned short __user *) (rWriteData.pBuf); - - mutex_lock(&mwave_mutex); - retval = tp3780I_ReadWriteDspDStore(&pDrvData->rBDData, - iocmd, pusBuffer, - rWriteData.ulDataLength, - rWriteData.usDspAddress); - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_WRITE_INST: { - struct mw_readwrite rWriteData; - unsigned short __user *pusBuffer = NULL; - - if (copy_from_user(&rWriteData, arg, sizeof(rWriteData))) - return -EFAULT; - pusBuffer = (unsigned short __user *)(rWriteData.pBuf); - - mutex_lock(&mwave_mutex); - retval = tp3780I_ReadWriteDspIStore(&pDrvData->rBDData, - iocmd, pusBuffer, - rWriteData.ulDataLength, - rWriteData.usDspAddress); - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_REGISTER_IPC: { - unsigned int ipcnum = (unsigned int) ioarg; - - if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - pr_err("%s: IOCTL_MW_REGISTER_IPC: Error: Invalid ipcnum %x\n", - __func__, ipcnum); - return -EINVAL; - } - ipcnum = array_index_nospec(ipcnum, - ARRAY_SIZE(pDrvData->IPCs)); - - mutex_lock(&mwave_mutex); - pDrvData->IPCs[ipcnum].bIsHere = false; - pDrvData->IPCs[ipcnum].bIsEnabled = true; - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_GET_IPC: { - unsigned int ipcnum = (unsigned int) ioarg; - - if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - pr_err("%s: IOCTL_MW_GET_IPC: Error: Invalid ipcnum %x\n", __func__, - ipcnum); - return -EINVAL; - } - ipcnum = array_index_nospec(ipcnum, - ARRAY_SIZE(pDrvData->IPCs)); - - mutex_lock(&mwave_mutex); - if (pDrvData->IPCs[ipcnum].bIsEnabled == true) { - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait); - pDrvData->IPCs[ipcnum].bIsHere = true; - set_current_state(TASK_INTERRUPTIBLE); - /* check whether an event was signalled by */ - /* the interrupt handler while we were gone */ - if (pDrvData->IPCs[ipcnum].usIntCount == 1) { /* first int has occurred (race condition) */ - pDrvData->IPCs[ipcnum].usIntCount = 2; /* first int has been handled */ - } else { /* either 1st int has not yet occurred, or we have already handled the first int */ - schedule(); - if (pDrvData->IPCs[ipcnum].usIntCount == 1) { - pDrvData->IPCs[ipcnum].usIntCount = 2; - } - } - pDrvData->IPCs[ipcnum].bIsHere = false; - remove_wait_queue(&pDrvData->IPCs[ipcnum].ipc_wait_queue, &wait); - set_current_state(TASK_RUNNING); - } - mutex_unlock(&mwave_mutex); - } - break; - - case IOCTL_MW_UNREGISTER_IPC: { - unsigned int ipcnum = (unsigned int) ioarg; - - if (ipcnum >= ARRAY_SIZE(pDrvData->IPCs)) { - pr_err("%s: IOCTL_MW_UNREGISTER_IPC: Error: Invalid ipcnum %x\n", - __func__, ipcnum); - return -EINVAL; - } - ipcnum = array_index_nospec(ipcnum, - ARRAY_SIZE(pDrvData->IPCs)); - mutex_lock(&mwave_mutex); - if (pDrvData->IPCs[ipcnum].bIsEnabled == true) { - pDrvData->IPCs[ipcnum].bIsEnabled = false; - if (pDrvData->IPCs[ipcnum].bIsHere == true) { - wake_up_interruptible(&pDrvData->IPCs[ipcnum].ipc_wait_queue); - } - } - mutex_unlock(&mwave_mutex); - } - break; - - default: - return -ENOTTY; - } /* switch */ - - return retval; -} - -static int register_serial_portandirq(unsigned int port, int irq) -{ - struct uart_8250_port uart; - - switch ( port ) { - case 0x3f8: - case 0x2f8: - case 0x3e8: - case 0x2e8: - /* OK */ - break; - default: - pr_err("%s: Error: Illegal port %x\n", __func__, port); - return -1; - } /* switch */ - /* port is okay */ - - switch ( irq ) { - case 3: - case 4: - case 5: - case 7: - /* OK */ - break; - default: - pr_err("%s: Error: Illegal irq %x\n", __func__, irq); - return -1; - } /* switch */ - /* irq is okay */ - - memset(&uart, 0, sizeof(uart)); - - uart.port.uartclk = 1843200; - uart.port.iobase = port; - uart.port.irq = irq; - uart.port.iotype = UPIO_PORT; - uart.port.flags = UPF_SHARE_IRQ; - return serial8250_register_8250_port(&uart); -} - -static const struct file_operations mwave_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = mwave_ioctl, - .llseek = default_llseek, -}; - -static struct miscdevice mwave_misc_dev = { MWAVE_MINOR, "mwave", &mwave_fops }; - -/* -* mwave_init is called on module load -* -* mwave_exit is called on module unload -* mwave_exit is also used to clean up after an aborted mwave_init -*/ -static void mwave_exit(void) -{ - struct mwave_device_data *pDrvData = &mwave_s_mdd; - - if ( pDrvData->sLine >= 0 ) { - serial8250_unregister_port(pDrvData->sLine); - } - if (pDrvData->bMwaveDevRegistered) { - misc_deregister(&mwave_misc_dev); - } - if (pDrvData->bDSPEnabled) { - tp3780I_DisableDSP(&pDrvData->rBDData); - } - if (pDrvData->bResourcesClaimed) { - tp3780I_ReleaseResources(&pDrvData->rBDData); - } - if (pDrvData->bBDInitialized) { - tp3780I_Cleanup(&pDrvData->rBDData); - } -} - -module_exit(mwave_exit); - -static int __init mwave_init(void) -{ - int i; - int retval = 0; - struct mwave_device_data *pDrvData = &mwave_s_mdd; - - memset(&mwave_s_mdd, 0, sizeof(mwave_s_mdd)); - - pDrvData->bBDInitialized = false; - pDrvData->bResourcesClaimed = false; - pDrvData->bDSPEnabled = false; - pDrvData->bDSPReset = false; - pDrvData->bMwaveDevRegistered = false; - pDrvData->sLine = -1; - - for (i = 0; i < ARRAY_SIZE(pDrvData->IPCs); i++) { - pDrvData->IPCs[i].bIsEnabled = false; - pDrvData->IPCs[i].bIsHere = false; - pDrvData->IPCs[i].usIntCount = 0; /* no ints received yet */ - init_waitqueue_head(&pDrvData->IPCs[i].ipc_wait_queue); - } - - retval = tp3780I_InitializeBoardData(&pDrvData->rBDData); - if (retval) { - pr_err("%s: Error: Failed to initialize board data\n", __func__); - goto cleanup_error; - } - pDrvData->bBDInitialized = true; - - retval = tp3780I_CalcResources(&pDrvData->rBDData); - if (retval) { - pr_err("%s: Error: Failed to calculate resources\n", __func__); - goto cleanup_error; - } - - retval = tp3780I_ClaimResources(&pDrvData->rBDData); - if (retval) { - pr_err("%s: Error: Failed to claim resources\n", __func__); - goto cleanup_error; - } - pDrvData->bResourcesClaimed = true; - - retval = tp3780I_EnableDSP(&pDrvData->rBDData); - if (retval) { - pr_err("%s: Error: Failed to enable DSP\n", __func__); - goto cleanup_error; - } - pDrvData->bDSPEnabled = true; - - if (misc_register(&mwave_misc_dev) < 0) { - pr_err("%s: Error: Failed to register misc device\n", __func__); - goto cleanup_error; - } - pDrvData->bMwaveDevRegistered = true; - - pDrvData->sLine = register_serial_portandirq( - pDrvData->rBDData.rDspSettings.usUartBaseIO, - pDrvData->rBDData.rDspSettings.usUartIrq - ); - if (pDrvData->sLine < 0) { - pr_err("%s: Error: Failed to register serial driver\n", __func__); - goto cleanup_error; - } - /* uart is registered */ - - /* SUCCESS! */ - return 0; - -cleanup_error: - pr_err("%s: Error: Failed to initialize\n", __func__); - mwave_exit(); /* clean up */ - - return -EIO; -} - -module_init(mwave_init); - diff --git a/drivers/char/mwave/mwavedd.h b/drivers/char/mwave/mwavedd.h deleted file mode 100644 index e1da1493eec5..000000000000 --- a/drivers/char/mwave/mwavedd.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -* -* mwavedd.h -- declarations for mwave device driver -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#ifndef _LINUX_MWAVEDD_H -#define _LINUX_MWAVEDD_H -#include "3780i.h" -#include "tp3780i.h" -#include "smapi.h" -#include "mwavepub.h" -#include -#include -#include - -extern int mwave_3780i_irq; -extern int mwave_3780i_io; -extern int mwave_uart_irq; -extern int mwave_uart_io; - -struct mwave_ipc { - unsigned short usIntCount; /* 0=none, 1=first, 2=greater than 1st */ - bool bIsEnabled; - bool bIsHere; - /* entry spin lock */ - wait_queue_head_t ipc_wait_queue; -}; - -struct mwave_device_data { - struct thinkpad_bd_data rBDData; /* board driver's data area */ - unsigned long ulIPCSource_ISR; /* IPC source bits for recently processed intr, set during ISR processing */ - unsigned long ulIPCSource_DPC; /* IPC source bits for recently processed intr, set during DPC processing */ - bool bBDInitialized; - bool bResourcesClaimed; - bool bDSPEnabled; - bool bDSPReset; - struct mwave_ipc IPCs[16]; - bool bMwaveDevRegistered; - short sLine; - int nr_registered_attrs; - int device_registered; - -}; - -extern struct mwave_device_data mwave_s_mdd; - -#endif diff --git a/drivers/char/mwave/mwavepub.h b/drivers/char/mwave/mwavepub.h deleted file mode 100644 index 280327bdaa38..000000000000 --- a/drivers/char/mwave/mwavepub.h +++ /dev/null @@ -1,89 +0,0 @@ -/* -* -* mwavepub.h -- PUBLIC declarations for the mwave driver -* and applications using it -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#ifndef _LINUX_MWAVEPUB_H -#define _LINUX_MWAVEPUB_H - -#include - - -struct mw_abilities { - unsigned long instr_per_sec; - unsigned long data_size; - unsigned long inst_size; - unsigned long bus_dma_bw; - unsigned short uart_enable; - short component_count; - unsigned long component_list[7]; - char mwave_os_name[16]; - char bios_task_name[16]; -}; - - -struct mw_readwrite { - unsigned short usDspAddress; /* The dsp address */ - unsigned long ulDataLength; /* The size in bytes of the data or user buffer */ - void __user *pBuf; /* Input:variable sized buffer */ -}; - -#define IOCTL_MW_RESET _IO(MWAVE_MINOR,1) -#define IOCTL_MW_RUN _IO(MWAVE_MINOR,2) -#define IOCTL_MW_DSP_ABILITIES _IOR(MWAVE_MINOR,3,struct mw_abilities) -#define IOCTL_MW_READ_DATA _IOR(MWAVE_MINOR,4,struct mw_readwrite) -#define IOCTL_MW_READCLEAR_DATA _IOR(MWAVE_MINOR,5,struct mw_readwrite) -#define IOCTL_MW_READ_INST _IOR(MWAVE_MINOR,6,struct mw_readwrite) -#define IOCTL_MW_WRITE_DATA _IOW(MWAVE_MINOR,7,struct mw_readwrite) -#define IOCTL_MW_WRITE_INST _IOW(MWAVE_MINOR,8,struct mw_readwrite) -#define IOCTL_MW_REGISTER_IPC _IOW(MWAVE_MINOR,9,int) -#define IOCTL_MW_UNREGISTER_IPC _IOW(MWAVE_MINOR,10,int) -#define IOCTL_MW_GET_IPC _IOW(MWAVE_MINOR,11,int) -#define IOCTL_MW_TRACE _IOR(MWAVE_MINOR,12,struct mw_readwrite) - - -#endif diff --git a/drivers/char/mwave/smapi.c b/drivers/char/mwave/smapi.c deleted file mode 100644 index df6354b24339..000000000000 --- a/drivers/char/mwave/smapi.c +++ /dev/null @@ -1,404 +0,0 @@ -/* -* -* smapi.c -- SMAPI interface routines -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#define pr_fmt(fmt) "smapi: " fmt - -#include -#include /* CMOS defines */ -#include "smapi.h" -#include "mwavedd.h" - -static unsigned short g_usSmapiPort = 0; - - -static int smapi_request(unsigned short inBX, unsigned short inCX, - unsigned short inDI, unsigned short inSI, - unsigned short *outAX, unsigned short *outBX, - unsigned short *outCX, unsigned short *outDX, - unsigned short *outDI, unsigned short *outSI) -{ - unsigned short myoutAX = 2, *pmyoutAX = &myoutAX; - unsigned short myoutBX = 3, *pmyoutBX = &myoutBX; - unsigned short myoutCX = 4, *pmyoutCX = &myoutCX; - unsigned short myoutDX = 5, *pmyoutDX = &myoutDX; - unsigned short myoutDI = 6, *pmyoutDI = &myoutDI; - unsigned short myoutSI = 7, *pmyoutSI = &myoutSI; - unsigned short usSmapiOK = -EIO, *pusSmapiOK = &usSmapiOK; - unsigned int inBXCX = (inBX << 16) | inCX; - unsigned int inDISI = (inDI << 16) | inSI; - - __asm__ __volatile__("movw $0x5380,%%ax\n\t" - "movl %7,%%ebx\n\t" - "shrl $16, %%ebx\n\t" - "movw %7,%%cx\n\t" - "movl %8,%%edi\n\t" - "shrl $16,%%edi\n\t" - "movw %8,%%si\n\t" - "movw %9,%%dx\n\t" - "out %%al,%%dx\n\t" - "out %%al,$0x4F\n\t" - "cmpb $0x53,%%ah\n\t" - "je 2f\n\t" - "1:\n\t" - "orb %%ah,%%ah\n\t" - "jnz 2f\n\t" - "movw %%ax,%0\n\t" - "movw %%bx,%1\n\t" - "movw %%cx,%2\n\t" - "movw %%dx,%3\n\t" - "movw %%di,%4\n\t" - "movw %%si,%5\n\t" - "movw $1,%6\n\t" - "2:\n\t":"=m"(*(unsigned short *) pmyoutAX), - "=m"(*(unsigned short *) pmyoutBX), - "=m"(*(unsigned short *) pmyoutCX), - "=m"(*(unsigned short *) pmyoutDX), - "=m"(*(unsigned short *) pmyoutDI), - "=m"(*(unsigned short *) pmyoutSI), - "=m"(*(unsigned short *) pusSmapiOK) - :"m"(inBXCX), "m"(inDISI), "m"(g_usSmapiPort) - :"%eax", "%ebx", "%ecx", "%edx", "%edi", - "%esi"); - - *outAX = myoutAX; - *outBX = myoutBX; - *outCX = myoutCX; - *outDX = myoutDX; - *outDI = myoutDI; - *outSI = myoutSI; - - return usSmapiOK == 1 ? 0 : -EIO; -} - - -int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings) -{ - int bRC; - unsigned short usAX, usBX, usCX, usDX, usDI, usSI; - static const unsigned short ausDspBases[] = { - 0x0030, 0x4E30, 0x8E30, 0xCE30, - 0x0130, 0x0350, 0x0070, 0x0DB0 }; - static const unsigned short ausUartBases[] = { - 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; - - bRC = smapi_request(0x1802, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) { - pr_err("%s: Error: Could not get DSP Settings. Aborting.\n", __func__); - return bRC; - } - - pSettings->bDSPPresent = ((usBX & 0x0100) != 0); - pSettings->bDSPEnabled = ((usCX & 0x0001) != 0); - pSettings->usDspIRQ = usSI & 0x00FF; - pSettings->usDspDMA = (usSI & 0xFF00) >> 8; - if ((usDI & 0x00FF) < ARRAY_SIZE(ausDspBases)) { - pSettings->usDspBaseIO = ausDspBases[usDI & 0x00FF]; - } else { - pSettings->usDspBaseIO = 0; - } - - /* check for illegal values */ - if ( pSettings->usDspBaseIO == 0 ) - pr_err("%s: Worry: DSP base I/O address is 0\n", __func__); - if ( pSettings->usDspIRQ == 0 ) - pr_err("%s: Worry: DSP IRQ line is 0\n", __func__); - - bRC = smapi_request(0x1804, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) { - pr_err("%s: Error: Could not get DSP modem settings. Aborting.\n", __func__); - return bRC; - } - - pSettings->bModemEnabled = ((usCX & 0x0001) != 0); - pSettings->usUartIRQ = usSI & 0x000F; - if (((usSI & 0xFF00) >> 8) < ARRAY_SIZE(ausUartBases)) { - pSettings->usUartBaseIO = ausUartBases[(usSI & 0xFF00) >> 8]; - } else { - pSettings->usUartBaseIO = 0; - } - - /* check for illegal values */ - if ( pSettings->usUartBaseIO == 0 ) - pr_err("%s: Worry: UART base I/O address is 0\n", __func__); - if ( pSettings->usUartIRQ == 0 ) - pr_err("%s: Worry: UART IRQ line is 0\n", __func__); - - return bRC; -} - - -int smapi_set_DSP_cfg(void) -{ - int bRC = -EIO; - int i; - unsigned short usAX, usBX, usCX, usDX, usDI, usSI; - static const unsigned short ausDspBases[] = { - 0x0030, 0x4E30, 0x8E30, 0xCE30, - 0x0130, 0x0350, 0x0070, 0x0DB0 }; - static const unsigned short ausUartBases[] = { - 0x03F8, 0x02F8, 0x03E8, 0x02E8 }; - static const unsigned short ausDspIrqs[] = { - 5, 7, 10, 11, 15 }; - static const unsigned short ausUartIrqs[] = { - 3, 4 }; - - unsigned short dspio_index = 0, uartio_index = 0; - - if (mwave_3780i_io) { - for (i = 0; i < ARRAY_SIZE(ausDspBases); i++) { - if (mwave_3780i_io == ausDspBases[i]) - break; - } - if (i == ARRAY_SIZE(ausDspBases)) { - pr_err("%s: Error: Invalid mwave_3780i_io address %x. Aborting.\n", - __func__, mwave_3780i_io); - return bRC; - } - dspio_index = i; - } - - if (mwave_3780i_irq) { - for (i = 0; i < ARRAY_SIZE(ausDspIrqs); i++) { - if (mwave_3780i_irq == ausDspIrqs[i]) - break; - } - if (i == ARRAY_SIZE(ausDspIrqs)) { - pr_err("%s: Error: Invalid mwave_3780i_irq %x. Aborting.\n", __func__, - mwave_3780i_irq); - return bRC; - } - } - - if (mwave_uart_io) { - for (i = 0; i < ARRAY_SIZE(ausUartBases); i++) { - if (mwave_uart_io == ausUartBases[i]) - break; - } - if (i == ARRAY_SIZE(ausUartBases)) { - pr_err("%s: Error: Invalid mwave_uart_io address %x. Aborting.\n", __func__, - mwave_uart_io); - return bRC; - } - uartio_index = i; - } - - - if (mwave_uart_irq) { - for (i = 0; i < ARRAY_SIZE(ausUartIrqs); i++) { - if (mwave_uart_irq == ausUartIrqs[i]) - break; - } - if (i == ARRAY_SIZE(ausUartIrqs)) { - pr_err("%s: Error: Invalid mwave_uart_irq %x. Aborting.\n", __func__, - mwave_uart_irq); - return bRC; - } - } - - if (mwave_uart_irq || mwave_uart_io) { - - /* Check serial port A */ - bRC = smapi_request(0x1402, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - /* bRC == 0 */ - if (usBX & 0x0100) { /* serial port A is present */ - if (usCX & 1) { /* serial port is enabled */ - if ((usSI & 0xFF) == mwave_uart_irq) { - pr_err("%s: Serial port A irq %x conflicts with mwave_uart_irq %x\n", - __func__, usSI & 0xFF, mwave_uart_irq); - goto exit_conflict; - } else { - if ((usSI >> 8) == uartio_index) { - pr_err("%s: Serial port A base I/O address %x conflicts with mwave uart I/O %x\n", - __func__, ausUartBases[usSI >> 8], - ausUartBases[uartio_index]); - goto exit_conflict; - } - } - } - } - - /* Check serial port B */ - bRC = smapi_request(0x1404, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - /* bRC == 0 */ - if (usBX & 0x0100) { /* serial port B is present */ - if (usCX & 1) { /* serial port is enabled */ - if ((usSI & 0xFF) == mwave_uart_irq) { - pr_err("%s: Serial port B irq %x conflicts with mwave_uart_irq %x\n", - __func__, usSI & 0xFF, mwave_uart_irq); - goto exit_conflict; - } else { - if ((usSI >> 8) == uartio_index) { - pr_err("%s: Serial port B base I/O address %x conflicts with mwave uart I/O %x\n", - __func__, ausUartBases[usSI >> 8], - ausUartBases[uartio_index]); - goto exit_conflict; - } - } - } - } - - /* Check IR port */ - bRC = smapi_request(0x1700, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - bRC = smapi_request(0x1704, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - /* bRC == 0 */ - if ((usCX & 0xff) != 0xff) { /* IR port not disabled */ - if ((usCX & 0xff) == mwave_uart_irq) { - pr_err("%s: IR port irq %x conflicts with mwave_uart_irq %x\n", - __func__, usCX & 0xff, mwave_uart_irq); - goto exit_conflict; - } else { - if ((usSI & 0xff) == uartio_index) { - pr_err("%s: IR port base I/O address %x conflicts with mwave uart I/O %x\n", - __func__, ausUartBases[usSI & 0xff], - ausUartBases[uartio_index]); - goto exit_conflict; - } - } - } - } - - bRC = smapi_request(0x1802, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - - if (mwave_3780i_io) { - usDI = dspio_index; - } - if (mwave_3780i_irq) { - usSI = (usSI & 0xff00) | mwave_3780i_irq; - } - - bRC = smapi_request(0x1803, 0x0101, usDI, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - - bRC = smapi_request(0x1804, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - - if (mwave_uart_io) { - usSI = (usSI & 0x00ff) | (uartio_index << 8); - } - if (mwave_uart_irq) { - usSI = (usSI & 0xff00) | mwave_uart_irq; - } - bRC = smapi_request(0x1805, 0x0101, 0, usSI, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - - bRC = smapi_request(0x1802, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - - bRC = smapi_request(0x1804, 0x0000, 0, 0, - &usAX, &usBX, &usCX, &usDX, &usDI, &usSI); - if (bRC) goto exit_smapi_request_error; - -/* normal exit: */ - return 0; - -exit_conflict: - /* Message has already been printed */ - return -EIO; - -exit_smapi_request_error: - pr_err("%s: exit on smapi_request error bRC %x\n", __func__, bRC); - return bRC; -} - - -int smapi_set_DSP_power_state(bool bOn) -{ - unsigned short usAX, usBX, usCX, usDX, usDI, usSI; - unsigned short usPowerFunction; - - usPowerFunction = (bOn) ? 1 : 0; - - return smapi_request(0x4901, 0x0000, 0, usPowerFunction, &usAX, &usBX, &usCX, &usDX, &usDI, - &usSI); -} - -int smapi_init(void) -{ - int retval = -EIO; - unsigned short usSmapiID = 0; - unsigned long flags; - - spin_lock_irqsave(&rtc_lock, flags); - usSmapiID = CMOS_READ(0x7C); - usSmapiID |= (CMOS_READ(0x7D) << 8); - spin_unlock_irqrestore(&rtc_lock, flags); - - if (usSmapiID == 0x5349) { - spin_lock_irqsave(&rtc_lock, flags); - g_usSmapiPort = CMOS_READ(0x7E); - g_usSmapiPort |= (CMOS_READ(0x7F) << 8); - spin_unlock_irqrestore(&rtc_lock, flags); - if (g_usSmapiPort == 0) { - pr_err("%s: ERROR unable to read from SMAPI port\n", __func__); - } else { - retval = 0; - //SmapiQuerySystemID(); - } - } else { - pr_err("%s: ERROR invalid usSmapiID\n", __func__); - retval = -ENXIO; - } - - return retval; -} diff --git a/drivers/char/mwave/smapi.h b/drivers/char/mwave/smapi.h deleted file mode 100644 index e605b16ed23c..000000000000 --- a/drivers/char/mwave/smapi.h +++ /dev/null @@ -1,76 +0,0 @@ -/* -* -* smapi.h -- declarations for SMAPI interface routines -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#ifndef _LINUX_SMAPI_H -#define _LINUX_SMAPI_H - -struct smapi_dsp_settings { - int bDSPPresent; - int bDSPEnabled; - int bModemEnabled; - int bMIDIEnabled; - int bSblstEnabled; - unsigned short usDspIRQ; - unsigned short usDspDMA; - unsigned short usDspBaseIO; - unsigned short usUartIRQ; - unsigned short usUartBaseIO; - unsigned short usMidiIRQ; - unsigned short usMidiBaseIO; - unsigned short usSndblstIRQ; - unsigned short usSndblstDMA; - unsigned short usSndblstBaseIO; -}; - -int smapi_init(void); -int smapi_query_DSP_cfg(struct smapi_dsp_settings *pSettings); -int smapi_set_DSP_cfg(void); -int smapi_set_DSP_power_state(bool bOn); - - -#endif diff --git a/drivers/char/mwave/tp3780i.c b/drivers/char/mwave/tp3780i.c deleted file mode 100644 index 7363b0f764e0..000000000000 --- a/drivers/char/mwave/tp3780i.c +++ /dev/null @@ -1,477 +0,0 @@ -/* -* -* tp3780i.c -- board driver for 3780i on ThinkPads -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#define pr_fmt(fmt) "tp3780i: " fmt - -#include -#include -#include -#include -#include -#include "smapi.h" -#include "mwavedd.h" -#include "tp3780i.h" -#include "3780i.h" -#include "mwavepub.h" - -static unsigned short s_ausThinkpadIrqToField[16] = - { 0xFFFF, 0xFFFF, 0xFFFF, 0x0001, 0x0002, 0x0003, 0xFFFF, 0x0004, - 0xFFFF, 0xFFFF, 0x0005, 0x0006, 0xFFFF, 0xFFFF, 0xFFFF, 0x0007 }; -static unsigned short s_ausThinkpadDmaToField[8] = - { 0x0001, 0x0002, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0x0003, 0x0004 }; -static unsigned short s_numIrqs = 16, s_numDmas = 8; - - -static void EnableSRAM(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - DSP_GPIO_OUTPUT_DATA_15_8 rGpioOutputData; - DSP_GPIO_DRIVER_ENABLE_15_8 rGpioDriverEnable; - DSP_GPIO_MODE_15_8 rGpioMode; - - MKWORD(rGpioMode) = ReadMsaCfg(DSP_GpioModeControl_15_8); - rGpioMode.GpioMode10 = 0; - WriteMsaCfg(DSP_GpioModeControl_15_8, MKWORD(rGpioMode)); - - MKWORD(rGpioDriverEnable) = 0; - rGpioDriverEnable.Enable10 = true; - rGpioDriverEnable.Mask10 = true; - WriteMsaCfg(DSP_GpioDriverEnable_15_8, MKWORD(rGpioDriverEnable)); - - MKWORD(rGpioOutputData) = 0; - rGpioOutputData.Latch10 = 0; - rGpioOutputData.Mask10 = true; - WriteMsaCfg(DSP_GpioOutputData_15_8, MKWORD(rGpioOutputData)); -} - - -static irqreturn_t UartInterrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static irqreturn_t DspInterrupt(int irq, void *dev_id) -{ - struct mwave_device_data *pDrvData = &mwave_s_mdd; - struct dsp_3780i_config_settings *pSettings = &pDrvData->rBDData.rDspSettings; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - unsigned short usIPCSource = 0, usIsolationMask, usPCNum; - - if (dsp3780I_GetIPCSource(usDspBaseIO, &usIPCSource) == 0) { - usIsolationMask = 1; - for (usPCNum = 1; usPCNum <= 16; usPCNum++) { - if (usIPCSource & usIsolationMask) { - usIPCSource &= ~usIsolationMask; - if (pDrvData->IPCs[usPCNum - 1].usIntCount == 0) { - pDrvData->IPCs[usPCNum - 1].usIntCount = 1; - } - if (pDrvData->IPCs[usPCNum - 1].bIsEnabled == true) { - wake_up_interruptible(&pDrvData->IPCs[usPCNum - 1].ipc_wait_queue); - } - } - if (usIPCSource == 0) - break; - /* try next IPC */ - usIsolationMask = usIsolationMask << 1; - } - } - return IRQ_HANDLED; -} - - -int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData) -{ - int retval = 0; - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - pBDData->bDSPEnabled = false; - pSettings->bInterruptClaimed = false; - - retval = smapi_init(); - if (retval) { - pr_err("%s: Error: SMAPI is not available on this machine\n", __func__); - } else { - if (mwave_3780i_irq || mwave_3780i_io || mwave_uart_irq || mwave_uart_io) { - retval = smapi_set_DSP_cfg(); - } - } - - return retval; -} - -void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData) -{ -} - -int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData) -{ - struct smapi_dsp_settings rSmapiInfo; - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - if (smapi_query_DSP_cfg(&rSmapiInfo)) { - pr_err("%s: Error: Could not query DSP config. Aborting.\n", __func__); - return -EIO; - } - - /* Sanity check */ - if ( - ( rSmapiInfo.usDspIRQ == 0 ) - || ( rSmapiInfo.usDspBaseIO == 0 ) - || ( rSmapiInfo.usUartIRQ == 0 ) - || ( rSmapiInfo.usUartBaseIO == 0 ) - ) { - pr_err("%s: Error: Illegal resource setting. Aborting.\n", __func__); - return -EIO; - } - - pSettings->bDSPEnabled = (rSmapiInfo.bDSPEnabled && rSmapiInfo.bDSPPresent); - pSettings->bModemEnabled = rSmapiInfo.bModemEnabled; - pSettings->usDspIrq = rSmapiInfo.usDspIRQ; - pSettings->usDspDma = rSmapiInfo.usDspDMA; - pSettings->usDspBaseIO = rSmapiInfo.usDspBaseIO; - pSettings->usUartIrq = rSmapiInfo.usUartIRQ; - pSettings->usUartBaseIO = rSmapiInfo.usUartBaseIO; - - pSettings->uDStoreSize = TP_ABILITIES_DATA_SIZE; - pSettings->uIStoreSize = TP_ABILITIES_INST_SIZE; - pSettings->uIps = TP_ABILITIES_INTS_PER_SEC; - - if (pSettings->bDSPEnabled && pSettings->bModemEnabled && pSettings->usDspIrq == pSettings->usUartIrq) { - pBDData->bShareDspIrq = pBDData->bShareUartIrq = 1; - } else { - pBDData->bShareDspIrq = pBDData->bShareUartIrq = 0; - } - - return 0; -} - - -int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData) -{ - int retval = 0; - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - struct resource *pres; - - pres = request_region(pSettings->usDspBaseIO, 16, "mwave_3780i"); - if ( pres == NULL ) retval = -EIO; - - if (retval) { - pr_err("%s: Error: Could not claim I/O region starting at %x\n", __func__, - pSettings->usDspBaseIO); - return -EIO; - } - - return retval; -} - -int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - release_region(pSettings->usDspBaseIO & (~3), 16); - - if (pSettings->bInterruptClaimed) { - free_irq(pSettings->usDspIrq, NULL); - pSettings->bInterruptClaimed = false; - } - - return 0; -} - - - -int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - bool bDSPPoweredUp = false, bInterruptAllocated = false; - - if (pBDData->bDSPEnabled) { - pr_err("%s: Error: DSP already enabled!\n", __func__); - goto exit_cleanup; - } - - if (!pSettings->bDSPEnabled) { - pr_err("%s: Error: pSettings->bDSPEnabled not set\n", __func__); - goto exit_cleanup; - } - - if ( - (pSettings->usDspIrq >= s_numIrqs) - || (pSettings->usDspDma >= s_numDmas) - || (s_ausThinkpadIrqToField[pSettings->usDspIrq] == 0xFFFF) - || (s_ausThinkpadDmaToField[pSettings->usDspDma] == 0xFFFF) - ) { - pr_err("%s: Error: invalid irq %x\n", __func__, pSettings->usDspIrq); - goto exit_cleanup; - } - - if ( - ((pSettings->usDspBaseIO & 0xF00F) != 0) - || (pSettings->usDspBaseIO & 0x0FF0) == 0 - ) { - pr_err("%s: Error: Invalid DSP base I/O address %x\n", __func__, - pSettings->usDspBaseIO); - goto exit_cleanup; - } - - if (pSettings->bModemEnabled) { - if ( - pSettings->usUartIrq >= s_numIrqs - || s_ausThinkpadIrqToField[pSettings->usUartIrq] == 0xFFFF - ) { - pr_err("%s: Error: Invalid UART IRQ %x\n", __func__, pSettings->usUartIrq); - goto exit_cleanup; - } - switch (pSettings->usUartBaseIO) { - case 0x03F8: - case 0x02F8: - case 0x03E8: - case 0x02E8: - break; - - default: - pr_err("%s: Error: Invalid UART base I/O address %x\n", __func__, - pSettings->usUartBaseIO); - goto exit_cleanup; - } - } - - pSettings->bDspIrqActiveLow = pSettings->bDspIrqPulse = true; - pSettings->bUartIrqActiveLow = pSettings->bUartIrqPulse = true; - - if (pBDData->bShareDspIrq) { - pSettings->bDspIrqActiveLow = false; - } - if (pBDData->bShareUartIrq) { - pSettings->bUartIrqActiveLow = false; - } - - pSettings->usNumTransfers = TP_CFG_NumTransfers; - pSettings->usReRequest = TP_CFG_RerequestTimer; - pSettings->bEnableMEMCS16 = TP_CFG_MEMCS16; - pSettings->usIsaMemCmdWidth = TP_CFG_IsaMemCmdWidth; - pSettings->bGateIOCHRDY = TP_CFG_GateIOCHRDY; - pSettings->bEnablePwrMgmt = TP_CFG_EnablePwrMgmt; - pSettings->usHBusTimerLoadValue = TP_CFG_HBusTimerValue; - pSettings->bDisableLBusTimeout = TP_CFG_DisableLBusTimeout; - pSettings->usN_Divisor = TP_CFG_N_Divisor; - pSettings->usM_Multiplier = TP_CFG_M_Multiplier; - pSettings->bPllBypass = TP_CFG_PllBypass; - pSettings->usChipletEnable = TP_CFG_ChipletEnable; - - if (request_irq(pSettings->usUartIrq, &UartInterrupt, 0, "mwave_uart", NULL)) { - pr_err("%s: Error: Could not get UART IRQ %x\n", __func__, pSettings->usUartIrq); - goto exit_cleanup; - } else { /* no conflict just release */ - free_irq(pSettings->usUartIrq, NULL); - } - - if (request_irq(pSettings->usDspIrq, &DspInterrupt, 0, "mwave_3780i", NULL)) { - pr_err("%s: Error: Could not get 3780i IRQ %x\n", __func__, pSettings->usDspIrq); - goto exit_cleanup; - } else { - bInterruptAllocated = true; - pSettings->bInterruptClaimed = true; - } - - smapi_set_DSP_power_state(false); - if (smapi_set_DSP_power_state(true)) { - pr_err("%s: Error: smapi_set_DSP_power_state(true) failed\n", __func__); - goto exit_cleanup; - } else { - bDSPPoweredUp = true; - } - - if (dsp3780I_EnableDSP(pSettings, s_ausThinkpadIrqToField, s_ausThinkpadDmaToField)) { - pr_err("%s: Error: dsp7880I_EnableDSP() failed\n", __func__); - goto exit_cleanup; - } - - EnableSRAM(pBDData); - - pBDData->bDSPEnabled = true; - - return 0; - -exit_cleanup: - pr_err("%s: Cleaning up\n", __func__); - if (bDSPPoweredUp) - smapi_set_DSP_power_state(false); - if (bInterruptAllocated) { - free_irq(pSettings->usDspIrq, NULL); - pSettings->bInterruptClaimed = false; - } - return -EIO; -} - - -int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - if (pBDData->bDSPEnabled) { - dsp3780I_DisableDSP(&pBDData->rDspSettings); - if (pSettings->bInterruptClaimed) { - free_irq(pSettings->usDspIrq, NULL); - pSettings->bInterruptClaimed = false; - } - smapi_set_DSP_power_state(false); - pBDData->bDSPEnabled = false; - } - - return 0; -} - - -int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - if (dsp3780I_Reset(pSettings) == 0) { - EnableSRAM(pBDData); - return 0; - } - return -EIO; -} - - -int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - - if (dsp3780I_Run(pSettings) == 0) { - // @BUG @TBD EnableSRAM(pBDData); - } else { - return -EIO; - } - - return 0; -} - - -int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities) -{ - memset(pAbilities, 0, sizeof(*pAbilities)); - /* fill out standard constant fields */ - pAbilities->instr_per_sec = pBDData->rDspSettings.uIps; - pAbilities->data_size = pBDData->rDspSettings.uDStoreSize; - pAbilities->inst_size = pBDData->rDspSettings.uIStoreSize; - pAbilities->bus_dma_bw = pBDData->rDspSettings.uDmaBandwidth; - - /* fill out dynamically determined fields */ - pAbilities->component_list[0] = 0x00010000 | MW_ADC_MASK; - pAbilities->component_list[1] = 0x00010000 | MW_ACI_MASK; - pAbilities->component_list[2] = 0x00010000 | MW_AIC1_MASK; - pAbilities->component_list[3] = 0x00010000 | MW_AIC2_MASK; - pAbilities->component_list[4] = 0x00010000 | MW_CDDAC_MASK; - pAbilities->component_list[5] = 0x00010000 | MW_MIDI_MASK; - pAbilities->component_list[6] = 0x00010000 | MW_UART_MASK; - pAbilities->component_count = 7; - - /* Fill out Mwave OS and BIOS task names */ - - memcpy(pAbilities->mwave_os_name, TP_ABILITIES_MWAVEOS_NAME, - sizeof(TP_ABILITIES_MWAVEOS_NAME)); - memcpy(pAbilities->bios_task_name, TP_ABILITIES_BIOSTASK_NAME, - sizeof(TP_ABILITIES_BIOSTASK_NAME)); - - return 0; -} - -int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, - void __user *pvBuffer, unsigned int uCount, - unsigned long ulDSPAddr) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - bool bRC = 0; - - if (pBDData->bDSPEnabled) { - switch (uOpcode) { - case IOCTL_MW_READ_DATA: - bRC = dsp3780I_ReadDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); - break; - - case IOCTL_MW_READCLEAR_DATA: - bRC = dsp3780I_ReadAndClearDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); - break; - - case IOCTL_MW_WRITE_DATA: - bRC = dsp3780I_WriteDStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); - break; - } - } - - return bRC ? -EIO : 0; -} - - -int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, - void __user *pvBuffer, unsigned int uCount, - unsigned long ulDSPAddr) -{ - struct dsp_3780i_config_settings *pSettings = &pBDData->rDspSettings; - unsigned short usDspBaseIO = pSettings->usDspBaseIO; - bool bRC = 0; - - if (pBDData->bDSPEnabled) { - switch (uOpcode) { - case IOCTL_MW_READ_INST: - bRC = dsp3780I_ReadIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); - break; - - case IOCTL_MW_WRITE_INST: - bRC = dsp3780I_WriteIStore(usDspBaseIO, pvBuffer, uCount, ulDSPAddr); - break; - } - } - - return bRC ? -EIO : 0; -} - diff --git a/drivers/char/mwave/tp3780i.h b/drivers/char/mwave/tp3780i.h deleted file mode 100644 index c0001a344741..000000000000 --- a/drivers/char/mwave/tp3780i.h +++ /dev/null @@ -1,103 +0,0 @@ -/* -* -* tp3780i.h -- declarations for tp3780i.c -* -* -* Written By: Mike Sullivan IBM Corporation -* -* Copyright (C) 1999 IBM Corporation -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* NO WARRANTY -* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR -* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT -* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, -* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is -* solely responsible for determining the appropriateness of using and -* distributing the Program and assumes all risks associated with its -* exercise of rights under this Agreement, including but not limited to -* the risks and costs of program errors, damage to or loss of data, -* programs or equipment, and unavailability or interruption of operations. -* -* DISCLAIMER OF LIABILITY -* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR -* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE -* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED -* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -* -* -* 10/23/2000 - Alpha Release -* First release to the public -*/ - -#ifndef _LINUX_TP3780I_H -#define _LINUX_TP3780I_H - -#include -#include "mwavepub.h" - - -/* DSP abilities constants for 3780i based Thinkpads */ -#define TP_ABILITIES_INTS_PER_SEC 39160800 -#define TP_ABILITIES_DATA_SIZE 32768 -#define TP_ABILITIES_INST_SIZE 32768 -#define TP_ABILITIES_MWAVEOS_NAME "mwaveos0700.dsp" -#define TP_ABILITIES_BIOSTASK_NAME "mwbio701.dsp" - - -/* DSP configuration values for 3780i based Thinkpads */ -#define TP_CFG_NumTransfers 3 /* 16 transfers */ -#define TP_CFG_RerequestTimer 1 /* 2 usec */ -#define TP_CFG_MEMCS16 0 /* Disabled, 16-bit memory assumed */ -#define TP_CFG_IsaMemCmdWidth 3 /* 295 nsec (16-bit) */ -#define TP_CFG_GateIOCHRDY 0 /* No IOCHRDY gating */ -#define TP_CFG_EnablePwrMgmt 1 /* Enable low poser suspend/resume */ -#define TP_CFG_HBusTimerValue 255 /* HBus timer load value */ -#define TP_CFG_DisableLBusTimeout 0 /* Enable LBus timeout */ -#define TP_CFG_N_Divisor 32 /* Clock = 39.1608 Mhz */ -#define TP_CFG_M_Multiplier 37 /* " */ -#define TP_CFG_PllBypass 0 /* don't bypass */ -#define TP_CFG_ChipletEnable 0xFFFF /* Enable all chiplets */ - -struct thinkpad_bd_data { - int bDSPEnabled; - int bShareDspIrq; - int bShareUartIrq; - struct dsp_3780i_config_settings rDspSettings; -}; - -int tp3780I_InitializeBoardData(struct thinkpad_bd_data *pBDData); -int tp3780I_CalcResources(struct thinkpad_bd_data *pBDData); -int tp3780I_ClaimResources(struct thinkpad_bd_data *pBDData); -int tp3780I_ReleaseResources(struct thinkpad_bd_data *pBDData); -int tp3780I_EnableDSP(struct thinkpad_bd_data *pBDData); -int tp3780I_DisableDSP(struct thinkpad_bd_data *pBDData); -int tp3780I_ResetDSP(struct thinkpad_bd_data *pBDData); -int tp3780I_StartDSP(struct thinkpad_bd_data *pBDData); -int tp3780I_QueryAbilities(struct thinkpad_bd_data *pBDData, struct mw_abilities *pAbilities); -void tp3780I_Cleanup(struct thinkpad_bd_data *pBDData); -int tp3780I_ReadWriteDspDStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, - void __user *pvBuffer, unsigned int uCount, - unsigned long ulDSPAddr); -int tp3780I_ReadWriteDspIStore(struct thinkpad_bd_data *pBDData, unsigned int uOpcode, - void __user *pvBuffer, unsigned int uCount, - unsigned long ulDSPAddr); - - -#endif diff --git a/drivers/char/powernv-op-panel.c b/drivers/char/powernv-op-panel.c index 53467b0a6187..63175b765c90 100644 --- a/drivers/char/powernv-op-panel.c +++ b/drivers/char/powernv-op-panel.c @@ -167,7 +167,7 @@ static int oppanel_probe(struct platform_device *pdev) if (!oppanel_data) return -ENOMEM; - oppanel_lines = kcalloc(num_lines, sizeof(oppanel_line_t), GFP_KERNEL); + oppanel_lines = kzalloc_objs(oppanel_line_t, num_lines); if (!oppanel_lines) { rc = -ENOMEM; goto free_oppanel_data; diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index d1dfbd8d4d42..6da817b9849f 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -689,7 +689,7 @@ static int pp_open(struct inode *inode, struct file *file) if (minor >= PARPORT_MAX) return -ENXIO; - pp = kmalloc(sizeof(struct pp_struct), GFP_KERNEL); + pp = kmalloc_obj(struct pp_struct); if (!pp) return -ENOMEM; diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 23871cde41fb..c73f443077a4 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -361,7 +361,7 @@ static int ps3flash_probe(struct ps3_system_bus_device *_dev) ps3flash_dev = dev; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { error = -ENOMEM; goto fail; diff --git a/drivers/char/random.c b/drivers/char/random.c index bab03c7c4194..7ff4d29911fd 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -96,8 +96,7 @@ static ATOMIC_NOTIFIER_HEAD(random_ready_notifier); /* Control how we warn userspace. */ static struct ratelimit_state urandom_warning = RATELIMIT_STATE_INIT_FLAGS("urandom_warning", HZ, 3, RATELIMIT_MSG_ON_RELEASE); -static int ratelimit_disable __read_mostly = - IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM); +static int ratelimit_disable __read_mostly = 0; module_param_named(ratelimit_disable, ratelimit_disable, int, 0644); MODULE_PARM_DESC(ratelimit_disable, "Disable random ratelimit suppression"); @@ -168,12 +167,6 @@ int __cold execute_with_initialized_rng(struct notifier_block *nb) return ret; } -#define warn_unseeded_randomness() \ - if (IS_ENABLED(CONFIG_WARN_ALL_UNSEEDED_RANDOM) && !crng_ready()) \ - printk_deferred(KERN_NOTICE "random: %s called from %pS with crng_init=%d\n", \ - __func__, (void *)_RET_IP_, crng_init) - - /********************************************************************* * * Fast key erasure RNG, the "crng". @@ -434,7 +427,6 @@ static void _get_random_bytes(void *buf, size_t len) */ void get_random_bytes(void *buf, size_t len) { - warn_unseeded_randomness(); _get_random_bytes(buf, len); } EXPORT_SYMBOL(get_random_bytes); @@ -523,8 +515,6 @@ type get_random_ ##type(void) \ struct batch_ ##type *batch; \ unsigned long next_gen; \ \ - warn_unseeded_randomness(); \ - \ if (!crng_ready()) { \ _get_random_bytes(&ret, sizeof(ret)); \ return ret; \ @@ -1248,7 +1238,7 @@ void __cold rand_initialize_disk(struct gendisk *disk) * If kzalloc returns null, we just won't use that entropy * source. */ - state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL); + state = kzalloc_obj(struct timer_rand_state); if (state) { state->last_time = INITIAL_JIFFIES; disk->random = state; diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index b381ea7e85d2..677d230a226c 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -776,7 +776,7 @@ static int __init tlclk_init(void) telclk_interrupt = (inb(TLCLK_REG7) & 0x0f); - alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); + alarm_events = kzalloc_obj(struct tlclk_alarms); if (!alarm_events) { ret = -ENOMEM; goto out1; diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 082b910ddf0d..0719577e584d 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -295,7 +295,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev, struct tpm_chip *chip; int rc; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c index 97c94b5e9340..2779a8738c59 100644 --- a/drivers/char/tpm/tpm-dev.c +++ b/drivers/char/tpm/tpm-dev.c @@ -30,7 +30,7 @@ static int tpm_open(struct inode *inode, struct file *file) return -EBUSY; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) goto out; diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 09df6353ef04..3b1cf1ca0420 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -991,7 +991,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip) return 0; } - auth = kzalloc(sizeof(*auth), GFP_KERNEL); + auth = kzalloc_obj(*auth); if (!auth) return -ENOMEM; diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c index 755b77b32ea4..99f1c1e5644b 100644 --- a/drivers/char/tpm/tpm_crb_ffa.c +++ b/drivers/char/tpm/tpm_crb_ffa.c @@ -346,7 +346,7 @@ static int tpm_crb_ffa_probe(struct ffa_device *ffa_dev) return -EINVAL; } - p = kzalloc(sizeof(*tpm_crb_ffa), GFP_KERNEL); + p = kzalloc_obj(*tpm_crb_ffa); if (!p) return -ENOMEM; tpm_crb_ffa = p; diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 4734a69406ce..6fb4d30eb6f6 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -611,7 +611,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, if (IS_ERR(chip)) return PTR_ERR(chip); - ibmvtpm = kzalloc(sizeof(struct ibmvtpm_dev), GFP_KERNEL); + ibmvtpm = kzalloc_obj(struct ibmvtpm_dev); if (!ibmvtpm) { dev_err(dev, "kzalloc for ibmvtpm failed\n"); goto cleanup; diff --git a/drivers/char/tpm/tpm_vtpm_proxy.c b/drivers/char/tpm/tpm_vtpm_proxy.c index 0818bb517805..7bb0f4d4a2ed 100644 --- a/drivers/char/tpm/tpm_vtpm_proxy.c +++ b/drivers/char/tpm/tpm_vtpm_proxy.c @@ -491,7 +491,7 @@ static struct proxy_dev *vtpm_proxy_create_proxy_dev(void) struct tpm_chip *chip; int err; - proxy_dev = kzalloc(sizeof(*proxy_dev), GFP_KERNEL); + proxy_dev = kzalloc_obj(*proxy_dev); if (proxy_dev == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/char/tpm/tpmrm-dev.c b/drivers/char/tpm/tpmrm-dev.c index c25df7ea064e..f48d4d9e179c 100644 --- a/drivers/char/tpm/tpmrm-dev.c +++ b/drivers/char/tpm/tpmrm-dev.c @@ -17,7 +17,7 @@ static int tpmrm_open(struct inode *inode, struct file *file) int rc; chip = container_of(inode->i_cdev, struct tpm_chip, cdevs); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return -ENOMEM; diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 556bf2256716..3c0cce57c4ae 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c @@ -338,7 +338,7 @@ static int tpmfront_probe(struct xenbus_device *dev, struct tpm_private *priv; int rv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { xenbus_dev_fatal(dev, -ENOMEM, "allocating priv structure"); return -ENOMEM; diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 088182e54deb..9a33217c68d9 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -412,7 +412,7 @@ static struct port_buffer *alloc_buf(struct virtio_device *vdev, size_t buf_size * Allocate buffer and the sg list. The sg list array is allocated * directly after the port_buffer struct. */ - buf = kmalloc(struct_size(buf, sg, pages), GFP_KERNEL); + buf = kmalloc_flex(*buf, sg, pages); if (!buf) goto fail; @@ -1325,7 +1325,7 @@ static int add_port(struct ports_device *portdev, u32 id) dev_t devt; int err; - port = kmalloc(sizeof(*port), GFP_KERNEL); + port = kmalloc_obj(*port); if (!port) { err = -ENOMEM; goto fail; @@ -1809,12 +1809,10 @@ static int init_vqs(struct ports_device *portdev) nr_ports = portdev->max_nr_ports; nr_queues = use_multiport(portdev) ? (nr_ports + 1) * 2 : 2; - vqs = kmalloc_array(nr_queues, sizeof(struct virtqueue *), GFP_KERNEL); - vqs_info = kcalloc(nr_queues, sizeof(*vqs_info), GFP_KERNEL); - portdev->in_vqs = kmalloc_array(nr_ports, sizeof(struct virtqueue *), - GFP_KERNEL); - portdev->out_vqs = kmalloc_array(nr_ports, sizeof(struct virtqueue *), - GFP_KERNEL); + vqs = kmalloc_objs(struct virtqueue *, nr_queues); + vqs_info = kzalloc_objs(*vqs_info, nr_queues); + portdev->in_vqs = kmalloc_objs(struct virtqueue *, nr_ports); + portdev->out_vqs = kmalloc_objs(struct virtqueue *, nr_ports); if (!vqs || !vqs_info || !portdev->in_vqs || !portdev->out_vqs) { err = -ENOMEM; goto free; @@ -1965,7 +1963,7 @@ static int virtcons_probe(struct virtio_device *vdev) return -EINVAL; } - portdev = kmalloc(sizeof(*portdev), GFP_KERNEL); + portdev = kmalloc_obj(*portdev); if (!portdev) { err = -ENOMEM; goto fail; diff --git a/drivers/char/xilinx_hwicap/fifo_icap.c b/drivers/char/xilinx_hwicap/fifo_icap.c index 619f3a30ec55..7bd786fa1be8 100644 --- a/drivers/char/xilinx_hwicap/fifo_icap.c +++ b/drivers/char/xilinx_hwicap/fifo_icap.c @@ -48,7 +48,7 @@ #define XHI_GIER_GIE_MASK 0x80000000 /* Global Interrupt enable Mask */ -/** +/* * HwIcap Device Interrupt Status/Enable Registers * * Interrupt Status Register (IPISR) : This register holds the @@ -102,6 +102,8 @@ static inline void fifo_icap_fifo_write(struct hwicap_drvdata *drvdata, * @drvdata: a pointer to the drvdata. * * This function will silently fail if the fifo is empty. + * + * Returns: 32-bit data from the Read FIFO **/ static inline u32 fifo_icap_fifo_read(struct hwicap_drvdata *drvdata) { @@ -156,6 +158,8 @@ static inline void fifo_icap_start_readback(struct hwicap_drvdata *drvdata) * D2 - Always 1 * D1 - Always 1 * D0 - Done bit + * + * Returns: the 32-bit ICAP status register **/ u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata) { @@ -165,8 +169,11 @@ u32 fifo_icap_get_status(struct hwicap_drvdata *drvdata) } /** - * fifo_icap_busy - Return true if the ICAP is still processing a transaction. + * fifo_icap_busy - Check the ICAP busy status. * @drvdata: a pointer to the drvdata. + * + * Returns: %true if the ICAP is still processing a transaction, + * otherwise %false **/ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) { @@ -178,7 +185,7 @@ static inline u32 fifo_icap_busy(struct hwicap_drvdata *drvdata) * fifo_icap_write_fifo_vacancy - Query the write fifo available space. * @drvdata: a pointer to the drvdata. * - * Return the number of words that can be safely pushed into the write fifo. + * Returns: the number of words that can be safely pushed into the write fifo. **/ static inline u32 fifo_icap_write_fifo_vacancy( struct hwicap_drvdata *drvdata) @@ -190,7 +197,7 @@ static inline u32 fifo_icap_write_fifo_vacancy( * fifo_icap_read_fifo_occupancy - Query the read fifo available data. * @drvdata: a pointer to the drvdata. * - * Return the number of words that can be safely read from the read fifo. + * Returns: the number of words that can be safely read from the read fifo. **/ static inline u32 fifo_icap_read_fifo_occupancy( struct hwicap_drvdata *drvdata) @@ -205,10 +212,12 @@ static inline u32 fifo_icap_read_fifo_occupancy( * ICAP device. * @num_words: the number of words (32 bit) to write to the ICAP * device. - + * * This function writes the given user data to the Write FIFO in * polled mode and starts the transfer of the data to * the ICAP device. + * + * Returns: %0 on success or %-errno on failure. **/ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, u32 *frame_buffer, u32 num_words) @@ -280,11 +289,13 @@ int fifo_icap_set_configuration(struct hwicap_drvdata *drvdata, /** * fifo_icap_get_configuration - Read configuration data from the device. * @drvdata: a pointer to the drvdata. - * @data: Address of the data representing the partial bitstream - * @size: the size of the partial bitstream in 32 bit words. + * @frame_buffer: Address of the data representing the partial bitstream + * @num_words: the size of the partial bitstream in 32 bit words. * * This function reads the specified number of words from the ICAP device in * the polled mode. + * + * Returns: %0 on success or %-errno on failure. */ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, u32 *frame_buffer, u32 num_words) @@ -347,7 +358,7 @@ int fifo_icap_get_configuration(struct hwicap_drvdata *drvdata, } /** - * buffer_icap_reset - Reset the logic of the icap device. + * fifo_icap_reset - Reset the logic of the icap device. * @drvdata: a pointer to the drvdata. * * This function forces the software reset of the complete HWICAP device. diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c index c92a628e389e..5e8f03b77064 100644 --- a/drivers/char/xillybus/xillybus_class.c +++ b/drivers/char/xillybus/xillybus_class.c @@ -57,7 +57,7 @@ int xillybus_init_chrdev(struct device *dev, size_t namelen; struct xilly_unit *unit, *u; - unit = kzalloc(sizeof(*unit), GFP_KERNEL); + unit = kzalloc_obj(*unit); if (!unit) return -ENOMEM; diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c index fc4e69b5cb6a..952ef149aba1 100644 --- a/drivers/char/xillybus/xillybus_core.c +++ b/drivers/char/xillybus/xillybus_core.c @@ -319,7 +319,7 @@ static int xilly_map_single(struct xilly_endpoint *ep, dma_addr_t addr; struct xilly_mapping *this; - this = kzalloc(sizeof(*this), GFP_KERNEL); + this = kzalloc_obj(*this); if (!this) return -ENOMEM; diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c index 386531474213..34e7ad3bcab3 100644 --- a/drivers/char/xillybus/xillyusb.c +++ b/drivers/char/xillybus/xillyusb.c @@ -495,7 +495,7 @@ static struct xillyusb_endpoint struct xillyusb_endpoint *ep; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return NULL; @@ -522,7 +522,7 @@ static struct xillyusb_endpoint struct xillybuffer *xb; unsigned long addr; - xb = kzalloc(sizeof(*xb), GFP_KERNEL); + xb = kzalloc_obj(*xb); if (!xb) { endpoint_dealloc(ep); @@ -1336,7 +1336,7 @@ static int xillyusb_open(struct inode *inode, struct file *filp) } if (filp->f_mode & FMODE_READ) { - in_fifo = kzalloc(sizeof(*in_fifo), GFP_KERNEL); + in_fifo = kzalloc_obj(*in_fifo); if (!in_fifo) { rc = -ENOMEM; @@ -1943,7 +1943,7 @@ static int setup_channels(struct xillyusb_dev *xdev, struct xillyusb_channel *chan, *new_channels; int i; - chan = kcalloc(num_channels, sizeof(*chan), GFP_KERNEL); + chan = kzalloc_objs(*chan, num_channels); if (!chan) return -ENOMEM; @@ -2149,7 +2149,7 @@ static int xillyusb_probe(struct usb_interface *interface, struct xillyusb_dev *xdev; int rc; - xdev = kzalloc(sizeof(*xdev), GFP_KERNEL); + xdev = kzalloc_obj(*xdev); if (!xdev) return -ENOMEM; diff --git a/drivers/clk/.kunitconfig b/drivers/clk/.kunitconfig index 08e26137f3d9..8a0ea41934a2 100644 --- a/drivers/clk/.kunitconfig +++ b/drivers/clk/.kunitconfig @@ -1,4 +1,5 @@ CONFIG_KUNIT=y +CONFIG_KUNIT_UML_PCI=n CONFIG_OF=y CONFIG_OF_OVERLAY=y CONFIG_COMMON_CLK=y @@ -6,4 +7,3 @@ CONFIG_CLK_KUNIT_TEST=y CONFIG_CLK_FIXED_RATE_KUNIT_TEST=y CONFIG_CLK_GATE_KUNIT_TEST=y CONFIG_CLK_FD_KUNIT_TEST=y -CONFIG_UML_PCI_OVER_VIRTIO=n diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 619bd63a3c77..3d803b4cf5c1 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -284,18 +284,6 @@ config COMMON_CLK_LAN966X LAN966X SoC. GCK generates and supplies clock to various peripherals within the SoC. -config COMMON_CLK_ASPEED - bool "Clock driver for Aspeed BMC SoCs" - depends on ARCH_ASPEED || COMPILE_TEST - default ARCH_ASPEED - select MFD_SYSCON - select RESET_CONTROLLER - help - This driver supports the SoC clocks on the Aspeed BMC platforms. - - The G4 and G5 series, including the ast2400 and ast2500, are supported - by this driver. - config COMMON_CLK_S2MPS11 tristate "Clock driver for S2MPS1X/S5M8767 MFD" depends on MFD_SEC_CORE || COMPILE_TEST @@ -513,6 +501,7 @@ config COMMON_CLK_RPMI source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" +source "drivers/clk/aspeed/Kconfig" source "drivers/clk/baikal-t1/Kconfig" source "drivers/clk/bcm/Kconfig" source "drivers/clk/hisilicon/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 61ec08404442..f7bce3951a30 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -62,8 +62,6 @@ obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o -obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o -obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o obj-$(CONFIG_COMMON_CLK_K210) += clk-k210.o @@ -114,6 +112,7 @@ obj-$(CONFIG_COMMON_CLK_XGENE) += clk-xgene.o # please keep this section sorted lexicographically by directory path name obj-y += actions/ obj-y += analogbits/ +obj-y += aspeed/ obj-$(CONFIG_COMMON_CLK_AT91) += at91/ obj-$(CONFIG_ARCH_ARTPEC) += axis/ obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ diff --git a/drivers/clk/actions/owl-composite.c b/drivers/clk/actions/owl-composite.c index 00b74f8bc437..9540444307d6 100644 --- a/drivers/clk/actions/owl-composite.c +++ b/drivers/clk/actions/owl-composite.c @@ -57,15 +57,10 @@ static int owl_comp_div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct owl_composite *comp = hw_to_owl_comp(hw); - long rate; + struct owl_divider_hw *div = &comp->rate.div_hw; - rate = owl_divider_helper_round_rate(&comp->common, &comp->rate.div_hw, - req->rate, &req->best_parent_rate); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_determine_rate(&comp->common.hw, req, div->table, + div->width, div->div_flags); } static unsigned long owl_comp_div_recalc_rate(struct clk_hw *hw, diff --git a/drivers/clk/actions/owl-divider.c b/drivers/clk/actions/owl-divider.c index 118f1393c678..316ace80e87e 100644 --- a/drivers/clk/actions/owl-divider.c +++ b/drivers/clk/actions/owl-divider.c @@ -13,26 +13,13 @@ #include "owl-divider.h" -long owl_divider_helper_round_rate(struct owl_clk_common *common, - const struct owl_divider_hw *div_hw, - unsigned long rate, - unsigned long *parent_rate) -{ - return divider_round_rate(&common->hw, rate, parent_rate, - div_hw->table, div_hw->width, - div_hw->div_flags); -} - static int owl_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct owl_divider *div = hw_to_owl_divider(hw); - req->rate = owl_divider_helper_round_rate(&div->common, &div->div_hw, - req->rate, - &req->best_parent_rate); - - return 0; + return divider_determine_rate(hw, req, div->div_hw.table, + div->div_hw.width, div->div_hw.div_flags); } unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, diff --git a/drivers/clk/actions/owl-divider.h b/drivers/clk/actions/owl-divider.h index d76f58782c52..1d3bb4e5898a 100644 --- a/drivers/clk/actions/owl-divider.h +++ b/drivers/clk/actions/owl-divider.h @@ -56,11 +56,6 @@ static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw) return container_of(common, struct owl_divider, common); } -long owl_divider_helper_round_rate(struct owl_clk_common *common, - const struct owl_divider_hw *div_hw, - unsigned long rate, - unsigned long *parent_rate); - unsigned long owl_divider_helper_recalc_rate(struct owl_clk_common *common, const struct owl_divider_hw *div_hw, unsigned long parent_rate); diff --git a/drivers/clk/aspeed/Kconfig b/drivers/clk/aspeed/Kconfig new file mode 100644 index 000000000000..ef50481c31ff --- /dev/null +++ b/drivers/clk/aspeed/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config COMMON_CLK_ASPEED + bool "Clock driver for Aspeed BMC SoCs" + depends on ARCH_ASPEED || COMPILE_TEST + default ARCH_ASPEED + select MFD_SYSCON + select RESET_CONTROLLER + help + This driver supports the SoC clocks on the Aspeed BMC platforms. + + The G4 and G5 series, including the ast2400 and ast2500, are supported + by this driver. + +config COMMON_CLK_AST2700 + bool "Clock driver for AST2700 SoC" + depends on ARCH_ASPEED || COMPILE_TEST + help + This driver provides support for clock on AST2700 SoC. + The driver is responsible for managing the various clocks required + by the peripherals and cores within the AST2700. diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile new file mode 100644 index 000000000000..eb5d219f738d --- /dev/null +++ b/drivers/clk/aspeed/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o +obj-$(CONFIG_MACH_ASPEED_G6) += clk-ast2600.o +obj-$(CONFIG_COMMON_CLK_AST2700) += clk-ast2700.o diff --git a/drivers/clk/clk-aspeed.c b/drivers/clk/aspeed/clk-aspeed.c similarity index 99% rename from drivers/clk/clk-aspeed.c rename to drivers/clk/aspeed/clk-aspeed.c index ff84191d0fe8..38a5766a435c 100644 --- a/drivers/clk/clk-aspeed.c +++ b/drivers/clk/aspeed/clk-aspeed.c @@ -278,6 +278,8 @@ static const u8 aspeed_resets[] = { [ASPEED_RESET_PECI] = 10, [ASPEED_RESET_I2C] = 2, [ASPEED_RESET_AHB] = 1, + [ASPEED_RESET_HACE] = 4, + [ASPEED_RESET_VIDEO] = 6, /* * SCUD4 resets start at an offset to separate them from @@ -352,7 +354,7 @@ static struct clk_hw *aspeed_clk_hw_register_gate(struct device *dev, struct clk_hw *hw; int ret; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); @@ -696,9 +698,7 @@ static void __init aspeed_cc_init(struct device_node *np) if (!scu_base) return; - aspeed_clk_data = kzalloc(struct_size(aspeed_clk_data, hws, - ASPEED_NUM_CLKS), - GFP_KERNEL); + aspeed_clk_data = kzalloc_flex(*aspeed_clk_data, hws, ASPEED_NUM_CLKS); if (!aspeed_clk_data) return; aspeed_clk_data->num = ASPEED_NUM_CLKS; diff --git a/drivers/clk/clk-aspeed.h b/drivers/clk/aspeed/clk-aspeed.h similarity index 100% rename from drivers/clk/clk-aspeed.h rename to drivers/clk/aspeed/clk-aspeed.h diff --git a/drivers/clk/clk-ast2600.c b/drivers/clk/aspeed/clk-ast2600.c similarity index 99% rename from drivers/clk/clk-ast2600.c rename to drivers/clk/aspeed/clk-ast2600.c index 114afc13d640..873879e5ad9b 100644 --- a/drivers/clk/clk-ast2600.c +++ b/drivers/clk/aspeed/clk-ast2600.c @@ -431,7 +431,7 @@ static struct clk_hw *aspeed_g6_clk_hw_register_gate(struct device *dev, struct clk_hw *hw; int ret; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); @@ -838,8 +838,8 @@ static void __init aspeed_g6_cc_init(struct device_node *np) soc_rev = (readl(scu_g6_base + ASPEED_G6_SILICON_REV) & CHIP_REVISION_ID) >> 16; - aspeed_g6_clk_data = kzalloc(struct_size(aspeed_g6_clk_data, hws, - ASPEED_G6_NUM_CLKS), GFP_KERNEL); + aspeed_g6_clk_data = kzalloc_flex(*aspeed_g6_clk_data, hws, + ASPEED_G6_NUM_CLKS); if (!aspeed_g6_clk_data) return; aspeed_g6_clk_data->num = ASPEED_G6_NUM_CLKS; diff --git a/drivers/clk/aspeed/clk-ast2700.c b/drivers/clk/aspeed/clk-ast2700.c new file mode 100644 index 000000000000..8b7b382f6f3e --- /dev/null +++ b/drivers/clk/aspeed/clk-ast2700.c @@ -0,0 +1,1055 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * Author: Ryan Chen + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* SOC0 */ +#define SCU0_HWSTRAP1 0x010 +#define SCU0_CLK_STOP 0x240 +#define SCU0_CLK_SEL1 0x280 +#define SCU0_CLK_SEL2 0x284 +#define GET_USB_REFCLK_DIV(x) ((GENMASK(23, 20) & (x)) >> 20) +#define UART_DIV13_EN BIT(30) +#define SCU0_HPLL_PARAM 0x300 +#define SCU0_DPLL_PARAM 0x308 +#define SCU0_MPLL_PARAM 0x310 +#define SCU0_D0CLK_PARAM 0x320 +#define SCU0_D1CLK_PARAM 0x330 +#define SCU0_CRT0CLK_PARAM 0x340 +#define SCU0_CRT1CLK_PARAM 0x350 +#define SCU0_MPHYCLK_PARAM 0x360 + +/* SOC1 */ +#define SCU1_REVISION_ID 0x0 +#define REVISION_ID GENMASK(23, 16) +#define SCU1_CLK_STOP 0x240 +#define SCU1_CLK_STOP2 0x260 +#define SCU1_CLK_SEL1 0x280 +#define SCU1_CLK_SEL2 0x284 +#define SCU1_CLK_I3C_DIV_MASK GENMASK(25, 23) +#define SCU1_CLK_I3C_DIV(n) ((n) - 1) +#define UXCLK_MASK GENMASK(1, 0) +#define HUXCLK_MASK GENMASK(4, 3) +#define SCU1_HPLL_PARAM 0x300 +#define SCU1_APLL_PARAM 0x310 +#define SCU1_DPLL_PARAM 0x320 +#define SCU1_UXCLK_CTRL 0x330 +#define SCU1_HUXCLK_CTRL 0x334 +#define SCU1_MAC12_CLK_DLY 0x390 +#define SCU1_MAC12_CLK_DLY_100M 0x394 +#define SCU1_MAC12_CLK_DLY_10M 0x398 + +enum ast2700_clk_type { + CLK_MUX, + CLK_PLL, + CLK_HPLL, + CLK_GATE, + CLK_MISC, + CLK_FIXED, + CLK_DIVIDER, + CLK_UART_PLL, + CLK_GATE_ASPEED, + CLK_FIXED_FACTOR, + CLK_FIXED_DISPLAY, +}; + +struct ast2700_clk_fixed_factor_data { + unsigned int mult; + unsigned int div; + int parent_id; +}; + +struct ast2700_clk_gate_data { + int parent_id; + u32 flags; + u32 reg; + u8 bit; +}; + +struct ast2700_clk_mux_data { + const struct clk_hw **parent_hws; + const unsigned int *parent_ids; + unsigned int num_parents; + u8 bit_shift; + u8 bit_width; + u32 reg; +}; + +struct ast2700_clk_div_data { + const struct clk_div_table *div_table; + unsigned int parent_id; + u8 bit_shift; + u8 bit_width; + u32 reg; +}; + +struct ast2700_clk_pll_data { + unsigned int parent_id; + u32 reg; +}; + +struct ast2700_clk_fixed_rate_data { + unsigned long fixed_rate; +}; + +struct ast2700_clk_display_fixed_data { + u32 reg; +}; + +struct ast2700_clk_info { + const char *name; + u32 id; + u32 reg; + u32 type; + union { + struct ast2700_clk_fixed_factor_data factor; + struct ast2700_clk_fixed_rate_data rate; + struct ast2700_clk_display_fixed_data display_rate; + struct ast2700_clk_gate_data gate; + struct ast2700_clk_div_data div; + struct ast2700_clk_pll_data pll; + struct ast2700_clk_mux_data mux; + } data; +}; + +struct ast2700_clk_data { + const struct ast2700_clk_info *clk_info; + unsigned int nr_clks; + const int scu; +}; + +struct ast2700_clk_ctrl { + const struct ast2700_clk_data *clk_data; + struct device *dev; + void __iomem *base; + spinlock_t lock; /* clk lock */ +}; + +static const struct clk_div_table ast2700_rgmii_div_table[] = { + { 0x0, 4 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_rmii_div_table[] = { + { 0x0, 8 }, + { 0x1, 8 }, + { 0x2, 12 }, + { 0x3, 16 }, + { 0x4, 20 }, + { 0x5, 24 }, + { 0x6, 28 }, + { 0x7, 32 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table[] = { + { 0x0, 2 }, + { 0x1, 2 }, + { 0x2, 3 }, + { 0x3, 4 }, + { 0x4, 5 }, + { 0x5, 6 }, + { 0x6, 7 }, + { 0x7, 8 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_div_table2[] = { + { 0x0, 2 }, + { 0x1, 4 }, + { 0x2, 6 }, + { 0x3, 8 }, + { 0x4, 10 }, + { 0x5, 12 }, + { 0x6, 14 }, + { 0x7, 16 }, + { 0 } +}; + +static const struct clk_div_table ast2700_hclk_div_table[] = { + { 0x0, 6 }, + { 0x1, 5 }, + { 0x2, 4 }, + { 0x3, 7 }, + { 0 } +}; + +static const struct clk_div_table ast2700_clk_uart_div_table[] = { + { 0x0, 1 }, + { 0x1, 13 }, + { 0 } +}; + +/* soc 0 */ +static const unsigned int psp_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL, + SCU0_CLK_MPLL_DIV2, + SCU0_CLK_HPLL_DIV2, + SCU0_CLK_HPLL, + SCU0_CLK_HPLL +}; + +static const struct clk_hw *psp_parent_hws[ARRAY_SIZE(psp_parent_ids)]; + +static const unsigned int hclk_parent_ids[] = { + SCU0_CLK_HPLL, + SCU0_CLK_MPLL +}; + +static const struct clk_hw *hclk_parent_hws[ARRAY_SIZE(hclk_parent_ids)]; + +static const unsigned int emmc_parent_ids[] = { + SCU0_CLK_MPLL_DIV4, + SCU0_CLK_HPLL_DIV4 +}; + +static const struct clk_hw *emmc_parent_hws[ARRAY_SIZE(emmc_parent_ids)]; + +static const unsigned int mphy_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL, + SCU0_CLK_DPLL, + SCU0_CLK_192M +}; + +static const struct clk_hw *mphy_parent_hws[ARRAY_SIZE(mphy_parent_ids)]; + +static const unsigned int u2phy_parent_ids[] = { + SCU0_CLK_MPLL, + SCU0_CLK_HPLL +}; + +static const struct clk_hw *u2phy_parent_hws[ARRAY_SIZE(u2phy_parent_ids)]; + +static const unsigned int uart_parent_ids[] = { + SCU0_CLK_24M, + SCU0_CLK_192M +}; + +static const struct clk_hw *uart_parent_hws[ARRAY_SIZE(uart_parent_ids)]; + +/* soc 1 */ +static const unsigned int uartx_parent_ids[] = { + SCU1_CLK_UARTX, + SCU1_CLK_HUARTX +}; + +static const struct clk_hw *uartx_parent_hws[ARRAY_SIZE(uartx_parent_ids)]; + +static const unsigned int uxclk_parent_ids[] = { + SCU1_CLK_APLL_DIV4, + SCU1_CLK_APLL_DIV2, + SCU1_CLK_APLL, + SCU1_CLK_HPLL +}; + +static const struct clk_hw *uxclk_parent_hws[ARRAY_SIZE(uxclk_parent_ids)]; + +static const unsigned int sdclk_parent_ids[] = { + SCU1_CLK_HPLL, + SCU1_CLK_APLL +}; + +static const struct clk_hw *sdclk_parent_hws[ARRAY_SIZE(sdclk_parent_ids)]; + +#define FIXED_CLK(_id, _name, _rate) \ + { \ + .id = _id, \ + .type = CLK_FIXED, \ + .name = _name, \ + .data = { .rate = { .fixed_rate = _rate, } }, \ + } + +#define FIXED_DISPLAY_CLK(_id, _name, _reg) \ + { \ + .id = _id, \ + .type = CLK_FIXED_DISPLAY, \ + .name = _name, \ + .data = { .display_rate = { .reg = _reg } }, \ + } + +#define PLL_CLK(_id, _type, _name, _parent_id, _reg) \ + { \ + .id = _id, \ + .type = _type, \ + .name = _name, \ + .data = { .pll = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + } }, \ + } + +#define MUX_CLK(_id, _name, _parent_ids, _num_parents, _parent_hws, _reg, _shift, _width) \ + { \ + .id = _id, \ + .type = CLK_MUX, \ + .name = _name, \ + .data = { \ + .mux = { \ + .parent_ids = _parent_ids, \ + .parent_hws = _parent_hws, \ + .num_parents = _num_parents, \ + .reg = (_reg), \ + .bit_shift = _shift, \ + .bit_width = _width, \ + }, \ + }, \ + } + +#define DIVIDER_CLK(_id, _name, _parent_id, _reg, _shift, _width, _div_table) \ + { \ + .id = _id, \ + .type = CLK_DIVIDER, \ + .name = _name, \ + .data = { \ + .div = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + .bit_shift = _shift, \ + .bit_width = _width, \ + .div_table = _div_table, \ + }, \ + }, \ + } + +#define FIXED_FACTOR_CLK(_id, _name, _parent_id, _mult, _div) \ + { \ + .id = _id, \ + .type = CLK_FIXED_FACTOR, \ + .name = _name, \ + .data = { .factor = { .parent_id = _parent_id, .mult = _mult, .div = _div, } }, \ + } + +#define GATE_CLK(_id, _type, _name, _parent_id, _reg, _bit, _flags) \ + { \ + .id = _id, \ + .type = _type, \ + .name = _name, \ + .data = { \ + .gate = { \ + .parent_id = _parent_id, \ + .reg = _reg, \ + .bit = _bit, \ + .flags = _flags, \ + }, \ + }, \ + } + +static const struct ast2700_clk_info ast2700_scu0_clk_info[] __initconst = { + FIXED_CLK(SCU0_CLKIN, "soc0-clkin", 25 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_24M, "soc0-clk24Mhz", 24 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_192M, "soc0-clk192Mhz", 192 * HZ_PER_MHZ), + FIXED_CLK(SCU0_CLK_U2PHY_CLK12M, "u2phy_clk12m", 12 * HZ_PER_MHZ), + FIXED_DISPLAY_CLK(SCU0_CLK_D0, "d0clk", SCU0_D0CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_D1, "d1clk", SCU0_D1CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_CRT0, "crt0clk", SCU0_CRT0CLK_PARAM), + FIXED_DISPLAY_CLK(SCU0_CLK_CRT1, "crt1clk", SCU0_CRT1CLK_PARAM), + PLL_CLK(SCU0_CLK_HPLL, CLK_HPLL, "soc0-hpll", SCU0_CLKIN, SCU0_HPLL_PARAM), + PLL_CLK(SCU0_CLK_DPLL, CLK_PLL, "soc0-dpll", SCU0_CLKIN, SCU0_DPLL_PARAM), + PLL_CLK(SCU0_CLK_MPLL, CLK_PLL, "soc0-mpll", SCU0_CLKIN, SCU0_MPLL_PARAM), + FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV2, "soc0-hpll_div2", SCU0_CLK_HPLL, 1, 2), + FIXED_FACTOR_CLK(SCU0_CLK_HPLL_DIV4, "soc0-hpll_div4", SCU0_CLK_HPLL, 1, 4), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV2, "soc0-mpll_div2", SCU0_CLK_MPLL, 1, 2), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV4, "soc0-mpll_div4", SCU0_CLK_MPLL, 1, 4), + FIXED_FACTOR_CLK(SCU0_CLK_MPLL_DIV8, "soc0-mpll_div8", SCU0_CLK_MPLL, 1, 8), + FIXED_FACTOR_CLK(SCU0_CLK_AXI1, "axi1clk", SCU0_CLK_MPLL, 1, 4), + MUX_CLK(SCU0_CLK_PSP, "pspclk", psp_parent_ids, ARRAY_SIZE(psp_parent_ids), + psp_parent_hws, SCU0_HWSTRAP1, 2, 3), + FIXED_FACTOR_CLK(SCU0_CLK_AXI0, "axi0clk", SCU0_CLK_PSP, 1, 2), + MUX_CLK(SCU0_CLK_AHBMUX, "soc0-ahbmux", hclk_parent_ids, ARRAY_SIZE(hclk_parent_ids), + hclk_parent_hws, SCU0_HWSTRAP1, 7, 1), + MUX_CLK(SCU0_CLK_EMMCMUX, "emmcsrc-mux", emmc_parent_ids, ARRAY_SIZE(emmc_parent_ids), + emmc_parent_hws, SCU0_CLK_SEL1, 11, 1), + MUX_CLK(SCU0_CLK_MPHYSRC, "mphysrc", mphy_parent_ids, ARRAY_SIZE(mphy_parent_ids), + mphy_parent_hws, SCU0_CLK_SEL2, 18, 2), + MUX_CLK(SCU0_CLK_U2PHY_REFCLKSRC, "u2phy_refclksrc", u2phy_parent_ids, + ARRAY_SIZE(u2phy_parent_ids), u2phy_parent_hws, SCU0_CLK_SEL2, 23, 1), + MUX_CLK(SCU0_CLK_UART, "soc0-uartclk", uart_parent_ids, ARRAY_SIZE(uart_parent_ids), + uart_parent_hws, SCU0_CLK_SEL2, 14, 1), + PLL_CLK(SCU0_CLK_MPHY, CLK_MISC, "mphyclk", SCU0_CLK_MPHYSRC, SCU0_MPHYCLK_PARAM), + PLL_CLK(SCU0_CLK_U2PHY_REFCLK, CLK_MISC, "u2phy_refclk", SCU0_CLK_U2PHY_REFCLKSRC, + SCU0_CLK_SEL2), + DIVIDER_CLK(SCU0_CLK_AHB, "soc0-ahb", SCU0_CLK_AHBMUX, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_EMMC, "emmcclk", SCU0_CLK_EMMCMUX, + SCU0_CLK_SEL1, 12, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU0_CLK_APB, "soc0-apb", SCU0_CLK_AXI0, + SCU0_CLK_SEL1, 23, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU0_CLK_HPLL_DIV_AHB, "soc0-hpll-ahb", SCU0_CLK_HPLL, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_MPLL_DIV_AHB, "soc0-mpll-ahb", SCU0_CLK_MPLL, + SCU0_HWSTRAP1, 5, 2, ast2700_hclk_div_table), + DIVIDER_CLK(SCU0_CLK_UART4, "uart4clk", SCU0_CLK_UART, + SCU0_CLK_SEL2, 30, 1, ast2700_clk_uart_div_table), + GATE_CLK(SCU0_CLK_GATE_MCLK, CLK_GATE_ASPEED, "mclk-gate", SCU0_CLK_MPLL, + SCU0_CLK_STOP, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_ECLK, CLK_GATE_ASPEED, "eclk-gate", -1, SCU0_CLK_STOP, 1, 0), + GATE_CLK(SCU0_CLK_GATE_2DCLK, CLK_GATE_ASPEED, "gclk-gate", -1, SCU0_CLK_STOP, 2, 0), + GATE_CLK(SCU0_CLK_GATE_VCLK, CLK_GATE_ASPEED, "vclk-gate", -1, SCU0_CLK_STOP, 3, 0), + GATE_CLK(SCU0_CLK_GATE_BCLK, CLK_GATE_ASPEED, "bclk-gate", -1, + SCU0_CLK_STOP, 4, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_VGA0CLK, CLK_GATE_ASPEED, "vga0clk-gate", -1, + SCU0_CLK_STOP, 5, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_REFCLK, CLK_GATE_ASPEED, "soc0-refclk-gate", SCU0_CLKIN, + SCU0_CLK_STOP, 6, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_PORTBUSB2CLK, CLK_GATE_ASPEED, "portb-usb2clk-gate", -1, + SCU0_CLK_STOP, 7, 0), + GATE_CLK(SCU0_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "uhciclk-gate", -1, SCU0_CLK_STOP, 9, 0), + GATE_CLK(SCU0_CLK_GATE_VGA1CLK, CLK_GATE_ASPEED, "vga1clk-gate", -1, + SCU0_CLK_STOP, 10, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DDRPHYCLK, CLK_GATE_ASPEED, "ddrphy-gate", -1, + SCU0_CLK_STOP, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_E2M0CLK, CLK_GATE_ASPEED, "e2m0clk-gate", -1, + SCU0_CLK_STOP, 12, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_HACCLK, CLK_GATE_ASPEED, "hacclk-gate", -1, SCU0_CLK_STOP, 13, 0), + GATE_CLK(SCU0_CLK_GATE_PORTAUSB2CLK, CLK_GATE_ASPEED, "porta-usb2clk-gate", -1, + SCU0_CLK_STOP, 14, 0), + GATE_CLK(SCU0_CLK_GATE_UART4CLK, CLK_GATE_ASPEED, "uart4clk-gate", SCU0_CLK_UART4, + SCU0_CLK_STOP, 15, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc0-sliclk-gate", -1, + SCU0_CLK_STOP, 16, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DACCLK, CLK_GATE_ASPEED, "dacclk-gate", -1, + SCU0_CLK_STOP, 17, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_DP, CLK_GATE_ASPEED, "dpclk-gate", -1, + SCU0_CLK_STOP, 18, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_E2M1CLK, CLK_GATE_ASPEED, "e2m1clk-gate", -1, + SCU0_CLK_STOP, 19, CLK_IS_CRITICAL), + GATE_CLK(SCU0_CLK_GATE_CRT0CLK, CLK_GATE_ASPEED, "crt0clk-gate", -1, + SCU0_CLK_STOP, 20, 0), + GATE_CLK(SCU0_CLK_GATE_CRT1CLK, CLK_GATE_ASPEED, "crt1clk-gate", -1, + SCU0_CLK_STOP, 21, 0), + GATE_CLK(SCU0_CLK_GATE_ECDSACLK, CLK_GATE_ASPEED, "eccclk-gate", -1, + SCU0_CLK_STOP, 23, 0), + GATE_CLK(SCU0_CLK_GATE_RSACLK, CLK_GATE_ASPEED, "rsaclk-gate", -1, + SCU0_CLK_STOP, 24, 0), + GATE_CLK(SCU0_CLK_GATE_RVAS0CLK, CLK_GATE_ASPEED, "rvas0clk-gate", -1, + SCU0_CLK_STOP, 25, 0), + GATE_CLK(SCU0_CLK_GATE_UFSCLK, CLK_GATE_ASPEED, "ufsclk-gate", -1, + SCU0_CLK_STOP, 26, 0), + GATE_CLK(SCU0_CLK_GATE_EMMCCLK, CLK_GATE_ASPEED, "emmcclk-gate", SCU0_CLK_EMMC, + SCU0_CLK_STOP, 27, 0), + GATE_CLK(SCU0_CLK_GATE_RVAS1CLK, CLK_GATE_ASPEED, "rvas1clk-gate", -1, + SCU0_CLK_STOP, 28, 0), +}; + +static const struct ast2700_clk_info ast2700_scu1_clk_info[] __initconst = { + FIXED_CLK(SCU1_CLKIN, "soc1-clkin", 25 * HZ_PER_MHZ), + PLL_CLK(SCU1_CLK_HPLL, CLK_PLL, "soc1-hpll", SCU1_CLKIN, SCU1_HPLL_PARAM), + PLL_CLK(SCU1_CLK_APLL, CLK_PLL, "soc1-apll", SCU1_CLKIN, SCU1_APLL_PARAM), + PLL_CLK(SCU1_CLK_DPLL, CLK_PLL, "soc1-dpll", SCU1_CLKIN, SCU1_DPLL_PARAM), + FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV2, "soc1-apll_div2", SCU1_CLK_APLL, 1, 2), + FIXED_FACTOR_CLK(SCU1_CLK_APLL_DIV4, "soc1-apll_div4", SCU1_CLK_APLL, 1, 4), + FIXED_FACTOR_CLK(SCU1_CLK_CAN, "canclk", SCU1_CLK_APLL, 1, 10), + DIVIDER_CLK(SCU1_CLK_APB, "soc1-apb", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 18, 3, ast2700_clk_div_table2), + DIVIDER_CLK(SCU1_CLK_RMII, "rmii", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 21, 3, ast2700_rmii_div_table), + DIVIDER_CLK(SCU1_CLK_RGMII, "rgmii", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 25, 3, ast2700_rgmii_div_table), + DIVIDER_CLK(SCU1_CLK_MACHCLK, "machclk", SCU1_CLK_HPLL, + SCU1_CLK_SEL1, 29, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_APLL_DIVN, "soc1-apll_divn", + SCU1_CLK_APLL, SCU1_CLK_SEL2, 8, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_AHB, "soc1-ahb", SCU1_CLK_HPLL, + SCU1_CLK_SEL2, 20, 3, ast2700_clk_div_table), + DIVIDER_CLK(SCU1_CLK_I3C, "soc1-i3c", SCU1_CLK_HPLL, + SCU1_CLK_SEL2, 23, 3, ast2700_clk_div_table), + MUX_CLK(SCU1_CLK_SDMUX, "sdclk-mux", sdclk_parent_ids, ARRAY_SIZE(sdclk_parent_ids), + sdclk_parent_hws, SCU1_CLK_SEL1, 13, 1), + MUX_CLK(SCU1_CLK_UXCLK, "uxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids), + uxclk_parent_hws, SCU1_CLK_SEL2, 0, 2), + MUX_CLK(SCU1_CLK_HUXCLK, "huxclk", uxclk_parent_ids, ARRAY_SIZE(uxclk_parent_ids), + uxclk_parent_hws, SCU1_CLK_SEL2, 3, 2), + DIVIDER_CLK(SCU1_CLK_SDCLK, "sdclk", SCU1_CLK_SDMUX, + SCU1_CLK_SEL1, 14, 3, ast2700_clk_div_table), + PLL_CLK(SCU1_CLK_UARTX, CLK_UART_PLL, "uartxclk", SCU1_CLK_UXCLK, SCU1_UXCLK_CTRL), + PLL_CLK(SCU1_CLK_HUARTX, CLK_UART_PLL, "huartxclk", SCU1_CLK_HUXCLK, SCU1_HUXCLK_CTRL), + MUX_CLK(SCU1_CLK_UART0, "uart0clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 0, 1), + MUX_CLK(SCU1_CLK_UART1, "uart1clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 1, 1), + MUX_CLK(SCU1_CLK_UART2, "uart2clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 2, 1), + MUX_CLK(SCU1_CLK_UART3, "uart3clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 3, 1), + MUX_CLK(SCU1_CLK_UART5, "uart5clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 5, 1), + MUX_CLK(SCU1_CLK_UART6, "uart6clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 6, 1), + MUX_CLK(SCU1_CLK_UART7, "uart7clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 7, 1), + MUX_CLK(SCU1_CLK_UART8, "uart8clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 8, 1), + MUX_CLK(SCU1_CLK_UART9, "uart9clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 9, 1), + MUX_CLK(SCU1_CLK_UART10, "uart10clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 10, 1), + MUX_CLK(SCU1_CLK_UART11, "uart11clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 11, 1), + MUX_CLK(SCU1_CLK_UART12, "uart12clk", uartx_parent_ids, ARRAY_SIZE(uartx_parent_ids), + uartx_parent_hws, SCU1_CLK_SEL1, 12, 1), + FIXED_FACTOR_CLK(SCU1_CLK_UART13, "uart13clk", SCU1_CLK_HUARTX, 1, 1), + FIXED_FACTOR_CLK(SCU1_CLK_UART14, "uart14clk", SCU1_CLK_HUARTX, 1, 1), + GATE_CLK(SCU1_CLK_MAC0RCLK, CLK_GATE, "mac0rclk-gate", SCU1_CLK_RMII, + SCU1_MAC12_CLK_DLY, 29, 0), + GATE_CLK(SCU1_CLK_MAC1RCLK, CLK_GATE, "mac1rclk-gate", SCU1_CLK_RMII, + SCU1_MAC12_CLK_DLY, 30, 0), + GATE_CLK(SCU1_CLK_GATE_LCLK0, CLK_GATE_ASPEED, "lclk0-gate", -1, + SCU1_CLK_STOP, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_LCLK1, CLK_GATE_ASPEED, "lclk1-gate", -1, + SCU1_CLK_STOP, 1, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_ESPI0CLK, CLK_GATE_ASPEED, "espi0clk-gate", -1, + SCU1_CLK_STOP, 2, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_ESPI1CLK, CLK_GATE_ASPEED, "espi1clk-gate", -1, + SCU1_CLK_STOP, 3, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_SDCLK, CLK_GATE_ASPEED, "sdclk-gate", SCU1_CLK_SDCLK, + SCU1_CLK_STOP, 4, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_IPEREFCLK, CLK_GATE_ASPEED, "soc1-iperefclk-gate", -1, + SCU1_CLK_STOP, 5, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_REFCLK, CLK_GATE_ASPEED, "soc1-refclk-gate", -1, + SCU1_CLK_STOP, 6, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_LPCHCLK, CLK_GATE_ASPEED, "lpchclk-gate", -1, + SCU1_CLK_STOP, 7, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_MAC0CLK, CLK_GATE_ASPEED, "mac0clk-gate", -1, + SCU1_CLK_STOP, 8, 0), + GATE_CLK(SCU1_CLK_GATE_MAC1CLK, CLK_GATE_ASPEED, "mac1clk-gate", -1, + SCU1_CLK_STOP, 9, 0), + GATE_CLK(SCU1_CLK_GATE_MAC2CLK, CLK_GATE_ASPEED, "mac2clk-gate", -1, + SCU1_CLK_STOP, 10, 0), + GATE_CLK(SCU1_CLK_GATE_UART0CLK, CLK_GATE_ASPEED, "uart0clk-gate", SCU1_CLK_UART0, + SCU1_CLK_STOP, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART1CLK, CLK_GATE_ASPEED, "uart1clk-gate", SCU1_CLK_UART1, + SCU1_CLK_STOP, 12, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART2CLK, CLK_GATE_ASPEED, "uart2clk-gate", SCU1_CLK_UART2, + SCU1_CLK_STOP, 13, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART3CLK, CLK_GATE_ASPEED, "uart3clk-gate", SCU1_CLK_UART3, + SCU1_CLK_STOP, 14, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_I2CCLK, CLK_GATE_ASPEED, "i2cclk-gate", -1, SCU1_CLK_STOP, 15, 0), + GATE_CLK(SCU1_CLK_GATE_I3C0CLK, CLK_GATE_ASPEED, "i3c0clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 16, 0), + GATE_CLK(SCU1_CLK_GATE_I3C1CLK, CLK_GATE_ASPEED, "i3c1clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 17, 0), + GATE_CLK(SCU1_CLK_GATE_I3C2CLK, CLK_GATE_ASPEED, "i3c2clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 18, 0), + GATE_CLK(SCU1_CLK_GATE_I3C3CLK, CLK_GATE_ASPEED, "i3c3clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 19, 0), + GATE_CLK(SCU1_CLK_GATE_I3C4CLK, CLK_GATE_ASPEED, "i3c4clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 20, 0), + GATE_CLK(SCU1_CLK_GATE_I3C5CLK, CLK_GATE_ASPEED, "i3c5clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 21, 0), + GATE_CLK(SCU1_CLK_GATE_I3C6CLK, CLK_GATE_ASPEED, "i3c6clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 22, 0), + GATE_CLK(SCU1_CLK_GATE_I3C7CLK, CLK_GATE_ASPEED, "i3c7clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 23, 0), + GATE_CLK(SCU1_CLK_GATE_I3C8CLK, CLK_GATE_ASPEED, "i3c8clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 24, 0), + GATE_CLK(SCU1_CLK_GATE_I3C9CLK, CLK_GATE_ASPEED, "i3c9clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 25, 0), + GATE_CLK(SCU1_CLK_GATE_I3C10CLK, CLK_GATE_ASPEED, "i3c10clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 26, 0), + GATE_CLK(SCU1_CLK_GATE_I3C11CLK, CLK_GATE_ASPEED, "i3c11clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 27, 0), + GATE_CLK(SCU1_CLK_GATE_I3C12CLK, CLK_GATE_ASPEED, "i3c12clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 28, 0), + GATE_CLK(SCU1_CLK_GATE_I3C13CLK, CLK_GATE_ASPEED, "i3c13clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 29, 0), + GATE_CLK(SCU1_CLK_GATE_I3C14CLK, CLK_GATE_ASPEED, "i3c14clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 30, 0), + GATE_CLK(SCU1_CLK_GATE_I3C15CLK, CLK_GATE_ASPEED, "i3c15clk-gate", SCU1_CLK_I3C, + SCU1_CLK_STOP, 31, 0), + GATE_CLK(SCU1_CLK_GATE_UART5CLK, CLK_GATE_ASPEED, "uart5clk-gate", SCU1_CLK_UART5, + SCU1_CLK_STOP2, 0, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART6CLK, CLK_GATE_ASPEED, "uart6clk-gate", SCU1_CLK_UART6, + SCU1_CLK_STOP2, 1, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART7CLK, CLK_GATE_ASPEED, "uart7clk-gate", SCU1_CLK_UART7, + SCU1_CLK_STOP2, 2, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART8CLK, CLK_GATE_ASPEED, "uart8clk-gate", SCU1_CLK_UART8, + SCU1_CLK_STOP2, 3, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UART9CLK, CLK_GATE_ASPEED, "uart9clk-gate", SCU1_CLK_UART9, + SCU1_CLK_STOP2, 4, 0), + GATE_CLK(SCU1_CLK_GATE_UART10CLK, CLK_GATE_ASPEED, "uart10clk-gate", SCU1_CLK_UART10, + SCU1_CLK_STOP2, 5, 0), + GATE_CLK(SCU1_CLK_GATE_UART11CLK, CLK_GATE_ASPEED, "uart11clk-gate", SCU1_CLK_UART11, + SCU1_CLK_STOP2, 6, 0), + GATE_CLK(SCU1_CLK_GATE_UART12CLK, CLK_GATE_ASPEED, "uart12clk-gate", SCU1_CLK_UART12, + SCU1_CLK_STOP2, 7, 0), + GATE_CLK(SCU1_CLK_GATE_FSICLK, CLK_GATE_ASPEED, "fsiclk-gate", -1, SCU1_CLK_STOP2, 8, 0), + GATE_CLK(SCU1_CLK_GATE_LTPIPHYCLK, CLK_GATE_ASPEED, "ltpiphyclk-gate", -1, + SCU1_CLK_STOP2, 9, 0), + GATE_CLK(SCU1_CLK_GATE_LTPICLK, CLK_GATE_ASPEED, "ltpiclk-gate", -1, + SCU1_CLK_STOP2, 10, 0), + GATE_CLK(SCU1_CLK_GATE_VGALCLK, CLK_GATE_ASPEED, "vgalclk-gate", -1, + SCU1_CLK_STOP2, 11, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_UHCICLK, CLK_GATE_ASPEED, "usbuartclk-gate", -1, + SCU1_CLK_STOP2, 12, 0), + GATE_CLK(SCU1_CLK_GATE_CANCLK, CLK_GATE_ASPEED, "canclk-gate", SCU1_CLK_CAN, + SCU1_CLK_STOP2, 13, 0), + GATE_CLK(SCU1_CLK_GATE_PCICLK, CLK_GATE_ASPEED, "pciclk-gate", -1, + SCU1_CLK_STOP2, 14, 0), + GATE_CLK(SCU1_CLK_GATE_SLICLK, CLK_GATE_ASPEED, "soc1-sliclk-gate", -1, + SCU1_CLK_STOP2, 15, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_E2MCLK, CLK_GATE_ASPEED, "soc1-e2m-gate", -1, + SCU1_CLK_STOP2, 16, CLK_IS_CRITICAL), + GATE_CLK(SCU1_CLK_GATE_PORTCUSB2CLK, CLK_GATE_ASPEED, "portcusb2-gate", -1, + SCU1_CLK_STOP2, 17, 0), + GATE_CLK(SCU1_CLK_GATE_PORTDUSB2CLK, CLK_GATE_ASPEED, "portdusb2-gate", -1, + SCU1_CLK_STOP2, 18, 0), + GATE_CLK(SCU1_CLK_GATE_LTPI1TXCLK, CLK_GATE_ASPEED, "ltp1tx-gate", -1, + SCU1_CLK_STOP2, 19, 0), +}; + +static struct clk_hw *ast2700_clk_hw_register_fixed_display(void __iomem *reg, const char *name, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div, r, n; + u32 xdclk; + u32 val; + + val = readl(clk_ctrl->base + SCU0_CLK_SEL2); + if (val & BIT(29)) + xdclk = 800 * HZ_PER_MHZ; + else + xdclk = 1000 * HZ_PER_MHZ; + + val = readl(reg); + r = val & GENMASK(15, 0); + n = (val >> 16) & GENMASK(15, 0); + mult = r; + div = 2 * n; + + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, 0, (xdclk * mult) / div); +} + +static struct clk_hw *ast2700_clk_hw_register_hpll(void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div; + u32 val; + + val = readl(clk_ctrl->base + SCU0_HWSTRAP1); + if ((readl(clk_ctrl->base) & REVISION_ID) && (val & BIT(3))) { + switch ((val & GENMASK(4, 2)) >> 2) { + case 2: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1800 * HZ_PER_MHZ); + case 3: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1700 * HZ_PER_MHZ); + case 6: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1200 * HZ_PER_MHZ); + case 7: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 800 * HZ_PER_MHZ); + default: + return ERR_PTR(-EINVAL); + } + } else if ((val & GENMASK(3, 2)) != 0) { + switch ((val & GENMASK(3, 2)) >> 2) { + case 1: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1900 * HZ_PER_MHZ); + case 2: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1800 * HZ_PER_MHZ); + case 3: + return devm_clk_hw_register_fixed_rate(clk_ctrl->dev, name, NULL, + 0, 1700 * HZ_PER_MHZ); + default: + return ERR_PTR(-EINVAL); + } + } else { + val = readl(reg); + + if (val & BIT(24)) { + /* Pass through mode */ + mult = 1; + div = 1; + } else { + u32 m = val & 0x1fff; + u32 n = (val >> 13) & 0x3f; + u32 p = (val >> 19) & 0xf; + + mult = (m + 1) / (2 * (n + 1)); + div = p + 1; + } + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_pll(int clk_idx, void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + int scu = clk_ctrl->clk_data->scu; + unsigned int mult, div; + u32 val = readl(reg); + + if (val & BIT(24)) { + /* Pass through mode */ + mult = 1; + div = 1; + } else { + u32 m = val & 0x1fff; + u32 n = (val >> 13) & 0x3f; + u32 p = (val >> 19) & 0xf; + + if (scu) { + mult = (m + 1) / (n + 1); + div = p + 1; + } else { + if (clk_idx == SCU0_CLK_MPLL) { + mult = m / (n + 1); + div = p + 1; + } else { + mult = (m + 1) / (2 * (n + 1)); + div = p + 1; + } + } + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_uartpll(void __iomem *reg, const char *name, + const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + unsigned int mult, div; + u32 val = readl(reg); + u32 r = val & 0xff; + u32 n = (val >> 8) & 0x3ff; + + mult = r; + div = n * 2; + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, mult, div); +} + +static struct clk_hw *ast2700_clk_hw_register_misc(int clk_idx, void __iomem *reg, + const char *name, const struct clk_hw *parent_hw, + struct ast2700_clk_ctrl *clk_ctrl) +{ + u32 div = 0; + + if (clk_idx == SCU0_CLK_MPHY) { + div = readl(reg) + 1; + } else if (clk_idx == SCU0_CLK_U2PHY_REFCLK) { + if (readl(clk_ctrl->base) & REVISION_ID) + div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 4; + else + div = (GET_USB_REFCLK_DIV(readl(reg)) + 1) << 1; + } else { + return ERR_PTR(-EINVAL); + } + + return devm_clk_hw_register_fixed_factor_parent_hw(clk_ctrl->dev, name, + parent_hw, 0, 1, div); +} + +static int ast2700_clk_is_enabled(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + u32 reg; + + reg = readl(gate->reg); + + return !(reg & clk); +} + +static int ast2700_clk_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + + if (readl(gate->reg) & clk) + writel(clk, gate->reg + 0x04); + + return 0; +} + +static void ast2700_clk_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + u32 clk = BIT(gate->bit_idx); + + /* Clock is set to enable, so use write to set register */ + writel(clk, gate->reg); +} + +static const struct clk_ops ast2700_clk_gate_ops = { + .enable = ast2700_clk_enable, + .disable = ast2700_clk_disable, + .is_enabled = ast2700_clk_is_enabled, +}; + +static struct clk_hw *ast2700_clk_hw_register_gate(struct device *dev, const char *name, + const struct clk_hw *parent_hw, + void __iomem *reg, u8 clock_idx, + unsigned long flags, spinlock_t *lock) +{ + struct clk_init_data init; + struct clk_gate *gate; + struct clk_hw *hw; + int ret = -EINVAL; + + gate = kzalloc_obj(*gate); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &ast2700_clk_gate_ops; + init.flags = flags; + init.parent_names = NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = NULL; + init.num_parents = parent_hw ? 1 : 0; + + gate->reg = reg; + gate->bit_idx = clock_idx; + gate->flags = 0; + gate->lock = lock; + gate->hw.init = &init; + + hw = &gate->hw; + ret = clk_hw_register(dev, hw); + if (ret) { + kfree(gate); + hw = ERR_PTR(ret); + } + + return hw; +} + +static void ast2700_soc1_configure_i3c_clk(struct ast2700_clk_ctrl *clk_ctrl) +{ + if (readl(clk_ctrl->base) & REVISION_ID) { + u32 val; + + /* I3C 250MHz = HPLL/4 */ + val = readl(clk_ctrl->base + SCU1_CLK_SEL2) & ~SCU1_CLK_I3C_DIV_MASK; + val |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4)); + writel(val, clk_ctrl->base + SCU1_CLK_SEL2); + } +} + +static inline const struct clk_hw *get_parent_hw_or_null(struct clk_hw **hws, int idx) +{ + if (idx < 0) + return NULL; + else + return hws[idx]; +} + +static int ast2700_soc_clk_probe(struct platform_device *pdev) +{ + const struct ast2700_clk_data *clk_data; + struct clk_hw_onecell_data *clk_hw_data; + struct ast2700_clk_ctrl *clk_ctrl; + struct device *dev = &pdev->dev; + struct auxiliary_device *adev; + void __iomem *clk_base; + struct clk_hw **hws; + char *reset_name; + int ret; + int i; + + clk_ctrl = devm_kzalloc(dev, sizeof(*clk_ctrl), GFP_KERNEL); + if (!clk_ctrl) + return -ENOMEM; + clk_ctrl->dev = dev; + dev_set_drvdata(&pdev->dev, clk_ctrl); + + spin_lock_init(&clk_ctrl->lock); + + clk_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(clk_base)) + return PTR_ERR(clk_base); + + clk_ctrl->base = clk_base; + + clk_data = device_get_match_data(dev); + if (!clk_data) + return -ENODEV; + + clk_ctrl->clk_data = clk_data; + reset_name = devm_kasprintf(dev, GFP_KERNEL, "reset%d", clk_data->scu); + + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, clk_data->nr_clks), + GFP_KERNEL); + if (!clk_hw_data) + return -ENOMEM; + + clk_hw_data->num = clk_data->nr_clks; + hws = clk_hw_data->hws; + + if (clk_data->scu) + ast2700_soc1_configure_i3c_clk(clk_ctrl); + + for (i = 0; i < clk_data->nr_clks; i++) { + const struct ast2700_clk_info *clk = &clk_data->clk_info[i]; + const struct clk_hw *phw = NULL; + unsigned int id = clk->id; + void __iomem *reg = NULL; + + if (id >= clk_hw_data->num || hws[id]) { + dev_err(dev, "clk id %u invalid for %s\n", id, clk->name); + return -EINVAL; + } + + if (clk->type == CLK_FIXED) { + const struct ast2700_clk_fixed_rate_data *fixed_rate = &clk->data.rate; + + hws[id] = devm_clk_hw_register_fixed_rate(dev, clk->name, NULL, 0, + fixed_rate->fixed_rate); + } else if (clk->type == CLK_FIXED_FACTOR) { + const struct ast2700_clk_fixed_factor_data *factor = &clk->data.factor; + + phw = hws[factor->parent_id]; + hws[id] = devm_clk_hw_register_fixed_factor_parent_hw(dev, clk->name, + phw, 0, factor->mult, + factor->div); + } else if (clk->type == CLK_FIXED_DISPLAY) { + reg = clk_ctrl->base + clk->data.display_rate.reg; + + hws[id] = ast2700_clk_hw_register_fixed_display(reg, clk->name, clk_ctrl); + } else if (clk->type == CLK_HPLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_hpll(reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_PLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_pll(id, reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_UART_PLL) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_uartpll(reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_MUX) { + const struct ast2700_clk_mux_data *mux = &clk->data.mux; + + reg = clk_ctrl->base + mux->reg; + for (int j = 0; j < mux->num_parents; j++) { + unsigned int pid = mux->parent_ids[j]; + + mux->parent_hws[j] = hws[pid]; + } + + hws[id] = devm_clk_hw_register_mux_parent_hws(dev, clk->name, + mux->parent_hws, + mux->num_parents, 0, + reg, mux->bit_shift, + mux->bit_width, 0, + &clk_ctrl->lock); + } else if (clk->type == CLK_MISC) { + const struct ast2700_clk_pll_data *pll = &clk->data.pll; + + reg = clk_ctrl->base + pll->reg; + phw = hws[pll->parent_id]; + hws[id] = ast2700_clk_hw_register_misc(id, reg, clk->name, phw, clk_ctrl); + } else if (clk->type == CLK_DIVIDER) { + const struct ast2700_clk_div_data *divider = &clk->data.div; + + reg = clk_ctrl->base + divider->reg; + phw = hws[divider->parent_id]; + hws[id] = clk_hw_register_divider_table_parent_hw(dev, clk->name, + phw, + 0, reg, + divider->bit_shift, + divider->bit_width, 0, + divider->div_table, + &clk_ctrl->lock); + } else if (clk->type == CLK_GATE_ASPEED) { + const struct ast2700_clk_gate_data *gate = &clk->data.gate; + + phw = get_parent_hw_or_null(hws, gate->parent_id); + reg = clk_ctrl->base + gate->reg; + hws[id] = ast2700_clk_hw_register_gate(dev, clk->name, phw, reg, gate->bit, + gate->flags, &clk_ctrl->lock); + } else { + const struct ast2700_clk_gate_data *gate = &clk->data.gate; + + phw = get_parent_hw_or_null(hws, gate->parent_id); + reg = clk_ctrl->base + gate->reg; + hws[id] = devm_clk_hw_register_gate_parent_hw(dev, clk->name, phw, + gate->flags, reg, gate->bit, + 0, &clk_ctrl->lock); + } + + if (IS_ERR(hws[id])) + return PTR_ERR(hws[id]); + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data); + if (ret) + return ret; + + adev = devm_auxiliary_device_create(dev, reset_name, (__force void *)clk_base); + if (!adev) + return -ENODEV; + + return 0; +} + +static const struct ast2700_clk_data ast2700_clk0_data = { + .scu = 0, + .nr_clks = ARRAY_SIZE(ast2700_scu0_clk_info), + .clk_info = ast2700_scu0_clk_info, +}; + +static const struct ast2700_clk_data ast2700_clk1_data = { + .scu = 1, + .nr_clks = ARRAY_SIZE(ast2700_scu1_clk_info), + .clk_info = ast2700_scu1_clk_info, +}; + +static const struct of_device_id ast2700_scu_match[] = { + { .compatible = "aspeed,ast2700-scu0", .data = &ast2700_clk0_data }, + { .compatible = "aspeed,ast2700-scu1", .data = &ast2700_clk1_data }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, ast2700_scu_match); + +static struct platform_driver ast2700_scu_driver = { + .probe = ast2700_soc_clk_probe, + .driver = { + .name = "clk-ast2700", + .of_match_table = ast2700_scu_match, + }, +}; + +module_platform_driver(ast2700_scu_driver); diff --git a/drivers/clk/at91/clk-audio-pll.c b/drivers/clk/at91/clk-audio-pll.c index bf9b635ac9d6..732037bfbda8 100644 --- a/drivers/clk/at91/clk-audio-pll.c +++ b/drivers/clk/at91/clk-audio-pll.c @@ -460,7 +460,7 @@ at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name, struct clk_init_data init = {}; int ret; - frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL); + frac_ck = kzalloc_obj(*frac_ck); if (!frac_ck) return ERR_PTR(-ENOMEM); @@ -490,7 +490,7 @@ at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL); + apad_ck = kzalloc_obj(*apad_ck); if (!apad_ck) return ERR_PTR(-ENOMEM); @@ -521,7 +521,7 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL); + apmc_ck = kzalloc_obj(*apmc_ck); if (!apmc_ck) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 4b4edeecc889..5d3a62433187 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -332,7 +332,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, if (!(parent_names || parent_hws)) return ERR_PTR(-ENOMEM); - gck = kzalloc(sizeof(*gck), GFP_KERNEL); + gck = kzalloc_obj(*gck); if (!gck) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c index a9aa93b5a870..12bd112d3c50 100644 --- a/drivers/clk/at91/clk-h32mx.c +++ b/drivers/clk/at91/clk-h32mx.c @@ -100,7 +100,7 @@ at91_clk_register_h32mx(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL); + h32mxclk = kzalloc_obj(*h32mxclk); if (!h32mxclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-i2s-mux.c b/drivers/clk/at91/clk-i2s-mux.c index fe6ce172b8b0..a762c56dcadd 100644 --- a/drivers/clk/at91/clk-i2s-mux.c +++ b/drivers/clk/at91/clk-i2s-mux.c @@ -57,7 +57,7 @@ at91_clk_i2s_mux_register(struct regmap *regmap, const char *name, struct clk_i2s_mux *i2s_ck; int ret; - i2s_ck = kzalloc(sizeof(*i2s_ck), GFP_KERNEL); + i2s_ck = kzalloc_obj(*i2s_ck); if (!i2s_ck) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index 9b462becc693..ab515239adcf 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -163,7 +163,7 @@ at91_clk_register_main_osc(struct regmap *regmap, if (!name || !(parent_name || parent_data)) return ERR_PTR(-EINVAL); - osc = kzalloc(sizeof(*osc), GFP_KERNEL); + osc = kzalloc_obj(*osc); if (!osc) return ERR_PTR(-ENOMEM); @@ -306,7 +306,7 @@ at91_clk_register_main_rc_osc(struct regmap *regmap, if (!name || !frequency) return ERR_PTR(-EINVAL); - osc = kzalloc(sizeof(*osc), GFP_KERNEL); + osc = kzalloc_obj(*osc); if (!osc) return ERR_PTR(-ENOMEM); @@ -415,7 +415,7 @@ at91_clk_register_rm9200_main(struct regmap *regmap, if (!(parent_name || parent_hw)) return ERR_PTR(-EINVAL); - clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); + clkmain = kzalloc_obj(*clkmain); if (!clkmain) return ERR_PTR(-ENOMEM); @@ -567,7 +567,7 @@ at91_clk_register_sam9x5_main(struct regmap *regmap, if (!(parent_hws || parent_names) || !num_parents) return ERR_PTR(-EINVAL); - clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); + clkmain = kzalloc_obj(*clkmain); if (!clkmain) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index d5ea2069ec83..05001e7700ca 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -488,7 +488,7 @@ at91_clk_register_master_internal(struct regmap *regmap, if (!name || !num_parents || !(parent_names || parent_hws) || !lock) return ERR_PTR(-EINVAL); - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return ERR_PTR(-ENOMEM); @@ -831,7 +831,7 @@ at91_clk_sama7g5_register_master(struct regmap *regmap, !lock || id > MASTER_MAX_ID) return ERR_PTR(-EINVAL); - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index e7208c47268b..4946ea0cdbba 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -109,7 +109,7 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name, if (!name || !(parent_name || parent_hw) || id > PERIPHERAL_ID_MAX) return ERR_PTR(-EINVAL); - periph = kzalloc(sizeof(*periph), GFP_KERNEL); + periph = kzalloc_obj(*periph); if (!periph) return ERR_PTR(-ENOMEM); @@ -471,7 +471,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, if (!name || !(parent_name || parent_hw)) return ERR_PTR(-EINVAL); - periph = kzalloc(sizeof(*periph), GFP_KERNEL); + periph = kzalloc_obj(*periph); if (!periph) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c index 5c5f7398effe..b89f60cf0241 100644 --- a/drivers/clk/at91/clk-pll.c +++ b/drivers/clk/at91/clk-pll.c @@ -326,7 +326,7 @@ at91_clk_register_pll(struct regmap *regmap, const char *name, if (id > PLL_MAX_ID) return ERR_PTR(-EINVAL); - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-plldiv.c b/drivers/clk/at91/clk-plldiv.c index 3ac09fecc54e..5f93aead03fa 100644 --- a/drivers/clk/at91/clk-plldiv.c +++ b/drivers/clk/at91/clk-plldiv.c @@ -91,7 +91,7 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - plldiv = kzalloc(sizeof(*plldiv), GFP_KERNEL); + plldiv = kzalloc_obj(*plldiv); if (!plldiv) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c index 1195fb405503..bfd8b03b035c 100644 --- a/drivers/clk/at91/clk-programmable.c +++ b/drivers/clk/at91/clk-programmable.c @@ -227,7 +227,7 @@ at91_clk_register_programmable(struct regmap *regmap, if (id > PROG_ID_MAX || !(parent_names || parent_hws)) return ERR_PTR(-EINVAL); - prog = kzalloc(sizeof(*prog), GFP_KERNEL); + prog = kzalloc_obj(*prog); if (!prog) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c index 3b965057ba0d..9d9b5adecf0d 100644 --- a/drivers/clk/at91/clk-sam9x60-pll.c +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -652,7 +652,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, if (id > PLL_MAX_ID || !lock || !parent_hw) return ERR_PTR(-EINVAL); - frac = kzalloc(sizeof(*frac), GFP_KERNEL); + frac = kzalloc_obj(*frac); if (!frac) return ERR_PTR(-ENOMEM); @@ -744,7 +744,7 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, if (safe_div >= PLL_DIV_MAX) safe_div = PLL_DIV_MAX - 1; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c index ac9f7a48b76e..f0cad50e490b 100644 --- a/drivers/clk/at91/clk-slow.c +++ b/drivers/clk/at91/clk-slow.c @@ -52,7 +52,7 @@ at91_clk_register_sam9260_slow(struct regmap *regmap, if (!parent_names || !num_parents) return ERR_PTR(-EINVAL); - slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); + slowck = kzalloc_obj(*slowck); if (!slowck) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-smd.c b/drivers/clk/at91/clk-smd.c index 09c649c8598e..77f2b8fe6cab 100644 --- a/drivers/clk/at91/clk-smd.c +++ b/drivers/clk/at91/clk-smd.c @@ -118,7 +118,7 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - smd = kzalloc(sizeof(*smd), GFP_KERNEL); + smd = kzalloc_obj(*smd); if (!smd) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c index 90eed39d0785..93e1e8cebce8 100644 --- a/drivers/clk/at91/clk-system.c +++ b/drivers/clk/at91/clk-system.c @@ -116,7 +116,7 @@ at91_clk_register_system(struct regmap *regmap, const char *name, if (!(parent_name || parent_hw) || id > SYSTEM_MAX_ID) return ERR_PTR(-EINVAL); - sys = kzalloc(sizeof(*sys), GFP_KERNEL); + sys = kzalloc_obj(*sys); if (!sys) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index e906928cfbf0..b4dc86193e09 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -229,7 +229,7 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - usb = kzalloc(sizeof(*usb), GFP_KERNEL); + usb = kzalloc_obj(*usb); if (!usb) return ERR_PTR(-ENOMEM); @@ -280,7 +280,7 @@ at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - usb = kzalloc(sizeof(*usb), GFP_KERNEL); + usb = kzalloc_obj(*usb); if (!usb) return ERR_PTR(-ENOMEM); @@ -399,7 +399,7 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, struct clk_init_data init; int ret; - usb = kzalloc(sizeof(*usb), GFP_KERNEL); + usb = kzalloc_obj(*usb); if (!usb) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c index b991180beea1..40b335b0195c 100644 --- a/drivers/clk/at91/clk-utmi.c +++ b/drivers/clk/at91/clk-utmi.c @@ -155,7 +155,7 @@ at91_clk_register_utmi_internal(struct regmap *regmap_pmc, if (!(parent_name || parent_hw)) return ERR_PTR(-EINVAL); - utmi = kzalloc(sizeof(*utmi), GFP_KERNEL); + utmi = kzalloc_obj(*utmi); if (!utmi) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c index f5a5f9ba7634..5d543e807843 100644 --- a/drivers/clk/at91/dt-compat.c +++ b/drivers/clk/at91/dt-compat.c @@ -369,7 +369,7 @@ of_at91_clk_master_get_characteristics(struct device_node *np) { struct clk_master_characteristics *characteristics; - characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); + characteristics = kzalloc_obj(*characteristics); if (!characteristics) return NULL; @@ -568,11 +568,11 @@ of_at91_clk_pll_get_characteristics(struct device_node *np) return NULL; num_output /= num_cells; - characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL); + characteristics = kzalloc_obj(*characteristics); if (!characteristics) return NULL; - output = kcalloc(num_output, sizeof(*output), GFP_KERNEL); + output = kzalloc_objs(*output, num_output); if (!output) goto out_free_characteristics; diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 2310f6f73162..b618a5e00b00 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -87,8 +87,7 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, unsigned int num_clks = ncore + nsystem + nperiph + ngck + npck; struct pmc_data *pmc_data; - pmc_data = kzalloc(struct_size(pmc_data, hwtable, num_clks), - GFP_KERNEL); + pmc_data = kzalloc_flex(*pmc_data, hwtable, num_clks); if (!pmc_data) return NULL; diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c index 021d1b412af4..776118f14867 100644 --- a/drivers/clk/at91/sckc.c +++ b/drivers/clk/at91/sckc.c @@ -132,7 +132,7 @@ at91_clk_register_slow_osc(void __iomem *sckcr, if (!sckcr || !name || !parent_data) return ERR_PTR(-EINVAL); - osc = kzalloc(sizeof(*osc), GFP_KERNEL); + osc = kzalloc_obj(*osc); if (!osc) return ERR_PTR(-ENOMEM); @@ -239,7 +239,7 @@ at91_clk_register_slow_rc_osc(void __iomem *sckcr, if (!sckcr || !name) return ERR_PTR(-EINVAL); - osc = kzalloc(sizeof(*osc), GFP_KERNEL); + osc = kzalloc_obj(*osc); if (!osc) return ERR_PTR(-ENOMEM); @@ -332,7 +332,7 @@ at91_clk_register_sam9x5_slow(void __iomem *sckcr, if (!sckcr || !name || !parent_hws || !num_parents) return ERR_PTR(-EINVAL); - slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); + slowck = kzalloc_obj(*slowck); if (!slowck) return ERR_PTR(-ENOMEM); @@ -502,7 +502,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np) if (IS_ERR(slow_osc)) goto unregister_slow_rc; - clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, 2); if (!clk_data) goto unregister_slow_osc; @@ -611,7 +611,7 @@ static void __init of_sama5d4_sckc_setup(struct device_node *np) goto unregister_slow_rc; parent_data.fw_name = xtal_name; - osc = kzalloc(sizeof(*osc), GFP_KERNEL); + osc = kzalloc_obj(*osc); if (!osc) goto unregister_slow_rc; diff --git a/drivers/clk/axis/clk-artpec6.c b/drivers/clk/axis/clk-artpec6.c index a3f349d4624d..a6f1499629dd 100644 --- a/drivers/clk/axis/clk-artpec6.c +++ b/drivers/clk/axis/clk-artpec6.c @@ -49,7 +49,7 @@ static void of_artpec6_clkctrl_setup(struct device_node *np) sys_refclk_name = of_clk_get_parent_name(np, i); - clkdata = kzalloc(sizeof(*clkdata), GFP_KERNEL); + clkdata = kzalloc_obj(*clkdata); if (!clkdata) return; diff --git a/drivers/clk/axs10x/pll_clock.c b/drivers/clk/axs10x/pll_clock.c index c7ca473ee76c..5ab1c220c62d 100644 --- a/drivers/clk/axs10x/pll_clock.c +++ b/drivers/clk/axs10x/pll_clock.c @@ -265,7 +265,7 @@ static void __init of_axs10x_pll_clk_setup(struct device_node *node) struct clk_init_data init = { }; int ret; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (!pll_clk) return; diff --git a/drivers/clk/baikal-t1/ccu-div.c b/drivers/clk/baikal-t1/ccu-div.c index 849d1f55765f..cc48e580e159 100644 --- a/drivers/clk/baikal-t1/ccu-div.c +++ b/drivers/clk/baikal-t1/ccu-div.c @@ -447,7 +447,7 @@ static void ccu_div_var_debug_init(struct clk_hw *hw, struct dentry *dentry) num += !!(div->flags & CLK_SET_RATE_GATE) + !!(div->features & CCU_DIV_RESET_DOMAIN); - bits = kcalloc(num, sizeof(*bits), GFP_KERNEL); + bits = kzalloc_objs(*bits, num); if (!bits) return; @@ -489,7 +489,7 @@ static void ccu_div_gate_debug_init(struct clk_hw *hw, struct dentry *dentry) struct ccu_div *div = to_ccu_div(hw); struct ccu_div_dbgfs_bit *bit; - bit = kmalloc(sizeof(*bit), GFP_KERNEL); + bit = kmalloc_obj(*bit); if (!bit) return; @@ -507,7 +507,7 @@ static void ccu_div_buf_debug_init(struct clk_hw *hw, struct dentry *dentry) struct ccu_div *div = to_ccu_div(hw); struct ccu_div_dbgfs_bit *bit; - bit = kmalloc(sizeof(*bit), GFP_KERNEL); + bit = kmalloc_obj(*bit); if (!bit) return; @@ -585,7 +585,7 @@ struct ccu_div *ccu_div_hw_register(const struct ccu_div_init_data *div_init) if (!div_init) return ERR_PTR(-EINVAL); - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/baikal-t1/ccu-pll.c b/drivers/clk/baikal-t1/ccu-pll.c index 357269f41cdc..da7fbebb39ab 100644 --- a/drivers/clk/baikal-t1/ccu-pll.c +++ b/drivers/clk/baikal-t1/ccu-pll.c @@ -445,7 +445,7 @@ static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry) struct ccu_pll_dbgfs_fld *flds; int idx; - bits = kcalloc(CCU_PLL_DBGFS_BIT_NUM, sizeof(*bits), GFP_KERNEL); + bits = kzalloc_objs(*bits, CCU_PLL_DBGFS_BIT_NUM); if (!bits) return; @@ -458,7 +458,7 @@ static void ccu_pll_debug_init(struct clk_hw *hw, struct dentry *dentry) &ccu_pll_dbgfs_bit_fops); } - flds = kcalloc(CCU_PLL_DBGFS_FLD_NUM, sizeof(*flds), GFP_KERNEL); + flds = kzalloc_objs(*flds, CCU_PLL_DBGFS_FLD_NUM); if (!flds) return; @@ -508,7 +508,7 @@ struct ccu_pll *ccu_pll_hw_register(const struct ccu_pll_init_data *pll_init) if (!pll_init) return ERR_PTR(-EINVAL); - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/baikal-t1/ccu-rst.c b/drivers/clk/baikal-t1/ccu-rst.c index 40023ea67463..969e5de381a8 100644 --- a/drivers/clk/baikal-t1/ccu-rst.c +++ b/drivers/clk/baikal-t1/ccu-rst.c @@ -172,7 +172,7 @@ struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init) if (!rst_init) return ERR_PTR(-EINVAL); - rst = kzalloc(sizeof(*rst), GFP_KERNEL); + rst = kzalloc_obj(*rst); if (!rst) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/baikal-t1/clk-ccu-div.c b/drivers/clk/baikal-t1/clk-ccu-div.c index 17d75e8e2e8f..d32072e4dd49 100644 --- a/drivers/clk/baikal-t1/clk-ccu-div.c +++ b/drivers/clk/baikal-t1/clk-ccu-div.c @@ -271,7 +271,7 @@ static struct ccu_div_data *ccu_div_create_data(struct device_node *np) struct ccu_div_data *data; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); @@ -289,7 +289,7 @@ static struct ccu_div_data *ccu_div_create_data(struct device_node *np) goto err_kfree_data; } - data->divs = kcalloc(data->divs_num, sizeof(*data->divs), GFP_KERNEL); + data->divs = kzalloc_objs(*data->divs, data->divs_num); if (!data->divs) { ret = -ENOMEM; goto err_kfree_data; diff --git a/drivers/clk/baikal-t1/clk-ccu-pll.c b/drivers/clk/baikal-t1/clk-ccu-pll.c index 921b87024feb..e5e4a6ea6f78 100644 --- a/drivers/clk/baikal-t1/clk-ccu-pll.c +++ b/drivers/clk/baikal-t1/clk-ccu-pll.c @@ -100,7 +100,7 @@ static struct ccu_pll_data *ccu_pll_create_data(struct device_node *np) { struct ccu_pll_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 02215ea79403..118df86d717c 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -1357,7 +1357,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, init.ops = &bcm2835_pll_clk_ops; init.flags = pll_data->flags | CLK_IGNORE_UNUSED; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return NULL; diff --git a/drivers/clk/bcm/clk-bcm53573-ilp.c b/drivers/clk/bcm/clk-bcm53573-ilp.c index b2fc05b60783..fb4f3b756282 100644 --- a/drivers/clk/bcm/clk-bcm53573-ilp.c +++ b/drivers/clk/bcm/clk-bcm53573-ilp.c @@ -102,7 +102,7 @@ static void bcm53573_ilp_init(struct device_node *np) const char *parent_name; int err; - ilp = kzalloc(sizeof(*ilp), GFP_KERNEL); + ilp = kzalloc_obj(*ilp); if (!ilp) return; diff --git a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c index 9e86c0c10b57..8485428fe49c 100644 --- a/drivers/clk/bcm/clk-iproc-armpll.c +++ b/drivers/clk/bcm/clk-iproc-armpll.c @@ -238,7 +238,7 @@ void __init iproc_armpll_setup(struct device_node *node) struct clk_init_data init; const char *parent_name; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (WARN_ON(!pll)) return; diff --git a/drivers/clk/bcm/clk-iproc-asiu.c b/drivers/clk/bcm/clk-iproc-asiu.c index 83ec13da9b2e..819ab1b55df3 100644 --- a/drivers/clk/bcm/clk-iproc-asiu.c +++ b/drivers/clk/bcm/clk-iproc-asiu.c @@ -188,17 +188,16 @@ void __init iproc_asiu_setup(struct device_node *node, if (WARN_ON(!gate || !div)) return; - asiu = kzalloc(sizeof(*asiu), GFP_KERNEL); + asiu = kzalloc_obj(*asiu); if (WARN_ON(!asiu)) return; - asiu->clk_data = kzalloc(struct_size(asiu->clk_data, hws, num_clks), - GFP_KERNEL); + asiu->clk_data = kzalloc_flex(*asiu->clk_data, hws, num_clks); if (WARN_ON(!asiu->clk_data)) goto err_clks; asiu->clk_data->num = num_clks; - asiu->clks = kcalloc(num_clks, sizeof(*asiu->clks), GFP_KERNEL); + asiu->clks = kzalloc_objs(*asiu->clks, num_clks); if (WARN_ON(!asiu->clks)) goto err_asiu_clks; diff --git a/drivers/clk/bcm/clk-iproc-pll.c b/drivers/clk/bcm/clk-iproc-pll.c index 680f9d8d357c..d708f770971c 100644 --- a/drivers/clk/bcm/clk-iproc-pll.c +++ b/drivers/clk/bcm/clk-iproc-pll.c @@ -731,16 +731,16 @@ void iproc_pll_clk_setup(struct device_node *node, if (WARN_ON(!pll_ctrl) || WARN_ON(!clk_ctrl)) return; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (WARN_ON(!pll)) return; - clk_data = kzalloc(struct_size(clk_data, hws, num_clks), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, num_clks); if (WARN_ON(!clk_data)) goto err_clk_data; clk_data->num = num_clks; - iclk_array = kcalloc(num_clks, sizeof(struct iproc_clk), GFP_KERNEL); + iclk_array = kzalloc_objs(struct iproc_clk, num_clks); if (WARN_ON(!iclk_array)) goto err_clks; diff --git a/drivers/clk/berlin/berlin2-avpll.c b/drivers/clk/berlin/berlin2-avpll.c index 79f3d37a0ee0..c801d42397bf 100644 --- a/drivers/clk/berlin/berlin2-avpll.c +++ b/drivers/clk/berlin/berlin2-avpll.c @@ -184,7 +184,7 @@ int __init berlin2_avpll_vco_register(void __iomem *base, struct berlin2_avpll_vco *vco; struct clk_init_data init; - vco = kzalloc(sizeof(*vco), GFP_KERNEL); + vco = kzalloc_obj(*vco); if (!vco) return -ENOMEM; @@ -360,7 +360,7 @@ int __init berlin2_avpll_channel_register(void __iomem *base, struct berlin2_avpll_channel *ch; struct clk_init_data init; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) return -ENOMEM; diff --git a/drivers/clk/berlin/berlin2-div.c b/drivers/clk/berlin/berlin2-div.c index 0a248bfe2193..8d2123f0bea2 100644 --- a/drivers/clk/berlin/berlin2-div.c +++ b/drivers/clk/berlin/berlin2-div.c @@ -236,7 +236,7 @@ berlin2_div_register(const struct berlin2_div_map *map, const struct clk_ops *gate_ops = &berlin2_div_gate_ops; struct berlin2_div *div; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/berlin/berlin2-pll.c b/drivers/clk/berlin/berlin2-pll.c index 9661820717a5..d0ec3d0bcf3e 100644 --- a/drivers/clk/berlin/berlin2-pll.c +++ b/drivers/clk/berlin/berlin2-pll.c @@ -81,7 +81,7 @@ berlin2_pll_register(const struct berlin2_pll_map *map, struct clk_init_data init; struct berlin2_pll *pll; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return -ENOMEM; diff --git a/drivers/clk/berlin/bg2.c b/drivers/clk/berlin/bg2.c index 67a9edbba29c..9bd1c91f5227 100644 --- a/drivers/clk/berlin/bg2.c +++ b/drivers/clk/berlin/bg2.c @@ -499,7 +499,7 @@ static void __init berlin2_clock_setup(struct device_node *np) u8 avpll_flags = 0; int n, ret; - clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, MAX_CLKS); if (!clk_data) { of_node_put(parent_np); return; diff --git a/drivers/clk/berlin/bg2q.c b/drivers/clk/berlin/bg2q.c index dd2784bb75b6..4d407c8c3b40 100644 --- a/drivers/clk/berlin/bg2q.c +++ b/drivers/clk/berlin/bg2q.c @@ -285,7 +285,7 @@ static void __init berlin2q_clock_setup(struct device_node *np) struct clk_hw **hws; int n, ret; - clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, MAX_CLKS); if (!clk_data) { of_node_put(parent_np); return; diff --git a/drivers/clk/clk-apple-nco.c b/drivers/clk/clk-apple-nco.c index d3ced4a0f029..434c067968bb 100644 --- a/drivers/clk/clk-apple-nco.c +++ b/drivers/clk/clk-apple-nco.c @@ -320,6 +320,7 @@ static int applnco_probe(struct platform_device *pdev) } static const struct of_device_id applnco_ids[] = { + { .compatible = "apple,t8103-nco" }, { .compatible = "apple,nco" }, { } }; diff --git a/drivers/clk/clk-asm9260.c b/drivers/clk/clk-asm9260.c index 595cfa533fb9..4fe29040bdb0 100644 --- a/drivers/clk/clk-asm9260.c +++ b/drivers/clk/clk-asm9260.c @@ -262,7 +262,7 @@ static void __init asm9260_acc_init(struct device_node *np) u32 rate; int n; - clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, MAX_CLKS); if (!clk_data) return; clk_data->num = MAX_CLKS; diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c index dac190bc6e19..46251008c83f 100644 --- a/drivers/clk/clk-bm1880.c +++ b/drivers/clk/clk-bm1880.c @@ -621,18 +621,11 @@ static int bm1880_clk_div_determine_rate(struct clk_hw *hw, val = readl(reg_addr) >> div->shift; val &= clk_div_mask(div->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - div->table, - div->width, div->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, div->table, + div->width, div->flags, val); } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - div->table, div->width, div->flags); - - return 0; + return divider_determine_rate(hw, req, div->table, div->width, div->flags); } static int bm1880_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -771,7 +764,7 @@ static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_cloc int ret; if (clks->mux_shift >= 0) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -791,7 +784,7 @@ static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_cloc } if (clks->gate_shift >= 0) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { ret = -ENOMEM; goto err_out; @@ -806,7 +799,7 @@ static struct clk_hw *bm1880_clk_register_composite(struct bm1880_composite_cloc } if (clks->div_shift >= 0) { - div_hws = kzalloc(sizeof(*div_hws), GFP_KERNEL); + div_hws = kzalloc_obj(*div_hws); if (!div_hws) { ret = -ENOMEM; goto err_out; diff --git a/drivers/clk/clk-bulk.c b/drivers/clk/clk-bulk.c index 826b3ff99433..d85dae4bdf89 100644 --- a/drivers/clk/clk-bulk.c +++ b/drivers/clk/clk-bulk.c @@ -54,7 +54,7 @@ static int __must_check of_clk_bulk_get_all(struct device_node *np, if (!num_clks) return 0; - clk_bulk = kmalloc_array(num_clks, sizeof(*clk_bulk), GFP_KERNEL); + clk_bulk = kmalloc_objs(*clk_bulk, num_clks); if (!clk_bulk) return -ENOMEM; diff --git a/drivers/clk/clk-clps711x.c b/drivers/clk/clk-clps711x.c index 402ab74d9bfb..27a57a9b3cb3 100644 --- a/drivers/clk/clk-clps711x.c +++ b/drivers/clk/clk-clps711x.c @@ -53,9 +53,8 @@ static void __init clps711x_clk_init_dt(struct device_node *np) base = of_iomap(np, 0); BUG_ON(!base); - clps711x_clk = kzalloc(struct_size(clps711x_clk, clk_data.hws, - CLPS711X_CLK_MAX), - GFP_KERNEL); + clps711x_clk = kzalloc_flex(*clps711x_clk, clk_data.hws, + CLPS711X_CLK_MAX); BUG_ON(!clps711x_clk); spin_lock_init(&clps711x_clk->lock); diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 66759fe28fad..44d010bccfb1 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -248,7 +248,7 @@ static struct clk_hw *__clk_hw_register_composite(struct device *dev, struct clk_ops *clk_composite_ops; int ret; - composite = kzalloc(sizeof(*composite), GFP_KERNEL); + composite = kzalloc_obj(*composite); if (!composite) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 2601b6155afb..45e7ebde4a8b 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -538,7 +538,7 @@ struct clk_hw *__clk_hw_register_divider(struct device *dev, } /* allocate the divider */ - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c index ea1c3d78e7cd..81137269352d 100644 --- a/drivers/clk/clk-eyeq.c +++ b/drivers/clk/clk-eyeq.c @@ -335,7 +335,7 @@ static int eqc_auxdev_create(struct device *dev, void __iomem *base, struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; @@ -400,7 +400,7 @@ static int eqc_probe(struct platform_device *pdev) clk_count = data->pll_count + data->div_count + data->fixed_factor_count + data->early_clk_count; - cells = kzalloc(struct_size(cells, hws, clk_count), GFP_KERNEL); + cells = kzalloc_flex(*cells, hws, clk_count); if (!cells) return -ENOMEM; @@ -738,7 +738,7 @@ static void __init eqc_early_init(struct device_node *np, clk_count = early_data->early_pll_count + early_data->early_fixed_factor_count + early_data->late_clk_count; - cells = kzalloc(struct_size(cells, hws, clk_count), GFP_KERNEL); + cells = kzalloc_flex(*cells, hws, clk_count); if (!cells) { ret = -ENOMEM; goto err; diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index de658c9e4c53..850e8b95f352 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -110,7 +110,7 @@ __clk_hw_register_fixed_factor(struct device *dev, struct device_node *np, fix = devres_alloc(devm_clk_hw_register_fixed_factor_release, sizeof(*fix), GFP_KERNEL); else - fix = kmalloc(sizeof(*fix), GFP_KERNEL); + fix = kmalloc_obj(*fix); if (!fix) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-fixed-rate.c b/drivers/clk/clk-fixed-rate.c index 6b4f76b9c4da..5dcb1bccf2b4 100644 --- a/drivers/clk/clk-fixed-rate.c +++ b/drivers/clk/clk-fixed-rate.c @@ -78,7 +78,7 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev, fixed = devres_alloc(devm_clk_hw_register_fixed_rate_release, sizeof(*fixed), GFP_KERNEL); else - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); + fixed = kzalloc_obj(*fixed); if (!fixed) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-fractional-divider.c b/drivers/clk/clk-fractional-divider.c index cd36a6e27f25..1c5fdcb68a50 100644 --- a/drivers/clk/clk-fractional-divider.c +++ b/drivers/clk/clk-fractional-divider.c @@ -275,7 +275,7 @@ struct clk_hw *clk_hw_register_fractional_divider(struct device *dev, struct clk_hw *hw; int ret; - fd = kzalloc(sizeof(*fd), GFP_KERNEL); + fd = kzalloc_obj(*fd); if (!fd) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 4746f8219132..44f5e0c53786 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -145,7 +145,7 @@ struct clk_hw *__clk_hw_register_gate(struct device *dev, } /* allocate the gate */ - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-gemini.c b/drivers/clk/clk-gemini.c index e94589c38568..9c0e6e7a7cac 100644 --- a/drivers/clk/clk-gemini.c +++ b/drivers/clk/clk-gemini.c @@ -197,7 +197,7 @@ static struct clk_hw *gemini_pci_clk_setup(const char *name, struct clk_init_data init; int ret; - pciclk = kzalloc(sizeof(*pciclk), GFP_KERNEL); + pciclk = kzalloc_obj(*pciclk); if (!pciclk) return ERR_PTR(-ENOMEM); @@ -398,9 +398,7 @@ static void __init gemini_cc_init(struct device_node *np) int ret; int i; - gemini_clk_data = kzalloc(struct_size(gemini_clk_data, hws, - GEMINI_NUM_CLKS), - GFP_KERNEL); + gemini_clk_data = kzalloc_flex(*gemini_clk_data, hws, GEMINI_NUM_CLKS); if (!gemini_clk_data) return; gemini_clk_data->num = GEMINI_NUM_CLKS; diff --git a/drivers/clk/clk-highbank.c b/drivers/clk/clk-highbank.c index cc583934ecf2..e9b177811dfc 100644 --- a/drivers/clk/clk-highbank.c +++ b/drivers/clk/clk-highbank.c @@ -277,7 +277,7 @@ static void __init hb_clk_init(struct device_node *node, const struct clk_ops *o if (WARN_ON(rc)) return; - hb_clk = kzalloc(sizeof(*hb_clk), GFP_KERNEL); + hb_clk = kzalloc_obj(*hb_clk); if (WARN_ON(!hb_clk)) return; diff --git a/drivers/clk/clk-hsdk-pll.c b/drivers/clk/clk-hsdk-pll.c index 7d56a47c2aa7..0e257cce588e 100644 --- a/drivers/clk/clk-hsdk-pll.c +++ b/drivers/clk/clk-hsdk-pll.c @@ -357,7 +357,7 @@ static void __init of_hsdk_pll_clk_setup(struct device_node *node) struct hsdk_pll_clk *pll_clk; struct clk_init_data init = { }; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (!pll_clk) return; diff --git a/drivers/clk/clk-k210.c b/drivers/clk/clk-k210.c index 7b7329a907ab..6e27f5334cf8 100644 --- a/drivers/clk/clk-k210.c +++ b/drivers/clk/clk-k210.c @@ -893,7 +893,7 @@ static void __init k210_clk_init(struct device_node *np) struct k210_sysclk *ksc; int i, ret; - ksc = kzalloc(sizeof(*ksc), GFP_KERNEL); + ksc = kzalloc_obj(*ksc); if (!ksc) return; diff --git a/drivers/clk/clk-lmk04832.c b/drivers/clk/clk-lmk04832.c index b2107b31efa2..9bf86caad829 100644 --- a/drivers/clk/clk-lmk04832.c +++ b/drivers/clk/clk-lmk04832.c @@ -1400,7 +1400,6 @@ static int lmk04832_probe(struct spi_device *spi) { const struct lmk04832_device_info *info; int rdbk_pin = RDBK_CLKIN_SEL1; - struct device_node *child; struct lmk04832 *lmk; u8 tmp[3]; int ret; @@ -1462,14 +1461,13 @@ static int lmk04832_probe(struct spi_device *spi) device_property_read_u32(lmk->dev, "ti,sysref-pulse-count", &lmk->sysref_pulse_cnt); - for_each_child_of_node(lmk->dev->of_node, child) { + for_each_child_of_node_scoped(lmk->dev->of_node, child) { int reg; ret = of_property_read_u32(child, "reg", ®); if (ret) { dev_err(lmk->dev, "missing reg property in child: %s\n", child->full_name); - of_node_put(child); return ret; } diff --git a/drivers/clk/clk-loongson1.c b/drivers/clk/clk-loongson1.c index f9f060d08a5f..1674181a1107 100644 --- a/drivers/clk/clk-loongson1.c +++ b/drivers/clk/clk-loongson1.c @@ -99,10 +99,7 @@ static int ls1x_divider_determine_rate(struct clk_hw *hw, struct ls1x_clk *ls1x_clk = to_ls1x_clk(hw); const struct ls1x_clk_div_data *d = ls1x_clk->data; - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - d->table, d->width, d->flags); - - return 0; + return divider_determine_rate(hw, req, d->table, d->width, d->flags); } static int ls1x_divider_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/clk-milbeaut.c b/drivers/clk/clk-milbeaut.c index b4f9b7143eaa..4265bc442dfd 100644 --- a/drivers/clk/clk-milbeaut.c +++ b/drivers/clk/clk-milbeaut.c @@ -333,7 +333,7 @@ static struct clk_hw *m10v_clk_hw_register_mux(struct device *dev, struct clk_init_data init; int ret; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -398,19 +398,12 @@ static int m10v_clk_divider_determine_rate(struct clk_hw *hw, val = readl(divider->reg) >> divider->shift; val &= clk_div_mask(divider->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - divider->table, - divider->width, - divider->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, divider->flags, + val); } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, divider->flags); } static int m10v_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, @@ -471,7 +464,7 @@ static struct clk_hw *m10v_clk_hw_register_divider(struct device *dev, struct clk_init_data init; int ret; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); @@ -618,9 +611,7 @@ static void __init m10v_cc_init(struct device_node *np) const char *parent_name; struct clk_hw *hw; - m10v_clk_data = kzalloc(struct_size(m10v_clk_data, hws, - M10V_NUM_CLKS), - GFP_KERNEL); + m10v_clk_data = kzalloc_flex(*m10v_clk_data, hws, M10V_NUM_CLKS); if (!m10v_clk_data) return; diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index fa817c317c2a..1d5b6b68711e 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -169,7 +169,7 @@ struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np, } /* allocate the mux */ - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index fc0aeb4247f2..da6b89759a14 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c @@ -270,7 +270,7 @@ pll_clk_register(struct device *dev, const char *name, return ERR_PTR(-EINVAL); } - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -357,7 +357,7 @@ src_clk_register(struct device *dev, const char *name, struct clk_src *sclk; struct clk_init_data init; - sclk = kzalloc(sizeof(*sclk), GFP_KERNEL); + sclk = kzalloc_obj(*sclk); if (!sclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk-npcm7xx.c b/drivers/clk/clk-npcm7xx.c index 030186def9c6..79eca6ee3120 100644 --- a/drivers/clk/clk-npcm7xx.c +++ b/drivers/clk/clk-npcm7xx.c @@ -74,7 +74,7 @@ npcm7xx_clk_register_pll(void __iomem *pllcon, const char *name, struct clk_hw *hw; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -421,8 +421,8 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np) if (!clk_base) goto npcm7xx_init_error; - npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws, - NPCM7XX_NUM_CLOCKS), GFP_KERNEL); + npcm7xx_clk_data = kzalloc_flex(*npcm7xx_clk_data, hws, + NPCM7XX_NUM_CLOCKS); if (!npcm7xx_clk_data) goto npcm7xx_init_np_err; diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c index a560edeb4b55..f05631e55310 100644 --- a/drivers/clk/clk-qoriq.c +++ b/drivers/clk/clk-qoriq.c @@ -976,7 +976,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx) u64 max_rate, pct80_rate; u32 clksel; - hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); + hwc = kzalloc_obj(*hwc); if (!hwc) return NULL; @@ -1020,7 +1020,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx) { struct mux_hwclock *hwc; - hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); + hwc = kzalloc_obj(*hwc); if (!hwc) return NULL; @@ -1319,11 +1319,11 @@ static void __init legacy_pll_init(struct device_node *np, int idx) count = of_property_count_strings(np, "clock-output-names"); BUILD_BUG_ON(ARRAY_SIZE(pll->div) < 4); - subclks = kcalloc(4, sizeof(struct clk *), GFP_KERNEL); + subclks = kzalloc_objs(struct clk *, 4); if (!subclks) return; - onecell_data = kmalloc(sizeof(*onecell_data), GFP_KERNEL); + onecell_data = kmalloc_obj(*onecell_data); if (!onecell_data) goto err_clks; diff --git a/drivers/clk/clk-renesas-pcie.c b/drivers/clk/clk-renesas-pcie.c index 4c3a5e4eb77a..aa108df12e44 100644 --- a/drivers/clk/clk-renesas-pcie.c +++ b/drivers/clk/clk-renesas-pcie.c @@ -64,7 +64,7 @@ struct rs9_driver_data { struct i2c_client *client; struct regmap *regmap; const struct rs9_chip_info *chip_info; - struct clk_hw *clk_dif[4]; + struct clk_hw *clk_dif[8]; u8 pll_amplitude; u8 pll_ssc; u8 clk_dif_sr; @@ -354,7 +354,7 @@ static int rs9_probe(struct i2c_client *client) return ret; } -static int __maybe_unused rs9_suspend(struct device *dev) +static int rs9_suspend(struct device *dev) { struct rs9_driver_data *rs9 = dev_get_drvdata(dev); @@ -364,7 +364,7 @@ static int __maybe_unused rs9_suspend(struct device *dev) return 0; } -static int __maybe_unused rs9_resume(struct device *dev) +static int rs9_resume(struct device *dev) { struct rs9_driver_data *rs9 = dev_get_drvdata(dev); int ret; @@ -410,12 +410,12 @@ static const struct of_device_id clk_rs9_of_match[] = { }; MODULE_DEVICE_TABLE(of, clk_rs9_of_match); -static SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume); static struct i2c_driver rs9_driver = { .driver = { .name = "clk-renesas-pcie-9series", - .pm = &rs9_pm_ops, + .pm = pm_sleep_ptr(&rs9_pm_ops), .of_match_table = clk_rs9_of_match, }, .probe = rs9_probe, diff --git a/drivers/clk/clk-scpi.c b/drivers/clk/clk-scpi.c index 0b592de7bdb2..7806569cd0d5 100644 --- a/drivers/clk/clk-scpi.c +++ b/drivers/clk/clk-scpi.c @@ -265,20 +265,19 @@ static int scpi_clocks_probe(struct platform_device *pdev) { int ret; struct device *dev = &pdev->dev; - struct device_node *child, *np = dev->of_node; + struct device_node *np = dev->of_node; const struct of_device_id *match; if (!get_scpi_ops()) return -ENXIO; - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { match = of_match_node(scpi_clk_match, child); if (!match) continue; ret = scpi_clk_add(dev, child, match); if (ret) { scpi_clocks_remove(pdev); - of_node_put(child); return ret; } diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index b5d4d48432a0..565b4d99bebb 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -489,7 +489,7 @@ static struct clk *clk_register_apb_mul(struct device *dev, const char *name, struct clk_init_data init; struct clk *clk; - am = kzalloc(sizeof(*am), GFP_KERNEL); + am = kzalloc_obj(*am); if (!am) return ERR_PTR(-ENOMEM); @@ -815,7 +815,7 @@ static struct clk_hw *clk_register_pll_div(const char *name, int ret; /* allocate the divider */ - pll_div = kzalloc(sizeof(*pll_div), GFP_KERNEL); + pll_div = kzalloc_obj(*pll_div); if (!pll_div) return ERR_PTR(-ENOMEM); @@ -937,7 +937,7 @@ static struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc, const struct stm32f4_vco_data *vco; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -1107,7 +1107,7 @@ static struct clk_hw *clk_register_rgate(struct device *dev, const char *name, struct clk_hw *hw; int ret; - rgate = kzalloc(sizeof(*rgate), GFP_KERNEL); + rgate = kzalloc_obj(*rgate); if (!rgate) return ERR_PTR(-ENOMEM); @@ -1202,13 +1202,13 @@ static struct clk_hw *stm32_register_cclk(struct device *dev, const char *name, struct clk_gate *gate; struct clk_mux *mux; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { hw = ERR_PTR(-EINVAL); goto fail; } - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) { kfree(gate); hw = ERR_PTR(-EINVAL); @@ -1776,7 +1776,7 @@ static struct clk_hw *stm32_register_aux_clk(const char *name, const struct clk_ops *mux_ops = NULL, *gate_ops = NULL; if (offset_gate != NO_GATE) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { hw = ERR_PTR(-EINVAL); goto fail; @@ -1791,7 +1791,7 @@ static struct clk_hw *stm32_register_aux_clk(const char *name, } if (offset_mux != NO_MUX) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) { hw = ERR_PTR(-EINVAL); goto fail; @@ -1855,8 +1855,7 @@ static void __init stm32f4_rcc_init(struct device_node *np) stm32fx_end_primary_clk = data->end_primary; - clks = kmalloc_array(data->gates_num + stm32fx_end_primary_clk, - sizeof(*clks), GFP_KERNEL); + clks = kmalloc_objs(*clks, data->gates_num + stm32fx_end_primary_clk); if (!clks) goto fail; diff --git a/drivers/clk/clk-stm32h7.c b/drivers/clk/clk-stm32h7.c index 04c18a1d45d3..82e0789cf189 100644 --- a/drivers/clk/clk-stm32h7.c +++ b/drivers/clk/clk-stm32h7.c @@ -222,7 +222,7 @@ static struct clk_hw *clk_register_ready_gate(struct device *dev, struct clk_hw *hw; int ret; - rgate = kzalloc(sizeof(*rgate), GFP_KERNEL); + rgate = kzalloc_obj(*rgate); if (!rgate) return ERR_PTR(-ENOMEM); @@ -297,7 +297,7 @@ static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width, { struct clk_mux *mux; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -315,7 +315,7 @@ static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width, { struct clk_divider *div; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); @@ -334,7 +334,7 @@ static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags, { struct clk_gate *gate; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); @@ -467,7 +467,7 @@ static struct clk_hw *clk_register_stm32_timer_ker(struct device *dev, struct clk_hw *hw; int err; - element = kzalloc(sizeof(*element), GFP_KERNEL); + element = kzalloc_obj(*element); if (!element) return ERR_PTR(-ENOMEM); @@ -792,7 +792,7 @@ static struct clk_hw *clk_register_stm32_pll(struct device *dev, struct stm32_fractional_divider *div = NULL; struct stm32_ready_gate *rgate; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -1200,8 +1200,7 @@ static void __init stm32h7_rcc_init(struct device_node *np) const char *hse_clk, *lse_clk, *i2s_clk; struct regmap *pdrm; - clk_data = kzalloc(struct_size(clk_data, hws, STM32H7_MAX_CLKS), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, STM32H7_MAX_CLKS); if (!clk_data) return; diff --git a/drivers/clk/clk-versaclock3.c b/drivers/clk/clk-versaclock3.c index 1849863dbd67..27b6cf70f3ae 100644 --- a/drivers/clk/clk-versaclock3.c +++ b/drivers/clk/clk-versaclock3.c @@ -523,11 +523,8 @@ static int vc3_div_determine_rate(struct clk_hw *hw, return 0; } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - div_data->table, - div_data->width, div_data->flags); - - return 0; + return divider_determine_rate(hw, req, div_data->table, div_data->width, + div_data->flags); } static int vc3_div_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index eae5b3fbfb82..3e62cb853d5e 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -235,7 +235,7 @@ static __init void vtwm_device_clk_init(struct device_node *node) if (!pmc_base) vtwm_set_pmc_base(); - dev_clk = kzalloc(sizeof(*dev_clk), GFP_KERNEL); + dev_clk = kzalloc_obj(*dev_clk); if (WARN_ON(!dev_clk)) return; @@ -698,7 +698,7 @@ static __init void vtwm_pll_clk_init(struct device_node *node, int pll_type) if (WARN_ON(rc)) return; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return; diff --git a/drivers/clk/clk-xgene.c b/drivers/clk/clk-xgene.c index 92e39f3237c2..ba3b1057e4f0 100644 --- a/drivers/clk/clk-xgene.c +++ b/drivers/clk/clk-xgene.c @@ -131,7 +131,7 @@ static struct clk *xgene_register_clk_pll(struct device *dev, struct clk_init_data init; /* allocate the APM clock structure */ - apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL); + apmclk = kzalloc_obj(*apmclk); if (!apmclk) return ERR_PTR(-ENOMEM); @@ -352,7 +352,7 @@ xgene_register_clk_pmd(struct device *dev, struct clk_init_data init; struct clk *clk; - fd = kzalloc(sizeof(*fd), GFP_KERNEL); + fd = kzalloc_obj(*fd); if (!fd) return ERR_PTR(-ENOMEM); @@ -638,7 +638,7 @@ static struct clk *xgene_register_clk(struct device *dev, int rc; /* allocate the APM clock structure */ - apmclk = kzalloc(sizeof(*apmclk), GFP_KERNEL); + apmclk = kzalloc_obj(*apmclk); if (!apmclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index 85d2f2481acf..47093cda9df3 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -4121,7 +4121,7 @@ static struct clk *alloc_clk(struct clk_core *core, const char *dev_id, { struct clk *clk; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); @@ -4238,7 +4238,7 @@ static int clk_core_populate_parent_map(struct clk_core *core, * Avoid unnecessary string look-ups of clk_core's possible parents by * having a cache of names/clk_hw pointers to clk_core pointers. */ - parents = kcalloc(num_parents, sizeof(*parents), GFP_KERNEL); + parents = kzalloc_objs(*parents, num_parents); core->parents = parents; if (!parents) return -ENOMEM; @@ -4328,7 +4328,7 @@ __clk_register(struct device *dev, struct device_node *np, struct clk_hw *hw) */ hw->init = NULL; - core = kzalloc(sizeof(*core), GFP_KERNEL); + core = kzalloc_obj(*core); if (!core) { ret = -ENOMEM; goto fail_out; @@ -4813,7 +4813,7 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb) goto found; /* if clk wasn't in the notifier list, allocate new clk_notifier */ - cn = kzalloc(sizeof(*cn), GFP_KERNEL); + cn = kzalloc_obj(*cn); if (!cn) goto out; @@ -5009,7 +5009,7 @@ int of_clk_add_provider(struct device_node *np, if (!np) return 0; - cp = kzalloc(sizeof(*cp), GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return -ENOMEM; @@ -5051,7 +5051,7 @@ int of_clk_add_hw_provider(struct device_node *np, if (!np) return 0; - cp = kzalloc(sizeof(*cp), GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return -ENOMEM; @@ -5548,7 +5548,7 @@ void __init of_clk_init(const struct of_device_id *matches) if (!of_device_is_available(np)) continue; - parent = kzalloc(sizeof(*parent), GFP_KERNEL); + parent = kzalloc_obj(*parent); if (!parent) { list_for_each_entry_safe(clk_provider, next, &clk_provider_list, node) { diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index e0bede6350e1..abaa0f9e0083 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c @@ -164,7 +164,7 @@ vclkdev_alloc(struct clk_hw *hw, const char *con_id, const char *dev_fmt, size_t max_size; ssize_t res; - cla = kzalloc(sizeof(*cla), GFP_KERNEL); + cla = kzalloc_obj(*cla); if (!cla) return NULL; diff --git a/drivers/clk/davinci/pll.c b/drivers/clk/davinci/pll.c index bfb6bbdc036c..f73b0ac5d8a0 100644 --- a/drivers/clk/davinci/pll.c +++ b/drivers/clk/davinci/pll.c @@ -243,14 +243,14 @@ static struct clk *davinci_pll_div_register(struct device *dev, struct clk *clk; int ret; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); gate->reg = reg; gate->bit_idx = DIV_ENABLE_SHIFT; - divider = kzalloc(sizeof(*divider), GFP_KERNEL); + divider = kzalloc_obj(*divider); if (!divider) { ret = -ENOMEM; goto err_free_gate; @@ -433,7 +433,7 @@ struct clk *davinci_pll_clk_register(struct device *dev, info->unlock_mask, 0); } - pllout = kzalloc(sizeof(*pllout), GFP_KERNEL); + pllout = kzalloc_obj(*pllout); if (!pllout) { ret = -ENOMEM; goto err_unregister_prediv; @@ -489,7 +489,7 @@ struct clk *davinci_pll_clk_register(struct device *dev, parent_name = postdiv_name; } - pllen = kzalloc(sizeof(*pllen), GFP_KERNEL); + pllen = kzalloc_obj(*pllen); if (!pllen) { ret = -ENOMEM; goto err_unregister_postdiv; @@ -579,7 +579,7 @@ davinci_pll_obsclk_register(struct device *dev, u32 oscdiv; int ret; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -587,7 +587,7 @@ davinci_pll_obsclk_register(struct device *dev, mux->table = info->table; mux->mask = info->ocsrc_mask; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { ret = -ENOMEM; goto err_free_mux; @@ -596,7 +596,7 @@ davinci_pll_obsclk_register(struct device *dev, gate->reg = base + CKEN; gate->bit_idx = CKEN_OBSCLK_SHIFT; - divider = kzalloc(sizeof(*divider), GFP_KERNEL); + divider = kzalloc_obj(*divider); if (!divider) { ret = -ENOMEM; goto err_free_gate; @@ -690,14 +690,14 @@ davinci_pll_sysclk_register(struct device *dev, else reg = PLLDIV4 + 4 * (info->id - 4); - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); gate->reg = base + reg; gate->bit_idx = DIV_ENABLE_SHIFT; - divider = kzalloc(sizeof(*divider), GFP_KERNEL); + divider = kzalloc_obj(*divider); if (!divider) { ret = -ENOMEM; goto err_free_gate; @@ -776,13 +776,13 @@ int of_davinci_pll_init(struct device *dev, struct device_node *node, int n_clks = max_sysclk_id + 1; int i; - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) { of_node_put(child); return -ENOMEM; } - clks = kmalloc_array(n_clks, sizeof(*clks), GFP_KERNEL); + clks = kmalloc_objs(*clks, n_clks); if (!clks) { kfree(clk_data); of_node_put(child); @@ -942,7 +942,7 @@ static void davinci_pll_debug_init(struct clk_hw *hw, struct dentry *dentry) struct davinci_pll_clk *pll = to_davinci_pll_clk(hw); struct debugfs_regset32 *regset; - regset = kzalloc(sizeof(*regset), GFP_KERNEL); + regset = kzalloc_obj(*regset); if (!regset) return; diff --git a/drivers/clk/davinci/psc.c b/drivers/clk/davinci/psc.c index f3ee9397bb0c..ff603520d56f 100644 --- a/drivers/clk/davinci/psc.c +++ b/drivers/clk/davinci/psc.c @@ -239,7 +239,7 @@ davinci_lpsc_clk_register(struct device *dev, const char *name, int ret; bool is_on; - lpsc = kzalloc(sizeof(*lpsc), GFP_KERNEL); + lpsc = kzalloc_obj(*lpsc); if (!lpsc) return ERR_PTR(-ENOMEM); @@ -372,11 +372,11 @@ __davinci_psc_register_clocks(struct device *dev, struct regmap *regmap; int i, ret; - psc = kzalloc(sizeof(*psc), GFP_KERNEL); + psc = kzalloc_obj(*psc); if (!psc) return ERR_PTR(-ENOMEM); - clks = kmalloc_array(num_clks, sizeof(*clks), GFP_KERNEL); + clks = kmalloc_objs(*clks, num_clks); if (!clks) { ret = -ENOMEM; goto err_free_psc; @@ -392,7 +392,7 @@ __davinci_psc_register_clocks(struct device *dev, for (i = 0; i < num_clks; i++) clks[i] = ERR_PTR(-ENOENT); - pm_domains = kcalloc(num_clks, sizeof(*pm_domains), GFP_KERNEL); + pm_domains = kzalloc_objs(*pm_domains, num_clks); if (!pm_domains) { ret = -ENOMEM; goto err_free_clks; diff --git a/drivers/clk/hisilicon/clk-hi3620.c b/drivers/clk/hisilicon/clk-hi3620.c index 5d0226530fdb..8dcad74e679a 100644 --- a/drivers/clk/hisilicon/clk-hi3620.c +++ b/drivers/clk/hisilicon/clk-hi3620.c @@ -414,7 +414,7 @@ static struct clk *hisi_register_clk_mmc(struct hisi_mmc_clock *mmc_clk, struct clk *clk; struct clk_init_data init; - mclk = kzalloc(sizeof(*mclk), GFP_KERNEL); + mclk = kzalloc_obj(*mclk); if (!mclk) return ERR_PTR(-ENOMEM); @@ -461,11 +461,11 @@ static void __init hi3620_mmc_clk_init(struct device_node *node) return; } - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (WARN_ON(!clk_data)) return; - clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL); + clk_data->clks = kzalloc_objs(*clk_data->clks, num); if (!clk_data->clks) { kfree(clk_data); return; diff --git a/drivers/clk/hisilicon/clk-hix5hd2.c b/drivers/clk/hisilicon/clk-hix5hd2.c index 64bdd3f05725..57db6fab43aa 100644 --- a/drivers/clk/hisilicon/clk-hix5hd2.c +++ b/drivers/clk/hisilicon/clk-hix5hd2.c @@ -261,7 +261,7 @@ hix5hd2_clk_register_complex(struct hix5hd2_complex_clock *clks, int nums, struct clk *clk; struct clk_init_data init; - p_clk = kzalloc(sizeof(*p_clk), GFP_KERNEL); + p_clk = kzalloc_obj(*p_clk); if (!p_clk) return; diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c index 09368fd32bef..fae65127cd4a 100644 --- a/drivers/clk/hisilicon/clk.c +++ b/drivers/clk/hisilicon/clk.c @@ -68,12 +68,12 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np, goto err; } - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) goto err; clk_data->base = base; - clk_table = kcalloc(nr_clks, sizeof(*clk_table), GFP_KERNEL); + clk_table = kzalloc_objs(*clk_table, nr_clks); if (!clk_table) goto err_data; diff --git a/drivers/clk/hisilicon/clkdivider-hi6220.c b/drivers/clk/hisilicon/clkdivider-hi6220.c index 6bae18a84cb6..1787ecefe601 100644 --- a/drivers/clk/hisilicon/clkdivider-hi6220.c +++ b/drivers/clk/hisilicon/clkdivider-hi6220.c @@ -60,10 +60,8 @@ static int hi6220_clkdiv_determine_rate(struct clk_hw *hw, { struct hi6220_clk_divider *dclk = to_hi6220_clk_divider(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, dclk->table, - dclk->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, dclk->table, dclk->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int hi6220_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, @@ -111,7 +109,7 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, int i; /* allocate the divider */ - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); @@ -119,7 +117,7 @@ struct clk *hi6220_register_clkdiv(struct device *dev, const char *name, max_div = div_mask(width) + 1; min_div = 1; - table = kcalloc(max_div + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, max_div + 1); if (!table) { kfree(div); return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/hisilicon/clkgate-separated.c b/drivers/clk/hisilicon/clkgate-separated.c index 21d4297f3225..199303157ebd 100644 --- a/drivers/clk/hisilicon/clkgate-separated.c +++ b/drivers/clk/hisilicon/clkgate-separated.c @@ -90,7 +90,7 @@ struct clk *hisi_register_clkgate_sep(struct device *dev, const char *name, struct clk *clk; struct clk_init_data init; - sclk = kzalloc(sizeof(*sclk), GFP_KERNEL); + sclk = kzalloc_obj(*sclk); if (!sclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imgtec/clk-boston.c b/drivers/clk/imgtec/clk-boston.c index db96f8bea630..f28c3ab93bcb 100644 --- a/drivers/clk/imgtec/clk-boston.c +++ b/drivers/clk/imgtec/clk-boston.c @@ -58,8 +58,7 @@ static void __init clk_boston_setup(struct device_node *np) cpu_div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV); cpu_freq = mult_frac(in_freq, mul, cpu_div); - onecell = kzalloc(struct_size(onecell, hws, BOSTON_CLK_COUNT), - GFP_KERNEL); + onecell = kzalloc_flex(*onecell, hws, BOSTON_CLK_COUNT); if (!onecell) return; diff --git a/drivers/clk/imx/clk-busy.c b/drivers/clk/imx/clk-busy.c index eb27c6fee359..b8b6e7c7e1fe 100644 --- a/drivers/clk/imx/clk-busy.c +++ b/drivers/clk/imx/clk-busy.c @@ -82,7 +82,7 @@ struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name struct clk_init_data init; int ret; - busy = kzalloc(sizeof(*busy), GFP_KERNEL); + busy = kzalloc_obj(*busy); if (!busy) return ERR_PTR(-ENOMEM); @@ -162,7 +162,7 @@ struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift struct clk_init_data init; int ret; - busy = kzalloc(sizeof(*busy), GFP_KERNEL); + busy = kzalloc_obj(*busy); if (!busy) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-composite-7ulp.c b/drivers/clk/imx/clk-composite-7ulp.c index 37d2fc197be6..689e3479d14d 100644 --- a/drivers/clk/imx/clk-composite-7ulp.c +++ b/drivers/clk/imx/clk-composite-7ulp.c @@ -99,7 +99,7 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, } if (mux_present) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); mux_hw = &mux->hw; @@ -111,7 +111,7 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, } if (rate_present) { - fd = kzalloc(sizeof(*fd), GFP_KERNEL); + fd = kzalloc_obj(*fd); if (!fd) { kfree(mux); return ERR_PTR(-ENOMEM); @@ -128,7 +128,7 @@ static struct clk_hw *imx_ulp_clk_hw_composite(const char *name, } if (gate_present) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { kfree(mux); kfree(fd); diff --git a/drivers/clk/imx/clk-composite-8m.c b/drivers/clk/imx/clk-composite-8m.c index 1467d0a1b934..e63e0cb4b203 100644 --- a/drivers/clk/imx/clk-composite-8m.c +++ b/drivers/clk/imx/clk-composite-8m.c @@ -231,7 +231,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, const struct clk_ops *mux_ops; const struct clk_ops *gate_ops; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_CAST(hw); @@ -241,7 +241,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, mux->mask = PCG_PCS_MASK; mux->lock = &imx_ccm_lock; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto free_mux; @@ -270,7 +270,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name, div->flags = CLK_DIVIDER_ROUND_CLOSEST; /* skip registering the gate ops if M4 is enabled */ - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto free_div; diff --git a/drivers/clk/imx/clk-composite-93.c b/drivers/clk/imx/clk-composite-93.c index 513d74a39d3b..ef20ceb2d255 100644 --- a/drivers/clk/imx/clk-composite-93.c +++ b/drivers/clk/imx/clk-composite-93.c @@ -193,7 +193,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p bool clk_ro = false; u32 authen; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) goto fail; @@ -203,7 +203,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p mux->mask = CCM_MUX_MASK; mux->lock = &imx_ccm_lock; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto fail; @@ -223,7 +223,7 @@ struct clk_hw *imx93_clk_composite_flags(const char *name, const char * const *p mux_hw, &clk_mux_ro_ops, div_hw, &clk_divider_ro_ops, NULL, NULL, flags); } else { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto fail; diff --git a/drivers/clk/imx/clk-cpu.c b/drivers/clk/imx/clk-cpu.c index 43637cb61693..f53dbaacddcc 100644 --- a/drivers/clk/imx/clk-cpu.c +++ b/drivers/clk/imx/clk-cpu.c @@ -81,7 +81,7 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name, struct clk_init_data init; int ret; - cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); + cpu = kzalloc_obj(*cpu); if (!cpu) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-divider-gate.c b/drivers/clk/imx/clk-divider-gate.c index 26b210cba9be..957d132c4607 100644 --- a/drivers/clk/imx/clk-divider-gate.c +++ b/drivers/clk/imx/clk-divider-gate.c @@ -185,7 +185,7 @@ struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name u32 val; int ret; - div_gate = kzalloc(sizeof(*div_gate), GFP_KERNEL); + div_gate = kzalloc_obj(*div_gate); if (!div_gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-fixup-div.c b/drivers/clk/imx/clk-fixup-div.c index aa6addbeb5a8..3866319af54e 100644 --- a/drivers/clk/imx/clk-fixup-div.c +++ b/drivers/clk/imx/clk-fixup-div.c @@ -97,7 +97,7 @@ struct clk_hw *imx_clk_hw_fixup_divider(const char *name, const char *parent, if (!fixup) return ERR_PTR(-EINVAL); - fixup_div = kzalloc(sizeof(*fixup_div), GFP_KERNEL); + fixup_div = kzalloc_obj(*fixup_div); if (!fixup_div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-fixup-mux.c b/drivers/clk/imx/clk-fixup-mux.c index 418ac9fe2c26..7188cdad79d3 100644 --- a/drivers/clk/imx/clk-fixup-mux.c +++ b/drivers/clk/imx/clk-fixup-mux.c @@ -77,7 +77,7 @@ struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg, if (!fixup) return ERR_PTR(-EINVAL); - fixup_mux = kzalloc(sizeof(*fixup_mux), GFP_KERNEL); + fixup_mux = kzalloc_obj(*fixup_mux); if (!fixup_mux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-frac-pll.c b/drivers/clk/imx/clk-frac-pll.c index eb668faaa38f..cd4e26bac19c 100644 --- a/drivers/clk/imx/clk-frac-pll.c +++ b/drivers/clk/imx/clk-frac-pll.c @@ -213,7 +213,7 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name, struct clk_hw *hw; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-fracn-gppll.c b/drivers/clk/imx/clk-fracn-gppll.c index 090d60867250..89ed7749bf47 100644 --- a/drivers/clk/imx/clk-fracn-gppll.c +++ b/drivers/clk/imx/clk-fracn-gppll.c @@ -88,7 +88,9 @@ static const struct imx_fracn_gppll_rate_table fracn_tbl[] = { PLL_FRACN_GP(445333333U, 167, 0, 1, 0, 9), PLL_FRACN_GP(400000000U, 200, 0, 1, 0, 12), PLL_FRACN_GP(393216000U, 163, 84, 100, 0, 10), - PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12) + PLL_FRACN_GP(332600000U, 138, 584, 1000, 0, 10), + PLL_FRACN_GP(300000000U, 150, 0, 1, 0, 12), + PLL_FRACN_GP(241900000U, 201, 584, 1000, 0, 20), }; struct imx_fracn_gppll_clk imx_fracn_gppll = { @@ -364,7 +366,7 @@ static struct clk_hw *_imx_clk_fracn_gppll(const char *name, const char *parent_ struct clk_init_data init; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-gate-93.c b/drivers/clk/imx/clk-gate-93.c index ceb56b290394..7acbcfec9610 100644 --- a/drivers/clk/imx/clk-gate-93.c +++ b/drivers/clk/imx/clk-gate-93.c @@ -164,7 +164,7 @@ struct clk_hw *imx93_clk_gate(struct device *dev, const char *name, const char * int ret; u32 authen; - gate = kzalloc(sizeof(struct imx93_clk_gate), GFP_KERNEL); + gate = kzalloc_obj(struct imx93_clk_gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-gate-exclusive.c b/drivers/clk/imx/clk-gate-exclusive.c index 7017e9d4e188..504cfeef28a0 100644 --- a/drivers/clk/imx/clk-gate-exclusive.c +++ b/drivers/clk/imx/clk-gate-exclusive.c @@ -67,7 +67,7 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent, if (exclusive_mask == 0) return ERR_PTR(-EINVAL); - exgate = kzalloc(sizeof(*exgate), GFP_KERNEL); + exgate = kzalloc_obj(*exgate); if (!exgate) return ERR_PTR(-ENOMEM); gate = &exgate->gate; diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index f16c4019f402..f07cf82dd9c9 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -144,7 +144,7 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name, struct clk_init_data init; int ret; - gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL); + gate = kzalloc_obj(struct clk_gate2); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-gpr-mux.c b/drivers/clk/imx/clk-gpr-mux.c index 0e14b61cba84..27b9a6e26997 100644 --- a/drivers/clk/imx/clk-gpr-mux.c +++ b/drivers/clk/imx/clk-gpr-mux.c @@ -87,7 +87,7 @@ struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible, return ERR_CAST(regmap); } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c index bf4c1d9c9928..f726c00aba72 100644 --- a/drivers/clk/imx/clk-imx6q.c +++ b/drivers/clk/imx/clk-imx6q.c @@ -439,8 +439,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) void __iomem *anatop_base, *base; int ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX6QDL_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX6QDL_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx6sl.c b/drivers/clk/imx/clk-imx6sl.c index 47b8667cfa3f..49639ad8f0b3 100644 --- a/drivers/clk/imx/clk-imx6sl.c +++ b/drivers/clk/imx/clk-imx6sl.c @@ -185,8 +185,7 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node) void __iomem *base; int ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX6SL_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX6SL_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c index 2fa70bf35e45..aa9e93a6af7b 100644 --- a/drivers/clk/imx/clk-imx6sll.c +++ b/drivers/clk/imx/clk-imx6sll.c @@ -81,8 +81,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node) struct device_node *np; void __iomem *base; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX6SLL_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX6SLL_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx6sx.c b/drivers/clk/imx/clk-imx6sx.c index 69f8f6f9ca49..a7266e20258d 100644 --- a/drivers/clk/imx/clk-imx6sx.c +++ b/drivers/clk/imx/clk-imx6sx.c @@ -123,8 +123,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) void __iomem *base; bool lcdif1_assigned_clk; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX6SX_CLK_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX6SX_CLK_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c index 05c7a82b751f..c14856e3040f 100644 --- a/drivers/clk/imx/clk-imx6ul.c +++ b/drivers/clk/imx/clk-imx6ul.c @@ -130,8 +130,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node) struct device_node *np; void __iomem *base; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX6UL_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX6UL_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c index 99adc55e3f5d..ebf482bfca7a 100644 --- a/drivers/clk/imx/clk-imx7d.c +++ b/drivers/clk/imx/clk-imx7d.c @@ -382,8 +382,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) struct device_node *np; void __iomem *base; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX7D_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX7D_CLK_END); if (WARN_ON(!clk_hw_data)) return; diff --git a/drivers/clk/imx/clk-imx7ulp.c b/drivers/clk/imx/clk-imx7ulp.c index f4a48a42637f..5c333da15077 100644 --- a/drivers/clk/imx/clk-imx7ulp.c +++ b/drivers/clk/imx/clk-imx7ulp.c @@ -49,8 +49,7 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np) struct clk_hw **hws; void __iomem *base; - clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, IMX7ULP_CLK_SCG1_END); if (!clk_data) return; @@ -138,8 +137,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np) struct clk_hw **hws; void __iomem *base; - clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC2_END), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, IMX7ULP_CLK_PCC2_END); if (!clk_data) return; @@ -186,8 +184,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np) struct clk_hw **hws; void __iomem *base; - clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_PCC3_END), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, IMX7ULP_CLK_PCC3_END); if (!clk_data) return; @@ -233,8 +230,7 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np) struct clk_hw **hws; void __iomem *base; - clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, IMX7ULP_CLK_SMC1_END); if (!clk_data) return; diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c index 342049b847b9..319af4deec01 100644 --- a/drivers/clk/imx/clk-imx8mm.c +++ b/drivers/clk/imx/clk-imx8mm.c @@ -303,8 +303,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev) void __iomem *base; int ret; - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, - IMX8MM_CLK_END), GFP_KERNEL); + clk_hw_data = kzalloc_flex(*clk_hw_data, hws, IMX8MM_CLK_END); if (WARN_ON(!clk_hw_data)) return -ENOMEM; diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c index 3ae162625bb1..c781425a005e 100644 --- a/drivers/clk/imx/clk-imx8qxp.c +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -346,7 +346,29 @@ static struct platform_driver imx8qxp_clk_driver = { }, .probe = imx8qxp_clk_probe, }; -module_platform_driver(imx8qxp_clk_driver); + +static int __init imx8qxp_clk_init(void) +{ + int ret; + + ret = platform_driver_register(&imx8qxp_clk_driver); + if (ret) + return ret; + + ret = imx_clk_scu_module_init(); + if (ret) + platform_driver_unregister(&imx8qxp_clk_driver); + + return ret; +} +module_init(imx8qxp_clk_init); + +static void __exit imx8qxp_clk_exit(void) +{ + imx_clk_scu_module_exit(); + platform_driver_unregister(&imx8qxp_clk_driver); +} +module_exit(imx8qxp_clk_exit); MODULE_AUTHOR("Aisheng Dong "); MODULE_DESCRIPTION("NXP i.MX8QXP clock driver"); diff --git a/drivers/clk/imx/clk-lpcg-scu.c b/drivers/clk/imx/clk-lpcg-scu.c index 6376557a3c3d..03bbfbe9bff3 100644 --- a/drivers/clk/imx/clk-lpcg-scu.c +++ b/drivers/clk/imx/clk-lpcg-scu.c @@ -119,7 +119,7 @@ struct clk_hw *__imx_clk_lpcg_scu(struct device *dev, const char *name, struct clk_hw *hw; int ret; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pfd.c b/drivers/clk/imx/clk-pfd.c index 31220fa7882b..e7a5d80c5008 100644 --- a/drivers/clk/imx/clk-pfd.c +++ b/drivers/clk/imx/clk-pfd.c @@ -132,7 +132,7 @@ struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name, struct clk_init_data init; int ret; - pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); + pfd = kzalloc_obj(*pfd); if (!pfd) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pfdv2.c b/drivers/clk/imx/clk-pfdv2.c index 6ca53a960eb7..0f92b92e2229 100644 --- a/drivers/clk/imx/clk-pfdv2.c +++ b/drivers/clk/imx/clk-pfdv2.c @@ -210,7 +210,7 @@ struct clk_hw *imx_clk_hw_pfdv2(enum imx_pfdv2_type type, const char *name, WARN_ON(idx > 3); - pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); + pfd = kzalloc_obj(*pfd); if (!pfd) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c index 36d0e80b55b8..7552aaafc339 100644 --- a/drivers/clk/imx/clk-pll14xx.c +++ b/drivers/clk/imx/clk-pll14xx.c @@ -504,7 +504,7 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name, int ret; u32 val; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pllv1.c b/drivers/clk/imx/clk-pllv1.c index 93ee81b28fc7..da5531e57da2 100644 --- a/drivers/clk/imx/clk-pllv1.c +++ b/drivers/clk/imx/clk-pllv1.c @@ -119,7 +119,7 @@ struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name, struct clk_init_data init; int ret; - pll = kmalloc(sizeof(*pll), GFP_KERNEL); + pll = kmalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pllv2.c b/drivers/clk/imx/clk-pllv2.c index bb497ad5e0ae..43396388030e 100644 --- a/drivers/clk/imx/clk-pllv2.c +++ b/drivers/clk/imx/clk-pllv2.c @@ -254,7 +254,7 @@ struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent, struct clk_init_data init; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c index b99508367bcb..a0ad6f4aae8f 100644 --- a/drivers/clk/imx/clk-pllv3.c +++ b/drivers/clk/imx/clk-pllv3.c @@ -426,7 +426,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name, struct clk_init_data init; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-pllv4.c b/drivers/clk/imx/clk-pllv4.c index 01d05b5d5438..8fa2f7111ce9 100644 --- a/drivers/clk/imx/clk-pllv4.c +++ b/drivers/clk/imx/clk-pllv4.c @@ -251,7 +251,7 @@ struct clk_hw *imx_clk_hw_pllv4(enum imx_pllv4_type type, const char *name, struct clk_init_data init; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-scu.c b/drivers/clk/imx/clk-scu.c index 34c9dc1fb20e..a85ec48a798b 100644 --- a/drivers/clk/imx/clk-scu.c +++ b/drivers/clk/imx/clk-scu.c @@ -191,6 +191,16 @@ static bool imx_scu_clk_is_valid(u32 rsrc_id) return p != NULL; } +int __init imx_clk_scu_module_init(void) +{ + return platform_driver_register(&imx_clk_scu_driver); +} + +void __exit imx_clk_scu_module_exit(void) +{ + return platform_driver_unregister(&imx_clk_scu_driver); +} + int imx_clk_scu_init(struct device_node *np, const struct imx_clk_scu_rsrc_table *data) { @@ -215,7 +225,7 @@ int imx_clk_scu_init(struct device_node *np, rsrc_table = data; } - return platform_driver_register(&imx_clk_scu_driver); + return 0; } /* @@ -457,7 +467,7 @@ struct clk_hw *__imx_clk_scu(struct device *dev, const char *name, struct clk_hw *hw; int ret; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); @@ -856,7 +866,7 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na if (rsrc_id >= IMX_SC_R_LAST || gpr_id >= IMX_SC_C_LAST) return ERR_PTR(-EINVAL); - clk_node = kzalloc(sizeof(*clk_node), GFP_KERNEL); + clk_node = kzalloc_obj(*clk_node); if (!clk_node) return ERR_PTR(-ENOMEM); @@ -870,7 +880,7 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na return NULL; } - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) { kfree(clk_node); return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk-scu.h b/drivers/clk/imx/clk-scu.h index af7b697f51ca..ca82f2cce897 100644 --- a/drivers/clk/imx/clk-scu.h +++ b/drivers/clk/imx/clk-scu.h @@ -25,6 +25,8 @@ extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl; extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp; extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm; +int __init imx_clk_scu_module_init(void); +void __exit imx_clk_scu_module_exit(void); int imx_clk_scu_init(struct device_node *np, const struct imx_clk_scu_rsrc_table *data); struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec, diff --git a/drivers/clk/imx/clk-sscg-pll.c b/drivers/clk/imx/clk-sscg-pll.c index 81f304fae908..7f104ecfa80f 100644 --- a/drivers/clk/imx/clk-sscg-pll.c +++ b/drivers/clk/imx/clk-sscg-pll.c @@ -509,7 +509,7 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name, struct clk_hw *hw; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index df83bd939492..f38506830ccf 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -189,7 +189,7 @@ void imx_register_uart_clocks(void) if (!of_stdout) return; - imx_uart_clocks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL); + imx_uart_clocks = kzalloc_objs(struct clk *, num); if (!imx_uart_clocks) return; diff --git a/drivers/clk/ingenic/cgu.c b/drivers/clk/ingenic/cgu.c index 91e7ac0cc334..41e4c69131bd 100644 --- a/drivers/clk/ingenic/cgu.c +++ b/drivers/clk/ingenic/cgu.c @@ -676,7 +676,7 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx) goto out; } - ingenic_clk = kzalloc(sizeof(*ingenic_clk), GFP_KERNEL); + ingenic_clk = kzalloc_obj(*ingenic_clk); if (!ingenic_clk) { err = -ENOMEM; goto out; @@ -790,7 +790,7 @@ ingenic_cgu_new(const struct ingenic_cgu_clk_info *clock_info, { struct ingenic_cgu *cgu; - cgu = kzalloc(sizeof(*cgu), GFP_KERNEL); + cgu = kzalloc_obj(*cgu); if (!cgu) goto err_out; @@ -819,8 +819,7 @@ int ingenic_cgu_register_clocks(struct ingenic_cgu *cgu) unsigned i; int err; - cgu->clocks.clks = kcalloc(cgu->clocks.clk_num, sizeof(struct clk *), - GFP_KERNEL); + cgu->clocks.clks = kzalloc_objs(struct clk *, cgu->clocks.clk_num); if (!cgu->clocks.clks) { err = -ENOMEM; goto err_out; diff --git a/drivers/clk/ingenic/tcu.c b/drivers/clk/ingenic/tcu.c index bc6a51da2072..678446251cd6 100644 --- a/drivers/clk/ingenic/tcu.c +++ b/drivers/clk/ingenic/tcu.c @@ -273,7 +273,7 @@ static int __init ingenic_tcu_register_clock(struct ingenic_tcu *tcu, struct ingenic_tcu_clk *tcu_clk; int err; - tcu_clk = kzalloc(sizeof(*tcu_clk), GFP_KERNEL); + tcu_clk = kzalloc_obj(*tcu_clk); if (!tcu_clk) return -ENOMEM; @@ -344,7 +344,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) if (IS_ERR(map)) return PTR_ERR(map); - tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); + tcu = kzalloc_obj(*tcu); if (!tcu) return -ENOMEM; @@ -379,8 +379,7 @@ static int __init ingenic_tcu_probe(struct device_node *np) } } - tcu->clocks = kzalloc(struct_size(tcu->clocks, hws, TCU_CLK_COUNT), - GFP_KERNEL); + tcu->clocks = kzalloc_flex(*tcu->clocks, hws, TCU_CLK_COUNT); if (!tcu->clocks) { ret = -ENOMEM; goto err_clk_disable; diff --git a/drivers/clk/keystone/gate.c b/drivers/clk/keystone/gate.c index 13ea047489eb..03e854f10fd9 100644 --- a/drivers/clk/keystone/gate.c +++ b/drivers/clk/keystone/gate.c @@ -168,7 +168,7 @@ static struct clk *clk_register_psc(struct device *dev, struct clk_psc *psc; struct clk *clk; - psc = kzalloc(sizeof(*psc), GFP_KERNEL); + psc = kzalloc_obj(*psc); if (!psc) return ERR_PTR(-ENOMEM); @@ -202,7 +202,7 @@ static void __init of_psc_clk_init(struct device_node *node, spinlock_t *lock) struct clk *clk; int i; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { pr_err("%s: Out of memory\n", __func__); return; diff --git a/drivers/clk/keystone/pll.c b/drivers/clk/keystone/pll.c index 6bbdd4705d71..ed197ee0cc88 100644 --- a/drivers/clk/keystone/pll.c +++ b/drivers/clk/keystone/pll.c @@ -126,7 +126,7 @@ static struct clk *clk_register_pll(struct device *dev, struct clk_pll *pll; struct clk *clk; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -162,7 +162,7 @@ static void __init _of_pll_clk_init(struct device_node *node, bool pllctrl) struct clk *clk; int i; - pll_data = kzalloc(sizeof(*pll_data), GFP_KERNEL); + pll_data = kzalloc_obj(*pll_data); if (!pll_data) { pr_err("%s: Out of memory\n", __func__); return; diff --git a/drivers/clk/mediatek/Kconfig b/drivers/clk/mediatek/Kconfig index 0e8dd82aa84e..2c09fd729bab 100644 --- a/drivers/clk/mediatek/Kconfig +++ b/drivers/clk/mediatek/Kconfig @@ -820,7 +820,7 @@ config COMMON_CLK_MT8192 depends on ARM64 || COMPILE_TEST select COMMON_CLK_MEDIATEK select COMMON_CLK_MEDIATEK_FHCTL - default ARM64 + default ARM64 && ARCH_MEDIATEK help This driver supports MediaTek MT8192 basic clocks. diff --git a/drivers/clk/mediatek/clk-apmixed.c b/drivers/clk/mediatek/clk-apmixed.c index 60e34f124250..16e8a325b5bf 100644 --- a/drivers/clk/mediatek/clk-apmixed.c +++ b/drivers/clk/mediatek/clk-apmixed.c @@ -77,7 +77,7 @@ struct clk_hw *mtk_clk_register_ref2usb_tx(const char *name, struct clk_init_data init = {}; int ret; - tx = kzalloc(sizeof(*tx), GFP_KERNEL); + tx = kzalloc_obj(*tx); if (!tx) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c index a03826db4dcb..412558b95127 100644 --- a/drivers/clk/mediatek/clk-cpumux.c +++ b/drivers/clk/mediatek/clk-cpumux.c @@ -66,7 +66,7 @@ mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux, int ret; struct clk_init_data init; - cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL); + cpumux = kzalloc_obj(*cpumux); if (!cpumux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c index f6b1429ff757..bd2fcd489a3f 100644 --- a/drivers/clk/mediatek/clk-gate.c +++ b/drivers/clk/mediatek/clk-gate.c @@ -212,7 +212,7 @@ static struct clk_hw *mtk_clk_register_gate(struct device *dev, int ret; struct clk_init_data init = {}; - cg = kzalloc(sizeof(*cg), GFP_KERNEL); + cg = kzalloc_obj(*cg); if (!cg) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mediatek/clk-mt2701.c b/drivers/clk/mediatek/clk-mt2701.c index 1e88ad8b93f4..d9f40fda73d1 100644 --- a/drivers/clk/mediatek/clk-mt2701.c +++ b/drivers/clk/mediatek/clk-mt2701.c @@ -978,7 +978,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls), + mtk_clk_register_plls(&pdev->dev, apmixed_plls, ARRAY_SIZE(apmixed_plls), clk_data); mtk_clk_register_factors(apmixed_fixed_divs, ARRAY_SIZE(apmixed_fixed_divs), clk_data); diff --git a/drivers/clk/mediatek/clk-mt2712-apmixedsys.c b/drivers/clk/mediatek/clk-mt2712-apmixedsys.c index a60622d251ff..54b18e9f83f8 100644 --- a/drivers/clk/mediatek/clk-mt2712-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt2712-apmixedsys.c @@ -119,7 +119,7 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c index e0949911e8f7..9e30c089a209 100644 --- a/drivers/clk/mediatek/clk-mt6735-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt6735-apmixedsys.c @@ -93,8 +93,8 @@ static int clk_mt6735_apmixed_probe(struct platform_device *pdev) return -ENOMEM; platform_set_drvdata(pdev, clk_data); - ret = mtk_clk_register_plls(pdev->dev.of_node, apmixedsys_plls, - ARRAY_SIZE(apmixedsys_plls), clk_data); + ret = mtk_clk_register_plls(&pdev->dev, apmixedsys_plls, + ARRAY_SIZE(apmixedsys_plls), clk_data); if (ret) { dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret); return ret; diff --git a/drivers/clk/mediatek/clk-mt6765.c b/drivers/clk/mediatek/clk-mt6765.c index d53731e7933f..60f6f9fa7dcf 100644 --- a/drivers/clk/mediatek/clk-mt6765.c +++ b/drivers/clk/mediatek/clk-mt6765.c @@ -740,7 +740,7 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); diff --git a/drivers/clk/mediatek/clk-mt6779.c b/drivers/clk/mediatek/clk-mt6779.c index 86732f5acf93..4b9dcb910b03 100644 --- a/drivers/clk/mediatek/clk-mt6779.c +++ b/drivers/clk/mediatek/clk-mt6779.c @@ -1220,7 +1220,7 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, ARRAY_SIZE(apmixed_clks), clk_data); diff --git a/drivers/clk/mediatek/clk-mt6795-apmixedsys.c b/drivers/clk/mediatek/clk-mt6795-apmixedsys.c index 91665d7f125e..123d5d7fea85 100644 --- a/drivers/clk/mediatek/clk-mt6795-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt6795-apmixedsys.c @@ -152,7 +152,7 @@ static int clk_mt6795_apmixed_probe(struct platform_device *pdev) return -ENOMEM; fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - ret = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + ret = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (ret) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt6797.c b/drivers/clk/mediatek/clk-mt6797.c index fb59e71af58e..ebf850ac57f5 100644 --- a/drivers/clk/mediatek/clk-mt6797.c +++ b/drivers/clk/mediatek/clk-mt6797.c @@ -655,7 +655,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); } diff --git a/drivers/clk/mediatek/clk-mt7622-apmixedsys.c b/drivers/clk/mediatek/clk-mt7622-apmixedsys.c index 2350592d9a93..8a29eaab0cfc 100644 --- a/drivers/clk/mediatek/clk-mt7622-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt7622-apmixedsys.c @@ -96,7 +96,7 @@ static int clk_mt7622_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt7629.c b/drivers/clk/mediatek/clk-mt7629.c index baf94e7bea37..e154771b1b8b 100644 --- a/drivers/clk/mediatek/clk-mt7629.c +++ b/drivers/clk/mediatek/clk-mt7629.c @@ -634,7 +634,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); mtk_clk_register_gates(&pdev->dev, node, apmixed_clks, diff --git a/drivers/clk/mediatek/clk-mt7981-apmixed.c b/drivers/clk/mediatek/clk-mt7981-apmixed.c index e8211eb4e09e..6606b54fb376 100644 --- a/drivers/clk/mediatek/clk-mt7981-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7981-apmixed.c @@ -76,7 +76,7 @@ static int clk_mt7981_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (r) { diff --git a/drivers/clk/mediatek/clk-mt7981-eth.c b/drivers/clk/mediatek/clk-mt7981-eth.c index 906aec9ddff5..0655ebb6c561 100644 --- a/drivers/clk/mediatek/clk-mt7981-eth.c +++ b/drivers/clk/mediatek/clk-mt7981-eth.c @@ -31,7 +31,7 @@ static const struct mtk_gate_regs sgmii0_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate sgmii0_clks[] __initconst = { +static const struct mtk_gate sgmii0_clks[] = { GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2), GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3), GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4), @@ -53,7 +53,7 @@ static const struct mtk_gate_regs sgmii1_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate sgmii1_clks[] __initconst = { +static const struct mtk_gate sgmii1_clks[] = { GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2), GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3), GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4), @@ -75,7 +75,7 @@ static const struct mtk_gate_regs eth_cg_regs = { .ops = &mtk_clk_gate_ops_no_setclr_inv, \ } -static const struct mtk_gate eth_clks[] __initconst = { +static const struct mtk_gate eth_clks[] = { GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6), GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7), GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8), diff --git a/drivers/clk/mediatek/clk-mt7986-apmixed.c b/drivers/clk/mediatek/clk-mt7986-apmixed.c index 93751abe6be8..1c79418d08a7 100644 --- a/drivers/clk/mediatek/clk-mt7986-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7986-apmixed.c @@ -74,7 +74,7 @@ static int clk_mt7986_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); if (r) { diff --git a/drivers/clk/mediatek/clk-mt7988-apmixed.c b/drivers/clk/mediatek/clk-mt7988-apmixed.c index 63d33a78cb48..416a4b88d100 100644 --- a/drivers/clk/mediatek/clk-mt7988-apmixed.c +++ b/drivers/clk/mediatek/clk-mt7988-apmixed.c @@ -86,7 +86,7 @@ static int clk_mt7988_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8135-apmixedsys.c b/drivers/clk/mediatek/clk-mt8135-apmixedsys.c index bdadc35c64cb..19e4ee489ec3 100644 --- a/drivers/clk/mediatek/clk-mt8135-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8135-apmixedsys.c @@ -57,7 +57,8 @@ static int clk_mt8135_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), + clk_data); if (ret) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8167-apmixedsys.c b/drivers/clk/mediatek/clk-mt8167-apmixedsys.c index adf576786696..fb6c21bbeef8 100644 --- a/drivers/clk/mediatek/clk-mt8167-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8167-apmixedsys.c @@ -105,7 +105,7 @@ static int clk_mt8167_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c index 95385bb67d55..d7d416172ab3 100644 --- a/drivers/clk/mediatek/clk-mt8173-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8173-apmixedsys.c @@ -140,13 +140,13 @@ MODULE_DEVICE_TABLE(of, of_match_clk_mt8173_apmixed); static int clk_mt8173_apmixed_probe(struct platform_device *pdev) { const u8 *fhctl_node = "mediatek,mt8173-fhctl"; - struct device_node *node = pdev->dev.of_node; struct clk_hw_onecell_data *clk_data; + struct device *dev = &pdev->dev; void __iomem *base; struct clk_hw *hw; int r; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) return -ENOMEM; @@ -157,25 +157,25 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev) } fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), - pllfhs, ARRAY_SIZE(pllfhs), clk_data); + r = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls), pllfhs, + ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_clk_data; hw = mtk_clk_register_ref2usb_tx("ref2usb_tx", "clk26m", base + REGOFF_REF2USB); if (IS_ERR(hw)) { r = PTR_ERR(hw); - dev_err(&pdev->dev, "Failed to register ref2usb_tx: %d\n", r); + dev_err(dev, "Failed to register ref2usb_tx: %d\n", r); goto unregister_plls; } clk_data->hws[CLK_APMIXED_REF2USB_TX] = hw; - hw = devm_clk_hw_register_divider(&pdev->dev, "hdmi_ref", "tvdpll_594m", 0, + hw = devm_clk_hw_register_divider(dev, "hdmi_ref", "tvdpll_594m", 0, base + REGOFF_HDMI_REF, 16, 3, CLK_DIVIDER_POWER_OF_TWO, NULL); clk_data->hws[CLK_APMIXED_HDMI_REF] = hw; - r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); + r = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clk_data); if (r) goto unregister_ref2usb; diff --git a/drivers/clk/mediatek/clk-mt8183-apmixedsys.c b/drivers/clk/mediatek/clk-mt8183-apmixedsys.c index 551adbfd7ac9..6242d4f5376e 100644 --- a/drivers/clk/mediatek/clk-mt8183-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8183-apmixedsys.c @@ -155,7 +155,7 @@ static int clk_mt8183_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8186-apmixedsys.c b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c index 4b2b16578232..d35dd2632e43 100644 --- a/drivers/clk/mediatek/clk-mt8186-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8186-apmixedsys.c @@ -151,7 +151,7 @@ static int clk_mt8186_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8188-apmixedsys.c b/drivers/clk/mediatek/clk-mt8188-apmixedsys.c index 21d7a9a2ab1a..a1de596bff99 100644 --- a/drivers/clk/mediatek/clk-mt8188-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8188-apmixedsys.c @@ -106,7 +106,7 @@ static int clk_mt8188_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8192-apmixedsys.c b/drivers/clk/mediatek/clk-mt8192-apmixedsys.c index 0b66a27e4d5a..b0563a285bd6 100644 --- a/drivers/clk/mediatek/clk-mt8192-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8192-apmixedsys.c @@ -162,7 +162,7 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c index 282a3137dc89..44917ab034c5 100644 --- a/drivers/clk/mediatek/clk-mt8195-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8195-apmixedsys.c @@ -181,7 +181,7 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev) fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs)); - r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls), + r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls), pllfhs, ARRAY_SIZE(pllfhs), clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c index 8b45a3fad02f..a2d98ed58e34 100644 --- a/drivers/clk/mediatek/clk-mt8195-apusys_pll.c +++ b/drivers/clk/mediatek/clk-mt8195-apusys_pll.c @@ -66,7 +66,8 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data); + r = mtk_clk_register_plls(&pdev->dev, apusys_plls, + ARRAY_SIZE(apusys_plls), clk_data); if (r) goto free_apusys_pll_data; diff --git a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c index 617f5449b88b..c4ebb0170b82 100644 --- a/drivers/clk/mediatek/clk-mt8196-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8196-apmixedsys.c @@ -152,7 +152,8 @@ static int clk_mt8196_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, mcd->clks, mcd->num_clks, clk_data); + r = mtk_clk_register_plls(&pdev->dev, mcd->clks, mcd->num_clks, + clk_data); if (r) goto free_apmixed_data; diff --git a/drivers/clk/mediatek/clk-mt8196-mcu.c b/drivers/clk/mediatek/clk-mt8196-mcu.c index 5cbcc411ae73..13642fc673c2 100644 --- a/drivers/clk/mediatek/clk-mt8196-mcu.c +++ b/drivers/clk/mediatek/clk-mt8196-mcu.c @@ -122,7 +122,7 @@ static int clk_mt8196_mcu_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8196-mfg.c b/drivers/clk/mediatek/clk-mt8196-mfg.c index ae1eb9de79ae..a317183f1681 100644 --- a/drivers/clk/mediatek/clk-mt8196-mfg.c +++ b/drivers/clk/mediatek/clk-mt8196-mfg.c @@ -58,24 +58,25 @@ .pcw_shift = _pcw_shift, \ .pcwbits = _pcwbits, \ .pcwibits = MT8196_INTEGER_BITS, \ + .parent_name = "mfg_eb", \ } static const struct mtk_pll_data mfg_ao_plls[] = { - PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, 0, - BIT(0), MFGPLL_CON1, 24, 0, 0, 0, + PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, + PLL_PARENT_EN, BIT(0), MFGPLL_CON1, 24, 0, 0, 0, MFGPLL_CON1, 0, 22), }; static const struct mtk_pll_data mfgsc0_ao_plls[] = { PLL(CLK_MFGSC0_AO_MFGPLL_SC0, "mfgpll-sc0", MFGPLL_SC0_CON0, - MFGPLL_SC0_CON0, 0, 0, 0, BIT(0), MFGPLL_SC0_CON1, 24, 0, 0, 0, - MFGPLL_SC0_CON1, 0, 22), + MFGPLL_SC0_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC0_CON1, 24, + 0, 0, 0, MFGPLL_SC0_CON1, 0, 22), }; static const struct mtk_pll_data mfgsc1_ao_plls[] = { PLL(CLK_MFGSC1_AO_MFGPLL_SC1, "mfgpll-sc1", MFGPLL_SC1_CON0, - MFGPLL_SC1_CON0, 0, 0, 0, BIT(0), MFGPLL_SC1_CON1, 24, 0, 0, 0, - MFGPLL_SC1_CON1, 0, 22), + MFGPLL_SC1_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC1_CON1, 24, + 0, 0, 0, MFGPLL_SC1_CON1, 0, 22), }; static const struct of_device_id of_match_clk_mt8196_mfg[] = { @@ -105,7 +106,7 @@ static int clk_mt8196_mfg_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - r = mtk_clk_register_plls(node, plls, num_plls, clk_data); + r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data); if (r) goto free_clk_data; diff --git a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c index d59a8a9d9855..7dcc164627c5 100644 --- a/drivers/clk/mediatek/clk-mt8196-vlpckgen.c +++ b/drivers/clk/mediatek/clk-mt8196-vlpckgen.c @@ -664,7 +664,7 @@ static int clk_mt8196_vlp_probe(struct platform_device *pdev) if (r) goto unregister_factors; - r = mtk_clk_register_plls(node, vlp_plls, ARRAY_SIZE(vlp_plls), + r = mtk_clk_register_plls(dev, vlp_plls, ARRAY_SIZE(vlp_plls), clk_data); if (r) goto unregister_muxes; diff --git a/drivers/clk/mediatek/clk-mt8365-apmixedsys.c b/drivers/clk/mediatek/clk-mt8365-apmixedsys.c index f41b991a0178..e331aa28a4bd 100644 --- a/drivers/clk/mediatek/clk-mt8365-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8365-apmixedsys.c @@ -133,7 +133,7 @@ static int clk_mt8365_apmixed_probe(struct platform_device *pdev) return PTR_ERR(hw); clk_data->hws[CLK_APMIXED_USB20_EN] = hw; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8516-apmixedsys.c b/drivers/clk/mediatek/clk-mt8516-apmixedsys.c index edd9174d2f2f..2a6206cae2f0 100644 --- a/drivers/clk/mediatek/clk-mt8516-apmixedsys.c +++ b/drivers/clk/mediatek/clk-mt8516-apmixedsys.c @@ -87,7 +87,7 @@ static int clk_mt8516_apmixed_probe(struct platform_device *pdev) if (!clk_data) return -ENOMEM; - ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); + ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data); if (ret) return ret; diff --git a/drivers/clk/mediatek/clk-mt8516.c b/drivers/clk/mediatek/clk-mt8516.c index 21eb052b0a53..342a59019fea 100644 --- a/drivers/clk/mediatek/clk-mt8516.c +++ b/drivers/clk/mediatek/clk-mt8516.c @@ -544,7 +544,7 @@ static const struct mtk_gate_regs top5_cg_regs = { #define GATE_TOP5(_id, _name, _parent, _shift) \ GATE_MTK(_id, _name, _parent, &top5_cg_regs, _shift, &mtk_clk_gate_ops_setclr) -static const struct mtk_gate top_clks[] __initconst = { +static const struct mtk_gate top_clks[] = { /* TOP1 */ GATE_TOP1(CLK_TOP_THEM, "them", "ahb_infra_sel", 1), GATE_TOP1(CLK_TOP_APDMA, "apdma", "ahb_infra_sel", 2), diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c index 19cd27941747..3dfdd3a422f8 100644 --- a/drivers/clk/mediatek/clk-mtk.c +++ b/drivers/clk/mediatek/clk-mtk.c @@ -67,7 +67,7 @@ struct clk_hw_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) { struct clk_hw_onecell_data *clk_data; - clk_data = kzalloc(struct_size(clk_data, hws, clk_num), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, clk_num); if (!clk_data) return NULL; @@ -230,7 +230,7 @@ static struct clk_hw *mtk_clk_register_composite(struct device *dev, int ret; if (mc->mux_shift >= 0) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -251,7 +251,7 @@ static struct clk_hw *mtk_clk_register_composite(struct device *dev, } if (mc->gate_shift >= 0) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { ret = -ENOMEM; goto err_out; @@ -267,7 +267,7 @@ static struct clk_hw *mtk_clk_register_composite(struct device *dev, } if (mc->divider_shift >= 0) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) { ret = -ENOMEM; goto err_out; @@ -497,14 +497,16 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev, if (mcd->need_runtime_pm) { - devm_pm_runtime_enable(&pdev->dev); + r = devm_pm_runtime_enable(&pdev->dev); + if (r) + goto unmap_io; /* * Do a pm_runtime_resume_and_get() to workaround a possible * deadlock between clk_register() and the genpd framework. */ r = pm_runtime_resume_and_get(&pdev->dev); if (r) - return r; + goto unmap_io; } /* Calculate how many clk_hw_onecell_data entries to allocate */ @@ -618,11 +620,11 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev, free_data: mtk_free_clk_data(clk_data); free_base: - if (mcd->shared_io && base) - iounmap(base); - if (mcd->need_runtime_pm) pm_runtime_put(&pdev->dev); +unmap_io: + if (mcd->shared_io && base) + iounmap(base); return r; } diff --git a/drivers/clk/mediatek/clk-mux.c b/drivers/clk/mediatek/clk-mux.c index c5af6dc078a3..5f4b07e7c757 100644 --- a/drivers/clk/mediatek/clk-mux.c +++ b/drivers/clk/mediatek/clk-mux.c @@ -281,7 +281,7 @@ static struct clk_hw *mtk_clk_register_mux(struct device *dev, struct clk_init_data init = {}; int ret; - clk_mux = kzalloc(sizeof(*clk_mux), GFP_KERNEL); + clk_mux = kzalloc_obj(*clk_mux); if (!clk_mux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c index cd2b6ce551c6..e97064868908 100644 --- a/drivers/clk/mediatek/clk-pll.c +++ b/drivers/clk/mediatek/clk-pll.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "clk-pll.h" @@ -358,6 +359,9 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, init.name = data->name; init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0; + if (data->flags & PLL_PARENT_EN) + init.flags |= CLK_OPS_PARENT_ENABLE; + init.ops = pll_ops; if (data->parent_name) init.parent_names = &data->parent_name; @@ -365,7 +369,7 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, init.parent_names = &parent_name; init.num_parents = 1; - ret = clk_hw_register(NULL, &pll->hw); + ret = clk_hw_register(pll->dev, &pll->hw); if (ret) return ERR_PTR(ret); @@ -373,17 +377,20 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, return &pll->hw; } -struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, +struct clk_hw *mtk_clk_register_pll(struct device *dev, + const struct mtk_pll_data *data, void __iomem *base) { struct mtk_clk_pll *pll; struct clk_hw *hw; const struct clk_ops *pll_ops = data->ops ? data->ops : &mtk_pll_ops; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); + pll->dev = dev; + hw = mtk_clk_register_pll_ops(pll, data, base, pll_ops); if (IS_ERR(hw)) kfree(pll); @@ -404,7 +411,7 @@ void mtk_clk_unregister_pll(struct clk_hw *hw) kfree(pll); } -int mtk_clk_register_plls(struct device_node *node, +int mtk_clk_register_plls(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct clk_hw_onecell_data *clk_data) { @@ -412,7 +419,7 @@ int mtk_clk_register_plls(struct device_node *node, int i; struct clk_hw *hw; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) { pr_err("%s(): ioremap failed\n", __func__); return -EINVAL; @@ -423,11 +430,11 @@ int mtk_clk_register_plls(struct device_node *node, if (!IS_ERR_OR_NULL(clk_data->hws[pll->id])) { pr_warn("%pOF: Trying to register duplicate clock ID: %d\n", - node, pll->id); + dev->of_node, pll->id); continue; } - hw = mtk_clk_register_pll(pll, base); + hw = mtk_clk_register_pll(dev, pll, base); if (IS_ERR(hw)) { pr_err("Failed to register clk %s: %pe\n", pll->name, diff --git a/drivers/clk/mediatek/clk-pll.h b/drivers/clk/mediatek/clk-pll.h index d71c150ce83e..f49dc2732ffe 100644 --- a/drivers/clk/mediatek/clk-pll.h +++ b/drivers/clk/mediatek/clk-pll.h @@ -10,9 +10,7 @@ #include #include -struct clk_ops; -struct clk_hw_onecell_data; -struct device_node; +struct device; struct mtk_pll_div_table { u32 div; @@ -21,6 +19,7 @@ struct mtk_pll_div_table { #define HAVE_RST_BAR BIT(0) #define PLL_AO BIT(1) +#define PLL_PARENT_EN BIT(2) #define POSTDIV_MASK GENMASK(2, 0) struct mtk_pll_data { @@ -63,6 +62,7 @@ struct mtk_pll_data { */ struct mtk_clk_pll { + struct device *dev; struct clk_hw hw; void __iomem *base_addr; void __iomem *pd_addr; @@ -78,9 +78,9 @@ struct mtk_clk_pll { const struct mtk_pll_data *data; }; -int mtk_clk_register_plls(struct device_node *node, - const struct mtk_pll_data *plls, int num_plls, - struct clk_hw_onecell_data *clk_data); +int mtk_clk_register_plls(struct device *dev, const struct mtk_pll_data *plls, + int num_plls, struct clk_hw_onecell_data *clk_data); + void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls, struct clk_hw_onecell_data *clk_data); @@ -110,7 +110,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll, const struct mtk_pll_data *data, void __iomem *base, const struct clk_ops *pll_ops); -struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data, +struct clk_hw *mtk_clk_register_pll(struct device *dev, + const struct mtk_pll_data *data, void __iomem *base); void mtk_clk_unregister_pll(struct clk_hw *hw); diff --git a/drivers/clk/mediatek/clk-pllfh.c b/drivers/clk/mediatek/clk-pllfh.c index 83630ee07ee9..aa95cd9197b3 100644 --- a/drivers/clk/mediatek/clk-pllfh.c +++ b/drivers/clk/mediatek/clk-pllfh.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "clk-mtk.h" #include "clk-pllfh.h" @@ -149,14 +150,14 @@ static bool fhctl_is_supported_and_enabled(const struct mtk_pllfh_data *pllfh) } static struct clk_hw * -mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data, +mtk_clk_register_pllfh(struct device *dev, const struct mtk_pll_data *pll_data, struct mtk_pllfh_data *pllfh_data, void __iomem *base) { struct clk_hw *hw; struct mtk_fh *fh; int ret; - fh = kzalloc(sizeof(*fh), GFP_KERNEL); + fh = kzalloc_obj(*fh); if (!fh) return ERR_PTR(-ENOMEM); @@ -166,6 +167,8 @@ mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data, goto out; } + fh->clk_pll.dev = dev; + hw = mtk_clk_register_pll_ops(&fh->clk_pll, pll_data, base, &mtk_pllfh_ops); @@ -194,7 +197,7 @@ static void mtk_clk_unregister_pllfh(struct clk_hw *hw) kfree(fh); } -int mtk_clk_register_pllfhs(struct device_node *node, +int mtk_clk_register_pllfhs(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_fhs, struct clk_hw_onecell_data *clk_data) @@ -203,7 +206,7 @@ int mtk_clk_register_pllfhs(struct device_node *node, int i; struct clk_hw *hw; - base = of_iomap(node, 0); + base = of_iomap(dev->of_node, 0); if (!base) { pr_err("%s(): ioremap failed\n", __func__); return -EINVAL; @@ -218,9 +221,9 @@ int mtk_clk_register_pllfhs(struct device_node *node, use_fhctl = fhctl_is_supported_and_enabled(pllfh); if (use_fhctl) - hw = mtk_clk_register_pllfh(pll, pllfh, base); + hw = mtk_clk_register_pllfh(dev, pll, pllfh, base); else - hw = mtk_clk_register_pll(pll, base); + hw = mtk_clk_register_pll(dev, pll, base); if (IS_ERR(hw)) { pr_err("Failed to register %s clk %s: %ld\n", diff --git a/drivers/clk/mediatek/clk-pllfh.h b/drivers/clk/mediatek/clk-pllfh.h index 5f419c2ec01f..a4f337acad71 100644 --- a/drivers/clk/mediatek/clk-pllfh.h +++ b/drivers/clk/mediatek/clk-pllfh.h @@ -68,7 +68,7 @@ struct fh_operation { int (*ssc_enable)(struct mtk_fh *fh, u32 rate); }; -int mtk_clk_register_pllfhs(struct device_node *node, +int mtk_clk_register_pllfhs(struct device *dev, const struct mtk_pll_data *plls, int num_plls, struct mtk_pllfh_data *pllfhs, int num_pllfhs, struct clk_hw_onecell_data *clk_data); diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig index 71481607a6d5..cf8cf3f9e4ee 100644 --- a/drivers/clk/meson/Kconfig +++ b/drivers/clk/meson/Kconfig @@ -201,4 +201,32 @@ config COMMON_CLK_S4_PERIPHERALS help Support for the peripherals clock controller on Amlogic S805X2 and S905Y4 devices, AKA S4. Say Y if you want S4 peripherals clock controller to work. + +config COMMON_CLK_T7_PLL + tristate "Amlogic T7 SoC PLL controller support" + depends on ARM64 + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_MPLL + select COMMON_CLK_MESON_PLL + imply COMMON_CLK_SCMI + help + Support for the PLL clock controller on Amlogic A311D2 based + device, AKA T7. PLLs are required by most peripheral to operate. + Say Y if you want T7 PLL clock controller to work. + +config COMMON_CLK_T7_PERIPHERALS + tristate "Amlogic T7 SoC peripherals clock controller support" + depends on ARM64 + default ARCH_MESON + select COMMON_CLK_MESON_REGMAP + select COMMON_CLK_MESON_CLKC_UTILS + select COMMON_CLK_MESON_DUALDIV + imply COMMON_CLK_SCMI + imply COMMON_CLK_T7_PLL + help + Support for the peripherals clock controller on Amlogic A311D2 based + device, AKA T7. Peripherals are required by most peripheral to operate. + Say Y if you want T7 peripherals clock controller to work. endmenu diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile index c6998e752c68..c6719694a242 100644 --- a/drivers/clk/meson/Makefile +++ b/drivers/clk/meson/Makefile @@ -26,3 +26,5 @@ obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o +obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o +obj-$(CONFIG_COMMON_CLK_T7_PERIPHERALS) += t7-peripherals.o diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index 185b6348251d..d0d4c7b6dc82 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -777,12 +777,23 @@ static struct clk_regmap g12a_hdmi_pll_dco = { }, }; +/* + * G12/SM1 hdmi OD dividers are POWER_OF_TWO dividers but limited to /4. + * A divider value of 3 should map to /8 but instead map /4 so ignore it. + */ +static const struct clk_div_table g12a_hdmi_pll_od_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { /* sentinel */ } +}; + static struct clk_regmap g12a_hdmi_pll_od = { .data = &(struct clk_regmap_div_data){ .offset = HHI_HDMI_PLL_CNTL0, .shift = 16, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", @@ -800,7 +811,7 @@ static struct clk_regmap g12a_hdmi_pll_od2 = { .offset = HHI_HDMI_PLL_CNTL0, .shift = 18, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", @@ -818,7 +829,7 @@ static struct clk_regmap g12a_hdmi_pll = { .offset = HHI_HDMI_PLL_CNTL0, .shift = 20, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = g12a_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 5a229c4ffae1..f9131d014ef4 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -349,12 +349,23 @@ static struct clk_regmap gxbb_hdmi_pll = { }, }; +/* + * GXL hdmi OD dividers are POWER_OF_TWO dividers but limited to /4. + * A divider value of 3 should map to /8 but instead map /4 so ignore it. + */ +static const struct clk_div_table gxl_hdmi_pll_od_div_table[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { /* sentinel */ } +}; + static struct clk_regmap gxl_hdmi_pll_od = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 21, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od", @@ -369,10 +380,10 @@ static struct clk_regmap gxl_hdmi_pll_od = { static struct clk_regmap gxl_hdmi_pll_od2 = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 23, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll_od2", @@ -387,10 +398,10 @@ static struct clk_regmap gxl_hdmi_pll_od2 = { static struct clk_regmap gxl_hdmi_pll = { .data = &(struct clk_regmap_div_data){ - .offset = HHI_HDMI_PLL_CNTL + 8, + .offset = HHI_HDMI_PLL_CNTL3, .shift = 19, .width = 2, - .flags = CLK_DIVIDER_POWER_OF_TWO, + .table = gxl_hdmi_pll_od_div_table, }, .hw.init = &(struct clk_init_data){ .name = "hdmi_pll", diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 95d0b9cbd904..bc029c6ab622 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -3646,7 +3646,7 @@ static void __init meson8b_clkc_init_common(struct device_node *np, return; } - rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); + rstc = kzalloc_obj(*rstc); if (!rstc) return; diff --git a/drivers/clk/meson/s4-peripherals.c b/drivers/clk/meson/s4-peripherals.c index 6d69b132d1e1..ba41fcd90588 100644 --- a/drivers/clk/meson/s4-peripherals.c +++ b/drivers/clk/meson/s4-peripherals.c @@ -44,6 +44,7 @@ #define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8 #define CLKCTRL_VAPBCLK_CTRL 0x0fc #define CLKCTRL_HDCP22_CTRL 0x100 +#define CLKCTRL_CDAC_CLK_CTRL 0x108 #define CLKCTRL_VDEC_CLK_CTRL 0x140 #define CLKCTRL_VDEC2_CLK_CTRL 0x144 #define CLKCTRL_VDEC3_CLK_CTRL 0x148 @@ -1106,7 +1107,6 @@ static struct clk_regmap s4_cts_enci_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1122,7 +1122,21 @@ static struct clk_regmap s4_cts_encp_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cts_encl_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = CLKCTRL_VIID_CLK_DIV, + .mask = 0xf, + .shift = 12, + .table = s4_cts_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cts_encl_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = s4_cts_parents, + .num_parents = ARRAY_SIZE(s4_cts_parents), }, }; @@ -1138,7 +1152,6 @@ static struct clk_regmap s4_cts_vdac_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_cts_parents, .num_parents = ARRAY_SIZE(s4_cts_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1169,7 +1182,6 @@ static struct clk_regmap s4_hdmi_tx_sel = { .ops = &clk_regmap_mux_ops, .parent_hws = s4_hdmi_tx_parents, .num_parents = ARRAY_SIZE(s4_hdmi_tx_parents), - .flags = CLK_SET_RATE_PARENT, }, }; @@ -1205,6 +1217,22 @@ static struct clk_regmap s4_cts_encp = { }, }; +static struct clk_regmap s4_cts_encl = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLKCTRL_VID_CLK_CTRL2, + .bit_idx = 3, + }, + .hw.init = &(struct clk_init_data) { + .name = "cts_encl", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cts_encl_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static struct clk_regmap s4_cts_vdac = { .data = &(struct clk_regmap_gate_data){ .offset = CLKCTRL_VID_CLK_CTRL2, @@ -2735,6 +2763,165 @@ static struct clk_regmap s4_gen_clk = { }, }; +/* CVBS DAC */ +static struct clk_regmap s4_cdac_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .mask = 0x3, + .shift = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .fw_name = "fclk_div5" }, + }, + .num_parents = 2, + }, +}; + +static struct clk_regmap s4_cdac_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .shift = 0, + .width = 16, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cdac_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_cdac = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_CDAC_CLK_CTRL, + .bit_idx = 20, + }, + .hw.init = &(struct clk_init_data){ + .name = "cdac", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_cdac_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x3, + .shift = 9, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div7" }, + { .fw_name = "fclk_div4" } + }, + .num_parents = 3, + }, +}; + +static struct clk_regmap s4_demod_core_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_demod_core = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 8 + }, + .hw.init = &(struct clk_init_data){ + .name = "demod_core", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_demod_core_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* CVBS ADC */ +static struct clk_regmap s4_adc_extclk_in_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .mask = 0x7, + .shift = 25, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal" }, + { .fw_name = "fclk_div4" }, + { .fw_name = "fclk_div3" }, + { .fw_name = "fclk_div5" }, + { .fw_name = "fclk_div7" }, + { .fw_name = "mpll2" }, + { .fw_name = "gp0_pll" }, + { .fw_name = "hifi_pll" } + }, + .num_parents = 8, + }, +}; + +static struct clk_regmap s4_adc_extclk_in_div = { + .data = &(struct clk_regmap_div_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .shift = 16, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap s4_adc_extclk_in = { + .data = &(struct clk_regmap_gate_data) { + .offset = CLKCTRL_DEMOD_CLK_CTRL, + .bit_idx = 24 + }, + .hw.init = &(struct clk_init_data){ + .name = "adc_extclk_in", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &s4_adc_extclk_in_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + static const struct clk_parent_data s4_pclk_parents = { .hw = &s4_sys_clk.hw }; #define S4_PCLK(_name, _reg, _bit, _flags) \ @@ -3028,6 +3215,17 @@ static struct clk_hw *s4_peripherals_hw_clks[] = { [CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_sel.hw, [CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw, [CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk.hw, + [CLKID_CTS_ENCL_SEL] = &s4_cts_encl_sel.hw, + [CLKID_CTS_ENCL] = &s4_cts_encl.hw, + [CLKID_CDAC_SEL] = &s4_cdac_sel.hw, + [CLKID_CDAC_DIV] = &s4_cdac_div.hw, + [CLKID_CDAC] = &s4_cdac.hw, + [CLKID_DEMOD_CORE_SEL] = &s4_demod_core_sel.hw, + [CLKID_DEMOD_CORE_DIV] = &s4_demod_core_div.hw, + [CLKID_DEMOD_CORE] = &s4_demod_core.hw, + [CLKID_ADC_EXTCLK_IN_SEL] = &s4_adc_extclk_in_sel.hw, + [CLKID_ADC_EXTCLK_IN_DIV] = &s4_adc_extclk_in_div.hw, + [CLKID_ADC_EXTCLK_IN] = &s4_adc_extclk_in.hw, }; static const struct meson_clkc_data s4_peripherals_clkc_data = { diff --git a/drivers/clk/meson/t7-peripherals.c b/drivers/clk/meson/t7-peripherals.c new file mode 100644 index 000000000000..214db7850d86 --- /dev/null +++ b/drivers/clk/meson/t7-peripherals.c @@ -0,0 +1,1271 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include "clk-dualdiv.h" +#include "clk-regmap.h" +#include "meson-clkc-utils.h" +#include + +#define RTC_BY_OSCIN_CTRL0 0x8 +#define RTC_BY_OSCIN_CTRL1 0xc +#define RTC_CTRL 0x10 +#define SYS_CLK_CTRL0 0x40 +#define SYS_CLK_EN0_REG0 0x44 +#define SYS_CLK_EN0_REG1 0x48 +#define SYS_CLK_EN0_REG2 0x4c +#define SYS_CLK_EN0_REG3 0x50 +#define CECA_CTRL0 0x88 +#define CECA_CTRL1 0x8c +#define CECB_CTRL0 0x90 +#define CECB_CTRL1 0x94 +#define SC_CLK_CTRL 0x98 +#define DSPA_CLK_CTRL0 0x9c +#define DSPB_CLK_CTRL0 0xa0 +#define CLK12_24_CTRL 0xa8 +#define ANAKIN_CLK_CTRL 0xac +#define MIPI_CSI_PHY_CLK_CTRL 0x10c +#define MIPI_ISP_CLK_CTRL 0x110 +#define TS_CLK_CTRL 0x158 +#define MALI_CLK_CTRL 0x15c +#define ETH_CLK_CTRL 0x164 +#define NAND_CLK_CTRL 0x168 +#define SD_EMMC_CLK_CTRL 0x16c +#define SPICC_CLK_CTRL 0x174 +#define SAR_CLK_CTRL0 0x17c +#define PWM_CLK_AB_CTRL 0x180 +#define PWM_CLK_CD_CTRL 0x184 +#define PWM_CLK_EF_CTRL 0x188 +#define PWM_CLK_AO_AB_CTRL 0x1a0 +#define PWM_CLK_AO_CD_CTRL 0x1a4 +#define PWM_CLK_AO_EF_CTRL 0x1a8 +#define PWM_CLK_AO_GH_CTRL 0x1ac +#define SPICC_CLK_CTRL1 0x1c0 +#define SPICC_CLK_CTRL2 0x1c4 + +#define T7_COMP_SEL(_name, _reg, _shift, _mask, _pdata) \ + MESON_COMP_SEL(t7_, _name, _reg, _shift, _mask, _pdata, NULL, 0, 0) + +#define T7_COMP_DIV(_name, _reg, _shift, _width) \ + MESON_COMP_DIV(t7_, _name, _reg, _shift, _width, 0, CLK_SET_RATE_PARENT) + +#define T7_COMP_GATE(_name, _reg, _bit, _iflags) \ + MESON_COMP_GATE(t7_, _name, _reg, _bit, CLK_SET_RATE_PARENT | (_iflags)) + +static struct clk_regmap t7_rtc_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_duandiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static const struct meson_clk_dualdiv_param t7_dualdiv_table[] = { + { + .n1 = 733, .m1 = 8, + .n2 = 732, .m2 = 11, + .dual = 1, + }, + {} +}; + +static struct clk_regmap t7_rtc_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = RTC_BY_OSCIN_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = RTC_BY_OSCIN_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_rtc_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = RTC_BY_OSCIN_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_div.hw, + &t7_rtc_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_rtc_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = RTC_BY_OSCIN_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "rtc_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_rtc_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_rtc = { + .data = &(struct clk_regmap_mux_data) { + .offset = RTC_CTRL, + .mask = 0x3, + .shift = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "rtc", + .ops = &clk_regmap_mux_ops, + /* + * xtal is also on parent input #3 but that it is not useful to CCF since + * the same parent is available with parent input #0 + */ + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "xtal", }, + { .hw = &t7_rtc_dualdiv.hw }, + { .fw_name = "ext_rtc", }, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "ceca_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECA_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECA_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECA_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECA_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECA_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_div.hw, + &t7_ceca_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_ceca_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECA_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_ceca = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECA_CTRL1, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "ceca", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ceca_dualdiv.hw, + &t7_rtc.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_in = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CTRL0, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data) { + .name = "cecb_dualdiv_in", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_div = { + .data = &(struct meson_clk_dualdiv_data){ + .n1 = { + .reg_off = CECB_CTRL0, + .shift = 0, + .width = 12, + }, + .n2 = { + .reg_off = CECB_CTRL0, + .shift = 12, + .width = 12, + }, + .m1 = { + .reg_off = CECB_CTRL1, + .shift = 0, + .width = 12, + }, + .m2 = { + .reg_off = CECB_CTRL1, + .shift = 12, + .width = 12, + }, + .dual = { + .reg_off = CECB_CTRL0, + .shift = 28, + .width = 1, + }, + .table = t7_dualdiv_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv_div", + .ops = &meson_clk_dualdiv_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_in.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CTRL1, + .mask = 0x1, + .shift = 24, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_div.hw, + &t7_cecb_dualdiv_in.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb_dualdiv = { + .data = &(struct clk_regmap_gate_data){ + .offset = CECB_CTRL0, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb_dualdiv", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_cecb = { + .data = &(struct clk_regmap_mux_data) { + .offset = CECB_CTRL1, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "cecb", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_cecb_dualdiv.hw, + &t7_rtc.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_sc_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "xtal", }, +}; + +static T7_COMP_SEL(sc, SC_CLK_CTRL, 9, 0x3, t7_sc_parents); +static T7_COMP_DIV(sc, SC_CLK_CTRL, 0, 8); +static T7_COMP_GATE(sc, SC_CLK_CTRL, 8, 0); + +static const struct clk_parent_data t7_dsp_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "hifi", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv7", }, + { .hw = &t7_rtc.hw }, +}; + +static T7_COMP_SEL(dspa_0, DSPA_CLK_CTRL0, 10, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspa_0, DSPA_CLK_CTRL0, 0, 10); +static T7_COMP_GATE(dspa_0, DSPA_CLK_CTRL0, 13, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(dspa_1, DSPA_CLK_CTRL0, 26, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspa_1, DSPA_CLK_CTRL0, 16, 10); +static T7_COMP_GATE(dspa_1, DSPA_CLK_CTRL0, 29, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_dspa = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPA_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspa", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_dspa_0.hw, + &t7_dspa_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static T7_COMP_SEL(dspb_0, DSPB_CLK_CTRL0, 10, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspb_0, DSPB_CLK_CTRL0, 0, 10); +static T7_COMP_GATE(dspb_0, DSPB_CLK_CTRL0, 13, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(dspb_1, DSPB_CLK_CTRL0, 26, 0x7, t7_dsp_parents); +static T7_COMP_DIV(dspb_1, DSPB_CLK_CTRL0, 16, 10); +static T7_COMP_GATE(dspb_1, DSPB_CLK_CTRL0, 29, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_dspb = { + .data = &(struct clk_regmap_mux_data){ + .offset = DSPB_CLK_CTRL0, + .mask = 0x1, + .shift = 15, + }, + .hw.init = &(struct clk_init_data){ + .name = "dspb", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_dspb_0.hw, + &t7_dspb_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_24m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 11, + }, + .hw.init = &(struct clk_init_data) { + .name = "24m", + .ops = &clk_regmap_gate_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor t7_24m_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "24m_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_24m.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_12m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "12m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_24m_div2.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_25m_div = { + .data = &(struct clk_regmap_div_data){ + .offset = CLK12_24_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "25m_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fix", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_25m = { + .data = &(struct clk_regmap_gate_data){ + .offset = CLK12_24_CTRL, + .bit_idx = 12, + }, + .hw.init = &(struct clk_init_data){ + .name = "25m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_25m_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_anakin_parents[] = { + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv2", }, + { .fw_name = "vid_pll0", }, + { .fw_name = "mpll1", }, + { .fw_name = "mpll2", }, + { .fw_name = "fdiv2p5", }, +}; + +static T7_COMP_SEL(anakin_0, ANAKIN_CLK_CTRL, 9, 0x7, t7_anakin_parents); +static T7_COMP_DIV(anakin_0, ANAKIN_CLK_CTRL, 0, 7); +static T7_COMP_GATE(anakin_0, ANAKIN_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(anakin_1, ANAKIN_CLK_CTRL, 25, 0x7, t7_anakin_parents); +static T7_COMP_DIV(anakin_1, ANAKIN_CLK_CTRL, 16, 7); +static T7_COMP_GATE(anakin_1, ANAKIN_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_anakin_01_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = ANAKIN_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "anakin_01_sel", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_anakin_0.hw, + &t7_anakin_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT + }, +}; + +static struct clk_regmap t7_anakin = { + .data = &(struct clk_regmap_gate_data){ + .offset = ANAKIN_CLK_CTRL, + .bit_idx = 30, + }, + .hw.init = &(struct clk_init_data) { + .name = "anakin", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_anakin_01_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT + }, +}; + +static const struct clk_parent_data t7_mipi_csi_phy_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp1", }, + { .fw_name = "mpll1", }, + { .fw_name = "mpll2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, +}; + +static T7_COMP_SEL(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 9, 0x7, t7_mipi_csi_phy_parents); +static T7_COMP_DIV(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mipi_csi_phy_0, MIPI_CSI_PHY_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 25, 0x7, t7_mipi_csi_phy_parents); +static T7_COMP_DIV(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 16, 7); +static T7_COMP_GATE(mipi_csi_phy_1, MIPI_CSI_PHY_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_mipi_csi_phy = { + .data = &(struct clk_regmap_mux_data){ + .offset = MIPI_CSI_PHY_CLK_CTRL, + .mask = 0x1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mipi_csi_phy", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mipi_csi_phy_0.hw, + &t7_mipi_csi_phy_1.hw + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_mipi_isp_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, + { .fw_name = "gp1", }, +}; + +static T7_COMP_SEL(mipi_isp, MIPI_ISP_CLK_CTRL, 9, 0x7, t7_mipi_isp_parents); +static T7_COMP_DIV(mipi_isp, MIPI_ISP_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mipi_isp, MIPI_ISP_CLK_CTRL, 8, 0); + +static struct clk_regmap t7_ts_div = { + .data = &(struct clk_regmap_div_data){ + .offset = TS_CLK_CTRL, + .shift = 0, + .width = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts_div", + .ops = &clk_regmap_divider_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "xtal", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_ts = { + .data = &(struct clk_regmap_gate_data){ + .offset = TS_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "ts", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_ts_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct clk_parent_data t7_mali_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "gp0", }, + { .fw_name = "gp1", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, +}; + +static T7_COMP_SEL(mali_0, MALI_CLK_CTRL, 9, 0x7, t7_mali_parents); +static T7_COMP_DIV(mali_0, MALI_CLK_CTRL, 0, 7); +static T7_COMP_GATE(mali_0, MALI_CLK_CTRL, 8, CLK_SET_RATE_GATE); + +static T7_COMP_SEL(mali_1, MALI_CLK_CTRL, 25, 0x7, t7_mali_parents); +static T7_COMP_DIV(mali_1, MALI_CLK_CTRL, 16, 7); +static T7_COMP_GATE(mali_1, MALI_CLK_CTRL, 24, CLK_SET_RATE_GATE); + +static struct clk_regmap t7_mali = { + .data = &(struct clk_regmap_mux_data){ + .offset = MALI_CLK_CTRL, + .mask = 1, + .shift = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mali", + .ops = &clk_regmap_mux_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mali_0.hw, + &t7_mali_1.hw, + }, + .num_parents = 2, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * parent index 2, 3, 4, 5, 6 not connect any clock signal, + * the last parent connect external PAD + */ +static u32 t7_eth_rmii_parents_val_table[] = { 0, 1, 7 }; +static const struct clk_parent_data t7_eth_rmii_parents[] = { + { .fw_name = "fdiv2", }, + { .fw_name = "gp1", }, + { .fw_name = "ext_rmii", }, +}; + +static struct clk_regmap t7_eth_rmii_sel = { + .data = &(struct clk_regmap_mux_data) { + .offset = ETH_CLK_CTRL, + .mask = 0x7, + .shift = 9, + .table = t7_eth_rmii_parents_val_table, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = t7_eth_rmii_parents, + .num_parents = ARRAY_SIZE(t7_eth_rmii_parents), + .flags = CLK_SET_RATE_NO_REPARENT, + }, +}; + +static struct clk_regmap t7_eth_rmii_div = { + .data = &(struct clk_regmap_div_data) { + .offset = ETH_CLK_CTRL, + .shift = 0, + .width = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_eth_rmii_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_eth_rmii = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_rmii", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_eth_rmii_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_fdiv2_div8 = { + .mult = 1, + .div = 8, + .hw.init = &(struct clk_init_data){ + .name = "fdiv2_div8", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "fdiv2", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_eth_125m = { + .data = &(struct clk_regmap_gate_data) { + .offset = ETH_CLK_CTRL, + .bit_idx = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "eth_125m", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_fdiv2_div8.hw + }, + .num_parents = 1, + }, +}; + +static const struct clk_parent_data t7_sd_emmc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv3", }, + { .fw_name = "hifi", }, + { .fw_name = "fdiv2p5", }, + { .fw_name = "mpll2", }, + { .fw_name = "mpll3", }, + { .fw_name = "gp0", }, +}; + +static T7_COMP_SEL(sd_emmc_a, SD_EMMC_CLK_CTRL, 9, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_a, SD_EMMC_CLK_CTRL, 0, 7); +static T7_COMP_GATE(sd_emmc_a, SD_EMMC_CLK_CTRL, 7, 0); + +static T7_COMP_SEL(sd_emmc_b, SD_EMMC_CLK_CTRL, 25, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_b, SD_EMMC_CLK_CTRL, 16, 7); +static T7_COMP_GATE(sd_emmc_b, SD_EMMC_CLK_CTRL, 23, 0); + +static T7_COMP_SEL(sd_emmc_c, NAND_CLK_CTRL, 9, 0x7, t7_sd_emmc_parents); +static T7_COMP_DIV(sd_emmc_c, NAND_CLK_CTRL, 0, 7); +static T7_COMP_GATE(sd_emmc_c, NAND_CLK_CTRL, 7, 0); + +static const struct clk_parent_data t7_spicc_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "sys", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, + { .fw_name = "fdiv2", }, + { .fw_name = "fdiv5", }, + { .fw_name = "fdiv7", }, + { .fw_name = "gp1", }, +}; + +static T7_COMP_SEL(spicc0, SPICC_CLK_CTRL, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc0, SPICC_CLK_CTRL, 0, 6); +static T7_COMP_GATE(spicc0, SPICC_CLK_CTRL, 6, 0); + +static T7_COMP_SEL(spicc1, SPICC_CLK_CTRL, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc1, SPICC_CLK_CTRL, 16, 6); +static T7_COMP_GATE(spicc1, SPICC_CLK_CTRL, 22, 0); + +static T7_COMP_SEL(spicc2, SPICC_CLK_CTRL1, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc2, SPICC_CLK_CTRL1, 0, 6); +static T7_COMP_GATE(spicc2, SPICC_CLK_CTRL1, 6, 0); + +static T7_COMP_SEL(spicc3, SPICC_CLK_CTRL1, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc3, SPICC_CLK_CTRL1, 16, 6); +static T7_COMP_GATE(spicc3, SPICC_CLK_CTRL1, 22, 0); + +static T7_COMP_SEL(spicc4, SPICC_CLK_CTRL2, 7, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc4, SPICC_CLK_CTRL2, 0, 6); +static T7_COMP_GATE(spicc4, SPICC_CLK_CTRL2, 6, 0); + +static T7_COMP_SEL(spicc5, SPICC_CLK_CTRL2, 23, 0x7, t7_spicc_parents); +static T7_COMP_DIV(spicc5, SPICC_CLK_CTRL2, 16, 6); +static T7_COMP_GATE(spicc5, SPICC_CLK_CTRL2, 22, 0); + +static const struct clk_parent_data t7_saradc_parents[] = { + { .fw_name = "xtal" }, + { .fw_name = "sys" }, +}; + +static T7_COMP_SEL(saradc, SAR_CLK_CTRL0, 9, 0x1, t7_saradc_parents); +static T7_COMP_DIV(saradc, SAR_CLK_CTRL0, 0, 8); +static T7_COMP_GATE(saradc, SAR_CLK_CTRL0, 8, 0); + +static const struct clk_parent_data t7_pwm_parents[] = { + { .fw_name = "xtal", }, + { .fw_name = "vid_pll0", }, + { .fw_name = "fdiv4", }, + { .fw_name = "fdiv3", }, +}; + +static T7_COMP_SEL(pwm_a, PWM_CLK_AB_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_a, PWM_CLK_AB_CTRL, 0, 8); +static T7_COMP_GATE(pwm_a, PWM_CLK_AB_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_b, PWM_CLK_AB_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_b, PWM_CLK_AB_CTRL, 16, 8); +static T7_COMP_GATE(pwm_b, PWM_CLK_AB_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_c, PWM_CLK_CD_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_c, PWM_CLK_CD_CTRL, 0, 8); +static T7_COMP_GATE(pwm_c, PWM_CLK_CD_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_d, PWM_CLK_CD_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_d, PWM_CLK_CD_CTRL, 16, 8); +static T7_COMP_GATE(pwm_d, PWM_CLK_CD_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_e, PWM_CLK_EF_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_e, PWM_CLK_EF_CTRL, 0, 8); +static T7_COMP_GATE(pwm_e, PWM_CLK_EF_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_f, PWM_CLK_EF_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_f, PWM_CLK_EF_CTRL, 16, 8); +static T7_COMP_GATE(pwm_f, PWM_CLK_EF_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_a, PWM_CLK_AO_AB_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_b, PWM_CLK_AO_AB_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_c, PWM_CLK_AO_CD_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_d, PWM_CLK_AO_CD_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_e, PWM_CLK_AO_EF_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_f, PWM_CLK_AO_EF_CTRL, 24, 0); + +static T7_COMP_SEL(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 9, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 0, 8); +static T7_COMP_GATE(pwm_ao_g, PWM_CLK_AO_GH_CTRL, 8, 0); + +static T7_COMP_SEL(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 25, 0x3, t7_pwm_parents); +static T7_COMP_DIV(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 16, 8); +static T7_COMP_GATE(pwm_ao_h, PWM_CLK_AO_GH_CTRL, 24, 0); + +static const struct clk_parent_data t7_sys_pclk_parents = { .fw_name = "sys" }; + +#define T7_SYS_PCLK(_name, _reg, _bit, _flags) \ + MESON_PCLK(t7_##_name, _reg, _bit, &t7_sys_pclk_parents, _flags) + +static T7_SYS_PCLK(sys_ddr, SYS_CLK_EN0_REG0, 0, 0); +static T7_SYS_PCLK(sys_dos, SYS_CLK_EN0_REG0, 1, 0); +static T7_SYS_PCLK(sys_mipi_dsi_a, SYS_CLK_EN0_REG0, 2, 0); +static T7_SYS_PCLK(sys_mipi_dsi_b, SYS_CLK_EN0_REG0, 3, 0); +static T7_SYS_PCLK(sys_ethphy, SYS_CLK_EN0_REG0, 4, 0); +static T7_SYS_PCLK(sys_mali, SYS_CLK_EN0_REG0, 6, 0); +static T7_SYS_PCLK(sys_aocpu, SYS_CLK_EN0_REG0, 13, 0); +static T7_SYS_PCLK(sys_aucpu, SYS_CLK_EN0_REG0, 14, 0); +static T7_SYS_PCLK(sys_cec, SYS_CLK_EN0_REG0, 16, 0); +static T7_SYS_PCLK(sys_gdc, SYS_CLK_EN0_REG0, 17, 0); +static T7_SYS_PCLK(sys_deswarp, SYS_CLK_EN0_REG0, 18, 0); +static T7_SYS_PCLK(sys_ampipe_nand, SYS_CLK_EN0_REG0, 19, 0); +static T7_SYS_PCLK(sys_ampipe_eth, SYS_CLK_EN0_REG0, 20, 0); +static T7_SYS_PCLK(sys_am2axi0, SYS_CLK_EN0_REG0, 21, 0); +static T7_SYS_PCLK(sys_am2axi1, SYS_CLK_EN0_REG0, 22, 0); +static T7_SYS_PCLK(sys_am2axi2, SYS_CLK_EN0_REG0, 23, 0); +static T7_SYS_PCLK(sys_sd_emmc_a, SYS_CLK_EN0_REG0, 24, 0); +static T7_SYS_PCLK(sys_sd_emmc_b, SYS_CLK_EN0_REG0, 25, 0); +static T7_SYS_PCLK(sys_sd_emmc_c, SYS_CLK_EN0_REG0, 26, 0); +static T7_SYS_PCLK(sys_smartcard, SYS_CLK_EN0_REG0, 27, 0); +static T7_SYS_PCLK(sys_acodec, SYS_CLK_EN0_REG0, 28, 0); +static T7_SYS_PCLK(sys_spifc, SYS_CLK_EN0_REG0, 29, 0); +static T7_SYS_PCLK(sys_msr_clk, SYS_CLK_EN0_REG0, 30, 0); +static T7_SYS_PCLK(sys_ir_ctrl, SYS_CLK_EN0_REG0, 31, 0); +static T7_SYS_PCLK(sys_audio, SYS_CLK_EN0_REG1, 0, 0); +static T7_SYS_PCLK(sys_eth, SYS_CLK_EN0_REG1, 3, 0); +static T7_SYS_PCLK(sys_uart_a, SYS_CLK_EN0_REG1, 5, 0); +static T7_SYS_PCLK(sys_uart_b, SYS_CLK_EN0_REG1, 6, 0); +static T7_SYS_PCLK(sys_uart_c, SYS_CLK_EN0_REG1, 7, 0); +static T7_SYS_PCLK(sys_uart_d, SYS_CLK_EN0_REG1, 8, 0); +static T7_SYS_PCLK(sys_uart_e, SYS_CLK_EN0_REG1, 9, 0); +static T7_SYS_PCLK(sys_uart_f, SYS_CLK_EN0_REG1, 10, 0); +static T7_SYS_PCLK(sys_aififo, SYS_CLK_EN0_REG1, 11, 0); +static T7_SYS_PCLK(sys_spicc2, SYS_CLK_EN0_REG1, 12, 0); +static T7_SYS_PCLK(sys_spicc3, SYS_CLK_EN0_REG1, 13, 0); +static T7_SYS_PCLK(sys_spicc4, SYS_CLK_EN0_REG1, 14, 0); +static T7_SYS_PCLK(sys_ts_a73, SYS_CLK_EN0_REG1, 15, 0); +static T7_SYS_PCLK(sys_ts_a53, SYS_CLK_EN0_REG1, 16, 0); +static T7_SYS_PCLK(sys_spicc5, SYS_CLK_EN0_REG1, 17, 0); +static T7_SYS_PCLK(sys_g2d, SYS_CLK_EN0_REG1, 20, 0); +static T7_SYS_PCLK(sys_spicc0, SYS_CLK_EN0_REG1, 21, 0); +static T7_SYS_PCLK(sys_spicc1, SYS_CLK_EN0_REG1, 22, 0); +static T7_SYS_PCLK(sys_pcie, SYS_CLK_EN0_REG1, 24, 0); +static T7_SYS_PCLK(sys_usb, SYS_CLK_EN0_REG1, 26, 0); +static T7_SYS_PCLK(sys_pcie_phy, SYS_CLK_EN0_REG1, 27, 0); +static T7_SYS_PCLK(sys_i2c_ao_a, SYS_CLK_EN0_REG1, 28, 0); +static T7_SYS_PCLK(sys_i2c_ao_b, SYS_CLK_EN0_REG1, 29, 0); +static T7_SYS_PCLK(sys_i2c_m_a, SYS_CLK_EN0_REG1, 30, 0); +static T7_SYS_PCLK(sys_i2c_m_b, SYS_CLK_EN0_REG1, 31, 0); +static T7_SYS_PCLK(sys_i2c_m_c, SYS_CLK_EN0_REG2, 0, 0); +static T7_SYS_PCLK(sys_i2c_m_d, SYS_CLK_EN0_REG2, 1, 0); +static T7_SYS_PCLK(sys_i2c_m_e, SYS_CLK_EN0_REG2, 2, 0); +static T7_SYS_PCLK(sys_i2c_m_f, SYS_CLK_EN0_REG2, 3, 0); +static T7_SYS_PCLK(sys_hdmitx_apb, SYS_CLK_EN0_REG2, 4, 0); +static T7_SYS_PCLK(sys_i2c_s_a, SYS_CLK_EN0_REG2, 5, 0); +static T7_SYS_PCLK(sys_hdmirx_pclk, SYS_CLK_EN0_REG2, 8, 0); +static T7_SYS_PCLK(sys_mmc_apb, SYS_CLK_EN0_REG2, 11, 0); +static T7_SYS_PCLK(sys_mipi_isp_pclk, SYS_CLK_EN0_REG2, 17, 0); +static T7_SYS_PCLK(sys_rsa, SYS_CLK_EN0_REG2, 18, 0); +static T7_SYS_PCLK(sys_pclk_sys_apb, SYS_CLK_EN0_REG2, 19, 0); +static T7_SYS_PCLK(sys_a73pclk_apb, SYS_CLK_EN0_REG2, 20, 0); +static T7_SYS_PCLK(sys_dspa, SYS_CLK_EN0_REG2, 21, 0); +static T7_SYS_PCLK(sys_dspb, SYS_CLK_EN0_REG2, 22, 0); +static T7_SYS_PCLK(sys_vpu_intr, SYS_CLK_EN0_REG2, 25, 0); +static T7_SYS_PCLK(sys_sar_adc, SYS_CLK_EN0_REG2, 28, 0); +/* + * sys_gic provides the clock for GIC(Generic Interrupt Controller). + * After clock is disabled, The GIC cannot work properly. At present, the driver + * used by our GIC is the public driver in kernel, and there is no management + * clock in the driver. + */ +static T7_SYS_PCLK(sys_gic, SYS_CLK_EN0_REG2, 30, CLK_IS_CRITICAL); +static T7_SYS_PCLK(sys_ts_gpu, SYS_CLK_EN0_REG2, 31, 0); +static T7_SYS_PCLK(sys_ts_nna, SYS_CLK_EN0_REG3, 0, 0); +static T7_SYS_PCLK(sys_ts_vpu, SYS_CLK_EN0_REG3, 1, 0); +static T7_SYS_PCLK(sys_ts_hevc, SYS_CLK_EN0_REG3, 2, 0); +static T7_SYS_PCLK(sys_pwm_ao_ab, SYS_CLK_EN0_REG3, 3, 0); +static T7_SYS_PCLK(sys_pwm_ao_cd, SYS_CLK_EN0_REG3, 4, 0); +static T7_SYS_PCLK(sys_pwm_ao_ef, SYS_CLK_EN0_REG3, 5, 0); +static T7_SYS_PCLK(sys_pwm_ao_gh, SYS_CLK_EN0_REG3, 6, 0); +static T7_SYS_PCLK(sys_pwm_ab, SYS_CLK_EN0_REG3, 7, 0); +static T7_SYS_PCLK(sys_pwm_cd, SYS_CLK_EN0_REG3, 8, 0); +static T7_SYS_PCLK(sys_pwm_ef, SYS_CLK_EN0_REG3, 9, 0); + +/* Array of all clocks registered by this provider */ +static struct clk_hw *t7_peripherals_hw_clks[] = { + [CLKID_RTC_DUALDIV_IN] = &t7_rtc_dualdiv_in.hw, + [CLKID_RTC_DUALDIV_DIV] = &t7_rtc_dualdiv_div.hw, + [CLKID_RTC_DUALDIV_SEL] = &t7_rtc_dualdiv_sel.hw, + [CLKID_RTC_DUALDIV] = &t7_rtc_dualdiv.hw, + [CLKID_RTC] = &t7_rtc.hw, + [CLKID_CECA_DUALDIV_IN] = &t7_ceca_dualdiv_in.hw, + [CLKID_CECA_DUALDIV_DIV] = &t7_ceca_dualdiv_div.hw, + [CLKID_CECA_DUALDIV_SEL] = &t7_ceca_dualdiv_sel.hw, + [CLKID_CECA_DUALDIV] = &t7_ceca_dualdiv.hw, + [CLKID_CECA] = &t7_ceca.hw, + [CLKID_CECB_DUALDIV_IN] = &t7_cecb_dualdiv_in.hw, + [CLKID_CECB_DUALDIV_DIV] = &t7_cecb_dualdiv_div.hw, + [CLKID_CECB_DUALDIV_SEL] = &t7_cecb_dualdiv_sel.hw, + [CLKID_CECB_DUALDIV] = &t7_cecb_dualdiv.hw, + [CLKID_CECB] = &t7_cecb.hw, + [CLKID_SC_SEL] = &t7_sc_sel.hw, + [CLKID_SC_DIV] = &t7_sc_div.hw, + [CLKID_SC] = &t7_sc.hw, + [CLKID_DSPA_0_SEL] = &t7_dspa_0_sel.hw, + [CLKID_DSPA_0_DIV] = &t7_dspa_0_div.hw, + [CLKID_DSPA_0] = &t7_dspa_0.hw, + [CLKID_DSPA_1_SEL] = &t7_dspa_1_sel.hw, + [CLKID_DSPA_1_DIV] = &t7_dspa_1_div.hw, + [CLKID_DSPA_1] = &t7_dspa_1.hw, + [CLKID_DSPA] = &t7_dspa.hw, + [CLKID_DSPB_0_SEL] = &t7_dspb_0_sel.hw, + [CLKID_DSPB_0_DIV] = &t7_dspb_0_div.hw, + [CLKID_DSPB_0] = &t7_dspb_0.hw, + [CLKID_DSPB_1_SEL] = &t7_dspb_1_sel.hw, + [CLKID_DSPB_1_DIV] = &t7_dspb_1_div.hw, + [CLKID_DSPB_1] = &t7_dspb_1.hw, + [CLKID_DSPB] = &t7_dspb.hw, + [CLKID_24M] = &t7_24m.hw, + [CLKID_24M_DIV2] = &t7_24m_div2.hw, + [CLKID_12M] = &t7_12m.hw, + [CLKID_25M_DIV] = &t7_25m_div.hw, + [CLKID_25M] = &t7_25m.hw, + [CLKID_ANAKIN_0_SEL] = &t7_anakin_0_sel.hw, + [CLKID_ANAKIN_0_DIV] = &t7_anakin_0_div.hw, + [CLKID_ANAKIN_0] = &t7_anakin_0.hw, + [CLKID_ANAKIN_1_SEL] = &t7_anakin_1_sel.hw, + [CLKID_ANAKIN_1_DIV] = &t7_anakin_1_div.hw, + [CLKID_ANAKIN_1] = &t7_anakin_1.hw, + [CLKID_ANAKIN_01_SEL] = &t7_anakin_01_sel.hw, + [CLKID_ANAKIN] = &t7_anakin.hw, + [CLKID_MIPI_CSI_PHY_0_SEL] = &t7_mipi_csi_phy_0_sel.hw, + [CLKID_MIPI_CSI_PHY_0_DIV] = &t7_mipi_csi_phy_0_div.hw, + [CLKID_MIPI_CSI_PHY_0] = &t7_mipi_csi_phy_0.hw, + [CLKID_MIPI_CSI_PHY_1_SEL] = &t7_mipi_csi_phy_1_sel.hw, + [CLKID_MIPI_CSI_PHY_1_DIV] = &t7_mipi_csi_phy_1_div.hw, + [CLKID_MIPI_CSI_PHY_1] = &t7_mipi_csi_phy_1.hw, + [CLKID_MIPI_CSI_PHY] = &t7_mipi_csi_phy.hw, + [CLKID_MIPI_ISP_SEL] = &t7_mipi_isp_sel.hw, + [CLKID_MIPI_ISP_DIV] = &t7_mipi_isp_div.hw, + [CLKID_MIPI_ISP] = &t7_mipi_isp.hw, + [CLKID_TS_DIV] = &t7_ts_div.hw, + [CLKID_TS] = &t7_ts.hw, + [CLKID_MALI_0_SEL] = &t7_mali_0_sel.hw, + [CLKID_MALI_0_DIV] = &t7_mali_0_div.hw, + [CLKID_MALI_0] = &t7_mali_0.hw, + [CLKID_MALI_1_SEL] = &t7_mali_1_sel.hw, + [CLKID_MALI_1_DIV] = &t7_mali_1_div.hw, + [CLKID_MALI_1] = &t7_mali_1.hw, + [CLKID_MALI] = &t7_mali.hw, + [CLKID_ETH_RMII_SEL] = &t7_eth_rmii_sel.hw, + [CLKID_ETH_RMII_DIV] = &t7_eth_rmii_div.hw, + [CLKID_ETH_RMII] = &t7_eth_rmii.hw, + [CLKID_FCLK_DIV2_DIV8] = &t7_fdiv2_div8.hw, + [CLKID_ETH_125M] = &t7_eth_125m.hw, + [CLKID_SD_EMMC_A_SEL] = &t7_sd_emmc_a_sel.hw, + [CLKID_SD_EMMC_A_DIV] = &t7_sd_emmc_a_div.hw, + [CLKID_SD_EMMC_A] = &t7_sd_emmc_a.hw, + [CLKID_SD_EMMC_B_SEL] = &t7_sd_emmc_b_sel.hw, + [CLKID_SD_EMMC_B_DIV] = &t7_sd_emmc_b_div.hw, + [CLKID_SD_EMMC_B] = &t7_sd_emmc_b.hw, + [CLKID_SD_EMMC_C_SEL] = &t7_sd_emmc_c_sel.hw, + [CLKID_SD_EMMC_C_DIV] = &t7_sd_emmc_c_div.hw, + [CLKID_SD_EMMC_C] = &t7_sd_emmc_c.hw, + [CLKID_SPICC0_SEL] = &t7_spicc0_sel.hw, + [CLKID_SPICC0_DIV] = &t7_spicc0_div.hw, + [CLKID_SPICC0] = &t7_spicc0.hw, + [CLKID_SPICC1_SEL] = &t7_spicc1_sel.hw, + [CLKID_SPICC1_DIV] = &t7_spicc1_div.hw, + [CLKID_SPICC1] = &t7_spicc1.hw, + [CLKID_SPICC2_SEL] = &t7_spicc2_sel.hw, + [CLKID_SPICC2_DIV] = &t7_spicc2_div.hw, + [CLKID_SPICC2] = &t7_spicc2.hw, + [CLKID_SPICC3_SEL] = &t7_spicc3_sel.hw, + [CLKID_SPICC3_DIV] = &t7_spicc3_div.hw, + [CLKID_SPICC3] = &t7_spicc3.hw, + [CLKID_SPICC4_SEL] = &t7_spicc4_sel.hw, + [CLKID_SPICC4_DIV] = &t7_spicc4_div.hw, + [CLKID_SPICC4] = &t7_spicc4.hw, + [CLKID_SPICC5_SEL] = &t7_spicc5_sel.hw, + [CLKID_SPICC5_DIV] = &t7_spicc5_div.hw, + [CLKID_SPICC5] = &t7_spicc5.hw, + [CLKID_SARADC_SEL] = &t7_saradc_sel.hw, + [CLKID_SARADC_DIV] = &t7_saradc_div.hw, + [CLKID_SARADC] = &t7_saradc.hw, + [CLKID_PWM_A_SEL] = &t7_pwm_a_sel.hw, + [CLKID_PWM_A_DIV] = &t7_pwm_a_div.hw, + [CLKID_PWM_A] = &t7_pwm_a.hw, + [CLKID_PWM_B_SEL] = &t7_pwm_b_sel.hw, + [CLKID_PWM_B_DIV] = &t7_pwm_b_div.hw, + [CLKID_PWM_B] = &t7_pwm_b.hw, + [CLKID_PWM_C_SEL] = &t7_pwm_c_sel.hw, + [CLKID_PWM_C_DIV] = &t7_pwm_c_div.hw, + [CLKID_PWM_C] = &t7_pwm_c.hw, + [CLKID_PWM_D_SEL] = &t7_pwm_d_sel.hw, + [CLKID_PWM_D_DIV] = &t7_pwm_d_div.hw, + [CLKID_PWM_D] = &t7_pwm_d.hw, + [CLKID_PWM_E_SEL] = &t7_pwm_e_sel.hw, + [CLKID_PWM_E_DIV] = &t7_pwm_e_div.hw, + [CLKID_PWM_E] = &t7_pwm_e.hw, + [CLKID_PWM_F_SEL] = &t7_pwm_f_sel.hw, + [CLKID_PWM_F_DIV] = &t7_pwm_f_div.hw, + [CLKID_PWM_F] = &t7_pwm_f.hw, + [CLKID_PWM_AO_A_SEL] = &t7_pwm_ao_a_sel.hw, + [CLKID_PWM_AO_A_DIV] = &t7_pwm_ao_a_div.hw, + [CLKID_PWM_AO_A] = &t7_pwm_ao_a.hw, + [CLKID_PWM_AO_B_SEL] = &t7_pwm_ao_b_sel.hw, + [CLKID_PWM_AO_B_DIV] = &t7_pwm_ao_b_div.hw, + [CLKID_PWM_AO_B] = &t7_pwm_ao_b.hw, + [CLKID_PWM_AO_C_SEL] = &t7_pwm_ao_c_sel.hw, + [CLKID_PWM_AO_C_DIV] = &t7_pwm_ao_c_div.hw, + [CLKID_PWM_AO_C] = &t7_pwm_ao_c.hw, + [CLKID_PWM_AO_D_SEL] = &t7_pwm_ao_d_sel.hw, + [CLKID_PWM_AO_D_DIV] = &t7_pwm_ao_d_div.hw, + [CLKID_PWM_AO_D] = &t7_pwm_ao_d.hw, + [CLKID_PWM_AO_E_SEL] = &t7_pwm_ao_e_sel.hw, + [CLKID_PWM_AO_E_DIV] = &t7_pwm_ao_e_div.hw, + [CLKID_PWM_AO_E] = &t7_pwm_ao_e.hw, + [CLKID_PWM_AO_F_SEL] = &t7_pwm_ao_f_sel.hw, + [CLKID_PWM_AO_F_DIV] = &t7_pwm_ao_f_div.hw, + [CLKID_PWM_AO_F] = &t7_pwm_ao_f.hw, + [CLKID_PWM_AO_G_SEL] = &t7_pwm_ao_g_sel.hw, + [CLKID_PWM_AO_G_DIV] = &t7_pwm_ao_g_div.hw, + [CLKID_PWM_AO_G] = &t7_pwm_ao_g.hw, + [CLKID_PWM_AO_H_SEL] = &t7_pwm_ao_h_sel.hw, + [CLKID_PWM_AO_H_DIV] = &t7_pwm_ao_h_div.hw, + [CLKID_PWM_AO_H] = &t7_pwm_ao_h.hw, + [CLKID_SYS_DDR] = &t7_sys_ddr.hw, + [CLKID_SYS_DOS] = &t7_sys_dos.hw, + [CLKID_SYS_MIPI_DSI_A] = &t7_sys_mipi_dsi_a.hw, + [CLKID_SYS_MIPI_DSI_B] = &t7_sys_mipi_dsi_b.hw, + [CLKID_SYS_ETHPHY] = &t7_sys_ethphy.hw, + [CLKID_SYS_MALI] = &t7_sys_mali.hw, + [CLKID_SYS_AOCPU] = &t7_sys_aocpu.hw, + [CLKID_SYS_AUCPU] = &t7_sys_aucpu.hw, + [CLKID_SYS_CEC] = &t7_sys_cec.hw, + [CLKID_SYS_GDC] = &t7_sys_gdc.hw, + [CLKID_SYS_DESWARP] = &t7_sys_deswarp.hw, + [CLKID_SYS_AMPIPE_NAND] = &t7_sys_ampipe_nand.hw, + [CLKID_SYS_AMPIPE_ETH] = &t7_sys_ampipe_eth.hw, + [CLKID_SYS_AM2AXI0] = &t7_sys_am2axi0.hw, + [CLKID_SYS_AM2AXI1] = &t7_sys_am2axi1.hw, + [CLKID_SYS_AM2AXI2] = &t7_sys_am2axi2.hw, + [CLKID_SYS_SD_EMMC_A] = &t7_sys_sd_emmc_a.hw, + [CLKID_SYS_SD_EMMC_B] = &t7_sys_sd_emmc_b.hw, + [CLKID_SYS_SD_EMMC_C] = &t7_sys_sd_emmc_c.hw, + [CLKID_SYS_SMARTCARD] = &t7_sys_smartcard.hw, + [CLKID_SYS_ACODEC] = &t7_sys_acodec.hw, + [CLKID_SYS_SPIFC] = &t7_sys_spifc.hw, + [CLKID_SYS_MSR_CLK] = &t7_sys_msr_clk.hw, + [CLKID_SYS_IR_CTRL] = &t7_sys_ir_ctrl.hw, + [CLKID_SYS_AUDIO] = &t7_sys_audio.hw, + [CLKID_SYS_ETH] = &t7_sys_eth.hw, + [CLKID_SYS_UART_A] = &t7_sys_uart_a.hw, + [CLKID_SYS_UART_B] = &t7_sys_uart_b.hw, + [CLKID_SYS_UART_C] = &t7_sys_uart_c.hw, + [CLKID_SYS_UART_D] = &t7_sys_uart_d.hw, + [CLKID_SYS_UART_E] = &t7_sys_uart_e.hw, + [CLKID_SYS_UART_F] = &t7_sys_uart_f.hw, + [CLKID_SYS_AIFIFO] = &t7_sys_aififo.hw, + [CLKID_SYS_SPICC2] = &t7_sys_spicc2.hw, + [CLKID_SYS_SPICC3] = &t7_sys_spicc3.hw, + [CLKID_SYS_SPICC4] = &t7_sys_spicc4.hw, + [CLKID_SYS_TS_A73] = &t7_sys_ts_a73.hw, + [CLKID_SYS_TS_A53] = &t7_sys_ts_a53.hw, + [CLKID_SYS_SPICC5] = &t7_sys_spicc5.hw, + [CLKID_SYS_G2D] = &t7_sys_g2d.hw, + [CLKID_SYS_SPICC0] = &t7_sys_spicc0.hw, + [CLKID_SYS_SPICC1] = &t7_sys_spicc1.hw, + [CLKID_SYS_PCIE] = &t7_sys_pcie.hw, + [CLKID_SYS_USB] = &t7_sys_usb.hw, + [CLKID_SYS_PCIE_PHY] = &t7_sys_pcie_phy.hw, + [CLKID_SYS_I2C_AO_A] = &t7_sys_i2c_ao_a.hw, + [CLKID_SYS_I2C_AO_B] = &t7_sys_i2c_ao_b.hw, + [CLKID_SYS_I2C_M_A] = &t7_sys_i2c_m_a.hw, + [CLKID_SYS_I2C_M_B] = &t7_sys_i2c_m_b.hw, + [CLKID_SYS_I2C_M_C] = &t7_sys_i2c_m_c.hw, + [CLKID_SYS_I2C_M_D] = &t7_sys_i2c_m_d.hw, + [CLKID_SYS_I2C_M_E] = &t7_sys_i2c_m_e.hw, + [CLKID_SYS_I2C_M_F] = &t7_sys_i2c_m_f.hw, + [CLKID_SYS_HDMITX_APB] = &t7_sys_hdmitx_apb.hw, + [CLKID_SYS_I2C_S_A] = &t7_sys_i2c_s_a.hw, + [CLKID_SYS_HDMIRX_PCLK] = &t7_sys_hdmirx_pclk.hw, + [CLKID_SYS_MMC_APB] = &t7_sys_mmc_apb.hw, + [CLKID_SYS_MIPI_ISP_PCLK] = &t7_sys_mipi_isp_pclk.hw, + [CLKID_SYS_RSA] = &t7_sys_rsa.hw, + [CLKID_SYS_PCLK_SYS_APB] = &t7_sys_pclk_sys_apb.hw, + [CLKID_SYS_A73PCLK_APB] = &t7_sys_a73pclk_apb.hw, + [CLKID_SYS_DSPA] = &t7_sys_dspa.hw, + [CLKID_SYS_DSPB] = &t7_sys_dspb.hw, + [CLKID_SYS_VPU_INTR] = &t7_sys_vpu_intr.hw, + [CLKID_SYS_SAR_ADC] = &t7_sys_sar_adc.hw, + [CLKID_SYS_GIC] = &t7_sys_gic.hw, + [CLKID_SYS_TS_GPU] = &t7_sys_ts_gpu.hw, + [CLKID_SYS_TS_NNA] = &t7_sys_ts_nna.hw, + [CLKID_SYS_TS_VPU] = &t7_sys_ts_vpu.hw, + [CLKID_SYS_TS_HEVC] = &t7_sys_ts_hevc.hw, + [CLKID_SYS_PWM_AO_AB] = &t7_sys_pwm_ao_ab.hw, + [CLKID_SYS_PWM_AO_CD] = &t7_sys_pwm_ao_cd.hw, + [CLKID_SYS_PWM_AO_EF] = &t7_sys_pwm_ao_ef.hw, + [CLKID_SYS_PWM_AO_GH] = &t7_sys_pwm_ao_gh.hw, + [CLKID_SYS_PWM_AB] = &t7_sys_pwm_ab.hw, + [CLKID_SYS_PWM_CD] = &t7_sys_pwm_cd.hw, + [CLKID_SYS_PWM_EF] = &t7_sys_pwm_ef.hw, +}; + +static const struct meson_clkc_data t7_peripherals_data = { + .hw_clks = { + .hws = t7_peripherals_hw_clks, + .num = ARRAY_SIZE(t7_peripherals_hw_clks), + }, +}; + +static const struct of_device_id t7_peripherals_clkc_match_table[] = { + { + .compatible = "amlogic,t7-peripherals-clkc", + .data = &t7_peripherals_data + }, + {} +}; +MODULE_DEVICE_TABLE(of, t7_peripherals_clkc_match_table); + +static struct platform_driver t7_peripherals_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "t7-peripherals-clkc", + .of_match_table = t7_peripherals_clkc_match_table, + }, +}; +module_platform_driver(t7_peripherals_clkc_driver); + +MODULE_DESCRIPTION("Amlogic T7 Peripherals Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/meson/t7-pll.c b/drivers/clk/meson/t7-pll.c new file mode 100644 index 000000000000..0a622f45fa36 --- /dev/null +++ b/drivers/clk/meson/t7-pll.c @@ -0,0 +1,1074 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR MIT) +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved. + * Author: Jian Hu + */ + +#include +#include +#include "clk-regmap.h" +#include "clk-pll.h" +#include "clk-mpll.h" +#include "meson-clkc-utils.h" +#include + +#define GP0PLL_CTRL0 0x00 +#define GP0PLL_CTRL1 0x04 +#define GP0PLL_CTRL2 0x08 +#define GP0PLL_CTRL3 0x0c +#define GP0PLL_CTRL4 0x10 +#define GP0PLL_CTRL5 0x14 +#define GP0PLL_CTRL6 0x18 +#define GP0PLL_STS 0x1c + +#define GP1PLL_CTRL0 0x00 +#define GP1PLL_CTRL1 0x04 +#define GP1PLL_CTRL2 0x08 +#define GP1PLL_CTRL3 0x0c +#define GP1PLL_STS 0x1c + +#define HIFIPLL_CTRL0 0x00 +#define HIFIPLL_CTRL1 0x04 +#define HIFIPLL_CTRL2 0x08 +#define HIFIPLL_CTRL3 0x0c +#define HIFIPLL_CTRL4 0x10 +#define HIFIPLL_CTRL5 0x14 +#define HIFIPLL_CTRL6 0x18 +#define HIFIPLL_STS 0x1c + +#define PCIEPLL_CTRL0 0x00 +#define PCIEPLL_CTRL1 0x04 +#define PCIEPLL_CTRL2 0x08 +#define PCIEPLL_CTRL3 0x0c +#define PCIEPLL_CTRL4 0x10 +#define PCIEPLL_CTRL5 0x14 +#define PCIEPLL_STS 0x18 + +#define MPLL_CTRL0 0x00 +#define MPLL_CTRL1 0x04 +#define MPLL_CTRL2 0x08 +#define MPLL_CTRL3 0x0c +#define MPLL_CTRL4 0x10 +#define MPLL_CTRL5 0x14 +#define MPLL_CTRL6 0x18 +#define MPLL_CTRL7 0x1c +#define MPLL_CTRL8 0x20 +#define MPLL_STS 0x24 + +#define HDMIPLL_CTRL0 0x00 +#define HDMIPLL_CTRL1 0x04 +#define HDMIPLL_CTRL2 0x08 +#define HDMIPLL_CTRL3 0x0c +#define HDMIPLL_CTRL4 0x10 +#define HDMIPLL_CTRL5 0x14 +#define HDMIPLL_CTRL6 0x18 +#define HDMIPLL_STS 0x1c + +#define MCLK_PLL_CNTL0 0x00 +#define MCLK_PLL_CNTL1 0x04 +#define MCLK_PLL_CNTL2 0x08 +#define MCLK_PLL_CNTL3 0x0c +#define MCLK_PLL_CNTL4 0x10 +#define MCLK_PLL_STS 0x14 + +static const struct pll_mult_range t7_media_pll_mult_range = { + .min = 125, + .max = 250, +}; + +static const struct reg_sequence t7_gp0_init_regs[] = { + { .reg = GP0PLL_CTRL1, .def = 0x00000000 }, + { .reg = GP0PLL_CTRL2, .def = 0x00000000 }, + { .reg = GP0PLL_CTRL3, .def = 0x48681c00 }, + { .reg = GP0PLL_CTRL4, .def = 0x88770290 }, + { .reg = GP0PLL_CTRL5, .def = 0x3927200a }, + { .reg = GP0PLL_CTRL6, .def = 0x56540000 }, +}; + +static struct clk_regmap t7_gp0_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = GP0PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = GP0PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = GP0PLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = GP0PLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = GP0PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_gp0_init_regs, + .init_count = ARRAY_SIZE(t7_gp0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_gp0_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = GP0PLL_CTRL0, + .shift = 16, + .width = 3, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp0_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_gp0_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * Compared with GP0 PLL, GP1 PLL is a newly designed PLL with + * a DCO range of 1.6GHz to 3.2GHz. + */ +static const struct pll_mult_range t7_gp1_pll_mult_range = { + .min = 67, + .max = 133, +}; + +static const struct reg_sequence t7_gp1_init_regs[] = { + { .reg = GP1PLL_CTRL1, .def = 0x1420500f }, + { .reg = GP1PLL_CTRL2, .def = 0x00023001 }, + { .reg = GP1PLL_CTRL3, .def = 0x00000000 }, +}; + +static struct clk_regmap t7_gp1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = GP1PLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = GP1PLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = GP1PLL_CTRL0, + .shift = 16, + .width = 5, + }, + .l = { + .reg_off = GP1PLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = GP1PLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_gp1_pll_mult_range, + .init_regs = t7_gp1_init_regs, + .init_count = ARRAY_SIZE(t7_gp1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_gp1_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = GP1PLL_CTRL0, + .shift = 12, + .width = 3, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "gp1_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_gp1_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_hifi_init_regs[] = { + { .reg = HIFIPLL_CTRL1, .def = 0x00000000 }, + { .reg = HIFIPLL_CTRL2, .def = 0x00000000 }, + { .reg = HIFIPLL_CTRL3, .def = 0x6a285c00 }, + { .reg = HIFIPLL_CTRL4, .def = 0x65771290 }, + { .reg = HIFIPLL_CTRL5, .def = 0x3927200a }, + { .reg = HIFIPLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap t7_hifi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HIFIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HIFIPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HIFIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HIFIPLL_CTRL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HIFIPLL_STS, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HIFIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_hifi_init_regs, + .init_count = ARRAY_SIZE(t7_hifi_init_regs), + .frac_max = 100000, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_hifi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HIFIPLL_CTRL0, + .shift = 16, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data) { + .name = "hifi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hifi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +/* + * The T7 PCIE PLL is fined tuned to deliver a very precise + * 100MHz reference clock for the PCIe Analog PHY, and thus requires + * a strict register sequence to enable the PLL. + */ +static const struct reg_sequence t7_pcie_pll_init_regs[] = { + { .reg = PCIEPLL_CTRL0, .def = 0x200c04c8 }, + { .reg = PCIEPLL_CTRL0, .def = 0x300c04c8 }, + { .reg = PCIEPLL_CTRL1, .def = 0x30000000 }, + { .reg = PCIEPLL_CTRL2, .def = 0x00001100 }, + { .reg = PCIEPLL_CTRL3, .def = 0x10058e00 }, + { .reg = PCIEPLL_CTRL4, .def = 0x000100c0 }, + { .reg = PCIEPLL_CTRL5, .def = 0x68000048 }, + { .reg = PCIEPLL_CTRL5, .def = 0x68000068, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL4, .def = 0x008100c0, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL0, .def = 0x340c04c8 }, + { .reg = PCIEPLL_CTRL0, .def = 0x140c04c8, .delay_us = 20 }, + { .reg = PCIEPLL_CTRL2, .def = 0x00001000 } +}; + +static struct clk_regmap t7_pcie_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = PCIEPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = PCIEPLL_CTRL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = PCIEPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = PCIEPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = PCIEPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .init_regs = t7_pcie_pll_init_regs, + .init_count = ARRAY_SIZE(t7_pcie_pll_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco", + .ops = &meson_clk_pcie_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor t7_pcie_pll_dco_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_pcie_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = PCIEPLL_CTRL0, + .shift = 16, + .width = 5, + /* the divisor is 32 when [16:21] = 0 */ + .flags = CLK_DIVIDER_MAX_AT_ZERO, + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_dco_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_pcie_pll = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_pcie_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_fixed_factor t7_mpll_prediv = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mpll_prediv", + .ops = &clk_fixed_factor_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +static const struct reg_sequence t7_mpll0_init_regs[] = { + { .reg = MPLL_CTRL2, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL1, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL1, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL1, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL1, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll0_init_regs, + .init_count = ARRAY_SIZE(t7_mpll0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL1, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll0_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll1_init_regs[] = { + { .reg = MPLL_CTRL4, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll1_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL3, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL3, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL3, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL3, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll1_init_regs, + .init_count = ARRAY_SIZE(t7_mpll1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL3, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll1_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll2_init_regs[] = { + { .reg = MPLL_CTRL6, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll2_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL5, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL5, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL5, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL5, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll2_init_regs, + .init_count = ARRAY_SIZE(t7_mpll2_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll2 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL5, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll2_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_mpll3_init_regs[] = { + { .reg = MPLL_CTRL8, .def = 0x40000033 } +}; + +static struct clk_regmap t7_mpll3_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = MPLL_CTRL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = MPLL_CTRL7, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = MPLL_CTRL7, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = MPLL_CTRL7, + .shift = 29, + .width = 1, + }, + .init_regs = t7_mpll3_init_regs, + .init_count = ARRAY_SIZE(t7_mpll3_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3_div", + .ops = &meson_clk_mpll_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mpll_prediv.hw + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_mpll3 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MPLL_CTRL7, + .bit_idx = 31, + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mpll3_div.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct reg_sequence t7_hdmi_init_regs[] = { + { .reg = HDMIPLL_CTRL1, .def = 0x00000000 }, + { .reg = HDMIPLL_CTRL2, .def = 0x00000000 }, + { .reg = HDMIPLL_CTRL3, .def = 0x6a28dc00 }, + { .reg = HDMIPLL_CTRL4, .def = 0x65771290 }, + { .reg = HDMIPLL_CTRL5, .def = 0x39272000 }, + { .reg = HDMIPLL_CTRL6, .def = 0x56540000 } +}; + +static struct clk_regmap t7_hdmi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HDMIPLL_CTRL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HDMIPLL_CTRL0, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HDMIPLL_CTRL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = HDMIPLL_CTRL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HDMIPLL_CTRL0, + .shift = 29, + .width = 1, + }, + .range = &t7_media_pll_mult_range, + .init_regs = t7_hdmi_init_regs, + .init_count = ARRAY_SIZE(t7_hdmi_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = (const struct clk_parent_data []) { + { .fw_name = "in0", } + }, + .num_parents = 1, + }, +}; + +static struct clk_regmap t7_hdmi_pll_od = { + .data = &(struct clk_regmap_div_data){ + .offset = HDMIPLL_CTRL0, + .shift = 16, + .width = 4, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hdmi_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_hdmi_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = HDMIPLL_CTRL0, + .shift = 20, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_hdmi_pll_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static const struct pll_mult_range t7_mclk_pll_mult_range = { + .min = 67, + .max = 133, +}; + +static const struct reg_sequence t7_mclk_init_regs[] = { + { .reg = MCLK_PLL_CNTL1, .def = 0x1470500f }, + { .reg = MCLK_PLL_CNTL2, .def = 0x00023001 }, + { .reg = MCLK_PLL_CNTL3, .def = 0x18180000 }, + { .reg = MCLK_PLL_CNTL4, .def = 0x00180303 }, +}; + +static struct clk_regmap t7_mclk_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 16, + .width = 5, + }, + .l = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = MCLK_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .l_detect = { + .reg_off = MCLK_PLL_CNTL2, + .shift = 6, + .width = 1, + }, + .range = &t7_mclk_pll_mult_range, + .init_regs = t7_mclk_init_regs, + .init_count = ARRAY_SIZE(t7_mclk_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .fw_name = "in0", + }, + .num_parents = 1, + }, +}; + +/* max div is 16 */ +static const struct clk_div_table t7_mclk_div[] = { + { .val = 0, .div = 1 }, + { .val = 1, .div = 2 }, + { .val = 2, .div = 4 }, + { .val = 3, .div = 8 }, + { .val = 4, .div = 16 }, + { /* sentinel */ } +}; + +static struct clk_regmap t7_mclk_pre_od = { + .data = &(struct clk_regmap_div_data){ + .offset = MCLK_PLL_CNTL0, + .shift = 12, + .width = 3, + .table = t7_mclk_div, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pre_od", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_pll_dco.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_pll = { + .data = &(struct clk_regmap_div_data){ + .offset = MCLK_PLL_CNTL4, + .shift = 16, + .width = 5, + .flags = CLK_DIVIDER_ONE_BASED, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_pll", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_pre_od.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = MCLK_PLL_CNTL4, + .mask = 0x3, + .shift = 4, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_0_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &t7_mclk_pll.hw }, + { .fw_name = "in1", }, + { .fw_name = "in2", }, + }, + .num_parents = 3, + }, +}; + +static struct clk_fixed_factor t7_mclk_0_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mclk_0_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mclk_0_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0_pre = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 2, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_0_pre", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_0_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_0 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 0, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_0", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_0_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = MCLK_PLL_CNTL4, + .mask = 0x3, + .shift = 12, + }, + .hw.init = &(struct clk_init_data){ + .name = "mclk_1_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = (const struct clk_parent_data []) { + { .hw = &t7_mclk_pll.hw }, + { .fw_name = "in1", }, + { .fw_name = "in2", }, + }, + .num_parents = 3, + }, +}; + +static struct clk_fixed_factor t7_mclk_1_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "mclk_1_div2", + .ops = &clk_fixed_factor_ops, + .parent_hws = (const struct clk_hw *[]) { &t7_mclk_1_sel.hw }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1_pre = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 10, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_1_pre", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_1_div2.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap t7_mclk_1 = { + .data = &(struct clk_regmap_gate_data){ + .offset = MCLK_PLL_CNTL4, + .bit_idx = 8, + }, + .hw.init = &(struct clk_init_data) { + .name = "mclk_1", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &t7_mclk_1_pre.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_hw *t7_gp0_hw_clks[] = { + [CLKID_GP0_PLL_DCO] = &t7_gp0_pll_dco.hw, + [CLKID_GP0_PLL] = &t7_gp0_pll.hw, +}; + +static struct clk_hw *t7_gp1_hw_clks[] = { + [CLKID_GP1_PLL_DCO] = &t7_gp1_pll_dco.hw, + [CLKID_GP1_PLL] = &t7_gp1_pll.hw, +}; + +static struct clk_hw *t7_hifi_hw_clks[] = { + [CLKID_HIFI_PLL_DCO] = &t7_hifi_pll_dco.hw, + [CLKID_HIFI_PLL] = &t7_hifi_pll.hw, +}; + +static struct clk_hw *t7_pcie_hw_clks[] = { + [CLKID_PCIE_PLL_DCO] = &t7_pcie_pll_dco.hw, + [CLKID_PCIE_PLL_DCO_DIV2] = &t7_pcie_pll_dco_div2.hw, + [CLKID_PCIE_PLL_OD] = &t7_pcie_pll_od.hw, + [CLKID_PCIE_PLL] = &t7_pcie_pll.hw, +}; + +static struct clk_hw *t7_mpll_hw_clks[] = { + [CLKID_MPLL_PREDIV] = &t7_mpll_prediv.hw, + [CLKID_MPLL0_DIV] = &t7_mpll0_div.hw, + [CLKID_MPLL0] = &t7_mpll0.hw, + [CLKID_MPLL1_DIV] = &t7_mpll1_div.hw, + [CLKID_MPLL1] = &t7_mpll1.hw, + [CLKID_MPLL2_DIV] = &t7_mpll2_div.hw, + [CLKID_MPLL2] = &t7_mpll2.hw, + [CLKID_MPLL3_DIV] = &t7_mpll3_div.hw, + [CLKID_MPLL3] = &t7_mpll3.hw, +}; + +static struct clk_hw *t7_hdmi_hw_clks[] = { + [CLKID_HDMI_PLL_DCO] = &t7_hdmi_pll_dco.hw, + [CLKID_HDMI_PLL_OD] = &t7_hdmi_pll_od.hw, + [CLKID_HDMI_PLL] = &t7_hdmi_pll.hw, +}; + +static struct clk_hw *t7_mclk_hw_clks[] = { + [CLKID_MCLK_PLL_DCO] = &t7_mclk_pll_dco.hw, + [CLKID_MCLK_PRE] = &t7_mclk_pre_od.hw, + [CLKID_MCLK_PLL] = &t7_mclk_pll.hw, + [CLKID_MCLK_0_SEL] = &t7_mclk_0_sel.hw, + [CLKID_MCLK_0_DIV2] = &t7_mclk_0_div2.hw, + [CLKID_MCLK_0_PRE] = &t7_mclk_0_pre.hw, + [CLKID_MCLK_0] = &t7_mclk_0.hw, + [CLKID_MCLK_1_SEL] = &t7_mclk_1_sel.hw, + [CLKID_MCLK_1_DIV2] = &t7_mclk_1_div2.hw, + [CLKID_MCLK_1_PRE] = &t7_mclk_1_pre.hw, + [CLKID_MCLK_1] = &t7_mclk_1.hw, +}; + +static const struct meson_clkc_data t7_gp0_data = { + .hw_clks = { + .hws = t7_gp0_hw_clks, + .num = ARRAY_SIZE(t7_gp0_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_gp1_data = { + .hw_clks = { + .hws = t7_gp1_hw_clks, + .num = ARRAY_SIZE(t7_gp1_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_hifi_data = { + .hw_clks = { + .hws = t7_hifi_hw_clks, + .num = ARRAY_SIZE(t7_hifi_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_pcie_data = { + .hw_clks = { + .hws = t7_pcie_hw_clks, + .num = ARRAY_SIZE(t7_pcie_hw_clks), + }, +}; + +static const struct reg_sequence t7_mpll_init_regs[] = { + { .reg = MPLL_CTRL0, .def = 0x00000543 } +}; + +static const struct meson_clkc_data t7_mpll_data = { + .hw_clks = { + .hws = t7_mpll_hw_clks, + .num = ARRAY_SIZE(t7_mpll_hw_clks), + }, + .init_regs = t7_mpll_init_regs, + .init_count = ARRAY_SIZE(t7_mpll_init_regs), +}; + +static const struct meson_clkc_data t7_hdmi_data = { + .hw_clks = { + .hws = t7_hdmi_hw_clks, + .num = ARRAY_SIZE(t7_hdmi_hw_clks), + }, +}; + +static const struct meson_clkc_data t7_mclk_data = { + .hw_clks = { + .hws = t7_mclk_hw_clks, + .num = ARRAY_SIZE(t7_mclk_hw_clks), + }, +}; + +static const struct of_device_id t7_pll_clkc_match_table[] = { + { .compatible = "amlogic,t7-gp0-pll", .data = &t7_gp0_data, }, + { .compatible = "amlogic,t7-gp1-pll", .data = &t7_gp1_data, }, + { .compatible = "amlogic,t7-hifi-pll", .data = &t7_hifi_data, }, + { .compatible = "amlogic,t7-pcie-pll", .data = &t7_pcie_data, }, + { .compatible = "amlogic,t7-mpll", .data = &t7_mpll_data, }, + { .compatible = "amlogic,t7-hdmi-pll", .data = &t7_hdmi_data, }, + { .compatible = "amlogic,t7-mclk-pll", .data = &t7_mclk_data, }, + {} +}; +MODULE_DEVICE_TABLE(of, t7_pll_clkc_match_table); + +static struct platform_driver t7_pll_clkc_driver = { + .probe = meson_clkc_mmio_probe, + .driver = { + .name = "t7-pll-clkc", + .of_match_table = t7_pll_clkc_match_table, + }, +}; +module_platform_driver(t7_pll_clkc_driver); + +MODULE_DESCRIPTION("Amlogic T7 PLL Clock Controller driver"); +MODULE_AUTHOR("Jian Hu "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("CLK_MESON"); diff --git a/drivers/clk/microchip/Kconfig b/drivers/clk/microchip/Kconfig index 1b9e43eb5497..0c03b14699bf 100644 --- a/drivers/clk/microchip/Kconfig +++ b/drivers/clk/microchip/Kconfig @@ -5,8 +5,8 @@ config COMMON_CLK_PIC32 config MCHP_CLK_MPFS bool "Clk driver for PolarFire SoC" - depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST - default ARCH_MICROCHIP_POLARFIRE + depends on ARCH_MICROCHIP || COMPILE_TEST + default y depends on MFD_SYSCON select AUXILIARY_BUS select REGMAP_MMIO diff --git a/drivers/clk/microchip/clk-core.c b/drivers/clk/microchip/clk-core.c index b34348d491f3..692152b5094e 100644 --- a/drivers/clk/microchip/clk-core.c +++ b/drivers/clk/microchip/clk-core.c @@ -9,8 +9,7 @@ #include #include #include -#include -#include +#include #include "clk-core.h" @@ -283,14 +282,13 @@ static u8 roclk_get_parent(struct clk_hw *hw) v = (readl(refo->ctrl_reg) >> REFO_SEL_SHIFT) & REFO_SEL_MASK; - if (!refo->parent_map) - return v; + if (refo->parent_map) { + for (i = 0; i < clk_hw_get_num_parents(hw); i++) + if (refo->parent_map[i] == v) + return i; + } - for (i = 0; i < clk_hw_get_num_parents(hw); i++) - if (refo->parent_map[i] == v) - return i; - - return -EINVAL; + return v; } static unsigned long roclk_calc_rate(unsigned long parent_rate, @@ -780,15 +778,6 @@ static unsigned long sclk_get_rate(struct clk_hw *hw, unsigned long parent_rate) return parent_rate / div; } -static int sclk_determine_rate(struct clk_hw *hw, - struct clk_rate_request *req) -{ - req->rate = calc_best_divided_rate(req->rate, req->best_parent_rate, - SLEW_SYSDIV, 1); - - return 0; -} - static int sclk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { @@ -826,13 +815,13 @@ static u8 sclk_get_parent(struct clk_hw *hw) v = (readl(sclk->mux_reg) >> OSC_CUR_SHIFT) & OSC_CUR_MASK; - if (!sclk->parent_map) - return v; + if (sclk->parent_map) { + for (i = 0; i < clk_hw_get_num_parents(hw); i++) + if (sclk->parent_map[i] == v) + return i; + } - for (i = 0; i < clk_hw_get_num_parents(hw); i++) - if (sclk->parent_map[i] == v) - return i; - return -EINVAL; + return v; } static int sclk_set_parent(struct clk_hw *hw, u8 index) @@ -912,7 +901,6 @@ static int sclk_init(struct clk_hw *hw) const struct clk_ops pic32_sclk_ops = { .get_parent = sclk_get_parent, .set_parent = sclk_set_parent, - .determine_rate = sclk_determine_rate, .set_rate = sclk_set_rate, .recalc_rate = sclk_get_rate, .init = sclk_init, diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c index 23c43a46604e..84532ce8fd09 100644 --- a/drivers/clk/mmp/clk-apbc.c +++ b/drivers/clk/mmp/clk-apbc.c @@ -124,7 +124,7 @@ struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - apbc = kzalloc(sizeof(*apbc), GFP_KERNEL); + apbc = kzalloc_obj(*apbc); if (!apbc) return NULL; diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c index 9313428b083a..30bbac1deca1 100644 --- a/drivers/clk/mmp/clk-apmu.c +++ b/drivers/clk/mmp/clk-apmu.c @@ -69,7 +69,7 @@ struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - apmu = kzalloc(sizeof(*apmu), GFP_KERNEL); + apmu = kzalloc_obj(*apmu); if (!apmu) return NULL; diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c index 0b1bb01346f0..13bfc4c99f3a 100644 --- a/drivers/clk/mmp/clk-frac.c +++ b/drivers/clk/mmp/clk-frac.c @@ -180,7 +180,7 @@ struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); } - factor = kzalloc(sizeof(*factor), GFP_KERNEL); + factor = kzalloc_obj(*factor); if (!factor) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mmp/clk-gate.c b/drivers/clk/mmp/clk-gate.c index 6855815ee8be..cc2f841ae9d9 100644 --- a/drivers/clk/mmp/clk-gate.c +++ b/drivers/clk/mmp/clk-gate.c @@ -99,7 +99,7 @@ struct clk *mmp_clk_register_gate(struct device *dev, const char *name, struct clk_init_data init; /* allocate the gate */ - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mmp/clk-mix.c b/drivers/clk/mmp/clk-mix.c index 07ac9e6937e5..b1c9899c71af 100644 --- a/drivers/clk/mmp/clk-mix.c +++ b/drivers/clk/mmp/clk-mix.c @@ -448,7 +448,7 @@ struct clk *mmp_clk_register_mix(struct device *dev, struct clk *clk; struct clk_init_data init; - mix = kzalloc(sizeof(*mix), GFP_KERNEL); + mix = kzalloc_obj(*mix); if (!mix) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c index a4f15cee630e..77e9244b53e5 100644 --- a/drivers/clk/mmp/clk-of-mmp2.c +++ b/drivers/clk/mmp/clk-of-mmp2.c @@ -462,7 +462,7 @@ static void mmp2_clk_reset_init(struct device_node *np, int i, nr_resets; nr_resets = ARRAY_SIZE(apbc_gate_clks); - cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + cells = kzalloc_objs(*cells, nr_resets); if (!cells) return; @@ -516,7 +516,7 @@ static void __init mmp2_clk_init(struct device_node *np) { struct mmp2_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c index 5f250427e60d..e3d6f4b407ed 100644 --- a/drivers/clk/mmp/clk-of-pxa168.c +++ b/drivers/clk/mmp/clk-of-pxa168.c @@ -282,7 +282,7 @@ static void pxa168_clk_reset_init(struct device_node *np, int i, nr_resets; nr_resets = ARRAY_SIZE(apbc_gate_clks); - cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + cells = kzalloc_objs(*cells, nr_resets); if (!cells) return; @@ -301,7 +301,7 @@ static void __init pxa168_clk_init(struct device_node *np) { struct pxa168_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; diff --git a/drivers/clk/mmp/clk-of-pxa1928.c b/drivers/clk/mmp/clk-of-pxa1928.c index ebb6e278eda3..3bc9866a2191 100644 --- a/drivers/clk/mmp/clk-of-pxa1928.c +++ b/drivers/clk/mmp/clk-of-pxa1928.c @@ -187,7 +187,7 @@ static void pxa1928_clk_reset_init(struct device_node *np, int i, base, nr_resets; nr_resets = ARRAY_SIZE(apbc_gate_clks); - cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + cells = kzalloc_objs(*cells, nr_resets); if (!cells) return; @@ -208,7 +208,7 @@ static void __init pxa1928_mpmu_clk_init(struct device_node *np) { struct pxa1928_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; @@ -227,7 +227,7 @@ static void __init pxa1928_apmu_clk_init(struct device_node *np) { struct pxa1928_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; @@ -248,7 +248,7 @@ static void __init pxa1928_apbc_clk_init(struct device_node *np) { struct pxa1928_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c index fe65e7bdb411..d90bcc9a8ae7 100644 --- a/drivers/clk/mmp/clk-of-pxa910.c +++ b/drivers/clk/mmp/clk-of-pxa910.c @@ -239,7 +239,7 @@ static void pxa910_clk_reset_init(struct device_node *np, nr_resets_apbc = ARRAY_SIZE(apbc_gate_clks); nr_resets_apbcp = ARRAY_SIZE(apbcp_gate_clks); nr_resets = nr_resets_apbc + nr_resets_apbcp; - cells = kcalloc(nr_resets, sizeof(*cells), GFP_KERNEL); + cells = kzalloc_objs(*cells, nr_resets); if (!cells) return; @@ -270,7 +270,7 @@ static void __init pxa910_clk_init(struct device_node *np) { struct pxa910_clk_unit *pxa_unit; - pxa_unit = kzalloc(sizeof(*pxa_unit), GFP_KERNEL); + pxa_unit = kzalloc_obj(*pxa_unit); if (!pxa_unit) return; diff --git a/drivers/clk/mmp/clk-pll.c b/drivers/clk/mmp/clk-pll.c index 962014cfdc44..430f5e3c8540 100644 --- a/drivers/clk/mmp/clk-pll.c +++ b/drivers/clk/mmp/clk-pll.c @@ -108,7 +108,7 @@ static struct clk *mmp_clk_register_pll(char *name, struct clk *clk; struct clk_init_data init; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mmp/clk.c b/drivers/clk/mmp/clk.c index ca7d37e2c7be..48b746bef833 100644 --- a/drivers/clk/mmp/clk.c +++ b/drivers/clk/mmp/clk.c @@ -12,7 +12,7 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit, { struct clk **clk_table; - clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); + clk_table = kzalloc_objs(struct clk *, nr_clks); if (!clk_table) return; diff --git a/drivers/clk/mmp/pwr-island.c b/drivers/clk/mmp/pwr-island.c index eaf5d2c5e593..1f57917133da 100644 --- a/drivers/clk/mmp/pwr-island.c +++ b/drivers/clk/mmp/pwr-island.c @@ -95,7 +95,7 @@ struct generic_pm_domain *mmp_pm_domain_register(const char *name, { struct mmp_pm_domain *pm_domain; - pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL); + pm_domain = kzalloc_obj(*pm_domain); if (!pm_domain) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mmp/reset.c b/drivers/clk/mmp/reset.c index ded7e391c737..1e4e105ef6ff 100644 --- a/drivers/clk/mmp/reset.c +++ b/drivers/clk/mmp/reset.c @@ -85,7 +85,7 @@ void mmp_clk_reset_register(struct device_node *np, { struct mmp_clk_reset_unit *unit; - unit = kzalloc(sizeof(*unit), GFP_KERNEL); + unit = kzalloc_obj(*unit); if (!unit) return; diff --git a/drivers/clk/mvebu/clk-corediv.c b/drivers/clk/mvebu/clk-corediv.c index 628032341cbb..ae48293b0c41 100644 --- a/drivers/clk/mvebu/clk-corediv.c +++ b/drivers/clk/mvebu/clk-corediv.c @@ -270,13 +270,11 @@ mvebu_corediv_clk_init(struct device_node *node, clk_data.clk_num = soc_desc->ndescs; /* clks holds the clock array */ - clks = kcalloc(clk_data.clk_num, sizeof(struct clk *), - GFP_KERNEL); + clks = kzalloc_objs(struct clk *, clk_data.clk_num); if (WARN_ON(!clks)) goto err_unmap; /* corediv holds the clock specific array */ - corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), - GFP_KERNEL); + corediv = kzalloc_objs(struct clk_corediv, clk_data.clk_num); if (WARN_ON(!corediv)) goto err_free_clks; diff --git a/drivers/clk/mvebu/clk-cpu.c b/drivers/clk/mvebu/clk-cpu.c index 0de7660e73d2..26d52ecaac50 100644 --- a/drivers/clk/mvebu/clk-cpu.c +++ b/drivers/clk/mvebu/clk-cpu.c @@ -183,11 +183,11 @@ static void __init of_cpu_clk_setup(struct device_node *node) pr_warn("%s: pmu-dfs base register not set, dynamic frequency scaling not available\n", __func__); - cpuclk = kcalloc(ncpus, sizeof(*cpuclk), GFP_KERNEL); + cpuclk = kzalloc_objs(*cpuclk, ncpus); if (WARN_ON(!cpuclk)) goto cpuclk_out; - clks = kcalloc(ncpus, sizeof(*clks), GFP_KERNEL); + clks = kzalloc_objs(*clks, ncpus); if (WARN_ON(!clks)) goto clks_out; diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index 5adbbd91a6db..28f2e1b2a932 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -124,8 +124,7 @@ void __init mvebu_coreclk_setup(struct device_node *np, if (desc->get_refclk_freq) clk_data.clk_num += 1; - clk_data.clks = kcalloc(clk_data.clk_num, sizeof(*clk_data.clks), - GFP_KERNEL); + clk_data.clks = kzalloc_objs(*clk_data.clks, clk_data.clk_num); if (WARN_ON(!clk_data.clks)) { iounmap(base); return; @@ -258,7 +257,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np, clk_put(clk); } - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (WARN_ON(!ctrl)) goto ctrl_out; @@ -272,8 +271,7 @@ void __init mvebu_clk_gating_setup(struct device_node *np, n++; ctrl->num_gates = n; - ctrl->gates = kcalloc(ctrl->num_gates, sizeof(*ctrl->gates), - GFP_KERNEL); + ctrl->gates = kzalloc_objs(*ctrl->gates, ctrl->num_gates); if (WARN_ON(!ctrl->gates)) goto gates_out; diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c index b47c86906046..fa95eb7197af 100644 --- a/drivers/clk/mvebu/cp110-system-controller.c +++ b/drivers/clk/mvebu/cp110-system-controller.c @@ -180,7 +180,7 @@ static struct clk_hw *cp110_register_gate(const char *name, struct clk_init_data init; int ret; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mvebu/kirkwood.c b/drivers/clk/mvebu/kirkwood.c index 8bc893df4736..ed061d82fb65 100644 --- a/drivers/clk/mvebu/kirkwood.c +++ b/drivers/clk/mvebu/kirkwood.c @@ -297,7 +297,7 @@ static void __init kirkwood_clk_muxing_setup(struct device_node *np, if (WARN_ON(!base)) return; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (WARN_ON(!ctrl)) goto ctrl_out; @@ -309,8 +309,7 @@ static void __init kirkwood_clk_muxing_setup(struct device_node *np, n++; ctrl->num_muxes = n; - ctrl->muxes = kcalloc(ctrl->num_muxes, sizeof(struct clk *), - GFP_KERNEL); + ctrl->muxes = kzalloc_objs(struct clk *, ctrl->num_muxes); if (WARN_ON(!ctrl->muxes)) goto muxes_out; diff --git a/drivers/clk/mxs/clk-div.c b/drivers/clk/mxs/clk-div.c index 8afe1a9c1552..fe7224162b3c 100644 --- a/drivers/clk/mxs/clk-div.c +++ b/drivers/clk/mxs/clk-div.c @@ -74,7 +74,7 @@ struct clk *mxs_clk_div(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mxs/clk-frac.c b/drivers/clk/mxs/clk-frac.c index 73f514fb84ff..52eb82fde322 100644 --- a/drivers/clk/mxs/clk-frac.c +++ b/drivers/clk/mxs/clk-frac.c @@ -116,7 +116,7 @@ struct clk *mxs_clk_frac(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - frac = kzalloc(sizeof(*frac), GFP_KERNEL); + frac = kzalloc_obj(*frac); if (!frac) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mxs/clk-pll.c b/drivers/clk/mxs/clk-pll.c index 431cf6f2c936..581868e0693c 100644 --- a/drivers/clk/mxs/clk-pll.c +++ b/drivers/clk/mxs/clk-pll.c @@ -86,7 +86,7 @@ struct clk *mxs_clk_pll(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/mxs/clk-ref.c b/drivers/clk/mxs/clk-ref.c index a99ee4cd2ece..9667d4d3c2a8 100644 --- a/drivers/clk/mxs/clk-ref.c +++ b/drivers/clk/mxs/clk-ref.c @@ -117,7 +117,7 @@ struct clk *mxs_clk_ref(const char *name, const char *parent_name, struct clk *clk; struct clk_init_data init; - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/nuvoton/clk-ma35d1-divider.c b/drivers/clk/nuvoton/clk-ma35d1-divider.c index e39f53d5bf45..e992e7c30341 100644 --- a/drivers/clk/nuvoton/clk-ma35d1-divider.c +++ b/drivers/clk/nuvoton/clk-ma35d1-divider.c @@ -44,11 +44,8 @@ static int ma35d1_clkdiv_determine_rate(struct clk_hw *hw, { struct ma35d1_adc_clk_div *dclk = to_ma35d1_adc_clk_div(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - dclk->table, dclk->width, - CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, dclk->table, dclk->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int ma35d1_clkdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) diff --git a/drivers/clk/nxp/clk-lpc18xx-ccu.c b/drivers/clk/nxp/clk-lpc18xx-ccu.c index 751b786d73f8..dcb6d0c0b41a 100644 --- a/drivers/clk/nxp/clk-lpc18xx-ccu.c +++ b/drivers/clk/nxp/clk-lpc18xx-ccu.c @@ -208,7 +208,7 @@ static void lpc18xx_ccu_register_branch_gate_div(struct lpc18xx_clk_branch *bran struct clk_hw *div_hw = NULL; if (branch->flags & CCU_BRANCH_HAVE_DIV2) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return; @@ -274,7 +274,7 @@ static void __init lpc18xx_ccu_init(struct device_node *np) return; } - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) { iounmap(reg_base); return; diff --git a/drivers/clk/nxp/clk-lpc32xx.c b/drivers/clk/nxp/clk-lpc32xx.c index 23f980cf6a2b..ae2fa5341a2e 100644 --- a/drivers/clk/nxp/clk-lpc32xx.c +++ b/drivers/clk/nxp/clk-lpc32xx.c @@ -975,10 +975,8 @@ static int clk_divider_determine_rate(struct clk_hw *hw, return 0; } - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/pistachio/clk-pll.c b/drivers/clk/pistachio/clk-pll.c index d05337915e2b..5b268a985a9c 100644 --- a/drivers/clk/pistachio/clk-pll.c +++ b/drivers/clk/pistachio/clk-pll.c @@ -457,7 +457,7 @@ static struct clk *pll_register(const char *name, const char *parent_name, struct clk_init_data init; struct clk *clk; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/pistachio/clk.c b/drivers/clk/pistachio/clk.c index 23d076a2b133..80c722c77a1b 100644 --- a/drivers/clk/pistachio/clk.c +++ b/drivers/clk/pistachio/clk.c @@ -17,11 +17,11 @@ pistachio_clk_alloc_provider(struct device_node *node, unsigned int num_clks) { struct pistachio_clk_provider *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return p; - p->clk_data.clks = kcalloc(num_clks, sizeof(struct clk *), GFP_KERNEL); + p->clk_data.clks = kzalloc_objs(struct clk *, num_clks); if (!p->clk_data.clks) goto free_provider; p->clk_data.clk_num = num_clks; diff --git a/drivers/clk/pxa/clk-pxa.c b/drivers/clk/pxa/clk-pxa.c index ebee2afd05de..d153ce76c64b 100644 --- a/drivers/clk/pxa/clk-pxa.c +++ b/drivers/clk/pxa/clk-pxa.c @@ -104,7 +104,7 @@ int __init clk_pxa_cken_init(const struct desc_clk_cken *clks, struct clk *clk; for (i = 0; i < nb_clks; i++) { - pxa_clk = kzalloc(sizeof(*pxa_clk), GFP_KERNEL); + pxa_clk = kzalloc_obj(*pxa_clk); if (!pxa_clk) return -ENOMEM; pxa_clk->is_in_low_power = clks[i].is_in_low_power; diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index a284ba040b78..a8a86ea6bb74 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -46,6 +46,61 @@ config CLK_GLYMUR_TCSRCC Support for the TCSR clock controller on GLYMUR devices. Say Y if you want to use peripheral devices such as USB/PCIe/EDP. +config CLK_KAANAPALI_CAMCC + tristate "Kaanapali Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the camera clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support camera devices and functionality such as + capturing pictures. + +config CLK_KAANAPALI_DISPCC + tristate "Kaanapali Display Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the display clock controller on Qualcomm Technologies, Inc + Kaanapali devices. + Say Y if you want to support display devices and functionality such as + splash screen. + +config CLK_KAANAPALI_GCC + tristate "Kaanapali Global Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the global clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as UART, + SPI, I2C, USB, SD/UFS, PCIe etc. + +config CLK_KAANAPALI_GPUCC + tristate "Kaanapali Graphics Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the graphics clock controller on Kaanapali devices. + Say Y if you want to support graphics controller devices and + functionality such as 3D graphics. + +config CLK_KAANAPALI_TCSRCC + tristate "Kaanapali TCSR Clock Controller" + depends on ARM64 || COMPILE_TEST + select QCOM_GDSC + help + Support for the TCSR clock controller on Kaanapali devices. + Say Y if you want to use peripheral devices such as PCIe, USB, UFS. + +config CLK_KAANAPALI_VIDEOCC + tristate "Kaanapali Video Clock Controller" + depends on ARM64 || COMPILE_TEST + select CLK_KAANAPALI_GCC + help + Support for the video clock controller on Kaanapali devices. + Say Y if you want to support video devices and functionality such as + video encode/decode. + config CLK_X1E80100_CAMCC tristate "X1E80100 Camera Clock Controller" depends on ARM64 || COMPILE_TEST @@ -370,12 +425,12 @@ config MSM_GCC_8916 SD/eMMC, display, graphics, camera etc. config MSM_GCC_8917 - tristate "MSM89(17/37)/QM215 Global Clock Controller" + tristate "MSM89(17/37/40)/QM215/SDM439 Global Clock Controller" depends on ARM64 || COMPILE_TEST select QCOM_GDSC help - Support for the global clock controller on msm8917, msm8937 - and qm215 devices. + Support for the global clock controller on msm8917, msm8937, + msm8940, qm215 and sdm439 devices. Say Y if you want to use devices such as UART, SPI i2c, USB, SD/eMMC, display, graphics, camera etc. @@ -1069,6 +1124,16 @@ config SM_CAMCC_8650 Support for the camera clock controller on SM8650 devices. Say Y if you want to support camera devices and camera functionality. +config SM_CAMCC_8750 + tristate "SM8750 Camera Clock Controller" + depends on ARM64 || COMPILE_TEST + select SM_GCC_8750 + help + Support for the camera clock controller on SM8750 devices. + The camera clock controller has a separate cambist controller which + controls the mclk of the camera clocks. + Say Y if you want to support camera devices and camera functionality. + config SM_DISPCC_4450 tristate "SM4450 Display Clock Controller" depends on ARM64 || COMPILE_TEST diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile index 0ac8a9055a43..6b0ad8832b55 100644 --- a/drivers/clk/qcom/Makefile +++ b/drivers/clk/qcom/Makefile @@ -24,6 +24,12 @@ obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o obj-$(CONFIG_CLK_GLYMUR_DISPCC) += dispcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_GCC) += gcc-glymur.o obj-$(CONFIG_CLK_GLYMUR_TCSRCC) += tcsrcc-glymur.o +obj-$(CONFIG_CLK_KAANAPALI_CAMCC) += cambistmclkcc-kaanapali.o camcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_DISPCC) += dispcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_GCC) += gcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_GPUCC) += gpucc-kaanapali.o gxclkctl-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_TCSRCC) += tcsrcc-kaanapali.o +obj-$(CONFIG_CLK_KAANAPALI_VIDEOCC) += videocc-kaanapali.o obj-$(CONFIG_CLK_X1E80100_CAMCC) += camcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_DISPCC) += dispcc-x1e80100.o obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o @@ -136,6 +142,7 @@ obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o obj-$(CONFIG_SM_CAMCC_8650) += camcc-sm8650.o +obj-$(CONFIG_SM_CAMCC_8750) += cambistmclkcc-sm8750.o camcc-sm8750.o obj-$(CONFIG_SM_CAMCC_MILOS) += camcc-milos.o obj-$(CONFIG_SM_DISPCC_4450) += dispcc-sm4450.o obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o diff --git a/drivers/clk/qcom/cambistmclkcc-kaanapali.c b/drivers/clk/qcom/cambistmclkcc-kaanapali.c new file mode 100644 index 000000000000..066c1087b0b6 --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-kaanapali.c @@ -0,0 +1,437 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, +}; + +static const struct pll_vco rivian_eko_t_vco[] = { + { 883200000, 1171200000, 0 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .cal_l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_eko_t_vco, + .num_vco = ARRAY_SIZE(rivian_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_eko_t_ops, + }, + }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { + .cmd_rcgr = 0x401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { + .cmd_rcgr = 0x4070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { + .cmd_rcgr = 0x408c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { + .cmd_rcgr = 0x40a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { + .cmd_rcgr = 0x40c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { + .halt_reg = 0x4018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { + .halt_reg = 0x4034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { + .halt_reg = 0x4050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { + .halt_reg = 0x406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x406c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { + .halt_reg = 0x4088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { + .halt_reg = 0x40a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { + .halt_reg = 0x40c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { + .halt_reg = 0x40dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *cam_bist_mclk_cc_kaanapali_clocks[] = { + [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, + [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_kaanapali_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_kaanapali_critical_cbcrs[] = { + 0x40e0, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_bist_mclk_cc_kaanapali_driver_data = { + .alpha_plls = cam_bist_mclk_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_plls), + .clk_cbcrs = cam_bist_mclk_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_bist_mclk_cc_kaanapali_desc = { + .config = &cam_bist_mclk_cc_kaanapali_regmap_config, + .clks = cam_bist_mclk_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_kaanapali_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_kaanapali_match_table); + +static int cam_bist_mclk_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_kaanapali_desc); +} + +static struct platform_driver cam_bist_mclk_cc_kaanapali_driver = { + .probe = cam_bist_mclk_cc_kaanapali_probe, + .driver = { + .name = "cambistmclkcc-kaanapali", + .of_match_table = cam_bist_mclk_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/cambistmclkcc-sm8750.c b/drivers/clk/qcom/cambistmclkcc-sm8750.c new file mode 100644 index 000000000000..d889a8f6561d --- /dev/null +++ b/drivers/clk/qcom/cambistmclkcc-sm8750.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, + P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, + P_SLEEP_CLK, +}; + +static const struct pll_vco rivian_elu_vco[] = { + { 833000000, 1125000000, 0 }, + { 777000000, 1062000000, 1 }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_bist_mclk_cc_pll0_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x12000000, + .config_ctl_hi_val = 0x00890263, + .config_ctl_hi1_val = 0x1af04237, + .config_ctl_hi2_val = 0x00000000, +}; + +static struct clk_alpha_pll cam_bist_mclk_cc_pll0 = { + .offset = 0x0, + .config = &cam_bist_mclk_cc_pll0_config, + .vco_table = rivian_elu_vco, + .num_vco = ARRAY_SIZE(rivian_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_RIVIAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_rivian_elu_ops, + }, + }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 3 }, + { P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 5 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, + { .hw = &cam_bist_mclk_cc_pll0.clkr.hw }, +}; + +static const struct parent_map cam_bist_mclk_cc_parent_map_1[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_bist_mclk_cc_parent_data_1[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_mclk0_clk_src[] = { + F(12000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 8), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(24000000, P_CAM_BIST_MCLK_CC_PLL0_OUT_EVEN, 10, 1, 4), + F(68571429, P_CAM_BIST_MCLK_CC_PLL0_OUT_MAIN, 14, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk0_clk_src = { + .cmd_rcgr = 0x4000, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk1_clk_src = { + .cmd_rcgr = 0x401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk2_clk_src = { + .cmd_rcgr = 0x4038, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk3_clk_src = { + .cmd_rcgr = 0x4054, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk4_clk_src = { + .cmd_rcgr = 0x4070, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk5_clk_src = { + .cmd_rcgr = 0x408c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk6_clk_src = { + .cmd_rcgr = 0x40a8, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_bist_mclk_cc_mclk7_clk_src = { + .cmd_rcgr = 0x40c4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_0, + .freq_tbl = ftbl_cam_bist_mclk_cc_mclk0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_bist_mclk_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_bist_mclk_cc_sleep_clk_src = { + .cmd_rcgr = 0x40e0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_bist_mclk_cc_parent_map_1, + .freq_tbl = ftbl_cam_bist_mclk_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_sleep_clk_src", + .parent_data = cam_bist_mclk_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_bist_mclk_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk0_clk = { + .halt_reg = 0x4018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk1_clk = { + .halt_reg = 0x4034, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4034, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk2_clk = { + .halt_reg = 0x4050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk3_clk = { + .halt_reg = 0x406c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x406c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk4_clk = { + .halt_reg = 0x4088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x4088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk5_clk = { + .halt_reg = 0x40a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk6_clk = { + .halt_reg = 0x40c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk6_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_bist_mclk_cc_mclk7_clk = { + .halt_reg = 0x40dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x40dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_bist_mclk_cc_mclk7_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_bist_mclk_cc_mclk7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *cam_bist_mclk_cc_sm8750_clocks[] = { + [CAM_BIST_MCLK_CC_MCLK0_CLK] = &cam_bist_mclk_cc_mclk0_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK0_CLK_SRC] = &cam_bist_mclk_cc_mclk0_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK] = &cam_bist_mclk_cc_mclk1_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK1_CLK_SRC] = &cam_bist_mclk_cc_mclk1_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK] = &cam_bist_mclk_cc_mclk2_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK2_CLK_SRC] = &cam_bist_mclk_cc_mclk2_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK] = &cam_bist_mclk_cc_mclk3_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK3_CLK_SRC] = &cam_bist_mclk_cc_mclk3_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK] = &cam_bist_mclk_cc_mclk4_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK4_CLK_SRC] = &cam_bist_mclk_cc_mclk4_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK] = &cam_bist_mclk_cc_mclk5_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK5_CLK_SRC] = &cam_bist_mclk_cc_mclk5_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK] = &cam_bist_mclk_cc_mclk6_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK6_CLK_SRC] = &cam_bist_mclk_cc_mclk6_clk_src.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK] = &cam_bist_mclk_cc_mclk7_clk.clkr, + [CAM_BIST_MCLK_CC_MCLK7_CLK_SRC] = &cam_bist_mclk_cc_mclk7_clk_src.clkr, + [CAM_BIST_MCLK_CC_PLL0] = &cam_bist_mclk_cc_pll0.clkr, + [CAM_BIST_MCLK_CC_SLEEP_CLK_SRC] = &cam_bist_mclk_cc_sleep_clk_src.clkr, +}; + +static struct clk_alpha_pll *cam_bist_mclk_cc_sm8750_plls[] = { + &cam_bist_mclk_cc_pll0, +}; + +static u32 cam_bist_mclk_cc_sm8750_critical_cbcrs[] = { + 0x40f8, /* CAM_BIST_MCLK_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_bist_mclk_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x5010, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_bist_mclk_cc_sm8750_driver_data = { + .alpha_plls = cam_bist_mclk_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_plls), + .clk_cbcrs = cam_bist_mclk_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_bist_mclk_cc_sm8750_desc = { + .config = &cam_bist_mclk_cc_sm8750_regmap_config, + .clks = cam_bist_mclk_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_bist_mclk_cc_sm8750_clocks), + .use_rpm = true, + .driver_data = &cam_bist_mclk_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_bist_mclk_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-cambistmclkcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_bist_mclk_cc_sm8750_match_table); + +static int cam_bist_mclk_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_bist_mclk_cc_sm8750_desc); +} + +static struct platform_driver cam_bist_mclk_cc_sm8750_driver = { + .probe = cam_bist_mclk_cc_sm8750_probe, + .driver = { + .name = "cambistmclkcc-sm8750", + .of_match_table = cam_bist_mclk_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_bist_mclk_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMBISTMCLKCC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-kaanapali.c b/drivers/clk/qcom/camcc-kaanapali.c new file mode 100644 index 000000000000..82967993fcff --- /dev/null +++ b/drivers/clk/qcom/camcc-kaanapali.c @@ -0,0 +1,2661 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_AHB_CLK, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_ODD, + P_CAM_CC_PLL7_OUT_EVEN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 1200.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .cal_l = 0x48, + .alpha = 0x8000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 665.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .cal_l = 0x48, + .alpha = 0xa2aa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 677.6 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .cal_l = 0x48, + .alpha = 0x4aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 720.56 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .cal_l = 0x48, + .alpha = 0x8777, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 960.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00008408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +/* 1000.0 MHz Configuration */ +static const struct alpha_pll_config cam_cc_pll7_config = { + .l = 0x34, + .cal_l = 0x48, + .alpha = 0x1555, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll7 = { + .offset = 0x7000, + .config = &cam_cc_pll7_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll7_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll7_out_even = { + .offset = 0x7000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll7_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll7_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll7_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll7.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL7_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll7_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x212cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x21250, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0x2126c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x21288, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x21064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cre_clk_src[] = { + F(137142857, P_CAM_CC_PLL6_OUT_EVEN, 3.5, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cre_clk_src = { + .cmd_rcgr = 0x211a0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x20000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x20024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x20044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x20064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x20084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .cmd_rcgr = 0x200a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x212a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(213333333, P_CAM_CC_PLL6_OUT_ODD, 1.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x200dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_0_clk_src[] = { + F(500000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(740000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(875000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + F(1000000000, P_CAM_CC_PLL7_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x211f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_icp_1_clk_src = { + .cmd_rcgr = 0x21220, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x21144, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x21170, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = { + F(332500000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x20188, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x211c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ofe_clk_src[] = { + F(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x2011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + F(60000000, P_CAM_CC_PLL6_OUT_EVEN, 8, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x21314, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(56470588, P_CAM_CC_PLL6_OUT_EVEN, 8.5, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x20100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_0_clk_src[] = { + F(360280000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x21018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_1_clk_src[] = { + F(360280000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x21094, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(360280000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x210f8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x2134c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_8, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x2137c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2137c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cam_top_fast_ahb_clk = { + .halt_reg = 0x2136c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2136c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_axi_clk = { + .halt_reg = 0x212f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x211bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x201b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_main_clk = { + .halt_reg = 0x20144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x212e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x2116c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2116c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x21040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x210bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x21120, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21120, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_xo_clk = { + .halt_reg = 0x2130c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2130c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0x21268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0x21284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21284, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_2_clk = { + .halt_reg = 0x212a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0x21348, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x21348, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_ahb_clk = { + .halt_reg = 0x211c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_clk = { + .halt_reg = 0x211b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x20018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x2003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2003c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x2005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2005c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x2007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2007c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x2009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2009c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi4phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi5phytimer_clk = { + .halt_reg = 0x200bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_clk = { + .halt_reg = 0x212bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x212bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_csiphy_rx_clk = { + .halt_reg = 0x20020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_csiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x2001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2001c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x20040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x20060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x20080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x200a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy5_clk = { + .halt_reg = 0x200c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_0_ahb_clk = { + .halt_reg = 0x21248, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21248, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_0_clk = { + .halt_reg = 0x21210, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21210, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x2124c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2124c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_clk = { + .halt_reg = 0x21238, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21238, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0x2119c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2119c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0x2115c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2115c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0x21198, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21198, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0x21188, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21188, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_ahb_clk = { + .halt_reg = 0x201cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_clk = { + .halt_reg = 0x201a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = { + .halt_reg = 0x201d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_clk = { + .halt_reg = 0x201b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = { + .halt_reg = 0x201d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x201d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_clk = { + .halt_reg = 0x211dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x211dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_ahb_clk = { + .halt_reg = 0x20118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_clk = { + .halt_reg = 0x20148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x200f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_clk = { + .halt_reg = 0x20158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x200fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_clk = { + .halt_reg = 0x20134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x20134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x200f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x200f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x2132c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2132c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x21330, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21330, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_clk = { + .halt_reg = 0x21044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x21060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_clk = { + .halt_reg = 0x21030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x2105c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2105c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_clk = { + .halt_reg = 0x210c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x210dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_clk = { + .halt_reg = 0x210ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x210d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x210d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_clk = { + .halt_reg = 0x21124, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21124, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x21140, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21140, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_clk = { + .halt_reg = 0x21110, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21110, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x2113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x2113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tracenoc_tpdm_1_cmb_clk = { + .halt_reg = 0x21394, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x21394, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tracenoc_tpdm_1_cmb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x21334, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x20174, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .parent = &cam_cc_titan_top_gdsc.pd, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x200c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_0_gdsc = { + .gdscr = 0x21004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_1_gdsc = { + .gdscr = 0x21080, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x210e4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + .parent = &cam_cc_titan_top_gdsc.pd, +}; + +static struct clk_regmap *cam_cc_kaanapali_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_clk.clkr, + [CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr, + [CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr, + [CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr, + [CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr, + [CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr, + [CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr, + [CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr, + [CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr, + [CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr, + [CAM_CC_JPEG_CLK] = &cam_cc_jpeg_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.clkr, + [CAM_CC_PLL7] = &cam_cc_pll7.clkr, + [CAM_CC_PLL7_OUT_EVEN] = &cam_cc_pll7_out_even.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_TRACENOC_TPDM_1_CMB_CLK] = &cam_cc_tracenoc_tpdm_1_cmb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_kaanapali_gdscs[] = { + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, +}; + +static const struct qcom_reset_map cam_cc_kaanapali_resets[] = { + [CAM_CC_DRV_BCR] = { 0x2138c }, + [CAM_CC_ICP_BCR] = { 0x211f4 }, + [CAM_CC_IPE_0_BCR] = { 0x20170 }, + [CAM_CC_OFE_BCR] = { 0x200c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x21310 }, + [CAM_CC_TFE_0_BCR] = { 0x21000 }, + [CAM_CC_TFE_1_BCR] = { 0x2107c }, + [CAM_CC_TFE_2_BCR] = { 0x210e0 }, +}; + +static struct clk_alpha_pll *cam_cc_kaanapali_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, + &cam_cc_pll7, +}; + +static u32 cam_cc_kaanapali_critical_cbcrs[] = { + 0x21398, /* CAM_CC_DRV_AHB_CLK */ + 0x21390, /* CAM_CC_DRV_XO_CLK */ + 0x21364, /* CAM_CC_GDSC_CLK */ + 0x21368, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x2601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_kaanapali_driver_data = { + .alpha_plls = cam_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_kaanapali_plls), + .clk_cbcrs = cam_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_kaanapali_desc = { + .config = &cam_cc_kaanapali_regmap_config, + .clks = cam_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(cam_cc_kaanapali_clocks), + .resets = cam_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(cam_cc_kaanapali_resets), + .gdscs = cam_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_kaanapali_driver_data, +}; + +static const struct of_device_id cam_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_kaanapali_match_table); + +static int cam_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_kaanapali_desc); +} + +static struct platform_driver cam_cc_kaanapali_driver = { + .probe = cam_cc_kaanapali_probe, + .driver = { + .name = "camcc-kaanapali", + .of_match_table = cam_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(cam_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI CAMCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/camcc-sm8750.c b/drivers/clk/qcom/camcc-sm8750.c new file mode 100644 index 000000000000..a797b783d4a9 --- /dev/null +++ b/drivers/clk/qcom/camcc-sm8750.c @@ -0,0 +1,2710 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_IFACE, + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, +}; + +enum { + P_BI_TCXO, + P_BI_TCXO_AO, + P_CAM_CC_PLL0_OUT_EVEN, + P_CAM_CC_PLL0_OUT_MAIN, + P_CAM_CC_PLL0_OUT_ODD, + P_CAM_CC_PLL1_OUT_EVEN, + P_CAM_CC_PLL2_OUT_EVEN, + P_CAM_CC_PLL3_OUT_EVEN, + P_CAM_CC_PLL4_OUT_EVEN, + P_CAM_CC_PLL5_OUT_EVEN, + P_CAM_CC_PLL6_OUT_EVEN, + P_CAM_CC_PLL6_OUT_ODD, + P_SLEEP_CLK, +}; + +static const struct pll_vco taycan_elu_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +static const struct alpha_pll_config cam_cc_pll0_config = { + .l = 0x3e, + .alpha = 0x8000, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll0 = { + .offset = 0x0, + .config = &cam_cc_pll0_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll0_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll0_out_odd = { + .offset = 0x0, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll0_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll0_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll0_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll1_config = { + .l = 0x22, + .alpha = 0xa2aa, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll1 = { + .offset = 0x1000, + .config = &cam_cc_pll1_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll1_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll1_out_even = { + .offset = 0x1000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll1_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll1_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll1_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll1.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll2_config = { + .l = 0x23, + .alpha = 0x4aaa, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll2 = { + .offset = 0x2000, + .config = &cam_cc_pll2_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll2_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll2_out_even = { + .offset = 0x2000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll2_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll2_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll2_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll2.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll3_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll3 = { + .offset = 0x3000, + .config = &cam_cc_pll3_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll3_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll3_out_even = { + .offset = 0x3000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll3_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll3_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll3_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll3.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll4_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll4 = { + .offset = 0x4000, + .config = &cam_cc_pll4_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll4_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll4_out_even = { + .offset = 0x4000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll4_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll4_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll4_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll4.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll5_config = { + .l = 0x25, + .alpha = 0x8777, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll5 = { + .offset = 0x5000, + .config = &cam_cc_pll5_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll5_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll5_out_even = { + .offset = 0x5000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll5_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll5_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll5_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll5.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct alpha_pll_config cam_cc_pll6_config = { + .l = 0x32, + .alpha = 0x0, + .config_ctl_val = 0x19660387, + .config_ctl_hi_val = 0x098060a0, + .config_ctl_hi1_val = 0xb416cb20, + .user_ctl_val = 0x00008400, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll cam_cc_pll6 = { + .offset = 0x6000, + .config = &cam_cc_pll6_config, + .vco_table = taycan_elu_vco, + .num_vco = ARRAY_SIZE(taycan_elu_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_elu_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_even = { + .offset = 0x6000, + .post_div_shift = 10, + .post_div_table = post_div_table_cam_cc_pll6_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_even", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct clk_div_table post_div_table_cam_cc_pll6_out_odd[] = { + { 0x2, 3 }, + { } +}; + +static struct clk_alpha_pll_postdiv cam_cc_pll6_out_odd = { + .offset = 0x6000, + .post_div_shift = 14, + .post_div_table = post_div_table_cam_cc_pll6_out_odd, + .num_post_div = ARRAY_SIZE(post_div_table_cam_cc_pll6_out_odd), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_pll6_out_odd", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_pll6.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_elu_ops, + }, +}; + +static const struct parent_map cam_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL0_OUT_MAIN, 1 }, + { P_CAM_CC_PLL0_OUT_EVEN, 2 }, + { P_CAM_CC_PLL0_OUT_ODD, 3 }, + { P_CAM_CC_PLL6_OUT_ODD, 4 }, + { P_CAM_CC_PLL6_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll0.clkr.hw }, + { .hw = &cam_cc_pll0_out_even.clkr.hw }, + { .hw = &cam_cc_pll0_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_odd.clkr.hw }, + { .hw = &cam_cc_pll6_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL1_OUT_EVEN, 4 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll1_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL2_OUT_EVEN, 5 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll2_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_4[] = { + { P_SLEEP_CLK, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_4[] = { + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map cam_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL3_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll3_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL4_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll4_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_CAM_CC_PLL5_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &cam_cc_pll5_out_even.clkr.hw }, +}; + +static const struct parent_map cam_cc_parent_map_8_ao[] = { + { P_BI_TCXO_AO, 0 }, +}; + +static const struct clk_parent_data cam_cc_parent_data_8_ao[] = { + { .index = DT_BI_TCXO_AO }, +}; + +static const struct freq_tbl ftbl_cam_cc_camnoc_rt_axi_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_EVEN, 3, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_EVEN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_camnoc_rt_axi_clk_src = { + .cmd_rcgr = 0x112e8, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_camnoc_rt_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cci_0_clk_src[] = { + F(37500000, P_CAM_CC_PLL0_OUT_EVEN, 16, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cci_0_clk_src = { + .cmd_rcgr = 0x1126c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_1_clk_src = { + .cmd_rcgr = 0x11288, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_cci_2_clk_src = { + .cmd_rcgr = 0x112a4, + .mnd_width = 8, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cci_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cphy_rx_clk_src[] = { + F(266666667, P_CAM_CC_PLL0_OUT_MAIN, 4.5, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(480000000, P_CAM_CC_PLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cphy_rx_clk_src = { + .cmd_rcgr = 0x11068, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cphy_rx_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_cre_clk_src[] = { + F(137142857, P_CAM_CC_PLL6_OUT_EVEN, 3.5, 0, 0), + F(200000000, P_CAM_CC_PLL0_OUT_ODD, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_cre_clk_src = { + .cmd_rcgr = 0x111ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_csi0phytimer_clk_src[] = { + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_csi0phytimer_clk_src = { + .cmd_rcgr = 0x10000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi1phytimer_clk_src = { + .cmd_rcgr = 0x10024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi2phytimer_clk_src = { + .cmd_rcgr = 0x10044, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi3phytimer_clk_src = { + .cmd_rcgr = 0x10064, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi4phytimer_clk_src = { + .cmd_rcgr = 0x10084, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csi5phytimer_clk_src = { + .cmd_rcgr = 0x100a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_csi0phytimer_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_csid_clk_src = { + .cmd_rcgr = 0x112c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_fast_ahb_clk_src[] = { + F(213333333, P_CAM_CC_PLL6_OUT_ODD, 1.5, 0, 0), + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_fast_ahb_clk_src = { + .cmd_rcgr = 0x100dc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_fast_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_fast_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_icp_0_clk_src[] = { + F(300000000, P_CAM_CC_PLL0_OUT_EVEN, 2, 0, 0), + F(400000000, P_CAM_CC_PLL0_OUT_ODD, 1, 0, 0), + F(480000000, P_CAM_CC_PLL6_OUT_EVEN, 1, 0, 0), + F(600000000, P_CAM_CC_PLL0_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_icp_0_clk_src = { + .cmd_rcgr = 0x11214, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_icp_1_clk_src = { + .cmd_rcgr = 0x1123c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_icp_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_clk_src = { + .cmd_rcgr = 0x11150, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_ife_lite_csid_clk_src = { + .cmd_rcgr = 0x1117c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_1, + .freq_tbl = ftbl_cam_cc_cphy_rx_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk_src", + .parent_data = cam_cc_parent_data_1, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ipe_nps_clk_src[] = { + F(332500000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(475000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(575000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(675000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + F(825000000, P_CAM_CC_PLL1_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ipe_nps_clk_src = { + .cmd_rcgr = 0x10190, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_2, + .freq_tbl = ftbl_cam_cc_ipe_nps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk_src", + .parent_data = cam_cc_parent_data_2, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 cam_cc_jpeg_clk_src = { + .cmd_rcgr = 0x111d0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_cre_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_ofe_clk_src[] = { + F(338800000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(484000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(586000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(688000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + F(841000000, P_CAM_CC_PLL2_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_ofe_clk_src = { + .cmd_rcgr = 0x1011c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_3, + .freq_tbl = ftbl_cam_cc_ofe_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_clk_src", + .parent_data = cam_cc_parent_data_3, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_qdss_debug_clk_src[] = { + F(40000000, P_CAM_CC_PLL6_OUT_ODD, 8, 0, 0), + F(60000000, P_CAM_CC_PLL6_OUT_EVEN, 8, 0, 0), + F(120000000, P_CAM_CC_PLL0_OUT_EVEN, 5, 0, 0), + F(240000000, P_CAM_CC_PLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_qdss_debug_clk_src = { + .cmd_rcgr = 0x1132c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_qdss_debug_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_sleep_clk_src[] = { + F(32000, P_SLEEP_CLK, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_sleep_clk_src = { + .cmd_rcgr = 0x11380, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_4, + .freq_tbl = ftbl_cam_cc_sleep_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_sleep_clk_src", + .parent_data = cam_cc_parent_data_4, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_slow_ahb_clk_src[] = { + F(56470588, P_CAM_CC_PLL6_OUT_EVEN, 8.5, 0, 0), + F(80000000, P_CAM_CC_PLL0_OUT_EVEN, 7.5, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_slow_ahb_clk_src = { + .cmd_rcgr = 0x10100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_0, + .freq_tbl = ftbl_cam_cc_slow_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_slow_ahb_clk_src", + .parent_data = cam_cc_parent_data_0, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_0_clk_src[] = { + F(360280000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL3_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_0_clk_src = { + .cmd_rcgr = 0x11018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_5, + .freq_tbl = ftbl_cam_cc_tfe_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_clk_src", + .parent_data = cam_cc_parent_data_5, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_1_clk_src[] = { + F(360280000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL4_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_1_clk_src = { + .cmd_rcgr = 0x11098, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_6, + .freq_tbl = ftbl_cam_cc_tfe_1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_clk_src", + .parent_data = cam_cc_parent_data_6, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_tfe_2_clk_src[] = { + F(360280000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(480000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(630000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(716000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + F(833000000, P_CAM_CC_PLL5_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_tfe_2_clk_src = { + .cmd_rcgr = 0x11100, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_7, + .freq_tbl = ftbl_cam_cc_tfe_2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_clk_src", + .parent_data = cam_cc_parent_data_7, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_cam_cc_xo_clk_src[] = { + F(19200000, P_BI_TCXO_AO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 cam_cc_xo_clk_src = { + .cmd_rcgr = 0x11364, + .mnd_width = 0, + .hid_width = 5, + .parent_map = cam_cc_parent_map_8_ao, + .freq_tbl = ftbl_cam_cc_xo_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "cam_cc_xo_clk_src", + .parent_data = cam_cc_parent_data_8_ao, + .num_parents = ARRAY_SIZE(cam_cc_parent_data_8_ao), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_branch cam_cc_cam_top_ahb_clk = { + .halt_reg = 0x113ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x113ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cam_top_fast_ahb_clk = { + .halt_reg = 0x1139c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1139c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cam_top_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_dcd_xo_clk = { + .halt_reg = 0x11320, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11320, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_dcd_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_axi_clk = { + .halt_reg = 0x11310, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x11310, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x11310, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_cre_clk = { + .halt_reg = 0x111c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ipe_nps_clk = { + .halt_reg = 0x101b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_anchor_clk = { + .halt_reg = 0x10158, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10158, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_hdr_clk = { + .halt_reg = 0x1016c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1016c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_nrt_ofe_main_clk = { + .halt_reg = 0x10144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_nrt_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_axi_clk = { + .halt_reg = 0x11300, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11300, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_camnoc_rt_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_ife_lite_clk = { + .halt_reg = 0x11178, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11178, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_0_bayer_clk = { + .halt_reg = 0x11054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_0_main_clk = { + .halt_reg = 0x11040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_bayer_clk = { + .halt_reg = 0x110d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_1_main_clk = { + .halt_reg = 0x110c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_bayer_clk = { + .halt_reg = 0x1113c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1113c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_rt_tfe_2_main_clk = { + .halt_reg = 0x11128, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11128, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_rt_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_camnoc_xo_clk = { + .halt_reg = 0x11324, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11324, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_camnoc_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_0_clk = { + .halt_reg = 0x11284, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11284, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_1_clk = { + .halt_reg = 0x112a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cci_2_clk = { + .halt_reg = 0x112bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cci_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cci_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_core_ahb_clk = { + .halt_reg = 0x11360, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x11360, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_core_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_ahb_clk = { + .halt_reg = 0x111cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_cre_clk = { + .halt_reg = 0x111c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_cre_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cre_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi0phytimer_clk = { + .halt_reg = 0x10018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi0phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi0phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi1phytimer_clk = { + .halt_reg = 0x1003c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1003c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi1phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi1phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi2phytimer_clk = { + .halt_reg = 0x1005c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1005c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi2phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi2phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi3phytimer_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1007c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi3phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi3phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi4phytimer_clk = { + .halt_reg = 0x1009c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1009c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi4phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi4phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csi5phytimer_clk = { + .halt_reg = 0x100bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csi5phytimer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csi5phytimer_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_clk = { + .halt_reg = 0x112d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x112d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csid_csiphy_rx_clk = { + .halt_reg = 0x10020, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csid_csiphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy0_clk = { + .halt_reg = 0x1001c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1001c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy1_clk = { + .halt_reg = 0x10040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy2_clk = { + .halt_reg = 0x10060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy2_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy3_clk = { + .halt_reg = 0x10080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy3_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy4_clk = { + .halt_reg = 0x100a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy4_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_csiphy5_clk = { + .halt_reg = 0x100c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_csiphy5_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_0_ahb_clk = { + .halt_reg = 0x11264, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11264, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_0_clk = { + .halt_reg = 0x1122c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1122c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_ahb_clk = { + .halt_reg = 0x11268, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11268, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_icp_1_clk = { + .halt_reg = 0x11254, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11254, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_icp_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_icp_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_ahb_clk = { + .halt_reg = 0x111a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_clk = { + .halt_reg = 0x11168, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11168, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_cphy_rx_clk = { + .halt_reg = 0x111a4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_cphy_rx_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_cphy_rx_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ife_lite_csid_clk = { + .halt_reg = 0x11194, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11194, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ife_lite_csid_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ife_lite_csid_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_ahb_clk = { + .halt_reg = 0x101d4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_clk = { + .halt_reg = 0x101a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_nps_fast_ahb_clk = { + .halt_reg = 0x101d8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_nps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_clk = { + .halt_reg = 0x101bc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ipe_nps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ipe_pps_fast_ahb_clk = { + .halt_reg = 0x101dc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x101dc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ipe_pps_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_0_clk = { + .halt_reg = 0x111e8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_jpeg_1_clk = { + .halt_reg = 0x111f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x111f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_jpeg_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_jpeg_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_ahb_clk = { + .halt_reg = 0x10118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_slow_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_clk = { + .halt_reg = 0x10148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_anchor_fast_ahb_clk = { + .halt_reg = 0x100f8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_anchor_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_clk = { + .halt_reg = 0x1015c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1015c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_hdr_fast_ahb_clk = { + .halt_reg = 0x100fc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100fc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_hdr_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_clk = { + .halt_reg = 0x10134, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x10134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_ofe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_ofe_main_fast_ahb_clk = { + .halt_reg = 0x100f4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x100f4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_ofe_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_clk = { + .halt_reg = 0x11344, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11344, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_qdss_debug_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_qdss_debug_xo_clk = { + .halt_reg = 0x11348, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11348, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_qdss_debug_xo_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_clk = { + .halt_reg = 0x11044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_bayer_fast_ahb_clk = { + .halt_reg = 0x11064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_clk = { + .halt_reg = 0x11030, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_0_main_fast_ahb_clk = { + .halt_reg = 0x11060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_0_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_clk = { + .halt_reg = 0x110c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_bayer_fast_ahb_clk = { + .halt_reg = 0x110e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_clk = { + .halt_reg = 0x110b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_1_main_fast_ahb_clk = { + .halt_reg = 0x110e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x110e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_1_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_clk = { + .halt_reg = 0x1112c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1112c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_bayer_fast_ahb_clk = { + .halt_reg = 0x1114c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x1114c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_bayer_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_clk = { + .halt_reg = 0x11118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_tfe_2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch cam_cc_tfe_2_main_fast_ahb_clk = { + .halt_reg = 0x11148, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x11148, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "cam_cc_tfe_2_main_fast_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &cam_cc_fast_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc cam_cc_titan_top_gdsc = { + .gdscr = 0x1134c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_titan_top_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ipe_0_gdsc = { + .gdscr = 0x1017c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_ofe_gdsc = { + .gdscr = 0x100c8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_ofe_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_0_gdsc = { + .gdscr = 0x11004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_1_gdsc = { + .gdscr = 0x11084, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc cam_cc_tfe_2_gdsc = { + .gdscr = 0x110ec, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "cam_cc_tfe_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *cam_cc_sm8750_clocks[] = { + [CAM_CC_CAM_TOP_AHB_CLK] = &cam_cc_cam_top_ahb_clk.clkr, + [CAM_CC_CAM_TOP_FAST_AHB_CLK] = &cam_cc_cam_top_fast_ahb_clk.clkr, + [CAM_CC_CAMNOC_DCD_XO_CLK] = &cam_cc_camnoc_dcd_xo_clk.clkr, + [CAM_CC_CAMNOC_NRT_AXI_CLK] = &cam_cc_camnoc_nrt_axi_clk.clkr, + [CAM_CC_CAMNOC_NRT_CRE_CLK] = &cam_cc_camnoc_nrt_cre_clk.clkr, + [CAM_CC_CAMNOC_NRT_IPE_NPS_CLK] = &cam_cc_camnoc_nrt_ipe_nps_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK] = &cam_cc_camnoc_nrt_ofe_anchor_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_HDR_CLK] = &cam_cc_camnoc_nrt_ofe_hdr_clk.clkr, + [CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK] = &cam_cc_camnoc_nrt_ofe_main_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK] = &cam_cc_camnoc_rt_axi_clk.clkr, + [CAM_CC_CAMNOC_RT_AXI_CLK_SRC] = &cam_cc_camnoc_rt_axi_clk_src.clkr, + [CAM_CC_CAMNOC_RT_IFE_LITE_CLK] = &cam_cc_camnoc_rt_ife_lite_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_0_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_0_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_1_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_1_main_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK] = &cam_cc_camnoc_rt_tfe_2_bayer_clk.clkr, + [CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK] = &cam_cc_camnoc_rt_tfe_2_main_clk.clkr, + [CAM_CC_CAMNOC_XO_CLK] = &cam_cc_camnoc_xo_clk.clkr, + [CAM_CC_CCI_0_CLK] = &cam_cc_cci_0_clk.clkr, + [CAM_CC_CCI_0_CLK_SRC] = &cam_cc_cci_0_clk_src.clkr, + [CAM_CC_CCI_1_CLK] = &cam_cc_cci_1_clk.clkr, + [CAM_CC_CCI_1_CLK_SRC] = &cam_cc_cci_1_clk_src.clkr, + [CAM_CC_CCI_2_CLK] = &cam_cc_cci_2_clk.clkr, + [CAM_CC_CCI_2_CLK_SRC] = &cam_cc_cci_2_clk_src.clkr, + [CAM_CC_CORE_AHB_CLK] = &cam_cc_core_ahb_clk.clkr, + [CAM_CC_CPHY_RX_CLK_SRC] = &cam_cc_cphy_rx_clk_src.clkr, + [CAM_CC_CRE_AHB_CLK] = &cam_cc_cre_ahb_clk.clkr, + [CAM_CC_CRE_CLK] = &cam_cc_cre_clk.clkr, + [CAM_CC_CRE_CLK_SRC] = &cam_cc_cre_clk_src.clkr, + [CAM_CC_CSI0PHYTIMER_CLK] = &cam_cc_csi0phytimer_clk.clkr, + [CAM_CC_CSI0PHYTIMER_CLK_SRC] = &cam_cc_csi0phytimer_clk_src.clkr, + [CAM_CC_CSI1PHYTIMER_CLK] = &cam_cc_csi1phytimer_clk.clkr, + [CAM_CC_CSI1PHYTIMER_CLK_SRC] = &cam_cc_csi1phytimer_clk_src.clkr, + [CAM_CC_CSI2PHYTIMER_CLK] = &cam_cc_csi2phytimer_clk.clkr, + [CAM_CC_CSI2PHYTIMER_CLK_SRC] = &cam_cc_csi2phytimer_clk_src.clkr, + [CAM_CC_CSI3PHYTIMER_CLK] = &cam_cc_csi3phytimer_clk.clkr, + [CAM_CC_CSI3PHYTIMER_CLK_SRC] = &cam_cc_csi3phytimer_clk_src.clkr, + [CAM_CC_CSI4PHYTIMER_CLK] = &cam_cc_csi4phytimer_clk.clkr, + [CAM_CC_CSI4PHYTIMER_CLK_SRC] = &cam_cc_csi4phytimer_clk_src.clkr, + [CAM_CC_CSI5PHYTIMER_CLK] = &cam_cc_csi5phytimer_clk.clkr, + [CAM_CC_CSI5PHYTIMER_CLK_SRC] = &cam_cc_csi5phytimer_clk_src.clkr, + [CAM_CC_CSID_CLK] = &cam_cc_csid_clk.clkr, + [CAM_CC_CSID_CLK_SRC] = &cam_cc_csid_clk_src.clkr, + [CAM_CC_CSID_CSIPHY_RX_CLK] = &cam_cc_csid_csiphy_rx_clk.clkr, + [CAM_CC_CSIPHY0_CLK] = &cam_cc_csiphy0_clk.clkr, + [CAM_CC_CSIPHY1_CLK] = &cam_cc_csiphy1_clk.clkr, + [CAM_CC_CSIPHY2_CLK] = &cam_cc_csiphy2_clk.clkr, + [CAM_CC_CSIPHY3_CLK] = &cam_cc_csiphy3_clk.clkr, + [CAM_CC_CSIPHY4_CLK] = &cam_cc_csiphy4_clk.clkr, + [CAM_CC_CSIPHY5_CLK] = &cam_cc_csiphy5_clk.clkr, + [CAM_CC_FAST_AHB_CLK_SRC] = &cam_cc_fast_ahb_clk_src.clkr, + [CAM_CC_ICP_0_AHB_CLK] = &cam_cc_icp_0_ahb_clk.clkr, + [CAM_CC_ICP_0_CLK] = &cam_cc_icp_0_clk.clkr, + [CAM_CC_ICP_0_CLK_SRC] = &cam_cc_icp_0_clk_src.clkr, + [CAM_CC_ICP_1_AHB_CLK] = &cam_cc_icp_1_ahb_clk.clkr, + [CAM_CC_ICP_1_CLK] = &cam_cc_icp_1_clk.clkr, + [CAM_CC_ICP_1_CLK_SRC] = &cam_cc_icp_1_clk_src.clkr, + [CAM_CC_IFE_LITE_AHB_CLK] = &cam_cc_ife_lite_ahb_clk.clkr, + [CAM_CC_IFE_LITE_CLK] = &cam_cc_ife_lite_clk.clkr, + [CAM_CC_IFE_LITE_CLK_SRC] = &cam_cc_ife_lite_clk_src.clkr, + [CAM_CC_IFE_LITE_CPHY_RX_CLK] = &cam_cc_ife_lite_cphy_rx_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK] = &cam_cc_ife_lite_csid_clk.clkr, + [CAM_CC_IFE_LITE_CSID_CLK_SRC] = &cam_cc_ife_lite_csid_clk_src.clkr, + [CAM_CC_IPE_NPS_AHB_CLK] = &cam_cc_ipe_nps_ahb_clk.clkr, + [CAM_CC_IPE_NPS_CLK] = &cam_cc_ipe_nps_clk.clkr, + [CAM_CC_IPE_NPS_CLK_SRC] = &cam_cc_ipe_nps_clk_src.clkr, + [CAM_CC_IPE_NPS_FAST_AHB_CLK] = &cam_cc_ipe_nps_fast_ahb_clk.clkr, + [CAM_CC_IPE_PPS_CLK] = &cam_cc_ipe_pps_clk.clkr, + [CAM_CC_IPE_PPS_FAST_AHB_CLK] = &cam_cc_ipe_pps_fast_ahb_clk.clkr, + [CAM_CC_JPEG_0_CLK] = &cam_cc_jpeg_0_clk.clkr, + [CAM_CC_JPEG_1_CLK] = &cam_cc_jpeg_1_clk.clkr, + [CAM_CC_JPEG_CLK_SRC] = &cam_cc_jpeg_clk_src.clkr, + [CAM_CC_OFE_AHB_CLK] = &cam_cc_ofe_ahb_clk.clkr, + [CAM_CC_OFE_ANCHOR_CLK] = &cam_cc_ofe_anchor_clk.clkr, + [CAM_CC_OFE_ANCHOR_FAST_AHB_CLK] = &cam_cc_ofe_anchor_fast_ahb_clk.clkr, + [CAM_CC_OFE_CLK_SRC] = &cam_cc_ofe_clk_src.clkr, + [CAM_CC_OFE_HDR_CLK] = &cam_cc_ofe_hdr_clk.clkr, + [CAM_CC_OFE_HDR_FAST_AHB_CLK] = &cam_cc_ofe_hdr_fast_ahb_clk.clkr, + [CAM_CC_OFE_MAIN_CLK] = &cam_cc_ofe_main_clk.clkr, + [CAM_CC_OFE_MAIN_FAST_AHB_CLK] = &cam_cc_ofe_main_fast_ahb_clk.clkr, + [CAM_CC_PLL0] = &cam_cc_pll0.clkr, + [CAM_CC_PLL0_OUT_EVEN] = &cam_cc_pll0_out_even.clkr, + [CAM_CC_PLL0_OUT_ODD] = &cam_cc_pll0_out_odd.clkr, + [CAM_CC_PLL1] = &cam_cc_pll1.clkr, + [CAM_CC_PLL1_OUT_EVEN] = &cam_cc_pll1_out_even.clkr, + [CAM_CC_PLL2] = &cam_cc_pll2.clkr, + [CAM_CC_PLL2_OUT_EVEN] = &cam_cc_pll2_out_even.clkr, + [CAM_CC_PLL3] = &cam_cc_pll3.clkr, + [CAM_CC_PLL3_OUT_EVEN] = &cam_cc_pll3_out_even.clkr, + [CAM_CC_PLL4] = &cam_cc_pll4.clkr, + [CAM_CC_PLL4_OUT_EVEN] = &cam_cc_pll4_out_even.clkr, + [CAM_CC_PLL5] = &cam_cc_pll5.clkr, + [CAM_CC_PLL5_OUT_EVEN] = &cam_cc_pll5_out_even.clkr, + [CAM_CC_PLL6] = &cam_cc_pll6.clkr, + [CAM_CC_PLL6_OUT_EVEN] = &cam_cc_pll6_out_even.clkr, + [CAM_CC_PLL6_OUT_ODD] = &cam_cc_pll6_out_odd.clkr, + [CAM_CC_QDSS_DEBUG_CLK] = &cam_cc_qdss_debug_clk.clkr, + [CAM_CC_QDSS_DEBUG_CLK_SRC] = &cam_cc_qdss_debug_clk_src.clkr, + [CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr, + [CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr, + [CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr, + [CAM_CC_TFE_0_BAYER_CLK] = &cam_cc_tfe_0_bayer_clk.clkr, + [CAM_CC_TFE_0_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_0_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_0_CLK_SRC] = &cam_cc_tfe_0_clk_src.clkr, + [CAM_CC_TFE_0_MAIN_CLK] = &cam_cc_tfe_0_main_clk.clkr, + [CAM_CC_TFE_0_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_0_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_BAYER_CLK] = &cam_cc_tfe_1_bayer_clk.clkr, + [CAM_CC_TFE_1_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_1_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_1_CLK_SRC] = &cam_cc_tfe_1_clk_src.clkr, + [CAM_CC_TFE_1_MAIN_CLK] = &cam_cc_tfe_1_main_clk.clkr, + [CAM_CC_TFE_1_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_1_main_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_BAYER_CLK] = &cam_cc_tfe_2_bayer_clk.clkr, + [CAM_CC_TFE_2_BAYER_FAST_AHB_CLK] = &cam_cc_tfe_2_bayer_fast_ahb_clk.clkr, + [CAM_CC_TFE_2_CLK_SRC] = &cam_cc_tfe_2_clk_src.clkr, + [CAM_CC_TFE_2_MAIN_CLK] = &cam_cc_tfe_2_main_clk.clkr, + [CAM_CC_TFE_2_MAIN_FAST_AHB_CLK] = &cam_cc_tfe_2_main_fast_ahb_clk.clkr, + [CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr, +}; + +static struct gdsc *cam_cc_sm8750_gdscs[] = { + [CAM_CC_TITAN_TOP_GDSC] = &cam_cc_titan_top_gdsc, + [CAM_CC_IPE_0_GDSC] = &cam_cc_ipe_0_gdsc, + [CAM_CC_OFE_GDSC] = &cam_cc_ofe_gdsc, + [CAM_CC_TFE_0_GDSC] = &cam_cc_tfe_0_gdsc, + [CAM_CC_TFE_1_GDSC] = &cam_cc_tfe_1_gdsc, + [CAM_CC_TFE_2_GDSC] = &cam_cc_tfe_2_gdsc, +}; + +static const struct qcom_reset_map cam_cc_sm8750_resets[] = { + [CAM_CC_DRV_BCR] = { 0x113bc }, + [CAM_CC_ICP_BCR] = { 0x11210 }, + [CAM_CC_IPE_0_BCR] = { 0x10178 }, + [CAM_CC_OFE_BCR] = { 0x100c4 }, + [CAM_CC_QDSS_DEBUG_BCR] = { 0x11328 }, + [CAM_CC_TFE_0_BCR] = { 0x11000 }, + [CAM_CC_TFE_1_BCR] = { 0x11080 }, + [CAM_CC_TFE_2_BCR] = { 0x110e8 }, +}; + +static struct clk_alpha_pll *cam_cc_sm8750_plls[] = { + &cam_cc_pll0, + &cam_cc_pll1, + &cam_cc_pll2, + &cam_cc_pll3, + &cam_cc_pll4, + &cam_cc_pll5, + &cam_cc_pll6, +}; + +static u32 cam_cc_sm8750_critical_cbcrs[] = { + 0x113c4, /* CAM_CC_DRV_AHB_CLK */ + 0x113c0, /* CAM_CC_DRV_XO_CLK */ + 0x1137c, /* CAM_CC_GDSC_CLK */ + 0x11398, /* CAM_CC_SLEEP_CLK */ +}; + +static const struct regmap_config cam_cc_sm8750_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1601c, + .fast_io = true, +}; + +static struct qcom_cc_driver_data cam_cc_sm8750_driver_data = { + .alpha_plls = cam_cc_sm8750_plls, + .num_alpha_plls = ARRAY_SIZE(cam_cc_sm8750_plls), + .clk_cbcrs = cam_cc_sm8750_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(cam_cc_sm8750_critical_cbcrs), +}; + +static const struct qcom_cc_desc cam_cc_sm8750_desc = { + .config = &cam_cc_sm8750_regmap_config, + .clks = cam_cc_sm8750_clocks, + .num_clks = ARRAY_SIZE(cam_cc_sm8750_clocks), + .resets = cam_cc_sm8750_resets, + .num_resets = ARRAY_SIZE(cam_cc_sm8750_resets), + .gdscs = cam_cc_sm8750_gdscs, + .num_gdscs = ARRAY_SIZE(cam_cc_sm8750_gdscs), + .use_rpm = true, + .driver_data = &cam_cc_sm8750_driver_data, +}; + +static const struct of_device_id cam_cc_sm8750_match_table[] = { + { .compatible = "qcom,sm8750-camcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, cam_cc_sm8750_match_table); + +static int cam_cc_sm8750_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &cam_cc_sm8750_desc); +} + +static struct platform_driver cam_cc_sm8750_driver = { + .probe = cam_cc_sm8750_probe, + .driver = { + .name = "camcc-sm8750", + .of_match_table = cam_cc_sm8750_match_table, + }, +}; + +module_platform_driver(cam_cc_sm8750_driver); + +MODULE_DESCRIPTION("QTI CAMCC SM8750 Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c index 6aeba40358c1..f8313f9d0e30 100644 --- a/drivers/clk/qcom/clk-alpha-pll.c +++ b/drivers/clk/qcom/clk-alpha-pll.c @@ -243,6 +243,19 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = { [PLL_OFF_TEST_CTL] = 0x28, [PLL_OFF_TEST_CTL_U] = 0x2c, }, + [CLK_ALPHA_PLL_TYPE_RIVIAN_ELU] = { + [PLL_OFF_OPMODE] = 0x04, + [PLL_OFF_STATUS] = 0x0c, + [PLL_OFF_L_VAL] = 0x10, + [PLL_OFF_USER_CTL] = 0x14, + [PLL_OFF_USER_CTL_U] = 0x18, + [PLL_OFF_CONFIG_CTL] = 0x1c, + [PLL_OFF_CONFIG_CTL_U] = 0x20, + [PLL_OFF_CONFIG_CTL_U1] = 0x24, + [PLL_OFF_CONFIG_CTL_U2] = 0x28, + [PLL_OFF_TEST_CTL] = 0x2c, + [PLL_OFF_TEST_CTL_U] = 0x30, + }, [CLK_ALPHA_PLL_TYPE_DEFAULT_EVO] = { [PLL_OFF_L_VAL] = 0x04, [PLL_OFF_ALPHA_VAL] = 0x08, @@ -1257,11 +1270,8 @@ static int clk_alpha_pll_postdiv_determine_rate(struct clk_hw *hw, else table = clk_alpha_div_table; - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - table, pll->width, - CLK_DIVIDER_POWER_OF_TWO); - - return 0; + return divider_determine_rate(hw, req, table, pll->width, + CLK_DIVIDER_POWER_OF_TWO); } static int clk_alpha_pll_postdiv_ro_determine_rate(struct clk_hw *hw, @@ -1617,11 +1627,8 @@ static int clk_trion_pll_postdiv_determine_rate(struct clk_hw *hw, { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, pll->post_div_table, pll->width, + CLK_DIVIDER_ROUND_CLOSEST); }; static int @@ -1657,11 +1664,8 @@ static int clk_alpha_pll_postdiv_fabia_determine_rate(struct clk_hw *hw, { struct clk_alpha_pll_postdiv *pll = to_clk_alpha_pll_postdiv(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - pll->post_div_table, - pll->width, CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, pll->post_div_table, pll->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int clk_alpha_pll_postdiv_fabia_set_rate(struct clk_hw *hw, @@ -2338,7 +2342,11 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma return; } - lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + if (config->cal_l) + lval |= config->cal_l << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + else + lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT; + clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval); clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha); clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val); @@ -3002,6 +3010,7 @@ void qcom_clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regm clk_taycan_elu_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_RIVIAN_EVO: + case CLK_ALPHA_PLL_TYPE_RIVIAN_ELU: clk_rivian_evo_pll_configure(pll, regmap, pll->config); break; case CLK_ALPHA_PLL_TYPE_TRION: diff --git a/drivers/clk/qcom/clk-alpha-pll.h b/drivers/clk/qcom/clk-alpha-pll.h index 0903a05b18cc..42d334492145 100644 --- a/drivers/clk/qcom/clk-alpha-pll.h +++ b/drivers/clk/qcom/clk-alpha-pll.h @@ -28,9 +28,12 @@ enum { CLK_ALPHA_PLL_TYPE_LUCID_EVO, CLK_ALPHA_PLL_TYPE_LUCID_OLE, CLK_ALPHA_PLL_TYPE_PONGO_ELU, + CLK_ALPHA_PLL_TYPE_PONGO_EKO_T = CLK_ALPHA_PLL_TYPE_PONGO_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T = CLK_ALPHA_PLL_TYPE_TAYCAN_ELU, CLK_ALPHA_PLL_TYPE_RIVIAN_EVO, + CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, + CLK_ALPHA_PLL_TYPE_RIVIAN_EKO_T = CLK_ALPHA_PLL_TYPE_RIVIAN_ELU, CLK_ALPHA_PLL_TYPE_DEFAULT_EVO, CLK_ALPHA_PLL_TYPE_BRAMMO_EVO, CLK_ALPHA_PLL_TYPE_STROMER, @@ -128,6 +131,7 @@ struct clk_alpha_pll_postdiv { struct alpha_pll_config { u32 l; + u32 cal_l; u32 alpha; u32 alpha_hi; u32 config_ctl_val; @@ -206,8 +210,11 @@ extern const struct clk_ops clk_alpha_pll_postdiv_lucid_evo_ops; #define clk_alpha_pll_postdiv_taycan_eko_t_ops clk_alpha_pll_postdiv_lucid_evo_ops extern const struct clk_ops clk_alpha_pll_pongo_elu_ops; +#define clk_alpha_pll_pongo_eko_t_ops clk_alpha_pll_pongo_elu_ops extern const struct clk_ops clk_alpha_pll_rivian_evo_ops; #define clk_alpha_pll_postdiv_rivian_evo_ops clk_alpha_pll_postdiv_fabia_ops +#define clk_alpha_pll_rivian_elu_ops clk_alpha_pll_rivian_evo_ops +#define clk_alpha_pll_rivian_eko_t_ops clk_alpha_pll_rivian_evo_ops extern const struct clk_ops clk_alpha_pll_regera_ops; extern const struct clk_ops clk_alpha_pll_slew_ops; diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c index e18cb8807d73..fc696b66ccda 100644 --- a/drivers/clk/qcom/clk-rcg2.c +++ b/drivers/clk/qcom/clk-rcg2.c @@ -755,7 +755,7 @@ static int clk_rcg2_get_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) { struct clk_rcg2 *rcg = to_clk_rcg2(hw); - u32 notn_m, n, m, d, not2d, mask, duty_per, cfg; + u32 notn_m, n, m, d, not2d, mask, cfg; int ret; /* Duty-cycle cannot be modified for non-MND RCGs */ @@ -774,10 +774,8 @@ static int clk_rcg2_set_duty_cycle(struct clk_hw *hw, struct clk_duty *duty) n = (~(notn_m) + m) & mask; - duty_per = (duty->num * 100) / duty->den; - /* Calculate 2d value */ - d = DIV_ROUND_CLOSEST(n * duty_per * 2, 100); + d = DIV_ROUND_CLOSEST(n * duty->num * 2, duty->den); /* * Check bit widths of 2d. If D is too big reduce duty cycle. @@ -1266,6 +1264,7 @@ static int clk_gfx3d_determine_rate(struct clk_hw *hw, if (req->max_rate < parent_req.max_rate) parent_req.max_rate = req->max_rate; + parent_req.best_parent_hw = req->best_parent_hw; ret = __clk_determine_rate(req->best_parent_hw, &parent_req); if (ret) return ret; @@ -1651,7 +1650,7 @@ static int clk_rcg2_dfs_populate_freq_table(struct clk_rcg2 *rcg) int i; /* Allocate space for 1 extra since table is NULL terminated */ - freq_tbl = kcalloc(MAX_PERF_LEVEL + 1, sizeof(*freq_tbl), GFP_KERNEL); + freq_tbl = kzalloc_objs(*freq_tbl, MAX_PERF_LEVEL + 1); if (!freq_tbl) return -ENOMEM; rcg->freq_tbl = freq_tbl; diff --git a/drivers/clk/qcom/clk-regmap-divider.c b/drivers/clk/qcom/clk-regmap-divider.c index 4f5395f0ab6d..672e82caf205 100644 --- a/drivers/clk/qcom/clk-regmap-divider.c +++ b/drivers/clk/qcom/clk-regmap-divider.c @@ -26,24 +26,16 @@ static int div_ro_determine_rate(struct clk_hw *hw, val >>= divider->shift; val &= BIT(divider->width) - 1; - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, NULL, - divider->width, - CLK_DIVIDER_ROUND_CLOSEST, val); - - return 0; + return divider_ro_determine_rate(hw, req, NULL, divider->width, + CLK_DIVIDER_ROUND_CLOSEST, val); } static int div_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct clk_regmap_div *divider = to_clk_regmap_div(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - NULL, - divider->width, - CLK_DIVIDER_ROUND_CLOSEST); - - return 0; + return divider_determine_rate(hw, req, NULL, divider->width, + CLK_DIVIDER_ROUND_CLOSEST); } static int div_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c index 1a98b3a0c528..547729b1a8ee 100644 --- a/drivers/clk/qcom/clk-rpmh.c +++ b/drivers/clk/qcom/clk-rpmh.c @@ -390,10 +390,21 @@ DEFINE_CLK_RPMH_VRM(clk7, _a4, "clka7", 4); DEFINE_CLK_RPMH_VRM(div_clk1, _div2, "divclka1", 2); -DEFINE_CLK_RPMH_VRM(clk3, _a, "C3A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk4, _a, "C4A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk5, _a, "C5A_E0", 1); -DEFINE_CLK_RPMH_VRM(clk8, _a, "C8A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk1, _a1_e0, "C1A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk2, _a1_e0, "C2A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk3, _a1_e0, "C3A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk4, _a1_e0, "C4A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk5, _a1_e0, "C5A_E0", 1); +DEFINE_CLK_RPMH_VRM(clk8, _a1_e0, "C8A_E0", 1); + +DEFINE_CLK_RPMH_VRM(clk3, _a2_e0, "C3A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk4, _a2_e0, "C4A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk5, _a2_e0, "C5A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk6, _a2_e0, "C6A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk7, _a2_e0, "C7A_E0", 2); +DEFINE_CLK_RPMH_VRM(clk8, _a2_e0, "C8A_E0", 2); + +DEFINE_CLK_RPMH_VRM(clk11, _a4_e0, "C11A_E0", 4); DEFINE_CLK_RPMH_BCM(ce, "CE0"); DEFINE_CLK_RPMH_BCM(hwkm, "HK0"); @@ -888,12 +899,12 @@ static const struct clk_rpmh_desc clk_rpmh_sm8750 = { static struct clk_hw *glymur_rpmh_clocks[] = { [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, - [RPMH_RF_CLK3] = &clk_rpmh_clk3_a.hw, - [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a_ao.hw, - [RPMH_RF_CLK4] = &clk_rpmh_clk4_a.hw, - [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a_ao.hw, - [RPMH_RF_CLK5] = &clk_rpmh_clk5_a.hw, - [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a1_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a1_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a1_e0.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a1_e0_ao.hw, + [RPMH_RF_CLK5] = &clk_rpmh_clk5_a1_e0.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a1_e0_ao.hw, }; static const struct clk_rpmh_desc clk_rpmh_glymur = { @@ -901,6 +912,34 @@ static const struct clk_rpmh_desc clk_rpmh_glymur = { .num_clks = ARRAY_SIZE(glymur_rpmh_clocks), }; +static struct clk_hw *kaanapali_rpmh_clocks[] = { + [RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw, + [RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw, + [RPMH_DIV_CLK1] = &clk_rpmh_clk11_a4_e0.hw, + [RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2_e0.hw, + [RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_e0_ao.hw, + [RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a2_e0.hw, + [RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a2_e0_ao.hw, + [RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2_e0.hw, + [RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_e0_ao.hw, + [RPMH_RF_CLK1] = &clk_rpmh_clk1_a1_e0.hw, + [RPMH_RF_CLK1_A] = &clk_rpmh_clk1_a1_e0_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_clk2_a1_e0.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_clk2_a1_e0_ao.hw, + [RPMH_RF_CLK3] = &clk_rpmh_clk3_a2_e0.hw, + [RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a2_e0_ao.hw, + [RPMH_RF_CLK4] = &clk_rpmh_clk4_a2_e0.hw, + [RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a2_e0_ao.hw, + [RPMH_RF_CLK5] = &clk_rpmh_clk5_a2_e0.hw, + [RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_e0_ao.hw, + [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, +}; + +static const struct clk_rpmh_desc clk_rpmh_kaanapali = { + .clks = kaanapali_rpmh_clocks, + .num_clks = ARRAY_SIZE(kaanapali_rpmh_clocks), +}; + static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec, void *data) { @@ -991,6 +1030,7 @@ static int clk_rpmh_probe(struct platform_device *pdev) static const struct of_device_id clk_rpmh_match_table[] = { { .compatible = "qcom,glymur-rpmh-clk", .data = &clk_rpmh_glymur}, + { .compatible = "qcom,kaanapali-rpmh-clk", .data = &clk_rpmh_kaanapali}, { .compatible = "qcom,milos-rpmh-clk", .data = &clk_rpmh_milos}, { .compatible = "qcom,qcs615-rpmh-clk", .data = &clk_rpmh_qcs615}, { .compatible = "qcom,qdu1000-rpmh-clk", .data = &clk_rpmh_qdu1000}, diff --git a/drivers/clk/qcom/dispcc-kaanapali.c b/drivers/clk/qcom/dispcc-kaanapali.c new file mode 100644 index 000000000000..baae2ec1f72a --- /dev/null +++ b/drivers/clk/qcom/dispcc-kaanapali.c @@ -0,0 +1,1956 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +#define DISP_CC_MISC_CMD 0xF000 + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_AHB_CLK, + DT_SLEEP_CLK, + DT_DP0_PHY_PLL_LINK_CLK, + DT_DP0_PHY_PLL_VCO_DIV_CLK, + DT_DP1_PHY_PLL_LINK_CLK, + DT_DP1_PHY_PLL_VCO_DIV_CLK, + DT_DP2_PHY_PLL_LINK_CLK, + DT_DP2_PHY_PLL_VCO_DIV_CLK, + DT_DP3_PHY_PLL_LINK_CLK, + DT_DP3_PHY_PLL_VCO_DIV_CLK, + DT_DSI0_PHY_PLL_OUT_BYTECLK, + DT_DSI0_PHY_PLL_OUT_DSICLK, + DT_DSI1_PHY_PLL_OUT_BYTECLK, + DT_DSI1_PHY_PLL_OUT_DSICLK, +}; + +enum { + P_BI_TCXO, + P_DISP_CC_PLL0_OUT_MAIN, + P_DISP_CC_PLL1_OUT_EVEN, + P_DISP_CC_PLL1_OUT_MAIN, + P_DISP_CC_PLL2_OUT_MAIN, + P_DP0_PHY_PLL_LINK_CLK, + P_DP0_PHY_PLL_VCO_DIV_CLK, + P_DP1_PHY_PLL_LINK_CLK, + P_DP1_PHY_PLL_VCO_DIV_CLK, + P_DP2_PHY_PLL_LINK_CLK, + P_DP2_PHY_PLL_VCO_DIV_CLK, + P_DP3_PHY_PLL_LINK_CLK, + P_DP3_PHY_PLL_VCO_DIV_CLK, + P_DSI0_PHY_PLL_OUT_BYTECLK, + P_DSI0_PHY_PLL_OUT_DSICLK, + P_DSI1_PHY_PLL_OUT_BYTECLK, + P_DSI1_PHY_PLL_OUT_DSICLK, +}; + +static const struct pll_vco pongo_eko_t_vco[] = { + { 38400000, 153600000, 0 }, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 257.142858 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll0_config = { + .l = 0xd, + .cal_l = 0x48, + .alpha = 0x6492, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll0 = { + .offset = 0x0, + .config = &disp_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 300.0 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll1_config = { + .l = 0xf, + .cal_l = 0x48, + .alpha = 0xa000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll disp_cc_pll1 = { + .offset = 0x1000, + .config = &disp_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 38.4 MHz Configuration */ +static const struct alpha_pll_config disp_cc_pll2_config = { + .l = 0x493, + .cal_l = 0x493, + .alpha = 0x0, + .config_ctl_val = 0x60000f68, + .config_ctl_hi_val = 0x0001c808, + .config_ctl_hi1_val = 0x00000000, + .config_ctl_hi2_val = 0x040082f4, + .test_ctl_val = 0x00000000, + .test_ctl_hi_val = 0x0080c496, + .test_ctl_hi1_val = 0x40100080, + .test_ctl_hi2_val = 0x001001bc, + .test_ctl_hi3_val = 0x002003d8, + .user_ctl_val = 0x00000400, + .user_ctl_hi_val = 0x00e50302, +}; + +static struct clk_alpha_pll disp_cc_pll2 = { + .offset = 0x2000, + .config = &disp_cc_pll2_config, + .vco_table = pongo_eko_t_vco, + .num_vco = ARRAY_SIZE(pongo_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_PONGO_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_SLEEP_CLK, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_pongo_eko_t_ops, + }, + }, +}; + +static const struct parent_map disp_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map disp_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_DSICLK, 1 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, + { P_DSI1_PHY_PLL_OUT_DSICLK, 3 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_DSICLK }, + { .hw = &disp_cc_pll2.clkr.hw }, + { .index = DT_DSI1_PHY_PLL_OUT_DSICLK }, +}; + +static const struct parent_map disp_cc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP0_PHY_PLL_VCO_DIV_CLK, 2 }, + { P_DP3_PHY_PLL_VCO_DIV_CLK, 3 }, + { P_DP1_PHY_PLL_VCO_DIV_CLK, 4 }, + { P_DP2_PHY_PLL_VCO_DIV_CLK, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP0_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP3_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP1_PHY_PLL_VCO_DIV_CLK }, + { .index = DT_DP2_PHY_PLL_VCO_DIV_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_DSI0_PHY_PLL_OUT_BYTECLK, 2 }, + { P_DSI1_PHY_PLL_OUT_BYTECLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DSI0_PHY_PLL_OUT_BYTECLK }, + { .index = DT_DSI1_PHY_PLL_OUT_BYTECLK }, +}; + +static const struct parent_map disp_cc_parent_map_7[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_7[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_DP0_PHY_PLL_LINK_CLK, 1 }, + { P_DP1_PHY_PLL_LINK_CLK, 2 }, + { P_DP2_PHY_PLL_LINK_CLK, 3 }, + { P_DP3_PHY_PLL_LINK_CLK, 4 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .index = DT_DP0_PHY_PLL_LINK_CLK }, + { .index = DT_DP1_PHY_PLL_LINK_CLK }, + { .index = DT_DP2_PHY_PLL_LINK_CLK }, + { .index = DT_DP3_PHY_PLL_LINK_CLK }, +}; + +static const struct parent_map disp_cc_parent_map_9[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL0_OUT_MAIN, 1 }, + { P_DISP_CC_PLL1_OUT_MAIN, 4 }, + { P_DISP_CC_PLL1_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_9[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll0.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, + { .hw = &disp_cc_pll1.clkr.hw }, +}; + +static const struct parent_map disp_cc_parent_map_10[] = { + { P_BI_TCXO, 0 }, + { P_DISP_CC_PLL2_OUT_MAIN, 2 }, +}; + +static const struct clk_parent_data disp_cc_parent_data_10[] = { + { .index = DT_BI_TCXO }, + { .hw = &disp_cc_pll2.clkr.hw }, +}; + +static const struct freq_tbl ftbl_disp_cc_esync0_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_esync0_clk_src = { + .cmd_rcgr = 0x80d4, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_esync1_clk_src = { + .cmd_rcgr = 0x80ec, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_4, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk_src", + .parent_data = disp_cc_parent_data_4, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(120000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(165000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(200000000, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(233333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(261666667, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + F(283333333, P_DISP_CC_PLL1_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = { + .cmd_rcgr = 0x8378, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_7, + .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk_src", + .parent_data = disp_cc_parent_data_7, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_7), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = { + .cmd_rcgr = 0x81b0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_aux_clk_src = { + .cmd_rcgr = 0x8248, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_link_clk_src = { + .cmd_rcgr = 0x81fc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_8, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk_src", + .parent_data = disp_cc_parent_data_8, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel0_clk_src = { + .cmd_rcgr = 0x8218, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx0_pixel1_clk_src = { + .cmd_rcgr = 0x8230, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_5, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk_src", + .parent_data = disp_cc_parent_data_5, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_aux_clk_src = { + .cmd_rcgr = 0x82ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_link_clk_src = { + .cmd_rcgr = 0x8290, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel0_clk_src = { + .cmd_rcgr = 0x8260, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx1_pixel1_clk_src = { + .cmd_rcgr = 0x8278, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_aux_clk_src = { + .cmd_rcgr = 0x8310, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_link_clk_src = { + .cmd_rcgr = 0x82c4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel0_clk_src = { + .cmd_rcgr = 0x82e0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx2_pixel1_clk_src = { + .cmd_rcgr = 0x82f8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_aux_clk_src = { + .cmd_rcgr = 0x835c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_link_clk_src = { + .cmd_rcgr = 0x8340, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_3, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk_src", + .parent_data = disp_cc_parent_data_3, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_byte2_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_dptx3_pixel0_clk_src = { + .cmd_rcgr = 0x8328, + .mnd_width = 16, + .hid_width = 5, + .parent_map = disp_cc_parent_map_2, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk_src", + .parent_data = disp_cc_parent_data_2, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_dp_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = { + .cmd_rcgr = 0x81cc, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_esc1_clk_src = { + .cmd_rcgr = 0x81e4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_6, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk_src", + .parent_data = disp_cc_parent_data_6, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(85714286, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(100000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(156000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(207000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(337000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(417000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(532000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(600000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + F(650000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = { + .cmd_rcgr = 0x8164, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_9, + .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk_src", + .parent_data = disp_cc_parent_data_9, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_9), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { + .cmd_rcgr = 0x811c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { + .cmd_rcgr = 0x8134, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_pclk2_clk_src = { + .cmd_rcgr = 0x814c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = disp_cc_parent_map_1, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk_src", + .parent_data = disp_cc_parent_data_1, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_pixel_ops, + }, +}; + +static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = { + .cmd_rcgr = 0x817c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_0, + .freq_tbl = ftbl_disp_cc_esync0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk_src", + .parent_data = disp_cc_parent_data_0, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_disp_cc_osc_clk_src[] = { + F(38400000, P_DISP_CC_PLL2_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 disp_cc_osc_clk_src = { + .cmd_rcgr = 0x8104, + .mnd_width = 0, + .hid_width = 5, + .parent_map = disp_cc_parent_map_10, + .freq_tbl = ftbl_disp_cc_osc_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk_src", + .parent_data = disp_cc_parent_data_10, + .num_parents = ARRAY_SIZE(disp_cc_parent_data_10), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_ahb_swi_div_clk_src = { + .reg = 0x8374, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = { + .reg = 0x81ac, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_byte1_div_clk_src = { + .reg = 0x81c8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx0_link_div_clk_src = { + .reg = 0x8214, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx1_link_div_clk_src = { + .reg = 0x82a8, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx2_link_div_clk_src = { + .reg = 0x82dc, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div disp_cc_mdss_dptx3_link_div_clk_src = { + .reg = 0x8358, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch disp_cc_esync0_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_esync1_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_esync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_esync1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_accu_shift_clk = { + .halt_reg = 0xe060, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xe060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb1_clk = { + .halt_reg = 0xa028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_clk = { + .halt_reg = 0x80c4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_ahb_swi_clk = { + .halt_reg = 0x80c0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_ahb_swi_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_swi_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_clk = { + .halt_reg = 0x8044, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte0_intf_clk = { + .halt_reg = 0x8048, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8048, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte0_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte0_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_clk = { + .halt_reg = 0x804c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x804c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_byte1_intf_clk = { + .halt_reg = 0x8050, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8050, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_byte1_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_byte1_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_aux_clk = { + .halt_reg = 0x8074, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8074, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_crypto_clk = { + .halt_reg = 0x8068, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_clk = { + .halt_reg = 0x805c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x805c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_link_intf_clk = { + .halt_reg = 0x8064, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8064, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel0_clk = { + .halt_reg = 0x806c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x806c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_pixel1_clk = { + .halt_reg = 0x8070, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx0_usb_router_link_intf_clk = { + .halt_reg = 0x8060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx0_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx0_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_aux_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_crypto_clk = { + .halt_reg = 0x808c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x808c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_clk = { + .halt_reg = 0x8080, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8080, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_link_intf_clk = { + .halt_reg = 0x8088, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8088, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel0_clk = { + .halt_reg = 0x8078, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8078, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_pixel1_clk = { + .halt_reg = 0x807c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x807c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx1_usb_router_link_intf_clk = { + .halt_reg = 0x8084, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8084, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx1_usb_router_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx1_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_aux_clk = { + .halt_reg = 0x80a8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_crypto_clk = { + .halt_reg = 0x80a4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80a4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_clk = { + .halt_reg = 0x809c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x809c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_link_intf_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel0_clk = { + .halt_reg = 0x8094, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx2_pixel1_clk = { + .halt_reg = 0x8098, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8098, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx2_pixel1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx2_pixel1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_aux_clk = { + .halt_reg = 0x80b8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_crypto_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_crypto_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_clk = { + .halt_reg = 0x80b0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_link_intf_clk = { + .halt_reg = 0x80b4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_link_intf_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_link_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_dptx3_pixel0_clk = { + .halt_reg = 0x80ac, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80ac, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_dptx3_pixel0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_dptx3_pixel0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc0_clk = { + .halt_reg = 0x8054, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_esc1_clk = { + .halt_reg = 0x8058, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8058, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_esc1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_esc1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp1_clk = { + .halt_reg = 0xa004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_clk = { + .halt_reg = 0x8010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut1_clk = { + .halt_reg = 0xa014, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xa014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_lut_clk = { + .halt_reg = 0x8020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_lut_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_mdp_ss_ip_clk = { + .halt_reg = 0x8030, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x8030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_mdp_ss_ip_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_mdp_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = { + .halt_reg = 0xc004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0xc004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_non_gdsc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_ahb_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk0_clk = { + .halt_reg = 0x8004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk0_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk1_clk = { + .halt_reg = 0x8008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_pclk2_clk = { + .halt_reg = 0x800c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x800c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_pclk2_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_pclk2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync1_clk = { + .halt_reg = 0xa024, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0xa024, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync1_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_mdss_vsync_clk = { + .halt_reg = 0x8040, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8040, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_mdss_vsync_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_mdss_vsync_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch disp_cc_osc_clk = { + .halt_reg = 0x80c8, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80c8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "disp_cc_osc_clk", + .parent_hws = (const struct clk_hw*[]) { + &disp_cc_osc_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc disp_cc_mdss_core_gdsc = { + .gdscr = 0x9000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct gdsc disp_cc_mdss_core_int2_gdsc = { + .gdscr = 0xb000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "disp_cc_mdss_core_int2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER, +}; + +static struct clk_regmap *disp_cc_kaanapali_clocks[] = { + [DISP_CC_ESYNC0_CLK] = &disp_cc_esync0_clk.clkr, + [DISP_CC_ESYNC0_CLK_SRC] = &disp_cc_esync0_clk_src.clkr, + [DISP_CC_ESYNC1_CLK] = &disp_cc_esync1_clk.clkr, + [DISP_CC_ESYNC1_CLK_SRC] = &disp_cc_esync1_clk_src.clkr, + [DISP_CC_MDSS_ACCU_SHIFT_CLK] = &disp_cc_mdss_accu_shift_clk.clkr, + [DISP_CC_MDSS_AHB1_CLK] = &disp_cc_mdss_ahb1_clk.clkr, + [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr, + [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr, + [DISP_CC_MDSS_AHB_SWI_CLK] = &disp_cc_mdss_ahb_swi_clk.clkr, + [DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC] = &disp_cc_mdss_ahb_swi_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr, + [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK] = &disp_cc_mdss_byte1_clk.clkr, + [DISP_CC_MDSS_BYTE1_CLK_SRC] = &disp_cc_mdss_byte1_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] = &disp_cc_mdss_byte1_div_clk_src.clkr, + [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK] = &disp_cc_mdss_dptx0_aux_clk.clkr, + [DISP_CC_MDSS_DPTX0_AUX_CLK_SRC] = &disp_cc_mdss_dptx0_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_CRYPTO_CLK] = &disp_cc_mdss_dptx0_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK] = &disp_cc_mdss_dptx0_link_clk.clkr, + [DISP_CC_MDSS_DPTX0_LINK_CLK_SRC] = &disp_cc_mdss_dptx0_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx0_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_LINK_INTF_CLK] = &disp_cc_mdss_dptx0_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK] = &disp_cc_mdss_dptx0_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx0_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK] = &disp_cc_mdss_dptx0_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx0_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx0_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK] = &disp_cc_mdss_dptx1_aux_clk.clkr, + [DISP_CC_MDSS_DPTX1_AUX_CLK_SRC] = &disp_cc_mdss_dptx1_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_CRYPTO_CLK] = &disp_cc_mdss_dptx1_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK] = &disp_cc_mdss_dptx1_link_clk.clkr, + [DISP_CC_MDSS_DPTX1_LINK_CLK_SRC] = &disp_cc_mdss_dptx1_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx1_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_LINK_INTF_CLK] = &disp_cc_mdss_dptx1_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK] = &disp_cc_mdss_dptx1_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx1_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK] = &disp_cc_mdss_dptx1_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx1_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK] = + &disp_cc_mdss_dptx1_usb_router_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK] = &disp_cc_mdss_dptx2_aux_clk.clkr, + [DISP_CC_MDSS_DPTX2_AUX_CLK_SRC] = &disp_cc_mdss_dptx2_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_CRYPTO_CLK] = &disp_cc_mdss_dptx2_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK] = &disp_cc_mdss_dptx2_link_clk.clkr, + [DISP_CC_MDSS_DPTX2_LINK_CLK_SRC] = &disp_cc_mdss_dptx2_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx2_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_LINK_INTF_CLK] = &disp_cc_mdss_dptx2_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK] = &disp_cc_mdss_dptx2_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx2_pixel0_clk_src.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK] = &disp_cc_mdss_dptx2_pixel1_clk.clkr, + [DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC] = &disp_cc_mdss_dptx2_pixel1_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK] = &disp_cc_mdss_dptx3_aux_clk.clkr, + [DISP_CC_MDSS_DPTX3_AUX_CLK_SRC] = &disp_cc_mdss_dptx3_aux_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_CRYPTO_CLK] = &disp_cc_mdss_dptx3_crypto_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK] = &disp_cc_mdss_dptx3_link_clk.clkr, + [DISP_CC_MDSS_DPTX3_LINK_CLK_SRC] = &disp_cc_mdss_dptx3_link_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC] = &disp_cc_mdss_dptx3_link_div_clk_src.clkr, + [DISP_CC_MDSS_DPTX3_LINK_INTF_CLK] = &disp_cc_mdss_dptx3_link_intf_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK] = &disp_cc_mdss_dptx3_pixel0_clk.clkr, + [DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC] = &disp_cc_mdss_dptx3_pixel0_clk_src.clkr, + [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr, + [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr, + [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr, + [DISP_CC_MDSS_ESC1_CLK_SRC] = &disp_cc_mdss_esc1_clk_src.clkr, + [DISP_CC_MDSS_MDP1_CLK] = &disp_cc_mdss_mdp1_clk.clkr, + [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr, + [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr, + [DISP_CC_MDSS_MDP_LUT1_CLK] = &disp_cc_mdss_mdp_lut1_clk.clkr, + [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr, + [DISP_CC_MDSS_MDP_SS_IP_CLK] = &disp_cc_mdss_mdp_ss_ip_clk.clkr, + [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr, + [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr, + [DISP_CC_MDSS_PCLK1_CLK] = &disp_cc_mdss_pclk1_clk.clkr, + [DISP_CC_MDSS_PCLK1_CLK_SRC] = &disp_cc_mdss_pclk1_clk_src.clkr, + [DISP_CC_MDSS_PCLK2_CLK] = &disp_cc_mdss_pclk2_clk.clkr, + [DISP_CC_MDSS_PCLK2_CLK_SRC] = &disp_cc_mdss_pclk2_clk_src.clkr, + [DISP_CC_MDSS_VSYNC1_CLK] = &disp_cc_mdss_vsync1_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr, + [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr, + [DISP_CC_OSC_CLK] = &disp_cc_osc_clk.clkr, + [DISP_CC_OSC_CLK_SRC] = &disp_cc_osc_clk_src.clkr, + [DISP_CC_PLL0] = &disp_cc_pll0.clkr, + [DISP_CC_PLL1] = &disp_cc_pll1.clkr, + [DISP_CC_PLL2] = &disp_cc_pll2.clkr, +}; + +static struct gdsc *disp_cc_kaanapali_gdscs[] = { + [DISP_CC_MDSS_CORE_GDSC] = &disp_cc_mdss_core_gdsc, + [DISP_CC_MDSS_CORE_INT2_GDSC] = &disp_cc_mdss_core_int2_gdsc, +}; + +static const struct qcom_reset_map disp_cc_kaanapali_resets[] = { + [DISP_CC_MDSS_CORE_BCR] = { 0x8000 }, + [DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 }, + [DISP_CC_MDSS_RSCC_BCR] = { 0xc000 }, +}; + +static struct clk_alpha_pll *disp_cc_kaanapali_plls[] = { + &disp_cc_pll0, + &disp_cc_pll1, + &disp_cc_pll2, +}; + +static u32 disp_cc_kaanapali_critical_cbcrs[] = { + 0xe064, /* DISP_CC_SLEEP_CLK */ + 0xe05c, /* DISP_CC_XO_CLK */ + 0xc00c, /* DISP_CC_MDSS_RSCC_AHB_CLK */ + 0xc008, /* DISP_CC_MDSS_RSCC_VSYNC_CLK */ +}; + +static const struct regmap_config disp_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x12094, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* Enable clock gating for MDP clocks */ + regmap_update_bits(regmap, DISP_CC_MISC_CMD, BIT(4), BIT(4)); +} + +static struct qcom_cc_driver_data disp_cc_kaanapali_driver_data = { + .alpha_plls = disp_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(disp_cc_kaanapali_plls), + .clk_cbcrs = disp_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(disp_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc disp_cc_kaanapali_desc = { + .config = &disp_cc_kaanapali_regmap_config, + .clks = disp_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(disp_cc_kaanapali_clocks), + .resets = disp_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(disp_cc_kaanapali_resets), + .gdscs = disp_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(disp_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &disp_cc_kaanapali_driver_data, +}; + +static const struct of_device_id disp_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-dispcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, disp_cc_kaanapali_match_table); + +static int disp_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &disp_cc_kaanapali_desc); +} + +static struct platform_driver disp_cc_kaanapali_driver = { + .probe = disp_cc_kaanapali_probe, + .driver = { + .name = "dispcc-kaanapali", + .of_match_table = disp_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(disp_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI DISPCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/dispcc-sdm845.c b/drivers/clk/qcom/dispcc-sdm845.c index 2f9e9665d7e9..78e43f6d7502 100644 --- a/drivers/clk/qcom/dispcc-sdm845.c +++ b/drivers/clk/qcom/dispcc-sdm845.c @@ -280,7 +280,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = { .name = "disp_cc_mdss_pclk0_clk_src", .parent_data = disp_cc_parent_data_4, .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; @@ -295,7 +295,7 @@ static struct clk_rcg2 disp_cc_mdss_pclk1_clk_src = { .name = "disp_cc_mdss_pclk1_clk_src", .parent_data = disp_cc_parent_data_4, .num_parents = ARRAY_SIZE(disp_cc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; diff --git a/drivers/clk/qcom/dispcc-sm7150.c b/drivers/clk/qcom/dispcc-sm7150.c index 811d380a8e9f..ed8e34ffd69b 100644 --- a/drivers/clk/qcom/dispcc-sm7150.c +++ b/drivers/clk/qcom/dispcc-sm7150.c @@ -371,7 +371,7 @@ static struct clk_rcg2 dispcc_mdss_pclk1_clk_src = { .name = "dispcc_mdss_pclk1_clk_src", .parent_data = dispcc_parent_data_4, .num_parents = ARRAY_SIZE(dispcc_parent_data_4), - .flags = CLK_SET_RATE_PARENT, + .flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, .ops = &clk_pixel_ops, }, }; diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c index deab819576d0..238e205735ed 100644 --- a/drivers/clk/qcom/gcc-glymur.c +++ b/drivers/clk/qcom/gcc-glymur.c @@ -2317,7 +2317,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_17, .num_parents = ARRAY_SIZE(gcc_parent_data_17), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -2339,7 +2339,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_3, .num_parents = ARRAY_SIZE(gcc_parent_data_3), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-ipq5018.c b/drivers/clk/qcom/gcc-ipq5018.c index dcda2be8c1a5..64792cda0620 100644 --- a/drivers/clk/qcom/gcc-ipq5018.c +++ b/drivers/clk/qcom/gcc-ipq5018.c @@ -1340,6 +1340,7 @@ static struct clk_branch gcc_sleep_clk_src = { .name = "gcc_sleep_clk_src", .parent_data = gcc_sleep_clk_data, .num_parents = ARRAY_SIZE(gcc_sleep_clk_data), + .flags = CLK_IS_CRITICAL, .ops = &clk_branch2_ops, }, }, diff --git a/drivers/clk/qcom/gcc-kaanapali.c b/drivers/clk/qcom/gcc-kaanapali.c new file mode 100644 index 000000000000..b9743284927d --- /dev/null +++ b/drivers/clk/qcom/gcc-kaanapali.c @@ -0,0 +1,3540 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "clk-regmap-phy-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_BI_TCXO_AO, + DT_SLEEP_CLK, + DT_PCIE_0_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, + DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +enum { + P_BI_TCXO, + P_GCC_GPLL0_OUT_EVEN, + P_GCC_GPLL0_OUT_MAIN, + P_GCC_GPLL1_OUT_MAIN, + P_GCC_GPLL4_OUT_MAIN, + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, + P_PCIE_0_PIPE_CLK, + P_SLEEP_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, + P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, +}; + +static struct clk_alpha_pll gcc_gpll0 = { + .offset = 0x0, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gcc_gpll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gcc_gpll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gcc_gpll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gcc_gpll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static struct clk_alpha_pll gcc_gpll1 = { + .offset = 0x1000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll4 = { + .offset = 0x4000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll4", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll7 = { + .offset = 0x7000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll7", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static struct clk_alpha_pll gcc_gpll9 = { + .offset = 0x9000, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .enable_reg = 0x52020, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpll9", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_fixed_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map gcc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL1_OUT_MAIN, 4 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll1.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_SLEEP_CLK, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .index = DT_SLEEP_CLK }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_4[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data gcc_parent_data_4[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map gcc_parent_map_5[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL7_OUT_MAIN, 2 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_5[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll7.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_6[] = { + { P_BI_TCXO, 0 }, + { P_SLEEP_CLK, 5 }, +}; + +static const struct clk_parent_data gcc_parent_data_6[] = { + { .index = DT_BI_TCXO }, + { .index = DT_SLEEP_CLK }, +}; + +static const struct parent_map gcc_parent_map_8[] = { + { P_BI_TCXO, 0 }, + { P_GCC_GPLL0_OUT_MAIN, 1 }, + { P_GCC_GPLL9_OUT_MAIN, 2 }, + { P_GCC_GPLL4_OUT_MAIN, 5 }, + { P_GCC_GPLL0_OUT_EVEN, 6 }, +}; + +static const struct clk_parent_data gcc_parent_data_8[] = { + { .index = DT_BI_TCXO }, + { .hw = &gcc_gpll0.clkr.hw }, + { .hw = &gcc_gpll9.clkr.hw }, + { .hw = &gcc_gpll4.clkr.hw }, + { .hw = &gcc_gpll0_out_even.clkr.hw }, +}; + +static const struct parent_map gcc_parent_map_12[] = { + { P_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK, 0 }, + { P_BI_TCXO, 2 }, +}; + +static const struct clk_parent_data gcc_parent_data_12[] = { + { .index = DT_USB3_PHY_WRAPPER_GCC_USB30_PIPE_CLK }, + { .index = DT_BI_TCXO }, +}; + +static struct clk_regmap_phy_mux gcc_pcie_0_pipe_clk_src = { + .reg = 0x6b090, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_PCIE_0_PIPE_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77068, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770ec, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_RX_SYMBOL_1_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77058, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data){ + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + .reg = 0x39074, + .shift = 0, + .width = 2, + .parent_map = gcc_parent_map_12, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk_src", + .parent_data = gcc_parent_data_12, + .num_parents = ARRAY_SIZE(gcc_parent_data_12), + .ops = &clk_regmap_mux_closest_ops, + }, + }, +}; + +static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp2_clk_src = { + .cmd_rcgr = 0x65004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_rcg2 gcc_gp3_clk_src = { + .cmd_rcgr = 0x66004, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_2, + .freq_tbl = ftbl_gcc_gp1_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk_src", + .parent_data = gcc_parent_data_2, + .num_parents = ARRAY_SIZE(gcc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_aux_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_aux_clk_src = { + .cmd_rcgr = 0x6b094, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_pcie_0_phy_aux_clk_src = { + .cmd_rcgr = 0x6b0ac, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pcie_0_phy_rchng_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pcie_0_phy_rchng_clk_src = { + .cmd_rcgr = 0x6b078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_phy_rchng_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_pdm2_clk_src[] = { + F(60000000, P_GCC_GPLL0_OUT_MAIN, 10, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_pdm2_clk_src = { + .cmd_rcgr = 0x33010, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pdm2_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s0_clk_src = { + .cmd_rcgr = 0x17008, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s1_clk_src = { + .cmd_rcgr = 0x17024, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s2_clk_src = { + .cmd_rcgr = 0x17040, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s3_clk_src = { + .cmd_rcgr = 0x1705c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_qupv3_i2c_s4_clk_src = { + .cmd_rcgr = 0x17078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(150000000, P_GCC_GPLL0_OUT_EVEN, 2, 0, 0), + F(250000000, P_GCC_GPLL7_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_qspi_ref_clk_src_init = { + .name = "gcc_qupv3_wrap1_qspi_ref_clk_src", + .parent_data = gcc_parent_data_5, + .num_parents = ARRAY_SIZE(gcc_parent_data_5), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_qspi_ref_clk_src = { + .cmd_rcgr = 0x188c0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_5, + .freq_tbl = ftbl_gcc_qupv3_wrap1_qspi_ref_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_qspi_ref_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s0_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = { + .name = "gcc_qupv3_wrap1_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = { + .cmd_rcgr = 0x18014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = { + .name = "gcc_qupv3_wrap1_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = { + .cmd_rcgr = 0x18150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = { + .name = "gcc_qupv3_wrap1_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = { + .cmd_rcgr = 0x182a0, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap1_s4_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = { + .name = "gcc_qupv3_wrap1_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = { + .cmd_rcgr = 0x183dc, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = { + .name = "gcc_qupv3_wrap1_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = { + .cmd_rcgr = 0x18518, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = { + .name = "gcc_qupv3_wrap1_s6_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = { + .cmd_rcgr = 0x18654, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = { + .name = "gcc_qupv3_wrap1_s7_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = { + .cmd_rcgr = 0x18790, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s0_clk_src_init = { + .name = "gcc_qupv3_wrap2_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s0_clk_src = { + .cmd_rcgr = 0x1e014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s1_clk_src_init = { + .name = "gcc_qupv3_wrap2_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s1_clk_src = { + .cmd_rcgr = 0x1e150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s2_clk_src_init = { + .name = "gcc_qupv3_wrap2_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s2_clk_src = { + .cmd_rcgr = 0x1e28c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s3_clk_src_init = { + .name = "gcc_qupv3_wrap2_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s3_clk_src = { + .cmd_rcgr = 0x1e3c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap2_s4_clk_src_init = { + .name = "gcc_qupv3_wrap2_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap2_s4_clk_src = { + .cmd_rcgr = 0x1e504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap2_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src[] = { + F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_ibi_ctrl_0_clk_src = { + .cmd_rcgr = 0xa877c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_1, + .freq_tbl = ftbl_gcc_qupv3_wrap3_ibi_ctrl_0_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_0_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s0_clk_src_init = { + .name = "gcc_qupv3_wrap3_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s0_clk_src = { + .cmd_rcgr = 0xa8014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s1_clk_src_init = { + .name = "gcc_qupv3_wrap3_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s1_clk_src = { + .cmd_rcgr = 0xa8150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s2_clk_src_init = { + .name = "gcc_qupv3_wrap3_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s2_clk_src = { + .cmd_rcgr = 0xa828c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s3_clk_src_init = { + .name = "gcc_qupv3_wrap3_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s3_clk_src = { + .cmd_rcgr = 0xa83c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap3_s4_clk_src_init = { + .name = "gcc_qupv3_wrap3_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s4_clk_src = { + .cmd_rcgr = 0xa8504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_qupv3_wrap3_s5_clk_src[] = { + F(7372800, P_GCC_GPLL0_OUT_EVEN, 1, 384, 15625), + F(14745600, P_GCC_GPLL0_OUT_EVEN, 1, 768, 15625), + F(19200000, P_BI_TCXO, 1, 0, 0), + F(29491200, P_GCC_GPLL0_OUT_EVEN, 1, 1536, 15625), + F(32000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 75), + F(48000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 25), + F(51200000, P_GCC_GPLL0_OUT_EVEN, 1, 64, 375), + F(60000000, P_GCC_GPLL0_OUT_EVEN, 5, 0, 0), + F(64000000, P_GCC_GPLL0_OUT_EVEN, 1, 16, 75), + F(66666667, P_GCC_GPLL0_OUT_MAIN, 9, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(80000000, P_GCC_GPLL0_OUT_EVEN, 1, 4, 15), + F(96000000, P_GCC_GPLL0_OUT_EVEN, 1, 8, 25), + F(100000000, P_GCC_GPLL0_OUT_MAIN, 6, 0, 0), + F(102400000, P_GCC_GPLL0_OUT_EVEN, 1, 128, 375), + F(112000000, P_GCC_GPLL0_OUT_EVEN, 1, 28, 75), + F(117964800, P_GCC_GPLL0_OUT_EVEN, 1, 6144, 15625), + F(120000000, P_GCC_GPLL0_OUT_MAIN, 5, 0, 0), + F(128000000, P_GCC_GPLL0_OUT_MAIN, 1, 16, 75), + { } +}; + +static struct clk_init_data gcc_qupv3_wrap3_s5_clk_src_init = { + .name = "gcc_qupv3_wrap3_s5_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap3_s5_clk_src = { + .cmd_rcgr = 0xa8640, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap3_s5_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap3_s5_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s0_clk_src_init = { + .name = "gcc_qupv3_wrap4_s0_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s0_clk_src = { + .cmd_rcgr = 0xa9014, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s0_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s1_clk_src_init = { + .name = "gcc_qupv3_wrap4_s1_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s1_clk_src = { + .cmd_rcgr = 0xa9150, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s1_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s2_clk_src_init = { + .name = "gcc_qupv3_wrap4_s2_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s2_clk_src = { + .cmd_rcgr = 0xa928c, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s4_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s2_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s3_clk_src_init = { + .name = "gcc_qupv3_wrap4_s3_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s3_clk_src = { + .cmd_rcgr = 0xa93c8, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s3_clk_src_init, +}; + +static struct clk_init_data gcc_qupv3_wrap4_s4_clk_src_init = { + .name = "gcc_qupv3_wrap4_s4_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, +}; + +static struct clk_rcg2 gcc_qupv3_wrap4_s4_clk_src = { + .cmd_rcgr = 0xa9504, + .mnd_width = 16, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_qupv3_wrap1_s0_clk_src, + .clkr.hw.init = &gcc_qupv3_wrap4_s4_clk_src_init, +}; + +static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .cmd_rcgr = 0x1401c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_8, + .freq_tbl = ftbl_gcc_sdcc2_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_sdcc4_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { + .cmd_rcgr = 0x1601c, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_sdcc4_apps_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_floor_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_axi_clk_src[] = { + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_axi_clk_src = { + .cmd_rcgr = 0x77034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_axi_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_ice_core_clk_src[] = { + F(75000000, P_GCC_GPLL0_OUT_EVEN, 4, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(201500000, P_GCC_GPLL4_OUT_MAIN, 4, 0, 0), + F(403000000, P_GCC_GPLL4_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_ice_core_clk_src = { + .cmd_rcgr = 0x7708c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_ufs_phy_phy_aux_clk_src[] = { + F(9600000, P_BI_TCXO, 2, 0, 0), + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_ufs_phy_phy_aux_clk_src = { + .cmd_rcgr = 0x770c0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_4, + .freq_tbl = ftbl_gcc_ufs_phy_phy_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk_src", + .parent_data = gcc_parent_data_4, + .num_parents = ARRAY_SIZE(gcc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_ufs_phy_unipro_core_clk_src = { + .cmd_rcgr = 0x770a4, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_3, + .freq_tbl = ftbl_gcc_ufs_phy_ice_core_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk_src", + .parent_data = gcc_parent_data_3, + .num_parents = ARRAY_SIZE(gcc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static const struct freq_tbl ftbl_gcc_usb30_prim_master_clk_src[] = { + F(66666667, P_GCC_GPLL0_OUT_EVEN, 4.5, 0, 0), + F(133333333, P_GCC_GPLL0_OUT_MAIN, 4.5, 0, 0), + F(200000000, P_GCC_GPLL0_OUT_MAIN, 3, 0, 0), + F(240000000, P_GCC_GPLL0_OUT_MAIN, 2.5, 0, 0), + { } +}; + +static struct clk_rcg2 gcc_usb30_prim_master_clk_src = { + .cmd_rcgr = 0x39034, + .mnd_width = 8, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_usb30_prim_master_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb30_prim_mock_utmi_clk_src = { + .cmd_rcgr = 0x3904c, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_0, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = { + .cmd_rcgr = 0x39078, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gcc_parent_map_6, + .freq_tbl = ftbl_gcc_pcie_0_aux_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk_src", + .parent_data = gcc_parent_data_6, + .num_parents = ARRAY_SIZE(gcc_parent_data_6), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_no_init_park_ops, + }, +}; + +static struct clk_regmap_div gcc_qupv3_wrap1_s2_clk_src = { + .reg = 0x1828c, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_regmap_div gcc_usb30_prim_mock_utmi_postdiv_clk_src = { + .reg = 0x39064, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_postdiv_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gcc_aggre_noc_pcie_axi_clk = { + .halt_reg = 0x10068, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10068, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_noc_pcie_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_ufs_phy_axi_clk = { + .halt_reg = 0x770f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770f0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_aggre_usb3_prim_axi_clk = { + .halt_reg = 0x39094, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39094, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39094, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_aggre_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_boot_rom_ahb_clk = { + .halt_reg = 0x38004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x38004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_boot_rom_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_hf_axi_clk = { + .halt_reg = 0x26014, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_camera_sf_axi_clk = { + .halt_reg = 0x26028, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x26028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_camera_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_pcie_anoc_ahb_clk = { + .halt_reg = 0x10050, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x10050, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_pcie_anoc_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cfg_noc_usb3_prim_axi_clk = { + .halt_reg = 0x39090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x39090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cfg_noc_usb3_prim_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_cnoc_pcie_sf_axi_clk = { + .halt_reg = 0x10058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_cnoc_pcie_sf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ddrss_pcie_sf_qtb_clk = { + .halt_reg = 0x1007c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x1007c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ddrss_pcie_sf_qtb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_hf_axi_clk = { + .halt_reg = 0x2701c, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2701c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_hf_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_disp_sf_axi_clk = { + .halt_reg = 0x27008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x27008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_disp_sf_axi_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0_clk = { + .halt_reg = 0x9f008, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_eva_axi0c_clk = { + .halt_reg = 0x9f01c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x9f01c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x9f01c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_eva_axi0c_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp1_clk = { + .halt_reg = 0x64000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x64000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp2_clk = { + .halt_reg = 0x65000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x65000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gp3_clk = { + .halt_reg = 0x66000, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x66000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gp3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gp3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gemnoc_gfx_clk = { + .halt_reg = 0x71010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gemnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_gpu_gpll0_div_clk_src = { + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_gpu_gpll0_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gcc_gpll0_out_even.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_aux_clk = { + .halt_reg = 0x6b044, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_cfg_ahb_clk = { + .halt_reg = 0x6b040, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b040, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_cfg_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_mstr_axi_clk = { + .halt_reg = 0x6b030, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x6b030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_mstr_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_aux_clk = { + .halt_reg = 0x6b054, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(31), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_phy_rchng_clk = { + .halt_reg = 0x6b074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52000, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_phy_rchng_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_phy_rchng_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_pipe_clk = { + .halt_reg = 0x6b064, + .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pcie_0_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_axi_clk = { + .halt_reg = 0x6b020, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b020, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pcie_0_slv_q2a_axi_clk = { + .halt_reg = 0x6b01c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_slv_q2a_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm2_clk = { + .halt_reg = 0x3300c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3300c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_pdm2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_ahb_clk = { + .halt_reg = 0x33004, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x33004, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x33004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_pdm_xo4_clk = { + .halt_reg = 0x33008, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x33008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pdm_xo4_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_cmd_ahb_clk = { + .halt_reg = 0x26010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_cmd_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_nrt_ahb_clk = { + .halt_reg = 0x26008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x26008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x26008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_nrt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_camera_rt_ahb_clk = { + .halt_reg = 0x2600c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2600c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x2600c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_camera_rt_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_disp_dcp_sf_ahb_clk = { + .halt_reg = 0x27030, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x27030, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x27030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_disp_dcp_sf_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_gpu_ahb_clk = { + .halt_reg = 0x71008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x71008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x71008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_gpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_pcie_ahb_clk = { + .halt_reg = 0x6b018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x6b018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_pcie_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cv_cpu_ahb_clk = { + .halt_reg = 0x32014, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32014, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cv_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_cvp_ahb_clk = { + .halt_reg = 0x32008, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32008, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32008, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_cvp_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_v_cpu_ahb_clk = { + .halt_reg = 0x32010, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x32010, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_v_cpu_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qmip_video_vcodec_ahb_clk = { + .halt_reg = 0x3200c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x3200c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3200c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qmip_video_vcodec_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_core_clk = { + .halt_reg = 0x23004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s0_clk = { + .halt_reg = 0x17004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s1_clk = { + .halt_reg = 0x17020, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s2_clk = { + .halt_reg = 0x1703c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s3_clk = { + .halt_reg = 0x17058, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s4_clk = { + .halt_reg = 0x17074, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_i2c_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_i2c_s_ahb_clk = { + .halt_reg = 0x23000, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23000, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_i2c_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_2x_clk = { + .halt_reg = 0x2315c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_core_clk = { + .halt_reg = 0x23148, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_qspi_ref_clk = { + .halt_reg = 0x188bc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_qspi_ref_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s0_clk = { + .halt_reg = 0x18004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s1_clk = { + .halt_reg = 0x18140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s2_clk = { + .halt_reg = 0x1827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s3_clk = { + .halt_reg = 0x18290, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s4_clk = { + .halt_reg = 0x183cc, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s5_clk = { + .halt_reg = 0x18508, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s6_clk = { + .halt_reg = 0x18644, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s6_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s6_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap1_s7_clk = { + .halt_reg = 0x18780, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap1_s7_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap1_s7_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_2x_clk = { + .halt_reg = 0x232b4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(3), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_core_clk = { + .halt_reg = 0x232a0, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s0_clk = { + .halt_reg = 0x1e004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(4), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s1_clk = { + .halt_reg = 0x1e140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(5), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s2_clk = { + .halt_reg = 0x1e27c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(6), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s3_clk = { + .halt_reg = 0x1e3b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(7), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap2_s4_clk = { + .halt_reg = 0x1e4f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap2_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap2_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_2x_clk = { + .halt_reg = 0x2340c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(11), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_core_clk = { + .halt_reg = 0x233f8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(10), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_1_clk = { + .halt_reg = 0xa8774, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8774, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_ibi_ctrl_2_clk = { + .halt_reg = 0xa8778, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8778, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_ibi_ctrl_2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s0_clk = { + .halt_reg = 0xa8004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(12), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s1_clk = { + .halt_reg = 0xa8140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(13), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s2_clk = { + .halt_reg = 0xa827c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(14), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s3_clk = { + .halt_reg = 0xa83b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(15), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s4_clk = { + .halt_reg = 0xa84f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(16), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap3_s5_clk = { + .halt_reg = 0xa8630, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(17), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap3_s5_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap3_s5_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_2x_clk = { + .halt_reg = 0x23564, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_2x_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_core_clk = { + .halt_reg = 0x23550, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(24), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_core_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s0_clk = { + .halt_reg = 0xa9004, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(26), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s1_clk = { + .halt_reg = 0xa9140, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(27), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s2_clk = { + .halt_reg = 0xa927c, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(28), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s2_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s2_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s3_clk = { + .halt_reg = 0xa93b8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(29), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s3_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s3_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap4_s4_clk = { + .halt_reg = 0xa94f4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap4_s4_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_qupv3_wrap4_s4_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_m_axi_clk = { + .halt_reg = 0x23140, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23140, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(20), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_m_axi_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_1_s_ahb_clk = { + .halt_reg = 0x23144, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23144, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52008, + .enable_mask = BIT(21), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_1_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_m_ahb_clk = { + .halt_reg = 0x23298, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23298, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(2), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_2_s_ahb_clk = { + .halt_reg = 0x2329c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2329c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52010, + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_2_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_1_ahb_clk = { + .halt_reg = 0xa876c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa876c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(18), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_1_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_ibi_2_ahb_clk = { + .halt_reg = 0xa8770, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0xa8770, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_ibi_2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_m_ahb_clk = { + .halt_reg = 0x233f0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(8), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_3_s_ahb_clk = { + .halt_reg = 0x233f4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x233f4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(9), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_3_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_m_ahb_clk = { + .halt_reg = 0x23548, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x23548, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(22), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_m_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_qupv3_wrap_4_s_ahb_clk = { + .halt_reg = 0x2354c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x2354c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x52018, + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_qupv3_wrap_4_s_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_ahb_clk = { + .halt_reg = 0x14014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc2_apps_clk = { + .halt_reg = 0x14004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x14004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc2_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc2_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_ahb_clk = { + .halt_reg = 0x16014, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16014, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_sdcc4_apps_clk = { + .halt_reg = 0x16004, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x16004, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_sdcc4_apps_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_sdcc4_apps_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ahb_clk = { + .halt_reg = 0x77028, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77028, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ahb_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_axi_clk = { + .halt_reg = 0x77018, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x77018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x77018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_axi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_axi_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_ice_core_clk = { + .halt_reg = 0x7707c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7707c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7707c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_ice_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_ice_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_phy_aux_clk = { + .halt_reg = 0x770bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x770bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x770bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { + .halt_reg = 0x77030, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x77030, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { + .halt_reg = 0x770d8, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x770d8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { + .halt_reg = 0x7702c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x7702c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_ufs_phy_unipro_core_clk = { + .halt_reg = 0x7706c, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x7706c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x7706c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_unipro_core_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_unipro_core_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_master_clk = { + .halt_reg = 0x39018, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_master_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_master_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_mock_utmi_clk = { + .halt_reg = 0x3902c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3902c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_mock_utmi_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb30_prim_sleep_clk = { + .halt_reg = 0x39028, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39028, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb30_prim_sleep_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_aux_clk = { + .halt_reg = 0x39068, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x39068, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + .halt_reg = 0x3906c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x3906c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_com_aux_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_aux_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x39070, + .halt_check = BRANCH_HALT_DELAY, + .hwcg_reg = 0x39070, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x39070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi0_clk = { + .halt_reg = 0x32018, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x32018, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x32018, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi0_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gcc_video_axi1_clk = { + .halt_reg = 0x3202c, + .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x3202c, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x3202c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_video_axi1_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gcc_pcie_0_gdsc = { + .gdscr = 0x6b004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(0), + .pd = { + .name = "gcc_pcie_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_pcie_0_phy_gdsc = { + .gdscr = 0x6c000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .collapse_ctrl = 0x5214c, + .collapse_mask = BIT(2), + .pd = { + .name = "gcc_pcie_0_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | VOTABLE, +}; + +static struct gdsc gcc_ufs_mem_phy_gdsc = { + .gdscr = 0x9e000, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_ufs_mem_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_ufs_phy_gdsc = { + .gdscr = 0x77004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_ufs_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb30_prim_gdsc = { + .gdscr = 0x39004, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gcc_usb30_prim_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc gcc_usb3_phy_gdsc = { + .gdscr = 0x50018, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x2, + .pd = { + .name = "gcc_usb3_phy_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gcc_kaanapali_clocks[] = { + [GCC_AGGRE_NOC_PCIE_AXI_CLK] = &gcc_aggre_noc_pcie_axi_clk.clkr, + [GCC_AGGRE_UFS_PHY_AXI_CLK] = &gcc_aggre_ufs_phy_axi_clk.clkr, + [GCC_AGGRE_USB3_PRIM_AXI_CLK] = &gcc_aggre_usb3_prim_axi_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMERA_HF_AXI_CLK] = &gcc_camera_hf_axi_clk.clkr, + [GCC_CAMERA_SF_AXI_CLK] = &gcc_camera_sf_axi_clk.clkr, + [GCC_CFG_NOC_PCIE_ANOC_AHB_CLK] = &gcc_cfg_noc_pcie_anoc_ahb_clk.clkr, + [GCC_CFG_NOC_USB3_PRIM_AXI_CLK] = &gcc_cfg_noc_usb3_prim_axi_clk.clkr, + [GCC_CNOC_PCIE_SF_AXI_CLK] = &gcc_cnoc_pcie_sf_axi_clk.clkr, + [GCC_DDRSS_PCIE_SF_QTB_CLK] = &gcc_ddrss_pcie_sf_qtb_clk.clkr, + [GCC_DISP_HF_AXI_CLK] = &gcc_disp_hf_axi_clk.clkr, + [GCC_DISP_SF_AXI_CLK] = &gcc_disp_sf_axi_clk.clkr, + [GCC_EVA_AXI0_CLK] = &gcc_eva_axi0_clk.clkr, + [GCC_EVA_AXI0C_CLK] = &gcc_eva_axi0c_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP1_CLK_SRC] = &gcc_gp1_clk_src.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP2_CLK_SRC] = &gcc_gp2_clk_src.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr, + [GCC_GPLL0] = &gcc_gpll0.clkr, + [GCC_GPLL0_OUT_EVEN] = &gcc_gpll0_out_even.clkr, + [GCC_GPLL1] = &gcc_gpll1.clkr, + [GCC_GPLL4] = &gcc_gpll4.clkr, + [GCC_GPLL7] = &gcc_gpll7.clkr, + [GCC_GPLL9] = &gcc_gpll9.clkr, + [GCC_GPU_GEMNOC_GFX_CLK] = &gcc_gpu_gemnoc_gfx_clk.clkr, + [GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr, + [GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr, + [GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr, + [GCC_PCIE_0_AUX_CLK_SRC] = &gcc_pcie_0_aux_clk_src.clkr, + [GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr, + [GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK] = &gcc_pcie_0_phy_aux_clk.clkr, + [GCC_PCIE_0_PHY_AUX_CLK_SRC] = &gcc_pcie_0_phy_aux_clk_src.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK] = &gcc_pcie_0_phy_rchng_clk.clkr, + [GCC_PCIE_0_PHY_RCHNG_CLK_SRC] = &gcc_pcie_0_phy_rchng_clk_src.clkr, + [GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr, + [GCC_PCIE_0_PIPE_CLK_SRC] = &gcc_pcie_0_pipe_clk_src.clkr, + [GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr, + [GCC_PCIE_0_SLV_Q2A_AXI_CLK] = &gcc_pcie_0_slv_q2a_axi_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM2_CLK_SRC] = &gcc_pdm2_clk_src.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PDM_XO4_CLK] = &gcc_pdm_xo4_clk.clkr, + [GCC_QUPV3_I2C_CORE_CLK] = &gcc_qupv3_i2c_core_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK] = &gcc_qupv3_i2c_s0_clk.clkr, + [GCC_QUPV3_I2C_S0_CLK_SRC] = &gcc_qupv3_i2c_s0_clk_src.clkr, + [GCC_QUPV3_I2C_S1_CLK] = &gcc_qupv3_i2c_s1_clk.clkr, + [GCC_QUPV3_I2C_S1_CLK_SRC] = &gcc_qupv3_i2c_s1_clk_src.clkr, + [GCC_QUPV3_I2C_S2_CLK] = &gcc_qupv3_i2c_s2_clk.clkr, + [GCC_QUPV3_I2C_S2_CLK_SRC] = &gcc_qupv3_i2c_s2_clk_src.clkr, + [GCC_QUPV3_I2C_S3_CLK] = &gcc_qupv3_i2c_s3_clk.clkr, + [GCC_QUPV3_I2C_S3_CLK_SRC] = &gcc_qupv3_i2c_s3_clk_src.clkr, + [GCC_QUPV3_I2C_S4_CLK] = &gcc_qupv3_i2c_s4_clk.clkr, + [GCC_QUPV3_I2C_S4_CLK_SRC] = &gcc_qupv3_i2c_s4_clk_src.clkr, + [GCC_QUPV3_I2C_S_AHB_CLK] = &gcc_qupv3_i2c_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_2X_CLK] = &gcc_qupv3_wrap1_core_2x_clk.clkr, + [GCC_QUPV3_WRAP1_CORE_CLK] = &gcc_qupv3_wrap1_core_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK] = &gcc_qupv3_wrap1_qspi_ref_clk.clkr, + [GCC_QUPV3_WRAP1_QSPI_REF_CLK_SRC] = &gcc_qupv3_wrap1_qspi_ref_clk_src.clkr, + [GCC_QUPV3_WRAP1_S0_CLK] = &gcc_qupv3_wrap1_s0_clk.clkr, + [GCC_QUPV3_WRAP1_S0_CLK_SRC] = &gcc_qupv3_wrap1_s0_clk_src.clkr, + [GCC_QUPV3_WRAP1_S1_CLK] = &gcc_qupv3_wrap1_s1_clk.clkr, + [GCC_QUPV3_WRAP1_S1_CLK_SRC] = &gcc_qupv3_wrap1_s1_clk_src.clkr, + [GCC_QUPV3_WRAP1_S2_CLK] = &gcc_qupv3_wrap1_s2_clk.clkr, + [GCC_QUPV3_WRAP1_S2_CLK_SRC] = &gcc_qupv3_wrap1_s2_clk_src.clkr, + [GCC_QUPV3_WRAP1_S3_CLK] = &gcc_qupv3_wrap1_s3_clk.clkr, + [GCC_QUPV3_WRAP1_S3_CLK_SRC] = &gcc_qupv3_wrap1_s3_clk_src.clkr, + [GCC_QUPV3_WRAP1_S4_CLK] = &gcc_qupv3_wrap1_s4_clk.clkr, + [GCC_QUPV3_WRAP1_S4_CLK_SRC] = &gcc_qupv3_wrap1_s4_clk_src.clkr, + [GCC_QUPV3_WRAP1_S5_CLK] = &gcc_qupv3_wrap1_s5_clk.clkr, + [GCC_QUPV3_WRAP1_S5_CLK_SRC] = &gcc_qupv3_wrap1_s5_clk_src.clkr, + [GCC_QUPV3_WRAP1_S6_CLK] = &gcc_qupv3_wrap1_s6_clk.clkr, + [GCC_QUPV3_WRAP1_S6_CLK_SRC] = &gcc_qupv3_wrap1_s6_clk_src.clkr, + [GCC_QUPV3_WRAP1_S7_CLK] = &gcc_qupv3_wrap1_s7_clk.clkr, + [GCC_QUPV3_WRAP1_S7_CLK_SRC] = &gcc_qupv3_wrap1_s7_clk_src.clkr, + [GCC_QUPV3_WRAP2_CORE_2X_CLK] = &gcc_qupv3_wrap2_core_2x_clk.clkr, + [GCC_QUPV3_WRAP2_CORE_CLK] = &gcc_qupv3_wrap2_core_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK] = &gcc_qupv3_wrap2_s0_clk.clkr, + [GCC_QUPV3_WRAP2_S0_CLK_SRC] = &gcc_qupv3_wrap2_s0_clk_src.clkr, + [GCC_QUPV3_WRAP2_S1_CLK] = &gcc_qupv3_wrap2_s1_clk.clkr, + [GCC_QUPV3_WRAP2_S1_CLK_SRC] = &gcc_qupv3_wrap2_s1_clk_src.clkr, + [GCC_QUPV3_WRAP2_S2_CLK] = &gcc_qupv3_wrap2_s2_clk.clkr, + [GCC_QUPV3_WRAP2_S2_CLK_SRC] = &gcc_qupv3_wrap2_s2_clk_src.clkr, + [GCC_QUPV3_WRAP2_S3_CLK] = &gcc_qupv3_wrap2_s3_clk.clkr, + [GCC_QUPV3_WRAP2_S3_CLK_SRC] = &gcc_qupv3_wrap2_s3_clk_src.clkr, + [GCC_QUPV3_WRAP2_S4_CLK] = &gcc_qupv3_wrap2_s4_clk.clkr, + [GCC_QUPV3_WRAP2_S4_CLK_SRC] = &gcc_qupv3_wrap2_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_CORE_2X_CLK] = &gcc_qupv3_wrap3_core_2x_clk.clkr, + [GCC_QUPV3_WRAP3_CORE_CLK] = &gcc_qupv3_wrap3_core_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_0_CLK_SRC] = &gcc_qupv3_wrap3_ibi_ctrl_0_clk_src.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_1_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_1_clk.clkr, + [GCC_QUPV3_WRAP3_IBI_CTRL_2_CLK] = &gcc_qupv3_wrap3_ibi_ctrl_2_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK] = &gcc_qupv3_wrap3_s0_clk.clkr, + [GCC_QUPV3_WRAP3_S0_CLK_SRC] = &gcc_qupv3_wrap3_s0_clk_src.clkr, + [GCC_QUPV3_WRAP3_S1_CLK] = &gcc_qupv3_wrap3_s1_clk.clkr, + [GCC_QUPV3_WRAP3_S1_CLK_SRC] = &gcc_qupv3_wrap3_s1_clk_src.clkr, + [GCC_QUPV3_WRAP3_S2_CLK] = &gcc_qupv3_wrap3_s2_clk.clkr, + [GCC_QUPV3_WRAP3_S2_CLK_SRC] = &gcc_qupv3_wrap3_s2_clk_src.clkr, + [GCC_QUPV3_WRAP3_S3_CLK] = &gcc_qupv3_wrap3_s3_clk.clkr, + [GCC_QUPV3_WRAP3_S3_CLK_SRC] = &gcc_qupv3_wrap3_s3_clk_src.clkr, + [GCC_QUPV3_WRAP3_S4_CLK] = &gcc_qupv3_wrap3_s4_clk.clkr, + [GCC_QUPV3_WRAP3_S4_CLK_SRC] = &gcc_qupv3_wrap3_s4_clk_src.clkr, + [GCC_QUPV3_WRAP3_S5_CLK] = &gcc_qupv3_wrap3_s5_clk.clkr, + [GCC_QUPV3_WRAP3_S5_CLK_SRC] = &gcc_qupv3_wrap3_s5_clk_src.clkr, + [GCC_QUPV3_WRAP4_CORE_2X_CLK] = &gcc_qupv3_wrap4_core_2x_clk.clkr, + [GCC_QUPV3_WRAP4_CORE_CLK] = &gcc_qupv3_wrap4_core_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK] = &gcc_qupv3_wrap4_s0_clk.clkr, + [GCC_QUPV3_WRAP4_S0_CLK_SRC] = &gcc_qupv3_wrap4_s0_clk_src.clkr, + [GCC_QUPV3_WRAP4_S1_CLK] = &gcc_qupv3_wrap4_s1_clk.clkr, + [GCC_QUPV3_WRAP4_S1_CLK_SRC] = &gcc_qupv3_wrap4_s1_clk_src.clkr, + [GCC_QUPV3_WRAP4_S2_CLK] = &gcc_qupv3_wrap4_s2_clk.clkr, + [GCC_QUPV3_WRAP4_S2_CLK_SRC] = &gcc_qupv3_wrap4_s2_clk_src.clkr, + [GCC_QUPV3_WRAP4_S3_CLK] = &gcc_qupv3_wrap4_s3_clk.clkr, + [GCC_QUPV3_WRAP4_S3_CLK_SRC] = &gcc_qupv3_wrap4_s3_clk_src.clkr, + [GCC_QUPV3_WRAP4_S4_CLK] = &gcc_qupv3_wrap4_s4_clk.clkr, + [GCC_QUPV3_WRAP4_S4_CLK_SRC] = &gcc_qupv3_wrap4_s4_clk_src.clkr, + [GCC_QUPV3_WRAP_1_M_AXI_CLK] = &gcc_qupv3_wrap_1_m_axi_clk.clkr, + [GCC_QUPV3_WRAP_1_S_AHB_CLK] = &gcc_qupv3_wrap_1_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_M_AHB_CLK] = &gcc_qupv3_wrap_2_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_2_S_AHB_CLK] = &gcc_qupv3_wrap_2_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_1_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_1_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_IBI_2_AHB_CLK] = &gcc_qupv3_wrap_3_ibi_2_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_M_AHB_CLK] = &gcc_qupv3_wrap_3_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_3_S_AHB_CLK] = &gcc_qupv3_wrap_3_s_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_M_AHB_CLK] = &gcc_qupv3_wrap_4_m_ahb_clk.clkr, + [GCC_QUPV3_WRAP_4_S_AHB_CLK] = &gcc_qupv3_wrap_4_s_ahb_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SDCC2_APPS_CLK_SRC] = &gcc_sdcc2_apps_clk_src.clkr, + [GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr, + [GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr, + [GCC_SDCC4_APPS_CLK_SRC] = &gcc_sdcc4_apps_clk_src.clkr, + [GCC_UFS_PHY_AHB_CLK] = &gcc_ufs_phy_ahb_clk.clkr, + [GCC_UFS_PHY_AXI_CLK] = &gcc_ufs_phy_axi_clk.clkr, + [GCC_UFS_PHY_AXI_CLK_SRC] = &gcc_ufs_phy_axi_clk_src.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK] = &gcc_ufs_phy_ice_core_clk.clkr, + [GCC_UFS_PHY_ICE_CORE_CLK_SRC] = &gcc_ufs_phy_ice_core_clk_src.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr, + [GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr, + [GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] = &gcc_ufs_phy_unipro_core_clk_src.clkr, + [GCC_USB30_PRIM_MASTER_CLK] = &gcc_usb30_prim_master_clk.clkr, + [GCC_USB30_PRIM_MASTER_CLK_SRC] = &gcc_usb30_prim_master_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK] = &gcc_usb30_prim_mock_utmi_clk.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC] = &gcc_usb30_prim_mock_utmi_clk_src.clkr, + [GCC_USB30_PRIM_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_prim_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_PRIM_SLEEP_CLK] = &gcc_usb30_prim_sleep_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK] = &gcc_usb3_prim_phy_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_AUX_CLK_SRC] = &gcc_usb3_prim_phy_aux_clk_src.clkr, + [GCC_USB3_PRIM_PHY_COM_AUX_CLK] = &gcc_usb3_prim_phy_com_aux_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK] = &gcc_usb3_prim_phy_pipe_clk.clkr, + [GCC_USB3_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb3_prim_phy_pipe_clk_src.clkr, + [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, + [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_QMIP_CAMERA_CMD_AHB_CLK] = &gcc_qmip_camera_cmd_ahb_clk.clkr, + [GCC_QMIP_VIDEO_VCODEC_AHB_CLK] = &gcc_qmip_video_vcodec_ahb_clk.clkr, + [GCC_QMIP_GPU_AHB_CLK] = &gcc_qmip_gpu_ahb_clk.clkr, + [GCC_QMIP_CAMERA_NRT_AHB_CLK] = &gcc_qmip_camera_nrt_ahb_clk.clkr, + [GCC_QMIP_CAMERA_RT_AHB_CLK] = &gcc_qmip_camera_rt_ahb_clk.clkr, + [GCC_QMIP_DISP_DCP_SF_AHB_CLK] = &gcc_qmip_disp_dcp_sf_ahb_clk.clkr, + [GCC_QMIP_PCIE_AHB_CLK] = &gcc_qmip_pcie_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CV_CPU_AHB_CLK] = &gcc_qmip_video_cv_cpu_ahb_clk.clkr, + [GCC_QMIP_VIDEO_CVP_AHB_CLK] = &gcc_qmip_video_cvp_ahb_clk.clkr, + [GCC_QMIP_VIDEO_V_CPU_AHB_CLK] = &gcc_qmip_video_v_cpu_ahb_clk.clkr, +}; + +static struct gdsc *gcc_kaanapali_gdscs[] = { + [GCC_PCIE_0_GDSC] = &gcc_pcie_0_gdsc, + [GCC_PCIE_0_PHY_GDSC] = &gcc_pcie_0_phy_gdsc, + [GCC_UFS_MEM_PHY_GDSC] = &gcc_ufs_mem_phy_gdsc, + [GCC_UFS_PHY_GDSC] = &gcc_ufs_phy_gdsc, + [GCC_USB30_PRIM_GDSC] = &gcc_usb30_prim_gdsc, + [GCC_USB3_PHY_GDSC] = &gcc_usb3_phy_gdsc, +}; + +static const struct qcom_reset_map gcc_kaanapali_resets[] = { + [GCC_CAMERA_BCR] = { 0x26000 }, + [GCC_DISPLAY_BCR] = { 0x27000 }, + [GCC_EVA_AXI0_CLK_ARES] = { 0x9f008, 2 }, + [GCC_EVA_AXI0C_CLK_ARES] = { 0x9f01c, 2 }, + [GCC_EVA_BCR] = { 0x9f000 }, + [GCC_GPU_BCR] = { 0x71000 }, + [GCC_PCIE_0_BCR] = { 0x6b000 }, + [GCC_PCIE_0_LINK_DOWN_BCR] = { 0x6c014 }, + [GCC_PCIE_0_NOCSR_COM_PHY_BCR] = { 0x6c020 }, + [GCC_PCIE_0_PHY_BCR] = { 0x6c01c }, + [GCC_PCIE_0_PHY_NOCSR_COM_PHY_BCR] = { 0x6c028 }, + [GCC_PCIE_PHY_BCR] = { 0x6f000 }, + [GCC_PCIE_PHY_CFG_AHB_BCR] = { 0x6f00c }, + [GCC_PCIE_PHY_COM_BCR] = { 0x6f010 }, + [GCC_PCIE_RSCC_BCR] = { 0x11000 }, + [GCC_PDM_BCR] = { 0x33000 }, + [GCC_QUPV3_WRAPPER_1_BCR] = { 0x18000 }, + [GCC_QUPV3_WRAPPER_2_BCR] = { 0x1e000 }, + [GCC_QUPV3_WRAPPER_3_BCR] = { 0xa8000 }, + [GCC_QUPV3_WRAPPER_4_BCR] = { 0xa9000 }, + [GCC_QUPV3_WRAPPER_I2C_BCR] = { 0x17000 }, + [GCC_QUSB2PHY_PRIM_BCR] = { 0x12000 }, + [GCC_QUSB2PHY_SEC_BCR] = { 0x12004 }, + [GCC_SDCC2_BCR] = { 0x14000 }, + [GCC_SDCC4_BCR] = { 0x16000 }, + [GCC_UFS_PHY_BCR] = { 0x77000 }, + [GCC_USB30_PRIM_BCR] = { 0x39000 }, + [GCC_USB3_DP_PHY_PRIM_BCR] = { 0x50008 }, + [GCC_USB3_DP_PHY_SEC_BCR] = { 0x50014 }, + [GCC_USB3_PHY_PRIM_BCR] = { 0x50000 }, + [GCC_USB3_PHY_SEC_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x50010 }, + [GCC_VIDEO_AXI0_CLK_ARES] = { 0x32018, 2 }, + [GCC_VIDEO_AXI1_CLK_ARES] = { 0x3202c, 2 }, + [GCC_VIDEO_BCR] = { 0x32000 }, + [GCC_VIDEO_XO_CLK_ARES] = { 0x32040, 2 }, +}; + +static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = { + DEFINE_RCG_DFS(gcc_qupv3_wrap1_qspi_ref_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap2_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s4_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap3_s5_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s0_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s1_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s2_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s3_clk_src), + DEFINE_RCG_DFS(gcc_qupv3_wrap4_s4_clk_src), +}; + +static u32 gcc_kaanapali_critical_cbcrs[] = { + 0xa0004, /* GCC_CAM_BIST_MCLK_AHB_CLK */ + 0x26004, /* GCC_CAMERA_AHB_CLK */ + 0x2603c, /* GCC_CAMERA_XO_CLK */ + 0x27004, /* GCC_DISP_AHB_CLK */ + 0x9f004, /* GCC_EVA_AHB_CLK */ + 0x9f024, /* GCC_EVA_XO_CLK */ + 0x71004, /* GCC_GPU_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_CFG_AHB_CLK */ + 0x52010, /* GCC_PCIE_RSCC_XO_CLK */ + 0x32004, /* GCC_VIDEO_AHB_CLK */ + 0x32040, /* GCC_VIDEO_XO_CLK */ +}; + +static const struct regmap_config gcc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x1f41f0, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* FORCE_MEM_CORE_ON for ufs phy ice core clocks */ + qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true); +} + +static struct qcom_cc_driver_data gcc_kaanapali_driver_data = { + .clk_cbcrs = gcc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gcc_kaanapali_critical_cbcrs), + .dfs_rcgs = gcc_dfs_clocks, + .num_dfs_rcgs = ARRAY_SIZE(gcc_dfs_clocks), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc gcc_kaanapali_desc = { + .config = &gcc_kaanapali_regmap_config, + .clks = gcc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gcc_kaanapali_clocks), + .resets = gcc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gcc_kaanapali_resets), + .gdscs = gcc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_kaanapali_gdscs), + .driver_data = &gcc_kaanapali_driver_data, +}; + +static const struct of_device_id gcc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gcc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gcc_kaanapali_match_table); + +static int gcc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gcc_kaanapali_desc); +} + +static struct platform_driver gcc_kaanapali_driver = { + .probe = gcc_kaanapali_probe, + .driver = { + .name = "gcc-kaanapali", + .of_match_table = gcc_kaanapali_match_table, + }, +}; + +static int __init gcc_kaanapali_init(void) +{ + return platform_driver_register(&gcc_kaanapali_driver); +} +subsys_initcall(gcc_kaanapali_init); + +static void __exit gcc_kaanapali_exit(void) +{ + platform_driver_unregister(&gcc_kaanapali_driver); +} +module_exit(gcc_kaanapali_exit); + +MODULE_DESCRIPTION("QTI GCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gcc-milos.c b/drivers/clk/qcom/gcc-milos.c index c9d61b05bafa..81fa09ec55d7 100644 --- a/drivers/clk/qcom/gcc-milos.c +++ b/drivers/clk/qcom/gcc-milos.c @@ -917,7 +917,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -938,7 +938,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .name = "gcc_sdcc1_ice_core_clk_src", .parent_data = gcc_parent_data_10, .num_parents = ARRAY_SIZE(gcc_parent_data_10), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -962,7 +962,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-msm8917.c b/drivers/clk/qcom/gcc-msm8917.c index 0a1aa623cd49..2f561a950bc2 100644 --- a/drivers/clk/qcom/gcc-msm8917.c +++ b/drivers/clk/qcom/gcc-msm8917.c @@ -957,6 +957,48 @@ static const struct freq_tbl ftbl_gfx3d_clk_src_msm8937[] = { { } }; +static const struct freq_tbl ftbl_gfx3d_clk_src_msm8940[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(216000000, P_GPLL6, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(300000000, P_GPLL3, 1, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(375000000, P_GPLL3, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(450000000, P_GPLL3, 1, 0, 0), + F(475000000, P_GPLL3, 1, 0, 0), + F(500000000, P_GPLL3, 1, 0, 0), + { } +}; + +static const struct freq_tbl ftbl_gfx3d_clk_src_sdm439[] = { + F(19200000, P_XO, 1, 0, 0), + F(50000000, P_GPLL0, 16, 0, 0), + F(80000000, P_GPLL0, 10, 0, 0), + F(100000000, P_GPLL0, 8, 0, 0), + F(160000000, P_GPLL0, 5, 0, 0), + F(200000000, P_GPLL0, 4, 0, 0), + F(216000000, P_GPLL6, 5, 0, 0), + F(228570000, P_GPLL0, 3.5, 0, 0), + F(240000000, P_GPLL6, 4.5, 0, 0), + F(266670000, P_GPLL0, 3, 0, 0), + F(320000000, P_GPLL0, 2.5, 0, 0), + F(355200000, P_GPLL3, 1, 0, 0), + F(400000000, P_GPLL0, 2, 0, 0), + F(450000000, P_GPLL3, 1, 0, 0), + F(510000000, P_GPLL3, 1, 0, 0), + F(560000000, P_GPLL3, 1, 0, 0), + F(650000000, P_GPLL3, 1, 0, 0), + { } +}; + static struct clk_rcg2 gfx3d_clk_src = { .cmd_rcgr = 0x59000, .hid_width = 5, @@ -3307,6 +3349,19 @@ static struct clk_branch gcc_vfe_tbu_clk = { } }; +static struct clk_branch gcc_ipa_tbu_clk = { + .halt_reg = 0x120a0, + .halt_check = BRANCH_VOTED, + .clkr = { + .enable_reg = 0x4500c, + .enable_mask = BIT(16), + .hw.init = &(struct clk_init_data){ + .name = "gcc_ipa_tbu_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + static struct gdsc venus_gdsc = { .gdscr = 0x4c018, .cxcs = (unsigned int []){ 0x4c024, 0x4c01c }, @@ -3409,7 +3464,6 @@ static struct gdsc cpp_gdsc = { .pd = { .name = "cpp_gdsc", }, - .flags = ALWAYS_ON, .pwrsts = PWRSTS_OFF_ON, }; @@ -3764,12 +3818,196 @@ static struct clk_regmap *gcc_msm8937_clocks[] = { [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, }; +static struct clk_regmap *gcc_msm8940_clocks[] = { + [GPLL0] = &gpll0.clkr, + [GPLL0_EARLY] = &gpll0_early.clkr, + [GPLL0_SLEEP_CLK_SRC] = &gpll0_sleep_clk_src.clkr, + [GPLL3] = &gpll3.clkr, + [GPLL3_EARLY] = &gpll3_early.clkr, + [GPLL4] = &gpll4.clkr, + [GPLL4_EARLY] = &gpll4_early.clkr, + [GPLL6] = &gpll6, + [GPLL6_EARLY] = &gpll6_early.clkr, + [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr, + [MSM8937_BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr, + [MSM8937_BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr, + [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr, + [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr, + [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr, + [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr, + [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr, + [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr, + [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr, + [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr, + [BLSP2_QUP1_I2C_APPS_CLK_SRC] = &blsp2_qup1_i2c_apps_clk_src.clkr, + [BLSP2_QUP1_SPI_APPS_CLK_SRC] = &blsp2_qup1_spi_apps_clk_src.clkr, + [BLSP2_QUP2_I2C_APPS_CLK_SRC] = &blsp2_qup2_i2c_apps_clk_src.clkr, + [BLSP2_QUP2_SPI_APPS_CLK_SRC] = &blsp2_qup2_spi_apps_clk_src.clkr, + [BLSP2_QUP3_I2C_APPS_CLK_SRC] = &blsp2_qup3_i2c_apps_clk_src.clkr, + [BLSP2_QUP3_SPI_APPS_CLK_SRC] = &blsp2_qup3_spi_apps_clk_src.clkr, + [MSM8937_BLSP2_QUP4_I2C_APPS_CLK_SRC] = &blsp2_qup4_i2c_apps_clk_src.clkr, + [MSM8937_BLSP2_QUP4_SPI_APPS_CLK_SRC] = &blsp2_qup4_spi_apps_clk_src.clkr, + [BLSP2_UART1_APPS_CLK_SRC] = &blsp2_uart1_apps_clk_src.clkr, + [BLSP2_UART2_APPS_CLK_SRC] = &blsp2_uart2_apps_clk_src.clkr, + [BYTE0_CLK_SRC] = &byte0_clk_src.clkr, + [MSM8937_BYTE1_CLK_SRC] = &byte1_clk_src.clkr, + [CAMSS_GP0_CLK_SRC] = &camss_gp0_clk_src.clkr, + [CAMSS_GP1_CLK_SRC] = &camss_gp1_clk_src.clkr, + [CAMSS_TOP_AHB_CLK_SRC] = &camss_top_ahb_clk_src.clkr, + [CCI_CLK_SRC] = &cci_clk_src.clkr, + [CPP_CLK_SRC] = &cpp_clk_src.clkr, + [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr, + [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr, + [CSI0_CLK_SRC] = &csi0_clk_src.clkr, + [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr, + [CSI1_CLK_SRC] = &csi1_clk_src.clkr, + [CSI2_CLK_SRC] = &csi2_clk_src.clkr, + [ESC0_CLK_SRC] = &esc0_clk_src.clkr, + [MSM8937_ESC1_CLK_SRC] = &esc1_clk_src.clkr, + [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr, + [GP1_CLK_SRC] = &gp1_clk_src.clkr, + [GP2_CLK_SRC] = &gp2_clk_src.clkr, + [GP3_CLK_SRC] = &gp3_clk_src.clkr, + [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr, + [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr, + [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr, + [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr, + [MDP_CLK_SRC] = &mdp_clk_src.clkr, + [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr, + [MSM8937_PCLK1_CLK_SRC] = &pclk1_clk_src.clkr, + [PDM2_CLK_SRC] = &pdm2_clk_src.clkr, + [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr, + [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr, + [SDCC2_APPS_CLK_SRC] = &sdcc2_apps_clk_src.clkr, + [USB_HS_SYSTEM_CLK_SRC] = &usb_hs_system_clk_src.clkr, + [VCODEC0_CLK_SRC] = &vcodec0_clk_src.clkr, + [VFE0_CLK_SRC] = &vfe0_clk_src.clkr, + [VFE1_CLK_SRC] = &vfe1_clk_src.clkr, + [VSYNC_CLK_SRC] = &vsync_clk_src.clkr, + [GCC_APSS_TCU_CLK] = &gcc_apss_tcu_clk.clkr, + [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr, + [GCC_BIMC_GPU_CLK] = &gcc_bimc_gpu_clk.clkr, + [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr, + [MSM8937_GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr, + [MSM8937_GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr, + [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr, + [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr, + [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr, + [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr, + [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr, + [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr, + [GCC_BLSP2_AHB_CLK] = &gcc_blsp2_ahb_clk.clkr, + [GCC_BLSP2_QUP1_I2C_APPS_CLK] = &gcc_blsp2_qup1_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP1_SPI_APPS_CLK] = &gcc_blsp2_qup1_spi_apps_clk.clkr, + [GCC_BLSP2_QUP2_I2C_APPS_CLK] = &gcc_blsp2_qup2_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP2_SPI_APPS_CLK] = &gcc_blsp2_qup2_spi_apps_clk.clkr, + [GCC_BLSP2_QUP3_I2C_APPS_CLK] = &gcc_blsp2_qup3_i2c_apps_clk.clkr, + [GCC_BLSP2_QUP3_SPI_APPS_CLK] = &gcc_blsp2_qup3_spi_apps_clk.clkr, + [MSM8937_GCC_BLSP2_QUP4_I2C_APPS_CLK] = &gcc_blsp2_qup4_i2c_apps_clk.clkr, + [MSM8937_GCC_BLSP2_QUP4_SPI_APPS_CLK] = &gcc_blsp2_qup4_spi_apps_clk.clkr, + [GCC_BLSP2_UART1_APPS_CLK] = &gcc_blsp2_uart1_apps_clk.clkr, + [GCC_BLSP2_UART2_APPS_CLK] = &gcc_blsp2_uart2_apps_clk.clkr, + [GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr, + [GCC_CAMSS_AHB_CLK] = &gcc_camss_ahb_clk.clkr, + [GCC_CAMSS_CCI_AHB_CLK] = &gcc_camss_cci_ahb_clk.clkr, + [GCC_CAMSS_CCI_CLK] = &gcc_camss_cci_clk.clkr, + [GCC_CAMSS_CPP_AHB_CLK] = &gcc_camss_cpp_ahb_clk.clkr, + [GCC_CAMSS_CPP_CLK] = &gcc_camss_cpp_clk.clkr, + [GCC_CAMSS_CSI0PHYTIMER_CLK] = &gcc_camss_csi0phytimer_clk.clkr, + [GCC_CAMSS_CSI0PHY_CLK] = &gcc_camss_csi0phy_clk.clkr, + [GCC_CAMSS_CSI0PIX_CLK] = &gcc_camss_csi0pix_clk.clkr, + [GCC_CAMSS_CSI0RDI_CLK] = &gcc_camss_csi0rdi_clk.clkr, + [GCC_CAMSS_CSI0_AHB_CLK] = &gcc_camss_csi0_ahb_clk.clkr, + [GCC_CAMSS_CSI0_CLK] = &gcc_camss_csi0_clk.clkr, + [GCC_CAMSS_CSI1PHYTIMER_CLK] = &gcc_camss_csi1phytimer_clk.clkr, + [GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr, + [GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr, + [GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr, + [GCC_CAMSS_CSI1_AHB_CLK] = &gcc_camss_csi1_ahb_clk.clkr, + [GCC_CAMSS_CSI1_CLK] = &gcc_camss_csi1_clk.clkr, + [GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr, + [GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr, + [GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr, + [GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr, + [GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr, + [GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr, + [GCC_CAMSS_CSI_VFE1_CLK] = &gcc_camss_csi_vfe1_clk.clkr, + [GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr, + [GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr, + [GCC_CAMSS_ISPIF_AHB_CLK] = &gcc_camss_ispif_ahb_clk.clkr, + [GCC_CAMSS_JPEG0_CLK] = &gcc_camss_jpeg0_clk.clkr, + [GCC_CAMSS_JPEG_AHB_CLK] = &gcc_camss_jpeg_ahb_clk.clkr, + [GCC_CAMSS_JPEG_AXI_CLK] = &gcc_camss_jpeg_axi_clk.clkr, + [GCC_CAMSS_MCLK0_CLK] = &gcc_camss_mclk0_clk.clkr, + [GCC_CAMSS_MCLK1_CLK] = &gcc_camss_mclk1_clk.clkr, + [GCC_CAMSS_MCLK2_CLK] = &gcc_camss_mclk2_clk.clkr, + [GCC_CAMSS_MICRO_AHB_CLK] = &gcc_camss_micro_ahb_clk.clkr, + [GCC_CAMSS_TOP_AHB_CLK] = &gcc_camss_top_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AHB_CLK] = &gcc_camss_vfe0_ahb_clk.clkr, + [GCC_CAMSS_VFE0_AXI_CLK] = &gcc_camss_vfe0_axi_clk.clkr, + [GCC_CAMSS_VFE0_CLK] = &gcc_camss_vfe0_clk.clkr, + [GCC_CAMSS_VFE1_AHB_CLK] = &gcc_camss_vfe1_ahb_clk.clkr, + [GCC_CAMSS_VFE1_AXI_CLK] = &gcc_camss_vfe1_axi_clk.clkr, + [GCC_CAMSS_VFE1_CLK] = &gcc_camss_vfe1_clk.clkr, + [GCC_CPP_TBU_CLK] = &gcc_cpp_tbu_clk.clkr, + [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr, + [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr, + [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr, + [GCC_DCC_CLK] = &gcc_dcc_clk.clkr, + [GCC_GP1_CLK] = &gcc_gp1_clk.clkr, + [GCC_GP2_CLK] = &gcc_gp2_clk.clkr, + [GCC_GP3_CLK] = &gcc_gp3_clk.clkr, + [GCC_JPEG_TBU_CLK] = &gcc_jpeg_tbu_clk.clkr, + [GCC_MDP_TBU_CLK] = &gcc_mdp_tbu_clk.clkr, + [GCC_MDSS_AHB_CLK] = &gcc_mdss_ahb_clk.clkr, + [GCC_MDSS_AXI_CLK] = &gcc_mdss_axi_clk.clkr, + [GCC_MDSS_BYTE0_CLK] = &gcc_mdss_byte0_clk.clkr, + [MSM8937_GCC_MDSS_BYTE1_CLK] = &gcc_mdss_byte1_clk.clkr, + [GCC_MDSS_ESC0_CLK] = &gcc_mdss_esc0_clk.clkr, + [MSM8937_GCC_MDSS_ESC1_CLK] = &gcc_mdss_esc1_clk.clkr, + [GCC_MDSS_MDP_CLK] = &gcc_mdss_mdp_clk.clkr, + [GCC_MDSS_PCLK0_CLK] = &gcc_mdss_pclk0_clk.clkr, + [MSM8937_GCC_MDSS_PCLK1_CLK] = &gcc_mdss_pclk1_clk.clkr, + [GCC_MDSS_VSYNC_CLK] = &gcc_mdss_vsync_clk.clkr, + [GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr, + [GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr, + [GCC_OXILI_AHB_CLK] = &gcc_oxili_ahb_clk.clkr, + [MSM8937_GCC_OXILI_AON_CLK] = &gcc_oxili_aon_clk.clkr, + [GCC_OXILI_GFX3D_CLK] = &gcc_oxili_gfx3d_clk.clkr, + [MSM8937_GCC_OXILI_TIMER_CLK] = &gcc_oxili_timer_clk.clkr, + [GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr, + [GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr, + [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr, + [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr, + [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr, + [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr, + [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr, + [GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr, + [GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr, + [GCC_SMMU_CFG_CLK] = &gcc_smmu_cfg_clk.clkr, + [GCC_USB2A_PHY_SLEEP_CLK] = &gcc_usb2a_phy_sleep_clk.clkr, + [GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr, + [GCC_USB_HS_PHY_CFG_AHB_CLK] = &gcc_usb_hs_phy_cfg_ahb_clk.clkr, + [GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr, + [GCC_VENUS0_AHB_CLK] = &gcc_venus0_ahb_clk.clkr, + [GCC_VENUS0_AXI_CLK] = &gcc_venus0_axi_clk.clkr, + [GCC_VENUS0_CORE0_VCODEC0_CLK] = &gcc_venus0_core0_vcodec0_clk.clkr, + [GCC_VENUS0_VCODEC0_CLK] = &gcc_venus0_vcodec0_clk.clkr, + [GCC_VENUS_TBU_CLK] = &gcc_venus_tbu_clk.clkr, + [GCC_VFE1_TBU_CLK] = &gcc_vfe1_tbu_clk.clkr, + [GCC_VFE_TBU_CLK] = &gcc_vfe_tbu_clk.clkr, + [MSM8940_GCC_IPA_TBU_CLK] = &gcc_ipa_tbu_clk.clkr, +}; + static const struct qcom_reset_map gcc_msm8917_resets[] = { [GCC_CAMSS_MICRO_BCR] = { 0x56008 }, [GCC_MSS_BCR] = { 0x71000 }, [GCC_QUSB2_PHY_BCR] = { 0x4103c }, [GCC_USB_HS_BCR] = { 0x41000 }, [GCC_USB2_HS_PHY_ONLY_BCR] = { 0x41034 }, + [GCC_MDSS_BCR] = { 0x4d074 }, }; static const struct regmap_config gcc_msm8917_regmap_config = { @@ -3833,6 +4071,26 @@ static const struct qcom_cc_desc gcc_msm8937_desc = { .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), }; +static const struct qcom_cc_desc gcc_msm8940_desc = { + .config = &gcc_msm8917_regmap_config, + .clks = gcc_msm8940_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8940_clocks), + .resets = gcc_msm8917_resets, + .num_resets = ARRAY_SIZE(gcc_msm8917_resets), + .gdscs = gcc_msm8937_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), +}; + +static const struct qcom_cc_desc gcc_sdm439_desc = { + .config = &gcc_msm8917_regmap_config, + .clks = gcc_msm8937_clocks, + .num_clks = ARRAY_SIZE(gcc_msm8937_clocks), + .resets = gcc_msm8917_resets, + .num_resets = ARRAY_SIZE(gcc_msm8917_resets), + .gdscs = gcc_msm8937_gdscs, + .num_gdscs = ARRAY_SIZE(gcc_msm8937_gdscs), +}; + static void msm8937_clock_override(void) { /* GPLL3 750MHz configuration */ @@ -3858,6 +4116,21 @@ static void msm8937_clock_override(void) usb_hs_system_clk_src.freq_tbl = ftbl_usb_hs_system_clk_src_msm8937; } +static void sdm439_clock_override(void) +{ + vcodec0_clk_src.parent_map = gcc_cpp_map; + vcodec0_clk_src.clkr.hw.init = &vcodec0_clk_src_init_msm8937; + + vfe0_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + vfe1_clk_src.freq_tbl = ftbl_vfe_clk_src_msm8937; + cpp_clk_src.freq_tbl = ftbl_cpp_clk_src_msm8937; + vcodec0_clk_src.freq_tbl = ftbl_vcodec0_clk_src_msm8937; + gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_sdm439; + csi0phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + csi1phytimer_clk_src.freq_tbl = ftbl_csi_phytimer_clk_src_msm8937; + usb_hs_system_clk_src.freq_tbl = ftbl_usb_hs_system_clk_src_msm8937; +} + static int gcc_msm8917_probe(struct platform_device *pdev) { struct regmap *regmap; @@ -3870,6 +4143,11 @@ static int gcc_msm8917_probe(struct platform_device *pdev) } else if (gcc_desc == &gcc_msm8937_desc) { msm8937_clock_override(); gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8937; + } else if (gcc_desc == &gcc_msm8940_desc) { + msm8937_clock_override(); + gfx3d_clk_src.freq_tbl = ftbl_gfx3d_clk_src_msm8940; + } else if (gcc_desc == &gcc_sdm439_desc) { + sdm439_clock_override(); } regmap = qcom_cc_map(pdev, gcc_desc); @@ -3885,6 +4163,8 @@ static const struct of_device_id gcc_msm8917_match_table[] = { { .compatible = "qcom,gcc-msm8917", .data = &gcc_msm8917_desc }, { .compatible = "qcom,gcc-qm215", .data = &gcc_qm215_desc }, { .compatible = "qcom,gcc-msm8937", .data = &gcc_msm8937_desc }, + { .compatible = "qcom,gcc-msm8940", .data = &gcc_msm8940_desc }, + { .compatible = "qcom,gcc-sdm439", .data = &gcc_sdm439_desc }, {}, }; MODULE_DEVICE_TABLE(of, gcc_msm8917_match_table); diff --git a/drivers/clk/qcom/gcc-msm8953.c b/drivers/clk/qcom/gcc-msm8953.c index 8f29ecc74c50..8fe1d3e42144 100644 --- a/drivers/clk/qcom/gcc-msm8953.c +++ b/drivers/clk/qcom/gcc-msm8953.c @@ -3946,7 +3946,6 @@ static struct gdsc cpp_gdsc = { .pd = { .name = "cpp_gdsc", }, - .flags = ALWAYS_ON, .pwrsts = PWRSTS_OFF_ON, }; diff --git a/drivers/clk/qcom/gcc-qdu1000.c b/drivers/clk/qcom/gcc-qdu1000.c index dbe9e9437939..915bb9b4ff81 100644 --- a/drivers/clk/qcom/gcc-qdu1000.c +++ b/drivers/clk/qcom/gcc-qdu1000.c @@ -904,7 +904,7 @@ static struct clk_rcg2 gcc_sdcc5_apps_clk_src = { .name = "gcc_sdcc5_apps_clk_src", .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -923,7 +923,7 @@ static struct clk_rcg2 gcc_sdcc5_ice_core_clk_src = { .name = "gcc_sdcc5_ice_core_clk_src", .parent_data = gcc_parent_data_2, .num_parents = ARRAY_SIZE(gcc_parent_data_2), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sdx75.c b/drivers/clk/qcom/gcc-sdx75.c index 453a6bf8e878..1f3cd58483a2 100644 --- a/drivers/clk/qcom/gcc-sdx75.c +++ b/drivers/clk/qcom/gcc-sdx75.c @@ -1033,7 +1033,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .name = "gcc_sdcc1_apps_clk_src", .parent_data = gcc_parent_data_17, .num_parents = ARRAY_SIZE(gcc_parent_data_17), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1057,7 +1057,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .name = "gcc_sdcc2_apps_clk_src", .parent_data = gcc_parent_data_18, .num_parents = ARRAY_SIZE(gcc_parent_data_18), - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm4450.c b/drivers/clk/qcom/gcc-sm4450.c index e2d9e4691c5b..023d840e9f4e 100644 --- a/drivers/clk/qcom/gcc-sm4450.c +++ b/drivers/clk/qcom/gcc-sm4450.c @@ -769,7 +769,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -791,7 +791,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { .parent_data = gcc_parent_data_4, .num_parents = ARRAY_SIZE(gcc_parent_data_4), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -815,7 +815,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_6, .num_parents = ARRAY_SIZE(gcc_parent_data_6), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8450.c b/drivers/clk/qcom/gcc-sm8450.c index 65d7d52bce03..b18bb34889ab 100644 --- a/drivers/clk/qcom/gcc-sm8450.c +++ b/drivers/clk/qcom/gcc-sm8450.c @@ -1034,7 +1034,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_7, .num_parents = ARRAY_SIZE(gcc_parent_data_7), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1057,7 +1057,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8550.c b/drivers/clk/qcom/gcc-sm8550.c index 862a9bf73bcb..36a5b7de5b55 100644 --- a/drivers/clk/qcom/gcc-sm8550.c +++ b/drivers/clk/qcom/gcc-sm8550.c @@ -1025,7 +1025,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1048,7 +1048,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8650.c b/drivers/clk/qcom/gcc-sm8650.c index 24f98062b9dd..2dd6444ce036 100644 --- a/drivers/clk/qcom/gcc-sm8650.c +++ b/drivers/clk/qcom/gcc-sm8650.c @@ -1257,7 +1257,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_11, .num_parents = ARRAY_SIZE(gcc_parent_data_11), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1279,7 +1279,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_shared_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c index def86b71a3da..db81569dd4b1 100644 --- a/drivers/clk/qcom/gcc-sm8750.c +++ b/drivers/clk/qcom/gcc-sm8750.c @@ -1030,7 +1030,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_8, .num_parents = ARRAY_SIZE(gcc_parent_data_8), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1052,7 +1052,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c index b63c8abdd2fc..74afd12c158c 100644 --- a/drivers/clk/qcom/gcc-x1e80100.c +++ b/drivers/clk/qcom/gcc-x1e80100.c @@ -59,6 +59,9 @@ enum { DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + DT_UFS_PHY_RX_SYMBOL_0_CLK, + DT_UFS_PHY_RX_SYMBOL_1_CLK, + DT_UFS_PHY_TX_SYMBOL_0_CLK, }; enum { @@ -103,6 +106,9 @@ enum { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + P_UFS_PHY_RX_SYMBOL_0_CLK, + P_UFS_PHY_RX_SYMBOL_1_CLK, + P_UFS_PHY_TX_SYMBOL_0_CLK, }; static struct clk_alpha_pll gcc_gpll0 = { @@ -482,6 +488,48 @@ static const struct clk_parent_data gcc_parent_data_33[] = { { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, }; +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_0_clk_src = { + .reg = 0x77064, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_RX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_rx_symbol_1_clk_src = { + .reg = 0x770e0, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_rx_symbol_1_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_RX_SYMBOL_1_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + +static struct clk_regmap_phy_mux gcc_ufs_phy_tx_symbol_0_clk_src = { + .reg = 0x77054, + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_ufs_phy_tx_symbol_0_clk_src", + .parent_data = &(const struct clk_parent_data) { + .index = DT_UFS_PHY_TX_SYMBOL_0_CLK, + }, + .num_parents = 1, + .ops = &clk_regmap_phy_mux_ops, + }, + }, +}; + static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { .reg = 0x9f06c, .clkr = { @@ -1516,7 +1564,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { .parent_data = gcc_parent_data_9, .num_parents = ARRAY_SIZE(gcc_parent_data_9), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -1538,7 +1586,7 @@ static struct clk_rcg2 gcc_sdcc4_apps_clk_src = { .parent_data = gcc_parent_data_0, .num_parents = ARRAY_SIZE(gcc_parent_data_0), .flags = CLK_SET_RATE_PARENT, - .ops = &clk_rcg2_floor_ops, + .ops = &clk_rcg2_shared_floor_ops, }, }; @@ -5148,12 +5196,17 @@ static struct clk_branch gcc_ufs_phy_phy_aux_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { .halt_reg = 0x7702c, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x7702c, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5161,12 +5214,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = { static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { .halt_reg = 0x770cc, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x770cc, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_rx_symbol_1_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_rx_symbol_1_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -5174,12 +5232,17 @@ static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = { static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = { .halt_reg = 0x77028, - .halt_check = BRANCH_HALT, + .halt_check = BRANCH_HALT_DELAY, .clkr = { .enable_reg = 0x77028, .enable_mask = BIT(0), .hw.init = &(const struct clk_init_data) { .name = "gcc_ufs_phy_tx_symbol_0_clk", + .parent_hws = (const struct clk_hw*[]) { + &gcc_ufs_phy_tx_symbol_0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, .ops = &clk_branch2_ops, }, }, @@ -7180,6 +7243,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { [GCC_USB4_2_TMU_CLK_SRC] = &gcc_usb4_2_tmu_clk_src.clkr, [GCC_VIDEO_AXI0_CLK] = &gcc_video_axi0_clk.clkr, [GCC_VIDEO_AXI1_CLK] = &gcc_video_axi1_clk.clkr, + [GCC_UFS_PHY_RX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_rx_symbol_0_clk_src.clkr, + [GCC_UFS_PHY_RX_SYMBOL_1_CLK_SRC] = &gcc_ufs_phy_rx_symbol_1_clk_src.clkr, + [GCC_UFS_PHY_TX_SYMBOL_0_CLK_SRC] = &gcc_ufs_phy_tx_symbol_0_clk_src.clkr, }; static struct gdsc *gcc_x1e80100_gdscs[] = { diff --git a/drivers/clk/qcom/gpucc-kaanapali.c b/drivers/clk/qcom/gpucc-kaanapali.c new file mode 100644 index 000000000000..52be48c15c67 --- /dev/null +++ b/drivers/clk/qcom/gpucc-kaanapali.c @@ -0,0 +1,482 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-pll.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +enum { + DT_BI_TCXO, + DT_GPLL0_OUT_MAIN, + DT_GPLL0_OUT_MAIN_DIV, +}; + +enum { + P_BI_TCXO, + P_GPLL0_OUT_MAIN, + P_GPLL0_OUT_MAIN_DIV, + P_GPU_CC_PLL0_OUT_EVEN, + P_GPU_CC_PLL0_OUT_MAIN, + P_GPU_CC_PLL0_OUT_ODD, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 950.0 MHz Configuration */ +static const struct alpha_pll_config gpu_cc_pll0_config = { + .l = 0x31, + .cal_l = 0x48, + .alpha = 0x7aaa, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000408, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll gpu_cc_pll0 = { + .offset = 0x0, + .config = &gpu_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct clk_div_table post_div_table_gpu_cc_pll0_out_even[] = { + { 0x1, 2 }, + { } +}; + +static struct clk_alpha_pll_postdiv gpu_cc_pll0_out_even = { + .offset = 0x0, + .post_div_shift = 10, + .post_div_table = post_div_table_gpu_cc_pll0_out_even, + .num_post_div = ARRAY_SIZE(post_div_table_gpu_cc_pll0_out_even), + .width = 4, + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_pll0_out_even", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_pll0.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_alpha_pll_postdiv_taycan_eko_t_ops, + }, +}; + +static const struct parent_map gpu_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, + { P_GPU_CC_PLL0_OUT_MAIN, 1 }, + { P_GPU_CC_PLL0_OUT_EVEN, 2 }, + { P_GPU_CC_PLL0_OUT_ODD, 3 }, + { P_GPLL0_OUT_MAIN, 5 }, + { P_GPLL0_OUT_MAIN_DIV, 6 }, +}; + +static const struct clk_parent_data gpu_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .hw = &gpu_cc_pll0_out_even.clkr.hw }, + { .hw = &gpu_cc_pll0.clkr.hw }, + { .index = DT_GPLL0_OUT_MAIN }, + { .index = DT_GPLL0_OUT_MAIN_DIV }, +}; + +static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + F(475000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(575000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(700000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(725000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + F(750000000, P_GPU_CC_PLL0_OUT_EVEN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_gmu_clk_src = { + .cmd_rcgr = 0x9318, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_gpu_cc_gmu_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gmu_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_gpu_cc_hub_clk_src[] = { + F(150000000, P_GPLL0_OUT_MAIN_DIV, 2, 0, 0), + F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0), + F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0), + F(400000000, P_GPLL0_OUT_MAIN, 1.5, 0, 0), + { } +}; + +static struct clk_rcg2 gpu_cc_hub_clk_src = { + .cmd_rcgr = 0x93f0, + .mnd_width = 0, + .hid_width = 5, + .parent_map = gpu_cc_parent_map_0, + .hw_clk_ctrl = true, + .freq_tbl = ftbl_gpu_cc_hub_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_clk_src", + .parent_data = gpu_cc_parent_data_0, + .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_regmap_div gpu_cc_hub_div_clk_src = { + .reg = 0x9430, + .shift = 0, + .width = 4, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_div_clk_src", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_regmap_div_ro_ops, + }, +}; + +static struct clk_branch gpu_cc_ahb_clk = { + .halt_reg = 0x90bc, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x90bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_ahb_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_div_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_accu_shift_clk = { + .halt_reg = 0x9104, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9104, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cx_gmu_clk = { + .halt_reg = 0x90d4, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90d4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_cxo_clk = { + .halt_reg = 0x90e4, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x90e4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_cxo_clk", + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_demet_clk = { + .halt_reg = 0x9010, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9010, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_demet_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_dpm_clk = { + .halt_reg = 0x9108, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_dpm_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_freq_measure_clk = { + .halt_reg = 0x900c, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x900c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_freq_measure_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gpu_smmu_vote_clk = { + .halt_reg = 0x7000, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x7000, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gpu_smmu_vote_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_accu_shift_clk = { + .halt_reg = 0x9070, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x9070, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_accu_shift_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_gx_gmu_clk = { + .halt_reg = 0x9060, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x9060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_gx_gmu_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_gmu_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_aon_clk = { + .halt_reg = 0x93ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x93ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_aon_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_hub_cx_int_clk = { + .halt_reg = 0x90e8, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90e8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_hub_cx_int_clk", + .parent_hws = (const struct clk_hw*[]) { + &gpu_cc_hub_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_aon_ops, + }, + }, +}; + +static struct clk_branch gpu_cc_memnoc_gfx_clk = { + .halt_reg = 0x90ec, + .halt_check = BRANCH_HALT_VOTED, + .clkr = { + .enable_reg = 0x90ec, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gpu_cc_memnoc_gfx_clk", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc gpu_cc_cx_gdsc = { + .gdscr = 0x9080, + .gds_hw_ctrl = 0x9094, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x8, + .pd = { + .name = "gpu_cc_cx_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *gpu_cc_kaanapali_clocks[] = { + [GPU_CC_AHB_CLK] = &gpu_cc_ahb_clk.clkr, + [GPU_CC_CX_ACCU_SHIFT_CLK] = &gpu_cc_cx_accu_shift_clk.clkr, + [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr, + [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr, + [GPU_CC_DEMET_CLK] = &gpu_cc_demet_clk.clkr, + [GPU_CC_DPM_CLK] = &gpu_cc_dpm_clk.clkr, + [GPU_CC_FREQ_MEASURE_CLK] = &gpu_cc_freq_measure_clk.clkr, + [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr, + [GPU_CC_GPU_SMMU_VOTE_CLK] = &gpu_cc_gpu_smmu_vote_clk.clkr, + [GPU_CC_GX_ACCU_SHIFT_CLK] = &gpu_cc_gx_accu_shift_clk.clkr, + [GPU_CC_GX_GMU_CLK] = &gpu_cc_gx_gmu_clk.clkr, + [GPU_CC_HUB_AON_CLK] = &gpu_cc_hub_aon_clk.clkr, + [GPU_CC_HUB_CLK_SRC] = &gpu_cc_hub_clk_src.clkr, + [GPU_CC_HUB_CX_INT_CLK] = &gpu_cc_hub_cx_int_clk.clkr, + [GPU_CC_HUB_DIV_CLK_SRC] = &gpu_cc_hub_div_clk_src.clkr, + [GPU_CC_MEMNOC_GFX_CLK] = &gpu_cc_memnoc_gfx_clk.clkr, + [GPU_CC_PLL0] = &gpu_cc_pll0.clkr, + [GPU_CC_PLL0_OUT_EVEN] = &gpu_cc_pll0_out_even.clkr, +}; + +static struct gdsc *gpu_cc_kaanapali_gdscs[] = { + [GPU_CC_CX_GDSC] = &gpu_cc_cx_gdsc, +}; + +static const struct qcom_reset_map gpu_cc_kaanapali_resets[] = { + [GPU_CC_CB_BCR] = { 0x93a0 }, + [GPU_CC_CX_BCR] = { 0x907c }, + [GPU_CC_FAST_HUB_BCR] = { 0x93e4 }, + [GPU_CC_FF_BCR] = { 0x9470 }, + [GPU_CC_GMU_BCR] = { 0x9314 }, + [GPU_CC_GX_BCR] = { 0x905c }, + [GPU_CC_XO_BCR] = { 0x9000 }, +}; + +static struct clk_alpha_pll *gpu_cc_kaanapali_plls[] = { + &gpu_cc_pll0, +}; + +static u32 gpu_cc_kaanapali_critical_cbcrs[] = { + 0x9008, /* GPU_CC_CXO_AON_CLK */ + 0x93e8, /* GPU_CC_RSCC_HUB_AON_CLK */ + 0x9004, /* GPU_CC_RSCC_XO_AON_CLK */ +}; + +static const struct regmap_config gpu_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x95e8, + .fast_io = true, +}; + +static struct qcom_cc_driver_data gpu_cc_kaanapali_driver_data = { + .alpha_plls = gpu_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(gpu_cc_kaanapali_plls), + .clk_cbcrs = gpu_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(gpu_cc_kaanapali_critical_cbcrs), +}; + +static const struct qcom_cc_desc gpu_cc_kaanapali_desc = { + .config = &gpu_cc_kaanapali_regmap_config, + .clks = gpu_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(gpu_cc_kaanapali_clocks), + .resets = gpu_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(gpu_cc_kaanapali_resets), + .gdscs = gpu_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(gpu_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &gpu_cc_kaanapali_driver_data, +}; + +static const struct of_device_id gpu_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gpucc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gpu_cc_kaanapali_match_table); + +static int gpu_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gpu_cc_kaanapali_desc); +} + +static struct platform_driver gpu_cc_kaanapali_driver = { + .probe = gpu_cc_kaanapali_probe, + .driver = { + .name = "gpucc-kaanapali", + .of_match_table = gpu_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(gpu_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GPUCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/gxclkctl-kaanapali.c b/drivers/clk/qcom/gxclkctl-kaanapali.c new file mode 100644 index 000000000000..c209ce5fe4f0 --- /dev/null +++ b/drivers/clk/qcom/gxclkctl-kaanapali.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "common.h" +#include "gdsc.h" + +enum { + DT_BI_TCXO, +}; + +static struct gdsc gx_clkctl_gx_gdsc = { + .gdscr = 0x4024, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "gx_clkctl_gx_gdsc", + .power_on = gdsc_gx_do_nothing_enable, + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc *gx_clkctl_gdscs[] = { + [GX_CLKCTL_GX_GDSC] = &gx_clkctl_gx_gdsc, +}; + +static const struct regmap_config gx_clkctl_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x4038, + .fast_io = true, +}; + +static const struct qcom_cc_desc gx_clkctl_kaanapali_desc = { + .config = &gx_clkctl_regmap_config, + .gdscs = gx_clkctl_gdscs, + .num_gdscs = ARRAY_SIZE(gx_clkctl_gdscs), + .use_rpm = true, +}; + +static const struct of_device_id gx_clkctl_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-gxclkctl" }, + { } +}; +MODULE_DEVICE_TABLE(of, gx_clkctl_kaanapali_match_table); + +static int gx_clkctl_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &gx_clkctl_kaanapali_desc); +} + +static struct platform_driver gx_clkctl_kaanapali_driver = { + .probe = gx_clkctl_kaanapali_probe, + .driver = { + .name = "gxclkctl-kaanapali", + .of_match_table = gx_clkctl_kaanapali_match_table, + }, +}; + +module_platform_driver(gx_clkctl_kaanapali_driver); + +MODULE_DESCRIPTION("QTI GXCLKCTL Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/tcsrcc-kaanapali.c b/drivers/clk/qcom/tcsrcc-kaanapali.c new file mode 100644 index 000000000000..4da77367c9e0 --- /dev/null +++ b/drivers/clk/qcom/tcsrcc-kaanapali.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-branch.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "clk-regmap-mux.h" +#include "common.h" + +enum { + DT_BI_TCXO_PAD, +}; + +static struct clk_branch tcsr_pcie_0_clkref_en = { + .halt_reg = 0x15044, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15044, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_0_clkref_en", + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb3_clkref_en = { + .halt_reg = 0x1504c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1504c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_ufs_clkref_en = { + .halt_reg = 0x15054, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x15054, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_ufs_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch tcsr_usb2_clkref_en = { + .halt_reg = 0x1505c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { + .enable_reg = 0x1505c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_clkref_en", + .parent_data = &(const struct clk_parent_data){ + .index = DT_BI_TCXO_PAD, + }, + .num_parents = 1, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_regmap *tcsr_cc_kaanapali_clocks[] = { + [TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr, + [TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr, + [TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr, + [TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr, +}; + +static const struct regmap_config tcsr_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x3d000, + .fast_io = true, +}; + +static const struct qcom_cc_desc tcsr_cc_kaanapali_desc = { + .config = &tcsr_cc_kaanapali_regmap_config, + .clks = tcsr_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(tcsr_cc_kaanapali_clocks), +}; + +static const struct of_device_id tcsr_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-tcsr" }, + { } +}; +MODULE_DEVICE_TABLE(of, tcsr_cc_kaanapali_match_table); + +static int tcsr_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &tcsr_cc_kaanapali_desc); +} + +static struct platform_driver tcsr_cc_kaanapali_driver = { + .probe = tcsr_cc_kaanapali_probe, + .driver = { + .name = "tcsr_cc-kaanapali", + .of_match_table = tcsr_cc_kaanapali_match_table, + }, +}; + +static int __init tcsr_cc_kaanapali_init(void) +{ + return platform_driver_register(&tcsr_cc_kaanapali_driver); +} +subsys_initcall(tcsr_cc_kaanapali_init); + +static void __exit tcsr_cc_kaanapali_exit(void) +{ + platform_driver_unregister(&tcsr_cc_kaanapali_driver); +} +module_exit(tcsr_cc_kaanapali_exit); + +MODULE_DESCRIPTION("QTI TCSR_CC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-kaanapali.c b/drivers/clk/qcom/videocc-kaanapali.c new file mode 100644 index 000000000000..835a59536ba7 --- /dev/null +++ b/drivers/clk/qcom/videocc-kaanapali.c @@ -0,0 +1,821 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include +#include +#include +#include +#include + +#include + +#include "clk-alpha-pll.h" +#include "clk-branch.h" +#include "clk-rcg.h" +#include "clk-regmap.h" +#include "clk-regmap-divider.h" +#include "common.h" +#include "gdsc.h" +#include "reset.h" + +#define ACCU_CFG_MASK GENMASK(25, 21) + +enum { + DT_BI_TCXO, + DT_AHB_CLK, +}; + +enum { + P_BI_TCXO, + P_VIDEO_CC_PLL0_OUT_MAIN, + P_VIDEO_CC_PLL1_OUT_MAIN, + P_VIDEO_CC_PLL2_OUT_MAIN, + P_VIDEO_CC_PLL3_OUT_MAIN, +}; + +static const struct pll_vco taycan_eko_t_vco[] = { + { 249600000, 2500000000, 0 }, +}; + +/* 360.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll0_config = { + .l = 0x12, + .cal_l = 0x48, + .alpha = 0xc000, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll0 = { + .offset = 0x0, + .config = &video_cc_pll0_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll0", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll1_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll1 = { + .offset = 0x1000, + .config = &video_cc_pll1_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll1", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll2_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll2 = { + .offset = 0x2000, + .config = &video_cc_pll2_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll2", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +/* 480.0 MHz Configuration */ +static const struct alpha_pll_config video_cc_pll3_config = { + .l = 0x19, + .cal_l = 0x48, + .alpha = 0x0, + .config_ctl_val = 0x25c400e7, + .config_ctl_hi_val = 0x0a8062e0, + .config_ctl_hi1_val = 0xf51dea20, + .user_ctl_val = 0x00000008, + .user_ctl_hi_val = 0x00000002, +}; + +static struct clk_alpha_pll video_cc_pll3 = { + .offset = 0x3000, + .config = &video_cc_pll3_config, + .vco_table = taycan_eko_t_vco, + .num_vco = ARRAY_SIZE(taycan_eko_t_vco), + .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_EKO_T], + .clkr = { + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_pll3", + .parent_data = &(const struct clk_parent_data) { + .index = DT_BI_TCXO, + }, + .num_parents = 1, + .ops = &clk_alpha_pll_taycan_eko_t_ops, + }, + }, +}; + +static const struct parent_map video_cc_parent_map_0[] = { + { P_BI_TCXO, 0 }, +}; + +static const struct clk_parent_data video_cc_parent_data_0[] = { + { .index = DT_BI_TCXO }, +}; + +static const struct parent_map video_cc_parent_map_1[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL1_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_1[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll1.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_2[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL3_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_2[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll3.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_3[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL2_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_3[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll2.clkr.hw }, +}; + +static const struct parent_map video_cc_parent_map_4[] = { + { P_BI_TCXO, 0 }, + { P_VIDEO_CC_PLL0_OUT_MAIN, 1 }, +}; + +static const struct clk_parent_data video_cc_parent_data_4[] = { + { .index = DT_BI_TCXO }, + { .hw = &video_cc_pll0.clkr.hw }, +}; + +static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = { + F(19200000, P_BI_TCXO, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_ahb_clk_src = { + .cmd_rcgr = 0x8060, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_ahb_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(800000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + F(1000000000, P_VIDEO_CC_PLL1_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0_clk_src = { + .cmd_rcgr = 0x8030, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_1, + .freq_tbl = ftbl_video_cc_mvs0_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk_src", + .parent_data = video_cc_parent_data_1, + .num_parents = ARRAY_SIZE(video_cc_parent_data_1), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0a_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL3_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0a_clk_src = { + .cmd_rcgr = 0x8000, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_2, + .freq_tbl = ftbl_video_cc_mvs0a_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk_src", + .parent_data = video_cc_parent_data_2, + .num_parents = ARRAY_SIZE(video_cc_parent_data_2), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0b_clk_src[] = { + F(240000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(338000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(420000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(444000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(533000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(630000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + F(850000000, P_VIDEO_CC_PLL2_OUT_MAIN, 2, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0b_clk_src = { + .cmd_rcgr = 0x8018, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_3, + .freq_tbl = ftbl_video_cc_mvs0b_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk_src", + .parent_data = video_cc_parent_data_3, + .num_parents = ARRAY_SIZE(video_cc_parent_data_3), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static const struct freq_tbl ftbl_video_cc_mvs0c_clk_src[] = { + F(360000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(507000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(630000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(666000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(800000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1104000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0), + { } +}; + +static struct clk_rcg2 video_cc_mvs0c_clk_src = { + .cmd_rcgr = 0x8048, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_4, + .freq_tbl = ftbl_video_cc_mvs0c_clk_src, + .hw_clk_ctrl = true, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk_src", + .parent_data = video_cc_parent_data_4, + .num_parents = ARRAY_SIZE(video_cc_parent_data_4), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_shared_ops, + }, +}; + +static struct clk_rcg2 video_cc_xo_clk_src = { + .cmd_rcgr = 0x8194, + .mnd_width = 0, + .hid_width = 5, + .parent_map = video_cc_parent_map_0, + .freq_tbl = ftbl_video_cc_ahb_clk_src, + .clkr.hw.init = &(const struct clk_init_data) { + .name = "video_cc_xo_clk_src", + .parent_data = video_cc_parent_data_0, + .num_parents = ARRAY_SIZE(video_cc_parent_data_0), + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_rcg2_ops, + }, +}; + +static struct clk_branch video_cc_mvs0_clk = { + .halt_reg = 0x80d0, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80d0, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80d0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_mem_branch video_cc_mvs0_freerun_clk = { + .mem_enable_reg = 0x80e4, + .mem_ack_reg = 0x80e4, + .mem_enable_mask = BIT(3), + .mem_enable_ack_mask = GENMASK(11, 10), + .mem_enable_invert = true, + .branch = { + .halt_reg = 0x80e0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80e0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_shift_clk = { + .halt_reg = 0x81b4, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b4, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b4, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_clk = { + .halt_reg = 0x8134, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8134, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8134, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp0_freerun_clk = { + .halt_reg = 0x8144, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8144, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp0_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp1_clk = { + .halt_reg = 0x8108, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8108, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0_vpp1_freerun_clk = { + .halt_reg = 0x8118, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8118, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0_vpp1_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_clk = { + .halt_reg = 0x8090, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8090, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8090, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0a_freerun_clk = { + .halt_reg = 0x80a0, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80a0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0a_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0a_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_clk = { + .halt_reg = 0x80bc, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x80bc, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x80bc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0b_freerun_clk = { + .halt_reg = 0x80cc, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x80cc, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0b_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0b_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_clk = { + .halt_reg = 0x8164, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x8164, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x8164, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_freerun_clk = { + .halt_reg = 0x8174, + .halt_check = BRANCH_HALT, + .clkr = { + .enable_reg = 0x8174, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_freerun_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_mvs0c_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct clk_branch video_cc_mvs0c_shift_clk = { + .halt_reg = 0x81b8, + .halt_check = BRANCH_HALT_VOTED, + .hwcg_reg = 0x81b8, + .hwcg_bit = 1, + .clkr = { + .enable_reg = 0x81b8, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "video_cc_mvs0c_shift_clk", + .parent_hws = (const struct clk_hw*[]) { + &video_cc_xo_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +}; + +static struct gdsc video_cc_mvs0_vpp0_gdsc = { + .gdscr = 0x8120, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_vpp1_gdsc = { + .gdscr = 0x80f4, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0_vpp1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0a_gdsc = { + .gdscr = 0x807c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0xf, + .pd = { + .name = "video_cc_mvs0a_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0c_gdsc = { + .gdscr = 0x814c, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0c_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct gdsc video_cc_mvs0_gdsc = { + .gdscr = 0x80a8, + .en_rest_wait_val = 0x2, + .en_few_wait_val = 0x2, + .clk_dis_wait_val = 0x6, + .pd = { + .name = "video_cc_mvs0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, + .parent = &video_cc_mvs0c_gdsc.pd, + .flags = HW_CTRL_TRIGGER | POLL_CFG_GDSCR | RETAIN_FF_ENABLE, +}; + +static struct clk_regmap *video_cc_kaanapali_clocks[] = { + [VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr, + [VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr, + [VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr, + [VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr, + [VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr, + [VIDEO_CC_MVS0_VPP0_CLK] = &video_cc_mvs0_vpp0_clk.clkr, + [VIDEO_CC_MVS0_VPP0_FREERUN_CLK] = &video_cc_mvs0_vpp0_freerun_clk.clkr, + [VIDEO_CC_MVS0_VPP1_CLK] = &video_cc_mvs0_vpp1_clk.clkr, + [VIDEO_CC_MVS0_VPP1_FREERUN_CLK] = &video_cc_mvs0_vpp1_freerun_clk.clkr, + [VIDEO_CC_MVS0A_CLK] = &video_cc_mvs0a_clk.clkr, + [VIDEO_CC_MVS0A_CLK_SRC] = &video_cc_mvs0a_clk_src.clkr, + [VIDEO_CC_MVS0A_FREERUN_CLK] = &video_cc_mvs0a_freerun_clk.clkr, + [VIDEO_CC_MVS0B_CLK] = &video_cc_mvs0b_clk.clkr, + [VIDEO_CC_MVS0B_CLK_SRC] = &video_cc_mvs0b_clk_src.clkr, + [VIDEO_CC_MVS0B_FREERUN_CLK] = &video_cc_mvs0b_freerun_clk.clkr, + [VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr, + [VIDEO_CC_MVS0C_CLK_SRC] = &video_cc_mvs0c_clk_src.clkr, + [VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr, + [VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr, + [VIDEO_CC_PLL0] = &video_cc_pll0.clkr, + [VIDEO_CC_PLL1] = &video_cc_pll1.clkr, + [VIDEO_CC_PLL2] = &video_cc_pll2.clkr, + [VIDEO_CC_PLL3] = &video_cc_pll3.clkr, + [VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr, +}; + +static struct gdsc *video_cc_kaanapali_gdscs[] = { + [VIDEO_CC_MVS0A_GDSC] = &video_cc_mvs0a_gdsc, + [VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc, + [VIDEO_CC_MVS0_VPP1_GDSC] = &video_cc_mvs0_vpp1_gdsc, + [VIDEO_CC_MVS0_VPP0_GDSC] = &video_cc_mvs0_vpp0_gdsc, + [VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc, +}; + +static const struct qcom_reset_map video_cc_kaanapali_resets[] = { + [VIDEO_CC_INTERFACE_BCR] = { 0x8178 }, + [VIDEO_CC_MVS0_BCR] = { 0x80a4 }, + [VIDEO_CC_MVS0_VPP0_BCR] = { 0x811c }, + [VIDEO_CC_MVS0_VPP1_BCR] = { 0x80f0 }, + [VIDEO_CC_MVS0A_BCR] = { 0x8078 }, + [VIDEO_CC_MVS0C_CLK_ARES] = { 0x8164, 2 }, + [VIDEO_CC_MVS0C_BCR] = { 0x8148 }, + [VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x80e0, 2 }, + [VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x8174, 2 }, + [VIDEO_CC_XO_CLK_ARES] = { 0x81ac, 2 }, +}; + +static struct clk_alpha_pll *video_cc_kaanapali_plls[] = { + &video_cc_pll0, + &video_cc_pll1, + &video_cc_pll2, + &video_cc_pll3, +}; + +static u32 video_cc_kaanapali_critical_cbcrs[] = { + 0x817c, /* VIDEO_CC_AHB_CLK */ + 0x81bc, /* VIDEO_CC_SLEEP_CLK */ + 0x81b0, /* VIDEO_CC_TS_XO_CLK */ + 0x81ac, /* VIDEO_CC_XO_CLK */ +}; + +static const struct regmap_config video_cc_kaanapali_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0xa010, + .fast_io = true, +}; + +static void clk_kaanapali_regs_configure(struct device *dev, struct regmap *regmap) +{ + /* + * Enable clk_on sync for MVS0 and VPP clocks via VIDEO_CC_SPARE1 + * during core reset by default. + */ + regmap_set_bits(regmap, 0x9f24, BIT(0)); + + /* + * As per HW design recommendation + * Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for the below GDSCs + * MVS0A CFG3, MVS0 CFG3, MVS0 VPP1 CFG3, MVS0 VPP0 CFG3, MVS0C CFG3 + */ + regmap_set_bits(regmap, 0x8088, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x80b4, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8100, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x812c, ACCU_CFG_MASK); + regmap_set_bits(regmap, 0x8158, ACCU_CFG_MASK); +} + +static struct qcom_cc_driver_data video_cc_kaanapali_driver_data = { + .alpha_plls = video_cc_kaanapali_plls, + .num_alpha_plls = ARRAY_SIZE(video_cc_kaanapali_plls), + .clk_cbcrs = video_cc_kaanapali_critical_cbcrs, + .num_clk_cbcrs = ARRAY_SIZE(video_cc_kaanapali_critical_cbcrs), + .clk_regs_configure = clk_kaanapali_regs_configure, +}; + +static const struct qcom_cc_desc video_cc_kaanapali_desc = { + .config = &video_cc_kaanapali_regmap_config, + .clks = video_cc_kaanapali_clocks, + .num_clks = ARRAY_SIZE(video_cc_kaanapali_clocks), + .resets = video_cc_kaanapali_resets, + .num_resets = ARRAY_SIZE(video_cc_kaanapali_resets), + .gdscs = video_cc_kaanapali_gdscs, + .num_gdscs = ARRAY_SIZE(video_cc_kaanapali_gdscs), + .use_rpm = true, + .driver_data = &video_cc_kaanapali_driver_data, +}; + +static const struct of_device_id video_cc_kaanapali_match_table[] = { + { .compatible = "qcom,kaanapali-videocc" }, + { } +}; +MODULE_DEVICE_TABLE(of, video_cc_kaanapali_match_table); + +static int video_cc_kaanapali_probe(struct platform_device *pdev) +{ + return qcom_cc_probe(pdev, &video_cc_kaanapali_desc); +} + +static struct platform_driver video_cc_kaanapali_driver = { + .probe = video_cc_kaanapali_probe, + .driver = { + .name = "videocc-kaanapali", + .of_match_table = video_cc_kaanapali_match_table, + }, +}; + +module_platform_driver(video_cc_kaanapali_driver); + +MODULE_DESCRIPTION("QTI VIDEOCC Kaanapali Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/qcom/videocc-sm8750.c b/drivers/clk/qcom/videocc-sm8750.c index 0acf3104d702..823aca2bdd34 100644 --- a/drivers/clk/qcom/videocc-sm8750.c +++ b/drivers/clk/qcom/videocc-sm8750.c @@ -416,7 +416,7 @@ static struct qcom_cc_driver_data video_cc_sm8750_driver_data = { .clk_regs_configure = clk_sm8750_regs_configure, }; -static struct qcom_cc_desc video_cc_sm8750_desc = { +static const struct qcom_cc_desc video_cc_sm8750_desc = { .config = &video_cc_sm8750_regmap_config, .clks = video_cc_sm8750_clocks, .num_clks = ARRAY_SIZE(video_cc_sm8750_clocks), diff --git a/drivers/clk/ralink/clk-mt7621.c b/drivers/clk/ralink/clk-mt7621.c index 92d14350c4b3..350c2b6fb46f 100644 --- a/drivers/clk/ralink/clk-mt7621.c +++ b/drivers/clk/ralink/clk-mt7621.c @@ -354,7 +354,7 @@ static void __init mt7621_clk_init(struct device_node *node) struct clk_hw_onecell_data *clk_data; int ret, i, count; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return; @@ -372,7 +372,7 @@ static void __init mt7621_clk_init(struct device_node *node) count = ARRAY_SIZE(mt7621_clks_base) + ARRAY_SIZE(mt7621_fixed_clks) + ARRAY_SIZE(mt7621_gates); - clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, count); if (!clk_data) goto free_clk_priv; diff --git a/drivers/clk/ralink/clk-mtmips.c b/drivers/clk/ralink/clk-mtmips.c index 19d433034884..370e5c36863d 100644 --- a/drivers/clk/ralink/clk-mtmips.c +++ b/drivers/clk/ralink/clk-mtmips.c @@ -916,7 +916,7 @@ static void __init mtmips_clk_init(struct device_node *node) struct clk_hw_onecell_data *clk_data; int ret, i, count; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return; @@ -936,7 +936,7 @@ static void __init mtmips_clk_init(struct device_node *node) priv->data = data; count = priv->data->num_clk_base + priv->data->num_clk_fixed + priv->data->num_clk_factor + priv->data->num_clk_periph; - clk_data = kzalloc(struct_size(clk_data, hws, count), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, count); if (!clk_data) goto free_clk_priv; diff --git a/drivers/clk/renesas/clk-div6.c b/drivers/clk/renesas/clk-div6.c index f7b827b5e9b2..c23489900e96 100644 --- a/drivers/clk/renesas/clk-div6.c +++ b/drivers/clk/renesas/clk-div6.c @@ -251,7 +251,7 @@ struct clk * __init cpg_div6_register(const char *name, struct clk *clk; unsigned int i; - clock = kzalloc(struct_size(clock, parents, num_parents), GFP_KERNEL); + clock = kzalloc_flex(*clock, parents, num_parents); if (!clock) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/renesas/clk-mstp.c b/drivers/clk/renesas/clk-mstp.c index 2f65fe2c6bdf..f57f2342847b 100644 --- a/drivers/clk/renesas/clk-mstp.c +++ b/drivers/clk/renesas/clk-mstp.c @@ -150,7 +150,7 @@ static struct clk * __init cpg_mstp_clock_register(const char *name, struct mstp_clock *clock; struct clk *clk; - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) return ERR_PTR(-ENOMEM); @@ -184,7 +184,7 @@ static void __init cpg_mstp_clocks_init(struct device_node *np) struct clk **clks; unsigned int i; - group = kzalloc(struct_size(group, clks, MSTP_MAX_CLOCKS), GFP_KERNEL); + group = kzalloc_flex(*group, clks, MSTP_MAX_CLOCKS); if (!group) return; @@ -316,7 +316,7 @@ void __init cpg_mstp_add_clk_domain(struct device_node *np) return; } - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return; diff --git a/drivers/clk/renesas/clk-r8a73a4.c b/drivers/clk/renesas/clk-r8a73a4.c index f331d8bc9daf..7f47644396e6 100644 --- a/drivers/clk/renesas/clk-r8a73a4.c +++ b/drivers/clk/renesas/clk-r8a73a4.c @@ -196,8 +196,8 @@ static void __init r8a73a4_cpg_clocks_init(struct device_node *np) return; } - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + cpg = kzalloc_obj(*cpg); + clks = kzalloc_objs(*clks, num_clks); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-r8a7740.c b/drivers/clk/renesas/clk-r8a7740.c index 22e9be7240bb..635d59ead499 100644 --- a/drivers/clk/renesas/clk-r8a7740.c +++ b/drivers/clk/renesas/clk-r8a7740.c @@ -155,8 +155,8 @@ static void __init r8a7740_cpg_clocks_init(struct device_node *np) return; } - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + cpg = kzalloc_obj(*cpg); + clks = kzalloc_objs(*clks, num_clks); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-r8a7778.c b/drivers/clk/renesas/clk-r8a7778.c index 6ea173f22251..9120f86fcc2a 100644 --- a/drivers/clk/renesas/clk-r8a7778.c +++ b/drivers/clk/renesas/clk-r8a7778.c @@ -92,8 +92,8 @@ static void __init r8a7778_cpg_clocks_init(struct device_node *np) return; } - data = kzalloc(sizeof(*data), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + data = kzalloc_obj(*data); + clks = kzalloc_objs(*clks, num_clks); if (data == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-r8a7779.c b/drivers/clk/renesas/clk-r8a7779.c index 9a2fea8cf4d7..f2d6cbaf6329 100644 --- a/drivers/clk/renesas/clk-r8a7779.c +++ b/drivers/clk/renesas/clk-r8a7779.c @@ -128,8 +128,8 @@ static void __init r8a7779_cpg_clocks_init(struct device_node *np) return; } - data = kzalloc(sizeof(*data), GFP_KERNEL); - clks = kcalloc(CPG_NUM_CLOCKS, sizeof(*clks), GFP_KERNEL); + data = kzalloc_obj(*data); + clks = kzalloc_objs(*clks, CPG_NUM_CLOCKS); if (data == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-rz.c b/drivers/clk/renesas/clk-rz.c index e770f09a27ed..5347c067e256 100644 --- a/drivers/clk/renesas/clk-rz.c +++ b/drivers/clk/renesas/clk-rz.c @@ -91,8 +91,8 @@ static void __init rz_cpg_clocks_init(struct device_node *np) if (WARN(num_clks <= 0, "can't count CPG clocks\n")) return; - data = kzalloc(sizeof(*data), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + data = kzalloc_obj(*data); + clks = kzalloc_objs(*clks, num_clks); BUG_ON(!data || !clks); data->clks = clks; diff --git a/drivers/clk/renesas/clk-sh73a0.c b/drivers/clk/renesas/clk-sh73a0.c index 47fc99ccd283..efae041ac6e8 100644 --- a/drivers/clk/renesas/clk-sh73a0.c +++ b/drivers/clk/renesas/clk-sh73a0.c @@ -170,8 +170,8 @@ static void __init sh73a0_cpg_clocks_init(struct device_node *np) return; } - cpg = kzalloc(sizeof(*cpg), GFP_KERNEL); - clks = kcalloc(num_clks, sizeof(*clks), GFP_KERNEL); + cpg = kzalloc_obj(*cpg); + clks = kzalloc_objs(*clks, num_clks); if (cpg == NULL || clks == NULL) { /* We're leaking memory on purpose, there's no point in cleaning * up as the system won't boot anyway. diff --git a/drivers/clk/renesas/clk-vbattb.c b/drivers/clk/renesas/clk-vbattb.c index ff9d1ead455c..2a961775b1d8 100644 --- a/drivers/clk/renesas/clk-vbattb.c +++ b/drivers/clk/renesas/clk-vbattb.c @@ -69,11 +69,11 @@ static void vbattb_clk_action(void *data) ret = reset_control_assert(rstc); if (ret) - dev_err(dev, "Failed to de-assert reset!"); + dev_err(dev, "Failed to de-assert reset!\n"); ret = pm_runtime_put_sync(dev); if (ret < 0) - dev_err(dev, "Failed to runtime suspend!"); + dev_err(dev, "Failed to runtime suspend!\n"); of_clk_del_provider(dev->of_node); } diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c index 0f5c91b5dfa9..7407a4183a6c 100644 --- a/drivers/clk/renesas/r9a06g032-clocks.c +++ b/drivers/clk/renesas/r9a06g032-clocks.c @@ -891,7 +891,7 @@ r9a06g032_register_gate(struct r9a06g032_priv *clocks, struct r9a06g032_clk_gate *g; struct clk_init_data init = {}; - g = kzalloc(sizeof(*g), GFP_KERNEL); + g = kzalloc_obj(*g); if (!g) return NULL; @@ -1063,7 +1063,7 @@ r9a06g032_register_div(struct r9a06g032_priv *clocks, struct clk_init_data init = {}; unsigned int i; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return NULL; @@ -1149,7 +1149,7 @@ r9a06g032_register_bitsel(struct r9a06g032_priv *clocks, const char *names[2]; /* allocate the gate */ - g = kzalloc(sizeof(*g), GFP_KERNEL); + g = kzalloc_obj(*g); if (!g) return NULL; @@ -1239,7 +1239,7 @@ r9a06g032_register_dualgate(struct r9a06g032_priv *clocks, struct clk_init_data init = {}; /* allocate the gate */ - g = kzalloc(sizeof(*g), GFP_KERNEL); + g = kzalloc_obj(*g); if (!g) return NULL; g->clocks = clocks; diff --git a/drivers/clk/renesas/r9a09g056-cpg.c b/drivers/clk/renesas/r9a09g056-cpg.c index f48a082e65d7..fead173cae8b 100644 --- a/drivers/clk/renesas/r9a09g056-cpg.c +++ b/drivers/clk/renesas/r9a09g056-cpg.c @@ -46,11 +46,17 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV20, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_DIV8, CLK_PLLDTY_DIV16, + CLK_PLLDTY_RCPU, + CLK_PLLDTY_RCPU_DIV4, CLK_PLLVDO_CRU0, CLK_PLLVDO_CRU1, CLK_PLLVDO_ISP, @@ -178,12 +184,18 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4), DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8), DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16), + DEF_DDIV(".plldty_rcpu", CLK_PLLDTY_RCPU, CLK_PLLDTY, CDDIV3_DIVCTL2, dtable_2_64), + DEF_FIXED(".plldty_rcpu_div4", CLK_PLLDTY_RCPU_DIV4, CLK_PLLDTY_RCPU, 1, 4), DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4), DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4), @@ -231,6 +243,18 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = { }; static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { + DEF_MOD("dmac_0_aclk", CLK_PLLCM33_GEAR, 0, 0, 0, 0, + BUS_MSTOP(5, BIT(9))), + DEF_MOD("dmac_1_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 1, 0, 1, + BUS_MSTOP(3, BIT(2))), + DEF_MOD("dmac_2_aclk", CLK_PLLDTY_ACPU_DIV2, 0, 2, 0, 2, + BUS_MSTOP(3, BIT(3))), + DEF_MOD("dmac_3_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 3, 0, 3, + BUS_MSTOP(10, BIT(11))), + DEF_MOD("dmac_4_aclk", CLK_PLLDTY_RCPU_DIV4, 0, 4, 0, 4, + BUS_MSTOP(10, BIT(12))), + DEF_MOD_CRITICAL("icu_0_pclk_i", CLK_PLLCM33_DIV16, 0, 5, 0, 5, + BUS_MSTOP_NONE), DEF_MOD_CRITICAL("gic_0_gicclk", CLK_PLLDTY_ACPU_DIV4, 1, 3, 0, 19, BUS_MSTOP(3, BIT(5))), DEF_MOD("gtm_0_pclk", CLK_PLLCM33_DIV16, 4, 3, 2, 3, @@ -265,6 +289,124 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_0_tclk", CLK_PLLCLN_DIV8, 5, 6, 2, 22, + BUS_MSTOP(11, BIT(0))), + DEF_MOD("rspi_1_pclk", CLK_PLLCLN_DIV8, 5, 7, 2, 23, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_1_pclk_sfr", CLK_PLLCLN_DIV8, 5, 8, 2, 24, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_1_tclk", CLK_PLLCLN_DIV8, 5, 9, 2, 25, + BUS_MSTOP(11, BIT(1))), + DEF_MOD("rspi_2_pclk", CLK_PLLCLN_DIV8, 5, 10, 2, 26, + BUS_MSTOP(11, BIT(2))), + DEF_MOD("rspi_2_pclk_sfr", CLK_PLLCLN_DIV8, 5, 11, 2, 27, + BUS_MSTOP(11, BIT(2))), + DEF_MOD("rspi_2_tclk", CLK_PLLCLN_DIV8, 5, 12, 2, 28, + BUS_MSTOP(11, BIT(2))), DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15, BUS_MSTOP(3, BIT(14))), DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16, @@ -291,6 +433,12 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(1, BIT(7))), DEF_MOD("riic_7_ckm", CLK_PLLCLN_DIV16, 9, 11, 4, 27, BUS_MSTOP(1, BIT(8))), + DEF_MOD("canfd_0_pclk", CLK_PLLCLN_DIV16, 9, 12, 4, 28, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clk_ram", CLK_PLLCLN_DIV8, 9, 13, 4, 29, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clkc", CLK_PLLCLN_DIV20, 9, 14, 4, 30, + BUS_MSTOP(10, BIT(14))), DEF_MOD("spi_hclk", CLK_PLLCM33_GEAR, 9, 15, 4, 31, BUS_MSTOP(4, BIT(5))), DEF_MOD("spi_aclk", CLK_PLLCM33_GEAR, 10, 0, 5, 0, @@ -397,10 +545,20 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = { BUS_MSTOP(3, BIT(4))), DEF_MOD("gpu_0_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18, BUS_MSTOP(3, BIT(4))), + DEF_MOD("tsu_0_pclk", CLK_QEXTAL, 16, 9, 8, 9, + BUS_MSTOP(5, BIT(2))), + DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10, + BUS_MSTOP(2, BIT(15))), }; static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(3, 0, 1, 1), /* SYS_0_PRESETN */ + DEF_RST(3, 1, 1, 2), /* DMAC_0_ARESETN */ + DEF_RST(3, 2, 1, 3), /* DMAC_1_ARESETN */ + DEF_RST(3, 3, 1, 4), /* DMAC_2_ARESETN */ + DEF_RST(3, 4, 1, 5), /* DMAC_3_ARESETN */ + DEF_RST(3, 5, 1, 6), /* DMAC_4_ARESETN */ + DEF_RST(3, 6, 1, 7), /* ICU_0_PRESETN_I */ DEF_RST(3, 8, 1, 9), /* GIC_0_GICRESET_N */ DEF_RST(3, 9, 1, 10), /* GIC_0_DBG_GICRESET_N */ DEF_RST(6, 13, 2, 30), /* GTM_0_PRESETZ */ @@ -415,6 +573,32 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ + DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ + DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */ + DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */ + DEF_RST(7, 14, 3, 15), /* RSPI_1_TRESETN */ + DEF_RST(7, 15, 3, 16), /* RSPI_2_PRESETN */ + DEF_RST(8, 0, 3, 17), /* RSPI_2_TRESETN */ DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */ DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */ DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */ @@ -427,6 +611,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(9, 14, 4, 15), /* RIIC_6_MRST */ DEF_RST(9, 15, 4, 16), /* RIIC_7_MRST */ DEF_RST(10, 0, 4, 17), /* RIIC_8_MRST */ + DEF_RST(10, 1, 4, 18), /* CANFD_0_RSTP_N */ + DEF_RST(10, 2, 4, 19), /* CANFD_0_RSTC_N */ DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ @@ -454,6 +640,8 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = { DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */ DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */ DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */ + DEF_RST(15, 7, 7, 8), /* TSU_0_PRESETN */ + DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */ }; const struct rzv2h_cpg_info r9a09g056_cpg_info __initconst = { diff --git a/drivers/clk/renesas/r9a09g057-cpg.c b/drivers/clk/renesas/r9a09g057-cpg.c index 400d9e94f2e9..6943cad318b5 100644 --- a/drivers/clk/renesas/r9a09g057-cpg.c +++ b/drivers/clk/renesas/r9a09g057-cpg.c @@ -46,6 +46,10 @@ enum clk_ids { CLK_PLLCLN_DIV2, CLK_PLLCLN_DIV8, CLK_PLLCLN_DIV16, + CLK_PLLCLN_DIV20, + CLK_PLLCLN_DIV64, + CLK_PLLCLN_DIV256, + CLK_PLLCLN_DIV1024, CLK_PLLDTY_ACPU, CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU_DIV4, @@ -182,6 +186,10 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = { DEF_FIXED(".pllcln_div2", CLK_PLLCLN_DIV2, CLK_PLLCLN, 1, 2), DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8), DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16), + DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20), + DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64), + DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256), + DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024), DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64), DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2), @@ -288,6 +296,106 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(5, BIT(13))), DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18, BUS_MSTOP(5, BIT(13))), + DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1, + BUS_MSTOP(11, BIT(3))), + DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6, + BUS_MSTOP(11, BIT(4))), + DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11, + BUS_MSTOP(11, BIT(5))), + DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16, + BUS_MSTOP(11, BIT(6))), + DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21, + BUS_MSTOP(11, BIT(7))), + DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26, + BUS_MSTOP(11, BIT(8))), + DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31, + BUS_MSTOP(11, BIT(9))), + DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4, + BUS_MSTOP(11, BIT(10))), + DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9, + BUS_MSTOP(11, BIT(11))), + DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13, + BUS_MSTOP(11, BIT(12))), + DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14, + BUS_MSTOP(11, BIT(12))), DEF_MOD("rtc_0_clk_rtc", CLK_PLLCM33_DIV16, 5, 3, 2, 19, BUS_MSTOP(3, BIT(11) | BIT(12))), DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20, @@ -334,6 +442,12 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = { BUS_MSTOP(1, BIT(7))), DEF_MOD("riic_7_ckm", CLK_PLLCLN_DIV16, 9, 11, 4, 27, BUS_MSTOP(1, BIT(8))), + DEF_MOD("canfd_0_pclk", CLK_PLLCLN_DIV16, 9, 12, 4, 28, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clk_ram", CLK_PLLCLN_DIV8, 9, 13, 4, 29, + BUS_MSTOP(10, BIT(14))), + DEF_MOD("canfd_0_clkc", CLK_PLLCLN_DIV20, 9, 14, 4, 30, + BUS_MSTOP(10, BIT(14))), DEF_MOD("spi_hclk", CLK_PLLCM33_GEAR, 9, 15, 4, 31, BUS_MSTOP(4, BIT(5))), DEF_MOD("spi_aclk", CLK_PLLCM33_GEAR, 10, 0, 5, 0, @@ -488,6 +602,26 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */ DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */ DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */ + DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */ + DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */ + DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */ + DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */ + DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */ + DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */ + DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */ + DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */ + DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */ + DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */ + DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */ + DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */ + DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */ + DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */ + DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */ + DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */ + DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */ + DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */ + DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */ + DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */ DEF_RST(7, 9, 3, 10), /* RTC_0_RST_RTC */ DEF_RST(7, 10, 3, 11), /* RTC_0_RST_RTC_V */ DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */ @@ -508,6 +642,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = { DEF_RST(9, 14, 4, 15), /* RIIC_6_MRST */ DEF_RST(9, 15, 4, 16), /* RIIC_7_MRST */ DEF_RST(10, 0, 4, 17), /* RIIC_8_MRST */ + DEF_RST(10, 1, 4, 18), /* CANFD_0_RSTP_N */ + DEF_RST(10, 2, 4, 19), /* CANFD_0_RSTC_N */ DEF_RST(10, 3, 4, 20), /* SPI_HRESETN */ DEF_RST(10, 4, 4, 21), /* SPI_ARESETN */ DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */ diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c index fb6cc94d08a1..93b15e06a19b 100644 --- a/drivers/clk/renesas/r9a09g077-cpg.c +++ b/drivers/clk/renesas/r9a09g077-cpg.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include @@ -41,6 +43,13 @@ #define GET_WIDTH(val) FIELD_GET(WIDTH_MASK, val) #define GET_REG_OFFSET(val) FIELD_GET(OFFSET_MASK, val) +#define FSELXSPI0 CONF_PACK(SCKCR, 0, 3) +#define FSELXSPI1 CONF_PACK(SCKCR, 8, 3) +#define DIVSEL_XSPI0 CONF_PACK(SCKCR, 6, 1) +#define DIVSEL_XSPI1 CONF_PACK(SCKCR, 14, 1) +#define FSELCANFD CONF_PACK(SCKCR, 20, 1) +#define SEL_PLL CONF_PACK(SCKCR, 22, 1) + #define DIVCA55C0 CONF_PACK(SCKCR2, 8, 1) #define DIVCA55C1 CONF_PACK(SCKCR2, 9, 1) #define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1) @@ -58,11 +67,10 @@ #define DIVSCI3ASYNC CONF_PACK(SCKCR3, 12, 2) #define DIVSCI4ASYNC CONF_PACK(SCKCR3, 14, 2) -#define SEL_PLL CONF_PACK(SCKCR, 22, 1) - enum rzt2h_clk_types { CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */ CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */ + CLK_TYPE_RZT2H_FSELXSPI, /* Clock with FSELXSPIn source selector */ }; #define DEF_DIV(_name, _id, _parent, _conf, _dtable) \ @@ -71,11 +79,14 @@ enum rzt2h_clk_types { #define DEF_MUX(_name, _id, _conf, _parent_names, _num_parents, _mux_flags) \ DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_MUX, .conf = _conf, \ .parent_names = _parent_names, .num_parents = _num_parents, \ - .flag = 0, .mux_flags = _mux_flags) + .flag = CLK_SET_RATE_PARENT, .mux_flags = _mux_flags) +#define DEF_DIV_FSELXSPI(_name, _id, _parent, _conf, _dtable) \ + DEF_TYPE(_name, _id, CLK_TYPE_RZT2H_FSELXSPI, .conf = _conf, \ + .parent = _parent, .dtable = _dtable, .flag = 0) enum clk_ids { /* Core Clock Outputs exported to DT */ - LAST_DT_CORE_CLK = R9A09G077_ETCLKE, + LAST_DT_CORE_CLK = R9A09G077_PCLKCAN, /* External Input Clocks */ CLK_EXTAL, @@ -91,6 +102,11 @@ enum clk_ids { CLK_SEL_CLK_PLL2, CLK_SEL_CLK_PLL4, CLK_PLL4D1, + CLK_PLL4D1_DIV3, + CLK_PLL4D1_DIV4, + CLK_PLL4D3, + CLK_PLL4D3_DIV10, + CLK_PLL4D3_DIV20, CLK_SCI0ASYNC, CLK_SCI1ASYNC, CLK_SCI2ASYNC, @@ -101,6 +117,8 @@ enum clk_ids { CLK_SPI1ASYNC, CLK_SPI2ASYNC, CLK_SPI3ASYNC, + CLK_DIVSELXSPI0_SCKCR, + CLK_DIVSELXSPI1_SCKCR, /* Module Clocks */ MOD_CLK_BASE, @@ -112,6 +130,15 @@ static const struct clk_div_table dtable_1_2[] = { {0, 0}, }; +static const struct clk_div_table dtable_6_8_16_32_64[] = { + {6, 64}, + {5, 32}, + {4, 16}, + {3, 8}, + {2, 6}, + {0, 0}, +}; + static const struct clk_div_table dtable_24_25_30_32[] = { {0, 32}, {1, 30}, @@ -126,6 +153,8 @@ static const char * const sel_clk_pll0[] = { ".loco", ".pll0" }; static const char * const sel_clk_pll1[] = { ".loco", ".pll1" }; static const char * const sel_clk_pll2[] = { ".loco", ".pll2" }; static const char * const sel_clk_pll4[] = { ".loco", ".pll4" }; +static const char * const sel_clk_pll4d1_div3_div4[] = { ".pll4d1_div3", ".pll4d1_div4" }; +static const char * const sel_clk_pll4d3_div10_div20[] = { ".pll4d3_div10", ".pll4d3_div20" }; static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { /* External Clock Inputs */ @@ -148,6 +177,12 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { sel_clk_pll4, ARRAY_SIZE(sel_clk_pll4), CLK_MUX_READ_ONLY), DEF_FIXED(".pll4d1", CLK_PLL4D1, CLK_SEL_CLK_PLL4, 1, 1), + DEF_FIXED(".pll4d1_div3", CLK_PLL4D1_DIV3, CLK_PLL4D1, 3, 1), + DEF_FIXED(".pll4d1_div4", CLK_PLL4D1_DIV4, CLK_PLL4D1, 4, 1), + DEF_FIXED(".pll4d3", CLK_PLL4D3, CLK_SEL_CLK_PLL4, 3, 1), + DEF_FIXED(".pll4d3_div10", CLK_PLL4D3_DIV10, CLK_PLL4D3, 10, 1), + DEF_FIXED(".pll4d3_div20", CLK_PLL4D3_DIV20, CLK_PLL4D3, 20, 1), + DEF_DIV(".sci0async", CLK_SCI0ASYNC, CLK_PLL4D1, DIVSCI0ASYNC, dtable_24_25_30_32), DEF_DIV(".sci1async", CLK_SCI1ASYNC, CLK_PLL4D1, DIVSCI1ASYNC, @@ -170,6 +205,13 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC, dtable_24_25_30_32), + DEF_MUX(".divselxspi0", CLK_DIVSELXSPI0_SCKCR, DIVSEL_XSPI0, + sel_clk_pll4d1_div3_div4, + ARRAY_SIZE(sel_clk_pll4d1_div3_div4), 0), + DEF_MUX(".divselxspi1", CLK_DIVSELXSPI1_SCKCR, DIVSEL_XSPI1, + sel_clk_pll4d1_div3_div4, + ARRAY_SIZE(sel_clk_pll4d1_div3_div4), 0), + /* Core output clk */ DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0, dtable_1_2), @@ -194,9 +236,17 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = { DEF_FIXED("ETCLKC", R9A09G077_ETCLKC, CLK_SEL_CLK_PLL1, 10, 1), DEF_FIXED("ETCLKD", R9A09G077_ETCLKD, CLK_SEL_CLK_PLL1, 20, 1), DEF_FIXED("ETCLKE", R9A09G077_ETCLKE, CLK_SEL_CLK_PLL1, 40, 1), + DEF_DIV_FSELXSPI("XSPI_CLK0", R9A09G077_XSPI_CLK0, CLK_DIVSELXSPI0_SCKCR, + FSELXSPI0, dtable_6_8_16_32_64), + DEF_DIV_FSELXSPI("XSPI_CLK1", R9A09G077_XSPI_CLK1, CLK_DIVSELXSPI1_SCKCR, + FSELXSPI1, dtable_6_8_16_32_64), + DEF_MUX("PCLKCAN", R9A09G077_PCLKCAN, FSELCANFD, + sel_clk_pll4d3_div10_div20, ARRAY_SIZE(sel_clk_pll4d3_div10_div20), 0), }; static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { + DEF_MOD("xspi0", 4, R9A09G077_CLK_PCLKH), + DEF_MOD("xspi1", 5, R9A09G077_CLK_PCLKH), DEF_MOD("sci0fck", 8, CLK_SCI0ASYNC), DEF_MOD("sci1fck", 9, CLK_SCI1ASYNC), DEF_MOD("sci2fck", 10, CLK_SCI2ASYNC), @@ -211,6 +261,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = { DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH), DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM), DEF_MOD("tsu", 307, R9A09G077_CLK_PCLKL), + DEF_MOD("canfd", 310, R9A09G077_CLK_PCLKM), DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM), DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM), DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM), @@ -284,6 +335,151 @@ r9a09g077_cpg_mux_clk_register(struct device *dev, return clk_hw->clk; } +static unsigned int r9a09g077_cpg_fselxspi_get_divider(struct clk_hw *hw, unsigned long rate, + unsigned int num_parents) +{ + struct clk_fixed_factor *ff; + struct clk_hw *parent_hw; + unsigned long best_rate; + unsigned int i; + + for (i = 0; i < num_parents; i++) { + parent_hw = clk_hw_get_parent_by_index(hw, i); + best_rate = clk_hw_round_rate(parent_hw, rate); + + if (best_rate == rate) { + ff = to_clk_fixed_factor(parent_hw); + return ff->div; + } + } + + /* No parent could provide the exact rate - this should not happen */ + return 0; +} + +static int r9a09g077_cpg_fselxspi_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + unsigned long parent_rate, best = 0, now; + const struct clk_div_table *clkt; + unsigned long rate = req->rate; + unsigned int num_parents; + unsigned int divselxspi; + unsigned int div = 0; + + if (!rate) + rate = 1; + + /* Get the number of parents for FSELXSPIn */ + num_parents = clk_hw_get_num_parents(req->best_parent_hw); + + for (clkt = divider->table; clkt->div; clkt++) { + parent_rate = clk_hw_round_rate(req->best_parent_hw, rate * clkt->div); + /* Skip if parent can't provide any valid rate */ + if (!parent_rate) + continue; + + /* Determine which DIVSELXSPIn divider (3 or 4) provides this parent_rate */ + divselxspi = r9a09g077_cpg_fselxspi_get_divider(req->best_parent_hw, parent_rate, + num_parents); + if (!divselxspi) + continue; + + /* + * DIVSELXSPIx supports 800MHz and 600MHz operation. + * When divselxspi is 4 (600MHz operation), only FSELXSPIn dividers of 8 and 16 + * are supported. Otherwise, when divselxspi is 3 (800MHz operation), + * dividers of 6, 8, 16, 32, and 64 are supported. This check ensures that + * FSELXSPIx is set correctly based on hardware limitations. + */ + if (divselxspi == 4 && (clkt->div != 8 && clkt->div != 16)) + continue; + + now = DIV_ROUND_UP_ULL(parent_rate, clkt->div); + if (abs(rate - now) < abs(rate - best)) { + div = clkt->div; + best = now; + req->best_parent_rate = parent_rate; + } + } + + if (!div) { + req->best_parent_rate = clk_hw_round_rate(req->best_parent_hw, 1); + divselxspi = r9a09g077_cpg_fselxspi_get_divider(req->best_parent_hw, + req->best_parent_rate, + num_parents); + /* default to divider 3 which will result DIVSELXSPIn = 800 MHz */ + if (!divselxspi) + divselxspi = 3; + + /* + * Use the maximum divider based on the parent clock rate: + * - 64 when DIVSELXSPIx is 800 MHz (divider = 3) + * - 16 when DIVSELXSPIx is 600 MHz (divider = 4) + */ + div = divselxspi == 3 ? 64 : 16; + } + + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div); + + return 0; +} + +static struct clk * __init +r9a09g077_cpg_fselxspi_div_clk_register(struct device *dev, + const struct cpg_core_clk *core, + void __iomem *addr, + struct cpg_mssr_pub *pub) +{ + static struct clk_ops *xspi_div_ops; + struct clk_init_data init = {}; + const struct clk *parent; + const char *parent_name; + struct clk_divider *div; + struct clk_hw *hw; + int ret; + + parent = pub->clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + if (!xspi_div_ops) { + xspi_div_ops = devm_kzalloc(dev, sizeof(*xspi_div_ops), GFP_KERNEL); + if (!xspi_div_ops) + return ERR_PTR(-ENOMEM); + memcpy(xspi_div_ops, &clk_divider_ops, + sizeof(const struct clk_ops)); + xspi_div_ops->determine_rate = r9a09g077_cpg_fselxspi_determine_rate; + } + + parent_name = __clk_get_name(parent); + init.name = core->name; + init.ops = xspi_div_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = &parent_name; + init.num_parents = 1; + + div->reg = addr; + div->shift = GET_SHIFT(core->conf); + div->width = GET_WIDTH(core->conf); + div->flags = core->flag; + div->lock = &pub->rmw_lock; + div->hw.init = &init; + div->table = core->dtable; + + hw = &div->hw; + ret = devm_clk_hw_register(dev, hw); + if (ret) + return ERR_PTR(ret); + + return hw->clk; +} + static struct clk * __init r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, const struct cpg_mssr_info *info, @@ -298,6 +494,8 @@ r9a09g077_cpg_clk_register(struct device *dev, const struct cpg_core_clk *core, return r9a09g077_cpg_div_clk_register(dev, core, addr, pub); case CLK_TYPE_RZT2H_MUX: return r9a09g077_cpg_mux_clk_register(dev, core, addr, pub); + case CLK_TYPE_RZT2H_FSELXSPI: + return r9a09g077_cpg_fselxspi_div_clk_register(dev, core, addr, pub); default: return ERR_PTR(-EINVAL); } diff --git a/drivers/clk/renesas/rcar-cpg-lib.c b/drivers/clk/renesas/rcar-cpg-lib.c index 7b271de7037a..fc73aa685281 100644 --- a/drivers/clk/renesas/rcar-cpg-lib.c +++ b/drivers/clk/renesas/rcar-cpg-lib.c @@ -94,7 +94,7 @@ struct clk * __init cpg_sdh_clk_register(const char *name, struct cpg_simple_notifier *csn; struct clk *clk; - csn = kzalloc(sizeof(*csn), GFP_KERNEL); + csn = kzalloc_obj(*csn); if (!csn) return ERR_PTR(-ENOMEM); @@ -144,7 +144,7 @@ struct clk * __init cpg_rpc_clk_register(const char *name, struct rpc_clock *rpc; struct clk *clk; - rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); + rpc = kzalloc_obj(*rpc); if (!rpc) return ERR_PTR(-ENOMEM); @@ -185,7 +185,7 @@ struct clk * __init cpg_rpcd2_clk_register(const char *name, struct rpcd2_clock *rpcd2; struct clk *clk; - rpcd2 = kzalloc(sizeof(*rpcd2), GFP_KERNEL); + rpcd2 = kzalloc_obj(*rpcd2); if (!rpcd2) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c index ab34bb8c3e07..484b27edf863 100644 --- a/drivers/clk/renesas/rcar-gen2-cpg.c +++ b/drivers/clk/renesas/rcar-gen2-cpg.c @@ -141,7 +141,7 @@ static struct clk * __init cpg_z_clk_register(const char *name, struct cpg_z_clk *zclk; struct clk *clk; - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + zclk = kzalloc_obj(*zclk); if (!zclk) return ERR_PTR(-ENOMEM); @@ -169,14 +169,14 @@ static struct clk * __init cpg_rcan_clk_register(const char *name, struct clk_gate *gate; struct clk *clk; - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); + fixed = kzalloc_obj(*fixed); if (!fixed) return ERR_PTR(-ENOMEM); fixed->mult = 1; fixed->div = 6; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { kfree(fixed); return ERR_PTR(-ENOMEM); @@ -213,7 +213,7 @@ static struct clk * __init cpg_adsp_clk_register(const char *name, struct clk_gate *gate; struct clk *clk; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); @@ -222,7 +222,7 @@ static struct clk * __init cpg_adsp_clk_register(const char *name, div->table = cpg_adsp_div_table; div->lock = &cpg_lock; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { kfree(div); return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c index b954278ddd9d..e5b503332217 100644 --- a/drivers/clk/renesas/rcar-gen3-cpg.c +++ b/drivers/clk/renesas/rcar-gen3-cpg.c @@ -123,7 +123,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name, struct clk_init_data init = {}; struct clk *clk; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (!pll_clk) return ERR_PTR(-ENOMEM); @@ -271,7 +271,7 @@ static struct clk * __init __cpg_z_clk_register(const char *name, struct cpg_z_clk *zclk; struct clk *clk; - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + zclk = kzalloc_obj(*zclk); if (!zclk) return ERR_PTR(-ENOMEM); @@ -410,7 +410,7 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, if (cpg_quirks & RCKCR_CKSEL) { struct cpg_simple_notifier *csn; - csn = kzalloc(sizeof(*csn), GFP_KERNEL); + csn = kzalloc_obj(*csn); if (!csn) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c index ac2b5afec46d..96922789e02a 100644 --- a/drivers/clk/renesas/rcar-gen4-cpg.c +++ b/drivers/clk/renesas/rcar-gen4-cpg.c @@ -234,7 +234,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name, struct cpg_pll_clk *pll_clk; struct clk *clk; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (!pll_clk) return ERR_PTR(-ENOMEM); @@ -374,7 +374,7 @@ static struct clk * __init cpg_z_clk_register(const char *name, struct cpg_z_clk *zclk; struct clk *clk; - zclk = kzalloc(sizeof(*zclk), GFP_KERNEL); + zclk = kzalloc_obj(*zclk); if (!zclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index 7f9b7aa39790..64a432fd0e8a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -237,20 +237,16 @@ struct mstp_clock { #define to_mstp_clock(_hw) container_of(_hw, struct mstp_clock, hw) -static u32 cpg_rzt2h_mstp_read(struct clk_hw *hw, u16 offset) +static u32 cpg_rzt2h_mstp_read(struct cpg_mssr_priv *priv, u16 offset) { - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; void __iomem *base = RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0; return readl(base + RZT2H_MSTPCR_OFFSET(offset)); } -static void cpg_rzt2h_mstp_write(struct clk_hw *hw, u16 offset, u32 value) +static void cpg_rzt2h_mstp_write(struct cpg_mssr_priv *priv, u16 offset, u32 value) { - struct mstp_clock *clock = to_mstp_clock(hw); - struct cpg_mssr_priv *priv = clock->priv; void __iomem *base = RZT2H_MSTPCR_BLOCK(offset) ? priv->pub.base1 : priv->pub.base0; @@ -286,17 +282,14 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) barrier_data(priv->pub.base0 + priv->control_regs[reg]); } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { - value = cpg_rzt2h_mstp_read(hw, - priv->control_regs[reg]); + value = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); if (enable) value &= ~bitmask; else value |= bitmask; - cpg_rzt2h_mstp_write(hw, - priv->control_regs[reg], - value); + cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], value); } else { value = readl(priv->pub.base0 + priv->control_regs[reg]); if (enable) @@ -318,7 +311,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) * the IP at least seven times. Instead of memory-mapping the IP * register, we simply add a delay after the read operation. */ - cpg_rzt2h_mstp_read(hw, priv->control_regs[reg]); + cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); udelay(10); return 0; } @@ -352,8 +345,7 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) value = readb(priv->pub.base0 + priv->control_regs[reg]); else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) - value = cpg_rzt2h_mstp_read(hw, - priv->control_regs[reg]); + value = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); else value = readl(priv->pub.base0 + priv->status_regs[reg]); @@ -412,7 +404,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", @@ -520,7 +512,7 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, goto fail; } - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) { clk = ERR_PTR(-ENOMEM); goto fail; @@ -802,14 +794,14 @@ static int cpg_mrcr_set_reset_state(struct reset_controller_dev *rcdev, /* Verify the operation */ val = readl(reg_addr); - if (set == !(bitmask & val)) { - dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); - spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); - return -EIO; - } spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + if (set == !(bitmask & val)) { + dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit); + return -EIO; + } + return 0; } @@ -1085,11 +1077,19 @@ static int cpg_mssr_suspend_noirq(struct device *dev) /* Save module registers with bits under our control */ for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { - if (priv->smstpcr_saved[reg].mask) - priv->smstpcr_saved[reg].val = - priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? - readb(priv->pub.base0 + priv->control_regs[reg]) : - readl(priv->pub.base0 + priv->control_regs[reg]); + u32 val; + + if (!priv->smstpcr_saved[reg].mask) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + val = readb(priv->pub.base0 + priv->control_regs[reg]); + else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + val = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); + else + val = readl(priv->pub.base0 + priv->control_regs[reg]); + + priv->smstpcr_saved[reg].val = val; } /* Save core clocks */ @@ -1120,6 +1120,8 @@ static int cpg_mssr_resume_noirq(struct device *dev) if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) oldval = readb(priv->pub.base0 + priv->control_regs[reg]); + else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) + oldval = cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); else oldval = readl(priv->pub.base0 + priv->control_regs[reg]); newval = oldval & ~mask; @@ -1133,6 +1135,12 @@ static int cpg_mssr_resume_noirq(struct device *dev) readb(priv->pub.base0 + priv->control_regs[reg]); barrier_data(priv->pub.base0 + priv->control_regs[reg]); continue; + } else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) { + cpg_rzt2h_mstp_write(priv, priv->control_regs[reg], newval); + /* See cpg_mstp_clock_endisable() on why this is necessary. */ + cpg_rzt2h_mstp_read(priv, priv->control_regs[reg]); + udelay(10); + continue; } else writel(newval, priv->pub.base0 + priv->control_regs[reg]); @@ -1250,7 +1258,7 @@ static int __init cpg_mssr_common_init(struct device *dev, } nclks = info->num_total_core_clks + info->num_hw_mod_clks; - priv = kzalloc(struct_size(priv, clks, nclks), GFP_KERNEL); + priv = kzalloc_flex(*priv, clks, nclks); if (!priv) return -ENOMEM; diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c index 64d1ef6e4c94..c0584bab58a3 100644 --- a/drivers/clk/renesas/rzg2l-cpg.c +++ b/drivers/clk/renesas/rzg2l-cpg.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -74,6 +75,17 @@ #define MSTOP_OFF(conf) FIELD_GET(GENMASK(31, 16), (conf)) #define MSTOP_MASK(conf) FIELD_GET(GENMASK(15, 0), (conf)) +#define PLL5_FOUTVCO_MIN 800000000 +#define PLL5_FOUTVCO_MAX 3000000000 +#define PLL5_POSTDIV_MIN 1 +#define PLL5_POSTDIV_MAX 7 +#define PLL5_REFDIV_MIN 1 +#define PLL5_REFDIV_MAX 2 +#define PLL5_INTIN_MIN 20 +#define PLL5_INTIN_MAX 320 +#define PLL5_HSCLK_MIN 10000000 +#define PLL5_HSCLK_MAX 187500000 + /** * struct clk_hw_data - clock hardware data * @hw: clock hw @@ -122,13 +134,19 @@ struct div_hw_data { struct rzg2l_pll5_param { u32 pl5_fracin; + u16 pl5_intin; u8 pl5_refdiv; - u8 pl5_intin; u8 pl5_postdiv1; u8 pl5_postdiv2; u8 pl5_spread; }; +/* PLL5 output will be used for DPI or MIPI-DSI */ +static int dsi_div_target = PLL5_TARGET_DPI; + +/* Required division ratio for MIPI D-PHY clock depending on number of lanes and bpp. */ +static u8 dsi_div_ab_desired; + struct rzg2l_pll5_mux_dsi_div_param { u8 clksrc; u8 dsi_div_a; @@ -170,6 +188,11 @@ struct rzg2l_cpg_priv { struct rzg2l_pll5_mux_dsi_div_param mux_dsi_div_params; }; +static inline u8 rzg2l_cpg_div_ab(u8 a, u8 b) +{ + return (b + 1) << a; +} + static void rzg2l_cpg_del_clk_provider(void *data) { of_clk_del_provider(data); @@ -556,23 +579,120 @@ rzg2l_cpg_sd_mux_clk_register(const struct cpg_core_clk *core, return clk_hw->clk; } +/* + * VCO-->[POSTDIV1,2]--FOUTPOSTDIV--------------->| + * | |-->[1/(DSI DIV A * B)]--> MIPI_DSI_VCLK + * |-->[1/2]--FOUT1PH0-->| + * | + * |------->[1/16]--------------------------------> hsclk (MIPI-PHY) + */ static unsigned long -rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_pll5_param *params, +rzg2l_cpg_get_foutpostdiv_rate(struct rzg2l_cpg_priv *priv, + struct rzg2l_pll5_param *params, unsigned long rate) { - unsigned long foutpostdiv_rate, foutvco_rate; + const u32 extal_hz = EXTAL_FREQ_IN_MEGA_HZ * MEGA; + unsigned long foutpostdiv_rate; + unsigned int a, b, odd; + unsigned long hsclk; + u8 dsi_div_ab_calc; + u64 foutvco_rate; - params->pl5_intin = rate / MEGA; - params->pl5_fracin = div_u64(((u64)rate % MEGA) << 24, MEGA); - params->pl5_refdiv = 2; - params->pl5_postdiv1 = 1; - params->pl5_postdiv2 = 1; + if (dsi_div_target == PLL5_TARGET_DSI) { + /* Check hsclk */ + hsclk = rate * dsi_div_ab_desired / 16; + if (hsclk < PLL5_HSCLK_MIN || hsclk > PLL5_HSCLK_MAX) { + dev_err(priv->dev, "hsclk out of range\n"); + return 0; + } + + /* Determine the correct clock source based on even/odd of the divider */ + odd = dsi_div_ab_desired & 1; + if (odd) { + priv->mux_dsi_div_params.clksrc = 0; /* FOUTPOSTDIV */ + dsi_div_ab_calc = dsi_div_ab_desired; + } else { + priv->mux_dsi_div_params.clksrc = 1; /* FOUT1PH0 */ + dsi_div_ab_calc = dsi_div_ab_desired / 2; + } + + /* Calculate the DIV_DSI_A and DIV_DSI_B based on the desired divider */ + for (a = 0; a < 4; a++) { + /* FOUT1PH0: Max output of DIV_DSI_A is 750MHz so at least 1/2 to be safe */ + if (!odd && a == 0) + continue; + + /* FOUTPOSTDIV: DIV_DSI_A must always be 1/1 */ + if (odd && a != 0) + break; + + for (b = 0; b < 16; b++) { + /* FOUTPOSTDIV: DIV_DSI_B must always be odd divider 1/(b+1) */ + if (odd && b & 1) + continue; + + if (rzg2l_cpg_div_ab(a, b) == dsi_div_ab_calc) { + priv->mux_dsi_div_params.dsi_div_a = a; + priv->mux_dsi_div_params.dsi_div_b = b; + goto calc_pll_clk; + } + } + } + + dev_err(priv->dev, "Failed to calculate DIV_DSI_A,B\n"); + + return 0; + } else if (dsi_div_target == PLL5_TARGET_DPI) { + /* Fixed settings for DPI */ + priv->mux_dsi_div_params.clksrc = 0; + priv->mux_dsi_div_params.dsi_div_a = 3; /* Divided by 8 */ + priv->mux_dsi_div_params.dsi_div_b = 0; /* Divided by 1 */ + dsi_div_ab_desired = rzg2l_cpg_div_ab(priv->mux_dsi_div_params.dsi_div_a, + priv->mux_dsi_div_params.dsi_div_b); + } + +calc_pll_clk: + /* PLL5 (MIPI_DSI_PLLCLK) = VCO / POSTDIV1 / POSTDIV2 */ + for (params->pl5_postdiv1 = PLL5_POSTDIV_MIN; + params->pl5_postdiv1 <= PLL5_POSTDIV_MAX; + params->pl5_postdiv1++) { + for (params->pl5_postdiv2 = PLL5_POSTDIV_MIN; + params->pl5_postdiv2 <= PLL5_POSTDIV_MAX; + params->pl5_postdiv2++) { + foutvco_rate = rate * params->pl5_postdiv1 * params->pl5_postdiv2 * + dsi_div_ab_desired; + if (foutvco_rate <= PLL5_FOUTVCO_MIN || foutvco_rate >= PLL5_FOUTVCO_MAX) + continue; + + for (params->pl5_refdiv = PLL5_REFDIV_MIN; + params->pl5_refdiv <= PLL5_REFDIV_MAX; + params->pl5_refdiv++) { + u32 rem; + + params->pl5_intin = div_u64_rem(foutvco_rate * params->pl5_refdiv, + extal_hz, &rem); + + if (params->pl5_intin < PLL5_INTIN_MIN || + params->pl5_intin > PLL5_INTIN_MAX) + continue; + + params->pl5_fracin = div_u64((u64)rem << 24, extal_hz); + + goto clk_valid; + } + } + } + + dev_err(priv->dev, "Failed to calculate PLL5 settings\n"); + return 0; + +clk_valid: params->pl5_spread = 0x16; foutvco_rate = div_u64(mul_u32_u32(EXTAL_FREQ_IN_MEGA_HZ * MEGA, (params->pl5_intin << 24) + params->pl5_fracin), params->pl5_refdiv) >> 24; - foutpostdiv_rate = DIV_ROUND_CLOSEST_ULL(foutvco_rate, + foutpostdiv_rate = DIV_U64_ROUND_CLOSEST(foutvco_rate, params->pl5_postdiv1 * params->pl5_postdiv2); return foutpostdiv_rate; @@ -607,7 +727,7 @@ static unsigned long rzg2l_cpg_get_vclk_parent_rate(struct clk_hw *hw, struct rzg2l_pll5_param params; unsigned long parent_rate; - parent_rate = rzg2l_cpg_get_foutpostdiv_rate(¶ms, rate); + parent_rate = rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, rate); if (priv->mux_dsi_div_params.clksrc) parent_rate /= 2; @@ -623,9 +743,19 @@ static int rzg2l_cpg_dsi_div_determine_rate(struct clk_hw *hw, req->best_parent_rate = rzg2l_cpg_get_vclk_parent_rate(hw, req->rate); + if (!req->best_parent_rate) + return -EINVAL; + return 0; } +void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) +{ + dsi_div_ab_desired = divider; + dsi_div_target = target; +} +EXPORT_SYMBOL_GPL(rzg2l_cpg_dsi_div_set_divider); + static int rzg2l_cpg_dsi_div_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) @@ -796,22 +926,6 @@ struct sipll5 { #define to_sipll5(_hw) container_of(_hw, struct sipll5, hw) -static unsigned long rzg2l_cpg_get_vclk_rate(struct clk_hw *hw, - unsigned long rate) -{ - struct sipll5 *sipll5 = to_sipll5(hw); - struct rzg2l_cpg_priv *priv = sipll5->priv; - unsigned long vclk; - - vclk = rate / ((1 << priv->mux_dsi_div_params.dsi_div_a) * - (priv->mux_dsi_div_params.dsi_div_b + 1)); - - if (priv->mux_dsi_div_params.clksrc) - vclk /= 2; - - return vclk; -} - static unsigned long rzg2l_cpg_sipll5_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { @@ -856,16 +970,16 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, if (!rate) return -EINVAL; - vclk_rate = rzg2l_cpg_get_vclk_rate(hw, rate); + vclk_rate = rate / dsi_div_ab_desired; sipll5->foutpostdiv_rate = - rzg2l_cpg_get_foutpostdiv_rate(¶ms, vclk_rate); + rzg2l_cpg_get_foutpostdiv_rate(priv, ¶ms, vclk_rate); /* Put PLL5 into standby mode */ writel(CPG_SIPLL5_STBY_RESETB_WEN, priv->base + CPG_SIPLL5_STBY); ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, !(val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000); if (ret) { - dev_err(priv->dev, "failed to release pll5 lock"); + dev_err(priv->dev, "failed to release pll5 lock\n"); return ret; } @@ -892,7 +1006,7 @@ static int rzg2l_cpg_sipll5_set_rate(struct clk_hw *hw, ret = readl_poll_timeout(priv->base + CPG_SIPLL5_MON, val, (val & CPG_SIPLL5_MON_PLL5_LOCK), 100, 250000); if (ret) { - dev_err(priv->dev, "failed to lock pll5"); + dev_err(priv->dev, "failed to lock pll5\n"); return ret; } @@ -945,9 +1059,7 @@ rzg2l_cpg_sipll5_register(const struct cpg_core_clk *core, if (ret) return ERR_PTR(ret); - priv->mux_dsi_div_params.clksrc = 1; /* Use clk src 1 for DSI */ - priv->mux_dsi_div_params.dsi_div_a = 1; /* Divided by 2 */ - priv->mux_dsi_div_params.dsi_div_b = 2; /* Divided by 3 */ + rzg2l_cpg_dsi_div_set_divider(8, PLL5_TARGET_DPI); return clk_hw->clk; } @@ -1102,7 +1214,7 @@ static struct clk } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", @@ -1647,6 +1759,7 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(info->resets[id].bit); s8 monbit = info->resets[id].monbit; u32 value = mask << 16; + u32 mon; int ret; dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", @@ -1667,10 +1780,10 @@ static int __rzg2l_cpg_assert(struct reset_controller_dev *rcdev, return 0; } - ret = readl_poll_timeout_atomic(priv->base + reg, value, - assert == !!(value & mask), 10, 200); - if (ret && !assert) { - value = mask << 16; + ret = readl_poll_timeout_atomic(priv->base + reg, mon, + assert == !!(mon & mask), 10, 200); + if (ret) { + value ^= mask; writel(value, priv->base + CLK_RST_R(info->resets[id].off)); } diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index 3f6299b9fec0..f6c47fb89bca 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -602,7 +602,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, val, !(val & CPG_PLL_MON_LOCK), 100, 2000); if (ret) { - dev_err(priv->dev, "Failed to put PLLDSI into standby mode"); + dev_err(priv->dev, "Failed to put PLLDSI into standby mode\n"); return ret; } @@ -630,7 +630,7 @@ static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk, val, (val & CPG_PLL_MON_LOCK), 100, 2000); if (ret) { - dev_err(priv->dev, "Failed to put PLLDSI into normal mode"); + dev_err(priv->dev, "Failed to put PLLDSI into normal mode\n"); return ret; } @@ -1013,7 +1013,7 @@ static struct clk } if (IS_ERR(clk)) - dev_err(dev, "Cannot get %s clock %u: %ld", type, clkidx, + dev_err(dev, "Cannot get %s clock %u: %ld\n", type, clkidx, PTR_ERR(clk)); else dev_dbg(dev, "clock (%u, %u) is %pC at %lu Hz\n", @@ -1352,6 +1352,7 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, u32 mask = BIT(priv->resets[id].reset_bit); u8 monbit = priv->resets[id].mon_bit; u32 value = mask << 16; + u32 mon; int ret; dev_dbg(rcdev->dev, "%s id:%ld offset:0x%x\n", @@ -1364,10 +1365,10 @@ static int __rzv2h_cpg_assert(struct reset_controller_dev *rcdev, reg = GET_RST_MON_OFFSET(priv->resets[id].mon_index); mask = BIT(monbit); - ret = readl_poll_timeout_atomic(priv->base + reg, value, - assert == !!(value & mask), 10, 200); - if (ret && !assert) { - value = mask << 16; + ret = readl_poll_timeout_atomic(priv->base + reg, mon, + assert == !!(mon & mask), 10, 200); + if (ret) { + value ^= mask; writel(value, priv->base + GET_RST_OFFSET(priv->resets[id].reset_index)); } diff --git a/drivers/clk/rockchip/clk-cpu.c b/drivers/clk/rockchip/clk-cpu.c index 6e91a3041a03..6205af9ba88a 100644 --- a/drivers/clk/rockchip/clk-cpu.c +++ b/drivers/clk/rockchip/clk-cpu.c @@ -313,7 +313,7 @@ struct clk *rockchip_clk_register_cpuclk(const char *name, return ERR_PTR(-EINVAL); } - cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); + cpuclk = kzalloc_obj(*cpuclk); if (!cpuclk) return ERR_PTR(-ENOMEM); @@ -479,7 +479,7 @@ struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, int ret; if (num_parents > 1) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -493,7 +493,7 @@ struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, } if (div_width > 0) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) { ret = -ENOMEM; goto free_mux; @@ -521,7 +521,7 @@ struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name, goto free_div; } - cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); + cpuclk = kzalloc_obj(*cpuclk); if (!cpuclk) { ret = -ENOMEM; goto unregister_clk; diff --git a/drivers/clk/rockchip/clk-ddr.c b/drivers/clk/rockchip/clk-ddr.c index 8866a65982a0..81ae8a4ee30e 100644 --- a/drivers/clk/rockchip/clk-ddr.c +++ b/drivers/clk/rockchip/clk-ddr.c @@ -100,7 +100,7 @@ struct clk *rockchip_clk_register_ddrclk(const char *name, int flags, struct clk_init_data init; struct clk *clk; - ddrclk = kzalloc(sizeof(*ddrclk), GFP_KERNEL); + ddrclk = kzalloc_obj(*ddrclk); if (!ddrclk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-gate-grf.c b/drivers/clk/rockchip/clk-gate-grf.c index 8122f471f391..88e409e91a63 100644 --- a/drivers/clk/rockchip/clk-gate-grf.c +++ b/drivers/clk/rockchip/clk-gate-grf.c @@ -81,7 +81,7 @@ struct clk *rockchip_clk_register_gate_grf(const char *name, return ERR_PTR(-EOPNOTSUPP); } - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-half-divider.c b/drivers/clk/rockchip/clk-half-divider.c index fbc018e8afa4..bafe3e998954 100644 --- a/drivers/clk/rockchip/clk-half-divider.c +++ b/drivers/clk/rockchip/clk-half-divider.c @@ -176,7 +176,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, *gate_ops = NULL; if (num_parents > 1) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -190,7 +190,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, } if (gate_offset >= 0) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto err_gate; @@ -202,7 +202,7 @@ struct clk *rockchip_clk_register_halfdiv(const char *name, } if (div_width > 0) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto err_div; diff --git a/drivers/clk/rockchip/clk-inverter.c b/drivers/clk/rockchip/clk-inverter.c index 5dfbdce18b48..bf9072ed9fd4 100644 --- a/drivers/clk/rockchip/clk-inverter.c +++ b/drivers/clk/rockchip/clk-inverter.c @@ -79,7 +79,7 @@ struct clk *rockchip_clk_register_inverter(const char *name, struct rockchip_inv_clock *inv_clock; struct clk *clk; - inv_clock = kmalloc(sizeof(*inv_clock), GFP_KERNEL); + inv_clock = kmalloc_obj(*inv_clock); if (!inv_clock) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 8b1292c56863..4efd22953f3e 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -210,7 +210,7 @@ struct clk *rockchip_clk_register_mmc(const char *name, struct clk *clk; int ret; - mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); + mmc_clock = kmalloc_obj(*mmc_clock); if (!mmc_clock) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-muxgrf.c b/drivers/clk/rockchip/clk-muxgrf.c index 4a335a5f4633..ccbb1379501a 100644 --- a/drivers/clk/rockchip/clk-muxgrf.c +++ b/drivers/clk/rockchip/clk-muxgrf.c @@ -67,7 +67,7 @@ struct clk *rockchip_clk_register_muxgrf(const char *name, return ERR_PTR(-ENOTSUPP); } - muxgrf_clock = kmalloc(sizeof(*muxgrf_clock), GFP_KERNEL); + muxgrf_clock = kmalloc_obj(*muxgrf_clock); if (!muxgrf_clock) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-pll.c b/drivers/clk/rockchip/clk-pll.c index 86dba3826a77..6b853800cb6b 100644 --- a/drivers/clk/rockchip/clk-pll.c +++ b/drivers/clk/rockchip/clk-pll.c @@ -1076,7 +1076,7 @@ struct clk *rockchip_clk_register_pll(struct rockchip_clk_provider *ctx, /* name the actual pll */ snprintf(pll_name, sizeof(pll_name), "pll_%s", name); - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/rockchip/clk-rk3576.c b/drivers/clk/rockchip/clk-rk3576.c index 9bc0ef51ef68..2557358e0b9d 100644 --- a/drivers/clk/rockchip/clk-rk3576.c +++ b/drivers/clk/rockchip/clk-rk3576.c @@ -1769,7 +1769,7 @@ static void __init rk3576_clk_init(struct device_node *np) goto err_unmap; } - pmu0_grf_e = kzalloc(sizeof(*pmu0_grf_e), GFP_KERNEL); + pmu0_grf_e = kzalloc_obj(*pmu0_grf_e); if (!pmu0_grf_e) goto err_unmap; @@ -1777,7 +1777,7 @@ static void __init rk3576_clk_init(struct device_node *np) pmu0_grf_e->type = grf_type_pmu0; hash_add(ctx->aux_grf_table, &pmu0_grf_e->node, grf_type_pmu0); - ioc_grf_e = kzalloc(sizeof(*ioc_grf_e), GFP_KERNEL); + ioc_grf_e = kzalloc_obj(*ioc_grf_e); if (!ioc_grf_e) goto err_free_pmu0; diff --git a/drivers/clk/rockchip/clk.c b/drivers/clk/rockchip/clk.c index 2601df3b1066..e8b3b0b9a4f8 100644 --- a/drivers/clk/rockchip/clk.c +++ b/drivers/clk/rockchip/clk.c @@ -55,7 +55,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, int ret; if (num_parents > 1) { - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, } if (gate_offset >= 0) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { ret = -ENOMEM; goto err_gate; @@ -84,7 +84,7 @@ static struct clk *rockchip_clk_register_branch(const char *name, } if (div_width > 0) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) { ret = -ENOMEM; goto err_div; @@ -221,7 +221,7 @@ static struct clk *rockchip_clk_register_frac_branch( return ERR_PTR(-EINVAL); } - frac = kzalloc(sizeof(*frac), GFP_KERNEL); + frac = kzalloc_obj(*frac); if (!frac) return ERR_PTR(-ENOMEM); @@ -323,7 +323,7 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, div); } - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); @@ -332,7 +332,7 @@ static struct clk *rockchip_clk_register_factor_branch(const char *name, gate->bit_idx = gate_shift; gate->lock = lock; - fix = kzalloc(sizeof(*fix), GFP_KERNEL); + fix = kzalloc_obj(*fix); if (!fix) { kfree(gate); return ERR_PTR(-ENOMEM); @@ -365,11 +365,11 @@ static struct rockchip_clk_provider *rockchip_clk_init_base( default_clk_val = ERR_PTR(has_late_clocks ? -EPROBE_DEFER : -ENOENT); - ctx = kzalloc(sizeof(struct rockchip_clk_provider), GFP_KERNEL); + ctx = kzalloc_obj(struct rockchip_clk_provider); if (!ctx) return ERR_PTR(-ENOMEM); - clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); + clk_table = kzalloc_objs(struct clk *, nr_clks); if (!clk_table) goto err_free; @@ -693,7 +693,7 @@ void rockchip_clk_register_late_branches(struct device *dev, break; } - if (!pdev) + if (IS_ERR_OR_NULL(pdev)) dev_err(dev, "failed to register device for clock %s\n", list->name); } } diff --git a/drivers/clk/rockchip/softrst.c b/drivers/clk/rockchip/softrst.c index fd56aaefe6d1..115f317a99a2 100644 --- a/drivers/clk/rockchip/softrst.c +++ b/drivers/clk/rockchip/softrst.c @@ -96,7 +96,7 @@ void rockchip_register_softrst_lut(struct device_node *np, struct rockchip_softrst *softrst; int ret; - softrst = kzalloc(sizeof(*softrst), GFP_KERNEL); + softrst = kzalloc_obj(*softrst); if (!softrst) return; diff --git a/drivers/clk/samsung/clk-cpu.c b/drivers/clk/samsung/clk-cpu.c index 300f8d5d3c48..ffc33e5decf5 100644 --- a/drivers/clk/samsung/clk-cpu.c +++ b/drivers/clk/samsung/clk-cpu.c @@ -660,7 +660,7 @@ static int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx, return -EINVAL; } - cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL); + cpuclk = kzalloc_obj(*cpuclk); if (!cpuclk) return -ENOMEM; diff --git a/drivers/clk/samsung/clk-exynos-arm64.c b/drivers/clk/samsung/clk-exynos-arm64.c index bf7de21f329e..35d4de233cc1 100644 --- a/drivers/clk/samsung/clk-exynos-arm64.c +++ b/drivers/clk/samsung/clk-exynos-arm64.c @@ -24,6 +24,16 @@ #define GATE_MANUAL BIT(20) #define GATE_ENABLE_HWACG BIT(28) +/* Option register bits */ +#define OPT_EN_MEM_PWR_GATING BIT(24) +#define OPT_EN_AUTO_GATING BIT(28) +#define OPT_EN_PWR_MANAGEMENT BIT(29) +#define OPT_EN_LAYER2_CTRL BIT(30) +#define OPT_EN_DBG BIT(31) + +#define CMU_OPT_GLOBAL_EN_AUTO_GATING (OPT_EN_DBG | OPT_EN_LAYER2_CTRL | \ + OPT_EN_PWR_MANAGEMENT | OPT_EN_AUTO_GATING | OPT_EN_MEM_PWR_GATING) + /* PLL_CONx_PLL register offsets range */ #define PLL_CON_OFF_START 0x100 #define PLL_CON_OFF_END 0x600 @@ -37,6 +47,8 @@ struct exynos_arm64_cmu_data { unsigned int nr_clk_save; const struct samsung_clk_reg_dump *clk_suspend; unsigned int nr_clk_suspend; + struct samsung_clk_reg_dump *clk_sysreg_save; + unsigned int nr_clk_sysreg; struct clk *clk; struct clk **pclks; @@ -76,19 +88,41 @@ static void __init exynos_arm64_init_clocks(struct device_node *np, const unsigned long *reg_offs = cmu->clk_regs; size_t reg_offs_len = cmu->nr_clk_regs; void __iomem *reg_base; + bool init_auto; size_t i; reg_base = of_iomap(np, 0); if (!reg_base) panic("%s: failed to map registers\n", __func__); + /* ensure compatibility with older DTs */ + if (cmu->auto_clock_gate && samsung_is_auto_capable(np)) + init_auto = true; + else + init_auto = false; + + if (cmu->option_offset && init_auto) { + /* + * Enable the global automatic mode for the entire CMU. + * This overrides the individual HWACG bits in each of the + * individual gate, mux and qch registers. + */ + writel(CMU_OPT_GLOBAL_EN_AUTO_GATING, + reg_base + cmu->option_offset); + } + for (i = 0; i < reg_offs_len; ++i) { void __iomem *reg = reg_base + reg_offs[i]; u32 val; if (cmu->manual_plls && is_pll_con1_reg(reg_offs[i])) { writel(PLL_CON1_MANUAL, reg); - } else if (is_gate_reg(reg_offs[i])) { + } else if (is_gate_reg(reg_offs[i]) && !init_auto) { + /* + * Setting GATE_MANUAL bit (which is described in TRM as + * reserved!) overrides the global CMU automatic mode + * option. + */ val = readl(reg); val |= GATE_MANUAL; val &= ~GATE_ENABLE_HWACG; @@ -140,7 +174,7 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, const struct samsung_cmu_info *cmu) { struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev); - int i; + int i, ret; data->clk_save = samsung_clk_alloc_reg_dump(cmu->clk_regs, cmu->nr_clk_regs); @@ -148,8 +182,22 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, return -ENOMEM; data->nr_clk_save = cmu->nr_clk_regs; + + if (cmu->nr_sysreg_clk_regs) { + data->clk_sysreg_save = + samsung_clk_alloc_reg_dump(cmu->sysreg_clk_regs, + cmu->nr_sysreg_clk_regs); + if (!data->clk_sysreg_save) { + ret = -ENOMEM; + goto free_clk_save; + } + + data->nr_clk_sysreg = cmu->nr_sysreg_clk_regs; + } + data->clk_suspend = cmu->suspend_regs; data->nr_clk_suspend = cmu->nr_suspend_regs; + data->nr_pclks = of_clk_get_parent_count(dev->of_node); if (!data->nr_pclks) return 0; @@ -157,23 +205,29 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev, data->pclks = devm_kcalloc(dev, sizeof(struct clk *), data->nr_pclks, GFP_KERNEL); if (!data->pclks) { - kfree(data->clk_save); - return -ENOMEM; + ret = -ENOMEM; + goto free_sysreg_save; } for (i = 0; i < data->nr_pclks; i++) { struct clk *clk = of_clk_get(dev->of_node, i); if (IS_ERR(clk)) { - kfree(data->clk_save); while (--i >= 0) clk_put(data->pclks[i]); - return PTR_ERR(clk); + ret = PTR_ERR(clk); + goto free_sysreg_save; } data->pclks[i] = clk; } return 0; + +free_sysreg_save: + kfree(data->clk_sysreg_save); +free_clk_save: + kfree(data->clk_save); + return ret; } /** @@ -210,8 +264,8 @@ void __init exynos_arm64_register_cmu(struct device *dev, /** * exynos_arm64_register_cmu_pm - Register Exynos CMU domain with PM support * - * @pdev: Platform device object - * @set_manual: If true, set gate clocks to manual mode + * @pdev: Platform device object + * @init_clk_regs: If true, initialize CMU registers * * It's a version of exynos_arm64_register_cmu() with PM support. Should be * called from probe function of platform driver. @@ -219,7 +273,7 @@ void __init exynos_arm64_register_cmu(struct device *dev, * Return: 0 on success, or negative error code on error. */ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, - bool set_manual) + bool init_clk_regs) { const struct samsung_cmu_info *cmu; struct device *dev = &pdev->dev; @@ -249,7 +303,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, dev_err(dev, "%s: could not enable bus clock %s; err = %d\n", __func__, cmu->clk_name, ret); - if (set_manual) + if (init_clk_regs) exynos_arm64_init_clocks(np, cmu); reg_base = devm_platform_ioremap_resource(pdev, 0); @@ -268,8 +322,10 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev, pm_runtime_set_active(dev); pm_runtime_enable(dev); - samsung_cmu_register_clocks(data->ctx, cmu); + samsung_cmu_register_clocks(data->ctx, cmu, np); samsung_clk_of_add_provider(dev->of_node, data->ctx); + /* sysreg DT nodes reference a clock in this CMU */ + samsung_en_dyn_root_clk_gating(np, data->ctx, cmu, true); pm_runtime_put_sync(dev); return 0; @@ -280,14 +336,17 @@ int exynos_arm64_cmu_suspend(struct device *dev) struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev); int i; - samsung_clk_save(data->ctx->reg_base, data->clk_save, + samsung_clk_save(data->ctx->reg_base, NULL, data->clk_save, data->nr_clk_save); + samsung_clk_save(NULL, data->ctx->sysreg, data->clk_sysreg_save, + data->nr_clk_sysreg); + for (i = 0; i < data->nr_pclks; i++) clk_prepare_enable(data->pclks[i]); /* For suspend some registers have to be set to certain values */ - samsung_clk_restore(data->ctx->reg_base, data->clk_suspend, + samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_suspend, data->nr_clk_suspend); for (i = 0; i < data->nr_pclks; i++) @@ -308,9 +367,14 @@ int exynos_arm64_cmu_resume(struct device *dev) for (i = 0; i < data->nr_pclks; i++) clk_prepare_enable(data->pclks[i]); - samsung_clk_restore(data->ctx->reg_base, data->clk_save, + samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_save, data->nr_clk_save); + if (data->ctx->sysreg) + samsung_clk_restore(NULL, data->ctx->sysreg, + data->clk_sysreg_save, + data->nr_clk_sysreg); + for (i = 0; i < data->nr_pclks; i++) clk_disable_unprepare(data->pclks[i]); diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index cc5c1644c41c..246bd28bac2d 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1361,12 +1361,12 @@ static void __init exynos4_clk_init(struct device_node *np, ARRAY_SIZE(exynos4x12_plls)); } - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4, np); if (exynos4_soc == EXYNOS4210) { - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210, np); } else { - samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12); + samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12, np); if (soc == EXYNOS4412) samsung_clk_register_cpu(ctx, exynos4412_cpu_clks, ARRAY_SIZE(exynos4412_cpu_clks)); @@ -1378,15 +1378,15 @@ static void __init exynos4_clk_init(struct device_node *np, if (soc == EXYNOS4212 || soc == EXYNOS4412) exynos4x12_core_down_clock(); - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs), src_mask_suspend, ARRAY_SIZE(src_mask_suspend)); if (exynos4_soc == EXYNOS4210) - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save), src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210)); else - samsung_clk_sleep_init(reg_base, exynos4x12_clk_save, + samsung_clk_sleep_init(reg_base, NULL, exynos4x12_clk_save, ARRAY_SIZE(exynos4x12_clk_save)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk-exynos4412-isp.c b/drivers/clk/samsung/clk-exynos4412-isp.c index fa915057e109..772bc18a1e68 100644 --- a/drivers/clk/samsung/clk-exynos4412-isp.c +++ b/drivers/clk/samsung/clk-exynos4412-isp.c @@ -94,7 +94,7 @@ static int __maybe_unused exynos4x12_isp_clk_suspend(struct device *dev) { struct samsung_clk_provider *ctx = dev_get_drvdata(dev); - samsung_clk_save(ctx->reg_base, exynos4x12_save_isp, + samsung_clk_save(ctx->reg_base, NULL, exynos4x12_save_isp, ARRAY_SIZE(exynos4x12_clk_isp_save)); return 0; } @@ -103,7 +103,7 @@ static int __maybe_unused exynos4x12_isp_clk_resume(struct device *dev) { struct samsung_clk_provider *ctx = dev_get_drvdata(dev); - samsung_clk_restore(ctx->reg_base, exynos4x12_save_isp, + samsung_clk_restore(ctx->reg_base, NULL, exynos4x12_save_isp, ARRAY_SIZE(exynos4x12_clk_isp_save)); return 0; } diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e90d3a0848cb..f97f30b29be7 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -854,7 +854,7 @@ static void __init exynos5250_clk_init(struct device_node *np) PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO); __raw_writel(tmp, reg_base + PWR_CTRL2); - samsung_clk_sleep_init(reg_base, exynos5250_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, exynos5250_clk_regs, ARRAY_SIZE(exynos5250_clk_regs)); exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5250_subcmus), exynos5250_subcmus); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a9df4e6db82f..1982e0751cee 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -1649,12 +1649,12 @@ static void __init exynos5x_clk_init(struct device_node *np, ARRAY_SIZE(exynos5800_cpu_clks)); } - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs), exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc)); if (soc == EXYNOS5800) { - samsung_clk_sleep_init(reg_base, exynos5800_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, exynos5800_clk_regs, ARRAY_SIZE(exynos5800_clk_regs)); exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5800_subcmus), diff --git a/drivers/clk/samsung/clk-exynosautov920.c b/drivers/clk/samsung/clk-exynosautov920.c index b90b73c3518f..d0617c7fff3a 100644 --- a/drivers/clk/samsung/clk-exynosautov920.c +++ b/drivers/clk/samsung/clk-exynosautov920.c @@ -29,6 +29,7 @@ #define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1) #define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1) #define CLKS_NR_MFC (CLK_DOUT_MFC_NOCP + 1) +#define CLKS_NR_MFD (CLK_DOUT_MFD_NOCP + 1) /* ---- CMU_TOP ------------------------------------------------------------ */ @@ -1905,6 +1906,42 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = { .clk_name = "noc", }; +/* ---- CMU_MFD --------------------------------------------------------- */ + +/* Register Offset definitions for CMU_MFD (0x19e00000) */ +#define PLL_CON0_MUX_CLKCMU_MFD_NOC_USER 0x600 +#define CLK_CON_DIV_DIV_CLK_MFD_NOCP 0x1800 + +static const unsigned long mfd_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_MFD_NOC_USER, + CLK_CON_DIV_DIV_CLK_MFD_NOCP, +}; + +/* List of parent clocks for Muxes in CMU_MFD */ +PNAME(mout_clkcmu_mfd_noc_user_p) = { "oscclk", "dout_clkcmu_mfd_noc" }; + +static const struct samsung_mux_clock mfd_mux_clks[] __initconst = { + MUX(CLK_MOUT_MFD_NOC_USER, "mout_clkcmu_mfd_noc_user", + mout_clkcmu_mfd_noc_user_p, PLL_CON0_MUX_CLKCMU_MFD_NOC_USER, 4, 1), +}; + +static const struct samsung_div_clock mfd_div_clks[] __initconst = { + DIV(CLK_DOUT_MFD_NOCP, "dout_mfd_nocp", + "mout_clkcmu_mfd_noc_user", CLK_CON_DIV_DIV_CLK_MFD_NOCP, + 0, 3), +}; + +static const struct samsung_cmu_info mfd_cmu_info __initconst = { + .mux_clks = mfd_mux_clks, + .nr_mux_clks = ARRAY_SIZE(mfd_mux_clks), + .div_clks = mfd_div_clks, + .nr_div_clks = ARRAY_SIZE(mfd_div_clks), + .nr_clk_ids = CLKS_NR_MFD, + .clk_regs = mfd_clk_regs, + .nr_clk_regs = ARRAY_SIZE(mfd_clk_regs), + .clk_name = "noc", +}; + static int __init exynosautov920_cmu_probe(struct platform_device *pdev) { const struct samsung_cmu_info *info; @@ -1941,6 +1978,9 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { }, { .compatible = "samsung,exynosautov920-cmu-mfc", .data = &mfc_cmu_info, + }, { + .compatible = "samsung,exynosautov920-cmu-mfd", + .data = &mfd_cmu_info, }, { } }; diff --git a/drivers/clk/samsung/clk-gs101.c b/drivers/clk/samsung/clk-gs101.c index 70b26db9b95a..44a8ecd332fd 100644 --- a/drivers/clk/samsung/clk-gs101.c +++ b/drivers/clk/samsung/clk-gs101.c @@ -20,12 +20,17 @@ /* NOTE: Must be equal to the last clock ID increased by one */ #define CLKS_NR_TOP (CLK_GOUT_CMU_TPU_UART + 1) #define CLKS_NR_APM (CLK_APM_PLL_DIV16_APM + 1) +#define CLKS_NR_DPU (CLK_GOUT_DPU_SYSREG_DPU_PCLK + 1) #define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_P_HSI0_ACLK + 1) #define CLKS_NR_HSI2 (CLK_GOUT_HSI2_XIU_P_HSI2_ACLK + 1) #define CLKS_NR_MISC (CLK_GOUT_MISC_XIU_D_MISC_ACLK + 1) #define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK + 1) #define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK + 1) +#define GS101_GATE_DBG_OFFSET 0x4000 +#define GS101_DRCG_EN_OFFSET 0x104 +#define GS101_MEMCLK_OFFSET 0x108 + /* ---- CMU_TOP ------------------------------------------------------------- */ /* Register Offset definitions for CMU_TOP (0x1e080000) */ @@ -1433,6 +1438,9 @@ static const struct samsung_cmu_info top_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_TOP, .clk_regs = cmu_top_clk_regs, .nr_clk_regs = ARRAY_SIZE(cmu_top_clk_regs), + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = CMU_CMU_TOP_CONTROLLER_OPTION, }; static void __init gs101_cmu_top_init(struct device_node *np) @@ -1900,6 +1908,11 @@ static const struct samsung_gate_clock apm_gate_clks[] __initconst = { CLK_CON_GAT_GOUT_BLK_APM_UID_XIU_DP_APM_IPCLKPORT_ACLK, 21, CLK_IS_CRITICAL, 0), }; +static const unsigned long dcrg_memclk_sysreg[] __initconst = { + GS101_DRCG_EN_OFFSET, + GS101_MEMCLK_OFFSET, +}; + static const struct samsung_cmu_info apm_cmu_info __initconst = { .mux_clks = apm_mux_clks, .nr_mux_clks = ARRAY_SIZE(apm_mux_clks), @@ -1912,6 +1925,291 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_APM, .clk_regs = apm_clk_regs, .nr_clk_regs = ARRAY_SIZE(apm_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, +}; + +/* ---- CMU_DPU ------------------------------------------------------------- */ + +/* Register Offset definitions for CMU_DPU (0x1c000000) */ +#define PLL_CON0_MUX_CLKCMU_DPU_BUS_USER 0x0600 +#define PLL_CON1_MUX_CLKCMU_DPU_BUS_USER 0x0604 +#define DPU_CMU_DPU_CONTROLLER_OPTION 0x0800 +#define CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0 0x0810 +#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800 +#define CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK 0x2000 +#define CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK 0x2004 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM 0x2008 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA 0x200c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP 0x2010 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK 0x2014 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK 0x2018 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK 0x201c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK 0x2020 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK 0x2024 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK 0x2028 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK 0x202c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK 0x2030 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK 0x2034 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK 0x2038 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK 0x203c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK 0x2040 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK 0x2044 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK 0x2048 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK 0x204c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK 0x2050 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK 0x2054 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK 0x2058 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK 0x205c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK 0x2060 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1 0x2064 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2 0x2068 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1 0x206c +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2 0x2070 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1 0x2074 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2 0x2078 +#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK 0x207c +#define PCH_CON_LHM_AXI_P_DPU_PCH 0x3000 +#define PCH_CON_LHS_AXI_D0_DPU_PCH 0x3004 +#define PCH_CON_LHS_AXI_D1_DPU_PCH 0x3008 +#define PCH_CON_LHS_AXI_D2_DPU_PCH 0x300c +#define QCH_CON_DPUF_QCH_DPU_DMA 0x3010 +#define QCH_CON_DPUF_QCH_DPU_DPP 0x3014 +#define QCH_CON_DPU_CMU_DPU_QCH 0x301c +#define QCH_CON_D_TZPC_DPU_QCH 0x3020 +#define QCH_CON_GPC_DPU_QCH 0x3024 +#define QCH_CON_LHM_AXI_P_DPU_QCH 0x3028 +#define QCH_CON_LHS_AXI_D0_DPU_QCH 0x302c +#define QCH_CON_LHS_AXI_D1_DPU_QCH 0x3030 +#define QCH_CON_LHS_AXI_D2_DPU_QCH 0x3034 +#define QCH_CON_PPMU_DPUD0_QCH 0x3038 +#define QCH_CON_PPMU_DPUD1_QCH 0x303c +#define QCH_CON_PPMU_DPUD2_QCH 0x3040 +#define QCH_CON_SSMT_DPU0_QCH 0x3044 +#define QCH_CON_SSMT_DPU1_QCH 0x3048 +#define QCH_CON_SSMT_DPU2_QCH 0x304c +#define QCH_CON_SYSMMU_DPUD0_QCH_S1 0x3050 +#define QCH_CON_SYSMMU_DPUD0_QCH_S2 0x3054 +#define QCH_CON_SYSMMU_DPUD1_QCH_S1 0x3058 +#define QCH_CON_SYSMMU_DPUD1_QCH_S2 0x305c +#define QCH_CON_SYSMMU_DPUD2_QCH_S1 0x3060 +#define QCH_CON_SYSMMU_DPUD2_QCH_S2 0x3064 +#define QCH_CON_SYSREG_DPU_QCH 0x3068 +#define QUEUE_CTRL_REG_BLK_DPU_CMU_DPU 0x3c00 + +static const unsigned long dpu_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_DPU_BUS_USER, + PLL_CON1_MUX_CLKCMU_DPU_BUS_USER, + DPU_CMU_DPU_CONTROLLER_OPTION, + CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0, + CLK_CON_DIV_DIV_CLK_DPU_BUSP, + CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM, + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA, + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP, + CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2, + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK, + PCH_CON_LHM_AXI_P_DPU_PCH, + PCH_CON_LHS_AXI_D0_DPU_PCH, + PCH_CON_LHS_AXI_D1_DPU_PCH, + PCH_CON_LHS_AXI_D2_DPU_PCH, + QCH_CON_DPUF_QCH_DPU_DMA, + QCH_CON_DPUF_QCH_DPU_DPP, + QCH_CON_DPU_CMU_DPU_QCH, + QCH_CON_D_TZPC_DPU_QCH, + QCH_CON_GPC_DPU_QCH, + QCH_CON_LHM_AXI_P_DPU_QCH, + QCH_CON_LHS_AXI_D0_DPU_QCH, + QCH_CON_LHS_AXI_D1_DPU_QCH, + QCH_CON_LHS_AXI_D2_DPU_QCH, + QCH_CON_PPMU_DPUD0_QCH, + QCH_CON_PPMU_DPUD1_QCH, + QCH_CON_PPMU_DPUD2_QCH, + QCH_CON_SSMT_DPU0_QCH, + QCH_CON_SSMT_DPU1_QCH, + QCH_CON_SSMT_DPU2_QCH, + QCH_CON_SYSMMU_DPUD0_QCH_S1, + QCH_CON_SYSMMU_DPUD0_QCH_S2, + QCH_CON_SYSMMU_DPUD1_QCH_S1, + QCH_CON_SYSMMU_DPUD1_QCH_S2, + QCH_CON_SYSMMU_DPUD2_QCH_S1, + QCH_CON_SYSMMU_DPUD2_QCH_S2, + QCH_CON_SYSREG_DPU_QCH, + QUEUE_CTRL_REG_BLK_DPU_CMU_DPU, +}; + +/* List of parent clocks for Muxes in CMU_DPU */ +PNAME(mout_dpu_bus_user_p) = { "oscclk", "dout_cmu_dpu_bus" }; + +static const struct samsung_mux_clock dpu_mux_clks[] __initconst = { + MUX(CLK_MOUT_DPU_BUS_USER, "mout_dpu_bus_user", + mout_dpu_bus_user_p, PLL_CON0_MUX_CLKCMU_DPU_BUS_USER, 4, 1), +}; + +static const struct samsung_div_clock dpu_div_clks[] __initconst = { + DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_bus_user", + CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3), +}; + +static const struct samsung_gate_clock dpu_gate_clks[] __initconst = { + GATE(CLK_GOUT_DPU_PCLK, "gout_dpu_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_OSCCLK_CLK, "gout_dpu_clk_dpu_oscclk_clk", + "oscclk", + CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_AD_APB_DPU_DMA_PCLKM, "gout_dpu_ad_apb_dpu_dma_pclkm", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM, + 21, 0, 0), + GATE(CLK_GOUT_DPU_DPUF_ACLK_DMA, "gout_dpu_dpuf_aclk_dma", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA, 21, 0, 0), + GATE(CLK_GOUT_DPU_DPUF_ACLK_DPP, "gout_dpu_dpuf_aclk_dpp", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP, 21, 0, 0), + GATE(CLK_GOUT_DPU_D_TZPC_DPU_PCLK, "gout_dpu_d_tzpc_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_GPC_DPU_PCLK, "gout_dpu_gpc_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_LHM_AXI_P_DPU_I_CLK, "gout_dpu_lhm_axi_p_dpu_i_clk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D0_DPU_I_CLK, "gout_dpu_lhs_axi_d0_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D1_DPU_I_CLK, "gout_dpu_lhs_axi_d1_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_LHS_AXI_D2_DPU_I_CLK, "gout_dpu_lhs_axi_d2_dpu_i_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD0_ACLK, "gout_dpu_ppmu_dpud0_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD0_PCLK, "gout_dpu_ppmu_dpud0_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD1_ACLK, "gout_dpu_ppmu_dpud1_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD1_PCLK, "gout_dpu_ppmu_dpud1_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD2_ACLK, "gout_dpu_ppmu_dpud2_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_DPUD2_PCLK, "gout_dpu_ppmu_dpud2_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_BUSD_CLK, "gout_dpu_clk_dpu_busd_clk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_CLK_DPU_BUSP_CLK, "gout_dpu_clk_dpu_busp_clk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU0_ACLK, "gout_dpu_ssmt_dpu0_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU0_PCLK, "gout_dpu_ssmt_dpu0_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU1_ACLK, "gout_dpu_ssmt_dpu1_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU1_PCLK, "gout_dpu_ssmt_dpu1_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU2_ACLK, "gout_dpu_ssmt_dpu2_aclk", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SSMT_DPU2_PCLK, "gout_dpu_ssmt_dpu2_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S1, "gout_dpu_sysmmu_dpud0_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S2, "gout_dpu_sysmmu_dpud0_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S1, "gout_dpu_sysmmu_dpud1_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S2, "gout_dpu_sysmmu_dpud1_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S1, "gout_dpu_sysmmu_dpud2_clk_s1", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1, + 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S2, "gout_dpu_sysmmu_dpud2_clk_s2", + "mout_dpu_bus_user", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2, 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSREG_DPU_PCLK, "gout_dpu_sysreg_dpu_pclk", + "dout_dpu_busp", + CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK, 21, 0, 0), +}; + +static const struct samsung_cmu_info dpu_cmu_info __initconst = { + .mux_clks = dpu_mux_clks, + .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks), + .div_clks = dpu_div_clks, + .nr_div_clks = ARRAY_SIZE(dpu_div_clks), + .gate_clks = dpu_gate_clks, + .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks), + .nr_clk_ids = CLKS_NR_DPU, + .clk_regs = dpu_clk_regs, + .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), + .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = DPU_CMU_DPU_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, }; /* ---- CMU_HSI0 ------------------------------------------------------------ */ @@ -2375,7 +2673,14 @@ static const struct samsung_cmu_info hsi0_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_HSI0, .clk_regs = hsi0_clk_regs, .nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = HSI0_CMU_HSI0_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; /* ---- CMU_HSI2 ------------------------------------------------------------ */ @@ -2863,7 +3168,14 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_HSI2, .clk_regs = cmu_hsi2_clk_regs, .nr_clk_regs = ARRAY_SIZE(cmu_hsi2_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = HSI2_CMU_HSI2_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; /* ---- CMU_MISC ------------------------------------------------------------ */ @@ -3423,7 +3735,14 @@ static const struct samsung_cmu_info misc_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_MISC, .clk_regs = misc_clk_regs, .nr_clk_regs = ARRAY_SIZE(misc_clk_regs), + .sysreg_clk_regs = dcrg_memclk_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = MISC_CMU_MISC_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, + .memclk_offset = GS101_MEMCLK_OFFSET, }; static void __init gs101_cmu_misc_init(struct device_node *np) @@ -4010,6 +4329,10 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = { 21, 0, 0), }; +static const unsigned long dcrg_sysreg[] __initconst = { + GS101_DRCG_EN_OFFSET, +}; + static const struct samsung_cmu_info peric0_cmu_info __initconst = { .mux_clks = peric0_mux_clks, .nr_mux_clks = ARRAY_SIZE(peric0_mux_clks), @@ -4020,7 +4343,13 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_PERIC0, .clk_regs = peric0_clk_regs, .nr_clk_regs = ARRAY_SIZE(peric0_clk_regs), + .sysreg_clk_regs = dcrg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = PERIC0_CMU_PERIC0_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, }; /* ---- CMU_PERIC1 ---------------------------------------------------------- */ @@ -4368,7 +4697,13 @@ static const struct samsung_cmu_info peric1_cmu_info __initconst = { .nr_clk_ids = CLKS_NR_PERIC1, .clk_regs = peric1_clk_regs, .nr_clk_regs = ARRAY_SIZE(peric1_clk_regs), + .sysreg_clk_regs = dcrg_sysreg, + .nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg), .clk_name = "bus", + .auto_clock_gate = true, + .gate_dbg_offset = GS101_GATE_DBG_OFFSET, + .option_offset = PERIC1_CMU_PERIC1_CONTROLLER_OPTION, + .drcg_offset = GS101_DRCG_EN_OFFSET, }; /* ---- platform_driver ----------------------------------------------------- */ @@ -4388,6 +4723,9 @@ static const struct of_device_id gs101_cmu_of_match[] = { { .compatible = "google,gs101-cmu-apm", .data = &apm_cmu_info, + }, { + .compatible = "google,gs101-cmu-dpu", + .data = &dpu_cmu_info, }, { .compatible = "google,gs101-cmu-hsi0", .data = &hsi0_cmu_info, diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 0a8fc9649ae2..026ac556fa2e 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -1435,7 +1435,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct clk_init_data init; int ret, len; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) { pr_err("%s: could not allocate pll clk %s\n", __func__, pll_clk->name); diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 397a057af5d1..5a2d5a5703ff 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -449,10 +449,10 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, samsung_clk_register_alias(ctx, s3c64xx_clock_aliases, ARRAY_SIZE(s3c64xx_clock_aliases)); - samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s3c64xx_clk_regs, ARRAY_SIZE(s3c64xx_clk_regs)); if (!is_s3c6400) - samsung_clk_sleep_init(reg_base, s3c6410_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s3c6410_clk_regs, ARRAY_SIZE(s3c6410_clk_regs)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk-s5pv210.c b/drivers/clk/samsung/clk-s5pv210.c index 9a4217cc1908..4ee4f2b5efbc 100644 --- a/drivers/clk/samsung/clk-s5pv210.c +++ b/drivers/clk/samsung/clk-s5pv210.c @@ -782,7 +782,7 @@ static void __init __s5pv210_clk_init(struct device_node *np, samsung_clk_register_alias(ctx, s5pv210_aliases, ARRAY_SIZE(s5pv210_aliases)); - samsung_clk_sleep_init(reg_base, s5pv210_clk_regs, + samsung_clk_sleep_init(reg_base, NULL, s5pv210_clk_regs, ARRAY_SIZE(s5pv210_clk_regs)); samsung_clk_of_add_provider(np, ctx); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index c149ca6c2217..94b2bccc7d02 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -12,8 +12,10 @@ #include #include #include +#include #include #include +#include #include #include "clk.h" @@ -21,19 +23,29 @@ static LIST_HEAD(clock_reg_cache_list); void samsung_clk_save(void __iomem *base, + struct regmap *regmap, struct samsung_clk_reg_dump *rd, unsigned int num_regs) { - for (; num_regs > 0; --num_regs, ++rd) - rd->value = readl(base + rd->offset); + for (; num_regs > 0; --num_regs, ++rd) { + if (base) + rd->value = readl(base + rd->offset); + else if (regmap) + regmap_read(regmap, rd->offset, &rd->value); + } } void samsung_clk_restore(void __iomem *base, + struct regmap *regmap, const struct samsung_clk_reg_dump *rd, unsigned int num_regs) { - for (; num_regs > 0; --num_regs, ++rd) - writel(rd->value, base + rd->offset); + for (; num_regs > 0; --num_regs, ++rd) { + if (base) + writel(rd->value, base + rd->offset); + else if (regmap) + regmap_write(regmap, rd->offset, rd->value); + } } struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( @@ -43,7 +55,7 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( struct samsung_clk_reg_dump *rd; unsigned int i; - rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL); + rd = kzalloc_objs(*rd, nr_rdump); if (!rd) return NULL; @@ -70,7 +82,7 @@ struct samsung_clk_provider * __init samsung_clk_init(struct device *dev, struct samsung_clk_provider *ctx; int i; - ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_clks), GFP_KERNEL); + ctx = kzalloc_flex(*ctx, clk_data.hws, nr_clks); if (!ctx) panic("could not allocate clock provider context.\n"); @@ -227,6 +239,103 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, } } +/* + * Some older DT's have an incorrect CMU resource size which is incompatible + * with the auto clock mode feature. In such cases we switch back to manual + * clock gating mode. + */ +bool samsung_is_auto_capable(struct device_node *np) +{ + struct resource res; + resource_size_t size; + + if (of_address_to_resource(np, 0, &res)) + return false; + + size = resource_size(&res); + if (size != 0x10000) { + pr_warn("%pOF: incorrect res size for automatic clocks\n", np); + return false; + } + return true; +} + +#define ACG_MSK GENMASK(6, 4) +#define CLK_IDLE GENMASK(5, 4) +static int samsung_auto_clk_gate_is_en(struct clk_hw *hw) +{ + u32 reg; + struct clk_gate *gate = to_clk_gate(hw); + + reg = readl(gate->reg); + return ((reg & ACG_MSK) == CLK_IDLE) ? 0 : 1; +} + +/* enable and disable are nops in automatic clock mode */ +static int samsung_auto_clk_gate_en(struct clk_hw *hw) +{ + return 0; +} + +static void samsung_auto_clk_gate_dis(struct clk_hw *hw) +{ +} + +static const struct clk_ops samsung_auto_clk_gate_ops = { + .enable = samsung_auto_clk_gate_en, + .disable = samsung_auto_clk_gate_dis, + .is_enabled = samsung_auto_clk_gate_is_en, +}; + +struct clk_hw *samsung_register_auto_gate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, + unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock) +{ + struct clk_gate *gate; + struct clk_hw *hw; + struct clk_init_data init = {}; + int ret = -EINVAL; + + /* allocate the gate */ + gate = kzalloc_obj(*gate); + if (!gate) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &samsung_auto_clk_gate_ops; + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.parent_hws = parent_hw ? &parent_hw : NULL; + init.parent_data = parent_data; + if (parent_name || parent_hw || parent_data) + init.num_parents = 1; + else + init.num_parents = 0; + + /* struct clk_gate assignments */ + gate->reg = reg; + gate->bit_idx = bit_idx; + gate->flags = clk_gate_flags; + gate->lock = lock; + gate->hw.init = &init; + + hw = &gate->hw; + if (dev || !np) + ret = clk_hw_register(dev, hw); + else if (np) + ret = of_clk_hw_register(np, hw); + if (ret) { + kfree(gate); + hw = ERR_PTR(ret); + } + + return hw; +} + /* register a list of gate clocks */ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, const struct samsung_gate_clock *list, @@ -234,14 +343,24 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, { struct clk_hw *clk_hw; unsigned int idx; + void __iomem *reg_offs; for (idx = 0; idx < nr_clk; idx++, list++) { - clk_hw = clk_hw_register_gate(ctx->dev, list->name, list->parent_name, - list->flags, ctx->reg_base + list->offset, + reg_offs = ctx->reg_base + list->offset; + + if (ctx->auto_clock_gate && ctx->gate_dbg_offset) + clk_hw = samsung_register_auto_gate(ctx->dev, NULL, + list->name, list->parent_name, NULL, NULL, + list->flags, reg_offs + ctx->gate_dbg_offset, list->bit_idx, list->gate_flags, &ctx->lock); + else + clk_hw = clk_hw_register_gate(ctx->dev, list->name, + list->parent_name, list->flags, + ctx->reg_base + list->offset, list->bit_idx, + list->gate_flags, &ctx->lock); if (IS_ERR(clk_hw)) { - pr_err("%s: failed to register clock %s\n", __func__, - list->name); + pr_err("%s: failed to register clock %s: %ld\n", __func__, + list->name, PTR_ERR(clk_hw)); continue; } @@ -276,10 +395,11 @@ static int samsung_clk_suspend(void *data) struct samsung_clock_reg_cache *reg_cache; list_for_each_entry(reg_cache, &clock_reg_cache_list, node) { - samsung_clk_save(reg_cache->reg_base, reg_cache->rdump, - reg_cache->rd_num); - samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend, - reg_cache->rsuspend_num); + samsung_clk_save(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rdump, reg_cache->rd_num); + samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rsuspend, + reg_cache->rsuspend_num); } return 0; } @@ -289,8 +409,8 @@ static void samsung_clk_resume(void *data) struct samsung_clock_reg_cache *reg_cache; list_for_each_entry(reg_cache, &clock_reg_cache_list, node) - samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump, - reg_cache->rd_num); + samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg, + reg_cache->rdump, reg_cache->rd_num); } static const struct syscore_ops samsung_clk_syscore_ops = { @@ -303,6 +423,7 @@ static struct syscore samsung_clk_syscore = { }; void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, @@ -310,8 +431,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, { struct samsung_clock_reg_cache *reg_cache; - reg_cache = kzalloc(sizeof(struct samsung_clock_reg_cache), - GFP_KERNEL); + reg_cache = kzalloc_obj(struct samsung_clock_reg_cache); if (!reg_cache) panic("could not allocate register reg_cache.\n"); reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); @@ -323,6 +443,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, register_syscore(&samsung_clk_syscore); reg_cache->reg_base = reg_base; + reg_cache->sysreg = sysreg; reg_cache->rd_num = nr_rdump; reg_cache->rsuspend = rsuspend; reg_cache->rsuspend_num = nr_rsuspend; @@ -334,10 +455,20 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base, * samsung_cmu_register_clocks() - Register all clocks provided in CMU object * @ctx: Clock provider object * @cmu: CMU object with clocks to register + * @np: CMU device tree node */ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu) + const struct samsung_cmu_info *cmu, + struct device_node *np) { + if (cmu->auto_clock_gate && samsung_is_auto_capable(np)) + ctx->auto_clock_gate = cmu->auto_clock_gate; + + ctx->gate_dbg_offset = cmu->gate_dbg_offset; + ctx->option_offset = cmu->option_offset; + ctx->drcg_offset = cmu->drcg_offset; + ctx->memclk_offset = cmu->memclk_offset; + if (cmu->pll_clks) samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks); if (cmu->mux_clks) @@ -357,6 +488,44 @@ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks); } +/* Each bit enable/disables DRCG of a bus component */ +#define DRCG_EN_MSK GENMASK(31, 0) +#define MEMCLK_EN BIT(0) + +/* Enable Dynamic Root Clock Gating (DRCG) of bus components */ +void samsung_en_dyn_root_clk_gating(struct device_node *np, + struct samsung_clk_provider *ctx, + const struct samsung_cmu_info *cmu, + bool cmu_has_pm) +{ + if (!ctx->auto_clock_gate) + return; + + ctx->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg"); + if (IS_ERR(ctx->sysreg)) { + pr_warn("%pOF: Unable to get CMU sysreg\n", np); + ctx->sysreg = NULL; + } else { + /* Enable DRCG for all bus components */ + regmap_write(ctx->sysreg, ctx->drcg_offset, DRCG_EN_MSK); + /* Enable memclk gate (not present on all sysreg) */ + if (ctx->memclk_offset) + regmap_write_bits(ctx->sysreg, ctx->memclk_offset, + MEMCLK_EN, 0x0); + + if (!cmu_has_pm) + /* + * When a CMU has PM support, clocks are saved/restored + * via its PM handlers, so only register them with the + * syscore suspend / resume paths if PM is not in use. + */ + samsung_clk_extended_sleep_init(NULL, ctx->sysreg, + cmu->sysreg_clk_regs, + cmu->nr_sysreg_clk_regs, + NULL, 0); + } +} + /* * Common function which registers plls, muxes, dividers and gates * for each CMU. It also add CMU register list to register cache. @@ -375,14 +544,17 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( } ctx = samsung_clk_init(NULL, reg_base, cmu->nr_clk_ids); - samsung_cmu_register_clocks(ctx, cmu); + samsung_cmu_register_clocks(ctx, cmu, np); if (cmu->clk_regs) - samsung_clk_extended_sleep_init(reg_base, + samsung_clk_extended_sleep_init(reg_base, NULL, cmu->clk_regs, cmu->nr_clk_regs, cmu->suspend_regs, cmu->nr_suspend_regs); samsung_clk_of_add_provider(np, ctx); + /* sysreg DT nodes reference a clock in this CMU */ + samsung_en_dyn_root_clk_gating(np, ctx, cmu, false); + return ctx; } diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index 18660c1ac6f0..b1192ca03db5 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -12,6 +12,7 @@ #include #include +#include #include "clk-pll.h" #include "clk-cpu.h" @@ -19,13 +20,25 @@ * struct samsung_clk_provider - information about clock provider * @reg_base: virtual address for the register base * @dev: clock provider device needed for runtime PM + * @sysreg: syscon regmap for clock-provider sysreg controller * @lock: maintains exclusion between callbacks for a given clock-provider + * @auto_clock_gate: enable auto clk mode for all clocks in clock-provider + * @gate_dbg_offset: gate debug reg offset. Used for all gates in auto clk mode + * @option_offset: option reg offset. Enables auto mode for clock-provider + * @drcg_offset: dynamic root clk gate enable register offset in sysreg + * @memclk_offset: memclk enable register offset in sysreg * @clk_data: holds clock related data like clk_hw* and number of clocks */ struct samsung_clk_provider { void __iomem *reg_base; struct device *dev; + struct regmap *sysreg; spinlock_t lock; + bool auto_clock_gate; + u32 gate_dbg_offset; + u32 option_offset; + u32 drcg_offset; + u32 memclk_offset; /* clk_data must be the last entry due to variable length 'hws' array */ struct clk_hw_onecell_data clk_data; }; @@ -310,6 +323,7 @@ struct samsung_cpu_clock { struct samsung_clock_reg_cache { struct list_head node; void __iomem *reg_base; + struct regmap *sysreg; struct samsung_clk_reg_dump *rdump; unsigned int rd_num; const struct samsung_clk_reg_dump *rsuspend; @@ -338,7 +352,14 @@ struct samsung_clock_reg_cache { * @suspend_regs: list of clock registers to set before suspend * @nr_suspend_regs: count of clock registers in @suspend_regs * @clk_name: name of the parent clock needed for CMU register access + * @sysreg_clk_regs: list of sysreg clock registers + * @nr_sysreg_clk_regs: count of clock registers in @sysreg_clk_regs * @manual_plls: Enable manual control for PLL clocks + * @auto_clock_gate: enable auto clock mode for all components in CMU + * @gate_dbg_offset: gate debug reg offset. Used by all gates in auto clk mode + * @option_offset: option reg offset. Enables auto clk mode for entire CMU + * @drcg_offset: dynamic root clk gate enable register offset in sysreg + * @memclk_offset: memclk enable register offset in sysreg */ struct samsung_cmu_info { const struct samsung_pll_clock *pll_clks; @@ -364,8 +385,16 @@ struct samsung_cmu_info { unsigned int nr_suspend_regs; const char *clk_name; + const unsigned long *sysreg_clk_regs; + unsigned int nr_sysreg_clk_regs; + /* ARM64 Exynos CMUs */ bool manual_plls; + bool auto_clock_gate; + u32 gate_dbg_offset; + u32 option_offset; + u32 drcg_offset; + u32 memclk_offset; }; struct samsung_clk_provider *samsung_clk_init(struct device *dev, @@ -408,35 +437,56 @@ void samsung_clk_register_cpu(struct samsung_clk_provider *ctx, const struct samsung_cpu_clock *list, unsigned int nr_clk); void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx, - const struct samsung_cmu_info *cmu); + const struct samsung_cmu_info *cmu, + struct device_node *np); struct samsung_clk_provider *samsung_cmu_register_one( struct device_node *, const struct samsung_cmu_info *); #ifdef CONFIG_PM_SLEEP void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, unsigned long nr_rsuspend); #else static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base, + struct regmap *sysreg, const unsigned long *rdump, unsigned long nr_rdump, const struct samsung_clk_reg_dump *rsuspend, unsigned long nr_rsuspend) {} #endif -#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \ - samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0) +#define samsung_clk_sleep_init(reg_base, sysreg, rdump, nr_rdump) \ + samsung_clk_extended_sleep_init(reg_base, sysreg, rdump, nr_rdump, \ + NULL, 0) void samsung_clk_save(void __iomem *base, + struct regmap *regmap, struct samsung_clk_reg_dump *rd, unsigned int num_regs); void samsung_clk_restore(void __iomem *base, + struct regmap *regmap, const struct samsung_clk_reg_dump *rd, unsigned int num_regs); struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( const unsigned long *rdump, unsigned long nr_rdump); +void samsung_en_dyn_root_clk_gating(struct device_node *np, + struct samsung_clk_provider *ctx, + const struct samsung_cmu_info *cmu, + bool cmu_has_pm); + +struct clk_hw *samsung_register_auto_gate(struct device *dev, + struct device_node *np, const char *name, + const char *parent_name, const struct clk_hw *parent_hw, + const struct clk_parent_data *parent_data, + unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock); + +bool samsung_is_auto_capable(struct device_node *np); + #endif /* __SAMSUNG_CLK_H */ diff --git a/drivers/clk/socfpga/clk-gate-a10.c b/drivers/clk/socfpga/clk-gate-a10.c index 06f129c160bc..dd8d1713aaff 100644 --- a/drivers/clk/socfpga/clk-gate-a10.c +++ b/drivers/clk/socfpga/clk-gate-a10.c @@ -52,7 +52,7 @@ static void __init __socfpga_gate_init(struct device_node *node, struct clk_init_data init; int rc; - socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + socfpga_clk = kzalloc_obj(*socfpga_clk); if (WARN_ON(!socfpga_clk)) return; diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index dce3ef137bf3..24f56a9edc44 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -132,7 +132,7 @@ struct clk_hw *s10_register_gate(const struct stratix10_gate_clock *clks, void _ const char *parent_name = clks->parent_name; int ret; - socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + socfpga_clk = kzalloc_obj(*socfpga_clk); if (!socfpga_clk) return NULL; @@ -190,7 +190,7 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi const char *parent_name = clks->parent_name; int ret; - socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + socfpga_clk = kzalloc_obj(*socfpga_clk); if (!socfpga_clk) return NULL; @@ -247,7 +247,7 @@ struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void struct clk_init_data init; int ret; - socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + socfpga_clk = kzalloc_obj(*socfpga_clk); if (!socfpga_clk) return NULL; diff --git a/drivers/clk/socfpga/clk-gate.c b/drivers/clk/socfpga/clk-gate.c index 0a5a95e0267f..ced8e0988406 100644 --- a/drivers/clk/socfpga/clk-gate.c +++ b/drivers/clk/socfpga/clk-gate.c @@ -147,7 +147,7 @@ void __init socfpga_gate_init(struct device_node *node) struct clk_ops *ops; int rc; - socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); + socfpga_clk = kzalloc_obj(*socfpga_clk); if (WARN_ON(!socfpga_clk)) return; diff --git a/drivers/clk/socfpga/clk-periph-a10.c b/drivers/clk/socfpga/clk-periph-a10.c index 64cc70b970b7..4eb5787f0dea 100644 --- a/drivers/clk/socfpga/clk-periph-a10.c +++ b/drivers/clk/socfpga/clk-periph-a10.c @@ -72,7 +72,7 @@ static void __init __socfpga_periph_init(struct device_node *node, of_property_read_u32(node, "reg", ®); - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return; diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index f12ca43ffe7c..5195b9476da1 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -108,7 +108,7 @@ struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks, const char *parent_name = clks->parent_name; int ret; - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return NULL; @@ -144,7 +144,7 @@ struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks, const char *parent_name = clks->parent_name; int ret; - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return NULL; @@ -179,7 +179,7 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c const char *parent_name = clks->parent_name; int ret; - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return NULL; @@ -224,7 +224,7 @@ struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock const char *name = clks->name; int ret; - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return NULL; diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c index 6a4075147b9c..3821db6777e7 100644 --- a/drivers/clk/socfpga/clk-periph.c +++ b/drivers/clk/socfpga/clk-periph.c @@ -62,7 +62,7 @@ static void __init __socfpga_periph_init(struct device_node *node, of_property_read_u32(node, "reg", ®); - periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); + periph_clk = kzalloc_obj(*periph_clk); if (WARN_ON(!periph_clk)) return; diff --git a/drivers/clk/socfpga/clk-pll-a10.c b/drivers/clk/socfpga/clk-pll-a10.c index 62eed964c3d0..c56f276e8d51 100644 --- a/drivers/clk/socfpga/clk-pll-a10.c +++ b/drivers/clk/socfpga/clk-pll-a10.c @@ -78,7 +78,7 @@ static void __init __socfpga_pll_init(struct device_node *node, of_property_read_u32(node, "reg", ®); - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return; diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index 1be92827cd93..ee236e87da33 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -196,7 +196,7 @@ struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks, const char *name = clks->name; int ret; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return NULL; @@ -236,7 +236,7 @@ struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks, const char *name = clks->name; int ret; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return NULL; @@ -275,7 +275,7 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks, const char *name = clks->name; int ret; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return NULL; @@ -314,7 +314,7 @@ struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks, const char *name = clks->name; int ret; - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return NULL; diff --git a/drivers/clk/socfpga/clk-pll.c b/drivers/clk/socfpga/clk-pll.c index 03a96139a576..f85adb16d414 100644 --- a/drivers/clk/socfpga/clk-pll.c +++ b/drivers/clk/socfpga/clk-pll.c @@ -84,7 +84,7 @@ static void __init __socfpga_pll_init(struct device_node *node, of_property_read_u32(node, "reg", ®); - pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); + pll_clk = kzalloc_obj(*pll_clk); if (WARN_ON(!pll_clk)) return; diff --git a/drivers/clk/sophgo/clk-cv18xx-ip.c b/drivers/clk/sophgo/clk-cv18xx-ip.c index c2b58faf0938..e936e3154003 100644 --- a/drivers/clk/sophgo/clk-cv18xx-ip.c +++ b/drivers/clk/sophgo/clk-cv18xx-ip.c @@ -152,28 +152,27 @@ static u32 div_helper_get_clockdiv(struct cv1800_clk_common *common, return clockdiv; } -static u32 div_helper_round_rate(struct cv1800_clk_regfield *div, - struct clk_hw *hw, struct clk_hw *parent, - unsigned long rate, unsigned long *prate) +static int div_helper_determine_rate(struct cv1800_clk_regfield *div, + struct clk_hw *hw, + struct clk_rate_request *req) { if (div->width == 0) { if (div->initval <= 0) - return DIV_ROUND_UP_ULL(*prate, 1); + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, 1); else - return DIV_ROUND_UP_ULL(*prate, div->initval); + req->rate = DIV_ROUND_UP_ULL(req->best_parent_rate, div->initval); + + return 0; } - return divider_round_rate_parent(hw, parent, rate, prate, NULL, - div->width, div->flags); + return divider_determine_rate(hw, req, NULL, div->width, div->flags); } -static long div_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_div_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_div *div = data; - return div_helper_round_rate(&div->div, &div->common.hw, parent, - rate, parent_rate); + return div_helper_determine_rate(&div->div, &div->common.hw, req); } static bool div_is_better_rate(struct cv1800_clk_common *common, @@ -188,53 +187,60 @@ static bool div_is_better_rate(struct cv1800_clk_common *common, static int mux_helper_determine_rate(struct cv1800_clk_common *common, struct clk_rate_request *req, - long (*round)(struct clk_hw *, - unsigned long *, - unsigned long, - int, - void *), + int (*round)(struct clk_rate_request *, + int, + void *), void *data) { unsigned long best_parent_rate = 0, best_rate = 0; struct clk_hw *best_parent, *hw = &common->hw; unsigned int i; + int ret; if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { - unsigned long adj_parent_rate; + struct clk_rate_request tmp_req = *req; best_parent = clk_hw_get_parent(hw); - best_parent_rate = clk_hw_get_rate(best_parent); + tmp_req.best_parent_hw = best_parent; + tmp_req.best_parent_rate = clk_hw_get_rate(best_parent); - best_rate = round(best_parent, &adj_parent_rate, - req->rate, -1, data); + ret = round(&tmp_req, -1, data); + if (ret) + return ret; + + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; goto find; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - unsigned long tmp_rate, parent_rate; + struct clk_rate_request tmp_req = *req; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); if (!parent) continue; - parent_rate = clk_hw_get_rate(parent); + tmp_req.best_parent_hw = parent; + tmp_req.best_parent_rate = clk_hw_get_rate(parent); - tmp_rate = round(parent, &parent_rate, req->rate, i, data); + ret = round(&tmp_req, i, data); + if (ret) + continue; - if (tmp_rate == req->rate) { + if (tmp_req.rate == req->rate) { best_parent = parent; - best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; goto find; } if (div_is_better_rate(common, req->rate, - tmp_rate, best_rate)) { + tmp_req.rate, best_rate)) { best_parent = parent; - best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_parent_rate = tmp_req.best_parent_rate; + best_rate = tmp_req.rate; } } @@ -254,7 +260,7 @@ static int div_determine_rate(struct clk_hw *hw, struct cv1800_clk_div *div = hw_to_cv1800_clk_div(hw); return mux_helper_determine_rate(&div->common, req, - div_round_rate, div); + do_div_determine_rate, div); } static unsigned long div_recalc_rate(struct clk_hw *hw, @@ -301,24 +307,28 @@ hw_to_cv1800_clk_bypass_div(struct clk_hw *hw) return container_of(div, struct cv1800_clk_bypass_div, div); } -static long bypass_div_round_rate(struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_bypass_div_determine_rate(struct clk_rate_request *req, int id, + void *data) { struct cv1800_clk_bypass_div *div = data; if (id == -1) { - if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) - return *parent_rate; - else - return div_round_rate(parent, parent_rate, rate, - -1, &div->div); + if (cv1800_clk_checkbit(&div->div.common, &div->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } + + return do_div_determine_rate(req, -1, &div->div); } - if (id == 0) - return *parent_rate; + if (id == 0) { + req->rate = req->best_parent_rate; - return div_round_rate(parent, parent_rate, rate, id - 1, &div->div); + return 0; + } + + return do_div_determine_rate(req, id - 1, &div->div); } static int bypass_div_determine_rate(struct clk_hw *hw, @@ -327,7 +337,7 @@ static int bypass_div_determine_rate(struct clk_hw *hw, struct cv1800_clk_bypass_div *div = hw_to_cv1800_clk_bypass_div(hw); return mux_helper_determine_rate(&div->div.common, req, - bypass_div_round_rate, div); + do_bypass_div_determine_rate, div); } static unsigned long bypass_div_recalc_rate(struct clk_hw *hw, @@ -414,13 +424,11 @@ static int mux_is_enabled(struct clk_hw *hw) return cv1800_clk_checkbit(&mux->common, &mux->gate); } -static long mux_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_mux_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_mux *mux = data; - return div_helper_round_rate(&mux->div, &mux->common.hw, parent, - rate, parent_rate); + return div_helper_determine_rate(&mux->div, &mux->common.hw, req); } static int mux_determine_rate(struct clk_hw *hw, @@ -429,7 +437,7 @@ static int mux_determine_rate(struct clk_hw *hw, struct cv1800_clk_mux *mux = hw_to_cv1800_clk_mux(hw); return mux_helper_determine_rate(&mux->common, req, - mux_round_rate, mux); + do_mux_determine_rate, mux); } static unsigned long mux_recalc_rate(struct clk_hw *hw, @@ -512,24 +520,28 @@ hw_to_cv1800_clk_bypass_mux(struct clk_hw *hw) return container_of(mux, struct cv1800_clk_bypass_mux, mux); } -static long bypass_mux_round_rate(struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_bypass_mux_determine_rate(struct clk_rate_request *req, int id, + void *data) { struct cv1800_clk_bypass_mux *mux = data; if (id == -1) { - if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) - return *parent_rate; - else - return mux_round_rate(parent, parent_rate, rate, - -1, &mux->mux); + if (cv1800_clk_checkbit(&mux->mux.common, &mux->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } + + return do_mux_determine_rate(req, -1, &mux->mux); } - if (id == 0) - return *parent_rate; + if (id == 0) { + req->rate = req->best_parent_rate; - return mux_round_rate(parent, parent_rate, rate, id - 1, &mux->mux); + return 0; + } + + return do_mux_determine_rate(req, id - 1, &mux->mux); } static int bypass_mux_determine_rate(struct clk_hw *hw, @@ -538,7 +550,7 @@ static int bypass_mux_determine_rate(struct clk_hw *hw, struct cv1800_clk_bypass_mux *mux = hw_to_cv1800_clk_bypass_mux(hw); return mux_helper_determine_rate(&mux->mux.common, req, - bypass_mux_round_rate, mux); + do_bypass_mux_determine_rate, mux); } static unsigned long bypass_mux_recalc_rate(struct clk_hw *hw, @@ -639,27 +651,31 @@ static int mmux_is_enabled(struct clk_hw *hw) return cv1800_clk_checkbit(&mmux->common, &mmux->gate); } -static long mmux_round_rate(struct clk_hw *parent, unsigned long *parent_rate, - unsigned long rate, int id, void *data) +static int do_mmux_determine_rate(struct clk_rate_request *req, int id, void *data) { struct cv1800_clk_mmux *mmux = data; s8 div_id; if (id == -1) { - if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) - return *parent_rate; + if (cv1800_clk_checkbit(&mmux->common, &mmux->bypass)) { + req->rate = req->best_parent_rate; + + return 0; + } id = mmux_get_parent_id(mmux); } div_id = mmux->parent2sel[id]; - if (div_id < 0) - return *parent_rate; + if (div_id < 0) { + req->rate = req->best_parent_rate; - return div_helper_round_rate(&mmux->div[div_id], - &mmux->common.hw, parent, - rate, parent_rate); + return 0; + } + + return div_helper_determine_rate(&mmux->div[div_id], &mmux->common.hw, + req); } static int mmux_determine_rate(struct clk_hw *hw, @@ -668,7 +684,7 @@ static int mmux_determine_rate(struct clk_hw *hw, struct cv1800_clk_mmux *mmux = hw_to_cv1800_clk_mmux(hw); return mux_helper_determine_rate(&mmux->common, req, - mmux_round_rate, mmux); + do_mmux_determine_rate, mmux); } static unsigned long mmux_recalc_rate(struct clk_hw *hw, diff --git a/drivers/clk/sophgo/clk-sg2042-clkgen.c b/drivers/clk/sophgo/clk-sg2042-clkgen.c index 683661b71787..9725ac4e050a 100644 --- a/drivers/clk/sophgo/clk-sg2042-clkgen.c +++ b/drivers/clk/sophgo/clk-sg2042-clkgen.c @@ -180,7 +180,6 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { struct sg2042_divider_clock *divider = to_sg2042_clk_divider(hw); - unsigned long ret_rate; u32 bestdiv; /* if read only, just return current value */ @@ -191,17 +190,13 @@ static int sg2042_clk_divider_determine_rate(struct clk_hw *hw, bestdiv = readl(divider->reg) >> divider->shift; bestdiv &= clk_div_mask(divider->width); } - ret_rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); - } else { - ret_rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, NULL, - divider->width, divider->div_flags); + req->rate = DIV_ROUND_UP_ULL((u64)req->best_parent_rate, bestdiv); + + return 0; } - pr_debug("--> %s: divider_round_rate: val = %ld\n", - clk_hw_get_name(hw), ret_rate); - req->rate = ret_rate; - - return 0; + return divider_determine_rate(hw, req, NULL, divider->width, + divider->div_flags); } static int sg2042_clk_divider_set_rate(struct clk_hw *hw, diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig index 3854f6ae6d0e..4ebe6aaa1980 100644 --- a/drivers/clk/spacemit/Kconfig +++ b/drivers/clk/spacemit/Kconfig @@ -1,19 +1,23 @@ # SPDX-License-Identifier: GPL-2.0-only -config SPACEMIT_CCU - tristate "Clock support for SpacemiT SoCs" +menu "Clock support for SpacemiT platforms" depends on ARCH_SPACEMIT || COMPILE_TEST + +config SPACEMIT_CCU + tristate select AUXILIARY_BUS select MFD_SYSCON - help - Say Y to enable clock controller unit support for SpacemiT SoCs. - -if SPACEMIT_CCU config SPACEMIT_K1_CCU tristate "Support for SpacemiT K1 SoC" - depends on ARCH_SPACEMIT || COMPILE_TEST + select SPACEMIT_CCU help Support for clock controller unit in SpacemiT K1 SoC. -endif +config SPACEMIT_K3_CCU + tristate "Support for SpacemiT K3 SoC" + select SPACEMIT_CCU + help + Support for clock controller unit in SpacemiT K3 SoC. + +endmenu diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile index 5ec6da61db98..0925eda384b4 100644 --- a/drivers/clk/spacemit/Makefile +++ b/drivers/clk/spacemit/Makefile @@ -1,5 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_SPACEMIT_K1_CCU) = spacemit-ccu-k1.o -spacemit-ccu-k1-y = ccu_pll.o ccu_mix.o ccu_ddn.o +obj-$(CONFIG_SPACEMIT_CCU) += spacemit-ccu.o +spacemit-ccu-y += ccu_common.o +spacemit-ccu-y += ccu_pll.o +spacemit-ccu-y += ccu_mix.o +spacemit-ccu-y += ccu_ddn.o + +obj-$(CONFIG_SPACEMIT_K1_CCU) += spacemit-ccu-k1.o spacemit-ccu-k1-y += ccu-k1.o + +obj-$(CONFIG_SPACEMIT_K3_CCU) += spacemit-ccu-k3.o +spacemit-ccu-k3-y += ccu-k3.o diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c index 4761bc1e3b6e..dee14d25f75d 100644 --- a/drivers/clk/spacemit/ccu-k1.c +++ b/drivers/clk/spacemit/ccu-k1.c @@ -5,15 +5,10 @@ */ #include -#include #include -#include -#include -#include #include #include #include -#include #include #include "ccu_common.h" @@ -23,14 +18,6 @@ #include -struct spacemit_ccu_data { - const char *reset_name; - struct clk_hw **hws; - size_t num; -}; - -static DEFINE_IDA(auxiliary_ids); - /* APBS clocks start, APBS region contains and only contains all PLL clocks */ /* @@ -802,7 +789,7 @@ static struct clk_hw *k1_ccu_mpmu_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_mpmu_data = { - .reset_name = "mpmu-reset", + .reset_name = "k1-mpmu-reset", .hws = k1_ccu_mpmu_hws, .num = ARRAY_SIZE(k1_ccu_mpmu_hws), }; @@ -913,7 +900,7 @@ static struct clk_hw *k1_ccu_apbc_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_apbc_data = { - .reset_name = "apbc-reset", + .reset_name = "k1-apbc-reset", .hws = k1_ccu_apbc_hws, .num = ARRAY_SIZE(k1_ccu_apbc_hws), }; @@ -984,184 +971,23 @@ static struct clk_hw *k1_ccu_apmu_hws[] = { }; static const struct spacemit_ccu_data k1_ccu_apmu_data = { - .reset_name = "apmu-reset", + .reset_name = "k1-apmu-reset", .hws = k1_ccu_apmu_hws, .num = ARRAY_SIZE(k1_ccu_apmu_hws), }; static const struct spacemit_ccu_data k1_ccu_rcpu_data = { - .reset_name = "rcpu-reset", + .reset_name = "k1-rcpu-reset", }; static const struct spacemit_ccu_data k1_ccu_rcpu2_data = { - .reset_name = "rcpu2-reset", + .reset_name = "k1-rcpu2-reset", }; static const struct spacemit_ccu_data k1_ccu_apbc2_data = { - .reset_name = "apbc2-reset", + .reset_name = "k1-apbc2-reset", }; -static int spacemit_ccu_register(struct device *dev, - struct regmap *regmap, - struct regmap *lock_regmap, - const struct spacemit_ccu_data *data) -{ - struct clk_hw_onecell_data *clk_data; - int i, ret; - - /* Nothing to do if the CCU does not implement any clocks */ - if (!data->hws) - return 0; - - clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num), - GFP_KERNEL); - if (!clk_data) - return -ENOMEM; - - clk_data->num = data->num; - - for (i = 0; i < data->num; i++) { - struct clk_hw *hw = data->hws[i]; - struct ccu_common *common; - const char *name; - - if (!hw) { - clk_data->hws[i] = ERR_PTR(-ENOENT); - continue; - } - - name = hw->init->name; - - common = hw_to_ccu_common(hw); - common->regmap = regmap; - common->lock_regmap = lock_regmap; - - ret = devm_clk_hw_register(dev, hw); - if (ret) { - dev_err(dev, "Cannot register clock %d - %s\n", - i, name); - return ret; - } - - clk_data->hws[i] = hw; - } - - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); - if (ret) - dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); - - return ret; -} - -static void spacemit_cadev_release(struct device *dev) -{ - struct auxiliary_device *adev = to_auxiliary_dev(dev); - - ida_free(&auxiliary_ids, adev->id); - kfree(to_spacemit_ccu_adev(adev)); -} - -static void spacemit_adev_unregister(void *data) -{ - struct auxiliary_device *adev = data; - - auxiliary_device_delete(adev); - auxiliary_device_uninit(adev); -} - -static int spacemit_ccu_reset_register(struct device *dev, - struct regmap *regmap, - const char *reset_name) -{ - struct spacemit_ccu_adev *cadev; - struct auxiliary_device *adev; - int ret; - - /* Nothing to do if the CCU does not implement a reset controller */ - if (!reset_name) - return 0; - - cadev = kzalloc(sizeof(*cadev), GFP_KERNEL); - if (!cadev) - return -ENOMEM; - - cadev->regmap = regmap; - - adev = &cadev->adev; - adev->name = reset_name; - adev->dev.parent = dev; - adev->dev.release = spacemit_cadev_release; - adev->dev.of_node = dev->of_node; - ret = ida_alloc(&auxiliary_ids, GFP_KERNEL); - if (ret < 0) - goto err_free_cadev; - adev->id = ret; - - ret = auxiliary_device_init(adev); - if (ret) - goto err_free_aux_id; - - ret = auxiliary_device_add(adev); - if (ret) { - auxiliary_device_uninit(adev); - return ret; - } - - return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev); - -err_free_aux_id: - ida_free(&auxiliary_ids, adev->id); -err_free_cadev: - kfree(cadev); - - return ret; -} - -static int k1_ccu_probe(struct platform_device *pdev) -{ - struct regmap *base_regmap, *lock_regmap = NULL; - const struct spacemit_ccu_data *data; - struct device *dev = &pdev->dev; - int ret; - - base_regmap = device_node_to_regmap(dev->of_node); - if (IS_ERR(base_regmap)) - return dev_err_probe(dev, PTR_ERR(base_regmap), - "failed to get regmap\n"); - - /* - * The lock status of PLLs locate in MPMU region, while PLLs themselves - * are in APBS region. Reference to MPMU syscon is required to check PLL - * status. - */ - if (of_device_is_compatible(dev->of_node, "spacemit,k1-pll")) { - struct device_node *mpmu = of_parse_phandle(dev->of_node, - "spacemit,mpmu", 0); - if (!mpmu) - return dev_err_probe(dev, -ENODEV, - "Cannot parse MPMU region\n"); - - lock_regmap = device_node_to_regmap(mpmu); - of_node_put(mpmu); - - if (IS_ERR(lock_regmap)) - return dev_err_probe(dev, PTR_ERR(lock_regmap), - "failed to get lock regmap\n"); - } - - data = of_device_get_match_data(dev); - - ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data); - if (ret) - return dev_err_probe(dev, ret, "failed to register clocks\n"); - - ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name); - if (ret) - return dev_err_probe(dev, ret, "failed to register resets\n"); - - return 0; -} - static const struct of_device_id of_k1_ccu_match[] = { { .compatible = "spacemit,k1-pll", @@ -1195,6 +1021,11 @@ static const struct of_device_id of_k1_ccu_match[] = { }; MODULE_DEVICE_TABLE(of, of_k1_ccu_match); +static int k1_ccu_probe(struct platform_device *pdev) +{ + return spacemit_ccu_probe(pdev, "spacemit,k1-pll"); +} + static struct platform_driver k1_ccu_driver = { .driver = { .name = "spacemit,k1-ccu", @@ -1204,6 +1035,7 @@ static struct platform_driver k1_ccu_driver = { }; module_platform_driver(k1_ccu_driver); +MODULE_IMPORT_NS("CLK_SPACEMIT"); MODULE_DESCRIPTION("SpacemiT K1 CCU driver"); MODULE_AUTHOR("Haylen Chu "); MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu-k3.c b/drivers/clk/spacemit/ccu-k3.c new file mode 100644 index 000000000000..e98afd59f05c --- /dev/null +++ b/drivers/clk/spacemit/ccu-k3.c @@ -0,0 +1,1487 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2025 SpacemiT Technology Co. Ltd + */ + +#include +#include +#include +#include + +#include "ccu_common.h" +#include "ccu_pll.h" +#include "ccu_mix.h" +#include "ccu_ddn.h" + +#include + +/* APBS clocks start, APBS region contains and only contains all PLL clocks */ + +/* + * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for + * peripherals. + */ +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { + CCU_PLLA_RATE(2457600000UL, 0x0b330ccc, 0x0000cd00, 0xa0558989), +}; + +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { + CCU_PLLA_RATE(3000000000UL, 0x0b3e2000, 0x00000000, 0xa0558c8c), +}; + +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { + CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787), +}; + +static const struct ccu_pll_rate_tbl pll4_rate_tbl[] = { + CCU_PLLA_RATE(2200000000UL, 0x0b2d3555, 0x00005500, 0xa0558787), +}; + +static const struct ccu_pll_rate_tbl pll5_rate_tbl[] = { + CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686), +}; + +static const struct ccu_pll_rate_tbl pll6_rate_tbl[] = { + CCU_PLLA_RATE(3200000000UL, 0x0b422aaa, 0x0000ab00, 0xa0558e8e), +}; + +static const struct ccu_pll_rate_tbl pll7_rate_tbl[] = { + CCU_PLLA_RATE(2800000000UL, 0x0b3a1555, 0x00005500, 0xa0558b8b), +}; + +static const struct ccu_pll_rate_tbl pll8_rate_tbl[] = { + CCU_PLLA_RATE(2000000000UL, 0x0b292aaa, 0x0000ab00, 0xa0558686), +}; + +CCU_PLLA_DEFINE(pll1, pll1_rate_tbl, APBS_PLL1_SWCR1, APBS_PLL1_SWCR2, APBS_PLL1_SWCR3, + MPMU_POSR, POSR_PLL1_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll2, pll2_rate_tbl, APBS_PLL2_SWCR1, APBS_PLL2_SWCR2, APBS_PLL2_SWCR3, + MPMU_POSR, POSR_PLL2_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll3, pll3_rate_tbl, APBS_PLL3_SWCR1, APBS_PLL3_SWCR2, APBS_PLL3_SWCR3, + MPMU_POSR, POSR_PLL3_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll4, pll4_rate_tbl, APBS_PLL4_SWCR1, APBS_PLL4_SWCR2, APBS_PLL4_SWCR3, + MPMU_POSR, POSR_PLL4_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll5, pll5_rate_tbl, APBS_PLL5_SWCR1, APBS_PLL5_SWCR2, APBS_PLL5_SWCR3, + MPMU_POSR, POSR_PLL5_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll6, pll6_rate_tbl, APBS_PLL6_SWCR1, APBS_PLL6_SWCR2, APBS_PLL6_SWCR3, + MPMU_POSR, POSR_PLL6_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll7, pll7_rate_tbl, APBS_PLL7_SWCR1, APBS_PLL7_SWCR2, APBS_PLL7_SWCR3, + MPMU_POSR, POSR_PLL7_LOCK, CLK_SET_RATE_GATE); +CCU_PLLA_DEFINE(pll8, pll8_rate_tbl, APBS_PLL8_SWCR1, APBS_PLL8_SWCR2, APBS_PLL8_SWCR3, + MPMU_POSR, POSR_PLL8_LOCK, CLK_SET_RATE_GATE); + +CCU_FACTOR_GATE_DEFINE(pll1_d2, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d3, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d5, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d6, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_FLAGS_DEFINE(pll1_d8, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(7), 8, 1, + CLK_IS_CRITICAL); +CCU_DIV_GATE_DEFINE(pll1_dx, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, 23, 5, BIT(22), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d64_38p4, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(31), 64, 1); +CCU_FACTOR_GATE_DEFINE(pll1_aud_245p7, CCU_PARENT_HW(pll1), APBS_PLL1_SWCR2, BIT(21), 10, 1); +CCU_FACTOR_DEFINE(pll1_aud_24p5, CCU_PARENT_HW(pll1_aud_245p7), 10, 1); + +CCU_FACTOR_GATE_DEFINE(pll2_d1, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d2, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d3, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d4, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d5, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d6, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d7, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll2_d8, CCU_PARENT_HW(pll2), APBS_PLL2_SWCR2, BIT(7), 8, 1); +CCU_FACTOR_DEFINE(pll2_66, CCU_PARENT_HW(pll2_d5), 9, 1); +CCU_FACTOR_DEFINE(pll2_33, CCU_PARENT_HW(pll2_66), 2, 1); +CCU_FACTOR_DEFINE(pll2_50, CCU_PARENT_HW(pll2_d5), 12, 1); +CCU_FACTOR_DEFINE(pll2_25, CCU_PARENT_HW(pll2_50), 2, 1); +CCU_FACTOR_DEFINE(pll2_20, CCU_PARENT_HW(pll2_d5), 30, 1); +CCU_FACTOR_DEFINE(pll2_d24_125, CCU_PARENT_HW(pll2_d3), 8, 1); +CCU_FACTOR_DEFINE(pll2_d120_25, CCU_PARENT_HW(pll2_d3), 40, 1); + +CCU_FACTOR_GATE_DEFINE(pll3_d1, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d2, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d3, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d4, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d5, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d6, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d7, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll3_d8, CCU_PARENT_HW(pll3), APBS_PLL3_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll4_d1, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d2, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d3, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d4, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d5, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d6, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d7, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll4_d8, CCU_PARENT_HW(pll4), APBS_PLL4_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll5_d1, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d2, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d3, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d4, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d5, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d6, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d7, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll5_d8, CCU_PARENT_HW(pll5), APBS_PLL5_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll6_d1, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d2, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d3, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d4, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d5, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d6, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d7, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll6_d8, CCU_PARENT_HW(pll6), APBS_PLL6_SWCR2, BIT(7), 8, 1); +CCU_FACTOR_DEFINE(pll6_80, CCU_PARENT_HW(pll6_d5), 8, 1); +CCU_FACTOR_DEFINE(pll6_40, CCU_PARENT_HW(pll6_d5), 16, 1); +CCU_FACTOR_DEFINE(pll6_20, CCU_PARENT_HW(pll6_d5), 32, 1); + +CCU_FACTOR_GATE_DEFINE(pll7_d1, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d2, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d3, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d4, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d5, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d6, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d7, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll7_d8, CCU_PARENT_HW(pll7), APBS_PLL7_SWCR2, BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(pll8_d1, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d2, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d3, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d4, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d5, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d6, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d7, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(pll8_d8, CCU_PARENT_HW(pll8), APBS_PLL8_SWCR2, BIT(7), 8, 1); +/* APBS clocks end */ + +/* MPMU clocks start */ +CCU_GATE_DEFINE(pll1_d8_307p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(13), 0); +CCU_FACTOR_DEFINE(pll1_d32_76p8, CCU_PARENT_HW(pll1_d8_307p2), 4, 1); +CCU_FACTOR_DEFINE(pll1_d40_61p44, CCU_PARENT_HW(pll1_d8_307p2), 5, 1); +CCU_FACTOR_DEFINE(pll1_d16_153p6, CCU_PARENT_HW(pll1_d8), 2, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d24_102p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(12), 3, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(7), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d48_51p2_ap, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(11), 6, 1); +CCU_FACTOR_GATE_DEFINE(pll1_m3d128_57p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(8), 16, 3); +CCU_FACTOR_GATE_DEFINE(pll1_d96_25p6, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(4), 12, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(3), 24, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d192_12p8_wdt, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(19), 24, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d384_6p4, CCU_PARENT_HW(pll1_d8), MPMU_ACGR, BIT(2), 48, 1); + +CCU_FACTOR_DEFINE(pll1_d768_3p2, CCU_PARENT_HW(pll1_d384_6p4), 2, 1); +CCU_FACTOR_DEFINE(pll1_d1536_1p6, CCU_PARENT_HW(pll1_d384_6p4), 4, 1); +CCU_FACTOR_DEFINE(pll1_d3072_0p8, CCU_PARENT_HW(pll1_d384_6p4), 8, 1); + +CCU_GATE_DEFINE(pll1_d6_409p6, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(0), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d12_204p8, CCU_PARENT_HW(pll1_d6), MPMU_ACGR, BIT(5), 2, 1); + +CCU_GATE_DEFINE(pll1_d5_491p52, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(21), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d10_245p76, CCU_PARENT_HW(pll1_d5), MPMU_ACGR, BIT(18), 2, 1); + +CCU_GATE_DEFINE(pll1_d4_614p4, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(15), 0); +CCU_FACTOR_GATE_DEFINE(pll1_d52_47p26, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(10), 13, 1); +CCU_FACTOR_GATE_DEFINE(pll1_d78_31p5, CCU_PARENT_HW(pll1_d4), MPMU_ACGR, BIT(6), 39, 2); + +CCU_GATE_DEFINE(pll1_d3_819p2, CCU_PARENT_HW(pll1_d3), MPMU_ACGR, BIT(14), 0); + +CCU_GATE_DEFINE(pll1_d2_1228p8, CCU_PARENT_HW(pll1_d2), MPMU_ACGR, BIT(16), 0); + +static const struct clk_parent_data apb_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d24_102p4), +}; +CCU_MUX_DEFINE(apb_clk, apb_parents, MPMU_APBCSCR, 0, 2, 0); + +CCU_GATE_DEFINE(slow_uart, CCU_PARENT_NAME(osc_32k), MPMU_ACGR, BIT(1), CLK_IGNORE_UNUSED); +CCU_DDN_DEFINE(slow_uart1_14p74, pll1_d16_153p6, MPMU_SUCCR, 16, 13, 0, 13, 2, 0); +CCU_DDN_DEFINE(slow_uart2_48, pll1_d4_614p4, MPMU_SUCCR_1, 16, 13, 0, 13, 2, 0); + +CCU_GATE_DEFINE(wdt_clk, CCU_PARENT_HW(pll1_d96_25p6), MPMU_WDTPCR, BIT(1), 0); +CCU_GATE_DEFINE(wdt_bus_clk, CCU_PARENT_HW(apb_clk), MPMU_WDTPCR, BIT(0), 0); + +CCU_GATE_DEFINE(r_ipc_clk, CCU_PARENT_HW(apb_clk), MPMU_RIPCCR, BIT(0), 0); + +CCU_FACTOR_DEFINE(i2s_153p6, CCU_PARENT_HW(pll1_d8_307p2), 2, 1); + +static const struct clk_parent_data i2s_153p6_base_parents[] = { + CCU_PARENT_HW(i2s_153p6), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DEFINE(i2s_153p6_base, i2s_153p6_base_parents, MPMU_FCCR, 29, 1, 0); + +static const struct clk_parent_data i2s_sysclk_src_parents[] = { + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(i2s_153p6_base), +}; +CCU_MUX_GATE_DEFINE(i2s_sysclk_src, i2s_sysclk_src_parents, MPMU_ISCCR, 30, 1, BIT(31), 0); + +CCU_DDN_DEFINE(i2s1_sysclk, i2s_sysclk_src, MPMU_ISCCR, 0, 15, 15, 12, 1, 0); + +CCU_DIV_GATE_DEFINE(i2s_bclk, CCU_PARENT_HW(i2s1_sysclk), MPMU_ISCCR, 27, 2, BIT(29), 0); + +static const struct clk_parent_data i2s_sysclk_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_NAME(vctcxo_24m), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_NAME(vctcxo_24m), +}; +CCU_MUX_DEFINE(i2s0_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 0, 2, 0); +CCU_MUX_DEFINE(i2s2_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 4, 2, 0); +CCU_MUX_DEFINE(i2s3_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 12, 2, 0); +CCU_MUX_DEFINE(i2s4_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 16, 2, 0); +CCU_MUX_DEFINE(i2s5_sysclk_sel, i2s_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 20, 2, 0); + +CCU_DDN_DEFINE(i2s0_sysclk_div, i2s0_sysclk_sel, MPMU_I2S0_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s2_sysclk_div, i2s2_sysclk_sel, MPMU_I2S2_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s3_sysclk_div, i2s3_sysclk_sel, MPMU_I2S3_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s4_sysclk_div, i2s4_sysclk_sel, MPMU_I2S4_SYSCLK, 0, 16, 16, 16, 1, 0); +CCU_DDN_DEFINE(i2s5_sysclk_div, i2s5_sysclk_sel, MPMU_I2S5_SYSCLK, 0, 16, 16, 16, 1, 0); + +static const struct clk_parent_data i2s2_sysclk_parents[] = { + CCU_PARENT_HW(i2s1_sysclk), + CCU_PARENT_HW(i2s2_sysclk_div), +}; +CCU_GATE_DEFINE(i2s0_sysclk, CCU_PARENT_HW(i2s0_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(2), 0); +CCU_MUX_GATE_DEFINE(i2s2_sysclk, i2s2_sysclk_parents, MPMU_I2S_SYSCLK_CTRL, 8, 1, BIT(6), 0); +CCU_GATE_DEFINE(i2s3_sysclk, CCU_PARENT_HW(i2s3_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(14), 0); +CCU_GATE_DEFINE(i2s4_sysclk, CCU_PARENT_HW(i2s4_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(18), 0); +CCU_GATE_DEFINE(i2s5_sysclk, CCU_PARENT_HW(i2s5_sysclk_div), MPMU_I2S_SYSCLK_CTRL, BIT(22), 0); +/* MPMU clocks end */ + +/* APBC clocks start */ +static const struct clk_parent_data uart_clk_parents[] = { + CCU_PARENT_HW(pll1_m3d128_57p6), + CCU_PARENT_HW(slow_uart1_14p74), + CCU_PARENT_HW(slow_uart2_48), +}; +CCU_MUX_GATE_DEFINE(uart0_clk, uart_clk_parents, APBC_UART0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart2_clk, uart_clk_parents, APBC_UART2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart3_clk, uart_clk_parents, APBC_UART3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart4_clk, uart_clk_parents, APBC_UART4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart5_clk, uart_clk_parents, APBC_UART5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart6_clk, uart_clk_parents, APBC_UART6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart7_clk, uart_clk_parents, APBC_UART7_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart8_clk, uart_clk_parents, APBC_UART8_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart9_clk, uart_clk_parents, APBC_UART9_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(uart10_clk, uart_clk_parents, APBC_UART10_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(uart0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART9_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(uart10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_UART10_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(gpio_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_GPIO_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(gpio_bus_clk, CCU_PARENT_HW(apb_clk), APBC_GPIO_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data pwm_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc_32k), +}; +CCU_MUX_GATE_DEFINE(pwm0_clk, pwm_parents, APBC_PWM0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm1_clk, pwm_parents, APBC_PWM1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm2_clk, pwm_parents, APBC_PWM2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm3_clk, pwm_parents, APBC_PWM3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm4_clk, pwm_parents, APBC_PWM4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm5_clk, pwm_parents, APBC_PWM5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm6_clk, pwm_parents, APBC_PWM6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm7_clk, pwm_parents, APBC_PWM7_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm8_clk, pwm_parents, APBC_PWM8_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm9_clk, pwm_parents, APBC_PWM9_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm10_clk, pwm_parents, APBC_PWM10_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm11_clk, pwm_parents, APBC_PWM11_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm12_clk, pwm_parents, APBC_PWM12_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm13_clk, pwm_parents, APBC_PWM13_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm14_clk, pwm_parents, APBC_PWM14_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm15_clk, pwm_parents, APBC_PWM15_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm16_clk, pwm_parents, APBC_PWM16_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm17_clk, pwm_parents, APBC_PWM17_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm18_clk, pwm_parents, APBC_PWM18_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(pwm19_clk, pwm_parents, APBC_PWM19_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(pwm0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm9_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM9_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm10_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM10_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm11_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM11_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm12_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM12_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm13_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM13_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm14_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM14_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm15_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM15_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm16_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM16_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm17_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM17_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm18_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM18_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(pwm19_bus_clk, CCU_PARENT_HW(apb_clk), APBC_PWM19_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data i2s_bclk_parents[] = { + CCU_PARENT_NAME(vctcxo_1m), + CCU_PARENT_HW(i2s_bclk), +}; +CCU_MUX_DEFINE(spi0_i2s_bclk, i2s_bclk_parents, APBC_SSP0_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(spi1_i2s_bclk, i2s_bclk_parents, APBC_SSP1_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(spi3_i2s_bclk, i2s_bclk_parents, APBC_SSP3_CLK_RST, 3, 1, 0); + +static const struct clk_parent_data spi0_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi0_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi0_clk, spi0_parents, APBC_SSP0_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data spi1_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi1_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi1_clk, spi1_parents, APBC_SSP1_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data spi3_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(spi3_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(spi3_clk, spi3_parents, APBC_SSP3_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(spi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(spi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(spi3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSP3_CLK_RST, BIT(0), 0); + + +CCU_GATE_DEFINE(rtc_clk, CCU_PARENT_NAME(osc_32k), APBC_RTC_CLK_RST, + BIT(7) | BIT(1), 0); +CCU_GATE_DEFINE(rtc_bus_clk, CCU_PARENT_HW(apb_clk), APBC_RTC_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data twsi_parents[] = { + CCU_PARENT_HW(pll1_d78_31p5), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d40_61p44), +}; +CCU_MUX_GATE_DEFINE(twsi0_clk, twsi_parents, APBC_TWSI0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi1_clk, twsi_parents, APBC_TWSI1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi2_clk, twsi_parents, APBC_TWSI2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi4_clk, twsi_parents, APBC_TWSI4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi5_clk, twsi_parents, APBC_TWSI5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi6_clk, twsi_parents, APBC_TWSI6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(twsi8_clk, twsi_parents, APBC_TWSI8_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(twsi0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(twsi8_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TWSI8_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data timer_parents[] = { + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_NAME(osc_32k), + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_NAME(vctcxo_3m), + CCU_PARENT_NAME(vctcxo_1m), +}; +CCU_MUX_GATE_DEFINE(timers0_clk, timer_parents, APBC_TIMERS0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers1_clk, timer_parents, APBC_TIMERS1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers2_clk, timer_parents, APBC_TIMERS2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers3_clk, timer_parents, APBC_TIMERS3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers4_clk, timer_parents, APBC_TIMERS4_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers5_clk, timer_parents, APBC_TIMERS5_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers6_clk, timer_parents, APBC_TIMERS6_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(timers7_clk, timer_parents, APBC_TIMERS7_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(timers0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers6_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(timers7_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TIMERS7_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(aib_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_AIB_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(aib_bus_clk, CCU_PARENT_HW(apb_clk), APBC_AIB_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(onewire_clk, CCU_PARENT_NAME(vctcxo_24m), APBC_ONEWIRE_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(onewire_bus_clk, CCU_PARENT_HW(apb_clk), APBC_ONEWIRE_CLK_RST, BIT(0), 0); + +/* + * When i2s_bclk is selected as the parent clock of sspa, + * the hardware requires bit3 to be set + */ + +CCU_MUX_DEFINE(i2s0_i2s_bclk, i2s_bclk_parents, APBC_SSPA0_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s1_i2s_bclk, i2s_bclk_parents, APBC_SSPA1_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s2_i2s_bclk, i2s_bclk_parents, APBC_SSPA2_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s3_i2s_bclk, i2s_bclk_parents, APBC_SSPA3_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s4_i2s_bclk, i2s_bclk_parents, APBC_SSPA4_CLK_RST, 3, 1, 0); +CCU_MUX_DEFINE(i2s5_i2s_bclk, i2s_bclk_parents, APBC_SSPA5_CLK_RST, 3, 1, 0); + +static const struct clk_parent_data i2s0_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s0_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s0_clk, i2s0_parents, APBC_SSPA0_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s1_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s1_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s1_clk, i2s1_parents, APBC_SSPA1_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s2_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s2_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s2_clk, i2s2_parents, APBC_SSPA2_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s3_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s3_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s3_clk, i2s3_parents, APBC_SSPA3_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s4_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s4_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s4_clk, i2s4_parents, APBC_SSPA4_CLK_RST, 4, 3, BIT(1), 0); + +static const struct clk_parent_data i2s5_parents[] = { + CCU_PARENT_HW(pll1_d384_6p4), + CCU_PARENT_HW(pll1_d192_12p8), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d48_51p2), + CCU_PARENT_HW(pll1_d768_3p2), + CCU_PARENT_HW(pll1_d1536_1p6), + CCU_PARENT_HW(pll1_d3072_0p8), + CCU_PARENT_HW(i2s5_i2s_bclk), +}; +CCU_MUX_GATE_DEFINE(i2s5_clk, i2s5_parents, APBC_SSPA5_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(i2s0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(i2s5_bus_clk, CCU_PARENT_HW(apb_clk), APBC_SSPA5_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(dro_clk, CCU_PARENT_HW(apb_clk), APBC_DRO_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ir0_clk, CCU_PARENT_HW(apb_clk), APBC_IR0_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ir1_clk, CCU_PARENT_HW(apb_clk), APBC_IR1_CLK_RST, BIT(1), 0); + +CCU_GATE_DEFINE(tsen_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(tsen_bus_clk, CCU_PARENT_HW(apb_clk), APBC_TSEN_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(ipc_ap2rcpu_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CLK_RST, BIT(1), 0); +CCU_GATE_DEFINE(ipc_ap2rcpu_bus_clk, CCU_PARENT_HW(apb_clk), APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0); + +static const struct clk_parent_data can_parents[] = { + CCU_PARENT_HW(pll6_20), + CCU_PARENT_HW(pll6_40), + CCU_PARENT_HW(pll6_80), +}; +CCU_MUX_GATE_DEFINE(can0_clk, can_parents, APBC_CAN0_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can1_clk, can_parents, APBC_CAN1_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can2_clk, can_parents, APBC_CAN2_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can3_clk, can_parents, APBC_CAN3_CLK_RST, 4, 3, BIT(1), 0); +CCU_MUX_GATE_DEFINE(can4_clk, can_parents, APBC_CAN4_CLK_RST, 4, 3, BIT(1), 0); + +CCU_GATE_DEFINE(can0_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can1_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can2_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can3_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(can4_bus_clk, CCU_PARENT_HW(apb_clk), APBC_CAN4_CLK_RST, BIT(0), 0); +/* APBC clocks end */ + +/* APMU clocks start */ +static const struct clk_parent_data axi_clk_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), +}; +CCU_MUX_DIV_FC_DEFINE(axi_clk, axi_clk_parents, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4), 0, 1, 0); + +static const struct clk_parent_data cci550_clk_parents[] = { + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll7_d3), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll7_d2), +}; +CCU_MUX_DIV_FC_DEFINE(cci550_clk, cci550_clk_parents, APMU_CCI550_CLK_CTRL, 8, 2, BIT(12), 0, 3, + CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c0_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll3_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll3_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c0_core_clk, cpu_c0_clk_parents, APMU_CPU_C0_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c1_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll4_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll4_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c1_core_clk, cpu_c1_clk_parents, APMU_CPU_C1_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c2_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll5_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll5_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c2_core_clk, cpu_c2_clk_parents, APMU_CPU_C2_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data cpu_c3_clk_parents[] = { + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll8_d2), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll8_d1), +}; +CCU_MUX_DIV_FC_DEFINE(cpu_c3_core_clk, cpu_c3_clk_parents, APMU_CPU_C3_CLK_CTRL, + 3, 3, BIT(12), 0, 3, CLK_IS_CRITICAL); + +static const struct clk_parent_data ccic2phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic2phy_clk, ccic2phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 7, 1, BIT(5), 0); + +static const struct clk_parent_data ccic3phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic3phy_clk, ccic3phy_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 31, 1, BIT(30), 0); + +static const struct clk_parent_data csi_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(csi_clk, csi_parents, APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15), + 16, 3, BIT(4), 0); + +static const struct clk_parent_data isp_bus_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d10_245p76), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(isp_bus_clk, isp_bus_parents, APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23), + 21, 2, BIT(17), 0); + +CCU_GATE_DEFINE(d1p_1228p8, CCU_PARENT_HW(pll1_d2_1228p8), APMU_PMU_CLK_GATE_CTRL, BIT(31), 0); +CCU_GATE_DEFINE(d1p_819p2, CCU_PARENT_HW(pll1_d3_819p2), APMU_PMU_CLK_GATE_CTRL, BIT(30), 0); +CCU_GATE_DEFINE(d1p_614p4, CCU_PARENT_HW(pll1_d4_614p4), APMU_PMU_CLK_GATE_CTRL, BIT(29), 0); +CCU_GATE_DEFINE(d1p_491p52, CCU_PARENT_HW(pll1_d5_491p52), APMU_PMU_CLK_GATE_CTRL, BIT(28), 0); +CCU_GATE_DEFINE(d1p_409p6, CCU_PARENT_HW(pll1_d6_409p6), APMU_PMU_CLK_GATE_CTRL, BIT(27), 0); +CCU_GATE_DEFINE(d1p_307p2, CCU_PARENT_HW(pll1_d8_307p2), APMU_PMU_CLK_GATE_CTRL, BIT(26), 0); +CCU_GATE_DEFINE(d1p_245p76, CCU_PARENT_HW(pll1_d10_245p76), APMU_PMU_CLK_GATE_CTRL, BIT(22), 0); + +static const struct clk_parent_data v2d_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d4_614p4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(v2d_clk, v2d_parents, APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2, + BIT(8), 0); + +static const struct clk_parent_data dsiesc_parents[] = { + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d32_76p8), +}; +CCU_MUX_GATE_DEFINE(dsi_esc_clk, dsiesc_parents, APMU_LCD_CLK_RES_CTRL1, 0, 2, BIT(2), 0); + +CCU_GATE_DEFINE(lcd_hclk, CCU_PARENT_HW(axi_clk), APMU_LCD_CLK_RES_CTRL1, BIT(5), 0); + +static const struct clk_parent_data lcd_dsc_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_dsc_clk, lcd_dsc_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 25, 3, BIT(26), 29, 3, BIT(14), 0); + +static const struct clk_parent_data lcdpx_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_pxclk, lcdpx_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(30), 21, 3, BIT(16), 0); + +static const struct clk_parent_data lcdmclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(lcd_mclk, lcdmclk_parents, APMU_LCD_CLK_RES_CTRL2, + APMU_LCD_CLK_RES_CTRL1, 1, 4, BIT(29), 5, 3, BIT(0), 0); + +static const struct clk_parent_data ccic_4x_parents[] = { + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll2_d2), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d2_1228p8), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(ccic_4x_clk, ccic_4x_parents, APMU_CCIC_CLK_RES_CTRL, 18, 3, + BIT(15), 23, 2, BIT(4), 0); + +static const struct clk_parent_data ccic1phy_parents[] = { + CCU_PARENT_HW(pll1_d24_102p4), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_GATE_DEFINE(ccic1phy_clk, ccic1phy_parents, APMU_CCIC_CLK_RES_CTRL, 7, 1, BIT(5), 0); + + +static const struct clk_parent_data sc2hclk_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sc2_hclk, sc2hclk_parents, APMU_CCIC_CLK_RES_CTRL, 10, 3, + BIT(16), 8, 2, BIT(3), 0); + +CCU_GATE_DEFINE(sdh_axi_aclk, CCU_PARENT_HW(axi_clk), APMU_SDH0_CLK_RES_CTRL, BIT(3), 0); +static const struct clk_parent_data sdh01_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll2_d5), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sdh0_clk, sdh01_parents, APMU_SDH0_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); +CCU_MUX_DIV_GATE_FC_DEFINE(sdh1_clk, sdh01_parents, APMU_SDH1_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); +static const struct clk_parent_data sdh2_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(sdh2_clk, sdh2_parents, APMU_SDH2_CLK_RES_CTRL, 8, 3, + BIT(11), 5, 3, BIT(4), 0); + +CCU_GATE_DEFINE(usb2_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_DEFINE(usb3_porta_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(4), 0); +CCU_GATE_DEFINE(usb3_portb_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(8), 0); +CCU_GATE_DEFINE(usb3_portc_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(12), 0); +CCU_GATE_DEFINE(usb3_portd_bus_clk, CCU_PARENT_HW(axi_clk), APMU_USB_CLK_RES_CTRL, BIT(16), 0); + +static const struct clk_parent_data qspi_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll2_d8), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d10_245p76), + CCU_PARENT_NAME(reserved_clk), + CCU_PARENT_HW(pll1_dx), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_NAME(reserved_clk), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(qspi_clk, qspi_parents, APMU_QSPI_CLK_RES_CTRL, 9, 3, + BIT(12), 6, 3, BIT(4), 0); +CCU_GATE_DEFINE(qspi_bus_clk, CCU_PARENT_HW(axi_clk), APMU_QSPI_CLK_RES_CTRL, BIT(3), 0); + +CCU_GATE_DEFINE(dma_clk, CCU_PARENT_HW(axi_clk), APMU_DMA_CLK_RES_CTRL, BIT(3), 0); + +static const struct clk_parent_data aes_wtm_parents[] = { + CCU_PARENT_HW(pll1_d12_204p8), + CCU_PARENT_HW(pll1_d24_102p4), +}; +CCU_MUX_GATE_DEFINE(aes_wtm_clk, aes_wtm_parents, APMU_AES_CLK_RES_CTRL, 6, 1, BIT(5), 0); + +static const struct clk_parent_data vpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(vpu_clk, vpu_parents, APMU_VPU_CLK_RES_CTRL, 13, 3, + BIT(21), 10, 3, BIT(3), 0); + +CCU_GATE_DEFINE(dtc_clk, CCU_PARENT_HW(axi_clk), APMU_DTC_CLK_RES_CTRL, BIT(3), 0); + +static const struct clk_parent_data gpu_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d3_819p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d2_1228p8), + CCU_PARENT_HW(pll2_d3), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll2_d5), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(gpu_clk, gpu_parents, APMU_GPU_CLK_RES_CTRL, 12, 3, + BIT(15), 18, 3, BIT(4), 0); + +CCU_GATE_DEFINE(mc_ahb_clk, CCU_PARENT_HW(axi_clk), APMU_PMUA_MC_CTRL, BIT(1), 0); + +static const struct clk_parent_data top_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d4), + CCU_PARENT_HW(pll6_d5), + CCU_PARENT_HW(pll7_d4), + CCU_PARENT_HW(pll6_d4), + CCU_PARENT_HW(pll7_d3), + CCU_PARENT_HW(pll6_d3), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(top_dclk, top_parents, APMU_TOP_DCLK_CTRL, 5, 3, + BIT(8), 2, 3, BIT(1), 0); + +static const struct clk_parent_data ucie_parents[] = { + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll3_d4), + CCU_PARENT_HW(pll6_d5), + CCU_PARENT_HW(pll7_d4), + CCU_PARENT_HW(pll6_d4), +}; +CCU_MUX_GATE_DEFINE(ucie_clk, ucie_parents, APMU_UCIE_CTRL, 4, 3, BIT(0), 0); +CCU_GATE_DEFINE(ucie_sbclk, CCU_PARENT_HW(axi_clk), APMU_UCIE_CTRL, BIT(8), 0); + +static const struct clk_parent_data rcpu_clk_parents[] = { + CCU_PARENT_HW(pll1_aud_245p7), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d6_409p6), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(rcpu_clk, rcpu_clk_parents, APMU_RCPU_CLK_RES_CTRL, + 4, 3, BIT(15), 7, 3, BIT(12), 0); + +static const struct clk_parent_data dsi4ln2_dsi_esc_parents[] = { + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll1_d52_47p26), + CCU_PARENT_HW(pll1_d96_25p6), + CCU_PARENT_HW(pll1_d32_76p8), +}; +CCU_MUX_GATE_DEFINE(dsi4ln2_dsi_esc_clk, dsi4ln2_dsi_esc_parents, APMU_LCD_CLK_RES_CTRL3, + 0, 1, BIT(2), 0); + +static const struct clk_parent_data dsi4ln2_lcd_dsc_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll6_d6), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d48_51p2_ap), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_dsc_clk, dsi4ln2_lcd_dsc_parents, + APMU_LCD_CLK_RES_CTRL4, APMU_LCD_CLK_RES_CTRL3, + 25, 3, BIT(26), 29, 3, BIT(14), 0); + +static const struct clk_parent_data dsi4ln2_lcdpx_parents[] = { + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll7_d5), + CCU_PARENT_HW(pll6_d6), + CCU_PARENT_HW(pll2_d7), + CCU_PARENT_HW(pll2_d4), + CCU_PARENT_HW(pll1_d48_51p2_ap), + CCU_PARENT_HW(pll2_d8), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_pxclk, dsi4ln2_lcdpx_parents, APMU_LCD_CLK_RES_CTRL4, + APMU_LCD_CLK_RES_CTRL3, 17, 3, BIT(30), 21, 3, BIT(16), 0); + +static const struct clk_parent_data dsi4ln2_lcd_mclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), +}; +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(dsi4ln2_lcd_mclk, dsi4ln2_lcd_mclk_parents, APMU_LCD_CLK_RES_CTRL4, + APMU_LCD_CLK_RES_CTRL3, 1, 4, BIT(29), 5, 3, BIT(0), 0); + +static const struct clk_parent_data dpu_aclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(dsi4ln2_dpu_aclk, dpu_aclk_parents, APMU_LCD_CLK_RES_CTRL5, + 2, 3, BIT(30), 5, 3, BIT(1), 0); + +CCU_MUX_DIV_GATE_FC_DEFINE(dpu_aclk, dpu_aclk_parents, APMU_LCD_CLK_RES_CTRL5, 17, 3, BIT(31), + 20, 3, BIT(16), 0); + +static const struct clk_parent_data ufs_aclk_parents[] = { + CCU_PARENT_HW(pll1_d6_409p6), + CCU_PARENT_HW(pll1_d5_491p52), + CCU_PARENT_HW(pll1_d4_614p4), + CCU_PARENT_HW(pll1_d8_307p2), + CCU_PARENT_HW(pll2_d4), +}; +CCU_MUX_DIV_GATE_FC_DEFINE(ufs_aclk, ufs_aclk_parents, APMU_UFS_CLK_RES_CTRL, 5, 3, BIT(8), + 2, 3, BIT(1), 0); + +static const struct clk_parent_data edp0_pclk_parents[] = { + CCU_PARENT_HW(lcd_pxclk), + CCU_PARENT_NAME(external_clk), +}; +CCU_MUX_GATE_DEFINE(edp0_pxclk, edp0_pclk_parents, APMU_LCD_EDP_CTRL, 2, 1, BIT(1), 0); + +static const struct clk_parent_data edp1_pclk_parents[] = { + CCU_PARENT_HW(dsi4ln2_lcd_pxclk), + CCU_PARENT_NAME(external_clk), +}; +CCU_MUX_GATE_DEFINE(edp1_pxclk, edp1_pclk_parents, APMU_LCD_EDP_CTRL, 18, 1, BIT(17), 0); + +CCU_GATE_DEFINE(pciea_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_A, BIT(2), 0); +CCU_GATE_DEFINE(pciea_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_A, BIT(1), 0); +CCU_GATE_DEFINE(pcieb_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_B, BIT(2), 0); +CCU_GATE_DEFINE(pcieb_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_B, BIT(1), 0); +CCU_GATE_DEFINE(pciec_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_C, BIT(2), 0); +CCU_GATE_DEFINE(pciec_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_C, BIT(1), 0); +CCU_GATE_DEFINE(pcied_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_D, BIT(2), 0); +CCU_GATE_DEFINE(pcied_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_D, BIT(1), 0); +CCU_GATE_DEFINE(pciee_mstr_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_E, BIT(2), 0); +CCU_GATE_DEFINE(pciee_slv_clk, CCU_PARENT_HW(axi_clk), APMU_PCIE_CLK_RES_CTRL_E, BIT(1), 0); + +static const struct clk_parent_data emac_1588_parents[] = { + CCU_PARENT_NAME(vctcxo_24m), + CCU_PARENT_HW(pll2_d24_125), +}; + +CCU_GATE_DEFINE(emac0_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac0_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC0_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac0_1588_clk, emac_1588_parents, APMU_EMAC0_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac0_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC0_CLK_RES_CTRL, + BIT(8), 0); +CCU_GATE_DEFINE(emac1_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac1_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC1_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac1_1588_clk, emac_1588_parents, APMU_EMAC1_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac1_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC1_CLK_RES_CTRL, + BIT(8), 0); +CCU_GATE_DEFINE(emac2_bus_clk, CCU_PARENT_HW(axi_clk), APMU_EMAC2_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_FLAGS_DEFINE(emac2_ref_clk, CCU_PARENT_HW(pll2_d120_25), APMU_EMAC2_CLK_RES_CTRL, + BIT(14), true, 0); +CCU_MUX_DEFINE(emac2_1588_clk, emac_1588_parents, APMU_EMAC2_CLK_RES_CTRL, 15, 1, 0); +CCU_GATE_DEFINE(emac2_rgmii_tx_clk, CCU_PARENT_HW(pll2_d24_125), APMU_EMAC2_CLK_RES_CTRL, + BIT(8), 0); + +static const struct clk_parent_data espi_sclk_src_parents[] = { + CCU_PARENT_HW(pll2_20), + CCU_PARENT_HW(pll2_25), + CCU_PARENT_HW(pll2_33), + CCU_PARENT_HW(pll2_50), + CCU_PARENT_HW(pll2_66), +}; +CCU_MUX_DEFINE(espi_sclk_src, espi_sclk_src_parents, APMU_ESPI_CLK_RES_CTRL, 4, 3, 0); + +static const struct clk_parent_data espi_sclk_parents[] = { + CCU_PARENT_NAME(external_clk), + CCU_PARENT_HW(espi_sclk_src), +}; +CCU_MUX_GATE_DEFINE(espi_sclk, espi_sclk_parents, APMU_ESPI_CLK_RES_CTRL, 7, 1, BIT(3), 0); + +CCU_GATE_DEFINE(espi_mclk, CCU_PARENT_HW(axi_clk), APMU_ESPI_CLK_RES_CTRL, BIT(1), 0); + +CCU_FACTOR_DEFINE(cam_src1_clk, CCU_PARENT_HW(pll1_d6_409p6), 15, 1); +CCU_FACTOR_DEFINE(cam_src2_clk, CCU_PARENT_HW(pll2_d5), 25, 1); +CCU_FACTOR_DEFINE(cam_src3_clk, CCU_PARENT_HW(pll2_d6), 20, 1); +CCU_FACTOR_DEFINE(cam_src4_clk, CCU_PARENT_HW(pll1_d6_409p6), 16, 1); + +static const struct clk_parent_data isim_vclk_parents[] = { + CCU_PARENT_HW(cam_src1_clk), + CCU_PARENT_HW(cam_src2_clk), + CCU_PARENT_HW(cam_src3_clk), + CCU_PARENT_HW(cam_src4_clk), +}; +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out0, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 3, 4, + 1, 2, BIT(0), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out1, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 11, 4, + 9, 2, BIT(8), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out2, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 19, 4, + 17, 2, BIT(16), 0); +CCU_MUX_DIV_GATE_DEFINE(isim_vclk_out3, isim_vclk_parents, APMU_SNR_ISIM_VCLK_CTRL, 27, 4, + 25, 2, BIT(24), 0); +/* APMU clocks end */ + +/* DCIU clocks start */ +CCU_GATE_DEFINE(hdma_clk, CCU_PARENT_HW(axi_clk), DCIU_DMASYS_CLK_EN, BIT(0), 0); +CCU_GATE_DEFINE(dma350_clk, CCU_PARENT_HW(axi_clk), DCIU_DMASYS_SDMA_CLK_EN, BIT(0), 0); +CCU_GATE_DEFINE(c2_tcm_pipe_clk, CCU_PARENT_HW(axi_clk), DCIU_C2_TCM_PIPE_CLK, BIT(0), 0); +CCU_GATE_DEFINE(c3_tcm_pipe_clk, CCU_PARENT_HW(axi_clk), DCIU_C3_TCM_PIPE_CLK, BIT(0), 0); +/* DCIU clocks end */ + +static struct clk_hw *k3_ccu_pll_hws[] = { + [CLK_PLL1] = &pll1.common.hw, + [CLK_PLL2] = &pll2.common.hw, + [CLK_PLL3] = &pll3.common.hw, + [CLK_PLL4] = &pll4.common.hw, + [CLK_PLL5] = &pll5.common.hw, + [CLK_PLL6] = &pll6.common.hw, + [CLK_PLL7] = &pll7.common.hw, + [CLK_PLL8] = &pll8.common.hw, + [CLK_PLL1_D2] = &pll1_d2.common.hw, + [CLK_PLL1_D3] = &pll1_d3.common.hw, + [CLK_PLL1_D4] = &pll1_d4.common.hw, + [CLK_PLL1_D5] = &pll1_d5.common.hw, + [CLK_PLL1_D6] = &pll1_d6.common.hw, + [CLK_PLL1_D7] = &pll1_d7.common.hw, + [CLK_PLL1_D8] = &pll1_d8.common.hw, + [CLK_PLL1_DX] = &pll1_dx.common.hw, + [CLK_PLL1_D64] = &pll1_d64_38p4.common.hw, + [CLK_PLL1_D10_AUD] = &pll1_aud_245p7.common.hw, + [CLK_PLL1_D100_AUD] = &pll1_aud_24p5.common.hw, + [CLK_PLL2_D1] = &pll2_d1.common.hw, + [CLK_PLL2_D2] = &pll2_d2.common.hw, + [CLK_PLL2_D3] = &pll2_d3.common.hw, + [CLK_PLL2_D4] = &pll2_d4.common.hw, + [CLK_PLL2_D5] = &pll2_d5.common.hw, + [CLK_PLL2_D6] = &pll2_d6.common.hw, + [CLK_PLL2_D7] = &pll2_d7.common.hw, + [CLK_PLL2_D8] = &pll2_d8.common.hw, + [CLK_PLL2_66] = &pll2_66.common.hw, + [CLK_PLL2_33] = &pll2_33.common.hw, + [CLK_PLL2_50] = &pll2_50.common.hw, + [CLK_PLL2_25] = &pll2_25.common.hw, + [CLK_PLL2_20] = &pll2_20.common.hw, + [CLK_PLL2_D24_125] = &pll2_d24_125.common.hw, + [CLK_PLL2_D120_25] = &pll2_d120_25.common.hw, + [CLK_PLL3_D1] = &pll3_d1.common.hw, + [CLK_PLL3_D2] = &pll3_d2.common.hw, + [CLK_PLL3_D3] = &pll3_d3.common.hw, + [CLK_PLL3_D4] = &pll3_d4.common.hw, + [CLK_PLL3_D5] = &pll3_d5.common.hw, + [CLK_PLL3_D6] = &pll3_d6.common.hw, + [CLK_PLL3_D7] = &pll3_d7.common.hw, + [CLK_PLL3_D8] = &pll3_d8.common.hw, + [CLK_PLL4_D1] = &pll4_d1.common.hw, + [CLK_PLL4_D2] = &pll4_d2.common.hw, + [CLK_PLL4_D3] = &pll4_d3.common.hw, + [CLK_PLL4_D4] = &pll4_d4.common.hw, + [CLK_PLL4_D5] = &pll4_d5.common.hw, + [CLK_PLL4_D6] = &pll4_d6.common.hw, + [CLK_PLL4_D7] = &pll4_d7.common.hw, + [CLK_PLL4_D8] = &pll4_d8.common.hw, + [CLK_PLL5_D1] = &pll5_d1.common.hw, + [CLK_PLL5_D2] = &pll5_d2.common.hw, + [CLK_PLL5_D3] = &pll5_d3.common.hw, + [CLK_PLL5_D4] = &pll5_d4.common.hw, + [CLK_PLL5_D5] = &pll5_d5.common.hw, + [CLK_PLL5_D6] = &pll5_d6.common.hw, + [CLK_PLL5_D7] = &pll5_d7.common.hw, + [CLK_PLL5_D8] = &pll5_d8.common.hw, + [CLK_PLL6_D1] = &pll6_d1.common.hw, + [CLK_PLL6_D2] = &pll6_d2.common.hw, + [CLK_PLL6_D3] = &pll6_d3.common.hw, + [CLK_PLL6_D4] = &pll6_d4.common.hw, + [CLK_PLL6_D5] = &pll6_d5.common.hw, + [CLK_PLL6_D6] = &pll6_d6.common.hw, + [CLK_PLL6_D7] = &pll6_d7.common.hw, + [CLK_PLL6_D8] = &pll6_d8.common.hw, + [CLK_PLL6_80] = &pll6_80.common.hw, + [CLK_PLL6_40] = &pll6_40.common.hw, + [CLK_PLL6_20] = &pll6_20.common.hw, + [CLK_PLL7_D1] = &pll7_d1.common.hw, + [CLK_PLL7_D2] = &pll7_d2.common.hw, + [CLK_PLL7_D3] = &pll7_d3.common.hw, + [CLK_PLL7_D4] = &pll7_d4.common.hw, + [CLK_PLL7_D5] = &pll7_d5.common.hw, + [CLK_PLL7_D6] = &pll7_d6.common.hw, + [CLK_PLL7_D7] = &pll7_d7.common.hw, + [CLK_PLL7_D8] = &pll7_d8.common.hw, + [CLK_PLL8_D1] = &pll8_d1.common.hw, + [CLK_PLL8_D2] = &pll8_d2.common.hw, + [CLK_PLL8_D3] = &pll8_d3.common.hw, + [CLK_PLL8_D4] = &pll8_d4.common.hw, + [CLK_PLL8_D5] = &pll8_d5.common.hw, + [CLK_PLL8_D6] = &pll8_d6.common.hw, + [CLK_PLL8_D7] = &pll8_d7.common.hw, + [CLK_PLL8_D8] = &pll8_d8.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_pll_data = { + /* The APBS CCU implements PLLs, but no resets */ + .hws = k3_ccu_pll_hws, + .num = ARRAY_SIZE(k3_ccu_pll_hws), +}; + +static struct clk_hw *k3_ccu_mpmu_hws[] = { + [CLK_MPMU_PLL1_307P2] = &pll1_d8_307p2.common.hw, + [CLK_MPMU_PLL1_76P8] = &pll1_d32_76p8.common.hw, + [CLK_MPMU_PLL1_61P44] = &pll1_d40_61p44.common.hw, + [CLK_MPMU_PLL1_153P6] = &pll1_d16_153p6.common.hw, + [CLK_MPMU_PLL1_102P4] = &pll1_d24_102p4.common.hw, + [CLK_MPMU_PLL1_51P2] = &pll1_d48_51p2.common.hw, + [CLK_MPMU_PLL1_51P2_AP] = &pll1_d48_51p2_ap.common.hw, + [CLK_MPMU_PLL1_57P6] = &pll1_m3d128_57p6.common.hw, + [CLK_MPMU_PLL1_25P6] = &pll1_d96_25p6.common.hw, + [CLK_MPMU_PLL1_12P8] = &pll1_d192_12p8.common.hw, + [CLK_MPMU_PLL1_12P8_WDT] = &pll1_d192_12p8_wdt.common.hw, + [CLK_MPMU_PLL1_6P4] = &pll1_d384_6p4.common.hw, + [CLK_MPMU_PLL1_3P2] = &pll1_d768_3p2.common.hw, + [CLK_MPMU_PLL1_1P6] = &pll1_d1536_1p6.common.hw, + [CLK_MPMU_PLL1_0P8] = &pll1_d3072_0p8.common.hw, + [CLK_MPMU_PLL1_409P6] = &pll1_d6_409p6.common.hw, + [CLK_MPMU_PLL1_204P8] = &pll1_d12_204p8.common.hw, + [CLK_MPMU_PLL1_491] = &pll1_d5_491p52.common.hw, + [CLK_MPMU_PLL1_245P76] = &pll1_d10_245p76.common.hw, + [CLK_MPMU_PLL1_614] = &pll1_d4_614p4.common.hw, + [CLK_MPMU_PLL1_47P26] = &pll1_d52_47p26.common.hw, + [CLK_MPMU_PLL1_31P5] = &pll1_d78_31p5.common.hw, + [CLK_MPMU_PLL1_819] = &pll1_d3_819p2.common.hw, + [CLK_MPMU_PLL1_1228] = &pll1_d2_1228p8.common.hw, + [CLK_MPMU_APB] = &apb_clk.common.hw, + [CLK_MPMU_SLOW_UART] = &slow_uart.common.hw, + [CLK_MPMU_SLOW_UART1] = &slow_uart1_14p74.common.hw, + [CLK_MPMU_SLOW_UART2] = &slow_uart2_48.common.hw, + [CLK_MPMU_WDT] = &wdt_clk.common.hw, + [CLK_MPMU_WDT_BUS] = &wdt_bus_clk.common.hw, + [CLK_MPMU_RIPC] = &r_ipc_clk.common.hw, + [CLK_MPMU_I2S_153P6] = &i2s_153p6.common.hw, + [CLK_MPMU_I2S_153P6_BASE] = &i2s_153p6_base.common.hw, + [CLK_MPMU_I2S_SYSCLK_SRC] = &i2s_sysclk_src.common.hw, + [CLK_MPMU_I2S1_SYSCLK] = &i2s1_sysclk.common.hw, + [CLK_MPMU_I2S_BCLK] = &i2s_bclk.common.hw, + [CLK_MPMU_I2S0_SYSCLK_SEL] = &i2s0_sysclk_sel.common.hw, + [CLK_MPMU_I2S2_SYSCLK_SEL] = &i2s2_sysclk_sel.common.hw, + [CLK_MPMU_I2S3_SYSCLK_SEL] = &i2s3_sysclk_sel.common.hw, + [CLK_MPMU_I2S4_SYSCLK_SEL] = &i2s4_sysclk_sel.common.hw, + [CLK_MPMU_I2S5_SYSCLK_SEL] = &i2s5_sysclk_sel.common.hw, + [CLK_MPMU_I2S0_SYSCLK_DIV] = &i2s0_sysclk_div.common.hw, + [CLK_MPMU_I2S2_SYSCLK_DIV] = &i2s2_sysclk_div.common.hw, + [CLK_MPMU_I2S3_SYSCLK_DIV] = &i2s3_sysclk_div.common.hw, + [CLK_MPMU_I2S4_SYSCLK_DIV] = &i2s4_sysclk_div.common.hw, + [CLK_MPMU_I2S5_SYSCLK_DIV] = &i2s5_sysclk_div.common.hw, + [CLK_MPMU_I2S0_SYSCLK] = &i2s0_sysclk.common.hw, + [CLK_MPMU_I2S2_SYSCLK] = &i2s2_sysclk.common.hw, + [CLK_MPMU_I2S3_SYSCLK] = &i2s3_sysclk.common.hw, + [CLK_MPMU_I2S4_SYSCLK] = &i2s4_sysclk.common.hw, + [CLK_MPMU_I2S5_SYSCLK] = &i2s5_sysclk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_mpmu_data = { + .reset_name = "k3-mpmu-reset", + .hws = k3_ccu_mpmu_hws, + .num = ARRAY_SIZE(k3_ccu_mpmu_hws), +}; + +static struct clk_hw *k3_ccu_apbc_hws[] = { + [CLK_APBC_UART0] = &uart0_clk.common.hw, + [CLK_APBC_UART2] = &uart2_clk.common.hw, + [CLK_APBC_UART3] = &uart3_clk.common.hw, + [CLK_APBC_UART4] = &uart4_clk.common.hw, + [CLK_APBC_UART5] = &uart5_clk.common.hw, + [CLK_APBC_UART6] = &uart6_clk.common.hw, + [CLK_APBC_UART7] = &uart7_clk.common.hw, + [CLK_APBC_UART8] = &uart8_clk.common.hw, + [CLK_APBC_UART9] = &uart9_clk.common.hw, + [CLK_APBC_UART10] = &uart10_clk.common.hw, + [CLK_APBC_UART0_BUS] = &uart0_bus_clk.common.hw, + [CLK_APBC_UART2_BUS] = &uart2_bus_clk.common.hw, + [CLK_APBC_UART3_BUS] = &uart3_bus_clk.common.hw, + [CLK_APBC_UART4_BUS] = &uart4_bus_clk.common.hw, + [CLK_APBC_UART5_BUS] = &uart5_bus_clk.common.hw, + [CLK_APBC_UART6_BUS] = &uart6_bus_clk.common.hw, + [CLK_APBC_UART7_BUS] = &uart7_bus_clk.common.hw, + [CLK_APBC_UART8_BUS] = &uart8_bus_clk.common.hw, + [CLK_APBC_UART9_BUS] = &uart9_bus_clk.common.hw, + [CLK_APBC_UART10_BUS] = &uart10_bus_clk.common.hw, + [CLK_APBC_GPIO] = &gpio_clk.common.hw, + [CLK_APBC_GPIO_BUS] = &gpio_bus_clk.common.hw, + [CLK_APBC_PWM0] = &pwm0_clk.common.hw, + [CLK_APBC_PWM1] = &pwm1_clk.common.hw, + [CLK_APBC_PWM2] = &pwm2_clk.common.hw, + [CLK_APBC_PWM3] = &pwm3_clk.common.hw, + [CLK_APBC_PWM4] = &pwm4_clk.common.hw, + [CLK_APBC_PWM5] = &pwm5_clk.common.hw, + [CLK_APBC_PWM6] = &pwm6_clk.common.hw, + [CLK_APBC_PWM7] = &pwm7_clk.common.hw, + [CLK_APBC_PWM8] = &pwm8_clk.common.hw, + [CLK_APBC_PWM9] = &pwm9_clk.common.hw, + [CLK_APBC_PWM10] = &pwm10_clk.common.hw, + [CLK_APBC_PWM11] = &pwm11_clk.common.hw, + [CLK_APBC_PWM12] = &pwm12_clk.common.hw, + [CLK_APBC_PWM13] = &pwm13_clk.common.hw, + [CLK_APBC_PWM14] = &pwm14_clk.common.hw, + [CLK_APBC_PWM15] = &pwm15_clk.common.hw, + [CLK_APBC_PWM16] = &pwm16_clk.common.hw, + [CLK_APBC_PWM17] = &pwm17_clk.common.hw, + [CLK_APBC_PWM18] = &pwm18_clk.common.hw, + [CLK_APBC_PWM19] = &pwm19_clk.common.hw, + [CLK_APBC_PWM0_BUS] = &pwm0_bus_clk.common.hw, + [CLK_APBC_PWM1_BUS] = &pwm1_bus_clk.common.hw, + [CLK_APBC_PWM2_BUS] = &pwm2_bus_clk.common.hw, + [CLK_APBC_PWM3_BUS] = &pwm3_bus_clk.common.hw, + [CLK_APBC_PWM4_BUS] = &pwm4_bus_clk.common.hw, + [CLK_APBC_PWM5_BUS] = &pwm5_bus_clk.common.hw, + [CLK_APBC_PWM6_BUS] = &pwm6_bus_clk.common.hw, + [CLK_APBC_PWM7_BUS] = &pwm7_bus_clk.common.hw, + [CLK_APBC_PWM8_BUS] = &pwm8_bus_clk.common.hw, + [CLK_APBC_PWM9_BUS] = &pwm9_bus_clk.common.hw, + [CLK_APBC_PWM10_BUS] = &pwm10_bus_clk.common.hw, + [CLK_APBC_PWM11_BUS] = &pwm11_bus_clk.common.hw, + [CLK_APBC_PWM12_BUS] = &pwm12_bus_clk.common.hw, + [CLK_APBC_PWM13_BUS] = &pwm13_bus_clk.common.hw, + [CLK_APBC_PWM14_BUS] = &pwm14_bus_clk.common.hw, + [CLK_APBC_PWM15_BUS] = &pwm15_bus_clk.common.hw, + [CLK_APBC_PWM16_BUS] = &pwm16_bus_clk.common.hw, + [CLK_APBC_PWM17_BUS] = &pwm17_bus_clk.common.hw, + [CLK_APBC_PWM18_BUS] = &pwm18_bus_clk.common.hw, + [CLK_APBC_PWM19_BUS] = &pwm19_bus_clk.common.hw, + [CLK_APBC_SPI0_I2S_BCLK] = &spi0_i2s_bclk.common.hw, + [CLK_APBC_SPI1_I2S_BCLK] = &spi1_i2s_bclk.common.hw, + [CLK_APBC_SPI3_I2S_BCLK] = &spi3_i2s_bclk.common.hw, + [CLK_APBC_SPI0] = &spi0_clk.common.hw, + [CLK_APBC_SPI1] = &spi1_clk.common.hw, + [CLK_APBC_SPI3] = &spi3_clk.common.hw, + [CLK_APBC_SPI0_BUS] = &spi0_bus_clk.common.hw, + [CLK_APBC_SPI1_BUS] = &spi1_bus_clk.common.hw, + [CLK_APBC_SPI3_BUS] = &spi3_bus_clk.common.hw, + [CLK_APBC_RTC] = &rtc_clk.common.hw, + [CLK_APBC_RTC_BUS] = &rtc_bus_clk.common.hw, + [CLK_APBC_TWSI0] = &twsi0_clk.common.hw, + [CLK_APBC_TWSI1] = &twsi1_clk.common.hw, + [CLK_APBC_TWSI2] = &twsi2_clk.common.hw, + [CLK_APBC_TWSI4] = &twsi4_clk.common.hw, + [CLK_APBC_TWSI5] = &twsi5_clk.common.hw, + [CLK_APBC_TWSI6] = &twsi6_clk.common.hw, + [CLK_APBC_TWSI8] = &twsi8_clk.common.hw, + [CLK_APBC_TWSI0_BUS] = &twsi0_bus_clk.common.hw, + [CLK_APBC_TWSI1_BUS] = &twsi1_bus_clk.common.hw, + [CLK_APBC_TWSI2_BUS] = &twsi2_bus_clk.common.hw, + [CLK_APBC_TWSI4_BUS] = &twsi4_bus_clk.common.hw, + [CLK_APBC_TWSI5_BUS] = &twsi5_bus_clk.common.hw, + [CLK_APBC_TWSI6_BUS] = &twsi6_bus_clk.common.hw, + [CLK_APBC_TWSI8_BUS] = &twsi8_bus_clk.common.hw, + [CLK_APBC_TIMERS0] = &timers0_clk.common.hw, + [CLK_APBC_TIMERS1] = &timers1_clk.common.hw, + [CLK_APBC_TIMERS2] = &timers2_clk.common.hw, + [CLK_APBC_TIMERS3] = &timers3_clk.common.hw, + [CLK_APBC_TIMERS4] = &timers4_clk.common.hw, + [CLK_APBC_TIMERS5] = &timers5_clk.common.hw, + [CLK_APBC_TIMERS6] = &timers6_clk.common.hw, + [CLK_APBC_TIMERS7] = &timers7_clk.common.hw, + [CLK_APBC_TIMERS0_BUS] = &timers0_bus_clk.common.hw, + [CLK_APBC_TIMERS1_BUS] = &timers1_bus_clk.common.hw, + [CLK_APBC_TIMERS2_BUS] = &timers2_bus_clk.common.hw, + [CLK_APBC_TIMERS3_BUS] = &timers3_bus_clk.common.hw, + [CLK_APBC_TIMERS4_BUS] = &timers4_bus_clk.common.hw, + [CLK_APBC_TIMERS5_BUS] = &timers5_bus_clk.common.hw, + [CLK_APBC_TIMERS6_BUS] = &timers6_bus_clk.common.hw, + [CLK_APBC_TIMERS7_BUS] = &timers7_bus_clk.common.hw, + [CLK_APBC_AIB] = &aib_clk.common.hw, + [CLK_APBC_AIB_BUS] = &aib_bus_clk.common.hw, + [CLK_APBC_ONEWIRE] = &onewire_clk.common.hw, + [CLK_APBC_ONEWIRE_BUS] = &onewire_bus_clk.common.hw, + [CLK_APBC_I2S0_BCLK] = &i2s0_i2s_bclk.common.hw, + [CLK_APBC_I2S1_BCLK] = &i2s1_i2s_bclk.common.hw, + [CLK_APBC_I2S2_BCLK] = &i2s2_i2s_bclk.common.hw, + [CLK_APBC_I2S3_BCLK] = &i2s3_i2s_bclk.common.hw, + [CLK_APBC_I2S4_BCLK] = &i2s4_i2s_bclk.common.hw, + [CLK_APBC_I2S5_BCLK] = &i2s5_i2s_bclk.common.hw, + [CLK_APBC_I2S0] = &i2s0_clk.common.hw, + [CLK_APBC_I2S1] = &i2s1_clk.common.hw, + [CLK_APBC_I2S2] = &i2s2_clk.common.hw, + [CLK_APBC_I2S3] = &i2s3_clk.common.hw, + [CLK_APBC_I2S4] = &i2s4_clk.common.hw, + [CLK_APBC_I2S5] = &i2s5_clk.common.hw, + [CLK_APBC_I2S0_BUS] = &i2s0_bus_clk.common.hw, + [CLK_APBC_I2S1_BUS] = &i2s1_bus_clk.common.hw, + [CLK_APBC_I2S2_BUS] = &i2s2_bus_clk.common.hw, + [CLK_APBC_I2S3_BUS] = &i2s3_bus_clk.common.hw, + [CLK_APBC_I2S4_BUS] = &i2s4_bus_clk.common.hw, + [CLK_APBC_I2S5_BUS] = &i2s5_bus_clk.common.hw, + [CLK_APBC_DRO] = &dro_clk.common.hw, + [CLK_APBC_IR0] = &ir0_clk.common.hw, + [CLK_APBC_IR1] = &ir1_clk.common.hw, + [CLK_APBC_TSEN] = &tsen_clk.common.hw, + [CLK_APBC_TSEN_BUS] = &tsen_bus_clk.common.hw, + [CLK_APBC_IPC_AP2RCPU] = &ipc_ap2rcpu_clk.common.hw, + [CLK_APBC_IPC_AP2RCPU_BUS] = &ipc_ap2rcpu_bus_clk.common.hw, + [CLK_APBC_CAN0] = &can0_clk.common.hw, + [CLK_APBC_CAN1] = &can1_clk.common.hw, + [CLK_APBC_CAN2] = &can2_clk.common.hw, + [CLK_APBC_CAN3] = &can3_clk.common.hw, + [CLK_APBC_CAN4] = &can4_clk.common.hw, + [CLK_APBC_CAN0_BUS] = &can0_bus_clk.common.hw, + [CLK_APBC_CAN1_BUS] = &can1_bus_clk.common.hw, + [CLK_APBC_CAN2_BUS] = &can2_bus_clk.common.hw, + [CLK_APBC_CAN3_BUS] = &can3_bus_clk.common.hw, + [CLK_APBC_CAN4_BUS] = &can4_bus_clk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_apbc_data = { + .reset_name = "k3-apbc-reset", + .hws = k3_ccu_apbc_hws, + .num = ARRAY_SIZE(k3_ccu_apbc_hws), +}; + +static struct clk_hw *k3_ccu_apmu_hws[] = { + [CLK_APMU_AXICLK] = &axi_clk.common.hw, + [CLK_APMU_CCI550] = &cci550_clk.common.hw, + [CLK_APMU_CPU_C0_CORE] = &cpu_c0_core_clk.common.hw, + [CLK_APMU_CPU_C1_CORE] = &cpu_c1_core_clk.common.hw, + [CLK_APMU_CPU_C2_CORE] = &cpu_c2_core_clk.common.hw, + [CLK_APMU_CPU_C3_CORE] = &cpu_c3_core_clk.common.hw, + [CLK_APMU_CCIC2PHY] = &ccic2phy_clk.common.hw, + [CLK_APMU_CCIC3PHY] = &ccic3phy_clk.common.hw, + [CLK_APMU_CSI] = &csi_clk.common.hw, + [CLK_APMU_ISP_BUS] = &isp_bus_clk.common.hw, + [CLK_APMU_D1P_1228P8] = &d1p_1228p8.common.hw, + [CLK_APMU_D1P_819P2] = &d1p_819p2.common.hw, + [CLK_APMU_D1P_614P4] = &d1p_614p4.common.hw, + [CLK_APMU_D1P_491P52] = &d1p_491p52.common.hw, + [CLK_APMU_D1P_409P6] = &d1p_409p6.common.hw, + [CLK_APMU_D1P_307P2] = &d1p_307p2.common.hw, + [CLK_APMU_D1P_245P76] = &d1p_245p76.common.hw, + [CLK_APMU_V2D] = &v2d_clk.common.hw, + [CLK_APMU_DSI_ESC] = &dsi_esc_clk.common.hw, + [CLK_APMU_LCD_HCLK] = &lcd_hclk.common.hw, + [CLK_APMU_LCD_DSC] = &lcd_dsc_clk.common.hw, + [CLK_APMU_LCD_PXCLK] = &lcd_pxclk.common.hw, + [CLK_APMU_LCD_MCLK] = &lcd_mclk.common.hw, + [CLK_APMU_CCIC_4X] = &ccic_4x_clk.common.hw, + [CLK_APMU_CCIC1PHY] = &ccic1phy_clk.common.hw, + [CLK_APMU_SC2_HCLK] = &sc2_hclk.common.hw, + [CLK_APMU_SDH_AXI] = &sdh_axi_aclk.common.hw, + [CLK_APMU_SDH0] = &sdh0_clk.common.hw, + [CLK_APMU_SDH1] = &sdh1_clk.common.hw, + [CLK_APMU_SDH2] = &sdh2_clk.common.hw, + [CLK_APMU_USB2_BUS] = &usb2_bus_clk.common.hw, + [CLK_APMU_USB3_PORTA_BUS] = &usb3_porta_bus_clk.common.hw, + [CLK_APMU_USB3_PORTB_BUS] = &usb3_portb_bus_clk.common.hw, + [CLK_APMU_USB3_PORTC_BUS] = &usb3_portc_bus_clk.common.hw, + [CLK_APMU_USB3_PORTD_BUS] = &usb3_portd_bus_clk.common.hw, + [CLK_APMU_QSPI] = &qspi_clk.common.hw, + [CLK_APMU_QSPI_BUS] = &qspi_bus_clk.common.hw, + [CLK_APMU_DMA] = &dma_clk.common.hw, + [CLK_APMU_AES_WTM] = &aes_wtm_clk.common.hw, + [CLK_APMU_VPU] = &vpu_clk.common.hw, + [CLK_APMU_DTC] = &dtc_clk.common.hw, + [CLK_APMU_GPU] = &gpu_clk.common.hw, + [CLK_APMU_MC_AHB] = &mc_ahb_clk.common.hw, + [CLK_APMU_TOP_DCLK] = &top_dclk.common.hw, + [CLK_APMU_UCIE] = &ucie_clk.common.hw, + [CLK_APMU_UCIE_SBCLK] = &ucie_sbclk.common.hw, + [CLK_APMU_RCPU] = &rcpu_clk.common.hw, + [CLK_APMU_DSI4LN2_DSI_ESC] = &dsi4ln2_dsi_esc_clk.common.hw, + [CLK_APMU_DSI4LN2_LCD_DSC] = &dsi4ln2_lcd_dsc_clk.common.hw, + [CLK_APMU_DSI4LN2_LCD_PXCLK] = &dsi4ln2_lcd_pxclk.common.hw, + [CLK_APMU_DSI4LN2_LCD_MCLK] = &dsi4ln2_lcd_mclk.common.hw, + [CLK_APMU_DSI4LN2_DPU_ACLK] = &dsi4ln2_dpu_aclk.common.hw, + [CLK_APMU_DPU_ACLK] = &dpu_aclk.common.hw, + [CLK_APMU_UFS_ACLK] = &ufs_aclk.common.hw, + [CLK_APMU_EDP0_PXCLK] = &edp0_pxclk.common.hw, + [CLK_APMU_EDP1_PXCLK] = &edp1_pxclk.common.hw, + [CLK_APMU_PCIE_PORTA_MSTE] = &pciea_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTA_SLV] = &pciea_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTB_MSTE] = &pcieb_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTB_SLV] = &pcieb_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTC_MSTE] = &pciec_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTC_SLV] = &pciec_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTD_MSTE] = &pcied_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTD_SLV] = &pcied_slv_clk.common.hw, + [CLK_APMU_PCIE_PORTE_MSTE] = &pciee_mstr_clk.common.hw, + [CLK_APMU_PCIE_PORTE_SLV] = &pciee_slv_clk.common.hw, + [CLK_APMU_EMAC0_BUS] = &emac0_bus_clk.common.hw, + [CLK_APMU_EMAC0_REF] = &emac0_ref_clk.common.hw, + [CLK_APMU_EMAC0_1588] = &emac0_1588_clk.common.hw, + [CLK_APMU_EMAC0_RGMII_TX] = &emac0_rgmii_tx_clk.common.hw, + [CLK_APMU_EMAC1_BUS] = &emac1_bus_clk.common.hw, + [CLK_APMU_EMAC1_REF] = &emac1_ref_clk.common.hw, + [CLK_APMU_EMAC1_1588] = &emac1_1588_clk.common.hw, + [CLK_APMU_EMAC1_RGMII_TX] = &emac1_rgmii_tx_clk.common.hw, + [CLK_APMU_EMAC2_BUS] = &emac2_bus_clk.common.hw, + [CLK_APMU_EMAC2_REF] = &emac2_ref_clk.common.hw, + [CLK_APMU_EMAC2_1588] = &emac2_1588_clk.common.hw, + [CLK_APMU_EMAC2_RGMII_TX] = &emac2_rgmii_tx_clk.common.hw, + [CLK_APMU_ESPI_SCLK_SRC] = &espi_sclk_src.common.hw, + [CLK_APMU_ESPI_SCLK] = &espi_sclk.common.hw, + [CLK_APMU_ESPI_MCLK] = &espi_mclk.common.hw, + [CLK_APMU_CAM_SRC1] = &cam_src1_clk.common.hw, + [CLK_APMU_CAM_SRC2] = &cam_src2_clk.common.hw, + [CLK_APMU_CAM_SRC3] = &cam_src3_clk.common.hw, + [CLK_APMU_CAM_SRC4] = &cam_src4_clk.common.hw, + [CLK_APMU_ISIM_VCLK0] = &isim_vclk_out0.common.hw, + [CLK_APMU_ISIM_VCLK1] = &isim_vclk_out1.common.hw, + [CLK_APMU_ISIM_VCLK2] = &isim_vclk_out2.common.hw, + [CLK_APMU_ISIM_VCLK3] = &isim_vclk_out3.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_apmu_data = { + .reset_name = "k3-apmu-reset", + .hws = k3_ccu_apmu_hws, + .num = ARRAY_SIZE(k3_ccu_apmu_hws), +}; + +static struct clk_hw *k3_ccu_dciu_hws[] = { + [CLK_DCIU_HDMA] = &hdma_clk.common.hw, + [CLK_DCIU_DMA350] = &dma350_clk.common.hw, + [CLK_DCIU_C2_TCM_PIPE] = &c2_tcm_pipe_clk.common.hw, + [CLK_DCIU_C3_TCM_PIPE] = &c3_tcm_pipe_clk.common.hw, +}; + +static const struct spacemit_ccu_data k3_ccu_dciu_data = { + .reset_name = "k3-dciu-reset", + .hws = k3_ccu_dciu_hws, + .num = ARRAY_SIZE(k3_ccu_dciu_hws), +}; + +static const struct of_device_id of_k3_ccu_match[] = { + { + .compatible = "spacemit,k3-pll", + .data = &k3_ccu_pll_data, + }, + { + .compatible = "spacemit,k3-syscon-mpmu", + .data = &k3_ccu_mpmu_data, + }, + { + .compatible = "spacemit,k3-syscon-apbc", + .data = &k3_ccu_apbc_data, + }, + { + .compatible = "spacemit,k3-syscon-apmu", + .data = &k3_ccu_apmu_data, + }, + { + .compatible = "spacemit,k3-syscon-dciu", + .data = &k3_ccu_dciu_data, + }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_k3_ccu_match); + +static int k3_ccu_probe(struct platform_device *pdev) +{ + return spacemit_ccu_probe(pdev, "spacemit,k3-pll"); +} + +static struct platform_driver k3_ccu_driver = { + .driver = { + .name = "spacemit,k3-ccu", + .of_match_table = of_k3_ccu_match, + }, + .probe = k3_ccu_probe, +}; +module_platform_driver(k3_ccu_driver); + +MODULE_IMPORT_NS("CLK_SPACEMIT"); +MODULE_DESCRIPTION("SpacemiT K3 CCU driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_common.c b/drivers/clk/spacemit/ccu_common.c new file mode 100644 index 000000000000..8696bb9cba2d --- /dev/null +++ b/drivers/clk/spacemit/ccu_common.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include + +#include "ccu_common.h" + +static DEFINE_IDA(auxiliary_ids); +static int spacemit_ccu_register(struct device *dev, + struct regmap *regmap, + struct regmap *lock_regmap, + const struct spacemit_ccu_data *data) +{ + struct clk_hw_onecell_data *clk_data; + int i, ret; + + /* Nothing to do if the CCU does not implement any clocks */ + if (!data->hws) + return 0; + + clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, data->num), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = data->num; + + for (i = 0; i < data->num; i++) { + struct clk_hw *hw = data->hws[i]; + struct ccu_common *common; + const char *name; + + if (!hw) { + clk_data->hws[i] = ERR_PTR(-ENOENT); + continue; + } + + name = hw->init->name; + + common = hw_to_ccu_common(hw); + common->regmap = regmap; + common->lock_regmap = lock_regmap; + + ret = devm_clk_hw_register(dev, hw); + if (ret) { + dev_err(dev, "Cannot register clock %d - %s\n", + i, name); + return ret; + } + + clk_data->hws[i] = hw; + } + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); + if (ret) + dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); + + return ret; +} + +static void spacemit_cadev_release(struct device *dev) +{ + struct auxiliary_device *adev = to_auxiliary_dev(dev); + + ida_free(&auxiliary_ids, adev->id); + kfree(to_spacemit_ccu_adev(adev)); +} + +static void spacemit_adev_unregister(void *data) +{ + struct auxiliary_device *adev = data; + + auxiliary_device_delete(adev); + auxiliary_device_uninit(adev); +} + +static int spacemit_ccu_reset_register(struct device *dev, + struct regmap *regmap, + const char *reset_name) +{ + struct spacemit_ccu_adev *cadev; + struct auxiliary_device *adev; + int ret; + + /* Nothing to do if the CCU does not implement a reset controller */ + if (!reset_name) + return 0; + + cadev = kzalloc_obj(*cadev); + if (!cadev) + return -ENOMEM; + + cadev->regmap = regmap; + + adev = &cadev->adev; + adev->name = reset_name; + adev->dev.parent = dev; + adev->dev.release = spacemit_cadev_release; + adev->dev.of_node = dev->of_node; + ret = ida_alloc(&auxiliary_ids, GFP_KERNEL); + if (ret < 0) + goto err_free_cadev; + adev->id = ret; + + ret = auxiliary_device_init(adev); + if (ret) + goto err_free_aux_id; + + ret = auxiliary_device_add(adev); + if (ret) { + auxiliary_device_uninit(adev); + return ret; + } + + return devm_add_action_or_reset(dev, spacemit_adev_unregister, adev); + +err_free_aux_id: + ida_free(&auxiliary_ids, adev->id); +err_free_cadev: + kfree(cadev); + + return ret; +} + +int spacemit_ccu_probe(struct platform_device *pdev, const char *compat) +{ + struct regmap *base_regmap, *lock_regmap = NULL; + const struct spacemit_ccu_data *data; + struct device *dev = &pdev->dev; + int ret; + + base_regmap = device_node_to_regmap(dev->of_node); + if (IS_ERR(base_regmap)) + return dev_err_probe(dev, PTR_ERR(base_regmap), + "failed to get regmap\n"); + + /* + * The lock status of PLLs locate in MPMU region, while PLLs themselves + * are in APBS region. Reference to MPMU syscon is required to check PLL + * status. + */ + if (compat && of_device_is_compatible(dev->of_node, compat)) { + struct device_node *mpmu = of_parse_phandle(dev->of_node, + "spacemit,mpmu", 0); + if (!mpmu) + return dev_err_probe(dev, -ENODEV, + "Cannot parse MPMU region\n"); + + lock_regmap = device_node_to_regmap(mpmu); + of_node_put(mpmu); + + if (IS_ERR(lock_regmap)) + return dev_err_probe(dev, PTR_ERR(lock_regmap), + "failed to get lock regmap\n"); + } + + data = of_device_get_match_data(dev); + + ret = spacemit_ccu_register(dev, base_regmap, lock_regmap, data); + if (ret) + return dev_err_probe(dev, ret, "failed to register clocks\n"); + + ret = spacemit_ccu_reset_register(dev, base_regmap, data->reset_name); + if (ret) + return dev_err_probe(dev, ret, "failed to register resets\n"); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_probe, "CLK_SPACEMIT"); + +MODULE_DESCRIPTION("SpacemiT CCU common clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/spacemit/ccu_common.h b/drivers/clk/spacemit/ccu_common.h index da72f3836e0b..8691698e007d 100644 --- a/drivers/clk/spacemit/ccu_common.h +++ b/drivers/clk/spacemit/ccu_common.h @@ -7,6 +7,8 @@ #ifndef _CCU_COMMON_H_ #define _CCU_COMMON_H_ +#include +#include #include struct ccu_common { @@ -24,6 +26,7 @@ struct ccu_common { /* For PLL */ struct { u32 reg_swcr1; + u32 reg_swcr2; u32 reg_swcr3; }; }; @@ -36,6 +39,12 @@ static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) return container_of(hw, struct ccu_common, hw); } +struct spacemit_ccu_data { + const char *reset_name; + struct clk_hw **hws; + size_t num; +}; + #define ccu_read(c, reg) \ ({ \ u32 tmp; \ @@ -45,4 +54,6 @@ static inline struct ccu_common *hw_to_ccu_common(struct clk_hw *hw) #define ccu_update(c, reg, mask, val) \ regmap_update_bits((c)->regmap, (c)->reg_##reg, mask, val) +int spacemit_ccu_probe(struct platform_device *pdev, const char *compat); + #endif /* _CCU_COMMON_H_ */ diff --git a/drivers/clk/spacemit/ccu_ddn.c b/drivers/clk/spacemit/ccu_ddn.c index 5b16e273bee5..b5540e0781ff 100644 --- a/drivers/clk/spacemit/ccu_ddn.c +++ b/drivers/clk/spacemit/ccu_ddn.c @@ -84,3 +84,4 @@ const struct clk_ops spacemit_ccu_ddn_ops = { .determine_rate = ccu_ddn_determine_rate, .set_rate = ccu_ddn_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_ddn_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_mix.c b/drivers/clk/spacemit/ccu_mix.c index 7b7990875372..9578366e9746 100644 --- a/drivers/clk/spacemit/ccu_mix.c +++ b/drivers/clk/spacemit/ccu_mix.c @@ -16,17 +16,19 @@ static void ccu_gate_disable(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); + struct ccu_gate_config *gate = &mix->gate; + u32 val = gate->inverted ? gate->mask : 0; - ccu_update(&mix->common, ctrl, mix->gate.mask, 0); + ccu_update(&mix->common, ctrl, gate->mask, val); } static int ccu_gate_enable(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); struct ccu_gate_config *gate = &mix->gate; + u32 val = gate->inverted ? 0 : gate->mask; - ccu_update(&mix->common, ctrl, gate->mask, gate->mask); - + ccu_update(&mix->common, ctrl, gate->mask, val); return 0; } @@ -34,8 +36,10 @@ static int ccu_gate_is_enabled(struct clk_hw *hw) { struct ccu_mix *mix = hw_to_ccu_mix(hw); struct ccu_gate_config *gate = &mix->gate; + u32 tmp = ccu_read(&mix->common, ctrl) & gate->mask; + u32 val = gate->inverted ? 0 : gate->mask; - return (ccu_read(&mix->common, ctrl) & gate->mask) == gate->mask; + return !!(tmp == val); } static unsigned long ccu_factor_recalc_rate(struct clk_hw *hw, @@ -198,24 +202,28 @@ const struct clk_ops spacemit_ccu_gate_ops = { .enable = ccu_gate_enable, .is_enabled = ccu_gate_is_enabled, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_factor_ops = { .determine_rate = ccu_factor_determine_rate, .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_factor_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_ops = { .determine_rate = ccu_mix_determine_rate, .get_parent = ccu_mux_get_parent, .set_parent = ccu_mux_set_parent, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_div_ops = { .determine_rate = ccu_mix_determine_rate, .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_div_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_factor_gate_ops = { .disable = ccu_gate_disable, @@ -226,6 +234,7 @@ const struct clk_ops spacemit_ccu_factor_gate_ops = { .recalc_rate = ccu_factor_recalc_rate, .set_rate = ccu_factor_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_factor_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_gate_ops = { .disable = ccu_gate_disable, @@ -236,6 +245,7 @@ const struct clk_ops spacemit_ccu_mux_gate_ops = { .get_parent = ccu_mux_get_parent, .set_parent = ccu_mux_set_parent, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_div_gate_ops = { .disable = ccu_gate_disable, @@ -246,6 +256,7 @@ const struct clk_ops spacemit_ccu_div_gate_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_div_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_div_gate_ops = { .disable = ccu_gate_disable, @@ -259,6 +270,7 @@ const struct clk_ops spacemit_ccu_mux_div_gate_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_div_gate_ops, "CLK_SPACEMIT"); const struct clk_ops spacemit_ccu_mux_div_ops = { .get_parent = ccu_mux_get_parent, @@ -268,3 +280,4 @@ const struct clk_ops spacemit_ccu_mux_div_ops = { .recalc_rate = ccu_div_recalc_rate, .set_rate = ccu_mix_set_rate, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_mux_div_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_mix.h b/drivers/clk/spacemit/ccu_mix.h index c406508e3504..dbba9bf49b3b 100644 --- a/drivers/clk/spacemit/ccu_mix.h +++ b/drivers/clk/spacemit/ccu_mix.h @@ -16,9 +16,11 @@ * * @mask: Mask to enable the gate. Some clocks may have more than one bit * set in this field. + * @inverted: Enable bit is inverted, 1 - disable clock, 0 - enable clock */ struct ccu_gate_config { u32 mask; + bool inverted; }; struct ccu_factor_config { @@ -48,6 +50,7 @@ struct ccu_mix { #define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } #define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } #define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } +#define CCU_GATE_FLAGS_INIT(_mask, _inverted) { .mask = _mask, .inverted = _inverted } #define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } #define CCU_PARENT_NAME(_name) { .fw_name = #_name } @@ -101,6 +104,15 @@ static struct ccu_mix _name = { \ } \ } +#define CCU_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _inverted, _flags) \ +static struct ccu_mix _name = { \ + .gate = CCU_GATE_FLAGS_INIT(_mask_gate, _inverted), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags), \ + } \ +} + #define CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ _mul, _flags) \ static struct ccu_mix _name = { \ diff --git a/drivers/clk/spacemit/ccu_pll.c b/drivers/clk/spacemit/ccu_pll.c index d92f0dae65a4..d4066a0ed452 100644 --- a/drivers/clk/spacemit/ccu_pll.c +++ b/drivers/clk/spacemit/ccu_pll.c @@ -17,6 +17,9 @@ #define PLL_SWCR3_EN ((u32)BIT(31)) #define PLL_SWCR3_MASK GENMASK(30, 0) +#define PLLA_SWCR2_EN ((u32)BIT(16)) +#define PLLA_SWCR2_MASK GENMASK(15, 8) + static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll, unsigned long rate) { @@ -148,6 +151,110 @@ static int ccu_pll_init(struct clk_hw *hw) return 0; } +static const struct ccu_pll_rate_tbl *ccu_plla_lookup_matched_entry(struct ccu_pll *pll) +{ + struct ccu_pll_config *config = &pll->config; + const struct ccu_pll_rate_tbl *entry; + u32 i, swcr1, swcr2, swcr3; + + swcr1 = ccu_read(&pll->common, swcr1); + swcr2 = ccu_read(&pll->common, swcr2); + swcr2 &= PLLA_SWCR2_MASK; + swcr3 = ccu_read(&pll->common, swcr3); + + for (i = 0; i < config->tbl_num; i++) { + entry = &config->rate_tbl[i]; + + if (swcr1 == entry->swcr1 && + swcr2 == entry->swcr2 && + swcr3 == entry->swcr3) + return entry; + } + + return NULL; +} + +static void ccu_plla_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry) +{ + struct ccu_common *common = &pll->common; + + regmap_write(common->regmap, common->reg_swcr1, entry->swcr1); + regmap_write(common->regmap, common->reg_swcr3, entry->swcr3); + ccu_update(common, swcr2, PLLA_SWCR2_MASK, entry->swcr2); +} + +static int ccu_plla_is_enabled(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return ccu_read(common, swcr2) & PLLA_SWCR2_EN; +} + +static int ccu_plla_enable(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + struct ccu_common *common = &pll->common; + unsigned int tmp; + + ccu_update(common, swcr2, PLLA_SWCR2_EN, PLLA_SWCR2_EN); + + /* check lock status */ + return regmap_read_poll_timeout_atomic(common->lock_regmap, + pll->config.reg_lock, + tmp, + tmp & pll->config.mask_lock, + PLL_DELAY_US, PLL_TIMEOUT_US); +} + +static void ccu_plla_disable(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + ccu_update(common, swcr2, PLLA_SWCR2_EN, 0); +} + +/* + * PLLAs must be gated before changing rate, which is ensured by + * flag CLK_SET_RATE_GATE. + */ +static int ccu_plla_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_pll_lookup_best_rate(pll, rate); + ccu_plla_update_param(pll, entry); + + return 0; +} + +static unsigned long ccu_plla_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_plla_lookup_matched_entry(pll); + + WARN_ON_ONCE(!entry); + + return entry ? entry->rate : 0; +} + +static int ccu_plla_init(struct clk_hw *hw) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + if (ccu_plla_lookup_matched_entry(pll)) + return 0; + + ccu_plla_disable(hw); + ccu_plla_update_param(pll, &pll->config.rate_tbl[0]); + + return 0; +} + const struct clk_ops spacemit_ccu_pll_ops = { .init = ccu_pll_init, .enable = ccu_pll_enable, @@ -157,3 +264,15 @@ const struct clk_ops spacemit_ccu_pll_ops = { .determine_rate = ccu_pll_determine_rate, .is_enabled = ccu_pll_is_enabled, }; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_pll_ops, "CLK_SPACEMIT"); + +const struct clk_ops spacemit_ccu_plla_ops = { + .init = ccu_plla_init, + .enable = ccu_plla_enable, + .disable = ccu_plla_disable, + .set_rate = ccu_plla_set_rate, + .recalc_rate = ccu_plla_recalc_rate, + .determine_rate = ccu_pll_determine_rate, + .is_enabled = ccu_plla_is_enabled, +}; +EXPORT_SYMBOL_NS_GPL(spacemit_ccu_plla_ops, "CLK_SPACEMIT"); diff --git a/drivers/clk/spacemit/ccu_pll.h b/drivers/clk/spacemit/ccu_pll.h index 0592f4c3068c..e41db5c97c1a 100644 --- a/drivers/clk/spacemit/ccu_pll.h +++ b/drivers/clk/spacemit/ccu_pll.h @@ -16,14 +16,31 @@ * configuration. * * @rate: PLL rate - * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1). - * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of - * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling - * the PLL and not contained in this field. + * @swcr1: Value of register PLLx_SW1_CTRL. + * @swcr2: Value of register PLLAx_SW2_CTRL. + * @swcr3: value of register PLLx_SW3_CTRL. + * + * See below tables for the register used in PPL/PPLA clocks + * + * Regular PLL type + * | Enable | swcr3 | PLLx_SW3_CTRL - BIT[31] | + * ----------------------------------------------- + * | Config | swcr1 | PLLx_SW1_CTRL - BIT[31:0] | + * | | swcr2 | Not used | + * | | swcr3 | PLLx_SW3_CTRL - BIT[30:0] | + * + * Special PLL type A + * | Enable | swcr2 | PLLAx_SW2_CTRL - BIT[16] | + * ----------------------------------------------- + * | Config | swcr1 | PLLAx_SW1_CTRL - BIT[31:0] | + * | | swcr2 | PLLAx_SW2_CTRL - BIT[15:8] | + * | | swcr3 | PLLAx_SW3_CTRL - BIT[31:0] | + * */ struct ccu_pll_rate_tbl { unsigned long rate; u32 swcr1; + u32 swcr2; u32 swcr3; }; @@ -36,11 +53,19 @@ struct ccu_pll_config { #define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \ { \ - .rate = _rate, \ + .rate = _rate, \ .swcr1 = _swcr1, \ .swcr3 = _swcr3, \ } +#define CCU_PLLA_RATE(_rate, _swcr1, _swcr2, _swcr3) \ + { \ + .rate = _rate, \ + .swcr1 = _swcr1, \ + .swcr2 = _swcr2, \ + .swcr3 = _swcr3, \ + } + struct ccu_pll { struct ccu_common common; struct ccu_pll_config config; @@ -54,26 +79,37 @@ struct ccu_pll { .mask_lock = (_mask_lock), \ } -#define CCU_PLL_HWINIT(_name, _flags) \ +#define CCU_PLL_COMMON_HWINIT(_name, _ops, _flags) \ (&(struct clk_init_data) { \ .name = #_name, \ - .ops = &spacemit_ccu_pll_ops, \ + .ops = _ops, \ .parent_data = &(struct clk_parent_data) { .index = 0 }, \ .num_parents = 1, \ .flags = _flags, \ }) -#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \ - _mask_lock, _flags) \ +#define CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, _ops, _flags) \ static struct ccu_pll _name = { \ .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \ .common = { \ .reg_swcr1 = _reg_swcr1, \ + .reg_swcr2 = _reg_swcr2, \ .reg_swcr3 = _reg_swcr3, \ - .hw.init = CCU_PLL_HWINIT(_name, _flags) \ + .hw.init = CCU_PLL_COMMON_HWINIT(_name, _ops, _flags) \ } \ } +#define CCU_PLL_DEFINE(_name, _table, _reg_swcr1, _reg_swcr3, _reg_lock, \ + _mask_lock, _flags) \ + CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, 0, _reg_swcr3, \ + _reg_lock, _mask_lock, &spacemit_ccu_pll_ops, _flags) + +#define CCU_PLLA_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, _flags) \ + CCU_PLL_X_DEFINE(_name, _table, _reg_swcr1, _reg_swcr2, _reg_swcr3, \ + _reg_lock, _mask_lock, &spacemit_ccu_plla_ops, _flags) + static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) { struct ccu_common *common = hw_to_ccu_common(hw); @@ -82,5 +118,6 @@ static inline struct ccu_pll *hw_to_ccu_pll(struct clk_hw *hw) } extern const struct clk_ops spacemit_ccu_pll_ops; +extern const struct clk_ops spacemit_ccu_plla_ops; #endif diff --git a/drivers/clk/spear/clk-aux-synth.c b/drivers/clk/spear/clk-aux-synth.c index d0d063147af8..61a8c3d4c1e4 100644 --- a/drivers/clk/spear/clk-aux-synth.c +++ b/drivers/clk/spear/clk-aux-synth.c @@ -147,7 +147,7 @@ struct clk *clk_register_aux(const char *aux_name, const char *gate_name, return ERR_PTR(-EINVAL); } - aux = kzalloc(sizeof(*aux), GFP_KERNEL); + aux = kzalloc_obj(*aux); if (!aux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/spear/clk-frac-synth.c b/drivers/clk/spear/clk-frac-synth.c index 150f051d28e0..3549f1cfdae1 100644 --- a/drivers/clk/spear/clk-frac-synth.c +++ b/drivers/clk/spear/clk-frac-synth.c @@ -134,7 +134,7 @@ struct clk *clk_register_frac(const char *name, const char *parent_name, return ERR_PTR(-EINVAL); } - frac = kzalloc(sizeof(*frac), GFP_KERNEL); + frac = kzalloc_obj(*frac); if (!frac) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/spear/clk-gpt-synth.c b/drivers/clk/spear/clk-gpt-synth.c index cf9659dc9073..1a431d7ec20c 100644 --- a/drivers/clk/spear/clk-gpt-synth.c +++ b/drivers/clk/spear/clk-gpt-synth.c @@ -123,7 +123,7 @@ struct clk *clk_register_gpt(const char *name, const char *parent_name, unsigned return ERR_PTR(-EINVAL); } - gpt = kzalloc(sizeof(*gpt), GFP_KERNEL); + gpt = kzalloc_obj(*gpt); if (!gpt) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/spear/clk-vco-pll.c b/drivers/clk/spear/clk-vco-pll.c index 723a6eb67754..601e123f5c4b 100644 --- a/drivers/clk/spear/clk-vco-pll.c +++ b/drivers/clk/spear/clk-vco-pll.c @@ -293,11 +293,11 @@ struct clk *clk_register_vco_pll(const char *vco_name, const char *pll_name, return ERR_PTR(-EINVAL); } - vco = kzalloc(sizeof(*vco), GFP_KERNEL); + vco = kzalloc_obj(*vco); if (!vco) return ERR_PTR(-ENOMEM); - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) goto free_vco; diff --git a/drivers/clk/sprd/div.c b/drivers/clk/sprd/div.c index 013423881968..cd57163a7204 100644 --- a/drivers/clk/sprd/div.c +++ b/drivers/clk/sprd/div.c @@ -14,11 +14,7 @@ static int sprd_div_determine_rate(struct clk_hw *hw, { struct sprd_div *cd = hw_to_sprd_div(hw); - req->rate = divider_round_rate(&cd->common.hw, req->rate, - &req->best_parent_rate, - NULL, cd->div.width, 0); - - return 0; + return divider_determine_rate(&cd->common.hw, req, NULL, cd->div.width, 0); } unsigned long sprd_div_helper_recalc_rate(struct sprd_clk_common *common, diff --git a/drivers/clk/sprd/pll.c b/drivers/clk/sprd/pll.c index bc6610d5fcb7..bc2db19aec0e 100644 --- a/drivers/clk/sprd/pll.c +++ b/drivers/clk/sprd/pll.c @@ -155,7 +155,7 @@ static int _sprd_pll_set_rate(const struct sprd_pll *pll, unsigned long kint, nint; u64 tmp, refin, fvco = rate; - cfg = kcalloc(regs_num, sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_objs(*cfg, regs_num); if (!cfg) return -ENOMEM; diff --git a/drivers/clk/st/clk-flexgen.c b/drivers/clk/st/clk-flexgen.c index e8e7626c76db..211535fd8ac9 100644 --- a/drivers/clk/st/clk-flexgen.c +++ b/drivers/clk/st/clk-flexgen.c @@ -213,7 +213,7 @@ static struct clk *clk_register_flexgen(const char *name, u32 xbar_shift; void __iomem *xbar_reg, *fdiv_reg; - fgxbar = kzalloc(sizeof(struct flexgen), GFP_KERNEL); + fgxbar = kzalloc_obj(struct flexgen); if (!fgxbar) return ERR_PTR(-ENOMEM); @@ -596,7 +596,7 @@ static void __init st_of_flexgen_setup(struct device_node *np) clk_mode = data->mode; } - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) goto err; @@ -612,12 +612,11 @@ static void __init st_of_flexgen_setup(struct device_node *np) } else clk_data->clk_num = data->outputs_nb; - clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), - GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, clk_data->clk_num); if (!clk_data->clks) goto err; - rlock = kzalloc(sizeof(spinlock_t), GFP_KERNEL); + rlock = kzalloc_obj(spinlock_t); if (!rlock) goto err; diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index e06e7e5cc1a5..3fcc1da20c04 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -454,7 +454,7 @@ static struct clk * __init st_clk_register_quadfs_pll( if (WARN_ON(!name || !parent_name)) return ERR_PTR(-EINVAL); - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -894,7 +894,7 @@ static struct clk * __init st_clk_register_quadfs_fsynth( if (WARN_ON(!name || !parent_name)) return ERR_PTR(-EINVAL); - fs = kzalloc(sizeof(*fs), GFP_KERNEL); + fs = kzalloc_obj(*fs); if (!fs) return ERR_PTR(-ENOMEM); @@ -926,13 +926,12 @@ static void __init st_of_create_quadfs_fsynths( struct clk_onecell_data *clk_data; int fschan; - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) return; clk_data->clk_num = QUADFS_MAX_CHAN; - clk_data->clks = kcalloc(QUADFS_MAX_CHAN, sizeof(struct clk *), - GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, QUADFS_MAX_CHAN); if (!clk_data->clks) { kfree(clk_data); @@ -1013,7 +1012,7 @@ static void __init st_of_quadfs_setup(struct device_node *np, if (!pll_name) return; - lock = kzalloc(sizeof(*lock), GFP_KERNEL); + lock = kzalloc_obj(*lock); if (!lock) goto err_exit; diff --git a/drivers/clk/st/clkgen-pll.c b/drivers/clk/st/clkgen-pll.c index c258ff87a171..9eb2cb83fa69 100644 --- a/drivers/clk/st/clkgen-pll.c +++ b/drivers/clk/st/clkgen-pll.c @@ -656,7 +656,7 @@ static struct clk * __init clkgen_pll_register(const char *parent_name, struct clk *clk; struct clk_init_data init; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -716,7 +716,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, flags = pll_flags | CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); @@ -725,7 +725,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name, gate->bit_idx = pll_data->odf_gate[odf].shift; gate->lock = odf_lock; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) { kfree(gate); return ERR_PTR(-ENOMEM); @@ -783,13 +783,12 @@ static void __init clkgen_c32_pll_setup(struct device_node *np, num_odfs = datac->data->num_odfs; - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) return; clk_data->clk_num = num_odfs; - clk_data->clks = kcalloc(clk_data->clk_num, sizeof(struct clk *), - GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, clk_data->clk_num); if (!clk_data->clks) goto err; diff --git a/drivers/clk/starfive/clk-starfive-jh7110-sys.c b/drivers/clk/starfive/clk-starfive-jh7110-sys.c index 52833d4241c5..03c17cd2032f 100644 --- a/drivers/clk/starfive/clk-starfive-jh7110-sys.c +++ b/drivers/clk/starfive/clk-starfive-jh7110-sys.c @@ -347,7 +347,7 @@ int jh7110_reset_controller_register(struct jh71x0_clk_priv *priv, struct auxiliary_device *adev; int ret; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return -ENOMEM; diff --git a/drivers/clk/stm32/clk-stm32-core.c b/drivers/clk/stm32/clk-stm32-core.c index 72825b9c36a4..e921c25a929c 100644 --- a/drivers/clk/stm32/clk-stm32-core.c +++ b/drivers/clk/stm32/clk-stm32-core.c @@ -369,22 +369,14 @@ static int clk_stm32_divider_determine_rate(struct clk_hw *hw, val = readl(div->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - req->rate = divider_ro_round_rate(hw, req->rate, - &req->best_parent_rate, - divider->table, - divider->width, - divider->flags, val); - - return 0; + return divider_ro_determine_rate(hw, req, + divider->table, + divider->width, + divider->flags, val); } - req->rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), - req->rate, - &req->best_parent_rate, - divider->table, - divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static unsigned long clk_stm32_divider_recalc_rate(struct clk_hw *hw, @@ -441,7 +433,6 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw, { struct clk_stm32_composite *composite = to_clk_stm32_composite(hw); const struct stm32_div_cfg *divider; - long rate; if (composite->div_id == NO_STM32_DIV) return 0; @@ -455,24 +446,13 @@ static int clk_stm32_composite_determine_rate(struct clk_hw *hw, val = readl(composite->base + divider->offset) >> divider->shift; val &= clk_div_mask(divider->width); - rate = divider_ro_round_rate(hw, req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags, - val); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, divider->flags, + val); } - rate = divider_round_rate_parent(hw, clk_hw_get_parent(hw), - req->rate, &req->best_parent_rate, - divider->table, divider->width, divider->flags); - if (rate < 0) - return rate; - - req->rate = rate; - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static u8 clk_stm32_composite_get_parent(struct clk_hw *hw) diff --git a/drivers/clk/stm32/reset-stm32.c b/drivers/clk/stm32/reset-stm32.c index 5a8f525842ce..fc237fccae68 100644 --- a/drivers/clk/stm32/reset-stm32.c +++ b/drivers/clk/stm32/reset-stm32.c @@ -130,7 +130,7 @@ int stm32_rcc_reset_init(struct device *dev, struct clk_stm32_reset_data *data, { struct stm32_reset_data *reset_data; - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + reset_data = kzalloc_obj(*reset_data); if (!reset_data) return -ENOMEM; diff --git a/drivers/clk/sunxi-ng/ccu_common.c b/drivers/clk/sunxi-ng/ccu_common.c index c7e00f0c29a5..1c083b4d0b7e 100644 --- a/drivers/clk/sunxi-ng/ccu_common.c +++ b/drivers/clk/sunxi-ng/ccu_common.c @@ -242,7 +242,7 @@ void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg, struct sunxi_ccu *ccu; int ret; - ccu = kzalloc(sizeof(*ccu), GFP_KERNEL); + ccu = kzalloc_obj(*ccu); if (!ccu) return; diff --git a/drivers/clk/sunxi-ng/ccu_div.c b/drivers/clk/sunxi-ng/ccu_div.c index 916d6da6d8a3..62d680ccb524 100644 --- a/drivers/clk/sunxi-ng/ccu_div.c +++ b/drivers/clk/sunxi-ng/ccu_div.c @@ -10,26 +10,25 @@ #include "ccu_gate.h" #include "ccu_div.h" -static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_div_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_div *cd = data; + int ret; if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= cd->fixed_post_div; + req->rate *= cd->fixed_post_div; - rate = divider_round_rate_parent(&cd->common.hw, parent, - rate, parent_rate, - cd->div.table, cd->div.width, - cd->div.flags); + ret = divider_determine_rate(&cd->common.hw, req, cd->div.table, + cd->div.width, cd->div.flags); + if (ret) + return ret; if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= cd->fixed_post_div; + req->rate /= cd->fixed_post_div; - return rate; + return 0; } static void ccu_div_disable(struct clk_hw *hw) @@ -82,7 +81,7 @@ static int ccu_div_determine_rate(struct clk_hw *hw, struct ccu_div *cd = hw_to_ccu_div(hw); return ccu_mux_helper_determine_rate(&cd->common, &cd->mux, - req, ccu_div_round_rate, cd); + req, ccu_div_determine_rate_helper, cd); } static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mp.c b/drivers/clk/sunxi-ng/ccu_mp.c index 4221b1888b38..7cdb0eedc69b 100644 --- a/drivers/clk/sunxi-ng/ccu_mp.c +++ b/drivers/clk/sunxi-ng/ccu_mp.c @@ -103,11 +103,9 @@ static unsigned long ccu_mp_find_best_with_parent_adj(struct clk_hw *hw, return best_rate; } -static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *hw, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_mp_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_mp *cmp = data; unsigned int max_m, max_p; @@ -115,7 +113,7 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, bool shift = true; if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= cmp->fixed_post_div; + req->rate *= cmp->fixed_post_div; if (cmp->common.features & CCU_FEATURE_DUAL_DIV) shift = false; @@ -127,17 +125,19 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux, max_p = cmp->p.max ?: 1 << cmp->p.width; if (!clk_hw_can_set_rate_parent(&cmp->common.hw)) { - rate = ccu_mp_find_best(*parent_rate, rate, max_m, max_p, shift, - &m, &p); + req->rate = ccu_mp_find_best(req->best_parent_rate, req->rate, + max_m, max_p, shift, &m, &p); } else { - rate = ccu_mp_find_best_with_parent_adj(hw, parent_rate, rate, - max_m, max_p, shift); + req->rate = ccu_mp_find_best_with_parent_adj(req->best_parent_hw, + &req->best_parent_rate, + req->rate, max_m, max_p, + shift); } if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= cmp->fixed_post_div; + req->rate /= cmp->fixed_post_div; - return rate; + return 0; } static void ccu_mp_disable(struct clk_hw *hw) @@ -201,7 +201,7 @@ static int ccu_mp_determine_rate(struct clk_hw *hw, struct ccu_mp *cmp = hw_to_ccu_mp(hw); return ccu_mux_helper_determine_rate(&cmp->common, &cmp->mux, - req, ccu_mp_round_rate, cmp); + req, ccu_mp_determine_rate_helper, cmp); } static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mult.c b/drivers/clk/sunxi-ng/ccu_mult.c index 8d5720f3dec1..3fc81e7de6e9 100644 --- a/drivers/clk/sunxi-ng/ccu_mult.c +++ b/drivers/clk/sunxi-ng/ccu_mult.c @@ -29,11 +29,9 @@ static void ccu_mult_find_best(unsigned long parent, unsigned long rate, mult->mult = _mult; } -static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_mult_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_mult *cm = data; struct _ccu_mult _cm; @@ -45,9 +43,11 @@ static unsigned long ccu_mult_round_rate(struct ccu_mux_internal *mux, else _cm.max = (1 << cm->mult.width) + cm->mult.offset - 1; - ccu_mult_find_best(*parent_rate, rate, &_cm); + ccu_mult_find_best(req->best_parent_rate, req->rate, &_cm); - return *parent_rate * _cm.mult; + req->rate = req->best_parent_rate * _cm.mult; + + return 0; } static void ccu_mult_disable(struct clk_hw *hw) @@ -97,7 +97,7 @@ static int ccu_mult_determine_rate(struct clk_hw *hw, struct ccu_mult *cm = hw_to_ccu_mult(hw); return ccu_mux_helper_determine_rate(&cm->common, &cm->mux, - req, ccu_mult_round_rate, cm); + req, ccu_mult_determine_rate_helper, cm); } static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi-ng/ccu_mux.c b/drivers/clk/sunxi-ng/ccu_mux.c index 74f9e98a5d35..766f27cff748 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.c +++ b/drivers/clk/sunxi-ng/ccu_mux.c @@ -79,41 +79,46 @@ static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, - unsigned long (*round)(struct ccu_mux_internal *, - struct clk_hw *, - unsigned long *, - unsigned long, - void *), + int (*round)(struct ccu_mux_internal *, + struct clk_rate_request *, + void *), void *data) { unsigned long best_parent_rate = 0, best_rate = 0; struct clk_hw *best_parent, *hw = &common->hw; unsigned int i; + int ret; if (clk_hw_get_flags(hw) & CLK_SET_RATE_NO_REPARENT) { - unsigned long adj_parent_rate; + struct clk_rate_request adj_req = *req; best_parent = clk_hw_get_parent(hw); best_parent_rate = clk_hw_get_rate(best_parent); - adj_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, - best_parent_rate); - best_rate = round(cm, best_parent, &adj_parent_rate, - req->rate, data); + adj_req.best_parent_hw = best_parent; + adj_req.best_parent_rate = ccu_mux_helper_apply_prediv(common, cm, -1, + best_parent_rate); + + ret = round(cm, &adj_req, data); + if (ret) + return ret; + + best_rate = adj_req.rate; /* - * adj_parent_rate might have been modified by our clock. + * best_parent_rate might have been modified by our clock. * Unapply the pre-divider if there's one, and give * the actual frequency the parent needs to run at. */ best_parent_rate = ccu_mux_helper_unapply_prediv(common, cm, -1, - adj_parent_rate); + adj_req.best_parent_rate); goto out; } for (i = 0; i < clk_hw_get_num_parents(hw); i++) { - unsigned long tmp_rate, parent_rate; + struct clk_rate_request tmp_req = *req; + unsigned long parent_rate; struct clk_hw *parent; parent = clk_hw_get_parent_by_index(hw, i); @@ -123,7 +128,12 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, parent_rate = ccu_mux_helper_apply_prediv(common, cm, i, clk_hw_get_rate(parent)); - tmp_rate = round(cm, parent, &parent_rate, req->rate, data); + tmp_req.best_parent_hw = parent; + tmp_req.best_parent_rate = parent_rate; + + ret = round(cm, &tmp_req, data); + if (ret) + continue; /* * parent_rate might have been modified by our clock. @@ -131,16 +141,17 @@ int ccu_mux_helper_determine_rate(struct ccu_common *common, * the actual frequency the parent needs to run at. */ parent_rate = ccu_mux_helper_unapply_prediv(common, cm, i, - parent_rate); - if (tmp_rate == req->rate) { + tmp_req.best_parent_rate); + + if (tmp_req.rate == req->rate) { best_parent = parent; best_parent_rate = parent_rate; - best_rate = tmp_rate; + best_rate = tmp_req.rate; goto out; } - if (ccu_is_better_rate(common, req->rate, tmp_rate, best_rate)) { - best_rate = tmp_rate; + if (ccu_is_better_rate(common, req->rate, tmp_req.rate, best_rate)) { + best_rate = tmp_req.rate; best_parent_rate = parent_rate; best_parent = parent; } diff --git a/drivers/clk/sunxi-ng/ccu_mux.h b/drivers/clk/sunxi-ng/ccu_mux.h index eb1172ebbd94..c94a4bde5d01 100644 --- a/drivers/clk/sunxi-ng/ccu_mux.h +++ b/drivers/clk/sunxi-ng/ccu_mux.h @@ -137,11 +137,9 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common, int ccu_mux_helper_determine_rate(struct ccu_common *common, struct ccu_mux_internal *cm, struct clk_rate_request *req, - unsigned long (*round)(struct ccu_mux_internal *, - struct clk_hw *, - unsigned long *, - unsigned long, - void *), + int (*round)(struct ccu_mux_internal *, + struct clk_rate_request *, + void *), void *data); u8 ccu_mux_helper_get_parent(struct ccu_common *common, struct ccu_mux_internal *cm); diff --git a/drivers/clk/sunxi-ng/ccu_nkm.c b/drivers/clk/sunxi-ng/ccu_nkm.c index 784eec9ac997..401fbb752479 100644 --- a/drivers/clk/sunxi-ng/ccu_nkm.c +++ b/drivers/clk/sunxi-ng/ccu_nkm.c @@ -162,11 +162,9 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw, return rate; } -static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, - struct clk_hw *parent_hw, - unsigned long *parent_rate, - unsigned long rate, - void *data) +static int ccu_nkm_determine_rate_helper(struct ccu_mux_internal *mux, + struct clk_rate_request *req, + void *data) { struct ccu_nkm *nkm = data; struct _ccu_nkm _nkm; @@ -179,18 +177,21 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux, _nkm.max_m = nkm->m.max ?: 1 << nkm->m.width; if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate *= nkm->fixed_post_div; + req->rate *= nkm->fixed_post_div; if (!clk_hw_can_set_rate_parent(&nkm->common.hw)) - rate = ccu_nkm_find_best(*parent_rate, rate, &_nkm, &nkm->common); + req->rate = ccu_nkm_find_best(req->best_parent_rate, req->rate, + &_nkm, &nkm->common); else - rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, parent_hw, parent_rate, rate, - &_nkm); + req->rate = ccu_nkm_find_best_with_parent_adj(&nkm->common, + req->best_parent_hw, + &req->best_parent_rate, + req->rate, &_nkm); if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV) - rate /= nkm->fixed_post_div; + req->rate /= nkm->fixed_post_div; - return rate; + return 0; } static int ccu_nkm_determine_rate(struct clk_hw *hw, @@ -199,7 +200,7 @@ static int ccu_nkm_determine_rate(struct clk_hw *hw, struct ccu_nkm *nkm = hw_to_ccu_nkm(hw); return ccu_mux_helper_determine_rate(&nkm->common, &nkm->mux, - req, ccu_nkm_round_rate, nkm); + req, ccu_nkm_determine_rate_helper, nkm); } static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate, diff --git a/drivers/clk/sunxi/clk-a10-hosc.c b/drivers/clk/sunxi/clk-a10-hosc.c index f07e976839eb..29eb5a024ac2 100644 --- a/drivers/clk/sunxi/clk-a10-hosc.c +++ b/drivers/clk/sunxi/clk-a10-hosc.c @@ -26,10 +26,10 @@ static void __init sun4i_osc_clk_setup(struct device_node *node) return; /* allocate fixed-rate and gate clock structs */ - fixed = kzalloc(sizeof(struct clk_fixed_rate), GFP_KERNEL); + fixed = kzalloc_obj(struct clk_fixed_rate); if (!fixed) return; - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc_obj(struct clk_gate); if (!gate) goto err_free_fixed; diff --git a/drivers/clk/sunxi/clk-a10-mod1.c b/drivers/clk/sunxi/clk-a10-mod1.c index 39ad56d753ba..3e267e293ae5 100644 --- a/drivers/clk/sunxi/clk-a10-mod1.c +++ b/drivers/clk/sunxi/clk-a10-mod1.c @@ -32,11 +32,11 @@ static void __init sun4i_mod1_clk_setup(struct device_node *node) if (IS_ERR(reg)) return; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) goto err_unmap; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto err_free_mux; diff --git a/drivers/clk/sunxi/clk-a10-pll2.c b/drivers/clk/sunxi/clk-a10-pll2.c index 2ea3b42320a6..96ebe72429b6 100644 --- a/drivers/clk/sunxi/clk-a10-pll2.c +++ b/drivers/clk/sunxi/clk-a10-pll2.c @@ -50,11 +50,11 @@ static void __init sun4i_pll2_setup(struct device_node *node, if (IS_ERR(reg)) return; - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) goto err_unmap; - clks = kcalloc(SUN4I_PLL2_OUTPUTS, sizeof(struct clk *), GFP_KERNEL); + clks = kzalloc_objs(struct clk *, SUN4I_PLL2_OUTPUTS); if (!clks) goto err_free_data; @@ -71,7 +71,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, } /* Setup the gate part of the PLL2 */ - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc_obj(struct clk_gate); if (!gate) goto err_unregister_prediv; @@ -80,7 +80,7 @@ static void __init sun4i_pll2_setup(struct device_node *node, gate->lock = &sun4i_a10_pll2_lock; /* Setup the multiplier part of the PLL2 */ - mult = kzalloc(sizeof(struct clk_multiplier), GFP_KERNEL); + mult = kzalloc_obj(struct clk_multiplier); if (!mult) goto err_free_gate; diff --git a/drivers/clk/sunxi/clk-a10-ve.c b/drivers/clk/sunxi/clk-a10-ve.c index 65810937a13a..75a5019565d8 100644 --- a/drivers/clk/sunxi/clk-a10-ve.c +++ b/drivers/clk/sunxi/clk-a10-ve.c @@ -97,11 +97,11 @@ static void __init sun4i_ve_clk_setup(struct device_node *node) if (IS_ERR(reg)) return; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto err_unmap; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto err_free_div; @@ -129,7 +129,7 @@ static void __init sun4i_ve_clk_setup(struct device_node *node) if (err) goto err_unregister_clk; - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + reset_data = kzalloc_obj(*reset_data); if (!reset_data) goto err_del_provider; diff --git a/drivers/clk/sunxi/clk-a20-gmac.c b/drivers/clk/sunxi/clk-a20-gmac.c index 43080c7d045b..2a81536b645c 100644 --- a/drivers/clk/sunxi/clk-a20-gmac.c +++ b/drivers/clk/sunxi/clk-a20-gmac.c @@ -63,11 +63,11 @@ static void __init sun7i_a20_gmac_clk_setup(struct device_node *node) return; /* allocate mux and gate clock structs */ - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); + mux = kzalloc_obj(struct clk_mux); if (!mux) return; - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc_obj(struct clk_gate); if (!gate) goto free_mux; diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c index 4d8f0422b876..149187f189d6 100644 --- a/drivers/clk/sunxi/clk-factors.c +++ b/drivers/clk/sunxi/clk-factors.c @@ -200,7 +200,7 @@ static struct clk *__sunxi_factors_register(struct device_node *node, else of_property_read_string(node, "clock-output-names", &clk_name); - factors = kzalloc(sizeof(struct clk_factors), GFP_KERNEL); + factors = kzalloc_obj(struct clk_factors); if (!factors) goto err_factors; @@ -213,7 +213,7 @@ static struct clk *__sunxi_factors_register(struct device_node *node, /* Add a gate if this factor clock can be gated */ if (data->enable) { - gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL); + gate = kzalloc_obj(struct clk_gate); if (!gate) goto err_gate; @@ -228,7 +228,7 @@ static struct clk *__sunxi_factors_register(struct device_node *node, /* Add a mux if this factor clock can be muxed */ if (data->mux) { - mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL); + mux = kzalloc_obj(struct clk_mux); if (!mux) goto err_mux; diff --git a/drivers/clk/sunxi/clk-mod0.c b/drivers/clk/sunxi/clk-mod0.c index 51800289ada9..b409a8d70962 100644 --- a/drivers/clk/sunxi/clk-mod0.c +++ b/drivers/clk/sunxi/clk-mod0.c @@ -300,11 +300,11 @@ static void __init sunxi_mmc_setup(struct device_node *node, return; } - clk_data = kmalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kmalloc_obj(*clk_data); if (!clk_data) return; - clk_data->clks = kcalloc(3, sizeof(*clk_data->clks), GFP_KERNEL); + clk_data->clks = kzalloc_objs(*clk_data->clks, 3); if (!clk_data->clks) goto err_free_data; @@ -323,7 +323,7 @@ static void __init sunxi_mmc_setup(struct device_node *node, }; struct mmc_phase *phase; - phase = kmalloc(sizeof(*phase), GFP_KERNEL); + phase = kmalloc_obj(*phase); if (!phase) continue; diff --git a/drivers/clk/sunxi/clk-simple-gates.c b/drivers/clk/sunxi/clk-simple-gates.c index 845efc1ec800..99e83ada7af6 100644 --- a/drivers/clk/sunxi/clk-simple-gates.c +++ b/drivers/clk/sunxi/clk-simple-gates.c @@ -34,14 +34,14 @@ static void __init sunxi_simple_gates_setup(struct device_node *node, clk_parent = of_clk_get_parent_name(node, 0); - clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); + clk_data = kmalloc_obj(struct clk_onecell_data); if (!clk_data) goto err_unmap; number = of_property_count_u32_elems(node, "clock-indices"); of_property_read_u32_index(node, "clock-indices", number - 1, &number); - clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, number + 1); if (!clk_data->clks) goto err_free_data; diff --git a/drivers/clk/sunxi/clk-sun4i-display.c b/drivers/clk/sunxi/clk-sun4i-display.c index 35d1541bedd9..e17325e741e1 100644 --- a/drivers/clk/sunxi/clk-sun4i-display.c +++ b/drivers/clk/sunxi/clk-sun4i-display.c @@ -126,7 +126,7 @@ static void __init sun4i_a10_display_init(struct device_node *node, goto unmap; } - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) goto unmap; @@ -135,7 +135,7 @@ static void __init sun4i_a10_display_init(struct device_node *node, mux->mask = (1 << data->width_mux) - 1; mux->lock = &sun4i_a10_display_lock; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto free_mux; @@ -144,7 +144,7 @@ static void __init sun4i_a10_display_init(struct device_node *node, gate->lock = &sun4i_a10_display_lock; if (data->has_div) { - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto free_gate; @@ -175,7 +175,7 @@ static void __init sun4i_a10_display_init(struct device_node *node, if (!data->num_rst) return; - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + reset_data = kzalloc_obj(*reset_data); if (!reset_data) goto free_of_clk; diff --git a/drivers/clk/sunxi/clk-sun4i-pll3.c b/drivers/clk/sunxi/clk-sun4i-pll3.c index 5328588fa2de..1b8b1959dc19 100644 --- a/drivers/clk/sunxi/clk-sun4i-pll3.c +++ b/drivers/clk/sunxi/clk-sun4i-pll3.c @@ -37,7 +37,7 @@ static void __init sun4i_a10_pll3_setup(struct device_node *node) return; } - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto err_unmap; @@ -45,7 +45,7 @@ static void __init sun4i_a10_pll3_setup(struct device_node *node) gate->bit_idx = SUN4I_A10_PLL3_GATE_BIT; gate->lock = &sun4i_a10_pll3_lock; - mult = kzalloc(sizeof(*mult), GFP_KERNEL); + mult = kzalloc_obj(*mult); if (!mult) goto err_free_gate; diff --git a/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c index 277a240b65a1..b61eba112a7f 100644 --- a/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c +++ b/drivers/clk/sunxi/clk-sun4i-tcon-ch1.c @@ -246,7 +246,7 @@ static void __init tcon_ch1_setup(struct device_node *node) goto err_unmap; } - tclk = kzalloc(sizeof(*tclk), GFP_KERNEL); + tclk = kzalloc_obj(*tclk); if (!tclk) goto err_unmap; diff --git a/drivers/clk/sunxi/clk-sun8i-bus-gates.c b/drivers/clk/sunxi/clk-sun8i-bus-gates.c index 8482ac8e5898..df0f055bae5c 100644 --- a/drivers/clk/sunxi/clk-sun8i-bus-gates.c +++ b/drivers/clk/sunxi/clk-sun8i-bus-gates.c @@ -44,14 +44,14 @@ static void __init sun8i_h3_bus_gates_init(struct device_node *node) parents[i] = of_clk_get_parent_name(node, idx); } - clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); + clk_data = kmalloc_obj(struct clk_onecell_data); if (!clk_data) goto err_unmap; number = of_property_count_u32_elems(node, "clock-indices"); of_property_read_u32_index(node, "clock-indices", number - 1, &number); - clk_data->clks = kcalloc(number + 1, sizeof(struct clk *), GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, number + 1); if (!clk_data->clks) goto err_free_data; diff --git a/drivers/clk/sunxi/clk-sun8i-mbus.c b/drivers/clk/sunxi/clk-sun8i-mbus.c index 539ea278823d..fe7a0693b15d 100644 --- a/drivers/clk/sunxi/clk-sun8i-mbus.c +++ b/drivers/clk/sunxi/clk-sun8i-mbus.c @@ -44,15 +44,15 @@ static void __init sun8i_a23_mbus_setup(struct device_node *node) goto err_free_parents; } - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) goto err_unmap; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) goto err_free_div; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto err_free_mux; diff --git a/drivers/clk/sunxi/clk-sun9i-cpus.c b/drivers/clk/sunxi/clk-sun9i-cpus.c index 48bf899bb2bc..516a94f28750 100644 --- a/drivers/clk/sunxi/clk-sun9i-cpus.c +++ b/drivers/clk/sunxi/clk-sun9i-cpus.c @@ -191,7 +191,7 @@ static void sun9i_a80_cpus_setup(struct device_node *node) struct clk *clk; int ret; - cpus = kzalloc(sizeof(*cpus), GFP_KERNEL); + cpus = kzalloc_obj(*cpus); if (!cpus) return; @@ -204,7 +204,7 @@ static void sun9i_a80_cpus_setup(struct device_node *node) /* we have a mux, we will have >1 parents */ ret = of_clk_parent_fill(node, parents, SUN9I_CPUS_MAX_PARENTS); - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) goto err_unmap; diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c index 4999504f7e60..c6557c1de33f 100644 --- a/drivers/clk/sunxi/clk-sunxi.c +++ b/drivers/clk/sunxi/clk-sunxi.c @@ -991,11 +991,11 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, return NULL; } - clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); + clk_data = kmalloc_obj(struct clk_onecell_data); if (!clk_data) goto out_unmap; - clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL); + clks = kzalloc_objs(*clks, ndivs); if (!clks) goto free_clkdata; @@ -1022,7 +1022,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, /* If this leaf clock can be gated, create a gate */ if (data->div[i].gate) { - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) goto free_clks; @@ -1035,7 +1035,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, /* Leaves can be fixed or configurable divisors */ if (data->div[i].fixed) { - fix_factor = kzalloc(sizeof(*fix_factor), GFP_KERNEL); + fix_factor = kzalloc_obj(*fix_factor); if (!fix_factor) goto free_gate; @@ -1045,7 +1045,7 @@ static struct clk ** __init sunxi_divs_clk_setup(struct device_node *node, rate_hw = &fix_factor->hw; rate_ops = &clk_fixed_factor_ops; } else { - divider = kzalloc(sizeof(*divider), GFP_KERNEL); + divider = kzalloc_obj(*divider); if (!divider) goto free_gate; diff --git a/drivers/clk/sunxi/clk-usb.c b/drivers/clk/sunxi/clk-usb.c index 3c53f65002a2..903d22c002cc 100644 --- a/drivers/clk/sunxi/clk-usb.c +++ b/drivers/clk/sunxi/clk-usb.c @@ -113,11 +113,11 @@ static void __init sunxi_usb_clk_setup(struct device_node *node, qty = find_last_bit((unsigned long *)&data->clk_mask, SUNXI_USB_MAX_SIZE); - clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL); + clk_data = kmalloc_obj(struct clk_onecell_data); if (!clk_data) return; - clk_data->clks = kcalloc(qty + 1, sizeof(struct clk *), GFP_KERNEL); + clk_data->clks = kzalloc_objs(struct clk *, qty + 1); if (!clk_data->clks) { kfree(clk_data); return; @@ -144,7 +144,7 @@ static void __init sunxi_usb_clk_setup(struct device_node *node, if (data->reset_mask == 0) return; - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + reset_data = kzalloc_obj(*reset_data); if (!reset_data) return; diff --git a/drivers/clk/tegra/clk-audio-sync.c b/drivers/clk/tegra/clk-audio-sync.c index 468a4403f147..0bbfcf46bedd 100644 --- a/drivers/clk/tegra/clk-audio-sync.c +++ b/drivers/clk/tegra/clk-audio-sync.c @@ -50,7 +50,7 @@ struct clk *tegra_clk_register_sync_source(const char *name, struct clk_init_data init; struct clk *clk; - sync = kzalloc(sizeof(*sync), GFP_KERNEL); + sync = kzalloc_obj(*sync); if (!sync) { pr_err("%s: could not allocate sync source clk\n", __func__); return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index 77a2586dbe00..f6d2b934228b 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -434,7 +434,7 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp, dev_dbg(bpmp->dev, "maximum clock ID: %u\n", max_id); - clocks = kcalloc(max_id + 1, sizeof(*clocks), GFP_KERNEL); + clocks = kzalloc_objs(*clocks, max_id + 1); if (!clocks) return -ENOMEM; diff --git a/drivers/clk/tegra/clk-device.c b/drivers/clk/tegra/clk-device.c index 8c8e2b853a99..e0531f6dcfb0 100644 --- a/drivers/clk/tegra/clk-device.c +++ b/drivers/clk/tegra/clk-device.c @@ -174,8 +174,19 @@ static int tegra_clock_probe(struct platform_device *pdev) * problem. In practice this makes no difference from a power management * perspective since voltage is kept at a nominal level during suspend anyways. */ +static inline int tegra_clock_suspend(struct device *dev) +{ + int ret; + + ret = pm_runtime_resume(dev); + if (ret < 0) + return ret; + + return 0; +} + static const struct dev_pm_ops tegra_clock_pm = { - SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_resume_and_get, pm_runtime_put) + SET_SYSTEM_SLEEP_PM_OPS(tegra_clock_suspend, NULL) }; static const struct of_device_id tegra_clock_match[] = { diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c index 37439fcb3ac0..27f43c3da156 100644 --- a/drivers/clk/tegra/clk-divider.c +++ b/drivers/clk/tegra/clk-divider.c @@ -148,7 +148,7 @@ struct clk *tegra_clk_register_divider(const char *name, struct clk *clk; struct clk_init_data init; - divider = kzalloc(sizeof(*divider), GFP_KERNEL); + divider = kzalloc_obj(*divider); if (!divider) { pr_err("%s: could not allocate fractional divider clk\n", __func__); diff --git a/drivers/clk/tegra/clk-periph-fixed.c b/drivers/clk/tegra/clk-periph-fixed.c index c088e7a280df..bb33e32cad4a 100644 --- a/drivers/clk/tegra/clk-periph-fixed.c +++ b/drivers/clk/tegra/clk-periph-fixed.c @@ -84,7 +84,7 @@ struct clk *tegra_clk_register_periph_fixed(const char *name, if (!regs) return ERR_PTR(-EINVAL); - fixed = kzalloc(sizeof(*fixed), GFP_KERNEL); + fixed = kzalloc_obj(*fixed); if (!fixed) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c index 2091fc9b0ca9..fa39d6487515 100644 --- a/drivers/clk/tegra/clk-periph-gate.c +++ b/drivers/clk/tegra/clk-periph-gate.c @@ -146,7 +146,7 @@ struct clk *tegra_clk_register_periph_gate(const char *name, if (!pregs) return ERR_PTR(-EINVAL); - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) { pr_err("%s: could not allocate periph gate clk\n", __func__); return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c index d8bf89a81e6d..2299545fc386 100644 --- a/drivers/clk/tegra/clk-pll-out.c +++ b/drivers/clk/tegra/clk-pll-out.c @@ -93,7 +93,7 @@ struct clk *tegra_clk_register_pll_out(const char *name, struct clk *clk; struct clk_init_data init; - pll_out = kzalloc(sizeof(*pll_out), GFP_KERNEL); + pll_out = kzalloc_obj(*pll_out); if (!pll_out) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c index 591b9f0c155a..d86003b6d94f 100644 --- a/drivers/clk/tegra/clk-pll.c +++ b/drivers/clk/tegra/clk-pll.c @@ -1882,7 +1882,7 @@ static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base, { struct tegra_clk_pll *pll; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c index 4f2c3309eea4..14b5439a100a 100644 --- a/drivers/clk/tegra/clk-sdmmc-mux.c +++ b/drivers/clk/tegra/clk-sdmmc-mux.c @@ -250,7 +250,7 @@ struct clk *tegra_clk_register_sdmmc_mux_div(const char *name, if (!bank) return ERR_PTR(-EINVAL); - sdmmc_mux = kzalloc(sizeof(*sdmmc_mux), GFP_KERNEL); + sdmmc_mux = kzalloc_obj(*sdmmc_mux); if (!sdmmc_mux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c index 51fb356e770e..370445e3d5ac 100644 --- a/drivers/clk/tegra/clk-super.c +++ b/drivers/clk/tegra/clk-super.c @@ -207,7 +207,7 @@ struct clk *tegra_clk_register_super_mux(const char *name, struct clk *clk; struct clk_init_data init; - super = kzalloc(sizeof(*super), GFP_KERNEL); + super = kzalloc_obj(*super); if (!super) return ERR_PTR(-ENOMEM); @@ -243,7 +243,7 @@ struct clk *tegra_clk_register_super_clk(const char *name, struct clk *clk; struct clk_init_data init; - super = kzalloc(sizeof(*super), GFP_KERNEL); + super = kzalloc_obj(*super); if (!super) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-tegra-super-cclk.c b/drivers/clk/tegra/clk-tegra-super-cclk.c index 3b22a4d0dffc..e7aeb67606b1 100644 --- a/drivers/clk/tegra/clk-tegra-super-cclk.c +++ b/drivers/clk/tegra/clk-tegra-super-cclk.c @@ -142,7 +142,7 @@ struct clk *tegra_clk_register_super_cclk(const char *name, if (WARN_ON(cclk_super)) return ERR_PTR(-EBUSY); - super = kzalloc(sizeof(*super), GFP_KERNEL); + super = kzalloc_obj(*super); if (!super) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-tegra114.c b/drivers/clk/tegra/clk-tegra114.c index 6c8e053311c3..a4f40533cc43 100644 --- a/drivers/clk/tegra/clk-tegra114.c +++ b/drivers/clk/tegra/clk-tegra114.c @@ -690,7 +690,6 @@ static struct tegra_clk tegra114_clks[tegra_clk_max] __initdata = { [tegra_clk_tsec] = { .dt_id = TEGRA114_CLK_TSEC, .present = true }, [tegra_clk_xusb_host] = { .dt_id = TEGRA114_CLK_XUSB_HOST, .present = true }, [tegra_clk_msenc] = { .dt_id = TEGRA114_CLK_MSENC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA114_CLK_CSUS, .present = true }, [tegra_clk_mselect] = { .dt_id = TEGRA114_CLK_MSELECT, .present = true }, [tegra_clk_tsensor] = { .dt_id = TEGRA114_CLK_TSENSOR, .present = true }, [tegra_clk_i2s3] = { .dt_id = TEGRA114_CLK_I2S3, .present = true }, @@ -1046,6 +1045,12 @@ static __init void tegra114_periph_clk_init(void __iomem *clk_base, 0, 82, periph_clk_enb_refcnt); clks[TEGRA114_CLK_DSIB] = clk; + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0, + clk_base, 0, TEGRA114_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA114_CLK_CSUS] = clk; + /* emc mux */ clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, ARRAY_SIZE(mux_pllmcp_clkm), diff --git a/drivers/clk/tegra/clk-tegra124-emc.c b/drivers/clk/tegra/clk-tegra124-emc.c index 2a6db0434281..f3b2c96fdcfc 100644 --- a/drivers/clk/tegra/clk-tegra124-emc.c +++ b/drivers/clk/tegra/clk-tegra124-emc.c @@ -197,8 +197,8 @@ static struct tegra_emc *emc_ensure_emc_driver(struct tegra_clk_emc *tegra) tegra->emc_node = NULL; tegra->emc = platform_get_drvdata(pdev); + put_device(&pdev->dev); if (!tegra->emc) { - put_device(&pdev->dev); pr_err("%s: cannot find EMC driver\n", __func__); return NULL; } @@ -444,7 +444,6 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, u32 ram_code) { struct emc_timing *timings_ptr; - struct device_node *child; int child_count = of_get_child_count(node); int i = 0, err; size_t size; @@ -458,12 +457,11 @@ static int load_timings_from_dt(struct tegra_clk_emc *tegra, timings_ptr = tegra->timings + tegra->num_timings; tegra->num_timings += child_count; - for_each_child_of_node(node, child) { + for_each_child_of_node_scoped(node, child) { struct emc_timing *timing = timings_ptr + (i++); err = load_one_timing_from_dt(tegra, timing, child); if (err) { - of_node_put(child); kfree(tegra->timings); return err; } @@ -494,7 +492,7 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np struct clk *clk; int err; - tegra = kcalloc(1, sizeof(*tegra), GFP_KERNEL); + tegra = kzalloc_objs(*tegra, 1); if (!tegra) return ERR_PTR(-ENOMEM); @@ -538,8 +536,10 @@ struct clk *tegra124_clk_register_emc(void __iomem *base, struct device_node *np tegra->hw.init = &init; clk = clk_register(NULL, &tegra->hw); - if (IS_ERR(clk)) + if (IS_ERR(clk)) { + kfree(tegra); return clk; + } tegra->prev_parent = clk_hw_get_parent_by_index( &tegra->hw, emc_get_parent(&tegra->hw))->clk; diff --git a/drivers/clk/tegra/clk-tegra20-emc.c b/drivers/clk/tegra/clk-tegra20-emc.c index dd74b8543bf1..44465726a8a6 100644 --- a/drivers/clk/tegra/clk-tegra20-emc.c +++ b/drivers/clk/tegra/clk-tegra20-emc.c @@ -249,7 +249,7 @@ struct clk *tegra20_clk_register_emc(void __iomem *ioaddr, bool low_jitter) struct clk_init_data init; struct clk *clk; - emc = kzalloc(sizeof(*emc), GFP_KERNEL); + emc = kzalloc_obj(*emc); if (!emc) return NULL; diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 2c58ce25af75..9da82dd7965b 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -530,7 +530,6 @@ static struct tegra_clk tegra20_clks[tegra_clk_max] __initdata = { [tegra_clk_rtc] = { .dt_id = TEGRA20_CLK_RTC, .present = true }, [tegra_clk_timer] = { .dt_id = TEGRA20_CLK_TIMER, .present = true }, [tegra_clk_kbc] = { .dt_id = TEGRA20_CLK_KBC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA20_CLK_CSUS, .present = true }, [tegra_clk_vcp] = { .dt_id = TEGRA20_CLK_VCP, .present = true }, [tegra_clk_bsea] = { .dt_id = TEGRA20_CLK_BSEA, .present = true }, [tegra_clk_bsev] = { .dt_id = TEGRA20_CLK_BSEV, .present = true }, @@ -802,9 +801,9 @@ static void __init tegra20_periph_clk_init(void) clks[TEGRA20_CLK_MC] = clk; /* dsi */ - clk = tegra_clk_register_periph_gate("dsi", "pll_d", 0, clk_base, 0, - 48, periph_clk_enb_refcnt); - clk_register_clkdev(clk, NULL, "dsi"); + clk = tegra_clk_register_periph_gate("dsi", "pll_d_out0", 0, + clk_base, 0, TEGRA20_CLK_DSI, + periph_clk_enb_refcnt); clks[TEGRA20_CLK_DSI] = clk; /* pex */ @@ -834,6 +833,12 @@ static void __init tegra20_periph_clk_init(void) clk_base, 0, 93, periph_clk_enb_refcnt); clks[TEGRA20_CLK_CDEV2] = clk; + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "csus_mux", 0, + clk_base, 0, TEGRA20_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA20_CLK_CSUS] = clk; + for (i = 0; i < ARRAY_SIZE(tegra_periph_clk_list); i++) { data = &tegra_periph_clk_list[i]; clk = tegra_clk_register_periph_data(clk_base, data); @@ -1093,14 +1098,15 @@ static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec, hw = __clk_get_hw(clk); /* - * Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent - * clock is created by the pinctrl driver. It is possible for clk user - * to request these clocks before pinctrl driver got probed and hence - * user will get an orphaned clock. That might be undesirable because - * user may expect parent clock to be enabled by the child. + * Tegra20 CDEV1, CDEV2 and CSUS clocks are a bit special case, their + * parent clock is created by the pinctrl driver. It is possible for + * clk user to request these clocks before pinctrl driver got probed + * and hence user will get an orphaned clock. That might be undesirable + * because user may expect parent clock to be enabled by the child. */ if (clkspec->args[0] == TEGRA20_CLK_CDEV1 || - clkspec->args[0] == TEGRA20_CLK_CDEV2) { + clkspec->args[0] == TEGRA20_CLK_CDEV2 || + clkspec->args[0] == TEGRA20_CLK_CSUS) { parent_hw = clk_hw_get_parent(hw); if (!parent_hw) return ERR_PTR(-EPROBE_DEFER); diff --git a/drivers/clk/tegra/clk-tegra210-emc.c b/drivers/clk/tegra/clk-tegra210-emc.c index fbf3c894eb56..9f140d94bef7 100644 --- a/drivers/clk/tegra/clk-tegra210-emc.c +++ b/drivers/clk/tegra/clk-tegra210-emc.c @@ -278,7 +278,7 @@ struct clk *tegra210_clk_register_emc(struct device_node *np, struct clk_init_data init; struct clk *clk; - emc = kzalloc(sizeof(*emc), GFP_KERNEL); + emc = kzalloc_obj(*emc); if (!emc) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c index 504d0ea997a5..0c86cff719e3 100644 --- a/drivers/clk/tegra/clk-tegra210.c +++ b/drivers/clk/tegra/clk-tegra210.c @@ -3705,8 +3705,7 @@ static void tegra210_mbist_clk_init(void) if (!num_clks) continue; - clk_data = kmalloc_array(num_clks, sizeof(*clk_data), - GFP_KERNEL); + clk_data = kmalloc_objs(*clk_data, num_clks); if (WARN_ON(!clk_data)) return; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index e7ebb63970d3..61fe527ee6c1 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -154,6 +154,7 @@ static unsigned long input_freq; static DEFINE_SPINLOCK(cml_lock); static DEFINE_SPINLOCK(pll_d_lock); +static DEFINE_SPINLOCK(pll_d2_lock); #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \ _clk_num, _gate_flags, _clk_id) \ @@ -780,7 +781,6 @@ static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = { [tegra_clk_rtc] = { .dt_id = TEGRA30_CLK_RTC, .present = true }, [tegra_clk_timer] = { .dt_id = TEGRA30_CLK_TIMER, .present = true }, [tegra_clk_kbc] = { .dt_id = TEGRA30_CLK_KBC, .present = true }, - [tegra_clk_csus] = { .dt_id = TEGRA30_CLK_CSUS, .present = true }, [tegra_clk_vcp] = { .dt_id = TEGRA30_CLK_VCP, .present = true }, [tegra_clk_bsea] = { .dt_id = TEGRA30_CLK_BSEA, .present = true }, [tegra_clk_bsev] = { .dt_id = TEGRA30_CLK_BSEV, .present = true }, @@ -860,7 +860,7 @@ static void __init tegra30_pll_init(void) /* PLLD2 */ clk = tegra_clk_register_pll("pll_d2", "pll_ref", clk_base, pmc_base, 0, - &pll_d2_params, NULL); + &pll_d2_params, &pll_d2_lock); clks[TEGRA30_CLK_PLL_D2] = clk; /* PLLD2_OUT0 */ @@ -1009,6 +1009,22 @@ static void __init tegra30_periph_clk_init(void) 0, 48, periph_clk_enb_refcnt); clks[TEGRA30_CLK_DSIA] = clk; + /* csia_pad */ + clk = clk_register_gate(NULL, "csia_pad", "pll_d", CLK_SET_RATE_PARENT, + clk_base + PLLD_BASE, 26, 0, &pll_d_lock); + clks[TEGRA30_CLK_CSIA_PAD] = clk; + + /* csib_pad */ + clk = clk_register_gate(NULL, "csib_pad", "pll_d2", CLK_SET_RATE_PARENT, + clk_base + PLLD2_BASE, 26, 0, &pll_d2_lock); + clks[TEGRA30_CLK_CSIB_PAD] = clk; + + /* csus */ + clk = tegra_clk_register_periph_gate("csus", "vi_sensor", 0, + clk_base, 0, TEGRA30_CLK_CSUS, + periph_clk_enb_refcnt); + clks[TEGRA30_CLK_CSUS] = clk; + /* pcie */ clk = tegra_clk_register_periph_gate("pcie", "clk_m", 0, clk_base, 0, 70, periph_clk_enb_refcnt); diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c index 19037346f522..78655422253d 100644 --- a/drivers/clk/tegra/clk.c +++ b/drivers/clk/tegra/clk.c @@ -227,15 +227,13 @@ struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks) if (WARN_ON(banks > ARRAY_SIZE(periph_regs))) return NULL; - periph_clk_enb_refcnt = kcalloc(32 * banks, - sizeof(*periph_clk_enb_refcnt), - GFP_KERNEL); + periph_clk_enb_refcnt = kzalloc_objs(*periph_clk_enb_refcnt, 32 * banks); if (!periph_clk_enb_refcnt) return NULL; periph_banks = banks; - clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL); + clks = kzalloc_objs(struct clk *, num); if (!clks) { kfree(periph_clk_enb_refcnt); return NULL; diff --git a/drivers/clk/thead/clk-th1520-ap.c b/drivers/clk/thead/clk-th1520-ap.c index 71ad03a998e8..3a6847f1c950 100644 --- a/drivers/clk/thead/clk-th1520-ap.c +++ b/drivers/clk/thead/clk-th1520-ap.c @@ -7,22 +7,38 @@ #include #include +#include #include +#include #include +#include #include #include #include +#define TH1520_PLL_STS 0x80 + #define TH1520_PLL_POSTDIV2 GENMASK(26, 24) #define TH1520_PLL_POSTDIV1 GENMASK(22, 20) #define TH1520_PLL_FBDIV GENMASK(19, 8) #define TH1520_PLL_REFDIV GENMASK(5, 0) #define TH1520_PLL_BYPASS BIT(30) #define TH1520_PLL_VCO_RST BIT(29) +#define TH1520_PLL_DACPD BIT(25) #define TH1520_PLL_DSMPD BIT(24) #define TH1520_PLL_FRAC GENMASK(23, 0) #define TH1520_PLL_FRAC_BITS 24 +/* + * All PLLs in TH1520 take 21250ns at maximum to lock, let's take its double + * for safety. + */ +#define TH1520_PLL_LOCK_TIMEOUT_US 44 +#define TH1520_PLL_STABLE_DELAY_US 30 + +/* c910_bus_clk must be kept below 750MHz for stability */ +#define TH1520_C910_BUS_MAX_RATE (750 * 1000 * 1000) + struct ccu_internal { u8 shift; u8 width; @@ -62,8 +78,19 @@ struct ccu_div { struct ccu_common common; }; +struct ccu_pll_cfg { + unsigned long freq; + u32 fbdiv; + u32 frac; + u32 postdiv1; + u32 postdiv2; +}; + struct ccu_pll { struct ccu_common common; + u32 lock_sts_mask; + int cfgnum; + const struct ccu_pll_cfg *cfgs; }; #define TH_CCU_ARG(_shift, _width) \ @@ -79,17 +106,22 @@ struct ccu_pll { .flags = _flags, \ } -#define TH_CCU_MUX(_name, _parents, _shift, _width) \ +#define TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, _flags, \ + _mux_flags) \ { \ .mask = GENMASK(_width - 1, 0), \ .shift = _shift, \ + .flags = _mux_flags, \ .hw.init = CLK_HW_INIT_PARENTS_DATA( \ _name, \ _parents, \ &clk_mux_ops, \ - 0), \ + _flags), \ } +#define TH_CCU_MUX(_name, _parents, _shift, _width) \ + TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, 0, 0) + #define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _bit, _flags) \ struct ccu_gate _struct = { \ .clkid = _clkid, \ @@ -299,9 +331,21 @@ static void ccu_pll_disable(struct clk_hw *hw) static int ccu_pll_enable(struct clk_hw *hw) { struct ccu_pll *pll = hw_to_ccu_pll(hw); + u32 reg; + int ret; - return regmap_clear_bits(pll->common.map, pll->common.cfg1, - TH1520_PLL_VCO_RST); + regmap_clear_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_VCO_RST); + + ret = regmap_read_poll_timeout_atomic(pll->common.map, TH1520_PLL_STS, + reg, reg & pll->lock_sts_mask, + 5, TH1520_PLL_LOCK_TIMEOUT_US); + if (ret) + return ret; + + udelay(TH1520_PLL_STABLE_DELAY_US); + + return 0; } static int ccu_pll_is_enabled(struct clk_hw *hw) @@ -368,17 +412,168 @@ static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw, return rate; } +static const struct ccu_pll_cfg *ccu_pll_lookup_best_cfg(struct ccu_pll *pll, + unsigned long rate) +{ + unsigned long best_delta = ULONG_MAX; + const struct ccu_pll_cfg *best_cfg; + int i; + + for (i = 0; i < pll->cfgnum; i++) { + const struct ccu_pll_cfg *cfg = &pll->cfgs[i]; + unsigned long delta; + + delta = abs_diff(cfg->freq, rate); + if (delta < best_delta) { + best_delta = delta; + best_cfg = cfg; + } + } + + return best_cfg; +} + +static int ccu_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + + req->rate = ccu_pll_lookup_best_cfg(pll, req->rate)->freq; + + return 0; +} + +static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct ccu_pll *pll = hw_to_ccu_pll(hw); + const struct ccu_pll_cfg *cfg; + + cfg = ccu_pll_lookup_best_cfg(pll, rate); + + ccu_pll_disable(hw); + + regmap_write(pll->common.map, pll->common.cfg0, + FIELD_PREP(TH1520_PLL_REFDIV, 1) | + FIELD_PREP(TH1520_PLL_FBDIV, cfg->fbdiv) | + FIELD_PREP(TH1520_PLL_POSTDIV1, cfg->postdiv1) | + FIELD_PREP(TH1520_PLL_POSTDIV2, cfg->postdiv2)); + + regmap_update_bits(pll->common.map, pll->common.cfg1, + TH1520_PLL_DACPD | TH1520_PLL_DSMPD | + TH1520_PLL_FRAC, + cfg->frac ? cfg->frac : + TH1520_PLL_DACPD | TH1520_PLL_DSMPD); + + return ccu_pll_enable(hw); +} + static const struct clk_ops clk_pll_ops = { .disable = ccu_pll_disable, .enable = ccu_pll_enable, .is_enabled = ccu_pll_is_enabled, .recalc_rate = ccu_pll_recalc_rate, + .determine_rate = ccu_pll_determine_rate, + .set_rate = ccu_pll_set_rate, +}; + +/* + * c910_clk could be reparented glitchlessly for DVFS. There are two parents, + * - c910_i0_clk, derived from cpu_pll0_clk or osc_24m. + * - cpu_pll1_clk, which provides the exact same set of rates as cpu_pll0_clk. + * + * During rate setting, always forward the request to the unused parent, and + * then switch c910_clk to it to avoid glitch. + */ +static u8 c910_clk_get_parent(struct clk_hw *hw) +{ + return clk_mux_ops.get_parent(hw); +} + +static int c910_clk_set_parent(struct clk_hw *hw, u8 index) +{ + return clk_mux_ops.set_parent(hw, index); +} + +static unsigned long c910_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + return parent_rate; +} + +static int c910_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + u8 alt_parent_index = !c910_clk_get_parent(hw); + struct clk_hw *alt_parent; + + alt_parent = clk_hw_get_parent_by_index(hw, alt_parent_index); + + req->rate = clk_hw_round_rate(alt_parent, req->rate); + req->best_parent_hw = alt_parent; + req->best_parent_rate = req->rate; + + return 0; +} + +static int c910_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return -EOPNOTSUPP; +} + +static int c910_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate, u8 index) +{ + struct clk_hw *parent = clk_hw_get_parent_by_index(hw, index); + + clk_set_rate(parent->clk, parent_rate); + + c910_clk_set_parent(hw, index); + + return 0; +} + +static const struct clk_ops c910_clk_ops = { + .get_parent = c910_clk_get_parent, + .set_parent = c910_clk_set_parent, + .recalc_rate = c910_clk_recalc_rate, + .determine_rate = c910_clk_determine_rate, + .set_rate = c910_clk_set_rate, + .set_rate_and_parent = c910_clk_set_rate_and_parent, }; static const struct clk_parent_data osc_24m_clk[] = { { .index = 0 } }; +static const struct ccu_pll_cfg cpu_pll_cfgs[] = { + { 125000000, 125, 0, 6, 4 }, + { 200000000, 125, 0, 5, 3 }, + { 300000000, 125, 0, 5, 2 }, + { 400000000, 100, 0, 3, 2 }, + { 500000000, 125, 0, 6, 1 }, + { 600000000, 125, 0, 5, 1 }, + { 702000000, 117, 0, 4, 1 }, + { 800000000, 100, 0, 3, 1 }, + { 900000000, 75, 0, 2, 1 }, + { 1000000000, 125, 0, 3, 1 }, + { 1104000000, 92, 0, 2, 1 }, + { 1200000000, 100, 0, 2, 1 }, + { 1296000000, 108, 0, 2, 1 }, + { 1404000000, 117, 0, 2, 1 }, + { 1500000000, 125, 0, 2, 1 }, + { 1608000000, 67, 0, 1, 1 }, + { 1704000000, 71, 0, 1, 1 }, + { 1800000000, 75, 0, 1, 1 }, + { 1896000000, 79, 0, 1, 1 }, + { 1992000000, 83, 0, 1, 1 }, + { 2112000000, 88, 0, 1, 1 }, + { 2208000000, 92, 0, 1, 1 }, + { 2304000000, 96, 0, 1, 1 }, + { 2400000000, 100, 0, 1, 1 }, +}; + static struct ccu_pll cpu_pll0_clk = { .common = { .clkid = CLK_CPU_PLL0, @@ -389,6 +584,9 @@ static struct ccu_pll cpu_pll0_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(1), + .cfgnum = ARRAY_SIZE(cpu_pll_cfgs), + .cfgs = cpu_pll_cfgs, }; static struct ccu_pll cpu_pll1_clk = { @@ -401,6 +599,17 @@ static struct ccu_pll cpu_pll1_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(4), + .cfgnum = ARRAY_SIZE(cpu_pll_cfgs), + .cfgs = cpu_pll_cfgs, +}; + +static const struct ccu_pll_cfg gmac_pll_cfg = { + .freq = 1000000000, + .fbdiv = 125, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, }; static struct ccu_pll gmac_pll_clk = { @@ -413,6 +622,9 @@ static struct ccu_pll gmac_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(3), + .cfgnum = 1, + .cfgs = &gmac_pll_cfg, }; static const struct clk_hw *gmac_pll_clk_parent[] = { @@ -423,6 +635,14 @@ static const struct clk_parent_data gmac_pll_clk_pd[] = { { .hw = &gmac_pll_clk.common.hw } }; +static const struct ccu_pll_cfg video_pll_cfg = { + .freq = 792000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, +}; + static struct ccu_pll video_pll_clk = { .common = { .clkid = CLK_VIDEO_PLL, @@ -433,6 +653,9 @@ static struct ccu_pll video_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(7), + .cfgnum = 1, + .cfgs = &video_pll_cfg, }; static const struct clk_hw *video_pll_clk_parent[] = { @@ -443,6 +666,14 @@ static const struct clk_parent_data video_pll_clk_pd[] = { { .hw = &video_pll_clk.common.hw } }; +static const struct ccu_pll_cfg dpu_pll_cfg = { + .freq = 1188000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 2, + .postdiv2 = 1, +}; + static struct ccu_pll dpu0_pll_clk = { .common = { .clkid = CLK_DPU0_PLL, @@ -453,6 +684,9 @@ static struct ccu_pll dpu0_pll_clk = { &clk_pll_ops, 0), }, + .lock_sts_mask = BIT(8), + .cfgnum = 1, + .cfgs = &dpu_pll_cfg, }; static const struct clk_hw *dpu0_pll_clk_parent[] = { @@ -469,12 +703,23 @@ static struct ccu_pll dpu1_pll_clk = { &clk_pll_ops, 0), }, + .lock_sts_mask = BIT(9), + .cfgnum = 1, + .cfgs = &dpu_pll_cfg, }; static const struct clk_hw *dpu1_pll_clk_parent[] = { &dpu1_pll_clk.common.hw }; +static const struct ccu_pll_cfg tee_pll_cfg = { + .freq = 792000000, + .fbdiv = 99, + .frac = 0, + .postdiv1 = 3, + .postdiv2 = 1, +}; + static struct ccu_pll tee_pll_clk = { .common = { .clkid = CLK_TEE_PLL, @@ -485,6 +730,9 @@ static struct ccu_pll tee_pll_clk = { &clk_pll_ops, CLK_IS_CRITICAL), }, + .lock_sts_mask = BIT(10), + .cfgnum = 1, + .cfgs = &tee_pll_cfg, }; static const struct clk_parent_data c910_i0_parents[] = { @@ -495,7 +743,8 @@ static const struct clk_parent_data c910_i0_parents[] = { static struct ccu_mux c910_i0_clk = { .clkid = CLK_C910_I0, .reg = 0x100, - .mux = TH_CCU_MUX("c910-i0", c910_i0_parents, 1, 1), + .mux = TH_CCU_MUX_FLAGS("c910-i0", c910_i0_parents, 1, 1, + CLK_SET_RATE_PARENT, CLK_MUX_ROUND_CLOSEST), }; static const struct clk_parent_data c910_parents[] = { @@ -506,7 +755,28 @@ static const struct clk_parent_data c910_parents[] = { static struct ccu_mux c910_clk = { .clkid = CLK_C910, .reg = 0x100, - .mux = TH_CCU_MUX("c910", c910_parents, 0, 1), + .mux = { + .mask = BIT(0), + .shift = 0, + .hw.init = CLK_HW_INIT_PARENTS_DATA("c910", + c910_parents, + &c910_clk_ops, + CLK_SET_RATE_PARENT), + }, +}; + +static struct ccu_div c910_bus_clk = { + .enable = BIT(7), + .div_en = BIT(11), + .div = TH_CCU_DIV_FLAGS(8, 3, 0), + .common = { + .clkid = CLK_C910_BUS, + .cfg0 = 0x100, + .hw.init = CLK_HW_INIT_HW("c910-bus", + &c910_clk.mux.hw, + &ccu_div_ops, + CLK_IS_CRITICAL), + }, }; static const struct clk_parent_data ahb2_cpusys_parents[] = { @@ -1021,6 +1291,7 @@ static struct ccu_common *th1520_pll_clks[] = { }; static struct ccu_common *th1520_div_clks[] = { + &c910_bus_clk.common, &ahb2_cpusys_hclk.common, &apb3_cpusys_pclk.common, &axi4_cpusys2_aclk.common, @@ -1164,7 +1435,7 @@ static const struct th1520_plat_data th1520_ap_platdata = { .th1520_mux_clks = th1520_mux_clks, .th1520_gate_clks = th1520_gate_clks, - .nr_clks = CLK_UART_SCLK + 1, + .nr_clks = CLK_C910_BUS + 1, .nr_pll_clks = ARRAY_SIZE(th1520_pll_clks), .nr_div_clks = ARRAY_SIZE(th1520_div_clks), @@ -1180,11 +1451,69 @@ static const struct th1520_plat_data th1520_vo_platdata = { .nr_gate_clks = ARRAY_SIZE(th1520_vo_gate_clks), }; +/* + * Maintain clock rate of c910_bus_clk below TH1520_C910_BUS_MAX_RATE (750MHz) + * when its parent, c910_clk, changes the rate. + * + * Additionally, TRM is unclear about c910_bus_clk behavior when the divisor is + * set below 2, thus we should ensure the new divisor stays in (2, MAXDIVISOR). + */ +static unsigned long c910_bus_clk_divisor(struct ccu_div *cd, + unsigned long parent_rate) +{ + return clamp(DIV_ROUND_UP(parent_rate, TH1520_C910_BUS_MAX_RATE), + 2U, 1U << cd->div.width); +} + +static int c910_clk_notifier_cb(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct clk_notifier_data *cnd = data; + unsigned long new_divisor, ref_rate; + + if (action != PRE_RATE_CHANGE && action != POST_RATE_CHANGE) + return NOTIFY_DONE; + + new_divisor = c910_bus_clk_divisor(&c910_bus_clk, cnd->new_rate); + + if (cnd->new_rate > cnd->old_rate) { + /* + * Scaling up. Adjust c910_bus_clk divisor + * - before c910_clk rate change to ensure the constraints + * aren't broken after scaling to higher rates, + * - after c910_clk rate change to keep c910_bus_clk as high as + * possible + */ + ref_rate = action == PRE_RATE_CHANGE ? + cnd->old_rate : cnd->new_rate; + clk_set_rate(c910_bus_clk.common.hw.clk, + ref_rate / new_divisor); + } else if (cnd->new_rate < cnd->old_rate && + action == POST_RATE_CHANGE) { + /* + * Scaling down. Adjust c910_bus_clk divisor only after + * c910_clk rate change to keep c910_bus_clk as high as + * possible, Scaling down never breaks the constraints. + */ + clk_set_rate(c910_bus_clk.common.hw.clk, + cnd->new_rate / new_divisor); + } else { + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static struct notifier_block c910_clk_notifier = { + .notifier_call = c910_clk_notifier_cb, +}; + static int th1520_clk_probe(struct platform_device *pdev) { const struct th1520_plat_data *plat_data; struct device *dev = &pdev->dev; struct clk_hw_onecell_data *priv; + struct clk *notifier_clk; struct regmap *map; void __iomem *base; @@ -1271,6 +1600,13 @@ static int th1520_clk_probe(struct platform_device *pdev) ret = devm_clk_hw_register(dev, &emmc_sdio_ref_clk.hw); if (ret) return ret; + + notifier_clk = devm_clk_hw_get_clk(dev, &c910_clk.mux.hw, + "dvfs"); + ret = devm_clk_notifier_register(dev, notifier_clk, + &c910_clk_notifier); + if (ret) + return ret; } ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv); diff --git a/drivers/clk/ti/apll.c b/drivers/clk/ti/apll.c index 43514e6f3b78..31bf097f8aba 100644 --- a/drivers/clk/ti/apll.c +++ b/drivers/clk/ti/apll.c @@ -183,9 +183,9 @@ static void __init of_dra7_apll_setup(struct device_node *node) const char **parent_names = NULL; int ret; - ad = kzalloc(sizeof(*ad), GFP_KERNEL); - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); - init = kzalloc(sizeof(*init), GFP_KERNEL); + ad = kzalloc_obj(*ad); + clk_hw = kzalloc_obj(*clk_hw); + init = kzalloc_obj(*init); if (!ad || !clk_hw || !init) goto cleanup; @@ -347,9 +347,9 @@ static void __init of_omap2_apll_setup(struct device_node *node) u32 val; int ret; - ad = kzalloc(sizeof(*ad), GFP_KERNEL); - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); - init = kzalloc(sizeof(*init), GFP_KERNEL); + ad = kzalloc_obj(*ad); + clk_hw = kzalloc_obj(*clk_hw); + init = kzalloc_obj(*init); if (!ad || !clk_hw || !init) goto cleanup; diff --git a/drivers/clk/ti/autoidle.c b/drivers/clk/ti/autoidle.c index a99aaf2e7684..610f225a8295 100644 --- a/drivers/clk/ti/autoidle.c +++ b/drivers/clk/ti/autoidle.c @@ -191,7 +191,7 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node) if (of_property_read_u32(node, "ti,autoidle-shift", &shift)) return 0; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return -ENOMEM; diff --git a/drivers/clk/ti/clk-dra7-atl.c b/drivers/clk/ti/clk-dra7-atl.c index b02f84d49b96..fb41f55d44e7 100644 --- a/drivers/clk/ti/clk-dra7-atl.c +++ b/drivers/clk/ti/clk-dra7-atl.c @@ -170,7 +170,7 @@ static void __init of_dra7_atl_clock_setup(struct device_node *node) const char *name; struct clk *clk; - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); if (!clk_hw) { pr_err("%s: could not allocate dra7_atl_desc\n", __func__); return; diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 693a4459a01b..efdb6ab4a5be 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -268,7 +268,7 @@ int __init ti_clk_retry_init(struct device_node *node, void *user, struct clk_init_item *retry; pr_debug("%pOFn: adding to retry list...\n", node); - retry = kzalloc(sizeof(*retry), GFP_KERNEL); + retry = kzalloc_obj(*retry); if (!retry) return -ENOMEM; @@ -411,7 +411,7 @@ int __init omap2_clk_provider_init(struct device_node *parent, int index, /* add clocks node info */ clocks_node_ptr[index] = clocks; - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kzalloc_obj(*io); if (!io) return -ENOMEM; @@ -576,7 +576,7 @@ int ti_clk_add_alias(struct clk *clk, const char *con) if (IS_ERR(clk)) return PTR_ERR(clk); - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return -ENOMEM; diff --git a/drivers/clk/ti/clkctrl.c b/drivers/clk/ti/clkctrl.c index 607e34d8e289..f779906cc8ef 100644 --- a/drivers/clk/ti/clkctrl.c +++ b/drivers/clk/ti/clkctrl.c @@ -297,7 +297,7 @@ _ti_clkctrl_clk_register(struct omap_clkctrl_provider *provider, ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT); - clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); + clkctrl_clk = kzalloc_obj(*clkctrl_clk); if (!init.name || !clkctrl_clk) { ret = -ENOMEM; goto cleanup; @@ -337,7 +337,7 @@ _ti_clkctrl_setup_gate(struct omap_clkctrl_provider *provider, { struct clk_hw_omap *clk_hw; - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); if (!clk_hw) return; @@ -360,7 +360,7 @@ _ti_clkctrl_setup_mux(struct omap_clkctrl_provider *provider, int num_parents = 0; const char * const *pname; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return; @@ -395,7 +395,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider, const struct omap_clkctrl_div_data *div_data = data->data; u8 div_flags = 0; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return; @@ -579,7 +579,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) return; } - provider = kzalloc(sizeof(*provider), GFP_KERNEL); + provider = kzalloc_obj(*provider); if (!provider) return; @@ -650,7 +650,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) continue; } - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) return; @@ -683,7 +683,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node) if (!init.name) goto cleanup; - clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL); + clkctrl_clk = kzalloc_obj(*clkctrl_clk); if (!clkctrl_clk) goto cleanup; diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index 8cba259188d4..c379bbdae25a 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -211,7 +211,7 @@ static void __init of_ti_composite_clk_setup(struct device_node *node) return; } - cclk = kzalloc(sizeof(*cclk), GFP_KERNEL); + cclk = kzalloc_obj(*cclk); if (!cclk) return; @@ -253,7 +253,7 @@ int __init ti_clk_add_component(struct device_node *node, struct clk_hw *hw, of_clk_parent_fill(node, parent_names, num_parents); - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) { kfree(parent_names); return -ENOMEM; diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index 6f58a0f2e74a..af923b8cb0ed 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -357,7 +357,7 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div, num_dividers = i; - tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_objs(*tmp, valid_div + 1); if (!tmp) return -ENOMEM; @@ -413,7 +413,7 @@ static int __init ti_clk_get_div_table(struct device_node *node, return -EINVAL; } - table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, valid_div + 1); if (!table) return -ENOMEM; @@ -517,7 +517,7 @@ static void __init of_ti_divider_clk_setup(struct device_node *node) u32 flags = 0; struct clk_omap_divider *div; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return; @@ -542,7 +542,7 @@ static void __init of_ti_composite_divider_clk_setup(struct device_node *node) struct clk_omap_divider *div; u32 tmp; - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return; diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 971adafd9a8b..e01272cd628d 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -222,7 +222,7 @@ static void _register_dpll_x2(struct device_node *node, return; } - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); if (!clk_hw) return; @@ -281,8 +281,8 @@ static void __init of_ti_dpll_setup(struct device_node *node, u32 min_div; dd = kmemdup(ddt, sizeof(*dd), GFP_KERNEL); - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); - init = kzalloc(sizeof(*init), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); + init = kzalloc_obj(*init); if (!dd || !clk_hw || !init) goto cleanup; diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 4f28138d2d8a..e54b1df3436e 100644 --- a/drivers/clk/ti/fapll.c +++ b/drivers/clk/ti/fapll.c @@ -499,7 +499,7 @@ static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd, struct fapll_synth *synth; struct clk *clk = ERR_PTR(-ENOMEM); - init = kzalloc(sizeof(*init), GFP_KERNEL); + init = kzalloc_obj(*init); if (!init) return ERR_PTR(-ENOMEM); @@ -508,7 +508,7 @@ static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd, init->parent_names = &parent; init->num_parents = 1; - synth = kzalloc(sizeof(*synth), GFP_KERNEL); + synth = kzalloc_obj(*synth); if (!synth) goto free; @@ -544,7 +544,7 @@ static void __init ti_fapll_setup(struct device_node *node) const char *name; int i; - fd = kzalloc(sizeof(*fd), GFP_KERNEL); + fd = kzalloc_obj(*fd); if (!fd) return; @@ -554,7 +554,7 @@ static void __init ti_fapll_setup(struct device_node *node) if (!fd->outputs.clks) goto free; - init = kzalloc(sizeof(*init), GFP_KERNEL); + init = kzalloc_obj(*init); if (!init) goto free; diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index a9febd6356b8..74741227013b 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -95,7 +95,7 @@ static struct clk *_register_gate(struct device_node *node, const char *name, struct clk_hw_omap *clk_hw; struct clk *clk; - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); if (!clk_hw) return ERR_PTR(-ENOMEM); @@ -169,7 +169,7 @@ _of_ti_composite_gate_clk_setup(struct device_node *node, { struct clk_hw_omap *gate; - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return; diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c index 3eb35c87c0ed..039c8075eca4 100644 --- a/drivers/clk/ti/interface.c +++ b/drivers/clk/ti/interface.c @@ -34,7 +34,7 @@ static struct clk *_register_interface(struct device_node *node, struct clk_hw_omap *clk_hw; struct clk *clk; - clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + clk_hw = kzalloc_obj(*clk_hw); if (!clk_hw) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index d6d247ff2be5..d6a0ccfd81db 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -129,7 +129,7 @@ static struct clk *_register_mux(struct device_node *node, const char *name, struct clk_init_data init; /* allocate the mux */ - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -227,7 +227,7 @@ struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) if (!setup) return NULL; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -253,7 +253,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node) struct clk_omap_mux *mux; unsigned int num_parents; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return; diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c index b85ee0930369..dce235df2576 100644 --- a/drivers/clk/ux500/clk-prcc.c +++ b/drivers/clk/ux500/clk-prcc.c @@ -106,7 +106,7 @@ static struct clk *clk_reg_prcc(const char *name, return ERR_PTR(-EINVAL); } - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c index f775e18acd46..ddc86551bf57 100644 --- a/drivers/clk/ux500/clk-prcmu.c +++ b/drivers/clk/ux500/clk-prcmu.c @@ -209,7 +209,7 @@ static struct clk_hw *clk_reg_prcmu(const char *name, return ERR_PTR(-EINVAL); } - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); @@ -376,7 +376,7 @@ struct clk_hw *clk_reg_prcmu_clkout(const char *name, return ERR_PTR(-EINVAL); } - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c index 8e2f6c65db2a..6f78808387b1 100644 --- a/drivers/clk/ux500/u8500_of_clk.c +++ b/drivers/clk/ux500/u8500_of_clk.c @@ -137,7 +137,7 @@ static void u8500_clk_init(struct device_node *np) * base addresses properly and pass to the reset controller init * function later on. */ - rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); + rstc = kzalloc_obj(*rstc); if (!rstc) return; diff --git a/drivers/clk/versatile/clk-icst.c b/drivers/clk/versatile/clk-icst.c index 86ca04ad9fab..6bd3db54dd22 100644 --- a/drivers/clk/versatile/clk-icst.c +++ b/drivers/clk/versatile/clk-icst.c @@ -363,7 +363,7 @@ struct clk *icst_clk_setup(struct device *dev, struct clk_init_data init; struct icst_params *pclone; - icst = kzalloc(sizeof(*icst), GFP_KERNEL); + icst = kzalloc_obj(*icst); if (!icst) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/versatile/clk-impd1.c b/drivers/clk/versatile/clk-impd1.c index 85c395df9c00..328dd47f1e43 100644 --- a/drivers/clk/versatile/clk-impd1.c +++ b/drivers/clk/versatile/clk-impd1.c @@ -104,15 +104,12 @@ static int integrator_impd1_clk_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; - struct device_node *child; int ret = 0; - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { ret = integrator_impd1_clk_spawn(dev, np, child); - if (ret) { - of_node_put(child); + if (ret) break; - } } return ret; diff --git a/drivers/clk/versatile/clk-sp810.c b/drivers/clk/versatile/clk-sp810.c index 033d4f78edc8..b0e69686f7a9 100644 --- a/drivers/clk/versatile/clk-sp810.c +++ b/drivers/clk/versatile/clk-sp810.c @@ -82,7 +82,7 @@ static struct clk *clk_sp810_timerclken_of_get(struct of_phandle_args *clkspec, static void __init clk_sp810_of_setup(struct device_node *node) { - struct clk_sp810 *sp810 = kzalloc(sizeof(*sp810), GFP_KERNEL); + struct clk_sp810 *sp810 = kzalloc_obj(*sp810); const char *parent_names[2]; int num = ARRAY_SIZE(parent_names); char name[12]; diff --git a/drivers/clk/visconti/pll.c b/drivers/clk/visconti/pll.c index 681721d85032..6fd02c4b641e 100644 --- a/drivers/clk/visconti/pll.c +++ b/drivers/clk/visconti/pll.c @@ -255,7 +255,7 @@ static struct clk_hw *visconti_register_pll(struct visconti_pll_provider *ctx, size_t len; int ret; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); @@ -330,7 +330,7 @@ struct visconti_pll_provider * __init visconti_init_pll(struct device_node *np, struct visconti_pll_provider *ctx; int i; - ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_plls), GFP_KERNEL); + ctx = kzalloc_flex(*ctx, clk_data.hws, nr_plls); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/x86/clk-cgu.c b/drivers/clk/x86/clk-cgu.c index d099667355f8..92ee05d75af2 100644 --- a/drivers/clk/x86/clk-cgu.c +++ b/drivers/clk/x86/clk-cgu.c @@ -137,10 +137,8 @@ static int lgm_clk_divider_determine_rate(struct clk_hw *hw, { struct lgm_clk_divider *divider = to_lgm_clk_divider(hw); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, divider->table, - divider->width, divider->flags); - - return 0; + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); } static int diff --git a/drivers/clk/zynq/clkc.c b/drivers/clk/zynq/clkc.c index c28d3dacf0fb..6a22cbbc1235 100644 --- a/drivers/clk/zynq/clkc.c +++ b/drivers/clk/zynq/clkc.c @@ -112,10 +112,10 @@ static void __init zynq_clk_register_fclk(enum zynq_clk fclk, spinlock_t *fclk_gate_lock; void __iomem *fclk_gate_reg = fclk_ctrl_reg + 8; - fclk_lock = kmalloc(sizeof(*fclk_lock), GFP_KERNEL); + fclk_lock = kmalloc_obj(*fclk_lock); if (!fclk_lock) goto err; - fclk_gate_lock = kmalloc(sizeof(*fclk_gate_lock), GFP_KERNEL); + fclk_gate_lock = kmalloc_obj(*fclk_gate_lock); if (!fclk_gate_lock) goto err_fclk_gate_lock; spin_lock_init(fclk_lock); @@ -180,7 +180,7 @@ static void __init zynq_clk_register_periph_clk(enum zynq_clk clk0, char *div_name; spinlock_t *lock; - lock = kmalloc(sizeof(*lock), GFP_KERNEL); + lock = kmalloc_obj(*lock); if (!lock) goto err; spin_lock_init(lock); diff --git a/drivers/clk/zynq/pll.c b/drivers/clk/zynq/pll.c index 5eca1c14981a..44c609378364 100644 --- a/drivers/clk/zynq/pll.c +++ b/drivers/clk/zynq/pll.c @@ -200,7 +200,7 @@ struct clk *clk_register_zynq_pll(const char *name, const char *parent, .flags = 0 }; - pll = kmalloc(sizeof(*pll), GFP_KERNEL); + pll = kmalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/zynqmp/clk-gate-zynqmp.c b/drivers/clk/zynqmp/clk-gate-zynqmp.c index b89e55737198..db10eb69f3fe 100644 --- a/drivers/clk/zynqmp/clk-gate-zynqmp.c +++ b/drivers/clk/zynqmp/clk-gate-zynqmp.c @@ -115,7 +115,7 @@ struct clk_hw *zynqmp_clk_register_gate(const char *name, u32 clk_id, struct clk_init_data init; /* allocate the gate */ - gate = kzalloc(sizeof(*gate), GFP_KERNEL); + gate = kzalloc_obj(*gate); if (!gate) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/zynqmp/clk-mux-zynqmp.c b/drivers/clk/zynqmp/clk-mux-zynqmp.c index 9b5d3050b742..e37bd3516974 100644 --- a/drivers/clk/zynqmp/clk-mux-zynqmp.c +++ b/drivers/clk/zynqmp/clk-mux-zynqmp.c @@ -138,7 +138,7 @@ struct clk_hw *zynqmp_clk_register_mux(const char *name, u32 clk_id, struct clk_init_data init; int ret; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/zynqmp/clkc.c b/drivers/clk/zynqmp/clkc.c index a91d98e238c2..d62f1901d0ab 100644 --- a/drivers/clk/zynqmp/clkc.c +++ b/drivers/clk/zynqmp/clkc.c @@ -759,12 +759,11 @@ static int zynqmp_clk_setup(struct device_node *np) if (ret) return ret; - zynqmp_data = kzalloc(struct_size(zynqmp_data, hws, clock_max_idx), - GFP_KERNEL); + zynqmp_data = kzalloc_flex(*zynqmp_data, hws, clock_max_idx); if (!zynqmp_data) return -ENOMEM; - clock = kcalloc(clock_max_idx, sizeof(*clock), GFP_KERNEL); + clock = kzalloc_objs(*clock, clock_max_idx); if (!clock) { kfree(zynqmp_data); return -ENOMEM; diff --git a/drivers/clk/zynqmp/divider.c b/drivers/clk/zynqmp/divider.c index c824eeacd8eb..4075f6ecf076 100644 --- a/drivers/clk/zynqmp/divider.c +++ b/drivers/clk/zynqmp/divider.c @@ -111,10 +111,9 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw, } /** - * zynqmp_clk_divider_round_rate() - Round rate of divider clock + * zynqmp_clk_divider_determine_rate() - Determine rate of divider clock * @hw: handle between common and hardware-specific interfaces - * @rate: rate of clock to be set - * @prate: rate of parent clock + * @req: rate of clock to be set * * Return: 0 on success else error+reason */ @@ -151,8 +150,9 @@ static int zynqmp_clk_divider_determine_rate(struct clk_hw *hw, width = fls(divider->max_div); - req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, - NULL, width, divider->flags); + ret = divider_determine_rate(hw, req, NULL, width, divider->flags); + if (ret != 0) + return ret; if (divider->is_frac && (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && (req->rate % req->best_parent_rate)) @@ -284,7 +284,7 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name, int ret; /* allocate the divider */ - div = kzalloc(sizeof(*div), GFP_KERNEL); + div = kzalloc_obj(*div); if (!div) return ERR_PTR(-ENOMEM); diff --git a/drivers/clk/zynqmp/pll.c b/drivers/clk/zynqmp/pll.c index 630a3936c97c..6463787cf57b 100644 --- a/drivers/clk/zynqmp/pll.c +++ b/drivers/clk/zynqmp/pll.c @@ -91,10 +91,9 @@ static inline void zynqmp_pll_set_mode(struct clk_hw *hw, bool on) } /** - * zynqmp_pll_round_rate() - Round a clock frequency + * zynqmp_pll_determine_rate() - Round a clock frequency * @hw: Handle between common and hardware-specific interfaces - * @rate: Desired clock frequency - * @prate: Clock frequency of parent clock + * @req: Desired clock frequency * * Return: Frequency closest to @rate the hardware can generate */ @@ -327,7 +326,7 @@ struct clk_hw *zynqmp_clk_register_pll(const char *name, u32 clk_id, init.parent_names = parents; init.num_parents = 1; - pll = kzalloc(sizeof(*pll), GFP_KERNEL); + pll = kzalloc_obj(*pll); if (!pll) return ERR_PTR(-ENOMEM); diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c index 319c0c780a15..d7662301bf0e 100644 --- a/drivers/clocksource/bcm2835_timer.c +++ b/drivers/clocksource/bcm2835_timer.c @@ -98,7 +98,7 @@ static int __init bcm2835_timer_init(struct device_node *node) goto err_iounmap; } - timer = kzalloc(sizeof(*timer), GFP_KERNEL); + timer = kzalloc_obj(*timer); if (!timer) { ret = -ENOMEM; goto err_iounmap; diff --git a/drivers/clocksource/clps711x-timer.c b/drivers/clocksource/clps711x-timer.c index bbceb0289d45..bb0a44adaf28 100644 --- a/drivers/clocksource/clps711x-timer.c +++ b/drivers/clocksource/clps711x-timer.c @@ -54,7 +54,7 @@ static int __init _clps711x_clkevt_init(struct clk *clock, void __iomem *base, struct clock_event_device *clkevt; unsigned long rate; - clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL); + clkevt = kzalloc_obj(*clkevt); if (!clkevt) return -ENOMEM; diff --git a/drivers/clocksource/dw_apb_timer.c b/drivers/clocksource/dw_apb_timer.c index 3a55ae5fe225..501980303ddf 100644 --- a/drivers/clocksource/dw_apb_timer.c +++ b/drivers/clocksource/dw_apb_timer.c @@ -222,8 +222,7 @@ struct dw_apb_clock_event_device * dw_apb_clockevent_init(int cpu, const char *name, unsigned rating, void __iomem *base, int irq, unsigned long freq) { - struct dw_apb_clock_event_device *dw_ced = - kzalloc(sizeof(*dw_ced), GFP_KERNEL); + struct dw_apb_clock_event_device *dw_ced = kzalloc_obj(*dw_ced); int err; if (!dw_ced) @@ -340,7 +339,7 @@ struct dw_apb_clocksource * dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base, unsigned long freq) { - struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL); + struct dw_apb_clocksource *dw_cs = kzalloc_obj(*dw_cs); if (!dw_cs) return NULL; diff --git a/drivers/clocksource/ingenic-sysost.c b/drivers/clocksource/ingenic-sysost.c index e79cfb0b8e05..026615bbe921 100644 --- a/drivers/clocksource/ingenic-sysost.c +++ b/drivers/clocksource/ingenic-sysost.c @@ -279,7 +279,7 @@ static int __init ingenic_ost_register_clock(struct ingenic_ost *ost, struct ingenic_ost_clk *ost_clk; int val, err; - ost_clk = kzalloc(sizeof(*ost_clk), GFP_KERNEL); + ost_clk = kzalloc_obj(*ost_clk); if (!ost_clk) return -ENOMEM; @@ -432,7 +432,7 @@ static int __init ingenic_ost_probe(struct device_node *np) unsigned int i; int ret; - ost = kzalloc(sizeof(*ost), GFP_KERNEL); + ost = kzalloc_obj(*ost); if (!ost) return -ENOMEM; @@ -458,8 +458,8 @@ static int __init ingenic_ost_probe(struct device_node *np) ost->soc_info = id->data; - ost->clocks = kzalloc(struct_size(ost->clocks, hws, ost->soc_info->num_channels), - GFP_KERNEL); + ost->clocks = kzalloc_flex(*ost->clocks, hws, + ost->soc_info->num_channels); if (!ost->clocks) { ret = -ENOMEM; goto err_clk_disable; diff --git a/drivers/clocksource/ingenic-timer.c b/drivers/clocksource/ingenic-timer.c index 154ee5f7954a..54bb56005dfd 100644 --- a/drivers/clocksource/ingenic-timer.c +++ b/drivers/clocksource/ingenic-timer.c @@ -286,8 +286,7 @@ static int __init ingenic_tcu_init(struct device_node *np) if (IS_ERR(map)) return PTR_ERR(map); - tcu = kzalloc(struct_size(tcu, timers, num_possible_cpus()), - GFP_KERNEL); + tcu = kzalloc_flex(*tcu, timers, num_possible_cpus()); if (!tcu) return -ENOMEM; diff --git a/drivers/clocksource/mmio.c b/drivers/clocksource/mmio.c index 9de751531831..cd5fbf49ac29 100644 --- a/drivers/clocksource/mmio.c +++ b/drivers/clocksource/mmio.c @@ -55,7 +55,7 @@ int __init clocksource_mmio_init(void __iomem *base, const char *name, if (bits > 64 || bits < 16) return -EINVAL; - cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL); + cs = kzalloc_obj(struct clocksource_mmio); if (!cs) return -ENOMEM; diff --git a/drivers/clocksource/mps2-timer.c b/drivers/clocksource/mps2-timer.c index efe8cad8f2a5..ebca55d8cfed 100644 --- a/drivers/clocksource/mps2-timer.c +++ b/drivers/clocksource/mps2-timer.c @@ -136,7 +136,7 @@ static int __init mps2_clockevent_init(struct device_node *np) goto out_iounmap; } - ce = kzalloc(sizeof(*ce), GFP_KERNEL); + ce = kzalloc_obj(*ce); if (!ce) { ret = -ENOMEM; goto out_iounmap; diff --git a/drivers/clocksource/renesas-ostm.c b/drivers/clocksource/renesas-ostm.c index 2089aeaae225..9404ccb1bda9 100644 --- a/drivers/clocksource/renesas-ostm.c +++ b/drivers/clocksource/renesas-ostm.c @@ -165,7 +165,7 @@ static int __init ostm_init(struct device_node *np) struct timer_of *to; int ret; - to = kzalloc(sizeof(*to), GFP_KERNEL); + to = kzalloc_obj(*to); if (!to) return -ENOMEM; diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 791b298c995b..cf057f531a58 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -1084,8 +1084,7 @@ static int sh_cmt_setup(struct sh_cmt_device *cmt, struct platform_device *pdev) /* Allocate and setup the channels. */ cmt->num_channels = hweight8(cmt->hw_channels); - cmt->channels = kcalloc(cmt->num_channels, sizeof(*cmt->channels), - GFP_KERNEL); + cmt->channels = kzalloc_objs(*cmt->channels, cmt->num_channels); if (cmt->channels == NULL) { ret = -ENOMEM; goto err_unmap; @@ -1139,7 +1138,7 @@ static int sh_cmt_probe(struct platform_device *pdev) goto out; } - cmt = kzalloc(sizeof(*cmt), GFP_KERNEL); + cmt = kzalloc_obj(*cmt); if (cmt == NULL) return -ENOMEM; diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index 34872df5458a..1997639b113e 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -420,8 +420,7 @@ static int sh_mtu2_setup(struct sh_mtu2_device *mtu, mtu->num_channels = min_t(unsigned int, ret, ARRAY_SIZE(sh_mtu2_channel_offsets)); - mtu->channels = kcalloc(mtu->num_channels, sizeof(*mtu->channels), - GFP_KERNEL); + mtu->channels = kzalloc_objs(*mtu->channels, mtu->num_channels); if (mtu->channels == NULL) { ret = -ENOMEM; goto err_unmap; @@ -462,7 +461,7 @@ static int sh_mtu2_probe(struct platform_device *pdev) goto out; } - mtu = kzalloc(sizeof(*mtu), GFP_KERNEL); + mtu = kzalloc_obj(*mtu); if (mtu == NULL) return -ENOMEM; diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 3fc6ed9b5630..8d6a9e279f73 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -546,8 +546,7 @@ static int sh_tmu_setup(struct sh_tmu_device *tmu, struct platform_device *pdev) } /* Allocate and setup the channels. */ - tmu->channels = kcalloc(tmu->num_channels, sizeof(*tmu->channels), - GFP_KERNEL); + tmu->channels = kzalloc_objs(*tmu->channels, tmu->num_channels); if (tmu->channels == NULL) { ret = -ENOMEM; goto err_unmap; @@ -593,7 +592,7 @@ static int sh_tmu_probe(struct platform_device *pdev) goto out; } - tmu = kzalloc(sizeof(*tmu), GFP_KERNEL); + tmu = kzalloc_obj(*tmu); if (tmu == NULL) return -ENOMEM; diff --git a/drivers/clocksource/timer-atmel-pit.c b/drivers/clocksource/timer-atmel-pit.c index b4f264ed1937..888b06731e54 100644 --- a/drivers/clocksource/timer-atmel-pit.c +++ b/drivers/clocksource/timer-atmel-pit.c @@ -170,7 +170,7 @@ static int __init at91sam926x_pit_dt_init(struct device_node *node) int ret; struct pit_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/clocksource/timer-cadence-ttc.c b/drivers/clocksource/timer-cadence-ttc.c index b8a1cf59b9d6..3c50d6892849 100644 --- a/drivers/clocksource/timer-cadence-ttc.c +++ b/drivers/clocksource/timer-cadence-ttc.c @@ -334,7 +334,7 @@ static int __init ttc_setup_clocksource(struct clk *clk, void __iomem *base, struct ttc_timer_clocksource *ttccs; int err; - ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); + ttccs = kzalloc_obj(*ttccs); if (!ttccs) return -ENOMEM; @@ -417,7 +417,7 @@ static int __init ttc_setup_clockevent(struct clk *clk, struct ttc_timer_clockevent *ttcce; int err; - ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); + ttcce = kzalloc_obj(*ttcce); if (!ttcce) return -ENOMEM; diff --git a/drivers/clocksource/timer-davinci.c b/drivers/clocksource/timer-davinci.c index b1c248498be4..16ee0687ef31 100644 --- a/drivers/clocksource/timer-davinci.c +++ b/drivers/clocksource/timer-davinci.c @@ -271,7 +271,7 @@ int __init davinci_timer_register(struct clk *clk, davinci_timer_init(base); tick_rate = clk_get_rate(clk); - clockevent = kzalloc(sizeof(*clockevent), GFP_KERNEL); + clockevent = kzalloc_obj(*clockevent); if (!clockevent) { rv = -ENOMEM; goto exit_iounmap_base; diff --git a/drivers/clocksource/timer-ep93xx.c b/drivers/clocksource/timer-ep93xx.c index 6981ff3ac8a9..1b719282c07f 100644 --- a/drivers/clocksource/timer-ep93xx.c +++ b/drivers/clocksource/timer-ep93xx.c @@ -141,7 +141,7 @@ static int __init ep93xx_timer_of_init(struct device_node *np) struct ep93xx_tcu *tcu; int ret; - tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); + tcu = kzalloc_obj(*tcu); if (!tcu) return -ENOMEM; diff --git a/drivers/clocksource/timer-fsl-ftm.c b/drivers/clocksource/timer-fsl-ftm.c index 93f336ec875a..4eed6cb46132 100644 --- a/drivers/clocksource/timer-fsl-ftm.c +++ b/drivers/clocksource/timer-fsl-ftm.c @@ -300,7 +300,7 @@ static int __init ftm_timer_init(struct device_node *np) unsigned long freq; int ret, irq; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/clocksource/timer-fttmr010.c b/drivers/clocksource/timer-fttmr010.c index 126fb1f259b2..308f94bfbaed 100644 --- a/drivers/clocksource/timer-fttmr010.c +++ b/drivers/clocksource/timer-fttmr010.c @@ -295,7 +295,7 @@ static int __init fttmr010_common_init(struct device_node *np, return ret; } - fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL); + fttmr010 = kzalloc_obj(*fttmr010); if (!fttmr010) { ret = -ENOMEM; goto out_disable_clock; diff --git a/drivers/clocksource/timer-goldfish.c b/drivers/clocksource/timer-goldfish.c index 0512d5eabc82..3fe12c7ee7b7 100644 --- a/drivers/clocksource/timer-goldfish.c +++ b/drivers/clocksource/timer-goldfish.c @@ -102,7 +102,7 @@ int __init goldfish_timer_init(int irq, void __iomem *base) struct goldfish_timer *timerdrv; int ret; - timerdrv = kzalloc(sizeof(*timerdrv), GFP_KERNEL); + timerdrv = kzalloc_obj(*timerdrv); if (!timerdrv) return -ENOMEM; diff --git a/drivers/clocksource/timer-gxp.c b/drivers/clocksource/timer-gxp.c index 48a73c101eb8..1becc943339d 100644 --- a/drivers/clocksource/timer-gxp.c +++ b/drivers/clocksource/timer-gxp.c @@ -76,7 +76,7 @@ static int __init gxp_timer_init(struct device_node *node) u32 freq; int ret, irq; - gxp_timer = kzalloc(sizeof(*gxp_timer), GFP_KERNEL); + gxp_timer = kzalloc_obj(*gxp_timer); if (!gxp_timer) { ret = -ENOMEM; pr_err("Can't allocate gxp_timer"); diff --git a/drivers/clocksource/timer-imx-gpt.c b/drivers/clocksource/timer-imx-gpt.c index 489e69169ed4..8335bd7f8c6c 100644 --- a/drivers/clocksource/timer-imx-gpt.c +++ b/drivers/clocksource/timer-imx-gpt.c @@ -428,7 +428,7 @@ static int __init mxc_timer_init_dt(struct device_node *np, enum imx_gpt_type t if (initialized) return 0; - imxtm = kzalloc(sizeof(*imxtm), GFP_KERNEL); + imxtm = kzalloc_obj(*imxtm); if (!imxtm) return -ENOMEM; diff --git a/drivers/clocksource/timer-imx-sysctr.c b/drivers/clocksource/timer-imx-sysctr.c index 44525813be1e..dfbd77950e02 100644 --- a/drivers/clocksource/timer-imx-sysctr.c +++ b/drivers/clocksource/timer-imx-sysctr.c @@ -139,7 +139,7 @@ static int __init __sysctr_timer_init(struct device_node *np) void __iomem *base; int ret; - priv = kzalloc(sizeof(struct sysctr_private), GFP_KERNEL); + priv = kzalloc_obj(struct sysctr_private); if (!priv) return -ENOMEM; diff --git a/drivers/clocksource/timer-ixp4xx.c b/drivers/clocksource/timer-ixp4xx.c index 720ed70a2964..4238a004fdef 100644 --- a/drivers/clocksource/timer-ixp4xx.c +++ b/drivers/clocksource/timer-ixp4xx.c @@ -166,7 +166,7 @@ static __init int ixp4xx_timer_register(void __iomem *base, struct ixp4xx_timer *tmr; int ret; - tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); + tmr = kzalloc_obj(*tmr); if (!tmr) return -ENOMEM; tmr->base = base; diff --git a/drivers/clocksource/timer-microchip-pit64b.c b/drivers/clocksource/timer-microchip-pit64b.c index 57209bb38c70..7439bff42233 100644 --- a/drivers/clocksource/timer-microchip-pit64b.c +++ b/drivers/clocksource/timer-microchip-pit64b.c @@ -350,7 +350,7 @@ static int __init mchp_pit64b_init_clksrc(struct mchp_pit64b_timer *timer, struct mchp_pit64b_clksrc *cs; int ret; - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; @@ -397,7 +397,7 @@ static int __init mchp_pit64b_init_clkevt(struct mchp_pit64b_timer *timer, struct mchp_pit64b_clkevt *ce; int ret; - ce = kzalloc(sizeof(*ce), GFP_KERNEL); + ce = kzalloc_obj(*ce); if (!ce) return -ENOMEM; diff --git a/drivers/clocksource/timer-msc313e.c b/drivers/clocksource/timer-msc313e.c index 54c54ca7c786..e4b9e3f161bb 100644 --- a/drivers/clocksource/timer-msc313e.c +++ b/drivers/clocksource/timer-msc313e.c @@ -171,7 +171,7 @@ static int __init msc313e_clkevt_init(struct device_node *np) int ret; struct timer_of *to; - to = kzalloc(sizeof(*to), GFP_KERNEL); + to = kzalloc_obj(*to); if (!to) return -ENOMEM; diff --git a/drivers/clocksource/timer-nxp-pit.c b/drivers/clocksource/timer-nxp-pit.c index d1740f18f718..bc5157e2ba57 100644 --- a/drivers/clocksource/timer-nxp-pit.c +++ b/drivers/clocksource/timer-nxp-pit.c @@ -276,7 +276,7 @@ static int pit_timer_init(struct device_node *np) unsigned long clk_rate; int irq, ret; - pit = kzalloc(sizeof(*pit), GFP_KERNEL); + pit = kzalloc_obj(*pit); if (!pit) return -ENOMEM; diff --git a/drivers/clocksource/timer-rockchip.c b/drivers/clocksource/timer-rockchip.c index 1f95d0aca08f..540a16667145 100644 --- a/drivers/clocksource/timer-rockchip.c +++ b/drivers/clocksource/timer-rockchip.c @@ -207,7 +207,7 @@ static int __init rk_clkevt_init(struct device_node *np) struct clock_event_device *ce; int ret = -EINVAL; - rk_clkevt = kzalloc(sizeof(struct rk_clkevt), GFP_KERNEL); + rk_clkevt = kzalloc_obj(struct rk_clkevt); if (!rk_clkevt) { ret = -ENOMEM; goto out; @@ -254,7 +254,7 @@ static int __init rk_clksrc_init(struct device_node *np) { int ret = -EINVAL; - rk_clksrc = kzalloc(sizeof(struct rk_timer), GFP_KERNEL); + rk_clksrc = kzalloc_obj(struct rk_timer); if (!rk_clksrc) { ret = -ENOMEM; goto out; diff --git a/drivers/clocksource/timer-stm32.c b/drivers/clocksource/timer-stm32.c index 0a4ea3288bfb..fee65914f99a 100644 --- a/drivers/clocksource/timer-stm32.c +++ b/drivers/clocksource/timer-stm32.c @@ -291,7 +291,7 @@ static int __init stm32_timer_init(struct device_node *node) struct timer_of *to; int ret; - to = kzalloc(sizeof(*to), GFP_KERNEL); + to = kzalloc_obj(*to); if (!to) return -ENOMEM; @@ -302,8 +302,7 @@ static int __init stm32_timer_init(struct device_node *node) if (ret) goto err; - to->private_data = kzalloc(sizeof(struct stm32_timer_private), - GFP_KERNEL); + to->private_data = kzalloc_obj(struct stm32_timer_private); if (!to->private_data) { ret = -ENOMEM; goto deinit; diff --git a/drivers/clocksource/timer-ti-dm-systimer.c b/drivers/clocksource/timer-ti-dm-systimer.c index 985a6d08512b..eb0dfe4b9b7c 100644 --- a/drivers/clocksource/timer-ti-dm-systimer.c +++ b/drivers/clocksource/timer-ti-dm-systimer.c @@ -600,7 +600,7 @@ static int __init dmtimer_clockevent_init(struct device_node *np) struct dmtimer_clockevent *clkevt; int error; - clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL); + clkevt = kzalloc_obj(*clkevt); if (!clkevt) return -ENOMEM; @@ -757,7 +757,7 @@ static int __init dmtimer_clocksource_init(struct device_node *np) struct clocksource *dev; int error; - clksrc = kzalloc(sizeof(*clksrc), GFP_KERNEL); + clksrc = kzalloc_obj(*clksrc); if (!clksrc) return -ENOMEM; diff --git a/drivers/clocksource/timer-zevio.c b/drivers/clocksource/timer-zevio.c index ecaa3568841c..9a67b84b3e4c 100644 --- a/drivers/clocksource/timer-zevio.c +++ b/drivers/clocksource/timer-zevio.c @@ -119,7 +119,7 @@ static int __init zevio_timer_add(struct device_node *node) struct resource res; int irqnr, ret; - timer = kzalloc(sizeof(*timer), GFP_KERNEL); + timer = kzalloc_obj(*timer); if (!timer) return -ENOMEM; diff --git a/drivers/comedi/comedi_buf.c b/drivers/comedi/comedi_buf.c index 785977b40a93..ed372619bf54 100644 --- a/drivers/comedi/comedi_buf.c +++ b/drivers/comedi/comedi_buf.c @@ -70,7 +70,7 @@ comedi_buf_map_alloc(struct comedi_device *dev, enum dma_data_direction dma_dir, struct comedi_buf_page *buf; unsigned int i; - bm = kzalloc(sizeof(*bm), GFP_KERNEL); + bm = kzalloc_obj(*bm); if (!bm) return NULL; diff --git a/drivers/comedi/comedi_fops.c b/drivers/comedi/comedi_fops.c index 2c3eb9e89571..48a8a607a84c 100644 --- a/drivers/comedi/comedi_fops.c +++ b/drivers/comedi/comedi_fops.c @@ -1058,7 +1058,7 @@ static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdevice *s; lockdep_assert_held(&dev->mutex); - tmp = kcalloc(dev->n_subdevices, sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_objs(*tmp, dev->n_subdevices); if (!tmp) return -ENOMEM; @@ -1169,6 +1169,8 @@ static int do_chaninfo_ioctl(struct comedi_device *dev, * COMEDI_BUFINFO ioctl * buffer information * + * Note that the comedi device's mutex has not been locked for this ioctl. + * * arg: * pointer to comedi_bufinfo structure * @@ -1186,24 +1188,42 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, struct comedi_async *async; unsigned int runflags; int retval = 0; + unsigned int old_detach_count; + unsigned int cmd_flags; bool become_nonbusy = false; + bool attach_locked; - lockdep_assert_held(&dev->mutex); if (copy_from_user(&bi, arg, sizeof(bi))) return -EFAULT; - if (bi.subdevice >= dev->n_subdevices) - return -EINVAL; + /* Protect against device detachment during operation. */ + down_read(&dev->attach_lock); + attach_locked = true; + old_detach_count = dev->detach_count; + + if (!dev->attached) { + dev_dbg(dev->class_dev, "no driver attached\n"); + retval = -ENODEV; + goto out; + } + + if (bi.subdevice >= dev->n_subdevices) { + retval = -EINVAL; + goto out; + } s = &dev->subdevices[bi.subdevice]; async = s->async; - if (!async || s->busy != file) - return -EINVAL; + if (!async || s->busy != file) { + retval = -EINVAL; + goto out; + } runflags = comedi_get_subdevice_runflags(s); - if (!(async->cmd.flags & CMDF_WRITE)) { + cmd_flags = async->cmd.flags; + if (!(cmd_flags & CMDF_WRITE)) { /* command was set up in "read" direction */ if (bi.bytes_read) { _comedi_buf_read_alloc(s, bi.bytes_read); @@ -1243,8 +1263,41 @@ static int do_bufinfo_ioctl(struct comedi_device *dev, bi.buf_read_count = async->buf_read_count; bi.buf_read_ptr = async->buf_read_ptr; - if (become_nonbusy) - do_become_nonbusy(dev, s); + if (become_nonbusy) { + struct comedi_subdevice *new_s = NULL; + + /* + * To avoid deadlock, cannot acquire dev->mutex + * while dev->attach_lock is held. + */ + up_read(&dev->attach_lock); + attach_locked = false; + mutex_lock(&dev->mutex); + /* + * Check device hasn't become detached behind our back. + * Checking dev->detach_count is unchanged ought to be + * sufficient, but check the subdevice pointer as well, + * and check the subdevice is still in a suitable state + * to become non-busy. It should still be "busy" after + * running an asynchronous commands, which should now have + * stopped, and for a command in the "read" direction, all + * available data should have been read. + */ + if (dev->attached && old_detach_count == dev->detach_count && + bi.subdevice < dev->n_subdevices) + new_s = &dev->subdevices[bi.subdevice]; + if (s == new_s && new_s->async == async && s->busy == file && + async->cmd.flags == cmd_flags && + !comedi_is_subdevice_running(s) && + ((cmd_flags & CMDF_WRITE) != 0 || + _comedi_buf_read_n_available(s) == 0)) + do_become_nonbusy(dev, s); + mutex_unlock(&dev->mutex); + } + +out: + if (attach_locked) + up_read(&dev->attach_lock); if (retval) return retval; @@ -2225,6 +2278,13 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, struct comedi_device *dev = cfp->dev; int rc; + /* Handle COMEDI_BUFINFO without locking the mutex first. */ + if (cmd == COMEDI_BUFINFO) { + return do_bufinfo_ioctl(dev, + (struct comedi_bufinfo __user *)arg, + file); + } + mutex_lock(&dev->mutex); /* @@ -2294,11 +2354,6 @@ static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd, rc = do_rangeinfo_ioctl(dev, &it); break; } - case COMEDI_BUFINFO: - rc = do_bufinfo_ioctl(dev, - (struct comedi_bufinfo __user *)arg, - file); - break; case COMEDI_LOCK: rc = do_lock_ioctl(dev, arg, file); break; @@ -2914,7 +2969,7 @@ static int comedi_open(struct inode *inode, struct file *file) return -ENODEV; } - cfp = kzalloc(sizeof(*cfp), GFP_KERNEL); + cfp = kzalloc_obj(*cfp); if (!cfp) { comedi_dev_put(dev); return -ENOMEM; @@ -3267,7 +3322,7 @@ static int compat_insnlist(struct file *file, unsigned long arg) rc = check_insnlist_len(dev, insnlist32.n_insns); if (rc) return rc; - insns = kcalloc(insnlist32.n_insns, sizeof(*insns), GFP_KERNEL); + insns = kzalloc_objs(*insns, insnlist32.n_insns); if (!insns) return -ENOMEM; @@ -3450,7 +3505,7 @@ struct comedi_device *comedi_alloc_board_minor(struct device *hardware_device) struct device *csdev; unsigned int i; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); comedi_device_init(dev); diff --git a/drivers/comedi/drivers.c b/drivers/comedi/drivers.c index 69cd2a253c66..db225a3bf012 100644 --- a/drivers/comedi/drivers.c +++ b/drivers/comedi/drivers.c @@ -101,7 +101,7 @@ int comedi_alloc_subdevices(struct comedi_device *dev, int num_subdevices) if (num_subdevices < 1) return -EINVAL; - s = kcalloc(num_subdevices, sizeof(*s), GFP_KERNEL); + s = kzalloc_objs(*s, num_subdevices); if (!s) return -ENOMEM; dev->subdevices = s; @@ -733,7 +733,7 @@ static int __comedi_device_postconfig_async(struct comedi_device *dev, dev_warn(dev->class_dev, "async subdevices should have a cancel() function\n"); - async = kzalloc(sizeof(*async), GFP_KERNEL); + async = kzalloc_obj(*async); if (!async) return -ENOMEM; diff --git a/drivers/comedi/drivers/addi_apci_2032.c b/drivers/comedi/drivers/addi_apci_2032.c index e048dfc3ec77..d0f52d5ece8f 100644 --- a/drivers/comedi/drivers/addi_apci_2032.c +++ b/drivers/comedi/drivers/addi_apci_2032.c @@ -274,7 +274,7 @@ static int apci2032_auto_attach(struct comedi_device *dev, struct apci2032_int_private *subpriv; dev->read_subdev = s; - subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); + subpriv = kzalloc_obj(*subpriv); if (!subpriv) return -ENOMEM; spin_lock_init(&subpriv->spinlock); diff --git a/drivers/comedi/drivers/comedi_8254.c b/drivers/comedi/drivers/comedi_8254.c index 6beca2a6d66e..a297dd650dab 100644 --- a/drivers/comedi/drivers/comedi_8254.c +++ b/drivers/comedi/drivers/comedi_8254.c @@ -633,7 +633,7 @@ static struct comedi_8254 *__i8254_init(comedi_8254_iocb_fn *iocb, if (!iocb) return ERR_PTR(-EINVAL); - i8254 = kzalloc(sizeof(*i8254), GFP_KERNEL); + i8254 = kzalloc_obj(*i8254); if (!i8254) return ERR_PTR(-ENOMEM); diff --git a/drivers/comedi/drivers/comedi_bond.c b/drivers/comedi/drivers/comedi_bond.c index 30650fa36fff..8e10ecab4f0d 100644 --- a/drivers/comedi/drivers/comedi_bond.c +++ b/drivers/comedi/drivers/comedi_bond.c @@ -223,7 +223,7 @@ static int do_dev_config(struct comedi_device *dev, struct comedi_devconfig *it) nchans, minor, sdev); return -EINVAL; } - bdev = kmalloc(sizeof(*bdev), GFP_KERNEL); + bdev = kmalloc_obj(*bdev); if (!bdev) return -ENOMEM; diff --git a/drivers/comedi/drivers/comedi_isadma.c b/drivers/comedi/drivers/comedi_isadma.c index 020b3d1e1ac0..04ce3eb9ae4f 100644 --- a/drivers/comedi/drivers/comedi_isadma.c +++ b/drivers/comedi/drivers/comedi_isadma.c @@ -161,11 +161,11 @@ struct comedi_isadma *comedi_isadma_alloc(struct comedi_device *dev, if (n_desc < 1 || n_desc > 2) goto no_dma; - dma = kzalloc(sizeof(*dma), GFP_KERNEL); + dma = kzalloc_obj(*dma); if (!dma) goto no_dma; - desc = kcalloc(n_desc, sizeof(*desc), GFP_KERNEL); + desc = kzalloc_objs(*desc, n_desc); if (!desc) goto no_dma; dma->desc = desc; diff --git a/drivers/comedi/drivers/comedi_test.c b/drivers/comedi/drivers/comedi_test.c index 7984950f0f99..01aafce20ef8 100644 --- a/drivers/comedi/drivers/comedi_test.c +++ b/drivers/comedi/drivers/comedi_test.c @@ -692,6 +692,44 @@ static int waveform_ao_insn_config(struct comedi_device *dev, return -EINVAL; } +static int waveform_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + u32 driven_low; + u16 wires; + + /* Update the channel outputs. */ + comedi_dio_update_state(s, data); + /* + * We are modelling the outputs as NPN open collector (0 = driven low, + * 1 = high impedance), with the lower 16 channels wired to the upper + * 16 channels in pairs (0 to 16, 1 to 17, ..., 15 to 31), with a + * pull-up resistor on each wire. When reading back each channel, we + * read back the state of the wire to which it is connected. + * + * The state of each wire and the value read back from both channels + * connected to it will be logic 1 unless either channel connected to + * the wire is configured as an output in the logic 0 state. + */ + driven_low = s->io_bits & ~s->state; + wires = 0xFFFF & ~driven_low & ~(driven_low >> 16); + /* Read back the state of the wires for each pair of channels. */ + data[1] = wires | (wires << 16); + + return insn->n; +} + +static int waveform_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + /* configure each channel as input or output individually */ + return comedi_dio_insn_config(dev, s, insn, data, 0); +} + static int waveform_common_attach(struct comedi_device *dev, int amplitude, int period) { @@ -707,7 +745,7 @@ static int waveform_common_attach(struct comedi_device *dev, devpriv->wf_amplitude = amplitude; devpriv->wf_period = period; - ret = comedi_alloc_subdevices(dev, 2); + ret = comedi_alloc_subdevices(dev, 3); if (ret) return ret; @@ -746,6 +784,16 @@ static int waveform_common_attach(struct comedi_device *dev, for (i = 0; i < s->n_chan; i++) devpriv->ao_loopbacks[i] = s->maxdata / 2; + s = &dev->subdevices[2]; + /* digital input/output subdevice */ + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + s->n_chan = 32; + s->maxdata = 1; + s->range_table = &range_digital; + s->insn_bits = waveform_dio_insn_bits; + s->insn_config = waveform_dio_insn_config; + devpriv->dev = dev; timer_setup(&devpriv->ai_timer, waveform_ai_timer, 0); timer_setup(&devpriv->ao_timer, waveform_ao_timer, 0); diff --git a/drivers/comedi/drivers/dt9812.c b/drivers/comedi/drivers/dt9812.c index b37b9d8eca0d..2541f75aff60 100644 --- a/drivers/comedi/drivers/dt9812.c +++ b/drivers/comedi/drivers/dt9812.c @@ -329,7 +329,7 @@ static int dt9812_write_multiple_registers(struct comedi_device *dev, int i, count; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -358,7 +358,7 @@ static int dt9812_rmw_multiple_registers(struct comedi_device *dev, int i, count; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/comedi/drivers/mite.c b/drivers/comedi/drivers/mite.c index 88f3cd6f54f1..e93150d6dc57 100644 --- a/drivers/comedi/drivers/mite.c +++ b/drivers/comedi/drivers/mite.c @@ -749,7 +749,7 @@ struct mite_ring *mite_alloc_ring(struct mite *mite) { struct mite_ring *ring; - ring = kmalloc(sizeof(*ring), GFP_KERNEL); + ring = kmalloc_obj(*ring); if (!ring) return NULL; ring->hw_dev = get_device(&mite->pcidev->dev); @@ -879,7 +879,7 @@ struct mite *mite_attach(struct comedi_device *dev, bool use_win1) unsigned int i; int ret; - mite = kzalloc(sizeof(*mite), GFP_KERNEL); + mite = kzalloc_obj(*mite); if (!mite) return NULL; diff --git a/drivers/comedi/drivers/ni_670x.c b/drivers/comedi/drivers/ni_670x.c index 563a9c790f12..9455c2abcc24 100644 --- a/drivers/comedi/drivers/ni_670x.c +++ b/drivers/comedi/drivers/ni_670x.c @@ -198,9 +198,7 @@ static int ni_670x_auto_attach(struct comedi_device *dev, if (s->n_chan == 32) { const struct comedi_lrange **range_table_list; - range_table_list = kmalloc_array(32, - sizeof(*range_table_list), - GFP_KERNEL); + range_table_list = kmalloc_objs(*range_table_list, 32); if (!range_table_list) return -ENOMEM; s->range_table_list = range_table_list; diff --git a/drivers/comedi/drivers/ni_tio.c b/drivers/comedi/drivers/ni_tio.c index da6826d77e60..519359a870a7 100644 --- a/drivers/comedi/drivers/ni_tio.c +++ b/drivers/comedi/drivers/ni_tio.c @@ -1778,7 +1778,7 @@ ni_gpct_device_construct(struct comedi_device *dev, if (num_counters == 0 || counters_per_chip == 0) return NULL; - counter_dev = kzalloc(sizeof(*counter_dev), GFP_KERNEL); + counter_dev = kzalloc_obj(*counter_dev); if (!counter_dev) return NULL; @@ -1793,10 +1793,9 @@ ni_gpct_device_construct(struct comedi_device *dev, counter_dev->num_counters = num_counters; counter_dev->num_chips = DIV_ROUND_UP(num_counters, counters_per_chip); - counter_dev->counters = kcalloc(num_counters, sizeof(*counter), - GFP_KERNEL); - counter_dev->regs = kcalloc(counter_dev->num_chips, - sizeof(*counter_dev->regs), GFP_KERNEL); + counter_dev->counters = kzalloc_objs(*counter, num_counters); + counter_dev->regs = kzalloc_objs(*counter_dev->regs, + counter_dev->num_chips); if (!counter_dev->regs || !counter_dev->counters) { kfree(counter_dev->regs); kfree(counter_dev->counters); diff --git a/drivers/comedi/drivers/usbduxsigma.c b/drivers/comedi/drivers/usbduxsigma.c index 3f215ae228b2..361b76d106ae 100644 --- a/drivers/comedi/drivers/usbduxsigma.c +++ b/drivers/comedi/drivers/usbduxsigma.c @@ -1336,8 +1336,8 @@ static int usbduxsigma_alloc_usb_buffers(struct comedi_device *dev) devpriv->dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); devpriv->in_buf = kzalloc(SIZEINBUF, GFP_KERNEL); devpriv->insn_buf = kzalloc(SIZEINSNBUF, GFP_KERNEL); - devpriv->ai_urbs = kcalloc(devpriv->n_ai_urbs, sizeof(urb), GFP_KERNEL); - devpriv->ao_urbs = kcalloc(devpriv->n_ao_urbs, sizeof(urb), GFP_KERNEL); + devpriv->ai_urbs = kzalloc_objs(urb, devpriv->n_ai_urbs); + devpriv->ao_urbs = kzalloc_objs(urb, devpriv->n_ao_urbs); if (!devpriv->dux_commands || !devpriv->in_buf || !devpriv->insn_buf || !devpriv->ai_urbs || !devpriv->ao_urbs) return -ENOMEM; diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 44b19e696176..0056ab81fbc3 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -429,8 +429,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, if (nsp->sk) { sk = nsp->sk; if (sk->sk_user_data == NULL) { - sk->sk_user_data = kzalloc(sizeof(struct proc_input), - GFP_KERNEL); + sk->sk_user_data = kzalloc_obj(struct proc_input); if (sk->sk_user_data == NULL) { err = ENOMEM; goto out; diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c index 996f025eb63c..2573b3000633 100644 --- a/drivers/connector/cn_queue.c +++ b/drivers/connector/cn_queue.c @@ -25,7 +25,7 @@ cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name, { struct cn_callback_entry *cbq; - cbq = kzalloc(sizeof(*cbq), GFP_KERNEL); + cbq = kzalloc_obj(*cbq); if (!cbq) { pr_err("Failed to create new callback queue.\n"); return NULL; @@ -113,7 +113,7 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls) { struct cn_queue_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/drivers/counter/counter-chrdev.c b/drivers/counter/counter-chrdev.c index 23fdf0caf712..61451ba74ca1 100644 --- a/drivers/counter/counter-chrdev.c +++ b/drivers/counter/counter-chrdev.c @@ -152,7 +152,7 @@ static int counter_set_event_node(struct counter_device *const counter, /* If event is not already in the list */ if (&event_node->l == &counter->next_events_list) { /* Allocate new event node */ - event_node = kmalloc(sizeof(*event_node), GFP_KERNEL); + event_node = kmalloc_obj(*event_node); if (!event_node) return -ENOMEM; @@ -172,7 +172,7 @@ static int counter_set_event_node(struct counter_device *const counter, } /* Allocate component node */ - comp_node = kmalloc(sizeof(*comp_node), GFP_KERNEL); + comp_node = kmalloc_obj(*comp_node); if (!comp_node) { err = -ENOMEM; goto exit_free_event_node; diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index e73a66785d69..e7eff6c2f092 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -700,7 +700,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) return blacklisted; #endif - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -798,8 +798,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) goto err_unreg; } - freq_table = kcalloc(perf->state_count + 1, sizeof(*freq_table), - GFP_KERNEL); + freq_table = kzalloc_objs(*freq_table, perf->state_count + 1); if (!freq_table) { result = -ENOMEM; goto err_unreg; diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c index ec9f38b219de..5aa9fcd80cf5 100644 --- a/drivers/cpufreq/amd-pstate.c +++ b/drivers/cpufreq/amd-pstate.c @@ -993,7 +993,7 @@ static int amd_pstate_cpu_init(struct cpufreq_policy *policy) if (!dev) return -ENODEV; - cpudata = kzalloc(sizeof(*cpudata), GFP_KERNEL); + cpudata = kzalloc_obj(*cpudata); if (!cpudata) return -ENOMEM; @@ -1478,7 +1478,7 @@ static int amd_pstate_epp_cpu_init(struct cpufreq_policy *policy) if (!dev) return -ENODEV; - cpudata = kzalloc(sizeof(*cpudata), GFP_KERNEL); + cpudata = kzalloc_obj(*cpudata); if (!cpudata) return -ENOMEM; diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c index b1d29b7af232..9396034167e5 100644 --- a/drivers/cpufreq/apple-soc-cpufreq.c +++ b/drivers/cpufreq/apple-soc-cpufreq.c @@ -276,7 +276,7 @@ static int apple_soc_cpufreq_init(struct cpufreq_policy *policy) goto out_free_opp; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto out_free_opp; diff --git a/drivers/cpufreq/armada-37xx-cpufreq.c b/drivers/cpufreq/armada-37xx-cpufreq.c index 0efe403a5980..1ec54fc4c2ba 100644 --- a/drivers/cpufreq/armada-37xx-cpufreq.c +++ b/drivers/cpufreq/armada-37xx-cpufreq.c @@ -467,8 +467,7 @@ static int __init armada37xx_cpufreq_driver_init(void) return -EINVAL; } - armada37xx_cpufreq_state = kmalloc(sizeof(*armada37xx_cpufreq_state), - GFP_KERNEL); + armada37xx_cpufreq_state = kmalloc_obj(*armada37xx_cpufreq_state); if (!armada37xx_cpufreq_state) { clk_put(clk); return -ENOMEM; diff --git a/drivers/cpufreq/armada-8k-cpufreq.c b/drivers/cpufreq/armada-8k-cpufreq.c index d96c1718f7f8..9d55398f3797 100644 --- a/drivers/cpufreq/armada-8k-cpufreq.c +++ b/drivers/cpufreq/armada-8k-cpufreq.c @@ -143,7 +143,7 @@ static int __init armada_8k_cpufreq_init(void) of_node_put(node); nb_cpus = num_possible_cpus(); - freq_tables = kcalloc(nb_cpus, sizeof(*freq_tables), GFP_KERNEL); + freq_tables = kzalloc_objs(*freq_tables, nb_cpus); if (!freq_tables) return -ENOMEM; cpumask_copy(&cpus, cpu_possible_mask); diff --git a/drivers/cpufreq/bmips-cpufreq.c b/drivers/cpufreq/bmips-cpufreq.c index 36051880640b..a8e35bc75fb2 100644 --- a/drivers/cpufreq/bmips-cpufreq.c +++ b/drivers/cpufreq/bmips-cpufreq.c @@ -71,7 +71,7 @@ bmips_cpufreq_get_freq_table(const struct cpufreq_policy *policy) cpu_freq = htp_freq_to_cpu_freq(priv->clk_mult); - table = kmalloc_array(priv->max_freqs + 1, sizeof(*table), GFP_KERNEL); + table = kmalloc_objs(*table, priv->max_freqs + 1); if (!table) return ERR_PTR(-ENOMEM); diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 7e8042efedd1..011f35cb47b9 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -575,7 +575,7 @@ static struct cppc_cpudata *cppc_cpufreq_get_cpu_data(unsigned int cpu) struct cppc_cpudata *cpu_data; int ret; - cpu_data = kzalloc(sizeof(struct cppc_cpudata), GFP_KERNEL); + cpu_data = kzalloc_obj(struct cppc_cpudata); if (!cpu_data) goto out; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index a7a69f4d7675..277884d91913 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1263,7 +1263,7 @@ static struct cpufreq_policy *cpufreq_policy_alloc(unsigned int cpu) if (!dev) return NULL; - policy = kzalloc(sizeof(*policy), GFP_KERNEL); + policy = kzalloc_obj(*policy); if (!policy) return NULL; diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index cce6a8d113e1..e0e847764511 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -273,7 +273,7 @@ static struct policy_dbs_info *cs_alloc(void) { struct cs_policy_dbs_info *dbs_info; - dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL); + dbs_info = kzalloc_obj(*dbs_info); return dbs_info ? &dbs_info->policy_dbs : NULL; } @@ -286,7 +286,7 @@ static int cs_init(struct dbs_data *dbs_data) { struct cs_dbs_tuners *tuners; - tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); + tuners = kzalloc_obj(*tuners); if (!tuners) return -ENOMEM; diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index 1a7fcaf39cc9..36eb7aee4bcd 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c @@ -429,7 +429,7 @@ int cpufreq_dbs_governor_init(struct cpufreq_policy *policy) goto out; } - dbs_data = kzalloc(sizeof(*dbs_data), GFP_KERNEL); + dbs_data = kzalloc_obj(*dbs_data); if (!dbs_data) { ret = -ENOMEM; goto free_policy_dbs_info; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index bb7db82930e4..9942dbb38dae 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -322,7 +322,7 @@ static struct policy_dbs_info *od_alloc(void) { struct od_policy_dbs_info *dbs_info; - dbs_info = kzalloc(sizeof(*dbs_info), GFP_KERNEL); + dbs_info = kzalloc_obj(*dbs_info); return dbs_info ? &dbs_info->policy_dbs : NULL; } @@ -335,7 +335,7 @@ static int od_init(struct dbs_data *dbs_data) { struct od_dbs_tuners *tuners; - tuners = kzalloc(sizeof(*tuners), GFP_KERNEL); + tuners = kzalloc_obj(*tuners); if (!tuners) return -ENOMEM; diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c index 40a9ff18da06..670a10c3ecfa 100644 --- a/drivers/cpufreq/cpufreq_stats.c +++ b/drivers/cpufreq/cpufreq_stats.c @@ -222,7 +222,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy) if (policy->stats) return; - stats = kzalloc(sizeof(*stats), GFP_KERNEL); + stats = kzalloc_obj(*stats); if (!stats) return; diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 4bd62e6c5c51..d738d31995f9 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -58,7 +58,7 @@ static int cpufreq_userspace_policy_init(struct cpufreq_policy *policy) { struct userspace_policy *userspace; - userspace = kzalloc(sizeof(*userspace), GFP_KERNEL); + userspace = kzalloc_obj(*userspace); if (!userspace) return -ENOMEM; diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 320a0af2266a..eb5a9209d828 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -55,8 +55,7 @@ static struct acpi_processor_performance *eps_acpi_cpu_perf; /* Minimum necessary to get acpi_processor_get_bios_limit() working */ static int eps_acpi_init(void) { - eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf), - GFP_KERNEL); + eps_acpi_cpu_perf = kzalloc_obj(*eps_acpi_cpu_perf); if (!eps_acpi_cpu_perf) return -ENOMEM; @@ -321,8 +320,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) states = 2; /* Allocate private data and frequency table for current cpu */ - centaur = kzalloc(struct_size(centaur, freq_table, states + 1), - GFP_KERNEL); + centaur = kzalloc_flex(*centaur, freq_table, states + 1); if (!centaur) return -ENOMEM; eps_cpu[0] = centaur; diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 75b3ef7ec679..d269a4f26f98 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -458,7 +458,7 @@ static int __init cpufreq_gx_init(void) pr_debug("geode suspend modulation available.\n"); - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (params == NULL) return -ENOMEM; diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 1625ec2d0d06..11c58af41900 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -1476,13 +1476,13 @@ static void __intel_pstate_update_max_freq(struct cpufreq_policy *policy, refresh_frequency_limits(policy); } -static bool intel_pstate_update_max_freq(struct cpudata *cpudata) +static bool intel_pstate_update_max_freq(int cpu) { - struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpudata->cpu); + struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu); if (!policy) return false; - __intel_pstate_update_max_freq(policy, cpudata); + __intel_pstate_update_max_freq(policy, all_cpu_data[cpu]); return true; } @@ -1501,7 +1501,7 @@ static void intel_pstate_update_limits_for_all(void) int cpu; for_each_possible_cpu(cpu) - intel_pstate_update_max_freq(all_cpu_data[cpu]); + intel_pstate_update_max_freq(cpu); mutex_lock(&hybrid_capacity_lock); @@ -1647,8 +1647,8 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type) { struct cpudata *cpudata = all_cpu_data[cpu]; - unsigned int freq = cpudata->pstate.turbo_freq; struct freq_qos_request *req; + unsigned int freq; struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu); if (!policy) @@ -1661,6 +1661,8 @@ static void update_cpu_qos_request(int cpu, enum freq_qos_req_type type) if (hwp_active) intel_pstate_get_hwp_cap(cpudata); + freq = cpudata->pstate.turbo_freq; + if (type == FREQ_QOS_MIN) { freq = DIV_ROUND_UP(freq * global.min_perf_pct, 100); } else { @@ -1908,7 +1910,7 @@ static void intel_pstate_notify_work(struct work_struct *work) struct cpudata *cpudata = container_of(to_delayed_work(work), struct cpudata, hwp_notify_work); - if (intel_pstate_update_max_freq(cpudata)) { + if (intel_pstate_update_max_freq(cpudata->cpu)) { /* * The driver will not be unregistered while this function is * running, so update the capacity without acquiring the driver @@ -2745,7 +2747,7 @@ static int intel_pstate_init_cpu(unsigned int cpunum) cpu = all_cpu_data[cpunum]; if (!cpu) { - cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); + cpu = kzalloc_obj(*cpu); if (!cpu) return -ENOMEM; @@ -3301,7 +3303,7 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy) /* This reflects the intel_pstate_get_cpu_pstates() setting. */ policy->cur = policy->cpuinfo.min_freq; - req = kcalloc(2, sizeof(*req), GFP_KERNEL); + req = kzalloc_objs(*req, 2); if (!req) { ret = -ENOMEM; goto pstate_exit; diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index 49e76b44468a..a18d1d11725f 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -475,8 +475,7 @@ static int longhaul_get_ranges(void) return -EINVAL; } - longhaul_table = kcalloc(numscales + 1, sizeof(*longhaul_table), - GFP_KERNEL); + longhaul_table = kzalloc_objs(*longhaul_table, numscales + 1); if (!longhaul_table) return -ENOMEM; diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 31039330a3ba..6b7caf4ae20d 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -304,7 +304,7 @@ static int powernow_acpi_init(void) goto err0; } - acpi_processor_perf = kzalloc(sizeof(*acpi_processor_perf), GFP_KERNEL); + acpi_processor_perf = kzalloc_obj(*acpi_processor_perf); if (!acpi_processor_perf) { retval = -ENOMEM; goto err0; diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index f7512b4e923e..4d77eef53fe0 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1029,7 +1029,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) if (rc) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 7d9a5f656de8..4a6f4d9043e9 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -323,7 +323,7 @@ static int init_powernv_pstates(void) powernv_freqs[i].frequency = freq * 1000; /* kHz */ powernv_freqs[i].driver_data = id & 0xFF; - revmap_data = kmalloc(sizeof(*revmap_data), GFP_KERNEL); + revmap_data = kmalloc_obj(*revmap_data); if (!revmap_data) { rc = -ENOMEM; goto out; @@ -857,7 +857,7 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) return 0; /* Initialise Gpstate ramp-down timer only on POWER8 */ - gpstates = kzalloc(sizeof(*gpstates), GFP_KERNEL); + gpstates = kzalloc_obj(*gpstates); if (!gpstates) return -ENOMEM; @@ -1053,7 +1053,7 @@ static int init_chip_info(void) return -ENOMEM; /* Allocate a chip cpu mask large enough to fit mask for all chips */ - chip_cpu_mask = kcalloc(MAX_NR_CHIPS, sizeof(cpumask_t), GFP_KERNEL); + chip_cpu_mask = kzalloc_objs(cpumask_t, MAX_NR_CHIPS); if (!chip_cpu_mask) { ret = -ENOMEM; goto free_and_return; @@ -1069,7 +1069,7 @@ static int init_chip_info(void) cpumask_set_cpu(cpu, &chip_cpu_mask[nr_chips-1]); } - chips = kcalloc(nr_chips, sizeof(struct chip), GFP_KERNEL); + chips = kzalloc_objs(struct chip, nr_chips); if (!chips) { ret = -ENOMEM; goto out_free_chip_cpu_mask; diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index 4afa48d172db..50ff3b6a6900 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -110,7 +110,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table; int i; - table = kcalloc(num + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, num + 1); if (table == NULL) return -ENOMEM; diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c index 8422704a3b10..ea9a20d27b8f 100644 --- a/drivers/cpufreq/qcom-cpufreq-hw.c +++ b/drivers/cpufreq/qcom-cpufreq-hw.c @@ -211,7 +211,7 @@ static int qcom_cpufreq_hw_read_lut(struct device *cpu_dev, struct qcom_cpufreq_data *drv_data = policy->driver_data; const struct qcom_cpufreq_soc_data *soc_data = qcom_cpufreq.soc_data; - table = kcalloc(LUT_MAX_ENTRIES + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, LUT_MAX_ENTRIES + 1); if (!table) return -ENOMEM; diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 8d1f5ac59132..42edb41ad459 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -168,7 +168,7 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) if (!np) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto err_np; @@ -181,11 +181,11 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) hwclk = __clk_get_hw(policy->clk); count = clk_hw_get_num_parents(hwclk); - data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL); + data->pclk = kzalloc_objs(struct clk *, count); if (!data->pclk) goto err_nomem2; - table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, count + 1); if (!table) goto err_pclk; diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index c7a3b038385b..4edb4f7a8aa9 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -214,7 +214,7 @@ static int scmi_cpufreq_init(struct cpufreq_policy *policy) if (domain < 0) return domain; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index e530345baddf..09e29b2a6d8e 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -128,7 +128,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy) goto out_free_opp; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto out_free_opp; diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 15899dd77c08..a68706406b88 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -323,8 +323,7 @@ static int __init us2e_freq_init(void) impl = ((ver >> 32) & 0xffff); if (manuf == 0x17 && impl == 0x13) { - us2e_freq_table = kcalloc(NR_CPUS, sizeof(*us2e_freq_table), - GFP_KERNEL); + us2e_freq_table = kzalloc_objs(*us2e_freq_table, NR_CPUS); if (!us2e_freq_table) return -ENOMEM; diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index de50a2f3b124..5a8ad86018e8 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -171,8 +171,7 @@ static int __init us3_freq_init(void) impl == CHEETAH_PLUS_IMPL || impl == JAGUAR_IMPL || impl == PANTHER_IMPL)) { - us3_freq_table = kcalloc(NR_CPUS, sizeof(*us3_freq_table), - GFP_KERNEL); + us3_freq_table = kzalloc_objs(*us3_freq_table, NR_CPUS); if (!us3_freq_table) return -ENOMEM; diff --git a/drivers/cpufreq/spear-cpufreq.c b/drivers/cpufreq/spear-cpufreq.c index 2a1550e1aa21..81a0780b2ebf 100644 --- a/drivers/cpufreq/spear-cpufreq.c +++ b/drivers/cpufreq/spear-cpufreq.c @@ -191,7 +191,7 @@ static int spear_cpufreq_probe(struct platform_device *pdev) goto out_put_node; } - freq_tbl = kcalloc(cnt + 1, sizeof(*freq_tbl), GFP_KERNEL); + freq_tbl = kzalloc_objs(*freq_tbl, cnt + 1); if (!freq_tbl) { ret = -ENOMEM; goto out_put_node; diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 4fffc8e83692..9261d148a165 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -244,8 +244,7 @@ static int sun50i_cpufreq_nvmem_probe(struct platform_device *pdev) int speed; int ret; - opp_tokens = kcalloc(num_possible_cpus(), sizeof(*opp_tokens), - GFP_KERNEL); + opp_tokens = kzalloc_objs(*opp_tokens, num_possible_cpus()); if (!opp_tokens) return -ENOMEM; diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index 34ed943c5f34..4fa6894f6371 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -135,7 +135,7 @@ static int tegra_cpufreq_init_cpufreq_table(struct cpufreq_policy *policy, dev_pm_opp_disable(cpu_dev, rate); } - freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_KERNEL); + freq_table = kzalloc_objs(*freq_table, (max_opps + 1)); if (!freq_table) return -ENOMEM; diff --git a/drivers/cpufreq/tegra194-cpufreq.c b/drivers/cpufreq/tegra194-cpufreq.c index 695599e1001f..7a41cfc71a46 100644 --- a/drivers/cpufreq/tegra194-cpufreq.c +++ b/drivers/cpufreq/tegra194-cpufreq.c @@ -463,7 +463,7 @@ static int tegra_cpufreq_init_cpufreq_table(struct cpufreq_policy *policy, return ret; } - freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_KERNEL); + freq_table = kzalloc_objs(*freq_table, (max_opps + 1)); if (!freq_table) return -ENOMEM; diff --git a/drivers/cpufreq/vexpress-spc-cpufreq.c b/drivers/cpufreq/vexpress-spc-cpufreq.c index 65fea47b82e6..8e4e29138464 100644 --- a/drivers/cpufreq/vexpress-spc-cpufreq.c +++ b/drivers/cpufreq/vexpress-spc-cpufreq.c @@ -252,7 +252,7 @@ static int merge_cluster_tables(void) for (i = 0; i < MAX_CLUSTERS; i++) count += get_table_count(freq_table[i]); - table = kcalloc(count, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, count); if (!table) return -ENOMEM; diff --git a/drivers/cpufreq/virtual-cpufreq.c b/drivers/cpufreq/virtual-cpufreq.c index 6ffa16d239b2..4159f31349b1 100644 --- a/drivers/cpufreq/virtual-cpufreq.c +++ b/drivers/cpufreq/virtual-cpufreq.c @@ -171,7 +171,7 @@ static int virt_cpufreq_get_freq_info(struct cpufreq_policy *policy) return 0; } - table = kcalloc(num_perftbl_entries + 1, sizeof(*table), GFP_KERNEL); + table = kzalloc_objs(*table, num_perftbl_entries + 1); if (!table) return -ENOMEM; diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index bb8761c8a42e..fb91a9e0e3c2 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c @@ -651,7 +651,7 @@ int cpuidle_coupled_register_device(struct cpuidle_device *dev) } /* No existing coupled info found, create a new one */ - coupled = kzalloc(sizeof(struct cpuidle_coupled), GFP_KERNEL); + coupled = kzalloc_obj(struct cpuidle_coupled); if (!coupled) return -ENOMEM; diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index 37c41209eaf9..b9e4ad7d43a3 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c @@ -55,7 +55,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) if (!pd) goto out; - pd_provider = kzalloc(sizeof(*pd_provider), GFP_KERNEL); + pd_provider = kzalloc_obj(*pd_provider); if (!pd_provider) goto free_pd; diff --git a/drivers/cpuidle/cpuidle-riscv-sbi.c b/drivers/cpuidle/cpuidle-riscv-sbi.c index 19be6475d356..a13e90bb43bd 100644 --- a/drivers/cpuidle/cpuidle-riscv-sbi.c +++ b/drivers/cpuidle/cpuidle-riscv-sbi.c @@ -380,7 +380,7 @@ static int sbi_pd_init(struct device_node *np) if (!pd) goto out; - pd_provider = kzalloc(sizeof(*pd_provider), GFP_KERNEL); + pd_provider = kzalloc_obj(*pd_provider); if (!pd_provider) goto free_pd; diff --git a/drivers/cpuidle/dt_idle_genpd.c b/drivers/cpuidle/dt_idle_genpd.c index 203e9b754aea..d292975cc468 100644 --- a/drivers/cpuidle/dt_idle_genpd.c +++ b/drivers/cpuidle/dt_idle_genpd.c @@ -95,7 +95,7 @@ struct generic_pm_domain *dt_idle_pd_alloc(struct device_node *np, struct genpd_power_state *states = NULL; int ret, state_count = 0; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) goto out; diff --git a/drivers/cpuidle/governors/haltpoll.c b/drivers/cpuidle/governors/haltpoll.c index 663b7f164d20..b367d10279c8 100644 --- a/drivers/cpuidle/governors/haltpoll.c +++ b/drivers/cpuidle/governors/haltpoll.c @@ -50,9 +50,7 @@ static int haltpoll_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, bool *stop_tick) { - s64 latency_req = cpuidle_governor_latency_req(dev->cpu); - - if (!drv->state_count || latency_req == 0) { + if (cpuidle_governor_latency_req(dev->cpu) == 0) { *stop_tick = false; return 0; } diff --git a/drivers/cpuidle/governors/menu.c b/drivers/cpuidle/governors/menu.c index c6052055ba0f..899ff16ff1fe 100644 --- a/drivers/cpuidle/governors/menu.c +++ b/drivers/cpuidle/governors/menu.c @@ -281,7 +281,7 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, data->bucket = BUCKETS - 1; } - if (drv->state_count <= 1 || latency_req == 0 || + if (latency_req == 0 || ((data->next_timer_ns < drv->states[1].target_residency_ns || latency_req < drv->states[1].exit_latency_ns) && !dev->states_usage[0].disable)) { diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c index 80f3ba942a06..bec0142377b8 100644 --- a/drivers/cpuidle/governors/teo.c +++ b/drivers/cpuidle/governors/teo.c @@ -338,12 +338,6 @@ static int teo_select(struct cpuidle_driver *drv, struct cpuidle_device *dev, */ cpu_data->sleep_length_ns = KTIME_MAX; - /* Check if there is any choice in the first place. */ - if (drv->state_count < 2) { - idx = 0; - goto out_tick; - } - if (!dev->states_usage[0].disable) idx = 0; diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index 61de64817604..b81d22479234 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -482,7 +482,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) /* state statistics */ for (i = 0; i < drv->state_count; i++) { - kobj = kzalloc(sizeof(struct cpuidle_state_kobj), GFP_KERNEL); + kobj = kzalloc_obj(struct cpuidle_state_kobj); if (!kobj) { ret = -ENOMEM; goto error_state; @@ -618,7 +618,7 @@ static int cpuidle_add_driver_sysfs(struct cpuidle_device *dev) struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev); int ret; - kdrv = kzalloc(sizeof(*kdrv), GFP_KERNEL); + kdrv = kzalloc_obj(*kdrv); if (!kdrv) return -ENOMEM; @@ -712,7 +712,7 @@ int cpuidle_add_sysfs(struct cpuidle_device *dev) if (!cpu_dev) return -ENODEV; - kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); + kdev = kzalloc_obj(*kdev); if (!kdev) return -ENOMEM; kdev->dev = dev; diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index 8cdc66d520c9..b7b6c97d2147 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c @@ -173,8 +173,7 @@ static u32 crypto4xx_build_pdr(struct crypto4xx_device *dev) if (!dev->pdr) return -ENOMEM; - dev->pdr_uinfo = kcalloc(PPC4XX_NUM_PD, sizeof(struct pd_uinfo), - GFP_KERNEL); + dev->pdr_uinfo = kzalloc_objs(struct pd_uinfo, PPC4XX_NUM_PD); if (!dev->pdr_uinfo) { dma_free_coherent(dev->core_dev->device, sizeof(struct ce_pd) * PPC4XX_NUM_PD, @@ -974,7 +973,7 @@ static int crypto4xx_register_alg(struct crypto4xx_device *sec_dev, int rc = 0; for (i = 0; i < array_size; i++) { - alg = kzalloc(sizeof(struct crypto4xx_alg), GFP_KERNEL); + alg = kzalloc_obj(struct crypto4xx_alg); if (!alg) return -ENOMEM; diff --git a/drivers/crypto/amcc/crypto4xx_trng.c b/drivers/crypto/amcc/crypto4xx_trng.c index f10a87e541ed..cfd66b779ce1 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.c +++ b/drivers/crypto/amcc/crypto4xx_trng.c @@ -87,7 +87,7 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) if (!dev->trng_base) goto err_out; - rng = kzalloc(sizeof(*rng), GFP_KERNEL); + rng = kzalloc_obj(*rng); if (!rng) goto err_out; diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c index 0d48e64d28b1..b6a77c8d439c 100644 --- a/drivers/crypto/atmel-ecc.c +++ b/drivers/crypto/atmel-ecc.c @@ -99,7 +99,7 @@ static int atmel_ecdh_set_secret(struct crypto_kpp *tfm, const void *buf, return crypto_kpp_set_secret(ctx->fallback, buf, len); } - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kmalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -182,7 +182,7 @@ static int atmel_ecdh_compute_shared_secret(struct kpp_request *req) gfp = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL : GFP_ATOMIC; - work_data = kmalloc(sizeof(*work_data), gfp); + work_data = kmalloc_obj(*work_data, gfp); if (!work_data) return -ENOMEM; diff --git a/drivers/crypto/atmel-i2c.c b/drivers/crypto/atmel-i2c.c index 9688d116d07e..da3cd986b1eb 100644 --- a/drivers/crypto/atmel-i2c.c +++ b/drivers/crypto/atmel-i2c.c @@ -321,7 +321,7 @@ static int device_sanity_check(struct i2c_client *client) struct atmel_i2c_cmd *cmd; int ret; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kmalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index b02a71061708..1f1341a16c42 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c @@ -2207,7 +2207,7 @@ struct atmel_sha_authenc_ctx *atmel_sha_authenc_spawn(unsigned long mode) tctx->start = atmel_sha_authenc_start; tctx->flags = mode; - auth = kzalloc(sizeof(*auth), GFP_KERNEL); + auth = kzalloc_obj(*auth); if (!auth) { err = -ENOMEM; goto err_free_ahash; diff --git a/drivers/crypto/atmel-sha204a.c b/drivers/crypto/atmel-sha204a.c index 0fcf4a39de27..98d1023007e3 100644 --- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -51,10 +51,11 @@ static int atmel_sha204a_rng_read_nonblocking(struct hwrng *rng, void *data, memcpy(data, &work_data->cmd.data, max); rng->priv = 0; } else { - work_data = kmalloc(sizeof(*work_data), GFP_ATOMIC); - if (!work_data) + work_data = kmalloc_obj(*work_data, GFP_ATOMIC); + if (!work_data) { + atomic_dec(&i2c_priv->tfm_count); return -ENOMEM; - + } work_data->ctx = i2c_priv; work_data->client = i2c_priv->client; diff --git a/drivers/crypto/bcm/cipher.c b/drivers/crypto/bcm/cipher.c index 6b80d033648e..2bce15dc0aa8 100644 --- a/drivers/crypto/bcm/cipher.c +++ b/drivers/crypto/bcm/cipher.c @@ -141,8 +141,7 @@ spu_skcipher_rx_sg_create(struct brcm_message *mssg, struct iproc_ctx_s *ctx = rctx->ctx; u32 datalen; /* Number of bytes of response data expected */ - mssg->spu.dst = kmalloc_array(rx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.dst = kmalloc_objs(struct scatterlist, rx_frag_num, rctx->gfp); if (!mssg->spu.dst) return -ENOMEM; @@ -205,8 +204,7 @@ spu_skcipher_tx_sg_create(struct brcm_message *mssg, u32 datalen; /* Number of bytes of response data expected */ u32 stat_len; - mssg->spu.src = kmalloc_array(tx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.src = kmalloc_objs(struct scatterlist, tx_frag_num, rctx->gfp); if (unlikely(!mssg->spu.src)) return -ENOMEM; @@ -532,8 +530,7 @@ spu_ahash_rx_sg_create(struct brcm_message *mssg, struct scatterlist *sg; /* used to build sgs in mbox message */ struct iproc_ctx_s *ctx = rctx->ctx; - mssg->spu.dst = kmalloc_array(rx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.dst = kmalloc_objs(struct scatterlist, rx_frag_num, rctx->gfp); if (!mssg->spu.dst) return -ENOMEM; @@ -587,8 +584,7 @@ spu_ahash_tx_sg_create(struct brcm_message *mssg, u32 datalen; /* Number of bytes of response data expected */ u32 stat_len; - mssg->spu.src = kmalloc_array(tx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.src = kmalloc_objs(struct scatterlist, tx_frag_num, rctx->gfp); if (!mssg->spu.src) return -ENOMEM; @@ -1077,8 +1073,7 @@ static int spu_aead_rx_sg_create(struct brcm_message *mssg, /* have to catch gcm pad in separate buffer */ rx_frag_num++; - mssg->spu.dst = kmalloc_array(rx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.dst = kmalloc_objs(struct scatterlist, rx_frag_num, rctx->gfp); if (!mssg->spu.dst) return -ENOMEM; @@ -1179,8 +1174,7 @@ static int spu_aead_tx_sg_create(struct brcm_message *mssg, u32 assoc_offset = 0; u32 stat_len; - mssg->spu.src = kmalloc_array(tx_frag_num, sizeof(struct scatterlist), - rctx->gfp); + mssg->spu.src = kmalloc_objs(struct scatterlist, tx_frag_num, rctx->gfp); if (!mssg->spu.src) return -ENOMEM; diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index c6117c23eb25..167372936ca7 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c @@ -3224,14 +3224,14 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, u32 *keylen, u8 *key, int ret = -ENOMEM; struct dpaa2_fl_entry *in_fle, *out_fle; - req_ctx = kzalloc(sizeof(*req_ctx), GFP_KERNEL); + req_ctx = kzalloc_obj(*req_ctx); if (!req_ctx) return -ENOMEM; in_fle = &req_ctx->fd_flt[1]; out_fle = &req_ctx->fd_flt[0]; - flc = kzalloc(sizeof(*flc), GFP_KERNEL); + flc = kzalloc_obj(*flc); if (!flc) goto err_flc; @@ -4635,7 +4635,7 @@ static struct caam_hash_alg *caam_hash_alloc(struct device *dev, struct ahash_alg *halg; struct crypto_alg *alg; - t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); + t_alg = kzalloc_obj(*t_alg); if (!t_alg) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c index 25c02e267258..628c43a7efc4 100644 --- a/drivers/crypto/caam/caamhash.c +++ b/drivers/crypto/caam/caamhash.c @@ -709,7 +709,7 @@ static struct ahash_edesc *ahash_edesc_alloc(struct ahash_request *req, struct ahash_edesc *edesc; sg_num = pad_sg_nents(sg_num); - edesc = kzalloc(struct_size(edesc, sec4_sg, sg_num), flags); + edesc = kzalloc_flex(*edesc, sec4_sg, sg_num, flags); if (!edesc) return NULL; @@ -1904,7 +1904,7 @@ caam_hash_alloc(struct caam_hash_template *template, struct ahash_alg *halg; struct crypto_alg *alg; - t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL); + t_alg = kzalloc_obj(*t_alg); if (!t_alg) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/caam/qi.c b/drivers/crypto/caam/qi.c index 1e731ed8702b..c4bfe8e4aa2c 100644 --- a/drivers/crypto/caam/qi.c +++ b/drivers/crypto/caam/qi.c @@ -181,7 +181,7 @@ static struct qman_fq *create_caam_req_fq(struct device *qidev, struct qman_fq *req_fq; struct qm_mcc_initfq opts; - req_fq = kzalloc(sizeof(*req_fq), GFP_ATOMIC); + req_fq = kzalloc_obj(*req_fq, GFP_ATOMIC); if (!req_fq) return ERR_PTR(-ENOMEM); @@ -416,7 +416,7 @@ struct caam_drv_ctx *caam_drv_ctx_init(struct device *qidev, return ERR_PTR(-EINVAL); } - drv_ctx = kzalloc(sizeof(*drv_ctx), GFP_ATOMIC); + drv_ctx = kzalloc_obj(*drv_ctx, GFP_ATOMIC); if (!drv_ctx) return ERR_PTR(-ENOMEM); @@ -619,7 +619,7 @@ static int alloc_rsp_fq_cpu(struct device *qidev, unsigned int cpu) struct qman_fq *fq; int ret; - fq = kzalloc(sizeof(*fq), GFP_KERNEL); + fq = kzalloc_obj(*fq); if (!fq) return -ENOMEM; diff --git a/drivers/crypto/cavium/cpt/cptvf_main.c b/drivers/crypto/cavium/cpt/cptvf_main.c index bccd680c7f7e..2c9a2af38876 100644 --- a/drivers/crypto/cavium/cpt/cptvf_main.c +++ b/drivers/crypto/cavium/cpt/cptvf_main.c @@ -35,7 +35,7 @@ static int init_worker_threads(struct cpt_vf *cptvf) struct cptvf_wqe_info *cwqe_info; int i; - cwqe_info = kzalloc(sizeof(*cwqe_info), GFP_KERNEL); + cwqe_info = kzalloc_obj(*cwqe_info); if (!cwqe_info) return -ENOMEM; @@ -111,7 +111,7 @@ static int alloc_pending_queues(struct pending_qinfo *pqinfo, u32 qlen, pqinfo->qlen = qlen; for_each_pending_queue(pqinfo, queue, i) { - queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL); + queue->head = kzalloc_objs(*queue->head, qlen); if (!queue->head) { ret = -ENOMEM; goto pending_qfail; @@ -225,7 +225,7 @@ static int alloc_command_queues(struct cpt_vf *cptvf, queue = &cqinfo->queue[i]; INIT_HLIST_HEAD(&cqinfo->queue[i].chead); do { - curr = kzalloc(sizeof(*curr), GFP_KERNEL); + curr = kzalloc_obj(*curr); if (!curr) goto cmd_qfail; diff --git a/drivers/crypto/cavium/cpt/cptvf_reqmanager.c b/drivers/crypto/cavium/cpt/cptvf_reqmanager.c index fb59bb282455..e183b60277ff 100644 --- a/drivers/crypto/cavium/cpt/cptvf_reqmanager.c +++ b/drivers/crypto/cavium/cpt/cptvf_reqmanager.c @@ -417,7 +417,7 @@ int process_request(struct cpt_vf *cptvf, struct cpt_request_info *req) struct cpt_vq_command vq_cmd; union cpt_inst_s cptinst; - info = kzalloc(sizeof(*info), req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); + info = kzalloc_obj(*info, req->may_sleep ? GFP_KERNEL : GFP_ATOMIC); if (unlikely(!info)) { dev_err(&pdev->dev, "Unable to allocate memory for info_buffer\n"); return -ENOMEM; diff --git a/drivers/crypto/cavium/nitrox/nitrox_isr.c b/drivers/crypto/cavium/nitrox/nitrox_isr.c index f19e520da6d0..cf09f7451f6f 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_isr.c +++ b/drivers/crypto/cavium/nitrox/nitrox_isr.c @@ -320,7 +320,7 @@ int nitrox_register_interrupts(struct nitrox_device *ndev) } ndev->num_vecs = nr_vecs; - ndev->qvec = kcalloc(nr_vecs, sizeof(*qvec), GFP_KERNEL); + ndev->qvec = kzalloc_objs(*qvec, nr_vecs); if (!ndev->qvec) { pci_free_irq_vectors(pdev); return -ENOMEM; @@ -424,7 +424,7 @@ int nitrox_sriov_register_interupts(struct nitrox_device *ndev) return ret; } - qvec = kcalloc(NR_NON_RING_VECTORS, sizeof(*qvec), GFP_KERNEL); + qvec = kzalloc_objs(*qvec, NR_NON_RING_VECTORS); if (!qvec) { pci_disable_msix(pdev); return -ENOMEM; diff --git a/drivers/crypto/cavium/nitrox/nitrox_lib.c b/drivers/crypto/cavium/nitrox/nitrox_lib.c index 068265207ddd..d35303857476 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_lib.c +++ b/drivers/crypto/cavium/nitrox/nitrox_lib.c @@ -219,7 +219,7 @@ void *crypto_alloc_context(struct nitrox_device *ndev) void *vaddr; dma_addr_t dma; - chdr = kmalloc(sizeof(*chdr), GFP_KERNEL); + chdr = kmalloc_obj(*chdr); if (!chdr) return NULL; diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index 65114f766e7d..8664d97261fe 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c @@ -441,7 +441,7 @@ static int nitrox_probe(struct pci_dev *pdev, goto flr_fail; pci_set_master(pdev); - ndev = kzalloc(sizeof(*ndev), GFP_KERNEL); + ndev = kzalloc_obj(*ndev); if (!ndev) { err = -ENOMEM; goto ndev_fail; diff --git a/drivers/crypto/cavium/nitrox/nitrox_mbx.c b/drivers/crypto/cavium/nitrox/nitrox_mbx.c index a6a76e50ba84..944d8b882afa 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_mbx.c +++ b/drivers/crypto/cavium/nitrox/nitrox_mbx.c @@ -139,7 +139,7 @@ void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev) vfdev->ring = i; /* fill the vf mailbox data */ vfdev->msg.value = pf2vf_read_mbox(ndev, vfdev->ring); - pfwork = kzalloc(sizeof(*pfwork), GFP_ATOMIC); + pfwork = kzalloc_obj(*pfwork, GFP_ATOMIC); if (!pfwork) continue; @@ -163,7 +163,7 @@ void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev) /* fill the vf mailbox data */ vfdev->msg.value = pf2vf_read_mbox(ndev, vfdev->ring); - pfwork = kzalloc(sizeof(*pfwork), GFP_ATOMIC); + pfwork = kzalloc_obj(*pfwork, GFP_ATOMIC); if (!pfwork) continue; @@ -181,8 +181,7 @@ int nitrox_mbox_init(struct nitrox_device *ndev) struct nitrox_vfdev *vfdev; int i; - ndev->iov.vfdev = kcalloc(ndev->iov.num_vfs, - sizeof(struct nitrox_vfdev), GFP_KERNEL); + ndev->iov.vfdev = kzalloc_objs(struct nitrox_vfdev, ndev->iov.num_vfs); if (!ndev->iov.vfdev) return -ENOMEM; diff --git a/drivers/crypto/cavium/nitrox/nitrox_reqmgr.c b/drivers/crypto/cavium/nitrox/nitrox_reqmgr.c index 55c18da4a500..6a1bdae73d1a 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_reqmgr.c +++ b/drivers/crypto/cavium/nitrox/nitrox_reqmgr.c @@ -390,7 +390,7 @@ int nitrox_process_se_request(struct nitrox_device *ndev, if (!nitrox_ready(ndev)) return -ENODEV; - sr = kzalloc(sizeof(*sr), req->gfp); + sr = kzalloc_obj(*sr, req->gfp); if (!sr) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c index 71480f7e6f6b..ead7566d78da 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes-cmac.c +++ b/drivers/crypto/ccp/ccp-crypto-aes-cmac.c @@ -354,7 +354,7 @@ int ccp_register_aes_cmac_algs(struct list_head *head) struct crypto_alg *base; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-aes-galois.c b/drivers/crypto/ccp/ccp-crypto-aes-galois.c index b1dbb8cea559..6c8d1b87d60d 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes-galois.c +++ b/drivers/crypto/ccp/ccp-crypto-aes-galois.c @@ -212,7 +212,7 @@ static int ccp_register_aes_aead(struct list_head *head, struct aead_alg *alg; int ret; - ccp_aead = kzalloc(sizeof(*ccp_aead), GFP_KERNEL); + ccp_aead = kzalloc_obj(*ccp_aead); if (!ccp_aead) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c b/drivers/crypto/ccp/ccp-crypto-aes-xts.c index 93f735d6b02b..c7e26ce71156 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c +++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c @@ -231,7 +231,7 @@ static int ccp_register_aes_xts_alg(struct list_head *head, struct skcipher_alg *alg; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-aes.c b/drivers/crypto/ccp/ccp-crypto-aes.c index 685d42ec7ade..01d298350b92 100644 --- a/drivers/crypto/ccp/ccp-crypto-aes.c +++ b/drivers/crypto/ccp/ccp-crypto-aes.c @@ -294,7 +294,7 @@ static int ccp_register_aes_alg(struct list_head *head, struct skcipher_alg *alg; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-des3.c b/drivers/crypto/ccp/ccp-crypto-des3.c index 91b1189c47de..c20b5a6a340a 100644 --- a/drivers/crypto/ccp/ccp-crypto-des3.c +++ b/drivers/crypto/ccp/ccp-crypto-des3.c @@ -182,7 +182,7 @@ static int ccp_register_des3_alg(struct list_head *head, struct skcipher_alg *alg; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-main.c b/drivers/crypto/ccp/ccp-crypto-main.c index bc90aba5162a..698e39ab107f 100644 --- a/drivers/crypto/ccp/ccp-crypto-main.c +++ b/drivers/crypto/ccp/ccp-crypto-main.c @@ -275,7 +275,7 @@ int ccp_crypto_enqueue_request(struct crypto_async_request *req, gfp = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; - crypto_cmd = kzalloc(sizeof(*crypto_cmd), gfp); + crypto_cmd = kzalloc_obj(*crypto_cmd, gfp); if (!crypto_cmd) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-rsa.c b/drivers/crypto/ccp/ccp-crypto-rsa.c index a14f85512cf4..090adacaaf93 100644 --- a/drivers/crypto/ccp/ccp-crypto-rsa.c +++ b/drivers/crypto/ccp/ccp-crypto-rsa.c @@ -249,7 +249,7 @@ static int ccp_register_rsa_alg(struct list_head *head, struct akcipher_alg *alg; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-crypto-sha.c b/drivers/crypto/ccp/ccp-crypto-sha.c index fa3ae8e78f6f..286b2d716236 100644 --- a/drivers/crypto/ccp/ccp-crypto-sha.c +++ b/drivers/crypto/ccp/ccp-crypto-sha.c @@ -418,7 +418,7 @@ static int ccp_register_hmac_alg(struct list_head *head, struct crypto_alg *base; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; @@ -462,7 +462,7 @@ static int ccp_register_sha_alg(struct list_head *head, struct crypto_alg *base; int ret; - ccp_alg = kzalloc(sizeof(*ccp_alg), GFP_KERNEL); + ccp_alg = kzalloc_obj(*ccp_alg); if (!ccp_alg) return -ENOMEM; diff --git a/drivers/crypto/ccp/ccp-ops.c b/drivers/crypto/ccp/ccp-ops.c index d0412e584762..f35803c37ab4 100644 --- a/drivers/crypto/ccp/ccp-ops.c +++ b/drivers/crypto/ccp/ccp-ops.c @@ -642,7 +642,7 @@ ccp_run_aes_gcm_cmd(struct ccp_cmd_queue *cmd_q, struct ccp_cmd *cmd) struct ccp_data dst; struct ccp_data aad; struct ccp_op op; - } *wa __free(kfree) = kzalloc(sizeof(*wa), GFP_KERNEL); + } *wa __free(kfree) = kzalloc_obj(*wa); unsigned int dm_offset; unsigned int authsize; unsigned int jobid; diff --git a/drivers/crypto/ccp/hsti.c b/drivers/crypto/ccp/hsti.c index 4b44729a019e..df09e0322304 100644 --- a/drivers/crypto/ccp/hsti.c +++ b/drivers/crypto/ccp/hsti.c @@ -87,7 +87,7 @@ static int psp_populate_hsti(struct psp_device *psp) return 0; /* Allocate command-response buffer */ - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/crypto/ccp/sev-dev-tio.c b/drivers/crypto/ccp/sev-dev-tio.c index 9a98f98c20a7..c84e23982b43 100644 --- a/drivers/crypto/ccp/sev-dev-tio.c +++ b/drivers/crypto/ccp/sev-dev-tio.c @@ -330,7 +330,7 @@ static struct sla_buffer_hdr *sla_buffer_map(struct sla_addr_t sla) if (WARN_ON_ONCE(!npages)) return NULL; - struct page **pp = kmalloc_array(npages, sizeof(pp[0]), GFP_KERNEL); + struct page **pp = kmalloc_objs(pp[0], npages); if (!pp) return NULL; diff --git a/drivers/crypto/ccp/sev-dev-tsm.c b/drivers/crypto/ccp/sev-dev-tsm.c index 3cdc38e84500..b07ae529b591 100644 --- a/drivers/crypto/ccp/sev-dev-tsm.c +++ b/drivers/crypto/ccp/sev-dev-tsm.c @@ -207,7 +207,7 @@ static int stream_alloc(struct pci_dev *pdev, struct pci_ide **ide, static struct pci_tsm *tio_pf0_probe(struct pci_dev *pdev, struct sev_device *sev) { - struct tio_dsm *dsm __free(kfree) = kzalloc(sizeof(*dsm), GFP_KERNEL); + struct tio_dsm *dsm __free(kfree) = kzalloc_obj(*dsm); int rc; if (!dsm) @@ -341,7 +341,7 @@ static struct pci_tsm_ops sev_tsm_ops = { void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page) { - struct sev_tio_status *t = kzalloc(sizeof(*t), GFP_KERNEL); + struct sev_tio_status *t = kzalloc_obj(*t); struct tsm_dev *tsmdev; int ret; @@ -378,9 +378,9 @@ void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page) return; error_exit: - kfree(t); pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n", ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV)); + kfree(t); } void sev_tsm_uninit(struct sev_device *sev) diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c index 1cdadddb744e..8b2dfc11289b 100644 --- a/drivers/crypto/ccp/sev-dev.c +++ b/drivers/crypto/ccp/sev-dev.c @@ -1105,15 +1105,12 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) { struct psp_device *psp_master = psp_get_master_device(); struct snp_hv_fixed_pages_entry *entry; - struct sev_device *sev; unsigned int order; struct page *page; - if (!psp_master || !psp_master->sev_data) + if (!psp_master) return NULL; - sev = psp_master->sev_data; - order = get_order(PMD_SIZE * num_2mb_pages); /* @@ -1126,7 +1123,8 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed * page state, fail if SNP is already initialized. */ - if (sev->snp_initialized) + if (psp_master->sev_data && + ((struct sev_device *)psp_master->sev_data)->snp_initialized) return NULL; /* Re-use freed pages that match the request */ @@ -1144,7 +1142,7 @@ struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages) if (!page) return NULL; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { __free_pages(page, order); return NULL; @@ -1162,7 +1160,7 @@ void snp_free_hv_fixed_pages(struct page *page) struct psp_device *psp_master = psp_get_master_device(); struct snp_hv_fixed_pages_entry *entry, *nentry; - if (!psp_master || !psp_master->sev_data) + if (!psp_master) return; /* @@ -2658,7 +2656,7 @@ static int sev_misc_init(struct sev_device *sev) if (!misc_dev) { struct miscdevice *misc; - misc_dev = kzalloc(sizeof(*misc_dev), GFP_KERNEL); + misc_dev = kzalloc_obj(*misc_dev); if (!misc_dev) return -ENOMEM; diff --git a/drivers/crypto/ccp/sfs.c b/drivers/crypto/ccp/sfs.c index 2f4beaafe7ec..a4777839790b 100644 --- a/drivers/crypto/ccp/sfs.c +++ b/drivers/crypto/ccp/sfs.c @@ -223,7 +223,7 @@ static int sfs_misc_init(struct sfs_device *sfs) if (!misc_dev) { struct miscdevice *misc; - misc_dev = kzalloc(sizeof(*misc_dev), GFP_KERNEL); + misc_dev = kzalloc_obj(*misc_dev); if (!misc_dev) return -ENOMEM; diff --git a/drivers/crypto/ccp/tee-dev.c b/drivers/crypto/ccp/tee-dev.c index 92ffa412622a..3e3645980e89 100644 --- a/drivers/crypto/ccp/tee-dev.c +++ b/drivers/crypto/ccp/tee-dev.c @@ -67,7 +67,7 @@ struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee) { struct tee_init_ring_cmd *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return NULL; diff --git a/drivers/crypto/ccree/cc_request_mgr.c b/drivers/crypto/ccree/cc_request_mgr.c index 887162df50f9..aa0220212406 100644 --- a/drivers/crypto/ccree/cc_request_mgr.c +++ b/drivers/crypto/ccree/cc_request_mgr.c @@ -116,7 +116,7 @@ int cc_req_mgr_init(struct cc_drvdata *drvdata) struct device *dev = drvdata_to_dev(drvdata); int rc = 0; - req_mgr_h = kzalloc(sizeof(*req_mgr_h), GFP_KERNEL); + req_mgr_h = kzalloc_obj(*req_mgr_h); if (!req_mgr_h) { rc = -ENOMEM; goto req_mgr_init_err; @@ -426,7 +426,7 @@ int cc_send_request(struct cc_drvdata *drvdata, struct cc_crypto_req *cc_req, if (rc == -ENOSPC && backlog_ok) { spin_unlock_bh(&mgr->hw_lock); - bli = kmalloc(sizeof(*bli), flags); + bli = kmalloc_obj(*bli, flags); if (!bli) { cc_pm_put_suspend(dev); return -ENOMEM; diff --git a/drivers/crypto/chelsio/chcr_core.c b/drivers/crypto/chelsio/chcr_core.c index 39c70e6255f9..2609a8c3c18b 100644 --- a/drivers/crypto/chelsio/chcr_core.c +++ b/drivers/crypto/chelsio/chcr_core.c @@ -189,7 +189,7 @@ static void *chcr_uld_add(const struct cxgb4_lld_info *lld) return ERR_PTR(-EOPNOTSUPP); /* Create the device and add it in the device list */ - u_ctx = kzalloc(sizeof(*u_ctx), GFP_KERNEL); + u_ctx = kzalloc_obj(*u_ctx); if (!u_ctx) { u_ctx = ERR_PTR(-ENOMEM); goto out; diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index edf36f6add52..a897541f897b 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2248,7 +2248,7 @@ static int hifn_alg_alloc(struct hifn_device *dev, const struct hifn_alg_templat struct hifn_crypto_alg *alg; int err; - alg = kzalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc_obj(*alg); if (!alg) return -ENOMEM; diff --git a/drivers/crypto/hisilicon/debugfs.c b/drivers/crypto/hisilicon/debugfs.c index 17eb236e9ee4..32e9f8350289 100644 --- a/drivers/crypto/hisilicon/debugfs.c +++ b/drivers/crypto/hisilicon/debugfs.c @@ -838,7 +838,7 @@ static struct dfx_diff_registers *dfx_regs_init(struct hisi_qm *qm, u32 j, base_offset; int i; - diff_regs = kcalloc(reg_len, sizeof(*diff_regs), GFP_KERNEL); + diff_regs = kzalloc_objs(*diff_regs, reg_len); if (!diff_regs) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index 571d0d250242..d1626685ed9f 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c @@ -2722,7 +2722,7 @@ static int qm_hw_err_isolate(struct hisi_qm *qm) if (qm->uacce->is_vf || isolate->is_isolate || !isolate->err_threshold) return 0; - hw_err = kzalloc(sizeof(*hw_err), GFP_KERNEL); + hw_err = kzalloc_obj(*hw_err); if (!hw_err) return -ENOMEM; @@ -3747,7 +3747,7 @@ static int hisi_qm_sort_devices(int node, struct list_head *head, if (dev_node < 0) dev_node = 0; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return -ENOMEM; @@ -5767,11 +5767,11 @@ static int hisi_qp_alloc_memory(struct hisi_qm *qm) size_t qp_dma_size; int i, ret; - qm->qp_array = kcalloc(qm->qp_num, sizeof(struct hisi_qp), GFP_KERNEL); + qm->qp_array = kzalloc_objs(struct hisi_qp, qm->qp_num); if (!qm->qp_array) return -ENOMEM; - qm->poll_data = kcalloc(qm->qp_num, sizeof(struct hisi_qm_poll_data), GFP_KERNEL); + qm->poll_data = kzalloc_objs(struct hisi_qm_poll_data, qm->qp_num); if (!qm->poll_data) { kfree(qm->qp_array); return -ENOMEM; @@ -5836,7 +5836,7 @@ static int hisi_qm_memory_init(struct hisi_qm *qm) if (test_bit(QM_SUPPORT_FUNC_QOS, &qm->caps)) { total_func = pci_sriov_get_totalvfs(qm->pdev) + 1; - qm->factor = kcalloc(total_func, sizeof(struct qm_shaper_factor), GFP_KERNEL); + qm->factor = kzalloc_objs(struct qm_shaper_factor, total_func); if (!qm->factor) return -ENOMEM; diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c index 1189effcdad0..54e24fd7b9be 100644 --- a/drivers/crypto/hisilicon/sec/sec_algs.c +++ b/drivers/crypto/hisilicon/sec/sec_algs.c @@ -553,7 +553,7 @@ static int sec_alg_alloc_and_calc_split_sizes(int length, size_t **split_sizes, /* Split into suitable sized blocks */ *steps = roundup(length, SEC_REQ_LIMIT) / SEC_REQ_LIMIT; - sizes = kcalloc(*steps, sizeof(*sizes), gfp); + sizes = kzalloc_objs(*sizes, *steps, gfp); if (!sizes) return -ENOMEM; @@ -577,12 +577,12 @@ static int sec_map_and_split_sg(struct scatterlist *sgl, size_t *split_sizes, if (!count) return -EINVAL; - *splits = kcalloc(steps, sizeof(struct scatterlist *), gfp); + *splits = kzalloc_objs(struct scatterlist *, steps, gfp); if (!*splits) { ret = -ENOMEM; goto err_unmap_sg; } - *splits_nents = kcalloc(steps, sizeof(int), gfp); + *splits_nents = kzalloc_objs(int, steps, gfp); if (!*splits_nents) { ret = -ENOMEM; goto err_free_splits; @@ -637,7 +637,7 @@ static struct sec_request_el struct sec_bd_info *req; int ret; - el = kzalloc(sizeof(*el), gfp); + el = kzalloc_obj(*el, gfp); if (!el) return ERR_PTR(-ENOMEM); el->el_length = el_size; diff --git a/drivers/crypto/hisilicon/sec2/sec_crypto.c b/drivers/crypto/hisilicon/sec2/sec_crypto.c index c462b58d3034..15174216d8c4 100644 --- a/drivers/crypto/hisilicon/sec2/sec_crypto.c +++ b/drivers/crypto/hisilicon/sec2/sec_crypto.c @@ -569,11 +569,11 @@ static int sec_alloc_qp_ctx_resource(struct sec_ctx *ctx, struct sec_qp_ctx *qp_ struct device *dev = ctx->dev; int ret = -ENOMEM; - qp_ctx->req_list = kcalloc(q_depth, sizeof(struct sec_req *), GFP_KERNEL); + qp_ctx->req_list = kzalloc_objs(struct sec_req *, q_depth); if (!qp_ctx->req_list) return ret; - qp_ctx->res = kcalloc(q_depth, sizeof(struct sec_alg_res), GFP_KERNEL); + qp_ctx->res = kzalloc_objs(struct sec_alg_res, q_depth); if (!qp_ctx->res) goto err_free_req_list; qp_ctx->res->depth = q_depth; @@ -672,8 +672,7 @@ static int sec_ctx_base_init(struct sec_ctx *ctx) ctx->hlf_q_num = sec->ctx_q_num >> 1; ctx->pbuf_supported = ctx->sec->iommu_used; - ctx->qp_ctx = kcalloc(sec->ctx_q_num, sizeof(struct sec_qp_ctx), - GFP_KERNEL); + ctx->qp_ctx = kzalloc_objs(struct sec_qp_ctx, sec->ctx_q_num); if (!ctx->qp_ctx) { ret = -ENOMEM; goto err_destroy_qps; diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 7dd125f5f511..efda8646fc60 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c @@ -420,7 +420,7 @@ struct hisi_qp **sec_create_qps(void) u8 *type; int ret; - qps = kcalloc(ctx_num, sizeof(struct hisi_qp *), GFP_KERNEL); + qps = kzalloc_objs(struct hisi_qp *, ctx_num); if (!qps) return NULL; diff --git a/drivers/crypto/hisilicon/sgl.c b/drivers/crypto/hisilicon/sgl.c index d41b34405c21..1b26077970d4 100644 --- a/drivers/crypto/hisilicon/sgl.c +++ b/drivers/crypto/hisilicon/sgl.c @@ -83,7 +83,7 @@ struct hisi_acc_sgl_pool *hisi_acc_create_sgl_pool(struct device *dev, (remain_sgl > 0 && block_num > HISI_ACC_MEM_BLOCK_NR - 1)) return ERR_PTR(-EINVAL); - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); block = pool->mem_block; diff --git a/drivers/crypto/hisilicon/zip/zip_crypto.c b/drivers/crypto/hisilicon/zip/zip_crypto.c index 98a68e44ac34..70adde049b53 100644 --- a/drivers/crypto/hisilicon/zip/zip_crypto.c +++ b/drivers/crypto/hisilicon/zip/zip_crypto.c @@ -479,8 +479,7 @@ static int hisi_zip_create_req_q(struct hisi_zip_ctx *ctx) } spin_lock_init(&req_q->req_lock); - req_q->q = kcalloc(req_q->size, sizeof(struct hisi_zip_req), - GFP_KERNEL); + req_q->q = kzalloc_objs(struct hisi_zip_req, req_q->size); if (!req_q->q) { ret = -ENOMEM; if (i == 0) diff --git a/drivers/crypto/inside-secure/eip93/eip93-aead.c b/drivers/crypto/inside-secure/eip93/eip93-aead.c index 18dd8a9a5165..1a08aed5de13 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-aead.c +++ b/drivers/crypto/inside-secure/eip93/eip93-aead.c @@ -70,7 +70,7 @@ static int eip93_aead_cra_init(struct crypto_tfm *tfm) ctx->type = tmpl->type; ctx->set_assoc = true; - ctx->sa_record = kzalloc(sizeof(*ctx->sa_record), GFP_KERNEL); + ctx->sa_record = kzalloc_obj(*ctx->sa_record); if (!ctx->sa_record) return -ENOMEM; diff --git a/drivers/crypto/inside-secure/eip93/eip93-cipher.c b/drivers/crypto/inside-secure/eip93/eip93-cipher.c index 1f2d6846610f..0713c71ab458 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-cipher.c +++ b/drivers/crypto/inside-secure/eip93/eip93-cipher.c @@ -61,7 +61,7 @@ static int eip93_skcipher_cra_init(struct crypto_tfm *tfm) ctx->eip93 = tmpl->eip93; ctx->type = tmpl->type; - ctx->sa_record = kzalloc(sizeof(*ctx->sa_record), GFP_KERNEL); + ctx->sa_record = kzalloc_obj(*ctx->sa_record); if (!ctx->sa_record) return -ENOMEM; diff --git a/drivers/crypto/inside-secure/eip93/eip93-common.c b/drivers/crypto/inside-secure/eip93/eip93-common.c index 66153aa2493f..f4ad6beff15e 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-common.c +++ b/drivers/crypto/inside-secure/eip93/eip93-common.c @@ -152,7 +152,7 @@ static int eip93_make_sg_copy(struct scatterlist *src, struct scatterlist **dst, { void *pages; - *dst = kmalloc(sizeof(**dst), GFP_KERNEL); + *dst = kmalloc_obj(**dst); if (!*dst) return -ENOMEM; diff --git a/drivers/crypto/inside-secure/eip93/eip93-hash.c b/drivers/crypto/inside-secure/eip93/eip93-hash.c index ac13d90a2b7c..2705855475b2 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-hash.c +++ b/drivers/crypto/inside-secure/eip93/eip93-hash.c @@ -332,7 +332,7 @@ static int __eip93_hash_update(struct ahash_request *req, bool complete_req) * and then reset to SHA256_BLOCK_SIZE. */ while (to_consume > max_read) { - block = kzalloc(sizeof(*block), GFP_ATOMIC); + block = kzalloc_obj(*block, GFP_ATOMIC); if (!block) { ret = -ENOMEM; goto free_blocks; diff --git a/drivers/crypto/inside-secure/safexcel.c b/drivers/crypto/inside-secure/safexcel.c index c3b2b22934b7..660f45ab8647 100644 --- a/drivers/crypto/inside-secure/safexcel.c +++ b/drivers/crypto/inside-secure/safexcel.c @@ -1889,7 +1889,7 @@ static int safexcel_pci_probe(struct pci_dev *pdev, ent->vendor, ent->device, ent->subvendor, ent->subdevice, ent->driver_data); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index e534b7a200cf..3402e570d045 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c @@ -2008,7 +2008,7 @@ static int safexcel_xcbcmac_cra_init(struct crypto_tfm *tfm) struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(tfm); safexcel_ahash_cra_init(tfm); - ctx->aes = kmalloc(sizeof(*ctx->aes), GFP_KERNEL); + ctx->aes = kmalloc_obj(*ctx->aes); return ctx->aes == NULL ? -ENOMEM : 0; } diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c index f79ea22e9abe..547abf453d4a 100644 --- a/drivers/crypto/intel/iaa/iaa_crypto_main.c +++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c @@ -335,7 +335,7 @@ int add_iaa_compression_mode(const char *name, goto out; } - mode = kzalloc(sizeof(*mode), GFP_KERNEL); + mode = kzalloc_obj(*mode); if (!mode) goto out; @@ -422,7 +422,7 @@ static int init_device_compression_mode(struct iaa_device *iaa_device, struct iaa_device_compression_mode *device_mode; int ret = -ENOMEM; - device_mode = kzalloc(sizeof(*device_mode), GFP_KERNEL); + device_mode = kzalloc_obj(*device_mode); if (!device_mode) return -ENOMEM; @@ -503,7 +503,7 @@ static struct iaa_device *iaa_device_alloc(void) { struct iaa_device *iaa_device; - iaa_device = kzalloc(sizeof(*iaa_device), GFP_KERNEL); + iaa_device = kzalloc_obj(*iaa_device); if (!iaa_device) return NULL; @@ -561,7 +561,7 @@ static int add_iaa_wq(struct iaa_device *iaa_device, struct idxd_wq *wq, struct device *dev = &pdev->dev; struct iaa_wq *iaa_wq; - iaa_wq = kzalloc(sizeof(*iaa_wq), GFP_KERNEL); + iaa_wq = kzalloc_obj(*iaa_wq); if (!iaa_wq) return -ENOMEM; @@ -718,7 +718,7 @@ static int alloc_wq_table(int max_wqs) for (cpu = 0; cpu < nr_cpus; cpu++) { entry = per_cpu_ptr(wq_table, cpu); - entry->wqs = kcalloc(max_wqs, sizeof(*entry->wqs), GFP_KERNEL); + entry->wqs = kzalloc_objs(*entry->wqs, max_wqs); if (!entry->wqs) { free_wq_table(); return -ENOMEM; diff --git a/drivers/crypto/intel/keembay/ocs-hcu.c b/drivers/crypto/intel/keembay/ocs-hcu.c index 55a41e6ab103..87711068d747 100644 --- a/drivers/crypto/intel/keembay/ocs-hcu.c +++ b/drivers/crypto/intel/keembay/ocs-hcu.c @@ -491,7 +491,7 @@ struct ocs_hcu_dma_list *ocs_hcu_dma_list_alloc(struct ocs_hcu_dev *hcu_dev, { struct ocs_hcu_dma_list *dma_list; - dma_list = kmalloc(sizeof(*dma_list), GFP_KERNEL); + dma_list = kmalloc_obj(*dma_list); if (!dma_list) return NULL; diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c b/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c index 4b5d0350fc2e..f9f1018a2823 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c +++ b/drivers/crypto/intel/qat/qat_common/adf_accel_engine.c @@ -178,7 +178,7 @@ int adf_ae_init(struct adf_accel_dev *accel_dev) if (!hw_device->fw_name) return 0; - loader_data = kzalloc(sizeof(*loader_data), GFP_KERNEL); + loader_data = kzalloc_obj(*loader_data); if (!loader_data) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_aer.c b/drivers/crypto/intel/qat/qat_common/adf_aer.c index a5964fd8204c..ed01fb9ad74e 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_aer.c +++ b/drivers/crypto/intel/qat/qat_common/adf_aer.c @@ -160,7 +160,7 @@ static int adf_dev_aer_schedule_reset(struct adf_accel_dev *accel_dev, return 0; set_bit(ADF_STATUS_RESTARTING, &accel_dev->status); - reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL); + reset_data = kzalloc_obj(*reset_data); if (!reset_data) return -ENOMEM; reset_data->accel_dev = accel_dev; @@ -258,7 +258,7 @@ int adf_notify_fatal_error(struct adf_accel_dev *accel_dev) { struct adf_fatal_error_data *wq_data; - wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC); + wq_data = kzalloc_obj(*wq_data, GFP_ATOMIC); if (!wq_data) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg.c b/drivers/crypto/intel/qat/qat_common/adf_cfg.c index b0fc453fa3fb..c202209f17d5 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_cfg.c +++ b/drivers/crypto/intel/qat/qat_common/adf_cfg.c @@ -68,7 +68,7 @@ int adf_cfg_dev_add(struct adf_accel_dev *accel_dev) { struct adf_cfg_device_data *dev_cfg_data; - dev_cfg_data = kzalloc(sizeof(*dev_cfg_data), GFP_KERNEL); + dev_cfg_data = kzalloc_obj(*dev_cfg_data); if (!dev_cfg_data) return -ENOMEM; INIT_LIST_HEAD(&dev_cfg_data->sec_list); @@ -289,7 +289,7 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, if (!section) return -EFAULT; - key_val = kzalloc(sizeof(*key_val), GFP_KERNEL); + key_val = kzalloc_obj(*key_val); if (!key_val) return -ENOMEM; @@ -356,7 +356,7 @@ int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name) if (sec) return 0; - sec = kzalloc(sizeof(*sec), GFP_KERNEL); + sec = kzalloc_obj(*sec); if (!sec) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c index 34b9f7731c78..e050de16ab5d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c @@ -172,7 +172,7 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, goto unlock; } num_devices++; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { ret = -ENOMEM; goto unlock; @@ -204,7 +204,7 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, goto unlock; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { ret = -ENOMEM; goto unlock; diff --git a/drivers/crypto/intel/qat/qat_common/adf_fw_counters.c b/drivers/crypto/intel/qat/qat_common/adf_fw_counters.c index 98fb7ccfed9f..608cd0213b40 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_fw_counters.c +++ b/drivers/crypto/intel/qat/qat_common/adf_fw_counters.c @@ -83,7 +83,7 @@ static struct adf_fw_counters *adf_fw_counters_allocate(unsigned long ae_count) if (unlikely(!ae_count)) return ERR_PTR(-EINVAL); - fw_counters = kmalloc(struct_size(fw_counters, ae_counters, ae_count), GFP_KERNEL); + fw_counters = kmalloc_flex(*fw_counters, ae_counters, ae_count); if (!fw_counters) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.c index 5dafd9a270db..efeb3d06b606 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_pm.c @@ -119,7 +119,7 @@ bool adf_gen4_handle_pm_interrupt(struct adf_accel_dev *accel_dev) val = ADF_CSR_RD(pmisc, ADF_GEN4_PM_INTERRUPT); - pm_data = kzalloc(sizeof(*pm_data), GFP_ATOMIC); + pm_data = kzalloc_obj(*pm_data, GFP_ATOMIC); if (!pm_data) return false; diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c index adb21656a3ba..bf2bae78a40d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c @@ -59,7 +59,7 @@ static int adf_gen4_vfmig_open_device(struct qat_mig_dev *mdev) vf_info = &accel_dev->pf.vf_info[mdev->vf_id]; - vfmig = kzalloc(sizeof(*vfmig), GFP_KERNEL); + vfmig = kzalloc_obj(*vfmig); if (!vfmig) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c b/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c index b19aa1ef8eee..0cdb4241f04b 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c +++ b/drivers/crypto/intel/qat/qat_common/adf_heartbeat.c @@ -281,7 +281,7 @@ int adf_heartbeat_init(struct adf_accel_dev *accel_dev) { struct adf_heartbeat *hb; - hb = kzalloc(sizeof(*hb), GFP_KERNEL); + hb = kzalloc_obj(*hb); if (!hb) goto err_ret; diff --git a/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c index 41cc763a74aa..f9017e03ec0f 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_mstate_mgr.c @@ -37,7 +37,7 @@ struct adf_mstate_mgr *adf_mstate_mgr_new(u8 *buf, u32 size) { struct adf_mstate_mgr *mgr; - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (!mgr) return NULL; diff --git a/drivers/crypto/intel/qat/qat_common/adf_rl.c b/drivers/crypto/intel/qat/qat_common/adf_rl.c index c6a54e465931..997ef448a4df 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_rl.c +++ b/drivers/crypto/intel/qat/qat_common/adf_rl.c @@ -622,7 +622,7 @@ static int add_new_sla_entry(struct adf_accel_dev *accel_dev, struct rl_sla *sla; int ret = 0; - sla = kzalloc(sizeof(*sla), GFP_KERNEL); + sla = kzalloc_obj(*sla); if (!sla) { ret = -ENOMEM; goto ret_err; @@ -1065,7 +1065,7 @@ int adf_rl_init(struct adf_accel_dev *accel_dev) goto err_ret; } - rl = kzalloc(sizeof(*rl), GFP_KERNEL); + rl = kzalloc_obj(*rl); if (!rl) { ret = -ENOMEM; goto err_ret; diff --git a/drivers/crypto/intel/qat/qat_common/adf_sriov.c b/drivers/crypto/intel/qat/qat_common/adf_sriov.c index bb904ba4bf84..8bf0fe1fcb4d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_sriov.c +++ b/drivers/crypto/intel/qat/qat_common/adf_sriov.c @@ -40,7 +40,7 @@ void adf_schedule_vf2pf_handler(struct adf_accel_vf_info *vf_info) { struct adf_pf2vf_resp *pf2vf_resp; - pf2vf_resp = kzalloc(sizeof(*pf2vf_resp), GFP_ATOMIC); + pf2vf_resp = kzalloc_obj(*pf2vf_resp, GFP_ATOMIC); if (!pf2vf_resp) return; @@ -173,8 +173,7 @@ static int adf_do_enable_sriov(struct adf_accel_dev *accel_dev) goto err_del_cfg; /* Allocate memory for VF info structs */ - accel_dev->pf.vf_info = kcalloc(totalvfs, sizeof(struct adf_accel_vf_info), - GFP_KERNEL); + accel_dev->pf.vf_info = kzalloc_objs(struct adf_accel_vf_info, totalvfs); ret = -ENOMEM; if (!accel_dev->pf.vf_info) goto err_del_cfg; diff --git a/drivers/crypto/intel/qat/qat_common/adf_telemetry.c b/drivers/crypto/intel/qat/qat_common/adf_telemetry.c index b64142db1f0d..8c575113cbcd 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_telemetry.c +++ b/drivers/crypto/intel/qat/qat_common/adf_telemetry.c @@ -75,9 +75,8 @@ static int adf_tl_alloc_mem(struct adf_accel_dev *accel_dev) if (!telemetry->rp_num_indexes) goto err_free_tl; - telemetry->regs_hist_buff = kmalloc_array(tl_data->num_hbuff, - sizeof(*telemetry->regs_hist_buff), - GFP_KERNEL); + telemetry->regs_hist_buff = kmalloc_objs(*telemetry->regs_hist_buff, + tl_data->num_hbuff); if (!telemetry->regs_hist_buff) goto err_free_rp_indexes; diff --git a/drivers/crypto/intel/qat/qat_common/adf_timer.c b/drivers/crypto/intel/qat/qat_common/adf_timer.c index 8962a49f145a..cee965f9368d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_timer.c +++ b/drivers/crypto/intel/qat/qat_common/adf_timer.c @@ -40,7 +40,7 @@ int adf_timer_start(struct adf_accel_dev *accel_dev) { struct adf_timer *timer_ctx; - timer_ctx = kzalloc(sizeof(*timer_ctx), GFP_KERNEL); + timer_ctx = kzalloc_obj(*timer_ctx); if (!timer_ctx) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c index 6c22bc9b28e4..a8f853516a3f 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c +++ b/drivers/crypto/intel/qat/qat_common/adf_transport_debug.c @@ -99,7 +99,7 @@ int adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name) struct adf_etr_ring_debug_entry *ring_debug; char entry_name[16]; - ring_debug = kzalloc(sizeof(*ring_debug), GFP_KERNEL); + ring_debug = kzalloc_obj(*ring_debug); if (!ring_debug) return -ENOMEM; diff --git a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c index d0fef20a3df4..9ffaa56def67 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c @@ -85,7 +85,7 @@ int adf_pf2vf_handle_pf_restarting(struct adf_accel_dev *accel_dev) struct adf_vf_stop_data *stop_data; clear_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status); - stop_data = kzalloc(sizeof(*stop_data), GFP_ATOMIC); + stop_data = kzalloc_obj(*stop_data, GFP_ATOMIC); if (!stop_data) { dev_err(&GET_DEV(accel_dev), "Couldn't schedule stop for vf_%d\n", diff --git a/drivers/crypto/intel/qat/qat_common/qat_hal.c b/drivers/crypto/intel/qat/qat_common/qat_hal.c index da4eca6e1633..7a6ba6f22e3e 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_hal.c +++ b/drivers/crypto/intel/qat/qat_common/qat_hal.c @@ -832,17 +832,17 @@ int qat_hal_init(struct adf_accel_dev *accel_dev) struct icp_qat_fw_loader_handle *handle; int ret = 0; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; - handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL); + handle->hal_handle = kzalloc_obj(*handle->hal_handle); if (!handle->hal_handle) { ret = -ENOMEM; goto out_hal_handle; } - handle->chip_info = kzalloc(sizeof(*handle->chip_info), GFP_KERNEL); + handle->chip_info = kzalloc_obj(*handle->chip_info); if (!handle->chip_info) { ret = -ENOMEM; goto out_chip_info; diff --git a/drivers/crypto/intel/qat/qat_common/qat_mig_dev.c b/drivers/crypto/intel/qat/qat_common/qat_mig_dev.c index 892c2283a50e..3869ada0190d 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_mig_dev.c +++ b/drivers/crypto/intel/qat/qat_common/qat_mig_dev.c @@ -24,7 +24,7 @@ struct qat_mig_dev *qat_vfmig_create(struct pci_dev *pdev, int vf_id) !ops->load_state || !ops->save_setup || !ops->load_setup) return ERR_PTR(-EINVAL); - mdev = kmalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kmalloc_obj(*mdev); if (!mdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/intel/qat/qat_common/qat_uclo.c b/drivers/crypto/intel/qat/qat_common/qat_uclo.c index 06d49cb781ae..e61a367b0d17 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_uclo.c +++ b/drivers/crypto/intel/qat/qat_common/qat_uclo.c @@ -42,10 +42,10 @@ static int qat_uclo_init_ae_data(struct icp_qat_uclo_objhandle *obj_handle, } else { ae_slice->ctx_mask_assigned = 0; } - ae_slice->region = kzalloc(sizeof(*ae_slice->region), GFP_KERNEL); + ae_slice->region = kzalloc_obj(*ae_slice->region); if (!ae_slice->region) return -ENOMEM; - ae_slice->page = kzalloc(sizeof(*ae_slice->page), GFP_KERNEL); + ae_slice->page = kzalloc_obj(*ae_slice->page); if (!ae_slice->page) goto out_err; page = ae_slice->page; @@ -258,7 +258,7 @@ static int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle init_header = *init_tab_base; if (!init_header) { - init_header = kzalloc(sizeof(*init_header), GFP_KERNEL); + init_header = kzalloc_obj(*init_header); if (!init_header) return -ENOMEM; init_header->size = 1; @@ -270,7 +270,7 @@ static int qat_uclo_create_batch_init_list(struct icp_qat_fw_loader_handle tail_old = tail_old->next; tail = tail_old; for (i = 0; i < init_mem->val_attr_num; i++) { - mem_init = kzalloc(sizeof(*mem_init), GFP_KERNEL); + mem_init = kzalloc_obj(*mem_init); if (!mem_init) goto out_err; mem_init->ae = ae; @@ -501,7 +501,7 @@ qat_uclo_map_chunk(char *buf, struct icp_qat_uof_filehdr *file_hdr, if (file_chunk->checksum != qat_uclo_calc_str_checksum( chunk, file_chunk->size)) break; - obj_hdr = kzalloc(sizeof(*obj_hdr), GFP_KERNEL); + obj_hdr = kzalloc_obj(*obj_hdr); if (!obj_hdr) break; obj_hdr->file_buff = chunk; @@ -634,8 +634,7 @@ static int qat_uclo_map_uimage(struct icp_qat_uclo_objhandle *obj_handle, if (qat_uclo_check_image_compat(encap_uof_obj, image)) goto out_err; ae_uimage[j].page = - kzalloc(sizeof(struct icp_qat_uclo_encap_page), - GFP_KERNEL); + kzalloc_obj(struct icp_qat_uclo_encap_page); if (!ae_uimage[j].page) goto out_err; qat_uclo_map_image_page(encap_uof_obj, image, @@ -1200,9 +1199,8 @@ static int qat_uclo_map_suof(struct icp_qat_fw_loader_handle *handle, suof_handle->img_table.num_simgs = suof_ptr->num_chunks - 1; if (suof_handle->img_table.num_simgs != 0) { - suof_img_hdr = kcalloc(suof_handle->img_table.num_simgs, - sizeof(img_header), - GFP_KERNEL); + suof_img_hdr = kzalloc_objs(img_header, + suof_handle->img_table.num_simgs); if (!suof_img_hdr) return -ENOMEM; suof_handle->img_table.simg_hdr = suof_img_hdr; @@ -1720,7 +1718,7 @@ static int qat_uclo_map_suof_obj(struct icp_qat_fw_loader_handle *handle, { struct icp_qat_suof_handle *suof_handle; - suof_handle = kzalloc(sizeof(*suof_handle), GFP_KERNEL); + suof_handle = kzalloc_obj(*suof_handle); if (!suof_handle) return -ENOMEM; handle->sobj_handle = suof_handle; @@ -1764,7 +1762,7 @@ static int qat_uclo_map_uof_obj(struct icp_qat_fw_loader_handle *handle, struct icp_qat_uof_filehdr *filehdr; struct icp_qat_uclo_objhandle *objhdl; - objhdl = kzalloc(sizeof(*objhdl), GFP_KERNEL); + objhdl = kzalloc_obj(*objhdl); if (!objhdl) return -ENOMEM; objhdl->obj_buf = kmemdup(addr_ptr, mem_size, GFP_KERNEL); @@ -1892,8 +1890,8 @@ static int qat_uclo_map_objs_from_mof(struct icp_qat_mof_handle *mobj_handle) if (sobj_hdr) sobj_chunk_num = sobj_hdr->num_chunks; - mobj_hdr = kcalloc(size_add(uobj_chunk_num, sobj_chunk_num), - sizeof(*mobj_hdr), GFP_KERNEL); + mobj_hdr = kzalloc_objs(*mobj_hdr, + size_add(uobj_chunk_num, sobj_chunk_num)); if (!mobj_hdr) return -ENOMEM; @@ -2003,7 +2001,7 @@ static int qat_uclo_map_mof_obj(struct icp_qat_fw_loader_handle *handle, if (qat_uclo_check_mof_format(mof_ptr)) return -EINVAL; - mobj_handle = kzalloc(sizeof(*mobj_handle), GFP_KERNEL); + mobj_handle = kzalloc_obj(*mobj_handle); if (!mobj_handle) return -ENOMEM; diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c index 417a48f41350..09e6a8474d1a 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c +++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c @@ -318,7 +318,7 @@ static int process_tar_file(struct device *dev, return -EINVAL; } - tar_info = kzalloc(sizeof(struct tar_ucode_info_t), GFP_KERNEL); + tar_info = kzalloc_obj(struct tar_ucode_info_t); if (!tar_info) return -ENOMEM; @@ -412,7 +412,7 @@ static struct tar_arch_info_t *load_tar_archive(struct device *dev, size_t tar_size; int ret; - tar_arch = kzalloc(sizeof(struct tar_arch_info_t), GFP_KERNEL); + tar_arch = kzalloc_obj(struct tar_arch_info_t); if (!tar_arch) return NULL; diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c index 6c0bfb3ea1c9..587609db6c69 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_main.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_main.c @@ -31,7 +31,7 @@ static int init_worker_threads(struct otx_cptvf *cptvf) struct otx_cptvf_wqe_info *cwqe_info; int i; - cwqe_info = kzalloc(sizeof(*cwqe_info), GFP_KERNEL); + cwqe_info = kzalloc_obj(*cwqe_info); if (!cwqe_info) return -ENOMEM; @@ -100,7 +100,7 @@ static int alloc_pending_queues(struct otx_cpt_pending_qinfo *pqinfo, u32 qlen, pqinfo->num_queues = num_queues; for_each_pending_queue(pqinfo, queue, i) { - queue->head = kcalloc(qlen, sizeof(*queue->head), GFP_KERNEL); + queue->head = kzalloc_objs(*queue->head, qlen); if (!queue->head) { ret = -ENOMEM; goto pending_qfail; @@ -212,7 +212,7 @@ static int alloc_command_queues(struct otx_cptvf *cptvf, queue = &cqinfo->queue[i]; INIT_LIST_HEAD(&queue->chead); do { - curr = kzalloc(sizeof(*curr), GFP_KERNEL); + curr = kzalloc_obj(*curr); if (!curr) goto cmd_qfail; diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c index f54f90588d86..346d1345f11c 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c @@ -340,8 +340,7 @@ static int cptpf_flr_wq_init(struct otx2_cptpf_dev *cptpf, int num_vfs) if (!cptpf->flr_wq) return -ENOMEM; - cptpf->flr_work = kcalloc(num_vfs, sizeof(struct cptpf_flr_work), - GFP_KERNEL); + cptpf->flr_work = kzalloc_objs(struct cptpf_flr_work, num_vfs); if (!cptpf->flr_work) goto destroy_wq; diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c index b5cc5401f704..9b0887d7e62c 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c @@ -372,7 +372,7 @@ static int load_fw(struct device *dev, struct fw_info_t *fw_info, int ucode_type, ucode_size; int ret; - uc_info = kzalloc(sizeof(*uc_info), GFP_KERNEL); + uc_info = kzalloc_obj(*uc_info); if (!uc_info) return -ENOMEM; diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c index c1c44a7b89fa..858f851c9c8a 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_main.c @@ -150,7 +150,7 @@ static int init_tasklet_work(struct otx2_cptlfs_info *lfs) int i, ret = 0; for (i = 0; i < lfs->lfs_num; i++) { - wqe = kzalloc(sizeof(struct otx2_cptlf_wqe), GFP_KERNEL); + wqe = kzalloc_obj(struct otx2_cptlf_wqe); if (!wqe) { ret = -ENOMEM; goto cleanup_tasklet; diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index b950fcce8a9b..b61f2545e165 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c @@ -105,7 +105,7 @@ void *nx842_crypto_alloc_ctx(struct nx842_driver *driver) { struct nx842_crypto_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/crypto/nx/nx-common-powernv.c b/drivers/crypto/nx/nx-common-powernv.c index 56aa1c29d782..d6185740ff93 100644 --- a/drivers/crypto/nx/nx-common-powernv.c +++ b/drivers/crypto/nx/nx-common-powernv.c @@ -810,7 +810,7 @@ static int __init vas_cfg_coproc_info(struct device_node *dn, int chip_id, return ret; } - coproc = kzalloc(sizeof(*coproc), GFP_KERNEL); + coproc = kzalloc_obj(*coproc); if (!coproc) return -ENOMEM; @@ -968,7 +968,7 @@ static int __init nx842_powernv_probe(struct device_node *dn) return -EINVAL; } - coproc = kzalloc(sizeof(*coproc), GFP_KERNEL); + coproc = kzalloc_obj(*coproc); if (!coproc) return -ENOMEM; diff --git a/drivers/crypto/nx/nx-common-pseries.c b/drivers/crypto/nx/nx-common-pseries.c index fc0222ebe807..a6e65c3d2873 100644 --- a/drivers/crypto/nx/nx-common-pseries.c +++ b/drivers/crypto/nx/nx-common-pseries.c @@ -747,7 +747,7 @@ static int nx842_OF_upd(struct property *new_prop) int ret = 0; unsigned long flags; - new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); + new_devdata = kzalloc_obj(*new_devdata, GFP_NOFS); if (!new_devdata) return -ENOMEM; @@ -1035,12 +1035,11 @@ static int nx842_probe(struct vio_dev *viodev, unsigned long flags; int ret = 0; - new_devdata = kzalloc(sizeof(*new_devdata), GFP_NOFS); + new_devdata = kzalloc_obj(*new_devdata, GFP_NOFS); if (!new_devdata) return -ENOMEM; - new_devdata->counters = kzalloc(sizeof(*new_devdata->counters), - GFP_NOFS); + new_devdata->counters = kzalloc_obj(*new_devdata->counters, GFP_NOFS); if (!new_devdata->counters) { kfree(new_devdata); return -ENOMEM; @@ -1149,7 +1148,7 @@ static void __init nxcop_get_capabilities(void) u64 feat; int rc; - hv_caps = kmalloc(sizeof(*hv_caps), GFP_KERNEL); + hv_caps = kmalloc_obj(*hv_caps); if (!hv_caps) return; /* @@ -1168,7 +1167,7 @@ static void __init nxcop_get_capabilities(void) /* * NX-GZIP feature available */ - hv_nxc = kmalloc(sizeof(*hv_nxc), GFP_KERNEL); + hv_nxc = kmalloc_obj(*hv_nxc); if (!hv_nxc) return; /* @@ -1218,7 +1217,7 @@ static int __init nx842_pseries_init(void) of_node_put(np); RCU_INIT_POINTER(devdata, NULL); - new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL); + new_devdata = kzalloc_obj(*new_devdata); if (!new_devdata) return -ENOMEM; diff --git a/drivers/crypto/omap-crypto.c b/drivers/crypto/omap-crypto.c index 0345c9383d50..7bd6869c2b21 100644 --- a/drivers/crypto/omap-crypto.c +++ b/drivers/crypto/omap-crypto.c @@ -21,7 +21,7 @@ static int omap_crypto_copy_sg_lists(int total, int bs, struct scatterlist *tmp; if (!(flags & OMAP_CRYPTO_FORCE_SINGLE_ENTRY)) { - new_sg = kmalloc_array(n, sizeof(*new_sg), GFP_KERNEL); + new_sg = kmalloc_objs(*new_sg, n); if (!new_sg) return -ENOMEM; diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 1ffc240e016a..6a3c7f9277cf 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -636,7 +636,7 @@ static int omap_sham_copy_sg_lists(struct omap_sham_reqctx *ctx, if (ctx->bufcnt) n++; - ctx->sg = kmalloc_array(n, sizeof(*sg), GFP_KERNEL); + ctx->sg = kmalloc_objs(*sg, n); if (!ctx->sg) return -ENOMEM; diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c index 97b56e92ea33..846e1d42775d 100644 --- a/drivers/crypto/qce/aead.c +++ b/drivers/crypto/qce/aead.c @@ -762,7 +762,7 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi struct aead_alg *alg; int ret; - tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + tmpl = kzalloc_obj(*tmpl); if (!tmpl) return -ENOMEM; diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index 71b748183cfa..402e4e64347d 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c @@ -457,7 +457,7 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def, struct crypto_alg *base; int ret; - tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + tmpl = kzalloc_obj(*tmpl); if (!tmpl) return -ENOMEM; diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index ffb334eb5b34..4ad3a1702010 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c @@ -440,7 +440,7 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, struct skcipher_alg *alg; int ret; - tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + tmpl = kzalloc_obj(*tmpl); if (!tmpl) return -ENOMEM; diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index b829c84f60f2..eece1ff6c62f 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -499,7 +499,7 @@ static int s5p_make_sg_cpy(struct s5p_aes_dev *dev, struct scatterlist *src, void *pages; int len; - *dst = kmalloc(sizeof(**dst), GFP_ATOMIC); + *dst = kmalloc_obj(**dst, GFP_ATOMIC); if (!*dst) return -ENOMEM; @@ -1056,7 +1056,7 @@ static int s5p_hash_copy_sg_lists(struct s5p_hash_reqctx *ctx, if (ctx->bufcnt) n++; - ctx->sg = kmalloc_array(n, sizeof(*sg), GFP_KERNEL); + ctx->sg = kmalloc_objs(*sg, n); if (!ctx->sg) { ctx->error = true; return -ENOMEM; diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index fdc0b2486069..df3defa1ef4b 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c @@ -1099,7 +1099,7 @@ static int sa_run(struct sa_req *req) gfp_flags = req->base->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; - rxd = kzalloc(sizeof(*rxd), gfp_flags); + rxd = kzalloc_obj(*rxd, gfp_flags); if (!rxd) return -ENOMEM; diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c index d206eddb67bf..3c9b3f679461 100644 --- a/drivers/crypto/stm32/stm32-cryp.c +++ b/drivers/crypto/stm32/stm32-cryp.c @@ -1498,7 +1498,7 @@ static int stm32_cryp_truncate_sg(struct scatterlist **new_sg, size_t *new_sg_le return alloc_sg_len; /* We allocate to much sg entry, but it is easier */ - *new_sg = kmalloc_array((size_t)alloc_sg_len, sizeof(struct scatterlist), GFP_KERNEL); + *new_sg = kmalloc_objs(struct scatterlist, (size_t)alloc_sg_len); if (!*new_sg) return -ENOMEM; diff --git a/drivers/crypto/tegra/tegra-se-main.c b/drivers/crypto/tegra/tegra-se-main.c index 4e7115b247e7..eb71113ed146 100644 --- a/drivers/crypto/tegra/tegra-se-main.c +++ b/drivers/crypto/tegra/tegra-se-main.c @@ -47,7 +47,7 @@ tegra_se_cmdbuf_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_dire struct host1x_bo_mapping *map; int err; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return ERR_PTR(-ENOMEM); @@ -56,7 +56,7 @@ tegra_se_cmdbuf_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_dire map->direction = direction; map->dev = dev; - map->sgt = kzalloc(sizeof(*map->sgt), GFP_KERNEL); + map->sgt = kzalloc_obj(*map->sgt); if (!map->sgt) { err = -ENOMEM; goto free; @@ -123,7 +123,7 @@ static struct tegra_se_cmdbuf *tegra_se_host1x_bo_alloc(struct tegra_se *se, ssi struct tegra_se_cmdbuf *cmdbuf; struct device *dev = se->dev->parent; - cmdbuf = kzalloc(sizeof(*cmdbuf), GFP_KERNEL); + cmdbuf = kzalloc_obj(*cmdbuf); if (!cmdbuf) return NULL; diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c index 2e44915c9f23..d8d452cac391 100644 --- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c @@ -112,7 +112,7 @@ static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher if (!pkey) return -ENOMEM; - vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + vc_ctrl_req = kzalloc_obj(*vc_ctrl_req); if (!vc_ctrl_req) { err = -ENOMEM; goto out; @@ -169,7 +169,7 @@ static int virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akciphe if (!ctx->session_valid) return 0; - vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + vc_ctrl_req = kzalloc_obj(*vc_ctrl_req); if (!vc_ctrl_req) return -ENOMEM; diff --git a/drivers/crypto/virtio/virtio_crypto_core.c b/drivers/crypto/virtio/virtio_crypto_core.c index ccc6b5c1b24b..955bff8820da 100644 --- a/drivers/crypto/virtio/virtio_crypto_core.c +++ b/drivers/crypto/virtio/virtio_crypto_core.c @@ -115,10 +115,10 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi) total_vqs = vi->max_data_queues + 1; /* Allocate space for find_vqs parameters */ - vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL); + vqs = kzalloc_objs(*vqs, total_vqs); if (!vqs) goto err_vq; - vqs_info = kcalloc(total_vqs, sizeof(*vqs_info), GFP_KERNEL); + vqs_info = kzalloc_objs(*vqs_info, total_vqs); if (!vqs_info) goto err_vqs_info; @@ -170,8 +170,7 @@ static int virtcrypto_find_vqs(struct virtio_crypto *vi) static int virtcrypto_alloc_queues(struct virtio_crypto *vi) { - vi->data_vq = kcalloc(vi->max_data_queues, sizeof(*vi->data_vq), - GFP_KERNEL); + vi->data_vq = kzalloc_objs(*vi->data_vq, vi->max_data_queues); if (!vi->data_vq) return -ENOMEM; diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c index 11053d1786d4..e82fc16cab25 100644 --- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c @@ -131,7 +131,7 @@ static int virtio_crypto_alg_skcipher_init_session( if (!cipher_key) return -ENOMEM; - vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + vc_ctrl_req = kzalloc_obj(*vc_ctrl_req); if (!vc_ctrl_req) { err = -ENOMEM; goto out; @@ -200,7 +200,7 @@ static int virtio_crypto_alg_skcipher_close_session( struct virtio_crypto_inhdr *ctrl_status; struct virtio_crypto_ctrl_request *vc_ctrl_req; - vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + vc_ctrl_req = kzalloc_obj(*vc_ctrl_req); if (!vc_ctrl_req) return -ENOMEM; diff --git a/drivers/cxl/acpi.c b/drivers/cxl/acpi.c index d78f005bd994..127537628817 100644 --- a/drivers/cxl/acpi.c +++ b/drivers/cxl/acpi.c @@ -336,7 +336,7 @@ static void del_cxl_resource(struct resource *res) static struct resource *alloc_cxl_resource(resource_size_t base, resource_size_t n, int id) { - struct resource *res __free(kfree) = kzalloc(sizeof(*res), GFP_KERNEL); + struct resource *res __free(kfree) = kzalloc_obj(*res); if (!res) return NULL; @@ -825,7 +825,7 @@ static int add_cxl_resources(struct resource *cxl_res) struct resource *res, *new, *next; for (res = cxl_res->child; res; res = next) { - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return -ENOMEM; new->name = res->name; diff --git a/drivers/cxl/core/cdat.c b/drivers/cxl/core/cdat.c index 18f0f2a25113..5c9f07262513 100644 --- a/drivers/cxl/core/cdat.c +++ b/drivers/cxl/core/cdat.c @@ -69,7 +69,7 @@ static int cdat_dsmas_handler(union acpi_subtable_headers *header, void *arg, /* Skip common header */ dsmas = (struct acpi_cdat_dsmas *)(hdr + 1); - dent = kzalloc(sizeof(*dent), GFP_KERNEL); + dent = kzalloc_obj(*dent); if (!dent) return -ENOMEM; @@ -669,7 +669,7 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, perf_ctx = xa_load(usp_xa, index); if (!perf_ctx) { struct cxl_perf_ctx *c __free(kfree) = - kzalloc(sizeof(*perf_ctx), GFP_KERNEL); + kzalloc_obj(*perf_ctx); if (!c) return -ENOMEM; @@ -756,7 +756,7 @@ static struct xarray *cxl_switch_gather_bandwidth(struct cxl_region *cxlr, bool *gp_is_root) { struct xarray *res_xa __free(free_perf_xa) = - kzalloc(sizeof(*res_xa), GFP_KERNEL); + kzalloc_obj(*res_xa); struct access_coordinate coords[ACCESS_COORDINATE_MAX]; struct cxl_perf_ctx *ctx, *us_ctx; unsigned long index, us_index; @@ -795,7 +795,7 @@ static struct xarray *cxl_switch_gather_bandwidth(struct cxl_region *cxlr, us_ctx = xa_load(res_xa, us_index); if (!us_ctx) { struct cxl_perf_ctx *n __free(kfree) = - kzalloc(sizeof(*n), GFP_KERNEL); + kzalloc_obj(*n); if (!n) return ERR_PTR(-ENOMEM); @@ -862,7 +862,7 @@ static struct xarray *cxl_switch_gather_bandwidth(struct cxl_region *cxlr, static struct xarray *cxl_rp_gather_bandwidth(struct xarray *xa) { struct xarray *hb_xa __free(free_perf_xa) = - kzalloc(sizeof(*hb_xa), GFP_KERNEL); + kzalloc_obj(*hb_xa); struct cxl_perf_ctx *ctx; unsigned long index; @@ -879,7 +879,7 @@ static struct xarray *cxl_rp_gather_bandwidth(struct xarray *xa) hb_ctx = xa_load(hb_xa, hb_index); if (!hb_ctx) { struct cxl_perf_ctx *n __free(kfree) = - kzalloc(sizeof(*n), GFP_KERNEL); + kzalloc_obj(*n); if (!n) return ERR_PTR(-ENOMEM); @@ -906,7 +906,7 @@ static struct xarray *cxl_rp_gather_bandwidth(struct xarray *xa) static struct xarray *cxl_hb_gather_bandwidth(struct xarray *xa) { struct xarray *mw_xa __free(free_perf_xa) = - kzalloc(sizeof(*mw_xa), GFP_KERNEL); + kzalloc_obj(*mw_xa); struct cxl_perf_ctx *ctx; unsigned long index; @@ -928,7 +928,7 @@ static struct xarray *cxl_hb_gather_bandwidth(struct xarray *xa) mw_ctx = xa_load(mw_xa, mw_index); if (!mw_ctx) { struct cxl_perf_ctx *n __free(kfree) = - kzalloc(sizeof(*n), GFP_KERNEL); + kzalloc_obj(*n); if (!n) return ERR_PTR(-ENOMEM); @@ -987,7 +987,7 @@ void cxl_region_shared_upstream_bandwidth_update(struct cxl_region *cxlr) lockdep_assert_held(&cxl_rwsem.dpa); struct xarray *usp_xa __free(free_perf_xa) = - kzalloc(sizeof(*usp_xa), GFP_KERNEL); + kzalloc_obj(*usp_xa); if (!usp_xa) return; diff --git a/drivers/cxl/core/core.h b/drivers/cxl/core/core.h index 007b8aff0238..5b0570df0fd9 100644 --- a/drivers/cxl/core/core.h +++ b/drivers/cxl/core/core.h @@ -152,6 +152,24 @@ int cxl_pci_get_bandwidth(struct pci_dev *pdev, struct access_coordinate *c); int cxl_port_get_switch_dport_bandwidth(struct cxl_port *port, struct access_coordinate *c); +static inline struct device *port_to_host(struct cxl_port *port) +{ + struct cxl_port *parent = is_cxl_root(port) ? NULL : + to_cxl_port(port->dev.parent); + + /* + * The host of CXL root port and the first level of ports is + * the platform firmware device, the host of all other ports + * is their parent port. + */ + if (!parent) + return port->uport_dev; + else if (is_cxl_root(parent)) + return parent->uport_dev; + else + return &parent->dev; +} + static inline struct device *dport_to_host(struct cxl_dport *dport) { struct cxl_port *port = dport->port; diff --git a/drivers/cxl/core/edac.c b/drivers/cxl/core/edac.c index 81160260e26b..b321971fef58 100644 --- a/drivers/cxl/core/edac.c +++ b/drivers/cxl/core/edac.c @@ -2009,8 +2009,7 @@ static void err_rec_free(void *_cxlmd) static int devm_cxl_memdev_setup_err_rec(struct cxl_memdev *cxlmd) { - struct cxl_mem_err_rec *array_rec = - kzalloc(sizeof(*array_rec), GFP_KERNEL); + struct cxl_mem_err_rec *array_rec = kzalloc_obj(*array_rec); if (!array_rec) return -ENOMEM; diff --git a/drivers/cxl/core/features.c b/drivers/cxl/core/features.c index 4bc484b46f43..3435db9ea6b1 100644 --- a/drivers/cxl/core/features.c +++ b/drivers/cxl/core/features.c @@ -94,7 +94,7 @@ get_supported_features(struct cxl_features_state *cxlfs) return NULL; struct cxl_feat_entries *entries __free(kvfree) = - kvmalloc(struct_size(entries, ent, count), GFP_KERNEL); + kvmalloc_flex(*entries, ent, count); if (!entries) return NULL; @@ -204,7 +204,7 @@ int devm_cxl_setup_features(struct cxl_dev_state *cxlds) return -ENODEV; struct cxl_features_state *cxlfs __free(kfree) = - kzalloc(sizeof(*cxlfs), GFP_KERNEL); + kzalloc_obj(*cxlfs); if (!cxlfs) return -ENOMEM; diff --git a/drivers/cxl/core/hdm.c b/drivers/cxl/core/hdm.c index e3f0c39e6812..c222e98ae736 100644 --- a/drivers/cxl/core/hdm.c +++ b/drivers/cxl/core/hdm.c @@ -904,7 +904,7 @@ static void cxl_decoder_reset(struct cxl_decoder *cxld) if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) return; - if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) + if (cxld->flags & CXL_DECODER_F_LOCK) return; if (port->commit_end == id) diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c index fa6dd0c94656..e7a6452bf544 100644 --- a/drivers/cxl/core/mbox.c +++ b/drivers/cxl/core/mbox.c @@ -311,6 +311,7 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * cxl_payload_from_user_allowed() - Check contents of in_payload. * @opcode: The mailbox command opcode. * @payload_in: Pointer to the input payload passed in from user space. + * @in_size: Size of @payload_in in bytes. * * Return: * * true - payload_in passes check for @opcode. @@ -325,12 +326,15 @@ static bool cxl_mem_raw_command_allowed(u16 opcode) * * The specific checks are determined by the opcode. */ -static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) +static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in, + size_t in_size) { switch (opcode) { case CXL_MBOX_OP_SET_PARTITION_INFO: { struct cxl_mbox_set_partition_info *pi = payload_in; + if (in_size < sizeof(*pi)) + return false; if (pi->flags & CXL_SET_PARTITION_IMMEDIATE_FLAG) return false; break; @@ -338,6 +342,8 @@ static bool cxl_payload_from_user_allowed(u16 opcode, void *payload_in) case CXL_MBOX_OP_CLEAR_LOG: { const uuid_t *uuid = (uuid_t *)payload_in; + if (in_size < sizeof(uuid_t)) + return false; /* * Restrict the ‘Clear log’ action to only apply to * Vendor debug logs. @@ -365,7 +371,8 @@ static int cxl_mbox_cmd_ctor(struct cxl_mbox_cmd *mbox_cmd, if (IS_ERR(mbox_cmd->payload_in)) return PTR_ERR(mbox_cmd->payload_in); - if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in)) { + if (!cxl_payload_from_user_allowed(opcode, mbox_cmd->payload_in, + in_size)) { dev_dbg(cxl_mbox->host, "%s: input payload not allowed\n", cxl_mem_opcode_to_name(opcode)); kvfree(mbox_cmd->payload_in); diff --git a/drivers/cxl/core/memdev.c b/drivers/cxl/core/memdev.c index af3d0cc65138..273c22118d3d 100644 --- a/drivers/cxl/core/memdev.c +++ b/drivers/cxl/core/memdev.c @@ -665,7 +665,7 @@ static struct cxl_memdev *cxl_memdev_alloc(struct cxl_dev_state *cxlds, struct cdev *cdev; int rc; - cxlmd = kzalloc(sizeof(*cxlmd), GFP_KERNEL); + cxlmd = kzalloc_obj(*cxlmd); if (!cxlmd) return ERR_PTR(-ENOMEM); @@ -831,7 +831,7 @@ static int cxl_mem_abort_fw_xfer(struct cxl_memdev_state *mds) struct cxl_mbox_cmd mbox_cmd; int rc; - transfer = kzalloc(struct_size(transfer, data, 0), GFP_KERNEL); + transfer = kzalloc_flex(*transfer, data, 0); if (!transfer) return -ENOMEM; @@ -1089,10 +1089,8 @@ static int cxlmd_add(struct cxl_memdev *cxlmd, struct cxl_dev_state *cxlds) DEFINE_FREE(put_cxlmd, struct cxl_memdev *, if (!IS_ERR_OR_NULL(_T)) put_device(&_T->dev)) -static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd) +static bool cxl_memdev_attach_failed(struct cxl_memdev *cxlmd) { - int rc; - /* * If @attach is provided fail if the driver is not attached upon * return. Note that failure here could be the result of a race to @@ -1100,7 +1098,14 @@ static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd) * succeeded and then cxl_mem unbound before the lock is acquired. */ guard(device)(&cxlmd->dev); - if (cxlmd->attach && !cxlmd->dev.driver) { + return (cxlmd->attach && !cxlmd->dev.driver); +} + +static struct cxl_memdev *cxl_memdev_autoremove(struct cxl_memdev *cxlmd) +{ + int rc; + + if (cxl_memdev_attach_failed(cxlmd)) { cxl_memdev_unregister(cxlmd); return ERR_PTR(-ENXIO); } diff --git a/drivers/cxl/core/pmem.c b/drivers/cxl/core/pmem.c index e7b1e6fa0ea0..68462e38a977 100644 --- a/drivers/cxl/core/pmem.c +++ b/drivers/cxl/core/pmem.c @@ -83,7 +83,7 @@ static struct cxl_nvdimm_bridge *cxl_nvdimm_bridge_alloc(struct cxl_port *port) struct device *dev; int rc; - cxl_nvb = kzalloc(sizeof(*cxl_nvb), GFP_KERNEL); + cxl_nvb = kzalloc_obj(*cxl_nvb); if (!cxl_nvb) return ERR_PTR(-ENOMEM); @@ -115,15 +115,17 @@ static void unregister_nvb(void *_cxl_nvb) device_unregister(&cxl_nvb->dev); } -/** - * devm_cxl_add_nvdimm_bridge() - add the root of a LIBNVDIMM topology - * @host: platform firmware root device - * @port: CXL port at the root of a CXL topology - * - * Return: bridge device that can host cxl_nvdimm objects - */ -struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, - struct cxl_port *port) +static bool cxl_nvdimm_bridge_failed_attach(struct cxl_nvdimm_bridge *cxl_nvb) +{ + struct device *dev = &cxl_nvb->dev; + + guard(device)(dev); + /* If the device has no driver, then it failed to attach. */ + return dev->driver == NULL; +} + +struct cxl_nvdimm_bridge *__devm_cxl_add_nvdimm_bridge(struct device *host, + struct cxl_port *port) { struct cxl_nvdimm_bridge *cxl_nvb; struct device *dev; @@ -145,6 +147,11 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, if (rc) goto err; + if (cxl_nvdimm_bridge_failed_attach(cxl_nvb)) { + unregister_nvb(cxl_nvb); + return ERR_PTR(-ENODEV); + } + rc = devm_add_action_or_reset(host, unregister_nvb, cxl_nvb); if (rc) return ERR_PTR(rc); @@ -155,7 +162,7 @@ struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, put_device(dev); return ERR_PTR(rc); } -EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, "CXL"); +EXPORT_SYMBOL_FOR_MODULES(__devm_cxl_add_nvdimm_bridge, "cxl_pmem"); static void cxl_nvdimm_release(struct device *dev) { @@ -198,7 +205,7 @@ static struct cxl_nvdimm *cxl_nvdimm_alloc(struct cxl_nvdimm_bridge *cxl_nvb, struct cxl_nvdimm *cxl_nvd; struct device *dev; - cxl_nvd = kzalloc(sizeof(*cxl_nvd), GFP_KERNEL); + cxl_nvd = kzalloc_obj(*cxl_nvd); if (!cxl_nvd) return ERR_PTR(-ENOMEM); @@ -255,6 +262,21 @@ int devm_cxl_add_nvdimm(struct device *host, struct cxl_port *port, if (!cxl_nvb) return -ENODEV; + /* + * Take the uport_dev lock to guard against race of nvdimm_bus object. + * cxl_acpi_probe() registers the nvdimm_bus and is done under the + * root port uport_dev lock. + * + * Take the cxl_nvb device lock to ensure that cxl_nvb driver is in a + * consistent state. And the driver registers nvdimm_bus. + */ + guard(device)(cxl_nvb->port->uport_dev); + guard(device)(&cxl_nvb->dev); + if (!cxl_nvb->nvdimm_bus) { + rc = -ENODEV; + goto err_alloc; + } + cxl_nvd = cxl_nvdimm_alloc(cxl_nvb, cxlmd); if (IS_ERR(cxl_nvd)) { rc = PTR_ERR(cxl_nvd); diff --git a/drivers/cxl/core/pmu.c b/drivers/cxl/core/pmu.c index b3136d7664ab..57e9a99f3639 100644 --- a/drivers/cxl/core/pmu.c +++ b/drivers/cxl/core/pmu.c @@ -33,7 +33,7 @@ int devm_cxl_pmu_add(struct device *parent, struct cxl_pmu_regs *regs, struct device *dev; int rc; - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + pmu = kzalloc_obj(*pmu); if (!pmu) return -ENOMEM; diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c index fea8d5f5f331..0c5957d1d329 100644 --- a/drivers/cxl/core/port.c +++ b/drivers/cxl/core/port.c @@ -615,22 +615,8 @@ struct cxl_port *parent_port_of(struct cxl_port *port) static void unregister_port(void *_port) { struct cxl_port *port = _port; - struct cxl_port *parent = parent_port_of(port); - struct device *lock_dev; - /* - * CXL root port's and the first level of ports are unregistered - * under the platform firmware device lock, all other ports are - * unregistered while holding their parent port lock. - */ - if (!parent) - lock_dev = port->uport_dev; - else if (is_cxl_root(parent)) - lock_dev = parent->uport_dev; - else - lock_dev = &parent->dev; - - device_lock_assert(lock_dev); + device_lock_assert(port_to_host(port)); port->dead = true; device_unregister(&port->dev); } @@ -688,11 +674,11 @@ static struct cxl_port *cxl_port_alloc(struct device *uport_dev, /* No parent_dport, root cxl_port */ if (!parent_dport) { - cxl_root = kzalloc(sizeof(*cxl_root), GFP_KERNEL); + cxl_root = kzalloc_obj(*cxl_root); if (!cxl_root) return ERR_PTR(-ENOMEM); } else { - _port = kzalloc(sizeof(*port), GFP_KERNEL); + _port = kzalloc_obj(*port); if (!_port) return ERR_PTR(-ENOMEM); } @@ -1184,7 +1170,7 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev, CXL_TARGET_STRLEN) return ERR_PTR(-EINVAL); - dport = kzalloc(sizeof(*dport), GFP_KERNEL); + dport = kzalloc_obj(*dport); if (!dport) return ERR_PTR(-ENOMEM); @@ -1350,7 +1336,7 @@ static int cxl_add_ep(struct cxl_dport *dport, struct device *ep_dev) struct cxl_ep *ep; int rc; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -1427,20 +1413,11 @@ static struct device *grandparent(struct device *dev) return NULL; } -static struct device *endpoint_host(struct cxl_port *endpoint) -{ - struct cxl_port *port = to_cxl_port(endpoint->dev.parent); - - if (is_cxl_root(port)) - return port->uport_dev; - return &port->dev; -} - static void delete_endpoint(void *data) { struct cxl_memdev *cxlmd = data; struct cxl_port *endpoint = cxlmd->endpoint; - struct device *host = endpoint_host(endpoint); + struct device *host = port_to_host(endpoint); scoped_guard(device, host) { if (host->driver && !endpoint->dead) { @@ -1456,7 +1433,7 @@ static void delete_endpoint(void *data) int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint) { - struct device *host = endpoint_host(endpoint); + struct device *host = port_to_host(endpoint); struct device *dev = &cxlmd->dev; get_device(host); @@ -1790,7 +1767,16 @@ static struct cxl_dport *find_or_add_dport(struct cxl_port *port, { struct cxl_dport *dport; - device_lock_assert(&port->dev); + /* + * The port is already visible in CXL hierarchy, but it may still + * be in the process of binding to the CXL port driver at this point. + * + * port creation and driver binding are protected by the port's host + * lock, so acquire the host lock here to ensure the port has completed + * driver binding before proceeding with dport addition. + */ + guard(device)(port_to_host(port)); + guard(device)(&port->dev); dport = cxl_find_dport_by_dev(port, dport_dev); if (!dport) { dport = probe_dport(port, dport_dev); @@ -1857,13 +1843,11 @@ int devm_cxl_enumerate_ports(struct cxl_memdev *cxlmd) * RP port enumerated by cxl_acpi without dport will * have the dport added here. */ - scoped_guard(device, &port->dev) { - dport = find_or_add_dport(port, dport_dev); - if (IS_ERR(dport)) { - if (PTR_ERR(dport) == -EAGAIN) - goto retry; - return PTR_ERR(dport); - } + dport = find_or_add_dport(port, dport_dev); + if (IS_ERR(dport)) { + if (PTR_ERR(dport) == -EAGAIN) + goto retry; + return PTR_ERR(dport); } rc = cxl_add_ep(dport, &cxlmd->dev); @@ -2017,8 +2001,7 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port, if (!is_cxl_root(port)) return ERR_PTR(-EINVAL); - cxlrd = kzalloc(struct_size(cxlrd, cxlsd.target, nr_targets), - GFP_KERNEL); + cxlrd = kzalloc_flex(*cxlrd, cxlsd.target, nr_targets); if (!cxlrd) return ERR_PTR(-ENOMEM); @@ -2071,7 +2054,7 @@ struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port, if (is_cxl_root(port) || is_cxl_endpoint(port)) return ERR_PTR(-EINVAL); - cxlsd = kzalloc(struct_size(cxlsd, target, nr_targets), GFP_KERNEL); + cxlsd = kzalloc_flex(*cxlsd, target, nr_targets); if (!cxlsd) return ERR_PTR(-ENOMEM); @@ -2102,7 +2085,7 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port) if (!is_cxl_endpoint(port)) return ERR_PTR(-EINVAL); - cxled = kzalloc(sizeof(*cxled), GFP_KERNEL); + cxled = kzalloc_obj(*cxled); if (!cxled) return ERR_PTR(-ENOMEM); diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 08fa3deef70a..42874948b589 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -998,7 +998,7 @@ alloc_region_ref(struct cxl_port *port, struct cxl_region *cxlr, return ERR_PTR(-EBUSY); } - cxl_rr = kzalloc(sizeof(*cxl_rr), GFP_KERNEL); + cxl_rr = kzalloc_obj(*cxl_rr); if (!cxl_rr) return ERR_PTR(-ENOMEM); cxl_rr->port = port; @@ -1100,12 +1100,12 @@ static int cxl_rr_assign_decoder(struct cxl_port *port, struct cxl_region *cxlr, static void cxl_region_setup_flags(struct cxl_region *cxlr, struct cxl_decoder *cxld) { - if (test_bit(CXL_DECODER_F_LOCK, &cxld->flags)) { + if (cxld->flags & CXL_DECODER_F_LOCK) { set_bit(CXL_REGION_F_LOCK, &cxlr->flags); clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); } - if (test_bit(CXL_DECODER_F_NORMALIZED_ADDRESSING, &cxld->flags)) + if (cxld->flags & CXL_DECODER_F_NORMALIZED_ADDRESSING) set_bit(CXL_REGION_F_NORMALIZED_ADDRESSING, &cxlr->flags); } @@ -2474,7 +2474,7 @@ static struct cxl_region *cxl_region_alloc(struct cxl_root_decoder *cxlrd, int i struct cxl_region *cxlr; struct device *dev; - cxlr = kzalloc(sizeof(*cxlr), GFP_KERNEL); + cxlr = kzalloc_obj(*cxlr); if (!cxlr) { memregion_free(id); return ERR_PTR(-ENOMEM); @@ -3464,7 +3464,7 @@ static int cxl_pmem_region_alloc(struct cxl_region *cxlr) return -ENXIO; struct cxl_pmem_region *cxlr_pmem __free(kfree) = - kzalloc(struct_size(cxlr_pmem, mapping, p->nr_targets), GFP_KERNEL); + kzalloc_flex(*cxlr_pmem, mapping, p->nr_targets); if (!cxlr_pmem) return -ENOMEM; @@ -3552,7 +3552,7 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr) if (p->state != CXL_CONFIG_COMMIT) return ERR_PTR(-ENXIO); - cxlr_dax = kzalloc(sizeof(*cxlr_dax), GFP_KERNEL); + cxlr_dax = kzalloc_obj(*cxlr_dax); if (!cxlr_dax) return ERR_PTR(-ENOMEM); @@ -3835,7 +3835,7 @@ static int __construct_region(struct cxl_region *cxlr, set_bit(CXL_REGION_F_AUTO, &cxlr->flags); cxlr->hpa_range = *hpa_range; - res = kmalloc(sizeof(*res), GFP_KERNEL); + res = kmalloc_obj(*res); if (!res) return -ENOMEM; diff --git a/drivers/cxl/cxl.h b/drivers/cxl/cxl.h index 04c673e7cdb0..9b947286eb9b 100644 --- a/drivers/cxl/cxl.h +++ b/drivers/cxl/cxl.h @@ -574,11 +574,16 @@ struct cxl_nvdimm_bridge { #define CXL_DEV_ID_LEN 19 +enum { + CXL_NVD_F_INVALIDATED = 0, +}; + struct cxl_nvdimm { struct device dev; struct cxl_memdev *cxlmd; u8 dev_id[CXL_DEV_ID_LEN]; /* for nvdimm, string of 'serial' */ u64 dirty_shutdowns; + unsigned long flags; }; struct cxl_pmem_region_mapping { @@ -920,6 +925,8 @@ void cxl_driver_unregister(struct cxl_driver *cxl_drv); struct cxl_nvdimm_bridge *to_cxl_nvdimm_bridge(struct device *dev); struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, struct cxl_port *port); +struct cxl_nvdimm_bridge *__devm_cxl_add_nvdimm_bridge(struct device *host, + struct cxl_port *port); struct cxl_nvdimm *to_cxl_nvdimm(struct device *dev); bool is_cxl_nvdimm(struct device *dev); int devm_cxl_add_nvdimm(struct device *host, struct cxl_port *port, diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c index e197883690ef..082ec0f1c3a0 100644 --- a/drivers/cxl/pmem.c +++ b/drivers/cxl/pmem.c @@ -13,6 +13,20 @@ static __read_mostly DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX); +/** + * devm_cxl_add_nvdimm_bridge() - add the root of a LIBNVDIMM topology + * @host: platform firmware root device + * @port: CXL port at the root of a CXL topology + * + * Return: bridge device that can host cxl_nvdimm objects + */ +struct cxl_nvdimm_bridge *devm_cxl_add_nvdimm_bridge(struct device *host, + struct cxl_port *port) +{ + return __devm_cxl_add_nvdimm_bridge(host, port); +} +EXPORT_SYMBOL_NS_GPL(devm_cxl_add_nvdimm_bridge, "CXL"); + static void clear_exclusive(void *mds) { clear_exclusive_cxl_commands(mds, exclusive_cmds); @@ -129,6 +143,9 @@ static int cxl_nvdimm_probe(struct device *dev) struct nvdimm *nvdimm; int rc; + if (test_bit(CXL_NVD_F_INVALIDATED, &cxl_nvd->flags)) + return -EBUSY; + set_exclusive_cxl_commands(mds, exclusive_cmds); rc = devm_add_action_or_reset(dev, clear_exclusive, mds); if (rc) @@ -234,7 +251,7 @@ static int cxl_pmem_set_config_data(struct cxl_memdev_state *mds, return -EINVAL; set_lsa = - kvzalloc(struct_size(set_lsa, data, cmd->in_length), GFP_KERNEL); + kvzalloc_flex(*set_lsa, data, cmd->in_length); if (!set_lsa) return -ENOMEM; @@ -309,8 +326,10 @@ static int detach_nvdimm(struct device *dev, void *data) scoped_guard(device, dev) { if (dev->driver) { cxl_nvd = to_cxl_nvdimm(dev); - if (cxl_nvd->cxlmd && cxl_nvd->cxlmd->cxl_nvb == data) + if (cxl_nvd->cxlmd && cxl_nvd->cxlmd->cxl_nvb == data) { release = true; + set_bit(CXL_NVD_F_INVALIDATED, &cxl_nvd->flags); + } } } if (release) @@ -353,6 +372,7 @@ static struct cxl_driver cxl_nvdimm_bridge_driver = { .probe = cxl_nvdimm_bridge_probe, .id = CXL_DEVICE_NVDIMM_BRIDGE, .drv = { + .probe_type = PROBE_FORCE_SYNCHRONOUS, .suppress_bind_attrs = true, }, }; @@ -426,7 +446,7 @@ static int cxl_pmem_region_probe(struct device *dev) set_bit(ND_REGION_CXL, &ndr_desc.flags); set_bit(ND_REGION_PERSIST_MEMCTRL, &ndr_desc.flags); - info = kmalloc_array(cxlr_pmem->nr_mappings, sizeof(*info), GFP_KERNEL); + info = kmalloc_objs(*info, cxlr_pmem->nr_mappings); if (!info) return -ENOMEM; diff --git a/drivers/dax/bus.c b/drivers/dax/bus.c index fde29e0ad68b..c94c09622516 100644 --- a/drivers/dax/bus.c +++ b/drivers/dax/bus.c @@ -110,7 +110,7 @@ static ssize_t do_id_store(struct device_driver *drv, const char *buf, dax_id = __dax_match_id(dax_drv, buf); if (!dax_id) { if (action == ID_ADD) { - dax_id = kzalloc(sizeof(*dax_id), GFP_KERNEL); + dax_id = kzalloc_obj(*dax_id); if (dax_id) { strscpy(dax_id->dev_name, buf, DAX_NAME_LEN); list_add(&dax_id->list, &dax_drv->ids); @@ -650,7 +650,7 @@ struct dax_region *alloc_dax_region(struct device *parent, int region_id, || !IS_ALIGNED(range_len(range), align)) return NULL; - dax_region = kzalloc(sizeof(*dax_region), GFP_KERNEL); + dax_region = kzalloc_obj(*dax_region); if (!dax_region) return NULL; @@ -807,7 +807,7 @@ static int devm_register_dax_mapping(struct dev_dax *dev_dax, int range_id) "region disabled\n")) return -ENXIO; - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) return -ENOMEM; mapping->range_id = range_id; @@ -1427,7 +1427,7 @@ static struct dev_dax *__devm_create_dev_dax(struct dev_dax_data *data) struct device *dev; int rc; - dev_dax = kzalloc(sizeof(*dev_dax), GFP_KERNEL); + dev_dax = kzalloc_obj(*dev_dax); if (!dev_dax) return ERR_PTR(-ENOMEM); diff --git a/drivers/dax/device.c b/drivers/dax/device.c index 22999a402e02..528e81240c4d 100644 --- a/drivers/dax/device.c +++ b/drivers/dax/device.c @@ -13,7 +13,7 @@ #include "dax-private.h" #include "bus.h" -static int __check_vma(struct dev_dax *dev_dax, vm_flags_t vm_flags, +static int __check_vma(struct dev_dax *dev_dax, vma_flags_t flags, unsigned long start, unsigned long end, struct file *file, const char *func) { @@ -24,7 +24,7 @@ static int __check_vma(struct dev_dax *dev_dax, vm_flags_t vm_flags, return -ENXIO; /* prevent private mappings from being established */ - if ((vm_flags & VM_MAYSHARE) != VM_MAYSHARE) { + if (!vma_flags_test(&flags, VMA_MAYSHARE_BIT)) { dev_info_ratelimited(dev, "%s: %s: fail, attempted private mapping\n", current->comm, func); @@ -53,7 +53,7 @@ static int __check_vma(struct dev_dax *dev_dax, vm_flags_t vm_flags, static int check_vma(struct dev_dax *dev_dax, struct vm_area_struct *vma, const char *func) { - return __check_vma(dev_dax, vma->vm_flags, vma->vm_start, vma->vm_end, + return __check_vma(dev_dax, vma->flags, vma->vm_start, vma->vm_end, vma->vm_file, func); } @@ -306,14 +306,14 @@ static int dax_mmap_prepare(struct vm_area_desc *desc) * fault time. */ id = dax_read_lock(); - rc = __check_vma(dev_dax, desc->vm_flags, desc->start, desc->end, filp, + rc = __check_vma(dev_dax, desc->vma_flags, desc->start, desc->end, filp, __func__); dax_read_unlock(id); if (rc) return rc; desc->vm_ops = &dax_vm_ops; - desc->vm_flags |= VM_HUGEPAGE; + vma_desc_set_flags(desc, VMA_HUGEPAGE_BIT); return 0; } diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c index c036e4d0b610..2cc8749bc871 100644 --- a/drivers/dax/kmem.c +++ b/drivers/dax/kmem.c @@ -121,7 +121,7 @@ static int dev_dax_kmem_probe(struct dev_dax *dev_dax) init_node_memory_type(numa_node, mtype); rc = -ENOMEM; - data = kzalloc(struct_size(data, res, dev_dax->nr_range), GFP_KERNEL); + data = kzalloc_flex(*data, res, dev_dax->nr_range); if (!data) goto err_dax_kmem_data; diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c index f5cedf816be1..583510850fad 100644 --- a/drivers/dca/dca-core.c +++ b/drivers/dca/dca-core.c @@ -44,7 +44,7 @@ static struct dca_domain *dca_allocate_domain(struct pci_bus *rc) { struct dca_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_NOWAIT); + domain = kzalloc_obj(*domain, GFP_NOWAIT); if (!domain) return NULL; diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c index 70219099c604..179de3cf6d6c 100644 --- a/drivers/devfreq/devfreq-event.c +++ b/drivers/devfreq/devfreq-event.c @@ -313,7 +313,7 @@ struct devfreq_event_dev *devfreq_event_add_edev(struct device *dev, if (!desc->ops->set_event || !desc->ops->get_event) return ERR_PTR(-EINVAL); - edev = kzalloc(sizeof(struct devfreq_event_dev), GFP_KERNEL); + edev = kzalloc_obj(struct devfreq_event_dev); if (!edev) return ERR_PTR(-ENOMEM); diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 00979f2e0e27..c0a74091b904 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -821,7 +821,7 @@ struct devfreq *devfreq_add_device(struct device *dev, goto err_out; } - devfreq = kzalloc(sizeof(struct devfreq), GFP_KERNEL); + devfreq = kzalloc_obj(struct devfreq); if (!devfreq) { err = -ENOMEM; goto err_out; diff --git a/drivers/devfreq/governor_passive.c b/drivers/devfreq/governor_passive.c index 8cd6f9a59f64..d7feecd900f1 100644 --- a/drivers/devfreq/governor_passive.c +++ b/drivers/devfreq/governor_passive.c @@ -310,8 +310,7 @@ static int cpufreq_passive_register_notifier(struct devfreq *devfreq) continue; } - parent_cpu_data = kzalloc(sizeof(*parent_cpu_data), - GFP_KERNEL); + parent_cpu_data = kzalloc_obj(*parent_cpu_data); if (!parent_cpu_data) { ret = -ENOMEM; goto err_put_policy; diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 395174f93960..3906ebedbae8 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -87,8 +87,7 @@ static const struct attribute_group dev_attr_group = { static int userspace_init(struct devfreq *devfreq) { int err = 0; - struct userspace_data *data = kzalloc(sizeof(struct userspace_data), - GFP_KERNEL); + struct userspace_data *data = kzalloc_obj(struct userspace_data); if (!data) { err = -ENOMEM; diff --git a/drivers/dibs/dibs_loopback.c b/drivers/dibs/dibs_loopback.c index aa029e29c6b2..ec3b48cb0e87 100644 --- a/drivers/dibs/dibs_loopback.c +++ b/drivers/dibs/dibs_loopback.c @@ -64,7 +64,7 @@ static int dibs_lo_register_dmb(struct dibs_dev *dibs, struct dibs_dmb *dmb, if (sba_idx == DIBS_LO_MAX_DMBS) return -ENOSPC; - dmb_node = kzalloc(sizeof(*dmb_node), GFP_KERNEL); + dmb_node = kzalloc_obj(*dmb_node); if (!dmb_node) { rc = -ENOMEM; goto err_bit; @@ -303,7 +303,7 @@ static int dibs_lo_dev_probe(void) struct dibs_dev *dibs; int ret; - ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + ldev = kzalloc_obj(*ldev); if (!ldev) return -ENOMEM; diff --git a/drivers/dibs/dibs_main.c b/drivers/dibs/dibs_main.c index b8c16586706c..f1816361b74d 100644 --- a/drivers/dibs/dibs_main.c +++ b/drivers/dibs/dibs_main.c @@ -133,7 +133,7 @@ struct dibs_dev *dibs_dev_alloc(void) { struct dibs_dev *dibs; - dibs = kzalloc(sizeof(*dibs), GFP_KERNEL); + dibs = kzalloc_obj(*dibs); if (!dibs) return dibs; dibs->dev.release = dibs_dev_release; diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c index 0a051d656880..419b3c13d491 100644 --- a/drivers/dio/dio.c +++ b/drivers/dio/dio.c @@ -221,7 +221,7 @@ static int __init dio_init(void) } /* Found a board, allocate it an entry in the list */ - dev = kzalloc(sizeof(struct dio_dev), GFP_KERNEL); + dev = kzalloc_obj(struct dio_dev); if (!dev) { if (scode >= DIOII_SCBASE) iounmap(va); diff --git a/drivers/dma-buf/dma-buf-mapping.c b/drivers/dma-buf/dma-buf-mapping.c index 174677faa577..794acff2546a 100644 --- a/drivers/dma-buf/dma-buf-mapping.c +++ b/drivers/dma-buf/dma-buf-mapping.c @@ -108,7 +108,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach, /* This function is supposed to work on MMIO memory only */ return ERR_PTR(-EINVAL); - dma = kzalloc(sizeof(*dma), GFP_KERNEL); + dma = kzalloc_obj(*dma); if (!dma) return ERR_PTR(-ENOMEM); @@ -119,7 +119,7 @@ struct sg_table *dma_buf_phys_vec_to_sgt(struct dma_buf_attachment *attach, */ break; case PCI_P2PDMA_MAP_THRU_HOST_BRIDGE: - dma->state = kzalloc(sizeof(*dma->state), GFP_KERNEL); + dma->state = kzalloc_obj(*dma->state); if (!dma->state) { ret = -ENOMEM; goto err_free_dma; diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 77555096e4c7..11711874a325 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -866,7 +866,7 @@ static int dma_buf_wrap_sg_table(struct sg_table **sg_table) * sg_table without copying the page_link and give only the copy back to * the importer. */ - to = kzalloc(sizeof(*to), GFP_KERNEL); + to = kzalloc_obj(*to); if (!to) return -ENOMEM; @@ -1020,7 +1020,7 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev, if (WARN_ON(importer_ops && !importer_ops->move_notify)) return ERR_PTR(-EINVAL); - attach = kzalloc(sizeof(*attach), GFP_KERNEL); + attach = kzalloc_obj(*attach); if (!attach) return ERR_PTR(-ENOMEM); diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c index 6657d4b30af9..37e2c6179d77 100644 --- a/drivers/dma-buf/dma-fence-array.c +++ b/drivers/dma-buf/dma-fence-array.c @@ -179,7 +179,7 @@ struct dma_fence_array *dma_fence_array_alloc(int num_fences) { struct dma_fence_array *array; - return kzalloc(struct_size(array, callbacks, num_fences), GFP_KERNEL); + return kzalloc_flex(*array, callbacks, num_fences); } EXPORT_SYMBOL(dma_fence_array_alloc); diff --git a/drivers/dma-buf/dma-fence-unwrap.c b/drivers/dma-buf/dma-fence-unwrap.c index a495d8a6c2e3..07fe9bf45aea 100644 --- a/drivers/dma-buf/dma-fence-unwrap.c +++ b/drivers/dma-buf/dma-fence-unwrap.c @@ -155,7 +155,7 @@ struct dma_fence *__dma_fence_unwrap_merge(unsigned int num_fences, dma_fence_put(unsignaled); - array = kmalloc_array(count, sizeof(*array), GFP_KERNEL); + array = kmalloc_objs(*array, count); if (!array) return NULL; diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c index 21c5c30b4f34..35afcfcac591 100644 --- a/drivers/dma-buf/dma-fence.c +++ b/drivers/dma-buf/dma-fence.c @@ -156,7 +156,7 @@ struct dma_fence *dma_fence_allocate_private_stub(ktime_t timestamp) { struct dma_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (fence == NULL) return NULL; @@ -905,7 +905,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, return 0; } - cb = kcalloc(count, sizeof(struct default_wait_cb), GFP_KERNEL); + cb = kzalloc_objs(struct default_wait_cb, count); if (cb == NULL) { ret = -ENOMEM; goto err_free_cb; diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index d230ddeb24e0..ac5f8685a649 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -244,7 +244,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) return ERR_PTR(-EINVAL); } - heap = kzalloc(sizeof(*heap), GFP_KERNEL); + heap = kzalloc_obj(*heap); if (!heap) return ERR_PTR(-ENOMEM); diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index 49cc45fb42dd..bd3370b9a3f6 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -74,7 +74,7 @@ static int cma_heap_attach(struct dma_buf *dmabuf, struct dma_heap_attachment *a; int ret; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return -ENOMEM; @@ -308,7 +308,7 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap, int ret = -ENOMEM; pgoff_t pg; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return ERR_PTR(-ENOMEM); @@ -346,7 +346,7 @@ static struct dma_buf *cma_heap_allocate(struct dma_heap *heap, memset(page_address(cma_pages), 0, size); } - buffer->pages = kmalloc_array(pagecount, sizeof(*buffer->pages), GFP_KERNEL); + buffer->pages = kmalloc_objs(*buffer->pages, pagecount); if (!buffer->pages) { ret = -ENOMEM; goto free_cma; @@ -391,7 +391,7 @@ static int __init __add_cma_heap(struct cma *cma, const char *name) struct dma_heap_export_info exp_info; struct cma_heap *cma_heap; - cma_heap = kzalloc(sizeof(*cma_heap), GFP_KERNEL); + cma_heap = kzalloc_obj(*cma_heap); if (!cma_heap) return -ENOMEM; cma_heap->cma = cma; diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 4049d042afa1..b3650d8fd651 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -77,7 +77,7 @@ static int system_heap_attach(struct dma_buf *dmabuf, struct dma_heap_attachment *a; int ret; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return -ENOMEM; @@ -354,7 +354,7 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap, struct page *page, *tmp_page; int i, ret = -ENOMEM; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return ERR_PTR(-ENOMEM); diff --git a/drivers/dma-buf/st-dma-fence-chain.c b/drivers/dma-buf/st-dma-fence-chain.c index ed4b323886e4..821023dd34df 100644 --- a/drivers/dma-buf/st-dma-fence-chain.c +++ b/drivers/dma-buf/st-dma-fence-chain.c @@ -116,13 +116,11 @@ static int fence_chains_init(struct fence_chains *fc, unsigned int count, unsigned int i; int err = 0; - fc->chains = kvmalloc_array(count, sizeof(*fc->chains), - GFP_KERNEL | __GFP_ZERO); + fc->chains = kvmalloc_objs(*fc->chains, count, GFP_KERNEL | __GFP_ZERO); if (!fc->chains) return -ENOMEM; - fc->fences = kvmalloc_array(count, sizeof(*fc->fences), - GFP_KERNEL | __GFP_ZERO); + fc->fences = kvmalloc_objs(*fc->fences, count, GFP_KERNEL | __GFP_ZERO); if (!fc->fences) { err = -ENOMEM; goto err_chains; @@ -452,7 +450,7 @@ static int find_race(void *arg) if (err) return err; - threads = kmalloc_array(ncpus, sizeof(*threads), GFP_KERNEL); + threads = kmalloc_objs(*threads, ncpus); if (!threads) { err = -ENOMEM; goto err; diff --git a/drivers/dma-buf/st-dma-fence-unwrap.c b/drivers/dma-buf/st-dma-fence-unwrap.c index a3be888ae2e8..9c74195f47fd 100644 --- a/drivers/dma-buf/st-dma-fence-unwrap.c +++ b/drivers/dma-buf/st-dma-fence-unwrap.c @@ -32,7 +32,7 @@ static struct dma_fence *__mock_fence(u64 context, u64 seqno) { struct mock_fence *f; - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc_obj(*f); if (!f) return NULL; @@ -54,7 +54,7 @@ static struct dma_fence *mock_array(unsigned int num_fences, ...) va_list valist; int i; - fences = kcalloc(num_fences, sizeof(*fences), GFP_KERNEL); + fences = kzalloc_objs(*fences, num_fences); if (!fences) goto error_put; diff --git a/drivers/dma-buf/st-dma-resv.c b/drivers/dma-buf/st-dma-resv.c index 15dbea1462ed..ad4dfb49dcd9 100644 --- a/drivers/dma-buf/st-dma-resv.c +++ b/drivers/dma-buf/st-dma-resv.c @@ -27,7 +27,7 @@ static struct dma_fence *alloc_fence(void) { struct dma_fence *f; - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc_obj(*f); if (!f) return NULL; diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index 6f09d13be6b6..963a72324d16 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -101,7 +101,7 @@ static struct sync_timeline *sync_timeline_create(const char *name) { struct sync_timeline *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; @@ -252,7 +252,7 @@ static struct sync_pt *sync_pt_create(struct sync_timeline *obj, { struct sync_pt *pt; - pt = kzalloc(sizeof(*pt), GFP_KERNEL); + pt = kzalloc_obj(*pt); if (!pt) return NULL; diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 747e377fb954..2166bbdf7e4a 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -24,7 +24,7 @@ static struct sync_file *sync_file_alloc(void) { struct sync_file *sync_file; - sync_file = kzalloc(sizeof(*sync_file), GFP_KERNEL); + sync_file = kzalloc_obj(*sync_file); if (!sync_file) return NULL; diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index 40399c26e6be..94b8ecb892bb 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -115,7 +115,7 @@ static int vmap_udmabuf(struct dma_buf *buf, struct iosys_map *map) dma_resv_assert_held(buf->resv); - pages = kvmalloc_array(ubuf->pagecount, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, ubuf->pagecount); if (!pages) return -ENOMEM; @@ -150,7 +150,7 @@ static struct sg_table *get_sg_table(struct device *dev, struct dma_buf *buf, unsigned int i = 0; int ret; - sg = kzalloc(sizeof(*sg), GFP_KERNEL); + sg = kzalloc_obj(*sg); if (!sg) return ERR_PTR(-ENOMEM); @@ -207,17 +207,15 @@ static void unpin_all_folios(struct udmabuf *ubuf) static __always_inline int init_udmabuf(struct udmabuf *ubuf, pgoff_t pgcnt) { - ubuf->folios = kvmalloc_array(pgcnt, sizeof(*ubuf->folios), GFP_KERNEL); + ubuf->folios = kvmalloc_objs(*ubuf->folios, pgcnt); if (!ubuf->folios) return -ENOMEM; - ubuf->offsets = kvcalloc(pgcnt, sizeof(*ubuf->offsets), GFP_KERNEL); + ubuf->offsets = kvzalloc_objs(*ubuf->offsets, pgcnt); if (!ubuf->offsets) return -ENOMEM; - ubuf->pinned_folios = kvmalloc_array(pgcnt, - sizeof(*ubuf->pinned_folios), - GFP_KERNEL); + ubuf->pinned_folios = kvmalloc_objs(*ubuf->pinned_folios, pgcnt); if (!ubuf->pinned_folios) return -ENOMEM; diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 8bb0a119ecd4..66cda7cc9f7a 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -590,7 +590,7 @@ config STE_DMA40 config ST_FDMA tristate "ST FDMA dmaengine support" - depends on ARCH_STI + depends on ARCH_STI || COMPILE_TEST depends on REMOTEPROC select ST_SLIM_REMOTEPROC select DMA_ENGINE diff --git a/drivers/dma/acpi-dma.c b/drivers/dma/acpi-dma.c index 2abbe11e797e..be73021ecbd6 100644 --- a/drivers/dma/acpi-dma.c +++ b/drivers/dma/acpi-dma.c @@ -189,7 +189,7 @@ int acpi_dma_controller_register(struct device *dev, if (!adev) return -EINVAL; - adma = kzalloc(sizeof(*adma), GFP_KERNEL); + adma = kzalloc_obj(*adma); if (!adma) return -ENOMEM; diff --git a/drivers/dma/altera-msgdma.c b/drivers/dma/altera-msgdma.c index a203fdd84950..b46999c81df0 100644 --- a/drivers/dma/altera-msgdma.c +++ b/drivers/dma/altera-msgdma.c @@ -396,13 +396,11 @@ msgdma_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, void *desc = NULL; size_t len, avail; dma_addr_t dma_dst, dma_src; - u32 desc_cnt = 0, i; - struct scatterlist *sg; + u32 desc_cnt; u32 stride; unsigned long irqflags; - for_each_sg(sgl, sg, sg_len, i) - desc_cnt += DIV_ROUND_UP(sg_dma_len(sg), MSGDMA_MAX_TRANS_LEN); + desc_cnt = sg_nents_for_dma(sgl, sg_len, MSGDMA_MAX_TRANS_LEN); spin_lock_irqsave(&mdev->lock, irqflags); if (desc_cnt > mdev->desc_free_cnt) { @@ -659,7 +657,7 @@ static int msgdma_alloc_chan_resources(struct dma_chan *dchan) struct msgdma_sw_desc *desc; int i; - mdev->sw_desq = kcalloc(MSGDMA_DESC_NUM, sizeof(*desc), GFP_NOWAIT); + mdev->sw_desq = kzalloc_objs(*desc, MSGDMA_DESC_NUM, GFP_NOWAIT); if (!mdev->sw_desq) return -ENOMEM; diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 38cdbca59485..5e88fd44812d 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -1010,7 +1010,7 @@ static inline u32 pl08x_lli_control_bits(struct pl08x_driver_data *pl08x, /* * Remove all src, dst and transfer size bits, then set the * width and size according to the parameters. The bit offsets - * are different in the FTDMAC020 so we need to accound for this. + * are different in the FTDMAC020 so we need to account for this. */ if (pl08x->vd->ftdmac020) { retbits &= ~FTDMAC020_LLI_DST_WIDTH_MSK; @@ -1743,7 +1743,7 @@ static void pl08x_issue_pending(struct dma_chan *chan) static struct pl08x_txd *pl08x_get_txd(struct pl08x_dma_chan *plchan) { - struct pl08x_txd *txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + struct pl08x_txd *txd = kzalloc_obj(*txd, GFP_NOWAIT); if (txd) INIT_LIST_HEAD(&txd->dsg_list); @@ -1895,7 +1895,7 @@ static struct dma_async_tx_descriptor *pl08x_prep_dma_memcpy( return NULL; } - dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT); + dsg = kzalloc_obj(struct pl08x_sg, GFP_NOWAIT); if (!dsg) { pl08x_free_txd(pl08x, txd); return NULL; @@ -2020,7 +2020,7 @@ static int pl08x_tx_add_sg(struct pl08x_txd *txd, { struct pl08x_sg *dsg; - dsg = kzalloc(sizeof(struct pl08x_sg), GFP_NOWAIT); + dsg = kzalloc_obj(struct pl08x_sg, GFP_NOWAIT); if (!dsg) return -ENOMEM; @@ -2372,7 +2372,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, * to cope with that situation. */ for (i = 0; i < channels; i++) { - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return -ENOMEM; @@ -2390,7 +2390,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x, chan->signal = i; pl08x_dma_slave_init(chan); } else { - chan->cd = kzalloc(sizeof(*chan->cd), GFP_KERNEL); + chan->cd = kzalloc_obj(*chan->cd); if (!chan->cd) { kfree(chan); return -ENOMEM; @@ -2709,7 +2709,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) goto out_no_pl08x; /* Create the driver state holder */ - pl08x = kzalloc(sizeof(*pl08x), GFP_KERNEL); + pl08x = kzalloc_obj(*pl08x); if (!pl08x) { ret = -ENOMEM; goto out_no_pl08x; @@ -2855,8 +2855,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) } /* Initialize physical channels */ - pl08x->phy_chans = kcalloc(vd->channels, sizeof(*pl08x->phy_chans), - GFP_KERNEL); + pl08x->phy_chans = kzalloc_objs(*pl08x->phy_chans, vd->channels); if (!pl08x->phy_chans) { ret = -ENOMEM; goto out_no_phychans; @@ -2978,7 +2977,7 @@ static int pl08x_probe(struct amba_device *adev, const struct amba_id *id) return ret; } -/* PL080 has 8 channels and the PL080 have just 2 */ +/* PL080 has 8 channels and the PL081 have just 2 */ static struct vendor_data vendor_pl080 = { .config_offset = PL080_CH_CONFIG, .channels = 8, diff --git a/drivers/dma/amd/qdma/qdma.c b/drivers/dma/amd/qdma/qdma.c index 8fb2d5e1df20..f5a02c6ed348 100644 --- a/drivers/dma/amd/qdma/qdma.c +++ b/drivers/dma/amd/qdma/qdma.c @@ -769,7 +769,7 @@ qdma_prep_device_sg(struct dma_chan *chan, struct scatterlist *sgl, struct dma_async_tx_descriptor *tx; struct qdma_mm_vdesc *vdesc; - vdesc = kzalloc(sizeof(*vdesc), GFP_NOWAIT); + vdesc = kzalloc_obj(*vdesc, GFP_NOWAIT); if (!vdesc) return NULL; vdesc->sgl = sgl; diff --git a/drivers/dma/apple-admac.c b/drivers/dma/apple-admac.c index 04bbd774b3b4..14a5ee14a481 100644 --- a/drivers/dma/apple-admac.c +++ b/drivers/dma/apple-admac.c @@ -260,7 +260,7 @@ static struct dma_async_tx_descriptor *admac_prep_dma_cyclic( if (direction != admac_chan_direction(adchan->no)) return NULL; - adtx = kzalloc(sizeof(*adtx), GFP_NOWAIT); + adtx = kzalloc_obj(*adtx, GFP_NOWAIT); if (!adtx) return NULL; diff --git a/drivers/dma/arm-dma350.c b/drivers/dma/arm-dma350.c index 9efe2ca7d5ec..84220fa83029 100644 --- a/drivers/dma/arm-dma350.c +++ b/drivers/dma/arm-dma350.c @@ -219,7 +219,7 @@ static struct dma_async_tx_descriptor *d350_prep_memcpy(struct dma_chan *chan, struct d350_desc *desc; u32 *cmd; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; @@ -257,7 +257,7 @@ static struct dma_async_tx_descriptor *d350_prep_memset(struct dma_chan *chan, struct d350_desc *desc; u32 *cmd; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index 22bb604a3f97..e5b30a57c477 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -929,7 +929,7 @@ atc_prep_dma_interleaved(struct dma_chan *chan, ATC_SRC_PIP | ATC_DST_PIP | FIELD_PREP(ATC_FC, ATC_FC_MEM2MEM); - desc = kzalloc(struct_size(desc, sg, 1), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, 1, GFP_ATOMIC); if (!desc) return NULL; desc->sglen = 1; @@ -992,7 +992,7 @@ atc_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, } sg_len = DIV_ROUND_UP(len, ATC_BTSIZE_MAX); - desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, sg_len, GFP_ATOMIC); if (!desc) return NULL; desc->sglen = sg_len; @@ -1131,7 +1131,7 @@ atc_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value, (fill_pattern << 8) | fill_pattern; - desc = kzalloc(struct_size(desc, sg, 1), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, 1, GFP_ATOMIC); if (!desc) goto err_free_buffer; desc->sglen = 1; @@ -1191,7 +1191,7 @@ atc_prep_dma_memset_sg(struct dma_chan *chan, } *(u32*)vaddr = value; - desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, sg_len, GFP_ATOMIC); if (!desc) goto err_free_dma_buf; desc->sglen = sg_len; @@ -1274,7 +1274,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - desc = kzalloc(struct_size(desc, sg, sg_len), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, sg_len, GFP_ATOMIC); if (!desc) return NULL; desc->sglen = sg_len; @@ -1531,7 +1531,7 @@ atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, if (atc_dma_cyclic_check_values(reg_width, buf_addr, period_len)) goto err_out; - desc = kzalloc(struct_size(desc, sg, periods), GFP_ATOMIC); + desc = kzalloc_flex(*desc, sg, periods, GFP_ATOMIC); if (!desc) goto err_out; desc->sglen = periods; @@ -1818,7 +1818,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec, dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - atslave = kmalloc(sizeof(*atslave), GFP_KERNEL); + atslave = kmalloc_obj(*atslave); if (!atslave) { put_device(&dmac_pdev->dev); return NULL; diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c index 3fbc74710a13..901971e8bae6 100644 --- a/drivers/dma/at_xdmac.c +++ b/drivers/dma/at_xdmac.c @@ -379,7 +379,6 @@ static void at_xdmac_runtime_suspend_descriptors(struct at_xdmac_chan *atchan) if (!desc->active_xfer) continue; - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); } } @@ -413,7 +412,6 @@ static bool at_xdmac_chan_is_enabled(struct at_xdmac_chan *atchan) ret = !!(at_xdmac_chan_read(atchan, AT_XDMAC_GS) & atchan->mask); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return ret; @@ -446,7 +444,6 @@ static void at_xdmac_off(struct at_xdmac *atxdmac, bool suspend_descriptors) } } - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); } @@ -1676,7 +1673,6 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, spin_unlock: spin_unlock_irqrestore(&atchan->lock, flags); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return ret; } @@ -1758,7 +1754,6 @@ static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) __func__, &bad_desc->lld.mbr_sa, &bad_desc->lld.mbr_da, bad_desc->lld.mbr_ubc); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); /* Then continue with usual descriptor management */ @@ -1822,7 +1817,6 @@ static void at_xdmac_tasklet(struct tasklet_struct *t) * Decrement runtime PM ref counter incremented in * at_xdmac_start_xfer(). */ - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); } @@ -1954,7 +1948,6 @@ static int at_xdmac_device_pause(struct dma_chan *chan) spin_unlock_irqrestore(&atchan->lock, flags); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return 0; @@ -1998,7 +1991,6 @@ static int at_xdmac_device_resume(struct dma_chan *chan) unlock: spin_unlock_irqrestore(&atchan->lock, flags); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return ret; @@ -2041,7 +2033,6 @@ static int at_xdmac_device_terminate_all(struct dma_chan *chan) clear_bit(AT_XDMAC_CHAN_IS_CYCLIC, &atchan->status); spin_unlock_irqrestore(&atchan->lock, flags); - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return 0; @@ -2235,7 +2226,6 @@ static int __maybe_unused atmel_xdmac_resume(struct device *dev) } } - pm_runtime_mark_last_busy(atxdmac->dev); pm_runtime_put_autosuspend(atxdmac->dev); return 0; @@ -2257,12 +2247,29 @@ static int __maybe_unused atmel_xdmac_runtime_resume(struct device *dev) return clk_enable(atxdmac->clk); } +static inline int at_xdmac_get_channel_number(struct platform_device *pdev, + u32 reg, u32 *pchannels) +{ + int ret; + + if (reg) { + *pchannels = AT_XDMAC_NB_CH(reg); + return 0; + } + + ret = of_property_read_u32(pdev->dev.of_node, "dma-channels", pchannels); + if (ret) + dev_err(&pdev->dev, "can't get number of channels\n"); + + return ret; +} + static int at_xdmac_probe(struct platform_device *pdev) { struct at_xdmac *atxdmac; - int irq, nr_channels, i, ret; + int irq, ret; void __iomem *base; - u32 reg; + u32 nr_channels, i, reg; irq = platform_get_irq(pdev, 0); if (irq < 0) @@ -2278,7 +2285,10 @@ static int at_xdmac_probe(struct platform_device *pdev) * of channels to do the allocation. */ reg = readl_relaxed(base + AT_XDMAC_GTYPE); - nr_channels = AT_XDMAC_NB_CH(reg); + ret = at_xdmac_get_channel_number(pdev, reg, &nr_channels); + if (ret) + return ret; + if (nr_channels > AT_XDMAC_MAX_CHAN) { dev_err(&pdev->dev, "invalid number of channels (%u)\n", nr_channels); @@ -2412,7 +2422,6 @@ static int at_xdmac_probe(struct platform_device *pdev) at_xdmac_axi_config(pdev); - pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_put_autosuspend(&pdev->dev); return 0; diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 321748e2983e..06d830d36882 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -260,23 +260,6 @@ static void bcm2835_dma_create_cb_set_length( control_block->info |= finalextrainfo; } -static inline size_t bcm2835_dma_count_frames_for_sg( - struct bcm2835_chan *c, - struct scatterlist *sgl, - unsigned int sg_len) -{ - size_t frames = 0; - struct scatterlist *sgent; - unsigned int i; - size_t plength = bcm2835_dma_max_frame_length(c); - - for_each_sg(sgl, sgent, sg_len, i) - frames += bcm2835_dma_frames_for_length( - sg_dma_len(sgent), plength); - - return frames; -} - /** * bcm2835_dma_create_cb_chain - create a control block and fills data in * @@ -314,7 +297,7 @@ static struct bcm2835_desc *bcm2835_dma_create_cb_chain( return NULL; /* allocate and setup the descriptor. */ - d = kzalloc(struct_size(d, cb_list, frames), gfp); + d = kzalloc_flex(*d, cb_list, frames, gfp); if (!d) return NULL; @@ -672,7 +655,7 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_slave_sg( } /* count frames in sg list */ - frames = bcm2835_dma_count_frames_for_sg(c, sgl, sg_len); + frames = sg_nents_for_dma(sgl, sg_len, bcm2835_dma_max_frame_length(c)); /* allocate the CB chain */ d = bcm2835_dma_create_cb_chain(chan, direction, false, diff --git a/drivers/dma/bestcomm/bestcomm.c b/drivers/dma/bestcomm/bestcomm.c index 6c4d655ffe77..432b43520ddc 100644 --- a/drivers/dma/bestcomm/bestcomm.c +++ b/drivers/dma/bestcomm/bestcomm.c @@ -393,7 +393,7 @@ static int mpc52xx_bcom_probe(struct platform_device *op) } /* Get a clean struct */ - bcom_eng = kzalloc(sizeof(struct bcom_engine), GFP_KERNEL); + bcom_eng = kzalloc_obj(struct bcom_engine); if (!bcom_eng) { rv = -ENOMEM; goto error_sramclean; diff --git a/drivers/dma/bestcomm/sram.c b/drivers/dma/bestcomm/sram.c index ad74d57cc3ab..09ef5142c26c 100644 --- a/drivers/dma/bestcomm/sram.c +++ b/drivers/dma/bestcomm/sram.c @@ -48,7 +48,7 @@ int bcom_sram_init(struct device_node *sram_node, char *owner) return -EBUSY; } - bcom_sram = kmalloc(sizeof(struct bcom_sram), GFP_KERNEL); + bcom_sram = kmalloc_obj(struct bcom_sram); if (!bcom_sram) { printk(KERN_ERR "%s: bcom_sram_init: " "Couldn't allocate internal state !\n", owner); diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c index 5b06b0dc67ee..eb65872c5d5c 100644 --- a/drivers/dma/dma-axi-dmac.c +++ b/drivers/dma/dma-axi-dmac.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -69,7 +70,9 @@ #define AXI_DMAC_REG_START_TRANSFER 0x408 #define AXI_DMAC_REG_FLAGS 0x40c #define AXI_DMAC_REG_DEST_ADDRESS 0x410 +#define AXI_DMAC_REG_DEST_ADDRESS_HIGH 0x490 #define AXI_DMAC_REG_SRC_ADDRESS 0x414 +#define AXI_DMAC_REG_SRC_ADDRESS_HIGH 0x494 #define AXI_DMAC_REG_X_LENGTH 0x418 #define AXI_DMAC_REG_Y_LENGTH 0x41c #define AXI_DMAC_REG_DEST_STRIDE 0x420 @@ -233,11 +236,9 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan) unsigned int flags = 0; unsigned int val; - if (!chan->hw_sg) { - val = axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER); - if (val) /* Queue is full, wait for the next SOT IRQ */ - return; - } + val = axi_dmac_read(dmac, AXI_DMAC_REG_START_TRANSFER); + if (val) /* Queue is full, wait for the next SOT IRQ */ + return; desc = chan->next_desc; @@ -247,6 +248,7 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan) return; list_move_tail(&vdesc->node, &chan->active_descs); desc = to_axi_dmac_desc(vdesc); + chan->next_desc = desc; } sg = &desc->sg[desc->num_submitted]; @@ -265,8 +267,6 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan) else chan->next_desc = NULL; flags |= AXI_DMAC_FLAG_LAST; - } else { - chan->next_desc = desc; } sg->hw->id = axi_dmac_read(dmac, AXI_DMAC_REG_TRANSFER_ID); @@ -274,11 +274,14 @@ static void axi_dmac_start_transfer(struct axi_dmac_chan *chan) if (!chan->hw_sg) { if (axi_dmac_dest_is_mem(chan)) { axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS, sg->hw->dest_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH, + sg->hw->dest_addr >> 32); axi_dmac_write(dmac, AXI_DMAC_REG_DEST_STRIDE, sg->hw->dst_stride); } if (axi_dmac_src_is_mem(chan)) { axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS, sg->hw->src_addr); + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH, sg->hw->src_addr >> 32); axi_dmac_write(dmac, AXI_DMAC_REG_SRC_STRIDE, sg->hw->src_stride); } } @@ -537,7 +540,7 @@ axi_dmac_alloc_desc(struct axi_dmac_chan *chan, unsigned int num_sgs) dma_addr_t hw_phys; unsigned int i; - desc = kzalloc(struct_size(desc, sg, num_sgs), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg, num_sgs, GFP_NOWAIT); if (!desc) return NULL; desc->num_sgs = num_sgs; @@ -674,10 +677,7 @@ static struct dma_async_tx_descriptor *axi_dmac_prep_slave_sg( if (direction != chan->direction) return NULL; - num_sgs = 0; - for_each_sg(sgl, sg, sg_len, i) - num_sgs += DIV_ROUND_UP(sg_dma_len(sg), chan->max_length); - + num_sgs = sg_nents_for_dma(sgl, sg_len, chan->max_length); desc = axi_dmac_alloc_desc(chan, num_sgs); if (!desc) return NULL; @@ -925,22 +925,18 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan, static int axi_dmac_parse_dt(struct device *dev, struct axi_dmac *dmac) { - struct device_node *of_channels, *of_chan; int ret; - of_channels = of_get_child_by_name(dev->of_node, "adi,channels"); + struct device_node *of_channels __free(device_node) = of_get_child_by_name(dev->of_node, + "adi,channels"); if (of_channels == NULL) return -ENODEV; - for_each_child_of_node(of_channels, of_chan) { + for_each_child_of_node_scoped(of_channels, of_chan) { ret = axi_dmac_parse_chan_dt(of_chan, &dmac->chan); - if (ret) { - of_node_put(of_chan); - of_node_put(of_channels); + if (ret) return -EINVAL; - } } - of_node_put(of_channels); return 0; } @@ -993,6 +989,9 @@ static int axi_dmac_read_chan_config(struct device *dev, struct axi_dmac *dmac) static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version) { struct axi_dmac_chan *chan = &dmac->chan; + struct device *dev = dmac->dma_dev.dev; + u32 mask; + int ret; axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC); if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC) @@ -1027,6 +1026,22 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac, unsigned int version) return -ENODEV; } + if (axi_dmac_dest_is_mem(chan)) { + axi_dmac_write(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH, 0xffffffff); + mask = axi_dmac_read(dmac, AXI_DMAC_REG_DEST_ADDRESS_HIGH); + } else { + axi_dmac_write(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH, 0xffffffff); + mask = axi_dmac_read(dmac, AXI_DMAC_REG_SRC_ADDRESS_HIGH); + } + + mask = 32 + fls(mask); + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(mask)); + if (ret) { + dev_err(dev, "DMA mask set error %d\n", ret); + return ret; + } + if (version >= ADI_AXI_PCORE_VER(4, 2, 'a')) chan->hw_partial_xfer = true; diff --git a/drivers/dma/dma-jz4780.c b/drivers/dma/dma-jz4780.c index 100057603fd4..6070dfdb7114 100644 --- a/drivers/dma/dma-jz4780.c +++ b/drivers/dma/dma-jz4780.c @@ -237,7 +237,7 @@ jz4780_dma_desc_alloc(struct jz4780_dma_chan *jzchan, unsigned int count, if (count > JZ_DMA_MAX_DESC) return NULL; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index ca13cd39330b..27a8980b03dd 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -1075,7 +1075,7 @@ static int __dma_async_device_channel_register(struct dma_device *device, chan->local = alloc_percpu(typeof(*chan->local)); if (!chan->local) return -ENOMEM; - chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL); + chan->dev = kzalloc_obj(*chan->dev); if (!chan->dev) { rc = -ENOMEM; goto err_free_local; diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 91b2fbc0b864..df38681a1ff4 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -677,11 +677,11 @@ static int dmatest_func(void *data) set_user_nice(current, 10); - srcs = kcalloc(src->cnt, sizeof(dma_addr_t), GFP_KERNEL); + srcs = kzalloc_objs(dma_addr_t, src->cnt); if (!srcs) goto err_dst; - dma_pq = kcalloc(dst->cnt, sizeof(dma_addr_t), GFP_KERNEL); + dma_pq = kzalloc_objs(dma_addr_t, dst->cnt); if (!dma_pq) goto err_srcs_array; @@ -987,7 +987,7 @@ static int dmatest_add_threads(struct dmatest_info *info, return -EINVAL; for (i = 0; i < params->threads_per_chan; i++) { - thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL); + thread = kzalloc_obj(struct dmatest_thread); if (!thread) { pr_warn("No memory for %s-%s%u\n", dma_chan_name(chan), op, i); @@ -1025,7 +1025,7 @@ static int dmatest_add_channel(struct dmatest_info *info, unsigned int thread_count = 0; int cnt; - dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL); + dtc = kmalloc_obj(struct dmatest_chan); if (!dtc) { pr_warn("No memory for %s\n", dma_chan_name(chan)); return -ENOMEM; diff --git a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c index b23536645ff7..5d74bc29cf89 100644 --- a/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c +++ b/drivers/dma/dw-axi-dmac/dw-axi-dmac-platform.c @@ -293,11 +293,11 @@ static struct axi_dma_desc *axi_desc_alloc(u32 num) { struct axi_dma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; - desc->hw_desc = kcalloc(num, sizeof(*desc->hw_desc), GFP_NOWAIT); + desc->hw_desc = kzalloc_objs(*desc->hw_desc, num, GFP_NOWAIT); if (!desc->hw_desc) { kfree(desc); return NULL; @@ -850,7 +850,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, unsigned int loop = 0; struct scatterlist *sg; size_t axi_block_len; - u32 len, num_sgs = 0; + u32 len, num_sgs; unsigned int i; dma_addr_t mem; int status; @@ -867,9 +867,7 @@ dw_axi_dma_chan_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, if (axi_block_len == 0) return NULL; - for_each_sg(sgl, sg, sg_len, i) - num_sgs += DIV_ROUND_UP(sg_dma_len(sg), axi_block_len); - + num_sgs = sg_nents_for_dma(sgl, sg_len, axi_block_len); desc = axi_desc_alloc(num_sgs); if (unlikely(!desc)) goto err_desc_get; diff --git a/drivers/dma/dw-edma/dw-edma-core.c b/drivers/dma/dw-edma/dw-edma-core.c index 8e5f7defa6b6..e7d698b352d3 100644 --- a/drivers/dma/dw-edma/dw-edma-core.c +++ b/drivers/dma/dw-edma/dw-edma-core.c @@ -44,7 +44,7 @@ static struct dw_edma_burst *dw_edma_alloc_burst(struct dw_edma_chunk *chunk) { struct dw_edma_burst *burst; - burst = kzalloc(sizeof(*burst), GFP_NOWAIT); + burst = kzalloc_obj(*burst, GFP_NOWAIT); if (unlikely(!burst)) return NULL; @@ -68,7 +68,7 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc) struct dw_edma_chan *chan = desc->chan; struct dw_edma_chunk *chunk; - chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + chunk = kzalloc_obj(*chunk, GFP_NOWAIT); if (unlikely(!chunk)) return NULL; @@ -111,7 +111,7 @@ static struct dw_edma_desc *dw_edma_alloc_desc(struct dw_edma_chan *chan) { struct dw_edma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (unlikely(!desc)) return NULL; diff --git a/drivers/dma/dw-edma/dw-edma-pcie.c b/drivers/dma/dw-edma/dw-edma-pcie.c index 3371e0a76d3c..83230acaa597 100644 --- a/drivers/dma/dw-edma/dw-edma-pcie.c +++ b/drivers/dma/dw-edma/dw-edma-pcie.c @@ -161,13 +161,13 @@ static int dw_edma_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *pid) { struct dw_edma_pcie_data *pdata = (void *)pid->driver_data; - struct dw_edma_pcie_data *vsec_data __free(kfree) = NULL; struct device *dev = &pdev->dev; struct dw_edma_chip *chip; int err, nr_irqs; int i, mask; - vsec_data = kmalloc(sizeof(*vsec_data), GFP_KERNEL); + struct dw_edma_pcie_data *vsec_data __free(kfree) = + kmalloc_obj(*vsec_data); if (!vsec_data) return -ENOMEM; diff --git a/drivers/dma/dw/rzn1-dmamux.c b/drivers/dma/dw/rzn1-dmamux.c index cbec277af4dd..fb495ee6edfc 100644 --- a/drivers/dma/dw/rzn1-dmamux.c +++ b/drivers/dma/dw/rzn1-dmamux.c @@ -53,7 +53,7 @@ static void *rzn1_dmamux_route_allocate(struct of_phandle_args *dma_spec, goto put_device; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { ret = -ENOMEM; goto put_device; diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index e424bb5c40e7..8eceb96d058c 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c @@ -966,7 +966,7 @@ static int ep93xx_dma_alloc_chan_resources(struct dma_chan *chan) for (i = 0; i < DMA_MAX_CHAN_DESCRIPTORS; i++) { struct ep93xx_dma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) { dev_warn(chan2dev(edmac), "not enough descriptors\n"); break; diff --git a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c index 36384d019263..bf771251264d 100644 --- a/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c +++ b/drivers/dma/fsl-dpaa2-qdma/dpaa2-qdma.c @@ -99,7 +99,7 @@ dpaa2_qdma_request_desc(struct dpaa2_qdma_chan *dpaa2_chan) spin_lock_irqsave(&dpaa2_chan->queue_lock, flags); if (list_empty(&dpaa2_chan->comp_free)) { spin_unlock_irqrestore(&dpaa2_chan->queue_lock, flags); - comp_temp = kzalloc(sizeof(*comp_temp), GFP_NOWAIT); + comp_temp = kzalloc_obj(*comp_temp, GFP_NOWAIT); if (!comp_temp) goto err; comp_temp->fd_virt_addr = @@ -353,7 +353,7 @@ static int __cold dpaa2_qdma_setup(struct fsl_mc_device *ls_dev) } priv->num_pairs = min(priv->dpdmai_attr.num_of_priorities, prio_def); - ppriv = kcalloc(priv->num_pairs, sizeof(*ppriv), GFP_KERNEL); + ppriv = kzalloc_objs(*ppriv, priv->num_pairs); if (!ppriv) { err = -ENOMEM; goto exit; @@ -659,7 +659,7 @@ static int dpaa2_qdma_probe(struct fsl_mc_device *dpdmai_dev) struct dpaa2_qdma_priv *priv; int err; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; dev_set_drvdata(dev, priv); @@ -707,7 +707,7 @@ static int dpaa2_qdma_probe(struct fsl_mc_device *dpdmai_dev) goto err_enable; } - dpaa2_qdma = kzalloc(sizeof(*dpaa2_qdma), GFP_KERNEL); + dpaa2_qdma = kzalloc_obj(*dpaa2_qdma); if (!dpaa2_qdma) { err = -ENOMEM; goto err_eng; diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c index 7137f51ff6a0..6a38738e56e2 100644 --- a/drivers/dma/fsl-edma-common.c +++ b/drivers/dma/fsl-edma-common.c @@ -565,7 +565,7 @@ static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan, struct fsl_edma_desc *fsl_desc; int i; - fsl_desc = kzalloc(struct_size(fsl_desc, tcd, sg_len), GFP_NOWAIT); + fsl_desc = kzalloc_flex(*fsl_desc, tcd, sg_len, GFP_NOWAIT); if (!fsl_desc) return NULL; diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index a753b7cbfa7a..dbcdd1e68319 100644 --- a/drivers/dma/fsl-edma-main.c +++ b/drivers/dma/fsl-edma-main.c @@ -915,7 +915,6 @@ static void fsl_edma_remove(struct platform_device *pdev) of_dma_controller_free(np); dma_async_device_unregister(&fsl_edma->dma_dev); fsl_edma_cleanup_vchan(&fsl_edma->dma_dev); - fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs); } static int fsl_edma_suspend_late(struct device *dev) diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c index 6ace5bf80c40..0bbff9df362f 100644 --- a/drivers/dma/fsl-qdma.c +++ b/drivers/dma/fsl-qdma.c @@ -406,7 +406,7 @@ static int fsl_qdma_pre_request_enqueue_desc(struct fsl_qdma_queue *queue) struct fsl_qdma_comp *comp_temp, *_comp_temp; for (i = 0; i < queue->n_cq + FSL_COMMAND_QUEUE_OVERFLLOW; i++) { - comp_temp = kzalloc(sizeof(*comp_temp), GFP_KERNEL); + comp_temp = kzalloc_obj(*comp_temp); if (!comp_temp) goto err_alloc; comp_temp->virt_addr = diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c index 6e6d7e0e475e..99945845d8b5 100644 --- a/drivers/dma/fsl_raid.c +++ b/drivers/dma/fsl_raid.c @@ -290,7 +290,7 @@ static struct fsl_re_desc *fsl_re_chan_alloc_desc(struct fsl_re_chan *re_chan, spin_unlock_irqrestore(&re_chan->desc_lock, lock_flag); if (!desc) { - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; @@ -579,7 +579,7 @@ static int fsl_re_alloc_chan_resources(struct dma_chan *chan) re_chan = container_of(chan, struct fsl_re_chan, chan); for (i = 0; i < FSL_RE_MIN_DESCS; i++) { - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) break; diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 9b126a260267..22d62d958abd 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1111,7 +1111,7 @@ static int fsl_dma_chan_probe(struct fsldma_device *fdev, int err; /* alloc channel */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) { err = -ENOMEM; goto out_return; @@ -1218,7 +1218,7 @@ static int fsldma_of_probe(struct platform_device *op) unsigned int i; int err; - fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); + fdev = kzalloc_obj(*fdev); if (!fdev) { err = -ENOMEM; goto out_return; diff --git a/drivers/dma/hisi_dma.c b/drivers/dma/hisi_dma.c index 25a4134be36b..32a0e95c6a20 100644 --- a/drivers/dma/hisi_dma.c +++ b/drivers/dma/hisi_dma.c @@ -485,7 +485,7 @@ hisi_dma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dst, dma_addr_t src, struct hisi_dma_chan *chan = to_hisi_dma_chan(c); struct hisi_dma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/hsu/hsu.c b/drivers/dma/hsu/hsu.c index af5a2e252c25..f62d60d7bc6b 100644 --- a/drivers/dma/hsu/hsu.c +++ b/drivers/dma/hsu/hsu.c @@ -245,11 +245,11 @@ static struct hsu_dma_desc *hsu_dma_alloc_desc(unsigned int nents) { struct hsu_dma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; - desc->sg = kcalloc(nents, sizeof(*desc->sg), GFP_NOWAIT); + desc->sg = kzalloc_objs(*desc->sg, nents, GFP_NOWAIT); if (!desc->sg) { kfree(desc); return NULL; diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index d147353d47ab..5fcd1befc92d 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c @@ -196,11 +196,11 @@ static struct idma64_desc *idma64_alloc_desc(unsigned int ndesc) { struct idma64_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; - desc->hw = kcalloc(ndesc, sizeof(*desc->hw), GFP_NOWAIT); + desc->hw = kzalloc_objs(*desc->hw, ndesc, GFP_NOWAIT); if (!desc->hw) { kfree(desc); return NULL; diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index 7e4715f92773..c37d233535f9 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -232,7 +232,7 @@ static int idxd_cdev_open(struct inode *inode, struct file *filp) dev_dbg(dev, "%s called: %d\n", __func__, idxd_wq_refcount(wq)); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -538,7 +538,7 @@ int idxd_wq_add_cdev(struct idxd_wq *wq) struct idxd_cdev_context *cdev_ctx; int rc, minor; - idxd_cdev = kzalloc(sizeof(*idxd_cdev), GFP_KERNEL); + idxd_cdev = kzalloc_obj(*idxd_cdev); if (!idxd_cdev) return -ENOMEM; diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c index c2cdf41b6e57..c26128529ff4 100644 --- a/drivers/dma/idxd/device.c +++ b/drivers/dma/idxd/device.c @@ -390,6 +390,7 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) memset(wq->name, 0, WQ_NAME_SIZE); wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); + idxd_wq_set_init_max_sgl_size(idxd, wq); if (wq->opcap_bmap) bitmap_copy(wq->opcap_bmap, idxd->opcap_bmap, IDXD_MAX_OPCAP_BITS); } @@ -989,6 +990,8 @@ static int idxd_wq_config_write(struct idxd_wq *wq) /* bytes 12-15 */ wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes); idxd_wqcfg_set_max_batch_shift(idxd->data->type, wq->wqcfg, ilog2(wq->max_batch_size)); + if (idxd_sgl_supported(idxd)) + wq->wqcfg->max_sgl_shift = ilog2(wq->max_sgl_size); /* bytes 32-63 */ if (idxd->hw.wq_cap.op_config && wq->opcap_bmap) { @@ -1167,6 +1170,8 @@ static int idxd_wq_load_config(struct idxd_wq *wq) wq->max_xfer_bytes = 1ULL << wq->wqcfg->max_xfer_shift; idxd_wq_set_max_batch_size(idxd->data->type, wq, 1U << wq->wqcfg->max_batch_shift); + if (idxd_sgl_supported(idxd)) + wq->max_sgl_size = 1U << wq->wqcfg->max_sgl_shift; for (i = 0; i < WQCFG_STRIDES(idxd); i++) { wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i); diff --git a/drivers/dma/idxd/idxd.h b/drivers/dma/idxd/idxd.h index 74e6695881e6..ea8c4daed38d 100644 --- a/drivers/dma/idxd/idxd.h +++ b/drivers/dma/idxd/idxd.h @@ -227,6 +227,7 @@ struct idxd_wq { char name[WQ_NAME_SIZE + 1]; u64 max_xfer_bytes; u32 max_batch_size; + u32 max_sgl_size; /* Lock to protect upasid_xa access. */ struct mutex uc_lock; @@ -252,6 +253,9 @@ struct idxd_hw { struct opcap opcap; u32 cmd_cap; union iaa_cap_reg iaa_cap; + union dsacap0_reg dsacap0; + union dsacap1_reg dsacap1; + union dsacap2_reg dsacap2; }; enum idxd_device_state { @@ -345,6 +349,7 @@ struct idxd_device { u64 max_xfer_bytes; u32 max_batch_size; + u32 max_sgl_size; int max_groups; int max_engines; int max_rdbufs; @@ -689,6 +694,20 @@ static inline void idxd_wq_set_max_batch_size(int idxd_type, struct idxd_wq *wq, wq->max_batch_size = max_batch_size; } +static bool idxd_sgl_supported(struct idxd_device *idxd) +{ + return idxd->data->type == IDXD_TYPE_DSA && + idxd->hw.version >= DEVICE_VERSION_3 && + idxd->hw.dsacap0.sgl_formats; +} + +static inline void idxd_wq_set_init_max_sgl_size(struct idxd_device *idxd, + struct idxd_wq *wq) +{ + if (idxd_sgl_supported(idxd)) + wq->max_sgl_size = 1U << idxd->hw.dsacap0.max_sgl_shift; +} + static inline void idxd_wqcfg_set_max_batch_shift(int idxd_type, union wqcfg *wqcfg, u32 max_batch_shift) { diff --git a/drivers/dma/idxd/init.c b/drivers/dma/idxd/init.c index 2acc34b3daff..fb80803d5b57 100644 --- a/drivers/dma/idxd/init.c +++ b/drivers/dma/idxd/init.c @@ -222,6 +222,7 @@ static int idxd_setup_wqs(struct idxd_device *idxd) init_completion(&wq->wq_resurrect); wq->max_xfer_bytes = WQ_DEFAULT_MAX_XFER; idxd_wq_set_max_batch_size(idxd->data->type, wq, WQ_DEFAULT_MAX_BATCH); + idxd_wq_set_init_max_sgl_size(idxd, wq); wq->enqcmds_retries = IDXD_ENQCMDS_RETRIES; wq->wqcfg = kzalloc_node(idxd->wqcfg_size, GFP_KERNEL, dev_to_node(dev)); if (!wq->wqcfg) { @@ -585,6 +586,16 @@ static void idxd_read_caps(struct idxd_device *idxd) } multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4); + if (idxd->hw.version >= DEVICE_VERSION_3) { + idxd->hw.dsacap0.bits = ioread64(idxd->reg_base + IDXD_DSACAP0_OFFSET); + idxd->hw.dsacap1.bits = ioread64(idxd->reg_base + IDXD_DSACAP1_OFFSET); + idxd->hw.dsacap2.bits = ioread64(idxd->reg_base + IDXD_DSACAP2_OFFSET); + } + if (idxd_sgl_supported(idxd)) { + idxd->max_sgl_size = 1U << idxd->hw.dsacap0.max_sgl_shift; + dev_dbg(dev, "max sgl size: %u\n", idxd->max_sgl_size); + } + /* read iaa cap */ if (idxd->data->type == IDXD_TYPE_IAX && idxd->hw.version >= DEVICE_VERSION_2) idxd->hw.iaa_cap.bits = ioread64(idxd->reg_base + IDXD_IAACAP_OFFSET); diff --git a/drivers/dma/idxd/irq.c b/drivers/dma/idxd/irq.c index 1107db3ce0a3..7782f8c51c32 100644 --- a/drivers/dma/idxd/irq.c +++ b/drivers/dma/idxd/irq.c @@ -492,7 +492,7 @@ irqreturn_t idxd_misc_thread(int vec, void *data) val |= IDXD_INTC_INT_HANDLE_REVOKED; - revoke = kzalloc(sizeof(*revoke), GFP_ATOMIC); + revoke = kzalloc_obj(*revoke, GFP_ATOMIC); if (revoke) { revoke->idxd = idxd; INIT_WORK(&revoke->work, idxd_int_handle_revoke); @@ -567,7 +567,7 @@ bool idxd_queue_int_handle_resubmit(struct idxd_desc *desc) struct idxd_device *idxd = wq->idxd; struct idxd_resubmit *irw; - irw = kzalloc(sizeof(*irw), GFP_KERNEL); + irw = kzalloc_obj(*irw); if (!irw) return false; diff --git a/drivers/dma/idxd/perfmon.c b/drivers/dma/idxd/perfmon.c index 4b6af2f15d8a..f854bd31a4f5 100644 --- a/drivers/dma/idxd/perfmon.c +++ b/drivers/dma/idxd/perfmon.c @@ -128,7 +128,7 @@ static int perfmon_validate_group(struct idxd_pmu *pmu, struct idxd_pmu *fake_pmu; int i, ret = 0, n, idx; - fake_pmu = kzalloc(sizeof(*fake_pmu), GFP_KERNEL); + fake_pmu = kzalloc_obj(*fake_pmu); if (!fake_pmu) return -ENOMEM; @@ -484,7 +484,7 @@ int perfmon_pmu_init(struct idxd_device *idxd) if (idxd->perfmon_offset == 0) return -ENODEV; - idxd_pmu = kzalloc(sizeof(*idxd_pmu), GFP_KERNEL); + idxd_pmu = kzalloc_obj(*idxd_pmu); if (!idxd_pmu) return -ENOMEM; diff --git a/drivers/dma/idxd/registers.h b/drivers/dma/idxd/registers.h index 8dc2e8bca779..f95411363ea9 100644 --- a/drivers/dma/idxd/registers.h +++ b/drivers/dma/idxd/registers.h @@ -18,6 +18,7 @@ #define DEVICE_VERSION_1 0x100 #define DEVICE_VERSION_2 0x200 +#define DEVICE_VERSION_3 0x300 #define IDXD_MMIO_BAR 0 #define IDXD_WQ_BAR 2 @@ -389,7 +390,8 @@ union wqcfg { /* bytes 12-15 */ u32 max_xfer_shift:5; u32 max_batch_shift:4; - u32 rsvd4:23; + u32 max_sgl_shift:4; + u32 rsvd4:19; /* bytes 16-19 */ u16 occupancy_inth; @@ -587,6 +589,30 @@ union evl_status_reg { u64 bits; }; +#define IDXD_DSACAP0_OFFSET 0x180 +union dsacap0_reg { + u64 bits; + struct { + u64 max_sgl_shift:4; + u64 max_gr_block_shift:4; + u64 ops_inter_domain:7; + u64 rsvd1:17; + u64 sgl_formats:16; + u64 max_sg_process:8; + u64 rsvd2:8; + }; +}; + +#define IDXD_DSACAP1_OFFSET 0x188 +union dsacap1_reg { + u64 bits; +}; + +#define IDXD_DSACAP2_OFFSET 0x190 +union dsacap2_reg { + u64 bits; +}; + #define IDXD_MAX_BATCH_IDENT 256 struct __evl_entry { diff --git a/drivers/dma/idxd/sysfs.c b/drivers/dma/idxd/sysfs.c index 9f0701021af0..cc2c83d7f710 100644 --- a/drivers/dma/idxd/sysfs.c +++ b/drivers/dma/idxd/sysfs.c @@ -1713,6 +1713,18 @@ static ssize_t event_log_size_store(struct device *dev, } static DEVICE_ATTR_RW(event_log_size); +static ssize_t dsacaps_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct idxd_device *idxd = confdev_to_idxd(dev); + + return sysfs_emit(buf, "%016llx,%016llx,%016llx\n", + (u64)idxd->hw.dsacap2.bits, + (u64)idxd->hw.dsacap1.bits, + (u64)idxd->hw.dsacap0.bits); +} +static DEVICE_ATTR_RO(dsacaps); + static bool idxd_device_attr_max_batch_size_invisible(struct attribute *attr, struct idxd_device *idxd) { @@ -1750,6 +1762,14 @@ static bool idxd_device_attr_event_log_size_invisible(struct attribute *attr, !idxd->hw.gen_cap.evl_support); } +static bool idxd_device_attr_dsacaps_invisible(struct attribute *attr, + struct idxd_device *idxd) +{ + return attr == &dev_attr_dsacaps.attr && + (idxd->data->type != IDXD_TYPE_DSA || + idxd->hw.version < DEVICE_VERSION_3); +} + static umode_t idxd_device_attr_visible(struct kobject *kobj, struct attribute *attr, int n) { @@ -1768,6 +1788,9 @@ static umode_t idxd_device_attr_visible(struct kobject *kobj, if (idxd_device_attr_event_log_size_invisible(attr, idxd)) return 0; + if (idxd_device_attr_dsacaps_invisible(attr, idxd)) + return 0; + return attr->mode; } @@ -1795,6 +1818,7 @@ static struct attribute *idxd_device_attributes[] = { &dev_attr_cmd_status.attr, &dev_attr_iaa_cap.attr, &dev_attr_event_log_size.attr, + &dev_attr_dsacaps.attr, NULL, }; diff --git a/drivers/dma/img-mdc-dma.c b/drivers/dma/img-mdc-dma.c index fd55bcd060ab..b3765ba15803 100644 --- a/drivers/dma/img-mdc-dma.c +++ b/drivers/dma/img-mdc-dma.c @@ -294,7 +294,7 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_memcpy( if (!len) return NULL; - mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT); + mdesc = kzalloc_obj(*mdesc, GFP_NOWAIT); if (!mdesc) return NULL; mdesc->chan = mchan; @@ -382,7 +382,7 @@ static struct dma_async_tx_descriptor *mdc_prep_dma_cyclic( if (mdc_check_slave_width(mchan, dir) < 0) return NULL; - mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT); + mdesc = kzalloc_obj(*mdesc, GFP_NOWAIT); if (!mdesc) return NULL; mdesc->chan = mchan; @@ -465,7 +465,7 @@ static struct dma_async_tx_descriptor *mdc_prep_slave_sg( if (mdc_check_slave_width(mchan, dir) < 0) return NULL; - mdesc = kzalloc(sizeof(*mdesc), GFP_NOWAIT); + mdesc = kzalloc_obj(*mdesc, GFP_NOWAIT); if (!mdesc) return NULL; mdesc->chan = mchan; diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index ba434657059a..81c6276436f8 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -746,7 +746,7 @@ static int imxdma_alloc_chan_resources(struct dma_chan *chan) while (imxdmac->descs_allocated < IMXDMA_MAX_CHAN_DESCRIPTORS) { struct imxdma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) break; dma_async_tx_descriptor_init(&desc->desc, chan); @@ -865,8 +865,8 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( kfree(imxdmac->sg_list); - imxdmac->sg_list = kcalloc(periods + 1, - sizeof(struct scatterlist), GFP_ATOMIC); + imxdmac->sg_list = kzalloc_objs(struct scatterlist, periods + 1, + GFP_ATOMIC); if (!imxdmac->sg_list) return NULL; diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index ed9e56de5a9b..4c8196d78001 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1544,7 +1544,7 @@ static struct sdma_desc *sdma_transfer_init(struct sdma_channel *sdmac, goto err_out; } - desc = kzalloc((sizeof(*desc)), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) goto err_out; @@ -2288,7 +2288,7 @@ static int sdma_probe(struct platform_device *pdev) sdma->irq = irq; - sdma->script_addrs = kzalloc(sizeof(*sdma->script_addrs), GFP_KERNEL); + sdma->script_addrs = kzalloc_obj(*sdma->script_addrs); if (!sdma->script_addrs) { ret = -ENOMEM; goto err_irq; diff --git a/drivers/dma/ioat/dma.c b/drivers/dma/ioat/dma.c index b8fff8333aef..ee93b029f9e3 100644 --- a/drivers/dma/ioat/dma.c +++ b/drivers/dma/ioat/dma.c @@ -378,7 +378,7 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags) int i, chunks; /* allocate the array to hold the software ring */ - ring = kcalloc(total_descs, sizeof(*ring), flags); + ring = kzalloc_objs(*ring, total_descs, flags); if (!ring) return NULL; diff --git a/drivers/dma/ioat/init.c b/drivers/dma/ioat/init.c index 227398673b73..737496391109 100644 --- a/drivers/dma/ioat/init.c +++ b/drivers/dma/ioat/init.c @@ -574,7 +574,7 @@ static void ioat_enumerate_channels(struct ioatdma_device *ioat_dma) dev_dbg(dev, "%s: xfercap = %d\n", __func__, 1 << xfercap_log); for (i = 0; i < chancnt; i++) { - ioat_chan = kzalloc(sizeof(*ioat_chan), GFP_KERNEL); + ioat_chan = kzalloc_obj(*ioat_chan); if (!ioat_chan) break; @@ -1332,7 +1332,7 @@ static void release_ioatdma(struct dma_device *device) static struct ioatdma_device * alloc_ioatdma(struct pci_dev *pdev, void __iomem *iobase) { - struct ioatdma_device *d = kzalloc(sizeof(*d), GFP_KERNEL); + struct ioatdma_device *d = kzalloc_obj(*d); if (!d) return NULL; diff --git a/drivers/dma/k3dma.c b/drivers/dma/k3dma.c index 0f9cd7815f88..e84f197fea76 100644 --- a/drivers/dma/k3dma.c +++ b/drivers/dma/k3dma.c @@ -471,7 +471,7 @@ static struct k3_dma_desc_sw *k3_dma_alloc_desc_resource(int num, return NULL; } - ds = kzalloc(sizeof(*ds), GFP_NOWAIT); + ds = kzalloc_obj(*ds, GFP_NOWAIT); if (!ds) return NULL; @@ -536,19 +536,14 @@ static struct dma_async_tx_descriptor *k3_dma_prep_slave_sg( size_t len, avail, total = 0; struct scatterlist *sg; dma_addr_t addr, src = 0, dst = 0; - int num = sglen, i; + int num, i; if (sgl == NULL) return NULL; c->cyclic = 0; - for_each_sg(sgl, sg, sglen, i) { - avail = sg_dma_len(sg); - if (avail > DMA_MAX_SIZE) - num += DIV_ROUND_UP(avail, DMA_MAX_SIZE) - 1; - } - + num = sg_nents_for_dma(sgl, sglen, DMA_MAX_SIZE); ds = k3_dma_alloc_desc_resource(num, chan); if (!ds) return NULL; diff --git a/drivers/dma/lgm/lgm-dma.c b/drivers/dma/lgm/lgm-dma.c index 8173c3f1075a..c1f859472a96 100644 --- a/drivers/dma/lgm/lgm-dma.c +++ b/drivers/dma/lgm/lgm-dma.c @@ -681,7 +681,7 @@ ldma_chan_desc_cfg(struct dma_chan *chan, dma_addr_t desc_base, int desc_num) c->desc_cnt = desc_num; c->desc_phys = desc_base; - ds = kzalloc(sizeof(*ds), GFP_NOWAIT); + ds = kzalloc_obj(*ds, GFP_NOWAIT); if (!ds) return NULL; @@ -982,7 +982,7 @@ dma_alloc_desc_resource(int num, struct ldma_chan *c) return NULL; } - ds = kzalloc(sizeof(*ds), GFP_NOWAIT); + ds = kzalloc_obj(*ds, GFP_NOWAIT); if (!ds) return NULL; @@ -1164,8 +1164,8 @@ ldma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, struct dw2_desc *hw_ds; struct dw2_desc_sw *ds; struct scatterlist *sg; - int num = sglen, i; dma_addr_t addr; + int num, i; if (!sgl) return NULL; @@ -1173,12 +1173,7 @@ ldma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (d->ver > DMA_VER22) return ldma_chan_desc_cfg(chan, sgl->dma_address, sglen); - for_each_sg(sgl, sg, sglen, i) { - avail = sg_dma_len(sg); - if (avail > DMA_MAX_SIZE) - num += DIV_ROUND_UP(avail, DMA_MAX_SIZE) - 1; - } - + num = sg_nents_for_dma(sgl, sglen, DMA_MAX_SIZE); ds = dma_alloc_desc_resource(num, c); if (!ds) return NULL; diff --git a/drivers/dma/loongson1-apb-dma.c b/drivers/dma/loongson1-apb-dma.c index 255fe7eca212..2e347aba9af8 100644 --- a/drivers/dma/loongson1-apb-dma.c +++ b/drivers/dma/loongson1-apb-dma.c @@ -204,7 +204,7 @@ static struct ls1x_dma_desc *ls1x_dma_alloc_desc(void) { struct ls1x_dma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; @@ -335,7 +335,7 @@ ls1x_dma_prep_dma_cyclic(struct dma_chan *dchan, dma_addr_t buf_addr, /* allocate the scatterlist */ sg_len = buf_len / period_len; - sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT); + sgl = kmalloc_objs(*sgl, sg_len, GFP_NOWAIT); if (!sgl) return NULL; diff --git a/drivers/dma/loongson2-apb-dma.c b/drivers/dma/loongson2-apb-dma.c index c528f02b9f84..b981475e6779 100644 --- a/drivers/dma/loongson2-apb-dma.c +++ b/drivers/dma/loongson2-apb-dma.c @@ -335,7 +335,7 @@ ls2x_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!burst_size) return NULL; - desc = kzalloc(struct_size(desc, sg, sg_len), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg, sg_len, GFP_NOWAIT); if (!desc) return NULL; @@ -400,7 +400,7 @@ ls2x_dma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_ return NULL; num_periods = buf_len / period_len; - desc = kzalloc(struct_size(desc, sg, num_periods), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg, num_periods, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/mediatek/mtk-cqdma.c b/drivers/dma/mediatek/mtk-cqdma.c index 9f0c41ca7770..80791e30aec2 100644 --- a/drivers/dma/mediatek/mtk-cqdma.c +++ b/drivers/dma/mediatek/mtk-cqdma.c @@ -501,12 +501,12 @@ mtk_cqdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, * until all the child CVDs completed. */ nr_vd = DIV_ROUND_UP(len, MTK_CQDMA_MAX_LEN); - cvd = kcalloc(nr_vd, sizeof(*cvd), GFP_NOWAIT); + cvd = kzalloc_objs(*cvd, nr_vd, GFP_NOWAIT); if (!cvd) return NULL; for (i = 0; i < nr_vd; ++i) { - cvd[i] = kzalloc(sizeof(*cvd[i]), GFP_NOWAIT); + cvd[i] = kzalloc_obj(*cvd[i], GFP_NOWAIT); if (!cvd[i]) { for (; i > 0; --i) kfree(cvd[i - 1]); diff --git a/drivers/dma/mediatek/mtk-hsdma.c b/drivers/dma/mediatek/mtk-hsdma.c index fa77bb24a430..a43412ff5edd 100644 --- a/drivers/dma/mediatek/mtk-hsdma.c +++ b/drivers/dma/mediatek/mtk-hsdma.c @@ -334,7 +334,7 @@ static int mtk_hsdma_alloc_pchan(struct mtk_hsdma_device *hsdma, ring->cur_tptr = 0; ring->cur_rptr = MTK_DMA_SIZE - 1; - ring->cb = kcalloc(MTK_DMA_SIZE, sizeof(*ring->cb), GFP_NOWAIT); + ring->cb = kzalloc_objs(*ring->cb, MTK_DMA_SIZE, GFP_NOWAIT); if (!ring->cb) { err = -ENOMEM; goto err_free_dma; @@ -722,7 +722,7 @@ mtk_hsdma_prep_dma_memcpy(struct dma_chan *c, dma_addr_t dest, { struct mtk_hsdma_vdesc *hvd; - hvd = kzalloc(sizeof(*hvd), GFP_NOWAIT); + hvd = kzalloc_obj(*hvd, GFP_NOWAIT); if (!hvd) return NULL; diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c b/drivers/dma/mediatek/mtk-uart-apdma.c index 08e15177427b..c269d84d7bd2 100644 --- a/drivers/dma/mediatek/mtk-uart-apdma.c +++ b/drivers/dma/mediatek/mtk-uart-apdma.c @@ -41,7 +41,7 @@ #define VFF_STOP_CLR_B 0 #define VFF_EN_CLR_B 0 #define VFF_INT_EN_CLR_B 0 -#define VFF_4G_SUPPORT_CLR_B 0 +#define VFF_ADDR2_CLR_B 0 /* * interrupt trigger level for tx @@ -72,12 +72,12 @@ /* TX: the buffer size SW can write. RX: the buffer size HW can write. */ #define VFF_LEFT_SIZE 0x40 #define VFF_DEBUG_STATUS 0x50 -#define VFF_4G_SUPPORT 0x54 +#define VFF_ADDR2 0x54 struct mtk_uart_apdmadev { struct dma_device ddev; struct clk *clk; - bool support_33bits; + bool support_ext_addr; unsigned int dma_requests; }; @@ -148,8 +148,8 @@ static void mtk_uart_apdma_start_tx(struct mtk_chan *c) mtk_uart_apdma_write(c, VFF_WPT, 0); mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_TX_INT_CLR_B); - if (mtkd->support_33bits) - mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_EN_B); + if (mtkd->support_ext_addr) + mtk_uart_apdma_write(c, VFF_ADDR2, upper_32_bits(d->addr)); } mtk_uart_apdma_write(c, VFF_EN, VFF_EN_B); @@ -191,8 +191,8 @@ static void mtk_uart_apdma_start_rx(struct mtk_chan *c) mtk_uart_apdma_write(c, VFF_RPT, 0); mtk_uart_apdma_write(c, VFF_INT_FLAG, VFF_RX_INT_CLR_B); - if (mtkd->support_33bits) - mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_EN_B); + if (mtkd->support_ext_addr) + mtk_uart_apdma_write(c, VFF_ADDR2, upper_32_bits(d->addr)); } mtk_uart_apdma_write(c, VFF_INT_EN, VFF_RX_INT_EN_B); @@ -297,8 +297,8 @@ static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan) goto err_pm; } - if (mtkd->support_33bits) - mtk_uart_apdma_write(c, VFF_4G_SUPPORT, VFF_4G_SUPPORT_CLR_B); + if (mtkd->support_ext_addr) + mtk_uart_apdma_write(c, VFF_ADDR2, VFF_ADDR2_CLR_B); err_pm: pm_runtime_put_noidle(mtkd->ddev.dev); @@ -351,7 +351,7 @@ static struct dma_async_tx_descriptor *mtk_uart_apdma_prep_slave_sg return NULL; /* Now allocate and setup the descriptor */ - d = kzalloc(sizeof(*d), GFP_NOWAIT); + d = kzalloc_obj(*d, GFP_NOWAIT); if (!d) return NULL; @@ -468,7 +468,10 @@ static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd) } static const struct of_device_id mtk_uart_apdma_match[] = { - { .compatible = "mediatek,mt6577-uart-dma", }, + { .compatible = "mediatek,mt6577-uart-dma", .data = (void *)32 }, + { .compatible = "mediatek,mt6795-uart-dma", .data = (void *)33 }, + { .compatible = "mediatek,mt6835-uart-dma", .data = (void *)34 }, + { .compatible = "mediatek,mt6985-uart-dma", .data = (void *)35 }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match); @@ -477,9 +480,9 @@ static int mtk_uart_apdma_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct mtk_uart_apdmadev *mtkd; - int bit_mask = 32, rc; struct mtk_chan *c; - unsigned int i; + unsigned int bit_mask, i; + int rc; mtkd = devm_kzalloc(&pdev->dev, sizeof(*mtkd), GFP_KERNEL); if (!mtkd) @@ -492,11 +495,9 @@ static int mtk_uart_apdma_probe(struct platform_device *pdev) return rc; } - if (of_property_read_bool(np, "mediatek,dma-33bits")) - mtkd->support_33bits = true; - - if (mtkd->support_33bits) - bit_mask = 33; + bit_mask = (unsigned int)(uintptr_t)of_device_get_match_data(&pdev->dev); + if (bit_mask > 32) + mtkd->support_ext_addr = true; rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(bit_mask)); if (rc) diff --git a/drivers/dma/milbeaut-hdmac.c b/drivers/dma/milbeaut-hdmac.c index 9a5ec247ed6d..b4ebc09e80d0 100644 --- a/drivers/dma/milbeaut-hdmac.c +++ b/drivers/dma/milbeaut-hdmac.c @@ -265,11 +265,11 @@ milbeaut_hdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!is_slave_direction(direction)) return NULL; - md = kzalloc(sizeof(*md), GFP_NOWAIT); + md = kzalloc_obj(*md, GFP_NOWAIT); if (!md) return NULL; - md->sgl = kcalloc(sg_len, sizeof(*sgl), GFP_NOWAIT); + md->sgl = kzalloc_objs(*sgl, sg_len, GFP_NOWAIT); if (!md->sgl) { kfree(md); return NULL; diff --git a/drivers/dma/milbeaut-xdmac.c b/drivers/dma/milbeaut-xdmac.c index 58d4fd6df0bf..0bfa247e746e 100644 --- a/drivers/dma/milbeaut-xdmac.c +++ b/drivers/dma/milbeaut-xdmac.c @@ -192,7 +192,7 @@ milbeaut_xdmac_prep_memcpy(struct dma_chan *chan, dma_addr_t dst, struct virt_dma_chan *vc = to_virt_chan(chan); struct milbeaut_xdmac_desc *md; - md = kzalloc(sizeof(*md), GFP_NOWAIT); + md = kzalloc_obj(*md, GFP_NOWAIT); if (!md) return NULL; diff --git a/drivers/dma/moxart-dma.c b/drivers/dma/moxart-dma.c index de09e1ab7767..442f5aa16031 100644 --- a/drivers/dma/moxart-dma.c +++ b/drivers/dma/moxart-dma.c @@ -301,7 +301,7 @@ static struct dma_async_tx_descriptor *moxart_prep_slave_sg( return NULL; } - d = kzalloc(struct_size(d, sg, sg_len), GFP_ATOMIC); + d = kzalloc_flex(*d, sg, sg_len, GFP_ATOMIC); if (!d) return NULL; d->sglen = sg_len; diff --git a/drivers/dma/mpc512x_dma.c b/drivers/dma/mpc512x_dma.c index bf131cb5db66..0adc8e01057e 100644 --- a/drivers/dma/mpc512x_dma.c +++ b/drivers/dma/mpc512x_dma.c @@ -503,7 +503,7 @@ static int mpc_dma_alloc_chan_resources(struct dma_chan *chan) /* Alloc descriptors for this channel */ for (i = 0; i < MPC_DMA_DESCRIPTORS; i++) { - mdesc = kzalloc(sizeof(struct mpc_dma_desc), GFP_KERNEL); + mdesc = kzalloc_obj(struct mpc_dma_desc); if (!mdesc) { dev_notice(mdma->dma.dev, "Memory allocation error. Allocated only %u descriptors\n", i); diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 5e8386296046..25ed61f1b089 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -443,7 +443,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan) /* Allocate descriptor slots */ idx = mv_chan->slots_allocated; while (idx < num_descs_in_pool) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) { dev_info(mv_chan_to_devp(mv_chan), "channel only initialized %d descriptor slots", diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index 423442e55d36..53d11063a4f2 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -127,7 +127,7 @@ int of_dma_controller_register(struct device_node *np, return -EINVAL; } - ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL); + ofdma = kzalloc_obj(*ofdma); if (!ofdma) return -ENOMEM; @@ -194,7 +194,7 @@ int of_dma_router_register(struct device_node *np, return -EINVAL; } - ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL); + ofdma = kzalloc_obj(*ofdma); if (!ofdma) return -ENOMEM; diff --git a/drivers/dma/owl-dma.c b/drivers/dma/owl-dma.c index 57cec757d8f5..7c80572fc71d 100644 --- a/drivers/dma/owl-dma.c +++ b/drivers/dma/owl-dma.c @@ -878,7 +878,7 @@ static struct dma_async_tx_descriptor if (!len) return NULL; - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; @@ -929,7 +929,7 @@ static struct dma_async_tx_descriptor size_t len; int ret, i; - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; @@ -993,7 +993,7 @@ static struct dma_async_tx_descriptor unsigned int periods = buf_len / period_len; int ret, i; - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 6b2793b07694..e9fbfd5a3d51 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c @@ -806,7 +806,7 @@ static int pch_dma_probe(struct pci_dev *pdev, int i; nr_channels = id->driver_data; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return -ENOMEM; diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index 82a9fe88ad54..25ba84b18704 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -1887,8 +1887,7 @@ static int dmac_alloc_threads(struct pl330_dmac *pl330) int i; /* Allocate 1 Manager and 'chans' Channel threads */ - pl330->channels = kcalloc(1 + chans, sizeof(*thrd), - GFP_KERNEL); + pl330->channels = kzalloc_objs(*thrd, 1 + chans); if (!pl330->channels) return -ENOMEM; @@ -2133,10 +2132,8 @@ static void pl330_tasklet(struct tasklet_struct *t) spin_unlock_irqrestore(&pch->lock, flags); /* If work list empty, power down */ - if (power_down) { - pm_runtime_mark_last_busy(pch->dmac->ddma.dev); + if (power_down) pm_runtime_put_autosuspend(pch->dmac->ddma.dev); - } } static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec, @@ -2313,7 +2310,6 @@ static int pl330_terminate_all(struct dma_chan *chan) list_splice_tail_init(&pch->work_list, &pl330->desc_pool); list_splice_tail_init(&pch->completed_list, &pl330->desc_pool); spin_unlock_irqrestore(&pch->lock, flags); - pm_runtime_mark_last_busy(pl330->ddma.dev); if (power_down) pm_runtime_put_autosuspend(pl330->ddma.dev); pm_runtime_put_autosuspend(pl330->ddma.dev); @@ -2347,7 +2343,6 @@ static int pl330_pause(struct dma_chan *chan) desc->status = PAUSED; } spin_unlock_irqrestore(&pch->lock, flags); - pm_runtime_mark_last_busy(pl330->ddma.dev); pm_runtime_put_autosuspend(pl330->ddma.dev); return 0; @@ -2371,7 +2366,6 @@ static void pl330_free_chan_resources(struct dma_chan *chan) list_splice_tail_init(&pch->work_list, &pch->dmac->desc_pool); spin_unlock_irqrestore(&pl330->lock, flags); - pm_runtime_mark_last_busy(pch->dmac->ddma.dev); pm_runtime_put_autosuspend(pch->dmac->ddma.dev); pl330_unprep_slave_fifo(pch); } @@ -2553,7 +2547,7 @@ static int add_desc(struct list_head *pool, spinlock_t *lock, unsigned long flags; int i; - desc = kcalloc(count, sizeof(*desc), flg); + desc = kzalloc_objs(*desc, count, flg); if (!desc) return 0; @@ -3098,7 +3092,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pl330->num_peripherals = num_chan; - pl330->peripherals = kcalloc(num_chan, sizeof(*pch), GFP_KERNEL); + pl330->peripherals = kzalloc_objs(*pch, num_chan); if (!pl330->peripherals) { ret = -ENOMEM; goto probe_err2; @@ -3176,7 +3170,6 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) pm_runtime_irq_safe(&adev->dev); pm_runtime_use_autosuspend(&adev->dev); pm_runtime_set_autosuspend_delay(&adev->dev, PL330_AUTOSUSPEND_DELAY); - pm_runtime_mark_last_busy(&adev->dev); pm_runtime_put_autosuspend(&adev->dev); return 0; diff --git a/drivers/dma/plx_dma.c b/drivers/dma/plx_dma.c index 34b6416c3287..84941a918b01 100644 --- a/drivers/dma/plx_dma.c +++ b/drivers/dma/plx_dma.c @@ -378,13 +378,12 @@ static int plx_dma_alloc_desc(struct plx_dma_dev *plxdev) struct plx_dma_desc *desc; int i; - plxdev->desc_ring = kcalloc(PLX_DMA_RING_COUNT, - sizeof(*plxdev->desc_ring), GFP_KERNEL); + plxdev->desc_ring = kzalloc_objs(*plxdev->desc_ring, PLX_DMA_RING_COUNT); if (!plxdev->desc_ring) return -ENOMEM; for (i = 0; i < PLX_DMA_RING_COUNT; i++) { - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) goto free_and_exit; @@ -501,7 +500,7 @@ static int plx_dma_create(struct pci_dev *pdev) struct dma_chan *chan; int rc; - plxdev = kzalloc(sizeof(*plxdev), GFP_KERNEL); + plxdev = kzalloc_obj(*plxdev); if (!plxdev) return -ENOMEM; diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 61500ad7c850..279a431ccae3 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c @@ -1781,8 +1781,7 @@ static int ppc440spe_adma_alloc_chan_resources(struct dma_chan *chan) db_sz = sizeof(struct xor_cb); for (; i < (ppc440spe_chan->device->pool_size / db_sz); i++) { - slot = kzalloc(sizeof(struct ppc440spe_adma_desc_slot), - GFP_KERNEL); + slot = kzalloc_obj(struct ppc440spe_adma_desc_slot); if (!slot) { printk(KERN_INFO "SPE ADMA Channel only initialized" " %d descriptor slots", i--); @@ -4064,7 +4063,7 @@ static int ppc440spe_adma_probe(struct platform_device *ofdev) } /* create a device */ - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) { initcode = PPC_ADMA_INIT_ALLOC; ret = -ENOMEM; @@ -4124,7 +4123,7 @@ static int ppc440spe_adma_probe(struct platform_device *ofdev) platform_set_drvdata(ofdev, adev); /* create a channel */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) { initcode = PPC_ADMA_INIT_CHANNEL; ret = -ENOMEM; @@ -4161,7 +4160,7 @@ static int ppc440spe_adma_probe(struct platform_device *ofdev) PAGE_SIZE, DMA_BIDIRECTIONAL); } - ref = kmalloc(sizeof(*ref), GFP_KERNEL); + ref = kmalloc_obj(*ref); if (ref) { ref->chan = &chan->common; INIT_LIST_HEAD(&ref->node); diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c index 249296389771..fa2ee0b3e09f 100644 --- a/drivers/dma/pxa_dma.c +++ b/drivers/dma/pxa_dma.c @@ -342,8 +342,7 @@ static void pxad_init_debugfs(struct pxad_device *pdev) struct dentry *chandir; pdev->dbgfs_chan = - kmalloc_array(pdev->nr_chans, sizeof(struct dentry *), - GFP_KERNEL); + kmalloc_objs(struct dentry *, pdev->nr_chans); if (!pdev->dbgfs_chan) return; @@ -742,8 +741,7 @@ pxad_alloc_desc(struct pxad_chan *chan, unsigned int nb_hw_desc) void *desc; int i; - sw_desc = kzalloc(struct_size(sw_desc, hw_desc, nb_hw_desc), - GFP_NOWAIT); + sw_desc = kzalloc_flex(*sw_desc, hw_desc, nb_hw_desc, GFP_NOWAIT); if (!sw_desc) return NULL; sw_desc->desc_pool = chan->desc_pool; @@ -970,7 +968,7 @@ pxad_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, struct scatterlist *sg; dma_addr_t dma; u32 dcmd, dsadr = 0, dtadr = 0; - unsigned int nb_desc = 0, i, j = 0; + unsigned int nb_desc, i, j = 0; if ((sgl == NULL) || (sg_len == 0)) return NULL; @@ -979,8 +977,7 @@ pxad_prep_slave_sg(struct dma_chan *dchan, struct scatterlist *sgl, dev_dbg(&chan->vc.chan.dev->device, "%s(): dir=%d flags=%lx\n", __func__, dir, flags); - for_each_sg(sgl, sg, sg_len, i) - nb_desc += DIV_ROUND_UP(sg_dma_len(sg), PDMA_MAX_DESC_BYTES); + nb_desc = sg_nents_for_dma(sgl, sg_len, PDMA_MAX_DESC_BYTES); sw_desc = pxad_alloc_desc(chan, nb_desc + 1); if (!sw_desc) return NULL; diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index 2cf060174795..19116295f832 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -23,24 +23,25 @@ * indication of where the hardware is currently working. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include +#include #include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include #include "../dmaengine.h" #include "../virt-dma.h" @@ -570,7 +571,6 @@ static void bam_free_chan(struct dma_chan *chan) struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; u32 val; - unsigned long flags; int ret; ret = pm_runtime_get_sync(bdev->dev); @@ -584,9 +584,8 @@ static void bam_free_chan(struct dma_chan *chan) goto err; } - spin_lock_irqsave(&bchan->vc.lock, flags); - bam_reset_channel(bchan); - spin_unlock_irqrestore(&bchan->vc.lock, flags); + scoped_guard(spinlock_irqsave, &bchan->vc.lock) + bam_reset_channel(bchan); dma_free_wc(bdev->dev, BAM_DESC_FIFO_SIZE, bchan->fifo_virt, bchan->fifo_phys); @@ -624,12 +623,11 @@ static int bam_slave_config(struct dma_chan *chan, struct dma_slave_config *cfg) { struct bam_chan *bchan = to_bam_chan(chan); - unsigned long flag; - spin_lock_irqsave(&bchan->vc.lock, flag); + guard(spinlock_irqsave)(&bchan->vc.lock); + memcpy(&bchan->slave, cfg, sizeof(*cfg)); bchan->reconfigure = 1; - spin_unlock_irqrestore(&bchan->vc.lock, flag); return 0; } @@ -655,22 +653,16 @@ static struct dma_async_tx_descriptor *bam_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sg; u32 i; struct bam_desc_hw *desc; - unsigned int num_alloc = 0; - + unsigned int num_alloc; if (!is_slave_direction(direction)) { dev_err(bdev->dev, "invalid dma direction\n"); return NULL; } - /* calculate number of required entries */ - for_each_sg(sgl, sg, sg_len, i) - num_alloc += DIV_ROUND_UP(sg_dma_len(sg), BAM_FIFO_SIZE); - /* allocate enough room to accommodate the number of entries */ - async_desc = kzalloc(struct_size(async_desc, desc, num_alloc), - GFP_NOWAIT); - + num_alloc = sg_nents_for_dma(sgl, sg_len, BAM_FIFO_SIZE); + async_desc = kzalloc_flex(*async_desc, desc, num_alloc, GFP_NOWAIT); if (!async_desc) return NULL; @@ -726,38 +718,37 @@ static int bam_dma_terminate_all(struct dma_chan *chan) { struct bam_chan *bchan = to_bam_chan(chan); struct bam_async_desc *async_desc, *tmp; - unsigned long flag; LIST_HEAD(head); /* remove all transactions, including active transaction */ - spin_lock_irqsave(&bchan->vc.lock, flag); - /* - * If we have transactions queued, then some might be committed to the - * hardware in the desc fifo. The only way to reset the desc fifo is - * to do a hardware reset (either by pipe or the entire block). - * bam_chan_init_hw() will trigger a pipe reset, and also reinit the - * pipe. If the pipe is left disabled (default state after pipe reset) - * and is accessed by a connected hardware engine, a fatal error in - * the BAM will occur. There is a small window where this could happen - * with bam_chan_init_hw(), but it is assumed that the caller has - * stopped activity on any attached hardware engine. Make sure to do - * this first so that the BAM hardware doesn't cause memory corruption - * by accessing freed resources. - */ - if (!list_empty(&bchan->desc_list)) { - async_desc = list_first_entry(&bchan->desc_list, - struct bam_async_desc, desc_node); - bam_chan_init_hw(bchan, async_desc->dir); - } + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { + /* + * If we have transactions queued, then some might be committed to the + * hardware in the desc fifo. The only way to reset the desc fifo is + * to do a hardware reset (either by pipe or the entire block). + * bam_chan_init_hw() will trigger a pipe reset, and also reinit the + * pipe. If the pipe is left disabled (default state after pipe reset) + * and is accessed by a connected hardware engine, a fatal error in + * the BAM will occur. There is a small window where this could happen + * with bam_chan_init_hw(), but it is assumed that the caller has + * stopped activity on any attached hardware engine. Make sure to do + * this first so that the BAM hardware doesn't cause memory corruption + * by accessing freed resources. + */ + if (!list_empty(&bchan->desc_list)) { + async_desc = list_first_entry(&bchan->desc_list, + struct bam_async_desc, desc_node); + bam_chan_init_hw(bchan, async_desc->dir); + } - list_for_each_entry_safe(async_desc, tmp, - &bchan->desc_list, desc_node) { - list_add(&async_desc->vd.node, &bchan->vc.desc_issued); - list_del(&async_desc->desc_node); - } + list_for_each_entry_safe(async_desc, tmp, + &bchan->desc_list, desc_node) { + list_add(&async_desc->vd.node, &bchan->vc.desc_issued); + list_del(&async_desc->desc_node); + } - vchan_get_all_descriptors(&bchan->vc, &head); - spin_unlock_irqrestore(&bchan->vc.lock, flag); + vchan_get_all_descriptors(&bchan->vc, &head); + } vchan_dma_desc_free_list(&bchan->vc, &head); @@ -773,17 +764,16 @@ static int bam_pause(struct dma_chan *chan) { struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; - unsigned long flag; int ret; ret = pm_runtime_get_sync(bdev->dev); if (ret < 0) return ret; - spin_lock_irqsave(&bchan->vc.lock, flag); - writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); - bchan->paused = 1; - spin_unlock_irqrestore(&bchan->vc.lock, flag); + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { + writel_relaxed(1, bam_addr(bdev, bchan->id, BAM_P_HALT)); + bchan->paused = 1; + } pm_runtime_mark_last_busy(bdev->dev); pm_runtime_put_autosuspend(bdev->dev); @@ -799,17 +789,16 @@ static int bam_resume(struct dma_chan *chan) { struct bam_chan *bchan = to_bam_chan(chan); struct bam_device *bdev = bchan->bdev; - unsigned long flag; int ret; ret = pm_runtime_get_sync(bdev->dev); if (ret < 0) return ret; - spin_lock_irqsave(&bchan->vc.lock, flag); - writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); - bchan->paused = 0; - spin_unlock_irqrestore(&bchan->vc.lock, flag); + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { + writel_relaxed(0, bam_addr(bdev, bchan->id, BAM_P_HALT)); + bchan->paused = 0; + } pm_runtime_mark_last_busy(bdev->dev); pm_runtime_put_autosuspend(bdev->dev); @@ -826,7 +815,6 @@ static int bam_resume(struct dma_chan *chan) static u32 process_channel_irqs(struct bam_device *bdev) { u32 i, srcs, pipe_stts, offset, avail; - unsigned long flags; struct bam_async_desc *async_desc, *tmp; srcs = readl_relaxed(bam_addr(bdev, 0, BAM_IRQ_SRCS_EE)); @@ -846,7 +834,7 @@ static u32 process_channel_irqs(struct bam_device *bdev) writel_relaxed(pipe_stts, bam_addr(bdev, i, BAM_P_IRQ_CLR)); - spin_lock_irqsave(&bchan->vc.lock, flags); + guard(spinlock_irqsave)(&bchan->vc.lock); offset = readl_relaxed(bam_addr(bdev, i, BAM_P_SW_OFSTS)) & P_SW_OFSTS_MASK; @@ -885,8 +873,6 @@ static u32 process_channel_irqs(struct bam_device *bdev) } list_del(&async_desc->desc_node); } - - spin_unlock_irqrestore(&bchan->vc.lock, flags); } return srcs; @@ -950,7 +936,6 @@ static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie, int ret; size_t residue = 0; unsigned int i; - unsigned long flags; ret = dma_cookie_status(chan, cookie, txstate); if (ret == DMA_COMPLETE) @@ -959,23 +944,22 @@ static enum dma_status bam_tx_status(struct dma_chan *chan, dma_cookie_t cookie, if (!txstate) return bchan->paused ? DMA_PAUSED : ret; - spin_lock_irqsave(&bchan->vc.lock, flags); - vd = vchan_find_desc(&bchan->vc, cookie); - if (vd) { - residue = container_of(vd, struct bam_async_desc, vd)->length; - } else { - list_for_each_entry(async_desc, &bchan->desc_list, desc_node) { - if (async_desc->vd.tx.cookie != cookie) - continue; + scoped_guard(spinlock_irqsave, &bchan->vc.lock) { + vd = vchan_find_desc(&bchan->vc, cookie); + if (vd) { + residue = container_of(vd, struct bam_async_desc, vd)->length; + } else { + list_for_each_entry(async_desc, &bchan->desc_list, desc_node) { + if (async_desc->vd.tx.cookie != cookie) + continue; - for (i = 0; i < async_desc->num_desc; i++) - residue += le16_to_cpu( - async_desc->curr_desc[i].size); + for (i = 0; i < async_desc->num_desc; i++) + residue += le16_to_cpu( + async_desc->curr_desc[i].size); + } } } - spin_unlock_irqrestore(&bchan->vc.lock, flags); - dma_set_residue(txstate, residue); if (ret == DMA_IN_PROGRESS && bchan->paused) @@ -1116,17 +1100,16 @@ static void dma_tasklet(struct tasklet_struct *t) { struct bam_device *bdev = from_tasklet(bdev, t, task); struct bam_chan *bchan; - unsigned long flags; unsigned int i; /* go through the channels and kick off transactions */ for (i = 0; i < bdev->num_channels; i++) { bchan = &bdev->channels[i]; - spin_lock_irqsave(&bchan->vc.lock, flags); + + guard(spinlock_irqsave)(&bchan->vc.lock); if (!list_empty(&bchan->vc.desc_issued) && !IS_BUSY(bchan)) bam_start_dma(bchan); - spin_unlock_irqrestore(&bchan->vc.lock, flags); } } @@ -1140,15 +1123,12 @@ static void dma_tasklet(struct tasklet_struct *t) static void bam_issue_pending(struct dma_chan *chan) { struct bam_chan *bchan = to_bam_chan(chan); - unsigned long flags; - spin_lock_irqsave(&bchan->vc.lock, flags); + guard(spinlock_irqsave)(&bchan->vc.lock); /* if work pending and idle, start a transaction */ if (vchan_issue_pending(&bchan->vc) && !IS_BUSY(bchan)) bam_start_dma(bchan); - - spin_unlock_irqrestore(&bchan->vc.lock, flags); } /** diff --git a/drivers/dma/qcom/gpi.c b/drivers/dma/qcom/gpi.c index 6e30f3aa401e..c9a6f610ffd9 100644 --- a/drivers/dma/qcom/gpi.c +++ b/drivers/dma/qcom/gpi.c @@ -1836,7 +1836,7 @@ gpi_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!(flags & DMA_PREP_INTERRUPT) && (nr - nr_tre < 2)) return NULL; - gpi_desc = kzalloc(sizeof(*gpi_desc), GFP_NOWAIT); + gpi_desc = kzalloc_obj(*gpi_desc, GFP_NOWAIT); if (!gpi_desc) return NULL; diff --git a/drivers/dma/qcom/hidma.c b/drivers/dma/qcom/hidma.c index c2b3e4452e71..5a8dca8db5ce 100644 --- a/drivers/dma/qcom/hidma.c +++ b/drivers/dma/qcom/hidma.c @@ -352,7 +352,7 @@ static int hidma_alloc_chan_resources(struct dma_chan *dmach) /* Alloc descriptors for this channel */ for (i = 0; i < dmadev->nr_descriptors; i++) { - mdesc = kzalloc(sizeof(struct hidma_desc), GFP_NOWAIT); + mdesc = kzalloc_obj(struct hidma_desc, GFP_NOWAIT); if (!mdesc) { rc = -ENOMEM; break; diff --git a/drivers/dma/qcom/qcom_adm.c b/drivers/dma/qcom/qcom_adm.c index 6be54fddcee1..07fbe32d31fa 100644 --- a/drivers/dma/qcom/qcom_adm.c +++ b/drivers/dma/qcom/qcom_adm.c @@ -390,19 +390,18 @@ static struct dma_async_tx_descriptor *adm_prep_slave_sg(struct dma_chan *chan, } /* iterate through sgs and compute allocation size of structures */ - for_each_sg(sgl, sg, sg_len, i) { - if (achan->slave.device_fc) { + if (achan->slave.device_fc) { + for_each_sg(sgl, sg, sg_len, i) { box_count += DIV_ROUND_UP(sg_dma_len(sg) / burst, ADM_MAX_ROWS); if (sg_dma_len(sg) % burst) single_count++; - } else { - single_count += DIV_ROUND_UP(sg_dma_len(sg), - ADM_MAX_XFER); } + } else { + single_count = sg_nents_for_dma(sgl, sg_len, ADM_MAX_XFER); } - async_desc = kzalloc(sizeof(*async_desc), GFP_NOWAIT); + async_desc = kzalloc_obj(*async_desc, GFP_NOWAIT); if (!async_desc) { dev_err(adev->dev, "not enough memory for async_desc struct\n"); return NULL; diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index dc1a9a05252e..a6fa431530e3 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -526,7 +526,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_desc *txd; struct scatterlist *sgent; - unsigned i, j = sglen; + unsigned int i, j; size_t size = 0; /* SA11x0 channels can only operate in their native direction */ @@ -542,10 +542,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( for_each_sg(sg, sgent, sglen, i) { dma_addr_t addr = sg_dma_address(sgent); - unsigned int len = sg_dma_len(sgent); - if (len > DMA_MAX_SIZE) - j += DIV_ROUND_UP(len, DMA_MAX_SIZE & ~DMA_ALIGN) - 1; if (addr & DMA_ALIGN) { dev_dbg(chan->device->dev, "vchan %p: bad buffer alignment: %pad\n", &c->vc, &addr); @@ -553,7 +550,8 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( } } - txd = kzalloc(struct_size(txd, sg, j), GFP_ATOMIC); + j = sg_nents_for_dma(sg, sglen, DMA_MAX_SIZE & ~DMA_ALIGN); + txd = kzalloc_flex(*txd, sg, j, GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; @@ -623,7 +621,7 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( if (sglen == 0) return NULL; - txd = kzalloc(struct_size(txd, sg, sglen), GFP_ATOMIC); + txd = kzalloc_flex(*txd, sg, sglen, GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; @@ -850,7 +848,7 @@ static int sa11x0_dma_init_dmadev(struct dma_device *dmadev, for (i = 0; i < ARRAY_SIZE(chan_desc); i++) { struct sa11x0_dma_chan *c; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) { dev_err(dev, "no memory for channel %u\n", i); return -ENOMEM; @@ -909,7 +907,7 @@ static int sa11x0_dma_probe(struct platform_device *pdev) if (!res) return -ENXIO; - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { ret = -ENOMEM; goto err_alloc; diff --git a/drivers/dma/sf-pdma/sf-pdma.c b/drivers/dma/sf-pdma/sf-pdma.c index 7ad3c29be146..b3cba11b6203 100644 --- a/drivers/dma/sf-pdma/sf-pdma.c +++ b/drivers/dma/sf-pdma/sf-pdma.c @@ -56,7 +56,7 @@ static struct sf_pdma_desc *sf_pdma_alloc_desc(struct sf_pdma_chan *chan) { struct sf_pdma_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/sh/rcar-dmac.c b/drivers/dma/sh/rcar-dmac.c index 475a347cae1b..44eab2d21d54 100644 --- a/drivers/dma/sh/rcar-dmac.c +++ b/drivers/dma/sh/rcar-dmac.c @@ -1254,7 +1254,7 @@ rcar_dmac_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, * Allocate the sg list dynamically as it would consume too much stack * space. */ - sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_NOWAIT); + sgl = kmalloc_objs(*sgl, sg_len, GFP_NOWAIT); if (!sgl) return NULL; diff --git a/drivers/dma/sh/rz-dmac.c b/drivers/dma/sh/rz-dmac.c index 9e5f088355e2..d84ca551b2bf 100644 --- a/drivers/dma/sh/rz-dmac.c +++ b/drivers/dma/sh/rz-dmac.c @@ -65,7 +65,6 @@ struct rz_dmac_chan { void __iomem *ch_base; void __iomem *ch_cmn_base; unsigned int index; - int irq; struct rz_dmac_desc *desc; int descs_allocated; @@ -444,7 +443,7 @@ static int rz_dmac_alloc_chan_resources(struct dma_chan *chan) while (channel->descs_allocated < RZ_DMAC_MAX_CHAN_DESCRIPTORS) { struct rz_dmac_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) break; @@ -800,29 +799,27 @@ static int rz_dmac_chan_probe(struct rz_dmac *dmac, struct rz_lmdesc *lmdesc; char pdev_irqname[6]; char *irqname; - int ret; + int irq, ret; channel->index = index; channel->mid_rid = -EINVAL; /* Request the channel interrupt. */ scnprintf(pdev_irqname, sizeof(pdev_irqname), "ch%u", index); - channel->irq = platform_get_irq_byname(pdev, pdev_irqname); - if (channel->irq < 0) - return channel->irq; + irq = platform_get_irq_byname(pdev, pdev_irqname); + if (irq < 0) + return irq; irqname = devm_kasprintf(dmac->dev, GFP_KERNEL, "%s:%u", dev_name(dmac->dev), index); if (!irqname) return -ENOMEM; - ret = devm_request_threaded_irq(dmac->dev, channel->irq, - rz_dmac_irq_handler, + ret = devm_request_threaded_irq(dmac->dev, irq, rz_dmac_irq_handler, rz_dmac_irq_handler_thread, 0, irqname, channel); if (ret) { - dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", - channel->irq, ret); + dev_err(dmac->dev, "failed to request IRQ %u (%d)\n", irq, ret); return ret; } diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index 834741adadaa..89a78e685b1d 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c @@ -143,7 +143,7 @@ static dma_cookie_t shdma_tx_submit(struct dma_async_tx_descriptor *tx) } schan->pm_state = SHDMA_PM_ESTABLISHED; - ret = pm_runtime_put(schan->dev); + pm_runtime_put(schan->dev); spin_unlock_irq(&schan->chan_lock); return ret; @@ -577,12 +577,11 @@ static struct dma_async_tx_descriptor *shdma_prep_sg(struct shdma_chan *schan, struct scatterlist *sg; struct shdma_desc *first = NULL, *new = NULL /* compiler... */; LIST_HEAD(tx_list); - int chunks = 0; + int chunks; unsigned long irq_flags; int i; - for_each_sg(sgl, sg, sg_len, i) - chunks += DIV_ROUND_UP(sg_dma_len(sg), schan->max_xfer_len); + chunks = sg_nents_for_dma(sgl, sg_len, schan->max_xfer_len); /* Have to lock the whole loop to protect against concurrent release */ spin_lock_irqsave(&schan->chan_lock, irq_flags); @@ -741,7 +740,7 @@ static struct dma_async_tx_descriptor *shdma_prep_dma_cyclic( * Allocate the sg list dynamically as it would consume too much stack * space. */ - sgl = kmalloc_array(sg_len, sizeof(*sgl), GFP_KERNEL); + sgl = kmalloc_objs(*sgl, sg_len); if (!sgl) return NULL; @@ -1013,7 +1012,7 @@ int shdma_init(struct device *dev, struct shdma_dev *sdev, !sdev->ops->desc_completed) return -EINVAL; - sdev->schan = kcalloc(chan_num, sizeof(*sdev->schan), GFP_KERNEL); + sdev->schan = kzalloc_objs(*sdev->schan, chan_num); if (!sdev->schan) return -ENOMEM; diff --git a/drivers/dma/sh/usb-dmac.c b/drivers/dma/sh/usb-dmac.c index b42e5a66fd95..16509be0d360 100644 --- a/drivers/dma/sh/usb-dmac.c +++ b/drivers/dma/sh/usb-dmac.c @@ -266,7 +266,7 @@ static int usb_dmac_desc_alloc(struct usb_dmac_chan *chan, unsigned int sg_len, struct usb_dmac_desc *desc; unsigned long flags; - desc = kzalloc(struct_size(desc, sg, sg_len), gfp); + desc = kzalloc_flex(*desc, sg, sg_len, gfp); if (!desc) return -ENOMEM; diff --git a/drivers/dma/sprd-dma.c b/drivers/dma/sprd-dma.c index 6207e0b185e1..087fea3af2e4 100644 --- a/drivers/dma/sprd-dma.c +++ b/drivers/dma/sprd-dma.c @@ -901,7 +901,7 @@ sprd_dma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, enum sprd_dma_datawidth datawidth; u32 step, temp; - sdesc = kzalloc(sizeof(*sdesc), GFP_NOWAIT); + sdesc = kzalloc_obj(*sdesc, GFP_NOWAIT); if (!sdesc) return NULL; @@ -986,7 +986,7 @@ sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, (flags >> SPRD_DMA_TRG_MODE_SHIFT) & SPRD_DMA_TRG_MODE_MASK; schan->int_type = flags & SPRD_DMA_INT_TYPE_MASK; - sdesc = kzalloc(sizeof(*sdesc), GFP_NOWAIT); + sdesc = kzalloc_obj(*sdesc, GFP_NOWAIT); if (!sdesc) return NULL; diff --git a/drivers/dma/st_fdma.c b/drivers/dma/st_fdma.c index dc2ab7d16cf2..d9547017f3bd 100644 --- a/drivers/dma/st_fdma.c +++ b/drivers/dma/st_fdma.c @@ -68,7 +68,7 @@ static void st_fdma_dreq_put(struct st_fdma_chan *fchan) { struct st_fdma_dev *fdev = fchan->fdev; - dev_dbg(fdev->dev, "put dreq_line:%#x\n", fchan->dreq_line); + dev_dbg(fdev->dev, "put dreq_line:%#lx\n", fchan->dreq_line); clear_bit(fchan->dreq_line, &fdev->dreq_mask); } @@ -241,7 +241,7 @@ static struct st_fdma_desc *st_fdma_alloc_desc(struct st_fdma_chan *fchan, struct st_fdma_desc *fdesc; int i; - fdesc = kzalloc(struct_size(fdesc, node, sg_len), GFP_NOWAIT); + fdesc = kzalloc_flex(*fdesc, node, sg_len, GFP_NOWAIT); if (!fdesc) return NULL; diff --git a/drivers/dma/st_fdma.h b/drivers/dma/st_fdma.h index f296412e96b6..f1e746f7bc7d 100644 --- a/drivers/dma/st_fdma.h +++ b/drivers/dma/st_fdma.h @@ -120,7 +120,7 @@ struct st_fdma_chan { struct dma_slave_config scfg; struct st_fdma_cfg cfg; - int dreq_line; + long dreq_line; struct virt_dma_chan vchan; struct st_fdma_desc *fdesc; diff --git a/drivers/dma/ste_dma40.c b/drivers/dma/ste_dma40.c index d52e1685aed5..9b803c0aec25 100644 --- a/drivers/dma/ste_dma40.c +++ b/drivers/dma/ste_dma40.c @@ -1452,7 +1452,6 @@ static int d40_pause(struct dma_chan *chan) res = d40_channel_execute_command(d40c, D40_DMA_SUSPEND_REQ); - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); return res; @@ -1479,7 +1478,6 @@ static int d40_resume(struct dma_chan *chan) if (d40_residue(d40c) || d40_tx_is_linked(d40c)) res = d40_channel_execute_command(d40c, D40_DMA_RUN); - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); return res; @@ -1581,7 +1579,6 @@ static void dma_tc_handle(struct d40_chan *d40c) if (d40_queue_start(d40c) == NULL) { d40c->busy = false; - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); } @@ -2054,16 +2051,13 @@ static int d40_free_dma(struct d40_chan *d40c) else d40c->base->lookup_phy_chans[phy->num] = NULL; - if (d40c->busy) { - pm_runtime_mark_last_busy(d40c->base->dev); + if (d40c->busy) pm_runtime_put_autosuspend(d40c->base->dev); - } d40c->busy = false; d40c->phy_chan = NULL; d40c->configured = false; mark_last_busy: - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); return res; } @@ -2466,7 +2460,6 @@ static int d40_alloc_chan_resources(struct dma_chan *chan) if (is_free_phy) d40_config_write(d40c); mark_last_busy: - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); spin_unlock_irqrestore(&d40c->lock, flags); return err; @@ -2536,7 +2529,7 @@ dma40_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, struct scatterlist *sg; int i; - sg = kcalloc(periods + 1, sizeof(struct scatterlist), GFP_NOWAIT); + sg = kzalloc_objs(struct scatterlist, periods + 1, GFP_NOWAIT); if (!sg) return NULL; @@ -2618,12 +2611,9 @@ static int d40_terminate_all(struct dma_chan *chan) chan_err(d40c, "Failed to stop channel\n"); d40_term_all(d40c); - pm_runtime_mark_last_busy(d40c->base->dev); pm_runtime_put_autosuspend(d40c->base->dev); - if (d40c->busy) { - pm_runtime_mark_last_busy(d40c->base->dev); + if (d40c->busy) pm_runtime_put_autosuspend(d40c->base->dev); - } d40c->busy = false; spin_unlock_irqrestore(&d40c->lock, flags); diff --git a/drivers/dma/stm32/stm32-dma.c b/drivers/dma/stm32/stm32-dma.c index 04389936c8a6..d3ad78562a14 100644 --- a/drivers/dma/stm32/stm32-dma.c +++ b/drivers/dma/stm32/stm32-dma.c @@ -1101,7 +1101,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_slave_sg( return NULL; } - desc = kzalloc(struct_size(desc, sg_req, sg_len), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg_req, sg_len, GFP_NOWAIT); if (!desc) return NULL; desc->num_sgs = sg_len; @@ -1213,7 +1213,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_cyclic( num_periods = buf_len / period_len; - desc = kzalloc(struct_size(desc, sg_req, num_periods), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg_req, num_periods, GFP_NOWAIT); if (!desc) return NULL; desc->num_sgs = num_periods; @@ -1250,7 +1250,7 @@ static struct dma_async_tx_descriptor *stm32_dma_prep_dma_memcpy( int dma_burst, i; num_sgs = DIV_ROUND_UP(len, STM32_DMA_ALIGNED_MAX_DATA_ITEMS); - desc = kzalloc(struct_size(desc, sg_req, num_sgs), GFP_NOWAIT); + desc = kzalloc_flex(*desc, sg_req, num_sgs, GFP_NOWAIT); if (!desc) return NULL; desc->num_sgs = num_sgs; diff --git a/drivers/dma/stm32/stm32-dma3.c b/drivers/dma/stm32/stm32-dma3.c index 50e7106c5cb7..4724e7fa0008 100644 --- a/drivers/dma/stm32/stm32-dma3.c +++ b/drivers/dma/stm32/stm32-dma3.c @@ -288,6 +288,7 @@ struct stm32_dma3_chan { u32 fifo_size; u32 max_burst; bool semaphore_mode; + bool semaphore_taken; struct stm32_dma3_dt_conf dt_config; struct dma_slave_config dma_config; u8 config_set; @@ -332,6 +333,11 @@ static struct device *chan2dev(struct stm32_dma3_chan *chan) return &chan->vchan.chan.dev->device; } +static struct device *ddata2dev(struct stm32_dma3_ddata *ddata) +{ + return ddata->dma_dev.dev; +} + static void stm32_dma3_chan_dump_reg(struct stm32_dma3_chan *chan) { struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); @@ -409,7 +415,7 @@ static struct stm32_dma3_swdesc *stm32_dma3_chan_desc_alloc(struct stm32_dma3_ch return NULL; } - swdesc = kzalloc(struct_size(swdesc, lli, count), GFP_NOWAIT); + swdesc = kzalloc_flex(*swdesc, lli, count, GFP_NOWAIT); if (!swdesc) return NULL; swdesc->lli_size = count; @@ -1063,14 +1069,53 @@ static irqreturn_t stm32_dma3_chan_irq(int irq, void *devid) return IRQ_HANDLED; } +static int stm32_dma3_get_chan_sem(struct stm32_dma3_chan *chan) +{ + struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); + u32 csemcr, ccid; + + csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(chan->id)); + /* Make an attempt to take the channel semaphore if not already taken */ + if (!(csemcr & CSEMCR_SEM_MUTEX)) { + writel_relaxed(CSEMCR_SEM_MUTEX, ddata->base + STM32_DMA3_CSEMCR(chan->id)); + csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(chan->id)); + } + + /* Check if channel is under CID1 control */ + ccid = FIELD_GET(CSEMCR_SEM_CCID, csemcr); + if (!(csemcr & CSEMCR_SEM_MUTEX) || ccid != CCIDCFGR_CID1) + goto bad_cid; + + chan->semaphore_taken = true; + dev_dbg(chan2dev(chan), "under CID1 control (semcr=0x%08x)\n", csemcr); + + return 0; + +bad_cid: + chan->semaphore_taken = false; + dev_err(chan2dev(chan), "not under CID1 control (in-use by CID%d)\n", ccid); + + return -EACCES; +} + +static void stm32_dma3_put_chan_sem(struct stm32_dma3_chan *chan) +{ + struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); + + if (chan->semaphore_taken) { + writel_relaxed(0, ddata->base + STM32_DMA3_CSEMCR(chan->id)); + chan->semaphore_taken = false; + dev_dbg(chan2dev(chan), "no more under CID1 control\n"); + } +} + static int stm32_dma3_alloc_chan_resources(struct dma_chan *c) { struct stm32_dma3_chan *chan = to_stm32_dma3_chan(c); struct stm32_dma3_ddata *ddata = to_stm32_dma3_ddata(chan); - u32 id = chan->id, csemcr, ccid; int ret; - ret = pm_runtime_resume_and_get(ddata->dma_dev.dev); + ret = pm_runtime_resume_and_get(ddata2dev(ddata)); if (ret < 0) return ret; @@ -1092,16 +1137,9 @@ static int stm32_dma3_alloc_chan_resources(struct dma_chan *c) /* Take the channel semaphore */ if (chan->semaphore_mode) { - writel_relaxed(CSEMCR_SEM_MUTEX, ddata->base + STM32_DMA3_CSEMCR(id)); - csemcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(id)); - ccid = FIELD_GET(CSEMCR_SEM_CCID, csemcr); - /* Check that the channel is well taken */ - if (ccid != CCIDCFGR_CID1) { - dev_err(chan2dev(chan), "Not under CID1 control (in-use by CID%d)\n", ccid); - ret = -EPERM; + ret = stm32_dma3_get_chan_sem(chan); + if (ret) goto err_pool_destroy; - } - dev_dbg(chan2dev(chan), "Under CID1 control (semcr=0x%08x)\n", csemcr); } return 0; @@ -1111,7 +1149,7 @@ static int stm32_dma3_alloc_chan_resources(struct dma_chan *c) chan->lli_pool = NULL; err_put_sync: - pm_runtime_put_sync(ddata->dma_dev.dev); + pm_runtime_put_sync(ddata2dev(ddata)); return ret; } @@ -1135,9 +1173,9 @@ static void stm32_dma3_free_chan_resources(struct dma_chan *c) /* Release the channel semaphore */ if (chan->semaphore_mode) - writel_relaxed(0, ddata->base + STM32_DMA3_CSEMCR(chan->id)); + stm32_dma3_put_chan_sem(chan); - pm_runtime_put_sync(ddata->dma_dev.dev); + pm_runtime_put_sync(ddata2dev(ddata)); /* Reset configuration */ memset(&chan->dt_config, 0, sizeof(chan->dt_config)); @@ -1204,6 +1242,10 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_memcpy(struct dma_cha bool prevent_refactor = !!FIELD_GET(STM32_DMA3_DT_NOPACK, chan->dt_config.tr_conf) || !!FIELD_GET(STM32_DMA3_DT_NOREFACT, chan->dt_config.tr_conf); + /* Semaphore could be lost during suspend/resume */ + if (chan->semaphore_mode && !chan->semaphore_taken) + return NULL; + count = stm32_dma3_get_ll_count(chan, len, prevent_refactor); swdesc = stm32_dma3_chan_desc_alloc(chan, count); @@ -1264,6 +1306,10 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_slave_sg(struct dma_chan !!FIELD_GET(STM32_DMA3_DT_NOREFACT, chan->dt_config.tr_conf); int ret; + /* Semaphore could be lost during suspend/resume */ + if (chan->semaphore_mode && !chan->semaphore_taken) + return NULL; + count = 0; for_each_sg(sgl, sg, sg_len, i) count += stm32_dma3_get_ll_count(chan, sg_dma_len(sg), prevent_refactor); @@ -1350,6 +1396,10 @@ static struct dma_async_tx_descriptor *stm32_dma3_prep_dma_cyclic(struct dma_cha u32 count, i, ctr1, ctr2; int ret; + /* Semaphore could be lost during suspend/resume */ + if (chan->semaphore_mode && !chan->semaphore_taken) + return NULL; + if (!buf_len || !period_len || period_len > STM32_DMA3_MAX_BLOCK_SIZE) { dev_err(chan2dev(chan), "Invalid buffer/period length\n"); return NULL; @@ -1565,11 +1615,11 @@ static bool stm32_dma3_filter_fn(struct dma_chan *c, void *fn_param) if (!(mask & BIT(chan->id))) return false; - ret = pm_runtime_resume_and_get(ddata->dma_dev.dev); + ret = pm_runtime_resume_and_get(ddata2dev(ddata)); if (ret < 0) return false; semcr = readl_relaxed(ddata->base + STM32_DMA3_CSEMCR(chan->id)); - pm_runtime_put_sync(ddata->dma_dev.dev); + pm_runtime_put_sync(ddata2dev(ddata)); /* Check if chan is free */ if (semcr & CSEMCR_SEM_MUTEX) @@ -1591,7 +1641,7 @@ static struct dma_chan *stm32_dma3_of_xlate(struct of_phandle_args *dma_spec, st struct dma_chan *c; if (dma_spec->args_count < 3) { - dev_err(ddata->dma_dev.dev, "Invalid args count\n"); + dev_err(ddata2dev(ddata), "Invalid args count\n"); return NULL; } @@ -1600,14 +1650,14 @@ static struct dma_chan *stm32_dma3_of_xlate(struct of_phandle_args *dma_spec, st conf.tr_conf = dma_spec->args[2]; if (conf.req_line >= ddata->dma_requests) { - dev_err(ddata->dma_dev.dev, "Invalid request line\n"); + dev_err(ddata2dev(ddata), "Invalid request line\n"); return NULL; } /* Request dma channel among the generic dma controller list */ c = dma_request_channel(mask, stm32_dma3_filter_fn, &conf); if (!c) { - dev_err(ddata->dma_dev.dev, "No suitable channel found\n"); + dev_err(ddata2dev(ddata), "No suitable channel found\n"); return NULL; } @@ -1620,6 +1670,7 @@ static struct dma_chan *stm32_dma3_of_xlate(struct of_phandle_args *dma_spec, st static u32 stm32_dma3_check_rif(struct stm32_dma3_ddata *ddata) { + struct device *dev = ddata2dev(ddata); u32 chan_reserved, mask = 0, i, ccidcfgr, invalid_cid = 0; /* Reserve Secure channels */ @@ -1631,7 +1682,7 @@ static u32 stm32_dma3_check_rif(struct stm32_dma3_ddata *ddata) * In case CID filtering is not configured, dma-channel-mask property can be used to * specify available DMA channels to the kernel. */ - of_property_read_u32(ddata->dma_dev.dev->of_node, "dma-channel-mask", &mask); + of_property_read_u32(dev->of_node, "dma-channel-mask", &mask); /* Reserve !CID-filtered not in dma-channel-mask, static CID != CID1, CID1 not allowed */ for (i = 0; i < ddata->dma_channels; i++) { @@ -1651,7 +1702,7 @@ static u32 stm32_dma3_check_rif(struct stm32_dma3_ddata *ddata) ddata->chans[i].semaphore_mode = true; } } - dev_dbg(ddata->dma_dev.dev, "chan%d: %s mode, %s\n", i, + dev_dbg(dev, "chan%d: %s mode, %s\n", i, !(ccidcfgr & CCIDCFGR_CFEN) ? "!CID-filtered" : ddata->chans[i].semaphore_mode ? "Semaphore" : "Static CID", (chan_reserved & BIT(i)) ? "denied" : @@ -1659,7 +1710,7 @@ static u32 stm32_dma3_check_rif(struct stm32_dma3_ddata *ddata) } if (invalid_cid) - dev_warn(ddata->dma_dev.dev, "chan%*pbl have invalid CID configuration\n", + dev_warn(dev, "chan%*pbl have invalid CID configuration\n", ddata->dma_channels, &invalid_cid); return chan_reserved; @@ -1899,8 +1950,69 @@ static int stm32_dma3_runtime_resume(struct device *dev) return ret; } +static int stm32_dma3_pm_suspend(struct device *dev) +{ + struct stm32_dma3_ddata *ddata = dev_get_drvdata(dev); + struct dma_device *dma_dev = &ddata->dma_dev; + struct dma_chan *c; + int ccr, ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + + list_for_each_entry(c, &dma_dev->channels, device_node) { + struct stm32_dma3_chan *chan = to_stm32_dma3_chan(c); + + ccr = readl_relaxed(ddata->base + STM32_DMA3_CCR(chan->id)); + if (ccr & CCR_EN) { + dev_warn(dev, "Suspend is prevented: %s still in use by %s\n", + dma_chan_name(c), dev_name(c->slave)); + pm_runtime_put_sync(dev); + return -EBUSY; + } + } + + pm_runtime_put_sync(dev); + + pm_runtime_force_suspend(dev); + + return 0; +} + +static int stm32_dma3_pm_resume(struct device *dev) +{ + struct stm32_dma3_ddata *ddata = dev_get_drvdata(dev); + struct dma_device *dma_dev = &ddata->dma_dev; + struct dma_chan *c; + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret < 0) + return ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + + /* + * Channel semaphores need to be restored in case of registers reset during low power. + * stm32_dma3_get_chan_sem() will prior check the semaphore status. + */ + list_for_each_entry(c, &dma_dev->channels, device_node) { + struct stm32_dma3_chan *chan = to_stm32_dma3_chan(c); + + if (chan->semaphore_mode && chan->semaphore_taken) + stm32_dma3_get_chan_sem(chan); + } + + pm_runtime_put_sync(dev); + + return 0; +} + static const struct dev_pm_ops stm32_dma3_pm_ops = { - SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) + SYSTEM_SLEEP_PM_OPS(stm32_dma3_pm_suspend, stm32_dma3_pm_resume) RUNTIME_PM_OPS(stm32_dma3_runtime_suspend, stm32_dma3_runtime_resume, NULL) }; @@ -1914,12 +2026,7 @@ static struct platform_driver stm32_dma3_driver = { }, }; -static int __init stm32_dma3_init(void) -{ - return platform_driver_register(&stm32_dma3_driver); -} - -subsys_initcall(stm32_dma3_init); +module_platform_driver(stm32_dma3_driver); MODULE_DESCRIPTION("STM32 DMA3 controller driver"); MODULE_AUTHOR("Amelie Delaunay "); diff --git a/drivers/dma/stm32/stm32-dmamux.c b/drivers/dma/stm32/stm32-dmamux.c index db13498b9c9f..57318715d9f3 100644 --- a/drivers/dma/stm32/stm32-dmamux.c +++ b/drivers/dma/stm32/stm32-dmamux.c @@ -104,7 +104,7 @@ static void *stm32_dmamux_route_allocate(struct of_phandle_args *dma_spec, goto err_put_pdev; } - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) { ret = -ENOMEM; goto err_put_pdev; diff --git a/drivers/dma/stm32/stm32-mdma.c b/drivers/dma/stm32/stm32-mdma.c index 080c1c725216..e3bbdc9ee36e 100644 --- a/drivers/dma/stm32/stm32-mdma.c +++ b/drivers/dma/stm32/stm32-mdma.c @@ -318,7 +318,7 @@ static struct stm32_mdma_desc *stm32_mdma_alloc_desc( struct stm32_mdma_desc *desc; int i; - desc = kzalloc(struct_size(desc, node, count), GFP_NOWAIT); + desc = kzalloc_flex(*desc, node, count, GFP_NOWAIT); if (!desc) return NULL; desc->count = count; @@ -731,7 +731,7 @@ static int stm32_mdma_setup_xfer(struct stm32_mdma_chan *chan, struct stm32_mdma_chan_config *chan_config = &chan->chan_config; struct scatterlist *sg; dma_addr_t src_addr, dst_addr; - u32 m2m_hw_period, ccr, ctcr, ctbr; + u32 m2m_hw_period = 0, ccr = 0, ctcr, ctbr; int i, ret = 0; if (chan_config->m2m_hw) diff --git a/drivers/dma/sun4i-dma.c b/drivers/dma/sun4i-dma.c index 00d2fd38d17f..d2321f7287d2 100644 --- a/drivers/dma/sun4i-dma.c +++ b/drivers/dma/sun4i-dma.c @@ -532,7 +532,7 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest, if (ret) return NULL; - promise = kzalloc(sizeof(*promise), GFP_NOWAIT); + promise = kzalloc_obj(*promise, GFP_NOWAIT); if (!promise) return NULL; @@ -595,7 +595,7 @@ generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest, struct sun4i_dma_promise *promise; int ret; - promise = kzalloc(sizeof(*promise), GFP_NOWAIT); + promise = kzalloc_obj(*promise, GFP_NOWAIT); if (!promise) return NULL; @@ -648,7 +648,7 @@ static struct sun4i_dma_contract *generate_dma_contract(void) { struct sun4i_dma_contract *contract; - contract = kzalloc(sizeof(*contract), GFP_NOWAIT); + contract = kzalloc_obj(*contract, GFP_NOWAIT); if (!contract) return NULL; diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c index 2215ff877bf7..a9a254dbf8cb 100644 --- a/drivers/dma/sun6i-dma.c +++ b/drivers/dma/sun6i-dma.c @@ -583,6 +583,22 @@ static irqreturn_t sun6i_dma_interrupt(int irq, void *dev_id) return ret; } +static u32 find_burst_size(const u32 burst_lengths, u32 maxburst) +{ + if (!maxburst) + return 1; + + if (BIT(maxburst) & burst_lengths) + return maxburst; + + /* Hardware only does power-of-two bursts. */ + for (u32 burst = rounddown_pow_of_two(maxburst); burst > 0; burst /= 2) + if (BIT(burst) & burst_lengths) + return burst; + + return 1; +} + static int set_config(struct sun6i_dma_dev *sdev, struct dma_slave_config *sconfig, enum dma_transfer_direction direction, @@ -616,15 +632,13 @@ static int set_config(struct sun6i_dma_dev *sdev, return -EINVAL; if (!(BIT(dst_addr_width) & sdev->slave.dst_addr_widths)) return -EINVAL; - if (!(BIT(src_maxburst) & sdev->cfg->src_burst_lengths)) - return -EINVAL; - if (!(BIT(dst_maxburst) & sdev->cfg->dst_burst_lengths)) - return -EINVAL; src_width = convert_buswidth(src_addr_width); dst_width = convert_buswidth(dst_addr_width); - dst_burst = convert_burst(dst_maxburst); - src_burst = convert_burst(src_maxburst); + src_burst = find_burst_size(sdev->cfg->src_burst_lengths, src_maxburst); + dst_burst = find_burst_size(sdev->cfg->dst_burst_lengths, dst_maxburst); + dst_burst = convert_burst(dst_burst); + src_burst = convert_burst(src_burst); *p_cfg = DMA_CHAN_CFG_SRC_WIDTH(src_width) | DMA_CHAN_CFG_DST_WIDTH(dst_width); @@ -664,7 +678,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy( if (!len) return NULL; - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; @@ -722,7 +736,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg( return NULL; } - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; @@ -805,7 +819,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( return NULL; } - txd = kzalloc(sizeof(*txd), GFP_NOWAIT); + txd = kzalloc_obj(*txd, GFP_NOWAIT); if (!txd) return NULL; @@ -826,6 +840,11 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( v_lli->cfg = lli_cfg; sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port); sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE); + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", + __func__, vchan->vc.chan.chan_id, + &sconfig->dst_addr, &buf_addr, + buf_len, flags); } else { sun6i_dma_set_addr(sdev, v_lli, sconfig->src_addr, @@ -833,6 +852,11 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic( v_lli->cfg = lli_cfg; sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM); sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE); + dev_dbg(chan2dev(chan), + "%s; chan: %d, dest: %pad, src: %pad, len: %zu. flags: 0x%08lx\n", + __func__, vchan->vc.chan.chan_id, + &buf_addr, &sconfig->src_addr, + buf_len, flags); } prev = sun6i_dma_lli_add(prev, v_lli, p_lli, txd); diff --git a/drivers/dma/tegra186-gpc-dma.c b/drivers/dma/tegra186-gpc-dma.c index 4d6fe0efa76e..5948fbf32c21 100644 --- a/drivers/dma/tegra186-gpc-dma.c +++ b/drivers/dma/tegra186-gpc-dma.c @@ -908,7 +908,7 @@ tegra_dma_prep_dma_memset(struct dma_chan *dc, dma_addr_t dest, int value, /* Set burst size */ mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_16; - dma_desc = kzalloc(struct_size(dma_desc, sg_req, 1), GFP_NOWAIT); + dma_desc = kzalloc_flex(*dma_desc, sg_req, 1, GFP_NOWAIT); if (!dma_desc) return NULL; @@ -977,7 +977,7 @@ tegra_dma_prep_dma_memcpy(struct dma_chan *dc, dma_addr_t dest, /* Set burst size */ mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_16; - dma_desc = kzalloc(struct_size(dma_desc, sg_req, 1), GFP_NOWAIT); + dma_desc = kzalloc_flex(*dma_desc, sg_req, 1, GFP_NOWAIT); if (!dma_desc) return NULL; @@ -1070,7 +1070,7 @@ tegra_dma_prep_slave_sg(struct dma_chan *dc, struct scatterlist *sgl, else mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_2; - dma_desc = kzalloc(struct_size(dma_desc, sg_req, sg_len), GFP_NOWAIT); + dma_desc = kzalloc_flex(*dma_desc, sg_req, sg_len, GFP_NOWAIT); if (!dma_desc) return NULL; @@ -1205,8 +1205,7 @@ tegra_dma_prep_dma_cyclic(struct dma_chan *dc, dma_addr_t buf_addr, size_t buf_l mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_2; period_count = buf_len / period_len; - dma_desc = kzalloc(struct_size(dma_desc, sg_req, period_count), - GFP_NOWAIT); + dma_desc = kzalloc_flex(*dma_desc, sg_req, period_count, GFP_NOWAIT); if (!dma_desc) return NULL; diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index 14a61e53a41b..640b8a218c9a 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c @@ -282,7 +282,7 @@ static struct tegra_dma_desc *tegra_dma_desc_get(struct tegra_dma_channel *tdc) spin_unlock_irqrestore(&tdc->lock, flags); /* Allocate DMA desc */ - dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT); + dma_desc = kzalloc_obj(*dma_desc, GFP_NOWAIT); if (!dma_desc) return NULL; @@ -321,7 +321,7 @@ tegra_dma_sg_req_get(struct tegra_dma_channel *tdc) } spin_unlock_irqrestore(&tdc->lock, flags); - sg_req = kzalloc(sizeof(*sg_req), GFP_NOWAIT); + sg_req = kzalloc_obj(*sg_req, GFP_NOWAIT); return sg_req; } diff --git a/drivers/dma/tegra210-adma.c b/drivers/dma/tegra210-adma.c index 215bfef37ec6..14e0c408ed1e 100644 --- a/drivers/dma/tegra210-adma.c +++ b/drivers/dma/tegra210-adma.c @@ -755,7 +755,7 @@ static struct dma_async_tx_descriptor *tegra_adma_prep_dma_cyclic( return NULL; } - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; diff --git a/drivers/dma/ti/Kconfig b/drivers/dma/ti/Kconfig index dbf168146d35..cbc30ab62783 100644 --- a/drivers/dma/ti/Kconfig +++ b/drivers/dma/ti/Kconfig @@ -36,11 +36,12 @@ config DMA_OMAP config TI_K3_UDMA tristate "Texas Instruments UDMA support" - depends on ARCH_K3 + depends on ARCH_K3 || COMPILE_TEST depends on TI_SCI_PROTOCOL depends on TI_SCI_INTA_IRQCHIP select DMA_ENGINE select DMA_VIRTUAL_CHANNELS + select SOC_TI select TI_K3_RINGACC select TI_K3_PSIL help @@ -49,7 +50,7 @@ config TI_K3_UDMA config TI_K3_UDMA_GLUE_LAYER tristate "Texas Instruments UDMA Glue layer for non DMAengine users" - depends on ARCH_K3 + depends on ARCH_K3 || COMPILE_TEST depends on TI_K3_UDMA help Say y here to support the K3 NAVSS DMA glue interface diff --git a/drivers/dma/ti/cppi41.c b/drivers/dma/ti/cppi41.c index 8d8c3d6038fc..88756dccd62c 100644 --- a/drivers/dma/ti/cppi41.c +++ b/drivers/dma/ti/cppi41.c @@ -390,7 +390,6 @@ static int cppi41_dma_alloc_chan_resources(struct dma_chan *chan) if (!c->is_tx) cppi_writel(c->q_num, c->gcr_reg + RXHPCRA0); - pm_runtime_mark_last_busy(cdd->ddev.dev); pm_runtime_put_autosuspend(cdd->ddev.dev); return 0; @@ -411,7 +410,6 @@ static void cppi41_dma_free_chan_resources(struct dma_chan *chan) WARN_ON(!list_empty(&cdd->pending)); - pm_runtime_mark_last_busy(cdd->ddev.dev); pm_runtime_put_autosuspend(cdd->ddev.dev); } @@ -509,7 +507,6 @@ static void cppi41_dma_issue_pending(struct dma_chan *chan) cppi41_run_queue(cdd); spin_unlock_irqrestore(&cdd->lock, flags); - pm_runtime_mark_last_busy(cdd->ddev.dev); pm_runtime_put_autosuspend(cdd->ddev.dev); } @@ -627,7 +624,6 @@ static struct dma_async_tx_descriptor *cppi41_dma_prep_slave_sg( txd = &c->txd; err_out_not_ready: - pm_runtime_mark_last_busy(cdd->ddev.dev); pm_runtime_put_autosuspend(cdd->ddev.dev); return txd; @@ -1139,7 +1135,6 @@ static int cppi41_dma_probe(struct platform_device *pdev) if (ret) goto err_of; - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return 0; diff --git a/drivers/dma/ti/dma-crossbar.c b/drivers/dma/ti/dma-crossbar.c index e04077d542d2..f6d75ee94e8d 100644 --- a/drivers/dma/ti/dma-crossbar.c +++ b/drivers/dma/ti/dma-crossbar.c @@ -103,7 +103,7 @@ static void *ti_am335x_xbar_route_allocate(struct of_phandle_args *dma_spec, goto out_put_pdev; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { of_node_put(dma_spec->np); map = ERR_PTR(-ENOMEM); @@ -260,7 +260,7 @@ static void *ti_dra7_xbar_route_allocate(struct of_phandle_args *dma_spec, goto out_put_pdev; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { of_node_put(dma_spec->np); map = ERR_PTR(-ENOMEM); @@ -393,7 +393,7 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev) if (!nelm) return -EINVAL; - rsv_events = kcalloc(nelm, sizeof(*rsv_events), GFP_KERNEL); + rsv_events = kzalloc_objs(*rsv_events, nelm); if (!rsv_events) return -ENOMEM; diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c index 552be71db6c4..d97db5af3555 100644 --- a/drivers/dma/ti/edma.c +++ b/drivers/dma/ti/edma.c @@ -1041,7 +1041,7 @@ static struct dma_async_tx_descriptor *edma_prep_slave_sg( return NULL; } - edesc = kzalloc(struct_size(edesc, pset, sg_len), GFP_ATOMIC); + edesc = kzalloc_flex(*edesc, pset, sg_len, GFP_ATOMIC); if (!edesc) return NULL; @@ -1158,7 +1158,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy( nslots = 2; } - edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC); + edesc = kzalloc_flex(*edesc, pset, nslots, GFP_ATOMIC); if (!edesc) return NULL; @@ -1265,7 +1265,7 @@ edma_prep_dma_interleaved(struct dma_chan *chan, if (src_bidx > SZ_64K || dst_bidx > SZ_64K) return NULL; - edesc = kzalloc(struct_size(edesc, pset, 1), GFP_ATOMIC); + edesc = kzalloc_flex(*edesc, pset, 1, GFP_ATOMIC); if (!edesc) return NULL; @@ -1361,7 +1361,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic( } } - edesc = kzalloc(struct_size(edesc, pset, nslots), GFP_ATOMIC); + edesc = kzalloc_flex(*edesc, pset, nslots, GFP_ATOMIC); if (!edesc) return NULL; diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index aa2dc762140f..c964ebfcf3b6 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -3241,7 +3241,7 @@ udma_prep_slave_sg_pkt(struct udma_chan *uc, struct scatterlist *sgl, unsigned int i; u64 asel; - d = kzalloc(struct_size(d, hwdesc, sglen), GFP_NOWAIT); + d = kzalloc_flex(*d, hwdesc, sglen, GFP_NOWAIT); if (!d) return NULL; @@ -3588,7 +3588,7 @@ udma_prep_dma_cyclic_pkt(struct udma_chan *uc, dma_addr_t buf_addr, if (period_len >= SZ_4M) return NULL; - d = kzalloc(struct_size(d, hwdesc, periods), GFP_NOWAIT); + d = kzalloc_flex(*d, hwdesc, periods, GFP_NOWAIT); if (!d) return NULL; @@ -4686,7 +4686,7 @@ static int udma_setup_resources(struct udma_dev *ud) irq_res.sets += rm_res->sets; } - irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); + irq_res.desc = kzalloc_objs(*irq_res.desc, irq_res.sets); if (!irq_res.desc) return -ENOMEM; rm_res = tisci_rm->rm_ranges[RM_RANGE_TCHAN]; @@ -4878,7 +4878,7 @@ static int bcdma_setup_resources(struct udma_dev *ud) } } - irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); + irq_res.desc = kzalloc_objs(*irq_res.desc, irq_res.sets); if (!irq_res.desc) return -ENOMEM; if (ud->bchan_cnt) { @@ -5080,7 +5080,7 @@ static int pktdma_setup_resources(struct udma_dev *ud) irq_res.sets += rm_res->sets; } - irq_res.desc = kcalloc(irq_res.sets, sizeof(*irq_res.desc), GFP_KERNEL); + irq_res.desc = kzalloc_objs(*irq_res.desc, irq_res.sets); if (!irq_res.desc) return -ENOMEM; rm_res = tisci_rm->rm_ranges[RM_RANGE_TFLOW]; diff --git a/drivers/dma/ti/omap-dma.c b/drivers/dma/ti/omap-dma.c index 73ed4b794630..55ece7fd0d99 100644 --- a/drivers/dma/ti/omap-dma.c +++ b/drivers/dma/ti/omap-dma.c @@ -1002,7 +1002,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg( } /* Now allocate and setup the descriptor. */ - d = kzalloc(struct_size(d, sg, sglen), GFP_ATOMIC); + d = kzalloc_flex(*d, sg, sglen, GFP_ATOMIC); if (!d) return NULL; d->sglen = sglen; @@ -1503,7 +1503,7 @@ static int omap_dma_chan_init(struct omap_dmadev *od) { struct omap_chan *c; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) return -ENOMEM; diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c index ecaf002558af..4fc5119854ec 100644 --- a/drivers/dma/timb_dma.c +++ b/drivers/dma/timb_dma.c @@ -325,7 +325,7 @@ static struct timb_dma_desc *td_alloc_init_desc(struct timb_dma_chan *td_chan) struct timb_dma_desc *td_desc; int err; - td_desc = kzalloc(sizeof(struct timb_dma_desc), GFP_KERNEL); + td_desc = kzalloc_obj(struct timb_dma_desc); if (!td_desc) goto out; @@ -635,8 +635,7 @@ static int td_probe(struct platform_device *pdev) DRIVER_NAME)) return -EBUSY; - td = kzalloc(struct_size(td, channels, pdata->nr_channels), - GFP_KERNEL); + td = kzalloc_flex(*td, channels, pdata->nr_channels); if (!td) { err = -ENOMEM; goto err_release_region; diff --git a/drivers/dma/txx9dmac.c b/drivers/dma/txx9dmac.c index 35d5221683b2..05622b68a936 100644 --- a/drivers/dma/txx9dmac.c +++ b/drivers/dma/txx9dmac.c @@ -192,7 +192,7 @@ static struct txx9dmac_desc *txx9dmac_desc_alloc(struct txx9dmac_chan *dc, struct txx9dmac_dev *ddev = dc->ddev; struct txx9dmac_desc *desc; - desc = kzalloc(sizeof(*desc), flags); + desc = kzalloc_obj(*desc, flags); if (!desc) return NULL; INIT_LIST_HEAD(&desc->tx_list); diff --git a/drivers/dma/uniphier-mdmac.c b/drivers/dma/uniphier-mdmac.c index 7a99f86ecb5a..a8aa904b88be 100644 --- a/drivers/dma/uniphier-mdmac.c +++ b/drivers/dma/uniphier-mdmac.c @@ -238,7 +238,7 @@ uniphier_mdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, if (!is_slave_direction(direction)) return NULL; - md = kzalloc(sizeof(*md), GFP_NOWAIT); + md = kzalloc_obj(*md, GFP_NOWAIT); if (!md) return NULL; diff --git a/drivers/dma/uniphier-xdmac.c b/drivers/dma/uniphier-xdmac.c index ceeb6171c9d1..120c0d4f12dd 100644 --- a/drivers/dma/uniphier-xdmac.c +++ b/drivers/dma/uniphier-xdmac.c @@ -292,7 +292,7 @@ uniphier_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst, nr = 1 + len / XDMAC_MAX_WORD_SIZE; - xd = kzalloc(struct_size(xd, nodes, nr), GFP_NOWAIT); + xd = kzalloc_flex(*xd, nodes, nr, GFP_NOWAIT); if (!xd) return NULL; xd->nr_node = nr; @@ -348,7 +348,7 @@ uniphier_xdmac_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, return NULL; } - xd = kzalloc(struct_size(xd, nodes, sg_len), GFP_NOWAIT); + xd = kzalloc_flex(*xd, nodes, sg_len, GFP_NOWAIT); if (!xd) return NULL; xd->nr_node = sg_len; diff --git a/drivers/dma/xilinx/xdma.c b/drivers/dma/xilinx/xdma.c index 5ecf8223c112..d02a4dac2291 100644 --- a/drivers/dma/xilinx/xdma.c +++ b/drivers/dma/xilinx/xdma.c @@ -275,7 +275,7 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, bool cyclic) void *addr; int i, j; - sw_desc = kzalloc(sizeof(*sw_desc), GFP_NOWAIT); + sw_desc = kzalloc_obj(*sw_desc, GFP_NOWAIT); if (!sw_desc) return NULL; @@ -284,8 +284,8 @@ xdma_alloc_desc(struct xdma_chan *chan, u32 desc_num, bool cyclic) sw_desc->cyclic = cyclic; sw_desc->error = false; dblk_num = DIV_ROUND_UP(desc_num, XDMA_DESC_ADJACENT); - sw_desc->desc_blocks = kcalloc(dblk_num, sizeof(*sw_desc->desc_blocks), - GFP_NOWAIT); + sw_desc->desc_blocks = kzalloc_objs(*sw_desc->desc_blocks, dblk_num, + GFP_NOWAIT); if (!sw_desc->desc_blocks) goto failed; @@ -605,13 +605,11 @@ xdma_prep_device_sg(struct dma_chan *chan, struct scatterlist *sgl, struct xdma_chan *xdma_chan = to_xdma_chan(chan); struct dma_async_tx_descriptor *tx_desc; struct xdma_desc *sw_desc; - u32 desc_num = 0, i; u64 addr, dev_addr, *src, *dst; + u32 desc_num, i; struct scatterlist *sg; - for_each_sg(sgl, sg, sg_len, i) - desc_num += DIV_ROUND_UP(sg_dma_len(sg), XDMA_DESC_BLEN_MAX); - + desc_num = sg_nents_for_dma(sgl, sg_len, XDMA_DESC_BLEN_MAX); sw_desc = xdma_alloc_desc(xdma_chan, desc_num, false); if (!sw_desc) return NULL; diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 89a8254d9cdc..b53292e02448 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -836,7 +836,7 @@ xilinx_dma_alloc_tx_descriptor(struct xilinx_dma_chan *chan) { struct xilinx_dma_tx_descriptor *desc; - desc = kzalloc(sizeof(*desc), GFP_NOWAIT); + desc = kzalloc_obj(*desc, GFP_NOWAIT); if (!desc) return NULL; @@ -1022,6 +1022,24 @@ static u32 xilinx_dma_get_residue(struct xilinx_dma_chan *chan, return residue; } +static u32 +xilinx_dma_get_residue_axidma_direct_s2mm(struct xilinx_dma_chan *chan, + struct xilinx_dma_tx_descriptor *desc) +{ + struct xilinx_axidma_tx_segment *seg; + struct xilinx_axidma_desc_hw *hw; + u32 finished_len; + + finished_len = dma_ctrl_read(chan, XILINX_DMA_REG_BTT); + + seg = list_first_entry(&desc->segments, struct xilinx_axidma_tx_segment, + node); + + hw = &seg->hw; + + return hw->control - finished_len; +} + /** * xilinx_dma_chan_handle_cyclic - Cyclic dma callback * @chan: Driver specific dma channel @@ -1733,6 +1751,9 @@ static void xilinx_dma_complete_descriptor(struct xilinx_dma_chan *chan) if (chan->has_sg && chan->xdev->dma_config->dmatype != XDMA_TYPE_VDMA) desc->residue = xilinx_dma_get_residue(chan, desc); + else if (chan->xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA && + chan->direction == DMA_DEV_TO_MEM && !chan->has_sg) + desc->residue = xilinx_dma_get_residue_axidma_direct_s2mm(chan, desc); else desc->residue = 0; desc->err = chan->err; diff --git a/drivers/dma/xilinx/xilinx_dpdma.c b/drivers/dma/xilinx/xilinx_dpdma.c index ee5d9fdbfd7f..d9a3542c4531 100644 --- a/drivers/dma/xilinx/xilinx_dpdma.c +++ b/drivers/dma/xilinx/xilinx_dpdma.c @@ -635,7 +635,7 @@ xilinx_dpdma_chan_alloc_tx_desc(struct xilinx_dpdma_chan *chan) { struct xilinx_dpdma_tx_desc *tx_desc; - tx_desc = kzalloc(sizeof(*tx_desc), GFP_NOWAIT); + tx_desc = kzalloc_obj(*tx_desc, GFP_NOWAIT); if (!tx_desc) return NULL; diff --git a/drivers/dma/xilinx/zynqmp_dma.c b/drivers/dma/xilinx/zynqmp_dma.c index f7e584de4335..f6a812e49ddc 100644 --- a/drivers/dma/xilinx/zynqmp_dma.c +++ b/drivers/dma/xilinx/zynqmp_dma.c @@ -482,8 +482,7 @@ static int zynqmp_dma_alloc_chan_resources(struct dma_chan *dchan) if (ret < 0) return ret; - chan->sw_desc_pool = kcalloc(ZYNQMP_DMA_NUM_DESCS, sizeof(*desc), - GFP_KERNEL); + chan->sw_desc_pool = kzalloc_objs(*desc, ZYNQMP_DMA_NUM_DESCS); if (!chan->sw_desc_pool) return -ENOMEM; @@ -695,7 +694,6 @@ static void zynqmp_dma_free_chan_resources(struct dma_chan *dchan) (2 * ZYNQMP_DMA_DESC_SIZE(chan) * ZYNQMP_DMA_NUM_DESCS), chan->desc_pool_v, chan->desc_pool_p); kfree(chan->sw_desc_pool); - pm_runtime_mark_last_busy(chan->dev); pm_runtime_put_autosuspend(chan->dev); } @@ -1145,7 +1143,6 @@ static int zynqmp_dma_probe(struct platform_device *pdev) goto free_chan_resources; } - pm_runtime_mark_last_busy(zdev->dev); pm_runtime_put_sync_autosuspend(zdev->dev); return 0; diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index 627a5b39a0ef..3f54754cdec4 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -205,7 +205,7 @@ dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, } if (!ref_exists) { - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) return -ENOMEM; ref->pin = pin; @@ -218,7 +218,7 @@ dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin, refcount_set(&ref->refcount, 1); } - reg = kzalloc(sizeof(*reg), GFP_KERNEL); + reg = kzalloc_obj(*reg); if (!reg) { if (!ref_exists) { xa_erase(xa_pins, pin->pin_idx); @@ -286,7 +286,7 @@ dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, } if (!ref_exists) { - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) return -ENOMEM; ref->dpll = dpll; @@ -299,7 +299,7 @@ dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll, refcount_set(&ref->refcount, 1); } - reg = kzalloc(sizeof(*reg), GFP_KERNEL); + reg = kzalloc_obj(*reg); if (!reg) { if (!ref_exists) { xa_erase(xa_dplls, dpll->id); @@ -360,7 +360,7 @@ dpll_device_alloc(const u64 clock_id, u32 device_idx, struct module *module) struct dpll_device *dpll; int ret; - dpll = kzalloc(sizeof(*dpll), GFP_KERNEL); + dpll = kzalloc_obj(*dpll); if (!dpll) return ERR_PTR(-ENOMEM); refcount_set(&dpll->refcount, 1); @@ -490,7 +490,7 @@ int dpll_device_register(struct dpll_device *dpll, enum dpll_type type, return -EEXIST; } - reg = kzalloc(sizeof(*reg), GFP_KERNEL); + reg = kzalloc_obj(*reg); if (!reg) { mutex_unlock(&dpll_lock); return -ENOMEM; @@ -644,7 +644,7 @@ dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module, } else if (pin_idx > INT_MAX) { return ERR_PTR(-EINVAL); } - pin = kzalloc(sizeof(*pin), GFP_KERNEL); + pin = kzalloc_obj(*pin); if (!pin) { ret = -ENOMEM; goto err_pin_alloc; diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c index 63bd97181b9e..37f3c33570ee 100644 --- a/drivers/dpll/zl3073x/core.c +++ b/drivers/dpll/zl3073x/core.c @@ -981,11 +981,7 @@ zl3073x_devm_dpll_init(struct zl3073x_dev *zldev, u8 num_dplls) } /* Add devres action to release DPLL related resources */ - rc = devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev); - if (rc) - goto error; - - return 0; + return devm_add_action_or_reset(zldev->dev, zl3073x_dev_dpll_fini, zldev); error: zl3073x_dev_dpll_fini(zldev); @@ -1026,6 +1022,7 @@ int zl3073x_dev_probe(struct zl3073x_dev *zldev, "Unknown or non-match chip ID: 0x%0x\n", id); } + zldev->chip_id = id; /* Read revision, firmware version and custom config version */ rc = zl3073x_read_u16(zldev, ZL_REG_REVISION, &revision); diff --git a/drivers/dpll/zl3073x/core.h b/drivers/dpll/zl3073x/core.h index dddfcacea5c0..fd2af3c62a7d 100644 --- a/drivers/dpll/zl3073x/core.h +++ b/drivers/dpll/zl3073x/core.h @@ -35,6 +35,7 @@ struct zl3073x_dpll; * @dev: pointer to device * @regmap: regmap to access device registers * @multiop_lock: to serialize multiple register operations + * @chip_id: chip ID read from hardware * @ref: array of input references' invariants * @out: array of outs' invariants * @synth: array of synths' invariants @@ -48,6 +49,7 @@ struct zl3073x_dev { struct device *dev; struct regmap *regmap; struct mutex multiop_lock; + u16 chip_id; /* Invariants */ struct zl3073x_ref ref[ZL3073X_NUM_REFS]; @@ -144,6 +146,32 @@ int zl3073x_write_hwreg_seq(struct zl3073x_dev *zldev, int zl3073x_ref_phase_offsets_update(struct zl3073x_dev *zldev, int channel); +/** + * zl3073x_dev_is_ref_phase_comp_32bit - check ref phase comp register size + * @zldev: pointer to zl3073x device + * + * Some chip IDs have a 32-bit wide ref_phase_offset_comp register instead + * of the default 48-bit. + * + * Return: true if the register is 32-bit, false if 48-bit + */ +static inline bool +zl3073x_dev_is_ref_phase_comp_32bit(struct zl3073x_dev *zldev) +{ + switch (zldev->chip_id) { + case 0x0E30: + case 0x0E93: + case 0x0E94: + case 0x0E95: + case 0x0E96: + case 0x0E97: + case 0x1F60: + return true; + default: + return false; + } +} + static inline bool zl3073x_is_n_pin(u8 id) { diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c index 78edc36b17fb..aaa14ea5e670 100644 --- a/drivers/dpll/zl3073x/dpll.c +++ b/drivers/dpll/zl3073x/dpll.c @@ -475,8 +475,11 @@ zl3073x_dpll_input_pin_phase_adjust_get(const struct dpll_pin *dpll_pin, ref_id = zl3073x_input_pin_ref_get(pin->id); ref = zl3073x_ref_state_get(zldev, ref_id); - /* Perform sign extension for 48bit signed value */ - phase_comp = sign_extend64(ref->phase_comp, 47); + /* Perform sign extension based on register width */ + if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) + phase_comp = sign_extend64(ref->phase_comp, 31); + else + phase_comp = sign_extend64(ref->phase_comp, 47); /* Reverse two's complement negation applied during set and convert * to 32bit signed int @@ -1372,7 +1375,7 @@ zl3073x_dpll_pin_alloc(struct zl3073x_dpll *zldpll, enum dpll_pin_direction dir, { struct zl3073x_dpll_pin *pin; - pin = kzalloc(sizeof(*pin), GFP_KERNEL); + pin = kzalloc_obj(*pin); if (!pin) return ERR_PTR(-ENOMEM); @@ -1944,7 +1947,7 @@ zl3073x_dpll_alloc(struct zl3073x_dev *zldev, u8 ch) { struct zl3073x_dpll *zldpll; - zldpll = kzalloc(sizeof(*zldpll), GFP_KERNEL); + zldpll = kzalloc_obj(*zldpll); if (!zldpll) return ERR_PTR(-ENOMEM); diff --git a/drivers/dpll/zl3073x/fw.c b/drivers/dpll/zl3073x/fw.c index 55b638247f4b..3acbb33ed7b8 100644 --- a/drivers/dpll/zl3073x/fw.c +++ b/drivers/dpll/zl3073x/fw.c @@ -129,7 +129,7 @@ zl3073x_fw_component_alloc(size_t size) { struct zl3073x_fw_component *comp; - comp = kzalloc(sizeof(*comp), GFP_KERNEL); + comp = kzalloc_obj(*comp); if (!comp) return NULL; @@ -313,7 +313,7 @@ struct zl3073x_fw *zl3073x_fw_load(struct zl3073x_dev *zldev, const char *data, ssize_t rc; /* Allocate firmware structure */ - fw = kzalloc(sizeof(*fw), GFP_KERNEL); + fw = kzalloc_obj(*fw); if (!fw) return ERR_PTR(-ENOMEM); diff --git a/drivers/dpll/zl3073x/prop.c b/drivers/dpll/zl3073x/prop.c index 8523dc8c226e..ac9d41d0f978 100644 --- a/drivers/dpll/zl3073x/prop.c +++ b/drivers/dpll/zl3073x/prop.c @@ -198,7 +198,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, const char *type; u32 curr_freq; - props = kzalloc(sizeof(*props), GFP_KERNEL); + props = kzalloc_obj(*props); if (!props) return ERR_PTR(-ENOMEM); @@ -289,7 +289,7 @@ struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, skip_fwnode_props: /* Allocate frequency ranges list - extra slot for current frequency */ - ranges = kcalloc(num_freqs + 1, sizeof(*ranges), GFP_KERNEL); + ranges = kzalloc_objs(*ranges, num_freqs + 1); if (!ranges) { rc = -ENOMEM; goto err_alloc_ranges; diff --git a/drivers/dpll/zl3073x/ref.c b/drivers/dpll/zl3073x/ref.c index aa2de13effa8..6b65e6103999 100644 --- a/drivers/dpll/zl3073x/ref.c +++ b/drivers/dpll/zl3073x/ref.c @@ -121,8 +121,16 @@ int zl3073x_ref_state_fetch(struct zl3073x_dev *zldev, u8 index) return rc; /* Read phase compensation register */ - rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, - &ref->phase_comp); + if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) { + u32 val; + + rc = zl3073x_read_u32(zldev, ZL_REG_REF_PHASE_OFFSET_COMP_32, + &val); + ref->phase_comp = val; + } else { + rc = zl3073x_read_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, + &ref->phase_comp); + } if (rc) return rc; @@ -179,9 +187,16 @@ int zl3073x_ref_state_set(struct zl3073x_dev *zldev, u8 index, if (!rc && dref->sync_ctrl != ref->sync_ctrl) rc = zl3073x_write_u8(zldev, ZL_REG_REF_SYNC_CTRL, ref->sync_ctrl); - if (!rc && dref->phase_comp != ref->phase_comp) - rc = zl3073x_write_u48(zldev, ZL_REG_REF_PHASE_OFFSET_COMP, - ref->phase_comp); + if (!rc && dref->phase_comp != ref->phase_comp) { + if (zl3073x_dev_is_ref_phase_comp_32bit(zldev)) + rc = zl3073x_write_u32(zldev, + ZL_REG_REF_PHASE_OFFSET_COMP_32, + ref->phase_comp); + else + rc = zl3073x_write_u48(zldev, + ZL_REG_REF_PHASE_OFFSET_COMP, + ref->phase_comp); + } if (rc) return rc; diff --git a/drivers/dpll/zl3073x/ref.h b/drivers/dpll/zl3073x/ref.h index efc7f59cd9f9..0d8618f5ce8d 100644 --- a/drivers/dpll/zl3073x/ref.h +++ b/drivers/dpll/zl3073x/ref.h @@ -91,6 +91,8 @@ zl3073x_ref_freq_set(struct zl3073x_ref *ref, u32 freq) ref->freq_base = base; ref->freq_mult = mult; + ref->freq_ratio_m = 1; + ref->freq_ratio_n = 1; return 0; } diff --git a/drivers/dpll/zl3073x/regs.h b/drivers/dpll/zl3073x/regs.h index d837bee72b17..5573d7188406 100644 --- a/drivers/dpll/zl3073x/regs.h +++ b/drivers/dpll/zl3073x/regs.h @@ -194,6 +194,7 @@ #define ZL_REF_CONFIG_DIFF_EN BIT(2) #define ZL_REG_REF_PHASE_OFFSET_COMP ZL_REG(10, 0x28, 6) +#define ZL_REG_REF_PHASE_OFFSET_COMP_32 ZL_REG(10, 0x28, 4) #define ZL_REG_REF_SYNC_CTRL ZL_REG(10, 0x2e, 1) #define ZL_REF_SYNC_CTRL_MODE GENMASK(2, 0) diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 63fca0ee2c23..8908ab881c85 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -3485,7 +3485,7 @@ static int dct_hw_info_get(struct amd64_pvt *pvt) static int umc_hw_info_get(struct amd64_pvt *pvt) { - pvt->umc = kcalloc(pvt->max_mcs, sizeof(struct amd64_umc), GFP_KERNEL); + pvt->umc = kzalloc_objs(struct amd64_umc, pvt->max_mcs); if (!pvt->umc) return -ENOMEM; @@ -3716,7 +3716,7 @@ static int gpu_hw_info_get(struct amd64_pvt *pvt) if (ret) return ret; - pvt->umc = kcalloc(pvt->max_mcs, sizeof(struct amd64_umc), GFP_KERNEL); + pvt->umc = kzalloc_objs(struct amd64_umc, pvt->max_mcs); if (!pvt->umc) return -ENOMEM; @@ -3916,7 +3916,7 @@ static int per_family_init(struct amd64_pvt *pvt) scnprintf(pvt->ctl_name, sizeof(pvt->ctl_name), "F%02Xh_M%02Xh", pvt->fam, pvt->model); - pvt->csels = kcalloc(pvt->max_mcs, sizeof(*pvt->csels), GFP_KERNEL); + pvt->csels = kzalloc_objs(*pvt->csels, pvt->max_mcs); if (!pvt->csels) return -ENOMEM; @@ -4000,13 +4000,13 @@ static int probe_one_instance(unsigned int nid) int ret; ret = -ENOMEM; - s = kzalloc(sizeof(struct ecc_settings), GFP_KERNEL); + s = kzalloc_obj(struct ecc_settings); if (!s) goto err_out; ecc_stngs[nid] = s; - pvt = kzalloc(sizeof(struct amd64_pvt), GFP_KERNEL); + pvt = kzalloc_obj(struct amd64_pvt); if (!pvt) goto err_settings; @@ -4146,7 +4146,7 @@ static int __init amd64_edac_init(void) opstate_init(); err = -ENOMEM; - ecc_stngs = kcalloc(amd_nb_num(), sizeof(ecc_stngs[0]), GFP_KERNEL); + ecc_stngs = kzalloc_objs(ecc_stngs[0], amd_nb_num()); if (!ecc_stngs) goto err_free; diff --git a/drivers/edac/edac_device.c b/drivers/edac/edac_device.c index 0734909b08a4..cf0d3c2dfc04 100644 --- a/drivers/edac/edac_device.c +++ b/drivers/edac/edac_device.c @@ -67,17 +67,18 @@ edac_device_alloc_ctl_info(unsigned pvt_sz, char *dev_name, unsigned nr_instance edac_dbg(4, "instances=%d blocks=%d\n", nr_instances, nr_blocks); - dev_ctl = kzalloc(sizeof(struct edac_device_ctl_info), GFP_KERNEL); + dev_ctl = kzalloc_obj(struct edac_device_ctl_info); if (!dev_ctl) return NULL; - dev_inst = kcalloc(nr_instances, sizeof(struct edac_device_instance), GFP_KERNEL); + dev_inst = kzalloc_objs(struct edac_device_instance, nr_instances); if (!dev_inst) goto free; dev_ctl->instances = dev_inst; - dev_blk = kcalloc(nr_instances * nr_blocks, sizeof(struct edac_device_block), GFP_KERNEL); + dev_blk = kzalloc_objs(struct edac_device_block, + nr_instances * nr_blocks); if (!dev_blk) goto free; @@ -642,22 +643,22 @@ int edac_dev_register(struct device *parent, char *name, } } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; - ras_attr_groups = kcalloc(attr_gcnt + 1, sizeof(*ras_attr_groups), GFP_KERNEL); + ras_attr_groups = kzalloc_objs(*ras_attr_groups, attr_gcnt + 1); if (!ras_attr_groups) goto ctx_free; if (scrub_cnt) { - ctx->scrub = kcalloc(scrub_cnt, sizeof(*ctx->scrub), GFP_KERNEL); + ctx->scrub = kzalloc_objs(*ctx->scrub, scrub_cnt); if (!ctx->scrub) goto groups_free; } if (mem_repair_cnt) { - ctx->mem_repair = kcalloc(mem_repair_cnt, sizeof(*ctx->mem_repair), GFP_KERNEL); + ctx->mem_repair = kzalloc_objs(*ctx->mem_repair, mem_repair_cnt); if (!ctx->mem_repair) goto data_mem_free; } diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 0959320fe51c..29e9828422bb 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -216,14 +216,14 @@ static int edac_mc_alloc_csrows(struct mem_ctl_info *mci) /* * Allocate and fill the csrow/channels structs */ - mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL); + mci->csrows = kzalloc_objs(*mci->csrows, tot_csrows); if (!mci->csrows) return -ENOMEM; for (row = 0; row < tot_csrows; row++) { struct csrow_info *csr; - csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL); + csr = kzalloc_obj(**mci->csrows); if (!csr) return -ENOMEM; @@ -231,15 +231,14 @@ static int edac_mc_alloc_csrows(struct mem_ctl_info *mci) csr->csrow_idx = row; csr->mci = mci; csr->nr_channels = tot_channels; - csr->channels = kcalloc(tot_channels, sizeof(*csr->channels), - GFP_KERNEL); + csr->channels = kzalloc_objs(*csr->channels, tot_channels); if (!csr->channels) return -ENOMEM; for (chn = 0; chn < tot_channels; chn++) { struct rank_info *chan; - chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL); + chan = kzalloc_obj(**csr->channels); if (!chan) return -ENOMEM; @@ -262,7 +261,7 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci) /* * Allocate and fill the dimm structs */ - mci->dimms = kcalloc(mci->tot_dimms, sizeof(*mci->dimms), GFP_KERNEL); + mci->dimms = kzalloc_objs(*mci->dimms, mci->tot_dimms); if (!mci->dimms) return -ENOMEM; @@ -276,7 +275,7 @@ static int edac_mc_alloc_dimms(struct mem_ctl_info *mci) chan = mci->csrows[row]->channels[chn]; - dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL); + dimm = kzalloc_obj(**mci->dimms); if (!dimm) return -ENOMEM; mci->dimms[idx] = dimm; @@ -362,11 +361,11 @@ struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num, per_rank = true; } - mci = kzalloc(sizeof(struct mem_ctl_info), GFP_KERNEL); + mci = kzalloc_obj(struct mem_ctl_info); if (!mci) return NULL; - mci->layers = kcalloc(n_layers, sizeof(struct edac_mc_layer), GFP_KERNEL); + mci->layers = kzalloc_objs(struct edac_mc_layer, n_layers); if (!mci->layers) goto error; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 091cc6aae8a9..c2ed6c696e54 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -648,7 +648,7 @@ int __init edac_mc_sysfs_init(void) { int err; - mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL); + mci_pdev = kzalloc_obj(*mci_pdev); if (!mci_pdev) return -ENOMEM; diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c index 64c142aecca7..327994a95073 100644 --- a/drivers/edac/edac_pci.c +++ b/drivers/edac/edac_pci.c @@ -32,7 +32,7 @@ struct edac_pci_ctl_info *edac_pci_alloc_ctl_info(unsigned int sz_pvt, edac_dbg(1, "\n"); - pci = kzalloc(sizeof(struct edac_pci_ctl_info), GFP_KERNEL); + pci = kzalloc_obj(struct edac_pci_ctl_info); if (!pci) return NULL; diff --git a/drivers/edac/edac_pci_sysfs.c b/drivers/edac/edac_pci_sysfs.c index 7b44afcf48db..446fef0a9399 100644 --- a/drivers/edac/edac_pci_sysfs.c +++ b/drivers/edac/edac_pci_sysfs.c @@ -361,7 +361,7 @@ static int edac_pci_main_kobj_setup(void) goto decrement_count_fail; } - edac_pci_top_main_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + edac_pci_top_main_kobj = kzalloc_obj(struct kobject); if (!edac_pci_top_main_kobj) { edac_dbg(1, "Failed to allocate\n"); err = -ENOMEM; diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 91e0a88ef904..0f783173d0ec 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -455,12 +455,11 @@ static struct i7core_dev *alloc_i7core_dev(u8 socket, { struct i7core_dev *i7core_dev; - i7core_dev = kzalloc(sizeof(*i7core_dev), GFP_KERNEL); + i7core_dev = kzalloc_obj(*i7core_dev); if (!i7core_dev) return NULL; - i7core_dev->pdev = kcalloc(table->n_devs, sizeof(*i7core_dev->pdev), - GFP_KERNEL); + i7core_dev->pdev = kzalloc_objs(*i7core_dev->pdev, table->n_devs); if (!i7core_dev->pdev) { kfree(i7core_dev); return NULL; @@ -1159,7 +1158,7 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) struct i7core_pvt *pvt = mci->pvt_info; int rc; - pvt->addrmatch_dev = kzalloc(sizeof(*pvt->addrmatch_dev), GFP_KERNEL); + pvt->addrmatch_dev = kzalloc_obj(*pvt->addrmatch_dev); if (!pvt->addrmatch_dev) return -ENOMEM; @@ -1177,8 +1176,7 @@ static int i7core_create_sysfs_devices(struct mem_ctl_info *mci) goto err_put_addrmatch; if (!pvt->is_registered) { - pvt->chancounts_dev = kzalloc(sizeof(*pvt->chancounts_dev), - GFP_KERNEL); + pvt->chancounts_dev = kzalloc_obj(*pvt->chancounts_dev); if (!pvt->chancounts_dev) { rc = -ENOMEM; goto err_del_addrmatch; diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c index 045c20179cd3..fcb8ab44cba5 100644 --- a/drivers/edac/igen6_edac.c +++ b/drivers/edac/igen6_edac.c @@ -1549,7 +1549,7 @@ static int igen6_probe(struct pci_dev *pdev, const struct pci_device_id *ent) edac_dbg(2, "\n"); - igen6_pvt = kzalloc(sizeof(*igen6_pvt), GFP_KERNEL); + igen6_pvt = kzalloc_obj(*igen6_pvt); if (!igen6_pvt) return -ENOMEM; diff --git a/drivers/edac/imh_base.c b/drivers/edac/imh_base.c index 4348b3883b45..40082ba45e62 100644 --- a/drivers/edac/imh_base.c +++ b/drivers/edac/imh_base.c @@ -171,7 +171,7 @@ static int __get_ddr_munits(struct res_config *cfg, struct skx_dev *d, d->imc[lmc].lmc = lmc; /* Create the imc device instance. */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; @@ -257,7 +257,7 @@ static int imh_get_all_mmio_base_h(struct res_config *cfg, struct list_head *eda struct skx_dev *d; for (i = 0; i < n; i++) { - d = kzalloc(struct_size(d, imc, imc_num), GFP_KERNEL); + d = kzalloc_flex(*d, imc, imc_num); if (!d) return -ENOMEM; diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index d5f12219598a..09d4e816404b 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -771,13 +771,12 @@ static struct sbridge_dev *alloc_sbridge_dev(int seg, u8 bus, enum domain dom, { struct sbridge_dev *sbridge_dev; - sbridge_dev = kzalloc(sizeof(*sbridge_dev), GFP_KERNEL); + sbridge_dev = kzalloc_obj(*sbridge_dev); if (!sbridge_dev) return NULL; - sbridge_dev->pdev = kcalloc(table->n_devs_per_imc, - sizeof(*sbridge_dev->pdev), - GFP_KERNEL); + sbridge_dev->pdev = kzalloc_objs(*sbridge_dev->pdev, + table->n_devs_per_imc); if (!sbridge_dev->pdev) { kfree(sbridge_dev); return NULL; diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index 3276afe43922..a9557c8344bc 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -346,7 +346,7 @@ int skx_get_all_bus_mappings(struct res_config *cfg, struct list_head **list) if (!pdev) break; ndev++; - d = kzalloc(struct_size(d, imc, imc_num), GFP_KERNEL); + d = kzalloc_flex(*d, imc, imc_num); if (!d) { pci_dev_put(pdev); return -ENOMEM; diff --git a/drivers/edac/versalnet_edac.c b/drivers/edac/versalnet_edac.c index 1a1092793092..2cbc13d9bd00 100644 --- a/drivers/edac/versalnet_edac.c +++ b/drivers/edac/versalnet_edac.c @@ -559,7 +559,7 @@ static int setup_mcdi(struct mc_priv *mc_priv) struct cdx_mcdi *amd_mcdi; int ret, i; - amd_mcdi = kzalloc(sizeof(*amd_mcdi), GFP_KERNEL); + amd_mcdi = kzalloc_obj(*amd_mcdi); if (!amd_mcdi) return -ENOMEM; @@ -812,7 +812,7 @@ static int init_versalnet(struct mc_priv *priv, struct platform_device *pdev) priv->mci[i] = mci; priv->dwidth = dt; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); dev->release = versal_edac_release; name = kmalloc(32, GFP_KERNEL); sprintf(name, "versal-net-ddrmc5-edac-%d", i); diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c index bd76d599109c..79ab44fe26aa 100644 --- a/drivers/eisa/eisa-bus.c +++ b/drivers/eisa/eisa-bus.c @@ -317,7 +317,7 @@ static int __init eisa_probe(struct eisa_root_device *root) /* First try to get hold of slot 0. If there is no device * here, simply fail, unless root->force_probe is set. */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) return -ENOMEM; @@ -350,7 +350,7 @@ static int __init eisa_probe(struct eisa_root_device *root) force_probe: for (c = 0, i = 1; i <= root->slots; i++) { - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) { dev_err(root->dev, "EISA: Out of memory for slot %d\n", i); diff --git a/drivers/extcon/extcon-usbc-cros-ec.c b/drivers/extcon/extcon-usbc-cros-ec.c index 1fb627ea8b50..a2ef710b0d6d 100644 --- a/drivers/extcon/extcon-usbc-cros-ec.c +++ b/drivers/extcon/extcon-usbc-cros-ec.c @@ -68,7 +68,7 @@ static int cros_ec_pd_command(struct cros_ec_extcon_info *info, struct cros_ec_command *msg; int ret; - msg = kzalloc(struct_size(msg, data, max(outsize, insize)), GFP_KERNEL); + msg = kzalloc_flex(*msg, data, max(outsize, insize)); if (!msg) return -ENOMEM; diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c index e7f55c021e56..d9e9815a5f96 100644 --- a/drivers/extcon/extcon.c +++ b/drivers/extcon/extcon.c @@ -1060,7 +1060,7 @@ struct extcon_dev *extcon_dev_allocate(const unsigned int *supported_cable) if (!supported_cable) return ERR_PTR(-EINVAL); - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) return ERR_PTR(-ENOMEM); @@ -1098,8 +1098,7 @@ static int extcon_alloc_cables(struct extcon_dev *edev) if (!edev->max_supported) return 0; - edev->cables = kcalloc(edev->max_supported, sizeof(*edev->cables), - GFP_KERNEL); + edev->cables = kzalloc_objs(*edev->cables, edev->max_supported); if (!edev->cables) return -ENOMEM; @@ -1160,13 +1159,11 @@ static int extcon_alloc_muex(struct extcon_dev *edev) for (index = 0; edev->mutually_exclusive[index]; index++) ; - edev->attrs_muex = kcalloc(index + 1, sizeof(*edev->attrs_muex), - GFP_KERNEL); + edev->attrs_muex = kzalloc_objs(*edev->attrs_muex, index + 1); if (!edev->attrs_muex) return -ENOMEM; - edev->d_attrs_muex = kcalloc(index, sizeof(*edev->d_attrs_muex), - GFP_KERNEL); + edev->d_attrs_muex = kzalloc_objs(*edev->d_attrs_muex, index); if (!edev->d_attrs_muex) { kfree(edev->attrs_muex); return -ENOMEM; @@ -1210,9 +1207,8 @@ static int extcon_alloc_groups(struct extcon_dev *edev) if (!edev->max_supported) return 0; - edev->extcon_dev_type.groups = kcalloc(edev->max_supported + 2, - sizeof(*edev->extcon_dev_type.groups), - GFP_KERNEL); + edev->extcon_dev_type.groups = kzalloc_objs(*edev->extcon_dev_type.groups, + edev->max_supported + 2); if (!edev->extcon_dev_type.groups) return -ENOMEM; @@ -1294,8 +1290,7 @@ int extcon_dev_register(struct extcon_dev *edev) spin_lock_init(&edev->lock); if (edev->max_supported) { - edev->nh = kcalloc(edev->max_supported, sizeof(*edev->nh), - GFP_KERNEL); + edev->nh = kzalloc_objs(*edev->nh, edev->max_supported); if (!edev->nh) { ret = -ENOMEM; goto err_alloc_nh; diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 9e964fdd175c..f791db4c8dff 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -291,7 +291,7 @@ static int fw_device_op_open(struct inode *inode, struct file *file) return -ENODEV; } - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (client == NULL) { fw_device_put(device); return -ENOMEM; @@ -412,7 +412,7 @@ static void queue_bus_reset_event(struct client *client) struct client_resource *resource; unsigned long index; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (e == NULL) return; @@ -745,8 +745,8 @@ static void handle_request(struct fw_card *card, struct fw_request *request, if (is_fcp) fw_request_get(request); - r = kmalloc(sizeof(*r), GFP_ATOMIC); - e = kmalloc(sizeof(*e), GFP_ATOMIC); + r = kmalloc_obj(*r, GFP_ATOMIC); + e = kmalloc_obj(*e, GFP_ATOMIC); if (r == NULL || e == NULL) goto failed; @@ -837,7 +837,7 @@ static int ioctl_allocate(struct client *client, union ioctl_arg *arg) struct fw_address_region region; int ret; - r = kmalloc(sizeof(*r), GFP_KERNEL); + r = kmalloc_obj(*r); if (r == NULL) return -ENOMEM; @@ -941,7 +941,7 @@ static int ioctl_add_descriptor(struct client *client, union ioctl_arg *arg) if (a->length > 256) return -EINVAL; - r = kmalloc(struct_size(r, data, a->length), GFP_KERNEL); + r = kmalloc_flex(*r, data, a->length); if (r == NULL) return -ENOMEM; @@ -1006,7 +1006,7 @@ static void iso_mc_callback(struct fw_iso_context *context, struct client *client = data; struct iso_interrupt_mc_event *e; - e = kmalloc(sizeof(*e), GFP_KERNEL); + e = kmalloc_obj(*e); if (e == NULL) return; @@ -1409,9 +1409,9 @@ static int init_iso_resource(struct client *client, request->bandwidth > BANDWIDTH_AVAILABLE_INITIAL) return -EINVAL; - r = kmalloc(sizeof(*r), GFP_KERNEL); - e1 = kmalloc(sizeof(*e1), GFP_KERNEL); - e2 = kmalloc(sizeof(*e2), GFP_KERNEL); + r = kmalloc_obj(*r); + e1 = kmalloc_obj(*e1); + e2 = kmalloc_obj(*e2); if (r == NULL || e1 == NULL || e2 == NULL) { ret = -ENOMEM; goto fail; diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index 9b0080397154..c0f17da27a22 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -849,7 +849,7 @@ static void create_units(struct fw_device *device) * Get the address of the unit directory and try to * match the drivers id_tables against it. */ - unit = kzalloc(sizeof(*unit), GFP_KERNEL); + unit = kzalloc_obj(*unit); if (unit == NULL) continue; @@ -1339,7 +1339,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) * without actually having a link. */ create: - device = kzalloc(sizeof(*device), GFP_ATOMIC); + device = kzalloc_obj(*device, GFP_ATOMIC); if (device == NULL) break; diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c index 3190b2ca1298..d2b40a1a565e 100644 --- a/drivers/firewire/core-iso.c +++ b/drivers/firewire/core-iso.c @@ -30,7 +30,8 @@ int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count) { - struct page **page_array __free(kfree) = kcalloc(page_count, sizeof(page_array[0]), GFP_KERNEL); + struct page **page_array __free(kfree) = kzalloc_objs(page_array[0], + page_count); if (!page_array) return -ENOMEM; @@ -55,8 +56,8 @@ int fw_iso_buffer_alloc(struct fw_iso_buffer *buffer, int page_count) int fw_iso_buffer_map_dma(struct fw_iso_buffer *buffer, struct fw_card *card, enum dma_data_direction direction) { - dma_addr_t *dma_addrs __free(kfree) = kcalloc(buffer->page_count, sizeof(dma_addrs[0]), - GFP_KERNEL); + dma_addr_t *dma_addrs __free(kfree) = kzalloc_objs(dma_addrs[0], + buffer->page_count); int i; if (!dma_addrs) diff --git a/drivers/firewire/core-topology.c b/drivers/firewire/core-topology.c index ed3ae8cdb0cd..bb2d2db30795 100644 --- a/drivers/firewire/core-topology.c +++ b/drivers/firewire/core-topology.c @@ -27,7 +27,7 @@ static struct fw_node *fw_node_create(u32 sid, int port_count, int color) { struct fw_node *node; - node = kzalloc(struct_size(node, ports, port_count), GFP_ATOMIC); + node = kzalloc_flex(*node, ports, port_count, GFP_ATOMIC); if (node == NULL) return NULL; diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 6d6446713539..f1a2bee39bf1 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -338,7 +338,7 @@ static struct fwnet_fragment_info *fwnet_frag_new( } } - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) return NULL; @@ -356,7 +356,7 @@ static struct fwnet_partial_datagram *fwnet_pd_new(struct net_device *net, struct fwnet_partial_datagram *new; struct fwnet_fragment_info *fi; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) goto fail; @@ -1402,7 +1402,7 @@ static int fwnet_add_peer(struct fwnet_device *dev, { struct fwnet_peer *peer; - peer = kmalloc(sizeof(*peer), GFP_KERNEL); + peer = kmalloc_obj(*peer); if (!peer) return -ENOMEM; diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index e59053738a43..900b7d904b41 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -281,7 +281,7 @@ nosy_open(struct inode *inode, struct file *file) if (lynx == NULL) return -ENODEV; - client = kmalloc(sizeof *client, GFP_KERNEL); + client = kmalloc_obj(*client); if (client == NULL) goto fail; @@ -545,7 +545,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused) } pci_set_master(dev); - lynx = kzalloc(sizeof *lynx, GFP_KERNEL); + lynx = kzalloc_obj(*lynx); if (lynx == NULL) { dev_err(&dev->dev, "Failed to allocate control structure\n"); ret = -ENOMEM; diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 1c868c1e4a49..8153d62c58f0 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -848,7 +848,7 @@ static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, { struct device *dev = ohci->card.device; unsigned int i; - struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES]; + struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES] = { NULL }; dma_addr_t dma_addrs[AR_BUFFERS]; void *vaddr; struct descriptor *d; diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index bb1a510b6423..021b8f698e34 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -558,7 +558,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, if (function == SBP2_LOGOUT_REQUEST && fw_device_is_shutdown(device)) return 0; - orb = kzalloc(sizeof(*orb), GFP_NOIO); + orb = kzalloc_obj(*orb, GFP_NOIO); if (orb == NULL) return -ENOMEM; @@ -667,7 +667,7 @@ static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) struct fw_transaction *t; static __be32 d; - t = kmalloc(sizeof(*t), GFP_ATOMIC); + t = kmalloc_obj(*t, GFP_ATOMIC); if (t == NULL) return; @@ -966,7 +966,7 @@ static int sbp2_add_logical_unit(struct sbp2_target *tgt, int lun_entry) { struct sbp2_logical_unit *lu; - lu = kmalloc(sizeof(*lu), GFP_KERNEL); + lu = kmalloc_obj(*lu); if (!lu) return -ENOMEM; @@ -1449,7 +1449,7 @@ static enum scsi_qc_status sbp2_scsi_queuecommand(struct Scsi_Host *shost, struct sbp2_command_orb *orb; int generation; - orb = kzalloc(sizeof(*orb), GFP_ATOMIC); + orb = kzalloc_obj(*orb, GFP_ATOMIC); if (orb == NULL) return SCSI_MLQUEUE_HOST_BUSY; diff --git a/drivers/firmware/arm_ffa/bus.c b/drivers/firmware/arm_ffa/bus.c index 50bfe56c755e..9576862d89c4 100644 --- a/drivers/firmware/arm_ffa/bus.c +++ b/drivers/firmware/arm_ffa/bus.c @@ -203,7 +203,7 @@ ffa_device_register(const struct ffa_partition_info *part_info, if (id < 0) return NULL; - ffa_dev = kzalloc(sizeof(*ffa_dev), GFP_KERNEL); + ffa_dev = kzalloc_obj(*ffa_dev); if (!ffa_dev) { ida_free(&ffa_bus_id, id); return NULL; diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 8144f6a9f0e9..12a625387d6e 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -410,7 +410,7 @@ ffa_partition_probe(const uuid_t *uuid, struct ffa_partition_info **buffer) if (count <= 0) return count; - pbuf = kcalloc(count, sizeof(*pbuf), GFP_KERNEL); + pbuf = kzalloc_objs(*pbuf, count); if (!pbuf) return -ENOMEM; @@ -1376,7 +1376,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu, if (notify_id >= FFA_MAX_NOTIFICATIONS) return -EINVAL; - cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL); + cb_info = kzalloc_obj(*cb_info); if (!cb_info) return -ENOMEM; @@ -1647,7 +1647,7 @@ static int ffa_xa_add_partition_info(struct ffa_device *dev) } } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ret; @@ -1655,7 +1655,7 @@ static int ffa_xa_add_partition_info(struct ffa_device *dev) info->dev = dev; if (!phead) { - phead = kzalloc(sizeof(*phead), GFP_KERNEL); + phead = kzalloc_obj(*phead); if (!phead) goto free_out; @@ -2039,7 +2039,7 @@ static int __init ffa_init(void) if (ret) return ret; - drv_info = kzalloc(sizeof(*drv_info), GFP_KERNEL); + drv_info = kzalloc_obj(*drv_info); if (!drv_info) return -ENOMEM; diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index c7698cfaa4e8..793be9eabaed 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -90,7 +90,7 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) * No duplicate found for requested id_table, so let's create a new * requested device entry for this new valid request. */ - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) { ret = -ENOMEM; goto out; @@ -103,7 +103,7 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) * there. */ if (!phead) { - phead = kzalloc(sizeof(*phead), GFP_KERNEL); + phead = kzalloc_obj(*phead); if (!phead) { kfree(rdev); ret = -ENOMEM; @@ -445,7 +445,7 @@ __scmi_device_create(struct device_node *np, struct device *parent, return NULL; } - scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL); + scmi_dev = kzalloc_obj(*scmi_dev); if (!scmi_dev) return NULL; diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index dee9f238f6fd..9168794adae4 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -897,7 +897,7 @@ scmi_allocate_event_handler(struct scmi_notify_instance *ni, u32 evt_key) { struct scmi_event_handler *hndl; - hndl = kzalloc(sizeof(*hndl), GFP_KERNEL); + hndl = kzalloc_obj(*hndl); if (!hndl) return NULL; hndl->key = evt_key; diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c index 73db5492ab44..1f6e51670208 100644 --- a/drivers/firmware/arm_scmi/raw_mode.c +++ b/drivers/firmware/arm_scmi/raw_mode.c @@ -908,7 +908,7 @@ static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp) return -ENODEV; raw = inode->i_private; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index 87c323de17b9..00e74449ce09 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -633,14 +633,14 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) if (!buf.opp_count) return ERR_PTR(-ENOENT); - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); info->count = buf.opp_count; info->latency = le16_to_cpu(buf.latency) * 1000; /* uS to nS */ - info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL); + info->opps = kzalloc_objs(*opp, info->count); if (!info->opps) { kfree(info); return ERR_PTR(-ENOMEM); diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 71e2a9a89f6a..f39ed7ba3a38 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -205,7 +205,7 @@ static struct sdei_event *sdei_event_create(u32 event_num, lockdep_assert_held(&sdei_events_lock); - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) { err = -ENOMEM; goto fail; @@ -227,7 +227,7 @@ static struct sdei_event *sdei_event_create(u32 event_num, event->type = result; if (event->type == SDEI_EVENT_TYPE_SHARED) { - reg = kzalloc(sizeof(*reg), GFP_KERNEL); + reg = kzalloc_obj(*reg); if (!reg) { err = -ENOMEM; goto fail; diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 9fdb50f3fec6..5d8be0ac7c5e 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -1059,7 +1059,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, } } - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kzalloc_obj(*ctl); if (!ctl) return -ENOMEM; @@ -1610,11 +1610,17 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, region_name); if (reg) { + /* + * Although we expect the underlying bus does not require + * physically-contiguous buffers, we pessimistically use + * a temporary buffer instead of trusting that the + * alignment of region->data is ok. + */ region_len = le32_to_cpu(region->len); if (region_len > buf_len) { buf_len = round_up(region_len, PAGE_SIZE); - kfree(buf); - buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + vfree(buf); + buf = vmalloc(buf_len); if (!buf) { ret = -ENOMEM; goto out_fw; @@ -1643,7 +1649,7 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, ret = 0; out_fw: - kfree(buf); + vfree(buf); if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -1781,7 +1787,7 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, { struct cs_dsp_alg_region_list_item *item; - item = kzalloc(sizeof(*item), GFP_KERNEL); + item = kzalloc_obj(*item); if (!item) return ERR_PTR(-ENOMEM); @@ -2331,11 +2337,17 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware } if (reg) { + /* + * Although we expect the underlying bus does not require + * physically-contiguous buffers, we pessimistically use + * a temporary buffer instead of trusting that the + * alignment of blk->data is ok. + */ region_len = le32_to_cpu(blk->len); if (region_len > buf_len) { buf_len = round_up(region_len, PAGE_SIZE); - kfree(buf); - buf = kmalloc(buf_len, GFP_KERNEL | GFP_DMA); + vfree(buf); + buf = vmalloc(buf_len); if (!buf) { ret = -ENOMEM; goto out_fw; @@ -2366,7 +2378,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware ret = 0; out_fw: - kfree(buf); + vfree(buf); if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index d19c78a78ae3..477a37e2ef80 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c @@ -96,6 +96,7 @@ static ssize_t get_modalias(char *buffer, size_t buffer_size) { "ct", DMI_CHASSIS_TYPE }, { "cvr", DMI_CHASSIS_VERSION }, { "sku", DMI_PRODUCT_SKU }, + { "pfa", DMI_PRODUCT_FAMILY }, { NULL, DMI_NONE } }; @@ -236,7 +237,7 @@ static int __init dmi_id_init(void) if (ret) return ret; - dmi_dev = kzalloc(sizeof(*dmi_dev), GFP_KERNEL); + dmi_dev = kzalloc_obj(*dmi_dev); if (!dmi_dev) { ret = -ENOMEM; goto fail_class_unregister; diff --git a/drivers/firmware/dmi-sysfs.c b/drivers/firmware/dmi-sysfs.c index 9cc963b2edc0..cda53d037715 100644 --- a/drivers/firmware/dmi-sysfs.c +++ b/drivers/firmware/dmi-sysfs.c @@ -451,7 +451,7 @@ static int dmi_system_event_log(struct dmi_sysfs_entry *entry) { int ret; - entry->child = kzalloc(sizeof(*entry->child), GFP_KERNEL); + entry->child = kzalloc_obj(*entry->child); if (!entry->child) return -ENOMEM; ret = kobject_init_and_add(entry->child, @@ -586,7 +586,7 @@ static void __init dmi_sysfs_register_handle(const struct dmi_header *dh, return; /* Allocate and register a new entry into the entries set */ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { *ret = -ENOMEM; return; diff --git a/drivers/firmware/edd.c b/drivers/firmware/edd.c index 55dec4eb2c00..f980c5b56858 100644 --- a/drivers/firmware/edd.c +++ b/drivers/firmware/edd.c @@ -740,7 +740,7 @@ edd_init(void) return -ENOMEM; for (i = 0; i < edd_num_devices(); i++) { - edev = kzalloc(sizeof (*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) { rc = -ENOMEM; goto out; diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c index ea84108035eb..13ac28754c03 100644 --- a/drivers/firmware/efi/apple-properties.c +++ b/drivers/firmware/efi/apple-properties.c @@ -146,8 +146,7 @@ static int __init unmarshal_devices(struct properties_header *properties) goto skip_device; } - entry = kcalloc(dev_header->prop_count + 1, sizeof(*entry), - GFP_KERNEL); + entry = kzalloc_objs(*entry, dev_header->prop_count + 1); if (!entry) { dev_err(dev, "cannot allocate properties\n"); goto skip_device; diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c index 53a5336cde5a..3167cab62014 100644 --- a/drivers/firmware/efi/arm-runtime.c +++ b/drivers/firmware/efi/arm-runtime.c @@ -113,7 +113,7 @@ static int __init arm_enable_runtime_services(void) if (!(md->attribute & EFI_MEMORY_SP)) continue; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (WARN_ON(!res)) break; diff --git a/drivers/firmware/efi/capsule-loader.c b/drivers/firmware/efi/capsule-loader.c index 0c17bdd388e1..2c628a127091 100644 --- a/drivers/firmware/efi/capsule-loader.c +++ b/drivers/firmware/efi/capsule-loader.c @@ -282,7 +282,7 @@ static int efi_capsule_open(struct inode *inode, struct file *file) { struct capsule_info *cap_info; - cap_info = kzalloc(sizeof(*cap_info), GFP_KERNEL); + cap_info = kzalloc_obj(*cap_info); if (!cap_info) return -ENOMEM; @@ -292,7 +292,7 @@ static int efi_capsule_open(struct inode *inode, struct file *file) return -ENOMEM; } - cap_info->phys = kzalloc(sizeof(phys_addr_t), GFP_KERNEL); + cap_info->phys = kzalloc_obj(phys_addr_t); if (!cap_info->phys) { kfree(cap_info->pages); kfree(cap_info); diff --git a/drivers/firmware/efi/capsule.c b/drivers/firmware/efi/capsule.c index 768430293669..dd62526380d2 100644 --- a/drivers/firmware/efi/capsule.c +++ b/drivers/firmware/efi/capsule.c @@ -230,7 +230,7 @@ int efi_capsule_update(efi_capsule_header_t *capsule, phys_addr_t *pages) count = DIV_ROUND_UP(imagesize, PAGE_SIZE); sg_count = sg_pages_num(count); - sg_pages = kcalloc(sg_count, sizeof(*sg_pages), GFP_KERNEL); + sg_pages = kzalloc_objs(*sg_pages, sg_count); if (!sg_pages) return -ENOMEM; diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index 432301dce76f..5a595d026f58 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -60,7 +60,7 @@ extern __weak const efi_config_table_type_t efi_arch_tables[]; * x86 defines its own instance of sysfb_primary_display and uses * it even without EFI, everything else can get them from here. */ -#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) +#if !defined(CONFIG_X86) && (defined(CONFIG_SYSFB) || defined(CONFIG_EFI_EARLYCON)) || defined(CONFIG_FIRMWARE_EDID) struct sysfb_display_info sysfb_primary_display __section(".data"); EXPORT_SYMBOL_GPL(sysfb_primary_display); #endif diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 111e87a618e5..b2fb92a4bbd1 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -692,13 +692,13 @@ static __init int match_config_table(const efi_guid_t *guid, static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted) { - phys_addr_t start, size; + phys_addr_t start, end; start = PAGE_ALIGN_DOWN(efi.unaccepted); - size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size); + end = PAGE_ALIGN(efi.unaccepted + sizeof(*unaccepted) + unaccepted->size); - memblock_add(start, size); - memblock_reserve(start, size); + memblock_add(start, end - start); + memblock_reserve(start, end - start); } int __init efi_config_parse_tables(const efi_config_table_t *config_tables, @@ -1079,7 +1079,7 @@ static int efi_mem_reserve_iomem(phys_addr_t addr, u64 size) struct resource *res, *parent; int ret; - res = kzalloc(sizeof(struct resource), GFP_ATOMIC); + res = kzalloc_obj(struct resource, GFP_ATOMIC); if (!res) return -ENOMEM; diff --git a/drivers/firmware/efi/efibc.c b/drivers/firmware/efi/efibc.c index 0a7c764dcc61..345a10aa7086 100644 --- a/drivers/firmware/efi/efibc.c +++ b/drivers/firmware/efi/efibc.c @@ -47,7 +47,7 @@ static int efibc_reboot_notifier_call(struct notifier_block *notifier, if (ret || !data) return NOTIFY_DONE; - wdata = kmalloc_array(MAX_DATA_LEN, sizeof(efi_char16_t), GFP_KERNEL); + wdata = kmalloc_objs(efi_char16_t, MAX_DATA_LEN); if (!wdata) return NOTIFY_DONE; diff --git a/drivers/firmware/efi/embedded-firmware.c b/drivers/firmware/efi/embedded-firmware.c index b49a09d7e665..82744b6a5582 100644 --- a/drivers/firmware/efi/embedded-firmware.c +++ b/drivers/firmware/efi/embedded-firmware.c @@ -64,7 +64,7 @@ static int __init efi_check_md_for_embedded_firmware( pr_info("Found EFI embedded fw '%s'\n", desc->name); - fw = kmalloc(sizeof(*fw), GFP_KERNEL); + fw = kmalloc_obj(*fw); if (!fw) { memunmap(map); return -ENOMEM; diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index 4bb7b0584bc9..df148f7331f4 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -164,7 +164,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) { struct esre_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/firmware/efi/mokvar-table.c b/drivers/firmware/efi/mokvar-table.c index aedbbd627706..6842aa96d704 100644 --- a/drivers/firmware/efi/mokvar-table.c +++ b/drivers/firmware/efi/mokvar-table.c @@ -85,7 +85,7 @@ static struct kobject *mokvar_kobj; * as an alternative to ordinary EFI variables, due to platform-dependent * limitations. The memory occupied by this table is marked as reserved. * - * This routine must be called before efi_free_boot_services() in order + * This routine must be called before efi_unmap_boot_services() in order * to guarantee that it can mark the table as reserved. * * Implicit inputs: @@ -329,7 +329,7 @@ static int __init efi_mokvar_sysfs_init(void) } while (efi_mokvar_entry_next(&mokvar_entry)) { - mokvar_sysfs = kzalloc(sizeof(*mokvar_sysfs), GFP_KERNEL); + mokvar_sysfs = kzalloc_obj(*mokvar_sysfs); if (!mokvar_sysfs) { err = -ENOMEM; break; diff --git a/drivers/firmware/efi/riscv-runtime.c b/drivers/firmware/efi/riscv-runtime.c index 66f584a228d0..60cdf7bf141f 100644 --- a/drivers/firmware/efi/riscv-runtime.c +++ b/drivers/firmware/efi/riscv-runtime.c @@ -83,7 +83,7 @@ static int __init riscv_enable_runtime_services(void) if (!(md->attribute & EFI_MEMORY_SP)) continue; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (WARN_ON(!res)) break; diff --git a/drivers/firmware/efi/stmm/tee_stmm_efi.c b/drivers/firmware/efi/stmm/tee_stmm_efi.c index 7b04dd649629..3bea2ef50ef3 100644 --- a/drivers/firmware/efi/stmm/tee_stmm_efi.c +++ b/drivers/firmware/efi/stmm/tee_stmm_efi.c @@ -14,7 +14,6 @@ #include "mm_communication.h" static struct efivars tee_efivars; -static struct efivar_operations tee_efivar_ops; static size_t max_buffer_size; /* comm + var + func + data */ static size_t max_payload_size; /* func + data */ @@ -520,6 +519,15 @@ static void tee_stmm_restore_efivars_generic_ops(void) efivars_generic_ops_register(); } +static const struct efivar_operations tee_efivar_ops = { + .get_variable = tee_get_variable, + .get_next_variable = tee_get_next_variable, + .set_variable = tee_set_variable, + .set_variable_nonblocking = tee_set_variable_nonblocking, + .query_variable_store = efi_query_variable_store, + .query_variable_info = tee_query_variable_info, +}; + static int tee_stmm_efi_probe(struct tee_client_device *tee_dev) { struct device *dev = &tee_dev->dev; @@ -558,13 +566,6 @@ static int tee_stmm_efi_probe(struct tee_client_device *tee_dev) MM_VARIABLE_COMMUNICATE_SIZE + max_payload_size; - tee_efivar_ops.get_variable = tee_get_variable; - tee_efivar_ops.get_next_variable = tee_get_next_variable; - tee_efivar_ops.set_variable = tee_set_variable; - tee_efivar_ops.set_variable_nonblocking = tee_set_variable_nonblocking; - tee_efivar_ops.query_variable_store = efi_query_variable_store; - tee_efivar_ops.query_variable_info = tee_query_variable_info; - efivars_generic_ops_unregister(); pr_info("Using TEE-based EFI runtime variable services\n"); efivars_register(&tee_efivars, &tee_efivar_ops); diff --git a/drivers/firmware/efi/test/efi_test.c b/drivers/firmware/efi/test/efi_test.c index 77b5f7ac3e20..d54d6a671326 100644 --- a/drivers/firmware/efi/test/efi_test.c +++ b/drivers/firmware/efi/test/efi_test.c @@ -614,8 +614,7 @@ static long efi_runtime_query_capsulecaps(unsigned long arg) if (qcaps.capsule_count == ULONG_MAX) return -EINVAL; - capsules = kcalloc(qcaps.capsule_count + 1, - sizeof(efi_capsule_header_t), GFP_KERNEL); + capsules = kzalloc_objs(efi_capsule_header_t, qcaps.capsule_count + 1); if (!capsules) return -ENOMEM; diff --git a/drivers/firmware/efi/unaccepted_memory.c b/drivers/firmware/efi/unaccepted_memory.c index c2c067eff634..4a8ec8d6a571 100644 --- a/drivers/firmware/efi/unaccepted_memory.c +++ b/drivers/firmware/efi/unaccepted_memory.c @@ -35,14 +35,17 @@ void accept_memory(phys_addr_t start, unsigned long size) struct efi_unaccepted_memory *unaccepted; unsigned long range_start, range_end; struct accept_range range, *entry; - phys_addr_t end = start + size; unsigned long flags; + phys_addr_t end; u64 unit_size; unaccepted = efi_get_unaccepted_table(); if (!unaccepted) return; + end = PAGE_ALIGN(start + size); + start = PAGE_ALIGN_DOWN(start); + unit_size = unaccepted->unit_size; /* @@ -160,15 +163,18 @@ void accept_memory(phys_addr_t start, unsigned long size) bool range_contains_unaccepted_memory(phys_addr_t start, unsigned long size) { struct efi_unaccepted_memory *unaccepted; - phys_addr_t end = start + size; unsigned long flags; bool ret = false; + phys_addr_t end; u64 unit_size; unaccepted = efi_get_unaccepted_table(); if (!unaccepted) return false; + end = PAGE_ALIGN(start + size); + start = PAGE_ALIGN_DOWN(start); + unit_size = unaccepted->unit_size; /* diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c index 0ceccde5a302..e21e7408cc6d 100644 --- a/drivers/firmware/google/gsmi.c +++ b/drivers/firmware/google/gsmi.c @@ -153,7 +153,7 @@ static struct gsmi_buf *gsmi_buf_alloc(void) { struct gsmi_buf *smibuf; - smibuf = kzalloc(sizeof(*smibuf), GFP_KERNEL); + smibuf = kzalloc_obj(*smibuf); if (!smibuf) { printk(KERN_ERR "gsmi: out of memory\n"); return NULL; diff --git a/drivers/firmware/google/vpd.c b/drivers/firmware/google/vpd.c index 339a3f74b247..54349e579b0d 100644 --- a/drivers/firmware/google/vpd.c +++ b/drivers/firmware/google/vpd.c @@ -107,7 +107,7 @@ static int vpd_section_attrib_add(const u8 *key, u32 key_len, if (vpd_section_check_key_name(key, key_len) != VPD_OK) return VPD_OK; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c index 371f24569b3b..e457b6049e83 100644 --- a/drivers/firmware/iscsi_ibft.c +++ b/drivers/firmware/iscsi_ibft.c @@ -634,7 +634,7 @@ static int __init ibft_create_kobject(struct acpi_table_ibft *header, struct pci_dev *pci_dev; int rc = 0; - ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL); + ibft_kobj = kzalloc_obj(*ibft_kobj); if (!ibft_kobj) return -ENOMEM; @@ -773,7 +773,7 @@ static int __init ibft_register_kobjects(struct acpi_table_ibft *header) if (rc) return rc; - ibft_kobj = kzalloc(sizeof(*ibft_kobj), GFP_KERNEL); + ibft_kobj = kzalloc_obj(*ibft_kobj); if (!ibft_kobj) return -ENOMEM; diff --git a/drivers/firmware/memmap.c b/drivers/firmware/memmap.c index 55b9cfad8a04..5862fbae9b78 100644 --- a/drivers/firmware/memmap.c +++ b/drivers/firmware/memmap.c @@ -289,7 +289,7 @@ int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type) entry = firmware_map_find_entry_bootmem(start, end - 1, type); if (!entry) { - entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC); + entry = kzalloc_obj(struct firmware_map_entry, GFP_ATOMIC); if (!entry) return -ENOMEM; } else { diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c index e194f7acb2a9..46b19d803446 100644 --- a/drivers/firmware/microchip/mpfs-auto-update.c +++ b/drivers/firmware/microchip/mpfs-auto-update.c @@ -162,9 +162,9 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader) u32 *response_msg __free(kfree) = kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL); struct mpfs_mss_response *response __free(kfree) = - kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL); + kzalloc_obj(struct mpfs_mss_response); struct mpfs_mss_msg *message __free(kfree) = - kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL); + kzalloc_obj(struct mpfs_mss_msg); int ret; if (!response_msg || !response || !message) @@ -364,9 +364,9 @@ static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv) u32 *response_msg __free(kfree) = kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL); struct mpfs_mss_response *response __free(kfree) = - kzalloc(sizeof(struct mpfs_mss_response), GFP_KERNEL); + kzalloc_obj(struct mpfs_mss_response); struct mpfs_mss_msg *message __free(kfree) = - kzalloc(sizeof(struct mpfs_mss_msg), GFP_KERNEL); + kzalloc_obj(struct mpfs_mss_msg); int ret; if (!response_msg || !response || !message) diff --git a/drivers/firmware/psci/psci_checker.c b/drivers/firmware/psci/psci_checker.c index df02a4ec3398..e67ba9891082 100644 --- a/drivers/firmware/psci/psci_checker.c +++ b/drivers/firmware/psci/psci_checker.c @@ -155,8 +155,7 @@ static int alloc_init_cpu_groups(cpumask_var_t **pcpu_groups) if (!alloc_cpumask_var(&tmp, GFP_KERNEL)) return -ENOMEM; - cpu_groups = kcalloc(nb_available_cpus, sizeof(*cpu_groups), - GFP_KERNEL); + cpu_groups = kzalloc_objs(*cpu_groups, nb_available_cpus); if (!cpu_groups) { free_cpumask_var(tmp); return -ENOMEM; @@ -370,8 +369,7 @@ static int suspend_tests(void) struct task_struct **threads; int nb_threads = 0; - threads = kmalloc_array(nb_available_cpus, sizeof(*threads), - GFP_KERNEL); + threads = kmalloc_objs(*threads, nb_available_cpus); if (!threads) return -ENOMEM; diff --git a/drivers/firmware/qcom/qcom_qseecom.c b/drivers/firmware/qcom/qcom_qseecom.c index 731e6d5719f9..320ec2a77524 100644 --- a/drivers/firmware/qcom/qcom_qseecom.c +++ b/drivers/firmware/qcom/qcom_qseecom.c @@ -50,7 +50,7 @@ static int qseecom_client_register(struct platform_device *qseecom_dev, dev_info(&qseecom_dev->dev, "setting up client for %s\n", desc->app_name); /* Allocate and set-up the client device */ - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c index 9f232e53115e..0635cbeacfc8 100644 --- a/drivers/firmware/qcom/qcom_tzmem.c +++ b/drivers/firmware/qcom/qcom_tzmem.c @@ -262,8 +262,7 @@ qcom_tzmem_pool_new(const struct qcom_tzmem_pool_config *config) return ERR_PTR(-EINVAL); } - struct qcom_tzmem_pool *pool __free(kfree) = kzalloc(sizeof(*pool), - GFP_KERNEL); + struct qcom_tzmem_pool *pool __free(kfree) = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/firmware/qemu_fw_cfg.c b/drivers/firmware/qemu_fw_cfg.c index 0eebd572f9a5..87a5421bc7d5 100644 --- a/drivers/firmware/qemu_fw_cfg.c +++ b/drivers/firmware/qemu_fw_cfg.c @@ -94,7 +94,7 @@ static ssize_t fw_cfg_dma_transfer(void *address, u32 length, u32 control) struct fw_cfg_dma_access *d = NULL; ssize_t ret = length; - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { ret = -ENOMEM; goto end; @@ -325,7 +325,7 @@ static ssize_t fw_cfg_write_vmcoreinfo(const struct fw_cfg_file *f) static struct fw_cfg_vmcoreinfo *data; ssize_t ret; - data = kmalloc(sizeof(struct fw_cfg_vmcoreinfo), GFP_KERNEL); + data = kmalloc_obj(struct fw_cfg_vmcoreinfo); if (!data) return -ENOMEM; @@ -530,7 +530,7 @@ static int fw_cfg_build_symlink(struct kset *dir, dir = to_kset(ko); } else { /* create new subdirectory kset */ - subdir = kzalloc(sizeof(struct kset), GFP_KERNEL); + subdir = kzalloc_obj(struct kset); if (!subdir) { ret = -ENOMEM; break; @@ -593,7 +593,7 @@ static int fw_cfg_register_file(const struct fw_cfg_file *f) #endif /* allocate new entry */ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 7ecde6921a0a..0aa322e9a2e7 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -282,7 +282,7 @@ static int rpi_firmware_probe(struct platform_device *pdev) * Memory will be freed by rpi_firmware_delete() once all users have * released their firmware handles. Don't use devm_kzalloc() here. */ - fw = kzalloc(sizeof(*fw), GFP_KERNEL); + fw = kzalloc_obj(*fw); if (!fw) return -ENOMEM; diff --git a/drivers/firmware/smccc/soc_id.c b/drivers/firmware/smccc/soc_id.c index c24b3fca1cfe..2f7475e66b3c 100644 --- a/drivers/firmware/smccc/soc_id.c +++ b/drivers/firmware/smccc/soc_id.c @@ -137,7 +137,7 @@ static int __init smccc_soc_init(void) return -EINVAL; } - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/firmware/stratix10-rsu.c b/drivers/firmware/stratix10-rsu.c index 41da07c445a6..e1912108a0fe 100644 --- a/drivers/firmware/stratix10-rsu.c +++ b/drivers/firmware/stratix10-rsu.c @@ -768,7 +768,9 @@ static int stratix10_rsu_probe(struct platform_device *pdev) rsu_async_status_callback); if (ret) { dev_err(dev, "Error, getting RSU status %i\n", ret); + stratix10_svc_remove_async_client(priv->chan); stratix10_svc_free_channel(priv->chan); + return ret; } /* get DCMF version from firmware */ diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c index 515b948ff320..e9e35d67ef96 100644 --- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -37,15 +37,14 @@ * service layer will return error to FPGA manager when timeout occurs, * timeout is set to 30 seconds (30 * 1000) at Intel Stratix10 SoC. */ -#define SVC_NUM_DATA_IN_FIFO 32 +#define SVC_NUM_DATA_IN_FIFO 8 #define SVC_NUM_CHANNEL 4 -#define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS 200 +#define FPGA_CONFIG_DATA_CLAIM_TIMEOUT_MS 2000 #define FPGA_CONFIG_STATUS_TIMEOUT_SEC 30 #define BYTE_TO_WORD_SIZE 4 /* stratix10 service layer clients */ #define STRATIX10_RSU "stratix10-rsu" -#define INTEL_FCS "intel-fcs" /* Maximum number of SDM client IDs. */ #define MAX_SDM_CLIENT_IDS 16 @@ -105,11 +104,9 @@ struct stratix10_svc_chan; /** * struct stratix10_svc - svc private data * @stratix10_svc_rsu: pointer to stratix10 RSU device - * @intel_svc_fcs: pointer to the FCS device */ struct stratix10_svc { struct platform_device *stratix10_svc_rsu; - struct platform_device *intel_svc_fcs; }; /** @@ -251,12 +248,10 @@ struct stratix10_async_ctrl { * @num_active_client: number of active service client * @node: list management * @genpool: memory pool pointing to the memory region - * @task: pointer to the thread task which handles SMC or HVC call - * @svc_fifo: a queue for storing service message data * @complete_status: state for completion - * @svc_fifo_lock: protect access to service message data queue * @invoke_fn: function to issue secure monitor call or hypervisor call * @svc: manages the list of client svc drivers + * @sdm_lock: only allows a single command single response to SDM * @actrl: async control structure * * This struct is used to create communication channels for service clients, to @@ -269,12 +264,10 @@ struct stratix10_svc_controller { int num_active_client; struct list_head node; struct gen_pool *genpool; - struct task_struct *task; - struct kfifo svc_fifo; struct completion complete_status; - spinlock_t svc_fifo_lock; svc_invoke_fn *invoke_fn; struct stratix10_svc *svc; + struct mutex sdm_lock; struct stratix10_async_ctrl actrl; }; @@ -283,6 +276,9 @@ struct stratix10_svc_controller { * @ctrl: pointer to service controller which is the provider of this channel * @scl: pointer to service client which owns the channel * @name: service client name associated with the channel + * @task: pointer to the thread task which handles SMC or HVC call + * @svc_fifo: a queue for storing service message data (separate fifo for every channel) + * @svc_fifo_lock: protect access to service message data queue (locking pending fifo) * @lock: protect access to the channel * @async_chan: reference to asynchronous channel object for this channel * @@ -293,6 +289,9 @@ struct stratix10_svc_chan { struct stratix10_svc_controller *ctrl; struct stratix10_svc_client *scl; char *name; + struct task_struct *task; + struct kfifo svc_fifo; + spinlock_t svc_fifo_lock; spinlock_t lock; struct stratix10_async_chan *async_chan; }; @@ -527,19 +526,19 @@ static void svc_thread_recv_status_ok(struct stratix10_svc_data *p_data, */ static int svc_normal_to_secure_thread(void *data) { - struct stratix10_svc_controller - *ctrl = (struct stratix10_svc_controller *)data; - struct stratix10_svc_data *pdata; - struct stratix10_svc_cb_data *cbdata; + struct stratix10_svc_chan *chan = (struct stratix10_svc_chan *)data; + struct stratix10_svc_controller *ctrl = chan->ctrl; + struct stratix10_svc_data *pdata = NULL; + struct stratix10_svc_cb_data *cbdata = NULL; struct arm_smccc_res res; unsigned long a0, a1, a2, a3, a4, a5, a6, a7; int ret_fifo = 0; - pdata = kmalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kmalloc_obj(*pdata); if (!pdata) return -ENOMEM; - cbdata = kmalloc(sizeof(*cbdata), GFP_KERNEL); + cbdata = kmalloc_obj(*cbdata); if (!cbdata) { kfree(pdata); return -ENOMEM; @@ -555,12 +554,12 @@ static int svc_normal_to_secure_thread(void *data) a6 = 0; a7 = 0; - pr_debug("smc_hvc_shm_thread is running\n"); + pr_debug("%s: %s: Thread is running!\n", __func__, chan->name); while (!kthread_should_stop()) { - ret_fifo = kfifo_out_spinlocked(&ctrl->svc_fifo, + ret_fifo = kfifo_out_spinlocked(&chan->svc_fifo, pdata, sizeof(*pdata), - &ctrl->svc_fifo_lock); + &chan->svc_fifo_lock); if (!ret_fifo) continue; @@ -569,9 +568,25 @@ static int svc_normal_to_secure_thread(void *data) (unsigned int)pdata->paddr, pdata->command, (unsigned int)pdata->size); + /* SDM can only process one command at a time */ + pr_debug("%s: %s: Thread is waiting for mutex!\n", + __func__, chan->name); + if (mutex_lock_interruptible(&ctrl->sdm_lock)) { + /* item already dequeued; notify client to unblock it */ + cbdata->status = BIT(SVC_STATUS_ERROR); + cbdata->kaddr1 = NULL; + cbdata->kaddr2 = NULL; + cbdata->kaddr3 = NULL; + if (pdata->chan->scl) + pdata->chan->scl->receive_cb(pdata->chan->scl, + cbdata); + break; + } + switch (pdata->command) { case COMMAND_RECONFIG_DATA_CLAIM: svc_thread_cmd_data_claim(ctrl, pdata, cbdata); + mutex_unlock(&ctrl->sdm_lock); continue; case COMMAND_RECONFIG: a0 = INTEL_SIP_SMC_FPGA_CONFIG_START; @@ -700,10 +715,11 @@ static int svc_normal_to_secure_thread(void *data) break; default: pr_warn("it shouldn't happen\n"); - break; + mutex_unlock(&ctrl->sdm_lock); + continue; } - pr_debug("%s: before SMC call -- a0=0x%016x a1=0x%016x", - __func__, + pr_debug("%s: %s: before SMC call -- a0=0x%016x a1=0x%016x", + __func__, chan->name, (unsigned int)a0, (unsigned int)a1); pr_debug(" a2=0x%016x\n", (unsigned int)a2); @@ -712,8 +728,8 @@ static int svc_normal_to_secure_thread(void *data) pr_debug(" a5=0x%016x\n", (unsigned int)a5); ctrl->invoke_fn(a0, a1, a2, a3, a4, a5, a6, a7, &res); - pr_debug("%s: after SMC call -- res.a0=0x%016x", - __func__, (unsigned int)res.a0); + pr_debug("%s: %s: after SMC call -- res.a0=0x%016x", + __func__, chan->name, (unsigned int)res.a0); pr_debug(" res.a1=0x%016x, res.a2=0x%016x", (unsigned int)res.a1, (unsigned int)res.a2); pr_debug(" res.a3=0x%016x\n", (unsigned int)res.a3); @@ -728,6 +744,7 @@ static int svc_normal_to_secure_thread(void *data) cbdata->kaddr2 = NULL; cbdata->kaddr3 = NULL; pdata->chan->scl->receive_cb(pdata->chan->scl, cbdata); + mutex_unlock(&ctrl->sdm_lock); continue; } @@ -801,6 +818,8 @@ static int svc_normal_to_secure_thread(void *data) break; } + + mutex_unlock(&ctrl->sdm_lock); } kfree(cbdata); @@ -1119,7 +1138,7 @@ int stratix10_svc_add_async_client(struct stratix10_svc_chan *chan, return 0; } - achan = kzalloc(sizeof(*achan), GFP_KERNEL); + achan = kzalloc_obj(*achan); if (!achan) return -ENOMEM; @@ -1317,7 +1336,7 @@ int stratix10_svc_async_send(struct stratix10_svc_chan *chan, void *msg, dev_dbg(ctrl->dev, "Async message sent with transaction_id 0x%02x\n", handle->transaction_id); - *handler = handle; + *handler = handle; return 0; case INTEL_SIP_SMC_STATUS_BUSY: dev_warn(ctrl->dev, "Mailbox is busy, try after some time\n"); @@ -1692,26 +1711,37 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg) int ret = 0; unsigned int cpu = 0; - p_data = kzalloc(sizeof(*p_data), GFP_KERNEL); + p_data = kzalloc_obj(*p_data); if (!p_data) return -ENOMEM; - /* first client will create kernel thread */ - if (!chan->ctrl->task) { - chan->ctrl->task = - kthread_run_on_cpu(svc_normal_to_secure_thread, - (void *)chan->ctrl, - cpu, "svc_smc_hvc_thread"); - if (IS_ERR(chan->ctrl->task)) { - dev_err(chan->ctrl->dev, - "failed to create svc_smc_hvc_thread\n"); - kfree(p_data); - return -EINVAL; - } + /* first caller creates the per-channel kthread */ + if (!chan->task) { + struct task_struct *task; + + task = kthread_run_on_cpu(svc_normal_to_secure_thread, + (void *)chan, + cpu, "svc_smc_hvc_thread"); + if (IS_ERR(task)) { + dev_err(chan->ctrl->dev, + "failed to create svc_smc_hvc_thread\n"); + kfree(p_data); + return -EINVAL; + } + + spin_lock(&chan->lock); + if (chan->task) { + /* another caller won the race; discard our thread */ + spin_unlock(&chan->lock); + kthread_stop(task); + } else { + chan->task = task; + spin_unlock(&chan->lock); + } } - pr_debug("%s: sent P-va=%p, P-com=%x, P-size=%u\n", __func__, - p_msg->payload, p_msg->command, + pr_debug("%s: %s: sent P-va=%p, P-com=%x, P-size=%u\n", __func__, + chan->name, p_msg->payload, p_msg->command, (unsigned int)p_msg->payload_length); if (list_empty(&svc_data_mem)) { @@ -1747,12 +1777,16 @@ int stratix10_svc_send(struct stratix10_svc_chan *chan, void *msg) p_data->arg[2] = p_msg->arg[2]; p_data->size = p_msg->payload_length; p_data->chan = chan; - pr_debug("%s: put to FIFO pa=0x%016x, cmd=%x, size=%u\n", __func__, - (unsigned int)p_data->paddr, p_data->command, - (unsigned int)p_data->size); - ret = kfifo_in_spinlocked(&chan->ctrl->svc_fifo, p_data, + pr_debug("%s: %s: put to FIFO pa=0x%016x, cmd=%x, size=%u\n", + __func__, + chan->name, + (unsigned int)p_data->paddr, + p_data->command, + (unsigned int)p_data->size); + + ret = kfifo_in_spinlocked(&chan->svc_fifo, p_data, sizeof(*p_data), - &chan->ctrl->svc_fifo_lock); + &chan->svc_fifo_lock); kfree(p_data); @@ -1773,11 +1807,12 @@ EXPORT_SYMBOL_GPL(stratix10_svc_send); */ void stratix10_svc_done(struct stratix10_svc_chan *chan) { - /* stop thread when thread is running AND only one active client */ - if (chan->ctrl->task && chan->ctrl->num_active_client <= 1) { - pr_debug("svc_smc_hvc_shm_thread is stopped\n"); - kthread_stop(chan->ctrl->task); - chan->ctrl->task = NULL; + /* stop thread when thread is running */ + if (chan->task) { + pr_debug("%s: %s: svc_smc_hvc_shm_thread is stopping\n", + __func__, chan->name); + kthread_stop(chan->task); + chan->task = NULL; } } EXPORT_SYMBOL_GPL(stratix10_svc_done); @@ -1817,8 +1852,8 @@ void *stratix10_svc_allocate_memory(struct stratix10_svc_chan *chan, pmem->paddr = pa; pmem->size = s; list_add_tail(&pmem->node, &svc_data_mem); - pr_debug("%s: va=%p, pa=0x%016x\n", __func__, - pmem->vaddr, (unsigned int)pmem->paddr); + pr_debug("%s: %s: va=%p, pa=0x%016x\n", __func__, + chan->name, pmem->vaddr, (unsigned int)pmem->paddr); return (void *)va; } @@ -1855,6 +1890,13 @@ static const struct of_device_id stratix10_svc_drv_match[] = { {}, }; +static const char * const chan_names[SVC_NUM_CHANNEL] = { + SVC_CLIENT_FPGA, + SVC_CLIENT_RSU, + SVC_CLIENT_FCS, + SVC_CLIENT_HWMON +}; + static int stratix10_svc_drv_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1862,11 +1904,11 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) struct stratix10_svc_chan *chans; struct gen_pool *genpool; struct stratix10_svc_sh_memory *sh_memory; - struct stratix10_svc *svc; + struct stratix10_svc *svc = NULL; svc_invoke_fn *invoke_fn; size_t fifo_size; - int ret; + int ret, i = 0; /* get SMC or HVC function */ invoke_fn = get_invoke_func(dev); @@ -1905,8 +1947,8 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) controller->num_active_client = 0; controller->chans = chans; controller->genpool = genpool; - controller->task = NULL; controller->invoke_fn = invoke_fn; + INIT_LIST_HEAD(&controller->node); init_completion(&controller->complete_status); ret = stratix10_svc_async_init(controller); @@ -1917,32 +1959,20 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) } fifo_size = sizeof(struct stratix10_svc_data) * SVC_NUM_DATA_IN_FIFO; - ret = kfifo_alloc(&controller->svc_fifo, fifo_size, GFP_KERNEL); - if (ret) { - dev_err(dev, "failed to allocate FIFO\n"); - goto err_async_exit; + mutex_init(&controller->sdm_lock); + + for (i = 0; i < SVC_NUM_CHANNEL; i++) { + chans[i].scl = NULL; + chans[i].ctrl = controller; + chans[i].name = (char *)chan_names[i]; + spin_lock_init(&chans[i].lock); + ret = kfifo_alloc(&chans[i].svc_fifo, fifo_size, GFP_KERNEL); + if (ret) { + dev_err(dev, "failed to allocate FIFO %d\n", i); + goto err_free_fifos; + } + spin_lock_init(&chans[i].svc_fifo_lock); } - spin_lock_init(&controller->svc_fifo_lock); - - chans[0].scl = NULL; - chans[0].ctrl = controller; - chans[0].name = SVC_CLIENT_FPGA; - spin_lock_init(&chans[0].lock); - - chans[1].scl = NULL; - chans[1].ctrl = controller; - chans[1].name = SVC_CLIENT_RSU; - spin_lock_init(&chans[1].lock); - - chans[2].scl = NULL; - chans[2].ctrl = controller; - chans[2].name = SVC_CLIENT_FCS; - spin_lock_init(&chans[2].lock); - - chans[3].scl = NULL; - chans[3].ctrl = controller; - chans[3].name = SVC_CLIENT_HWMON; - spin_lock_init(&chans[3].lock); list_add_tail(&controller->node, &svc_ctrl); platform_set_drvdata(pdev, controller); @@ -1951,7 +1981,7 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) svc = devm_kzalloc(dev, sizeof(*svc), GFP_KERNEL); if (!svc) { ret = -ENOMEM; - goto err_free_kfifo; + goto err_free_fifos; } controller->svc = svc; @@ -1959,51 +1989,43 @@ static int stratix10_svc_drv_probe(struct platform_device *pdev) if (!svc->stratix10_svc_rsu) { dev_err(dev, "failed to allocate %s device\n", STRATIX10_RSU); ret = -ENOMEM; - goto err_free_kfifo; + goto err_free_fifos; } ret = platform_device_add(svc->stratix10_svc_rsu); - if (ret) { - platform_device_put(svc->stratix10_svc_rsu); - goto err_free_kfifo; - } - - svc->intel_svc_fcs = platform_device_alloc(INTEL_FCS, 1); - if (!svc->intel_svc_fcs) { - dev_err(dev, "failed to allocate %s device\n", INTEL_FCS); - ret = -ENOMEM; - goto err_unregister_rsu_dev; - } - - ret = platform_device_add(svc->intel_svc_fcs); - if (ret) { - platform_device_put(svc->intel_svc_fcs); - goto err_unregister_rsu_dev; - } + if (ret) + goto err_put_device; ret = of_platform_default_populate(dev_of_node(dev), NULL, dev); if (ret) - goto err_unregister_fcs_dev; + goto err_unregister_rsu_dev; pr_info("Intel Service Layer Driver Initialized\n"); return 0; -err_unregister_fcs_dev: - platform_device_unregister(svc->intel_svc_fcs); err_unregister_rsu_dev: platform_device_unregister(svc->stratix10_svc_rsu); -err_free_kfifo: - kfifo_free(&controller->svc_fifo); -err_async_exit: + goto err_free_fifos; +err_put_device: + platform_device_put(svc->stratix10_svc_rsu); +err_free_fifos: + /* only remove from list if list_add_tail() was reached */ + if (!list_empty(&controller->node)) + list_del(&controller->node); + /* free only the FIFOs that were successfully allocated */ + while (i--) + kfifo_free(&chans[i].svc_fifo); stratix10_svc_async_exit(controller); err_destroy_pool: gen_pool_destroy(genpool); + return ret; } static void stratix10_svc_drv_remove(struct platform_device *pdev) { + int i; struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev); struct stratix10_svc *svc = ctrl->svc; @@ -2011,14 +2033,16 @@ static void stratix10_svc_drv_remove(struct platform_device *pdev) of_platform_depopulate(ctrl->dev); - platform_device_unregister(svc->intel_svc_fcs); platform_device_unregister(svc->stratix10_svc_rsu); - kfifo_free(&ctrl->svc_fifo); - if (ctrl->task) { - kthread_stop(ctrl->task); - ctrl->task = NULL; + for (i = 0; i < SVC_NUM_CHANNEL; i++) { + if (ctrl->chans[i].task) { + kthread_stop(ctrl->chans[i].task); + ctrl->chans[i].task = NULL; + } + kfifo_free(&ctrl->chans[i].svc_fifo); } + if (ctrl->genpool) gen_pool_destroy(ctrl->genpool); list_del(&ctrl->node); diff --git a/drivers/firmware/thead,th1520-aon.c b/drivers/firmware/thead,th1520-aon.c index 38f812ac9920..a35fd5e2a07f 100644 --- a/drivers/firmware/thead,th1520-aon.c +++ b/drivers/firmware/thead,th1520-aon.c @@ -205,7 +205,7 @@ struct th1520_aon_chan *th1520_aon_init(struct device *dev) struct mbox_client *cl; int ret; - aon_chan = kzalloc(sizeof(*aon_chan), GFP_KERNEL); + aon_chan = kzalloc_obj(*aon_chan); if (!aon_chan) return ERR_PTR(-ENOMEM); diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index f15db1a818dc..fbe8510f4927 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c @@ -267,7 +267,7 @@ static int do_feature_check_call(const u32 api_id) } /* Add new entry if not present */ - feature_data = kmalloc(sizeof(*feature_data), GFP_ATOMIC); + feature_data = kmalloc_obj(*feature_data, GFP_ATOMIC); if (!feature_data) return -ENOMEM; diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c index 5aa7b8884374..87652d58d03f 100644 --- a/drivers/fpga/dfl-afu-dma-region.c +++ b/drivers/fpga/dfl-afu-dma-region.c @@ -42,7 +42,7 @@ static int afu_dma_pin_pages(struct dfl_feature_dev_data *fdata, if (ret) return ret; - region->pages = kcalloc(npages, sizeof(struct page *), GFP_KERNEL); + region->pages = kzalloc_objs(struct page *, npages); if (!region->pages) { ret = -ENOMEM; goto unlock_vm; diff --git a/drivers/fpga/dfl-pci.c b/drivers/fpga/dfl-pci.c index 602807d6afcc..e25205c6d8f0 100644 --- a/drivers/fpga/dfl-pci.c +++ b/drivers/fpga/dfl-pci.c @@ -139,7 +139,7 @@ static int *cci_pci_create_irq_table(struct pci_dev *pcidev, unsigned int nvec) unsigned int i; int *table; - table = kcalloc(nvec, sizeof(int), GFP_KERNEL); + table = kzalloc_objs(int, nvec); if (!table) return table; diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 7022657243c0..4087a36a0571 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -347,7 +347,7 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, struct dfl_device *ddev; int id, i, ret; - ddev = kzalloc(sizeof(*ddev), GFP_KERNEL); + ddev = kzalloc_obj(*ddev); if (!ddev) return ERR_PTR(-ENOMEM); @@ -397,8 +397,7 @@ dfl_dev_add(struct dfl_feature_dev_data *fdata, /* then add irq resource */ if (feature->nr_irqs) { - ddev->irqs = kcalloc(feature->nr_irqs, - sizeof(*ddev->irqs), GFP_KERNEL); + ddev->irqs = kzalloc_objs(*ddev->irqs, feature->nr_irqs); if (!ddev->irqs) { ret = -ENOMEM; goto put_dev; @@ -1182,7 +1181,7 @@ create_feature_instance(struct build_feature_devs_info *binfo, if (binfo->len - ofst < size) return -EINVAL; - finfo = kzalloc(struct_size(finfo, params, dfh_psize / sizeof(u64)), GFP_KERNEL); + finfo = kzalloc_flex(*finfo, params, dfh_psize / sizeof(u64)); if (!finfo) return -ENOMEM; @@ -2018,7 +2017,7 @@ static void __exit dfl_fpga_exit(void) bus_unregister(&dfl_bus_type); } -module_init(dfl_fpga_init); +subsys_initcall(dfl_fpga_init); module_exit(dfl_fpga_exit); MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support"); diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 95539f1213cb..9549f63b00eb 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -82,7 +82,7 @@ #define DFH_TYPE_FIU 4 /* - * DFHv1 Register Offset definitons + * DFHv1 Register Offset definitions * In DHFv1, DFH + GUID + CSR_START + CSR_SIZE_GROUP + PARAM_HDR + PARAM_DATA * as common header registers */ diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index 8ef395b49bf8..ca68c38aa4a1 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -346,7 +346,7 @@ __fpga_bridge_register(struct device *parent, const char *name, return ERR_PTR(-EINVAL); } - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return ERR_PTR(-ENOMEM); diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 0f4035b089a2..2672070ced02 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -486,7 +486,7 @@ static int fpga_mgr_buf_load(struct fpga_manager *mgr, */ nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) - (unsigned long)buf / PAGE_SIZE; - pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, nr_pages); if (!pages) return -ENOMEM; @@ -801,7 +801,7 @@ __fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info * return ERR_PTR(-EINVAL); } - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (!mgr) return ERR_PTR(-ENOMEM); diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 753cd142503e..662e8e4203ca 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -201,7 +201,7 @@ __fpga_region_register_full(struct device *parent, const struct fpga_region_info return ERR_PTR(-EINVAL); } - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) return ERR_PTR(-ENOMEM); diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c index 43db4bb77138..caa091224dc5 100644 --- a/drivers/fpga/of-fpga-region.c +++ b/drivers/fpga/of-fpga-region.c @@ -83,7 +83,7 @@ static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np) * done with the bridges. * * Return: 0 for success (even if there are no bridges specified) - * or -EBUSY if any of the bridges are in use. + * or an error code if any of the bridges are not available. */ static int of_fpga_region_get_bridges(struct fpga_region *region) { @@ -130,10 +130,10 @@ static int of_fpga_region_get_bridges(struct fpga_region *region) ®ion->bridge_list); of_node_put(br); - /* If any of the bridges are in use, give up */ - if (ret == -EBUSY) { + /* If any of the bridges are not available, give up */ + if (ret) { fpga_bridges_put(®ion->bridge_list); - return -EBUSY; + return ret; } } diff --git a/drivers/fpga/xilinx-pr-decoupler.c b/drivers/fpga/xilinx-pr-decoupler.c index 822751fad18a..6994d68e9036 100644 --- a/drivers/fpga/xilinx-pr-decoupler.c +++ b/drivers/fpga/xilinx-pr-decoupler.c @@ -173,5 +173,5 @@ module_platform_driver(xlnx_pr_decoupler_driver); MODULE_DESCRIPTION("Xilinx Partial Reconfiguration Decoupler"); MODULE_AUTHOR("Moritz Fischer "); -MODULE_AUTHOR("Michal Simek "); +MODULE_AUTHOR("Michal Simek "); MODULE_LICENSE("GPL v2"); diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c index b7629a0e4813..9d1d599ef718 100644 --- a/drivers/fpga/zynq-fpga.c +++ b/drivers/fpga/zynq-fpga.c @@ -652,6 +652,6 @@ static struct platform_driver zynq_fpga_driver = { module_platform_driver(zynq_fpga_driver); MODULE_AUTHOR("Moritz Fischer "); -MODULE_AUTHOR("Michal Simek "); +MODULE_AUTHOR("Michal Simek "); MODULE_DESCRIPTION("Xilinx Zynq FPGA Manager"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index c6c115993ebc..91b60b1fb86a 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -100,6 +100,61 @@ static int fsi_master_write(struct fsi_master *master, int link, uint8_t slave_id, uint32_t addr, const void *val, size_t size); static int fsi_master_break(struct fsi_master *master, int link); +/* FSI core & Linux bus type definitions */ + +static int fsi_bus_match(struct device *dev, const struct device_driver *drv) +{ + struct fsi_device *fsi_dev = to_fsi_dev(dev); + const struct fsi_driver *fsi_drv = to_fsi_drv(drv); + const struct fsi_device_id *id; + + if (!fsi_drv->id_table) + return 0; + + for (id = fsi_drv->id_table; id->engine_type; id++) { + if (id->engine_type != fsi_dev->engine_type) + continue; + if (id->version == FSI_VERSION_ANY || + id->version == fsi_dev->version) { + if (drv->of_match_table) { + if (of_driver_match_device(dev, drv)) + return 1; + } else { + return 1; + } + } + } + + return 0; +} + +static int fsi_probe(struct device *dev) +{ + struct fsi_device *fsidev = to_fsi_dev(dev); + struct fsi_driver *fsidrv = to_fsi_drv(dev->driver); + + if (fsidrv->probe) + return fsidrv->probe(fsidev); + else + return 0; +} + +static void fsi_remove(struct device *dev) +{ + struct fsi_device *fsidev = to_fsi_dev(dev); + struct fsi_driver *fsidrv = to_fsi_drv(dev->driver); + + if (fsidrv->remove) + fsidrv->remove(fsidev); +} + +static const struct bus_type fsi_bus_type = { + .name = "fsi", + .match = fsi_bus_match, + .probe = fsi_probe, + .remove = fsi_remove, +}; + /* * fsi_device_read() / fsi_device_write() / fsi_device_peek() * @@ -156,7 +211,7 @@ static struct fsi_device *fsi_create_device(struct fsi_slave *slave) { struct fsi_device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -1028,7 +1083,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) /* We can communicate with a slave; create the slave device and * register. */ - slave = kzalloc(sizeof(*slave), GFP_KERNEL); + slave = kzalloc_obj(*slave); if (!slave) return -ENOMEM; @@ -1359,32 +1414,23 @@ void fsi_master_unregister(struct fsi_master *master) } EXPORT_SYMBOL_GPL(fsi_master_unregister); -/* FSI core & Linux bus type definitions */ - -static int fsi_bus_match(struct device *dev, const struct device_driver *drv) +static int fsi_legacy_probe(struct fsi_device *fsidev) { - struct fsi_device *fsi_dev = to_fsi_dev(dev); - const struct fsi_driver *fsi_drv = to_fsi_drv(drv); - const struct fsi_device_id *id; + struct device *dev = &fsidev->dev; + struct device_driver *driver = dev->driver; - if (!fsi_drv->id_table) - return 0; + return driver->probe(dev); +} - for (id = fsi_drv->id_table; id->engine_type; id++) { - if (id->engine_type != fsi_dev->engine_type) - continue; - if (id->version == FSI_VERSION_ANY || - id->version == fsi_dev->version) { - if (drv->of_match_table) { - if (of_driver_match_device(dev, drv)) - return 1; - } else { - return 1; - } - } - } +static void fsi_legacy_remove(struct fsi_device *fsidev) +{ + struct device *dev = &fsidev->dev; + struct device_driver *driver = dev->driver; + int ret; - return 0; + ret = driver->remove(dev); + if (unlikely(ret)) + dev_warn(dev, "Ignoring return value of remove callback (%pe)\n", ERR_PTR(ret)); } int fsi_driver_register(struct fsi_driver *fsi_drv) @@ -1394,6 +1440,17 @@ int fsi_driver_register(struct fsi_driver *fsi_drv) if (!fsi_drv->id_table) return -EINVAL; + fsi_drv->drv.bus = &fsi_bus_type; + + /* + * This driver needs updating. Note that driver_register() warns about + * this, so we're not adding another warning here. + */ + if (!fsi_drv->probe && fsi_drv->drv.probe) + fsi_drv->probe = fsi_legacy_probe; + if (!fsi_drv->remove && fsi_drv->drv.remove) + fsi_drv->remove = fsi_legacy_remove; + return driver_register(&fsi_drv->drv); } EXPORT_SYMBOL_GPL(fsi_driver_register); @@ -1404,12 +1461,6 @@ void fsi_driver_unregister(struct fsi_driver *fsi_drv) } EXPORT_SYMBOL_GPL(fsi_driver_unregister); -const struct bus_type fsi_bus_type = { - .name = "fsi", - .match = fsi_bus_match, -}; -EXPORT_SYMBOL_GPL(fsi_bus_type); - static int __init fsi_init(void) { int rc; diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c index bff897f77fe5..aa1380cdff33 100644 --- a/drivers/fsi/fsi-master-aspeed.c +++ b/drivers/fsi/fsi-master-aspeed.c @@ -546,7 +546,7 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev) return rc; } - aspeed = kzalloc(sizeof(*aspeed), GFP_KERNEL); + aspeed = kzalloc_obj(*aspeed); if (!aspeed) return -ENOMEM; diff --git a/drivers/fsi/fsi-master-ast-cf.c b/drivers/fsi/fsi-master-ast-cf.c index e67d7cd30fca..c3ac76bf7e97 100644 --- a/drivers/fsi/fsi-master-ast-cf.c +++ b/drivers/fsi/fsi-master-ast-cf.c @@ -1220,7 +1220,7 @@ static int fsi_master_acf_probe(struct platform_device *pdev) uint32_t cf_mem_align; int rc; - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return -ENOMEM; diff --git a/drivers/fsi/fsi-master-gpio.c b/drivers/fsi/fsi-master-gpio.c index 69de0b5b9cbd..0884e143b30e 100644 --- a/drivers/fsi/fsi-master-gpio.c +++ b/drivers/fsi/fsi-master-gpio.c @@ -774,7 +774,7 @@ static int fsi_master_gpio_probe(struct platform_device *pdev) struct gpio_desc *gpio; int rc; - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return -ENOMEM; diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c index 6568fed7db3c..e5ac9025762e 100644 --- a/drivers/fsi/fsi-master-hub.c +++ b/drivers/fsi/fsi-master-hub.c @@ -192,9 +192,9 @@ static int hub_master_init(struct fsi_master_hub *hub) return fsi_device_write(dev, FSI_MRESB0, ®, sizeof(reg)); } -static int hub_master_probe(struct device *dev) +static int hub_master_probe(struct fsi_device *fsi_dev) { - struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct device *dev = &fsi_dev->dev; struct fsi_master_hub *hub; uint32_t reg, links; __be32 __reg; @@ -215,7 +215,7 @@ static int hub_master_probe(struct device *dev) return rc; } - hub = kzalloc(sizeof(*hub), GFP_KERNEL); + hub = kzalloc_obj(*hub); if (!hub) { rc = -ENOMEM; goto err_release; @@ -235,7 +235,7 @@ static int hub_master_probe(struct device *dev) hub->master.send_break = hub_master_break; hub->master.link_enable = hub_master_link_enable; - dev_set_drvdata(dev, hub); + fsi_set_drvdata(fsi_dev, hub); hub_master_init(hub); @@ -259,9 +259,9 @@ static int hub_master_probe(struct device *dev) return rc; } -static int hub_master_remove(struct device *dev) +static void hub_master_remove(struct fsi_device *fsi_dev) { - struct fsi_master_hub *hub = dev_get_drvdata(dev); + struct fsi_master_hub *hub = fsi_get_drvdata(fsi_dev); fsi_master_unregister(&hub->master); fsi_slave_release_range(hub->upstream->slave, hub->addr, hub->size); @@ -272,8 +272,6 @@ static int hub_master_remove(struct device *dev) * the hub */ put_device(&hub->master.dev); - - return 0; } static const struct fsi_device_id hub_master_ids[] = { @@ -286,11 +284,10 @@ static const struct fsi_device_id hub_master_ids[] = { static struct fsi_driver hub_master_driver = { .id_table = hub_master_ids, + .probe = hub_master_probe, + .remove = hub_master_remove, .drv = { .name = "fsi-master-hub", - .bus = &fsi_bus_type, - .probe = hub_master_probe, - .remove = hub_master_remove, } }; diff --git a/drivers/fsi/fsi-master-i2cr.c b/drivers/fsi/fsi-master-i2cr.c index 40f1f4d231e5..d36a4328ad73 100644 --- a/drivers/fsi/fsi-master-i2cr.c +++ b/drivers/fsi/fsi-master-i2cr.c @@ -261,7 +261,7 @@ static int i2cr_probe(struct i2c_client *client) struct fsi_master_i2cr *i2cr; int ret; - i2cr = kzalloc(sizeof(*i2cr), GFP_KERNEL); + i2cr = kzalloc_obj(*i2cr); if (!i2cr) return -ENOMEM; diff --git a/drivers/fsi/fsi-occ.c b/drivers/fsi/fsi-occ.c index e41ef12fa095..416d176f0936 100644 --- a/drivers/fsi/fsi-occ.c +++ b/drivers/fsi/fsi-occ.c @@ -79,7 +79,7 @@ static DEFINE_IDA(occ_ida); static int occ_open(struct inode *inode, struct file *file) { - struct occ_client *client = kzalloc(sizeof(*client), GFP_KERNEL); + struct occ_client *client = kzalloc_obj(*client); struct miscdevice *mdev = file->private_data; struct occ *occ = to_occ(mdev); diff --git a/drivers/fsi/fsi-sbefifo.c b/drivers/fsi/fsi-sbefifo.c index 0a98517f3959..619b8e1b26fd 100644 --- a/drivers/fsi/fsi-sbefifo.c +++ b/drivers/fsi/fsi-sbefifo.c @@ -792,7 +792,7 @@ static int sbefifo_user_open(struct inode *inode, struct file *file) struct sbefifo *sbefifo = container_of(inode->i_cdev, struct sbefifo, cdev); struct sbefifo_user *user; - user = kzalloc(sizeof(struct sbefifo_user), GFP_KERNEL); + user = kzalloc_obj(struct sbefifo_user); if (!user) return -ENOMEM; @@ -1022,9 +1022,9 @@ static void sbefifo_free(struct device *dev) * Probe/remove */ -static int sbefifo_probe(struct device *dev) +static int sbefifo_probe(struct fsi_device *fsi_dev) { - struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct device *dev = &fsi_dev->dev; struct sbefifo *sbefifo; struct device_node *np; struct platform_device *child; @@ -1033,7 +1033,7 @@ static int sbefifo_probe(struct device *dev) dev_dbg(dev, "Found sbefifo device\n"); - sbefifo = kzalloc(sizeof(*sbefifo), GFP_KERNEL); + sbefifo = kzalloc_obj(*sbefifo); if (!sbefifo) return -ENOMEM; @@ -1045,7 +1045,7 @@ static int sbefifo_probe(struct device *dev) sbefifo->magic = SBEFIFO_MAGIC; sbefifo->fsi_dev = fsi_dev; - dev_set_drvdata(dev, sbefifo); + fsi_set_drvdata(fsi_dev, sbefifo); mutex_init(&sbefifo->lock); sbefifo->timeout_in_cmd_ms = SBEFIFO_TIMEOUT_IN_CMD; sbefifo->timeout_start_rsp_ms = SBEFIFO_TIMEOUT_START_RSP; @@ -1101,9 +1101,10 @@ static int sbefifo_unregister_child(struct device *dev, void *data) return 0; } -static int sbefifo_remove(struct device *dev) +static void sbefifo_remove(struct fsi_device *fsi_dev) { - struct sbefifo *sbefifo = dev_get_drvdata(dev); + struct device *dev = &fsi_dev->dev; + struct sbefifo *sbefifo = fsi_get_drvdata(fsi_dev); dev_dbg(dev, "Removing sbefifo device...\n"); @@ -1117,8 +1118,6 @@ static int sbefifo_remove(struct device *dev) fsi_free_minor(sbefifo->dev.devt); device_for_each_child(dev, NULL, sbefifo_unregister_child); put_device(&sbefifo->dev); - - return 0; } static const struct fsi_device_id sbefifo_ids[] = { @@ -1131,26 +1130,14 @@ static const struct fsi_device_id sbefifo_ids[] = { static struct fsi_driver sbefifo_drv = { .id_table = sbefifo_ids, + .probe = sbefifo_probe, + .remove = sbefifo_remove, .drv = { .name = DEVICE_NAME, - .bus = &fsi_bus_type, - .probe = sbefifo_probe, - .remove = sbefifo_remove, } }; -static int sbefifo_init(void) -{ - return fsi_driver_register(&sbefifo_drv); -} - -static void sbefifo_exit(void) -{ - fsi_driver_unregister(&sbefifo_drv); -} - -module_init(sbefifo_init); -module_exit(sbefifo_exit); +module_fsi_driver(sbefifo_drv); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Brad Bishop "); MODULE_AUTHOR("Eddie James "); diff --git a/drivers/fsi/fsi-scom.c b/drivers/fsi/fsi-scom.c index 411ddc018cd8..bb4d3700c934 100644 --- a/drivers/fsi/fsi-scom.c +++ b/drivers/fsi/fsi-scom.c @@ -527,16 +527,16 @@ static void scom_free(struct device *dev) kfree(scom); } -static int scom_probe(struct device *dev) +static int scom_probe(struct fsi_device *fsi_dev) { - struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct device *dev = &fsi_dev->dev; struct scom_device *scom; int rc, didx; - scom = kzalloc(sizeof(*scom), GFP_KERNEL); + scom = kzalloc_obj(*scom); if (!scom) return -ENOMEM; - dev_set_drvdata(dev, scom); + fsi_set_drvdata(fsi_dev, scom); mutex_init(&scom->lock); /* Grab a reference to the device (parent of our cdev), we'll drop it later */ @@ -574,9 +574,9 @@ static int scom_probe(struct device *dev) return rc; } -static int scom_remove(struct device *dev) +static void scom_remove(struct fsi_device *fsi_dev) { - struct scom_device *scom = dev_get_drvdata(dev); + struct scom_device *scom = fsi_get_drvdata(fsi_dev); mutex_lock(&scom->lock); scom->dead = true; @@ -584,8 +584,6 @@ static int scom_remove(struct device *dev) cdev_device_del(&scom->cdev, &scom->dev); fsi_free_minor(scom->dev.devt); put_device(&scom->dev); - - return 0; } static const struct of_device_id scom_of_ids[] = { @@ -604,26 +602,14 @@ static const struct fsi_device_id scom_ids[] = { static struct fsi_driver scom_drv = { .id_table = scom_ids, + .probe = scom_probe, + .remove = scom_remove, .drv = { .name = "scom", - .bus = &fsi_bus_type, .of_match_table = scom_of_ids, - .probe = scom_probe, - .remove = scom_remove, } }; -static int scom_init(void) -{ - return fsi_driver_register(&scom_drv); -} - -static void scom_exit(void) -{ - fsi_driver_unregister(&scom_drv); -} - -module_init(scom_init); -module_exit(scom_exit); +module_fsi_driver(scom_drv); MODULE_DESCRIPTION("SCOM FSI Client device driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/fsi/i2cr-scom.c b/drivers/fsi/i2cr-scom.c index cb7e02213032..3efca2e944bb 100644 --- a/drivers/fsi/i2cr-scom.c +++ b/drivers/fsi/i2cr-scom.c @@ -81,9 +81,9 @@ static const struct file_operations i2cr_scom_fops = { .write = i2cr_scom_write, }; -static int i2cr_scom_probe(struct device *dev) +static int i2cr_scom_probe(struct fsi_device *fsi_dev) { - struct fsi_device *fsi_dev = to_fsi_dev(dev); + struct device *dev = &fsi_dev->dev; struct i2cr_scom *scom; int didx; int ret; @@ -115,14 +115,12 @@ static int i2cr_scom_probe(struct device *dev) return ret; } -static int i2cr_scom_remove(struct device *dev) +static void i2cr_scom_remove(struct fsi_device *fsi_dev) { - struct i2cr_scom *scom = dev_get_drvdata(dev); + struct i2cr_scom *scom = dev_get_drvdata(&fsi_dev->dev); cdev_device_del(&scom->cdev, &scom->dev); fsi_free_minor(scom->dev.devt); - - return 0; } static const struct of_device_id i2cr_scom_of_ids[] = { @@ -137,13 +135,12 @@ static const struct fsi_device_id i2cr_scom_ids[] = { }; static struct fsi_driver i2cr_scom_driver = { + .probe = i2cr_scom_probe, + .remove = i2cr_scom_remove, .id_table = i2cr_scom_ids, .drv = { .name = "i2cr_scom", - .bus = &fsi_bus_type, .of_match_table = i2cr_scom_of_ids, - .probe = i2cr_scom_probe, - .remove = i2cr_scom_remove, } }; diff --git a/drivers/fwctl/mlx5/main.c b/drivers/fwctl/mlx5/main.c index 3dacccf7855c..e86ab703c767 100644 --- a/drivers/fwctl/mlx5/main.c +++ b/drivers/fwctl/mlx5/main.c @@ -167,7 +167,7 @@ static void *mlx5ctl_info(struct fwctl_uctx *uctx, size_t *length) container_of(uctx, struct mlx5ctl_uctx, uctx); struct fwctl_info_mlx5 *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); diff --git a/drivers/fwctl/pds/main.c b/drivers/fwctl/pds/main.c index 1809853f6353..08872ee8422f 100644 --- a/drivers/fwctl/pds/main.c +++ b/drivers/fwctl/pds/main.c @@ -58,7 +58,7 @@ static void *pdsfc_info(struct fwctl_uctx *uctx, size_t *length) struct pdsfc_uctx *pdsfc_uctx = container_of(uctx, struct pdsfc_uctx, uctx); struct fwctl_info_pds *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); diff --git a/drivers/gnss/core.c b/drivers/gnss/core.c index 883ef86ad3fc..006f5533e97b 100644 --- a/drivers/gnss/core.c +++ b/drivers/gnss/core.c @@ -227,7 +227,7 @@ struct gnss_device *gnss_allocate_device(struct device *parent) int id; int ret; - gdev = kzalloc(sizeof(*gdev), GFP_KERNEL); + gdev = kzalloc_obj(*gdev); if (!gdev) return NULL; diff --git a/drivers/gnss/usb.c b/drivers/gnss/usb.c index 028ce56b20ea..0d9dde02397c 100644 --- a/drivers/gnss/usb.c +++ b/drivers/gnss/usb.c @@ -131,7 +131,7 @@ static int gnss_usb_probe(struct usb_interface *intf, const struct usb_device_id if (ret) return ret; - gusb = kzalloc(sizeof(*gusb), GFP_KERNEL); + gusb = kzalloc_obj(*gusb); if (!gusb) return -ENOMEM; diff --git a/drivers/gpib/agilent_82350b/agilent_82350b.c b/drivers/gpib/agilent_82350b/agilent_82350b.c index 01a5bb43cd2d..9787c09faad8 100644 --- a/drivers/gpib/agilent_82350b/agilent_82350b.c +++ b/drivers/gpib/agilent_82350b/agilent_82350b.c @@ -481,7 +481,7 @@ static void agilent_82350b_return_to_local(struct gpib_board *board) static int agilent_82350b_allocate_private(struct gpib_board *board) { - board->private_data = kzalloc(sizeof(struct agilent_82350b_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct agilent_82350b_priv); if (!board->private_data) return -ENOMEM; return 0; @@ -599,8 +599,9 @@ static int agilent_82350b_generic_attach(struct gpib_board *board, board->status = 0; - if (agilent_82350b_allocate_private(board)) - return -ENOMEM; + retval = agilent_82350b_allocate_private(board); + if (retval) + return retval; a_priv = board->private_data; a_priv->using_fifos = use_fifos; tms_priv = &a_priv->tms9914_priv; diff --git a/drivers/gpib/agilent_82357a/agilent_82357a.c b/drivers/gpib/agilent_82357a/agilent_82357a.c index 77c8e549b208..e1349afbf933 100644 --- a/drivers/gpib/agilent_82357a/agilent_82357a.c +++ b/drivers/gpib/agilent_82357a/agilent_82357a.c @@ -1196,7 +1196,7 @@ static int agilent_82357a_allocate_private(struct gpib_board *board) { struct agilent_82357a_priv *a_priv; - board->private_data = kzalloc(sizeof(struct agilent_82357a_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct agilent_82357a_priv); if (!board->private_data) return -ENOMEM; a_priv = board->private_data; @@ -1316,7 +1316,7 @@ static int agilent_82357a_attach(struct gpib_board *board, const struct gpib_boa return -ERESTARTSYS; retval = agilent_82357a_allocate_private(board); - if (retval < 0) { + if (retval) { mutex_unlock(&agilent_82357a_hotplug_lock); return retval; } diff --git a/drivers/gpib/cb7210/cb7210.c b/drivers/gpib/cb7210/cb7210.c index 24c61b151071..6dd8637c5964 100644 --- a/drivers/gpib/cb7210/cb7210.c +++ b/drivers/gpib/cb7210/cb7210.c @@ -856,11 +856,10 @@ static int cb7210_allocate_private(struct gpib_board *board) { struct cb7210_priv *priv; - board->private_data = kmalloc(sizeof(struct cb7210_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct cb7210_priv); if (!board->private_data) return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct cb7210_priv)); init_nec7210_private(&priv->nec7210_priv); return 0; } @@ -876,11 +875,13 @@ static int cb7210_generic_attach(struct gpib_board *board) { struct cb7210_priv *cb_priv; struct nec7210_priv *nec_priv; + int retval; board->status = 0; - if (cb7210_allocate_private(board)) - return -ENOMEM; + retval = cb7210_allocate_private(board); + if (retval) + return retval; cb_priv = board->private_data; nec_priv = &cb_priv->nec7210_priv; nec_priv->read_byte = nec7210_locking_ioport_read_byte; @@ -1187,7 +1188,7 @@ static int cb_gpib_probe(struct pcmcia_device *link) int ret; /* Allocate space for private device-specific data */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/gpib/cec/cec_gpib.c b/drivers/gpib/cec/cec_gpib.c index dbf9b95baabc..c13bc302d9e9 100644 --- a/drivers/gpib/cec/cec_gpib.c +++ b/drivers/gpib/cec/cec_gpib.c @@ -220,11 +220,10 @@ static int cec_allocate_private(struct gpib_board *board) { struct cec_priv *priv; - board->private_data = kmalloc(sizeof(struct cec_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct cec_priv); if (!board->private_data) - return -1; + return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct cec_priv)); init_nec7210_private(&priv->nec7210_priv); return 0; } @@ -239,11 +238,13 @@ static int cec_generic_attach(struct gpib_board *board) { struct cec_priv *cec_priv; struct nec7210_priv *nec_priv; + int retval; board->status = 0; - if (cec_allocate_private(board)) - return -ENOMEM; + retval = cec_allocate_private(board); + if (retval) + return retval; cec_priv = board->private_data; nec_priv = &cec_priv->nec7210_priv; nec_priv->read_byte = nec7210_ioport_read_byte; diff --git a/drivers/gpib/common/gpib_os.c b/drivers/gpib/common/gpib_os.c index 9dbbac8b8436..be757db993a5 100644 --- a/drivers/gpib/common/gpib_os.c +++ b/drivers/gpib/common/gpib_os.c @@ -199,7 +199,7 @@ int push_status_byte(struct gpib_board *board, struct gpib_status_queue *device, return retval; } - status = kmalloc(sizeof(*status), GFP_KERNEL); + status = kmalloc_obj(*status); if (!status) return -ENOMEM; @@ -513,7 +513,7 @@ static int init_gpib_file_private(struct gpib_file_private *priv) { memset(priv, 0, sizeof(*priv)); atomic_set(&priv->holding_mutex, 0); - priv->descriptors[0] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL); + priv->descriptors[0] = kmalloc_obj(struct gpib_descriptor); if (!priv->descriptors[0]) { pr_err("gpib: failed to allocate default board descriptor\n"); return -ENOMEM; @@ -537,7 +537,7 @@ int ibopen(struct inode *inode, struct file *filep) board = &board_array[minor]; - filep->private_data = kmalloc(sizeof(struct gpib_file_private), GFP_KERNEL); + filep->private_data = kmalloc_obj(struct gpib_file_private); if (!filep->private_data) return -ENOMEM; @@ -1146,7 +1146,7 @@ static int increment_open_device_count(struct gpib_board *board, struct list_hea } /* otherwise we need to allocate a new struct gpib_status_queue */ - device = kmalloc(sizeof(struct gpib_status_queue), GFP_ATOMIC); + device = kmalloc_obj(struct gpib_status_queue, GFP_ATOMIC); if (!device) return -ENOMEM; init_gpib_status_queue(device); @@ -1241,7 +1241,7 @@ static int open_dev_ioctl(struct file *filep, struct gpib_board *board, unsigned mutex_unlock(&file_priv->descriptors_mutex); return -ERANGE; } - file_priv->descriptors[i] = kmalloc(sizeof(struct gpib_descriptor), GFP_KERNEL); + file_priv->descriptors[i] = kmalloc_obj(struct gpib_descriptor); if (!file_priv->descriptors[i]) { mutex_unlock(&file_priv->descriptors_mutex); return -ENOMEM; @@ -1876,7 +1876,7 @@ static int push_gpib_event_nolock(struct gpib_board *board, short event_type) return retval; } - event = kmalloc(sizeof(struct gpib_event), GFP_ATOMIC); + event = kmalloc_obj(struct gpib_event, GFP_ATOMIC); if (!event) { queue->dropped_event = 1; dev_err(board->gpib_dev, "failed to allocate memory for event\n"); @@ -2041,7 +2041,7 @@ int gpib_register_driver(struct gpib_interface *interface, struct module *provid { struct gpib_interface_list *entry; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/gpib/common/iblib.c b/drivers/gpib/common/iblib.c index 7cbb6a467177..b672dd6aad25 100644 --- a/drivers/gpib/common/iblib.c +++ b/drivers/gpib/common/iblib.c @@ -227,11 +227,10 @@ int ibonline(struct gpib_board *board) #ifndef CONFIG_NIOS2 board->autospoll_task = kthread_run(&autospoll_thread, board, "gpib%d_autospoll_kthread", board->minor); - retval = IS_ERR(board->autospoll_task); - if (retval) { + if (IS_ERR(board->autospoll_task)) { dev_err(board->gpib_dev, "failed to create autospoll thread\n"); board->interface->detach(board); - return retval; + return PTR_ERR(board->autospoll_task); } #endif board->online = 1; diff --git a/drivers/gpib/eastwood/fluke_gpib.c b/drivers/gpib/eastwood/fluke_gpib.c index 3ae848e3f738..2069c771ecef 100644 --- a/drivers/gpib/eastwood/fluke_gpib.c +++ b/drivers/gpib/eastwood/fluke_gpib.c @@ -853,11 +853,10 @@ static int fluke_allocate_private(struct gpib_board *board) { struct fluke_priv *priv; - board->private_data = kmalloc(sizeof(struct fluke_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct fluke_priv); if (!board->private_data) return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct fluke_priv)); init_nec7210_private(&priv->nec7210_priv); priv->dma_buffer_size = 0x7ff; priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL); @@ -887,7 +886,7 @@ static int fluke_generic_attach(struct gpib_board *board) board->status = 0; retval = fluke_allocate_private(board); - if (retval < 0) + if (retval) return retval; e_priv = board->private_data; nec_priv = &e_priv->nec7210_priv; diff --git a/drivers/gpib/fmh_gpib/fmh_gpib.c b/drivers/gpib/fmh_gpib/fmh_gpib.c index f7bfb4a8e553..fcafdc02ea2e 100644 --- a/drivers/gpib/fmh_gpib/fmh_gpib.c +++ b/drivers/gpib/fmh_gpib/fmh_gpib.c @@ -1250,11 +1250,10 @@ static int fmh_gpib_allocate_private(struct gpib_board *board) { struct fmh_priv *priv; - board->private_data = kmalloc(sizeof(struct fmh_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct fmh_priv); if (!board->private_data) return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct fmh_priv)); init_nec7210_private(&priv->nec7210_priv); priv->dma_buffer_size = 0x800; priv->dma_buffer = kmalloc(priv->dma_buffer_size, GFP_KERNEL); @@ -1286,7 +1285,7 @@ static int fmh_gpib_generic_attach(struct gpib_board *board) board->status = 0; retval = fmh_gpib_allocate_private(board); - if (retval < 0) + if (retval) return retval; e_priv = board->private_data; nec_priv = &e_priv->nec7210_priv; diff --git a/drivers/gpib/gpio/gpib_bitbang.c b/drivers/gpib/gpio/gpib_bitbang.c index 374cd61355e9..0e227980b493 100644 --- a/drivers/gpib/gpio/gpib_bitbang.c +++ b/drivers/gpib/gpio/gpib_bitbang.c @@ -1066,9 +1066,9 @@ static int bb_line_status(const struct gpib_board *board) static int allocate_private(struct gpib_board *board) { - board->private_data = kzalloc(sizeof(struct bb_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct bb_priv); if (!board->private_data) - return -1; + return -ENOMEM; return 0; } @@ -1205,14 +1205,15 @@ static void bb_detach(struct gpib_board *board) static int bb_attach(struct gpib_board *board, const struct gpib_board_config *config) { struct bb_priv *priv; - int retval = 0; + int retval; dbg_printk(2, "%s\n", "Enter ..."); board->status = 0; - if (allocate_private(board)) - return -ENOMEM; + retval = allocate_private(board); + if (retval) + return retval; priv = board->private_data; priv->direction = -1; priv->t1_delay = 2000; diff --git a/drivers/gpib/hp_82335/hp82335.c b/drivers/gpib/hp_82335/hp82335.c index d0e47ef77c87..b7544b3c15c6 100644 --- a/drivers/gpib/hp_82335/hp82335.c +++ b/drivers/gpib/hp_82335/hp82335.c @@ -210,9 +210,9 @@ static struct gpib_interface hp82335_interface = { static int hp82335_allocate_private(struct gpib_board *board) { - board->private_data = kzalloc(sizeof(struct hp82335_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct hp82335_priv); if (!board->private_data) - return -1; + return -ENOMEM; return 0; } @@ -253,8 +253,9 @@ static int hp82335_attach(struct gpib_board *board, const struct gpib_board_conf board->status = 0; - if (hp82335_allocate_private(board)) - return -ENOMEM; + retval = hp82335_allocate_private(board); + if (retval) + return retval; hp_priv = board->private_data; tms_priv = &hp_priv->tms9914_priv; tms_priv->read_byte = hp82335_read_byte; diff --git a/drivers/gpib/hp_82341/hp_82341.c b/drivers/gpib/hp_82341/hp_82341.c index 1a2ad0560e14..46175ba2ac36 100644 --- a/drivers/gpib/hp_82341/hp_82341.c +++ b/drivers/gpib/hp_82341/hp_82341.c @@ -462,7 +462,7 @@ static struct gpib_interface hp_82341_interface = { static int hp_82341_allocate_private(struct gpib_board *board) { - board->private_data = kzalloc(sizeof(struct hp_82341_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct hp_82341_priv); if (!board->private_data) return -ENOMEM; return 0; @@ -693,8 +693,9 @@ static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_con int retval; board->status = 0; - if (hp_82341_allocate_private(board)) - return -ENOMEM; + retval = hp_82341_allocate_private(board); + if (retval) + return retval; hp_priv = board->private_data; tms_priv = &hp_priv->tms9914_priv; tms_priv->read_byte = hp_82341_read_byte; diff --git a/drivers/gpib/ines/ines_gpib.c b/drivers/gpib/ines/ines_gpib.c index a3cf846fd0f9..c000f647fbb5 100644 --- a/drivers/gpib/ines/ines_gpib.c +++ b/drivers/gpib/ines/ines_gpib.c @@ -657,11 +657,10 @@ static int ines_allocate_private(struct gpib_board *board) { struct ines_priv *priv; - board->private_data = kmalloc(sizeof(struct ines_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct ines_priv); if (!board->private_data) - return -1; + return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct ines_priv)); init_nec7210_private(&priv->nec7210_priv); return 0; } @@ -676,11 +675,13 @@ static int ines_generic_attach(struct gpib_board *board) { struct ines_priv *ines_priv; struct nec7210_priv *nec_priv; + int retval; board->status = 0; - if (ines_allocate_private(board)) - return -ENOMEM; + retval = ines_allocate_private(board); + if (retval) + return retval; ines_priv = board->private_data; nec_priv = &ines_priv->nec7210_priv; nec_priv->read_byte = nec7210_ioport_read_byte; @@ -1060,7 +1061,7 @@ static int ines_gpib_probe(struct pcmcia_device *link) // int ret, i; /* Allocate space for private device-specific data */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c b/drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c index dd68c4843490..ee781d2f0b8e 100644 --- a/drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c +++ b/drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c @@ -38,8 +38,10 @@ MODULE_DESCRIPTION("GPIB driver for LPVO usb devices"); /* * Table of devices that work with this driver. * - * Currently, only one device is known to be used in the - * lpvo_usb_gpib adapter (FTDI 0403:6001). + * Currently, only one device is known to be used in the lpvo_usb_gpib + * adapter (FTDI 0403:6001) but as this device id is already handled by the + * ftdi_sio USB serial driver the LPVO driver must not bind to it by default. + * * If your adapter uses a different chip, insert a line * in the following table with proper , . * @@ -50,7 +52,6 @@ MODULE_DESCRIPTION("GPIB driver for LPVO usb devices"); */ static const struct usb_device_id skel_table[] = { - { USB_DEVICE(0x0403, 0x6001) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, skel_table); @@ -440,7 +441,7 @@ static int usb_gpib_attach(struct gpib_board *board, const struct gpib_board_con return -EIO; } - board->private_data = kzalloc(sizeof(struct usb_gpib_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct usb_gpib_priv); if (!board->private_data) return -ENOMEM; @@ -1864,7 +1865,7 @@ static int skel_probe(struct usb_interface *interface, mutex_init(&minors_lock); /* required for handling minor numbers table */ /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/gpib/ni_usb/ni_usb_gpib.c b/drivers/gpib/ni_usb/ni_usb_gpib.c index 1f8412de9fa3..a24cd6521362 100644 --- a/drivers/gpib/ni_usb/ni_usb_gpib.c +++ b/drivers/gpib/ni_usb/ni_usb_gpib.c @@ -566,7 +566,7 @@ static int ni_usb_write_registers(struct ni_usb_priv *ni_priv, retval, bytes_read); ni_usb_dump_raw_block(in_data, bytes_read); kfree(in_data); - return retval; + return retval ?: -EINVAL; } mutex_unlock(&ni_priv->addressed_transfer_lock); @@ -1659,11 +1659,10 @@ static int ni_usb_allocate_private(struct gpib_board *board) { struct ni_usb_priv *ni_priv; - board->private_data = kmalloc(sizeof(struct ni_usb_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct ni_usb_priv); if (!board->private_data) return -ENOMEM; ni_priv = board->private_data; - memset(ni_priv, 0, sizeof(struct ni_usb_priv)); mutex_init(&ni_priv->bulk_transfer_lock); mutex_init(&ni_priv->control_transfer_lock); mutex_init(&ni_priv->interrupt_transfer_lock); @@ -1780,7 +1779,7 @@ static int ni_usb_setup_init(struct gpib_board *board, struct ni_usb_register *w i++; if (i > NUM_INIT_WRITES) { dev_err(&usb_dev->dev, "bug!, buffer overrun, i=%i\n", i); - return 0; + return -EINVAL; } return i; } @@ -1794,15 +1793,17 @@ static int ni_usb_init(struct gpib_board *board) unsigned int ibsta; int writes_len; - writes = kmalloc_array(NUM_INIT_WRITES, sizeof(*writes), GFP_KERNEL); + writes = kmalloc_objs(*writes, NUM_INIT_WRITES); if (!writes) return -ENOMEM; writes_len = ni_usb_setup_init(board, writes); - if (writes_len) - retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); - else - return -EFAULT; + if (writes_len < 0) { + kfree(writes); + return writes_len; + } + + retval = ni_usb_write_registers(ni_priv, writes, writes_len, &ibsta); kfree(writes); if (retval) { dev_err(&usb_dev->dev, "register write failed, retval=%i\n", retval); @@ -2233,7 +2234,7 @@ static int ni_usb_attach(struct gpib_board *board, const struct gpib_board_confi mutex_lock(&ni_usb_hotplug_lock); retval = ni_usb_allocate_private(board); - if (retval < 0) { + if (retval) { mutex_unlock(&ni_usb_hotplug_lock); return retval; } diff --git a/drivers/gpib/pc2/pc2_gpib.c b/drivers/gpib/pc2/pc2_gpib.c index 9f3943d1df66..d7260181925f 100644 --- a/drivers/gpib/pc2/pc2_gpib.c +++ b/drivers/gpib/pc2/pc2_gpib.c @@ -237,11 +237,10 @@ static int allocate_private(struct gpib_board *board) { struct pc2_priv *priv; - board->private_data = kmalloc(sizeof(struct pc2_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct pc2_priv); if (!board->private_data) - return -1; + return -ENOMEM; priv = board->private_data; - memset(priv, 0, sizeof(struct pc2_priv)); init_nec7210_private(&priv->nec7210_priv); return 0; } @@ -257,10 +256,12 @@ static int pc2_generic_attach(struct gpib_board *board, const struct gpib_board_ { struct pc2_priv *pc2_priv; struct nec7210_priv *nec_priv; + int retval; board->status = 0; - if (allocate_private(board)) - return -ENOMEM; + retval = allocate_private(board); + if (retval) + return retval; pc2_priv = board->private_data; nec_priv = &pc2_priv->nec7210_priv; nec_priv->read_byte = nec7210_ioport_read_byte; diff --git a/drivers/gpib/tnt4882/mite.c b/drivers/gpib/tnt4882/mite.c index 847b96f411bd..c75c45cdf03f 100644 --- a/drivers/gpib/tnt4882/mite.c +++ b/drivers/gpib/tnt4882/mite.c @@ -57,7 +57,7 @@ void mite_init(void) for (pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, NULL); pcidev; pcidev = pci_get_device(PCI_VENDOR_ID_NATINST, PCI_ANY_ID, pcidev)) { - mite = kzalloc(sizeof(*mite), GFP_KERNEL); + mite = kzalloc_obj(*mite); if (!mite) return; diff --git a/drivers/gpib/tnt4882/tnt4882_gpib.c b/drivers/gpib/tnt4882/tnt4882_gpib.c index c03a976b7380..51a920e1d9a4 100644 --- a/drivers/gpib/tnt4882/tnt4882_gpib.c +++ b/drivers/gpib/tnt4882/tnt4882_gpib.c @@ -843,11 +843,10 @@ static int tnt4882_allocate_private(struct gpib_board *board) { struct tnt4882_priv *tnt_priv; - board->private_data = kmalloc(sizeof(struct tnt4882_priv), GFP_KERNEL); + board->private_data = kzalloc_obj(struct tnt4882_priv); if (!board->private_data) - return -1; + return -ENOMEM; tnt_priv = board->private_data; - memset(tnt_priv, 0, sizeof(struct tnt4882_priv)); init_nec7210_private(&tnt_priv->nec7210_priv); return 0; } @@ -916,8 +915,9 @@ static int ni_pci_attach(struct gpib_board *board, const struct gpib_board_confi board->status = 0; - if (tnt4882_allocate_private(board)) - return -ENOMEM; + retval = tnt4882_allocate_private(board); + if (retval) + return retval; tnt_priv = board->private_data; nec_priv = &tnt_priv->nec7210_priv; nec_priv->type = TNT4882; @@ -1039,8 +1039,9 @@ static int ni_isa_attach_common(struct gpib_board *board, const struct gpib_boar board->status = 0; - if (tnt4882_allocate_private(board)) - return -ENOMEM; + retval = tnt4882_allocate_private(board); + if (retval) + return retval; tnt_priv = board->private_data; nec_priv = &tnt_priv->nec7210_priv; nec_priv->type = chipset; @@ -1566,7 +1567,7 @@ static int ni_gpib_probe(struct pcmcia_device *link) //struct struct gpib_board *dev; /* Allocate space for private device-specific data */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -1725,8 +1726,9 @@ static int ni_pcmcia_attach(struct gpib_board *board, const struct gpib_board_co board->status = 0; - if (tnt4882_allocate_private(board)) - return -ENOMEM; + retval = tnt4882_allocate_private(board); + if (retval) + return retval; tnt_priv = board->private_data; nec_priv = &tnt_priv->nec7210_priv; diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c index a4cd32674a96..9adf3228c12a 100644 --- a/drivers/gpio/gpio-aggregator.c +++ b/drivers/gpio/gpio-aggregator.c @@ -159,7 +159,7 @@ gpio_aggregator_line_alloc(struct gpio_aggregator *parent, unsigned int idx, { struct gpio_aggregator_line *line; - line = kzalloc(sizeof(*line), GFP_KERNEL); + line = kzalloc_obj(*line); if (!line) return ERR_PTR(-ENOMEM); @@ -916,8 +916,7 @@ static int gpio_aggregator_activate(struct gpio_aggregator *aggr) if (gpio_aggregator_count_lines(aggr) == 0) return -EINVAL; - aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), - GFP_KERNEL); + aggr->lookups = kzalloc_flex(*aggr->lookups, table, 1); if (!aggr->lookups) return -ENOMEM; @@ -1457,8 +1456,7 @@ static ssize_t gpio_aggregator_new_device_store(struct device_driver *driver, memcpy(aggr->args, buf, count + 1); aggr->init_via_sysfs = true; - aggr->lookups = kzalloc(struct_size(aggr->lookups, table, 1), - GFP_KERNEL); + aggr->lookups = kzalloc_flex(*aggr->lookups, table, 1); if (!aggr->lookups) { res = -ENOMEM; goto free_ga; diff --git a/drivers/gpio/gpio-amd-fch.c b/drivers/gpio/gpio-amd-fch.c index e6c6c3ec7656..9f329938202b 100644 --- a/drivers/gpio/gpio-amd-fch.c +++ b/drivers/gpio/gpio-amd-fch.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include @@ -120,15 +121,15 @@ static int amd_fch_gpio_get(struct gpio_chip *gc, unsigned int offset) { unsigned long flags; - int ret; + u32 val; struct amd_fch_gpio_priv *priv = gpiochip_get_data(gc); void __iomem *ptr = amd_fch_gpio_addr(priv, offset); spin_lock_irqsave(&priv->lock, flags); - ret = (readl_relaxed(ptr) & AMD_FCH_GPIO_FLAG_READ); + val = readl_relaxed(ptr); spin_unlock_irqrestore(&priv->lock, flags); - return ret; + return FIELD_GET(AMD_FCH_GPIO_FLAG_READ, val); } static int amd_fch_gpio_request(struct gpio_chip *chip, diff --git a/drivers/gpio/gpio-nomadik.c b/drivers/gpio/gpio-nomadik.c index 97c5cd33279d..e22b713166d7 100644 --- a/drivers/gpio/gpio-nomadik.c +++ b/drivers/gpio/gpio-nomadik.c @@ -430,6 +430,9 @@ void nmk_gpio_dbg_show_one(struct seq_file *s, struct pinctrl_dev *pctldev, #ifdef CONFIG_PINCTRL_NOMADIK if (mode == NMK_GPIO_ALT_C && pctldev) { desc = gpio_device_get_desc(chip->gpiodev, offset); + if (IS_ERR(desc)) + return; + mode = nmk_prcm_gpiocr_get_mode(pctldev, desc_to_gpio(desc)); } #endif diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c index f2238196faf1..296c210b228c 100644 --- a/drivers/gpio/gpio-reg.c +++ b/drivers/gpio/gpio-reg.c @@ -150,7 +150,7 @@ struct gpio_chip *gpio_reg_init(struct device *dev, void __iomem *reg, if (dev) r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL); else - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index 9581bd5ca947..9ae4a41a2427 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c @@ -259,7 +259,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config if (config->reg_dir_out_base && config->reg_dir_in_base) return ERR_PTR(-EINVAL); - gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); + gpio = kzalloc_obj(*gpio); if (!gpio) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c index 437b4500f56b..13b87c8e6d0c 100644 --- a/drivers/gpio/gpio-sim.c +++ b/drivers/gpio/gpio-sim.c @@ -813,7 +813,7 @@ static int gpio_sim_add_hogs(struct gpio_sim_device *dev) return 0; /* Allocate one more for the sentinel. */ - dev->hogs = kcalloc(num_hogs + 1, sizeof(*dev->hogs), GFP_KERNEL); + dev->hogs = kzalloc_objs(*dev->hogs, num_hogs + 1); if (!dev->hogs) return -ENOMEM; @@ -1406,7 +1406,7 @@ gpio_sim_line_config_make_hog_item(struct config_group *group, const char *name) guard(mutex)(&dev->lock); - hog = kzalloc(sizeof(*hog), GFP_KERNEL); + hog = kzalloc_obj(*hog); if (!hog) return ERR_PTR(-ENOMEM); @@ -1467,7 +1467,7 @@ gpio_sim_bank_config_make_line_group(struct config_group *group, if (gpio_sim_device_is_live(dev)) return ERR_PTR(-EBUSY); - line = kzalloc(sizeof(*line), GFP_KERNEL); + line = kzalloc_obj(*line); if (!line) return ERR_PTR(-ENOMEM); @@ -1521,7 +1521,7 @@ gpio_sim_device_config_make_bank_group(struct config_group *group, if (gpio_sim_device_is_live(dev)) return ERR_PTR(-EBUSY); - bank = kzalloc(sizeof(*bank), GFP_KERNEL); + bank = kzalloc_obj(*bank); if (!bank) return ERR_PTR(-ENOMEM); @@ -1569,8 +1569,7 @@ gpio_sim_config_make_device_group(struct config_group *group, const char *name) { int id; - struct gpio_sim_device *dev __free(kfree) = kzalloc(sizeof(*dev), - GFP_KERNEL); + struct gpio_sim_device *dev __free(kfree) = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpio/gpio-virtuser.c b/drivers/gpio/gpio-virtuser.c index b6c515e7a876..955b5efc283e 100644 --- a/drivers/gpio/gpio-virtuser.c +++ b/drivers/gpio/gpio-virtuser.c @@ -1388,7 +1388,7 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev) lockdep_assert_held(&dev->lock); struct gpiod_lookup_table *table __free(kfree) = - kzalloc(struct_size(table, table, num_entries + 1), GFP_KERNEL); + kzalloc_flex(*table, table, num_entries + 1); if (!table) return -ENOMEM; @@ -1605,7 +1605,7 @@ gpio_virtuser_make_lookup_entry_group(struct config_group *group, return ERR_PTR(-EBUSY); struct gpio_virtuser_lookup_entry *entry __free(kfree) = - kzalloc(sizeof(*entry), GFP_KERNEL); + kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -1661,7 +1661,7 @@ gpio_virtuser_make_lookup_group(struct config_group *group, const char *name) return ERR_PTR(-EBUSY); struct gpio_virtuser_lookup *lookup __free(kfree) = - kzalloc(sizeof(*lookup), GFP_KERNEL); + kzalloc_obj(*lookup); if (!lookup) return ERR_PTR(-ENOMEM); @@ -1711,8 +1711,7 @@ static struct config_group * gpio_virtuser_config_make_device_group(struct config_group *group, const char *name) { - struct gpio_virtuser_device *dev __free(kfree) = kzalloc(sizeof(*dev), - GFP_KERNEL); + struct gpio_virtuser_device *dev __free(kfree) = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpio/gpiolib-acpi-core.c b/drivers/gpio/gpiolib-acpi-core.c index 5e709ba35ec2..ced6375d1bad 100644 --- a/drivers/gpio/gpiolib-acpi-core.c +++ b/drivers/gpio/gpiolib-acpi-core.c @@ -403,7 +403,7 @@ static acpi_status acpi_gpiochip_alloc_event(struct acpi_resource *ares, goto fail_unlock_irq; } - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) goto fail_unlock_irq; @@ -1144,7 +1144,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address, goto out; } - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) { gpiochip_free_own_desc(desc); mutex_unlock(&achip->conn_lock); @@ -1302,7 +1302,7 @@ void acpi_gpiochip_add(struct gpio_chip *chip) if (!adev) return; - acpi_gpio = kzalloc(sizeof(*acpi_gpio), GFP_KERNEL); + acpi_gpio = kzalloc_obj(*acpi_gpio); if (!acpi_gpio) { dev_err(chip->parent, "Failed to allocate memory for ACPI GPIO chip\n"); diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 2adc3c070908..73ae77f0f213 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -318,7 +318,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) if (ret) return ret; - lh = kzalloc(sizeof(*lh), GFP_KERNEL); + lh = kzalloc_obj(*lh); if (!lh) return -ENOMEM; lh->gdev = gpio_device_get(gdev); @@ -388,7 +388,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) fd_publish(fdf); dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n", - lh->num_descs); + handlereq.lines); return 0; } @@ -1280,7 +1280,7 @@ static long linereq_get_values(struct linereq *lr, void __user *ip) if (num_get != 1) { /* build compacted desc array */ - descs = kmalloc_array(num_get, sizeof(*descs), GFP_KERNEL); + descs = kmalloc_objs(*descs, num_get); if (!descs) return -ENOMEM; for (didx = 0, i = 0; i < lr->num_lines; i++) { @@ -1355,7 +1355,7 @@ static long linereq_set_values(struct linereq *lr, void __user *ip) if (num_set != 1) { /* build compacted desc array */ - descs = kmalloc_array(num_set, sizeof(*descs), GFP_KERNEL); + descs = kmalloc_objs(*descs, num_set); if (!descs) return -ENOMEM; for (didx = 0, i = 0; i < lr->num_lines; i++) { @@ -1610,7 +1610,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip) if (ret) return ret; - lr = kvzalloc(struct_size(lr, lines, ulr.num_lines), GFP_KERNEL); + lr = kvzalloc_flex(*lr, lines, ulr.num_lines); if (!lr) return -ENOMEM; lr->num_lines = ulr.num_lines; @@ -2054,7 +2054,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) (lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP))) return -EINVAL; - le = kzalloc(sizeof(*le), GFP_KERNEL); + le = kzalloc_obj(*le); if (!le) return -ENOMEM; le->gdev = gpio_device_get(gdev); @@ -2546,7 +2546,7 @@ static int lineinfo_changed_notify(struct notifier_block *nb, * is executed. */ - ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); + ctx = kzalloc_obj(*ctx, GFP_ATOMIC); if (!ctx) { pr_err("Failed to allocate memory for line info notification\n"); fput(fp); diff --git a/drivers/gpio/gpiolib-shared.c b/drivers/gpio/gpiolib-shared.c index b3525d1f06a4..17a7128b6bd9 100644 --- a/drivers/gpio/gpiolib-shared.c +++ b/drivers/gpio/gpiolib-shared.c @@ -84,7 +84,7 @@ static struct gpio_shared_ref *gpio_shared_make_ref(struct fwnode_handle *fwnode { char *con_id_cpy __free(kfree) = NULL; - struct gpio_shared_ref *ref __free(kfree) = kzalloc(sizeof(*ref), GFP_KERNEL); + struct gpio_shared_ref *ref __free(kfree) = kzalloc_obj(*ref); if (!ref) return NULL; @@ -227,7 +227,7 @@ static int gpio_shared_of_traverse(struct device_node *curr) entry = gpio_shared_find_entry(fwnode, offset); if (!entry) { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -477,7 +477,7 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id, if (!key) return -ENOMEM; - lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + lookup = kzalloc_flex(*lookup, table, 2); if (!lookup) return -ENOMEM; @@ -626,7 +626,7 @@ gpiod_shared_desc_create(struct gpio_shared_entry *entry) lockdep_assert_held(&entry->lock); - shared_desc = kzalloc(sizeof(*shared_desc), GFP_KERNEL); + shared_desc = kzalloc_obj(*shared_desc); if (!shared_desc) return ERR_PTR(-ENOMEM); @@ -748,14 +748,14 @@ static bool gpio_shared_entry_is_really_shared(struct gpio_shared_entry *entry) static void gpio_shared_free_exclusive(void) { struct gpio_shared_entry *entry, *epos; + struct gpio_shared_ref *ref, *rpos; list_for_each_entry_safe(entry, epos, &gpio_shared_list, list) { if (gpio_shared_entry_is_really_shared(entry)) continue; - gpio_shared_drop_ref(list_first_entry(&entry->refs, - struct gpio_shared_ref, - list)); + list_for_each_entry_safe(ref, rpos, &entry->refs, list) + gpio_shared_drop_ref(ref); gpio_shared_drop_entry(entry); } } diff --git a/drivers/gpio/gpiolib-swnode.c b/drivers/gpio/gpiolib-swnode.c index 21478b45c127..0d7f3f09a0b4 100644 --- a/drivers/gpio/gpiolib-swnode.c +++ b/drivers/gpio/gpiolib-swnode.c @@ -42,6 +42,25 @@ static struct gpio_device *swnode_get_gpio_device(struct fwnode_handle *fwnode) fwnode_lookup: gdev = gpio_device_find_by_fwnode(fwnode); + if (!gdev && gdev_node && gdev_node->name) + /* + * FIXME: We shouldn't need to compare the GPIO controller's + * label against the software node that is supposedly attached + * to it. However there are currently GPIO users that - knowing + * the expected label of the GPIO chip whose pins they want to + * control - set up dummy software nodes named after those GPIO + * controllers, which aren't actually attached to them. In this + * case gpio_device_find_by_fwnode() will fail as no device on + * the GPIO bus is actually associated with the fwnode we're + * looking for. + * + * As a fallback: continue checking the label if we have no + * match. However, the situation described above is an abuse + * of the software node API and should be phased out and the + * following line - eventually removed. + */ + gdev = gpio_device_find_by_label(gdev_node->name); + return gdev ?: ERR_PTR(-EPROBE_DEFER); } diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index cd553acf3055..270e8060e761 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -761,7 +761,7 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change) goto err_clear_bit; } - desc_data = kzalloc(sizeof(*desc_data), GFP_KERNEL); + desc_data = kzalloc_obj(*desc_data); if (!desc_data) { status = -ENOMEM; goto err_clear_bit; @@ -919,6 +919,51 @@ int gpiod_export_link(struct device *dev, const char *name, } EXPORT_SYMBOL_GPL(gpiod_export_link); +static void gpiod_unexport_unlocked(struct gpio_desc *desc) +{ + struct gpiod_data *tmp, *desc_data = NULL; + struct gpiodev_data *gdev_data; + struct gpio_device *gdev; + + if (!test_bit(GPIOD_FLAG_EXPORT, &desc->flags)) + return; + + gdev = gpiod_to_gpio_device(desc); + gdev_data = gdev_get_data(gdev); + if (!gdev_data) + return; + + list_for_each_entry(tmp, &gdev_data->exported_lines, list) { + if (gpiod_is_equal(desc, tmp->desc)) { + desc_data = tmp; + break; + } + } + + if (!desc_data) + return; + + list_del(&desc_data->list); + clear_bit(GPIOD_FLAG_EXPORT, &desc->flags); +#if IS_ENABLED(CONFIG_GPIO_SYSFS_LEGACY) + sysfs_put(desc_data->value_kn); + device_unregister(desc_data->dev); + + /* + * Release irq after deregistration to prevent race with + * edge_store. + */ + if (desc_data->irq_flags) + gpio_sysfs_free_irq(desc_data); +#endif /* CONFIG_GPIO_SYSFS_LEGACY */ + + sysfs_remove_groups(desc_data->parent, + desc_data->chip_attr_groups); + + mutex_destroy(&desc_data->mutex); + kfree(desc_data); +} + /** * gpiod_unexport - reverse effect of gpiod_export() * @desc: GPIO to make unavailable @@ -927,54 +972,14 @@ EXPORT_SYMBOL_GPL(gpiod_export_link); */ void gpiod_unexport(struct gpio_desc *desc) { - struct gpiod_data *tmp, *desc_data = NULL; - struct gpiodev_data *gdev_data; - struct gpio_device *gdev; - if (!desc) { pr_warn("%s: invalid GPIO\n", __func__); return; } - scoped_guard(mutex, &sysfs_lock) { - if (!test_bit(GPIOD_FLAG_EXPORT, &desc->flags)) - return; + guard(mutex)(&sysfs_lock); - gdev = gpiod_to_gpio_device(desc); - gdev_data = gdev_get_data(gdev); - if (!gdev_data) - return; - - list_for_each_entry(tmp, &gdev_data->exported_lines, list) { - if (gpiod_is_equal(desc, tmp->desc)) { - desc_data = tmp; - break; - } - } - - if (!desc_data) - return; - - list_del(&desc_data->list); - clear_bit(GPIOD_FLAG_EXPORT, &desc->flags); -#if IS_ENABLED(CONFIG_GPIO_SYSFS_LEGACY) - sysfs_put(desc_data->value_kn); - device_unregister(desc_data->dev); - - /* - * Release irq after deregistration to prevent race with - * edge_store. - */ - if (desc_data->irq_flags) - gpio_sysfs_free_irq(desc_data); -#endif /* CONFIG_GPIO_SYSFS_LEGACY */ - - sysfs_remove_groups(desc_data->parent, - desc_data->chip_attr_groups); - } - - mutex_destroy(&desc_data->mutex); - kfree(desc_data); + gpiod_unexport_unlocked(desc); } EXPORT_SYMBOL_GPL(gpiod_unexport); @@ -1009,7 +1014,7 @@ int gpiochip_sysfs_register(struct gpio_device *gdev) else parent = &gdev->dev; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; @@ -1054,29 +1059,28 @@ void gpiochip_sysfs_unregister(struct gpio_device *gdev) struct gpio_desc *desc; struct gpio_chip *chip; - scoped_guard(mutex, &sysfs_lock) { - data = gdev_get_data(gdev); - if (!data) - return; + guard(mutex)(&sysfs_lock); -#if IS_ENABLED(CONFIG_GPIO_SYSFS_LEGACY) - device_unregister(data->cdev_base); -#endif /* CONFIG_GPIO_SYSFS_LEGACY */ - device_unregister(data->cdev_id); - kfree(data); - } + data = gdev_get_data(gdev); + if (!data) + return; guard(srcu)(&gdev->srcu); - chip = srcu_dereference(gdev->chip, &gdev->srcu); if (!chip) return; /* unregister gpiod class devices owned by sysfs */ for_each_gpio_desc_with_flag(chip, desc, GPIOD_FLAG_SYSFS) { - gpiod_unexport(desc); + gpiod_unexport_unlocked(desc); gpiod_free(desc); } + +#if IS_ENABLED(CONFIG_GPIO_SYSFS_LEGACY) + device_unregister(data->cdev_base); +#endif /* CONFIG_GPIO_SYSFS_LEGACY */ + device_unregister(data->cdev_id); + kfree(data); } /* diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c52200eaaaff..ada572aaebd6 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -147,8 +147,7 @@ static int desc_set_label(struct gpio_desc *desc, const char *label) struct gpio_desc_label *new = NULL, *old; if (label) { - new = kzalloc(struct_size(new, str, strlen(label) + 1), - GFP_KERNEL); + new = kzalloc_flex(*new, str, strlen(label) + 1); if (!new) return -ENOMEM; @@ -2333,7 +2332,7 @@ int gpiochip_add_pingroup_range(struct gpio_chip *gc, struct gpio_device *gdev = gc->gpiodev; int ret; - pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); + pin_range = kzalloc_obj(*pin_range); if (!pin_range) return -ENOMEM; @@ -2394,7 +2393,7 @@ int gpiochip_add_pin_range_with_pins(struct gpio_chip *gc, struct gpio_device *gdev = gc->gpiodev; int ret; - pin_range = kzalloc(sizeof(*pin_range), GFP_KERNEL); + pin_range = kzalloc_obj(*pin_range); if (!pin_range) return -ENOMEM; @@ -3268,8 +3267,12 @@ static int gpiochip_get(struct gpio_chip *gc, unsigned int offset) /* Make sure this is called after checking for gc->get(). */ ret = gc->get(gc, offset); - if (ret > 1) - ret = -EBADE; + if (ret > 1) { + gpiochip_warn(gc, + "invalid return value from gc->get(): %d, consider fixing the driver\n", + ret); + ret = !!ret; + } return ret; } @@ -5370,7 +5373,7 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) s->private = NULL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/aldebaran.c b/drivers/gpu/drm/amd/amdgpu/aldebaran.c index daa7b23bc775..938fb0b2368d 100644 --- a/drivers/gpu/drm/amd/amdgpu/aldebaran.c +++ b/drivers/gpu/drm/amd/amdgpu/aldebaran.c @@ -447,7 +447,7 @@ int aldebaran_reset_init(struct amdgpu_device *adev) { struct amdgpu_reset_control *reset_ctl; - reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL); + reset_ctl = kzalloc_obj(*reset_ctl); if (!reset_ctl) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c index 9b3180449150..db7858fe0c3d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_aca.c @@ -52,7 +52,7 @@ static int aca_banks_add_bank(struct aca_banks *banks, struct aca_bank *bank) if (!bank) return -EINVAL; - node = kvzalloc(sizeof(*node), GFP_KERNEL); + node = kvzalloc_obj(*node); if (!node) return -ENOMEM; @@ -230,7 +230,7 @@ static struct aca_bank_error *new_bank_error(struct aca_error *aerr, struct aca_ { struct aca_bank_error *bank_error; - bank_error = kvzalloc(sizeof(*bank_error), GFP_KERNEL); + bank_error = kvzalloc_obj(*bank_error); if (!bank_error) return NULL; @@ -641,6 +641,7 @@ static void aca_error_fini(struct aca_error *aerr) aca_bank_error_remove(aerr, bank_error); out_unlock: + mutex_unlock(&aerr->lock); mutex_destroy(&aerr->lock); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index 381ef205b0df..62807b65f2af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c @@ -246,7 +246,7 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block) return -EINVAL; acp_base = adev->rmmio_base; - adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); + adev->acp.acp_genpd = kzalloc_obj(struct acp_pm_domain); if (!adev->acp.acp_genpd) return -ENOMEM; @@ -260,20 +260,19 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block) switch (acp_machine_id) { case ST_JADEITE: { - adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell), - GFP_KERNEL); + adev->acp.acp_cell = kzalloc_objs(struct mfd_cell, 2); if (!adev->acp.acp_cell) { r = -ENOMEM; goto failure; } - adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL); + adev->acp.acp_res = kzalloc_objs(struct resource, 3); if (!adev->acp.acp_res) { r = -ENOMEM; goto failure; } - i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL); + i2s_pdata = kzalloc_objs(struct i2s_platform_data, 1); if (!i2s_pdata) { r = -ENOMEM; goto failure; @@ -324,21 +323,20 @@ static int acp_hw_init(struct amdgpu_ip_block *ip_block) break; } default: - adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell), - GFP_KERNEL); + adev->acp.acp_cell = kzalloc_objs(struct mfd_cell, ACP_DEVS); if (!adev->acp.acp_cell) { r = -ENOMEM; goto failure; } - adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL); + adev->acp.acp_res = kzalloc_objs(struct resource, 5); if (!adev->acp.acp_res) { r = -ENOMEM; goto failure; } - i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL); + i2s_pdata = kzalloc_objs(struct i2s_platform_data, 3); if (!i2s_pdata) { r = -ENOMEM; goto failure; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c index c126d1bf2bc8..516ab9cf88fc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c @@ -897,7 +897,7 @@ static struct amdgpu_numa_info *amdgpu_acpi_get_numa_info(uint32_t pxm) if (!numa_info) { struct sysinfo info; - numa_info = kzalloc(sizeof(*numa_info), GFP_KERNEL); + numa_info = kzalloc_obj(*numa_info); if (!numa_info) return NULL; @@ -1016,7 +1016,7 @@ static int amdgpu_acpi_dev_init(struct amdgpu_acpi_dev_info **dev_info, int ret = -ENOENT; *dev_info = NULL; - tmp = kzalloc(sizeof(struct amdgpu_acpi_dev_info), GFP_KERNEL); + tmp = kzalloc_obj(struct amdgpu_acpi_dev_info); if (!tmp) return -ENOMEM; @@ -1166,8 +1166,7 @@ int amdgpu_acpi_enumerate_xcc(void) break; } - xcc_info = kzalloc(sizeof(struct amdgpu_acpi_xcc_info), - GFP_KERNEL); + xcc_info = kzalloc_obj(struct amdgpu_acpi_xcc_info); if (!xcc_info) return -ENOMEM; @@ -1186,8 +1185,10 @@ int amdgpu_acpi_enumerate_xcc(void) if (!dev_info) ret = amdgpu_acpi_dev_init(&dev_info, xcc_info, sbdf); - if (ret == -ENOMEM) + if (ret == -ENOMEM) { + kfree(xcc_info); return ret; + } if (!dev_info) { kfree(xcc_info); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c index 877d0df50376..40c22438b1d2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c @@ -317,8 +317,7 @@ int amdgpu_amdkfd_post_reset(struct amdgpu_device *adev) void amdgpu_amdkfd_gpu_reset(struct amdgpu_device *adev) { if (amdgpu_device_should_recover_gpu(adev)) - amdgpu_reset_domain_schedule(adev->reset_domain, - &adev->kfd.reset_work); + (void)amdgpu_reset_domain_schedule(adev->reset_domain, &adev->kfd.reset_work); } int amdgpu_amdkfd_alloc_kernel_mem(struct amdgpu_device *adev, size_t size, @@ -720,9 +719,8 @@ void amdgpu_amdkfd_set_compute_idle(struct amdgpu_device *adev, bool idle) if (gfx_block != NULL) gfx_block->version->funcs->set_powergating_state((void *)gfx_block, state); } - amdgpu_dpm_switch_power_profile(adev, - PP_SMC_POWER_PROFILE_COMPUTE, - !idle); + (void)amdgpu_dpm_switch_power_profile(adev, PP_SMC_POWER_PROFILE_COMPUTE, !idle); + } bool amdgpu_amdkfd_is_kfd_vmid(struct amdgpu_device *adev, u32 vmid) @@ -831,11 +829,11 @@ int amdgpu_amdkfd_unmap_hiq(struct amdgpu_device *adev, u32 doorbell_off, if (!kiq_ring->sched.ready || amdgpu_in_reset(adev)) return 0; - ring_funcs = kzalloc(sizeof(*ring_funcs), GFP_KERNEL); + ring_funcs = kzalloc_obj(*ring_funcs); if (!ring_funcs) return -ENOMEM; - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) { r = -ENOMEM; goto free_ring_funcs; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 1105a09e55dc..a1d93f217844 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -199,7 +199,7 @@ int kgd_arcturus_hqd_sdma_dump(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+6+7+10) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c index 193ed8becab8..6a364357522b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_fence.c @@ -67,7 +67,7 @@ struct amdgpu_amdkfd_fence *amdgpu_amdkfd_fence_create(u64 context, { struct amdgpu_amdkfd_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (fence == NULL) return NULL; @@ -107,7 +107,7 @@ static const char *amdkfd_fence_get_timeline_name(struct dma_fence *f) { struct amdgpu_amdkfd_fence *fence = to_amdgpu_amdkfd_fence(f); - return fence->timeline_name; + return fence ? fence->timeline_name : NULL; } /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c index 89a45a9218f3..f35947be3763 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gc_9_4_3.c @@ -141,7 +141,7 @@ static int kgd_gfx_v9_4_3_hqd_sdma_dump(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c index 0239114fb6c4..88acf75f0edd 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10.c @@ -352,7 +352,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32_SOC15_IP(GC, addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -449,7 +449,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+6+7+10) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c index f2278a0937ff..e31afee42979 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v10_3.c @@ -338,7 +338,7 @@ static int hqd_dump_v10_3(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32_SOC15_IP(GC, addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -435,7 +435,7 @@ static int hqd_sdma_dump_v10_3(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+6+7+12) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c index aaccf0b9947d..8aa068a4d3e3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v11.c @@ -323,7 +323,7 @@ static int hqd_dump_v11(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -420,7 +420,7 @@ static int hqd_sdma_dump_v11(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (7+11+1+12+12) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c index e0ceab400b2d..bf0bd7688ee4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v12.c @@ -115,7 +115,7 @@ static int hqd_dump_v12(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -146,7 +146,7 @@ static int hqd_sdma_dump_v12(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (last_reg - first_reg + 1) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c index df77558e03ef..2f62e5e306e8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c @@ -214,7 +214,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -301,7 +301,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+4) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c index e68c0fa8d751..dc74fa26cf02 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c @@ -238,7 +238,7 @@ static int kgd_hqd_dump(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -324,7 +324,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+4+2+3+7) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c index 088d09cc7a72..2e116c06d5be 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c @@ -363,7 +363,7 @@ int kgd_gfx_v9_hqd_dump(struct amdgpu_device *adev, (*dump)[i++][1] = RREG32(addr); \ } while (0) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; @@ -460,7 +460,7 @@ static int kgd_hqd_sdma_dump(struct amdgpu_device *adev, #undef HQD_N_REGS #define HQD_N_REGS (19+6+7+10) - *dump = kmalloc_array(HQD_N_REGS, sizeof(**dump), GFP_KERNEL); + *dump = kmalloc_objs(**dump, HQD_N_REGS); if (*dump == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c index 4ce93536eeda..29b400cdd6d5 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c @@ -540,7 +540,7 @@ static uint64_t get_pte_flags(struct amdgpu_device *adev, struct amdgpu_vm *vm, */ static struct sg_table *create_sg_table(uint64_t addr, uint32_t size) { - struct sg_table *sg = kmalloc(sizeof(*sg), GFP_KERNEL); + struct sg_table *sg = kmalloc_obj(*sg); if (!sg) return NULL; @@ -573,7 +573,7 @@ kfd_mem_dmamap_userptr(struct kgd_mem *mem, if (WARN_ON(ttm->num_pages != src_ttm->num_pages)) return -EINVAL; - ttm->sg = kmalloc(sizeof(*ttm->sg), GFP_KERNEL); + ttm->sg = kmalloc_obj(*ttm->sg); if (unlikely(!ttm->sg)) return -ENOMEM; @@ -878,6 +878,7 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, struct amdgpu_bo *bo[2] = {NULL, NULL}; struct amdgpu_bo_va *bo_va; bool same_hive = false; + struct drm_exec exec; int i, ret; if (!va) { @@ -958,19 +959,25 @@ static int kfd_mem_attach(struct amdgpu_device *adev, struct kgd_mem *mem, goto unwind; } - /* Add BO to VM internal data structures */ - ret = amdgpu_bo_reserve(bo[i], false); - if (ret) { - pr_debug("Unable to reserve BO during memory attach"); - goto unwind; + drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); + drm_exec_until_all_locked(&exec) { + ret = amdgpu_vm_lock_pd(vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(ret)) + goto unwind; + ret = drm_exec_lock_obj(&exec, &bo[i]->tbo.base); + drm_exec_retry_on_contention(&exec); + if (unlikely(ret)) + goto unwind; } + bo_va = amdgpu_vm_bo_find(vm, bo[i]); if (!bo_va) bo_va = amdgpu_vm_bo_add(adev, vm, bo[i]); else ++bo_va->ref_count; attachment[i]->bo_va = bo_va; - amdgpu_bo_unreserve(bo[i]); + drm_exec_fini(&exec); if (unlikely(!attachment[i]->bo_va)) { ret = -ENOMEM; pr_err("Failed to add BO object to VM. ret == %d\n", @@ -1402,7 +1409,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, process = container_of(process_info, struct kfd_process, kgd_process_info); if (!*process_info) { - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -1432,7 +1439,10 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, *process_info = info; } - vm->process_info = *process_info; + if (cmpxchg(&vm->process_info, NULL, *process_info) != NULL) { + ret = -EINVAL; + goto already_acquired; + } /* Validate page directory and attach eviction fence */ ret = amdgpu_bo_reserve(vm->root.bo, true); @@ -1472,6 +1482,7 @@ static int init_kfd_vm(struct amdgpu_vm *vm, void **process_info, amdgpu_bo_unreserve(vm->root.bo); reserve_pd_fail: vm->process_info = NULL; +already_acquired: if (info) { dma_fence_put(&info->eviction_fence->base); *process_info = NULL; @@ -1766,7 +1777,7 @@ int amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu( if (flags & KFD_IOC_ALLOC_MEM_FLAGS_UNCACHED) alloc_flags |= AMDGPU_GEM_CREATE_UNCACHED; - *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); + *mem = kzalloc_obj(struct kgd_mem); if (!*mem) { ret = -ENOMEM; goto err; @@ -2367,7 +2378,7 @@ static int import_obj_create(struct amdgpu_device *adev, /* Only VRAM and GTT BOs are supported */ return -EINVAL; - *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); + *mem = kzalloc_obj(struct kgd_mem); if (!*mem) return -ENOMEM; @@ -3122,7 +3133,7 @@ int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem if (!info || !gws) return -EINVAL; - *mem = kzalloc(sizeof(struct kgd_mem), GFP_KERNEL); + *mem = kzalloc_obj(struct kgd_mem); if (!*mem) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c index 763f2b8dcf13..9f38b7dd1011 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atombios.c @@ -1897,7 +1897,7 @@ void amdgpu_atombios_fini(struct amdgpu_device *adev) int amdgpu_atombios_init(struct amdgpu_device *adev) { struct card_info *atom_card_info = - kzalloc(sizeof(struct card_info), GFP_KERNEL); + kzalloc_obj(struct card_info); if (!atom_card_info) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index 87ec46c56a6e..4662bfbe70b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -76,7 +76,7 @@ int amdgpu_bo_list_create(struct amdgpu_device *adev, struct drm_file *filp, unsigned i; int r; - list = kvzalloc(struct_size(list, entries, num_entries), GFP_KERNEL); + list = kvzalloc_flex(*list, entries, num_entries); if (!list) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 09c8942c22d3..babd23e5a27e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -399,8 +399,7 @@ static const struct cgs_ops amdgpu_cgs_ops = { struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) { - struct amdgpu_cgs_device *cgs_device = - kmalloc(sizeof(*cgs_device), GFP_KERNEL); + struct amdgpu_cgs_device *cgs_device = kmalloc_obj(*cgs_device); if (!cgs_device) { drm_err(adev_to_drm(adev), "Couldn't allocate CGS device structure\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c index d3e312bda4ed..d1bf2e150c1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c @@ -1652,7 +1652,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, } } - amdgpu_connector = kzalloc(sizeof(struct amdgpu_connector), GFP_KERNEL); + amdgpu_connector = kzalloc_obj(struct amdgpu_connector); if (!amdgpu_connector) return; @@ -1673,7 +1673,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, } if (is_dp_bridge) { - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; @@ -1828,7 +1828,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; @@ -1885,7 +1885,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, break; case DRM_MODE_CONNECTOR_HDMIA: case DRM_MODE_CONNECTOR_HDMIB: - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; @@ -1934,7 +1934,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_DisplayPort: - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; @@ -1983,7 +1983,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_eDP: - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; @@ -2010,7 +2010,7 @@ amdgpu_connector_add(struct amdgpu_device *adev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_LVDS: - amdgpu_dig_connector = kzalloc(sizeof(struct amdgpu_connector_atom_dig), GFP_KERNEL); + amdgpu_dig_connector = kzalloc_obj(struct amdgpu_connector_atom_dig); if (!amdgpu_dig_connector) goto failed; amdgpu_connector->con_priv = amdgpu_dig_connector; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index d591dce0f3b3..24e4b4fc9156 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c @@ -192,8 +192,7 @@ static int amdgpu_cs_pass1(struct amdgpu_cs_parser *p, return PTR_ERR(chunk_array); p->nchunks = cs->in.num_chunks; - p->chunks = kvmalloc_array(p->nchunks, sizeof(struct amdgpu_cs_chunk), - GFP_KERNEL); + p->chunks = kvmalloc_objs(struct amdgpu_cs_chunk, p->nchunks); if (!p->chunks) { ret = -ENOMEM; goto free_chunk; @@ -523,8 +522,7 @@ static int amdgpu_cs_p2_syncobj_out(struct amdgpu_cs_parser *p, if (p->post_deps) return -EINVAL; - p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), - GFP_KERNEL); + p->post_deps = kmalloc_objs(*p->post_deps, num_deps); p->num_post_deps = 0; if (!p->post_deps) @@ -557,8 +555,7 @@ static int amdgpu_cs_p2_syncobj_timeline_signal(struct amdgpu_cs_parser *p, if (p->post_deps) return -EINVAL; - p->post_deps = kmalloc_array(num_deps, sizeof(*p->post_deps), - GFP_KERNEL); + p->post_deps = kmalloc_objs(*p->post_deps, num_deps); p->num_post_deps = 0; if (!p->post_deps) @@ -892,8 +889,10 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, struct amdgpu_bo *bo = e->bo; e->range = amdgpu_hmm_range_alloc(NULL); - if (unlikely(!e->range)) - return -ENOMEM; + if (unlikely(!e->range)) { + r = -ENOMEM; + goto out_free_user_pages; + } r = amdgpu_ttm_tt_get_user_pages(bo, e->range); if (r) @@ -1689,7 +1688,7 @@ static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev, long r; /* Prepare the fence array */ - array = kcalloc(fence_count, sizeof(struct dma_fence *), GFP_KERNEL); + array = kzalloc_objs(struct dma_fence *, fence_count); if (array == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 5c344665b43c..f2c038c91c70 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -212,8 +212,7 @@ static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, u32 hw_ip, int32_t ctx_prio; int r; - entity = kzalloc(struct_size(entity, fences, amdgpu_sched_jobs), - GFP_KERNEL); + entity = kzalloc_flex(*entity, fences, amdgpu_sched_jobs); if (!entity) return -ENOMEM; @@ -483,7 +482,7 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev, struct amdgpu_ctx *ctx; int r; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index aeb90708f229..f7467af2e102 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -206,7 +206,7 @@ static int amdgpu_debugfs_regs2_open(struct inode *inode, struct file *file) { struct amdgpu_debugfs_regs2_data *rd; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; rd->adev = file_inode(file)->i_private; @@ -371,7 +371,7 @@ static int amdgpu_debugfs_gprwave_open(struct inode *inode, struct file *file) { struct amdgpu_debugfs_gprwave_data *rd; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; rd->adev = file_inode(file)->i_private; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c index ca71c2948227..c38e7371bafc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dev_coredump.c @@ -332,7 +332,7 @@ void amdgpu_coredump(struct amdgpu_device *adev, bool skip_vram_check, struct amdgpu_coredump_info *coredump; struct drm_sched_job *s_job; - coredump = kzalloc(sizeof(*coredump), GFP_NOWAIT); + coredump = kzalloc_obj(*coredump, GFP_NOWAIT); if (!coredump) return; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index c7f44422939f..d8296dfc5e8a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2596,7 +2596,7 @@ static int amdgpu_device_parse_gpu_info_fw(struct amdgpu_device *adev) static void amdgpu_uid_init(struct amdgpu_device *adev) { /* Initialize the UID for the device */ - adev->uid_info = kzalloc(sizeof(struct amdgpu_uid), GFP_KERNEL); + adev->uid_info = kzalloc_obj(struct amdgpu_uid); if (!adev->uid_info) { dev_warn(adev->dev, "Failed to allocate memory for UID\n"); return; @@ -2690,8 +2690,10 @@ static int amdgpu_device_ip_early_init(struct amdgpu_device *adev) break; default: r = amdgpu_discovery_set_ip_blocks(adev); - if (r) + if (r) { + adev->num_ip_blocks = 0; return r; + } break; } @@ -3247,6 +3249,8 @@ int amdgpu_device_set_cg_state(struct amdgpu_device *adev, i = state == AMD_CG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; if (!adev->ip_blocks[i].status.late_initialized) continue; + if (!adev->ip_blocks[i].version) + continue; /* skip CG for GFX, SDMA on S0ix */ if (adev->in_s0ix && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || @@ -3286,6 +3290,8 @@ int amdgpu_device_set_pg_state(struct amdgpu_device *adev, i = state == AMD_PG_STATE_GATE ? j : adev->num_ip_blocks - j - 1; if (!adev->ip_blocks[i].status.late_initialized) continue; + if (!adev->ip_blocks[i].version) + continue; /* skip PG for GFX, SDMA on S0ix */ if (adev->in_s0ix && (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GFX || @@ -3493,6 +3499,8 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) int i, r; for (i = 0; i < adev->num_ip_blocks; i++) { + if (!adev->ip_blocks[i].version) + continue; if (!adev->ip_blocks[i].version->funcs->early_fini) continue; @@ -3504,9 +3512,6 @@ static int amdgpu_device_ip_fini_early(struct amdgpu_device *adev) } } - amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); - amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); - amdgpu_amdkfd_suspend(adev, true); amdgpu_amdkfd_teardown_processes(adev); amdgpu_userq_suspend(adev); @@ -3573,6 +3578,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) if (!adev->ip_blocks[i].status.sw) continue; + if (!adev->ip_blocks[i].version) + continue; if (adev->ip_blocks[i].version->type == AMD_IP_BLOCK_TYPE_GMC) { amdgpu_ucode_free_bo(adev); amdgpu_free_static_csa(&adev->virt.csa_obj); @@ -3599,6 +3606,8 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev) for (i = adev->num_ip_blocks - 1; i >= 0; i--) { if (!adev->ip_blocks[i].status.late_initialized) continue; + if (!adev->ip_blocks[i].version) + continue; if (adev->ip_blocks[i].version->funcs->late_fini) adev->ip_blocks[i].version->funcs->late_fini(&adev->ip_blocks[i]); adev->ip_blocks[i].status.late_initialized = false; @@ -4618,9 +4627,10 @@ int amdgpu_device_init(struct amdgpu_device *adev, /* APUs w/ gfx9 onwards doesn't reply on PCIe atomics, rather it is a * internal path natively support atomics, set have_atomics_support to true. */ - } else if ((adev->flags & AMD_IS_APU) && - (amdgpu_ip_version(adev, GC_HWIP, 0) > - IP_VERSION(9, 0, 0))) { + } else if ((adev->flags & AMD_IS_APU && + amdgpu_ip_version(adev, GC_HWIP, 0) > IP_VERSION(9, 0, 0)) || + (adev->gmc.xgmi.connected_to_cpu && + amdgpu_ip_version(adev, GC_HWIP, 0) >= IP_VERSION(12, 1, 0))) { adev->have_atomics_support = true; } else { adev->have_atomics_support = @@ -4655,9 +4665,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, dev_info(adev->dev, "Pending hive reset.\n"); amdgpu_set_init_level(adev, AMDGPU_INIT_LEVEL_MINIMAL_XGMI); - } else if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) && - !amdgpu_device_has_display_hardware(adev)) { - r = psp_gpu_reset(adev); } else { tmp = amdgpu_reset_method; /* It should do a default reset when loading or reloading the driver, @@ -4902,6 +4909,9 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_virt_fini_data_exchange(adev); } + amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); + amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); + /* disable all interrupts */ amdgpu_irq_disable_all(adev); if (adev->mode_info.mode_config_initialized) { @@ -4924,7 +4934,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) * before ip_fini_early to prevent kfd locking refcount issues by calling * amdgpu_amdkfd_suspend() */ - if (drm_dev_is_unplugged(adev_to_drm(adev))) + if (pci_dev_is_disconnected(adev->pdev)) amdgpu_amdkfd_device_fini_sw(adev); amdgpu_device_ip_fini_early(adev); @@ -4936,7 +4946,7 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) amdgpu_gart_dummy_page_fini(adev); - if (drm_dev_is_unplugged(adev_to_drm(adev))) + if (pci_dev_is_disconnected(adev->pdev)) amdgpu_device_unmap_mmio(adev); } @@ -5733,6 +5743,9 @@ int amdgpu_device_mode1_reset(struct amdgpu_device *adev) /* enable mmio access after mode 1 reset completed */ adev->no_hw_access = false; + /* ensure no_hw_access is updated before we access hw */ + smp_mb(); + amdgpu_device_load_pci_state(adev->pdev); ret = amdgpu_psp_wait_for_bootloader(adev); if (ret) @@ -7058,6 +7071,15 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev) dev_info(adev->dev, "PCI error: slot reset callback!!\n"); memset(&reset_context, 0, sizeof(reset_context)); + INIT_LIST_HEAD(&device_list); + hive = amdgpu_get_xgmi_hive(adev); + if (hive) { + mutex_lock(&hive->hive_lock); + list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) + list_add_tail(&tmp_adev->reset_list, &device_list); + } else { + list_add_tail(&adev->reset_list, &device_list); + } if (adev->pcie_reset_ctx.swus) link_dev = adev->pcie_reset_ctx.swus; @@ -7098,19 +7120,13 @@ pci_ers_result_t amdgpu_pci_slot_reset(struct pci_dev *pdev) reset_context.reset_req_dev = adev; set_bit(AMDGPU_NEED_FULL_RESET, &reset_context.flags); set_bit(AMDGPU_SKIP_COREDUMP, &reset_context.flags); - INIT_LIST_HEAD(&device_list); - hive = amdgpu_get_xgmi_hive(adev); if (hive) { - mutex_lock(&hive->hive_lock); reset_context.hive = hive; - list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) { + list_for_each_entry(tmp_adev, &hive->device_list, gmc.xgmi.head) tmp_adev->pcie_reset_ctx.in_link_reset = true; - list_add_tail(&tmp_adev->reset_list, &device_list); - } } else { set_bit(AMDGPU_SKIP_HW_RESET, &reset_context.flags); - list_add_tail(&adev->reset_list, &device_list); } r = amdgpu_device_asic_reset(adev, &device_list, &reset_context); @@ -7357,6 +7373,9 @@ void amdgpu_device_halt(struct amdgpu_device *adev) amdgpu_xcp_dev_unplug(adev); drm_dev_unplug(ddev); + amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE); + amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE); + amdgpu_irq_disable_all(adev); amdgpu_fence_driver_hw_fini(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 41e63c286912..af3d2fd61cf3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -1149,7 +1149,7 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev, * block if not yet registered. */ if (!ip_hw_id) { - ip_hw_id = kzalloc(sizeof(*ip_hw_id), GFP_KERNEL); + ip_hw_id = kzalloc_obj(*ip_hw_id); if (!ip_hw_id) return -ENOMEM; ip_hw_id->hw_id = ii; @@ -1177,10 +1177,9 @@ static int amdgpu_discovery_sysfs_ips(struct amdgpu_device *adev, /* Now register its instance. */ - ip_hw_instance = kzalloc(struct_size(ip_hw_instance, - base_addr, - ip->num_base_address), - GFP_KERNEL); + ip_hw_instance = kzalloc_flex(*ip_hw_instance, + base_addr, + ip->num_base_address); if (!ip_hw_instance) { DRM_ERROR("no memory for ip_hw_instance"); return -ENOMEM; @@ -1255,7 +1254,7 @@ static int amdgpu_discovery_sysfs_recurse(struct amdgpu_device *adev) * amdgpu_discovery_reg_base_init(). */ - ip_die_entry = kzalloc(sizeof(*ip_die_entry), GFP_KERNEL); + ip_die_entry = kzalloc_obj(*ip_die_entry); if (!ip_die_entry) return -ENOMEM; @@ -1287,7 +1286,7 @@ static int amdgpu_discovery_sysfs_init(struct amdgpu_device *adev) if (!discovery_bin) return -EINVAL; - ip_top = kzalloc(sizeof(*ip_top), GFP_KERNEL); + ip_top = kzalloc_obj(*ip_top); if (!ip_top) return -ENOMEM; @@ -1931,9 +1930,7 @@ int amdgpu_discovery_get_nps_info(struct amdgpu_device *adev, switch (le16_to_cpu(nps_info->v1.header.version_major)) { case 1: - mem_ranges = kvcalloc(nps_info->v1.count, - sizeof(*mem_ranges), - GFP_KERNEL); + mem_ranges = kvzalloc_objs(*mem_ranges, nps_info->v1.count); if (!mem_ranges) return -ENOMEM; *nps_type = nps_info->v1.nps_type; @@ -2164,6 +2161,7 @@ static int amdgpu_discovery_set_psp_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(13, 0, 11): case IP_VERSION(13, 0, 12): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): case IP_VERSION(14, 0, 0): case IP_VERSION(14, 0, 1): case IP_VERSION(14, 0, 4): @@ -2988,9 +2986,11 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) case IP_VERSION(11, 5, 1): case IP_VERSION(11, 5, 2): case IP_VERSION(11, 5, 3): - case IP_VERSION(11, 5, 4): adev->family = AMDGPU_FAMILY_GC_11_5_0; break; + case IP_VERSION(11, 5, 4): + adev->family = AMDGPU_FAMILY_GC_11_5_4; + break; case IP_VERSION(12, 0, 0): case IP_VERSION(12, 0, 1): case IP_VERSION(12, 1, 0): diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c index 48b6f6077992..bef9dce2e7ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c @@ -204,7 +204,7 @@ int amdgpu_display_crtc_page_flip_target(struct drm_crtc *crtc, u64 tiling_flags; int i, r; - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (work == NULL) return -ENOMEM; @@ -1323,7 +1323,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev, return ERR_PTR(-EINVAL); } - amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL); + amdgpu_fb = kzalloc_obj(*amdgpu_fb); if (amdgpu_fb == NULL) { drm_gem_object_put(obj); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c index b9c38a4fe546..656c267dbe58 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c @@ -514,8 +514,15 @@ amdgpu_dma_buf_move_notify(struct dma_buf_attachment *attach) r = dma_resv_reserve_fences(resv, 2); if (!r) r = amdgpu_vm_clear_freed(adev, vm, NULL); + + /* Don't pass 'ticket' to amdgpu_vm_handle_moved: we want the clear=true + * path to be used otherwise we might update the PT of another process + * while it's using the BO. + * With clear=true, amdgpu_vm_bo_update will sync to command submission + * from the same VM. + */ if (!r) - r = amdgpu_vm_handle_moved(adev, vm, ticket); + r = amdgpu_vm_handle_moved(adev, vm, NULL); if (r && r != -EBUSY) DRM_ERROR("Failed to invalidate VM page tables (%d))\n", diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c index 23d7d0b0d625..3b588c7740ec 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_eviction_fence.c @@ -161,7 +161,7 @@ amdgpu_eviction_fence_create(struct amdgpu_eviction_fence_mgr *evf_mgr) { struct amdgpu_eviction_fence *ev_fence; - ev_fence = kzalloc(sizeof(*ev_fence), GFP_KERNEL); + ev_fence = kzalloc_obj(*ev_fence); if (!ev_fence) return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c index b0082aa7f3c6..514bd302365f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fru_eeprom.c @@ -130,7 +130,7 @@ int amdgpu_fru_get_product_info(struct amdgpu_device *adev) return 0; if (!adev->fru_info) { - adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL); + adev->fru_info = kzalloc_obj(*adev->fru_info); if (!adev->fru_info) return -ENOMEM; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c index ec911dce345f..e2d32c29668a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gart.c @@ -153,7 +153,7 @@ int amdgpu_gart_table_ram_alloc(struct amdgpu_device *adev) dev_info(adev->dev, "%s dma_addr:%pad\n", __func__, &dma_addr); /* Create SG table */ - sg = kmalloc(sizeof(*sg), GFP_KERNEL); + sg = kmalloc_obj(*sg); if (!sg) { ret = -ENOMEM; goto error; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c index 5f9fa2140f09..a6107109a2b8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c @@ -232,6 +232,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, struct amdgpu_vm *vm = &fpriv->vm; struct amdgpu_bo_va *bo_va; struct mm_struct *mm; + struct drm_exec exec; int r; mm = amdgpu_ttm_tt_get_usermm(abo->tbo.ttm); @@ -242,9 +243,18 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, !amdgpu_vm_is_bo_always_valid(vm, abo)) return -EPERM; - r = amdgpu_bo_reserve(abo, false); - if (r) - return r; + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); + drm_exec_until_all_locked(&exec) { + r = drm_exec_prepare_obj(&exec, &abo->tbo.base, 1); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto out_unlock; + + r = amdgpu_vm_lock_pd(vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto out_unlock; + } amdgpu_vm_bo_update_shared(abo); bo_va = amdgpu_vm_bo_find(vm, abo); @@ -260,8 +270,7 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, amdgpu_bo_unreserve(abo); return r; } - - amdgpu_bo_unreserve(abo); + drm_exec_fini(&exec); /* Validate and add eviction fence to DMABuf imports with dynamic * attachment in compute VMs. Re-validation will be done by @@ -294,7 +303,10 @@ static int amdgpu_gem_object_open(struct drm_gem_object *obj, } } mutex_unlock(&vm->process_info->lock); + return r; +out_unlock: + drm_exec_fini(&exec); return r; } @@ -1171,7 +1183,7 @@ int amdgpu_gem_list_handles_ioctl(struct drm_device *dev, void *data, return 0; } - bo_entries = kvcalloc(num_bos, sizeof(*bo_entries), GFP_KERNEL); + bo_entries = kvzalloc_objs(*bo_entries, num_bos); if (!bo_entries) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index b793ce17140c..5179fa008626 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -1068,6 +1068,16 @@ void amdgpu_gmc_get_vbios_allocations(struct amdgpu_device *adev) case CHIP_RENOIR: adev->mman.keep_stolen_vga_memory = true; break; + case CHIP_POLARIS10: + case CHIP_POLARIS11: + case CHIP_POLARIS12: + /* MacBookPros with switchable graphics put VRAM at 0 when + * the iGPU is enabled which results in cursor issues if + * the cursor ends up at 0. Reserve vram at 0 in that case. + */ + if (adev->gmc.vram_start == 0) + adev->mman.keep_stolen_vga_memory = true; + break; default: adev->mman.keep_stolen_vga_memory = false; break; @@ -1436,7 +1446,7 @@ int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev, if (!*exp_ranges) *exp_ranges = range_cnt; err: - kfree(ranges); + kvfree(ranges); return ret; } @@ -1717,9 +1727,8 @@ int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev) { bool valid; - adev->gmc.mem_partitions = kcalloc(AMDGPU_MAX_MEM_RANGES, - sizeof(struct amdgpu_mem_partition_info), - GFP_KERNEL); + adev->gmc.mem_partitions = kzalloc_objs(struct amdgpu_mem_partition_info, + AMDGPU_MAX_MEM_RANGES); if (!adev->gmc.mem_partitions) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h index e8e8bfa098c3..0e8a52d96573 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h @@ -33,9 +33,9 @@ #include "amdgpu_ras.h" /* VA hole for 48bit and 57bit addresses */ -#define AMDGPU_GMC_HOLE_START (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ +#define AMDGPU_GMC_HOLE_START (adev->vm_manager.max_level == 4 ?\ 0x0100000000000000ULL : 0x0000800000000000ULL) -#define AMDGPU_GMC_HOLE_END (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ +#define AMDGPU_GMC_HOLE_END (adev->vm_manager.max_level == 4 ?\ 0xff00000000000000ULL : 0xffff800000000000ULL) /* @@ -45,8 +45,8 @@ * This mask is used to remove the upper 16bits of the VA and so come up with * the linear addr value. */ -#define AMDGPU_GMC_HOLE_MASK (adev->vm_manager.root_level == AMDGPU_VM_PDB3 ?\ - 0x00ffffffffffffffULL : 0x0000ffffffffffffULL) +#define AMDGPU_GMC_HOLE_MASK (adev->vm_manager.max_level == 4 ?\ + 0x01ffffffffffffffULL : 0x0000ffffffffffffULL) /* * Ring size as power of two for the log of recent faults. diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c index dd9b845d5783..ac276bb53c7c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c @@ -122,7 +122,7 @@ static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man, struct ttm_range_mgr_node *node; int r; - node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL); + node = kzalloc_flex(*node, mm_nodes, 1); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c index 90d26d820bac..f72990ac046e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_hmm.c @@ -265,7 +265,7 @@ struct amdgpu_hmm_range *amdgpu_hmm_range_alloc(struct amdgpu_bo *bo) { struct amdgpu_hmm_range *range; - range = kzalloc(sizeof(*range), GFP_KERNEL); + range = kzalloc_obj(*range); if (!range) return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c index 9cb72f0c5277..c576e103a783 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c @@ -168,7 +168,7 @@ struct amdgpu_i2c_chan *amdgpu_i2c_create(struct drm_device *dev, if (rec->mm_i2c && (amdgpu_hw_i2c == 0)) return NULL; - i2c = kzalloc(sizeof(struct amdgpu_i2c_chan), GFP_KERNEL); + i2c = kzalloc_obj(struct amdgpu_i2c_chan); if (i2c == NULL) return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c index 44f230d67da2..3a7bab87b5d8 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c @@ -169,7 +169,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, csa_va = 0; gds_va = 0; init_shadow = false; - af = kzalloc(sizeof(*af), GFP_ATOMIC); + af = kzalloc_obj(*af, GFP_ATOMIC); if (!af) return -ENOMEM; } @@ -229,7 +229,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned int num_ibs, r = amdgpu_vm_flush(ring, job, need_pipe_sync); if (r) { amdgpu_ring_undo(ring); - return r; + goto free_fence; } } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c index 9cab36322c16..64c519cd7395 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c @@ -119,7 +119,7 @@ void amdgpu_pasid_free_delayed(struct dma_resv *resv, return; } - cb = kmalloc(sizeof(*cb), GFP_KERNEL); + cb = kmalloc_obj(*cb); if (!cb) { /* Last resort when we are OOM */ dma_fence_wait(fence, false); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index 82bc6d657e5a..254a4e983f40 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c @@ -436,9 +436,8 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, if (!adev->irq.client[client_id].sources) { adev->irq.client[client_id].sources = - kcalloc(AMDGPU_MAX_IRQ_SRC_ID, - sizeof(struct amdgpu_irq_src *), - GFP_KERNEL); + kzalloc_objs(struct amdgpu_irq_src *, + AMDGPU_MAX_IRQ_SRC_ID); if (!adev->irq.client[client_id].sources) return -ENOMEM; } @@ -449,8 +448,7 @@ int amdgpu_irq_add_id(struct amdgpu_device *adev, if (source->num_types && !source->enabled_types) { atomic_t *types; - types = kcalloc(source->num_types, sizeof(atomic_t), - GFP_KERNEL); + types = kzalloc_objs(atomic_t, source->num_types); if (!types) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index aaf5477fcd7a..d7c1ffbf7626 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -92,6 +92,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) struct drm_wedge_task_info *info = NULL; struct amdgpu_task_info *ti = NULL; struct amdgpu_device *adev = ring->adev; + enum drm_gpu_sched_stat status = DRM_GPU_SCHED_STAT_RESET; int idx, r; if (!drm_dev_enter(adev_to_drm(adev), &idx)) { @@ -135,13 +136,19 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) ring->funcs->reset) { dev_err(adev->dev, "Starting %s ring reset\n", s_job->sched->name); + /* Stop the scheduler to prevent anybody else from touching the ring buffer. */ + drm_sched_wqueue_stop(&ring->sched); r = amdgpu_ring_reset(ring, job->vmid, job->hw_fence); if (!r) { + /* Start the scheduler again */ + drm_sched_wqueue_start(&ring->sched); atomic_inc(&ring->adev->gpu_reset_counter); dev_err(adev->dev, "Ring %s reset succeeded\n", ring->sched.name); drm_dev_wedged_event(adev_to_drm(adev), DRM_WEDGE_RECOVERY_NONE, info); + /* This is needed to add the job back to the pending list */ + status = DRM_GPU_SCHED_STAT_NO_HANG; goto exit; } dev_err(adev->dev, "Ring %s reset failed\n", ring->sched.name); @@ -177,7 +184,7 @@ static enum drm_gpu_sched_stat amdgpu_job_timedout(struct drm_sched_job *s_job) exit: amdgpu_vm_put_task_info(ti); drm_dev_exit(idx); - return DRM_GPU_SCHED_STAT_RESET; + return status; } int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, @@ -191,18 +198,18 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, if (num_ibs == 0) return -EINVAL; - *job = kzalloc(struct_size(*job, ibs, num_ibs), GFP_KERNEL); + *job = kzalloc_flex(**job, ibs, num_ibs); if (!*job) return -ENOMEM; - af = kzalloc(sizeof(struct amdgpu_fence), GFP_KERNEL); + af = kzalloc_obj(struct amdgpu_fence); if (!af) { r = -ENOMEM; goto err_job; } (*job)->hw_fence = af; - af = kzalloc(sizeof(struct amdgpu_fence), GFP_KERNEL); + af = kzalloc_obj(struct amdgpu_fence); if (!af) { r = -ENOMEM; goto err_fence; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c index 1878e0faa722..7f19554b9ad1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c @@ -83,7 +83,7 @@ void amdgpu_driver_unload_kms(struct drm_device *dev) { struct amdgpu_device *adev = drm_to_adev(dev); - if (adev == NULL) + if (adev == NULL || !adev->num_ip_blocks) return; amdgpu_unregister_gpu_instance(adev); @@ -942,7 +942,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) uint64_t vm_size; uint32_t pcie_gen_mask, pcie_width_mask; - dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); + dev_info = kzalloc_obj(*dev_info); if (!dev_info) return -ENOMEM; @@ -1329,7 +1329,7 @@ int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) return -EINVAL; } - caps = kzalloc(sizeof(*caps), GFP_KERNEL); + caps = kzalloc_obj(*caps); if (!caps) return -ENOMEM; @@ -1445,6 +1445,7 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) { struct amdgpu_device *adev = drm_to_adev(dev); struct amdgpu_fpriv *fpriv; + struct drm_exec exec; int r, pasid; /* Ensure IB tests are run on ring */ @@ -1484,7 +1485,16 @@ int amdgpu_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) if (r) goto error_pasid; + drm_exec_init(&exec, DRM_EXEC_IGNORE_DUPLICATES, 0); + drm_exec_until_all_locked(&exec) { + r = amdgpu_vm_lock_pd(&fpriv->vm, &exec, 0); + drm_exec_retry_on_contention(&exec); + if (unlikely(r)) + goto error_vm; + } + fpriv->prt_va = amdgpu_vm_bo_add(adev, &fpriv->vm, NULL); + drm_exec_fini(&exec); if (!fpriv->prt_va) { r = -ENOMEM; goto error_vm; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c index 3ca03b5e0f91..823ba17e32af 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mca.c @@ -169,7 +169,7 @@ static int amdgpu_mca_bank_set_add_entry(struct mca_bank_set *mca_set, struct mc if (!entry) return -EINVAL; - node = kvzalloc(sizeof(*node), GFP_KERNEL); + node = kvzalloc_obj(*node); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h index dc8d2f52c7d6..e244c12ceb23 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h @@ -368,15 +368,15 @@ struct amdgpu_mode_info { struct drm_property *plane_ctm_property; /** - * @shaper_lut_property: Plane property to set pre-blending shaper LUT - * that converts color content before 3D LUT. If - * plane_shaper_tf_property != Identity TF, AMD color module will + * @plane_shaper_lut_property: Plane property to set pre-blending + * shaper LUT that converts color content before 3D LUT. + * If plane_shaper_tf_property != Identity TF, AMD color module will * combine the user LUT values with pre-defined TF into the LUT * parameters to be programmed. */ struct drm_property *plane_shaper_lut_property; /** - * @shaper_lut_size_property: Plane property for the size of + * @plane_shaper_lut_size_property: Plane property for the size of * pre-blending shaper LUT as supported by the driver (read-only). */ struct drm_property *plane_shaper_lut_size_property; @@ -400,10 +400,10 @@ struct amdgpu_mode_info { */ struct drm_property *plane_lut3d_property; /** - * @plane_degamma_lut_size_property: Plane property to define the max - * size of 3D LUT as supported by the driver (read-only). The max size - * is the max size of one dimension and, therefore, the max number of - * entries for 3D LUT array is the 3D LUT size cubed; + * @plane_lut3d_size_property: Plane property to define the max size + * of 3D LUT as supported by the driver (read-only). The max size is + * the max size of one dimension and, therefore, the max number of + * entries for 3D LUT array is the 3D LUT size cubed. */ struct drm_property *plane_lut3d_size_property; /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c index 6e91ea1de5aa..60bbe00e8024 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pmu.c @@ -446,25 +446,24 @@ static int amdgpu_pmu_alloc_pmu_attrs( struct amdgpu_pmu_event_attribute **evt_attr, struct amdgpu_pmu_config *config) { - *fmt_attr = kcalloc(config->num_formats, sizeof(**fmt_attr), - GFP_KERNEL); + *fmt_attr = kzalloc_objs(**fmt_attr, config->num_formats); if (!(*fmt_attr)) return -ENOMEM; - fmt_attr_group->attrs = kcalloc(config->num_formats + 1, - sizeof(*fmt_attr_group->attrs), GFP_KERNEL); + fmt_attr_group->attrs = kzalloc_objs(*fmt_attr_group->attrs, + config->num_formats + 1); if (!fmt_attr_group->attrs) goto err_fmt_attr_grp; - *evt_attr = kcalloc(config->num_events, sizeof(**evt_attr), GFP_KERNEL); + *evt_attr = kzalloc_objs(**evt_attr, config->num_events); if (!(*evt_attr)) goto err_evt_attr; - evt_attr_group->attrs = kcalloc(config->num_events + 1, - sizeof(*evt_attr_group->attrs), GFP_KERNEL); + evt_attr_group->attrs = kzalloc_objs(*evt_attr_group->attrs, + config->num_events + 1); if (!evt_attr_group->attrs) goto err_evt_attr_grp; @@ -599,7 +598,7 @@ static struct amdgpu_pmu_entry *create_pmu_entry(struct amdgpu_device *adev, { struct amdgpu_pmu_entry *pmu_entry; - pmu_entry = kzalloc(sizeof(struct amdgpu_pmu_entry), GFP_KERNEL); + pmu_entry = kzalloc_obj(struct amdgpu_pmu_entry); if (!pmu_entry) return pmu_entry; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c index 34b5e22b44e5..b1dc33301d83 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_preempt_mgr.c @@ -61,7 +61,7 @@ static int amdgpu_preempt_mgr_new(struct ttm_resource_manager *man, const struct ttm_place *place, struct ttm_resource **res) { - *res = kzalloc(sizeof(**res), GFP_KERNEL); + *res = kzalloc_obj(**res); if (!*res) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c index b0540b009e84..27b67da9fdac 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -148,6 +148,7 @@ static int psp_init_sriov_microcode(struct psp_context *psp) break; case IP_VERSION(13, 0, 6): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): ret = psp_init_cap_microcode(psp, ucode_prefix); ret &= psp_init_ta_microcode(psp, ucode_prefix); break; @@ -219,6 +220,7 @@ static int psp_early_init(struct amdgpu_ip_block *ip_block) psp->autoload_supported = false; break; case IP_VERSION(13, 0, 12): + case IP_VERSION(13, 0, 15): psp_v13_0_set_psp_funcs(psp); psp->autoload_supported = false; adev->psp.sup_ifwi_up = !amdgpu_sriov_vf(adev); @@ -383,7 +385,8 @@ static bool psp_get_runtime_db_entry(struct amdgpu_device *adev, if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) return false; db_header_pos = adev->gmc.mc_vram_size - PSP_RUNTIME_DB_OFFSET; @@ -454,7 +457,7 @@ static int psp_sw_init(struct amdgpu_ip_block *ip_block) struct psp_memory_training_context *mem_training_ctx = &psp->mem_train_ctx; struct psp_runtime_scpm_entry scpm_entry; - psp->cmd = kzalloc(sizeof(struct psp_gfx_cmd_resp), GFP_KERNEL); + psp->cmd = kzalloc_obj(struct psp_gfx_cmd_resp); if (!psp->cmd) { dev_err(adev->dev, "Failed to allocate memory to command buffer!\n"); return -ENOMEM; @@ -735,7 +738,7 @@ psp_cmd_submit_buf(struct psp_context *psp, ras_intr = amdgpu_ras_intr_triggered(); if (ras_intr) break; - usleep_range(10, 100); + usleep_range(60, 100); amdgpu_device_invalidate_hdp(psp->adev, NULL); } @@ -4381,7 +4384,7 @@ static int psp_read_spirom_debugfs_open(struct inode *inode, struct file *filp) return -EBUSY; } - bo_triplet = kzalloc(sizeof(struct spirom_bo), GFP_KERNEL); + bo_triplet = kzalloc_obj(struct spirom_bo); if (!bo_triplet) { mutex_unlock(&adev->psp.mutex); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c index 6e8aad91bcd3..0d3c18f04ac3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp_ta.c @@ -332,13 +332,13 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size if (!context || !context->initialized) { dev_err(adev->dev, "TA is not initialized\n"); ret = -EINVAL; - goto err_free_shared_buf; + goto free_shared_buf; } if (!psp->ta_funcs || !psp->ta_funcs->fn_ta_invoke) { dev_err(adev->dev, "Unsupported function to invoke TA\n"); ret = -EOPNOTSUPP; - goto err_free_shared_buf; + goto free_shared_buf; } context->session_id = ta_id; @@ -346,7 +346,7 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size mutex_lock(&psp->ras_context.mutex); ret = prep_ta_mem_context(&context->mem_context, shared_buf, shared_buf_len); if (ret) - goto err_free_shared_buf; + goto unlock; ret = psp_fn_ta_invoke(psp, cmd_id); if (ret || context->resp_status) { @@ -354,15 +354,17 @@ static ssize_t ta_if_invoke_debugfs_write(struct file *fp, const char *buf, size ret, context->resp_status); if (!ret) { ret = -EINVAL; - goto err_free_shared_buf; + goto unlock; } } if (copy_to_user((char *)&buf[copy_pos], context->mem_context.shared_buf, shared_buf_len)) ret = -EFAULT; -err_free_shared_buf: +unlock: mutex_unlock(&psp->ras_context.mutex); + +free_shared_buf: kfree(shared_buf); return ret; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c index f582113d78b7..c0336ca9bf6a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c @@ -891,7 +891,7 @@ int amdgpu_ras_feature_enable(struct amdgpu_device *adev, if (head->block == AMDGPU_RAS_BLOCK__GFX && !amdgpu_sriov_vf(adev) && !amdgpu_ras_intr_triggered()) { - info = kzalloc(sizeof(union ta_ras_cmd_input), GFP_KERNEL); + info = kzalloc_obj(union ta_ras_cmd_input); if (!info) return -ENOMEM; @@ -1904,7 +1904,7 @@ static ssize_t amdgpu_ras_sysfs_badpages_read(struct file *f, memset(buf, 0, count); bps_count = end - start; - bps = kmalloc_array(bps_count, sizeof(*bps), GFP_KERNEL); + bps = kmalloc_objs(*bps, bps_count); if (!bps) return 0; @@ -2811,7 +2811,7 @@ static int amdgpu_uniras_badpages_read(struct amdgpu_device *adev, if (!bps || !count) return -EINVAL; - output = kmalloc(sizeof(*output), GFP_KERNEL); + output = kmalloc_obj(*output); if (!output) return -ENOMEM; @@ -2991,7 +2991,7 @@ static int amdgpu_ras_realloc_eh_data_space(struct amdgpu_device *adev, unsigned int old_space = data->count + data->space_left; unsigned int new_space = old_space + pages; unsigned int align_space = ALIGN(new_space, 512); - void *bps = kmalloc_array(align_space, sizeof(*data->bps), GFP_KERNEL); + void *bps = kmalloc_objs(*data->bps, align_space); if (!bps) { return -ENOMEM; @@ -3238,8 +3238,8 @@ int amdgpu_ras_add_bad_pages(struct amdgpu_device *adev, if (from_rom) { err_data.err_addr = - kcalloc(adev->umc.retire_unit, - sizeof(struct eeprom_table_record), GFP_KERNEL); + kzalloc_objs(struct eeprom_table_record, + adev->umc.retire_unit); if (!err_data.err_addr) { dev_warn(adev->dev, "Failed to alloc UMC error address record in mca2pa conversion!\n"); return -ENOMEM; @@ -3375,7 +3375,7 @@ static int amdgpu_ras_load_bad_pages(struct amdgpu_device *adev) if (control->ras_num_recs == 0 || amdgpu_bad_page_threshold == 0) return 0; - bps = kcalloc(control->ras_num_recs, sizeof(*bps), GFP_KERNEL); + bps = kzalloc_objs(*bps, control->ras_num_recs); if (!bps) return -ENOMEM; @@ -3863,7 +3863,7 @@ int amdgpu_ras_recovery_init(struct amdgpu_device *adev, bool init_bp_info) return 0; data = &con->eh_data; - *data = kzalloc(sizeof(**data), GFP_KERNEL); + *data = kzalloc_obj(**data); if (!*data) { ret = -ENOMEM; goto out; @@ -4352,7 +4352,7 @@ int amdgpu_ras_init(struct amdgpu_device *adev) * to handle fatal error */ r = amdgpu_nbio_ras_sw_init(adev); if (r) - return r; + goto release_con; if (adev->nbio.ras && adev->nbio.ras->init_ras_controller_interrupt) { @@ -4499,7 +4499,7 @@ int amdgpu_ras_block_late_init(struct amdgpu_device *adev, /* Those are the cached values at init. */ - query_info = kzalloc(sizeof(*query_info), GFP_KERNEL); + query_info = kzalloc_obj(*query_info); if (!query_info) return -ENOMEM; memcpy(&query_info->head, ras_block, sizeof(struct ras_common_if)); @@ -4650,6 +4650,8 @@ int amdgpu_ras_late_init(struct amdgpu_device *adev) amdgpu_ras_block_late_init_default(adev, &obj->ras_comm); } + amdgpu_ras_check_bad_page_status(adev); + return 0; } @@ -5186,7 +5188,7 @@ int amdgpu_ras_register_ras_block(struct amdgpu_device *adev, if (!adev || !ras_block_obj) return -EINVAL; - ras_node = kzalloc(sizeof(*ras_node), GFP_KERNEL); + ras_node = kzalloc_obj(*ras_node); if (!ras_node) return -ENOMEM; @@ -5387,7 +5389,7 @@ static struct ras_err_node *amdgpu_ras_error_node_new(void) { struct ras_err_node *err_node; - err_node = kvzalloc(sizeof(*err_node), GFP_KERNEL); + err_node = kvzalloc_obj(*err_node); if (!err_node) return NULL; @@ -5680,7 +5682,7 @@ int amdgpu_ras_add_critical_region(struct amdgpu_device *adev, /* Record new critical amdgpu bo */ list_for_each_entry(block, &vres->blocks, link) { - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c index 469d04a39d7d..6fba9d5b29ea 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.c @@ -1701,10 +1701,12 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control) } res = __verify_ras_table_checksum(control); - if (res) + if (res) { dev_err(adev->dev, "RAS table incorrect checksum or error:%d\n", res); + return -EINVAL; + } /* Warn if we are at 90% of the threshold or above */ @@ -1712,10 +1714,6 @@ int amdgpu_ras_eeprom_check(struct amdgpu_ras_eeprom_control *control) dev_warn(adev->dev, "RAS records:%u exceeds 90%% of threshold:%d", control->ras_num_bad_pages, ras->bad_page_cnt_threshold); - if (amdgpu_bad_page_threshold != 0 && - control->ras_num_bad_pages >= ras->bad_page_cnt_threshold) - amdgpu_dpm_send_rma_reason(adev); - } else if (hdr->header == RAS_TABLE_HDR_BAD && amdgpu_bad_page_threshold != 0) { if (hdr->version >= RAS_TABLE_VER_V2_1) { @@ -1932,3 +1930,26 @@ int amdgpu_ras_smu_erase_ras_table(struct amdgpu_device *adev, result); return -EOPNOTSUPP; } + +void amdgpu_ras_check_bad_page_status(struct amdgpu_device *adev) +{ + struct amdgpu_ras *ras = amdgpu_ras_get_context(adev); + struct amdgpu_ras_eeprom_control *control = ras ? &ras->eeprom_control : NULL; + + if (!control || amdgpu_bad_page_threshold == 0) + return; + + if (control->ras_num_bad_pages >= ras->bad_page_cnt_threshold) { + if (amdgpu_dpm_send_rma_reason(adev)) + dev_warn(adev->dev, "Unable to send out-of-band RMA CPER"); + else + dev_dbg(adev->dev, "Sent out-of-band RMA CPER"); + + if (adev->cper.enabled && !amdgpu_uniras_enabled(adev)) { + if (amdgpu_cper_generate_bp_threshold_record(adev)) + dev_warn(adev->dev, "Unable to send in-band RMA CPER"); + else + dev_dbg(adev->dev, "Sent in-band RMA CPER"); + } + } +} diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h index 2e5d63957e71..a62114800a92 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ras_eeprom.h @@ -193,6 +193,8 @@ int amdgpu_ras_eeprom_read_idx(struct amdgpu_ras_eeprom_control *control, int amdgpu_ras_eeprom_update_record_num(struct amdgpu_ras_eeprom_control *control); +void amdgpu_ras_check_bad_page_status(struct amdgpu_device *adev); + extern const struct file_operations amdgpu_ras_debugfs_eeprom_size_ops; extern const struct file_operations amdgpu_ras_debugfs_eeprom_table_ops; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c index 28c4ad62f50e..7a2fcb7ded1d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reset.c @@ -276,7 +276,7 @@ struct amdgpu_reset_domain *amdgpu_reset_create_reset_domain(enum amdgpu_reset_d { struct amdgpu_reset_domain *reset_domain; - reset_domain = kvzalloc(sizeof(struct amdgpu_reset_domain), GFP_KERNEL); + reset_domain = kvzalloc_obj(struct amdgpu_reset_domain); if (!reset_domain) { DRM_ERROR("Failed to allocate amdgpu_reset_domain!"); return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c index b82357c65723..4638a686a84e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c @@ -507,13 +507,13 @@ static ssize_t amdgpu_ras_cper_debugfs_read(struct file *f, char __user *buf, const uint8_t ring_header_size = 12; struct amdgpu_ring *ring = file_inode(f)->i_private; struct ras_cmd_cper_snapshot_req *snapshot_req __free(kfree) = - kzalloc(sizeof(struct ras_cmd_cper_snapshot_req), GFP_KERNEL); + kzalloc_obj(struct ras_cmd_cper_snapshot_req); struct ras_cmd_cper_snapshot_rsp *snapshot_rsp __free(kfree) = - kzalloc(sizeof(struct ras_cmd_cper_snapshot_rsp), GFP_KERNEL); + kzalloc_obj(struct ras_cmd_cper_snapshot_rsp); struct ras_cmd_cper_record_req *record_req __free(kfree) = - kzalloc(sizeof(struct ras_cmd_cper_record_req), GFP_KERNEL); + kzalloc_obj(struct ras_cmd_cper_record_req); struct ras_cmd_cper_record_rsp *record_rsp __free(kfree) = - kzalloc(sizeof(struct ras_cmd_cper_record_rsp), GFP_KERNEL); + kzalloc_obj(struct ras_cmd_cper_record_rsp); uint8_t *ring_header __free(kfree) = kzalloc(ring_header_size, GFP_KERNEL); uint32_t total_cper_num; @@ -868,8 +868,6 @@ bool amdgpu_ring_sched_ready(struct amdgpu_ring *ring) void amdgpu_ring_reset_helper_begin(struct amdgpu_ring *ring, struct amdgpu_fence *guilty_fence) { - /* Stop the scheduler to prevent anybody else from touching the ring buffer. */ - drm_sched_wqueue_stop(&ring->sched); /* back up the non-guilty commands */ amdgpu_ring_backup_unprocessed_commands(ring, guilty_fence); } @@ -895,8 +893,6 @@ int amdgpu_ring_reset_helper_end(struct amdgpu_ring *ring, amdgpu_ring_write(ring, ring->ring_backup[i]); amdgpu_ring_commit(ring); } - /* Start the scheduler again */ - drm_sched_wqueue_start(&ring->sched); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c index 7e7d6c3865bc..6e64a96fa285 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring_mux.c @@ -153,7 +153,7 @@ int amdgpu_ring_mux_init(struct amdgpu_ring_mux *mux, struct amdgpu_ring *ring, mux->real_ring = ring; mux->num_ring_entries = 0; - mux->ring_entry = kcalloc(entry_size, sizeof(struct amdgpu_mux_entry), GFP_KERNEL); + mux->ring_entry = kzalloc_objs(struct amdgpu_mux_entry, entry_size); if (!mux->ring_entry) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index 8b8a04138711..321310ba2c08 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -558,6 +558,9 @@ int amdgpu_sdma_reset_engine(struct amdgpu_device *adev, uint32_t instance_id, struct amdgpu_ring *gfx_ring = &sdma_instance->ring; struct amdgpu_ring *page_ring = &sdma_instance->page; + if (amdgpu_sriov_vf(adev)) + return -EOPNOTSUPP; + mutex_lock(&sdma_instance->engine_reset_mutex); if (!caller_handles_kernel_queues) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 15d561e3d87f..eeaa56c8d129 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1122,7 +1122,7 @@ int amdgpu_ttm_mmio_remap_alloc_sgt(struct amdgpu_device *adev, phys = adev->rmmio_remap.bus_addr + cur.start; /* Build a single-entry sg_table mapped as I/O (no struct page backing). */ - *sgt = kzalloc(sizeof(**sgt), GFP_KERNEL); + *sgt = kzalloc_obj(**sgt); if (!*sgt) return -ENOMEM; r = sg_alloc_table(*sgt, 1, GFP_KERNEL); @@ -1172,7 +1172,7 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, struct amdgpu_ttm_tt *gtt; enum ttm_caching caching; - gtt = kzalloc(sizeof(struct amdgpu_ttm_tt), GFP_KERNEL); + gtt = kzalloc_obj(struct amdgpu_ttm_tt); if (!gtt) return NULL; @@ -1213,7 +1213,7 @@ static int amdgpu_ttm_tt_populate(struct ttm_device *bdev, /* user pages are bound by amdgpu_ttm_tt_pin_userptr() */ if (gtt->userptr) { - ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + ttm->sg = kzalloc_obj(struct sg_table); if (!ttm->sg) return -ENOMEM; return 0; @@ -1880,9 +1880,8 @@ static int amdgpu_ttm_pools_init(struct amdgpu_device *adev) if (!adev->gmc.is_app_apu || !adev->gmc.num_mem_partitions) return 0; - adev->mman.ttm_pools = kcalloc(adev->gmc.num_mem_partitions, - sizeof(*adev->mman.ttm_pools), - GFP_KERNEL); + adev->mman.ttm_pools = kzalloc_objs(*adev->mman.ttm_pools, + adev->gmc.num_mem_partitions); if (!adev->mman.ttm_pools) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c index 3f0b0e9af4f3..4df0f9d5ad11 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_umc.c @@ -58,8 +58,8 @@ int amdgpu_umc_page_retirement_mca(struct amdgpu_device *adev, return ret; err_data.err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); + kzalloc_objs(struct eeprom_table_record, + adev->umc.max_ras_err_cnt_per_query); if (!err_data.err_addr) { dev_warn(adev->dev, "Failed to alloc memory for umc error record in MCA notifier!\n"); @@ -105,8 +105,8 @@ void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev, amdgpu_ras_get_error_query_mode(adev, &error_query_mode); err_data->err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); + kzalloc_objs(struct eeprom_table_record, + adev->umc.max_ras_err_cnt_per_query); /* still call query_ras_error_address to clear error status * even NOMEM error is encountered @@ -131,8 +131,8 @@ void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev, adev->umc.ras->ras_block.hw_ops->query_ras_error_address && adev->umc.max_ras_err_cnt_per_query) { err_data->err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); + kzalloc_objs(struct eeprom_table_record, + adev->umc.max_ras_err_cnt_per_query); /* still call query_ras_error_address to clear error status * even NOMEM error is encountered @@ -161,8 +161,8 @@ void amdgpu_umc_handle_bad_pages(struct amdgpu_device *adev, adev->umc.ras->ecc_info_query_ras_error_address && adev->umc.max_ras_err_cnt_per_query) { err_data->err_addr = - kcalloc(adev->umc.max_ras_err_cnt_per_query, - sizeof(struct eeprom_table_record), GFP_KERNEL); + kzalloc_objs(struct eeprom_table_record, + adev->umc.max_ras_err_cnt_per_query); /* still call query_ras_error_address to clear error status * even NOMEM error is encountered @@ -551,8 +551,8 @@ int amdgpu_umc_lookup_bad_pages_in_a_row(struct amdgpu_device *adev, int i, ret; struct ras_err_data err_data; - err_data.err_addr = kcalloc(adev->umc.retire_unit, - sizeof(struct eeprom_table_record), GFP_KERNEL); + err_data.err_addr = kzalloc_objs(struct eeprom_table_record, + adev->umc.retire_unit); if (!err_data.err_addr) { dev_warn(adev->dev, "Failed to alloc memory in bad page lookup!\n"); return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c index b700c2b91465..7c450350847d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c @@ -217,7 +217,7 @@ static int amdgpu_userq_buffer_va_list_add(struct amdgpu_usermode_queue *queue, struct amdgpu_userq_va_cursor *va_cursor; struct userq_va_list; - va_cursor = kzalloc(sizeof(*va_cursor), GFP_KERNEL); + va_cursor = kzalloc_obj(*va_cursor); if (!va_cursor) return -ENOMEM; @@ -446,8 +446,7 @@ static int amdgpu_userq_wait_for_last_fence(struct amdgpu_usermode_queue *queue) return ret; } -static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, - int queue_id) +static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue) { struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr; struct amdgpu_device *adev = uq_mgr->adev; @@ -461,7 +460,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, uq_funcs->mqd_destroy(queue); amdgpu_userq_fence_driver_free(queue); /* Use interrupt-safe locking since IRQ handlers may access these XArrays */ - xa_erase_irq(&uq_mgr->userq_xa, (unsigned long)queue_id); xa_erase_irq(&adev->userq_doorbell_xa, queue->doorbell_index); queue->userq_mgr = NULL; list_del(&queue->userq_va_list); @@ -470,12 +468,6 @@ static void amdgpu_userq_cleanup(struct amdgpu_usermode_queue *queue, up_read(&adev->reset_domain->sem); } -static struct amdgpu_usermode_queue * -amdgpu_userq_find(struct amdgpu_userq_mgr *uq_mgr, int qid) -{ - return xa_load(&uq_mgr->userq_xa, qid); -} - void amdgpu_userq_ensure_ev_fence(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_eviction_fence_mgr *evf_mgr) @@ -625,22 +617,13 @@ amdgpu_userq_get_doorbell_index(struct amdgpu_userq_mgr *uq_mgr, } static int -amdgpu_userq_destroy(struct drm_file *filp, int queue_id) +amdgpu_userq_destroy(struct amdgpu_userq_mgr *uq_mgr, struct amdgpu_usermode_queue *queue) { - struct amdgpu_fpriv *fpriv = filp->driver_priv; - struct amdgpu_userq_mgr *uq_mgr = &fpriv->userq_mgr; struct amdgpu_device *adev = uq_mgr->adev; - struct amdgpu_usermode_queue *queue; int r = 0; cancel_delayed_work_sync(&uq_mgr->resume_work); mutex_lock(&uq_mgr->userq_mutex); - queue = amdgpu_userq_find(uq_mgr, queue_id); - if (!queue) { - drm_dbg_driver(adev_to_drm(uq_mgr->adev), "Invalid queue id to destroy\n"); - mutex_unlock(&uq_mgr->userq_mutex); - return -EINVAL; - } amdgpu_userq_wait_for_last_fence(queue); /* Cancel any pending hang detection work and cleanup */ if (queue->hang_detect_fence) { @@ -672,7 +655,7 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) drm_warn(adev_to_drm(uq_mgr->adev), "trying to destroy a HW mapping userq\n"); queue->state = AMDGPU_USERQ_STATE_HUNG; } - amdgpu_userq_cleanup(queue, queue_id); + amdgpu_userq_cleanup(queue); mutex_unlock(&uq_mgr->userq_mutex); pm_runtime_put_autosuspend(adev_to_drm(adev)->dev); @@ -680,6 +663,37 @@ amdgpu_userq_destroy(struct drm_file *filp, int queue_id) return r; } +static void amdgpu_userq_kref_destroy(struct kref *kref) +{ + int r; + struct amdgpu_usermode_queue *queue = + container_of(kref, struct amdgpu_usermode_queue, refcount); + struct amdgpu_userq_mgr *uq_mgr = queue->userq_mgr; + + r = amdgpu_userq_destroy(uq_mgr, queue); + if (r) + drm_file_err(uq_mgr->file, "Failed to destroy usermode queue %d\n", r); +} + +struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid) +{ + struct amdgpu_usermode_queue *queue; + + xa_lock(&uq_mgr->userq_xa); + queue = xa_load(&uq_mgr->userq_xa, qid); + if (queue) + kref_get(&queue->refcount); + xa_unlock(&uq_mgr->userq_xa); + + return queue; +} + +void amdgpu_userq_put(struct amdgpu_usermode_queue *queue) +{ + if (queue) + kref_put(&queue->refcount, amdgpu_userq_kref_destroy); +} + static int amdgpu_userq_priority_permit(struct drm_file *filp, int priority) { @@ -781,7 +795,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) goto unlock; } - queue = kzalloc(sizeof(struct amdgpu_usermode_queue), GFP_KERNEL); + queue = kzalloc_obj(struct amdgpu_usermode_queue); if (!queue) { drm_file_err(uq_mgr->file, "Failed to allocate memory for queue\n"); r = -ENOMEM; @@ -834,6 +848,9 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) goto unlock; } + /* drop this refcount during queue destroy */ + kref_init(&queue->refcount); + /* Wait for mode-1 reset to complete */ down_read(&adev->reset_domain->sem); r = xa_err(xa_store_irq(&adev->userq_doorbell_xa, index, queue, GFP_KERNEL)); @@ -985,7 +1002,9 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) { union drm_amdgpu_userq *args = data; - int r; + struct amdgpu_fpriv *fpriv = filp->driver_priv; + struct amdgpu_usermode_queue *queue; + int r = 0; if (!amdgpu_userq_enabled(dev)) return -ENOTSUPP; @@ -1000,11 +1019,16 @@ int amdgpu_userq_ioctl(struct drm_device *dev, void *data, drm_file_err(filp, "Failed to create usermode queue\n"); break; - case AMDGPU_USERQ_OP_FREE: - r = amdgpu_userq_destroy(filp, args->in.queue_id); - if (r) - drm_file_err(filp, "Failed to destroy usermode queue\n"); + case AMDGPU_USERQ_OP_FREE: { + xa_lock(&fpriv->userq_mgr.userq_xa); + queue = __xa_erase(&fpriv->userq_mgr.userq_xa, args->in.queue_id); + xa_unlock(&fpriv->userq_mgr.userq_xa); + if (!queue) + return -ENOENT; + + amdgpu_userq_put(queue); break; + } default: drm_dbg_driver(dev, "Invalid user queue op specified: %d\n", args->in.op); @@ -1023,16 +1047,23 @@ amdgpu_userq_restore_all(struct amdgpu_userq_mgr *uq_mgr) /* Resume all the queues for this process */ xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { + queue = amdgpu_userq_get(uq_mgr, queue_id); + if (!queue) + continue; + if (!amdgpu_userq_buffer_vas_mapped(queue)) { drm_file_err(uq_mgr->file, "trying restore queue without va mapping\n"); queue->state = AMDGPU_USERQ_STATE_INVALID_VA; + amdgpu_userq_put(queue); continue; } r = amdgpu_userq_restore_helper(queue); if (r) ret = r; + + amdgpu_userq_put(queue); } if (ret) @@ -1266,9 +1297,13 @@ amdgpu_userq_evict_all(struct amdgpu_userq_mgr *uq_mgr) amdgpu_userq_detect_and_reset_queues(uq_mgr); /* Try to unmap all the queues in this process ctx */ xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { + queue = amdgpu_userq_get(uq_mgr, queue_id); + if (!queue) + continue; r = amdgpu_userq_preempt_helper(queue); if (r) ret = r; + amdgpu_userq_put(queue); } if (ret) @@ -1301,16 +1336,24 @@ amdgpu_userq_wait_for_signal(struct amdgpu_userq_mgr *uq_mgr) int ret; xa_for_each(&uq_mgr->userq_xa, queue_id, queue) { + queue = amdgpu_userq_get(uq_mgr, queue_id); + if (!queue) + continue; + struct dma_fence *f = queue->last_fence; - if (!f || dma_fence_is_signaled(f)) + if (!f || dma_fence_is_signaled(f)) { + amdgpu_userq_put(queue); continue; + } ret = dma_fence_wait_timeout(f, true, msecs_to_jiffies(100)); if (ret <= 0) { drm_file_err(uq_mgr->file, "Timed out waiting for fence=%llu:%llu\n", f->context, f->seqno); + amdgpu_userq_put(queue); return -ETIMEDOUT; } + amdgpu_userq_put(queue); } return 0; @@ -1361,20 +1404,23 @@ int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *f void amdgpu_userq_mgr_fini(struct amdgpu_userq_mgr *userq_mgr) { struct amdgpu_usermode_queue *queue; - unsigned long queue_id; + unsigned long queue_id = 0; - cancel_delayed_work_sync(&userq_mgr->resume_work); + for (;;) { + xa_lock(&userq_mgr->userq_xa); + queue = xa_find(&userq_mgr->userq_xa, &queue_id, ULONG_MAX, + XA_PRESENT); + if (queue) + __xa_erase(&userq_mgr->userq_xa, queue_id); + xa_unlock(&userq_mgr->userq_xa); - mutex_lock(&userq_mgr->userq_mutex); - amdgpu_userq_detect_and_reset_queues(userq_mgr); - xa_for_each(&userq_mgr->userq_xa, queue_id, queue) { - amdgpu_userq_wait_for_last_fence(queue); - amdgpu_userq_unmap_helper(queue); - amdgpu_userq_cleanup(queue, queue_id); + if (!queue) + break; + + amdgpu_userq_put(queue); } xa_destroy(&userq_mgr->userq_xa); - mutex_unlock(&userq_mgr->userq_mutex); mutex_destroy(&userq_mgr->userq_mutex); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h index 5845d8959034..736c1d38297c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h @@ -74,6 +74,7 @@ struct amdgpu_usermode_queue { struct dentry *debugfs_queue; struct delayed_work hang_detect_work; struct dma_fence *hang_detect_fence; + struct kref refcount; struct list_head userq_va_list; }; @@ -112,6 +113,9 @@ struct amdgpu_db_info { struct amdgpu_userq_obj *db_obj; }; +struct amdgpu_usermode_queue *amdgpu_userq_get(struct amdgpu_userq_mgr *uq_mgr, u32 qid); +void amdgpu_userq_put(struct amdgpu_usermode_queue *queue); + int amdgpu_userq_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); int amdgpu_userq_mgr_init(struct amdgpu_userq_mgr *userq_mgr, struct drm_file *file_priv, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c index 212056d4ddf0..5239b06b9ab0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq_fence.c @@ -35,6 +35,8 @@ static const struct dma_fence_ops amdgpu_userq_fence_ops; static struct kmem_cache *amdgpu_userq_fence_slab; +#define AMDGPU_USERQ_MAX_HANDLES (1U << 16) + int amdgpu_userq_fence_slab_init(void) { amdgpu_userq_fence_slab = kmem_cache_create("amdgpu_userq_fence", @@ -82,7 +84,7 @@ int amdgpu_userq_fence_driver_alloc(struct amdgpu_device *adev, unsigned long flags; int r; - fence_drv = kzalloc(sizeof(*fence_drv), GFP_KERNEL); + fence_drv = kzalloc_obj(*fence_drv); if (!fence_drv) return -ENOMEM; @@ -266,9 +268,8 @@ static int amdgpu_userq_fence_create(struct amdgpu_usermode_queue *userq, count++; userq_fence->fence_drv_array = - kvmalloc_array(count, - sizeof(struct amdgpu_userq_fence_driver *), - GFP_ATOMIC); + kvmalloc_objs(struct amdgpu_userq_fence_driver *, count, + GFP_ATOMIC); if (userq_fence->fence_drv_array) { xa_for_each(&userq->fence_drv_xa, index, stored_fence_drv) { @@ -465,7 +466,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, struct drm_amdgpu_userq_signal *args = data; struct drm_gem_object **gobj_write = NULL; struct drm_gem_object **gobj_read = NULL; - struct amdgpu_usermode_queue *queue; + struct amdgpu_usermode_queue *queue = NULL; struct amdgpu_userq_fence *userq_fence; struct drm_syncobj **syncobj = NULL; u32 *bo_handles_write, num_write_bo_handles; @@ -479,6 +480,11 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, if (!amdgpu_userq_enabled(dev)) return -ENOTSUPP; + if (args->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES || + args->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES || + args->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES) + return -EINVAL; + num_syncobj_handles = args->num_syncobj_handles; syncobj_handles = memdup_user(u64_to_user_ptr(args->syncobj_handles), size_mul(sizeof(u32), num_syncobj_handles)); @@ -547,7 +553,7 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, } /* Retrieve the user queue */ - queue = xa_load(&userq_mgr->userq_xa, args->queue_id); + queue = amdgpu_userq_get(userq_mgr, args->queue_id); if (!queue) { r = -ENOENT; goto put_gobj_write; @@ -642,6 +648,9 @@ int amdgpu_userq_signal_ioctl(struct drm_device *dev, void *data, free_syncobj_handles: kfree(syncobj_handles); + if (queue) + amdgpu_userq_put(queue); + return r; } @@ -654,7 +663,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, struct drm_amdgpu_userq_wait *wait_info = data; struct amdgpu_fpriv *fpriv = filp->driver_priv; struct amdgpu_userq_mgr *userq_mgr = &fpriv->userq_mgr; - struct amdgpu_usermode_queue *waitq; + struct amdgpu_usermode_queue *waitq = NULL; struct drm_gem_object **gobj_write; struct drm_gem_object **gobj_read; struct dma_fence **fences = NULL; @@ -665,6 +674,11 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, if (!amdgpu_userq_enabled(dev)) return -ENOTSUPP; + if (wait_info->num_syncobj_handles > AMDGPU_USERQ_MAX_HANDLES || + wait_info->num_bo_write_handles > AMDGPU_USERQ_MAX_HANDLES || + wait_info->num_bo_read_handles > AMDGPU_USERQ_MAX_HANDLES) + return -EINVAL; + num_read_bo_handles = wait_info->num_bo_read_handles; bo_handles_read = memdup_user(u64_to_user_ptr(wait_info->bo_read_handles), size_mul(sizeof(u32), num_read_bo_handles)); @@ -834,7 +848,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, dma_resv_for_each_fence(&resv_cursor, gobj_read[i]->resv, DMA_RESV_USAGE_READ, fence) { - if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) { + if (num_fences >= wait_info->num_fences) { r = -EINVAL; goto free_fences; } @@ -851,7 +865,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, dma_resv_for_each_fence(&resv_cursor, gobj_write[i]->resv, DMA_RESV_USAGE_WRITE, fence) { - if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) { + if (num_fences >= wait_info->num_fences) { r = -EINVAL; goto free_fences; } @@ -875,8 +889,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, goto free_fences; dma_fence_unwrap_for_each(f, &iter, fence) { - if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) { + if (num_fences >= wait_info->num_fences) { r = -EINVAL; + dma_fence_put(fence); goto free_fences; } @@ -899,8 +914,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, if (r) goto free_fences; - if (WARN_ON_ONCE(num_fences >= wait_info->num_fences)) { + if (num_fences >= wait_info->num_fences) { r = -EINVAL; + dma_fence_put(fence); goto free_fences; } @@ -913,7 +929,7 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, */ num_fences = dma_fence_dedup_array(fences, num_fences); - waitq = xa_load(&userq_mgr->userq_xa, wait_info->waitq_id); + waitq = amdgpu_userq_get(userq_mgr, wait_info->waitq_id); if (!waitq) { r = -EINVAL; goto free_fences; @@ -970,32 +986,14 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, r = -EFAULT; goto free_fences; } - - kfree(fences); - kfree(fence_info); } - drm_exec_fini(&exec); - for (i = 0; i < num_read_bo_handles; i++) - drm_gem_object_put(gobj_read[i]); - kfree(gobj_read); - - for (i = 0; i < num_write_bo_handles; i++) - drm_gem_object_put(gobj_write[i]); - kfree(gobj_write); - - kfree(timeline_points); - kfree(timeline_handles); - kfree(syncobj_handles); - kfree(bo_handles_write); - kfree(bo_handles_read); - - return 0; - free_fences: - while (num_fences-- > 0) - dma_fence_put(fences[num_fences]); - kfree(fences); + if (fences) { + while (num_fences-- > 0) + dma_fence_put(fences[num_fences]); + kfree(fences); + } free_fence_info: kfree(fence_info); exec_fini: @@ -1019,5 +1017,8 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data, free_bo_handles_read: kfree(bo_handles_read); + if (waitq) + amdgpu_userq_put(waitq); + return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c index f01f38509108..275745aa5829 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c @@ -294,15 +294,15 @@ static int amdgpu_virt_init_ras_err_handler_data(struct amdgpu_device *adev) void *bps = NULL; struct amdgpu_bo **bps_bo = NULL; - *data = kmalloc(sizeof(struct amdgpu_virt_ras_err_handler_data), GFP_KERNEL); + *data = kmalloc_obj(struct amdgpu_virt_ras_err_handler_data); if (!*data) goto data_failure; - bps = kmalloc_array(align_space, sizeof(*(*data)->bps), GFP_KERNEL); + bps = kmalloc_objs(*(*data)->bps, align_space); if (!bps) goto bps_failure; - bps_bo = kmalloc_array(align_space, sizeof(*(*data)->bps_bo), GFP_KERNEL); + bps_bo = kmalloc_objs(*(*data)->bps_bo, align_space); if (!bps_bo) goto bps_bo_failure; @@ -966,7 +966,7 @@ int amdgpu_virt_init_critical_region(struct amdgpu_device *adev) } /* Allocate for init_data_hdr */ - init_data_hdr = kzalloc(sizeof(struct amd_sriov_msg_init_data_header), GFP_KERNEL); + init_data_hdr = kzalloc_obj(struct amd_sriov_msg_init_data_header); if (!init_data_hdr) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index e548dc9708a2..5cef8cd14148 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -411,7 +411,7 @@ static struct drm_plane *amdgpu_vkms_plane_init(struct drm_device *dev, struct drm_plane *plane; int ret; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -499,8 +499,8 @@ static int amdgpu_vkms_sw_init(struct amdgpu_ip_block *ip_block) int r, i; struct amdgpu_device *adev = ip_block->adev; - adev->amdgpu_vkms_output = kcalloc(adev->mode_info.num_crtc, - sizeof(struct amdgpu_vkms_output), GFP_KERNEL); + adev->amdgpu_vkms_output = kzalloc_objs(struct amdgpu_vkms_output, + adev->mode_info.num_crtc); if (!adev->amdgpu_vkms_output) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index e549accf96ba..f2beb980e3c3 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -1118,7 +1118,7 @@ int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm, if (!drm_dev_enter(adev_to_drm(adev), &idx)) return -ENODEV; - tlb_cb = kmalloc(sizeof(*tlb_cb), GFP_KERNEL); + tlb_cb = kmalloc_obj(*tlb_cb); if (!tlb_cb) { drm_dev_exit(idx); return -ENOMEM; @@ -1471,7 +1471,7 @@ static void amdgpu_vm_add_prt_cb(struct amdgpu_device *adev, if (!adev->gmc.gmc_funcs->set_prt) return; - cb = kmalloc(sizeof(struct amdgpu_prt_cb), GFP_KERNEL); + cb = kmalloc_obj(struct amdgpu_prt_cb); if (!cb) { /* Last resort when we are OOM */ if (fence) @@ -1735,7 +1735,9 @@ struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev, { struct amdgpu_bo_va *bo_va; - bo_va = kzalloc(sizeof(struct amdgpu_bo_va), GFP_KERNEL); + amdgpu_vm_assert_locked(vm); + + bo_va = kzalloc_obj(struct amdgpu_bo_va); if (bo_va == NULL) { return NULL; } @@ -1864,7 +1866,7 @@ int amdgpu_vm_bo_map(struct amdgpu_device *adev, return -EINVAL; } - mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kmalloc_obj(*mapping); if (!mapping) return -ENOMEM; @@ -1911,7 +1913,7 @@ int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev, return r; /* Allocate all the needed memory */ - mapping = kmalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kmalloc_obj(*mapping); if (!mapping) return -ENOMEM; @@ -2031,12 +2033,12 @@ int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev, eaddr = saddr + (size - 1) / AMDGPU_GPU_PAGE_SIZE; /* Allocate all the needed memory */ - before = kzalloc(sizeof(*before), GFP_KERNEL); + before = kzalloc_obj(*before); if (!before) return -ENOMEM; INIT_LIST_HEAD(&before->list); - after = kzalloc(sizeof(*after), GFP_KERNEL); + after = kzalloc_obj(*after); if (!after) { kfree(before); return -ENOMEM; @@ -2360,26 +2362,9 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, unsigned max_bits) { unsigned int max_size = 1 << (max_bits - 30); - bool sys_5level_pgtable = false; unsigned int vm_size; uint64_t tmp; -#ifdef CONFIG_X86_64 - /* - * Refer to function configure_5level_paging() for details. - */ - sys_5level_pgtable = (native_read_cr4() & X86_CR4_LA57); -#endif - - /* - * If GPU supports 5-level page table, but system uses 4-level page table, - * then use 4-level page table on GPU - */ - if (max_level == 4 && !sys_5level_pgtable) { - min_vm_size = 256 * 1024; - max_level = 3; - } - /* adjust vm size first */ if (amdgpu_vm_size != -1) { vm_size = amdgpu_vm_size; @@ -2415,6 +2400,7 @@ void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size, } adev->vm_manager.max_pfn = (uint64_t)vm_size << 18; + adev->vm_manager.max_level = max_level; tmp = roundup_pow_of_two(adev->vm_manager.max_pfn); if (amdgpu_vm_block_size != -1) @@ -2547,7 +2533,7 @@ amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid) static int amdgpu_vm_create_task_info(struct amdgpu_vm *vm) { - vm->task_info = kzalloc(sizeof(struct amdgpu_task_info), GFP_KERNEL); + vm->task_info = kzalloc_obj(struct amdgpu_task_info); if (!vm->task_info) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h index 139642eacdd0..806d62ed61ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h @@ -456,6 +456,7 @@ struct amdgpu_vm_manager { bool concurrent_flush; uint64_t max_pfn; + uint32_t max_level; uint32_t num_level; uint32_t block_size; uint32_t fragment_size; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_tlb_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_tlb_fence.c index 5d26797356a3..82b8badde453 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_tlb_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm_tlb_fence.c @@ -80,7 +80,7 @@ void amdgpu_vm_tlb_fence_create(struct amdgpu_device *adev, struct amdgpu_vm *vm { struct amdgpu_tlb_fence *f; - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc_obj(*f); if (!f) { /* * We can't fail since the PDEs and PTEs are already updated, so diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index 9d934c07fa6b..6c9b3e21e15c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -340,7 +340,7 @@ int amdgpu_vram_mgr_reserve_range(struct amdgpu_vram_mgr *mgr, { struct amdgpu_vram_reservation *rsv; - rsv = kzalloc(sizeof(*rsv), GFP_KERNEL); + rsv = kzalloc_obj(*rsv); if (!rsv) return -ENOMEM; @@ -478,7 +478,7 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, tbo->page_alignment); } - vres = kzalloc(sizeof(*vres), GFP_KERNEL); + vres = kzalloc_obj(*vres); if (!vres) return -ENOMEM; @@ -684,7 +684,7 @@ int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev, int num_entries = 0; int i, r; - *sgt = kmalloc(sizeof(**sgt), GFP_KERNEL); + *sgt = kmalloc_obj(**sgt); if (!*sgt) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c index 73250ab45f20..cc5f4e01e38f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xcp.c @@ -334,7 +334,7 @@ int amdgpu_xcp_mgr_init(struct amdgpu_device *adev, int init_mode, if (!xcp_funcs || !xcp_funcs->get_ip_details) return -EINVAL; - xcp_mgr = kzalloc(sizeof(*xcp_mgr), GFP_KERNEL); + xcp_mgr = kzalloc_obj(*xcp_mgr); if (!xcp_mgr) return -ENOMEM; @@ -907,7 +907,7 @@ static void amdgpu_xcp_cfg_sysfs_init(struct amdgpu_device *adev) if (!adev->xcp_mgr) return; - xcp_cfg = kzalloc(sizeof(*xcp_cfg), GFP_KERNEL); + xcp_cfg = kzalloc_obj(*xcp_cfg); if (!xcp_cfg) return; xcp_cfg->xcp_mgr = adev->xcp_mgr; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c index aad530c46a9f..11e56df1d91b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_xgmi.c @@ -42,8 +42,6 @@ #define XGMI_STATE_DISABLE 0xD1 #define XGMI_STATE_LS0 0x81 -#define XGMI_LINK_ACTIVE 1 -#define XGMI_LINK_INACTIVE 0 static DEFINE_MUTEX(xgmi_mutex); @@ -365,9 +363,9 @@ int amdgpu_get_xgmi_link_status(struct amdgpu_device *adev, int global_link_num) return -ENOLINK; if ((xgmi_state_reg_val & 0xFF) == XGMI_STATE_LS0) - return XGMI_LINK_ACTIVE; + return AMDGPU_XGMI_LINK_ACTIVE; - return XGMI_LINK_INACTIVE; + return AMDGPU_XGMI_LINK_INACTIVE; } /** @@ -692,7 +690,7 @@ struct amdgpu_hive_info *amdgpu_get_xgmi_hive(struct amdgpu_device *adev) goto pro_end; } - hive = kzalloc(sizeof(*hive), GFP_KERNEL); + hive = kzalloc_obj(*hive); if (!hive) { dev_err(adev->dev, "XGMI: allocation failed\n"); ret = -ENOMEM; @@ -1176,7 +1174,7 @@ static int xgmi_v6_4_0_aca_bank_parser(struct aca_handle *handle, struct aca_ban switch (type) { case ACA_SMU_TYPE_UE: - if (ext_error_code != 0 && ext_error_code != 9) + if (ext_error_code != 0 && ext_error_code != 1 && ext_error_code != 9) count = 0ULL; bank->aca_err_type = ACA_ERROR_TYPE_UE; diff --git a/drivers/gpu/drm/amd/amdgpu/atom.c b/drivers/gpu/drm/amd/amdgpu/atom.c index 371ee82a8912..e4ce3029d3fb 100644 --- a/drivers/gpu/drm/amd/amdgpu/atom.c +++ b/drivers/gpu/drm/amd/amdgpu/atom.c @@ -1524,7 +1524,7 @@ struct atom_context *amdgpu_atom_parse(struct card_info *card, void *bios) { int base; struct atom_context *ctx = - kzalloc(sizeof(struct atom_context), GFP_KERNEL); + kzalloc_obj(struct atom_context); struct _ATOM_ROM_HEADER *atom_rom_header; struct _ATOM_MASTER_DATA_TABLE *master_table; struct _ATOM_FIRMWARE_INFO *atom_fw_info; diff --git a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c index 34644cab6cff..a1d05df0ac99 100644 --- a/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c +++ b/drivers/gpu/drm/amd/amdgpu/atombios_encoders.c @@ -191,7 +191,7 @@ void amdgpu_atombios_encoder_init_backlight(struct amdgpu_encoder *amdgpu_encode goto register_acpi_backlight; } - pdata = kmalloc(sizeof(struct amdgpu_backlight_privdata), GFP_KERNEL); + pdata = kmalloc_obj(struct amdgpu_backlight_privdata); if (!pdata) { DRM_ERROR("Memory allocation failed\n"); goto error; @@ -1980,7 +1980,7 @@ amdgpu_atombios_encoder_get_lcd_info(struct amdgpu_encoder *encoder) lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset); lvds = - kzalloc(sizeof(struct amdgpu_encoder_atom_dig), GFP_KERNEL); + kzalloc_obj(struct amdgpu_encoder_atom_dig); if (!lvds) return NULL; @@ -2107,7 +2107,7 @@ struct amdgpu_encoder_atom_dig * amdgpu_atombios_encoder_get_dig_info(struct amdgpu_encoder *amdgpu_encoder) { int encoder_enum = (amdgpu_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - struct amdgpu_encoder_atom_dig *dig = kzalloc(sizeof(struct amdgpu_encoder_atom_dig), GFP_KERNEL); + struct amdgpu_encoder_atom_dig *dig = kzalloc_obj(struct amdgpu_encoder_atom_dig); if (!dig) return NULL; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index 61302204e9b4..a7ffe10eea1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -1775,7 +1775,7 @@ static int dce_v10_0_afmt_init(struct amdgpu_device *adev) /* DCE10 has audio blocks tied to DIG encoders */ for (i = 0; i < adev->mode_info.num_dig; i++) { - adev->mode_info.afmt[i] = kzalloc(sizeof(struct amdgpu_afmt), GFP_KERNEL); + adev->mode_info.afmt[i] = kzalloc_obj(struct amdgpu_afmt); if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; @@ -3516,7 +3516,7 @@ static void dce_v10_0_encoder_add(struct amdgpu_device *adev, } /* add a new one */ - amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder), GFP_KERNEL); + amdgpu_encoder = kzalloc_obj(struct amdgpu_encoder); if (!amdgpu_encoder) return; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index 8f4b4c2e36b9..a72e20db5363 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -1818,7 +1818,7 @@ static int dce_v6_0_afmt_init(struct amdgpu_device *adev) /* DCE6 has audio blocks tied to DIG encoders */ for (i = 0; i < adev->mode_info.num_dig; i++) { - adev->mode_info.afmt[i] = kzalloc(sizeof(struct amdgpu_afmt), GFP_KERNEL); + adev->mode_info.afmt[i] = kzalloc_obj(struct amdgpu_afmt); if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; @@ -3413,7 +3413,7 @@ static void dce_v6_0_encoder_add(struct amdgpu_device *adev, } /* add a new one */ - amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder), GFP_KERNEL); + amdgpu_encoder = kzalloc_obj(struct amdgpu_encoder); if (!amdgpu_encoder) return; diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 9d1853c41fcd..4221c7b7c506 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -1722,7 +1722,7 @@ static int dce_v8_0_afmt_init(struct amdgpu_device *adev) /* DCE8 has audio blocks tied to DIG encoders */ for (i = 0; i < adev->mode_info.num_dig; i++) { - adev->mode_info.afmt[i] = kzalloc(sizeof(struct amdgpu_afmt), GFP_KERNEL); + adev->mode_info.afmt[i] = kzalloc_obj(struct amdgpu_afmt); if (adev->mode_info.afmt[i]) { adev->mode_info.afmt[i]->offset = dig_offsets[i]; adev->mode_info.afmt[i]->id = i; @@ -3424,7 +3424,7 @@ static void dce_v8_0_encoder_add(struct amdgpu_device *adev, } /* add a new one */ - amdgpu_encoder = kzalloc(sizeof(struct amdgpu_encoder), GFP_KERNEL); + amdgpu_encoder = kzalloc_obj(struct amdgpu_encoder); if (!amdgpu_encoder) return; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index b2e87d3aa203..d25fdedb0d9f 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1064,8 +1064,7 @@ static int gmc_v7_0_sw_init(struct amdgpu_ip_block *ip_block) adev->vm_manager.vram_base_offset = 0; } - adev->gmc.vm_fault_info = kmalloc(sizeof(struct kfd_vm_fault_info), - GFP_KERNEL); + adev->gmc.vm_fault_info = kmalloc_obj(struct kfd_vm_fault_info); if (!adev->gmc.vm_fault_info) return -ENOMEM; atomic_set_release(&adev->gmc.vm_fault_info_updated, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 1d5bd90ac57f..4910e5557a67 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1179,8 +1179,7 @@ static int gmc_v8_0_sw_init(struct amdgpu_ip_block *ip_block) adev->vm_manager.vram_base_offset = 0; } - adev->gmc.vm_fault_info = kmalloc(sizeof(struct kfd_vm_fault_info), - GFP_KERNEL); + adev->gmc.vm_fault_info = kmalloc_obj(struct kfd_vm_fault_info); if (!adev->gmc.vm_fault_info) return -ENOMEM; atomic_set_release(&adev->gmc.vm_fault_info_updated, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c index 0027a639c7e6..3a2473655b6d 100644 --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_0.c @@ -50,7 +50,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) isp_base = adev->rmmio_base; - isp->isp_cell = kcalloc(3, sizeof(struct mfd_cell), GFP_KERNEL); + isp->isp_cell = kzalloc_objs(struct mfd_cell, 3); if (!isp->isp_cell) { r = -ENOMEM; drm_err(&adev->ddev, @@ -59,8 +59,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) } num_res = MAX_ISP410_MEM_RES + MAX_ISP410_INT_SRC; - isp->isp_res = kcalloc(num_res, sizeof(struct resource), - GFP_KERNEL); + isp->isp_res = kzalloc_objs(struct resource, num_res); if (!isp->isp_res) { r = -ENOMEM; drm_err(&adev->ddev, @@ -68,7 +67,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) goto failure; } - isp->isp_pdata = kzalloc(sizeof(*isp->isp_pdata), GFP_KERNEL); + isp->isp_pdata = kzalloc_obj(*isp->isp_pdata); if (!isp->isp_pdata) { r = -ENOMEM; drm_err(&adev->ddev, @@ -107,7 +106,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); /* initialize isp i2c platform data */ - isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); + isp->isp_i2c_res = kzalloc_objs(struct resource, 1); if (!isp->isp_i2c_res) { r = -ENOMEM; drm_err(&adev->ddev, @@ -127,7 +126,7 @@ static int isp_v4_1_0_hw_init(struct amdgpu_isp *isp) isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); /* initialize isp gpiochip platform data */ - isp->isp_gpio_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); + isp->isp_gpio_res = kzalloc_objs(struct resource, 1); if (!isp->isp_gpio_res) { r = -ENOMEM; drm_err(&adev->ddev, diff --git a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c index 0002bcc6c4ec..b3590b33cab9 100644 --- a/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c +++ b/drivers/gpu/drm/amd/amdgpu/isp_v4_1_1.c @@ -259,7 +259,7 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) return -EINVAL; } - isp->isp_cell = kcalloc(3, sizeof(struct mfd_cell), GFP_KERNEL); + isp->isp_cell = kzalloc_objs(struct mfd_cell, 3); if (!isp->isp_cell) { r = -ENOMEM; drm_err(&adev->ddev, "isp mfd cell alloc failed (%d)\n", r); @@ -268,15 +268,14 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) num_res = MAX_ISP411_MEM_RES + MAX_ISP411_INT_SRC; - isp->isp_res = kcalloc(num_res, sizeof(struct resource), - GFP_KERNEL); + isp->isp_res = kzalloc_objs(struct resource, num_res); if (!isp->isp_res) { r = -ENOMEM; drm_err(&adev->ddev, "isp mfd resource alloc failed (%d)\n", r); goto failure; } - isp->isp_pdata = kzalloc(sizeof(*isp->isp_pdata), GFP_KERNEL); + isp->isp_pdata = kzalloc_obj(*isp->isp_pdata); if (!isp->isp_pdata) { r = -ENOMEM; drm_err(&adev->ddev, "isp platform data alloc failed (%d)\n", r); @@ -318,7 +317,7 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) isp->isp_cell[0].pdata_size = sizeof(struct isp_platform_data); /* initialize isp i2c platform data */ - isp->isp_i2c_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); + isp->isp_i2c_res = kzalloc_objs(struct resource, 1); if (!isp->isp_i2c_res) { r = -ENOMEM; drm_err(&adev->ddev, "isp mfd res alloc failed (%d)\n", r); @@ -337,7 +336,7 @@ static int isp_v4_1_1_hw_init(struct amdgpu_isp *isp) isp->isp_cell[1].pdata_size = sizeof(struct isp_platform_data); /* initialize isp gpiochip platform data */ - isp->isp_gpio_res = kcalloc(1, sizeof(struct resource), GFP_KERNEL); + isp->isp_gpio_res = kzalloc_objs(struct resource, 1); if (!isp->isp_gpio_res) { r = -ENOMEM; drm_err(&adev->ddev, "isp gpio resource alloc failed (%d)\n", r); diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c index 9508709abd49..8c74894254f7 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c @@ -283,7 +283,7 @@ static int mes_userq_mqd_create(struct amdgpu_usermode_queue *queue, int r; /* Structure to initialize MQD for userqueue using generic MQD init function */ - userq_props = kzalloc(sizeof(struct amdgpu_mqd_prop), GFP_KERNEL); + userq_props = kzalloc_obj(struct amdgpu_mqd_prop); if (!userq_props) { DRM_ERROR("Failed to allocate memory for userq_props\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c index 09ebb13ca5e8..a926a330700e 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -720,11 +720,6 @@ static int mes_v11_0_set_hw_resources(struct amdgpu_mes *mes) mes_set_hw_res_pkt.enable_reg_active_poll = 1; mes_set_hw_res_pkt.enable_level_process_quantum_check = 1; mes_set_hw_res_pkt.oversubscription_timer = 50; - if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x7f) - mes_set_hw_res_pkt.enable_lr_compute_wa = 1; - else - dev_info_once(mes->adev->dev, - "MES FW version must be >= 0x7f to enable LR compute workaround.\n"); if (amdgpu_mes_log_enable) { mes_set_hw_res_pkt.enable_mes_event_int_logging = 1; diff --git a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c index b1c864dc79a8..023c7345ea54 100644 --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c @@ -731,6 +731,9 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) int i; struct amdgpu_device *adev = mes->adev; union MESAPI_SET_HW_RESOURCES mes_set_hw_res_pkt; + uint32_t mes_rev = (pipe == AMDGPU_MES_SCHED_PIPE) ? + (mes->sched_version & AMDGPU_MES_VERSION_MASK) : + (mes->kiq_version & AMDGPU_MES_VERSION_MASK); memset(&mes_set_hw_res_pkt, 0, sizeof(mes_set_hw_res_pkt)); @@ -779,18 +782,13 @@ static int mes_v12_0_set_hw_resources(struct amdgpu_mes *mes, int pipe) mes_set_hw_res_pkt.use_different_vmid_compute = 1; mes_set_hw_res_pkt.enable_reg_active_poll = 1; mes_set_hw_res_pkt.enable_level_process_quantum_check = 1; - if ((mes->adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x82) - mes_set_hw_res_pkt.enable_lr_compute_wa = 1; - else - dev_info_once(adev->dev, - "MES FW version must be >= 0x82 to enable LR compute workaround.\n"); /* * Keep oversubscribe timer for sdma . When we have unmapped doorbell * handling support, other queue will not use the oversubscribe timer. * handling mode - 0: disabled; 1: basic version; 2: basic+ version */ - mes_set_hw_res_pkt.oversubscription_timer = 50; + mes_set_hw_res_pkt.oversubscription_timer = mes_rev < 0x8b ? 0 : 50; mes_set_hw_res_pkt.unmapped_doorbell_handling = 1; if (amdgpu_mes_log_enable) { diff --git a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c index 7e917eb47a8c..a72770e3d0e9 100644 --- a/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mmhub_v4_2_0.c @@ -395,7 +395,10 @@ static void mmhub_v4_2_0_mid_enable_system_domain(struct amdgpu_device *adev, tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, ENABLE_CONTEXT, 1); tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, - PAGE_TABLE_DEPTH, 0); + PAGE_TABLE_DEPTH, adev->gmc.vmid0_page_table_depth); + tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, + PAGE_TABLE_BLOCK_SIZE, + adev->gmc.vmid0_page_table_block_size); tmp = REG_SET_FIELD(tmp, MMVM_CONTEXT0_CNTL, RETRY_PERMISSION_OR_INVALID_PAGE_FAULT, 0); WREG32_SOC15(MMHUB, GET_INST(MMHUB, i), diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index af4a7d7c4abd..d1e1a4369521 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -57,6 +57,8 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_12_sos.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_12_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_14_sos.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_14_ta.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_15_sos.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_15_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_0_toc.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_0_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_14_0_1_toc.bin"); @@ -121,6 +123,7 @@ static int psp_v13_0_init_microcode(struct psp_context *psp) case IP_VERSION(13, 0, 10): case IP_VERSION(13, 0, 12): case IP_VERSION(13, 0, 14): + case IP_VERSION(13, 0, 15): err = psp_init_sos_microcode(psp, ucode_prefix); if (err) return err; @@ -156,7 +159,8 @@ static void psp_v13_0_bootloader_print_status(struct psp_context *psp, if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) { + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) { at = 0; for_each_inst(i, adev->aid_mask) { bl_status_reg = @@ -202,7 +206,8 @@ static int psp_v13_0_wait_for_bootloader(struct psp_context *psp) retry_cnt = ((amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14))) ? + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15))) ? PSP_VMBX_POLLING_LIMIT : 10; /* Wait for bootloader to signify that it is ready having bit 31 of @@ -232,7 +237,8 @@ static int psp_v13_0_wait_for_bootloader_steady_state(struct psp_context *psp) if (amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) { + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) { ret = psp_v13_0_wait_for_vmbx_ready(psp); if (ret) amdgpu_ras_query_boot_status(adev, 4); @@ -872,7 +878,8 @@ static bool psp_v13_0_get_ras_capability(struct psp_context *psp) if ((amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 6) || amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 12) || - amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14)) && + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 14) || + amdgpu_ip_version(adev, MP0_HWIP, 0) == IP_VERSION(13, 0, 15)) && (!(adev->flags & AMD_IS_APU))) { reg_data = RREG32_SOC15(MP0, 0, regMP0_SMN_C2PMSG_127); adev->ras_hw_enabled = (reg_data & GENMASK_ULL(23, 0)); diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c index 3aca293e2f0c..73a709773e85 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0.c @@ -45,6 +45,10 @@ static int psp_v15_0_0_init_microcode(struct psp_context *psp) if (err) return err; + err = psp_init_ta_microcode(psp, ucode_prefix); + if (err) + return err; + return 0; } @@ -65,12 +69,12 @@ static int psp_v15_0_0_ring_stop(struct psp_context *psp, 0x80000000, 0x80000000, false); } else { /* Write the ring destroy command*/ - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64, + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64, GFX_CTRL_CMD_ID_DESTROY_RINGS); /* there might be handshake issue with hardware which needs delay */ mdelay(20); /* Wait for response flag (bit 31) */ - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64), + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64), 0x80000000, 0x80000000, false); } @@ -112,7 +116,7 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp, } else { /* Wait for sOS ready for ring creation */ - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64), + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64), 0x80000000, 0x80000000, false); if (ret) { DRM_ERROR("Failed to wait for trust OS ready for ring creation\n"); @@ -121,23 +125,23 @@ static int psp_v15_0_0_ring_create(struct psp_context *psp, /* Write low address of the ring to C2PMSG_69 */ psp_ring_reg = lower_32_bits(ring->ring_mem_mc_addr); - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_69, psp_ring_reg); + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_69, psp_ring_reg); /* Write high address of the ring to C2PMSG_70 */ psp_ring_reg = upper_32_bits(ring->ring_mem_mc_addr); - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_70, psp_ring_reg); + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_70, psp_ring_reg); /* Write size of ring to C2PMSG_71 */ psp_ring_reg = ring->ring_size; - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_71, psp_ring_reg); + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_71, psp_ring_reg); /* Write the ring initialization command to C2PMSG_64 */ psp_ring_reg = ring_type; psp_ring_reg = psp_ring_reg << 16; - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_64, psp_ring_reg); + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64, psp_ring_reg); /* there might be handshake issue with hardware which needs delay */ mdelay(20); /* Wait for response flag (bit 31) in C2PMSG_64 */ - ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_SMN_C2PMSG_64), + ret = psp_wait_for(psp, SOC15_REG_OFFSET(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_64), 0x80000000, 0x8000FFFF, false); } @@ -170,7 +174,7 @@ static uint32_t psp_v15_0_0_ring_get_wptr(struct psp_context *psp) if (amdgpu_sriov_vf(adev)) data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_102); else - data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67); + data = RREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67); return data; } @@ -184,7 +188,7 @@ static void psp_v15_0_0_ring_set_wptr(struct psp_context *psp, uint32_t value) WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_101, GFX_CTRL_CMD_ID_CONSUME_CMD); } else - WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value); + WREG32_SOC15(MP0, 0, regMPASP_PCRU1_MPASP_C2PMSG_67, value); } static const struct psp_funcs psp_v15_0_0_funcs = { diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v15_0_8.c b/drivers/gpu/drm/amd/amdgpu/psp_v15_0_8.c index 5249f5bd2a10..b2d7cbd894c0 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v15_0_8.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v15_0_8.c @@ -187,6 +187,26 @@ static void psp_v15_0_8_ring_set_wptr(struct psp_context *psp, uint32_t value) WREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_67, value); } +static bool psp_v15_0_8_get_ras_capability(struct psp_context *psp) +{ + struct amdgpu_device *adev = psp->adev; + struct amdgpu_ras *con = amdgpu_ras_get_context(adev); + u32 reg_data; + + /* query ras cap should be done from host side */ + if (amdgpu_sriov_vf(adev)) + return false; + + if (!con) + return false; + + reg_data = RREG32_SOC15(MP0, 0, regMPASP_SMN_C2PMSG_127); + adev->ras_hw_enabled = (reg_data & GENMASK_ULL(23, 0)); + con->poison_supported = ((reg_data & GENMASK_ULL(24, 24)) >> 24) ? true : false; + + return true; +} + static int psp_v15_0_8_get_fw_type(struct amdgpu_firmware_info *ucode, enum psp_gfx_fw_type *type) { @@ -334,6 +354,7 @@ static const struct psp_funcs psp_v15_0_8_funcs = { .ring_get_wptr = psp_v15_0_8_ring_get_wptr, .ring_set_wptr = psp_v15_0_8_ring_set_wptr, .get_fw_type = psp_v15_0_8_get_fw_type, + .get_ras_capability = psp_v15_0_8_get_ras_capability, }; void psp_v15_0_8_set_psp_funcs(struct psp_context *psp) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index e77e079fe833..e3a035c9fece 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -1424,18 +1424,9 @@ static int sdma_v5_0_sw_init(struct amdgpu_ip_block *ip_block) adev->sdma.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); - switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { - case IP_VERSION(5, 0, 0): - case IP_VERSION(5, 0, 2): - case IP_VERSION(5, 0, 5): - if ((adev->sdma.instance[0].fw_version >= 35) && - !amdgpu_sriov_vf(adev) && - !adev->debug_disable_gpu_ring_reset) - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; - break; - default: - break; - } + if (!amdgpu_sriov_vf(adev) && + !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; /* Allocate memory for SDMA IP Dump buffer */ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 50b51965c211..feebaa8cd9b1 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -1342,25 +1342,9 @@ static int sdma_v5_2_sw_init(struct amdgpu_ip_block *ip_block) adev->sdma.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); - switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { - case IP_VERSION(5, 2, 0): - case IP_VERSION(5, 2, 2): - case IP_VERSION(5, 2, 3): - case IP_VERSION(5, 2, 4): - if ((adev->sdma.instance[0].fw_version >= 76) && - !amdgpu_sriov_vf(adev) && - !adev->debug_disable_gpu_ring_reset) - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; - break; - case IP_VERSION(5, 2, 5): - if ((adev->sdma.instance[0].fw_version >= 34) && - !amdgpu_sriov_vf(adev) && - !adev->debug_disable_gpu_ring_reset) - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; - break; - default: - break; - } + if (!amdgpu_sriov_vf(adev) && + !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; /* Allocate memory for SDMA IP Dump buffer */ ptr = kcalloc(adev->sdma.num_instances * reg_count, sizeof(uint32_t), GFP_KERNEL); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c index eec659194718..b40126f5d3ef 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c @@ -1364,18 +1364,9 @@ static int sdma_v6_0_sw_init(struct amdgpu_ip_block *ip_block) adev->sdma.supported_reset = amdgpu_get_soft_full_reset_mask(&adev->sdma.instance[0].ring); - switch (amdgpu_ip_version(adev, SDMA0_HWIP, 0)) { - case IP_VERSION(6, 0, 0): - case IP_VERSION(6, 0, 2): - case IP_VERSION(6, 0, 3): - if ((adev->sdma.instance[0].fw_version >= 21) && - !amdgpu_sriov_vf(adev) && - !adev->debug_disable_gpu_ring_reset) - adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; - break; - default: - break; - } + if (!amdgpu_sriov_vf(adev) && + !adev->debug_disable_gpu_ring_reset) + adev->sdma.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE; if (amdgpu_sdma_ras_sw_init(adev)) { dev_err(adev->dev, "Failed to initialize sdma ras block!\n"); diff --git a/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c b/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c index 2594467bdd87..cb58032109e2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c +++ b/drivers/gpu/drm/amd/amdgpu/sienna_cichlid.c @@ -273,7 +273,7 @@ int sienna_cichlid_reset_init(struct amdgpu_device *adev) { struct amdgpu_reset_control *reset_ctl; - reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL); + reset_ctl = kzalloc_obj(*reset_ctl); if (!reset_ctl) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c index 70569ea906bc..11a574e8d3d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c +++ b/drivers/gpu/drm/amd/amdgpu/smu_v13_0_10.c @@ -270,7 +270,7 @@ int smu_v13_0_10_reset_init(struct amdgpu_device *adev) { struct amdgpu_reset_control *reset_ctl; - reset_ctl = kzalloc(sizeof(*reset_ctl), GFP_KERNEL); + reset_ctl = kzalloc_obj(*reset_ctl); if (!reset_ctl) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/soc15.c b/drivers/gpu/drm/amd/amdgpu/soc15.c index 54b14751fd7a..4e037a6978f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc15.c +++ b/drivers/gpu/drm/amd/amdgpu/soc15.c @@ -1478,7 +1478,8 @@ static void soc15_common_get_clockgating_state(struct amdgpu_ip_block *ip_block, if ((amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 2)) && (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 6)) && (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 12)) && - (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 14))) { + (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 14)) && + (amdgpu_ip_version(adev, MP0_HWIP, 0) != IP_VERSION(13, 0, 15))) { /* AMD_CG_SUPPORT_DRM_MGCG */ data = RREG32(SOC15_REG_OFFSET(MP0, 0, mmMP0_MISC_CGTT_CTRL0)); if (!(data & 0x01000000)) diff --git a/drivers/gpu/drm/amd/amdgpu/soc21.c b/drivers/gpu/drm/amd/amdgpu/soc21.c index d9cc649d81ad..a0ad1f8a76f0 100644 --- a/drivers/gpu/drm/amd/amdgpu/soc21.c +++ b/drivers/gpu/drm/amd/amdgpu/soc21.c @@ -422,6 +422,7 @@ soc21_asic_reset_method(struct amdgpu_device *adev) case IP_VERSION(14, 0, 1): case IP_VERSION(14, 0, 4): case IP_VERSION(14, 0, 5): + case IP_VERSION(15, 0, 0): return AMD_RESET_METHOD_MODE2; default: if (amdgpu_dpm_is_baco_supported(adev)) @@ -838,9 +839,30 @@ static int soc21_common_early_init(struct amdgpu_ip_block *ip_block) break; case IP_VERSION(11, 5, 4): adev->cg_flags = AMD_CG_SUPPORT_VCN_MGCG | - AMD_CG_SUPPORT_JPEG_MGCG; - adev->pg_flags = AMD_PG_SUPPORT_VCN | - AMD_PG_SUPPORT_JPEG; + AMD_CG_SUPPORT_JPEG_MGCG | + AMD_CG_SUPPORT_GFX_CGCG | + AMD_CG_SUPPORT_GFX_CGLS | + AMD_CG_SUPPORT_GFX_MGCG | + AMD_CG_SUPPORT_GFX_FGCG | + AMD_CG_SUPPORT_REPEATER_FGCG | + AMD_CG_SUPPORT_GFX_PERF_CLK | + AMD_CG_SUPPORT_GFX_3D_CGCG | + AMD_CG_SUPPORT_GFX_3D_CGLS | + AMD_CG_SUPPORT_MC_MGCG | + AMD_CG_SUPPORT_MC_LS | + AMD_CG_SUPPORT_HDP_LS | + AMD_CG_SUPPORT_HDP_DS | + AMD_CG_SUPPORT_HDP_SD | + AMD_CG_SUPPORT_ATHUB_MGCG | + AMD_CG_SUPPORT_ATHUB_LS | + AMD_CG_SUPPORT_IH_CG | + AMD_CG_SUPPORT_BIF_MGCG | + AMD_CG_SUPPORT_BIF_LS; + adev->pg_flags = AMD_PG_SUPPORT_VCN_DPG | + AMD_PG_SUPPORT_VCN | + AMD_PG_SUPPORT_JPEG_DPG | + AMD_PG_SUPPORT_JPEG | + AMD_PG_SUPPORT_GFX_PG; adev->external_rev_id = adev->rev_id + 0x1; break; default: diff --git a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c index 0f5b1719fda5..1f80045775f5 100644 --- a/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/umc_v12_0.c @@ -567,7 +567,7 @@ static int umc_v12_0_update_ecc_status(struct amdgpu_device *adev, if (ret) return ret; - ecc_err = kzalloc(sizeof(*ecc_err), GFP_KERNEL); + ecc_err = kzalloc_obj(*ecc_err); if (!ecc_err) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index cebee453871c..006a15451197 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -521,7 +521,9 @@ static int vcn_v2_5_hw_fini(struct amdgpu_ip_block *ip_block) RREG32_SOC15(VCN, i, mmUVD_STATUS))) vinst->set_pg_state(vinst, AMD_PG_STATE_GATE); - if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) + /* VF doesn't enable interrupt operations for RAS */ + if (!amdgpu_sriov_vf(adev) && + amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) amdgpu_irq_put(adev, &vinst->ras_poison_irq, 0); } diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c index 0202df5db1e1..6109124f852e 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_0.c @@ -174,6 +174,10 @@ static int vcn_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block) fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE); fw_shared->sq.is_enabled = 1; + fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_SMU_DPM_INTERFACE_FLAG); + fw_shared->smu_dpm_interface.smu_interface_type = (adev->flags & AMD_IS_APU) ? + AMDGPU_VCN_SMU_DPM_INTERFACE_APU : AMDGPU_VCN_SMU_DPM_INTERFACE_DGPU; + if (amdgpu_vcnfw_log) amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 88621cb7d409..09dabb3b3297 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -780,8 +780,8 @@ static int kfd_ioctl_get_process_apertures_new(struct file *filp, * nodes, but not more than args->num_of_nodes as that is * the amount of memory allocated by user */ - pa = kcalloc(args->num_of_nodes, sizeof(struct kfd_process_device_apertures), - GFP_KERNEL); + pa = kzalloc_objs(struct kfd_process_device_apertures, + args->num_of_nodes); if (!pa) return -ENOMEM; @@ -2224,7 +2224,7 @@ static int criu_restore_devices(struct kfd_process *p, if (*priv_offset + (args->num_devices * sizeof(*device_privs)) > max_priv_data_size) return -EINVAL; - device_buckets = kmalloc_array(args->num_devices, sizeof(*device_buckets), GFP_KERNEL); + device_buckets = kmalloc_objs(*device_buckets, args->num_devices); if (!device_buckets) return -ENOMEM; @@ -2467,7 +2467,7 @@ static int criu_restore_bos(struct kfd_process *p, /* Prevent MMU notifications until stage-4 IOCTL (CRIU_RESUME) is received */ amdgpu_amdkfd_block_mmu_notifications(p->kgd_process_info); - bo_buckets = kvmalloc_array(args->num_bos, sizeof(*bo_buckets), GFP_KERNEL); + bo_buckets = kvmalloc_objs(*bo_buckets, args->num_bos); if (!bo_buckets) return -ENOMEM; @@ -2485,7 +2485,7 @@ static int criu_restore_bos(struct kfd_process *p, goto exit; } - bo_privs = kvmalloc_array(args->num_bos, sizeof(*bo_privs), GFP_KERNEL); + bo_privs = kvmalloc_objs(*bo_privs, args->num_bos); if (!bo_privs) { ret = -ENOMEM; goto exit; @@ -2804,8 +2804,12 @@ static int runtime_enable(struct kfd_process *p, uint64_t r_debug, * SET_SHADER_DEBUGGER clears any stale process context data * saved in MES. */ - if (pdd->dev->kfd->shared_resources.enable_mes) - kfd_dbg_set_mes_debug_mode(pdd, !kfd_dbg_has_cwsr_workaround(pdd->dev)); + if (pdd->dev->kfd->shared_resources.enable_mes) { + ret = kfd_dbg_set_mes_debug_mode( + pdd, !kfd_dbg_has_cwsr_workaround(pdd->dev)); + if (ret) + return ret; + } } p->runtime_info.runtime_state = DEBUG_RUNTIME_STATE_ENABLED; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c index 36ffc3c78536..a1087c13f241 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_crat.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_crat.c @@ -2359,7 +2359,7 @@ static int kfd_create_vcrat_image_gpu(void *pcrat_image, if (kdev->kfd->hive_id) { for (nid = 0; nid < proximity_domain; ++nid) { peer_dev = kfd_topology_device_by_proximity_domain_no_lock(nid); - if (!peer_dev->gpu) + if (!peer_dev || !peer_dev->gpu) continue; if (peer_dev->gpu->kfd->hive_id != kdev->kfd->hive_id) continue; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c index 8f8a0975f1a7..0f7aa51b629e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debug.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debug.c @@ -404,27 +404,25 @@ static int kfd_dbg_get_dev_watch_id(struct kfd_process_device *pdd, int *watch_i return -ENOMEM; } -static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, int watch_id) +static void kfd_dbg_clear_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) { spin_lock(&pdd->dev->watch_points_lock); /* process owns device watch point so safe to clear */ - if ((pdd->alloc_watch_ids >> watch_id) & 0x1) { - pdd->alloc_watch_ids &= ~(0x1 << watch_id); - pdd->dev->alloc_watch_ids &= ~(0x1 << watch_id); + if (pdd->alloc_watch_ids & BIT(watch_id)) { + pdd->alloc_watch_ids &= ~BIT(watch_id); + pdd->dev->alloc_watch_ids &= ~BIT(watch_id); } spin_unlock(&pdd->dev->watch_points_lock); } -static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, int watch_id) +static bool kfd_dbg_owns_dev_watch_id(struct kfd_process_device *pdd, u32 watch_id) { bool owns_watch_id = false; spin_lock(&pdd->dev->watch_points_lock); - owns_watch_id = watch_id < MAX_WATCH_ADDRESSES && - ((pdd->alloc_watch_ids >> watch_id) & 0x1); - + owns_watch_id = pdd->alloc_watch_ids & BIT(watch_id); spin_unlock(&pdd->dev->watch_points_lock); return owns_watch_id; @@ -435,6 +433,9 @@ int kfd_dbg_trap_clear_dev_address_watch(struct kfd_process_device *pdd, { int r; + if (watch_id >= MAX_WATCH_ADDRESSES) + return -EINVAL; + if (!kfd_dbg_owns_dev_watch_id(pdd, watch_id)) return -EINVAL; @@ -472,6 +473,9 @@ int kfd_dbg_trap_set_dev_address_watch(struct kfd_process_device *pdd, if (r) return r; + if (*watch_id >= MAX_WATCH_ADDRESSES) + return -EINVAL; + if (!pdd->dev->kfd->shared_resources.enable_mes) { r = debug_lock_and_unmap(pdd->dev->dqm); if (r) { @@ -519,10 +523,15 @@ int kfd_dbg_trap_set_flags(struct kfd_process *target, uint32_t *flags) int i, r = 0, rewind_count = 0; for (i = 0; i < target->n_pdds; i++) { + uint32_t caps; + uint32_t caps2; struct kfd_topology_device *topo_dev = - kfd_topology_device_by_id(target->pdds[i]->dev->id); - uint32_t caps = topo_dev->node_props.capability; - uint32_t caps2 = topo_dev->node_props.capability2; + kfd_topology_device_by_id(target->pdds[i]->dev->id); + if (!topo_dev) + return -EINVAL; + + caps = topo_dev->node_props.capability; + caps2 = topo_dev->node_props.capability2; if (!(caps & HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED) && (*flags & KFD_DBG_TRAP_FLAG_SINGLE_MEM_OP)) { @@ -575,9 +584,9 @@ int kfd_dbg_trap_set_flags(struct kfd_process *target, uint32_t *flags) continue; if (!pdd->dev->kfd->shared_resources.enable_mes) - debug_refresh_runlist(pdd->dev->dqm); + (void)debug_refresh_runlist(pdd->dev->dqm); else - kfd_dbg_set_mes_debug_mode(pdd, true); + (void)kfd_dbg_set_mes_debug_mode(pdd, true); } } @@ -637,9 +646,10 @@ void kfd_dbg_trap_deactivate(struct kfd_process *target, bool unwind, int unwind pr_err("Failed to release debug vmid on [%i]\n", pdd->dev->id); if (!pdd->dev->kfd->shared_resources.enable_mes) - debug_refresh_runlist(pdd->dev->dqm); + (void)debug_refresh_runlist(pdd->dev->dqm); else - kfd_dbg_set_mes_debug_mode(pdd, !kfd_dbg_has_cwsr_workaround(pdd->dev)); + (void)kfd_dbg_set_mes_debug_mode(pdd, + !kfd_dbg_has_cwsr_workaround(pdd->dev)); } kfd_dbg_set_workaround(target, false); @@ -1081,6 +1091,10 @@ int kfd_dbg_trap_device_snapshot(struct kfd_process *target, for (i = 0; i < tmp_num_devices; i++) { struct kfd_process_device *pdd = target->pdds[i]; struct kfd_topology_device *topo_dev = kfd_topology_device_by_id(pdd->dev->id); + if (!topo_dev) { + r = -EINVAL; + break; + } device_info.gpu_id = pdd->dev->id; device_info.exception_status = pdd->exception_status; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c index 9bde2c64540f..7d4e07452cdb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_debugfs.c @@ -146,7 +146,7 @@ void kfd_debugfs_add_process(struct kfd_process *p) char name[MAX_DEBUGFS_FILENAME_LEN]; struct debugfs_proc_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device.c b/drivers/gpu/drm/amd/amdkfd/kfd_device.c index 9a66ee661e57..8ff97bf7d95a 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device.c @@ -478,7 +478,7 @@ struct kfd_dev *kgd2kfd_probe(struct amdgpu_device *adev, bool vf) return NULL; } - kfd = kzalloc(sizeof(*kfd), GFP_KERNEL); + kfd = kzalloc_obj(*kfd); if (!kfd) return NULL; @@ -864,7 +864,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd, /* Allocate the KFD nodes */ for (i = 0, xcp_idx = 0; i < kfd->num_nodes; i++) { - node = kzalloc(sizeof(struct kfd_node), GFP_KERNEL); + node = kzalloc_obj(struct kfd_node); if (!node) goto node_alloc_error; @@ -1328,7 +1328,7 @@ int kfd_gtt_sa_allocate(struct kfd_node *node, unsigned int size, if (size > kfd->gtt_sa_num_of_chunks * kfd->gtt_sa_chunk_size) return -ENOMEM; - *mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); + *mem_obj = kzalloc_obj(struct kfd_mem_obj); if (!(*mem_obj)) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 804851632c4c..3ddf06c755b5 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -1401,7 +1401,7 @@ static int register_process(struct device_queue_manager *dqm, uint64_t pd_base; int retval; - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) return -ENOMEM; @@ -2921,7 +2921,7 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_node *dev) pr_debug("Loading device queue manager\n"); - dqm = kzalloc(sizeof(*dqm), GFP_KERNEL); + dqm = kzalloc_obj(*dqm); if (!dqm) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index 1ad312af8ff0..bafc7b699dcc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -67,7 +67,7 @@ static struct kfd_signal_page *allocate_signal_page(struct kfd_process *p) void *backing_store; struct kfd_signal_page *page; - page = kzalloc(sizeof(*page), GFP_KERNEL); + page = kzalloc_obj(*page); if (!page) return NULL; @@ -331,7 +331,13 @@ static int kfd_event_page_set(struct kfd_process *p, void *kernel_address, if (p->signal_page) return -EBUSY; - page = kzalloc(sizeof(*page), GFP_KERNEL); + if (size < KFD_SIGNAL_EVENT_LIMIT * 8) { + pr_err("Event page size %llu is too small, need at least %lu bytes\n", + size, (unsigned long)(KFD_SIGNAL_EVENT_LIMIT * 8)); + return -EINVAL; + } + + page = kzalloc_obj(*page); if (!page) return -ENOMEM; @@ -399,7 +405,7 @@ int kfd_event_create(struct file *devkfd, struct kfd_process *p, uint64_t *event_page_offset, uint32_t *event_slot_index) { int ret = 0; - struct kfd_event *ev = kzalloc(sizeof(*ev), GFP_KERNEL); + struct kfd_event *ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -452,11 +458,11 @@ int kfd_criu_restore_event(struct file *devkfd, struct kfd_event *ev = NULL; int ret = 0; - ev_priv = kmalloc(sizeof(*ev_priv), GFP_KERNEL); + ev_priv = kmalloc_obj(*ev_priv); if (!ev_priv) return -ENOMEM; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) { ret = -ENOMEM; goto exit; @@ -785,8 +791,7 @@ static struct kfd_event_waiter *alloc_event_waiters(uint32_t num_events) struct kfd_event_waiter *event_waiters; uint32_t i; - event_waiters = kcalloc(num_events, sizeof(struct kfd_event_waiter), - GFP_KERNEL); + event_waiters = kzalloc_objs(struct kfd_event_waiter, num_events); if (!event_waiters) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c index d987ff7ccfc9..3ffa081daaec 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c @@ -309,7 +309,7 @@ struct kernel_queue *kernel_queue_init(struct kfd_node *dev, { struct kernel_queue *kq; - kq = kzalloc(sizeof(*kq), GFP_KERNEL); + kq = kzalloc_obj(*kq); if (!kq) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index d88d0de58edd..723b725d20b8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c @@ -51,7 +51,7 @@ struct kfd_mem_obj *allocate_hiq_mqd(struct mqd_manager *mm, struct queue_proper struct kfd_mem_obj *mqd_mem_obj; struct kfd_node *dev = mm->dev; - mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); + mqd_mem_obj = kzalloc_obj(struct kfd_mem_obj); if (!mqd_mem_obj) return NULL; @@ -69,7 +69,7 @@ struct kfd_mem_obj *allocate_sdma_mqd(struct mqd_manager *mm, struct kfd_node *dev = mm->dev; uint64_t offset; - mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); + mqd_mem_obj = kzalloc_obj(struct kfd_mem_obj); if (!mqd_mem_obj) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c index 90ac3a30e81d..562d475cf4c9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c @@ -70,7 +70,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct cik_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -389,7 +389,7 @@ struct mqd_manager *mqd_manager_init_cik(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c index 97055f808d4a..d6067316d7f4 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v10.c @@ -70,7 +70,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v10_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -451,7 +451,7 @@ struct mqd_manager *mqd_manager_init_v10(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c index 7e5a7ab6d0c0..e3a7acb0ccbc 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c @@ -96,7 +96,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v11_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -465,7 +465,7 @@ struct mqd_manager *mqd_manager_init_v11(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c index a51f217329db..0b97376fc6f9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12.c @@ -77,7 +77,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v12_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -385,7 +385,7 @@ struct mqd_manager *mqd_manager_init_v12(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c index d0776ba2cc99..eef6bdce4be3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v12_1.c @@ -131,7 +131,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v12_1_compute_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -646,7 +646,7 @@ struct mqd_manager *mqd_manager_init_v12_1(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c index dcf4bbfa641b..d5c234f30e8d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v9.c @@ -106,11 +106,14 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct v9_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static bool mqd_on_vram(struct amdgpu_device *adev) { + if (adev->apu_prefer_gtt) + return false; + switch (amdgpu_ip_version(adev, GC_HWIP, 0)) { case IP_VERSION(9, 4, 3): case IP_VERSION(9, 5, 0): @@ -144,7 +147,7 @@ static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, * amdgpu memory functions to do so. */ if (node->kfd->cwsr_enabled && (q->type == KFD_QUEUE_TYPE_COMPUTE)) { - mqd_mem_obj = kzalloc(sizeof(struct kfd_mem_obj), GFP_KERNEL); + mqd_mem_obj = kzalloc_obj(struct kfd_mem_obj); if (!mqd_mem_obj) return NULL; retval = amdgpu_amdkfd_alloc_kernel_mem(node->adev, @@ -957,7 +960,7 @@ struct mqd_manager *mqd_manager_init_v9(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c index 09483f0862d4..69c1b8a690b8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_vi.c @@ -73,7 +73,7 @@ static void update_cu_mask(struct mqd_manager *mm, void *mqd, static void set_priority(struct vi_mqd *m, struct queue_properties *q) { m->cp_hqd_pipe_priority = pipe_priority_map[q->priority]; - m->cp_hqd_queue_priority = q->priority; + /* m->cp_hqd_queue_priority = q->priority; */ } static struct kfd_mem_obj *allocate_mqd(struct mqd_manager *mm, @@ -446,7 +446,7 @@ struct mqd_manager *mqd_manager_init_vi(enum KFD_MQD_TYPE type, if (WARN_ON(type >= KFD_MQD_TYPE_MAX)) return NULL; - mqd = kzalloc(sizeof(*mqd), GFP_KERNEL); + mqd = kzalloc_obj(*mqd); if (!mqd) return NULL; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index 9849b54f54ba..e5b56412931b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h @@ -91,7 +91,7 @@ /* Macro for allocating structures */ #define kfd_alloc_struct(ptr_to_struct) \ - ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL)) + ((typeof(ptr_to_struct)) kzalloc_obj(*ptr_to_struct)) #define KFD_MAX_NUM_OF_PROCESSES 512 #define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024 diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index 219d08f092db..12e24fbf8c46 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -153,7 +153,7 @@ static void kfd_sdma_activity_worker(struct work_struct *work) (q->properties.type != KFD_QUEUE_TYPE_SDMA_XGMI)) continue; - sdma_q = kzalloc(sizeof(struct temp_sdma_queue_list), GFP_KERNEL); + sdma_q = kzalloc_obj(struct temp_sdma_queue_list); if (!sdma_q) { dqm_unlock(dqm); goto cleanup; @@ -291,7 +291,7 @@ static int kfd_get_cu_occupancy(struct attribute *attr, char *buffer) wave_cnt = 0; max_waves_per_cu = 0; - cu_occupancy = kcalloc(AMDGPU_MAX_QUEUES, sizeof(*cu_occupancy), GFP_KERNEL); + cu_occupancy = kzalloc_objs(*cu_occupancy, AMDGPU_MAX_QUEUES); if (!cu_occupancy) return -ENOMEM; @@ -1592,7 +1592,7 @@ struct kfd_process *create_process(const struct task_struct *thread, bool primar struct mmu_notifier *mn; int err = -ENOMEM; - process = kzalloc(sizeof(*process), GFP_KERNEL); + process = kzalloc_obj(*process); if (!process) goto err_alloc_process; @@ -1708,7 +1708,7 @@ struct kfd_process_device *kfd_create_process_device_data(struct kfd_node *dev, if (WARN_ON_ONCE(p->n_pdds >= MAX_GPU_INSTANCE)) return NULL; - pdd = kzalloc(sizeof(*pdd), GFP_KERNEL); + pdd = kzalloc_obj(*pdd); if (!pdd) return NULL; @@ -1767,9 +1767,6 @@ int kfd_process_device_init_vm(struct kfd_process_device *pdd, struct kfd_node *dev; int ret; - if (!drm_file) - return -EINVAL; - if (pdd->drm_priv) return -EBUSY; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c index 449be58e884c..f5d2847e1cbb 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c @@ -383,7 +383,7 @@ int pqm_create_queue(struct process_queue_manager *pqm, memset(pdd->proc_ctx_cpu_ptr, 0, AMDGPU_MES_PROC_CTX_SIZE); } - pqn = kzalloc(sizeof(*pqn), GFP_KERNEL); + pqn = kzalloc_obj(*pqn); if (!pqn) { retval = -ENOMEM; goto err_allocate_pqn; @@ -593,6 +593,7 @@ int pqm_update_queue_properties(struct process_queue_manager *pqm, p->queue_size)) { pr_debug("ring buf 0x%llx size 0x%llx not mapped on GPU\n", p->queue_address, p->queue_size); + amdgpu_bo_unreserve(vm->root.bo); return -EFAULT; } @@ -991,7 +992,7 @@ int kfd_criu_restore_queue(struct kfd_process *p, if (*priv_data_offset + sizeof(*q_data) > max_priv_data_size) return -EINVAL; - q_data = kmalloc(sizeof(*q_data), GFP_KERNEL); + q_data = kmalloc_obj(*q_data); if (!q_data) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c index d1978e3f68be..bbe869ceae3f 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_queue.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_queue.c @@ -70,7 +70,7 @@ int init_queue(struct queue **q, const struct queue_properties *properties) { struct queue *tmp_q; - tmp_q = kzalloc(sizeof(*tmp_q), GFP_KERNEL); + tmp_q = kzalloc_obj(*tmp_q); if (!tmp_q) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c index d2bc169e84b0..15975c23a88e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c @@ -370,7 +370,7 @@ int kfd_smi_event_open(struct kfd_node *dev, uint32_t *fd) struct kfd_smi_client *client; int ret; - client = kzalloc(sizeof(struct kfd_smi_client), GFP_KERNEL); + client = kzalloc_obj(struct kfd_smi_client); if (!client) return -ENOMEM; INIT_LIST_HEAD(&client->list); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c index fcddb54a439f..080242f9981b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c @@ -168,7 +168,7 @@ svm_range_dma_map_dev(struct amdgpu_device *adev, struct svm_range *prange, int i, r; if (!addr) { - addr = kvcalloc(prange->npages, sizeof(*addr), GFP_KERNEL); + addr = kvzalloc_objs(*addr, prange->npages); if (!addr) return -ENOMEM; prange->dma_addr[gpuidx] = addr; @@ -329,7 +329,7 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start, struct svm_range *prange; struct kfd_process *p; - prange = kzalloc(sizeof(*prange), GFP_KERNEL); + prange = kzalloc_obj(*prange); if (!prange) return NULL; @@ -539,7 +539,7 @@ static struct svm_range_bo *svm_range_bo_new(void) { struct svm_range_bo *svm_bo; - svm_bo = kzalloc(sizeof(*svm_bo), GFP_KERNEL); + svm_bo = kzalloc_obj(*svm_bo); if (!svm_bo) return NULL; @@ -1674,7 +1674,7 @@ static int svm_range_validate_and_map(struct mm_struct *mm, int32_t idx; int r = 0; - ctx = kzalloc(sizeof(struct svm_validate_context), GFP_KERNEL); + ctx = kzalloc_obj(struct svm_validate_context); if (!ctx) return -ENOMEM; ctx->process = container_of(prange->svms, struct kfd_process, svms); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index 1ccd4514d3ee..995f2c2528a9 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -711,7 +711,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, i = 0; list_for_each_entry(mem, &dev->mem_props, list) { - mem->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + mem->kobj = kzalloc_obj(struct kobject); if (!mem->kobj) return -ENOMEM; ret = kobject_init_and_add(mem->kobj, &mem_type, @@ -732,7 +732,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, i = 0; list_for_each_entry(cache, &dev->cache_props, list) { - cache->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + cache->kobj = kzalloc_obj(struct kobject); if (!cache->kobj) return -ENOMEM; ret = kobject_init_and_add(cache->kobj, &cache_type, @@ -753,7 +753,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, i = 0; list_for_each_entry(iolink, &dev->io_link_props, list) { - iolink->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + iolink->kobj = kzalloc_obj(struct kobject); if (!iolink->kobj) return -ENOMEM; ret = kobject_init_and_add(iolink->kobj, &iolink_type, @@ -774,7 +774,7 @@ static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev, i = 0; list_for_each_entry(p2plink, &dev->p2p_link_props, list) { - p2plink->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + p2plink->kobj = kzalloc_obj(struct kobject); if (!p2plink->kobj) return -ENOMEM; ret = kobject_init_and_add(p2plink->kobj, &iolink_type, @@ -1381,7 +1381,7 @@ static int kfd_build_p2p_node_entry(struct kfd_topology_device *dev, { int ret; - p2plink->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + p2plink->kobj = kzalloc_obj(struct kobject); if (!p2plink->kobj) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 0b4fc654e76f..b3d6f2cd8ab6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -545,13 +545,15 @@ static void schedule_dc_vmin_vmax(struct amdgpu_device *adev, struct dc_stream_state *stream, struct dc_crtc_timing_adjust *adjust) { - struct vupdate_offload_work *offload_work = kzalloc(sizeof(*offload_work), GFP_NOWAIT); + struct vupdate_offload_work *offload_work = kzalloc_obj(*offload_work, + GFP_NOWAIT); if (!offload_work) { drm_dbg_driver(adev_to_drm(adev), "Failed to allocate vupdate_offload_work\n"); return; } - struct dc_crtc_timing_adjust *adjust_copy = kzalloc(sizeof(*adjust_copy), GFP_NOWAIT); + struct dc_crtc_timing_adjust *adjust_copy = kzalloc_obj(*adjust_copy, + GFP_NOWAIT); if (!adjust_copy) { drm_dbg_driver(adev_to_drm(adev), "Failed to allocate adjust_copy\n"); kfree(offload_work); @@ -1023,7 +1025,8 @@ static void dm_dmub_outbox1_low_irq(void *interrupt_params) continue; } if (dm->dmub_thread_offload[notify.type] == true) { - dmub_hpd_wrk = kzalloc(sizeof(*dmub_hpd_wrk), GFP_ATOMIC); + dmub_hpd_wrk = kzalloc_obj(*dmub_hpd_wrk, + GFP_ATOMIC); if (!dmub_hpd_wrk) { drm_err(adev_to_drm(adev), "Failed to allocate dmub_hpd_wrk"); return; @@ -1244,6 +1247,7 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) struct dmub_srv *dmub_srv = adev->dm.dmub_srv; struct dmub_srv_fb_info *fb_info = adev->dm.dmub_fb_info; const struct firmware *dmub_fw = adev->dm.dmub_fw; + struct dc *dc = adev->dm.dc; struct dmcu *dmcu = adev->dm.dc->res_pool->dmcu; struct abm *abm = adev->dm.dc->res_pool->abm; struct dc_context *ctx = adev->dm.dc->ctx; @@ -1349,18 +1353,15 @@ static int dm_dmub_hw_init(struct amdgpu_device *adev) for (i = 0; i < fb_info->num_fb; ++i) hw_params.fb[i] = &fb_info->fb[i]; - switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) { - case IP_VERSION(3, 1, 3): - case IP_VERSION(3, 1, 4): - case IP_VERSION(3, 5, 0): - case IP_VERSION(3, 5, 1): - case IP_VERSION(3, 6, 0): - case IP_VERSION(4, 0, 1): + /* Enable usb4 dpia in the FW APU */ + if (dc->caps.is_apu && + dc->res_pool->usb4_dpia_count != 0 && + !dc->debug.dpia_debug.bits.disable_dpia) { hw_params.dpia_supported = true; - hw_params.disable_dpia = adev->dm.dc->debug.dpia_debug.bits.disable_dpia; - break; - default: - break; + hw_params.disable_dpia = dc->debug.dpia_debug.bits.disable_dpia; + hw_params.dpia_hpd_int_enable_supported = false; + hw_params.enable_non_transparent_setconfig = dc->config.consolidated_dpia_dp_lt; + hw_params.disable_dpia_bw_allocation = !dc->config.usb4_bw_alloc_support; } switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) { @@ -1649,7 +1650,7 @@ static struct hpd_rx_irq_offload_work_queue *hpd_rx_irq_create_workqueue(struct int i = 0; struct hpd_rx_irq_offload_work_queue *hpd_rx_offload_wq = NULL; - hpd_rx_offload_wq = kcalloc(max_caps, sizeof(*hpd_rx_offload_wq), GFP_KERNEL); + hpd_rx_offload_wq = kzalloc_objs(*hpd_rx_offload_wq, max_caps); if (!hpd_rx_offload_wq) return NULL; @@ -1722,7 +1723,7 @@ dm_allocate_gpu_mem( AMDGPU_GEM_DOMAIN_GTT : AMDGPU_GEM_DOMAIN_VRAM; int ret; - da = kzalloc(sizeof(struct dal_allocation), GFP_KERNEL); + da = kzalloc_obj(struct dal_allocation); if (!da) return NULL; @@ -2128,7 +2129,7 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) } if (dc_is_dmub_outbox_supported(adev->dm.dc)) { init_completion(&adev->dm.dmub_aux_transfer_done); - adev->dm.dmub_notify = kzalloc(sizeof(struct dmub_notification), GFP_KERNEL); + adev->dm.dmub_notify = kzalloc_obj(struct dmub_notification); if (!adev->dm.dmub_notify) { drm_info(adev_to_drm(adev), "fail to allocate adev->dm.dmub_notify"); goto error; @@ -2523,7 +2524,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) } - adev->dm.dmub_srv = kzalloc(sizeof(*adev->dm.dmub_srv), GFP_KERNEL); + adev->dm.dmub_srv = kzalloc_obj(*adev->dm.dmub_srv); dmub_srv = adev->dm.dmub_srv; if (!dmub_srv) { @@ -2604,8 +2605,7 @@ static int dm_dmub_sw_init(struct amdgpu_device *adev) memory_params.region_info = ®ion_info; memory_params.window_memory_type = window_memory_type; - adev->dm.dmub_fb_info = - kzalloc(sizeof(*adev->dm.dmub_fb_info), GFP_KERNEL); + adev->dm.dmub_fb_info = kzalloc_obj(*adev->dm.dmub_fb_info); fb_info = adev->dm.dmub_fb_info; if (!fb_info) { @@ -3361,7 +3361,7 @@ static void dm_gpureset_commit_state(struct dc_state *dc_state, } *bundle __free(kfree); int k, m; - bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); + bundle = kzalloc_obj(*bundle); if (!bundle) { drm_err(dm->ddev, "Failed to allocate update bundle\n"); @@ -3481,7 +3481,17 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) struct dc_commit_streams_params commit_params = {}; if (dm->dc->caps.ips_support) { + if (!amdgpu_in_reset(adev)) + mutex_lock(&dm->dc_lock); + + /* Need to set POWER_STATE_D0 first or it will not execute + * idle_power_optimizations command to DMUB. + */ + dc_dmub_srv_set_power_state(dm->dc->ctx->dmub_srv, DC_ACPI_CM_POWER_STATE_D0); dc_dmub_srv_apply_idle_power_optimizations(dm->dc, false); + + if (!amdgpu_in_reset(adev)) + mutex_unlock(&dm->dc_lock); } if (amdgpu_in_reset(adev)) { @@ -3606,6 +3616,11 @@ static int dm_resume(struct amdgpu_ip_block *ip_block) if (aconnector->mst_root) continue; + /* Skip eDP detection, when there is no sink present */ + if (aconnector->dc_link->connector_signal == SIGNAL_TYPE_EDP && + !aconnector->dc_link->edp_sink_present) + continue; + guard(mutex)(&aconnector->hpd_lock); if (!dc_link_detect_connection_type(aconnector->dc_link, &new_connection_type)) drm_err(adev_to_drm(adev), "KMS: Failed to detect connector\n"); @@ -3914,7 +3929,7 @@ void amdgpu_dm_update_connector_after_detect( if (!aconnector->timing_requested) { aconnector->timing_requested = - kzalloc(sizeof(struct dc_crtc_timing), GFP_KERNEL); + kzalloc_obj(struct dc_crtc_timing); if (!aconnector->timing_requested) drm_err(dev, "failed to create aconnector->requested_timing\n"); @@ -4143,8 +4158,7 @@ static void handle_hpd_irq(void *param) static void schedule_hpd_rx_offload_work(struct amdgpu_device *adev, struct hpd_rx_irq_offload_work_queue *offload_wq, union hpd_irq_data hpd_irq_data) { - struct hpd_rx_irq_offload_work *offload_work = - kzalloc(sizeof(*offload_work), GFP_KERNEL); + struct hpd_rx_irq_offload_work *offload_work = kzalloc_obj(*offload_work); if (!offload_work) { drm_err(adev_to_drm(adev), "Failed to allocate hpd_rx_irq_offload_work.\n"); @@ -4865,7 +4879,7 @@ dm_atomic_duplicate_state(struct drm_private_obj *obj) { struct dm_atomic_state *old_state, *new_state; - new_state = kzalloc(sizeof(*new_state), GFP_KERNEL); + new_state = kzalloc_obj(*new_state); if (!new_state) return NULL; @@ -4922,7 +4936,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) /* indicates support for immediate flip */ adev_to_drm(adev)->mode_config.async_page_flip = true; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -5350,7 +5364,7 @@ static int initialize_plane(struct amdgpu_display_manager *dm, unsigned long possible_crtcs; int ret = 0; - plane = kzalloc(sizeof(struct drm_plane), GFP_KERNEL); + plane = kzalloc_obj(struct drm_plane); if (!plane) { drm_err(adev_to_drm(dm->adev), "KMS: Failed to allocate plane\n"); return -ENOMEM; @@ -5589,7 +5603,7 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) link = dc_get_link_at_index(dm->dc, i); if (link->connector_signal == SIGNAL_TYPE_VIRTUAL) { - struct amdgpu_dm_wb_connector *wbcon = kzalloc(sizeof(*wbcon), GFP_KERNEL); + struct amdgpu_dm_wb_connector *wbcon = kzalloc_obj(*wbcon); if (!wbcon) { drm_err(adev_to_drm(adev), "KMS: Failed to allocate writeback connector\n"); @@ -5608,11 +5622,11 @@ static int amdgpu_dm_initialize_drm_device(struct amdgpu_device *adev) continue; } - aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); + aconnector = kzalloc_obj(*aconnector); if (!aconnector) goto fail; - aencoder = kzalloc(sizeof(*aencoder), GFP_KERNEL); + aencoder = kzalloc_obj(*aencoder); if (!aencoder) goto fail; @@ -7806,7 +7820,7 @@ void amdgpu_dm_connector_funcs_reset(struct drm_connector *connector) kfree(state); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) { state->scaling = RMX_OFF; @@ -9081,7 +9095,7 @@ static int amdgpu_dm_i2c_xfer(struct i2c_adapter *i2c_adap, if (!ddc_service->ddc_pin) return result; - cmd.payloads = kcalloc(num, sizeof(struct i2c_payload), GFP_KERNEL); + cmd.payloads = kzalloc_objs(struct i2c_payload, num); if (!cmd.payloads) return result; @@ -9130,7 +9144,7 @@ create_i2c(struct ddc_service *ddc_service, bool oem) struct amdgpu_device *adev = ddc_service->ctx->driver_context; struct amdgpu_i2c_adapter *i2c; - i2c = kzalloc(sizeof(struct amdgpu_i2c_adapter), GFP_KERNEL); + i2c = kzalloc_obj(struct amdgpu_i2c_adapter); if (!i2c) return NULL; i2c->base.owner = THIS_MODULE; @@ -9931,7 +9945,7 @@ static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, struct dc_stream_update stream_update; } *bundle; - bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); + bundle = kzalloc_obj(*bundle); if (!bundle) { drm_err(dev, "Failed to allocate update bundle\n"); @@ -10606,7 +10620,7 @@ static void dm_set_writeback(struct amdgpu_display_manager *dm, struct amdgpu_framebuffer *afb; int i = 0; - wb_info = kzalloc(sizeof(*wb_info), GFP_KERNEL); + wb_info = kzalloc_obj(*wb_info); if (!wb_info) { drm_err(adev_to_drm(adev), "Failed to allocate wb_info\n"); return; @@ -10662,10 +10676,10 @@ static void dm_set_writeback(struct amdgpu_display_manager *dm, wb_info->dwb_params.capture_rate = dwb_capture_rate_0; - wb_info->dwb_params.scaler_taps.h_taps = 4; - wb_info->dwb_params.scaler_taps.v_taps = 4; - wb_info->dwb_params.scaler_taps.h_taps_c = 2; - wb_info->dwb_params.scaler_taps.v_taps_c = 2; + wb_info->dwb_params.scaler_taps.h_taps = 1; + wb_info->dwb_params.scaler_taps.v_taps = 1; + wb_info->dwb_params.scaler_taps.h_taps_c = 1; + wb_info->dwb_params.scaler_taps.v_taps_c = 1; wb_info->dwb_params.subsample_position = DWB_INTERSTITIAL_SUBSAMPLING; wb_info->mcif_buf_params.luma_pitch = afb->base.pitches[0]; @@ -10965,7 +10979,7 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) continue; } for (j = 0; j < status->plane_count; j++) - dummy_updates[j].surface = status->plane_states[0]; + dummy_updates[j].surface = status->plane_states[j]; sort(dummy_updates, status->plane_count, sizeof(*dummy_updates), dm_plane_layer_index_cmp, NULL); @@ -11681,6 +11695,8 @@ static bool should_reset_plane(struct drm_atomic_state *state, struct drm_crtc_state *old_crtc_state, *new_crtc_state; struct dm_crtc_state *old_dm_crtc_state, *new_dm_crtc_state; struct amdgpu_device *adev = drm_to_adev(plane->dev); + struct drm_connector_state *new_con_state; + struct drm_connector *connector; int i; /* @@ -11691,6 +11707,15 @@ static bool should_reset_plane(struct drm_atomic_state *state, state->allow_modeset) return true; + /* Check for writeback commit */ + for_each_new_connector_in_state(state, connector, new_con_state, i) { + if (connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK) + continue; + + if (new_con_state->writeback_job) + return true; + } + if (amdgpu_in_reset(adev) && state->allow_modeset) return true; @@ -12289,10 +12314,9 @@ static int dm_crtc_get_cursor_mode(struct amdgpu_device *adev, /* Overlay cursor not supported on HW before DCN * DCN401 does not have the cursor-on-scaled-plane or cursor-on-yuv-plane restrictions - * as previous DCN generations, so enable native mode on DCN401 in addition to DCE + * as previous DCN generations, so enable native mode on DCN401 */ - if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0 || - amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == IP_VERSION(4, 0, 1)) { *cursor_mode = DM_CURSOR_NATIVE_MODE; return 0; } @@ -12612,6 +12636,12 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev, * need to be added for DC to not disable a plane by mistake */ if (dm_new_crtc_state->cursor_mode == DM_CURSOR_OVERLAY_MODE) { + if (amdgpu_ip_version(adev, DCE_HWIP, 0) == 0) { + drm_dbg(dev, "Overlay cursor not supported on DCE\n"); + ret = -EINVAL; + goto fail; + } + ret = drm_atomic_add_affected_planes(state, crtc); if (ret) goto fail; @@ -13129,6 +13159,7 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector, u8 *edid_ext = NULL; int i; int j = 0; + int total_ext_block_len; if (edid == NULL || edid->extensions == 0) return -ENODEV; @@ -13140,7 +13171,8 @@ static int parse_amd_vsdb(struct amdgpu_dm_connector *aconnector, break; } - while (j < EDID_LENGTH - sizeof(struct amd_vsdb_block)) { + total_ext_block_len = EDID_LENGTH * edid->extensions; + while (j < total_ext_block_len - sizeof(struct amd_vsdb_block)) { struct amd_vsdb_block *amd_vsdb = (struct amd_vsdb_block *)&edid_ext[j]; unsigned int ieeeId = (amd_vsdb->ieee_id[2] << 16) | (amd_vsdb->ieee_id[1] << 8) | (amd_vsdb->ieee_id[0]); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c index 20a76d81d532..cd1e58b8defc 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c @@ -1227,7 +1227,7 @@ int amdgpu_dm_check_crtc_color_mgmt(struct dm_crtc_state *crtc, crtc->cm_is_degamma_srgb = false; if (check_only) { - out_tf = kvzalloc(sizeof(*out_tf), GFP_KERNEL); + out_tf = kvzalloc_obj(*out_tf); if (!out_tf) return -ENOMEM; } else { @@ -1706,6 +1706,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state, struct dc_transfer_func *tf = &dc_plane_state->in_shaper_func; struct drm_atomic_state *state = plane_state->state; const struct amdgpu_device *adev = drm_to_adev(colorop->dev); + bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend; const struct drm_device *dev = colorop->dev; const struct drm_color_lut32 *lut3d; uint32_t lut3d_size; @@ -1722,7 +1723,7 @@ __set_dm_plane_colorop_3dlut(struct drm_plane_state *plane_state, } if (colorop_state && !colorop_state->bypass && colorop->type == DRM_COLOROP_3D_LUT) { - if (!adev->dm.dc->caps.color.dpp.hw_3d_lut) { + if (!has_3dlut) { drm_dbg(dev, "3D LUT is not supported by hardware\n"); return -EINVAL; } @@ -1875,6 +1876,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, struct drm_colorop *colorop = plane_state->color_pipeline; struct drm_device *dev = plane_state->plane->dev; struct amdgpu_device *adev = drm_to_adev(dev); + bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend; int ret; /* 1D Curve - DEGAM TF */ @@ -1907,7 +1909,7 @@ amdgpu_dm_plane_set_colorop_properties(struct drm_plane_state *plane_state, if (ret) return ret; - if (adev->dm.dc->caps.color.dpp.hw_3d_lut) { + if (has_3dlut) { /* 1D Curve & LUT - SHAPER TF & LUT */ colorop = colorop->next; if (!colorop) { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c index a2de3bba8346..d59ba82d3d7c 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_colorop.c @@ -60,13 +60,14 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr struct drm_colorop *ops[MAX_COLOR_PIPELINE_OPS]; struct drm_device *dev = plane->dev; struct amdgpu_device *adev = drm_to_adev(dev); + bool has_3dlut = adev->dm.dc->caps.color.dpp.hw_3d_lut || adev->dm.dc->caps.color.mpc.preblend; int ret; int i = 0; memset(ops, 0, sizeof(ops)); /* 1D curve - DEGAM TF */ - ops[i] = kzalloc(sizeof(*ops[0]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[0]); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -83,7 +84,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; /* Multiplier */ - ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + ops[i] = kzalloc_obj(struct drm_colorop); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -98,7 +99,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 3x4 matrix */ - ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + ops[i] = kzalloc_obj(struct drm_colorop); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -112,9 +113,9 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; - if (adev->dm.dc->caps.color.dpp.hw_3d_lut) { + if (has_3dlut) { /* 1D curve - SHAPER TF */ - ops[i] = kzalloc(sizeof(*ops[0]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[0]); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -131,7 +132,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 1D LUT - SHAPER LUT */ - ops[i] = kzalloc(sizeof(*ops[0]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[0]); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -148,7 +149,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 3D LUT */ - ops[i] = kzalloc(sizeof(*ops[0]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[0]); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -166,7 +167,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr } /* 1D curve - BLND TF */ - ops[i] = kzalloc(sizeof(*ops[0]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[0]); if (!ops[i]) { ret = -ENOMEM; goto cleanup; @@ -183,7 +184,7 @@ int amdgpu_dm_initialize_default_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 1D LUT - BLND LUT */ - ops[i] = kzalloc(sizeof(struct drm_colorop), GFP_KERNEL); + ops[i] = kzalloc_obj(struct drm_colorop); if (!ops[i]) { ret = -ENOMEM; goto cleanup; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index 5851f2d55dde..b96fbc03c371 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -506,6 +506,7 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, struct amdgpu_dm_connector *aconnector = NULL; bool enable = amdgpu_dm_is_valid_crc_source(source); int ret = 0; + enum crc_poly_mode crc_poly_mode = CRC_POLY_MODE_16; /* Configuration will be deferred to stream enable. */ if (!stream_state) @@ -528,10 +529,18 @@ int amdgpu_dm_crtc_configure_crc_source(struct drm_crtc *crtc, amdgpu_dm_replay_disable(stream_state); } + /* CRC polynomial selection only support for DCN3.6+ except DCN4.0.1 */ + if ((amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 6, 0)) && + (amdgpu_ip_version(adev, DCE_HWIP, 0) != IP_VERSION(4, 0, 1))) { + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + + crc_poly_mode = acrtc->dm_irq_params.crc_poly_mode; + } + /* Enable or disable CRTC CRC generation */ if (dm_is_crc_source_crtc(source) || source == AMDGPU_DM_PIPE_CRC_SOURCE_NONE) { if (!dc_stream_configure_crc(stream_state->ctx->dc, - stream_state, NULL, enable, enable, 0, true)) { + stream_state, NULL, enable, enable, 0, true, crc_poly_mode)) { ret = -EINVAL; goto unlock; } @@ -877,7 +886,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE) /* update ROI via dm*/ dc_stream_configure_crc(stream_state->ctx->dc, stream_state, - &crc_window, true, true, i, false); + &crc_window, true, true, i, false, (enum crc_poly_mode)acrtc->dm_irq_params.crc_poly_mode); reset_crc_frame_count[i] = true; @@ -901,7 +910,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) else if (adev->dm.secure_display_ctx.op_mode == DISPLAY_CRC_MODE) /* Avoid ROI window get changed, keep overwriting. */ dc_stream_configure_crc(stream_state->ctx->dc, stream_state, - &crc_window, true, true, i, false); + &crc_window, true, true, i, false, (enum crc_poly_mode)acrtc->dm_irq_params.crc_poly_mode); /* crc ready for psp to read out */ crtc_ctx->crc_info.crc[i].crc_ready = true; @@ -949,9 +958,8 @@ void amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev) struct secure_display_crtc_context *crtc_ctx = NULL; int i; - crtc_ctx = kcalloc(adev->mode_info.num_crtc, - sizeof(struct secure_display_crtc_context), - GFP_KERNEL); + crtc_ctx = kzalloc_objs(struct secure_display_crtc_context, + adev->mode_info.num_crtc); if (!crtc_ctx) { adev->dm.secure_display_ctx.crtc_ctx = NULL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 9fcd72d87d25..304437c2284d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -231,7 +231,7 @@ struct idle_workqueue *idle_create_workqueue(struct amdgpu_device *adev) { struct idle_workqueue *idle_work; - idle_work = kzalloc(sizeof(*idle_work), GFP_KERNEL); + idle_work = kzalloc_obj(*idle_work); if (ZERO_OR_NULL_PTR(idle_work)) return NULL; @@ -392,7 +392,7 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable) return 0; if (dm->vblank_control_workqueue) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return -ENOMEM; @@ -447,7 +447,7 @@ static struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *cr if (WARN_ON(!crtc->state)) return NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; @@ -487,7 +487,7 @@ static void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc) if (crtc->state) amdgpu_dm_crtc_destroy_state(crtc, crtc->state); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (WARN_ON(!state)) return; @@ -728,14 +728,14 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, bool has_degamma; int res = -ENOMEM; - cursor_plane = kzalloc(sizeof(*cursor_plane), GFP_KERNEL); + cursor_plane = kzalloc_obj(*cursor_plane); if (!cursor_plane) goto fail; cursor_plane->type = DRM_PLANE_TYPE_CURSOR; res = amdgpu_dm_plane_init(dm, cursor_plane, 0, NULL); - acrtc = kzalloc(sizeof(struct amdgpu_crtc), GFP_KERNEL); + acrtc = kzalloc_obj(struct amdgpu_crtc); if (!acrtc) goto fail; @@ -765,15 +765,15 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, dm->adev->mode_info.crtcs[crtc_index] = acrtc; /* Don't enable DRM CRTC degamma property for - * 1. Degamma is replaced by color pipeline. - * 2. DCE since it doesn't support programmable degamma anywhere. - * 3. DCN401 since pre-blending degamma LUT doesn't apply to cursor. + * 1. DCE since it doesn't support programmable degamma anywhere. + * 2. DCN401 since pre-blending degamma LUT doesn't apply to cursor. + * Note: DEGAMMA properties are created even if the primary plane has the + * COLOR_PIPELINE property. User space can use either the DEGAMMA properties + * or the COLOR_PIPELINE property. An atomic commit which attempts to enable + * both is rejected. */ - if (plane->color_pipeline_property) - has_degamma = false; - else - has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch && - dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01; + has_degamma = dm->adev->dm.dc->caps.color.dpp.dcn_arch && + dm->adev->dm.dc->ctx->dce_version != DCN_VERSION_4_01; drm_crtc_enable_color_mgmt(&acrtc->base, has_degamma ? MAX_COLOR_LUT_ENTRIES : 0, true, MAX_COLOR_LUT_ENTRIES); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c index b9ed29ec60dc..24bc2a86904b 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c @@ -46,6 +46,7 @@ #include "amdgpu_dm_psr.h" #endif +#define MULTIPLIER_TO_LR 270000 struct dmub_debugfs_trace_header { uint32_t entry_count; uint32_t reserved[3]; @@ -302,8 +303,11 @@ static ssize_t dp_link_settings_write(struct file *f, const char __user *buf, switch (param[1]) { case LINK_RATE_LOW: + case LINK_RATE_RATE_2: + case LINK_RATE_RATE_3: case LINK_RATE_HIGH: case LINK_RATE_RBR2: + case LINK_RATE_RATE_6: case LINK_RATE_HIGH2: case LINK_RATE_HIGH3: case LINK_RATE_UHBR10: @@ -3504,6 +3508,10 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf, uint8_t param_nums = 0; long param[2]; bool valid_input = true; + uint8_t supported_link_rates[16] = {0}; + uint32_t entry = 0; + uint32_t link_rate_in_khz = 0; + uint8_t dpcd_rev = 0; if (size == 0) return -EINVAL; @@ -3548,6 +3556,20 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf, return size; } + if (!dm_helpers_dp_read_dpcd(link->ctx, link, DP_SUPPORTED_LINK_RATES, + supported_link_rates, sizeof(supported_link_rates))) + return -EINVAL; + + dpcd_rev = link->dpcd_caps.dpcd_rev.raw; + if (dpcd_rev < DP_DPCD_REV_13 || + (supported_link_rates[entry + 1] == 0 && supported_link_rates[entry] == 0)) { + return size; + } + + entry = param[1] * 2; + link_rate_in_khz = (supported_link_rates[entry + 1] * 0x100 + + supported_link_rates[entry]) * 200; + /* save user force lane_count, link_rate to preferred settings * spread spectrum will not be changed */ @@ -3555,7 +3577,7 @@ static ssize_t edp_ilr_write(struct file *f, const char __user *buf, prefer_link_settings.lane_count = param[0]; prefer_link_settings.use_link_rate_set = true; prefer_link_settings.link_rate_set = param[1]; - prefer_link_settings.link_rate = link->dpcd_caps.edp_supported_link_rates[param[1]]; + prefer_link_settings.link_rate = link_rate_in_khz / MULTIPLIER_TO_LR; mutex_lock(&adev->dm.dc_lock); dc_link_set_preferred_training_settings(dc, &prefer_link_settings, @@ -3817,6 +3839,50 @@ static int crc_win_update_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(crc_win_update_fops, crc_win_update_get, crc_win_update_set, "%llu\n"); + +/* + * Trigger to set crc polynomial mode + * 0: 16-bit CRC, 1: 32-bit CRC + * only accepts 0 or 1 for supported hwip versions + */ +static int crc_poly_mode_set(void *data, u64 val) +{ + struct drm_crtc *crtc = data; + struct amdgpu_crtc *acrtc; + struct amdgpu_device *adev = drm_to_adev(crtc->dev); + + if ((amdgpu_ip_version(adev, DCE_HWIP, 0) >= IP_VERSION(3, 6, 0)) && + (amdgpu_ip_version(adev, DCE_HWIP, 0) != IP_VERSION(4, 0, 1)) && + (val < 2)) { + acrtc = to_amdgpu_crtc(crtc); + mutex_lock(&adev->dm.dc_lock); + spin_lock_irq(&adev_to_drm(adev)->event_lock); + acrtc->dm_irq_params.crc_poly_mode = val; + spin_unlock_irq(&adev_to_drm(adev)->event_lock); + mutex_unlock(&adev->dm.dc_lock); + } + + return 0; +} + +/* + * Get crc polynomial mode (0: 16-bit CRC, 1: 32-bit CRC) + */ +static int crc_poly_mode_get(void *data, u64 *val) +{ + struct drm_crtc *crtc = data; + struct drm_device *drm_dev = crtc->dev; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + + spin_lock_irq(&drm_dev->event_lock); + *val = acrtc->dm_irq_params.crc_poly_mode; + spin_unlock_irq(&drm_dev->event_lock); + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(crc_poly_mode_fops, crc_poly_mode_get, + crc_poly_mode_set, "%llu\n"); #endif void crtc_debugfs_init(struct drm_crtc *crtc) { @@ -3836,6 +3902,8 @@ void crtc_debugfs_init(struct drm_crtc *crtc) &crc_win_y_end_fops); debugfs_create_file_unsafe("crc_win_update", 0644, dir, crtc, &crc_win_update_fops); + debugfs_create_file_unsafe("crc_poly_mode", 0644, dir, crtc, + &crc_poly_mode_fops); dput(dir); #endif debugfs_create_file("amdgpu_current_bpc", 0644, crtc->debugfs_entry, @@ -4233,7 +4301,7 @@ static ssize_t dcc_en_bits_read( int *dcc_en_bits; int i, r; - dcc_en_bits = kcalloc(num_pipes, sizeof(int), GFP_KERNEL); + dcc_en_bits = kzalloc_objs(int, num_pipes); if (!dcc_en_bits) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c index a10401675f53..eb73bbf8f411 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c @@ -746,7 +746,7 @@ struct hdcp_workqueue *hdcp_create_workqueue(struct amdgpu_device *adev, struct hdcp_workqueue *hdcp_work; int i = 0; - hdcp_work = kcalloc(max_caps, sizeof(*hdcp_work), GFP_KERNEL); + hdcp_work = kzalloc_objs(*hdcp_work, max_caps); if (ZERO_OR_NULL_PTR(hdcp_work)) return NULL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c index 1f41d6540b83..a09761f9882d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -617,7 +617,7 @@ bool dm_helpers_submit_i2c( return false; } - msgs = kcalloc(num, sizeof(struct i2c_msg), GFP_KERNEL); + msgs = kzalloc_objs(struct i2c_msg, num); if (!msgs) return false; @@ -1153,11 +1153,19 @@ void dm_helpers_init_panel_settings( void dm_helpers_override_panel_settings( struct dc_context *ctx, - struct dc_panel_config *panel_config) + struct dc_link *link) { + unsigned int panel_inst = 0; + // Feature DSC if (amdgpu_dc_debug_mask & DC_DISABLE_DSC) - panel_config->dsc.disable_dsc_edp = true; + link->panel_config.dsc.disable_dsc_edp = true; + + if (dc_get_edp_link_panel_inst(ctx->dc, link, &panel_inst) && panel_inst == 1) { + link->panel_config.psr.disable_psr = true; + link->panel_config.psr.disallow_psrsu = true;; + link->panel_config.psr.disallow_replay = true; + } } void *dm_helpers_allocate_gpu_mem( diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c index e7b0928bd3db..e49803a90eda 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq.c @@ -313,7 +313,7 @@ void *amdgpu_dm_irq_register_interrupt(struct amdgpu_device *adev, if (false == validate_irq_registration_params(int_params, ih)) return DAL_INVALID_IRQ_HANDLER_IDX; - handler_data = kzalloc(sizeof(*handler_data), GFP_KERNEL); + handler_data = kzalloc_obj(*handler_data); if (!handler_data) { DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n"); return DAL_INVALID_IRQ_HANDLER_IDX; @@ -594,7 +594,7 @@ static void amdgpu_dm_irq_schedule_work(struct amdgpu_device *adev, handler_data = container_of(handler_list->next, struct amdgpu_dm_irq_handler_data, list); /*allocate a new amdgpu_dm_irq_handler_data*/ - handler_data_add = kzalloc(sizeof(*handler_data), GFP_ATOMIC); + handler_data_add = kzalloc_obj(*handler_data, GFP_ATOMIC); if (!handler_data_add) { DRM_ERROR("DM_IRQ: failed to allocate irq handler!\n"); return; @@ -919,16 +919,15 @@ void amdgpu_dm_hpd_init(struct amdgpu_device *adev) continue; amdgpu_dm_connector = to_amdgpu_dm_connector(connector); + dc_link = amdgpu_dm_connector->dc_link; + if (!dc_link) + continue; /* * Analog connectors may be hot-plugged unlike other connector * types that don't support HPD. Only poll analog connectors. */ - use_polling |= - amdgpu_dm_connector->dc_link && - dc_connector_supports_analog(amdgpu_dm_connector->dc_link->link_id.id); - - dc_link = amdgpu_dm_connector->dc_link; + use_polling |= dc_connector_supports_analog(dc_link->link_id.id); /* * Get a base driver irq reference for hpd ints for the lifetime diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h index 3c9995275cbd..f0c1b0c1faa9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_irq_params.h @@ -39,6 +39,7 @@ struct dm_irq_params { #ifdef CONFIG_DEBUG_FS enum amdgpu_dm_pipe_crc_source crc_src; + int crc_poly_mode; /* enum crc_poly_mode from timing_generator.h */ #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY struct crc_window_param window_param[MAX_CRC_WINDOW_NUM]; /* At least one CRC window is activated or not*/ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c index 5e92eaa67aa3..7be50e8c0636 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c @@ -640,7 +640,7 @@ dm_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, struct drm_connector *connector; int i; - aconnector = kzalloc(sizeof(*aconnector), GFP_KERNEL); + aconnector = kzalloc_obj(*aconnector); if (!aconnector) return NULL; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index d3e62f511c8f..127207e18dcb 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -1060,10 +1060,15 @@ static void amdgpu_dm_plane_get_min_max_dc_plane_scaling(struct drm_device *dev, *min_downscale = plane_cap->max_downscale_factor.nv12; break; + /* All 64 bpp formats have the same fp16 scaling limits */ case DRM_FORMAT_XRGB16161616F: case DRM_FORMAT_ARGB16161616F: case DRM_FORMAT_XBGR16161616F: case DRM_FORMAT_ABGR16161616F: + case DRM_FORMAT_XRGB16161616: + case DRM_FORMAT_ARGB16161616: + case DRM_FORMAT_XBGR16161616: + case DRM_FORMAT_ABGR16161616: *max_upscale = plane_cap->max_upscale_factor.fp16; *min_downscale = plane_cap->max_downscale_factor.fp16; break; @@ -1251,6 +1256,14 @@ static int amdgpu_dm_plane_atomic_check(struct drm_plane *plane, if (ret) return ret; + /* Reject commits that attempt to use both COLOR_PIPELINE and CRTC DEGAMMA_LUT */ + if (new_plane_state->color_pipeline && new_crtc_state->degamma_lut) { + drm_dbg_atomic(plane->dev, + "[PLANE:%d:%s] COLOR_PIPELINE and CRTC DEGAMMA_LUT cannot be enabled simultaneously\n", + plane->base.id, plane->name); + return -EINVAL; + } + ret = amdgpu_dm_plane_fill_dc_scaling_info(adev, new_plane_state, &scaling_info); if (ret) return ret; @@ -1465,7 +1478,7 @@ static void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane) if (plane->state) plane->funcs->atomic_destroy_state(plane, plane->state); - amdgpu_state = kzalloc(sizeof(*amdgpu_state), GFP_KERNEL); + amdgpu_state = kzalloc_obj(*amdgpu_state); WARN_ON(amdgpu_state == NULL); if (!amdgpu_state) @@ -1483,7 +1496,7 @@ static struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct struct dm_plane_state *dm_plane_state, *old_dm_plane_state; old_dm_plane_state = to_dm_plane_state(plane->state); - dm_plane_state = kzalloc(sizeof(*dm_plane_state), GFP_KERNEL); + dm_plane_state = kzalloc_obj(*dm_plane_state); if (!dm_plane_state) return NULL; @@ -1650,7 +1663,7 @@ dm_atomic_plane_attach_color_mgmt_properties(struct amdgpu_display_manager *dm, MAX_COLOR_3DLUT_SIZE); } - if (dpp_color_caps.ogam_ram) { + if (dpp_color_caps.ogam_ram || dm->dc->caps.color.mpc.preblend) { drm_object_attach_property(&plane->base, mode_info.plane_blend_lut_property, 0); drm_object_attach_property(&plane->base, diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c index fd491b7a3cd7..99d6d6c93561 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_psr.c @@ -80,12 +80,20 @@ void amdgpu_dm_set_psr_caps(struct dc_link *link) link->psr_settings.psr_feature_enabled = false; } else { + unsigned int panel_inst = 0; + if (link_supports_psrsu(link)) link->psr_settings.psr_version = DC_PSR_VERSION_SU_1; else link->psr_settings.psr_version = DC_PSR_VERSION_1; link->psr_settings.psr_feature_enabled = true; + + /*disable allow psr/psrsu/replay on eDP1*/ + if (dc_get_edp_link_panel_inst(link->ctx->dc, link, &panel_inst) && panel_inst == 1) { + link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; + link->psr_settings.psr_feature_enabled = false; + } } } diff --git a/drivers/gpu/drm/amd/display/dc/Makefile b/drivers/gpu/drm/amd/display/dc/Makefile index 7277ed21552f..93d02956c5eb 100644 --- a/drivers/gpu/drm/amd/display/dc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/Makefile @@ -22,7 +22,7 @@ # # Makefile for Display Core (dc) component. -DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link virtual dsc resource optc dpp hubbub dccg hubp dio dwb hpo mmhubbub mpc opp pg +DC_LIBS = basics bios dml clk_mgr dce gpio hwss irq link dsc resource optc dpp hubbub dccg hubp dio dwb hpo mmhubbub mpc opp pg ifdef CONFIG_DRM_AMD_DC_FP diff --git a/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c b/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c index 4da5adab799c..8c54c02a0e26 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/basics/dce_calcs.c @@ -120,19 +120,19 @@ static void calculate_bandwidth( int32_t number_of_displays_enabled_with_margin = 0; int32_t number_of_aligned_displays_with_no_margin = 0; - yclk = kcalloc(3, sizeof(*yclk), GFP_KERNEL); + yclk = kzalloc_objs(*yclk, 3); if (!yclk) return; - sclk = kcalloc(8, sizeof(*sclk), GFP_KERNEL); + sclk = kzalloc_objs(*sclk, 8); if (!sclk) goto free_yclk; - tiling_mode = kcalloc(maximum_number_of_surfaces, sizeof(*tiling_mode), GFP_KERNEL); + tiling_mode = kzalloc_objs(*tiling_mode, maximum_number_of_surfaces); if (!tiling_mode) goto free_sclk; - surface_type = kcalloc(maximum_number_of_surfaces, sizeof(*surface_type), GFP_KERNEL); + surface_type = kzalloc_objs(*surface_type, maximum_number_of_surfaces); if (!surface_type) goto free_tiling_mode; @@ -2049,11 +2049,11 @@ void bw_calcs_init(struct bw_calcs_dceip *bw_dceip, enum bw_calcs_version version = bw_calcs_version_from_asic_id(asic_id); - dceip = kzalloc(sizeof(*dceip), GFP_KERNEL); + dceip = kzalloc_obj(*dceip); if (!dceip) return; - vbios = kzalloc(sizeof(*vbios), GFP_KERNEL); + vbios = kzalloc_obj(*vbios); if (!vbios) { kfree(dceip); return; @@ -3045,8 +3045,7 @@ bool bw_calcs(struct dc_context *ctx, int pipe_count, struct dce_bw_output *calcs_output) { - struct bw_calcs_data *data = kzalloc(sizeof(struct bw_calcs_data), - GFP_KERNEL); + struct bw_calcs_data *data = kzalloc_obj(struct bw_calcs_data); if (!data) return false; diff --git a/drivers/gpu/drm/amd/display/dc/basics/vector.c b/drivers/gpu/drm/amd/display/dc/basics/vector.c index b413a672c2c0..a8b750ff8573 100644 --- a/drivers/gpu/drm/amd/display/dc/basics/vector.c +++ b/drivers/gpu/drm/amd/display/dc/basics/vector.c @@ -94,7 +94,7 @@ struct vector *dal_vector_presized_create( void *initial_value, uint32_t struct_size) { - struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL); + struct vector *vector = kzalloc_obj(struct vector); if (vector == NULL) return NULL; @@ -113,7 +113,7 @@ struct vector *dal_vector_create( uint32_t capacity, uint32_t struct_size) { - struct vector *vector = kzalloc(sizeof(struct vector), GFP_KERNEL); + struct vector *vector = kzalloc_obj(struct vector); if (vector == NULL) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c index 9f11e6ca4051..73e3c45eeeba 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser.c @@ -98,7 +98,7 @@ struct dc_bios *bios_parser_create( { struct bios_parser *bp; - bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); + bp = kzalloc_obj(struct bios_parser); if (!bp) return NULL; @@ -2667,7 +2667,7 @@ static struct integrated_info *bios_parser_create_integrated_info( struct bios_parser *bp = BP_FROM_DCB(dcb); struct integrated_info *info; - info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); + info = kzalloc_obj(struct integrated_info); if (info == NULL) { ASSERT_CRITICAL(0); diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c index 550a9f1d03f8..94fddf22f5a9 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c @@ -3207,7 +3207,7 @@ static struct integrated_info *bios_parser_create_integrated_info( struct bios_parser *bp = BP_FROM_DCB(dcb); struct integrated_info *info; - info = kzalloc(sizeof(struct integrated_info), GFP_KERNEL); + info = kzalloc_obj(struct integrated_info); if (info == NULL) { ASSERT_CRITICAL(0); @@ -3793,7 +3793,7 @@ struct dc_bios *firmware_parser_create( { struct bios_parser *bp; - bp = kzalloc(sizeof(struct bios_parser), GFP_KERNEL); + bp = kzalloc_obj(struct bios_parser); if (!bp) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/bios/command_table.c b/drivers/gpu/drm/amd/display/dc/bios/command_table.c index 76a3559f0ddc..b692fa37402d 100644 --- a/drivers/gpu/drm/amd/display/dc/bios/command_table.c +++ b/drivers/gpu/drm/amd/display/dc/bios/command_table.c @@ -1874,8 +1874,7 @@ static void dac_encoder_control_prepare_params( uint8_t dac_standard) { params->ucDacStandard = dac_standard; - if (action == ENCODER_CONTROL_SETUP || - action == ENCODER_CONTROL_INIT) + if (action == ENCODER_CONTROL_INIT) params->ucAction = ATOM_ENCODER_INIT; else if (action == ENCODER_CONTROL_ENABLE) params->ucAction = ATOM_ENABLE; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c index 15cf13ec5302..08d0e05a313e 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c @@ -151,7 +151,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p switch (asic_id.chip_family) { #if defined(CONFIG_DRM_AMD_DC_SI) case FAMILY_SI: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -163,7 +163,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p #endif case FAMILY_CI: case FAMILY_KV: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -173,7 +173,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p return &clk_mgr->base; } case FAMILY_CZ: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -183,7 +183,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p return &clk_mgr->base; } case FAMILY_VI: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -207,7 +207,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p return &clk_mgr->base; } case FAMILY_AI: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -221,7 +221,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } #if defined(CONFIG_DRM_AMD_DC_FP) case FAMILY_RV: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -249,7 +249,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p return &clk_mgr->base; } case FAMILY_NV: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -276,7 +276,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } case FAMILY_VGH: if (ASICREV_IS_VANGOGH(asic_id.hw_internal_rev)) { - struct clk_mgr_vgh *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_vgh *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -288,7 +288,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p break; case FAMILY_YELLOW_CARP: { - struct clk_mgr_dcn31 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_dcn31 *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -300,7 +300,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } break; case AMDGPU_FAMILY_GC_10_3_6: { - struct clk_mgr_dcn315 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_dcn315 *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -312,7 +312,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } break; case AMDGPU_FAMILY_GC_10_3_7: { - struct clk_mgr_dcn316 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_dcn316 *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -324,7 +324,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } break; case AMDGPU_FAMILY_GC_11_0_0: { - struct clk_mgr_internal *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_internal *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -335,7 +335,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p } case AMDGPU_FAMILY_GC_11_0_1: { - struct clk_mgr_dcn314 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_dcn314 *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); @@ -348,7 +348,7 @@ struct clk_mgr *dc_clk_mgr_create(struct dc_context *ctx, struct pp_smu_funcs *p break; case AMDGPU_FAMILY_GC_11_5_0: { - struct clk_mgr_dcn35 *clk_mgr = kzalloc(sizeof(*clk_mgr), GFP_KERNEL); + struct clk_mgr_dcn35 *clk_mgr = kzalloc_obj(*clk_mgr); if (clk_mgr == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c index ef77fcd164ed..b0aba3a6f13c 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn30/dcn30_clk_mgr.c @@ -561,7 +561,7 @@ void dcn3_clk_mgr_construct( dce_clock_read_ss_info(clk_mgr); - clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL); + clk_mgr->base.bw_params = kzalloc_obj(*clk_mgr->base.bw_params); if (!clk_mgr->base.bw_params) { BREAK_TO_DEBUGGER(); return; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c index 7da7b41bd092..2856b0337e87 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c @@ -1206,7 +1206,7 @@ void dcn32_clk_mgr_construct( clk_mgr->smu_present = false; - clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL); + clk_mgr->base.bw_params = kzalloc_obj(*clk_mgr->base.bw_params); if (!clk_mgr->base.bw_params) { BREAK_TO_DEBUGGER(); return; diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c index 72558cc55a9a..6fc524752613 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c @@ -186,7 +186,7 @@ static int dcn35_get_active_display_cnt_wa( return display_count; } -static void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, +void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, struct dc_state *context, bool safe_to_lower, bool disable) { struct dc *dc = clk_mgr_base->ctx->dc; @@ -766,32 +766,32 @@ static struct wm_table ddr5_wm_table = { .wm_inst = WM_A, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_B, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_C, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, { .wm_inst = WM_D, .wm_type = WM_TYPE_PSTATE_CHG, .pstate_latency_us = 11.72, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .valid = true, }, } diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h index a12a9bf90806..83e2263563fe 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.h @@ -64,4 +64,10 @@ void dcn351_clk_mgr_construct(struct dc_context *ctx, struct clk_mgr_dcn35 *clk_mgr, struct pp_smu_funcs *pp_smu, struct dccg *dccg); + +void dcn35_disable_otg_wa(struct clk_mgr *clk_mgr_base, + struct dc_state *context, + bool safe_to_lower, + bool disable); + #endif //__DCN35_CLK_MGR_H__ diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c index 306016c1f109..03464f21d119 100644 --- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c @@ -1549,7 +1549,7 @@ struct clk_mgr_internal *dcn401_clk_mgr_construct( struct dccg *dccg) { struct clk_log_info log_info = {0}; - struct dcn401_clk_mgr *clk_mgr401 = kzalloc(sizeof(struct dcn401_clk_mgr), GFP_KERNEL); + struct dcn401_clk_mgr *clk_mgr401 = kzalloc_obj(struct dcn401_clk_mgr); struct clk_mgr_internal *clk_mgr; if (!clk_mgr401) @@ -1599,7 +1599,7 @@ struct clk_mgr_internal *dcn401_clk_mgr_construct( clk_mgr->smu_present = false; - clk_mgr->base.bw_params = kzalloc(sizeof(*clk_mgr->base.bw_params), GFP_KERNEL); + clk_mgr->base.bw_params = kzalloc_obj(*clk_mgr->base.bw_params); if (!clk_mgr->base.bw_params) { BREAK_TO_DEBUGGER(); kfree(clk_mgr401); diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c index cb85b7ac2697..3e87b6a553be 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -53,7 +53,7 @@ #include "dpp.h" #include "timing_generator.h" #include "abm.h" -#include "virtual/virtual_link_encoder.h" +#include "dio/virtual/virtual_link_encoder.h" #include "hubp.h" #include "link_hwss.h" @@ -284,7 +284,7 @@ static bool create_links( } for (i = 0; i < num_virtual_links; i++) { - struct dc_link *link = kzalloc(sizeof(*link), GFP_KERNEL); + struct dc_link *link = kzalloc_obj(*link); struct encoder_init_data enc_init = {0}; if (link == NULL) { @@ -304,7 +304,7 @@ static bool create_links( link->link_id.enum_id = ENUM_ID_1; link->psr_settings.psr_version = DC_PSR_VERSION_UNSUPPORTED; link->replay_settings.config.replay_version = DC_REPLAY_VERSION_UNSUPPORTED; - link->link_enc = kzalloc(sizeof(*link->link_enc), GFP_KERNEL); + link->link_enc = kzalloc_obj(*link->link_enc); if (!link->link_enc) { BREAK_TO_DEBUGGER(); @@ -409,7 +409,7 @@ static void destroy_link_encoders(struct dc *dc) static struct dc_perf_trace *dc_perf_trace_create(void) { - return kzalloc(sizeof(struct dc_perf_trace), GFP_KERNEL); + return kzalloc_obj(struct dc_perf_trace); } static void dc_perf_trace_destroy(struct dc_perf_trace **perf_trace) @@ -701,6 +701,7 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream, * once. * @idx: Capture CRC on which CRC engine instance * @reset: Reset CRC engine before the configuration + * @crc_poly_mode: CRC polynomial mode * * By default, the entire frame is used to calculate the CRC. * @@ -709,7 +710,7 @@ dc_stream_forward_multiple_crc_window(struct dc_stream_state *stream, */ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, struct crc_params *crc_window, bool enable, bool continuous, - uint8_t idx, bool reset) + uint8_t idx, bool reset, enum crc_poly_mode crc_poly_mode) { struct pipe_ctx *pipe; struct crc_params param; @@ -733,6 +734,7 @@ bool dc_stream_configure_crc(struct dc *dc, struct dc_stream_state *stream, param.windowb_y_start = 0; param.windowb_x_end = pipe->stream->timing.h_addressable; param.windowb_y_end = pipe->stream->timing.v_addressable; + param.crc_poly_mode = crc_poly_mode; if (crc_window) { param.windowa_x_start = crc_window->windowa_x_start; @@ -1003,7 +1005,7 @@ static bool dc_construct_ctx(struct dc *dc, { struct dc_context *dc_ctx; - dc_ctx = kzalloc(sizeof(*dc_ctx), GFP_KERNEL); + dc_ctx = kzalloc_obj(*dc_ctx); if (!dc_ctx) return false; @@ -1021,7 +1023,7 @@ static bool dc_construct_ctx(struct dc *dc, dc_ctx->clk_reg_offsets = init_params->clk_reg_offsets; /* Create logger */ - dc_ctx->logger = kmalloc(sizeof(*dc_ctx->logger), GFP_KERNEL); + dc_ctx->logger = kmalloc_obj(*dc_ctx->logger); if (!dc_ctx->logger) { kfree(dc_ctx); @@ -1061,7 +1063,7 @@ static bool dc_construct(struct dc *dc, dc->config = init_params->flags; // Allocate memory for the vm_helper - dc->vm_helper = kzalloc(sizeof(struct vm_helper), GFP_KERNEL); + dc->vm_helper = kzalloc_obj(struct vm_helper); if (!dc->vm_helper) { dm_error("%s: failed to create dc->vm_helper\n", __func__); goto fail; @@ -1069,7 +1071,7 @@ static bool dc_construct(struct dc *dc, memcpy(&dc->bb_overrides, &init_params->bb_overrides, sizeof(dc->bb_overrides)); - dc_dceip = kzalloc(sizeof(*dc_dceip), GFP_KERNEL); + dc_dceip = kzalloc_obj(*dc_dceip); if (!dc_dceip) { dm_error("%s: failed to create dceip\n", __func__); goto fail; @@ -1077,14 +1079,14 @@ static bool dc_construct(struct dc *dc, dc->bw_dceip = dc_dceip; - dc_vbios = kzalloc(sizeof(*dc_vbios), GFP_KERNEL); + dc_vbios = kzalloc_obj(*dc_vbios); if (!dc_vbios) { dm_error("%s: failed to create vbios\n", __func__); goto fail; } dc->bw_vbios = dc_vbios; - dcn_soc = kzalloc(sizeof(*dcn_soc), GFP_KERNEL); + dcn_soc = kzalloc_obj(*dcn_soc); if (!dcn_soc) { dm_error("%s: failed to create dcn_soc\n", __func__); goto fail; @@ -1092,7 +1094,7 @@ static bool dc_construct(struct dc *dc, dc->dcn_soc = dcn_soc; - dcn_ip = kzalloc(sizeof(*dcn_ip), GFP_KERNEL); + dcn_ip = kzalloc_obj(*dcn_ip); if (!dcn_ip) { dm_error("%s: failed to create dcn_ip\n", __func__); goto fail; @@ -1494,7 +1496,7 @@ static void disable_vbios_mode_if_required( struct dc *dc_create(const struct dc_init_data *init_params) { - struct dc *dc = kzalloc(sizeof(*dc), GFP_KERNEL); + struct dc *dc = kzalloc_obj(*dc); unsigned int full_pipe_count; if (!dc) @@ -2611,8 +2613,7 @@ bool dc_set_generic_gpio_for_stereo(bool enable, enum gpio_result gpio_result = GPIO_RESULT_NON_SPECIFIC_ERROR; struct gpio_pin_info pin_info; struct gpio *generic; - struct gpio_generic_mux_config *config = kzalloc(sizeof(struct gpio_generic_mux_config), - GFP_KERNEL); + struct gpio_generic_mux_config *config = kzalloc_obj(struct gpio_generic_mux_config); if (!config) return false; @@ -3366,6 +3367,10 @@ static void copy_stream_update_to_stream(struct dc *dc, stream->scaler_sharpener_update = *update->scaler_sharpener_update; if (update->sharpening_required) stream->sharpening_required = *update->sharpening_required; + + if (update->drr_trigger_mode) { + stream->drr_trigger_mode = *update->drr_trigger_mode; + } } static void backup_planes_and_stream_state( @@ -3860,7 +3865,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc, if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream)) return; - if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) + if (!dc->config.frame_update_cmd_version2 && !dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) return; memset(&cmd, 0x0, sizeof(cmd)); @@ -3880,7 +3885,11 @@ void dc_dmub_update_dirty_rect(struct dc *dc, if (srf_updates[i].surface->flip_immediate) continue; - update_dirty_rect->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; + if (dc->config.frame_update_cmd_version2) + update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2; + else + update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1; + update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count; memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects, sizeof(flip_addr->dirty_rects)); @@ -3894,6 +3903,7 @@ void dc_dmub_update_dirty_rect(struct dc *dc, update_dirty_rect->panel_inst = panel_inst; update_dirty_rect->pipe_idx = j; + update_dirty_rect->otg_inst = pipe_ctx->stream_res.tg->inst; dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_NO_WAIT); } } @@ -3916,7 +3926,7 @@ static void build_dmub_update_dirty_rect( if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream)) return; - if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) + if (!dc->config.frame_update_cmd_version2 && !dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) return; memset(&cmd, 0x0, sizeof(cmd)); @@ -3935,7 +3945,12 @@ static void build_dmub_update_dirty_rect( /* Do not send in immediate flip mode */ if (srf_updates[i].surface->flip_immediate) continue; - update_dirty_rect->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; + + if (dc->config.frame_update_cmd_version2) + update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2; + else + update_dirty_rect->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1; + update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count; memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects, sizeof(flip_addr->dirty_rects)); @@ -3948,6 +3963,7 @@ static void build_dmub_update_dirty_rect( continue; update_dirty_rect->panel_inst = panel_inst; update_dirty_rect->pipe_idx = j; + update_dirty_rect->otg_inst = pipe_ctx->stream_res.tg->inst; dc_dmub_cmd[*dmub_cmd_count].dmub_cmd = cmd; dc_dmub_cmd[*dmub_cmd_count].wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT; (*dmub_cmd_count)++; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c index 848c267ef11e..03d125f794b0 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_resource.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_resource.c @@ -37,7 +37,7 @@ #include "dpp.h" #include "core_types.h" #include "set_mode_types.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dpcd_defs.h" #include "link_enc_cfg.h" #include "link_service.h" @@ -45,7 +45,7 @@ #include "dc_state_priv.h" #include "dc_stream_priv.h" -#include "virtual/virtual_link_hwss.h" +#include "link/hwss/link_hwss_virtual.h" #include "link/hwss/link_hwss_dio.h" #include "link/hwss/link_hwss_dpia.h" #include "link/hwss/link_hwss_hpo_dp.h" diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c index 455fa5dd1420..e5ac7056a187 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_sink.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_sink.c @@ -76,7 +76,7 @@ void dc_sink_release(struct dc_sink *sink) struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params) { - struct dc_sink *sink = kzalloc(sizeof(*sink), GFP_KERNEL); + struct dc_sink *sink = kzalloc_obj(*sink); if (NULL == sink) goto alloc_fail; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_state.c b/drivers/gpu/drm/amd/display/dc/core/dc_state.c index 2de8ef4a58ec..a40e5c44143f 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_state.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_state.c @@ -195,7 +195,7 @@ struct dc_state *dc_state_create(struct dc *dc, struct dc_state_create_params *p { struct dc_state *state; - state = kvzalloc(sizeof(struct dc_state), GFP_KERNEL); + state = kvzalloc_obj(struct dc_state); if (!state) return NULL; @@ -251,8 +251,7 @@ struct dc_state *dc_state_create_copy(struct dc_state *src_state) { struct dc_state *new_state; - new_state = kvmalloc(sizeof(struct dc_state), - GFP_KERNEL); + new_state = kvmalloc_obj(struct dc_state); if (!new_state) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c index f59020f1a722..baf820e6eae8 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_stream.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_stream.c @@ -170,11 +170,11 @@ struct dc_stream_state *dc_create_stream_for_sink( if (sink == NULL) goto fail; - stream = kzalloc(sizeof(struct dc_stream_state), GFP_KERNEL); + stream = kzalloc_obj(struct dc_stream_state, GFP_ATOMIC); if (stream == NULL) goto fail; - stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_KERNEL); + stream->update_scratch = kzalloc((int32_t) dc_update_scratch_space_size(), GFP_ATOMIC); if (stream->update_scratch == NULL) goto fail; @@ -515,16 +515,18 @@ bool dc_stream_program_cursor_position( } } - /* apply manual trigger */ - int i; + if (stream->drr_trigger_mode == DRR_TRIGGER_ON_FLIP_AND_CURSOR) { + /* apply manual trigger */ + int i; - for (i = 0; i < dc->res_pool->pipe_count; i++) { - struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *pipe_ctx = &dc->current_state->res_ctx.pipe_ctx[i]; - /* trigger event on first pipe with current stream */ - if (stream == pipe_ctx->stream) { - pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); - break; + /* trigger event on first pipe with current stream */ + if (stream == pipe_ctx->stream) { + pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); + break; + } } } diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c index 0971dfa25845..d4c40b44d909 100644 --- a/drivers/gpu/drm/amd/display/dc/core/dc_surface.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc_surface.c @@ -85,8 +85,8 @@ uint8_t dc_plane_get_pipe_mask(struct dc_state *dc_state, const struct dc_plane ******************************************************************************/ struct dc_plane_state *dc_create_plane_state(const struct dc *dc) { - struct dc_plane_state *plane_state = kvzalloc(sizeof(*plane_state), - GFP_ATOMIC); + struct dc_plane_state *plane_state = kvzalloc_obj(*plane_state, + GFP_ATOMIC); if (NULL == plane_state) return NULL; @@ -195,7 +195,7 @@ void dc_gamma_release(struct dc_gamma **gamma) struct dc_gamma *dc_create_gamma(void) { - struct dc_gamma *gamma = kvzalloc(sizeof(*gamma), GFP_KERNEL); + struct dc_gamma *gamma = kvzalloc_obj(*gamma); if (gamma == NULL) goto alloc_fail; @@ -225,7 +225,7 @@ void dc_transfer_func_release(struct dc_transfer_func *tf) struct dc_transfer_func *dc_create_transfer_func(void) { - struct dc_transfer_func *tf = kvzalloc(sizeof(*tf), GFP_KERNEL); + struct dc_transfer_func *tf = kvzalloc_obj(*tf); if (tf == NULL) goto alloc_fail; @@ -247,7 +247,7 @@ static void dc_3dlut_func_free(struct kref *kref) struct dc_3dlut *dc_create_3dlut_func(void) { - struct dc_3dlut *lut = kvzalloc(sizeof(*lut), GFP_KERNEL); + struct dc_3dlut *lut = kvzalloc_obj(*lut); if (lut == NULL) goto alloc_fail; diff --git a/drivers/gpu/drm/amd/display/dc/dc.h b/drivers/gpu/drm/amd/display/dc/dc.h index ab19b6230945..4c4239cac863 100644 --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -63,7 +63,7 @@ struct dcn_dsc_reg_state; struct dcn_optc_reg_state; struct dcn_dccg_reg_state; -#define DC_VER "3.2.367" +#define DC_VER "3.2.369" /** * MAX_SURFACES - representative of the upper bound of surfaces that can be piped to a single CRTC @@ -505,7 +505,6 @@ union allow_lttpr_non_transparent_mode { } bits; unsigned char raw; }; - /* Structure to hold configuration flags set by dm at dc creation. */ struct dc_config { bool gpu_vm_support; @@ -560,6 +559,7 @@ struct dc_config { bool enable_dpia_pre_training; bool unify_link_enc_assignment; bool enable_cursor_offload; + bool frame_update_cmd_version2; struct spl_sharpness_range dcn_sharpness_range; struct spl_sharpness_range dcn_override_sharpness_range; }; diff --git a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c index dc1b3f6c22c9..b15360bcdacf 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c +++ b/drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c @@ -60,7 +60,7 @@ static void dc_dmub_srv_handle_failure(struct dc_dmub_srv *dc_dmub_srv) struct dc_dmub_srv *dc_dmub_srv_create(struct dc *dc, struct dmub_srv *dmub) { struct dc_dmub_srv *dc_srv = - kzalloc(sizeof(struct dc_dmub_srv), GFP_KERNEL); + kzalloc_obj(struct dc_dmub_srv); if (dc_srv == NULL) { BREAK_TO_DEBUGGER(); @@ -1034,12 +1034,19 @@ static void dc_build_cursor_update_payload0( struct pipe_ctx *pipe_ctx, uint8_t p_idx, struct dmub_cmd_update_cursor_payload0 *payload) { + struct dc *dc = pipe_ctx->stream->ctx->dc; struct hubp *hubp = pipe_ctx->plane_res.hubp; unsigned int panel_inst = 0; - if (!dc_get_edp_link_panel_inst(hubp->ctx->dc, - pipe_ctx->stream->link, &panel_inst)) - return; + if (dc->config.frame_update_cmd_version2 == true) { + /* Don't need panel_inst for command version2 */ + payload->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_2; + } else { + if (!dc_get_edp_link_panel_inst(hubp->ctx->dc, + pipe_ctx->stream->link, &panel_inst)) + return; + payload->cmd_version = DMUB_CMD_CURSOR_UPDATE_VERSION_1; + } /* Payload: Cursor Rect is built from position & attribute * x & y are obtained from postion @@ -1052,8 +1059,8 @@ static void dc_build_cursor_update_payload0( payload->enable = hubp->pos.cur_ctl.bits.cur_enable; payload->pipe_idx = p_idx; - payload->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; payload->panel_inst = panel_inst; + payload->otg_inst = pipe_ctx->stream_res.tg->inst; } static void dc_build_cursor_position_update_payload0( diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h index 719b98d8e8ca..86394203cee7 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_stream.h +++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h @@ -183,6 +183,11 @@ struct luminance_data { int dm_max_decrease_from_nominal; }; +enum dc_drr_trigger_mode { + DRR_TRIGGER_ON_FLIP = 0, + DRR_TRIGGER_ON_FLIP_AND_CURSOR, +}; + struct dc_stream_state { // sink is deprecated, new code should not reference // this pointer @@ -316,6 +321,8 @@ struct dc_stream_state { bool scaler_sharpener_update; bool sharpening_required; + enum dc_drr_trigger_mode drr_trigger_mode; + struct dc_update_scratch_space *update_scratch; }; @@ -366,6 +373,8 @@ struct dc_stream_update { bool *hw_cursor_req; bool *scaler_sharpener_update; bool *sharpening_required; + + enum dc_drr_trigger_mode *drr_trigger_mode; }; bool dc_is_stream_unchanged( @@ -584,7 +593,8 @@ bool dc_stream_configure_crc(struct dc *dc, bool enable, bool continuous, uint8_t idx, - bool reset); + bool reset, + enum crc_poly_mode crc_poly_mode); bool dc_stream_get_crc(struct dc *dc, struct dc_stream_state *stream, diff --git a/drivers/gpu/drm/amd/display/dc/dc_types.h b/drivers/gpu/drm/amd/display/dc/dc_types.h index 0e953059ff6d..bddb16bb76d4 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_types.h @@ -1230,7 +1230,7 @@ struct replay_settings { uint32_t replay_desync_error_fail_count; /* The frame skip number dal send to DMUB */ uint16_t frame_skip_number; - /* Current Panel Replay event */ + /* Current Panel Replay events */ uint32_t replay_events; }; @@ -1256,7 +1256,7 @@ struct dc_panel_config { unsigned int max_nonboost_brightness_millinits; unsigned int min_brightness_millinits; } nits_brightness; - /* PSR */ + /* PSR/Replay */ struct psr { bool disable_psr; bool disallow_psrsu; @@ -1266,6 +1266,8 @@ struct dc_panel_config { bool rc_allow_fullscreen_VPB; bool read_psrcap_again; unsigned int replay_enable_option; + bool enable_frame_skipping; + bool enable_teams_optimization; } psr; /* ABM */ struct varib { @@ -1282,6 +1284,27 @@ struct dc_panel_config { struct ilr { bool optimize_edp_link_rate; /* eDP ILR */ } ilr; + /* Adaptive VariBright*/ + struct adaptive_vb { + bool disable_adaptive_vb; + unsigned int default_abm_vb_levels; // default value = 0xDCAA6414 + unsigned int default_cacp_vb_levels; + unsigned int default_abm_vb_hdr_levels; // default value = 0xB4805A40 + unsigned int default_cacp_vb_hdr_levels; + unsigned int abm_scaling_factors; // default value = 0x23210012 + unsigned int cacp_scaling_factors; + unsigned int battery_life_configures; // default value = 0x0A141E + unsigned int abm_backlight_adaptive_pwl_1; // default value = 0x6A4F7244 + unsigned int abm_backlight_adaptive_pwl_2; // default value = 0x4C615659 + unsigned int abm_backlight_adaptive_pwl_3; // default value = 0x0064 + unsigned int cacp_backlight_adaptive_pwl_1; + unsigned int cacp_backlight_adaptive_pwl_2; + unsigned int cacp_backlight_adaptive_pwl_3; + } adaptive_vb; + /* Ramless Idle Opt*/ + struct rio { + bool disable_rio; + } rio; }; #define MAX_SINKS_PER_LINK 4 diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c index 33d8bd91cb01..13ba7f5ce13e 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.c @@ -131,6 +131,54 @@ void dccg2_otg_drop_pixel(struct dccg *dccg, void dccg2_init(struct dccg *dccg) { + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + /* Hardcoded register values for DCN20 + * These are specific to 100Mhz refclk + * Different ASICs with different refclk may override this in their own init + */ + REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x00120264); + REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x001186a0); + REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0x0e01003c); + + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); +} + +void dccg2_refclk_setup(struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + /* REFCLK programming that must occur after hubbub initialization */ + if (REG(REFCLK_CNTL)) + REG_WRITE(REFCLK_CNTL, 0); +} + +bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + return REG_READ(MICROSECOND_TIME_BASE_DIV) == 0x00120464; +} + +void dccg2_allow_clock_gating(struct dccg *dccg, bool allow) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + if (allow) { + REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + } else { + REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0xFFFFFFFF); + REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0xFFFFFFFF); + } +} + +void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable) +{ + struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); + + REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, enable ? 0 : 1); } static const struct dccg_funcs dccg2_funcs = { @@ -139,7 +187,11 @@ static const struct dccg_funcs dccg2_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg2_create( @@ -148,7 +200,7 @@ struct dccg *dccg2_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h index 8bdffd9ff31b..4c4e61bc91b5 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn20/dcn20_dccg.h @@ -37,7 +37,12 @@ SR(REFCLK_CNTL),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 0),\ DCCG_SRII(PIXEL_RATE_CNTL, OTG, 1),\ - SR(DISPCLK_FREQ_CHANGE_CNTL) + SR(DISPCLK_FREQ_CHANGE_CNTL),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ + SR(MICROSECOND_TIME_BASE_DIV),\ + SR(MILLISECOND_TIME_BASE_DIV),\ + SR(DCCG_GATE_DISABLE_CNTL),\ + SR(DCCG_GATE_DISABLE_CNTL2) #define DCCG_REG_LIST_DCN2() \ DCCG_COMMON_REG_LIST_DCN_BASE(),\ @@ -81,7 +86,8 @@ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 0, mask_sh),\ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, ADD_PIXEL, 1, mask_sh),\ DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 0, mask_sh),\ - DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh) + DCCG_SFII(OTG, PIXEL_RATE_CNTL, OTG, DROP_PIXEL, 1, mask_sh),\ + DCCG_SF(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, mask_sh) @@ -130,7 +136,8 @@ type DISPCLK_CHG_FWD_CORR_DISABLE;\ type DISPCLK_FREQ_CHANGE_CNTL;\ type OTG_ADD_PIXEL[MAX_PIPES];\ - type OTG_DROP_PIXEL[MAX_PIPES]; + type OTG_DROP_PIXEL[MAX_PIPES];\ + type DC_MEM_GLOBAL_PWR_REQ_DIS; #define DCCG3_REG_FIELD_LIST(type) \ type HDMICHARCLK0_EN;\ @@ -515,6 +522,11 @@ void dccg2_otg_drop_pixel(struct dccg *dccg, void dccg2_init(struct dccg *dccg); +void dccg2_refclk_setup(struct dccg *dccg); +void dccg2_allow_clock_gating(struct dccg *dccg, bool allow); +void dccg2_enable_memory_low_power(struct dccg *dccg, bool enable); +bool dccg2_is_s0i3_golden_init_wa_done(struct dccg *dccg); + struct dccg *dccg2_create( struct dc_context *ctx, const struct dccg_registers *regs, diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c index 9a3402148fde..5b9ba9a811ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn201/dcn201_dccg.c @@ -24,6 +24,7 @@ */ #include "dcn201_dccg.h" +#include "dcn20/dcn20_dccg.h" #include "reg_helper.h" #include "core_types.h" @@ -56,7 +57,11 @@ static const struct dccg_funcs dccg201_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg201_create( @@ -65,7 +70,7 @@ struct dccg *dccg201_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c index d07c04458d31..c4d4eea140f3 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn21/dcn21_dccg.c @@ -96,6 +96,25 @@ static void dccg21_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppcl dccg->pipe_dppclk_khz[dpp_inst] = req_dppclk; } +/* + * On DCN21 S0i3 resume, BIOS programs MICROSECOND_TIME_BASE_DIV to + * 0x00120464 as a marker that golden init has already been done. + * dcn21_s0i3_golden_init_wa() reads this marker later in bios_golden_init() + * to decide whether to skip golden init. + * + * dccg2_init() unconditionally overwrites MICROSECOND_TIME_BASE_DIV to + * 0x00120264, destroying the marker before it can be read. + * + * Guard the call: if the S0i3 marker is present, skip dccg2_init() so the + * WA can function correctly. bios_golden_init() will handle init in that case. + */ +static void dccg21_init(struct dccg *dccg) +{ + if (dccg2_is_s0i3_golden_init_wa_done(dccg)) + return; + + dccg2_init(dccg); +} static const struct dccg_funcs dccg21_funcs = { .update_dpp_dto = dccg21_update_dpp_dto, @@ -103,7 +122,11 @@ static const struct dccg_funcs dccg21_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg21_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg21_create( @@ -112,7 +135,7 @@ struct dccg *dccg21_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c index d445dfefc047..ca947d710ad1 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn30/dcn30_dccg.c @@ -49,7 +49,11 @@ static const struct dccg_funcs dccg3_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg3_create( @@ -58,7 +62,7 @@ struct dccg *dccg3_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { @@ -83,7 +87,7 @@ struct dccg *dccg30_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c index 97e9be87afd9..837f4e3d1a60 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.c @@ -48,7 +48,11 @@ static const struct dccg_funcs dccg301_funcs = { .set_fifo_errdet_ovr_en = dccg2_set_fifo_errdet_ovr_en, .otg_add_pixel = dccg2_otg_add_pixel, .otg_drop_pixel = dccg2_otg_drop_pixel, - .dccg_init = dccg2_init + .dccg_init = dccg2_init, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg301_create( @@ -57,7 +61,7 @@ struct dccg *dccg301_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h index 067e49cb238e..e2381ca0be0b 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn301/dcn301_dccg.h @@ -34,7 +34,13 @@ DCCG_SRII(DTO_PARAM, DPPCLK, 1),\ DCCG_SRII(DTO_PARAM, DPPCLK, 2),\ DCCG_SRII(DTO_PARAM, DPPCLK, 3),\ - SR(REFCLK_CNTL) + SR(REFCLK_CNTL),\ + SR(DISPCLK_FREQ_CHANGE_CNTL),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ + SR(MICROSECOND_TIME_BASE_DIV),\ + SR(MILLISECOND_TIME_BASE_DIV),\ + SR(DCCG_GATE_DISABLE_CNTL),\ + SR(DCCG_GATE_DISABLE_CNTL2) #define DCCG_MASK_SH_LIST_DCN301(mask_sh) \ DCCG_SFI(DPPCLK_DTO_CTRL, DTO_ENABLE, DPPCLK, 0, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c index 97df04b7e39d..7f58acfe1177 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.c @@ -26,6 +26,7 @@ #include "reg_helper.h" #include "core_types.h" #include "dcn31_dccg.h" +#include "dcn20/dcn20_dccg.h" #include "dal_asic_id.h" #define TO_DCN_DCCG(dccg)\ @@ -850,6 +851,10 @@ static const struct dccg_funcs dccg31_funcs = { .disable_dsc = dccg31_disable_dscclk, .enable_dsc = dccg31_enable_dscclk, .dccg_read_reg_state = dccg31_read_reg_state, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg31_create( @@ -858,7 +863,7 @@ struct dccg *dccg31_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h index bf659920d4cc..b5e3849ef12a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn31/dcn31_dccg.h @@ -64,9 +64,12 @@ SR(DSCCLK1_DTO_PARAM),\ SR(DSCCLK2_DTO_PARAM),\ SR(DSCCLK_DTO_CTRL),\ + SR(DCCG_GATE_DISABLE_CNTL),\ SR(DCCG_GATE_DISABLE_CNTL2),\ SR(DCCG_GATE_DISABLE_CNTL3),\ - SR(HDMISTREAMCLK0_DTO_PARAM) + SR(HDMISTREAMCLK0_DTO_PARAM),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ + SR(MICROSECOND_TIME_BASE_DIV) #define DCCG_MASK_SH_LIST_DCN31(mask_sh) \ diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c index ef3db6beba25..ac6a909187c0 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.c @@ -29,6 +29,7 @@ #include "dcn31/dcn31_dccg.h" #include "dcn314_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -378,7 +379,11 @@ static const struct dccg_funcs dccg314_funcs = { .trigger_dio_fifo_resync = dccg314_trigger_dio_fifo_resync, .set_valid_pixel_rate = dccg314_set_valid_pixel_rate, .set_dtbclk_p_src = dccg314_set_dtbclk_p_src, - .dccg_read_reg_state = dccg31_read_reg_state + .dccg_read_reg_state = dccg31_read_reg_state, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg314_create( @@ -387,7 +392,7 @@ struct dccg *dccg314_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h index a609635f35db..ecbdc05f7c45 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn314/dcn314_dccg.h @@ -70,11 +70,14 @@ SR(DSCCLK2_DTO_PARAM),\ SR(DSCCLK3_DTO_PARAM),\ SR(DSCCLK_DTO_CTRL),\ + SR(DCCG_GATE_DISABLE_CNTL),\ SR(DCCG_GATE_DISABLE_CNTL2),\ SR(DCCG_GATE_DISABLE_CNTL3),\ SR(HDMISTREAMCLK0_DTO_PARAM),\ SR(OTG_PIXEL_RATE_DIV),\ - SR(DTBCLK_P_CNTL) + SR(DTBCLK_P_CNTL),\ + SR(DC_MEM_GLOBAL_PWR_REQ_CNTL),\ + SR(MICROSECOND_TIME_BASE_DIV) #define DCCG_MASK_SH_LIST_DCN314_COMMON(mask_sh) \ DCCG_SFI(DPPCLK_DTO_CTRL, DTO_DB_EN, DPPCLK, 0, mask_sh),\ diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c index 21a6ca5ca192..e817cd7c2b6a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn32/dcn32_dccg.c @@ -26,6 +26,7 @@ #include "reg_helper.h" #include "core_types.h" #include "dcn32_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -347,6 +348,10 @@ static const struct dccg_funcs dccg32_funcs = { .get_pixel_rate_div = dccg32_get_pixel_rate_div, .trigger_dio_fifo_resync = dccg32_trigger_dio_fifo_resync, .set_dtbclk_p_src = dccg32_set_dtbclk_p_src, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; struct dccg *dccg32_create( @@ -355,7 +360,7 @@ struct dccg *dccg32_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c index bd2f528137b2..0b7908fbb115 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.c @@ -26,6 +26,7 @@ #include "core_types.h" #include "resource.h" #include "dcn35_dccg.h" +#include "dcn20/dcn20_dccg.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -1105,7 +1106,7 @@ static void dccg35_enable_dpstreamclk_new(struct dccg *dccg, dccg35_set_dpstreamclk_src_new(dccg, src, inst); } -static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg) +void dccg35_trigger_dio_fifo_resync(struct dccg *dccg) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); uint32_t dispclk_rdivider_value = 0; @@ -1114,6 +1115,7 @@ static void dccg35_trigger_dio_fifo_resync(struct dccg *dccg) if (dispclk_rdivider_value != 0) REG_UPDATE(DENTIST_DISPCLK_CNTL, DENTIST_DISPCLK_WDIVIDER, dispclk_rdivider_value); } + static void dccg35_wait_for_dentist_change_done( struct dccg *dccg) { @@ -1151,8 +1153,7 @@ static void dcn35_set_dppclk_enable(struct dccg *dccg, } -static void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, - int req_dppclk) +void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1498,11 +1499,7 @@ static void dccg35_set_dpstreamclk( __func__, dp_hpo_inst, (src == REFCLK) ? 0 : 1, otg_inst); } - -static void dccg35_set_dpstreamclk_root_clock_gating( - struct dccg *dccg, - int dp_hpo_inst, - bool enable) +void dccg35_set_dpstreamclk_root_clock_gating(struct dccg *dccg, int dp_hpo_inst, bool enable) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1669,10 +1666,7 @@ static void dccg35_set_valid_pixel_rate( dccg35_set_dtbclk_dto(dccg, &dto_params); } -static void dccg35_dpp_root_clock_control( - struct dccg *dccg, - unsigned int dpp_inst, - bool clock_on) +void dccg35_dpp_root_clock_control(struct dccg *dccg, unsigned int dpp_inst, bool clock_on) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1704,9 +1698,7 @@ static void dccg35_dpp_root_clock_control( DC_LOG_DEBUG("%s: dpp_inst(%d) clock_on = %d\n", __func__, dpp_inst, clock_on); } -static void dccg35_disable_symclk32_se( - struct dccg *dccg, - int hpo_se_inst) +void dccg35_disable_symclk32_se(struct dccg *dccg, int hpo_se_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1813,7 +1805,7 @@ void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value) REG_UPDATE(DCCG_GLOBAL_FGCG_REP_CNTL, DCCG_GLOBAL_FGCG_REP_DIS, !value); } -static void dccg35_enable_dscclk(struct dccg *dccg, int inst) +void dccg35_enable_dscclk(struct dccg *dccg, int inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1860,8 +1852,7 @@ static void dccg35_enable_dscclk(struct dccg *dccg, int inst) udelay(10); } -static void dccg35_disable_dscclk(struct dccg *dccg, - int inst) +void dccg35_disable_dscclk(struct dccg *dccg, int inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -1906,7 +1897,7 @@ static void dccg35_disable_dscclk(struct dccg *dccg, udelay(10); } -static void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) +void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) { struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -2013,7 +2004,7 @@ static uint8_t dccg35_get_number_enabled_symclk_fe_connected_to_be(struct dccg * return num_enabled_symclk_fe; } -static void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) +void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst) { uint8_t num_enabled_symclk_fe = 0; struct dcn_dccg *dccg_dcn = TO_DCN_DCCG(dccg); @@ -2421,6 +2412,10 @@ static const struct dccg_funcs dccg35_funcs_new = { .enable_symclk_se = dccg35_enable_symclk_se_cb, .disable_symclk_se = dccg35_disable_symclk_se_cb, .set_dtbclk_p_src = dccg35_set_dtbclk_p_src_cb, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done /* Deprecated - for backward compatibility only */ }; static const struct dccg_funcs dccg35_funcs = { @@ -2452,8 +2447,12 @@ static const struct dccg_funcs dccg35_funcs = { .enable_symclk_se = dccg35_enable_symclk_se, .disable_symclk_se = dccg35_disable_symclk_se, .set_dtbclk_p_src = dccg35_set_dtbclk_p_src, + .refclk_setup = dccg2_refclk_setup, /* Deprecated - for backward compatibility only */ + .allow_clock_gating = dccg2_allow_clock_gating, + .enable_memory_low_power = dccg2_enable_memory_low_power, + .is_s0i3_golden_init_wa_done = dccg2_is_s0i3_golden_init_wa_done, /* Deprecated - for backward compatibility only */ .dccg_root_gate_disable_control = dccg35_root_gate_disable_control, - .dccg_read_reg_state = dccg31_read_reg_state, + .dccg_read_reg_state = dccg31_read_reg_state }; struct dccg *dccg35_create( @@ -2462,7 +2461,7 @@ struct dccg *dccg35_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h index 7b9c36456cd9..554700287c1a 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn35/dcn35_dccg.h @@ -249,8 +249,25 @@ struct dccg *dccg35_create( void dccg35_init(struct dccg *dccg); +void dccg35_trigger_dio_fifo_resync(struct dccg *dccg); + +void dccg35_update_dpp_dto(struct dccg *dccg, int dpp_inst, int req_dppclk); + void dccg35_enable_global_fgcg_rep(struct dccg *dccg, bool value); void dccg35_root_gate_disable_control(struct dccg *dccg, uint32_t pipe_idx, uint32_t disable_clock_gating); +void dccg35_set_dpstreamclk_root_clock_gating(struct dccg *dccg, int dp_hpo_inst, bool enable); + +void dccg35_set_hdmistreamclk_root_clock_gating(struct dccg *dccg, bool enable); + +void dccg35_dpp_root_clock_control(struct dccg *dccg, unsigned int dpp_inst, bool clock_on); + +void dccg35_disable_symclk32_se(struct dccg *dccg, int hpo_se_inst); + +void dccg35_enable_dscclk(struct dccg *dccg, int inst); +void dccg35_disable_dscclk(struct dccg *dccg, int inst); + +void dccg35_enable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); +void dccg35_disable_symclk_se(struct dccg *dccg, uint32_t stream_enc_inst, uint32_t link_enc_inst); #endif //__DCN35_DCCG_H__ diff --git a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c index 663a18ee5162..a37f94dec6f2 100644 --- a/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c +++ b/drivers/gpu/drm/amd/display/dc/dccg/dcn401/dcn401_dccg.c @@ -27,6 +27,7 @@ #include "core_types.h" #include "dcn401_dccg.h" #include "dcn31/dcn31_dccg.h" +#include "dcn20/dcn20_dccg.h" /* #include "dmub_common.h" @@ -595,16 +596,6 @@ void dccg401_set_dp_dto( bool enable = false; - if (params->otg_inst > 3) { - /* dcn401 only has 4 instances */ - BREAK_TO_DEBUGGER(); - return; - } - if (!params->refclk_hz) { - BREAK_TO_DEBUGGER(); - return; - } - if (!dc_is_tmds_signal(params->signal)) { uint64_t dto_integer; uint64_t dto_phase_hz; @@ -612,6 +603,11 @@ void dccg401_set_dp_dto( enable = true; + if (!params->refclk_hz) { + BREAK_TO_DEBUGGER(); + return; + } + /* Set DTO values: * int = target_pix_rate / reference_clock * phase = target_pix_rate - int * reference_clock, @@ -866,6 +862,7 @@ static const struct dccg_funcs dccg401_funcs = { .update_dpp_dto = dccg401_update_dpp_dto, .get_dccg_ref_freq = dccg401_get_dccg_ref_freq, .dccg_init = dccg401_init, + .allow_clock_gating = dccg2_allow_clock_gating, .set_dpstreamclk = dccg401_set_dpstreamclk, .enable_symclk32_se = dccg31_enable_symclk32_se, .disable_symclk32_se = dccg31_disable_symclk32_se, @@ -895,7 +892,7 @@ struct dccg *dccg401_create( const struct dccg_shift *dccg_shift, const struct dccg_mask *dccg_mask) { - struct dcn_dccg *dccg_dcn = kzalloc(sizeof(*dccg_dcn), GFP_KERNEL); + struct dcn_dccg *dccg_dcn = kzalloc_obj(*dccg_dcn); struct dccg *base; if (dccg_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c index 2dcf394edf22..41169b42534c 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_abm.c @@ -283,7 +283,7 @@ struct abm *dce_abm_create( const struct dce_abm_shift *abm_shift, const struct dce_abm_mask *abm_mask) { - struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); + struct dce_abm *abm_dce = kzalloc_obj(*abm_dce); if (abm_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c index fcad61c618a1..d18490cd0f1e 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_audio.c @@ -1331,7 +1331,7 @@ struct audio *dce_audio_create( const struct dce_audio_mask *masks ) { - struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL); + struct dce_audio *audio = kzalloc_obj(*audio); if (audio == NULL) { ASSERT_CRITICAL(audio); @@ -1357,7 +1357,7 @@ struct audio *dce60_audio_create( const struct dce_audio_mask *masks ) { - struct dce_audio *audio = kzalloc(sizeof(*audio), GFP_KERNEL); + struct dce_audio *audio = kzalloc_obj(*audio); if (audio == NULL) { ASSERT_CRITICAL(audio); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c index e7acd6eec1fd..dca025b5ff1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clk_mgr.c @@ -848,7 +848,7 @@ struct clk_mgr *dce_clk_mgr_create( const struct clk_mgr_shift *clk_shift, const struct clk_mgr_mask *clk_mask) { - struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); + struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce); if (clk_mgr_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -871,7 +871,7 @@ struct clk_mgr *dce110_clk_mgr_create( const struct clk_mgr_shift *clk_shift, const struct clk_mgr_mask *clk_mask) { - struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); + struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce); if (clk_mgr_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -896,7 +896,7 @@ struct clk_mgr *dce112_clk_mgr_create( const struct clk_mgr_shift *clk_shift, const struct clk_mgr_mask *clk_mask) { - struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); + struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce); if (clk_mgr_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -917,7 +917,7 @@ struct clk_mgr *dce112_clk_mgr_create( struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx) { - struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), GFP_KERNEL); + struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce); if (clk_mgr_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -939,8 +939,7 @@ struct clk_mgr *dce120_clk_mgr_create(struct dc_context *ctx) struct clk_mgr *dce121_clk_mgr_create(struct dc_context *ctx) { - struct dce_clk_mgr *clk_mgr_dce = kzalloc(sizeof(*clk_mgr_dce), - GFP_KERNEL); + struct dce_clk_mgr *clk_mgr_dce = kzalloc_obj(*clk_mgr_dce); if (clk_mgr_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c index b4f5b4a6331a..5722be965422 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c @@ -1476,16 +1476,12 @@ static void get_ss_info_from_atombios( if (*ss_entries_num == 0) return; - ss_info = kcalloc(*ss_entries_num, - sizeof(struct spread_spectrum_info), - GFP_KERNEL); + ss_info = kzalloc_objs(struct spread_spectrum_info, *ss_entries_num); ss_info_cur = ss_info; if (ss_info == NULL) return; - ss_data = kcalloc(*ss_entries_num, - sizeof(struct spread_spectrum_data), - GFP_KERNEL); + ss_data = kzalloc_objs(struct spread_spectrum_data, *ss_entries_num); if (ss_data == NULL) goto out_free_info; diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c index 5f8fba45d98d..e871b72e43ef 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_dmcu.c @@ -1105,7 +1105,7 @@ struct dmcu *dce_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc_obj(*dmcu_dce); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -1126,7 +1126,7 @@ struct dmcu *dcn10_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc_obj(*dmcu_dce); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -1147,7 +1147,7 @@ struct dmcu *dcn20_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc_obj(*dmcu_dce); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); @@ -1168,7 +1168,7 @@ struct dmcu *dcn21_dmcu_create( const struct dce_dmcu_shift *dmcu_shift, const struct dce_dmcu_mask *dmcu_mask) { - struct dce_dmcu *dmcu_dce = kzalloc(sizeof(*dmcu_dce), GFP_KERNEL); + struct dce_dmcu *dmcu_dce = kzalloc_obj(*dmcu_dce); if (dmcu_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c index 7f0766b5fa3d..2ba3d3a3aac5 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.c @@ -102,6 +102,7 @@ static const struct link_encoder_funcs dce110_lnk_enc_funcs = { .enable_dp_output = dce110_link_encoder_enable_dp_output, .enable_dp_mst_output = dce110_link_encoder_enable_dp_mst_output, .enable_lvds_output = dce110_link_encoder_enable_lvds_output, + .enable_analog_output = dce110_link_encoder_enable_analog_output, .disable_output = dce110_link_encoder_disable_output, .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, .dp_set_phy_pattern = dce110_link_encoder_dp_set_phy_pattern, @@ -133,6 +134,21 @@ static enum bp_result link_transmitter_control( return result; } +static enum bp_result link_dac_encoder_control( + struct dce110_link_encoder *link_enc, + enum bp_encoder_control_action action, + uint32_t pix_clk_100hz) +{ + struct dc_bios *bios = link_enc->base.ctx->dc_bios; + struct bp_encoder_control encoder_control = {0}; + + encoder_control.action = action; + encoder_control.engine_id = link_enc->base.analog_engine; + encoder_control.pixel_clock = pix_clk_100hz / 10; + + return bios->funcs->encoder_control(bios, &encoder_control); +} + static void enable_phy_bypass_mode( struct dce110_link_encoder *enc110, bool enable) @@ -1021,6 +1037,16 @@ void dce110_link_encoder_hw_init( cntl.coherent = false; cntl.hpd_sel = enc110->base.hpd_source; + if (enc110->base.analog_engine != ENGINE_ID_UNKNOWN) { + result = link_dac_encoder_control(enc110, ENCODER_CONTROL_INIT, 0); + if (result != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table for DAC!\n", + __func__); + BREAK_TO_DEBUGGER(); + return; + } + } + /* The code below is only applicable to encoders with a digital transmitter. */ if (enc110->base.transmitter == TRANSMITTER_UNKNOWN) return; @@ -1175,6 +1201,22 @@ void dce110_link_encoder_enable_lvds_output( } } +void dce110_link_encoder_enable_analog_output( + struct link_encoder *enc, + uint32_t pixel_clock) +{ + struct dce110_link_encoder *enc110 = TO_DCE110_LINK_ENC(enc); + enum bp_result result; + + result = link_dac_encoder_control(enc110, ENCODER_CONTROL_ENABLE, pixel_clock); + + if (result != BP_RESULT_OK) { + DC_LOG_ERROR("%s: Failed to execute VBIOS command table!\n", + __func__); + BREAK_TO_DEBUGGER(); + } +} + /* enables DP PHY output */ void dce110_link_encoder_enable_dp_output( struct link_encoder *enc, @@ -1345,19 +1387,8 @@ void dce110_link_encoder_disable_output( struct bp_transmitter_control cntl = { 0 }; enum bp_result result; - switch (enc->analog_engine) { - case ENGINE_ID_DACA: - REG_UPDATE(DAC_ENABLE, DAC_ENABLE, 0); - break; - case ENGINE_ID_DACB: - /* DACB doesn't seem to be present on DCE6+, - * although there are references to it in the register file. - */ - DC_LOG_ERROR("%s DACB is unsupported\n", __func__); - break; - default: - break; - } + if (enc->analog_engine != ENGINE_ID_UNKNOWN) + link_dac_encoder_control(enc110, ENCODER_CONTROL_DISABLE, 0); /* The code below only applies to connectors that support digital signals. */ if (enc->transmitter == TRANSMITTER_UNKNOWN) @@ -1804,6 +1835,7 @@ static const struct link_encoder_funcs dce60_lnk_enc_funcs = { .enable_dp_output = dce60_link_encoder_enable_dp_output, .enable_dp_mst_output = dce60_link_encoder_enable_dp_mst_output, .enable_lvds_output = dce110_link_encoder_enable_lvds_output, + .enable_analog_output = dce110_link_encoder_enable_analog_output, .disable_output = dce110_link_encoder_disable_output, .dp_set_lane_settings = dce110_link_encoder_dp_set_lane_settings, .dp_set_phy_pattern = dce60_link_encoder_dp_set_phy_pattern, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h index 9ba533aa6f88..8841000361fb 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_link_encoder.h @@ -101,8 +101,7 @@ SRI(DP_SEC_CNTL, DP, id), \ SRI(DP_VID_STREAM_CNTL, DP, id), \ SRI(DP_DPHY_FAST_TRAINING, DP, id), \ - SRI(DP_SEC_CNTL1, DP, id), \ - SR(DAC_ENABLE) + SRI(DP_SEC_CNTL1, DP, id) #endif #define LE_DCE80_REG_LIST(id)\ @@ -268,6 +267,11 @@ void dce110_link_encoder_enable_lvds_output( enum clock_source_id clock_source, uint32_t pixel_clock); +/* enables analog output from the DAC */ +void dce110_link_encoder_enable_analog_output( + struct link_encoder *enc, + uint32_t pixel_clock); + /* disable PHY output */ void dce110_link_encoder_disable_output( struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c index 574618d5d4a4..87c19f17c799 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.c @@ -1498,7 +1498,10 @@ static void dig_connect_to_otg( { struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); + if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) + REG_UPDATE(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, tg_inst); + else + REG_UPDATE(DIG_FE_CNTL, DIG_SOURCE_SELECT, tg_inst); } static unsigned int dig_source_otg( @@ -1507,7 +1510,10 @@ static unsigned int dig_source_otg( uint32_t tg_inst = 0; struct dce110_stream_encoder *enc110 = DCE110STRENC_FROM_STRENC(enc); - REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); + if (enc->id == ENGINE_ID_DACA || enc->id == ENGINE_ID_DACB) + REG_GET(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, &tg_inst); + else + REG_GET(DIG_FE_CNTL, DIG_SOURCE_SELECT, &tg_inst); return tg_inst; } @@ -1568,16 +1574,25 @@ void dce110_stream_encoder_construct( enc110->se_mask = se_mask; } -static const struct stream_encoder_funcs dce110_an_str_enc_funcs = {}; +static const struct stream_encoder_funcs dce110_an_str_enc_funcs = { + .dig_connect_to_otg = dig_connect_to_otg, + .dig_source_otg = dig_source_otg, +}; void dce110_analog_stream_encoder_construct( struct dce110_stream_encoder *enc110, struct dc_context *ctx, struct dc_bios *bp, - enum engine_id eng_id) + enum engine_id eng_id, + const struct dce110_stream_enc_registers *regs, + const struct dce_stream_encoder_shift *se_shift, + const struct dce_stream_encoder_mask *se_mask) { enc110->base.funcs = &dce110_an_str_enc_funcs; enc110->base.ctx = ctx; enc110->base.id = eng_id; enc110->base.bp = bp; + enc110->regs = regs; + enc110->se_shift = se_shift; + enc110->se_mask = se_mask; } diff --git a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h index 068de1392121..342c0afe6a94 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/dce/dce_stream_encoder.h @@ -65,6 +65,7 @@ SRI(AFMT_60958_1, DIG, id), \ SRI(AFMT_60958_2, DIG, id), \ SRI(DIG_FE_CNTL, DIG, id), \ + SR(DAC_SOURCE_SELECT), \ SRI(HDMI_CONTROL, DIG, id), \ SRI(HDMI_GC, DIG, id), \ SRI(HDMI_GENERIC_PACKET_CONTROL0, DIG, id), \ @@ -290,7 +291,8 @@ #define SE_COMMON_MASK_SH_LIST_DCE80_100(mask_sh)\ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ SE_SF(TMDS_CNTL, TMDS_PIXEL_ENCODING, mask_sh),\ - SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh) + SE_SF(TMDS_CNTL, TMDS_COLOR_FORMAT, mask_sh),\ + SE_SF(DAC_SOURCE_SELECT, DAC_SOURCE_SELECT, mask_sh) #define SE_COMMON_MASK_SH_LIST_DCE110(mask_sh)\ SE_COMMON_MASK_SH_LIST_DCE_COMMON(mask_sh),\ @@ -494,6 +496,7 @@ struct dce_stream_encoder_shift { uint8_t DP_VID_N_MUL; uint8_t DP_VID_M_DOUBLE_VALUE_EN; uint8_t DIG_SOURCE_SELECT; + uint8_t DAC_SOURCE_SELECT; }; struct dce_stream_encoder_mask { @@ -626,6 +629,7 @@ struct dce_stream_encoder_mask { uint32_t DP_VID_N_MUL; uint32_t DP_VID_M_DOUBLE_VALUE_EN; uint32_t DIG_SOURCE_SELECT; + uint32_t DAC_SOURCE_SELECT; }; struct dce110_stream_enc_registers { @@ -653,6 +657,7 @@ struct dce110_stream_enc_registers { uint32_t AFMT_60958_1; uint32_t AFMT_60958_2; uint32_t DIG_FE_CNTL; + uint32_t DAC_SOURCE_SELECT; uint32_t DP_MSE_RATE_CNTL; uint32_t DP_MSE_RATE_UPDATE; uint32_t DP_PIXEL_FORMAT; @@ -712,7 +717,10 @@ void dce110_analog_stream_encoder_construct( struct dce110_stream_encoder *enc110, struct dc_context *ctx, struct dc_bios *bp, - enum engine_id eng_id); + enum engine_id eng_id, + const struct dce110_stream_enc_registers *regs, + const struct dce_stream_encoder_shift *se_shift, + const struct dce_stream_encoder_mask *se_mask); void dce110_se_audio_mute_control( struct stream_encoder *enc, bool mute); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c index 3b9011ef9b68..b686d89b79b2 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_abm.c @@ -222,7 +222,7 @@ struct abm *dmub_abm_create( const struct dce_abm_mask *abm_mask) { if (ctx->dc->caps.dmcub_support) { - struct dce_abm *abm_dce = kzalloc(sizeof(*abm_dce), GFP_KERNEL); + struct dce_abm *abm_dce = kzalloc_obj(*abm_dce); if (abm_dce == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c index 87af4fdc04a6..f94fd007af23 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_psr.c @@ -488,7 +488,7 @@ static void dmub_psr_construct(struct dmub_psr *psr, struct dc_context *ctx) */ struct dmub_psr *dmub_psr_create(struct dc_context *ctx) { - struct dmub_psr *psr = kzalloc(sizeof(struct dmub_psr), GFP_KERNEL); + struct dmub_psr *psr = kzalloc_obj(struct dmub_psr); if (psr == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c index fd8244c94687..28a218149b8b 100644 --- a/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c +++ b/drivers/gpu/drm/amd/display/dc/dce/dmub_replay.c @@ -438,7 +438,7 @@ static void dmub_replay_construct(struct dmub_replay *replay, struct dc_context */ struct dmub_replay *dmub_replay_create(struct dc_context *ctx) { - struct dmub_replay *replay = kzalloc(sizeof(struct dmub_replay), GFP_KERNEL); + struct dmub_replay *replay = kzalloc_obj(struct dmub_replay); if (replay == NULL) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c index 59a0961b49da..9be578ff8c88 100644 --- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_compressor.c @@ -394,7 +394,7 @@ void dce110_compressor_set_fbc_invalidation_triggers( struct compressor *dce110_compressor_create(struct dc_context *ctx) { struct dce110_compressor *cp110 = - kzalloc(sizeof(struct dce110_compressor), GFP_KERNEL); + kzalloc_obj(struct dce110_compressor); if (!cp110) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c b/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c index faae12cf7968..187f45a7f5e1 100644 --- a/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c +++ b/drivers/gpu/drm/amd/display/dc/dce112/dce112_compressor.c @@ -831,7 +831,7 @@ void dce112_compressor_construct(struct dce112_compressor *compressor, struct compressor *dce112_compressor_create(struct dc_context *ctx) { struct dce112_compressor *cp110 = - kzalloc(sizeof(struct dce112_compressor), GFP_KERNEL); + kzalloc_obj(struct dce112_compressor); if (!cp110) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/dio/Makefile b/drivers/gpu/drm/amd/display/dc/dio/Makefile index 0dfd480976f7..2f5619078e1f 100644 --- a/drivers/gpu/drm/amd/display/dc/dio/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dio/Makefile @@ -23,11 +23,20 @@ # # +############################################################################### +# VIRTUAL +############################################################################### +DIO_VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o + +AMD_DAL_DIO_VIRTUAL = $(addprefix $(AMDDALPATH)/dc/dio/virtual/,$(DIO_VIRTUAL)) + +AMD_DISPLAY_FILES += $(AMD_DAL_DIO_VIRTUAL) + ifdef CONFIG_DRM_AMD_DC_FP ############################################################################### # DCN10 ############################################################################### -DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o +DIO_DCN10 = dcn10_link_encoder.o dcn10_stream_encoder.o dcn10_dio.o AMD_DAL_DIO_DCN10 = $(addprefix $(AMDDALPATH)/dc/dio/dcn10/,$(DIO_DCN10)) diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c new file mode 100644 index 000000000000..edcf4e67483b --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2025 Advanced Micro Devices, Inc. + +#include "dc_hw_types.h" +#include "dm_services.h" +#include "reg_helper.h" +#include "dcn10_dio.h" + +#define CTX \ + dio10->base.ctx +#define REG(reg)\ + dio10->regs->reg + +#undef FN +#define FN(reg_name, field_name) \ + dio10->shifts->field_name, dio10->masks->field_name + +static void dcn10_dio_mem_pwr_ctrl(struct dio *dio, bool enable_i2c_light_sleep) +{ + struct dcn10_dio *dio10 = TO_DCN10_DIO(dio); + + /* power AFMT HDMI memory */ + REG_WRITE(DIO_MEM_PWR_CTRL, 0); + + if (enable_i2c_light_sleep) + REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1); +} + +static const struct dio_funcs dcn10_dio_funcs = { + .mem_pwr_ctrl = dcn10_dio_mem_pwr_ctrl, +}; + +void dcn10_dio_construct( + struct dcn10_dio *dio10, + struct dc_context *ctx, + const struct dcn_dio_registers *regs, + const struct dcn_dio_shift *shifts, + const struct dcn_dio_mask *masks) +{ + dio10->base.ctx = ctx; + dio10->base.funcs = &dcn10_dio_funcs; + + dio10->regs = regs; + dio10->shifts = shifts; + dio10->masks = masks; +} diff --git a/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h new file mode 100644 index 000000000000..369c5996326e --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/dio/dcn10/dcn10_dio.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2025 Advanced Micro Devices, Inc. + +#ifndef __DCN10_DIO_H__ +#define __DCN10_DIO_H__ + +#include "dio.h" + +#define TO_DCN10_DIO(dio_base) \ + container_of(dio_base, struct dcn10_dio, base) + +#define DIO_REG_LIST_DCN10()\ + SR(DIO_MEM_PWR_CTRL) + +struct dcn_dio_registers { + uint32_t DIO_MEM_PWR_CTRL; +}; + +struct dcn_dio_shift { + uint8_t I2C_LIGHT_SLEEP_FORCE; +}; + +struct dcn_dio_mask { + uint32_t I2C_LIGHT_SLEEP_FORCE; +}; + +struct dcn10_dio { + struct dio base; + const struct dcn_dio_registers *regs; + const struct dcn_dio_shift *shifts; + const struct dcn_dio_mask *masks; +}; + +void dcn10_dio_construct( + struct dcn10_dio *dio10, + struct dc_context *ctx, + const struct dcn_dio_registers *regs, + const struct dcn_dio_shift *shifts, + const struct dcn_dio_mask *masks); + +#endif /* __DCN10_DIO_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c similarity index 99% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c index 1d226e0519a5..2655bc194a35 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.c @@ -128,5 +128,3 @@ bool virtual_link_encoder_construct( return true; } - - diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_encoder.h rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_link_encoder.h diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c similarity index 98% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c index ad088d70e189..a9c8857476ac 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.c +++ b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.c @@ -159,7 +159,7 @@ bool virtual_stream_encoder_construct( struct stream_encoder *virtual_stream_encoder_create( struct dc_context *ctx, struct dc_bios *bp) { - struct stream_encoder *enc = kzalloc(sizeof(*enc), GFP_KERNEL); + struct stream_encoder *enc = kzalloc_obj(*enc); if (!enc) return NULL; @@ -171,4 +171,3 @@ struct stream_encoder *virtual_stream_encoder_create( kfree(enc); return NULL; } - diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.h b/drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.h similarity index 100% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_stream_encoder.h rename to drivers/gpu/drm/amd/display/dc/dio/virtual/virtual_stream_encoder.h diff --git a/drivers/gpu/drm/amd/display/dc/dm_helpers.h b/drivers/gpu/drm/amd/display/dc/dm_helpers.h index 7014b8c2c956..2818df555e62 100644 --- a/drivers/gpu/drm/amd/display/dc/dm_helpers.h +++ b/drivers/gpu/drm/amd/display/dc/dm_helpers.h @@ -209,7 +209,7 @@ void dm_helpers_init_panel_settings( struct dc_sink *sink); void dm_helpers_override_panel_settings( struct dc_context *ctx, - struct dc_panel_config *config); + struct dc_link *link); int dm_helper_dmub_aux_transfer_sync( struct dc_context *ctx, const struct dc_link *link, diff --git a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c index 817a370e80a7..8a177d5ae213 100644 --- a/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c +++ b/drivers/gpu/drm/amd/display/dc/dml/dcn35/dcn35_fpu.c @@ -164,8 +164,8 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { }, }, .num_states = 5, - .sr_exit_time_us = 28.0, - .sr_enter_plus_exit_time_us = 30.0, + .sr_exit_time_us = 31.0, + .sr_enter_plus_exit_time_us = 33.0, .sr_exit_z8_time_us = 250.0, .sr_enter_plus_exit_z8_time_us = 350.0, .fclk_change_latency_us = 24.0, diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c index 89890c88fd66..4022f91193ed 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/display_mode_util.c @@ -655,7 +655,7 @@ __DML_DLL_EXPORT__ void dml_print_soc_bounding_box(const struct soc_bounding_box dml_print("DML: soc_bbox: refclk_mhz = %f\n", soc->refclk_mhz); dml_print("DML: soc_bbox: amclk_mhz = %f\n", soc->amclk_mhz); - dml_print("DML: soc_bbox: max_outstanding_reqs = %f\n", soc->max_outstanding_reqs); + dml_print("DML: soc_bbox: max_outstanding_reqs = %d\n", soc->max_outstanding_reqs); dml_print("DML: soc_bbox: pct_ideal_sdp_bw_after_urgent = %f\n", soc->pct_ideal_sdp_bw_after_urgent); dml_print("DML: soc_bbox: pct_ideal_fabric_bw_after_urgent = %f\n", soc->pct_ideal_fabric_bw_after_urgent); dml_print("DML: soc_bbox: pct_ideal_dram_bw_after_urgent_pixel_only = %f\n", soc->pct_ideal_dram_bw_after_urgent_pixel_only); diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h index 1fbc520c2540..c4cce870877a 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/inc/dml_top_soc_parameter_types.h @@ -115,9 +115,12 @@ struct dml2_dram_params { unsigned int channel_width_bytes; unsigned int channel_count; unsigned int transactions_per_clock; + bool alt_clock_bw_conversion; }; +#define ENABLE_WCK struct dml2_soc_state_table { + struct dml2_clk_table wck_ratio; struct dml2_clk_table uclk; struct dml2_clk_table fclk; struct dml2_clk_table dcfclk; diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c index 01b87be24ce3..ca5ac3c0deb5 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -7077,10 +7077,21 @@ static void calculate_excess_vactive_bandwidth_required( } } -static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config) +static double uclk_khz_to_dram_bw_mbps(unsigned long uclk_khz, const struct dml2_dram_params *dram_config, const struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table) { double bw_mbps = 0; - bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0; + unsigned int i; + + if (!dram_config->alt_clock_bw_conversion) + bw_mbps = ((double)uclk_khz * dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock) / 1000.0; + else + for (i = 0; i < dram_bw_table->num_entries; i++) + if (dram_bw_table->entries[i].min_uclk_khz >= uclk_khz) { + bw_mbps = (double)dram_bw_table->entries[i].pre_derate_dram_bw_kbps / 1000.0; + break; + } + + DML_ASSERT(bw_mbps > 0); return bw_mbps; } @@ -7964,7 +7975,9 @@ static bool dml_core_mode_support(struct dml2_core_calcs_mode_support_ex *in_out mode_lib->ms.max_dispclk_freq_mhz = (double)min_clk_table->max_ss_clocks_khz.dispclk / 1000; mode_lib->ms.max_dscclk_freq_mhz = (double)min_clk_table->max_clocks_khz.dscclk / 1000; mode_lib->ms.max_dppclk_freq_mhz = (double)min_clk_table->max_ss_clocks_khz.dppclk / 1000; - mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config); + mode_lib->ms.uclk_freq_mhz = (double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz / 1000.0; + if (!mode_lib->ms.uclk_freq_mhz) + mode_lib->ms.uclk_freq_mhz = dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config); mode_lib->ms.dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps / 1000); mode_lib->ms.max_dram_bw_mbps = ((double)min_clk_table->dram_bw_table.entries[min_clk_table->dram_bw_table.num_entries - 1].pre_derate_dram_bw_kbps / 1000); mode_lib->ms.qos_param_index = get_qos_param_index((unsigned int) (mode_lib->ms.uclk_freq_mhz * 1000.0), mode_lib->soc.qos_parameters.qos_params.dcn4x.per_uclk_dpm_params); @@ -10407,7 +10420,7 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex mode_lib->mp.Dcfclk = programming->min_clocks.dcn4x.active.dcfclk_khz / 1000.0; mode_lib->mp.FabricClock = programming->min_clocks.dcn4x.active.fclk_khz / 1000.0; - mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config); + mode_lib->mp.dram_bw_mbps = uclk_khz_to_dram_bw_mbps(programming->min_clocks.dcn4x.active.uclk_khz, &mode_lib->soc.clk_table.dram_config, &min_clk_table->dram_bw_table); mode_lib->mp.uclk_freq_mhz = programming->min_clocks.dcn4x.active.uclk_khz / 1000.0; mode_lib->mp.GlobalDPPCLK = programming->min_clocks.dcn4x.dpprefclk_khz / 1000.0; s->SOCCLK = (double)programming->min_clocks.dcn4x.socclk_khz / 1000; @@ -10485,7 +10498,10 @@ static bool dml_core_mode_programming(struct dml2_core_calcs_mode_programming_ex DML_LOG_VERBOSE("DML::%s: SOCCLK = %f\n", __func__, s->SOCCLK); DML_LOG_VERBOSE("DML::%s: min_clk_index = %0d\n", __func__, in_out_params->min_clk_index); DML_LOG_VERBOSE("DML::%s: min_clk_table min_fclk_khz = %ld\n", __func__, min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_fclk_khz); - DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config)); + if (min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz) + DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].min_uclk_khz / 1000.0); + else + DML_LOG_VERBOSE("DML::%s: min_clk_table uclk_mhz = %f\n", __func__, dram_bw_kbps_to_uclk_mhz(min_clk_table->dram_bw_table.entries[in_out_params->min_clk_index].pre_derate_dram_bw_kbps, &mode_lib->soc.clk_table.dram_config)); for (k = 0; k < mode_lib->mp.num_active_pipes; ++k) { DML_LOG_VERBOSE("DML::%s: pipe=%d is in plane=%d\n", __func__, k, mode_lib->mp.pipe_plane[k]); DML_LOG_VERBOSE("DML::%s: Per-plane DPPPerSurface[%0d] = %d\n", __func__, k, mode_lib->mp.NoOfDPP[k]); diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c index 22969a533a7b..9d7741fd0adb 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/dml2_dpmm/dml2_dpmm_dcn4.c @@ -7,14 +7,24 @@ #include "dml_top_types.h" #include "lib_float_math.h" -static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config) +static double dram_bw_kbps_to_uclk_khz(unsigned long long bandwidth_kbps, const struct dml2_dram_params *dram_config, struct dml2_mcg_dram_bw_to_min_clk_table *dram_bw_table) { double uclk_khz = 0; - unsigned long uclk_mbytes_per_tick = 0; - uclk_mbytes_per_tick = dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock; + if (!dram_config->alt_clock_bw_conversion) { + unsigned long uclk_bytes_per_tick = 0; - uclk_khz = (double)bandwidth_kbps / uclk_mbytes_per_tick; + uclk_bytes_per_tick = dram_config->channel_count * dram_config->channel_width_bytes * dram_config->transactions_per_clock; + uclk_khz = (double)bandwidth_kbps / uclk_bytes_per_tick; + } else { + unsigned int i; + /* For lpddr5 bytes per tick changes with mpstate, use table to find uclk*/ + for (i = 0; i < dram_bw_table->num_entries; i++) + if (dram_bw_table->entries[i].pre_derate_dram_bw_kbps >= bandwidth_kbps) { + uclk_khz = dram_bw_table->entries[i].min_uclk_khz; + break; + } + } return uclk_khz; } @@ -34,7 +44,7 @@ static void get_minimum_clocks_for_latency(struct dml2_dpmm_map_mode_to_soc_dpm_ *dcfclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_dcfclk_khz; *fclk = in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].min_fclk_khz; *uclk = dram_bw_kbps_to_uclk_khz(in_out->min_clk_table->dram_bw_table.entries[min_clock_index_for_latency].pre_derate_dram_bw_kbps, - &in_out->soc_bb->clk_table.dram_config); + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); } static unsigned long dml_round_up(double a) @@ -53,14 +63,18 @@ static void calculate_system_active_minimums(struct dml2_dpmm_map_mode_to_soc_dp double min_uclk_latency, min_fclk_latency, min_dcfclk_latency; const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; - min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100); + min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); - min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); if (in_out->display_cfg->display_config.hostvm_enable) - min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100); + min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel_and_vm / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); else - min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100); + min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.urgent_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg; @@ -97,11 +111,13 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; /* assumes DF throttling is enabled */ - min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100); + min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_average.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); - min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100); + min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.dcn_mall_prefetch_urgent.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg; @@ -128,11 +144,13 @@ static void calculate_svp_prefetch_minimums(struct dml2_dpmm_map_mode_to_soc_dpm in_out->programming->min_clocks.dcn4x.svp_prefetch.dcfclk_khz = dml_round_up(min_dcfclk_bw > min_dcfclk_latency ? min_dcfclk_bw : min_dcfclk_latency); /* assumes DF throttling is disabled */ - min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100); + min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.average_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_average.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); - min_uclk_urgent = dram_bw_kbps_to_uclk_khz(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_urgent = (double)min_uclk_urgent / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100); + min_uclk_urgent = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.svp_prefetch.urgent_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_active_urgent.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); min_uclk_bw = min_uclk_urgent > min_uclk_avg ? min_uclk_urgent : min_uclk_avg; @@ -167,8 +185,9 @@ static void calculate_idle_minimums(struct dml2_dpmm_map_mode_to_soc_dpm_params_ double min_uclk_latency, min_fclk_latency, min_dcfclk_latency; const struct dml2_core_mode_support_result *mode_support_result = &in_out->display_cfg->mode_support_result; - min_uclk_avg = dram_bw_kbps_to_uclk_khz(mode_support_result->global.active.average_bw_dram_kbps, &in_out->soc_bb->clk_table.dram_config); - min_uclk_avg = (double)min_uclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100); + min_uclk_avg = dram_bw_kbps_to_uclk_khz((unsigned long long)(mode_support_result->global.active.average_bw_dram_kbps + / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.dram_derate_percent_pixel / 100)), + &in_out->soc_bb->clk_table.dram_config, &in_out->min_clk_table->dram_bw_table); min_fclk_avg = (double)mode_support_result->global.active.average_bw_sdp_kbps / in_out->soc_bb->fabric_datapath_to_dcn_data_return_bytes; min_fclk_avg = (double)min_fclk_avg / ((double)in_out->soc_bb->qos_parameters.derate_table.system_idle_average.fclk_derate_percent / 100); diff --git a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h index 1a6c0727cd2a..a6bd75f30d20 100644 --- a/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h +++ b/drivers/gpu/drm/amd/display/dc/dml2_0/dml21/src/inc/dml2_internal_shared_types.h @@ -16,6 +16,7 @@ struct dram_bw_to_min_clk_table_entry { unsigned long long pre_derate_dram_bw_kbps; + unsigned long min_uclk_khz; unsigned long min_fclk_khz; unsigned long min_dcfclk_khz; }; diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c index ef4a16117181..c7923531da83 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.c @@ -376,10 +376,10 @@ void dpp3_cnv_setup ( tbl_entry.color_space = input_color_space; - if (color_space >= COLOR_SPACE_YCBCR601) - select = INPUT_CSC_SELECT_ICSC; - else + if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) select = INPUT_CSC_SELECT_BYPASS; + else + select = INPUT_CSC_SELECT_ICSC; dpp3_program_post_csc(dpp_base, color_space, select, &tbl_entry); @@ -1541,3 +1541,18 @@ bool dpp3_construct( return true; } +bool dpp3_should_bypass_post_csc_for_colorspace(enum dc_color_space dc_color_space) +{ + switch (dc_color_space) { + case COLOR_SPACE_UNKNOWN: + case COLOR_SPACE_SRGB: + case COLOR_SPACE_XR_RGB: + case COLOR_SPACE_SRGB_LIMITED: + case COLOR_SPACE_MSREF_SCRGB: + case COLOR_SPACE_2020_RGB_FULLRANGE: + case COLOR_SPACE_2020_RGB_LIMITEDRANGE: + return true; + default: + return false; + } +} diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h index d4a70b4379ea..6a61b99d6a79 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h @@ -644,4 +644,8 @@ void dpp3_program_cm_dealpha( void dpp3_cm_get_gamut_remap(struct dpp *dpp_base, struct dpp_grph_csc_adjustment *adjust); + +bool dpp3_should_bypass_post_csc_for_colorspace( + enum dc_color_space dc_color_space); + #endif /* __DC_HWSS_DCN30_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c index 96c2c853de42..2d6a646462e2 100644 --- a/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c +++ b/drivers/gpu/drm/amd/display/dc/dpp/dcn401/dcn401_dpp.c @@ -206,10 +206,10 @@ void dpp401_dpp_setup( tbl_entry.color_space = input_color_space; - if (color_space >= COLOR_SPACE_YCBCR601) - select = INPUT_CSC_SELECT_ICSC; - else + if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) select = INPUT_CSC_SELECT_BYPASS; + else + select = INPUT_CSC_SELECT_ICSC; dpp3_program_post_csc(dpp_base, color_space, select, &tbl_entry); diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dsc.h b/drivers/gpu/drm/amd/display/dc/dsc/dsc.h index 81c83d5fe042..ad7ef83694ea 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dsc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dsc.h @@ -115,6 +115,7 @@ struct dsc_funcs { void (*dsc_disconnect)(struct display_stream_compressor *dsc); void (*dsc_wait_disconnect_pending_clear)(struct display_stream_compressor *dsc); void (*dsc_get_single_enc_caps)(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz); + void (*set_fgcg)(struct display_stream_compressor *dsc, bool enable); }; #endif diff --git a/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c index 03a50c32fcfe..37adf0e6a166 100644 --- a/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c +++ b/drivers/gpu/drm/amd/display/dc/dwb/dcn30/dcn30_dwb_cm.c @@ -280,7 +280,7 @@ bool dwb3_ogam_set_input_transfer_func( if (in_transfer_func_dwb_ogam == NULL) return result; - dwb_ogam_lut = kzalloc(sizeof(*dwb_ogam_lut), GFP_KERNEL); + dwb_ogam_lut = kzalloc_obj(*dwb_ogam_lut); if (dwb_ogam_lut) { cm_helper_translate_curve_to_hw_format(dwbc->ctx, diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c index 8183cdf517b8..95532b7ee884 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_base.c @@ -270,7 +270,7 @@ struct gpio *dal_gpio_create( uint32_t en, enum gpio_pin_output_state output_state) { - struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL); + struct gpio *gpio = kzalloc_obj(struct gpio); if (!gpio) { ASSERT_CRITICAL(false); diff --git a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c index 942d9f0b6df2..a2c46350e44e 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/gpio_service.c @@ -58,7 +58,7 @@ struct gpio_service *dal_gpio_service_create( struct gpio_service *service; int32_t index_of_id; - service = kzalloc(sizeof(struct gpio_service), GFP_KERNEL); + service = kzalloc_obj(struct gpio_service); if (!service) { BREAK_TO_DEBUGGER(); @@ -498,7 +498,7 @@ struct ddc *dal_gpio_create_ddc( if (!service->translate.funcs->offset_to_id(offset, mask, &id, &en)) return NULL; - ddc = kzalloc(sizeof(struct ddc), GFP_KERNEL); + ddc = kzalloc_obj(struct ddc); if (!ddc) { BREAK_TO_DEBUGGER(); diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c index d9e6e70dc394..86d60986d669 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_ddc.c @@ -233,7 +233,7 @@ void dal_hw_ddc_init( *hw_ddc = NULL; } - *hw_ddc = kzalloc(sizeof(struct hw_ddc), GFP_KERNEL); + *hw_ddc = kzalloc_obj(struct hw_ddc); if (!*hw_ddc) { ASSERT_CRITICAL(false); return; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c index 6cd50232c432..7f137cb96895 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_generic.c @@ -111,7 +111,7 @@ void dal_hw_generic_init( *hw_generic = NULL; } - *hw_generic = kzalloc(sizeof(struct hw_generic), GFP_KERNEL); + *hw_generic = kzalloc_obj(struct hw_generic); if (!*hw_generic) { ASSERT_CRITICAL(false); return; diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c index 01ec451004f7..79e107904e21 100644 --- a/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c +++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_hpd.c @@ -132,7 +132,7 @@ void dal_hw_hpd_init( *hw_hpd = NULL; } - *hw_hpd = kzalloc(sizeof(struct hw_hpd), GFP_KERNEL); + *hw_hpd = kzalloc_obj(struct hw_hpd); if (!*hw_hpd) { ASSERT_CRITICAL(false); return; diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c index d11afd1ce72a..941dce439e97 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.c @@ -41,7 +41,7 @@ #define FN(reg_name, field_name) \ hubbub2->shifts->field_name, hubbub2->masks->field_name -static void dcn401_init_crb(struct hubbub *hubbub) +void dcn401_init_crb(struct hubbub *hubbub) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1110,7 +1110,7 @@ bool hubbub401_get_dcc_compression_cap(struct hubbub *hubbub, return true; } -static void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg) +void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1147,7 +1147,7 @@ static void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, un } } -static void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase) +void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1170,7 +1170,7 @@ static void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned comp } } -static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) +void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); @@ -1192,7 +1192,7 @@ static void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst) } } -static bool dcn401_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower) +bool dcn401_program_arbiter(struct hubbub *hubbub, struct dml2_display_arb_regs *arb_regs, bool safe_to_lower) { struct dcn20_hubbub *hubbub2 = TO_DCN20_HUBBUB(hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h index b1d9ea9d1c3d..f48715544429 100644 --- a/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h +++ b/drivers/gpu/drm/amd/display/dc/hubbub/dcn401/dcn401_hubbub.h @@ -194,6 +194,11 @@ bool hubbub401_get_dcc_compression_cap( const struct dc_dcc_surface_param *input, struct dc_surface_dcc_cap *output); +bool dcn401_program_arbiter( + struct hubbub *hubbub, + struct dml2_display_arb_regs *arb_regs, + bool safe_to_lower); + void hubbub401_construct(struct dcn20_hubbub *hubbub2, struct dc_context *ctx, const struct dcn_hubbub_registers *hubbub_regs, @@ -203,4 +208,9 @@ void hubbub401_construct(struct dcn20_hubbub *hubbub2, int pixel_chunk_size_kb, int config_return_buffer_size_kb); +void dcn401_program_det_segments(struct hubbub *hubbub, int hubp_inst, unsigned det_buffer_size_seg); +void dcn401_program_compbuf_segments(struct hubbub *hubbub, unsigned compbuf_size_seg, bool safe_to_increase); +void dcn401_wait_for_det_update(struct hubbub *hubbub, int hubp_inst); +void dcn401_init_crb(struct hubbub *hubbub); + #endif diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c index 4659e1b489ba..699a756bbc40 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -660,20 +660,6 @@ void dce110_update_info_frame(struct pipe_ctx *pipe_ctx) } } -static void -dce110_dac_encoder_control(struct pipe_ctx *pipe_ctx, bool enable) -{ - struct dc_link *link = pipe_ctx->stream->link; - struct dc_bios *bios = link->ctx->dc_bios; - struct bp_encoder_control encoder_control = {0}; - - encoder_control.action = enable ? ENCODER_CONTROL_ENABLE : ENCODER_CONTROL_DISABLE; - encoder_control.engine_id = link->link_enc->analog_engine; - encoder_control.pixel_clock = pipe_ctx->stream->timing.pix_clk_100hz / 10; - - bios->funcs->encoder_control(bios, &encoder_control); -} - void dce110_enable_stream(struct pipe_ctx *pipe_ctx) { enum dc_lane_count lane_count = @@ -704,8 +690,6 @@ void dce110_enable_stream(struct pipe_ctx *pipe_ctx) tg->funcs->set_early_control(tg, early_control); - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - dce110_dac_encoder_control(pipe_ctx, true); } static enum bp_result link_transmitter_control( @@ -1199,9 +1183,6 @@ void dce110_disable_stream(struct pipe_ctx *pipe_ctx) dccg->funcs->disable_symclk_se(dccg, stream_enc->stream_enc_inst, link_enc->transmitter - TRANSMITTER_UNIPHY_A); } - - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - dce110_dac_encoder_control(pipe_ctx, false); } void dce110_unblank_stream(struct pipe_ctx *pipe_ctx, @@ -1584,25 +1565,6 @@ static enum dc_status dce110_enable_stream_timing( return DC_OK; } -static void -dce110_select_crtc_source(struct pipe_ctx *pipe_ctx) -{ - struct dc_link *link = pipe_ctx->stream->link; - struct dc_bios *bios = link->ctx->dc_bios; - struct bp_crtc_source_select crtc_source_select = {0}; - enum engine_id engine_id = link->link_enc->preferred_engine; - - if (dc_is_rgb_signal(pipe_ctx->stream->signal)) - engine_id = link->link_enc->analog_engine; - - crtc_source_select.controller_id = CONTROLLER_ID_D0 + pipe_ctx->stream_res.tg->inst; - crtc_source_select.color_depth = pipe_ctx->stream->timing.display_color_depth; - crtc_source_select.engine_id = engine_id; - crtc_source_select.sink_signal = pipe_ctx->stream->signal; - - bios->funcs->select_crtc_source(bios, &crtc_source_select); -} - enum dc_status dce110_apply_single_controller_ctx_to_hw( struct pipe_ctx *pipe_ctx, struct dc_state *context, @@ -1622,10 +1584,6 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( hws->funcs.disable_stream_gating(dc, pipe_ctx); } - if (pipe_ctx->stream->signal == SIGNAL_TYPE_RGB) { - dce110_select_crtc_source(pipe_ctx); - } - if (pipe_ctx->stream_res.audio != NULL) { struct audio_output audio_output = {0}; @@ -1705,8 +1663,7 @@ enum dc_status dce110_apply_single_controller_ctx_to_hw( pipe_ctx->stream_res.tg->funcs->set_static_screen_control( pipe_ctx->stream_res.tg, event_triggers, 2); - if (!dc_is_virtual_signal(pipe_ctx->stream->signal) && - !dc_is_rgb_signal(pipe_ctx->stream->signal)) + if (!dc_is_virtual_signal(pipe_ctx->stream->signal)) pipe_ctx->stream_res.stream_enc->funcs->dig_connect_to_otg( pipe_ctx->stream_res.stream_enc, pipe_ctx->stream_res.tg->inst); @@ -1964,8 +1921,8 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context) get_edp_streams(context, edp_streams, &edp_stream_num); - /* Check fastboot support, disable on DCE 6-8 because of blank screens */ - if (edp_num && edp_stream_num && dc->ctx->dce_version < DCE_VERSION_10_0) { + /* Check fastboot support, disable on DCE 6-8-10 because of blank screens */ + if (edp_num && edp_stream_num && dc->ctx->dce_version > DCE_VERSION_10_0) { for (i = 0; i < edp_num; i++) { edp_link = edp_links[i]; if (edp_link != edp_streams[0]->link) @@ -3304,6 +3261,15 @@ void dce110_enable_tmds_link_output(struct dc_link *link, link->phy_state.symclk_state = SYMCLK_ON_TX_ON; } +static void dce110_enable_analog_link_output( + struct dc_link *link, + uint32_t pix_clk_100hz) +{ + link->link_enc->funcs->enable_analog_output( + link->link_enc, + pix_clk_100hz); +} + void dce110_enable_dp_link_output( struct dc_link *link, const struct link_resource *link_res, @@ -3441,6 +3407,7 @@ static const struct hw_sequencer_funcs dce110_funcs = { .enable_lvds_link_output = dce110_enable_lvds_link_output, .enable_tmds_link_output = dce110_enable_tmds_link_output, .enable_dp_link_output = dce110_enable_dp_link_output, + .enable_analog_link_output = dce110_enable_analog_link_output, .disable_link_output = dce110_disable_link_output, }; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c index c1586364ecd4..a2d28be480e8 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn10/dcn10_hwseq.c @@ -50,6 +50,7 @@ #include "link_hwss.h" #include "dpcd_defs.h" #include "dsc.h" +#include "dio/dcn10/dcn10_dio.h" #include "dce/dmub_psr.h" #include "dc_dmub_srv.h" #include "dce/dmub_hw_lock_mgr.h" @@ -1881,13 +1882,13 @@ void dcn10_init_hw(struct dc *dc) /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ if (!is_optimized_init_done) - REG_WRITE(DIO_MEM_PWR_CTRL, 0); + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } @@ -2398,7 +2399,7 @@ static int dcn10_align_pixel_clocks(struct dc *dc, int group_size, DC_LOGGER_INIT(dc_ctx->logger); - hw_crtc_timing = kcalloc(MAX_PIPES, sizeof(*hw_crtc_timing), GFP_KERNEL); + hw_crtc_timing = kzalloc_objs(*hw_crtc_timing, MAX_PIPES); if (!hw_crtc_timing) return master; diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c index a76436dcbe40..307e8f8060e6 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn20/dcn20_hwseq.c @@ -357,26 +357,10 @@ void dcn20_enable_power_gating_plane( void dcn20_dccg_init(struct dce_hwseq *hws) { - /* - * set MICROSECOND_TIME_BASE_DIV - * 100Mhz refclk -> 0x120264 - * 27Mhz refclk -> 0x12021b - * 48Mhz refclk -> 0x120230 - * - */ - REG_WRITE(MICROSECOND_TIME_BASE_DIV, 0x120264); + struct dc *dc = hws->ctx->dc; - /* - * set MILLISECOND_TIME_BASE_DIV - * 100Mhz refclk -> 0x1186a0 - * 27Mhz refclk -> 0x106978 - * 48Mhz refclk -> 0x10bb80 - * - */ - REG_WRITE(MILLISECOND_TIME_BASE_DIV, 0x1186a0); - - /* This value is dependent on the hardware pipeline delay so set once per SOC */ - REG_WRITE(DISPCLK_FREQ_CHANGE_CNTL, 0xe01003c); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->dccg_init) + dc->res_pool->dccg->funcs->dccg_init(dc->res_pool->dccg); } void dcn20_disable_vga( @@ -3155,8 +3139,12 @@ void dcn20_fpga_init_hw(struct dc *dc) REG_WRITE(RBBMIF_TIMEOUT_DIS_2, 0xFFFFFFFF); dcn10_hubbub_global_timer_enable(dc->res_pool->hubbub, true, 2); - if (REG(REFCLK_CNTL)) - REG_WRITE(REFCLK_CNTL, 0); + + if (hws->funcs.dccg_init) + hws->funcs.dccg_init(hws); + + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->refclk_setup) + dc->res_pool->dccg->funcs->refclk_setup(dc->res_pool->dccg); // diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c index 482053c4ad22..ce18d75fd991 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn201/dcn201_hwseq.c @@ -40,6 +40,8 @@ #include "clk_mgr.h" #include "reg_helper.h" #include "dcn10/dcn10_hubbub.h" +#include "dio/dcn10/dcn10_dio.h" + #define CTX \ hws->ctx @@ -360,13 +362,13 @@ void dcn201_init_hw(struct dc *dc) } /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c index e2269211553c..062745389d9a 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn21/dcn21_hwseq.c @@ -33,6 +33,7 @@ #include "vmid.h" #include "reg_helper.h" #include "hw/clk_mgr.h" +#include "hw/dccg.h" #include "dc_dmub_srv.h" #include "abm.h" #include "link_service.h" @@ -87,12 +88,10 @@ int dcn21_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_ bool dcn21_s0i3_golden_init_wa(struct dc *dc) { - struct dce_hwseq *hws = dc->hwseq; - uint32_t value = 0; + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done) + return !dc->res_pool->dccg->funcs->is_s0i3_golden_init_wa_done(dc->res_pool->dccg); - value = REG_READ(MICROSECOND_TIME_BASE_DIV); - - return value != 0x00120464; + return false; } void dcn21_exit_optimized_pwr_state( diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c index 9b95f5883925..d04cfd403b7e 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn30/dcn30_hwseq.c @@ -53,6 +53,7 @@ #include "dcn30/dcn30_resource.h" #include "link_service.h" #include "dc_state_priv.h" +#include "dio/dcn10/dcn10_dio.h" #define TO_DCN_DCCG(dccg)\ container_of(dccg, struct dcn_dccg, base) @@ -795,13 +796,13 @@ void dcn30_init_hw(struct dc *dc) } /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c index 2adbcc105aa6..db2f7cbb12ff 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn31/dcn31_hwseq.c @@ -53,6 +53,7 @@ #include "dcn30/dcn30_vpg.h" #include "dce/dce_i2c_hw.h" #include "dce/dmub_abm_lcd.h" +#include "dio/dcn10/dcn10_dio.h" #define DC_LOGGER_INIT(logger) @@ -237,21 +238,17 @@ void dcn31_init_hw(struct dc *dc) abms[i]->funcs->abm_init(abms[i], backlight, user_level); } - /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); - - // Set i2c to light sleep until engine is setup - if (dc->debug.enable_mem_low_power.bits.i2c) - REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 1); + /* Power on DIO memory (AFMT HDMI) and set I2C to light sleep */ + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, dc->debug.enable_mem_low_power.bits.i2c); if (hws->funcs.setup_hpo_hw_control) hws->funcs.setup_hpo_hw_control(hws, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c index 518794fad9e1..a0aaa727e9fa 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn32/dcn32_hwseq.c @@ -52,6 +52,7 @@ #include "link_service.h" #include "../dcn20/dcn20_hwseq.h" #include "dc_state_priv.h" +#include "dio/dcn10/dcn10_dio.h" #define DC_LOGGER_INIT(logger) @@ -485,7 +486,7 @@ bool dcn32_set_mcm_luts( struct dpp *dpp_base = pipe_ctx->plane_res.dpp; int mpcc_id = pipe_ctx->plane_res.hubp->inst; struct mpc *mpc = pipe_ctx->stream_res.opp->ctx->dc->res_pool->mpc; - bool result = true; + bool rval, result; const struct pwl_params *lut_params = NULL; // 1D LUT @@ -508,10 +509,10 @@ bool dcn32_set_mcm_luts( lut_params = &plane_state->in_shaper_func.pwl; else if (plane_state->in_shaper_func.type == TF_TYPE_DISTRIBUTED_POINTS) { // TODO: dpp_base replace - cm3_helper_translate_curve_to_hw_format(plane_state->ctx, + rval = cm3_helper_translate_curve_to_hw_format(plane_state->ctx, &plane_state->in_shaper_func, &dpp_base->shaper_params, true); - lut_params = &dpp_base->shaper_params; + lut_params = rval ? &dpp_base->shaper_params : NULL; } mpc->funcs->program_shaper(mpc, lut_params, mpcc_id); @@ -957,13 +958,13 @@ void dcn32_init_hw(struct dc *dc) } /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c index f7e16fee7594..b5a4cefbd35f 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -53,6 +53,7 @@ #include "dcn30/dcn30_vpg.h" #include "dce/dce_i2c_hw.h" #include "dsc.h" +#include "dio/dcn10/dcn10_dio.h" #include "dcn20/dcn20_optc.h" #include "dcn30/dcn30_cm_common.h" #include "dcn31/dcn31_hwseq.h" @@ -272,12 +273,9 @@ void dcn35_init_hw(struct dc *dc) } } - /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); - - // Set i2c to light sleep until engine is setup - if (dc->debug.enable_mem_low_power.bits.i2c) - REG_UPDATE(DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, 0); + /* Power on DIO memory (AFMT HDMI) and optionally disable I2C light sleep */ + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, !dc->debug.enable_mem_low_power.bits.i2c); if (hws->funcs.setup_hpo_hw_control) hws->funcs.setup_hpo_hw_control(hws, false); @@ -288,7 +286,8 @@ void dcn35_init_hw(struct dc *dc) } if (dc->debug.disable_mem_low_power) { - REG_UPDATE(DC_MEM_GLOBAL_PWR_REQ_CNTL, DC_MEM_GLOBAL_PWR_REQ_DIS, 1); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->enable_memory_low_power) + dc->res_pool->dccg->funcs->enable_memory_low_power(dc->res_pool->dccg, false); } if (!dcb->funcs->is_accelerated_mode(dcb) && dc->res_pool->hubbub->funcs->init_watermarks) dc->res_pool->hubbub->funcs->init_watermarks(dc->res_pool->hubbub); diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c index 39b6f6d2d7c1..eb198d52a115 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c @@ -39,6 +39,7 @@ #include "dc_state_priv.h" #include "link_enc_cfg.h" #include "../hw_sequencer.h" +#include "dio/dcn10/dcn10_dio.h" #define DC_LOGGER_INIT(logger) @@ -71,7 +72,11 @@ void dcn401_initialize_min_clocks(struct dc *dc) * audio corruption. Read current DISPCLK from DENTIST and request the same * freq to ensure that the timing is valid and unchanged. */ - clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr); + if (dc->clk_mgr->funcs->get_dispclk_from_dentist) { + clocks->dispclk_khz = dc->clk_mgr->funcs->get_dispclk_from_dentist(dc->clk_mgr); + } else { + clocks->dispclk_khz = dc->clk_mgr->boot_snapshot.dispclk * 1000; + } } clocks->ref_dtbclk_khz = dc->clk_mgr->bw_params->clk_table.entries[0].dtbclk_mhz * 1000; clocks->fclk_p_state_change_support = true; @@ -320,13 +325,13 @@ void dcn401_init_hw(struct dc *dc) } /* power AFMT HDMI memory TODO: may move to dis/en output save power*/ - REG_WRITE(DIO_MEM_PWR_CTRL, 0); + if (dc->res_pool->dio && dc->res_pool->dio->funcs->mem_pwr_ctrl) + dc->res_pool->dio->funcs->mem_pwr_ctrl(dc->res_pool->dio, false); if (!dc->debug.disable_clock_gate) { /* enable all DCN clock gating */ - REG_WRITE(DCCG_GATE_DISABLE_CNTL, 0); - - REG_WRITE(DCCG_GATE_DISABLE_CNTL2, 0); + if (dc->res_pool->dccg && dc->res_pool->dccg->funcs && dc->res_pool->dccg->funcs->allow_clock_gating) + dc->res_pool->dccg->funcs->allow_clock_gating(dc->res_pool->dccg, true); REG_UPDATE(DCFCLK_CNTL, DCFCLK_GATE_DIS, 0); } diff --git a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h index 51b0f0fd8fcd..4632a5761b16 100644 --- a/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h +++ b/drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h @@ -1184,6 +1184,8 @@ struct hw_sequencer_funcs { const struct link_resource *link_res, enum clock_source_id clock_source, uint32_t pixel_clock); + void (*enable_analog_link_output)(struct dc_link *link, + uint32_t pixel_clock); void (*disable_link_output)(struct dc_link *link, const struct link_resource *link_res, enum signal_type signal); diff --git a/drivers/gpu/drm/amd/display/dc/inc/core_types.h b/drivers/gpu/drm/amd/display/dc/inc/core_types.h index 61d8ef759aca..43579b0e1482 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/core_types.h +++ b/drivers/gpu/drm/amd/display/dc/inc/core_types.h @@ -35,6 +35,7 @@ #include "hubp.h" #include "mpc.h" #include "dwb.h" +#include "hw/dio.h" #include "mcif_wb.h" #include "panel_cntl.h" #include "dmub/inc/dmub_cmd.h" @@ -250,6 +251,7 @@ struct resource_pool { struct timing_generator *timing_generators[MAX_PIPES]; struct stream_encoder *stream_enc[MAX_PIPES * 2]; struct hubbub *hubbub; + struct dio *dio; struct mpc *mpc; struct pp_smu_funcs *pp_smu; struct dce_aux *engines[MAX_PIPES]; diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h index 1e6ffd86a4c0..d6f5e01a0b66 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dccg.h @@ -224,6 +224,10 @@ struct dccg_funcs { void (*otg_drop_pixel)(struct dccg *dccg, uint32_t otg_inst); void (*dccg_init)(struct dccg *dccg); + void (*refclk_setup)(struct dccg *dccg); /* Deprecated - for backward compatibility only */ + void (*allow_clock_gating)(struct dccg *dccg, bool allow); + void (*enable_memory_low_power)(struct dccg *dccg, bool enable); + bool (*is_s0i3_golden_init_wa_done)(struct dccg *dccg); void (*set_dpstreamclk_root_clock_gating)( struct dccg *dccg, int dp_hpo_inst, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h b/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h new file mode 100644 index 000000000000..532bf54cf2c4 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/dio.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +// +// Copyright 2025 Advanced Micro Devices, Inc. + +#ifndef __DC_DIO_H__ +#define __DC_DIO_H__ + +#include "dc_types.h" + +struct dc_context; +struct dio; + +struct dio_funcs { + void (*mem_pwr_ctrl)(struct dio *dio, bool enable_i2c_light_sleep); +}; + +struct dio { + const struct dio_funcs *funcs; + struct dc_context *ctx; +}; + +#endif /* __DC_DIO_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h index d795fc43dc9d..5abbf485d273 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/link_encoder.h @@ -132,6 +132,8 @@ struct link_encoder_funcs { void (*enable_lvds_output)(struct link_encoder *enc, enum clock_source_id clock_source, uint32_t pixel_clock); + void (*enable_analog_output)(struct link_encoder *enc, + uint32_t pixel_clock); void (*disable_output)(struct link_encoder *link_enc, enum signal_type signal); void (*dp_set_lane_settings)(struct link_encoder *enc, diff --git a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h index da7bf59c4b9d..671ab1fc7320 100644 --- a/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h +++ b/drivers/gpu/drm/amd/display/dc/inc/hw/timing_generator.h @@ -122,6 +122,12 @@ enum timing_synchronization_type { VBLANK_SYNCHRONIZABLE }; +enum crc_poly_mode { + CRC_POLY_MODE_16, + CRC_POLY_MODE_32, + CRC_POLY_MODE_MAX, +}; + struct crc_params { /* Regions used to calculate CRC*/ uint16_t windowa_x_start; @@ -144,6 +150,7 @@ struct crc_params { uint8_t crc_eng_inst; bool reset; + enum crc_poly_mode crc_poly_mode; }; struct dcn_otg_state { diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c index bb576a9c5fdb..676df39079fc 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce110/irq_service_dce110.c @@ -419,8 +419,7 @@ static void dce110_irq_construct(struct irq_service *irq_service, struct irq_service * dal_irq_service_dce110_create(struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c index 33ce470e4c88..b473dae2abbb 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce120/irq_service_dce120.c @@ -257,8 +257,7 @@ static void dce120_irq_construct( struct irq_service *dal_irq_service_dce120_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c index d777b85e70da..68692a126f60 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce60/irq_service_dce60.c @@ -355,8 +355,7 @@ static void dce60_irq_construct( struct irq_service *dal_irq_service_dce60_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c index 3a9163acb49b..b5c5f42cf8f2 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dce80/irq_service_dce80.c @@ -267,8 +267,7 @@ static void dce80_irq_construct( struct irq_service *dal_irq_service_dce80_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c index 4ce9edd16344..ca2e13702fbb 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn10/irq_service_dcn10.c @@ -369,8 +369,7 @@ static void dcn10_irq_construct( struct irq_service *dal_irq_service_dcn10_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c index 5847af0e66cb..1c4c51abc259 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn20/irq_service_dcn20.c @@ -374,8 +374,7 @@ static void dcn20_irq_construct( struct irq_service *dal_irq_service_dcn20_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c index 6417011d2246..04b5d748e03a 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn201/irq_service_dcn201.c @@ -328,8 +328,7 @@ static void dcn201_irq_construct( struct irq_service *dal_irq_service_dcn201_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c index 71d2f065140b..9e0881472e38 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn21/irq_service_dcn21.c @@ -402,8 +402,7 @@ static void dcn21_irq_construct( struct irq_service *dal_irq_service_dcn21_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c index 2a4080bdcf6b..92bcd35723ca 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn30/irq_service_dcn30.c @@ -411,8 +411,7 @@ static void dcn30_irq_construct( struct irq_service *dal_irq_service_dcn30_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c index 624f1ac309f8..16685d066c1a 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn302/irq_service_dcn302.c @@ -377,7 +377,7 @@ static void dcn302_irq_construct(struct irq_service *irq_service, struct irq_ser struct irq_service *dal_irq_service_dcn302_create(struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c index 137caffae916..01d83e1922d6 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn303/irq_service_dcn303.c @@ -273,7 +273,7 @@ static void dcn303_irq_construct(struct irq_service *irq_service, struct irq_ser struct irq_service *dal_irq_service_dcn303_create(struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c index 921cb167d920..2114c5669e6e 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn31/irq_service_dcn31.c @@ -393,8 +393,7 @@ static void dcn31_irq_construct( struct irq_service *dal_irq_service_dcn31_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c b/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c index 0118fd6e5db0..16f158e0fb60 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn314/irq_service_dcn314.c @@ -395,8 +395,7 @@ static void dcn314_irq_construct( struct irq_service *dal_irq_service_dcn314_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c index adebfc888618..8ee03c006ad6 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn315/irq_service_dcn315.c @@ -400,8 +400,7 @@ static void dcn315_irq_construct( struct irq_service *dal_irq_service_dcn315_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c b/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c index e9e315c75d76..07e6f7dd6b99 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn32/irq_service_dcn32.c @@ -425,8 +425,7 @@ static void dcn32_irq_construct( struct irq_service *dal_irq_service_dcn32_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c b/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c index 79e5e8c137ca..3d28a5007f53 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn35/irq_service_dcn35.c @@ -389,8 +389,7 @@ static void dcn35_irq_construct( struct irq_service *dal_irq_service_dcn35_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c b/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c index 163b8ee9ebf7..f716c2590876 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn351/irq_service_dcn351.c @@ -371,8 +371,7 @@ static void dcn351_irq_construct( struct irq_service *dal_irq_service_dcn351_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c index f716ab0fd30e..e718004901cf 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn36/irq_service_dcn36.c @@ -370,8 +370,7 @@ static void dcn36_irq_construct( struct irq_service *dal_irq_service_dcn36_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c b/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c index fd9bb1950c20..2cde50b2ae22 100644 --- a/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c +++ b/drivers/gpu/drm/amd/display/dc/irq/dcn401/irq_service_dcn401.c @@ -403,8 +403,7 @@ static void dcn401_irq_construct( struct irq_service *dal_irq_service_dcn401_create( struct irq_service_init_data *init_data) { - struct irq_service *irq_service = kzalloc(sizeof(*irq_service), - GFP_KERNEL); + struct irq_service *irq_service = kzalloc_obj(*irq_service); if (!irq_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/link/Makefile b/drivers/gpu/drm/amd/display/dc/link/Makefile index 84dace27daf7..0f3670e30232 100644 --- a/drivers/gpu/drm/amd/display/dc/link/Makefile +++ b/drivers/gpu/drm/amd/display/dc/link/Makefile @@ -43,7 +43,8 @@ AMD_DISPLAY_FILES += $(AMD_DAL_LINK_ACCESSORIES) # hwss ############################################################################### LINK_HWSS = link_hwss_dio.o link_hwss_dpia.o link_hwss_hpo_dp.o \ -link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o +link_hwss_dio_fixed_vs_pe_retimer.o link_hwss_hpo_fixed_vs_pe_retimer_dp.o \ +link_hwss_virtual.o AMD_DAL_LINK_HWSS = $(addprefix $(AMDDALPATH)/dc/link/hwss/, \ $(LINK_HWSS)) diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c similarity index 98% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c rename to drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c index 4f7f99156897..64742c24f7e6 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.c +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.c @@ -23,7 +23,7 @@ * */ -#include "virtual_link_hwss.h" +#include "link_hwss_virtual.h" void virtual_setup_stream_encoder(struct pipe_ctx *pipe_ctx) { diff --git a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h similarity index 92% rename from drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h rename to drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h index fbcbc5afb47d..f6e448c89751 100644 --- a/drivers/gpu/drm/amd/display/dc/virtual/virtual_link_hwss.h +++ b/drivers/gpu/drm/amd/display/dc/link/hwss/link_hwss_virtual.h @@ -22,8 +22,8 @@ * Authors: AMD * */ -#ifndef __DC_VIRTUAL_LINK_HWSS_H__ -#define __DC_VIRTUAL_LINK_HWSS_H__ +#ifndef __DC_LINK_HWSS_VIRTUAL_H__ +#define __DC_LINK_HWSS_VIRTUAL_H__ #include "core_types.h" @@ -32,4 +32,4 @@ void virtual_setup_stream_attribute(struct pipe_ctx *pipe_ctx); void virtual_reset_stream_encoder(struct pipe_ctx *pipe_ctx); const struct link_hwss *get_virtual_link_hwss(void); -#endif /* __DC_VIRTUAL_LINK_HWSS_H__ */ +#endif /* __DC_LINK_HWSS_VIRTUAL_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/link/link_detection.c b/drivers/gpu/drm/amd/display/dc/link/link_detection.c index 578509e8d0e2..b2c020071cbf 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_detection.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_detection.c @@ -1333,7 +1333,7 @@ static bool detect_link_and_local_sink(struct dc_link *link, // Pickup base DM settings dm_helpers_init_panel_settings(dc_ctx, &link->panel_config, sink); // Override dc_panel_config if system has specific settings - dm_helpers_override_panel_settings(dc_ctx, &link->panel_config); + dm_helpers_override_panel_settings(dc_ctx, link); //sink only can use supported link rate table, we are foreced to enable it if (link->reported_link_cap.link_rate == LINK_RATE_UNKNOWN) diff --git a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c index 91742bde4dc2..9b1d34c3438b 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_dpms.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_dpms.c @@ -2155,6 +2155,18 @@ static enum dc_status enable_link_dp_mst( return enable_link_dp(state, pipe_ctx); } +static enum dc_status enable_link_analog( + struct dc_state *state, + struct pipe_ctx *pipe_ctx) +{ + struct dc_link *link = pipe_ctx->stream->link; + + link->dc->hwss.enable_analog_link_output( + link, pipe_ctx->stream->timing.pix_clk_100hz); + + return DC_OK; +} + static enum dc_status enable_link_virtual(struct pipe_ctx *pipe_ctx) { struct dc_link *link = pipe_ctx->stream->link; @@ -2210,7 +2222,7 @@ static enum dc_status enable_link( status = DC_OK; break; case SIGNAL_TYPE_RGB: - status = DC_OK; + status = enable_link_analog(state, pipe_ctx); break; case SIGNAL_TYPE_VIRTUAL: status = enable_link_virtual(pipe_ctx); diff --git a/drivers/gpu/drm/amd/display/dc/link/link_factory.c b/drivers/gpu/drm/amd/display/dc/link/link_factory.c index 5fbcf04c6251..21815ad01a29 100644 --- a/drivers/gpu/drm/amd/display/dc/link/link_factory.c +++ b/drivers/gpu/drm/amd/display/dc/link/link_factory.c @@ -302,7 +302,7 @@ static void construct_link_service(struct link_service *link_srv) struct link_service *link_create_link_service(void) { - struct link_service *link_srv = kzalloc(sizeof(*link_srv), GFP_KERNEL); + struct link_service *link_srv = kzalloc_obj(*link_srv); if (link_srv == NULL) goto fail; @@ -561,12 +561,13 @@ static bool construct_phy(struct dc_link *link, enc_init_data.connector = link->link_id; enc_init_data.channel = get_ddc_line(link); enc_init_data.transmitter = transmitter_from_encoder; - enc_init_data.analog_engine = find_analog_engine(link, &enc_init_data.analog_encoder); enc_init_data.encoder = link_encoder; enc_init_data.analog_engine = link_analog_engine; - enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, - link->ctx->gpio_service); - + if (link->ctx->dce_version <= DCN_VERSION_4_01) + enc_init_data.hpd_gpio = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, + link->ctx->gpio_service); + else + enc_init_data.hpd_gpio = NULL; if (enc_init_data.hpd_gpio) { dal_gpio_open(enc_init_data.hpd_gpio, GPIO_MODE_INTERRUPT); dal_gpio_unlock_pin(enc_init_data.hpd_gpio); @@ -896,8 +897,7 @@ static bool link_construct(struct dc_link *link, struct dc_link *link_create(const struct link_init_data *init_params) { - struct dc_link *link = - kzalloc(sizeof(*link), GFP_KERNEL); + struct dc_link *link = kzalloc_obj(*link); if (NULL == link) goto alloc_fail; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c index 5d2bcce2f669..a66217e54a09 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_ddc.c @@ -156,7 +156,7 @@ struct ddc_service *link_create_ddc_service( { struct ddc_service *ddc_service; - ddc_service = kzalloc(sizeof(struct ddc_service), GFP_KERNEL); + ddc_service = kzalloc_obj(struct ddc_service); if (!ddc_service) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c index bbd6f93f5c98..7e45d1e767bb 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_panel_replay.c @@ -34,6 +34,47 @@ link->ctx->logger #define DP_SINK_PR_ENABLE_AND_CONFIGURATION 0x37B +#define DP_SINK_ENABLE_FRAME_SKIPPING_MODE_SHIFT (5) + +static unsigned int dp_pr_calc_num_static_frames(unsigned int vsync_rate_hz) +{ + // at least 2 frames for static screen + unsigned int num_frames = 2; + + // get number of frames for at least 50ms + if (vsync_rate_hz > 40) + num_frames = (vsync_rate_hz + 10) / 20; + + return num_frames; +} + +static void dp_pr_set_static_screen_param(struct dc_link *link) +{ + struct dc_static_screen_params params = {0}; + struct dc *dc = link->ctx->dc; + // only support DP sst for now + if (!dc_is_dp_sst_signal(link->connector_signal)) + return; + + for (int i = 0; i < MAX_PIPES; i++) { + if (dc->current_state->res_ctx.pipe_ctx[i].stream && + dc->current_state->res_ctx.pipe_ctx[i].stream->link == link) { + struct dc_stream_state *stream = dc->current_state->res_ctx.pipe_ctx[i].stream; + unsigned int vsync_rate_hz = div64_u64(div64_u64( + (stream->timing.pix_clk_100hz * (u64)100), + stream->timing.v_total), + stream->timing.h_total); + + params.triggers.cursor_update = true; + params.triggers.overlay_update = true; + params.triggers.surface_update = true; + params.num_frames = dp_pr_calc_num_static_frames(vsync_rate_hz); + + dc_stream_set_static_screen_params(dc, &stream, 1, ¶ms); + break; + } + } +} static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_state *stream) { @@ -49,6 +90,7 @@ static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_s union panel_replay_enable_and_configuration_2 pr_config_2 = { 0 }; union dpcd_alpm_configuration alpm_config; + uint8_t data = 0; replay_context.controllerId = CONTROLLER_ID_UNDEFINED; @@ -146,6 +188,14 @@ static bool dp_setup_panel_replay(struct dc_link *link, const struct dc_stream_s DP_RECEIVER_ALPM_CONFIG, &alpm_config.raw, sizeof(alpm_config.raw)); + + //Enable frame skipping + if (link->replay_settings.config.frame_skip_supported) + data = data | (1 << DP_SINK_ENABLE_FRAME_SKIPPING_MODE_SHIFT); + + dm_helpers_dp_write_dpcd(link->ctx, link, + DP_SINK_PR_ENABLE_AND_CONFIGURATION, + (uint8_t *)&(data), sizeof(uint8_t)); } return true; @@ -159,6 +209,9 @@ bool dp_pr_get_panel_inst(const struct dc *dc, if (!dc || !link || !inst_out) return false; + if (dc->config.frame_update_cmd_version2 == false) + return dc_get_edp_link_panel_inst(dc, link, inst_out); + if (!dc_is_dp_sst_signal(link->connector_signal)) /* only supoprt DP sst (eDP included) for now */ return false; @@ -199,6 +252,9 @@ bool dp_pr_enable(struct dc_link *link, bool enable) if (!dp_pr_get_panel_inst(dc, link, &panel_inst)) return false; + if (enable && !dc_is_embedded_signal(link->connector_signal)) + dp_pr_set_static_screen_param(link); + if (link->replay_settings.replay_allow_active != enable) { //for sending PR enable commands to DMUB memset(&cmd, 0, sizeof(cmd)); @@ -276,6 +332,12 @@ bool dp_pr_copy_settings(struct dc_link *link, struct replay_context *replay_con pipe_ctx->stream->timing.v_border_top + pipe_ctx->stream->timing.v_border_bottom) / pipe_ctx->stream->timing.dsc_cfg.num_slices_v; + if (dc_is_embedded_signal(link->connector_signal)) + cmd.pr_copy_settings.data.main_link_activity_option = OPTION_1C; + else + // For external DP, use option 1-A + cmd.pr_copy_settings.data.main_link_activity_option = OPTION_1A; + dc_wake_and_execute_dmub_cmd(dc->ctx, &cmd, DM_DMUB_WAIT_TYPE_WAIT); return true; } diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c index 29f3a03687b2..b157d05b67ad 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_hpd.c @@ -136,8 +136,13 @@ enum hpd_source_id get_hpd_line(struct dc_link *link) hpd_id = HPD_SOURCEID_UNKNOWN; - hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, - link->ctx->gpio_service); + /* Use GPIO path where supported, otherwise use hardware encoder path */ + if (link->ctx && link->ctx->dce_version <= DCN_VERSION_4_01) { + hpd = link_get_hpd_gpio(link->ctx->dc_bios, link->link_id, + link->ctx->gpio_service); + } else { + hpd = NULL; + } if (hpd) { switch (dal_irq_get_source(hpd)) { diff --git a/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c b/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c index 83bbbf34bcac..badcef027b84 100644 --- a/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c +++ b/drivers/gpu/drm/amd/display/dc/mpc/dcn32/dcn32_mpc.c @@ -724,8 +724,7 @@ bool mpc32_program_shaper( return false; } - if (mpc->ctx->dc->debug.enable_mem_low_power.bits.mpc) - mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); + mpc32_power_on_shaper_3dlut(mpc, mpcc_id, true); current_mode = mpc32_get_shaper_current(mpc, mpcc_id); diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h index 803bcc25601c..0b3f974f452e 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn10/dcn10_optc.h @@ -244,7 +244,13 @@ uint32_t OTG_TRIGB_MANUAL_TRIG; \ uint32_t OTG_UPDATE_LOCK; \ uint32_t OTG_V_TOTAL_INT_STATUS; \ - uint32_t OTG_VSYNC_NOM_INT_STATUS + uint32_t OTG_VSYNC_NOM_INT_STATUS; \ + uint32_t OTG_CRC0_DATA_R32; \ + uint32_t OTG_CRC0_DATA_G32; \ + uint32_t OTG_CRC0_DATA_B32; \ + uint32_t OTG_CRC1_DATA_R32; \ + uint32_t OTG_CRC1_DATA_G32; \ + uint32_t OTG_CRC1_DATA_B32 struct dcn_optc_registers { @@ -657,6 +663,15 @@ struct dcn_optc_registers { type OTG_V_COUNT_STOP;\ type OTG_V_COUNT_STOP_TIMER; +#define TG_REG_FIELD_LIST_DCN3_6(type) \ + type OTG_CRC_POLY_SEL; \ + type CRC0_R_CR32; \ + type CRC0_G_Y32; \ + type CRC0_B_CB32; \ + type CRC1_R_CR32; \ + type CRC1_G_Y32; \ + type CRC1_B_CB32; + #define TG_REG_FIELD_LIST_DCN401(type) \ type OPTC_SEGMENT_WIDTH_LAST;\ type OTG_PSTATE_KEEPOUT_START;\ @@ -670,6 +685,7 @@ struct dcn_optc_shift { TG_REG_FIELD_LIST_DCN2_0(uint8_t) TG_REG_FIELD_LIST_DCN3_2(uint8_t) TG_REG_FIELD_LIST_DCN3_5(uint8_t) + TG_REG_FIELD_LIST_DCN3_6(uint8_t) TG_REG_FIELD_LIST_DCN401(uint8_t) }; @@ -678,6 +694,7 @@ struct dcn_optc_mask { TG_REG_FIELD_LIST_DCN2_0(uint32_t) TG_REG_FIELD_LIST_DCN3_2(uint32_t) TG_REG_FIELD_LIST_DCN3_5(uint32_t) + TG_REG_FIELD_LIST_DCN3_6(uint32_t) TG_REG_FIELD_LIST_DCN401(uint32_t) }; diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c index f699e95059f3..5aafd0eedf66 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.c @@ -180,7 +180,97 @@ static void optc35_phantom_crtc_post_enable(struct timing_generator *optc) REG_WAIT(OTG_CLOCK_CONTROL, OTG_BUSY, 0, 1, 100000); } -static bool optc35_configure_crc(struct timing_generator *optc, +/** + * optc35_get_crc - Capture CRC result per component + * + * @optc: timing_generator instance. + * @idx: index of crc engine to get CRC from + * @r_cr: primary CRC signature for red data. + * @g_y: primary CRC signature for green data. + * @b_cb: primary CRC signature for blue data. + * + * This function reads the CRC signature from the OPTC registers. Notice that + * we have three registers to keep the CRC result per color component (RGB). + * + * For different DCN versions: + * - If CRC32 registers (OTG_CRC0_DATA_R32/G32/B32) are available, read from + * 32-bit CRC registers. DCN 3.6+ supports both CRC-32 and CRC-16 polynomials + * selectable via OTG_CRC_POLY_SEL. + * - Otherwise, read from legacy 16-bit CRC registers (OTG_CRC0_DATA_RG/B) + * which only support CRC-16 polynomial. + * + * Returns: + * If CRC is disabled, return false; otherwise, return true, and the CRC + * results in the parameters. + */ +static bool optc35_get_crc(struct timing_generator *optc, uint8_t idx, + uint32_t *r_cr, uint32_t *g_y, uint32_t *b_cb) +{ + uint32_t field = 0; + struct optc *optc1 = DCN10TG_FROM_TG(optc); + + REG_GET(OTG_CRC_CNTL, OTG_CRC_EN, &field); + + /* Early return if CRC is not enabled for this CRTC */ + if (!field) + return false; + + if (optc1->tg_mask->CRC0_R_CR32 != 0 && optc1->tg_mask->CRC1_R_CR32 != 0 && + optc1->tg_mask->CRC0_G_Y32 != 0 && optc1->tg_mask->CRC1_G_Y32 != 0 && + optc1->tg_mask->CRC0_B_CB32 != 0 && optc1->tg_mask->CRC1_B_CB32 != 0) { + switch (idx) { + case 0: + /* OTG_CRC0_DATA_R32/G32/B32 has the CRC32 results */ + REG_GET(OTG_CRC0_DATA_R32, + CRC0_R_CR32, r_cr); + REG_GET(OTG_CRC0_DATA_G32, + CRC0_G_Y32, g_y); + REG_GET(OTG_CRC0_DATA_B32, + CRC0_B_CB32, b_cb); + break; + case 1: + /* OTG_CRC1_DATA_R32/G32/B32 has the CRC32 results */ + REG_GET(OTG_CRC1_DATA_R32, + CRC1_R_CR32, r_cr); + REG_GET(OTG_CRC1_DATA_G32, + CRC1_G_Y32, g_y); + REG_GET(OTG_CRC1_DATA_B32, + CRC1_B_CB32, b_cb); + break; + default: + return false; + } + } else { + switch (idx) { + case 0: + /* OTG_CRC0_DATA_RG has the CRC16 results for the red and green component */ + REG_GET_2(OTG_CRC0_DATA_RG, + CRC0_R_CR, r_cr, + CRC0_G_Y, g_y); + + /* OTG_CRC0_DATA_B has the CRC16 results for the blue component */ + REG_GET(OTG_CRC0_DATA_B, + CRC0_B_CB, b_cb); + break; + case 1: + /* OTG_CRC1_DATA_RG has the CRC16 results for the red and green component */ + REG_GET_2(OTG_CRC1_DATA_RG, + CRC1_R_CR, r_cr, + CRC1_G_Y, g_y); + + /* OTG_CRC1_DATA_B has the CRC16 results for the blue component */ + REG_GET(OTG_CRC1_DATA_B, + CRC1_B_CB, b_cb); + break; + default: + return false; + } + } + + return true; +} + +bool optc35_configure_crc(struct timing_generator *optc, const struct crc_params *params) { struct optc *optc1 = DCN10TG_FROM_TG(optc); @@ -266,6 +356,10 @@ static bool optc35_configure_crc(struct timing_generator *optc, default: return false; } + if (optc1->tg_mask->OTG_CRC_POLY_SEL != 0) { + REG_UPDATE(OTG_CRC_CNTL, + OTG_CRC_POLY_SEL, params->crc_poly_mode); + } return true; } @@ -343,7 +437,7 @@ void optc35_set_drr( REG_WRITE(OTG_V_COUNT_STOP_CONTROL2, 0); } -static void optc35_set_long_vtotal( +void optc35_set_long_vtotal( struct timing_generator *optc, const struct long_vtotal_params *params) { @@ -430,7 +524,7 @@ static void optc35_set_long_vtotal( } } -static void optc35_wait_otg_disable(struct timing_generator *optc) +void optc35_wait_otg_disable(struct timing_generator *optc) { struct optc *optc1; uint32_t is_master_en; @@ -488,7 +582,7 @@ static const struct timing_generator_funcs dcn35_tg_funcs = { .is_optc_underflow_occurred = optc1_is_optc_underflow_occurred, .clear_optc_underflow = optc1_clear_optc_underflow, .setup_global_swap_lock = NULL, - .get_crc = optc1_get_crc, + .get_crc = optc35_get_crc, .configure_crc = optc35_configure_crc, .set_dsc_config = optc3_set_dsc_config, .get_dsc_status = optc2_get_dsc_status, diff --git a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h index 733a2f149d9a..82e0818c8f9f 100644 --- a/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h +++ b/drivers/gpu/drm/amd/display/dc/optc/dcn35/dcn35_optc.h @@ -74,10 +74,29 @@ SF(OTG0_OTG_PIPE_UPDATE_STATUS, OTG_VUPDATE_KEEPOUT_STATUS, mask_sh),\ SF(OTG0_INTERRUPT_DEST, OTG0_IHC_OTG_VERTICAL_INTERRUPT2_DEST, mask_sh) +#define OPTC_COMMON_MASK_SH_LIST_DCN3_6(mask_sh)\ + OPTC_COMMON_MASK_SH_LIST_DCN3_5(mask_sh),\ + SF(OTG0_OTG_CRC_CNTL, OTG_CRC_POLY_SEL, mask_sh),\ + SF(OTG_CRC320_OTG_CRC0_DATA_R32, CRC0_R_CR32, mask_sh),\ + SF(OTG_CRC320_OTG_CRC0_DATA_G32, CRC0_G_Y32, mask_sh),\ + SF(OTG_CRC320_OTG_CRC0_DATA_B32, CRC0_B_CB32, mask_sh),\ + SF(OTG_CRC320_OTG_CRC1_DATA_R32, CRC1_R_CR32, mask_sh),\ + SF(OTG_CRC320_OTG_CRC1_DATA_G32, CRC1_G_Y32, mask_sh),\ + SF(OTG_CRC320_OTG_CRC1_DATA_B32, CRC1_B_CB32, mask_sh) + void dcn35_timing_generator_init(struct optc *optc1); void dcn35_timing_generator_set_fgcg(struct optc *optc1, bool enable); void optc35_set_drr(struct timing_generator *optc, const struct drr_params *params); +void optc35_set_long_vtotal( + struct timing_generator *optc, + const struct long_vtotal_params *params); + +bool optc35_configure_crc(struct timing_generator *optc, + const struct crc_params *params); + +void optc35_wait_otg_disable(struct timing_generator *optc); + #endif /* __DC_OPTC_DCN35_H__ */ diff --git a/drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c b/drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c index 72bd43f9bbe2..f5bf5940e748 100644 --- a/drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c +++ b/drivers/gpu/drm/amd/display/dc/pg/dcn35/dcn35_pg_cntl.c @@ -542,7 +542,7 @@ struct pg_cntl *pg_cntl35_create( const struct pg_cntl_shift *pg_cntl_shift, const struct pg_cntl_mask *pg_cntl_mask) { - struct dcn_pg_cntl *pg_cntl_dcn = kzalloc(sizeof(*pg_cntl_dcn), GFP_KERNEL); + struct dcn_pg_cntl *pg_cntl_dcn = kzalloc_obj(*pg_cntl_dcn); struct pg_cntl *base; if (pg_cntl_dcn == NULL) { diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c index d40d91ec2035..92c123aca0c9 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce100/dce100_resource.c @@ -31,7 +31,7 @@ #include "resource.h" #include "clk_mgr.h" #include "include/irq_service_interface.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce110/dce110_timing_generator.h" #include "irq/dce110/irq_service_dce110.h" @@ -226,7 +226,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), link_regs(6), - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\ @@ -242,7 +242,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(3), stream_enc_regs(4), stream_enc_regs(5), - stream_enc_regs(6) + stream_enc_regs(6), + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -471,7 +472,7 @@ static struct timing_generator *dce100_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -485,13 +486,14 @@ static struct stream_encoder *dce100_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } @@ -518,7 +520,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dce100_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -571,8 +573,7 @@ static struct mem_input *dce100_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -595,7 +596,7 @@ static struct transform *dce100_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -608,7 +609,7 @@ static struct transform *dce100_transform_create( static struct input_pixel_processor *dce100_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -632,13 +633,14 @@ static struct link_encoder *dce100_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { dce110_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, @@ -666,7 +668,7 @@ static struct link_encoder *dce100_link_encoder_create( static struct panel_cntl *dce100_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -685,7 +687,7 @@ static struct output_pixel_processor *dce100_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -700,7 +702,7 @@ static struct dce_aux *dce100_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -738,7 +740,7 @@ static struct dce_i2c_hw *dce100_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -756,7 +758,7 @@ static struct clock_source *dce100_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -978,7 +980,10 @@ struct stream_encoder *dce100_find_first_free_match_stream_enc_for_link( struct dc_link *link = stream->link; enum engine_id preferred_engine = link->link_enc->preferred_engine; - if (dc_is_rgb_signal(stream->signal)) + /* Prefer analog engine if the link encoder has one. + * Otherwise, it's an external encoder. + */ + if (dc_is_rgb_signal(stream->signal) && link->link_enc->analog_engine != ENGINE_ID_UNKNOWN) preferred_engine = link->link_enc->analog_engine; for (i = 0; i < pool->stream_enc_count; i++) { @@ -1209,7 +1214,7 @@ struct resource_pool *dce100_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c index 7c09825cd9bd..95852d277c22 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce110/dce110_resource.c @@ -516,7 +516,7 @@ static struct timing_generator *dce110_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -530,7 +530,7 @@ static struct stream_encoder *dce110_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; @@ -563,7 +563,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dce110_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -608,8 +608,7 @@ static struct mem_input *dce110_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -632,7 +631,7 @@ static struct transform *dce110_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -645,7 +644,7 @@ static struct transform *dce110_transform_create( static struct input_pixel_processor *dce110_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -669,7 +668,7 @@ static struct link_encoder *dce110_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -690,7 +689,7 @@ static struct link_encoder *dce110_link_encoder_create( static struct panel_cntl *dce110_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -709,7 +708,7 @@ static struct output_pixel_processor *dce110_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -724,7 +723,7 @@ static struct dce_aux *dce110_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -762,7 +761,7 @@ static struct dce_i2c_hw *dce110_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -780,7 +779,7 @@ static struct clock_source *dce110_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -1250,14 +1249,10 @@ static const struct resource_funcs dce110_res_pool_funcs = { static bool underlay_create(struct dc_context *ctx, struct resource_pool *pool) { - struct dce110_timing_generator *dce110_tgv = kzalloc(sizeof(*dce110_tgv), - GFP_KERNEL); - struct dce_transform *dce110_xfmv = kzalloc(sizeof(*dce110_xfmv), - GFP_KERNEL); - struct dce_mem_input *dce110_miv = kzalloc(sizeof(*dce110_miv), - GFP_KERNEL); - struct dce110_opp *dce110_oppv = kzalloc(sizeof(*dce110_oppv), - GFP_KERNEL); + struct dce110_timing_generator *dce110_tgv = kzalloc_obj(*dce110_tgv); + struct dce_transform *dce110_xfmv = kzalloc_obj(*dce110_xfmv); + struct dce_mem_input *dce110_miv = kzalloc_obj(*dce110_miv); + struct dce110_opp *dce110_oppv = kzalloc_obj(*dce110_oppv); if (!dce110_tgv || !dce110_xfmv || !dce110_miv || !dce110_oppv) { kfree(dce110_tgv); @@ -1545,7 +1540,7 @@ struct resource_pool *dce110_create_resource_pool( struct hw_asic_id asic_id) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c index 3f0a6bc4dcc2..58c6a00397cf 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce112/dce112_resource.c @@ -497,7 +497,7 @@ static struct timing_generator *dce112_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -511,7 +511,7 @@ static struct stream_encoder *dce112_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; @@ -540,7 +540,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dce112_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -580,8 +580,7 @@ static struct mem_input *dce112_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -603,7 +602,7 @@ static struct transform *dce112_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -630,7 +629,7 @@ static struct link_encoder *dce112_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -651,7 +650,7 @@ static struct link_encoder *dce112_link_encoder_create( static struct panel_cntl *dce112_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -668,7 +667,7 @@ static struct panel_cntl *dce112_panel_cntl_create(const struct panel_cntl_init_ static struct input_pixel_processor *dce112_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -685,7 +684,7 @@ static struct output_pixel_processor *dce112_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -700,7 +699,7 @@ static struct dce_aux *dce112_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -738,7 +737,7 @@ static struct dce_i2c_hw *dce112_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -756,7 +755,7 @@ static struct clock_source *dce112_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -1423,7 +1422,7 @@ struct resource_pool *dce112_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c index b1570b6b1af3..71d76b021375 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce120/dce120_resource.c @@ -35,7 +35,7 @@ #include "dce112/dce112_resource.h" #include "dce110/dce110_resource.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce120/dce120_timing_generator.h" #include "irq/dce120/irq_service_dce120.h" #include "dce/dce_opp.h" @@ -428,7 +428,7 @@ static struct output_pixel_processor *dce120_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -442,7 +442,7 @@ static struct dce_aux *dce120_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -480,7 +480,7 @@ static struct dce_i2c_hw *dce120_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -541,8 +541,7 @@ static struct clock_source *dce120_clock_source_create( const struct dce110_clk_src_regs *regs, bool dp_clk_src) { - struct dce110_clk_src *clk_src = - kzalloc(sizeof(*clk_src), GFP_KERNEL); + struct dce110_clk_src *clk_src = kzalloc_obj(*clk_src); if (!clk_src) return NULL; @@ -583,7 +582,7 @@ static struct timing_generator *dce120_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -714,7 +713,7 @@ static struct link_encoder *dce120_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -736,7 +735,7 @@ static struct link_encoder *dce120_link_encoder_create( static struct panel_cntl *dce120_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -753,7 +752,7 @@ static struct panel_cntl *dce120_panel_cntl_create(const struct panel_cntl_init_ static struct input_pixel_processor *dce120_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -770,7 +769,7 @@ static struct stream_encoder *dce120_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; @@ -813,7 +812,7 @@ static const struct dce_hwseq_mask dce121_hwseq_mask = { static struct dce_hwseq *dce120_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -827,7 +826,7 @@ static struct dce_hwseq *dce120_hwseq_create( static struct dce_hwseq *dce121_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -875,8 +874,7 @@ static struct mem_input *dce120_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -892,7 +890,7 @@ static struct transform *dce120_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -1296,7 +1294,7 @@ struct resource_pool *dce120_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c index f0152933bee2..c27645708286 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce60/dce60_resource.c @@ -243,7 +243,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), {0}, - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\ @@ -258,7 +258,9 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(2), stream_enc_regs(3), stream_enc_regs(4), - stream_enc_regs(5) + stream_enc_regs(5), + {0}, + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -505,7 +507,7 @@ static struct timing_generator *dce60_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -519,7 +521,7 @@ static struct output_pixel_processor *dce60_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -534,7 +536,7 @@ static struct dce_aux *dce60_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -572,7 +574,7 @@ static struct dce_i2c_hw *dce60_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -587,7 +589,7 @@ static struct dce_i2c_sw *dce60_i2c_sw_create( struct dc_context *ctx) { struct dce_i2c_sw *dce_i2c_sw = - kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_sw); if (!dce_i2c_sw) return NULL; @@ -601,13 +603,14 @@ static struct stream_encoder *dce60_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } @@ -635,7 +638,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dce60_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -680,8 +683,7 @@ static struct mem_input *dce60_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -704,7 +706,7 @@ static struct transform *dce60_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -727,14 +729,15 @@ static struct link_encoder *dce60_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { - dce110_link_encoder_construct(enc110, + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { + dce60_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, &link_enc_regs[ENGINE_ID_DACA], @@ -761,7 +764,7 @@ static struct link_encoder *dce60_link_encoder_create( static struct panel_cntl *dce60_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -783,7 +786,7 @@ static struct clock_source *dce60_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -808,7 +811,7 @@ static void dce60_clock_source_destroy(struct clock_source **clk_src) static struct input_pixel_processor *dce60_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -1094,7 +1097,7 @@ struct resource_pool *dce60_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; @@ -1292,7 +1295,7 @@ struct resource_pool *dce61_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; @@ -1489,7 +1492,7 @@ struct resource_pool *dce64_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c index 8687104cabb7..d66d8ac6d897 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dce80/dce80_resource.c @@ -242,7 +242,7 @@ static const struct dce110_link_enc_registers link_enc_regs[] = { link_regs(4), link_regs(5), link_regs(6), - { .DAC_ENABLE = mmDAC_ENABLE }, + {0} }; #define stream_enc_regs(id)\ @@ -258,7 +258,8 @@ static const struct dce110_stream_enc_registers stream_enc_regs[] = { stream_enc_regs(3), stream_enc_regs(4), stream_enc_regs(5), - stream_enc_regs(6) + stream_enc_regs(6), + {SR(DAC_SOURCE_SELECT),} /* DACA */ }; static const struct dce_stream_encoder_shift se_shift = { @@ -512,7 +513,7 @@ static struct timing_generator *dce80_timing_generator_create( const struct dce110_timing_generator_offsets *offsets) { struct dce110_timing_generator *tg110 = - kzalloc(sizeof(struct dce110_timing_generator), GFP_KERNEL); + kzalloc_obj(struct dce110_timing_generator); if (!tg110) return NULL; @@ -526,7 +527,7 @@ static struct output_pixel_processor *dce80_opp_create( uint32_t inst) { struct dce110_opp *opp = - kzalloc(sizeof(struct dce110_opp), GFP_KERNEL); + kzalloc_obj(struct dce110_opp); if (!opp) return NULL; @@ -541,7 +542,7 @@ static struct dce_aux *dce80_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -579,7 +580,7 @@ static struct dce_i2c_hw *dce80_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -594,7 +595,7 @@ static struct dce_i2c_sw *dce80_i2c_sw_create( struct dc_context *ctx) { struct dce_i2c_sw *dce_i2c_sw = - kzalloc(sizeof(struct dce_i2c_sw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_sw); if (!dce_i2c_sw) return NULL; @@ -608,13 +609,14 @@ static struct stream_encoder *dce80_stream_encoder_create( struct dc_context *ctx) { struct dce110_stream_encoder *enc110 = - kzalloc(sizeof(struct dce110_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_stream_encoder); if (!enc110) return NULL; if (eng_id == ENGINE_ID_DACA || eng_id == ENGINE_ID_DACB) { - dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id); + dce110_analog_stream_encoder_construct(enc110, ctx, ctx->dc_bios, eng_id, + &stream_enc_regs[eng_id], &se_shift, &se_mask); return &enc110->base; } @@ -642,7 +644,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dce80_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -687,8 +689,7 @@ static struct mem_input *dce80_mem_input_create( struct dc_context *ctx, uint32_t inst) { - struct dce_mem_input *dce_mi = kzalloc(sizeof(struct dce_mem_input), - GFP_KERNEL); + struct dce_mem_input *dce_mi = kzalloc_obj(struct dce_mem_input); if (!dce_mi) { BREAK_TO_DEBUGGER(); @@ -711,7 +712,7 @@ static struct transform *dce80_transform_create( uint32_t inst) { struct dce_transform *transform = - kzalloc(sizeof(struct dce_transform), GFP_KERNEL); + kzalloc_obj(struct dce_transform); if (!transform) return NULL; @@ -734,13 +735,14 @@ static struct link_encoder *dce80_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dce110_link_encoder *enc110 = - kzalloc(sizeof(struct dce110_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dce110_link_encoder); int link_regs_id; if (!enc110) return NULL; - if (enc_init_data->connector.id == CONNECTOR_ID_VGA) { + if (enc_init_data->connector.id == CONNECTOR_ID_VGA && + enc_init_data->analog_engine != ENGINE_ID_UNKNOWN) { dce110_link_encoder_construct(enc110, enc_init_data, &link_enc_feature, @@ -768,7 +770,7 @@ static struct link_encoder *dce80_link_encoder_create( static struct panel_cntl *dce80_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -790,7 +792,7 @@ static struct clock_source *dce80_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -815,7 +817,7 @@ static void dce80_clock_source_destroy(struct clock_source **clk_src) static struct input_pixel_processor *dce80_ipp_create( struct dc_context *ctx, uint32_t inst) { - struct dce_ipp *ipp = kzalloc(sizeof(struct dce_ipp), GFP_KERNEL); + struct dce_ipp *ipp = kzalloc_obj(struct dce_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -1106,7 +1108,7 @@ struct resource_pool *dce80_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; @@ -1306,7 +1308,7 @@ struct resource_pool *dce81_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; @@ -1504,7 +1506,7 @@ struct resource_pool *dce83_create_resource_pool( struct dc *dc) { struct dce110_resource_pool *pool = - kzalloc(sizeof(struct dce110_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dce110_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c index f12367adf145..bbe185e15eb6 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn10/dcn10_resource.c @@ -48,7 +48,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce112/dce112_resource.h" #include "dcn10/dcn10_hubp.h" @@ -574,7 +574,7 @@ static struct dpp *dcn10_dpp_create( uint32_t inst) { struct dcn10_dpp *dpp = - kzalloc(sizeof(struct dcn10_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn10_dpp); if (!dpp) return NULL; @@ -588,7 +588,7 @@ static struct input_pixel_processor *dcn10_ipp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_ipp *ipp = - kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); + kzalloc_obj(struct dcn10_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -605,7 +605,7 @@ static struct output_pixel_processor *dcn10_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_opp *opp = - kzalloc(sizeof(struct dcn10_opp), GFP_KERNEL); + kzalloc_obj(struct dcn10_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -621,7 +621,7 @@ static struct dce_aux *dcn10_aux_engine_create(struct dc_context *ctx, uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -658,7 +658,7 @@ static struct dce_i2c_hw *dcn10_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -670,8 +670,7 @@ static struct dce_i2c_hw *dcn10_i2c_hw_create(struct dc_context *ctx, } static struct mpc *dcn10_mpc_create(struct dc_context *ctx) { - struct dcn10_mpc *mpc10 = kzalloc(sizeof(struct dcn10_mpc), - GFP_KERNEL); + struct dcn10_mpc *mpc10 = kzalloc_obj(struct dcn10_mpc); if (!mpc10) return NULL; @@ -687,8 +686,7 @@ static struct mpc *dcn10_mpc_create(struct dc_context *ctx) static struct hubbub *dcn10_hubbub_create(struct dc_context *ctx) { - struct dcn10_hubbub *dcn10_hubbub = kzalloc(sizeof(struct dcn10_hubbub), - GFP_KERNEL); + struct dcn10_hubbub *dcn10_hubbub = kzalloc_obj(struct dcn10_hubbub); if (!dcn10_hubbub) return NULL; @@ -706,7 +704,7 @@ static struct timing_generator *dcn10_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -739,7 +737,7 @@ static struct link_encoder *dcn10_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn10_link_encoder *enc10 = - kzalloc(sizeof(struct dcn10_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn10_link_encoder); int link_regs_id; if (!enc10 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -763,7 +761,7 @@ static struct link_encoder *dcn10_link_encoder_create( static struct panel_cntl *dcn10_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -785,7 +783,7 @@ static struct clock_source *dcn10_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -821,7 +819,7 @@ static struct stream_encoder *dcn10_stream_encoder_create( struct dc_context *ctx) { struct dcn10_stream_encoder *enc1 = - kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn10_stream_encoder); if (!enc1) return NULL; @@ -847,7 +845,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dcn10_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -891,7 +889,7 @@ static void dcn10_clock_source_destroy(struct clock_source **clk_src) static struct pp_smu_funcs *dcn10_pp_smu_create(struct dc_context *ctx) { - struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); + struct pp_smu_funcs *pp_smu = kzalloc_obj(*pp_smu); if (!pp_smu) return pp_smu; @@ -984,7 +982,7 @@ static struct hubp *dcn10_hubp_create( uint32_t inst) { struct dcn10_hubp *hubp1 = - kzalloc(sizeof(struct dcn10_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn10_hubp); if (!hubp1) return NULL; @@ -1681,7 +1679,7 @@ struct resource_pool *dcn10_create_resource_pool( struct dc *dc) { struct dcn10_resource_pool *pool = - kzalloc(sizeof(struct dcn10_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn10_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c index 46985eb2a623..8b555187ac75 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn20/dcn20_resource.c @@ -55,7 +55,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn20/dcn20_dccg.h" @@ -736,7 +736,7 @@ struct dpp *dcn20_dpp_create( uint32_t inst) { struct dcn20_dpp *dpp = - kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn20_dpp); if (!dpp) return NULL; @@ -754,7 +754,7 @@ struct input_pixel_processor *dcn20_ipp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_ipp *ipp = - kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); + kzalloc_obj(struct dcn10_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -771,7 +771,7 @@ struct output_pixel_processor *dcn20_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -788,7 +788,7 @@ struct dce_aux *dcn20_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -826,7 +826,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -838,7 +838,7 @@ struct dce_i2c_hw *dcn20_i2c_hw_create( } struct mpc *dcn20_mpc_create(struct dc_context *ctx) { - struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), GFP_KERNEL); + struct dcn20_mpc *mpc20 = kzalloc_obj(struct dcn20_mpc); if (!mpc20) return NULL; @@ -855,7 +855,7 @@ struct mpc *dcn20_mpc_create(struct dc_context *ctx) struct hubbub *dcn20_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL); + struct dcn20_hubbub *hubbub = kzalloc_obj(struct dcn20_hubbub); if (!hubbub) return NULL; @@ -883,7 +883,7 @@ struct timing_generator *dcn20_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -917,7 +917,7 @@ struct link_encoder *dcn20_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); int link_regs_id; if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -941,7 +941,7 @@ struct link_encoder *dcn20_link_encoder_create( static struct panel_cntl *dcn20_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -963,7 +963,7 @@ static struct clock_source *dcn20_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -999,7 +999,7 @@ struct stream_encoder *dcn20_stream_encoder_create( struct dc_context *ctx) { struct dcn10_stream_encoder *enc1 = - kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn10_stream_encoder); if (!enc1) return NULL; @@ -1031,7 +1031,7 @@ static const struct dce_hwseq_mask hwseq_mask = { struct dce_hwseq *dcn20_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1062,7 +1062,7 @@ struct display_stream_compressor *dcn20_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1199,7 +1199,7 @@ struct hubp *dcn20_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -2130,7 +2130,8 @@ enum dc_status dcn20_validate_bandwidth(struct dc *dc, struct dc_state *context, bool voltage_supported; display_e2e_pipe_params_st *pipes; - pipes = kcalloc(dc->res_pool->pipe_count, sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); if (!pipes) return DC_FAIL_BANDWIDTH_VALIDATE; @@ -2240,8 +2241,7 @@ bool dcn20_dwbc_create(struct dc_context *ctx, struct resource_pool *pool) uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn20_dwbc *dwbc20 = kzalloc(sizeof(struct dcn20_dwbc), - GFP_KERNEL); + struct dcn20_dwbc *dwbc20 = kzalloc_obj(struct dcn20_dwbc); if (!dwbc20) { dm_error("DC: failed to create dwbc20!\n"); @@ -2265,8 +2265,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) ASSERT(pipe_count > 0); for (i = 0; i < pipe_count; i++) { - struct dcn20_mmhubbub *mcif_wb20 = kzalloc(sizeof(struct dcn20_mmhubbub), - GFP_KERNEL); + struct dcn20_mmhubbub *mcif_wb20 = kzalloc_obj(struct dcn20_mmhubbub); if (!mcif_wb20) { dm_error("DC: failed to create mcif_wb20!\n"); @@ -2286,7 +2285,7 @@ bool dcn20_mmhubbub_create(struct dc_context *ctx, struct resource_pool *pool) static struct pp_smu_funcs *dcn20_pp_smu_create(struct dc_context *ctx) { - struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); + struct pp_smu_funcs *pp_smu = kzalloc_obj(*pp_smu); if (!pp_smu) return pp_smu; @@ -2766,7 +2765,7 @@ struct resource_pool *dcn20_create_resource_pool( struct dc *dc) { struct dcn20_resource_pool *pool = - kzalloc(sizeof(struct dcn20_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn20_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c index 055107843a70..4ea76e46ab15 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn201/dcn201_resource.c @@ -51,7 +51,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dce/dce_aux.h" #include "dce/dce_i2c.h" @@ -632,7 +632,7 @@ static struct dpp *dcn201_dpp_create( uint32_t inst) { struct dcn201_dpp *dpp = - kzalloc(sizeof(struct dcn201_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn201_dpp); if (!dpp) return NULL; @@ -649,7 +649,7 @@ static struct input_pixel_processor *dcn201_ipp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_ipp *ipp = - kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); + kzalloc_obj(struct dcn10_ipp); if (!ipp) { return NULL; @@ -665,7 +665,7 @@ static struct output_pixel_processor *dcn201_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn201_opp *opp = - kzalloc(sizeof(struct dcn201_opp), GFP_KERNEL); + kzalloc_obj(struct dcn201_opp); if (!opp) { return NULL; @@ -680,7 +680,7 @@ static struct dce_aux *dcn201_aux_engine_create(struct dc_context *ctx, uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -713,7 +713,7 @@ static struct dce_i2c_hw *dcn201_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -726,7 +726,7 @@ static struct dce_i2c_hw *dcn201_i2c_hw_create(struct dc_context *ctx, static struct mpc *dcn201_mpc_create(struct dc_context *ctx, uint32_t num_mpcc) { - struct dcn201_mpc *mpc201 = kzalloc(sizeof(struct dcn201_mpc), GFP_KERNEL); + struct dcn201_mpc *mpc201 = kzalloc_obj(struct dcn201_mpc); if (!mpc201) return NULL; @@ -742,7 +742,7 @@ static struct mpc *dcn201_mpc_create(struct dc_context *ctx, uint32_t num_mpcc) static struct hubbub *dcn201_hubbub_create(struct dc_context *ctx) { - struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL); + struct dcn20_hubbub *hubbub = kzalloc_obj(struct dcn20_hubbub); if (!hubbub) return NULL; @@ -760,7 +760,7 @@ static struct timing_generator *dcn201_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -794,7 +794,7 @@ static struct link_encoder *dcn201_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); struct dcn10_link_encoder *enc10; if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -822,7 +822,7 @@ static struct clock_source *dcn201_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -857,7 +857,7 @@ static struct stream_encoder *dcn201_stream_encoder_create( struct dc_context *ctx) { struct dcn10_stream_encoder *enc1 = - kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn10_stream_encoder); if (!enc1) return NULL; @@ -884,7 +884,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dcn201_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -984,7 +984,7 @@ static struct hubp *dcn201_hubp_create( uint32_t inst) { struct dcn201_hubp *hubp201 = - kzalloc(sizeof(struct dcn201_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn201_hubp); if (!hubp201) return NULL; @@ -1305,7 +1305,7 @@ struct resource_pool *dcn201_create_resource_pool( struct dc *dc) { struct dcn201_resource_pool *pool = - kzalloc(sizeof(struct dcn201_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn201_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c index 967e813a45e5..0f4307f8f3dd 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn21/dcn21_resource.c @@ -57,7 +57,7 @@ #include "dce/dce_clock_source.h" #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn20/dcn20_dccg.h" #include "dcn21/dcn21_dccg.h" @@ -484,7 +484,7 @@ static struct input_pixel_processor *dcn21_ipp_create( struct dc_context *ctx, uint32_t inst) { struct dcn10_ipp *ipp = - kzalloc(sizeof(struct dcn10_ipp), GFP_KERNEL); + kzalloc_obj(struct dcn10_ipp); if (!ipp) { BREAK_TO_DEBUGGER(); @@ -501,7 +501,7 @@ static struct dpp *dcn21_dpp_create( uint32_t inst) { struct dcn20_dpp *dpp = - kzalloc(sizeof(struct dcn20_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn20_dpp); if (!dpp) return NULL; @@ -520,7 +520,7 @@ static struct dce_aux *dcn21_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -557,7 +557,7 @@ static struct dce_i2c_hw *dcn21_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -930,7 +930,8 @@ static enum dc_status dcn21_validate_bandwidth(struct dc *dc, struct dc_state *c bool voltage_supported; display_e2e_pipe_params_st *pipes; - pipes = kcalloc(dc->res_pool->pipe_count, sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); if (!pipes) return DC_FAIL_BANDWIDTH_VALIDATE; @@ -959,7 +960,7 @@ static struct clock_source *dcn21_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -980,7 +981,7 @@ static struct hubp *dcn21_hubp_create( uint32_t inst) { struct dcn21_hubp *hubp21 = - kzalloc(sizeof(struct dcn21_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn21_hubp); if (!hubp21) return NULL; @@ -998,8 +999,7 @@ static struct hubbub *dcn21_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub = kzalloc_obj(struct dcn20_hubbub); if (!hubbub) return NULL; @@ -1027,7 +1027,7 @@ static struct output_pixel_processor *dcn21_opp_create(struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -1043,7 +1043,7 @@ static struct timing_generator *dcn21_timing_generator_create(struct dc_context uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1062,8 +1062,7 @@ static struct timing_generator *dcn21_timing_generator_create(struct dc_context static struct mpc *dcn21_mpc_create(struct dc_context *ctx) { - struct dcn20_mpc *mpc20 = kzalloc(sizeof(struct dcn20_mpc), - GFP_KERNEL); + struct dcn20_mpc *mpc20 = kzalloc_obj(struct dcn20_mpc); if (!mpc20) return NULL; @@ -1091,7 +1090,7 @@ static struct display_stream_compressor *dcn21_dsc_create(struct dc_context *ctx uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1104,7 +1103,7 @@ static struct display_stream_compressor *dcn21_dsc_create(struct dc_context *ctx static struct pp_smu_funcs *dcn21_pp_smu_create(struct dc_context *ctx) { - struct pp_smu_funcs *pp_smu = kzalloc(sizeof(*pp_smu), GFP_KERNEL); + struct pp_smu_funcs *pp_smu = kzalloc_obj(*pp_smu); if (!pp_smu) return pp_smu; @@ -1141,7 +1140,7 @@ static struct stream_encoder *dcn21_stream_encoder_create(enum engine_id eng_id, struct dc_context *ctx) { struct dcn10_stream_encoder *enc1 = - kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn10_stream_encoder); if (!enc1) return NULL; @@ -1168,7 +1167,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dcn21_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1295,7 +1294,7 @@ static struct link_encoder *dcn21_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn21_link_encoder *enc21 = - kzalloc(sizeof(struct dcn21_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn21_link_encoder); int link_regs_id; if (!enc21 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) @@ -1319,7 +1318,7 @@ static struct link_encoder *dcn21_link_encoder_create( static struct panel_cntl *dcn21_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -1704,7 +1703,7 @@ struct resource_pool *dcn21_create_resource_pool( struct dc *dc) { struct dcn21_resource_pool *pool = - kzalloc(sizeof(struct dcn21_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn21_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c index d0ebb733e802..2fa86b9587ed 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn30/dcn30_resource.c @@ -55,7 +55,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn30/dcn30_dccg.h" @@ -753,7 +753,7 @@ static struct dpp *dcn30_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -771,7 +771,7 @@ static struct output_pixel_processor *dcn30_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -788,7 +788,7 @@ static struct dce_aux *dcn30_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -827,7 +827,7 @@ static struct dce_i2c_hw *dcn30_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -843,8 +843,7 @@ static struct mpc *dcn30_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -863,8 +862,7 @@ static struct hubbub *dcn30_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -893,7 +891,7 @@ static struct timing_generator *dcn30_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -927,7 +925,7 @@ static struct link_encoder *dcn30_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -947,7 +945,7 @@ static struct link_encoder *dcn30_link_encoder_create( static struct panel_cntl *dcn30_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dce_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -981,7 +979,7 @@ static struct vpg *dcn30_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -998,7 +996,7 @@ static struct afmt *dcn30_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -1027,7 +1025,7 @@ static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id, } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn30_vpg_create(ctx, vpg_inst); afmt = dcn30_afmt_create(ctx, afmt_inst); @@ -1048,7 +1046,7 @@ static struct stream_encoder *dcn30_stream_encoder_create(enum engine_id eng_id, static struct dce_hwseq *dcn30_hwseq_create(struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1201,7 +1199,7 @@ static struct hubp *dcn30_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1221,8 +1219,7 @@ static bool dcn30_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1246,8 +1243,7 @@ static bool dcn30_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1269,7 +1265,7 @@ static struct display_stream_compressor *dcn30_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1303,7 +1299,7 @@ static struct clock_source *dcn30_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2048,8 +2044,8 @@ enum dc_status dcn30_validate_bandwidth(struct dc *dc, int vlevel = 0; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kcalloc(dc->res_pool->pipe_count, - sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); DC_LOGGER_INIT(dc->ctx->logger); BW_VAL_TRACE_COUNT(); @@ -2622,7 +2618,7 @@ struct resource_pool *dcn30_create_resource_pool( struct dc *dc) { struct dcn30_resource_pool *pool = - kzalloc(sizeof(struct dcn30_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn30_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c index 3ad6a3d4858e..7842bee57e63 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn301/dcn301_resource.c @@ -54,7 +54,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn301/dcn301_dccg.h" @@ -717,7 +717,7 @@ static void dcn301_dpp_destroy(struct dpp **dpp) static struct dpp *dcn301_dpp_create(struct dc_context *ctx, uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -734,7 +734,7 @@ static struct output_pixel_processor *dcn301_opp_create(struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -749,7 +749,7 @@ static struct output_pixel_processor *dcn301_opp_create(struct dc_context *ctx, static struct dce_aux *dcn301_aux_engine_create(struct dc_context *ctx, uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -783,7 +783,7 @@ static const struct dce_i2c_mask i2c_masks = { static struct dce_i2c_hw *dcn301_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -798,8 +798,7 @@ static struct mpc *dcn301_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -818,8 +817,7 @@ static struct hubbub *dcn301_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -849,7 +847,7 @@ static struct timing_generator *dcn301_timing_generator_create( struct dc_context *ctx, uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -883,7 +881,7 @@ static struct link_encoder *dcn301_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -903,7 +901,7 @@ static struct link_encoder *dcn301_link_encoder_create( static struct panel_cntl *dcn301_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn301_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn301_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn301_panel_cntl); if (!panel_cntl) return NULL; @@ -952,7 +950,7 @@ static struct vpg *dcn301_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -969,7 +967,7 @@ static struct afmt *dcn301_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -998,7 +996,7 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn301_vpg_create(ctx, vpg_inst); afmt = dcn301_afmt_create(ctx, afmt_inst); @@ -1019,7 +1017,7 @@ static struct stream_encoder *dcn301_stream_encoder_create(enum engine_id eng_id static struct dce_hwseq *dcn301_hwseq_create(struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1161,7 +1159,7 @@ static void dcn301_destruct(struct dcn301_resource_pool *pool) static struct hubp *dcn301_hubp_create(struct dc_context *ctx, uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1181,8 +1179,7 @@ static bool dcn301_dwbc_create(struct dc_context *ctx, struct resource_pool *poo uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1206,8 +1203,7 @@ static bool dcn301_mmhubbub_create(struct dc_context *ctx, struct resource_pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1229,7 +1225,7 @@ static struct display_stream_compressor *dcn301_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1258,7 +1254,7 @@ static struct clock_source *dcn301_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -1728,7 +1724,7 @@ struct resource_pool *dcn301_create_resource_pool( struct dc *dc) { struct dcn301_resource_pool *pool = - kzalloc(sizeof(struct dcn301_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn301_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c index c0d4a1dc94f8..1874d5d6b782 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn302/dcn302_resource.c @@ -257,7 +257,7 @@ static struct hubbub *dcn302_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -299,7 +299,7 @@ static const struct dcn30_vpg_mask vpg_mask = { static struct vpg *dcn302_vpg_create(struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -331,7 +331,7 @@ static const struct dcn30_afmt_mask afmt_mask = { static struct afmt *dcn302_afmt_create(struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -406,7 +406,7 @@ static struct stream_encoder *dcn302_stream_encoder_create(enum engine_id eng_id } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn302_vpg_create(ctx, vpg_inst); afmt = dcn302_afmt_create(ctx, afmt_inst); @@ -445,7 +445,7 @@ static const struct dce110_clk_src_mask cs_mask = { static struct clock_source *dcn302_clock_source_create(struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, const struct dce110_clk_src_regs *regs, bool dp_clk_src) { - struct dce110_clk_src *clk_src = kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + struct dce110_clk_src *clk_src = kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -474,7 +474,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dcn302_hwseq_create(struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -506,7 +506,7 @@ static const struct dcn_hubp2_mask hubp_mask = { static struct hubp *dcn302_hubp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_hubp *hubp2 = kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + struct dcn20_hubp *hubp2 = kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -540,7 +540,7 @@ static const struct dcn3_dpp_mask tf_mask = { static struct dpp *dcn302_dpp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + struct dcn3_dpp *dpp = kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -574,7 +574,7 @@ static const struct dcn20_opp_mask opp_mask = { static struct output_pixel_processor *dcn302_opp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + struct dcn20_opp *opp = kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -606,7 +606,7 @@ static const struct dcn_optc_mask optc_mask = { static struct timing_generator *dcn302_timing_generator_create(struct dc_context *ctx, uint32_t instance) { - struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL); + struct optc *tgn10 = kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -651,7 +651,7 @@ static const struct dcn30_mpc_mask mpc_mask = { static struct mpc *dcn302_mpc_create(struct dc_context *ctx, int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -682,7 +682,7 @@ static const struct dcn20_dsc_mask dsc_mask = { static struct display_stream_compressor *dcn302_dsc_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_dsc *dsc = kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + struct dcn20_dsc *dsc = kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -714,7 +714,7 @@ static bool dcn302_dwbc_create(struct dc_context *ctx, struct resource_pool *poo uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -749,7 +749,7 @@ static bool dcn302_mmhubbub_create(struct dc_context *ctx, struct resource_pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -789,7 +789,7 @@ static const struct dce110_aux_registers_mask aux_mask = { static struct dce_aux *dcn302_aux_engine_create(struct dc_context *ctx, uint32_t inst) { - struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + struct aux_engine_dce110 *aux_engine = kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -820,7 +820,7 @@ static const struct dce_i2c_mask i2c_masks = { static struct dce_i2c_hw *dcn302_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { - struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + struct dce_i2c_hw *dce_i2c_hw = kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -894,7 +894,7 @@ static struct link_encoder *dcn302_link_encoder_create( struct dc_context *ctx, const struct encoder_init_data *enc_init_data) { - struct dcn20_link_encoder *enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + struct dcn20_link_encoder *enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -920,7 +920,7 @@ static const struct dce_panel_cntl_mask panel_cntl_mask = { static struct panel_cntl *dcn302_panel_cntl_create(const struct panel_cntl_init_data *init_data) { - struct dce_panel_cntl *panel_cntl = kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + struct dce_panel_cntl *panel_cntl = kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -1512,7 +1512,7 @@ static bool dcn302_resource_construct( struct resource_pool *dcn302_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc) { - struct resource_pool *pool = kzalloc(sizeof(struct resource_pool), GFP_KERNEL); + struct resource_pool *pool = kzalloc_obj(struct resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c index 75e09c2c283e..d52201cb359f 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn303/dcn303_resource.c @@ -253,7 +253,7 @@ static struct hubbub *dcn303_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -292,7 +292,7 @@ static const struct dcn30_vpg_mask vpg_mask = { static struct vpg *dcn303_vpg_create(struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -321,7 +321,7 @@ static const struct dcn30_afmt_mask afmt_mask = { static struct afmt *dcn303_afmt_create(struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -393,7 +393,7 @@ static struct stream_encoder *dcn303_stream_encoder_create(enum engine_id eng_id } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn303_vpg_create(ctx, vpg_inst); afmt = dcn303_afmt_create(ctx, afmt_inst); @@ -429,7 +429,7 @@ static const struct dce110_clk_src_mask cs_mask = { static struct clock_source *dcn303_clock_source_create(struct dc_context *ctx, struct dc_bios *bios, enum clock_source_id id, const struct dce110_clk_src_regs *regs, bool dp_clk_src) { - struct dce110_clk_src *clk_src = kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + struct dce110_clk_src *clk_src = kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -458,7 +458,7 @@ static const struct dce_hwseq_mask hwseq_mask = { static struct dce_hwseq *dcn303_hwseq_create(struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -487,7 +487,7 @@ static const struct dcn_hubp2_mask hubp_mask = { static struct hubp *dcn303_hubp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_hubp *hubp2 = kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + struct dcn20_hubp *hubp2 = kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -518,7 +518,7 @@ static const struct dcn3_dpp_mask tf_mask = { static struct dpp *dcn303_dpp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + struct dcn3_dpp *dpp = kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -549,7 +549,7 @@ static const struct dcn20_opp_mask opp_mask = { static struct output_pixel_processor *dcn303_opp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_opp *opp = kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + struct dcn20_opp *opp = kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -578,7 +578,7 @@ static const struct dcn_optc_mask optc_mask = { static struct timing_generator *dcn303_timing_generator_create(struct dc_context *ctx, uint32_t instance) { - struct optc *tgn10 = kzalloc(sizeof(struct optc), GFP_KERNEL); + struct optc *tgn10 = kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -615,7 +615,7 @@ static const struct dcn30_mpc_mask mpc_mask = { static struct mpc *dcn303_mpc_create(struct dc_context *ctx, int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -643,7 +643,7 @@ static const struct dcn20_dsc_mask dsc_mask = { static struct display_stream_compressor *dcn303_dsc_create(struct dc_context *ctx, uint32_t inst) { - struct dcn20_dsc *dsc = kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + struct dcn20_dsc *dsc = kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -675,7 +675,7 @@ static bool dcn303_dwbc_create(struct dc_context *ctx, struct resource_pool *poo uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -710,7 +710,7 @@ static bool dcn303_mmhubbub_create(struct dc_context *ctx, struct resource_pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -747,7 +747,7 @@ static const struct dce110_aux_registers_mask aux_mask = { static struct dce_aux *dcn303_aux_engine_create(struct dc_context *ctx, uint32_t inst) { - struct aux_engine_dce110 *aux_engine = kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + struct aux_engine_dce110 *aux_engine = kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -775,7 +775,7 @@ static const struct dce_i2c_mask i2c_masks = { static struct dce_i2c_hw *dcn303_i2c_hw_create(struct dc_context *ctx, uint32_t inst) { - struct dce_i2c_hw *dce_i2c_hw = kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + struct dce_i2c_hw *dce_i2c_hw = kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -839,7 +839,7 @@ static struct link_encoder *dcn303_link_encoder_create( struct dc_context *ctx, const struct encoder_init_data *enc_init_data) { - struct dcn20_link_encoder *enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + struct dcn20_link_encoder *enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -865,7 +865,7 @@ static const struct dce_panel_cntl_mask panel_cntl_mask = { static struct panel_cntl *dcn303_panel_cntl_create(const struct panel_cntl_init_data *init_data) { - struct dce_panel_cntl *panel_cntl = kzalloc(sizeof(struct dce_panel_cntl), GFP_KERNEL); + struct dce_panel_cntl *panel_cntl = kzalloc_obj(struct dce_panel_cntl); if (!panel_cntl) return NULL; @@ -1444,7 +1444,7 @@ static bool dcn303_resource_construct( struct resource_pool *dcn303_create_resource_pool(const struct dc_init_data *init_data, struct dc *dc) { - struct resource_pool *pool = kzalloc(sizeof(struct resource_pool), GFP_KERNEL); + struct resource_pool *pool = kzalloc_obj(struct resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c index e853ea110310..2055f1f8af65 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -64,7 +64,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" @@ -919,7 +919,7 @@ static struct dpp *dcn31_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -937,7 +937,7 @@ static struct output_pixel_processor *dcn31_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -954,7 +954,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -991,7 +991,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -1006,8 +1006,7 @@ static struct mpc *dcn31_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -1026,8 +1025,7 @@ static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1059,7 +1057,7 @@ static struct timing_generator *dcn31_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1093,7 +1091,7 @@ static struct link_encoder *dcn31_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1122,7 +1120,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1139,7 +1137,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1169,7 +1167,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1186,7 +1184,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1205,7 +1203,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1235,7 +1233,7 @@ static struct stream_encoder *dcn31_stream_encoder_create( } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1285,7 +1283,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1311,7 +1309,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1325,7 +1323,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn31_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1499,7 +1497,7 @@ static struct hubp *dcn31_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1519,8 +1517,7 @@ static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1544,8 +1541,7 @@ static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1567,7 +1563,7 @@ static struct display_stream_compressor *dcn31_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1595,7 +1591,7 @@ static struct clock_source *dcn31_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -1771,8 +1767,8 @@ enum dc_status dcn31_validate_bandwidth(struct dc *dc, int vlevel = 0; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kcalloc(dc->res_pool->pipe_count, - sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); DC_LOGGER_INIT(dc->ctx->logger); BW_VAL_TRACE_COUNT(); @@ -1866,7 +1862,7 @@ static struct clock_source *dcn30_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2227,7 +2223,7 @@ struct resource_pool *dcn31_create_resource_pool( struct dc *dc) { struct dcn31_resource_pool *pool = - kzalloc(sizeof(struct dcn31_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn31_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c index 3ccde75a4ecb..1939f720ba29 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c @@ -66,7 +66,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" @@ -955,7 +955,7 @@ static struct dpp *dcn31_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -973,7 +973,7 @@ static struct output_pixel_processor *dcn31_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -990,7 +990,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -1049,7 +1049,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -1064,8 +1064,7 @@ static struct mpc *dcn31_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -1084,8 +1083,7 @@ static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1117,7 +1115,7 @@ static struct timing_generator *dcn31_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1151,7 +1149,7 @@ static struct link_encoder *dcn31_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1180,7 +1178,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1197,7 +1195,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1227,7 +1225,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1244,7 +1242,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1263,7 +1261,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1293,7 +1291,7 @@ static struct stream_encoder *dcn314_stream_encoder_create( } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1344,7 +1342,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1370,7 +1368,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1384,7 +1382,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn314_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1557,7 +1555,7 @@ static struct hubp *dcn31_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1577,8 +1575,7 @@ static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1602,8 +1599,7 @@ static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1625,7 +1621,7 @@ static struct display_stream_compressor *dcn314_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1653,7 +1649,7 @@ static struct clock_source *dcn31_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -1709,8 +1705,8 @@ enum dc_status dcn314_validate_bandwidth(struct dc *dc, int vlevel = 0; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kcalloc(dc->res_pool->pipe_count, - sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); DC_LOGGER_INIT(dc->ctx->logger); BW_VAL_TRACE_COUNT(); @@ -1797,7 +1793,7 @@ static struct clock_source *dcn30_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2145,7 +2141,7 @@ struct resource_pool *dcn314_create_resource_pool( struct dc *dc) { struct dcn314_resource_pool *pool = - kzalloc(sizeof(struct dcn314_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn314_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c index 4e962f522f1b..e8377c190f63 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn315/dcn315_resource.c @@ -63,7 +63,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" @@ -918,7 +918,7 @@ static struct dpp *dcn31_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -936,7 +936,7 @@ static struct output_pixel_processor *dcn31_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -953,7 +953,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -990,7 +990,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -1005,8 +1005,7 @@ static struct mpc *dcn31_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -1025,8 +1024,7 @@ static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1058,7 +1056,7 @@ static struct timing_generator *dcn31_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1092,7 +1090,7 @@ static struct link_encoder *dcn31_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1121,7 +1119,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1138,7 +1136,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1168,7 +1166,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1185,7 +1183,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1204,7 +1202,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1230,13 +1228,13 @@ static struct stream_encoder *dcn315_stream_encoder_create( /*PHYB is wired off in HW, allow front end to remapping, otherwise needs more changes*/ /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1286,7 +1284,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1312,7 +1310,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1326,7 +1324,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn31_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1500,7 +1498,7 @@ static struct hubp *dcn31_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1520,8 +1518,7 @@ static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1545,8 +1542,7 @@ static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1568,7 +1564,7 @@ static struct display_stream_compressor *dcn31_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1596,7 +1592,7 @@ static struct clock_source *dcn31_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2167,7 +2163,7 @@ struct resource_pool *dcn315_create_resource_pool( struct dc *dc) { struct dcn315_resource_pool *pool = - kzalloc(sizeof(struct dcn315_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn315_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c index 5a95dd54cb42..045ce01bd74e 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn316/dcn316_resource.c @@ -63,7 +63,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dml/dcn31/dcn31_fpu.h" @@ -911,7 +911,7 @@ static struct dpp *dcn31_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp) return NULL; @@ -929,7 +929,7 @@ static struct output_pixel_processor *dcn31_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -946,7 +946,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -983,7 +983,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -998,8 +998,7 @@ static struct mpc *dcn31_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -1018,8 +1017,7 @@ static struct hubbub *dcn31_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1051,7 +1049,7 @@ static struct timing_generator *dcn31_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1085,7 +1083,7 @@ static struct link_encoder *dcn31_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1114,7 +1112,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1131,7 +1129,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1161,7 +1159,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1178,7 +1176,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1198,7 +1196,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1223,13 +1221,13 @@ static struct stream_encoder *dcn316_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1280,7 +1278,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1306,7 +1304,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1321,7 +1319,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn31_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); if (hws) { hws->ctx = ctx; @@ -1492,7 +1490,7 @@ static struct hubp *dcn31_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1512,8 +1510,7 @@ static bool dcn31_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1537,8 +1534,7 @@ static bool dcn31_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1560,7 +1556,7 @@ static struct display_stream_compressor *dcn31_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1588,7 +1584,7 @@ static struct clock_source *dcn31_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2034,7 +2030,7 @@ struct resource_pool *dcn316_create_resource_pool( struct dc *dc) { struct dcn316_resource_pool *pool = - kzalloc(sizeof(struct dcn316_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn316_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c index b276fec3e479..7ebb7d1193af 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn32/dcn32_resource.c @@ -65,7 +65,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn32/dcn32_dccg.h" #include "dcn10/dcn10_resource.h" @@ -750,7 +750,7 @@ static struct dce_aux *dcn32_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -790,7 +790,7 @@ static struct dce_i2c_hw *dcn32_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -817,7 +817,7 @@ static struct clock_source *dcn32_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -837,8 +837,7 @@ static struct hubbub *dcn32_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub2 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub2) return NULL; @@ -893,7 +892,7 @@ static struct hubp *dcn32_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -925,7 +924,7 @@ static struct dpp *dcn32_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp3 = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp3) return NULL; @@ -951,8 +950,7 @@ static struct mpc *dcn32_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -975,7 +973,7 @@ static struct output_pixel_processor *dcn32_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp2 = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp2) { BREAK_TO_DEBUGGER(); @@ -1000,7 +998,7 @@ static struct timing_generator *dcn32_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1041,7 +1039,7 @@ static struct link_encoder *dcn32_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1085,7 +1083,7 @@ static struct link_encoder *dcn32_link_encoder_create( struct panel_cntl *dcn32_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1124,7 +1122,7 @@ static struct vpg *dcn32_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -1154,7 +1152,7 @@ static struct afmt *dcn32_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -1180,7 +1178,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1211,13 +1209,13 @@ static struct stream_encoder *dcn32_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn32_vpg_create(ctx, vpg_inst); afmt = dcn32_afmt_create(ctx, afmt_inst); @@ -1275,7 +1273,7 @@ static struct hpo_dp_stream_encoder *dcn32_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn32_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1308,7 +1306,7 @@ static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1327,7 +1325,7 @@ static struct hpo_dp_link_encoder *dcn32_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn32_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1510,8 +1508,7 @@ static bool dcn32_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1539,8 +1536,7 @@ static bool dcn32_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1566,7 +1562,7 @@ static struct display_stream_compressor *dcn32_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1754,8 +1750,8 @@ static bool dml1_validate(struct dc *dc, struct dc_state *context, enum dc_valid int vlevel = 0; int pipe_cnt = 0; - display_e2e_pipe_params_st *pipes = kcalloc(dc->res_pool->pipe_count, - sizeof(display_e2e_pipe_params_st), GFP_KERNEL); + display_e2e_pipe_params_st *pipes = kzalloc_objs(display_e2e_pipe_params_st, + dc->res_pool->pipe_count); /* To handle Freesync properly, setting FreeSync DML parameters * to its default state for the first stage of validation @@ -2571,7 +2567,7 @@ struct resource_pool *dcn32_create_resource_pool( struct dc *dc) { struct dcn32_resource_pool *pool = - kzalloc(sizeof(struct dcn32_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn32_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c index 3466ca34c93f..c1582c27ac87 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn321/dcn321_resource.c @@ -68,7 +68,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn32/dcn32_dccg.h" #include "dcn10/dcn10_resource.h" @@ -744,7 +744,7 @@ static struct dce_aux *dcn321_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -784,7 +784,7 @@ static struct dce_i2c_hw *dcn321_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -811,7 +811,7 @@ static struct clock_source *dcn321_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -831,8 +831,7 @@ static struct hubbub *dcn321_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub2 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub2) return NULL; @@ -887,7 +886,7 @@ static struct hubp *dcn321_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -919,7 +918,7 @@ static struct dpp *dcn321_dpp_create( uint32_t inst) { struct dcn3_dpp *dpp3 = - kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn3_dpp); if (!dpp3) return NULL; @@ -945,8 +944,7 @@ static struct mpc *dcn321_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), - GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -969,7 +967,7 @@ static struct output_pixel_processor *dcn321_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp2 = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp2) { BREAK_TO_DEBUGGER(); @@ -994,7 +992,7 @@ static struct timing_generator *dcn321_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1035,7 +1033,7 @@ static struct link_encoder *dcn321_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1105,7 +1103,7 @@ static struct vpg *dcn321_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_vpg *vpg3 = kzalloc(sizeof(struct dcn30_vpg), GFP_KERNEL); + struct dcn30_vpg *vpg3 = kzalloc_obj(struct dcn30_vpg); if (!vpg3) return NULL; @@ -1135,7 +1133,7 @@ static struct afmt *dcn321_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt3 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt3 = kzalloc_obj(struct dcn30_afmt); if (!afmt3) return NULL; @@ -1161,7 +1159,7 @@ static struct apg *dcn321_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1192,13 +1190,13 @@ static struct stream_encoder *dcn321_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn321_vpg_create(ctx, vpg_inst); afmt = dcn321_afmt_create(ctx, afmt_inst); @@ -1256,7 +1254,7 @@ static struct hpo_dp_stream_encoder *dcn321_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn321_vpg_create(ctx, vpg_inst); apg = dcn321_apg_create(ctx, apg_inst); @@ -1289,7 +1287,7 @@ static struct hpo_dp_link_encoder *dcn321_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1308,7 +1306,7 @@ static struct hpo_dp_link_encoder *dcn321_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn321_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1490,8 +1488,7 @@ static bool dcn321_dwbc_create(struct dc_context *ctx, struct resource_pool *poo uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1519,8 +1516,7 @@ static bool dcn321_mmhubbub_create(struct dc_context *ctx, struct resource_pool uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1546,7 +1542,7 @@ static struct display_stream_compressor *dcn321_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -2064,7 +2060,7 @@ struct resource_pool *dcn321_create_resource_pool( struct dc *dc) { struct dcn321_resource_pool *pool = - kzalloc(sizeof(struct dcn321_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn321_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c index 45454a097264..3494a40cea99 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -70,7 +70,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" @@ -810,7 +810,7 @@ static void dcn35_dpp_destroy(struct dpp **dpp) static struct dpp *dcn35_dpp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + struct dcn3_dpp *dpp = kzalloc_obj(struct dcn3_dpp); bool success = (dpp != NULL); if (!success) @@ -841,7 +841,7 @@ static struct output_pixel_processor *dcn35_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -868,7 +868,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -931,7 +931,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -954,7 +954,7 @@ static struct mpc *dcn35_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -977,8 +977,7 @@ static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1033,7 +1032,7 @@ static struct timing_generator *dcn35_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1074,7 +1073,7 @@ static struct link_encoder *dcn35_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1127,7 +1126,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1144,7 +1143,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1185,7 +1184,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1215,7 +1214,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1243,7 +1242,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1274,13 +1273,13 @@ static struct stream_encoder *dcn35_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1338,7 +1337,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1371,7 +1370,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1390,7 +1389,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn35_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1571,7 +1570,7 @@ static struct hubp *dcn35_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1604,8 +1603,7 @@ static bool dcn35_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1643,8 +1641,7 @@ static bool dcn35_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1672,7 +1669,7 @@ static struct display_stream_compressor *dcn35_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1709,7 +1706,7 @@ static struct clock_source *dcn35_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2209,7 +2206,7 @@ struct resource_pool *dcn35_create_resource_pool( struct dc *dc) { struct dcn35_resource_pool *pool = - kzalloc(sizeof(struct dcn35_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn35_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c index e3c587165807..080bc7f24ffa 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -49,7 +49,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" @@ -790,7 +790,7 @@ static void dcn35_dpp_destroy(struct dpp **dpp) static struct dpp *dcn35_dpp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + struct dcn3_dpp *dpp = kzalloc_obj(struct dcn3_dpp); bool success = (dpp != NULL); if (!success) @@ -821,7 +821,7 @@ static struct output_pixel_processor *dcn35_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -848,7 +848,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -911,7 +911,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -934,7 +934,7 @@ static struct mpc *dcn35_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -957,8 +957,7 @@ static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1013,7 +1012,7 @@ static struct timing_generator *dcn35_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1054,7 +1053,7 @@ static struct link_encoder *dcn35_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1107,7 +1106,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1124,7 +1123,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1165,7 +1164,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1195,7 +1194,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1223,7 +1222,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1254,13 +1253,13 @@ static struct stream_encoder *dcn35_stream_encoder_create( int afmt_inst; /* Mapping of VPG, AFMT, DME register blocks to DIO block instance */ - if (eng_id <= ENGINE_ID_DIGF) { - vpg_inst = eng_id; - afmt_inst = eng_id; - } else + if (eng_id < 0 || eng_id >= ARRAY_SIZE(stream_enc_regs)) return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + vpg_inst = eng_id; + afmt_inst = eng_id; + + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1318,7 +1317,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1351,7 +1350,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1370,7 +1369,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn351_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1551,7 +1550,7 @@ static struct hubp *dcn35_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1584,8 +1583,7 @@ static bool dcn35_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1623,8 +1621,7 @@ static bool dcn35_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1652,7 +1649,7 @@ static struct display_stream_compressor *dcn35_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1689,7 +1686,7 @@ static struct clock_source *dcn35_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2182,7 +2179,7 @@ struct resource_pool *dcn351_create_resource_pool( struct dc *dc) { struct dcn351_resource_pool *pool = - kzalloc(sizeof(struct dcn351_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn351_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c index 6469d5fe2e6d..af51ac4ea59e 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c @@ -49,7 +49,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dce110/dce110_resource.h" #include "dml/display_mode_vba.h" #include "dcn35/dcn35_dccg.h" @@ -460,16 +460,22 @@ static const struct dcn30_mpc_mask mpc_mask = { }; #define optc_regs_init(id)\ - OPTC_COMMON_REG_LIST_DCN3_5_RI(id) + OPTC_COMMON_REG_LIST_DCN3_5_RI(id),\ + SRI_ARR(OTG_CRC0_DATA_R32, OTG_CRC32, id),\ + SRI_ARR(OTG_CRC0_DATA_G32, OTG_CRC32, id),\ + SRI_ARR(OTG_CRC0_DATA_B32, OTG_CRC32, id),\ + SRI_ARR(OTG_CRC1_DATA_R32, OTG_CRC32, id),\ + SRI_ARR(OTG_CRC1_DATA_G32, OTG_CRC32, id),\ + SRI_ARR(OTG_CRC1_DATA_B32, OTG_CRC32, id) static struct dcn_optc_registers optc_regs[4]; static const struct dcn_optc_shift optc_shift = { - OPTC_COMMON_MASK_SH_LIST_DCN3_5(__SHIFT) + OPTC_COMMON_MASK_SH_LIST_DCN3_6(__SHIFT) }; static const struct dcn_optc_mask optc_mask = { - OPTC_COMMON_MASK_SH_LIST_DCN3_5(_MASK) + OPTC_COMMON_MASK_SH_LIST_DCN3_6(_MASK) }; #define hubp_regs_init(id)\ @@ -769,7 +775,7 @@ static const struct dc_debug_options debug_defaults_drv = { }; static const struct dc_check_config config_defaults = { - .enable_legacy_fast_update = true, + .enable_legacy_fast_update = false, }; static const struct dc_panel_config panel_config_defaults = { @@ -791,7 +797,7 @@ static void dcn35_dpp_destroy(struct dpp **dpp) static struct dpp *dcn35_dpp_create(struct dc_context *ctx, uint32_t inst) { - struct dcn3_dpp *dpp = kzalloc(sizeof(struct dcn3_dpp), GFP_KERNEL); + struct dcn3_dpp *dpp = kzalloc_obj(struct dcn3_dpp); bool success = (dpp != NULL); if (!success) @@ -822,7 +828,7 @@ static struct output_pixel_processor *dcn35_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp) { BREAK_TO_DEBUGGER(); @@ -849,7 +855,7 @@ static struct dce_aux *dcn31_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -912,7 +918,7 @@ static struct dce_i2c_hw *dcn31_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -935,7 +941,7 @@ static struct mpc *dcn35_mpc_create( int num_mpcc, int num_rmu) { - struct dcn30_mpc *mpc30 = kzalloc(sizeof(struct dcn30_mpc), GFP_KERNEL); + struct dcn30_mpc *mpc30 = kzalloc_obj(struct dcn30_mpc); if (!mpc30) return NULL; @@ -958,8 +964,7 @@ static struct hubbub *dcn35_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub3 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub3 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub3) return NULL; @@ -1014,7 +1019,7 @@ static struct timing_generator *dcn35_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1055,7 +1060,7 @@ static struct link_encoder *dcn35_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1108,7 +1113,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( if ((eng_id - ENGINE_ID_DIGA) > ctx->dc->res_pool->res_cap->num_dig_link_enc) return NULL; - enc20 = kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + enc20 = kzalloc_obj(struct dcn20_link_encoder); if (!enc20) return NULL; @@ -1125,7 +1130,7 @@ static struct link_encoder *dcn31_link_enc_create_minimal( static struct panel_cntl *dcn31_panel_cntl_create(const struct panel_cntl_init_data *init_data) { struct dcn31_panel_cntl *panel_cntl = - kzalloc(sizeof(struct dcn31_panel_cntl), GFP_KERNEL); + kzalloc_obj(struct dcn31_panel_cntl); if (!panel_cntl) return NULL; @@ -1166,7 +1171,7 @@ static struct vpg *dcn31_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg31 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg31 = kzalloc_obj(struct dcn31_vpg); if (!vpg31) return NULL; @@ -1196,7 +1201,7 @@ static struct afmt *dcn31_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_afmt *afmt31 = kzalloc(sizeof(struct dcn31_afmt), GFP_KERNEL); + struct dcn31_afmt *afmt31 = kzalloc_obj(struct dcn31_afmt); if (!afmt31) return NULL; @@ -1224,7 +1229,7 @@ static struct apg *dcn31_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1261,7 +1266,7 @@ static struct stream_encoder *dcn35_stream_encoder_create( } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); afmt = dcn31_afmt_create(ctx, afmt_inst); @@ -1319,7 +1324,7 @@ static struct hpo_dp_stream_encoder *dcn31_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn31_vpg_create(ctx, vpg_inst); apg = dcn31_apg_create(ctx, apg_inst); @@ -1352,7 +1357,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1371,7 +1376,7 @@ static struct hpo_dp_link_encoder *dcn31_hpo_dp_link_encoder_create( static struct dce_hwseq *dcn36_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1552,7 +1557,7 @@ static struct hubp *dcn35_hubp_create( uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -1585,8 +1590,7 @@ static bool dcn35_dwbc_create(struct dc_context *ctx, struct resource_pool *pool uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_dwbc *dwbc30 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc30 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc30) { dm_error("DC: failed to create dwbc30!\n"); @@ -1624,8 +1628,7 @@ static bool dcn35_mmhubbub_create(struct dc_context *ctx, struct resource_pool * uint32_t pipe_count = pool->res_cap->num_dwb; for (i = 0; i < pipe_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1653,7 +1656,7 @@ static struct display_stream_compressor *dcn35_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_dsc *dsc = - kzalloc(sizeof(struct dcn20_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn20_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -1690,7 +1693,7 @@ static struct clock_source *dcn35_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -2182,7 +2185,7 @@ struct resource_pool *dcn36_create_resource_pool( struct dc *dc) { struct dcn36_resource_pool *pool = - kzalloc(sizeof(struct dcn36_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn36_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c index 1cdbb65da4a3..e37aab939a41 100644 --- a/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn401/dcn401_resource.c @@ -21,6 +21,7 @@ #include "dcn401/dcn401_hubbub.h" #include "dcn401/dcn401_mpc.h" #include "dcn401/dcn401_hubp.h" +#include "dio/dcn10/dcn10_dio.h" #include "irq/dcn401/irq_service_dcn401.h" #include "dcn401/dcn401_dpp.h" #include "dcn401/dcn401_optc.h" @@ -46,7 +47,7 @@ #include "dce/dce_audio.h" #include "dce/dce_hwseq.h" #include "clk_mgr.h" -#include "virtual/virtual_stream_encoder.h" +#include "dio/virtual/virtual_stream_encoder.h" #include "dml/display_mode_vba.h" #include "dcn401/dcn401_dccg.h" #include "dcn10/dcn10_resource.h" @@ -634,6 +635,22 @@ static const struct dcn20_vmid_mask vmid_masks = { DCN20_VMID_MASK_SH_LIST(_MASK) }; +#define dio_regs_init() \ + DIO_REG_LIST_DCN10() + +static struct dcn_dio_registers dio_regs; + +#define DIO_MASK_SH_LIST_DCN401(mask_sh)\ + HWS_SF(, DIO_MEM_PWR_CTRL, I2C_LIGHT_SLEEP_FORCE, mask_sh) + +static const struct dcn_dio_shift dio_shift = { + DIO_MASK_SH_LIST_DCN401(__SHIFT) +}; + +static const struct dcn_dio_mask dio_mask = { + DIO_MASK_SH_LIST_DCN401(_MASK) +}; + static const struct resource_caps res_cap_dcn4_01 = { .num_timing_generator = 4, .num_opp = 4, @@ -745,7 +762,7 @@ static struct dce_aux *dcn401_aux_engine_create( uint32_t inst) { struct aux_engine_dce110 *aux_engine = - kzalloc(sizeof(struct aux_engine_dce110), GFP_KERNEL); + kzalloc_obj(struct aux_engine_dce110); if (!aux_engine) return NULL; @@ -784,7 +801,7 @@ static struct dce_i2c_hw *dcn401_i2c_hw_create( uint32_t inst) { struct dce_i2c_hw *dce_i2c_hw = - kzalloc(sizeof(struct dce_i2c_hw), GFP_KERNEL); + kzalloc_obj(struct dce_i2c_hw); if (!dce_i2c_hw) return NULL; @@ -810,7 +827,7 @@ static struct clock_source *dcn401_clock_source_create( bool dp_clk_src) { struct dce110_clk_src *clk_src = - kzalloc(sizeof(struct dce110_clk_src), GFP_KERNEL); + kzalloc_obj(struct dce110_clk_src); if (!clk_src) return NULL; @@ -830,8 +847,7 @@ static struct hubbub *dcn401_hubbub_create(struct dc_context *ctx) { int i; - struct dcn20_hubbub *hubbub2 = kzalloc(sizeof(struct dcn20_hubbub), - GFP_KERNEL); + struct dcn20_hubbub *hubbub2 = kzalloc_obj(struct dcn20_hubbub); if (!hubbub2) return NULL; @@ -881,12 +897,28 @@ static struct hubbub *dcn401_hubbub_create(struct dc_context *ctx) return &hubbub2->base; } +static struct dio *dcn401_dio_create(struct dc_context *ctx) +{ + struct dcn10_dio *dio10 = kzalloc_obj(struct dcn10_dio); + + if (!dio10) + return NULL; + +#undef REG_STRUCT +#define REG_STRUCT dio_regs + dio_regs_init(); + + dcn10_dio_construct(dio10, ctx, &dio_regs, &dio_shift, &dio_mask); + + return &dio10->base; +} + static struct hubp *dcn401_hubp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_hubp *hubp2 = - kzalloc(sizeof(struct dcn20_hubp), GFP_KERNEL); + kzalloc_obj(struct dcn20_hubp); if (!hubp2) return NULL; @@ -918,7 +950,7 @@ static struct dpp *dcn401_dpp_create( uint32_t inst) { struct dcn401_dpp *dpp401 = - kzalloc(sizeof(struct dcn401_dpp), GFP_KERNEL); + kzalloc_obj(struct dcn401_dpp); if (!dpp401) return NULL; @@ -944,8 +976,7 @@ static struct mpc *dcn401_mpc_create( int num_mpcc, int num_rmu) { - struct dcn401_mpc *mpc401 = kzalloc(sizeof(struct dcn401_mpc), - GFP_KERNEL); + struct dcn401_mpc *mpc401 = kzalloc_obj(struct dcn401_mpc); if (!mpc401) return NULL; @@ -968,7 +999,7 @@ static struct output_pixel_processor *dcn401_opp_create( struct dc_context *ctx, uint32_t inst) { struct dcn20_opp *opp4 = - kzalloc(sizeof(struct dcn20_opp), GFP_KERNEL); + kzalloc_obj(struct dcn20_opp); if (!opp4) { BREAK_TO_DEBUGGER(); @@ -993,7 +1024,7 @@ static struct timing_generator *dcn401_timing_generator_create( uint32_t instance) { struct optc *tgn10 = - kzalloc(sizeof(struct optc), GFP_KERNEL); + kzalloc_obj(struct optc); if (!tgn10) return NULL; @@ -1033,7 +1064,7 @@ static struct link_encoder *dcn401_link_encoder_create( const struct encoder_init_data *enc_init_data) { struct dcn20_link_encoder *enc20 = - kzalloc(sizeof(struct dcn20_link_encoder), GFP_KERNEL); + kzalloc_obj(struct dcn20_link_encoder); if (!enc20 || enc_init_data->hpd_source >= ARRAY_SIZE(link_enc_hpd_regs)) return NULL; @@ -1098,7 +1129,7 @@ static struct vpg *dcn401_vpg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_vpg *vpg4 = kzalloc(sizeof(struct dcn31_vpg), GFP_KERNEL); + struct dcn31_vpg *vpg4 = kzalloc_obj(struct dcn31_vpg); if (!vpg4) return NULL; @@ -1128,7 +1159,7 @@ static struct afmt *dcn401_afmt_create( struct dc_context *ctx, uint32_t inst) { - struct dcn30_afmt *afmt401 = kzalloc(sizeof(struct dcn30_afmt), GFP_KERNEL); + struct dcn30_afmt *afmt401 = kzalloc_obj(struct dcn30_afmt); if (!afmt401) return NULL; @@ -1153,7 +1184,7 @@ static struct apg *dcn401_apg_create( struct dc_context *ctx, uint32_t inst) { - struct dcn31_apg *apg31 = kzalloc(sizeof(struct dcn31_apg), GFP_KERNEL); + struct dcn31_apg *apg31 = kzalloc_obj(struct dcn31_apg); if (!apg31) return NULL; @@ -1190,7 +1221,7 @@ static struct stream_encoder *dcn401_stream_encoder_create( } else return NULL; - enc1 = kzalloc(sizeof(struct dcn10_stream_encoder), GFP_KERNEL); + enc1 = kzalloc_obj(struct dcn10_stream_encoder); vpg = dcn401_vpg_create(ctx, vpg_inst); afmt = dcn401_afmt_create(ctx, afmt_inst); @@ -1246,7 +1277,7 @@ static struct hpo_dp_stream_encoder *dcn401_hpo_dp_stream_encoder_create( apg_inst = hpo_dp_inst; /* allocate HPO stream encoder and create VPG sub-block */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_stream_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_stream_encoder); vpg = dcn401_vpg_create(ctx, vpg_inst); apg = dcn401_apg_create(ctx, apg_inst); @@ -1279,7 +1310,7 @@ static struct hpo_dp_link_encoder *dcn401_hpo_dp_link_encoder_create( struct dcn31_hpo_dp_link_encoder *hpo_dp_enc31; /* allocate HPO link encoder */ - hpo_dp_enc31 = kzalloc(sizeof(struct dcn31_hpo_dp_link_encoder), GFP_KERNEL); + hpo_dp_enc31 = kzalloc_obj(struct dcn31_hpo_dp_link_encoder); if (!hpo_dp_enc31) return NULL; /* out of memory */ @@ -1323,7 +1354,7 @@ static unsigned int dcn401_calc_num_avail_chans_for_mall(struct dc *dc, unsigned static struct dce_hwseq *dcn401_hwseq_create( struct dc_context *ctx) { - struct dce_hwseq *hws = kzalloc(sizeof(struct dce_hwseq), GFP_KERNEL); + struct dce_hwseq *hws = kzalloc_obj(struct dce_hwseq); #undef REG_STRUCT #define REG_STRUCT hwseq_reg @@ -1499,6 +1530,11 @@ static void dcn401_resource_destruct(struct dcn401_resource_pool *pool) if (pool->base.dccg != NULL) dcn_dccg_destroy(&pool->base.dccg); + if (pool->base.dio != NULL) { + kfree(TO_DCN10_DIO(pool->base.dio)); + pool->base.dio = NULL; + } + if (pool->base.oem_device != NULL) { struct dc *dc = pool->base.oem_device->ctx->dc; @@ -1513,8 +1549,7 @@ static bool dcn401_dwbc_create(struct dc_context *ctx, struct resource_pool *poo uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_dwbc *dwbc401 = kzalloc(sizeof(struct dcn30_dwbc), - GFP_KERNEL); + struct dcn30_dwbc *dwbc401 = kzalloc_obj(struct dcn30_dwbc); if (!dwbc401) { dm_error("DC: failed to create dwbc401!\n"); @@ -1544,8 +1579,7 @@ static bool dcn401_mmhubbub_create(struct dc_context *ctx, struct resource_pool uint32_t dwb_count = pool->res_cap->num_dwb; for (i = 0; i < dwb_count; i++) { - struct dcn30_mmhubbub *mcif_wb30 = kzalloc(sizeof(struct dcn30_mmhubbub), - GFP_KERNEL); + struct dcn30_mmhubbub *mcif_wb30 = kzalloc_obj(struct dcn30_mmhubbub); if (!mcif_wb30) { dm_error("DC: failed to create mcif_wb30!\n"); @@ -1571,7 +1605,7 @@ static struct display_stream_compressor *dcn401_dsc_create( struct dc_context *ctx, uint32_t inst) { struct dcn401_dsc *dsc = - kzalloc(sizeof(struct dcn401_dsc), GFP_KERNEL); + kzalloc_obj(struct dcn401_dsc); if (!dsc) { BREAK_TO_DEBUGGER(); @@ -2071,6 +2105,14 @@ static bool dcn401_resource_construct( goto create_fail; } + /* DIO */ + pool->base.dio = dcn401_dio_create(ctx); + if (pool->base.dio == NULL) { + BREAK_TO_DEBUGGER(); + dm_error("DC: failed to create dio!\n"); + goto create_fail; + } + /* HUBPs, DPPs, OPPs, TGs, ABMs */ for (i = 0, j = 0; i < pool->base.res_cap->num_timing_generator; i++) { @@ -2268,7 +2310,7 @@ struct resource_pool *dcn401_create_resource_pool( struct dc *dc) { struct dcn401_resource_pool *pool = - kzalloc(sizeof(struct dcn401_resource_pool), GFP_KERNEL); + kzalloc_obj(struct dcn401_resource_pool); if (!pool) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c index 0fc0e5a6c171..6617c9d2d5f8 100644 --- a/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c +++ b/drivers/gpu/drm/amd/display/dc/soc_and_ip_translator/soc_and_ip_translator.c @@ -21,7 +21,7 @@ struct soc_and_ip_translator *dc_create_soc_and_ip_translator(enum dce_version d { struct soc_and_ip_translator *soc_and_ip_translator; - soc_and_ip_translator = kzalloc(sizeof(*soc_and_ip_translator), GFP_KERNEL); + soc_and_ip_translator = kzalloc_obj(*soc_and_ip_translator); if (!soc_and_ip_translator) return NULL; diff --git a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c index 1d9edb89e47a..a75ab23b0726 100644 --- a/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c +++ b/drivers/gpu/drm/amd/display/dc/sspl/dc_spl_isharp_filters.c @@ -293,7 +293,7 @@ static const uint16_t filter_isharp_bs_3tap_64p_s1_12[99] = { }; /* Pre-generated 1DLUT for given setup and sharpness level */ -struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = { +static struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = { { 0, 0, { @@ -332,7 +332,7 @@ struct isharp_1D_lut_pregen filter_isharp_1D_lut_pregen[NUM_SHARPNESS_SETUPS] = }, }; -struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { +static struct scale_ratio_to_sharpness_level_adj sharpness_level_adj[NUM_SHARPNESS_ADJ_LEVELS] = { {1125, 1000, 0}, {11, 10, 1}, {1075, 1000, 2}, diff --git a/drivers/gpu/drm/amd/display/dc/virtual/Makefile b/drivers/gpu/drm/amd/display/dc/virtual/Makefile deleted file mode 100644 index 931facd4dab5..000000000000 --- a/drivers/gpu/drm/amd/display/dc/virtual/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright 2017 Advanced Micro Devices, Inc. -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR -# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -# -# -# Makefile for the virtual sub-component of DAL. -# It provides the control and status of HW CRTC block. - -VIRTUAL = virtual_link_encoder.o virtual_stream_encoder.o virtual_link_hwss.o - -AMD_DAL_VIRTUAL = $(addprefix $(AMDDALPATH)/dc/virtual/,$(VIRTUAL)) - -AMD_DISPLAY_FILES += $(AMD_DAL_VIRTUAL) diff --git a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h index 18e0bdfd6ff4..6f388c910e18 100644 --- a/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h +++ b/drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h @@ -736,6 +736,16 @@ union pr_hw_flags { uint32_t u32All; }; +/** + * Definition of Panel Replay ML Activity Options + */ +enum pr_ml_activity_option { + OPTION_DEFAULT = 0x00, // VESA Option Default (1C) + OPTION_1A = 0x01, // VESA Option 1A + OPTION_1B = 0x02, // VESA Option 1B + OPTION_1C = 0x03, // VESA Option 1C +}; + union fw_assisted_mclk_switch_version { struct { uint8_t minor : 5; @@ -1628,6 +1638,11 @@ enum dmub_gpint_command { * DESC: Initiates IPS wake sequence. */ DMUB_GPINT__IPS_DEBUG_WAKE = 137, + /** + * DESC: Do panel power off sequence + * ARGS: 1 - Power off + */ + DMUB_GPINT__PANEL_POWER_OFF_SEQ = 138, }; /** @@ -4398,6 +4413,7 @@ enum dmub_cmd_panel_replay_type { enum dmub_cmd_panel_replay_state_update_subtype { PR_STATE_UPDATE_COASTING_VTOTAL = 0x1, PR_STATE_UPDATE_SYNC_MODE = 0x2, + PR_STATE_UPDATE_RUNTIME_FLAGS = 0x3, }; enum dmub_cmd_panel_replay_general_subtype { @@ -6691,6 +6707,13 @@ struct dmub_rb_cmd_pr_copy_settings { struct dmub_cmd_pr_copy_settings_data data; }; +union dmub_pr_runtime_flags { + struct { + uint32_t disable_abm_optimization : 1; // Disable ABM optimization for PR + } bitfields; + uint32_t u32All; +}; + struct dmub_cmd_pr_update_state_data { /** * Panel Instance. @@ -6709,6 +6732,8 @@ struct dmub_cmd_pr_update_state_data { */ uint32_t coasting_vtotal; uint32_t sync_mode; + + union dmub_pr_runtime_flags pr_runtime_flags; }; struct dmub_cmd_pr_general_cmd_data { diff --git a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c index a71df052cf25..2639163b8ba2 100644 --- a/drivers/gpu/drm/amd/display/modules/color/color_gamma.c +++ b/drivers/gpu/drm/amd/display/modules/color/color_gamma.c @@ -933,7 +933,7 @@ static bool build_regamma(struct pwl_float_data_ex *rgb_regamma, struct pwl_float_data_ex *rgb = rgb_regamma; const struct hw_x_point *coord_x = coordinate_x; - coeff = kvzalloc(sizeof(*coeff), GFP_KERNEL); + coeff = kvzalloc_obj(*coeff); if (!coeff) goto release; @@ -1714,14 +1714,13 @@ bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, input_tf->type = TF_TYPE_DISTRIBUTED_POINTS; if (map_user_ramp && ramp && ramp->type == GAMMA_RGB_256) { - rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, - sizeof(*rgb_user), - GFP_KERNEL); + rgb_user = kvzalloc_objs(*rgb_user, + ramp->num_entries + _EXTRA_POINTS); if (!rgb_user) goto rgb_user_alloc_fail; - axis_x = kvcalloc(ramp->num_entries + _EXTRA_POINTS, sizeof(*axis_x), - GFP_KERNEL); + axis_x = kvzalloc_objs(*axis_x, + ramp->num_entries + _EXTRA_POINTS); if (!axis_x) goto axis_x_alloc_fail; @@ -1737,13 +1736,11 @@ bool mod_color_calculate_degamma_params(struct dc_color_caps *dc_caps, scale_gamma(rgb_user, ramp, dividers); } - curve = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*curve), - GFP_KERNEL); + curve = kvzalloc_objs(*curve, MAX_HW_POINTS + _EXTRA_POINTS); if (!curve) goto curve_alloc_fail; - coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff), - GFP_KERNEL); + coeff = kvzalloc_objs(*coeff, MAX_HW_POINTS + _EXTRA_POINTS); if (!coeff) goto coeff_alloc_fail; @@ -1940,14 +1937,12 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, if (ramp && ramp->type != GAMMA_CS_TFM_1D && (map_user_ramp || ramp->type != GAMMA_RGB_256)) { - rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS, - sizeof(*rgb_user), - GFP_KERNEL); + rgb_user = kvzalloc_objs(*rgb_user, + ramp->num_entries + _EXTRA_POINTS); if (!rgb_user) goto rgb_user_alloc_fail; - axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x), - GFP_KERNEL); + axis_x = kvzalloc_objs(*axis_x, ramp->num_entries + 3); if (!axis_x) goto axis_x_alloc_fail; @@ -1966,14 +1961,11 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf, scale_gamma_dx(rgb_user, ramp, dividers); } - rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, - sizeof(*rgb_regamma), - GFP_KERNEL); + rgb_regamma = kvzalloc_objs(*rgb_regamma, MAX_HW_POINTS + _EXTRA_POINTS); if (!rgb_regamma) goto rgb_regamma_alloc_fail; - coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff), - GFP_KERNEL); + coeff = kvzalloc_objs(*coeff, MAX_HW_POINTS + _EXTRA_POINTS); if (!coeff) goto coeff_alloc_fail; diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c index 1aae46d703ba..19de72173052 100644 --- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c +++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c @@ -61,7 +61,7 @@ struct core_freesync { struct mod_freesync *mod_freesync_create(struct dc *dc) { struct core_freesync *core_freesync = - kzalloc(sizeof(struct core_freesync), GFP_KERNEL); + kzalloc_obj(struct core_freesync); if (core_freesync == NULL) goto fail_alloc_context; diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c index 2c40212d86da..9f408cb11ac9 100644 --- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c +++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c @@ -144,7 +144,7 @@ struct mod_vmid *mod_vmid_create( if (dc == NULL) goto fail_dc_null; - core_vmid = kzalloc(sizeof(struct core_vmid), GFP_KERNEL); + core_vmid = kzalloc_obj(struct core_vmid); if (core_vmid == NULL) goto fail_alloc_context; diff --git a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h index 0e4c195297a4..fe97943b9b97 100644 --- a/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h +++ b/drivers/gpu/drm/amd/include/asic_reg/mp/mp_15_0_0_offset.h @@ -82,6 +82,24 @@ #define regMPASP_SMN_IH_SW_INT_CTRL 0x0142 #define regMPASP_SMN_IH_SW_INT_CTRL_BASE_IDX 0 +// addressBlock: mp_SmuMpASPPub_PcruDec +// base address: 0x3800000 +#define regMPASP_PCRU1_MPASP_C2PMSG_64 0x4280 +#define regMPASP_PCRU1_MPASP_C2PMSG_64_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_65 0x4281 +#define regMPASP_PCRU1_MPASP_C2PMSG_65_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_66 0x4282 +#define regMPASP_PCRU1_MPASP_C2PMSG_66_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_67 0x4283 +#define regMPASP_PCRU1_MPASP_C2PMSG_67_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_68 0x4284 +#define regMPASP_PCRU1_MPASP_C2PMSG_68_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_69 0x4285 +#define regMPASP_PCRU1_MPASP_C2PMSG_69_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_70 0x4286 +#define regMPASP_PCRU1_MPASP_C2PMSG_70_BASE_IDX 3 +#define regMPASP_PCRU1_MPASP_C2PMSG_71 0x4287 +#define regMPASP_PCRU1_MPASP_C2PMSG_71_BASE_IDX 3 // addressBlock: mp_SmuMp1_SmnDec // base address: 0x0 diff --git a/drivers/gpu/drm/amd/include/kgd_pp_interface.h b/drivers/gpu/drm/amd/include/kgd_pp_interface.h index 9fd78fcff15c..6683ffd6aa68 100644 --- a/drivers/gpu/drm/amd/include/kgd_pp_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_pp_interface.h @@ -1829,4 +1829,9 @@ struct amdgpu_partition_metrics_v1_1 { struct gpu_metrics_attr metrics_attrs[]; }; +enum amdgpu_xgmi_link_status { + AMDGPU_XGMI_LINK_INACTIVE = 0, + AMDGPU_XGMI_LINK_ACTIVE = 1, +}; + #endif diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c index 07641c9413d2..eca93a9d0b84 100644 --- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c @@ -243,11 +243,11 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev, enum amd_pm_state_type state; int ret; - if (strncmp("battery", buf, strlen("battery")) == 0) + if (sysfs_streq(buf, "battery")) state = POWER_STATE_TYPE_BATTERY; - else if (strncmp("balanced", buf, strlen("balanced")) == 0) + else if (sysfs_streq(buf, "balanced")) state = POWER_STATE_TYPE_BALANCED; - else if (strncmp("performance", buf, strlen("performance")) == 0) + else if (sysfs_streq(buf, "performance")) state = POWER_STATE_TYPE_PERFORMANCE; else return -EINVAL; @@ -363,29 +363,28 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev, enum amd_dpm_forced_level level; int ret = 0; - if (strncmp("low", buf, strlen("low")) == 0) { + if (sysfs_streq(buf, "low")) level = AMD_DPM_FORCED_LEVEL_LOW; - } else if (strncmp("high", buf, strlen("high")) == 0) { + else if (sysfs_streq(buf, "high")) level = AMD_DPM_FORCED_LEVEL_HIGH; - } else if (strncmp("auto", buf, strlen("auto")) == 0) { + else if (sysfs_streq(buf, "auto")) level = AMD_DPM_FORCED_LEVEL_AUTO; - } else if (strncmp("manual", buf, strlen("manual")) == 0) { + else if (sysfs_streq(buf, "manual")) level = AMD_DPM_FORCED_LEVEL_MANUAL; - } else if (strncmp("profile_exit", buf, strlen("profile_exit")) == 0) { + else if (sysfs_streq(buf, "profile_exit")) level = AMD_DPM_FORCED_LEVEL_PROFILE_EXIT; - } else if (strncmp("profile_standard", buf, strlen("profile_standard")) == 0) { + else if (sysfs_streq(buf, "profile_standard")) level = AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD; - } else if (strncmp("profile_min_sclk", buf, strlen("profile_min_sclk")) == 0) { + else if (sysfs_streq(buf, "profile_min_sclk")) level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK; - } else if (strncmp("profile_min_mclk", buf, strlen("profile_min_mclk")) == 0) { + else if (sysfs_streq(buf, "profile_min_mclk")) level = AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK; - } else if (strncmp("profile_peak", buf, strlen("profile_peak")) == 0) { + else if (sysfs_streq(buf, "profile_peak")) level = AMD_DPM_FORCED_LEVEL_PROFILE_PEAK; - } else if (strncmp("perf_determinism", buf, strlen("perf_determinism")) == 0) { + else if (sysfs_streq(buf, "perf_determinism")) level = AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM; - } else { + else return -EINVAL; - } ret = amdgpu_pm_get_access(adev); if (ret < 0) @@ -2747,7 +2746,7 @@ static int amdgpu_device_attr_create(struct amdgpu_device *adev, name, ret); } - attr_entry = kmalloc(sizeof(*attr_entry), GFP_KERNEL); + attr_entry = kmalloc_obj(*attr_entry); if (!attr_entry) return -ENOMEM; @@ -4593,7 +4592,7 @@ static int amdgpu_od_set_init(struct amdgpu_device *adev) int ret; /* Setup the top `gpu_od` directory which holds all other OD interfaces */ - top_set = kzalloc(sizeof(*top_set), GFP_KERNEL); + top_set = kzalloc_obj(*top_set); if (!top_set) return -ENOMEM; list_add(&top_set->entry, &adev->pm.od_kobj_list); @@ -4630,7 +4629,7 @@ static int amdgpu_od_set_init(struct amdgpu_device *adev) * The container is presented as a plain file under top `gpu_od` * directory. */ - attribute = kzalloc(sizeof(*attribute), GFP_KERNEL); + attribute = kzalloc_obj(*attribute); if (!attribute) { ret = -ENOMEM; goto err_out; @@ -4650,7 +4649,7 @@ static int amdgpu_od_set_init(struct amdgpu_device *adev) goto err_out; } else { /* The container is presented as a sub directory. */ - sub_set = kzalloc(sizeof(*sub_set), GFP_KERNEL); + sub_set = kzalloc_obj(*sub_set); if (!sub_set) { ret = -ENOMEM; goto err_out; @@ -4680,7 +4679,7 @@ static int amdgpu_od_set_init(struct amdgpu_device *adev) * With the container presented as a sub directory, the entry within * it is presented as a plain file under the sub directory. */ - attribute = kzalloc(sizeof(*attribute), GFP_KERNEL); + attribute = kzalloc_obj(*attribute); if (!attribute) { ret = -ENOMEM; goto err_out; diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c index 33eb85dd68e9..cdf3f8e6ec2f 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/kv_dpm.c @@ -2724,9 +2724,8 @@ static int kv_parse_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct amdgpu_ps), - GFP_KERNEL); + adev->pm.dpm.ps = kzalloc_objs(struct amdgpu_ps, + state_array->ucNumEntries); if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -2736,7 +2735,7 @@ static int kv_parse_power_table(struct amdgpu_device *adev) non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); + ps = kzalloc_obj(struct kv_ps); if (ps == NULL) return -ENOMEM; adev->pm.dpm.ps[i].ps_priv = ps; @@ -2783,7 +2782,7 @@ static int kv_dpm_init(struct amdgpu_device *adev) struct kv_power_info *pi; int ret, i; - pi = kzalloc(sizeof(struct kv_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct kv_power_info); if (pi == NULL) return -ENOMEM; adev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c index c7ed0b457129..6362a14b1a6e 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/legacy_dpm.c @@ -302,9 +302,8 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) ATOM_PPLIB_PhaseSheddingLimits_Record *entry; adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries = - kcalloc(psl->ucNumEntries, - sizeof(struct amdgpu_phase_shedding_limits_entry), - GFP_KERNEL); + kzalloc_objs(struct amdgpu_phase_shedding_limits_entry, + psl->ucNumEntries); if (!adev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) return -ENOMEM; @@ -503,7 +502,7 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(ext_hdr->usPPMTableOffset)); adev->pm.dpm.dyn_state.ppm_table = - kzalloc(sizeof(struct amdgpu_ppm_table), GFP_KERNEL); + kzalloc_obj(struct amdgpu_ppm_table); if (!adev->pm.dpm.dyn_state.ppm_table) return -ENOMEM; adev->pm.dpm.dyn_state.ppm_table->ppm_design = ppm->ucPpmDesign; @@ -557,7 +556,7 @@ int amdgpu_parse_extended_power_table(struct amdgpu_device *adev) le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); ATOM_PowerTune_Table *pt; adev->pm.dpm.dyn_state.cac_tdp_table = - kzalloc(sizeof(struct amdgpu_cac_tdp_table), GFP_KERNEL); + kzalloc_obj(struct amdgpu_cac_tdp_table); if (!adev->pm.dpm.dyn_state.cac_tdp_table) return -ENOMEM; if (rev > 0) { diff --git a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c index 0f8f69481f5b..61b1c5aa74cb 100644 --- a/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +++ b/drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c @@ -2586,7 +2586,7 @@ static int si_initialize_smc_dte_tables(struct amdgpu_device *adev) if (dte_data->k <= 0) return -EINVAL; - dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL); + dte_tables = kzalloc_obj(Smc_SIslands_DTE_Configuration); if (dte_tables == NULL) { si_pi->enable_dte = false; return -ENOMEM; @@ -2767,7 +2767,7 @@ static int si_initialize_smc_cac_tables(struct amdgpu_device *adev) if (ni_pi->enable_cac == false) return 0; - cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL); + cac_tables = kzalloc_obj(PP_SIslands_CacConfig); if (!cac_tables) return -ENOMEM; @@ -2964,7 +2964,7 @@ static int si_init_smc_spll_table(struct amdgpu_device *adev) if (si_pi->spll_table_start == 0) return -EINVAL; - spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL); + spll_table = kzalloc_obj(SMC_SISLANDS_SPLL_DIV_TABLE); if (spll_table == NULL) return -ENOMEM; @@ -3464,6 +3464,11 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, max_sclk = 60000; max_mclk = 80000; } + if ((adev->pdev->device == 0x666f) && + (adev->pdev->revision == 0x00)) { + max_sclk = 80000; + max_mclk = 95000; + } } else if (adev->asic_type == CHIP_OLAND) { if ((adev->pdev->revision == 0xC7) || (adev->pdev->revision == 0x80) || @@ -6049,7 +6054,7 @@ static int si_initialize_mc_reg_table(struct amdgpu_device *adev) u8 module_index = rv770_get_memory_module_index(adev); int ret; - table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(struct atom_mc_reg_table); if (!table) return -ENOMEM; @@ -7336,9 +7341,8 @@ static int si_parse_power_table(struct amdgpu_device *adev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - adev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct amdgpu_ps), - GFP_KERNEL); + adev->pm.dpm.ps = kzalloc_objs(struct amdgpu_ps, + state_array->ucNumEntries); if (!adev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -7348,7 +7352,7 @@ static int si_parse_power_table(struct amdgpu_device *adev) non_clock_array_index = power_state->v2.nonClockInfoIndex; non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; - ps = kzalloc(sizeof(struct si_ps), GFP_KERNEL); + ps = kzalloc_obj(struct si_ps); if (ps == NULL) return -ENOMEM; adev->pm.dpm.ps[i].ps_priv = ps; @@ -7401,7 +7405,7 @@ static int si_dpm_init(struct amdgpu_device *adev) struct atom_clock_dividers dividers; int ret; - si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); + si_pi = kzalloc_obj(struct si_power_info); if (si_pi == NULL) return -ENOMEM; adev->pm.dpm.priv = si_pi; @@ -7438,9 +7442,7 @@ static int si_dpm_init(struct amdgpu_device *adev) return ret; adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kcalloc(4, - sizeof(struct amdgpu_clock_voltage_dependency_entry), - GFP_KERNEL); + kzalloc_objs(struct amdgpu_clock_voltage_dependency_entry, 4); if (!adev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c index 0bbb89788335..e558b81b25c9 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c +++ b/drivers/gpu/drm/amd/pm/powerplay/amd_powerplay.c @@ -41,7 +41,7 @@ static int amd_powerplay_create(struct amdgpu_device *adev) if (adev == NULL) return -EINVAL; - hwmgr = kzalloc(sizeof(struct pp_hwmgr), GFP_KERNEL); + hwmgr = kzalloc_obj(struct pp_hwmgr); if (hwmgr == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c index 6cfef1b295ab..6fcca65bd7d4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/process_pptables_v1_0.c @@ -165,7 +165,7 @@ static int get_vddc_lookup_table( PP_ASSERT_WITH_CODE((0 != vddc_lookup_pp_tables->ucNumEntries), "Invalid CAC Leakage PowerPlay Table!", return 1); - table = kzalloc(struct_size(table, entries, max_levels), GFP_KERNEL); + table = kzalloc_flex(*table, entries, max_levels); if (!table) return -ENOMEM; @@ -200,7 +200,7 @@ static int get_platform_power_management_table( struct pp_hwmgr *hwmgr, ATOM_Tonga_PPM_Table *atom_ppm_table) { - struct phm_ppm_table *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + struct phm_ppm_table *ptr = kzalloc_obj(*ptr); struct phm_ppt_v1_information *pp_table_information = (struct phm_ppt_v1_information *)(hwmgr->pptable); @@ -321,8 +321,7 @@ static int get_valid_clk( PP_ASSERT_WITH_CODE((0 != clk_volt_pp_table->count), "Invalid PowerPlay Table!", return -1); - table = kzalloc(struct_size(table, values, clk_volt_pp_table->count), - GFP_KERNEL); + table = kzalloc_flex(*table, values, clk_volt_pp_table->count); if (!table) return -ENOMEM; @@ -371,8 +370,8 @@ static int get_mclk_voltage_dependency_table( PP_ASSERT_WITH_CODE((0 != mclk_dep_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); - mclk_table = kzalloc(struct_size(mclk_table, entries, mclk_dep_table->ucNumEntries), - GFP_KERNEL); + mclk_table = kzalloc_flex(*mclk_table, entries, + mclk_dep_table->ucNumEntries); if (!mclk_table) return -ENOMEM; @@ -415,8 +414,8 @@ static int get_sclk_voltage_dependency_table( PP_ASSERT_WITH_CODE((0 != tonga_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); - sclk_table = kzalloc(struct_size(sclk_table, entries, tonga_table->ucNumEntries), - GFP_KERNEL); + sclk_table = kzalloc_flex(*sclk_table, entries, + tonga_table->ucNumEntries); if (!sclk_table) return -ENOMEM; @@ -444,8 +443,8 @@ static int get_sclk_voltage_dependency_table( PP_ASSERT_WITH_CODE((0 != polaris_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); - sclk_table = kzalloc(struct_size(sclk_table, entries, polaris_table->ucNumEntries), - GFP_KERNEL); + sclk_table = kzalloc_flex(*sclk_table, entries, + polaris_table->ucNumEntries); if (!sclk_table) return -ENOMEM; @@ -491,9 +490,8 @@ static int get_pcie_table( PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); - pcie_table = kzalloc(struct_size(pcie_table, entries, - atom_pcie_table->ucNumEntries), - GFP_KERNEL); + pcie_table = kzalloc_flex(*pcie_table, entries, + atom_pcie_table->ucNumEntries); if (!pcie_table) return -ENOMEM; @@ -528,9 +526,8 @@ static int get_pcie_table( PP_ASSERT_WITH_CODE((atom_pcie_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); - pcie_table = kzalloc(struct_size(pcie_table, entries, - atom_pcie_table->ucNumEntries), - GFP_KERNEL); + pcie_table = kzalloc_flex(*pcie_table, entries, + atom_pcie_table->ucNumEntries); if (!pcie_table) return -ENOMEM; @@ -724,8 +721,8 @@ static int get_mm_clock_voltage_table( PP_ASSERT_WITH_CODE((0 != mm_dependency_table->ucNumEntries), "Invalid PowerPlay Table!", return -1); - mm_table = kzalloc(struct_size(mm_table, entries, mm_dependency_table->ucNumEntries), - GFP_KERNEL); + mm_table = kzalloc_flex(*mm_table, entries, + mm_dependency_table->ucNumEntries); if (!mm_table) return -ENOMEM; @@ -1141,7 +1138,7 @@ static int pp_tables_v1_0_initialize(struct pp_hwmgr *hwmgr) int result = 0; const ATOM_Tonga_POWERPLAYTABLE *powerplay_table; - hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v1_information), GFP_KERNEL); + hwmgr->pptable = kzalloc_obj(struct phm_ppt_v1_information); PP_ASSERT_WITH_CODE((NULL != hwmgr->pptable), "Failed to allocate hwmgr->pptable!", return -ENOMEM); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c index f06b29e33ba4..59af3314ffc4 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/processpptables.c @@ -382,8 +382,7 @@ static int get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_clock_voltage_dependency_table *dep_table; - dep_table = kzalloc(struct_size(dep_table, entries, table->ucNumEntries), - GFP_KERNEL); + dep_table = kzalloc_flex(*dep_table, entries, table->ucNumEntries); if (NULL == dep_table) return -ENOMEM; @@ -409,7 +408,7 @@ static int get_valid_clk(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_clock_array *clock_table; - clock_table = kzalloc(struct_size(clock_table, values, table->count), GFP_KERNEL); + clock_table = kzalloc_flex(*clock_table, values, table->count); if (!clock_table) return -ENOMEM; @@ -1209,8 +1208,7 @@ static int get_uvd_clock_voltage_limit_table(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_uvd_clock_voltage_dependency_table *uvd_table; - uvd_table = kzalloc(struct_size(uvd_table, entries, table->numEntries), - GFP_KERNEL); + uvd_table = kzalloc_flex(*uvd_table, entries, table->numEntries); if (!uvd_table) return -ENOMEM; @@ -1239,8 +1237,7 @@ static int get_vce_clock_voltage_limit_table(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_vce_clock_voltage_dependency_table *vce_table; - vce_table = kzalloc(struct_size(vce_table, entries, table->numEntries), - GFP_KERNEL); + vce_table = kzalloc_flex(*vce_table, entries, table->numEntries); if (!vce_table) return -ENOMEM; @@ -1267,8 +1264,7 @@ static int get_samu_clock_voltage_limit_table(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_samu_clock_voltage_dependency_table *samu_table; - samu_table = kzalloc(struct_size(samu_table, entries, table->numEntries), - GFP_KERNEL); + samu_table = kzalloc_flex(*samu_table, entries, table->numEntries); if (!samu_table) return -ENOMEM; @@ -1292,8 +1288,7 @@ static int get_acp_clock_voltage_limit_table(struct pp_hwmgr *hwmgr, unsigned long i; struct phm_acp_clock_voltage_dependency_table *acp_table; - acp_table = kzalloc(struct_size(acp_table, entries, table->numEntries), - GFP_KERNEL); + acp_table = kzalloc_flex(*acp_table, entries, table->numEntries); if (!acp_table) return -ENOMEM; @@ -1487,8 +1482,8 @@ static int get_cac_leakage_table(struct pp_hwmgr *hwmgr, if (!hwmgr || !table || !ptable) return -EINVAL; - cac_leakage_table = kzalloc(struct_size(cac_leakage_table, entries, table->ucNumEntries), - GFP_KERNEL); + cac_leakage_table = kzalloc_flex(*cac_leakage_table, entries, + table->ucNumEntries); if (!cac_leakage_table) return -ENOMEM; @@ -1514,7 +1509,7 @@ static int get_cac_leakage_table(struct pp_hwmgr *hwmgr, static int get_platform_power_management_table(struct pp_hwmgr *hwmgr, ATOM_PPLIB_PPM_Table *atom_ppm_table) { - struct phm_ppm_table *ptr = kzalloc(sizeof(struct phm_ppm_table), GFP_KERNEL); + struct phm_ppm_table *ptr = kzalloc_obj(struct phm_ppm_table); if (NULL == ptr) return -ENOMEM; @@ -1625,8 +1620,8 @@ static int init_phase_shedding_table(struct pp_hwmgr *hwmgr, unsigned long i; - table = kzalloc(struct_size(table, entries, ptable->ucNumEntries), - GFP_KERNEL); + table = kzalloc_flex(*table, entries, + ptable->ucNumEntries); if (!table) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c index 8de8d66df95f..2e671b45f174 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu10_hwmgr.c @@ -133,8 +133,7 @@ static int smu10_init_dynamic_state_adjustment_rule_settings( int count = 8; struct phm_clock_voltage_dependency_table *table_clk_vlt; - table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, count), - GFP_KERNEL); + table_clk_vlt = kzalloc_flex(*table_clk_vlt, entries, count); if (NULL == table_clk_vlt) { pr_err("Can not allocate memory!\n"); @@ -473,7 +472,7 @@ static int smu10_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr, uint32_t i; struct smu10_voltage_dependency_table *ptable; - ptable = kzalloc(struct_size(ptable, entries, num_entry), GFP_KERNEL); + ptable = kzalloc_flex(*ptable, entries, num_entry); if (NULL == ptable) return -ENOMEM; @@ -551,7 +550,7 @@ static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) int result = 0; struct smu10_hwmgr *data; - data = kzalloc(sizeof(struct smu10_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct smu10_hwmgr); if (data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c index 2be584aefd0a..e38222877f7e 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu7_hwmgr.c @@ -2961,7 +2961,7 @@ static int smu7_hwmgr_backend_init(struct pp_hwmgr *hwmgr) struct smu7_hwmgr *data; int result = 0; - data = kzalloc(sizeof(struct smu7_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct smu7_hwmgr); if (data == NULL) return -ENOMEM; @@ -4652,7 +4652,7 @@ static const struct amdgpu_irq_src_funcs smu7_irq_funcs = { static int smu7_register_irq_handlers(struct pp_hwmgr *hwmgr) { struct amdgpu_irq_src *source = - kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL); + kzalloc_obj(struct amdgpu_irq_src); if (!source) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c index 736e5a8af477..5ad6ab3d2d37 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu8_hwmgr.c @@ -276,8 +276,7 @@ static int smu8_init_dynamic_state_adjustment_rule_settings( { struct phm_clock_voltage_dependency_table *table_clk_vlt; - table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, 8), - GFP_KERNEL); + table_clk_vlt = kzalloc_flex(*table_clk_vlt, entries, 8); if (NULL == table_clk_vlt) { pr_err("Can not allocate memory!\n"); @@ -1122,7 +1121,7 @@ static int smu8_hwmgr_backend_init(struct pp_hwmgr *hwmgr) int result = 0; struct smu8_hwmgr *data; - data = kzalloc(sizeof(struct smu8_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct smu8_hwmgr); if (data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c index c305ea4ec17d..40ecaac6c604 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/smu_helper.c @@ -211,8 +211,7 @@ int phm_trim_voltage_table(struct pp_atomctrl_voltage_table *vol_table) PP_ASSERT_WITH_CODE((NULL != vol_table), "Voltage Table empty.", return -EINVAL); - table = kzalloc(sizeof(struct pp_atomctrl_voltage_table), - GFP_KERNEL); + table = kzalloc_obj(struct pp_atomctrl_voltage_table); if (NULL == table) return -EINVAL; @@ -496,8 +495,7 @@ int phm_initializa_dynamic_state_adjustment_rule_settings(struct pp_hwmgr *hwmgr struct phm_ppt_v1_information *pptable_info = (struct phm_ppt_v1_information *)(hwmgr->pptable); /* initialize vddc_dep_on_dal_pwrl table */ - table_clk_vlt = kzalloc(struct_size(table_clk_vlt, entries, 4), - GFP_KERNEL); + table_clk_vlt = kzalloc_flex(*table_clk_vlt, entries, 4); if (NULL == table_clk_vlt) { pr_err("Can not allocate space for vddc_dep_on_dal_pwrl! \n"); @@ -646,7 +644,7 @@ static const struct amdgpu_irq_src_funcs smu9_irq_funcs = { int smu9_register_irq_handlers(struct pp_hwmgr *hwmgr) { struct amdgpu_irq_src *source = - kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL); + kzalloc_obj(struct amdgpu_irq_src); if (!source) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c index 1b8a57d98759..d9899cf7020b 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_hwmgr.c @@ -831,7 +831,7 @@ static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr) struct pp_atomfwctrl_voltage_table vol_table; struct amdgpu_device *adev = hwmgr->adev; - data = kzalloc(sizeof(struct vega10_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct vega10_hwmgr); if (data == NULL) return -ENOMEM; @@ -1029,8 +1029,7 @@ static int vega10_trim_voltage_table(struct pp_hwmgr *hwmgr, PP_ASSERT_WITH_CODE(vol_table, "Voltage Table empty.", return -EINVAL); - table = kzalloc(sizeof(struct pp_atomfwctrl_voltage_table), - GFP_KERNEL); + table = kzalloc_obj(struct pp_atomfwctrl_voltage_table); if (!table) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c index 3be616af327e..052d139584fd 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega10_processpptables.c @@ -350,8 +350,8 @@ static int get_mm_clock_voltage_table( PP_ASSERT_WITH_CODE((mm_dependency_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); - mm_table = kzalloc(struct_size(mm_table, entries, mm_dependency_table->ucNumEntries), - GFP_KERNEL); + mm_table = kzalloc_flex(*mm_table, entries, + mm_dependency_table->ucNumEntries); if (!mm_table) return -ENOMEM; @@ -573,8 +573,8 @@ static int get_socclk_voltage_dependency_table( PP_ASSERT_WITH_CODE(clk_dep_table->ucNumEntries, "Invalid PowerPlay Table!", return -1); - clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), - GFP_KERNEL); + clk_table = kzalloc_flex(*clk_table, entries, + clk_dep_table->ucNumEntries); if (!clk_table) return -ENOMEM; @@ -603,8 +603,8 @@ static int get_mclk_voltage_dependency_table( PP_ASSERT_WITH_CODE(mclk_dep_table->ucNumEntries, "Invalid PowerPlay Table!", return -1); - mclk_table = kzalloc(struct_size(mclk_table, entries, mclk_dep_table->ucNumEntries), - GFP_KERNEL); + mclk_table = kzalloc_flex(*mclk_table, entries, + mclk_dep_table->ucNumEntries); if (!mclk_table) return -ENOMEM; @@ -640,8 +640,8 @@ static int get_gfxclk_voltage_dependency_table( PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); - clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), - GFP_KERNEL); + clk_table = kzalloc_flex(*clk_table, entries, + clk_dep_table->ucNumEntries); if (!clk_table) return -ENOMEM; @@ -702,8 +702,8 @@ static int get_pix_clk_voltage_dependency_table( PP_ASSERT_WITH_CODE((clk_dep_table->ucNumEntries != 0), "Invalid PowerPlay Table!", return -1); - clk_table = kzalloc(struct_size(clk_table, entries, clk_dep_table->ucNumEntries), - GFP_KERNEL); + clk_table = kzalloc_flex(*clk_table, entries, + clk_dep_table->ucNumEntries); if (!clk_table) return -ENOMEM; @@ -755,8 +755,7 @@ static int get_dcefclk_voltage_dependency_table( num_entries = clk_dep_table->ucNumEntries; - clk_table = kzalloc(struct_size(clk_table, entries, num_entries), - GFP_KERNEL); + clk_table = kzalloc_flex(*clk_table, entries, num_entries); if (!clk_table) return -ENOMEM; @@ -794,8 +793,8 @@ static int get_pcie_table(struct pp_hwmgr *hwmgr, "Invalid PowerPlay Table!", return 0); - pcie_table = kzalloc(struct_size(pcie_table, entries, atom_pcie_table->ucNumEntries), - GFP_KERNEL); + pcie_table = kzalloc_flex(*pcie_table, entries, + atom_pcie_table->ucNumEntries); if (!pcie_table) return -ENOMEM; @@ -853,8 +852,7 @@ static int get_valid_clk( PP_ASSERT_WITH_CODE(clk_volt_pp_table->count, "Invalid PowerPlay Table!", return -1); - table = kzalloc(struct_size(table, values, clk_volt_pp_table->count), - GFP_KERNEL); + table = kzalloc_flex(*table, values, clk_volt_pp_table->count); if (!table) return -ENOMEM; @@ -1041,7 +1039,7 @@ static int get_vddc_lookup_table( PP_ASSERT_WITH_CODE((vddc_lookup_pp_tables->ucNumEntries != 0), "Invalid SOC_VDDD Lookup Table!", return 1); - table = kzalloc(struct_size(table, entries, max_levels), GFP_KERNEL); + table = kzalloc_flex(*table, entries, max_levels); if (!table) return -ENOMEM; @@ -1149,7 +1147,7 @@ static int vega10_pp_tables_initialize(struct pp_hwmgr *hwmgr) int result = 0; const ATOM_Vega10_POWERPLAYTABLE *powerplay_table; - hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v2_information), GFP_KERNEL); + hwmgr->pptable = kzalloc_obj(struct phm_ppt_v2_information); PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL), "Failed to allocate hwmgr->pptable!", return -ENOMEM); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c index 5a987a535e73..a9a85fd639b2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_hwmgr.c @@ -395,7 +395,7 @@ static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr) struct vega12_hwmgr *data; struct amdgpu_device *adev = hwmgr->adev; - data = kzalloc(sizeof(struct vega12_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct vega12_hwmgr); if (data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c index 89148f73b514..55e13f376039 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega12_processpptables.c @@ -263,7 +263,7 @@ static int vega12_pp_tables_initialize(struct pp_hwmgr *hwmgr) int result = 0; const ATOM_Vega12_POWERPLAYTABLE *powerplay_table; - hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v3_information), GFP_KERNEL); + hwmgr->pptable = kzalloc_obj(struct phm_ppt_v3_information); PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL), "Failed to allocate hwmgr->pptable!", return -ENOMEM); diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c index 5193b7d0e11b..dab9b78a9fc8 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_hwmgr.c @@ -436,7 +436,7 @@ static int vega20_hwmgr_backend_init(struct pp_hwmgr *hwmgr) struct amdgpu_device *adev = hwmgr->adev; int result; - data = kzalloc(sizeof(struct vega20_hwmgr), GFP_KERNEL); + data = kzalloc_obj(struct vega20_hwmgr); if (data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c index 2b446f8866ba..36cb7aa80d07 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c +++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/vega20_processpptables.c @@ -336,7 +336,7 @@ static int vega20_pp_tables_initialize(struct pp_hwmgr *hwmgr) int result = 0; const ATOM_Vega20_POWERPLAYTABLE *powerplay_table; - hwmgr->pptable = kzalloc(sizeof(struct phm_ppt_v3_information), GFP_KERNEL); + hwmgr->pptable = kzalloc_obj(struct phm_ppt_v3_information); PP_ASSERT_WITH_CODE((hwmgr->pptable != NULL), "Failed to allocate hwmgr->pptable!", return -ENOMEM); diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c index ad1fd3150d03..62ebec1c6fe3 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/ci_smumgr.c @@ -2681,7 +2681,7 @@ static int ci_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) struct ci_mc_reg_table *ni_table = &smu_data->mc_reg_table; uint8_t module_index = ci_get_memory_modile_index(hwmgr); - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(pp_atomctrl_mc_reg_table); if (NULL == table) return -ENOMEM; @@ -2735,7 +2735,7 @@ static int ci_smu_init(struct pp_hwmgr *hwmgr) { struct ci_smumgr *ci_priv; - ci_priv = kzalloc(sizeof(struct ci_smumgr), GFP_KERNEL); + ci_priv = kzalloc_obj(struct ci_smumgr); if (ci_priv == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c index 0a876c840c79..7cf389e4717e 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/fiji_smumgr.c @@ -334,7 +334,7 @@ static int fiji_smu_init(struct pp_hwmgr *hwmgr) { struct fiji_smumgr *fiji_priv; - fiji_priv = kzalloc(sizeof(struct fiji_smumgr), GFP_KERNEL); + fiji_priv = kzalloc_obj(struct fiji_smumgr); if (fiji_priv == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c index aa3ae9b115c4..8f1bcbb482b5 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/iceland_smumgr.c @@ -261,7 +261,7 @@ static int iceland_smu_init(struct pp_hwmgr *hwmgr) { struct iceland_smumgr *iceland_priv; - iceland_priv = kzalloc(sizeof(struct iceland_smumgr), GFP_KERNEL); + iceland_priv = kzalloc_obj(struct iceland_smumgr); if (iceland_priv == NULL) return -ENOMEM; @@ -2608,7 +2608,7 @@ static int iceland_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) struct iceland_mc_reg_table *ni_table = &smu_data->mc_reg_table; uint8_t module_index = iceland_get_memory_modile_index(hwmgr); - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(pp_atomctrl_mc_reg_table); if (NULL == table) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c index bf6d09572cfc..e59b87238e76 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/polaris10_smumgr.c @@ -336,7 +336,7 @@ static int polaris10_smu_init(struct pp_hwmgr *hwmgr) { struct polaris10_smumgr *smu_data; - smu_data = kzalloc(sizeof(struct polaris10_smumgr), GFP_KERNEL); + smu_data = kzalloc_obj(struct polaris10_smumgr); if (smu_data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c index 38e19e5cad4d..c9fdca88c96a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu10_smumgr.c @@ -244,7 +244,7 @@ static int smu10_smu_init(struct pp_hwmgr *hwmgr) struct smu10_smumgr *priv; int r; - priv = kzalloc(sizeof(struct smu10_smumgr), GFP_KERNEL); + priv = kzalloc_obj(struct smu10_smumgr); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c index 0d4cbe4113a0..3e0068a6aeb2 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c @@ -333,7 +333,7 @@ int smu7_request_smu_load_fw(struct pp_hwmgr *hwmgr) if (!smu_data->toc) { struct SMU_DRAMData_TOC *toc; - smu_data->toc = kzalloc(sizeof(struct SMU_DRAMData_TOC), GFP_KERNEL); + smu_data->toc = kzalloc_obj(struct SMU_DRAMData_TOC); if (!smu_data->toc) return -ENOMEM; toc = smu_data->toc; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu8_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu8_smumgr.c index 76d4f12ceedf..f3f2b8fe8d63 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu8_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu8_smumgr.c @@ -758,7 +758,7 @@ static int smu8_smu_init(struct pp_hwmgr *hwmgr) int ret = 0; struct smu8_smumgr *smu8_smu; - smu8_smu = kzalloc(sizeof(struct smu8_smumgr), GFP_KERNEL); + smu8_smu = kzalloc_obj(struct smu8_smumgr); if (smu8_smu == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c index 2e21f9d066cb..28fe988c2262 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/tonga_smumgr.c @@ -228,7 +228,7 @@ static int tonga_smu_init(struct pp_hwmgr *hwmgr) { struct tonga_smumgr *tonga_priv; - tonga_priv = kzalloc(sizeof(struct tonga_smumgr), GFP_KERNEL); + tonga_priv = kzalloc_obj(struct tonga_smumgr); if (tonga_priv == NULL) return -ENOMEM; @@ -3072,7 +3072,7 @@ static int tonga_initialize_mc_reg_table(struct pp_hwmgr *hwmgr) struct tonga_mc_reg_table *ni_table = &smu_data->mc_reg_table; uint8_t module_index = tonga_get_memory_modile_index(hwmgr); - table = kzalloc(sizeof(pp_atomctrl_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(pp_atomctrl_mc_reg_table); if (table == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c index 0bf1bf5528c2..39192adf441f 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega10_smumgr.c @@ -218,7 +218,7 @@ static int vega10_smu_init(struct pp_hwmgr *hwmgr) if (ret || !info.kptr) return -EINVAL; - priv = kzalloc(sizeof(struct vega10_smumgr), GFP_KERNEL); + priv = kzalloc_obj(struct vega10_smumgr); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c index e2ba593faa5d..99db4cf8e11d 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega12_smumgr.c @@ -221,7 +221,7 @@ static int vega12_smu_init(struct pp_hwmgr *hwmgr) if (ret || !info.kptr) return -EINVAL; - priv = kzalloc(sizeof(struct vega12_smumgr), GFP_KERNEL); + priv = kzalloc_obj(struct vega12_smumgr); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c index e3515156d26f..b982c03f9e9a 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vega20_smumgr.c @@ -430,7 +430,7 @@ static int vega20_smu_init(struct pp_hwmgr *hwmgr) if (ret || !info.kptr) return -EINVAL; - priv = kzalloc(sizeof(struct vega20_smumgr), GFP_KERNEL); + priv = kzalloc_obj(struct vega20_smumgr); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c index 34c9f59b889a..cca6693853ec 100644 --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/vegam_smumgr.c @@ -83,7 +83,7 @@ static int vegam_smu_init(struct pp_hwmgr *hwmgr) { struct vegam_smumgr *smu_data; - smu_data = kzalloc(sizeof(struct vegam_smumgr), GFP_KERNEL); + smu_data = kzalloc_obj(struct vegam_smumgr); if (smu_data == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c index 75897ac203c3..b05c8bbdf2f3 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +++ b/drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c @@ -803,14 +803,14 @@ static int smu_early_init(struct amdgpu_ip_block *ip_block) struct smu_context *smu; int r; - smu = kzalloc(sizeof(struct smu_context), GFP_KERNEL); + smu = kzalloc_obj(struct smu_context); if (!smu) return -ENOMEM; smu->adev = adev; smu->pm_enabled = !!amdgpu_dpm; smu->is_apu = false; - smu->smu_baco.state = SMU_BACO_STATE_NONE; + smu->smu_baco.state = SMU_BACO_STATE_EXIT; smu->smu_baco.platform_support = false; smu->smu_baco.maco_support = false; smu->user_dpm_profile.fan_mode = -1; @@ -1355,7 +1355,7 @@ static int smu_sw_init(struct amdgpu_ip_block *ip_block) int i, ret; smu->pool_size = adev->pm.smu_prv_buffer_size; - smu_feature_init(smu, SMU_FEATURE_MAX); + smu_feature_init(smu, SMU_FEATURE_NUM_DEFAULT); INIT_WORK(&smu->throttling_logging_work, smu_throttling_logging_work_fn); INIT_WORK(&smu->interrupt_work, smu_interrupt_work_fn); @@ -1646,7 +1646,7 @@ static int smu_smc_hw_setup(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; uint8_t pcie_gen = 0, pcie_width = 0; - uint64_t features_supported; + struct smu_feature_bits features_supported; int ret = 0; switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) { @@ -1807,7 +1807,7 @@ static int smu_smc_hw_setup(struct smu_context *smu) return ret; } smu_feature_list_set_bits(smu, SMU_FEATURE_LIST_SUPPORTED, - (unsigned long *)&features_supported); + features_supported.bits); if (!smu_is_dpm_running(smu)) dev_info(adev->dev, "dpm has been disabled\n"); @@ -2120,9 +2120,8 @@ static int smu_reset_mp1_state(struct smu_context *smu) int ret = 0; if ((!adev->in_runpm) && (!adev->in_suspend) && - (!amdgpu_in_reset(adev)) && amdgpu_ip_version(adev, MP1_HWIP, 0) == - IP_VERSION(13, 0, 10) && - !amdgpu_device_has_display_hardware(adev)) + (!amdgpu_in_reset(adev)) && !smu->is_apu && + amdgpu_ip_version(adev, MP1_HWIP, 0) >= IP_VERSION(13, 0, 0)) ret = smu_set_mp1_state(smu, PP_MP1_STATE_UNLOAD); return ret; @@ -3152,10 +3151,19 @@ static int smu_read_sensor(void *handle, *((uint32_t *)data) = pstate_table->uclk_pstate.peak * 100; *size = 4; break; - case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK: - ret = smu_feature_get_enabled_mask(smu, (uint64_t *)data); + case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK: { + struct smu_feature_bits feature_mask; + uint32_t features[2]; + + /* TBD: need to handle for > 64 bits */ + ret = smu_feature_get_enabled_mask(smu, &feature_mask); + if (!ret) { + smu_feature_bits_to_arr32(&feature_mask, features, 64); + *(uint64_t *)data = *(uint64_t *)features; + } *size = 8; break; + } case AMDGPU_PP_SENSOR_UVD_POWER: *(uint32_t *)data = smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UVD_BIT) ? 1 : 0; *size = 4; diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h index 7c63c631f6d4..a6303d093c50 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h @@ -471,12 +471,30 @@ struct smu_power_context { struct smu_power_gate power_gate; }; -#define SMU_FEATURE_MAX (64) +#define SMU_FEATURE_NUM_DEFAULT (64) +#define SMU_FEATURE_MAX (128) struct smu_feature_bits { DECLARE_BITMAP(bits, SMU_FEATURE_MAX); }; +/* + * Helpers for initializing smu_feature_bits statically. + * Use SMU_FEATURE_BIT_INIT() which automatically handles array indexing: + * static const struct smu_feature_bits example = { + * .bits = { + * SMU_FEATURE_BIT_INIT(5), + * SMU_FEATURE_BIT_INIT(10), + * SMU_FEATURE_BIT_INIT(65), + * SMU_FEATURE_BIT_INIT(100) + * } + * }; + */ +#define SMU_FEATURE_BITS_ELEM(bit) ((bit) / BITS_PER_LONG) +#define SMU_FEATURE_BITS_POS(bit) ((bit) % BITS_PER_LONG) +#define SMU_FEATURE_BIT_INIT(bit) \ + [SMU_FEATURE_BITS_ELEM(bit)] = (1UL << SMU_FEATURE_BITS_POS(bit)) + enum smu_feature_list { SMU_FEATURE_LIST_SUPPORTED, SMU_FEATURE_LIST_ALLOWED, @@ -518,7 +536,6 @@ enum smu_reset_mode { enum smu_baco_state { SMU_BACO_STATE_ENTER = 0, SMU_BACO_STATE_EXIT, - SMU_BACO_STATE_NONE, }; struct smu_baco_context { @@ -1212,7 +1229,8 @@ struct pptable_funcs { * on the SMU. * &feature_mask: Enabled feature mask. */ - int (*get_enabled_mask)(struct smu_context *smu, uint64_t *feature_mask); + int (*get_enabled_mask)(struct smu_context *smu, + struct smu_feature_bits *feature_mask); /** * @feature_is_enabled: Test if a feature is enabled. @@ -2044,6 +2062,12 @@ static inline bool smu_feature_bits_empty(const struct smu_feature_bits *bits, return bitmap_empty(bits->bits, nbits); } +static inline bool smu_feature_bits_full(const struct smu_feature_bits *bits, + unsigned int nbits) +{ + return bitmap_full(bits->bits, nbits); +} + static inline void smu_feature_bits_copy(struct smu_feature_bits *dst, const unsigned long *src, unsigned int nbits) diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h index 14e8d8c7a80a..ab4a64f54e79 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h +++ b/drivers/gpu/drm/amd/pm/swsmu/inc/smu_v15_0.h @@ -226,8 +226,6 @@ int smu_v15_0_deep_sleep_control(struct smu_context *smu, int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context *smu); -int smu_v15_0_set_default_dpm_tables(struct smu_context *smu); - int smu_v15_0_get_pptable_from_firmware(struct smu_context *smu, void **table, uint32_t *size, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c index b22a0e91826d..74c818e3fbd0 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/arcturus_ppt.c @@ -65,14 +65,15 @@ #define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000 #define SMU_FEATURES_HIGH_SHIFT 32 -#define SMC_DPM_FEATURE ( \ - FEATURE_DPM_PREFETCHER_MASK | \ - FEATURE_DPM_GFXCLK_MASK | \ - FEATURE_DPM_UCLK_MASK | \ - FEATURE_DPM_SOCCLK_MASK | \ - FEATURE_DPM_MP0CLK_MASK | \ - FEATURE_DPM_FCLK_MASK | \ - FEATURE_DPM_XGMI_MASK) +static const struct smu_feature_bits arcturus_dpm_features = { + .bits = { SMU_FEATURE_BIT_INIT(FEATURE_DPM_PREFETCHER_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_XGMI_BIT) } +}; #define smnPCIE_ESM_CTRL 0x111003D0 @@ -266,7 +267,7 @@ static int arcturus_tables_init(struct smu_context *smu) sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) return -ENOMEM; smu_table->metrics_time = 0; @@ -306,14 +307,13 @@ static int arcturus_allocate_dpm_context(struct smu_context *smu) struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_dpm_policy *policy; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_11_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); smu_dpm->dpm_policies = - kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); + kzalloc_obj(struct smu_dpm_policy_ctxt); if (!smu_dpm->dpm_policies) return -ENOMEM; @@ -1526,13 +1526,14 @@ static int arcturus_set_performance_level(struct smu_context *smu, static bool arcturus_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + arcturus_dpm_features.bits); } static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, @@ -1577,7 +1578,7 @@ static int arcturus_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c index 4a5dcc893665..4e70308a455e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/cyan_skillfish_ppt.c @@ -60,11 +60,13 @@ static struct gfx_user_settings { static uint32_t cyan_skillfish_sclk_default; -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOC_DPM_BIT) | \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT)) +static const struct smu_feature_bits cyan_skillfish_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOC_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT) + } +}; static struct cmn2asic_msg_mapping cyan_skillfish_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), @@ -95,7 +97,7 @@ static int cyan_skillfish_tables_init(struct smu_context *smu) PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err0_out; @@ -361,7 +363,7 @@ static bool cyan_skillfish_is_dpm_running(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; /* we need to re-init after suspend so return false */ if (adev->in_suspend) @@ -378,7 +380,8 @@ static bool cyan_skillfish_is_dpm_running(struct smu_context *smu) cyan_skillfish_get_smu_metrics_data(smu, METRICS_CURR_GFXCLK, &cyan_skillfish_sclk_default); - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + cyan_skillfish_dpm_features.bits); } static ssize_t cyan_skillfish_get_gpu_metrics(struct smu_context *smu, @@ -565,12 +568,13 @@ static int cyan_skillfish_get_dpm_ultimate_freq(struct smu_context *smu, return 0; } -static int cyan_skillfish_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask) +static int +cyan_skillfish_get_enabled_mask(struct smu_context *smu, + struct smu_feature_bits *feature_mask) { if (!feature_mask) return -EINVAL; - memset(feature_mask, 0xff, sizeof(*feature_mask)); + smu_feature_bits_fill(feature_mask); return 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c index f14eed052526..163e09ca0730 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/navi10_ppt.c @@ -58,16 +58,18 @@ #undef pr_info #undef pr_debug -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_GFX_PACE_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) +static const struct smu_feature_bits navi10_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DPM_PREFETCHER_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFX_PACE_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_DCEFCLK_BIT) + } +}; #define SMU_11_0_GFX_BUSY_THRESHOLD 15 @@ -514,8 +516,7 @@ static int navi10_tables_init(struct smu_context *smu) dummy_read_1_table->align = PAGE_SIZE; dummy_read_1_table->domain = AMDGPU_GEM_DOMAIN_VRAM; - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_NV1X_t), - GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_NV1X_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -526,7 +527,7 @@ static int navi10_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -933,8 +934,7 @@ static int navi10_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_11_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -1619,13 +1619,14 @@ static int navi10_display_config_changed(struct smu_context *smu) static bool navi10_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + navi10_dpm_features.bits); } static int navi10_get_fan_speed_rpm(struct smu_context *smu, @@ -2791,7 +2792,7 @@ static int navi10_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c index 98a02fc08214..cf030af18aad 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/sienna_cichlid_ppt.c @@ -60,16 +60,18 @@ #undef pr_info #undef pr_debug -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_FCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)) +static const struct smu_feature_bits sienna_cichlid_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DPM_PREFETCHER_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_DCEFCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT) + } +}; #define SMU_11_0_7_GFX_BUSY_THRESHOLD 15 @@ -553,7 +555,7 @@ static int sienna_cichlid_tables_init(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_DRIVER_SMU_CONFIG, sizeof(DriverSmuConfigExternal_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetricsExternal_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -564,7 +566,7 @@ static int sienna_cichlid_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -919,8 +921,7 @@ static int sienna_cichlid_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_11_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -1534,13 +1535,14 @@ static int sienna_cichlid_display_config_changed(struct smu_context *smu) static bool sienna_cichlid_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + sienna_cichlid_dpm_features.bits); } static int sienna_cichlid_get_fan_speed_rpm(struct smu_context *smu, @@ -2504,7 +2506,7 @@ static int sienna_cichlid_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c index 1d0f9f8ddf9b..12b052d920f5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c @@ -378,7 +378,7 @@ int smu_v11_0_init_smc_tables(struct smu_context *smu) } smu_table->max_sustainable_clocks = - kzalloc(sizeof(struct smu_11_0_max_sustainable_clocks), GFP_KERNEL); + kzalloc_obj(struct smu_11_0_max_sustainable_clocks); if (!smu_table->max_sustainable_clocks) { ret = -ENOMEM; goto err1_out; @@ -751,7 +751,7 @@ int smu_v11_0_set_allowed_mask(struct smu_context *smu) uint32_t feature_mask[2]; if (smu_feature_list_is_empty(smu, SMU_FEATURE_LIST_ALLOWED) || - feature->feature_num < 64) { + feature->feature_num < SMU_FEATURE_NUM_DEFAULT) { ret = -EINVAL; goto failed; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c index 4de1778ea6b3..5eabaf55dfc5 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/vangogh_ppt.c @@ -58,17 +58,19 @@ #define SMUIO_GFX_MISC_CNTL__SMU_GFX_cold_vs_gfxoff_MASK 0x00000001L #define SMUIO_GFX_MISC_CNTL__PWR_GFXOFF_STATUS_MASK 0x00000006L -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT)) +static const struct smu_feature_bits vangogh_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_MP0CLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT) + } +}; static struct cmn2asic_msg_mapping vangogh_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0), @@ -251,11 +253,11 @@ static int vangogh_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err3_out; @@ -431,8 +433,7 @@ static int vangogh_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_11_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -504,7 +505,7 @@ static bool vangogh_is_dpm_running(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; /* we need to re-init after suspend so return false */ if (adev->in_suspend) @@ -515,7 +516,8 @@ static bool vangogh_is_dpm_running(struct smu_context *smu) if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + vangogh_dpm_features.bits); } static int vangogh_get_dpm_clk_limited(struct smu_context *smu, enum smu_clk_type clk_type, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c index 5346b60b09b9..186020ed6708 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/renoir_ppt.c @@ -157,16 +157,16 @@ static int renoir_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err0_out; - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err1_out; smu_table->metrics_time = 0; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -1434,11 +1434,11 @@ static int renoir_gfx_state_change_set(struct smu_context *smu, uint32_t state) } static int renoir_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask) + struct smu_feature_bits *feature_mask) { if (!feature_mask) return -EINVAL; - memset(feature_mask, 0xff, sizeof(*feature_mask)); + smu_feature_bits_fill(feature_mask); return 0; } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c index 3b6a34644a92..2b4faab37693 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/aldebaran_ppt.c @@ -61,15 +61,18 @@ [smu_feature] = {1, (aldebaran_feature)} #define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DATA_CALCULATIONS) | \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_FCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_XGMI_BIT) | \ - FEATURE_MASK(FEATURE_DPM_VCN_BIT)) +static const struct smu_feature_bits aldebaran_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DATA_CALCULATIONS), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_XGMI_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_VCN_BIT) + } +}; #define smnPCIE_ESM_CTRL 0x111003D0 @@ -242,7 +245,7 @@ static int aldebaran_tables_init(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) return -ENOMEM; smu_table->metrics_time = 0; @@ -291,14 +294,13 @@ static int aldebaran_allocate_dpm_context(struct smu_context *smu) struct smu_dpm_context *smu_dpm = &smu->smu_dpm; struct smu_dpm_policy *policy; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_13_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context); smu_dpm->dpm_policies = - kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); + kzalloc_obj(struct smu_dpm_policy_ctxt); if (!smu_dpm->dpm_policies) return -ENOMEM; @@ -1395,12 +1397,13 @@ static int aldebaran_usr_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_ static bool aldebaran_is_dpm_running(struct smu_context *smu) { int ret; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + aldebaran_dpm_features.bits); } static int aldebaran_i2c_xfer(struct i2c_adapter *i2c_adap, @@ -1418,7 +1421,7 @@ static int aldebaran_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c index 3b0aa6a2e78e..447a9c26bb77 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -449,7 +449,7 @@ int smu_v13_0_init_smc_tables(struct smu_context *smu) } smu_table->max_sustainable_clocks = - kzalloc(sizeof(struct smu_13_0_max_sustainable_clocks), GFP_KERNEL); + kzalloc_obj(struct smu_13_0_max_sustainable_clocks); if (!smu_table->max_sustainable_clocks) { ret = -ENOMEM; goto err1_out; @@ -553,8 +553,7 @@ int smu_v13_0_init_power(struct smu_context *smu) if (smu_power->power_context || smu_power->power_context_size != 0) return -EINVAL; - smu_power->power_context = kzalloc(sizeof(struct smu_13_0_power_context), - GFP_KERNEL); + smu_power->power_context = kzalloc_obj(struct smu_13_0_power_context); if (!smu_power->power_context) return -ENOMEM; smu_power->power_context_size = sizeof(struct smu_13_0_power_context); @@ -762,7 +761,7 @@ int smu_v13_0_set_allowed_mask(struct smu_context *smu) uint32_t feature_mask[2]; if (smu_feature_list_is_empty(smu, SMU_FEATURE_LIST_ALLOWED) || - feature->feature_num < 64) + feature->feature_num < SMU_FEATURE_NUM_DEFAULT) return -EINVAL; smu_feature_list_to_arr32(smu, SMU_FEATURE_LIST_ALLOWED, feature_mask); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c index 9c4298736b28..a8d63d4d1f6e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c @@ -59,14 +59,16 @@ #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_FCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)) +static const struct smu_feature_bits smu_v13_0_0_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT) + } +}; #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 @@ -493,7 +495,7 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu) sizeof(WifiBandEntryTable_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetricsExternal_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -504,7 +506,7 @@ static int smu_v13_0_0_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -528,8 +530,7 @@ static int smu_v13_0_0_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_13_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -689,13 +690,14 @@ static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu) static bool smu_v13_0_0_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_0_dpm_features.bits); } static int smu_v13_0_0_system_features_control(struct smu_context *smu, @@ -2032,6 +2034,7 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, smu, SMU_DRIVER_TABLE_GPU_METRICS); SmuMetricsExternal_t metrics_ext; SmuMetrics_t *metrics = &metrics_ext.SmuMetrics; + uint32_t mp1_ver = amdgpu_ip_version(smu->adev, MP1_HWIP, 0); int ret = 0; ret = smu_cmn_get_metrics_table(smu, @@ -2056,7 +2059,12 @@ static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu, metrics->Vcn1ActivityPercentage); gpu_metrics->average_socket_power = metrics->AverageSocketPower; - gpu_metrics->energy_accumulator = metrics->EnergyAccumulator; + + if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) || + (mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800)) + gpu_metrics->energy_accumulator = metrics->EnergyAccumulator; + else + gpu_metrics->energy_accumulator = UINT_MAX; if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD) gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs; @@ -2214,7 +2222,8 @@ static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu) user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | BIT(PP_OD_FEATURE_UCLK_BIT) | BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table); user_od_table->OverDriveTable.FeatureCtrlMask = 0; if (res == 0) @@ -2612,21 +2621,11 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - u32 smu_version; - int ret; /* SRIOV does not support SMU mode1 reset */ if (amdgpu_sriov_vf(adev)) return false; - /* PMFW support is available since 78.41 */ - ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); - if (ret) - return false; - - if (smu_version < 0x004e2900) - return false; - return true; } @@ -2645,7 +2644,7 @@ static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2775,13 +2774,7 @@ static int smu_v13_0_0_set_mp1_state(struct smu_context *smu, switch (mp1_state) { case PP_MP1_STATE_UNLOAD: - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_PrepareMp1ForUnload, - 0x55, NULL); - - if (!ret && smu->smu_baco.state == SMU_BACO_STATE_EXIT) - ret = smu_v13_0_disable_pmfw_state(smu); - + ret = smu_cmn_set_mp1_state(smu, mp1_state); break; default: /* Ignore others */ @@ -2825,8 +2818,9 @@ static int smu_v13_0_0_mode1_reset(struct smu_context *smu) /* SMU 13_0_0 PMFW supports RAS fatal error reset from 78.77 */ smu_v13_0_0_set_mode1_reset_param(smu, 0x004e4d00, ¶m); - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_Mode1Reset, param, NULL); + ret = smu_cmn_send_debug_smc_msg_with_param(smu, + DEBUGSMC_MSG_Mode1Reset, param); + break; case IP_VERSION(13, 0, 10): diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c index 9a34e5460b35..32d5e2170d80 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_12_ppt.c @@ -52,10 +52,13 @@ #define SMU_13_0_12_FEA_MAP(smu_feature, smu_13_0_12_feature) \ [smu_feature] = { 1, (smu_13_0_12_feature) } -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE \ - (FEATURE_MASK(FEATURE_DATA_CALCULATION) | \ - FEATURE_MASK(FEATURE_DPM_GFXCLK) | FEATURE_MASK(FEATURE_DPM_FCLK)) +static const struct smu_feature_bits smu_v13_0_12_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DATA_CALCULATION), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK) + } +}; #define NUM_JPEG_RINGS_FW 10 #define NUM_JPEG_RINGS_GPU_METRICS(gpu_metrics) \ @@ -199,14 +202,14 @@ void smu_v13_0_12_tables_fini(struct smu_context *smu) } static int smu_v13_0_12_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask) + struct smu_feature_bits *feature_mask) { int ret; ret = smu_cmn_get_enabled_mask(smu, feature_mask); if (ret == -EIO) { - *feature_mask = 0; + smu_feature_bits_clearall(feature_mask); ret = 0; } @@ -220,7 +223,7 @@ static int smu_v13_0_12_fru_get_product_info(struct smu_context *smu, struct amdgpu_device *adev = smu->adev; if (!adev->fru_info) { - adev->fru_info = kzalloc(sizeof(*adev->fru_info), GFP_KERNEL); + adev->fru_info = kzalloc_obj(*adev->fru_info); if (!adev->fru_info) return -ENOMEM; } @@ -372,14 +375,15 @@ int smu_v13_0_12_setup_driver_pptable(struct smu_context *smu) bool smu_v13_0_12_is_dpm_running(struct smu_context *smu) { int ret; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_v13_0_12_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_12_dpm_features.bits); } int smu_v13_0_12_get_smu_metrics_data(struct smu_context *smu, @@ -819,6 +823,9 @@ ssize_t smu_v13_0_12_get_xcp_metrics(struct smu_context *smu, struct amdgpu_xcp idx++; } + xcp_metrics->accumulation_counter = metrics->AccumulationCounter; + xcp_metrics->firmware_timestamp = metrics->Timestamp; + return sizeof(*xcp_metrics); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c index 41c61362f7fc..5b1a038d6a19 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_4_ppt.c @@ -52,24 +52,25 @@ #define mmMP1_SMN_C2PMSG_90 0x029a #define mmMP1_SMN_C2PMSG_90_BASE_IDX 1 -#define FEATURE_MASK(feature) (1ULL << feature) - #define SMU_13_0_4_UMD_PSTATE_GFXCLK 938 #define SMU_13_0_4_UMD_PSTATE_SOCCLK 938 #define SMU_13_0_4_UMD_PSTATE_FCLK 1875 -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_ISP_DPM_BIT) | \ - FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT)) +static const struct smu_feature_bits smu_v13_0_4_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_MP0CLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_ISP_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_IPU_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT) + } +}; static struct cmn2asic_msg_mapping smu_v13_0_4_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), @@ -160,16 +161,16 @@ static int smu_v13_0_4_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err0_out; - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err1_out; smu_table->metrics_time = 0; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -212,14 +213,15 @@ static int smu_v13_0_4_fini_smc_tables(struct smu_context *smu) static bool smu_v13_0_4_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_4_dpm_features.bits); } static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c index e4be727789c0..d534723fef91 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_5_ppt.c @@ -51,17 +51,19 @@ #define mmMP1_C2PMSG_33 (0xbee261 + 0xb00000 / 4) #define mmMP1_C2PMSG_33_BASE_IDX 0 -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT)) +static const struct smu_feature_bits smu_v13_0_5_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_MP0CLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT) + } +}; static struct cmn2asic_msg_mapping smu_v13_0_5_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), @@ -134,16 +136,16 @@ static int smu_v13_0_5_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err0_out; - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err1_out; smu_table->metrics_time = 0; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -230,14 +232,15 @@ static int smu_v13_0_5_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) static bool smu_v13_0_5_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_5_dpm_features.bits); } static int smu_v13_0_5_mode_reset(struct smu_context *smu, int type) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c index bd893e95515f..896b51c8a9a7 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c @@ -76,12 +76,18 @@ MODULE_FIRMWARE("amdgpu/smu_13_0_14.bin"); [smu_feature] = { 1, (smu_13_0_6_feature) } #define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE \ - (FEATURE_MASK(FEATURE_DATA_CALCULATION) | \ - FEATURE_MASK(FEATURE_DPM_GFXCLK) | FEATURE_MASK(FEATURE_DPM_UCLK) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK) | FEATURE_MASK(FEATURE_DPM_FCLK) | \ - FEATURE_MASK(FEATURE_DPM_LCLK) | FEATURE_MASK(FEATURE_DPM_XGMI) | \ - FEATURE_MASK(FEATURE_DPM_VCN)) +static const struct smu_feature_bits smu_v13_0_6_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DATA_CALCULATION), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LCLK), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_XGMI), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_VCN) + } +}; #define smnPCIE_ESM_CTRL 0x93D0 #define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288 @@ -580,7 +586,7 @@ static int smu_v13_0_6_tables_init(struct smu_context *smu) return -ENOMEM; smu_table->metrics_time = 0; - driver_pptable = kzalloc(sizeof(struct PPTable_t), GFP_KERNEL); + driver_pptable = kzalloc_obj(struct PPTable_t); if (!driver_pptable) return -ENOMEM; @@ -684,13 +690,13 @@ static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu) struct smu_dpm_policy *policy; smu_dpm->dpm_context = - kzalloc(sizeof(struct smu_13_0_dpm_context), GFP_KERNEL); + kzalloc_obj(struct smu_13_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context); smu_dpm->dpm_policies = - kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL); + kzalloc_obj(struct smu_dpm_policy_ctxt); if (!smu_dpm->dpm_policies) { kfree(smu_dpm->dpm_context); return -ENOMEM; @@ -2266,14 +2272,14 @@ static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu, } static int smu_v13_0_6_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask) + struct smu_feature_bits *feature_mask) { int ret; ret = smu_cmn_get_enabled_mask(smu, feature_mask); if (ret == -EIO && !smu_v13_0_6_cap_supported(smu, SMU_CAP(DPM))) { - *feature_mask = 0; + smu_feature_bits_clearall(feature_mask); ret = 0; } @@ -2283,7 +2289,7 @@ static int smu_v13_0_6_get_enabled_mask(struct smu_context *smu, static bool smu_v13_0_6_is_dpm_running(struct smu_context *smu) { int ret; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12)) return smu_v13_0_12_is_dpm_running(smu); @@ -2293,7 +2299,8 @@ static bool smu_v13_0_6_is_dpm_running(struct smu_context *smu) if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_6_dpm_features.bits); } static int smu_v13_0_6_request_i2c_xfer(struct smu_context *smu, @@ -2334,7 +2341,7 @@ static int smu_v13_0_6_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2557,9 +2564,10 @@ static ssize_t smu_v13_0_6_get_xcp_metrics(struct smu_context *smu, int xcp_id, const u8 num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS_4_0_3; int version = smu_v13_0_6_get_metrics_version(smu); struct smu_v13_0_6_partition_metrics *xcp_metrics; - MetricsTableV0_t *metrics_v0 __free(kfree) = NULL; + struct smu_table_context *smu_table = &smu->smu_table; struct amdgpu_device *adev = smu->adev; int ret, inst, i, j, k, idx; + MetricsTableV0_t *metrics_v0; MetricsTableV1_t *metrics_v1; MetricsTableV2_t *metrics_v2; struct amdgpu_xcp *xcp; @@ -2579,22 +2587,20 @@ static ssize_t smu_v13_0_6_get_xcp_metrics(struct smu_context *smu, int xcp_id, xcp_metrics = (struct smu_v13_0_6_partition_metrics *)table; smu_v13_0_6_partition_metrics_init(xcp_metrics, 1, 1); - metrics_v0 = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL); - if (!metrics_v0) - return -ENOMEM; - - ret = smu_v13_0_6_get_metrics_table(smu, metrics_v0, false); + ret = smu_v13_0_6_get_metrics_table(smu, NULL, false); if (ret) return ret; + metrics_v0 = (MetricsTableV0_t *)smu_table->metrics_table; + if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 12) && smu_v13_0_6_cap_supported(smu, SMU_CAP(STATIC_METRICS))) return smu_v13_0_12_get_xcp_metrics(smu, xcp, table, metrics_v0); - metrics_v1 = (MetricsTableV1_t *)metrics_v0; - metrics_v2 = (MetricsTableV2_t *)metrics_v0; + metrics_v1 = (MetricsTableV1_t *)smu_table->metrics_table; + metrics_v2 = (MetricsTableV2_t *)smu_table->metrics_table; per_inst = smu_v13_0_6_cap_supported(smu, SMU_CAP(PER_INST_METRICS)); @@ -2662,6 +2668,8 @@ static ssize_t smu_v13_0_6_get_xcp_metrics(struct smu_context *smu, int xcp_id, idx++; } } + xcp_metrics->accumulation_counter = GET_METRIC_FIELD(AccumulationCounter, version); + xcp_metrics->firmware_timestamp = GET_METRIC_FIELD(Timestamp, version); return sizeof(*xcp_metrics); } @@ -2670,21 +2678,21 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table { struct smu_v13_0_6_gpu_metrics *gpu_metrics; int version = smu_v13_0_6_get_metrics_version(smu); - MetricsTableV0_t *metrics_v0 __free(kfree) = NULL; + struct smu_table_context *smu_table = &smu->smu_table; struct amdgpu_device *adev = smu->adev; int ret = 0, xcc_id, inst, i, j; + MetricsTableV0_t *metrics_v0; MetricsTableV1_t *metrics_v1; MetricsTableV2_t *metrics_v2; u16 link_width_level; u8 num_jpeg_rings; bool per_inst; - metrics_v0 = kzalloc(METRICS_TABLE_SIZE, GFP_KERNEL); - ret = smu_v13_0_6_get_metrics_table(smu, metrics_v0, false); + ret = smu_v13_0_6_get_metrics_table(smu, NULL, false); if (ret) return ret; - metrics_v2 = (MetricsTableV2_t *)metrics_v0; + metrics_v0 = (MetricsTableV0_t *)smu_table->metrics_table; gpu_metrics = (struct smu_v13_0_6_gpu_metrics *)smu_driver_table_ptr( smu, SMU_DRIVER_TABLE_GPU_METRICS); @@ -2695,8 +2703,8 @@ static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table goto fill; } - metrics_v1 = (MetricsTableV1_t *)metrics_v0; - metrics_v2 = (MetricsTableV2_t *)metrics_v0; + metrics_v1 = (MetricsTableV1_t *)smu_table->metrics_table; + metrics_v2 = (MetricsTableV2_t *)smu_table->metrics_table; gpu_metrics->temperature_hotspot = SMUQ10_ROUND(GET_METRIC_FIELD(MaxSocketTemperature, version)); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h index 0588a5aa952d..ffb06564f830 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.h @@ -140,7 +140,7 @@ extern const struct ras_smu_drv smu_v13_0_12_ras_smu_drv; SMU_SCALAR(SMU_MATTR(SYSTEM_CLOCK_COUNTER), SMU_MUNIT(TIME_1), \ SMU_MTYPE(U64), system_clock_counter); \ SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ - SMU_MTYPE(U32), accumulation_counter); \ + SMU_MTYPE(U64), accumulation_counter); \ SMU_SCALAR(SMU_MATTR(PROCHOT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ SMU_MTYPE(U32), prochot_residency_acc); \ SMU_SCALAR(SMU_MATTR(PPT_RESIDENCY_ACC), SMU_MUNIT(NONE), \ @@ -259,7 +259,11 @@ void smu_v13_0_12_get_gpu_metrics(struct smu_context *smu, void **table, SMU_13_0_6_MAX_XCC); \ SMU_ARRAY(SMU_MATTR(GFX_BELOW_HOST_LIMIT_TOTAL_ACC), SMU_MUNIT(NONE), \ SMU_MTYPE(U64), gfx_below_host_limit_total_acc, \ - SMU_13_0_6_MAX_XCC); + SMU_13_0_6_MAX_XCC); \ + SMU_SCALAR(SMU_MATTR(ACCUMULATION_COUNTER), SMU_MUNIT(NONE), \ + SMU_MTYPE(U64), accumulation_counter); \ + SMU_SCALAR(SMU_MATTR(FIRMWARE_TIMESTAMP), SMU_MUNIT(TIME_2), \ + SMU_MTYPE(U64), firmware_timestamp); DECLARE_SMU_METRICS_CLASS(smu_v13_0_6_partition_metrics, SMU_13_0_6_PARTITION_METRICS_FIELDS); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c index 415766dbfe6c..5500a0f12f0e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c @@ -59,19 +59,32 @@ #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_FCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)) +static const struct smu_feature_bits smu_v13_0_7_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT) + } +}; #define smnMP1_FIRMWARE_FLAGS_SMU_13_0_7 0x3b10028 #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 +#define mmMP1_SMN_C2PMSG_75 0x028b +#define mmMP1_SMN_C2PMSG_75_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_53 0x0275 +#define mmMP1_SMN_C2PMSG_53_BASE_IDX 0 + +#define mmMP1_SMN_C2PMSG_54 0x0276 +#define mmMP1_SMN_C2PMSG_54_BASE_IDX 0 + +#define DEBUGSMC_MSG_Mode1Reset 2 + #define PP_OD_FEATURE_GFXCLK_FMIN 0 #define PP_OD_FEATURE_GFXCLK_FMAX 1 #define PP_OD_FEATURE_UCLK_FMIN 2 @@ -517,7 +530,7 @@ static int smu_v13_0_7_tables_init(struct smu_context *smu) sizeof(WifiBandEntryTable_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetricsExternal_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -528,7 +541,7 @@ static int smu_v13_0_7_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -546,8 +559,7 @@ static int smu_v13_0_7_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_13_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_13_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -697,13 +709,14 @@ static int smu_v13_0_7_set_default_dpm_table(struct smu_context *smu) static bool smu_v13_0_7_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v13_0_7_dpm_features.bits); } static uint32_t smu_v13_0_7_get_throttler_status(SmuMetrics_t *metrics) @@ -2052,7 +2065,8 @@ static ssize_t smu_v13_0_7_get_gpu_metrics(struct smu_context *smu, metrics->Vcn1ActivityPercentage); gpu_metrics->average_socket_power = metrics->AverageSocketPower; - gpu_metrics->energy_accumulator = metrics->EnergyAccumulator; + gpu_metrics->energy_accumulator = smu->smc_fw_version <= 0x00521400 ? + metrics->EnergyAccumulator : UINT_MAX; if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD) gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs; @@ -2210,7 +2224,8 @@ static int smu_v13_0_7_restore_user_od_settings(struct smu_context *smu) user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | BIT(PP_OD_FEATURE_UCLK_BIT) | BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table); user_od_table->OverDriveTable.FeatureCtrlMask = 0; if (res == 0) @@ -2386,9 +2401,8 @@ static int smu_v13_0_7_get_power_profile_mode(struct smu_context *smu, char *buf if (!buf) return -EINVAL; - activity_monitor_external = kcalloc(PP_SMC_POWER_PROFILE_COUNT, - sizeof(*activity_monitor_external), - GFP_KERNEL); + activity_monitor_external = kzalloc_objs(*activity_monitor_external, + PP_SMC_POWER_PROFILE_COUNT); if (!activity_monitor_external) return -ENOMEM; @@ -2731,6 +2745,36 @@ static int smu_v13_0_7_update_pcie_parameters(struct smu_context *smu, return ret; } +static int smu_v13_0_7_mode1_reset(struct smu_context *smu) +{ + int ret; + + ret = smu_cmn_send_debug_smc_msg(smu, DEBUGSMC_MSG_Mode1Reset); + if (!ret) { + /* disable mmio access while doing mode 1 reset*/ + smu->adev->no_hw_access = true; + /* ensure no_hw_access is globally visible before any MMIO */ + smp_mb(); + msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS); + } + + return ret; +} + +static void smu_v13_0_7_init_msg_ctl(struct smu_context *smu) +{ + struct amdgpu_device *adev = smu->adev; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + smu_v13_0_init_msg_ctl(smu, smu_v13_0_7_message_map); + + /* Set up debug mailbox registers */ + ctl->config.debug_param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_53); + ctl->config.debug_msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_75); + ctl->config.debug_resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_54); + ctl->flags |= SMU_MSG_CTL_DEBUG_MAILBOX; +} + static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .init_allowed_features = smu_v13_0_7_init_allowed_features, .set_default_dpm_table = smu_v13_0_7_set_default_dpm_table, @@ -2792,7 +2836,7 @@ static const struct pptable_funcs smu_v13_0_7_ppt_funcs = { .baco_enter = smu_v13_0_baco_enter, .baco_exit = smu_v13_0_baco_exit, .mode1_reset_is_support = smu_v13_0_7_is_mode1_reset_supported, - .mode1_reset = smu_v13_0_mode1_reset, + .mode1_reset = smu_v13_0_7_mode1_reset, .set_mp1_state = smu_v13_0_7_set_mp1_state, .set_df_cstate = smu_v13_0_7_set_df_cstate, .gpo_control = smu_v13_0_gpo_control, @@ -2811,5 +2855,5 @@ void smu_v13_0_7_set_ppt_funcs(struct smu_context *smu) smu->pwr_src_map = smu_v13_0_7_pwr_src_map; smu->workload_map = smu_v13_0_7_workload_map; smu->smc_driver_if_version = SMU13_0_7_DRIVER_IF_VERSION; - smu_v13_0_init_msg_ctl(smu, smu_v13_0_7_message_map); + smu_v13_0_7_init_msg_ctl(smu); } diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c index 7f70f79c3b2f..f43a91ac6970 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/yellow_carp_ppt.c @@ -55,17 +55,19 @@ #define SMU_13_0_1_UMD_PSTATE_SOCCLK 678 #define SMU_13_0_1_UMD_PSTATE_FCLK 1800 -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_MP0CLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT)) +static const struct smu_feature_bits yellow_carp_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_MP0CLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT) + } +}; static struct cmn2asic_msg_mapping yellow_carp_message_map[SMU_MSG_MAX_COUNT] = { MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), @@ -161,16 +163,16 @@ static int yellow_carp_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err0_out; - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err1_out; smu_table->metrics_time = 0; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -257,14 +259,15 @@ static int yellow_carp_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) static bool yellow_carp_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + yellow_carp_dpm_features.bits); } static int yellow_carp_post_smu_init(struct smu_context *smu) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c index cabbd234c6e2..cec2df1ad0af 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c @@ -439,7 +439,7 @@ int smu_v14_0_init_smc_tables(struct smu_context *smu) } smu_table->max_sustainable_clocks = - kzalloc(sizeof(struct smu_14_0_max_sustainable_clocks), GFP_KERNEL); + kzalloc_obj(struct smu_14_0_max_sustainable_clocks); if (!smu_table->max_sustainable_clocks) { ret = -ENOMEM; goto err1_out; @@ -538,8 +538,7 @@ int smu_v14_0_init_power(struct smu_context *smu) if (smu_power->power_context || smu_power->power_context_size != 0) return -EINVAL; - smu_power->power_context = kzalloc(sizeof(struct smu_14_0_dpm_context), - GFP_KERNEL); + smu_power->power_context = kzalloc_obj(struct smu_14_0_dpm_context); if (!smu_power->power_context) return -ENOMEM; smu_power->power_context_size = sizeof(struct smu_14_0_dpm_context); @@ -747,7 +746,7 @@ int smu_v14_0_set_allowed_mask(struct smu_context *smu) uint32_t feature_mask[2]; if (smu_feature_list_is_empty(smu, SMU_FEATURE_LIST_ALLOWED) || - feature->feature_num < 64) + feature->feature_num < SMU_FEATURE_NUM_DEFAULT) return -EINVAL; smu_feature_list_to_arr32(smu, SMU_FEATURE_LIST_ALLOWED, feature_mask); diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c index a4e376e8328c..2353524b8821 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c @@ -72,19 +72,21 @@ #define SMU_14_0_4_UMD_PSTATE_GFXCLK 938 #define SMU_14_0_4_UMD_PSTATE_SOCCLK 938 -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ - FEATURE_MASK(FEATURE_IPU_DPM_BIT) | \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VPE_DPM_BIT)) +static const struct smu_feature_bits smu_v14_0_0_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_ISP_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_IPU_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VPE_DPM_BIT) + } +}; enum smu_mall_pg_config { SMU_MALL_PG_CONFIG_PMFW_CONTROL = 0, @@ -195,7 +197,7 @@ static int smu_v14_0_0_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -204,7 +206,7 @@ static int smu_v14_0_0_init_smc_tables(struct smu_context *smu) if (!smu_table->clocks_table) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -470,14 +472,15 @@ static int smu_v14_0_0_read_sensor(struct smu_context *smu, static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v14_0_0_dpm_features.bits); } static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c index 3c351ee41e68..73762d9b5969 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c @@ -56,13 +56,13 @@ #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c)) -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ - FEATURE_MASK(FEATURE_DPM_FCLK_BIT)) +static const struct smu_feature_bits smu_v14_0_2_dpm_features = { + .bits = { SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT) } +}; #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000 #define DEBUGSMC_MSG_Mode1Reset 2 @@ -393,7 +393,7 @@ static int smu_v14_0_2_tables_init(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetricsExternal_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetricsExternal_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; @@ -404,7 +404,7 @@ static int smu_v14_0_2_tables_init(struct smu_context *smu) if (ret) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -428,8 +428,7 @@ static int smu_v14_0_2_allocate_dpm_context(struct smu_context *smu) { struct smu_dpm_context *smu_dpm = &smu->smu_dpm; - smu_dpm->dpm_context = kzalloc(sizeof(struct smu_14_0_dpm_context), - GFP_KERNEL); + smu_dpm->dpm_context = kzalloc_obj(struct smu_14_0_dpm_context); if (!smu_dpm->dpm_context) return -ENOMEM; @@ -589,13 +588,14 @@ static int smu_v14_0_2_set_default_dpm_table(struct smu_context *smu) static bool smu_v14_0_2_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v14_0_2_dpm_features.bits); } static uint32_t smu_v14_0_2_get_throttler_status(SmuMetrics_t *metrics) @@ -1875,7 +1875,7 @@ static int smu_v14_0_2_i2c_xfer(struct i2c_adapter *i2c_adap, if (!adev->pm.dpm_enabled) return -EBUSY; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2311,7 +2311,8 @@ static int smu_v14_0_2_restore_user_od_settings(struct smu_context *smu) user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) | BIT(PP_OD_FEATURE_UCLK_BIT) | BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) | - BIT(PP_OD_FEATURE_FAN_CURVE_BIT); + BIT(PP_OD_FEATURE_FAN_CURVE_BIT) | + BIT(PP_OD_FEATURE_ZERO_FAN_BIT); res = smu_v14_0_2_upload_overdrive_table(smu, user_od_table); user_od_table->OverDriveTable.FeatureCtrlMask = 0; if (res == 0) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c index d77eaac556d9..3fd84dd85e9b 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0.c @@ -408,7 +408,7 @@ int smu_v15_0_init_smc_tables(struct smu_context *smu) } smu_table->max_sustainable_clocks = - kzalloc(sizeof(struct smu_15_0_max_sustainable_clocks), GFP_KERNEL); + kzalloc_obj(struct smu_15_0_max_sustainable_clocks); if (!smu_table->max_sustainable_clocks) { ret = -ENOMEM; goto err1_out; @@ -507,8 +507,7 @@ int smu_v15_0_init_power(struct smu_context *smu) if (smu_power->power_context || smu_power->power_context_size != 0) return -EINVAL; - smu_power->power_context = kzalloc(sizeof(struct smu_15_0_dpm_context), - GFP_KERNEL); + smu_power->power_context = kzalloc_obj(struct smu_15_0_dpm_context); if (!smu_power->power_context) return -ENOMEM; smu_power->power_context_size = sizeof(struct smu_15_0_dpm_context); @@ -716,7 +715,7 @@ int smu_v15_0_set_allowed_mask(struct smu_context *smu) uint32_t feature_mask[2]; if (smu_feature_list_is_empty(smu, SMU_FEATURE_LIST_ALLOWED) || - feature->feature_num < 64) + feature->feature_num < SMU_FEATURE_NUM_DEFAULT) return -EINVAL; smu_feature_list_to_arr32(smu, SMU_FEATURE_LIST_ALLOWED, feature_mask); @@ -1726,14 +1725,6 @@ int smu_v15_0_set_gfx_power_up_by_imu(struct smu_context *smu) return ret; } -int smu_v15_0_set_default_dpm_tables(struct smu_context *smu) -{ - struct smu_table_context *smu_table = &smu->smu_table; - - return smu_cmn_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, - smu_table->clocks_table, false); -} - int smu_v15_0_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c index b48444706c1e..49cf2b9d931e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_0_ppt.c @@ -52,37 +52,32 @@ #define mmMP1_SMN_C2PMSG_32 0x0060 #define mmMP1_SMN_C2PMSG_32_BASE_IDX 1 -/* MALLPowerController message arguments (Defines for the Cache mode control) */ -#define SMU_MALL_PMFW_CONTROL 0 -#define SMU_MALL_DRIVER_CONTROL 1 +#define mmMP1_SMN_C2PMSG_33 0x0061 +#define mmMP1_SMN_C2PMSG_33_BASE_IDX 1 -/* - * MALLPowerState message arguments - * (Defines for the Allocate/Release Cache mode if in driver mode) - */ -#define SMU_MALL_EXIT_PG 0 -#define SMU_MALL_ENTER_PG 1 - -#define SMU_MALL_PG_CONFIG_DEFAULT SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON +#define mmMP1_SMN_C2PMSG_34 0x0062 +#define mmMP1_SMN_C2PMSG_34_BASE_IDX 1 #define SMU_15_0_UMD_PSTATE_GFXCLK 700 #define SMU_15_0_UMD_PSTATE_SOCCLK 678 #define SMU_15_0_UMD_PSTATE_FCLK 1800 -#define FEATURE_MASK(feature) (1ULL << feature) -#define SMC_DPM_FEATURE ( \ - FEATURE_MASK(FEATURE_CCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VCN_DPM_BIT) | \ - FEATURE_MASK(FEATURE_FCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SOCCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_LCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_SHUBCLK_DPM_BIT) | \ - FEATURE_MASK(FEATURE_DCFCLK_DPM_BIT)| \ - FEATURE_MASK(FEATURE_ISP_DPM_BIT)| \ - FEATURE_MASK(FEATURE_NPU_DPM_BIT) | \ - FEATURE_MASK(FEATURE_GFX_DPM_BIT) | \ - FEATURE_MASK(FEATURE_VPE_DPM_BIT)) +static const struct smu_feature_bits smu_v15_0_0_dpm_features = { + .bits = { + SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_ISP_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_NPU_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT), + SMU_FEATURE_BIT_INIT(FEATURE_VPE_DPM_BIT) + } +}; enum smu_mall_pg_config { SMU_MALL_PG_CONFIG_PMFW_CONTROL = 0, @@ -178,16 +173,16 @@ static int smu_v15_0_0_init_smc_tables(struct smu_context *smu) SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t), PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); - smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL); + smu_table->metrics_table = kzalloc_obj(SmuMetrics_t); if (!smu_table->metrics_table) goto err0_out; smu_table->metrics_time = 0; - smu_table->clocks_table = kzalloc(sizeof(DpmClocks_t), GFP_KERNEL); + smu_table->clocks_table = kzalloc_obj(DpmClocks_t); if (!smu_table->clocks_table) goto err1_out; - smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); + smu_table->watermarks_table = kzalloc_obj(Watermarks_t); if (!smu_table->watermarks_table) goto err2_out; @@ -238,6 +233,102 @@ static int smu_v15_0_0_system_features_control(struct smu_context *smu, bool en) return ret; } +static int smu_v15_0_0_update_table(struct smu_context *smu, + enum smu_table_id table_index, + int argument, + void *table_data, + bool drv2smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + struct amdgpu_device *adev = smu->adev; + struct smu_table *table = &smu_table->driver_table; + int table_id = smu_cmn_to_asic_specific_index(smu, + CMN2ASIC_MAPPING_TABLE, + table_index); + uint64_t address; + uint32_t table_size; + int ret; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + if (!table_data || table_index >= SMU_TABLE_COUNT || table_id < 0) + return -EINVAL; + + table_size = smu_table->tables[table_index].size; + + if (drv2smu) { + memcpy(table->cpu_addr, table_data, table_size); + /* + * Flush hdp cache: to guard the content seen by + * GPU is consitent with CPU. + */ + amdgpu_hdp_flush(adev, NULL); + } + + address = table->mc_address; + + struct smu_msg_args args = { + .msg = drv2smu ? + SMU_MSG_TransferTableDram2Smu : + SMU_MSG_TransferTableSmu2Dram, + .num_args = 3, + .num_out_args = 0, + }; + + args.args[0] = table_id; + args.args[1] = (uint32_t)lower_32_bits(address); + args.args[2] = (uint32_t)upper_32_bits(address); + + ret = ctl->ops->send_msg(ctl, &args); + + if (ret) + return ret; + + if (!drv2smu) { + amdgpu_hdp_invalidate(adev, NULL); + memcpy(table_data, table->cpu_addr, table_size); + } + + return 0; +} + +static int smu_v15_0_0_set_default_dpm_tables(struct smu_context *smu) +{ + struct smu_table_context *smu_table = &smu->smu_table; + + return smu_v15_0_0_update_table(smu, SMU_TABLE_DPMCLOCKS, 0, + smu_table->clocks_table, false); +} + +static int smu_v15_0_0_get_metrics_table(struct smu_context *smu, + void *metrics_table, + bool bypass_cache) +{ + struct smu_table_context *smu_table = &smu->smu_table; + uint32_t table_size = + smu_table->tables[SMU_TABLE_SMU_METRICS].size; + int ret; + + if (bypass_cache || + !smu_table->metrics_time || + time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) { + ret = smu_v15_0_0_update_table(smu, + SMU_TABLE_SMU_METRICS, + 0, + smu_table->metrics_table, + false); + if (ret) { + dev_info(smu->adev->dev, "Failed to export SMU15_0_0 metrics table!\n"); + return ret; + } + smu_table->metrics_time = jiffies; + } + + if (metrics_table) + memcpy(metrics_table, smu_table->metrics_table, table_size); + + return 0; +} + static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, MetricsMember_t member, uint32_t *value) @@ -247,7 +338,7 @@ static int smu_v15_0_0_get_smu_metrics_data(struct smu_context *smu, SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table; int ret = 0; - ret = smu_cmn_get_metrics_table(smu, NULL, false); + ret = smu_v15_0_0_get_metrics_table(smu, NULL, false); if (ret) return ret; @@ -441,17 +532,42 @@ static int smu_v15_0_0_read_sensor(struct smu_context *smu, return ret; } +static int smu_v15_0_0_get_enabled_mask(struct smu_context *smu, + struct smu_feature_bits *feature_mask) +{ + int ret; + struct smu_msg_ctl *ctl = &smu->msg_ctl; + + if (!feature_mask) + return -EINVAL; + + struct smu_msg_args args = { + .msg = SMU_MSG_GetEnabledSmuFeatures, + .num_args = 0, + .num_out_args = 2, + }; + + ret = ctl->ops->send_msg(ctl, &args); + + if (!ret) + smu_feature_bits_from_arr32(feature_mask, args.out_args, + SMU_FEATURE_NUM_DEFAULT); + + return ret; +} + static bool smu_v15_0_0_is_dpm_running(struct smu_context *smu) { int ret = 0; - uint64_t feature_enabled; + struct smu_feature_bits feature_enabled; - ret = smu_cmn_get_enabled_mask(smu, &feature_enabled); + ret = smu_v15_0_0_get_enabled_mask(smu, &feature_enabled); if (ret) return false; - return !!(feature_enabled & SMC_DPM_FEATURE); + return smu_feature_bits_test_mask(&feature_enabled, + smu_v15_0_0_dpm_features.bits); } static int smu_v15_0_0_set_watermarks_table(struct smu_context *smu, @@ -521,7 +637,7 @@ static ssize_t smu_v15_0_0_get_gpu_metrics(struct smu_context *smu, SmuMetrics_t metrics; int ret = 0; - ret = smu_cmn_get_metrics_table(smu, &metrics, true); + ret = smu_v15_0_0_get_metrics_table(smu, &metrics, false); if (ret) return ret; @@ -976,26 +1092,21 @@ static int smu_v15_0_0_set_soft_freq_limited_range(struct smu_context *smu, switch (clk_type) { case SMU_GFXCLK: case SMU_SCLK: - msg_set_min = SMU_MSG_SetHardMinGfxClk; + msg_set_min = SMU_MSG_SetSoftMinGfxclk; msg_set_max = SMU_MSG_SetSoftMaxGfxClk; break; case SMU_FCLK: - msg_set_min = SMU_MSG_SetHardMinFclkByFreq; + msg_set_min = SMU_MSG_SetSoftMinFclk; msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq; break; case SMU_SOCCLK: - msg_set_min = SMU_MSG_SetHardMinSocclkByFreq; + msg_set_min = SMU_MSG_SetSoftMinSocclkByFreq; msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq; break; case SMU_VCLK: case SMU_DCLK: - msg_set_min = SMU_MSG_SetHardMinVcn0; - msg_set_max = SMU_MSG_SetSoftMaxVcn0; - break; - case SMU_VCLK1: - case SMU_DCLK1: - msg_set_min = SMU_MSG_SetHardMinVcn1; - msg_set_max = SMU_MSG_SetSoftMaxVcn1; + msg_set_min = SMU_MSG_SetSoftMinVcn; + msg_set_max = SMU_MSG_SetSoftMaxVcn; break; default: return -EINVAL; @@ -1312,14 +1423,13 @@ static const struct pptable_funcs smu_v15_0_0_ppt_funcs = { .system_features_control = smu_v15_0_0_system_features_control, .dpm_set_vcn_enable = smu_v15_0_set_vcn_enable, .dpm_set_jpeg_enable = smu_v15_0_set_jpeg_enable, - .set_default_dpm_table = smu_v15_0_set_default_dpm_tables, + .set_default_dpm_table = smu_v15_0_0_set_default_dpm_tables, .read_sensor = smu_v15_0_0_read_sensor, .is_dpm_running = smu_v15_0_0_is_dpm_running, .set_watermarks_table = smu_v15_0_0_set_watermarks_table, .get_gpu_metrics = smu_v15_0_0_get_gpu_metrics, - .get_enabled_mask = smu_cmn_get_enabled_mask, + .get_enabled_mask = smu_v15_0_0_get_enabled_mask, .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, - .set_driver_table_location = smu_v15_0_set_driver_table_location, .gfx_off_control = smu_v15_0_gfx_off_control, .mode2_reset = smu_v15_0_0_mode2_reset, .get_dpm_ultimate_freq = smu_v15_0_common_get_dpm_ultimate_freq, @@ -1344,7 +1454,9 @@ static void smu_v15_0_0_init_msg_ctl(struct smu_context *smu) ctl->config.msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_30); ctl->config.resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_31); ctl->config.arg_regs[0] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_32); - ctl->config.num_arg_regs = 1; + ctl->config.arg_regs[1] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_33); + ctl->config.arg_regs[2] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_34); + ctl->config.num_arg_regs = 3; ctl->ops = &smu_msg_v1_ops; ctl->default_timeout = adev->usec_timeout * 20; ctl->message_map = smu_v15_0_0_message_map; diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c index 9bb7e3760c0f..6fd50c2fd20e 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c @@ -690,7 +690,7 @@ int smu_cmn_feature_is_supported(struct smu_context *smu, } static int __smu_get_enabled_features(struct smu_context *smu, - uint64_t *enabled_features) + struct smu_feature_bits *enabled_features) { return smu_cmn_call_asic_func(get_enabled_mask, smu, enabled_features); } @@ -699,7 +699,7 @@ int smu_cmn_feature_is_enabled(struct smu_context *smu, enum smu_feature_mask mask) { struct amdgpu_device *adev = smu->adev; - uint64_t enabled_features; + struct smu_feature_bits enabled_features; int feature_id; if (__smu_get_enabled_features(smu, &enabled_features)) { @@ -712,7 +712,8 @@ int smu_cmn_feature_is_enabled(struct smu_context *smu, * enabled. Also considering they have no feature_map available, the * check here can avoid unwanted feature_map check below. */ - if (enabled_features == ULLONG_MAX) + if (smu_feature_bits_full(&enabled_features, + smu->smu_feature.feature_num)) return 1; feature_id = smu_cmn_to_asic_specific_index(smu, @@ -721,7 +722,7 @@ int smu_cmn_feature_is_enabled(struct smu_context *smu, if (feature_id < 0) return 0; - return test_bit(feature_id, (unsigned long *)&enabled_features); + return smu_feature_bits_is_set(&enabled_features, feature_id); } bool smu_cmn_clk_dpm_is_enabled(struct smu_context *smu, @@ -763,45 +764,39 @@ bool smu_cmn_clk_dpm_is_enabled(struct smu_context *smu, } int smu_cmn_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask) + struct smu_feature_bits *feature_mask) { - uint32_t *feature_mask_high; - uint32_t *feature_mask_low; + uint32_t features[2]; int ret = 0, index = 0; if (!feature_mask) return -EINVAL; - feature_mask_low = &((uint32_t *)feature_mask)[0]; - feature_mask_high = &((uint32_t *)feature_mask)[1]; - index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG, SMU_MSG_GetEnabledSmuFeatures); if (index > 0) { - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetEnabledSmuFeatures, - 0, - feature_mask_low); + ret = smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_GetEnabledSmuFeatures, 0, &features[0]); if (ret) return ret; - ret = smu_cmn_send_smc_msg_with_param(smu, - SMU_MSG_GetEnabledSmuFeatures, - 1, - feature_mask_high); + ret = smu_cmn_send_smc_msg_with_param( + smu, SMU_MSG_GetEnabledSmuFeatures, 1, &features[1]); } else { - ret = smu_cmn_send_smc_msg(smu, - SMU_MSG_GetEnabledSmuFeaturesHigh, - feature_mask_high); + ret = smu_cmn_send_smc_msg( + smu, SMU_MSG_GetEnabledSmuFeaturesHigh, &features[1]); if (ret) return ret; - ret = smu_cmn_send_smc_msg(smu, - SMU_MSG_GetEnabledSmuFeaturesLow, - feature_mask_low); + ret = smu_cmn_send_smc_msg( + smu, SMU_MSG_GetEnabledSmuFeaturesLow, &features[0]); } + if (!ret) + smu_feature_bits_from_arr32(feature_mask, features, + SMU_FEATURE_NUM_DEFAULT); + return ret; } @@ -886,7 +881,8 @@ size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu, char *buf) { int8_t sort_feature[MAX(SMU_FEATURE_COUNT, SMU_FEATURE_MAX)]; - uint64_t feature_mask; + struct smu_feature_bits feature_mask; + uint32_t features[2]; int i, feature_index; uint32_t count = 0; size_t size = 0; @@ -894,8 +890,10 @@ size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu, if (__smu_get_enabled_features(smu, &feature_mask)) return 0; - size = sysfs_emit_at(buf, size, "features high: 0x%08x low: 0x%08x\n", - upper_32_bits(feature_mask), lower_32_bits(feature_mask)); + /* TBD: Need to handle for > 64 bits */ + smu_feature_bits_to_arr32(&feature_mask, features, 64); + size = sysfs_emit_at(buf, size, "features high: 0x%08x low: 0x%08x\n", + features[1], features[0]); memset(sort_feature, -1, sizeof(sort_feature)); @@ -912,16 +910,18 @@ size_t smu_cmn_get_pp_feature_mask(struct smu_context *smu, size += sysfs_emit_at(buf, size, "%-2s. %-20s %-3s : %-s\n", "No", "Feature", "Bit", "State"); - for (feature_index = 0; feature_index < SMU_FEATURE_MAX; feature_index++) { + for (feature_index = 0; feature_index < smu->smu_feature.feature_num; + feature_index++) { if (sort_feature[feature_index] < 0) continue; - size += sysfs_emit_at(buf, size, "%02d. %-20s (%2d) : %s\n", - count++, - smu_get_feature_name(smu, sort_feature[feature_index]), - feature_index, - !!test_bit(feature_index, (unsigned long *)&feature_mask) ? - "enabled" : "disabled"); + size += sysfs_emit_at( + buf, size, "%02d. %-20s (%2d) : %s\n", count++, + smu_get_feature_name(smu, sort_feature[feature_index]), + feature_index, + smu_feature_bits_is_set(&feature_mask, feature_index) ? + "enabled" : + "disabled"); } return size; @@ -931,7 +931,8 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu, uint64_t new_mask) { int ret = 0; - uint64_t feature_mask; + struct smu_feature_bits feature_mask; + uint64_t feature_mask_u64; uint64_t feature_2_enabled = 0; uint64_t feature_2_disabled = 0; @@ -939,8 +940,9 @@ int smu_cmn_set_pp_feature_mask(struct smu_context *smu, if (ret) return ret; - feature_2_enabled = ~feature_mask & new_mask; - feature_2_disabled = feature_mask & ~new_mask; + feature_mask_u64 = *(uint64_t *)feature_mask.bits; + feature_2_enabled = ~feature_mask_u64 & new_mask; + feature_2_disabled = feature_mask_u64 & ~new_mask; if (feature_2_enabled) { ret = smu_cmn_feature_update_enable_state(smu, diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h index 92ad2ece7a36..b7bfddc65fb2 100644 --- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h +++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h @@ -141,7 +141,7 @@ bool smu_cmn_clk_dpm_is_enabled(struct smu_context *smu, enum smu_clk_type clk_type); int smu_cmn_get_enabled_mask(struct smu_context *smu, - uint64_t *feature_mask); + struct smu_feature_bits *feature_mask); uint64_t smu_cmn_get_indep_throttler_status( const unsigned long dep_status, diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c index 59c063625920..9190c9cd7993 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_ras_mgr.c @@ -299,7 +299,7 @@ static int amdgpu_ras_mgr_sw_init(struct amdgpu_ip_block *ip_block) if (!con->uniras_enabled) return 0; - ras_mgr = kzalloc(sizeof(*ras_mgr), GFP_KERNEL); + ras_mgr = kzalloc_obj(*ras_mgr); if (!ras_mgr) return -EINVAL; diff --git a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c index a75479593864..de197ae4b37f 100644 --- a/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c +++ b/drivers/gpu/drm/amd/ras/ras_mgr/amdgpu_virt_ras_cmd.c @@ -195,7 +195,7 @@ static int amdgpu_virt_ras_get_cper_records(struct ras_core_context *ras_core, if (!req->buf_size || !req->buf_ptr || !req->cper_num) return RAS_CMD__ERROR_INVALID_INPUT_DATA; - trace = kcalloc(MAX_RECORD_PER_BATCH, sizeof(*trace), GFP_KERNEL); + trace = kzalloc_objs(*trace, MAX_RECORD_PER_BATCH); if (!trace) return RAS_CMD__ERROR_GENERIC; @@ -365,7 +365,7 @@ int amdgpu_virt_ras_sw_init(struct amdgpu_device *adev) { struct amdgpu_ras_mgr *ras_mgr = amdgpu_ras_mgr_get_context(adev); - ras_mgr->virt_ras_cmd = kzalloc(sizeof(struct amdgpu_virt_ras_cmd), GFP_KERNEL); + ras_mgr->virt_ras_cmd = kzalloc_obj(struct amdgpu_virt_ras_cmd); if (!ras_mgr->virt_ras_cmd) return -ENOMEM; diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_aca_v1_0.c b/drivers/gpu/drm/amd/ras/rascore/ras_aca_v1_0.c index 29df98948703..210fbd8851a6 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_aca_v1_0.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_aca_v1_0.c @@ -299,7 +299,7 @@ static int aca_parse_xgmi_bank(struct ras_core_context *ras_core, count = ACA_REG_MISC0_ERRCNT(bank->regs[ACA_REG_IDX__MISC0]); if (bank->ecc_type == RAS_ERR_TYPE__UE) { - if (ext_error_code != 0 && ext_error_code != 9) + if (ext_error_code != 0 && ext_error_code != 1 && ext_error_code != 9) count = 0ULL; ecc->ue_count = count; } else if (bank->ecc_type == RAS_ERR_TYPE__CE) { diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_core.c b/drivers/gpu/drm/amd/ras/rascore/ras_core.c index f2fccdf5e329..3f56f26abd6d 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_core.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_core.c @@ -263,11 +263,11 @@ struct ras_core_context *ras_core_create(struct ras_core_config *init_config) struct ras_core_context *ras_core; struct ras_core_config *config; - ras_core = kzalloc(sizeof(*ras_core), GFP_KERNEL); + ras_core = kzalloc_obj(*ras_core); if (!ras_core) return NULL; - config = kzalloc(sizeof(*config), GFP_KERNEL); + config = kzalloc_obj(*config); if (!config) { kfree(ras_core); return NULL; diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c b/drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c index 0a838fdcb2f6..f10e856f3c8c 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_log_ring.c @@ -202,7 +202,7 @@ struct ras_log_batch_tag *ras_log_ring_create_batch_tag(struct ras_core_context struct ras_log_batch_tag *batch_tag; unsigned long flags = 0; - batch_tag = kzalloc(sizeof(*batch_tag), GFP_KERNEL); + batch_tag = kzalloc_obj(*batch_tag); if (!batch_tag) return NULL; diff --git a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c index b19c26f6feaf..2abe8553e479 100644 --- a/drivers/gpu/drm/amd/ras/rascore/ras_umc.c +++ b/drivers/gpu/drm/amd/ras/rascore/ras_umc.c @@ -199,7 +199,7 @@ int ras_umc_log_bad_bank_pending(struct ras_core_context *ras_core, struct ras_b struct ras_umc *ras_umc = &ras_core->ras_umc; struct ras_bank_ecc_node *ecc_node; - ecc_node = kzalloc(sizeof(*ecc_node), GFP_KERNEL); + ecc_node = kzalloc_obj(*ecc_node); if (!ecc_node) return -ENOMEM; @@ -246,7 +246,7 @@ int ras_umc_log_bad_bank(struct ras_core_context *ras_core, struct ras_bank_ecc if (ret) goto out; - err_rec = kzalloc(sizeof(*err_rec), GFP_KERNEL); + err_rec = kzalloc_obj(*err_rec); if (!err_rec) { ret = -ENOMEM; goto out; @@ -454,7 +454,7 @@ int ras_umc_load_bad_pages(struct ras_core_context *ras_core) ras_core->ras_eeprom.record_threshold_config == DISABLE_RETIRE_PAGE) return 0; - bps = kcalloc(ras_num_recs, sizeof(*bps), GFP_KERNEL); + bps = kzalloc_objs(*bps, ras_num_recs); if (!bps) return -ENOMEM; @@ -512,8 +512,7 @@ int ras_umc_handle_bad_pages(struct ras_core_context *ras_core, void *data) struct eeprom_umc_record *records; int count, ret; - records = kcalloc(MAX_ECC_NUM_PER_RETIREMENT, - sizeof(*records), GFP_KERNEL); + records = kzalloc_objs(*records, MAX_ECC_NUM_PER_RETIREMENT); if (!records) return -ENOMEM; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c index 5a66948ffd24..9c8b8da531a7 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_crtc.c @@ -503,7 +503,7 @@ static void komeda_crtc_reset(struct drm_crtc *crtc) kfree(to_kcrtc_st(crtc->state)); crtc->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -514,7 +514,7 @@ komeda_crtc_atomic_duplicate_state(struct drm_crtc *crtc) struct komeda_crtc_state *old = to_kcrtc_st(crtc->state); struct komeda_crtc_state *new; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c index 3ca461eb0a24..6ee909f8d534 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_framebuffer.c @@ -165,7 +165,7 @@ komeda_fb_create(struct drm_device *dev, struct drm_file *file, struct komeda_fb *kfb; int ret = 0, i; - kfb = kzalloc(sizeof(*kfb), GFP_KERNEL); + kfb = kzalloc_obj(*kfb); if (!kfb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c index c20ff72f0ae5..835c11fdd7ff 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_plane.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_plane.c @@ -142,7 +142,7 @@ static void komeda_plane_reset(struct drm_plane *plane) kfree(plane->state); plane->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_plane_reset(plane, &state->base); } @@ -155,7 +155,7 @@ komeda_plane_atomic_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; @@ -247,7 +247,7 @@ static int komeda_plane_add(struct komeda_kms_dev *kms, u32 *formats, n_formats = 0; int err; - kplane = kzalloc(sizeof(*kplane), GFP_KERNEL); + kplane = kzalloc_obj(*kplane); if (!kplane) return -ENOMEM; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c index 914400c4af73..ee57e306bf7b 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_private_obj.c @@ -50,7 +50,7 @@ static int komeda_layer_obj_add(struct komeda_kms_dev *kms, { struct komeda_layer_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -92,7 +92,7 @@ static int komeda_scaler_obj_add(struct komeda_kms_dev *kms, { struct komeda_scaler_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -135,7 +135,7 @@ static int komeda_compiz_obj_add(struct komeda_kms_dev *kms, { struct komeda_compiz_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -178,7 +178,7 @@ static int komeda_splitter_obj_add(struct komeda_kms_dev *kms, { struct komeda_splitter_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -221,7 +221,7 @@ static int komeda_merger_obj_add(struct komeda_kms_dev *kms, { struct komeda_merger_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -265,7 +265,7 @@ static int komeda_improc_obj_add(struct komeda_kms_dev *kms, { struct komeda_improc_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -308,7 +308,7 @@ static int komeda_timing_ctrlr_obj_add(struct komeda_kms_dev *kms, { struct komeda_compiz_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; @@ -352,7 +352,7 @@ static int komeda_pipeline_obj_add(struct komeda_kms_dev *kms, { struct komeda_pipeline_state *st; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index 875cdbff18c9..41cc3e080dc9 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -149,7 +149,7 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, if (!kcrtc->master->wb_layer) return 0; - kwb_conn = kzalloc(sizeof(*kwb_conn), GFP_KERNEL); + kwb_conn = kzalloc_obj(*kwb_conn); if (!kwb_conn) return -ENOMEM; diff --git a/drivers/gpu/drm/arm/malidp_crtc.c b/drivers/gpu/drm/arm/malidp_crtc.c index e61cf362abdf..18e6157b1047 100644 --- a/drivers/gpu/drm/arm/malidp_crtc.c +++ b/drivers/gpu/drm/arm/malidp_crtc.c @@ -447,7 +447,7 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) return NULL; old_state = to_malidp_crtc_state(crtc->state); - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; @@ -478,8 +478,7 @@ static void malidp_crtc_destroy_state(struct drm_crtc *crtc, static void malidp_crtc_reset(struct drm_crtc *crtc) { - struct malidp_crtc_state *state = - kzalloc(sizeof(*state), GFP_KERNEL); + struct malidp_crtc_state *state = kzalloc_obj(*state); if (crtc->state) malidp_crtc_destroy_state(crtc, crtc->state); diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index 47733c85d271..fad343842038 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -66,8 +66,7 @@ static const struct drm_connector_helper_funcs malidp_mw_connector_helper_funcs static void malidp_mw_connector_reset(struct drm_connector *connector) { - struct malidp_mw_connector_state *mw_state = - kzalloc(sizeof(*mw_state), GFP_KERNEL); + struct malidp_mw_connector_state *mw_state = kzalloc_obj(*mw_state); if (connector->state) __drm_atomic_helper_connector_destroy_state(connector->state); @@ -98,7 +97,7 @@ malidp_mw_connector_duplicate_state(struct drm_connector *connector) if (WARN_ON(!connector->state)) return NULL; - mw_state = kzalloc(sizeof(*mw_state), GFP_KERNEL); + mw_state = kzalloc_obj(*mw_state); if (!mw_state) return NULL; diff --git a/drivers/gpu/drm/arm/malidp_planes.c b/drivers/gpu/drm/arm/malidp_planes.c index f1a5014bcfa1..4b9876322501 100644 --- a/drivers/gpu/drm/arm/malidp_planes.c +++ b/drivers/gpu/drm/arm/malidp_planes.c @@ -81,7 +81,7 @@ static void malidp_plane_reset(struct drm_plane *plane) __drm_atomic_helper_plane_destroy_state(&state->base); kfree(state); plane->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_plane_reset(plane, &state->base); } @@ -94,7 +94,7 @@ drm_plane_state *malidp_duplicate_plane_state(struct drm_plane *plane) if (!plane->state) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c index 033b19b31f63..d40bb9cf9ff1 100644 --- a/drivers/gpu/drm/armada/armada_crtc.c +++ b/drivers/gpu/drm/armada/armada_crtc.c @@ -921,7 +921,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, if (IS_ERR(base)) return PTR_ERR(base); - dcrtc = kzalloc(sizeof(*dcrtc), GFP_KERNEL); + dcrtc = kzalloc_obj(*dcrtc); if (!dcrtc) { DRM_ERROR("failed to allocate Armada crtc\n"); return -ENOMEM; @@ -970,7 +970,7 @@ static int armada_drm_crtc_create(struct drm_device *drm, struct device *dev, dcrtc->crtc.port = port; - primary = kzalloc(sizeof(*primary), GFP_KERNEL); + primary = kzalloc_obj(*primary); if (!primary) { ret = -ENOMEM; goto err_crtc; diff --git a/drivers/gpu/drm/armada/armada_fb.c b/drivers/gpu/drm/armada/armada_fb.c index 77098928f821..b828bba419bf 100644 --- a/drivers/gpu/drm/armada/armada_fb.c +++ b/drivers/gpu/drm/armada/armada_fb.c @@ -57,7 +57,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev, return ERR_PTR(-EINVAL); } - dfb = kzalloc(sizeof(*dfb), GFP_KERNEL); + dfb = kzalloc_obj(*dfb); if (!dfb) { DRM_ERROR("failed to allocate Armada fb object\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/armada/armada_gem.c b/drivers/gpu/drm/armada/armada_gem.c index 35fcfa0d85ff..da7335cbe82d 100644 --- a/drivers/gpu/drm/armada/armada_gem.c +++ b/drivers/gpu/drm/armada/armada_gem.c @@ -137,7 +137,7 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj) void __iomem *ptr; int ret; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOSPC; @@ -200,7 +200,7 @@ armada_gem_alloc_private_object(struct drm_device *dev, size_t size) size = roundup_gem_size(size); - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; @@ -221,7 +221,7 @@ static struct armada_gem_object *armada_gem_alloc_object(struct drm_device *dev, size = roundup_gem_size(size); - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; @@ -393,7 +393,7 @@ armada_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, struct sg_table *sgt; int i; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return NULL; diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 21fd3b4ba10f..361fdcece4b0 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -310,7 +310,7 @@ static void armada_overlay_reset(struct drm_plane *plane) kfree(plane->state); plane->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) { state->colorkey_yr = 0xfefefe00; state->colorkey_ug = 0x01010100; @@ -550,7 +550,7 @@ int armada_overlay_plane_create(struct drm_device *dev, unsigned long crtcs) if (ret) return ret; - overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kzalloc_obj(*overlay); if (!overlay) return -ENOMEM; diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c index a0326b4f568e..eba12bba1e09 100644 --- a/drivers/gpu/drm/armada/armada_plane.c +++ b/drivers/gpu/drm/armada/armada_plane.c @@ -262,7 +262,7 @@ void armada_plane_reset(struct drm_plane *plane) if (plane->state) __drm_atomic_helper_plane_destroy_state(plane->state); kfree(plane->state); - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (st) __drm_atomic_helper_plane_reset(plane, &st->base); } diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index 8e650a02c528..9d07dad358cf 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -479,8 +479,7 @@ static const struct drm_connector_helper_funcs ast_astdp_connector_helper_funcs static void ast_astdp_connector_reset(struct drm_connector *connector) { - struct ast_astdp_connector_state *astdp_state = - kzalloc(sizeof(*astdp_state), GFP_KERNEL); + struct ast_astdp_connector_state *astdp_state = kzalloc_obj(*astdp_state); if (connector->state) connector->funcs->atomic_destroy_state(connector, connector->state); @@ -500,7 +499,7 @@ ast_astdp_connector_atomic_duplicate_state(struct drm_connector *connector) if (drm_WARN_ON(dev, !connector->state)) return NULL; - new_astdp_state = kmalloc(sizeof(*new_astdp_state), GFP_KERNEL); + new_astdp_state = kmalloc_obj(*new_astdp_state); if (!new_astdp_state) return NULL; __drm_atomic_helper_connector_duplicate_state(connector, &new_astdp_state->base); diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 57c6fbc3232b..21abb6a6d8bc 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -876,8 +876,7 @@ static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = { static void ast_crtc_reset(struct drm_crtc *crtc) { - struct ast_crtc_state *ast_state = - kzalloc(sizeof(*ast_state), GFP_KERNEL); + struct ast_crtc_state *ast_state = kzalloc_obj(*ast_state); if (crtc->state) crtc->funcs->atomic_destroy_state(crtc, crtc->state); @@ -897,7 +896,7 @@ ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc) if (drm_WARN_ON(dev, !crtc->state)) return NULL; - new_ast_state = kmalloc(sizeof(*new_ast_state), GFP_KERNEL); + new_ast_state = kmalloc_obj(*new_ast_state); if (!new_ast_state) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &new_ast_state->base); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index b075f291847f..d8cf3d231920 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -540,7 +540,7 @@ static void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) crtc->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -554,7 +554,7 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) if (WARN_ON(!crtc->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index c52da47982ee..bccd1564216e 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -1194,7 +1194,7 @@ static void atmel_hlcdc_plane_reset(struct drm_plane *p) p->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) { if (atmel_hlcdc_plane_alloc_dscrs(p, state)) { kfree(state); diff --git a/drivers/gpu/drm/bridge/aux-bridge.c b/drivers/gpu/drm/bridge/aux-bridge.c index b3e4cdff61d6..1ed21a8713bf 100644 --- a/drivers/gpu/drm/bridge/aux-bridge.c +++ b/drivers/gpu/drm/bridge/aux-bridge.c @@ -47,7 +47,7 @@ int drm_aux_bridge_register(struct device *parent) struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; diff --git a/drivers/gpu/drm/bridge/aux-hpd-bridge.c b/drivers/gpu/drm/bridge/aux-hpd-bridge.c index 2e9c702c7087..f02a38a2638a 100644 --- a/drivers/gpu/drm/bridge/aux-hpd-bridge.c +++ b/drivers/gpu/drm/bridge/aux-hpd-bridge.c @@ -52,7 +52,7 @@ struct auxiliary_device *devm_drm_dp_hpd_bridge_alloc(struct device *parent, str struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 09b289f0fcbf..0dd85e26248c 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -902,7 +902,7 @@ static u32 *cdns_dsi_bridge_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 0; - input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kzalloc_obj(*input_fmts); if (!input_fmts) return NULL; @@ -985,7 +985,7 @@ cdns_dsi_bridge_atomic_duplicate_state(struct drm_bridge *bridge) bridge_state = drm_priv_to_bridge_state(bridge->base.state); old_dsi_state = to_cdns_dsi_bridge_state(bridge_state); - dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL); + dsi_state = kzalloc_obj(*dsi_state); if (!dsi_state) return NULL; @@ -1013,7 +1013,7 @@ cdns_dsi_bridge_atomic_reset(struct drm_bridge *bridge) { struct cdns_dsi_bridge_state *dsi_state; - dsi_state = kzalloc(sizeof(*dsi_state), GFP_KERNEL); + dsi_state = kzalloc_obj(*dsi_state); if (!dsi_state) return NULL; diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c index 38726ae1bf15..9392c226ff5b 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c @@ -2055,7 +2055,7 @@ cdns_mhdp_bridge_atomic_duplicate_state(struct drm_bridge *bridge) { struct cdns_mhdp_bridge_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; @@ -2085,7 +2085,7 @@ cdns_mhdp_bridge_atomic_reset(struct drm_bridge *bridge) { struct cdns_mhdp_bridge_state *cdns_mhdp_state; - cdns_mhdp_state = kzalloc(sizeof(*cdns_mhdp_state), GFP_KERNEL); + cdns_mhdp_state = kzalloc_obj(*cdns_mhdp_state); if (!cdns_mhdp_state) return NULL; @@ -2105,7 +2105,7 @@ static u32 *cdns_mhdp_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 0; - input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kzalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c index e9f16dbc9535..16c0631adeb1 100644 --- a/drivers/gpu/drm/bridge/display-connector.c +++ b/drivers/gpu/drm/bridge/display-connector.c @@ -116,7 +116,7 @@ static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge, u32 *out_bus_fmts; *num_output_fmts = 1; - out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); + out_bus_fmts = kmalloc_obj(*out_bus_fmts); if (!out_bus_fmts) return NULL; @@ -158,7 +158,7 @@ static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge, u32 *in_bus_fmts; *num_input_fmts = 1; - in_bus_fmts = kmalloc(sizeof(*in_bus_fmts), GFP_KERNEL); + in_bus_fmts = kmalloc_obj(*in_bus_fmts); if (!in_bus_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c index fc67e7ed653d..bdecee56fa49 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qm-ldb.c @@ -319,7 +319,7 @@ imx8qm_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c index ada11eed13cf..fbd7a37c0812 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-ldb.c @@ -333,7 +333,7 @@ imx8qxp_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c index 27ad66f240cf..5582456a4490 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-combiner.c @@ -216,7 +216,7 @@ imx8qxp_pc_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c index 433c080197a2..b52b7c7ce183 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pixel-link.c @@ -206,7 +206,7 @@ imx8qxp_pixel_link_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c index 9dc2b3d2ecef..441fd32dc91c 100644 --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c @@ -175,7 +175,7 @@ imx8qxp_pxl2dpi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c index 8f7a0d46601a..8f312f9edf97 100644 --- a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -609,7 +609,7 @@ static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data, return NULL; } - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; input_fmts[0] = input_fmt; diff --git a/drivers/gpu/drm/bridge/ite-it6263.c b/drivers/gpu/drm/bridge/ite-it6263.c index 3991fb76143c..e77681047bb2 100644 --- a/drivers/gpu/drm/bridge/ite-it6263.c +++ b/drivers/gpu/drm/bridge/ite-it6263.c @@ -735,7 +735,7 @@ it6263_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, if (!it6263_is_input_bus_fmt_valid(it->lvds_data_mapping)) return NULL; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 1d85e706c74b..ec632f268644 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1741,7 +1741,7 @@ samsung_dsim_atomic_get_input_bus_fmts(struct drm_bridge *bridge, { u32 *input_fmts; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; @@ -1881,6 +1881,14 @@ static int samsung_dsim_register_te_irq(struct samsung_dsim *dsi, struct device return 0; } +static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi) +{ + if (dsi->te_gpio) { + free_irq(gpiod_to_irq(dsi->te_gpio), dsi); + gpiod_put(dsi->te_gpio); + } +} + static int samsung_dsim_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { @@ -1961,7 +1969,7 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host, if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) { ret = samsung_dsim_register_te_irq(dsi, &device->dev); if (ret) - return ret; + goto err_remove_bridge; } // The next bridge can be used by host_ops->attach @@ -1982,15 +1990,12 @@ static int samsung_dsim_host_attach(struct mipi_dsi_host *host, err_release_next_bridge: drm_bridge_put(dsi->bridge.next_bridge); dsi->bridge.next_bridge = NULL; - return ret; -} -static void samsung_dsim_unregister_te_irq(struct samsung_dsim *dsi) -{ - if (dsi->te_gpio) { - free_irq(gpiod_to_irq(dsi->te_gpio), dsi); - gpiod_put(dsi->te_gpio); - } + if (!(device->mode_flags & MIPI_DSI_MODE_VIDEO)) + samsung_dsim_unregister_te_irq(dsi); +err_remove_bridge: + drm_bridge_remove(&dsi->bridge); + return ret; } static int samsung_dsim_host_detach(struct mipi_dsi_host *host, diff --git a/drivers/gpu/drm/bridge/sil-sii8620.c b/drivers/gpu/drm/bridge/sil-sii8620.c index 9e48ad39e1cc..d3f238b1f2a9 100644 --- a/drivers/gpu/drm/bridge/sil-sii8620.c +++ b/drivers/gpu/drm/bridge/sil-sii8620.c @@ -384,7 +384,7 @@ static void sii8620_mt_msc_cmd_send(struct sii8620 *ctx, static struct sii8620_mt_msg *sii8620_mt_msg_new(struct sii8620 *ctx) { - struct sii8620_mt_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL); + struct sii8620_mt_msg *msg = kzalloc_obj(*msg); if (!msg) ctx->error = -ENOMEM; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-dp.c b/drivers/gpu/drm/bridge/synopsys/dw-dp.c index 432342452484..fd23ca2834b0 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-dp.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-dp.c @@ -1809,7 +1809,7 @@ static struct drm_bridge_state *dw_dp_bridge_atomic_duplicate_state(struct drm_b { struct dw_dp_bridge_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; @@ -2049,7 +2049,9 @@ struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder, bridge->type = DRM_MODE_CONNECTOR_DisplayPort; bridge->ycbcr_420_allowed = true; - devm_drm_bridge_add(dev, bridge); + ret = devm_drm_bridge_add(dev, bridge); + if (ret) + return ERR_PTR(ret); dp->aux.dev = dev; dp->aux.drm_dev = encoder->dev; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 8fc2e282ff11..ca4dea226f4b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -561,7 +561,7 @@ dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, output_fmt, num_input_fmts); /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */ - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; input_fmts[0] = MEDIA_BUS_FMT_FIXED; diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c index 5926a3a05d79..e6eaf9fd0251 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi2.c @@ -711,7 +711,7 @@ dw_mipi_dsi2_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, output_fmt, num_input_fmts); /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */ - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; input_fmts[0] = MEDIA_BUS_FMT_FIXED; diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi83.c b/drivers/gpu/drm/bridge/ti-sn65dsi83.c index f6736b4457bb..17a885244e1e 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c @@ -351,9 +351,9 @@ static u8 sn65dsi83_get_dsi_range(struct sn65dsi83 *ctx, * DSI_CLK = mode clock * bpp / dsi_data_lanes / 2 * the 2 is there because the bus is DDR. */ - return DIV_ROUND_UP(clamp((unsigned int)mode->clock * - mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) / - ctx->dsi->lanes / 2, 40000U, 500000U), 5000U); + return clamp((unsigned int)mode->clock * + mipi_dsi_pixel_format_to_bpp(ctx->dsi->format) / + ctx->dsi->lanes / 2, 40000U, 500000U) / 5000U; } static u8 sn65dsi83_get_dsi_div(struct sn65dsi83 *ctx) @@ -517,6 +517,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, struct drm_atomic_state *state) { struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge); + const unsigned int dual_factor = ctx->lvds_dual_link ? 2 : 1; const struct drm_bridge_state *bridge_state; const struct drm_crtc_state *crtc_state; const struct drm_display_mode *mode; @@ -653,18 +654,18 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, /* 32 + 1 pixel clock to ensure proper operation */ le16val = cpu_to_le16(32 + 1); regmap_bulk_write(ctx->regmap, REG_VID_CHA_SYNC_DELAY_LOW, &le16val, 2); - le16val = cpu_to_le16(mode->hsync_end - mode->hsync_start); + le16val = cpu_to_le16((mode->hsync_end - mode->hsync_start) / dual_factor); regmap_bulk_write(ctx->regmap, REG_VID_CHA_HSYNC_PULSE_WIDTH_LOW, &le16val, 2); le16val = cpu_to_le16(mode->vsync_end - mode->vsync_start); regmap_bulk_write(ctx->regmap, REG_VID_CHA_VSYNC_PULSE_WIDTH_LOW, &le16val, 2); regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_BACK_PORCH, - mode->htotal - mode->hsync_end); + (mode->htotal - mode->hsync_end) / dual_factor); regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_BACK_PORCH, mode->vtotal - mode->vsync_end); regmap_write(ctx->regmap, REG_VID_CHA_HORIZONTAL_FRONT_PORCH, - mode->hsync_start - mode->hdisplay); + (mode->hsync_start - mode->hdisplay) / dual_factor); regmap_write(ctx->regmap, REG_VID_CHA_VERTICAL_FRONT_PORCH, mode->vsync_start - mode->vdisplay); regmap_write(ctx->regmap, REG_VID_CHA_TEST_PATTERN, 0x00); diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 276d05d25ad8..98d64ad791d0 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -1415,6 +1415,7 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, { struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent); struct device_node *np = pdata->dev->of_node; + const struct i2c_client *client = to_i2c_client(pdata->dev); int ret; pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0); @@ -1433,8 +1434,9 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP; if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { - pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT | - DRM_BRIDGE_OP_HPD; + pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT; + if (client->irq) + pdata->bridge.ops |= DRM_BRIDGE_OP_HPD; /* * If comms were already enabled they would have been enabled * with the wrong value of HPD_DISABLE. Update it now. Comms diff --git a/drivers/gpu/drm/bridge/ti-tfp410.c b/drivers/gpu/drm/bridge/ti-tfp410.c index 11b5bb50e9f4..3b6b0e92cf89 100644 --- a/drivers/gpu/drm/bridge/ti-tfp410.c +++ b/drivers/gpu/drm/bridge/ti-tfp410.c @@ -213,7 +213,7 @@ static u32 *tfp410_get_input_bus_fmts(struct drm_bridge *bridge, *num_input_fmts = 0; - input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kzalloc_obj(*input_fmts); if (!input_fmts) return NULL; diff --git a/drivers/gpu/drm/clients/drm_fbdev_client.c b/drivers/gpu/drm/clients/drm_fbdev_client.c index 28951e392482..91d196a397cf 100644 --- a/drivers/gpu/drm/clients/drm_fbdev_client.c +++ b/drivers/gpu/drm/clients/drm_fbdev_client.c @@ -154,7 +154,7 @@ int drm_fbdev_client_setup(struct drm_device *dev, const struct drm_format_info drm_WARN(dev, !dev->registered, "Device has not been registered.\n"); drm_WARN(dev, dev->fb_helper, "fb_helper is already set!\n"); - fb_helper = kzalloc(sizeof(*fb_helper), GFP_KERNEL); + fb_helper = kzalloc_obj(*fb_helper); if (!fb_helper) return -ENOMEM; drm_fb_helper_prepare(dev, fb_helper, color_mode, NULL); diff --git a/drivers/gpu/drm/clients/drm_log.c b/drivers/gpu/drm/clients/drm_log.c index 2bd5189c967e..8d21b785bead 100644 --- a/drivers/gpu/drm/clients/drm_log.c +++ b/drivers/gpu/drm/clients/drm_log.c @@ -248,7 +248,7 @@ static void drm_log_init_client(struct drm_log *dlog) if (!max_modeset) return; - dlog->scanout = kcalloc(max_modeset, sizeof(*dlog->scanout), GFP_KERNEL); + dlog->scanout = kzalloc_objs(*dlog->scanout, max_modeset); if (!dlog->scanout) return; @@ -419,7 +419,7 @@ void drm_log_register(struct drm_device *dev) { struct drm_log *new; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) goto err_warn; diff --git a/drivers/gpu/drm/display/drm_dp_aux_bus.c b/drivers/gpu/drm/display/drm_dp_aux_bus.c index 2d279e82922f..6e5e3e542290 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_bus.c +++ b/drivers/gpu/drm/display/drm_dp_aux_bus.c @@ -280,7 +280,7 @@ int of_dp_aux_populate_bus(struct drm_dp_aux *aux, goto err_did_get_np; } - aux_ep_with_data = kzalloc(sizeof(*aux_ep_with_data), GFP_KERNEL); + aux_ep_with_data = kzalloc_obj(*aux_ep_with_data); if (!aux_ep_with_data) { ret = -ENOMEM; goto err_did_set_populated; diff --git a/drivers/gpu/drm/display/drm_dp_aux_dev.c b/drivers/gpu/drm/display/drm_dp_aux_dev.c index 29555b9f03c8..f0632e43b69e 100644 --- a/drivers/gpu/drm/display/drm_dp_aux_dev.c +++ b/drivers/gpu/drm/display/drm_dp_aux_dev.c @@ -75,7 +75,7 @@ static struct drm_dp_aux_dev *alloc_drm_dp_aux_dev(struct drm_dp_aux *aux) struct drm_dp_aux_dev *aux_dev; int index; - aux_dev = kzalloc(sizeof(*aux_dev), GFP_KERNEL); + aux_dev = kzalloc_obj(*aux_dev); if (!aux_dev) return ERR_PTR(-ENOMEM); aux_dev->aux = aux; diff --git a/drivers/gpu/drm/display/drm_dp_mst_topology.c b/drivers/gpu/drm/display/drm_dp_mst_topology.c index be749dcad3b5..170113520a43 100644 --- a/drivers/gpu/drm/display/drm_dp_mst_topology.c +++ b/drivers/gpu/drm/display/drm_dp_mst_topology.c @@ -1333,7 +1333,7 @@ static struct drm_dp_mst_branch *drm_dp_add_mst_branch_device(u8 lct, u8 *rad) { struct drm_dp_mst_branch *mstb; - mstb = kzalloc(sizeof(*mstb), GFP_KERNEL); + mstb = kzalloc_obj(*mstb); if (!mstb) return NULL; @@ -2317,7 +2317,7 @@ drm_dp_mst_add_port(struct drm_device *dev, struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_branch *mstb, u8 port_number) { - struct drm_dp_mst_port *port = kzalloc(sizeof(*port), GFP_KERNEL); + struct drm_dp_mst_port *port = kzalloc_obj(*port); if (!port) return NULL; @@ -2923,7 +2923,7 @@ static int drm_dp_send_link_address(struct drm_dp_mst_topology_mgr *mgr, int i, ret, port_mask = 0; bool changed = false; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) return -ENOMEM; @@ -3000,7 +3000,7 @@ drm_dp_send_clear_payload_id_table(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg; int ret; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) return; @@ -3025,7 +3025,7 @@ drm_dp_send_enum_path_resources(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_sideband_msg_tx *txmsg; int ret; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) return -ENOMEM; @@ -3138,7 +3138,7 @@ static int drm_dp_payload_send_msg(struct drm_dp_mst_topology_mgr *mgr, return -EINVAL; } - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { ret = -ENOMEM; goto fail_put; @@ -3185,7 +3185,7 @@ int drm_dp_send_power_updown_phy(struct drm_dp_mst_topology_mgr *mgr, if (!port) return -EINVAL; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { drm_dp_mst_topology_put_port(port); return -ENOMEM; @@ -3219,7 +3219,7 @@ int drm_dp_send_query_stream_enc_status(struct drm_dp_mst_topology_mgr *mgr, u8 nonce[7]; int ret; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) return -ENOMEM; @@ -3470,7 +3470,7 @@ static int drm_dp_send_dpcd_read(struct drm_dp_mst_topology_mgr *mgr, if (!mstb) return -EINVAL; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { ret = -ENOMEM; goto fail_put; @@ -3521,7 +3521,7 @@ static int drm_dp_send_dpcd_write(struct drm_dp_mst_topology_mgr *mgr, if (!mstb) return -EINVAL; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { ret = -ENOMEM; goto fail_put; @@ -3562,7 +3562,7 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, { struct drm_dp_sideband_msg_tx *txmsg; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) return -ENOMEM; @@ -4135,7 +4135,7 @@ static int drm_dp_mst_handle_up_req(struct drm_dp_mst_topology_mgr *mgr) if (!mgr->up_req_recv.have_eomt) return 0; - up_req = kzalloc(sizeof(*up_req), GFP_KERNEL); + up_req = kzalloc_obj(*up_req); if (!up_req) { ret = -ENOMEM; goto out_clear_reply; @@ -4479,7 +4479,7 @@ int drm_dp_atomic_find_time_slots(struct drm_atomic_state *state, /* Add the new allocation to the state, note the VCPI isn't assigned until the end */ if (!payload) { - payload = kzalloc(sizeof(*payload), GFP_KERNEL); + payload = kzalloc_obj(*payload); if (!payload) return -ENOMEM; @@ -4604,8 +4604,8 @@ int drm_dp_mst_atomic_setup_commit(struct drm_atomic_state *state) continue; num_commit_deps = hweight32(mst_state->pending_crtc_mask); - mst_state->commit_deps = kmalloc_array(num_commit_deps, - sizeof(*mst_state->commit_deps), GFP_KERNEL); + mst_state->commit_deps = kmalloc_objs(*mst_state->commit_deps, + num_commit_deps); if (!mst_state->commit_deps) return -ENOMEM; mst_state->num_commit_deps = num_commit_deps; @@ -5743,7 +5743,7 @@ int drm_dp_mst_topology_mgr_init(struct drm_dp_mst_topology_mgr *mgr, mgr->max_payloads = max_payloads; mgr->conn_base_id = conn_base_id; - mst_state = kzalloc(sizeof(*mst_state), GFP_KERNEL); + mst_state = kzalloc_obj(*mst_state); if (mst_state == NULL) return -ENOMEM; @@ -5843,7 +5843,7 @@ static int drm_dp_mst_i2c_read(struct drm_dp_mst_branch *mstb, msg.u.i2c_read.read_i2c_device_id = msgs[num - 1].addr; msg.u.i2c_read.num_bytes_read = msgs[num - 1].len; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { ret = -ENOMEM; goto out; @@ -5883,7 +5883,7 @@ static int drm_dp_mst_i2c_write(struct drm_dp_mst_branch *mstb, struct drm_dp_sideband_msg_tx *txmsg = NULL; int ret; - txmsg = kzalloc(sizeof(*txmsg), GFP_KERNEL); + txmsg = kzalloc_obj(*txmsg); if (!txmsg) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/display/drm_dp_tunnel.c b/drivers/gpu/drm/display/drm_dp_tunnel.c index 43f13a7c79b9..7aee57416902 100644 --- a/drivers/gpu/drm/display/drm_dp_tunnel.c +++ b/drivers/gpu/drm/display/drm_dp_tunnel.c @@ -476,7 +476,7 @@ create_tunnel(struct drm_dp_tunnel_mgr *mgr, u8 drv_group_id = tunnel_reg_drv_group_id(regs); struct drm_dp_tunnel *tunnel; - tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL); + tunnel = kzalloc_obj(*tunnel); if (!tunnel) return NULL; @@ -1387,7 +1387,7 @@ add_tunnel_state(struct drm_dp_tunnel_group_state *group_state, "Adding state for tunnel %p to group state %p\n", tunnel, group_state); - tunnel_state = kzalloc(sizeof(*tunnel_state), GFP_KERNEL); + tunnel_state = kzalloc_obj(*tunnel_state); if (!tunnel_state) return NULL; @@ -1458,7 +1458,7 @@ tunnel_group_duplicate_state(struct drm_private_obj *obj) struct drm_dp_tunnel_group_state *group_state; struct drm_dp_tunnel_state *tunnel_state; - group_state = kzalloc(sizeof(*group_state), GFP_KERNEL); + group_state = kzalloc_obj(*group_state); if (!group_state) return NULL; @@ -1583,7 +1583,7 @@ static bool init_group(struct drm_dp_tunnel_mgr *mgr, struct drm_dp_tunnel_group { struct drm_dp_tunnel_group_state *group_state; - group_state = kzalloc(sizeof(*group_state), GFP_KERNEL); + group_state = kzalloc_obj(*group_state); if (!group_state) return false; @@ -1644,7 +1644,7 @@ static int resize_bw_array(struct drm_dp_tunnel_state *tunnel_state, if (old_mask == new_mask) return 0; - new_bws = kcalloc(hweight32(new_mask), sizeof(*new_bws), GFP_KERNEL); + new_bws = kzalloc_objs(*new_bws, hweight32(new_mask)); if (!new_bws) return -ENOMEM; @@ -1906,14 +1906,14 @@ drm_dp_tunnel_mgr_create(struct drm_device *dev, int max_group_count) struct drm_dp_tunnel_mgr *mgr; int i; - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (!mgr) return ERR_PTR(-ENOMEM); mgr->dev = dev; init_waitqueue_head(&mgr->bw_req_queue); - mgr->groups = kcalloc(max_group_count, sizeof(*mgr->groups), GFP_KERNEL); + mgr->groups = kzalloc_objs(*mgr->groups, max_group_count); if (!mgr->groups) { kfree(mgr); diff --git a/drivers/gpu/drm/display/drm_hdmi_cec_helper.c b/drivers/gpu/drm/display/drm_hdmi_cec_helper.c index 3651ad0f76e0..ef6dbaa59dee 100644 --- a/drivers/gpu/drm/display/drm_hdmi_cec_helper.c +++ b/drivers/gpu/drm/display/drm_hdmi_cec_helper.c @@ -97,7 +97,7 @@ int drmm_connector_hdmi_cec_register(struct drm_connector *connector, if (!funcs->init || !funcs->enable || !funcs->log_addr || !funcs->transmit) return -EINVAL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 52738b80ddbe..f2cd2e25f009 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -132,16 +132,15 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state) */ state->allow_modeset = true; - state->crtcs = kcalloc(dev->mode_config.num_crtc, - sizeof(*state->crtcs), GFP_KERNEL); + state->crtcs = kzalloc_objs(*state->crtcs, dev->mode_config.num_crtc); if (!state->crtcs) goto fail; - state->planes = kcalloc(dev->mode_config.num_total_plane, - sizeof(*state->planes), GFP_KERNEL); + state->planes = kzalloc_objs(*state->planes, + dev->mode_config.num_total_plane); if (!state->planes) goto fail; - state->colorops = kcalloc(dev->mode_config.num_colorop, - sizeof(*state->colorops), GFP_KERNEL); + state->colorops = kzalloc_objs(*state->colorops, + dev->mode_config.num_colorop); if (!state->colorops) goto fail; @@ -176,7 +175,7 @@ drm_atomic_state_alloc(struct drm_device *dev) if (!config->funcs->atomic_state_alloc) { struct drm_atomic_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; if (drm_atomic_state_init(dev, state) < 0) { diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index cc1f0c102414..af02c409c2f6 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -2453,7 +2453,7 @@ crtc_or_fake_commit(struct drm_atomic_state *state, struct drm_crtc *crtc) } if (!state->fake_commit) { - state->fake_commit = kzalloc(sizeof(*state->fake_commit), GFP_KERNEL); + state->fake_commit = kzalloc_obj(*state->fake_commit); if (!state->fake_commit) return NULL; @@ -2524,7 +2524,7 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, funcs = state->dev->mode_config.helper_private; for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) { - commit = kzalloc(sizeof(*commit), GFP_KERNEL); + commit = kzalloc_obj(*commit); if (!commit) return -ENOMEM; @@ -2553,8 +2553,7 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state, } if (!new_crtc_state->event) { - commit->event = kzalloc(sizeof(*commit->event), - GFP_KERNEL); + commit->event = kzalloc_obj(*commit->event); if (!commit->event) return -ENOMEM; @@ -4080,7 +4079,7 @@ drm_atomic_helper_bridge_propagate_bus_fmt(struct drm_bridge *bridge, { u32 *input_fmts; - input_fmts = kzalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kzalloc_obj(*input_fmts); if (!input_fmts) { *num_input_fmts = 0; return NULL; diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index cee6d8fc44ad..41f916f11a76 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -114,7 +114,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) { struct drm_crtc_state *crtc_state = - kzalloc(sizeof(*crtc->state), GFP_KERNEL); + kzalloc_obj(*crtc->state); if (crtc->state) crtc->funcs->atomic_destroy_state(crtc, crtc->state); @@ -175,7 +175,7 @@ drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc) if (WARN_ON(!crtc->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (state) __drm_atomic_helper_crtc_duplicate_state(crtc, state); @@ -333,7 +333,7 @@ void drm_atomic_helper_plane_reset(struct drm_plane *plane) __drm_atomic_helper_plane_destroy_state(plane->state); kfree(plane->state); - plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL); + plane->state = kzalloc_obj(*plane->state); if (plane->state) __drm_atomic_helper_plane_reset(plane, plane->state); } @@ -377,7 +377,7 @@ drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (state) __drm_atomic_helper_plane_duplicate_state(plane, state); @@ -473,8 +473,7 @@ EXPORT_SYMBOL(__drm_atomic_helper_connector_reset); */ void drm_atomic_helper_connector_reset(struct drm_connector *connector) { - struct drm_connector_state *conn_state = - kzalloc(sizeof(*conn_state), GFP_KERNEL); + struct drm_connector_state *conn_state = kzalloc_obj(*conn_state); if (connector->state) __drm_atomic_helper_connector_destroy_state(connector->state); @@ -666,7 +665,7 @@ drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector) if (WARN_ON(!connector->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (state) __drm_atomic_helper_connector_duplicate_state(connector, state); @@ -763,7 +762,7 @@ drm_atomic_helper_bridge_duplicate_state(struct drm_bridge *bridge) if (WARN_ON(!bridge->base.state)) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (new) __drm_atomic_helper_bridge_duplicate_state(bridge, new); @@ -821,7 +820,7 @@ drm_atomic_helper_bridge_reset(struct drm_bridge *bridge) { struct drm_bridge_state *bridge_state; - bridge_state = kzalloc(sizeof(*bridge_state), GFP_KERNEL); + bridge_state = kzalloc_obj(*bridge_state); if (!bridge_state) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index dc013a22bf26..87de41fb4459 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1088,7 +1088,7 @@ static struct drm_pending_vblank_event *create_vblank_event( { struct drm_pending_vblank_event *e = NULL; - e = kzalloc(sizeof *e, GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return NULL; diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index a2556d16bed6..e17bb0f1f9e0 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c @@ -132,7 +132,7 @@ struct drm_master *drm_master_create(struct drm_device *dev) { struct drm_master *master; - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return NULL; diff --git a/drivers/gpu/drm/drm_blend.c b/drivers/gpu/drm/drm_blend.c index 6852d73c931c..3b1f5f72885e 100644 --- a/drivers/gpu/drm/drm_blend.c +++ b/drivers/gpu/drm/drm_blend.c @@ -459,7 +459,7 @@ static int drm_atomic_helper_crtc_normalize_zpos(struct drm_crtc *crtc, drm_dbg_atomic(dev, "[CRTC:%d:%s] calculating normalized zpos values\n", crtc->base.id, crtc->name); - states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL); + states = kmalloc_objs(*states, total_planes); if (!states) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 3b165a0d1e77..d6f11c68bb6a 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -1189,7 +1189,7 @@ drm_atomic_bridge_chain_select_bus_fmts(struct drm_bridge *bridge, return -ENOMEM; } else { num_out_bus_fmts = 1; - out_bus_fmts = kmalloc(sizeof(*out_bus_fmts), GFP_KERNEL); + out_bus_fmts = kmalloc_obj(*out_bus_fmts); if (!out_bus_fmts) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index fd34d3755f7c..dbf984f8e301 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -320,16 +320,13 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) BUG_ON(mm->max_order > DRM_BUDDY_MAX_ORDER); - mm->free_trees = kmalloc_array(DRM_BUDDY_MAX_FREE_TREES, - sizeof(*mm->free_trees), - GFP_KERNEL); + mm->free_trees = kmalloc_objs(*mm->free_trees, DRM_BUDDY_MAX_FREE_TREES); if (!mm->free_trees) return -ENOMEM; for_each_free_tree(i) { - mm->free_trees[i] = kmalloc_array(mm->max_order + 1, - sizeof(struct rb_root), - GFP_KERNEL); + mm->free_trees[i] = kmalloc_objs(struct rb_root, + mm->max_order + 1); if (!mm->free_trees[i]) goto out_free_tree; @@ -339,9 +336,7 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) mm->n_roots = hweight64(size); - mm->roots = kmalloc_array(mm->n_roots, - sizeof(struct drm_buddy_block *), - GFP_KERNEL); + mm->roots = kmalloc_objs(struct drm_buddy_block *, mm->n_roots); if (!mm->roots) goto out_free_tree; diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c index a82d741e6630..6236ec46d62a 100644 --- a/drivers/gpu/drm/drm_client.c +++ b/drivers/gpu/drm/drm_client.c @@ -225,7 +225,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, struct drm_framebuffer *fb; int ret; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index fc4caf7da5fc..bb49b8361271 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -44,7 +44,7 @@ int drm_client_modeset_create(struct drm_client_dev *client) int i = 0; /* Add terminating zero entry to enable index less iteration */ - client->modesets = kcalloc(num_crtc + 1, sizeof(*client->modesets), GFP_KERNEL); + client->modesets = kzalloc_objs(*client->modesets, num_crtc + 1); if (!client->modesets) return -ENOMEM; @@ -58,8 +58,8 @@ int drm_client_modeset_create(struct drm_client_dev *client) max_connector_count = DRM_CLIENT_MAX_CLONED_CONNECTORS; for (modeset = client->modesets; modeset->crtc; modeset++) { - modeset->connectors = kcalloc(max_connector_count, - sizeof(*modeset->connectors), GFP_KERNEL); + modeset->connectors = kzalloc_objs(*modeset->connectors, + max_connector_count); if (!modeset->connectors) goto err_free; } @@ -565,7 +565,7 @@ static int drm_client_pick_crtcs(struct drm_client_dev *client, if (modes[n] == NULL) return best_score; - crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL); + crtcs = kzalloc_objs(*crtcs, connector_count); if (!crtcs) return best_score; @@ -641,7 +641,7 @@ static bool drm_client_firmware_config(struct drm_client_dev *client, if (drm_WARN_ON(dev, count <= 0)) return false; - save_enabled = kcalloc(count, sizeof(bool), GFP_KERNEL); + save_enabled = kzalloc_objs(bool, count); if (!save_enabled) return false; @@ -853,10 +853,10 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, if (!connector_count) return 0; - crtcs = kcalloc(connector_count, sizeof(*crtcs), GFP_KERNEL); - modes = kcalloc(connector_count, sizeof(*modes), GFP_KERNEL); - offsets = kcalloc(connector_count, sizeof(*offsets), GFP_KERNEL); - enabled = kcalloc(connector_count, sizeof(bool), GFP_KERNEL); + crtcs = kzalloc_objs(*crtcs, connector_count); + modes = kzalloc_objs(*modes, connector_count); + offsets = kzalloc_objs(*offsets, connector_count); + enabled = kzalloc_objs(bool, connector_count); if (!crtcs || !modes || !enabled || !offsets) { ret = -ENOMEM; goto out; @@ -930,7 +930,8 @@ int drm_client_modeset_probe(struct drm_client_dev *client, unsigned int width, mutex_unlock(&client->modeset_mutex); out: kfree(crtcs); - modes_destroy(dev, modes, connector_count); + if (modes) + modes_destroy(dev, modes, connector_count); kfree(modes); kfree(offsets); kfree(enabled); diff --git a/drivers/gpu/drm/drm_colorop.c b/drivers/gpu/drm/drm_colorop.c index 44eb823585d2..398cc81ae588 100644 --- a/drivers/gpu/drm/drm_colorop.c +++ b/drivers/gpu/drm/drm_colorop.c @@ -453,7 +453,7 @@ drm_atomic_helper_colorop_duplicate_state(struct drm_colorop *colorop) if (WARN_ON(!colorop->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (state) __drm_atomic_helper_colorop_duplicate_state(colorop, state); @@ -514,7 +514,7 @@ static void __drm_colorop_reset(struct drm_colorop *colorop, void drm_colorop_reset(struct drm_colorop *colorop) { kfree(colorop->state); - colorop->state = kzalloc(sizeof(*colorop->state), GFP_KERNEL); + colorop->state = kzalloc_obj(*colorop->state); if (colorop->state) __drm_colorop_reset(colorop, colorop->state); diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c index 4f5b27fab475..2a3a1fa0594b 100644 --- a/drivers/gpu/drm/drm_connector.c +++ b/drivers/gpu/drm/drm_connector.c @@ -3605,7 +3605,7 @@ struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev, struct drm_tile_group *tg; int ret; - tg = kzalloc(sizeof(*tg), GFP_KERNEL); + tg = kzalloc_obj(*tg); if (!tg) return NULL; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index a7797d260f1e..90684f30a048 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -185,7 +185,7 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc) { struct dma_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; @@ -845,9 +845,8 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, goto out; } - connector_set = kmalloc_array(crtc_req->count_connectors, - sizeof(struct drm_connector *), - GFP_KERNEL); + connector_set = kmalloc_objs(struct drm_connector *, + crtc_req->count_connectors); if (!connector_set) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 39497493f74c..5de9aaa5ba04 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -602,13 +602,13 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set, * Allocate space for the backup of all (non-pointer) encoder and * connector data. */ - save_encoder_crtcs = kcalloc(dev->mode_config.num_encoder, - sizeof(struct drm_crtc *), GFP_KERNEL); + save_encoder_crtcs = kzalloc_objs(struct drm_crtc *, + dev->mode_config.num_encoder); if (!save_encoder_crtcs) return -ENOMEM; - save_connector_encoders = kcalloc(dev->mode_config.num_connector, - sizeof(struct drm_encoder *), GFP_KERNEL); + save_connector_encoders = kzalloc_objs(struct drm_encoder *, + dev->mode_config.num_connector); if (!save_connector_encoders) { kfree(save_encoder_crtcs); return -ENOMEM; diff --git a/drivers/gpu/drm/drm_damage_helper.c b/drivers/gpu/drm/drm_damage_helper.c index 6a49e7a0ab84..1b6850aa1688 100644 --- a/drivers/gpu/drm/drm_damage_helper.c +++ b/drivers/gpu/drm/drm_damage_helper.c @@ -140,7 +140,7 @@ int drm_atomic_helper_dirtyfb(struct drm_framebuffer *fb, num_clips /= 2; } - rects = kcalloc(num_clips, sizeof(*rects), GFP_KERNEL); + rects = kzalloc_objs(*rects, num_clips); if (!rects) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/drm_debugfs_crc.c b/drivers/gpu/drm/drm_debugfs_crc.c index 6b43b1cf2327..371edb0b9b17 100644 --- a/drivers/gpu/drm/drm_debugfs_crc.c +++ b/drivers/gpu/drm/drm_debugfs_crc.c @@ -224,7 +224,7 @@ static int crtc_crc_open(struct inode *inode, struct file *filep) if (WARN_ON(values_cnt == 0)) return -EINVAL; - entries = kcalloc(DRM_CRC_ENTRIES_NR, sizeof(*entries), GFP_KERNEL); + entries = kzalloc_objs(*entries, DRM_CRC_ENTRIES_NR); if (!entries) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 26bb7710a462..ff432ac6b569 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -2503,7 +2503,7 @@ static const struct drm_edid *_drm_edid_alloc(const void *edid, size_t size) if (!edid || !size || size < EDID_LENGTH) return NULL; - drm_edid = kzalloc(sizeof(*drm_edid), GFP_KERNEL); + drm_edid = kzalloc_obj(*drm_edid); if (drm_edid) { drm_edid->edid = edid; drm_edid->size = size; @@ -5764,7 +5764,7 @@ static int _drm_edid_to_sad(const struct drm_edid *drm_edid, int i; count = cea_db_payload_len(db) / 3; /* SAD is 3B */ - sads = kcalloc(count, sizeof(*sads), GFP_KERNEL); + sads = kzalloc_objs(*sads, count); *psads = sads; if (!sads) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_file.c b/drivers/gpu/drm/drm_file.c index be5e617ceb9f..ec820686b302 100644 --- a/drivers/gpu/drm/drm_file.c +++ b/drivers/gpu/drm/drm_file.c @@ -136,7 +136,7 @@ struct drm_file *drm_file_alloc(struct drm_minor *minor) struct drm_file *file; int ret; - file = kzalloc(sizeof(*file), GFP_KERNEL); + file = kzalloc_obj(*file); if (!file) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_flip_work.c b/drivers/gpu/drm/drm_flip_work.c index f5889dd8e7aa..52c437746d48 100644 --- a/drivers/gpu/drm/drm_flip_work.c +++ b/drivers/gpu/drm/drm_flip_work.c @@ -37,7 +37,7 @@ static struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags { struct drm_flip_task *task; - task = kzalloc(sizeof(*task), flags); + task = kzalloc_obj(*task, flags); if (task) task->data = data; diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c index 18e753ade001..147ac19f851b 100644 --- a/drivers/gpu/drm/drm_framebuffer.c +++ b/drivers/gpu/drm/drm_framebuffer.c @@ -747,7 +747,7 @@ int drm_mode_dirtyfb_ioctl(struct drm_device *dev, ret = -EINVAL; goto out_err1; } - clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); + clips = kzalloc_objs(*clips, num_clips); if (!clips) { ret = -ENOMEM; goto out_err1; diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index ffa7852c8f6c..891c3bff5ae0 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -186,15 +186,16 @@ int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj, { struct vfsmount *huge_mnt; struct file *filp; + const vma_flags_t flags = mk_vma_flags(VMA_NORESERVE_BIT); drm_gem_private_object_init(dev, obj, size); huge_mnt = drm_gem_get_huge_mnt(dev); if (huge_mnt) filp = shmem_file_setup_with_mnt(huge_mnt, "drm mm object", - size, VM_NORESERVE); + size, flags); else - filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); + filp = shmem_file_setup("drm mm object", size, flags); if (IS_ERR(filp)) return PTR_ERR(filp); @@ -683,7 +684,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj) npages = obj->size >> PAGE_SHIFT; - pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + pages = kvmalloc_objs(struct page *, npages); if (pages == NULL) return ERR_PTR(-ENOMEM); @@ -831,7 +832,7 @@ int drm_gem_objects_lookup(struct drm_file *filp, void __user *bo_handles, if (!count) return 0; - objs = kvmalloc_array(count, sizeof(struct drm_gem_object *), + objs = kvmalloc_objs(struct drm_gem_object *, count, GFP_KERNEL | __GFP_ZERO); if (!objs) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index 569d41a65a0b..421c460ac972 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -256,7 +256,7 @@ drm_gem_duplicate_shadow_plane_state(struct drm_plane *plane) if (!plane_state) return NULL; - new_shadow_plane_state = kzalloc(sizeof(*new_shadow_plane_state), GFP_KERNEL); + new_shadow_plane_state = kzalloc_obj(*new_shadow_plane_state); if (!new_shadow_plane_state) return NULL; __drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state); @@ -337,7 +337,7 @@ void drm_gem_reset_shadow_plane(struct drm_plane *plane) plane->state = NULL; /* must be set to NULL here */ } - shadow_plane_state = kzalloc(sizeof(*shadow_plane_state), GFP_KERNEL); + shadow_plane_state = kzalloc_obj(*shadow_plane_state); __drm_gem_reset_shadow_plane(plane, shadow_plane_state); } EXPORT_SYMBOL(drm_gem_reset_shadow_plane); diff --git a/drivers/gpu/drm/drm_gem_dma_helper.c b/drivers/gpu/drm/drm_gem_dma_helper.c index eb56ba234796..ecb9746f4da8 100644 --- a/drivers/gpu/drm/drm_gem_dma_helper.c +++ b/drivers/gpu/drm/drm_gem_dma_helper.c @@ -82,7 +82,7 @@ __drm_gem_dma_create(struct drm_device *drm, size_t size, bool private) return ERR_CAST(gem_obj); dma_obj = to_drm_gem_dma_obj(gem_obj); } else { - dma_obj = kzalloc(sizeof(*dma_obj), GFP_KERNEL); + dma_obj = kzalloc_obj(*dma_obj); if (!dma_obj) return ERR_PTR(-ENOMEM); gem_obj = &dma_obj->base; @@ -428,7 +428,7 @@ struct sg_table *drm_gem_dma_get_sg_table(struct drm_gem_dma_object *dma_obj) struct sg_table *sgt; int ret; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_gem_framebuffer_helper.c b/drivers/gpu/drm/drm_gem_framebuffer_helper.c index 9fd4eb02a20f..9166c353f131 100644 --- a/drivers/gpu/drm/drm_gem_framebuffer_helper.c +++ b/drivers/gpu/drm/drm_gem_framebuffer_helper.c @@ -238,7 +238,7 @@ drm_gem_fb_create_with_funcs(struct drm_device *dev, struct drm_file *file, struct drm_framebuffer *fb; int ret; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c b/drivers/gpu/drm/drm_gem_shmem_helper.c index 3871a6d92f77..7b5a49935ae4 100644 --- a/drivers/gpu/drm/drm_gem_shmem_helper.c +++ b/drivers/gpu/drm/drm_gem_shmem_helper.c @@ -127,7 +127,7 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private) return ERR_CAST(obj); shmem = to_drm_gem_shmem_obj(obj); } else { - shmem = kzalloc(sizeof(*shmem), GFP_KERNEL); + shmem = kzalloc_obj(*shmem); if (!shmem) return ERR_PTR(-ENOMEM); obj = &shmem->base; diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c b/drivers/gpu/drm/drm_gem_vram_helper.c index 5e5b70518dbe..d7fcced75e79 100644 --- a/drivers/gpu/drm/drm_gem_vram_helper.c +++ b/drivers/gpu/drm/drm_gem_vram_helper.c @@ -197,7 +197,7 @@ struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev, return ERR_CAST(gem); gbo = drm_gem_vram_of_gem(gem); } else { - gbo = kzalloc(sizeof(*gbo), GFP_KERNEL); + gbo = kzalloc_obj(*gbo); if (!gbo) return ERR_PTR(-ENOMEM); gem = &gbo->bo.base; @@ -721,7 +721,7 @@ static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo, struct ttm_tt *tt; int ret; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); if (!tt) return NULL; @@ -890,7 +890,7 @@ static struct drm_vram_mm *drm_vram_helper_alloc_mm(struct drm_device *dev, uint if (WARN_ON(dev->vram_mm)) return dev->vram_mm; - dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL); + dev->vram_mm = kzalloc_obj(*dev->vram_mm); if (!dev->vram_mm) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_gpusvm.c b/drivers/gpu/drm/drm_gpusvm.c index aa9a0b60e727..9ef9e52c0547 100644 --- a/drivers/gpu/drm/drm_gpusvm.c +++ b/drivers/gpu/drm/drm_gpusvm.c @@ -522,7 +522,7 @@ drm_gpusvm_notifier_alloc(struct drm_gpusvm *gpusvm, unsigned long fault_addr) if (gpusvm->ops->notifier_alloc) notifier = gpusvm->ops->notifier_alloc(); else - notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); + notifier = kzalloc_obj(*notifier); if (!notifier) return ERR_PTR(-ENOMEM); @@ -629,7 +629,7 @@ drm_gpusvm_range_alloc(struct drm_gpusvm *gpusvm, if (gpusvm->ops->range_alloc) range = gpusvm->ops->range_alloc(gpusvm); else - range = kzalloc(sizeof(*range), GFP_KERNEL); + range = kzalloc_obj(*range); if (!range) return ERR_PTR(-ENOMEM); @@ -1150,7 +1150,7 @@ static void __drm_gpusvm_unmap_pages(struct drm_gpusvm *gpusvm, addr->dir); else if (dpagemap && dpagemap->ops->device_unmap) dpagemap->ops->device_unmap(dpagemap, - dev, *addr); + dev, addr); i += 1 << addr->order; } @@ -1338,14 +1338,14 @@ bool drm_gpusvm_range_pages_valid(struct drm_gpusvm *gpusvm, EXPORT_SYMBOL_GPL(drm_gpusvm_range_pages_valid); /** - * drm_gpusvm_range_pages_valid_unlocked() - GPU SVM range pages valid unlocked + * drm_gpusvm_pages_valid_unlocked() - GPU SVM pages valid unlocked * @gpusvm: Pointer to the GPU SVM structure - * @range: Pointer to the GPU SVM range structure + * @svm_pages: Pointer to the GPU SVM pages structure * - * This function determines if a GPU SVM range pages are valid. Expected be - * called without holding gpusvm->notifier_lock. + * This function determines if a GPU SVM pages are valid. Expected be called + * without holding gpusvm->notifier_lock. * - * Return: True if GPU SVM range has valid pages, False otherwise + * Return: True if GPU SVM pages are valid, False otherwise */ static bool drm_gpusvm_pages_valid_unlocked(struct drm_gpusvm *gpusvm, struct drm_gpusvm_pages *svm_pages) @@ -1471,7 +1471,7 @@ int drm_gpusvm_get_pages(struct drm_gpusvm *gpusvm, /* Unlock and restart mapping to allocate memory. */ drm_gpusvm_notifier_unlock(gpusvm); svm_pages->dma_addr = - kvmalloc_array(npages, sizeof(*svm_pages->dma_addr), GFP_KERNEL); + kvmalloc_objs(*svm_pages->dma_addr, npages); if (!svm_pages->dma_addr) { err = -ENOMEM; goto err_free; diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 14469765a780..44acfe4120d2 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1060,7 +1060,7 @@ drm_gpuvm_resv_object_alloc(struct drm_device *drm) { struct drm_gem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; @@ -1581,7 +1581,7 @@ drm_gpuvm_bo_create(struct drm_gpuvm *gpuvm, if (ops && ops->vm_bo_alloc) vm_bo = ops->vm_bo_alloc(); else - vm_bo = kzalloc(sizeof(*vm_bo), GFP_KERNEL); + vm_bo = kzalloc_obj(*vm_bo); if (unlikely(!vm_bo)) return NULL; @@ -2852,7 +2852,7 @@ gpuva_op_alloc(struct drm_gpuvm *gpuvm) if (fn && fn->op_alloc) op = fn->op_alloc(); else - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (unlikely(!op)) return NULL; @@ -2946,7 +2946,7 @@ __drm_gpuvm_sm_map_ops_create(struct drm_gpuvm *gpuvm, } args; int ret; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (unlikely(!ops)) return ERR_PTR(-ENOMEM); @@ -3080,7 +3080,7 @@ drm_gpuvm_sm_unmap_ops_create(struct drm_gpuvm *gpuvm, } args; int ret; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (unlikely(!ops)) return ERR_PTR(-ENOMEM); @@ -3130,7 +3130,7 @@ drm_gpuvm_prefetch_ops_create(struct drm_gpuvm *gpuvm, u64 end = addr + range; int ret; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (!ops) return ERR_PTR(-ENOMEM); @@ -3184,7 +3184,7 @@ drm_gpuvm_bo_unmap_ops_create(struct drm_gpuvm_bo *vm_bo) drm_gem_gpuva_assert_lock_held(vm_bo->vm, vm_bo->obj); - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (!ops) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_lease.c b/drivers/gpu/drm/drm_lease.c index 94375c6a5425..5d2cf724cbd7 100644 --- a/drivers/gpu/drm/drm_lease.c +++ b/drivers/gpu/drm/drm_lease.c @@ -386,8 +386,7 @@ static int fill_object_idr(struct drm_device *dev, int ret; bool universal_planes = READ_ONCE(lessor_priv->universal_planes); - objects = kcalloc(object_count, sizeof(struct drm_mode_object *), - GFP_KERNEL); + objects = kzalloc_objs(struct drm_mode_object *, object_count); if (!objects) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c index a712e177b350..0390e14d3157 100644 --- a/drivers/gpu/drm/drm_mipi_dsi.c +++ b/drivers/gpu/drm/drm_mipi_dsi.c @@ -134,7 +134,7 @@ static struct mipi_dsi_device *mipi_dsi_device_alloc(struct mipi_dsi_host *host) { struct mipi_dsi_device *dsi; - dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); + dsi = kzalloc_obj(*dsi); if (!dsi) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index e72f855fc495..3f8e025fd6d9 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -75,7 +75,7 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev) { struct drm_display_mode *nmode; - nmode = kzalloc(sizeof(struct drm_display_mode), GFP_KERNEL); + nmode = kzalloc_obj(struct drm_display_mode); if (!nmode) return NULL; diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c index beb91a13a312..2c806b0146d6 100644 --- a/drivers/gpu/drm/drm_modeset_lock.c +++ b/drivers/gpu/drm/drm_modeset_lock.c @@ -148,7 +148,7 @@ void drm_modeset_lock_all(struct drm_device *dev) struct drm_modeset_acquire_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL); + ctx = kzalloc_obj(*ctx, GFP_KERNEL | __GFP_NOFAIL); if (WARN_ON(!ctx)) return; diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c index 38eca94f01a1..862675ac5bb2 100644 --- a/drivers/gpu/drm/drm_pagemap.c +++ b/drivers/gpu/drm/drm_pagemap.c @@ -94,7 +94,7 @@ drm_pagemap_zdd_alloc(struct drm_pagemap *dpagemap) { struct drm_pagemap_zdd *zdd; - zdd = kmalloc(sizeof(*zdd), GFP_KERNEL); + zdd = kmalloc_obj(*zdd); if (!zdd) return NULL; @@ -318,7 +318,7 @@ static void drm_pagemap_migrate_unmap_pages(struct device *dev, struct drm_pagemap_zdd *zdd = page->zone_device_data; struct drm_pagemap *dpagemap = zdd->dpagemap; - dpagemap->ops->device_unmap(dpagemap, dev, pagemap_addr[i]); + dpagemap->ops->device_unmap(dpagemap, dev, &pagemap_addr[i]); } else { dma_unmap_page(dev, pagemap_addr[i].addr, PAGE_SIZE << pagemap_addr[i].order, dir); @@ -480,18 +480,8 @@ int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation, .start = start, .end = end, .pgmap_owner = pagemap->owner, - /* - * FIXME: MIGRATE_VMA_SELECT_DEVICE_PRIVATE intermittently - * causes 'xe_exec_system_allocator --r *race*no*' to trigger aa - * engine reset and a hard hang due to getting stuck on a folio - * lock. This should work and needs to be root-caused. The only - * downside of not selecting MIGRATE_VMA_SELECT_DEVICE_PRIVATE - * is that device-to-device migrations won’t work; instead, - * memory will bounce through system memory. This path should be - * rare and only occur when the madvise attributes of memory are - * changed or atomics are being used. - */ - .flags = MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT, + .flags = MIGRATE_VMA_SELECT_SYSTEM | MIGRATE_VMA_SELECT_DEVICE_COHERENT | + MIGRATE_VMA_SELECT_DEVICE_PRIVATE, }; unsigned long i, npages = npages_in_range(start, end); unsigned long own_pages = 0, migrated_pages = 0; @@ -861,7 +851,7 @@ drm_pagemap_dev_hold(struct drm_pagemap *dpagemap) struct drm_pagemap_dev_hold *dev_hold; struct drm_device *drm = dpagemap->drm; - dev_hold = kzalloc(sizeof(*dev_hold), GFP_KERNEL); + dev_hold = kzalloc_obj(*dev_hold); if (!dev_hold) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_pagemap_util.c b/drivers/gpu/drm/drm_pagemap_util.c index c6ae3357c7fb..14ddb948a32e 100644 --- a/drivers/gpu/drm/drm_pagemap_util.c +++ b/drivers/gpu/drm/drm_pagemap_util.c @@ -94,7 +94,7 @@ static void drm_pagemap_cache_fini(void *arg) */ struct drm_pagemap_cache *drm_pagemap_cache_create_devm(struct drm_pagemap_shrinker *shrinker) { - struct drm_pagemap_cache *cache = kzalloc(sizeof(*cache), GFP_KERNEL); + struct drm_pagemap_cache *cache = kzalloc_obj(*cache); int err; if (!cache) @@ -424,7 +424,7 @@ struct drm_pagemap_shrinker *drm_pagemap_shrinker_create_devm(struct drm_device struct shrinker *shrink; int err; - shrinker = kzalloc(sizeof(*shrinker), GFP_KERNEL); + shrinker = kzalloc_obj(*shrinker); if (!shrinker) return ERR_PTR(-ENOMEM); @@ -548,7 +548,7 @@ int drm_pagemap_acquire_owner(struct drm_pagemap_peer *peer, } if (!interconnect) { - owner = kmalloc(sizeof(*owner), GFP_KERNEL); + owner = kmalloc_obj(*owner); if (!owner) { mutex_unlock(&owner_list->lock); return -ENOMEM; diff --git a/drivers/gpu/drm/drm_plane.c b/drivers/gpu/drm/drm_plane.c index bed2562bf911..46adef2a30c0 100644 --- a/drivers/gpu/drm/drm_plane.c +++ b/drivers/gpu/drm/drm_plane.c @@ -1514,7 +1514,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, } if (page_flip->flags & DRM_MODE_PAGE_FLIP_EVENT) { - e = kzalloc(sizeof *e, GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { ret = -ENOMEM; goto out; @@ -1844,9 +1844,7 @@ int drm_plane_create_color_pipeline_property(struct drm_plane *plane, int len = 0; int i; - all_pipelines = kcalloc(num_pipelines + 1, - sizeof(*all_pipelines), - GFP_KERNEL); + all_pipelines = kzalloc_objs(*all_pipelines, num_pipelines + 1); if (!all_pipelines) { drm_err(plane->dev, "failed to allocate color pipeline\n"); diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c index 747d248aaf02..9ffcd9e8b58d 100644 --- a/drivers/gpu/drm/drm_plane_helper.c +++ b/drivers/gpu/drm/drm_plane_helper.c @@ -217,8 +217,7 @@ int drm_plane_helper_update_primary(struct drm_plane *plane, struct drm_crtc *cr /* Find current connectors for CRTC */ num_connectors = get_connectors_for_crtc(crtc, NULL, 0); BUG_ON(num_connectors == 0); - connector_list = kcalloc(num_connectors, sizeof(*connector_list), - GFP_KERNEL); + connector_list = kzalloc_objs(*connector_list, num_connectors); if (!connector_list) return -ENOMEM; get_connectors_for_crtc(crtc, connector_list, num_connectors); diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c index 21809a82187b..51fdb06d3e9f 100644 --- a/drivers/gpu/drm/drm_prime.c +++ b/drivers/gpu/drm/drm_prime.c @@ -100,7 +100,7 @@ int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv, struct drm_prime_member *member; struct rb_node **p, *rb; - member = kmalloc(sizeof(*member), GFP_KERNEL); + member = kmalloc_obj(*member); if (!member) return -ENOMEM; @@ -780,8 +780,8 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) return 0; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - fil = kzalloc(sizeof(*fil), GFP_KERNEL); + priv = kzalloc_obj(*priv); + fil = kzalloc_obj(*fil); if (!priv || !fil) { ret = -ENOMEM; goto out; @@ -854,7 +854,7 @@ struct sg_table *drm_prime_pages_to_sg(struct drm_device *dev, size_t max_segment = 0; int err; - sg = kmalloc(sizeof(struct sg_table), GFP_KERNEL); + sg = kmalloc_obj(struct sg_table); if (!sg) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_privacy_screen.c b/drivers/gpu/drm/drm_privacy_screen.c index 8959f7084e0b..a2a6e8368131 100644 --- a/drivers/gpu/drm/drm_privacy_screen.c +++ b/drivers/gpu/drm/drm_privacy_screen.c @@ -395,7 +395,7 @@ struct drm_privacy_screen *drm_privacy_screen_register( struct drm_privacy_screen *priv; int ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_property.c b/drivers/gpu/drm/drm_property.c index 540cd41d8368..f38f2c5437e6 100644 --- a/drivers/gpu/drm/drm_property.c +++ b/drivers/gpu/drm/drm_property.c @@ -107,7 +107,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) return NULL; - property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); + property = kzalloc_obj(struct drm_property); if (!property) return NULL; @@ -417,7 +417,7 @@ int drm_property_add_enum(struct drm_property *property, if (WARN_ON(index >= property->num_values)) return -EINVAL; - prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); + prop_enum = kzalloc_obj(struct drm_property_enum); if (!prop_enum) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_self_refresh_helper.c b/drivers/gpu/drm/drm_self_refresh_helper.c index c0948586b7fd..74907f33841c 100644 --- a/drivers/gpu/drm/drm_self_refresh_helper.c +++ b/drivers/gpu/drm/drm_self_refresh_helper.c @@ -238,7 +238,7 @@ int drm_self_refresh_helper_init(struct drm_crtc *crtc) if (WARN_ON(sr_data)) return -EINVAL; - sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL); + sr_data = kzalloc_obj(*sr_data); if (!sr_data) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_suballoc.c b/drivers/gpu/drm/drm_suballoc.c index 879ea33dbbc4..e44ad39e310c 100644 --- a/drivers/gpu/drm/drm_suballoc.c +++ b/drivers/gpu/drm/drm_suballoc.c @@ -329,7 +329,7 @@ drm_suballoc_new(struct drm_suballoc_manager *sa_manager, size_t size, if (!align) align = sa_manager->align; - sa = kmalloc(sizeof(*sa), gfp); + sa = kmalloc_obj(*sa, gfp); if (!sa) return ERR_PTR(-ENOMEM); sa->manager = sa_manager; diff --git a/drivers/gpu/drm/drm_syncobj.c b/drivers/gpu/drm/drm_syncobj.c index 2d4ab745fdad..250734dee928 100644 --- a/drivers/gpu/drm/drm_syncobj.c +++ b/drivers/gpu/drm/drm_syncobj.c @@ -557,7 +557,7 @@ int drm_syncobj_create(struct drm_syncobj **out_syncobj, uint32_t flags, int ret; struct drm_syncobj *syncobj; - syncobj = kzalloc(sizeof(struct drm_syncobj), GFP_KERNEL); + syncobj = kzalloc_obj(struct drm_syncobj); if (!syncobj) return -ENOMEM; @@ -1062,7 +1062,7 @@ static signed long drm_syncobj_array_wait_timeout(struct drm_syncobj **syncobjs, goto err_free_points; } - entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); + entries = kzalloc_objs(*entries, count); if (!entries) { timeout = -ENOMEM; goto err_free_points; @@ -1279,7 +1279,7 @@ static int drm_syncobj_array_find(struct drm_file *file_private, goto err_free_handles; } - syncobjs = kmalloc_array(count_handles, sizeof(*syncobjs), GFP_KERNEL); + syncobjs = kmalloc_objs(*syncobjs, count_handles); if (syncobjs == NULL) { ret = -ENOMEM; goto err_free_handles; @@ -1485,7 +1485,7 @@ drm_syncobj_eventfd_ioctl(struct drm_device *dev, void *data, goto err_fdget; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { ret = -ENOMEM; goto err_kzalloc; diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index b01ffa4d6509..ef4e923a8728 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -349,7 +349,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) if (connector->kdev) return 0; - kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); + kdev = kzalloc_obj(*kdev); if (!kdev) return -ENOMEM; @@ -554,7 +554,7 @@ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) struct device *kdev; int r; - kdev = kzalloc(sizeof(*kdev), GFP_KERNEL); + kdev = kzalloc_obj(*kdev); if (!kdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c index 42fe11cc139b..f78bf37f1e0a 100644 --- a/drivers/gpu/drm/drm_vblank.c +++ b/drivers/gpu/drm/drm_vblank.c @@ -1615,7 +1615,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, unsigned int pipe, u64 seq; int ret; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (e == NULL) { ret = -ENOMEM; goto err_put; @@ -2094,7 +2094,7 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data, vblank = drm_crtc_vblank_crtc(crtc); - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (e == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c index 58659c16874c..1b8daec1013e 100644 --- a/drivers/gpu/drm/drm_vma_manager.c +++ b/drivers/gpu/drm/drm_vma_manager.c @@ -253,7 +253,7 @@ static int vma_node_allow(struct drm_vma_offset_node *node, * unlikely that an open-file is added twice to a single node so we * don't optimize for this case. OOM is checked below only if the entry * is actually used. */ - new = kmalloc(sizeof(*entry), GFP_KERNEL); + new = kmalloc_obj(*entry); write_lock(&node->vm_lock); diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index 95b8a2e4bda6..09362cf4f22f 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -422,8 +422,7 @@ int drm_writeback_set_fb(struct drm_connector_state *conn_state, WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK); if (!conn_state->writeback_job) { - conn_state->writeback_job = - kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL); + conn_state->writeback_job = kzalloc_obj(*conn_state->writeback_job); if (!conn_state->writeback_job) return -ENOMEM; @@ -581,7 +580,7 @@ drm_writeback_get_out_fence(struct drm_writeback_connector *wb_connector) DRM_MODE_CONNECTOR_WRITEBACK)) return NULL; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c index 3a221923f15d..854292066ce8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c @@ -33,7 +33,7 @@ etnaviv_cmdbuf_suballoc_new(struct device *dev) struct etnaviv_cmdbuf_suballoc *suballoc; int ret; - suballoc = kzalloc(sizeof(*suballoc), GFP_KERNEL); + suballoc = kzalloc_obj(*suballoc); if (!suballoc) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index bb1b84eecec8..08aca9035fc1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -66,7 +66,7 @@ static int etnaviv_open(struct drm_device *dev, struct drm_file *file) struct etnaviv_file_private *ctx; int ret, i; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -531,7 +531,7 @@ static int etnaviv_bind(struct device *dev) if (IS_ERR(drm)) return PTR_ERR(drm); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { dev_err(dev, "failed to allocate private data\n"); ret = -ENOMEM; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c index 58d957ee861d..eb4b253ff835 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_flop_reset.c @@ -182,8 +182,7 @@ int etnaviv_flop_reset_ppu_init(struct etnaviv_drm_private *priv) * (input and output image, and shader), we keep this buffer * for the whole life time the driver is bound */ - priv->flop_reset_data_ppu = - kzalloc(sizeof(*priv->flop_reset_data_ppu), GFP_KERNEL); + priv->flop_reset_data_ppu = kzalloc_obj(*priv->flop_reset_data_ppu); if (!priv->flop_reset_data_ppu) return -ENOMEM; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 5d8f3b03d4ae..b0436a1e103f 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -288,7 +288,7 @@ struct etnaviv_vram_mapping *etnaviv_gem_mapping_get( */ mapping = etnaviv_gem_get_vram_mapping(etnaviv_obj, NULL); if (!mapping) { - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) { ret = -ENOMEM; goto out; @@ -675,7 +675,7 @@ static int etnaviv_gem_userptr_get_pages(struct etnaviv_gem_object *etnaviv_obj) if (userptr->mm != current->mm) return -EPERM; - pvec = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + pvec = kvmalloc_objs(struct page *, npages); if (!pvec) return -ENOMEM; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 40a50c60dfff..6757ae6ec304 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -126,7 +126,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, npages = size / PAGE_SIZE; etnaviv_obj->sgt = sgt; - etnaviv_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + etnaviv_obj->pages = kvmalloc_objs(struct page *, npages); if (!etnaviv_obj->pages) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index a9611c1a773f..fbf693addd74 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -38,8 +38,7 @@ static struct etnaviv_gem_submit *submit_create(struct drm_device *dev, if (!submit) return NULL; - submit->pmrs = kcalloc(nr_pmrs, sizeof(struct etnaviv_perfmon_request), - GFP_KERNEL); + submit->pmrs = kzalloc_objs(struct etnaviv_perfmon_request, nr_pmrs); if (!submit->pmrs) { kfree(submit); return NULL; @@ -468,9 +467,9 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, * Copy the command submission and bo array to kernel space in * one go, and do this outside of any locks. */ - bos = kvmalloc_array(args->nr_bos, sizeof(*bos), GFP_KERNEL); - relocs = kvmalloc_array(args->nr_relocs, sizeof(*relocs), GFP_KERNEL); - pmrs = kvmalloc_array(args->nr_pmrs, sizeof(*pmrs), GFP_KERNEL); + bos = kvmalloc_objs(*bos, args->nr_bos); + relocs = kvmalloc_objs(*relocs, args->nr_relocs); + pmrs = kvmalloc_objs(*pmrs, args->nr_pmrs); stream = kvmalloc_array(1, args->stream_size, GFP_KERNEL); if (!bos || !relocs || !pmrs || !stream) { ret = -ENOMEM; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 94326dddaf6f..a891d4f1f843 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -1184,7 +1184,7 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu) */ lockdep_assert_held(&gpu->lock); - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) return NULL; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c index afe5dd6a9925..38377b2065b7 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_iommu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_iommu.c @@ -143,7 +143,7 @@ etnaviv_iommuv1_context_alloc(struct etnaviv_iommu_global *global) return context; } - v1_context = kzalloc(sizeof(*v1_context), GFP_KERNEL); + v1_context = kzalloc_obj(*v1_context); if (!v1_context) { mutex_unlock(&global->lock); return NULL; diff --git a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c index a992be2ede88..e3572461b599 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_mmu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_mmu.c @@ -494,7 +494,7 @@ int etnaviv_iommu_global_init(struct etnaviv_gpu *gpu) return 0; } - global = kzalloc(sizeof(*global), GFP_KERNEL); + global = kzalloc_obj(*global); if (!global) return -ENOMEM; diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index d19e796c2061..41252caccd67 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -180,7 +180,7 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, struct drm_crtc *crtc; int ret; - exynos_crtc = kzalloc(sizeof(*exynos_crtc), GFP_KERNEL); + exynos_crtc = kzalloc_obj(*exynos_crtc); if (!exynos_crtc) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 6cc7bf77bcac..2101a74dc1ed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -50,7 +50,7 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) struct drm_exynos_file_private *file_priv; int ret; - file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); + file_priv = kzalloc_obj(*file_priv); if (!file_priv) return -ENOMEM; @@ -245,7 +245,7 @@ static int exynos_drm_bind(struct device *dev) if (IS_ERR(drm)) return PTR_ERR(drm); - private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); + private = kzalloc_obj(struct exynos_drm_private); if (!private) { ret = -ENOMEM; goto err_free_drm; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 6ecd95bcb0c4..ab0e0c74ec47 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c @@ -66,7 +66,7 @@ exynos_drm_framebuffer_init(struct drm_device *dev, int i; int ret; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 2bea107dd960..348603262af0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -287,7 +287,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) return -ENOMEM; } - node = kcalloc(G2D_CMDLIST_NUM, sizeof(*node), GFP_KERNEL); + node = kzalloc_objs(*node, G2D_CMDLIST_NUM); if (!node) { ret = -ENOMEM; goto err; @@ -459,7 +459,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, } } - g2d_userptr = kzalloc(sizeof(*g2d_userptr), GFP_KERNEL); + g2d_userptr = kzalloc_obj(*g2d_userptr); if (!g2d_userptr) return ERR_PTR(-ENOMEM); @@ -470,8 +470,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, offset = userptr & ~PAGE_MASK; end = PAGE_ALIGN(userptr + size); npages = (end - start) >> PAGE_SHIFT; - g2d_userptr->pages = kvmalloc_array(npages, sizeof(*g2d_userptr->pages), - GFP_KERNEL); + g2d_userptr->pages = kvmalloc_objs(*g2d_userptr->pages, npages); if (!g2d_userptr->pages) { ret = -ENOMEM; goto err_free; @@ -491,7 +490,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct g2d_data *g2d, } g2d_userptr->npages = npages; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto err_unpin_pages; @@ -1169,7 +1168,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, node->event = NULL; if (req->event_type != G2D_EVENT_NOT) { - e = kzalloc(sizeof(*node->event), GFP_KERNEL); + e = kzalloc_obj(*node->event); if (!e) { ret = -ENOMEM; goto err; diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index b9b2f000072d..69ef6cda1ce9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -152,7 +152,7 @@ static struct exynos_drm_gem *exynos_drm_gem_init(struct drm_device *dev, struct drm_gem_object *obj; int ret; - exynos_gem = kzalloc(sizeof(*exynos_gem), GFP_KERNEL); + exynos_gem = kzalloc_obj(*exynos_gem); if (!exynos_gem) return ERR_PTR(-ENOMEM); @@ -411,7 +411,7 @@ struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj) struct sg_table *sgt; int ret; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/exynos/exynos_drm_ipp.c b/drivers/gpu/drm/exynos/exynos_drm_ipp.c index 008def51225a..ee3d61345a66 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_ipp.c +++ b/drivers/gpu/drm/exynos/exynos_drm_ipp.c @@ -260,7 +260,7 @@ static inline struct exynos_drm_ipp_task * { struct exynos_drm_ipp_task *task; - task = kzalloc(sizeof(*task), GFP_KERNEL); + task = kzalloc_obj(*task); if (!task) return NULL; @@ -699,7 +699,7 @@ static int exynos_drm_ipp_event_create(struct exynos_drm_ipp_task *task, struct drm_pending_exynos_ipp_event *e = NULL; int ret; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 67afddd566e2..da043bd357a4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -134,7 +134,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane) plane->state = NULL; } - exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL); + exynos_state = kzalloc_obj(*exynos_state); if (exynos_state) { __drm_atomic_helper_plane_reset(plane, &exynos_state->base); plane->state->zpos = exynos_plane->config->zpos; @@ -148,7 +148,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane) struct exynos_drm_plane_state *copy; exynos_state = to_exynos_plane_state(plane->state); - copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL); + copy = kzalloc_obj(*exynos_state); if (!copy) return NULL; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c index a9a341ea6507..a9b3467263d6 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c @@ -209,7 +209,7 @@ struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev) struct drm_plane *primary; int ret; - primary = kzalloc(sizeof(*primary), GFP_KERNEL); + primary = kzalloc_obj(*primary); if (!primary) { DRM_DEBUG_KMS("Failed to allocate primary plane\n"); return NULL; diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index 06fe7480e7af..342a57c82846 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c @@ -250,11 +250,11 @@ void cdv_intel_crt_init(struct drm_device *dev, struct drm_encoder *encoder; int ret; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto err_free_encoder; diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 5942a9d46b02..a901721ea73a 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -939,7 +939,7 @@ struct drm_display_mode *cdv_intel_crtc_mode_get(struct drm_device *dev, vsync = p->vsync; } - mode = kzalloc(sizeof(*mode), GFP_KERNEL); + mode = kzalloc_obj(*mode); if (!mode) return NULL; diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index 54bf626f0524..fbed35cf7603 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -1953,13 +1953,13 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev const char *name = NULL; int type = DRM_MODE_CONNECTOR_DisplayPort; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto err_connector; - intel_dp = kzalloc(sizeof(struct cdv_intel_dp), GFP_KERNEL); + intel_dp = kzalloc_obj(struct cdv_intel_dp); if (!intel_dp) goto err_priv; diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 8e93ee0d0ccd..ce7850647778 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c @@ -284,15 +284,15 @@ void cdv_hdmi_init(struct drm_device *dev, int ddc_reg; int ret; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto err_free_encoder; - hdmi_priv = kzalloc(sizeof(struct mid_intel_hdmi_priv), GFP_KERNEL); + hdmi_priv = kzalloc_obj(struct mid_intel_hdmi_priv); if (!hdmi_priv) goto err_free_connector; diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index fbe7fe317393..d7fd9a783cde 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -501,17 +501,15 @@ void cdv_intel_lvds_init(struct drm_device *dev, return; } - gma_encoder = kzalloc(sizeof(struct gma_encoder), - GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), - GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto err_free_encoder; - lvds_priv = kzalloc(sizeof(struct cdv_intel_lvds_priv), GFP_KERNEL); + lvds_priv = kzalloc_obj(struct cdv_intel_lvds_priv); if (!lvds_priv) goto err_free_connector; diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index e69b537ded6b..fe1f43f0abff 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -75,7 +75,7 @@ struct drm_framebuffer *psb_framebuffer_create(struct drm_device *dev, struct drm_framebuffer *fb; int ret; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 2e44a2ac2742..88f1e86c8903 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -146,7 +146,7 @@ psb_gem_create(struct drm_device *dev, u64 size, const char *name, bool stolen, size = roundup(size, PAGE_SIZE); - pobj = kzalloc(sizeof(*pobj), GFP_KERNEL); + pobj = kzalloc_obj(*pobj); if (!pobj) return ERR_PTR(-ENOMEM); obj = &pobj->base; diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index b60720560830..c6a945358e3e 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c @@ -247,8 +247,7 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv, entry = &lvds_lfp_data->data[lvds_options->panel_type]; dvo_timing = &entry->dvo_timing; - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), - GFP_KERNEL); + panel_fixed_mode = kzalloc_obj(*panel_fixed_mode); if (panel_fixed_mode == NULL) { dev_err(dev_priv->dev.dev, "out of memory for fixed panel mode\n"); return; @@ -286,7 +285,7 @@ static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv, if (!dvo_timing) return; - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + panel_fixed_mode = kzalloc_obj(*panel_fixed_mode); if (!panel_fixed_mode) return; @@ -478,7 +477,7 @@ parse_device_mapping(struct drm_psb_private *dev_priv, DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); return; } - dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); + dev_priv->child_dev = kzalloc_objs(*p_child, count); if (!dev_priv->child_dev) { DRM_DEBUG_KMS("No memory space for child devices\n"); return; diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 2b06ba22f9c6..5933ae04a6aa 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c @@ -187,7 +187,7 @@ intel_gpio_create(struct drm_psb_private *dev_priv, u32 pin) if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) return NULL; - gpio = kzalloc(sizeof(struct intel_gpio), GFP_KERNEL); + gpio = kzalloc_obj(struct intel_gpio); if (gpio == NULL) return NULL; @@ -399,8 +399,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) struct drm_psb_private *dev_priv = to_drm_psb_private(dev); int ret, i; - dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus), - GFP_KERNEL); + dev_priv->gmbus = kzalloc_objs(struct intel_gmbus, GMBUS_NUM_PORTS); if (dev_priv->gmbus == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/gma500/intel_i2c.c b/drivers/gpu/drm/gma500/intel_i2c.c index 9d02a7b6d9a3..ab8217796817 100644 --- a/drivers/gpu/drm/gma500/intel_i2c.c +++ b/drivers/gpu/drm/gma500/intel_i2c.c @@ -107,7 +107,7 @@ struct gma_i2c_chan *gma_i2c_create(struct drm_device *dev, const u32 reg, { struct gma_i2c_chan *chan; - chan = kzalloc(sizeof(struct gma_i2c_chan), GFP_KERNEL); + chan = kzalloc_obj(struct gma_i2c_chan); if (!chan) goto out_free; diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c index 0326f3ddc621..428aff92a7bb 100644 --- a/drivers/gpu/drm/gma500/mid_bios.c +++ b/drivers/gpu/drm/gma500/mid_bios.c @@ -228,7 +228,7 @@ static int mid_get_vbt_data_r10(struct drm_psb_private *dev_priv, u32 addr) if (read_vbt_r10(addr, &vbt)) return -1; - gct = kmalloc_array(vbt.panel_count, sizeof(*gct), GFP_KERNEL); + gct = kmalloc_objs(*gct, vbt.panel_count); if (!gct) return -ENOMEM; diff --git a/drivers/gpu/drm/gma500/mmu.c b/drivers/gpu/drm/gma500/mmu.c index e6753282e70e..6b6b44e426cf 100644 --- a/drivers/gpu/drm/gma500/mmu.c +++ b/drivers/gpu/drm/gma500/mmu.c @@ -158,7 +158,7 @@ static inline uint32_t psb_mmu_mask_pte(uint32_t pfn, int type) struct psb_mmu_pd *psb_mmu_alloc_pd(struct psb_mmu_driver *driver, int trap_pagefaults, int invalid_type) { - struct psb_mmu_pd *pd = kmalloc(sizeof(*pd), GFP_KERNEL); + struct psb_mmu_pd *pd = kmalloc_obj(*pd); uint32_t *v; int i; @@ -260,7 +260,7 @@ void psb_mmu_free_pagedir(struct psb_mmu_pd *pd) static struct psb_mmu_pt *psb_mmu_alloc_pt(struct psb_mmu_pd *pd) { - struct psb_mmu_pt *pt = kmalloc(sizeof(*pt), GFP_KERNEL); + struct psb_mmu_pt *pt = kmalloc_obj(*pt); void *v; uint32_t clflush_add = pd->driver->clflush_add >> PAGE_SHIFT; uint32_t clflush_count = PAGE_SIZE / clflush_add; @@ -425,7 +425,7 @@ struct psb_mmu_driver *psb_mmu_driver_init(struct drm_device *dev, struct psb_mmu_driver *driver; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - driver = kmalloc(sizeof(*driver), GFP_KERNEL); + driver = kmalloc_obj(*driver); if (!driver) return NULL; diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index 20d027d552c7..58d7e191fd56 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -633,11 +633,11 @@ void oaktrail_hdmi_init(struct drm_device *dev, struct drm_connector *connector; struct drm_encoder *encoder; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto failed_connector; @@ -677,7 +677,7 @@ void oaktrail_hdmi_setup(struct drm_device *dev) if (!pdev) return; - hdmi_dev = kzalloc(sizeof(struct oaktrail_hdmi_dev), GFP_KERNEL); + hdmi_dev = kzalloc_obj(struct oaktrail_hdmi_dev); if (!hdmi_dev) { dev_err(dev->dev, "failed to allocate memory\n"); goto out; diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c index 48e8ac560a2a..2a7916ca5907 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c @@ -280,7 +280,7 @@ int oaktrail_hdmi_i2c_init(struct pci_dev *dev) hdmi_dev = pci_get_drvdata(dev); - i2c_dev = kzalloc(sizeof(struct hdmi_i2c_dev), GFP_KERNEL); + i2c_dev = kzalloc_obj(struct hdmi_i2c_dev); if (!i2c_dev) return -ENOMEM; diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 0705ba3813e6..884d324f0044 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -223,7 +223,7 @@ static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev, /* Use the firmware provided data on Moorestown */ if (dev_priv->has_gct) { - mode = kzalloc(sizeof(*mode), GFP_KERNEL); + mode = kzalloc_obj(*mode); if (!mode) return; @@ -302,11 +302,11 @@ void oaktrail_lvds_init(struct drm_device *dev, struct drm_display_mode *scan; /* *modes, *bios_mode; */ int ret; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) return; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) goto err_free_encoder; diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c b/drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c index 939c53fd09e8..bbfbe893d1c4 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c @@ -135,7 +135,7 @@ struct gma_i2c_chan *oaktrail_lvds_i2c_init(struct drm_device *dev) struct gma_i2c_chan *chan; int ret; - chan = kzalloc(sizeof(struct gma_i2c_chan), GFP_KERNEL); + chan = kzalloc_obj(struct gma_i2c_chan); if (!chan) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index 1ff2bd23db74..0df75a4a7739 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -404,7 +404,7 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev, vsync = p->vsync; } - mode = kzalloc(sizeof(*mode), GFP_KERNEL); + mode = kzalloc_obj(*mode); if (!mode) return NULL; @@ -487,7 +487,7 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, return; gma_crtc->crtc_state = - kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL); + kzalloc_obj(struct psb_intel_crtc_state); if (!gma_crtc->crtc_state) { dev_err(dev->dev, "Crtc state error: No memory\n"); kfree(gma_crtc); diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index f8f3c42e67a7..2ca164b21293 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -639,20 +639,20 @@ void psb_intel_lvds_init(struct drm_device *dev, int pipe; int ret; - gma_encoder = kzalloc(sizeof(struct gma_encoder), GFP_KERNEL); + gma_encoder = kzalloc_obj(struct gma_encoder); if (!gma_encoder) { dev_err(dev->dev, "gma_encoder allocation error\n"); return; } encoder = &gma_encoder->base; - gma_connector = kzalloc(sizeof(struct gma_connector), GFP_KERNEL); + gma_connector = kzalloc_obj(struct gma_connector); if (!gma_connector) { dev_err(dev->dev, "gma_connector allocation error\n"); goto err_free_encoder; } - lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL); + lvds_priv = kzalloc_obj(struct psb_intel_lvds_priv); if (!lvds_priv) { dev_err(dev->dev, "LVDS private allocation error\n"); goto err_free_connector; diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 553e7c7d9bb8..3ca11aad569d 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1977,7 +1977,7 @@ psb_intel_sdvo_dvi_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) struct gma_connector *intel_connector; struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); + psb_intel_sdvo_connector = kzalloc_obj(struct psb_intel_sdvo_connector); if (!psb_intel_sdvo_connector) return false; @@ -2017,7 +2017,7 @@ psb_intel_sdvo_tv_init(struct psb_intel_sdvo *psb_intel_sdvo, int type) struct gma_connector *intel_connector; struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); + psb_intel_sdvo_connector = kzalloc_obj(struct psb_intel_sdvo_connector); if (!psb_intel_sdvo_connector) return false; @@ -2056,7 +2056,7 @@ psb_intel_sdvo_analog_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) struct gma_connector *intel_connector; struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); + psb_intel_sdvo_connector = kzalloc_obj(struct psb_intel_sdvo_connector); if (!psb_intel_sdvo_connector) return false; @@ -2090,7 +2090,7 @@ psb_intel_sdvo_lvds_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) struct gma_connector *intel_connector; struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; - psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); + psb_intel_sdvo_connector = kzalloc_obj(struct psb_intel_sdvo_connector); if (!psb_intel_sdvo_connector) return false; @@ -2442,7 +2442,7 @@ bool psb_intel_sdvo_init(struct drm_device *dev, int sdvo_reg) struct psb_intel_sdvo *psb_intel_sdvo; int i; - psb_intel_sdvo = kzalloc(sizeof(struct psb_intel_sdvo), GFP_KERNEL); + psb_intel_sdvo = kzalloc_obj(struct psb_intel_sdvo); if (!psb_intel_sdvo) return false; diff --git a/drivers/gpu/drm/gud/gud_connector.c b/drivers/gpu/drm/gud/gud_connector.c index 1726a3fadff8..a91a7e96cb88 100644 --- a/drivers/gpu/drm/gud/gud_connector.c +++ b/drivers/gpu/drm/gud/gud_connector.c @@ -246,7 +246,7 @@ static int gud_connector_get_modes(struct drm_connector *connector) if (drm_edid && edid_ctx.edid_override) goto out; - reqmodes = kmalloc_array(GUD_CONNECTOR_MAX_NUM_MODES, sizeof(*reqmodes), GFP_KERNEL); + reqmodes = kmalloc_objs(*reqmodes, GUD_CONNECTOR_MAX_NUM_MODES); if (!reqmodes) goto out; @@ -479,7 +479,7 @@ static int gud_connector_add_properties(struct gud_device *gdrm, struct gud_conn unsigned int i, num_properties; int ret; - properties = kcalloc(GUD_CONNECTOR_PROPERTIES_MAX_NUM, sizeof(*properties), GFP_KERNEL); + properties = kzalloc_objs(*properties, GUD_CONNECTOR_PROPERTIES_MAX_NUM); if (!properties) return -ENOMEM; @@ -619,7 +619,7 @@ static int gud_connector_create(struct gud_device *gdrm, unsigned int index, int ret, connector_type; u32 flags; - gconn = kzalloc(sizeof(*gconn), GFP_KERNEL); + gconn = kzalloc_obj(*gconn); if (!gconn) return -ENOMEM; @@ -698,7 +698,7 @@ int gud_get_connectors(struct gud_device *gdrm) unsigned int i, num_connectors; int ret; - descs = kmalloc_array(GUD_CONNECTORS_MAX_NUM, sizeof(*descs), GFP_KERNEL); + descs = kmalloc_objs(*descs, GUD_CONNECTORS_MAX_NUM); if (!descs) return -ENOMEM; diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c index 42135a48d92e..17c2dead2c13 100644 --- a/drivers/gpu/drm/gud/gud_drv.c +++ b/drivers/gpu/drm/gud/gud_drv.c @@ -82,7 +82,7 @@ static int gud_get_display_descriptor(struct usb_interface *intf, void *buf; int ret; - buf = kmalloc(sizeof(*desc), GFP_KERNEL); + buf = kmalloc_obj(*desc); if (!buf) return -ENOMEM; @@ -135,7 +135,7 @@ static int gud_usb_get_status(struct usb_interface *intf) int ret, status = -EIO; u8 *buf; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) return -ENOMEM; @@ -255,7 +255,7 @@ static int gud_plane_add_properties(struct gud_device *gdrm) unsigned int i, num_properties; int ret; - properties = kcalloc(GUD_PROPERTIES_MAX_NUM, sizeof(*properties), GFP_KERNEL); + properties = kzalloc_objs(*properties, GUD_PROPERTIES_MAX_NUM); if (!properties) return -ENOMEM; @@ -339,7 +339,9 @@ static int gud_stats_debugfs(struct seq_file *m, void *data) } static const struct drm_crtc_helper_funcs gud_crtc_helper_funcs = { - .atomic_check = drm_crtc_helper_atomic_check + .atomic_check = drm_crtc_helper_atomic_check, + .atomic_enable = gud_crtc_atomic_enable, + .atomic_disable = gud_crtc_atomic_disable, }; static const struct drm_crtc_funcs gud_crtc_funcs = { @@ -364,6 +366,10 @@ static const struct drm_plane_funcs gud_plane_funcs = { DRM_GEM_SHADOW_PLANE_FUNCS, }; +static const struct drm_mode_config_helper_funcs gud_mode_config_helpers = { + .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm, +}; + static const struct drm_mode_config_funcs gud_mode_config_funcs = { .fb_create = drm_gem_fb_create_with_dirty, .atomic_check = drm_atomic_helper_check, @@ -401,7 +407,7 @@ static int gud_alloc_bulk_buffer(struct gud_device *gdrm) return -ENOMEM; num_pages = DIV_ROUND_UP(gdrm->bulk_len, PAGE_SIZE); - pages = kmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, num_pages); if (!pages) return -ENOMEM; @@ -499,6 +505,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id) drm->mode_config.min_height = le32_to_cpu(desc.min_height); drm->mode_config.max_height = le32_to_cpu(desc.max_height); drm->mode_config.funcs = &gud_mode_config_funcs; + drm->mode_config.helper_private = &gud_mode_config_helpers; /* Format init */ formats_dev = devm_kmalloc(dev, GUD_FORMATS_MAX_NUM, GFP_KERNEL); diff --git a/drivers/gpu/drm/gud/gud_internal.h b/drivers/gpu/drm/gud/gud_internal.h index d27c31648341..8eec8335f5f9 100644 --- a/drivers/gpu/drm/gud/gud_internal.h +++ b/drivers/gpu/drm/gud/gud_internal.h @@ -62,6 +62,10 @@ int gud_usb_set_u8(struct gud_device *gdrm, u8 request, u8 val); void gud_clear_damage(struct gud_device *gdrm); void gud_flush_work(struct work_struct *work); +void gud_crtc_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state); +void gud_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_state *state); int gud_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state); void gud_plane_atomic_update(struct drm_plane *plane, diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c index 4b77be94348d..b355bf4d3389 100644 --- a/drivers/gpu/drm/gud/gud_pipe.c +++ b/drivers/gpu/drm/gud/gud_pipe.c @@ -580,6 +580,39 @@ int gud_plane_atomic_check(struct drm_plane *plane, return ret; } +void gud_crtc_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_device *drm = crtc->dev; + struct gud_device *gdrm = to_gud_device(drm); + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 1); + gud_usb_set(gdrm, GUD_REQ_SET_STATE_COMMIT, 0, NULL, 0); + gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, 1); + + drm_dev_exit(idx); +} + +void gud_crtc_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_device *drm = crtc->dev; + struct gud_device *gdrm = to_gud_device(drm); + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, 0); + gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 0); + + drm_dev_exit(idx); +} + void gud_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *atomic_state) { @@ -607,24 +640,12 @@ void gud_plane_atomic_update(struct drm_plane *plane, mutex_unlock(&gdrm->damage_lock); } - if (!drm_dev_enter(drm, &idx)) + if (!crtc || !drm_dev_enter(drm, &idx)) return; - if (!old_state->fb) - gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 1); - - if (fb && (crtc->state->mode_changed || crtc->state->connectors_changed)) - gud_usb_set(gdrm, GUD_REQ_SET_STATE_COMMIT, 0, NULL, 0); - - if (crtc->state->active_changed) - gud_usb_set_u8(gdrm, GUD_REQ_SET_DISPLAY_ENABLE, crtc->state->active); - - if (!fb) - goto ctrl_disable; - ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); if (ret) - goto ctrl_disable; + goto out; drm_atomic_helper_damage_iter_init(&iter, old_state, new_state); drm_atomic_for_each_plane_damage(&iter, &damage) @@ -632,9 +653,6 @@ void gud_plane_atomic_update(struct drm_plane *plane, drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); -ctrl_disable: - if (!crtc->state->enable) - gud_usb_set_u8(gdrm, GUD_REQ_SET_CONTROLLER_ENABLE, 0); - +out: drm_dev_exit(idx); } diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c index 013a7829182d..051ecc526832 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_proto.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_proto.c @@ -1,8 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright 2021 Microsoft - * - * Portions of this code is derived from hyperv_fb.c */ #include @@ -304,16 +302,13 @@ int hyperv_update_situation(struct hv_device *hdev, u8 active, u32 bpp, * but the Hyper-V host still draws a point as an extra mouse pointer, * which is unwanted, especially when Xorg is running. * - * The hyperv_fb driver uses synthvid_send_ptr() to hide the unwanted - * pointer, by setting msg.ptr_pos.is_visible = 1 and setting the - * msg.ptr_shape.data. Note: setting msg.ptr_pos.is_visible to 0 doesn't + * Hide the unwanted pointer, by setting msg.ptr_pos.is_visible = 1 and setting + * the msg.ptr_shape.data. Note: setting msg.ptr_pos.is_visible to 0 doesn't * work in tests. * - * Copy synthvid_send_ptr() to hyperv_drm and rename it to - * hyperv_hide_hw_ptr(). Note: hyperv_hide_hw_ptr() is also called in the - * handler of the SYNTHVID_FEATURE_CHANGE event, otherwise the host still - * draws an extra unwanted mouse pointer after the VM Connection window is - * closed and reopened. + * The hyperv_hide_hw_ptr() is also called in the handler of the + * SYNTHVID_FEATURE_CHANGE event, otherwise the host still draws an extra + * unwanted mouse pointer after the VM Connection window is closed and reopened. */ int hyperv_hide_hw_ptr(struct hv_device *hdev) { diff --git a/drivers/gpu/drm/i915/display/dvo_ch7017.c b/drivers/gpu/drm/i915/display/dvo_ch7017.c index f10c0fb8d2c8..326b08e7a362 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7017.c @@ -207,7 +207,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, const char *str; u8 val; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c index 49f02aca818b..1382fe195bb1 100644 --- a/drivers/gpu/drm/i915/display/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/display/dvo_ch7xxx.c @@ -218,7 +218,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, u8 vendor, device; char *name, *devid; - ch7xxx = kzalloc(sizeof(*ch7xxx), GFP_KERNEL); + ch7xxx = kzalloc_obj(*ch7xxx); if (ch7xxx == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/dvo_ivch.c b/drivers/gpu/drm/i915/display/dvo_ivch.c index 0713b2709412..0970dc6fd73d 100644 --- a/drivers/gpu/drm/i915/display/dvo_ivch.c +++ b/drivers/gpu/drm/i915/display/dvo_ivch.c @@ -269,7 +269,7 @@ static bool ivch_init(struct intel_dvo_device *dvo, u16 temp; int i; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/dvo_ns2501.c b/drivers/gpu/drm/i915/display/dvo_ns2501.c index 80b71bd6a837..6a6072b78410 100644 --- a/drivers/gpu/drm/i915/display/dvo_ns2501.c +++ b/drivers/gpu/drm/i915/display/dvo_ns2501.c @@ -476,7 +476,7 @@ static bool ns2501_init(struct intel_dvo_device *dvo, struct ns2501_priv *ns; unsigned char ch; - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_obj(*ns); if (ns == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/dvo_sil164.c b/drivers/gpu/drm/i915/display/dvo_sil164.c index 017b617a8069..c6989a4bad0f 100644 --- a/drivers/gpu/drm/i915/display/dvo_sil164.c +++ b/drivers/gpu/drm/i915/display/dvo_sil164.c @@ -143,7 +143,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, struct sil164_priv *sil; unsigned char ch; - sil = kzalloc(sizeof(*sil), GFP_KERNEL); + sil = kzalloc_obj(*sil); if (sil == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/dvo_tfp410.c b/drivers/gpu/drm/i915/display/dvo_tfp410.c index ed560e3438db..10d8dd4f4d17 100644 --- a/drivers/gpu/drm/i915/display/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/display/dvo_tfp410.c @@ -175,7 +175,7 @@ static bool tfp410_init(struct intel_dvo_device *dvo, struct tfp410_priv *tfp; int id; - tfp = kzalloc(sizeof(*tfp), GFP_KERNEL); + tfp = kzalloc_obj(*tfp); if (tfp == NULL) return false; diff --git a/drivers/gpu/drm/i915/display/icl_dsi.c b/drivers/gpu/drm/i915/display/icl_dsi.c index dac781f54661..fc265f71d72b 100644 --- a/drivers/gpu/drm/i915/display/icl_dsi.c +++ b/drivers/gpu/drm/i915/display/icl_dsi.c @@ -1934,7 +1934,7 @@ void icl_dsi_init(struct intel_display *display, if (port == PORT_NONE) return; - intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); + intel_dsi = kzalloc_obj(*intel_dsi); if (!intel_dsi) return; diff --git a/drivers/gpu/drm/i915/display/intel_acpi.c b/drivers/gpu/drm/i915/display/intel_acpi.c index 68c01932f7b4..e06f324027be 100644 --- a/drivers/gpu/drm/i915/display/intel_acpi.c +++ b/drivers/gpu/drm/i915/display/intel_acpi.c @@ -96,6 +96,7 @@ static void intel_dsm_platform_mux_info(acpi_handle dhandle) if (!pkg->package.count) { DRM_DEBUG_DRIVER("no connection in _DSM\n"); + ACPI_FREE(pkg); return; } diff --git a/drivers/gpu/drm/i915/display/intel_alpm.c b/drivers/gpu/drm/i915/display/intel_alpm.c index 7ce8c674bb03..f4f1b68f7543 100644 --- a/drivers/gpu/drm/i915/display/intel_alpm.c +++ b/drivers/gpu/drm/i915/display/intel_alpm.c @@ -43,12 +43,6 @@ bool intel_alpm_is_alpm_aux_less(struct intel_dp *intel_dp, void intel_alpm_init(struct intel_dp *intel_dp) { - u8 dpcd; - - if (drm_dp_dpcd_readb(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, &dpcd) < 0) - return; - - intel_dp->alpm_dpcd = dpcd; mutex_init(&intel_dp->alpm.lock); } @@ -562,12 +556,7 @@ void intel_alpm_disable(struct intel_dp *intel_dp) mutex_lock(&intel_dp->alpm.lock); intel_de_rmw(display, ALPM_CTL(display, cpu_transcoder), - ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE | - ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); - - intel_de_rmw(display, - PORT_ALPM_CTL(cpu_transcoder), - PORT_ALPM_CTL_ALPM_AUX_LESS_ENABLE, 0); + ALPM_CTL_ALPM_ENABLE | ALPM_CTL_LOBF_ENABLE, 0); drm_dbg_kms(display->drm, "Disabling ALPM\n"); mutex_unlock(&intel_dp->alpm.lock); diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c index 348b1655435e..71b7325917b6 100644 --- a/drivers/gpu/drm/i915/display/intel_atomic.c +++ b/drivers/gpu/drm/i915/display/intel_atomic.c @@ -323,7 +323,7 @@ intel_crtc_destroy_state(struct drm_crtc *crtc, struct drm_atomic_state * intel_atomic_state_alloc(struct drm_device *dev) { - struct intel_atomic_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct intel_atomic_state *state = kzalloc_obj(*state); if (!state || drm_atomic_state_init(dev, &state->base) < 0) { kfree(state); diff --git a/drivers/gpu/drm/i915/display/intel_bios.c b/drivers/gpu/drm/i915/display/intel_bios.c index ae0b922d5bc3..a1fa3571eca0 100644 --- a/drivers/gpu/drm/i915/display/intel_bios.c +++ b/drivers/gpu/drm/i915/display/intel_bios.c @@ -486,8 +486,7 @@ init_bdb_block(struct intel_display *display, if (section_id == BDB_MIPI_SEQUENCE && *(const u8 *)block >= 3) block_size += 5; - entry = kzalloc(struct_size(entry, data, max(min_size, block_size) + 3), - GFP_KERNEL); + entry = kzalloc_flex(*entry, data, max(min_size, block_size) + 3); if (!entry) { kfree(temp_block); return; @@ -852,7 +851,7 @@ parse_lfp_panel_dtd(struct intel_display *display, lfp_data_ptrs, panel_type); - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + panel_fixed_mode = kzalloc_obj(*panel_fixed_mode); if (!panel_fixed_mode) return; @@ -968,7 +967,7 @@ parse_generic_dtd(struct intel_display *display, dtd = &generic_dtd->dtd[panel->vbt.panel_type]; - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + panel_fixed_mode = kzalloc_obj(*panel_fixed_mode); if (!panel_fixed_mode) return; @@ -1141,7 +1140,7 @@ parse_sdvo_lvds_data(struct intel_display *display, return; } - panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); + panel_fixed_mode = kzalloc_obj(*panel_fixed_mode); if (!panel_fixed_mode) return; @@ -2929,7 +2928,7 @@ parse_general_definitions(struct intel_display *display) "Found VBT child device with type 0x%x\n", child->device_type); - devdata = kzalloc(sizeof(*devdata), GFP_KERNEL); + devdata = kzalloc_obj(*devdata); if (!devdata) break; @@ -3010,7 +3009,7 @@ init_vbt_missing_defaults(struct intel_display *display) continue; /* Create fake child device config */ - devdata = kzalloc(sizeof(*devdata), GFP_KERNEL); + devdata = kzalloc_obj(*devdata); if (!devdata) break; diff --git a/drivers/gpu/drm/i915/display/intel_bw.c b/drivers/gpu/drm/i915/display/intel_bw.c index 4ee3f5172f4e..fe48949b5880 100644 --- a/drivers/gpu/drm/i915/display/intel_bw.c +++ b/drivers/gpu/drm/i915/display/intel_bw.c @@ -1470,7 +1470,7 @@ int intel_bw_init(struct intel_display *display) { struct intel_bw_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c index 9bfbfbf34dc0..f5946e677c93 100644 --- a/drivers/gpu/drm/i915/display/intel_cdclk.c +++ b/drivers/gpu/drm/i915/display/intel_cdclk.c @@ -3409,7 +3409,7 @@ int intel_cdclk_init(struct intel_display *display) { struct intel_cdclk_state *cdclk_state; - cdclk_state = kzalloc(sizeof(*cdclk_state), GFP_KERNEL); + cdclk_state = kzalloc_obj(*cdclk_state); if (!cdclk_state) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_colorop.c b/drivers/gpu/drm/i915/display/intel_colorop.c index 1d84933f05aa..a898b8d73dd8 100644 --- a/drivers/gpu/drm/i915/display/intel_colorop.c +++ b/drivers/gpu/drm/i915/display/intel_colorop.c @@ -15,7 +15,7 @@ struct intel_colorop *intel_colorop_alloc(void) { struct intel_colorop *colorop; - colorop = kzalloc(sizeof(*colorop), GFP_KERNEL); + colorop = kzalloc_obj(*colorop); if (!colorop) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_connector.c b/drivers/gpu/drm/i915/display/intel_connector.c index 682bf1be350d..7ef9338d67ab 100644 --- a/drivers/gpu/drm/i915/display/intel_connector.c +++ b/drivers/gpu/drm/i915/display/intel_connector.c @@ -86,7 +86,7 @@ static int intel_connector_init(struct intel_connector *connector) * need it we'll free the state and allocate a smaller one on the first * successful commit anyway. */ - conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL); + conn_state = kzalloc_obj(*conn_state); if (!conn_state) return -ENOMEM; @@ -105,7 +105,7 @@ struct intel_connector *intel_connector_alloc(void) { struct intel_connector *connector; - connector = kzalloc(sizeof(*connector), GFP_KERNEL); + connector = kzalloc_obj(*connector); if (!connector) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_crt.c b/drivers/gpu/drm/i915/display/intel_crt.c index 5f9a03877ea9..59d637c6a187 100644 --- a/drivers/gpu/drm/i915/display/intel_crt.c +++ b/drivers/gpu/drm/i915/display/intel_crt.c @@ -1037,7 +1037,7 @@ void intel_crt_init(struct intel_display *display) intel_de_write(display, adpa_reg, adpa); } - crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); + crt = kzalloc_obj(struct intel_crt); if (!crt) return; diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c index 778ebc5095c3..53378d2dcbec 100644 --- a/drivers/gpu/drm/i915/display/intel_crtc.c +++ b/drivers/gpu/drm/i915/display/intel_crtc.c @@ -168,7 +168,7 @@ struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc) { struct intel_crtc_state *crtc_state; - crtc_state = kmalloc(sizeof(*crtc_state), GFP_KERNEL); + crtc_state = kmalloc_obj(*crtc_state); if (crtc_state) intel_crtc_state_reset(crtc_state, crtc); @@ -196,7 +196,7 @@ static struct intel_crtc *intel_crtc_alloc(void) struct intel_crtc_state *crtc_state; struct intel_crtc *crtc; - crtc = kzalloc(sizeof(*crtc), GFP_KERNEL); + crtc = kzalloc_obj(*crtc); if (!crtc) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c index 8b8894c37f63..0562d4df6a07 100644 --- a/drivers/gpu/drm/i915/display/intel_dbuf_bw.c +++ b/drivers/gpu/drm/i915/display/intel_dbuf_bw.c @@ -284,7 +284,7 @@ int intel_dbuf_bw_init(struct intel_display *display) { struct intel_dbuf_bw_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 81b3a6692ca2..c4246481fc2f 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -1614,7 +1614,6 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta } intel_set_transcoder_timings(crtc_state); - intel_vrr_set_transcoder_timings(crtc_state); if (cpu_transcoder != TRANSCODER_EDP) intel_de_write(display, TRANS_MULT(display, cpu_transcoder), @@ -4122,7 +4121,7 @@ intel_encoder_current_mode(struct intel_encoder *encoder) crtc = intel_crtc_for_pipe(display, pipe); - mode = kzalloc(sizeof(*mode), GFP_KERNEL); + mode = kzalloc_obj(*mode); if (!mode) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_display_device.c b/drivers/gpu/drm/i915/display/intel_display_device.c index 471f236c9ddf..01e0ae01fc50 100644 --- a/drivers/gpu/drm/i915/display/intel_display_device.c +++ b/drivers/gpu/drm/i915/display/intel_display_device.c @@ -1663,7 +1663,7 @@ struct intel_display *intel_display_device_probe(struct pci_dev *pdev, const struct subplatform_desc *subdesc; enum intel_step step; - display = kzalloc(sizeof(*display), GFP_KERNEL); + display = kzalloc_obj(*display); if (!display) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c index 9adeebb376b1..6e7e4654eb79 100644 --- a/drivers/gpu/drm/i915/display/intel_display_irq.c +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c @@ -2479,7 +2479,7 @@ intel_display_irq_snapshot_capture(struct intel_display *display) { struct intel_display_irq_snapshot *snapshot; - snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + snapshot = kzalloc_obj(*snapshot, GFP_ATOMIC); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_display_power_map.c b/drivers/gpu/drm/i915/display/intel_display_power_map.c index 9b49952994ce..c559ff000e67 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power_map.c +++ b/drivers/gpu/drm/i915/display/intel_display_power_map.c @@ -1823,9 +1823,8 @@ __set_power_wells(struct i915_power_domains *power_domains, power_domains->power_well_count = power_well_count; power_domains->power_wells = - kcalloc(power_well_count, - sizeof(*power_domains->power_wells), - GFP_KERNEL); + kzalloc_objs(*power_domains->power_wells, + power_well_count); if (!power_domains->power_wells) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_display_rps.c b/drivers/gpu/drm/i915/display/intel_display_rps.c index e77811396474..b58281edc563 100644 --- a/drivers/gpu/drm/i915/display/intel_display_rps.c +++ b/drivers/gpu/drm/i915/display/intel_display_rps.c @@ -59,7 +59,7 @@ void intel_display_rps_boost_after_vblank(struct drm_crtc *crtc, if (drm_crtc_vblank_get(crtc)) return; - wait = kmalloc(sizeof(*wait), GFP_KERNEL); + wait = kmalloc_obj(*wait); if (!wait) { drm_crtc_vblank_put(crtc); return; diff --git a/drivers/gpu/drm/i915/display/intel_display_snapshot.c b/drivers/gpu/drm/i915/display/intel_display_snapshot.c index 66087302fdbc..f650f15ad394 100644 --- a/drivers/gpu/drm/i915/display/intel_display_snapshot.c +++ b/drivers/gpu/drm/i915/display/intel_display_snapshot.c @@ -28,7 +28,7 @@ struct intel_display_snapshot *intel_display_snapshot_capture(struct intel_displ { struct intel_display_snapshot *snapshot; - snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + snapshot = kzalloc_obj(*snapshot, GFP_ATOMIC); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c index 1182bc9a2e6d..1006b060c3f3 100644 --- a/drivers/gpu/drm/i915/display/intel_dmc.c +++ b/drivers/gpu/drm/i915/display/intel_dmc.c @@ -1417,7 +1417,7 @@ void intel_dmc_init(struct intel_display *display) */ intel_dmc_runtime_pm_get(display); - dmc = kzalloc(sizeof(*dmc), GFP_KERNEL); + dmc = kzalloc_obj(*dmc); if (!dmc) return; @@ -1547,7 +1547,7 @@ struct intel_dmc_snapshot *intel_dmc_snapshot_capture(struct intel_display *disp if (!HAS_DMC(display)) return NULL; - snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + snapshot = kzalloc_obj(*snapshot, GFP_ATOMIC); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 7e022c47e8ac..696edf40b243 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -2557,6 +2557,9 @@ bool intel_dp_mode_valid_with_dsc(struct intel_connector *connector, if (min_bpp_x16 <= 0 || min_bpp_x16 > max_bpp_x16) return false; + if (dsc_slice_count == 0) + return false; + return is_bw_sufficient_for_dsc_config(intel_dp, link_clock, lane_count, mode_clock, mode_hdisplay, @@ -2665,6 +2668,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, bool dsc, struct link_config_limits *limits) { + struct intel_display *display = to_intel_display(intel_dp); bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST); struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -2677,8 +2681,7 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, limits->min_lane_count = intel_dp_min_lane_count(intel_dp); limits->max_lane_count = intel_dp_max_lane_count(intel_dp); - limits->pipe.min_bpp = intel_dp_in_hdr_mode(conn_state) ? 30 : - intel_dp_min_bpp(crtc_state->output_format); + limits->pipe.min_bpp = intel_dp_min_bpp(crtc_state->output_format); if (is_mst) { /* * FIXME: If all the streams can't fit into the link with their @@ -2694,6 +2697,19 @@ intel_dp_compute_config_limits(struct intel_dp *intel_dp, respect_downstream_limits); } + if (!dsc && intel_dp_in_hdr_mode(conn_state)) { + if (intel_dp_supports_dsc(intel_dp, connector, crtc_state) && + limits->pipe.max_bpp >= 30) + limits->pipe.min_bpp = max(limits->pipe.min_bpp, 30); + else + drm_dbg_kms(display->drm, + "[CONNECTOR:%d:%s] Can't force 30 bpp for HDR (pipe bpp: %d-%d DSC-support: %s)\n", + connector->base.base.id, connector->base.name, + limits->pipe.min_bpp, limits->pipe.max_bpp, + str_yes_no(intel_dp_supports_dsc(intel_dp, connector, + crtc_state))); + } + if (dsc && !intel_dp_dsc_compute_pipe_bpp_limits(connector, limits)) return false; @@ -2825,10 +2841,11 @@ intel_dp_compute_link_config(struct intel_encoder *encoder, } drm_dbg_kms(display->drm, - "DP lane count %d clock %d bpp input %d compressed " FXP_Q4_FMT " link rate required %d available %d\n", + "DP lane count %d clock %d bpp input %d compressed " FXP_Q4_FMT " HDR %s link rate required %d available %d\n", pipe_config->lane_count, pipe_config->port_clock, pipe_config->pipe_bpp, FXP_Q4_ARGS(pipe_config->dsc.compressed_bpp_x16), + str_yes_no(intel_dp_in_hdr_mode(conn_state)), intel_dp_config_required_rate(pipe_config), intel_dp_max_link_data_rate(intel_dp, pipe_config->port_clock, @@ -4560,6 +4577,7 @@ static bool intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector) { struct intel_display *display = to_intel_display(intel_dp); + int ret; /* this function is meant to be called only once */ drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0); @@ -4599,6 +4617,12 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector */ intel_dp_init_source_oui(intel_dp); + /* Read the ALPM DPCD caps */ + ret = drm_dp_dpcd_read_byte(&intel_dp->aux, DP_RECEIVER_ALPM_CAP, + &intel_dp->alpm_dpcd); + if (ret < 0) + return false; + /* * This has to be called after intel_dp->edp_dpcd is filled, PSR checks * for SET_POWER_CAPABLE bit in intel_dp->edp_dpcd[1] diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 24f8e60df9ac..70a21685a3e1 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1765,7 +1765,7 @@ mst_stream_encoder_create(struct intel_digital_port *dig_port, enum pipe pipe) struct intel_dp_mst_encoder *intel_mst; struct intel_encoder *encoder; - intel_mst = kzalloc(sizeof(*intel_mst), GFP_KERNEL); + intel_mst = kzalloc_obj(*intel_mst); if (!intel_mst) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c index faa2b7a46699..83865c02d477 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_tunnel.c +++ b/drivers/gpu/drm/i915/display/intel_dp_tunnel.c @@ -381,8 +381,7 @@ add_inherited_tunnel(struct intel_atomic_state *state, } if (!state->inherited_dp_tunnels) { - state->inherited_dp_tunnels = kzalloc(sizeof(*state->inherited_dp_tunnels), - GFP_KERNEL); + state->inherited_dp_tunnels = kzalloc_obj(*state->inherited_dp_tunnels); if (!state->inherited_dp_tunnels) return -ENOMEM; } diff --git a/drivers/gpu/drm/i915/display/intel_dpt.c b/drivers/gpu/drm/i915/display/intel_dpt.c index 58d953472218..da472371c7d7 100644 --- a/drivers/gpu/drm/i915/display/intel_dpt.c +++ b/drivers/gpu/drm/i915/display/intel_dpt.c @@ -280,7 +280,7 @@ intel_dpt_create(struct intel_framebuffer *fb) return ERR_PTR(ret); } - dpt = kzalloc(sizeof(*dpt), GFP_KERNEL); + dpt = kzalloc_obj(*dpt); if (!dpt) { i915_gem_object_put(dpt_obj); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c index 91060e2a5762..b5d774706fec 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb.c +++ b/drivers/gpu/drm/i915/display/intel_dsb.c @@ -974,7 +974,7 @@ struct intel_dsb *intel_dsb_prepare(struct intel_atomic_state *state, if (!display->params.enable_dsb) return NULL; - dsb = kzalloc(sizeof(*dsb), GFP_KERNEL); + dsb = kzalloc_obj(*dsb); if (!dsb) goto out; diff --git a/drivers/gpu/drm/i915/display/intel_dsb_buffer.c b/drivers/gpu/drm/i915/display/intel_dsb_buffer.c index 50faf3869b6c..9b6060af250d 100644 --- a/drivers/gpu/drm/i915/display/intel_dsb_buffer.c +++ b/drivers/gpu/drm/i915/display/intel_dsb_buffer.c @@ -46,7 +46,7 @@ struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t u32 *buf; int ret; - dsb_buf = kzalloc(sizeof(*dsb_buf), GFP_KERNEL); + dsb_buf = kzalloc_obj(*dsb_buf); if (!dsb_buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_dsi.c b/drivers/gpu/drm/i915/display/intel_dsi.c index a8f012119165..9005c1f5d857 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi.c +++ b/drivers/gpu/drm/i915/display/intel_dsi.c @@ -87,7 +87,7 @@ struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, struct intel_dsi_host *host; struct mipi_dsi_device *device; - host = kzalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc_obj(*host); if (!host) return NULL; @@ -102,7 +102,7 @@ struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, * devices by ourselves here too. Need to be careful though, because we * don't initialize any of the driver model devices here. */ - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) { kfree(host); return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c index 4b815ce6b1fe..18755a8e613d 100644 --- a/drivers/gpu/drm/i915/display/intel_dsi_vbt.c +++ b/drivers/gpu/drm/i915/display/intel_dsi_vbt.c @@ -231,7 +231,7 @@ static void soc_opaque_gpio_set_value(struct intel_connector *connector, { struct gpiod_lookup_table *lookup; - lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + lookup = kzalloc_flex(*lookup, table, 2); if (!lookup) return; diff --git a/drivers/gpu/drm/i915/display/intel_dvo.c b/drivers/gpu/drm/i915/display/intel_dvo.c index c2663d6e2c92..405b33aca9dd 100644 --- a/drivers/gpu/drm/i915/display/intel_dvo.c +++ b/drivers/gpu/drm/i915/display/intel_dvo.c @@ -494,7 +494,7 @@ void intel_dvo_init(struct intel_display *display) struct intel_encoder *encoder; struct intel_dvo *intel_dvo; - intel_dvo = kzalloc(sizeof(*intel_dvo), GFP_KERNEL); + intel_dvo = kzalloc_obj(*intel_dvo); if (!intel_dvo) return; diff --git a/drivers/gpu/drm/i915/display/intel_encoder.c b/drivers/gpu/drm/i915/display/intel_encoder.c index 2ffe1f251ef8..d01b081a6074 100644 --- a/drivers/gpu/drm/i915/display/intel_encoder.c +++ b/drivers/gpu/drm/i915/display/intel_encoder.c @@ -108,7 +108,7 @@ struct intel_digital_port *intel_dig_port_alloc(void) { struct intel_digital_port *dig_port; - dig_port = kzalloc(sizeof(*dig_port), GFP_KERNEL); + dig_port = kzalloc_obj(*dig_port); if (!dig_port) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_fb.c b/drivers/gpu/drm/i915/display/intel_fb.c index b9bd9b6dfe94..38c33f2ca05c 100644 --- a/drivers/gpu/drm/i915/display/intel_fb.c +++ b/drivers/gpu/drm/i915/display/intel_fb.c @@ -2173,7 +2173,7 @@ static int intel_user_framebuffer_dirty(struct drm_framebuffer *fb, if (ret || !fence) goto flush; - cb = kmalloc(sizeof(*cb), GFP_KERNEL); + cb = kmalloc_obj(*cb); if (!cb) { dma_fence_put(fence); ret = -ENOMEM; @@ -2361,7 +2361,7 @@ struct intel_framebuffer *intel_framebuffer_alloc(void) { struct intel_framebuffer *intel_fb; - intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); + intel_fb = kzalloc_obj(*intel_fb); if (!intel_fb) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c index 9f39b6990bbd..91de38379282 100644 --- a/drivers/gpu/drm/i915/display/intel_fbc.c +++ b/drivers/gpu/drm/i915/display/intel_fbc.c @@ -2294,7 +2294,7 @@ static struct intel_fbc *intel_fbc_create(struct intel_display *display, { struct intel_fbc *fbc; - fbc = kzalloc(sizeof(*fbc), GFP_KERNEL); + fbc = kzalloc_obj(*fbc); if (!fbc) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_global_state.c b/drivers/gpu/drm/i915/display/intel_global_state.c index 30eff6009e87..9e1369c834e4 100644 --- a/drivers/gpu/drm/i915/display/intel_global_state.c +++ b/drivers/gpu/drm/i915/display/intel_global_state.c @@ -52,7 +52,7 @@ static struct intel_global_commit *commit_new(void) { struct intel_global_commit *commit; - commit = kzalloc(sizeof(*commit), GFP_KERNEL); + commit = kzalloc_obj(*commit); if (!commit) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_gmbus.c b/drivers/gpu/drm/i915/display/intel_gmbus.c index 2caff677600c..a7bce0c6a17e 100644 --- a/drivers/gpu/drm/i915/display/intel_gmbus.c +++ b/drivers/gpu/drm/i915/display/intel_gmbus.c @@ -925,7 +925,7 @@ int intel_gmbus_setup(struct intel_display *display) if (!gmbus_pin) continue; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) { ret = -ENOMEM; goto err; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp.c b/drivers/gpu/drm/i915/display/intel_hdcp.c index 7114fc405c29..555d35bae887 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp.c @@ -2327,9 +2327,8 @@ static int initialize_hdcp_port_data(struct intel_connector *connector, data->protocol = (u8)shim->protocol; if (!data->streams) - data->streams = kcalloc(INTEL_NUM_PIPES(display), - sizeof(struct hdcp2_streamid_type), - GFP_KERNEL); + data->streams = kzalloc_objs(struct hdcp2_streamid_type, + INTEL_NUM_PIPES(display)); if (!data->streams) { drm_err(display->drm, "Out of Memory\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c index 781667b710b4..c2de48f57f30 100644 --- a/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c +++ b/drivers/gpu/drm/i915/display/intel_hdcp_gsc_message.c @@ -633,7 +633,7 @@ int intel_hdcp_gsc_init(struct intel_display *display) struct i915_hdcp_arbiter *arbiter; int ret = 0; - arbiter = kzalloc(sizeof(*arbiter), GFP_KERNEL); + arbiter = kzalloc_obj(*arbiter); if (!arbiter) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_lpe_audio.c b/drivers/gpu/drm/i915/display/intel_lpe_audio.c index 5b41abe1c64d..117b60656ca1 100644 --- a/drivers/gpu/drm/i915/display/intel_lpe_audio.c +++ b/drivers/gpu/drm/i915/display/intel_lpe_audio.c @@ -87,11 +87,11 @@ lpe_audio_platdev_create(struct intel_display *display) struct platform_device *platdev; struct intel_hdmi_lpe_audio_pdata *pdata; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return ERR_PTR(-ENOMEM); - rsc = kcalloc(2, sizeof(*rsc), GFP_KERNEL); + rsc = kzalloc_objs(*rsc, 2); if (!rsc) { kfree(pdata); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_lvds.c b/drivers/gpu/drm/i915/display/intel_lvds.c index 457d60863536..cc6d4bfcff10 100644 --- a/drivers/gpu/drm/i915/display/intel_lvds.c +++ b/drivers/gpu/drm/i915/display/intel_lvds.c @@ -886,7 +886,7 @@ void intel_lvds_init(struct intel_display *display) "LVDS is not present in VBT, but enabled anyway\n"); } - lvds_encoder = kzalloc(sizeof(*lvds_encoder), GFP_KERNEL); + lvds_encoder = kzalloc_obj(*lvds_encoder); if (!lvds_encoder) return; diff --git a/drivers/gpu/drm/i915/display/intel_opregion.c b/drivers/gpu/drm/i915/display/intel_opregion.c index cbc220310813..e25be56e678b 100644 --- a/drivers/gpu/drm/i915/display/intel_opregion.c +++ b/drivers/gpu/drm/i915/display/intel_opregion.c @@ -898,7 +898,7 @@ int intel_opregion_setup(struct intel_display *display) return -ENOTSUPP; } - opregion = kzalloc(sizeof(*opregion), GFP_KERNEL); + opregion = kzalloc_obj(*opregion); if (!opregion) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_overlay.c b/drivers/gpu/drm/i915/display/intel_overlay.c index 88eb7ae5765c..05c7545c49e5 100644 --- a/drivers/gpu/drm/i915/display/intel_overlay.c +++ b/drivers/gpu/drm/i915/display/intel_overlay.c @@ -1409,7 +1409,7 @@ void intel_overlay_setup(struct intel_display *display) if (!engine || !engine->kernel_context) return; - overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kzalloc_obj(*overlay); if (!overlay) return; @@ -1484,7 +1484,7 @@ intel_overlay_snapshot_capture(struct intel_display *display) if (!overlay || !overlay->active) return NULL; - error = kmalloc(sizeof(*error), GFP_ATOMIC); + error = kmalloc_obj(*error, GFP_ATOMIC); if (error == NULL) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_plane.c b/drivers/gpu/drm/i915/display/intel_plane.c index 3dc2ed52147f..e06a0618b4c6 100644 --- a/drivers/gpu/drm/i915/display/intel_plane.c +++ b/drivers/gpu/drm/i915/display/intel_plane.c @@ -77,11 +77,11 @@ struct intel_plane *intel_plane_alloc(void) struct intel_plane_state *plane_state; struct intel_plane *plane; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); - plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL); + plane_state = kzalloc_obj(*plane_state); if (!plane_state) { kfree(plane); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/display/intel_pmdemand.c b/drivers/gpu/drm/i915/display/intel_pmdemand.c index dc44a7a169c1..f3db55710010 100644 --- a/drivers/gpu/drm/i915/display/intel_pmdemand.c +++ b/drivers/gpu/drm/i915/display/intel_pmdemand.c @@ -121,7 +121,7 @@ int intel_pmdemand_init(struct intel_display *display) { struct intel_pmdemand_state *pmdemand_state; - pmdemand_state = kzalloc(sizeof(*pmdemand_state), GFP_KERNEL); + pmdemand_state = kzalloc_obj(*pmdemand_state); if (!pmdemand_state) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 62208ffc5101..b7302a32ded4 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1307,9 +1307,14 @@ static bool psr2_granularity_check(struct intel_crtc_state *crtc_state, u16 sink_y_granularity = crtc_state->has_panel_replay ? connector->dp.panel_replay_caps.su_y_granularity : connector->dp.psr_caps.su_y_granularity; - u16 sink_w_granularity = crtc_state->has_panel_replay ? - connector->dp.panel_replay_caps.su_w_granularity : - connector->dp.psr_caps.su_w_granularity; + u16 sink_w_granularity; + + if (crtc_state->has_panel_replay) + sink_w_granularity = connector->dp.panel_replay_caps.su_w_granularity == + DP_PANEL_REPLAY_FULL_LINE_GRANULARITY ? + crtc_hdisplay : connector->dp.panel_replay_caps.su_w_granularity; + else + sink_w_granularity = connector->dp.psr_caps.su_w_granularity; /* PSR2 HW only send full lines so we only need to validate the width */ if (crtc_hdisplay % sink_w_granularity) @@ -2614,6 +2619,12 @@ void intel_psr2_program_trans_man_trk_ctl(struct intel_dsb *dsb, intel_de_write_dsb(display, dsb, PIPE_SRCSZ_ERLY_TPT(crtc->pipe), crtc_state->pipe_srcsz_early_tpt); + + if (!crtc_state->dsc.compression_enable) + return; + + intel_dsc_su_et_parameters_configure(dsb, encoder, crtc_state, + drm_rect_height(&crtc_state->psr2_su_area)); } static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state, @@ -2684,11 +2695,12 @@ static void clip_area_update(struct drm_rect *overlap_damage_area, overlap_damage_area->y2 = damage_area->y2; } -static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_state) +static bool intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; u16 y_alignment; + bool su_area_changed = false; /* ADLP aligns the SU region to vdsc slice height in case dsc is enabled */ if (crtc_state->dsc.compression_enable && @@ -2697,10 +2709,18 @@ static void intel_psr2_sel_fetch_pipe_alignment(struct intel_crtc_state *crtc_st else y_alignment = crtc_state->su_y_granularity; - crtc_state->psr2_su_area.y1 -= crtc_state->psr2_su_area.y1 % y_alignment; - if (crtc_state->psr2_su_area.y2 % y_alignment) + if (crtc_state->psr2_su_area.y1 % y_alignment) { + crtc_state->psr2_su_area.y1 -= crtc_state->psr2_su_area.y1 % y_alignment; + su_area_changed = true; + } + + if (crtc_state->psr2_su_area.y2 % y_alignment) { crtc_state->psr2_su_area.y2 = ((crtc_state->psr2_su_area.y2 / y_alignment) + 1) * y_alignment; + su_area_changed = true; + } + + return su_area_changed; } /* @@ -2834,7 +2854,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, struct intel_crtc_state *crtc_state = intel_atomic_get_new_crtc_state(state, crtc); struct intel_plane_state *new_plane_state, *old_plane_state; struct intel_plane *plane; - bool full_update = false, cursor_in_su_area = false; + bool full_update = false, su_area_changed; int i, ret; if (!crtc_state->enable_psr2_sel_fetch) @@ -2941,15 +2961,32 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, if (ret) return ret; - /* - * Adjust su area to cover cursor fully as necessary (early - * transport). This needs to be done after - * drm_atomic_add_affected_planes to ensure visible cursor is added into - * affected planes even when cursor is not updated by itself. - */ - intel_psr2_sel_fetch_et_alignment(state, crtc, &cursor_in_su_area); + do { + bool cursor_in_su_area; - intel_psr2_sel_fetch_pipe_alignment(crtc_state); + /* + * Adjust su area to cover cursor fully as necessary + * (early transport). This needs to be done after + * drm_atomic_add_affected_planes to ensure visible + * cursor is added into affected planes even when + * cursor is not updated by itself. + */ + intel_psr2_sel_fetch_et_alignment(state, crtc, &cursor_in_su_area); + + su_area_changed = intel_psr2_sel_fetch_pipe_alignment(crtc_state); + + /* + * If the cursor was outside the SU area before + * alignment, the alignment step (which only expands + * SU) may pull the cursor partially inside, so we + * must run ET alignment again to fully cover it. But + * if the cursor was already fully inside before + * alignment, expanding the SU area won't change that, + * so no further work is needed. + */ + if (cursor_in_su_area) + break; + } while (su_area_changed); /* * Now that we have the pipe damaged area check if it intersect with @@ -3009,6 +3046,10 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state, } skip_sel_fetch_set_loop: + if (full_update) + clip_area_update(&crtc_state->psr2_su_area, &crtc_state->pipe_src, + &crtc_state->pipe_src); + psr2_man_trk_ctl_calc(crtc_state, full_update); crtc_state->pipe_srcsz_early_tpt = psr2_pipe_srcsz_early_tpt_calc(crtc_state, full_update); diff --git a/drivers/gpu/drm/i915/display/intel_quirks.c b/drivers/gpu/drm/i915/display/intel_quirks.c index d2e16b79d6be..1abbdd426e58 100644 --- a/drivers/gpu/drm/i915/display/intel_quirks.c +++ b/drivers/gpu/drm/i915/display/intel_quirks.c @@ -239,7 +239,7 @@ static struct intel_quirk intel_quirks[] = { { 0x0f31, 0x103c, 0x220f, quirk_invert_brightness }, /* Dell XPS 13 7390 2-in-1 */ - { 0x8a12, 0x1028, 0x08b0, quirk_edp_limit_rate_hbr2 }, + { 0x8a52, 0x1028, 0x08b0, quirk_edp_limit_rate_hbr2 }, }; static const struct intel_dpcd_quirk intel_dpcd_quirks[] = { diff --git a/drivers/gpu/drm/i915/display/intel_rom.c b/drivers/gpu/drm/i915/display/intel_rom.c index c8f615315310..05b6ea764ebb 100644 --- a/drivers/gpu/drm/i915/display/intel_rom.c +++ b/drivers/gpu/drm/i915/display/intel_rom.c @@ -47,7 +47,7 @@ struct intel_rom *intel_rom_spi(struct drm_device *drm) struct intel_rom *rom; u32 static_region; - rom = kzalloc(sizeof(*rom), GFP_KERNEL); + rom = kzalloc_obj(*rom); if (!rom) return NULL; @@ -92,7 +92,7 @@ struct intel_rom *intel_rom_pci(struct drm_device *drm) { struct intel_rom *rom; - rom = kzalloc(sizeof(*rom), GFP_KERNEL); + rom = kzalloc_obj(*rom); if (!rom) return NULL; diff --git a/drivers/gpu/drm/i915/display/intel_sdvo.c b/drivers/gpu/drm/i915/display/intel_sdvo.c index 6c032d81e7ee..2e1af9e869de 100644 --- a/drivers/gpu/drm/i915/display/intel_sdvo.c +++ b/drivers/gpu/drm/i915/display/intel_sdvo.c @@ -474,7 +474,7 @@ static bool __intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, if (!buf) return false; - msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); + msgs = kzalloc_objs(*msgs, args_len + 3); if (!msgs) { kfree(buf); return false; @@ -2774,11 +2774,11 @@ static struct intel_sdvo_connector *intel_sdvo_connector_alloc(void) struct intel_sdvo_connector *sdvo_connector; struct intel_sdvo_connector_state *conn_state; - sdvo_connector = kzalloc(sizeof(*sdvo_connector), GFP_KERNEL); + sdvo_connector = kzalloc_obj(*sdvo_connector); if (!sdvo_connector) return NULL; - conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL); + conn_state = kzalloc_obj(*conn_state); if (!conn_state) { kfree(sdvo_connector); return NULL; @@ -3389,7 +3389,7 @@ bool intel_sdvo_init(struct intel_display *display, if (!assert_sdvo_port_valid(display, port)) return false; - intel_sdvo = kzalloc(sizeof(*intel_sdvo), GFP_KERNEL); + intel_sdvo = kzalloc_obj(*intel_sdvo); if (!intel_sdvo) return false; diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c index 064f572bbc85..bd12148e42f7 100644 --- a/drivers/gpu/drm/i915/display/intel_tc.c +++ b/drivers/gpu/drm/i915/display/intel_tc.c @@ -1977,7 +1977,7 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy) if (drm_WARN_ON(display->drm, tc_port == TC_PORT_NONE)) return -EINVAL; - tc = kzalloc(sizeof(*tc), GFP_KERNEL); + tc = kzalloc_obj(*tc); if (!tc) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/display/intel_tv.c b/drivers/gpu/drm/i915/display/intel_tv.c index e3ab49815a3c..8fbf0adb5699 100644 --- a/drivers/gpu/drm/i915/display/intel_tv.c +++ b/drivers/gpu/drm/i915/display/intel_tv.c @@ -1966,7 +1966,7 @@ intel_tv_init(struct intel_display *display) (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) return; - intel_tv = kzalloc(sizeof(*intel_tv), GFP_KERNEL); + intel_tv = kzalloc_obj(*intel_tv); if (!intel_tv) { return; } diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.c b/drivers/gpu/drm/i915/display/intel_vdsc.c index 5493082f30a7..2065dac1e3fd 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.c +++ b/drivers/gpu/drm/i915/display/intel_vdsc.c @@ -767,6 +767,29 @@ void intel_dsc_dp_pps_write(struct intel_encoder *encoder, sizeof(dp_dsc_pps_sdp)); } +void intel_dsc_su_et_parameters_configure(struct intel_dsb *dsb, struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int su_lines) +{ + struct intel_display *display = to_intel_display(crtc_state); + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); + const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config; + enum pipe pipe = crtc->pipe; + int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state); + int slice_row_per_frame = su_lines / vdsc_cfg->slice_height; + u32 val; + + drm_WARN_ON_ONCE(display->drm, su_lines % vdsc_cfg->slice_height); + drm_WARN_ON_ONCE(display->drm, vdsc_instances_per_pipe > 2); + + val = DSC_SUPS0_SU_SLICE_ROW_PER_FRAME(slice_row_per_frame); + val |= DSC_SUPS0_SU_PIC_HEIGHT(su_lines); + + intel_de_write_dsb(display, dsb, LNL_DSC0_SU_PARAMETER_SET_0(pipe), val); + + if (vdsc_instances_per_pipe == 2) + intel_de_write_dsb(display, dsb, LNL_DSC1_SU_PARAMETER_SET_0(pipe), val); +} + static i915_reg_t dss_ctl1_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder) { return is_pipe_dsc(crtc, cpu_transcoder) ? diff --git a/drivers/gpu/drm/i915/display/intel_vdsc.h b/drivers/gpu/drm/i915/display/intel_vdsc.h index 99f64ac54b27..99bb9042592a 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc.h @@ -13,6 +13,7 @@ struct drm_printer; enum transcoder; struct intel_crtc; struct intel_crtc_state; +struct intel_dsb; struct intel_encoder; bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state); @@ -31,6 +32,8 @@ void intel_dsc_dsi_pps_write(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); void intel_dsc_dp_pps_write(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); +void intel_dsc_su_et_parameters_configure(struct intel_dsb *dsb, struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state, int su_lines); void intel_vdsc_state_dump(struct drm_printer *p, int indent, const struct intel_crtc_state *crtc_state); int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h index 2d478a84b07c..2b2e3c1b8138 100644 --- a/drivers/gpu/drm/i915/display/intel_vdsc_regs.h +++ b/drivers/gpu/drm/i915/display/intel_vdsc_regs.h @@ -196,6 +196,18 @@ #define DSC_PPS18_NSL_BPG_OFFSET(offset) REG_FIELD_PREP(DSC_PPS18_NSL_BPG_OFFSET_MASK, offset) #define DSC_PPS18_SL_OFFSET_ADJ(offset) REG_FIELD_PREP(DSC_PPS18_SL_OFFSET_ADJ_MASK, offset) +#define _LNL_DSC0_SU_PARAMETER_SET_0_PA 0x78064 +#define _LNL_DSC1_SU_PARAMETER_SET_0_PA 0x78164 +#define _LNL_DSC0_SU_PARAMETER_SET_0_PB 0x78264 +#define _LNL_DSC1_SU_PARAMETER_SET_0_PB 0x78364 +#define LNL_DSC0_SU_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe), _LNL_DSC0_SU_PARAMETER_SET_0_PA, _LNL_DSC0_SU_PARAMETER_SET_0_PB) +#define LNL_DSC1_SU_PARAMETER_SET_0(pipe) _MMIO_PIPE((pipe), _LNL_DSC1_SU_PARAMETER_SET_0_PA, _LNL_DSC1_SU_PARAMETER_SET_0_PB) + +#define DSC_SUPS0_SU_SLICE_ROW_PER_FRAME_MASK REG_GENMASK(31, 20) +#define DSC_SUPS0_SU_SLICE_ROW_PER_FRAME(rows) REG_FIELD_PREP(DSC_SUPS0_SU_SLICE_ROW_PER_FRAME_MASK, (rows)) +#define DSC_SUPS0_SU_PIC_HEIGHT_MASK REG_GENMASK(15, 0) +#define DSC_SUPS0_SU_PIC_HEIGHT(h) REG_FIELD_PREP(DSC_SUPS0_SU_PIC_HEIGHT_MASK, (h)) + /* Icelake Rate Control Buffer Threshold Registers */ #define DSCA_RC_BUF_THRESH_0 _MMIO(0x6B230) #define DSCA_RC_BUF_THRESH_0_UDW _MMIO(0x6B230 + 4) diff --git a/drivers/gpu/drm/i915/display/intel_vrr.c b/drivers/gpu/drm/i915/display/intel_vrr.c index db74744ddb31..bea005752327 100644 --- a/drivers/gpu/drm/i915/display/intel_vrr.c +++ b/drivers/gpu/drm/i915/display/intel_vrr.c @@ -597,6 +597,18 @@ void intel_vrr_set_transcoder_timings(const struct intel_crtc_state *crtc_state) if (!HAS_VRR(display)) return; + /* + * Bspec says: + * "(note: VRR needs to be programmed after + * TRANS_DDI_FUNC_CTL and before TRANS_CONF)." + * + * In practice it turns out that ICL can hang if + * TRANS_VRR_VMAX/FLIPLINE are written before + * enabling TRANS_DDI_FUNC_CTL. + */ + drm_WARN_ON(display->drm, + !(intel_de_read(display, TRANS_DDI_FUNC_CTL(display, cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE)); + /* * This bit seems to have two meanings depending on the platform: * TGL: generate VRR "safe window" for DSB vblank waits @@ -939,6 +951,8 @@ void intel_vrr_transcoder_enable(const struct intel_crtc_state *crtc_state) { struct intel_display *display = to_intel_display(crtc_state); + intel_vrr_set_transcoder_timings(crtc_state); + if (!intel_vrr_possible(crtc_state)) return; diff --git a/drivers/gpu/drm/i915/display/skl_watermark.c b/drivers/gpu/drm/i915/display/skl_watermark.c index a6aab79812e5..f5a6fae815d1 100644 --- a/drivers/gpu/drm/i915/display/skl_watermark.c +++ b/drivers/gpu/drm/i915/display/skl_watermark.c @@ -3366,7 +3366,7 @@ int intel_dbuf_init(struct intel_display *display) { struct intel_dbuf_state *dbuf_state; - dbuf_state = kzalloc(sizeof(*dbuf_state), GFP_KERNEL); + dbuf_state = kzalloc_obj(*dbuf_state); if (!dbuf_state) return -ENOMEM; @@ -3892,7 +3892,7 @@ void intel_wm_state_verify(struct intel_atomic_state *state, if (DISPLAY_VER(display) < 9 || !new_crtc_state->hw.active) return; - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) return; diff --git a/drivers/gpu/drm/i915/display/vlv_dsi.c b/drivers/gpu/drm/i915/display/vlv_dsi.c index d705af3bf8ba..60857d2afdb1 100644 --- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1919,7 +1919,7 @@ void vlv_dsi_init(struct intel_display *display) else display->dsi.mmio_base = VLV_MIPI_BASE; - intel_dsi = kzalloc(sizeof(*intel_dsi), GFP_KERNEL); + intel_dsi = kzalloc_obj(*intel_dsi); if (!intel_dsi) return; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c index c1deea20c28a..30cc08583cbd 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_clflush.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_clflush.c @@ -52,7 +52,7 @@ static struct clflush *clflush_work_create(struct drm_i915_gem_object *obj) GEM_BUG_ON(!obj->cache_dirty); - clflush = kmalloc(sizeof(*clflush), GFP_KERNEL); + clflush = kmalloc_obj(*clflush); if (!clflush) return NULL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_context.c b/drivers/gpu/drm/i915/gem/i915_gem_context.c index 3215ef49c975..6ac0f23570f3 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_context.c @@ -285,7 +285,7 @@ proto_context_create(struct drm_i915_file_private *fpriv, { struct i915_gem_proto_context *pc, *err; - pc = kzalloc(sizeof(*pc), GFP_KERNEL); + pc = kzalloc_obj(*pc); if (!pc) return ERR_PTR(-ENOMEM); @@ -442,7 +442,7 @@ set_proto_ctx_engines_balance(struct i915_user_extension __user *base, if (num_siblings == 0) return 0; - siblings = kmalloc_array(num_siblings, sizeof(*siblings), GFP_KERNEL); + siblings = kmalloc_objs(*siblings, num_siblings); if (!siblings) return -ENOMEM; @@ -644,9 +644,7 @@ set_proto_ctx_engines_parallel_submit(struct i915_user_extension __user *base, return -EINVAL; } - siblings = kmalloc_array(num_siblings * width, - sizeof(*siblings), - GFP_KERNEL); + siblings = kmalloc_objs(*siblings, num_siblings * width); if (!siblings) return -ENOMEM; @@ -761,7 +759,7 @@ static int set_proto_ctx_engines(struct drm_i915_file_private *fpriv, if (set.num_engines > I915_EXEC_RING_MASK + 1) return -EINVAL; - set.engines = kmalloc_array(set.num_engines, sizeof(*set.engines), GFP_KERNEL); + set.engines = kmalloc_objs(*set.engines, set.num_engines); if (!set.engines) return -ENOMEM; @@ -1105,7 +1103,7 @@ static struct i915_gem_engines *alloc_engines(unsigned int count) { struct i915_gem_engines *e; - e = kzalloc(struct_size(e, engines, count), GFP_KERNEL); + e = kzalloc_flex(*e, engines, count); if (!e) return NULL; @@ -1611,7 +1609,7 @@ i915_gem_create_context(struct drm_i915_private *i915, int err; int i; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_create.c b/drivers/gpu/drm/i915/gem/i915_gem_create.c index 189ecdd0a9c1..e12ec59afb8d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_create.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_create.c @@ -54,9 +54,7 @@ static int object_set_placements(struct drm_i915_gem_object *obj, obj->mm.placements = &i915->mm.regions[mr->id]; obj->mm.n_placements = 1; } else { - arr = kmalloc_array(n_placements, - sizeof(struct intel_memory_region *), - GFP_KERNEL); + arr = kmalloc_objs(struct intel_memory_region *, n_placements); if (!arr) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c index f4f1c979d1b9..b43d34c7d641 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_dmabuf.c @@ -36,7 +36,7 @@ static struct sg_table *i915_gem_map_dma_buf(struct dma_buf_attachment *attach, * Make a copy of the object's sgt, so that we can make an independent * mapping */ - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto err; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index d49e96f9be51..e7918f896a26 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2006,7 +2006,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb) for_each_batch_create_order(eb, j) { struct i915_capture_list *capture; - capture = kmalloc(sizeof(*capture), GFP_KERNEL); + capture = kmalloc_obj(*capture); if (!capture) continue; @@ -3190,7 +3190,7 @@ eb_composite_fence_create(struct i915_execbuffer *eb, int out_fence_fd) GEM_BUG_ON(!intel_context_is_parent(eb->context)); - fences = kmalloc_array(eb->num_batches, sizeof(*fences), GFP_KERNEL); + fences = kmalloc_objs(*fences, eb->num_batches); if (!fences) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_internal.c b/drivers/gpu/drm/i915/gem/i915_gem_internal.c index 232b984f60b6..37d286ecb99b 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_internal.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_internal.c @@ -54,7 +54,7 @@ static int i915_gem_object_get_pages_internal(struct drm_i915_gem_object *obj) } create_st: - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/i915_gem_mman.c index 4542135b20d5..0644f85c6c8e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_mman.c @@ -730,7 +730,7 @@ mmap_offset_attach(struct drm_i915_gem_object *obj, if (mmo) goto out; - mmo = kmalloc(sizeof(*mmo), GFP_KERNEL); + mmo = kmalloc_obj(*mmo); if (!mmo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c index aaa15e7b3f17..adba3fa96c05 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_object_frontbuffer.c @@ -32,7 +32,7 @@ i915_gem_object_frontbuffer_get(struct drm_i915_gem_object *obj) if (front) return front; - front = kmalloc(sizeof(*front), GFP_KERNEL); + front = kmalloc_obj(*front); if (!front) return NULL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c index c2f8e5f95696..df35bdb755e4 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c @@ -314,7 +314,7 @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, if (n_pages > ARRAY_SIZE(stack)) { /* Too big for stack -- allocate temporary array instead */ - pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, n_pages); if (!pages) return ERR_PTR(-ENOMEM); } @@ -382,7 +382,7 @@ static struct page **i915_gem_object_panic_pages(struct drm_i915_gem_object *obj struct sgt_iter iter; /* For a 3840x2160 32 bits Framebuffer, this should require ~64K */ - pages = kmalloc_array(n_pages, sizeof(*pages), GFP_ATOMIC); + pages = kmalloc_objs(*pages, n_pages, GFP_ATOMIC); if (!pages) return NULL; @@ -437,7 +437,7 @@ struct intel_panic *i915_gem_object_alloc_panic(void) { struct intel_panic *panic; - panic = kzalloc(sizeof(*panic), GFP_KERNEL); + panic = kzalloc_obj(*panic); return panic; } diff --git a/drivers/gpu/drm/i915/gem/i915_gem_phys.c b/drivers/gpu/drm/i915/gem/i915_gem_phys.c index bc799f182850..ce2780ef97ef 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_phys.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_phys.c @@ -47,7 +47,7 @@ static int i915_gem_object_get_pages_phys(struct drm_i915_gem_object *obj) if (!vaddr) return -ENOMEM; - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) goto err_pci; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c index 6ad1d6f99363..720a9ad39aa2 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_shmem.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_shmem.c @@ -153,8 +153,12 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, } } while (1); - nr_pages = min_t(unsigned long, - folio_nr_pages(folio), page_count - i); + nr_pages = min_array(((unsigned long[]) { + folio_nr_pages(folio), + page_count - i, + max_segment / PAGE_SIZE, + }), 3); + if (!i || sg->length >= max_segment || folio_pfn(folio) != next_pfn) { @@ -164,7 +168,9 @@ int shmem_sg_alloc_table(struct drm_i915_private *i915, struct sg_table *st, st->nents++; sg_set_folio(sg, folio, nr_pages * PAGE_SIZE, 0); } else { - /* XXX: could overflow? */ + nr_pages = min_t(unsigned long, nr_pages, + (max_segment - sg->length) / PAGE_SIZE); + sg->length += nr_pages * PAGE_SIZE; } next_pfn = folio_pfn(folio) + nr_pages; @@ -222,7 +228,7 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj) GEM_BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); rebuild_st: - st = kmalloc(sizeof(*st), GFP_KERNEL | __GFP_NOWARN); + st = kmalloc_obj(*st, GFP_KERNEL | __GFP_NOWARN); if (!st) return -ENOMEM; @@ -499,7 +505,7 @@ static int __create_shmem(struct drm_i915_private *i915, resource_size_t size, unsigned int flags) { - unsigned long shmem_flags = VM_NORESERVE; + const vma_flags_t shmem_flags = mk_vma_flags(VMA_NORESERVE_BIT); struct vfsmount *huge_mnt; struct file *filp; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c index c3e0b8da485c..77f85359f279 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_stolen.c @@ -648,7 +648,7 @@ i915_pages_create_for_stolen(struct drm_device *dev, * dma mapping in a single scatterlist. */ - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (st == NULL) return ERR_PTR(-ENOMEM); @@ -783,7 +783,7 @@ static int _i915_gem_object_stolen_init(struct intel_memory_region *mem, !(flags & I915_BO_ALLOC_GPU_ONLY)) return -ENOSPC; - stolen = kzalloc(sizeof(*stolen), GFP_KERNEL); + stolen = kzalloc_obj(*stolen); if (!stolen) return -ENOMEM; @@ -1074,7 +1074,7 @@ static struct intel_stolen_node *i915_gem_stolen_node_alloc(struct drm_device *d struct drm_i915_private *i915 = to_i915(drm); struct intel_stolen_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return NULL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c index f65fe86c02b5..033eda38e4b5 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm.c @@ -200,7 +200,8 @@ static int i915_ttm_tt_shmem_populate(struct ttm_device *bdev, struct address_space *mapping; gfp_t mask; - filp = shmem_file_setup("i915-shmem-tt", size, VM_NORESERVE); + filp = shmem_file_setup("i915-shmem-tt", size, + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(filp)) return PTR_ERR(filp); @@ -278,7 +279,7 @@ static struct ttm_tt *i915_ttm_tt_create(struct ttm_buffer_object *bo, if (i915_ttm_is_ghost_object(bo)) return NULL; - i915_tt = kzalloc(sizeof(*i915_tt), GFP_KERNEL); + i915_tt = kzalloc_obj(*i915_tt); if (!i915_tt) return NULL; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c index 2f6b33edb9c9..3a7e202ae87d 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_ttm_move.c @@ -498,7 +498,7 @@ __i915_ttm_move(struct ttm_buffer_object *bo, struct dma_fence *dep = fence; if (!I915_SELFTEST_ONLY(fail_work_allocation)) - copy_work = kzalloc(sizeof(*copy_work), GFP_KERNEL); + copy_work = kzalloc_obj(*copy_work); if (copy_work) { copy_work->i915 = i915; diff --git a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c index 77cc3af3d518..043095f93ac6 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_userptr.c @@ -109,7 +109,7 @@ static int i915_gem_userptr_get_pages(struct drm_i915_gem_object *obj) return -E2BIG; num_pages = obj->base.size >> PAGE_SHIFT; - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) return -ENOMEM; @@ -258,7 +258,7 @@ int i915_gem_object_userptr_submit_init(struct drm_i915_gem_object *obj) if (ret) return ret; - pvec = kvmalloc_array(num_pages, sizeof(struct page *), GFP_KERNEL); + pvec = kvmalloc_objs(struct page *, num_pages); if (!pvec) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c index bac957755068..8caaf325e56a 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_gem_object.c @@ -38,7 +38,7 @@ static int huge_get_pages(struct drm_i915_gem_object *obj) return -E2BIG; npages = obj->base.size / PAGE_SIZE; - pages = kmalloc(sizeof(*pages), GFP); + pages = kmalloc_obj(*pages, GFP); if (!pages) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c index 02e9bf87f654..44718e728291 100644 --- a/drivers/gpu/drm/i915/gem/selftests/huge_pages.c +++ b/drivers/gpu/drm/i915/gem/selftests/huge_pages.c @@ -88,7 +88,7 @@ static int get_huge_pages(struct drm_i915_gem_object *obj) if (overflows_type(obj->base.size >> PAGE_SHIFT, unsigned int)) return -E2BIG; - st = kmalloc(sizeof(*st), GFP); + st = kmalloc_obj(*st, GFP); if (!st) return -ENOMEM; @@ -220,7 +220,7 @@ static int fake_get_huge_pages(struct drm_i915_gem_object *obj) if (overflows_type(obj->base.size >> PAGE_SHIFT, unsigned int)) return -E2BIG; - st = kmalloc(sizeof(*st), GFP); + st = kmalloc_obj(*st, GFP); if (!st) return -ENOMEM; @@ -270,7 +270,7 @@ static int fake_get_huge_pages_single(struct drm_i915_gem_object *obj) struct scatterlist *sg; unsigned int page_size; - st = kmalloc(sizeof(*st), GFP); + st = kmalloc_obj(*st, GFP); if (!st) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c index 3557e9e6f422..1d4d7cfb3f9c 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_client_blt.c @@ -540,7 +540,7 @@ tiled_blits_create(struct intel_engine_cs *engine, struct rnd_state *prng) u64 hole_size; int err; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c index 1330c0b431a7..9d405098f9e7 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c @@ -56,7 +56,7 @@ static int live_nop_switch(void *arg) if (IS_ERR(file)) return PTR_ERR(file); - ctx = kcalloc(nctx, sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_objs(*ctx, nctx); if (!ctx) { err = -ENOMEM; goto out_file; @@ -317,7 +317,7 @@ static int live_parallel_switch(void *arg) engines = i915_gem_context_lock_engines(ctx); count = engines->num_engines; - data = kcalloc(count, sizeof(*data), GFP_KERNEL); + data = kzalloc_objs(*data, count); if (!data) { i915_gem_context_unlock_engines(ctx); err = -ENOMEM; @@ -1054,7 +1054,7 @@ __sseu_prepare(const char *name, if (!(flags & (TEST_BUSY | TEST_RESET))) return 0; - *spin = kzalloc(sizeof(**spin), GFP_KERNEL); + *spin = kzalloc_obj(**spin); if (!*spin) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c index 0d250d57496a..17829ad57099 100644 --- a/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c +++ b/drivers/gpu/drm/i915/gem/selftests/i915_gem_mman.c @@ -677,7 +677,7 @@ static int igt_mmap_offset_exhaustion(void *arg) list_for_each_entry_safe(hole, next, &mm->hole_stack, hole_stack) { struct drm_mm_node *resv; - resv = kzalloc(sizeof(*resv), GFP_NOWAIT); + resv = kzalloc_obj(*resv, GFP_NOWAIT); if (!resv) { err = -ENOMEM; goto out_park; diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_context.c b/drivers/gpu/drm/i915/gem/selftests/mock_context.c index fd8babb513e5..24f1437262ec 100644 --- a/drivers/gpu/drm/i915/gem/selftests/mock_context.c +++ b/drivers/gpu/drm/i915/gem/selftests/mock_context.c @@ -17,7 +17,7 @@ mock_context(struct drm_i915_private *i915, struct i915_gem_engines *e; struct intel_sseu null_sseu = {}; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; diff --git a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c index 5cd58e0f0dcf..f2863da7f5c1 100644 --- a/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c +++ b/drivers/gpu/drm/i915/gem/selftests/mock_dmabuf.c @@ -15,7 +15,7 @@ static struct sg_table *mock_map_dma_buf(struct dma_buf_attachment *attachment, struct scatterlist *sg; int i, err; - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) return ERR_PTR(-ENOMEM); @@ -103,7 +103,7 @@ static struct dma_buf *mock_dmabuf(int npages) struct dma_buf *dmabuf; int i; - mock = kmalloc(struct_size(mock, pages, npages), GFP_KERNEL); + mock = kmalloc_flex(*mock, pages, npages); if (!mock) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c index c2bdc133c89a..e8fab45759c3 100644 --- a/drivers/gpu/drm/i915/gt/gen6_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen6_ppgtt.c @@ -431,7 +431,7 @@ struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt) struct gen6_ppgtt *ppgtt; int err; - ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + ppgtt = kzalloc_obj(*ppgtt); if (!ppgtt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c index 398d60a66410..cfa09b250a1b 100644 --- a/drivers/gpu/drm/i915/gt/gen8_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/gen8_ppgtt.c @@ -1006,7 +1006,7 @@ struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt, struct i915_ppgtt *ppgtt; int err; - ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + ppgtt = kzalloc_obj(*ppgtt); if (!ppgtt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c index bf6117d5fc57..a2b413982ce6 100644 --- a/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c +++ b/drivers/gpu/drm/i915/gt/intel_breadcrumbs.c @@ -279,7 +279,7 @@ intel_breadcrumbs_create(struct intel_engine_cs *irq_engine) { struct intel_breadcrumbs *b; - b = kzalloc(sizeof(*b), GFP_KERNEL); + b = kzalloc_obj(*b); if (!b) return NULL; diff --git a/drivers/gpu/drm/i915/gt/intel_engine_cs.c b/drivers/gpu/drm/i915/gt/intel_engine_cs.c index 98a3a7a9de50..d37966ec7a92 100644 --- a/drivers/gpu/drm/i915/gt/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/gt/intel_engine_cs.c @@ -471,7 +471,7 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id, if (GEM_DEBUG_WARN_ON(gt->engine_class[info->class][info->instance])) return -EINVAL; - engine = kzalloc(sizeof(*engine), GFP_KERNEL); + engine = kzalloc_obj(*engine); if (!engine) return -ENOMEM; @@ -1311,7 +1311,7 @@ static int measure_breadcrumb_dw(struct intel_context *ce) GEM_BUG_ON(!engine->gt->scratch); - frame = kzalloc(sizeof(*frame), GFP_KERNEL); + frame = kzalloc_obj(*frame); if (!frame) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c index 3df683b0402a..cafe0b8e6bdd 100644 --- a/drivers/gpu/drm/i915/gt/intel_execlists_submission.c +++ b/drivers/gpu/drm/i915/gt/intel_execlists_submission.c @@ -2254,7 +2254,7 @@ static struct execlists_capture *capture_regs(struct intel_engine_cs *engine) const gfp_t gfp = GFP_ATOMIC | __GFP_NOWARN; struct execlists_capture *cap; - cap = kmalloc(sizeof(*cap), gfp); + cap = kmalloc_obj(*cap, gfp); if (!cap) return NULL; @@ -3934,7 +3934,7 @@ execlists_create_virtual(struct intel_engine_cs **siblings, unsigned int count, unsigned int n; int err; - ve = kzalloc(struct_size(ve, siblings, count), GFP_KERNEL); + ve = kzalloc_flex(*ve, siblings, count); if (!ve) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c index 5eda98ebc1ae..db995dce914a 100644 --- a/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c +++ b/drivers/gpu/drm/i915/gt/intel_ggtt_fencing.c @@ -865,9 +865,7 @@ void intel_ggtt_init_fences(struct i915_ggtt *ggtt) if (intel_vgpu_active(i915)) num_fences = intel_uncore_read(uncore, vgtif_reg(avail_rs.fence_num)); - ggtt->fence_regs = kcalloc(num_fences, - sizeof(*ggtt->fence_regs), - GFP_KERNEL); + ggtt->fence_regs = kzalloc_objs(*ggtt->fence_regs, num_fences); if (!ggtt->fence_regs) num_fences = 0; diff --git a/drivers/gpu/drm/i915/gt/intel_gsc.c b/drivers/gpu/drm/i915/gt/intel_gsc.c index c43febc862dc..050d909fb4f8 100644 --- a/drivers/gpu/drm/i915/gt/intel_gsc.c +++ b/drivers/gpu/drm/i915/gt/intel_gsc.c @@ -204,7 +204,7 @@ static void gsc_init_one(struct drm_i915_private *i915, struct intel_gsc *gsc, } add_device: - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) goto fail; diff --git a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c index c7befc5c20d0..372cdc758c5f 100644 --- a/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c +++ b/drivers/gpu/drm/i915/gt/intel_gt_buffer_pool.c @@ -144,8 +144,8 @@ node_create(struct intel_gt_buffer_pool *pool, size_t sz, struct intel_gt_buffer_pool_node *node; struct drm_i915_gem_object *obj; - node = kmalloc(sizeof(*node), - GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + node = kmalloc_obj(*node, + GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); if (!node) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/intel_ppgtt.c b/drivers/gpu/drm/i915/gt/intel_ppgtt.c index d07a4f97b943..72d8473a448b 100644 --- a/drivers/gpu/drm/i915/gt/intel_ppgtt.c +++ b/drivers/gpu/drm/i915/gt/intel_ppgtt.c @@ -17,7 +17,7 @@ struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz) { struct i915_page_table *pt; - pt = kmalloc(sizeof(*pt), I915_GFP_ALLOW_FAIL); + pt = kmalloc_obj(*pt, I915_GFP_ALLOW_FAIL); if (unlikely(!pt)) return ERR_PTR(-ENOMEM); @@ -36,11 +36,11 @@ struct i915_page_directory *__alloc_pd(int count) { struct i915_page_directory *pd; - pd = kzalloc(sizeof(*pd), I915_GFP_ALLOW_FAIL); + pd = kzalloc_obj(*pd, I915_GFP_ALLOW_FAIL); if (unlikely(!pd)) return NULL; - pd->entry = kcalloc(count, sizeof(*pd->entry), I915_GFP_ALLOW_FAIL); + pd->entry = kzalloc_objs(*pd->entry, count, I915_GFP_ALLOW_FAIL); if (unlikely(!pd->entry)) { kfree(pd); return NULL; diff --git a/drivers/gpu/drm/i915/gt/intel_ring.c b/drivers/gpu/drm/i915/gt/intel_ring.c index b74d9205c0f5..be7eeb95ff12 100644 --- a/drivers/gpu/drm/i915/gt/intel_ring.c +++ b/drivers/gpu/drm/i915/gt/intel_ring.c @@ -152,7 +152,7 @@ intel_engine_create_ring(struct intel_engine_cs *engine, int size) GEM_BUG_ON(!is_power_of_2(size)); GEM_BUG_ON(RING_CTL_SIZE(size) & ~RING_NR_PAGES); - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/intel_timeline.c b/drivers/gpu/drm/i915/gt/intel_timeline.c index 843f72829a24..7070047bfbaa 100644 --- a/drivers/gpu/drm/i915/gt/intel_timeline.c +++ b/drivers/gpu/drm/i915/gt/intel_timeline.c @@ -151,7 +151,7 @@ __intel_timeline_create(struct intel_gt *gt, struct intel_timeline *timeline; int err; - timeline = kzalloc(sizeof(*timeline), GFP_KERNEL); + timeline = kzalloc_obj(*timeline); if (!timeline) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/intel_workarounds.c b/drivers/gpu/drm/i915/gt/intel_workarounds.c index ece88c612e27..b0ee3d0ae681 100644 --- a/drivers/gpu/drm/i915/gt/intel_workarounds.c +++ b/drivers/gpu/drm/i915/gt/intel_workarounds.c @@ -157,8 +157,7 @@ static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa) if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */ struct i915_wa *list; - list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*list), - GFP_KERNEL); + list = kmalloc_objs(*list, ALIGN(wal->count + 1, grow)); if (!list) { drm_err(&i915->drm, "No space for workaround init!\n"); return; diff --git a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c index 9e4f0e417b3b..b893a8fde895 100644 --- a/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c +++ b/drivers/gpu/drm/i915/gt/selftest_engine_heartbeat.c @@ -72,7 +72,7 @@ static struct pulse *pulse_create(void) { struct pulse *p; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return p; diff --git a/drivers/gpu/drm/i915/gt/selftest_execlists.c b/drivers/gpu/drm/i915/gt/selftest_execlists.c index a06b397b6d42..21e5ed9f72a3 100644 --- a/drivers/gpu/drm/i915/gt/selftest_execlists.c +++ b/drivers/gpu/drm/i915/gt/selftest_execlists.c @@ -3564,7 +3564,7 @@ static int smoke_crescendo(struct preempt_smoke *smoke, unsigned int flags) unsigned long count; int err = 0; - arg = kmalloc_array(I915_NUM_ENGINES, sizeof(*arg), GFP_KERNEL); + arg = kmalloc_objs(*arg, I915_NUM_ENGINES); if (!arg) return -ENOMEM; @@ -3648,9 +3648,7 @@ static int live_preempt_smoke(void *arg) u32 *cs; int n; - smoke.contexts = kmalloc_array(smoke.ncontext, - sizeof(*smoke.contexts), - GFP_KERNEL); + smoke.contexts = kmalloc_objs(*smoke.contexts, smoke.ncontext); if (!smoke.contexts) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c index 4f252f704975..00dfc37221fa 100644 --- a/drivers/gpu/drm/i915/gt/selftest_hangcheck.c +++ b/drivers/gpu/drm/i915/gt/selftest_hangcheck.c @@ -986,7 +986,7 @@ static int __igt_reset_engines(struct intel_gt *gt, h.ctx->sched.priority = 1024; } - threads = kmalloc_array(I915_NUM_ENGINES, sizeof(*threads), GFP_KERNEL); + threads = kmalloc_objs(*threads, I915_NUM_ENGINES); if (!threads) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/selftest_migrate.c b/drivers/gpu/drm/i915/gt/selftest_migrate.c index fdf0e9858607..5b986a7687d9 100644 --- a/drivers/gpu/drm/i915/gt/selftest_migrate.c +++ b/drivers/gpu/drm/i915/gt/selftest_migrate.c @@ -689,7 +689,7 @@ static int threaded_migrate(struct intel_migrate *migrate, unsigned int i; int err = 0; - thread = kcalloc(n_cpus, sizeof(*thread), GFP_KERNEL); + thread = kzalloc_objs(*thread, n_cpus); if (!thread) return 0; diff --git a/drivers/gpu/drm/i915/gt/selftest_rc6.c b/drivers/gpu/drm/i915/gt/selftest_rc6.c index 41716ed454b7..90f30b988d68 100644 --- a/drivers/gpu/drm/i915/gt/selftest_rc6.c +++ b/drivers/gpu/drm/i915/gt/selftest_rc6.c @@ -201,7 +201,7 @@ randomised_engines(struct intel_gt *gt, if (!n) return NULL; - engines = kmalloc_array(n, sizeof(*engines), GFP_KERNEL); + engines = kmalloc_objs(*engines, n); if (!engines) return NULL; diff --git a/drivers/gpu/drm/i915/gt/selftest_slpc.c b/drivers/gpu/drm/i915/gt/selftest_slpc.c index e61bb0bad12c..c3c918248989 100644 --- a/drivers/gpu/drm/i915/gt/selftest_slpc.c +++ b/drivers/gpu/drm/i915/gt/selftest_slpc.c @@ -499,7 +499,7 @@ static int live_slpc_tile_interaction(void *arg) struct slpc_thread *threads; int i = 0, ret = 0; - threads = kcalloc(I915_MAX_GT, sizeof(*threads), GFP_KERNEL); + threads = kzalloc_objs(*threads, I915_MAX_GT); if (!threads) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/selftest_timeline.c b/drivers/gpu/drm/i915/gt/selftest_timeline.c index fa36cf920bde..29d860a5c9c8 100644 --- a/drivers/gpu/drm/i915/gt/selftest_timeline.c +++ b/drivers/gpu/drm/i915/gt/selftest_timeline.c @@ -170,7 +170,7 @@ static int mock_hwsp_freelist(void *arg) state.max = PAGE_SIZE / sizeof(*state.history); state.count = 0; - state.history = kcalloc(state.max, sizeof(*state.history), GFP_KERNEL); + state.history = kzalloc_objs(*state.history, state.max); if (!state.history) { err = -ENOMEM; goto err_put; @@ -536,9 +536,7 @@ static int live_hwsp_engine(void *arg) * independently to each of their breadcrumb slots. */ - timelines = kvmalloc_array(NUM_TIMELINES * I915_NUM_ENGINES, - sizeof(*timelines), - GFP_KERNEL); + timelines = kvmalloc_objs(*timelines, NUM_TIMELINES * I915_NUM_ENGINES); if (!timelines) return -ENOMEM; @@ -611,9 +609,7 @@ static int live_hwsp_alternate(void *arg) * engines. */ - timelines = kvmalloc_array(NUM_TIMELINES * I915_NUM_ENGINES, - sizeof(*timelines), - GFP_KERNEL); + timelines = kvmalloc_objs(*timelines, NUM_TIMELINES * I915_NUM_ENGINES); if (!timelines) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/selftest_workarounds.c b/drivers/gpu/drm/i915/gt/selftest_workarounds.c index 14a8b25b6204..81cdecd38346 100644 --- a/drivers/gpu/drm/i915/gt/selftest_workarounds.c +++ b/drivers/gpu/drm/i915/gt/selftest_workarounds.c @@ -1204,7 +1204,7 @@ live_gpu_reset_workarounds(void *arg) if (!intel_has_gpu_reset(gt)) return 0; - lists = kzalloc(sizeof(*lists), GFP_KERNEL); + lists = kzalloc_obj(*lists); if (!lists) return -ENOMEM; @@ -1248,7 +1248,7 @@ live_engine_reset_workarounds(void *arg) if (!intel_has_reset_engine(gt)) return 0; - lists = kzalloc(sizeof(*lists), GFP_KERNEL); + lists = kzalloc_obj(*lists); if (!lists) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/shmem_utils.c b/drivers/gpu/drm/i915/gt/shmem_utils.c index 365c4b8b04f4..5850adaebf82 100644 --- a/drivers/gpu/drm/i915/gt/shmem_utils.c +++ b/drivers/gpu/drm/i915/gt/shmem_utils.c @@ -19,7 +19,8 @@ struct file *shmem_create_from_data(const char *name, void *data, size_t len) struct file *file; int err; - file = shmem_file_setup(name, PAGE_ALIGN(len), VM_NORESERVE); + file = shmem_file_setup(name, PAGE_ALIGN(len), + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(file)) return file; @@ -62,7 +63,7 @@ void *shmem_pin_map(struct file *file) void *vaddr; n_pages = file->f_mapping->host->i_size >> PAGE_SHIFT; - pages = kvmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, n_pages); if (!pages) return NULL; diff --git a/drivers/gpu/drm/i915/gt/sysfs_engines.c b/drivers/gpu/drm/i915/gt/sysfs_engines.c index 4a81bc396b21..da740bbcd083 100644 --- a/drivers/gpu/drm/i915/gt/sysfs_engines.c +++ b/drivers/gpu/drm/i915/gt/sysfs_engines.c @@ -430,7 +430,7 @@ kobj_engine(struct kobject *dir, struct intel_engine_cs *engine) { struct kobj_engine *ke; - ke = kzalloc(sizeof(*ke), GFP_KERNEL); + ke = kzalloc_obj(*ke); if (!ke) return NULL; @@ -458,7 +458,7 @@ static void add_defaults(struct kobj_engine *parent) }; struct kobj_engine *ke; - ke = kzalloc(sizeof(*ke), GFP_KERNEL); + ke = kzalloc_obj(*ke); if (!ke) return; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c index 9547fff672bd..865b61057566 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_capture.c @@ -275,7 +275,7 @@ __alloc_ext_regs(struct __guc_mmio_reg_descr_group *newlist, { struct __guc_mmio_reg_descr *list; - list = kcalloc(num_regs, sizeof(struct __guc_mmio_reg_descr), GFP_KERNEL); + list = kzalloc_objs(struct __guc_mmio_reg_descr, num_regs); if (!list) return -ENOMEM; @@ -320,7 +320,7 @@ guc_capture_alloc_steered_lists(struct intel_guc *guc, return; /* allocate an extra for an end marker */ - extlists = kcalloc(2, sizeof(struct __guc_mmio_reg_descr_group), GFP_KERNEL); + extlists = kzalloc_objs(struct __guc_mmio_reg_descr_group, 2); if (!extlists) return; @@ -984,13 +984,13 @@ guc_capture_alloc_one_node(struct intel_guc *guc) struct __guc_capture_parsed_output *new; int i; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; for (i = 0; i < GUC_CAPTURE_LIST_TYPE_MAX; ++i) { - new->reginfo[i].regs = kcalloc(guc->capture->max_mmio_per_node, - sizeof(struct guc_mmio_reg), GFP_KERNEL); + new->reginfo[i].regs = kzalloc_objs(struct guc_mmio_reg, + guc->capture->max_mmio_per_node); if (!new->reginfo[i].regs) { while (i) kfree(new->reginfo[--i].regs); @@ -1639,7 +1639,7 @@ void intel_guc_capture_destroy(struct intel_guc *guc) int intel_guc_capture_init(struct intel_guc *guc) { - guc->capture = kzalloc(sizeof(*guc->capture), GFP_KERNEL); + guc->capture = kzalloc_obj(*guc->capture); if (!guc->capture) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c index f1e53312ed90..8c4da526d461 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_ct.c @@ -866,7 +866,7 @@ static struct ct_incoming_msg *ct_alloc_msg(u32 num_dwords) { struct ct_incoming_msg *msg; - msg = kmalloc(struct_size(msg, msg, num_dwords), GFP_ATOMIC); + msg = kmalloc_flex(*msg, msg, num_dwords, GFP_ATOMIC); if (msg) msg->size = num_dwords; return msg; diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c index 68f2b8d363ac..142183d3f7fb 100644 --- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c +++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c @@ -2110,7 +2110,7 @@ static int init_tlb_lookup(struct intel_guc *guc) xa_init_flags(&guc->tlb_lookup, XA_FLAGS_ALLOC); - wait = kzalloc(sizeof(*wait), GFP_KERNEL); + wait = kzalloc_obj(*wait); if (!wait) return -ENOMEM; @@ -4222,9 +4222,7 @@ guc_create_parallel(struct intel_engine_cs **engines, struct intel_context *parent = NULL, *ce, *err; int i, j; - siblings = kmalloc_array(num_siblings, - sizeof(*siblings), - GFP_KERNEL); + siblings = kmalloc_objs(*siblings, num_siblings); if (!siblings) return ERR_PTR(-ENOMEM); @@ -5907,7 +5905,7 @@ guc_create_virtual(struct intel_engine_cs **siblings, unsigned int count, unsigned int n; int err; - ve = kzalloc(sizeof(*ve), GFP_KERNEL); + ve = kzalloc_obj(*ve); if (!ve) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c index 68feb55654f7..477c163d2660 100644 --- a/drivers/gpu/drm/i915/gt/uc/selftest_guc.c +++ b/drivers/gpu/drm/i915/gt/uc/selftest_guc.c @@ -153,7 +153,7 @@ static int intel_guc_steal_guc_ids(void *arg) struct i915_request *spin_rq = NULL, *rq, *last = NULL; int number_guc_id_stolen = guc->number_guc_id_stolen; - ce = kcalloc(GUC_MAX_CONTEXT_ID, sizeof(*ce), GFP_KERNEL); + ce = kzalloc_objs(*ce, GUC_MAX_CONTEXT_ID); if (!ce) { guc_err(guc, "Context array allocation failed\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/cmd_parser.c b/drivers/gpu/drm/i915/gvt/cmd_parser.c index bf7c3d3f5f8a..b868a0501886 100644 --- a/drivers/gpu/drm/i915/gvt/cmd_parser.c +++ b/drivers/gpu/drm/i915/gvt/cmd_parser.c @@ -1921,7 +1921,7 @@ static int perform_bb_shadow(struct parser_exec_state *s) if (ret) return ret; - bb = kzalloc(sizeof(*bb), GFP_KERNEL); + bb = kzalloc_obj(*bb); if (!bb) return -ENOMEM; @@ -3226,7 +3226,7 @@ static int init_cmd_table(struct intel_gvt *gvt) if (!(cmd_info[i].devices & gen_type)) continue; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c index ae3fd2c3cd23..36f55861228f 100644 --- a/drivers/gpu/drm/i915/gvt/debugfs.c +++ b/drivers/gpu/drm/i915/gvt/debugfs.c @@ -68,7 +68,7 @@ static inline int mmio_diff_handler(struct intel_gvt *gvt, vreg = vgpu_vreg(param->vgpu, offset); if (preg != vreg) { - node = kmalloc(sizeof(*node), GFP_ATOMIC); + node = kmalloc_obj(*node, GFP_ATOMIC); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/display.c b/drivers/gpu/drm/i915/gvt/display.c index 21341842c0a9..fe4302c8cae5 100644 --- a/drivers/gpu/drm/i915/gvt/display.c +++ b/drivers/gpu/drm/i915/gvt/display.c @@ -562,11 +562,11 @@ static int setup_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num, if (drm_WARN_ON(&i915->drm, resolution >= GVT_EDID_NUM)) return -EINVAL; - port->edid = kzalloc(sizeof(*(port->edid)), GFP_KERNEL); + port->edid = kzalloc_obj(*(port->edid)); if (!port->edid) return -ENOMEM; - port->dpcd = kzalloc(sizeof(*(port->dpcd)), GFP_KERNEL); + port->dpcd = kzalloc_obj(*(port->dpcd)); if (!port->dpcd) { kfree(port->edid); return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/dmabuf.c b/drivers/gpu/drm/i915/gvt/dmabuf.c index 8e76869b352c..8a1d6c5636c2 100644 --- a/drivers/gpu/drm/i915/gvt/dmabuf.c +++ b/drivers/gpu/drm/i915/gvt/dmabuf.c @@ -67,7 +67,7 @@ static int vgpu_gem_get_pages(struct drm_i915_gem_object *obj) if (drm_WARN_ON(&dev_priv->drm, !vgpu)) return -ENODEV; - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (unlikely(!st)) return -ENOMEM; @@ -447,15 +447,14 @@ int intel_vgpu_query_plane(struct intel_vgpu *vgpu, void *args) mutex_unlock(&vgpu->dmabuf_lock); /* Need to allocate a new one*/ - dmabuf_obj = kmalloc(sizeof(struct intel_vgpu_dmabuf_obj), GFP_KERNEL); + dmabuf_obj = kmalloc_obj(struct intel_vgpu_dmabuf_obj); if (unlikely(!dmabuf_obj)) { gvt_vgpu_err("alloc dmabuf_obj failed\n"); ret = -ENOMEM; goto out; } - dmabuf_obj->info = kmalloc(sizeof(struct intel_vgpu_fb_info), - GFP_KERNEL); + dmabuf_obj->info = kmalloc_obj(struct intel_vgpu_fb_info); if (unlikely(!dmabuf_obj->info)) { gvt_vgpu_err("allocate intel vgpu fb info failed\n"); ret = -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/gtt.c b/drivers/gpu/drm/i915/gvt/gtt.c index 49028e7ef1e0..5056a5887b31 100644 --- a/drivers/gpu/drm/i915/gvt/gtt.c +++ b/drivers/gpu/drm/i915/gvt/gtt.c @@ -654,7 +654,7 @@ static void *alloc_spt(gfp_t gfp_mask) { struct intel_vgpu_ppgtt_spt *spt; - spt = kzalloc(sizeof(*spt), gfp_mask); + spt = kzalloc_obj(*spt, gfp_mask); if (!spt) return NULL; @@ -1770,7 +1770,7 @@ static struct intel_vgpu_mm *vgpu_alloc_mm(struct intel_vgpu *vgpu) { struct intel_vgpu_mm *mm; - mm = kzalloc(sizeof(*mm), GFP_KERNEL); + mm = kzalloc_obj(*mm); if (!mm) return NULL; @@ -2206,7 +2206,7 @@ static int emulate_ggtt_mmio_write(struct intel_vgpu *vgpu, unsigned int off, if (!found) { /* the first partial part */ - partial_pte = kzalloc(sizeof(*partial_pte), GFP_KERNEL); + partial_pte = kzalloc_obj(*partial_pte); if (!partial_pte) return -ENOMEM; partial_pte->offset = off; @@ -2502,7 +2502,7 @@ static int setup_spt_oos(struct intel_gvt *gvt) INIT_LIST_HEAD(>t->oos_page_use_list_head); for (i = 0; i < preallocated_oos_pages; i++) { - oos_page = kzalloc(sizeof(*oos_page), GFP_KERNEL); + oos_page = kzalloc_obj(*oos_page); if (!oos_page) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/i915/gvt/handlers.c b/drivers/gpu/drm/i915/gvt/handlers.c index bd20f287720f..b0d8d3e74ae7 100644 --- a/drivers/gpu/drm/i915/gvt/handlers.c +++ b/drivers/gpu/drm/i915/gvt/handlers.c @@ -2892,7 +2892,7 @@ static int handle_mmio(struct intel_gvt_mmio_table_iter *iter, u32 offset, return -EEXIST; } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/kvmgt.c b/drivers/gpu/drm/i915/gvt/kvmgt.c index 009aa2df7958..ec62db5cc367 100644 --- a/drivers/gpu/drm/i915/gvt/kvmgt.c +++ b/drivers/gpu/drm/i915/gvt/kvmgt.c @@ -250,7 +250,7 @@ static int __gvt_cache_add(struct intel_vgpu *vgpu, gfn_t gfn, struct gvt_dma *new, *itr; struct rb_node **link, *parent = NULL; - new = kzalloc(sizeof(struct gvt_dma), GFP_KERNEL); + new = kzalloc_obj(struct gvt_dma); if (!new) return -ENOMEM; @@ -378,7 +378,7 @@ static void kvmgt_protect_table_add(struct intel_vgpu *info, gfn_t gfn) if (kvmgt_gfn_is_write_protected(info, gfn)) return; - p = kzalloc(sizeof(struct kvmgt_pgfn), GFP_ATOMIC); + p = kzalloc_obj(struct kvmgt_pgfn, GFP_ATOMIC); if (WARN(!p, "gfn: 0x%llx\n", gfn)) return; @@ -595,7 +595,7 @@ int intel_gvt_set_edid(struct intel_vgpu *vgpu, int port_num) struct vfio_edid_region *base; int ret; - base = kzalloc(sizeof(*base), GFP_KERNEL); + base = kzalloc_obj(*base); if (!base) return -ENOMEM; @@ -1183,8 +1183,7 @@ static int intel_vgpu_ioctl_get_region_info(struct vfio_device *vfio_dev, VFIO_REGION_INFO_FLAG_WRITE; info->size = gvt_aperture_sz(vgpu->gvt); - sparse = kzalloc(struct_size(sparse, areas, nr_areas), - GFP_KERNEL); + sparse = kzalloc_flex(*sparse, areas, nr_areas); if (!sparse) return -ENOMEM; @@ -1830,7 +1829,7 @@ static int intel_gvt_init_device(struct drm_i915_private *i915) if (drm_WARN_ON(&i915->drm, i915->gvt)) return -EEXIST; - gvt = kzalloc(sizeof(struct intel_gvt), GFP_KERNEL); + gvt = kzalloc_obj(struct intel_gvt); if (!gvt) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/page_track.c b/drivers/gpu/drm/i915/gvt/page_track.c index b22ef801963e..3ecac67b0fc4 100644 --- a/drivers/gpu/drm/i915/gvt/page_track.c +++ b/drivers/gpu/drm/i915/gvt/page_track.c @@ -58,7 +58,7 @@ int intel_vgpu_register_page_track(struct intel_vgpu *vgpu, unsigned long gfn, if (track) return -EEXIST; - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (!track) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/sched_policy.c b/drivers/gpu/drm/i915/gvt/sched_policy.c index 9736a15a896f..b353fedc0ba0 100644 --- a/drivers/gpu/drm/i915/gvt/sched_policy.c +++ b/drivers/gpu/drm/i915/gvt/sched_policy.c @@ -282,7 +282,7 @@ static int tbs_sched_init(struct intel_gvt *gvt) struct gvt_sched_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -312,7 +312,7 @@ static int tbs_sched_init_vgpu(struct intel_vgpu *vgpu) { struct vgpu_sched_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/gvt/vgpu.c b/drivers/gpu/drm/i915/gvt/vgpu.c index 96d0bd1fa337..a437875a30e3 100644 --- a/drivers/gpu/drm/i915/gvt/vgpu.c +++ b/drivers/gpu/drm/i915/gvt/vgpu.c @@ -113,13 +113,11 @@ int intel_gvt_init_vgpu_types(struct intel_gvt *gvt) unsigned int num_types = ARRAY_SIZE(intel_vgpu_configs); unsigned int i; - gvt->types = kcalloc(num_types, sizeof(struct intel_vgpu_type), - GFP_KERNEL); + gvt->types = kzalloc_objs(struct intel_vgpu_type, num_types); if (!gvt->types) return -ENOMEM; - gvt->mdev_types = kcalloc(num_types, sizeof(*gvt->mdev_types), - GFP_KERNEL); + gvt->mdev_types = kzalloc_objs(*gvt->mdev_types, num_types); if (!gvt->mdev_types) goto out_free_types; diff --git a/drivers/gpu/drm/i915/i915_active.c b/drivers/gpu/drm/i915/i915_active.c index 6b0c1162505a..25c46d7b1ea7 100644 --- a/drivers/gpu/drm/i915/i915_active.c +++ b/drivers/gpu/drm/i915/i915_active.c @@ -650,7 +650,7 @@ static int __await_barrier(struct i915_active *ref, struct i915_sw_fence *fence) { struct wait_barrier *wb; - wb = kmalloc(sizeof(*wb), GFP_KERNEL); + wb = kmalloc_obj(*wb); if (unlikely(!wb)) return -ENOMEM; @@ -1160,7 +1160,7 @@ struct i915_active *i915_active_create(void) { struct auto_active *aa; - aa = kmalloc(sizeof(*aa), GFP_KERNEL); + aa = kmalloc_obj(*aa); if (!aa) return NULL; diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c index 7654f1be8d3b..41fef2d02449 100644 --- a/drivers/gpu/drm/i915/i915_cmd_parser.c +++ b/drivers/gpu/drm/i915/i915_cmd_parser.c @@ -918,8 +918,7 @@ static int init_hash_table(struct intel_engine_cs *engine, for (j = 0; j < table->count; j++) { const struct drm_i915_cmd_descriptor *desc = &table->table[j]; - struct cmd_node *desc_node = - kmalloc(sizeof(*desc_node), GFP_KERNEL); + struct cmd_node *desc_node = kmalloc_obj(*desc_node); if (!desc_node) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_deps.c b/drivers/gpu/drm/i915/i915_deps.c index 91c61864285a..40133e0ac01a 100644 --- a/drivers/gpu/drm/i915/i915_deps.c +++ b/drivers/gpu/drm/i915/i915_deps.c @@ -82,7 +82,7 @@ static int i915_deps_grow(struct i915_deps *deps, struct dma_fence *fence, struct dma_fence **new_fences; new_size = max(new_size, I915_DEPS_MIN_ALLOC_CHUNK); - new_fences = kmalloc_array(new_size, sizeof(*new_fences), deps->gfp); + new_fences = kmalloc_objs(*new_fences, new_size, deps->gfp); if (!new_fences) goto sync; diff --git a/drivers/gpu/drm/i915/i915_drm_client.c b/drivers/gpu/drm/i915/i915_drm_client.c index 168d7375304b..82cbb0528ff1 100644 --- a/drivers/gpu/drm/i915/i915_drm_client.c +++ b/drivers/gpu/drm/i915/i915_drm_client.c @@ -21,7 +21,7 @@ struct i915_drm_client *i915_drm_client_alloc(void) { struct i915_drm_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return NULL; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b40d4d88de01..160733619a4a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1319,7 +1319,7 @@ int i915_gem_open(struct drm_i915_private *i915, struct drm_file *file) drm_dbg(&i915->drm, "\n"); - file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); + file_priv = kzalloc_obj(*file_priv); if (!file_priv) goto err_alloc; diff --git a/drivers/gpu/drm/i915/i915_gpu_error.c b/drivers/gpu/drm/i915/i915_gpu_error.c index 303d8d9b7775..a99b4e45d26c 100644 --- a/drivers/gpu/drm/i915/i915_gpu_error.c +++ b/drivers/gpu/drm/i915/i915_gpu_error.c @@ -1155,7 +1155,7 @@ i915_vma_coredump_create(const struct intel_gt *gt, if (!vma_res || !vma_res->bi.pages || !compress) return NULL; - dst = kmalloc(sizeof(*dst), ALLOW_FAIL); + dst = kmalloc_obj(*dst, ALLOW_FAIL); if (!dst) return NULL; @@ -1502,7 +1502,7 @@ capture_vma_snapshot(struct intel_engine_capture_vma *next, if (!vma_res) return next; - c = kmalloc(sizeof(*c), gfp); + c = kmalloc_obj(*c, gfp); if (!c) return next; @@ -1598,7 +1598,7 @@ intel_engine_coredump_alloc(struct intel_engine_cs *engine, gfp_t gfp, u32 dump_ { struct intel_engine_coredump *ee; - ee = kzalloc(sizeof(*ee), gfp); + ee = kzalloc_obj(*ee, gfp); if (!ee) return NULL; @@ -1829,7 +1829,7 @@ gt_record_uc(struct intel_gt_coredump *gt, const struct intel_uc *uc = >->_gt->uc; struct intel_uc_coredump *error_uc; - error_uc = kzalloc(sizeof(*error_uc), ALLOW_FAIL); + error_uc = kzalloc_obj(*error_uc, ALLOW_FAIL); if (!error_uc) return NULL; @@ -2088,7 +2088,7 @@ i915_gpu_coredump_alloc(struct drm_i915_private *i915, gfp_t gfp) if (!i915->params.error_capture) return NULL; - error = kzalloc(sizeof(*error), gfp); + error = kzalloc_obj(*error, gfp); if (!error) return NULL; @@ -2112,7 +2112,7 @@ intel_gt_coredump_alloc(struct intel_gt *gt, gfp_t gfp, u32 dump_flags) { struct intel_gt_coredump *gc; - gc = kzalloc(sizeof(*gc), gfp); + gc = kzalloc_obj(*gc, gfp); if (!gc) return NULL; @@ -2143,7 +2143,7 @@ i915_vma_capture_prepare(struct intel_gt_coredump *gt) { struct i915_vma_compress *compress; - compress = kmalloc(sizeof(*compress), ALLOW_FAIL); + compress = kmalloc_obj(*compress, ALLOW_FAIL); if (!compress) return NULL; diff --git a/drivers/gpu/drm/i915/i915_hdcp_gsc.c b/drivers/gpu/drm/i915/i915_hdcp_gsc.c index 9906da2aef1c..168b9ccbef3e 100644 --- a/drivers/gpu/drm/i915/i915_hdcp_gsc.c +++ b/drivers/gpu/drm/i915/i915_hdcp_gsc.c @@ -94,7 +94,7 @@ static struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_de struct intel_hdcp_gsc_context *gsc_context; int ret; - gsc_context = kzalloc(sizeof(*gsc_context), GFP_KERNEL); + gsc_context = kzalloc_obj(*gsc_context); if (!gsc_context) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/i915_hwmon.c b/drivers/gpu/drm/i915/i915_hwmon.c index 7dfe1784153f..16e64d752e12 100644 --- a/drivers/gpu/drm/i915/i915_hwmon.c +++ b/drivers/gpu/drm/i915/i915_hwmon.c @@ -915,7 +915,7 @@ void i915_hwmon_register(struct drm_i915_private *i915) if (!IS_DGFX(i915)) return; - hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); + hwmon = kzalloc_obj(*hwmon); if (!hwmon) return; diff --git a/drivers/gpu/drm/i915/i915_perf.c b/drivers/gpu/drm/i915/i915_perf.c index 0b9d9f3f7813..2820e8f0f765 100644 --- a/drivers/gpu/drm/i915/i915_perf.c +++ b/drivers/gpu/drm/i915/i915_perf.c @@ -2200,7 +2200,7 @@ alloc_oa_config_buffer(struct i915_perf_stream *stream, u32 *cs; int err; - oa_bo = kzalloc(sizeof(*oa_bo), GFP_KERNEL); + oa_bo = kzalloc_obj(*oa_bo); if (!oa_bo) return ERR_PTR(-ENOMEM); @@ -3872,7 +3872,7 @@ i915_perf_open_ioctl_locked(struct i915_perf *perf, goto err_ctx; } - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) { ret = -ENOMEM; goto err_ctx; @@ -4505,7 +4505,7 @@ static struct i915_oa_reg *alloc_oa_regs(struct i915_perf *perf, if (!is_valid) return ERR_PTR(-EINVAL); - oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL); + oa_regs = kmalloc_objs(*oa_regs, n_regs); if (!oa_regs) return ERR_PTR(-ENOMEM); @@ -4614,7 +4614,7 @@ int i915_perf_add_config_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL); + oa_config = kzalloc_obj(*oa_config); if (!oa_config) { drm_dbg(&perf->i915->drm, "Failed to allocate memory for the OA config\n"); @@ -4910,7 +4910,7 @@ static int oa_init_gt(struct intel_gt *gt) struct i915_perf_group *g; intel_engine_mask_t tmp; - g = kcalloc(num_groups, sizeof(*g), GFP_KERNEL); + g = kzalloc_objs(*g, num_groups); if (!g) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index a6697db21c72..1c3bafda9c70 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -1028,16 +1028,16 @@ create_event_attributes(struct i915_pmu *pmu) } /* Allocate attribute objects and table. */ - i915_attr = kcalloc(count, sizeof(*i915_attr), GFP_KERNEL); + i915_attr = kzalloc_objs(*i915_attr, count); if (!i915_attr) goto err_alloc; - pmu_attr = kcalloc(count, sizeof(*pmu_attr), GFP_KERNEL); + pmu_attr = kzalloc_objs(*pmu_attr, count); if (!pmu_attr) goto err_alloc; /* Max one pointer of each attribute type plus a termination entry. */ - attr = kcalloc(count * 2 + 1, sizeof(*attr), GFP_KERNEL); + attr = kzalloc_objs(*attr, count * 2 + 1); if (!attr) goto err_alloc; diff --git a/drivers/gpu/drm/i915/i915_scatterlist.c b/drivers/gpu/drm/i915/i915_scatterlist.c index 4d830740946d..ad868adb30dc 100644 --- a/drivers/gpu/drm/i915/i915_scatterlist.c +++ b/drivers/gpu/drm/i915/i915_scatterlist.c @@ -90,7 +90,7 @@ struct i915_refct_sgt *i915_rsgt_from_mm_node(const struct drm_mm_node *node, GEM_BUG_ON(!max_segment); - rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL | __GFP_NOWARN); + rsgt = kmalloc_obj(*rsgt, GFP_KERNEL | __GFP_NOWARN); if (!rsgt) return ERR_PTR(-ENOMEM); @@ -178,7 +178,7 @@ struct i915_refct_sgt *i915_rsgt_from_buddy_resource(struct ttm_resource *res, GEM_BUG_ON(list_empty(blocks)); GEM_BUG_ON(!max_segment); - rsgt = kmalloc(sizeof(*rsgt), GFP_KERNEL | __GFP_NOWARN); + rsgt = kmalloc_obj(*rsgt, GFP_KERNEL | __GFP_NOWARN); if (!rsgt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/i915_scheduler.c b/drivers/gpu/drm/i915/i915_scheduler.c index 70a854557e6e..aec1342402ca 100644 --- a/drivers/gpu/drm/i915/i915_scheduler.c +++ b/drivers/gpu/drm/i915/i915_scheduler.c @@ -453,7 +453,7 @@ i915_sched_engine_create(unsigned int subclass) { struct i915_sched_engine *sched_engine; - sched_engine = kzalloc(sizeof(*sched_engine), GFP_KERNEL); + sched_engine = kzalloc_obj(*sched_engine); if (!sched_engine) return NULL; diff --git a/drivers/gpu/drm/i915/i915_sw_fence.c b/drivers/gpu/drm/i915/i915_sw_fence.c index 73e89b168fc3..f24f616e23ee 100644 --- a/drivers/gpu/drm/i915/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/i915_sw_fence.c @@ -360,7 +360,7 @@ static int __i915_sw_fence_await_sw_fence(struct i915_sw_fence *fence, pending = I915_SW_FENCE_FLAG_FENCE; if (!wq) { - wq = kmalloc(sizeof(*wq), gfp); + wq = kmalloc_obj(*wq, gfp); if (!wq) { if (!gfpflags_allow_blocking(gfp)) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_syncmap.c b/drivers/gpu/drm/i915/i915_syncmap.c index df6437c37373..fbc3a13a4974 100644 --- a/drivers/gpu/drm/i915/i915_syncmap.c +++ b/drivers/gpu/drm/i915/i915_syncmap.c @@ -197,7 +197,7 @@ __sync_alloc_leaf(struct i915_syncmap *parent, u64 id) { struct i915_syncmap *p; - p = kmalloc(struct_size(p, seqno, KSYNCMAP), GFP_KERNEL); + p = kmalloc_flex(*p, seqno, KSYNCMAP); if (unlikely(!p)) return NULL; @@ -279,8 +279,7 @@ static noinline int __sync_set(struct i915_syncmap **root, u64 id, u32 seqno) unsigned int above; /* Insert a join above the current layer */ - next = kzalloc(struct_size(next, child, KSYNCMAP), - GFP_KERNEL); + next = kzalloc_flex(*next, child, KSYNCMAP); if (unlikely(!next)) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c index d5c6e6605086..caceef5ab543 100644 --- a/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c +++ b/drivers/gpu/drm/i915/i915_ttm_buddy_manager.c @@ -48,7 +48,7 @@ static int i915_ttm_buddy_man_alloc(struct ttm_resource_manager *man, if (!lpfn) lpfn = man->size; - bman_res = kzalloc(sizeof(*bman_res), GFP_KERNEL); + bman_res = kzalloc_obj(*bman_res); if (!bman_res) return -ENOMEM; @@ -289,7 +289,7 @@ int i915_ttm_buddy_man_init(struct ttm_device *bdev, struct i915_ttm_buddy_manager *bman; int err; - bman = kzalloc(sizeof(*bman), GFP_KERNEL); + bman = kzalloc_obj(*bman); if (!bman) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/i915_vma.c b/drivers/gpu/drm/i915/i915_vma.c index 2c0a63664e13..afc192d9931b 100644 --- a/drivers/gpu/drm/i915/i915_vma.c +++ b/drivers/gpu/drm/i915/i915_vma.c @@ -394,7 +394,7 @@ struct i915_vma_work *i915_vma_work(void) { struct i915_vma_work *vw; - vw = kzalloc(sizeof(*vw), GFP_KERNEL); + vw = kzalloc_obj(*vw); if (!vw) return NULL; @@ -1027,7 +1027,7 @@ intel_rotate_pages(struct intel_rotation_info *rot_info, int i; /* Allocate target SG list. */ - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) goto err_st_alloc; @@ -1237,7 +1237,7 @@ intel_remap_pages(struct intel_remapped_info *rem_info, int i; /* Allocate target SG list. */ - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) goto err_st_alloc; @@ -1275,7 +1275,7 @@ intel_partial_pages(const struct i915_gtt_view *view, unsigned int count = view->partial.size; int ret = -ENOMEM; - st = kmalloc(sizeof(*st), GFP_KERNEL); + st = kmalloc_obj(*st); if (!st) goto err_st_alloc; diff --git a/drivers/gpu/drm/i915/intel_memory_region.c b/drivers/gpu/drm/i915/intel_memory_region.c index ce722f20cab1..35f96ce7822f 100644 --- a/drivers/gpu/drm/i915/intel_memory_region.c +++ b/drivers/gpu/drm/i915/intel_memory_region.c @@ -258,7 +258,7 @@ intel_memory_region_create(struct drm_i915_private *i915, struct intel_memory_region *mem; int err; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c index fdd2a940f983..bccedd59a114 100644 --- a/drivers/gpu/drm/i915/intel_uncore.c +++ b/drivers/gpu/drm/i915/intel_uncore.c @@ -2072,7 +2072,7 @@ static int __fw_domain_init(struct intel_uncore *uncore, GEM_BUG_ON(domain_id >= FW_DOMAIN_ID_COUNT); GEM_BUG_ON(uncore->fw_domain[domain_id]); - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/pxp/intel_pxp.c b/drivers/gpu/drm/i915/pxp/intel_pxp.c index d4b0c76f335b..f7ed4e18a3ab 100644 --- a/drivers/gpu/drm/i915/pxp/intel_pxp.c +++ b/drivers/gpu/drm/i915/pxp/intel_pxp.c @@ -222,7 +222,7 @@ int intel_pxp_init(struct drm_i915_private *i915) * including session and object management, or we will init the backend tee * channel for internal users such as HuC loading by GSC */ - i915->pxp = kzalloc(sizeof(*i915->pxp), GFP_KERNEL); + i915->pxp = kzalloc_obj(*i915->pxp); if (!i915->pxp) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/selftests/i915_active.c b/drivers/gpu/drm/i915/selftests/i915_active.c index 36c3a5460221..52345073b409 100644 --- a/drivers/gpu/drm/i915/selftests/i915_active.c +++ b/drivers/gpu/drm/i915/selftests/i915_active.c @@ -66,7 +66,7 @@ static struct live_active *__live_alloc(struct drm_i915_private *i915) { struct live_active *active; - active = kzalloc(sizeof(*active), GFP_KERNEL); + active = kzalloc_obj(*active); if (!active) return NULL; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c index f8fe3681c3dc..718cddde7e73 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_evict.c @@ -421,7 +421,7 @@ static int igt_evict_contexts(void *arg) struct reserved *r; mutex_unlock(&ggtt->vm.mutex); - r = kcalloc(1, sizeof(*r), GFP_KERNEL); + r = kzalloc_objs(*r, 1); mutex_lock(&ggtt->vm.mutex); if (!r) { err = -ENOMEM; diff --git a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c index 0a86e4857539..e6bd06774816 100644 --- a/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/selftests/i915_gem_gtt.c @@ -63,7 +63,7 @@ static int fake_get_pages(struct drm_i915_gem_object *obj) struct scatterlist *sg; typeof(obj->base.size) rem; - pages = kmalloc(sizeof(*pages), GFP); + pages = kmalloc_obj(*pages, GFP); if (!pages) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/selftests/i915_perf.c b/drivers/gpu/drm/i915/selftests/i915_perf.c index 403134a7acec..e9469e27f42a 100644 --- a/drivers/gpu/drm/i915/selftests/i915_perf.c +++ b/drivers/gpu/drm/i915/selftests/i915_perf.c @@ -21,7 +21,7 @@ alloc_empty_config(struct i915_perf *perf) { struct i915_oa_config *oa_config; - oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL); + oa_config = kzalloc_obj(*oa_config); if (!oa_config) return -ENOMEM; @@ -114,7 +114,7 @@ test_stream(struct i915_perf *perf) props.metrics_set = oa_config->id; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) { i915_oa_config_put(oa_config); return NULL; diff --git a/drivers/gpu/drm/i915/selftests/i915_request.c b/drivers/gpu/drm/i915/selftests/i915_request.c index 1260601bda1f..e1a7c454a0a9 100644 --- a/drivers/gpu/drm/i915/selftests/i915_request.c +++ b/drivers/gpu/drm/i915/selftests/i915_request.c @@ -329,7 +329,7 @@ static void __igt_breadcrumbs_smoketest(struct kthread_work *work) * that the fences were marked as signaled. */ - requests = kcalloc(total, sizeof(*requests), GFP_KERNEL); + requests = kzalloc_objs(*requests, total); if (!requests) { thread->result = -ENOMEM; return; @@ -472,11 +472,11 @@ static int mock_breadcrumbs_smoketest(void *arg) * See __igt_breadcrumbs_smoketest(); */ - threads = kcalloc(ncpus, sizeof(*threads), GFP_KERNEL); + threads = kzalloc_objs(*threads, ncpus); if (!threads) return -ENOMEM; - t.contexts = kcalloc(t.ncontexts, sizeof(*t.contexts), GFP_KERNEL); + t.contexts = kzalloc_objs(*t.contexts, t.ncontexts); if (!t.contexts) { ret = -ENOMEM; goto out_threads; @@ -1203,7 +1203,7 @@ static int live_all_engines(void *arg) * block doing so, and that they don't complete too soon. */ - request = kcalloc(nengines, sizeof(*request), GFP_KERNEL); + request = kzalloc_objs(*request, nengines); if (!request) return -ENOMEM; @@ -1333,7 +1333,7 @@ static int live_sequential_engines(void *arg) * they are running on independent engines. */ - request = kcalloc(nengines, sizeof(*request), GFP_KERNEL); + request = kzalloc_objs(*request, nengines); if (!request) return -ENOMEM; @@ -1626,7 +1626,7 @@ static int live_parallel_engines(void *arg) * tests that we load up the system maximally. */ - threads = kcalloc(nengines, sizeof(*threads), GFP_KERNEL); + threads = kzalloc_objs(*threads, nengines); if (!threads) return -ENOMEM; @@ -1754,13 +1754,13 @@ static int live_breadcrumbs_smoketest(void *arg) goto out_rpm; } - smoke = kcalloc(nengines, sizeof(*smoke), GFP_KERNEL); + smoke = kzalloc_objs(*smoke, nengines); if (!smoke) { ret = -ENOMEM; goto out_file; } - threads = kcalloc(ncpus * nengines, sizeof(*threads), GFP_KERNEL); + threads = kzalloc_objs(*threads, ncpus * nengines); if (!threads) { ret = -ENOMEM; goto out_smoke; @@ -1768,9 +1768,7 @@ static int live_breadcrumbs_smoketest(void *arg) smoke[0].request_alloc = __live_request_alloc; smoke[0].ncontexts = 64; - smoke[0].contexts = kcalloc(smoke[0].ncontexts, - sizeof(*smoke[0].contexts), - GFP_KERNEL); + smoke[0].contexts = kzalloc_objs(*smoke[0].contexts, smoke[0].ncontexts); if (!smoke[0].contexts) { ret = -ENOMEM; goto out_threads; @@ -2838,11 +2836,11 @@ static int perf_series_engines(void *arg) unsigned int idx; int err = 0; - stats = kcalloc(nengines, sizeof(*stats), GFP_KERNEL); + stats = kzalloc_objs(*stats, nengines); if (!stats) return -ENOMEM; - ps = kzalloc(struct_size(ps, ce, nengines), GFP_KERNEL); + ps = kzalloc_flex(*ps, ce, nengines); if (!ps) { kfree(stats); return -ENOMEM; @@ -3194,7 +3192,7 @@ static int perf_parallel_engines(void *arg) struct p_thread *engines; int err = 0; - engines = kcalloc(nengines, sizeof(*engines), GFP_KERNEL); + engines = kzalloc_objs(*engines, nengines); if (!engines) return -ENOMEM; diff --git a/drivers/gpu/drm/i915/selftests/i915_sw_fence.c b/drivers/gpu/drm/i915/selftests/i915_sw_fence.c index 8f5ce71fa453..6c376338bb37 100644 --- a/drivers/gpu/drm/i915/selftests/i915_sw_fence.c +++ b/drivers/gpu/drm/i915/selftests/i915_sw_fence.c @@ -47,7 +47,7 @@ static struct i915_sw_fence *alloc_fence(void) { struct i915_sw_fence *fence; - fence = kmalloc(sizeof(*fence), GFP_KERNEL); + fence = kmalloc_obj(*fence); if (!fence) return NULL; @@ -454,7 +454,7 @@ static int test_chain(void *arg) int ret, i; /* Test a long chain of fences */ - fences = kmalloc_array(nfences, sizeof(*fences), GFP_KERNEL); + fences = kmalloc_objs(*fences, nfences); if (!fences) return -ENOMEM; @@ -639,7 +639,7 @@ static struct dma_fence *alloc_dma_fence(void) { struct dma_fence *dma; - dma = kmalloc(sizeof(*dma), GFP_KERNEL); + dma = kmalloc_obj(*dma); if (dma) dma_fence_init(dma, &mock_fence_ops, &mock_fence_lock, 0, 0); diff --git a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c index d79e4defb71d..4ac956dfd1f8 100644 --- a/drivers/gpu/drm/i915/selftests/lib_sw_fence.c +++ b/drivers/gpu/drm/i915/selftests/lib_sw_fence.c @@ -109,7 +109,7 @@ struct i915_sw_fence *heap_fence_create(gfp_t gfp) { struct heap_fence *h; - h = kmalloc(sizeof(*h), gfp); + h = kmalloc_obj(*h, gfp); if (!h) return NULL; diff --git a/drivers/gpu/drm/i915/selftests/mock_gem_device.c b/drivers/gpu/drm/i915/selftests/mock_gem_device.c index b59626c4994c..210b9f8f7b61 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gem_device.c +++ b/drivers/gpu/drm/i915/selftests/mock_gem_device.c @@ -148,7 +148,7 @@ struct drm_i915_private *mock_gem_device(void) struct pci_dev *pdev; int ret; - pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + pdev = kzalloc_obj(*pdev); if (!pdev) return NULL; device_initialize(&pdev->dev); diff --git a/drivers/gpu/drm/i915/selftests/mock_gtt.c b/drivers/gpu/drm/i915/selftests/mock_gtt.c index a516c0aa88fd..933990a8dc52 100644 --- a/drivers/gpu/drm/i915/selftests/mock_gtt.c +++ b/drivers/gpu/drm/i915/selftests/mock_gtt.c @@ -66,7 +66,7 @@ struct i915_ppgtt *mock_ppgtt(struct drm_i915_private *i915, const char *name) { struct i915_ppgtt *ppgtt; - ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); + ppgtt = kzalloc_obj(*ppgtt); if (!ppgtt) return NULL; diff --git a/drivers/gpu/drm/i915/vlv_suspend.c b/drivers/gpu/drm/i915/vlv_suspend.c index bace7b38329b..dac4b9bac743 100644 --- a/drivers/gpu/drm/i915/vlv_suspend.c +++ b/drivers/gpu/drm/i915/vlv_suspend.c @@ -464,8 +464,7 @@ int vlv_suspend_init(struct drm_i915_private *i915) return 0; /* we write all the values in the struct, so no need to zero it out */ - i915->vlv_s0ix_state = kmalloc(sizeof(*i915->vlv_s0ix_state), - GFP_KERNEL); + i915->vlv_s0ix_state = kmalloc_obj(*i915->vlv_s0ix_state); if (!i915->vlv_s0ix_state) return -ENOMEM; diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index 9294b4ba1de7..00c236d24acc 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -543,7 +543,7 @@ struct dma_fence *pvr_kccb_fence_alloc(void) { struct pvr_kccb_fence *kccb_fence; - kccb_fence = kzalloc(sizeof(*kccb_fence), GFP_KERNEL); + kccb_fence = kzalloc_obj(*kccb_fence); if (!kccb_fence) return NULL; diff --git a/drivers/gpu/drm/imagination/pvr_context.c b/drivers/gpu/drm/imagination/pvr_context.c index 5edc3c01af72..8de70c30b9de 100644 --- a/drivers/gpu/drm/imagination/pvr_context.c +++ b/drivers/gpu/drm/imagination/pvr_context.c @@ -292,7 +292,7 @@ int pvr_context_create(struct pvr_file *pvr_file, struct drm_pvr_ioctl_create_co if (ctx_size < 0) return ctx_size; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/gpu/drm/imagination/pvr_drv.c b/drivers/gpu/drm/imagination/pvr_drv.c index 916b40ced7eb..268900464ab6 100644 --- a/drivers/gpu/drm/imagination/pvr_drv.c +++ b/drivers/gpu/drm/imagination/pvr_drv.c @@ -1312,7 +1312,7 @@ pvr_drm_driver_open(struct drm_device *drm_dev, struct drm_file *file) struct pvr_device *pvr_dev = to_pvr_device(drm_dev); struct pvr_file *pvr_file; - pvr_file = kzalloc(sizeof(*pvr_file), GFP_KERNEL); + pvr_file = kzalloc_obj(*pvr_file); if (!pvr_file) return -ENOMEM; diff --git a/drivers/gpu/drm/imagination/pvr_free_list.c b/drivers/gpu/drm/imagination/pvr_free_list.c index 5228e214491c..e85cac83834c 100644 --- a/drivers/gpu/drm/imagination/pvr_free_list.c +++ b/drivers/gpu/drm/imagination/pvr_free_list.c @@ -307,7 +307,7 @@ pvr_free_list_grow(struct pvr_free_list *free_list, u32 num_pages) goto err_unlock; } - free_list_node = kzalloc(sizeof(*free_list_node), GFP_KERNEL); + free_list_node = kzalloc_obj(*free_list_node); if (!free_list_node) { err = -ENOMEM; goto err_unlock; @@ -415,7 +415,7 @@ pvr_free_list_create(struct pvr_file *pvr_file, int err; /* Create and fill out the kernel structure */ - free_list = kzalloc(sizeof(*free_list), GFP_KERNEL); + free_list = kzalloc_obj(*free_list); if (!free_list) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 779a58fe6ee8..288516dc2560 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -1272,7 +1272,7 @@ pvr_fw_object_create_and_map_common(struct pvr_device *pvr_dev, size_t size, /* %DRM_PVR_BO_PM_FW_PROTECT is implicit for FW objects. */ flags |= DRM_PVR_BO_PM_FW_PROTECT; - fw_obj = kzalloc(sizeof(*fw_obj), GFP_KERNEL); + fw_obj = kzalloc_obj(*fw_obj); if (!fw_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_fw_trace.c b/drivers/gpu/drm/imagination/pvr_fw_trace.c index 673ee71276e9..e154cb35f604 100644 --- a/drivers/gpu/drm/imagination/pvr_fw_trace.c +++ b/drivers/gpu/drm/imagination/pvr_fw_trace.c @@ -455,7 +455,7 @@ static int fw_trace_open(struct inode *inode, struct file *file) struct pvr_fw_trace_seq_data *trace_seq_data; int err; - trace_seq_data = kzalloc(sizeof(*trace_seq_data), GFP_KERNEL); + trace_seq_data = kzalloc_obj(*trace_seq_data); if (!trace_seq_data) return -ENOMEM; diff --git a/drivers/gpu/drm/imagination/pvr_gem.c b/drivers/gpu/drm/imagination/pvr_gem.c index c07c9a915190..686a3fe22986 100644 --- a/drivers/gpu/drm/imagination/pvr_gem.c +++ b/drivers/gpu/drm/imagination/pvr_gem.c @@ -314,7 +314,7 @@ struct drm_gem_object *pvr_gem_create_object(struct drm_device *drm_dev, size_t struct drm_gem_object *gem_obj; struct pvr_gem_object *pvr_obj; - pvr_obj = kzalloc(sizeof(*pvr_obj), GFP_KERNEL); + pvr_obj = kzalloc_obj(*pvr_obj); if (!pvr_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_hwrt.c b/drivers/gpu/drm/imagination/pvr_hwrt.c index dc0c25fa1847..05c68c78da22 100644 --- a/drivers/gpu/drm/imagination/pvr_hwrt.c +++ b/drivers/gpu/drm/imagination/pvr_hwrt.c @@ -457,7 +457,7 @@ pvr_hwrt_dataset_create(struct pvr_file *pvr_file, int err, i = 0; /* Create and fill out the kernel structure */ - hwrt = kzalloc(sizeof(*hwrt), GFP_KERNEL); + hwrt = kzalloc_obj(*hwrt); if (!hwrt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_job.c b/drivers/gpu/drm/imagination/pvr_job.c index 7564b0f21b42..0c2f511a6178 100644 --- a/drivers/gpu/drm/imagination/pvr_job.c +++ b/drivers/gpu/drm/imagination/pvr_job.c @@ -415,7 +415,7 @@ create_job(struct pvr_device *pvr_dev, (args->hwrt.set_handle || args->hwrt.data_index)) return ERR_PTR(-EINVAL); - job = kzalloc(sizeof(*job), GFP_KERNEL); + job = kzalloc_obj(*job); if (!job) return ERR_PTR(-ENOMEM); @@ -718,8 +718,8 @@ pvr_submit_jobs(struct pvr_device *pvr_dev, struct pvr_file *pvr_file, if (err) return err; - job_data = kvmalloc_array(args->jobs.count, sizeof(*job_data), - GFP_KERNEL | __GFP_ZERO); + job_data = kvmalloc_objs(*job_data, args->jobs.count, + GFP_KERNEL | __GFP_ZERO); if (!job_data) { err = -ENOMEM; goto out_free; diff --git a/drivers/gpu/drm/imagination/pvr_mmu.c b/drivers/gpu/drm/imagination/pvr_mmu.c index 450d476d183f..2e4da5b2c499 100644 --- a/drivers/gpu/drm/imagination/pvr_mmu.c +++ b/drivers/gpu/drm/imagination/pvr_mmu.c @@ -1828,7 +1828,7 @@ pvr_page_table_l0_get_or_insert(struct pvr_mmu_op_context *op_ctx, */ struct pvr_mmu_context *pvr_mmu_context_create(struct pvr_device *pvr_dev) { - struct pvr_mmu_context *ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + struct pvr_mmu_context *ctx = kzalloc_obj(*ctx); int err; if (!ctx) @@ -1877,8 +1877,7 @@ pvr_page_table_l1_alloc(struct pvr_mmu_context *ctx) { int err; - struct pvr_page_table_l1 *table = - kzalloc(sizeof(*table), GFP_KERNEL); + struct pvr_page_table_l1 *table = kzalloc_obj(*table); if (!table) return ERR_PTR(-ENOMEM); @@ -1906,8 +1905,7 @@ pvr_page_table_l0_alloc(struct pvr_mmu_context *ctx) { int err; - struct pvr_page_table_l0 *table = - kzalloc(sizeof(*table), GFP_KERNEL); + struct pvr_page_table_l0 *table = kzalloc_obj(*table); if (!table) return ERR_PTR(-ENOMEM); @@ -2352,8 +2350,7 @@ pvr_mmu_op_context_create(struct pvr_mmu_context *ctx, struct sg_table *sgt, { int err; - struct pvr_mmu_op_context *op_ctx = - kzalloc(sizeof(*op_ctx), GFP_KERNEL); + struct pvr_mmu_op_context *op_ctx = kzalloc_obj(*op_ctx); if (!op_ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_power.c b/drivers/gpu/drm/imagination/pvr_power.c index b9f801c63260..0cf7393f89c6 100644 --- a/drivers/gpu/drm/imagination/pvr_power.c +++ b/drivers/gpu/drm/imagination/pvr_power.c @@ -614,11 +614,11 @@ int pvr_power_domains_init(struct pvr_device *pvr_dev) link_count = domain_count + (domain_count - 1); - domain_devs = kcalloc(domain_count, sizeof(*domain_devs), GFP_KERNEL); + domain_devs = kzalloc_objs(*domain_devs, domain_count); if (!domain_devs) return -ENOMEM; - domain_links = kcalloc(link_count, sizeof(*domain_links), GFP_KERNEL); + domain_links = kzalloc_objs(*domain_links, link_count); if (!domain_links) return -ENOMEM; diff --git a/drivers/gpu/drm/imagination/pvr_queue.c b/drivers/gpu/drm/imagination/pvr_queue.c index fc415dd0d7a7..dd88949f6194 100644 --- a/drivers/gpu/drm/imagination/pvr_queue.c +++ b/drivers/gpu/drm/imagination/pvr_queue.c @@ -249,7 +249,7 @@ pvr_queue_fence_alloc(void) { struct pvr_queue_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; @@ -1266,7 +1266,7 @@ struct pvr_queue *pvr_queue_create(struct pvr_context *ctx, if (ctx_state_size < 0) return ERR_PTR(ctx_state_size); - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_sync.c b/drivers/gpu/drm/imagination/pvr_sync.c index 129f646d14ba..3582616ff722 100644 --- a/drivers/gpu/drm/imagination/pvr_sync.c +++ b/drivers/gpu/drm/imagination/pvr_sync.c @@ -64,7 +64,7 @@ pvr_sync_signal_array_add(struct xarray *array, struct drm_file *file, u32 handl int err; u32 id; - sig_sync = kzalloc(sizeof(*sig_sync), GFP_KERNEL); + sig_sync = kzalloc_obj(*sig_sync); if (!sig_sync) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imagination/pvr_vm.c b/drivers/gpu/drm/imagination/pvr_vm.c index 9a9ad4e82305..e1ec60f34b6e 100644 --- a/drivers/gpu/drm/imagination/pvr_vm.c +++ b/drivers/gpu/drm/imagination/pvr_vm.c @@ -261,9 +261,9 @@ pvr_vm_bind_op_map_init(struct pvr_vm_bind_op *bind_op, if (IS_ERR(bind_op->gpuvm_bo)) return PTR_ERR(bind_op->gpuvm_bo); - bind_op->new_va = kzalloc(sizeof(*bind_op->new_va), GFP_KERNEL); - bind_op->prev_va = kzalloc(sizeof(*bind_op->prev_va), GFP_KERNEL); - bind_op->next_va = kzalloc(sizeof(*bind_op->next_va), GFP_KERNEL); + bind_op->new_va = kzalloc_obj(*bind_op->new_va); + bind_op->prev_va = kzalloc_obj(*bind_op->prev_va); + bind_op->next_va = kzalloc_obj(*bind_op->next_va); if (!bind_op->new_va || !bind_op->prev_va || !bind_op->next_va) { err = -ENOMEM; goto err_bind_op_fini; @@ -310,8 +310,8 @@ pvr_vm_bind_op_unmap_init(struct pvr_vm_bind_op *bind_op, bind_op->type = PVR_VM_BIND_TYPE_UNMAP; - bind_op->prev_va = kzalloc(sizeof(*bind_op->prev_va), GFP_KERNEL); - bind_op->next_va = kzalloc(sizeof(*bind_op->next_va), GFP_KERNEL); + bind_op->prev_va = kzalloc_obj(*bind_op->prev_va); + bind_op->next_va = kzalloc_obj(*bind_op->next_va); if (!bind_op->prev_va || !bind_op->next_va) { err = -ENOMEM; goto err_bind_op_fini; @@ -565,7 +565,7 @@ pvr_vm_create_context(struct pvr_device *pvr_dev, bool is_userspace_context) return ERR_PTR(-EINVAL); } - vm_ctx = kzalloc(sizeof(*vm_ctx), GFP_KERNEL); + vm_ctx = kzalloc_obj(*vm_ctx); if (!vm_ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imx/dcss/dcss-plane.c b/drivers/gpu/drm/imx/dcss/dcss-plane.c index 0b99b407ac0a..c014ef70dfd1 100644 --- a/drivers/gpu/drm/imx/dcss/dcss-plane.c +++ b/drivers/gpu/drm/imx/dcss/dcss-plane.c @@ -381,7 +381,7 @@ struct dcss_plane *dcss_plane_init(struct drm_device *drm, if (zpos > 2) return ERR_PTR(-EINVAL); - dcss_plane = kzalloc(sizeof(*dcss_plane), GFP_KERNEL); + dcss_plane = kzalloc_obj(*dcss_plane); if (!dcss_plane) { DRM_ERROR("failed to allocate plane\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c index cf7b02b2d52c..a18b9d1a68b6 100644 --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-crtc.c @@ -117,7 +117,7 @@ static void imx_drm_crtc_reset(struct drm_crtc *crtc) kfree(to_imx_crtc_state(crtc->state)); crtc->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -126,7 +126,7 @@ static struct drm_crtc_state *imx_drm_crtc_duplicate_state(struct drm_crtc *crtc { struct imx_crtc_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c index db50eccea0ca..0ea70b8fd743 100644 --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c @@ -308,7 +308,7 @@ static void ipu_plane_state_reset(struct drm_plane *plane) plane->state = NULL; } - ipu_state = kzalloc(sizeof(*ipu_state), GFP_KERNEL); + ipu_state = kzalloc_obj(*ipu_state); if (ipu_state) __drm_atomic_helper_plane_reset(plane, &ipu_state->base); @@ -322,7 +322,7 @@ ipu_plane_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (state) __drm_atomic_helper_plane_duplicate_state(plane, &state->base); diff --git a/drivers/gpu/drm/imx/ipuv3/parallel-display.c b/drivers/gpu/drm/imx/ipuv3/parallel-display.c index 6fbf505d2801..4ce772bc3cb3 100644 --- a/drivers/gpu/drm/imx/ipuv3/parallel-display.c +++ b/drivers/gpu/drm/imx/ipuv3/parallel-display.c @@ -66,7 +66,7 @@ imx_pd_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, } *num_output_fmts = 1; - output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL); + output_fmts = kmalloc_obj(*output_fmts); if (!output_fmts) return NULL; @@ -117,7 +117,7 @@ imx_pd_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, } *num_input_fmts = 1; - input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + input_fmts = kmalloc_obj(*input_fmts); if (!input_fmts) return NULL; @@ -256,7 +256,9 @@ static int imx_pd_probe(struct platform_device *pdev) platform_set_drvdata(pdev, imxpd); - devm_drm_bridge_add(dev, &imxpd->bridge); + ret = devm_drm_bridge_add(dev, &imxpd->bridge); + if (ret) + return ret; return component_add(dev, &imx_pd_ops); } diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c index d3213fbf22be..6601589339f6 100644 --- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c +++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c @@ -923,7 +923,7 @@ ingenic_drm_gem_create_object(struct drm_device *drm, size_t size) struct ingenic_drm *priv = drm_device_get_priv(drm); struct drm_gem_dma_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); @@ -1387,7 +1387,7 @@ static int ingenic_drm_bind(struct device *dev, bool has_components) goto err_devclk_disable; } - private_state = kzalloc(sizeof(*private_state), GFP_KERNEL); + private_state = kzalloc_obj(*private_state); if (!private_state) { ret = -ENOMEM; goto err_clk_notifier_unregister; diff --git a/drivers/gpu/drm/ingenic/ingenic-ipu.c b/drivers/gpu/drm/ingenic/ingenic-ipu.c index 32638a713241..289274f464ba 100644 --- a/drivers/gpu/drm/ingenic/ingenic-ipu.c +++ b/drivers/gpu/drm/ingenic/ingenic-ipu.c @@ -887,7 +887,7 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d) return err; } - private_state = kzalloc(sizeof(*private_state), GFP_KERNEL); + private_state = kzalloc_obj(*private_state); if (!private_state) { err = -ENOMEM; goto err_clk_unprepare; diff --git a/drivers/gpu/drm/kmb/kmb_dsi.c b/drivers/gpu/drm/kmb/kmb_dsi.c index faf38ca9e44c..aeb2f9f98f23 100644 --- a/drivers/gpu/drm/kmb/kmb_dsi.c +++ b/drivers/gpu/drm/kmb/kmb_dsi.c @@ -220,14 +220,14 @@ int kmb_dsi_host_bridge_init(struct device *dev) /* Create and register MIPI DSI host */ if (!dsi_host) { - dsi_host = kzalloc(sizeof(*dsi_host), GFP_KERNEL); + dsi_host = kzalloc_obj(*dsi_host); if (!dsi_host) return -ENOMEM; dsi_host->ops = &kmb_dsi_host_ops; if (!dsi_device) { - dsi_device = kzalloc(sizeof(*dsi_device), GFP_KERNEL); + dsi_device = kzalloc_obj(*dsi_device); if (!dsi_device) { kfree(dsi_host); return -ENOMEM; diff --git a/drivers/gpu/drm/lima/lima_ctx.c b/drivers/gpu/drm/lima/lima_ctx.c index 0e668fc1e0f9..68ede7a725e2 100644 --- a/drivers/gpu/drm/lima/lima_ctx.c +++ b/drivers/gpu/drm/lima/lima_ctx.c @@ -12,7 +12,7 @@ int lima_ctx_create(struct lima_device *dev, struct lima_ctx_mgr *mgr, u32 *id) struct lima_ctx *ctx; int i, err; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->dev = dev; diff --git a/drivers/gpu/drm/lima/lima_drv.c b/drivers/gpu/drm/lima/lima_drv.c index 65210ab081bb..9a0eb1092ad3 100644 --- a/drivers/gpu/drm/lima/lima_drv.c +++ b/drivers/gpu/drm/lima/lima_drv.c @@ -215,7 +215,7 @@ static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file) struct lima_drm_priv *priv; struct lima_device *ldev = to_lima_dev(dev); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c index 9722b847a539..0c73860bb501 100644 --- a/drivers/gpu/drm/lima/lima_gem.c +++ b/drivers/gpu/drm/lima/lima_gem.c @@ -39,8 +39,8 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) if (bo->base.pages) { pages = bo->base.pages; } else { - pages = kvmalloc_array(bo->base.base.size >> PAGE_SHIFT, - sizeof(*pages), GFP_KERNEL | __GFP_ZERO); + pages = kvmalloc_objs(*pages, bo->base.base.size >> PAGE_SHIFT, + GFP_KERNEL | __GFP_ZERO); if (!pages) { dma_resv_unlock(bo->base.base.resv); return -ENOMEM; @@ -73,7 +73,7 @@ int lima_heap_alloc(struct lima_bo *bo, struct lima_vm *vm) dma_unmap_sgtable(dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); sg_free_table(bo->base.sgt); } else { - bo->base.sgt = kmalloc(sizeof(*bo->base.sgt), GFP_KERNEL); + bo->base.sgt = kmalloc_obj(*bo->base.sgt); if (!bo->base.sgt) { ret = -ENOMEM; goto err_out0; @@ -226,7 +226,7 @@ struct drm_gem_object *lima_gem_create_object(struct drm_device *dev, size_t siz { struct lima_bo *bo; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/lima/lima_vm.c b/drivers/gpu/drm/lima/lima_vm.c index 2b2739adc7f5..c1b75b15c260 100644 --- a/drivers/gpu/drm/lima/lima_vm.c +++ b/drivers/gpu/drm/lima/lima_vm.c @@ -109,7 +109,7 @@ int lima_vm_bo_add(struct lima_vm *vm, struct lima_bo *bo, bool create) return -ENOENT; } - bo_va = kzalloc(sizeof(*bo_va), GFP_KERNEL); + bo_va = kzalloc_obj(*bo_va); if (!bo_va) { err = -ENOMEM; goto err_out0; @@ -201,7 +201,7 @@ struct lima_vm *lima_vm_create(struct lima_device *dev) { struct lima_vm *vm; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = kzalloc_obj(*vm); if (!vm) return NULL; diff --git a/drivers/gpu/drm/logicvc/logicvc_drm.c b/drivers/gpu/drm/logicvc/logicvc_drm.c index 204b0fee55d0..bbebf4fc7f51 100644 --- a/drivers/gpu/drm/logicvc/logicvc_drm.c +++ b/drivers/gpu/drm/logicvc/logicvc_drm.c @@ -92,7 +92,6 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc) struct device *dev = drm_dev->dev; struct device_node *of_node = dev->of_node; struct logicvc_drm_config *config = &logicvc->config; - struct device_node *layers_node; int ret; logicvc_of_property_parse_bool(of_node, LOGICVC_OF_PROPERTY_DITHERING, @@ -128,7 +127,8 @@ static int logicvc_drm_config_parse(struct logicvc_drm *logicvc) if (ret) return ret; - layers_node = of_get_child_by_name(of_node, "layers"); + struct device_node *layers_node __free(device_node) = + of_get_child_by_name(of_node, "layers"); if (!layers_node) { drm_err(drm_dev, "Missing non-optional layers node\n"); return -EINVAL; diff --git a/drivers/gpu/drm/loongson/lsdc_crtc.c b/drivers/gpu/drm/loongson/lsdc_crtc.c index a5b7d5c5fd20..587fbe285e9e 100644 --- a/drivers/gpu/drm/loongson/lsdc_crtc.c +++ b/drivers/gpu/drm/loongson/lsdc_crtc.c @@ -397,7 +397,7 @@ static void lsdc_crtc_reset(struct drm_crtc *crtc) if (crtc->state) crtc->funcs->atomic_destroy_state(crtc, crtc->state); - priv_crtc_state = kzalloc(sizeof(*priv_crtc_state), GFP_KERNEL); + priv_crtc_state = kzalloc_obj(*priv_crtc_state); if (!priv_crtc_state) __drm_atomic_helper_crtc_reset(crtc, NULL); @@ -424,7 +424,7 @@ lsdc_crtc_atomic_duplicate_state(struct drm_crtc *crtc) struct lsdc_crtc_state *new_priv_state; struct lsdc_crtc_state *old_priv_state; - new_priv_state = kzalloc(sizeof(*new_priv_state), GFP_KERNEL); + new_priv_state = kzalloc_obj(*new_priv_state); if (!new_priv_state) return NULL; diff --git a/drivers/gpu/drm/loongson/lsdc_gfxpll.c b/drivers/gpu/drm/loongson/lsdc_gfxpll.c index 249c09d703ad..2daa62e72fda 100644 --- a/drivers/gpu/drm/loongson/lsdc_gfxpll.c +++ b/drivers/gpu/drm/loongson/lsdc_gfxpll.c @@ -178,7 +178,7 @@ int loongson_gfxpll_create(struct drm_device *ddev, struct loongson_gfxpll *this; int ret; - this = kzalloc(sizeof(*this), GFP_KERNEL); + this = kzalloc_obj(*this); if (IS_ERR_OR_NULL(this)) return -ENOMEM; diff --git a/drivers/gpu/drm/loongson/lsdc_i2c.c b/drivers/gpu/drm/loongson/lsdc_i2c.c index 012b4761c538..b5ff68866f02 100644 --- a/drivers/gpu/drm/loongson/lsdc_i2c.c +++ b/drivers/gpu/drm/loongson/lsdc_i2c.c @@ -124,7 +124,7 @@ int lsdc_create_i2c_chan(struct drm_device *ddev, struct lsdc_i2c *li2c; int ret; - li2c = kzalloc(sizeof(*li2c), GFP_KERNEL); + li2c = kzalloc_obj(*li2c); if (!li2c) return -ENOMEM; diff --git a/drivers/gpu/drm/loongson/lsdc_pixpll.c b/drivers/gpu/drm/loongson/lsdc_pixpll.c index 51b9a032cf43..41131a74056f 100644 --- a/drivers/gpu/drm/loongson/lsdc_pixpll.c +++ b/drivers/gpu/drm/loongson/lsdc_pixpll.c @@ -124,7 +124,7 @@ static int lsdc_pixel_pll_setup(struct lsdc_pixpll * const this) if (!this->mmio) return -ENOMEM; - pparms = kzalloc(sizeof(*pparms), GFP_KERNEL); + pparms = kzalloc_obj(*pparms); if (!pparms) { iounmap(this->mmio); return -ENOMEM; diff --git a/drivers/gpu/drm/loongson/lsdc_ttm.c b/drivers/gpu/drm/loongson/lsdc_ttm.c index 5d9075634bf8..d7441d96a0dc 100644 --- a/drivers/gpu/drm/loongson/lsdc_ttm.c +++ b/drivers/gpu/drm/loongson/lsdc_ttm.c @@ -96,7 +96,7 @@ lsdc_ttm_tt_create(struct ttm_buffer_object *tbo, uint32_t page_flags) struct ttm_tt *tt; int ret; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); if (!tt) return NULL; @@ -441,7 +441,7 @@ struct lsdc_bo *lsdc_bo_create(struct drm_device *ddev, enum ttm_bo_type bo_type; int ret; - lbo = kzalloc(sizeof(*lbo), GFP_KERNEL); + lbo = kzalloc_obj(*lbo); if (!lbo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/mediatek/mtk_crtc.c b/drivers/gpu/drm/mediatek/mtk_crtc.c index 6ad712c0339a..351d58c50b84 100644 --- a/drivers/gpu/drm/mediatek/mtk_crtc.c +++ b/drivers/gpu/drm/mediatek/mtk_crtc.c @@ -160,7 +160,7 @@ static void mtk_crtc_reset(struct drm_crtc *crtc) kfree(to_mtk_crtc_state(crtc->state)); crtc->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -169,7 +169,7 @@ static struct drm_crtc_state *mtk_crtc_duplicate_state(struct drm_crtc *crtc) { struct mtk_crtc_state *state; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/gpu/drm/mediatek/mtk_dp.c b/drivers/gpu/drm/mediatek/mtk_dp.c index 5e67dab6e2e9..08c4d64b87b9 100644 --- a/drivers/gpu/drm/mediatek/mtk_dp.c +++ b/drivers/gpu/drm/mediatek/mtk_dp.c @@ -2482,7 +2482,7 @@ static u32 *mtk_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, u32 *output_fmts; *num_output_fmts = 0; - output_fmts = kmalloc(sizeof(*output_fmts), GFP_KERNEL); + output_fmts = kmalloc_obj(*output_fmts); if (!output_fmts) return NULL; *num_output_fmts = 1; diff --git a/drivers/gpu/drm/mediatek/mtk_gem.c b/drivers/gpu/drm/mediatek/mtk_gem.c index 7525a9f9907a..f059a1452220 100644 --- a/drivers/gpu/drm/mediatek/mtk_gem.c +++ b/drivers/gpu/drm/mediatek/mtk_gem.c @@ -50,7 +50,7 @@ static struct sg_table *mtk_gem_prime_get_sg_table(struct drm_gem_object *obj) struct sg_table *sgt; int ret; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); @@ -85,7 +85,7 @@ static struct drm_gem_dma_object *mtk_gem_init(struct drm_device *dev, if (size == 0) return ERR_PTR(-EINVAL); - dma_obj = kzalloc(sizeof(*dma_obj), GFP_KERNEL); + dma_obj = kzalloc_obj(*dma_obj); if (!dma_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/mediatek/mtk_plane.c b/drivers/gpu/drm/mediatek/mtk_plane.c index fcd10d7e8342..86c6f60eadb3 100644 --- a/drivers/gpu/drm/mediatek/mtk_plane.c +++ b/drivers/gpu/drm/mediatek/mtk_plane.c @@ -35,7 +35,7 @@ static void mtk_plane_reset(struct drm_plane *plane) state = to_mtk_plane_state(plane->state); memset(state, 0, sizeof(*state)); } else { - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return; } @@ -52,7 +52,7 @@ static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane struct mtk_plane_state *old_state = to_mtk_plane_state(plane->state); struct mtk_plane_state *state; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index d019177462cf..8894a063b1a1 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -697,7 +697,7 @@ void mgag200_crtc_reset(struct drm_crtc *crtc) if (crtc->state) crtc->funcs->atomic_destroy_state(crtc, crtc->state); - mgag200_crtc_state = kzalloc(sizeof(*mgag200_crtc_state), GFP_KERNEL); + mgag200_crtc_state = kzalloc_obj(*mgag200_crtc_state); if (mgag200_crtc_state) __drm_atomic_helper_crtc_reset(crtc, &mgag200_crtc_state->base); else @@ -713,7 +713,7 @@ struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc if (!crtc_state) return NULL; - new_mgag200_crtc_state = kzalloc(sizeof(*new_mgag200_crtc_state), GFP_KERNEL); + new_mgag200_crtc_state = kzalloc_obj(*new_mgag200_crtc_state); if (!new_mgag200_crtc_state) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &new_mgag200_crtc_state->base); diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c index f6e48bb8cc69..d5a5fa9e2cf8 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c @@ -457,7 +457,7 @@ static void a2xx_dump(struct msm_gpu *gpu) static struct msm_gpu_state *a2xx_gpu_state_get(struct msm_gpu *gpu) { - struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct msm_gpu_state *state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); @@ -509,7 +509,7 @@ static struct msm_gpu *a2xx_gpu_init(struct drm_device *dev) goto fail; } - a2xx_gpu = kzalloc(sizeof(*a2xx_gpu), GFP_KERNEL); + a2xx_gpu = kzalloc_obj(*a2xx_gpu); if (!a2xx_gpu) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c index 0407c9bc8c1b..e2225c5ba647 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c +++ b/drivers/gpu/drm/msm/adreno/a2xx_gpummu.c @@ -78,7 +78,7 @@ static void a2xx_gpummu_destroy(struct msm_mmu *mmu) { struct a2xx_gpummu *gpummu = to_a2xx_gpummu(mmu); - dma_free_attrs(mmu->dev, TABLE_SIZE, gpummu->table, gpummu->pt_base, + dma_free_attrs(mmu->dev, TABLE_SIZE + 32, gpummu->table, gpummu->pt_base, DMA_ATTR_FORCE_CONTIGUOUS); kfree(gpummu); @@ -95,7 +95,7 @@ struct msm_mmu *a2xx_gpummu_new(struct device *dev, struct msm_gpu *gpu) { struct a2xx_gpummu *gpummu; - gpummu = kzalloc(sizeof(*gpummu), GFP_KERNEL); + gpummu = kzalloc_obj(*gpummu); if (!gpummu) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c index f22d33e99e81..018183e0ac3f 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a3xx_gpu.c @@ -480,7 +480,7 @@ static void a3xx_dump(struct msm_gpu *gpu) static struct msm_gpu_state *a3xx_gpu_state_get(struct msm_gpu *gpu) { - struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct msm_gpu_state *state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); @@ -533,7 +533,7 @@ static struct msm_gpu *a3xx_gpu_init(struct drm_device *dev) goto fail; } - a3xx_gpu = kzalloc(sizeof(*a3xx_gpu), GFP_KERNEL); + a3xx_gpu = kzalloc_obj(*a3xx_gpu); if (!a3xx_gpu) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c index db06c06067ae..8464d89e37f3 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a4xx_gpu.c @@ -550,7 +550,7 @@ static const unsigned int a405_registers[] = { static struct msm_gpu_state *a4xx_gpu_state_get(struct msm_gpu *gpu) { - struct msm_gpu_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct msm_gpu_state *state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); @@ -645,7 +645,7 @@ static struct msm_gpu *a4xx_gpu_init(struct drm_device *dev) goto fail; } - a4xx_gpu = kzalloc(sizeof(*a4xx_gpu), GFP_KERNEL); + a4xx_gpu = kzalloc_obj(*a4xx_gpu); if (!a4xx_gpu) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 56eaff2ee4e4..ef9fd6171af7 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1570,8 +1570,7 @@ static void a5xx_gpu_state_get_hlsq_regs(struct msm_gpu *gpu, static struct msm_gpu_state *a5xx_gpu_state_get(struct msm_gpu *gpu) { - struct a5xx_gpu_state *a5xx_state = kzalloc(sizeof(*a5xx_state), - GFP_KERNEL); + struct a5xx_gpu_state *a5xx_state = kzalloc_obj(*a5xx_state); bool stalled = !!(gpu_read(gpu, REG_A5XX_RBBM_STATUS3) & BIT(24)); if (!a5xx_state) @@ -1735,7 +1734,7 @@ static struct msm_gpu *a5xx_gpu_init(struct drm_device *dev) unsigned int nr_rings; int ret; - a5xx_gpu = kzalloc(sizeof(*a5xx_gpu), GFP_KERNEL); + a5xx_gpu = kzalloc_obj(*a5xx_gpu); if (!a5xx_gpu) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c index 550a53a7865e..38561f26837e 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_catalog.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_catalog.c @@ -1759,7 +1759,7 @@ static const u32 x285_protect_regs[] = { A6XX_PROTECT_NORDWR(0x27c06, 0x0000), }; -DECLARE_ADRENO_PROTECT(x285_protect, 64); +DECLARE_ADRENO_PROTECT(x285_protect, 15); static const struct adreno_reglist_pipe a840_nonctxt_regs[] = { { REG_A8XX_CP_SMMU_STREAM_ID_LPAC, 0x00000101, BIT(PIPE_NONE) }, @@ -1966,5 +1966,4 @@ static inline __always_unused void __build_asserts(void) BUILD_BUG_ON(a660_protect.count > a660_protect.count_max); BUILD_BUG_ON(a690_protect.count > a690_protect.count_max); BUILD_BUG_ON(a730_protect.count > a730_protect.count_max); - BUILD_BUG_ON(a840_protect.count > a840_protect.count_max); } diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index 2129d230a92b..d6dfe6337bc3 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -2648,7 +2648,7 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_device *dev) bool is_a7xx; int ret, nr_rings = 1; - a6xx_gpu = kzalloc(sizeof(*a6xx_gpu), GFP_KERNEL); + a6xx_gpu = kzalloc_obj(*a6xx_gpu); if (!a6xx_gpu) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c index d2d6b2fd3cba..2d56fe0a65b7 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu_state.c @@ -1584,8 +1584,7 @@ struct msm_gpu_state *a6xx_gpu_state_get(struct msm_gpu *gpu) struct a6xx_crashdumper _dumper = { 0 }, *dumper = NULL; struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu); - struct a6xx_gpu_state *a6xx_state = kzalloc(sizeof(*a6xx_state), - GFP_KERNEL); + struct a6xx_gpu_state *a6xx_state = kzalloc_obj(*a6xx_state); bool stalled; if (!a6xx_state) diff --git a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c index 5a320f5bde41..b1887e0cf698 100644 --- a/drivers/gpu/drm/msm/adreno/a8xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a8xx_gpu.c @@ -310,11 +310,21 @@ static void a8xx_set_ubwc_config(struct msm_gpu *gpu) hbb = cfg->highest_bank_bit - 13; hbb_hi = hbb >> 2; hbb_lo = hbb & 3; - a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_GRAS_NC_MODE_CNTL, hbb << 5); - a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_GRAS_NC_MODE_CNTL, hbb << 5); + + a8xx_write_pipe(gpu, PIPE_BV, REG_A8XX_GRAS_NC_MODE_CNTL, + hbb << 5 | + level3_swizzling_dis << 4 | + level2_swizzling_dis << 3); + + a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_GRAS_NC_MODE_CNTL, + hbb << 5 | + level3_swizzling_dis << 4 | + level2_swizzling_dis << 3); a8xx_write_pipe(gpu, PIPE_BR, REG_A8XX_RB_CCU_NC_MODE_CNTL, yuvnotcomptofc << 6 | + level3_swizzling_dis << 5 | + level2_swizzling_dis << 4 | hbb_hi << 3 | hbb_lo << 1); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 554d746f115b..4edfe80c5be7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -302,6 +302,7 @@ static const struct of_device_id dt_match[] = { { .compatible = "qcom,kgsl-3d0" }, {} }; +MODULE_DEVICE_TABLE(of, dt_match); static int adreno_runtime_resume(struct device *dev) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 303d33dc7783..9f2bceca1789 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -133,7 +133,7 @@ static const struct dpu_sspp_cfg sc8280xp_sspp[] = { static const struct dpu_lm_cfg sc8280xp_lm[] = { { .name = "lm_0", .id = LM_0, - .base = 0x44000, .len = 0x320, + .base = 0x44000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_1, @@ -141,7 +141,7 @@ static const struct dpu_lm_cfg sc8280xp_lm[] = { .dspp = DSPP_0, }, { .name = "lm_1", .id = LM_1, - .base = 0x45000, .len = 0x320, + .base = 0x45000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_0, @@ -149,7 +149,7 @@ static const struct dpu_lm_cfg sc8280xp_lm[] = { .dspp = DSPP_1, }, { .name = "lm_2", .id = LM_2, - .base = 0x46000, .len = 0x320, + .base = 0x46000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_3, @@ -157,7 +157,7 @@ static const struct dpu_lm_cfg sc8280xp_lm[] = { .dspp = DSPP_2, }, { .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, + .base = 0x47000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, @@ -165,14 +165,14 @@ static const struct dpu_lm_cfg sc8280xp_lm[] = { .dspp = DSPP_3, }, { .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, + .base = 0x48000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_5, .pingpong = PINGPONG_4, }, { .name = "lm_5", .id = LM_5, - .base = 0x49000, .len = 0x320, + .base = 0x49000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_4, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h index b09a6af4c474..04b22167f93d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h @@ -134,7 +134,7 @@ static const struct dpu_sspp_cfg sm8450_sspp[] = { static const struct dpu_lm_cfg sm8450_lm[] = { { .name = "lm_0", .id = LM_0, - .base = 0x44000, .len = 0x320, + .base = 0x44000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_1, @@ -142,7 +142,7 @@ static const struct dpu_lm_cfg sm8450_lm[] = { .dspp = DSPP_0, }, { .name = "lm_1", .id = LM_1, - .base = 0x45000, .len = 0x320, + .base = 0x45000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_0, @@ -150,7 +150,7 @@ static const struct dpu_lm_cfg sm8450_lm[] = { .dspp = DSPP_1, }, { .name = "lm_2", .id = LM_2, - .base = 0x46000, .len = 0x320, + .base = 0x46000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_3, @@ -158,7 +158,7 @@ static const struct dpu_lm_cfg sm8450_lm[] = { .dspp = DSPP_2, }, { .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, + .base = 0x47000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, @@ -166,14 +166,14 @@ static const struct dpu_lm_cfg sm8450_lm[] = { .dspp = DSPP_3, }, { .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, + .base = 0x48000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_5, .pingpong = PINGPONG_4, }, { .name = "lm_5", .id = LM_5, - .base = 0x49000, .len = 0x320, + .base = 0x49000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_4, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h index 0f7b4a224e4c..42cf3bd5a12a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_4_sa8775p.h @@ -366,8 +366,8 @@ static const struct dpu_intf_cfg sa8775p_intf[] = { .type = INTF_NONE, .controller_id = MSM_DP_CONTROLLER_0, /* pair with intf_0 for DP MST */ .prog_fetch_lines_worst_case = 24, - .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17), - .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16), + .intr_underrun = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 16), + .intr_vsync = DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 17), }, { .name = "intf_7", .id = INTF_7, .base = 0x3b000, .len = 0x280, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h index 465b6460f875..4c7eb55d474c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h @@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sm8550_sspp[] = { static const struct dpu_lm_cfg sm8550_lm[] = { { .name = "lm_0", .id = LM_0, - .base = 0x44000, .len = 0x320, + .base = 0x44000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_1, @@ -139,7 +139,7 @@ static const struct dpu_lm_cfg sm8550_lm[] = { .dspp = DSPP_0, }, { .name = "lm_1", .id = LM_1, - .base = 0x45000, .len = 0x320, + .base = 0x45000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_0, @@ -147,7 +147,7 @@ static const struct dpu_lm_cfg sm8550_lm[] = { .dspp = DSPP_1, }, { .name = "lm_2", .id = LM_2, - .base = 0x46000, .len = 0x320, + .base = 0x46000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_3, @@ -155,7 +155,7 @@ static const struct dpu_lm_cfg sm8550_lm[] = { .dspp = DSPP_2, }, { .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, + .base = 0x47000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, @@ -163,14 +163,14 @@ static const struct dpu_lm_cfg sm8550_lm[] = { .dspp = DSPP_3, }, { .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, + .base = 0x48000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_5, .pingpong = PINGPONG_4, }, { .name = "lm_5", .id = LM_5, - .base = 0x49000, .len = 0x320, + .base = 0x49000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_4, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h index 6caa7d40f368..dec83ea8167d 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_1_sar2130p.h @@ -131,7 +131,7 @@ static const struct dpu_sspp_cfg sar2130p_sspp[] = { static const struct dpu_lm_cfg sar2130p_lm[] = { { .name = "lm_0", .id = LM_0, - .base = 0x44000, .len = 0x320, + .base = 0x44000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_1, @@ -139,7 +139,7 @@ static const struct dpu_lm_cfg sar2130p_lm[] = { .dspp = DSPP_0, }, { .name = "lm_1", .id = LM_1, - .base = 0x45000, .len = 0x320, + .base = 0x45000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_0, @@ -147,7 +147,7 @@ static const struct dpu_lm_cfg sar2130p_lm[] = { .dspp = DSPP_1, }, { .name = "lm_2", .id = LM_2, - .base = 0x46000, .len = 0x320, + .base = 0x46000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_3, @@ -155,7 +155,7 @@ static const struct dpu_lm_cfg sar2130p_lm[] = { .dspp = DSPP_2, }, { .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, + .base = 0x47000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, @@ -163,14 +163,14 @@ static const struct dpu_lm_cfg sar2130p_lm[] = { .dspp = DSPP_3, }, { .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, + .base = 0x48000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_5, .pingpong = PINGPONG_4, }, { .name = "lm_5", .id = LM_5, - .base = 0x49000, .len = 0x320, + .base = 0x49000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_4, diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h index 7243eebb85f3..52ff4baa668a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_2_x1e80100.h @@ -130,7 +130,7 @@ static const struct dpu_sspp_cfg x1e80100_sspp[] = { static const struct dpu_lm_cfg x1e80100_lm[] = { { .name = "lm_0", .id = LM_0, - .base = 0x44000, .len = 0x320, + .base = 0x44000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_1, @@ -138,7 +138,7 @@ static const struct dpu_lm_cfg x1e80100_lm[] = { .dspp = DSPP_0, }, { .name = "lm_1", .id = LM_1, - .base = 0x45000, .len = 0x320, + .base = 0x45000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_0, @@ -146,7 +146,7 @@ static const struct dpu_lm_cfg x1e80100_lm[] = { .dspp = DSPP_1, }, { .name = "lm_2", .id = LM_2, - .base = 0x46000, .len = 0x320, + .base = 0x46000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_3, @@ -154,7 +154,7 @@ static const struct dpu_lm_cfg x1e80100_lm[] = { .dspp = DSPP_2, }, { .name = "lm_3", .id = LM_3, - .base = 0x47000, .len = 0x320, + .base = 0x47000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_2, @@ -162,14 +162,14 @@ static const struct dpu_lm_cfg x1e80100_lm[] = { .dspp = DSPP_3, }, { .name = "lm_4", .id = LM_4, - .base = 0x48000, .len = 0x320, + .base = 0x48000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_5, .pingpong = PINGPONG_4, }, { .name = "lm_5", .id = LM_5, - .base = 0x49000, .len = 0x320, + .base = 0x49000, .len = 0x400, .features = MIXER_MSM8998_MASK, .sblk = &sdm845_lm_sblk, .lm_pair = LM_4, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 6bf7c46379ae..0f4921b1a892 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -887,7 +887,7 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc) if (!state->gamma_lut) { dspp->ops.setup_gc(dspp, NULL); } else { - gc_lut = kzalloc(sizeof(*gc_lut), GFP_KERNEL); + gc_lut = kzalloc_obj(*gc_lut); if (!gc_lut) continue; _dpu_crtc_get_gc_lut(state, gc_lut); @@ -1146,7 +1146,7 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) static void dpu_crtc_reset(struct drm_crtc *crtc) { - struct dpu_crtc_state *cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); + struct dpu_crtc_state *cstate = kzalloc_obj(*cstate); if (crtc->state) dpu_crtc_destroy_state(crtc, crtc->state); @@ -1343,7 +1343,7 @@ static int dpu_crtc_reassign_planes(struct drm_crtc *crtc, struct drm_crtc_state if (!crtc_state->enable) return 0; - states = kcalloc(total_planes, sizeof(*states), GFP_KERNEL); + states = kzalloc_objs(*states, total_planes); if (!states) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c index 188ee0af2c90..23dcbe1ce1b8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dspp.c @@ -89,7 +89,7 @@ static void dpu_setup_dspp_gc(struct dpu_hw_dspp *ctx, base = ctx->cap->sblk->gc.base; if (!base) { - DRM_ERROR("invalid ctx %pK gc base\n", ctx); + DRM_ERROR("invalid ctx %p gc base\n", ctx); return; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp_v13.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp_v13.c index e65f1fc026fd..f8f96ad971d7 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp_v13.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp_v13.c @@ -156,11 +156,13 @@ static void dpu_hw_sspp_setup_pe_config_v13(struct dpu_hw_sspp *ctx, u8 color; u32 lr_pe[4], tb_pe[4]; const u32 bytemask = 0xff; - u32 offset = ctx->cap->sblk->sspp_rec0_blk.base; + u32 offset; if (!ctx || !pe_ext) return; + offset = ctx->cap->sblk->sspp_rec0_blk.base; + c = &ctx->hw; /* program SW pixel extension override for all pipes*/ for (color = 0; color < DPU_MAX_PLANES; color++) { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 0623f1dbed97..61d7e65469b3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -385,7 +385,7 @@ static int dpu_kms_global_obj_init(struct dpu_kms *dpu_kms) { struct dpu_global_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 9b7a8b46bfa9..547d084f2944 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -1684,7 +1684,7 @@ static void dpu_plane_reset(struct drm_plane *plane) plane->state = NULL; } - pstate = kzalloc(sizeof(*pstate), GFP_KERNEL); + pstate = kzalloc_obj(*pstate); if (!pstate) { DPU_ERROR_PLANE(pdpu, "failed to allocate state\n"); return; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 451a4fcf3e65..7e77d88f8959 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -350,26 +350,28 @@ static bool _dpu_rm_check_lm_and_get_connected_blks(struct dpu_rm *rm, return true; } -static bool dpu_rm_find_lms(struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t crtc_id, bool skip_dspp, - struct msm_display_topology *topology, - int *lm_idx, int *pp_idx, int *dspp_idx) +static int _dpu_rm_reserve_lms(struct dpu_rm *rm, + struct dpu_global_state *global_state, + uint32_t crtc_id, + struct msm_display_topology *topology) { + int lm_idx[MAX_BLOCKS]; + int pp_idx[MAX_BLOCKS]; + int dspp_idx[MAX_BLOCKS] = {0}; int i, lm_count = 0; + if (!topology->num_lm) { + DPU_ERROR("zero LMs in topology\n"); + return -EINVAL; + } + /* Find a primary mixer */ for (i = 0; i < ARRAY_SIZE(rm->mixer_blks) && lm_count < topology->num_lm; i++) { if (!rm->mixer_blks[i]) continue; - if (skip_dspp && to_dpu_hw_mixer(rm->mixer_blks[i])->cap->dspp) { - DPU_DEBUG("Skipping LM_%d, skipping LMs with DSPPs\n", i); - continue; - } - /* * Reset lm_count to an even index. This will drop the previous * primary mixer if failed to find its peer. @@ -408,38 +410,12 @@ static bool dpu_rm_find_lms(struct dpu_rm *rm, } } - return lm_count == topology->num_lm; -} - -static int _dpu_rm_reserve_lms(struct dpu_rm *rm, - struct dpu_global_state *global_state, - uint32_t crtc_id, - struct msm_display_topology *topology) - -{ - int lm_idx[MAX_BLOCKS]; - int pp_idx[MAX_BLOCKS]; - int dspp_idx[MAX_BLOCKS] = {0}; - int i; - bool found; - - if (!topology->num_lm) { - DPU_ERROR("zero LMs in topology\n"); - return -EINVAL; - } - - /* Try using non-DSPP LM blocks first */ - found = dpu_rm_find_lms(rm, global_state, crtc_id, !topology->num_dspp, - topology, lm_idx, pp_idx, dspp_idx); - if (!found && !topology->num_dspp) - found = dpu_rm_find_lms(rm, global_state, crtc_id, false, - topology, lm_idx, pp_idx, dspp_idx); - if (!found) { + if (lm_count != topology->num_lm) { DPU_DEBUG("unable to find appropriate mixers\n"); return -ENAVAIL; } - for (i = 0; i < topology->num_lm; i++) { + for (i = 0; i < lm_count; i++) { global_state->mixer_to_crtc_id[lm_idx[i]] = crtc_id; global_state->pingpong_to_crtc_id[pp_idx[i]] = crtc_id; global_state->dspp_to_crtc_id[dspp_idx[i]] = diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c index 373ae7d9bf01..b29541bc4843 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c @@ -1130,8 +1130,7 @@ static void mdp5_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state static void mdp5_crtc_reset(struct drm_crtc *crtc) { - struct mdp5_crtc_state *mdp5_cstate = - kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL); + struct mdp5_crtc_state *mdp5_cstate = kzalloc_obj(*mdp5_cstate); if (crtc->state) mdp5_crtc_destroy_state(crtc, crtc->state); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c index 61edf6864092..8bb503e0f962 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_kms.c @@ -133,7 +133,7 @@ static int mdp5_global_obj_init(struct mdp5_kms *mdp5_kms) { struct mdp5_global_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 4ca183fb61a9..c4624a49b32f 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -89,7 +89,7 @@ static void mdp5_plane_reset(struct drm_plane *plane) kfree(to_mdp5_plane_state(plane->state)); plane->state = NULL; - mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); + mdp5_state = kzalloc_obj(*mdp5_state); if (!mdp5_state) return; __drm_atomic_helper_plane_reset(plane, &mdp5_state->base); diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c index 2be00b11e557..d99771684728 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot.c @@ -36,7 +36,7 @@ msm_disp_snapshot_state_sync(struct msm_kms *kms) WARN_ON(!mutex_is_locked(&kms->dump_mutex)); - disp_state = kzalloc(sizeof(struct msm_disp_state), GFP_KERNEL); + disp_state = kzalloc_obj(struct msm_disp_state); if (!disp_state) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c index 19b470968f4d..427d3ee2b833 100644 --- a/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c +++ b/drivers/gpu/drm/msm/disp/msm_disp_snapshot_util.c @@ -172,7 +172,7 @@ void msm_disp_snapshot_add_block(struct msm_disp_state *disp_state, u32 len, struct va_format vaf; va_list va; - new_blk = kzalloc(sizeof(struct msm_disp_state_block), GFP_KERNEL); + new_blk = kzalloc_obj(struct msm_disp_state_block); if (!new_blk) return; diff --git a/drivers/gpu/drm/msm/dp/dp_ctrl.c b/drivers/gpu/drm/msm/dp/dp_ctrl.c index 5fc261191cb7..ef298c7d3e5e 100644 --- a/drivers/gpu/drm/msm/dp/dp_ctrl.c +++ b/drivers/gpu/drm/msm/dp/dp_ctrl.c @@ -921,7 +921,7 @@ static void _dp_ctrl_calc_tu(struct msm_dp_ctrl_private *ctrl, uint EXTRA_PIXCLK_CYCLE_DELAY = 4; uint HBLANK_MARGIN = 4; - tu = kzalloc(sizeof(*tu), GFP_KERNEL); + tu = kzalloc_obj(*tu); if (!tu) return; diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index e0de545d4077..db6da99375a1 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -584,13 +584,30 @@ void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host) * FIXME: Reconsider this if/when CMD mode handling is rewritten to use * transfer time and data overhead as a starting point of the calculations. */ -static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mode *mode, - const struct drm_dsc_config *dsc) +static unsigned long +dsi_adjust_pclk_for_compression(const struct drm_display_mode *mode, + const struct drm_dsc_config *dsc, + bool is_bonded_dsi) { - int new_hdisplay = DIV_ROUND_UP(mode->hdisplay * drm_dsc_get_bpp_int(dsc), - dsc->bits_per_component * 3); + int hdisplay, new_hdisplay, new_htotal; - int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; + /* + * For bonded DSI, split hdisplay across two links and round up each + * half separately, passing the full hdisplay would only round up once. + * This also aligns with the hdisplay we program later in + * dsi_timing_setup() + */ + hdisplay = mode->hdisplay; + if (is_bonded_dsi) + hdisplay /= 2; + + new_hdisplay = DIV_ROUND_UP(hdisplay * drm_dsc_get_bpp_int(dsc), + dsc->bits_per_component * 3); + + if (is_bonded_dsi) + new_hdisplay *= 2; + + new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal); } @@ -603,7 +620,7 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, pclk_rate = mode->clock * 1000u; if (dsc) - pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); + pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc, is_bonded_dsi); /* * For bonded DSI mode, the current DRM mode has the complete width of the @@ -993,7 +1010,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (msm_host->dsc) { struct drm_dsc_config *dsc = msm_host->dsc; - u32 bytes_per_pclk; + u32 bits_per_pclk; /* update dsc params with timing params */ if (!dsc || !mode->hdisplay || !mode->vdisplay) { @@ -1015,7 +1032,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) /* * DPU sends 3 bytes per pclk cycle to DSI. If widebus is - * enabled, bus width is extended to 6 bytes. + * enabled, MDP always sends out 48-bit compressed data per + * pclk and on average, DSI consumes an amount of compressed + * data equivalent to the uncompressed pixel depth per pclk. * * Calculate the number of pclks needed to transmit one line of * the compressed data. @@ -1027,12 +1046,12 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) * unused anyway. */ h_total -= hdisplay; - if (wide_bus_enabled && !(msm_host->mode_flags & MIPI_DSI_MODE_VIDEO)) - bytes_per_pclk = 6; + if (wide_bus_enabled) + bits_per_pclk = mipi_dsi_pixel_format_to_bpp(msm_host->format); else - bytes_per_pclk = 3; + bits_per_pclk = 24; - hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc), bytes_per_pclk); + hdisplay = DIV_ROUND_UP(msm_dsc_get_bytes_per_line(msm_host->dsc) * 8, bits_per_pclk); h_total += hdisplay; ha_end = ha_start + hdisplay; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 8cb0db3a9880..01182442dfd6 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -51,8 +51,8 @@ #define DSI_PHY_7NM_QUIRK_V4_3 BIT(3) /* Hardware is V5.2 */ #define DSI_PHY_7NM_QUIRK_V5_2 BIT(4) -/* Hardware is V7.0 */ -#define DSI_PHY_7NM_QUIRK_V7_0 BIT(5) +/* Hardware is V7.2 */ +#define DSI_PHY_7NM_QUIRK_V7_2 BIT(5) struct dsi_pll_config { bool enable_ssc; @@ -143,7 +143,7 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll, struct dsi_pll_config if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_PRE_V4_1) { config->pll_clock_inverters = 0x28; - } else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0)) { + } else if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) { if (pll_freq < 163000000ULL) config->pll_clock_inverters = 0xa0; else if (pll_freq < 175000000ULL) @@ -284,7 +284,7 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) } if ((pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) || - (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0)) { + (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) { if (pll->vco_current_rate < 1557000000ULL) vco_config_1 = 0x08; else @@ -699,7 +699,7 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) case MSM_DSI_PHY_MASTER: pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX]; /* v7.0: Enable ATB_EN0 and alternate clock output to external phy */ - if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0) + if (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2) writel(0x07, base + REG_DSI_7nm_PHY_CMN_CTRL_5); break; case MSM_DSI_PHY_SLAVE: @@ -987,7 +987,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, /* Request for REFGEN READY */ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) || (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) || - (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0)) { + (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) { writel(0x1, phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10); udelay(500); } @@ -1021,7 +1021,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, lane_ctrl0 = 0x1f; } - if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0)) { + if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) { if (phy->cphy_mode) { /* TODO: different for second phy */ vreg_ctrl_0 = 0x57; @@ -1097,7 +1097,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, /* program CMN_CTRL_4 for minor_ver 2 chipsets*/ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) || - (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0) || + (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2) || (readl(base + REG_DSI_7nm_PHY_CMN_REVISION_ID0) & (0xf0)) == 0x20) writel(0x04, base + REG_DSI_7nm_PHY_CMN_CTRL_4); @@ -1213,7 +1213,7 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) /* Turn off REFGEN Vote */ if ((phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_3) || (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V5_2) || - (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_0)) { + (phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V7_2)) { writel(0x0, base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE10); wmb(); /* Delay to ensure HW removes vote before PHY shut down */ @@ -1502,7 +1502,7 @@ const struct msm_dsi_phy_cfg dsi_phy_3nm_8750_cfgs = { #endif .io_start = { 0xae95000, 0xae97000 }, .num_dsi_phy = 2, - .quirks = DSI_PHY_7NM_QUIRK_V7_0, + .quirks = DSI_PHY_7NM_QUIRK_V7_2, }; const struct msm_dsi_phy_cfg dsi_phy_3nm_kaanapali_cfgs = { @@ -1525,5 +1525,5 @@ const struct msm_dsi_phy_cfg dsi_phy_3nm_kaanapali_cfgs = { #endif .io_start = { 0x9ac1000, 0x9ac4000 }, .num_dsi_phy = 2, - .quirks = DSI_PHY_7NM_QUIRK_V7_0, + .quirks = DSI_PHY_7NM_QUIRK_V7_2, }; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c index 0752fe373351..8fb5497aac9f 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_hdcp.c @@ -1400,7 +1400,7 @@ struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi) return ERR_PTR(-EINVAL); } - hdcp_ctrl = kzalloc(sizeof(*hdcp_ctrl), GFP_KERNEL); + hdcp_ctrl = kzalloc_obj(*hdcp_ctrl); if (!hdcp_ctrl) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c index ebefea4fb408..6b9265159195 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_i2c.c @@ -246,7 +246,7 @@ struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi) struct i2c_adapter *i2c = NULL; int ret; - hdmi_i2c = kzalloc(sizeof(*hdmi_i2c), GFP_KERNEL); + hdmi_i2c = kzalloc_obj(*hdmi_i2c); if (!hdmi_i2c) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/msm_debugfs.c b/drivers/gpu/drm/msm/msm_debugfs.c index 97dc70876442..1059a9b29d6a 100644 --- a/drivers/gpu/drm/msm/msm_debugfs.c +++ b/drivers/gpu/drm/msm/msm_debugfs.c @@ -76,7 +76,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file) if (!gpu || !gpu->funcs->gpu_state_get) return -ENODEV; - show_priv = kmalloc(sizeof(*show_priv), GFP_KERNEL); + show_priv = kmalloc_obj(*show_priv); if (!show_priv) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ed2a61c66ac9..e5ab1e28851d 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -247,7 +247,7 @@ static int context_init(struct drm_device *dev, struct drm_file *file) static atomic_t ident = ATOMIC_INIT(0); struct msm_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 1eff615ff9bf..b3fdb83202ab 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c @@ -194,7 +194,7 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, goto fail; } - msm_fb = kzalloc(sizeof(*msm_fb), GFP_KERNEL); + msm_fb = kzalloc_obj(*msm_fb); if (!msm_fb) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/msm_fence.c b/drivers/gpu/drm/msm/msm_fence.c index d41e5a6bbee0..3dca8e09c192 100644 --- a/drivers/gpu/drm/msm/msm_fence.c +++ b/drivers/gpu/drm/msm/msm_fence.c @@ -46,7 +46,7 @@ msm_fence_context_alloc(struct drm_device *dev, volatile uint32_t *fenceptr, struct msm_fence_context *fctx; static int index = 0; - fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); + fctx = kzalloc_obj(*fctx); if (!fctx) return ERR_PTR(-ENOMEM); @@ -176,7 +176,7 @@ msm_fence_alloc(void) { struct msm_fence *f; - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index da74f1413f94..b27abaa13926 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -1215,7 +1215,7 @@ static int msm_gem_new_impl(struct drm_device *dev, uint32_t flags, return -EINVAL; } - msm_obj = kzalloc(sizeof(*msm_obj), GFP_KERNEL); + msm_obj = kzalloc_obj(*msm_obj); if (!msm_obj) return -ENOMEM; @@ -1301,7 +1301,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, msm_obj = to_msm_bo(obj); msm_gem_lock(obj); msm_obj->sgt = sgt; - msm_obj->pages = kvmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + msm_obj->pages = kvmalloc_objs(struct page *, npages); if (!msm_obj->pages) { msm_gem_unlock(obj); ret = -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 5fd58d910620..adf88cf8f41a 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -375,7 +375,7 @@ msm_gem_vma_new(struct drm_gpuvm *gpuvm, struct drm_gem_object *obj, drm_gpuvm_resv_assert_held(&vm->base); - vma = kzalloc(sizeof(*vma), GFP_KERNEL); + vma = kzalloc_obj(*vma); if (!vma) return ERR_PTR(-ENOMEM); @@ -465,7 +465,7 @@ struct op_arg { static int vm_op_enqueue(struct op_arg *arg, struct msm_vm_op _op) { - struct msm_vm_op *op = kmalloc(sizeof(*op), GFP_KERNEL); + struct msm_vm_op *op = kmalloc_obj(*op); if (!op) return -ENOMEM; @@ -819,7 +819,7 @@ msm_gem_vm_create(struct drm_device *drm, struct msm_mmu *mmu, const char *name, if (IS_ERR(mmu)) return ERR_CAST(mmu); - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = kzalloc_obj(*vm); if (!vm) return ERR_PTR(-ENOMEM); @@ -869,8 +869,8 @@ msm_gem_vm_create(struct drm_device *drm, struct msm_mmu *mmu, const char *name, vm->log_shift = MIN(vm_log_shift, 8); if (vm->log_shift) { - vm->log = kmalloc_array(1 << vm->log_shift, sizeof(vm->log[0]), - GFP_KERNEL | __GFP_ZERO); + vm->log = kmalloc_objs(vm->log[0], 1 << vm->log_shift, + GFP_KERNEL | __GFP_ZERO); } return &vm->base; @@ -952,7 +952,7 @@ vm_bind_job_create(struct drm_device *dev, struct drm_file *file, struct msm_vm_bind_job *job; int ret; - job = kzalloc(struct_size(job, ops, nr_ops), GFP_KERNEL | __GFP_NOWARN); + job = kzalloc_flex(*job, ops, nr_ops, GFP_KERNEL | __GFP_NOWARN); if (!job) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 995549d0bbbc..84d6c7f50c8d 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -346,8 +346,7 @@ static void crashstate_get_vm_logs(struct msm_gpu_state *state, struct msm_gem_v state->nr_vm_logs = vm_log_len; } - state->vm_logs = kmalloc_array( - state->nr_vm_logs, sizeof(vm->log[0]), GFP_KERNEL); + state->vm_logs = kmalloc_objs(vm->log[0], state->nr_vm_logs); if (!state->vm_logs) { state->nr_vm_logs = 0; } diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index d5dede4ff761..7d449e5202c5 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -332,7 +332,7 @@ msm_iommu_pagetable_prealloc_allocate(struct msm_mmu *mmu, struct msm_mmu_preall struct kmem_cache *pt_cache = get_pt_cache(mmu); int ret; - p->pages = kvmalloc_array(p->count, sizeof(p->pages), GFP_KERNEL); + p->pages = kvmalloc_objs(*p->pages, p->count); if (!p->pages) return -ENOMEM; @@ -521,7 +521,7 @@ struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent, bool kernel_m if (WARN_ONCE(!ttbr1_cfg, "No per-process page tables")) return ERR_PTR(-ENODEV); - pagetable = kzalloc(sizeof(*pagetable), GFP_KERNEL); + pagetable = kzalloc_obj(*pagetable); if (!pagetable) return ERR_PTR(-ENOMEM); @@ -734,7 +734,7 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks) iommu_set_pgtable_quirks(domain, quirks); - iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + iommu = kzalloc_obj(*iommu); if (!iommu) { iommu_domain_free(domain); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/msm_kms.c b/drivers/gpu/drm/msm/msm_kms.c index 6e5e94f5c9a7..e5d0ea629448 100644 --- a/drivers/gpu/drm/msm/msm_kms.c +++ b/drivers/gpu/drm/msm/msm_kms.c @@ -128,7 +128,7 @@ static int vblank_ctrl_queue_work(struct msm_drm_private *priv, { struct msm_vblank_work *vbl_work; - vbl_work = kzalloc(sizeof(*vbl_work), GFP_ATOMIC); + vbl_work = kzalloc_obj(*vbl_work, GFP_ATOMIC); if (!vbl_work) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_perf.c b/drivers/gpu/drm/msm/msm_perf.c index c369d4acc378..7768bde6745f 100644 --- a/drivers/gpu/drm/msm/msm_perf.c +++ b/drivers/gpu/drm/msm/msm_perf.c @@ -204,7 +204,7 @@ int msm_perf_debugfs_init(struct drm_minor *minor) if (priv->perf) return 0; - perf = kzalloc(sizeof(*perf), GFP_KERNEL); + perf = kzalloc_obj(*perf); if (!perf) return -ENOMEM; diff --git a/drivers/gpu/drm/msm/msm_rd.c b/drivers/gpu/drm/msm/msm_rd.c index 54493a94dcb7..8fab0b4ed8f4 100644 --- a/drivers/gpu/drm/msm/msm_rd.c +++ b/drivers/gpu/drm/msm/msm_rd.c @@ -245,7 +245,7 @@ static struct msm_rd_state *rd_init(struct drm_minor *minor, const char *name) { struct msm_rd_state *rd; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/msm/msm_ringbuffer.c b/drivers/gpu/drm/msm/msm_ringbuffer.c index b2f612e5dc79..30ddb5351e98 100644 --- a/drivers/gpu/drm/msm/msm_ringbuffer.c +++ b/drivers/gpu/drm/msm/msm_ringbuffer.c @@ -79,7 +79,7 @@ struct msm_ringbuffer *msm_ringbuffer_new(struct msm_gpu *gpu, int id, /* We assume everywhere that MSM_GPU_RINGBUFFER_SZ is a power of 2 */ BUILD_BUG_ON(!is_power_of_2(MSM_GPU_RINGBUFFER_SZ)); - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index d53dfad16bde..2598d674a99d 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -151,7 +151,7 @@ get_sched_entity(struct msm_context *ctx, struct msm_ringbuffer *ring, struct drm_gpu_scheduler *sched = &ring->sched; int ret; - entity = kzalloc(sizeof(*ctx->entities[idx]), GFP_KERNEL); + entity = kzalloc_obj(*ctx->entities[idx]); ret = drm_sched_entity_init(entity, sched_prio, &sched, 1, NULL); if (ret) { @@ -207,7 +207,7 @@ int msm_submitqueue_create(struct drm_device *drm, struct msm_context *ctx, if (ret) return ret; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); } if (!queue) diff --git a/drivers/gpu/drm/msm/msm_syncobj.c b/drivers/gpu/drm/msm/msm_syncobj.c index 4baa9f522c54..c67aaf6f7105 100644 --- a/drivers/gpu/drm/msm/msm_syncobj.c +++ b/drivers/gpu/drm/msm/msm_syncobj.c @@ -19,8 +19,8 @@ msm_syncobj_parse_deps(struct drm_device *dev, int ret = 0; uint32_t i, j; - syncobjs = kcalloc(nr_in_syncobjs, sizeof(*syncobjs), - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); + syncobjs = kzalloc_objs(*syncobjs, nr_in_syncobjs, + GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); if (!syncobjs) return ERR_PTR(-ENOMEM); @@ -94,8 +94,8 @@ msm_syncobj_parse_post_deps(struct drm_device *dev, int ret = 0; uint32_t i, j; - post_deps = kcalloc(nr_syncobjs, sizeof(*post_deps), - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); + post_deps = kzalloc_objs(*post_deps, nr_syncobjs, + GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY); if (!post_deps) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/mxsfb/lcdif_kms.c b/drivers/gpu/drm/mxsfb/lcdif_kms.c index 72eb0de46b54..ef3250a5c54f 100644 --- a/drivers/gpu/drm/mxsfb/lcdif_kms.c +++ b/drivers/gpu/drm/mxsfb/lcdif_kms.c @@ -595,7 +595,7 @@ static void lcdif_crtc_reset(struct drm_crtc *crtc) crtc->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -609,7 +609,7 @@ lcdif_crtc_atomic_duplicate_state(struct drm_crtc *crtc) if (WARN_ON(!crtc->state)) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 80493224eb6c..500fd77b87d1 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1158,7 +1158,7 @@ nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, cli = chan->cli; push = &chan->chan.push; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; @@ -1291,7 +1291,7 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) struct drm_plane *primary; int ret; - nv_crtc = kzalloc(sizeof(*nv_crtc), GFP_KERNEL); + nv_crtc = kzalloc_obj(*nv_crtc); if (!nv_crtc) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c index 2e12bf136607..22f903258f96 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dac.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c @@ -532,7 +532,7 @@ nv04_dac_create(struct drm_connector *connector, struct dcb_output *entry) struct drm_device *dev = connector->dev; struct drm_encoder *encoder; - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); + nv_encoder = kzalloc_obj(*nv_encoder); if (!nv_encoder) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index c724bacc67f8..c9f96ec8455d 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -697,7 +697,7 @@ nv04_dfp_create(struct drm_connector *connector, struct dcb_output *entry) return -EINVAL; } - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); + nv_encoder = kzalloc_obj(*nv_encoder); if (!nv_encoder) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/i2c/ch7006_drv.c b/drivers/gpu/drm/nouveau/dispnv04/i2c/ch7006_drv.c index fd2150e07e36..976ed59a86e4 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/nouveau/dispnv04/i2c/ch7006_drv.c @@ -444,7 +444,7 @@ static int ch7006_encoder_init(struct i2c_client *client, ch7006_dbg(client, "\n"); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/i2c/sil164_drv.c b/drivers/gpu/drm/nouveau/dispnv04/i2c/sil164_drv.c index 54ea8459332d..7f402b901977 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/i2c/sil164_drv.c +++ b/drivers/gpu/drm/nouveau/dispnv04/i2c/sil164_drv.c @@ -399,7 +399,7 @@ sil164_encoder_init(struct i2c_client *client, struct sil164_priv *priv; struct i2c_client *slave_client; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index 33f29736024a..214d511be880 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -279,7 +279,7 @@ static void nv10_overlay_init(struct drm_device *device) { struct nouveau_drm *drm = nouveau_drm(device); - struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL); + struct nouveau_plane *plane = kzalloc_obj(struct nouveau_plane); unsigned int num_formats = ARRAY_SIZE(formats); int ret; @@ -470,7 +470,7 @@ static void nv04_overlay_init(struct drm_device *device) { struct nouveau_drm *drm = nouveau_drm(device); - struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL); + struct nouveau_plane *plane = kzalloc_obj(struct nouveau_plane); int ret; if (!plane) diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index c61ab083f62e..9e1d4b353680 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -215,7 +215,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry) return type; /* Allocate the necessary memory */ - nv_encoder = kzalloc(sizeof(*nv_encoder), GFP_KERNEL); + nv_encoder = kzalloc_obj(*nv_encoder); if (!nv_encoder) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c index 06de05fe5db6..2721a2e0c885 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.c @@ -797,7 +797,7 @@ nv17_tv_create(struct drm_connector *connector, struct dcb_output *entry) struct drm_encoder *encoder; struct nv17_tv_encoder *tv_enc = NULL; - tv_enc = kzalloc(sizeof(*tv_enc), GFP_KERNEL); + tv_enc = kzalloc_obj(*tv_enc); if (!tv_enc) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/dispnv50/core507d.c b/drivers/gpu/drm/nouveau/dispnv50/core507d.c index 4b947b67a844..46c945480522 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/core507d.c +++ b/drivers/gpu/drm/nouveau/dispnv50/core507d.c @@ -162,7 +162,7 @@ core507d_new_(const struct nv50_core_func *func, struct nouveau_drm *drm, struct nv50_core *core; int ret; - if (!(core = *pcore = kzalloc(sizeof(*core), GFP_KERNEL))) + if (!(core = *pcore = kzalloc_obj(*core))) return -ENOMEM; core->func = func; core->disp = disp; diff --git a/drivers/gpu/drm/nouveau/dispnv50/disp.c b/drivers/gpu/drm/nouveau/dispnv50/disp.c index 12b1dba8e05d..6c3a8712d38a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv50/disp.c @@ -1115,7 +1115,7 @@ nv50_msto_new(struct drm_device *dev, struct nv50_head *head, int id) struct nv50_msto *msto; int ret; - msto = kzalloc(sizeof(*msto), GFP_KERNEL); + msto = kzalloc_obj(*msto); if (!msto) return ERR_PTR(-ENOMEM); @@ -1267,7 +1267,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port, struct nv50_mstc *mstc; int ret; - if (!(mstc = *pmstc = kzalloc(sizeof(*mstc), GFP_KERNEL))) + if (!(mstc = *pmstc = kzalloc_obj(*mstc))) return -ENOMEM; mstc->mstm = mstm; mstc->port = port; @@ -1520,7 +1520,7 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, struct nv50_mstm *mstm; int ret; - if (!(mstm = *pmstm = kzalloc(sizeof(*mstm), GFP_KERNEL))) + if (!(mstm = *pmstm = kzalloc_obj(*mstm))) return -ENOMEM; mstm->outp = outp; mstm->mgr.cbs = &nv50_mstm; @@ -2496,7 +2496,7 @@ nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder) return outp; } - outp = kzalloc(sizeof(*outp), GFP_KERNEL); + outp = kzalloc_obj(*outp); if (!outp) return ERR_PTR(-ENOMEM); @@ -2643,7 +2643,7 @@ static struct drm_atomic_state * nv50_disp_atomic_state_alloc(struct drm_device *dev) { struct nv50_atom *atom; - if (!(atom = kzalloc(sizeof(*atom), GFP_KERNEL)) || + if (!(atom = kzalloc_obj(*atom)) || drm_atomic_state_init(dev, &atom->state) < 0) { kfree(atom); return NULL; @@ -2833,7 +2833,7 @@ nv50_display_create(struct drm_device *dev) int ret, i; bool has_mst = false; - disp = kzalloc(sizeof(*disp), GFP_KERNEL); + disp = kzalloc_obj(*disp); if (!disp) return -ENOMEM; @@ -2900,7 +2900,7 @@ nv50_display_create(struct drm_device *dev) for_each_set_bit(i, &disp->disp->outp_mask, sizeof(disp->disp->outp_mask) * 8) { struct nouveau_encoder *outp; - outp = kzalloc(sizeof(*outp), GFP_KERNEL); + outp = kzalloc_obj(*outp); if (!outp) break; @@ -2921,7 +2921,7 @@ nv50_display_create(struct drm_device *dev) outp->base.base.possible_clones = 0; outp->conn = nouveau_connector(connector); - outp->dcb = kzalloc(sizeof(*outp->dcb), GFP_KERNEL); + outp->dcb = kzalloc_obj(*outp->dcb); if (!outp->dcb) break; diff --git a/drivers/gpu/drm/nouveau/dispnv50/head.c b/drivers/gpu/drm/nouveau/dispnv50/head.c index e32ed1db6c56..4ca7700fb784 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/head.c +++ b/drivers/gpu/drm/nouveau/dispnv50/head.c @@ -470,7 +470,7 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) { struct nv50_head_atom *armh = nv50_head_atom(crtc->state); struct nv50_head_atom *asyh; - if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL))) + if (!(asyh = kmalloc_obj(*asyh))) return NULL; __drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state); asyh->wndw = armh->wndw; @@ -496,7 +496,7 @@ nv50_head_reset(struct drm_crtc *crtc) { struct nv50_head_atom *asyh; - if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL)))) + if (WARN_ON(!(asyh = kzalloc_obj(*asyh)))) return; if (crtc->state) @@ -577,7 +577,7 @@ nv50_head_create(struct drm_device *dev, int index) const struct drm_crtc_funcs *funcs; int ret; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (!head) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/nouveau/dispnv50/lut.c b/drivers/gpu/drm/nouveau/dispnv50/lut.c index 6b2ad1e6eab9..d9db2486ef6e 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/lut.c +++ b/drivers/gpu/drm/nouveau/dispnv50/lut.c @@ -38,7 +38,7 @@ nv50_lut_load(struct nv50_lut *lut, int buffer, struct drm_property_blob *blob, int i; if (!in) { - in = kvmalloc_array(1024, sizeof(*in), GFP_KERNEL); + in = kvmalloc_objs(*in, 1024); if (!WARN_ON(!in)) { for (i = 0; i < 1024; i++) { in[i].red = diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.c b/drivers/gpu/drm/nouveau/dispnv50/wndw.c index 9a2c20fce0f3..9ad4973716f7 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.c @@ -80,7 +80,7 @@ nv50_wndw_ctxdma_new(struct nv50_wndw *wndw, struct drm_framebuffer *fb) return ctxdma; } - if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) + if (!(ctxdma = kzalloc_obj(*ctxdma))) return ERR_PTR(-ENOMEM); list_add(&ctxdma->head, &wndw->ctxdma.list); @@ -730,7 +730,7 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) { struct nv50_wndw_atom *armw = nv50_wndw_atom(plane->state); struct nv50_wndw_atom *asyw; - if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL))) + if (!(asyw = kmalloc_obj(*asyw))) return NULL; __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); asyw->sema = armw->sema; @@ -757,7 +757,7 @@ nv50_wndw_reset(struct drm_plane *plane) { struct nv50_wndw_atom *asyw; - if (WARN_ON(!(asyw = kzalloc(sizeof(*asyw), GFP_KERNEL)))) + if (WARN_ON(!(asyw = kzalloc_obj(*asyw)))) return; if (plane->state) @@ -863,7 +863,7 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev, int nformat; int ret; - if (!(wndw = *pwndw = kzalloc(sizeof(*wndw), GFP_KERNEL))) + if (!(wndw = *pwndw = kzalloc_obj(*wndw))) return -ENOMEM; wndw->func = func; wndw->id = index; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index a3ba07fc48a0..f9201f2e73a3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -44,7 +44,7 @@ nouveau_abi16(struct drm_file *file_priv) struct nouveau_cli *cli = nouveau_cli(file_priv); if (!cli->abi16) { struct nouveau_abi16 *abi16; - cli->abi16 = abi16 = kzalloc(sizeof(*abi16), GFP_KERNEL); + cli->abi16 = abi16 = kzalloc_obj(*abi16); if (cli->abi16) { abi16->cli = cli; INIT_LIST_HEAD(&abi16->channels); @@ -124,7 +124,7 @@ nouveau_abi16_obj_new(struct nouveau_abi16 *abi16, enum nouveau_abi16_obj_type t if (obj) return ERR_PTR(-EEXIST); - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); @@ -397,7 +397,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, -EINVAL); /* allocate "abi16 channel" data and make up a handle for it */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return nouveau_abi16_put(abi16, -ENOMEM); @@ -597,7 +597,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) if (!oclass) return nouveau_abi16_put(abi16, -EINVAL); - ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL); + ntfy = kzalloc_obj(*ntfy); if (!ntfy) return nouveau_abi16_put(abi16, -ENOMEM); @@ -635,7 +635,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) if (!chan) return nouveau_abi16_put(abi16, -ENOENT); - ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL); + ntfy = kzalloc_obj(*ntfy); if (!ntfy) return nouveau_abi16_put(abi16, -ENOMEM); diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 4a75d146a171..da1ee24a2531 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -314,7 +314,7 @@ nouveau_backlight_init(struct drm_connector *connector) if (!nv_encoder) return 0; - bl = kzalloc(sizeof(*bl), GFP_KERNEL); + bl = kzalloc_obj(*bl); if (!bl) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f26562eafffc..3c7d2e5b3850 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -222,7 +222,7 @@ nouveau_bo_alloc(struct nouveau_cli *cli, u64 *size, int *align, u32 domain, return ERR_PTR(-EINVAL); } - nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); + nvbo = kzalloc_obj(struct nouveau_bo); if (!nvbo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index b1e92b1f7a26..598513f60449 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -149,7 +149,7 @@ nouveau_channel_prep(struct nouveau_cli *cli, u32 target; int ret; - chan = *pchan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = *pchan = kzalloc_obj(*chan); if (!chan) return -ENOMEM; @@ -545,7 +545,7 @@ nouveau_channels_init(struct nouveau_drm *drm) drm->chan_nr = drm->chan_total = channels->data; drm->runl_nr = fls64(runlists->data); - drm->runl = kcalloc(drm->runl_nr, sizeof(*drm->runl), GFP_KERNEL); + drm->runl = kzalloc_objs(*drm->runl, drm->runl_nr); if (!drm->runl) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 63621b1510f6..cc239492c7f0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -232,7 +232,7 @@ nouveau_conn_atomic_duplicate_state(struct drm_connector *connector) { struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); struct nouveau_conn_atom *asyc; - if (!(asyc = kmalloc(sizeof(*asyc), GFP_KERNEL))) + if (!(asyc = kmalloc_obj(*asyc))) return NULL; __drm_atomic_helper_connector_duplicate_state(connector, &asyc->state); asyc->dither = armc->dither; @@ -249,7 +249,7 @@ nouveau_conn_reset(struct drm_connector *connector) struct nouveau_conn_atom *asyc; if (drm_drv_uses_atomic_modeset(connector->dev)) { - if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) + if (WARN_ON(!(asyc = kzalloc_obj(*asyc)))) return; if (connector->state) @@ -1230,6 +1230,9 @@ nouveau_connector_aux_xfer(struct drm_dp_aux *obj, struct drm_dp_aux_msg *msg) u8 size = msg->size; int ret; + if (pm_runtime_suspended(nv_connector->base.dev->dev)) + return -EBUSY; + nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP); if (!nv_encoder) return -ENODEV; @@ -1298,7 +1301,7 @@ nouveau_connector_create(struct drm_device *dev, int index) } drm_connector_list_iter_end(&conn_iter); - nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); + nv_connector = kzalloc_obj(*nv_connector); if (!nv_connector) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index c7869a639bef..47d5579c568d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c @@ -295,7 +295,7 @@ nouveau_drm_debugfs_init(struct drm_minor *minor) int nouveau_debugfs_init(struct nouveau_drm *drm) { - drm->debugfs = kzalloc(sizeof(*drm->debugfs), GFP_KERNEL); + drm->debugfs = kzalloc_obj(*drm->debugfs); if (!drm->debugfs) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 00515623a2cc..d71dcfc6ee66 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -316,7 +316,7 @@ nouveau_framebuffer_new(struct drm_device *dev, } } - if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL))) + if (!(fb = *pfb = kzalloc_obj(*fb))) return -ENOMEM; drm_helper_mode_fill_fb_struct(dev, fb, info, mode_cmd); @@ -646,7 +646,7 @@ nouveau_display_create(struct drm_device *dev) struct nouveau_display *disp; int ret; - disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL); + disp = drm->display = kzalloc_obj(*disp); if (!disp) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_dmem.c b/drivers/gpu/drm/nouveau/nouveau_dmem.c index 3d8031296eed..9442ec6e1f6c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dmem.c +++ b/drivers/gpu/drm/nouveau/nouveau_dmem.c @@ -303,7 +303,7 @@ nouveau_dmem_chunk_alloc(struct nouveau_drm *drm, struct page **ppage, unsigned long i, pfn_first, pfn; int ret; - chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); + chunk = kzalloc_obj(*chunk); if (chunk == NULL) { ret = -ENOMEM; goto out; @@ -481,7 +481,7 @@ nouveau_dmem_evict_chunk(struct nouveau_dmem_chunk *chunk) src_pfns = kvcalloc(npages, sizeof(*src_pfns), GFP_KERNEL | __GFP_NOFAIL); dst_pfns = kvcalloc(npages, sizeof(*dst_pfns), GFP_KERNEL | __GFP_NOFAIL); - dma_info = kvcalloc(npages, sizeof(*dma_info), GFP_KERNEL | __GFP_NOFAIL); + dma_info = kvzalloc_objs(*dma_info, npages, GFP_KERNEL | __GFP_NOFAIL); migrate_device_range(src_pfns, chunk->pagemap.range.start >> PAGE_SHIFT, npages); @@ -707,7 +707,7 @@ nouveau_dmem_init(struct nouveau_drm *drm) if (drm->client.device.info.family < NV_DEVICE_INFO_V0_PASCAL) return; - if (!(drm->dmem = kzalloc(sizeof(*drm->dmem), GFP_KERNEL))) + if (!(drm->dmem = kzalloc_obj(*drm->dmem))) return; drm->dmem->drm = drm; @@ -855,7 +855,7 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm, if (!args.dst) goto out_free_src; - dma_info = kmalloc_array(max, sizeof(*dma_info), GFP_KERNEL); + dma_info = kmalloc_objs(*dma_info, max); if (!dma_info) goto out_free_dst; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index dc469e571c0a..915f73279302 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -739,7 +739,7 @@ nouveau_drm_device_new(const struct drm_driver *drm_driver, struct device *paren struct nouveau_drm *drm; int ret; - drm = kzalloc(sizeof(*drm), GFP_KERNEL); + drm = kzalloc_obj(*drm); if (!drm) return ERR_PTR(-ENOMEM); @@ -1203,7 +1203,7 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv) current->comm, pid_nr(rcu_dereference(fpriv->pid))); rcu_read_unlock(); - if (!(cli = kzalloc(sizeof(*cli), GFP_KERNEL))) { + if (!(cli = kzalloc_obj(*cli))) { ret = -ENOMEM; goto done; } diff --git a/drivers/gpu/drm/nouveau/nouveau_exec.c b/drivers/gpu/drm/nouveau/nouveau_exec.c index c4949e815eb3..c01a01aee32b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_exec.c +++ b/drivers/gpu/drm/nouveau/nouveau_exec.c @@ -219,7 +219,7 @@ nouveau_exec_job_init(struct nouveau_exec_job **pjob, } } - job = *pjob = kzalloc(sizeof(*job), GFP_KERNEL); + job = *pjob = kzalloc_obj(*job); if (!job) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 4a193b7d6d9e..903d326927ca 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -408,7 +408,7 @@ nouveau_fence_create(struct nouveau_fence **pfence, if (unlikely(!chan->fence)) return -ENODEV; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 395d92ab6271..82621ede42e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -168,7 +168,7 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) return; } - if (!(work = kmalloc(sizeof(*work), GFP_KERNEL))) { + if (!(work = kmalloc_obj(*work))) { WARN_ON(dma_fence_wait_timeout(fence, false, 2 * HZ) <= 0); nouveau_gem_object_delete(vma); return; diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_hwmon.c index 34effe6d86ad..726397ab035d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_hwmon.c @@ -678,7 +678,7 @@ nouveau_hwmon_init(struct drm_device *dev) return 0; } - hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); + hwmon = drm->hwmon = kzalloc_obj(*hwmon); if (!hwmon) return -ENOMEM; hwmon->dev = dev; diff --git a/drivers/gpu/drm/nouveau/nouveau_led.c b/drivers/gpu/drm/nouveau/nouveau_led.c index ac950518a820..19e2110904d1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_led.c +++ b/drivers/gpu/drm/nouveau/nouveau_led.c @@ -89,7 +89,7 @@ nouveau_led_init(struct drm_device *dev) if (nvkm_gpio_find(gpio, 0, DCB_GPIO_LOGO_LED_PWM, 0xff, &logo_led)) return 0; - drm->led = kzalloc(sizeof(*drm->led), GFP_KERNEL); + drm->led = kzalloc_obj(*drm->led); if (!drm->led) return -ENOMEM; drm->led->dev = dev; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index fac92fdbf9cc..b26c521166f1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -176,7 +176,7 @@ nouveau_mem_new(struct nouveau_drm *drm, u8 kind, u8 comp, { struct nouveau_mem *mem; - if (!(mem = kzalloc(sizeof(*mem), GFP_KERNEL))) + if (!(mem = kzalloc_obj(*mem))) return -ENOMEM; mem->drm = drm; diff --git a/drivers/gpu/drm/nouveau/nouveau_sched.c b/drivers/gpu/drm/nouveau/nouveau_sched.c index a7bf539e5d86..5546be488795 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sched.c +++ b/drivers/gpu/drm/nouveau/nouveau_sched.c @@ -69,17 +69,15 @@ nouveau_job_init(struct nouveau_job *job, goto err_free_in_sync; } - job->out_sync.objs = kcalloc(job->out_sync.count, - sizeof(*job->out_sync.objs), - GFP_KERNEL); + job->out_sync.objs = kzalloc_objs(*job->out_sync.objs, + job->out_sync.count); if (!job->out_sync.objs) { ret = -ENOMEM; goto err_free_out_sync; } - job->out_sync.chains = kcalloc(job->out_sync.count, - sizeof(*job->out_sync.chains), - GFP_KERNEL); + job->out_sync.chains = kzalloc_objs(*job->out_sync.chains, + job->out_sync.count); if (!job->out_sync.chains) { ret = -ENOMEM; goto err_free_objs; @@ -467,7 +465,7 @@ nouveau_sched_create(struct nouveau_sched **psched, struct nouveau_drm *drm, struct nouveau_sched *sched; int ret; - sched = kzalloc(sizeof(*sched), GFP_KERNEL); + sched = kzalloc_obj(*sched); if (!sched) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index bd870028514b..fa3b4ebf38a8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -79,7 +79,7 @@ nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo, uint32_t page_flags) else caching = ttm_cached; - nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL); + nvbe = kzalloc_obj(*nvbe); if (!nvbe) return NULL; diff --git a/drivers/gpu/drm/nouveau/nouveau_svm.c b/drivers/gpu/drm/nouveau/nouveau_svm.c index b8a3378154d5..dcc92131488e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_svm.c +++ b/drivers/gpu/drm/nouveau/nouveau_svm.c @@ -223,7 +223,7 @@ nouveau_svmm_join(struct nouveau_svmm *svmm, u64 inst) { struct nouveau_ivmm *ivmm; if (svmm) { - if (!(ivmm = kmalloc(sizeof(*ivmm), GFP_KERNEL))) + if (!(ivmm = kmalloc_obj(*ivmm))) return -ENOMEM; ivmm->svmm = svmm; ivmm->inst = inst; @@ -326,7 +326,7 @@ nouveau_svmm_init(struct drm_device *dev, void *data, return -ENOSYS; /* Allocate tracking for SVM-enabled VMM. */ - if (!(svmm = kzalloc(sizeof(*svmm), GFP_KERNEL))) + if (!(svmm = kzalloc_obj(*svmm))) return -ENOMEM; svmm->vmm = &cli->svm; svmm->unmanaged.start = args->unmanaged_addr; @@ -475,7 +475,7 @@ nouveau_svm_fault_cache(struct nouveau_svm *svm, nvif_mask(memory, offset + 0x1c, 0x80000000, 0x00000000); if (!buffer->fault[buffer->fault_nr]) { - fault = kmalloc(sizeof(*fault), GFP_KERNEL); + fault = kmalloc_obj(*fault); if (WARN_ON(!fault)) { nouveau_svm_fault_cancel(svm, inst, hub, gpc, client); return; @@ -900,7 +900,7 @@ nouveau_pfns_alloc(unsigned long npages) { struct nouveau_pfnmap_args *args; - args = kzalloc(struct_size(args, p.phys, npages), GFP_KERNEL); + args = kzalloc_flex(*args, p.phys, npages); if (!args) return NULL; @@ -1010,7 +1010,7 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id) if (ret) return ret; - buffer->fault = kvcalloc(buffer->entries, sizeof(*buffer->fault), GFP_KERNEL); + buffer->fault = kvzalloc_objs(*buffer->fault, buffer->entries); if (!buffer->fault) return -ENOMEM; @@ -1062,7 +1062,7 @@ nouveau_svm_init(struct nouveau_drm *drm) if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL) return; - drm->svm = svm = kzalloc(struct_size(drm->svm, buffer, 1), GFP_KERNEL); + drm->svm = svm = kzalloc_flex(*drm->svm, buffer, 1); if (!drm->svm) return; diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c index 0a55babdf667..ad01f922aa86 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ttm.c +++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c @@ -181,7 +181,7 @@ static int nouveau_ttm_init_vram(struct nouveau_drm *drm) { if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) { - struct ttm_resource_manager *man = kzalloc(sizeof(*man), GFP_KERNEL); + struct ttm_resource_manager *man = kzalloc_obj(*man); if (!man) return -ENOMEM; @@ -229,7 +229,7 @@ nouveau_ttm_init_gtt(struct nouveau_drm *drm) return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT, true, size_pages); - man = kzalloc(sizeof(*man), GFP_KERNEL); + man = kzalloc_obj(*man); if (!man) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_uvmm.c b/drivers/gpu/drm/nouveau/nouveau_uvmm.c index 0d693760d222..36445915aa58 100644 --- a/drivers/gpu/drm/nouveau/nouveau_uvmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_uvmm.c @@ -218,7 +218,7 @@ nouveau_uvma_unmap(struct nouveau_uvma *uvma) static int nouveau_uvma_alloc(struct nouveau_uvma **puvma) { - *puvma = kzalloc(sizeof(**puvma), GFP_KERNEL); + *puvma = kzalloc_obj(**puvma); if (!*puvma) return -ENOMEM; @@ -246,7 +246,7 @@ nouveau_uvma_gem_put(struct nouveau_uvma *uvma) static int nouveau_uvma_region_alloc(struct nouveau_uvma_region **preg) { - *preg = kzalloc(sizeof(**preg), GFP_KERNEL); + *preg = kzalloc_obj(**preg); if (!*preg) return -ENOMEM; @@ -1020,7 +1020,7 @@ nouveau_uvmm_validate_range(struct nouveau_uvmm *uvmm, u64 addr, u64 range) static int nouveau_uvmm_bind_job_alloc(struct nouveau_uvmm_bind_job **pjob) { - *pjob = kzalloc(sizeof(**pjob), GFP_KERNEL); + *pjob = kzalloc_obj(**pjob); if (!*pjob) return -ENOMEM; @@ -1618,7 +1618,7 @@ bind_job_op_from_uop(struct bind_job_op **pop, { struct bind_job_op *op; - op = *pop = kzalloc(sizeof(*op), GFP_KERNEL); + op = *pop = kzalloc_obj(*op); if (!op) return -ENOMEM; @@ -1911,7 +1911,7 @@ nouveau_uvmm_ioctl_vm_init(struct drm_device *dev, goto out_unlock; } - uvmm = kzalloc(sizeof(*uvmm), GFP_KERNEL); + uvmm = kzalloc_obj(*uvmm); if (!uvmm) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/gpu/drm/nouveau/nouveau_vmm.c b/drivers/gpu/drm/nouveau/nouveau_vmm.c index 3dda885df5b2..5812f27bfecf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vmm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vmm.c @@ -87,7 +87,7 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, return 0; } - if (!(vma = *pvma = kmalloc(sizeof(*vma), GFP_KERNEL))) + if (!(vma = *pvma = kmalloc_obj(*vma))) return -ENOMEM; vma->vmm = vmm; vma->refs = 1; diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c index fa5c6029f783..a640430944ee 100644 --- a/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/drivers/gpu/drm/nouveau/nv04_fence.c @@ -76,7 +76,7 @@ nv04_fence_context_del(struct nouveau_channel *chan) static int nv04_fence_context_new(struct nouveau_channel *chan) { - struct nv04_fence_chan *fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); + struct nv04_fence_chan *fctx = kzalloc_obj(*fctx); if (fctx) { nouveau_fence_context_new(chan, &fctx->base); fctx->base.emit = nv04_fence_emit; @@ -101,7 +101,7 @@ nv04_fence_create(struct nouveau_drm *drm) { struct nv04_fence_priv *priv; - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = drm->fence = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 40ee95340814..6e88050f41fb 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -70,7 +70,7 @@ nv10_fence_context_new(struct nouveau_channel *chan) { struct nv10_fence_chan *fctx; - fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); + fctx = chan->fence = kzalloc_obj(*fctx); if (!fctx) return -ENOMEM; @@ -96,7 +96,7 @@ nv10_fence_create(struct nouveau_drm *drm) { struct nv10_fence_priv *priv; - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = drm->fence = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 1b0c0aa3c305..1e1a01699935 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -83,7 +83,7 @@ nv17_fence_context_new(struct nouveau_channel *chan) u32 limit = start + priv->bo->bo.base.size - 1; int ret = 0; - fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); + fctx = chan->fence = kzalloc_obj(*fctx); if (!fctx) return -ENOMEM; @@ -120,7 +120,7 @@ nv17_fence_create(struct nouveau_drm *drm) struct nv10_fence_priv *priv; int ret = 0; - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = drm->fence = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index e1f0e8adf313..2dd0ef4e6497 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -42,7 +42,7 @@ nv50_fence_context_new(struct nouveau_channel *chan) u32 limit = start + priv->bo->bo.base.size - 1; int ret; - fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); + fctx = chan->fence = kzalloc_obj(*fctx); if (!fctx) return -ENOMEM; @@ -71,7 +71,7 @@ nv50_fence_create(struct nouveau_drm *drm) struct nv10_fence_priv *priv; int ret = 0; - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = drm->fence = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 1765b2cedaf9..6e5eb279b3a8 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -131,7 +131,7 @@ nv84_fence_context_new(struct nouveau_channel *chan) struct nv84_fence_chan *fctx; int ret; - fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); + fctx = chan->fence = kzalloc_obj(*fctx); if (!fctx) return -ENOMEM; @@ -198,7 +198,7 @@ nv84_fence_create(struct nouveau_drm *drm) u32 domain; int ret; - priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = drm->fence = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvif/fifo.c b/drivers/gpu/drm/nouveau/nvif/fifo.c index b0ab80995d98..155223f5f05f 100644 --- a/drivers/gpu/drm/nouveau/nvif/fifo.c +++ b/drivers/gpu/drm/nouveau/nvif/fifo.c @@ -36,7 +36,7 @@ nvif_fifo_runlists(struct nvif_device *device) if (device->runlist) return 0; - if (!(a = kmalloc(sizeof(*a), GFP_KERNEL))) + if (!(a = kmalloc_obj(*a))) return -ENOMEM; a->m.version = 1; a->m.count = sizeof(a->v) / sizeof(a->v.runlists); @@ -51,8 +51,7 @@ nvif_fifo_runlists(struct nvif_device *device) goto done; device->runlists = fls64(a->v.runlists.data); - device->runlist = kcalloc(device->runlists, sizeof(*device->runlist), - GFP_KERNEL); + device->runlist = kzalloc_objs(*device->runlist, device->runlists); if (!device->runlist) { ret = -ENOMEM; goto done; diff --git a/drivers/gpu/drm/nouveau/nvif/mmu.c b/drivers/gpu/drm/nouveau/nvif/mmu.c index c9dd3cff49a0..e1e902750991 100644 --- a/drivers/gpu/drm/nouveau/nvif/mmu.c +++ b/drivers/gpu/drm/nouveau/nvif/mmu.c @@ -69,15 +69,12 @@ nvif_mmu_ctor(struct nvif_object *parent, const char *name, s32 oclass, goto done; mmu->mem = mems[ret].oclass; - mmu->heap = kmalloc_array(mmu->heap_nr, sizeof(*mmu->heap), - GFP_KERNEL); - mmu->type = kmalloc_array(mmu->type_nr, sizeof(*mmu->type), - GFP_KERNEL); + mmu->heap = kmalloc_objs(*mmu->heap, mmu->heap_nr); + mmu->type = kmalloc_objs(*mmu->type, mmu->type_nr); if (ret = -ENOMEM, !mmu->heap || !mmu->type) goto done; - mmu->kind = kmalloc_array(mmu->kind_nr, sizeof(*mmu->kind), - GFP_KERNEL); + mmu->kind = kmalloc_objs(*mmu->kind, mmu->kind_nr); if (!mmu->kind && mmu->kind_nr) goto done; diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index 70af63d70976..6d5018a5e93c 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -81,7 +81,7 @@ nvif_object_sclass_get(struct nvif_object *object, struct nvif_sclass **psclass) return ret; } - *psclass = kcalloc(args->sclass.count, sizeof(**psclass), GFP_KERNEL); + *psclass = kzalloc_objs(**psclass, args->sclass.count); if (*psclass) { for (i = 0; i < args->sclass.count; i++) { (*psclass)[i].oclass = args->sclass.oclass[i].oclass; diff --git a/drivers/gpu/drm/nouveau/nvif/outp.c b/drivers/gpu/drm/nouveau/nvif/outp.c index 32f6c5eb92af..8cf4775a0a1e 100644 --- a/drivers/gpu/drm/nouveau/nvif/outp.c +++ b/drivers/gpu/drm/nouveau/nvif/outp.c @@ -438,7 +438,7 @@ nvif_outp_edid_get(struct nvif_outp *outp, u8 **pedid) struct nvif_outp_edid_get_v0 *args; int ret; - args = kmalloc(sizeof(*args), GFP_KERNEL); + args = kmalloc_obj(*args); if (!args) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvif/vmm.c b/drivers/gpu/drm/nouveau/nvif/vmm.c index 07c1ebc2a941..65c3e883b119 100644 --- a/drivers/gpu/drm/nouveau/nvif/vmm.c +++ b/drivers/gpu/drm/nouveau/nvif/vmm.c @@ -234,8 +234,7 @@ nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass, vmm->limit = args->size; vmm->page_nr = args->page_nr; - vmm->page = kmalloc_array(vmm->page_nr, sizeof(*vmm->page), - GFP_KERNEL); + vmm->page = kmalloc_objs(*vmm->page, vmm->page_nr); if (!vmm->page) { ret = -ENOMEM; goto done; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c index 72c88db627a5..9590834d3777 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/client.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c @@ -109,7 +109,7 @@ nvkm_client_new(const char *name, u64 device, const char *cfg, const char *dbg, struct nvkm_oclass oclass = { .base = nvkm_uclient_sclass }; struct nvkm_client *client; - if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL))) + if (!(client = *pclient = kzalloc_obj(*client))) return -ENOMEM; oclass.client = client; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/engine.c b/drivers/gpu/drm/nouveau/nvkm/core/engine.c index 5bf62940d7be..b1453bc4ad79 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/engine.c @@ -183,7 +183,7 @@ nvkm_engine_new_(const struct nvkm_engine_func *func, struct nvkm_device *device enum nvkm_subdev_type type, int inst, bool enable, struct nvkm_engine **pengine) { - if (!(*pengine = kzalloc(sizeof(**pengine), GFP_KERNEL))) + if (!(*pengine = kzalloc_obj(**pengine))) return -ENOMEM; return nvkm_engine_ctor(func, device, type, inst, enable, *pengine); } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c index d6de2b3ed2c3..8916e31ee210 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c @@ -232,7 +232,7 @@ nvkm_gpuobj_new(struct nvkm_device *device, u32 size, int align, bool zero, struct nvkm_gpuobj *gpuobj; int ret; - if (!(gpuobj = *pgpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL))) + if (!(gpuobj = *pgpuobj = kzalloc_obj(*gpuobj))) return -ENOMEM; ret = nvkm_gpuobj_ctor(device, size, align, zero, parent, gpuobj); @@ -249,7 +249,7 @@ nvkm_gpuobj_new(struct nvkm_device *device, u32 size, int align, bool zero, int nvkm_gpuobj_wrap(struct nvkm_memory *memory, struct nvkm_gpuobj **pgpuobj) { - if (!(*pgpuobj = kzalloc(sizeof(**pgpuobj), GFP_KERNEL))) + if (!(*pgpuobj = kzalloc_obj(**pgpuobj))) return -ENOMEM; (*pgpuobj)->addr = nvkm_memory_addr(memory); diff --git a/drivers/gpu/drm/nouveau/nvkm/core/intr.c b/drivers/gpu/drm/nouveau/nvkm/core/intr.c index 36a747f0039e..f31aca949e2c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/intr.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/intr.c @@ -239,8 +239,8 @@ nvkm_intr_add(const struct nvkm_intr_func *func, const struct nvkm_intr_data *da intr->data = data; intr->subdev = subdev; intr->leaves = leaves; - intr->stat = kcalloc(leaves, sizeof(*intr->stat), GFP_KERNEL); - intr->mask = kcalloc(leaves, sizeof(*intr->mask), GFP_KERNEL); + intr->stat = kzalloc_objs(*intr->stat, leaves); + intr->mask = kzalloc_objs(*intr->mask, leaves); if (!intr->stat || !intr->mask) { kfree(intr->stat); return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/memory.c b/drivers/gpu/drm/nouveau/nvkm/core/memory.c index a705c2dfca80..548df7b76f02 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/memory.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/memory.c @@ -69,7 +69,7 @@ nvkm_memory_tags_get(struct nvkm_memory *memory, struct nvkm_device *device, return 0; } - if (!(tags = kmalloc(sizeof(*tags), GFP_KERNEL))) { + if (!(tags = kmalloc_obj(*tags))) { mutex_unlock(&fb->tags.mutex); return -ENOMEM; } diff --git a/drivers/gpu/drm/nouveau/nvkm/core/mm.c b/drivers/gpu/drm/nouveau/nvkm/core/mm.c index f78a06a6b2f1..cc32003086a0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/mm.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/mm.c @@ -90,7 +90,7 @@ region_head(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size) if (a->length == size) return a; - b = kmalloc(sizeof(*b), GFP_KERNEL); + b = kmalloc_obj(*b); if (unlikely(b == NULL)) return NULL; @@ -165,7 +165,7 @@ region_tail(struct nvkm_mm *mm, struct nvkm_mm_node *a, u32 size) if (a->length == size) return a; - b = kmalloc(sizeof(*b), GFP_KERNEL); + b = kmalloc_obj(*b); if (unlikely(b == NULL)) return NULL; @@ -247,7 +247,7 @@ nvkm_mm_init(struct nvkm_mm *mm, u8 heap, u32 offset, u32 length, u32 block) next = prev->offset + prev->length; if (next != offset) { BUG_ON(next > offset); - if (!(node = kzalloc(sizeof(*node), GFP_KERNEL))) + if (!(node = kzalloc_obj(*node))) return -ENOMEM; node->type = NVKM_MM_TYPE_HOLE; node->offset = next; @@ -262,7 +262,7 @@ nvkm_mm_init(struct nvkm_mm *mm, u8 heap, u32 offset, u32 length, u32 block) mm->heap_nodes = 0; } - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c index af9f00f74c28..d2f827b9a435 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/object.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c @@ -290,7 +290,7 @@ nvkm_object_new_(const struct nvkm_object_func *func, struct nvkm_object **pobject) { if (size == 0) { - if (!(*pobject = kzalloc(sizeof(**pobject), GFP_KERNEL))) + if (!(*pobject = kzalloc_obj(**pobject))) return -ENOMEM; nvkm_object_ctor(func, oclass, *pobject); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c index 7c9edf752768..27406ac3171a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/oproxy.c @@ -178,7 +178,7 @@ int nvkm_oproxy_new_(const struct nvkm_oproxy_func *func, const struct nvkm_oclass *oclass, struct nvkm_oproxy **poproxy) { - if (!(*poproxy = kzalloc(sizeof(**poproxy), GFP_KERNEL))) + if (!(*poproxy = kzalloc_obj(**poproxy))) return -ENOMEM; nvkm_oproxy_ctor(func, oclass, *poproxy); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c index b7045d1c8415..aab5a73f467a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c @@ -280,7 +280,7 @@ int nvkm_subdev_new_(const struct nvkm_subdev_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_subdev **psubdev) { - if (!(*psubdev = kzalloc(sizeof(**psubdev), GFP_KERNEL))) + if (!(*psubdev = kzalloc_obj(**psubdev))) return -ENOMEM; nvkm_subdev_ctor(func, device, type, inst, *psubdev); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c index 46beb6e470ee..81ab29fffbf4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/core/uevent.c +++ b/drivers/gpu/drm/nouveau/nvkm/core/uevent.c @@ -144,7 +144,7 @@ nvkm_uevent_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, if (argc < sizeof(args->v0) || args->v0.version != 0) return -ENOSYS; - if (!(uevent = kzalloc(sizeof(*uevent), GFP_KERNEL))) + if (!(uevent = kzalloc_obj(*uevent))) return -ENOMEM; *pobject = &uevent->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c index ce774579c89d..f2e9a06263ce 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/ctrl.c @@ -194,7 +194,7 @@ nvkm_control_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, { struct nvkm_control *ctrl; - if (!(ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL))) + if (!(ctrl = kzalloc_obj(*ctrl))) return -ENOMEM; *pobject = &ctrl->object; ctrl->device = device; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c index 4c29b60460d4..248623b91e29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c @@ -1688,7 +1688,7 @@ nvkm_device_pci_new(struct pci_dev *pci_dev, const char *cfg, const char *dbg, pcid++; } - if (!(pdev = kzalloc(sizeof(*pdev), GFP_KERNEL))) { + if (!(pdev = kzalloc_obj(*pdev))) { pci_disable_device(pci_dev); return -ENOMEM; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c index 03aa6f09ec89..46bb55a1f565 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c @@ -253,7 +253,7 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, unsigned long rate; int ret; - if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) + if (!(tdev = kzalloc_obj(*tdev))) return -ENOMEM; tdev->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c index 32ff3181f47b..23d11d8221cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c @@ -327,7 +327,7 @@ nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_client *client = oclass->client; struct nvkm_udevice *udev; - if (!(udev = kzalloc(sizeof(*udev), GFP_KERNEL))) + if (!(udev = kzalloc_obj(*udev))) return -ENOMEM; nvkm_object_ctor(&nvkm_udevice, oclass, &udev->object); *pobject = &udev->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c index 84745f60912e..d44c4316a578 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -232,7 +232,7 @@ nvkm_disp_new_(const struct nvkm_disp_func *func, struct nvkm_device *device, struct nvkm_disp *disp; int ret; - if (!(disp = *pdisp = kzalloc(sizeof(**pdisp), GFP_KERNEL))) + if (!(disp = *pdisp = kzalloc_obj(**pdisp))) return -ENOMEM; disp->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c index 57a62a2de7c7..a8f72abbb371 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c @@ -86,7 +86,7 @@ nvkm_disp_chan_child_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_disp_chan_object *object; int ret; - if (!(object = kzalloc(sizeof(*object), GFP_KERNEL))) + if (!(object = kzalloc_obj(*object))) return -ENOMEM; nvkm_oproxy_ctor(&nvkm_disp_chan_child_func_, oclass, &object->oproxy); object->disp = disp; @@ -195,7 +195,7 @@ nvkm_disp_chan_new_(struct nvkm_disp *disp, int nr, const struct nvkm_oclass *oc if (args->v0.id >= nr || !args->v0.pushbuf != !user->func->push) return -EINVAL; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; *pobject = &chan->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c index ff88a5a5253a..e4e238aa514b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/conn.c @@ -78,7 +78,7 @@ int nvkm_conn_new(struct nvkm_disp *disp, int index, struct nvbios_connE *info, struct nvkm_conn **pconn) { - if (!(*pconn = kzalloc(sizeof(**pconn), GFP_KERNEL))) + if (!(*pconn = kzalloc_obj(**pconn))) return -ENOMEM; nvkm_conn_ctor(disp, index, info, *pconn); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c index 614921166fba..dbd984da7501 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c @@ -822,7 +822,7 @@ gv100_disp_caps_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_disp *disp = nvkm_udisp(oclass->parent); struct gv100_disp_caps *caps; - if (!(caps = kzalloc(sizeof(*caps), GFP_KERNEL))) + if (!(caps = kzalloc_obj(*caps))) return -ENOMEM; *pobject = &caps->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.c index 7f5d13d13c94..c70cbbe418a3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.c @@ -56,7 +56,7 @@ nvkm_head_new_(const struct nvkm_head_func *func, struct nvkm_disp *disp, int id) { struct nvkm_head *head; - if (!(head = kzalloc(sizeof(*head), GFP_KERNEL))) + if (!(head = kzalloc_obj(*head))) return -ENOMEM; head->func = func; head->disp = disp; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.c index e420bf2e4330..36bce3f75a57 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.c @@ -58,7 +58,7 @@ nvkm_ior_new_(const struct nvkm_ior_func *func, struct nvkm_disp *disp, enum nvkm_ior_type type, int id, bool hda) { struct nvkm_ior *ior; - if (!(ior = kzalloc(sizeof(*ior), GFP_KERNEL))) + if (!(ior = kzalloc_obj(*ior))) return -ENOMEM; ior->func = func; ior->disp = disp; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c index 28adc5a30f2f..5360b4e223af 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c @@ -379,7 +379,7 @@ nvkm_outp_new_(const struct nvkm_outp_func *func, struct nvkm_disp *disp, enum nvkm_ior_proto proto; enum nvkm_ior_type type; - if (!(outp = *poutp = kzalloc(sizeof(*outp), GFP_KERNEL))) + if (!(outp = *poutp = kzalloc_obj(*outp))) return -ENOMEM; outp->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c index 425cde35f128..151da7a0a6ea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/base.c @@ -108,7 +108,7 @@ nvkm_dma_new_(const struct nvkm_dma_func *func, struct nvkm_device *device, { struct nvkm_dma *dma; - if (!(dma = *pdma = kzalloc(sizeof(*dma), GFP_KERNEL))) + if (!(dma = *pdma = kzalloc_obj(*dma))) return -ENOMEM; dma->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf100.c index ef7ac360101e..dccf53585c0b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf100.c @@ -78,7 +78,7 @@ gf100_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, u32 kind, user, unkn; int ret; - if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + if (!(dmaobj = kzalloc_obj(*dmaobj))) return -ENOMEM; *pdmaobj = &dmaobj->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf119.c index c068cee34588..89f707ac1657 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergf119.c @@ -76,7 +76,7 @@ gf119_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, u32 kind, page; int ret; - if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + if (!(dmaobj = kzalloc_obj(*dmaobj))) return -ENOMEM; *pdmaobj = &dmaobj->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c index 39eba9fc82be..1b65a6aa31d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usergv100.c @@ -75,7 +75,7 @@ gv100_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, u32 kind, page; int ret; - if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + if (!(dmaobj = kzalloc_obj(*dmaobj))) return -ENOMEM; *pdmaobj = &dmaobj->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c index 5159d5df20a2..2201ca225fe1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv04.c @@ -85,7 +85,7 @@ nv04_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, struct nv04_dmaobj *dmaobj; int ret; - if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + if (!(dmaobj = kzalloc_obj(*dmaobj))) return -ENOMEM; *pdmaobj = &dmaobj->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv50.c index 6a85b5dea643..e12c9544a856 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/dma/usernv50.c @@ -78,7 +78,7 @@ nv50_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass, u32 user, part, comp, kind; int ret; - if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL))) + if (!(dmaobj = kzalloc_obj(*dmaobj))) return -ENOMEM; *pdmaobj = &dmaobj->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c index cf8e356867b4..fa34c223a46f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c @@ -341,7 +341,7 @@ nvkm_falcon_new_(const struct nvkm_falcon_func *func, struct nvkm_device *device { struct nvkm_falcon *falcon; - if (!(falcon = kzalloc(sizeof(*falcon), GFP_KERNEL))) + if (!(falcon = kzalloc_obj(*falcon))) return -ENOMEM; falcon->func = func; falcon->addr = addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 1561287a32f2..9dd924694306 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -377,7 +377,7 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, { struct nvkm_fifo *fifo; - if (!(fifo = *pfifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) + if (!(fifo = *pfifo = kzalloc_obj(*fifo))) return -ENOMEM; fifo->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.c index 814db9daa194..7e2d5711a1cb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/cgrp.c @@ -69,7 +69,7 @@ nvkm_cgrp_ectx_get(struct nvkm_cgrp *cgrp, struct nvkm_engn *engn, struct nvkm_e /* Nope - create a fresh one. */ CGRP_TRACE(cgrp, "ctor ectx %d[%s]", engn->id, engn->engine->subdev.name); - if (!(ectx = *pectx = kzalloc(sizeof(*ectx), GFP_KERNEL))) + if (!(ectx = *pectx = kzalloc_obj(*ectx))) return -ENOMEM; ectx->engn = engn; @@ -141,7 +141,7 @@ nvkm_cgrp_vctx_get(struct nvkm_cgrp *cgrp, struct nvkm_engn *engn, struct nvkm_c /* Now, create the sub-context. */ CGRP_TRACE(cgrp, "ctor vctx %d[%s]", engn->id, engn->engine->subdev.name); - if (!(vctx = *pvctx = kzalloc(sizeof(*vctx), GFP_KERNEL))) { + if (!(vctx = *pvctx = kzalloc_obj(*vctx))) { nvkm_cgrp_ectx_put(cgrp, &ectx); return -ENOMEM; } @@ -224,7 +224,7 @@ nvkm_cgrp_new(struct nvkm_runl *runl, const char *name, struct nvkm_vmm *vmm, bo { struct nvkm_cgrp *cgrp; - if (!(cgrp = *pcgrp = kmalloc(sizeof(*cgrp), GFP_KERNEL))) + if (!(cgrp = *pcgrp = kmalloc_obj(*cgrp))) return -ENOMEM; cgrp->func = runl->fifo->func->cgrp.func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index e5bbd8563007..418a8918bcb8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -117,7 +117,7 @@ nvkm_chan_cctx_get(struct nvkm_chan *chan, struct nvkm_engn *engn, struct nvkm_c /* Now, create the channel context - to track engine binding. */ CHAN_TRACE(chan, "ctor cctx %d[%s]", engn->id, engn->engine->subdev.name); - if (!(cctx = *pcctx = kzalloc(sizeof(*cctx), GFP_KERNEL))) { + if (!(cctx = *pcctx = kzalloc_obj(*cctx))) { nvkm_cgrp_vctx_put(cgrp, &vctx); ret = -ENOMEM; goto done; @@ -367,7 +367,7 @@ nvkm_chan_new_(const struct nvkm_chan_func *func, struct nvkm_runl *runl, int ru return -EINVAL; } - if (!(chan = *pchan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = *pchan = kzalloc_obj(*chan))) return -ENOMEM; chan->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c index 23944d95efd5..a866602ad32a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c @@ -89,7 +89,7 @@ nvkm_chid_new(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, struct nvkm_chid *chid; int id; - if (!(chid = *pchid = kzalloc(struct_size(chid, used, nr), GFP_KERNEL))) + if (!(chid = *pchid = kzalloc_flex(*chid, used, nr))) return -ENOMEM; kref_init(&chid->kref); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c index 454a481a0aef..2092521053ef 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c @@ -349,7 +349,7 @@ nvkm_runl_add(struct nvkm_runl *runl, int engi, const struct nvkm_engn_func *fun return NULL; } - if (!(engn = kzalloc(sizeof(*engn), GFP_KERNEL))) + if (!(engn = kzalloc_obj(*engn))) return NULL; engn->func = func; @@ -398,7 +398,7 @@ nvkm_runl_new(struct nvkm_fifo *fifo, int runi, u32 addr, int id_nr) struct nvkm_runl *runl; int ret; - if (!(runl = kzalloc(sizeof(*runl), GFP_KERNEL))) + if (!(runl = kzalloc_obj(*runl))) return ERR_PTR(-ENOMEM); runl->func = fifo->func->runl; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.c index 33bcf5fb3ef0..cc000adbcaf0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runq.c @@ -34,7 +34,7 @@ nvkm_runq_new(struct nvkm_fifo *fifo, int pbid) { struct nvkm_runq *runq; - if (!(runq = kzalloc(sizeof(*runq), GFP_KERNEL))) + if (!(runq = kzalloc_obj(*runq))) return NULL; runq->func = fifo->func->runq; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c index 52c594dfb1b8..dfa3c7dbdf34 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ucgrp.c @@ -104,7 +104,7 @@ nvkm_ucgrp_new(struct nvkm_fifo *fifo, const struct nvkm_oclass *oclass, void *a return PTR_ERR(vmm); /* Allocate channel group. */ - if (!(ucgrp = kzalloc(sizeof(*ucgrp), GFP_KERNEL))) { + if (!(ucgrp = kzalloc_obj(*ucgrp))) { ret = -ENOMEM; goto done; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c index c978b97e10c6..d6a87cec2150 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c @@ -166,7 +166,7 @@ nvkm_uchan_object_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, return -EINVAL; /* Allocate SW object. */ - if (!(uobj = kzalloc(sizeof(*uobj), GFP_KERNEL))) + if (!(uobj = kzalloc_obj(*uobj))) return -ENOMEM; nvkm_oproxy_ctor(&nvkm_uchan_object, oclass, &uobj->oproxy); @@ -375,7 +375,7 @@ nvkm_uchan_new(struct nvkm_fifo *fifo, struct nvkm_cgrp *cgrp, const struct nvkm } /* Allocate channel. */ - if (!(uchan = kzalloc(sizeof(*uchan), GFP_KERNEL))) { + if (!(uchan = kzalloc_obj(*uchan))) { ret = -ENOMEM; goto done; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c index 3608215f0f11..c2a9dd9018b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c @@ -285,7 +285,7 @@ gf100_gr_object_new(const struct nvkm_oclass *oclass, void *data, u32 size, struct gf100_gr_chan *chan = gf100_gr_chan(oclass->parent); struct gf100_gr_object *object; - if (!(object = kzalloc(sizeof(*object), GFP_KERNEL))) + if (!(object = kzalloc_obj(*object))) return -ENOMEM; *pobject = &object->object; @@ -384,7 +384,7 @@ gf100_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nvkm_device *device = gr->base.engine.subdev.device; int ret; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&gf100_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -2624,7 +2624,7 @@ gf100_gr_new_(const struct gf100_gr_fwif *fwif, struct nvkm_device *device, struct gf100_gr *gr; int ret; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; *pgr = &gr->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c index 82937df8b8c0..7568b3ddb2b8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv04.c @@ -1188,7 +1188,7 @@ nv04_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv04_gr_chan *chan; unsigned long flags; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv04_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -1417,7 +1417,7 @@ nv04_gr_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, st { struct nv04_gr *gr; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; spin_lock_init(&gr->lock); *pgr = &gr->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c index fcb4e4fce83f..abcf1ffbf66c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv10.c @@ -1007,7 +1007,7 @@ nv10_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nvkm_device *device = gr->base.engine.subdev.device; unsigned long flags; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv10_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -1177,7 +1177,7 @@ nv10_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, { struct nv10_gr *gr; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; spin_lock_init(&gr->lock); *pgr = &gr->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c index ab57b3b40228..66aa6398754b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv20.c @@ -79,7 +79,7 @@ nv20_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv20_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -334,7 +334,7 @@ nv20_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, { struct nv20_gr *gr; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; *pgr = &gr->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c index d6bc6904dcc8..bcf2a3697e7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv25.c @@ -25,7 +25,7 @@ nv25_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv25_gr_chan, oclass, &chan->object); chan->gr = gr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c index e5a351b51eb9..6526538dfdb0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv2a.c @@ -25,7 +25,7 @@ nv2a_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv2a_gr_chan, oclass, &chan->object); chan->gr = gr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c index 80370323755e..00e25d68d72d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv30.c @@ -26,7 +26,7 @@ nv30_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv30_gr_chan, oclass, &chan->object); chan->gr = gr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c index cdf043bbdd59..ffd1840f0271 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv34.c @@ -25,7 +25,7 @@ nv34_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv34_gr_chan, oclass, &chan->object); chan->gr = gr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c index fa5a6ccb871d..22011e3fdbfd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv35.c @@ -25,7 +25,7 @@ nv35_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv20_gr_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv35_gr_chan, oclass, &chan->object); chan->gr = gr; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c index e3e797cf3034..c8b97aabcb69 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv40.c @@ -152,7 +152,7 @@ nv40_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv40_gr_chan *chan; unsigned long flags; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv40_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -433,7 +433,7 @@ nv40_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, { struct nv40_gr *gr; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; *pgr = &gr->base; INIT_LIST_HEAD(&gr->chan); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c index c8a0288c092d..1aff861a845e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/nv50.c @@ -92,7 +92,7 @@ nv50_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *fifoch, struct nv50_gr *gr = nv50_gr(base); struct nv50_gr_chan *chan; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv50_gr_chan, oclass, &chan->object); chan->gr = gr; @@ -765,7 +765,7 @@ nv50_gr_new_(const struct nvkm_gr_func *func, struct nvkm_device *device, { struct nv50_gr *gr; - if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL))) + if (!(gr = kzalloc_obj(*gr))) return -ENOMEM; spin_lock_init(&gr->lock); *pgr = &gr->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c index db9fc1ecae0d..3652833c7951 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c @@ -89,7 +89,7 @@ nv31_mpeg_chan_new(struct nvkm_chan *fifoch, const struct nvkm_oclass *oclass, unsigned long flags; int ret = -EBUSY; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv31_mpeg_chan, oclass, &chan->object); chan->mpeg = mpeg; @@ -277,7 +277,7 @@ nv31_mpeg_new_(const struct nv31_mpeg_func *func, struct nvkm_device *device, { struct nv31_mpeg *mpeg; - if (!(mpeg = kzalloc(sizeof(*mpeg), GFP_KERNEL))) + if (!(mpeg = kzalloc_obj(*mpeg))) return -ENOMEM; mpeg->func = func; *pmpeg = &mpeg->engine; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c index 38146f9cc81c..eeb9f90745b3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c @@ -107,7 +107,7 @@ nv44_mpeg_chan_new(struct nvkm_chan *fifoch, const struct nvkm_oclass *oclass, struct nv44_mpeg_chan *chan; unsigned long flags; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; nvkm_object_ctor(&nv44_mpeg_chan, oclass, &chan->object); chan->mpeg = mpeg; @@ -207,7 +207,7 @@ nv44_mpeg_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct nv44_mpeg *mpeg; - if (!(mpeg = kzalloc(sizeof(*mpeg), GFP_KERNEL))) + if (!(mpeg = kzalloc_obj(*mpeg))) return -ENOMEM; INIT_LIST_HEAD(&mpeg->chan); *pmpeg = &mpeg->engine; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/base.c index 7d1c6791ae82..b3b3d0e1efc4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvdec/base.c @@ -43,7 +43,7 @@ nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif, struct nvkm_device *device, struct nvkm_nvdec *nvdec; int ret; - if (!(nvdec = *pnvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL))) + if (!(nvdec = *pnvdec = kzalloc_obj(*nvdec))) return -ENOMEM; ret = nvkm_engine_ctor(&nvkm_nvdec, device, type, inst, true, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/base.c index d45dbb42a0db..aeda415a2dd3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/nvenc/base.c @@ -44,7 +44,7 @@ nvkm_nvenc_new_(const struct nvkm_nvenc_fwif *fwif, struct nvkm_device *device, struct nvkm_nvenc *nvenc; int ret; - if (!(nvenc = *pnvenc = kzalloc(sizeof(*nvenc), GFP_KERNEL))) + if (!(nvenc = *pnvenc = kzalloc_obj(*nvenc))) return -ENOMEM; ret = nvkm_engine_ctor(&nvkm_nvenc, device, type, inst, true, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c index 3e4d6a680ee9..417ed23a6b81 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/base.c @@ -137,7 +137,7 @@ nvkm_sec2_new_(const struct nvkm_sec2_fwif *fwif, struct nvkm_device *device, struct nvkm_sec2 *sec2; int ret; - if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL))) + if (!(sec2 = *psec2 = kzalloc_obj(*sec2))) return -ENOMEM; ret = nvkm_engine_ctor(&nvkm_sec2, device, type, inst, true, &sec2->engine); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/r535.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/r535.c index 83a6bad5967e..c119f1415a12 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sec2/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec2/r535.c @@ -42,7 +42,7 @@ r535_sec2_new(const struct nvkm_sec2_func *func, struct nvkm_device *device, struct nvkm_sec2 *sec2; int ret; - if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL))) + if (!(sec2 = *psec2 = kzalloc_obj(*sec2))) return -ENOMEM; ret = nvkm_engine_ctor(&r535_sec2, device, type, inst, true, &sec2->engine); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c index 20220d6d4a13..02aac061c1ee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/base.c @@ -100,7 +100,7 @@ nvkm_sw_new_(const struct nvkm_sw_func *func, struct nvkm_device *device, { struct nvkm_sw *sw; - if (!(sw = *psw = kzalloc(sizeof(*sw), GFP_KERNEL))) + if (!(sw = *psw = kzalloc_obj(*sw))) return -ENOMEM; INIT_LIST_HEAD(&sw->chan); sw->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c index a0273baf4c67..0171cdf6f639 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/gf100.c @@ -110,7 +110,7 @@ gf100_sw_chan_new(struct nvkm_sw *sw, struct nvkm_chan *fifoch, struct nv50_sw_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; *pobject = &chan->base.object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c index 8a1d112da894..83b93ce06c64 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv04.c @@ -111,7 +111,7 @@ nv04_sw_chan_new(struct nvkm_sw *sw, struct nvkm_chan *fifo, { struct nv04_sw_chan *chan; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; atomic_set(&chan->ref, 0); *pobject = &chan->base.object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c index 742c75859569..2ca044861508 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv10.c @@ -41,7 +41,7 @@ nv10_sw_chan_new(struct nvkm_sw *sw, struct nvkm_chan *fifo, { struct nvkm_sw_chan *chan; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; *pobject = &chan->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c index 99476d32c5af..0cfb1eaae6de 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nv50.c @@ -106,7 +106,7 @@ nv50_sw_chan_new(struct nvkm_sw *sw, struct nvkm_chan *fifoch, struct nv50_sw_chan *chan; int ret, i; - if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) + if (!(chan = kzalloc_obj(*chan))) return -ENOMEM; *pobject = &chan->base.object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.c b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.c index f5affa1c8f34..ff0dd2153052 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/sw/nvsw.c @@ -64,7 +64,7 @@ nvkm_nvsw_new_(const struct nvkm_nvsw_func *func, struct nvkm_sw_chan *chan, { struct nvkm_nvsw *nvsw; - if (!(nvsw = kzalloc(sizeof(*nvsw), GFP_KERNEL))) + if (!(nvsw = kzalloc_obj(*nvsw))) return -ENOMEM; *pobject = &nvsw->object; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c index 910a5bb2d191..127657d485b0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/xtensa.c @@ -181,7 +181,7 @@ nvkm_xtensa_new_(const struct nvkm_xtensa_func *func, struct nvkm_device *device { struct nvkm_xtensa *xtensa; - if (!(xtensa = kzalloc(sizeof(*xtensa), GFP_KERNEL))) + if (!(xtensa = kzalloc_obj(*xtensa))) return -ENOMEM; xtensa->func = func; xtensa->addr = addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c index 211ebe7afac6..a73783fb5557 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/cmdq.c @@ -203,7 +203,7 @@ nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *qmgr, const char *name, { struct nvkm_falcon_cmdq *cmdq = *pcmdq; - if (!(cmdq = *pcmdq = kzalloc(sizeof(*cmdq), GFP_KERNEL))) + if (!(cmdq = *pcmdq = kzalloc_obj(*cmdq))) return -ENOMEM; cmdq->qmgr = qmgr; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c index 16b246fda666..56d038ce9e6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgq.c @@ -203,7 +203,7 @@ nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *qmgr, const char *name, { struct nvkm_falcon_msgq *msgq = *pmsgq; - if (!(msgq = *pmsgq = kzalloc(sizeof(*msgq), GFP_KERNEL))) + if (!(msgq = *pmsgq = kzalloc_obj(*msgq))) return -ENOMEM; msgq->qmgr = qmgr; diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c index a453de341a75..96aa621be4ed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/qmgr.c @@ -73,7 +73,7 @@ nvkm_falcon_qmgr_new(struct nvkm_falcon *falcon, struct nvkm_falcon_qmgr *qmgr; int i; - if (!(qmgr = *pqmgr = kzalloc(sizeof(*qmgr), GFP_KERNEL))) + if (!(qmgr = *pqmgr = kzalloc_obj(*qmgr))) return -ENOMEM; qmgr->falcon = falcon; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c index 13d829593180..4c7745cd6ae5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/base.c @@ -251,7 +251,7 @@ nvkm_acr_oneinit(struct nvkm_subdev *subdev) nvkm_falcon_put(lsfw->falcon, subdev); - if (!(lsf = kmalloc(sizeof(*lsf), GFP_KERNEL))) + if (!(lsf = kmalloc_obj(*lsf))) return -ENOMEM; lsf->func = lsfw->func; lsf->falcon = lsfw->falcon; @@ -422,7 +422,7 @@ nvkm_acr_new_(const struct nvkm_acr_fwif *fwif, struct nvkm_device *device, struct nvkm_acr *acr; long wprfw; - if (!(acr = *pacr = kzalloc(sizeof(*acr), GFP_KERNEL))) + if (!(acr = *pacr = kzalloc_obj(*acr))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_acr, device, type, inst, &acr->subdev); INIT_LIST_HEAD(&acr->hsfw); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga100.c index e3370c1551c0..b3f84345ee53 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga100.c @@ -37,7 +37,7 @@ ga100_acr_hsfw_ctor(struct nvkm_acr *acr, const char *bl, const char *fw, { struct nvkm_acr_hsfw *hsfw; - if (!(hsfw = kzalloc(sizeof(*hsfw), GFP_KERNEL))) + if (!(hsfw = kzalloc_obj(*hsfw))) return -ENOMEM; hsfw->falcon_id = fwif->falcon_id; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga102.c index c7d38609bb7e..a9f0090b2310 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/ga102.c @@ -32,7 +32,7 @@ ga102_acr_wpr_patch(struct nvkm_acr *acr, s64 adjust) struct nvkm_acr_lsfw *lsfw; u32 offset = 0; - lsb = kvmalloc(sizeof(*lsb), GFP_KERNEL); + lsb = kvmalloc_obj(*lsb); if (!lsb) return -ENOMEM; @@ -67,7 +67,7 @@ ga102_acr_wpr_build_lsb(struct nvkm_acr *acr, struct nvkm_acr_lsfw *lsfw) if (WARN_ON(lsfw->sig->size != sizeof(hdr->signature))) return -EINVAL; - hdr = kvzalloc(sizeof(*hdr), GFP_KERNEL); + hdr = kvzalloc_obj(*hdr); if (!hdr) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c index 31079c947758..fd78965d841f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/gm200.c @@ -247,7 +247,7 @@ gm200_acr_hsfw_ctor(struct nvkm_acr *acr, const char *bl, const char *fw, const { struct nvkm_acr_hsfw *hsfw; - if (!(hsfw = kzalloc(sizeof(*hsfw), GFP_KERNEL))) + if (!(hsfw = kzalloc_obj(*hsfw))) return -ENOMEM; hsfw->falcon_id = fwif->falcon_id; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c index bd104a030243..acb5e1dd4744 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/acr/lsfw.c @@ -71,7 +71,7 @@ nvkm_acr_lsfw_add(const struct nvkm_acr_lsf_func *func, struct nvkm_acr *acr, } if (!lsfw) { - if (!(lsfw = kzalloc(sizeof(*lsfw), GFP_KERNEL))) + if (!(lsfw = kzalloc_obj(*lsfw))) return ERR_PTR(-ENOMEM); lsfw->id = id; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index e5e60915029c..a1fa1b0c8954 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -165,7 +165,7 @@ gf100_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_bar **pbar) { struct gf100_bar *bar; - if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL))) + if (!(bar = kzalloc_obj(*bar))) return -ENOMEM; nvkm_bar_ctor(func, device, type, inst, &bar->base); bar->bar2_halve = nvkm_boolopt(device->cfgopt, "NvBar2Halve", false); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c index 6a881becb02c..cf3bbaf1a85a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/nv50.c @@ -223,7 +223,7 @@ nv50_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, u32 pgd_addr, struct nvkm_bar **pbar) { struct nv50_bar *bar; - if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL))) + if (!(bar = kzalloc_obj(*bar))) return -ENOMEM; nvkm_bar_ctor(func, device, type, inst, &bar->base); bar->pgd_addr = pgd_addr; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c index 91f486ee4c42..fd3192df452e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c @@ -156,7 +156,7 @@ nvkm_bios_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct bit_entry bit_i; int ret, idx = 0; - if (!(bios = *pbios = kzalloc(sizeof(*bios), GFP_KERNEL))) + if (!(bios = *pbios = kzalloc_obj(*bios))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_bios, device, type, inst, &bios->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c index dea444d48f94..5a481fa56fd5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -73,8 +73,7 @@ nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) } iccsense->nr_entry = cnt; - iccsense->rail = kmalloc_array(cnt, sizeof(struct pwr_rail_t), - GFP_KERNEL); + iccsense->rail = kmalloc_objs(struct pwr_rail_t, cnt); if (!iccsense->rail) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c index cb05f7f48a98..e963090f95be 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c @@ -58,7 +58,7 @@ of_init(struct nvkm_bios *bios, const char *name) struct priv *priv; if (!(dn = pci_device_to_OF_node(pdev))) return ERR_PTR(-ENODEV); - if (!(priv = kzalloc(sizeof(*priv), GFP_KERNEL))) + if (!(priv = kzalloc_obj(*priv))) return ERR_PTR(-ENOMEM); if ((priv->data = of_get_property(dn, "NVDA,BMP", &priv->size))) return priv; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c index 8d9812a51ef6..cb07c2a2d362 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowpci.c @@ -65,7 +65,7 @@ pcirom_init(struct nvkm_bios *bios, const char *name) if (!(ret = pci_enable_rom(pdev))) { if (ret = -ENOMEM, - (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + (priv = kmalloc_obj(*priv))) { if (ret = -EFAULT, (priv->rom = pci_map_rom(pdev, &priv->size))) { priv->pdev = pdev; @@ -104,7 +104,7 @@ platform_init(struct nvkm_bios *bios, const char *name) if (!pdev->rom || pdev->romlen == 0) return ERR_PTR(-ENODEV); - if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + if ((priv = kmalloc_obj(*priv))) { priv->size = pdev->romlen; if (ret = -ENODEV, (priv->rom = ioremap(pdev->rom, pdev->romlen))) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c index 023ddc7c5399..d5411d176e3a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowramin.c @@ -102,7 +102,7 @@ pramin_init(struct nvkm_bios *bios, const char *name) } /* modify bar0 PRAMIN window to cover the bios image */ - if (!(priv = kmalloc(sizeof(*priv), GFP_KERNEL))) { + if (!(priv = kmalloc_obj(*priv))) { nvkm_error(subdev, "... out of memory\n"); return ERR_PTR(-ENOMEM); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c index 0e5a46db52ea..ca1825b71669 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/base.c @@ -56,7 +56,7 @@ nvkm_bus_new_(const struct nvkm_bus_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_bus **pbus) { struct nvkm_bus *bus; - if (!(bus = *pbus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = *pbus = kzalloc_obj(*bus))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_bus, device, type, inst, &bus->subdev); bus->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c index 2a5668938f2f..7cd19e77f6a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bus/hwsq.c @@ -45,7 +45,7 @@ nvkm_hwsq_init(struct nvkm_subdev *subdev, struct nvkm_hwsq **phwsq) { struct nvkm_hwsq *hwsq; - hwsq = *phwsq = kmalloc(sizeof(*hwsq), GFP_KERNEL); + hwsq = *phwsq = kmalloc_obj(*hwsq); if (hwsq) { hwsq->subdev = subdev; hwsq->addr = ~0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c index 71420f81714b..572e63846315 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/base.c @@ -239,7 +239,7 @@ nvkm_cstate_new(struct nvkm_clk *clk, int idx, struct nvkm_pstate *pstate) if (volt && nvkm_volt_map_min(volt, cstepX.voltage) > volt->max_uv) return -EINVAL; - cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); + cstate = kzalloc_obj(*cstate); if (!cstate) return -ENOMEM; @@ -416,7 +416,7 @@ nvkm_pstate_new(struct nvkm_clk *clk, int idx) if (perfE.pstate == 0xff) return 0; - pstate = kzalloc(sizeof(*pstate), GFP_KERNEL); + pstate = kzalloc_obj(*pstate); if (!pstate) return -ENOMEM; @@ -710,7 +710,7 @@ int nvkm_clk_new_(const struct nvkm_clk_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, bool allow_reclock, struct nvkm_clk **pclk) { - if (!(*pclk = kzalloc(sizeof(**pclk), GFP_KERNEL))) + if (!(*pclk = kzalloc_obj(**pclk))) return -ENOMEM; return nvkm_clk_ctor(func, device, type, inst, allow_reclock, *pclk); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c index 6eea11aefb70..163c1b2b9b8d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gf100.c @@ -473,7 +473,7 @@ gf100_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct gf100_clk *clk; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c index 0d8e2ddcc5ee..9860a50bb4ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk104.c @@ -509,7 +509,7 @@ gk104_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct gk104_clk *clk; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c index 65f5d0f1f3bf..b1197fa70687 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gk20a.c @@ -649,7 +649,7 @@ gk20a_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct gk20a_clk *clk; int ret; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c index fa8ca53acbd1..73d696dbb698 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gm20b.c @@ -919,7 +919,7 @@ gm20b_clk_new_speedo0(struct nvkm_device *device, enum nvkm_subdev_type type, in struct gk20a_clk *clk; int ret; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c index 492b62c0ee96..7fa8beb95180 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gp10b.c @@ -165,7 +165,7 @@ gp10b_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct gp10b_clk *clk; int ret, i; - clk = kzalloc(sizeof(*clk), GFP_KERNEL); + clk = kzalloc_obj(*clk); if (!clk) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c index b5f3969727a2..5421200282b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c @@ -542,7 +542,7 @@ gt215_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct gt215_clk *clk; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c index 81f103f88dc8..3d01de9b892c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/mcp77.c @@ -414,7 +414,7 @@ mcp77_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct mcp77_clk *clk; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c index 7ddd8cecb805..7fcba24855ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv40.c @@ -223,7 +223,7 @@ nv40_clk_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct nv40_clk *clk; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; clk->base.pll_calc = nv04_clk_pll_calc; clk->base.pll_prog = nv04_clk_pll_prog; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c index e1d31c62f9ec..630c4fc26500 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/clk/nv50.c @@ -513,7 +513,7 @@ nv50_clk_new_(const struct nvkm_clk_func *func, struct nvkm_device *device, struct nv50_clk *clk; int ret; - if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL))) + if (!(clk = kzalloc_obj(*clk))) return -ENOMEM; ret = nvkm_clk_ctor(func, device, type, inst, allow_reclock, &clk->base); *pclk = &clk->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c index 88bc890f89a2..ab97a177ea97 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv04.c @@ -439,7 +439,7 @@ nv04_devinit_new_(const struct nvkm_devinit_func *func, struct nvkm_device *devi { struct nv04_devinit *init; - if (!(init = kzalloc(sizeof(*init), GFP_KERNEL))) + if (!(init = kzalloc_obj(*init))) return -ENOMEM; *pinit = &init->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c index 07ed8fd778b2..0983a29a6655 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c @@ -150,7 +150,7 @@ nv50_devinit_new_(const struct nvkm_devinit_func *func, struct nvkm_device *devi { struct nv50_devinit *init; - if (!(init = kzalloc(sizeof(*init), GFP_KERNEL))) + if (!(init = kzalloc_obj(*init))) return -ENOMEM; *pinit = &init->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/r535.c index 666eb93b1742..9921dd3d3fd9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/r535.c @@ -36,7 +36,7 @@ r535_devinit_new(const struct nvkm_devinit_func *hw, struct nvkm_devinit_func *rm; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_devinit_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c index d8d32bb5bcd9..92e38755c218 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -76,7 +76,7 @@ nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id) struct nvkm_fault_buffer *buffer; int ret; - if (!(buffer = kzalloc(sizeof(*buffer), GFP_KERNEL))) + if (!(buffer = kzalloc_obj(*buffer))) return -ENOMEM; buffer->fault = fault; buffer->id = id; @@ -156,7 +156,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fault **pfault) { struct nvkm_fault *fault; - if (!(fault = *pfault = kzalloc(sizeof(*fault), GFP_KERNEL))) + if (!(fault = *pfault = kzalloc_obj(*fault))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_fault, device, type, inst, &fault->subdev); fault->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c index 7ce1b65e2c1c..6f521653adaa 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c @@ -296,7 +296,7 @@ int nvkm_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fb **pfb) { - if (!(*pfb = kzalloc(sizeof(**pfb), GFP_KERNEL))) + if (!(*pfb = kzalloc_obj(**pfb))) return -ENOMEM; return nvkm_fb_ctor(func, device, type, inst, *pfb); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index 64281a09fb39..dc5cb6c54b13 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -112,7 +112,7 @@ gf100_fb_new_(const struct nvkm_fb_func *func, struct nvkm_device *device, { struct gf100_fb *fb; - if (!(fb = kzalloc(sizeof(*fb), GFP_KERNEL))) + if (!(fb = kzalloc_obj(*fb))) return -ENOMEM; nvkm_fb_ctor(func, device, type, inst, &fb->base); *pfb = &fb->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c index 076d968b7297..f1413fd193ad 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c @@ -244,7 +244,7 @@ nv50_fb_new_(const struct nv50_fb_func *func, struct nvkm_device *device, { struct nv50_fb *fb; - if (!(fb = kzalloc(sizeof(*fb), GFP_KERNEL))) + if (!(fb = kzalloc_obj(*fb))) return -ENOMEM; nvkm_fb_ctor(&nv50_fb_, device, type, inst, &fb->base); fb->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c index d32515010167..9db6accc75a8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/r535.c @@ -35,7 +35,7 @@ r535_fb_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nvkm_ram *ram; int ret; - if (!(ram = *pram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = *pram = kzalloc_obj(*ram))) return -ENOMEM; ram->func = &r535_fb_ram; @@ -71,7 +71,7 @@ r535_fb_new(const struct nvkm_fb_func *hw, struct nvkm_fb_func *rm; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_fb_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c index c826980bf70e..66274083e215 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ram.c @@ -127,7 +127,7 @@ nvkm_ram_wrap(struct nvkm_device *device, u64 addr, u64 size, return -ENODEV; ram = device->fb->ram; - if (!(vram = kzalloc(sizeof(*vram), GFP_KERNEL))) + if (!(vram = kzalloc_obj(*vram))) return -ENOMEM; nvkm_memory_ctor(&nvkm_vram, &vram->memory); @@ -135,7 +135,7 @@ nvkm_ram_wrap(struct nvkm_device *device, u64 addr, u64 size, vram->page = NVKM_RAM_MM_SHIFT; *pmemory = &vram->memory; - vram->mn = kzalloc(sizeof(*vram->mn), GFP_KERNEL); + vram->mn = kzalloc_obj(*vram->mn); if (!vram->mn) return -ENOMEM; @@ -163,7 +163,7 @@ nvkm_ram_get(struct nvkm_device *device, u8 heap, u8 type, u8 rpage, u64 size, ram = device->fb->ram; mm = &ram->vram; - if (!(vram = kzalloc(sizeof(*vram), GFP_KERNEL))) + if (!(vram = kzalloc_obj(*vram))) return -ENOMEM; nvkm_memory_ctor(&nvkm_vram, &vram->memory); vram->ram = ram; @@ -257,7 +257,7 @@ int nvkm_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size, struct nvkm_ram **pram) { - if (!(*pram = kzalloc(sizeof(**pram), GFP_KERNEL))) + if (!(*pram = kzalloc_obj(**pram))) return -ENOMEM; return nvkm_ram_ctor(func, fb, type, size, *pram); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c index ba43fe158b22..b6b8398eb254 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c @@ -572,7 +572,7 @@ gf100_ram_new_(const struct nvkm_ram_func *func, struct gf100_ram *ram; int ret; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c index 2b678b60b4d3..f89e7101e65c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgk104.c @@ -1371,7 +1371,7 @@ gk104_ram_train_init(struct nvkm_ram *ram) struct gk104_ram_train *train; int ret, i; - if (!(train = kzalloc(sizeof(*train), GFP_KERNEL))) + if (!(train = kzalloc_obj(*train))) return -ENOMEM; for (i = 0; i < 0x100; i++) { @@ -1446,7 +1446,7 @@ gk104_ram_ctor_data(struct gk104_ram *ram, u8 ramcfg, int i) u32 data; int ret; - if (!(cfg = kmalloc(sizeof(*cfg), GFP_KERNEL))) + if (!(cfg = kmalloc_obj(*cfg))) return -ENOMEM; p = &list_last_entry(&ram->cfg, typeof(*cfg), head)->bios; n = &cfg->bios; @@ -1530,7 +1530,7 @@ gk104_ram_new_(const struct nvkm_ram_func *func, struct nvkm_fb *fb, u8 ramcfg = nvbios_ramcfg_index(subdev); u32 tmp; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c index 8987a21e81d1..980aa9f2a7a1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgp100.c @@ -91,7 +91,7 @@ gp100_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) { struct nvkm_ram *ram; - if (!(ram = *pram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = *pram = kzalloc_obj(*ram))) return -ENOMEM; return gf100_ram_ctor(&gp100_ram, fb, ram); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c index bbfde1cb3a17..3135b46cbfcd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c @@ -942,7 +942,7 @@ gt215_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct gt215_ram *ram; int ret, i; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c index 7de18e53ef45..56605cbf0130 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/rammcp77.c @@ -66,7 +66,7 @@ mcp77_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct mcp77_ram *ram; int ret; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c index 97b3a28ca5c0..53d37c9cc7ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c @@ -192,7 +192,7 @@ nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size, struct nvkm_ram **pram) { struct nv40_ram *ram; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, &ram->base); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c index 7b1eb44ff3da..be15519d0c96 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv50.c @@ -587,7 +587,7 @@ nv50_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram) struct nv50_ram *ram; int ret, i; - if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL))) + if (!(ram = kzalloc_obj(*ram))) return -ENOMEM; *pram = &ram->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c index e366a980baa9..b782fef91dca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fsp/base.c @@ -55,7 +55,7 @@ nvkm_fsp_new_(const struct nvkm_fsp_func *func, { struct nvkm_fsp *fsp; - fsp = *pfsp = kzalloc(sizeof(*fsp), GFP_KERNEL); + fsp = *pfsp = kzalloc_obj(*fsp); if (!fsp) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c index 375dfce09f84..c1318e92e1f4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fuse/base.c @@ -45,7 +45,7 @@ nvkm_fuse_new_(const struct nvkm_fuse_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fuse **pfuse) { struct nvkm_fuse *fuse; - if (!(fuse = *pfuse = kzalloc(sizeof(*fuse), GFP_KERNEL))) + if (!(fuse = *pfuse = kzalloc_obj(*fuse))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_fuse, device, type, inst, &fuse->subdev); fuse->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c index b2c34878a68f..7a90196d2d09 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gpio/base.c @@ -227,7 +227,7 @@ nvkm_gpio_new_(const struct nvkm_gpio_func *func, struct nvkm_device *device, { struct nvkm_gpio *gpio; - if (!(gpio = *pgpio = kzalloc(sizeof(*gpio), GFP_KERNEL))) + if (!(gpio = *pgpio = kzalloc_obj(*gpio))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_gpio, device, type, inst, &gpio->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c index 30cb843ba35c..9ba1316831e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/base.c @@ -132,7 +132,7 @@ nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, { struct nvkm_gsp *gsp; - if (!(gsp = *pgsp = kzalloc(sizeof(*gsp), GFP_KERNEL))) + if (!(gsp = *pgsp = kzalloc_obj(*gsp))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_gsp, device, type, inst, &gsp->subdev); @@ -148,7 +148,7 @@ nvkm_gsp_new_(const struct nvkm_gsp_fwif *fwif, struct nvkm_device *device, if (fwif->rm) { nvkm_info(&gsp->subdev, "RM version: %s\n", fwif->ver); - gsp->rm = kzalloc(sizeof(*gsp->rm), GFP_KERNEL); + gsp->rm = kzalloc_obj(*gsp->rm); if (!gsp->rm) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c index 3b0e83b2f57f..2156cc414648 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/engine.c @@ -44,7 +44,7 @@ nvkm_rm_engine_obj_new(struct nvkm_gsp_object *chan, int chid, const struct nvkm struct nvkm_rm_engine_obj *obj; int ret; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return -ENOMEM; @@ -106,7 +106,7 @@ nvkm_rm_engine_ctor(void *(*dtor)(struct nvkm_engine *), struct nvkm_rm *rm, { struct nvkm_engine_func *func; - func = kzalloc(struct_size(func, sclass, nclass + 1), GFP_KERNEL); + func = kzalloc_flex(*func, sclass, nclass + 1); if (!func) return -ENOMEM; @@ -130,7 +130,7 @@ nvkm_rm_engine_new_(struct nvkm_rm *rm, enum nvkm_subdev_type type, int inst, u3 struct nvkm_engine *engine; int ret; - engine = kzalloc(sizeof(*engine), GFP_KERNEL); + engine = kzalloc_obj(*engine); if (!engine) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c index f40b8fcc2bcb..6cc65e19528d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/gr.c @@ -56,7 +56,7 @@ nvkm_rm_gr_new(struct nvkm_rm *rm) struct nvkm_gr_func *func; struct r535_gr *gr; - func = kzalloc(struct_size(func, sclass, ARRAY_SIZE(classes) + 1), GFP_KERNEL); + func = kzalloc_flex(*func, sclass, ARRAY_SIZE(classes) + 1); if (!func) return -ENOMEM; @@ -74,7 +74,7 @@ nvkm_rm_gr_new(struct nvkm_rm *rm) func->sclass[i].ctor = nvkm_rm_gr_obj_ctor; } - gr = kzalloc(sizeof(*gr), GFP_KERNEL); + gr = kzalloc_obj(*gr); if (!gr) { kfree(func); return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c index d9fbfc377864..e2a74973a1e8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvdec.c @@ -17,7 +17,7 @@ nvkm_rm_nvdec_new(struct nvkm_rm *rm, int inst) struct nvkm_nvdec *nvdec; int ret; - nvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL); + nvdec = kzalloc_obj(*nvdec); if (!nvdec) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c index 6dfa7b789e07..0da6a3e0c8f9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/nvenc.c @@ -17,7 +17,7 @@ nvkm_rm_nvenc_new(struct nvkm_rm *rm, int inst) struct nvkm_nvenc *nvenc; int ret; - nvenc = kzalloc(sizeof(*nvenc), GFP_KERNEL); + nvenc = kzalloc_obj(*nvenc); if (!nvenc) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c index d06bf95b9a4a..fae08ac3b18c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/bar.c @@ -169,7 +169,7 @@ r535_bar_new_(const struct nvkm_bar_func *hw, struct nvkm_device *device, struct nvkm_bar *bar; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_bar_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c index e962d0e8f837..700cea5def35 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c @@ -184,7 +184,7 @@ fbsr_vram(struct fbsr *fbsr, const char *type, u64 addr, u64 size) { struct fbsr_item *item; - if (!(item = kzalloc(sizeof(*item), GFP_KERNEL))) + if (!(item = kzalloc_obj(*item))) return false; item->type = type; @@ -309,7 +309,7 @@ r535_instmem_new(const struct nvkm_instmem_func *hw, struct nvkm_instmem_func *rm; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_instmem_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c index 4ed54b386a60..76ee938efea3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c @@ -591,7 +591,7 @@ r535_fifo_new(const struct nvkm_fifo_func *hw, struct nvkm_device *device, const struct nvkm_rm_gpu *gpu = device->gsp->rm->gpu; struct nvkm_fifo_func *rm; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_fifo_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c index ddb57d5e73d6..7fe488d4d5ff 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c @@ -147,7 +147,7 @@ r535_gr_chan_new(struct nvkm_gr *base, struct nvkm_chan *chan, const struct nvkm struct r535_gr_chan *grc; int ret; - if (!(grc = kzalloc(sizeof(*grc), GFP_KERNEL))) + if (!(grc = kzalloc_obj(*grc))) return -ENOMEM; nvkm_object_ctor(&r535_gr_chan, oclass, &grc->object); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c index 7fb13434c051..0121d5639471 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c @@ -737,8 +737,8 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps) if (!obj) goto done; - if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) || - WARN_ON(obj->buffer.length != 4)) + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length != 4) goto done; caps->status = 0; @@ -773,8 +773,8 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt) if (!obj) goto done; - if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) || - WARN_ON(obj->buffer.length != 4)) + if (obj->type != ACPI_TYPE_BUFFER || + obj->buffer.length != 4) goto done; jt->status = 0; @@ -861,8 +861,8 @@ r535_gsp_acpi_dod(acpi_handle handle, DOD_METHOD_DATA *dod) _DOD = output.pointer; - if (WARN_ON(_DOD->type != ACPI_TYPE_PACKAGE) || - WARN_ON(_DOD->package.count > ARRAY_SIZE(dod->acpiIdList))) + if (_DOD->type != ACPI_TYPE_PACKAGE || + _DOD->package.count > ARRAY_SIZE(dod->acpiIdList)) return; for (int i = 0; i < _DOD->package.count; i++) { @@ -2003,7 +2003,7 @@ static void r535_gsp_retain_logging(struct nvkm_gsp *gsp) goto exit; } - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) goto error; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c index f25ea610cd99..1ff42f1a8486 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/vmm.c @@ -171,7 +171,7 @@ r535_mmu_new(const struct nvkm_mmu_func *hw, struct nvkm_mmu_func *rm; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_mmu_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c index 6c76e5e14b75..f01abe193e25 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/anx9805.c @@ -107,7 +107,7 @@ anx9805_bus_new(struct nvkm_i2c_pad *base, int id, u8 drive, struct anx9805_bus *bus; int ret; - if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = kzalloc_obj(*bus))) return -ENOMEM; *pbus = &bus->base; bus->pad = pad; @@ -236,7 +236,7 @@ anx9805_aux_new(struct nvkm_i2c_pad *base, int id, u8 drive, struct anx9805_aux *aux; int ret; - if (!(aux = kzalloc(sizeof(*aux), GFP_KERNEL))) + if (!(aux = kzalloc_obj(*aux))) return -ENOMEM; *pbus = &aux->base; aux->pad = pad; @@ -267,7 +267,7 @@ anx9805_pad_new(struct nvkm_i2c_bus *bus, int id, u8 addr, { struct anx9805_pad *pad; - if (!(pad = kzalloc(sizeof(*pad), GFP_KERNEL))) + if (!(pad = kzalloc_obj(*pad))) return -ENOMEM; *ppad = &pad->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c index fafc634acbf6..383af72f006e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxch.c @@ -209,7 +209,7 @@ nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *func, struct nvkm_i2c_pad *pad, int id, struct nvkm_i2c_aux **paux) { - if (!(*paux = kzalloc(sizeof(**paux), GFP_KERNEL))) + if (!(*paux = kzalloc_obj(**paux))) return -ENOMEM; return nvkm_i2c_aux_ctor(func, pad, id, *paux); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c index 854bb4b5fdb4..f41bd332064d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c @@ -171,7 +171,7 @@ g94_i2c_aux_new_(const struct nvkm_i2c_aux_func *func, { struct g94_i2c_aux *aux; - if (!(aux = kzalloc(sizeof(*aux), GFP_KERNEL))) + if (!(aux = kzalloc_obj(*aux))) return -ENOMEM; *paux = &aux->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c index 3c5005e3b330..b8a16eddc553 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c @@ -177,7 +177,7 @@ gm200_i2c_aux_new(struct nvkm_i2c_pad *pad, int index, u8 drive, { struct gm200_i2c_aux *aux; - if (!(aux = kzalloc(sizeof(*aux), GFP_KERNEL))) + if (!(aux = kzalloc_obj(*aux))) return -ENOMEM; *paux = &aux->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c index 454bb21815a2..bd256e99feed 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/base.c @@ -266,7 +266,7 @@ nvkm_i2c_new_(const struct nvkm_i2c_func *func, struct nvkm_device *device, u8 ver, hdr; int ret, i, ids; - if (!(i2c = *pi2c = kzalloc(sizeof(*i2c), GFP_KERNEL))) + if (!(i2c = *pi2c = kzalloc_obj(*i2c))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_i2c, device, type, inst, &i2c->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c index ed50cc3736b9..5129f692ae1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/bus.c @@ -232,7 +232,7 @@ nvkm_i2c_bus_ctor(const struct nvkm_i2c_bus_func *func, if ( bus->func->drive_scl && !nvkm_boolopt(device->cfgopt, "NvI2C", internal)) { - if (!(bit = kzalloc(sizeof(*bit), GFP_KERNEL))) + if (!(bit = kzalloc_obj(*bit))) return -ENOMEM; bit->udelay = 10; bit->timeout = usecs_to_jiffies(2200); @@ -258,7 +258,7 @@ nvkm_i2c_bus_new_(const struct nvkm_i2c_bus_func *func, struct nvkm_i2c_pad *pad, int id, struct nvkm_i2c_bus **pbus) { - if (!(*pbus = kzalloc(sizeof(**pbus), GFP_KERNEL))) + if (!(*pbus = kzalloc_obj(**pbus))) return -ENOMEM; return nvkm_i2c_bus_ctor(func, pad, id, *pbus); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busgf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busgf119.c index 96bbdda0f439..a0fdc623d204 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busgf119.c @@ -85,7 +85,7 @@ gf119_i2c_bus_new(struct nvkm_i2c_pad *pad, int id, u8 drive, { struct gf119_i2c_bus *bus; - if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = kzalloc_obj(*bus))) return -ENOMEM; *pbus = &bus->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv04.c index a58db159231f..04e180257553 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv04.c @@ -85,7 +85,7 @@ nv04_i2c_bus_new(struct nvkm_i2c_pad *pad, int id, u8 drive, u8 sense, { struct nv04_i2c_bus *bus; - if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = kzalloc_obj(*bus))) return -ENOMEM; *pbus = &bus->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv4e.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv4e.c index cdd73dcb1197..b9b08860939d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv4e.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv4e.c @@ -76,7 +76,7 @@ nv4e_i2c_bus_new(struct nvkm_i2c_pad *pad, int id, u8 drive, { struct nv4e_i2c_bus *bus; - if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = kzalloc_obj(*bus))) return -ENOMEM; *pbus = &bus->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv50.c index 8db8399381ca..29db5cae8358 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/busnv50.c @@ -102,7 +102,7 @@ nv50_i2c_bus_new(struct nvkm_i2c_pad *pad, int id, u8 drive, return -ENODEV; } - if (!(bus = kzalloc(sizeof(*bus), GFP_KERNEL))) + if (!(bus = kzalloc_obj(*bus))) return -ENOMEM; *pbus = &bus->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c index 2c5fcb9c504b..b4b9c24b7130 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/i2c/pad.c @@ -109,7 +109,7 @@ int nvkm_i2c_pad_new_(const struct nvkm_i2c_pad_func *func, struct nvkm_i2c *i2c, int id, struct nvkm_i2c_pad **ppad) { - if (!(*ppad = kzalloc(sizeof(**ppad), GFP_KERNEL))) + if (!(*ppad = kzalloc_obj(**ppad))) return -ENOMEM; nvkm_i2c_pad_ctor(func, i2c, id, *ppad); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c index 8f0ccd3664eb..3ccdbbe2fad0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c @@ -188,7 +188,7 @@ nvkm_iccsense_create_sensor(struct nvkm_iccsense *iccsense, u8 id) return NULL; } - sensor = kmalloc(sizeof(*sensor), GFP_KERNEL); + sensor = kmalloc_obj(*sensor); if (!sensor) return NULL; @@ -279,7 +279,7 @@ nvkm_iccsense_oneinit(struct nvkm_subdev *subdev) continue; } - rail = kmalloc(sizeof(*rail), GFP_KERNEL); + rail = kmalloc_obj(*rail); if (!rail) return -ENOMEM; @@ -322,7 +322,7 @@ int nvkm_iccsense_new_(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_iccsense **iccsense) { - if (!(*iccsense = kzalloc(sizeof(**iccsense), GFP_KERNEL))) + if (!(*iccsense = kzalloc_obj(**iccsense))) return -ENOMEM; INIT_LIST_HEAD(&(*iccsense)->sensors); INIT_LIST_HEAD(&(*iccsense)->rails); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c index 201022ae9214..8f85fc88bdb6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c @@ -387,7 +387,7 @@ gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align, struct nvkm_subdev *subdev = &imem->base.subdev; struct device *dev = subdev->device->dev; - if (!(node = kzalloc(sizeof(*node), GFP_KERNEL))) + if (!(node = kzalloc_obj(*node))) return -ENOMEM; *_node = &node->base; @@ -577,7 +577,7 @@ gk20a_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int in struct nvkm_device_tegra *tdev = device->func->tegra(device); struct gk20a_instmem *imem; - if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) + if (!(imem = kzalloc_obj(*imem))) return -ENOMEM; nvkm_instmem_ctor(&gk20a_instmem, device, type, inst, &imem->base); mutex_init(&imem->lock); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c index e5320ef849bf..c6859a775085 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv04.c @@ -125,7 +125,7 @@ nv04_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, struct nv04_instobj *iobj; int ret; - if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) + if (!(iobj = kzalloc_obj(*iobj))) return -ENOMEM; *pmemory = &iobj->base.memory; @@ -267,7 +267,7 @@ nv04_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins { struct nv04_instmem *imem; - if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) + if (!(imem = kzalloc_obj(*imem))) return -ENOMEM; nvkm_instmem_ctor(&nv04_instmem, device, type, inst, &imem->base); *pimem = &imem->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c index 2544b9f0ec85..ee790d70a92b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv40.c @@ -124,7 +124,7 @@ nv40_instobj_new(struct nvkm_instmem *base, u32 size, u32 align, bool zero, struct nv40_instobj *iobj; int ret; - if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) + if (!(iobj = kzalloc_obj(*iobj))) return -ENOMEM; *pmemory = &iobj->base.memory; @@ -240,7 +240,7 @@ nv40_instmem_new(struct nvkm_device *device, enum nvkm_subdev_type type, int ins { struct nv40_instmem *imem; - if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) + if (!(imem = kzalloc_obj(*imem))) return -ENOMEM; nvkm_instmem_ctor(&nv40_instmem, device, type, inst, &imem->base); *pimem = &imem->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c index 4ca6fb30743d..6fbaa1e5876d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/nv50.c @@ -360,7 +360,7 @@ nv50_instobj_wrap(struct nvkm_instmem *base, struct nv50_instmem *imem = nv50_instmem(base); struct nv50_instobj *iobj; - if (!(iobj = kzalloc(sizeof(*iobj), GFP_KERNEL))) + if (!(iobj = kzalloc_obj(*iobj))) return -ENOMEM; *pmemory = &iobj->base.memory; @@ -431,7 +431,7 @@ nv50_instmem_new_(const struct nvkm_instmem_func *func, { struct nv50_instmem *imem; - if (!(imem = kzalloc(sizeof(*imem), GFP_KERNEL))) + if (!(imem = kzalloc_obj(*imem))) return -ENOMEM; nvkm_instmem_ctor(func, device, type, inst, &imem->base); INIT_LIST_HEAD(&imem->lru); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c index f742a7b7b175..371892c9cf44 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c @@ -133,7 +133,7 @@ nvkm_ltc_new_(const struct nvkm_ltc_func *func, struct nvkm_device *device, { struct nvkm_ltc *ltc; - if (!(ltc = *pltc = kzalloc(sizeof(*ltc), GFP_KERNEL))) + if (!(ltc = *pltc = kzalloc_obj(*ltc))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_ltc, device, type, inst, <c->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c index c85600ba69f9..5f85c806abd7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/base.c @@ -130,7 +130,7 @@ nvkm_mc_new_(const struct nvkm_mc_func *func, struct nvkm_device *device, struct nvkm_mc *mc; int ret; - if (!(mc = *pmc = kzalloc(sizeof(*mc), GFP_KERNEL))) + if (!(mc = *pmc = kzalloc_obj(*mc))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_mc, device, type, inst, &mc->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c index b67ace7ae93c..df86214183cc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c @@ -68,13 +68,13 @@ nvkm_mmu_ptp_get(struct nvkm_mmu *mmu, u32 size, bool zero) struct nvkm_mmu_ptp *ptp; int slot; - if (!(pt = kzalloc(sizeof(*pt), GFP_KERNEL))) + if (!(pt = kzalloc_obj(*pt))) return NULL; ptp = list_first_entry_or_null(&mmu->ptp.list, typeof(*ptp), head); if (!ptp) { /* Need to allocate a new parent to sub-allocate from. */ - if (!(ptp = kmalloc(sizeof(*ptp), GFP_KERNEL))) { + if (!(ptp = kmalloc_obj(*ptp))) { kfree(pt); return NULL; } @@ -126,7 +126,7 @@ nvkm_mmu_ptc_find(struct nvkm_mmu *mmu, u32 size) return ptc; } - ptc = kmalloc(sizeof(*ptc), GFP_KERNEL); + ptc = kmalloc_obj(*ptc); if (ptc) { INIT_LIST_HEAD(&ptc->item); ptc->size = size; @@ -199,7 +199,7 @@ nvkm_mmu_ptc_get(struct nvkm_mmu *mmu, u32 size, u32 align, bool zero) mutex_unlock(&mmu->ptc.mutex); /* No such luck, we need to allocate. */ - if (!(pt = kmalloc(sizeof(*pt), GFP_KERNEL))) + if (!(pt = kmalloc_obj(*pt))) return NULL; pt->ptc = ptc; pt->sub = false; @@ -434,7 +434,7 @@ int nvkm_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_mmu **pmmu) { - if (!(*pmmu = kzalloc(sizeof(**pmmu), GFP_KERNEL))) + if (!(*pmmu = kzalloc_obj(**pmmu))) return -ENOMEM; nvkm_mmu_ctor(func, device, type, inst, *pmmu); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c index 92e363dbbc5a..81fecf852e98 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/mem.c @@ -163,7 +163,7 @@ nvkm_mem_new_host(struct nvkm_mmu *mmu, int type, u8 page, u64 size, if (page != PAGE_SHIFT) return -EINVAL; - if (!(mem = kzalloc(sizeof(*mem), GFP_KERNEL))) + if (!(mem = kzalloc_obj(*mem))) return -ENOMEM; mem->target = target; mem->mmu = mmu; @@ -191,9 +191,9 @@ nvkm_mem_new_host(struct nvkm_mmu *mmu, int type, u8 page, u64 size, nvkm_memory_ctor(&nvkm_mem_dma, &mem->memory); size = ALIGN(size, PAGE_SIZE) >> PAGE_SHIFT; - if (!(mem->mem = kvmalloc_array(size, sizeof(*mem->mem), GFP_KERNEL))) + if (!(mem->mem = kvmalloc_objs(*mem->mem, size))) return -ENOMEM; - if (!(mem->dma = kvmalloc_array(size, sizeof(*mem->dma), GFP_KERNEL))) + if (!(mem->dma = kvmalloc_objs(*mem->dma, size))) return -ENOMEM; if (mmu->dma_bits > 32) diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c index e530bb8b3b17..456d7356b3e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/umem.c @@ -161,7 +161,7 @@ nvkm_umem_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, if (type >= mmu->type_nr) return -EINVAL; - if (!(umem = kzalloc(sizeof(*umem), GFP_KERNEL))) + if (!(umem = kzalloc_obj(*umem))) return -ENOMEM; nvkm_object_ctor(&nvkm_umem, oclass, &umem->object); umem->mmu = mmu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c index 6870fda4b188..cc450e7bb3fd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c @@ -172,7 +172,7 @@ nvkm_ummu_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, } else return ret; - if (!(ummu = kzalloc(sizeof(*ummu), GFP_KERNEL))) + if (!(ummu = kzalloc_obj(*ummu))) return -ENOMEM; nvkm_object_ctor(&nvkm_ummu, oclass, &ummu->object); ummu->mmu = mmu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c index cf490ff2b9f1..fefbe65af9f1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/uvmm.c @@ -551,7 +551,7 @@ nvkm_uvmm_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, } else return ret; - if (!(uvmm = kzalloc(sizeof(*uvmm), GFP_KERNEL))) + if (!(uvmm = kzalloc_obj(*uvmm))) return -ENOMEM; nvkm_object_ctor(&nvkm_uvmm, oclass, &uvmm->object); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c index 19a7407cf702..958fd78080bd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c @@ -59,7 +59,7 @@ nvkm_vmm_pt_new(const struct nvkm_vmm_desc *desc, bool sparse, pgt->sparse = sparse; if (desc->type == PGD) { - pgt->pde = kvcalloc(pten, sizeof(*pgt->pde), GFP_KERNEL); + pgt->pde = kvzalloc_objs(*pgt->pde, pten); if (!pgt->pde) { kfree(pgt); return NULL; @@ -823,7 +823,7 @@ nvkm_vmm_ptes_get_map(struct nvkm_vmm *vmm, const struct nvkm_vmm_page *page, struct nvkm_vma * nvkm_vma_new(u64 addr, u64 size) { - struct nvkm_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); + struct nvkm_vma *vma = kzalloc_obj(*vma); if (vma) { vma->addr = addr; vma->size = size; @@ -1226,7 +1226,7 @@ nvkm_vmm_new_(const struct nvkm_vmm_func *func, struct nvkm_mmu *mmu, struct lock_class_key *key, const char *name, struct nvkm_vmm **pvmm) { - if (!(*pvmm = kzalloc(sizeof(**pvmm), GFP_KERNEL))) + if (!(*pvmm = kzalloc_obj(**pvmm))) return -ENOMEM; return nvkm_vmm_ctor(func, mmu, hdr, managed, addr, size, key, name, *pvmm); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c index ff08ad5005a9..5217ce64d005 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmnv50.c @@ -346,7 +346,7 @@ nv50_vmm_join(struct nvkm_vmm *vmm, struct nvkm_memory *inst) u64 data; u32 pdei; - if (!(join = kmalloc(sizeof(*join), GFP_KERNEL))) + if (!(join = kmalloc_obj(*join))) return -ENOMEM; join->inst = inst; list_add_tail(&join->head, &vmm->join); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c index c1acfe642da3..26ec50b66e66 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c @@ -238,7 +238,7 @@ nvkm_mxm_new_(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, u8 ver, len; u16 data; - if (!(mxm = *pmxm = kzalloc(sizeof(*mxm), GFP_KERNEL))) + if (!(mxm = *pmxm = kzalloc_obj(*mxm))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_mxm, device, type, inst, &mxm->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index 0f3e0d324a52..bd421d5b1faf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -162,7 +162,7 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device, { struct nvkm_pci *pci; - if (!(pci = *ppci = kzalloc(sizeof(**ppci), GFP_KERNEL))) + if (!(pci = *ppci = kzalloc_obj(**ppci))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_pci_func, device, type, inst, &pci->subdev); pci->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c index 9e9004ec4588..e556b1905702 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c @@ -161,7 +161,7 @@ nvkm_pmu_new_(const struct nvkm_pmu_fwif *fwif, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_pmu **ppmu) { struct nvkm_pmu *pmu; - if (!(pmu = *ppmu = kzalloc(sizeof(*pmu), GFP_KERNEL))) + if (!(pmu = *ppmu = kzalloc_obj(*pmu))) return -ENOMEM; return nvkm_pmu_ctor(fwif, device, type, inst, *ppmu); } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c index b5e52b35f5d0..9831d849e4d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c @@ -215,7 +215,7 @@ gk20a_pmu_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct gk20a_pmu *pmu; int ret; - if (!(pmu = kzalloc(sizeof(*pmu), GFP_KERNEL))) + if (!(pmu = kzalloc_obj(*pmu))) return -ENOMEM; *ppmu = &pmu->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c index 22eaebefced3..cdbadb5b71d7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/memx.c @@ -53,7 +53,7 @@ nvkm_memx_init(struct nvkm_pmu *pmu, struct nvkm_memx **pmemx) if (ret) return ret; - memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL); + memx = *pmemx = kzalloc_obj(*memx); if (!memx) return -ENOMEM; memx->pmu = pmu; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c index 1510aba33956..224222914f1c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/base.c @@ -447,7 +447,7 @@ nvkm_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, { struct nvkm_therm *therm; - if (!(therm = *ptherm = kzalloc(sizeof(*therm), GFP_KERNEL))) + if (!(therm = *ptherm = kzalloc_obj(*therm))) return -ENOMEM; nvkm_therm_ctor(therm, device, type, inst, func); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c index 8ae300f911b6..8970422c9eeb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fannil.c @@ -40,7 +40,7 @@ nvkm_fannil_create(struct nvkm_therm *therm) { struct nvkm_fan *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); therm->fan = priv; if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c index b13ba9b2f6be..7e61be4bcf88 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fanpwm.c @@ -97,7 +97,7 @@ nvkm_fanpwm_create(struct nvkm_therm *therm, struct dcb_gpio_func *func) therm->func->pwm_get(therm, func->line, &divs, &duty) == -ENODEV) return -ENODEV; - fan = kzalloc(sizeof(*fan), GFP_KERNEL); + fan = kzalloc_obj(*fan); if (!fan) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c index bfdf4ca5625c..4b8e2c3bef59 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/fantog.c @@ -99,7 +99,7 @@ nvkm_fantog_create(struct nvkm_therm *therm, struct dcb_gpio_func *func) return ret; } - fan = kzalloc(sizeof(*fan), GFP_KERNEL); + fan = kzalloc_obj(*fan); if (!fan) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c index 45e295c271fb..b816fd304238 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gk104.c @@ -112,7 +112,7 @@ gk104_therm_new_(const struct nvkm_therm_func *func, struct nvkm_device *device, const struct gf100_idle_filter *idle_filter, struct nvkm_therm **ptherm) { - struct gk104_therm *therm = kzalloc(sizeof(*therm), GFP_KERNEL); + struct gk104_therm *therm = kzalloc_obj(*therm); if (!therm) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c index ddb2b2c600ca..b828dec2e3e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c @@ -119,7 +119,7 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs, if (active) { struct work_struct *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) { INIT_WORK(work, nv_poweroff_work); schedule_work(work); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c index a5c3c282b5d0..e971b6643483 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/timer/base.c @@ -187,7 +187,7 @@ nvkm_timer_new_(const struct nvkm_timer_func *func, struct nvkm_device *device, { struct nvkm_timer *tmr; - if (!(tmr = *ptmr = kzalloc(sizeof(*tmr), GFP_KERNEL))) + if (!(tmr = *ptmr = kzalloc_obj(*tmr))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_timer, device, type, inst, &tmr->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c index eb348dfc1d7a..c987c4abe15c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/top/base.c @@ -26,7 +26,7 @@ struct nvkm_top_device * nvkm_top_device_new(struct nvkm_top *top) { - struct nvkm_top_device *info = kmalloc(sizeof(*info), GFP_KERNEL); + struct nvkm_top_device *info = kmalloc_obj(*info); if (info) { info->type = NVKM_SUBDEV_NR; info->inst = -1; @@ -152,7 +152,7 @@ nvkm_top_new_(const struct nvkm_top_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_top **ptop) { struct nvkm_top *top; - if (!(top = *ptop = kzalloc(sizeof(*top), GFP_KERNEL))) + if (!(top = *ptop = kzalloc_obj(*top))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_top, device, type, inst, &top->subdev); top->func = func; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c index 62e81d551f44..c0258bcfe8f5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c @@ -39,7 +39,7 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct nvkm_device *device, struct nvkm_vfn *vfn; int ret; - if (!(vfn = *pvfn = kzalloc(sizeof(*vfn), GFP_KERNEL))) + if (!(vfn = *pvfn = kzalloc_obj(*vfn))) return -ENOMEM; nvkm_subdev_ctor(&nvkm_vfn, device, type, inst, &vfn->subdev); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c index d294844d9eae..36709c0e3bb4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/r535.c @@ -38,7 +38,7 @@ r535_vfn_new(const struct nvkm_vfn_func *hw, struct nvkm_vfn_func *rm; int ret; - if (!(rm = kzalloc(sizeof(*rm), GFP_KERNEL))) + if (!(rm = kzalloc_obj(*rm))) return -ENOMEM; rm->dtor = r535_vfn_dtor; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c index 4e64d8843373..0004cf642ec6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c @@ -56,7 +56,7 @@ nvkm_uvfn_new(struct nvkm_device *device, const struct nvkm_oclass *oclass, if (argc != 0) return -ENOSYS; - if (!(uvfn = kzalloc(sizeof(*uvfn), GFP_KERNEL))) + if (!(uvfn = kzalloc_obj(*uvfn))) return -ENOMEM; nvkm_object_ctor(&nvkm_uvfn, oclass, &uvfn->object); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c index 803b98df4858..f0c66f9b4b1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/base.c @@ -321,7 +321,7 @@ int nvkm_volt_new_(const struct nvkm_volt_func *func, struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_volt **pvolt) { - if (!(*pvolt = kzalloc(sizeof(**pvolt), GFP_KERNEL))) + if (!(*pvolt = kzalloc_obj(**pvolt))) return -ENOMEM; nvkm_volt_ctor(func, device, type, inst, *pvolt); return 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c index d1ce4309cfb8..7bc264fb753b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c @@ -113,7 +113,7 @@ gk104_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, volt_func = &gk104_volt_pwm; } - if (!(volt = kzalloc(sizeof(*volt), GFP_KERNEL))) + if (!(volt = kzalloc_obj(*volt))) return -ENOMEM; nvkm_volt_ctor(volt_func, device, type, inst, &volt->base); *pvolt = &volt->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c index ccac88da8864..5aef95c9f20f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk20a.c @@ -176,7 +176,7 @@ gk20a_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, { struct gk20a_volt *volt; - volt = kzalloc(sizeof(*volt), GFP_KERNEL); + volt = kzalloc_obj(*volt); if (!volt) return -ENOMEM; *pvolt = &volt->base; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c index c2e9694d333f..5a2a909b57eb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c @@ -77,7 +77,7 @@ gm20b_volt_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, return -EINVAL; } - volt = kzalloc(sizeof(*volt), GFP_KERNEL); + volt = kzalloc_obj(*volt); if (!volt) return -ENOMEM; *pvolt = &volt->base; diff --git a/drivers/gpu/drm/omapdrm/dss/dispc.c b/drivers/gpu/drm/omapdrm/dss/dispc.c index cf055815077c..78b74217f952 100644 --- a/drivers/gpu/drm/omapdrm/dss/dispc.c +++ b/drivers/gpu/drm/omapdrm/dss/dispc.c @@ -4603,7 +4603,7 @@ static int dispc_bind(struct device *dev, struct device *master, void *data) int r = 0; struct device_node *np = pdev->dev.of_node; - dispc = kzalloc(sizeof(*dispc), GFP_KERNEL); + dispc = kzalloc_obj(*dispc); if (!dispc) return -ENOMEM; diff --git a/drivers/gpu/drm/omapdrm/dss/dsi.c b/drivers/gpu/drm/omapdrm/dss/dsi.c index b129e5a8d791..27fe7bca9e2c 100644 --- a/drivers/gpu/drm/omapdrm/dss/dsi.c +++ b/drivers/gpu/drm/omapdrm/dss/dsi.c @@ -1041,7 +1041,7 @@ static int dsi_dump_dsi_irqs(struct seq_file *s, void *p) unsigned long flags; struct dsi_irq_stats *stats; - stats = kmalloc(sizeof(*stats), GFP_KERNEL); + stats = kmalloc_obj(*stats); if (!stats) return -ENOMEM; diff --git a/drivers/gpu/drm/omapdrm/dss/dss.c b/drivers/gpu/drm/omapdrm/dss/dss.c index 692df747e2ae..53b7938a3d05 100644 --- a/drivers/gpu/drm/omapdrm/dss/dss.c +++ b/drivers/gpu/drm/omapdrm/dss/dss.c @@ -928,7 +928,7 @@ dss_debugfs_create_file(struct dss_device *dss, const char *name, { struct dss_debugfs_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -1419,7 +1419,7 @@ static int dss_probe(struct platform_device *pdev) struct dss_device *dss; int r; - dss = kzalloc(sizeof(*dss), GFP_KERNEL); + dss = kzalloc_obj(*dss); if (!dss) return -ENOMEM; diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 1c2a1920c0a6..ee4c0119d408 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -716,7 +716,7 @@ static void omap_crtc_reset(struct drm_crtc *crtc) kfree(crtc->state); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_crtc_reset(crtc, &state->base); } @@ -731,7 +731,7 @@ omap_crtc_duplicate_state(struct drm_crtc *crtc) current_state = to_omap_crtc_state(crtc->state); - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; @@ -793,7 +793,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, DBG("%s", channel_names[channel]); - omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL); + omap_crtc = kzalloc_obj(*omap_crtc); if (!omap_crtc) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c index bbe427ab43c1..a2c702b831a7 100644 --- a/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c +++ b/drivers/gpu/drm/omapdrm/omap_dmm_tiler.c @@ -536,7 +536,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w, unsigned long flags; u32 slot_bytes; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return ERR_PTR(-ENOMEM); @@ -571,7 +571,7 @@ struct tiler_block *tiler_reserve_2d(enum tiler_fmt fmt, u16 w, struct tiler_block *tiler_reserve_1d(size_t size) { - struct tiler_block *block = kzalloc(sizeof(*block), GFP_KERNEL); + struct tiler_block *block = kzalloc_obj(*block); int num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long flags; @@ -774,7 +774,7 @@ static int omap_dmm_probe(struct platform_device *dev) u32 hwinfo, pat_geom; struct resource *mem; - omap_dmm = kzalloc(sizeof(*omap_dmm), GFP_KERNEL); + omap_dmm = kzalloc_obj(*omap_dmm); if (!omap_dmm) goto fail; @@ -885,8 +885,8 @@ static int omap_dmm_probe(struct platform_device *dev) } /* alloc engines */ - omap_dmm->engines = kcalloc(omap_dmm->num_engines, - sizeof(*omap_dmm->engines), GFP_KERNEL); + omap_dmm->engines = kzalloc_objs(*omap_dmm->engines, + omap_dmm->num_engines); if (!omap_dmm->engines) { ret = -ENOMEM; goto fail; @@ -904,8 +904,7 @@ static int omap_dmm_probe(struct platform_device *dev) list_add(&omap_dmm->engines[i].idle_node, &omap_dmm->idle_head); } - omap_dmm->tcm = kcalloc(omap_dmm->num_lut, sizeof(*omap_dmm->tcm), - GFP_KERNEL); + omap_dmm->tcm = kzalloc_objs(*omap_dmm->tcm, omap_dmm->num_lut); if (!omap_dmm->tcm) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 1b96343226a5..bf0bad8c8cf1 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -146,7 +146,7 @@ static int omap_atomic_update_normalize_zpos(struct drm_device *dev, struct drm_plane_state **states; int ret = 0; - states = kmalloc_array(total_planes, sizeof(*states), GFP_KERNEL); + states = kmalloc_objs(*states, total_planes); if (!states) return -ENOMEM; @@ -285,7 +285,7 @@ static int omap_global_obj_init(struct drm_device *dev) struct omap_drm_private *priv = dev->dev_private; struct omap_global_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -798,7 +798,7 @@ static int pdev_probe(struct platform_device *pdev) } /* Allocate and initialize the driver private structure. */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 195715b162e3..b02c46d70f29 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c @@ -122,7 +122,7 @@ struct drm_encoder *omap_encoder_init(struct drm_device *dev, struct drm_encoder *encoder = NULL; struct omap_encoder *omap_encoder; - omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL); + omap_encoder = kzalloc_obj(*omap_encoder); if (!omap_encoder) goto fail; diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c index b8c249ec1891..1df232232a64 100644 --- a/drivers/gpu/drm/omapdrm/omap_fb.c +++ b/drivers/gpu/drm/omapdrm/omap_fb.c @@ -390,7 +390,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, goto fail; } - omap_fb = kzalloc(sizeof(*omap_fb), GFP_KERNEL); + omap_fb = kzalloc_obj(*omap_fb); if (!omap_fb) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c index 71e79f53489a..8e013e4f2c6b 100644 --- a/drivers/gpu/drm/omapdrm/omap_gem.c +++ b/drivers/gpu/drm/omapdrm/omap_gem.c @@ -254,7 +254,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) * DSS, GPU, etc. are not cache coherent: */ if (omap_obj->flags & (OMAP_BO_WC|OMAP_BO_UNCACHED)) { - addrs = kmalloc_array(npages, sizeof(*addrs), GFP_KERNEL); + addrs = kmalloc_objs(*addrs, npages); if (!addrs) { ret = -ENOMEM; goto free_pages; @@ -278,7 +278,7 @@ static int omap_gem_attach_pages(struct drm_gem_object *obj) } } } else { - addrs = kcalloc(npages, sizeof(*addrs), GFP_KERNEL); + addrs = kzalloc_objs(*addrs, npages); if (!addrs) { ret = -ENOMEM; goto free_pages; @@ -989,7 +989,7 @@ struct sg_table *omap_gem_get_sg(struct drm_gem_object *obj, if (sgt) goto out; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto err_unpin; @@ -1319,7 +1319,7 @@ struct drm_gem_object *omap_gem_new(struct drm_device *dev, } /* Allocate the initialize the OMAP GEM object. */ - omap_obj = kzalloc(sizeof(*omap_obj), GFP_KERNEL); + omap_obj = kzalloc_obj(*omap_obj); if (!omap_obj) return NULL; @@ -1410,7 +1410,7 @@ struct drm_gem_object *omap_gem_new_dmabuf(struct drm_device *dev, size_t size, unsigned int ret; npages = DIV_ROUND_UP(size, PAGE_SIZE); - pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, npages); if (!pages) { omap_gem_free_object(obj); return ERR_PTR(-ENOMEM); @@ -1470,7 +1470,7 @@ void omap_gem_init(struct drm_device *dev) return; } - usergart = kcalloc(3, sizeof(*usergart), GFP_KERNEL); + usergart = kzalloc_objs(*usergart, 3); if (!usergart) return; diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c index 943c5307da00..d0f895c43ee4 100644 --- a/drivers/gpu/drm/omapdrm/omap_irq.c +++ b/drivers/gpu/drm/omapdrm/omap_irq.c @@ -43,7 +43,7 @@ struct omap_irq_wait * omap_irq_wait_init(struct drm_device *dev, u32 irqmask, int count) { struct omap_drm_private *priv = dev->dev_private; - struct omap_irq_wait *wait = kzalloc(sizeof(*wait), GFP_KERNEL); + struct omap_irq_wait *wait = kzalloc_obj(*wait); unsigned long flags; init_waitqueue_head(&wait->wq); diff --git a/drivers/gpu/drm/omapdrm/omap_overlay.c b/drivers/gpu/drm/omapdrm/omap_overlay.c index 6fb7510cbebb..77c1b78d0163 100644 --- a/drivers/gpu/drm/omapdrm/omap_overlay.c +++ b/drivers/gpu/drm/omapdrm/omap_overlay.c @@ -159,7 +159,7 @@ static struct omap_hw_overlay *omap_overlay_init(enum omap_plane_id overlay_id, { struct omap_hw_overlay *overlay; - overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kzalloc_obj(*overlay); if (!overlay) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index f9698890c989..0e09d8f1fe5e 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c @@ -410,7 +410,7 @@ static void omap_plane_reset(struct drm_plane *plane) if (plane->state) drm_atomic_helper_plane_destroy_state(plane, plane->state); - omap_state = kzalloc(sizeof(*omap_state), GFP_KERNEL); + omap_state = kzalloc_obj(*omap_state); if (!omap_state) return; @@ -427,7 +427,7 @@ omap_plane_atomic_duplicate_state(struct drm_plane *plane) current_state = to_omap_plane_state(plane->state); - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; @@ -533,7 +533,7 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, if (WARN_ON(idx >= num_planes)) return ERR_PTR(-EINVAL); - omap_plane = kzalloc(sizeof(*omap_plane), GFP_KERNEL); + omap_plane = kzalloc_obj(*omap_plane); if (!omap_plane) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c index 2f58a9b0773a..711f5101aa04 100644 --- a/drivers/gpu/drm/panfrost/panfrost_drv.c +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c @@ -207,9 +207,8 @@ panfrost_lookup_bos(struct drm_device *dev, if (ret) return ret; - job->mappings = kvmalloc_array(job->bo_count, - sizeof(struct panfrost_gem_mapping *), - GFP_KERNEL | __GFP_ZERO); + job->mappings = kvmalloc_objs(struct panfrost_gem_mapping *, + job->bo_count, GFP_KERNEL | __GFP_ZERO); if (!job->mappings) return -ENOMEM; @@ -317,7 +316,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data, goto out_put_syncout; } - job = kzalloc(sizeof(*job), GFP_KERNEL); + job = kzalloc_obj(*job); if (!job) { ret = -ENOMEM; goto out_put_jm_ctx; @@ -598,7 +597,7 @@ static int panfrost_ioctl_sync_bo(struct drm_device *ddev, void *data, if (!args->op_count) return 0; - ops = kvmalloc_array(args->op_count, sizeof(*ops), GFP_KERNEL); + ops = kvmalloc_objs(*ops, args->op_count); if (!ops) { DRM_DEBUG("Failed to allocate incoming BO sync ops array\n"); return -ENOMEM; @@ -683,7 +682,7 @@ panfrost_open(struct drm_device *dev, struct drm_file *file) struct panfrost_device *pfdev = to_panfrost_device(dev); struct panfrost_file_priv *panfrost_priv; - panfrost_priv = kzalloc(sizeof(*panfrost_priv), GFP_KERNEL); + panfrost_priv = kzalloc_obj(*panfrost_priv); if (!panfrost_priv) return -ENOMEM; diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c b/drivers/gpu/drm/panfrost/panfrost_gem.c index 47ac8386aabc..822633da741e 100644 --- a/drivers/gpu/drm/panfrost/panfrost_gem.c +++ b/drivers/gpu/drm/panfrost/panfrost_gem.c @@ -175,7 +175,7 @@ int panfrost_gem_open(struct drm_gem_object *obj, struct drm_file *file_priv) struct panfrost_file_priv *priv = file_priv->driver_priv; struct panfrost_gem_mapping *mapping; - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) return -ENOMEM; @@ -429,7 +429,7 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t struct panfrost_device *pfdev = to_panfrost_device(dev); struct panfrost_gem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c index 11894a6b9fcc..d59b4863b8ad 100644 --- a/drivers/gpu/drm/panfrost/panfrost_job.c +++ b/drivers/gpu/drm/panfrost/panfrost_job.c @@ -95,7 +95,7 @@ static struct dma_fence *panfrost_fence_create(struct panfrost_device *pfdev, in struct panfrost_fence *fence; struct panfrost_job_slot *js = pfdev->js; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return ERR_PTR(-ENOMEM); @@ -1053,7 +1053,7 @@ int panfrost_jm_ctx_create(struct drm_file *file, struct panfrost_jm_ctx *jm_ctx; int ret; - jm_ctx = kzalloc(sizeof(*jm_ctx), GFP_KERNEL); + jm_ctx = kzalloc_obj(*jm_ctx); if (!jm_ctx) return -ENOMEM; diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 50ff30849361..4a3162c3b659 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -620,14 +620,16 @@ static int panfrost_mmu_map_fault_addr(struct panfrost_device *pfdev, int as, dma_resv_lock(obj->resv, NULL); if (!bo->base.pages) { - bo->sgts = kvmalloc_array(bo->base.base.size / SZ_2M, - sizeof(struct sg_table), GFP_KERNEL | __GFP_ZERO); + bo->sgts = kvmalloc_objs(struct sg_table, + bo->base.base.size / SZ_2M, + GFP_KERNEL | __GFP_ZERO); if (!bo->sgts) { ret = -ENOMEM; goto err_unlock; } - pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); + pages = kvmalloc_objs(struct page *, nr_pages, + GFP_KERNEL | __GFP_ZERO); if (!pages) { kvfree(bo->sgts); bo->sgts = NULL; @@ -792,7 +794,7 @@ struct panfrost_mmu *panfrost_mmu_ctx_create(struct panfrost_device *pfdev) fmt = ARM_MALI_LPAE; } - mmu = kzalloc(sizeof(*mmu), GFP_KERNEL); + mmu = kzalloc_obj(*mmu); if (!mmu) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panthor/panthor_drv.c b/drivers/gpu/drm/panthor/panthor_drv.c index 165dddfde6ca..1bcec6a2e3e0 100644 --- a/drivers/gpu/drm/panthor/panthor_drv.c +++ b/drivers/gpu/drm/panthor/panthor_drv.c @@ -382,7 +382,7 @@ panthor_submit_ctx_add_sync_signal(struct panthor_submit_ctx *ctx, u32 handle, u struct dma_fence *cur_fence; int ret; - sig_sync = kzalloc(sizeof(*sig_sync), GFP_KERNEL); + sig_sync = kzalloc_obj(*sig_sync); if (!sig_sync) return -ENOMEM; @@ -723,8 +723,8 @@ panthor_submit_ctx_push_jobs(struct panthor_submit_ctx *ctx, static int panthor_submit_ctx_init(struct panthor_submit_ctx *ctx, struct drm_file *file, u32 job_count) { - ctx->jobs = kvmalloc_array(job_count, sizeof(*ctx->jobs), - GFP_KERNEL | __GFP_ZERO); + ctx->jobs = kvmalloc_objs(*ctx->jobs, job_count, + GFP_KERNEL | __GFP_ZERO); if (!ctx->jobs) return -ENOMEM; @@ -1471,7 +1471,7 @@ panthor_open(struct drm_device *ddev, struct drm_file *file) struct panthor_file *pfile; int ret; - pfile = kzalloc(sizeof(*pfile), GFP_KERNEL); + pfile = kzalloc_obj(*pfile); if (!pfile) return -ENOMEM; diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c index 2c215efb5320..4b4575dd6e90 100644 --- a/drivers/gpu/drm/panthor/panthor_gem.c +++ b/drivers/gpu/drm/panthor/panthor_gem.c @@ -183,7 +183,7 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, if (drm_WARN_ON(&ptdev->base, !vm)) return ERR_PTR(-EINVAL); - kbo = kzalloc(sizeof(*kbo), GFP_KERNEL); + kbo = kzalloc_obj(*kbo); if (!kbo) return ERR_PTR(-ENOMEM); @@ -399,7 +399,7 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t { struct panthor_gem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panthor/panthor_heap.c b/drivers/gpu/drm/panthor/panthor_heap.c index 0b6ff4c0a11b..1ee30dc7066f 100644 --- a/drivers/gpu/drm/panthor/panthor_heap.c +++ b/drivers/gpu/drm/panthor/panthor_heap.c @@ -145,7 +145,7 @@ static int panthor_alloc_heap_chunk(struct panthor_heap_pool *pool, struct panthor_heap_chunk_header *hdr; int ret; - chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); + chunk = kmalloc_obj(*chunk); if (!chunk) return -ENOMEM; @@ -303,7 +303,7 @@ int panthor_heap_create(struct panthor_heap_pool *pool, if (!vm) return -EINVAL; - heap = kzalloc(sizeof(*heap), GFP_KERNEL); + heap = kzalloc_obj(*heap); if (!heap) { ret = -ENOMEM; goto err_put_vm; @@ -541,7 +541,7 @@ panthor_heap_pool_create(struct panthor_device *ptdev, struct panthor_vm *vm) struct panthor_heap_pool *pool; int ret = 0; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c index 198d59f42578..41604a7aaf85 100644 --- a/drivers/gpu/drm/panthor/panthor_mmu.c +++ b/drivers/gpu/drm/panthor/panthor_mmu.c @@ -1159,7 +1159,7 @@ panthor_vm_op_ctx_prealloc_vmas(struct panthor_vm_op_ctx *op_ctx) } for (u32 i = 0; i < vma_count; i++) { - struct panthor_vma *vma = kzalloc(sizeof(*vma), GFP_KERNEL); + struct panthor_vma *vma = kzalloc_obj(*vma); if (!vma) return -ENOMEM; @@ -1257,9 +1257,8 @@ static int panthor_vm_prepare_map_op_ctx(struct panthor_vm_op_ctx *op_ctx, ((ALIGN(va + size, 1ull << 30) - ALIGN_DOWN(va, 1ull << 30)) >> 30) + ((ALIGN(va + size, 1ull << 21) - ALIGN_DOWN(va, 1ull << 21)) >> 21); - op_ctx->rsvd_page_tables.pages = kcalloc(pt_count, - sizeof(*op_ctx->rsvd_page_tables.pages), - GFP_KERNEL); + op_ctx->rsvd_page_tables.pages = kzalloc_objs(*op_ctx->rsvd_page_tables.pages, + pt_count); if (!op_ctx->rsvd_page_tables.pages) { ret = -ENOMEM; goto err_cleanup; @@ -1312,9 +1311,8 @@ static int panthor_vm_prepare_unmap_op_ctx(struct panthor_vm_op_ctx *op_ctx, goto err_cleanup; if (pt_count) { - op_ctx->rsvd_page_tables.pages = kcalloc(pt_count, - sizeof(*op_ctx->rsvd_page_tables.pages), - GFP_KERNEL); + op_ctx->rsvd_page_tables.pages = kzalloc_objs(*op_ctx->rsvd_page_tables.pages, + pt_count); if (!op_ctx->rsvd_page_tables.pages) { ret = -ENOMEM; goto err_cleanup; @@ -1587,7 +1585,7 @@ void panthor_vm_pool_destroy(struct panthor_file *pfile) */ int panthor_vm_pool_create(struct panthor_file *pfile) { - pfile->vms = kzalloc(sizeof(*pfile->vms), GFP_KERNEL); + pfile->vms = kzalloc_obj(*pfile->vms); if (!pfile->vms) return -ENOMEM; @@ -2426,7 +2424,7 @@ panthor_vm_create(struct panthor_device *ptdev, bool for_mcu, struct panthor_vm *vm; int ret; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = kzalloc_obj(*vm); if (!vm) return ERR_PTR(-ENOMEM); @@ -2609,7 +2607,7 @@ panthor_vm_bind_job_create(struct drm_file *file, if (vm->destroyed || vm->unusable) return ERR_PTR(-EINVAL); - job = kzalloc(sizeof(*job), GFP_KERNEL); + job = kzalloc_obj(*job); if (!job) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c index ca272dbae14d..a70f1db0764e 100644 --- a/drivers/gpu/drm/panthor/panthor_sched.c +++ b/drivers/gpu/drm/panthor/panthor_sched.c @@ -893,14 +893,15 @@ panthor_queue_get_syncwait_obj(struct panthor_group *group, struct panthor_queue out_sync: /* Make sure the CPU caches are invalidated before the seqno is read. - * drm_gem_shmem_sync() is a NOP if map_wc=true, so no need to check + * panthor_gem_sync() is a NOP if map_wc=true, so no need to check * it here. */ - panthor_gem_sync(&bo->base.base, queue->syncwait.offset, + panthor_gem_sync(&bo->base.base, + DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE, + queue->syncwait.offset, queue->syncwait.sync64 ? sizeof(struct panthor_syncobj_64b) : - sizeof(struct panthor_syncobj_32b), - DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE); + sizeof(struct panthor_syncobj_32b)); return queue->syncwait.kmap + queue->syncwait.offset; @@ -3512,7 +3513,7 @@ group_create_queue(struct panthor_group *group, if (args->priority > CSF_MAX_QUEUE_PRIO) return ERR_PTR(-EINVAL); - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return ERR_PTR(-ENOMEM); @@ -3659,7 +3660,7 @@ int panthor_group_create(struct panthor_file *pfile, hweight64(group_args->tiler_core_mask) < group_args->max_tiler_cores) return -EINVAL; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; @@ -3853,7 +3854,7 @@ int panthor_group_pool_create(struct panthor_file *pfile) { struct panthor_group_pool *gpool; - gpool = kzalloc(sizeof(*gpool), GFP_KERNEL); + gpool = kzalloc_obj(*gpool); if (!gpool) return -ENOMEM; @@ -3979,7 +3980,7 @@ panthor_job_create(struct panthor_file *pfile, if (qsubmit->latest_flush & GENMASK(30, 24)) return ERR_PTR(-EINVAL); - job = kzalloc(sizeof(*job), GFP_KERNEL); + job = kzalloc_obj(*job); if (!job) return ERR_PTR(-ENOMEM); @@ -4011,7 +4012,7 @@ panthor_job_create(struct panthor_file *pfile, * the previously submitted job. */ if (job->call_info.size) { - job->done_fence = kzalloc(sizeof(*job->done_fence), GFP_KERNEL); + job->done_fence = kzalloc_obj(*job->done_fence); if (!job->done_fence) { ret = -ENOMEM; goto err_put_job; diff --git a/drivers/gpu/drm/qxl/qxl_cmd.c b/drivers/gpu/drm/qxl/qxl_cmd.c index 2e3200db2f39..0be2c4334b74 100644 --- a/drivers/gpu/drm/qxl/qxl_cmd.c +++ b/drivers/gpu/drm/qxl/qxl_cmd.c @@ -63,7 +63,7 @@ qxl_ring_create(struct qxl_ring_header *header, { struct qxl_ring *ring; - ring = kmalloc(sizeof(*ring), GFP_KERNEL); + ring = kmalloc_obj(*ring); if (!ring) return NULL; diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index a134820aac58..75d47e6b9142 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -58,9 +58,8 @@ static int qxl_alloc_client_monitors_config(struct qxl_device *qdev, qdev->client_monitors_config = NULL; } if (!qdev->client_monitors_config) { - qdev->client_monitors_config = kzalloc( - struct_size(qdev->client_monitors_config, - heads, count), GFP_KERNEL); + qdev->client_monitors_config = kzalloc_flex(*qdev->client_monitors_config, + heads, count); if (!qdev->client_monitors_config) return -ENOMEM; } @@ -1008,7 +1007,7 @@ static int qdev_crtc_init(struct drm_device *dev, int crtc_id) struct qxl_device *qdev = to_qxl(dev); int r; - qxl_crtc = kzalloc(sizeof(struct qxl_crtc), GFP_KERNEL); + qxl_crtc = kzalloc_obj(struct qxl_crtc); if (!qxl_crtc) return -ENOMEM; @@ -1159,7 +1158,7 @@ static int qdev_output_init(struct drm_device *dev, int num_output) struct drm_encoder *encoder; int ret; - qxl_output = kzalloc(sizeof(struct qxl_output), GFP_KERNEL); + qxl_output = kzalloc_obj(struct qxl_output); if (!qxl_output) return -ENOMEM; @@ -1241,8 +1240,7 @@ int qxl_create_monitors_object(struct qxl_device *qdev) qxl_bo_physical_address(qdev, qdev->monitors_config_bo, 0); memset(qdev->monitors_config, 0, monitors_config_size); - qdev->dumb_heads = kcalloc(qxl_num_crtc, sizeof(qdev->dumb_heads[0]), - GFP_KERNEL); + qdev->dumb_heads = kzalloc_objs(qdev->dumb_heads[0], qxl_num_crtc); if (!qdev->dumb_heads) { qxl_destroy_monitors_object(qdev); return -ENOMEM; diff --git a/drivers/gpu/drm/qxl/qxl_image.c b/drivers/gpu/drm/qxl/qxl_image.c index 3cc45997533d..578e8aa63f24 100644 --- a/drivers/gpu/drm/qxl/qxl_image.c +++ b/drivers/gpu/drm/qxl/qxl_image.c @@ -40,7 +40,7 @@ qxl_allocate_chunk(struct qxl_device *qdev, struct qxl_drm_chunk *chunk; int ret; - chunk = kmalloc(sizeof(struct qxl_drm_chunk), GFP_KERNEL); + chunk = kmalloc_obj(struct qxl_drm_chunk); if (!chunk) return -ENOMEM; @@ -63,7 +63,7 @@ qxl_image_alloc_objects(struct qxl_device *qdev, struct qxl_drm_image *image; int ret; - image = kmalloc(sizeof(struct qxl_drm_image), GFP_KERNEL); + image = kmalloc_obj(struct qxl_drm_image); if (!image) return -ENOMEM; diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c index 336cbff26089..4ee2b5acf2e0 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -168,8 +168,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, cmd->command_size)) return -EFAULT; - reloc_info = kmalloc_array(cmd->relocs_num, - sizeof(struct qxl_reloc_info), GFP_KERNEL); + reloc_info = kmalloc_objs(struct qxl_reloc_info, cmd->relocs_num); if (!reloc_info) return -ENOMEM; diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c index 66635c55cf85..313f6c30cac8 100644 --- a/drivers/gpu/drm/qxl/qxl_object.c +++ b/drivers/gpu/drm/qxl/qxl_object.c @@ -116,7 +116,7 @@ int qxl_bo_create(struct qxl_device *qdev, unsigned long size, else type = ttm_bo_type_device; *bo_ptr = NULL; - bo = kzalloc(sizeof(struct qxl_bo), GFP_KERNEL); + bo = kzalloc_obj(struct qxl_bo); if (bo == NULL) return -ENOMEM; size = roundup(size, PAGE_SIZE); diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c index 7b3c9a6016db..b1bf1e798cc6 100644 --- a/drivers/gpu/drm/qxl/qxl_release.c +++ b/drivers/gpu/drm/qxl/qxl_release.c @@ -177,7 +177,7 @@ int qxl_release_list_add(struct qxl_release *release, struct qxl_bo *bo) return 0; } - entry = kmalloc(sizeof(struct qxl_bo_list), GFP_KERNEL); + entry = kmalloc_obj(struct qxl_bo_list); if (!entry) return -ENOMEM; diff --git a/drivers/gpu/drm/qxl/qxl_ttm.c b/drivers/gpu/drm/qxl/qxl_ttm.c index 1a40590077dd..5d495c4798a3 100644 --- a/drivers/gpu/drm/qxl/qxl_ttm.c +++ b/drivers/gpu/drm/qxl/qxl_ttm.c @@ -109,7 +109,7 @@ static struct ttm_tt *qxl_ttm_tt_create(struct ttm_buffer_object *bo, { struct ttm_tt *ttm; - ttm = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL); + ttm = kzalloc_obj(struct ttm_tt); if (ttm == NULL) return NULL; if (ttm_tt_init(ttm, bo, page_flags, ttm_cached, 0)) { diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index b31125eb9a65..dbd192650c69 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -1281,7 +1281,7 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) { int base; struct atom_context *ctx = - kzalloc(sizeof(struct atom_context), GFP_KERNEL); + kzalloc_obj(struct atom_context); char *str; char name[512]; int i; diff --git a/drivers/gpu/drm/radeon/atombios_encoders.c b/drivers/gpu/drm/radeon/atombios_encoders.c index 3d9f47bc807a..5cfd8fcfa5e8 100644 --- a/drivers/gpu/drm/radeon/atombios_encoders.c +++ b/drivers/gpu/drm/radeon/atombios_encoders.c @@ -218,7 +218,7 @@ void radeon_atom_backlight_init(struct radeon_encoder *radeon_encoder, return; } - pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL); + pdata = kmalloc_obj(struct radeon_backlight_privdata); if (!pdata) { DRM_ERROR("Memory allocation failed\n"); goto error; @@ -2625,7 +2625,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) { struct drm_device *dev = radeon_encoder->base.dev; struct radeon_device *rdev = dev->dev_private; - struct radeon_encoder_atom_dac *dac = kzalloc(sizeof(struct radeon_encoder_atom_dac), GFP_KERNEL); + struct radeon_encoder_atom_dac *dac = kzalloc_obj(struct radeon_encoder_atom_dac); if (!dac) return NULL; @@ -2638,7 +2638,7 @@ static struct radeon_encoder_atom_dig * radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) { int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; - struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); + struct radeon_encoder_atom_dig *dig = kzalloc_obj(struct radeon_encoder_atom_dig); if (!dig) return NULL; @@ -2676,7 +2676,7 @@ radeon_add_atom_encoder(struct drm_device *dev, } /* add a new one */ - radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); + radeon_encoder = kzalloc_obj(struct radeon_encoder); if (!radeon_encoder) return; diff --git a/drivers/gpu/drm/radeon/btc_dpm.c b/drivers/gpu/drm/radeon/btc_dpm.c index 70931b04bbac..c868649508fb 100644 --- a/drivers/gpu/drm/radeon/btc_dpm.c +++ b/drivers/gpu/drm/radeon/btc_dpm.c @@ -1992,7 +1992,7 @@ static int btc_initialize_mc_reg_table(struct radeon_device *rdev) struct evergreen_mc_reg_table *eg_table = &eg_pi->mc_reg_table; u8 module_index = rv770_get_memory_module_index(rdev); - table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(struct atom_mc_reg_table); if (!table) return -ENOMEM; @@ -2526,7 +2526,7 @@ int btc_dpm_init(struct radeon_device *rdev) struct atom_clock_dividers dividers; int ret; - eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL); + eg_pi = kzalloc_obj(struct evergreen_power_info); if (eg_pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = eg_pi; @@ -2552,9 +2552,7 @@ int btc_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kcalloc(4, - sizeof(struct radeon_clock_voltage_dependency_entry), - GFP_KERNEL); + kzalloc_objs(struct radeon_clock_voltage_dependency_entry, 4); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c index ba8db1d07c07..22321eb95b7d 100644 --- a/drivers/gpu/drm/radeon/ci_dpm.c +++ b/drivers/gpu/drm/radeon/ci_dpm.c @@ -4579,7 +4579,7 @@ static int ci_initialize_mc_reg_table(struct radeon_device *rdev) u8 module_index = rv770_get_memory_module_index(rdev); int ret; - table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(struct atom_mc_reg_table); if (!table) return -ENOMEM; @@ -5517,9 +5517,8 @@ static int ci_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + state_array->ucNumEntries); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -5534,7 +5533,7 @@ static int ci_parse_power_table(struct radeon_device *rdev) ret = -EINVAL; goto err_free_ps; } - ps = kzalloc(sizeof(struct ci_ps), GFP_KERNEL); + ps = kzalloc_obj(struct ci_ps); if (ps == NULL) { ret = -ENOMEM; goto err_free_ps; @@ -5638,7 +5637,7 @@ int ci_dpm_init(struct radeon_device *rdev) struct pci_dev *root = rdev->pdev->bus->self; int ret; - pi = kzalloc(sizeof(struct ci_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct ci_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; @@ -5741,9 +5740,7 @@ int ci_dpm_init(struct radeon_device *rdev) ci_set_private_data_variables_based_on_pptable(rdev); rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kcalloc(4, - sizeof(struct radeon_clock_voltage_dependency_entry), - GFP_KERNEL); + kzalloc_objs(struct radeon_clock_voltage_dependency_entry, 4); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { ci_dpm_fini(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/cypress_dpm.c b/drivers/gpu/drm/radeon/cypress_dpm.c index 72a0768df00f..aef702ff12ee 100644 --- a/drivers/gpu/drm/radeon/cypress_dpm.c +++ b/drivers/gpu/drm/radeon/cypress_dpm.c @@ -2028,7 +2028,7 @@ int cypress_dpm_init(struct radeon_device *rdev) struct atom_clock_dividers dividers; int ret; - eg_pi = kzalloc(sizeof(struct evergreen_power_info), GFP_KERNEL); + eg_pi = kzalloc_obj(struct evergreen_power_info); if (eg_pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = eg_pi; diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 1162cb5d75ed..3142ef4da7f4 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -2769,7 +2769,7 @@ int evergreen_cs_parse(struct radeon_cs_parser *p) if (p->track == NULL) { /* initialize tracker, we are in kms */ - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (track == NULL) return -ENOMEM; evergreen_cs_track_init(track); diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 4aa050385284..1693b36fc52d 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c @@ -2457,9 +2457,8 @@ static int kv_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + state_array->ucNumEntries); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -2471,7 +2470,7 @@ static int kv_parse_power_table(struct radeon_device *rdev) &non_clock_info_array->nonClockInfo[non_clock_array_index]; if (!rdev->pm.power_state[i].clock_info) return -EINVAL; - ps = kzalloc(sizeof(struct kv_ps), GFP_KERNEL); + ps = kzalloc_obj(struct kv_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -2520,7 +2519,7 @@ int kv_dpm_init(struct radeon_device *rdev) struct kv_power_info *pi; int ret, i; - pi = kzalloc(sizeof(struct kv_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct kv_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/radeon/ni_dpm.c b/drivers/gpu/drm/radeon/ni_dpm.c index 82edbfb259bf..8059e019d4fc 100644 --- a/drivers/gpu/drm/radeon/ni_dpm.c +++ b/drivers/gpu/drm/radeon/ni_dpm.c @@ -2104,7 +2104,7 @@ static int ni_init_smc_spll_table(struct radeon_device *rdev) if (ni_pi->spll_table_start == 0) return -EINVAL; - spll_table = kzalloc(sizeof(SMC_NISLANDS_SPLL_DIV_TABLE), GFP_KERNEL); + spll_table = kzalloc_obj(SMC_NISLANDS_SPLL_DIV_TABLE); if (spll_table == NULL) return -ENOMEM; @@ -2879,7 +2879,7 @@ static int ni_initialize_mc_reg_table(struct radeon_device *rdev) struct ni_mc_reg_table *ni_table = &ni_pi->mc_reg_table; u8 module_index = rv770_get_memory_module_index(rdev); - table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(struct atom_mc_reg_table); if (!table) return -ENOMEM; @@ -3147,7 +3147,7 @@ static int ni_initialize_smc_cac_tables(struct radeon_device *rdev) if (ni_pi->enable_cac == false) return 0; - cac_tables = kzalloc(sizeof(PP_NIslands_CACTABLES), GFP_KERNEL); + cac_tables = kzalloc_obj(PP_NIslands_CACTABLES); if (!cac_tables) return -ENOMEM; @@ -4000,9 +4000,8 @@ static int ni_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + power_info->pplib.ucNumStates); if (!rdev->pm.dpm.ps) return -ENOMEM; @@ -4018,7 +4017,7 @@ static int ni_parse_power_table(struct radeon_device *rdev) power_info->pplib.ucNonClockSize)); if (power_info->pplib.ucStateEntrySize - 1) { u8 *idx; - ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL); + ps = kzalloc_obj(struct ni_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -4051,7 +4050,7 @@ int ni_dpm_init(struct radeon_device *rdev) struct atom_clock_dividers dividers; int ret; - ni_pi = kzalloc(sizeof(struct ni_power_info), GFP_KERNEL); + ni_pi = kzalloc_obj(struct ni_power_info); if (ni_pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = ni_pi; @@ -4078,9 +4077,7 @@ int ni_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kcalloc(4, - sizeof(struct radeon_clock_voltage_dependency_entry), - GFP_KERNEL); + kzalloc_objs(struct radeon_clock_voltage_dependency_entry, 4); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 07a9c523a17a..3ac1a79b6f13 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -2063,7 +2063,7 @@ int r100_cs_parse(struct radeon_cs_parser *p) struct r100_cs_track *track; int r; - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (!track) return -ENOMEM; r100_cs_track_clear(p->rdev, track); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index d2ee6deec039..60a784769120 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1284,7 +1284,7 @@ int r300_cs_parse(struct radeon_cs_parser *p) struct r100_cs_track *track; int r; - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (track == NULL) return -ENOMEM; r100_cs_track_clear(p->rdev, track); diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 8eeceeeca362..17b2ff2387aa 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -2282,7 +2282,7 @@ int r600_cs_parse(struct radeon_cs_parser *p) if (p->track == NULL) { /* initialize tracker, we are in kms */ - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (track == NULL) return -ENOMEM; r600_cs_track_init(track); diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c index 81d58ef667dd..83f1ae31cbdb 100644 --- a/drivers/gpu/drm/radeon/r600_dpm.c +++ b/drivers/gpu/drm/radeon/r600_dpm.c @@ -821,9 +821,8 @@ static int r600_parse_clk_voltage_dep_table(struct radeon_clock_voltage_dependen int i; ATOM_PPLIB_Clock_Voltage_Dependency_Record *entry; - radeon_table->entries = kcalloc(atom_table->ucNumEntries, - sizeof(struct radeon_clock_voltage_dependency_entry), - GFP_KERNEL); + radeon_table->entries = kzalloc_objs(struct radeon_clock_voltage_dependency_entry, + atom_table->ucNumEntries); if (!radeon_table->entries) return -ENOMEM; @@ -988,9 +987,8 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) ATOM_PPLIB_PhaseSheddingLimits_Record *entry; rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries = - kcalloc(psl->ucNumEntries, - sizeof(struct radeon_phase_shedding_limits_entry), - GFP_KERNEL); + kzalloc_objs(struct radeon_phase_shedding_limits_entry, + psl->ucNumEntries); if (!rdev->pm.dpm.dyn_state.phase_shedding_limits_table.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; @@ -1198,7 +1196,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(ext_hdr->usPPMTableOffset)); rdev->pm.dpm.dyn_state.ppm_table = - kzalloc(sizeof(struct radeon_ppm_table), GFP_KERNEL); + kzalloc_obj(struct radeon_ppm_table); if (!rdev->pm.dpm.dyn_state.ppm_table) { r600_free_extended_power_table(rdev); return -ENOMEM; @@ -1256,7 +1254,7 @@ int r600_parse_extended_power_table(struct radeon_device *rdev) le16_to_cpu(ext_hdr->usPowerTuneTableOffset)); ATOM_PowerTune_Table *pt; rdev->pm.dpm.dyn_state.cac_tdp_table = - kzalloc(sizeof(struct radeon_cac_tdp_table), GFP_KERNEL); + kzalloc_obj(struct radeon_cac_tdp_table); if (!rdev->pm.dpm.dyn_state.cac_tdp_table) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 89d7b0e9e79f..84cf71bc1330 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c @@ -132,7 +132,7 @@ struct radeon_agp_head *radeon_agp_head_init(struct drm_device *dev) struct pci_dev *pdev = to_pci_dev(dev->dev); struct radeon_agp_head *head; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (!head) return NULL; head->bridge = agp_find_bridge(pdev); diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 81a0a91921b9..3dd9724b331d 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1632,7 +1632,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct lvds_info = (union lvds_info *)(mode_info->atom_context->bios + data_offset); lvds = - kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); + kzalloc_obj(struct radeon_encoder_atom_dig); if (!lvds) return NULL; @@ -1773,7 +1773,7 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) dac_info = (struct _COMPASSIONATE_DATA *) (mode_info->atom_context->bios + data_offset); - p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), GFP_KERNEL); + p_dac = kzalloc_obj(struct radeon_encoder_primary_dac); if (!p_dac) return NULL; @@ -1960,7 +1960,7 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) dac_info = (struct _COMPASSIONATE_DATA *) (mode_info->atom_context->bios + data_offset); - tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); + tv_dac = kzalloc_obj(struct radeon_encoder_tv_dac); if (!tv_dac) return NULL; @@ -2117,9 +2117,8 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; if (num_modes == 0) return state_index; - rdev->pm.power_state = kcalloc(num_modes, - sizeof(struct radeon_power_state), - GFP_KERNEL); + rdev->pm.power_state = kzalloc_objs(struct radeon_power_state, + num_modes); if (!rdev->pm.power_state) return state_index; /* last mode is usually default, array is low to high */ @@ -2127,8 +2126,7 @@ static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) /* avoid memory leaks from invalid modes or unknown frev. */ if (!rdev->pm.power_state[state_index].clock_info) { rdev->pm.power_state[state_index].clock_info = - kzalloc(sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_obj(struct radeon_pm_clock_info); } if (!rdev->pm.power_state[state_index].clock_info) goto out; @@ -2591,9 +2589,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); if (power_info->pplib.ucNumStates == 0) return state_index; - rdev->pm.power_state = kcalloc(power_info->pplib.ucNumStates, - sizeof(struct radeon_power_state), - GFP_KERNEL); + rdev->pm.power_state = kzalloc_objs(struct radeon_power_state, + power_info->pplib.ucNumStates); if (!rdev->pm.power_state) return state_index; /* first mode is usually default, followed by low to high */ @@ -2609,10 +2606,8 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) (power_state->v1.ucNonClockStateIndex * power_info->pplib.ucNonClockSize)); rdev->pm.power_state[i].clock_info = - kcalloc((power_info->pplib.ucStateEntrySize - 1) ? - (power_info->pplib.ucStateEntrySize - 1) : 1, - sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_objs(struct radeon_pm_clock_info, + (power_info->pplib.ucStateEntrySize - 1) ? (power_info->pplib.ucStateEntrySize - 1) : 1); if (!rdev->pm.power_state[i].clock_info) return state_index; if (power_info->pplib.ucStateEntrySize - 1) { @@ -2694,9 +2689,8 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); if (state_array->ucNumEntries == 0) return state_index; - rdev->pm.power_state = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_power_state), - GFP_KERNEL); + rdev->pm.power_state = kzalloc_objs(struct radeon_power_state, + state_array->ucNumEntries); if (!rdev->pm.power_state) return state_index; power_state_offset = (u8 *)state_array->states; @@ -2707,10 +2701,8 @@ static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) &non_clock_info_array->nonClockInfo[non_clock_array_index]; rdev->pm.power_state[i].clock_info = - kcalloc(power_state->v2.ucNumDPMLevels ? - power_state->v2.ucNumDPMLevels : 1, - sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_objs(struct radeon_pm_clock_info, + power_state->v2.ucNumDPMLevels ? power_state->v2.ucNumDPMLevels : 1); if (!rdev->pm.power_state[i].clock_info) return state_index; if (power_state->v2.ucNumDPMLevels) { @@ -2787,12 +2779,10 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) } if (state_index == 0) { - rdev->pm.power_state = kzalloc(sizeof(struct radeon_power_state), GFP_KERNEL); + rdev->pm.power_state = kzalloc_obj(struct radeon_power_state); if (rdev->pm.power_state) { rdev->pm.power_state[0].clock_info = - kcalloc(1, - sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_objs(struct radeon_pm_clock_info, 1); if (rdev->pm.power_state[0].clock_info) { /* add the default mode */ rdev->pm.power_state[state_index].type = diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index df8d7f56b028..6a4e268ffd99 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -851,8 +851,7 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct struct radeon_encoder_primary_dac *p_dac; int found = 0; - p_dac = kzalloc(sizeof(struct radeon_encoder_primary_dac), - GFP_KERNEL); + p_dac = kzalloc_obj(struct radeon_encoder_primary_dac); if (!p_dac) return NULL; @@ -1002,7 +1001,7 @@ struct radeon_encoder_tv_dac *radeon_combios_get_tv_dac_info(struct struct radeon_encoder_tv_dac *tv_dac; int found = 0; - tv_dac = kzalloc(sizeof(struct radeon_encoder_tv_dac), GFP_KERNEL); + tv_dac = kzalloc_obj(struct radeon_encoder_tv_dac); if (!tv_dac) return NULL; @@ -1090,7 +1089,7 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct uint32_t ppll_div_sel, ppll_val; uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); - lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); + lvds = kzalloc_obj(struct radeon_encoder_lvds); if (!lvds) return NULL; @@ -1165,7 +1164,7 @@ struct radeon_encoder_lvds *radeon_combios_get_lvds_info(struct radeon_encoder lcd_info = combios_get_table_offset(dev, COMBIOS_LCD_INFO_TABLE); if (lcd_info) { - lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); + lvds = kzalloc_obj(struct radeon_encoder_lvds); if (!lvds) return NULL; @@ -2630,16 +2629,13 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) rdev->pm.default_power_state_index = -1; /* allocate 2 power states */ - rdev->pm.power_state = kcalloc(2, sizeof(struct radeon_power_state), - GFP_KERNEL); + rdev->pm.power_state = kzalloc_objs(struct radeon_power_state, 2); if (rdev->pm.power_state) { /* allocate 1 clock mode per state */ rdev->pm.power_state[0].clock_info = - kcalloc(1, sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_objs(struct radeon_pm_clock_info, 1); rdev->pm.power_state[1].clock_info = - kcalloc(1, sizeof(struct radeon_pm_clock_info), - GFP_KERNEL); + kzalloc_objs(struct radeon_pm_clock_info, 1); if (!rdev->pm.power_state[0].clock_info || !rdev->pm.power_state[1].clock_info) goto pm_failed; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 012d8b2295b8..373f08a125ff 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1887,7 +1887,7 @@ radeon_add_atom_connector(struct drm_device *dev, } } - radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); + radeon_connector = kzalloc_obj(struct radeon_connector); if (!radeon_connector) return; @@ -1907,7 +1907,7 @@ radeon_add_atom_connector(struct drm_device *dev, } if (is_dp_bridge) { - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2078,7 +2078,7 @@ radeon_add_atom_connector(struct drm_device *dev, break; case DRM_MODE_CONNECTOR_DVII: case DRM_MODE_CONNECTOR_DVID: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2140,7 +2140,7 @@ radeon_add_atom_connector(struct drm_device *dev, break; case DRM_MODE_CONNECTOR_HDMIA: case DRM_MODE_CONNECTOR_HDMIB: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2195,7 +2195,7 @@ radeon_add_atom_connector(struct drm_device *dev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_DisplayPort: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2250,7 +2250,7 @@ radeon_add_atom_connector(struct drm_device *dev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_eDP: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2297,7 +2297,7 @@ radeon_add_atom_connector(struct drm_device *dev, connector->doublescan_allowed = false; break; case DRM_MODE_CONNECTOR_LVDS: - radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); + radeon_dig_connector = kzalloc_obj(struct radeon_connector_atom_dig); if (!radeon_dig_connector) goto failed; radeon_dig_connector->igp_lane_info = igp_lane_info; @@ -2379,7 +2379,7 @@ radeon_add_legacy_connector(struct drm_device *dev, } } - radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL); + radeon_connector = kzalloc_obj(struct radeon_connector); if (!radeon_connector) return; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 3f9c0011244f..2db819ab85d2 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -93,8 +93,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->dma_reloc_idx = 0; /* FIXME: we assume that each relocs use 4 dwords */ p->nrelocs = chunk->length_dw / 4; - p->relocs = kvcalloc(p->nrelocs, sizeof(struct radeon_bo_list), - GFP_KERNEL); + p->relocs = kvzalloc_objs(struct radeon_bo_list, p->nrelocs); if (p->relocs == NULL) { return -ENOMEM; } @@ -297,7 +296,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) } p->cs_flags = 0; p->nchunks = cs->num_chunks; - p->chunks = kvcalloc(p->nchunks, sizeof(struct radeon_cs_chunk), GFP_KERNEL); + p->chunks = kvzalloc_objs(struct radeon_cs_chunk, p->nchunks); if (p->chunks == NULL) { return -ENOMEM; } diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 5faae0361361..5d523d5dae88 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -974,7 +974,7 @@ static uint32_t cail_ioreg_read(struct card_info *info, uint32_t reg) int radeon_atombios_init(struct radeon_device *rdev) { struct card_info *atom_card_info = - kzalloc(sizeof(struct card_info), GFP_KERNEL); + kzalloc_obj(struct card_info); if (!atom_card_info) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index bc28117e01b4..5c72aad3dae7 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -494,7 +494,7 @@ static int radeon_crtc_page_flip_target(struct drm_crtc *crtc, unsigned long flags; int r; - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (work == NULL) return -ENOMEM; @@ -682,7 +682,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) struct radeon_device *rdev = dev->dev_private; struct radeon_crtc *radeon_crtc; - radeon_crtc = kzalloc(sizeof(*radeon_crtc), GFP_KERNEL); + radeon_crtc = kzalloc_obj(*radeon_crtc); if (radeon_crtc == NULL) return; @@ -1346,7 +1346,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, return ERR_PTR(-EINVAL); } - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (fb == NULL) { drm_gem_object_put(obj); return ERR_PTR(-ENOMEM); @@ -1539,7 +1539,7 @@ static void radeon_afmt_init(struct radeon_device *rdev) BUG_ON(num_afmt > ARRAY_SIZE(eg_offsets)); for (i = 0; i < num_afmt; i++) { - rdev->mode_info.afmt[i] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + rdev->mode_info.afmt[i] = kzalloc_obj(struct radeon_afmt); if (rdev->mode_info.afmt[i]) { rdev->mode_info.afmt[i]->offset = eg_offsets[i]; rdev->mode_info.afmt[i]->id = i; @@ -1547,26 +1547,26 @@ static void radeon_afmt_init(struct radeon_device *rdev) } } else if (ASIC_IS_DCE3(rdev)) { /* DCE3.x has 2 audio blocks tied to DIG encoders */ - rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + rdev->mode_info.afmt[0] = kzalloc_obj(struct radeon_afmt); if (rdev->mode_info.afmt[0]) { rdev->mode_info.afmt[0]->offset = DCE3_HDMI_OFFSET0; rdev->mode_info.afmt[0]->id = 0; } - rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + rdev->mode_info.afmt[1] = kzalloc_obj(struct radeon_afmt); if (rdev->mode_info.afmt[1]) { rdev->mode_info.afmt[1]->offset = DCE3_HDMI_OFFSET1; rdev->mode_info.afmt[1]->id = 1; } } else if (ASIC_IS_DCE2(rdev)) { /* DCE2 has at least 1 routable audio block */ - rdev->mode_info.afmt[0] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + rdev->mode_info.afmt[0] = kzalloc_obj(struct radeon_afmt); if (rdev->mode_info.afmt[0]) { rdev->mode_info.afmt[0]->offset = DCE2_HDMI_OFFSET0; rdev->mode_info.afmt[0]->id = 0; } /* r6xx has 2 routable audio blocks */ if (rdev->family >= CHIP_R600) { - rdev->mode_info.afmt[1] = kzalloc(sizeof(struct radeon_afmt), GFP_KERNEL); + rdev->mode_info.afmt[1] = kzalloc_obj(struct radeon_afmt); if (rdev->mode_info.afmt[1]) { rdev->mode_info.afmt[1]->offset = DCE2_HDMI_OFFSET1; rdev->mode_info.afmt[1]->id = 1; diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c b/drivers/gpu/drm/radeon/radeon_fbdev.c index fd083aaa91bb..18d61f3f7344 100644 --- a/drivers/gpu/drm/radeon/radeon_fbdev.c +++ b/drivers/gpu/drm/radeon/radeon_fbdev.c @@ -228,7 +228,7 @@ int radeon_fbdev_driver_fbdev_probe(struct drm_fb_helper *fb_helper, } rbo = gem_to_radeon_bo(gobj); - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) { ret = -ENOMEM; goto err_radeon_fbdev_destroy_pinned_object; diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 167d6f122b8e..02a40e4750c7 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -137,7 +137,7 @@ int radeon_fence_emit(struct radeon_device *rdev, u64 seq; /* we are protected by the ring emission mutex */ - *fence = kmalloc(sizeof(struct radeon_fence), GFP_KERNEL); + *fence = kmalloc_obj(struct radeon_fence); if ((*fence) == NULL) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index f3ba4187092c..13a091ec797b 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -912,7 +912,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, if (rec->mm_i2c && (radeon_hw_i2c == 0)) return NULL; - i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); + i2c = kzalloc_obj(struct radeon_i2c_chan); if (i2c == NULL) return NULL; diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 7cbe02ffb193..dc43fd790a9c 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -640,7 +640,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) /* new gpu have virtual address space support */ if (rdev->family >= CHIP_CAYMAN) { - fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); + fpriv = kzalloc_obj(*fpriv); if (unlikely(!fpriv)) { r = -ENOMEM; goto err_suspend; diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index d1e8b9757a65..1f82e2b57f5d 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c @@ -394,7 +394,7 @@ void radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder, return; } - pdata = kmalloc(sizeof(struct radeon_backlight_privdata), GFP_KERNEL); + pdata = kmalloc_obj(struct radeon_backlight_privdata); if (!pdata) { DRM_ERROR("Memory allocation failed\n"); goto error; @@ -1695,7 +1695,7 @@ static struct radeon_encoder_int_tmds *radeon_legacy_get_tmds_info(struct radeon struct radeon_encoder_int_tmds *tmds; bool ret; - tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL); + tmds = kzalloc_obj(struct radeon_encoder_int_tmds); if (!tmds) return NULL; @@ -1721,7 +1721,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra if (rdev->is_atom_bios) return NULL; - tmds = kzalloc(sizeof(struct radeon_encoder_ext_tmds), GFP_KERNEL); + tmds = kzalloc_obj(struct radeon_encoder_ext_tmds); if (!tmds) return NULL; @@ -1752,7 +1752,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_ } /* add a new one */ - radeon_encoder = kzalloc(sizeof(struct radeon_encoder), GFP_KERNEL); + radeon_encoder = kzalloc_obj(struct radeon_encoder); if (!radeon_encoder) return; diff --git a/drivers/gpu/drm/radeon/radeon_semaphore.c b/drivers/gpu/drm/radeon/radeon_semaphore.c index 1f0a9a4ff5ae..da0a0b28f2b8 100644 --- a/drivers/gpu/drm/radeon/radeon_semaphore.c +++ b/drivers/gpu/drm/radeon/radeon_semaphore.c @@ -36,7 +36,7 @@ int radeon_semaphore_create(struct radeon_device *rdev, { int r; - *semaphore = kmalloc(sizeof(struct radeon_semaphore), GFP_KERNEL); + *semaphore = kmalloc_obj(struct radeon_semaphore); if (*semaphore == NULL) { return -ENOMEM; } diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 818554e60537..0b459f7df23b 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -60,7 +60,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) n = rdev->mc.gtt_size - rdev->gart_pin_size; n /= size; - gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL); + gtt_obj = kzalloc_objs(*gtt_obj, n); if (!gtt_obj) { DRM_ERROR("Failed to allocate %d pointers\n", n); r = 1; diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 695ac32f7535..e7ab8162ac69 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -492,7 +492,7 @@ static struct ttm_tt *radeon_ttm_tt_create(struct ttm_buffer_object *bo, #endif rbo = container_of(bo, struct radeon_bo, tbo); - gtt = kzalloc(sizeof(struct radeon_ttm_tt), GFP_KERNEL); + gtt = kzalloc_obj(struct radeon_ttm_tt); if (gtt == NULL) { return NULL; } @@ -533,7 +533,7 @@ static int radeon_ttm_tt_populate(struct ttm_device *bdev, bool slave = !!(ttm->page_flags & TTM_TT_FLAG_EXTERNAL); if (gtt && gtt->userptr) { - ttm->sg = kzalloc(sizeof(struct sg_table), GFP_KERNEL); + ttm->sg = kzalloc_obj(struct sg_table); if (!ttm->sg) return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index 21a5340aefdf..45207310048b 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c @@ -133,8 +133,7 @@ struct radeon_bo_list *radeon_vm_get_bos(struct radeon_device *rdev, struct radeon_bo_list *list; unsigned i, idx; - list = kvmalloc_array(vm->max_pde_used + 2, - sizeof(struct radeon_bo_list), GFP_KERNEL); + list = kvmalloc_objs(struct radeon_bo_list, vm->max_pde_used + 2); if (!list) return NULL; @@ -321,7 +320,7 @@ struct radeon_bo_va *radeon_vm_bo_add(struct radeon_device *rdev, { struct radeon_bo_va *bo_va; - bo_va = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); + bo_va = kzalloc_obj(struct radeon_bo_va); if (bo_va == NULL) return NULL; @@ -495,7 +494,7 @@ int radeon_vm_bo_set_addr(struct radeon_device *rdev, if (bo_va->it.start || bo_va->it.last) { /* add a clone of the bo_va to clear the old address */ struct radeon_bo_va *tmp; - tmp = kzalloc(sizeof(struct radeon_bo_va), GFP_KERNEL); + tmp = kzalloc_obj(struct radeon_bo_va); if (!tmp) { mutex_unlock(&vm->mutex); r = -ENOMEM; diff --git a/drivers/gpu/drm/radeon/rs780_dpm.c b/drivers/gpu/drm/radeon/rs780_dpm.c index 24ad12409120..64bb4cafb8b5 100644 --- a/drivers/gpu/drm/radeon/rs780_dpm.c +++ b/drivers/gpu/drm/radeon/rs780_dpm.c @@ -804,9 +804,8 @@ static int rs780_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + power_info->pplib.ucNumStates); if (!rdev->pm.dpm.ps) return -ENOMEM; @@ -826,7 +825,7 @@ static int rs780_parse_power_table(struct radeon_device *rdev) le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + (power_state->v1.ucClockStateIndices[0] * power_info->pplib.ucClockInfoSize)); - ps = kzalloc(sizeof(struct igp_ps), GFP_KERNEL); + ps = kzalloc_obj(struct igp_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -853,7 +852,7 @@ int rs780_dpm_init(struct radeon_device *rdev) u8 frev, crev; int ret; - pi = kzalloc(sizeof(struct igp_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct igp_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c index 69d380fff22a..c734370e5336 100644 --- a/drivers/gpu/drm/radeon/rv6xx_dpm.c +++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c @@ -1887,9 +1887,8 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + power_info->pplib.ucNumStates); if (!rdev->pm.dpm.ps) return -ENOMEM; @@ -1905,7 +1904,7 @@ static int rv6xx_parse_power_table(struct radeon_device *rdev) power_info->pplib.ucNonClockSize)); if (power_info->pplib.ucStateEntrySize - 1) { u8 *idx; - ps = kzalloc(sizeof(struct rv6xx_ps), GFP_KERNEL); + ps = kzalloc_obj(struct rv6xx_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -1936,7 +1935,7 @@ int rv6xx_dpm_init(struct radeon_device *rdev) struct rv6xx_power_info *pi; int ret; - pi = kzalloc(sizeof(struct rv6xx_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct rv6xx_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/radeon/rv770_dpm.c b/drivers/gpu/drm/radeon/rv770_dpm.c index e3e1f6833f12..5f5cf5dd1d58 100644 --- a/drivers/gpu/drm/radeon/rv770_dpm.c +++ b/drivers/gpu/drm/radeon/rv770_dpm.c @@ -2283,9 +2283,8 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) return -EINVAL; power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - rdev->pm.dpm.ps = kcalloc(power_info->pplib.ucNumStates, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + power_info->pplib.ucNumStates); if (!rdev->pm.dpm.ps) return -ENOMEM; @@ -2301,7 +2300,7 @@ int rv7xx_parse_power_table(struct radeon_device *rdev) power_info->pplib.ucNonClockSize)); if (power_info->pplib.ucStateEntrySize - 1) { u8 *idx; - ps = kzalloc(sizeof(struct rv7xx_ps), GFP_KERNEL); + ps = kzalloc_obj(struct rv7xx_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -2348,7 +2347,7 @@ int rv770_dpm_init(struct radeon_device *rdev) struct atom_clock_dividers dividers; int ret; - pi = kzalloc(sizeof(struct rv7xx_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct rv7xx_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 9deb91970d4d..b4aa49b1ac63 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c @@ -2419,7 +2419,7 @@ static int si_initialize_smc_dte_tables(struct radeon_device *rdev) if (dte_data->k <= 0) return -EINVAL; - dte_tables = kzalloc(sizeof(Smc_SIslands_DTE_Configuration), GFP_KERNEL); + dte_tables = kzalloc_obj(Smc_SIslands_DTE_Configuration); if (dte_tables == NULL) { si_pi->enable_dte = false; return -ENOMEM; @@ -2599,7 +2599,7 @@ static int si_initialize_smc_cac_tables(struct radeon_device *rdev) if (ni_pi->enable_cac == false) return 0; - cac_tables = kzalloc(sizeof(PP_SIslands_CacConfig), GFP_KERNEL); + cac_tables = kzalloc_obj(PP_SIslands_CacConfig); if (!cac_tables) return -ENOMEM; @@ -2794,7 +2794,7 @@ static int si_init_smc_spll_table(struct radeon_device *rdev) if (si_pi->spll_table_start == 0) return -EINVAL; - spll_table = kzalloc(sizeof(SMC_SISLANDS_SPLL_DIV_TABLE), GFP_KERNEL); + spll_table = kzalloc_obj(SMC_SISLANDS_SPLL_DIV_TABLE); if (spll_table == NULL) return -ENOMEM; @@ -2925,6 +2925,11 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev, max_sclk = 60000; max_mclk = 80000; } + if ((rdev->pdev->device == 0x666f) && + (rdev->pdev->revision == 0x00)) { + max_sclk = 80000; + max_mclk = 95000; + } } else if (rdev->family == CHIP_OLAND) { if ((rdev->pdev->revision == 0xC7) || (rdev->pdev->revision == 0x80) || @@ -5474,7 +5479,7 @@ static int si_initialize_mc_reg_table(struct radeon_device *rdev) u8 module_index = rv770_get_memory_module_index(rdev); int ret; - table = kzalloc(sizeof(struct atom_mc_reg_table), GFP_KERNEL); + table = kzalloc_obj(struct atom_mc_reg_table); if (!table) return -ENOMEM; @@ -6773,9 +6778,8 @@ static int si_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + state_array->ucNumEntries); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -6787,7 +6791,7 @@ static int si_parse_power_table(struct radeon_device *rdev) &non_clock_info_array->nonClockInfo[non_clock_array_index]; if (!rdev->pm.power_state[i].clock_info) return -EINVAL; - ps = kzalloc(sizeof(struct ni_ps), GFP_KERNEL); + ps = kzalloc_obj(struct ni_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -6844,7 +6848,7 @@ int si_dpm_init(struct radeon_device *rdev) struct pci_dev *root = rdev->pdev->bus->self; int ret; - si_pi = kzalloc(sizeof(struct si_power_info), GFP_KERNEL); + si_pi = kzalloc_obj(struct si_power_info); if (si_pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = si_pi; @@ -6894,9 +6898,7 @@ int si_dpm_init(struct radeon_device *rdev) return ret; rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries = - kcalloc(4, - sizeof(struct radeon_clock_voltage_dependency_entry), - GFP_KERNEL); + kzalloc_objs(struct radeon_clock_voltage_dependency_entry, 4); if (!rdev->pm.dpm.dyn_state.vddc_dependency_on_dispclk.entries) { r600_free_extended_power_table(rdev); return -ENOMEM; diff --git a/drivers/gpu/drm/radeon/sumo_dpm.c b/drivers/gpu/drm/radeon/sumo_dpm.c index b11f7c5bbcbe..acee6c82e9f0 100644 --- a/drivers/gpu/drm/radeon/sumo_dpm.c +++ b/drivers/gpu/drm/radeon/sumo_dpm.c @@ -1479,9 +1479,8 @@ static int sumo_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + state_array->ucNumEntries); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -1495,7 +1494,7 @@ static int sumo_parse_power_table(struct radeon_device *rdev) kfree(rdev->pm.dpm.ps); return -EINVAL; } - ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + ps = kzalloc_obj(struct sumo_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -1745,7 +1744,7 @@ int sumo_dpm_init(struct radeon_device *rdev) u32 hw_rev = (RREG32(HW_REV) & ATI_REV_ID_MASK) >> ATI_REV_ID_SHIFT; int ret; - pi = kzalloc(sizeof(struct sumo_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct sumo_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/radeon/trinity_dpm.c b/drivers/gpu/drm/radeon/trinity_dpm.c index b9a2c7ccc881..566615c877cc 100644 --- a/drivers/gpu/drm/radeon/trinity_dpm.c +++ b/drivers/gpu/drm/radeon/trinity_dpm.c @@ -1710,9 +1710,8 @@ static int trinity_parse_power_table(struct radeon_device *rdev) (mode_info->atom_context->bios + data_offset + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset)); - rdev->pm.dpm.ps = kcalloc(state_array->ucNumEntries, - sizeof(struct radeon_ps), - GFP_KERNEL); + rdev->pm.dpm.ps = kzalloc_objs(struct radeon_ps, + state_array->ucNumEntries); if (!rdev->pm.dpm.ps) return -ENOMEM; power_state_offset = (u8 *)state_array->states; @@ -1726,7 +1725,7 @@ static int trinity_parse_power_table(struct radeon_device *rdev) kfree(rdev->pm.dpm.ps); return -EINVAL; } - ps = kzalloc(sizeof(struct sumo_ps), GFP_KERNEL); + ps = kzalloc_obj(struct sumo_ps); if (ps == NULL) { kfree(rdev->pm.dpm.ps); return -ENOMEM; @@ -1903,7 +1902,7 @@ int trinity_dpm_init(struct radeon_device *rdev) struct trinity_power_info *pi; int ret, i; - pi = kzalloc(sizeof(struct trinity_power_info), GFP_KERNEL); + pi = kzalloc_obj(struct trinity_power_info); if (pi == NULL) return -ENOMEM; rdev->pm.dpm.priv = pi; diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c index 2e2906ab750b..28a5aa5a14d8 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_crtc.c @@ -1006,7 +1006,7 @@ static void rcar_du_crtc_reset(struct drm_crtc *crtc) crtc->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return; diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c index 6294443f6068..60e6f43b8ab2 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_kms.c @@ -381,7 +381,7 @@ struct drm_gem_object *rcar_du_gem_prime_import_sg_table(struct drm_device *dev, return drm_gem_dma_prime_import_sg_table(dev, attach, sgt); /* Create a DMA GEM buffer. */ - dma_obj = kzalloc(sizeof(*dma_obj), GFP_KERNEL); + dma_obj = kzalloc_obj(*dma_obj); if (!dma_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c index c546ab0805d6..01840feabdbe 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_plane.c @@ -721,7 +721,7 @@ static void rcar_du_plane_reset(struct drm_plane *plane) plane->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return; diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c index 7aa0373563a4..94c22d2db197 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_vsp.c @@ -404,7 +404,7 @@ rcar_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - copy = kzalloc(sizeof(*copy), GFP_KERNEL); + copy = kzalloc_obj(*copy); if (copy == NULL) return NULL; @@ -429,7 +429,7 @@ static void rcar_du_vsp_plane_reset(struct drm_plane *plane) plane->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return; @@ -488,7 +488,7 @@ int rcar_du_vsp_init(struct rcar_du_vsp *vsp, struct device_node *np, num_planes = rcdu->info->num_rpf; - vsp->planes = kcalloc(num_planes, sizeof(*vsp->planes), GFP_KERNEL); + vsp->planes = kzalloc_objs(*vsp->planes, num_planes); if (!vsp->planes) return -ENOMEM; diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c b/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c index 8cd37d7b8ae2..e5e6e6a156aa 100644 --- a/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c +++ b/drivers/gpu/drm/renesas/rcar-du/rcar_du_writeback.c @@ -57,7 +57,7 @@ static int rcar_du_wb_prepare_job(struct drm_writeback_connector *connector, if (!job->fb) return 0; - rjob = kzalloc(sizeof(*rjob), GFP_KERNEL); + rjob = kzalloc_obj(*rjob); if (!rjob) return -ENOMEM; @@ -99,7 +99,7 @@ rcar_du_wb_conn_duplicate_state(struct drm_connector *connector) if (WARN_ON(!connector->state)) return NULL; - copy = kzalloc(sizeof(*copy), GFP_KERNEL); + copy = kzalloc_obj(*copy); if (!copy) return NULL; @@ -124,7 +124,7 @@ static void rcar_du_wb_conn_reset(struct drm_connector *connector) connector->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c index 6e7aac6219be..18e2b981b691 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_crtc.c @@ -336,7 +336,7 @@ static void rzg2l_du_crtc_reset(struct drm_crtc *crtc) crtc->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c index 040d4e4aff00..bd486377f037 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_vsp.c @@ -249,7 +249,7 @@ rzg2l_du_vsp_plane_atomic_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - copy = kzalloc(sizeof(*copy), GFP_KERNEL); + copy = kzalloc_obj(*copy); if (!copy) return NULL; @@ -274,7 +274,7 @@ static void rzg2l_du_vsp_plane_reset(struct drm_plane *plane) plane->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return; diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c index f74a0aa85ba8..29f2b7d24fe5 100644 --- a/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c +++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_mipi_dsi.c @@ -1122,6 +1122,7 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host, struct mipi_dsi_device *device) { struct rzg2l_mipi_dsi *dsi = host_to_rzg2l_mipi_dsi(host); + int bpp; int ret; if (device->lanes > dsi->num_data_lanes) { @@ -1131,7 +1132,8 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host, return -EINVAL; } - switch (mipi_dsi_pixel_format_to_bpp(device->format)) { + bpp = mipi_dsi_pixel_format_to_bpp(device->format); + switch (bpp) { case 24: break; case 18: @@ -1162,6 +1164,18 @@ static int rzg2l_mipi_dsi_host_attach(struct mipi_dsi_host *host, drm_bridge_add(&dsi->bridge); + /* + * Report the required division ratio setting for the MIPI clock dividers. + * + * vclk * bpp = hsclk * 8 * num_lanes + * + * vclk * DSI_AB_divider = hsclk * 16 + * + * which simplifies to... + * DSI_AB_divider = bpp * 2 / num_lanes + */ + rzg2l_cpg_dsi_div_set_divider(bpp * 2 / dsi->lanes, PLL5_TARGET_DSI); + return 0; } diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c index 2e2f37b9d0a4..5f460b38596c 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c @@ -551,7 +551,7 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev, return ERR_PTR(-EINVAL); } - scon = kzalloc(sizeof(*scon), GFP_KERNEL); + scon = kzalloc_obj(*scon); if (!scon) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c index 9d166ab2af8b..b61fda52d17a 100644 --- a/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c +++ b/drivers/gpu/drm/renesas/shmobile/shmob_drm_plane.c @@ -260,7 +260,7 @@ static void shmob_drm_plane_reset(struct drm_plane *plane) plane->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index 2f469d370021..45588b79b3d4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -36,7 +36,7 @@ rockchip_fb_create(struct drm_device *dev, struct drm_file *file, struct drm_afbc_framebuffer *afbc_fb; int ret; - afbc_fb = kzalloc(sizeof(*afbc_fb), GFP_KERNEL); + afbc_fb = kzalloc_obj(*afbc_fb); if (!afbc_fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index df9a8bff2e22..09d14a072d27 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -289,7 +289,7 @@ static struct rockchip_gem_object * size = round_up(size, PAGE_SIZE); - rk_obj = kzalloc(sizeof(*rk_obj), GFP_KERNEL); + rk_obj = kzalloc_obj(*rk_obj); if (!rk_obj) return ERR_PTR(-ENOMEM); @@ -434,7 +434,7 @@ struct sg_table *rockchip_gem_prime_get_sg_table(struct drm_gem_object *obj) if (rk_obj->pages) return drm_prime_pages_to_sg(obj->dev, rk_obj->pages, rk_obj->num_pages); - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 1b466623b6c7..572f4adfd111 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1658,8 +1658,7 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc, static void vop_crtc_reset(struct drm_crtc *crtc) { - struct rockchip_crtc_state *crtc_state = - kzalloc(sizeof(*crtc_state), GFP_KERNEL); + struct rockchip_crtc_state *crtc_state = kzalloc_obj(*crtc_state); if (crtc->state) vop_crtc_destroy_state(crtc, crtc->state); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index ec3b4fde10db..a195f5c819a2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -2140,8 +2140,7 @@ static void vop2_crtc_destroy_state(struct drm_crtc *crtc, static void vop2_crtc_reset(struct drm_crtc *crtc) { - struct rockchip_crtc_state *vcstate = - kzalloc(sizeof(*vcstate), GFP_KERNEL); + struct rockchip_crtc_state *vcstate = kzalloc_obj(*vcstate); if (crtc->state) vop2_crtc_destroy_state(crtc, crtc->state); diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c index bd7936c03da2..2d5cb21a05b6 100644 --- a/drivers/gpu/drm/scheduler/sched_main.c +++ b/drivers/gpu/drm/scheduler/sched_main.c @@ -361,6 +361,7 @@ static void drm_sched_run_free_queue(struct drm_gpu_scheduler *sched) /** * drm_sched_job_done - complete a job * @s_job: pointer to the job which is done + * @result: 0 on success, -ERRNO on error * * Finish the job's fence and resubmit the work items. */ @@ -1352,13 +1353,13 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, const struct drm_sched_init_ sched->own_submit_wq = true; } - sched->sched_rq = kmalloc_array(args->num_rqs, sizeof(*sched->sched_rq), - GFP_KERNEL | __GFP_ZERO); + sched->sched_rq = kmalloc_objs(*sched->sched_rq, args->num_rqs, + GFP_KERNEL | __GFP_ZERO); if (!sched->sched_rq) goto Out_check_own; sched->num_rqs = args->num_rqs; for (i = DRM_SCHED_PRIORITY_KERNEL; i < sched->num_rqs; i++) { - sched->sched_rq[i] = kzalloc(sizeof(*sched->sched_rq[i]), GFP_KERNEL); + sched->sched_rq[i] = kzalloc_obj(*sched->sched_rq[i]); if (!sched->sched_rq[i]) goto Out_unroll; drm_sched_rq_init(sched, sched->sched_rq[i]); diff --git a/drivers/gpu/drm/sitronix/st7586.c b/drivers/gpu/drm/sitronix/st7586.c index b57ebf37a664..16b6b4e368af 100644 --- a/drivers/gpu/drm/sitronix/st7586.c +++ b/drivers/gpu/drm/sitronix/st7586.c @@ -347,6 +347,12 @@ static int st7586_probe(struct spi_device *spi) if (ret) return ret; + /* + * Override value set by mipi_dbi_spi_init(). This driver is a bit + * non-standard, so best to set it explicitly here. + */ + dbi->write_memory_bpw = 8; + /* Cannot read from this controller via SPI */ dbi->read_commands = NULL; @@ -356,15 +362,6 @@ static int st7586_probe(struct spi_device *spi) if (ret) return ret; - /* - * we are using 8-bit data, so we are not actually swapping anything, - * but setting mipi->swap_bytes makes mipi_dbi_typec3_command() do the - * right thing and not use 16-bit transfers (which results in swapped - * bytes on little-endian systems and causes out of order data to be - * sent to the display). - */ - dbi->swap_bytes = true; - drm_mode_config_reset(drm); ret = drm_dev_register(drm, 0); diff --git a/drivers/gpu/drm/sitronix/st7920.c b/drivers/gpu/drm/sitronix/st7920.c index f35a157fdad8..18fe7a28ed07 100644 --- a/drivers/gpu/drm/sitronix/st7920.c +++ b/drivers/gpu/drm/sitronix/st7920.c @@ -459,7 +459,7 @@ static void st7920_primary_plane_reset(struct drm_plane *plane) drm_WARN_ON_ONCE(plane->dev, plane->state); - st7920_state = kzalloc(sizeof(*st7920_state), GFP_KERNEL); + st7920_state = kzalloc_obj(*st7920_state); if (!st7920_state) return; @@ -474,7 +474,7 @@ static struct drm_plane_state *st7920_primary_plane_duplicate_state(struct drm_p if (drm_WARN_ON_ONCE(plane->dev, !plane->state)) return NULL; - st7920_state = kzalloc(sizeof(*st7920_state), GFP_KERNEL); + st7920_state = kzalloc_obj(*st7920_state); if (!st7920_state) return NULL; @@ -581,7 +581,7 @@ static void st7920_crtc_reset(struct drm_crtc *crtc) drm_WARN_ON_ONCE(crtc->dev, crtc->state); - st7920_state = kzalloc(sizeof(*st7920_state), GFP_KERNEL); + st7920_state = kzalloc_obj(*st7920_state); if (!st7920_state) return; @@ -595,7 +595,7 @@ static struct drm_crtc_state *st7920_crtc_duplicate_state(struct drm_crtc *crtc) if (drm_WARN_ON_ONCE(crtc->dev, !crtc->state)) return NULL; - st7920_state = kzalloc(sizeof(*st7920_state), GFP_KERNEL); + st7920_state = kzalloc_obj(*st7920_state); if (!st7920_state) return NULL; diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 96cf39320137..c77455b1834d 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -737,6 +737,7 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, unsigned int height = drm_rect_height(rect); unsigned int line_length = DIV_ROUND_UP(width, 8); unsigned int page_height = SSD130X_PAGE_HEIGHT; + u8 page_start = ssd130x->page_offset + y / page_height; unsigned int pages = DIV_ROUND_UP(height, page_height); struct drm_device *drm = &ssd130x->drm; u32 array_idx = 0; @@ -774,14 +775,11 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, */ if (!ssd130x->page_address_mode) { - u8 page_start; - /* Set address range for horizontal addressing mode */ ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); if (ret < 0) return ret; - page_start = ssd130x->page_offset + y / page_height; ret = ssd130x_set_page_range(ssd130x, page_start, pages); if (ret < 0) return ret; @@ -813,7 +811,7 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, */ if (ssd130x->page_address_mode) { ret = ssd130x_set_page_pos(ssd130x, - ssd130x->page_offset + i, + page_start + i, ssd130x->col_offset + x); if (ret < 0) return ret; @@ -1396,7 +1394,7 @@ static void ssd130x_primary_plane_reset(struct drm_plane *plane) drm_WARN_ON_ONCE(plane->dev, plane->state); - ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL); + ssd130x_state = kzalloc_obj(*ssd130x_state); if (!ssd130x_state) return; @@ -1553,7 +1551,7 @@ static void ssd130x_crtc_reset(struct drm_crtc *crtc) drm_WARN_ON_ONCE(crtc->dev, crtc->state); - ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL); + ssd130x_state = kzalloc_obj(*ssd130x_state); if (!ssd130x_state) return; diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index f16345f01065..d02d71866f2a 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c @@ -151,7 +151,7 @@ static int sti_init(struct drm_device *ddev) { struct sti_private *private; - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (!private) return -ENOMEM; diff --git a/drivers/gpu/drm/sun4i/sun4i_layer.c b/drivers/gpu/drm/sun4i/sun4i_layer.c index 98f3176366c0..63cb8c7c3636 100644 --- a/drivers/gpu/drm/sun4i/sun4i_layer.c +++ b/drivers/gpu/drm/sun4i/sun4i_layer.c @@ -29,7 +29,7 @@ static void sun4i_backend_layer_reset(struct drm_plane *plane) plane->state = NULL; } - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) __drm_atomic_helper_plane_reset(plane, &state->state); } @@ -40,7 +40,7 @@ sun4i_backend_layer_duplicate_state(struct drm_plane *plane) struct sun4i_layer_state *orig = state_to_sun4i_layer_state(plane->state); struct sun4i_layer_state *copy; - copy = kzalloc(sizeof(*copy), GFP_KERNEL); + copy = kzalloc_obj(*copy); if (!copy) return NULL; diff --git a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c index 6214b7709b37..808b1eda871a 100644 --- a/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c +++ b/drivers/gpu/drm/sysfb/drm_sysfb_modeset.c @@ -427,7 +427,7 @@ void drm_sysfb_plane_reset(struct drm_plane *plane) if (plane->state) drm_sysfb_plane_state_destroy(to_drm_sysfb_plane_state(plane->state)); - sysfb_plane_state = kzalloc(sizeof(*sysfb_plane_state), GFP_KERNEL); + sysfb_plane_state = kzalloc_obj(*sysfb_plane_state); if (sysfb_plane_state) __drm_gem_reset_shadow_plane(plane, &sysfb_plane_state->base); else @@ -447,7 +447,7 @@ struct drm_plane_state *drm_sysfb_plane_atomic_duplicate_state(struct drm_plane return NULL; sysfb_plane_state = to_drm_sysfb_plane_state(plane_state); - new_sysfb_plane_state = kzalloc(sizeof(*new_sysfb_plane_state), GFP_KERNEL); + new_sysfb_plane_state = kzalloc_obj(*new_sysfb_plane_state); if (!new_sysfb_plane_state) return NULL; new_shadow_plane_state = &new_sysfb_plane_state->base; @@ -523,7 +523,7 @@ void drm_sysfb_crtc_reset(struct drm_crtc *crtc) if (crtc->state) drm_sysfb_crtc_state_destroy(to_drm_sysfb_crtc_state(crtc->state)); - sysfb_crtc_state = kzalloc(sizeof(*sysfb_crtc_state), GFP_KERNEL); + sysfb_crtc_state = kzalloc_obj(*sysfb_crtc_state); if (sysfb_crtc_state) { sysfb_crtc_state->format = sysfb->fb_format; __drm_atomic_helper_crtc_reset(crtc, &sysfb_crtc_state->base); @@ -543,7 +543,7 @@ struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *cr if (drm_WARN_ON(dev, !crtc_state)) return NULL; - new_sysfb_crtc_state = kzalloc(sizeof(*new_sysfb_crtc_state), GFP_KERNEL); + new_sysfb_crtc_state = kzalloc_obj(*new_sysfb_crtc_state); if (!new_sysfb_crtc_state) return NULL; diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index 01e9d5011dd8..06370b7e0e56 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -812,7 +812,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, const u32 *formats; int err; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -1115,7 +1115,7 @@ static struct drm_plane *tegra_dc_cursor_plane_create(struct drm_device *drm, const u32 *formats; int err; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -1263,7 +1263,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, const u32 *formats; int err; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -1389,7 +1389,7 @@ static void tegra_dc_destroy(struct drm_crtc *crtc) static void tegra_crtc_reset(struct drm_crtc *crtc) { - struct tegra_dc_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct tegra_dc_state *state = kzalloc_obj(*state); if (crtc->state) tegra_crtc_atomic_destroy_state(crtc, crtc->state); @@ -1406,7 +1406,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc) struct tegra_dc_state *state = to_dc_state(crtc->state); struct tegra_dc_state *copy; - copy = kmalloc(sizeof(*copy), GFP_KERNEL); + copy = kmalloc_obj(*copy); if (!copy) return NULL; diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c index f7222819d672..1dcef4e7d104 100644 --- a/drivers/gpu/drm/tegra/drm.c +++ b/drivers/gpu/drm/tegra/drm.c @@ -104,7 +104,7 @@ static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp) { struct tegra_drm_file *fpriv; - fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); + fpriv = kzalloc_obj(*fpriv); if (!fpriv) return -ENOMEM; @@ -212,7 +212,7 @@ int tegra_drm_submit(struct tegra_drm_context *context, */ num_refs = num_cmdbufs + num_relocs * 2; - refs = kmalloc_array(num_refs, sizeof(*refs), GFP_KERNEL); + refs = kmalloc_objs(*refs, num_refs); if (!refs) { err = -ENOMEM; goto put; @@ -465,7 +465,7 @@ static int tegra_open_channel(struct drm_device *drm, void *data, struct tegra_drm_client *client; int err = -ENODEV; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return -ENOMEM; @@ -1147,7 +1147,7 @@ static int host1x_drm_probe(struct host1x_device *dev) if (IS_ERR(drm)) return PTR_ERR(drm); - tegra = kzalloc(sizeof(*tegra), GFP_KERNEL); + tegra = kzalloc_obj(*tegra); if (!tegra) { err = -ENOMEM; goto put; diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 8ee96b59fdbc..2c5aefe9621a 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c @@ -772,7 +772,7 @@ static void tegra_dsi_soft_reset(struct tegra_dsi *dsi) static void tegra_dsi_connector_reset(struct drm_connector *connector) { - struct tegra_dsi_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct tegra_dsi_state *state = kzalloc_obj(*state); if (!state) return; diff --git a/drivers/gpu/drm/tegra/fb.c b/drivers/gpu/drm/tegra/fb.c index 1cef8c5cac50..1e4803d355dd 100644 --- a/drivers/gpu/drm/tegra/fb.c +++ b/drivers/gpu/drm/tegra/fb.c @@ -112,7 +112,7 @@ struct drm_framebuffer *tegra_fb_alloc(struct drm_device *drm, unsigned int i; int err; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/tegra/gem.c b/drivers/gpu/drm/tegra/gem.c index 6b14f1e919eb..d2bae88ad545 100644 --- a/drivers/gpu/drm/tegra/gem.c +++ b/drivers/gpu/drm/tegra/gem.c @@ -64,7 +64,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ struct host1x_bo_mapping *map; int err; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return ERR_PTR(-ENOMEM); @@ -103,7 +103,7 @@ static struct host1x_bo_mapping *tegra_bo_pin(struct device *dev, struct host1x_ * If we don't have a mapping for this buffer yet, return an SG table * so that host1x can do the mapping for us via the DMA API. */ - map->sgt = kzalloc(sizeof(*map->sgt), GFP_KERNEL); + map->sgt = kzalloc_obj(*map->sgt); if (!map->sgt) { err = -ENOMEM; goto free; @@ -240,7 +240,7 @@ static int tegra_bo_iommu_map(struct tegra_drm *tegra, struct tegra_bo *bo) if (bo->mm) return -EBUSY; - bo->mm = kzalloc(sizeof(*bo->mm), GFP_KERNEL); + bo->mm = kzalloc_obj(*bo->mm); if (!bo->mm) return -ENOMEM; @@ -302,7 +302,7 @@ static struct tegra_bo *tegra_bo_alloc_object(struct drm_device *drm, struct tegra_bo *bo; int err; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); @@ -639,7 +639,7 @@ tegra_gem_prime_map_dma_buf(struct dma_buf_attachment *attach, struct tegra_bo *bo = to_tegra_bo(gem); struct sg_table *sgt; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return NULL; diff --git a/drivers/gpu/drm/tegra/hub.c b/drivers/gpu/drm/tegra/hub.c index c924ffba4094..a6fa196c2813 100644 --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -769,7 +769,7 @@ struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, const u32 *formats; int err; - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -943,7 +943,7 @@ static int tegra_display_hub_init(struct host1x_client *client) struct tegra_drm *tegra = drm->dev_private; struct tegra_display_hub_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index ffe5f06b770d..0cb30910773f 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c @@ -36,7 +36,7 @@ static void tegra_plane_reset(struct drm_plane *plane) kfree(plane->state); plane->state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state) { plane->state = &state->base; plane->state->plane = plane; @@ -55,7 +55,7 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane) struct tegra_plane_state *copy; unsigned int i; - copy = kmalloc(sizeof(*copy), GFP_KERNEL); + copy = kmalloc_obj(*copy); if (!copy) return NULL; diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c index 4023cb5998f1..de8b2dfc4984 100644 --- a/drivers/gpu/drm/tegra/sor.c +++ b/drivers/gpu/drm/tegra/sor.c @@ -1721,7 +1721,7 @@ static void tegra_sor_connector_reset(struct drm_connector *connector) { struct tegra_sor_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return; diff --git a/drivers/gpu/drm/tegra/submit.c b/drivers/gpu/drm/tegra/submit.c index 2430fcc97448..3009b8b9e619 100644 --- a/drivers/gpu/drm/tegra/submit.c +++ b/drivers/gpu/drm/tegra/submit.c @@ -71,7 +71,7 @@ gather_bo_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direction struct host1x_bo_mapping *map; int err; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return ERR_PTR(-ENOMEM); @@ -80,7 +80,7 @@ gather_bo_pin(struct device *dev, struct host1x_bo *bo, enum dma_data_direction map->direction = direction; map->dev = dev; - map->sgt = kzalloc(sizeof(*map->sgt), GFP_KERNEL); + map->sgt = kzalloc_obj(*map->sgt); if (!map->sgt) { err = -ENOMEM; goto free; @@ -193,7 +193,7 @@ static int submit_copy_gather_data(struct gather_bo **pbo, struct device *dev, return -EINVAL; } - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) { SUBMIT_ERR(context, "failed to allocate memory for bo info"); return -ENOMEM; @@ -270,7 +270,7 @@ static int submit_process_bufs(struct tegra_drm_context *context, struct gather_ return PTR_ERR(bufs); } - mappings = kcalloc(args->num_bufs, sizeof(*mappings), GFP_KERNEL); + mappings = kzalloc_objs(*mappings, args->num_bufs); if (!mappings) { SUBMIT_ERR(context, "failed to allocate memory for mapping info"); err = -ENOMEM; @@ -560,7 +560,7 @@ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data, if (err) goto unlock; - job_data = kzalloc(sizeof(*job_data), GFP_KERNEL); + job_data = kzalloc_obj(*job_data); if (!job_data) { SUBMIT_ERR(context, "failed to allocate memory for job data"); err = -ENOMEM; diff --git a/drivers/gpu/drm/tegra/uapi.c b/drivers/gpu/drm/tegra/uapi.c index d0b6a1fa6efa..c0ac6b45f2d7 100644 --- a/drivers/gpu/drm/tegra/uapi.c +++ b/drivers/gpu/drm/tegra/uapi.c @@ -86,7 +86,7 @@ int tegra_drm_ioctl_channel_open(struct drm_device *drm, void *data, struct drm_ if (args->flags) return -EINVAL; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return -ENOMEM; @@ -206,7 +206,7 @@ int tegra_drm_ioctl_channel_map(struct drm_device *drm, void *data, struct drm_f return -EINVAL; } - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) { err = -ENOMEM; goto unlock; diff --git a/drivers/gpu/drm/tests/drm_gem_shmem_test.c b/drivers/gpu/drm/tests/drm_gem_shmem_test.c index 4b459f21acfd..44a190109249 100644 --- a/drivers/gpu/drm/tests/drm_gem_shmem_test.c +++ b/drivers/gpu/drm/tests/drm_gem_shmem_test.c @@ -80,7 +80,7 @@ static void drm_gem_shmem_test_obj_create_private(struct kunit *test) buf = kunit_kzalloc(test, TEST_SIZE, GFP_KERNEL); KUNIT_ASSERT_NOT_NULL(test, buf); - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); KUNIT_ASSERT_NOT_NULL(test, sgt); ret = kunit_add_action_or_reset(test, kfree_wrapper, sgt); diff --git a/drivers/gpu/drm/tests/drm_mm_test.c b/drivers/gpu/drm/tests/drm_mm_test.c index aec9eccdeae9..f4f473f87838 100644 --- a/drivers/gpu/drm/tests/drm_mm_test.c +++ b/drivers/gpu/drm/tests/drm_mm_test.c @@ -252,7 +252,7 @@ static void drm_test_mm_align_pot(struct kunit *test, int max) for (bit = max - 1; bit; bit--) { u64 align, size; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) { KUNIT_FAIL(test, "failed to allocate node"); goto out; diff --git a/drivers/gpu/drm/tests/drm_panic_test.c b/drivers/gpu/drm/tests/drm_panic_test.c index d60150877df8..ad2f3a2f93b6 100644 --- a/drivers/gpu/drm/tests/drm_panic_test.c +++ b/drivers/gpu/drm/tests/drm_panic_test.c @@ -127,7 +127,7 @@ static void drm_test_panic_screen_user_page(struct kunit *test) fb_size = params->width * params->height * sb->format->cpp[0]; npages = DIV_ROUND_UP(fb_size, PAGE_SIZE); - pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, npages); KUNIT_ASSERT_NOT_NULL(test, pages); for (p = 0; p < npages; p++) { diff --git a/drivers/gpu/drm/tidss/tidss_crtc.c b/drivers/gpu/drm/tidss/tidss_crtc.c index 8f81eb560b9e..a31c21c5f855 100644 --- a/drivers/gpu/drm/tidss/tidss_crtc.c +++ b/drivers/gpu/drm/tidss/tidss_crtc.c @@ -364,7 +364,7 @@ static void tidss_crtc_reset(struct drm_crtc *crtc) if (crtc->state) tidss_crtc_destroy_state(crtc, crtc->state); - tstate = kzalloc(sizeof(*tstate), GFP_KERNEL); + tstate = kzalloc_obj(*tstate); if (!tstate) { crtc->state = NULL; return; @@ -382,7 +382,7 @@ static struct drm_crtc_state *tidss_crtc_duplicate_state(struct drm_crtc *crtc) current_state = to_tidss_crtc_state(crtc->state); - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; @@ -425,7 +425,7 @@ struct tidss_crtc *tidss_crtc_create(struct tidss_device *tidss, bool has_ctm = tidss->feat->vp_feat.color.has_ctm; int ret; - tcrtc = kzalloc(sizeof(*tcrtc), GFP_KERNEL); + tcrtc = kzalloc_obj(*tcrtc); if (!tcrtc) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/tidss/tidss_plane.c b/drivers/gpu/drm/tidss/tidss_plane.c index bd10bc1b9961..aaa02c851c59 100644 --- a/drivers/gpu/drm/tidss/tidss_plane.c +++ b/drivers/gpu/drm/tidss/tidss_plane.c @@ -203,7 +203,7 @@ struct tidss_plane *tidss_plane_create(struct tidss_device *tidss, BIT(DRM_MODE_BLEND_COVERAGE)); int ret; - tplane = kzalloc(sizeof(*tplane), GFP_KERNEL); + tplane = kzalloc_obj(*tplane); if (!tplane) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/tilcdc/tilcdc_panel.c b/drivers/gpu/drm/tilcdc/tilcdc_panel.c index 262f290d85d9..1de3996501f7 100644 --- a/drivers/gpu/drm/tilcdc/tilcdc_panel.c +++ b/drivers/gpu/drm/tilcdc/tilcdc_panel.c @@ -272,7 +272,7 @@ static struct tilcdc_panel_info *of_get_panel_info(struct device_node *np) return NULL; } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) goto put_node; diff --git a/drivers/gpu/drm/tiny/appletbdrm.c b/drivers/gpu/drm/tiny/appletbdrm.c index 751b05753c94..3bae91d7eefe 100644 --- a/drivers/gpu/drm/tiny/appletbdrm.c +++ b/drivers/gpu/drm/tiny/appletbdrm.c @@ -225,7 +225,7 @@ static int appletbdrm_send_msg(struct appletbdrm_device *adev, __le32 msg) struct appletbdrm_msg_simple_request *request; int ret; - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) return -ENOMEM; @@ -260,7 +260,7 @@ static int appletbdrm_get_information(struct appletbdrm_device *adev) __le32 pixel_format; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -358,7 +358,7 @@ static int appletbdrm_primary_plane_helper_atomic_check(struct drm_plane *plane, if (!appletbdrm_state->request) return -ENOMEM; - appletbdrm_state->response = kzalloc(sizeof(*appletbdrm_state->response), GFP_KERNEL); + appletbdrm_state->response = kzalloc_obj(*appletbdrm_state->response); if (!appletbdrm_state->response) return -ENOMEM; @@ -505,7 +505,7 @@ static void appletbdrm_primary_plane_reset(struct drm_plane *plane) WARN_ON(plane->state); - appletbdrm_state = kzalloc(sizeof(*appletbdrm_state), GFP_KERNEL); + appletbdrm_state = kzalloc_obj(*appletbdrm_state); if (!appletbdrm_state) return; @@ -520,7 +520,7 @@ static struct drm_plane_state *appletbdrm_primary_plane_duplicate_state(struct d if (WARN_ON(!plane->state)) return NULL; - appletbdrm_state = kzalloc(sizeof(*appletbdrm_state), GFP_KERNEL); + appletbdrm_state = kzalloc_obj(*appletbdrm_state); if (!appletbdrm_state) return NULL; diff --git a/drivers/gpu/drm/tiny/sharp-memory.c b/drivers/gpu/drm/tiny/sharp-memory.c index 64272cd0f6e2..cbf69460ebf3 100644 --- a/drivers/gpu/drm/tiny/sharp-memory.c +++ b/drivers/gpu/drm/tiny/sharp-memory.c @@ -541,8 +541,8 @@ static int sharp_memory_probe(struct spi_device *spi) smd = devm_drm_dev_alloc(dev, &sharp_memory_drm_driver, struct sharp_memory_device, drm); - if (!smd) - return -ENOMEM; + if (IS_ERR(smd)) + return PTR_ERR(smd); spi_set_drvdata(spi, smd); diff --git a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c index d468f8322072..f3103307b5df 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_bo_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_bo_test.c @@ -222,13 +222,13 @@ static void ttm_bo_reserve_interrupted(struct kunit *test) KUNIT_FAIL(test, "Couldn't create ttm bo reserve task\n"); /* Take a lock so the threaded reserve has to wait */ - mutex_lock(&bo->base.resv->lock.base); + dma_resv_lock(bo->base.resv, NULL); wake_up_process(task); msleep(20); err = kthread_stop(task); - mutex_unlock(&bo->base.resv->lock.base); + dma_resv_unlock(bo->base.resv); KUNIT_ASSERT_EQ(test, err, -ERESTARTSYS); } diff --git a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c index 7b533e4e1e04..5cfe8f3f80d7 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c +++ b/drivers/gpu/drm/ttm/tests/ttm_kunit_helpers.c @@ -49,7 +49,7 @@ static struct ttm_tt *ttm_tt_simple_create(struct ttm_buffer_object *bo, u32 pag { struct ttm_tt *tt; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); ttm_tt_init(tt, bo, page_flags, ttm_cached, 0); return tt; diff --git a/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c b/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c index dd395229e388..c97e8b7a4e7a 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c +++ b/drivers/gpu/drm/ttm/tests/ttm_mock_manager.c @@ -35,7 +35,7 @@ static int ttm_mock_manager_alloc(struct ttm_resource_manager *man, u64 lpfn, fpfn, alloc_size; int err; - mock_res = kzalloc(sizeof(*mock_res), GFP_KERNEL); + mock_res = kzalloc_obj(*mock_res); if (!mock_res) return -ENOMEM; @@ -100,7 +100,7 @@ int ttm_mock_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size) struct ttm_resource_manager *base; int err; - manager = kzalloc(sizeof(*manager), GFP_KERNEL); + manager = kzalloc_obj(*manager); if (!manager) return -ENOMEM; @@ -194,7 +194,7 @@ int ttm_bad_manager_init(struct ttm_device *bdev, u32 mem_type, u32 size) { struct ttm_resource_manager *man; - man = kzalloc(sizeof(*man), GFP_KERNEL); + man = kzalloc_obj(*man); if (!man) return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/tests/ttm_tt_test.c b/drivers/gpu/drm/ttm/tests/ttm_tt_test.c index 61ec6f580b62..bd5f7d0b9b62 100644 --- a/drivers/gpu/drm/ttm/tests/ttm_tt_test.c +++ b/drivers/gpu/drm/ttm/tests/ttm_tt_test.c @@ -143,7 +143,7 @@ static void ttm_tt_fini_shmem(struct kunit *test) err = ttm_tt_init(tt, bo, 0, caching, 0); KUNIT_ASSERT_EQ(test, err, 0); - shmem = shmem_file_setup("ttm swap", BO_SIZE, 0); + shmem = shmem_file_setup("ttm swap", BO_SIZE, EMPTY_VMA_FLAGS); tt->swap_storage = shmem; ttm_tt_fini(tt); diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index fca0a1a3c6fd..147e25ee53ba 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c @@ -128,7 +128,7 @@ struct ttm_tt *ttm_agp_tt_create(struct ttm_buffer_object *bo, { struct ttm_agp_backend *agp_be; - agp_be = kmalloc(sizeof(*agp_be), GFP_KERNEL); + agp_be = kmalloc_obj(*agp_be); if (!agp_be) return NULL; diff --git a/drivers/gpu/drm/ttm/ttm_backup.c b/drivers/gpu/drm/ttm/ttm_backup.c index 32530c75f038..6bd4c123d94c 100644 --- a/drivers/gpu/drm/ttm/ttm_backup.c +++ b/drivers/gpu/drm/ttm/ttm_backup.c @@ -178,5 +178,6 @@ EXPORT_SYMBOL_GPL(ttm_backup_bytes_avail); */ struct file *ttm_backup_shmem_create(loff_t size) { - return shmem_file_setup("ttm shmem backup", size, 0); + return shmem_file_setup("ttm shmem backup", size, + EMPTY_VMA_FLAGS); } diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index acb9197db879..0765d69423d2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1107,8 +1107,7 @@ struct ttm_bo_swapout_walk { static s64 ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) { - struct ttm_resource *res = bo->resource; - struct ttm_place place = { .mem_type = res->mem_type }; + struct ttm_place place = { .mem_type = bo->resource->mem_type }; struct ttm_bo_swapout_walk *swapout_walk = container_of(walk, typeof(*swapout_walk), walk); struct ttm_operation_ctx *ctx = walk->arg.ctx; @@ -1148,7 +1147,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) /* * Move to system cached */ - if (res->mem_type != TTM_PL_SYSTEM) { + if (bo->resource->mem_type != TTM_PL_SYSTEM) { struct ttm_resource *evict_mem; struct ttm_place hop; @@ -1180,15 +1179,15 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) if (ttm_tt_is_populated(tt)) { spin_lock(&bdev->lru_lock); - ttm_resource_del_bulk_move(res, bo); + ttm_resource_del_bulk_move(bo->resource, bo); spin_unlock(&bdev->lru_lock); ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags); spin_lock(&bdev->lru_lock); if (ret) - ttm_resource_add_bulk_move(res, bo); - ttm_resource_move_to_lru_tail(res); + ttm_resource_add_bulk_move(bo->resource, bo); + ttm_resource_move_to_lru_tail(bo->resource); spin_unlock(&bdev->lru_lock); } diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index cabcfeaa70dc..f83b7d5ec6c6 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -233,7 +233,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, struct ttm_transfer_obj *fbo; int ret; - fbo = kmalloc(sizeof(*fbo), GFP_KERNEL); + fbo = kmalloc_obj(*fbo); if (!fbo) return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/ttm_pool.c b/drivers/gpu/drm/ttm/ttm_pool.c index 217e45958099..c0d95559197c 100644 --- a/drivers/gpu/drm/ttm/ttm_pool.c +++ b/drivers/gpu/drm/ttm/ttm_pool.c @@ -164,7 +164,7 @@ static struct page *ttm_pool_alloc_page(struct ttm_pool *pool, gfp_t gfp_flags, return p; } - dma = kmalloc(sizeof(*dma), GFP_KERNEL); + dma = kmalloc_obj(*dma); if (!dma) return NULL; @@ -858,7 +858,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, if (ctx->gfp_retry_mayfail) gfp |= __GFP_RETRY_MAYFAIL; - restore = kzalloc(sizeof(*restore), gfp); + restore = kzalloc_obj(*restore, gfp); if (!restore) return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/ttm_pool_internal.h b/drivers/gpu/drm/ttm/ttm_pool_internal.h index 82c4b7e56a99..24c179fd69d1 100644 --- a/drivers/gpu/drm/ttm/ttm_pool_internal.h +++ b/drivers/gpu/drm/ttm/ttm_pool_internal.h @@ -17,7 +17,7 @@ static inline bool ttm_pool_uses_dma32(struct ttm_pool *pool) return pool->alloc_flags & TTM_ALLOCATION_POOL_USE_DMA32; } -static inline bool ttm_pool_beneficial_order(struct ttm_pool *pool) +static inline unsigned int ttm_pool_beneficial_order(struct ttm_pool *pool) { return pool->alloc_flags & 0xff; } diff --git a/drivers/gpu/drm/ttm/ttm_range_manager.c b/drivers/gpu/drm/ttm/ttm_range_manager.c index db854b581d83..b818836f0726 100644 --- a/drivers/gpu/drm/ttm/ttm_range_manager.c +++ b/drivers/gpu/drm/ttm/ttm_range_manager.c @@ -73,7 +73,7 @@ static int ttm_range_man_alloc(struct ttm_resource_manager *man, if (!lpfn) lpfn = man->size; - node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL); + node = kzalloc_flex(*node, mm_nodes, 1); if (!node) return -ENOMEM; @@ -184,7 +184,7 @@ int ttm_range_man_init_nocheck(struct ttm_device *bdev, struct ttm_resource_manager *man; struct ttm_range_manager *rman; - rman = kzalloc(sizeof(*rman), GFP_KERNEL); + rman = kzalloc_obj(*rman); if (!rman) return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/ttm_sys_manager.c b/drivers/gpu/drm/ttm/ttm_sys_manager.c index 2ced169513cb..04398bb9c710 100644 --- a/drivers/gpu/drm/ttm/ttm_sys_manager.c +++ b/drivers/gpu/drm/ttm/ttm_sys_manager.c @@ -12,7 +12,7 @@ static int ttm_sys_man_alloc(struct ttm_resource_manager *man, const struct ttm_place *place, struct ttm_resource **res) { - *res = kzalloc(sizeof(**res), GFP_KERNEL); + *res = kzalloc_obj(**res); if (!*res) return -ENOMEM; diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index af33fa020249..b645a1818184 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c @@ -137,8 +137,7 @@ static int ttm_dma_tt_alloc_page_directory(struct ttm_tt *ttm) static int ttm_sg_tt_alloc_page_directory(struct ttm_tt *ttm) { - ttm->dma_address = kvcalloc(ttm->num_pages, sizeof(*ttm->dma_address), - GFP_KERNEL); + ttm->dma_address = kvzalloc_objs(*ttm->dma_address, ttm->num_pages); if (!ttm->dma_address) return -ENOMEM; @@ -330,7 +329,7 @@ int ttm_tt_swapout(struct ttm_device *bdev, struct ttm_tt *ttm, struct page *to_page; int i, ret; - swap_storage = shmem_file_setup("ttm swap", size, 0); + swap_storage = shmem_file_setup("ttm swap", size, EMPTY_VMA_FLAGS); if (IS_ERR(swap_storage)) { pr_err("Failed allocating swap storage\n"); return PTR_ERR(swap_storage); diff --git a/drivers/gpu/drm/udl/udl_main.c b/drivers/gpu/drm/udl/udl_main.c index bc58991a6f14..08a0e9480d70 100644 --- a/drivers/gpu/drm/udl/udl_main.c +++ b/drivers/gpu/drm/udl/udl_main.c @@ -218,7 +218,7 @@ static int udl_alloc_urb_list(struct udl_device *udl, int count, size_t size) udl->urbs.size = size; while (udl->urbs.count * size < wanted_size) { - unode = kzalloc(sizeof(struct urb_node), GFP_KERNEL); + unode = kzalloc_obj(struct urb_node); if (!unode) break; unode->dev = udl; diff --git a/drivers/gpu/drm/v3d/v3d_bo.c b/drivers/gpu/drm/v3d/v3d_bo.c index 36aae97cf6da..a847d2f0ccf5 100644 --- a/drivers/gpu/drm/v3d/v3d_bo.c +++ b/drivers/gpu/drm/v3d/v3d_bo.c @@ -86,7 +86,7 @@ struct drm_gem_object *v3d_create_object(struct drm_device *dev, size_t size) if (size == 0) return ERR_PTR(-EINVAL); - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); obj = &bo->base.base; diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index 8de4f151a5c0..dd60acdf52c2 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -133,7 +133,7 @@ v3d_open(struct drm_device *dev, struct drm_file *file) struct drm_gpu_scheduler *sched; int i; - v3d_priv = kzalloc(sizeof(*v3d_priv), GFP_KERNEL); + v3d_priv = kzalloc_obj(*v3d_priv); if (!v3d_priv) return -ENOMEM; diff --git a/drivers/gpu/drm/v3d/v3d_fence.c b/drivers/gpu/drm/v3d/v3d_fence.c index c82500a1df73..3c999f60003c 100644 --- a/drivers/gpu/drm/v3d/v3d_fence.c +++ b/drivers/gpu/drm/v3d/v3d_fence.c @@ -8,7 +8,7 @@ struct dma_fence *v3d_fence_create(struct v3d_dev *v3d, enum v3d_queue q) struct v3d_queue_state *queue = &v3d->queue[q]; struct v3d_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index 9a3fe5255874..e3d7474854eb 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -353,8 +353,7 @@ int v3d_perfmon_create_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - perfmon = kzalloc(struct_size(perfmon, values, req->ncounters), - GFP_KERNEL); + perfmon = kzalloc_flex(*perfmon, values, req->ncounters); if (!perfmon) return -ENOMEM; diff --git a/drivers/gpu/drm/v3d/v3d_submit.c b/drivers/gpu/drm/v3d/v3d_submit.c index 794c3571662d..18f2bf1fe89f 100644 --- a/drivers/gpu/drm/v3d/v3d_submit.c +++ b/drivers/gpu/drm/v3d/v3d_submit.c @@ -335,9 +335,7 @@ v3d_get_multisync_post_deps(struct drm_file *file_priv, return 0; se->out_syncs = (struct v3d_submit_outsync *) - kvmalloc_array(count, - sizeof(struct v3d_submit_outsync), - GFP_KERNEL); + kvmalloc_objs(struct v3d_submit_outsync, count); if (!se->out_syncs) return -ENOMEM; @@ -486,9 +484,8 @@ v3d_get_cpu_timestamp_query_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_TIMESTAMP_QUERY; - query_info->queries = kvmalloc_array(timestamp.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); + query_info->queries = kvmalloc_objs(struct v3d_timestamp_query, + timestamp.count); if (!query_info->queries) return -ENOMEM; @@ -545,9 +542,8 @@ v3d_get_cpu_reset_timestamp_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_RESET_TIMESTAMP_QUERY; - query_info->queries = kvmalloc_array(reset.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); + query_info->queries = kvmalloc_objs(struct v3d_timestamp_query, + reset.count); if (!query_info->queries) return -ENOMEM; @@ -602,9 +598,8 @@ v3d_get_cpu_copy_query_results_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_COPY_TIMESTAMP_QUERY; - query_info->queries = kvmalloc_array(copy.count, - sizeof(struct v3d_timestamp_query), - GFP_KERNEL); + query_info->queries = kvmalloc_objs(struct v3d_timestamp_query, + copy.count); if (!query_info->queries) return -ENOMEM; @@ -729,9 +724,7 @@ v3d_get_cpu_reset_performance_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_RESET_PERFORMANCE_QUERY; query_info->queries = - kvmalloc_array(reset.count, - sizeof(struct v3d_performance_query), - GFP_KERNEL); + kvmalloc_objs(struct v3d_performance_query, reset.count); if (!query_info->queries) return -ENOMEM; @@ -771,9 +764,7 @@ v3d_get_cpu_copy_performance_query_params(struct drm_file *file_priv, job->job_type = V3D_CPU_JOB_TYPE_COPY_PERFORMANCE_QUERY; query_info->queries = - kvmalloc_array(copy.count, - sizeof(struct v3d_performance_query), - GFP_KERNEL); + kvmalloc_objs(struct v3d_performance_query, copy.count); if (!query_info->queries) return -ENOMEM; @@ -1082,8 +1073,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, goto fail; } - job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles), - sizeof(*job->base.bo), GFP_KERNEL); + job->base.bo = kzalloc_objs(*job->base.bo, ARRAY_SIZE(args->bo_handles)); if (!job->base.bo) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/vboxvideo/vbox_mode.c b/drivers/gpu/drm/vboxvideo/vbox_mode.c index d363c3f0afdf..9c11a6b945ff 100644 --- a/drivers/gpu/drm/vboxvideo/vbox_mode.c +++ b/drivers/gpu/drm/vboxvideo/vbox_mode.c @@ -528,7 +528,7 @@ static struct drm_plane *vbox_create_plane(struct vbox_private *vbox, return ERR_PTR(-EINVAL); } - plane = kzalloc(sizeof(*plane), GFP_KERNEL); + plane = kzalloc_obj(*plane); if (!plane) return ERR_PTR(-ENOMEM); @@ -562,7 +562,7 @@ static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i) if (ret) return ERR_PTR(ret); - vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL); + vbox_crtc = kzalloc_obj(*vbox_crtc); if (!vbox_crtc) return ERR_PTR(-ENOMEM); @@ -622,7 +622,7 @@ static struct drm_encoder *vbox_encoder_init(struct drm_device *dev, { struct vbox_encoder *vbox_encoder; - vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL); + vbox_encoder = kzalloc_obj(*vbox_encoder); if (!vbox_encoder) return NULL; @@ -808,7 +808,7 @@ static int vbox_connector_init(struct drm_device *dev, struct vbox_connector *vbox_connector; struct drm_connector *connector; - vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL); + vbox_connector = kzalloc_obj(*vbox_connector); if (!vbox_connector) return -ENOMEM; diff --git a/drivers/gpu/drm/vc4/vc4_bo.c b/drivers/gpu/drm/vc4/vc4_bo.c index 46b4474ac41d..1f93bc5a3d02 100644 --- a/drivers/gpu/drm/vc4/vc4_bo.c +++ b/drivers/gpu/drm/vc4/vc4_bo.c @@ -205,8 +205,7 @@ static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev, struct list_head *new_list; uint32_t i; - new_list = kmalloc_array(new_size, sizeof(struct list_head), - GFP_KERNEL); + new_list = kmalloc_objs(struct list_head, new_size); if (!new_list) return NULL; @@ -400,7 +399,7 @@ struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size) if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return ERR_PTR(-ENODEV); - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); @@ -1015,8 +1014,7 @@ int vc4_bo_cache_init(struct drm_device *dev) * use. This lets us avoid a bunch of string reallocation in * the kernel's draw and BO allocation paths. */ - vc4->bo_labels = kcalloc(VC4_BO_TYPE_COUNT, sizeof(*vc4->bo_labels), - GFP_KERNEL); + vc4->bo_labels = kzalloc_objs(*vc4->bo_labels, VC4_BO_TYPE_COUNT); if (!vc4->bo_labels) return -ENOMEM; vc4->num_labels = VC4_BO_TYPE_COUNT; diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index 2a48038abe7a..4a606986afcc 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c @@ -997,7 +997,7 @@ vc4_async_page_flip_common(struct drm_crtc *crtc, struct drm_plane *plane = crtc->primary; struct vc4_async_flip_state *flip_state; - flip_state = kzalloc(sizeof(*flip_state), GFP_KERNEL); + flip_state = kzalloc_obj(*flip_state); if (!flip_state) return -ENOMEM; @@ -1105,7 +1105,7 @@ struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) { struct vc4_crtc_state *vc4_state, *old_vc4_state; - vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL); + vc4_state = kzalloc_obj(*vc4_state); if (!vc4_state) return NULL; @@ -1142,7 +1142,7 @@ void vc4_crtc_reset(struct drm_crtc *crtc) if (crtc->state) vc4_crtc_destroy_state(crtc, crtc->state); - vc4_crtc_state = kzalloc(sizeof(*vc4_crtc_state), GFP_KERNEL); + vc4_crtc_state = kzalloc_obj(*vc4_crtc_state); if (!vc4_crtc_state) { crtc->state = NULL; return; diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 3846996f9028..a14ecb769461 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c @@ -152,7 +152,7 @@ static int vc4_open(struct drm_device *dev, struct drm_file *file) if (WARN_ON_ONCE(vc4->gen > VC4_GEN_4)) return -ENODEV; - vc4file = kzalloc(sizeof(*vc4file), GFP_KERNEL); + vc4file = kzalloc_obj(*vc4file); if (!vc4file) return -ENOMEM; vc4file->dev = vc4; diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c index ab16164b5eda..ad8cbd727b80 100644 --- a/drivers/gpu/drm/vc4/vc4_gem.c +++ b/drivers/gpu/drm/vc4/vc4_gem.c @@ -110,7 +110,7 @@ vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, state->bo = get_state->bo; memcpy(get_state, state, sizeof(*state)); - bo_state = kcalloc(state->bo_count, sizeof(*bo_state), GFP_KERNEL); + bo_state = kzalloc_objs(*bo_state, state->bo_count); if (!bo_state) { ret = -ENOMEM; goto err_free; @@ -161,7 +161,7 @@ vc4_save_hang_state(struct drm_device *dev) unsigned long irqflags; unsigned int i, j, k, unref_list_count; - kernel_state = kcalloc(1, sizeof(*kernel_state), GFP_KERNEL); + kernel_state = kzalloc_objs(*kernel_state, 1); if (!kernel_state) return; @@ -187,8 +187,8 @@ vc4_save_hang_state(struct drm_device *dev) state->bo_count += exec[i]->bo_count + unref_list_count; } - kernel_state->bo = kcalloc(state->bo_count, - sizeof(*kernel_state->bo), GFP_ATOMIC); + kernel_state->bo = kzalloc_objs(*kernel_state->bo, state->bo_count, + GFP_ATOMIC); if (!kernel_state->bo) { spin_unlock_irqrestore(&vc4->job_lock, irqflags); @@ -622,7 +622,7 @@ vc4_queue_submit(struct drm_device *dev, struct vc4_exec_info *exec, unsigned long irqflags; struct vc4_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return -ENOMEM; fence->dev = dev; @@ -1043,7 +1043,7 @@ vc4_submit_cl_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - exec = kcalloc(1, sizeof(*exec), GFP_KERNEL); + exec = kzalloc_objs(*exec, 1); if (!exec) return -ENOMEM; diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 2ea31938168d..fda214b5a466 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c @@ -2941,8 +2941,7 @@ static int vc4_hdmi_build_regset(struct drm_device *drm, unsigned int i; int ret; - regs = kcalloc(variant->num_registers, sizeof(*regs), - GFP_KERNEL); + regs = kzalloc_objs(*regs, variant->num_registers); if (!regs) return -ENOMEM; diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index e563c1210937..245485e744a5 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c @@ -103,7 +103,7 @@ static int vc4_ctm_obj_init(struct vc4_dev *vc4) drm_modeset_lock_init(&vc4->ctm_state_lock); - ctm_state = kzalloc(sizeof(*ctm_state), GFP_KERNEL); + ctm_state = kzalloc_obj(*ctm_state); if (!ctm_state) return -ENOMEM; @@ -734,7 +734,7 @@ static int vc4_load_tracker_obj_init(struct vc4_dev *vc4) { struct vc4_load_tracker_state *load_state; - load_state = kzalloc(sizeof(*load_state), GFP_KERNEL); + load_state = kzalloc_obj(*load_state); if (!load_state) return -ENOMEM; @@ -752,7 +752,7 @@ vc4_hvs_channels_duplicate_state(struct drm_private_obj *obj) struct vc4_hvs_state *state; unsigned int i; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; @@ -817,7 +817,7 @@ static int vc4_hvs_channels_obj_init(struct vc4_dev *vc4) { struct vc4_hvs_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -911,7 +911,7 @@ static int vc4_pv_muxing_atomic_check(struct drm_device *dev, * If the layout changes and doesn't give us that in the future, * we will need to have something smarter, but it works so far. */ - sorted_crtcs = kmalloc_array(dev->num_crtcs, sizeof(*sorted_crtcs), GFP_KERNEL); + sorted_crtcs = kmalloc_objs(*sorted_crtcs, dev->num_crtcs); if (!sorted_crtcs) return -ENOMEM; diff --git a/drivers/gpu/drm/vc4/vc4_perfmon.c b/drivers/gpu/drm/vc4/vc4_perfmon.c index 1ac80c0b258f..eb5e1c936a01 100644 --- a/drivers/gpu/drm/vc4/vc4_perfmon.c +++ b/drivers/gpu/drm/vc4/vc4_perfmon.c @@ -172,8 +172,7 @@ int vc4_perfmon_create_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - perfmon = kzalloc(struct_size(perfmon, counters, req->ncounters), - GFP_KERNEL); + perfmon = kzalloc_flex(*perfmon, counters, req->ncounters); if (!perfmon) return -ENOMEM; perfmon->dev = vc4; diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index f00d4076ba07..91d499fefba2 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c @@ -374,7 +374,7 @@ static void vc4_plane_reset(struct drm_plane *plane) kfree(plane->state); - vc4_state = kzalloc(sizeof(*vc4_state), GFP_KERNEL); + vc4_state = kzalloc_obj(*vc4_state); if (!vc4_state) return; diff --git a/drivers/gpu/drm/vc4/vc4_validate_shaders.c b/drivers/gpu/drm/vc4/vc4_validate_shaders.c index b50b6cdac3f4..d48cf76983c0 100644 --- a/drivers/gpu/drm/vc4/vc4_validate_shaders.c +++ b/drivers/gpu/drm/vc4/vc4_validate_shaders.c @@ -803,7 +803,7 @@ vc4_validate_shader(struct drm_gem_dma_object *shader_obj) if (!validation_state.branch_targets) goto fail; - validated_shader = kcalloc(1, sizeof(*validated_shader), GFP_KERNEL); + validated_shader = kzalloc_objs(*validated_shader, 1); if (!validated_shader) goto fail; diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c index 260c64733972..a9f5c247db71 100644 --- a/drivers/gpu/drm/vgem/vgem_drv.c +++ b/drivers/gpu/drm/vgem/vgem_drv.c @@ -60,7 +60,7 @@ static int vgem_open(struct drm_device *dev, struct drm_file *file) struct vgem_file *vfile; int ret; - vfile = kzalloc(sizeof(*vfile), GFP_KERNEL); + vfile = kzalloc_obj(*vfile); if (!vfile) return -ENOMEM; @@ -94,7 +94,7 @@ static struct drm_gem_object *vgem_gem_create_object(struct drm_device *dev, siz { struct drm_gem_shmem_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c index 07db319c3d7f..0e53ba7db629 100644 --- a/drivers/gpu/drm/vgem/vgem_fence.c +++ b/drivers/gpu/drm/vgem/vgem_fence.c @@ -71,7 +71,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, { struct vgem_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return NULL; diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c index 6a962c1d6e95..f1dae9569805 100644 --- a/drivers/gpu/drm/virtio/virtgpu_display.c +++ b/drivers/gpu/drm/virtio/virtgpu_display.c @@ -334,7 +334,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev, if (!obj) return ERR_PTR(-EINVAL); - virtio_gpu_fb = kzalloc(sizeof(*virtio_gpu_fb), GFP_KERNEL); + virtio_gpu_fb = kzalloc_obj(*virtio_gpu_fb); if (virtio_gpu_fb == NULL) { drm_gem_object_put(obj); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/virtio/virtgpu_fence.c b/drivers/gpu/drm/virtio/virtgpu_fence.c index 44c1d8ef3c4d..c3e66ef2133a 100644 --- a/drivers/gpu/drm/virtio/virtgpu_fence.c +++ b/drivers/gpu/drm/virtio/virtgpu_fence.c @@ -61,8 +61,7 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev, { uint64_t fence_context = base_fence_ctx + ring_idx; struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv; - struct virtio_gpu_fence *fence = kzalloc(sizeof(struct virtio_gpu_fence), - GFP_KERNEL); + struct virtio_gpu_fence *fence = kzalloc_obj(struct virtio_gpu_fence); if (!fence) return fence; diff --git a/drivers/gpu/drm/virtio/virtgpu_gem.c b/drivers/gpu/drm/virtio/virtgpu_gem.c index 90c99d83c4cf..f22dc5c21cd4 100644 --- a/drivers/gpu/drm/virtio/virtgpu_gem.c +++ b/drivers/gpu/drm/virtio/virtgpu_gem.c @@ -154,7 +154,7 @@ struct virtio_gpu_object_array *virtio_gpu_panic_array_alloc(void) { struct virtio_gpu_object_array *objs; - objs = kmalloc(sizeof(struct virtio_gpu_object_array), GFP_ATOMIC); + objs = kmalloc_obj(struct virtio_gpu_object_array, GFP_ATOMIC); if (!objs) return NULL; @@ -167,7 +167,7 @@ struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents) { struct virtio_gpu_object_array *objs; - objs = kmalloc(struct_size(objs, objs, nents), GFP_KERNEL); + objs = kmalloc_flex(*objs, objs, nents); if (!objs) return NULL; diff --git a/drivers/gpu/drm/virtio/virtgpu_kms.c b/drivers/gpu/drm/virtio/virtgpu_kms.c index f3594695bb82..80ba69b4860b 100644 --- a/drivers/gpu/drm/virtio/virtgpu_kms.c +++ b/drivers/gpu/drm/virtio/virtgpu_kms.c @@ -316,7 +316,7 @@ int virtio_gpu_driver_open(struct drm_device *dev, struct drm_file *file) return 0; /* allocate a virt GPU context for this opener */ - vfpriv = kzalloc(sizeof(*vfpriv), GFP_KERNEL); + vfpriv = kzalloc_obj(*vfpriv); if (!vfpriv) return -ENOMEM; diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c index 4270bfede7b9..ec9efacc6919 100644 --- a/drivers/gpu/drm/virtio/virtgpu_object.c +++ b/drivers/gpu/drm/virtio/virtgpu_object.c @@ -149,7 +149,7 @@ struct drm_gem_object *virtio_gpu_create_object(struct drm_device *dev, struct virtio_gpu_object_shmem *shmem; struct drm_gem_shmem_object *dshmem; - shmem = kzalloc(sizeof(*shmem), GFP_KERNEL); + shmem = kzalloc_obj(*shmem); if (!shmem) return ERR_PTR(-ENOMEM); @@ -177,9 +177,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, else *nents = pages->orig_nents; - *ents = kvmalloc_array(*nents, - sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); + *ents = kvmalloc_objs(struct virtio_gpu_mem_entry, *nents); if (!(*ents)) { DRM_ERROR("failed to allocate ent list\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/virtio/virtgpu_plane.c b/drivers/gpu/drm/virtio/virtgpu_plane.c index a7863f8ee4ee..a126d1b25f46 100644 --- a/drivers/gpu/drm/virtio/virtgpu_plane.c +++ b/drivers/gpu/drm/virtio/virtgpu_plane.c @@ -79,7 +79,7 @@ drm_plane_state *virtio_gpu_plane_duplicate_state(struct drm_plane *plane) if (WARN_ON(!plane->state)) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c index ce49282198cb..8adcf5c15d45 100644 --- a/drivers/gpu/drm/virtio/virtgpu_prime.c +++ b/drivers/gpu/drm/virtio/virtgpu_prime.c @@ -164,9 +164,7 @@ int virtgpu_dma_buf_import_sgt(struct virtio_gpu_mem_entry **ents, if (IS_ERR(sgt)) return PTR_ERR(sgt); - *ents = kvmalloc_array(sgt->nents, - sizeof(struct virtio_gpu_mem_entry), - GFP_KERNEL); + *ents = kvmalloc_objs(struct virtio_gpu_mem_entry, sgt->nents); if (!(*ents)) { dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); return -ENOMEM; @@ -315,7 +313,7 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev, if (!vgdev->has_resource_blob || vgdev->has_virgl_3d) return drm_gem_prime_import(dev, buf); - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/virtio/virtgpu_submit.c b/drivers/gpu/drm/virtio/virtgpu_submit.c index 7d34cf83f5f2..dae761fa5788 100644 --- a/drivers/gpu/drm/virtio/virtgpu_submit.c +++ b/drivers/gpu/drm/virtio/virtgpu_submit.c @@ -104,7 +104,7 @@ virtio_gpu_parse_deps(struct virtio_gpu_submit *submit) * internally for allocations larger than a page size, preventing * storm of KMSG warnings. */ - syncobjs = kvcalloc(num_in_syncobjs, sizeof(*syncobjs), GFP_KERNEL); + syncobjs = kvzalloc_objs(*syncobjs, num_in_syncobjs); if (!syncobjs) return -ENOMEM; @@ -195,7 +195,7 @@ static int virtio_gpu_parse_post_deps(struct virtio_gpu_submit *submit) if (!num_out_syncobjs) return 0; - post_deps = kvcalloc(num_out_syncobjs, sizeof(*post_deps), GFP_KERNEL); + post_deps = kvzalloc_objs(*post_deps, num_out_syncobjs); if (!post_deps) return -ENOMEM; @@ -277,7 +277,7 @@ static int virtio_gpu_fence_event_create(struct drm_device *dev, struct virtio_gpu_fence_event *e = NULL; int ret; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c index 0c194b4e9488..67865810a2e7 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vq.c +++ b/drivers/gpu/drm/virtio/virtgpu_vq.c @@ -312,7 +312,7 @@ static struct sg_table *vmalloc_to_sgt(char *data, uint32_t size, int *sg_ents) if (WARN_ON(!PAGE_ALIGNED(data))) return NULL; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return NULL; @@ -936,8 +936,7 @@ int virtio_gpu_cmd_get_display_info(struct virtio_gpu_device *vgdev) struct virtio_gpu_vbuffer *vbuf; void *resp_buf; - resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_display_info), - GFP_KERNEL); + resp_buf = kzalloc_obj(struct virtio_gpu_resp_display_info); if (!resp_buf) return -ENOMEM; @@ -959,8 +958,7 @@ int virtio_gpu_cmd_get_capset_info(struct virtio_gpu_device *vgdev, int idx) struct virtio_gpu_vbuffer *vbuf; void *resp_buf; - resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_capset_info), - GFP_KERNEL); + resp_buf = kzalloc_obj(struct virtio_gpu_resp_capset_info); if (!resp_buf) return -ENOMEM; @@ -995,7 +993,7 @@ int virtio_gpu_cmd_get_capset(struct virtio_gpu_device *vgdev, if (version > vgdev->capsets[idx].max_version) return -EINVAL; - cache_ent = kzalloc(sizeof(*cache_ent), GFP_KERNEL); + cache_ent = kzalloc_obj(*cache_ent); if (!cache_ent) return -ENOMEM; @@ -1063,8 +1061,7 @@ int virtio_gpu_cmd_get_edids(struct virtio_gpu_device *vgdev) return -EINVAL; for (scanout = 0; scanout < vgdev->num_scanouts; scanout++) { - resp_buf = kzalloc(sizeof(struct virtio_gpu_resp_edid), - GFP_KERNEL); + resp_buf = kzalloc_obj(struct virtio_gpu_resp_edid); if (!resp_buf) return -ENOMEM; @@ -1341,7 +1338,7 @@ virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf; struct virtio_gpu_resp_resource_uuid *resp_buf; - resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL); + resp_buf = kzalloc_obj(*resp_buf); if (!resp_buf) { spin_lock(&vgdev->resource_export_lock); bo->uuid_state = STATE_ERR; @@ -1394,7 +1391,7 @@ int virtio_gpu_cmd_map(struct virtio_gpu_device *vgdev, struct virtio_gpu_vbuffer *vbuf; struct virtio_gpu_resp_map_info *resp_buf; - resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL); + resp_buf = kzalloc_obj(*resp_buf); if (!resp_buf) return -ENOMEM; diff --git a/drivers/gpu/drm/virtio/virtgpu_vram.c b/drivers/gpu/drm/virtio/virtgpu_vram.c index 5ad3b7c6f73c..084e80227433 100644 --- a/drivers/gpu/drm/virtio/virtgpu_vram.c +++ b/drivers/gpu/drm/virtio/virtgpu_vram.c @@ -79,7 +79,7 @@ struct sg_table *virtio_gpu_vram_map_dma_buf(struct virtio_gpu_object *bo, dma_addr_t addr; int ret; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) return ERR_PTR(-ENOMEM); @@ -193,7 +193,7 @@ int virtio_gpu_vram_create(struct virtio_gpu_device *vgdev, struct virtio_gpu_object_vram *vram; int ret; - vram = kzalloc(sizeof(*vram), GFP_KERNEL); + vram = kzalloc_obj(*vram); if (!vram) return -ENOMEM; diff --git a/drivers/gpu/drm/vkms/vkms_colorop.c b/drivers/gpu/drm/vkms/vkms_colorop.c index d03a1f2e9c41..bf8a0e4fc719 100644 --- a/drivers/gpu/drm/vkms/vkms_colorop.c +++ b/drivers/gpu/drm/vkms/vkms_colorop.c @@ -24,7 +24,7 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr memset(ops, 0, sizeof(ops)); /* 1st op: 1d curve */ - ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); ret = -ENOMEM; @@ -41,7 +41,7 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 2nd op: 3x4 matrix */ - ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); ret = -ENOMEM; @@ -57,7 +57,7 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 3rd op: 3x4 matrix */ - ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); ret = -ENOMEM; @@ -73,7 +73,7 @@ static int vkms_initialize_color_pipeline(struct drm_plane *plane, struct drm_pr i++; /* 4th op: 1d curve */ - ops[i] = kzalloc(sizeof(*ops[i]), GFP_KERNEL); + ops[i] = kzalloc_obj(*ops[i]); if (!ops[i]) { drm_err(dev, "KMS: Failed to allocate colorop\n"); ret = -ENOMEM; diff --git a/drivers/gpu/drm/vkms/vkms_config.c b/drivers/gpu/drm/vkms/vkms_config.c index 8788df9edb7c..5a654d6dead8 100644 --- a/drivers/gpu/drm/vkms/vkms_config.c +++ b/drivers/gpu/drm/vkms/vkms_config.c @@ -12,7 +12,7 @@ struct vkms_config *vkms_config_create(const char *dev_name) { struct vkms_config *config; - config = kzalloc(sizeof(*config), GFP_KERNEL); + config = kzalloc_obj(*config); if (!config) return ERR_PTR(-ENOMEM); @@ -388,7 +388,7 @@ struct vkms_config_plane *vkms_config_create_plane(struct vkms_config *config) { struct vkms_config_plane *plane_cfg; - plane_cfg = kzalloc(sizeof(*plane_cfg), GFP_KERNEL); + plane_cfg = kzalloc_obj(*plane_cfg); if (!plane_cfg) return ERR_PTR(-ENOMEM); @@ -448,7 +448,7 @@ struct vkms_config_crtc *vkms_config_create_crtc(struct vkms_config *config) { struct vkms_config_crtc *crtc_cfg; - crtc_cfg = kzalloc(sizeof(*crtc_cfg), GFP_KERNEL); + crtc_cfg = kzalloc_obj(*crtc_cfg); if (!crtc_cfg) return ERR_PTR(-ENOMEM); @@ -527,7 +527,7 @@ struct vkms_config_encoder *vkms_config_create_encoder(struct vkms_config *confi { struct vkms_config_encoder *encoder_cfg; - encoder_cfg = kzalloc(sizeof(*encoder_cfg), GFP_KERNEL); + encoder_cfg = kzalloc_obj(*encoder_cfg); if (!encoder_cfg) return ERR_PTR(-ENOMEM); @@ -591,7 +591,7 @@ struct vkms_config_connector *vkms_config_create_connector(struct vkms_config *c { struct vkms_config_connector *connector_cfg; - connector_cfg = kzalloc(sizeof(*connector_cfg), GFP_KERNEL); + connector_cfg = kzalloc_obj(*connector_cfg); if (!connector_cfg) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/vkms/vkms_configfs.c b/drivers/gpu/drm/vkms/vkms_configfs.c index 506666e21c91..7551b8c7766d 100644 --- a/drivers/gpu/drm/vkms/vkms_configfs.c +++ b/drivers/gpu/drm/vkms/vkms_configfs.c @@ -769,7 +769,7 @@ static struct config_group *make_device_group(struct config_group *group, if (strcmp(name, DEFAULT_DEVICE_NAME) == 0) return ERR_PTR(-EINVAL); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c index 9a7db1d51022..ba2ff353e1a9 100644 --- a/drivers/gpu/drm/vkms/vkms_crtc.c +++ b/drivers/gpu/drm/vkms/vkms_crtc.c @@ -62,7 +62,7 @@ vkms_atomic_crtc_duplicate_state(struct drm_crtc *crtc) if (WARN_ON(!crtc->state)) return NULL; - vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL); + vkms_state = kzalloc_obj(*vkms_state); if (!vkms_state) return NULL; @@ -87,8 +87,7 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc, static void vkms_atomic_crtc_reset(struct drm_crtc *crtc) { - struct vkms_crtc_state *vkms_state = - kzalloc(sizeof(*vkms_state), GFP_KERNEL); + struct vkms_crtc_state *vkms_state = kzalloc_obj(*vkms_state); if (crtc->state) vkms_atomic_crtc_destroy_state(crtc, crtc->state); @@ -137,7 +136,7 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc, i++; } - vkms_state->active_planes = kcalloc(i, sizeof(*vkms_state->active_planes), GFP_KERNEL); + vkms_state->active_planes = kzalloc_objs(*vkms_state->active_planes, i); if (!vkms_state->active_planes) return -ENOMEM; vkms_state->num_active_planes = i; diff --git a/drivers/gpu/drm/vkms/vkms_plane.c b/drivers/gpu/drm/vkms/vkms_plane.c index 19fe6acad306..ca7aee101a95 100644 --- a/drivers/gpu/drm/vkms/vkms_plane.c +++ b/drivers/gpu/drm/vkms/vkms_plane.c @@ -56,11 +56,11 @@ vkms_plane_duplicate_state(struct drm_plane *plane) struct vkms_plane_state *vkms_state; struct vkms_frame_info *frame_info; - vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL); + vkms_state = kzalloc_obj(*vkms_state); if (!vkms_state) return NULL; - frame_info = kzalloc(sizeof(*frame_info), GFP_KERNEL); + frame_info = kzalloc_obj(*frame_info); if (!frame_info) { DRM_DEBUG_KMS("Couldn't allocate frame_info\n"); kfree(vkms_state); @@ -104,7 +104,7 @@ static void vkms_plane_reset(struct drm_plane *plane) plane->state = NULL; /* must be set to NULL here */ } - vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL); + vkms_state = kzalloc_obj(*vkms_state); if (!vkms_state) { DRM_ERROR("Cannot allocate vkms_plane_state\n"); return; diff --git a/drivers/gpu/drm/vkms/vkms_writeback.c b/drivers/gpu/drm/vkms/vkms_writeback.c index 097ae1f0a230..908b7e602ffb 100644 --- a/drivers/gpu/drm/vkms/vkms_writeback.c +++ b/drivers/gpu/drm/vkms/vkms_writeback.c @@ -81,7 +81,7 @@ static int vkms_wb_prepare_job(struct drm_writeback_connector *wb_connector, if (!job->fb) return 0; - vkmsjob = kzalloc(sizeof(*vkmsjob), GFP_KERNEL); + vkmsjob = kzalloc_obj(*vkmsjob); if (!vkmsjob) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/ttm_object.c b/drivers/gpu/drm/vmwgfx/ttm_object.c index 36d46b79562a..2421b0dd057c 100644 --- a/drivers/gpu/drm/vmwgfx/ttm_object.c +++ b/drivers/gpu/drm/vmwgfx/ttm_object.c @@ -318,7 +318,7 @@ int ttm_ref_object_add(struct ttm_object_file *tfile, if (require_existed) return -EPERM; - ref = kmalloc(sizeof(*ref), GFP_KERNEL); + ref = kmalloc_obj(*ref); if (unlikely(ref == NULL)) { return -ENOMEM; } @@ -404,7 +404,7 @@ void ttm_object_file_release(struct ttm_object_file **p_tfile) struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev) { - struct ttm_object_file *tfile = kmalloc(sizeof(*tfile), GFP_KERNEL); + struct ttm_object_file *tfile = kmalloc_obj(*tfile); if (unlikely(tfile == NULL)) return NULL; @@ -422,7 +422,7 @@ struct ttm_object_file *ttm_object_file_init(struct ttm_object_device *tdev) struct ttm_object_device * ttm_object_device_init(const struct dma_buf_ops *ops) { - struct ttm_object_device *tdev = kmalloc(sizeof(*tdev), GFP_KERNEL); + struct ttm_object_device *tdev = kmalloc_obj(*tdev); if (unlikely(tdev == NULL)) return NULL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c index fa5841fda659..135b75a3e013 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_blit.c @@ -586,8 +586,7 @@ int vmw_bo_cpu_blit(struct vmw_bo *vmw_dst, w, h, diff); if (!src->ttm->pages && src->ttm->sg) { - src_pages = kvmalloc_array(src->ttm->num_pages, - sizeof(struct page *), GFP_KERNEL); + src_pages = kvmalloc_objs(struct page *, src->ttm->num_pages); if (!src_pages) return -ENOMEM; ret = drm_prime_sg_to_page_array(src->ttm->sg, src_pages, @@ -596,8 +595,7 @@ int vmw_bo_cpu_blit(struct vmw_bo *vmw_dst, goto out; } if (!dst->ttm->pages && dst->ttm->sg) { - dst_pages = kvmalloc_array(dst->ttm->num_pages, - sizeof(struct page *), GFP_KERNEL); + dst_pages = kvmalloc_objs(struct page *, dst->ttm->num_pages); if (!dst_pages) { ret = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c index b22887e8c881..9c7a73c0b0dc 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c @@ -449,7 +449,7 @@ int vmw_bo_create(struct vmw_private *vmw, { int ret; - *p_bo = kmalloc(sizeof(**p_bo), GFP_KERNEL); + *p_bo = kmalloc_obj(**p_bo); if (unlikely(!*p_bo)) { DRM_ERROR("Failed to allocate a buffer.\n"); return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c index 8fe02131a6c4..d932e38d7942 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c @@ -103,7 +103,7 @@ struct vmw_fifo_state *vmw_fifo_create(struct vmw_private *dev_priv) if (!dev_priv->fifo_mem) return NULL; - fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); + fifo = kzalloc_obj(*fifo); if (!fifo) return ERR_PTR(-ENOMEM); fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c index 94e8982f5616..f45d93e8c1c8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf.c @@ -105,6 +105,7 @@ struct vmw_cmdbuf_context { * @handle: DMA address handle for the command buffer space if @using_mob is * false. Immutable. * @size: The size of the command buffer space. Immutable. + * @id: Monotonically increasing ID of the last cmdbuf submitted. * @num_contexts: Number of contexts actually enabled. */ struct vmw_cmdbuf_man { @@ -132,6 +133,7 @@ struct vmw_cmdbuf_man { bool has_pool; dma_addr_t handle; size_t size; + u64 id; u32 num_contexts; }; @@ -303,6 +305,8 @@ static int vmw_cmdbuf_header_submit(struct vmw_cmdbuf_header *header) struct vmw_cmdbuf_man *man = header->man; u32 val; + header->cb_header->id = man->id++; + val = upper_32_bits(header->handle); vmw_write(man->dev_priv, SVGA_REG_COMMAND_HIGH, val); @@ -961,7 +965,7 @@ void *vmw_cmdbuf_alloc(struct vmw_cmdbuf_man *man, *p_header = NULL; - header = kzalloc(sizeof(*header), GFP_KERNEL); + header = kzalloc_obj(*header); if (!header) return ERR_PTR(-ENOMEM); @@ -1296,7 +1300,7 @@ struct vmw_cmdbuf_man *vmw_cmdbuf_man_create(struct vmw_private *dev_priv) if (!(dev_priv->capabilities & SVGA_CAP_COMMAND_BUFFERS)) return ERR_PTR(-ENOSYS); - man = kzalloc(sizeof(*man), GFP_KERNEL); + man = kzalloc_obj(*man); if (!man) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c index 47bc0b411055..fe1ba1a61a68 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmdbuf_res.c @@ -200,7 +200,7 @@ int vmw_cmdbuf_res_add(struct vmw_cmdbuf_res_manager *man, { struct vmw_cmdbuf_res *cres; - cres = kzalloc(sizeof(*cres), GFP_KERNEL); + cres = kzalloc_obj(*cres); if (unlikely(!cres)) return -ENOMEM; @@ -284,7 +284,7 @@ vmw_cmdbuf_res_man_create(struct vmw_private *dev_priv) { struct vmw_cmdbuf_res_manager *man; - man = kzalloc(sizeof(*man), GFP_KERNEL); + man = kzalloc_obj(*man); if (!man) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c index ecc503e42790..bd96f4d5e090 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_context.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_context.c @@ -738,7 +738,7 @@ static int vmw_context_define(struct drm_device *dev, void *data, return -EINVAL; } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (unlikely(!ctx)) { ret = -ENOMEM; goto out_ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c index 98331c4c0335..091f1039a052 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cotable.c @@ -604,7 +604,7 @@ struct vmw_resource *vmw_cotable_alloc(struct vmw_private *dev_priv, int ret; u32 num_entries; - vcotbl = kzalloc(sizeof(*vcotbl), GFP_KERNEL); + vcotbl = kzalloc_obj(*vcotbl); if (unlikely(!vcotbl)) { ret = -ENOMEM; goto out_no_alloc; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 599052d07ae8..0f101aedb49a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -1209,7 +1209,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) struct vmw_fpriv *vmw_fp; int ret = -ENOMEM; - vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL); + vmw_fp = kzalloc_obj(*vmw_fp); if (unlikely(!vmw_fp)) return ret; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 3057f8baa7d2..e1f18020170a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -1143,7 +1143,7 @@ static int vmw_translate_mob_ptr(struct vmw_private *dev_priv, ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo); if (ret != 0) { drm_dbg(&dev_priv->drm, "Could not find or use MOB buffer.\n"); - return PTR_ERR(vmw_bo); + return ret; } vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_MOB, VMW_BO_DOMAIN_MOB); ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo); @@ -1199,7 +1199,7 @@ static int vmw_translate_guest_ptr(struct vmw_private *dev_priv, ret = vmw_user_bo_lookup(sw_context->filp, handle, &vmw_bo); if (ret != 0) { drm_dbg(&dev_priv->drm, "Could not find or use GMR region.\n"); - return PTR_ERR(vmw_bo); + return ret; } vmw_bo_placement_set(vmw_bo, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM, VMW_BO_DOMAIN_GMR | VMW_BO_DOMAIN_VRAM); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 85795082fef9..3469e2c9e706 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c @@ -129,7 +129,7 @@ static const struct dma_fence_ops vmw_fence_ops = { struct vmw_fence_manager *vmw_fence_manager_init(struct vmw_private *dev_priv) { - struct vmw_fence_manager *fman = kzalloc(sizeof(*fman), GFP_KERNEL); + struct vmw_fence_manager *fman = kzalloc_obj(*fman); if (unlikely(!fman)) return NULL; @@ -251,7 +251,7 @@ int vmw_fence_create(struct vmw_fence_manager *fman, struct vmw_fence_obj *fence; int ret; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (unlikely(!fence)) return -ENOMEM; @@ -298,7 +298,7 @@ int vmw_user_fence_create(struct drm_file *file_priv, struct vmw_fence_obj *tmp; int ret; - ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); + ufence = kzalloc_obj(*ufence); if (unlikely(!ufence)) { ret = -ENOMEM; goto out_no_object; @@ -580,7 +580,7 @@ int vmw_event_fence_action_queue(struct drm_file *file_priv, struct vmw_event_fence_action *eaction; struct vmw_fence_manager *fman = fman_from_fence(fence); - eaction = kzalloc(sizeof(*eaction), GFP_KERNEL); + eaction = kzalloc_obj(*eaction); if (unlikely(!eaction)) return -ENOMEM; @@ -612,7 +612,7 @@ static int vmw_event_fence_action_create(struct drm_file *file_priv, struct drm_device *dev = &fman->dev_priv->drm; int ret; - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (unlikely(!event)) { DRM_ERROR("Failed to allocate an event.\n"); ret = -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c index 5bd967fbcf55..d607452dff6a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c @@ -57,7 +57,7 @@ static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man, struct vmwgfx_gmrid_man *gman = to_gmrid_manager(man); int id; - *res = kmalloc(sizeof(**res), GFP_KERNEL); + *res = kmalloc_obj(**res); if (!*res) return -ENOMEM; @@ -154,8 +154,7 @@ static const struct ttm_resource_manager_func vmw_gmrid_manager_func; int vmw_gmrid_man_init(struct vmw_private *dev_priv, int type) { struct ttm_resource_manager *man; - struct vmwgfx_gmrid_man *gman = - kzalloc(sizeof(*gman), GFP_KERNEL); + struct vmwgfx_gmrid_man *gman = kzalloc_obj(*gman); if (unlikely(!gman)) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c index 835d1eed8dd9..d962ef2ef316 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ioctl.c @@ -196,7 +196,7 @@ int vmw_present_ioctl(struct drm_device *dev, void *data, goto out_clips; } - clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); + clips = kzalloc_objs(*clips, num_clips); if (clips == NULL) { DRM_ERROR("Failed to allocate clip rect list.\n"); ret = -ENOMEM; @@ -273,7 +273,7 @@ int vmw_present_readback_ioctl(struct drm_device *dev, void *data, goto out_clips; } - clips = kcalloc(num_clips, sizeof(*clips), GFP_KERNEL); + clips = kzalloc_objs(*clips, num_clips); if (clips == NULL) { DRM_ERROR("Failed to allocate clip rect list.\n"); ret = -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index bc51b5d55e38..55730e29d3ae 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -224,7 +224,7 @@ void vmw_du_crtc_reset(struct drm_crtc *crtc) kfree(vmw_crtc_state_to_vcs(crtc->state)); } - vcs = kzalloc(sizeof(*vcs), GFP_KERNEL); + vcs = kzalloc_obj(*vcs); if (!vcs) { DRM_ERROR("Cannot allocate vmw_crtc_state\n"); @@ -300,7 +300,7 @@ void vmw_du_plane_reset(struct drm_plane *plane) if (plane->state) vmw_du_plane_destroy_state(plane, plane->state); - vps = kzalloc(sizeof(*vps), GFP_KERNEL); + vps = kzalloc_obj(*vps); if (!vps) { DRM_ERROR("Cannot allocate vmw_plane_state\n"); @@ -382,7 +382,7 @@ void vmw_du_connector_reset(struct drm_connector *connector) kfree(vmw_connector_state_to_vcs(connector->state)); } - vcs = kzalloc(sizeof(*vcs), GFP_KERNEL); + vcs = kzalloc_obj(*vcs); if (!vcs) { DRM_ERROR("Cannot allocate vmw_connector_state\n"); @@ -543,7 +543,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, return -EINVAL; } - vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); + vfbs = kzalloc_obj(*vfbs); if (!vfbs) { ret = -ENOMEM; goto out_err1; @@ -632,7 +632,7 @@ static int vmw_kms_new_framebuffer_bo(struct vmw_private *dev_priv, return -EINVAL; } - vfbd = kzalloc(sizeof(*vfbd), GFP_KERNEL); + vfbd = kzalloc_obj(*vfbd); if (!vfbd) { ret = -ENOMEM; goto out_err1; @@ -948,8 +948,7 @@ static int vmw_kms_check_topology(struct drm_device *dev, uint32_t i; int ret = 0; - rects = kcalloc(dev->mode_config.num_crtc, sizeof(struct drm_rect), - GFP_KERNEL); + rects = kzalloc_objs(struct drm_rect, dev->mode_config.num_crtc); if (!rects) return -ENOMEM; @@ -1422,8 +1421,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, } rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); - rects = kcalloc(arg->num_outputs, sizeof(struct drm_vmw_rect), - GFP_KERNEL); + rects = kzalloc_objs(struct drm_vmw_rect, arg->num_outputs); if (unlikely(!rects)) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index c23c9195f0dc..f07669b27fba 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c @@ -416,7 +416,7 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) struct drm_crtc *crtc; int ret; - ldu = kzalloc(sizeof(*ldu), GFP_KERNEL); + ldu = kzalloc_obj(*ldu); if (!ldu) return -ENOMEM; @@ -547,7 +547,7 @@ int vmw_kms_ldu_init_display(struct vmw_private *dev_priv) return -EINVAL; } - dev_priv->ldu_priv = kmalloc(sizeof(*dev_priv->ldu_priv), GFP_KERNEL); + dev_priv->ldu_priv = kmalloc_obj(*dev_priv->ldu_priv); if (!dev_priv->ldu_priv) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c index d8204d4265d3..de7a504de9ce 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c @@ -390,7 +390,7 @@ static unsigned long vmw_mob_calculate_pt_pages(unsigned long data_pages) */ struct vmw_mob *vmw_mob_create(unsigned long data_pages) { - struct vmw_mob *mob = kzalloc(sizeof(*mob), GFP_KERNEL); + struct vmw_mob *mob = kzalloc_obj(*mob); if (unlikely(!mob)) return NULL; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c index 1d9a42cbc88f..fd77ab6568cb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_msg.c @@ -981,10 +981,8 @@ int vmw_mksstat_add_ioctl(struct drm_device *dev, void *data, BUG_ON(dev_priv->mksstat_user_pages[slot]); /* Allocate statically-sized temp arrays for pages -- too big to keep in frame */ - pages_stat = (struct page **)kmalloc_array( - ARRAY_SIZE(pdesc->statPPNs) + - ARRAY_SIZE(pdesc->infoPPNs) + - ARRAY_SIZE(pdesc->strsPPNs), sizeof(*pages_stat), GFP_KERNEL); + pages_stat = (struct page **) kmalloc_objs(*pages_stat, + ARRAY_SIZE(pdesc->statPPNs) + ARRAY_SIZE(pdesc->infoPPNs) + ARRAY_SIZE(pdesc->strsPPNs)); if (!pages_stat) goto err_nomem; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c index e20f64b67b26..679adf7c7183 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_overlay.c @@ -539,7 +539,7 @@ int vmw_overlay_init(struct vmw_private *dev_priv) if (dev_priv->overlay_priv) return -EINVAL; - overlay = kzalloc(sizeof(*overlay), GFP_KERNEL); + overlay = kzalloc_obj(*overlay); if (!overlay) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c index fd4e76486f2d..45561bc1c9ef 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_page_dirty.c @@ -260,6 +260,13 @@ int vmw_bo_dirty_add(struct vmw_bo *vbo) return ret; } +static void vmw_bo_dirty_free(struct kref *kref) +{ + struct vmw_bo_dirty *dirty = container_of(kref, struct vmw_bo_dirty, ref_count); + + kvfree(dirty); +} + /** * vmw_bo_dirty_release - Release a dirty-tracking user from a buffer object * @vbo: The buffer object @@ -274,7 +281,7 @@ void vmw_bo_dirty_release(struct vmw_bo *vbo) { struct vmw_bo_dirty *dirty = vbo->dirty; - if (dirty && kref_put(&dirty->ref_count, (void *)kvfree)) + if (dirty && kref_put(&dirty->ref_count, vmw_bo_dirty_free)) vbo->dirty = NULL; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 5f5f5a94301f..605d037d18c6 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c @@ -811,7 +811,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) struct drm_crtc *crtc; int ret; - sou = kzalloc(sizeof(*sou), GFP_KERNEL); + sou = kzalloc_obj(*sou); if (!sou) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c index a8c8c9375d29..eca4e3e97eb4 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c @@ -595,7 +595,7 @@ int vmw_dx_shader_add(struct vmw_cmdbuf_res_manager *man, if (!vmw_shader_id_ok(user_key, shader_type)) return -EINVAL; - shader = kmalloc(sizeof(*shader), GFP_KERNEL); + shader = kmalloc_obj(*shader); if (!shader) { return -ENOMEM; } @@ -696,7 +696,7 @@ static int vmw_user_shader_alloc(struct vmw_private *dev_priv, struct vmw_resource *res, *tmp; int ret; - ushader = kzalloc(sizeof(*ushader), GFP_KERNEL); + ushader = kzalloc_obj(*ushader); if (unlikely(!ushader)) { ret = -ENOMEM; goto out; @@ -746,7 +746,7 @@ static struct vmw_resource *vmw_shader_alloc(struct vmw_private *dev_priv, struct vmw_resource *res; int ret; - shader = kzalloc(sizeof(*shader), GFP_KERNEL); + shader = kzalloc_obj(*shader); if (unlikely(!shader)) { ret = -ENOMEM; goto out_err; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c index 20aab725e53a..dcbacee97f61 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c @@ -1541,7 +1541,7 @@ static int vmw_stdu_init(struct vmw_private *dev_priv, unsigned unit) struct drm_crtc *crtc; int ret; - stdu = kzalloc(sizeof(*stdu), GFP_KERNEL); + stdu = kzalloc_obj(*stdu); if (!stdu) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c index edcc40659038..52c6cfa163da 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_streamoutput.c @@ -284,7 +284,7 @@ int vmw_dx_streamoutput_add(struct vmw_cmdbuf_res_manager *man, struct vmw_private *dev_priv = ctx->dev_priv; int ret; - so = kmalloc(sizeof(*so), GFP_KERNEL); + so = kmalloc_obj(*so); if (!so) { return -ENOMEM; } diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c index c4ac9b47e23a..b2d3927b5567 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_surface.c @@ -741,7 +741,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, return -EINVAL; } - user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); + user_srf = kzalloc_obj(*user_srf); if (unlikely(!user_srf)) { ret = -ENOMEM; goto out_unlock; @@ -767,8 +767,7 @@ int vmw_surface_define_ioctl(struct drm_device *dev, void *data, ret = PTR_ERR(metadata->sizes); goto out_no_sizes; } - srf->offsets = kmalloc_array(metadata->num_sizes, sizeof(*srf->offsets), - GFP_KERNEL); + srf->offsets = kmalloc_objs(*srf->offsets, metadata->num_sizes); if (unlikely(!srf->offsets)) { ret = -ENOMEM; goto out_no_offsets; @@ -2144,7 +2143,7 @@ int vmw_gb_surface_define(struct vmw_private *dev_priv, if (req->sizes != NULL) return -EINVAL; - user_srf = kzalloc(sizeof(*user_srf), GFP_KERNEL); + user_srf = kzalloc_obj(*user_srf); if (unlikely(!user_srf)) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c index ee7964cbdaca..585996b6c9b7 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c @@ -37,7 +37,7 @@ static int vmw_sys_man_alloc(struct ttm_resource_manager *man, const struct ttm_place *place, struct ttm_resource **res) { - *res = kzalloc(sizeof(**res), GFP_KERNEL); + *res = kzalloc_obj(**res); if (!*res) return -ENOMEM; @@ -60,8 +60,7 @@ static const struct ttm_resource_manager_func vmw_sys_manager_func = { int vmw_sys_man_init(struct vmw_private *dev_priv) { struct ttm_device *bdev = &dev_priv->bdev; - struct ttm_resource_manager *man = - kzalloc(sizeof(*man), GFP_KERNEL); + struct ttm_resource_manager *man = kzalloc_obj(*man); if (!man) return -ENOMEM; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c index 5553892d7c3e..dfd08ee19041 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c @@ -404,7 +404,7 @@ static struct ttm_tt *vmw_ttm_tt_create(struct ttm_buffer_object *bo, int ret; bool external = bo->type == ttm_bo_type_sg; - vmw_be = kzalloc(sizeof(*vmw_be), GFP_KERNEL); + vmw_be = kzalloc_obj(*vmw_be); if (!vmw_be) return NULL; diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c index e8049a255d21..05d5e5c0a0de 100644 --- a/drivers/gpu/drm/xe/display/intel_bo.c +++ b/drivers/gpu/drm/xe/display/intel_bo.c @@ -57,7 +57,7 @@ struct intel_frontbuffer *intel_bo_frontbuffer_get(struct drm_gem_object *obj) { struct xe_frontbuffer *front; - front = kmalloc(sizeof(*front), GFP_KERNEL); + front = kmalloc_obj(*front); if (!front) return NULL; diff --git a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c index fa0acb11eaad..8ffc13855ef7 100644 --- a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c +++ b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c @@ -43,7 +43,7 @@ struct intel_dsb_buffer *intel_dsb_buffer_create(struct drm_device *drm, size_t struct xe_bo *obj; int ret; - dsb_buf = kzalloc(sizeof(*dsb_buf), GFP_KERNEL); + dsb_buf = kzalloc_obj(*dsb_buf); if (!dsb_buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c index ed1f65f5ef4d..29c72aa4b0d2 100644 --- a/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c +++ b/drivers/gpu/drm/xe/display/xe_hdcp_gsc.c @@ -95,7 +95,7 @@ static struct intel_hdcp_gsc_context *intel_hdcp_gsc_context_alloc(struct drm_de struct intel_hdcp_gsc_context *gsc_context; int ret; - gsc_context = kzalloc(sizeof(*gsc_context), GFP_KERNEL); + gsc_context = kzalloc_obj(*gsc_context); if (!gsc_context) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/display/xe_panic.c b/drivers/gpu/drm/xe/display/xe_panic.c index e078494dc8ba..bebb21d617f0 100644 --- a/drivers/gpu/drm/xe/display/xe_panic.c +++ b/drivers/gpu/drm/xe/display/xe_panic.c @@ -79,7 +79,7 @@ static struct intel_panic *xe_panic_alloc(void) { struct intel_panic *panic; - panic = kzalloc(sizeof(*panic), GFP_KERNEL); + panic = kzalloc_obj(*panic); return panic; } diff --git a/drivers/gpu/drm/xe/display/xe_stolen.c b/drivers/gpu/drm/xe/display/xe_stolen.c index 8dc2f86ec602..5c7df67be8f9 100644 --- a/drivers/gpu/drm/xe/display/xe_stolen.c +++ b/drivers/gpu/drm/xe/display/xe_stolen.c @@ -86,7 +86,7 @@ static struct intel_stolen_node *xe_stolen_node_alloc(struct drm_device *drm) struct xe_device *xe = to_xe_device(drm); struct intel_stolen_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return NULL; diff --git a/drivers/gpu/drm/xe/regs/xe_engine_regs.h b/drivers/gpu/drm/xe/regs/xe_engine_regs.h index 68172b0248a6..dc5a4fafa70c 100644 --- a/drivers/gpu/drm/xe/regs/xe_engine_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_engine_regs.h @@ -96,6 +96,12 @@ #define ENABLE_SEMAPHORE_POLL_BIT REG_BIT(13) #define RING_CMD_CCTL(base) XE_REG((base) + 0xc4, XE_REG_OPTION_MASKED) + +#define CS_MMIO_GROUP_INSTANCE_SELECT(base) XE_REG((base) + 0xcc) +#define SELECTIVE_READ_ADDRESSING REG_BIT(30) +#define SELECTIVE_READ_GROUP REG_GENMASK(29, 23) +#define SELECTIVE_READ_INSTANCE REG_GENMASK(22, 16) + /* * CMD_CCTL read/write fields take a MOCS value and _not_ a table index. * The lsb of each can be considered a separate enabling bit for encryption. diff --git a/drivers/gpu/drm/xe/tests/xe_bo.c b/drivers/gpu/drm/xe/tests/xe_bo.c index b7d8e45804cf..49c95ed67d7e 100644 --- a/drivers/gpu/drm/xe/tests/xe_bo.c +++ b/drivers/gpu/drm/xe/tests/xe_bo.c @@ -482,7 +482,7 @@ static int shrink_test_run_device(struct xe_device *xe) unsigned int mem_type; struct xe_ttm_tt *xe_tt; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) { KUNIT_FAIL(test, "Unexpected link allocation failure\n"); failed = true; diff --git a/drivers/gpu/drm/xe/xe_bb.c b/drivers/gpu/drm/xe/xe_bb.c index 8b678297aaa2..4749aa7f9466 100644 --- a/drivers/gpu/drm/xe/xe_bb.c +++ b/drivers/gpu/drm/xe/xe_bb.c @@ -31,7 +31,7 @@ static int bb_prefetch(struct xe_gt *gt) struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm) { struct xe_tile *tile = gt_to_tile(gt); - struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL); + struct xe_bb *bb = kmalloc_obj(*bb); int err; if (!bb) @@ -62,7 +62,7 @@ struct xe_bb *xe_bb_new(struct xe_gt *gt, u32 dwords, bool usm) struct xe_bb *xe_bb_ccs_new(struct xe_gt *gt, u32 dwords, enum xe_sriov_vf_ccs_rw_ctxs ctx_id) { - struct xe_bb *bb = kmalloc(sizeof(*bb), GFP_KERNEL); + struct xe_bb *bb = kmalloc_obj(*bb); struct xe_device *xe = gt_to_xe(gt); struct xe_sa_manager *bb_pool; int err; diff --git a/drivers/gpu/drm/xe/xe_bo.c b/drivers/gpu/drm/xe/xe_bo.c index e9180b01a4e4..29fffc81f240 100644 --- a/drivers/gpu/drm/xe/xe_bo.c +++ b/drivers/gpu/drm/xe/xe_bo.c @@ -480,7 +480,7 @@ static struct ttm_tt *xe_ttm_tt_create(struct ttm_buffer_object *ttm_bo, enum ttm_caching caching = ttm_cached; int err; - xe_tt = kzalloc(sizeof(*xe_tt), GFP_KERNEL); + xe_tt = kzalloc_obj(*xe_tt); if (!xe_tt) return NULL; @@ -1941,7 +1941,7 @@ static vm_fault_t xe_bo_cpu_fault(struct vm_fault *vmf) int err = 0; int idx; - if (!drm_dev_enter(&xe->drm, &idx)) + if (xe_device_wedged(xe) || !drm_dev_enter(&xe->drm, &idx)) return ttm_bo_vm_dummy_page(vmf, vmf->vma->vm_page_prot); ret = xe_bo_cpu_fault_fastpath(vmf, xe, bo, needs_rpm); @@ -2089,7 +2089,7 @@ static const struct drm_gem_object_funcs xe_gem_object_funcs = { */ struct xe_bo *xe_bo_alloc(void) { - struct xe_bo *bo = kzalloc(sizeof(*bo), GFP_KERNEL); + struct xe_bo *bo = kzalloc_obj(*bo); if (!bo) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_configfs.c b/drivers/gpu/drm/xe/xe_configfs.c index 82edd0466005..7fd07d1280bb 100644 --- a/drivers/gpu/drm/xe/xe_configfs.c +++ b/drivers/gpu/drm/xe/xe_configfs.c @@ -830,6 +830,7 @@ static void xe_config_device_release(struct config_item *item) mutex_destroy(&dev->lock); + kfree(dev->config.ctx_restore_mid_bb[0].cs); kfree(dev->config.ctx_restore_post_bb[0].cs); kfree(dev); } @@ -998,7 +999,7 @@ static struct config_group *xe_config_make_device_group(struct config_group *gro if (!match) return ERR_PTR(-ENOENT); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_configfs.h b/drivers/gpu/drm/xe/xe_configfs.h index fed57be0b90e..f3683bc7eb90 100644 --- a/drivers/gpu/drm/xe/xe_configfs.h +++ b/drivers/gpu/drm/xe/xe_configfs.h @@ -21,9 +21,11 @@ bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev); bool xe_configfs_media_gt_allowed(struct pci_dev *pdev); u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev); bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev); -u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, +u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, + enum xe_engine_class class, const u32 **cs); -u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, +u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, + enum xe_engine_class class, const u32 **cs); #ifdef CONFIG_PCI_IOV unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev); @@ -37,9 +39,11 @@ static inline bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev) { return static inline bool xe_configfs_media_gt_allowed(struct pci_dev *pdev) { return true; } static inline u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) { return U64_MAX; } static inline bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) { return false; } -static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, enum xe_engine_class, +static inline u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, + enum xe_engine_class class, const u32 **cs) { return 0; } -static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, enum xe_engine_class, +static inline u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, + enum xe_engine_class class, const u32 **cs) { return 0; } static inline unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev) { return UINT_MAX; } #endif diff --git a/drivers/gpu/drm/xe/xe_dep_scheduler.c b/drivers/gpu/drm/xe/xe_dep_scheduler.c index 9bd3bfd2e526..51d99fee9aa5 100644 --- a/drivers/gpu/drm/xe/xe_dep_scheduler.c +++ b/drivers/gpu/drm/xe/xe_dep_scheduler.c @@ -86,7 +86,7 @@ xe_dep_scheduler_create(struct xe_device *xe, }; int err; - dep_scheduler = kzalloc(sizeof(*dep_scheduler), GFP_KERNEL); + dep_scheduler = kzalloc_obj(*dep_scheduler); if (!dep_scheduler) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c index 1581f4dab69d..52ee24e9cd3a 100644 --- a/drivers/gpu/drm/xe/xe_device.c +++ b/drivers/gpu/drm/xe/xe_device.c @@ -86,7 +86,7 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file) int ret = -ENOMEM; struct task_struct *task = NULL; - xef = kzalloc(sizeof(*xef), GFP_KERNEL); + xef = kzalloc_obj(*xef); if (!xef) return ret; diff --git a/drivers/gpu/drm/xe/xe_drm_client.c b/drivers/gpu/drm/xe/xe_drm_client.c index 2787bbb36141..84b66147bf49 100644 --- a/drivers/gpu/drm/xe/xe_drm_client.c +++ b/drivers/gpu/drm/xe/xe_drm_client.c @@ -88,7 +88,7 @@ struct xe_drm_client *xe_drm_client_alloc(void) { struct xe_drm_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return NULL; diff --git a/drivers/gpu/drm/xe/xe_eu_stall.c b/drivers/gpu/drm/xe/xe_eu_stall.c index a5c36a317a70..39723928a019 100644 --- a/drivers/gpu/drm/xe/xe_eu_stall.c +++ b/drivers/gpu/drm/xe/xe_eu_stall.c @@ -238,7 +238,7 @@ int xe_eu_stall_init(struct xe_gt *gt) if (!xe_eu_stall_supported_on_platform(xe)) return 0; - gt->eu_stall = kzalloc(sizeof(*gt->eu_stall), GFP_KERNEL); + gt->eu_stall = kzalloc_obj(*gt->eu_stall); if (!gt->eu_stall) { ret = -ENOMEM; goto exit; @@ -636,7 +636,7 @@ static int xe_eu_stall_data_buf_alloc(struct xe_eu_stall_data_stream *stream, struct xe_bo *bo; u32 size; - stream->xecore_buf = kcalloc(last_xecore, sizeof(*stream->xecore_buf), GFP_KERNEL); + stream->xecore_buf = kzalloc_objs(*stream->xecore_buf, last_xecore); if (!stream->xecore_buf) return -ENOMEM; @@ -905,7 +905,7 @@ static int xe_eu_stall_stream_open_locked(struct drm_device *dev, return -EBUSY; } - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_exec.c b/drivers/gpu/drm/xe/xe_exec.c index dbe6c006f1d6..e05dabfcd43c 100644 --- a/drivers/gpu/drm/xe/xe_exec.c +++ b/drivers/gpu/drm/xe/xe_exec.c @@ -162,7 +162,7 @@ int xe_exec_ioctl(struct drm_device *dev, void *data, struct drm_file *file) } if (args->num_syncs) { - syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL); + syncs = kzalloc_objs(*syncs, args->num_syncs); if (!syncs) { err = -ENOMEM; goto err_exec_queue; diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c index 9b6311f7fd4f..8ecdf949f9e4 100644 --- a/drivers/gpu/drm/xe/xe_exec_queue.c +++ b/drivers/gpu/drm/xe/xe_exec_queue.c @@ -208,7 +208,7 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe, /* only kernel queues can be permanent */ XE_WARN_ON((flags & EXEC_QUEUE_FLAG_PERMANENT) && !(flags & EXEC_QUEUE_FLAG_KERNEL)); - q = kzalloc(struct_size(q, lrc, width), GFP_KERNEL); + q = kzalloc_flex(*q, lrc, width); if (!q) return ERR_PTR(-ENOMEM); @@ -266,6 +266,16 @@ static struct xe_exec_queue *__xe_exec_queue_alloc(struct xe_device *xe, return q; } +static void __xe_exec_queue_fini(struct xe_exec_queue *q) +{ + int i; + + q->ops->fini(q); + + for (i = 0; i < q->width; ++i) + xe_lrc_put(q->lrc[i]); +} + static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags) { int i, err; @@ -320,21 +330,10 @@ static int __xe_exec_queue_init(struct xe_exec_queue *q, u32 exec_queue_flags) return 0; err_lrc: - for (i = i - 1; i >= 0; --i) - xe_lrc_put(q->lrc[i]); + __xe_exec_queue_fini(q); return err; } -static void __xe_exec_queue_fini(struct xe_exec_queue *q) -{ - int i; - - q->ops->fini(q); - - for (i = 0; i < q->width; ++i) - xe_lrc_put(q->lrc[i]); -} - struct xe_exec_queue *xe_exec_queue_create(struct xe_device *xe, struct xe_vm *vm, u32 logical_mask, u16 width, struct xe_hw_engine *hwe, u32 flags, @@ -681,7 +680,7 @@ static int xe_exec_queue_group_init(struct xe_device *xe, struct xe_exec_queue * struct xe_exec_queue_group *group; struct xe_bo *bo; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_execlist.c b/drivers/gpu/drm/xe/xe_execlist.c index 8bf330aeaec0..371983c94a1b 100644 --- a/drivers/gpu/drm/xe/xe_execlist.c +++ b/drivers/gpu/drm/xe/xe_execlist.c @@ -352,7 +352,7 @@ static int execlist_exec_queue_init(struct xe_exec_queue *q) drm_info(&xe->drm, "Enabling execlist submission (GuC submission disabled)\n"); - exl = kzalloc(sizeof(*exl), GFP_KERNEL); + exl = kzalloc_obj(*exl); if (!exl) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index 60665ad1415b..2bda426a6986 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -702,7 +702,7 @@ int xe_ggtt_node_insert(struct xe_ggtt_node *node, u32 size, u32 align) **/ struct xe_ggtt_node *xe_ggtt_node_init(struct xe_ggtt *ggtt) { - struct xe_ggtt_node *node = kzalloc(sizeof(*node), GFP_NOFS); + struct xe_ggtt_node *node = kzalloc_obj(*node, GFP_NOFS); if (!node) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_gsc_proxy.c b/drivers/gpu/drm/xe/xe_gsc_proxy.c index 42438b21f235..707db650a2ae 100644 --- a/drivers/gpu/drm/xe/xe_gsc_proxy.c +++ b/drivers/gpu/drm/xe/xe_gsc_proxy.c @@ -435,15 +435,11 @@ static int proxy_channel_alloc(struct xe_gsc *gsc) return 0; } -static void xe_gsc_proxy_remove(void *arg) +static void xe_gsc_proxy_stop(struct xe_gsc *gsc) { - struct xe_gsc *gsc = arg; struct xe_gt *gt = gsc_to_gt(gsc); struct xe_device *xe = gt_to_xe(gt); - if (!gsc->proxy.component_added) - return; - /* disable HECI2 IRQs */ scoped_guard(xe_pm_runtime, xe) { CLASS(xe_force_wake, fw_ref)(gt_to_fw(gt), XE_FW_GSC); @@ -455,6 +451,30 @@ static void xe_gsc_proxy_remove(void *arg) } xe_gsc_wait_for_worker_completion(gsc); + gsc->proxy.started = false; +} + +static void xe_gsc_proxy_remove(void *arg) +{ + struct xe_gsc *gsc = arg; + struct xe_gt *gt = gsc_to_gt(gsc); + struct xe_device *xe = gt_to_xe(gt); + + if (!gsc->proxy.component_added) + return; + + /* + * GSC proxy start is an async process that can be ongoing during + * Xe module load/unload. Using devm managed action to register + * xe_gsc_proxy_stop could cause issues if Xe module unload has + * already started when the action is registered, potentially leading + * to the cleanup being called at the wrong time. Therefore, instead + * of registering a separate devm action to undo what is done in + * proxy start, we call it from here, but only if the start has + * completed successfully (tracked with the 'started' flag). + */ + if (gsc->proxy.started) + xe_gsc_proxy_stop(gsc); component_del(xe->drm.dev, &xe_gsc_proxy_component_ops); gsc->proxy.component_added = false; @@ -510,6 +530,7 @@ int xe_gsc_proxy_init(struct xe_gsc *gsc) */ int xe_gsc_proxy_start(struct xe_gsc *gsc) { + struct xe_gt *gt = gsc_to_gt(gsc); int err; /* enable the proxy interrupt in the GSC shim layer */ @@ -521,12 +542,18 @@ int xe_gsc_proxy_start(struct xe_gsc *gsc) */ err = xe_gsc_proxy_request_handler(gsc); if (err) - return err; + goto err_irq_disable; if (!xe_gsc_proxy_init_done(gsc)) { - xe_gt_err(gsc_to_gt(gsc), "GSC FW reports proxy init not completed\n"); - return -EIO; + xe_gt_err(gt, "GSC FW reports proxy init not completed\n"); + err = -EIO; + goto err_irq_disable; } + gsc->proxy.started = true; return 0; + +err_irq_disable: + gsc_proxy_irq_toggle(gsc, false); + return err; } diff --git a/drivers/gpu/drm/xe/xe_gsc_types.h b/drivers/gpu/drm/xe/xe_gsc_types.h index 97c056656df0..5aaa2a75861f 100644 --- a/drivers/gpu/drm/xe/xe_gsc_types.h +++ b/drivers/gpu/drm/xe/xe_gsc_types.h @@ -58,6 +58,8 @@ struct xe_gsc { struct mutex mutex; /** @proxy.component_added: whether the component has been added */ bool component_added; + /** @proxy.started: whether the proxy has been started */ + bool started; /** @proxy.bo: object to store message to and from the GSC */ struct xe_bo *bo; /** @proxy.to_gsc: map of the memory used to send messages to the GSC */ diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 9d090d0f2438..df6d04704823 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -210,11 +210,15 @@ static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q) return ret; } +/* Dwords required to emit a RMW of a register */ +#define EMIT_RMW_DW 20 + static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) { - struct xe_reg_sr *sr = &q->hwe->reg_lrc; + struct xe_hw_engine *hwe = q->hwe; + struct xe_reg_sr *sr = &hwe->reg_lrc; struct xe_reg_sr_entry *entry; - int count_rmw = 0, count = 0, ret; + int count_rmw = 0, count_rmw_mcr = 0, count = 0, ret; unsigned long idx; struct xe_bb *bb; size_t bb_len = 0; @@ -224,6 +228,8 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) xa_for_each(&sr->xa, idx, entry) { if (entry->reg.masked || entry->clr_bits == ~0) ++count; + else if (entry->reg.mcr) + ++count_rmw_mcr; else ++count_rmw; } @@ -231,17 +237,35 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) if (count) bb_len += count * 2 + 1; - if (count_rmw) - bb_len += count_rmw * 20 + 7; + /* + * RMW of MCR registers is the same as a normal RMW, except an + * additional LRI (3 dwords) is required per register to steer the read + * to a nom-terminated instance. + * + * We could probably shorten the batch slightly by eliding the + * steering for consecutive MCR registers that have the same + * group/instance target, but it's not worth the extra complexity to do + * so. + */ + bb_len += count_rmw * EMIT_RMW_DW; + bb_len += count_rmw_mcr * (EMIT_RMW_DW + 3); - if (q->hwe->class == XE_ENGINE_CLASS_RENDER) + /* + * After doing all RMW, we need 7 trailing dwords to clean up, + * plus an additional 3 dwords to reset steering if any of the + * registers were MCR. + */ + if (count_rmw || count_rmw_mcr) + bb_len += 7 + (count_rmw_mcr ? 3 : 0); + + if (hwe->class == XE_ENGINE_CLASS_RENDER) /* * Big enough to emit all of the context's 3DSTATE via * xe_lrc_emit_hwe_state_instructions() */ - bb_len += xe_gt_lrc_size(gt, q->hwe->class) / sizeof(u32); + bb_len += xe_gt_lrc_size(gt, hwe->class) / sizeof(u32); - xe_gt_dbg(gt, "LRC %s WA job: %zu dwords\n", q->hwe->name, bb_len); + xe_gt_dbg(gt, "LRC %s WA job: %zu dwords\n", hwe->name, bb_len); bb = xe_bb_new(gt, bb_len, false); if (IS_ERR(bb)) @@ -276,13 +300,23 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) } } - if (count_rmw) { - /* Emit MI_MATH for each RMW reg: 20dw per reg + 7 trailing dw */ - + if (count_rmw || count_rmw_mcr) { xa_for_each(&sr->xa, idx, entry) { if (entry->reg.masked || entry->clr_bits == ~0) continue; + if (entry->reg.mcr) { + struct xe_reg_mcr reg = { .__reg.raw = entry->reg.raw }; + u8 group, instance; + + xe_gt_mcr_get_nonterminated_steering(gt, reg, &group, &instance); + *cs++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1); + *cs++ = CS_MMIO_GROUP_INSTANCE_SELECT(hwe->mmio_base).addr; + *cs++ = SELECTIVE_READ_ADDRESSING | + REG_FIELD_PREP(SELECTIVE_READ_GROUP, group) | + REG_FIELD_PREP(SELECTIVE_READ_INSTANCE, instance); + } + *cs++ = MI_LOAD_REGISTER_REG | MI_LRR_DST_CS_MMIO; *cs++ = entry->reg.addr; *cs++ = CS_GPR_REG(0, 0).addr; @@ -308,8 +342,9 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) *cs++ = CS_GPR_REG(0, 0).addr; *cs++ = entry->reg.addr; - xe_gt_dbg(gt, "REG[%#x] = ~%#x|%#x\n", - entry->reg.addr, entry->clr_bits, entry->set_bits); + xe_gt_dbg(gt, "REG[%#x] = ~%#x|%#x%s\n", + entry->reg.addr, entry->clr_bits, entry->set_bits, + entry->reg.mcr ? " (MCR)" : ""); } /* reset used GPR */ @@ -321,6 +356,13 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q) *cs++ = 0; *cs++ = CS_GPR_REG(0, 2).addr; *cs++ = 0; + + /* reset steering */ + if (count_rmw_mcr) { + *cs++ = MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1); + *cs++ = CS_MMIO_GROUP_INSTANCE_SELECT(q->hwe->mmio_base).addr; + *cs++ = 0; + } } cs = xe_lrc_emit_hwe_state_instructions(q, cs); diff --git a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c index 91ac22ef5703..fe944687728c 100644 --- a/drivers/gpu/drm/xe/xe_gt_ccs_mode.c +++ b/drivers/gpu/drm/xe/xe_gt_ccs_mode.c @@ -191,7 +191,7 @@ int xe_gt_ccs_mode_sysfs_init(struct xe_gt *gt) struct xe_device *xe = gt_to_xe(gt); int err; - if (!xe_gt_ccs_mode_enabled(gt)) + if (!xe_gt_ccs_mode_enabled(gt) || IS_SRIOV_VF(xe)) return 0; err = sysfs_create_files(gt->sysfs, gt_ccs_mode_attrs); diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c index f97abb02aebd..ffa27f66bba7 100644 --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_debugfs.c @@ -710,7 +710,7 @@ static int config_blob_open(struct inode *inode, struct file *file) if (ret < 0) return ret; - cbd = kzalloc(struct_size(cbd, blob, ret), GFP_KERNEL); + cbd = kzalloc_flex(*cbd, blob, ret); if (!cbd) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_gt_sysfs.c b/drivers/gpu/drm/xe/xe_gt_sysfs.c index 1448be047b4a..7fc0bed6ece0 100644 --- a/drivers/gpu/drm/xe/xe_gt_sysfs.c +++ b/drivers/gpu/drm/xe/xe_gt_sysfs.c @@ -36,7 +36,7 @@ int xe_gt_sysfs_init(struct xe_gt *gt) struct kobj_gt *kg; int err; - kg = kzalloc(sizeof(*kg), GFP_KERNEL); + kg = kzalloc_obj(*kg); if (!kg) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index dfbf76037b04..d04589140b77 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -1957,7 +1957,7 @@ static struct xe_guc_ct_snapshot *guc_ct_snapshot_alloc(struct xe_guc_ct *ct, bo { struct xe_guc_ct_snapshot *snapshot; - snapshot = kzalloc(sizeof(*snapshot), atomic ? GFP_ATOMIC : GFP_KERNEL); + snapshot = kzalloc_obj(*snapshot, atomic ? GFP_ATOMIC : GFP_KERNEL); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/xe/xe_guc_log.c b/drivers/gpu/drm/xe/xe_guc_log.c index acac66a4eca7..538d4df0f7aa 100644 --- a/drivers/gpu/drm/xe/xe_guc_log.c +++ b/drivers/gpu/drm/xe/xe_guc_log.c @@ -116,7 +116,7 @@ static struct xe_guc_log_snapshot *xe_guc_log_snapshot_alloc(struct xe_guc_log * size_t remain; int i; - snapshot = kzalloc(sizeof(*snapshot), atomic ? GFP_ATOMIC : GFP_KERNEL); + snapshot = kzalloc_obj(*snapshot, atomic ? GFP_ATOMIC : GFP_KERNEL); if (!snapshot) return NULL; @@ -128,8 +128,8 @@ static struct xe_guc_log_snapshot *xe_guc_log_snapshot_alloc(struct xe_guc_log * snapshot->size = xe_bo_size(log->bo); snapshot->num_chunks = DIV_ROUND_UP(snapshot->size, GUC_LOG_CHUNK_SIZE); - snapshot->copy = kcalloc(snapshot->num_chunks, sizeof(*snapshot->copy), - atomic ? GFP_ATOMIC : GFP_KERNEL); + snapshot->copy = kzalloc_objs(*snapshot->copy, snapshot->num_chunks, + atomic ? GFP_ATOMIC : GFP_KERNEL); if (!snapshot->copy) goto fail_snap; diff --git a/drivers/gpu/drm/xe/xe_guc_submit.c b/drivers/gpu/drm/xe/xe_guc_submit.c index 1b2f66f4425b..799ef9f48003 100644 --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1903,7 +1903,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q) xe_gt_assert(guc_to_gt(guc), xe_device_uc_enabled(guc_to_xe(guc))); - ge = kzalloc(sizeof(*ge), GFP_KERNEL); + ge = kzalloc_obj(*ge); if (!ge) return -ENOMEM; @@ -2057,7 +2057,7 @@ static int guc_exec_queue_set_priority(struct xe_exec_queue *q, exec_queue_killed_or_banned_or_wedged(q)) return 0; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -2075,7 +2075,7 @@ static int guc_exec_queue_set_timeslice(struct xe_exec_queue *q, u32 timeslice_u exec_queue_killed_or_banned_or_wedged(q)) return 0; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -2094,7 +2094,7 @@ static int guc_exec_queue_set_preempt_timeout(struct xe_exec_queue *q, exec_queue_killed_or_banned_or_wedged(q)) return 0; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -2115,7 +2115,7 @@ static int guc_exec_queue_set_multi_queue_priority(struct xe_exec_queue *q, exec_queue_killed_or_banned_or_wedged(q)) return 0; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -3128,7 +3128,7 @@ xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q) struct xe_guc_submit_exec_queue_snapshot *snapshot; int i; - snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + snapshot = kzalloc_obj(*snapshot, GFP_ATOMIC); if (!snapshot) return NULL; @@ -3144,8 +3144,8 @@ xe_guc_exec_queue_snapshot_capture(struct xe_exec_queue *q) snapshot->sched_props.preempt_timeout_us = q->sched_props.preempt_timeout_us; - snapshot->lrc = kmalloc_array(q->width, sizeof(struct xe_lrc_snapshot *), - GFP_ATOMIC); + snapshot->lrc = kmalloc_objs(struct xe_lrc_snapshot *, q->width, + GFP_ATOMIC); if (snapshot->lrc) { for (i = 0; i < q->width; ++i) { diff --git a/drivers/gpu/drm/xe/xe_heci_gsc.c b/drivers/gpu/drm/xe/xe_heci_gsc.c index c1f15313f92e..5af8903e10af 100644 --- a/drivers/gpu/drm/xe/xe_heci_gsc.c +++ b/drivers/gpu/drm/xe/xe_heci_gsc.c @@ -131,7 +131,7 @@ static int heci_gsc_add_device(struct xe_device *xe, const struct heci_gsc_def * struct mei_aux_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; adev->irq = heci_gsc->irq; diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index 4d3ee5226e3a..688d645e0e73 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -927,7 +927,7 @@ xe_hw_engine_snapshot_capture(struct xe_hw_engine *hwe, struct xe_exec_queue *q) if (!xe_hw_engine_is_valid(hwe)) return NULL; - snapshot = kzalloc(sizeof(*snapshot), GFP_ATOMIC); + snapshot = kzalloc_obj(*snapshot, GFP_ATOMIC); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c index 3c65becb39ad..d42e263e0611 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c +++ b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c @@ -549,7 +549,7 @@ kobj_xe_hw_engine_class(struct xe_device *xe, struct kobject *parent, const char struct kobj_eclass *keclass; int err = 0; - keclass = kzalloc(sizeof(*keclass), GFP_KERNEL); + keclass = kzalloc_obj(*keclass); if (!keclass) return NULL; @@ -582,7 +582,7 @@ static int xe_add_hw_engine_class_defaults(struct xe_device *xe, struct kobject *kobj; int err = 0; - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + kobj = kzalloc_obj(*kobj); if (!kobj) return -ENOMEM; @@ -629,7 +629,7 @@ int xe_hw_engine_class_sysfs_init(struct xe_gt *gt) u16 class_mask = 0; int err = 0; - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + kobj = kzalloc_obj(*kobj); if (!kobj) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_hwmon.c b/drivers/gpu/drm/xe/xe_hwmon.c index baf277955b33..0fd4d4f1014a 100644 --- a/drivers/gpu/drm/xe/xe_hwmon.c +++ b/drivers/gpu/drm/xe/xe_hwmon.c @@ -48,7 +48,7 @@ enum xe_hwmon_channel { CHANNEL_MCTRL, CHANNEL_PCIE, CHANNEL_VRAM_N, - CHANNEL_VRAM_N_MAX = CHANNEL_VRAM_N + MAX_VRAM_CHANNELS, + CHANNEL_VRAM_N_MAX = CHANNEL_VRAM_N + MAX_VRAM_CHANNELS - 1, CHANNEL_MAX, }; @@ -264,7 +264,7 @@ static struct xe_reg xe_hwmon_get_reg(struct xe_hwmon *hwmon, enum xe_hwmon_reg return BMG_PACKAGE_TEMPERATURE; else if (channel == CHANNEL_VRAM) return BMG_VRAM_TEMPERATURE; - else if (in_range(channel, CHANNEL_VRAM_N, CHANNEL_VRAM_N_MAX)) + else if (in_range(channel, CHANNEL_VRAM_N, MAX_VRAM_CHANNELS)) return BMG_VRAM_TEMPERATURE_N(channel - CHANNEL_VRAM_N); } else if (xe->info.platform == XE_DG2) { if (channel == CHANNEL_PKG) @@ -1427,7 +1427,7 @@ static int xe_hwmon_read_label(struct device *dev, *str = "mctrl"; else if (channel == CHANNEL_PCIE) *str = "pcie"; - else if (in_range(channel, CHANNEL_VRAM_N, CHANNEL_VRAM_N_MAX)) + else if (in_range(channel, CHANNEL_VRAM_N, MAX_VRAM_CHANNELS)) *str = hwmon->temp.vram_label[channel - CHANNEL_VRAM_N]; return 0; case hwmon_power: diff --git a/drivers/gpu/drm/xe/xe_lmtt.c b/drivers/gpu/drm/xe/xe_lmtt.c index 2077e1ef8b43..8163c3a8fc87 100644 --- a/drivers/gpu/drm/xe/xe_lmtt.c +++ b/drivers/gpu/drm/xe/xe_lmtt.c @@ -64,7 +64,7 @@ static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level struct xe_bo *bo; int err; - pt = kzalloc(struct_size(pt, entries, num_entries), GFP_KERNEL); + pt = kzalloc_flex(*pt, entries, num_entries); if (!pt) { err = -ENOMEM; goto out; diff --git a/drivers/gpu/drm/xe/xe_lrc.c b/drivers/gpu/drm/xe/xe_lrc.c index 3db7968aa5e2..b0f037bc227f 100644 --- a/drivers/gpu/drm/xe/xe_lrc.c +++ b/drivers/gpu/drm/xe/xe_lrc.c @@ -1616,7 +1616,7 @@ struct xe_lrc *xe_lrc_create(struct xe_hw_engine *hwe, struct xe_vm *vm, struct xe_lrc *lrc; int err; - lrc = kzalloc(sizeof(*lrc), GFP_KERNEL); + lrc = kzalloc_obj(*lrc); if (!lrc) return ERR_PTR(-ENOMEM); @@ -2269,7 +2269,7 @@ u32 *xe_lrc_emit_hwe_state_instructions(struct xe_exec_queue *q, u32 *cs) struct xe_lrc_snapshot *xe_lrc_snapshot_capture(struct xe_lrc *lrc) { - struct xe_lrc_snapshot *snapshot = kmalloc(sizeof(*snapshot), GFP_NOWAIT); + struct xe_lrc_snapshot *snapshot = kmalloc_obj(*snapshot, GFP_NOWAIT); if (!snapshot) return NULL; diff --git a/drivers/gpu/drm/xe/xe_lrc.h b/drivers/gpu/drm/xe/xe_lrc.h index c307a3fd9ea2..c1c615447c85 100644 --- a/drivers/gpu/drm/xe/xe_lrc.h +++ b/drivers/gpu/drm/xe/xe_lrc.h @@ -75,7 +75,8 @@ static inline struct xe_lrc *xe_lrc_get(struct xe_lrc *lrc) */ static inline void xe_lrc_put(struct xe_lrc *lrc) { - kref_put(&lrc->refcount, xe_lrc_destroy); + if (lrc) + kref_put(&lrc->refcount, xe_lrc_destroy); } /** diff --git a/drivers/gpu/drm/xe/xe_migrate.c b/drivers/gpu/drm/xe/xe_migrate.c index 078a9bc2821d..e58b9b433654 100644 --- a/drivers/gpu/drm/xe/xe_migrate.c +++ b/drivers/gpu/drm/xe/xe_migrate.c @@ -2303,7 +2303,7 @@ static struct drm_pagemap_addr *xe_migrate_dma_map(struct xe_device *xe, struct drm_pagemap_addr *pagemap_addr; unsigned long i, npages = DIV_ROUND_UP(len, PAGE_SIZE); - pagemap_addr = kcalloc(npages, sizeof(*pagemap_addr), GFP_KERNEL); + pagemap_addr = kzalloc_objs(*pagemap_addr, npages); if (!pagemap_addr) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_mmio.c b/drivers/gpu/drm/xe/xe_mmio.c index bcb6674b7dac..a1a05c68dc7d 100644 --- a/drivers/gpu/drm/xe/xe_mmio.c +++ b/drivers/gpu/drm/xe/xe_mmio.c @@ -256,11 +256,11 @@ u64 xe_mmio_read64_2x32(struct xe_mmio *mmio, struct xe_reg reg) struct xe_reg reg_udw = { .addr = reg.addr + 0x4 }; u32 ldw, udw, oldudw, retries; - reg.addr = xe_mmio_adjusted_addr(mmio, reg.addr); - reg_udw.addr = xe_mmio_adjusted_addr(mmio, reg_udw.addr); - - /* we shouldn't adjust just one register address */ - xe_tile_assert(mmio->tile, reg_udw.addr == reg.addr + 0x4); + /* + * The two dwords of a 64-bit register can never straddle the offset + * adjustment cutoff. + */ + xe_tile_assert(mmio->tile, !in_range(mmio->adj_limit, reg.addr + 1, 7)); oldudw = xe_mmio_read32(mmio, reg_udw); for (retries = 5; retries; --retries) { diff --git a/drivers/gpu/drm/xe/xe_mmio_gem.c b/drivers/gpu/drm/xe/xe_mmio_gem.c index 9a97c4387e4f..8c803ef233cc 100644 --- a/drivers/gpu/drm/xe/xe_mmio_gem.c +++ b/drivers/gpu/drm/xe/xe_mmio_gem.c @@ -78,7 +78,7 @@ struct xe_mmio_gem *xe_mmio_gem_create(struct xe_device *xe, struct drm_file *fi if ((phys_addr % PAGE_SIZE != 0) || (size % PAGE_SIZE != 0)) return ERR_PTR(-EINVAL); - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_module.h b/drivers/gpu/drm/xe/xe_module.h index 1c75f38ca393..79cb9639c0f3 100644 --- a/drivers/gpu/drm/xe/xe_module.h +++ b/drivers/gpu/drm/xe/xe_module.h @@ -12,7 +12,7 @@ struct xe_modparam { bool force_execlist; bool probe_display; - u32 force_vram_bar_size; + int force_vram_bar_size; int guc_log_level; char *guc_firmware_path; char *huc_firmware_path; diff --git a/drivers/gpu/drm/xe/xe_nvm.c b/drivers/gpu/drm/xe/xe_nvm.c index 6f9dd519371c..9c4ccd3b39d4 100644 --- a/drivers/gpu/drm/xe/xe_nvm.c +++ b/drivers/gpu/drm/xe/xe_nvm.c @@ -133,7 +133,7 @@ int xe_nvm_init(struct xe_device *xe) if (WARN_ON(xe->nvm)) return -EFAULT; - xe->nvm = kzalloc(sizeof(*nvm), GFP_KERNEL); + xe->nvm = kzalloc_obj(*nvm); if (!xe->nvm) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c index abf87fe0b345..4dd3f29933cf 100644 --- a/drivers/gpu/drm/xe/xe_oa.c +++ b/drivers/gpu/drm/xe/xe_oa.c @@ -905,7 +905,7 @@ __xe_oa_alloc_config_buffer(struct xe_oa_stream *stream, struct xe_oa_config *oa size_t config_length; struct xe_bb *bb; - oa_bo = kzalloc(sizeof(*oa_bo), GFP_KERNEL); + oa_bo = kzalloc_obj(*oa_bo); if (!oa_bo) return ERR_PTR(-ENOMEM); @@ -997,7 +997,7 @@ static int xe_oa_emit_oa_config(struct xe_oa_stream *stream, struct xe_oa_config int i, err, num_signal = 0; struct dma_fence *fence; - ofence = kzalloc(sizeof(*ofence), GFP_KERNEL); + ofence = kzalloc_obj(*ofence); if (!ofence) { err = -ENOMEM; goto exit; @@ -1408,7 +1408,7 @@ static int xe_oa_parse_syncs(struct xe_oa *oa, } if (param->num_syncs) { - param->syncs = kcalloc(param->num_syncs, sizeof(*param->syncs), GFP_KERNEL); + param->syncs = kzalloc_objs(*param->syncs, param->num_syncs); if (!param->syncs) { ret = -ENOMEM; goto exit; @@ -1852,7 +1852,7 @@ static int xe_oa_stream_open_ioctl_locked(struct xe_oa *oa, if (ret) goto exit; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) { ret = -ENOMEM; goto err_syncobj; @@ -2259,7 +2259,7 @@ xe_oa_alloc_regs(struct xe_oa *oa, bool (*is_valid)(struct xe_oa *oa, u32 addr), int err; u32 i; - oa_regs = kmalloc_array(n_regs, sizeof(*oa_regs), GFP_KERNEL); + oa_regs = kmalloc_objs(*oa_regs, n_regs); if (!oa_regs) return ERR_PTR(-ENOMEM); @@ -2361,7 +2361,7 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi XE_IOCTL_DBG(oa->xe, !arg->n_regs)) return -EINVAL; - oa_config = kzalloc(sizeof(*oa_config), GFP_KERNEL); + oa_config = kzalloc_obj(*oa_config); if (!oa_config) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c index 3805be561751..5c0b3224f20d 100644 --- a/drivers/gpu/drm/xe/xe_pci.c +++ b/drivers/gpu/drm/xe/xe_pci.c @@ -553,6 +553,12 @@ static int read_gmdid(struct xe_device *xe, enum xe_gmdid_type type, u32 *ver, u struct xe_gt *gt __free(kfree) = NULL; int err; + /* Don't try to read media ver if media GT is not allowed */ + if (type == GMDID_MEDIA && !xe_configfs_media_gt_allowed(to_pci_dev(xe->drm.dev))) { + *ver = *revid = 0; + return 0; + } + gt = kzalloc(sizeof(*gt), GFP_KERNEL); if (!gt) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_pmu.c b/drivers/gpu/drm/xe/xe_pmu.c index 0b20059dd7b3..ce1b110f762b 100644 --- a/drivers/gpu/drm/xe/xe_pmu.c +++ b/drivers/gpu/drm/xe/xe_pmu.c @@ -142,7 +142,7 @@ static bool event_gt_forcewake(struct perf_event *event) gt = xe_device_get_gt(xe, config_to_gt_id(config)); - fw_ref = kzalloc(sizeof(*fw_ref), GFP_KERNEL); + fw_ref = kzalloc_obj(*fw_ref); if (!fw_ref) return false; diff --git a/drivers/gpu/drm/xe/xe_preempt_fence.c b/drivers/gpu/drm/xe/xe_preempt_fence.c index 7f587ca3947d..d6427b473ddd 100644 --- a/drivers/gpu/drm/xe/xe_preempt_fence.c +++ b/drivers/gpu/drm/xe/xe_preempt_fence.c @@ -101,7 +101,7 @@ struct xe_preempt_fence *xe_preempt_fence_alloc(void) { struct xe_preempt_fence *pfence; - pfence = kmalloc(sizeof(*pfence), GFP_KERNEL); + pfence = kmalloc_obj(*pfence); if (!pfence) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_pt.c b/drivers/gpu/drm/xe/xe_pt.c index 6703a7049227..13b355fadd58 100644 --- a/drivers/gpu/drm/xe/xe_pt.c +++ b/drivers/gpu/drm/xe/xe_pt.c @@ -109,11 +109,11 @@ struct xe_pt *xe_pt_create(struct xe_vm *vm, struct xe_tile *tile, int err; if (level) { - struct xe_pt_dir *dir = kzalloc(sizeof(*dir), GFP_KERNEL); + struct xe_pt_dir *dir = kzalloc_obj(*dir); pt = (dir) ? &dir->pt : NULL; } else { - pt = kzalloc(sizeof(*pt), GFP_KERNEL); + pt = kzalloc_obj(*pt); } if (!pt) return ERR_PTR(-ENOMEM); @@ -368,9 +368,7 @@ xe_pt_new_shared(struct xe_walk_update *wupd, struct xe_pt *parent, entry->pt_bo->update_index = -1; if (alloc_entries) { - entry->pt_entries = kmalloc_array(XE_PDES, - sizeof(*entry->pt_entries), - GFP_KERNEL); + entry->pt_entries = kmalloc_objs(*entry->pt_entries, XE_PDES); if (!entry->pt_entries) return -ENOMEM; } @@ -2574,7 +2572,7 @@ xe_pt_update_ops_run(struct xe_tile *tile, struct xe_vma_ops *vops) } } - rfence = kzalloc(sizeof(*rfence), GFP_KERNEL); + rfence = kzalloc_obj(*rfence); if (!rfence) { err = -ENOMEM; goto free_ijob; diff --git a/drivers/gpu/drm/xe/xe_reg_sr.c b/drivers/gpu/drm/xe/xe_reg_sr.c index d3e13ea33123..a07be161cfa2 100644 --- a/drivers/gpu/drm/xe/xe_reg_sr.c +++ b/drivers/gpu/drm/xe/xe_reg_sr.c @@ -89,7 +89,7 @@ int xe_reg_sr_add(struct xe_reg_sr *sr, return 0; } - pentry = kmalloc(sizeof(*pentry), GFP_KERNEL); + pentry = kmalloc_obj(*pentry); if (!pentry) { ret = -ENOMEM; goto fail; @@ -98,10 +98,12 @@ int xe_reg_sr_add(struct xe_reg_sr *sr, *pentry = *e; ret = xa_err(xa_store(&sr->xa, idx, pentry, GFP_KERNEL)); if (ret) - goto fail; + goto fail_free; return 0; +fail_free: + kfree(pentry); fail: xe_gt_err(gt, "discarding save-restore reg %04lx (clear: %08x, set: %08x, masked: %s, mcr: %s): ret=%d\n", diff --git a/drivers/gpu/drm/xe/xe_ring_ops.c b/drivers/gpu/drm/xe/xe_ring_ops.c index 248620b0901d..53d420d72164 100644 --- a/drivers/gpu/drm/xe/xe_ring_ops.c +++ b/drivers/gpu/drm/xe/xe_ring_ops.c @@ -280,6 +280,9 @@ static void __emit_job_gen12_simple(struct xe_sched_job *job, struct xe_lrc *lrc i = emit_bb_start(batch_addr, ppgtt_flag, dw, i); + /* Don't preempt fence signaling */ + dw[i++] = MI_ARB_ON_OFF | MI_ARB_DISABLE; + if (job->user_fence.used) { i = emit_flush_dw(dw, i); i = emit_store_imm_ppgtt_posted(job->user_fence.addr, @@ -345,6 +348,9 @@ static void __emit_job_gen12_video(struct xe_sched_job *job, struct xe_lrc *lrc, i = emit_bb_start(batch_addr, ppgtt_flag, dw, i); + /* Don't preempt fence signaling */ + dw[i++] = MI_ARB_ON_OFF | MI_ARB_DISABLE; + if (job->user_fence.used) { i = emit_flush_dw(dw, i); i = emit_store_imm_ppgtt_posted(job->user_fence.addr, @@ -397,6 +403,9 @@ static void __emit_job_gen12_render_compute(struct xe_sched_job *job, i = emit_bb_start(batch_addr, ppgtt_flag, dw, i); + /* Don't preempt fence signaling */ + dw[i++] = MI_ARB_ON_OFF | MI_ARB_DISABLE; + i = emit_render_cache_flush(job, dw, i); if (job->user_fence.used) diff --git a/drivers/gpu/drm/xe/xe_shrinker.c b/drivers/gpu/drm/xe/xe_shrinker.c index 90244fe59b59..83374cd57660 100644 --- a/drivers/gpu/drm/xe/xe_shrinker.c +++ b/drivers/gpu/drm/xe/xe_shrinker.c @@ -282,7 +282,7 @@ static void xe_shrinker_fini(struct drm_device *drm, void *arg) */ int xe_shrinker_create(struct xe_device *xe) { - struct xe_shrinker *shrinker = kzalloc(sizeof(*shrinker), GFP_KERNEL); + struct xe_shrinker *shrinker = kzalloc_obj(*shrinker); if (!shrinker) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_sriov_packet.c b/drivers/gpu/drm/xe/xe_sriov_packet.c index 7a4c3de662e5..968f32496282 100644 --- a/drivers/gpu/drm/xe/xe_sriov_packet.c +++ b/drivers/gpu/drm/xe/xe_sriov_packet.c @@ -89,7 +89,7 @@ struct xe_sriov_packet *xe_sriov_packet_alloc(struct xe_device *xe) { struct xe_sriov_packet *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; diff --git a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c index 3d140506ba36..0b88cdade6f1 100644 --- a/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c +++ b/drivers/gpu/drm/xe/xe_sriov_pf_sysfs.c @@ -349,18 +349,33 @@ static const struct attribute_group *xe_sriov_vf_attr_groups[] = { /* no user serviceable parts below */ -static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid) +static void action_put_kobject(void *arg) +{ + struct kobject *kobj = arg; + + kobject_put(kobj); +} + +static struct kobject *create_xe_sriov_kobj(struct xe_device *xe, unsigned int vfid, + const struct kobj_type *ktype) { struct xe_sriov_kobj *vkobj; + int err; xe_sriov_pf_assert_vfid(xe, vfid); - vkobj = kzalloc(sizeof(*vkobj), GFP_KERNEL); + vkobj = kzalloc_obj(*vkobj); if (!vkobj) - return NULL; + return ERR_PTR(-ENOMEM); vkobj->xe = xe; vkobj->vfid = vfid; + kobject_init(&vkobj->base, ktype); + + err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, &vkobj->base); + if (err) + return ERR_PTR(err); + return &vkobj->base; } @@ -463,28 +478,17 @@ static void pf_sysfs_note(struct xe_device *xe, int err, const char *what) xe_sriov_dbg(xe, "Failed to setup sysfs %s (%pe)\n", what, ERR_PTR(err)); } -static void action_put_kobject(void *arg) -{ - struct kobject *kobj = arg; - - kobject_put(kobj); -} - static int pf_setup_root(struct xe_device *xe) { struct kobject *parent = &xe->drm.dev->kobj; struct kobject *root; int err; - root = create_xe_sriov_kobj(xe, PFID); - if (!root) - return pf_sysfs_error(xe, -ENOMEM, "root obj"); + root = create_xe_sriov_kobj(xe, PFID, &xe_sriov_dev_ktype); + if (IS_ERR(root)) + return pf_sysfs_error(xe, PTR_ERR(root), "root obj"); - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "root action"); - - err = kobject_init_and_add(root, &xe_sriov_dev_ktype, parent, "sriov_admin"); + err = kobject_add(root, parent, "sriov_admin"); if (err) return pf_sysfs_error(xe, err, "root init"); @@ -505,20 +509,14 @@ static int pf_setup_tree(struct xe_device *xe) root = xe->sriov.pf.sysfs.root; for (n = 0; n <= totalvfs; n++) { - kobj = create_xe_sriov_kobj(xe, VFID(n)); - if (!kobj) - return pf_sysfs_error(xe, -ENOMEM, "tree obj"); - - err = devm_add_action_or_reset(xe->drm.dev, action_put_kobject, root); - if (err) - return pf_sysfs_error(xe, err, "tree action"); + kobj = create_xe_sriov_kobj(xe, VFID(n), &xe_sriov_vf_ktype); + if (IS_ERR(kobj)) + return pf_sysfs_error(xe, PTR_ERR(kobj), "tree obj"); if (n) - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "vf%u", n); + err = kobject_add(kobj, root, "vf%u", n); else - err = kobject_init_and_add(kobj, &xe_sriov_vf_ktype, - root, "pf"); + err = kobject_add(kobj, root, "pf"); if (err) return pf_sysfs_error(xe, err, "tree init"); diff --git a/drivers/gpu/drm/xe/xe_svm.c b/drivers/gpu/drm/xe/xe_svm.c index 213f0334518a..ca67d0bdbfac 100644 --- a/drivers/gpu/drm/xe/xe_svm.c +++ b/drivers/gpu/drm/xe/xe_svm.c @@ -109,7 +109,7 @@ xe_svm_range_alloc(struct drm_gpusvm *gpusvm) { struct xe_svm_range *range; - range = kzalloc(sizeof(*range), GFP_KERNEL); + range = kzalloc_obj(*range); if (!range) return NULL; @@ -1676,13 +1676,13 @@ xe_drm_pagemap_device_map(struct drm_pagemap *dpagemap, static void xe_drm_pagemap_device_unmap(struct drm_pagemap *dpagemap, struct device *dev, - struct drm_pagemap_addr addr) + const struct drm_pagemap_addr *addr) { - if (addr.proto != XE_INTERCONNECT_P2P) + if (addr->proto != XE_INTERCONNECT_P2P) return; - dma_unmap_resource(dev, addr.addr, PAGE_SIZE << addr.order, - addr.dir, DMA_ATTR_SKIP_CPU_SYNC); + dma_unmap_resource(dev, addr->addr, PAGE_SIZE << addr->order, + addr->dir, DMA_ATTR_SKIP_CPU_SYNC); } static void xe_pagemap_destroy_work(struct work_struct *work) @@ -1748,7 +1748,7 @@ static struct xe_pagemap *xe_pagemap_create(struct xe_device *xe, struct xe_vram void *addr; int err; - xpagemap = kzalloc(sizeof(*xpagemap), GFP_KERNEL); + xpagemap = kzalloc_obj(*xpagemap); if (!xpagemap) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_sync.c b/drivers/gpu/drm/xe/xe_sync.c index c8fdcdbd6ae7..24d6d9af20d6 100644 --- a/drivers/gpu/drm/xe/xe_sync.c +++ b/drivers/gpu/drm/xe/xe_sync.c @@ -59,7 +59,7 @@ static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 addr, if (get_user(prefetch_val, ptr)) return ERR_PTR(-EFAULT); - ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); + ufence = kzalloc_obj(*ufence); if (!ufence) return ERR_PTR(-ENOMEM); @@ -146,8 +146,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, if (!signal) { sync->fence = drm_syncobj_fence_get(sync->syncobj); - if (XE_IOCTL_DBG(xe, !sync->fence)) - return -EINVAL; + if (XE_IOCTL_DBG(xe, !sync->fence)) { + err = -EINVAL; + goto free_sync; + } } break; @@ -167,17 +169,21 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, if (signal) { sync->chain_fence = dma_fence_chain_alloc(); - if (!sync->chain_fence) - return -ENOMEM; + if (!sync->chain_fence) { + err = -ENOMEM; + goto free_sync; + } } else { sync->fence = drm_syncobj_fence_get(sync->syncobj); - if (XE_IOCTL_DBG(xe, !sync->fence)) - return -EINVAL; + if (XE_IOCTL_DBG(xe, !sync->fence)) { + err = -EINVAL; + goto free_sync; + } err = dma_fence_chain_find_seqno(&sync->fence, sync_in.timeline_value); if (err) - return err; + goto free_sync; } break; @@ -200,8 +206,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, if (XE_IOCTL_DBG(xe, IS_ERR(sync->ufence))) return PTR_ERR(sync->ufence); sync->ufence_chain_fence = dma_fence_chain_alloc(); - if (!sync->ufence_chain_fence) - return -ENOMEM; + if (!sync->ufence_chain_fence) { + err = -ENOMEM; + goto free_sync; + } sync->ufence_syncobj = ufence_syncobj; } @@ -216,6 +224,10 @@ int xe_sync_entry_parse(struct xe_device *xe, struct xe_file *xef, sync->timeline_value = sync_in.timeline_value; return 0; + +free_sync: + xe_sync_entry_cleanup(sync); + return err; } ALLOW_ERROR_INJECTION(xe_sync_entry_parse, ERRNO); @@ -343,8 +355,7 @@ xe_sync_in_fence_get(struct xe_sync_entry *sync, int num_sync, num_fence++; } - fences = kmalloc_array(num_fence, sizeof(*fences), - GFP_KERNEL); + fences = kmalloc_objs(*fences, num_fence); if (!fences) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xe/xe_tile_sysfs.c b/drivers/gpu/drm/xe/xe_tile_sysfs.c index 9e1236a9ec67..0bfd28422dc2 100644 --- a/drivers/gpu/drm/xe/xe_tile_sysfs.c +++ b/drivers/gpu/drm/xe/xe_tile_sysfs.c @@ -36,7 +36,7 @@ int xe_tile_sysfs_init(struct xe_tile *tile) struct kobj_tile *kt; int err; - kt = kzalloc(sizeof(*kt), GFP_KERNEL); + kt = kzalloc_obj(*kt); if (!kt) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_tlb_inval_job.c b/drivers/gpu/drm/xe/xe_tlb_inval_job.c index 01c413a2537e..04d21015cd5d 100644 --- a/drivers/gpu/drm/xe/xe_tlb_inval_job.c +++ b/drivers/gpu/drm/xe/xe_tlb_inval_job.c @@ -108,7 +108,7 @@ xe_tlb_inval_job_create(struct xe_exec_queue *q, struct xe_tlb_inval *tlb_inval, xe_assert(vm->xe, type == XE_EXEC_QUEUE_TLB_INVAL_MEDIA_GT || type == XE_EXEC_QUEUE_TLB_INVAL_PRIMARY_GT); - job = kmalloc(sizeof(*job), GFP_KERNEL); + job = kmalloc_obj(*job); if (!job) return ERR_PTR(-ENOMEM); @@ -125,7 +125,7 @@ xe_tlb_inval_job_create(struct xe_exec_queue *q, struct xe_tlb_inval *tlb_inval, xe_exec_queue_get(q); /* Pairs with put in xe_tlb_inval_job_destroy */ xe_vm_get(vm); /* Pairs with put in xe_tlb_inval_job_destroy */ - ifence = kmalloc(sizeof(*ifence), GFP_KERNEL); + ifence = kmalloc_obj(*ifence); if (!ifence) { err = -ENOMEM; goto err_job; diff --git a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c index 99fb7e99eb7f..9d77ba605aec 100644 --- a/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_sys_mgr.c @@ -33,7 +33,7 @@ static int xe_ttm_sys_mgr_new(struct ttm_resource_manager *man, struct xe_ttm_sys_node *node; int r; - node = kzalloc(struct_size(node, base.mm_nodes, 1), GFP_KERNEL); + node = kzalloc_flex(*node, base.mm_nodes, 1); if (!node) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c index 6553a19f7cf2..344769d939e0 100644 --- a/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c +++ b/drivers/gpu/drm/xe/xe_ttm_vram_mgr.c @@ -64,7 +64,7 @@ static int xe_ttm_vram_mgr_new(struct ttm_resource_manager *man, if (tbo->base.size >> PAGE_SHIFT > (lpfn - place->fpfn)) return -E2BIG; /* don't trigger eviction for the impossible */ - vres = kzalloc(sizeof(*vres), GFP_KERNEL); + vres = kzalloc_obj(*vres); if (!vres) return -ENOMEM; @@ -371,7 +371,7 @@ int xe_ttm_vram_mgr_alloc_sgt(struct xe_device *xe, if (vres->used_visible_size < res->size) return -EOPNOTSUPP; - *sgt = kmalloc(sizeof(**sgt), GFP_KERNEL); + *sgt = kmalloc_obj(**sgt); if (!*sgt) return -ENOMEM; diff --git a/drivers/gpu/drm/xe/xe_vm.c b/drivers/gpu/drm/xe/xe_vm.c index dd6d99d7fca8..a82e3a4fb389 100644 --- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -586,9 +586,9 @@ static int xe_vma_ops_alloc(struct xe_vma_ops *vops, bool array_of_binds) continue; vops->pt_update_ops[i].ops = - kmalloc_array(vops->pt_update_ops[i].num_ops, - sizeof(*vops->pt_update_ops[i].ops), - GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + kmalloc_objs(*vops->pt_update_ops[i].ops, + vops->pt_update_ops[i].num_ops, + GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); if (!vops->pt_update_ops[i].ops) return array_of_binds ? -ENOBUFS : -ENOMEM; } @@ -667,7 +667,7 @@ static int xe_vm_ops_add_rebind(struct xe_vma_ops *vops, struct xe_vma *vma, { struct xe_vma_op *op; - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (!op) return -ENOMEM; @@ -803,7 +803,7 @@ xe_vm_ops_add_range_rebind(struct xe_vma_ops *vops, { struct xe_vma_op *op; - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (!op) return -ENOMEM; @@ -889,7 +889,7 @@ xe_vm_ops_add_range_unbind(struct xe_vma_ops *vops, { struct xe_vma_op *op; - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (!op) return -ENOMEM; @@ -1008,14 +1008,14 @@ static struct xe_vma *xe_vma_create(struct xe_vm *vm, * matches what was allocated. */ if (!bo && !is_null && !is_cpu_addr_mirror) { - struct xe_userptr_vma *uvma = kzalloc(sizeof(*uvma), GFP_KERNEL); + struct xe_userptr_vma *uvma = kzalloc_obj(*uvma); if (!uvma) return ERR_PTR(-ENOMEM); vma = &uvma->vma; } else { - vma = kzalloc(sizeof(*vma), GFP_KERNEL); + vma = kzalloc_obj(*vma); if (!vma) return ERR_PTR(-ENOMEM); @@ -1235,7 +1235,7 @@ static struct drm_gpuva_op *xe_vm_op_alloc(void) { struct xe_vma_op *op; - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (unlikely(!op)) return NULL; @@ -3161,7 +3161,7 @@ static struct dma_fence *ops_execute(struct xe_vm *vm, ++n_fence; } - fences = kmalloc_array(n_fence, sizeof(*fences), GFP_KERNEL); + fences = kmalloc_objs(*fences, n_fence); if (!fences) { fence = ERR_PTR(-ENOMEM); goto err_trace; @@ -3373,10 +3373,9 @@ static int vm_bind_ioctl_check_args(struct xe_device *xe, struct xe_vm *vm, u64 __user *bind_user = u64_to_user_ptr(args->vector_of_binds); - *bind_ops = kvmalloc_array(args->num_binds, - sizeof(struct drm_xe_vm_bind_op), - GFP_KERNEL | __GFP_ACCOUNT | - __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + *bind_ops = kvmalloc_objs(struct drm_xe_vm_bind_op, + args->num_binds, + GFP_KERNEL | __GFP_ACCOUNT | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); if (!*bind_ops) return args->num_binds > 1 ? -ENOBUFS : -ENOMEM; @@ -3663,17 +3662,15 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) } if (args->num_binds) { - bos = kvcalloc(args->num_binds, sizeof(*bos), - GFP_KERNEL | __GFP_ACCOUNT | - __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + bos = kvzalloc_objs(*bos, args->num_binds, + GFP_KERNEL | __GFP_ACCOUNT | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); if (!bos) { err = -ENOMEM; goto release_vm_lock; } - ops = kvcalloc(args->num_binds, sizeof(*ops), - GFP_KERNEL | __GFP_ACCOUNT | - __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + ops = kvzalloc_objs(*ops, args->num_binds, + GFP_KERNEL | __GFP_ACCOUNT | __GFP_RETRY_MAYFAIL | __GFP_NOWARN); if (!ops) { err = -ENOMEM; goto free_bos; @@ -3708,7 +3705,7 @@ int xe_vm_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file) } if (args->num_syncs) { - syncs = kcalloc(args->num_syncs, sizeof(*syncs), GFP_KERNEL); + syncs = kzalloc_objs(*syncs, args->num_syncs); if (!syncs) { err = -ENOMEM; goto put_obj; diff --git a/drivers/gpu/drm/xe/xe_vm_madvise.c b/drivers/gpu/drm/xe/xe_vm_madvise.c index add9a6ca2390..bc39a9a9790c 100644 --- a/drivers/gpu/drm/xe/xe_vm_madvise.c +++ b/drivers/gpu/drm/xe/xe_vm_madvise.c @@ -47,7 +47,7 @@ static int get_vmas(struct xe_vm *vm, struct xe_vmas_in_madvise_range *madvise_r lockdep_assert_held(&vm->lock); madvise_range->num_vmas = 0; - madvise_range->vmas = kmalloc_array(max_vmas, sizeof(*madvise_range->vmas), GFP_KERNEL); + madvise_range->vmas = kmalloc_objs(*madvise_range->vmas, max_vmas); if (!madvise_range->vmas) return -ENOMEM; @@ -291,8 +291,13 @@ static bool madvise_args_are_sane(struct xe_device *xe, const struct drm_xe_madv break; case DRM_XE_MEM_RANGE_ATTR_PAT: { - u16 coh_mode = xe_pat_index_get_coh_mode(xe, args->pat_index.val); + u16 pat_index, coh_mode; + if (XE_IOCTL_DBG(xe, args->pat_index.val >= xe->pat.n_entries)) + return false; + + pat_index = array_index_nospec(args->pat_index.val, xe->pat.n_entries); + coh_mode = xe_pat_index_get_coh_mode(xe, pat_index); if (XE_IOCTL_DBG(xe, !coh_mode)) return false; @@ -448,7 +453,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil madvise_range.num_vmas, args->atomic.val)) { err = -EINVAL; - goto madv_fini; + goto free_vmas; } } @@ -485,6 +490,7 @@ int xe_vm_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *fil err_fini: if (madvise_range.has_bo_vmas) drm_exec_fini(&exec); +free_vmas: kfree(madvise_range.vmas); madvise_range.vmas = NULL; madv_fini: diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index a991ee2b8781..462c2fa712e0 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -241,12 +241,13 @@ static const struct xe_rtp_entry_sr gt_was[] = { { XE_RTP_NAME("16025250150"), XE_RTP_RULES(GRAPHICS_VERSION(2001)), - XE_RTP_ACTIONS(SET(LSN_VC_REG2, - LSN_LNI_WGT(1) | - LSN_LNE_WGT(1) | - LSN_DIM_X_WGT(1) | - LSN_DIM_Y_WGT(1) | - LSN_DIM_Z_WGT(1))) + XE_RTP_ACTIONS(FIELD_SET(LSN_VC_REG2, + LSN_LNI_WGT_MASK | LSN_LNE_WGT_MASK | + LSN_DIM_X_WGT_MASK | LSN_DIM_Y_WGT_MASK | + LSN_DIM_Z_WGT_MASK, + LSN_LNI_WGT(1) | LSN_LNE_WGT(1) | + LSN_DIM_X_WGT(1) | LSN_DIM_Y_WGT(1) | + LSN_DIM_Z_WGT(1))) }, /* Xe2_HPM */ @@ -548,16 +549,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(ROW_CHICKEN, EARLY_EOT_DIS)) }, - { XE_RTP_NAME("14019988906"), - XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), - FUNC(xe_rtp_match_first_render_or_compute)), - XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) - }, - { XE_RTP_NAME("14019877138"), - XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), - FUNC(xe_rtp_match_first_render_or_compute)), - XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) - }, { XE_RTP_NAME("14020338487"), XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), FUNC(xe_rtp_match_first_render_or_compute)), @@ -833,6 +824,14 @@ static const struct xe_rtp_entry_sr lrc_was[] = { XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), XE_RTP_ACTIONS(SET(WM_CHICKEN3, HIZ_PLANE_COMPRESSION_DIS)) }, + { XE_RTP_NAME("14019988906"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FLSH_IGNORES_PSD)) + }, + { XE_RTP_NAME("14019877138"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(2001, 2002), ENGINE_CLASS(RENDER)), + XE_RTP_ACTIONS(SET(XEHP_PSS_CHICKEN, FD_END_COLLECT)) + }, { XE_RTP_NAME("14021490052"), XE_RTP_RULES(GRAPHICS_VERSION(2001), ENGINE_CLASS(RENDER)), XE_RTP_ACTIONS(SET(FF_MODE, diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c index 4fa45dbe1dcb..e1890d0c7369 100644 --- a/drivers/gpu/drm/xen/xen_drm_front.c +++ b/drivers/gpu/drm/xen/xen_drm_front.c @@ -171,7 +171,7 @@ int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info, if (unlikely(!evtchnl)) return -EIO; - dbuf = kzalloc(sizeof(*dbuf), GFP_KERNEL); + dbuf = kzalloc_obj(*dbuf); if (!dbuf) return -ENOMEM; @@ -496,7 +496,7 @@ static int xen_drm_drv_init(struct xen_drm_front_info *front_info) DRM_INFO("Creating %s\n", xen_drm_driver.desc); - drm_info = kzalloc(sizeof(*drm_info), GFP_KERNEL); + drm_info = kzalloc_obj(*drm_info); if (!drm_info) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c b/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c index e52afd792346..a4888277164d 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c +++ b/drivers/gpu/drm/xen/xen_drm_front_evtchnl.c @@ -212,9 +212,8 @@ int xen_drm_front_evtchnl_create_all(struct xen_drm_front_info *front_info) cfg = &front_info->cfg; front_info->evt_pairs = - kcalloc(cfg->num_connectors, - sizeof(struct xen_drm_front_evtchnl_pair), - GFP_KERNEL); + kzalloc_objs(struct xen_drm_front_evtchnl_pair, + cfg->num_connectors); if (!front_info->evt_pairs) { ret = -ENOMEM; goto fail; diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index 386ae7441093..eec4c1da3f9e 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -47,8 +47,7 @@ static int gem_alloc_pages_array(struct xen_gem_object *xen_obj, size_t buf_size) { xen_obj->num_pages = DIV_ROUND_UP(buf_size, PAGE_SIZE); - xen_obj->pages = kvmalloc_array(xen_obj->num_pages, - sizeof(struct page *), GFP_KERNEL); + xen_obj->pages = kvmalloc_objs(struct page *, xen_obj->num_pages); return !xen_obj->pages ? -ENOMEM : 0; } @@ -118,7 +117,7 @@ static struct xen_gem_object *gem_create_obj(struct drm_device *dev, struct xen_gem_object *xen_obj; int ret; - xen_obj = kzalloc(sizeof(*xen_obj), GFP_KERNEL); + xen_obj = kzalloc_obj(*xen_obj); if (!xen_obj) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/drm/xlnx/zynqmp_disp.c b/drivers/gpu/drm/xlnx/zynqmp_disp.c index 80d1e499a18d..9a8f38230cb4 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_disp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_disp.c @@ -1360,7 +1360,7 @@ int zynqmp_disp_probe(struct zynqmp_dpsub *dpsub) struct zynqmp_disp *disp; int ret; - disp = kzalloc(sizeof(*disp), GFP_KERNEL); + disp = kzalloc_obj(*disp); if (!disp) return -ENOMEM; diff --git a/drivers/gpu/drm/xlnx/zynqmp_dp.c b/drivers/gpu/drm/xlnx/zynqmp_dp.c index 34ddbf98e81d..379180fb3004 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dp.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dp.c @@ -1739,7 +1739,7 @@ static const struct drm_edid *zynqmp_dp_bridge_edid_read(struct drm_bridge *brid static u32 *zynqmp_dp_bridge_default_bus_fmts(unsigned int *num_input_fmts) { - u32 *formats = kzalloc(sizeof(*formats), GFP_KERNEL); + u32 *formats = kzalloc_obj(*formats); if (formats) *formats = MEDIA_BUS_FMT_FIXED; diff --git a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c index 2764c4b17c5e..53ab1a2a5aaf 100644 --- a/drivers/gpu/drm/xlnx/zynqmp_dpsub.c +++ b/drivers/gpu/drm/xlnx/zynqmp_dpsub.c @@ -189,7 +189,7 @@ static int zynqmp_dpsub_probe(struct platform_device *pdev) int ret; /* Allocate private data. */ - dpsub = kzalloc(sizeof(*dpsub), GFP_KERNEL); + dpsub = kzalloc_obj(*dpsub); if (!dpsub) return -ENOMEM; diff --git a/drivers/gpu/host1x/bus.c b/drivers/gpu/host1x/bus.c index e2673bc7cb31..f814eb4941c0 100644 --- a/drivers/gpu/host1x/bus.c +++ b/drivers/gpu/host1x/bus.c @@ -43,7 +43,7 @@ static int host1x_subdev_add(struct host1x_device *device, struct host1x_subdev *subdev; int err; - subdev = kzalloc(sizeof(*subdev), GFP_KERNEL); + subdev = kzalloc_obj(*subdev); if (!subdev) return -ENOMEM; @@ -459,7 +459,7 @@ static int host1x_device_add(struct host1x *host1x, struct host1x_device *device; int err; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return -ENOMEM; diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c index 08077afe4cde..ca5d0f51cf7d 100644 --- a/drivers/gpu/host1x/channel.c +++ b/drivers/gpu/host1x/channel.c @@ -16,8 +16,7 @@ int host1x_channel_list_init(struct host1x_channel_list *chlist, unsigned int num_channels) { - chlist->channels = kcalloc(num_channels, sizeof(struct host1x_channel), - GFP_KERNEL); + chlist->channels = kzalloc_objs(struct host1x_channel, num_channels); if (!chlist->channels) return -ENOMEM; diff --git a/drivers/gpu/host1x/context.c b/drivers/gpu/host1x/context.c index a6f6779662a3..d50d41c20561 100644 --- a/drivers/gpu/host1x/context.c +++ b/drivers/gpu/host1x/context.c @@ -35,7 +35,7 @@ int host1x_memory_context_list_init(struct host1x *host1x) return 0; cdl->len = err / 4; - cdl->devs = kcalloc(cdl->len, sizeof(*cdl->devs), GFP_KERNEL); + cdl->devs = kzalloc_objs(*cdl->devs, cdl->len); if (!cdl->devs) return -ENOMEM; diff --git a/drivers/gpu/host1x/fence.c b/drivers/gpu/host1x/fence.c index 139ad1afd935..b9a7d0bf91f8 100644 --- a/drivers/gpu/host1x/fence.c +++ b/drivers/gpu/host1x/fence.c @@ -127,7 +127,7 @@ struct dma_fence *host1x_fence_create(struct host1x_syncpt *sp, u32 threshold, { struct host1x_syncpt_fence *fence; - fence = kzalloc(sizeof(*fence), GFP_KERNEL); + fence = kzalloc_obj(*fence); if (!fence) return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/host1x/mipi.c b/drivers/gpu/host1x/mipi.c index e51b43dd15a3..fea9f491df66 100644 --- a/drivers/gpu/host1x/mipi.c +++ b/drivers/gpu/host1x/mipi.c @@ -219,7 +219,7 @@ struct tegra_mipi_device *tegra_mipi_request(struct device *device, if (err < 0) return ERR_PTR(err); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { err = -ENOMEM; goto out; diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 333f36e0a715..5db100bb1e4d 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -183,7 +183,7 @@ struct ipuv3_channel *ipu_idmac_get(struct ipu_soc *ipu, unsigned num) } } - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) { channel = ERR_PTR(-ENOMEM); goto out; diff --git a/drivers/gpu/ipu-v3/ipu-image-convert.c b/drivers/gpu/ipu-v3/ipu-image-convert.c index 3c33b4defab5..29b6d36c9bb6 100644 --- a/drivers/gpu/ipu-v3/ipu-image-convert.c +++ b/drivers/gpu/ipu-v3/ipu-image-convert.c @@ -2082,7 +2082,7 @@ ipu_image_convert_prepare(struct ipu_soc *ipu, enum ipu_ic_task ic_task, chan = &priv->chan[ic_task]; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); @@ -2402,7 +2402,7 @@ ipu_image_convert(struct ipu_soc *ipu, enum ipu_ic_task ic_task, if (IS_ERR(ctx)) return ERR_CAST(ctx); - run = kzalloc(sizeof(*run), GFP_KERNEL); + run = kzalloc_obj(*run); if (!run) { ipu_image_convert_unprepare(ctx); return ERR_PTR(-ENOMEM); diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index 174feaca0a6b..c69adaa92bbe 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -47,16 +47,12 @@ unsafe impl AsBytes for PteArray {} impl PteArray { - /// Creates a new page table array mapping `NUM_PAGES` GSP pages starting at address `start`. - fn new(start: DmaAddress) -> Result { - let mut ptes = [0u64; NUM_PAGES]; - for (i, pte) in ptes.iter_mut().enumerate() { - *pte = start - .checked_add(num::usize_as_u64(i) << GSP_PAGE_SHIFT) - .ok_or(EOVERFLOW)?; - } - - Ok(Self(ptes)) + /// Returns the page table entry for `index`, for a mapping starting at `start`. + // TODO: Replace with `IoView` projection once available. + fn entry(start: DmaAddress, index: usize) -> Result { + start + .checked_add(num::usize_as_u64(index) << GSP_PAGE_SHIFT) + .ok_or(EOVERFLOW) } } @@ -86,16 +82,22 @@ fn new(dev: &device::Device) -> Result { NUM_PAGES * GSP_PAGE_SIZE, GFP_KERNEL | __GFP_ZERO, )?); - let ptes = PteArray::::new(obj.0.dma_handle())?; + + let start_addr = obj.0.dma_handle(); // SAFETY: `obj` has just been created and we are its sole user. - unsafe { - // Copy the self-mapping PTE at the expected location. + let pte_region = unsafe { obj.0 - .as_slice_mut(size_of::(), size_of_val(&ptes))? - .copy_from_slice(ptes.as_bytes()) + .as_slice_mut(size_of::(), NUM_PAGES * size_of::())? }; + // Write values one by one to avoid an on-stack instance of `PteArray`. + for (i, chunk) in pte_region.chunks_exact_mut(size_of::()).enumerate() { + let pte_value = PteArray::<0>::entry(start_addr, i)?; + + chunk.copy_from_slice(&pte_value.to_ne_bytes()); + } + Ok(obj) } } @@ -143,14 +145,14 @@ pub(crate) fn new(pdev: &pci::Device) -> impl PinInit::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; - dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?; + dma_write!(wpr_meta, [0]?, GspFwWprMeta::new(&gsp_fw, &fb_layout)); self.cmdq .send_command(bar, commands::SetSystemInfo::new(pdev))?; diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs index 46819a82a51a..03a4f3599849 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -2,11 +2,7 @@ use core::{ cmp, - mem, - sync::atomic::{ - fence, - Ordering, // - }, // + mem, // }; use kernel::{ @@ -146,30 +142,36 @@ struct MsgqData { #[repr(C)] // There is no struct defined for this in the open-gpu-kernel-source headers. // Instead it is defined by code in `GspMsgQueuesInit()`. -struct Msgq { +// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module. +pub(super) struct Msgq { /// Header for sending messages, including the write pointer. - tx: MsgqTxHeader, + pub(super) tx: MsgqTxHeader, /// Header for receiving messages, including the read pointer. - rx: MsgqRxHeader, + pub(super) rx: MsgqRxHeader, /// The message queue proper. msgq: MsgqData, } /// Structure shared between the driver and the GSP and containing the command and message queues. #[repr(C)] -struct GspMem { +// TODO: Revert to private once `IoView` projections replace the `gsp_mem` module. +pub(super) struct GspMem { /// Self-mapping page table entries. - ptes: PteArray<{ GSP_PAGE_SIZE / size_of::() }>, + ptes: PteArray<{ Self::PTE_ARRAY_SIZE }>, /// CPU queue: the driver writes commands here, and the GSP reads them. It also contains the /// write and read pointers that the CPU updates. /// /// This member is read-only for the GSP. - cpuq: Msgq, + pub(super) cpuq: Msgq, /// GSP queue: the GSP writes messages here, and the driver reads them. It also contains the /// write and read pointers that the GSP updates. /// /// This member is read-only for the driver. - gspq: Msgq, + pub(super) gspq: Msgq, +} + +impl GspMem { + const PTE_ARRAY_SIZE: usize = GSP_PAGE_SIZE / size_of::(); } // SAFETY: These structs don't meet the no-padding requirements of AsBytes but @@ -201,9 +203,19 @@ fn new(dev: &device::Device) -> Result { let gsp_mem = CoherentAllocation::::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; - dma_write!(gsp_mem[0].ptes = PteArray::new(gsp_mem.dma_handle())?)?; - dma_write!(gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES))?; - dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new())?; + + let start = gsp_mem.dma_handle(); + // Write values one by one to avoid an on-stack instance of `PteArray`. + for i in 0..GspMem::PTE_ARRAY_SIZE { + dma_write!(gsp_mem, [0]?.ptes.0[i], PteArray::<0>::entry(start, i)?); + } + + dma_write!( + gsp_mem, + [0]?.cpuq.tx, + MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES) + ); + dma_write!(gsp_mem, [0]?.cpuq.rx, MsgqRxHeader::new()); Ok(Self(gsp_mem)) } @@ -317,12 +329,7 @@ fn allocate_command(&mut self, size: usize) -> Result> { // // - The returned value is between `0` and `MSGQ_NUM_PAGES`. fn gsp_write_ptr(&self) -> u32 { - let gsp_mem = self.0.start_ptr(); - - // SAFETY: - // - The 'CoherentAllocation' contains at least one object. - // - By the invariants of `CoherentAllocation` the pointer is valid. - (unsafe { (*gsp_mem).gspq.tx.write_ptr() } % MSGQ_NUM_PAGES) + super::fw::gsp_mem::gsp_write_ptr(&self.0) } // Returns the index of the memory page the GSP will read the next command from. @@ -331,12 +338,7 @@ fn gsp_write_ptr(&self) -> u32 { // // - The returned value is between `0` and `MSGQ_NUM_PAGES`. fn gsp_read_ptr(&self) -> u32 { - let gsp_mem = self.0.start_ptr(); - - // SAFETY: - // - The 'CoherentAllocation' contains at least one object. - // - By the invariants of `CoherentAllocation` the pointer is valid. - (unsafe { (*gsp_mem).gspq.rx.read_ptr() } % MSGQ_NUM_PAGES) + super::fw::gsp_mem::gsp_read_ptr(&self.0) } // Returns the index of the memory page the CPU can read the next message from. @@ -345,27 +347,12 @@ fn gsp_read_ptr(&self) -> u32 { // // - The returned value is between `0` and `MSGQ_NUM_PAGES`. fn cpu_read_ptr(&self) -> u32 { - let gsp_mem = self.0.start_ptr(); - - // SAFETY: - // - The ['CoherentAllocation'] contains at least one object. - // - By the invariants of CoherentAllocation the pointer is valid. - (unsafe { (*gsp_mem).cpuq.rx.read_ptr() } % MSGQ_NUM_PAGES) + super::fw::gsp_mem::cpu_read_ptr(&self.0) } // Informs the GSP that it can send `elem_count` new pages into the message queue. fn advance_cpu_read_ptr(&mut self, elem_count: u32) { - let rptr = self.cpu_read_ptr().wrapping_add(elem_count) % MSGQ_NUM_PAGES; - - // Ensure read pointer is properly ordered. - fence(Ordering::SeqCst); - - let gsp_mem = self.0.start_ptr_mut(); - - // SAFETY: - // - The 'CoherentAllocation' contains at least one object. - // - By the invariants of `CoherentAllocation` the pointer is valid. - unsafe { (*gsp_mem).cpuq.rx.set_read_ptr(rptr) }; + super::fw::gsp_mem::advance_cpu_read_ptr(&self.0, elem_count) } // Returns the index of the memory page the CPU can write the next command to. @@ -374,26 +361,12 @@ fn advance_cpu_read_ptr(&mut self, elem_count: u32) { // // - The returned value is between `0` and `MSGQ_NUM_PAGES`. fn cpu_write_ptr(&self) -> u32 { - let gsp_mem = self.0.start_ptr(); - - // SAFETY: - // - The 'CoherentAllocation' contains at least one object. - // - By the invariants of `CoherentAllocation` the pointer is valid. - (unsafe { (*gsp_mem).cpuq.tx.write_ptr() } % MSGQ_NUM_PAGES) + super::fw::gsp_mem::cpu_write_ptr(&self.0) } // Informs the GSP that it can process `elem_count` new pages from the command queue. fn advance_cpu_write_ptr(&mut self, elem_count: u32) { - let wptr = self.cpu_write_ptr().wrapping_add(elem_count) & MSGQ_NUM_PAGES; - let gsp_mem = self.0.start_ptr_mut(); - - // SAFETY: - // - The 'CoherentAllocation' contains at least one object. - // - By the invariants of `CoherentAllocation` the pointer is valid. - unsafe { (*gsp_mem).cpuq.tx.set_write_ptr(wptr) }; - - // Ensure all command data is visible before triggering the GSP read. - fence(Ordering::SeqCst); + super::fw::gsp_mem::advance_cpu_write_ptr(&self.0, elem_count) } } diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs index 83ff91614e36..040b30ec3089 100644 --- a/drivers/gpu/nova-core/gsp/fw.rs +++ b/drivers/gpu/nova-core/gsp/fw.rs @@ -40,6 +40,75 @@ }, }; +// TODO: Replace with `IoView` projections once available; the `unwrap()` calls go away once we +// switch to the new `dma::Coherent` API. +pub(super) mod gsp_mem { + use core::sync::atomic::{ + fence, + Ordering, // + }; + + use kernel::{ + dma::CoherentAllocation, + dma_read, + dma_write, + prelude::*, // + }; + + use crate::gsp::cmdq::{ + GspMem, + MSGQ_NUM_PAGES, // + }; + + pub(in crate::gsp) fn gsp_write_ptr(qs: &CoherentAllocation) -> u32 { + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { Ok(dma_read!(qs, [0]?.gspq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() + } + + pub(in crate::gsp) fn gsp_read_ptr(qs: &CoherentAllocation) -> u32 { + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { Ok(dma_read!(qs, [0]?.gspq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() + } + + pub(in crate::gsp) fn cpu_read_ptr(qs: &CoherentAllocation) -> u32 { + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { Ok(dma_read!(qs, [0]?.cpuq.rx.0.readPtr) % MSGQ_NUM_PAGES) }().unwrap() + } + + pub(in crate::gsp) fn advance_cpu_read_ptr(qs: &CoherentAllocation, count: u32) { + let rptr = cpu_read_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; + + // Ensure read pointer is properly ordered. + fence(Ordering::SeqCst); + + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { + dma_write!(qs, [0]?.cpuq.rx.0.readPtr, rptr); + Ok(()) + }() + .unwrap() + } + + pub(in crate::gsp) fn cpu_write_ptr(qs: &CoherentAllocation) -> u32 { + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { Ok(dma_read!(qs, [0]?.cpuq.tx.0.writePtr) % MSGQ_NUM_PAGES) }().unwrap() + } + + pub(in crate::gsp) fn advance_cpu_write_ptr(qs: &CoherentAllocation, count: u32) { + let wptr = cpu_write_ptr(qs).wrapping_add(count) % MSGQ_NUM_PAGES; + + // PANIC: A `dma::CoherentAllocation` always contains at least one element. + || -> Result { + dma_write!(qs, [0]?.cpuq.tx.0.writePtr, wptr); + Ok(()) + }() + .unwrap(); + + // Ensure all command data is visible before triggering the GSP read. + fence(Ordering::SeqCst); + } +} + /// Empty type to group methods related to heap parameters for running the GSP firmware. enum GspFwHeapParams {} @@ -708,22 +777,6 @@ pub(crate) fn new(msgq_size: u32, rx_hdr_offset: u32, msg_count: u32) -> Self { entryOff: num::usize_into_u32::(), }) } - - /// Returns the value of the write pointer for this queue. - pub(crate) fn write_ptr(&self) -> u32 { - let ptr = core::ptr::from_ref(&self.0.writePtr); - - // SAFETY: `ptr` is a valid pointer to a `u32`. - unsafe { ptr.read_volatile() } - } - - /// Sets the value of the write pointer for this queue. - pub(crate) fn set_write_ptr(&mut self, val: u32) { - let ptr = core::ptr::from_mut(&mut self.0.writePtr); - - // SAFETY: `ptr` is a valid pointer to a `u32`. - unsafe { ptr.write_volatile(val) } - } } // SAFETY: Padding is explicit and does not contain uninitialized data. @@ -739,22 +792,6 @@ impl MsgqRxHeader { pub(crate) fn new() -> Self { Self(Default::default()) } - - /// Returns the value of the read pointer for this queue. - pub(crate) fn read_ptr(&self) -> u32 { - let ptr = core::ptr::from_ref(&self.0.readPtr); - - // SAFETY: `ptr` is a valid pointer to a `u32`. - unsafe { ptr.read_volatile() } - } - - /// Sets the value of the read pointer for this queue. - pub(crate) fn set_read_ptr(&mut self, val: u32) { - let ptr = core::ptr::from_mut(&mut self.0.readPtr); - - // SAFETY: `ptr` is a valid pointer to a `u32`. - unsafe { ptr.write_volatile(val) } - } } // SAFETY: Padding is explicit and does not contain uninitialized data. diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 68e45a26e85f..8fe1ae3c71bb 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -297,7 +297,7 @@ static int register_client(struct pci_dev *pdev, { struct vga_switcheroo_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; diff --git a/drivers/greybus/bundle.c b/drivers/greybus/bundle.c index a6e1cca06172..d1831d0986e9 100644 --- a/drivers/greybus/bundle.c +++ b/drivers/greybus/bundle.c @@ -197,7 +197,7 @@ struct gb_bundle *gb_bundle_create(struct gb_interface *intf, u8 bundle_id, return NULL; } - bundle = kzalloc(sizeof(*bundle), GFP_KERNEL); + bundle = kzalloc_obj(*bundle); if (!bundle) return NULL; diff --git a/drivers/greybus/connection.c b/drivers/greybus/connection.c index 9c88861986c8..bd04485decb3 100644 --- a/drivers/greybus/connection.c +++ b/drivers/greybus/connection.c @@ -165,7 +165,7 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id, } hd_cport_id = ret; - connection = kzalloc(sizeof(*connection), GFP_KERNEL); + connection = kzalloc_obj(*connection); if (!connection) { ret = -ENOMEM; goto err_hd_cport_release; diff --git a/drivers/greybus/control.c b/drivers/greybus/control.c index b5cf49d09df2..aec3c8e3802a 100644 --- a/drivers/greybus/control.c +++ b/drivers/greybus/control.c @@ -446,7 +446,7 @@ struct gb_control *gb_control_create(struct gb_interface *intf) struct gb_connection *connection; struct gb_control *control; - control = kzalloc(sizeof(*control), GFP_KERNEL); + control = kzalloc_obj(*control); if (!control) return ERR_PTR(-ENOMEM); diff --git a/drivers/greybus/core.c b/drivers/greybus/core.c index 313eb65cf703..45c5437c460f 100644 --- a/drivers/greybus/core.c +++ b/drivers/greybus/core.c @@ -185,13 +185,6 @@ static void greybus_shutdown(struct device *dev) } } -const struct bus_type greybus_bus_type = { - .name = "greybus", - .match = greybus_match_device, - .uevent = greybus_uevent, - .shutdown = greybus_shutdown, -}; - static int greybus_probe(struct device *dev) { struct greybus_driver *driver = to_greybus_driver(dev->driver); @@ -252,7 +245,7 @@ static int greybus_probe(struct device *dev) return 0; } -static int greybus_remove(struct device *dev) +static void greybus_remove(struct device *dev) { struct greybus_driver *driver = to_greybus_driver(dev->driver); struct gb_bundle *bundle = to_gb_bundle(dev); @@ -291,10 +284,17 @@ static int greybus_remove(struct device *dev) pm_runtime_set_suspended(dev); pm_runtime_dont_use_autosuspend(dev); pm_runtime_put_noidle(dev); - - return 0; } +const struct bus_type greybus_bus_type = { + .name = "greybus", + .match = greybus_match_device, + .uevent = greybus_uevent, + .probe = greybus_probe, + .remove = greybus_remove, + .shutdown = greybus_shutdown, +}; + int greybus_register_driver(struct greybus_driver *driver, struct module *owner, const char *mod_name) { @@ -305,8 +305,6 @@ int greybus_register_driver(struct greybus_driver *driver, struct module *owner, driver->driver.bus = &greybus_bus_type; driver->driver.name = driver->name; - driver->driver.probe = greybus_probe; - driver->driver.remove = greybus_remove; driver->driver.owner = owner; driver->driver.mod_name = mod_name; diff --git a/drivers/greybus/es2.c b/drivers/greybus/es2.c index 7630a36ecf81..6ae0ac828afa 100644 --- a/drivers/greybus/es2.c +++ b/drivers/greybus/es2.c @@ -547,7 +547,7 @@ static int cport_enable(struct gb_host_device *hd, u16 cport_id, u32 connection_flags; int ret; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -883,7 +883,7 @@ static struct arpc *arpc_alloc(void *payload, u16 size, u8 type) if (size + sizeof(*rpc->req) > ARPC_OUT_SIZE_MAX) return NULL; - rpc = kzalloc(sizeof(*rpc), GFP_KERNEL); + rpc = kzalloc_obj(*rpc); if (!rpc) return NULL; @@ -892,7 +892,7 @@ static struct arpc *arpc_alloc(void *payload, u16 size, u8 type) if (!rpc->req) goto err_free_rpc; - rpc->resp = kzalloc(sizeof(*rpc->resp), GFP_KERNEL); + rpc->resp = kzalloc_obj(*rpc->resp); if (!rpc->resp) goto err_free_req; @@ -1203,7 +1203,7 @@ static int apb_get_cport_count(struct usb_device *udev) int retval; __le16 *cport_count; - cport_count = kzalloc(sizeof(*cport_count), GFP_KERNEL); + cport_count = kzalloc_obj(*cport_count); if (!cport_count) return -ENOMEM; diff --git a/drivers/greybus/interface.c b/drivers/greybus/interface.c index a0f3e9422721..4ee4bda4a267 100644 --- a/drivers/greybus/interface.c +++ b/drivers/greybus/interface.c @@ -789,7 +789,7 @@ struct gb_interface *gb_interface_create(struct gb_module *module, struct gb_host_device *hd = module->hd; struct gb_interface *intf; - intf = kzalloc(sizeof(*intf), GFP_KERNEL); + intf = kzalloc_obj(*intf); if (!intf) return NULL; diff --git a/drivers/greybus/manifest.c b/drivers/greybus/manifest.c index dd7040697bde..9be5d95da587 100644 --- a/drivers/greybus/manifest.c +++ b/drivers/greybus/manifest.c @@ -157,7 +157,7 @@ static int identify_descriptor(struct gb_interface *intf, expected_size, desc_size); } - descriptor = kzalloc(sizeof(*descriptor), GFP_KERNEL); + descriptor = kzalloc_obj(*descriptor); if (!descriptor) return -ENOMEM; @@ -275,8 +275,7 @@ static u32 gb_manifest_parse_cports(struct gb_bundle *bundle) if (!count) return 0; - bundle->cport_desc = kcalloc(count, sizeof(*bundle->cport_desc), - GFP_KERNEL); + bundle->cport_desc = kzalloc_objs(*bundle->cport_desc, count); if (!bundle->cport_desc) goto exit; diff --git a/drivers/greybus/module.c b/drivers/greybus/module.c index 7f7153a1dd60..709da8ef5071 100644 --- a/drivers/greybus/module.c +++ b/drivers/greybus/module.c @@ -93,8 +93,7 @@ struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id, struct gb_module *module; int i; - module = kzalloc(struct_size(module, interfaces, num_interfaces), - GFP_KERNEL); + module = kzalloc_flex(*module, interfaces, num_interfaces); if (!module) return NULL; diff --git a/drivers/greybus/svc.c b/drivers/greybus/svc.c index 35ea7147dca6..1b854f53f21e 100644 --- a/drivers/greybus/svc.c +++ b/drivers/greybus/svc.c @@ -782,8 +782,7 @@ static void gb_svc_pwrmon_debugfs_init(struct gb_svc *svc) if (!rail_names) goto err_pwrmon_debugfs; - svc->pwrmon_rails = kcalloc(rail_count, sizeof(*svc->pwrmon_rails), - GFP_KERNEL); + svc->pwrmon_rails = kzalloc_objs(*svc->pwrmon_rails, rail_count); if (!svc->pwrmon_rails) goto err_pwrmon_debugfs_free; @@ -1128,7 +1127,7 @@ static int gb_svc_queue_deferred_request(struct gb_operation *operation) struct gb_svc *svc = gb_connection_get_data(operation->connection); struct gb_svc_deferred_request *dr; - dr = kmalloc(sizeof(*dr), GFP_KERNEL); + dr = kmalloc_obj(*dr); if (!dr) return -ENOMEM; @@ -1315,7 +1314,7 @@ struct gb_svc *gb_svc_create(struct gb_host_device *hd) { struct gb_svc *svc; - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) return NULL; diff --git a/drivers/greybus/svc_watchdog.c b/drivers/greybus/svc_watchdog.c index b6b1682c19c4..16e6de5e9eff 100644 --- a/drivers/greybus/svc_watchdog.c +++ b/drivers/greybus/svc_watchdog.c @@ -112,7 +112,7 @@ int gb_svc_watchdog_create(struct gb_svc *svc) if (svc->watchdog) return 0; - watchdog = kmalloc(sizeof(*watchdog), GFP_KERNEL); + watchdog = kmalloc_obj(*watchdog); if (!watchdog) return -ENOMEM; diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 2fab4964d21c..aa3c103d0894 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -107,7 +107,6 @@ menu "Special HID drivers" config HID_A4TECH tristate "A4TECH mice" - default !EXPERT help Support for some A4TECH mice with two scroll wheels. @@ -140,7 +139,6 @@ config HID_APPLE tristate "Apple {i,Power,Mac}Books" depends on LEDS_CLASS depends on NEW_LEDS - default !EXPERT help Support for some Apple devices which less or more break HID specification. @@ -209,7 +207,6 @@ config HID_AUREAL config HID_BELKIN tristate "Belkin Flip KVM and Wireless keyboard" - default !EXPERT help Support for Belkin Flip KVM and Wireless keyboard. @@ -237,14 +234,12 @@ config HID_BIGBEN_FF config HID_CHERRY tristate "Cherry Cymotion keyboard" - default !EXPERT help Support for Cherry Cymotion keyboard. config HID_CHICONY tristate "Chicony devices" depends on USB_HID - default !EXPERT help Support for Chicony Tactical pad and special keys on Chicony keyboards. @@ -322,7 +317,6 @@ config HID_CREATIVE_SB0540 config HID_CYPRESS tristate "Cypress mouse and barcode readers" - default !EXPERT help Support for cypress mouse and barcode readers. @@ -388,7 +382,6 @@ config HID_EVISION config HID_EZKEY tristate "Ezkey BTC 8193 keyboard" - default !EXPERT help Support for Ezkey BTC 8193 keyboard. @@ -564,7 +557,6 @@ config HID_ICADE config HID_ITE tristate "ITE devices" - default !EXPERT help Support for ITE devices not fully compliant with HID standard. @@ -585,7 +577,6 @@ config HID_TWINHAN config HID_KENSINGTON tristate "Kensington Slimblade Trackball" - default !EXPERT help Support for Kensington Slimblade Trackball. @@ -642,7 +633,6 @@ config HID_LOGITECH depends on USB_HID depends on LEDS_CLASS depends on LEDS_CLASS_MULTICOLOR - default !EXPERT help Support for Logitech devices that are not fully compliant with HID standard. @@ -757,20 +747,17 @@ config HID_MEGAWORLD_FF config HID_REDRAGON tristate "Redragon keyboards" - default !EXPERT help Support for Redragon keyboards that need fix-ups to work properly. config HID_MICROSOFT tristate "Microsoft non-fully HID-compliant devices" - default !EXPERT select INPUT_FF_MEMLESS help Support for Microsoft devices that are not fully compliant with HID standard. config HID_MONTEREY tristate "Monterey Genius KB29E keyboard" - default !EXPERT help Support for Monterey Genius KB29E. diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index 7017bfa59093..96ae792beeb6 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c @@ -47,7 +47,7 @@ int amd_sfh_get_report(struct hid_device *hid, int report_id, int report_type) guard(mutex)(&mp2->lock); for (i = 0; i < cli_data->num_hid_devices; i++) { if (cli_data->hid_sensor_hubs[i] == hid) { - struct request_list *new = kzalloc(sizeof(*new), GFP_KERNEL); + struct request_list *new = kzalloc_obj(*new); if (!new) return -ENOMEM; diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c index 81f3024b7b1b..b04f675d49b0 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_hid.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_hid.c @@ -135,7 +135,7 @@ int amdtp_hid_probe(u32 cur_hid_dev, struct amdtp_cl_data *cli_data) if (IS_ERR(hid)) return PTR_ERR(hid); - hid_data = kzalloc(sizeof(*hid_data), GFP_KERNEL); + hid_data = kzalloc_obj(*hid_data); if (!hid_data) { rc = -ENOMEM; goto err_hid_data; diff --git a/drivers/hid/bpf/hid_bpf_dispatch.c b/drivers/hid/bpf/hid_bpf_dispatch.c index 33af17fdc729..50c7b45c59e3 100644 --- a/drivers/hid/bpf/hid_bpf_dispatch.c +++ b/drivers/hid/bpf/hid_bpf_dispatch.c @@ -320,7 +320,7 @@ hid_bpf_allocate_context(unsigned int hid_id) if (IS_ERR(hdev)) return NULL; - ctx_kern = kzalloc(sizeof(*ctx_kern), GFP_KERNEL); + ctx_kern = kzalloc_obj(*ctx_kern); if (!ctx_kern) { hid_put_device(hdev); return NULL; diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index cb1bd6dca835..bf7dd0fbf249 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -623,17 +623,19 @@ static int apple_fetch_battery(struct hid_device *hdev) struct apple_sc *asc = hid_get_drvdata(hdev); struct hid_report_enum *report_enum; struct hid_report *report; + struct hid_battery *bat; - if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery) + bat = hid_get_battery(hdev); + if (!(asc->quirks & APPLE_RDESC_BATTERY) || !bat) return -1; - report_enum = &hdev->report_enum[hdev->battery_report_type]; - report = report_enum->report_id_hash[hdev->battery_report_id]; + report_enum = &hdev->report_enum[bat->report_type]; + report = report_enum->report_id_hash[bat->report_id]; if (!report || report->maxfield < 1) return -1; - if (hdev->battery_capacity == hdev->battery_max) + if (bat->capacity == bat->max) return -1; hid_hw_request(hdev, report, HID_REQ_GET_REPORT); @@ -795,7 +797,7 @@ static int apple_backlight_set(struct hid_device *hdev, u16 value, u16 rate) int ret = 0; struct apple_backlight_set_report *rep; - rep = kmalloc(sizeof(*rep), GFP_KERNEL); + rep = kmalloc_obj(*rep); if (rep == NULL) return -ENOMEM; diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index fbe4e16ab029..3c5c2bf02425 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -96,7 +96,7 @@ static int axff_init(struct hid_device *hid) return -ENODEV; } - axff = kzalloc(sizeof(struct axff_device), GFP_KERNEL); + axff = kzalloc_obj(struct axff_device); if (!axff) return -ENOMEM; diff --git a/drivers/hid/hid-betopff.c b/drivers/hid/hid-betopff.c index a6d5f030d023..8a7fe895926c 100644 --- a/drivers/hid/hid-betopff.c +++ b/drivers/hid/hid-betopff.c @@ -100,7 +100,7 @@ static int betopff_init(struct hid_device *hid) } } - betopff = kzalloc(sizeof(*betopff), GFP_KERNEL); + betopff = kzalloc_obj(*betopff); if (!betopff) return -ENOMEM; diff --git a/drivers/hid/hid-cmedia.c b/drivers/hid/hid-cmedia.c index 8bf5649b0c79..7b3dd4197875 100644 --- a/drivers/hid/hid-cmedia.c +++ b/drivers/hid/hid-cmedia.c @@ -145,7 +145,7 @@ static int cmhid_probe(struct hid_device *hid, const struct hid_device_id *id) int ret; struct cmhid *cm; - cm = kzalloc(sizeof(struct cmhid), GFP_KERNEL); + cm = kzalloc_obj(struct cmhid); if (!cm) { ret = -ENOMEM; goto allocfail; diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f5587b786f87..dd78884a200a 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -71,6 +71,9 @@ static u32 s32ton(__s32 value, unsigned int n) if (!value || !n) return 0; + if (n > 32) + n = 32; + a = value >> (n - 1); if (a && a != -1) return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; @@ -93,7 +96,7 @@ struct hid_report *hid_register_report(struct hid_device *device, if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; - report = kzalloc(sizeof(struct hid_report), GFP_KERNEL); + report = kzalloc_obj(struct hid_report); if (!report) return NULL; @@ -924,7 +927,6 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item) */ static int hid_scan_report(struct hid_device *hid) { - struct hid_parser *parser; struct hid_item item; const __u8 *start = hid->dev_rdesc; const __u8 *end = start + hid->dev_rsize; @@ -936,7 +938,7 @@ static int hid_scan_report(struct hid_device *hid) hid_parser_reserved }; - parser = vzalloc(sizeof(struct hid_parser)); + struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser)); if (!parser) return -ENOMEM; @@ -987,7 +989,6 @@ static int hid_scan_report(struct hid_device *hid) } kfree(parser->collection_stack); - vfree(parser); return 0; } @@ -1244,6 +1245,90 @@ void hid_setup_resolution_multiplier(struct hid_device *hid) } EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier); +static int hid_parse_collections(struct hid_device *device) +{ + struct hid_item item; + const u8 *start = device->rdesc; + const u8 *end = start + device->rsize; + const u8 *next; + int ret; + static typeof(hid_parser_main) (* const dispatch_type[]) = { + hid_parser_main, + hid_parser_global, + hid_parser_local, + hid_parser_reserved + }; + + struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser)); + if (!parser) + return -ENOMEM; + + parser->device = device; + + device->collection = kzalloc_objs(*device->collection, + HID_DEFAULT_NUM_COLLECTIONS); + if (!device->collection) + return -ENOMEM; + + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; + for (unsigned int i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) + device->collection[i].parent_idx = -1; + + ret = -EINVAL; + if (start == end) { + hid_err(device, "rejecting 0-sized report descriptor\n"); + goto out; + } + + while ((next = fetch_item(start, end, &item)) != NULL) { + start = next; + + if (item.format != HID_ITEM_FORMAT_SHORT) { + hid_err(device, "unexpected long global item\n"); + goto out; + } + + if (dispatch_type[item.type](parser, &item)) { + hid_err(device, "item %u %u %u %u parsing failed\n", + item.format, + (unsigned int)item.size, + (unsigned int)item.type, + (unsigned int)item.tag); + goto out; + } + } + + if (start != end) { + hid_err(device, "item fetching failed at offset %u/%u\n", + device->rsize - (unsigned int)(end - start), + device->rsize); + goto out; + } + + if (parser->collection_stack_ptr) { + hid_err(device, "unbalanced collection at end of report description\n"); + goto out; + } + + if (parser->local.delimiter_depth) { + hid_err(device, "unbalanced delimiter at end of report description\n"); + goto out; + } + + /* + * fetch initial values in case the device's + * default multiplier isn't the recommended 1 + */ + hid_setup_resolution_multiplier(device); + + device->status |= HID_STAT_PARSED; + ret = 0; + +out: + kfree(parser->collection_stack); + return ret; +} + /** * hid_open_report - open a driver-specific device report * @@ -1258,21 +1343,9 @@ EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier); */ int hid_open_report(struct hid_device *device) { - struct hid_parser *parser; - struct hid_item item; unsigned int size; - const __u8 *start; - const __u8 *end; - const __u8 *next; - int ret; - int i; - static int (*dispatch_type[])(struct hid_parser *parser, - struct hid_item *item) = { - hid_parser_main, - hid_parser_global, - hid_parser_local, - hid_parser_reserved - }; + const u8 *start; + int error; if (WARN_ON(device->status & HID_STAT_PARSED)) return -EBUSY; @@ -1288,9 +1361,9 @@ int hid_open_report(struct hid_device *device) * on a copy of our report descriptor so it can * change it. */ - __u8 *buf = kmemdup(start, size, GFP_KERNEL); + u8 *buf __free(kfree) = kmemdup(start, size, GFP_KERNEL); - if (buf == NULL) + if (!buf) return -ENOMEM; start = device->driver->report_fixup(device, buf, &size); @@ -1301,82 +1374,20 @@ int hid_open_report(struct hid_device *device) * needs to be cleaned up or not at the end. */ start = kmemdup(start, size, GFP_KERNEL); - kfree(buf); - if (start == NULL) + if (!start) return -ENOMEM; } device->rdesc = start; device->rsize = size; - parser = vzalloc(sizeof(struct hid_parser)); - if (!parser) { - ret = -ENOMEM; - goto alloc_err; + error = hid_parse_collections(device); + if (error) { + hid_close_report(device); + return error; } - parser->device = device; - - end = start + size; - - device->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, - sizeof(struct hid_collection), GFP_KERNEL); - if (!device->collection) { - ret = -ENOMEM; - goto err; - } - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; - for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) - device->collection[i].parent_idx = -1; - - ret = -EINVAL; - while ((next = fetch_item(start, end, &item)) != NULL) { - start = next; - - if (item.format != HID_ITEM_FORMAT_SHORT) { - hid_err(device, "unexpected long global item\n"); - goto err; - } - - if (dispatch_type[item.type](parser, &item)) { - hid_err(device, "item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, - (unsigned)item.type, (unsigned)item.tag); - goto err; - } - - if (start == end) { - if (parser->collection_stack_ptr) { - hid_err(device, "unbalanced collection at end of report description\n"); - goto err; - } - if (parser->local.delimiter_depth) { - hid_err(device, "unbalanced delimiter at end of report description\n"); - goto err; - } - - /* - * fetch initial values in case the device's - * default multiplier isn't the recommended 1 - */ - hid_setup_resolution_multiplier(device); - - kfree(parser->collection_stack); - vfree(parser); - device->status |= HID_STAT_PARSED; - - return 0; - } - } - - hid_err(device, "item fetching failed at offset %u/%u\n", - size - (unsigned int)(end - start), size); -err: - kfree(parser->collection_stack); -alloc_err: - vfree(parser); - hid_close_report(device); - return ret; + return 0; } EXPORT_SYMBOL_GPL(hid_open_report); @@ -1796,7 +1807,7 @@ static void hid_report_process_ordering(struct hid_device *hid, } /* allocate the memory to process the fields */ - entries = kcalloc(count, sizeof(*entries), GFP_KERNEL); + entries = kzalloc_objs(*entries, count); if (!entries) return; @@ -1989,11 +2000,11 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, int __hid_request(struct hid_device *hid, struct hid_report *report, enum hid_class_request reqtype) { - char *buf, *data_buf; + u8 *data_buf; int ret; u32 len; - buf = hid_alloc_report_buf(report, GFP_KERNEL); + u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -2012,17 +2023,13 @@ int __hid_request(struct hid_device *hid, struct hid_report *report, ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype); if (ret < 0) { dbg_hid("unable to complete request: %d\n", ret); - goto out; + return ret; } if (reqtype == HID_REQ_GET_REPORT) hid_input_report(hid, report->type, buf, ret, 0); - ret = 0; - -out: - kfree(buf); - return ret; + return 0; } EXPORT_SYMBOL_GPL(__hid_request); @@ -2611,7 +2618,7 @@ static ssize_t new_id_store(struct device_driver *drv, const char *buf, if (ret < 3) return -EINVAL; - dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); + dynid = kzalloc_obj(*dynid); if (!dynid) return -ENOMEM; @@ -2973,7 +2980,7 @@ struct hid_device *hid_allocate_device(void) struct hid_device *hdev; int ret = -ENOMEM; - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); + hdev = kzalloc_obj(*hdev); if (hdev == NULL) return ERR_PTR(ret); @@ -2991,6 +2998,10 @@ struct hid_device *hid_allocate_device(void) mutex_init(&hdev->ll_open_lock); kref_init(&hdev->ref); +#ifdef CONFIG_HID_BATTERY_STRENGTH + INIT_LIST_HEAD(&hdev->batteries); +#endif + ret = hid_bpf_device_init(hdev); if (ret) goto out_err; diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 62b99f5c3cf8..21cd8b12a757 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -427,7 +427,7 @@ static int k90_init_backlight(struct hid_device *dev) size_t name_sz; char *name; - drvdata->backlight = kzalloc(sizeof(struct k90_led), GFP_KERNEL); + drvdata->backlight = kzalloc_obj(struct k90_led); if (!drvdata->backlight) { ret = -ENOMEM; goto fail_backlight_alloc; @@ -471,7 +471,7 @@ static int k90_init_macro_functions(struct hid_device *dev) size_t name_sz; char *name; - k90 = kzalloc(sizeof(struct k90_drvdata), GFP_KERNEL); + k90 = kzalloc_obj(struct k90_drvdata); if (!k90) { ret = -ENOMEM; goto fail_drvdata; diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c index 5596dd940322..ad027c45f162 100644 --- a/drivers/hid/hid-cougar.c +++ b/drivers/hid/hid-cougar.c @@ -166,7 +166,7 @@ static int cougar_bind_shared_data(struct hid_device *hdev, shared = cougar_get_shared_data(hdev); if (!shared) { - shared = kzalloc(sizeof(*shared), GFP_KERNEL); + shared = kzalloc_obj(*shared); if (!shared) { error = -ENOMEM; goto out; diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index a8d2b36a7852..f44e6e708404 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -3687,7 +3687,7 @@ static int hid_debug_events_open(struct inode *inode, struct file *file) struct hid_debug_list *list; unsigned long flags; - if (!(list = kzalloc(sizeof(struct hid_debug_list), GFP_KERNEL))) { + if (!(list = kzalloc_obj(struct hid_debug_list))) { err = -ENOMEM; goto out; } diff --git a/drivers/hid/hid-dr.c b/drivers/hid/hid-dr.c index 84e1e90a266b..8a8f68a7feb0 100644 --- a/drivers/hid/hid-dr.c +++ b/drivers/hid/hid-dr.c @@ -104,7 +104,7 @@ static int drff_init(struct hid_device *hid) return -ENODEV; } - drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL); + drff = kzalloc_obj(struct drff_device); if (!drff) return -ENOMEM; diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c index cf17bdd14d9c..b8f5f3eb53a4 100644 --- a/drivers/hid/hid-elo.c +++ b/drivers/hid/hid-elo.c @@ -232,7 +232,7 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) if (!hid_is_usb(hdev)) return -EINVAL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index 60bfb6a924d7..1b4ad18f6051 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -76,7 +76,7 @@ static int emsff_init(struct hid_device *hid) return -ENODEV; } - emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL); + emsff = kzalloc_obj(struct emsff_device); if (!emsff) return -ENOMEM; diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index c6db8b6cc8ee..8b99686b63df 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -96,7 +96,7 @@ static int gaff_init(struct hid_device *hid) return -ENODEV; } - gaff = kzalloc(sizeof(struct gaff_device), GFP_KERNEL); + gaff = kzalloc_obj(struct gaff_device); if (!gaff) return -ENOMEM; diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index 4c1ccf7a267a..1af477e58480 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c @@ -59,8 +59,7 @@ static int cbas_ec_query_base(struct cros_ec_device *ec_dev, bool get_state, struct cros_ec_command *msg; int ret; - msg = kzalloc(struct_size(msg, data, max(sizeof(u32), sizeof(*params))), - GFP_KERNEL); + msg = kzalloc_flex(*msg, data, max(sizeof(u32), sizeof(*params))); if (!msg) return -ENOMEM; diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c index fc8a9997f815..deadab28cdbe 100644 --- a/drivers/hid/hid-haptic.c +++ b/drivers/hid/hid-haptic.c @@ -474,8 +474,7 @@ int hid_haptic_init(struct hid_device *hdev, ret = -ENOMEM; goto duration_map; } - haptic->effect = kcalloc(FF_MAX_EFFECTS, - sizeof(struct hid_haptic_effect), GFP_KERNEL); + haptic->effect = kzalloc_objs(struct hid_haptic_effect, FF_MAX_EFFECTS); if (!haptic->effect) { ret = -ENOMEM; goto output_queue; diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c index 8619b80c834c..32d08f7a660d 100644 --- a/drivers/hid/hid-holtekff.c +++ b/drivers/hid/hid-holtekff.c @@ -149,7 +149,7 @@ static int holtekff_init(struct hid_device *hid) return -ENODEV; } - holtekff = kzalloc(sizeof(*holtekff), GFP_KERNEL); + holtekff = kzalloc_obj(*holtekff); if (!holtekff) return -ENOMEM; diff --git a/drivers/hid/hid-hyperv.c b/drivers/hid/hid-hyperv.c index 9eafff0b6ea4..7d2b0063df15 100644 --- a/drivers/hid/hid-hyperv.c +++ b/drivers/hid/hid-hyperv.c @@ -149,7 +149,7 @@ static struct mousevsc_dev *mousevsc_alloc_device(struct hv_device *device) { struct mousevsc_dev *input_dev; - input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL); + input_dev = kzalloc_obj(struct mousevsc_dev); if (!input_dev) return NULL; diff --git a/drivers/hid/hid-input-test.c b/drivers/hid/hid-input-test.c index 6f5c71660d82..c92008dafddf 100644 --- a/drivers/hid/hid-input-test.c +++ b/drivers/hid/hid-input-test.c @@ -9,54 +9,59 @@ static void hid_test_input_update_battery_charge_status(struct kunit *test) { - struct hid_device *dev; + struct hid_battery *bat; bool handled; - dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + bat = kunit_kzalloc(test, sizeof(*bat), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bat); - handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0); + handled = hidinput_update_battery_charge_status(bat, HID_DG_HEIGHT, 0); KUNIT_EXPECT_FALSE(test, handled); - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_UNKNOWN); - handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0); + handled = hidinput_update_battery_charge_status(bat, HID_BAT_CHARGING, 0); KUNIT_EXPECT_TRUE(test, handled); - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_DISCHARGING); - handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1); + handled = hidinput_update_battery_charge_status(bat, HID_BAT_CHARGING, 1); KUNIT_EXPECT_TRUE(test, handled); - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_CHARGING); } static void hid_test_input_get_battery_property(struct kunit *test) { struct power_supply *psy; + struct hid_battery *bat; struct hid_device *dev; union power_supply_propval val; int ret; dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); - dev->battery_avoid_query = true; + + bat = kunit_kzalloc(test, sizeof(*bat), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bat); + bat->dev = dev; + bat->avoid_query = true; psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy); - psy->drv_data = dev; + psy->drv_data = bat; - dev->battery_status = HID_BATTERY_UNKNOWN; - dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; + bat->status = HID_BATTERY_UNKNOWN; + bat->charge_status = POWER_SUPPLY_STATUS_CHARGING; ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN); - dev->battery_status = HID_BATTERY_REPORTED; - dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; + bat->status = HID_BATTERY_REPORTED; + bat->charge_status = POWER_SUPPLY_STATUS_CHARGING; ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING); - dev->battery_status = HID_BATTERY_REPORTED; - dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + bat->status = HID_BATTERY_REPORTED; + bat->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); KUNIT_EXPECT_EQ(test, ret, 0); KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING); diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index ce9c3251287d..d73cfa2e73d3 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -416,43 +416,39 @@ static unsigned find_battery_quirk(struct hid_device *hdev) return quirks; } -static int hidinput_scale_battery_capacity(struct hid_device *dev, +static int hidinput_scale_battery_capacity(struct hid_battery *bat, int value) { - if (dev->battery_min < dev->battery_max && - value >= dev->battery_min && value <= dev->battery_max) - value = ((value - dev->battery_min) * 100) / - (dev->battery_max - dev->battery_min); + if (bat->min < bat->max && + value >= bat->min && value <= bat->max) + value = ((value - bat->min) * 100) / + (bat->max - bat->min); return value; } -static int hidinput_query_battery_capacity(struct hid_device *dev) +static int hidinput_query_battery_capacity(struct hid_battery *bat) { - u8 *buf; int ret; - buf = kmalloc(4, GFP_KERNEL); + u8 *buf __free(kfree) = kmalloc(4, GFP_KERNEL); if (!buf) return -ENOMEM; - ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 4, - dev->battery_report_type, HID_REQ_GET_REPORT); - if (ret < 2) { - kfree(buf); + ret = hid_hw_raw_request(bat->dev, bat->report_id, buf, 4, + bat->report_type, HID_REQ_GET_REPORT); + if (ret < 2) return -ENODATA; - } - ret = hidinput_scale_battery_capacity(dev, buf[1]); - kfree(buf); - return ret; + return hidinput_scale_battery_capacity(bat, buf[1]); } static int hidinput_get_battery_property(struct power_supply *psy, enum power_supply_property prop, union power_supply_propval *val) { - struct hid_device *dev = power_supply_get_drvdata(psy); + struct hid_battery *bat = power_supply_get_drvdata(psy); + struct hid_device *dev = bat->dev; int value; int ret = 0; @@ -462,17 +458,17 @@ static int hidinput_get_battery_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_PRESENT: - val->intval = dev->battery_present; + val->intval = bat->present; break; case POWER_SUPPLY_PROP_CAPACITY: - if (dev->battery_status != HID_BATTERY_REPORTED && - !dev->battery_avoid_query) { - value = hidinput_query_battery_capacity(dev); + if (bat->status != HID_BATTERY_REPORTED && + !bat->avoid_query) { + value = hidinput_query_battery_capacity(bat); if (value < 0) return value; } else { - value = dev->battery_capacity; + value = bat->capacity; } val->intval = value; @@ -483,20 +479,20 @@ static int hidinput_get_battery_property(struct power_supply *psy, break; case POWER_SUPPLY_PROP_STATUS: - if (dev->battery_status != HID_BATTERY_REPORTED && - !dev->battery_avoid_query) { - value = hidinput_query_battery_capacity(dev); + if (bat->status != HID_BATTERY_REPORTED && + !bat->avoid_query) { + value = hidinput_query_battery_capacity(bat); if (value < 0) return value; - dev->battery_capacity = value; - dev->battery_status = HID_BATTERY_QUERIED; + bat->capacity = value; + bat->status = HID_BATTERY_QUERIED; } - if (dev->battery_status == HID_BATTERY_UNKNOWN) + if (bat->status == HID_BATTERY_UNKNOWN) val->intval = POWER_SUPPLY_STATUS_UNKNOWN; else - val->intval = dev->battery_charge_status; + val->intval = bat->charge_status; break; case POWER_SUPPLY_PROP_SCOPE: @@ -511,36 +507,59 @@ static int hidinput_get_battery_property(struct power_supply *psy, return ret; } +static struct hid_battery *hidinput_find_battery(struct hid_device *dev, + int report_id) +{ + struct hid_battery *bat; + + list_for_each_entry(bat, &dev->batteries, list) { + if (bat->report_id == report_id) + return bat; + } + return NULL; +} + static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, struct hid_field *field, bool is_percentage) { + struct hid_battery *bat; struct power_supply_desc *psy_desc; - struct power_supply_config psy_cfg = { .drv_data = dev, }; + struct power_supply_config psy_cfg = { 0 }; unsigned quirks; s32 min, max; int error; - if (dev->battery) - return 0; /* already initialized? */ + /* Check if battery for this report ID already exists */ + if (hidinput_find_battery(dev, field->report->id)) + return 0; quirks = find_battery_quirk(dev); - hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", - dev->bus, dev->vendor, dev->product, dev->version, quirks); + hid_dbg(dev, "device %x:%x:%x %d quirks %d report_id %d\n", + dev->bus, dev->vendor, dev->product, dev->version, quirks, + field->report->id); if (quirks & HID_BATTERY_QUIRK_IGNORE) return 0; - psy_desc = kzalloc(sizeof(*psy_desc), GFP_KERNEL); - if (!psy_desc) + bat = devm_kzalloc(&dev->dev, sizeof(*bat), GFP_KERNEL); + if (!bat) return -ENOMEM; - psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", - strlen(dev->uniq) ? - dev->uniq : dev_name(&dev->dev)); + psy_desc = devm_kzalloc(&dev->dev, sizeof(*psy_desc), GFP_KERNEL); + if (!psy_desc) { + error = -ENOMEM; + goto err_free_bat; + } + + psy_desc->name = devm_kasprintf(&dev->dev, GFP_KERNEL, + "hid-%s-battery-%d", + strlen(dev->uniq) ? + dev->uniq : dev_name(&dev->dev), + field->report->id); if (!psy_desc->name) { error = -ENOMEM; - goto err_free_mem; + goto err_free_desc; } psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; @@ -560,102 +579,95 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, if (quirks & HID_BATTERY_QUIRK_FEATURE) report_type = HID_FEATURE_REPORT; - dev->battery_min = min; - dev->battery_max = max; - dev->battery_report_type = report_type; - dev->battery_report_id = field->report->id; - dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + bat->dev = dev; + bat->min = min; + bat->max = max; + bat->report_type = report_type; + bat->report_id = field->report->id; + bat->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; + bat->status = HID_BATTERY_UNKNOWN; /* * Stylus is normally not connected to the device and thus we * can't query the device and get meaningful battery strength. * We have to wait for the device to report it on its own. */ - dev->battery_avoid_query = report_type == HID_INPUT_REPORT && - field->physical == HID_DG_STYLUS; + bat->avoid_query = report_type == HID_INPUT_REPORT && + field->physical == HID_DG_STYLUS; if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY) - dev->battery_avoid_query = true; + bat->avoid_query = true; - dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; + bat->present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; - dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); - if (IS_ERR(dev->battery)) { - error = PTR_ERR(dev->battery); + psy_cfg.drv_data = bat; + bat->ps = devm_power_supply_register(&dev->dev, psy_desc, &psy_cfg); + if (IS_ERR(bat->ps)) { + error = PTR_ERR(bat->ps); hid_warn(dev, "can't register power supply: %d\n", error); goto err_free_name; } - power_supply_powers(dev->battery, &dev->dev); + power_supply_powers(bat->ps, &dev->dev); + list_add_tail(&bat->list, &dev->batteries); return 0; err_free_name: - kfree(psy_desc->name); -err_free_mem: - kfree(psy_desc); - dev->battery = NULL; + devm_kfree(&dev->dev, psy_desc->name); +err_free_desc: + devm_kfree(&dev->dev, psy_desc); +err_free_bat: + devm_kfree(&dev->dev, bat); return error; } -static void hidinput_cleanup_battery(struct hid_device *dev) -{ - const struct power_supply_desc *psy_desc; - - if (!dev->battery) - return; - - psy_desc = dev->battery->desc; - power_supply_unregister(dev->battery); - kfree(psy_desc->name); - kfree(psy_desc); - dev->battery = NULL; -} - -static bool hidinput_update_battery_charge_status(struct hid_device *dev, +static bool hidinput_update_battery_charge_status(struct hid_battery *bat, unsigned int usage, int value) { switch (usage) { case HID_BAT_CHARGING: - dev->battery_charge_status = value ? - POWER_SUPPLY_STATUS_CHARGING : - POWER_SUPPLY_STATUS_DISCHARGING; + bat->charge_status = value ? + POWER_SUPPLY_STATUS_CHARGING : + POWER_SUPPLY_STATUS_DISCHARGING; return true; } return false; } -static void hidinput_update_battery(struct hid_device *dev, unsigned int usage, - int value) +static void hidinput_update_battery(struct hid_device *dev, int report_id, + unsigned int usage, int value) { + struct hid_battery *bat; int capacity; - if (!dev->battery) + bat = hidinput_find_battery(dev, report_id); + if (!bat) return; - if (hidinput_update_battery_charge_status(dev, usage, value)) { - dev->battery_present = true; - power_supply_changed(dev->battery); + if (hidinput_update_battery_charge_status(bat, usage, value)) { + bat->present = true; + power_supply_changed(bat->ps); return; } if ((usage & HID_USAGE_PAGE) == HID_UP_DIGITIZER && value == 0) return; - if (value < dev->battery_min || value > dev->battery_max) + if (value < bat->min || value > bat->max) return; - capacity = hidinput_scale_battery_capacity(dev, value); + capacity = hidinput_scale_battery_capacity(bat, value); - if (dev->battery_status != HID_BATTERY_REPORTED || - capacity != dev->battery_capacity || - ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) { - dev->battery_present = true; - dev->battery_capacity = capacity; - dev->battery_status = HID_BATTERY_REPORTED; - dev->battery_ratelimit_time = + if (bat->status != HID_BATTERY_REPORTED || + capacity != bat->capacity || + ktime_after(ktime_get_coarse(), bat->ratelimit_time)) { + bat->present = true; + bat->capacity = capacity; + bat->status = HID_BATTERY_REPORTED; + bat->ratelimit_time = ktime_add_ms(ktime_get_coarse(), 30 * 1000); - power_supply_changed(dev->battery); + power_supply_changed(bat->ps); } } #else /* !CONFIG_HID_BATTERY_STRENGTH */ @@ -665,12 +677,8 @@ static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, return 0; } -static void hidinput_cleanup_battery(struct hid_device *dev) -{ -} - -static void hidinput_update_battery(struct hid_device *dev, unsigned int usage, - int value) +static void hidinput_update_battery(struct hid_device *dev, int report_id, + unsigned int usage, int value) { } #endif /* CONFIG_HID_BATTERY_STRENGTH */ @@ -1557,7 +1565,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct return; if (usage->type == EV_PWR) { - hidinput_update_battery(hid, usage->hid, value); + hidinput_update_battery(hid, report->id, usage->hid, value); return; } @@ -1839,7 +1847,6 @@ static void hidinput_led_worker(struct work_struct *work) struct hid_report *report; int ret; u32 len; - __u8 *buf; field = hidinput_get_led_field(hid); if (!field) @@ -1866,7 +1873,7 @@ static void hidinput_led_worker(struct work_struct *work) /* fall back to generic raw-output-report */ len = hid_report_len(report); - buf = hid_alloc_report_buf(report, GFP_KERNEL); + u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL); if (!buf) return; @@ -1876,7 +1883,6 @@ static void hidinput_led_worker(struct work_struct *work) if (ret == -ENOSYS) hid_hw_raw_request(hid, report->id, buf, len, HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); - kfree(buf); } static int hidinput_input_event(struct input_dev *dev, unsigned int type, @@ -2030,7 +2036,7 @@ static void report_features(struct hid_device *hid) static struct hid_input *hidinput_allocate(struct hid_device *hid, unsigned int application) { - struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); + struct hid_input *hidinput = kzalloc_obj(*hidinput); struct input_dev *input_dev = input_allocate_device(); const char *suffix = NULL; size_t suffix_len, name_len; @@ -2403,8 +2409,6 @@ void hidinput_disconnect(struct hid_device *hid) { struct hid_input *hidinput, *next; - hidinput_cleanup_battery(hid); - list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { list_del(&hidinput->list); if (hidinput->registered) diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 9a2cfa018bd3..197c2f3b077f 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -768,7 +768,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) return -ENODEV; } - drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); + drv_data = kzalloc_obj(struct lg_drv_data); if (!drv_data) { hid_err(hdev, "Insufficient memory, cannot allocate driver data\n"); return -ENOMEM; diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index 73d07e35f12a..c3e85b079d80 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -66,7 +66,7 @@ int lg2ff_init(struct hid_device *hid) if (!report) return -ENODEV; - lg2ff = kmalloc(sizeof(struct lg2ff_device), GFP_KERNEL); + lg2ff = kmalloc_obj(struct lg2ff_device); if (!lg2ff) return -ENOMEM; diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 32b711723f2a..e901fdb7d033 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -1288,7 +1288,7 @@ int lg4ff_init(struct hid_device *hid) hid_err(hid, "Cannot add device, private driver data not allocated\n"); return -1; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; spin_lock_init(&entry->report_lock); diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 695d3031009e..381e4dc5aba7 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -733,7 +733,7 @@ static struct dj_receiver_dev *dj_get_receiver_dev(struct hid_device *hdev, djrcv_dev = dj_find_receiver_dev(hdev, type); if (!djrcv_dev) { - djrcv_dev = kzalloc(sizeof(*djrcv_dev), GFP_KERNEL); + djrcv_dev = kzalloc_obj(*djrcv_dev); if (!djrcv_dev) goto out; @@ -851,7 +851,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, snprintf(tmpstr, sizeof(tmpstr), ":%d", device_index); strlcat(dj_hiddev->phys, tmpstr, sizeof(dj_hiddev->phys)); - dj_dev = kzalloc(sizeof(struct dj_device), GFP_KERNEL); + dj_dev = kzalloc_obj(struct dj_device); if (!dj_dev) { hid_err(djrcv_hdev, "%s: failed allocating dj_dev\n", __func__); @@ -1332,7 +1332,7 @@ static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) goto out; } - dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); + dj_report = kzalloc_obj(struct dj_report); if (!dj_report) return -ENOMEM; dj_report->report_id = REPORT_ID_DJ_SHORT; @@ -1356,7 +1356,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, u8 *buf; int retval = 0; - dj_report = kzalloc(sizeof(struct dj_report), GFP_KERNEL); + dj_report = kzalloc_obj(struct dj_report); if (!dj_report) return -ENOMEM; diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 8bcd43f17b07..b1330d23bd2d 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -395,7 +395,7 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp, return -EINVAL; } - message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); + message = kzalloc_obj(struct hidpp_report); if (!message) return -ENOMEM; @@ -448,7 +448,7 @@ static int hidpp_send_rap_command_sync(struct hidpp_device *hidpp_dev, if (param_count > max_count) return -EINVAL; - message = kzalloc(sizeof(struct hidpp_report), GFP_KERNEL); + message = kzalloc_obj(struct hidpp_report); if (!message) return -ENOMEM; message->report_id = report_id; @@ -2535,7 +2535,7 @@ static void hidpp_ff_work_handler(struct work_struct *w) static int hidpp_ff_queue_work(struct hidpp_ff_private_data *data, int effect_id, u8 command, u8 *params, u8 size) { - struct hidpp_ff_work_data *wd = kzalloc(sizeof(*wd), GFP_KERNEL); + struct hidpp_ff_work_data *wd = kzalloc_obj(*wd); int s; if (!wd) @@ -2861,7 +2861,7 @@ static int hidpp_ff_init(struct hidpp_device *hidpp, data = kmemdup(data, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - data->effect_ids = kcalloc(num_slots, sizeof(int), GFP_KERNEL); + data->effect_ids = kzalloc_objs(int, num_slots); if (!data->effect_ids) { kfree(data); return -ENOMEM; diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 9eadf3252d0d..e70bd3dc07ab 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -817,19 +817,21 @@ static int magicmouse_fetch_battery(struct hid_device *hdev) #ifdef CONFIG_HID_BATTERY_STRENGTH struct hid_report_enum *report_enum; struct hid_report *report; + struct hid_battery *bat; - if (!hdev->battery || + bat = hid_get_battery(hdev); + if (!bat || (!is_usb_magicmouse2(hdev->vendor, hdev->product) && !is_usb_magictrackpad2(hdev->vendor, hdev->product))) return -1; - report_enum = &hdev->report_enum[hdev->battery_report_type]; - report = report_enum->report_id_hash[hdev->battery_report_id]; + report_enum = &hdev->report_enum[bat->report_type]; + report = report_enum->report_id_hash[bat->report_id]; if (!report || report->maxfield < 1) return -1; - if (hdev->battery_capacity == hdev->battery_max) + if (bat->capacity == bat->max) return -1; hid_hw_request(hdev, report, HID_REQ_GET_REPORT); diff --git a/drivers/hid/hid-megaworld.c b/drivers/hid/hid-megaworld.c index 0476d7d16e7f..81acdbc3a00f 100644 --- a/drivers/hid/hid-megaworld.c +++ b/drivers/hid/hid-megaworld.c @@ -57,7 +57,7 @@ static int mwctrl_init(struct hid_device *hid) return -ENODEV; } - mwctrl = kzalloc(sizeof(struct mwctrl_device), GFP_KERNEL); + mwctrl = kzalloc_obj(struct mwctrl_device); if (!mwctrl) return -ENOMEM; diff --git a/drivers/hid/hid-mf.c b/drivers/hid/hid-mf.c index 49a4052a1496..6ff54a1ec697 100644 --- a/drivers/hid/hid-mf.c +++ b/drivers/hid/hid-mf.c @@ -88,7 +88,7 @@ static int mf_init(struct hid_device *hid) input_ptr = input_ptr->next; input = list_entry(input_ptr, struct hid_input, list); - mf = kzalloc(sizeof(struct mf_device), GFP_KERNEL); + mf = kzalloc_obj(struct mf_device); if (!mf) return -ENOMEM; diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index a7f10c45f62b..2b31756b549e 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -900,7 +900,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) hdev->quirks |= HID_QUIRK_MULTI_INPUT | HID_QUIRK_NO_INIT_REPORTS; - nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); + nd = kmalloc_obj(struct ntrig_data); if (!nd) { hid_err(hdev, "cannot allocate N-Trig data\n"); return -ENOMEM; diff --git a/drivers/hid/hid-picolcd_core.c b/drivers/hid/hid-picolcd_core.c index 6a88e6bc70f3..2cc01e1bc1a8 100644 --- a/drivers/hid/hid-picolcd_core.c +++ b/drivers/hid/hid-picolcd_core.c @@ -78,7 +78,7 @@ struct picolcd_pending *picolcd_send_and_wait(struct hid_device *hdev, return NULL; if (data->status & PICOLCD_FAILED) return NULL; - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return NULL; @@ -528,7 +528,7 @@ static int picolcd_probe(struct hid_device *hdev, * Let's allocate the picolcd data structure, set some reasonable * defaults, and associate it with the device */ - data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL); + data = kzalloc_obj(struct picolcd_data); if (data == NULL) { hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n"); return -ENOMEM; diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index dc11d5322fc0..c6c2961dd574 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -140,7 +140,7 @@ static int plff_init(struct hid_device *hid) return -ENODEV; } - plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL); + plff = kzalloc_obj(struct plff_device); if (!plff) return -ENOMEM; diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 43c0340660c2..c43caac20b61 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -1658,7 +1658,7 @@ static int dualsense_reset_leds(struct dualsense *ds) struct dualsense_output_report report; struct dualsense_output_report_bt *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return -ENOMEM; diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 6e413df38358..fba01e4fcab1 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -797,7 +797,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) intf = to_usb_interface(hdev->dev.parent); ifnum = intf->cur_altsetting->desc.bInterfaceNumber; - pm = kzalloc(sizeof(*pm), GFP_KERNEL); + pm = kzalloc_obj(*pm); if (pm == NULL) { hid_err(hdev, "can't alloc descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 5f8afb22bcbe..eb811b1fb80f 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -1166,11 +1166,11 @@ static int hid_modify_dquirk(const struct hid_device_id *id, int list_edited = 0; int ret = 0; - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); + hdev = kzalloc_obj(*hdev); if (!hdev) return -ENOMEM; - q_new = kmalloc(sizeof(struct quirks_list_struct), GFP_KERNEL); + q_new = kmalloc_obj(struct quirks_list_struct); if (!q_new) { ret = -ENOMEM; goto out; diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 7b09adfa44a1..0cf2f0008c7f 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -299,7 +299,7 @@ static int arvo_init_specials(struct hid_device *hdev) return 0; } - arvo = kzalloc(sizeof(*arvo), GFP_KERNEL); + arvo = kzalloc_obj(*arvo); if (!arvo) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 339378771ed5..93a49c93ae8c 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -279,7 +279,7 @@ static int isku_init_specials(struct hid_device *hdev) return 0; } - isku = kzalloc(sizeof(*isku), GFP_KERNEL); + isku = kzalloc_obj(*isku); if (!isku) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index fabc08efcfd8..58654cf78f0d 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -704,7 +704,7 @@ static int kone_init_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { - kone = kzalloc(sizeof(*kone), GFP_KERNEL); + kone = kzalloc_obj(*kone); if (!kone) return -ENOMEM; hid_set_drvdata(hdev, kone); diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 77d45d36421a..f80a60539a96 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -384,7 +384,7 @@ static int koneplus_init_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { - koneplus = kzalloc(sizeof(*koneplus), GFP_KERNEL); + koneplus = kzalloc_obj(*koneplus); if (!koneplus) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index 027bfc55ef9c..7f753dfc2a10 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c @@ -88,7 +88,7 @@ static int konepure_init_specials(struct hid_device *hdev) return 0; } - konepure = kzalloc(sizeof(*konepure), GFP_KERNEL); + konepure = kzalloc_obj(*konepure); if (!konepure) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index a66f1b4730f3..9ec42c218ef9 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -453,7 +453,7 @@ static int kovaplus_init_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { - kovaplus = kzalloc(sizeof(*kovaplus), GFP_KERNEL); + kovaplus = kzalloc_obj(*kovaplus); if (!kovaplus) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c index 45e30549c236..8e35e1a0660b 100644 --- a/drivers/hid/hid-roccat-lua.c +++ b/drivers/hid/hid-roccat-lua.c @@ -119,7 +119,7 @@ static int lua_init_specials(struct hid_device *hdev) struct lua_device *lua; int retval; - lua = kzalloc(sizeof(*lua), GFP_KERNEL); + lua = kzalloc_obj(*lua); if (!lua) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index de2da6086e0b..0d515995bb9d 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -403,7 +403,7 @@ static int pyra_init_specials(struct hid_device *hdev) if (intf->cur_altsetting->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) { - pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); + pyra = kzalloc_obj(*pyra); if (!pyra) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c index 36911c9da4fe..db83f42457da 100644 --- a/drivers/hid/hid-roccat-ryos.c +++ b/drivers/hid/hid-roccat-ryos.c @@ -96,7 +96,7 @@ static int ryos_init_specials(struct hid_device *hdev) return 0; } - ryos = kzalloc(sizeof(*ryos), GFP_KERNEL); + ryos = kzalloc_obj(*ryos); if (!ryos) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index fb2e464c3ada..679136933560 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -68,7 +68,7 @@ static int savu_init_specials(struct hid_device *hdev) return 0; } - savu = kzalloc(sizeof(*savu), GFP_KERNEL); + savu = kzalloc_obj(*savu); if (!savu) { hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index e413662f7508..d6fff53d4ee7 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -152,7 +152,7 @@ static int roccat_open(struct inode *inode, struct file *file) struct roccat_device *device; int error = 0; - reader = kzalloc(sizeof(struct roccat_reader), GFP_KERNEL); + reader = kzalloc_obj(struct roccat_reader); if (!reader) return -ENOMEM; @@ -303,7 +303,7 @@ int roccat_connect(const struct class *klass, struct hid_device *hid, int report struct roccat_device *device; int temp; - device = kzalloc(sizeof(struct roccat_device), GFP_KERNEL); + device = kzalloc_obj(struct roccat_device); if (!device) return -ENOMEM; diff --git a/drivers/hid/hid-sensor-custom.c b/drivers/hid/hid-sensor-custom.c index 761760668f6d..afffea894021 100644 --- a/drivers/hid/hid-sensor-custom.c +++ b/drivers/hid/hid-sensor-custom.c @@ -912,7 +912,7 @@ hid_sensor_custom_get_known(struct hid_sensor_hub_device *hsdev, hid_sensor_custom_known_table; struct hid_sensor_custom_properties *prop; - prop = kmalloc(sizeof(struct hid_sensor_custom_properties), GFP_KERNEL); + prop = kmalloc_obj(struct hid_sensor_custom_properties); if (!prop) return -ENOMEM; diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index 0edec902be41..90666ff629de 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c @@ -139,7 +139,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -EINVAL; } - callback = kzalloc(sizeof(*callback), GFP_ATOMIC); + callback = kzalloc_obj(*callback, GFP_ATOMIC); if (!callback) { spin_unlock_irqrestore(&pdata->dyn_callback_lock, flags); return -ENOMEM; diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index d3a777f52a3f..bab93d71b760 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -83,7 +83,7 @@ static int sjoyff_init(struct hid_device *hid) return -ENODEV; } - sjoyff = kzalloc(sizeof(struct sjoyff_device), GFP_KERNEL); + sjoyff = kzalloc_obj(struct sjoyff_device); if (!sjoyff) return -ENOMEM; diff --git a/drivers/hid/hid-thrustmaster.c b/drivers/hid/hid-thrustmaster.c index 0bf70664c35e..48a79c97b7d0 100644 --- a/drivers/hid/hid-thrustmaster.c +++ b/drivers/hid/hid-thrustmaster.c @@ -308,7 +308,7 @@ static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_i } // Now we allocate the tm_wheel - tm_wheel = kzalloc(sizeof(struct tm_wheel), GFP_KERNEL); + tm_wheel = kzalloc_obj(struct tm_wheel); if (!tm_wheel) { ret = -ENOMEM; goto error1; @@ -328,7 +328,7 @@ static int thrustmaster_probe(struct hid_device *hdev, const struct hid_device_i goto error3; } - tm_wheel->response = kzalloc(sizeof(struct tm_wheel_response), GFP_KERNEL); + tm_wheel->response = kzalloc_obj(struct tm_wheel_response); if (!tm_wheel->response) { ret = -ENOMEM; goto error4; diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index fcd859aa3a8c..423f395d01ac 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -132,7 +132,7 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) hidinput = list_entry(hid->inputs.next, struct hid_input, list); input_dev = hidinput->input; - tmff = kzalloc(sizeof(struct tmff_device), GFP_KERNEL); + tmff = kzalloc_obj(struct tmff_device); if (!tmff) return -ENOMEM; diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c index e28176d9d9c9..ed16f50f21ed 100644 --- a/drivers/hid/hid-uclogic-params.c +++ b/drivers/hid/hid-uclogic-params.c @@ -1358,13 +1358,13 @@ static int uclogic_params_ugee_v2_init_event_hooks(struct hid_device *hdev, if (!uclogic_params_ugee_v2_has_battery(hdev)) return 0; - p->event_hooks = kzalloc(sizeof(*p->event_hooks), GFP_KERNEL); + p->event_hooks = kzalloc_obj(*p->event_hooks); if (!p->event_hooks) return -ENOMEM; INIT_LIST_HEAD(&p->event_hooks->list); - event_hook = kzalloc(sizeof(*event_hook), GFP_KERNEL); + event_hook = kzalloc_obj(*event_hook); if (!event_hook) return -ENOMEM; diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 5b5fc460a4c5..63c4fa8fbb9b 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c @@ -1737,7 +1737,7 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) { struct wiimote_data *wdata; - wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); + wdata = kzalloc_obj(*wdata); if (!wdata) return NULL; diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index 00f9be55f148..5f74917781f2 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c @@ -174,7 +174,7 @@ int wiidebug_init(struct wiimote_data *wdata) struct wiimote_debug *dbg; unsigned long flags; - dbg = kzalloc(sizeof(*dbg), GFP_KERNEL); + dbg = kzalloc_obj(*dbg); if (!dbg) return -ENOMEM; diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index aacf7f137b18..d8e023c8aa84 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -71,7 +71,7 @@ static int zpff_init(struct hid_device *hid) return -ENODEV; } - zpff = kzalloc(sizeof(struct zpff_device), GFP_KERNEL); + zpff = kzalloc_obj(struct zpff_device); if (!zpff) return -ENOMEM; diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index bbd6f23bce78..9129fabed181 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -281,7 +281,7 @@ static int hidraw_open(struct inode *inode, struct file *file) unsigned long flags; int err = 0; - if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) { + if (!(list = kzalloc_obj(struct hidraw_list))) { err = -ENOMEM; goto out; } @@ -603,7 +603,7 @@ int hidraw_connect(struct hid_device *hid) /* we accept any HID device, all applications */ - dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL); + dev = kzalloc_obj(struct hidraw); if (!dev) return -ENOMEM; diff --git a/drivers/hid/i2c-hid/i2c-hid-of-elan.c b/drivers/hid/i2c-hid/i2c-hid-of-elan.c index 0215f217f6d8..b81fcc6ff49e 100644 --- a/drivers/hid/i2c-hid/i2c-hid-of-elan.c +++ b/drivers/hid/i2c-hid/i2c-hid-of-elan.c @@ -168,6 +168,13 @@ static const struct elan_i2c_hid_chip_data elan_ekth6a12nay_chip_data = { .power_after_backlight = true, }; +static const struct elan_i2c_hid_chip_data focaltech_ft8112_chip_data = { + .post_power_delay_ms = 10, + .post_gpio_reset_on_delay_ms = 150, + .hid_descriptor_address = 0x0001, + .main_supply_name = "vcc33", +}; + static const struct elan_i2c_hid_chip_data ilitek_ili9882t_chip_data = { .post_power_delay_ms = 1, .post_gpio_reset_on_delay_ms = 200, @@ -191,6 +198,7 @@ static const struct elan_i2c_hid_chip_data ilitek_ili2901_chip_data = { static const struct of_device_id elan_i2c_hid_of_match[] = { { .compatible = "elan,ekth6915", .data = &elan_ekth6915_chip_data }, { .compatible = "elan,ekth6a12nay", .data = &elan_ekth6a12nay_chip_data }, + { .compatible = "focaltech,ft8112", .data = &focaltech_ft8112_chip_data }, { .compatible = "ilitek,ili9882t", .data = &ilitek_ili9882t_chip_data }, { .compatible = "ilitek,ili2901", .data = &ilitek_ili2901_chip_data }, { } diff --git a/drivers/hid/intel-ish-hid/ishtp-hid.c b/drivers/hid/intel-ish-hid/ishtp-hid.c index be2c62fc8251..6e255b1bc721 100644 --- a/drivers/hid/intel-ish-hid/ishtp-hid.c +++ b/drivers/hid/intel-ish-hid/ishtp-hid.c @@ -214,7 +214,7 @@ int ishtp_hid_probe(unsigned int cur_hid_dev, if (IS_ERR(hid)) return PTR_ERR(hid); - hid_data = kzalloc(sizeof(*hid_data), GFP_KERNEL); + hid_data = kzalloc_obj(*hid_data); if (!hid_data) { rv = -ENOMEM; goto err_hid_data; diff --git a/drivers/hid/intel-ish-hid/ishtp/bus.c b/drivers/hid/intel-ish-hid/ishtp/bus.c index b890fbf97a75..44db90ad5495 100644 --- a/drivers/hid/intel-ish-hid/ishtp/bus.c +++ b/drivers/hid/intel-ish-hid/ishtp/bus.c @@ -435,7 +435,7 @@ static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev, } spin_unlock_irqrestore(&dev->device_list_lock, flags); - device = kzalloc(sizeof(struct ishtp_cl_device), GFP_KERNEL); + device = kzalloc_obj(struct ishtp_cl_device); if (!device) return NULL; diff --git a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c index 97f4026b1627..45ddc9a047bc 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client-buffers.c +++ b/drivers/hid/intel-ish-hid/ishtp/client-buffers.c @@ -66,7 +66,7 @@ int ishtp_cl_alloc_tx_ring(struct ishtp_cl *cl) for (j = 0; j < cl->tx_ring_size; ++j) { struct ishtp_cl_tx_ring *tx_buf; - tx_buf = kzalloc(sizeof(struct ishtp_cl_tx_ring), GFP_KERNEL); + tx_buf = kzalloc_obj(struct ishtp_cl_tx_ring); if (!tx_buf) goto out; @@ -183,7 +183,7 @@ struct ishtp_cl_rb *ishtp_io_rb_init(struct ishtp_cl *cl) { struct ishtp_cl_rb *rb; - rb = kzalloc(sizeof(struct ishtp_cl_rb), GFP_KERNEL); + rb = kzalloc_obj(struct ishtp_cl_rb); if (!rb) return NULL; diff --git a/drivers/hid/intel-ish-hid/ishtp/client.c b/drivers/hid/intel-ish-hid/ishtp/client.c index 40f510b1c072..4824f3302927 100644 --- a/drivers/hid/intel-ish-hid/ishtp/client.c +++ b/drivers/hid/intel-ish-hid/ishtp/client.c @@ -105,7 +105,7 @@ struct ishtp_cl *ishtp_cl_allocate(struct ishtp_cl_device *cl_device) { struct ishtp_cl *cl; - cl = kmalloc(sizeof(struct ishtp_cl), GFP_KERNEL); + cl = kmalloc_obj(struct ishtp_cl); if (!cl) return NULL; diff --git a/drivers/hid/intel-ish-hid/ishtp/hbm.c b/drivers/hid/intel-ish-hid/ishtp/hbm.c index 97c4fcd9e3c6..d4296dbf7eb0 100644 --- a/drivers/hid/intel-ish-hid/ishtp/hbm.c +++ b/drivers/hid/intel-ish-hid/ishtp/hbm.c @@ -34,8 +34,7 @@ static void ishtp_hbm_fw_cl_allocate(struct ishtp_device *dev) return; /* allocate storage for fw clients representation */ - clients = kcalloc(dev->fw_clients_num, sizeof(struct ishtp_fw_client), - GFP_KERNEL); + clients = kzalloc_objs(struct ishtp_fw_client, dev->fw_clients_num); if (!clients) { dev->dev_state = ISHTP_DEV_RESETTING; ish_hw_reset(dev); diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 21a70420151e..524b53a3c87b 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -110,7 +110,7 @@ static int uhid_queue_event(struct uhid_device *uhid, __u32 event) unsigned long flags; struct uhid_event *ev; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -129,7 +129,7 @@ static int uhid_hid_start(struct hid_device *hid) struct uhid_event *ev; unsigned long flags; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -240,7 +240,7 @@ static int uhid_hid_get_report(struct hid_device *hid, unsigned char rnum, if (!READ_ONCE(uhid->running)) return -EIO; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -282,7 +282,7 @@ static int uhid_hid_set_report(struct hid_device *hid, unsigned char rnum, if (!READ_ONCE(uhid->running) || count > UHID_DATA_MAX) return -EIO; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -365,7 +365,7 @@ static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count, if (count < 1 || count > UHID_DATA_MAX) return -EINVAL; - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) return -ENOMEM; @@ -433,7 +433,7 @@ static int uhid_event_from_user(const char __user *buffer, size_t len, */ struct uhid_create_req_compat *compat; - compat = kzalloc(sizeof(*compat), GFP_KERNEL); + compat = kzalloc_obj(*compat); if (!compat) return -ENOMEM; @@ -636,7 +636,7 @@ static int uhid_char_open(struct inode *inode, struct file *file) { struct uhid_device *uhid; - uhid = kzalloc(sizeof(*uhid), GFP_KERNEL); + uhid = kzalloc_obj(*uhid); if (!uhid) return -ENOMEM; diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index df3cc89dfb37..fbbfc0f60829 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -858,7 +858,7 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) &usbhid->inbuf_dma); usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, &usbhid->outbuf_dma); - usbhid->cr = kmalloc(sizeof(*usbhid->cr), GFP_KERNEL); + usbhid->cr = kmalloc_obj(*usbhid->cr); usbhid->ctrlbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL, &usbhid->ctrlbuf_dma); if (!usbhid->inbuf || !usbhid->outbuf || !usbhid->cr || @@ -1363,19 +1363,17 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * { struct usb_host_interface *interface = intf->cur_altsetting; struct usb_device *dev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *ep; struct usbhid_device *usbhid; struct hid_device *hid; - unsigned int n, has_in = 0; size_t len; int ret; dbg_hid("HID probe called for ifnum %d\n", intf->altsetting->desc.bInterfaceNumber); - for (n = 0; n < interface->desc.bNumEndpoints; n++) - if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) - has_in++; - if (!has_in) { + ret = usb_find_int_in_endpoint(interface, &ep); + if (ret) { hid_err(intf, "couldn't find an input interrupt endpoint\n"); return -ENODEV; } @@ -1430,7 +1428,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) hid->uniq[0] = 0; - usbhid = kzalloc(sizeof(*usbhid), GFP_KERNEL); + usbhid = kzalloc_obj(*usbhid); if (usbhid == NULL) { ret = -ENOMEM; goto err; diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index 56d6af39ba81..fbf3dbc92e66 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -1531,7 +1531,7 @@ int hid_pidff_init_with_quirks(struct hid_device *hid, u32 initial_quirks) return -ENODEV; } - pidff = kzalloc(sizeof(*pidff), GFP_KERNEL); + pidff = kzalloc_obj(*pidff); if (!pidff) return -ENOMEM; diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 59cf3ddfdf78..6378801b22c6 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -434,7 +434,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd, struct hid_field *field; int i; - uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL); + uref_multi = kmalloc_obj(struct hiddev_usage_ref_multi); if (!uref_multi) return -ENOMEM; uref = &uref_multi->uref; @@ -890,7 +890,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) return -EINVAL; } - if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) + if (!(hiddev = kzalloc_obj(struct hiddev))) return -ENOMEM; init_waitqueue_head(&hiddev->wait); diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index af6bc76dbf64..6b33e6ad0846 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c @@ -241,7 +241,7 @@ static int usb_kbd_alloc_mem(struct usb_device *dev, struct usb_kbd *kbd) return -1; if (!(kbd->new = usb_alloc_coherent(dev, 8, GFP_KERNEL, &kbd->new_dma))) return -1; - if (!(kbd->cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL))) + if (!(kbd->cr = kmalloc_obj(struct usb_ctrlrequest))) return -1; if (!(kbd->leds = usb_alloc_coherent(dev, 1, GFP_KERNEL, &kbd->leds_dma))) return -1; @@ -281,7 +281,7 @@ static int usb_kbd_probe(struct usb_interface *iface, pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe); - kbd = kzalloc(sizeof(struct usb_kbd), GFP_KERNEL); + kbd = kzalloc_obj(struct usb_kbd); input_dev = input_allocate_device(); if (!kbd || !input_dev) goto fail1; diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index 3fd93c2e4f4a..7cc4f9558e5f 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c @@ -125,7 +125,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe); - mouse = kzalloc(sizeof(struct usb_mouse), GFP_KERNEL); + mouse = kzalloc_obj(struct usb_mouse); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index afc900560706..0d1c6d90fe21 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -892,7 +892,7 @@ static int wacom_add_shared_data(struct hid_device *hdev) data = wacom_get_hdev_data(hdev); if (!data) { - data = kzalloc(sizeof(struct wacom_hdev_data), GFP_KERNEL); + data = kzalloc_obj(struct wacom_hdev_data); if (!data) { mutex_unlock(&wacom_udev_list_lock); return -ENOMEM; diff --git a/drivers/hsi/clients/cmt_speech.c b/drivers/hsi/clients/cmt_speech.c index daa8e1bff5d9..d5aa87833768 100644 --- a/drivers/hsi/clients/cmt_speech.c +++ b/drivers/hsi/clients/cmt_speech.c @@ -139,7 +139,7 @@ static void cs_notify(u32 message, struct list_head *head) goto out; } - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) { dev_err(&cs_char_data.cl->device, "Can't allocate new entry for the queue.\n"); @@ -273,7 +273,7 @@ static int cs_alloc_cmds(struct cs_hsi_iface *hi) msg = hsi_alloc_msg(1, GFP_KERNEL); if (!msg) goto out; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) { hsi_free_msg(msg); goto out; @@ -985,7 +985,7 @@ static int cs_hsi_start(struct cs_hsi_iface **hi, struct hsi_client *cl, unsigned long mmap_base, unsigned long mmap_size) { int err = 0; - struct cs_hsi_iface *hsi_if = kzalloc(sizeof(*hsi_if), GFP_KERNEL); + struct cs_hsi_iface *hsi_if = kzalloc_obj(*hsi_if); dev_dbg(&cl->device, "cs_hsi_start\n"); diff --git a/drivers/hsi/clients/hsi_char.c b/drivers/hsi/clients/hsi_char.c index 71ce7dbfe31d..a31cc1466dd3 100644 --- a/drivers/hsi/clients/hsi_char.c +++ b/drivers/hsi/clients/hsi_char.c @@ -683,7 +683,7 @@ static int hsc_probe(struct device *dev) int ret; int i; - cl_data = kzalloc(sizeof(*cl_data), GFP_KERNEL); + cl_data = kzalloc_obj(*cl_data); if (!cl_data) return -ENOMEM; diff --git a/drivers/hsi/clients/ssi_protocol.c b/drivers/hsi/clients/ssi_protocol.c index d10a01f3eb9e..7c6ca8391a6b 100644 --- a/drivers/hsi/clients/ssi_protocol.c +++ b/drivers/hsi/clients/ssi_protocol.c @@ -259,7 +259,7 @@ static int ssip_alloc_cmds(struct ssi_protocol *ssi) msg = hsi_alloc_msg(1, GFP_KERNEL); if (!msg) goto out; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) { hsi_free_msg(msg); goto out; @@ -1077,7 +1077,7 @@ static int ssi_protocol_probe(struct device *dev) struct ssi_protocol *ssi; int err; - ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); + ssi = kzalloc_obj(*ssi); if (!ssi) return -ENOMEM; diff --git a/drivers/hsi/hsi_boardinfo.c b/drivers/hsi/hsi_boardinfo.c index 52500e7fd836..8c79e4062798 100644 --- a/drivers/hsi/hsi_boardinfo.c +++ b/drivers/hsi/hsi_boardinfo.c @@ -36,7 +36,7 @@ int __init hsi_register_board_info(struct hsi_board_info const *info, { struct hsi_cl_info *cl_info; - cl_info = kcalloc(len, sizeof(*cl_info), GFP_KERNEL); + cl_info = kzalloc_objs(*cl_info, len); if (!cl_info) return -ENOMEM; diff --git a/drivers/hsi/hsi_core.c b/drivers/hsi/hsi_core.c index 8113cb9d4015..7cb2dcb30fdb 100644 --- a/drivers/hsi/hsi_core.c +++ b/drivers/hsi/hsi_core.c @@ -70,7 +70,7 @@ struct hsi_client *hsi_new_client(struct hsi_port *port, struct hsi_client *cl; size_t size; - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) goto err; @@ -203,7 +203,7 @@ static void hsi_add_client_from_dt(struct hsi_port *port, char name[32]; int length, cells, err, i, max_chan, mode; - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return; @@ -253,13 +253,13 @@ static void hsi_add_client_from_dt(struct hsi_port *port, cl->rx_cfg.num_channels = cells; cl->tx_cfg.num_channels = cells; - cl->rx_cfg.channels = kcalloc(cells, sizeof(channel), GFP_KERNEL); + cl->rx_cfg.channels = kzalloc_objs(channel, cells); if (!cl->rx_cfg.channels) { err = -ENOMEM; goto err; } - cl->tx_cfg.channels = kcalloc(cells, sizeof(channel), GFP_KERNEL); + cl->tx_cfg.channels = kzalloc_objs(channel, cells); if (!cl->tx_cfg.channels) { err = -ENOMEM; goto err2; @@ -468,10 +468,10 @@ struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) if (!n_ports) return NULL; - hsi = kzalloc(sizeof(*hsi), flags); + hsi = kzalloc_obj(*hsi, flags); if (!hsi) return NULL; - port = kcalloc(n_ports, sizeof(*port), flags); + port = kzalloc_objs(*port, n_ports, flags); if (!port) { kfree(hsi); return NULL; @@ -482,7 +482,7 @@ struct hsi_controller *hsi_alloc_controller(unsigned int n_ports, gfp_t flags) device_initialize(&hsi->device); for (i = 0; i < n_ports; i++) { - port[i] = kzalloc(sizeof(**port), flags); + port[i] = kzalloc_obj(**port, flags); if (port[i] == NULL) goto out; port[i]->num = i; @@ -538,7 +538,7 @@ struct hsi_msg *hsi_alloc_msg(unsigned int nents, gfp_t flags) struct hsi_msg *msg; int err; - msg = kzalloc(sizeof(*msg), flags); + msg = kzalloc_obj(*msg, flags); if (!msg) return NULL; diff --git a/drivers/hte/hte.c b/drivers/hte/hte.c index 23a6eeb8c506..fd0f29038a5f 100644 --- a/drivers/hte/hte.c +++ b/drivers/hte/hte.c @@ -850,7 +850,7 @@ static int hte_register_chip(struct hte_chip *chip) return -EINVAL; } - gdev = kzalloc(struct_size(gdev, ei, chip->nlines), GFP_KERNEL); + gdev = kzalloc_flex(*gdev, ei, chip->nlines); if (!gdev) return -ENOMEM; diff --git a/drivers/hv/Makefile b/drivers/hv/Makefile index a49f93c2d245..2593711c3628 100644 --- a/drivers/hv/Makefile +++ b/drivers/hv/Makefile @@ -15,6 +15,7 @@ hv_vmbus-$(CONFIG_HYPERV_TESTING) += hv_debugfs.o hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \ mshv_root_hv_call.o mshv_portid_table.o mshv_regions.o +mshv_root-$(CONFIG_DEBUG_FS) += mshv_debugfs.o mshv_vtl-y := mshv_vtl_main.o # Code that must be built-in diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 74fed2c073d4..7c77ada12b2e 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -354,7 +354,7 @@ static struct vmbus_channel *alloc_channel(void) { struct vmbus_channel *channel; - channel = kzalloc(sizeof(*channel), GFP_ATOMIC); + channel = kzalloc_obj(*channel, GFP_ATOMIC); if (!channel) return NULL; diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 5d9cb5bf2d62..b5b322ce16df 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -313,9 +313,8 @@ int vmbus_connect(void) pr_info("Vmbus version:%d.%d\n", version >> 16, version & 0xFFFF); - vmbus_connection.channels = kcalloc(MAX_CHANNEL_RELIDS, - sizeof(struct vmbus_channel *), - GFP_KERNEL); + vmbus_connection.channels = kzalloc_objs(struct vmbus_channel *, + MAX_CHANNEL_RELIDS); if (vmbus_connection.channels == NULL) { ret = -ENOMEM; goto cleanup; diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c index c100f04b3581..ae60fd542292 100644 --- a/drivers/hv/hv.c +++ b/drivers/hv/hv.c @@ -183,8 +183,7 @@ int hv_synic_alloc(void) memset(hv_cpu, 0, sizeof(*hv_cpu)); } - hv_context.hv_numa_map = kcalloc(nr_node_ids, sizeof(struct cpumask), - GFP_KERNEL); + hv_context.hv_numa_map = kzalloc_objs(struct cpumask, nr_node_ids); if (!hv_context.hv_numa_map) { pr_err("Unable to allocate NUMA map\n"); goto err; @@ -287,11 +286,11 @@ void hv_hyp_synic_enable_regs(unsigned int cpu) simp.simp_enabled = 1; if (ms_hyperv.paravisor_present || hv_root_partition()) { - /* Mask out vTOM bit. ioremap_cache() maps decrypted */ + /* Mask out vTOM bit and map as decrypted */ u64 base = (simp.base_simp_gpa << HV_HYP_PAGE_SHIFT) & ~ms_hyperv.shared_gpa_boundary; hv_cpu->hyp_synic_message_page = - (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); + memremap(base, HV_HYP_PAGE_SIZE, MEMREMAP_WB | MEMREMAP_DEC); if (!hv_cpu->hyp_synic_message_page) pr_err("Fail to map synic message page.\n"); } else { @@ -306,11 +305,11 @@ void hv_hyp_synic_enable_regs(unsigned int cpu) siefp.siefp_enabled = 1; if (ms_hyperv.paravisor_present || hv_root_partition()) { - /* Mask out vTOM bit. ioremap_cache() maps decrypted */ + /* Mask out vTOM bit and map as decrypted */ u64 base = (siefp.base_siefp_gpa << HV_HYP_PAGE_SHIFT) & ~ms_hyperv.shared_gpa_boundary; hv_cpu->hyp_synic_event_page = - (void *)ioremap_cache(base, HV_HYP_PAGE_SIZE); + memremap(base, HV_HYP_PAGE_SIZE, MEMREMAP_WB | MEMREMAP_DEC); if (!hv_cpu->hyp_synic_event_page) pr_err("Fail to map synic event page.\n"); } else { @@ -429,7 +428,7 @@ void hv_hyp_synic_disable_regs(unsigned int cpu) simp.simp_enabled = 0; if (ms_hyperv.paravisor_present || hv_root_partition()) { if (hv_cpu->hyp_synic_message_page) { - iounmap(hv_cpu->hyp_synic_message_page); + memunmap(hv_cpu->hyp_synic_message_page); hv_cpu->hyp_synic_message_page = NULL; } } else { @@ -443,7 +442,7 @@ void hv_hyp_synic_disable_regs(unsigned int cpu) if (ms_hyperv.paravisor_present || hv_root_partition()) { if (hv_cpu->hyp_synic_event_page) { - iounmap(hv_cpu->hyp_synic_event_page); + memunmap(hv_cpu->hyp_synic_event_page); hv_cpu->hyp_synic_event_page = NULL; } } else { diff --git a/drivers/hv/hv_balloon.c b/drivers/hv/hv_balloon.c index 2b4080e51f97..a848400a59a2 100644 --- a/drivers/hv/hv_balloon.c +++ b/drivers/hv/hv_balloon.c @@ -801,7 +801,7 @@ static int pfn_covered(unsigned long start_pfn, unsigned long pfn_cnt) * is, create a gap and update covered_end_pfn. */ if (has->covered_end_pfn != start_pfn) { - gap = kzalloc(sizeof(struct hv_hotadd_gap), GFP_ATOMIC); + gap = kzalloc_obj(struct hv_hotadd_gap, GFP_ATOMIC); if (!gap) { ret = -ENOMEM; break; diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c index f1c17fb60dc1..6b67ac616789 100644 --- a/drivers/hv/hv_common.c +++ b/drivers/hv/hv_common.c @@ -793,6 +793,9 @@ static const struct hv_status_info hv_status_infos[] = { _STATUS_INFO(HV_STATUS_UNKNOWN_PROPERTY, -EIO), _STATUS_INFO(HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE, -EIO), _STATUS_INFO(HV_STATUS_INSUFFICIENT_MEMORY, -ENOMEM), + _STATUS_INFO(HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY, -ENOMEM), + _STATUS_INFO(HV_STATUS_INSUFFICIENT_ROOT_MEMORY, -ENOMEM), + _STATUS_INFO(HV_STATUS_INSUFFICIENT_CONTIGUOUS_ROOT_MEMORY, -ENOMEM), _STATUS_INFO(HV_STATUS_INVALID_PARTITION_ID, -EINVAL), _STATUS_INFO(HV_STATUS_INVALID_VP_INDEX, -EINVAL), _STATUS_INFO(HV_STATUS_NOT_FOUND, -EIO), diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 62795f6cbb00..0d73daf745a7 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -134,7 +134,7 @@ kvp_register(int reg_value) struct hv_kvp_msg *kvp_msg; char *version; - kvp_msg = kzalloc(sizeof(*kvp_msg), GFP_KERNEL); + kvp_msg = kzalloc_obj(*kvp_msg); if (kvp_msg) { version = kvp_msg->body.kvp_register.version; @@ -385,7 +385,7 @@ kvp_send_key(struct work_struct *dummy) if (kvp_transaction.state != HVUTIL_HOSTMSG_RECEIVED) return; - message = kzalloc(sizeof(*message), GFP_KERNEL); + message = kzalloc_obj(*message); if (!message) return; diff --git a/drivers/hv/hv_proc.c b/drivers/hv/hv_proc.c index fbb4eb3901bb..3cb4b2a3035c 100644 --- a/drivers/hv/hv_proc.c +++ b/drivers/hv/hv_proc.c @@ -40,7 +40,7 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) return -ENOMEM; pages = page_address(page); - counts = kcalloc(HV_DEPOSIT_MAX, sizeof(int), GFP_KERNEL); + counts = kzalloc_objs(int, HV_DEPOSIT_MAX); if (!counts) { free_page((unsigned long)pages); return -ENOMEM; @@ -110,6 +110,50 @@ int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) } EXPORT_SYMBOL_GPL(hv_call_deposit_pages); +int hv_deposit_memory_node(int node, u64 partition_id, + u64 hv_status) +{ + u32 num_pages = 1; + + switch (hv_result(hv_status)) { + case HV_STATUS_INSUFFICIENT_MEMORY: + break; + case HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY: + num_pages = HV_MAX_CONTIGUOUS_ALLOCATION_PAGES; + break; + + case HV_STATUS_INSUFFICIENT_CONTIGUOUS_ROOT_MEMORY: + num_pages = HV_MAX_CONTIGUOUS_ALLOCATION_PAGES; + fallthrough; + case HV_STATUS_INSUFFICIENT_ROOT_MEMORY: + if (!hv_root_partition()) { + hv_status_err(hv_status, "Unexpected root memory deposit\n"); + return -ENOMEM; + } + partition_id = HV_PARTITION_ID_SELF; + break; + + default: + hv_status_err(hv_status, "Unexpected!\n"); + return -ENOMEM; + } + return hv_call_deposit_pages(node, partition_id, num_pages); +} +EXPORT_SYMBOL_GPL(hv_deposit_memory_node); + +bool hv_result_needs_memory(u64 status) +{ + switch (hv_result(status)) { + case HV_STATUS_INSUFFICIENT_MEMORY: + case HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY: + case HV_STATUS_INSUFFICIENT_ROOT_MEMORY: + case HV_STATUS_INSUFFICIENT_CONTIGUOUS_ROOT_MEMORY: + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(hv_result_needs_memory); + int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id) { struct hv_input_add_logical_processor *input; @@ -137,7 +181,7 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id) input, output); local_irq_restore(flags); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { if (!hv_result_success(status)) { hv_status_err(status, "cpu %u apic ID: %u\n", lp_index, apic_id); @@ -145,7 +189,8 @@ int hv_call_add_logical_proc(int node, u32 lp_index, u32 apic_id) } break; } - ret = hv_call_deposit_pages(node, hv_current_partition_id, 1); + ret = hv_deposit_memory_node(node, hv_current_partition_id, + status); } while (!ret); return ret; @@ -179,7 +224,7 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags) status = hv_do_hypercall(HVCALL_CREATE_VP, input, NULL); local_irq_restore(irq_flags); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { if (!hv_result_success(status)) { hv_status_err(status, "vcpu: %u, lp: %u\n", vp_index, flags); @@ -187,7 +232,7 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags) } break; } - ret = hv_call_deposit_pages(node, partition_id, 1); + ret = hv_deposit_memory_node(node, partition_id, status); } while (!ret); diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 2e7f537d53cf..506871aeacf0 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c @@ -184,7 +184,7 @@ static void vss_send_op(void) return; } - vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL); + vss_msg = kzalloc_obj(*vss_msg); if (!vss_msg) return; @@ -424,7 +424,7 @@ int hv_vss_pre_suspend(void) * write() will fail with EINVAL (see vss_on_msg()), and the daemon * will reset the device by closing and re-opening it. */ - vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL); + vss_msg = kzalloc_obj(*vss_msg); if (!vss_msg) return -ENOMEM; diff --git a/drivers/hv/hv_utils_transport.c b/drivers/hv/hv_utils_transport.c index b3de35ff6334..c3be5c570263 100644 --- a/drivers/hv/hv_utils_transport.c +++ b/drivers/hv/hv_utils_transport.c @@ -274,7 +274,7 @@ struct hvutil_transport *hvutil_transport_init(const char *name, { struct hvutil_transport *hvt; - hvt = kzalloc(sizeof(*hvt), GFP_KERNEL); + hvt = kzalloc_obj(*hvt); if (!hvt) return NULL; diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h index cdbc5f5c3215..7bd8f8486e85 100644 --- a/drivers/hv/hyperv_vmbus.h +++ b/drivers/hv/hyperv_vmbus.h @@ -370,8 +370,8 @@ static inline void vmbus_signal_eom(struct hv_message *msg, u32 old_msg_type) * CHANNELMSG_UNLOAD_RESPONSE and we don't care about other messages * on crash. */ - if (cmpxchg(&msg->header.message_type, old_msg_type, - HVMSG_NONE) != old_msg_type) + if (!try_cmpxchg(&msg->header.message_type, + &old_msg_type, HVMSG_NONE)) return; /* diff --git a/drivers/hv/mshv_debugfs.c b/drivers/hv/mshv_debugfs.c new file mode 100644 index 000000000000..418b6dc8f3c2 --- /dev/null +++ b/drivers/hv/mshv_debugfs.c @@ -0,0 +1,724 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026, Microsoft Corporation. + * + * The /sys/kernel/debug/mshv directory contents. + * Contains various statistics data, provided by the hypervisor. + * + * Authors: Microsoft Linux virtualization team + */ + +#include +#include +#include +#include + +#include "mshv.h" +#include "mshv_root.h" + +/* Ensure this file is not used elsewhere by accident */ +#define MSHV_DEBUGFS_C +#include "mshv_debugfs_counters.c" + +#define U32_BUF_SZ 11 +#define U64_BUF_SZ 21 +/* Only support SELF and PARENT areas */ +#define NUM_STATS_AREAS 2 +static_assert(HV_STATS_AREA_SELF == 0 && HV_STATS_AREA_PARENT == 1, + "SELF and PARENT areas must be usable as indices into an array of size NUM_STATS_AREAS"); +/* HV_HYPERVISOR_COUNTER */ +#define HV_HYPERVISOR_COUNTER_LOGICAL_PROCESSORS 1 + +static struct dentry *mshv_debugfs; +static struct dentry *mshv_debugfs_partition; +static struct dentry *mshv_debugfs_lp; +static struct dentry **parent_vp_stats; +static struct dentry *parent_partition_stats; + +static u64 mshv_lps_count; +static struct hv_stats_page **mshv_lps_stats; + +static int lp_stats_show(struct seq_file *m, void *v) +{ + const struct hv_stats_page *stats = m->private; + int idx; + + for (idx = 0; idx < ARRAY_SIZE(hv_lp_counters); idx++) { + char *name = hv_lp_counters[idx]; + + if (!name) + continue; + seq_printf(m, "%-32s: %llu\n", name, stats->data[idx]); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(lp_stats); + +static void mshv_lp_stats_unmap(u32 lp_index) +{ + union hv_stats_object_identity identity = { + .lp.lp_index = lp_index, + .lp.stats_area_type = HV_STATS_AREA_SELF, + }; + int err; + + err = hv_unmap_stats_page(HV_STATS_OBJECT_LOGICAL_PROCESSOR, + mshv_lps_stats[lp_index], &identity); + if (err) + pr_err("%s: failed to unmap logical processor %u stats, err: %d\n", + __func__, lp_index, err); + + mshv_lps_stats[lp_index] = NULL; +} + +static struct hv_stats_page * __init mshv_lp_stats_map(u32 lp_index) +{ + union hv_stats_object_identity identity = { + .lp.lp_index = lp_index, + .lp.stats_area_type = HV_STATS_AREA_SELF, + }; + struct hv_stats_page *stats; + int err; + + err = hv_map_stats_page(HV_STATS_OBJECT_LOGICAL_PROCESSOR, &identity, + &stats); + if (err) { + pr_err("%s: failed to map logical processor %u stats, err: %d\n", + __func__, lp_index, err); + return ERR_PTR(err); + } + mshv_lps_stats[lp_index] = stats; + + return stats; +} + +static struct hv_stats_page * __init lp_debugfs_stats_create(u32 lp_index, + struct dentry *parent) +{ + struct dentry *dentry; + struct hv_stats_page *stats; + + stats = mshv_lp_stats_map(lp_index); + if (IS_ERR(stats)) + return stats; + + dentry = debugfs_create_file("stats", 0400, parent, + stats, &lp_stats_fops); + if (IS_ERR(dentry)) { + mshv_lp_stats_unmap(lp_index); + return ERR_CAST(dentry); + } + return stats; +} + +static int __init lp_debugfs_create(u32 lp_index, struct dentry *parent) +{ + struct dentry *idx; + char lp_idx_str[U32_BUF_SZ]; + struct hv_stats_page *stats; + int err; + + sprintf(lp_idx_str, "%u", lp_index); + + idx = debugfs_create_dir(lp_idx_str, parent); + if (IS_ERR(idx)) + return PTR_ERR(idx); + + stats = lp_debugfs_stats_create(lp_index, idx); + if (IS_ERR(stats)) { + err = PTR_ERR(stats); + goto remove_debugfs_lp_idx; + } + + return 0; + +remove_debugfs_lp_idx: + debugfs_remove_recursive(idx); + return err; +} + +static void mshv_debugfs_lp_remove(void) +{ + int lp_index; + + debugfs_remove_recursive(mshv_debugfs_lp); + + for (lp_index = 0; lp_index < mshv_lps_count; lp_index++) + mshv_lp_stats_unmap(lp_index); + + kfree(mshv_lps_stats); + mshv_lps_stats = NULL; +} + +static int __init mshv_debugfs_lp_create(struct dentry *parent) +{ + struct dentry *lp_dir; + int err, lp_index; + + mshv_lps_stats = kzalloc_objs(*mshv_lps_stats, mshv_lps_count, + GFP_KERNEL_ACCOUNT); + + if (!mshv_lps_stats) + return -ENOMEM; + + lp_dir = debugfs_create_dir("lp", parent); + if (IS_ERR(lp_dir)) { + err = PTR_ERR(lp_dir); + goto free_lp_stats; + } + + for (lp_index = 0; lp_index < mshv_lps_count; lp_index++) { + err = lp_debugfs_create(lp_index, lp_dir); + if (err) + goto remove_debugfs_lps; + } + + mshv_debugfs_lp = lp_dir; + + return 0; + +remove_debugfs_lps: + for (lp_index -= 1; lp_index >= 0; lp_index--) + mshv_lp_stats_unmap(lp_index); + debugfs_remove_recursive(lp_dir); +free_lp_stats: + kfree(mshv_lps_stats); + mshv_lps_stats = NULL; + + return err; +} + +static int vp_stats_show(struct seq_file *m, void *v) +{ + const struct hv_stats_page **pstats = m->private; + u64 parent_val, self_val; + int idx; + + /* + * For VP and partition stats, there may be two stats areas mapped, + * SELF and PARENT. These refer to the privilege level of the data in + * each page. Some fields may be 0 in SELF and nonzero in PARENT, or + * vice versa. + * + * Hence, prioritize printing from the PARENT page (more privileged + * data), but use the value from the SELF page if the PARENT value is + * 0. + */ + + for (idx = 0; idx < ARRAY_SIZE(hv_vp_counters); idx++) { + char *name = hv_vp_counters[idx]; + + if (!name) + continue; + + parent_val = pstats[HV_STATS_AREA_PARENT]->data[idx]; + self_val = pstats[HV_STATS_AREA_SELF]->data[idx]; + seq_printf(m, "%-43s: %llu\n", name, + parent_val ? parent_val : self_val); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(vp_stats); + +static void vp_debugfs_remove(struct dentry *vp_stats) +{ + debugfs_remove_recursive(vp_stats->d_parent); +} + +static int vp_debugfs_create(u64 partition_id, u32 vp_index, + struct hv_stats_page **pstats, + struct dentry **vp_stats_ptr, + struct dentry *parent) +{ + struct dentry *vp_idx_dir, *d; + char vp_idx_str[U32_BUF_SZ]; + int err; + + sprintf(vp_idx_str, "%u", vp_index); + + vp_idx_dir = debugfs_create_dir(vp_idx_str, parent); + if (IS_ERR(vp_idx_dir)) + return PTR_ERR(vp_idx_dir); + + d = debugfs_create_file("stats", 0400, vp_idx_dir, + pstats, &vp_stats_fops); + if (IS_ERR(d)) { + err = PTR_ERR(d); + goto remove_debugfs_vp_idx; + } + + *vp_stats_ptr = d; + + return 0; + +remove_debugfs_vp_idx: + debugfs_remove_recursive(vp_idx_dir); + return err; +} + +static int partition_stats_show(struct seq_file *m, void *v) +{ + const struct hv_stats_page **pstats = m->private; + u64 parent_val, self_val; + int idx; + + for (idx = 0; idx < ARRAY_SIZE(hv_partition_counters); idx++) { + char *name = hv_partition_counters[idx]; + + if (!name) + continue; + + parent_val = pstats[HV_STATS_AREA_PARENT]->data[idx]; + self_val = pstats[HV_STATS_AREA_SELF]->data[idx]; + seq_printf(m, "%-37s: %llu\n", name, + parent_val ? parent_val : self_val); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(partition_stats); + +static void mshv_partition_stats_unmap(u64 partition_id, + struct hv_stats_page *stats_page, + enum hv_stats_area_type stats_area_type) +{ + union hv_stats_object_identity identity = { + .partition.partition_id = partition_id, + .partition.stats_area_type = stats_area_type, + }; + int err; + + err = hv_unmap_stats_page(HV_STATS_OBJECT_PARTITION, stats_page, + &identity); + if (err) + pr_err("%s: failed to unmap partition %lld %s stats, err: %d\n", + __func__, partition_id, + (stats_area_type == HV_STATS_AREA_SELF) ? "self" : "parent", + err); +} + +static struct hv_stats_page *mshv_partition_stats_map(u64 partition_id, + enum hv_stats_area_type stats_area_type) +{ + union hv_stats_object_identity identity = { + .partition.partition_id = partition_id, + .partition.stats_area_type = stats_area_type, + }; + struct hv_stats_page *stats; + int err; + + err = hv_map_stats_page(HV_STATS_OBJECT_PARTITION, &identity, &stats); + if (err) { + pr_err("%s: failed to map partition %lld %s stats, err: %d\n", + __func__, partition_id, + (stats_area_type == HV_STATS_AREA_SELF) ? "self" : "parent", + err); + return ERR_PTR(err); + } + return stats; +} + +static int mshv_debugfs_partition_stats_create(u64 partition_id, + struct dentry **partition_stats_ptr, + struct dentry *parent) +{ + struct dentry *dentry; + struct hv_stats_page **pstats; + int err; + + pstats = kzalloc_objs(struct hv_stats_page *, NUM_STATS_AREAS, + GFP_KERNEL_ACCOUNT); + if (!pstats) + return -ENOMEM; + + pstats[HV_STATS_AREA_SELF] = mshv_partition_stats_map(partition_id, + HV_STATS_AREA_SELF); + if (IS_ERR(pstats[HV_STATS_AREA_SELF])) { + err = PTR_ERR(pstats[HV_STATS_AREA_SELF]); + goto cleanup; + } + + /* + * L1VH partition cannot access its partition stats in parent area. + */ + if (is_l1vh_parent(partition_id)) { + pstats[HV_STATS_AREA_PARENT] = pstats[HV_STATS_AREA_SELF]; + } else { + pstats[HV_STATS_AREA_PARENT] = mshv_partition_stats_map(partition_id, + HV_STATS_AREA_PARENT); + if (IS_ERR(pstats[HV_STATS_AREA_PARENT])) { + err = PTR_ERR(pstats[HV_STATS_AREA_PARENT]); + goto unmap_self; + } + if (!pstats[HV_STATS_AREA_PARENT]) + pstats[HV_STATS_AREA_PARENT] = pstats[HV_STATS_AREA_SELF]; + } + + dentry = debugfs_create_file("stats", 0400, parent, + pstats, &partition_stats_fops); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); + goto unmap_partition_stats; + } + + *partition_stats_ptr = dentry; + return 0; + +unmap_partition_stats: + if (pstats[HV_STATS_AREA_PARENT] != pstats[HV_STATS_AREA_SELF]) + mshv_partition_stats_unmap(partition_id, pstats[HV_STATS_AREA_PARENT], + HV_STATS_AREA_PARENT); +unmap_self: + mshv_partition_stats_unmap(partition_id, pstats[HV_STATS_AREA_SELF], + HV_STATS_AREA_SELF); +cleanup: + kfree(pstats); + return err; +} + +static void partition_debugfs_remove(u64 partition_id, struct dentry *dentry) +{ + struct hv_stats_page **pstats = NULL; + + pstats = dentry->d_inode->i_private; + + debugfs_remove_recursive(dentry->d_parent); + + if (pstats[HV_STATS_AREA_PARENT] != pstats[HV_STATS_AREA_SELF]) { + mshv_partition_stats_unmap(partition_id, + pstats[HV_STATS_AREA_PARENT], + HV_STATS_AREA_PARENT); + } + + mshv_partition_stats_unmap(partition_id, + pstats[HV_STATS_AREA_SELF], + HV_STATS_AREA_SELF); + + kfree(pstats); +} + +static int partition_debugfs_create(u64 partition_id, + struct dentry **vp_dir_ptr, + struct dentry **partition_stats_ptr, + struct dentry *parent) +{ + char part_id_str[U64_BUF_SZ]; + struct dentry *part_id_dir, *vp_dir; + int err; + + if (is_l1vh_parent(partition_id)) + sprintf(part_id_str, "self"); + else + sprintf(part_id_str, "%llu", partition_id); + + part_id_dir = debugfs_create_dir(part_id_str, parent); + if (IS_ERR(part_id_dir)) + return PTR_ERR(part_id_dir); + + vp_dir = debugfs_create_dir("vp", part_id_dir); + if (IS_ERR(vp_dir)) { + err = PTR_ERR(vp_dir); + goto remove_debugfs_partition_id; + } + + err = mshv_debugfs_partition_stats_create(partition_id, + partition_stats_ptr, + part_id_dir); + if (err) + goto remove_debugfs_partition_id; + + *vp_dir_ptr = vp_dir; + + return 0; + +remove_debugfs_partition_id: + debugfs_remove_recursive(part_id_dir); + return err; +} + +static void parent_vp_debugfs_remove(u32 vp_index, + struct dentry *vp_stats_ptr) +{ + struct hv_stats_page **pstats; + + pstats = vp_stats_ptr->d_inode->i_private; + vp_debugfs_remove(vp_stats_ptr); + mshv_vp_stats_unmap(hv_current_partition_id, vp_index, pstats); + kfree(pstats); +} + +static void mshv_debugfs_parent_partition_remove(void) +{ + int idx; + + for_each_online_cpu(idx) + parent_vp_debugfs_remove(hv_vp_index[idx], + parent_vp_stats[idx]); + + partition_debugfs_remove(hv_current_partition_id, + parent_partition_stats); + kfree(parent_vp_stats); + parent_vp_stats = NULL; + parent_partition_stats = NULL; +} + +static int __init parent_vp_debugfs_create(u32 vp_index, + struct dentry **vp_stats_ptr, + struct dentry *parent) +{ + struct hv_stats_page **pstats; + int err; + + pstats = kzalloc_objs(struct hv_stats_page *, NUM_STATS_AREAS, + GFP_KERNEL_ACCOUNT); + if (!pstats) + return -ENOMEM; + + err = mshv_vp_stats_map(hv_current_partition_id, vp_index, pstats); + if (err) + goto cleanup; + + err = vp_debugfs_create(hv_current_partition_id, vp_index, pstats, + vp_stats_ptr, parent); + if (err) + goto unmap_vp_stats; + + return 0; + +unmap_vp_stats: + mshv_vp_stats_unmap(hv_current_partition_id, vp_index, pstats); +cleanup: + kfree(pstats); + return err; +} + +static int __init mshv_debugfs_parent_partition_create(void) +{ + struct dentry *vp_dir; + int err, idx, i; + + mshv_debugfs_partition = debugfs_create_dir("partition", + mshv_debugfs); + if (IS_ERR(mshv_debugfs_partition)) + return PTR_ERR(mshv_debugfs_partition); + + err = partition_debugfs_create(hv_current_partition_id, + &vp_dir, + &parent_partition_stats, + mshv_debugfs_partition); + if (err) + goto remove_debugfs_partition; + + parent_vp_stats = kzalloc_objs(*parent_vp_stats, nr_cpu_ids); + if (!parent_vp_stats) { + err = -ENOMEM; + goto remove_debugfs_partition; + } + + for_each_online_cpu(idx) { + err = parent_vp_debugfs_create(hv_vp_index[idx], + &parent_vp_stats[idx], + vp_dir); + if (err) + goto remove_debugfs_partition_vp; + } + + return 0; + +remove_debugfs_partition_vp: + for_each_online_cpu(i) { + if (i >= idx) + break; + parent_vp_debugfs_remove(i, parent_vp_stats[i]); + } + partition_debugfs_remove(hv_current_partition_id, + parent_partition_stats); + + kfree(parent_vp_stats); + parent_vp_stats = NULL; + parent_partition_stats = NULL; + +remove_debugfs_partition: + debugfs_remove_recursive(mshv_debugfs_partition); + mshv_debugfs_partition = NULL; + return err; +} + +static int hv_stats_show(struct seq_file *m, void *v) +{ + const struct hv_stats_page *stats = m->private; + int idx; + + for (idx = 0; idx < ARRAY_SIZE(hv_hypervisor_counters); idx++) { + char *name = hv_hypervisor_counters[idx]; + + if (!name) + continue; + seq_printf(m, "%-27s: %llu\n", name, stats->data[idx]); + } + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(hv_stats); + +static void mshv_hv_stats_unmap(void) +{ + union hv_stats_object_identity identity = { + .hv.stats_area_type = HV_STATS_AREA_SELF, + }; + int err; + + err = hv_unmap_stats_page(HV_STATS_OBJECT_HYPERVISOR, NULL, &identity); + if (err) + pr_err("%s: failed to unmap hypervisor stats: %d\n", + __func__, err); +} + +static void * __init mshv_hv_stats_map(void) +{ + union hv_stats_object_identity identity = { + .hv.stats_area_type = HV_STATS_AREA_SELF, + }; + struct hv_stats_page *stats; + int err; + + err = hv_map_stats_page(HV_STATS_OBJECT_HYPERVISOR, &identity, &stats); + if (err) { + pr_err("%s: failed to map hypervisor stats: %d\n", + __func__, err); + return ERR_PTR(err); + } + return stats; +} + +static int __init mshv_debugfs_hv_stats_create(struct dentry *parent) +{ + struct dentry *dentry; + u64 *stats; + int err; + + stats = mshv_hv_stats_map(); + if (IS_ERR(stats)) + return PTR_ERR(stats); + + dentry = debugfs_create_file("stats", 0400, parent, + stats, &hv_stats_fops); + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); + pr_err("%s: failed to create hypervisor stats dentry: %d\n", + __func__, err); + goto unmap_hv_stats; + } + + mshv_lps_count = stats[HV_HYPERVISOR_COUNTER_LOGICAL_PROCESSORS]; + + return 0; + +unmap_hv_stats: + mshv_hv_stats_unmap(); + return err; +} + +int mshv_debugfs_vp_create(struct mshv_vp *vp) +{ + struct mshv_partition *p = vp->vp_partition; + + if (!mshv_debugfs) + return 0; + + return vp_debugfs_create(p->pt_id, vp->vp_index, + vp->vp_stats_pages, + &vp->vp_stats_dentry, + p->pt_vp_dentry); +} + +void mshv_debugfs_vp_remove(struct mshv_vp *vp) +{ + if (!mshv_debugfs) + return; + + vp_debugfs_remove(vp->vp_stats_dentry); +} + +int mshv_debugfs_partition_create(struct mshv_partition *partition) +{ + int err; + + if (!mshv_debugfs) + return 0; + + err = partition_debugfs_create(partition->pt_id, + &partition->pt_vp_dentry, + &partition->pt_stats_dentry, + mshv_debugfs_partition); + if (err) + return err; + + return 0; +} + +void mshv_debugfs_partition_remove(struct mshv_partition *partition) +{ + if (!mshv_debugfs) + return; + + partition_debugfs_remove(partition->pt_id, + partition->pt_stats_dentry); +} + +int __init mshv_debugfs_init(void) +{ + int err; + + mshv_debugfs = debugfs_create_dir("mshv", NULL); + if (IS_ERR(mshv_debugfs)) { + pr_err("%s: failed to create debugfs directory\n", __func__); + return PTR_ERR(mshv_debugfs); + } + + if (hv_root_partition()) { + err = mshv_debugfs_hv_stats_create(mshv_debugfs); + if (err) + goto remove_mshv_dir; + + err = mshv_debugfs_lp_create(mshv_debugfs); + if (err) + goto unmap_hv_stats; + } + + err = mshv_debugfs_parent_partition_create(); + if (err) + goto unmap_lp_stats; + + return 0; + +unmap_lp_stats: + if (hv_root_partition()) { + mshv_debugfs_lp_remove(); + mshv_debugfs_lp = NULL; + } +unmap_hv_stats: + if (hv_root_partition()) + mshv_hv_stats_unmap(); +remove_mshv_dir: + debugfs_remove_recursive(mshv_debugfs); + mshv_debugfs = NULL; + return err; +} + +void mshv_debugfs_exit(void) +{ + mshv_debugfs_parent_partition_remove(); + + if (hv_root_partition()) { + mshv_debugfs_lp_remove(); + mshv_debugfs_lp = NULL; + mshv_hv_stats_unmap(); + } + + debugfs_remove_recursive(mshv_debugfs); + mshv_debugfs = NULL; + mshv_debugfs_partition = NULL; +} diff --git a/drivers/hv/mshv_debugfs_counters.c b/drivers/hv/mshv_debugfs_counters.c new file mode 100644 index 000000000000..978536ba691f --- /dev/null +++ b/drivers/hv/mshv_debugfs_counters.c @@ -0,0 +1,490 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2026, Microsoft Corporation. + * + * Data for printing stats page counters via debugfs. + * + * Authors: Microsoft Linux virtualization team + */ + +/* + * For simplicity, this file is included directly in mshv_debugfs.c. + * If these are ever needed elsewhere they should be compiled separately. + * Ensure this file is not used twice by accident. + */ +#ifndef MSHV_DEBUGFS_C +#error "This file should only be included in mshv_debugfs.c" +#endif + +/* HV_HYPERVISOR_COUNTER */ +static char *hv_hypervisor_counters[] = { + [1] = "HvLogicalProcessors", + [2] = "HvPartitions", + [3] = "HvTotalPages", + [4] = "HvVirtualProcessors", + [5] = "HvMonitoredNotifications", + [6] = "HvModernStandbyEntries", + [7] = "HvPlatformIdleTransitions", + [8] = "HvHypervisorStartupCost", + + [10] = "HvIOSpacePages", + [11] = "HvNonEssentialPagesForDump", + [12] = "HvSubsumedPages", +}; + +/* HV_CPU_COUNTER */ +static char *hv_lp_counters[] = { + [1] = "LpGlobalTime", + [2] = "LpTotalRunTime", + [3] = "LpHypervisorRunTime", + [4] = "LpHardwareInterrupts", + [5] = "LpContextSwitches", + [6] = "LpInterProcessorInterrupts", + [7] = "LpSchedulerInterrupts", + [8] = "LpTimerInterrupts", + [9] = "LpInterProcessorInterruptsSent", + [10] = "LpProcessorHalts", + [11] = "LpMonitorTransitionCost", + [12] = "LpContextSwitchTime", + [13] = "LpC1TransitionsCount", + [14] = "LpC1RunTime", + [15] = "LpC2TransitionsCount", + [16] = "LpC2RunTime", + [17] = "LpC3TransitionsCount", + [18] = "LpC3RunTime", + [19] = "LpRootVpIndex", + [20] = "LpIdleSequenceNumber", + [21] = "LpGlobalTscCount", + [22] = "LpActiveTscCount", + [23] = "LpIdleAccumulation", + [24] = "LpReferenceCycleCount0", + [25] = "LpActualCycleCount0", + [26] = "LpReferenceCycleCount1", + [27] = "LpActualCycleCount1", + [28] = "LpProximityDomainId", + [29] = "LpPostedInterruptNotifications", + [30] = "LpBranchPredictorFlushes", +#if IS_ENABLED(CONFIG_X86_64) + [31] = "LpL1DataCacheFlushes", + [32] = "LpImmediateL1DataCacheFlushes", + [33] = "LpMbFlushes", + [34] = "LpCounterRefreshSequenceNumber", + [35] = "LpCounterRefreshReferenceTime", + [36] = "LpIdleAccumulationSnapshot", + [37] = "LpActiveTscCountSnapshot", + [38] = "LpHwpRequestContextSwitches", + [39] = "LpPlaceholder1", + [40] = "LpPlaceholder2", + [41] = "LpPlaceholder3", + [42] = "LpPlaceholder4", + [43] = "LpPlaceholder5", + [44] = "LpPlaceholder6", + [45] = "LpPlaceholder7", + [46] = "LpPlaceholder8", + [47] = "LpPlaceholder9", + [48] = "LpSchLocalRunListSize", + [49] = "LpReserveGroupId", + [50] = "LpRunningPriority", + [51] = "LpPerfmonInterruptCount", +#elif IS_ENABLED(CONFIG_ARM64) + [31] = "LpCounterRefreshSequenceNumber", + [32] = "LpCounterRefreshReferenceTime", + [33] = "LpIdleAccumulationSnapshot", + [34] = "LpActiveTscCountSnapshot", + [35] = "LpHwpRequestContextSwitches", + [36] = "LpPlaceholder2", + [37] = "LpPlaceholder3", + [38] = "LpPlaceholder4", + [39] = "LpPlaceholder5", + [40] = "LpPlaceholder6", + [41] = "LpPlaceholder7", + [42] = "LpPlaceholder8", + [43] = "LpPlaceholder9", + [44] = "LpSchLocalRunListSize", + [45] = "LpReserveGroupId", + [46] = "LpRunningPriority", +#endif +}; + +/* HV_PROCESS_COUNTER */ +static char *hv_partition_counters[] = { + [1] = "PtVirtualProcessors", + + [3] = "PtTlbSize", + [4] = "PtAddressSpaces", + [5] = "PtDepositedPages", + [6] = "PtGpaPages", + [7] = "PtGpaSpaceModifications", + [8] = "PtVirtualTlbFlushEntires", + [9] = "PtRecommendedTlbSize", + [10] = "PtGpaPages4K", + [11] = "PtGpaPages2M", + [12] = "PtGpaPages1G", + [13] = "PtGpaPages512G", + [14] = "PtDevicePages4K", + [15] = "PtDevicePages2M", + [16] = "PtDevicePages1G", + [17] = "PtDevicePages512G", + [18] = "PtAttachedDevices", + [19] = "PtDeviceInterruptMappings", + [20] = "PtIoTlbFlushes", + [21] = "PtIoTlbFlushCost", + [22] = "PtDeviceInterruptErrors", + [23] = "PtDeviceDmaErrors", + [24] = "PtDeviceInterruptThrottleEvents", + [25] = "PtSkippedTimerTicks", + [26] = "PtPartitionId", +#if IS_ENABLED(CONFIG_X86_64) + [27] = "PtNestedTlbSize", + [28] = "PtRecommendedNestedTlbSize", + [29] = "PtNestedTlbFreeListSize", + [30] = "PtNestedTlbTrimmedPages", + [31] = "PtPagesShattered", + [32] = "PtPagesRecombined", + [33] = "PtHwpRequestValue", + [34] = "PtAutoSuspendEnableTime", + [35] = "PtAutoSuspendTriggerTime", + [36] = "PtAutoSuspendDisableTime", + [37] = "PtPlaceholder1", + [38] = "PtPlaceholder2", + [39] = "PtPlaceholder3", + [40] = "PtPlaceholder4", + [41] = "PtPlaceholder5", + [42] = "PtPlaceholder6", + [43] = "PtPlaceholder7", + [44] = "PtPlaceholder8", + [45] = "PtHypervisorStateTransferGeneration", + [46] = "PtNumberofActiveChildPartitions", +#elif IS_ENABLED(CONFIG_ARM64) + [27] = "PtHwpRequestValue", + [28] = "PtAutoSuspendEnableTime", + [29] = "PtAutoSuspendTriggerTime", + [30] = "PtAutoSuspendDisableTime", + [31] = "PtPlaceholder1", + [32] = "PtPlaceholder2", + [33] = "PtPlaceholder3", + [34] = "PtPlaceholder4", + [35] = "PtPlaceholder5", + [36] = "PtPlaceholder6", + [37] = "PtPlaceholder7", + [38] = "PtPlaceholder8", + [39] = "PtHypervisorStateTransferGeneration", + [40] = "PtNumberofActiveChildPartitions", +#endif +}; + +/* HV_THREAD_COUNTER */ +static char *hv_vp_counters[] = { + [1] = "VpTotalRunTime", + [2] = "VpHypervisorRunTime", + [3] = "VpRemoteNodeRunTime", + [4] = "VpNormalizedRunTime", + [5] = "VpIdealCpu", + + [7] = "VpHypercallsCount", + [8] = "VpHypercallsTime", +#if IS_ENABLED(CONFIG_X86_64) + [9] = "VpPageInvalidationsCount", + [10] = "VpPageInvalidationsTime", + [11] = "VpControlRegisterAccessesCount", + [12] = "VpControlRegisterAccessesTime", + [13] = "VpIoInstructionsCount", + [14] = "VpIoInstructionsTime", + [15] = "VpHltInstructionsCount", + [16] = "VpHltInstructionsTime", + [17] = "VpMwaitInstructionsCount", + [18] = "VpMwaitInstructionsTime", + [19] = "VpCpuidInstructionsCount", + [20] = "VpCpuidInstructionsTime", + [21] = "VpMsrAccessesCount", + [22] = "VpMsrAccessesTime", + [23] = "VpOtherInterceptsCount", + [24] = "VpOtherInterceptsTime", + [25] = "VpExternalInterruptsCount", + [26] = "VpExternalInterruptsTime", + [27] = "VpPendingInterruptsCount", + [28] = "VpPendingInterruptsTime", + [29] = "VpEmulatedInstructionsCount", + [30] = "VpEmulatedInstructionsTime", + [31] = "VpDebugRegisterAccessesCount", + [32] = "VpDebugRegisterAccessesTime", + [33] = "VpPageFaultInterceptsCount", + [34] = "VpPageFaultInterceptsTime", + [35] = "VpGuestPageTableMaps", + [36] = "VpLargePageTlbFills", + [37] = "VpSmallPageTlbFills", + [38] = "VpReflectedGuestPageFaults", + [39] = "VpApicMmioAccesses", + [40] = "VpIoInterceptMessages", + [41] = "VpMemoryInterceptMessages", + [42] = "VpApicEoiAccesses", + [43] = "VpOtherMessages", + [44] = "VpPageTableAllocations", + [45] = "VpLogicalProcessorMigrations", + [46] = "VpAddressSpaceEvictions", + [47] = "VpAddressSpaceSwitches", + [48] = "VpAddressDomainFlushes", + [49] = "VpAddressSpaceFlushes", + [50] = "VpGlobalGvaRangeFlushes", + [51] = "VpLocalGvaRangeFlushes", + [52] = "VpPageTableEvictions", + [53] = "VpPageTableReclamations", + [54] = "VpPageTableResets", + [55] = "VpPageTableValidations", + [56] = "VpApicTprAccesses", + [57] = "VpPageTableWriteIntercepts", + [58] = "VpSyntheticInterrupts", + [59] = "VpVirtualInterrupts", + [60] = "VpApicIpisSent", + [61] = "VpApicSelfIpisSent", + [62] = "VpGpaSpaceHypercalls", + [63] = "VpLogicalProcessorHypercalls", + [64] = "VpLongSpinWaitHypercalls", + [65] = "VpOtherHypercalls", + [66] = "VpSyntheticInterruptHypercalls", + [67] = "VpVirtualInterruptHypercalls", + [68] = "VpVirtualMmuHypercalls", + [69] = "VpVirtualProcessorHypercalls", + [70] = "VpHardwareInterrupts", + [71] = "VpNestedPageFaultInterceptsCount", + [72] = "VpNestedPageFaultInterceptsTime", + [73] = "VpPageScans", + [74] = "VpLogicalProcessorDispatches", + [75] = "VpWaitingForCpuTime", + [76] = "VpExtendedHypercalls", + [77] = "VpExtendedHypercallInterceptMessages", + [78] = "VpMbecNestedPageTableSwitches", + [79] = "VpOtherReflectedGuestExceptions", + [80] = "VpGlobalIoTlbFlushes", + [81] = "VpGlobalIoTlbFlushCost", + [82] = "VpLocalIoTlbFlushes", + [83] = "VpLocalIoTlbFlushCost", + [84] = "VpHypercallsForwardedCount", + [85] = "VpHypercallsForwardingTime", + [86] = "VpPageInvalidationsForwardedCount", + [87] = "VpPageInvalidationsForwardingTime", + [88] = "VpControlRegisterAccessesForwardedCount", + [89] = "VpControlRegisterAccessesForwardingTime", + [90] = "VpIoInstructionsForwardedCount", + [91] = "VpIoInstructionsForwardingTime", + [92] = "VpHltInstructionsForwardedCount", + [93] = "VpHltInstructionsForwardingTime", + [94] = "VpMwaitInstructionsForwardedCount", + [95] = "VpMwaitInstructionsForwardingTime", + [96] = "VpCpuidInstructionsForwardedCount", + [97] = "VpCpuidInstructionsForwardingTime", + [98] = "VpMsrAccessesForwardedCount", + [99] = "VpMsrAccessesForwardingTime", + [100] = "VpOtherInterceptsForwardedCount", + [101] = "VpOtherInterceptsForwardingTime", + [102] = "VpExternalInterruptsForwardedCount", + [103] = "VpExternalInterruptsForwardingTime", + [104] = "VpPendingInterruptsForwardedCount", + [105] = "VpPendingInterruptsForwardingTime", + [106] = "VpEmulatedInstructionsForwardedCount", + [107] = "VpEmulatedInstructionsForwardingTime", + [108] = "VpDebugRegisterAccessesForwardedCount", + [109] = "VpDebugRegisterAccessesForwardingTime", + [110] = "VpPageFaultInterceptsForwardedCount", + [111] = "VpPageFaultInterceptsForwardingTime", + [112] = "VpVmclearEmulationCount", + [113] = "VpVmclearEmulationTime", + [114] = "VpVmptrldEmulationCount", + [115] = "VpVmptrldEmulationTime", + [116] = "VpVmptrstEmulationCount", + [117] = "VpVmptrstEmulationTime", + [118] = "VpVmreadEmulationCount", + [119] = "VpVmreadEmulationTime", + [120] = "VpVmwriteEmulationCount", + [121] = "VpVmwriteEmulationTime", + [122] = "VpVmxoffEmulationCount", + [123] = "VpVmxoffEmulationTime", + [124] = "VpVmxonEmulationCount", + [125] = "VpVmxonEmulationTime", + [126] = "VpNestedVMEntriesCount", + [127] = "VpNestedVMEntriesTime", + [128] = "VpNestedSLATSoftPageFaultsCount", + [129] = "VpNestedSLATSoftPageFaultsTime", + [130] = "VpNestedSLATHardPageFaultsCount", + [131] = "VpNestedSLATHardPageFaultsTime", + [132] = "VpInvEptAllContextEmulationCount", + [133] = "VpInvEptAllContextEmulationTime", + [134] = "VpInvEptSingleContextEmulationCount", + [135] = "VpInvEptSingleContextEmulationTime", + [136] = "VpInvVpidAllContextEmulationCount", + [137] = "VpInvVpidAllContextEmulationTime", + [138] = "VpInvVpidSingleContextEmulationCount", + [139] = "VpInvVpidSingleContextEmulationTime", + [140] = "VpInvVpidSingleAddressEmulationCount", + [141] = "VpInvVpidSingleAddressEmulationTime", + [142] = "VpNestedTlbPageTableReclamations", + [143] = "VpNestedTlbPageTableEvictions", + [144] = "VpFlushGuestPhysicalAddressSpaceHypercalls", + [145] = "VpFlushGuestPhysicalAddressListHypercalls", + [146] = "VpPostedInterruptNotifications", + [147] = "VpPostedInterruptScans", + [148] = "VpTotalCoreRunTime", + [149] = "VpMaximumRunTime", + [150] = "VpHwpRequestContextSwitches", + [151] = "VpWaitingForCpuTimeBucket0", + [152] = "VpWaitingForCpuTimeBucket1", + [153] = "VpWaitingForCpuTimeBucket2", + [154] = "VpWaitingForCpuTimeBucket3", + [155] = "VpWaitingForCpuTimeBucket4", + [156] = "VpWaitingForCpuTimeBucket5", + [157] = "VpWaitingForCpuTimeBucket6", + [158] = "VpVmloadEmulationCount", + [159] = "VpVmloadEmulationTime", + [160] = "VpVmsaveEmulationCount", + [161] = "VpVmsaveEmulationTime", + [162] = "VpGifInstructionEmulationCount", + [163] = "VpGifInstructionEmulationTime", + [164] = "VpEmulatedErrataSvmInstructions", + [165] = "VpPlaceholder1", + [166] = "VpPlaceholder2", + [167] = "VpPlaceholder3", + [168] = "VpPlaceholder4", + [169] = "VpPlaceholder5", + [170] = "VpPlaceholder6", + [171] = "VpPlaceholder7", + [172] = "VpPlaceholder8", + [173] = "VpContentionTime", + [174] = "VpWakeUpTime", + [175] = "VpSchedulingPriority", + [176] = "VpRdpmcInstructionsCount", + [177] = "VpRdpmcInstructionsTime", + [178] = "VpPerfmonPmuMsrAccessesCount", + [179] = "VpPerfmonLbrMsrAccessesCount", + [180] = "VpPerfmonIptMsrAccessesCount", + [181] = "VpPerfmonInterruptCount", + [182] = "VpVtl1DispatchCount", + [183] = "VpVtl2DispatchCount", + [184] = "VpVtl2DispatchBucket0", + [185] = "VpVtl2DispatchBucket1", + [186] = "VpVtl2DispatchBucket2", + [187] = "VpVtl2DispatchBucket3", + [188] = "VpVtl2DispatchBucket4", + [189] = "VpVtl2DispatchBucket5", + [190] = "VpVtl2DispatchBucket6", + [191] = "VpVtl1RunTime", + [192] = "VpVtl2RunTime", + [193] = "VpIommuHypercalls", + [194] = "VpCpuGroupHypercalls", + [195] = "VpVsmHypercalls", + [196] = "VpEventLogHypercalls", + [197] = "VpDeviceDomainHypercalls", + [198] = "VpDepositHypercalls", + [199] = "VpSvmHypercalls", + [200] = "VpBusLockAcquisitionCount", + [201] = "VpLoadAvg", + [202] = "VpRootDispatchThreadBlocked", + [203] = "VpIdleCpuTime", + [204] = "VpWaitingForCpuTimeBucket7", + [205] = "VpWaitingForCpuTimeBucket8", + [206] = "VpWaitingForCpuTimeBucket9", + [207] = "VpWaitingForCpuTimeBucket10", + [208] = "VpWaitingForCpuTimeBucket11", + [209] = "VpWaitingForCpuTimeBucket12", + [210] = "VpHierarchicalSuspendTime", + [211] = "VpExpressSchedulingAttempts", + [212] = "VpExpressSchedulingCount", +#elif IS_ENABLED(CONFIG_ARM64) + [9] = "VpSysRegAccessesCount", + [10] = "VpSysRegAccessesTime", + [11] = "VpSmcInstructionsCount", + [12] = "VpSmcInstructionsTime", + [13] = "VpOtherInterceptsCount", + [14] = "VpOtherInterceptsTime", + [15] = "VpExternalInterruptsCount", + [16] = "VpExternalInterruptsTime", + [17] = "VpPendingInterruptsCount", + [18] = "VpPendingInterruptsTime", + [19] = "VpGuestPageTableMaps", + [20] = "VpLargePageTlbFills", + [21] = "VpSmallPageTlbFills", + [22] = "VpReflectedGuestPageFaults", + [23] = "VpMemoryInterceptMessages", + [24] = "VpOtherMessages", + [25] = "VpLogicalProcessorMigrations", + [26] = "VpAddressDomainFlushes", + [27] = "VpAddressSpaceFlushes", + [28] = "VpSyntheticInterrupts", + [29] = "VpVirtualInterrupts", + [30] = "VpApicSelfIpisSent", + [31] = "VpGpaSpaceHypercalls", + [32] = "VpLogicalProcessorHypercalls", + [33] = "VpLongSpinWaitHypercalls", + [34] = "VpOtherHypercalls", + [35] = "VpSyntheticInterruptHypercalls", + [36] = "VpVirtualInterruptHypercalls", + [37] = "VpVirtualMmuHypercalls", + [38] = "VpVirtualProcessorHypercalls", + [39] = "VpHardwareInterrupts", + [40] = "VpNestedPageFaultInterceptsCount", + [41] = "VpNestedPageFaultInterceptsTime", + [42] = "VpLogicalProcessorDispatches", + [43] = "VpWaitingForCpuTime", + [44] = "VpExtendedHypercalls", + [45] = "VpExtendedHypercallInterceptMessages", + [46] = "VpMbecNestedPageTableSwitches", + [47] = "VpOtherReflectedGuestExceptions", + [48] = "VpGlobalIoTlbFlushes", + [49] = "VpGlobalIoTlbFlushCost", + [50] = "VpLocalIoTlbFlushes", + [51] = "VpLocalIoTlbFlushCost", + [52] = "VpFlushGuestPhysicalAddressSpaceHypercalls", + [53] = "VpFlushGuestPhysicalAddressListHypercalls", + [54] = "VpPostedInterruptNotifications", + [55] = "VpPostedInterruptScans", + [56] = "VpTotalCoreRunTime", + [57] = "VpMaximumRunTime", + [58] = "VpWaitingForCpuTimeBucket0", + [59] = "VpWaitingForCpuTimeBucket1", + [60] = "VpWaitingForCpuTimeBucket2", + [61] = "VpWaitingForCpuTimeBucket3", + [62] = "VpWaitingForCpuTimeBucket4", + [63] = "VpWaitingForCpuTimeBucket5", + [64] = "VpWaitingForCpuTimeBucket6", + [65] = "VpHwpRequestContextSwitches", + [66] = "VpPlaceholder2", + [67] = "VpPlaceholder3", + [68] = "VpPlaceholder4", + [69] = "VpPlaceholder5", + [70] = "VpPlaceholder6", + [71] = "VpPlaceholder7", + [72] = "VpPlaceholder8", + [73] = "VpContentionTime", + [74] = "VpWakeUpTime", + [75] = "VpSchedulingPriority", + [76] = "VpVtl1DispatchCount", + [77] = "VpVtl2DispatchCount", + [78] = "VpVtl2DispatchBucket0", + [79] = "VpVtl2DispatchBucket1", + [80] = "VpVtl2DispatchBucket2", + [81] = "VpVtl2DispatchBucket3", + [82] = "VpVtl2DispatchBucket4", + [83] = "VpVtl2DispatchBucket5", + [84] = "VpVtl2DispatchBucket6", + [85] = "VpVtl1RunTime", + [86] = "VpVtl2RunTime", + [87] = "VpIommuHypercalls", + [88] = "VpCpuGroupHypercalls", + [89] = "VpVsmHypercalls", + [90] = "VpEventLogHypercalls", + [91] = "VpDeviceDomainHypercalls", + [92] = "VpDepositHypercalls", + [93] = "VpSvmHypercalls", + [94] = "VpLoadAvg", + [95] = "VpRootDispatchThreadBlocked", + [96] = "VpIdleCpuTime", + [97] = "VpWaitingForCpuTimeBucket7", + [98] = "VpWaitingForCpuTimeBucket8", + [99] = "VpWaitingForCpuTimeBucket9", + [100] = "VpWaitingForCpuTimeBucket10", + [101] = "VpWaitingForCpuTimeBucket11", + [102] = "VpWaitingForCpuTimeBucket12", + [103] = "VpHierarchicalSuspendTime", + [104] = "VpExpressSchedulingAttempts", + [105] = "VpExpressSchedulingCount", +#endif +}; diff --git a/drivers/hv/mshv_eventfd.c b/drivers/hv/mshv_eventfd.c index 0b75ff1edb73..d8471546e6a0 100644 --- a/drivers/hv/mshv_eventfd.c +++ b/drivers/hv/mshv_eventfd.c @@ -87,8 +87,9 @@ static void mshv_irqfd_resampler_ack(struct mshv_irq_ack_notifier *mian) idx = srcu_read_lock(&partition->pt_irq_srcu); - hlist_for_each_entry_rcu(irqfd, &resampler->rsmplr_irqfd_list, - irqfd_resampler_hnode) { + hlist_for_each_entry_srcu(irqfd, &resampler->rsmplr_irqfd_list, + irqfd_resampler_hnode, + srcu_read_lock_held(&partition->pt_irq_srcu)) { if (hv_should_clear_interrupt(irqfd->irqfd_lapic_irq.lapic_control.interrupt_type)) hv_call_clear_virtual_interrupt(partition->pt_id); @@ -128,8 +129,8 @@ static int mshv_vp_irq_try_set_vector(struct mshv_vp *vp, u32 vector) new_iv.vector[new_iv.vector_count++] = vector; - if (cmpxchg(&vp->vp_register_page->interrupt_vectors.as_uint64, - iv.as_uint64, new_iv.as_uint64) != iv.as_uint64) + if (!try_cmpxchg(&vp->vp_register_page->interrupt_vectors.as_uint64, + &iv.as_uint64, new_iv.as_uint64)) return -EAGAIN; return 0; @@ -247,12 +248,13 @@ static void mshv_irqfd_shutdown(struct work_struct *work) { struct mshv_irqfd *irqfd = container_of(work, struct mshv_irqfd, irqfd_shutdown); + u64 cnt; /* * Synchronize with the wait-queue and unhook ourselves to prevent * further events. */ - remove_wait_queue(irqfd->irqfd_wqh, &irqfd->irqfd_wait); + eventfd_ctx_remove_wait_queue(irqfd->irqfd_eventfd_ctx, &irqfd->irqfd_wait, &cnt); if (irqfd->irqfd_resampler) { mshv_irqfd_resampler_shutdown(irqfd); @@ -295,13 +297,13 @@ static int mshv_irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, { struct mshv_irqfd *irqfd = container_of(wait, struct mshv_irqfd, irqfd_wait); - unsigned long flags = (unsigned long)key; + __poll_t flags = key_to_poll(key); int idx; unsigned int seq; struct mshv_partition *pt = irqfd->irqfd_partn; int ret = 0; - if (flags & POLLIN) { + if (flags & EPOLLIN) { u64 cnt; eventfd_ctx_do_read(irqfd->irqfd_eventfd_ctx, &cnt); @@ -320,7 +322,7 @@ static int mshv_irqfd_wakeup(wait_queue_entry_t *wait, unsigned int mode, ret = 1; } - if (flags & POLLHUP) { + if (flags & EPOLLHUP) { /* The eventfd is closing, detach from the partition */ unsigned long flags; @@ -371,8 +373,6 @@ static void mshv_irqfd_queue_proc(struct file *file, wait_queue_head_t *wqh, struct mshv_irqfd *irqfd = container_of(polltbl, struct mshv_irqfd, irqfd_polltbl); - irqfd->irqfd_wqh = wqh; - /* * TODO: Ensure there isn't already an exclusive, priority waiter, e.g. * that the irqfd isn't already bound to another partition. Only the @@ -394,7 +394,7 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, CLASS(fd, f)(args->fd); - irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); + irqfd = kzalloc_obj(*irqfd); if (!irqfd) return -ENOMEM; @@ -439,7 +439,7 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, } if (!irqfd->irqfd_resampler) { - rp = kzalloc(sizeof(*rp), GFP_KERNEL_ACCOUNT); + rp = kzalloc_obj(*rp, GFP_KERNEL_ACCOUNT); if (!rp) { ret = -ENOMEM; mutex_unlock(&pt->irqfds_resampler_lock); @@ -506,7 +506,7 @@ static int mshv_irqfd_assign(struct mshv_partition *pt, */ events = vfs_poll(fd_file(f), &irqfd->irqfd_polltbl); - if (events & POLLIN) + if (events & EPOLLIN) mshv_assert_irq_slow(irqfd); srcu_read_unlock(&pt->pt_irq_srcu, idx); @@ -707,7 +707,7 @@ static int mshv_assign_ioeventfd(struct mshv_partition *pt, if (IS_ERR(eventfd)) return PTR_ERR(eventfd); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { ret = -ENOMEM; goto fail; diff --git a/drivers/hv/mshv_eventfd.h b/drivers/hv/mshv_eventfd.h index 332e7670a344..464c6b81ab33 100644 --- a/drivers/hv/mshv_eventfd.h +++ b/drivers/hv/mshv_eventfd.h @@ -32,7 +32,6 @@ struct mshv_irqfd { struct mshv_lapic_irq irqfd_lapic_irq; struct hlist_node irqfd_hnode; poll_table irqfd_polltbl; - wait_queue_head_t *irqfd_wqh; wait_queue_entry_t irqfd_wait; struct work_struct irqfd_shutdown; struct mshv_irqfd_resampler *irqfd_resampler; diff --git a/drivers/hv/mshv_irq.c b/drivers/hv/mshv_irq.c index 798e7e1ab06e..02c56fc3a498 100644 --- a/drivers/hv/mshv_irq.c +++ b/drivers/hv/mshv_irq.c @@ -37,8 +37,8 @@ int mshv_update_routing_table(struct mshv_partition *partition, } nr_rt_entries += 1; - new = kzalloc(struct_size(new, mshv_girq_info_tbl, nr_rt_entries), - GFP_KERNEL_ACCOUNT); + new = kzalloc_flex(*new, mshv_girq_info_tbl, nr_rt_entries, + GFP_KERNEL_ACCOUNT); if (!new) return -ENOMEM; diff --git a/drivers/hv/mshv_regions.c b/drivers/hv/mshv_regions.c index adba3564d9f1..c28aac0726de 100644 --- a/drivers/hv/mshv_regions.c +++ b/drivers/hv/mshv_regions.c @@ -88,7 +88,7 @@ static long mshv_region_process_chunk(struct mshv_mem_region *region, struct page *page; int stride, ret; - page = region->pages[page_offset]; + page = region->mreg_pages[page_offset]; if (!page) return -EINVAL; @@ -98,7 +98,7 @@ static long mshv_region_process_chunk(struct mshv_mem_region *region, /* Start at stride since the first stride is validated */ for (count = stride; count < page_count; count += stride) { - page = region->pages[page_offset + count]; + page = region->mreg_pages[page_offset + count]; /* Break if current page is not present */ if (!page) @@ -152,7 +152,7 @@ static int mshv_region_process_range(struct mshv_mem_region *region, while (page_count) { /* Skip non-present pages */ - if (!region->pages[page_offset]) { + if (!region->mreg_pages[page_offset]) { page_offset++; page_count--; continue; @@ -190,7 +190,7 @@ struct mshv_mem_region *mshv_region_create(u64 guest_pfn, u64 nr_pages, if (flags & BIT(MSHV_SET_MEM_BIT_EXECUTABLE)) region->hv_map_flags |= HV_MAP_GPA_EXECUTABLE; - kref_init(®ion->refcount); + kref_init(®ion->mreg_refcount); return region; } @@ -204,7 +204,7 @@ static int mshv_region_chunk_share(struct mshv_mem_region *region, flags |= HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE; return hv_call_modify_spa_host_access(region->partition->pt_id, - region->pages + page_offset, + region->mreg_pages + page_offset, page_count, HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE, @@ -229,7 +229,7 @@ static int mshv_region_chunk_unshare(struct mshv_mem_region *region, flags |= HV_MODIFY_SPA_PAGE_HOST_ACCESS_LARGE_PAGE; return hv_call_modify_spa_host_access(region->partition->pt_id, - region->pages + page_offset, + region->mreg_pages + page_offset, page_count, 0, flags, false); } @@ -254,7 +254,7 @@ static int mshv_region_chunk_remap(struct mshv_mem_region *region, return hv_call_map_gpa_pages(region->partition->pt_id, region->start_gfn + page_offset, page_count, flags, - region->pages + page_offset); + region->mreg_pages + page_offset); } static int mshv_region_remap_pages(struct mshv_mem_region *region, @@ -277,10 +277,10 @@ int mshv_region_map(struct mshv_mem_region *region) static void mshv_region_invalidate_pages(struct mshv_mem_region *region, u64 page_offset, u64 page_count) { - if (region->type == MSHV_REGION_TYPE_MEM_PINNED) - unpin_user_pages(region->pages + page_offset, page_count); + if (region->mreg_type == MSHV_REGION_TYPE_MEM_PINNED) + unpin_user_pages(region->mreg_pages + page_offset, page_count); - memset(region->pages + page_offset, 0, + memset(region->mreg_pages + page_offset, 0, page_count * sizeof(struct page *)); } @@ -297,7 +297,7 @@ int mshv_region_pin(struct mshv_mem_region *region) int ret; for (done_count = 0; done_count < region->nr_pages; done_count += ret) { - pages = region->pages + done_count; + pages = region->mreg_pages + done_count; userspace_addr = region->start_uaddr + done_count * HV_HYP_PAGE_SIZE; nr_pages = min(region->nr_pages - done_count, @@ -348,11 +348,11 @@ static int mshv_region_unmap(struct mshv_mem_region *region) static void mshv_region_destroy(struct kref *ref) { struct mshv_mem_region *region = - container_of(ref, struct mshv_mem_region, refcount); + container_of(ref, struct mshv_mem_region, mreg_refcount); struct mshv_partition *partition = region->partition; int ret; - if (region->type == MSHV_REGION_TYPE_MEM_MOVABLE) + if (region->mreg_type == MSHV_REGION_TYPE_MEM_MOVABLE) mshv_region_movable_fini(region); if (mshv_partition_encrypted(partition)) { @@ -374,12 +374,12 @@ static void mshv_region_destroy(struct kref *ref) void mshv_region_put(struct mshv_mem_region *region) { - kref_put(®ion->refcount, mshv_region_destroy); + kref_put(®ion->mreg_refcount, mshv_region_destroy); } int mshv_region_get(struct mshv_mem_region *region) { - return kref_get_unless_zero(®ion->refcount); + return kref_get_unless_zero(®ion->mreg_refcount); } /** @@ -405,16 +405,16 @@ static int mshv_region_hmm_fault_and_lock(struct mshv_mem_region *region, int ret; range->notifier_seq = mmu_interval_read_begin(range->notifier); - mmap_read_lock(region->mni.mm); + mmap_read_lock(region->mreg_mni.mm); ret = hmm_range_fault(range); - mmap_read_unlock(region->mni.mm); + mmap_read_unlock(region->mreg_mni.mm); if (ret) return ret; - mutex_lock(®ion->mutex); + mutex_lock(®ion->mreg_mutex); if (mmu_interval_read_retry(range->notifier, range->notifier_seq)) { - mutex_unlock(®ion->mutex); + mutex_unlock(®ion->mreg_mutex); cond_resched(); return -EBUSY; } @@ -438,7 +438,7 @@ static int mshv_region_range_fault(struct mshv_mem_region *region, u64 page_offset, u64 page_count) { struct hmm_range range = { - .notifier = ®ion->mni, + .notifier = ®ion->mreg_mni, .default_flags = HMM_PFN_REQ_FAULT | HMM_PFN_REQ_WRITE, }; unsigned long *pfns; @@ -461,12 +461,12 @@ static int mshv_region_range_fault(struct mshv_mem_region *region, goto out; for (i = 0; i < page_count; i++) - region->pages[page_offset + i] = hmm_pfn_to_page(pfns[i]); + region->mreg_pages[page_offset + i] = hmm_pfn_to_page(pfns[i]); ret = mshv_region_remap_pages(region, region->hv_map_flags, page_offset, page_count); - mutex_unlock(®ion->mutex); + mutex_unlock(®ion->mreg_mutex); out: kfree(pfns); return ret; @@ -520,7 +520,7 @@ static bool mshv_region_interval_invalidate(struct mmu_interval_notifier *mni, { struct mshv_mem_region *region = container_of(mni, struct mshv_mem_region, - mni); + mreg_mni); u64 page_offset, page_count; unsigned long mstart, mend; int ret = -EPERM; @@ -533,8 +533,8 @@ static bool mshv_region_interval_invalidate(struct mmu_interval_notifier *mni, page_count = HVPFN_DOWN(mend - mstart); if (mmu_notifier_range_blockable(range)) - mutex_lock(®ion->mutex); - else if (!mutex_trylock(®ion->mutex)) + mutex_lock(®ion->mreg_mutex); + else if (!mutex_trylock(®ion->mreg_mutex)) goto out_fail; mmu_interval_set_seq(mni, cur_seq); @@ -546,12 +546,12 @@ static bool mshv_region_interval_invalidate(struct mmu_interval_notifier *mni, mshv_region_invalidate_pages(region, page_offset, page_count); - mutex_unlock(®ion->mutex); + mutex_unlock(®ion->mreg_mutex); return true; out_unlock: - mutex_unlock(®ion->mutex); + mutex_unlock(®ion->mreg_mutex); out_fail: WARN_ONCE(ret, "Failed to invalidate region %#llx-%#llx (range %#lx-%#lx, event: %u, pages %#llx-%#llx, mm: %#llx): %d\n", @@ -568,21 +568,21 @@ static const struct mmu_interval_notifier_ops mshv_region_mni_ops = { void mshv_region_movable_fini(struct mshv_mem_region *region) { - mmu_interval_notifier_remove(®ion->mni); + mmu_interval_notifier_remove(®ion->mreg_mni); } bool mshv_region_movable_init(struct mshv_mem_region *region) { int ret; - ret = mmu_interval_notifier_insert(®ion->mni, current->mm, + ret = mmu_interval_notifier_insert(®ion->mreg_mni, current->mm, region->start_uaddr, region->nr_pages << HV_HYP_PAGE_SHIFT, &mshv_region_mni_ops); if (ret) return false; - mutex_init(®ion->mutex); + mutex_init(®ion->mreg_mutex); return true; } diff --git a/drivers/hv/mshv_root.h b/drivers/hv/mshv_root.h index 3c1d88b36741..04c2a1910a8a 100644 --- a/drivers/hv/mshv_root.h +++ b/drivers/hv/mshv_root.h @@ -52,6 +52,9 @@ struct mshv_vp { unsigned int kicked_by_hv; wait_queue_head_t vp_suspend_queue; } run; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *vp_stats_dentry; +#endif }; #define vp_fmt(fmt) "p%lluvp%u: " fmt @@ -79,16 +82,16 @@ enum mshv_region_type { struct mshv_mem_region { struct hlist_node hnode; - struct kref refcount; + struct kref mreg_refcount; u64 nr_pages; u64 start_gfn; u64 start_uaddr; u32 hv_map_flags; struct mshv_partition *partition; - enum mshv_region_type type; - struct mmu_interval_notifier mni; - struct mutex mutex; /* protects region pages remapping */ - struct page *pages[]; + enum mshv_region_type mreg_type; + struct mmu_interval_notifier mreg_mni; + struct mutex mreg_mutex; /* protects region pages remapping */ + struct page *mreg_pages[]; }; struct mshv_irq_ack_notifier { @@ -136,6 +139,10 @@ struct mshv_partition { u64 isolation_type; bool import_completed; bool pt_initialized; +#if IS_ENABLED(CONFIG_DEBUG_FS) + struct dentry *pt_stats_dentry; + struct dentry *pt_vp_dentry; +#endif }; #define pt_fmt(fmt) "p%llu: " fmt @@ -254,6 +261,16 @@ struct mshv_partition *mshv_partition_get(struct mshv_partition *partition); void mshv_partition_put(struct mshv_partition *partition); struct mshv_partition *mshv_partition_find(u64 partition_id) __must_hold(RCU); +static inline bool is_l1vh_parent(u64 partition_id) +{ + return hv_l1vh_partition() && (partition_id == HV_PARTITION_ID_SELF); +} + +int mshv_vp_stats_map(u64 partition_id, u32 vp_index, + struct hv_stats_page **stats_pages); +void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, + struct hv_stats_page **stats_pages); + /* hypercalls */ int hv_call_withdraw_memory(u64 count, int node, u64 partition_id); @@ -307,8 +324,9 @@ int hv_call_disconnect_port(u64 connection_partition_id, int hv_call_notify_port_ring_empty(u32 sint_index); int hv_map_stats_page(enum hv_stats_object_type type, const union hv_stats_object_identity *identity, - void **addr); -int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr, + struct hv_stats_page **addr); +int hv_unmap_stats_page(enum hv_stats_object_type type, + struct hv_stats_page *page_addr, const union hv_stats_object_identity *identity); int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages, u64 page_struct_count, u32 host_access, @@ -316,6 +334,33 @@ int hv_call_modify_spa_host_access(u64 partition_id, struct page **pages, int hv_call_get_partition_property_ex(u64 partition_id, u64 property_code, u64 arg, void *property_value, size_t property_value_sz); +#if IS_ENABLED(CONFIG_DEBUG_FS) +int __init mshv_debugfs_init(void); +void mshv_debugfs_exit(void); + +int mshv_debugfs_partition_create(struct mshv_partition *partition); +void mshv_debugfs_partition_remove(struct mshv_partition *partition); +int mshv_debugfs_vp_create(struct mshv_vp *vp); +void mshv_debugfs_vp_remove(struct mshv_vp *vp); +#else +static inline int __init mshv_debugfs_init(void) +{ + return 0; +} +static inline void mshv_debugfs_exit(void) { } + +static inline int mshv_debugfs_partition_create(struct mshv_partition *partition) +{ + return 0; +} +static inline void mshv_debugfs_partition_remove(struct mshv_partition *partition) { } +static inline int mshv_debugfs_vp_create(struct mshv_vp *vp) +{ + return 0; +} +static inline void mshv_debugfs_vp_remove(struct mshv_vp *vp) { } +#endif + extern struct mshv_root mshv_root; extern enum hv_scheduler_type hv_scheduler_type; extern u8 * __percpu *hv_synic_eventring_tail; diff --git a/drivers/hv/mshv_root_hv_call.c b/drivers/hv/mshv_root_hv_call.c index 598eaff4ff29..7f91096f95a8 100644 --- a/drivers/hv/mshv_root_hv_call.c +++ b/drivers/hv/mshv_root_hv_call.c @@ -115,7 +115,7 @@ int hv_call_create_partition(u64 flags, status = hv_do_hypercall(HVCALL_CREATE_PARTITION, input, output); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { if (hv_result_success(status)) *partition_id = output->partition_id; local_irq_restore(irq_flags); @@ -123,8 +123,7 @@ int hv_call_create_partition(u64 flags, break; } local_irq_restore(irq_flags); - ret = hv_call_deposit_pages(NUMA_NO_NODE, - hv_current_partition_id, 1); + ret = hv_deposit_memory(hv_current_partition_id, status); } while (!ret); return ret; @@ -147,11 +146,11 @@ int hv_call_initialize_partition(u64 partition_id) status = hv_do_fast_hypercall8(HVCALL_INITIALIZE_PARTITION, *(u64 *)&input); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { ret = hv_result_to_errno(status); break; } - ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id, 1); + ret = hv_deposit_memory(partition_id, status); } while (!ret); return ret; @@ -239,7 +238,7 @@ static int hv_do_map_gpa_hcall(u64 partition_id, u64 gfn, u64 page_struct_count, completed = hv_repcomp(status); - if (hv_result(status) == HV_STATUS_INSUFFICIENT_MEMORY) { + if (hv_result_needs_memory(status)) { ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id, HV_MAP_GPA_DEPOSIT_PAGES); if (ret) @@ -455,7 +454,7 @@ int hv_call_get_vp_state(u32 vp_index, u64 partition_id, status = hv_do_hypercall(control, input, output); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { if (hv_result_success(status) && ret_output) memcpy(ret_output, output, sizeof(*output)); @@ -465,8 +464,7 @@ int hv_call_get_vp_state(u32 vp_index, u64 partition_id, } local_irq_restore(flags); - ret = hv_call_deposit_pages(NUMA_NO_NODE, - partition_id, 1); + ret = hv_deposit_memory(partition_id, status); } while (!ret); return ret; @@ -518,15 +516,14 @@ int hv_call_set_vp_state(u32 vp_index, u64 partition_id, status = hv_do_hypercall(control, input, NULL); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { local_irq_restore(flags); ret = hv_result_to_errno(status); break; } local_irq_restore(flags); - ret = hv_call_deposit_pages(NUMA_NO_NODE, - partition_id, 1); + ret = hv_deposit_memory(partition_id, status); } while (!ret); return ret; @@ -563,7 +560,7 @@ static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, status = hv_do_hypercall(HVCALL_MAP_VP_STATE_PAGE, input, output); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { if (hv_result_success(status)) *state_page = pfn_to_page(output->map_location); local_irq_restore(flags); @@ -573,7 +570,7 @@ static int hv_call_map_vp_state_page(u64 partition_id, u32 vp_index, u32 type, local_irq_restore(flags); - ret = hv_call_deposit_pages(NUMA_NO_NODE, partition_id, 1); + ret = hv_deposit_memory(partition_id, status); } while (!ret); return ret; @@ -718,12 +715,11 @@ hv_call_create_port(u64 port_partition_id, union hv_port_id port_id, if (hv_result_success(status)) break; - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { ret = hv_result_to_errno(status); break; } - ret = hv_call_deposit_pages(NUMA_NO_NODE, port_partition_id, 1); - + ret = hv_deposit_memory(port_partition_id, status); } while (!ret); return ret; @@ -772,12 +768,11 @@ hv_call_connect_port(u64 port_partition_id, union hv_port_id port_id, if (hv_result_success(status)) break; - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { ret = hv_result_to_errno(status); break; } - ret = hv_call_deposit_pages(NUMA_NO_NODE, - connection_partition_id, 1); + ret = hv_deposit_memory(connection_partition_id, status); } while (!ret); return ret; @@ -813,6 +808,13 @@ hv_call_notify_port_ring_empty(u32 sint_index) return hv_result_to_errno(status); } +/* + * Equivalent of hv_call_map_stats_page() for cases when the caller provides + * the map location. + * + * NOTE: This is a newer hypercall that always supports SELF and PARENT stats + * areas, unlike hv_call_map_stats_page(). + */ static int hv_call_map_stats_page2(enum hv_stats_object_type type, const union hv_stats_object_identity *identity, u64 map_location) @@ -843,21 +845,49 @@ static int hv_call_map_stats_page2(enum hv_stats_object_type type, if (!ret) break; - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { + if (!hv_result_needs_memory(status)) { hv_status_debug(status, "\n"); break; } - ret = hv_call_deposit_pages(NUMA_NO_NODE, - hv_current_partition_id, 1); + ret = hv_deposit_memory(hv_current_partition_id, status); } while (!ret); return ret; } -static int hv_call_map_stats_page(enum hv_stats_object_type type, - const union hv_stats_object_identity *identity, - void **addr) +static int +hv_stats_get_area_type(enum hv_stats_object_type type, + const union hv_stats_object_identity *identity) +{ + switch (type) { + case HV_STATS_OBJECT_HYPERVISOR: + return identity->hv.stats_area_type; + case HV_STATS_OBJECT_LOGICAL_PROCESSOR: + return identity->lp.stats_area_type; + case HV_STATS_OBJECT_PARTITION: + return identity->partition.stats_area_type; + case HV_STATS_OBJECT_VP: + return identity->vp.stats_area_type; + } + + return -EINVAL; +} + +/* + * Map a stats page, where the page location is provided by the hypervisor. + * + * NOTE: The concept of separate SELF and PARENT stats areas does not exist on + * older hypervisor versions. All the available stats information can be found + * on the SELF page. When attempting to map the PARENT area on a hypervisor + * that doesn't support it, return "success" but with a NULL address. The + * caller should check for this case and instead fallback to the SELF area + * alone. + */ +static int +hv_call_map_stats_page(enum hv_stats_object_type type, + const union hv_stats_object_identity *identity, + struct hv_stats_page **addr) { unsigned long flags; struct hv_input_map_stats_page *input; @@ -878,15 +908,22 @@ static int hv_call_map_stats_page(enum hv_stats_object_type type, pfn = output->map_location; local_irq_restore(flags); - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) { - ret = hv_result_to_errno(status); + + if (!hv_result_needs_memory(status)) { if (hv_result_success(status)) break; - return ret; + + if (hv_stats_get_area_type(type, identity) == HV_STATS_AREA_PARENT && + hv_result(status) == HV_STATUS_INVALID_PARAMETER) { + *addr = NULL; + return 0; + } + + hv_status_debug(status, "\n"); + return hv_result_to_errno(status); } - ret = hv_call_deposit_pages(NUMA_NO_NODE, - hv_current_partition_id, 1); + ret = hv_deposit_memory(hv_current_partition_id, status); if (ret) return ret; } while (!ret); @@ -898,7 +935,7 @@ static int hv_call_map_stats_page(enum hv_stats_object_type type, int hv_map_stats_page(enum hv_stats_object_type type, const union hv_stats_object_identity *identity, - void **addr) + struct hv_stats_page **addr) { int ret; struct page *allocated_page = NULL; @@ -946,7 +983,8 @@ static int hv_call_unmap_stats_page(enum hv_stats_object_type type, return hv_result_to_errno(status); } -int hv_unmap_stats_page(enum hv_stats_object_type type, void *page_addr, +int hv_unmap_stats_page(enum hv_stats_object_type type, + struct hv_stats_page *page_addr, const union hv_stats_object_identity *identity) { int ret; diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c index 681b58154d5e..82ff823ef0ca 100644 --- a/drivers/hv/mshv_root_main.c +++ b/drivers/hv/mshv_root_main.c @@ -39,22 +39,12 @@ MODULE_AUTHOR("Microsoft"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Microsoft Hyper-V root partition VMM interface /dev/mshv"); -/* TODO move this to another file when debugfs code is added */ -enum hv_stats_vp_counters { /* HV_THREAD_COUNTER */ -#if defined(CONFIG_X86) - VpRootDispatchThreadBlocked = 202, +/* HV_THREAD_COUNTER */ +#if defined(CONFIG_X86_64) +#define HV_VP_COUNTER_ROOT_DISPATCH_THREAD_BLOCKED 202 #elif defined(CONFIG_ARM64) - VpRootDispatchThreadBlocked = 94, +#define HV_VP_COUNTER_ROOT_DISPATCH_THREAD_BLOCKED 95 #endif - VpStatsMaxCounter -}; - -struct hv_stats_page { - union { - u64 vp_cntrs[VpStatsMaxCounter]; /* VP counters */ - u8 data[HV_HYP_PAGE_SIZE]; - }; -} __packed; struct mshv_root mshv_root; @@ -130,6 +120,7 @@ static u16 mshv_passthru_hvcalls[] = { HVCALL_SET_VP_REGISTERS, HVCALL_TRANSLATE_VIRTUAL_ADDRESS, HVCALL_CLEAR_VIRTUAL_INTERRUPT, + HVCALL_SCRUB_PARTITION, HVCALL_REGISTER_INTERCEPT_RESULT, HVCALL_ASSERT_VIRTUAL_INTERRUPT, HVCALL_GET_GPA_PAGES_ACCESS_STATES, @@ -261,11 +252,10 @@ static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, if (hv_result_success(status)) break; - if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) + if (!hv_result_needs_memory(status)) ret = hv_result_to_errno(status); else - ret = hv_call_deposit_pages(NUMA_NO_NODE, - pt_id, 1); + ret = hv_deposit_memory(pt_id, status); } while (!ret); args.status = hv_result(status); @@ -485,12 +475,11 @@ static u64 mshv_vp_interrupt_pending(struct mshv_vp *vp) static bool mshv_vp_dispatch_thread_blocked(struct mshv_vp *vp) { struct hv_stats_page **stats = vp->vp_stats_pages; - u64 *self_vp_cntrs = stats[HV_STATS_AREA_SELF]->vp_cntrs; - u64 *parent_vp_cntrs = stats[HV_STATS_AREA_PARENT]->vp_cntrs; + u64 *self_vp_cntrs = stats[HV_STATS_AREA_SELF]->data; + u64 *parent_vp_cntrs = stats[HV_STATS_AREA_PARENT]->data; - if (self_vp_cntrs[VpRootDispatchThreadBlocked]) - return self_vp_cntrs[VpRootDispatchThreadBlocked]; - return parent_vp_cntrs[VpRootDispatchThreadBlocked]; + return parent_vp_cntrs[HV_VP_COUNTER_ROOT_DISPATCH_THREAD_BLOCKED] || + self_vp_cntrs[HV_VP_COUNTER_ROOT_DISPATCH_THREAD_BLOCKED]; } static int @@ -661,7 +650,7 @@ static bool mshv_handle_gpa_intercept(struct mshv_vp *vp) return false; /* Only movable memory ranges are supported for GPA intercepts */ - if (region->type == MSHV_REGION_TYPE_MEM_MOVABLE) + if (region->mreg_type == MSHV_REGION_TYPE_MEM_MOVABLE) ret = mshv_region_handle_gfn_fault(region, gfn); else ret = false; @@ -724,7 +713,7 @@ mshv_vp_ioctl_get_set_state_pfn(struct mshv_vp *vp, return -EOVERFLOW; /* Pin user pages so hypervisor can copy directly to them */ - pages = kcalloc(page_count, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, page_count); if (!pages) return -ENOMEM; @@ -957,23 +946,36 @@ mshv_vp_release(struct inode *inode, struct file *filp) return 0; } -static void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, - void *stats_pages[]) +void mshv_vp_stats_unmap(u64 partition_id, u32 vp_index, + struct hv_stats_page *stats_pages[]) { union hv_stats_object_identity identity = { .vp.partition_id = partition_id, .vp.vp_index = vp_index, }; + int err; identity.vp.stats_area_type = HV_STATS_AREA_SELF; - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); + err = hv_unmap_stats_page(HV_STATS_OBJECT_VP, + stats_pages[HV_STATS_AREA_SELF], + &identity); + if (err) + pr_err("%s: failed to unmap partition %llu vp %u self stats, err: %d\n", + __func__, partition_id, vp_index, err); - identity.vp.stats_area_type = HV_STATS_AREA_PARENT; - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); + if (stats_pages[HV_STATS_AREA_PARENT] != stats_pages[HV_STATS_AREA_SELF]) { + identity.vp.stats_area_type = HV_STATS_AREA_PARENT; + err = hv_unmap_stats_page(HV_STATS_OBJECT_VP, + stats_pages[HV_STATS_AREA_PARENT], + &identity); + if (err) + pr_err("%s: failed to unmap partition %llu vp %u parent stats, err: %d\n", + __func__, partition_id, vp_index, err); + } } -static int mshv_vp_stats_map(u64 partition_id, u32 vp_index, - void *stats_pages[]) +int mshv_vp_stats_map(u64 partition_id, u32 vp_index, + struct hv_stats_page *stats_pages[]) { union hv_stats_object_identity identity = { .vp.partition_id = partition_id, @@ -984,20 +986,37 @@ static int mshv_vp_stats_map(u64 partition_id, u32 vp_index, identity.vp.stats_area_type = HV_STATS_AREA_SELF; err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, &stats_pages[HV_STATS_AREA_SELF]); - if (err) + if (err) { + pr_err("%s: failed to map partition %llu vp %u self stats, err: %d\n", + __func__, partition_id, vp_index, err); return err; + } - identity.vp.stats_area_type = HV_STATS_AREA_PARENT; - err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, - &stats_pages[HV_STATS_AREA_PARENT]); - if (err) - goto unmap_self; + /* + * L1VH partition cannot access its vp stats in parent area. + */ + if (is_l1vh_parent(partition_id)) { + stats_pages[HV_STATS_AREA_PARENT] = stats_pages[HV_STATS_AREA_SELF]; + } else { + identity.vp.stats_area_type = HV_STATS_AREA_PARENT; + err = hv_map_stats_page(HV_STATS_OBJECT_VP, &identity, + &stats_pages[HV_STATS_AREA_PARENT]); + if (err) { + pr_err("%s: failed to map partition %llu vp %u parent stats, err: %d\n", + __func__, partition_id, vp_index, err); + goto unmap_self; + } + if (!stats_pages[HV_STATS_AREA_PARENT]) + stats_pages[HV_STATS_AREA_PARENT] = stats_pages[HV_STATS_AREA_SELF]; + } return 0; unmap_self: identity.vp.stats_area_type = HV_STATS_AREA_SELF; - hv_unmap_stats_page(HV_STATS_OBJECT_VP, NULL, &identity); + hv_unmap_stats_page(HV_STATS_OBJECT_VP, + stats_pages[HV_STATS_AREA_SELF], + &identity); return err; } @@ -1008,7 +1027,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition, struct mshv_create_vp args; struct mshv_vp *vp; struct page *intercept_msg_page, *register_page, *ghcb_page; - void *stats_pages[2]; + struct hv_stats_page *stats_pages[2]; long ret; if (copy_from_user(&args, arg, sizeof(args))) @@ -1048,18 +1067,12 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition, goto unmap_register_page; } - /* - * This mapping of the stats page is for detecting if dispatch thread - * is blocked - only relevant for root scheduler - */ - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) { - ret = mshv_vp_stats_map(partition->pt_id, args.vp_index, - stats_pages); - if (ret) - goto unmap_ghcb_page; - } + ret = mshv_vp_stats_map(partition->pt_id, args.vp_index, + stats_pages); + if (ret) + goto unmap_ghcb_page; - vp = kzalloc(sizeof(*vp), GFP_KERNEL); + vp = kzalloc_obj(*vp); if (!vp) goto unmap_stats_pages; @@ -1081,8 +1094,11 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition, if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) vp->vp_ghcb_page = page_to_virt(ghcb_page); - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) - memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages)); + memcpy(vp->vp_stats_pages, stats_pages, sizeof(stats_pages)); + + ret = mshv_debugfs_vp_create(vp); + if (ret) + goto put_partition; /* * Keep anon_inode_getfd last: it installs fd in the file struct and @@ -1091,7 +1107,7 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition, ret = anon_inode_getfd("mshv_vp", &mshv_vp_fops, vp, O_RDWR | O_CLOEXEC); if (ret < 0) - goto put_partition; + goto remove_debugfs_vp; /* already exclusive with the partition mutex for all ioctls */ partition->pt_vp_count++; @@ -1099,13 +1115,14 @@ mshv_partition_ioctl_create_vp(struct mshv_partition *partition, return ret; +remove_debugfs_vp: + mshv_debugfs_vp_remove(vp); put_partition: mshv_partition_put(partition); free_vp: kfree(vp); unmap_stats_pages: - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) - mshv_vp_stats_unmap(partition->pt_id, args.vp_index, stats_pages); + mshv_vp_stats_unmap(partition->pt_id, args.vp_index, stats_pages); unmap_ghcb_page: if (mshv_partition_encrypted(partition) && is_ghcb_mapping_available()) hv_unmap_vp_state_page(partition->pt_id, args.vp_index, @@ -1176,12 +1193,12 @@ static int mshv_partition_create_region(struct mshv_partition *partition, return PTR_ERR(rg); if (is_mmio) - rg->type = MSHV_REGION_TYPE_MMIO; + rg->mreg_type = MSHV_REGION_TYPE_MMIO; else if (mshv_partition_encrypted(partition) || !mshv_region_movable_init(rg)) - rg->type = MSHV_REGION_TYPE_MEM_PINNED; + rg->mreg_type = MSHV_REGION_TYPE_MEM_PINNED; else - rg->type = MSHV_REGION_TYPE_MEM_MOVABLE; + rg->mreg_type = MSHV_REGION_TYPE_MEM_MOVABLE; rg->partition = partition; @@ -1298,7 +1315,7 @@ mshv_map_user_memory(struct mshv_partition *partition, if (ret) return ret; - switch (region->type) { + switch (region->mreg_type) { case MSHV_REGION_TYPE_MEM_PINNED: ret = mshv_prepare_pinned_region(region); break; @@ -1542,10 +1559,16 @@ mshv_partition_ioctl_initialize(struct mshv_partition *partition) if (ret) goto withdraw_mem; + ret = mshv_debugfs_partition_create(partition); + if (ret) + goto finalize_partition; + partition->pt_initialized = true; return 0; +finalize_partition: + hv_call_finalize_partition(partition->pt_id); withdraw_mem: hv_call_withdraw_memory(U64_MAX, NUMA_NO_NODE, partition->pt_id); @@ -1725,9 +1748,9 @@ static void destroy_partition(struct mshv_partition *partition) if (!vp) continue; - if (hv_scheduler_type == HV_SCHEDULER_TYPE_ROOT) - mshv_vp_stats_unmap(partition->pt_id, vp->vp_index, - (void **)vp->vp_stats_pages); + mshv_debugfs_vp_remove(vp); + mshv_vp_stats_unmap(partition->pt_id, vp->vp_index, + vp->vp_stats_pages); if (vp->vp_register_page) { (void)hv_unmap_vp_state_page(partition->pt_id, @@ -1759,6 +1782,8 @@ static void destroy_partition(struct mshv_partition *partition) partition->pt_vp_array[i] = NULL; } + mshv_debugfs_partition_remove(partition); + /* Deallocates and unmaps everything including vcpus, GPA mappings etc */ hv_call_finalize_partition(partition->pt_id); @@ -1921,6 +1946,10 @@ static long mshv_ioctl_process_pt_flags(void __user *user_arg, u64 *pt_flags, *pt_flags |= HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE; if (args.pt_flags & BIT_ULL(MSHV_PT_BIT_GPA_SUPER_PAGES)) *pt_flags |= HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED; + if (args.pt_flags & BIT(MSHV_PT_BIT_NESTED_VIRTUALIZATION)) + *pt_flags |= HV_PARTITION_CREATION_FLAG_NESTED_VIRTUALIZATION_CAPABLE; + if (args.pt_flags & BIT(MSHV_PT_BIT_SMT_ENABLED_GUEST)) + *pt_flags |= HV_PARTITION_CREATION_FLAG_SMT_ENABLED_GUEST; isol_props->as_uint64 = 0; @@ -1948,7 +1977,7 @@ mshv_ioctl_create_partition(void __user *user_arg, struct device *module_dev) if (ret) return ret; - partition = kzalloc(sizeof(*partition), GFP_KERNEL); + partition = kzalloc_obj(*partition); if (!partition) return -ENOMEM; @@ -2054,6 +2083,29 @@ static const char *scheduler_type_to_string(enum hv_scheduler_type type) }; } +static int __init l1vh_retrieve_scheduler_type(enum hv_scheduler_type *out) +{ + u64 integrated_sched_enabled; + int ret; + + *out = HV_SCHEDULER_TYPE_CORE_SMT; + + if (!mshv_root.vmm_caps.vmm_enable_integrated_scheduler) + return 0; + + ret = hv_call_get_partition_property_ex(HV_PARTITION_ID_SELF, + HV_PARTITION_PROPERTY_INTEGRATED_SCHEDULER_ENABLED, + 0, &integrated_sched_enabled, + sizeof(integrated_sched_enabled)); + if (ret) + return ret; + + if (integrated_sched_enabled) + *out = HV_SCHEDULER_TYPE_ROOT; + + return 0; +} + /* TODO move this to hv_common.c when needed outside */ static int __init hv_retrieve_scheduler_type(enum hv_scheduler_type *out) { @@ -2086,13 +2138,12 @@ static int __init hv_retrieve_scheduler_type(enum hv_scheduler_type *out) /* Retrieve and stash the supported scheduler type */ static int __init mshv_retrieve_scheduler_type(struct device *dev) { - int ret = 0; + int ret; if (hv_l1vh_partition()) - hv_scheduler_type = HV_SCHEDULER_TYPE_CORE_SMT; + ret = l1vh_retrieve_scheduler_type(&hv_scheduler_type); else ret = hv_retrieve_scheduler_type(&hv_scheduler_type); - if (ret) return ret; @@ -2212,42 +2263,29 @@ struct notifier_block mshv_reboot_nb = { static void mshv_root_partition_exit(void) { unregister_reboot_notifier(&mshv_reboot_nb); - root_scheduler_deinit(); } static int __init mshv_root_partition_init(struct device *dev) { - int err; - - err = root_scheduler_init(dev); - if (err) - return err; - - err = register_reboot_notifier(&mshv_reboot_nb); - if (err) - goto root_sched_deinit; - - return 0; - -root_sched_deinit: - root_scheduler_deinit(); - return err; + return register_reboot_notifier(&mshv_reboot_nb); } -static void mshv_init_vmm_caps(struct device *dev) +static int __init mshv_init_vmm_caps(struct device *dev) { - /* - * This can only fail here if HVCALL_GET_PARTITION_PROPERTY_EX or - * HV_PARTITION_PROPERTY_VMM_CAPABILITIES are not supported. In that - * case it's valid to proceed as if all vmm_caps are disabled (zero). - */ - if (hv_call_get_partition_property_ex(HV_PARTITION_ID_SELF, - HV_PARTITION_PROPERTY_VMM_CAPABILITIES, - 0, &mshv_root.vmm_caps, - sizeof(mshv_root.vmm_caps))) - dev_warn(dev, "Unable to get VMM capabilities\n"); + int ret; + + ret = hv_call_get_partition_property_ex(HV_PARTITION_ID_SELF, + HV_PARTITION_PROPERTY_VMM_CAPABILITIES, + 0, &mshv_root.vmm_caps, + sizeof(mshv_root.vmm_caps)); + if (ret && hv_l1vh_partition()) { + dev_err(dev, "Failed to get VMM capabilities: %d\n", ret); + return ret; + } dev_dbg(dev, "vmm_caps = %#llx\n", mshv_root.vmm_caps.as_uint64[0]); + + return 0; } static int __init mshv_parent_partition_init(void) @@ -2293,6 +2331,10 @@ static int __init mshv_parent_partition_init(void) mshv_cpuhp_online = ret; + ret = mshv_init_vmm_caps(dev); + if (ret) + goto remove_cpu_state; + ret = mshv_retrieve_scheduler_type(dev); if (ret) goto remove_cpu_state; @@ -2302,11 +2344,17 @@ static int __init mshv_parent_partition_init(void) if (ret) goto remove_cpu_state; - mshv_init_vmm_caps(dev); + ret = root_scheduler_init(dev); + if (ret) + goto exit_partition; + + ret = mshv_debugfs_init(); + if (ret) + goto deinit_root_scheduler; ret = mshv_irqfd_wq_init(); if (ret) - goto exit_partition; + goto exit_debugfs; spin_lock_init(&mshv_root.pt_ht_lock); hash_init(mshv_root.pt_htable); @@ -2315,6 +2363,10 @@ static int __init mshv_parent_partition_init(void) return 0; +exit_debugfs: + mshv_debugfs_exit(); +deinit_root_scheduler: + root_scheduler_deinit(); exit_partition: if (hv_root_partition()) mshv_root_partition_exit(); @@ -2331,8 +2383,10 @@ static void __exit mshv_parent_partition_exit(void) { hv_setup_mshv_handler(NULL); mshv_port_table_fini(); + mshv_debugfs_exit(); misc_deregister(&mshv_dev); mshv_irqfd_wq_cleanup(); + root_scheduler_deinit(); if (hv_root_partition()) mshv_root_partition_exit(); cpuhp_remove_state(mshv_cpuhp_online); diff --git a/drivers/hv/mshv_synic.c b/drivers/hv/mshv_synic.c index f8b0337cdc82..216065e21d28 100644 --- a/drivers/hv/mshv_synic.c +++ b/drivers/hv/mshv_synic.c @@ -605,7 +605,7 @@ mshv_register_doorbell(u64 partition_id, doorbell_cb_t doorbell_cb, void *data, union hv_port_id port_id = { 0 }; int ret; - port_table_info = kmalloc(sizeof(*port_table_info), GFP_KERNEL); + port_table_info = kmalloc_obj(*port_table_info); if (!port_table_info) return -ENOMEM; diff --git a/drivers/hv/mshv_vtl_main.c b/drivers/hv/mshv_vtl_main.c index 2cebe9de5a5a..5856975f32e1 100644 --- a/drivers/hv/mshv_vtl_main.c +++ b/drivers/hv/mshv_vtl_main.c @@ -117,7 +117,7 @@ mshv_ioctl_create_vtl(void __user *user_arg, struct device *module_dev) struct file *file; int fd; - vtl = kzalloc(sizeof(*vtl), GFP_KERNEL); + vtl = kzalloc_obj(*vtl); if (!vtl) return -ENOMEM; @@ -393,7 +393,7 @@ static int mshv_vtl_ioctl_add_vtl0_mem(struct mshv_vtl *vtl, void __user *arg) return -EFAULT; } - pgmap = kzalloc(sizeof(*pgmap), GFP_KERNEL); + pgmap = kzalloc_obj(*pgmap); if (!pgmap) return -ENOMEM; @@ -845,9 +845,10 @@ static const struct file_operations mshv_vtl_fops = { .mmap = mshv_vtl_mmap, }; -static void mshv_vtl_synic_mask_vmbus_sint(const u8 *mask) +static void mshv_vtl_synic_mask_vmbus_sint(void *info) { union hv_synic_sint sint; + const u8 *mask = info; sint.as_uint64 = 0; sint.vector = HYPERVISOR_CALLBACK_VECTOR; @@ -999,7 +1000,7 @@ static int mshv_vtl_sint_ioctl_pause_msg_stream(struct mshv_sint_mask __user *ar if (copy_from_user(&mask, arg, sizeof(mask))) return -EFAULT; guard(mutex)(&vtl2_vmbus_sint_mask_mutex); - on_each_cpu((smp_call_func_t)mshv_vtl_synic_mask_vmbus_sint, &mask.mask, 1); + on_each_cpu(mshv_vtl_synic_mask_vmbus_sint, &mask.mask, 1); WRITE_ONCE(vtl_synic_mask_vmbus_sint_masked, mask.mask != 0); if (mask.mask) wake_up_interruptible_poll(&fd_wait_queue, EPOLLIN); @@ -1343,7 +1344,7 @@ static int __init mshv_vtl_init(void) /* * "mshv vtl mem dev" device is later used to setup VTL0 memory. */ - mem_dev = kzalloc(sizeof(*mem_dev), GFP_KERNEL); + mem_dev = kzalloc_obj(*mem_dev); if (!mem_dev) { ret = -ENOMEM; goto free_low; diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c index 3c421a7f78c0..592a9601faaa 100644 --- a/drivers/hv/ring_buffer.c +++ b/drivers/hv/ring_buffer.c @@ -196,9 +196,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, * First page holds struct hv_ring_buffer, do wraparound mapping for * the rest. */ - pages_wraparound = kcalloc(page_cnt * 2 - 1, - sizeof(struct page *), - GFP_KERNEL); + pages_wraparound = kzalloc_objs(struct page *, page_cnt * 2 - 1); if (!pages_wraparound) return -ENOMEM; diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c index 9c937190be81..bc4fc1951ae1 100644 --- a/drivers/hv/vmbus_drv.c +++ b/drivers/hv/vmbus_drv.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -51,7 +52,7 @@ static struct device *vmbus_root_device; static int hyperv_cpuhp_online; -static long __percpu *vmbus_evt; +static DEFINE_PER_CPU(long, vmbus_evt); /* Values parsed from ACPI DSDT */ int vmbus_irq; @@ -755,7 +756,7 @@ static int vmbus_add_dynid(struct hv_driver *drv, guid_t *guid) { struct vmbus_dynid *dynid; - dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); + dynid = kzalloc_obj(*dynid); if (!dynid) return -ENOMEM; @@ -1119,7 +1120,7 @@ static void __vmbus_on_msg_dpc(void *message_page_addr) } if (entry->handler_type == VMHT_BLOCKING) { - ctx = kmalloc(struct_size(ctx, msg.payload, payload_size), GFP_ATOMIC); + ctx = kmalloc_flex(*ctx, msg.payload, payload_size, GFP_ATOMIC); if (ctx == NULL) return; @@ -1350,7 +1351,7 @@ static void vmbus_message_sched(struct hv_per_cpu_context *hv_cpu, void *message } } -void vmbus_isr(void) +static void __vmbus_isr(void) { struct hv_per_cpu_context *hv_cpu = this_cpu_ptr(hv_context.cpu_context); @@ -1363,6 +1364,53 @@ void vmbus_isr(void) add_interrupt_randomness(vmbus_interrupt); } + +static DEFINE_PER_CPU(bool, vmbus_irq_pending); +static DEFINE_PER_CPU(struct task_struct *, vmbus_irqd); + +static void vmbus_irqd_wake(void) +{ + struct task_struct *tsk = __this_cpu_read(vmbus_irqd); + + __this_cpu_write(vmbus_irq_pending, true); + wake_up_process(tsk); +} + +static void vmbus_irqd_setup(unsigned int cpu) +{ + sched_set_fifo(current); +} + +static int vmbus_irqd_should_run(unsigned int cpu) +{ + return __this_cpu_read(vmbus_irq_pending); +} + +static void run_vmbus_irqd(unsigned int cpu) +{ + __this_cpu_write(vmbus_irq_pending, false); + __vmbus_isr(); +} + +static bool vmbus_irq_initialized; + +static struct smp_hotplug_thread vmbus_irq_threads = { + .store = &vmbus_irqd, + .setup = vmbus_irqd_setup, + .thread_should_run = vmbus_irqd_should_run, + .thread_fn = run_vmbus_irqd, + .thread_comm = "vmbus_irq/%u", +}; + +void vmbus_isr(void) +{ + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + vmbus_irqd_wake(); + } else { + lockdep_hardirq_threaded(); + __vmbus_isr(); + } +} EXPORT_SYMBOL_FOR_MODULES(vmbus_isr, "mshv_vtl"); static irqreturn_t vmbus_percpu_isr(int irq, void *dev_id) @@ -1462,16 +1510,21 @@ static int vmbus_bus_init(void) * the VMbus interrupt handler. */ + if (IS_ENABLED(CONFIG_PREEMPT_RT) && !vmbus_irq_initialized) { + ret = smpboot_register_percpu_thread(&vmbus_irq_threads); + if (ret) + goto err_kthread; + vmbus_irq_initialized = true; + } + if (vmbus_irq == -1) { hv_setup_vmbus_handler(vmbus_isr); } else { - vmbus_evt = alloc_percpu(long); ret = request_percpu_irq(vmbus_irq, vmbus_percpu_isr, - "Hyper-V VMbus", vmbus_evt); + "Hyper-V VMbus", &vmbus_evt); if (ret) { pr_err("Can't request Hyper-V VMbus IRQ %d, Err %d", vmbus_irq, ret); - free_percpu(vmbus_evt); goto err_setup; } } @@ -1500,13 +1553,16 @@ static int vmbus_bus_init(void) return 0; err_connect: - if (vmbus_irq == -1) { + if (vmbus_irq == -1) hv_remove_vmbus_handler(); - } else { - free_percpu_irq(vmbus_irq, vmbus_evt); - free_percpu(vmbus_evt); - } + else + free_percpu_irq(vmbus_irq, &vmbus_evt); err_setup: + if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { + smpboot_unregister_percpu_thread(&vmbus_irq_threads); + vmbus_irq_initialized = false; + } +err_kthread: bus_unregister(&hv_bus); return ret; } @@ -2100,7 +2156,7 @@ struct hv_device *vmbus_device_create(const guid_t *type, { struct hv_device *child_device_obj; - child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL); + child_device_obj = kzalloc_obj(struct hv_device); if (!child_device_obj) { pr_err("Unable to allocate device object for child device\n"); return NULL; @@ -2262,7 +2318,7 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx) if (end < 0x100000) return AE_OK; - new_res = kzalloc(sizeof(*new_res), GFP_ATOMIC); + new_res = kzalloc_obj(*new_res, GFP_ATOMIC); if (!new_res) return AE_NO_MEMORY; @@ -2356,8 +2412,8 @@ static void __maybe_unused vmbus_reserve_fb(void) } /* - * Release the PCI device so hyperv_drm or hyperv_fb driver can - * grab it later. + * Release the PCI device so hyperv_drm driver can grab it + * later. */ pci_dev_put(pdev); } @@ -2616,7 +2672,7 @@ static int vmbus_device_add(struct platform_device *pdev) for_each_of_range(&parser, &range) { struct resource *res; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) { vmbus_mmio_remove(); return -ENOMEM; @@ -2970,11 +3026,13 @@ static void __exit vmbus_exit(void) vmbus_connection.conn_state = DISCONNECTED; hv_stimer_global_cleanup(); vmbus_disconnect(); - if (vmbus_irq == -1) { + if (vmbus_irq == -1) hv_remove_vmbus_handler(); - } else { - free_percpu_irq(vmbus_irq, vmbus_evt); - free_percpu(vmbus_evt); + else + free_percpu_irq(vmbus_irq, &vmbus_evt); + if (IS_ENABLED(CONFIG_PREEMPT_RT) && vmbus_irq_initialized) { + smpboot_unregister_percpu_thread(&vmbus_irq_threads); + vmbus_irq_initialized = false; } for_each_online_cpu(cpu) { struct hv_per_cpu_context *hv_cpu diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 41c381764c2b..328867242cb3 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1493,8 +1493,7 @@ config SENSORS_LM73 config SENSORS_LM75 tristate "National Semiconductor LM75 and compatibles" - depends on I2C - depends on I3C || !I3C + depends on I3C_OR_I2C select REGMAP_I2C select REGMAP_I3C if I3C help @@ -1927,16 +1926,6 @@ config SENSORS_RASPBERRYPI_HWMON This driver can also be built as a module. If so, the module will be called raspberrypi-hwmon. -config SENSORS_SA67MCU - tristate "Kontron sa67mcu hardware monitoring driver" - depends on MFD_SL28CPLD || COMPILE_TEST - help - If you say yes here you get support for the voltage and temperature - monitor of the sa67 board management controller. - - This driver can also be built as a module. If so, the module - will be called sa67mcu-hwmon. - config SENSORS_SL28CPLD tristate "Kontron sl28cpld hardware monitoring driver" depends on MFD_SL28CPLD || COMPILE_TEST @@ -2392,8 +2381,7 @@ config SENSORS_TMP103 config SENSORS_TMP108 tristate "Texas Instruments TMP108" - depends on I2C - depends on I3C || !I3C + depends on I3C_OR_I2C select REGMAP_I2C select REGMAP_I3C if I3C help diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index eade8e3b1bde..5833c807c688 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -199,7 +199,6 @@ obj-$(CONFIG_SENSORS_PT5161L) += pt5161l.o obj-$(CONFIG_SENSORS_PWM_FAN) += pwm-fan.o obj-$(CONFIG_SENSORS_QNAP_MCU_HWMON) += qnap-mcu-hwmon.o obj-$(CONFIG_SENSORS_RASPBERRYPI_HWMON) += raspberrypi-hwmon.o -obj-$(CONFIG_SENSORS_SA67MCU) += sa67mcu-hwmon.o obj-$(CONFIG_SENSORS_SBTSI) += sbtsi_temp.o obj-$(CONFIG_SENSORS_SBRMI) += sbrmi.o obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 7cb66216f358..1e3fab5f7946 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c @@ -245,9 +245,8 @@ static int read_domain_devices(struct acpi_power_meter_resource *resource) if (!pss->package.count) goto end; - resource->domain_devices = kcalloc(pss->package.count, - sizeof(struct acpi_device *), - GFP_KERNEL); + resource->domain_devices = kzalloc_objs(struct acpi_device *, + pss->package.count); if (!resource->domain_devices) { res = -ENOMEM; goto end; @@ -893,7 +892,7 @@ static int acpi_power_meter_add(struct acpi_device *device) if (!device) return -EINVAL; - resource = kzalloc(sizeof(*resource), GFP_KERNEL); + resource = kzalloc_obj(*resource); if (!resource) return -ENOMEM; diff --git a/drivers/hwmon/aht10.c b/drivers/hwmon/aht10.c index 007befdba977..4ce019d2cc80 100644 --- a/drivers/hwmon/aht10.c +++ b/drivers/hwmon/aht10.c @@ -37,7 +37,9 @@ #define AHT10_CMD_MEAS 0b10101100 #define AHT10_CMD_RST 0b10111010 -#define DHT20_CMD_INIT 0x71 +#define AHT20_CMD_INIT 0b10111110 + +#define DHT20_CMD_INIT 0b01110001 /* * Flags in the answer byte/command @@ -341,7 +343,7 @@ static int aht10_probe(struct i2c_client *client) data->meas_size = AHT20_MEAS_SIZE; data->crc8 = true; crc8_populate_msb(crc8_table, AHT20_CRC8_POLY); - data->init_cmd = AHT10_CMD_INIT; + data->init_cmd = AHT20_CMD_INIT; break; case dht20: data->meas_size = AHT20_MEAS_SIZE; diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index fc6d6a9053ce..24f3e86d0ebf 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c @@ -586,7 +586,7 @@ static int applesmc_init_smcreg_try(void) s->key_count = count; if (!s->cache) - s->cache = kcalloc(s->key_count, sizeof(*s->cache), GFP_KERNEL); + s->cache = kzalloc_objs(*s->cache, s->key_count); if (!s->cache) return -ENOMEM; @@ -1141,7 +1141,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) int ret, i; for (grp = groups; grp->format; grp++) { - grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL); + grp->nodes = kzalloc_objs(*node, num + 1); if (!grp->nodes) { ret = -ENOMEM; goto out; diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index d2dfa4e30407..6a0d94711ead 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -492,13 +492,13 @@ init_temp_data(struct platform_data *pdata, unsigned int cpu, int pkg_flag) * when this information becomes available. */ pdata->nr_cores = NUM_REAL_CORES; - pdata->core_data = kcalloc(pdata->nr_cores, sizeof(struct temp_data *), - GFP_KERNEL); + pdata->core_data = kzalloc_objs(struct temp_data *, + pdata->nr_cores); if (!pdata->core_data) return NULL; } - tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL); + tdata = kzalloc_obj(struct temp_data); if (!tdata) return NULL; @@ -625,7 +625,7 @@ static int coretemp_device_add(int zoneid) int err; /* Initialize the per-zone data structures */ - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return -ENOMEM; @@ -804,8 +804,7 @@ static int __init coretemp_init(void) return -ENODEV; max_zones = topology_max_packages() * topology_max_dies_per_package(); - zone_devices = kcalloc(max_zones, sizeof(struct platform_device *), - GFP_KERNEL); + zone_devices = kzalloc_objs(struct platform_device *, max_zones); if (!zone_devices) return -ENOMEM; diff --git a/drivers/hwmon/drivetemp.c b/drivers/hwmon/drivetemp.c index 9c5b021aab86..002e0660a0b8 100644 --- a/drivers/hwmon/drivetemp.c +++ b/drivers/hwmon/drivetemp.c @@ -556,7 +556,7 @@ static int drivetemp_add(struct device *dev) struct drivetemp_data *st; int err; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) return -ENOMEM; diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c index a303959879ef..1211fa2259e5 100644 --- a/drivers/hwmon/fschmd.c +++ b/drivers/hwmon/fschmd.c @@ -1088,7 +1088,7 @@ static int fschmd_probe(struct i2c_client *client) int i, err; enum chips kind = (uintptr_t)i2c_get_match_data(client); - data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL); + data = kzalloc_obj(struct fschmd_data); if (!data) return -ENOMEM; diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c index 714caa6a36a3..9695dca62a7e 100644 --- a/drivers/hwmon/hwmon.c +++ b/drivers/hwmon/hwmon.c @@ -533,7 +533,7 @@ static struct attribute *hwmon_genattr(const void *drvdata, if ((mode & 0222) && !ops->write) return ERR_PTR(-EINVAL); - hattr = kzalloc(sizeof(*hattr), GFP_KERNEL); + hattr = kzalloc_obj(*hattr); if (!hattr) return ERR_PTR(-ENOMEM); @@ -879,7 +879,7 @@ __hwmon_create_attrs(const void *drvdata, const struct hwmon_chip_info *chip) if (nattrs == 0) return ERR_PTR(-EINVAL); - attrs = kcalloc(nattrs + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, nattrs + 1); if (!attrs) return ERR_PTR(-ENOMEM); @@ -917,7 +917,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, if (id < 0) return ERR_PTR(id); - hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL); + hwdev = kzalloc_obj(*hwdev); if (hwdev == NULL) { err = -ENOMEM; goto ida_remove; @@ -933,7 +933,7 @@ __hwmon_device_register(struct device *dev, const char *name, void *drvdata, for (i = 0; groups[i]; i++) ngroups++; - hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL); + hwdev->groups = kzalloc_objs(*groups, ngroups); if (!hwdev->groups) { err = -ENOMEM; goto free_hwmon; diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index b22e0423e324..de486e69e6b8 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -494,7 +494,7 @@ static int i5k_amb_probe(struct platform_device *pdev) struct resource *reso; int i, res; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c index daed437d34a4..0a9c3a29e6f2 100644 --- a/drivers/hwmon/ibmaem.c +++ b/drivers/hwmon/ibmaem.c @@ -517,7 +517,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) int i; int res = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return res; mutex_init(&data->lock); @@ -657,7 +657,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, int i; int res = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return res; mutex_init(&data->lock); diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index 228c5f6c6f38..dec730798d58 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c @@ -367,8 +367,7 @@ static int ibmpex_find_sensors(struct ibmpex_bmc_data *data) return -ENOENT; data->num_sensors = err; - data->sensors = kcalloc(data->num_sensors, sizeof(*data->sensors), - GFP_KERNEL); + data->sensors = kzalloc_objs(*data->sensors, data->num_sensors); if (!data->sensors) return -ENOMEM; @@ -438,7 +437,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev) struct ibmpex_bmc_data *data; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return; diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index e233aafa8856..5cfb98a0512f 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -3590,10 +3590,13 @@ static int it87_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct it87_data *data = dev_get_drvdata(dev); + int err; it87_resume_sio(pdev); - it87_lock(data); + err = it87_lock(data); + if (err) + return err; it87_check_pwm(dev); it87_check_limit_regs(data); diff --git a/drivers/hwmon/macsmc-hwmon.c b/drivers/hwmon/macsmc-hwmon.c index 1c0bbec7e8eb..1500ec2cc9f8 100644 --- a/drivers/hwmon/macsmc-hwmon.c +++ b/drivers/hwmon/macsmc-hwmon.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -130,7 +131,7 @@ static int macsmc_hwmon_read_ioft_scaled(struct apple_smc *smc, smc_key key, if (ret < 0) return ret; - *p = mult_frac(val, scale, 65536); + *p = mul_u64_u32_div(val, scale, 65536); return 0; } @@ -140,7 +141,7 @@ static int macsmc_hwmon_read_ioft_scaled(struct apple_smc *smc, smc_key key, * them. */ static int macsmc_hwmon_read_f32_scaled(struct apple_smc *smc, smc_key key, - int *p, int scale) + long *p, int scale) { u32 fval; u64 val; @@ -162,21 +163,21 @@ static int macsmc_hwmon_read_f32_scaled(struct apple_smc *smc, smc_key key, val = 0; else if (exp < 0) val >>= -exp; - else if (exp != 0 && (val & ~((1UL << (64 - exp)) - 1))) /* overflow */ + else if (exp != 0 && (val & ~((1ULL << (64 - exp)) - 1))) /* overflow */ val = U64_MAX; else val <<= exp; if (fval & FLT_SIGN_MASK) { - if (val > (-(s64)INT_MIN)) - *p = INT_MIN; + if (val > (u64)LONG_MAX + 1) + *p = LONG_MIN; else - *p = -val; + *p = -(long)val; } else { - if (val > INT_MAX) - *p = INT_MAX; + if (val > (u64)LONG_MAX) + *p = LONG_MAX; else - *p = val; + *p = (long)val; } return 0; @@ -195,7 +196,7 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, switch (sensor->info.type_code) { /* 32-bit IEEE 754 float */ case __SMC_KEY('f', 'l', 't', ' '): { - u32 flt_ = 0; + long flt_ = 0; ret = macsmc_hwmon_read_f32_scaled(smc, sensor->macsmc_key, &flt_, scale); @@ -214,7 +215,10 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, if (ret) return ret; - *val = (long)ioft; + if (ioft > LONG_MAX) + *val = LONG_MAX; + else + *val = (long)ioft; break; } default: @@ -224,29 +228,26 @@ static int macsmc_hwmon_read_key(struct apple_smc *smc, return 0; } -static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, int value) +static int macsmc_hwmon_write_f32(struct apple_smc *smc, smc_key key, long value) { u64 val; u32 fval = 0; - int exp = 0, neg; + int exp, neg; + neg = value < 0; val = abs(value); - neg = val != value; if (val) { - int msb = __fls(val) - exp; + exp = __fls(val); - if (msb > 23) { - val >>= msb - FLT_MANT_BIAS; - exp -= msb - FLT_MANT_BIAS; - } else if (msb < 23) { - val <<= FLT_MANT_BIAS - msb; - exp += msb; - } + if (exp > 23) + val >>= exp - 23; + else + val <<= 23 - exp; fval = FIELD_PREP(FLT_SIGN_MASK, neg) | FIELD_PREP(FLT_EXP_MASK, exp + FLT_EXP_BIAS) | - FIELD_PREP(FLT_MANT_MASK, val); + FIELD_PREP(FLT_MANT_MASK, val & FLT_MANT_MASK); } return apple_smc_write_u32(smc, key, fval); @@ -663,8 +664,8 @@ static int macsmc_hwmon_populate_sensors(struct macsmc_hwmon *hwmon, if (!hwmon->volt.sensors) return -ENOMEM; - for_each_child_of_node_with_prefix(hwmon_node, key_node, "volt-") { - sensor = &hwmon->temp.sensors[hwmon->temp.count]; + for_each_child_of_node_with_prefix(hwmon_node, key_node, "voltage-") { + sensor = &hwmon->volt.sensors[hwmon->volt.count]; if (!macsmc_hwmon_create_sensor(hwmon->dev, hwmon->smc, key_node, sensor)) { sensor->attrs = HWMON_I_INPUT; diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c index a0a1dbbda887..9a3c515efe2e 100644 --- a/drivers/hwmon/max6639.c +++ b/drivers/hwmon/max6639.c @@ -607,7 +607,7 @@ static int max6639_init_client(struct i2c_client *client, return err; /* Fans PWM polarity high by default */ - err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x00); + err = regmap_write(data->regmap, MAX6639_REG_FAN_CONFIG2a(i), 0x02); if (err) return err; diff --git a/drivers/hwmon/pmbus/q54sj108a2.c b/drivers/hwmon/pmbus/q54sj108a2.c index fc030ca34480..d5d60a9af8c5 100644 --- a/drivers/hwmon/pmbus/q54sj108a2.c +++ b/drivers/hwmon/pmbus/q54sj108a2.c @@ -79,7 +79,8 @@ static ssize_t q54sj108a2_debugfs_read(struct file *file, char __user *buf, int idx = *idxp; struct q54sj108a2_data *psu = to_psu(idxp, idx); char data[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; - char data_char[I2C_SMBUS_BLOCK_MAX + 2] = { 0 }; + char data_char[I2C_SMBUS_BLOCK_MAX * 2 + 2] = { 0 }; + char *out = data; char *res; switch (idx) { @@ -150,27 +151,27 @@ static ssize_t q54sj108a2_debugfs_read(struct file *file, char __user *buf, if (rc < 0) return rc; - res = bin2hex(data, data_char, 32); - rc = res - data; - + res = bin2hex(data_char, data, rc); + rc = res - data_char; + out = data_char; break; case Q54SJ108A2_DEBUGFS_FLASH_KEY: rc = i2c_smbus_read_block_data(psu->client, PMBUS_FLASH_KEY_WRITE, data); if (rc < 0) return rc; - res = bin2hex(data, data_char, 4); - rc = res - data; - + res = bin2hex(data_char, data, rc); + rc = res - data_char; + out = data_char; break; default: return -EINVAL; } - data[rc] = '\n'; + out[rc] = '\n'; rc += 2; - return simple_read_from_buffer(buf, count, ppos, data, rc); + return simple_read_from_buffer(buf, count, ppos, out, rc); } static ssize_t q54sj108a2_debugfs_write(struct file *file, const char __user *buf, diff --git a/drivers/hwmon/sa67mcu-hwmon.c b/drivers/hwmon/sa67mcu-hwmon.c deleted file mode 100644 index 22f703b7b256..000000000000 --- a/drivers/hwmon/sa67mcu-hwmon.c +++ /dev/null @@ -1,161 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * sl67mcu hardware monitoring driver - * - * Copyright 2025 Kontron Europe GmbH - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SA67MCU_VOLTAGE(n) (0x00 + ((n) * 2)) -#define SA67MCU_TEMP(n) (0x04 + ((n) * 2)) - -struct sa67mcu_hwmon { - struct regmap *regmap; - u32 offset; -}; - -static int sa67mcu_hwmon_read(struct device *dev, - enum hwmon_sensor_types type, u32 attr, - int channel, long *input) -{ - struct sa67mcu_hwmon *hwmon = dev_get_drvdata(dev); - unsigned int offset; - u8 reg[2]; - int ret; - - switch (type) { - case hwmon_in: - switch (attr) { - case hwmon_in_input: - offset = hwmon->offset + SA67MCU_VOLTAGE(channel); - break; - default: - return -EOPNOTSUPP; - } - break; - case hwmon_temp: - switch (attr) { - case hwmon_temp_input: - offset = hwmon->offset + SA67MCU_TEMP(channel); - break; - default: - return -EOPNOTSUPP; - } - break; - default: - return -EOPNOTSUPP; - } - - /* Reading the low byte will capture the value */ - ret = regmap_bulk_read(hwmon->regmap, offset, reg, ARRAY_SIZE(reg)); - if (ret) - return ret; - - *input = reg[1] << 8 | reg[0]; - - /* Temperatures are s16 and in 0.1degC steps. */ - if (type == hwmon_temp) - *input = sign_extend32(*input, 15) * 100; - - return 0; -} - -static const struct hwmon_channel_info * const sa67mcu_hwmon_info[] = { - HWMON_CHANNEL_INFO(in, - HWMON_I_INPUT | HWMON_I_LABEL, - HWMON_I_INPUT | HWMON_I_LABEL), - HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), - NULL -}; - -static const char *const sa67mcu_hwmon_in_labels[] = { - "VDDIN", - "VDD_RTC", -}; - -static int sa67mcu_hwmon_read_string(struct device *dev, - enum hwmon_sensor_types type, u32 attr, - int channel, const char **str) -{ - switch (type) { - case hwmon_in: - switch (attr) { - case hwmon_in_label: - *str = sa67mcu_hwmon_in_labels[channel]; - return 0; - default: - return -EOPNOTSUPP; - } - default: - return -EOPNOTSUPP; - } -} - -static const struct hwmon_ops sa67mcu_hwmon_ops = { - .visible = 0444, - .read = sa67mcu_hwmon_read, - .read_string = sa67mcu_hwmon_read_string, -}; - -static const struct hwmon_chip_info sa67mcu_hwmon_chip_info = { - .ops = &sa67mcu_hwmon_ops, - .info = sa67mcu_hwmon_info, -}; - -static int sa67mcu_hwmon_probe(struct platform_device *pdev) -{ - struct sa67mcu_hwmon *hwmon; - struct device *hwmon_dev; - int ret; - - if (!pdev->dev.parent) - return -ENODEV; - - hwmon = devm_kzalloc(&pdev->dev, sizeof(*hwmon), GFP_KERNEL); - if (!hwmon) - return -ENOMEM; - - hwmon->regmap = dev_get_regmap(pdev->dev.parent, NULL); - if (!hwmon->regmap) - return -ENODEV; - - ret = device_property_read_u32(&pdev->dev, "reg", &hwmon->offset); - if (ret) - return -EINVAL; - - hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, - "sa67mcu_hwmon", hwmon, - &sa67mcu_hwmon_chip_info, - NULL); - if (IS_ERR(hwmon_dev)) - dev_err(&pdev->dev, "failed to register as hwmon device"); - - return PTR_ERR_OR_ZERO(hwmon_dev); -} - -static const struct of_device_id sa67mcu_hwmon_of_match[] = { - { .compatible = "kontron,sa67mcu-hwmon", }, - {} -}; -MODULE_DEVICE_TABLE(of, sa67mcu_hwmon_of_match); - -static struct platform_driver sa67mcu_hwmon_driver = { - .probe = sa67mcu_hwmon_probe, - .driver = { - .name = "sa67mcu-hwmon", - .of_match_table = sa67mcu_hwmon_of_match, - }, -}; -module_platform_driver(sa67mcu_hwmon_driver); - -MODULE_DESCRIPTION("sa67mcu Hardware Monitoring Driver"); -MODULE_AUTHOR("Michael Walle "); -MODULE_LICENSE("GPL"); diff --git a/drivers/hwmon/sch56xx-common.c b/drivers/hwmon/sch56xx-common.c index 98e075e54e9d..a385aae3bb0f 100644 --- a/drivers/hwmon/sch56xx-common.c +++ b/drivers/hwmon/sch56xx-common.c @@ -330,7 +330,7 @@ struct regmap *devm_regmap_init_sch56xx(struct device *dev, struct mutex *lock, if (config->reg_bits != 16 && config->val_bits != 8) return ERR_PTR(-EOPNOTSUPP); - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return ERR_PTR(-ENOMEM); diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 823bff2871e1..a5c03ed59c1f 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -222,7 +222,7 @@ static int via_cputemp_online(unsigned int cpu) goto exit; } - pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL); + pdev_entry = kzalloc_obj(struct pdev_entry); if (!pdev_entry) { err = -ENOMEM; goto exit_device_put; diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index 67728f60333f..24772cfbecb3 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -1650,7 +1650,7 @@ static int w83793_probe(struct i2c_client *client) int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; int files_temp = ARRAY_SIZE(w83793_temp) / 6; - data = kzalloc(sizeof(struct w83793_data), GFP_KERNEL); + data = kzalloc_obj(struct w83793_data); if (!data) { err = -ENOMEM; goto exit; diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c index 69b36bae97ab..dfd035852b12 100644 --- a/drivers/hwtracing/coresight/coresight-catu.c +++ b/drivers/hwtracing/coresight/coresight-catu.c @@ -337,7 +337,7 @@ static int catu_alloc_etr_buf(struct tmc_drvdata *tmc_drvdata, csdev = tmc_etr_get_catu_device(tmc_drvdata); if (!csdev) return -ENODEV; - catu_buf = kzalloc(sizeof(*catu_buf), GFP_KERNEL); + catu_buf = kzalloc_obj(*catu_buf); if (!catu_buf) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index c660cf8adb1c..80e26396ad0a 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -821,7 +821,7 @@ static int _coresight_build_path(struct coresight_device *csdev, if (ret) return ret; - node = kzalloc(sizeof(struct coresight_node), GFP_KERNEL); + node = kzalloc_obj(struct coresight_node); if (!node) return -ENOMEM; @@ -840,7 +840,7 @@ struct coresight_path *coresight_build_path(struct coresight_device *source, if (!sink) return ERR_PTR(-EINVAL); - path = kzalloc(sizeof(struct coresight_path), GFP_KERNEL); + path = kzalloc_obj(struct coresight_path); if (!path) return ERR_PTR(-ENOMEM); @@ -1327,7 +1327,7 @@ struct coresight_device *coresight_register(struct coresight_desc *desc) struct coresight_device *csdev; bool registered = false; - csdev = kzalloc(sizeof(*csdev), GFP_KERNEL); + csdev = kzalloc_obj(*csdev); if (!csdev) { ret = -ENOMEM; goto err_out; diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c index d0ae10bf6128..4eff96f48594 100644 --- a/drivers/hwtracing/coresight/coresight-cti-platform.c +++ b/drivers/hwtracing/coresight/coresight-cti-platform.c @@ -325,7 +325,7 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata, if (nr_filter_sigs > drvdata->config.nr_trig_max) return -EINVAL; - tg = kzalloc(sizeof(*tg), GFP_KERNEL); + tg = kzalloc_obj(*tg); if (!tg) return -ENOMEM; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c index 17afa0f4cdee..72017dcc3b7f 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.c +++ b/drivers/hwtracing/coresight/coresight-etm-perf.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -50,26 +51,22 @@ struct etm_ctxt { static DEFINE_PER_CPU(struct etm_ctxt, etm_ctxt); static DEFINE_PER_CPU(struct coresight_device *, csdev_src); -/* - * The PMU formats were orignally for ETMv3.5/PTM's ETMCR 'config'; - * now take them as general formats and apply on all ETMs. - */ -PMU_FORMAT_ATTR(branch_broadcast, "config:"__stringify(ETM_OPT_BRANCH_BROADCAST)); -PMU_FORMAT_ATTR(cycacc, "config:" __stringify(ETM_OPT_CYCACC)); -/* contextid1 enables tracing CONTEXTIDR_EL1 for ETMv4 */ -PMU_FORMAT_ATTR(contextid1, "config:" __stringify(ETM_OPT_CTXTID)); -/* contextid2 enables tracing CONTEXTIDR_EL2 for ETMv4 */ -PMU_FORMAT_ATTR(contextid2, "config:" __stringify(ETM_OPT_CTXTID2)); -PMU_FORMAT_ATTR(timestamp, "config:" __stringify(ETM_OPT_TS)); -PMU_FORMAT_ATTR(retstack, "config:" __stringify(ETM_OPT_RETSTK)); -/* preset - if sink ID is used as a configuration selector */ -PMU_FORMAT_ATTR(preset, "config:0-3"); -/* Sink ID - same for all ETMs */ -PMU_FORMAT_ATTR(sinkid, "config2:0-31"); -/* config ID - set if a system configuration is selected */ -PMU_FORMAT_ATTR(configid, "config2:32-63"); -PMU_FORMAT_ATTR(cc_threshold, "config3:0-11"); +GEN_PMU_FORMAT_ATTR(cycacc); +GEN_PMU_FORMAT_ATTR(timestamp); +GEN_PMU_FORMAT_ATTR(retstack); +GEN_PMU_FORMAT_ATTR(sinkid); +#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) +GEN_PMU_FORMAT_ATTR(branch_broadcast); +/* contextid1 enables tracing CONTEXTIDR_EL1*/ +GEN_PMU_FORMAT_ATTR(contextid1); +/* contextid2 enables tracing CONTEXTIDR_EL2*/ +GEN_PMU_FORMAT_ATTR(contextid2); +/* preset - if sink ID is used as a configuration selector */ +GEN_PMU_FORMAT_ATTR(preset); +/* config ID - set if a system configuration is selected */ +GEN_PMU_FORMAT_ATTR(configid); +GEN_PMU_FORMAT_ATTR(cc_threshold); /* * contextid always traces the "PID". The PID is in CONTEXTIDR_EL1 @@ -80,29 +77,35 @@ static ssize_t format_attr_contextid_show(struct device *dev, struct device_attribute *attr, char *page) { - int pid_fmt = ETM_OPT_CTXTID; - -#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) - pid_fmt = is_kernel_in_hyp_mode() ? ETM_OPT_CTXTID2 : ETM_OPT_CTXTID; -#endif - return sprintf(page, "config:%d\n", pid_fmt); + if (is_kernel_in_hyp_mode()) + return contextid2_show(dev, attr, page); + return contextid1_show(dev, attr, page); } static struct device_attribute format_attr_contextid = __ATTR(contextid, 0444, format_attr_contextid_show, NULL); +#endif +/* + * ETMv3 only uses the first 3 attributes for programming itself (see + * ETM3X_SUPPORTED_OPTIONS). Sink ID is also supported for selecting a + * sink in both, but not used for configuring the ETM. The remaining + * attributes are ETMv4 specific. + */ static struct attribute *etm_config_formats_attr[] = { &format_attr_cycacc.attr, - &format_attr_contextid.attr, - &format_attr_contextid1.attr, - &format_attr_contextid2.attr, &format_attr_timestamp.attr, &format_attr_retstack.attr, &format_attr_sinkid.attr, +#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM4X) + &format_attr_contextid.attr, + &format_attr_contextid1.attr, + &format_attr_contextid2.attr, &format_attr_preset.attr, &format_attr_configid.attr, &format_attr_branch_broadcast.attr, &format_attr_cc_threshold.attr, +#endif NULL, }; @@ -257,7 +260,7 @@ static void *alloc_event_data(int cpu) struct etm_event_data *event_data; /* First get memory for the session's data */ - event_data = kzalloc(sizeof(struct etm_event_data), GFP_KERNEL); + event_data = kzalloc_obj(struct etm_event_data); if (!event_data) return NULL; @@ -315,7 +318,7 @@ static bool sinks_compatible(struct coresight_device *a, static void *etm_setup_aux(struct perf_event *event, void **pages, int nr_pages, bool overwrite) { - u32 id, cfg_hash; + u32 sink_hash, cfg_hash; int cpu = event->cpu; cpumask_t *mask; struct coresight_device *sink = NULL; @@ -328,13 +331,12 @@ static void *etm_setup_aux(struct perf_event *event, void **pages, INIT_WORK(&event_data->work, free_event_data); /* First get the selected sink from user space. */ - if (event->attr.config2 & GENMASK_ULL(31, 0)) { - id = (u32)event->attr.config2; - sink = user_sink = coresight_get_sink_by_id(id); - } + sink_hash = ATTR_CFG_GET_FLD(&event->attr, sinkid); + if (sink_hash) + sink = user_sink = coresight_get_sink_by_id(sink_hash); /* check if user wants a coresight configuration selected */ - cfg_hash = (u32)((event->attr.config2 & GENMASK_ULL(63, 32)) >> 32); + cfg_hash = ATTR_CFG_GET_FLD(&event->attr, configid); if (cfg_hash) { if (cscfg_activate_config(cfg_hash)) goto err; diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h index 5febbcdb8696..24d929428633 100644 --- a/drivers/hwtracing/coresight/coresight-etm-perf.h +++ b/drivers/hwtracing/coresight/coresight-etm-perf.h @@ -20,6 +20,44 @@ struct cscfg_config_desc; */ #define ETM_ADDR_CMP_MAX 8 +#define ATTR_CFG_FLD_preset_CFG config +#define ATTR_CFG_FLD_preset_LO 0 +#define ATTR_CFG_FLD_preset_HI 3 +#define ATTR_CFG_FLD_timestamp_CFG config +#define ATTR_CFG_FLD_timestamp_LO 4 +#define ATTR_CFG_FLD_timestamp_HI 7 +#define ATTR_CFG_FLD_branch_broadcast_CFG config +#define ATTR_CFG_FLD_branch_broadcast_LO 8 +#define ATTR_CFG_FLD_branch_broadcast_HI 8 +#define ATTR_CFG_FLD_cycacc_CFG config +#define ATTR_CFG_FLD_cycacc_LO 12 +#define ATTR_CFG_FLD_cycacc_HI 12 +#define ATTR_CFG_FLD_contextid1_CFG config +#define ATTR_CFG_FLD_contextid1_LO 14 +#define ATTR_CFG_FLD_contextid1_HI 14 +#define ATTR_CFG_FLD_contextid2_CFG config +#define ATTR_CFG_FLD_contextid2_LO 15 +#define ATTR_CFG_FLD_contextid2_HI 15 +/* + * Old position of 'timestamp' and not published in sysfs. Remove at a later + * date if necessary. + */ +#define ATTR_CFG_FLD_deprecated_timestamp_CFG config +#define ATTR_CFG_FLD_deprecated_timestamp_LO 28 +#define ATTR_CFG_FLD_deprecated_timestamp_HI 28 +#define ATTR_CFG_FLD_retstack_CFG config +#define ATTR_CFG_FLD_retstack_LO 29 +#define ATTR_CFG_FLD_retstack_HI 29 +#define ATTR_CFG_FLD_sinkid_CFG config2 +#define ATTR_CFG_FLD_sinkid_LO 0 +#define ATTR_CFG_FLD_sinkid_HI 31 +#define ATTR_CFG_FLD_configid_CFG config2 +#define ATTR_CFG_FLD_configid_LO 32 +#define ATTR_CFG_FLD_configid_HI 63 +#define ATTR_CFG_FLD_cc_threshold_CFG config3 +#define ATTR_CFG_FLD_cc_threshold_LO 0 +#define ATTR_CFG_FLD_cc_threshold_HI 11 + /** * struct etm_filter - single instruction range or start/stop configuration. * @start_addr: The address to start tracing on. diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c index a5e809589d3e..a547a6d2e0bd 100644 --- a/drivers/hwtracing/coresight/coresight-etm3x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include "coresight-etm.h" @@ -309,6 +310,7 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata, { struct etm_config *config = &drvdata->config; struct perf_event_attr *attr = &event->attr; + u8 ts_level; if (!attr) return -EINVAL; @@ -332,28 +334,31 @@ static int etm_parse_event_config(struct etm_drvdata *drvdata, if (config->mode) etm_config_trace_mode(config); - /* - * At this time only cycle accurate, return stack and timestamp - * options are available. - */ - if (attr->config & ~ETM3X_SUPPORTED_OPTIONS) + config->ctrl = 0; + + if (ATTR_CFG_GET_FLD(attr, cycacc)) + config->ctrl |= ETMCR_CYC_ACC; + + ts_level = max(ATTR_CFG_GET_FLD(attr, timestamp), + ATTR_CFG_GET_FLD(attr, deprecated_timestamp)); + + if (ts_level > 1) { + dev_dbg(&drvdata->csdev->dev, + "timestamp format attribute should be 0 (off) or 1 (on)\n"); return -EINVAL; + } - config->ctrl = attr->config; - - /* Don't trace contextID when runs in non-root PID namespace */ - if (!task_is_in_init_pid_ns(current)) - config->ctrl &= ~ETMCR_CTXID_SIZE; + if (ts_level) + config->ctrl |= ETMCR_TIMESTAMP_EN; /* - * Possible to have cores with PTM (supports ret stack) and ETM - * (never has ret stack) on the same SoC. So if we have a request - * for return stack that can't be honoured on this core then - * clear the bit - trace will still continue normally + * Possible to have cores with PTM (supports ret stack) and ETM (never + * has ret stack) on the same SoC. So only enable when it can be honored + * - trace will still continue normally otherwise. */ - if ((config->ctrl & ETMCR_RETURN_STACK) && - !(drvdata->etmccer & ETMCCER_RETSTACK)) - config->ctrl &= ~ETMCR_RETURN_STACK; + if (ATTR_CFG_GET_FLD(attr, retstack) && + (drvdata->etmccer & ETMCCER_RETSTACK)) + config->ctrl |= ETMCR_RETURN_STACK; return 0; } @@ -795,16 +800,16 @@ static int __init etm_hp_setup(void) { int ret; - ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ARM_CORESIGHT_STARTING, - "arm/coresight:starting", - etm_starting_cpu, etm_dying_cpu); + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING, + "arm/coresight:starting", + etm_starting_cpu, etm_dying_cpu); if (ret) return ret; - ret = cpuhp_setup_state_nocalls_cpuslocked(CPUHP_AP_ONLINE_DYN, - "arm/coresight:online", - etm_online_cpu, NULL); + ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, + "arm/coresight:online", + etm_online_cpu, NULL); /* HP dyn state ID returned in ret on success */ if (ret > 0) { diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 560975b70474..d565a73f0042 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -642,18 +643,34 @@ static void etm4_enable_sysfs_smp_call(void *info) * TRCRSCTLR1 (always true) used to get the counter to decrement. From * there a resource selector is configured with the counter and the * timestamp control register to use the resource selector to trigger the - * event that will insert a timestamp packet in the stream. + * event that will insert a timestamp packet in the stream: + * + * +--------------+ + * | Resource 1 | fixed "always-true" resource + * +--------------+ + * | + * +------v-------+ + * | Counter x | (reload to 2 ^ (ts_level - 1) on underflow) + * +--------------+ + * | + * +------v--------------+ + * | Resource Selector y | (trigger on counter x == 0) + * +---------------------+ + * | + * +------v---------------+ + * | Timestamp Generator | (timestamp on resource y) + * +----------------------+ */ -static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) +static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata, + u8 ts_level) { - int ctridx, ret = -EINVAL; - int counter, rselector; - u32 val = 0; + int ctridx; + int rselector; struct etmv4_config *config = &drvdata->config; /* No point in trying if we don't have at least one counter */ if (!drvdata->nr_cntr) - goto out; + return -EINVAL; /* Find a counter that hasn't been initialised */ for (ctridx = 0; ctridx < drvdata->nr_cntr; ctridx++) @@ -663,15 +680,19 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) /* All the counters have been configured already, bail out */ if (ctridx == drvdata->nr_cntr) { pr_debug("%s: no available counter found\n", __func__); - ret = -ENOSPC; - goto out; + return -ENOSPC; } /* - * Searching for an available resource selector to use, starting at - * '2' since every implementation has at least 2 resource selector. - * ETMIDR4 gives the number of resource selector _pairs_, - * hence multiply by 2. + * Searching for an available resource selector to use, starting at '2' + * since resource 0 is the fixed 'always returns false' resource and 1 + * is the fixed 'always returns true' resource. See IHI0064H_b '7.3.64 + * TRCRSCTLRn, Resource Selection Control Registers, n=2-31'. If there + * are no resources, there would also be no counters so wouldn't get + * here. + * + * ETMIDR4 gives the number of resource selector _pairs_, hence multiply + * by 2. */ for (rselector = 2; rselector < drvdata->nr_resource * 2; rselector++) if (!config->res_ctrl[rselector]) @@ -680,40 +701,47 @@ static int etm4_config_timestamp_event(struct etmv4_drvdata *drvdata) if (rselector == drvdata->nr_resource * 2) { pr_debug("%s: no available resource selector found\n", __func__); - ret = -ENOSPC; - goto out; + return -ENOSPC; } - /* Remember what counter we used */ - counter = 1 << ctridx; + /* Initialise original and reload counter value. */ + config->cntr_val[ctridx] = config->cntrldvr[ctridx] = 1 << (ts_level - 1); /* - * Initialise original and reload counter value to the smallest - * possible value in order to get as much precision as we can. + * Trace Counter Control Register TRCCNTCTLRn + * + * CNTCHAIN = 0, don't reload on the previous counter + * RLDSELF = true, reload counter automatically on underflow + * RLDEVENT = RES_SEL_FALSE (0), reload on single false resource (never reload) + * CNTEVENT = RES_SEL_TRUE (1), count single fixed 'always true' resource (always decrement) */ - config->cntr_val[ctridx] = 1; - config->cntrldvr[ctridx] = 1; + config->cntr_ctrl[ctridx] = TRCCNTCTLRn_RLDSELF | + FIELD_PREP(TRCCNTCTLRn_RLDEVENT_MASK, + etm4_res_sel_single(ETM4_RES_SEL_FALSE)) | + FIELD_PREP(TRCCNTCTLRn_CNTEVENT_MASK, + etm4_res_sel_single(ETM4_RES_SEL_TRUE)); - /* Set the trace counter control register */ - val = 0x1 << 16 | /* Bit 16, reload counter automatically */ - 0x0 << 7 | /* Select single resource selector */ - 0x1; /* Resource selector 1, i.e always true */ + /* + * Resource Selection Control Register TRCRSCTLRn + * + * PAIRINV = 0, INV = 0, don't invert + * GROUP = 2, SELECT = ctridx, trigger when counter 'ctridx' reaches 0 + * + * Multiple counters can be selected, and each bit signifies a counter, + * so set bit 'ctridx' to select our counter. + */ + config->res_ctrl[rselector] = FIELD_PREP(TRCRSCTLRn_GROUP_MASK, 2) | + FIELD_PREP(TRCRSCTLRn_SELECT_MASK, 1 << ctridx); - config->cntr_ctrl[ctridx] = val; + /* + * Global Timestamp Control Register TRCTSCTLR + * + * EVENT = generate timestamp on single resource 'rselector' + */ + config->ts_ctrl = FIELD_PREP(TRCTSCTLR_EVENT_MASK, + etm4_res_sel_single(rselector)); - val = 0x2 << 16 | /* Group 0b0010 - Counter and sequencers */ - counter << 0; /* Counter to use */ - - config->res_ctrl[rselector] = val; - - val = 0x0 << 7 | /* Select single resource selector */ - rselector; /* Resource selector */ - - config->ts_ctrl = val; - - ret = 0; -out: - return ret; + return 0; } static int etm4_parse_event_config(struct coresight_device *csdev, @@ -722,9 +750,13 @@ static int etm4_parse_event_config(struct coresight_device *csdev, int ret = 0; struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); struct etmv4_config *config = &drvdata->config; + struct perf_event_attr max_timestamp = { + .ATTR_CFG_FLD_timestamp_CFG = U64_MAX, + }; struct perf_event_attr *attr = &event->attr; unsigned long cfg_hash; int preset, cc_threshold; + u8 ts_level; /* Clear configuration from previous run */ memset(config, 0, sizeof(struct etmv4_config)); @@ -750,47 +782,51 @@ static int etm4_parse_event_config(struct coresight_device *csdev, goto out; /* Go from generic option to ETMv4 specifics */ - if (attr->config & BIT(ETM_OPT_CYCACC)) { + if (ATTR_CFG_GET_FLD(attr, cycacc)) { config->cfg |= TRCCONFIGR_CCI; /* TRM: Must program this for cycacc to work */ - cc_threshold = attr->config3 & ETM_CYC_THRESHOLD_MASK; + cc_threshold = ATTR_CFG_GET_FLD(attr, cc_threshold); if (!cc_threshold) cc_threshold = ETM_CYC_THRESHOLD_DEFAULT; if (cc_threshold < drvdata->ccitmin) cc_threshold = drvdata->ccitmin; config->ccctlr = cc_threshold; } - if (attr->config & BIT(ETM_OPT_TS)) { - /* - * Configure timestamps to be emitted at regular intervals in - * order to correlate instructions executed on different CPUs - * (CPU-wide trace scenarios). - */ - ret = etm4_config_timestamp_event(drvdata); + ts_level = max(ATTR_CFG_GET_FLD(attr, timestamp), + ATTR_CFG_GET_FLD(attr, deprecated_timestamp)); + if (ts_level) { /* - * No need to go further if timestamp intervals can't - * be configured. + * Don't do counter generated timestamps when ts_level == MAX. + * Leave only SYNC timestamps from TRCCONFIGR_TS. */ - if (ret) - goto out; + if (ts_level != ATTR_CFG_GET_FLD(&max_timestamp, timestamp)) { + ret = etm4_config_timestamp_event(drvdata, ts_level); + + /* + * Error if user asked for timestamps but there was no + * free counter. + */ + if (ret) + goto out; + } /* bit[11], Global timestamp tracing bit */ config->cfg |= TRCCONFIGR_TS; } /* Only trace contextID when runs in root PID namespace */ - if ((attr->config & BIT(ETM_OPT_CTXTID)) && + if (ATTR_CFG_GET_FLD(attr, contextid1) && task_is_in_init_pid_ns(current)) /* bit[6], Context ID tracing bit */ config->cfg |= TRCCONFIGR_CID; /* - * If set bit ETM_OPT_CTXTID2 in perf config, this asks to trace VMID - * for recording CONTEXTIDR_EL2. Do not enable VMID tracing if the - * kernel is not running in EL2. + * If set bit contextid2 in perf config, this asks to trace VMID for + * recording CONTEXTIDR_EL2. Do not enable VMID tracing if the kernel + * is not running in EL2. */ - if (attr->config & BIT(ETM_OPT_CTXTID2)) { + if (ATTR_CFG_GET_FLD(attr, contextid2)) { if (!is_kernel_in_hyp_mode()) { ret = -EINVAL; goto out; @@ -801,26 +837,22 @@ static int etm4_parse_event_config(struct coresight_device *csdev, } /* return stack - enable if selected and supported */ - if ((attr->config & BIT(ETM_OPT_RETSTK)) && drvdata->retstack) + if (ATTR_CFG_GET_FLD(attr, retstack) && drvdata->retstack) /* bit[12], Return stack enable bit */ config->cfg |= TRCCONFIGR_RS; /* - * Set any selected configuration and preset. - * - * This extracts the values of PMU_FORMAT_ATTR(configid) and PMU_FORMAT_ATTR(preset) - * in the perf attributes defined in coresight-etm-perf.c. - * configid uses bits 63:32 of attr->config2, preset uses bits 3:0 of attr->config. - * A zero configid means no configuration active, preset = 0 means no preset selected. + * Set any selected configuration and preset. A zero configid means no + * configuration active, preset = 0 means no preset selected. */ - if (attr->config2 & GENMASK_ULL(63, 32)) { - cfg_hash = (u32)(attr->config2 >> 32); - preset = attr->config & 0xF; + cfg_hash = ATTR_CFG_GET_FLD(attr, configid); + if (cfg_hash) { + preset = ATTR_CFG_GET_FLD(attr, preset); ret = cscfg_csdev_enable_active_config(csdev, cfg_hash, preset); } /* branch broadcast - enable if selected and supported */ - if (attr->config & BIT(ETM_OPT_BRANCH_BROADCAST)) { + if (ATTR_CFG_GET_FLD(attr, branch_broadcast)) { if (!drvdata->trcbb) { /* * Missing BB support could cause silent decode errors @@ -829,7 +861,7 @@ static int etm4_parse_event_config(struct coresight_device *csdev, ret = -EINVAL; goto out; } else { - config->cfg |= BIT(ETM4_CFG_BIT_BB); + config->cfg |= TRCCONFIGR_BB; } } @@ -1053,11 +1085,8 @@ static int etm4_disable_perf(struct coresight_device *csdev, return -EINVAL; etm4_disable_hw(drvdata); - /* - * The config_id occupies bits 63:32 of the config2 perf event attr - * field. If this is non-zero then we will have enabled a config. - */ - if (attr->config2 & GENMASK_ULL(63, 32)) + /* If configid is non-zero then we will have enabled a config. */ + if (ATTR_CFG_GET_FLD(attr, configid)) cscfg_csdev_disable_active_config(csdev); /* diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 012c52fd1933..89d81ce4e04e 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -225,6 +225,50 @@ #define TRCRSCTLRn_GROUP_MASK GENMASK(19, 16) #define TRCRSCTLRn_SELECT_MASK GENMASK(15, 0) +#define TRCCNTCTLRn_CNTCHAIN BIT(17) +#define TRCCNTCTLRn_RLDSELF BIT(16) +#define TRCCNTCTLRn_RLDEVENT_MASK GENMASK(15, 8) +#define TRCCNTCTLRn_CNTEVENT_MASK GENMASK(7, 0) + +#define TRCTSCTLR_EVENT_MASK GENMASK(7, 0) + +#define ETM4_RES_SEL_FALSE 0 /* Fixed function 'always false' resource selector */ +#define ETM4_RES_SEL_TRUE 1 /* Fixed function 'always true' resource selector */ + +#define ETM4_RES_SEL_SINGLE_MASK GENMASK(4, 0) +#define ETM4_RES_SEL_PAIR_MASK GENMASK(3, 0) +#define ETM4_RES_SEL_TYPE_PAIR BIT(7) + +/* + * Utilities for programming EVENT resource selectors, e.g. TRCCNTCTLRn_RLDEVENT. + * + * Resource selectors have a common format across registers: + * + * 7 6 5 4 0 + * +------+------+-------+ + * | TYPE | RES0 | SEL | + * +------+------+-------+ + * + * Where TYPE indicates whether the selector is for a single event or a pair. + * When TYPE is pair, SEL is 4 bits wide and using pair 0 is UNPREDICTABLE. + * Otherwise for single it's 5 bits wide. + */ +static inline u32 etm4_res_sel_single(u8 res_sel_idx) +{ + WARN_ON_ONCE(!FIELD_FIT(ETM4_RES_SEL_SINGLE_MASK, res_sel_idx)); + return FIELD_PREP(ETM4_RES_SEL_SINGLE_MASK, res_sel_idx); +} + +static inline u32 etm4_res_sel_pair(u8 res_sel_idx) +{ + if (__builtin_constant_p(res_sel_idx)) + BUILD_BUG_ON(res_sel_idx == 0); + WARN_ON_ONCE(!FIELD_FIT(ETM4_RES_SEL_PAIR_MASK, res_sel_idx) || + (res_sel_idx == 0)); + return FIELD_PREP(ETM4_RES_SEL_PAIR_MASK, res_sel_idx) | + ETM4_RES_SEL_TYPE_PAIR; +} + /* * System instructions to access ETM registers. * See ETMv4.4 spec ARM IHI0064F section 4.3.6 System instructions @@ -824,8 +868,7 @@ struct etmv4_config { u32 eventctrl0; u32 eventctrl1; u32 stall_ctrl; - u32 ts_ctrl; - u32 syncfreq; + u32 ts_ctrl; /* TRCTSCTLR */ u32 ccctlr; u32 bb_ctrl; u32 vinst_ctrl; @@ -833,15 +876,16 @@ struct etmv4_config { u32 vissctlr; u32 vipcssctlr; u8 seq_idx; + u8 syncfreq; u32 seq_ctrl[ETM_MAX_SEQ_STATES]; u32 seq_rst; u32 seq_state; u8 cntr_idx; - u32 cntrldvr[ETMv4_MAX_CNTR]; - u32 cntr_ctrl[ETMv4_MAX_CNTR]; - u32 cntr_val[ETMv4_MAX_CNTR]; + u32 cntrldvr[ETMv4_MAX_CNTR]; /* TRCCNTRLDVRn */ + u32 cntr_ctrl[ETMv4_MAX_CNTR]; /* TRCCNTCTLRn */ + u32 cntr_val[ETMv4_MAX_CNTR]; /* TRCCNTVRn */ u8 res_idx; - u32 res_ctrl[ETM_MAX_RES_SEL]; + u32 res_ctrl[ETM_MAX_RES_SEL]; /* TRCRSCTLRn */ u8 ss_idx; u32 ss_ctrl[ETM_MAX_SS_CMP]; u32 ss_status[ETM_MAX_SS_CMP]; @@ -1016,27 +1060,27 @@ struct etmv4_drvdata { u8 ns_ex_level; u8 q_support; u8 os_lock_model; - bool sticky_enable; - bool boot_enable; - bool os_unlock; - bool instrp0; - bool q_filt; - bool trcbb; - bool trccond; - bool retstack; - bool trccci; - bool trc_error; - bool syncpr; - bool stallctl; - bool sysstall; - bool nooverflow; - bool atbtrig; - bool lpoverride; + bool sticky_enable : 1; + bool boot_enable : 1; + bool os_unlock : 1; + bool instrp0 : 1; + bool q_filt : 1; + bool trcbb : 1; + bool trccond : 1; + bool retstack : 1; + bool trccci : 1; + bool trc_error : 1; + bool syncpr : 1; + bool stallctl : 1; + bool sysstall : 1; + bool nooverflow : 1; + bool atbtrig : 1; + bool lpoverride : 1; + bool skip_power_up : 1; + bool paused : 1; u64 trfcr; struct etmv4_config config; struct etmv4_save_state *save_state; - bool skip_power_up; - bool paused; DECLARE_BITMAP(arch_features, ETM4_IMPDEF_FEATURE_MAX); }; diff --git a/drivers/hwtracing/coresight/coresight-syscfg.c b/drivers/hwtracing/coresight/coresight-syscfg.c index 6836b05986e8..d7f5037953d6 100644 --- a/drivers/hwtracing/coresight/coresight-syscfg.c +++ b/drivers/hwtracing/coresight/coresight-syscfg.c @@ -756,7 +756,7 @@ static int cscfg_list_add_csdev(struct coresight_device *csdev, struct cscfg_registered_csdev *csdev_item; /* allocate the list entry structure */ - csdev_item = kzalloc(sizeof(struct cscfg_registered_csdev), GFP_KERNEL); + csdev_item = kzalloc_obj(struct cscfg_registered_csdev); if (!csdev_item) return -ENOMEM; @@ -1190,7 +1190,7 @@ static int cscfg_create_device(void) goto create_dev_exit_unlock; } - cscfg_mgr = kzalloc(sizeof(struct cscfg_manager), GFP_KERNEL); + cscfg_mgr = kzalloc_obj(struct cscfg_manager); if (!cscfg_mgr) goto create_dev_exit_unlock; diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index e0d83ee01b77..4dc1defe27a5 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -204,12 +204,10 @@ static int tmc_pages_alloc(struct tmc_pages *tmc_pages, struct device *real_dev = dev->parent; nr_pages = tmc_pages->nr_pages; - tmc_pages->daddrs = kcalloc(nr_pages, sizeof(*tmc_pages->daddrs), - GFP_KERNEL); + tmc_pages->daddrs = kzalloc_objs(*tmc_pages->daddrs, nr_pages); if (!tmc_pages->daddrs) return -ENOMEM; - tmc_pages->pages = kcalloc(nr_pages, sizeof(*tmc_pages->pages), - GFP_KERNEL); + tmc_pages->pages = kzalloc_objs(*tmc_pages->pages, nr_pages); if (!tmc_pages->pages) { kfree(tmc_pages->daddrs); tmc_pages->daddrs = NULL; @@ -332,7 +330,7 @@ struct tmc_sg_table *tmc_alloc_sg_table(struct device *dev, long rc; struct tmc_sg_table *sg_table; - sg_table = kzalloc(sizeof(*sg_table), GFP_KERNEL); + sg_table = kzalloc_obj(*sg_table); if (!sg_table) return ERR_PTR(-ENOMEM); sg_table->data_pages.nr_pages = nr_dpages; @@ -575,7 +573,7 @@ tmc_init_etr_sg_table(struct device *dev, int node, struct tmc_sg_table *sg_table; struct etr_sg_table *etr_table; - etr_table = kzalloc(sizeof(*etr_table), GFP_KERNEL); + etr_table = kzalloc_obj(*etr_table); if (!etr_table) return ERR_PTR(-ENOMEM); nr_entries = tmc_etr_sg_table_entries(nr_dpages); @@ -612,7 +610,7 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, if (pages) return -EINVAL; - flat_buf = kzalloc(sizeof(*flat_buf), GFP_KERNEL); + flat_buf = kzalloc_obj(*flat_buf); if (!flat_buf) return -ENOMEM; @@ -710,7 +708,7 @@ static int tmc_etr_alloc_resrv_buf(struct tmc_drvdata *drvdata, if (pages) return -EINVAL; - resrv_buf = kzalloc(sizeof(*resrv_buf), GFP_KERNEL); + resrv_buf = kzalloc_obj(*resrv_buf); if (!resrv_buf) return -ENOMEM; @@ -942,7 +940,7 @@ static struct etr_buf *tmc_alloc_etr_buf(struct tmc_drvdata *drvdata, struct device *dev = &drvdata->csdev->dev; get_etr_buf_hw(dev, &buf_hw); - etr_buf = kzalloc(sizeof(*etr_buf), GFP_KERNEL); + etr_buf = kzalloc_obj(*etr_buf); if (!etr_buf) return ERR_PTR(-ENOMEM); @@ -1306,6 +1304,19 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) raw_spin_lock_irqsave(&drvdata->spinlock, flags); + /* + * Since the sysfs buffer allocation and the hardware enablement is not + * in the same critical region, it's possible to race with the perf. + */ + if (coresight_get_mode(csdev) == CS_MODE_PERF) { + drvdata->sysfs_buf = NULL; + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); + + /* Free allocated memory out side of the spinlock */ + tmc_etr_free_sysfs_buf(sysfs_buf); + return -EBUSY; + } + /* * In sysFS mode we can have multiple writers per sink. Since this * sink is already enabled no memory is needed and the HW need not be @@ -1354,9 +1365,7 @@ EXPORT_SYMBOL_GPL(tmc_etr_get_buffer); /* * alloc_etr_buf: Allocate ETR buffer for use by perf. - * The size of the hardware buffer is dependent on the size configured - * via sysfs and the perf ring buffer size. We prefer to allocate the - * largest possible size, scaling down the size by half until it + * Allocate the largest possible size, scaling down the size by half until it * reaches a minimum limit (1M), beyond which we give up. */ static struct etr_buf * @@ -1365,36 +1374,26 @@ alloc_etr_buf(struct tmc_drvdata *drvdata, struct perf_event *event, { int node; struct etr_buf *etr_buf; - unsigned long size; + ssize_t size; node = (event->cpu == -1) ? NUMA_NO_NODE : cpu_to_node(event->cpu); - /* - * Try to match the perf ring buffer size if it is larger - * than the size requested via sysfs. - */ - if ((nr_pages << PAGE_SHIFT) > drvdata->size) { - etr_buf = tmc_alloc_etr_buf(drvdata, ((ssize_t)nr_pages << PAGE_SHIFT), - 0, node, NULL); - if (!IS_ERR(etr_buf)) - goto done; - } + + /* Use the minimum limit if the required size is smaller */ + size = nr_pages << PAGE_SHIFT; + size = max_t(ssize_t, size, TMC_ETR_PERF_MIN_BUF_SIZE); /* - * Else switch to configured size for this ETR - * and scale down until we hit the minimum limit. + * Try to allocate the required size for this ETR, if failed scale + * down until we hit the minimum limit. */ - size = drvdata->size; do { etr_buf = tmc_alloc_etr_buf(drvdata, size, 0, node, NULL); if (!IS_ERR(etr_buf)) - goto done; + return etr_buf; size /= 2; } while (size >= TMC_ETR_PERF_MIN_BUF_SIZE); return ERR_PTR(-ENOMEM); - -done: - return etr_buf; } static struct etr_buf * diff --git a/drivers/hwtracing/coresight/coresight-tmc.h b/drivers/hwtracing/coresight/coresight-tmc.h index 95473d131032..319a354ede9f 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.h +++ b/drivers/hwtracing/coresight/coresight-tmc.h @@ -221,6 +221,7 @@ struct tmc_resrv_buf { * @pid: Process ID of the process that owns the session that is using * this component. For example this would be the pid of the Perf * process. + * @reading: buffer's in the reading through "/dev/xyz.tmc" entry * @stop_on_flush: Stop on flush trigger user configuration. * @buf: Snapshot of the trace data for ETF/ETB. * @etr_buf: details of buffer used in TMC-ETR @@ -233,6 +234,7 @@ struct tmc_resrv_buf { * @trigger_cntr: amount of words to store after a trigger. * @etr_caps: Bitmask of capabilities of the TMC ETR, inferred from the * device configuration register (DEVID) + * @etr_mode: User preferred mode of the ETR device, default auto mode. * @idr: Holds etr_bufs allocated for this ETR. * @idr_mutex: Access serialisation for idr. * @sysfs_buf: SYSFS buffer for ETR. diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index ff9a0a9cfe96..1128612e70a7 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -34,6 +34,7 @@ * @base: memory mapped base address for this component. * @dev: device node for trace_noc_drvdata. * @csdev: component vitals needed by the framework. + * @pclk: APB clock if present, otherwise NULL * @spinlock: serialize enable/disable operation. * @atid: id for the trace packet. */ @@ -41,8 +42,9 @@ struct trace_noc_drvdata { void __iomem *base; struct device *dev; struct coresight_device *csdev; + struct clk *pclk; spinlock_t spinlock; - u32 atid; + int atid; }; DEFINE_CORESIGHT_DEVLIST(trace_noc_devs, "traceNoc"); @@ -51,6 +53,12 @@ static void trace_noc_enable_hw(struct trace_noc_drvdata *drvdata) { u32 val; + /* No valid ATID, simply enable the unit */ + if (drvdata->atid == -EOPNOTSUPP) { + writel(TRACE_NOC_CTRL_PORTEN, drvdata->base + TRACE_NOC_CTRL); + return; + } + /* Set ATID */ writel_relaxed(drvdata->atid, drvdata->base + TRACE_NOC_XLD); @@ -124,6 +132,11 @@ static int trace_noc_init_default_data(struct trace_noc_drvdata *drvdata) { int atid; + if (!dev_is_amba(drvdata->dev)) { + drvdata->atid = -EOPNOTSUPP; + return 0; + } + atid = coresight_trace_id_get_system_id(); if (atid < 0) return atid; @@ -149,8 +162,21 @@ static struct attribute *coresight_tnoc_attrs[] = { NULL, }; +static umode_t trace_id_is_visible(struct kobject *kobj, + struct attribute *attr, int idx) +{ + struct device *dev = kobj_to_dev(kobj); + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (attr == &dev_attr_traceid.attr && drvdata->atid < 0) + return 0; + + return attr->mode; +} + static const struct attribute_group coresight_tnoc_group = { .attrs = coresight_tnoc_attrs, + .is_visible = trace_id_is_visible, }; static const struct attribute_group *coresight_tnoc_groups[] = { @@ -158,9 +184,8 @@ static const struct attribute_group *coresight_tnoc_groups[] = { NULL, }; -static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) +static int _tnoc_probe(struct device *dev, struct resource *res) { - struct device *dev = &adev->dev; struct coresight_platform_data *pdata; struct trace_noc_drvdata *drvdata; struct coresight_desc desc = { 0 }; @@ -173,16 +198,20 @@ static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); - adev->dev.platform_data = pdata; + dev->platform_data = pdata; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; - drvdata->dev = &adev->dev; + drvdata->dev = dev; dev_set_drvdata(dev, drvdata); - drvdata->base = devm_ioremap_resource(dev, &adev->res); + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL); + if (ret) + return ret; + + drvdata->base = devm_ioremap_resource(dev, res); if (IS_ERR(drvdata->base)) return PTR_ERR(drvdata->base); @@ -195,20 +224,31 @@ static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &trace_noc_cs_ops; desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; - desc.pdata = adev->dev.platform_data; - desc.dev = &adev->dev; + desc.pdata = pdata; + desc.dev = dev; desc.access = CSDEV_ACCESS_IOMEM(drvdata->base); desc.groups = coresight_tnoc_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { - coresight_trace_id_put_system_id(drvdata->atid); + if (drvdata->atid > 0) + coresight_trace_id_put_system_id(drvdata->atid); return PTR_ERR(drvdata->csdev); } - pm_runtime_put(&adev->dev); return 0; } +static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + + ret = _tnoc_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + static void trace_noc_remove(struct amba_device *adev) { struct trace_noc_drvdata *drvdata = dev_get_drvdata(&adev->dev); @@ -240,7 +280,81 @@ static struct amba_driver trace_noc_driver = { .id_table = trace_noc_ids, }; -module_amba_driver(trace_noc_driver); +static int itnoc_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int ret; + + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = _tnoc_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static void itnoc_remove(struct platform_device *pdev) +{ + struct trace_noc_drvdata *drvdata = platform_get_drvdata(pdev); + + coresight_unregister(drvdata->csdev); + pm_runtime_disable(&pdev->dev); +} + +#ifdef CONFIG_PM +static int itnoc_runtime_suspend(struct device *dev) +{ + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev); + + clk_disable_unprepare(drvdata->pclk); + + return 0; +} + +static int itnoc_runtime_resume(struct device *dev) +{ + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev); + + return clk_prepare_enable(drvdata->pclk); +} +#endif + +static const struct dev_pm_ops itnoc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(itnoc_runtime_suspend, itnoc_runtime_resume, NULL) +}; + +static const struct of_device_id itnoc_of_match[] = { + { .compatible = "qcom,coresight-itnoc" }, + {} +}; +MODULE_DEVICE_TABLE(of, itnoc_of_match); + +static struct platform_driver itnoc_driver = { + .probe = itnoc_probe, + .remove = itnoc_remove, + .driver = { + .name = "coresight-itnoc", + .of_match_table = itnoc_of_match, + .suppress_bind_attrs = true, + .pm = &itnoc_dev_pm_ops, + }, +}; + +static int __init tnoc_init(void) +{ + return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE); +} + +static void __exit tnoc_exit(void) +{ + coresight_remove_driver(&trace_noc_driver, &itnoc_driver); +} +module_init(tnoc_init); +module_exit(tnoc_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Trace NOC driver"); diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index 3a3825d27f86..7055f8f13427 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -137,12 +137,46 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata, /* Settings pre enabling port control register */ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) { - u32 val; + u32 val = 0; - val = readl_relaxed(drvdata->base + TPDA_CR); - val &= ~TPDA_CR_ATID; val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid); + if (drvdata->trig_async) + val |= TPDA_CR_SRIE; + + if (drvdata->trig_flag_ts) + val |= TPDA_CR_FLRIE; + + if (drvdata->trig_freq) + val |= TPDA_CR_FRIE; + + if (drvdata->freq_ts) + val |= TPDA_CR_FREQTS; + + if (drvdata->cmbchan_mode) + val |= TPDA_CR_CMBCHANMODE; + writel_relaxed(val, drvdata->base + TPDA_CR); + + /* + * If FLRIE bit is set, set the master and channel + * id as zero + */ + if (drvdata->trig_flag_ts) + writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR); + + /* Initialize with a value of 0 */ + val = 0; + if (drvdata->syncr_mode) + val |= TPDA_SYNCR_MODE_CTRL_MASK; + + if (drvdata->syncr_count > 0 && + drvdata->syncr_count < TPDA_SYNCR_COUNT_MASK) + val |= drvdata->syncr_count; + else + /* Program the count to its MAX value by default */ + val |= TPDA_SYNCR_COUNT_MASK; + + writel_relaxed(val, drvdata->base + TPDA_SYNCR); } static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) @@ -258,6 +292,248 @@ static const struct coresight_ops tpda_cs_ops = { .link_ops = &tpda_link_ops, }; +/* Read cross-trigger register member */ +static ssize_t tpda_trig_sysfs_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_trig_sysfs_attribute *tpda_attr = + container_of(attr, struct tpda_trig_sysfs_attribute, attr); + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + + guard(spinlock)(&drvdata->spinlock); + switch (tpda_attr->mem) { + case FREQTS: + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts); + case FRIE: + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq); + case FLRIE: + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts); + case SRIE: + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async); + case CMBCHANMODE: + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->cmbchan_mode); + + } + return -EINVAL; +} + +static ssize_t tpda_trig_sysfs_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_trig_sysfs_attribute *tpda_attr = + container_of(attr, struct tpda_trig_sysfs_attribute, attr); + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + switch (tpda_attr->mem) { + case FREQTS: + drvdata->freq_ts = !!val; + break; + case FRIE: + drvdata->trig_freq = !!val; + break; + case FLRIE: + drvdata->trig_flag_ts = !!val; + break; + case SRIE: + drvdata->trig_async = !!val; + break; + case CMBCHANMODE: + drvdata->cmbchan_mode = !!val; + break; + default: + return -EINVAL; + } + + return size; +} + +static ssize_t global_flush_req_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + val = readl_relaxed(drvdata->base + TPDA_CR); + /* read global_flush_req bit */ + val &= TPDA_CR_FLREQ; + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t global_flush_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (!drvdata->csdev->refcnt || !val) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + val = readl_relaxed(drvdata->base + TPDA_CR); + /* set global_flush_req bit */ + val |= TPDA_CR_FLREQ; + CS_UNLOCK(drvdata->base); + writel_relaxed(val, drvdata->base + TPDA_CR); + CS_LOCK(drvdata->base); + + return size; +} +static DEVICE_ATTR_RW(global_flush_req); + +static ssize_t syncr_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val, syncr_val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + syncr_val = readl_relaxed(drvdata->base + TPDA_SYNCR); + val = FIELD_GET(TPDA_SYNCR_MODE_CTRL_MASK, syncr_val); + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t syncr_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + /* set the mode when first enabling the device */ + drvdata->syncr_mode = !!val; + + return size; +} +static DEVICE_ATTR_RW(syncr_mode); + +static ssize_t syncr_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + val = readl_relaxed(drvdata->base + TPDA_SYNCR); + val &= TPDA_SYNCR_COUNT_MASK; + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t syncr_count_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + if (val > TPDA_SYNCR_COUNT_MASK) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->syncr_count = val; + + return size; +} +static DEVICE_ATTR_RW(syncr_count); + +static ssize_t port_flush_req_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR); + + return sysfs_emit(buf, "0x%lx\n", val); +} + +static ssize_t port_flush_req_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t size) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + u32 val; + + if (kstrtou32(buf, 0, &val)) + return -EINVAL; + + if (!drvdata->csdev->refcnt || !val) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + CS_UNLOCK(drvdata->base); + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR); + CS_LOCK(drvdata->base); + + return size; +} +static DEVICE_ATTR_RW(port_flush_req); + +static struct attribute *tpda_attrs[] = { + &dev_attr_global_flush_req.attr, + &dev_attr_syncr_mode.attr, + &dev_attr_syncr_count.attr, + &dev_attr_port_flush_req.attr, + tpda_trig_sysfs_rw(freq_ts_enable, FREQTS), + tpda_trig_sysfs_rw(trig_freq_enable, FRIE), + tpda_trig_sysfs_rw(trig_flag_ts_enable, FLRIE), + tpda_trig_sysfs_rw(trig_async_enable, SRIE), + tpda_trig_sysfs_rw(cmbchan_mode, CMBCHANMODE), + NULL, +}; + +static struct attribute_group tpda_attr_grp = { + .attrs = tpda_attrs, +}; + +static const struct attribute_group *tpda_attr_grps[] = { + &tpda_attr_grp, + NULL, +}; + static int tpda_init_default_data(struct tpda_drvdata *drvdata) { int atid; @@ -273,6 +549,7 @@ static int tpda_init_default_data(struct tpda_drvdata *drvdata) return atid; drvdata->atid = atid; + drvdata->freq_ts = true; return 0; } @@ -316,6 +593,7 @@ static int tpda_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &tpda_cs_ops; desc.pdata = adev->dev.platform_data; desc.dev = &adev->dev; + desc.groups = tpda_attr_grps; desc.access = CSDEV_ACCESS_IOMEM(base); drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index c6af3d2da3ef..a090352009bb 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.h +++ b/drivers/hwtracing/coresight/coresight-tpda.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023,2025 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CORESIGHT_CORESIGHT_TPDA_H @@ -8,6 +8,29 @@ #define TPDA_CR (0x000) #define TPDA_Pn_CR(n) (0x004 + (n * 4)) +#define TPDA_FPID_CR (0x084) +#define TPDA_SYNCR (0x08C) +#define TPDA_FLUSH_CR (0x090) + +/* Cross trigger global (all ports) flush request bit */ +#define TPDA_CR_FLREQ BIT(0) +/* Cross trigger FREQ packets timestamp bit */ +#define TPDA_CR_FREQTS BIT(2) +/* Cross trigger FREQ packet request bit */ +#define TPDA_CR_FRIE BIT(3) +/* Cross trigger FLAG packet request interface bit */ +#define TPDA_CR_FLRIE BIT(4) +/* Cross trigger synchronization bit */ +#define TPDA_CR_SRIE BIT(5) +/* Bits 6 ~ 12 is for atid value */ +#define TPDA_CR_ATID GENMASK(12, 6) +/* + * Channel mode bit of the packetization of CMB/MCB traffic + * 0 - raw channel mapping mode + * 1 - channel pair marking mode + */ +#define TPDA_CR_CMBCHANMODE BIT(20) + /* Aggregator port enable bit */ #define TPDA_Pn_CR_ENA BIT(0) /* Aggregator port CMB data set element size bit */ @@ -15,10 +38,12 @@ /* Aggregator port DSB data set element size bit */ #define TPDA_Pn_CR_DSBSIZE BIT(8) -#define TPDA_MAX_INPORTS 32 +/* TPDA_SYNCR count mask */ +#define TPDA_SYNCR_COUNT_MASK GENMASK(11, 0) +/* TPDA_SYNCR mode control bit */ +#define TPDA_SYNCR_MODE_CTRL_MASK GENMASK(12, 12) -/* Bits 6 ~ 12 is for atid value */ -#define TPDA_CR_ATID GENMASK(12, 6) +#define TPDA_MAX_INPORTS 32 /** * struct tpda_drvdata - specifics associated to an TPDA component @@ -29,6 +54,13 @@ * @enable: enable status of the component. * @dsb_esize Record the DSB element size. * @cmb_esize Record the CMB element size. + * @trig_async: Enable/disable cross trigger synchronization sequence interface. + * @trig_flag_ts: Enable/disable cross trigger FLAG packet request interface. + * @trig_freq: Enable/disable cross trigger FREQ packet request interface. + * @freq_ts: Enable/disable the timestamp for all FREQ packets. + * @cmbchan_mode: Configure the CMB/MCMB channel mode. + * @syncr_mode: Setting the mode for counting packets. + * @syncr_count: Setting the value of the count. */ struct tpda_drvdata { void __iomem *base; @@ -38,6 +70,42 @@ struct tpda_drvdata { u8 atid; u32 dsb_esize; u32 cmb_esize; + bool trig_async; + bool trig_flag_ts; + bool trig_freq; + bool freq_ts; + bool cmbchan_mode; + bool syncr_mode; + u32 syncr_count; }; +/* Enumerate members of global control register(cr) */ +enum tpda_cr_mem { + FREQTS, + FRIE, + FLRIE, + SRIE, + CMBCHANMODE +}; + +/** + * struct tpda_trig_sysfs_attribute - Record the member variables of cross + * trigger register that need to be operated by sysfs file + * @attr: The device attribute + * @mem: The member in the control register data structure + */ +struct tpda_trig_sysfs_attribute { + struct device_attribute attr; + enum tpda_cr_mem mem; +}; + +#define tpda_trig_sysfs_rw(name, mem) \ + (&((struct tpda_trig_sysfs_attribute[]) { \ + { \ + __ATTR(name, 0644, tpda_trig_sysfs_show, \ + tpda_trig_sysfs_store), \ + mem, \ + } \ + })[0].attr.attr) + #endif /* _CORESIGHT_CORESIGHT_TPDA_H */ diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 474861903f6c..1511f8eb95af 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -751,7 +751,7 @@ static void *arm_trbe_alloc_buffer(struct coresight_device *csdev, if (!buf) return NULL; - pglist = kcalloc(nr_pages, sizeof(*pglist), GFP_KERNEL); + pglist = kzalloc_objs(*pglist, nr_pages); if (!pglist) { kfree(buf); return NULL; diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c index 2482ecf5776b..3924e63e2eee 100644 --- a/drivers/hwtracing/intel_th/core.c +++ b/drivers/hwtracing/intel_th/core.c @@ -891,7 +891,7 @@ intel_th_alloc(struct device *dev, const struct intel_th_drvdata *drvdata, int err, r, nr_mmios = 0; struct intel_th *th; - th = kzalloc(sizeof(*th), GFP_KERNEL); + th = kzalloc_obj(*th); if (!th) return ERR_PTR(-ENOMEM); diff --git a/drivers/hwtracing/intel_th/msu-sink.c b/drivers/hwtracing/intel_th/msu-sink.c index 256ce3260ad9..b809a7f805a9 100644 --- a/drivers/hwtracing/intel_th/msu-sink.c +++ b/drivers/hwtracing/intel_th/msu-sink.c @@ -23,7 +23,7 @@ static void *msu_sink_assign(struct device *dev, int *mode) { struct msu_sink_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; diff --git a/drivers/hwtracing/intel_th/msu.c b/drivers/hwtracing/intel_th/msu.c index f3a13b300835..a82cf74f39ad 100644 --- a/drivers/hwtracing/intel_th/msu.c +++ b/drivers/hwtracing/intel_th/msu.c @@ -236,7 +236,7 @@ int intel_th_msu_buffer_register(const struct msu_buffer *mbuf, struct msu_buffer_entry *mbe; int ret = 0; - mbe = kzalloc(sizeof(*mbe), GFP_KERNEL); + mbe = kzalloc_obj(*mbe); if (!mbe) return -ENOMEM; @@ -450,7 +450,7 @@ static struct msc_iter *msc_iter_install(struct msc *msc) { struct msc_iter *iter; - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc_obj(*iter); if (!iter) return ERR_PTR(-ENOMEM); @@ -1105,7 +1105,7 @@ static int msc_buffer_win_alloc(struct msc *msc, unsigned int nr_blocks) if (!nr_blocks) return 0; - win = kzalloc(sizeof(*win), GFP_KERNEL); + win = kzalloc_obj(*win); if (!win) return -ENOMEM; diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c index e3def163d5cf..6cd5ac3c6430 100644 --- a/drivers/hwtracing/intel_th/pci.c +++ b/drivers/hwtracing/intel_th/pci.c @@ -14,6 +14,7 @@ #include #include "intel_th.h" +#include "pci_ids.h" #define DRIVER_NAME "intel_th_pci" @@ -141,225 +142,55 @@ static const struct intel_th_drvdata intel_th_2x = { }; static const struct pci_device_id intel_th_pci_id_table[] = { - { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9d26), - .driver_data = (kernel_ulong_t)0, - }, - { - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa126), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Apollo Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x5a8e), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Broxton */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Broxton B-step */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1a8e), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Kaby Lake PCH-H */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6), - .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, - }, - { - /* Denverton */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x19e1), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Lewisburg PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa1a6), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Lewisburg PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226), - .driver_data = (kernel_ulong_t)0, - }, - { - /* Gemini Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Cannon Lake H */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa326), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Cannon Lake LP */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9da6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Cedar Fork PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Ice Lake PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Comet Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x02a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Comet Lake PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x06a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Comet Lake PCH-V */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa3a6), - .driver_data = (kernel_ulong_t)&intel_th_1x_multi_is_broken, - }, - { - /* Ice Lake NNPI */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Ice Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8a29), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Tiger Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x9a33), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Tiger Lake PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Tiger Lake PCH-H */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x43a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Jasper Lake PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4da6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Jasper Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4e29), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Elkhart Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4529), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Elkhart Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4b26), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Emmitsburg PCH */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x1bcc), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Alder Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7aa6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Alder Lake-P */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x51a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Alder Lake-M */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x54a6), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Meteor Lake-P */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7e24), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Meteor Lake-S */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7f26), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Meteor Lake-S CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xae24), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Raptor Lake-S */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7a26), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Raptor Lake-S CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa76f), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Granite Rapids */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0963), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Granite Rapids SOC */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3256), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Sapphire Rapids SOC */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x3456), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Lunar Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa824), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Arrow Lake */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x7724), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Panther Lake-H */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe324), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Panther Lake-P/U */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xe424), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Alder Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x466f), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { - /* Rocket Lake CPU */ - PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4c19), - .driver_data = (kernel_ulong_t)&intel_th_2x, - }, - { 0 }, + { PCI_DEVICE_DATA(INTEL, NPK_CML, &intel_th_2x) }, /* Comet Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_CML_PCH, &intel_th_2x) }, /* Comet Lake PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_GNR, &intel_th_2x) }, /* Granite Rapids */ + { PCI_DEVICE_DATA(INTEL, NPK_BXT, NULL) }, /* Broxton */ + { PCI_DEVICE_DATA(INTEL, NPK_CDF, &intel_th_2x) }, /* Cedar Fork PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_DNV, NULL) }, /* Denverton */ + { PCI_DEVICE_DATA(INTEL, NPK_BXT_B, NULL) }, /* Broxton B-step */ + { PCI_DEVICE_DATA(INTEL, NPK_EBG, &intel_th_2x) }, /* Emmitsburg PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_GLK, &intel_th_2x) }, /* Gemini Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_GNR_SOC, &intel_th_2x) }, /* Granite Rapids SOC */ + { PCI_DEVICE_DATA(INTEL, NPK_SPR, &intel_th_2x) }, /* Sapphire Rapids SOC */ + { PCI_DEVICE_DATA(INTEL, NPK_ICL_PCH, &intel_th_2x) }, /* Ice Lake PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_TGL_PCH_H, &intel_th_2x) }, /* Tiger Lake PCH-H */ + { PCI_DEVICE_DATA(INTEL, NPK_EHL_CPU, &intel_th_2x) }, /* Elkhart Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_ICL_NNPI, &intel_th_2x) }, /* Ice Lake NNPI */ + { PCI_DEVICE_DATA(INTEL, NPK_ADL_CPU, &intel_th_2x) }, /* Alder Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_EHL, &intel_th_2x) }, /* Elkhart Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_RKL, &intel_th_2x) }, /* Rocket Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_JSL_PCH, &intel_th_2x) }, /* Jasper Lake PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_JSL_CPU, &intel_th_2x) }, /* Jasper Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_ADL_P, &intel_th_2x) }, /* Alder Lake-P */ + { PCI_DEVICE_DATA(INTEL, NPK_ADL_M, &intel_th_2x) }, /* Alder Lake-M */ + { PCI_DEVICE_DATA(INTEL, NPK_APL, NULL) }, /* Apollo Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_NVL_PCH, &intel_th_2x) }, /* Nova Lake-PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_ARL, &intel_th_2x) }, /* Arrow Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_RPL_S, &intel_th_2x) }, /* Raptor Lake-S */ + { PCI_DEVICE_DATA(INTEL, NPK_ADL, &intel_th_2x) }, /* Alder Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_MTL_P, &intel_th_2x) }, /* Meteor Lake-P */ + { PCI_DEVICE_DATA(INTEL, NPK_MTL_S, &intel_th_2x) }, /* Meteor Lake-S */ + { PCI_DEVICE_DATA(INTEL, NPK_ICL_CPU, &intel_th_2x) }, /* Ice Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_TGL_CPU, &intel_th_2x) }, /* Tiger Lake CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_0, NULL) }, + { PCI_DEVICE_DATA(INTEL, NPK_CNL_LP, &intel_th_2x) }, /* Cannon Lake LP */ + { PCI_DEVICE_DATA(INTEL, NPK_TGL_PCH, &intel_th_2x) }, /* Tiger Lake PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_1, NULL) }, + { PCI_DEVICE_DATA(INTEL, NPK_LBG_PCH, NULL) }, /* Lewisburg PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_LBG_PCH_2, NULL) }, /* Lewisburg PCH */ + { PCI_DEVICE_DATA(INTEL, NPK_KBL_PCH, &intel_th_1x_multi_is_broken) }, /* Kaby Lake PCH-H */ + { PCI_DEVICE_DATA(INTEL, NPK_CNL_H, &intel_th_2x) }, /* Cannon Lake H */ + { PCI_DEVICE_DATA(INTEL, NPK_CML_PCH_V, &intel_th_1x_multi_is_broken) }, /* Comet Lake PCH-V */ + { PCI_DEVICE_DATA(INTEL, NPK_RPL_S_CPU, &intel_th_2x) }, /* Raptor Lake-S CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_LNL, &intel_th_2x) }, /* Lunar Lake */ + { PCI_DEVICE_DATA(INTEL, NPK_MTL_S_CPU, &intel_th_2x) }, /* Meteor Lake-S CPU */ + { PCI_DEVICE_DATA(INTEL, NPK_NVL_P, &intel_th_2x) }, /* Nova Lake-P */ + { PCI_DEVICE_DATA(INTEL, NPK_NVL_H, &intel_th_2x) }, /* Nova Lake-H */ + { PCI_DEVICE_DATA(INTEL, NPK_NVL_S, &intel_th_2x) }, /* Nova Lake-S */ + { PCI_DEVICE_DATA(INTEL, NPK_PTL_H, &intel_th_2x) }, /* Panther Lake-H */ + { PCI_DEVICE_DATA(INTEL, NPK_PTL_PU, &intel_th_2x) }, /* Panther Lake-P/U */ + { } }; MODULE_DEVICE_TABLE(pci, intel_th_pci_id_table); diff --git a/drivers/hwtracing/intel_th/pci_ids.h b/drivers/hwtracing/intel_th/pci_ids.h new file mode 100644 index 000000000000..4a0c53beac22 --- /dev/null +++ b/drivers/hwtracing/intel_th/pci_ids.h @@ -0,0 +1,60 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Intel(R) Trace Hub driver debugging + * + * Copyright (C) 2025 Intel Corporation. + */ + +#ifndef __INTEL_TH_PCI_IDS_H__ +#define __INTEL_TH_PCI_IDS_H__ + +#define PCI_DEVICE_ID_INTEL_NPK_CML 0x02a6 +#define PCI_DEVICE_ID_INTEL_NPK_CML_PCH 0x06a6 +#define PCI_DEVICE_ID_INTEL_NPK_GNR 0x0963 +#define PCI_DEVICE_ID_INTEL_NPK_BXT 0x0a80 +#define PCI_DEVICE_ID_INTEL_NPK_CDF 0x18e1 +#define PCI_DEVICE_ID_INTEL_NPK_DNV 0x19e1 +#define PCI_DEVICE_ID_INTEL_NPK_BXT_B 0x1a8e +#define PCI_DEVICE_ID_INTEL_NPK_EBG 0x1bcc +#define PCI_DEVICE_ID_INTEL_NPK_GLK 0x318e +#define PCI_DEVICE_ID_INTEL_NPK_GNR_SOC 0x3256 +#define PCI_DEVICE_ID_INTEL_NPK_SPR 0x3456 +#define PCI_DEVICE_ID_INTEL_NPK_ICL_PCH 0x34a6 +#define PCI_DEVICE_ID_INTEL_NPK_TGL_PCH_H 0x43a6 +#define PCI_DEVICE_ID_INTEL_NPK_EHL_CPU 0x4529 +#define PCI_DEVICE_ID_INTEL_NPK_ICL_NNPI 0x45c5 +#define PCI_DEVICE_ID_INTEL_NPK_ADL_CPU 0x466f +#define PCI_DEVICE_ID_INTEL_NPK_EHL 0x4b26 +#define PCI_DEVICE_ID_INTEL_NPK_RKL 0x4c19 +#define PCI_DEVICE_ID_INTEL_NPK_JSL_PCH 0x4da6 +#define PCI_DEVICE_ID_INTEL_NPK_JSL_CPU 0x4e29 +#define PCI_DEVICE_ID_INTEL_NPK_ADL_P 0x51a6 +#define PCI_DEVICE_ID_INTEL_NPK_ADL_M 0x54a6 +#define PCI_DEVICE_ID_INTEL_NPK_APL 0x5a8e +#define PCI_DEVICE_ID_INTEL_NPK_NVL_PCH 0x6e26 +#define PCI_DEVICE_ID_INTEL_NPK_ARL 0x7724 +#define PCI_DEVICE_ID_INTEL_NPK_RPL_S 0x7a26 +#define PCI_DEVICE_ID_INTEL_NPK_ADL 0x7aa6 +#define PCI_DEVICE_ID_INTEL_NPK_MTL_P 0x7e24 +#define PCI_DEVICE_ID_INTEL_NPK_MTL_S 0x7f26 +#define PCI_DEVICE_ID_INTEL_NPK_ICL_CPU 0x8a29 +#define PCI_DEVICE_ID_INTEL_NPK_TGL_CPU 0x9a33 +#define PCI_DEVICE_ID_INTEL_NPK_0 0x9d26 +#define PCI_DEVICE_ID_INTEL_NPK_CNL_LP 0x9da6 +#define PCI_DEVICE_ID_INTEL_NPK_TGL_PCH 0xa0a6 +#define PCI_DEVICE_ID_INTEL_NPK_1 0xa126 +#define PCI_DEVICE_ID_INTEL_NPK_LBG_PCH 0xa1a6 +#define PCI_DEVICE_ID_INTEL_NPK_LBG_PCH_2 0xa226 +#define PCI_DEVICE_ID_INTEL_NPK_KBL_PCH 0xa2a6 +#define PCI_DEVICE_ID_INTEL_NPK_CNL_H 0xa326 +#define PCI_DEVICE_ID_INTEL_NPK_CML_PCH_V 0xa3a6 +#define PCI_DEVICE_ID_INTEL_NPK_RPL_S_CPU 0xa76f +#define PCI_DEVICE_ID_INTEL_NPK_LNL 0xa824 +#define PCI_DEVICE_ID_INTEL_NPK_MTL_S_CPU 0xae24 +#define PCI_DEVICE_ID_INTEL_NPK_NVL_P 0xd224 +#define PCI_DEVICE_ID_INTEL_NPK_NVL_H 0xd324 +#define PCI_DEVICE_ID_INTEL_NPK_NVL_S 0xd424 +#define PCI_DEVICE_ID_INTEL_NPK_PTL_H 0xe324 +#define PCI_DEVICE_ID_INTEL_NPK_PTL_PU 0xe424 + +#endif /* __INTEL_TH_PCI_IDS_H__ */ diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c index 3090479a2979..94c371c49135 100644 --- a/drivers/hwtracing/ptt/hisi_ptt.c +++ b/drivers/hwtracing/ptt/hisi_ptt.c @@ -384,7 +384,7 @@ hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port) return NULL; } - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) { pci_err(hisi_ptt->pdev, "failed to add filter for %s\n", filter_name); @@ -1043,11 +1043,11 @@ static void *hisi_ptt_pmu_setup_aux(struct perf_event *event, void **pages, if (nr_pages < HISI_PTT_TRACE_TOTAL_BUF_SIZE / PAGE_SIZE) return NULL; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return NULL; - pagelist = kcalloc(nr_pages, sizeof(*pagelist), GFP_KERNEL); + pagelist = kzalloc_objs(*pagelist, nr_pages); if (!pagelist) goto err; diff --git a/drivers/hwtracing/stm/Kconfig b/drivers/hwtracing/stm/Kconfig index eda6b11d40a1..cd7f0b0f3fbe 100644 --- a/drivers/hwtracing/stm/Kconfig +++ b/drivers/hwtracing/stm/Kconfig @@ -13,7 +13,7 @@ if STM config STM_PROTO_BASIC tristate "Basic STM framing protocol driver" - default CONFIG_STM + default STM help This is a simple framing protocol for sending data over STM devices. This was the protocol that the STM framework used @@ -28,7 +28,7 @@ config STM_PROTO_BASIC config STM_PROTO_SYS_T tristate "MIPI SyS-T STM framing protocol driver" - default CONFIG_STM + default STM help This is an implementation of MIPI SyS-T protocol to be used over the STP transport. In addition to the data payload, it diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c index cdba4e875b28..37584e786bb5 100644 --- a/drivers/hwtracing/stm/core.c +++ b/drivers/hwtracing/stm/core.c @@ -160,9 +160,9 @@ static int stp_master_alloc(struct stm_device *stm, unsigned int idx) { struct stp_master *master; - master = kzalloc(struct_size(master, chan_map, - BITS_TO_LONGS(stm->data->sw_nchannels)), - GFP_ATOMIC); + master = kzalloc_flex(*master, chan_map, + BITS_TO_LONGS(stm->data->sw_nchannels), + GFP_ATOMIC); if (!master) return -ENOMEM; @@ -406,7 +406,7 @@ int stm_register_protocol(const struct stm_protocol_driver *pdrv) goto unlock; } - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc_obj(*pe); if (!pe) goto unlock; @@ -493,7 +493,7 @@ static int stm_char_open(struct inode *inode, struct file *file) if (!dev) return -ENODEV; - stmf = kzalloc(sizeof(*stmf), GFP_KERNEL); + stmf = kzalloc_obj(*stmf); if (!stmf) goto err_put_device; @@ -1229,7 +1229,7 @@ int stm_source_register_device(struct device *parent, if (!stm_core_up) return -EPROBE_DEFER; - src = kzalloc(sizeof(*src), GFP_KERNEL); + src = kzalloc_obj(*src); if (!src) return -ENOMEM; diff --git a/drivers/hwtracing/stm/p_sys-t.c b/drivers/hwtracing/stm/p_sys-t.c index 1e75aa0025a3..bcbbc4d92325 100644 --- a/drivers/hwtracing/stm/p_sys-t.c +++ b/drivers/hwtracing/stm/p_sys-t.c @@ -128,7 +128,7 @@ static int sys_t_output_open(void *priv, struct stm_output *output) struct sys_t_policy_node *pn = priv; struct sys_t_output *opriv; - opriv = kzalloc(sizeof(*opriv), GFP_ATOMIC); + opriv = kzalloc_obj(*opriv, GFP_ATOMIC); if (!opriv) return -ENOMEM; diff --git a/drivers/hwtracing/stm/policy.c b/drivers/hwtracing/stm/policy.c index 42103c3a177f..fabaf4b14889 100644 --- a/drivers/hwtracing/stm/policy.c +++ b/drivers/hwtracing/stm/policy.c @@ -437,7 +437,7 @@ stp_policy_make(struct config_group *group, const char *name) goto unlock_policy; } - stm->policy = kzalloc(sizeof(*stm->policy), GFP_KERNEL); + stm->policy = kzalloc_obj(*stm->policy); if (!stm->policy) { ret = ERR_PTR(-ENOMEM); goto unlock_policy; diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 09ba55bae1fa..e11d50750e63 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -569,24 +569,17 @@ config I2C_DESIGNWARE_CORE help This option enables support for the Synopsys DesignWare I2C adapter. This driver includes support for the I2C host on the Synopsys - Designware I2C adapter. + Designware I2C adapter, and the I2C slave when enabled (select + I2C_SLAVE). To compile the driver as a module, choose M here: the module will be called i2c-designware-core. if I2C_DESIGNWARE_CORE -config I2C_DESIGNWARE_SLAVE - bool "Synopsys DesignWare Slave" - select I2C_SLAVE - help - If you say yes to this option, support will be included for the - Synopsys DesignWare I2C slave adapter. - config I2C_DESIGNWARE_PLATFORM tristate "Synopsys DesignWare Platform driver" depends on (ACPI && COMMON_CLK) || !ACPI - select MFD_SYSCON if MIPS_BAIKAL_T1 default I2C_DESIGNWARE_CORE help If you say yes to this option, support will be included for the diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index fb985769f5ff..547123ab351f 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -53,7 +53,7 @@ obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o i2c-designware-core-y := i2c-designware-common.o i2c-designware-core-y += i2c-designware-master.o -i2c-designware-core-$(CONFIG_I2C_DESIGNWARE_SLAVE) += i2c-designware-slave.o +i2c-designware-core-$(CONFIG_I2C_SLAVE) += i2c-designware-slave.o obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o i2c-designware-platform-y := i2c-designware-platdrv.o i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_AMDPSP) += i2c-designware-amdpsp.o diff --git a/drivers/i2c/busses/i2c-amd-mp2-pci.c b/drivers/i2c/busses/i2c-amd-mp2-pci.c index 60edbabc2986..5b41d18b62d3 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-pci.c +++ b/drivers/i2c/busses/i2c-amd-mp2-pci.c @@ -456,18 +456,20 @@ module_pci_driver(amd_mp2_pci_driver); struct amd_mp2_dev *amd_mp2_find_device(void) { + struct amd_mp2_dev *privdata; struct device *dev; struct pci_dev *pci_dev; - struct amd_mp2_dev *mp2_dev; dev = driver_find_next_device(&amd_mp2_pci_driver.driver, NULL); if (!dev) return NULL; pci_dev = to_pci_dev(dev); - mp2_dev = (struct amd_mp2_dev *)pci_get_drvdata(pci_dev); + privdata = pci_get_drvdata(pci_dev); + put_device(dev); - return mp2_dev; + + return privdata; } EXPORT_SYMBOL_GPL(amd_mp2_find_device); diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 42a9b1221065..dd9ac4bb6704 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c @@ -17,7 +17,7 @@ #include MODULE_LICENSE("GPL"); -MODULE_AUTHOR ("Vojtech Pavlik "); +MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("AMD8111 SMBus 2.0 driver"); struct amd_smbus { @@ -417,7 +417,7 @@ static const struct pci_device_id amd8111_ids[] = { { 0, } }; -MODULE_DEVICE_TABLE (pci, amd8111_ids); +MODULE_DEVICE_TABLE(pci, amd8111_ids); static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) { @@ -427,7 +427,7 @@ static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) if (!(pci_resource_flags(dev, 0) & IORESOURCE_IO)) return -ENODEV; - smbus = kzalloc(sizeof(struct amd_smbus), GFP_KERNEL); + smbus = devm_kzalloc(&dev->dev, sizeof(struct amd_smbus), GFP_KERNEL); if (!smbus) return -ENOMEM; @@ -436,19 +436,15 @@ static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) smbus->size = pci_resource_len(dev, 0); error = acpi_check_resource_conflict(&dev->resource[0]); - if (error) { - error = -ENODEV; - goto out_kfree; - } + if (error) + return -ENODEV; - if (!request_region(smbus->base, smbus->size, amd8111_driver.name)) { - error = -EBUSY; - goto out_kfree; - } + if (!devm_request_region(&dev->dev, smbus->base, smbus->size, amd8111_driver.name)) + return -EBUSY; smbus->adapter.owner = THIS_MODULE; snprintf(smbus->adapter.name, sizeof(smbus->adapter.name), - "SMBus2 AMD8111 adapter at %04x", smbus->base); + "SMBus2 AMD8111 adapter at %04x", smbus->base); smbus->adapter.class = I2C_CLASS_HWMON; smbus->adapter.algo = &smbus_algorithm; smbus->adapter.algo_data = smbus; @@ -459,16 +455,10 @@ static int amd8111_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(smbus->dev, AMD_PCI_MISC, 0); error = i2c_add_adapter(&smbus->adapter); if (error) - goto out_release_region; + return error; pci_set_drvdata(dev, smbus); return 0; - - out_release_region: - release_region(smbus->base, smbus->size); - out_kfree: - kfree(smbus); - return error; } static void amd8111_remove(struct pci_dev *dev) @@ -476,8 +466,6 @@ static void amd8111_remove(struct pci_dev *dev) struct amd_smbus *smbus = pci_get_drvdata(dev); i2c_del_adapter(&smbus->adapter); - release_region(smbus->base, smbus->size); - kfree(smbus); } static struct pci_driver amd8111_driver = { diff --git a/drivers/i2c/busses/i2c-cp2615.c b/drivers/i2c/busses/i2c-cp2615.c index e7720ea4045e..e2d7cd2390fc 100644 --- a/drivers/i2c/busses/i2c-cp2615.c +++ b/drivers/i2c/busses/i2c-cp2615.c @@ -124,7 +124,7 @@ static int cp2615_check_status(enum cp2615_i2c_status status) static int cp2615_i2c_send(struct usb_interface *usbif, struct cp2615_i2c_transfer *i2c_w) { - struct cp2615_iop_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL); + struct cp2615_iop_msg *msg = kzalloc_obj(*msg); struct usb_device *usbdev = interface_to_usbdev(usbif); int res = cp2615_init_i2c_msg(msg, i2c_w); @@ -143,7 +143,7 @@ cp2615_i2c_recv(struct usb_interface *usbif, unsigned char tag, void *buf) struct cp2615_i2c_transfer_result *i2c_r; int res; - msg = kzalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -171,7 +171,7 @@ cp2615_i2c_recv(struct usb_interface *usbif, unsigned char tag, void *buf) /* Checks if the IOP is functional by querying the part's ID */ static int cp2615_check_iop(struct usb_interface *usbif) { - struct cp2615_iop_msg *msg = kzalloc(sizeof(*msg), GFP_KERNEL); + struct cp2615_iop_msg *msg = kzalloc_obj(*msg); struct cp2615_iop_accessory_info *info = (struct cp2615_iop_accessory_info *)&msg->data; struct usb_device *usbdev = interface_to_usbdev(usbif); int res = cp2615_init_iop_msg(msg, iop_GetAccessoryInfo, NULL, 0); diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index 260e1643c2cc..2cb6a233d313 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c @@ -636,7 +636,7 @@ static int cpm_i2c_probe(struct platform_device *ofdev) struct cpm_i2c *cpm; const u32 *data; - cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL); + cpm = kzalloc_obj(struct cpm_i2c); if (!cpm) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-designware-amdisp.c b/drivers/i2c/busses/i2c-designware-amdisp.c index 450793d5f839..c48728ad9f6f 100644 --- a/drivers/i2c/busses/i2c-designware-amdisp.c +++ b/drivers/i2c/busses/i2c-designware-amdisp.c @@ -18,9 +18,6 @@ static void amd_isp_dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *i2c_dev) { pm_runtime_disable(i2c_dev->dev); - - if (i2c_dev->shared_with_punit) - pm_runtime_put_noidle(i2c_dev->dev); } static inline u32 amd_isp_dw_i2c_get_clk_rate(struct dw_i2c_dev *i2c_dev) @@ -79,9 +76,6 @@ static int amd_isp_dw_i2c_plat_probe(struct platform_device *pdev) device_enable_async_suspend(&pdev->dev); - if (isp_i2c_dev->shared_with_punit) - pm_runtime_get_noresume(&pdev->dev); - pm_runtime_enable(&pdev->dev); pm_runtime_get_sync(&pdev->dev); @@ -130,9 +124,6 @@ static int amd_isp_dw_i2c_plat_runtime_suspend(struct device *dev) { struct dw_i2c_dev *i_dev = dev_get_drvdata(dev); - if (i_dev->shared_with_punit) - return 0; - i2c_dw_disable(i_dev); i2c_dw_prepare_clk(i_dev, false); @@ -161,10 +152,8 @@ static int amd_isp_dw_i2c_plat_runtime_resume(struct device *dev) if (!i_dev) return -ENODEV; - if (!i_dev->shared_with_punit) - i2c_dw_prepare_clk(i_dev, true); - if (i_dev->init) - i_dev->init(i_dev); + i2c_dw_prepare_clk(i_dev, true); + i2c_dw_init(i_dev); return 0; } diff --git a/drivers/i2c/busses/i2c-designware-amdpsp.c b/drivers/i2c/busses/i2c-designware-amdpsp.c index 404571ad61a8..186f9b9f48b4 100644 --- a/drivers/i2c/busses/i2c-designware-amdpsp.c +++ b/drivers/i2c/busses/i2c-designware-amdpsp.c @@ -93,7 +93,7 @@ static int psp_send_i2c_req(enum psp_i2c_req_type i2c_req_type) int status, ret; /* Allocate command-response buffer */ - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 5b1e8f74c4ac..4dc57fd56170 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -12,6 +12,7 @@ #define DEFAULT_SYMBOL_NAMESPACE "I2C_DW_COMMON" #include +#include #include #include #include @@ -34,6 +35,10 @@ #include "i2c-designware-core.h" +#define DW_IC_DEFAULT_BUS_CAPACITANCE_pF 100 +#define DW_IC_ABORT_TIMEOUT_US 10 +#define DW_IC_BUSY_POLL_TIMEOUT_US (1 * USEC_PER_MSEC) + static const char *const abort_sources[] = { [ABRT_7B_ADDR_NOACK] = "slave address not acknowledged (7bit mode)", @@ -106,7 +111,7 @@ static int dw_reg_read_word(void *context, unsigned int reg, unsigned int *val) struct dw_i2c_dev *dev = context; *val = readw(dev->base + reg) | - (readw(dev->base + reg + 2) << 16); + (readw(dev->base + reg + DW_IC_REG_STEP_BYTES) << DW_IC_REG_WORD_SHIFT); return 0; } @@ -116,7 +121,7 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) struct dw_i2c_dev *dev = context; writew(val, dev->base + reg); - writew(val >> 16, dev->base + reg + 2); + writew(val >> DW_IC_REG_WORD_SHIFT, dev->base + reg + DW_IC_REG_STEP_BYTES); return 0; } @@ -131,7 +136,7 @@ static int dw_reg_write_word(void *context, unsigned int reg, unsigned int val) * * Return: 0 on success, or negative errno otherwise. */ -int i2c_dw_init_regmap(struct dw_i2c_dev *dev) +static int i2c_dw_init_regmap(struct dw_i2c_dev *dev) { struct regmap_config map_cfg = { .reg_bits = 32, @@ -165,7 +170,7 @@ int i2c_dw_init_regmap(struct dw_i2c_dev *dev) if (reg == swab32(DW_IC_COMP_TYPE_VALUE)) { map_cfg.reg_read = dw_reg_read_swab; map_cfg.reg_write = dw_reg_write_swab; - } else if (reg == (DW_IC_COMP_TYPE_VALUE & 0x0000ffff)) { + } else if (reg == lower_16_bits(DW_IC_COMP_TYPE_VALUE)) { map_cfg.reg_read = dw_reg_read_word; map_cfg.reg_write = dw_reg_write_word; } else if (reg != DW_IC_COMP_TYPE_VALUE) { @@ -238,14 +243,10 @@ static void i2c_dw_of_configure(struct device *device) struct platform_device *pdev = to_platform_device(device); struct dw_i2c_dev *dev = dev_get_drvdata(device); - switch (dev->flags & MODEL_MASK) { - case MODEL_MSCC_OCELOT: + if (device_is_compatible(dev->dev, "mscc,ocelot-i2c")) { dev->ext = devm_platform_ioremap_resource(pdev, 1); if (!IS_ERR(dev->ext)) dev->set_sda_hold_time = mscc_twi_set_sda_hold_time; - break; - default: - break; } } @@ -358,6 +359,109 @@ static inline u32 i2c_dw_acpi_round_bus_speed(struct device *device) { return 0; #endif /* CONFIG_ACPI */ +static void i2c_dw_configure_mode(struct dw_i2c_dev *dev, int mode) +{ + switch (mode) { + case DW_IC_MASTER: + regmap_write(dev->map, DW_IC_TX_TL, dev->tx_fifo_depth / 2); + regmap_write(dev->map, DW_IC_RX_TL, 0); + regmap_write(dev->map, DW_IC_CON, dev->master_cfg); + break; + case DW_IC_SLAVE: + dev->status = 0; + regmap_write(dev->map, DW_IC_TX_TL, 0); + regmap_write(dev->map, DW_IC_RX_TL, 0); + regmap_write(dev->map, DW_IC_CON, dev->slave_cfg); + regmap_write(dev->map, DW_IC_SAR, dev->slave->addr); + regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK); + __i2c_dw_enable(dev); + break; + default: + WARN(1, "Invalid mode %d\n", mode); + return; + } +} + +static void i2c_dw_write_timings(struct dw_i2c_dev *dev) +{ + /* Write standard speed timing parameters */ + regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt); + regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt); + + /* Write fast mode/fast mode plus timing parameters */ + regmap_write(dev->map, DW_IC_FS_SCL_HCNT, dev->fs_hcnt); + regmap_write(dev->map, DW_IC_FS_SCL_LCNT, dev->fs_lcnt); + + /* Write high speed timing parameters */ + regmap_write(dev->map, DW_IC_HS_SCL_HCNT, dev->hs_hcnt); + regmap_write(dev->map, DW_IC_HS_SCL_LCNT, dev->hs_lcnt); +} + +/** + * i2c_dw_set_mode() - Select the controller mode of operation - master or slave + * @dev: device private data + * @mode: I2C mode of operation + * + * Configures the controller to operate in @mode. This function needs to be + * called when ever a mode swap is required. + * + * Setting the slave mode does not have an effect before a slave device is + * registered. So before the slave device is registered, the controller is kept + * in master mode regardless of @mode. + * + * The controller must be disabled before this function is called. + */ +void i2c_dw_set_mode(struct dw_i2c_dev *dev, int mode) +{ + if (mode == DW_IC_SLAVE && !dev->slave) + mode = DW_IC_MASTER; + if (dev->mode == mode) + return; + + i2c_dw_configure_mode(dev, mode); + dev->mode = mode; +} + +/** + * i2c_dw_init() - Initialize the DesignWare I2C hardware + * @dev: device private data + * + * This functions configures and enables the DesigWare I2C hardware. + * + * Return: 0 on success, or negative errno otherwise. + */ +int i2c_dw_init(struct dw_i2c_dev *dev) +{ + int ret; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* Disable the adapter */ + __i2c_dw_disable(dev); + + /* + * Mask SMBus interrupts to block storms from broken + * firmware that leaves IC_SMBUS=1; the handler never + * services them. + */ + regmap_write(dev->map, DW_IC_SMBUS_INTR_MASK, 0); + + i2c_dw_write_timings(dev); + + /* Write SDA hold time if supported */ + if (dev->sda_hold_time) + regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time); + + i2c_dw_configure_mode(dev, dev->mode); + + i2c_dw_release_lock(dev); + + return 0; +} +EXPORT_SYMBOL_GPL(i2c_dw_init); + static void i2c_dw_adjust_bus_speed(struct dw_i2c_dev *dev) { u32 acpi_speed = i2c_dw_acpi_round_bus_speed(dev->dev); @@ -384,10 +488,16 @@ int i2c_dw_fw_parse_and_configure(struct dw_i2c_dev *dev) i2c_parse_fw_timings(device, t, false); if (device_property_read_u32(device, "snps,bus-capacitance-pf", &dev->bus_capacitance_pF)) - dev->bus_capacitance_pF = 100; + dev->bus_capacitance_pF = DW_IC_DEFAULT_BUS_CAPACITANCE_pF; dev->clk_freq_optimized = device_property_read_bool(device, "snps,clk-freq-optimized"); + /* Mobileye controllers do not hold the clock on empty FIFO */ + if (device_is_compatible(device, "mobileye,eyeq6lplus-i2c")) + dev->emptyfifo_hold_master = false; + else + dev->emptyfifo_hold_master = true; + i2c_dw_adjust_bus_speed(dev); if (is_of_node(fwnode)) @@ -457,7 +567,7 @@ u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, return DIV_ROUND_CLOSEST_ULL((u64)ic_clk * (tLOW + tf), MICRO) - 1 + offset; } -int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) +static int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev) { unsigned int reg; int ret; @@ -539,8 +649,9 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev) regmap_write(dev->map, DW_IC_ENABLE, enable | DW_IC_ENABLE_ABORT); ret = regmap_read_poll_timeout(dev->map, DW_IC_ENABLE, enable, - !(enable & DW_IC_ENABLE_ABORT), 10, - 100); + !(enable & DW_IC_ENABLE_ABORT), + DW_IC_ABORT_TIMEOUT_US, + 10 * DW_IC_ABORT_TIMEOUT_US); if (ret) dev_err(dev->dev, "timeout while trying to abort current transfer\n"); } @@ -552,7 +663,7 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev) * in that case this test reads zero and exits the loop. */ regmap_read(dev->map, DW_IC_ENABLE_STATUS, &status); - if ((status & 1) == 0) + if (!(status & 1)) return; /* @@ -635,7 +746,8 @@ int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) ret = regmap_read_poll_timeout(dev->map, DW_IC_STATUS, status, !(status & DW_IC_STATUS_ACTIVITY), - 1100, 20000); + DW_IC_BUSY_POLL_TIMEOUT_US, + 20 * DW_IC_BUSY_POLL_TIMEOUT_US); if (ret) { dev_warn(dev->dev, "timeout waiting for bus ready\n"); @@ -672,7 +784,7 @@ int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) return -EIO; } -int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) +static int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) { u32 tx_fifo_depth, rx_fifo_depth; unsigned int param; @@ -699,12 +811,12 @@ int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev) if (ret) return ret; - tx_fifo_depth = ((param >> 16) & 0xff) + 1; - rx_fifo_depth = ((param >> 8) & 0xff) + 1; + tx_fifo_depth = FIELD_GET(DW_IC_FIFO_TX_FIELD, param) + 1; + rx_fifo_depth = FIELD_GET(DW_IC_FIFO_RX_FIELD, param) + 1; if (!dev->tx_fifo_depth) { dev->tx_fifo_depth = tx_fifo_depth; dev->rx_fifo_depth = rx_fifo_depth; - } else if (tx_fifo_depth >= 2) { + } else if (tx_fifo_depth >= DW_IC_FIFO_MIN_DEPTH) { dev->tx_fifo_depth = min_t(u32, dev->tx_fifo_depth, tx_fifo_depth); dev->rx_fifo_depth = min_t(u32, dev->rx_fifo_depth, @@ -741,19 +853,117 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) } EXPORT_SYMBOL_GPL(i2c_dw_disable); +static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) +{ + struct dw_i2c_dev *dev = dev_id; + + if (dev->mode == DW_IC_SLAVE) + return i2c_dw_isr_slave(dev); + + return i2c_dw_isr_master(dev); +} + +static const struct i2c_algorithm i2c_dw_algo = { + .xfer = i2c_dw_xfer, + .functionality = i2c_dw_func, +#if IS_ENABLED(CONFIG_I2C_SLAVE) + .reg_slave = i2c_dw_reg_slave, + .unreg_slave = i2c_dw_unreg_slave, +#endif +}; + +static const struct i2c_adapter_quirks i2c_dw_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN, +}; + int i2c_dw_probe(struct dw_i2c_dev *dev) { + struct i2c_adapter *adap = &dev->adapter; + unsigned long irq_flags; + int ret; + device_set_node(&dev->adapter.dev, dev_fwnode(dev->dev)); - switch (dev->mode) { - case DW_IC_SLAVE: - return i2c_dw_probe_slave(dev); - case DW_IC_MASTER: - return i2c_dw_probe_master(dev); - default: - dev_err(dev->dev, "Wrong operation mode: %d\n", dev->mode); - return -EINVAL; + ret = i2c_dw_init_regmap(dev); + if (ret) + return ret; + + ret = i2c_dw_set_sda_hold(dev); + if (ret) + return ret; + + ret = i2c_dw_set_fifo_size(dev); + if (ret) + return ret; + + ret = i2c_dw_probe_master(dev); + if (ret) + return ret; + + ret = i2c_dw_init(dev); + if (ret) + return ret; + + if (!adap->name[0]) + strscpy(adap->name, "Synopsys DesignWare I2C adapter"); + + adap->retries = 3; + adap->algo = &i2c_dw_algo; + adap->quirks = &i2c_dw_quirks; + adap->dev.parent = dev->dev; + i2c_set_adapdata(adap, dev); + + /* + * REVISIT: The mode check may not be necessary. + * For now keeping the flags as they were originally. + */ + if (dev->mode == DW_IC_SLAVE) + irq_flags = IRQF_SHARED; + else if (dev->flags & ACCESS_NO_IRQ_SUSPEND) + irq_flags = IRQF_NO_SUSPEND; + else + irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; + + /* + * The first writing to TX FIFO buffer causes transmission start. + * If IC_EMPTYFIFO_HOLD_MASTER_EN is not set, when TX FIFO gets + * empty, I2C controller finishes the transaction. If writing to + * FIFO is interrupted, FIFO can get empty and the transaction will + * be finished prematurely. FIFO buffer is filled in IRQ handler, + * but in PREEMPT_RT kernel IRQ handler by default is executed + * in thread that can be preempted with another higher priority + * thread or an interrupt. So, IRQF_NO_THREAD flag is required in + * order to prevent any preemption when filling the FIFO. + */ + if (!dev->emptyfifo_hold_master) + irq_flags |= IRQF_NO_THREAD; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + __i2c_dw_write_intr_mask(dev, 0); + i2c_dw_release_lock(dev); + + if (!(dev->flags & ACCESS_POLLING)) { + ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, + irq_flags, dev_name(dev->dev), dev); + if (ret) + return ret; } + + /* + * Increment PM usage count during adapter registration in order to + * avoid possible spurious runtime suspend when adapter device is + * registered to the device core and immediate resume in case bus has + * registered I2C slaves that do I2C transfers in their probe. + */ + ACQUIRE(pm_runtime_noresume, pm)(dev->dev); + ret = ACQUIRE_ERR(pm_runtime_noresume, &pm); + if (ret) + return ret; + + return i2c_add_numbered_adapter(adap); } EXPORT_SYMBOL_GPL(i2c_dw_probe); @@ -797,7 +1007,7 @@ static int i2c_dw_runtime_resume(struct device *device) if (!dev->shared_with_punit) i2c_dw_prepare_clk(dev, true); - dev->init(dev); + i2c_dw_init(dev); return 0; } diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index bb5ce0a382f9..9d8d104cc391 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,19 @@ #define DW_IC_DATA_CMD_DAT GENMASK(7, 0) #define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11) +/* + * Register access parameters + */ +#define DW_IC_REG_STEP_BYTES 2 +#define DW_IC_REG_WORD_SHIFT 16 + +/* + * FIFO depth configuration + */ +#define DW_IC_FIFO_TX_FIELD GENMASK(23, 16) +#define DW_IC_FIFO_RX_FIELD GENMASK(15, 8) +#define DW_IC_FIFO_MIN_DEPTH 2 + /* * Registers offset */ @@ -239,7 +253,6 @@ struct reset_control; * @semaphore_idx: Index of table with semaphore type attached to the bus. It's * -1 if there is no semaphore. * @shared_with_punit: true if this bus is shared with the SoC's PUNIT - * @init: function to initialize the I2C hardware * @set_sda_hold_time: callback to retrieve IP specific SDA hold timing * @mode: operation mode - DW_IC_MASTER or DW_IC_SLAVE * @rinfo: I²C GPIO recovery information @@ -247,6 +260,8 @@ struct reset_control; * @clk_freq_optimized: if this value is true, it means the hardware reduces * its internal clock frequency by reducing the internal latency required * to generate the high period and low period of SCL line. + * @emptyfifo_hold_master: true if the controller acting as master holds + * the clock when the Tx FIFO is empty instead of emitting a stop. * * HCNT and LCNT parameters can be used if the platform knows more accurate * values than the one computed based only on the input clock frequency. @@ -300,12 +315,12 @@ struct dw_i2c_dev { void (*release_lock)(void); int semaphore_idx; bool shared_with_punit; - int (*init)(struct dw_i2c_dev *dev); int (*set_sda_hold_time)(struct dw_i2c_dev *dev); int mode; struct i2c_bus_recovery_info rinfo; u32 bus_capacitance_pF; bool clk_freq_optimized; + bool emptyfifo_hold_master; }; #define ACCESS_INTR_MASK BIT(0) @@ -313,8 +328,6 @@ struct dw_i2c_dev { #define ARBITRATION_SEMAPHORE BIT(2) #define ACCESS_POLLING BIT(3) -#define MODEL_MSCC_OCELOT BIT(8) -#define MODEL_BAIKAL_BT1 BIT(9) #define MODEL_AMD_NAVI_GPU BIT(10) #define MODEL_WANGXUN_SP BIT(11) #define MODEL_MASK GENMASK(11, 8) @@ -333,20 +346,18 @@ struct i2c_dw_semaphore_callbacks { int (*probe)(struct dw_i2c_dev *dev); }; -int i2c_dw_init_regmap(struct dw_i2c_dev *dev); u32 i2c_dw_scl_hcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, u32 tSYMBOL, u32 tf, int offset); u32 i2c_dw_scl_lcnt(struct dw_i2c_dev *dev, unsigned int reg, u32 ic_clk, u32 tLOW, u32 tf, int offset); -int i2c_dw_set_sda_hold(struct dw_i2c_dev *dev); u32 i2c_dw_clk_rate(struct dw_i2c_dev *dev); int i2c_dw_prepare_clk(struct dw_i2c_dev *dev, bool prepare); int i2c_dw_acquire_lock(struct dw_i2c_dev *dev); void i2c_dw_release_lock(struct dw_i2c_dev *dev); int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); -int i2c_dw_set_fifo_size(struct dw_i2c_dev *dev); u32 i2c_dw_func(struct i2c_adapter *adap); +irqreturn_t i2c_dw_isr_master(struct dw_i2c_dev *dev); extern const struct dev_pm_ops i2c_dw_dev_pm_ops; @@ -386,23 +397,27 @@ void i2c_dw_disable(struct dw_i2c_dev *dev); extern void i2c_dw_configure_master(struct dw_i2c_dev *dev); extern int i2c_dw_probe_master(struct dw_i2c_dev *dev); -#if IS_ENABLED(CONFIG_I2C_DESIGNWARE_SLAVE) +int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); + +#if IS_ENABLED(CONFIG_I2C_SLAVE) extern void i2c_dw_configure_slave(struct dw_i2c_dev *dev); -extern int i2c_dw_probe_slave(struct dw_i2c_dev *dev); +irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev); +int i2c_dw_reg_slave(struct i2c_client *client); +int i2c_dw_unreg_slave(struct i2c_client *client); #else static inline void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { } -static inline int i2c_dw_probe_slave(struct dw_i2c_dev *dev) { return -EINVAL; } +static inline irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev) { return IRQ_NONE; } #endif static inline void i2c_dw_configure(struct dw_i2c_dev *dev) { - if (i2c_detect_slave_mode(dev->dev)) - i2c_dw_configure_slave(dev); - else - i2c_dw_configure_master(dev); + i2c_dw_configure_slave(dev); + i2c_dw_configure_master(dev); } int i2c_dw_probe(struct dw_i2c_dev *dev); +int i2c_dw_init(struct dw_i2c_dev *dev); +void i2c_dw_set_mode(struct dw_i2c_dev *dev, int mode); #if IS_ENABLED(CONFIG_I2C_DESIGNWARE_BAYTRAIL) int i2c_dw_baytrail_probe_lock_support(struct dw_i2c_dev *dev); diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index 45bfca05bb30..de929b91d5ea 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -31,16 +31,6 @@ #define AMD_TIMEOUT_MAX_US 250 #define AMD_MASTERCFG_MASK GENMASK(15, 0) -static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev) -{ - /* Configure Tx/Rx FIFO threshold levels */ - regmap_write(dev->map, DW_IC_TX_TL, dev->tx_fifo_depth / 2); - regmap_write(dev->map, DW_IC_RX_TL, 0); - - /* Configure the I2C master */ - regmap_write(dev->map, DW_IC_CON, dev->master_cfg); -} - static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) { unsigned int comp_param1; @@ -191,66 +181,10 @@ static int i2c_dw_set_timings_master(struct dw_i2c_dev *dev) dev->hs_hcnt, dev->hs_lcnt); } - ret = i2c_dw_set_sda_hold(dev); - if (ret) - return ret; - dev_dbg(dev->dev, "Bus speed: %s\n", i2c_freq_mode_string(t->bus_freq_hz)); return 0; } -/** - * i2c_dw_init_master() - Initialize the DesignWare I2C master hardware - * @dev: device private data - * - * This functions configures and enables the I2C master. - * This function is called during I2C init function, and in case of timeout at - * run time. - * - * Return: 0 on success, or negative errno otherwise. - */ -static int i2c_dw_init_master(struct dw_i2c_dev *dev) -{ - int ret; - - ret = i2c_dw_acquire_lock(dev); - if (ret) - return ret; - - /* Disable the adapter */ - __i2c_dw_disable(dev); - - /* - * Mask SMBus interrupts to block storms from broken - * firmware that leaves IC_SMBUS=1; the handler never - * services them. - */ - regmap_write(dev->map, DW_IC_SMBUS_INTR_MASK, 0); - - /* Write standard speed timing parameters */ - regmap_write(dev->map, DW_IC_SS_SCL_HCNT, dev->ss_hcnt); - regmap_write(dev->map, DW_IC_SS_SCL_LCNT, dev->ss_lcnt); - - /* Write fast mode/fast mode plus timing parameters */ - regmap_write(dev->map, DW_IC_FS_SCL_HCNT, dev->fs_hcnt); - regmap_write(dev->map, DW_IC_FS_SCL_LCNT, dev->fs_lcnt); - - /* Write high speed timing parameters if supported */ - if (dev->hs_hcnt && dev->hs_lcnt) { - regmap_write(dev->map, DW_IC_HS_SCL_HCNT, dev->hs_hcnt); - regmap_write(dev->map, DW_IC_HS_SCL_LCNT, dev->hs_lcnt); - } - - /* Write SDA hold time if supported */ - if (dev->sda_hold_time) - regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time); - - i2c_dw_configure_fifo_master(dev); - i2c_dw_release_lock(dev); - - return 0; -} - static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; @@ -260,6 +194,8 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) /* Disable the adapter */ __i2c_dw_disable(dev); + i2c_dw_set_mode(dev, DW_IC_MASTER); + /* If the slave address is ten bit address, enable 10BITADDR */ if (msgs[dev->msg_write_idx].flags & I2C_M_TEN) { ic_con = DW_IC_CON_10BITADDR_MASTER; @@ -353,14 +289,17 @@ static int i2c_dw_status(struct dw_i2c_dev *dev) * Initiate and continue master read/write transaction with polling * based transfer routine afterward write messages into the Tx buffer. */ -static int amd_i2c_dw_xfer_quirk(struct i2c_adapter *adap, struct i2c_msg *msgs, int num_msgs) +static int amd_i2c_dw_xfer_quirk(struct dw_i2c_dev *dev, struct i2c_msg *msgs, int num_msgs) { - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); int msg_wrt_idx, msg_itr_lmt, buf_len, data_idx; int cmd = 0, status; u8 *tx_buf; unsigned int val; + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev->dev, pm); + if (PM_RUNTIME_ACQUIRE_ERR(&pm)) + return -ENXIO; + /* * In order to enable the interrupt for UCSI i.e. AMD NAVI GPU card, * it is mandatory to set the right value in specific register @@ -438,7 +377,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) struct i2c_msg *msgs = dev->msgs; u32 intr_mask; int tx_limit, rx_limit; - u32 addr = msgs[dev->msg_write_idx].addr; u32 buf_len = dev->tx_buf_len; u8 *buf = dev->tx_buf; bool need_restart = false; @@ -449,18 +387,6 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) for (; dev->msg_write_idx < dev->msgs_num; dev->msg_write_idx++) { u32 flags = msgs[dev->msg_write_idx].flags; - /* - * If target address has changed, we need to - * reprogram the target address in the I2C - * adapter when we are done with this transfer. - */ - if (msgs[dev->msg_write_idx].addr != addr) { - dev_err(dev->dev, - "%s: invalid target address\n", __func__); - dev->msg_err = -EINVAL; - break; - } - if (!(dev->status & STATUS_WRITE_IN_PROGRESS)) { /* new i2c_msg */ buf = msgs[dev->msg_write_idx].buf; @@ -571,7 +497,7 @@ i2c_dw_recv_len(struct dw_i2c_dev *dev, u8 len) * after receiving the first byte. */ len += (flags & I2C_CLIENT_PEC) ? 2 : 1; - dev->tx_buf_len = len - min_t(u8, len, dev->rx_outstanding); + dev->tx_buf_len = len - min(len, dev->rx_outstanding); msgs[dev->msg_read_idx].len = len; msgs[dev->msg_read_idx].flags &= ~I2C_M_RECV_LEN; @@ -593,11 +519,12 @@ i2c_dw_read(struct dw_i2c_dev *dev) unsigned int rx_valid; for (; dev->msg_read_idx < dev->msgs_num; dev->msg_read_idx++) { + u32 flags = msgs[dev->msg_read_idx].flags; unsigned int tmp; u32 len; u8 *buf; - if (!(msgs[dev->msg_read_idx].flags & I2C_M_RD)) + if (!(flags & I2C_M_RD)) continue; if (!(dev->status & STATUS_READ_IN_PROGRESS)) { @@ -611,8 +538,6 @@ i2c_dw_read(struct dw_i2c_dev *dev) regmap_read(dev->map, DW_IC_RXFLR, &rx_valid); for (; len > 0 && rx_valid > 0; len--, rx_valid--) { - u32 flags = msgs[dev->msg_read_idx].flags; - regmap_read(dev->map, DW_IC_DATA_CMD, &tmp); tmp &= DW_IC_DATA_CMD_DAT; /* Ensure length byte is a valid value */ @@ -727,6 +652,14 @@ static void i2c_dw_process_transfer(struct dw_i2c_dev *dev, unsigned int stat) if (stat & DW_IC_INTR_TX_EMPTY) i2c_dw_xfer_msg(dev); + /* Abort if we detect a STOP in the middle of a read or a write */ + if ((stat & DW_IC_INTR_STOP_DET) && + (dev->status & (STATUS_READ_IN_PROGRESS | STATUS_WRITE_IN_PROGRESS))) { + dev_err(dev->dev, "spurious STOP detected\n"); + dev->rx_outstanding = 0; + dev->msg_err = -EIO; + } + /* * No need to modify or disable the interrupt mask here. * i2c_dw_xfer_msg() will take care of it according to @@ -749,9 +682,8 @@ static void i2c_dw_process_transfer(struct dw_i2c_dev *dev, unsigned int stat) * Interrupt service routine. This gets called whenever an I2C master interrupt * occurs. */ -static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) +irqreturn_t i2c_dw_isr_master(struct dw_i2c_dev *dev) { - struct dw_i2c_dev *dev = dev_id; unsigned int stat, enabled; regmap_read(dev->map, DW_IC_ENABLE, &enabled); @@ -809,26 +741,15 @@ static int i2c_dw_wait_transfer(struct dw_i2c_dev *dev) } /* - * Prepare controller for a transaction and call i2c_dw_xfer_msg. + * Prepare controller for a transaction, start the transfer of the @msgs + * and wait for completion, either a STOP or a error. + * Return: 0 or a negative error code. */ static int -i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) +__i2c_dw_xfer_one_part(struct dw_i2c_dev *dev, struct i2c_msg *msgs, size_t num) { - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); int ret; - dev_dbg(dev->dev, "%s: msgs: %d\n", __func__, num); - - pm_runtime_get_sync(dev->dev); - - switch (dev->flags & MODEL_MASK) { - case MODEL_AMD_NAVI_GPU: - ret = amd_i2c_dw_xfer_quirk(adap, msgs, num); - goto done_nolock; - default: - break; - } - reinit_completion(&dev->cmd_complete); dev->msgs = msgs; dev->msgs_num = num; @@ -840,13 +761,9 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) dev->abort_source = 0; dev->rx_outstanding = 0; - ret = i2c_dw_acquire_lock(dev); - if (ret) - goto done_nolock; - ret = i2c_dw_wait_bus_not_busy(dev); if (ret < 0) - goto done; + return ret; /* Start the transfers */ i2c_dw_xfer_init(dev); @@ -855,10 +772,10 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) ret = i2c_dw_wait_transfer(dev); if (ret) { dev_err(dev->dev, "controller timed out\n"); - /* i2c_dw_init_master() implicitly disables the adapter */ + /* i2c_dw_init() implicitly disables the adapter */ i2c_recover_bus(&dev->adapter); - i2c_dw_init_master(dev); - goto done; + i2c_dw_init(dev); + return ret; } /* @@ -881,52 +798,138 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) */ __i2c_dw_disable_nowait(dev); - if (dev->msg_err) { - ret = dev->msg_err; - goto done; - } + if (dev->msg_err) + return dev->msg_err; /* No error */ - if (likely(!dev->cmd_err && !dev->status)) { - ret = num; - goto done; - } + if (likely(!dev->cmd_err && !dev->status)) + return 0; /* We have an error */ - if (dev->cmd_err == DW_IC_ERR_TX_ABRT) { - ret = i2c_dw_handle_tx_abort(dev); - goto done; - } + if (dev->cmd_err == DW_IC_ERR_TX_ABRT) + return i2c_dw_handle_tx_abort(dev); if (dev->status) dev_err(dev->dev, "transfer terminated early - interrupt latency too high?\n"); - ret = -EIO; - -done: - i2c_dw_release_lock(dev); - -done_nolock: - pm_runtime_put_autosuspend(dev->dev); - - return ret; + return -EIO; } -static const struct i2c_algorithm i2c_dw_algo = { - .xfer = i2c_dw_xfer, - .functionality = i2c_dw_func, -}; +/* + * Verify that the message at index @idx can be processed as part + * of a single transaction. The @msgs array contains the messages + * of the transaction. The message is checked against its predecessor + * to ensure that it respects the limitation of the controller. + * Return: true if the message can be processed, false otherwise. + */ +static bool +i2c_dw_msg_is_valid(struct dw_i2c_dev *dev, const struct i2c_msg *msgs, size_t idx) +{ + /* + * The first message of a transaction is valid, + * no constraints from a previous message. + */ + if (!idx) + return true; -static const struct i2c_adapter_quirks i2c_dw_quirks = { - .flags = I2C_AQ_NO_ZERO_LEN, -}; + /* + * We cannot change the target address during a transaction, so make + * sure the address is identical to the one of the previous message. + */ + if (msgs[idx - 1].addr != msgs[idx].addr) { + dev_err(dev->dev, "invalid target address\n"); + return false; + } + + /* + * Make sure we don't need explicit RESTART between two messages + * in the same direction for controllers that cannot emit them. + */ + if (!dev->emptyfifo_hold_master && + (msgs[idx - 1].flags & I2C_M_RD) == (msgs[idx].flags & I2C_M_RD)) { + dev_err(dev->dev, "cannot emit RESTART\n"); + return false; + } + + return true; +} + +static int +i2c_dw_xfer_common(struct dw_i2c_dev *dev, struct i2c_msg msgs[], int num) +{ + struct i2c_msg *msgs_part; + size_t cnt; + int ret; + + dev_dbg(dev->dev, "msgs: %d\n", num); + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev->dev, pm); + if (PM_RUNTIME_ACQUIRE_ERR(&pm)) + return -ENXIO; + + ret = i2c_dw_acquire_lock(dev); + if (ret) + return ret; + + /* + * If the I2C_M_STOP is present in some the messages, + * we do one transaction for each part up to the STOP. + */ + for (msgs_part = msgs; msgs_part < msgs + num; msgs_part += cnt) { + /* + * Count the messages in a transaction, up to a STOP or + * the end of the msgs. The last if below guarantees that + * we check all messages and that msg_parts and cnt are + * in-bounds of msgs and num. + */ + for (cnt = 1; ; cnt++) { + if (!i2c_dw_msg_is_valid(dev, msgs_part, cnt - 1)) { + ret = -EINVAL; + break; + } + + if ((msgs_part[cnt - 1].flags & I2C_M_STOP) || + (msgs_part + cnt == msgs + num)) + break; + } + if (ret < 0) + break; + + /* transfer one part up to a STOP */ + ret = __i2c_dw_xfer_one_part(dev, msgs_part, cnt); + if (ret < 0) + break; + } + + i2c_dw_set_mode(dev, DW_IC_SLAVE); + + i2c_dw_release_lock(dev); + + if (ret < 0) + return ret; + return num; +} + +int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) +{ + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); + + if ((dev->flags & MODEL_MASK) == MODEL_AMD_NAVI_GPU) + return amd_i2c_dw_xfer_quirk(dev, msgs, num); + + return i2c_dw_xfer_common(dev, msgs, num); +} void i2c_dw_configure_master(struct dw_i2c_dev *dev) { struct i2c_timings *t = &dev->timings; - dev->functionality = I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; + dev->functionality |= I2C_FUNC_10BIT_ADDR | DW_IC_DEFAULT_FUNCTIONALITY; + + /* amd_i2c_dw_xfer_quirk() does not implement protocol mangling */ + if ((dev->flags & MODEL_MASK) != MODEL_AMD_NAVI_GPU) + dev->functionality |= I2C_FUNC_PROTOCOL_MANGLING; dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN; @@ -961,7 +964,7 @@ static void i2c_dw_unprepare_recovery(struct i2c_adapter *adap) i2c_dw_prepare_clk(dev, true); reset_control_deassert(dev->rst); - i2c_dw_init_master(dev); + i2c_dw_init(dev); } static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) @@ -1005,27 +1008,15 @@ static int i2c_dw_init_recovery_info(struct dw_i2c_dev *dev) int i2c_dw_probe_master(struct dw_i2c_dev *dev) { - struct i2c_adapter *adap = &dev->adapter; - unsigned long irq_flags; unsigned int ic_con; int ret; init_completion(&dev->cmd_complete); - dev->init = i2c_dw_init_master; - - ret = i2c_dw_init_regmap(dev); - if (ret) - return ret; - ret = i2c_dw_set_timings_master(dev); if (ret) return ret; - ret = i2c_dw_set_fifo_size(dev); - if (ret) - return ret; - /* Lock the bus for accessing DW_IC_CON */ ret = i2c_dw_acquire_lock(dev); if (ret) @@ -1045,60 +1036,8 @@ int i2c_dw_probe_master(struct dw_i2c_dev *dev) if (ic_con & DW_IC_CON_BUS_CLEAR_CTRL) dev->master_cfg |= DW_IC_CON_BUS_CLEAR_CTRL; - ret = dev->init(dev); - if (ret) - return ret; - - if (!adap->name[0]) - scnprintf(adap->name, sizeof(adap->name), - "Synopsys DesignWare I2C adapter"); - adap->retries = 3; - adap->algo = &i2c_dw_algo; - adap->quirks = &i2c_dw_quirks; - adap->dev.parent = dev->dev; - i2c_set_adapdata(adap, dev); - - if (dev->flags & ACCESS_NO_IRQ_SUSPEND) { - irq_flags = IRQF_NO_SUSPEND; - } else { - irq_flags = IRQF_SHARED | IRQF_COND_SUSPEND; - } - - ret = i2c_dw_acquire_lock(dev); - if (ret) - return ret; - - __i2c_dw_write_intr_mask(dev, 0); - i2c_dw_release_lock(dev); - - if (!(dev->flags & ACCESS_POLLING)) { - ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr, - irq_flags, dev_name(dev->dev), dev); - if (ret) - return dev_err_probe(dev->dev, ret, - "failure requesting irq %i: %d\n", - dev->irq, ret); - } - - ret = i2c_dw_init_recovery_info(dev); - if (ret) - return ret; - - /* - * Increment PM usage count during adapter registration in order to - * avoid possible spurious runtime suspend when adapter device is - * registered to the device core and immediate resume in case bus has - * registered I2C slaves that do I2C transfers in their probe. - */ - pm_runtime_get_noresume(dev->dev); - ret = i2c_add_numbered_adapter(adap); - if (ret) - dev_err(dev->dev, "failure adding adapter: %d\n", ret); - pm_runtime_put_noidle(dev->dev); - - return ret; + return i2c_dw_init_recovery_info(dev); } -EXPORT_SYMBOL_GPL(i2c_dw_probe_master); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus master adapter"); MODULE_LICENSE("GPL"); diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 7be99656a67d..426ffec06e22 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c @@ -37,70 +37,6 @@ static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev) return clk_get_rate(dev->clk) / HZ_PER_KHZ; } -#ifdef CONFIG_OF -#define BT1_I2C_CTL 0x100 -#define BT1_I2C_CTL_ADDR_MASK GENMASK(7, 0) -#define BT1_I2C_CTL_WR BIT(8) -#define BT1_I2C_CTL_GO BIT(31) -#define BT1_I2C_DI 0x104 -#define BT1_I2C_DO 0x108 - -static int bt1_i2c_read(void *context, unsigned int reg, unsigned int *val) -{ - struct dw_i2c_dev *dev = context; - int ret; - - /* - * Note these methods shouldn't ever fail because the system controller - * registers are memory mapped. We check the return value just in case. - */ - ret = regmap_write(dev->sysmap, BT1_I2C_CTL, - BT1_I2C_CTL_GO | (reg & BT1_I2C_CTL_ADDR_MASK)); - if (ret) - return ret; - - return regmap_read(dev->sysmap, BT1_I2C_DO, val); -} - -static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val) -{ - struct dw_i2c_dev *dev = context; - int ret; - - ret = regmap_write(dev->sysmap, BT1_I2C_DI, val); - if (ret) - return ret; - - return regmap_write(dev->sysmap, BT1_I2C_CTL, - BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK)); -} - -static const struct regmap_config bt1_i2c_cfg = { - .reg_bits = 32, - .val_bits = 32, - .reg_stride = 4, - .fast_io = true, - .reg_read = bt1_i2c_read, - .reg_write = bt1_i2c_write, - .max_register = DW_IC_COMP_TYPE, -}; - -static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) -{ - dev->sysmap = syscon_node_to_regmap(dev->dev->of_node->parent); - if (IS_ERR(dev->sysmap)) - return PTR_ERR(dev->sysmap); - - dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg); - return PTR_ERR_OR_ZERO(dev->map); -} -#else -static int bt1_i2c_request_regs(struct dw_i2c_dev *dev) -{ - return -ENODEV; -} -#endif - static int dw_i2c_get_parent_regmap(struct dw_i2c_dev *dev) { dev->map = dev_get_regmap(dev->dev->parent, NULL); @@ -127,9 +63,6 @@ static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev) return dw_i2c_get_parent_regmap(dev); switch (dev->flags & MODEL_MASK) { - case MODEL_BAIKAL_BT1: - ret = bt1_i2c_request_regs(dev); - break; case MODEL_WANGXUN_SP: ret = dw_i2c_get_parent_regmap(dev); break; @@ -227,40 +160,32 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) if (ret) return ret; - dev->rst = devm_reset_control_get_optional_exclusive(device, NULL); + dev->rst = devm_reset_control_get_optional_exclusive_deasserted(device, NULL); if (IS_ERR(dev->rst)) return dev_err_probe(device, PTR_ERR(dev->rst), "failed to acquire reset\n"); - reset_control_deassert(dev->rst); - ret = i2c_dw_fw_parse_and_configure(dev); if (ret) - goto exit_reset; + return ret; ret = i2c_dw_probe_lock_support(dev); - if (ret) { - dev_err_probe(device, ret, "failed to probe lock support\n"); - goto exit_reset; - } + if (ret) + return dev_err_probe(device, ret, "failed to probe lock support\n"); i2c_dw_configure(dev); /* Optional interface clock */ dev->pclk = devm_clk_get_optional(device, "pclk"); - if (IS_ERR(dev->pclk)) { - ret = dev_err_probe(device, PTR_ERR(dev->pclk), "failed to acquire pclk\n"); - goto exit_reset; - } + if (IS_ERR(dev->pclk)) + return dev_err_probe(device, PTR_ERR(dev->pclk), "failed to acquire pclk\n"); dev->clk = devm_clk_get_optional(device, NULL); - if (IS_ERR(dev->clk)) { - ret = dev_err_probe(device, PTR_ERR(dev->clk), "failed to acquire clock\n"); - goto exit_reset; - } + if (IS_ERR(dev->clk)) + return dev_err_probe(device, PTR_ERR(dev->clk), "failed to acquire clock\n"); ret = i2c_dw_prepare_clk(dev, true); if (ret) - goto exit_reset; + return ret; if (dev->clk) { struct i2c_timings *t = &dev->timings; @@ -300,17 +225,12 @@ static int dw_i2c_plat_probe(struct platform_device *pdev) pm_runtime_enable(device); ret = i2c_dw_probe(dev); - if (ret) - goto exit_probe; + if (ret) { + dw_i2c_plat_pm_cleanup(dev); + i2c_dw_prepare_clk(dev, false); + } return ret; - -exit_probe: - dw_i2c_plat_pm_cleanup(dev); - i2c_dw_prepare_clk(dev, false); -exit_reset: - reset_control_assert(dev->rst); - return ret; } static void dw_i2c_plat_remove(struct platform_device *pdev) @@ -329,14 +249,12 @@ static void dw_i2c_plat_remove(struct platform_device *pdev) dw_i2c_plat_pm_cleanup(dev); i2c_dw_prepare_clk(dev, false); - - reset_control_assert(dev->rst); } static const struct of_device_id dw_i2c_of_match[] = { - { .compatible = "snps,designware-i2c", }, - { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT }, - { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 }, + { .compatible = "mobileye,eyeq6lplus-i2c" }, + { .compatible = "mscc,ocelot-i2c" }, + { .compatible = "snps,designware-i2c" }, {} }; MODULE_DEVICE_TABLE(of, dw_i2c_of_match); diff --git a/drivers/i2c/busses/i2c-designware-slave.c b/drivers/i2c/busses/i2c-designware-slave.c index 6eb16b7d75a6..ad0d5fbfa6d5 100644 --- a/drivers/i2c/busses/i2c-designware-slave.c +++ b/drivers/i2c/busses/i2c-designware-slave.c @@ -21,74 +21,33 @@ #include "i2c-designware-core.h" -static void i2c_dw_configure_fifo_slave(struct dw_i2c_dev *dev) -{ - /* Configure Tx/Rx FIFO threshold levels. */ - regmap_write(dev->map, DW_IC_TX_TL, 0); - regmap_write(dev->map, DW_IC_RX_TL, 0); - - /* Configure the I2C slave. */ - regmap_write(dev->map, DW_IC_CON, dev->slave_cfg); - regmap_write(dev->map, DW_IC_INTR_MASK, DW_IC_INTR_SLAVE_MASK); -} - -/** - * i2c_dw_init_slave() - Initialize the DesignWare i2c slave hardware - * @dev: device private data - * - * This function configures and enables the I2C in slave mode. - * This function is called during I2C init function, and in case of timeout at - * run time. - * - * Return: 0 on success, or negative errno otherwise. - */ -static int i2c_dw_init_slave(struct dw_i2c_dev *dev) +int i2c_dw_reg_slave(struct i2c_client *slave) { + struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); int ret; + if (!i2c_check_functionality(slave->adapter, I2C_FUNC_SLAVE)) + return -EOPNOTSUPP; + if (dev->slave) + return -EBUSY; + if (slave->flags & I2C_CLIENT_TEN) + return -EAFNOSUPPORT; + ret = i2c_dw_acquire_lock(dev); if (ret) return ret; - /* Disable the adapter. */ - __i2c_dw_disable(dev); + pm_runtime_get_sync(dev->dev); + __i2c_dw_disable_nowait(dev); + dev->slave = slave; + i2c_dw_set_mode(dev, DW_IC_SLAVE); - /* Write SDA hold time if supported */ - if (dev->sda_hold_time) - regmap_write(dev->map, DW_IC_SDA_HOLD, dev->sda_hold_time); - - i2c_dw_configure_fifo_slave(dev); i2c_dw_release_lock(dev); return 0; } -static int i2c_dw_reg_slave(struct i2c_client *slave) -{ - struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); - - if (dev->slave) - return -EBUSY; - if (slave->flags & I2C_CLIENT_TEN) - return -EAFNOSUPPORT; - pm_runtime_get_sync(dev->dev); - - /* - * Set slave address in the IC_SAR register, - * the address to which the DW_apb_i2c responds. - */ - __i2c_dw_disable_nowait(dev); - regmap_write(dev->map, DW_IC_SAR, slave->addr); - dev->slave = slave; - - __i2c_dw_enable(dev); - - dev->status = 0; - - return 0; -} - -static int i2c_dw_unreg_slave(struct i2c_client *slave) +int i2c_dw_unreg_slave(struct i2c_client *slave) { struct dw_i2c_dev *dev = i2c_get_adapdata(slave->adapter); @@ -96,6 +55,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave) i2c_dw_disable(dev); synchronize_irq(dev->irq); dev->slave = NULL; + i2c_dw_set_mode(dev, DW_IC_MASTER); pm_runtime_put_sync_suspend(dev->dev); return 0; @@ -152,9 +112,8 @@ static u32 i2c_dw_read_clear_intrbits_slave(struct dw_i2c_dev *dev) * Interrupt service routine. This gets called whenever an I2C slave interrupt * occurs. */ -static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) +irqreturn_t i2c_dw_isr_slave(struct dw_i2c_dev *dev) { - struct dw_i2c_dev *dev = dev_id; unsigned int raw_stat, stat, enabled, tmp; u8 val = 0, slave_activity; @@ -217,68 +176,18 @@ static irqreturn_t i2c_dw_isr_slave(int this_irq, void *dev_id) return IRQ_HANDLED; } -static const struct i2c_algorithm i2c_dw_algo = { - .functionality = i2c_dw_func, - .reg_slave = i2c_dw_reg_slave, - .unreg_slave = i2c_dw_unreg_slave, -}; - void i2c_dw_configure_slave(struct dw_i2c_dev *dev) { - dev->functionality = I2C_FUNC_SLAVE; + if (dev->flags & ACCESS_POLLING) + return; + + dev->functionality |= I2C_FUNC_SLAVE; dev->slave_cfg = DW_IC_CON_RX_FIFO_FULL_HLD_CTRL | DW_IC_CON_RESTART_EN | DW_IC_CON_STOP_DET_IFADDRESSED; - - dev->mode = DW_IC_SLAVE; } EXPORT_SYMBOL_GPL(i2c_dw_configure_slave); -int i2c_dw_probe_slave(struct dw_i2c_dev *dev) -{ - struct i2c_adapter *adap = &dev->adapter; - int ret; - - dev->init = i2c_dw_init_slave; - - ret = i2c_dw_init_regmap(dev); - if (ret) - return ret; - - ret = i2c_dw_set_sda_hold(dev); - if (ret) - return ret; - - ret = i2c_dw_set_fifo_size(dev); - if (ret) - return ret; - - ret = dev->init(dev); - if (ret) - return ret; - - snprintf(adap->name, sizeof(adap->name), - "Synopsys DesignWare I2C Slave adapter"); - adap->retries = 3; - adap->algo = &i2c_dw_algo; - adap->dev.parent = dev->dev; - i2c_set_adapdata(adap, dev); - - ret = devm_request_irq(dev->dev, dev->irq, i2c_dw_isr_slave, - IRQF_SHARED, dev_name(dev->dev), dev); - if (ret) - return dev_err_probe(dev->dev, ret, - "failure requesting IRQ %i: %d\n", - dev->irq, ret); - - ret = i2c_add_numbered_adapter(adap); - if (ret) - dev_err(dev->dev, "failure adding adapter: %d\n", ret); - - return ret; -} -EXPORT_SYMBOL_GPL(i2c_dw_probe_slave); - MODULE_AUTHOR("Luis Oliveira "); MODULE_DESCRIPTION("Synopsys DesignWare I2C bus slave adapter"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/i2c/busses/i2c-diolan-u2c.c b/drivers/i2c/busses/i2c-diolan-u2c.c index c02459405b26..077b093ba834 100644 --- a/drivers/i2c/busses/i2c-diolan-u2c.c +++ b/drivers/i2c/busses/i2c-diolan-u2c.c @@ -445,7 +445,7 @@ static int diolan_u2c_probe(struct usb_interface *interface, return -ENODEV; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { ret = -ENOMEM; goto error; diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 27ea3c130a16..f83238868802 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c @@ -720,7 +720,7 @@ static int pch_i2c_probe(struct pci_dev *pdev, pch_pci_dbg(pdev, "Entered.\n"); - adap_info = kzalloc((sizeof(struct adapter_info)), GFP_KERNEL); + adap_info = kzalloc_obj(struct adapter_info); if (adap_info == NULL) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-fsi.c b/drivers/i2c/busses/i2c-fsi.c index ae016a9431da..82c87e04ac6f 100644 --- a/drivers/i2c/busses/i2c-fsi.c +++ b/drivers/i2c/busses/i2c-fsi.c @@ -674,8 +674,9 @@ static struct device_node *fsi_i2c_find_port_of_node(struct device_node *fsi, return NULL; } -static int fsi_i2c_probe(struct device *dev) +static int fsi_i2c_probe(struct fsi_device *fsi_dev) { + struct device *dev = &fsi_dev->dev; struct fsi_i2c_ctrl *i2c; struct fsi_i2c_port *port; struct device_node *np; @@ -706,7 +707,7 @@ static int fsi_i2c_probe(struct device *dev) if (!of_device_is_available(np)) continue; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) { of_node_put(np); break; @@ -735,14 +736,14 @@ static int fsi_i2c_probe(struct device *dev) list_add(&port->list, &i2c->ports); } - dev_set_drvdata(dev, i2c); + fsi_set_drvdata(fsi_dev, i2c); return 0; } -static int fsi_i2c_remove(struct device *dev) +static void fsi_i2c_remove(struct fsi_device *fsi_dev) { - struct fsi_i2c_ctrl *i2c = dev_get_drvdata(dev); + struct fsi_i2c_ctrl *i2c = fsi_get_drvdata(fsi_dev); struct fsi_i2c_port *port, *tmp; list_for_each_entry_safe(port, tmp, &i2c->ports, list) { @@ -750,8 +751,6 @@ static int fsi_i2c_remove(struct device *dev) i2c_del_adapter(&port->adapter); kfree(port); } - - return 0; } static const struct fsi_device_id fsi_i2c_ids[] = { @@ -761,11 +760,10 @@ static const struct fsi_device_id fsi_i2c_ids[] = { static struct fsi_driver fsi_i2c_driver = { .id_table = fsi_i2c_ids, + .probe = fsi_i2c_probe, + .remove = fsi_i2c_remove, .drv = { .name = "i2c-fsi", - .bus = &fsi_bus_type, - .probe = fsi_i2c_probe, - .remove = fsi_i2c_remove, }, }; diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index 78c5845e0877..a53b4bb7c3c0 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -365,7 +365,7 @@ static int highlander_i2c_probe(struct platform_device *pdev) return -ENODEV; } - dev = kzalloc(sizeof(struct highlander_i2c_dev), GFP_KERNEL); + dev = kzalloc_obj(struct highlander_i2c_dev); if (unlikely(!dev)) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 9e1789725edf..32a3cef02c7b 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -310,9 +310,10 @@ struct i801_priv { /* * If set to true the host controller registers are reserved for - * ACPI AML use. + * ACPI AML use. Needs extra protection by acpi_lock. */ bool acpi_reserved; + struct mutex acpi_lock; }; #define FEATURE_SMBUS_PEC BIT(0) @@ -894,8 +895,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, int hwpec, ret; struct i801_priv *priv = i2c_get_adapdata(adap); - if (priv->acpi_reserved) + mutex_lock(&priv->acpi_lock); + if (priv->acpi_reserved) { + mutex_unlock(&priv->acpi_lock); return -EBUSY; + } pm_runtime_get_sync(&priv->pci_dev->dev); @@ -935,6 +939,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr, iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv)); pm_runtime_put_autosuspend(&priv->pci_dev->dev); + mutex_unlock(&priv->acpi_lock); return ret; } @@ -1465,7 +1470,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, * further access from the driver itself. This device is now owned * by the system firmware. */ - i2c_lock_bus(&priv->adapter, I2C_LOCK_SEGMENT); + mutex_lock(&priv->acpi_lock); if (!priv->acpi_reserved && i801_acpi_is_smbus_ioport(priv, address)) { priv->acpi_reserved = true; @@ -1485,7 +1490,7 @@ i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits, else status = acpi_os_write_port(address, (u32)*value, bits); - i2c_unlock_bus(&priv->adapter, I2C_LOCK_SEGMENT); + mutex_unlock(&priv->acpi_lock); return status; } @@ -1545,6 +1550,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id) priv->adapter.dev.parent = &dev->dev; acpi_use_parent_companion(&priv->adapter.dev); priv->adapter.retries = 3; + mutex_init(&priv->acpi_lock); priv->pci_dev = dev; priv->features = id->driver_data; diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index 6bf45d752ff9..7c70e8bda24e 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c @@ -687,7 +687,7 @@ static int iic_probe(struct platform_device *ofdev) const u32 *freq; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index d882126c1778..a01c23696481 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c @@ -5,6 +5,7 @@ * Copyright 2016 Freescale Semiconductor, Inc. */ +#include #include #include #include @@ -90,6 +91,7 @@ #define MRDR_RXEMPTY BIT(14) #define MDER_TDDE BIT(0) #define MDER_RDDE BIT(1) +#define MSR_RDF_ASSERTED(x) FIELD_GET(MSR_RDF, (x)) #define SCR_SEN BIT(0) #define SCR_RST BIT(1) @@ -131,6 +133,7 @@ #define CHUNK_DATA 256 #define I2C_PM_TIMEOUT 10 /* ms */ +#define I2C_PM_LONG_TIMEOUT_MS 1000 /* Avoid dead lock caused by big clock prepare lock */ #define I2C_DMA_THRESHOLD 8 /* bytes */ enum lpi2c_imx_mode { @@ -148,6 +151,11 @@ enum lpi2c_imx_pincfg { FOUR_PIN_PP, }; +struct imx_lpi2c_hwdata { + bool need_request_free_irq; /* Needed by irqsteer */ + bool need_prepare_unprepare_clk; /* Needed by LPCG */ +}; + struct lpi2c_imx_dma { bool using_pio_mode; u8 rx_cmd_buf_len; @@ -186,6 +194,21 @@ struct lpi2c_imx_struct { bool can_use_dma; struct lpi2c_imx_dma *dma; struct i2c_client *target; + int irq; + const struct imx_lpi2c_hwdata *hwdata; +}; + +static const struct imx_lpi2c_hwdata imx7ulp_lpi2c_hwdata = { +}; + +static const struct imx_lpi2c_hwdata imx8qxp_lpi2c_hwdata = { + .need_request_free_irq = true, + .need_prepare_unprepare_clk = true, +}; + +static const struct imx_lpi2c_hwdata imx8qm_lpi2c_hwdata = { + .need_request_free_irq = true, + .need_prepare_unprepare_clk = true, }; #define lpi2c_imx_read_msr_poll_timeout(atomic, val, cond) \ @@ -461,7 +484,7 @@ static bool lpi2c_imx_write_txfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atom static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomic) { - unsigned int blocklen, remaining; + unsigned int remaining; unsigned int temp, data; do { @@ -472,15 +495,6 @@ static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomi lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff; } while (1); - /* - * First byte is the length of remaining packet in the SMBus block - * data read. Add it to msgs->len. - */ - if (lpi2c_imx->block_data) { - blocklen = lpi2c_imx->rx_buf[0]; - lpi2c_imx->msglen += blocklen; - } - remaining = lpi2c_imx->msglen - lpi2c_imx->delivered; if (!remaining) { @@ -493,12 +507,7 @@ static bool lpi2c_imx_read_rxfifo(struct lpi2c_imx_struct *lpi2c_imx, bool atomi lpi2c_imx_set_rx_watermark(lpi2c_imx); /* multiple receive commands */ - if (lpi2c_imx->block_data) { - lpi2c_imx->block_data = 0; - temp = remaining; - temp |= (RECV_DATA << 8); - writel(temp, lpi2c_imx->base + LPI2C_MTDR); - } else if (!(lpi2c_imx->delivered & 0xff)) { + if (!(lpi2c_imx->delivered & 0xff)) { temp = (remaining > CHUNK_DATA ? CHUNK_DATA : remaining) - 1; temp |= (RECV_DATA << 8); writel(temp, lpi2c_imx->base + LPI2C_MTDR); @@ -536,18 +545,77 @@ static int lpi2c_imx_write_atomic(struct lpi2c_imx_struct *lpi2c_imx, return err; } -static void lpi2c_imx_read_init(struct lpi2c_imx_struct *lpi2c_imx, - struct i2c_msg *msgs) +static unsigned int lpi2c_SMBus_block_read_length_byte(struct lpi2c_imx_struct *lpi2c_imx) { - unsigned int temp; + unsigned int data; + + data = readl(lpi2c_imx->base + LPI2C_MRDR); + lpi2c_imx->rx_buf[lpi2c_imx->delivered++] = data & 0xff; + + return data; +} + +static int lpi2c_imx_read_init(struct lpi2c_imx_struct *lpi2c_imx, + struct i2c_msg *msgs) +{ + unsigned int temp, val, block_len; + int ret; lpi2c_imx->rx_buf = msgs->buf; lpi2c_imx->block_data = msgs->flags & I2C_M_RECV_LEN; lpi2c_imx_set_rx_watermark(lpi2c_imx); - temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1; - temp |= (RECV_DATA << 8); - writel(temp, lpi2c_imx->base + LPI2C_MTDR); + + if (!lpi2c_imx->block_data) { + temp = msgs->len > CHUNK_DATA ? CHUNK_DATA - 1 : msgs->len - 1; + temp |= (RECV_DATA << 8); + writel(temp, lpi2c_imx->base + LPI2C_MTDR); + } else { + /* + * The LPI2C controller automatically sends a NACK after the last byte of a + * receive command, unless the next command in MTDR is also a receive command. + * If MTDR is empty when a receive completes, a NACK is sent by default. + * + * To comply with the SMBus block read spec, we start with a 2-byte read: + * The first byte in RXFIFO is the block length. Once this byte arrives, the + * controller immediately updates MTDR with the next read command, ensuring + * continuous ACK instead of NACK. + * + * The second byte is the first block data byte. Therefore, the subsequent + * read command should request (block_len - 1) bytes, since one data byte + * has already been read. + */ + + writel((RECV_DATA << 8) | 0x01, lpi2c_imx->base + LPI2C_MTDR); + + ret = readl_poll_timeout(lpi2c_imx->base + LPI2C_MSR, val, + MSR_RDF_ASSERTED(val), 1, 1000); + if (ret) { + dev_err(&lpi2c_imx->adapter.dev, "SMBus read count failed %d\n", ret); + return ret; + } + + /* Read block length byte and confirm this SMBus transfer meets protocol */ + block_len = lpi2c_SMBus_block_read_length_byte(lpi2c_imx); + if (block_len == 0 || block_len > I2C_SMBUS_BLOCK_MAX) { + dev_err(&lpi2c_imx->adapter.dev, "Invalid SMBus block read length\n"); + return -EPROTO; + } + + /* + * When block_len shows more bytes need to be read, update second read command to + * keep MTDR non-empty and ensuring continuous ACKs. Only update command register + * here. All block bytes will be read out at IRQ handler or lpi2c_imx_read_atomic() + * function. + */ + if (block_len > 1) + writel((RECV_DATA << 8) | (block_len - 2), lpi2c_imx->base + LPI2C_MTDR); + + lpi2c_imx->msglen += block_len; + msgs->len += block_len; + } + + return 0; } static bool lpi2c_imx_read_chunk_atomic(struct lpi2c_imx_struct *lpi2c_imx) @@ -592,6 +660,10 @@ static bool is_use_dma(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg) if (!lpi2c_imx->can_use_dma) return false; + /* DMA is not suitable for SMBus block read */ + if (msg->flags & I2C_M_RECV_LEN) + return false; + /* * A system-wide suspend or resume transition is in progress. LPI2C should use PIO to * transfer data to avoid issue caused by no ready DMA HW resource. @@ -609,10 +681,14 @@ static bool is_use_dma(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg) static int lpi2c_imx_pio_xfer(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg) { + int ret; + reinit_completion(&lpi2c_imx->complete); if (msg->flags & I2C_M_RD) { - lpi2c_imx_read_init(lpi2c_imx, msg); + ret = lpi2c_imx_read_init(lpi2c_imx, msg); + if (ret) + return ret; lpi2c_imx_intctrl(lpi2c_imx, MIER_RDIE | MIER_NDIE); } else { lpi2c_imx_write(lpi2c_imx, msg); @@ -624,8 +700,12 @@ static int lpi2c_imx_pio_xfer(struct lpi2c_imx_struct *lpi2c_imx, static int lpi2c_imx_pio_xfer_atomic(struct lpi2c_imx_struct *lpi2c_imx, struct i2c_msg *msg) { + int ret; + if (msg->flags & I2C_M_RD) { - lpi2c_imx_read_init(lpi2c_imx, msg); + ret = lpi2c_imx_read_init(lpi2c_imx, msg); + if (ret) + return ret; return lpi2c_imx_read_atomic(lpi2c_imx, msg); } @@ -1370,7 +1450,9 @@ static const struct i2c_algorithm lpi2c_imx_algo = { }; static const struct of_device_id lpi2c_imx_of_match[] = { - { .compatible = "fsl,imx7ulp-lpi2c" }, + { .compatible = "fsl,imx7ulp-lpi2c", .data = &imx7ulp_lpi2c_hwdata,}, + { .compatible = "fsl,imx8qxp-lpi2c", .data = &imx8qxp_lpi2c_hwdata,}, + { .compatible = "fsl,imx8qm-lpi2c", .data = &imx8qm_lpi2c_hwdata,}, { } }; MODULE_DEVICE_TABLE(of, lpi2c_imx_of_match); @@ -1381,19 +1463,23 @@ static int lpi2c_imx_probe(struct platform_device *pdev) struct resource *res; dma_addr_t phy_addr; unsigned int temp; - int irq, ret; + int ret; lpi2c_imx = devm_kzalloc(&pdev->dev, sizeof(*lpi2c_imx), GFP_KERNEL); if (!lpi2c_imx) return -ENOMEM; + lpi2c_imx->hwdata = of_device_get_match_data(&pdev->dev); + if (!lpi2c_imx->hwdata) + return -ENODEV; + lpi2c_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(lpi2c_imx->base)) return PTR_ERR(lpi2c_imx->base); - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; + lpi2c_imx->irq = platform_get_irq(pdev, 0); + if (lpi2c_imx->irq < 0) + return lpi2c_imx->irq; lpi2c_imx->adapter.owner = THIS_MODULE; lpi2c_imx->adapter.algo = &lpi2c_imx_algo; @@ -1413,10 +1499,10 @@ static int lpi2c_imx_probe(struct platform_device *pdev) if (ret) lpi2c_imx->bitrate = I2C_MAX_STANDARD_MODE_FREQ; - ret = devm_request_irq(&pdev->dev, irq, lpi2c_imx_isr, IRQF_NO_SUSPEND, + ret = devm_request_irq(&pdev->dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND, pdev->name, lpi2c_imx); if (ret) - return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", irq); + return dev_err_probe(&pdev->dev, ret, "can't claim irq %d\n", lpi2c_imx->irq); i2c_set_adapdata(&lpi2c_imx->adapter, lpi2c_imx); platform_set_drvdata(pdev, lpi2c_imx); @@ -1439,7 +1525,11 @@ static int lpi2c_imx_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, -EINVAL, "can't get I2C peripheral clock rate\n"); - pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); + if (lpi2c_imx->hwdata->need_prepare_unprepare_clk) + pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_LONG_TIMEOUT_MS); + else + pm_runtime_set_autosuspend_delay(&pdev->dev, I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_get_noresume(&pdev->dev); pm_runtime_set_active(&pdev->dev); @@ -1494,8 +1584,16 @@ static void lpi2c_imx_remove(struct platform_device *pdev) static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) { struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); + bool need_prepare_unprepare_clk = lpi2c_imx->hwdata->need_prepare_unprepare_clk; + bool need_request_free_irq = lpi2c_imx->hwdata->need_request_free_irq; - clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks); + if (need_request_free_irq) + devm_free_irq(dev, lpi2c_imx->irq, lpi2c_imx); + + if (need_prepare_unprepare_clk) + clk_bulk_disable_unprepare(lpi2c_imx->num_clks, lpi2c_imx->clks); + else + clk_bulk_disable(lpi2c_imx->num_clks, lpi2c_imx->clks); pinctrl_pm_select_sleep_state(dev); return 0; @@ -1504,13 +1602,32 @@ static int __maybe_unused lpi2c_runtime_suspend(struct device *dev) static int __maybe_unused lpi2c_runtime_resume(struct device *dev) { struct lpi2c_imx_struct *lpi2c_imx = dev_get_drvdata(dev); + bool need_prepare_unprepare_clk = lpi2c_imx->hwdata->need_prepare_unprepare_clk; + bool need_request_free_irq = lpi2c_imx->hwdata->need_request_free_irq; int ret; pinctrl_pm_select_default_state(dev); - ret = clk_bulk_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); - if (ret) { - dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret); - return ret; + if (need_prepare_unprepare_clk) { + ret = clk_bulk_prepare_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); + if (ret) { + dev_err(dev, "failed to enable I2C clock, ret=%d\n", ret); + return ret; + } + } else { + ret = clk_bulk_enable(lpi2c_imx->num_clks, lpi2c_imx->clks); + if (ret) { + dev_err(dev, "failed to enable clock %d\n", ret); + return ret; + } + } + + if (need_request_free_irq) { + ret = devm_request_irq(dev, lpi2c_imx->irq, lpi2c_imx_isr, IRQF_NO_SUSPEND, + dev_name(dev), lpi2c_imx); + if (ret) { + dev_err(dev, "can't claim irq %d\n", lpi2c_imx->irq); + return ret; + } } return 0; diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index ce5ca5b90b39..4c67c5d18f34 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c @@ -415,13 +415,13 @@ iop3xx_i2c_probe(struct platform_device *pdev) struct i2c_adapter *new_adapter; struct i2c_algo_iop3xx_data *adapter_data; - new_adapter = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); + new_adapter = kzalloc_obj(struct i2c_adapter); if (!new_adapter) { ret = -ENOMEM; goto out; } - adapter_data = kzalloc(sizeof(struct i2c_algo_iop3xx_data), GFP_KERNEL); + adapter_data = kzalloc_obj(struct i2c_algo_iop3xx_data); if (!adapter_data) { ret = -ENOMEM; goto free_adapter; diff --git a/drivers/i2c/busses/i2c-k1.c b/drivers/i2c/busses/i2c-k1.c index 8ef6d5d1927b..6e93da576bbd 100644 --- a/drivers/i2c/busses/i2c-k1.c +++ b/drivers/i2c/busses/i2c-k1.c @@ -4,12 +4,13 @@ */ #include - #include - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include +#include +#include /* spacemit i2c registers */ #define SPACEMIT_ICR 0x0 /* Control register */ @@ -534,6 +535,7 @@ static int spacemit_i2c_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct device_node *of_node = pdev->dev.of_node; struct spacemit_i2c_dev *i2c; + struct reset_control *rst; int ret; i2c = devm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL); @@ -578,6 +580,11 @@ static int spacemit_i2c_probe(struct platform_device *pdev) if (IS_ERR(clk)) return dev_err_probe(dev, PTR_ERR(clk), "failed to enable bus clock"); + rst = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); + if (IS_ERR(rst)) + return dev_err_probe(dev, PTR_ERR(rst), + "failed to acquire deasserted reset\n"); + spacemit_i2c_reset(i2c); i2c_set_adapdata(&i2c->adapt, i2c); diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index 8345f7e6385d..6c1cfe9ec8ac 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c @@ -20,6 +20,7 @@ #include #include #include +#include /* Defines what functionality is present. */ #define MLXBF_I2C_FUNC_SMBUS_BLOCK \ @@ -65,15 +66,13 @@ * strongly dependent on the core clock frequency of the SMBus * Master. Default value is set to 400MHz. */ -#define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * 1000 * 1000) +#define MLXBF_I2C_TYU_PLL_OUT_FREQ (400 * HZ_PER_MHZ) /* Reference clock for Bluefield - 156 MHz. */ #define MLXBF_I2C_PLL_IN_FREQ 156250000ULL /* Constant used to determine the PLL frequency. */ #define MLNXBF_I2C_COREPLL_CONST 16384ULL -#define MLXBF_I2C_FREQUENCY_1GHZ 1000000000ULL - /* PLL registers. */ #define MLXBF_I2C_CORE_PLL_REG1 0x4 #define MLXBF_I2C_CORE_PLL_REG2 0x8 @@ -325,12 +324,6 @@ .name = (str) \ } -enum { - MLXBF_I2C_TIMING_100KHZ = 100000, - MLXBF_I2C_TIMING_400KHZ = 400000, - MLXBF_I2C_TIMING_1000KHZ = 1000000, -}; - enum { MLXBF_I2C_F_READ = BIT(0), MLXBF_I2C_F_WRITE = BIT(1), @@ -1083,7 +1076,7 @@ static u32 mlxbf_i2c_get_ticks(struct mlxbf_i2c_priv *priv, u64 nanoseconds, * Frequency */ frequency = priv->frequency; - ticks = div_u64(nanoseconds * frequency, MLXBF_I2C_FREQUENCY_1GHZ); + ticks = div_u64(nanoseconds * frequency, HZ_PER_GHZ); /* * The number of ticks is rounded down and if minimum is equal to 1 * then add one tick. diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c index aefdbee1f03c..cb4d3aa709d0 100644 --- a/drivers/i2c/busses/i2c-mt65xx.c +++ b/drivers/i2c/busses/i2c-mt65xx.c @@ -24,6 +24,7 @@ #include #include #include +#include #define I2C_RS_TRANSFER (1 << 4) #define I2C_ARB_LOST (1 << 3) @@ -685,7 +686,7 @@ static int mtk_i2c_get_clk_div_restri(struct mtk_i2c *i2c, * Check and Calculate i2c ac-timing * * Hardware design: - * sample_ns = (1000000000 * (sample_cnt + 1)) / clk_src + * sample_ns = (HZ_PER_GHZ * (sample_cnt + 1)) / clk_src * xxx_cnt_div = spec->min_xxx_ns / sample_ns * * Sample_ns is rounded down for xxx_cnt_div would be greater @@ -701,9 +702,8 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c, { const struct i2c_spec_values *spec; unsigned int su_sta_cnt, low_cnt, high_cnt, max_step_cnt; - unsigned int sda_max, sda_min, clk_ns, max_sta_cnt = 0x3f; - unsigned int sample_ns = div_u64(1000000000ULL * (sample_cnt + 1), - clk_src); + unsigned int sda_max, sda_min, max_sta_cnt = 0x3f; + unsigned int clk_ns, sample_ns; if (!i2c->dev_comp->timing_adjust) return 0; @@ -713,8 +713,9 @@ static int mtk_i2c_check_ac_timing(struct mtk_i2c *i2c, spec = mtk_i2c_get_spec(check_speed); + sample_ns = div_u64(1ULL * HZ_PER_GHZ * (sample_cnt + 1), clk_src); if (i2c->dev_comp->ltiming_adjust) - clk_ns = 1000000000 / clk_src; + clk_ns = HZ_PER_GHZ / clk_src; else clk_ns = sample_ns / 2; diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index d58a308582e4..7064fab81eac 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c @@ -359,7 +359,7 @@ static int nforce2_probe(struct pci_dev *dev, const struct pci_device_id *id) int res1, res2; /* we support 2 SMBus adapters */ - smbuses = kcalloc(2, sizeof(struct nforce2_smbus), GFP_KERNEL); + smbuses = kzalloc_objs(struct nforce2_smbus, 2); if (!smbuses) return -ENOMEM; pci_set_drvdata(dev, smbuses); diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index 19b648fc094d..b63ee51c1652 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -31,6 +31,7 @@ #include #include #include +#include #define DRIVER_NAME "nmk-i2c" @@ -419,10 +420,10 @@ static void setup_i2c_controller(struct nmk_i2c_dev *priv) * modes are 250ns, 100ns, 10ns respectively. * * As the time for one cycle T in nanoseconds is - * T = (1/f) * 1000000000 => - * slsu = cycles / (1000000000 / f) + 1 + * T = (1/f) * HZ_PER_GHZ => + * slsu = cycles / (HZ_PER_GHZ / f) + 1 */ - ns = DIV_ROUND_UP_ULL(1000000000ULL, i2c_clk); + ns = DIV_ROUND_UP(HZ_PER_GHZ, i2c_clk); switch (priv->sm) { case I2C_FREQ_MODE_FAST: case I2C_FREQ_MODE_FAST_PLUS: diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 3249bbd5eb43..e438ec8175d9 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c @@ -288,7 +288,7 @@ static void i2c_parport_attach(struct parport *port) return; } - adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL); + adapter = kzalloc_obj(struct i2c_par); if (!adapter) return; memset(&i2c_parport_cb, 0, sizeof(i2c_parport_cb)); diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index ac3bb550303f..7b6a4e201be4 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c @@ -919,7 +919,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, struct i2c_piix4_adapdata *adapdata; int retval; - adap = kzalloc(sizeof(*adap), GFP_KERNEL); + adap = kzalloc_obj(*adap); if (adap == NULL) { release_region(smba, SMBIOSIZE); return -ENOMEM; @@ -930,7 +930,7 @@ static int piix4_add_adapter(struct pci_dev *dev, unsigned short smba, adap->algo = sb800_main ? &piix4_smbus_algorithm_sb800 : &smbus_algorithm; - adapdata = kzalloc(sizeof(*adapdata), GFP_KERNEL); + adapdata = kzalloc_obj(*adapdata); if (adapdata == NULL) { kfree(adap); release_region(smba, SMBIOSIZE); diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c index af2094720a4d..dbd542300f80 100644 --- a/drivers/i2c/busses/i2c-pxa-pci.c +++ b/drivers/i2c/busses/i2c-pxa-pci.c @@ -112,7 +112,7 @@ static int ce4100_i2c_probe(struct pci_dev *dev, dev_err(&dev->dev, "Missing device tree node.\n"); return -EINVAL; } - sds = kzalloc(sizeof(*sds), GFP_KERNEL); + sds = kzalloc_obj(*sds); if (!sds) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index ae609bdd2ec4..a4acb78fafb6 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c @@ -799,7 +799,7 @@ static int geni_i2c_gpi_xfer(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], i if (gi2c->is_tx_multi_desc_xfer) { tx_multi_xfer->dma_buf = kcalloc(num, sizeof(void *), GFP_KERNEL); - tx_multi_xfer->dma_addr = kcalloc(num, sizeof(dma_addr_t), GFP_KERNEL); + tx_multi_xfer->dma_addr = kzalloc_objs(dma_addr_t, num); if (!tx_multi_xfer->dma_buf || !tx_multi_xfer->dma_addr) { ret = -ENOMEM; goto err; diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c index d4e9196445c0..fcede9f6ed54 100644 --- a/drivers/i2c/busses/i2c-rk3x.c +++ b/drivers/i2c/busses/i2c-rk3x.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -896,13 +897,12 @@ static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, unsigned long clk_rate) clk_disable(i2c->pclk); - t_low_ns = div_u64(((u64)calc.div_low + 1) * 8 * 1000000000, clk_rate); - t_high_ns = div_u64(((u64)calc.div_high + 1) * 8 * 1000000000, - clk_rate); + t_low_ns = div_u64(8ULL * HZ_PER_GHZ * (calc.div_low + 1), clk_rate); + t_high_ns = div_u64(8ULL * HZ_PER_GHZ * (calc.div_high + 1), clk_rate); dev_dbg(i2c->dev, - "CLK %lukhz, Req %uns, Act low %lluns high %lluns\n", - clk_rate / 1000, - 1000000000 / t->bus_freq_hz, + "CLK %lukHz, Req %luns, Act low %lluns high %lluns\n", + clk_rate / HZ_PER_KHZ, + HZ_PER_GHZ / t->bus_freq_hz, t_low_ns, t_high_ns); } diff --git a/drivers/i2c/busses/i2c-rtl9300.c b/drivers/i2c/busses/i2c-rtl9300.c index 4723e48cfe18..672cb978066d 100644 --- a/drivers/i2c/busses/i2c-rtl9300.c +++ b/drivers/i2c/busses/i2c-rtl9300.c @@ -129,7 +129,7 @@ static int rtl9310_i2c_select_scl(struct rtl9300_i2c *i2c, u8 scl) static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_chan *chan) { - struct rtl9300_i2c_drv_data *drv_data; + const struct rtl9300_i2c_drv_data *drv_data; int ret; if (i2c->sda_num == chan->sda_num) @@ -139,7 +139,7 @@ static int rtl9300_i2c_config_chan(struct rtl9300_i2c *i2c, struct rtl9300_i2c_c if (ret) return ret; - drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev); + drv_data = device_get_match_data(i2c->dev); ret = drv_data->select_scl(i2c, i2c->scl_num); if (ret) return ret; @@ -371,8 +371,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rtl9300_i2c *i2c; - struct fwnode_handle *child; - struct rtl9300_i2c_drv_data *drv_data; + const struct rtl9300_i2c_drv_data *drv_data; struct reg_field fields[F_NUM_FIELDS]; u32 clock_freq, scl_num, sda_num; int ret, i = 0; @@ -399,7 +398,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev) platform_set_drvdata(pdev, i2c); - drv_data = (struct rtl9300_i2c_drv_data *)device_get_match_data(i2c->dev); + drv_data = device_get_match_data(i2c->dev); if (device_get_child_node_count(dev) > drv_data->max_nchan) return dev_err_probe(dev, -EINVAL, "Too many channels\n"); @@ -415,15 +414,15 @@ static int rtl9300_i2c_probe(struct platform_device *pdev) return ret; i = 0; - device_for_each_child_node(dev, child) { + for_each_child_of_node_scoped(dev->of_node, child) { struct rtl9300_i2c_chan *chan = &i2c->chans[i]; struct i2c_adapter *adap = &chan->adap; - ret = fwnode_property_read_u32(child, "reg", &sda_num); + ret = of_property_read_u32(child, "reg", &sda_num); if (ret) return ret; - ret = fwnode_property_read_u32(child, "clock-frequency", &clock_freq); + ret = of_property_read_u32(child, "clock-frequency", &clock_freq); if (ret) clock_freq = I2C_MAX_STANDARD_MODE_FREQ; @@ -449,7 +448,7 @@ static int rtl9300_i2c_probe(struct platform_device *pdev) adap->retries = 3; adap->dev.parent = dev; i2c_set_adapdata(adap, chan); - adap->dev.of_node = to_of_node(child); + adap->dev.of_node = child; snprintf(adap->name, sizeof(adap->name), "%s SDA%d\n", dev_name(dev), sda_num); i++; diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 10a5146b3aa5..324a63efa1ab 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c @@ -359,7 +359,7 @@ static int smbus_cmi_probe(struct platform_device *device) struct acpi_smbus_cmi *smbus_cmi; int ret; - smbus_cmi = kzalloc(sizeof(struct acpi_smbus_cmi), GFP_KERNEL); + smbus_cmi = kzalloc_obj(struct acpi_smbus_cmi); if (!smbus_cmi) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index 43f33988b98f..ba0cbb36ab15 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c @@ -443,7 +443,7 @@ static int sh7760_i2c_probe(struct platform_device *pdev) goto out0; } - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { ret = -ENOMEM; goto out0; diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index d90606048611..b4ca256a0aa9 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c @@ -64,7 +64,7 @@ static int simtec_i2c_probe(struct platform_device *dev) int size; int ret; - pd = kzalloc(sizeof(struct simtec_i2c_data), GFP_KERNEL); + pd = kzalloc_obj(struct simtec_i2c_data); if (pd == NULL) return -ENOMEM; diff --git a/drivers/i2c/busses/i2c-st.c b/drivers/i2c/busses/i2c-st.c index 97d70e667227..751ea421caaf 100644 --- a/drivers/i2c/busses/i2c-st.c +++ b/drivers/i2c/busses/i2c-st.c @@ -20,6 +20,7 @@ #include #include #include +#include /* SSC registers */ #define SSC_BRG 0x000 @@ -285,7 +286,7 @@ static void st_i2c_hw_config(struct st_i2c_dev *i2c_dev) writel_relaxed(val, i2c_dev->base + SSC_CTL); rate = clk_get_rate(i2c_dev->clk); - ns_per_clk = 1000000000 / rate; + ns_per_clk = HZ_PER_GHZ / rate; /* Baudrate */ val = rate / (2 * t->rate); diff --git a/drivers/i2c/busses/i2c-stm32f7.c b/drivers/i2c/busses/i2c-stm32f7.c index dc69ed934ec8..70cb5822bf17 100644 --- a/drivers/i2c/busses/i2c-stm32f7.c +++ b/drivers/i2c/busses/i2c-stm32f7.c @@ -544,7 +544,7 @@ static int stm32f7_i2c_compute_timing(struct stm32f7_i2c_dev *i2c_dev, if (((sdadel >= sdadel_min) && (sdadel <= sdadel_max)) && (p != p_prev)) { - v = kmalloc(sizeof(*v), GFP_KERNEL); + v = kmalloc_obj(*v); if (!v) { ret = -ENOMEM; goto exit; diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c index 1230f51e1624..4891d68bf0ee 100644 --- a/drivers/i2c/busses/i2c-synquacer.c +++ b/drivers/i2c/busses/i2c-synquacer.c @@ -18,9 +18,10 @@ #include #include #include +#include #define WAIT_PCLK(n, rate) \ - ndelay(DIV_ROUND_UP(DIV_ROUND_UP(1000000000, rate), n) + 10) + ndelay(DIV_ROUND_UP(DIV_ROUND_UP(HZ_PER_GHZ, rate), n) + 10) /* I2C register address definitions */ #define SYNQUACER_I2C_REG_BSR (0x00 << 2) // Bus Status diff --git a/drivers/i2c/busses/i2c-taos-evm.c b/drivers/i2c/busses/i2c-taos-evm.c index cb97f72291bc..debaf5189a83 100644 --- a/drivers/i2c/busses/i2c-taos-evm.c +++ b/drivers/i2c/busses/i2c-taos-evm.c @@ -203,7 +203,7 @@ static int taos_connect(struct serio *serio, struct serio_driver *drv) char *name; int err; - taos = kzalloc(sizeof(struct taos_data), GFP_KERNEL); + taos = kzalloc_obj(struct taos_data); if (!taos) { err = -ENOMEM; goto exit; diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index e533460bccc3..bec619b9af4e 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -85,6 +85,7 @@ #define PACKET_HEADER0_PROTOCOL GENMASK(7, 4) #define PACKET_HEADER0_PROTOCOL_I2C 1 +#define I2C_HEADER_HS_MODE BIT(22) #define I2C_HEADER_CONT_ON_NAK BIT(21) #define I2C_HEADER_READ BIT(19) #define I2C_HEADER_10BIT_ADDR BIT(18) @@ -136,6 +137,14 @@ #define I2C_MASTER_RESET_CNTRL 0x0a8 +#define I2C_SW_MUTEX 0x0ec +#define I2C_SW_MUTEX_REQUEST GENMASK(3, 0) +#define I2C_SW_MUTEX_GRANT GENMASK(7, 4) +#define I2C_SW_MUTEX_ID_CCPLEX 9 + +/* SW mutex acquire timeout value in microseconds. */ +#define I2C_SW_MUTEX_TIMEOUT_US (25 * USEC_PER_MSEC) + /* configuration load timeout in microseconds */ #define I2C_CONFIG_LOAD_TIMEOUT 1000000 @@ -196,16 +205,24 @@ enum msg_end_type { * @has_apb_dma: Support of APBDMA on corresponding Tegra chip. * @tlow_std_mode: Low period of the clock in standard mode. * @thigh_std_mode: High period of the clock in standard mode. - * @tlow_fast_fastplus_mode: Low period of the clock in fast/fast-plus modes. - * @thigh_fast_fastplus_mode: High period of the clock in fast/fast-plus modes. + * @tlow_fast_mode: Low period of the clock in fast mode. + * @thigh_fast_mode: High period of the clock in fast mode. + * @tlow_fastplus_mode: Low period of the clock in fast-plus mode. + * @thigh_fastplus_mode: High period of the clock in fast-plus mode. + * @tlow_hs_mode: Low period of the clock in HS mode. + * @thigh_hs_mode: High period of the clock in HS mode. * @setup_hold_time_std_mode: Setup and hold time for start and stop conditions * in standard mode. - * @setup_hold_time_fast_fast_plus_mode: Setup and hold time for start and stop - * conditions in fast/fast-plus modes. + * @setup_hold_time_fast_mode: Setup and hold time for start and stop + * conditions in fast mode. + * @setup_hold_time_fastplus_mode: Setup and hold time for start and stop + * conditions in fast-plus mode. * @setup_hold_time_hs_mode: Setup and hold time for start and stop conditions * in HS mode. * @has_interface_timing_reg: Has interface timing register to program the tuned * timing settings. + * @enable_hs_mode_support: Enable support for high speed (HS) mode transfers. + * @has_mutex: Has mutex register for mutual exclusion with other firmwares or VMs. */ struct tegra_i2c_hw_feature { bool has_continue_xfer_support; @@ -224,12 +241,19 @@ struct tegra_i2c_hw_feature { bool has_apb_dma; u32 tlow_std_mode; u32 thigh_std_mode; - u32 tlow_fast_fastplus_mode; - u32 thigh_fast_fastplus_mode; + u32 tlow_fast_mode; + u32 thigh_fast_mode; + u32 tlow_fastplus_mode; + u32 thigh_fastplus_mode; + u32 tlow_hs_mode; + u32 thigh_hs_mode; u32 setup_hold_time_std_mode; - u32 setup_hold_time_fast_fast_plus_mode; + u32 setup_hold_time_fast_mode; + u32 setup_hold_time_fastplus_mode; u32 setup_hold_time_hs_mode; bool has_interface_timing_reg; + bool enable_hs_mode_support; + bool has_mutex; }; /** @@ -240,7 +264,6 @@ struct tegra_i2c_hw_feature { * @div_clk: clock reference for div clock of I2C controller * @clocks: array of I2C controller clocks * @nclocks: number of clocks in the array - * @rst: reset control for the I2C controller * @base: ioremapped registers cookie * @base_phys: physical base address of the I2C controller * @cont_id: I2C controller ID, used for packet header @@ -269,7 +292,6 @@ struct tegra_i2c_dev { struct i2c_adapter adapter; const struct tegra_i2c_hw_feature *hw; - struct reset_control *rst; unsigned int cont_id; unsigned int irq; @@ -374,6 +396,76 @@ static void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data, readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len); } +static bool tegra_i2c_mutex_acquired(struct tegra_i2c_dev *i2c_dev) +{ + unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + u32 val, id; + + val = readl(i2c_dev->base + reg); + id = FIELD_GET(I2C_SW_MUTEX_GRANT, val); + + return id == I2C_SW_MUTEX_ID_CCPLEX; +} + +static bool tegra_i2c_mutex_trylock(struct tegra_i2c_dev *i2c_dev) +{ + unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + u32 val, id; + + val = readl(i2c_dev->base + reg); + id = FIELD_GET(I2C_SW_MUTEX_GRANT, val); + if (id != 0 && id != I2C_SW_MUTEX_ID_CCPLEX) + return false; + + val = FIELD_PREP(I2C_SW_MUTEX_REQUEST, I2C_SW_MUTEX_ID_CCPLEX); + writel(val, i2c_dev->base + reg); + + return tegra_i2c_mutex_acquired(i2c_dev); +} + +static int tegra_i2c_mutex_lock(struct tegra_i2c_dev *i2c_dev) +{ + bool locked; + int ret; + + if (!i2c_dev->hw->has_mutex) + return 0; + + if (i2c_dev->atomic_mode) + ret = read_poll_timeout_atomic(tegra_i2c_mutex_trylock, locked, locked, + USEC_PER_MSEC, I2C_SW_MUTEX_TIMEOUT_US, + false, i2c_dev); + else + ret = read_poll_timeout(tegra_i2c_mutex_trylock, locked, locked, USEC_PER_MSEC, + I2C_SW_MUTEX_TIMEOUT_US, false, i2c_dev); + + if (ret) + dev_warn(i2c_dev->dev, "failed to acquire mutex\n"); + + return ret; +} + +static int tegra_i2c_mutex_unlock(struct tegra_i2c_dev *i2c_dev) +{ + unsigned int reg = tegra_i2c_reg_addr(i2c_dev, I2C_SW_MUTEX); + u32 val, id; + + if (!i2c_dev->hw->has_mutex) + return 0; + + val = readl(i2c_dev->base + reg); + + id = FIELD_GET(I2C_SW_MUTEX_GRANT, val); + if (id && id != I2C_SW_MUTEX_ID_CCPLEX) { + dev_warn(i2c_dev->dev, "unable to unlock mutex, mutex is owned by: %u\n", id); + return -EPERM; + } + + writel(0, i2c_dev->base + reg); + + return 0; +} + static void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask) { u32 int_mask; @@ -449,6 +541,11 @@ static int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev) if (IS_VI(i2c_dev)) return 0; + if (!of_property_present(i2c_dev->dev->of_node, "dmas")) { + dev_dbg(i2c_dev->dev, "DMA not available, falling back to PIO\n"); + return 0; + } + if (i2c_dev->hw->has_apb_dma) { if (!IS_ENABLED(CONFIG_TEGRA20_APB_DMA)) { dev_dbg(i2c_dev->dev, "APB DMA support not enabled\n"); @@ -634,6 +731,7 @@ static int tegra_i2c_master_reset(struct tegra_i2c_dev *i2c_dev) static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) { u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode; + u32 max_bus_freq_hz; struct i2c_timings *t = &i2c_dev->timings; int err; @@ -672,25 +770,40 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) if (IS_VI(i2c_dev)) tegra_i2c_vi_init(i2c_dev); - switch (t->bus_freq_hz) { - case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ: - default: - tlow = i2c_dev->hw->tlow_fast_fastplus_mode; - thigh = i2c_dev->hw->thigh_fast_fastplus_mode; - tsu_thd = i2c_dev->hw->setup_hold_time_fast_fast_plus_mode; + if (i2c_dev->hw->enable_hs_mode_support) + max_bus_freq_hz = I2C_MAX_HIGH_SPEED_MODE_FREQ; + else + max_bus_freq_hz = I2C_MAX_FAST_MODE_PLUS_FREQ; - if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) - non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode; - else - non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode; - break; + if (WARN_ON(t->bus_freq_hz > max_bus_freq_hz)) + t->bus_freq_hz = max_bus_freq_hz; - case 0 ... I2C_MAX_STANDARD_MODE_FREQ: + if (t->bus_freq_hz <= I2C_MAX_STANDARD_MODE_FREQ) { tlow = i2c_dev->hw->tlow_std_mode; thigh = i2c_dev->hw->thigh_std_mode; tsu_thd = i2c_dev->hw->setup_hold_time_std_mode; non_hs_mode = i2c_dev->hw->clk_divisor_std_mode; - break; + } else if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_FREQ) { + tlow = i2c_dev->hw->tlow_fast_mode; + thigh = i2c_dev->hw->thigh_fast_mode; + tsu_thd = i2c_dev->hw->setup_hold_time_fast_mode; + non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode; + } else if (t->bus_freq_hz <= I2C_MAX_FAST_MODE_PLUS_FREQ) { + tlow = i2c_dev->hw->tlow_fastplus_mode; + thigh = i2c_dev->hw->thigh_fastplus_mode; + tsu_thd = i2c_dev->hw->setup_hold_time_fastplus_mode; + non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode; + } else { + /* + * When using HS mode, i.e. when the bus frequency is greater than fast plus mode, + * the non-hs timing registers will be used for sending the master code byte for + * transition to HS mode. Configure the non-hs timing registers for Fast Mode to + * send the master code byte at 400kHz. + */ + tlow = i2c_dev->hw->tlow_fast_mode; + thigh = i2c_dev->hw->thigh_fast_mode; + tsu_thd = i2c_dev->hw->setup_hold_time_fast_mode; + non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode; } /* make sure clock divisor programmed correctly */ @@ -712,6 +825,18 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) if (i2c_dev->hw->has_interface_timing_reg && tsu_thd) i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1); + /* Write HS mode registers. These will get used only for HS mode*/ + if (i2c_dev->hw->enable_hs_mode_support) { + tlow = i2c_dev->hw->tlow_hs_mode; + thigh = i2c_dev->hw->thigh_hs_mode; + tsu_thd = i2c_dev->hw->setup_hold_time_hs_mode; + + val = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, thigh) | + FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, tlow); + i2c_writel(i2c_dev, val, I2C_HS_INTERFACE_TIMING_0); + i2c_writel(i2c_dev, tsu_thd, I2C_HS_INTERFACE_TIMING_1); + } + clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1); err = clk_set_rate(i2c_dev->div_clk, @@ -1209,6 +1334,9 @@ static void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev, if (msg->flags & I2C_M_RD) packet_header |= I2C_HEADER_READ; + if (i2c_dev->timings.bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) + packet_header |= I2C_HEADER_HS_MODE; + if (i2c_dev->dma_mode && !i2c_dev->msg_read) *dma_buf++ = packet_header; else @@ -1393,6 +1521,10 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], return ret; } + ret = tegra_i2c_mutex_lock(i2c_dev); + if (ret) + return ret; + for (i = 0; i < num; i++) { enum msg_end_type end_type = MSG_END_STOP; @@ -1422,6 +1554,7 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], break; } + ret = tegra_i2c_mutex_unlock(i2c_dev); pm_runtime_put(i2c_dev->dev); return ret ?: i; @@ -1491,12 +1624,17 @@ static const struct tegra_i2c_hw_feature tegra20_i2c_hw = { .has_apb_dma = true, .tlow_std_mode = 0x4, .thigh_std_mode = 0x2, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0x0, - .setup_hold_time_fast_fast_plus_mode = 0x0, + .setup_hold_time_fast_mode = 0x0, + .setup_hold_time_fastplus_mode = 0x0, .setup_hold_time_hs_mode = 0x0, .has_interface_timing_reg = false, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra30_i2c_hw = { @@ -1516,12 +1654,17 @@ static const struct tegra_i2c_hw_feature tegra30_i2c_hw = { .has_apb_dma = true, .tlow_std_mode = 0x4, .thigh_std_mode = 0x2, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0x0, - .setup_hold_time_fast_fast_plus_mode = 0x0, + .setup_hold_time_fast_mode = 0x0, + .setup_hold_time_fastplus_mode = 0x0, .setup_hold_time_hs_mode = 0x0, .has_interface_timing_reg = false, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra114_i2c_hw = { @@ -1541,12 +1684,17 @@ static const struct tegra_i2c_hw_feature tegra114_i2c_hw = { .has_apb_dma = true, .tlow_std_mode = 0x4, .thigh_std_mode = 0x2, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0x0, - .setup_hold_time_fast_fast_plus_mode = 0x0, + .setup_hold_time_fast_mode = 0x0, + .setup_hold_time_fastplus_mode = 0x0, .setup_hold_time_hs_mode = 0x0, .has_interface_timing_reg = false, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra124_i2c_hw = { @@ -1566,12 +1714,17 @@ static const struct tegra_i2c_hw_feature tegra124_i2c_hw = { .has_apb_dma = true, .tlow_std_mode = 0x4, .thigh_std_mode = 0x2, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0x0, - .setup_hold_time_fast_fast_plus_mode = 0x0, + .setup_hold_time_fast_mode = 0x0, + .setup_hold_time_fastplus_mode = 0x0, .setup_hold_time_hs_mode = 0x0, .has_interface_timing_reg = true, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra210_i2c_hw = { @@ -1591,12 +1744,17 @@ static const struct tegra_i2c_hw_feature tegra210_i2c_hw = { .has_apb_dma = true, .tlow_std_mode = 0x4, .thigh_std_mode = 0x2, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0, - .setup_hold_time_fast_fast_plus_mode = 0, + .setup_hold_time_fast_mode = 0, + .setup_hold_time_fastplus_mode = 0, .setup_hold_time_hs_mode = 0, .has_interface_timing_reg = true, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra186_i2c_hw = { @@ -1616,12 +1774,17 @@ static const struct tegra_i2c_hw_feature tegra186_i2c_hw = { .has_apb_dma = false, .tlow_std_mode = 0x4, .thigh_std_mode = 0x3, - .tlow_fast_fastplus_mode = 0x4, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x2, .setup_hold_time_std_mode = 0, - .setup_hold_time_fast_fast_plus_mode = 0, + .setup_hold_time_fast_mode = 0, + .setup_hold_time_fastplus_mode = 0, .setup_hold_time_hs_mode = 0, .has_interface_timing_reg = true, + .enable_hs_mode_support = false, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra194_i2c_hw = { @@ -1641,21 +1804,28 @@ static const struct tegra_i2c_hw_feature tegra194_i2c_hw = { .has_apb_dma = false, .tlow_std_mode = 0x8, .thigh_std_mode = 0x7, - .tlow_fast_fastplus_mode = 0x2, - .thigh_fast_fastplus_mode = 0x2, + .tlow_fast_mode = 0x2, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x2, + .thigh_fastplus_mode = 0x2, + .tlow_hs_mode = 0x8, + .thigh_hs_mode = 0x3, .setup_hold_time_std_mode = 0x08080808, - .setup_hold_time_fast_fast_plus_mode = 0x02020202, + .setup_hold_time_fast_mode = 0x02020202, + .setup_hold_time_fastplus_mode = 0x02020202, .setup_hold_time_hs_mode = 0x090909, .has_interface_timing_reg = true, + .enable_hs_mode_support = true, + .has_mutex = false, }; static const struct tegra_i2c_hw_feature tegra256_i2c_hw = { .has_continue_xfer_support = true, .has_per_pkt_xfer_complete_irq = true, - .clk_divisor_hs_mode = 7, + .clk_divisor_hs_mode = 9, .clk_divisor_std_mode = 0x7a, .clk_divisor_fast_mode = 0x40, - .clk_divisor_fast_plus_mode = 0x19, + .clk_divisor_fast_plus_mode = 0x14, .has_config_load_reg = true, .has_multi_master_mode = true, .has_slcg_override_reg = true, @@ -1666,15 +1836,55 @@ static const struct tegra_i2c_hw_feature tegra256_i2c_hw = { .has_apb_dma = false, .tlow_std_mode = 0x8, .thigh_std_mode = 0x7, - .tlow_fast_fastplus_mode = 0x3, - .thigh_fast_fastplus_mode = 0x3, + .tlow_fast_mode = 0x4, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x4, + .thigh_fastplus_mode = 0x4, + .tlow_hs_mode = 0x3, + .thigh_hs_mode = 0x2, .setup_hold_time_std_mode = 0x08080808, - .setup_hold_time_fast_fast_plus_mode = 0x02020202, + .setup_hold_time_fast_mode = 0x04010101, + .setup_hold_time_fastplus_mode = 0x04020202, + .setup_hold_time_hs_mode = 0x030303, + .has_interface_timing_reg = true, + .enable_hs_mode_support = true, + .has_mutex = true, +}; + +static const struct tegra_i2c_hw_feature tegra264_i2c_hw = { + .has_continue_xfer_support = true, + .has_per_pkt_xfer_complete_irq = true, + .clk_divisor_hs_mode = 1, + .clk_divisor_std_mode = 0x1d, + .clk_divisor_fast_mode = 0x15, + .clk_divisor_fast_plus_mode = 0x8, + .has_config_load_reg = true, + .has_multi_master_mode = true, + .has_slcg_override_reg = true, + .has_mst_fifo = true, + .has_mst_reset = true, + .quirks = &tegra194_i2c_quirks, + .supports_bus_clear = true, + .has_apb_dma = false, + .tlow_std_mode = 0x8, + .thigh_std_mode = 0x7, + .tlow_fast_mode = 0x2, + .thigh_fast_mode = 0x2, + .tlow_fastplus_mode = 0x2, + .thigh_fastplus_mode = 0x2, + .tlow_hs_mode = 0x4, + .thigh_hs_mode = 0x2, + .setup_hold_time_std_mode = 0x08080808, + .setup_hold_time_fast_mode = 0x02020202, + .setup_hold_time_fastplus_mode = 0x02020202, .setup_hold_time_hs_mode = 0x090909, .has_interface_timing_reg = true, + .enable_hs_mode_support = true, + .has_mutex = true, }; static const struct of_device_id tegra_i2c_of_match[] = { + { .compatible = "nvidia,tegra264-i2c", .data = &tegra264_i2c_hw, }, { .compatible = "nvidia,tegra256-i2c", .data = &tegra256_i2c_hw, }, { .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, }, { .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, }, diff --git a/drivers/i2c/busses/i2c-tiny-usb.c b/drivers/i2c/busses/i2c-tiny-usb.c index 57dfe5f1a7d9..9ef495f88ef2 100644 --- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -55,7 +55,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num) struct i2c_msg *pmsg; int i, ret; - pstatus = kmalloc(sizeof(*pstatus), GFP_KERNEL); + pstatus = kmalloc_obj(*pstatus); if (!pstatus) return -ENOMEM; @@ -123,7 +123,7 @@ static u32 usb_func(struct i2c_adapter *adapter) __le32 *pfunc; u32 ret; - pfunc = kmalloc(sizeof(*pfunc), GFP_KERNEL); + pfunc = kmalloc_obj(*pfunc); /* get functionality from adapter */ if (!pfunc || usb_read(adapter, CMD_GET_FUNC, 0, 0, pfunc, @@ -233,7 +233,7 @@ static int i2c_tiny_usb_probe(struct usb_interface *interface, dev_dbg(&interface->dev, "probing usb device\n"); /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto error; diff --git a/drivers/i2c/busses/i2c-virtio.c b/drivers/i2c/busses/i2c-virtio.c index af1381949f50..7b0b0bff8000 100644 --- a/drivers/i2c/busses/i2c-virtio.c +++ b/drivers/i2c/busses/i2c-virtio.c @@ -139,7 +139,7 @@ static int virtio_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, struct virtio_i2c_req *reqs; int count; - reqs = kcalloc(num, sizeof(*reqs), GFP_KERNEL); + reqs = kzalloc_objs(*reqs, num); if (!reqs) return -ENOMEM; diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 06cf221557f2..0cd0a18a7082 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c @@ -418,7 +418,7 @@ static struct scx200_acb_iface *scx200_create_iface(const char *text, struct scx200_acb_iface *iface; struct i2c_adapter *adapter; - iface = kzalloc(sizeof(*iface), GFP_KERNEL); + iface = kzalloc_obj(*iface); if (!iface) return NULL; diff --git a/drivers/i2c/i2c-atr.c b/drivers/i2c/i2c-atr.c index dd194476b118..f9fcb4793aaf 100644 --- a/drivers/i2c/i2c-atr.c +++ b/drivers/i2c/i2c-atr.c @@ -137,7 +137,7 @@ static struct i2c_atr_alias_pool *i2c_atr_alloc_alias_pool(size_t num_aliases, b struct i2c_atr_alias_pool *alias_pool; int ret; - alias_pool = kzalloc(sizeof(*alias_pool), GFP_KERNEL); + alias_pool = kzalloc_obj(*alias_pool); if (!alias_pool) return ERR_PTR(-ENOMEM); @@ -183,7 +183,7 @@ static struct i2c_atr_alias_pair *i2c_atr_create_c2a(struct i2c_atr_chan *chan, lockdep_assert_held(&chan->alias_pairs_lock); - c2a = kzalloc(sizeof(*c2a), GFP_KERNEL); + c2a = kzalloc_obj(*c2a); if (!c2a) return NULL; @@ -724,7 +724,7 @@ struct i2c_atr *i2c_atr_new(struct i2c_adapter *parent, struct device *dev, if (!ops || !ops->attach_addr || !ops->detach_addr) return ERR_PTR(-EINVAL); - atr = kzalloc(struct_size(atr, adapter, max_adapters), GFP_KERNEL); + atr = kzalloc_flex(*atr, adapter, max_adapters); if (!atr) return ERR_PTR(-ENOMEM); @@ -800,7 +800,7 @@ int i2c_atr_add_adapter(struct i2c_atr *atr, struct i2c_atr_adap_desc *desc) return -EEXIST; } - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return -ENOMEM; diff --git a/drivers/i2c/i2c-boardinfo.c b/drivers/i2c/i2c-boardinfo.c index 4df8ad092df3..735fd13fefc4 100644 --- a/drivers/i2c/i2c-boardinfo.c +++ b/drivers/i2c/i2c-boardinfo.c @@ -61,7 +61,7 @@ int i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsig for (status = 0; len; len--, info++) { struct i2c_devinfo *devinfo; - devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); + devinfo = kzalloc_obj(*devinfo); if (!devinfo) { pr_debug("i2c-core: can't register boardinfo!\n"); status = -ENOMEM; diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index ed90858a27b7..2cbd31f77667 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c @@ -683,7 +683,7 @@ i2c_acpi_space_handler(u32 function, acpi_physical_address command, if (ACPI_FAILURE(ret)) return ret; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) { ret = AE_NO_MEMORY; goto err; @@ -793,8 +793,7 @@ int i2c_acpi_install_space_handler(struct i2c_adapter *adapter) if (!handle) return -ENODEV; - data = kzalloc(sizeof(struct i2c_acpi_handler_data), - GFP_KERNEL); + data = kzalloc_obj(struct i2c_acpi_handler_data); if (!data) return -ENOMEM; diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index ae7e9c8b65a6..9c46147e3506 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -964,7 +964,7 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf bool need_put = false; int status; - client = kzalloc(sizeof *client, GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return ERR_PTR(-ENOMEM); @@ -1090,7 +1090,7 @@ struct i2c_client *i2c_find_device_by_fwnode(struct fwnode_handle *fwnode) struct i2c_client *client; struct device *dev; - if (!fwnode) + if (IS_ERR_OR_NULL(fwnode)) return NULL; dev = bus_find_device_by_fwnode(&i2c_bus_type, fwnode); @@ -1476,7 +1476,7 @@ static int i2c_setup_host_notify_irq_domain(struct i2c_adapter *adap) if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_HOST_NOTIFY)) return 0; - domain = irq_domain_create_linear(adap->dev.parent->fwnode, + domain = irq_domain_create_linear(dev_fwnode(adap->dev.parent), I2C_ADDR_7BITS_COUNT, &i2c_host_notify_irq_ops, adap); if (!domain) @@ -1852,10 +1852,10 @@ EXPORT_SYMBOL_GPL(devm_i2c_add_adapter); static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data) { - if (dev_fwnode(dev) == data) + if (device_match_fwnode(dev, data)) return 1; - if (dev->parent && dev_fwnode(dev->parent) == data) + if (dev->parent && device_match_fwnode(dev->parent, data)) return 1; return 0; @@ -1875,7 +1875,7 @@ struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) struct i2c_adapter *adapter; struct device *dev; - if (!fwnode) + if (IS_ERR_OR_NULL(fwnode)) return NULL; dev = bus_find_device(&i2c_bus_type, NULL, fwnode, @@ -2529,7 +2529,7 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver) return 0; /* Set up a temporary client to help detect callback */ - temp_client = kzalloc(sizeof(*temp_client), GFP_KERNEL); + temp_client = kzalloc_obj(*temp_client); if (!temp_client) return -ENOMEM; diff --git a/drivers/i2c/i2c-core-of-prober.c b/drivers/i2c/i2c-core-of-prober.c index 0a66267e4836..6a82b03809d4 100644 --- a/drivers/i2c/i2c-core-of-prober.c +++ b/drivers/i2c/i2c-core-of-prober.c @@ -63,7 +63,7 @@ static int i2c_of_probe_enable_node(struct device *dev, struct device_node *node dev_dbg(dev, "Enabling %pOF\n", node); - struct of_changeset *ocs __free(kfree) = kzalloc(sizeof(*ocs), GFP_KERNEL); + struct of_changeset *ocs __free(kfree) = kzalloc_obj(*ocs); if (!ocs) return -ENOMEM; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index e9577f920286..7bbe0263411e 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -74,7 +74,7 @@ static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) return ERR_PTR(-ENODEV); } - i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL); + i2c_dev = kzalloc_obj(*i2c_dev); if (!i2c_dev) return ERR_PTR(-ENOMEM); i2c_dev->adap = adap; @@ -552,8 +552,7 @@ static long compat_i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned lo if (rdwr_arg.nmsgs > I2C_RDWR_IOCTL_MAX_MSGS) return -EINVAL; - rdwr_pa = kmalloc_array(rdwr_arg.nmsgs, sizeof(struct i2c_msg), - GFP_KERNEL); + rdwr_pa = kmalloc_objs(struct i2c_msg, rdwr_arg.nmsgs); if (!rdwr_pa) return -ENOMEM; @@ -612,7 +611,7 @@ static int i2cdev_open(struct inode *inode, struct file *file) * or I2C core code!! It just holds private copies of addressing * information and maybe a PEC flag. */ - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) { i2c_put_adapter(adap); return -ENOMEM; diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index d59644e50f14..681a201c239b 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c @@ -277,7 +277,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, return -EINVAL; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/i2c/i2c-smbus.c b/drivers/i2c/i2c-smbus.c index 0316b347f9e7..bc7bd55e6370 100644 --- a/drivers/i2c/i2c-smbus.c +++ b/drivers/i2c/i2c-smbus.c @@ -319,8 +319,7 @@ struct i2c_client *i2c_new_slave_host_notify_device(struct i2c_adapter *adapter) struct i2c_client *client; int ret; - status = kzalloc(sizeof(struct i2c_slave_host_notify_status), - GFP_KERNEL); + status = kzalloc_obj(struct i2c_slave_host_notify_status); if (!status) return ERR_PTR(-ENOMEM); diff --git a/drivers/i2c/i2c-stub.c b/drivers/i2c/i2c-stub.c index 09e7b7bf4c5f..fbb0db41b10e 100644 --- a/drivers/i2c/i2c-stub.c +++ b/drivers/i2c/i2c-stub.c @@ -372,8 +372,7 @@ static int __init i2c_stub_init(void) /* Allocate memory for all chips at once */ stub_chips_nr = i; - stub_chips = kcalloc(stub_chips_nr, sizeof(struct stub_chip), - GFP_KERNEL); + stub_chips = kzalloc_objs(struct stub_chip, stub_chips_nr); if (!stub_chips) return -ENOMEM; diff --git a/drivers/i3c/Kconfig b/drivers/i3c/Kconfig index 30a441506f61..626c54b386d5 100644 --- a/drivers/i3c/Kconfig +++ b/drivers/i3c/Kconfig @@ -22,3 +22,15 @@ menuconfig I3C if I3C source "drivers/i3c/master/Kconfig" endif # I3C + +config I3C_OR_I2C + tristate + default m if I3C=m + default I2C + help + Device drivers using module_i3c_i2c_driver() can use either + i2c or i3c hosts, but cannot be built-in for the kernel when + CONFIG_I3C=m. + + Add 'depends on I2C_OR_I3C' in Kconfig for those drivers to + get the correct dependencies. diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 0eae19b3823d..9e6be49bebb2 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -858,7 +858,7 @@ i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, { struct i2c_dev_desc *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -983,7 +983,7 @@ i3c_master_alloc_i3c_dev(struct i3c_master_controller *master, { struct i3c_dev_desc *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -1742,7 +1742,7 @@ i3c_master_register_new_i3c_devs(struct i3c_master_controller *master) if (desc->dev || !desc->info.dyn_addr || desc == master->this) continue; - desc->dev = kzalloc(sizeof(*desc->dev), GFP_KERNEL); + desc->dev = kzalloc_obj(*desc->dev); if (!desc->dev) continue; @@ -1852,7 +1852,7 @@ struct i3c_dma *i3c_master_dma_map_single(struct device *dev, void *buf, void *bounce __free(kfree) = NULL; void *dma_buf = buf; - struct i3c_dma *dma_xfer __free(kfree) = kzalloc(sizeof(*dma_xfer), GFP_KERNEL); + struct i3c_dma *dma_xfer __free(kfree) = kzalloc_obj(*dma_xfer); if (!dma_xfer) return NULL; @@ -2847,7 +2847,7 @@ i3c_generic_ibi_alloc_pool(struct i3c_dev_desc *dev, unsigned int i; int ret; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); @@ -2855,7 +2855,7 @@ i3c_generic_ibi_alloc_pool(struct i3c_dev_desc *dev, INIT_LIST_HEAD(&pool->free_slots); INIT_LIST_HEAD(&pool->pending); - pool->slots = kcalloc(req->num_slots, sizeof(*slot), GFP_KERNEL); + pool->slots = kzalloc_objs(*slot, req->num_slots); if (!pool->slots) { ret = -ENOMEM; goto err_free_pool; @@ -3218,7 +3218,7 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev, if (dev->ibi) return -EBUSY; - ibi = kzalloc(sizeof(*ibi), GFP_KERNEL); + ibi = kzalloc_obj(*ibi); if (!ibi) return -ENOMEM; diff --git a/drivers/i3c/master/adi-i3c-master.c b/drivers/i3c/master/adi-i3c-master.c index 6380a38e6d29..6616f751075a 100644 --- a/drivers/i3c/master/adi-i3c-master.c +++ b/drivers/i3c/master/adi-i3c-master.c @@ -187,7 +187,7 @@ static struct adi_i3c_xfer *adi_i3c_master_alloc_xfer(struct adi_i3c_master *mas { struct adi_i3c_xfer *xfer; - xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL); + xfer = kzalloc_flex(*xfer, cmds, ncmds); if (!xfer) return NULL; @@ -459,7 +459,7 @@ static int adi_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) int slot; u8 addr; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -531,7 +531,7 @@ static int adi_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) if (slot < 0) return slot; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c index 7eb09ad10171..d6bdb32397fb 100644 --- a/drivers/i3c/master/dw-i3c-master.c +++ b/drivers/i3c/master/dw-i3c-master.c @@ -382,7 +382,7 @@ dw_i3c_master_alloc_xfer(struct dw_i3c_master *master, unsigned int ncmds) { struct dw_i3c_xfer *xfer; - xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL); + xfer = kzalloc_flex(*xfer, cmds, ncmds); if (!xfer) return NULL; @@ -1024,7 +1024,7 @@ static int dw_i3c_master_reattach_i3c_dev(struct i3c_dev_desc *dev, master->free_pos &= ~BIT(pos); } - writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr), + writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(dev->info.dyn_addr) | DEV_ADDR_TABLE_SIR_REJECT, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); @@ -1044,7 +1044,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) if (pos < 0) return pos; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1053,7 +1053,7 @@ static int dw_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) master->free_pos &= ~BIT(pos); i3c_dev_set_master_data(dev, data); - writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr), + writel(DEV_ADDR_TABLE_DYNAMIC_ADDR(master->devs[pos].addr) | DEV_ADDR_TABLE_SIR_REJECT, master->regs + DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index)); @@ -1162,7 +1162,7 @@ static int dw_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) if (pos < 0) return pos; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1659,6 +1659,8 @@ int dw_i3c_common_probe(struct dw_i3c_master *master, pm_runtime_get_noresume(&pdev->dev); INIT_WORK(&master->hj_work, dw_i3c_hj_work); + + device_set_of_node_from_dev(&master->base.i2c.dev, &pdev->dev); ret = i3c_master_register(&master->base, &pdev->dev, &dw_mipi_i3c_ops, false); if (ret) diff --git a/drivers/i3c/master/i3c-master-cdns.c b/drivers/i3c/master/i3c-master-cdns.c index 8eb76b8ca2b0..b78aebf6b2ca 100644 --- a/drivers/i3c/master/i3c-master-cdns.c +++ b/drivers/i3c/master/i3c-master-cdns.c @@ -498,7 +498,7 @@ cdns_i3c_master_alloc_xfer(struct cdns_i3c_master *master, unsigned int ncmds) { struct cdns_i3c_xfer *xfer; - xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL); + xfer = kzalloc_flex(*xfer, cmds, ncmds); if (!xfer) return NULL; @@ -940,7 +940,7 @@ static int cdns_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) struct cdns_i3c_i2c_dev_data *data; int slot; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -991,7 +991,7 @@ static int cdns_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) if (slot < 0) return slot; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/i3c/master/mipi-i3c-hci/cmd.h b/drivers/i3c/master/mipi-i3c-hci/cmd.h index 1d6dd2c5d01a..b1bf87daa651 100644 --- a/drivers/i3c/master/mipi-i3c-hci/cmd.h +++ b/drivers/i3c/master/mipi-i3c-hci/cmd.h @@ -17,6 +17,7 @@ #define CMD_0_TOC W0_BIT_(31) #define CMD_0_ROC W0_BIT_(30) #define CMD_0_ATTR W0_MASK(2, 0) +#define CMD_0_TID W0_MASK(6, 3) /* * Response Descriptor Structure diff --git a/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c b/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c index fe260461e7e6..75d452d7f6af 100644 --- a/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c +++ b/drivers/i3c/master/mipi-i3c-hci/cmd_v1.c @@ -331,12 +331,10 @@ static int hci_cmd_v1_daa(struct i3c_hci *hci) CMD_A0_ROC | CMD_A0_TOC; xfer->cmd_desc[1] = 0; xfer->completion = &done; - hci->io->queue_xfer(hci, xfer, 1); - if (!wait_for_completion_timeout(&done, HZ) && - hci->io->dequeue_xfer(hci, xfer, 1)) { - ret = -ETIME; + xfer->timeout = HZ; + ret = i3c_hci_process_xfer(hci, xfer, 1); + if (ret) break; - } if ((RESP_STATUS(xfer->response) == RESP_ERR_ADDR_HEADER || RESP_STATUS(xfer->response) == RESP_ERR_NACK) && RESP_DATA_LENGTH(xfer->response) == 1) { diff --git a/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c b/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c index 3729e6419581..39eec26a363c 100644 --- a/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c +++ b/drivers/i3c/master/mipi-i3c-hci/cmd_v2.c @@ -253,6 +253,7 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci) xfer[0].rnw = true; xfer[0].cmd_desc[1] = CMD_A1_DATA_LENGTH(8); xfer[1].completion = &done; + xfer[1].timeout = HZ; for (;;) { ret = i3c_master_get_free_addr(&hci->master, next_addr); @@ -272,12 +273,9 @@ static int hci_cmd_v2_daa(struct i3c_hci *hci) CMD_A0_ASSIGN_ADDRESS(next_addr) | CMD_A0_ROC | CMD_A0_TOC; - hci->io->queue_xfer(hci, xfer, 2); - if (!wait_for_completion_timeout(&done, HZ) && - hci->io->dequeue_xfer(hci, xfer, 2)) { - ret = -ETIME; + ret = i3c_hci_process_xfer(hci, xfer, 2); + if (ret) break; - } if (RESP_STATUS(xfer[0].response) != RESP_SUCCESS) { ret = 0; /* no more devices to be assigned */ break; diff --git a/drivers/i3c/master/mipi-i3c-hci/core.c b/drivers/i3c/master/mipi-i3c-hci/core.c index e925584113d1..284f3ed7af8c 100644 --- a/drivers/i3c/master/mipi-i3c-hci/core.c +++ b/drivers/i3c/master/mipi-i3c-hci/core.c @@ -152,7 +152,11 @@ static int i3c_hci_bus_init(struct i3c_master_controller *m) if (hci->quirks & HCI_QUIRK_RESP_BUF_THLD) amd_set_resp_buf_thld(hci); - reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE); + scoped_guard(spinlock_irqsave, &hci->lock) + hci->irq_inactive = false; + + /* Enable bus with Hot-Join disabled */ + reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE | HC_CONTROL_HOT_JOIN_CTRL); dev_dbg(&hci->master.dev, "HC_CONTROL = %#x", reg_read(HC_CONTROL)); return 0; @@ -177,21 +181,51 @@ static int i3c_hci_bus_disable(struct i3c_hci *hci) return ret; } +static int i3c_hci_software_reset(struct i3c_hci *hci) +{ + u32 regval; + int ret; + + /* + * SOFT_RST must be clear before we write to it. + * Then we must wait until it clears again. + */ + ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval, + !(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC); + if (ret) { + dev_err(&hci->master.dev, "%s: Software reset stuck\n", __func__); + return ret; + } + + reg_write(RESET_CONTROL, SOFT_RST); + + ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval, + !(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC); + if (ret) { + dev_err(&hci->master.dev, "%s: Software reset failed\n", __func__); + return ret; + } + + return 0; +} + void i3c_hci_sync_irq_inactive(struct i3c_hci *hci) { struct platform_device *pdev = to_platform_device(hci->master.dev.parent); int irq = platform_get_irq(pdev, 0); reg_write(INTR_SIGNAL_ENABLE, 0x0); - hci->irq_inactive = true; synchronize_irq(irq); + scoped_guard(spinlock_irqsave, &hci->lock) + hci->irq_inactive = true; } static void i3c_hci_bus_cleanup(struct i3c_master_controller *m) { struct i3c_hci *hci = to_i3c_hci(m); - i3c_hci_bus_disable(hci); + if (i3c_hci_bus_disable(hci)) + i3c_hci_software_reset(hci); hci->io->cleanup(hci); } @@ -212,6 +246,36 @@ void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci) reg_write(DCT_SECTION, FIELD_PREP(DCT_TABLE_INDEX, 0)); } +int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n) +{ + struct completion *done = xfer[n - 1].completion; + unsigned long timeout = xfer[n - 1].timeout; + int ret; + + ret = hci->io->queue_xfer(hci, xfer, n); + if (ret) + return ret; + + if (!wait_for_completion_timeout(done, timeout)) { + if (hci->io->dequeue_xfer(hci, xfer, n)) { + dev_err(&hci->master.dev, "%s: timeout error\n", __func__); + return -ETIMEDOUT; + } + return 0; + } + + if (hci->io->handle_error) { + bool error = false; + + for (int i = 0; i < n && !error; i++) + error = RESP_STATUS(xfer[i].response); + if (error) + return hci->io->handle_error(hci, xfer, n); + } + + return 0; +} + static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m, struct i3c_ccc_cmd *ccc) { @@ -252,18 +316,14 @@ static int i3c_hci_send_ccc_cmd(struct i3c_master_controller *m, last = i - 1; xfer[last].cmd_desc[0] |= CMD_0_TOC; xfer[last].completion = &done; + xfer[last].timeout = HZ; if (prefixed) xfer--; - ret = hci->io->queue_xfer(hci, xfer, nxfers); + ret = i3c_hci_process_xfer(hci, xfer, nxfers); if (ret) goto out; - if (!wait_for_completion_timeout(&done, HZ) && - hci->io->dequeue_xfer(hci, xfer, nxfers)) { - ret = -ETIME; - goto out; - } for (i = prefixed; i < nxfers; i++) { if (ccc->rnw) ccc->dests[i - prefixed].payload.len = @@ -334,15 +394,11 @@ static int i3c_hci_i3c_xfers(struct i3c_dev_desc *dev, last = i - 1; xfer[last].cmd_desc[0] |= CMD_0_TOC; xfer[last].completion = &done; + xfer[last].timeout = HZ; - ret = hci->io->queue_xfer(hci, xfer, nxfers); + ret = i3c_hci_process_xfer(hci, xfer, nxfers); if (ret) goto out; - if (!wait_for_completion_timeout(&done, HZ) && - hci->io->dequeue_xfer(hci, xfer, nxfers)) { - ret = -ETIME; - goto out; - } for (i = 0; i < nxfers; i++) { if (i3c_xfers[i].rnw) i3c_xfers[i].len = RESP_DATA_LENGTH(xfer[i].response); @@ -382,15 +438,11 @@ static int i3c_hci_i2c_xfers(struct i2c_dev_desc *dev, last = i - 1; xfer[last].cmd_desc[0] |= CMD_0_TOC; xfer[last].completion = &done; + xfer[last].timeout = m->i2c.timeout; - ret = hci->io->queue_xfer(hci, xfer, nxfers); + ret = i3c_hci_process_xfer(hci, xfer, nxfers); if (ret) goto out; - if (!wait_for_completion_timeout(&done, m->i2c.timeout) && - hci->io->dequeue_xfer(hci, xfer, nxfers)) { - ret = -ETIME; - goto out; - } for (i = 0; i < nxfers; i++) { if (RESP_STATUS(xfer[i].response) != RESP_SUCCESS) { ret = -EIO; @@ -410,7 +462,7 @@ static int i3c_hci_attach_i3c_dev(struct i3c_dev_desc *dev) struct i3c_hci_dev_data *dev_data; int ret; - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kzalloc_obj(*dev_data); if (!dev_data) return -ENOMEM; if (hci->cmd == &mipi_i3c_hci_cmd_v1) { @@ -460,7 +512,7 @@ static int i3c_hci_attach_i2c_dev(struct i2c_dev_desc *dev) if (hci->cmd != &mipi_i3c_hci_cmd_v1) return 0; - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kzalloc_obj(*dev_data); if (!dev_data) return -ENOMEM; ret = mipi_i3c_hci_dat_v1.alloc_entry(hci); @@ -566,6 +618,8 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id) irqreturn_t result = IRQ_NONE; u32 val; + guard(spinlock)(&hci->lock); + /* * The IRQ can be shared, so the handler may be called when the IRQ is * due to a different device. That could happen when runtime suspended, @@ -601,34 +655,6 @@ static irqreturn_t i3c_hci_irq_handler(int irq, void *dev_id) return result; } -static int i3c_hci_software_reset(struct i3c_hci *hci) -{ - u32 regval; - int ret; - - /* - * SOFT_RST must be clear before we write to it. - * Then we must wait until it clears again. - */ - ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval, - !(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC); - if (ret) { - dev_err(&hci->master.dev, "%s: Software reset stuck\n", __func__); - return ret; - } - - reg_write(RESET_CONTROL, SOFT_RST); - - ret = readx_poll_timeout(reg_read, RESET_CONTROL, regval, - !(regval & SOFT_RST), 0, 10 * USEC_PER_MSEC); - if (ret) { - dev_err(&hci->master.dev, "%s: Software reset failed\n", __func__); - return ret; - } - - return 0; -} - static inline bool is_version_1_1_or_newer(struct i3c_hci *hci) { return hci->version_major > 1 || (hci->version_major == 1 && hci->version_minor > 0); @@ -739,8 +765,12 @@ static int i3c_hci_runtime_suspend(struct device *dev) int ret; ret = i3c_hci_bus_disable(hci); - if (ret) + if (ret) { + /* Fall back to software reset to disable the bus */ + ret = i3c_hci_software_reset(hci); + i3c_hci_sync_irq_inactive(hci); return ret; + } hci->io->suspend(hci); @@ -760,11 +790,13 @@ static int i3c_hci_runtime_resume(struct device *dev) mipi_i3c_hci_dat_v1.restore(hci); - hci->irq_inactive = false; - hci->io->resume(hci); - reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE); + scoped_guard(spinlock_irqsave, &hci->lock) + hci->irq_inactive = false; + + /* Enable bus with Hot-Join disabled */ + reg_set(HC_CONTROL, HC_CONTROL_BUS_ENABLE | HC_CONTROL_HOT_JOIN_CTRL); return 0; } @@ -924,6 +956,9 @@ static int i3c_hci_probe(struct platform_device *pdev) if (!hci) return -ENOMEM; + spin_lock_init(&hci->lock); + mutex_init(&hci->control_mutex); + /* * Multi-bus instances share the same MMIO address range, but not * necessarily in separate contiguous sub-ranges. To avoid overlapping @@ -950,6 +985,8 @@ static int i3c_hci_probe(struct platform_device *pdev) if (ret) return ret; + hci->irq_inactive = true; + irq = platform_get_irq(pdev, 0); ret = devm_request_irq(&pdev->dev, irq, i3c_hci_irq_handler, IRQF_SHARED, NULL, hci); diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c index 2e5b4974d431..e487ef52f6b4 100644 --- a/drivers/i3c/master/mipi-i3c-hci/dma.c +++ b/drivers/i3c/master/mipi-i3c-hci/dma.c @@ -129,9 +129,8 @@ struct hci_rh_data { dma_addr_t xfer_dma, resp_dma, ibi_status_dma, ibi_data_dma; unsigned int xfer_entries, ibi_status_entries, ibi_chunks_total; unsigned int xfer_struct_sz, resp_struct_sz, ibi_status_sz, ibi_chunk_sz; - unsigned int done_ptr, ibi_chunk_ptr; + unsigned int done_ptr, ibi_chunk_ptr, xfer_space; struct hci_xfer **src_xfers; - spinlock_t lock; struct completion op_done; }; @@ -261,6 +260,7 @@ static void hci_dma_init_rh(struct i3c_hci *hci, struct hci_rh_data *rh, int i) rh->done_ptr = 0; rh->ibi_chunk_ptr = 0; + rh->xfer_space = rh->xfer_entries; } static void hci_dma_init_rings(struct i3c_hci *hci) @@ -328,7 +328,7 @@ static int hci_dma_init(struct i3c_hci *hci) } if (nr_rings > XFER_RINGS) nr_rings = XFER_RINGS; - rings = kzalloc(struct_size(rings, headers, nr_rings), GFP_KERNEL); + rings = kzalloc_flex(*rings, headers, nr_rings); if (!rings) return -ENOMEM; hci->io_data = rings; @@ -344,7 +344,6 @@ static int hci_dma_init(struct i3c_hci *hci) goto err_out; rh = &rings->headers[i]; rh->regs = hci->base_regs + offset; - spin_lock_init(&rh->lock); init_completion(&rh->op_done); rh->xfer_entries = XFER_RING_ENTRIES; @@ -363,8 +362,7 @@ static int hci_dma_init(struct i3c_hci *hci) rh->resp = dma_alloc_coherent(rings->sysdev, resps_sz, &rh->resp_dma, GFP_KERNEL); rh->src_xfers = - kmalloc_array(rh->xfer_entries, sizeof(*rh->src_xfers), - GFP_KERNEL); + kmalloc_objs(*rh->src_xfers, rh->xfer_entries); ret = -ENOMEM; if (!rh->xfer || !rh->resp || !rh->src_xfers) goto err_out; @@ -440,26 +438,63 @@ static void hci_dma_unmap_xfer(struct i3c_hci *hci, } } +static struct i3c_dma *hci_dma_map_xfer(struct device *dev, struct hci_xfer *xfer) +{ + enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + bool need_bounce = device_iommu_mapped(dev) && xfer->rnw && (xfer->data_len & 3); + + return i3c_master_dma_map_single(dev, xfer->data, xfer->data_len, need_bounce, dir); +} + +static int hci_dma_map_xfer_list(struct i3c_hci *hci, struct device *dev, + struct hci_xfer *xfer_list, int n) +{ + for (int i = 0; i < n; i++) { + struct hci_xfer *xfer = xfer_list + i; + + if (!xfer->data) + continue; + + xfer->dma = hci_dma_map_xfer(dev, xfer); + if (!xfer->dma) { + hci_dma_unmap_xfer(hci, xfer_list, i); + return -ENOMEM; + } + } + + return 0; +} + static int hci_dma_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer_list, int n) { struct hci_rings_data *rings = hci->io_data; struct hci_rh_data *rh; unsigned int i, ring, enqueue_ptr; - u32 op1_val, op2_val; + u32 op1_val; + int ret; + + ret = hci_dma_map_xfer_list(hci, rings->sysdev, xfer_list, n); + if (ret) + return ret; /* For now we only use ring 0 */ ring = 0; rh = &rings->headers[ring]; + spin_lock_irq(&hci->lock); + + if (n > rh->xfer_space) { + spin_unlock_irq(&hci->lock); + hci_dma_unmap_xfer(hci, xfer_list, n); + return -EBUSY; + } + op1_val = rh_reg_read(RING_OPERATION1); enqueue_ptr = FIELD_GET(RING_OP1_CR_ENQ_PTR, op1_val); for (i = 0; i < n; i++) { struct hci_xfer *xfer = xfer_list + i; u32 *ring_data = rh->xfer + rh->xfer_struct_sz * enqueue_ptr; - enum dma_data_direction dir = xfer->rnw ? DMA_FROM_DEVICE : - DMA_TO_DEVICE; - bool need_bounce; /* store cmd descriptor */ *ring_data++ = xfer->cmd_desc[0]; @@ -478,18 +513,6 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci, /* 2nd and 3rd words of Data Buffer Descriptor Structure */ if (xfer->data) { - need_bounce = device_iommu_mapped(rings->sysdev) && - xfer->rnw && - xfer->data_len != ALIGN(xfer->data_len, 4); - xfer->dma = i3c_master_dma_map_single(rings->sysdev, - xfer->data, - xfer->data_len, - need_bounce, - dir); - if (!xfer->dma) { - hci_dma_unmap_xfer(hci, xfer_list, i); - return -ENOMEM; - } *ring_data++ = lower_32_bits(xfer->dma->addr); *ring_data++ = upper_32_bits(xfer->dma->addr); } else { @@ -504,26 +527,14 @@ static int hci_dma_queue_xfer(struct i3c_hci *hci, xfer->ring_entry = enqueue_ptr; enqueue_ptr = (enqueue_ptr + 1) % rh->xfer_entries; - - /* - * We may update the hardware view of the enqueue pointer - * only if we didn't reach its dequeue pointer. - */ - op2_val = rh_reg_read(RING_OPERATION2); - if (enqueue_ptr == FIELD_GET(RING_OP2_CR_DEQ_PTR, op2_val)) { - /* the ring is full */ - hci_dma_unmap_xfer(hci, xfer_list, i + 1); - return -EBUSY; - } } - /* take care to update the hardware enqueue pointer atomically */ - spin_lock_irq(&rh->lock); - op1_val = rh_reg_read(RING_OPERATION1); + rh->xfer_space -= n; + op1_val &= ~RING_OP1_CR_ENQ_PTR; op1_val |= FIELD_PREP(RING_OP1_CR_ENQ_PTR, enqueue_ptr); rh_reg_write(RING_OPERATION1, op1_val); - spin_unlock_irq(&rh->lock); + spin_unlock_irq(&hci->lock); return 0; } @@ -535,18 +546,29 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number]; unsigned int i; bool did_unqueue = false; + u32 ring_status; - /* stop the ring */ - rh_reg_write(RING_CONTROL, RING_CTRL_ABORT); - if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) { - /* - * We're deep in it if ever this condition is ever met. - * Hardware might still be writing to memory, etc. - */ - dev_crit(&hci->master.dev, "unable to abort the ring\n"); - WARN_ON(1); + guard(mutex)(&hci->control_mutex); + + ring_status = rh_reg_read(RING_STATUS); + if (ring_status & RING_STATUS_RUNNING) { + /* stop the ring */ + reinit_completion(&rh->op_done); + rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT); + wait_for_completion_timeout(&rh->op_done, HZ); + ring_status = rh_reg_read(RING_STATUS); + if (ring_status & RING_STATUS_RUNNING) { + /* + * We're deep in it if ever this condition is ever met. + * Hardware might still be writing to memory, etc. + */ + dev_crit(&hci->master.dev, "unable to abort the ring\n"); + WARN_ON(1); + } } + spin_lock_irq(&hci->lock); + for (i = 0; i < n; i++) { struct hci_xfer *xfer = xfer_list + i; int idx = xfer->ring_entry; @@ -560,7 +582,7 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, u32 *ring_data = rh->xfer + rh->xfer_struct_sz * idx; /* store no-op cmd descriptor */ - *ring_data++ = FIELD_PREP(CMD_0_ATTR, 0x7); + *ring_data++ = FIELD_PREP(CMD_0_ATTR, 0x7) | FIELD_PREP(CMD_0_TID, xfer->cmd_tid); *ring_data++ = 0; if (hci->cmd == &mipi_i3c_hci_cmd_v2) { *ring_data++ = 0; @@ -578,15 +600,25 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci, } /* restart the ring */ + mipi_i3c_hci_resume(hci); rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE); + rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_RUN_STOP); + + spin_unlock_irq(&hci->lock); return did_unqueue; } +static int hci_dma_handle_error(struct i3c_hci *hci, struct hci_xfer *xfer_list, int n) +{ + return hci_dma_dequeue_xfer(hci, xfer_list, n) ? -EIO : 0; +} + static void hci_dma_xfer_done(struct i3c_hci *hci, struct hci_rh_data *rh) { u32 op1_val, op2_val, resp, *ring_resp; unsigned int tid, done_ptr = rh->done_ptr; + unsigned int done_cnt = 0; struct hci_xfer *xfer; for (;;) { @@ -604,6 +636,7 @@ static void hci_dma_xfer_done(struct i3c_hci *hci, struct hci_rh_data *rh) dev_dbg(&hci->master.dev, "orphaned ring entry"); } else { hci_dma_unmap_xfer(hci, xfer, 1); + rh->src_xfers[done_ptr] = NULL; xfer->ring_entry = -1; xfer->response = resp; if (tid != xfer->cmd_tid) { @@ -618,15 +651,14 @@ static void hci_dma_xfer_done(struct i3c_hci *hci, struct hci_rh_data *rh) done_ptr = (done_ptr + 1) % rh->xfer_entries; rh->done_ptr = done_ptr; + done_cnt += 1; } - /* take care to update the software dequeue pointer atomically */ - spin_lock(&rh->lock); + rh->xfer_space += done_cnt; op1_val = rh_reg_read(RING_OPERATION1); op1_val &= ~RING_OP1_CR_SW_DEQ_PTR; op1_val |= FIELD_PREP(RING_OP1_CR_SW_DEQ_PTR, done_ptr); rh_reg_write(RING_OPERATION1, op1_val); - spin_unlock(&rh->lock); } static int hci_dma_request_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev, @@ -636,7 +668,7 @@ static int hci_dma_request_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev, struct i3c_generic_ibi_pool *pool; struct hci_dma_dev_ibi_data *dev_ibi; - dev_ibi = kmalloc(sizeof(*dev_ibi), GFP_KERNEL); + dev_ibi = kmalloc_obj(*dev_ibi); if (!dev_ibi) return -ENOMEM; pool = i3c_generic_ibi_alloc_pool(dev, req); @@ -806,13 +838,10 @@ static void hci_dma_process_ibi(struct i3c_hci *hci, struct hci_rh_data *rh) i3c_master_queue_ibi(dev, slot); done: - /* take care to update the ibi dequeue pointer atomically */ - spin_lock(&rh->lock); op1_val = rh_reg_read(RING_OPERATION1); op1_val &= ~RING_OP1_IBI_DEQ_PTR; op1_val |= FIELD_PREP(RING_OP1_IBI_DEQ_PTR, deq_ptr); rh_reg_write(RING_OPERATION1, op1_val); - spin_unlock(&rh->lock); /* update the chunk pointer */ rh->ibi_chunk_ptr += ibi_chunks; @@ -846,29 +875,8 @@ static bool hci_dma_irq_handler(struct i3c_hci *hci) hci_dma_xfer_done(hci, rh); if (status & INTR_RING_OP) complete(&rh->op_done); - - if (status & INTR_TRANSFER_ABORT) { - u32 ring_status; - - dev_notice_ratelimited(&hci->master.dev, - "Ring %d: Transfer Aborted\n", i); - mipi_i3c_hci_resume(hci); - ring_status = rh_reg_read(RING_STATUS); - if (!(ring_status & RING_STATUS_RUNNING) && - status & INTR_TRANSFER_COMPLETION && - status & INTR_TRANSFER_ERR) { - /* - * Ring stop followed by run is an Intel - * specific required quirk after resuming the - * halted controller. Do it only when the ring - * is not in running state after a transfer - * error. - */ - rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE); - rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | - RING_CTRL_RUN_STOP); - } - } + if (status & INTR_TRANSFER_ABORT) + dev_dbg(&hci->master.dev, "Ring %d: Transfer Aborted\n", i); if (status & INTR_IBI_RING_FULL) dev_err_ratelimited(&hci->master.dev, "Ring %d: IBI Ring Full Condition\n", i); @@ -884,6 +892,7 @@ const struct hci_io_ops mipi_i3c_hci_dma = { .cleanup = hci_dma_cleanup, .queue_xfer = hci_dma_queue_xfer, .dequeue_xfer = hci_dma_dequeue_xfer, + .handle_error = hci_dma_handle_error, .irq_handler = hci_dma_irq_handler, .request_ibi = hci_dma_request_ibi, .free_ibi = hci_dma_free_ibi, diff --git a/drivers/i3c/master/mipi-i3c-hci/hci.h b/drivers/i3c/master/mipi-i3c-hci/hci.h index 6035f74212db..9ac9d0e342f4 100644 --- a/drivers/i3c/master/mipi-i3c-hci/hci.h +++ b/drivers/i3c/master/mipi-i3c-hci/hci.h @@ -50,6 +50,8 @@ struct i3c_hci { const struct hci_io_ops *io; void *io_data; const struct hci_cmd_ops *cmd; + spinlock_t lock; + struct mutex control_mutex; atomic_t next_cmd_tid; bool irq_inactive; u32 caps; @@ -87,6 +89,7 @@ struct hci_xfer { unsigned int data_len; unsigned int cmd_tid; struct completion *completion; + unsigned long timeout; union { struct { /* PIO specific */ @@ -107,7 +110,7 @@ struct hci_xfer { static inline struct hci_xfer *hci_alloc_xfer(unsigned int n) { - return kcalloc(n, sizeof(struct hci_xfer), GFP_KERNEL); + return kzalloc_objs(struct hci_xfer, n); } static inline void hci_free_xfer(struct hci_xfer *xfer, unsigned int n) @@ -120,6 +123,7 @@ struct hci_io_ops { bool (*irq_handler)(struct i3c_hci *hci); int (*queue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n); bool (*dequeue_xfer)(struct i3c_hci *hci, struct hci_xfer *xfer, int n); + int (*handle_error)(struct i3c_hci *hci, struct hci_xfer *xfer, int n); int (*request_ibi)(struct i3c_hci *hci, struct i3c_dev_desc *dev, const struct i3c_ibi_setup *req); void (*free_ibi)(struct i3c_hci *hci, struct i3c_dev_desc *dev); @@ -154,5 +158,6 @@ void mipi_i3c_hci_dct_index_reset(struct i3c_hci *hci); void amd_set_od_pp_timing(struct i3c_hci *hci); void amd_set_resp_buf_thld(struct i3c_hci *hci); void i3c_hci_sync_irq_inactive(struct i3c_hci *hci); +int i3c_hci_process_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n); #endif diff --git a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c index 0f05a15c14c7..30302e4d08e2 100644 --- a/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c +++ b/drivers/i3c/master/mipi-i3c-hci/mipi-i3c-hci-pci.c @@ -242,7 +242,7 @@ static void mipi_i3c_hci_pci_setup_cell(struct mipi_i3c_hci_pci *hci, int idx, cell->resources = &data->res; } -#define mipi_i3c_hci_pci_alloc(h, x) kcalloc((h)->info->instance_count, sizeof(*(x)), GFP_KERNEL) +#define mipi_i3c_hci_pci_alloc(h, x) kzalloc_objs(*(x), (h)->info->instance_count) static int mipi_i3c_hci_pci_add_instances(struct mipi_i3c_hci_pci *hci) { diff --git a/drivers/i3c/master/mipi-i3c-hci/pio.c b/drivers/i3c/master/mipi-i3c-hci/pio.c index 8e868e81acda..8f48a81e65ab 100644 --- a/drivers/i3c/master/mipi-i3c-hci/pio.c +++ b/drivers/i3c/master/mipi-i3c-hci/pio.c @@ -123,7 +123,6 @@ struct hci_pio_ibi_data { }; struct hci_pio_data { - spinlock_t lock; struct hci_xfer *curr_xfer, *xfer_queue; struct hci_xfer *curr_rx, *rx_queue; struct hci_xfer *curr_tx, *tx_queue; @@ -212,7 +211,6 @@ static int hci_pio_init(struct i3c_hci *hci) return -ENOMEM; hci->io_data = pio; - spin_lock_init(&pio->lock); __hci_pio_init(hci, &size_val); @@ -631,7 +629,7 @@ static int hci_pio_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n) xfer[i].data_left = xfer[i].data_len; } - spin_lock_irq(&pio->lock); + spin_lock_irq(&hci->lock); prev_queue_tail = pio->xfer_queue; pio->xfer_queue = &xfer[n - 1]; if (pio->curr_xfer) { @@ -645,7 +643,7 @@ static int hci_pio_queue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int n) pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE)); } - spin_unlock_irq(&pio->lock); + spin_unlock_irq(&hci->lock); return 0; } @@ -716,14 +714,14 @@ static bool hci_pio_dequeue_xfer(struct i3c_hci *hci, struct hci_xfer *xfer, int struct hci_pio_data *pio = hci->io_data; int ret; - spin_lock_irq(&pio->lock); + spin_lock_irq(&hci->lock); dev_dbg(&hci->master.dev, "n=%d status=%#x/%#x", n, pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE)); dev_dbg(&hci->master.dev, "main_status = %#x/%#x", readl(hci->base_regs + 0x20), readl(hci->base_regs + 0x28)); ret = hci_pio_dequeue_xfer_common(hci, pio, xfer, n); - spin_unlock_irq(&pio->lock); + spin_unlock_irq(&hci->lock); return ret; } @@ -977,7 +975,7 @@ static int hci_pio_request_ibi(struct i3c_hci *hci, struct i3c_dev_desc *dev, struct i3c_generic_ibi_pool *pool; struct hci_pio_dev_ibi_data *dev_ibi; - dev_ibi = kmalloc(sizeof(*dev_ibi), GFP_KERNEL); + dev_ibi = kmalloc_obj(*dev_ibi); if (!dev_ibi) return -ENOMEM; pool = i3c_generic_ibi_alloc_pool(dev, req); @@ -1016,15 +1014,12 @@ static bool hci_pio_irq_handler(struct i3c_hci *hci) struct hci_pio_data *pio = hci->io_data; u32 status; - spin_lock(&pio->lock); status = pio_reg_read(INTR_STATUS); dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x", status, pio->enabled_irqs); status &= pio->enabled_irqs | STAT_LATENCY_WARNINGS; - if (!status) { - spin_unlock(&pio->lock); + if (!status) return false; - } if (status & STAT_IBI_STATUS_THLD) hci_pio_process_ibi(hci, pio); @@ -1058,7 +1053,6 @@ static bool hci_pio_irq_handler(struct i3c_hci *hci) pio_reg_write(INTR_SIGNAL_ENABLE, pio->enabled_irqs); dev_dbg(&hci->master.dev, "PIO_INTR_STATUS %#x/%#x", pio_reg_read(INTR_STATUS), pio_reg_read(INTR_SIGNAL_ENABLE)); - spin_unlock(&pio->lock); return true; } diff --git a/drivers/i3c/master/renesas-i3c.c b/drivers/i3c/master/renesas-i3c.c index 528bccc2c68e..d9f5b30a4b2f 100644 --- a/drivers/i3c/master/renesas-i3c.c +++ b/drivers/i3c/master/renesas-i3c.c @@ -345,7 +345,7 @@ static struct renesas_i3c_xfer *renesas_i3c_alloc_xfer(struct renesas_i3c *i3c, { struct renesas_i3c_xfer *xfer; - xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL); + xfer = kzalloc_flex(*xfer, cmds, ncmds); if (!xfer) return NULL; @@ -874,7 +874,7 @@ static int renesas_i3c_attach_i3c_dev(struct i3c_dev_desc *dev) if (pos < 0) return pos; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -984,7 +984,7 @@ static int renesas_i3c_attach_i2c_dev(struct i2c_dev_desc *dev) if (pos < 0) return pos; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index 857504d36e18..b84b324e4111 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -900,7 +900,7 @@ static int svc_i3c_master_attach_i3c_dev(struct i3c_dev_desc *dev) if (slot < 0) return slot; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { svc_i3c_master_release_slot(master, slot); return -ENOMEM; @@ -953,7 +953,7 @@ static int svc_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev) if (slot < 0) return slot; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { svc_i3c_master_release_slot(master, slot); return -ENOMEM; @@ -1504,7 +1504,7 @@ svc_i3c_master_alloc_xfer(struct svc_i3c_master *master, unsigned int ncmds) { struct svc_i3c_xfer *xfer; - xfer = kzalloc(struct_size(xfer, cmds, ncmds), GFP_KERNEL); + xfer = kzalloc_flex(*xfer, cmds, ncmds); if (!xfer) return NULL; diff --git a/drivers/iio/accel/Kconfig b/drivers/iio/accel/Kconfig index 76911278fb21..3d3f8d8673dd 100644 --- a/drivers/iio/accel/Kconfig +++ b/drivers/iio/accel/Kconfig @@ -64,7 +64,7 @@ config ADXL345 config ADXL345_I2C tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer I2C Driver" - depends on INPUT_ADXL34X=n + depends on !INPUT_ADXL34X depends on I2C select ADXL345 select REGMAP_I2C @@ -74,11 +74,12 @@ config ADXL345_I2C To compile this driver as a module, choose M here: the module will be called adxl345_i2c and you will also get adxl345_core - for the core module. + for the core module. INPUT_ADXL34X share compatibles with this + driver, do not add both modules to the kernel. config ADXL345_SPI tristate "Analog Devices ADXL345 3-Axis Digital Accelerometer SPI Driver" - depends on INPUT_ADXL34X=n + depends on !INPUT_ADXL34X depends on SPI select ADXL345 select REGMAP_SPI @@ -88,7 +89,8 @@ config ADXL345_SPI To compile this driver as a module, choose M here: the module will be called adxl345_spi and you will also get adxl345_core - for the core module. + for the core module. INPUT_ADXL34X share compatibles with this + driver, do not add both modules to the kernel. config ADXL355 tristate diff --git a/drivers/iio/accel/adxl355_core.c b/drivers/iio/accel/adxl355_core.c index 5fc7f814b907..1c1d64d5cbcb 100644 --- a/drivers/iio/accel/adxl355_core.c +++ b/drivers/iio/accel/adxl355_core.c @@ -768,9 +768,8 @@ static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq) data->dready_trig->ops = &adxl355_trigger_ops; iio_trigger_set_drvdata(data->dready_trig, indio_dev); - ret = devm_request_irq(data->dev, irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_ONESHOT, "adxl355_irq", data->dready_trig); + ret = devm_request_irq(data->dev, irq, &iio_trigger_generic_data_rdy_poll, + IRQF_NO_THREAD, "adxl355_irq", data->dready_trig); if (ret) return dev_err_probe(data->dev, ret, "request irq %d failed\n", irq); diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c index 46d518a2a029..28a8793a53b6 100644 --- a/drivers/iio/accel/adxl372.c +++ b/drivers/iio/accel/adxl372.c @@ -295,7 +295,6 @@ struct adxl372_state { u32 inact_time_ms; u8 fifo_set_size; unsigned long int1_bitmask; - unsigned long int2_bitmask; u16 watermark; __be16 fifo_buf[ADXL372_FIFO_SIZE]; bool peak_fifo_mode_en; @@ -1247,11 +1246,10 @@ int adxl372_probe(struct device *dev, struct regmap *regmap, indio_dev->trig = iio_trigger_get(st->dready_trig); - ret = devm_request_threaded_irq(dev, st->irq, - iio_trigger_generic_data_rdy_poll, - NULL, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - indio_dev->name, st->dready_trig); + ret = devm_request_irq(dev, st->irq, + iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + indio_dev->name, st->dready_trig); if (ret < 0) return ret; } diff --git a/drivers/iio/accel/adxl380.c b/drivers/iio/accel/adxl380.c index aef5109c1ddd..8fab2fdbe147 100644 --- a/drivers/iio/accel/adxl380.c +++ b/drivers/iio/accel/adxl380.c @@ -232,25 +232,46 @@ bool adxl380_readable_noinc_reg(struct device *dev, unsigned int reg) } EXPORT_SYMBOL_NS_GPL(adxl380_readable_noinc_reg, "IIO_ADXL380"); +static int adxl380_act_inact_enabled(struct adxl380_state *st, bool *enabled) +{ + unsigned int act_inact_ctl; + int ret; + + if (!st->chip_info->has_low_power) { + *enabled = false; + return 0; + } + + ret = regmap_read(st->regmap, ADXL380_ACT_INACT_CTL_REG, &act_inact_ctl); + if (ret) + return ret; + + *enabled = FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || + FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl); + + return 0; +} + static int adxl380_set_measure_en(struct adxl380_state *st, bool en) { int ret; - unsigned int act_inact_ctl; u8 op_mode = ADXL380_OP_MODE_STANDBY; if (en) { - ret = regmap_read(st->regmap, ADXL380_ACT_INACT_CTL_REG, &act_inact_ctl); + bool act_inact_enabled; + + ret = adxl380_act_inact_enabled(st, &act_inact_enabled); if (ret) return ret; /* * Activity/Inactivity detection available only in VLP/ULP - * mode and for devices that support low power modes. Otherwise - * go straight to measure mode (same bits as ADXL380_OP_MODE_HP). + * mode and for devices that support low power modes. */ - if (st->chip_info->has_low_power && - (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || - FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl))) + if (act_inact_enabled) + st->odr = ADXL380_ODR_VLP; + + if (st->odr == ADXL380_ODR_VLP) op_mode = ADXL380_OP_MODE_VLP; else op_mode = ADXL380_OP_MODE_HP; @@ -417,17 +438,7 @@ static int adxl380_read_chn(struct adxl380_state *st, u8 addr) static int adxl380_get_odr(struct adxl380_state *st, int *odr) { - int ret; - unsigned int trig_cfg, odr_idx; - - ret = regmap_read(st->regmap, ADXL380_TRIG_CFG_REG, &trig_cfg); - if (ret) - return ret; - - odr_idx = (FIELD_GET(ADXL380_TRIG_CFG_SINC_RATE_MSK, trig_cfg) << 1) | - (FIELD_GET(ADXL380_TRIG_CFG_DEC_2X_MSK, trig_cfg) & 1); - - *odr = st->chip_info->samp_freq_tbl[odr_idx]; + *odr = st->chip_info->samp_freq_tbl[st->odr]; return 0; } @@ -488,18 +499,24 @@ static int adxl380_set_odr(struct adxl380_state *st, u8 odr) if (ret) return ret; - ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, - ADXL380_TRIG_CFG_DEC_2X_MSK, - FIELD_PREP(ADXL380_TRIG_CFG_DEC_2X_MSK, odr & 1)); - if (ret) - return ret; + if (odr >= ADXL380_ODR_DSM) { + u8 mul = odr - ADXL380_ODR_DSM; + u8 field; - ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, - ADXL380_TRIG_CFG_SINC_RATE_MSK, - FIELD_PREP(ADXL380_TRIG_CFG_SINC_RATE_MSK, odr >> 1)); - if (ret) - return ret; + field = FIELD_PREP(ADXL380_TRIG_CFG_DEC_2X_MSK, mul & 1); + ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, + ADXL380_TRIG_CFG_DEC_2X_MSK, field); + if (ret) + return ret; + field = FIELD_PREP(ADXL380_TRIG_CFG_SINC_RATE_MSK, mul >> 1); + ret = regmap_update_bits(st->regmap, ADXL380_TRIG_CFG_REG, + ADXL380_TRIG_CFG_SINC_RATE_MSK, field); + if (ret) + return ret; + } + + st->odr = odr; ret = adxl380_set_measure_en(st, true); if (ret) return ret; @@ -949,14 +966,13 @@ static irqreturn_t adxl380_irq_handler(int irq, void *p) if (ret) return IRQ_HANDLED; - for (i = 0; i < fifo_entries; i += st->fifo_set_size) { - ret = regmap_noinc_read(st->regmap, ADXL380_FIFO_DATA, - &st->fifo_buf[i], - 2 * st->fifo_set_size); - if (ret) - return IRQ_HANDLED; + fifo_entries = rounddown(fifo_entries, st->fifo_set_size); + ret = regmap_noinc_read(st->regmap, ADXL380_FIFO_DATA, &st->fifo_buf, + sizeof(*st->fifo_buf) * fifo_entries); + if (ret) + return IRQ_HANDLED; + for (i = 0; i < fifo_entries; i += st->fifo_set_size) iio_push_to_buffers(indio_dev, &st->fifo_buf[i]); - } return IRQ_HANDLED; } @@ -1138,6 +1154,32 @@ static const struct iio_buffer_setup_ops adxl380_buffer_ops = { .predisable = adxl380_buffer_predisable, }; +static int adxl380_samp_freq_avail(struct adxl380_state *st, const int **vals, + int *length) +{ + bool act_inact_enabled; + int ret; + + if (!st->chip_info->has_low_power) { + *vals = st->chip_info->samp_freq_tbl + ADXL380_ODR_DSM; + *length = ADXL380_ODR_MAX - ADXL380_ODR_DSM; + return 0; + } + + ret = adxl380_act_inact_enabled(st, &act_inact_enabled); + if (ret) + return 0; + + /* + * Motion detection is only functional in low-power mode, and this + * affects the available sampling frequencies. + */ + *vals = st->chip_info->samp_freq_tbl; + *length = act_inact_enabled ? ADXL380_ODR_DSM : ADXL380_ODR_MAX; + + return 0; +} + static int adxl380_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long info) @@ -1218,6 +1260,7 @@ static int adxl380_read_avail(struct iio_dev *indio_dev, long mask) { struct adxl380_state *st = iio_priv(indio_dev); + int ret; if (chan->type != IIO_ACCEL) return -EINVAL; @@ -1229,9 +1272,11 @@ static int adxl380_read_avail(struct iio_dev *indio_dev, *length = ARRAY_SIZE(st->chip_info->scale_tbl) * 2; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_SAMP_FREQ: - *vals = (const int *)st->chip_info->samp_freq_tbl; + ret = adxl380_samp_freq_avail(st, vals, length); + if (ret) + return ret; + *type = IIO_VAL_INT; - *length = ARRAY_SIZE(st->chip_info->samp_freq_tbl); return IIO_AVAIL_LIST; case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: *vals = (const int *)st->lpf_tbl; @@ -1254,12 +1299,16 @@ static int adxl380_write_raw(struct iio_dev *indio_dev, int val, int val2, long info) { struct adxl380_state *st = iio_priv(indio_dev); - int odr_index, lpf_index, hpf_index, range_index; + const int *freq_vals; + int odr_index, lpf_index, hpf_index, range_index, freq_count, ret; switch (info) { case IIO_CHAN_INFO_SAMP_FREQ: - odr_index = adxl380_find_match_1d_tbl(st->chip_info->samp_freq_tbl, - ARRAY_SIZE(st->chip_info->samp_freq_tbl), + ret = adxl380_samp_freq_avail(st, &freq_vals, &freq_count); + if (ret) + return ret; + + odr_index = adxl380_find_match_1d_tbl(freq_vals, freq_count, val); return adxl380_set_odr(st, odr_index); case IIO_CHAN_INFO_CALIBBIAS: @@ -1621,7 +1670,7 @@ const struct adxl380_chip_info adxl318_chip_info = { [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, }, - .samp_freq_tbl = { 8000, 16000, 32000 }, + .samp_freq_tbl = { 0, 8000, 16000, 32000 }, /* * The datasheet defines an intercept of 550 LSB at 25 degC * and a sensitivity of 10.2 LSB/C. @@ -1639,7 +1688,7 @@ const struct adxl380_chip_info adxl319_chip_info = { [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, }, - .samp_freq_tbl = { 16000, 32000, 64000 }, + .samp_freq_tbl = { 0, 16000, 32000, 64000 }, /* * The datasheet defines an intercept of 550 LSB at 25 degC * and a sensitivity of 10.2 LSB/C. @@ -1657,7 +1706,7 @@ const struct adxl380_chip_info adxl380_chip_info = { [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, }, - .samp_freq_tbl = { 8000, 16000, 32000 }, + .samp_freq_tbl = { 1000, 8000, 16000, 32000 }, /* * The datasheet defines an intercept of 470 LSB at 25 degC * and a sensitivity of 10.2 LSB/C. @@ -1677,7 +1726,7 @@ const struct adxl380_chip_info adxl382_chip_info = { [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, }, - .samp_freq_tbl = { 16000, 32000, 64000 }, + .samp_freq_tbl = { 1000, 16000, 32000, 64000 }, /* * The datasheet defines an intercept of 570 LSB at 25 degC * and a sensitivity of 10.2 LSB/C. @@ -1916,6 +1965,7 @@ int adxl380_probe(struct device *dev, struct regmap *regmap, st->dev = dev; st->regmap = regmap; st->chip_info = chip_info; + st->odr = ADXL380_ODR_DSM; mutex_init(&st->lock); diff --git a/drivers/iio/accel/adxl380.h b/drivers/iio/accel/adxl380.h index e67c5aab8efc..d2c260c8b2fa 100644 --- a/drivers/iio/accel/adxl380.h +++ b/drivers/iio/accel/adxl380.h @@ -8,10 +8,18 @@ #ifndef _ADXL380_H_ #define _ADXL380_H_ +enum adxl380_odr { + ADXL380_ODR_VLP, + ADXL380_ODR_DSM, + ADXL380_ODR_DSM_2X, + ADXL380_ODR_DSM_4X, + ADXL380_ODR_MAX +}; + struct adxl380_chip_info { const char *name; const int scale_tbl[3][2]; - const int samp_freq_tbl[3]; + const int samp_freq_tbl[ADXL380_ODR_MAX]; const struct iio_info *info; const int temp_offset; const u16 chip_id; diff --git a/drivers/iio/accel/bma180.c b/drivers/iio/accel/bma180.c index 8925f5279e62..7bc6761f5135 100644 --- a/drivers/iio/accel/bma180.c +++ b/drivers/iio/accel/bma180.c @@ -986,8 +986,9 @@ static int bma180_probe(struct i2c_client *client) } ret = devm_request_irq(dev, client->irq, - iio_trigger_generic_data_rdy_poll, IRQF_TRIGGER_RISING, - "bma180_event", data->trig); + iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + "bma180_event", data->trig); if (ret) { dev_err(dev, "unable to request IRQ\n"); goto err_trigger_free; diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c index ac973d871c8b..a2c3cf13d098 100644 --- a/drivers/iio/accel/mxc4005.c +++ b/drivers/iio/accel/mxc4005.c @@ -486,13 +486,10 @@ static int mxc4005_probe(struct i2c_client *client) if (!data->dready_trig) return -ENOMEM; - ret = devm_request_threaded_irq(&client->dev, client->irq, - iio_trigger_generic_data_rdy_poll, - NULL, - IRQF_TRIGGER_FALLING | - IRQF_ONESHOT, - "mxc4005_event", - data->dready_trig); + ret = devm_request_irq(&client->dev, client->irq, + iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_FALLING | IRQF_NO_THREAD, + "mxc4005_event", data->dready_trig); if (ret) { dev_err(&client->dev, "failed to init threaded irq\n"); diff --git a/drivers/iio/accel/sca3000.c b/drivers/iio/accel/sca3000.c index bfa8a3f5a92f..4a827be439a2 100644 --- a/drivers/iio/accel/sca3000.c +++ b/drivers/iio/accel/sca3000.c @@ -153,7 +153,6 @@ * struct sca3000_state - device instance state information * @us: the associated spi device * @info: chip variant information - * @last_timestamp: the timestamp of the last event * @mo_det_use_count: reference counter for the motion detection unit * @lock: lock used to protect elements of sca3000_state * and the underlying device state. @@ -163,7 +162,6 @@ struct sca3000_state { struct spi_device *us; const struct sca3000_chip_info *info; - s64 last_timestamp; int mo_det_use_count; struct mutex lock; /* Can these share a cacheline ? */ @@ -1489,7 +1487,11 @@ static int sca3000_probe(struct spi_device *spi) if (ret) goto error_free_irq; - return iio_device_register(indio_dev); + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_irq; + + return 0; error_free_irq: if (spi->irq) diff --git a/drivers/iio/accel/stk8ba50.c b/drivers/iio/accel/stk8ba50.c index 384f1fbcbcb3..a9ff2a273fe1 100644 --- a/drivers/iio/accel/stk8ba50.c +++ b/drivers/iio/accel/stk8ba50.c @@ -428,13 +428,10 @@ static int stk8ba50_probe(struct i2c_client *client) } if (client->irq > 0) { - ret = devm_request_threaded_irq(&client->dev, client->irq, - stk8ba50_data_rdy_trig_poll, - NULL, - IRQF_TRIGGER_RISING | - IRQF_ONESHOT, - "stk8ba50_event", - indio_dev); + ret = devm_request_irq(&client->dev, client->irq, + stk8ba50_data_rdy_trig_poll, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + "stk8ba50_event", indio_dev); if (ret < 0) { dev_err(&client->dev, "request irq %d failed\n", client->irq); diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 58da8255525e..60038ae8dfc4 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig @@ -70,6 +70,19 @@ config AD4030 To compile this driver as a module, choose M here: the module will be called ad4030. +config AD4062 + tristate "Analog Devices AD4062 Driver" + depends on I3C + select REGMAP_I3C + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for Analog Devices AD4062 I3C analog + to digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4062. + config AD4080 tristate "Analog Devices AD4080 high speed ADC" depends on SPI @@ -99,6 +112,17 @@ config AD4130 To compile this driver as a module, choose M here: the module will be called ad4130. +config AD4134 + tristate "Analog Device AD4134 ADC Driver" + depends on SPI + select REGMAP_SPI + select CRC8 + help + Say yes here to build support for Analog Devices AD4134 SPI analog to + digital converters (ADC). + + To compile this driver as a module, choose M here: the module will be + called ad4134_spi. config AD4170_4 tristate "Analog Device AD4170-4 ADC Driver" @@ -387,6 +411,7 @@ config AD7768_1 depends on SPI select REGULATOR select REGMAP_SPI + select RATIONAL select IIO_BUFFER select IIO_TRIGGER select IIO_TRIGGERED_BUFFER @@ -1222,6 +1247,18 @@ config NPCM_ADC This driver can also be built as a module. If so, the module will be called npcm_adc. +config NXP_SAR_ADC + tristate "NXP S32G SAR-ADC driver" + depends on ARCH_S32 || COMPILE_TEST + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + Say yes here to build support for S32G platforms + analog-to-digital converter. + + This driver can also be built as a module. If so, the module will be + called nxp_sar_adc. + config PAC1921 tristate "Microchip Technology PAC1921 driver" depends on I2C @@ -1664,6 +1701,18 @@ config TI_ADS1015 This driver can also be built as a module. If so, the module will be called ti-ads1015. +config TI_ADS1018 + tristate "Texas Instruments ADS1018 ADC" + depends on SPI + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + help + If you say yes here you get support for Texas Instruments ADS1018 and + ADS1118 ADC chips. + + This driver can also be built as a module. If so, the module will be + called ti-ads1018. + config TI_ADS1100 tristate "Texas Instruments ADS1100 and ADS1000 ADC" depends on I2C @@ -1722,6 +1771,17 @@ config TI_ADS131E08 This driver can also be built as a module. If so, the module will be called ti-ads131e08. +config TI_ADS131M02 + tristate "Texas Instruments ADS131M02" + depends on SPI && REGULATOR + select CRC_ITU_T + help + Say yes here to get support for Texas Instruments ADS131M02, ADS131M03, + ADS131M04, ADS131M06 and ADS131M08 chips. + + This driver can also be built as a module. If so, the module will be + called ti-ads131m02. + config TI_ADS7138 tristate "Texas Instruments ADS7128 and ADS7138 ADC driver" depends on I2C diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 7cc8f9a12f76..c76550415ff1 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile @@ -11,8 +11,10 @@ obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_AD_SIGMA_DELTA) += ad_sigma_delta.o obj-$(CONFIG_AD4000) += ad4000.o obj-$(CONFIG_AD4030) += ad4030.o +obj-$(CONFIG_AD4062) += ad4062.o obj-$(CONFIG_AD4080) += ad4080.o obj-$(CONFIG_AD4130) += ad4130.o +obj-$(CONFIG_AD4134) += ad4134.o obj-$(CONFIG_AD4170_4) += ad4170-4.o obj-$(CONFIG_AD4695) += ad4695.o obj-$(CONFIG_AD4851) += ad4851.o @@ -108,6 +110,7 @@ obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o obj-$(CONFIG_NAU7802) += nau7802.o obj-$(CONFIG_NCT7201) += nct7201.o obj-$(CONFIG_NPCM_ADC) += npcm_adc.o +obj-$(CONFIG_NXP_SAR_ADC) += nxp-sar-adc.o obj-$(CONFIG_PAC1921) += pac1921.o obj-$(CONFIG_PAC1934) += pac1934.o obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o @@ -145,11 +148,13 @@ obj-$(CONFIG_TI_ADC12138) += ti-adc12138.o obj-$(CONFIG_TI_ADC128S052) += ti-adc128s052.o obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o +obj-$(CONFIG_TI_ADS1018) += ti-ads1018.o obj-$(CONFIG_TI_ADS1100) += ti-ads1100.o obj-$(CONFIG_TI_ADS1119) += ti-ads1119.o obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o obj-$(CONFIG_TI_ADS1298) += ti-ads1298.o obj-$(CONFIG_TI_ADS131E08) += ti-ads131e08.o +obj-$(CONFIG_TI_ADS131M02) += ti-ads131m02.o obj-$(CONFIG_TI_ADS7138) += ti-ads7138.o obj-$(CONFIG_TI_ADS7924) += ti-ads7924.o obj-$(CONFIG_TI_ADS7950) += ti-ads7950.o diff --git a/drivers/iio/adc/ad4062.c b/drivers/iio/adc/ad4062.c new file mode 100644 index 000000000000..dd4ad32aa6f5 --- /dev/null +++ b/drivers/iio/adc/ad4062.c @@ -0,0 +1,1609 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD4062 I3C ADC driver + * + * Copyright 2025 Analog Devices Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD4062_REG_INTERFACE_CONFIG_A 0x00 +#define AD4062_REG_DEVICE_CONFIG 0x02 +#define AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK GENMASK(1, 0) +#define AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE 3 +#define AD4062_REG_PROD_ID_1 0x05 +#define AD4062_REG_DEVICE_GRADE 0x06 +#define AD4062_REG_SCRATCH_PAD 0x0A +#define AD4062_REG_VENDOR_H 0x0D +#define AD4062_REG_STREAM_MODE 0x0E +#define AD4062_REG_INTERFACE_STATUS 0x11 +#define AD4062_REG_MODE_SET 0x20 +#define AD4062_REG_MODE_SET_ENTER_ADC BIT(0) +#define AD4062_REG_ADC_MODES 0x21 +#define AD4062_REG_ADC_MODES_MODE_MSK GENMASK(1, 0) +#define AD4062_REG_ADC_CONFIG 0x22 +#define AD4062_REG_ADC_CONFIG_REF_EN_MSK BIT(5) +#define AD4062_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) +#define AD4062_REG_AVG_CONFIG 0x23 +#define AD4062_REG_GP_CONF 0x24 +#define AD4062_REG_GP_CONF_MODE_MSK_0 GENMASK(2, 0) +#define AD4062_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) +#define AD4062_REG_INTR_CONF 0x25 +#define AD4062_REG_INTR_CONF_EN_MSK_0 GENMASK(1, 0) +#define AD4062_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) +#define AD4062_REG_TIMER_CONFIG 0x27 +#define AD4062_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) +#define AD4062_REG_MAX_LIMIT 0x29 +#define AD4062_REG_MIN_LIMIT 0x2B +#define AD4062_REG_MAX_HYST 0x2C +#define AD4062_REG_MIN_HYST 0x2D +#define AD4062_REG_MON_VAL 0x2F +#define AD4062_REG_ADC_IBI_EN 0x31 +#define AD4062_REG_ADC_IBI_EN_CONV_TRIGGER BIT(2) +#define AD4062_REG_ADC_IBI_EN_MAX BIT(1) +#define AD4062_REG_ADC_IBI_EN_MIN BIT(0) +#define AD4062_REG_FUSE_CRC 0x40 +#define AD4062_REG_DEVICE_STATUS 0x41 +#define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) +#define AD4062_REG_IBI_STATUS 0x48 +#define AD4062_REG_CONV_READ_LSB 0x50 +#define AD4062_REG_CONV_READ_16BITS 0x51 +#define AD4062_REG_CONV_READ_32BITS 0x53 +#define AD4062_REG_CONV_TRIGGER_16BITS 0x57 +#define AD4062_REG_CONV_TRIGGER_32BITS 0x59 +#define AD4062_REG_CONV_AUTO 0x61 +#define AD4062_MAX_REG AD4062_REG_CONV_AUTO + +#define AD4062_MON_VAL_MIDDLE_POINT 0x8000 + +#define AD4062_I3C_VENDOR 0x0177 +#define AD4062_SOFT_RESET 0x81 +#define AD4060_PROD_ID 0x7A +#define AD4062_PROD_ID 0x7C + +#define AD4062_GP_DISABLED 0x0 +#define AD4062_GP_INTR 0x1 +#define AD4062_GP_DRDY 0x2 +#define AD4062_GP_STATIC_LOW 0x5 +#define AD4062_GP_STATIC_HIGH 0x6 + +#define AD4062_LIMIT_BITS 12 + +#define AD4062_INTR_EN_NEITHER 0x0 +#define AD4062_INTR_EN_EITHER 0x3 + +#define AD4062_TCONV_NS 270 + +enum ad4062_operation_mode { + AD4062_SAMPLE_MODE = 0x0, + AD4062_BURST_AVERAGING_MODE = 0x1, + AD4062_MONITOR_MODE = 0x3, +}; + +struct ad4062_chip_info { + const struct iio_chan_spec channels[1]; + const char *name; + u16 prod_id; + u16 avg_max; +}; + +enum { + AD4062_SCAN_TYPE_SAMPLE, + AD4062_SCAN_TYPE_BURST_AVG, +}; + +static const struct iio_scan_type ad4062_scan_type_12_s[] = { + [AD4062_SCAN_TYPE_SAMPLE] = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + .endianness = IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] = { + .sign = 's', + .realbits = 14, + .storagebits = 16, + .endianness = IIO_BE, + }, +}; + +static const struct iio_scan_type ad4062_scan_type_16_s[] = { + [AD4062_SCAN_TYPE_SAMPLE] = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_BE, + }, + [AD4062_SCAN_TYPE_BURST_AVG] = { + .sign = 's', + .realbits = 20, + .storagebits = 32, + .endianness = IIO_BE, + }, +}; + +static const unsigned int ad4062_conversion_freqs[] = { + 2000000, 1000000, 300000, 100000, /* 0 - 3 */ + 33300, 10000, 3000, 500, /* 4 - 7 */ + 333, 250, 200, 166, /* 8 - 11 */ + 140, 124, 111, /* 12 - 15 */ +}; + +struct ad4062_state { + const struct ad4062_chip_info *chip; + const struct ad4062_bus_ops *ops; + enum ad4062_operation_mode mode; + struct work_struct trig_conv; + struct completion completion; + struct iio_trigger *trigger; + struct iio_dev *indio_dev; + struct i3c_device *i3cdev; + struct regmap *regmap; + bool wait_event; + int vref_uV; + unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; + bool gpo_irq[2]; + u16 sampling_frequency; + u16 events_frequency; + u8 oversamp_ratio; + u8 conv_sizeof; + u8 conv_addr; + union { + __be32 be32; + __be16 be16; + } buf __aligned(IIO_DMA_MINALIGN); +}; + +static const struct regmap_range ad4062_regmap_rd_ranges[] = { + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_GRADE), + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_INTERFACE_STATUS), + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_IBI_STATUS), + regmap_reg_range(AD4062_REG_CONV_READ_LSB, AD4062_REG_CONV_AUTO), +}; + +static const struct regmap_access_table ad4062_regmap_rd_table = { + .yes_ranges = ad4062_regmap_rd_ranges, + .n_yes_ranges = ARRAY_SIZE(ad4062_regmap_rd_ranges), +}; + +static const struct regmap_range ad4062_regmap_wr_ranges[] = { + regmap_reg_range(AD4062_REG_INTERFACE_CONFIG_A, AD4062_REG_DEVICE_CONFIG), + regmap_reg_range(AD4062_REG_SCRATCH_PAD, AD4062_REG_SCRATCH_PAD), + regmap_reg_range(AD4062_REG_STREAM_MODE, AD4062_REG_INTERFACE_STATUS), + regmap_reg_range(AD4062_REG_MODE_SET, AD4062_REG_ADC_IBI_EN), + regmap_reg_range(AD4062_REG_FUSE_CRC, AD4062_REG_DEVICE_STATUS), +}; + +static const struct regmap_access_table ad4062_regmap_wr_table = { + .yes_ranges = ad4062_regmap_wr_ranges, + .n_yes_ranges = ARRAY_SIZE(ad4062_regmap_wr_ranges), +}; + +static const struct iio_event_spec ad4062_events[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_shared_by_all = BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_RISING, + .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_FALLING, + .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_HYSTERESIS), + }, +}; + +#define AD4062_CHAN(bits) { \ + .type = IIO_VOLTAGE, \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_CALIBSCALE) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .indexed = 1, \ + .channel = 0, \ + .event_spec = ad4062_events, \ + .num_event_specs = ARRAY_SIZE(ad4062_events), \ + .has_ext_scan_type = 1, \ + .ext_scan_type = ad4062_scan_type_##bits##_s, \ + .num_ext_scan_type = ARRAY_SIZE(ad4062_scan_type_##bits##_s), \ +} + +static const struct ad4062_chip_info ad4060_chip_info = { + .name = "ad4060", + .channels = { AD4062_CHAN(12) }, + .prod_id = AD4060_PROD_ID, + .avg_max = 256, +}; + +static const struct ad4062_chip_info ad4062_chip_info = { + .name = "ad4062", + .channels = { AD4062_CHAN(16) }, + .prod_id = AD4062_PROD_ID, + .avg_max = 4096, +}; + +static ssize_t sampling_frequency_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct ad4062_state *st = iio_priv(dev_to_iio_dev(dev)); + + return sysfs_emit(buf, "%d\n", ad4062_conversion_freqs[st->events_frequency]); +} + +static int sampling_frequency_store_dispatch(struct iio_dev *indio_dev, + const char *buf) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int val, ret; + + if (st->wait_event) + return -EBUSY; + + ret = kstrtoint(buf, 10, &val); + if (ret) + return ret; + + st->events_frequency = find_closest_descending(val, ad4062_conversion_freqs, + ARRAY_SIZE(ad4062_conversion_freqs)); + return 0; +} + +static ssize_t sampling_frequency_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = sampling_frequency_store_dispatch(indio_dev, buf); + iio_device_release_direct(indio_dev); + return ret ?: len; +} + +static IIO_DEVICE_ATTR_RW(sampling_frequency, 0); + +static ssize_t sampling_frequency_available_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret = 0; + + for (u8 i = 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) + ret += sysfs_emit_at(buf, ret, "%d%s", ad4062_conversion_freqs[i], + i != (ARRAY_SIZE(ad4062_conversion_freqs) - 1) ? " " : "\n"); + return ret; +} + +static IIO_DEVICE_ATTR_RO(sampling_frequency_available, 0); + +static struct attribute *ad4062_event_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad4062_event_attribute_group = { + .attrs = ad4062_event_attributes, +}; + +static int ad4062_set_oversampling_ratio(struct ad4062_state *st, int val, int val2) +{ + const u32 _max = st->chip->avg_max; + const u32 _min = 1; + int ret; + + if (!in_range(val, _min, _max) || val2 != 0) + return -EINVAL; + + /* 1 disables oversampling */ + val = ilog2(val); + if (val == 0) { + st->mode = AD4062_SAMPLE_MODE; + } else { + st->mode = AD4062_BURST_AVERAGING_MODE; + ret = regmap_write(st->regmap, AD4062_REG_AVG_CONFIG, val - 1); + if (ret) + return ret; + } + st->oversamp_ratio = val; + + return 0; +} + +static int ad4062_get_oversampling_ratio(struct ad4062_state *st, int *val) +{ + int ret, buf; + + if (st->mode == AD4062_SAMPLE_MODE) { + *val = 1; + return 0; + } + + ret = regmap_read(st->regmap, AD4062_REG_AVG_CONFIG, &buf); + if (ret) + return ret; + + *val = BIT(buf + 1); + return 0; +} + +static int ad4062_calc_sampling_frequency(unsigned int fosc, unsigned int oversamp_ratio) +{ + /* From datasheet p.31: (n_avg - 1)/fosc + tconv */ + u32 n_avg = BIT(oversamp_ratio) - 1; + u32 period_ns = NSEC_PER_SEC / fosc; + + /* Result is less than 1 Hz */ + if (n_avg >= fosc) + return 1; + + return NSEC_PER_SEC / (n_avg * period_ns + AD4062_TCONV_NS); +} + +static int ad4062_populate_sampling_frequency(struct ad4062_state *st) +{ + for (u8 i = 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) + st->samp_freqs[i] = + ad4062_calc_sampling_frequency(ad4062_conversion_freqs[i], + st->oversamp_ratio); + return 0; +} + +static int ad4062_get_sampling_frequency(struct ad4062_state *st, int *val) +{ + int freq = ad4062_conversion_freqs[st->sampling_frequency]; + + *val = ad4062_calc_sampling_frequency(freq, st->oversamp_ratio); + return IIO_VAL_INT; +} + +static int ad4062_set_sampling_frequency(struct ad4062_state *st, int val, int val2) +{ + int ret; + + if (val2 != 0) + return -EINVAL; + + ret = ad4062_populate_sampling_frequency(st); + if (ret) + return ret; + + st->sampling_frequency = + find_closest_descending(val, st->samp_freqs, + ARRAY_SIZE(ad4062_conversion_freqs)); + return 0; +} + +static int ad4062_check_ids(struct ad4062_state *st) +{ + struct device *dev = &st->i3cdev->dev; + int ret; + u16 val; + + ret = regmap_bulk_read(st->regmap, AD4062_REG_PROD_ID_1, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + val = be16_to_cpu(st->buf.be16); + if (val != st->chip->prod_id) + dev_warn(dev, "Production ID x%x does not match known values", val); + + ret = regmap_bulk_read(st->regmap, AD4062_REG_VENDOR_H, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + val = be16_to_cpu(st->buf.be16); + if (val != AD4062_I3C_VENDOR) { + dev_err(dev, "Vendor ID x%x does not match expected value\n", val); + return -ENODEV; + } + + return 0; +} + +static int ad4062_conversion_frequency_set(struct ad4062_state *st, u8 val) +{ + return regmap_write(st->regmap, AD4062_REG_TIMER_CONFIG, + FIELD_PREP(AD4062_REG_TIMER_CONFIG_FS_MASK, val)); +} + +static int ad4062_set_operation_mode(struct ad4062_state *st, + enum ad4062_operation_mode mode) +{ + const unsigned int samp_freq = mode == AD4062_MONITOR_MODE ? + st->events_frequency : st->sampling_frequency; + int ret; + + ret = ad4062_conversion_frequency_set(st, samp_freq); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_MODES, + AD4062_REG_ADC_MODES_MODE_MSK, mode); + if (ret) + return ret; + + if (mode == AD4062_MONITOR_MODE) { + /* Change address pointer to enter monitor mode */ + struct i3c_xfer xfer_trigger = { + .data.out = &st->conv_addr, + .len = sizeof(st->conv_addr), + .rnw = false, + }; + st->conv_addr = AD4062_REG_CONV_TRIGGER_32BITS; + return i3c_device_do_xfers(st->i3cdev, &xfer_trigger, 1, I3C_SDR); + } + + return regmap_write(st->regmap, AD4062_REG_MODE_SET, + AD4062_REG_MODE_SET_ENTER_ADC); +} + +static int ad4062_soft_reset(struct ad4062_state *st) +{ + u8 val = AD4062_SOFT_RESET; + int ret; + + ret = regmap_write(st->regmap, AD4062_REG_INTERFACE_CONFIG_A, val); + if (ret) + return ret; + + /* Wait AD4062 treset time, datasheet p8 */ + ndelay(60); + + return 0; +} + +static int ad4062_setup(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + const bool *ref_sel) +{ + struct ad4062_state *st = iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + int ret; + + scan_type = iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_0, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, + AD4062_GP_INTR)); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, + AD4062_GP_DRDY)); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, + AD4062_REG_ADC_CONFIG_REF_EN_MSK, + FIELD_PREP(AD4062_REG_ADC_CONFIG_REF_EN_MSK, + *ref_sel)); + if (ret) + return ret; + + ret = regmap_write(st->regmap, AD4062_REG_DEVICE_STATUS, + AD4062_REG_DEVICE_STATUS_DEVICE_RESET); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_0, + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_0, + AD4062_INTR_EN_EITHER)); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, + AD4062_REG_INTR_CONF_EN_MSK_1, + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, + AD4062_INTR_EN_NEITHER)); + if (ret) + return ret; + + st->buf.be16 = cpu_to_be16(AD4062_MON_VAL_MIDDLE_POINT); + return regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); +} + +static irqreturn_t ad4062_irq_handler_thresh(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + + iio_push_event(indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(indio_dev)); + + return IRQ_HANDLED; +} + +static irqreturn_t ad4062_irq_handler_drdy(int irq, void *private) +{ + struct iio_dev *indio_dev = private; + struct ad4062_state *st = iio_priv(indio_dev); + + if (iio_buffer_enabled(indio_dev) && iio_trigger_using_own(indio_dev)) + iio_trigger_poll(st->trigger); + else + complete(&st->completion); + + return IRQ_HANDLED; +} + +static void ad4062_ibi_handler(struct i3c_device *i3cdev, + const struct i3c_ibi_payload *payload) +{ + struct ad4062_state *st = i3cdev_get_drvdata(i3cdev); + + if (st->wait_event) { + iio_push_event(st->indio_dev, + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER), + iio_get_time_ns(st->indio_dev)); + return; + } + if (iio_buffer_enabled(st->indio_dev)) + iio_trigger_poll_nested(st->trigger); + else + complete(&st->completion); +} + +static void ad4062_trigger_work(struct work_struct *work) +{ + struct ad4062_state *st = + container_of(work, struct ad4062_state, trig_conv); + int ret; + + /* + * Read current conversion, if at reg CONV_READ, stop bit triggers + * next sample and does not need writing the address. + */ + struct i3c_xfer xfer_sample = { + .data.in = &st->buf.be32, + .len = st->conv_sizeof, + .rnw = true, + }; + struct i3c_xfer xfer_trigger = { + .data.out = &st->conv_addr, + .len = sizeof(st->conv_addr), + .rnw = false, + }; + + ret = i3c_device_do_xfers(st->i3cdev, &xfer_sample, 1, I3C_SDR); + if (ret) + return; + + iio_push_to_buffers_with_ts(st->indio_dev, &st->buf.be32, st->conv_sizeof, + iio_get_time_ns(st->indio_dev)); + if (st->gpo_irq[1]) + return; + + i3c_device_do_xfers(st->i3cdev, &xfer_trigger, 1, I3C_SDR); +} + +static irqreturn_t ad4062_poll_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ad4062_state *st = iio_priv(indio_dev); + + iio_trigger_notify_done(indio_dev->trig); + schedule_work(&st->trig_conv); + + return IRQ_HANDLED; +} + +static void ad4062_disable_ibi(void *data) +{ + struct i3c_device *i3cdev = data; + + i3c_device_disable_ibi(i3cdev); +} + +static void ad4062_free_ibi(void *data) +{ + struct i3c_device *i3cdev = data; + + i3c_device_free_ibi(i3cdev); +} + +static int ad4062_request_ibi(struct i3c_device *i3cdev) +{ + const struct i3c_ibi_setup ibireq = { + .max_payload_len = 1, + .num_slots = 1, + .handler = ad4062_ibi_handler, + }; + int ret; + + ret = i3c_device_request_ibi(i3cdev, &ibireq); + if (ret) + return ret; + + ret = devm_add_action_or_reset(&i3cdev->dev, ad4062_free_ibi, i3cdev); + if (ret) + return ret; + + ret = i3c_device_enable_ibi(i3cdev); + if (ret) + return ret; + + return devm_add_action_or_reset(&i3cdev->dev, ad4062_disable_ibi, i3cdev); +} + +static int ad4062_request_irq(struct iio_dev *indio_dev) +{ + struct ad4062_state *st = iio_priv(indio_dev); + struct device *dev = &st->i3cdev->dev; + int ret; + + ret = fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp0"); + if (ret == -EPROBE_DEFER) + return ret; + + if (ret < 0) { + st->gpo_irq[0] = false; + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN, + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN); + if (ret) + return ret; + } else { + st->gpo_irq[0] = true; + ret = devm_request_threaded_irq(dev, ret, NULL, + ad4062_irq_handler_thresh, + IRQF_ONESHOT, indio_dev->name, + indio_dev); + if (ret) + return ret; + } + + ret = fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); + if (ret == -EPROBE_DEFER) + return ret; + + if (ret < 0) { + st->gpo_irq[1] = false; + return regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER, + AD4062_REG_ADC_IBI_EN_CONV_TRIGGER); + } + st->gpo_irq[1] = true; + + return devm_request_threaded_irq(dev, ret, + ad4062_irq_handler_drdy, + NULL, IRQF_ONESHOT, indio_dev->name, + indio_dev); +} + +static const struct iio_trigger_ops ad4062_trigger_ops = { + .validate_device = &iio_trigger_validate_own_device, +}; + +static int ad4062_request_trigger(struct iio_dev *indio_dev) +{ + struct ad4062_state *st = iio_priv(indio_dev); + struct device *dev = &st->i3cdev->dev; + int ret; + + st->trigger = devm_iio_trigger_alloc(dev, "%s-dev%d", + indio_dev->name, + iio_device_id(indio_dev)); + if (!st->trigger) + return -ENOMEM; + + st->trigger->ops = &ad4062_trigger_ops; + iio_trigger_set_drvdata(st->trigger, indio_dev); + + ret = devm_iio_trigger_register(dev, st->trigger); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trigger); + + return 0; +} + +static const int ad4062_oversampling_avail[] = { + 1, 2, 4, 8, 16, 32, 64, 128, /* 0 - 7 */ + 256, 512, 1024, 2048, 4096, /* 8 - 12 */ +}; + +static int ad4062_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, const int **vals, + int *type, int *len, long mask) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + *vals = ad4062_oversampling_avail; + *len = ARRAY_SIZE(ad4062_oversampling_avail); + *len -= st->chip->avg_max == 256 ? 4 : 0; + *type = IIO_VAL_INT; + + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = ad4062_populate_sampling_frequency(st); + if (ret) + return ret; + *vals = st->samp_freqs; + *len = st->oversamp_ratio ? ARRAY_SIZE(ad4062_conversion_freqs) : 1; + *type = IIO_VAL_INT; + + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int ad4062_get_chan_scale(struct iio_dev *indio_dev, int *val, int *val2) +{ + struct ad4062_state *st = iio_priv(indio_dev); + const struct iio_scan_type *scan_type; + + /* + * In burst averaging mode the averaging filter accumulates resulting + * in a sample with increased precision. + */ + scan_type = iio_get_current_scan_type(indio_dev, st->chip->channels); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); + + *val = (st->vref_uV * 2) / (MICRO / MILLI); /* signed */ + *val2 = scan_type->realbits - 1; + + return IIO_VAL_FRACTIONAL_LOG2; +} + +static int ad4062_get_chan_calibscale(struct ad4062_state *st, int *val, int *val2) +{ + int ret; + + ret = regmap_bulk_read(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + /* From datasheet: code out = code in × mon_val/0x8000 */ + *val = be16_to_cpu(st->buf.be16) * 2; + *val2 = 16; + + return IIO_VAL_FRACTIONAL_LOG2; +} + +static int ad4062_set_chan_calibscale(struct ad4062_state *st, int gain_int, + int gain_frac) +{ + /* Divide numerator and denumerator by known great common divider */ + const u32 mon_val = AD4062_MON_VAL_MIDDLE_POINT / 64; + const u32 micro = MICRO / 64; + const u32 gain_fp = gain_int * MICRO + gain_frac; + const u32 reg_val = DIV_ROUND_CLOSEST(gain_fp * mon_val, micro); + int ret; + + /* Checks if the gain is in range and the value fits the field */ + if (gain_int < 0 || gain_int > 1 || reg_val > BIT(16) - 1) + return -EINVAL; + + st->buf.be16 = cpu_to_be16(reg_val); + ret = regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, + &st->buf.be16, sizeof(st->buf.be16)); + if (ret) + return ret; + + /* Enable scale if gain is not equal to one */ + return regmap_update_bits(st->regmap, AD4062_REG_ADC_CONFIG, + AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, + FIELD_PREP(AD4062_REG_ADC_CONFIG_SCALE_EN_MSK, + !(gain_int == 1 && gain_frac == 0))); +} + +static int ad4062_read_chan_raw(struct ad4062_state *st, int *val) +{ + struct i3c_device *i3cdev = st->i3cdev; + struct i3c_xfer xfer_trigger = { + .data.out = &st->conv_addr, + .len = sizeof(st->conv_addr), + .rnw = false, + }; + struct i3c_xfer xfer_sample = { + .data.in = &st->buf.be32, + .len = sizeof(st->buf.be32), + .rnw = true, + }; + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret = ad4062_set_operation_mode(st, st->mode); + if (ret) + return ret; + + reinit_completion(&st->completion); + /* Change address pointer to trigger conversion */ + st->conv_addr = AD4062_REG_CONV_TRIGGER_32BITS; + ret = i3c_device_do_xfers(i3cdev, &xfer_trigger, 1, I3C_SDR); + if (ret) + return ret; + /* + * Single sample read should be used only for oversampling and + * sampling frequency pairs that take less than 1 sec. + */ + ret = wait_for_completion_timeout(&st->completion, + msecs_to_jiffies(1000)); + if (!ret) + return -ETIMEDOUT; + + ret = i3c_device_do_xfers(i3cdev, &xfer_sample, 1, I3C_SDR); + if (ret) + return ret; + *val = be32_to_cpu(st->buf.be32); + return 0; +} + +static int ad4062_read_raw_dispatch(struct ad4062_state *st, + int *val, int *val2, long info) +{ + if (st->wait_event) + return -EBUSY; + + switch (info) { + case IIO_CHAN_INFO_RAW: + return ad4062_read_chan_raw(st, val); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_get_chan_calibscale(st, val, val2); + + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4062_get_oversampling_ratio(st, val); + + default: + return -EINVAL; + } +} + +static int ad4062_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_SCALE: + return ad4062_get_chan_scale(indio_dev, val, val2); + + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_get_sampling_frequency(st, val); + } + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad4062_read_raw_dispatch(st, val, val2, info); + iio_device_release_direct(indio_dev); + return ret ?: IIO_VAL_INT; +} + +static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int val2, + long info) +{ + if (st->wait_event) + return -EBUSY; + + switch (info) { + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + return ad4062_set_oversampling_ratio(st, val, val2); + + case IIO_CHAN_INFO_CALIBSCALE: + return ad4062_set_chan_calibscale(st, val, val2); + + default: + return -EINVAL; + } +}; + +static int ad4062_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long info) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + return ad4062_set_sampling_frequency(st, val, val2); + } + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad4062_write_raw_dispatch(st, val, val2, info); + iio_device_release_direct(indio_dev); + return ret; +} + +static int pm_ad4062_monitor_mode_enable(struct ad4062_state *st) +{ + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + return ad4062_set_operation_mode(st, AD4062_MONITOR_MODE); +} + +static int ad4062_monitor_mode_enable(struct ad4062_state *st) +{ + int ret; + + ret = pm_ad4062_monitor_mode_enable(st); + if (ret) + return ret; + + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; +} + +static int ad4062_monitor_mode_disable(struct ad4062_state *st) +{ + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return 0; +} + +static int ad4062_read_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + return st->wait_event; +} + +static int ad4062_write_event_config_dispatch(struct iio_dev *indio_dev, + bool state) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int ret; + + if (st->wait_event == state) + ret = 0; + else if (state) + ret = ad4062_monitor_mode_enable(st); + else + ret = ad4062_monitor_mode_disable(st); + if (ret) + return ret; + + st->wait_event = state; + return 0; +} + +static int ad4062_write_event_config(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + bool state) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad4062_write_event_config_dispatch(indio_dev, state); + iio_device_release_direct(indio_dev); + return ret; +} + +static int __ad4062_read_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + int ret; + u8 reg; + + if (dir == IIO_EV_DIR_RISING) + reg = AD4062_REG_MAX_LIMIT; + else + reg = AD4062_REG_MIN_LIMIT; + + ret = regmap_bulk_read(st->regmap, reg, &st->buf.be16, + sizeof(st->buf.be16)); + if (ret) + return ret; + + *val = sign_extend32(be16_to_cpu(st->buf.be16), AD4062_LIMIT_BITS - 1); + + return 0; +} + +static int __ad4062_read_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int *val) +{ + u8 reg; + + if (dir == IIO_EV_DIR_RISING) + reg = AD4062_REG_MAX_HYST; + else + reg = AD4062_REG_MIN_HYST; + return regmap_read(st->regmap, reg, val); +} + +static int ad4062_read_event_config_dispatch(struct iio_dev *indio_dev, + enum iio_event_direction dir, + enum iio_event_info info, int *val) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + if (st->wait_event) + return -EBUSY; + + switch (info) { + case IIO_EV_INFO_VALUE: + return __ad4062_read_event_info_value(st, dir, val); + case IIO_EV_INFO_HYSTERESIS: + return __ad4062_read_event_info_hysteresis(st, dir, val); + default: + return -EINVAL; + } +} + +static int ad4062_read_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int *val, + int *val2) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad4062_read_event_config_dispatch(indio_dev, dir, info, val); + iio_device_release_direct(indio_dev); + return ret ?: IIO_VAL_INT; +} + +static int __ad4062_write_event_info_value(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val != sign_extend32(val, AD4062_LIMIT_BITS - 1)) + return -EINVAL; + if (dir == IIO_EV_DIR_RISING) + reg = AD4062_REG_MAX_LIMIT; + else + reg = AD4062_REG_MIN_LIMIT; + st->buf.be16 = cpu_to_be16(val); + + return regmap_bulk_write(st->regmap, reg, &st->buf.be16, + sizeof(st->buf.be16)); +} + +static int __ad4062_write_event_info_hysteresis(struct ad4062_state *st, + enum iio_event_direction dir, int val) +{ + u8 reg; + + if (val > BIT(7) - 1) + return -EINVAL; + if (dir == IIO_EV_DIR_RISING) + reg = AD4062_REG_MAX_HYST; + else + reg = AD4062_REG_MIN_HYST; + + return regmap_write(st->regmap, reg, val); +} + +static int ad4062_write_event_value_dispatch(struct iio_dev *indio_dev, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + if (st->wait_event) + return -EBUSY; + + switch (type) { + case IIO_EV_TYPE_THRESH: + switch (info) { + case IIO_EV_INFO_VALUE: + return __ad4062_write_event_info_value(st, dir, val); + case IIO_EV_INFO_HYSTERESIS: + return __ad4062_write_event_info_hysteresis(st, dir, val); + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static int ad4062_write_event_value(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, + enum iio_event_type type, + enum iio_event_direction dir, + enum iio_event_info info, int val, + int val2) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad4062_write_event_value_dispatch(indio_dev, type, dir, info, val); + iio_device_release_direct(indio_dev); + return ret; +} + +/* + * The AD4062 in burst averaging mode increases realbits from 16-bits to + * 20-bits, increasing the storagebits from 16-bits to 32-bits. + */ +static inline size_t ad4062_sizeof_storagebits(struct ad4062_state *st) +{ + const struct iio_scan_type *scan_type = + iio_get_current_scan_type(st->indio_dev, st->chip->channels); + + return BITS_TO_BYTES(scan_type->storagebits); +} + +/* Read registers only with realbits (no sign extension bytes) */ +static inline size_t ad4062_get_conv_addr(struct ad4062_state *st, size_t _sizeof) +{ + if (st->gpo_irq[1]) + return _sizeof == sizeof(u32) ? AD4062_REG_CONV_READ_32BITS : + AD4062_REG_CONV_READ_16BITS; + return _sizeof == sizeof(u32) ? AD4062_REG_CONV_TRIGGER_32BITS : + AD4062_REG_CONV_TRIGGER_16BITS; +} + +static int pm_ad4062_triggered_buffer_postenable(struct ad4062_state *st) +{ + int ret; + + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + if (st->wait_event) + return -EBUSY; + + ret = ad4062_set_operation_mode(st, st->mode); + if (ret) + return ret; + + st->conv_sizeof = ad4062_sizeof_storagebits(st); + st->conv_addr = ad4062_get_conv_addr(st, st->conv_sizeof); + /* CONV_READ requires read to trigger first sample. */ + struct i3c_xfer xfer_sample[2] = { + { + .data.out = &st->conv_addr, + .len = sizeof(st->conv_addr), + .rnw = false, + }, + { + .data.in = &st->buf.be32, + .len = sizeof(st->buf.be32), + .rnw = true, + } + }; + + return i3c_device_do_xfers(st->i3cdev, xfer_sample, + st->gpo_irq[1] ? 2 : 1, I3C_SDR); +} + +static int ad4062_triggered_buffer_postenable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st = iio_priv(indio_dev); + int ret; + + ret = pm_ad4062_triggered_buffer_postenable(st); + if (ret) + return ret; + + pm_runtime_get_noresume(&st->i3cdev->dev); + return 0; +} + +static int ad4062_triggered_buffer_predisable(struct iio_dev *indio_dev) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + pm_runtime_put_autosuspend(&st->i3cdev->dev); + return 0; +} + +static const struct iio_buffer_setup_ops ad4062_triggered_buffer_setup_ops = { + .postenable = &ad4062_triggered_buffer_postenable, + .predisable = &ad4062_triggered_buffer_predisable, +}; + +static int ad4062_debugfs_reg_access(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + else + return regmap_write(st->regmap, reg, writeval); +} + +static int ad4062_get_current_scan_type(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct ad4062_state *st = iio_priv(indio_dev); + + return st->mode == AD4062_BURST_AVERAGING_MODE ? + AD4062_SCAN_TYPE_BURST_AVG : + AD4062_SCAN_TYPE_SAMPLE; +} + +static const struct iio_info ad4062_info = { + .read_raw = ad4062_read_raw, + .write_raw = ad4062_write_raw, + .read_avail = ad4062_read_avail, + .read_event_config = ad4062_read_event_config, + .write_event_config = ad4062_write_event_config, + .read_event_value = ad4062_read_event_value, + .write_event_value = ad4062_write_event_value, + .event_attrs = &ad4062_event_attribute_group, + .get_current_scan_type = ad4062_get_current_scan_type, + .debugfs_reg_access = ad4062_debugfs_reg_access, +}; + +static const struct regmap_config ad4062_regmap_config = { + .name = "ad4062", + .reg_bits = 8, + .val_bits = 8, + .max_register = AD4062_MAX_REG, + .rd_table = &ad4062_regmap_rd_table, + .wr_table = &ad4062_regmap_wr_table, + .can_sleep = true, +}; + +static int ad4062_regulators_get(struct ad4062_state *st, bool *ref_sel) +{ + struct device *dev = &st->i3cdev->dev; + int ret; + + ret = devm_regulator_get_enable(dev, "vio"); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable vio voltage\n"); + + st->vref_uV = devm_regulator_get_enable_read_voltage(dev, "ref"); + *ref_sel = st->vref_uV == -ENODEV; + if (st->vref_uV < 0 && !*ref_sel) + return dev_err_probe(dev, st->vref_uV, + "Failed to enable and read ref voltage\n"); + + if (*ref_sel) { + st->vref_uV = devm_regulator_get_enable_read_voltage(dev, "vdd"); + if (st->vref_uV < 0) + return dev_err_probe(dev, st->vref_uV, + "Failed to enable and read vdd voltage\n"); + } else { + ret = devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, + "Failed to enable vdd regulator\n"); + } + + return 0; +} + +static int ad4062_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) +{ + return GPIO_LINE_DIRECTION_OUT; +} + +static int ad4062_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +{ + struct ad4062_state *st = gpiochip_get_data(gc); + unsigned int reg_val = value ? AD4062_GP_STATIC_HIGH : AD4062_GP_STATIC_LOW; + + if (offset) + return regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, reg_val)); + else + return regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_0, + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, reg_val)); +} + +static int ad4062_gpio_get(struct gpio_chip *gc, unsigned int offset) +{ + struct ad4062_state *st = gpiochip_get_data(gc); + unsigned int reg_val; + int ret; + + ret = regmap_read(st->regmap, AD4062_REG_GP_CONF, ®_val); + if (ret) + return ret; + + if (offset) + reg_val = FIELD_GET(AD4062_REG_GP_CONF_MODE_MSK_1, reg_val); + else + reg_val = FIELD_GET(AD4062_REG_GP_CONF_MODE_MSK_0, reg_val); + + return reg_val == AD4062_GP_STATIC_HIGH; +} + +static void ad4062_gpio_disable(void *data) +{ + struct ad4062_state *st = data; + u8 val = FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_DISABLED) | + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_DISABLED); + + regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + AD4062_REG_GP_CONF_MODE_MSK_1 | AD4062_REG_GP_CONF_MODE_MSK_0, + val); +} + +static int ad4062_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct ad4062_state *st = gpiochip_get_data(gc); + + bitmap_zero(valid_mask, ngpios); + + for (unsigned int i = 0; i < ARRAY_SIZE(st->gpo_irq); i++) + __assign_bit(i, valid_mask, !st->gpo_irq[i]); + + return 0; +} + +static int ad4062_gpio_init(struct ad4062_state *st) +{ + struct device *dev = &st->i3cdev->dev; + struct gpio_chip *gc; + u8 val, mask; + int ret; + + if (!device_property_read_bool(dev, "gpio-controller")) + return 0; + + gc = devm_kzalloc(dev, sizeof(*gc), GFP_KERNEL); + if (!gc) + return -ENOMEM; + + val = 0; + mask = 0; + if (!st->gpo_irq[0]) { + mask |= AD4062_REG_GP_CONF_MODE_MSK_0; + val |= FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, AD4062_GP_STATIC_LOW); + } + if (!st->gpo_irq[1]) { + mask |= AD4062_REG_GP_CONF_MODE_MSK_1; + val |= FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, AD4062_GP_STATIC_LOW); + } + + ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, + mask, val); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, ad4062_gpio_disable, st); + if (ret) + return ret; + + gc->parent = dev; + gc->label = st->chip->name; + gc->owner = THIS_MODULE; + gc->base = -1; + gc->ngpio = 2; + gc->init_valid_mask = ad4062_gpio_init_valid_mask; + gc->get_direction = ad4062_gpio_get_direction; + gc->set = ad4062_gpio_set; + gc->get = ad4062_gpio_get; + gc->can_sleep = true; + + ret = devm_gpiochip_add_data(dev, gc, st); + if (ret) + return dev_err_probe(dev, ret, "Unable to register GPIO chip\n"); + + return 0; +} + +static const struct i3c_device_id ad4062_id_table[] = { + I3C_DEVICE(AD4062_I3C_VENDOR, AD4060_PROD_ID, &ad4060_chip_info), + I3C_DEVICE(AD4062_I3C_VENDOR, AD4062_PROD_ID, &ad4062_chip_info), + { } +}; +MODULE_DEVICE_TABLE(i3c, ad4062_id_table); + +static int ad4062_probe(struct i3c_device *i3cdev) +{ + const struct i3c_device_id *id = i3c_device_match_id(i3cdev, ad4062_id_table); + const struct ad4062_chip_info *chip = id->data; + struct device *dev = &i3cdev->dev; + struct iio_dev *indio_dev; + struct ad4062_state *st; + bool ref_sel; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->i3cdev = i3cdev; + i3cdev_set_drvdata(i3cdev, st); + init_completion(&st->completion); + + ret = ad4062_regulators_get(st, &ref_sel); + if (ret) + return ret; + + st->regmap = devm_regmap_init_i3c(i3cdev, &ad4062_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to initialize regmap\n"); + + st->mode = AD4062_SAMPLE_MODE; + st->wait_event = false; + st->chip = chip; + st->sampling_frequency = 0; + st->events_frequency = 0; + st->oversamp_ratio = 0; + st->indio_dev = indio_dev; + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->num_channels = 1; + indio_dev->info = &ad4062_info; + indio_dev->name = chip->name; + indio_dev->channels = chip->channels; + + ret = ad4062_soft_reset(st); + if (ret) + return dev_err_probe(dev, ret, "AD4062 failed to soft reset\n"); + + ret = ad4062_check_ids(st); + if (ret) + return ret; + + ret = ad4062_setup(indio_dev, indio_dev->channels, &ref_sel); + if (ret) + return ret; + + ret = ad4062_request_irq(indio_dev); + if (ret) + return ret; + + ret = ad4062_request_trigger(indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(&i3cdev->dev, indio_dev, + iio_pollfunc_store_time, + ad4062_poll_handler, + &ad4062_triggered_buffer_setup_ops); + if (ret) + return ret; + + pm_runtime_set_active(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n"); + + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + + ret = ad4062_request_ibi(i3cdev); + if (ret) + return dev_err_probe(dev, ret, "Failed to request i3c ibi\n"); + + ret = ad4062_gpio_init(st); + if (ret) + return ret; + + ret = devm_work_autocancel(dev, &st->trig_conv, ad4062_trigger_work); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static int ad4062_runtime_suspend(struct device *dev) +{ + struct ad4062_state *st = dev_get_drvdata(dev); + + return regmap_write(st->regmap, AD4062_REG_DEVICE_CONFIG, + FIELD_PREP(AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK, + AD4062_REG_DEVICE_CONFIG_LOW_POWER_MODE)); +} + +static int ad4062_runtime_resume(struct device *dev) +{ + struct ad4062_state *st = dev_get_drvdata(dev); + int ret; + + ret = regmap_clear_bits(st->regmap, AD4062_REG_DEVICE_CONFIG, + AD4062_REG_DEVICE_CONFIG_POWER_MODE_MSK); + if (ret) + return ret; + + /* Wait device functional blocks to power up */ + fsleep(3 * USEC_PER_MSEC); + return 0; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(ad4062_pm_ops, + ad4062_runtime_suspend, ad4062_runtime_resume, NULL); + +static struct i3c_driver ad4062_driver = { + .driver = { + .name = "ad4062", + .pm = pm_ptr(&ad4062_pm_ops), + }, + .probe = ad4062_probe, + .id_table = ad4062_id_table, +}; +module_i3c_driver(ad4062_driver); + +MODULE_AUTHOR("Jorge Marques "); +MODULE_DESCRIPTION("Analog Devices AD4062"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/ad4134.c b/drivers/iio/adc/ad4134.c new file mode 100644 index 000000000000..e42ee328fcbf --- /dev/null +++ b/drivers/iio/adc/ad4134.c @@ -0,0 +1,500 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2026 Analog Devices, Inc. + * Author: Marcelo Schmitt + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AD4134_RESET_TIME_US (10 * USEC_PER_SEC) + +#define AD4134_REG_READ_MASK BIT(7) +#define AD4134_SPI_MAX_XFER_LEN 3 + +#define AD4134_EXT_CLOCK_MHZ (48 * HZ_PER_MHZ) + +#define AD4134_NUM_CHANNELS 4 +#define AD4134_CHAN_PRECISION_BITS 24 + +#define AD4134_IFACE_CONFIG_A_REG 0x00 +#define AD4134_IFACE_CONFIG_B_REG 0x01 +#define AD4134_IFACE_CONFIG_B_SINGLE_INSTR BIT(7) + +#define AD4134_DEVICE_CONFIG_REG 0x02 +#define AD4134_DEVICE_CONFIG_POWER_MODE_MASK BIT(0) +#define AD4134_POWER_MODE_HIGH_PERF 0x1 + +#define AD4134_SILICON_REV_REG 0x07 +#define AD4134_SCRATCH_PAD_REG 0x0A +#define AD4134_STREAM_MODE_REG 0x0E +#define AD4134_SDO_PIN_SRC_SEL_REG 0x10 +#define AD4134_SDO_PIN_SRC_SEL_SDO_SEL_MASK BIT(2) + +#define AD4134_DATA_PACKET_CONFIG_REG 0x11 +#define AD4134_DATA_PACKET_CONFIG_FRAME_MASK GENMASK(5, 4) +#define AD4134_DATA_PACKET_24BIT_FRAME 0x2 + +#define AD4134_DIG_IF_CFG_REG 0x12 +#define AD4134_DIF_IF_CFG_FORMAT_MASK GENMASK(1, 0) +#define AD4134_DATA_FORMAT_SINGLE_CH_MODE 0x0 + +#define AD4134_PW_DOWN_CTRL_REG 0x13 +#define AD4134_DEVICE_STATUS_REG 0x15 +#define AD4134_ODR_VAL_INT_LSB_REG 0x16 +#define AD4134_CH3_OFFSET_MSB_REG 0x3E +#define AD4134_AIN_OR_ERROR_REG 0x48 + +/* + * AD4134 register map ends at address 0x48 and there is no register for + * retrieving ADC sample data. Though, to make use of Linux regmap API both + * for register access and sample read, we define one virtual register for each + * ADC channel. AD4134_CH_VREG(x) maps a channel number to it's virtual register + * address while AD4134_VREG_CH(x) tells which channel given the address. + */ +#define AD4134_CH_VREG(x) ((x) + 0x50) +#define AD4134_VREG_CH(x) ((x) - 0x50) + +#define AD4134_SPI_CRC_POLYNOM 0x07 +#define AD4134_SPI_CRC_INIT_VALUE 0xA5 +static unsigned char ad4134_spi_crc_table[CRC8_TABLE_SIZE]; + +#define AD4134_CHANNEL(_index) { \ + .type = IIO_VOLTAGE, \ + .indexed = 1, \ + .channel = (_index), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec ad4134_chan_set[] = { + AD4134_CHANNEL(0), + AD4134_CHANNEL(1), + AD4134_CHANNEL(2), + AD4134_CHANNEL(3), +}; + +struct ad4134_state { + struct spi_device *spi; + struct regmap *regmap; + unsigned long sys_clk_hz; + struct gpio_desc *odr_gpio; + int refin_mv; + /* + * DMA (thus cache coherency maintenance) requires the transfer buffers + * to live in their own cache lines. + */ + u8 rx_buf[AD4134_SPI_MAX_XFER_LEN] __aligned(IIO_DMA_MINALIGN); + u8 tx_buf[AD4134_SPI_MAX_XFER_LEN]; +}; + +static const struct regmap_range ad4134_regmap_rd_range[] = { + regmap_reg_range(AD4134_IFACE_CONFIG_A_REG, AD4134_SILICON_REV_REG), + regmap_reg_range(AD4134_SCRATCH_PAD_REG, AD4134_PW_DOWN_CTRL_REG), + regmap_reg_range(AD4134_DEVICE_STATUS_REG, AD4134_AIN_OR_ERROR_REG), + regmap_reg_range(AD4134_CH_VREG(0), AD4134_CH_VREG(AD4134_NUM_CHANNELS)), +}; + +static const struct regmap_range ad4134_regmap_wr_range[] = { + regmap_reg_range(AD4134_IFACE_CONFIG_A_REG, AD4134_DEVICE_CONFIG_REG), + regmap_reg_range(AD4134_SCRATCH_PAD_REG, AD4134_SCRATCH_PAD_REG), + regmap_reg_range(AD4134_STREAM_MODE_REG, AD4134_PW_DOWN_CTRL_REG), + regmap_reg_range(AD4134_ODR_VAL_INT_LSB_REG, AD4134_CH3_OFFSET_MSB_REG), +}; + +static const struct regmap_access_table ad4134_regmap_rd_table = { + .yes_ranges = ad4134_regmap_rd_range, + .n_yes_ranges = ARRAY_SIZE(ad4134_regmap_rd_range), +}; + +static const struct regmap_access_table ad4134_regmap_wr_table = { + .yes_ranges = ad4134_regmap_wr_range, + .n_yes_ranges = ARRAY_SIZE(ad4134_regmap_wr_range), +}; + +static int ad4134_calc_spi_crc(u8 inst, u8 data) +{ + u8 buf[] = { inst, data }; + + return crc8(ad4134_spi_crc_table, buf, ARRAY_SIZE(buf), + AD4134_SPI_CRC_INIT_VALUE); +} + +static void ad4134_prepare_spi_tx_buf(u8 inst, u8 data, u8 *buf) +{ + buf[0] = inst; + buf[1] = data; + buf[2] = ad4134_calc_spi_crc(inst, data); +} + +static int ad4134_reg_write(void *context, unsigned int reg, unsigned int val) +{ + struct ad4134_state *st = context; + struct spi_transfer xfer = { + .tx_buf = st->tx_buf, + .rx_buf = st->rx_buf, + .len = AD4134_SPI_MAX_XFER_LEN, + }; + int ret; + + ad4134_prepare_spi_tx_buf(reg, val, st->tx_buf); + + ret = spi_sync_transfer(st->spi, &xfer, 1); + if (ret) + return ret; + + if (st->rx_buf[2] != st->tx_buf[2]) + dev_dbg(&st->spi->dev, "reg write CRC check failed\n"); + + return 0; +} + +static int ad4134_data_read(struct ad4134_state *st, unsigned int reg, + unsigned int *val) +{ + unsigned int i; + int ret; + + /* + * To be able to read data from all 4 channels through a single line, we + * set DOUTx output format to 0 in the digital interface config register + * (0x12). With that, data from all four channels is serialized and + * output on DOUT0. During the probe, we also set SDO_PIN_SRC_SEL in + * DEVICE_CONFIG_1 register to duplicate DOUT0 on the SDO pin. Combined, + * those configurations enable ADC data read through a conventional SPI + * interface. Now we read data from all channels but keep only the bits + * from the requested one. + */ + for (i = 0; i < ARRAY_SIZE(ad4134_chan_set); i++) { + ret = spi_write_then_read(st->spi, NULL, 0, st->rx_buf, + BITS_TO_BYTES(AD4134_CHAN_PRECISION_BITS)); + if (ret) + return ret; + + /* + * AD4134 has a built-in feature that flags when data transfers + * don't run enough clock cycles to read the entire data frame. + * Clock out data from all channels to avoid that. + */ + if (i == AD4134_VREG_CH(reg)) + *val = get_unaligned_be24(st->rx_buf); + } + + return 0; +} + +static int ad4134_register_read(struct ad4134_state *st, unsigned int reg, + unsigned int *val) +{ + struct spi_transfer xfer = { + .tx_buf = st->tx_buf, + .rx_buf = st->rx_buf, + .len = AD4134_SPI_MAX_XFER_LEN, + }; + unsigned int inst; + int ret; + + inst = AD4134_REG_READ_MASK | reg; + ad4134_prepare_spi_tx_buf(inst, 0, st->tx_buf); + + ret = spi_sync_transfer(st->spi, &xfer, 1); + if (ret) + return ret; + + *val = st->rx_buf[1]; + + /* Check CRC */ + if (st->rx_buf[2] != st->tx_buf[2]) + dev_dbg(&st->spi->dev, "reg read CRC check failed\n"); + + return 0; +} + +static int ad4134_reg_read(void *context, unsigned int reg, unsigned int *val) +{ + struct ad4134_state *st = context; + + if (reg >= AD4134_CH_VREG(0)) + return ad4134_data_read(st, reg, val); + + return ad4134_register_read(st, reg, val); +} + +static const struct regmap_config ad4134_regmap_config = { + .reg_read = ad4134_reg_read, + .reg_write = ad4134_reg_write, + .rd_table = &ad4134_regmap_rd_table, + .wr_table = &ad4134_regmap_wr_table, + .max_register = AD4134_CH_VREG(ARRAY_SIZE(ad4134_chan_set)), +}; + +static int ad4134_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long info) +{ + struct ad4134_state *st = iio_priv(indio_dev); + int ret; + + switch (info) { + case IIO_CHAN_INFO_RAW: + gpiod_set_value_cansleep(st->odr_gpio, 1); + /* + * For slave mode gated DCLK (data sheet page 11), the minimum + * ODR high time is 3 * tDIGCLK. The internal digital clock + * period is tDIGCLK = 1/fDIGCLK = 2/fSYSCLK. + * The System clock frequency (fSYSCLK) is typically 48 MHz. + * Thus, ODR high time = 3 * (2 / (48 * HZ_PER_MHZ)) + * ODR high time = 0.000000125 s = 125 ns + * 1 micro second should be more than enough. Not worth it + * tweaking for shorter dealy since this is not a fast data path. + */ + fsleep(1); + gpiod_set_value_cansleep(st->odr_gpio, 0); + ret = regmap_read(st->regmap, AD4134_CH_VREG(chan->channel), val); + if (ret) + return ret; + + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = st->refin_mv; + *val2 = AD4134_CHAN_PRECISION_BITS - 1; + + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int ad4134_debugfs_reg_access(struct iio_dev *indio_dev, + unsigned int reg, unsigned int writeval, + unsigned int *readval) +{ + struct ad4134_state *st = iio_priv(indio_dev); + + if (readval) + return regmap_read(st->regmap, reg, readval); + + return regmap_write(st->regmap, reg, writeval); +} + +static int ad4134_min_io_mode_setup(struct ad4134_state *st) +{ + struct device *dev = &st->spi->dev; + int ret; + + st->odr_gpio = devm_gpiod_get(dev, "odr", GPIOD_OUT_LOW); + if (IS_ERR(st->odr_gpio)) + return dev_err_probe(dev, PTR_ERR(st->odr_gpio), + "failed to get ODR GPIO\n"); + + ret = regmap_update_bits(st->regmap, AD4134_DIG_IF_CFG_REG, + AD4134_DIF_IF_CFG_FORMAT_MASK, + FIELD_PREP(AD4134_DIF_IF_CFG_FORMAT_MASK, + AD4134_DATA_FORMAT_SINGLE_CH_MODE)); + if (ret) + return dev_err_probe(dev, ret, + "failed to set single channel mode\n"); + + ret = regmap_set_bits(st->regmap, AD4134_SDO_PIN_SRC_SEL_REG, + AD4134_SDO_PIN_SRC_SEL_SDO_SEL_MASK); + if (ret) + return dev_err_probe(dev, ret, + "failed to set SDO source selection\n"); + + return regmap_set_bits(st->regmap, AD4134_IFACE_CONFIG_B_REG, + AD4134_IFACE_CONFIG_B_SINGLE_INSTR); +} + +static const struct iio_info ad4134_info = { + .read_raw = ad4134_read_raw, + .debugfs_reg_access = ad4134_debugfs_reg_access, +}; + +static const char * const ad4143_required_regulators[] = { + "avdd5", "dvdd5", "iovdd", +}; + +static const char * const ad4143_optional_regulators[] = { + "avdd1v8", "dvdd1v8", "clkvdd", +}; + +static int ad4134_regulator_setup(struct ad4134_state *st) +{ + struct device *dev = &st->spi->dev; + int ret; + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4143_required_regulators), + ad4143_required_regulators); + if (ret) + return dev_err_probe(dev, ret, "failed to enable power supplies\n"); + + /* Required regulator that we need to read the voltage */ + ret = devm_regulator_get_enable_read_voltage(dev, "refin"); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get REFIN voltage.\n"); + + st->refin_mv = ret / (MICRO / MILLI); + + ret = devm_regulator_get_enable_optional(dev, "ldoin"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to enable ldoin supply\n"); + + /* If ldoin was provided, then use the use the internal LDO regulators */ + if (ret == 0) + return 0; + + /* + * If ldoin is not provided, then avdd1v8, dvdd1v8, and clkvdd are + * required. + */ + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(ad4143_optional_regulators), + ad4143_optional_regulators); + if (ret) + return dev_err_probe(dev, ret, "failed to enable 1V8 power supplies\n"); + + return 0; +} + +static int ad4134_clock_select(struct ad4134_state *st) +{ + struct device *dev = &st->spi->dev; + struct clk *xtal_clk, *clkin_clk; + + /* + * AD4134 requires one external clock source and only one external clock + * source can be provided at a time. Try to get a crystal provided clock. + * If that fails, try to get a CMOS clock. + */ + xtal_clk = devm_clk_get_optional_enabled(dev, "xtal"); + if (!xtal_clk) + xtal_clk = devm_clk_get_optional_enabled(dev, "xtal"); + if (IS_ERR(xtal_clk)) + return dev_err_probe(dev, PTR_ERR(xtal_clk), + "failed to get xtal\n"); + + clkin_clk = devm_clk_get_optional_enabled(dev, "clkin"); + if (!clkin_clk) + clkin_clk = devm_clk_get_optional_enabled(dev, "clkin"); + if (IS_ERR(clkin_clk)) + return dev_err_probe(dev, PTR_ERR(clkin_clk), + "failed to get clkin\n"); + + st->sys_clk_hz = clk_get_rate(xtal_clk) | clk_get_rate(clkin_clk); + if (st->sys_clk_hz != AD4134_EXT_CLOCK_MHZ) + dev_warn(dev, "invalid external clock frequency %lu\n", + st->sys_clk_hz); + + return 0; +} + +static int ad4134_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct reset_control *rst; + struct iio_dev *indio_dev; + struct ad4134_state *st; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi = spi; + + indio_dev->name = "ad4134"; + indio_dev->channels = ad4134_chan_set; + indio_dev->num_channels = ARRAY_SIZE(ad4134_chan_set); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ad4134_info; + + ret = ad4134_regulator_setup(st); + if (ret) + return ret; + + ret = ad4134_clock_select(st); + if (ret) + return ret; + + rst = devm_reset_control_get_optional_exclusive_deasserted(dev, NULL); + if (IS_ERR(rst)) + return dev_err_probe(dev, PTR_ERR(rst), + "failed to get and deassert reset\n"); + + crc8_populate_msb(ad4134_spi_crc_table, AD4134_SPI_CRC_POLYNOM); + + st->regmap = devm_regmap_init(dev, NULL, st, &ad4134_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "failed to initialize regmap"); + + ret = ad4134_min_io_mode_setup(st); + if (ret) + return dev_err_probe(dev, ret, + "failed to setup minimum I/O mode\n"); + + /* Bump precision to 24-bit */ + ret = regmap_update_bits(st->regmap, AD4134_DATA_PACKET_CONFIG_REG, + AD4134_DATA_PACKET_CONFIG_FRAME_MASK, + FIELD_PREP(AD4134_DATA_PACKET_CONFIG_FRAME_MASK, + AD4134_DATA_PACKET_24BIT_FRAME)); + if (ret) + return ret; + + /* Set high performance power mode */ + ret = regmap_update_bits(st->regmap, AD4134_DEVICE_CONFIG_REG, + AD4134_DEVICE_CONFIG_POWER_MODE_MASK, + FIELD_PREP(AD4134_DEVICE_CONFIG_POWER_MODE_MASK, + AD4134_POWER_MODE_HIGH_PERF)); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct spi_device_id ad4134_id[] = { + { "ad4134" }, + { } +}; +MODULE_DEVICE_TABLE(spi, ad4134_id); + +static const struct of_device_id ad4134_of_match[] = { + { .compatible = "adi,ad4134" }, + { } +}; +MODULE_DEVICE_TABLE(of, ad4134_of_match); + +static struct spi_driver ad4134_driver = { + .driver = { + .name = "ad4134", + .of_match_table = ad4134_of_match, + }, + .probe = ad4134_probe, + .id_table = ad4134_id, +}; +module_spi_driver(ad4134_driver); + +MODULE_AUTHOR("Marcelo Schmitt "); +MODULE_DESCRIPTION("Analog Devices AD4134 SPI driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_AD4134"); diff --git a/drivers/iio/adc/ad4170-4.c b/drivers/iio/adc/ad4170-4.c index efaed92191f1..82205bfae531 100644 --- a/drivers/iio/adc/ad4170-4.c +++ b/drivers/iio/adc/ad4170-4.c @@ -2973,7 +2973,7 @@ static int ad4170_probe(struct spi_device *spi) if (spi->irq) { ret = devm_request_irq(dev, spi->irq, &ad4170_irq_handler, - IRQF_ONESHOT, indio_dev->name, indio_dev); + IRQF_NO_THREAD, indio_dev->name, indio_dev); if (ret) return ret; diff --git a/drivers/iio/adc/ad7476.c b/drivers/iio/adc/ad7476.c index 1bec6657394c..21d3f6aae972 100644 --- a/drivers/iio/adc/ad7476.c +++ b/drivers/iio/adc/ad7476.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index f28e4ca37707..7e17ccbcedd0 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -345,7 +345,7 @@ static int ad7606_spi_update_scan_mode(struct iio_dev *indio_dev, * has no way of demuxing the data to filter out unwanted * channels. */ - if (bitmap_weight(scan_mask, num_adc_ch) != num_adc_ch) + if (!bitmap_full(scan_mask, num_adc_ch)) return -EINVAL; } diff --git a/drivers/iio/adc/ad7766.c b/drivers/iio/adc/ad7766.c index 4d570383ef02..9e4a66477d2d 100644 --- a/drivers/iio/adc/ad7766.c +++ b/drivers/iio/adc/ad7766.c @@ -184,12 +184,6 @@ static const struct iio_info ad7766_info = { .read_raw = &ad7766_read_raw, }; -static irqreturn_t ad7766_irq(int irq, void *private) -{ - iio_trigger_poll(private); - return IRQ_HANDLED; -} - static int ad7766_set_trigger_state(struct iio_trigger *trig, bool enable) { struct ad7766 *ad7766 = iio_trigger_get_drvdata(trig); @@ -260,8 +254,8 @@ static int ad7766_probe(struct spi_device *spi) * Some platforms might not allow the option to power it down so * don't enable the interrupt to avoid extra load on the system */ - ret = devm_request_irq(&spi->dev, spi->irq, ad7766_irq, - IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN, + ret = devm_request_irq(&spi->dev, spi->irq, iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_FALLING | IRQF_NO_AUTOEN | IRQF_NO_THREAD, dev_name(&spi->dev), ad7766->trig); if (ret < 0) diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index d96802b7847a..e16dede687d3 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -6,6 +6,7 @@ */ #include #include +#include #include #include #include @@ -14,8 +15,12 @@ #include #include #include +#include +#include #include #include +#include +#include #include #include #include @@ -107,10 +112,15 @@ #define AD7768_VCM_OFF 0x07 +#define ADAQ776X_GAIN_MAX_NANO (128 * NANO) +#define ADAQ776X_MAX_GAIN_MODES 8 + #define AD7768_TRIGGER_SOURCE_SYNC_IDX 0 #define AD7768_MAX_CHANNELS 1 +#define ADAQ7768_PGA_PINS 3 + enum ad7768_conv_mode { AD7768_CONTINUOUS, AD7768_ONE_SHOT, @@ -153,6 +163,51 @@ enum ad7768_scan_type { AD7768_SCAN_TYPE_HIGH_SPEED, }; +enum { + AD7768_PGA_GAIN_0, + AD7768_PGA_GAIN_1, + AD7768_PGA_GAIN_2, + AD7768_PGA_GAIN_3, + AD7768_PGA_GAIN_4, + AD7768_PGA_GAIN_5, + AD7768_PGA_GAIN_6, + AD7768_PGA_GAIN_7, +}; + +enum { + AD7768_AAF_IN1, + AD7768_AAF_IN2, + AD7768_AAF_IN3, +}; + +/* PGA and AAF gains in V/V */ +static const int adaq7768_gains[] = { + [AD7768_PGA_GAIN_0] = 325, /* 0.325 */ + [AD7768_PGA_GAIN_1] = 650, /* 0.650 */ + [AD7768_PGA_GAIN_2] = 1300, /* 1.300 */ + [AD7768_PGA_GAIN_3] = 2600, /* 2.600 */ + [AD7768_PGA_GAIN_4] = 5200, /* 5.200 */ + [AD7768_PGA_GAIN_5] = 10400, /* 10.400 */ + [AD7768_PGA_GAIN_6] = 20800, /* 20.800 */ +}; + +static const int adaq7769_gains[] = { + [AD7768_PGA_GAIN_0] = 1000, /* 1.000 */ + [AD7768_PGA_GAIN_1] = 2000, /* 2.000 */ + [AD7768_PGA_GAIN_2] = 4000, /* 4.000 */ + [AD7768_PGA_GAIN_3] = 8000, /* 8.000 */ + [AD7768_PGA_GAIN_4] = 16000, /* 16.000 */ + [AD7768_PGA_GAIN_5] = 32000, /* 32.000 */ + [AD7768_PGA_GAIN_6] = 64000, /* 64.000 */ + [AD7768_PGA_GAIN_7] = 128000, /* 128.000 */ +}; + +static const int ad7768_aaf_gains_bp[] = { + [AD7768_AAF_IN1] = 10000, /* 1.000 */ + [AD7768_AAF_IN2] = 3640, /* 0.364 */ + [AD7768_AAF_IN3] = 1430, /* 0.143 */ +}; + /* -3dB cutoff frequency multipliers (relative to ODR) for each filter type. */ static const int ad7768_filter_3db_odr_multiplier[] = { [AD7768_FILTER_SINC5] = 204, /* 0.204 */ @@ -213,6 +268,19 @@ static const struct iio_scan_type ad7768_scan_type[] = { }, }; +struct ad7768_chip_info { + const char *name; + const struct iio_chan_spec *channel_spec; + int num_channels; + const int *pga_gains; + int num_pga_modes; + int default_pga_mode; + int pgia_mode2pin_offset; + bool has_pga; + bool has_variable_aaf; + bool has_vcm_regulator; +}; + struct ad7768_state { struct spi_device *spi; struct regmap *regmap; @@ -228,13 +296,19 @@ struct ad7768_state { unsigned int samp_freq; unsigned int samp_freq_avail[ARRAY_SIZE(ad7768_mclk_div_rates)]; unsigned int samp_freq_avail_len; + unsigned int pga_gain_mode; + unsigned int aaf_gain; + int scale_tbl[ADAQ776X_MAX_GAIN_MODES][2]; struct completion completion; struct iio_trigger *trig; + struct gpio_descs *pga_gpios; struct gpio_desc *gpio_sync_in; struct gpio_desc *gpio_reset; const char *labels[AD7768_MAX_CHANNELS]; struct gpio_chip gpiochip; + const struct ad7768_chip_info *chip; bool en_spi_sync; + struct mutex pga_lock; /* protect device internal state (PGA) */ /* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines. @@ -457,6 +531,49 @@ static int ad7768_reg_access(struct iio_dev *indio_dev, return ret; } +static int ad7768_fill_scale_tbl(struct iio_dev *dev) +{ + struct ad7768_state *st = iio_priv(dev); + const struct iio_scan_type *scan_type; + int val, val2, tmp0, tmp1, i; + struct u32_fract fract; + unsigned long n, d; + u64 tmp2; + + scan_type = iio_get_current_scan_type(dev, &dev->channels[0]); + if (IS_ERR(scan_type)) { + dev_err(&st->spi->dev, "Failed to get scan type.\n"); + return PTR_ERR(scan_type); + } + + if (scan_type->sign == 's') + val2 = scan_type->realbits - 1; + else + val2 = scan_type->realbits; + + for (i = 0; i < st->chip->num_pga_modes; i++) { + /* Convert gain to a fraction format */ + fract.numerator = st->chip->pga_gains[i]; + fract.denominator = MILLI; + if (st->chip->has_variable_aaf) { + fract.numerator *= ad7768_aaf_gains_bp[st->aaf_gain]; + fract.denominator *= PERMYRIAD; + } + + rational_best_approximation(fract.numerator, fract.denominator, + INT_MAX, INT_MAX, &n, &d); + + val = mult_frac(st->vref_uv, d, n); + /* Would multiply by NANO here, but value is already in milli */ + tmp2 = ((u64)val * MICRO) >> val2; + tmp0 = div_u64_rem(tmp2, NANO, &tmp1); + st->scale_tbl[i][0] = tmp0; /* Integer part */ + st->scale_tbl[i][1] = abs(tmp1); /* Fractional part */ + } + + return 0; +} + static int ad7768_set_sinc3_dec_rate(struct ad7768_state *st, unsigned int dec_rate) { @@ -558,12 +675,68 @@ static int ad7768_configure_dig_fil(struct iio_dev *dev, st->oversampling_ratio = ad7768_dec_rate_values[dec_rate_idx]; } + /* Update scale table: scale values vary according to the precision */ + ret = ad7768_fill_scale_tbl(dev); + if (ret) + return ret; + ad7768_fill_samp_freq_tbl(st); /* A sync-in pulse is required after every configuration change */ return ad7768_send_sync_pulse(st); } +static int ad7768_setup_pga(struct device *dev, struct ad7768_state *st) +{ + st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW); + if (IS_ERR(st->pga_gpios)) + return dev_err_probe(dev, PTR_ERR(st->pga_gpios), + "Failed to get PGA gpios.\n"); + + if (st->pga_gpios->ndescs != ADAQ7768_PGA_PINS) + return dev_err_probe(dev, -EINVAL, + "Expected %d GPIOs for PGA control.\n", + ADAQ7768_PGA_PINS); + return 0; +} + +static int ad7768_calc_pga_gain(struct ad7768_state *st, int gain_int, + int gain_fract, int precision) +{ + u64 gain_nano; + u32 tmp; + + gain_nano = gain_int * NANO + gain_fract; + gain_nano = clamp(gain_nano, 0, ADAQ776X_GAIN_MAX_NANO); + tmp = DIV_ROUND_CLOSEST_ULL(gain_nano << precision, NANO); + gain_nano = DIV_ROUND_CLOSEST(st->vref_uv, tmp); + if (st->chip->has_variable_aaf) + gain_nano = DIV_ROUND_CLOSEST_ULL(gain_nano * PERMYRIAD, + ad7768_aaf_gains_bp[st->aaf_gain]); + + return find_closest(gain_nano, st->chip->pga_gains, + (int)st->chip->num_pga_modes); +} + +static int ad7768_set_pga_gain(struct ad7768_state *st, + int gain_mode) +{ + int pgia_pins_value = abs(gain_mode - st->chip->pgia_mode2pin_offset); + DECLARE_BITMAP(bitmap, ADAQ7768_PGA_PINS) = { }; + int ret; + + guard(mutex)(&st->pga_lock); + + bitmap_write(bitmap, pgia_pins_value, 0, ADAQ7768_PGA_PINS); + ret = gpiod_multi_set_value_cansleep(st->pga_gpios, bitmap); + if (ret) + return ret; + + st->pga_gain_mode = gain_mode; + + return 0; +} + static int ad7768_gpio_direction_input(struct gpio_chip *chip, unsigned int offset) { struct iio_dev *indio_dev = gpiochip_get_data(chip); @@ -735,6 +908,19 @@ static int ad7768_get_filter_type_attr(struct iio_dev *dev, return ad7768_filter_regval_to_type[FIELD_GET(mask, mode)]; } +static int ad7768_update_dec_rate(struct iio_dev *dev, unsigned int dec_rate) +{ + struct ad7768_state *st = iio_priv(dev); + int ret; + + ret = ad7768_configure_dig_fil(dev, st->filter_type, dec_rate); + if (ret) + return ret; + + /* Update sampling frequency */ + return ad7768_set_freq(st, st->samp_freq); +} + static const struct iio_enum ad7768_filter_type_iio_enum = { .items = ad7768_filter_enum, .num_items = ARRAY_SIZE(ad7768_filter_enum), @@ -748,24 +934,32 @@ static const struct iio_chan_spec_ext_info ad7768_ext_info[] = { { } }; +#define AD7768_CHAN(_idx, _msk_avail) \ +{ \ + .type = IIO_VOLTAGE, \ + .info_mask_separate_available = _msk_avail, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | \ + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .ext_info = ad7768_ext_info, \ + .indexed = 1, \ + .channel = _idx, \ + .scan_index = _idx, \ + .has_ext_scan_type = 1, \ + .ext_scan_type = ad7768_scan_type, \ + .num_ext_scan_type = ARRAY_SIZE(ad7768_scan_type), \ +} + static const struct iio_chan_spec ad7768_channels[] = { - { - .type = IIO_VOLTAGE, - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY) | - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), - .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), - .ext_info = ad7768_ext_info, - .indexed = 1, - .channel = 0, - .scan_index = 0, - .has_ext_scan_type = 1, - .ext_scan_type = ad7768_scan_type, - .num_ext_scan_type = ARRAY_SIZE(ad7768_scan_type), - }, + AD7768_CHAN(0, 0), +}; + +static const struct iio_chan_spec adaq776x_channels[] = { + AD7768_CHAN(0, BIT(IIO_CHAN_INFO_SCALE)), }; static int ad7768_read_raw(struct iio_dev *indio_dev, @@ -795,7 +989,19 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: - *val = (st->vref_uv * 2) / 1000; + if (st->chip->has_pga) { + guard(mutex)(&st->pga_lock); + + *val = st->scale_tbl[st->pga_gain_mode][0]; + *val2 = st->scale_tbl[st->pga_gain_mode][1]; + return IIO_VAL_INT_PLUS_NANO; + } + + temp = (st->vref_uv * 2) / 1000; + if (st->chip->has_variable_aaf) + temp = (temp * PERMYRIAD) / ad7768_aaf_gains_bp[st->aaf_gain]; + + *val = temp; *val2 = scan_type->realbits; return IIO_VAL_FRACTIONAL_LOG2; @@ -851,31 +1057,24 @@ static int ad7768_read_avail(struct iio_dev *indio_dev, *length = st->samp_freq_avail_len; *type = IIO_VAL_INT; return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SCALE: + *vals = (int *)st->scale_tbl; + *length = st->chip->num_pga_modes * 2; + *type = IIO_VAL_INT_PLUS_NANO; + return IIO_AVAIL_LIST; default: return -EINVAL; } } -static int __ad7768_write_raw(struct iio_dev *indio_dev, - struct iio_chan_spec const *chan, - int val, int val2, long info) +static int ad7768_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long mask) { - struct ad7768_state *st = iio_priv(indio_dev); - int ret; - - switch (info) { - case IIO_CHAN_INFO_SAMP_FREQ: - return ad7768_set_freq(st, val); - - case IIO_CHAN_INFO_OVERSAMPLING_RATIO: - ret = ad7768_configure_dig_fil(indio_dev, st->filter_type, val); - if (ret) - return ret; - - /* Update sampling frequency */ - return ad7768_set_freq(st, st->samp_freq); + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; default: - return -EINVAL; + return IIO_VAL_INT_PLUS_MICRO; } } @@ -883,15 +1082,47 @@ static int ad7768_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long info) { + struct ad7768_state *st = iio_priv(indio_dev); + const struct iio_scan_type *scan_type; int ret; - if (!iio_device_claim_direct(indio_dev)) - return -EBUSY; + scan_type = iio_get_current_scan_type(indio_dev, chan); + if (IS_ERR(scan_type)) + return PTR_ERR(scan_type); - ret = __ad7768_write_raw(indio_dev, chan, val, val2, info); - iio_device_release_direct(indio_dev); + switch (info) { + case IIO_CHAN_INFO_SAMP_FREQ: + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; - return ret; + ret = ad7768_set_freq(st, val); + iio_device_release_direct(indio_dev); + return ret; + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = ad7768_update_dec_rate(indio_dev, val); + iio_device_release_direct(indio_dev); + return ret; + case IIO_CHAN_INFO_SCALE: { + int gain_mode; + + if (!st->chip->has_pga) + return -EOPNOTSUPP; + + if (scan_type->sign == 's') + gain_mode = ad7768_calc_pga_gain(st, val, val2, + scan_type->realbits - 1); + else + gain_mode = ad7768_calc_pga_gain(st, val, val2, + scan_type->realbits); + + return ad7768_set_pga_gain(st, gain_mode); + } + default: + return -EINVAL; + } } static int ad7768_read_label(struct iio_dev *indio_dev, @@ -915,6 +1146,7 @@ static const struct iio_info ad7768_info = { .read_raw = &ad7768_read_raw, .read_avail = &ad7768_read_avail, .write_raw = &ad7768_write_raw, + .write_raw_get_fmt = &ad7768_write_raw_get_fmt, .read_label = ad7768_read_label, .get_current_scan_type = &ad7768_get_current_scan_type, .debugfs_reg_access = &ad7768_reg_access, @@ -1298,8 +1530,9 @@ static const struct regulator_desc vcm_desc = { .owner = THIS_MODULE, }; -static int ad7768_register_regulators(struct device *dev, struct ad7768_state *st, - struct iio_dev *indio_dev) +static int ad7768_register_vcm_regulator(struct device *dev, + struct ad7768_state *st, + struct iio_dev *indio_dev) { struct regulator_config config = { .dev = dev, @@ -1321,6 +1554,79 @@ static int ad7768_register_regulators(struct device *dev, struct ad7768_state *s return 0; } +static int ad7768_parse_aaf_gain(struct device *dev, struct ad7768_state *st) +{ + u32 val; + int ret; + + ret = device_property_read_u32(dev, "adi,aaf-gain-bp", &val); + if (ret == -EINVAL) { + /* If controllable, use default */ + if (st->chip->has_variable_aaf) + st->aaf_gain = AD7768_AAF_IN1; + return 0; + } + if (ret) + return dev_err_probe(dev, ret, "Failed to get AAF gain value\n"); + + if (!st->chip->has_variable_aaf) + return dev_err_probe(dev, -EOPNOTSUPP, + "AAF gain provided, but not supported for %s\n", st->chip->name); + + switch (val) { + case 10000: + st->aaf_gain = AD7768_AAF_IN1; + break; + case 3640: + st->aaf_gain = AD7768_AAF_IN2; + break; + case 1430: + st->aaf_gain = AD7768_AAF_IN3; + break; + default: + return dev_err_probe(dev, -EINVAL, "Invalid firmware provided AAF gain\n"); + } + + return 0; +} + +static const struct ad7768_chip_info ad7768_chip_info = { + .name = "ad7768-1", + .channel_spec = ad7768_channels, + .num_channels = ARRAY_SIZE(ad7768_channels), + .has_vcm_regulator = true, +}; + +static const struct ad7768_chip_info adaq7767_chip_info = { + .name = "adaq7767-1", + .channel_spec = ad7768_channels, + .num_channels = ARRAY_SIZE(ad7768_channels), + .has_variable_aaf = true, +}; + +static const struct ad7768_chip_info adaq7768_chip_info = { + .name = "adaq7768-1", + .channel_spec = adaq776x_channels, + .num_channels = ARRAY_SIZE(adaq776x_channels), + .pga_gains = adaq7768_gains, + .default_pga_mode = AD7768_PGA_GAIN_2, + .num_pga_modes = ARRAY_SIZE(adaq7768_gains), + .pgia_mode2pin_offset = 6, + .has_pga = true, +}; + +static const struct ad7768_chip_info adaq7769_chip_info = { + .name = "adaq7769-1", + .channel_spec = adaq776x_channels, + .num_channels = ARRAY_SIZE(adaq776x_channels), + .pga_gains = adaq7769_gains, + .default_pga_mode = AD7768_PGA_GAIN_0, + .num_pga_modes = ARRAY_SIZE(adaq7769_gains), + .pgia_mode2pin_offset = 0, + .has_pga = true, + .has_variable_aaf = true, +}; + static int ad7768_probe(struct spi_device *spi) { struct ad7768_state *st; @@ -1347,6 +1653,7 @@ static int ad7768_probe(struct spi_device *spi) return ret; } + st->chip = spi_get_device_match_data(spi); st->spi = spi; st->regmap = devm_regmap_init_spi(spi, &ad7768_regmap_config); @@ -1371,14 +1678,20 @@ static int ad7768_probe(struct spi_device *spi) st->mclk_freq = clk_get_rate(st->mclk); - indio_dev->channels = ad7768_channels; - indio_dev->num_channels = ARRAY_SIZE(ad7768_channels); - indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->channels = st->chip->channel_spec; + indio_dev->num_channels = st->chip->num_channels; + indio_dev->name = st->chip->name; indio_dev->info = &ad7768_info; indio_dev->modes = INDIO_DIRECT_MODE; /* Register VCM output regulator */ - ret = ad7768_register_regulators(&spi->dev, st, indio_dev); + if (st->chip->has_vcm_regulator) { + ret = ad7768_register_vcm_regulator(&spi->dev, st, indio_dev); + if (ret) + return ret; + } + + ret = ad7768_parse_aaf_gain(&spi->dev, st); if (ret) return ret; @@ -1389,14 +1702,26 @@ static int ad7768_probe(struct spi_device *spi) } init_completion(&st->completion); - - ret = ad7768_set_channel_label(indio_dev, ARRAY_SIZE(ad7768_channels)); + ret = devm_mutex_init(&spi->dev, &st->pga_lock); if (ret) return ret; - ret = devm_request_irq(&spi->dev, spi->irq, - &ad7768_interrupt, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + if (st->chip->has_pga) { + ret = ad7768_setup_pga(&spi->dev, st); + if (ret) + return ret; + + ret = ad7768_set_pga_gain(st, st->chip->default_pga_mode); + if (ret) + return ret; + } + + ret = ad7768_set_channel_label(indio_dev, st->chip->num_channels); + if (ret) + return ret; + + ret = devm_request_irq(&spi->dev, spi->irq, &ad7768_interrupt, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, indio_dev->name, indio_dev); if (ret) return ret; @@ -1409,13 +1734,19 @@ static int ad7768_probe(struct spi_device *spi) } static const struct spi_device_id ad7768_id_table[] = { - { "ad7768-1", 0 }, + { "ad7768-1", (kernel_ulong_t)&ad7768_chip_info }, + { "adaq7767-1", (kernel_ulong_t)&adaq7767_chip_info }, + { "adaq7768-1", (kernel_ulong_t)&adaq7768_chip_info }, + { "adaq7769-1", (kernel_ulong_t)&adaq7769_chip_info }, { } }; MODULE_DEVICE_TABLE(spi, ad7768_id_table); static const struct of_device_id ad7768_of_match[] = { - { .compatible = "adi,ad7768-1" }, + { .compatible = "adi,ad7768-1", .data = &ad7768_chip_info }, + { .compatible = "adi,adaq7767-1", .data = &adaq7767_chip_info }, + { .compatible = "adi,adaq7768-1", .data = &adaq7768_chip_info }, + { .compatible = "adi,adaq7769-1", .data = &adaq7769_chip_info }, { } }; MODULE_DEVICE_TABLE(of, ad7768_of_match); diff --git a/drivers/iio/adc/ad7779.c b/drivers/iio/adc/ad7779.c index aac5049c9a07..695cc79e78da 100644 --- a/drivers/iio/adc/ad7779.c +++ b/drivers/iio/adc/ad7779.c @@ -840,7 +840,7 @@ static int ad7779_setup_without_backend(struct ad7779_state *st, struct iio_dev iio_trigger_set_drvdata(st->trig, st); ret = devm_request_irq(dev, st->spi->irq, iio_trigger_generic_data_rdy_poll, - IRQF_ONESHOT | IRQF_NO_AUTOEN, indio_dev->name, + IRQF_NO_THREAD | IRQF_NO_AUTOEN, indio_dev->name, st->trig); if (ret) return dev_err_probe(dev, ret, "request IRQ %d failed\n", diff --git a/drivers/iio/adc/ad9467.c b/drivers/iio/adc/ad9467.c index 2d8f8da3671d..022888545580 100644 --- a/drivers/iio/adc/ad9467.c +++ b/drivers/iio/adc/ad9467.c @@ -5,29 +5,29 @@ * Copyright 2012-2020 Analog Devices Inc. */ +#include #include #include #include +#include #include +#include +#include +#include +#include +#include #include #include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include - +#include #include #include #include -#include - /* * ADI High-Speed ADC common spi interface registers * See Application-Note AN-877: @@ -73,6 +73,7 @@ #define AN877_ADC_OUTPUT_MODE_OFFSET_BINARY 0x0 #define AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT 0x1 #define AN877_ADC_OUTPUT_MODE_GRAY_CODE 0x2 +#define AN877_ADC_OUTPUT_MODE_MASK GENMASK(1, 0) /* AN877_ADC_REG_OUTPUT_PHASE */ #define AN877_ADC_OUTPUT_EVEN_ODD_MODE_EN 0x20 @@ -81,12 +82,20 @@ /* AN877_ADC_REG_OUTPUT_DELAY */ #define AN877_ADC_DCO_DELAY_ENABLE 0x80 +/* + * Analog Devices AD9211 10-Bit, 200/250/300 MSPS ADC + */ + +#define CHIPID_AD9211 0x06 +#define AD9211_DEF_OUTPUT_MODE 0x01 +#define AD9211_REG_VREF_MASK GENMASK(4, 0) + /* * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC */ #define CHIPID_AD9265 0x64 -#define AD9265_DEF_OUTPUT_MODE 0x40 +#define AD9265_DEF_OUTPUT_MODE 0x41 #define AD9265_REG_VREF_MASK 0xC0 /* @@ -94,7 +103,7 @@ */ #define CHIPID_AD9434 0x6A -#define AD9434_DEF_OUTPUT_MODE 0x00 +#define AD9434_DEF_OUTPUT_MODE 0x01 #define AD9434_REG_VREF_MASK GENMASK(4, 0) /* @@ -102,7 +111,7 @@ */ #define CHIPID_AD9467 0x50 -#define AD9467_DEF_OUTPUT_MODE 0x08 +#define AD9467_DEF_OUTPUT_MODE 0x09 #define AD9467_REG_VREF_MASK 0x0F /* @@ -110,6 +119,7 @@ */ #define CHIPID_AD9643 0x82 +#define AD9643_DEF_OUTPUT_MODE 0x01 #define AD9643_REG_VREF_MASK 0x1F /* @@ -117,6 +127,7 @@ */ #define CHIPID_AD9652 0xC1 +#define AD9652_DEF_OUTPUT_MODE 0x01 #define AD9652_REG_VREF_MASK 0xC0 /* @@ -124,6 +135,7 @@ */ #define CHIPID_AD9649 0x6F +#define AD9649_DEF_OUTPUT_MODE 0x01 #define AD9649_TEST_POINTS 8 #define AD9647_MAX_TEST_POINTS 32 @@ -145,6 +157,7 @@ struct ad9467_chip_info { unsigned int num_lanes; unsigned int dco_en; unsigned int test_points; + const int *offset_range; /* data clock output */ bool has_dco; bool has_dco_invert; @@ -234,6 +247,21 @@ static int ad9467_reg_access(struct iio_dev *indio_dev, unsigned int reg, return 0; } +static const int ad9434_offset_range[] = { + -128, 1, 127, +}; + +static const unsigned int ad9211_scale_table[][2] = { + {980, 0x10}, {1000, 0x11}, {1020, 0x12}, {1040, 0x13}, + {1060, 0x14}, {1080, 0x15}, {1100, 0x16}, {1120, 0x17}, + {1140, 0x18}, {1160, 0x19}, {1180, 0x1A}, {1190, 0x1B}, + {1200, 0x1C}, {1210, 0x1D}, {1220, 0x1E}, {1230, 0x1F}, + {1250, 0x0}, {1270, 0x1}, {1290, 0x2}, {1310, 0x3}, + {1330, 0x4}, {1350, 0x5}, {1370, 0x6}, {1390, 0x7}, + {1410, 0x8}, {1430, 0x9}, {1450, 0xA}, {1460, 0xB}, + {1470, 0xC}, {1480, 0xD}, {1490, 0xE}, {1500, 0xF}, +}; + static const unsigned int ad9265_scale_table[][2] = { {1250, 0x00}, {1500, 0x40}, {1750, 0x80}, {2000, 0xC0}, }; @@ -297,8 +325,29 @@ static void __ad9467_get_scale(struct ad9467_state *st, int index, }, \ } +static const struct iio_chan_spec ad9211_channels[] = { + AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 10, 's'), +}; + static const struct iio_chan_spec ad9434_channels[] = { - AD9467_CHAN(0, BIT(IIO_CHAN_INFO_SCALE), 0, 12, 's'), + { + .type = IIO_VOLTAGE, + .indexed = 1, + .channel = 0, + .info_mask_shared_by_type = + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_SAMP_FREQ) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + .info_mask_shared_by_type_available = + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_CALIBBIAS), + .scan_index = 0, + .scan_type = { + .sign = 's', + .realbits = 12, + .storagebits = 16, + }, + }, }; static const struct iio_chan_spec ad9467_channels[] = { @@ -367,6 +416,24 @@ static const struct ad9467_chip_info ad9434_chip_tbl = { .default_output_mode = AD9434_DEF_OUTPUT_MODE, .vref_mask = AD9434_REG_VREF_MASK, .num_lanes = 6, + .offset_range = ad9434_offset_range, +}; + +static const struct ad9467_chip_info ad9211_chip_tbl = { + .name = "ad9211", + .id = CHIPID_AD9211, + .max_rate = 300 * HZ_PER_MHZ, + .scale_table = ad9211_scale_table, + .num_scales = ARRAY_SIZE(ad9211_scale_table), + .channels = ad9211_channels, + .num_channels = ARRAY_SIZE(ad9211_channels), + .test_points = AD9647_MAX_TEST_POINTS, + .test_mask = GENMASK(AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE, + AN877_ADC_TESTMODE_OFF), + .test_mask_len = AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE + 1, + .default_output_mode = AD9211_DEF_OUTPUT_MODE, + .vref_mask = AD9211_REG_VREF_MASK, + .has_dco = true, }; static const struct ad9467_chip_info ad9265_chip_tbl = { @@ -399,6 +466,7 @@ static const struct ad9467_chip_info ad9643_chip_tbl = { .test_mask = BIT(AN877_ADC_TESTMODE_RAMP) | GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY, AN877_ADC_TESTMODE_OFF), .test_mask_len = AN877_ADC_TESTMODE_RAMP + 1, + .default_output_mode = AD9643_DEF_OUTPUT_MODE, .vref_mask = AD9643_REG_VREF_MASK, .has_dco = true, .has_dco_invert = true, @@ -417,6 +485,7 @@ static const struct ad9467_chip_info ad9649_chip_tbl = { .test_mask = GENMASK(AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY, AN877_ADC_TESTMODE_OFF), .test_mask_len = AN877_ADC_TESTMODE_MIXED_BIT_FREQUENCY + 1, + .default_output_mode = AD9649_DEF_OUTPUT_MODE, .has_dco = true, .has_dco_invert = true, .dco_en = AN877_ADC_DCO_DELAY_ENABLE, @@ -434,6 +503,7 @@ static const struct ad9467_chip_info ad9652_chip_tbl = { .test_mask = GENMASK(AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE, AN877_ADC_TESTMODE_OFF), .test_mask_len = AN877_ADC_TESTMODE_ONE_ZERO_TOGGLE + 1, + .default_output_mode = AD9652_DEF_OUTPUT_MODE, .vref_mask = AD9652_REG_VREF_MASK, .has_dco = true, }; @@ -499,6 +569,33 @@ static int ad9467_set_scale(struct ad9467_state *st, int val, int val2) return -EINVAL; } +static int ad9467_get_offset(struct ad9467_state *st, int *val) +{ + int ret; + + ret = ad9467_spi_read(st, AN877_ADC_REG_OFFSET); + if (ret < 0) + return ret; + *val = ret; + + return IIO_VAL_INT; +} + +static int ad9467_set_offset(struct ad9467_state *st, int val) +{ + int ret; + + if (val < st->info->offset_range[0] || val > st->info->offset_range[2]) + return -EINVAL; + + ret = ad9467_spi_write(st, AN877_ADC_REG_OFFSET, val); + if (ret < 0) + return ret; + + return ad9467_spi_write(st, AN877_ADC_REG_TRANSFER, + AN877_ADC_TRANSFER_SYNC); +} + static int ad9467_outputmode_set(struct ad9467_state *st, unsigned int mode) { int ret; @@ -582,10 +679,14 @@ static int ad9467_backend_testmode_off(struct ad9467_state *st, static int ad9647_calibrate_prepare(struct ad9467_state *st) { + unsigned int cmode; unsigned int c; int ret; - ret = ad9467_outputmode_set(st, st->info->default_output_mode); + cmode = st->info->default_output_mode; + FIELD_MODIFY(AN877_ADC_OUTPUT_MODE_MASK, &cmode, + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY); + ret = ad9467_outputmode_set(st, cmode); if (ret) return ret; @@ -689,7 +790,7 @@ static int ad9647_calibrate_stop(struct ad9467_state *st) return ret; } - mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; + mode = st->info->default_output_mode; return ad9467_outputmode_set(st, mode); } @@ -802,6 +903,8 @@ static int ad9467_read_raw(struct iio_dev *indio_dev, struct ad9467_state *st = iio_priv(indio_dev); switch (m) { + case IIO_CHAN_INFO_CALIBBIAS: + return ad9467_get_offset(st, val); case IIO_CHAN_INFO_SCALE: return ad9467_get_scale(st, val, val2); case IIO_CHAN_INFO_SAMP_FREQ: @@ -836,6 +939,8 @@ static int ad9467_write_raw(struct iio_dev *indio_dev, int ret; switch (mask) { + case IIO_CHAN_INFO_CALIBBIAS: + return ad9467_set_offset(st, val); case IIO_CHAN_INFO_SCALE: return ad9467_set_scale(st, val, val2); case IIO_CHAN_INFO_SAMP_FREQ: @@ -874,6 +979,10 @@ static int ad9467_read_avail(struct iio_dev *indio_dev, const struct ad9467_chip_info *info = st->info; switch (mask) { + case IIO_CHAN_INFO_CALIBBIAS: + *type = IIO_VAL_INT; + *vals = info->offset_range; + return IIO_AVAIL_RANGE; case IIO_CHAN_INFO_SCALE: *vals = (const int *)st->scales; *type = IIO_VAL_INT_PLUS_MICRO; @@ -1077,12 +1186,17 @@ static ssize_t ad9467_chan_test_mode_write(struct file *file, if (ret) return ret; - out_mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; + out_mode = st->info->default_output_mode; ret = ad9467_outputmode_set(st, out_mode); if (ret) return ret; } else { - ret = ad9467_outputmode_set(st, st->info->default_output_mode); + unsigned int cmode; + + cmode = st->info->default_output_mode; + FIELD_MODIFY(AN877_ADC_OUTPUT_MODE_MASK, &cmode, + AN877_ADC_OUTPUT_MODE_OFFSET_BINARY); + ret = ad9467_outputmode_set(st, cmode); if (ret) return ret; @@ -1264,6 +1378,7 @@ static int ad9467_probe(struct spi_device *spi) } static const struct of_device_id ad9467_of_match[] = { + { .compatible = "adi,ad9211", .data = &ad9211_chip_tbl, }, { .compatible = "adi,ad9265", .data = &ad9265_chip_tbl, }, { .compatible = "adi,ad9434", .data = &ad9434_chip_tbl, }, { .compatible = "adi,ad9467", .data = &ad9467_chip_tbl, }, @@ -1275,6 +1390,7 @@ static const struct of_device_id ad9467_of_match[] = { MODULE_DEVICE_TABLE(of, ad9467_of_match); static const struct spi_device_id ad9467_ids[] = { + { "ad9211", (kernel_ulong_t)&ad9211_chip_tbl }, { "ad9265", (kernel_ulong_t)&ad9265_chip_tbl }, { "ad9434", (kernel_ulong_t)&ad9434_chip_tbl }, { "ad9467", (kernel_ulong_t)&ad9467_chip_tbl }, diff --git a/drivers/iio/adc/ade9000.c b/drivers/iio/adc/ade9000.c index 2de8a718d62a..db085dc5e526 100644 --- a/drivers/iio/adc/ade9000.c +++ b/drivers/iio/adc/ade9000.c @@ -964,7 +964,7 @@ static irqreturn_t ade9000_dready_thread(int irq, void *data) struct iio_dev *indio_dev = data; /* Handle data ready interrupt from C4/EVENT/DREADY pin */ - if (!iio_device_claim_buffer_mode(indio_dev)) { + if (iio_device_try_claim_buffer_mode(indio_dev)) { ade9000_iio_push_buffer(indio_dev); iio_device_release_buffer_mode(indio_dev); } diff --git a/drivers/iio/adc/adi-axi-adc.c b/drivers/iio/adc/adi-axi-adc.c index 14fa4238c2b9..5f445e0de9ea 100644 --- a/drivers/iio/adc/adi-axi-adc.c +++ b/drivers/iio/adc/adi-axi-adc.c @@ -591,17 +591,12 @@ static int axi_adc_create_platform_device(struct adi_axi_adc_state *st, .size_data = st->info->pdata_sz, }; struct platform_device *pdev; - int ret; pdev = platform_device_register_full(&pi); if (IS_ERR(pdev)) return PTR_ERR(pdev); - ret = devm_add_action_or_reset(st->dev, axi_adc_child_remove, pdev); - if (ret) - return ret; - - return 0; + return devm_add_action_or_reset(st->dev, axi_adc_child_remove, pdev); } static const struct iio_backend_ops adi_axi_adc_ops = { @@ -674,13 +669,14 @@ static const struct iio_backend_info axi_ad408x = { static int adi_axi_adc_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct adi_axi_adc_state *st; void __iomem *base; unsigned int ver; struct clk *clk; int ret; - st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; @@ -688,20 +684,19 @@ static int adi_axi_adc_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - st->dev = &pdev->dev; - st->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &axi_adc_regmap_config); + st->dev = dev; + st->regmap = devm_regmap_init_mmio(dev, base, &axi_adc_regmap_config); if (IS_ERR(st->regmap)) - return dev_err_probe(&pdev->dev, PTR_ERR(st->regmap), + return dev_err_probe(dev, PTR_ERR(st->regmap), "failed to init register map\n"); - st->info = device_get_match_data(&pdev->dev); + st->info = device_get_match_data(dev); if (!st->info) return -ENODEV; - clk = devm_clk_get_enabled(&pdev->dev, NULL); + clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk), + return dev_err_probe(dev, PTR_ERR(clk), "failed to get clock\n"); /* @@ -716,47 +711,42 @@ static int adi_axi_adc_probe(struct platform_device *pdev) if (ret) return ret; - if (ADI_AXI_PCORE_VER_MAJOR(ver) != - ADI_AXI_PCORE_VER_MAJOR(st->info->version)) { - dev_err(&pdev->dev, - "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", - ADI_AXI_PCORE_VER_MAJOR(st->info->version), - ADI_AXI_PCORE_VER_MINOR(st->info->version), - ADI_AXI_PCORE_VER_PATCH(st->info->version), - ADI_AXI_PCORE_VER_MAJOR(ver), - ADI_AXI_PCORE_VER_MINOR(ver), - ADI_AXI_PCORE_VER_PATCH(ver)); - return -ENODEV; - } + if (ADI_AXI_PCORE_VER_MAJOR(ver) != ADI_AXI_PCORE_VER_MAJOR(st->info->version)) + return dev_err_probe(dev, -ENODEV, + "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", + ADI_AXI_PCORE_VER_MAJOR(st->info->version), + ADI_AXI_PCORE_VER_MINOR(st->info->version), + ADI_AXI_PCORE_VER_PATCH(st->info->version), + ADI_AXI_PCORE_VER_MAJOR(ver), + ADI_AXI_PCORE_VER_MINOR(ver), + ADI_AXI_PCORE_VER_PATCH(ver)); - ret = devm_iio_backend_register(&pdev->dev, st->info->backend_info, st); + ret = devm_iio_backend_register(dev, st->info->backend_info, st); if (ret) - return dev_err_probe(&pdev->dev, ret, - "failed to register iio backend\n"); + return dev_err_probe(dev, ret, "failed to register iio backend\n"); - device_for_each_child_node_scoped(&pdev->dev, child) { + device_for_each_child_node_scoped(dev, child) { int val; if (!st->info->has_child_nodes) - return dev_err_probe(&pdev->dev, -EINVAL, + return dev_err_probe(dev, -EINVAL, "invalid fdt axi-dac compatible."); /* Processing only reg 0 node */ ret = fwnode_property_read_u32(child, "reg", &val); if (ret) - return dev_err_probe(&pdev->dev, ret, - "invalid reg property."); + return dev_err_probe(dev, ret, "invalid reg property."); if (val != 0) - return dev_err_probe(&pdev->dev, -EINVAL, + return dev_err_probe(dev, -EINVAL, "invalid node address."); ret = axi_adc_create_platform_device(st, child); if (ret) - return dev_err_probe(&pdev->dev, -EINVAL, + return dev_err_probe(dev, -EINVAL, "cannot create device."); } - dev_info(&pdev->dev, "AXI ADC IP core (%d.%.2d.%c) probed\n", + dev_info(dev, "AXI ADC IP core (%d.%.2d.%c) probed\n", ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); diff --git a/drivers/iio/adc/aspeed_adc.c b/drivers/iio/adc/aspeed_adc.c index bf2bfd6bdc41..4be44c524b4d 100644 --- a/drivers/iio/adc/aspeed_adc.c +++ b/drivers/iio/adc/aspeed_adc.c @@ -472,16 +472,18 @@ static int aspeed_adc_probe(struct platform_device *pdev) struct aspeed_adc_data *data; int ret; u32 adc_engine_control_reg_val; + struct device *dev = &pdev->dev; + struct device_node *np = dev_of_node(dev); unsigned long scaler_flags = 0; char clk_name[32], clk_parent_name[32]; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*data)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) return -ENOMEM; data = iio_priv(indio_dev); - data->dev = &pdev->dev; - data->model_data = of_device_get_match_data(&pdev->dev); + data->dev = dev; + data->model_data = of_device_get_match_data(dev); platform_set_drvdata(pdev, indio_dev); data->base = devm_platform_ioremap_resource(pdev, 0); @@ -491,16 +493,15 @@ static int aspeed_adc_probe(struct platform_device *pdev) /* Register ADC clock prescaler with source specified by device tree. */ spin_lock_init(&data->clk_lock); snprintf(clk_parent_name, ARRAY_SIZE(clk_parent_name), "%s", - of_clk_get_parent_name(pdev->dev.of_node, 0)); + of_clk_get_parent_name(np, 0)); snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-fixed-div", data->model_data->model_name); - data->fixed_div_clk = clk_hw_register_fixed_factor( - &pdev->dev, clk_name, clk_parent_name, 0, 1, 2); + data->fixed_div_clk = clk_hw_register_fixed_factor(dev, clk_name, + clk_parent_name, 0, 1, 2); if (IS_ERR(data->fixed_div_clk)) return PTR_ERR(data->fixed_div_clk); - ret = devm_add_action_or_reset(data->dev, - aspeed_adc_unregister_fixed_divider, + ret = devm_add_action_or_reset(dev, aspeed_adc_unregister_fixed_divider, data->fixed_div_clk); if (ret) return ret; @@ -510,7 +511,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-prescaler", data->model_data->model_name); data->clk_prescaler = devm_clk_hw_register_divider( - &pdev->dev, clk_name, clk_parent_name, 0, + dev, clk_name, clk_parent_name, 0, data->base + ASPEED_REG_CLOCK_CONTROL, 17, 15, 0, &data->clk_lock); if (IS_ERR(data->clk_prescaler)) @@ -526,7 +527,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) snprintf(clk_name, ARRAY_SIZE(clk_name), "%s-scaler", data->model_data->model_name); data->clk_scaler = devm_clk_hw_register_divider( - &pdev->dev, clk_name, clk_parent_name, scaler_flags, + dev, clk_name, clk_parent_name, scaler_flags, data->base + ASPEED_REG_CLOCK_CONTROL, 0, data->model_data->scaler_bit_width, data->model_data->need_prescaler ? CLK_DIVIDER_ONE_BASED : 0, @@ -534,16 +535,14 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (IS_ERR(data->clk_scaler)) return PTR_ERR(data->clk_scaler); - data->rst = devm_reset_control_get_shared(&pdev->dev, NULL); - if (IS_ERR(data->rst)) { - dev_err(&pdev->dev, - "invalid or missing reset controller device tree entry"); - return PTR_ERR(data->rst); - } + data->rst = devm_reset_control_get_shared(dev, NULL); + if (IS_ERR(data->rst)) + return dev_err_probe(dev, PTR_ERR(data->rst), + "invalid or missing reset controller device tree entry"); + reset_control_deassert(data->rst); - ret = devm_add_action_or_reset(data->dev, aspeed_adc_reset_assert, - data->rst); + ret = devm_add_action_or_reset(dev, aspeed_adc_reset_assert, data->rst); if (ret) return ret; @@ -555,7 +554,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) if (ret) return ret; - if (of_property_present(data->dev->of_node, "aspeed,battery-sensing")) { + if (of_property_present(np, "aspeed,battery-sensing")) { if (data->model_data->bat_sense_sup) { data->battery_sensing = 1; if (readl(data->base + ASPEED_REG_ENGINE_CONTROL) & @@ -567,15 +566,13 @@ static int aspeed_adc_probe(struct platform_device *pdev) data->battery_mode_gain.div = 2; } } else - dev_warn(&pdev->dev, - "Failed to enable battery-sensing mode\n"); + dev_warn(dev, "Failed to enable battery-sensing mode\n"); } ret = clk_prepare_enable(data->clk_scaler->clk); if (ret) return ret; - ret = devm_add_action_or_reset(data->dev, - aspeed_adc_clk_disable_unprepare, + ret = devm_add_action_or_reset(dev, aspeed_adc_clk_disable_unprepare, data->clk_scaler->clk); if (ret) return ret; @@ -593,8 +590,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) writel(adc_engine_control_reg_val, data->base + ASPEED_REG_ENGINE_CONTROL); - ret = devm_add_action_or_reset(data->dev, aspeed_adc_power_down, - data); + ret = devm_add_action_or_reset(dev, aspeed_adc_power_down, data); if (ret) return ret; @@ -626,8 +622,7 @@ static int aspeed_adc_probe(struct platform_device *pdev) aspeed_adc_iio_channels; indio_dev->num_channels = data->model_data->num_channels; - ret = devm_iio_device_register(data->dev, indio_dev); - return ret; + return devm_iio_device_register(dev, indio_dev); } static const struct aspeed_adc_trim_locate ast2500_adc_trim = { diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index f2400897818c..c1a0061b16ca 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c @@ -543,22 +543,21 @@ static const struct iio_chan_spec exynos_adc_iio_channels[] = { static int exynos_adc_probe(struct platform_device *pdev) { struct exynos_adc *info = NULL; + struct device *dev = &pdev->dev; struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev = NULL; int ret; int irq; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct exynos_adc)); + indio_dev = devm_iio_device_alloc(dev, sizeof(struct exynos_adc)); if (!indio_dev) return -ENOMEM; info = iio_priv(indio_dev); info->data = exynos_adc_get_data(pdev); - if (!info->data) { - dev_err(&pdev->dev, "failed getting exynos_adc_data\n"); - return -EINVAL; - } + if (!info->data) + return dev_err_probe(dev, -EINVAL, "failed getting exynos_adc_data\n"); info->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(info->regs)) @@ -566,44 +565,34 @@ static int exynos_adc_probe(struct platform_device *pdev) if (info->data->needs_adc_phy) { - info->pmu_map = syscon_regmap_lookup_by_phandle( - pdev->dev.of_node, - "samsung,syscon-phandle"); - if (IS_ERR(info->pmu_map)) { - dev_err(&pdev->dev, "syscon regmap lookup failed.\n"); - return PTR_ERR(info->pmu_map); - } + info->pmu_map = syscon_regmap_lookup_by_phandle(np, "samsung,syscon-phandle"); + if (IS_ERR(info->pmu_map)) + return dev_err_probe(dev, PTR_ERR(info->pmu_map), + "syscon regmap lookup failed.\n"); } irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; info->irq = irq; - info->dev = &pdev->dev; + info->dev = dev; init_completion(&info->completion); - info->clk = devm_clk_get(&pdev->dev, "adc"); - if (IS_ERR(info->clk)) { - dev_err(&pdev->dev, "failed getting clock, err = %ld\n", - PTR_ERR(info->clk)); - return PTR_ERR(info->clk); - } + info->clk = devm_clk_get(dev, "adc"); + if (IS_ERR(info->clk)) + return dev_err_probe(dev, PTR_ERR(info->clk), "failed getting clock\n"); if (info->data->needs_sclk) { - info->sclk = devm_clk_get(&pdev->dev, "sclk"); - if (IS_ERR(info->sclk)) { - dev_err(&pdev->dev, - "failed getting sclk clock, err = %ld\n", - PTR_ERR(info->sclk)); - return PTR_ERR(info->sclk); - } + info->sclk = devm_clk_get(dev, "sclk"); + if (IS_ERR(info->sclk)) + return dev_err_probe(dev, PTR_ERR(info->sclk), + "failed getting sclk clock\n"); } - info->vdd = devm_regulator_get(&pdev->dev, "vdd"); + info->vdd = devm_regulator_get(dev, "vdd"); if (IS_ERR(info->vdd)) - return dev_err_probe(&pdev->dev, PTR_ERR(info->vdd), - "failed getting regulator"); + return dev_err_probe(dev, PTR_ERR(info->vdd), "failed getting regulator"); ret = regulator_enable(info->vdd); if (ret) @@ -619,7 +608,7 @@ static int exynos_adc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, indio_dev); - indio_dev->name = dev_name(&pdev->dev); + indio_dev->name = dev_name(dev); indio_dev->info = &exynos_adc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = exynos_adc_iio_channels; @@ -627,11 +616,9 @@ static int exynos_adc_probe(struct platform_device *pdev) mutex_init(&info->lock); - ret = request_irq(info->irq, exynos_adc_isr, - 0, dev_name(&pdev->dev), info); + ret = request_irq(info->irq, exynos_adc_isr, 0, dev_name(dev), info); if (ret < 0) { - dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", - info->irq); + dev_err(dev, "failed requesting irq, irq = %d\n", info->irq); goto err_disable_clk; } @@ -644,7 +631,7 @@ static int exynos_adc_probe(struct platform_device *pdev) ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev); if (ret < 0) { - dev_err(&pdev->dev, "failed adding child nodes\n"); + dev_err(dev, "failed adding child nodes\n"); goto err_of_populate; } diff --git a/drivers/iio/adc/mcp3911.c b/drivers/iio/adc/mcp3911.c index a6f21791c685..ddc3721f3f68 100644 --- a/drivers/iio/adc/mcp3911.c +++ b/drivers/iio/adc/mcp3911.c @@ -815,7 +815,7 @@ static int mcp3911_probe(struct spi_device *spi) * don't enable the interrupt to avoid extra load on the system. */ ret = devm_request_irq(dev, spi->irq, &iio_trigger_generic_data_rdy_poll, - IRQF_NO_AUTOEN | IRQF_ONESHOT, + IRQF_NO_AUTOEN | IRQF_NO_THREAD, indio_dev->name, adc->trig); if (ret) return ret; diff --git a/drivers/iio/adc/men_z188_adc.c b/drivers/iio/adc/men_z188_adc.c index cf8a8c0412ec..90919d282e7b 100644 --- a/drivers/iio/adc/men_z188_adc.c +++ b/drivers/iio/adc/men_z188_adc.c @@ -171,5 +171,4 @@ module_mcb_driver(men_z188_driver); MODULE_AUTHOR("Johannes Thumshirn "); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core"); -MODULE_ALIAS("mcb:16z188"); MODULE_IMPORT_NS("MCB"); diff --git a/drivers/iio/adc/nxp-sar-adc.c b/drivers/iio/adc/nxp-sar-adc.c new file mode 100644 index 000000000000..9efa883c277d --- /dev/null +++ b/drivers/iio/adc/nxp-sar-adc.c @@ -0,0 +1,1016 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * NXP SAR-ADC driver (adapted from Freescale Vybrid vf610 ADC driver + * by Fugang Duan ) + * + * Copyright 2013 Freescale Semiconductor, Inc. + * Copyright 2017, 2020-2025 NXP + * Copyright 2025, Linaro Ltd + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* SAR ADC registers. */ +#define NXP_SAR_ADC_CDR(__base, __channel) (((__base) + 0x100) + ((__channel) * 0x4)) + +#define NXP_SAR_ADC_CDR_CDATA_MASK GENMASK(11, 0) +#define NXP_SAR_ADC_CDR_VALID BIT(19) + +/* Main Configuration Register */ +#define NXP_SAR_ADC_MCR(__base) ((__base) + 0x00) + +#define NXP_SAR_ADC_MCR_PWDN BIT(0) +#define NXP_SAR_ADC_MCR_ACKO BIT(5) +#define NXP_SAR_ADC_MCR_ADCLKSEL BIT(8) +#define NXP_SAR_ADC_MCR_TSAMP_MASK GENMASK(10, 9) +#define NXP_SAR_ADC_MCR_NRSMPL_MASK GENMASK(12, 11) +#define NXP_SAR_ADC_MCR_AVGEN BIT(13) +#define NXP_SAR_ADC_MCR_CALSTART BIT(14) +#define NXP_SAR_ADC_MCR_NSTART BIT(24) +#define NXP_SAR_ADC_MCR_MODE BIT(29) +#define NXP_SAR_ADC_MCR_OWREN BIT(31) + +/* Main Status Register */ +#define NXP_SAR_ADC_MSR(__base) ((__base) + 0x04) + +#define NXP_SAR_ADC_MSR_CALBUSY BIT(29) +#define NXP_SAR_ADC_MSR_CALFAIL BIT(30) + +/* Interrupt Status Register */ +#define NXP_SAR_ADC_ISR(__base) ((__base) + 0x10) + +#define NXP_SAR_ADC_ISR_ECH BIT(0) + +/* Channel Pending Register */ +#define NXP_SAR_ADC_CEOCFR0(__base) ((__base) + 0x14) +#define NXP_SAR_ADC_CEOCFR1(__base) ((__base) + 0x18) + +#define NXP_SAR_ADC_EOC_CH(c) BIT(c) + +/* Interrupt Mask Register */ +#define NXP_SAR_ADC_IMR(__base) ((__base) + 0x20) + +/* Channel Interrupt Mask Register */ +#define NXP_SAR_ADC_CIMR0(__base) ((__base) + 0x24) +#define NXP_SAR_ADC_CIMR1(__base) ((__base) + 0x28) + +/* DMA Setting Register */ +#define NXP_SAR_ADC_DMAE(__base) ((__base) + 0x40) + +#define NXP_SAR_ADC_DMAE_DMAEN BIT(0) +#define NXP_SAR_ADC_DMAE_DCLR BIT(1) + +/* DMA Control register */ +#define NXP_SAR_ADC_DMAR0(__base) ((__base) + 0x44) +#define NXP_SAR_ADC_DMAR1(__base) ((__base) + 0x48) + +/* Conversion Timing Register */ +#define NXP_SAR_ADC_CTR0(__base) ((__base) + 0x94) +#define NXP_SAR_ADC_CTR1(__base) ((__base) + 0x98) + +#define NXP_SAR_ADC_CTR_INPSAMP_MIN 0x08 +#define NXP_SAR_ADC_CTR_INPSAMP_MAX 0xff + +/* Normal Conversion Mask Register */ +#define NXP_SAR_ADC_NCMR0(__base) ((__base) + 0xa4) +#define NXP_SAR_ADC_NCMR1(__base) ((__base) + 0xa8) + +/* Normal Conversion Mask Register field define */ +#define NXP_SAR_ADC_CH_MASK GENMASK(7, 0) + +/* Other field define */ +#define NXP_SAR_ADC_CONV_TIMEOUT (msecs_to_jiffies(100)) +#define NXP_SAR_ADC_CAL_TIMEOUT_US (100 * USEC_PER_MSEC) +#define NXP_SAR_ADC_WAIT_US (2 * USEC_PER_MSEC) +#define NXP_SAR_ADC_RESOLUTION 12 + +/* Duration of conversion phases */ +#define NXP_SAR_ADC_TPT 2 +#define NXP_SAR_ADC_DP 2 +#define NXP_SAR_ADC_CT ((NXP_SAR_ADC_RESOLUTION + 2) * 4) +#define NXP_SAR_ADC_CONV_TIME (NXP_SAR_ADC_TPT + NXP_SAR_ADC_CT + NXP_SAR_ADC_DP) + +#define NXP_SAR_ADC_NR_CHANNELS 8 + +#define NXP_PAGE_SIZE SZ_4K +#define NXP_SAR_ADC_DMA_SAMPLE_SZ DMA_SLAVE_BUSWIDTH_4_BYTES +#define NXP_SAR_ADC_DMA_BUFF_SZ (NXP_PAGE_SIZE * NXP_SAR_ADC_DMA_SAMPLE_SZ) +#define NXP_SAR_ADC_DMA_SAMPLE_CNT (NXP_SAR_ADC_DMA_BUFF_SZ / NXP_SAR_ADC_DMA_SAMPLE_SZ) + +struct nxp_sar_adc { + void __iomem *regs; + phys_addr_t regs_phys; + u8 current_channel; + u8 channels_used; + u16 value; + u32 vref_mV; + + /* Save and restore context. */ + u32 inpsamp; + u32 pwdn; + + struct clk *clk; + struct dma_chan *dma_chan; + struct completion completion; + struct circ_buf dma_buf; + + dma_addr_t rx_dma_buf; + dma_cookie_t cookie; + + /* Protect circular buffers access. */ + spinlock_t lock; + + /* Array of enabled channels. */ + u16 buffered_chan[NXP_SAR_ADC_NR_CHANNELS]; + + /* Buffer to be filled by the DMA. */ + IIO_DECLARE_BUFFER_WITH_TS(u16, buffer, NXP_SAR_ADC_NR_CHANNELS); +}; + +struct nxp_sar_adc_data { + u32 vref_mV; + const char *model; +}; + +#define ADC_CHAN(_idx, _chan_type) { \ + .type = (_chan_type), \ + .indexed = 1, \ + .channel = (_idx), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = (_idx), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = 12, \ + .storagebits = 16, \ + }, \ +} + +static const struct iio_chan_spec nxp_sar_adc_iio_channels[] = { + ADC_CHAN(0, IIO_VOLTAGE), + ADC_CHAN(1, IIO_VOLTAGE), + ADC_CHAN(2, IIO_VOLTAGE), + ADC_CHAN(3, IIO_VOLTAGE), + ADC_CHAN(4, IIO_VOLTAGE), + ADC_CHAN(5, IIO_VOLTAGE), + ADC_CHAN(6, IIO_VOLTAGE), + ADC_CHAN(7, IIO_VOLTAGE), + /* + * The NXP SAR ADC documentation marks the channels 8 to 31 as + * "Reserved". Reflect the same in the driver in case new ADC + * variants comes with more channels. + */ + IIO_CHAN_SOFT_TIMESTAMP(32), +}; + +static void nxp_sar_adc_irq_cfg(struct nxp_sar_adc *info, bool enable) +{ + if (enable) + writel(NXP_SAR_ADC_ISR_ECH, NXP_SAR_ADC_IMR(info->regs)); + else + writel(0, NXP_SAR_ADC_IMR(info->regs)); +} + +static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable) +{ + u32 mcr; + bool pwdn; + + mcr = readl(NXP_SAR_ADC_MCR(info->regs)); + + /* + * Get the current state and return it later. This is used for + * suspend/resume to get the power state + */ + pwdn = FIELD_GET(NXP_SAR_ADC_MCR_PWDN, mcr); + + /* When the enabled flag is not set, we set the power down bit */ + FIELD_MODIFY(NXP_SAR_ADC_MCR_PWDN, &mcr, !enable); + + writel(mcr, NXP_SAR_ADC_MCR(info->regs)); + + /* + * Ensure there are at least three cycles between the + * configuration of NCMR and the setting of NSTART. + */ + if (enable) + ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk) * 3)); + + return pwdn; +} + +static inline bool nxp_sar_adc_enable(struct nxp_sar_adc *info) +{ + return nxp_sar_adc_set_enabled(info, true); +} + +static inline bool nxp_sar_adc_disable(struct nxp_sar_adc *info) +{ + return nxp_sar_adc_set_enabled(info, false); +} + +static inline void nxp_sar_adc_calibration_start(void __iomem *base) +{ + u32 mcr = readl(NXP_SAR_ADC_MCR(base)); + + FIELD_MODIFY(NXP_SAR_ADC_MCR_CALSTART, &mcr, 0x1); + + writel(mcr, NXP_SAR_ADC_MCR(base)); +} + +static inline int nxp_sar_adc_calibration_wait(void __iomem *base) +{ + u32 msr, ret; + + ret = readl_poll_timeout(NXP_SAR_ADC_MSR(base), msr, + !FIELD_GET(NXP_SAR_ADC_MSR_CALBUSY, msr), + NXP_SAR_ADC_WAIT_US, + NXP_SAR_ADC_CAL_TIMEOUT_US); + if (ret) + return ret; + + if (FIELD_GET(NXP_SAR_ADC_MSR_CALFAIL, msr)) { + /* + * If the calibration fails, the status register bit must be + * cleared. + */ + FIELD_MODIFY(NXP_SAR_ADC_MSR_CALFAIL, &msr, 0x0); + writel(msr, NXP_SAR_ADC_MSR(base)); + + return -EAGAIN; + } + + return 0; +} + +static int nxp_sar_adc_calibration(struct nxp_sar_adc *info) +{ + int ret; + + /* Calibration works only if the ADC is powered up. */ + nxp_sar_adc_enable(info); + + /* The calibration operation starts. */ + nxp_sar_adc_calibration_start(info->regs); + + ret = nxp_sar_adc_calibration_wait(info->regs); + + /* + * Calibration works only if the ADC is powered up. However + * the calibration is called from the probe function where the + * iio is not enabled, so we disable after the calibration. + */ + nxp_sar_adc_disable(info); + + return ret; +} + +static void nxp_sar_adc_conversion_timing_set(struct nxp_sar_adc *info, u32 inpsamp) +{ + inpsamp = clamp(inpsamp, NXP_SAR_ADC_CTR_INPSAMP_MIN, NXP_SAR_ADC_CTR_INPSAMP_MAX); + + writel(inpsamp, NXP_SAR_ADC_CTR0(info->regs)); +} + +static u32 nxp_sar_adc_conversion_timing_get(struct nxp_sar_adc *info) +{ + return readl(NXP_SAR_ADC_CTR0(info->regs)); +} + +static void nxp_sar_adc_read_notify(struct nxp_sar_adc *info) +{ + writel(NXP_SAR_ADC_CH_MASK, NXP_SAR_ADC_CEOCFR0(info->regs)); + writel(NXP_SAR_ADC_CH_MASK, NXP_SAR_ADC_CEOCFR1(info->regs)); +} + +static int nxp_sar_adc_read_data(struct nxp_sar_adc *info, unsigned int chan) +{ + u32 ceocfr, cdr; + + ceocfr = readl(NXP_SAR_ADC_CEOCFR0(info->regs)); + + /* + * FIELD_GET() can not be used here because EOC_CH is not constant. + * TODO: Switch to field_get() when it will be available. + */ + if (!(NXP_SAR_ADC_EOC_CH(chan) & ceocfr)) + return -EIO; + + cdr = readl(NXP_SAR_ADC_CDR(info->regs, chan)); + if (!(FIELD_GET(NXP_SAR_ADC_CDR_VALID, cdr))) + return -EIO; + + return FIELD_GET(NXP_SAR_ADC_CDR_CDATA_MASK, cdr); +} + +static void nxp_sar_adc_isr_buffer(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + unsigned int i; + int ret; + + for (i = 0; i < info->channels_used; i++) { + ret = nxp_sar_adc_read_data(info, info->buffered_chan[i]); + if (ret < 0) { + nxp_sar_adc_read_notify(info); + return; + } + + info->buffer[i] = ret; + } + + nxp_sar_adc_read_notify(info); + + iio_push_to_buffers_with_ts(indio_dev, info->buffer, sizeof(info->buffer), + iio_get_time_ns(indio_dev)); + + iio_trigger_notify_done(indio_dev->trig); +} + +static void nxp_sar_adc_isr_read_raw(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + int ret; + + ret = nxp_sar_adc_read_data(info, info->current_channel); + nxp_sar_adc_read_notify(info); + if (ret < 0) + return; + + info->value = ret; + complete(&info->completion); +} + +static irqreturn_t nxp_sar_adc_isr(int irq, void *dev_id) +{ + struct iio_dev *indio_dev = dev_id; + struct nxp_sar_adc *info = iio_priv(indio_dev); + int isr; + + isr = readl(NXP_SAR_ADC_ISR(info->regs)); + if (!(FIELD_GET(NXP_SAR_ADC_ISR_ECH, isr))) + return IRQ_NONE; + + if (iio_buffer_enabled(indio_dev)) + nxp_sar_adc_isr_buffer(indio_dev); + else + nxp_sar_adc_isr_read_raw(indio_dev); + + writel(NXP_SAR_ADC_ISR_ECH, NXP_SAR_ADC_ISR(info->regs)); + + return IRQ_HANDLED; +} + +static void nxp_sar_adc_channels_disable(struct nxp_sar_adc *info, u32 mask) +{ + u32 ncmr, cimr; + + ncmr = readl(NXP_SAR_ADC_NCMR0(info->regs)); + cimr = readl(NXP_SAR_ADC_CIMR0(info->regs)); + + /* FIELD_MODIFY() can not be used because the mask is not constant */ + ncmr &= ~mask; + cimr &= ~mask; + + writel(ncmr, NXP_SAR_ADC_NCMR0(info->regs)); + writel(cimr, NXP_SAR_ADC_CIMR0(info->regs)); +} + +static void nxp_sar_adc_channels_enable(struct nxp_sar_adc *info, u32 mask) +{ + u32 ncmr, cimr; + + ncmr = readl(NXP_SAR_ADC_NCMR0(info->regs)); + cimr = readl(NXP_SAR_ADC_CIMR0(info->regs)); + + ncmr |= mask; + cimr |= mask; + + writel(ncmr, NXP_SAR_ADC_NCMR0(info->regs)); + writel(cimr, NXP_SAR_ADC_CIMR0(info->regs)); +} + +static void nxp_sar_adc_dma_channels_enable(struct nxp_sar_adc *info, u32 mask) +{ + u32 dmar; + + dmar = readl(NXP_SAR_ADC_DMAR0(info->regs)); + + dmar |= mask; + + writel(dmar, NXP_SAR_ADC_DMAR0(info->regs)); +} + +static void nxp_sar_adc_dma_channels_disable(struct nxp_sar_adc *info, u32 mask) +{ + u32 dmar; + + dmar = readl(NXP_SAR_ADC_DMAR0(info->regs)); + + dmar &= ~mask; + + writel(dmar, NXP_SAR_ADC_DMAR0(info->regs)); +} + +static void nxp_sar_adc_dma_cfg(struct nxp_sar_adc *info, bool enable) +{ + u32 dmae; + + dmae = readl(NXP_SAR_ADC_DMAE(info->regs)); + + FIELD_MODIFY(NXP_SAR_ADC_DMAE_DMAEN, &dmae, enable); + + writel(dmae, NXP_SAR_ADC_DMAE(info->regs)); +} + +static void nxp_sar_adc_stop_conversion(struct nxp_sar_adc *info) +{ + u32 mcr; + + mcr = readl(NXP_SAR_ADC_MCR(info->regs)); + + FIELD_MODIFY(NXP_SAR_ADC_MCR_NSTART, &mcr, 0x0); + + writel(mcr, NXP_SAR_ADC_MCR(info->regs)); + + /* + * On disable, we have to wait for the transaction to finish. + * ADC does not abort the transaction if a chain conversion is + * in progress. Wait for the worst case scenario - 80 ADC clk + * cycles. The clock rate is 80MHz, this routine is called + * only when the capture finishes. The delay will be very + * short, usec-ish, which is acceptable in the atomic context. + */ + ndelay(div64_u64(NSEC_PER_SEC, clk_get_rate(info->clk)) * 80); +} + +static int nxp_sar_adc_start_conversion(struct nxp_sar_adc *info, bool raw) +{ + u32 mcr; + + mcr = readl(NXP_SAR_ADC_MCR(info->regs)); + + FIELD_MODIFY(NXP_SAR_ADC_MCR_NSTART, &mcr, 0x1); + FIELD_MODIFY(NXP_SAR_ADC_MCR_MODE, &mcr, raw ? 0 : 1); + + writel(mcr, NXP_SAR_ADC_MCR(info->regs)); + + return 0; +} + +static int nxp_sar_adc_read_channel(struct nxp_sar_adc *info, int channel) +{ + int ret; + + info->current_channel = channel; + nxp_sar_adc_channels_enable(info, BIT(channel)); + nxp_sar_adc_irq_cfg(info, true); + nxp_sar_adc_enable(info); + + reinit_completion(&info->completion); + ret = nxp_sar_adc_start_conversion(info, true); + if (ret < 0) + goto out_disable; + + if (!wait_for_completion_interruptible_timeout(&info->completion, + NXP_SAR_ADC_CONV_TIMEOUT)) + ret = -ETIMEDOUT; + + nxp_sar_adc_stop_conversion(info); + +out_disable: + nxp_sar_adc_channels_disable(info, BIT(channel)); + nxp_sar_adc_irq_cfg(info, false); + nxp_sar_adc_disable(info); + + return ret; +} + +static int nxp_sar_adc_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + u32 inpsamp; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + + ret = nxp_sar_adc_read_channel(info, chan->channel); + + iio_device_release_direct(indio_dev); + + if (ret) + return ret; + + *val = info->value; + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + *val = info->vref_mV; + *val2 = NXP_SAR_ADC_RESOLUTION; + return IIO_VAL_FRACTIONAL_LOG2; + + case IIO_CHAN_INFO_SAMP_FREQ: + inpsamp = nxp_sar_adc_conversion_timing_get(info); + *val = clk_get_rate(info->clk) / (inpsamp + NXP_SAR_ADC_CONV_TIME); + return IIO_VAL_INT; + + default: + return -EINVAL; + } +} + +static int nxp_sar_adc_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + u32 inpsamp; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + /* + * Configures the sample period duration in terms of the SAR + * controller clock. The minimum acceptable value is 8. + * Configuring it to a value lower than 8 sets the sample period + * to 8 cycles. We read the clock value and divide by the + * sampling timing which gives us the number of cycles expected. + * The value is 8-bit wide, consequently the max value is 0xFF. + */ + inpsamp = clk_get_rate(info->clk) / val - NXP_SAR_ADC_CONV_TIME; + nxp_sar_adc_conversion_timing_set(info, inpsamp); + return 0; + + default: + return -EINVAL; + } +} + +static void nxp_sar_adc_dma_cb(void *data) +{ + struct iio_dev *indio_dev = data; + struct nxp_sar_adc *info = iio_priv(indio_dev); + struct dma_tx_state state; + struct circ_buf *dma_buf; + struct device *dev_dma; + u32 *dma_samples; + s64 timestamp; + int idx, ret; + + guard(spinlock_irqsave)(&info->lock); + + dma_buf = &info->dma_buf; + dma_samples = (u32 *)dma_buf->buf; + dev_dma = info->dma_chan->device->dev; + + /* + * DMA in some corner cases might have already be charged for + * the next transfer. Potentially there can be a race where + * the residue changes while the dma engine updates the + * buffer. That could be handled by using the + * callback_result() instead of callback() because the residue + * will be passed as a parameter to the function. However this + * new callback is pretty new and the backend does not update + * the residue. So let's stick to the version other drivers do + * which has proven running well in production since several + * years. + */ + dmaengine_tx_status(info->dma_chan, info->cookie, &state); + + dma_sync_single_for_cpu(dev_dma, info->rx_dma_buf, + NXP_SAR_ADC_DMA_BUFF_SZ, DMA_FROM_DEVICE); + + /* Current head position. */ + dma_buf->head = (NXP_SAR_ADC_DMA_BUFF_SZ - state.residue) / + NXP_SAR_ADC_DMA_SAMPLE_SZ; + + /* If everything was transferred, avoid an off by one error. */ + if (!state.residue) + dma_buf->head--; + + /* Something went wrong and nothing transferred. */ + if (state.residue != NXP_SAR_ADC_DMA_BUFF_SZ) { + /* Make sure that head is multiple of info->channels_used. */ + dma_buf->head -= dma_buf->head % info->channels_used; + + /* + * dma_buf->tail != dma_buf->head condition will become false + * because dma_buf->tail will be incremented with 1. + */ + while (dma_buf->tail != dma_buf->head) { + idx = dma_buf->tail % info->channels_used; + info->buffer[idx] = dma_samples[dma_buf->tail]; + dma_buf->tail = (dma_buf->tail + 1) % NXP_SAR_ADC_DMA_SAMPLE_CNT; + if (idx != info->channels_used - 1) + continue; + + /* + * iio_push_to_buffers_with_ts() should not be + * called with dma_samples as parameter. The samples + * will be smashed if timestamp is enabled. + */ + timestamp = iio_get_time_ns(indio_dev); + ret = iio_push_to_buffers_with_ts(indio_dev, info->buffer, + sizeof(info->buffer), + timestamp); + if (ret < 0 && ret != -EBUSY) + dev_err_ratelimited(&indio_dev->dev, + "failed to push iio buffer: %d", + ret); + } + + dma_buf->tail = dma_buf->head; + } + + dma_sync_single_for_device(dev_dma, info->rx_dma_buf, + NXP_SAR_ADC_DMA_BUFF_SZ, DMA_FROM_DEVICE); +} + +static int nxp_sar_adc_start_cyclic_dma(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + struct dma_slave_config config; + struct dma_async_tx_descriptor *desc; + int ret; + + info->dma_buf.head = 0; + info->dma_buf.tail = 0; + + config.direction = DMA_DEV_TO_MEM; + config.src_addr_width = NXP_SAR_ADC_DMA_SAMPLE_SZ; + config.src_addr = NXP_SAR_ADC_CDR(info->regs_phys, info->buffered_chan[0]); + config.src_port_window_size = info->channels_used; + config.src_maxburst = info->channels_used; + ret = dmaengine_slave_config(info->dma_chan, &config); + if (ret < 0) + return ret; + + desc = dmaengine_prep_dma_cyclic(info->dma_chan, + info->rx_dma_buf, + NXP_SAR_ADC_DMA_BUFF_SZ, + NXP_SAR_ADC_DMA_BUFF_SZ / 2, + DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); + if (!desc) + return -EINVAL; + + desc->callback = nxp_sar_adc_dma_cb; + desc->callback_param = indio_dev; + info->cookie = dmaengine_submit(desc); + ret = dma_submit_error(info->cookie); + if (ret) { + dmaengine_terminate_async(info->dma_chan); + return ret; + } + + dma_async_issue_pending(info->dma_chan); + + return 0; +} + +static void nxp_sar_adc_buffer_software_do_predisable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + + /* + * The ADC DMAEN bit should be cleared before DMA transaction + * is canceled. + */ + nxp_sar_adc_stop_conversion(info); + dmaengine_terminate_sync(info->dma_chan); + nxp_sar_adc_dma_cfg(info, false); + nxp_sar_adc_dma_channels_disable(info, *indio_dev->active_scan_mask); + + dma_release_channel(info->dma_chan); +} + +static int nxp_sar_adc_buffer_software_do_postenable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + int ret; + + nxp_sar_adc_dma_channels_enable(info, *indio_dev->active_scan_mask); + + nxp_sar_adc_dma_cfg(info, true); + + ret = nxp_sar_adc_start_cyclic_dma(indio_dev); + if (ret) + goto out_dma_channels_disable; + + ret = nxp_sar_adc_start_conversion(info, false); + if (ret) + goto out_stop_cyclic_dma; + + return 0; + +out_stop_cyclic_dma: + dmaengine_terminate_sync(info->dma_chan); + +out_dma_channels_disable: + nxp_sar_adc_dma_cfg(info, false); + nxp_sar_adc_dma_channels_disable(info, *indio_dev->active_scan_mask); + + return ret; +} + +static void nxp_sar_adc_buffer_trigger_do_predisable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + + nxp_sar_adc_irq_cfg(info, false); +} + +static int nxp_sar_adc_buffer_trigger_do_postenable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + + nxp_sar_adc_irq_cfg(info, true); + + return 0; +} + +static int nxp_sar_adc_buffer_postenable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + int current_mode = iio_device_get_current_mode(indio_dev); + unsigned long channel; + int ret; + + info->dma_chan = dma_request_chan(indio_dev->dev.parent, "rx"); + if (IS_ERR(info->dma_chan)) + return PTR_ERR(info->dma_chan); + + info->channels_used = 0; + + /* + * The SAR-ADC has two groups of channels. + * + * - Group #0: + * * bit 0-7 : channel 0 -> channel 7 + * * bit 8-31 : reserved + * + * - Group #32: + * * bit 0-7 : Internal + * * bit 8-31 : reserved + * + * The 8 channels from group #0 are used in this driver for + * ADC as described when declaring the IIO device and the + * mapping is the same. That means the active_scan_mask can be + * used directly to write the channel interrupt mask. + */ + nxp_sar_adc_channels_enable(info, *indio_dev->active_scan_mask); + + for_each_set_bit(channel, indio_dev->active_scan_mask, NXP_SAR_ADC_NR_CHANNELS) + info->buffered_chan[info->channels_used++] = channel; + + nxp_sar_adc_enable(info); + + if (current_mode == INDIO_BUFFER_SOFTWARE) + ret = nxp_sar_adc_buffer_software_do_postenable(indio_dev); + else + ret = nxp_sar_adc_buffer_trigger_do_postenable(indio_dev); + if (ret) + goto out_postenable; + + return 0; + +out_postenable: + nxp_sar_adc_disable(info); + nxp_sar_adc_channels_disable(info, *indio_dev->active_scan_mask); + + return ret; +} + +static int nxp_sar_adc_buffer_predisable(struct iio_dev *indio_dev) +{ + struct nxp_sar_adc *info = iio_priv(indio_dev); + int currentmode = iio_device_get_current_mode(indio_dev); + + if (currentmode == INDIO_BUFFER_SOFTWARE) + nxp_sar_adc_buffer_software_do_predisable(indio_dev); + else + nxp_sar_adc_buffer_trigger_do_predisable(indio_dev); + + nxp_sar_adc_disable(info); + + nxp_sar_adc_channels_disable(info, *indio_dev->active_scan_mask); + + return 0; +} + +static irqreturn_t nxp_sar_adc_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct nxp_sar_adc *info = iio_priv(indio_dev); + int ret; + + ret = nxp_sar_adc_start_conversion(info, true); + if (ret < 0) + dev_dbg(&indio_dev->dev, "Failed to start conversion\n"); + + return IRQ_HANDLED; +} + +static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = { + .postenable = nxp_sar_adc_buffer_postenable, + .predisable = nxp_sar_adc_buffer_predisable, +}; + +static const struct iio_info nxp_sar_adc_iio_info = { + .read_raw = nxp_sar_adc_read_raw, + .write_raw = nxp_sar_adc_write_raw, +}; + +static int nxp_sar_adc_dma_probe(struct device *dev, struct nxp_sar_adc *info) +{ + u8 *rx_buf; + + rx_buf = dmam_alloc_coherent(dev, NXP_SAR_ADC_DMA_BUFF_SZ, + &info->rx_dma_buf, GFP_KERNEL); + if (!rx_buf) + return -ENOMEM; + + info->dma_buf.buf = rx_buf; + + return 0; +} + +/* + * The documentation describes the reset values for the registers. + * However some registers do not have these values after a reset. It + * is not a desirable situation. In some other SoC family + * documentation NXP recommends not assuming the default values are + * set and to initialize the registers conforming to the documentation + * reset information to prevent this situation. Assume the same rule + * applies here as there is a discrepancy between what is read from + * the registers at reset time and the documentation. + */ +static void nxp_sar_adc_set_default_values(struct nxp_sar_adc *info) +{ + writel(0x00003901, NXP_SAR_ADC_MCR(info->regs)); + writel(0x00000001, NXP_SAR_ADC_MSR(info->regs)); + writel(0x00000014, NXP_SAR_ADC_CTR0(info->regs)); + writel(0x00000014, NXP_SAR_ADC_CTR1(info->regs)); + writel(0x00000000, NXP_SAR_ADC_CIMR0(info->regs)); + writel(0x00000000, NXP_SAR_ADC_CIMR1(info->regs)); + writel(0x00000000, NXP_SAR_ADC_NCMR0(info->regs)); + writel(0x00000000, NXP_SAR_ADC_NCMR1(info->regs)); +} + +static int nxp_sar_adc_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const struct nxp_sar_adc_data *data = device_get_match_data(dev); + struct nxp_sar_adc *info; + struct iio_dev *indio_dev; + struct resource *mem; + int irq, ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); + if (!indio_dev) + return -ENOMEM; + + info = iio_priv(indio_dev); + info->vref_mV = data->vref_mV; + spin_lock_init(&info->lock); + info->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); + if (IS_ERR(info->regs)) + return dev_err_probe(dev, PTR_ERR(info->regs), + "Failed to get and remap resource"); + + info->regs_phys = mem->start; + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret = devm_request_irq(dev, irq, nxp_sar_adc_isr, 0, dev_name(dev), + indio_dev); + if (ret < 0) + return ret; + + info->clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(info->clk)) + return dev_err_probe(dev, PTR_ERR(info->clk), + "Failed to get the clock\n"); + + platform_set_drvdata(pdev, indio_dev); + + init_completion(&info->completion); + + indio_dev->name = data->model; + indio_dev->info = &nxp_sar_adc_iio_info; + indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; + indio_dev->channels = nxp_sar_adc_iio_channels; + indio_dev->num_channels = ARRAY_SIZE(nxp_sar_adc_iio_channels); + + nxp_sar_adc_set_default_values(info); + + ret = nxp_sar_adc_calibration(info); + if (ret) + dev_err_probe(dev, ret, "Calibration failed\n"); + + ret = nxp_sar_adc_dma_probe(dev, info); + if (ret) + return dev_err_probe(dev, ret, "Failed to initialize the DMA\n"); + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + &iio_pollfunc_store_time, + &nxp_sar_adc_trigger_handler, + &iio_triggered_buffer_setup_ops); + if (ret < 0) + return dev_err_probe(dev, ret, "Couldn't initialise the buffer\n"); + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "Couldn't register the device\n"); + + return 0; +} + +static int nxp_sar_adc_suspend(struct device *dev) +{ + struct nxp_sar_adc *info = iio_priv(dev_get_drvdata(dev)); + + info->pwdn = nxp_sar_adc_disable(info); + info->inpsamp = nxp_sar_adc_conversion_timing_get(info); + + clk_disable_unprepare(info->clk); + + return 0; +} + +static int nxp_sar_adc_resume(struct device *dev) +{ + struct nxp_sar_adc *info = iio_priv(dev_get_drvdata(dev)); + int ret; + + ret = clk_prepare_enable(info->clk); + if (ret) + return ret; + + nxp_sar_adc_conversion_timing_set(info, info->inpsamp); + + if (!info->pwdn) + nxp_sar_adc_enable(info); + + return 0; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(nxp_sar_adc_pm_ops, nxp_sar_adc_suspend, + nxp_sar_adc_resume); + +static const struct nxp_sar_adc_data s32g2_sar_adc_data = { + .vref_mV = 1800, + .model = "s32g2-sar-adc", +}; + +static const struct of_device_id nxp_sar_adc_match[] = { + { .compatible = "nxp,s32g2-sar-adc", .data = &s32g2_sar_adc_data }, + { } +}; +MODULE_DEVICE_TABLE(of, nxp_sar_adc_match); + +static struct platform_driver nxp_sar_adc_driver = { + .probe = nxp_sar_adc_probe, + .driver = { + .name = "nxp-sar-adc", + .of_match_table = nxp_sar_adc_match, + .pm = pm_sleep_ptr(&nxp_sar_adc_pm_ops), + }, +}; +module_platform_driver(nxp_sar_adc_driver); + +MODULE_AUTHOR("NXP"); +MODULE_DESCRIPTION("NXP SAR-ADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/qcom-spmi-rradc.c b/drivers/iio/adc/qcom-spmi-rradc.c index b245416bae12..8e75665204d1 100644 --- a/drivers/iio/adc/qcom-spmi-rradc.c +++ b/drivers/iio/adc/qcom-spmi-rradc.c @@ -934,20 +934,15 @@ static int rradc_probe(struct platform_device *pdev) chip = iio_priv(indio_dev); chip->regmap = dev_get_regmap(pdev->dev.parent, NULL); - if (!chip->regmap) { - dev_err(dev, "Couldn't get parent's regmap\n"); - return -EINVAL; - } + if (!chip->regmap) + return dev_err_probe(dev, -EINVAL, "Couldn't get parent's regmap\n"); chip->dev = dev; mutex_init(&chip->conversion_lock); ret = device_property_read_u32(dev, "reg", &chip->base); - if (ret < 0) { - dev_err(chip->dev, "Couldn't find reg address, ret = %d\n", - ret); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "Couldn't find reg address\n"); batt_id_delay = -1; ret = device_property_read_u32(dev, "qcom,batt-id-delay-ms", @@ -975,10 +970,9 @@ static int rradc_probe(struct platform_device *pdev) /* Get the PMIC revision, we need it to handle some varying coefficients */ chip->pmic = qcom_pmic_get(chip->dev); - if (IS_ERR(chip->pmic)) { - dev_err(chip->dev, "Unable to get reference to PMIC device\n"); - return PTR_ERR(chip->pmic); - } + if (IS_ERR(chip->pmic)) + return dev_err_probe(dev, PTR_ERR(chip->pmic), + "Unable to get reference to PMIC device\n"); switch (chip->pmic->subtype) { case PMI8998_SUBTYPE: diff --git a/drivers/iio/adc/rockchip_saradc.c b/drivers/iio/adc/rockchip_saradc.c index 6721da0ed7bb..0f0bf2906af0 100644 --- a/drivers/iio/adc/rockchip_saradc.c +++ b/drivers/iio/adc/rockchip_saradc.c @@ -456,6 +456,7 @@ static int rockchip_saradc_probe(struct platform_device *pdev) { const struct rockchip_saradc_data *match_data; struct rockchip_saradc *info = NULL; + struct device *dev = &pdev->dev; struct device_node *np = pdev->dev.of_node; struct iio_dev *indio_dev = NULL; int ret; @@ -464,23 +465,21 @@ static int rockchip_saradc_probe(struct platform_device *pdev) if (!np) return -ENODEV; - indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info)); + indio_dev = devm_iio_device_alloc(dev, sizeof(*info)); if (!indio_dev) return -ENOMEM; info = iio_priv(indio_dev); - match_data = of_device_get_match_data(&pdev->dev); + match_data = of_device_get_match_data(dev); if (!match_data) - return dev_err_probe(&pdev->dev, -ENODEV, - "failed to match device\n"); + return dev_err_probe(dev, -ENODEV, "failed to match device\n"); info->data = match_data; /* Sanity check for possible later IP variants with more channels */ if (info->data->num_channels > SARADC_MAX_CHANNELS) - return dev_err_probe(&pdev->dev, -EINVAL, - "max channels exceeded"); + return dev_err_probe(dev, -EINVAL, "max channels exceeded"); info->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(info->regs)) @@ -490,12 +489,10 @@ static int rockchip_saradc_probe(struct platform_device *pdev) * The reset should be an optional property, as it should work * with old devicetrees as well */ - info->reset = devm_reset_control_get_optional_exclusive(&pdev->dev, - "saradc-apb"); - if (IS_ERR(info->reset)) { - ret = PTR_ERR(info->reset); - return dev_err_probe(&pdev->dev, ret, "failed to get saradc-apb\n"); - } + info->reset = devm_reset_control_get_optional_exclusive(dev, "saradc-apb"); + if (IS_ERR(info->reset)) + return dev_err_probe(dev, PTR_ERR(info->reset), + "failed to get saradc-apb\n"); init_completion(&info->completion); @@ -503,16 +500,14 @@ static int rockchip_saradc_probe(struct platform_device *pdev) if (irq < 0) return irq; - ret = devm_request_irq(&pdev->dev, irq, rockchip_saradc_isr, + ret = devm_request_irq(dev, irq, rockchip_saradc_isr, 0, dev_name(&pdev->dev), info); - if (ret < 0) { - dev_err(&pdev->dev, "failed requesting irq %d\n", irq); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "failed requesting irq %d\n", irq); - info->vref = devm_regulator_get(&pdev->dev, "vref"); + info->vref = devm_regulator_get(dev, "vref"); if (IS_ERR(info->vref)) - return dev_err_probe(&pdev->dev, PTR_ERR(info->vref), + return dev_err_probe(dev, PTR_ERR(info->vref), "failed to get regulator\n"); if (info->reset) @@ -520,11 +515,9 @@ static int rockchip_saradc_probe(struct platform_device *pdev) ret = regulator_enable(info->vref); if (ret < 0) - return dev_err_probe(&pdev->dev, ret, - "failed to enable vref regulator\n"); + return dev_err_probe(dev, ret, "failed to enable vref regulator\n"); - ret = devm_add_action_or_reset(&pdev->dev, - rockchip_saradc_regulator_disable, info); + ret = devm_add_action_or_reset(dev, rockchip_saradc_regulator_disable, info); if (ret) return ret; @@ -534,14 +527,13 @@ static int rockchip_saradc_probe(struct platform_device *pdev) info->uv_vref = ret; - info->pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk"); + info->pclk = devm_clk_get_enabled(dev, "apb_pclk"); if (IS_ERR(info->pclk)) - return dev_err_probe(&pdev->dev, PTR_ERR(info->pclk), - "failed to get pclk\n"); + return dev_err_probe(dev, PTR_ERR(info->pclk), "failed to get pclk\n"); - info->clk = devm_clk_get_enabled(&pdev->dev, "saradc"); + info->clk = devm_clk_get_enabled(dev, "saradc"); if (IS_ERR(info->clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(info->clk), + return dev_err_probe(dev, PTR_ERR(info->clk), "failed to get adc clock\n"); /* * Use a default value for the converter clock. @@ -549,18 +541,17 @@ static int rockchip_saradc_probe(struct platform_device *pdev) */ ret = clk_set_rate(info->clk, info->data->clk_rate); if (ret < 0) - return dev_err_probe(&pdev->dev, ret, - "failed to set adc clk rate\n"); + return dev_err_probe(dev, ret, "failed to set adc clk rate\n"); platform_set_drvdata(pdev, indio_dev); - indio_dev->name = dev_name(&pdev->dev); + indio_dev->name = dev_name(dev); indio_dev->info = &rockchip_saradc_iio_info; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = info->data->channels; indio_dev->num_channels = info->data->num_channels; - ret = devm_iio_triggered_buffer_setup(&indio_dev->dev, indio_dev, NULL, + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, rockchip_saradc_trigger_handler, NULL); if (ret) @@ -571,7 +562,7 @@ static int rockchip_saradc_probe(struct platform_device *pdev) if (ret) return ret; - ret = devm_add_action_or_reset(&pdev->dev, + ret = devm_add_action_or_reset(dev, rockchip_saradc_regulator_unreg_notifier, info); if (ret) @@ -579,7 +570,7 @@ static int rockchip_saradc_probe(struct platform_device *pdev) mutex_init(&info->lock); - return devm_iio_device_register(&pdev->dev, indio_dev); + return devm_iio_device_register(dev, indio_dev); } static int rockchip_saradc_suspend(struct device *dev) diff --git a/drivers/iio/adc/sc27xx_adc.c b/drivers/iio/adc/sc27xx_adc.c index 2535c2c3e60b..6209499c5c37 100644 --- a/drivers/iio/adc/sc27xx_adc.c +++ b/drivers/iio/adc/sc27xx_adc.c @@ -867,10 +867,8 @@ static int sc27xx_adc_probe(struct platform_device *pdev) int ret; pdata = of_device_get_match_data(dev); - if (!pdata) { - dev_err(dev, "No matching driver data found\n"); - return -EINVAL; - } + if (!pdata) + return dev_err_probe(dev, -EINVAL, "No matching driver data found\n"); indio_dev = devm_iio_device_alloc(dev, sizeof(*sc27xx_data)); if (!indio_dev) @@ -879,56 +877,43 @@ static int sc27xx_adc_probe(struct platform_device *pdev) sc27xx_data = iio_priv(indio_dev); sc27xx_data->regmap = dev_get_regmap(dev->parent, NULL); - if (!sc27xx_data->regmap) { - dev_err(dev, "failed to get ADC regmap\n"); - return -ENODEV; - } + if (!sc27xx_data->regmap) + return dev_err_probe(dev, -ENODEV, "failed to get ADC regmap\n"); ret = of_property_read_u32(np, "reg", &sc27xx_data->base); - if (ret) { - dev_err(dev, "failed to get ADC base address\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to get ADC base address\n"); sc27xx_data->irq = platform_get_irq(pdev, 0); if (sc27xx_data->irq < 0) return sc27xx_data->irq; ret = of_hwspin_lock_get_id(np, 0); - if (ret < 0) { - dev_err(dev, "failed to get hwspinlock id\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get hwspinlock id\n"); sc27xx_data->hwlock = devm_hwspin_lock_request_specific(dev, ret); - if (!sc27xx_data->hwlock) { - dev_err(dev, "failed to request hwspinlock\n"); - return -ENXIO; - } + if (!sc27xx_data->hwlock) + return dev_err_probe(dev, -ENXIO, "failed to request hwspinlock\n"); sc27xx_data->dev = dev; if (pdata->set_volref) { sc27xx_data->volref = devm_regulator_get(dev, "vref"); - if (IS_ERR(sc27xx_data->volref)) { - ret = PTR_ERR(sc27xx_data->volref); - return dev_err_probe(dev, ret, "failed to get ADC volref\n"); - } + if (IS_ERR(sc27xx_data->volref)) + return dev_err_probe(dev, PTR_ERR(sc27xx_data->volref), + "failed to get ADC volref\n"); } sc27xx_data->var_data = pdata; sc27xx_data->var_data->init_scale(sc27xx_data); ret = sc27xx_adc_enable(sc27xx_data); - if (ret) { - dev_err(dev, "failed to enable ADC module\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to enable ADC module\n"); ret = devm_add_action_or_reset(dev, sc27xx_adc_disable, sc27xx_data); - if (ret) { - dev_err(dev, "failed to add ADC disable action\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to add ADC disable action\n"); indio_dev->name = dev_name(dev); indio_dev->modes = INDIO_DIRECT_MODE; diff --git a/drivers/iio/adc/ti-ads1018.c b/drivers/iio/adc/ti-ads1018.c new file mode 100644 index 000000000000..6246b3cab71f --- /dev/null +++ b/drivers/iio/adc/ti-ads1018.c @@ -0,0 +1,739 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Texas Instruments ADS1018 ADC driver + * + * Copyright (C) 2025 Kurt Borja + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define ADS1018_CFG_OS_TRIG BIT(15) +#define ADS1018_CFG_TS_MODE_EN BIT(4) +#define ADS1018_CFG_PULL_UP BIT(3) +#define ADS1018_CFG_NOP BIT(1) +#define ADS1018_CFG_VALID (ADS1018_CFG_PULL_UP | ADS1018_CFG_NOP) + +#define ADS1018_CFG_MUX_MASK GENMASK(14, 12) + +#define ADS1018_CFG_PGA_MASK GENMASK(11, 9) +#define ADS1018_PGA_DEFAULT 2 + +#define ADS1018_CFG_MODE_MASK BIT(8) +#define ADS1018_MODE_CONTINUOUS 0 +#define ADS1018_MODE_ONESHOT 1 + +#define ADS1018_CFG_DRATE_MASK GENMASK(7, 5) +#define ADS1018_DRATE_DEFAULT 4 + +#define ADS1018_NUM_PGA_MODES 6 +#define ADS1018_CHANNELS_MAX 10 + +struct ads1018_chan_data { + u8 pga_mode; + u8 data_rate_mode; +}; + +struct ads1018_chip_info { + const char *name; + const struct iio_chan_spec *channels; + unsigned long num_channels; + + /* IIO_VAL_INT */ + const u32 *data_rate_mode_to_hz; + unsigned long num_data_rate_mode_to_hz; + + /* + * Let `res` be the chip's resolution and `fsr` (millivolts) be the + * full-scale range corresponding to the PGA mode given by the array + * index. Then, the gain is calculated using the following formula: + * + * gain = |fsr| / 2^(res - 1) + * + * This value then has to be represented in IIO_VAL_INT_PLUS_NANO + * format. For example if: + * + * gain = 6144 / 2^(16 - 1) = 0.1875 + * + * ...then the formatted value is: + * + * { 0, 187500000 } + */ + const u32 pga_mode_to_gain[ADS1018_NUM_PGA_MODES][2]; + + /* IIO_VAL_INT_PLUS_MICRO */ + const u32 temp_scale[2]; +}; + +struct ads1018 { + struct spi_device *spi; + struct iio_trigger *indio_trig; + + struct gpio_desc *drdy_gpiod; + int drdy_irq; + + struct ads1018_chan_data chan_data[ADS1018_CHANNELS_MAX]; + const struct ads1018_chip_info *chip_info; + + struct spi_message msg_read; + struct spi_transfer xfer; + __be16 tx_buf[2] __aligned(IIO_DMA_MINALIGN); + __be16 rx_buf[2]; +}; + +#define ADS1018_VOLT_DIFF_CHAN(_index, _chan, _chan2, _realbits) { \ + .type = IIO_VOLTAGE, \ + .channel = _chan, \ + .channel2 = _chan2, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = _realbits, \ + .storagebits = 16, \ + .shift = 16 - _realbits, \ + .endianness = IIO_BE, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .indexed = true, \ + .differential = true, \ +} + +#define ADS1018_VOLT_CHAN(_index, _chan, _realbits) { \ + .type = IIO_VOLTAGE, \ + .channel = _chan, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = _realbits, \ + .storagebits = 16, \ + .shift = 16 - _realbits, \ + .endianness = IIO_BE, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .indexed = true, \ +} + +#define ADS1018_TEMP_CHAN(_index, _realbits) { \ + .type = IIO_TEMP, \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = _realbits, \ + .storagebits = 16, \ + .shift = 16 - _realbits, \ + .endianness = IIO_BE, \ + }, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ +} + +static const struct iio_chan_spec ads1118_iio_channels[] = { + ADS1018_VOLT_DIFF_CHAN(0, 0, 1, 16), + ADS1018_VOLT_DIFF_CHAN(1, 0, 3, 16), + ADS1018_VOLT_DIFF_CHAN(2, 1, 3, 16), + ADS1018_VOLT_DIFF_CHAN(3, 2, 3, 16), + ADS1018_VOLT_CHAN(4, 0, 16), + ADS1018_VOLT_CHAN(5, 1, 16), + ADS1018_VOLT_CHAN(6, 2, 16), + ADS1018_VOLT_CHAN(7, 3, 16), + ADS1018_TEMP_CHAN(8, 14), + IIO_CHAN_SOFT_TIMESTAMP(9), +}; + +static const struct iio_chan_spec ads1018_iio_channels[] = { + ADS1018_VOLT_DIFF_CHAN(0, 0, 1, 12), + ADS1018_VOLT_DIFF_CHAN(1, 0, 3, 12), + ADS1018_VOLT_DIFF_CHAN(2, 1, 3, 12), + ADS1018_VOLT_DIFF_CHAN(3, 2, 3, 12), + ADS1018_VOLT_CHAN(4, 0, 12), + ADS1018_VOLT_CHAN(5, 1, 12), + ADS1018_VOLT_CHAN(6, 2, 12), + ADS1018_VOLT_CHAN(7, 3, 12), + ADS1018_TEMP_CHAN(8, 12), + IIO_CHAN_SOFT_TIMESTAMP(9), +}; + +/** + * ads1018_calc_delay - Calculates a suitable delay for a single-shot reading + * @hz: Sampling frequency + * + * Calculates an appropriate delay for a single shot reading given a sampling + * frequency. + * + * Return: Delay in microseconds (Always greater than 0). + */ +static u32 ads1018_calc_delay(unsigned int hz) +{ + /* + * Calculate the worst-case sampling rate by subtracting 10% error + * specified in the datasheet... + */ + hz -= DIV_ROUND_UP(hz, 10); + + /* ...Then calculate time per sample in microseconds. */ + return DIV_ROUND_UP(HZ_PER_MHZ, hz); +} + +/** + * ads1018_spi_read_exclusive - Reads a conversion value from the device + * @ads1018: Device data + * @cnv: ADC Conversion value (optional) + * @hold_cs: Keep CS line asserted after the SPI transfer + * + * Reads the most recent ADC conversion value, without updating the + * device's configuration. + * + * Context: Expects SPI bus *exclusive* use. + * + * Return: 0 on success, negative errno on error. + */ +static int ads1018_spi_read_exclusive(struct ads1018 *ads1018, __be16 *cnv, + bool hold_cs) +{ + int ret; + + ads1018->xfer.cs_change = hold_cs; + + ret = spi_sync_locked(ads1018->spi, &ads1018->msg_read); + if (ret) + return ret; + + if (cnv) + *cnv = ads1018->rx_buf[0]; + + return 0; +} + +/** + * ads1018_single_shot - Performs a one-shot reading sequence + * @ads1018: Device data + * @chan: Channel specification + * @cnv: Conversion value + * + * Writes a new configuration, waits an appropriate delay, then reads the most + * recent conversion. + * + * Context: Expects iio_device_claim_direct() is held. + * + * Return: 0 on success, negative errno on error. + */ +static int ads1018_single_shot(struct ads1018 *ads1018, + struct iio_chan_spec const *chan, u16 *cnv) +{ + u8 max_drate_mode = ads1018->chip_info->num_data_rate_mode_to_hz - 1; + u8 drate = ads1018->chip_info->data_rate_mode_to_hz[max_drate_mode]; + u8 pga_mode = ads1018->chan_data[chan->scan_index].pga_mode; + struct spi_transfer xfer[2] = { + { + .tx_buf = ads1018->tx_buf, + .len = sizeof(ads1018->tx_buf[0]), + .delay = { + .value = ads1018_calc_delay(drate), + .unit = SPI_DELAY_UNIT_USECS, + }, + .cs_change = 1, /* 16-bit mode requires CS de-assert */ + }, + { + .rx_buf = ads1018->rx_buf, + .len = sizeof(ads1018->rx_buf[0]), + }, + }; + u16 cfg; + int ret; + + cfg = ADS1018_CFG_VALID | ADS1018_CFG_OS_TRIG; + cfg |= FIELD_PREP(ADS1018_CFG_MUX_MASK, chan->scan_index); + cfg |= FIELD_PREP(ADS1018_CFG_PGA_MASK, pga_mode); + cfg |= FIELD_PREP(ADS1018_CFG_MODE_MASK, ADS1018_MODE_ONESHOT); + cfg |= FIELD_PREP(ADS1018_CFG_DRATE_MASK, max_drate_mode); + + if (chan->type == IIO_TEMP) + cfg |= ADS1018_CFG_TS_MODE_EN; + + ads1018->tx_buf[0] = cpu_to_be16(cfg); + ret = spi_sync_transfer(ads1018->spi, xfer, ARRAY_SIZE(xfer)); + if (ret) + return ret; + + *cnv = be16_to_cpu(ads1018->rx_buf[0]); + + return 0; +} + +static int +ads1018_read_raw_direct_mode(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, int *val2, + long mask) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + const struct ads1018_chip_info *chip_info = ads1018->chip_info; + u8 addr = chan->scan_index; + u8 pga_mode, drate_mode; + u16 cnv; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = ads1018_single_shot(ads1018, chan, &cnv); + if (ret) + return ret; + + cnv >>= chan->scan_type.shift; + *val = sign_extend32(cnv, chan->scan_type.realbits - 1); + + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_VOLTAGE: + pga_mode = ads1018->chan_data[addr].pga_mode; + *val = chip_info->pga_mode_to_gain[pga_mode][0]; + *val2 = chip_info->pga_mode_to_gain[pga_mode][1]; + return IIO_VAL_INT_PLUS_NANO; + + case IIO_TEMP: + *val = chip_info->temp_scale[0]; + *val2 = chip_info->temp_scale[1]; + return IIO_VAL_INT_PLUS_MICRO; + + default: + return -EOPNOTSUPP; + } + + case IIO_CHAN_INFO_SAMP_FREQ: + drate_mode = ads1018->chan_data[addr].data_rate_mode; + *val = chip_info->data_rate_mode_to_hz[drate_mode]; + return IIO_VAL_INT; + + default: + return -EOPNOTSUPP; + } +} + +static int +ads1018_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ret = ads1018_read_raw_direct_mode(indio_dev, chan, val, val2, mask); + iio_device_release_direct(indio_dev); + + return ret; +} + +static int +ads1018_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, long mask) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *type = IIO_VAL_INT_PLUS_NANO; + *vals = (const int *)ads1018->chip_info->pga_mode_to_gain; + *length = ADS1018_NUM_PGA_MODES * 2; + return IIO_AVAIL_LIST; + + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT; + *vals = ads1018->chip_info->data_rate_mode_to_hz; + *length = ads1018->chip_info->num_data_rate_mode_to_hz; + return IIO_AVAIL_LIST; + + default: + return -EOPNOTSUPP; + } +} + +static int +ads1018_write_raw_direct_mode(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, int val2, + long mask) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + const struct ads1018_chip_info *info = ads1018->chip_info; + unsigned int i; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + for (i = 0; i < ADS1018_NUM_PGA_MODES; i++) { + if (val == info->pga_mode_to_gain[i][0] && + val2 == info->pga_mode_to_gain[i][1]) + break; + } + if (i == ADS1018_NUM_PGA_MODES) + return -EINVAL; + + ads1018->chan_data[chan->scan_index].pga_mode = i; + return 0; + + case IIO_CHAN_INFO_SAMP_FREQ: + for (i = 0; i < info->num_data_rate_mode_to_hz; i++) { + if (val == info->data_rate_mode_to_hz[i]) + break; + } + if (i == info->num_data_rate_mode_to_hz) + return -EINVAL; + + ads1018->chan_data[chan->scan_index].data_rate_mode = i; + return 0; + + default: + return -EOPNOTSUPP; + } +} + +static int +ads1018_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + int ret; + + if (!iio_device_claim_direct(indio_dev)) + return -EBUSY; + ret = ads1018_write_raw_direct_mode(indio_dev, chan, val, val2, mask); + iio_device_release_direct(indio_dev); + + return ret; +} + +static int +ads1018_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + +static const struct iio_info ads1018_iio_info = { + .read_raw = ads1018_read_raw, + .read_avail = ads1018_read_avail, + .write_raw = ads1018_write_raw, + .write_raw_get_fmt = ads1018_write_raw_get_fmt, +}; + +static void ads1018_set_trigger_enable(struct ads1018 *ads1018) +{ + spi_bus_lock(ads1018->spi->controller); + ads1018_spi_read_exclusive(ads1018, NULL, true); + enable_irq(ads1018->drdy_irq); +} + +static void ads1018_set_trigger_disable(struct ads1018 *ads1018) +{ + disable_irq(ads1018->drdy_irq); + ads1018_spi_read_exclusive(ads1018, NULL, false); + spi_bus_unlock(ads1018->spi->controller); +} + +static int ads1018_set_trigger_state(struct iio_trigger *trig, bool state) +{ + struct ads1018 *ads1018 = iio_trigger_get_drvdata(trig); + + /* + * We need to lock the SPI bus and tie CS low (hold_cs) to catch + * data-ready interrupts, otherwise the MISO line enters a Hi-Z state. + */ + + if (state) + ads1018_set_trigger_enable(ads1018); + else + ads1018_set_trigger_disable(ads1018); + + return 0; +} + +static const struct iio_trigger_ops ads1018_trigger_ops = { + .set_trigger_state = ads1018_set_trigger_state, + .validate_device = iio_trigger_validate_own_device, +}; + +static int ads1018_buffer_preenable(struct iio_dev *indio_dev) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + const struct ads1018_chip_info *chip_info = ads1018->chip_info; + unsigned int pga, drate, addr; + u16 cfg; + + addr = find_first_bit(indio_dev->active_scan_mask, + iio_get_masklength(indio_dev)); + pga = ads1018->chan_data[addr].pga_mode; + drate = ads1018->chan_data[addr].data_rate_mode; + + cfg = ADS1018_CFG_VALID; + cfg |= FIELD_PREP(ADS1018_CFG_MUX_MASK, addr); + cfg |= FIELD_PREP(ADS1018_CFG_PGA_MASK, pga); + cfg |= FIELD_PREP(ADS1018_CFG_MODE_MASK, ADS1018_MODE_CONTINUOUS); + cfg |= FIELD_PREP(ADS1018_CFG_DRATE_MASK, drate); + + if (chip_info->channels[addr].type == IIO_TEMP) + cfg |= ADS1018_CFG_TS_MODE_EN; + + ads1018->tx_buf[0] = cpu_to_be16(cfg); + ads1018->tx_buf[1] = 0; + + return spi_write(ads1018->spi, ads1018->tx_buf, sizeof(ads1018->tx_buf)); +} + +static int ads1018_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + u16 cfg; + + cfg = ADS1018_CFG_VALID; + cfg |= FIELD_PREP(ADS1018_CFG_MODE_MASK, ADS1018_MODE_ONESHOT); + + ads1018->tx_buf[0] = cpu_to_be16(cfg); + ads1018->tx_buf[1] = 0; + + return spi_write(ads1018->spi, ads1018->tx_buf, sizeof(ads1018->tx_buf)); +} + +static const struct iio_buffer_setup_ops ads1018_buffer_ops = { + .preenable = ads1018_buffer_preenable, + .postdisable = ads1018_buffer_postdisable, + .validate_scan_mask = iio_validate_scan_mask_onehot, +}; + +static irqreturn_t ads1018_irq_handler(int irq, void *dev_id) +{ + struct ads1018 *ads1018 = dev_id; + + /* + * We need to check if the "drdy" pin is actually active or if it's a + * pending interrupt triggered by the SPI transfer. + */ + if (!gpiod_get_value(ads1018->drdy_gpiod)) + return IRQ_HANDLED; + + iio_trigger_poll(ads1018->indio_trig); + + return IRQ_HANDLED; +} + +static irqreturn_t ads1018_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct ads1018 *ads1018 = iio_priv(indio_dev); + struct { + __be16 conv; + aligned_s64 ts; + } scan = {}; + int ret; + + if (iio_trigger_using_own(indio_dev)) { + disable_irq(ads1018->drdy_irq); + ret = ads1018_spi_read_exclusive(ads1018, &scan.conv, true); + enable_irq(ads1018->drdy_irq); + } else { + ret = spi_read(ads1018->spi, ads1018->rx_buf, sizeof(ads1018->rx_buf)); + scan.conv = ads1018->rx_buf[0]; + } + + if (!ret) + iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), + pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +static int ads1018_trigger_setup(struct iio_dev *indio_dev) +{ + struct ads1018 *ads1018 = iio_priv(indio_dev); + struct spi_device *spi = ads1018->spi; + struct device *dev = &spi->dev; + const char *con_id = "drdy"; + int ret; + + ads1018->drdy_gpiod = devm_gpiod_get_optional(dev, con_id, GPIOD_IN); + if (IS_ERR(ads1018->drdy_gpiod)) + return dev_err_probe(dev, PTR_ERR(ads1018->drdy_gpiod), + "Failed to get %s GPIO.\n", con_id); + + /* First try to get IRQ from SPI core, then from GPIO */ + if (spi->irq > 0) + ads1018->drdy_irq = spi->irq; + else if (ads1018->drdy_gpiod) + ads1018->drdy_irq = gpiod_to_irq(ads1018->drdy_gpiod); + if (ads1018->drdy_irq < 0) + return dev_err_probe(dev, ads1018->drdy_irq, + "Failed to get IRQ from %s GPIO.\n", con_id); + + /* An IRQ line is only an optional requirement for the IIO trigger */ + if (ads1018->drdy_irq == 0) + return 0; + + ads1018->indio_trig = devm_iio_trigger_alloc(dev, "%s-dev%d-%s", + indio_dev->name, + iio_device_id(indio_dev), + con_id); + if (!ads1018->indio_trig) + return -ENOMEM; + + iio_trigger_set_drvdata(ads1018->indio_trig, ads1018); + ads1018->indio_trig->ops = &ads1018_trigger_ops; + + ret = devm_iio_trigger_register(dev, ads1018->indio_trig); + if (ret) + return ret; + + /* + * The "data-ready" IRQ line is shared with the MOSI pin, thus we need + * to keep it disabled until we actually request data. + */ + return devm_request_irq(dev, ads1018->drdy_irq, ads1018_irq_handler, + IRQF_NO_AUTOEN, ads1018->chip_info->name, ads1018); +} + +static int ads1018_spi_probe(struct spi_device *spi) +{ + const struct ads1018_chip_info *info = spi_get_device_match_data(spi); + struct device *dev = &spi->dev; + struct iio_dev *indio_dev; + struct ads1018 *ads1018; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*ads1018)); + if (!indio_dev) + return -ENOMEM; + + ads1018 = iio_priv(indio_dev); + ads1018->spi = spi; + ads1018->chip_info = info; + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = info->name; + indio_dev->info = &ads1018_iio_info; + indio_dev->channels = info->channels; + indio_dev->num_channels = info->num_channels; + + for (unsigned int i = 0; i < ADS1018_CHANNELS_MAX; i++) { + ads1018->chan_data[i].data_rate_mode = ADS1018_DRATE_DEFAULT; + ads1018->chan_data[i].pga_mode = ADS1018_PGA_DEFAULT; + } + + ads1018->xfer.rx_buf = ads1018->rx_buf; + ads1018->xfer.len = sizeof(ads1018->rx_buf); + spi_message_init_with_transfers(&ads1018->msg_read, &ads1018->xfer, 1); + + ret = ads1018_trigger_setup(indio_dev); + if (ret) + return ret; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, + iio_pollfunc_store_time, + ads1018_trigger_handler, + &ads1018_buffer_ops); + if (ret) + return ret; + + return devm_iio_device_register(&spi->dev, indio_dev); +} + +static const unsigned int ads1018_data_rate_table[] = { + 128, 250, 490, 920, 1600, 2400, 3300, +}; + +static const unsigned int ads1118_data_rate_table[] = { + 8, 16, 32, 64, 128, 250, 475, 860, +}; + +static const struct ads1018_chip_info ads1018_chip_info = { + .name = "ads1018", + .channels = ads1018_iio_channels, + .num_channels = ARRAY_SIZE(ads1018_iio_channels), + .data_rate_mode_to_hz = ads1018_data_rate_table, + .num_data_rate_mode_to_hz = ARRAY_SIZE(ads1018_data_rate_table), + .pga_mode_to_gain = { + { 3, 0 }, /* fsr = 6144 mV */ + { 2, 0 }, /* fsr = 4096 mV */ + { 1, 0 }, /* fsr = 2048 mV */ + { 0, 500000000 }, /* fsr = 1024 mV */ + { 0, 250000000 }, /* fsr = 512 mV */ + { 0, 125000000 }, /* fsr = 256 mV */ + }, + .temp_scale = { 125, 0 }, +}; + +static const struct ads1018_chip_info ads1118_chip_info = { + .name = "ads1118", + .channels = ads1118_iio_channels, + .num_channels = ARRAY_SIZE(ads1118_iio_channels), + .data_rate_mode_to_hz = ads1118_data_rate_table, + .num_data_rate_mode_to_hz = ARRAY_SIZE(ads1118_data_rate_table), + .pga_mode_to_gain = { + { 0, 187500000 }, /* fsr = 6144 mV */ + { 0, 125000000 }, /* fsr = 4096 mV */ + { 0, 62500000 }, /* fsr = 2048 mV */ + { 0, 31250000 }, /* fsr = 1024 mV */ + { 0, 15625000 }, /* fsr = 512 mV */ + { 0, 7812500 }, /* fsr = 256 mV */ + }, + .temp_scale = { 31, 250000 }, +}; + +static const struct of_device_id ads1018_of_match[] = { + { .compatible = "ti,ads1018", .data = &ads1018_chip_info }, + { .compatible = "ti,ads1118", .data = &ads1118_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(of, ads1018_of_match); + +static const struct spi_device_id ads1018_spi_match[] = { + { "ads1018", (kernel_ulong_t)&ads1018_chip_info }, + { "ads1118", (kernel_ulong_t)&ads1118_chip_info }, + { } +}; +MODULE_DEVICE_TABLE(spi, ads1018_spi_match); + +static struct spi_driver ads1018_spi_driver = { + .driver = { + .name = "ads1018", + .of_match_table = ads1018_of_match, + }, + .probe = ads1018_spi_probe, + .id_table = ads1018_spi_match, +}; +module_spi_driver(ads1018_spi_driver); + +MODULE_DESCRIPTION("Texas Instruments ADS1018 ADC Driver"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Kurt Borja "); diff --git a/drivers/iio/adc/ti-ads131e08.c b/drivers/iio/adc/ti-ads131e08.c index c9a20024d6b1..a585621b0bc3 100644 --- a/drivers/iio/adc/ti-ads131e08.c +++ b/drivers/iio/adc/ti-ads131e08.c @@ -827,7 +827,7 @@ static int ads131e08_probe(struct spi_device *spi) if (spi->irq) { ret = devm_request_irq(&spi->dev, spi->irq, ads131e08_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + IRQF_TRIGGER_FALLING | IRQF_NO_THREAD, spi->dev.driver->name, indio_dev); if (ret) return dev_err_probe(&spi->dev, ret, diff --git a/drivers/iio/adc/ti-ads131m02.c b/drivers/iio/adc/ti-ads131m02.c new file mode 100644 index 000000000000..07d63bf62c5f --- /dev/null +++ b/drivers/iio/adc/ti-ads131m02.c @@ -0,0 +1,968 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Driver for Texas Instruments ADS131M02 family ADC chips. + * + * Copyright (C) 2024 Protonic Holland + * Copyright (C) 2025 Oleksij Rempel , Pengutronix + * + * Primary Datasheet Reference (used for citations): + * ADS131M08 8-Channel, Simultaneously-Sampling, 24-Bit, Delta-Sigma ADC + * Document SBAS950B, Revised February 2021 + * https://www.ti.com/lit/ds/symlink/ads131m08.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Max channels supported by the largest variant in the family (ADS131M08) */ +#define ADS131M_MAX_CHANNELS 8 + +/* Section 6.7, t_REGACQ (min time after reset) is 5us */ +#define ADS131M_RESET_DELAY_US 5 + +#define ADS131M_WORD_SIZE_BYTES 3 +#define ADS131M_RESPONSE_WORDS 1 +#define ADS131M_CRC_WORDS 1 + +/* + * SPI Frame word count calculation. + * Frame = N channel words + 1 response word + 1 CRC word. + * Word size depends on WLENGTH bits in MODE register (Default 24-bit). + */ +#define ADS131M_FRAME_WORDS(nch) \ + ((nch) + ADS131M_RESPONSE_WORDS + ADS131M_CRC_WORDS) + +/* + * SPI Frame byte size calculation. + * Assumes default word size of 24 bits (3 bytes). + */ +#define ADS131M_FRAME_BYTES(nch) \ + (ADS131M_FRAME_WORDS(nch) * ADS131M_WORD_SIZE_BYTES) + +/* + * Index calculation for the start byte of channel 'x' data within the RX buffer. + * Assumes 24-bit words (3 bytes per word). + * The received frame starts with the response word (e.g., STATUS register + * content when NULL command was sent), followed by data for channels 0 to N-1, + * and finally the output CRC word. + * Response = index 0..2, Chan0 = index 3..5, Chan1 = index 6..8, ... + * Index for ChanX = 3 (response) + x * 3 (channel data size). + */ +#define ADS131M_CHANNEL_INDEX(x) \ + ((x) * ADS131M_WORD_SIZE_BYTES + ADS131M_WORD_SIZE_BYTES) + +#define ADS131M_CMD_NULL 0x0000 +#define ADS131M_CMD_RESET 0x0011 + +#define ADS131M_CMD_ADDR_MASK GENMASK(11, 7) +#define ADS131M_CMD_NUM_MASK GENMASK(6, 0) + +#define ADS131M_CMD_RREG_OP 0xa000 +#define ADS131M_CMD_WREG_OP 0x6000 + +#define ADS131M_CMD_RREG(a, n) \ + (ADS131M_CMD_RREG_OP | \ + FIELD_PREP(ADS131M_CMD_ADDR_MASK, a) | \ + FIELD_PREP(ADS131M_CMD_NUM_MASK, n)) +#define ADS131M_CMD_WREG(a, n) \ + (ADS131M_CMD_WREG_OP | \ + FIELD_PREP(ADS131M_CMD_ADDR_MASK, a) | \ + FIELD_PREP(ADS131M_CMD_NUM_MASK, n)) + +/* STATUS Register (0x01h) bit definitions */ +#define ADS131M_STATUS_CRC_ERR BIT(12) /* Input CRC error */ + +#define ADS131M_REG_MODE 0x02 +#define ADS131M_MODE_RX_CRC_EN BIT(12) /* Enable Input CRC */ +#define ADS131M_MODE_CRC_TYPE_ANSI BIT(11) /* 0 = CCITT, 1 = ANSI */ +#define ADS131M_MODE_RESET_FLAG BIT(10) + +#define ADS131M_REG_CLOCK 0x03 +#define ADS131M_CLOCK_XTAL_DIS BIT(7) +#define ADS131M_CLOCK_EXTREF_EN BIT(6) + +/* 1.2V internal reference, in millivolts, for IIO_VAL_FRACTIONAL_LOG2 */ +#define ADS131M_VREF_INTERNAL_mV 1200 +/* 24-bit resolution */ +#define ADS131M_RESOLUTION_BITS 24 +/* Signed data uses (RESOLUTION_BITS - 1) magnitude bits */ +#define ADS131M_CODE_BITS (ADS131M_RESOLUTION_BITS - 1) + +/* External ref FSR = Vref * 0.96 */ +#define ADS131M_EXTREF_SCALE_NUM 96 +#define ADS131M_EXTREF_SCALE_DEN 100 + +struct ads131m_configuration { + const struct iio_chan_spec *channels; + const char *name; + u16 reset_ack; + u8 num_channels; + u8 supports_extref:1; + u8 supports_xtal:1; +}; + +struct ads131m_priv { + struct iio_dev *indio_dev; + struct spi_device *spi; + const struct ads131m_configuration *config; + + bool use_external_ref; + int scale_val; + int scale_val2; + + struct spi_transfer xfer; + struct spi_message msg; + + /* + * Protects the shared tx_buffer and rx_buffer. More importantly, + * this serializes all SPI communication to ensure the atomicity + * of multi-cycle command sequences (like WREG, RREG, or RESET). + */ + struct mutex lock; + + /* DMA-safe buffers should be placed at the end of the struct. */ + u8 tx_buffer[ADS131M_FRAME_BYTES(ADS131M_MAX_CHANNELS)] + __aligned(IIO_DMA_MINALIGN); + u8 rx_buffer[ADS131M_FRAME_BYTES(ADS131M_MAX_CHANNELS)]; +}; + +/** + * ads131m_tx_frame_unlocked - Sends a command frame with Input CRC + * @priv: Device private data structure. + * @command: The 16-bit command to send (e.g., NULL, RREG, RESET). + * + * This function sends a command in Word 0, and its calculated 16-bit + * CRC in Word 1, as required when Input CRC is enabled. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_tx_frame_unlocked(struct ads131m_priv *priv, u32 command) +{ + struct iio_dev *indio_dev = priv->indio_dev; + u16 crc; + + lockdep_assert_held(&priv->lock); + + memset(priv->tx_buffer, 0, ADS131M_FRAME_BYTES(indio_dev->num_channels)); + + /* Word 0: 16-bit command, MSB-aligned in 24-bit word */ + put_unaligned_be16(command, &priv->tx_buffer[0]); + + /* Word 1: Input CRC. Calculated over the 3 bytes of Word 0. */ + crc = crc_itu_t(0xffff, priv->tx_buffer, 3); + put_unaligned_be16(crc, &priv->tx_buffer[3]); + + return spi_sync(priv->spi, &priv->msg); +} + +/** + * ads131m_rx_frame_unlocked - Receives a full SPI data frame. + * @priv: Device private data structure. + * + * This function sends a NULL command (with its CRC) to clock out a + * full SPI frame from the device (e.g., response + channel data + CRC). + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_rx_frame_unlocked(struct ads131m_priv *priv) +{ + return ads131m_tx_frame_unlocked(priv, ADS131M_CMD_NULL); +} + +/** + * ads131m_check_status_crc_err - Checks for an Input CRC error. + * @priv: Device private data structure. + * + * Sends a NULL command to fetch the STATUS register and checks the + * CRC_ERR bit. This is used to verify the integrity of the previous + * command (like RREG or WREG). + * + * Return: 0 on success, -EIO if CRC_ERR bit is set. + */ +static int ads131m_check_status_crc_err(struct ads131m_priv *priv) +{ + struct device *dev = &priv->spi->dev; + u16 status; + int ret; + + lockdep_assert_held(&priv->lock); + + ret = ads131m_rx_frame_unlocked(priv); + if (ret < 0) { + dev_err_ratelimited(dev, + "SPI error on STATUS read for CRC check\n"); + return ret; + } + + status = get_unaligned_be16(&priv->rx_buffer[0]); + if (status & ADS131M_STATUS_CRC_ERR) { + dev_err_ratelimited(dev, + "Input CRC error reported in STATUS = 0x%04x\n", + status); + return -EIO; + } + + return 0; +} + +/** + * ads131m_write_reg_unlocked - Writes a single register and verifies the ACK. + * @priv: Device private data structure. + * @reg: The 8-bit register address. + * @val: The 16-bit value to write. + * + * This function performs the full 3-cycle WREG operation with Input CRC: + * 1. (Cycle 1) Sends WREG command, data, and its calculated CRC. + * 2. (Cycle 2) Sends NULL+CRC to retrieve the response from Cycle 1. + * 3. Verifies the response is the correct ACK for the WREG. + * 4. (Cycle 3) Sends NULL+CRC to retrieve STATUS and check for CRC_ERR. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_write_reg_unlocked(struct ads131m_priv *priv, u8 reg, u16 val) +{ + struct iio_dev *indio_dev = priv->indio_dev; + u16 command, expected_ack, response, crc; + struct device *dev = &priv->spi->dev; + int ret_crc_err = 0; + int ret; + + lockdep_assert_held(&priv->lock); + + command = ADS131M_CMD_WREG(reg, 0); /* n = 0 for 1 register */ + /* + * Per Table 8-11, WREG response is: 010a aaaa ammm mmmm + * For 1 reg (n = 0 -> m = 0): 010a aaaa a000 0000 = 0x4000 | (reg << 7) + */ + expected_ack = 0x4000 | (reg << 7); + + /* Cycle 1: Send WREG Command + Data + Input CRC */ + + memset(priv->tx_buffer, 0, ADS131M_FRAME_BYTES(indio_dev->num_channels)); + + /* Word 0: WREG command, 1 reg (n = 0), MSB-aligned */ + put_unaligned_be16(command, &priv->tx_buffer[0]); + + /* Word 1: Data, MSB-aligned */ + put_unaligned_be16(val, &priv->tx_buffer[3]); + + /* Word 2: Input CRC. Calculated over Word 0 (Cmd) and Word 1 (Data). */ + crc = crc_itu_t(0xffff, priv->tx_buffer, 6); + put_unaligned_be16(crc, &priv->tx_buffer[6]); + + /* Ignore the RX buffer (it's from the previous command) */ + ret = spi_sync(priv->spi, &priv->msg); + if (ret < 0) { + dev_err_ratelimited(dev, "SPI error on WREG (cycle 1)\n"); + return ret; + } + + /* Cycle 2: Send NULL Command to get the WREG response */ + ret = ads131m_rx_frame_unlocked(priv); + if (ret < 0) { + dev_err_ratelimited(dev, "SPI error on WREG ACK (cycle 2)\n"); + return ret; + } + + /* + * Response is in the first 2 bytes of the RX buffer + * (MSB-aligned 16-bit response) + */ + response = get_unaligned_be16(&priv->rx_buffer[0]); + if (response != expected_ack) { + dev_err_ratelimited(dev, "WREG(0x%02x) failed, expected ACK 0x%04x, got 0x%04x\n", + reg, expected_ack, response); + ret_crc_err = -EIO; + /* + * Don't return yet, still need to do Cycle 3 to clear + * any potential CRC_ERR flag from this failed command. + */ + } + + /* + * Cycle 3: Check STATUS for Input CRC error. + * This is necessary even if ACK was wrong, to clear the CRC_ERR flag. + */ + ret = ads131m_check_status_crc_err(priv); + if (ret < 0) + return ret; + + return ret_crc_err; +} + +/** + * ads131m_read_reg_unlocked - Reads a single register from the device. + * @priv: Device private data structure. + * @reg: The 8-bit register address. + * @val: Pointer to store the 16-bit register value. + * + * This function performs the full 3-cycle RREG operation with Input CRC: + * 1. (Cycle 1) Sends the RREG command + Input CRC. + * 2. (Cycle 2) Sends NULL+CRC to retrieve the register data. + * 3. (Cycle 3) Sends NULL+CRC to retrieve STATUS and check for CRC_ERR. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_read_reg_unlocked(struct ads131m_priv *priv, u8 reg, u16 *val) +{ + struct device *dev = &priv->spi->dev; + u16 command; + int ret; + + lockdep_assert_held(&priv->lock); + + command = ADS131M_CMD_RREG(reg, 0); /* n=0 for 1 register */ + + /* + * Cycle 1: Send RREG Command + Input CRC + * Ignore the RX buffer (it's from the previous command) + */ + ret = ads131m_tx_frame_unlocked(priv, command); + if (ret < 0) { + dev_err_ratelimited(dev, "SPI error on RREG (cycle 1)\n"); + return ret; + } + + /* Cycle 2: Send NULL Command to get the register data */ + ret = ads131m_rx_frame_unlocked(priv); + if (ret < 0) { + dev_err_ratelimited(dev, "SPI error on RREG data (cycle 2)\n"); + return ret; + } + + /* + * Per datasheet, for a single reg read, the response is the data. + * It's in the first 2 bytes of the RX buffer (MSB-aligned 16-bit). + */ + *val = get_unaligned_be16(&priv->rx_buffer[0]); + + /* + * Cycle 3: Check STATUS for Input CRC error. + * The RREG command does not execute if CRC is bad, but we read + * STATUS anyway to clear the flag in case it was set. + */ + return ads131m_check_status_crc_err(priv); +} + +/** + * ads131m_rmw_reg - Reads, modifies, and writes a single register. + * @priv: Device private data structure. + * @reg: The 8-bit register address. + * @clear: Bitmask of bits to clear. + * @set: Bitmask of bits to set. + * + * This function performs an atomic read-modify-write operation on a register. + * It reads the register, applies the clear and set masks, and writes + * the new value back if it has changed. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_rmw_reg(struct ads131m_priv *priv, u8 reg, u16 clear, u16 set) +{ + u16 old_val, new_val; + int ret; + + guard(mutex)(&priv->lock); + + ret = ads131m_read_reg_unlocked(priv, reg, &old_val); + if (ret < 0) + return ret; + + new_val = (old_val & ~clear) | set; + if (new_val == old_val) + return 0; + + return ads131m_write_reg_unlocked(priv, reg, new_val); +} + +/** + * ads131m_verify_output_crc - Verifies the CRC of the received SPI frame. + * @priv: Device private data structure. + * + * This function calculates the CRC-16-CCITT (Poly 0x1021, Seed 0xFFFF) over + * the received response and channel data, and compares it to the CRC word + * received at the end of the SPI frame. + * + * Return: 0 on success, -EIO on CRC mismatch. + */ +static int ads131m_verify_output_crc(struct ads131m_priv *priv) +{ + struct iio_dev *indio_dev = priv->indio_dev; + struct device *dev = &priv->spi->dev; + u16 calculated_crc, received_crc; + size_t data_len; + + lockdep_assert_held(&priv->lock); + + /* + * Frame: [Response][Chan 0]...[Chan N-1][CRC Word] + * Data for CRC: [Response][Chan 0]...[Chan N-1] + * Data length = (N_channels + 1) * 3 bytes (at 24-bit word size) + */ + data_len = ADS131M_FRAME_BYTES(indio_dev->num_channels) - 3; + calculated_crc = crc_itu_t(0xffff, priv->rx_buffer, data_len); + + /* + * The received 16-bit CRC is MSB-aligned in the last 24-bit word. + * We extract it from the first 2 bytes (BE) of that word. + */ + received_crc = get_unaligned_be16(&priv->rx_buffer[data_len]); + if (calculated_crc != received_crc) { + dev_err_ratelimited(dev, "Output CRC error. Got %04x, expected %04x\n", + received_crc, calculated_crc); + return -EIO; + } + + return 0; +} + +/** + * ads131m_adc_read - Reads channel data, checks input and output CRCs. + * @priv: Device private data structure. + * @channel: The channel number to read. + * @val: Pointer to store the raw 24-bit value. + * + * This function sends a NULL command (with Input CRC) to retrieve data. + * It checks the received STATUS word for any Input CRC errors from the + * previous command, and then verifies the Output CRC of the current + * data frame. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_adc_read(struct ads131m_priv *priv, u8 channel, s32 *val) +{ + struct device *dev = &priv->spi->dev; + u16 status; + int ret; + u8 *buf; + + guard(mutex)(&priv->lock); + + /* Send NULL command + Input CRC, and receive data frame */ + ret = ads131m_rx_frame_unlocked(priv); + if (ret < 0) + return ret; + + /* + * Check STATUS for Input CRC error from the previous command frame. + * Note: the STATUS word belongs to the frame before this NULL command. + */ + status = get_unaligned_be16(&priv->rx_buffer[0]); + if (status & ADS131M_STATUS_CRC_ERR) { + dev_err_ratelimited(dev, + "Previous input CRC error reported in STATUS (0x%04x)\n", + status); + } + + ret = ads131m_verify_output_crc(priv); + if (ret < 0) + return ret; + + buf = &priv->rx_buffer[ADS131M_CHANNEL_INDEX(channel)]; + *val = sign_extend32(get_unaligned_be24(buf), ADS131M_CODE_BITS); + + return 0; +} + +static int ads131m_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *channel, + int *val, int *val2, long mask) +{ + struct ads131m_priv *priv = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = ads131m_adc_read(priv, channel->channel, val); + if (ret) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = priv->scale_val; + *val2 = priv->scale_val2; + + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; + } +} + +#define ADS131M_VOLTAGE_CHANNEL(num) \ + { \ + .type = IIO_VOLTAGE, \ + .differential = 1, \ + .indexed = 1, \ + .channel = (num), \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + } + +static const struct iio_chan_spec ads131m02_channels[] = { + ADS131M_VOLTAGE_CHANNEL(0), + ADS131M_VOLTAGE_CHANNEL(1), +}; + +static const struct iio_chan_spec ads131m03_channels[] = { + ADS131M_VOLTAGE_CHANNEL(0), + ADS131M_VOLTAGE_CHANNEL(1), + ADS131M_VOLTAGE_CHANNEL(2), +}; + +static const struct iio_chan_spec ads131m04_channels[] = { + ADS131M_VOLTAGE_CHANNEL(0), + ADS131M_VOLTAGE_CHANNEL(1), + ADS131M_VOLTAGE_CHANNEL(2), + ADS131M_VOLTAGE_CHANNEL(3), +}; + +static const struct iio_chan_spec ads131m06_channels[] = { + ADS131M_VOLTAGE_CHANNEL(0), + ADS131M_VOLTAGE_CHANNEL(1), + ADS131M_VOLTAGE_CHANNEL(2), + ADS131M_VOLTAGE_CHANNEL(3), + ADS131M_VOLTAGE_CHANNEL(4), + ADS131M_VOLTAGE_CHANNEL(5), +}; + +static const struct iio_chan_spec ads131m08_channels[] = { + ADS131M_VOLTAGE_CHANNEL(0), + ADS131M_VOLTAGE_CHANNEL(1), + ADS131M_VOLTAGE_CHANNEL(2), + ADS131M_VOLTAGE_CHANNEL(3), + ADS131M_VOLTAGE_CHANNEL(4), + ADS131M_VOLTAGE_CHANNEL(5), + ADS131M_VOLTAGE_CHANNEL(6), + ADS131M_VOLTAGE_CHANNEL(7), +}; + +static const struct ads131m_configuration ads131m02_config = { + .channels = ads131m02_channels, + .num_channels = ARRAY_SIZE(ads131m02_channels), + .reset_ack = 0xff22, + .name = "ads131m02", +}; + +static const struct ads131m_configuration ads131m03_config = { + .channels = ads131m03_channels, + .num_channels = ARRAY_SIZE(ads131m03_channels), + .reset_ack = 0xff23, + .name = "ads131m03", +}; + +static const struct ads131m_configuration ads131m04_config = { + .channels = ads131m04_channels, + .num_channels = ARRAY_SIZE(ads131m04_channels), + .reset_ack = 0xff24, + .name = "ads131m04", +}; + +static const struct ads131m_configuration ads131m06_config = { + .channels = ads131m06_channels, + .num_channels = ARRAY_SIZE(ads131m06_channels), + .reset_ack = 0xff26, + .supports_extref = true, + .supports_xtal = true, + .name = "ads131m06", +}; + +static const struct ads131m_configuration ads131m08_config = { + .channels = ads131m08_channels, + .num_channels = ARRAY_SIZE(ads131m08_channels), + .reset_ack = 0xff28, + .supports_extref = true, + .supports_xtal = true, + .name = "ads131m08", +}; + +static const struct iio_info ads131m_info = { + .read_raw = ads131m_read_raw, +}; + +/* + * Prepares the reusable SPI message structure for a full-duplex transfer. + * The ADS131M requires sending a command frame while simultaneously + * receiving the response/data frame from the previous command cycle. + * + * This message is optimized for the primary data acquisition workflow: + * sending a single-word command (like NULL) and receiving a full data + * frame (Response + N*Channels + CRC). + * + * This message is sized for a full data frame and is reused for all + * command/data cycles. The driver does not implement variable-length SPI + * messages. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_prepare_message(struct ads131m_priv *priv) +{ + struct iio_dev *indio_dev = priv->indio_dev; + struct device *dev = &priv->spi->dev; + int ret; + + priv->xfer.tx_buf = priv->tx_buffer; + priv->xfer.rx_buf = priv->rx_buffer; + priv->xfer.len = ADS131M_FRAME_BYTES(indio_dev->num_channels); + spi_message_init_with_transfers(&priv->msg, &priv->xfer, 1); + + ret = devm_spi_optimize_message(dev, priv->spi, &priv->msg); + if (ret) + return dev_err_probe(dev, ret, "failed to optimize SPI message\n"); + + return 0; +} + +/** + * ads131m_hw_reset - Pulses the optional hardware reset. + * @priv: Device private data structure. + * @rstc: Reset control for the /RESET line. + * + * Pulses the /RESET line to perform a hardware reset and waits the + * required t_REGACQ time for the device to be ready. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_hw_reset(struct ads131m_priv *priv, + struct reset_control *rstc) +{ + struct device *dev = &priv->spi->dev; + int ret; + + /* + * Manually pulse the reset line using the framework. + * The reset-gpio provider does not implement the .reset op, + * so we must use .assert and .deassert. + */ + ret = reset_control_assert(rstc); + if (ret) + return dev_err_probe(dev, ret, "Failed to assert reset\n"); + + /* Datasheet: Hold /RESET low for > 2 f_CLKIN cycles. 1us is ample. */ + fsleep(1); + + ret = reset_control_deassert(rstc); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to deassert reset\n"); + + /* Wait t_REGACQ (5us) for registers to be accessible */ + fsleep(ADS131M_RESET_DELAY_US); + + return 0; +} + +/** + * ads131m_sw_reset - Issues a software RESET and verifies ACK. + * @priv: Device private data structure. + * + * This function sends a RESET command (with Input CRC), waits t_REGACQ, + * reads back the RESET ACK, and then sends a final NULL to check for + * any input CRC errors. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_sw_reset(struct ads131m_priv *priv) +{ + u16 expected_ack = priv->config->reset_ack; + struct device *dev = &priv->spi->dev; + u16 response; + int ret; + + guard(mutex)(&priv->lock); + + ret = ads131m_tx_frame_unlocked(priv, ADS131M_CMD_RESET); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to send RESET command\n"); + + /* Wait t_REGACQ (5us) for device to be ready after reset */ + fsleep(ADS131M_RESET_DELAY_US); + + /* Cycle 2: Send NULL + CRC to retrieve the response to the RESET */ + ret = ads131m_rx_frame_unlocked(priv); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read RESET ACK\n"); + + response = get_unaligned_be16(&priv->rx_buffer[0]); + + /* Check against the device-specific ACK value */ + if (response != expected_ack) + return dev_err_probe(dev, -EIO, + "RESET ACK mismatch, got 0x%04x, expected 0x%04x\n", + response, expected_ack); + + /* Cycle 3: Check STATUS for Input CRC error on the RESET command. */ + return ads131m_check_status_crc_err(priv); +} + +/** + * ads131m_reset - Resets the device using hardware or software. + * @priv: Device private data structure. + * @rstc: Optional reset control, or NULL for software reset. + * + * This function performs a hardware reset if supported (rstc provided), + * otherwise it issues a software RESET command via SPI. + * + * Note: The software reset path also validates the device's reset + * acknowledgment against the expected ID for the compatible string. + * The hardware reset path bypasses this ID check. + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_reset(struct ads131m_priv *priv, struct reset_control *rstc) +{ + if (rstc) + return ads131m_hw_reset(priv, rstc); + + return ads131m_sw_reset(priv); +} + +static int ads131m_power_init(struct ads131m_priv *priv) +{ + static const char * const supply_ids[] = { "avdd", "dvdd" }; + struct device *dev = &priv->spi->dev; + int vref_uV; + int ret; + + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(supply_ids), supply_ids); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to enable regulators\n"); + + /* Default to Internal 1.2V reference: 1200mV / 2^23 */ + priv->scale_val = ADS131M_VREF_INTERNAL_mV; + priv->scale_val2 = BIT(ADS131M_CODE_BITS); + + if (!priv->config->supports_extref) + return 0; + + ret = devm_regulator_get_enable_read_voltage(dev, "refin"); + if (ret < 0 && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to get refin supply\n"); + + if (ret == 0) + return dev_err_probe(dev, -EINVAL, "refin supply reports 0V\n"); + + if (ret == -ENODEV) + return 0; + + vref_uV = ret; + + /* + * External reference found: Scale(mV) = (vref_uV * 0.96) / 1000 + * The denominator is 100 * 2^23 because of the 0.96 factor (96/100). + */ + priv->scale_val = div_s64((s64)vref_uV * ADS131M_EXTREF_SCALE_NUM, 1000); + priv->scale_val2 = ADS131M_EXTREF_SCALE_DEN * BIT(ADS131M_CODE_BITS); + priv->use_external_ref = true; + + return 0; +} + +/** + * ads131m_hw_init - Initialize the ADC hardware. + * @priv: Device private data structure. + * @rstc: Optional reset control, or NULL for software reset. + * @is_xtal: True if 'clock-names' is "xtal", false if "clkin". + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_hw_init(struct ads131m_priv *priv, + struct reset_control *rstc, bool is_xtal) +{ + struct device *dev = &priv->spi->dev; + u16 mode_clear, mode_set; + int ret; + + ret = ads131m_reset(priv, rstc); + if (ret < 0) + return ret; + + /* + * Configure CLOCK register (0x03) based on DT properties. + * This register only needs configuration for 32-pin (M06/M08) + * variants, as the configurable bits (XTAL_DIS, EXTREF_EN) + * are reserved on 20-pin (M02/M03/M04) variants. + */ + if (priv->config->supports_xtal || priv->config->supports_extref) { + u16 clk_set = 0; + + if (priv->config->supports_xtal && !is_xtal) + clk_set |= ADS131M_CLOCK_XTAL_DIS; + + if (priv->config->supports_extref && priv->use_external_ref) + clk_set |= ADS131M_CLOCK_EXTREF_EN; + + ret = ads131m_rmw_reg(priv, ADS131M_REG_CLOCK, + ADS131M_CLOCK_EXTREF_EN | ADS131M_CLOCK_XTAL_DIS, + clk_set); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to configure CLOCK register\n"); + } + + /* + * The RESET command sets all registers to default, which means: + * 1. The RESET bit (Bit 10) in MODE is set to '1'. + * 2. The CRC_TYPE bit (Bit 11) in MODE is '0' (CCITT). + * 3. The RX_CRC_EN bit (Bit 12) in MODE is '0' (Disabled). + * + * We must: + * 1. Clear the RESET bit. + * 2. Enable Input CRC (RX_CRC_EN). + * 3. Explicitly clear the ANSI CRC bit (for certainty). + */ + mode_clear = ADS131M_MODE_CRC_TYPE_ANSI | ADS131M_MODE_RESET_FLAG; + mode_set = ADS131M_MODE_RX_CRC_EN; + + ret = ads131m_rmw_reg(priv, ADS131M_REG_MODE, mode_clear, mode_set); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to configure MODE register\n"); + + return 0; +} + +/** + * ads131m_parse_clock - enable clock and detect "xtal" selection + * @priv: Device private data structure. + * @is_xtal: result flag (true if "xtal", false if default "clkin") + * + * Return: 0 on success, or a negative error code. + */ +static int ads131m_parse_clock(struct ads131m_priv *priv, bool *is_xtal) +{ + struct device *dev = &priv->spi->dev; + struct clk *clk; + int ret; + + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR_OR_NULL(clk)) { + if (IS_ERR(clk)) + ret = PTR_ERR(clk); + else + ret = -ENODEV; + + return dev_err_probe(dev, ret, "clk get enabled failed\n"); + } + + ret = device_property_match_string(dev, "clock-names", "xtal"); + if (ret > 0) + return dev_err_probe(dev, -EINVAL, + "'xtal' must be the only or first clock name"); + + if (ret < 0 && ret != -ENODATA) + return dev_err_probe(dev, ret, + "failed to read 'clock-names' property"); + + if (ret == 0 && !priv->config->supports_xtal) + return dev_err_probe(dev, -EINVAL, + "'xtal' clock not supported on this device"); + + *is_xtal = !ret; + + return 0; +} + +static int ads131m_probe(struct spi_device *spi) +{ + const struct ads131m_configuration *config; + struct device *dev = &spi->dev; + struct reset_control *rstc; + struct iio_dev *indio_dev; + struct ads131m_priv *priv; + bool is_xtal; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); + if (!indio_dev) + return -ENOMEM; + + priv = iio_priv(indio_dev); + priv->indio_dev = indio_dev; + priv->spi = spi; + + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->info = &ads131m_info; + + config = spi_get_device_match_data(spi); + + priv->config = config; + indio_dev->name = config->name; + indio_dev->channels = config->channels; + indio_dev->num_channels = config->num_channels; + + rstc = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(rstc)) + return dev_err_probe(dev, PTR_ERR(rstc), + "Failed to get reset controller\n"); + + ret = devm_mutex_init(dev, &priv->lock); + if (ret < 0) + return ret; + + ret = ads131m_prepare_message(priv); + if (ret < 0) + return ret; + + ret = ads131m_power_init(priv); + if (ret < 0) + return ret; + + /* Power must be applied and stable before the clock is enabled. */ + ret = ads131m_parse_clock(priv, &is_xtal); + if (ret < 0) + return ret; + + ret = ads131m_hw_init(priv, rstc, is_xtal); + if (ret < 0) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id ads131m_of_match[] = { + { .compatible = "ti,ads131m02", .data = &ads131m02_config }, + { .compatible = "ti,ads131m03", .data = &ads131m03_config }, + { .compatible = "ti,ads131m04", .data = &ads131m04_config }, + { .compatible = "ti,ads131m06", .data = &ads131m06_config }, + { .compatible = "ti,ads131m08", .data = &ads131m08_config }, + { } +}; +MODULE_DEVICE_TABLE(of, ads131m_of_match); + +static const struct spi_device_id ads131m_id[] = { + { "ads131m02", (kernel_ulong_t)&ads131m02_config }, + { "ads131m03", (kernel_ulong_t)&ads131m03_config }, + { "ads131m04", (kernel_ulong_t)&ads131m04_config }, + { "ads131m06", (kernel_ulong_t)&ads131m06_config }, + { "ads131m08", (kernel_ulong_t)&ads131m08_config }, + { } +}; +MODULE_DEVICE_TABLE(spi, ads131m_id); + +static struct spi_driver ads131m_driver = { + .driver = { + .name = "ads131m02", + .of_match_table = ads131m_of_match, + }, + .probe = ads131m_probe, + .id_table = ads131m_id, +}; +module_spi_driver(ads131m_driver); + +MODULE_AUTHOR("David Jander "); +MODULE_DESCRIPTION("Texas Instruments ADS131M02 ADC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/adc/ti-tsc2046.c b/drivers/iio/adc/ti-tsc2046.c index 8eb717b11cff..aba4b10a17ac 100644 --- a/drivers/iio/adc/ti-tsc2046.c +++ b/drivers/iio/adc/ti-tsc2046.c @@ -290,15 +290,13 @@ static int tsc2046_adc_read_one(struct tsc2046_adc_priv *priv, int ch_idx, if (sizeof(struct tsc2046_adc_atom) * max_count > PAGE_SIZE) return -ENOSPC; - struct tsc2046_adc_atom *tx_buf __free(kfree) = kcalloc(max_count, - sizeof(*tx_buf), - GFP_KERNEL); + struct tsc2046_adc_atom *tx_buf __free(kfree) = kzalloc_objs(*tx_buf, + max_count); if (!tx_buf) return -ENOMEM; - struct tsc2046_adc_atom *rx_buf __free(kfree) = kcalloc(max_count, - sizeof(*rx_buf), - GFP_KERNEL); + struct tsc2046_adc_atom *rx_buf __free(kfree) = kzalloc_objs(*rx_buf, + max_count); if (!rx_buf) return -ENOMEM; diff --git a/drivers/iio/amplifiers/Kconfig b/drivers/iio/amplifiers/Kconfig index 55eb16b32f6c..a8a604863eed 100644 --- a/drivers/iio/amplifiers/Kconfig +++ b/drivers/iio/amplifiers/Kconfig @@ -36,6 +36,18 @@ config ADA4250 To compile this driver as a module, choose M here: the module will be called ada4250. +config ADL8113 + tristate "Analog Devices ADL8113 Low Noise Amplifier" + depends on GPIOLIB + help + Say yes here to build support for Analog Devices ADL8113 Low Noise + Amplifier with integrated bypass switches. The device supports four + operation modes controlled by GPIO pins: internal amplifier, + internal bypass, and two external bypass modes. + + To compile this driver as a module, choose M here: the + module will be called adl8113. + config HMC425 tristate "Analog Devices HMC425A and similar GPIO Gain Amplifiers" depends on GPIOLIB diff --git a/drivers/iio/amplifiers/Makefile b/drivers/iio/amplifiers/Makefile index 2126331129cf..0a76443be1aa 100644 --- a/drivers/iio/amplifiers/Makefile +++ b/drivers/iio/amplifiers/Makefile @@ -6,4 +6,5 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_AD8366) += ad8366.o obj-$(CONFIG_ADA4250) += ada4250.o +obj-$(CONFIG_ADL8113) += adl8113.o obj-$(CONFIG_HMC425) += hmc425a.o diff --git a/drivers/iio/amplifiers/adl8113.c b/drivers/iio/amplifiers/adl8113.c new file mode 100644 index 000000000000..b8a431b6616b --- /dev/null +++ b/drivers/iio/amplifiers/adl8113.c @@ -0,0 +1,269 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ADL8113 Low Noise Amplifier with integrated bypass switches + * + * Copyright 2025 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum adl8113_signal_path { + ADL8113_INTERNAL_AMP, + ADL8113_INTERNAL_BYPASS, + ADL8113_EXTERNAL_A, + ADL8113_EXTERNAL_B, +}; + +struct adl8113_gain_config { + enum adl8113_signal_path path; + int gain_db; +}; + +struct adl8113_state { + struct gpio_descs *gpios; + struct adl8113_gain_config *gain_configs; + unsigned int num_gain_configs; + enum adl8113_signal_path current_path; +}; + +static const char * const adl8113_supply_names[] = { + "vdd1", + "vss2", + "vdd2", +}; + +static int adl8113_set_path(struct adl8113_state *st, + enum adl8113_signal_path path) +{ + DECLARE_BITMAP(values, 2); + int ret; + + /* + * Determine GPIO values based on signal path. + * Va: bit 0, Vb: bit 1. + */ + switch (path) { + case ADL8113_INTERNAL_AMP: + bitmap_write(values, 0x00, 0, 2); + break; + case ADL8113_INTERNAL_BYPASS: + bitmap_write(values, 0x03, 0, 2); + break; + case ADL8113_EXTERNAL_A: + bitmap_write(values, 0x02, 0, 2); + break; + case ADL8113_EXTERNAL_B: + bitmap_write(values, 0x01, 0, 2); + break; + default: + return -EINVAL; + } + + ret = gpiod_set_array_value_cansleep(st->gpios->ndescs, st->gpios->desc, + st->gpios->info, values); + if (ret) + return ret; + + st->current_path = path; + return 0; +} + +static int adl8113_find_gain_config(struct adl8113_state *st, int gain_db) +{ + unsigned int i; + + for (i = 0; i < st->num_gain_configs; i++) { + if (st->gain_configs[i].gain_db == gain_db) + return i; + } + return -EINVAL; +} + +static const struct iio_chan_spec adl8113_channels[] = { + { + .type = IIO_VOLTAGE, + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_HARDWAREGAIN), + }, +}; + +static int adl8113_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct adl8113_state *st = iio_priv(indio_dev); + unsigned int i; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + /* Find current gain configuration */ + for (i = 0; i < st->num_gain_configs; i++) { + if (st->gain_configs[i].path == st->current_path) { + *val = st->gain_configs[i].gain_db; + *val2 = 0; + return IIO_VAL_INT_PLUS_MICRO_DB; + } + } + return -EINVAL; + default: + return -EINVAL; + } +} + +static int adl8113_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct adl8113_state *st = iio_priv(indio_dev); + int config_idx; + + switch (mask) { + case IIO_CHAN_INFO_HARDWAREGAIN: + if (val2 != 0) + return -EINVAL; + + config_idx = adl8113_find_gain_config(st, val); + if (config_idx < 0) + return config_idx; + + return adl8113_set_path(st, st->gain_configs[config_idx].path); + default: + return -EINVAL; + } +} + +static const struct iio_info adl8113_info = { + .read_raw = adl8113_read_raw, + .write_raw = adl8113_write_raw, +}; + +static int adl8113_init_gain_configs(struct device *dev, struct adl8113_state *st) +{ + int external_a_gain, external_b_gain; + unsigned int i; + + /* + * Allocate for all 4 possible paths: + * - Internal amp and bypass (always present) + * - External bypass A and B (optional if configured) + */ + st->gain_configs = devm_kcalloc(dev, 4, sizeof(*st->gain_configs), + GFP_KERNEL); + if (!st->gain_configs) + return -ENOMEM; + + /* Start filling the gain configurations with data */ + i = 0; + + /* Always include internal amplifier (14dB) */ + st->gain_configs[i++] = (struct adl8113_gain_config) { + .path = ADL8113_INTERNAL_AMP, + .gain_db = 14, + }; + + /* Always include internal bypass (-2dB insertion loss) */ + st->gain_configs[i++] = (struct adl8113_gain_config) { + .path = ADL8113_INTERNAL_BYPASS, + .gain_db = -2, + }; + + /* Add external bypass A if configured */ + if (!device_property_read_u32(dev, "adi,external-bypass-a-gain-db", + &external_a_gain)) { + st->gain_configs[i++] = (struct adl8113_gain_config) { + .path = ADL8113_EXTERNAL_A, + .gain_db = external_a_gain, + }; + } + + /* Add external bypass B if configured */ + if (!device_property_read_u32(dev, "adi,external-bypass-b-gain-db", + &external_b_gain)) { + st->gain_configs[i++] = (struct adl8113_gain_config) { + .path = ADL8113_EXTERNAL_B, + .gain_db = external_b_gain, + }; + } + + st->num_gain_configs = i; + + return 0; +} + +static int adl8113_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct adl8113_state *st; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->gpios = devm_gpiod_get_array(dev, "ctrl", GPIOD_OUT_LOW); + if (IS_ERR(st->gpios)) + return dev_err_probe(dev, PTR_ERR(st->gpios), + "failed to get control GPIOs\n"); + + if (st->gpios->ndescs != 2) + return dev_err_probe(dev, -EINVAL, + "expected 2 control GPIOs, got %u\n", + st->gpios->ndescs); + + ret = devm_regulator_bulk_get_enable(dev, + ARRAY_SIZE(adl8113_supply_names), + adl8113_supply_names); + if (ret) + return dev_err_probe(dev, ret, + "failed to get and enable supplies\n"); + + /* Initialize gain configurations from devicetree */ + ret = adl8113_init_gain_configs(dev, st); + if (ret) + return ret; + + /* Initialize to internal amplifier path (14dB) */ + ret = adl8113_set_path(st, ADL8113_INTERNAL_AMP); + if (ret) + return ret; + + indio_dev->info = &adl8113_info; + indio_dev->name = "adl8113"; + indio_dev->channels = adl8113_channels; + indio_dev->num_channels = ARRAY_SIZE(adl8113_channels); + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct of_device_id adl8113_of_match[] = { + { .compatible = "adi,adl8113" }, + { } +}; +MODULE_DEVICE_TABLE(of, adl8113_of_match); + +static struct platform_driver adl8113_driver = { + .driver = { + .name = "adl8113", + .of_match_table = adl8113_of_match, + }, + .probe = adl8113_probe, +}; +module_platform_driver(adl8113_driver); + +MODULE_AUTHOR("Antoniu Miclaus "); +MODULE_DESCRIPTION("Analog Devices ADL8113 Low Noise Amplifier"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c index f4ebff968493..0c266c216525 100644 --- a/drivers/iio/buffer/industrialio-buffer-cb.c +++ b/drivers/iio/buffer/industrialio-buffer-cb.c @@ -60,7 +60,7 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, return ERR_PTR(-EINVAL); } - cb_buff = kzalloc(sizeof(*cb_buff), GFP_KERNEL); + cb_buff = kzalloc_obj(*cb_buff); if (cb_buff == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/buffer/industrialio-buffer-dma.c b/drivers/iio/buffer/industrialio-buffer-dma.c index 7a7a9d37339b..1daac23087a7 100644 --- a/drivers/iio/buffer/industrialio-buffer-dma.c +++ b/drivers/iio/buffer/industrialio-buffer-dma.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -135,9 +136,8 @@ static void iio_dma_buffer_cleanup_worker(struct work_struct *work) struct iio_dma_buffer_block *block, *_block; LIST_HEAD(block_list); - spin_lock_irq(&iio_dma_buffer_dead_blocks_lock); - list_splice_tail_init(&iio_dma_buffer_dead_blocks, &block_list); - spin_unlock_irq(&iio_dma_buffer_dead_blocks_lock); + scoped_guard(spinlock_irq, &iio_dma_buffer_dead_blocks_lock) + list_splice_tail_init(&iio_dma_buffer_dead_blocks, &block_list); list_for_each_entry_safe(block, _block, &block_list, head) iio_buffer_block_release(&block->kref); @@ -147,13 +147,11 @@ static DECLARE_WORK(iio_dma_buffer_cleanup_work, iio_dma_buffer_cleanup_worker); static void iio_buffer_block_release_atomic(struct kref *kref) { struct iio_dma_buffer_block *block; - unsigned long flags; block = container_of(kref, struct iio_dma_buffer_block, kref); - spin_lock_irqsave(&iio_dma_buffer_dead_blocks_lock, flags); - list_add_tail(&block->head, &iio_dma_buffer_dead_blocks); - spin_unlock_irqrestore(&iio_dma_buffer_dead_blocks_lock, flags); + scoped_guard(spinlock_irqsave, &iio_dma_buffer_dead_blocks_lock) + list_add_tail(&block->head, &iio_dma_buffer_dead_blocks); schedule_work(&iio_dma_buffer_cleanup_work); } @@ -171,22 +169,20 @@ static struct iio_dma_buffer_queue *iio_buffer_to_queue(struct iio_buffer *buf) return container_of(buf, struct iio_dma_buffer_queue, buffer); } -static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( - struct iio_dma_buffer_queue *queue, size_t size, bool fileio) +static struct iio_dma_buffer_block * +iio_dma_buffer_alloc_block(struct iio_dma_buffer_queue *queue, size_t size, + bool fileio) { - struct iio_dma_buffer_block *block; - - block = kzalloc(sizeof(*block), GFP_KERNEL); + struct iio_dma_buffer_block *block __free(kfree) = + kzalloc_obj(*block); if (!block) return NULL; if (fileio) { block->vaddr = dma_alloc_coherent(queue->dev, PAGE_ALIGN(size), &block->phys_addr, GFP_KERNEL); - if (!block->vaddr) { - kfree(block); + if (!block->vaddr) return NULL; - } } block->fileio = fileio; @@ -201,7 +197,7 @@ static struct iio_dma_buffer_block *iio_dma_buffer_alloc_block( if (!fileio) atomic_inc(&queue->num_dmabufs); - return block; + return_ptr(block); } static void _iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) @@ -232,14 +228,12 @@ static void iio_dma_buffer_queue_wake(struct iio_dma_buffer_queue *queue) void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block) { struct iio_dma_buffer_queue *queue = block->queue; - unsigned long flags; bool cookie; cookie = dma_fence_begin_signalling(); - spin_lock_irqsave(&queue->list_lock, flags); - _iio_dma_buffer_block_done(block); - spin_unlock_irqrestore(&queue->list_lock, flags); + scoped_guard(spinlock_irqsave, &queue->list_lock) + _iio_dma_buffer_block_done(block); if (!block->fileio) iio_buffer_signal_dmabuf_done(block->fence, 0); @@ -261,25 +255,25 @@ EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_block_done, "IIO_DMA_BUFFER"); * hand the blocks back to the queue. */ void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, - struct list_head *list) + struct list_head *list) { struct iio_dma_buffer_block *block, *_block; - unsigned long flags; bool cookie; cookie = dma_fence_begin_signalling(); - spin_lock_irqsave(&queue->list_lock, flags); - list_for_each_entry_safe(block, _block, list, head) { - list_del(&block->head); - block->bytes_used = 0; - _iio_dma_buffer_block_done(block); + scoped_guard(spinlock_irqsave, &queue->list_lock) { + list_for_each_entry_safe(block, _block, list, head) { + list_del(&block->head); + block->bytes_used = 0; + _iio_dma_buffer_block_done(block); - if (!block->fileio) - iio_buffer_signal_dmabuf_done(block->fence, -EINTR); - iio_buffer_block_put_atomic(block); + if (!block->fileio) + iio_buffer_signal_dmabuf_done(block->fence, + -EINTR); + iio_buffer_block_put_atomic(block); + } } - spin_unlock_irqrestore(&queue->list_lock, flags); if (queue->fileio.enabled) queue->fileio.enabled = false; @@ -328,7 +322,6 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) struct iio_dma_buffer_block *block; bool try_reuse = false; size_t size; - int ret = 0; int i; /* @@ -339,13 +332,13 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) size = DIV_ROUND_UP(queue->buffer.bytes_per_datum * queue->buffer.length, 2); - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); queue->fileio.enabled = iio_dma_buffer_can_use_fileio(queue); /* If DMABUFs were created, disable fileio interface */ if (!queue->fileio.enabled) - goto out_unlock; + return 0; /* Allocations are page aligned */ if (PAGE_ALIGN(queue->fileio.block_size) == PAGE_ALIGN(size)) @@ -354,22 +347,22 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) queue->fileio.block_size = size; queue->fileio.active_block = NULL; - spin_lock_irq(&queue->list_lock); - for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { - block = queue->fileio.blocks[i]; + scoped_guard(spinlock_irq, &queue->list_lock) { + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + block = queue->fileio.blocks[i]; - /* If we can't re-use it free it */ - if (block && (!iio_dma_block_reusable(block) || !try_reuse)) - block->state = IIO_BLOCK_STATE_DEAD; + /* If we can't re-use it free it */ + if (block && (!iio_dma_block_reusable(block) || !try_reuse)) + block->state = IIO_BLOCK_STATE_DEAD; + } + + /* + * At this point all blocks are either owned by the core or + * marked as dead. This means we can reset the lists without + * having to fear corruption. + */ } - /* - * At this point all blocks are either owned by the core or marked as - * dead. This means we can reset the lists without having to fear - * corrution. - */ - spin_unlock_irq(&queue->list_lock); - INIT_LIST_HEAD(&queue->incoming); for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { @@ -388,10 +381,9 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) if (!block) { block = iio_dma_buffer_alloc_block(queue, size, true); - if (!block) { - ret = -ENOMEM; - goto out_unlock; - } + if (!block) + return -ENOMEM; + queue->fileio.blocks[i] = block; } @@ -415,10 +407,7 @@ int iio_dma_buffer_request_update(struct iio_buffer *buffer) } } -out_unlock: - mutex_unlock(&queue->lock); - - return ret; + return 0; } EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_request_update, "IIO_DMA_BUFFER"); @@ -426,13 +415,13 @@ static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue) { unsigned int i; - spin_lock_irq(&queue->list_lock); - for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { - if (!queue->fileio.blocks[i]) - continue; - queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; + scoped_guard(spinlock_irq, &queue->list_lock) { + for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { + if (!queue->fileio.blocks[i]) + continue; + queue->fileio.blocks[i]->state = IIO_BLOCK_STATE_DEAD; + } } - spin_unlock_irq(&queue->list_lock); INIT_LIST_HEAD(&queue->incoming); @@ -446,7 +435,7 @@ static void iio_dma_buffer_fileio_free(struct iio_dma_buffer_queue *queue) } static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue, - struct iio_dma_buffer_block *block) + struct iio_dma_buffer_block *block) { int ret; @@ -490,19 +479,17 @@ static void iio_dma_buffer_submit_block(struct iio_dma_buffer_queue *queue, * * This will allocate the DMA buffers and start the DMA transfers. */ -int iio_dma_buffer_enable(struct iio_buffer *buffer, - struct iio_dev *indio_dev) +int iio_dma_buffer_enable(struct iio_buffer *buffer, struct iio_dev *indio_dev) { struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); struct iio_dma_buffer_block *block, *_block; - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); queue->active = true; list_for_each_entry_safe(block, _block, &queue->incoming, head) { list_del(&block->head); iio_dma_buffer_submit_block(queue, block); } - mutex_unlock(&queue->lock); return 0; } @@ -516,24 +503,22 @@ EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_enable, "IIO_DMA_BUFFER"); * Needs to be called when the device that the buffer is attached to stops * sampling. Typically should be the iio_buffer_access_ops disable callback. */ -int iio_dma_buffer_disable(struct iio_buffer *buffer, - struct iio_dev *indio_dev) +int iio_dma_buffer_disable(struct iio_buffer *buffer, struct iio_dev *indio_dev) { struct iio_dma_buffer_queue *queue = iio_buffer_to_queue(buffer); - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); queue->active = false; if (queue->ops && queue->ops->abort) queue->ops->abort(queue); - mutex_unlock(&queue->lock); return 0; } EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_disable, "IIO_DMA_BUFFER"); static void iio_dma_buffer_enqueue(struct iio_dma_buffer_queue *queue, - struct iio_dma_buffer_block *block) + struct iio_dma_buffer_block *block) { if (block->state == IIO_BLOCK_STATE_DEAD) { iio_buffer_block_put(block); @@ -545,25 +530,22 @@ static void iio_dma_buffer_enqueue(struct iio_dma_buffer_queue *queue, } } -static struct iio_dma_buffer_block *iio_dma_buffer_dequeue( - struct iio_dma_buffer_queue *queue) +static struct iio_dma_buffer_block * +iio_dma_buffer_dequeue(struct iio_dma_buffer_queue *queue) { struct iio_dma_buffer_block *block; unsigned int idx; - spin_lock_irq(&queue->list_lock); + guard(spinlock_irq)(&queue->list_lock); idx = queue->fileio.next_dequeue; block = queue->fileio.blocks[idx]; - if (block->state == IIO_BLOCK_STATE_DONE) { - idx = (idx + 1) % ARRAY_SIZE(queue->fileio.blocks); - queue->fileio.next_dequeue = idx; - } else { - block = NULL; - } + if (block->state != IIO_BLOCK_STATE_DONE) + return NULL; - spin_unlock_irq(&queue->list_lock); + idx = (idx + 1) % ARRAY_SIZE(queue->fileio.blocks); + queue->fileio.next_dequeue = idx; return block; } @@ -579,14 +561,13 @@ static int iio_dma_buffer_io(struct iio_buffer *buffer, size_t n, if (n < buffer->bytes_per_datum) return -EINVAL; - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); if (!queue->fileio.active_block) { block = iio_dma_buffer_dequeue(queue); - if (block == NULL) { - ret = 0; - goto out_unlock; - } + if (!block) + return 0; + queue->fileio.pos = 0; queue->fileio.active_block = block; } else { @@ -602,10 +583,8 @@ static int iio_dma_buffer_io(struct iio_buffer *buffer, size_t n, ret = copy_from_user(addr, user_buffer, n); else ret = copy_to_user(user_buffer, addr, n); - if (ret) { - ret = -EFAULT; - goto out_unlock; - } + if (ret) + return -EFAULT; queue->fileio.pos += n; @@ -614,12 +593,7 @@ static int iio_dma_buffer_io(struct iio_buffer *buffer, size_t n, iio_dma_buffer_enqueue(queue, block); } - ret = n; - -out_unlock: - mutex_unlock(&queue->lock); - - return ret; + return n; } /** @@ -677,23 +651,19 @@ size_t iio_dma_buffer_usage(struct iio_buffer *buf) * but won't increase since all blocks are in use. */ - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); if (queue->fileio.active_block) data_available += queue->fileio.active_block->size; - spin_lock_irq(&queue->list_lock); + guard(spinlock_irq)(&queue->list_lock); for (i = 0; i < ARRAY_SIZE(queue->fileio.blocks); i++) { block = queue->fileio.blocks[i]; - if (block != queue->fileio.active_block - && block->state == IIO_BLOCK_STATE_DONE) + if (block != queue->fileio.active_block && block->state == IIO_BLOCK_STATE_DONE) data_available += block->size; } - spin_unlock_irq(&queue->list_lock); - mutex_unlock(&queue->lock); - return data_available; } EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_usage, "IIO_DMA_BUFFER"); @@ -764,7 +734,7 @@ int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer, bool cookie; int ret; - WARN_ON(!mutex_is_locked(&queue->lock)); + lockdep_assert_held(&queue->lock); cookie = dma_fence_begin_signalling(); @@ -854,8 +824,8 @@ EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_set_length, "IIO_DMA_BUFFER"); * should refer to the device that will perform the DMA to ensure that * allocations are done from a memory region that can be accessed by the device. */ -int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, - struct device *dev, const struct iio_dma_buffer_ops *ops) +void iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, struct device *dev, + const struct iio_dma_buffer_ops *ops) { iio_buffer_init(&queue->buffer); queue->buffer.length = PAGE_SIZE; @@ -867,8 +837,6 @@ int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, mutex_init(&queue->lock); spin_lock_init(&queue->list_lock); - - return 0; } EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_init, "IIO_DMA_BUFFER"); @@ -881,12 +849,10 @@ EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_init, "IIO_DMA_BUFFER"); */ void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue) { - mutex_lock(&queue->lock); + guard(mutex)(&queue->lock); iio_dma_buffer_fileio_free(queue); queue->ops = NULL; - - mutex_unlock(&queue->lock); } EXPORT_SYMBOL_NS_GPL(iio_dma_buffer_exit, "IIO_DMA_BUFFER"); diff --git a/drivers/iio/buffer/industrialio-buffer-dmaengine.c b/drivers/iio/buffer/industrialio-buffer-dmaengine.c index 27dd56334345..98acce909854 100644 --- a/drivers/iio/buffer/industrialio-buffer-dmaengine.c +++ b/drivers/iio/buffer/industrialio-buffer-dmaengine.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -39,27 +40,24 @@ struct dmaengine_buffer { size_t max_size; }; -static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer( - struct iio_buffer *buffer) +static struct dmaengine_buffer *iio_buffer_to_dmaengine_buffer(struct iio_buffer *buffer) { return container_of(buffer, struct dmaengine_buffer, queue.buffer); } static void iio_dmaengine_buffer_block_done(void *data, - const struct dmaengine_result *result) + const struct dmaengine_result *result) { struct iio_dma_buffer_block *block = data; - unsigned long flags; - spin_lock_irqsave(&block->queue->list_lock, flags); - list_del(&block->head); - spin_unlock_irqrestore(&block->queue->list_lock, flags); + scoped_guard(spinlock_irqsave, &block->queue->list_lock) + list_del(&block->head); block->bytes_used -= result->residue; iio_dma_buffer_block_done(block); } static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, - struct iio_dma_buffer_block *block) + struct iio_dma_buffer_block *block) { struct dmaengine_buffer *dmaengine_buffer = iio_buffer_to_dmaengine_buffer(&queue->buffer); @@ -131,9 +129,8 @@ static int iio_dmaengine_buffer_submit_block(struct iio_dma_buffer_queue *queue, if (dma_submit_error(cookie)) return dma_submit_error(cookie); - spin_lock_irq(&dmaengine_buffer->queue.list_lock); - list_add_tail(&block->head, &dmaengine_buffer->active); - spin_unlock_irq(&dmaengine_buffer->queue.list_lock); + scoped_guard(spinlock_irq, &dmaengine_buffer->queue.list_lock) + list_add_tail(&block->head, &dmaengine_buffer->active); dma_async_issue_pending(dmaengine_buffer->chan); @@ -189,7 +186,7 @@ static const struct iio_dma_buffer_ops iio_dmaengine_default_ops = { }; static ssize_t iio_dmaengine_buffer_get_length_align(struct device *dev, - struct device_attribute *attr, char *buf) + struct device_attribute *attr, char *buf) { struct iio_buffer *buffer = to_iio_dev_attr(attr)->buffer; struct dmaengine_buffer *dmaengine_buffer = @@ -227,7 +224,7 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct dma_chan *chan) if (ret < 0) return ERR_PTR(ret); - dmaengine_buffer = kzalloc(sizeof(*dmaengine_buffer), GFP_KERNEL); + dmaengine_buffer = kzalloc_obj(*dmaengine_buffer); if (!dmaengine_buffer) return ERR_PTR(-ENOMEM); @@ -248,7 +245,7 @@ static struct iio_buffer *iio_dmaengine_buffer_alloc(struct dma_chan *chan) dmaengine_buffer->max_size = dma_get_max_seg_size(chan->device->dev); iio_dma_buffer_init(&dmaengine_buffer->queue, chan->device->dev, - &iio_dmaengine_default_ops); + &iio_dmaengine_default_ops); dmaengine_buffer->queue.buffer.attrs = iio_dmaengine_buffer_attrs; dmaengine_buffer->queue.buffer.access = &iio_dmaengine_buffer_ops; diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c index 526b2a8d725d..cb771ef8eeb3 100644 --- a/drivers/iio/buffer/industrialio-hw-consumer.c +++ b/drivers/iio/buffer/industrialio-hw-consumer.c @@ -60,7 +60,7 @@ static struct hw_consumer_buffer *iio_hw_consumer_get_buffer( return buf; } - buf = kzalloc(struct_size(buf, scan_mask, mask_longs), GFP_KERNEL); + buf = kzalloc_flex(*buf, scan_mask, mask_longs); if (!buf) return NULL; @@ -87,7 +87,7 @@ struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) struct iio_channel *chan; int ret; - hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); + hwc = kzalloc_obj(*hwc); if (!hwc) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/buffer/kfifo_buf.c b/drivers/iio/buffer/kfifo_buf.c index 38034c8bcc04..a6ff9085b8a2 100644 --- a/drivers/iio/buffer/kfifo_buf.c +++ b/drivers/iio/buffer/kfifo_buf.c @@ -204,7 +204,7 @@ struct iio_buffer *iio_kfifo_allocate(void) { struct iio_kfifo *kf; - kf = kzalloc(sizeof(*kf), GFP_KERNEL); + kf = kzalloc_obj(*kf); if (!kf) return NULL; diff --git a/drivers/iio/chemical/bme680_core.c b/drivers/iio/chemical/bme680_core.c index 70f81c4a96ba..24e0b59e2fdf 100644 --- a/drivers/iio/chemical/bme680_core.c +++ b/drivers/iio/chemical/bme680_core.c @@ -613,7 +613,7 @@ static int bme680_wait_for_eoc(struct bme680_data *data) * + heater duration */ int wait_eoc_us = ((data->oversampling_temp + data->oversampling_press + - data->oversampling_humid) * 1936) + (477 * 4) + + data->oversampling_humid) * 1963) + (477 * 4) + (477 * 5) + 1000 + (data->heater_dur * 1000); fsleep(wait_eoc_us); diff --git a/drivers/iio/chemical/ens160_core.c b/drivers/iio/chemical/ens160_core.c index 86bde4a91bf7..bbc96c4c6283 100644 --- a/drivers/iio/chemical/ens160_core.c +++ b/drivers/iio/chemical/ens160_core.c @@ -316,12 +316,9 @@ static int ens160_setup_trigger(struct iio_dev *indio_dev, int irq) indio_dev->trig = iio_trigger_get(trig); - ret = devm_request_threaded_irq(dev, irq, - iio_trigger_generic_data_rdy_poll, - NULL, - IRQF_ONESHOT, - indio_dev->name, - indio_dev->trig); + ret = devm_request_irq(dev, irq, iio_trigger_generic_data_rdy_poll, + IRQF_NO_THREAD, indio_dev->name, + indio_dev->trig); if (ret) return dev_err_probe(dev, ret, "failed to request irq\n"); diff --git a/drivers/iio/chemical/scd4x.c b/drivers/iio/chemical/scd4x.c index 0fd839176e26..23a326fb62a7 100644 --- a/drivers/iio/chemical/scd4x.c +++ b/drivers/iio/chemical/scd4x.c @@ -59,6 +59,8 @@ enum scd4x_channel_idx { SCD4X_CO2, SCD4X_TEMP, SCD4X_HR, + /* kernel timestamp, at the end of buffer */ + SCD4X_TS, }; struct scd4x_state { @@ -615,6 +617,7 @@ static const struct iio_chan_spec scd4x_channels[] = { .endianness = IIO_CPU, }, }, + IIO_CHAN_SOFT_TIMESTAMP(SCD4X_TS), }; static int scd4x_suspend(struct device *dev) diff --git a/drivers/iio/chemical/sps30_i2c.c b/drivers/iio/chemical/sps30_i2c.c index f692c089d17b..c92f04990c34 100644 --- a/drivers/iio/chemical/sps30_i2c.c +++ b/drivers/iio/chemical/sps30_i2c.c @@ -171,7 +171,7 @@ static int sps30_i2c_read_meas(struct sps30_state *state, __be32 *meas, size_t n if (!sps30_i2c_meas_ready(state)) return -ETIMEDOUT; - return sps30_i2c_command(state, SPS30_I2C_READ_MEAS, NULL, 0, meas, sizeof(num) * num); + return sps30_i2c_command(state, SPS30_I2C_READ_MEAS, NULL, 0, meas, sizeof(*meas) * num); } static int sps30_i2c_clean_fan(struct sps30_state *state) diff --git a/drivers/iio/chemical/sps30_serial.c b/drivers/iio/chemical/sps30_serial.c index 008bc88590f3..a5e6bc08d5fd 100644 --- a/drivers/iio/chemical/sps30_serial.c +++ b/drivers/iio/chemical/sps30_serial.c @@ -303,7 +303,7 @@ static int sps30_serial_read_meas(struct sps30_state *state, __be32 *meas, size_ if (msleep_interruptible(1000)) return -EINTR; - ret = sps30_serial_command(state, SPS30_SERIAL_READ_MEAS, NULL, 0, meas, num * sizeof(num)); + ret = sps30_serial_command(state, SPS30_SERIAL_READ_MEAS, NULL, 0, meas, num * sizeof(*meas)); if (ret < 0) return ret; /* if measurements aren't ready sensor returns empty frame */ diff --git a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c index 9ac80e4b7d75..5133755c2ea6 100644 --- a/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c +++ b/drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c @@ -188,11 +188,8 @@ int cros_ec_sensors_push_data(struct iio_dev *indio_dev, /* * Ignore samples if the buffer is not set: it is needed if the ODR is * set but the buffer is not enabled yet. - * - * Note: iio_device_claim_buffer_mode() returns -EBUSY if the buffer - * is not enabled. */ - if (iio_device_claim_buffer_mode(indio_dev) < 0) + if (!iio_device_try_claim_buffer_mode(indio_dev)) return 0; out = (s16 *)st->samples; @@ -444,14 +441,14 @@ static ssize_t cros_ec_sensors_calibrate(struct iio_dev *indio_dev, ret = kstrtobool(buf, &calibrate); if (ret < 0) return ret; - if (!calibrate) - return -EINVAL; mutex_lock(&st->cmd_lock); st->param.cmd = MOTIONSENSE_CMD_PERFORM_CALIB; + st->param.perform_calib.enable = calibrate; ret = cros_ec_motion_send_host_cmd(st, 0); if (ret != 0) { - dev_warn(&indio_dev->dev, "Unable to calibrate sensor\n"); + dev_warn(&indio_dev->dev, "Unable to calibrate sensor: %d\n", + ret); } else { /* Save values */ for (i = CROS_EC_SENSOR_X; i < CROS_EC_SENSOR_MAX_AXIS; i++) diff --git a/drivers/iio/common/ssp_sensors/ssp_spi.c b/drivers/iio/common/ssp_sensors/ssp_spi.c index b7f093d7345b..6c81c0385fb5 100644 --- a/drivers/iio/common/ssp_sensors/ssp_spi.c +++ b/drivers/iio/common/ssp_sensors/ssp_spi.c @@ -77,7 +77,7 @@ static struct ssp_msg *ssp_create_msg(u8 cmd, u16 len, u16 opt, u32 data) struct ssp_msg_header h; struct ssp_msg *msg; - msg = kzalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc_obj(*msg); if (!msg) return NULL; diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig index 7cd3caec1262..db9f5c711b3d 100644 --- a/drivers/iio/dac/Kconfig +++ b/drivers/iio/dac/Kconfig @@ -482,6 +482,19 @@ config MAX517 This driver can also be built as a module. If so, the module will be called max517. +config MAX22007 + tristate "Analog Devices MAX22007 DAC Driver" + depends on SPI + select REGMAP_SPI + select CRC8 + help + Say Y here if you want to build a driver for Analog Devices MAX22007. + + MAX22007 is a quad-channel, 12-bit, voltage-output digital to + analog converter (DAC) with SPI interface. + + If compiled as a module, it will be called max22007. + config MAX5522 tristate "Maxim MAX5522 DAC driver" depends on SPI_MASTER @@ -524,6 +537,26 @@ config MCP4728 To compile this driver as a module, choose M here: the module will be called mcp4728. +config MCP47FEB02 + tristate "MCP47F(E/V)B01/02/04/08/11/12/14/18/21/22/24/28 DAC driver" + depends on I2C + help + Say yes here if you want to build the driver for the Microchip: + - 8-bit DAC: + MCP47FEB01, MCP47FEB02, MCP47FEB04, MCP47FEB08, + MCP47FVB01, MCP47FVB02, MCP47FVB04, MCP47FVB08 + - 10-bit DAC: + MCP47FEB11, MCP47FEB12, MCP47FEB14, MCP47FEB18, + MCP47FVB11, MCP47FVB12, MCP47FVB14, MCP47FVB18 + - 12-bit DAC: + MCP47FEB21, MCP47FEB22, MCP47FEB24, MCP47FEB28, + MCP47FVB21, MCP47FVB22, MCP47FVB24, MCP47FVB28 + having 1 to 8 channels, 8/10/12-bit digital-to-analog converter + (DAC) with I2C interface. + + To compile this driver as a module, choose M here: the module + will be called mcp47feb02. + config MCP4821 tristate "MCP4801/02/11/12/21/22 DAC driver" depends on SPI diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile index e6ac4c67e337..2a80bbf4e80a 100644 --- a/drivers/iio/dac/Makefile +++ b/drivers/iio/dac/Makefile @@ -48,10 +48,12 @@ obj-$(CONFIG_LTC2664) += ltc2664.o obj-$(CONFIG_LTC2688) += ltc2688.o obj-$(CONFIG_M62332) += m62332.o obj-$(CONFIG_MAX517) += max517.o +obj-$(CONFIG_MAX22007) += max22007.o obj-$(CONFIG_MAX5522) += max5522.o obj-$(CONFIG_MAX5821) += max5821.o obj-$(CONFIG_MCP4725) += mcp4725.o obj-$(CONFIG_MCP4728) += mcp4728.o +obj-$(CONFIG_MCP47FEB02) += mcp47feb02.o obj-$(CONFIG_MCP4821) += mcp4821.o obj-$(CONFIG_MCP4922) += mcp4922.o obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o diff --git a/drivers/iio/dac/ad5360.c b/drivers/iio/dac/ad5360.c index 8271849b1c83..bd32fa57b1d7 100644 --- a/drivers/iio/dac/ad5360.c +++ b/drivers/iio/dac/ad5360.c @@ -439,8 +439,8 @@ static int ad5360_alloc_channels(struct iio_dev *indio_dev) struct iio_chan_spec *channels; unsigned int i; - channels = kcalloc(st->chip_info->num_channels, - sizeof(struct iio_chan_spec), GFP_KERNEL); + channels = kzalloc_objs(struct iio_chan_spec, + st->chip_info->num_channels); if (!channels) return -ENOMEM; diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 0d525272a8a8..9cc895bbe51a 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -885,34 +885,35 @@ static const struct regmap_config axi_dac_regmap_config = { static int axi_dac_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; struct axi_dac_state *st; void __iomem *base; unsigned int ver; struct clk *clk; int ret; - st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL); + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; - st->info = device_get_match_data(&pdev->dev); + st->info = device_get_match_data(dev); if (!st->info) return -ENODEV; - clk = devm_clk_get_enabled(&pdev->dev, "s_axi_aclk"); + clk = devm_clk_get_enabled(dev, "s_axi_aclk"); if (IS_ERR(clk)) { /* Backward compat., old fdt versions without clock-names. */ - clk = devm_clk_get_enabled(&pdev->dev, NULL); + clk = devm_clk_get_enabled(dev, NULL); if (IS_ERR(clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(clk), - "failed to get clock\n"); + return dev_err_probe(dev, PTR_ERR(clk), + "failed to get clock\n"); } if (st->info->has_dac_clk) { struct clk *dac_clk; - dac_clk = devm_clk_get_enabled(&pdev->dev, "dac_clk"); + dac_clk = devm_clk_get_enabled(dev, "dac_clk"); if (IS_ERR(dac_clk)) - return dev_err_probe(&pdev->dev, PTR_ERR(dac_clk), + return dev_err_probe(dev, PTR_ERR(dac_clk), "failed to get dac_clk clock\n"); /* We only care about the streaming mode rate */ @@ -923,11 +924,10 @@ static int axi_dac_probe(struct platform_device *pdev) if (IS_ERR(base)) return PTR_ERR(base); - st->dev = &pdev->dev; - st->regmap = devm_regmap_init_mmio(&pdev->dev, base, - &axi_dac_regmap_config); + st->dev = dev; + st->regmap = devm_regmap_init_mmio(dev, base, &axi_dac_regmap_config); if (IS_ERR(st->regmap)) - return dev_err_probe(&pdev->dev, PTR_ERR(st->regmap), + return dev_err_probe(dev, PTR_ERR(st->regmap), "failed to init register map\n"); /* @@ -942,18 +942,15 @@ static int axi_dac_probe(struct platform_device *pdev) if (ret) return ret; - if (ADI_AXI_PCORE_VER_MAJOR(ver) != - ADI_AXI_PCORE_VER_MAJOR(st->info->version)) { - dev_err(&pdev->dev, - "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", - ADI_AXI_PCORE_VER_MAJOR(st->info->version), - ADI_AXI_PCORE_VER_MINOR(st->info->version), - ADI_AXI_PCORE_VER_PATCH(st->info->version), - ADI_AXI_PCORE_VER_MAJOR(ver), - ADI_AXI_PCORE_VER_MINOR(ver), - ADI_AXI_PCORE_VER_PATCH(ver)); - return -ENODEV; - } + if (ADI_AXI_PCORE_VER_MAJOR(ver) != ADI_AXI_PCORE_VER_MAJOR(st->info->version)) + return dev_err_probe(dev, -ENODEV, + "Major version mismatch. Expected %d.%.2d.%c, Reported %d.%.2d.%c\n", + ADI_AXI_PCORE_VER_MAJOR(st->info->version), + ADI_AXI_PCORE_VER_MINOR(st->info->version), + ADI_AXI_PCORE_VER_PATCH(st->info->version), + ADI_AXI_PCORE_VER_MAJOR(ver), + ADI_AXI_PCORE_VER_MINOR(ver), + ADI_AXI_PCORE_VER_PATCH(ver)); /* Let's get the core read only configuration */ ret = regmap_read(st->regmap, AXI_DAC_CONFIG_REG, &st->reg_config); @@ -975,34 +972,33 @@ static int axi_dac_probe(struct platform_device *pdev) mutex_init(&st->lock); - ret = devm_iio_backend_register(&pdev->dev, st->info->backend_info, st); + ret = devm_iio_backend_register(dev, st->info->backend_info, st); if (ret) - return dev_err_probe(&pdev->dev, ret, + return dev_err_probe(dev, ret, "failed to register iio backend\n"); - device_for_each_child_node_scoped(&pdev->dev, child) { + device_for_each_child_node_scoped(dev, child) { int val; if (!st->info->has_child_nodes) - return dev_err_probe(&pdev->dev, -EINVAL, + return dev_err_probe(dev, -EINVAL, "invalid fdt axi-dac compatible."); /* Processing only reg 0 node */ ret = fwnode_property_read_u32(child, "reg", &val); if (ret) - return dev_err_probe(&pdev->dev, ret, - "invalid reg property."); + return dev_err_probe(dev, ret, "invalid reg property."); if (val != 0) - return dev_err_probe(&pdev->dev, -EINVAL, - "invalid node address."); + return dev_err_probe(dev, -EINVAL, + "invalid node address."); ret = axi_dac_create_platform_device(st, child); if (ret) - return dev_err_probe(&pdev->dev, -EINVAL, - "cannot create device."); + return dev_err_probe(dev, -EINVAL, + "cannot create device."); } - dev_info(&pdev->dev, "AXI DAC IP core (%d.%.2d.%c) probed\n", + dev_info(dev, "AXI DAC IP core (%d.%.2d.%c) probed\n", ADI_AXI_PCORE_VER_MAJOR(ver), ADI_AXI_PCORE_VER_MINOR(ver), ADI_AXI_PCORE_VER_PATCH(ver)); diff --git a/drivers/iio/dac/ds4424.c b/drivers/iio/dac/ds4424.c index a8198ba4f98a..c61868f2de31 100644 --- a/drivers/iio/dac/ds4424.c +++ b/drivers/iio/dac/ds4424.c @@ -14,7 +14,6 @@ #include #include #include -#include #define DS4422_MAX_DAC_CHANNELS 2 #define DS4424_MAX_DAC_CHANNELS 4 @@ -141,7 +140,7 @@ static int ds4424_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (val < S8_MIN || val > S8_MAX) + if (val <= S8_MIN || val > S8_MAX) return -EINVAL; if (val > 0) { diff --git a/drivers/iio/dac/max22007.c b/drivers/iio/dac/max22007.c new file mode 100644 index 000000000000..182ac7155a89 --- /dev/null +++ b/drivers/iio/dac/max22007.c @@ -0,0 +1,491 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * max22007.c - MAX22007 DAC driver + * + * Driver for Analog Devices MAX22007 Digital to Analog Converter. + * + * Copyright (c) 2026 Analog Devices Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +struct device; + +#define MAX22007_NUM_CHANNELS 4 +#define MAX22007_REV_ID_REG 0x00 +#define MAX22007_STAT_INTR_REG 0x01 +#define MAX22007_INTERRUPT_EN_REG 0x02 +#define MAX22007_CONFIG_REG 0x03 +#define MAX22007_CONTROL_REG 0x04 +#define MAX22007_CHANNEL_MODE_REG 0x05 +#define MAX22007_SOFT_RESET_REG 0x06 +#define MAX22007_DAC_CHANNEL_REG(ch) (0x07 + (ch)) +#define MAX22007_GPIO_CTRL_REG 0x0B +#define MAX22007_GPIO_DATA_REG 0x0C +#define MAX22007_GPI_EDGE_INT_CTRL_REG 0x0D +#define MAX22007_GPI_INT_STATUS_REG 0x0E + +/* Channel mask definitions */ +#define MAX22007_CH_MODE_CH_MASK(ch) BIT(12 + (ch)) +#define MAX22007_CH_PWRON_CH_MASK(ch) BIT(8 + (ch)) +#define MAX22007_DAC_LATCH_MODE_MASK(ch) BIT(12 + (ch)) +#define MAX22007_LDAC_UPDATE_MASK(ch) BIT(12 + (ch)) +#define MAX22007_SW_RST_MASK BIT(8) +#define MAX22007_SW_CLR_MASK BIT(12) +#define MAX22007_SOFT_RESET_BITS_MASK (MAX22007_SW_RST_MASK | \ + MAX22007_SW_CLR_MASK) +#define MAX22007_DAC_DATA_MASK GENMASK(15, 4) +#define MAX22007_DAC_MAX_RAW GENMASK(11, 0) +#define MAX22007_CRC8_POLYNOMIAL 0x8C +#define MAX22007_CRC_EN_MASK BIT(0) +#define MAX22007_RW_MASK BIT(0) +#define MAX22007_CRC_OVERHEAD 1 +#define MAX22007_NUM_SUPPLIES 3 +#define MAX22007_REF_MV 2500 + +/* Field value preparation macros with masking */ +#define MAX22007_CH_PWR_VAL(ch, val) (((val) & 0x1) << (8 + (ch))) +#define MAX22007_CH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch))) +#define MAX22007_DAC_LATCH_MODE_VAL(ch, val) (((val) & 0x1) << (12 + (ch))) + +static u8 max22007_crc8_table[CRC8_TABLE_SIZE]; + +static const char * const max22007_supply_names[MAX22007_NUM_SUPPLIES] = { + "vdd", + "hvdd", + "hvss", +}; + +struct max22007_state { + struct spi_device *spi; + struct regmap *regmap; + struct iio_chan_spec *iio_chans; + u8 tx_buf[4] __aligned(IIO_DMA_MINALIGN); + u8 rx_buf[4]; +}; + +static int max22007_spi_read(void *context, const void *reg, size_t reg_size, + void *val, size_t val_size) +{ + struct max22007_state *st = context; + u8 calculated_crc, received_crc; + u8 rx_buf[4]; + u8 reg_byte; + int ret; + + if (reg_size != 1) + return -EINVAL; + + if (val_size == 0 || val_size > 3) + return -EINVAL; + + memcpy(®_byte, reg, 1); + + ret = spi_write_then_read(st->spi, ®_byte, 1, rx_buf, + val_size + MAX22007_CRC_OVERHEAD); + if (ret) { + dev_err(&st->spi->dev, "SPI transfer failed: %d\n", ret); + return ret; + } + + calculated_crc = crc8(max22007_crc8_table, ®_byte, 1, 0x00); + calculated_crc = crc8(max22007_crc8_table, rx_buf, 2, calculated_crc); + received_crc = rx_buf[val_size]; + + if (calculated_crc != received_crc) { + dev_err(&st->spi->dev, "CRC mismatch on read register %02x\n", reg_byte); + return -EIO; + } + + memcpy(val, rx_buf, val_size); + + return 0; +} + +static int max22007_spi_write(void *context, const void *data, size_t count) +{ + struct max22007_state *st = context; + struct spi_transfer xfer = { + .tx_buf = st->tx_buf, + .rx_buf = st->rx_buf, + }; + + if (count + MAX22007_CRC_OVERHEAD > sizeof(st->tx_buf)) + return -EINVAL; + + memset(st->tx_buf, 0, sizeof(st->tx_buf)); + + xfer.len = count + MAX22007_CRC_OVERHEAD; + + memcpy(st->tx_buf, data, count); + st->tx_buf[count] = crc8(max22007_crc8_table, st->tx_buf, + sizeof(st->tx_buf) - 1, 0x00); + + return spi_sync_transfer(st->spi, &xfer, 1); +} + +static bool max22007_reg_readable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX22007_REV_ID_REG: + case MAX22007_STAT_INTR_REG: + case MAX22007_CONFIG_REG: + case MAX22007_CONTROL_REG: + case MAX22007_CHANNEL_MODE_REG: + case MAX22007_SOFT_RESET_REG: + case MAX22007_GPIO_CTRL_REG: + case MAX22007_GPIO_DATA_REG: + case MAX22007_GPI_EDGE_INT_CTRL_REG: + case MAX22007_GPI_INT_STATUS_REG: + return true; + case MAX22007_DAC_CHANNEL_REG(0) ... MAX22007_DAC_CHANNEL_REG(MAX22007_NUM_CHANNELS - 1): + return true; + default: + return false; + } +} + +static bool max22007_reg_writable(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MAX22007_CONFIG_REG: + case MAX22007_CONTROL_REG: + case MAX22007_CHANNEL_MODE_REG: + case MAX22007_SOFT_RESET_REG: + case MAX22007_GPIO_CTRL_REG: + case MAX22007_GPIO_DATA_REG: + case MAX22007_GPI_EDGE_INT_CTRL_REG: + return true; + case MAX22007_DAC_CHANNEL_REG(0) ... MAX22007_DAC_CHANNEL_REG(MAX22007_NUM_CHANNELS - 1): + return true; + default: + return false; + } +} + +static const struct regmap_bus max22007_regmap_bus = { + .read = max22007_spi_read, + .write = max22007_spi_write, + .read_flag_mask = MAX22007_RW_MASK, + .reg_format_endian_default = REGMAP_ENDIAN_BIG, + .val_format_endian_default = REGMAP_ENDIAN_BIG, +}; + +static const struct regmap_config max22007_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_shift = -1, + .readable_reg = max22007_reg_readable, + .writeable_reg = max22007_reg_writable, + .max_register = 0x0E, +}; + +static int max22007_write_channel_data(struct max22007_state *st, + unsigned int channel, int data) +{ + unsigned int reg_val; + + if (data < 0 || data > MAX22007_DAC_MAX_RAW) + return -EINVAL; + + reg_val = FIELD_PREP(MAX22007_DAC_DATA_MASK, data); + + return regmap_write(st->regmap, MAX22007_DAC_CHANNEL_REG(channel), reg_val); +} + +static int max22007_read_channel_data(struct max22007_state *st, + unsigned int channel, int *data) +{ + unsigned int reg_val; + int ret; + + ret = regmap_read(st->regmap, MAX22007_DAC_CHANNEL_REG(channel), ®_val); + if (ret) + return ret; + + *data = FIELD_GET(MAX22007_DAC_DATA_MASK, reg_val); + + return 0; +} + +static int max22007_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct max22007_state *st = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = max22007_read_channel_data(st, chan->channel, val); + if (ret) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_VOLTAGE) + *val = 5 * MAX22007_REF_MV; /* 5 * Vref in mV */ + else + *val = 25; /* Vref / (2 * Rsense) = MAX22007_REF_MV / 100 */ + *val2 = 12; /* 12-bit DAC resolution */ + return IIO_VAL_FRACTIONAL_LOG2; + default: + return -EINVAL; + } +} + +static int max22007_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct max22007_state *st = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + return max22007_write_channel_data(st, chan->channel, val); + default: + return -EINVAL; + } +} + +static const struct iio_info max22007_info = { + .read_raw = max22007_read_raw, + .write_raw = max22007_write_raw, +}; + +static ssize_t max22007_read_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + char *buf) +{ + struct max22007_state *st = iio_priv(indio_dev); + unsigned int reg_val; + bool powerdown; + int ret; + + ret = regmap_read(st->regmap, MAX22007_CHANNEL_MODE_REG, ®_val); + if (ret) + return ret; + + powerdown = !(reg_val & MAX22007_CH_PWRON_CH_MASK(chan->channel)); + + return sysfs_emit(buf, "%d\n", powerdown); +} + +static ssize_t max22007_write_dac_powerdown(struct iio_dev *indio_dev, + uintptr_t private, + const struct iio_chan_spec *chan, + const char *buf, size_t len) +{ + struct max22007_state *st = iio_priv(indio_dev); + bool powerdown; + int ret; + + ret = kstrtobool(buf, &powerdown); + if (ret) + return ret; + + ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG, + MAX22007_CH_PWRON_CH_MASK(chan->channel), + MAX22007_CH_PWR_VAL(chan->channel, powerdown ? 0 : 1)); + if (ret) + return ret; + + return len; +} + +static const struct iio_chan_spec_ext_info max22007_ext_info[] = { + { + .name = "powerdown", + .read = max22007_read_dac_powerdown, + .write = max22007_write_dac_powerdown, + .shared = IIO_SEPARATE, + }, + { } +}; + +static int max22007_parse_channel_cfg(struct max22007_state *st, u8 *num_channels) +{ + struct device *dev = &st->spi->dev; + int ret, num_chan; + int i = 0; + u32 reg; + + num_chan = device_get_child_node_count(dev); + if (!num_chan) + return dev_err_probe(dev, -ENODEV, "no channels configured\n"); + + st->iio_chans = devm_kcalloc(dev, num_chan, sizeof(*st->iio_chans), GFP_KERNEL); + if (!st->iio_chans) + return -ENOMEM; + + device_for_each_child_node_scoped(dev, child) { + u32 ch_func; + enum iio_chan_type chan_type; + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret) + return dev_err_probe(dev, ret, + "failed to read reg property of %pfwP\n", child); + + if (reg >= MAX22007_NUM_CHANNELS) + return dev_err_probe(dev, -EINVAL, + "reg out of range in %pfwP\n", child); + + ret = fwnode_property_read_u32(child, "adi,ch-func", &ch_func); + if (ret) + return dev_err_probe(dev, ret, + "missing adi,ch-func property for %pfwP\n", child); + + switch (ch_func) { + case CH_FUNC_VOLTAGE_OUTPUT: + chan_type = IIO_VOLTAGE; + break; + case CH_FUNC_CURRENT_OUTPUT: + chan_type = IIO_CURRENT; + break; + default: + return dev_err_probe(dev, -EINVAL, + "invalid adi,ch-func %u for %pfwP\n", + ch_func, child); + } + + st->iio_chans[i++] = (struct iio_chan_spec) { + .output = 1, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE), + .ext_info = max22007_ext_info, + .channel = reg, + .type = chan_type, + }; + + ret = regmap_update_bits(st->regmap, MAX22007_CHANNEL_MODE_REG, + MAX22007_CH_MODE_CH_MASK(reg), + MAX22007_CH_MODE_VAL(reg, ch_func - 1)); + if (ret) + return ret; + + /* Set DAC to transparent mode (immediate update) */ + ret = regmap_update_bits(st->regmap, MAX22007_CONFIG_REG, + MAX22007_DAC_LATCH_MODE_MASK(reg), + MAX22007_DAC_LATCH_MODE_VAL(reg, 1)); + if (ret) + return ret; + } + + *num_channels = num_chan; + + return 0; +} + +static int max22007_probe(struct spi_device *spi) +{ + struct device *dev = &spi->dev; + struct gpio_desc *reset_gpio; + struct max22007_state *st; + struct iio_dev *indio_dev; + u8 num_channels; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + + st = iio_priv(indio_dev); + st->spi = spi; + + crc8_populate_lsb(max22007_crc8_table, MAX22007_CRC8_POLYNOMIAL); + + st->regmap = devm_regmap_init(dev, &max22007_regmap_bus, st, + &max22007_regmap_config); + if (IS_ERR(st->regmap)) + return dev_err_probe(dev, PTR_ERR(st->regmap), + "Failed to initialize regmap\n"); + + ret = devm_regulator_bulk_get_enable(dev, MAX22007_NUM_SUPPLIES, + max22007_supply_names); + if (ret) + return dev_err_probe(dev, ret, "Failed to get and enable regulators\n"); + + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(reset_gpio)) + return dev_err_probe(dev, PTR_ERR(reset_gpio), + "Failed to get reset GPIO\n"); + + if (reset_gpio) { + gpiod_set_value_cansleep(reset_gpio, 1); + usleep_range(1000, 5000); + gpiod_set_value_cansleep(reset_gpio, 0); + usleep_range(1000, 5000); + } else { + ret = regmap_write(st->regmap, MAX22007_SOFT_RESET_REG, + MAX22007_SOFT_RESET_BITS_MASK); + if (ret) + return ret; + } + + ret = regmap_set_bits(st->regmap, MAX22007_CONFIG_REG, + MAX22007_CRC_EN_MASK); + if (ret) + return ret; + + ret = max22007_parse_channel_cfg(st, &num_channels); + if (ret) + return ret; + + indio_dev->info = &max22007_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->iio_chans; + indio_dev->num_channels = num_channels; + indio_dev->name = "max22007"; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct spi_device_id max22007_id[] = { + { "max22007" }, + { } +}; +MODULE_DEVICE_TABLE(spi, max22007_id); + +static const struct of_device_id max22007_of_match[] = { + { .compatible = "adi,max22007" }, + { } +}; +MODULE_DEVICE_TABLE(of, max22007_of_match); + +static struct spi_driver max22007_driver = { + .driver = { + .name = "max22007", + .of_match_table = max22007_of_match, + }, + .probe = max22007_probe, + .id_table = max22007_id, +}; +module_spi_driver(max22007_driver); + +MODULE_AUTHOR("Janani Sunil "); +MODULE_DESCRIPTION("Analog Devices MAX22007 DAC"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/dac/mcp47feb02.c b/drivers/iio/dac/mcp47feb02.c new file mode 100644 index 000000000000..b218f0c3a0bd --- /dev/null +++ b/drivers/iio/dac/mcp47feb02.c @@ -0,0 +1,1250 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * IIO driver for MCP47FEB02 Multi-Channel DAC with I2C interface + * + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries + * + * Author: Ariana Lazar + * + * Datasheet links: + * [MCP47FEBxx] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf + * [MCP47FVBxx] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf + * [MCP47FxBx4/8] https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register addresses must be left shifted with 3 positions in order to append command mask */ +#define MCP47FEB02_DAC0_REG_ADDR 0x00 +#define MCP47FEB02_VREF_REG_ADDR 0x40 +#define MCP47FEB02_POWER_DOWN_REG_ADDR 0x48 +#define MCP47FEB02_DAC_CTRL_MASK GENMASK(1, 0) + +#define MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR 0x50 +#define MCP47FEB02_GAIN_BIT_MASK BIT(0) +#define MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK BIT(6) +#define MCP47FEB02_GAIN_BITS_MASK GENMASK(15, 8) + +#define MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR 0x58 + +#define MCP47FEB02_NV_DAC0_REG_ADDR 0x80 +#define MCP47FEB02_NV_VREF_REG_ADDR 0xC0 +#define MCP47FEB02_NV_POWER_DOWN_REG_ADDR 0xC8 +#define MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR 0xD0 +#define MCP47FEB02_NV_I2C_SLAVE_ADDR_MASK GENMASK(7, 0) + +/* Voltage reference, Power-Down control register and DAC Wiperlock status register fields */ +#define DAC_CTRL_MASK(ch) (GENMASK(1, 0) << (2 * (ch))) +#define DAC_CTRL_VAL(ch, val) ((val) << (2 * (ch))) + +/* Gain Control and I2C Slave Address Reguster fields */ +#define DAC_GAIN_MASK(ch) (BIT(0) << (8 + (ch))) +#define DAC_GAIN_VAL(ch, val) ((val) << (8 + (ch))) + +#define REG_ADDR(reg) ((reg) << 3) +#define NV_REG_ADDR(reg) ((NV_DAC_ADDR_OFFSET + (reg)) << 3) +#define READFLAG_MASK GENMASK(2, 1) + +#define MCP47FEB02_MAX_CH 8 +#define MCP47FEB02_MAX_SCALES_CH 3 +#define MCP47FEB02_DAC_WIPER_UNLOCKED 0 +#define MCP47FEB02_NORMAL_OPERATION 0 +#define MCP47FEB02_INTERNAL_BAND_GAP_mV 2440 +#define NV_DAC_ADDR_OFFSET 0x10 + +enum mcp47feb02_vref_mode { + MCP47FEB02_VREF_VDD = 0, + MCP47FEB02_INTERNAL_BAND_GAP = 1, + MCP47FEB02_EXTERNAL_VREF_UNBUFFERED = 2, + MCP47FEB02_EXTERNAL_VREF_BUFFERED = 3, +}; + +enum mcp47feb02_scale { + MCP47FEB02_SCALE_VDD = 0, + MCP47FEB02_SCALE_GAIN_X1 = 1, + MCP47FEB02_SCALE_GAIN_X2 = 2, +}; + +enum mcp47feb02_gain_bit_mode { + MCP47FEB02_GAIN_BIT_X1 = 0, + MCP47FEB02_GAIN_BIT_X2 = 1, +}; + +static const char * const mcp47feb02_powerdown_modes[] = { + "1kohm_to_gnd", + "100kohm_to_gnd", + "open_circuit", +}; + +/** + * struct mcp47feb02_features - chip specific data + * @name: device name + * @phys_channels: number of hardware channels + * @resolution: DAC resolution + * @have_ext_vref1: does the hardware have an the second external voltage reference? + * @have_eeprom: does the hardware have an internal eeprom? + */ +struct mcp47feb02_features { + const char *name; + unsigned int phys_channels; + unsigned int resolution; + bool have_ext_vref1; + bool have_eeprom; +}; + +static const struct mcp47feb02_features mcp47feb01_chip_features = { + .name = "mcp47feb01", + .phys_channels = 1, + .resolution = 8, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb02_chip_features = { + .name = "mcp47feb02", + .phys_channels = 2, + .resolution = 8, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb04_chip_features = { + .name = "mcp47feb04", + .phys_channels = 4, + .resolution = 8, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb08_chip_features = { + .name = "mcp47feb08", + .phys_channels = 8, + .resolution = 8, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb11_chip_features = { + .name = "mcp47feb11", + .phys_channels = 1, + .resolution = 10, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb12_chip_features = { + .name = "mcp47feb12", + .phys_channels = 2, + .resolution = 10, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb14_chip_features = { + .name = "mcp47feb14", + .phys_channels = 4, + .resolution = 10, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb18_chip_features = { + .name = "mcp47feb18", + .phys_channels = 8, + .resolution = 10, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb21_chip_features = { + .name = "mcp47feb21", + .phys_channels = 1, + .resolution = 12, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb22_chip_features = { + .name = "mcp47feb22", + .phys_channels = 2, + .resolution = 12, + .have_ext_vref1 = false, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb24_chip_features = { + .name = "mcp47feb24", + .phys_channels = 4, + .resolution = 12, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47feb28_chip_features = { + .name = "mcp47feb28", + .phys_channels = 8, + .resolution = 12, + .have_ext_vref1 = true, + .have_eeprom = true, +}; + +static const struct mcp47feb02_features mcp47fvb01_chip_features = { + .name = "mcp47fvb01", + .phys_channels = 1, + .resolution = 8, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb02_chip_features = { + .name = "mcp47fvb02", + .phys_channels = 2, + .resolution = 8, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb04_chip_features = { + .name = "mcp47fvb04", + .phys_channels = 4, + .resolution = 8, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb08_chip_features = { + .name = "mcp47fvb08", + .phys_channels = 8, + .resolution = 8, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb11_chip_features = { + .name = "mcp47fvb11", + .phys_channels = 1, + .resolution = 10, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb12_chip_features = { + .name = "mcp47fvb12", + .phys_channels = 2, + .resolution = 10, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb14_chip_features = { + .name = "mcp47fvb14", + .phys_channels = 4, + .resolution = 10, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb18_chip_features = { + .name = "mcp47fvb18", + .phys_channels = 8, + .resolution = 10, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb21_chip_features = { + .name = "mcp47fvb21", + .phys_channels = 1, + .resolution = 12, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb22_chip_features = { + .name = "mcp47fvb22", + .phys_channels = 2, + .resolution = 12, + .have_ext_vref1 = false, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb24_chip_features = { + .name = "mcp47fvb24", + .phys_channels = 4, + .resolution = 12, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +static const struct mcp47feb02_features mcp47fvb28_chip_features = { + .name = "mcp47fvb28", + .phys_channels = 8, + .resolution = 12, + .have_ext_vref1 = true, + .have_eeprom = false, +}; + +/** + * struct mcp47feb02_channel_data - channel configuration + * @ref_mode: chosen voltage for reference + * @use_2x_gain: output driver gain control + * @powerdown: is false if the channel is in normal operation mode + * @powerdown_mode: selected power-down mode + * @dac_data: dac value + */ +struct mcp47feb02_channel_data { + u8 ref_mode; + bool use_2x_gain; + bool powerdown; + u8 powerdown_mode; + u16 dac_data; +}; + +/** + * struct mcp47feb02_data - chip configuration + * @chdata: options configured for each channel on the device + * @lock: prevents concurrent reads/writes to driver's state members + * @chip_features: pointer to features struct + * @scale_1: scales set on channels that are based on Vref1 + * @scale: scales set on channels that are based on Vref/Vref0 + * @active_channels_mask: enabled channels + * @regmap: regmap for directly accessing device register + * @labels: table with channels labels + * @phys_channels: physical channels on the device + * @vref1_buffered: Vref1 buffer is enabled + * @vref_buffered: Vref/Vref0 buffer is enabled + * @use_vref1: vref1-supply is defined + * @use_vref: vref-supply is defined + */ +struct mcp47feb02_data { + struct mcp47feb02_channel_data chdata[MCP47FEB02_MAX_CH]; + struct mutex lock; /* prevents concurrent reads/writes to driver's state members */ + const struct mcp47feb02_features *chip_features; + int scale_1[2 * MCP47FEB02_MAX_SCALES_CH]; + int scale[2 * MCP47FEB02_MAX_SCALES_CH]; + unsigned long active_channels_mask; + struct regmap *regmap; + const char *labels[MCP47FEB02_MAX_CH]; + u16 phys_channels; + bool vref1_buffered; + bool vref_buffered; + bool use_vref1; + bool use_vref; +}; + +static const struct regmap_range mcp47feb02_readable_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), +}; + +static const struct regmap_range mcp47feb02_writable_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), +}; + +static const struct regmap_range mcp47feb02_volatile_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), +}; + +static const struct regmap_access_table mcp47feb02_readable_table = { + .yes_ranges = mcp47feb02_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_readable_ranges), +}; + +static const struct regmap_access_table mcp47feb02_writable_table = { + .yes_ranges = mcp47feb02_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_writable_ranges), +}; + +static const struct regmap_access_table mcp47feb02_volatile_table = { + .yes_ranges = mcp47feb02_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_volatile_ranges), +}; + +static const struct regmap_config mcp47feb02_regmap_config = { + .name = "mcp47feb02_regmap", + .reg_bits = 8, + .val_bits = 16, + .rd_table = &mcp47feb02_readable_table, + .wr_table = &mcp47feb02_writable_table, + .volatile_table = &mcp47feb02_volatile_table, + .max_register = MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, + .read_flag_mask = READFLAG_MASK, + .cache_type = REGCACHE_MAPLE, + .val_format_endian = REGMAP_ENDIAN_BIG, +}; + +/* For devices that doesn't have nonvolatile memory */ +static const struct regmap_range mcp47fvb02_readable_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), +}; + +static const struct regmap_range mcp47fvb02_writable_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), +}; + +static const struct regmap_range mcp47fvb02_volatile_ranges[] = { + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), +}; + +static const struct regmap_access_table mcp47fvb02_readable_table = { + .yes_ranges = mcp47fvb02_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_readable_ranges), +}; + +static const struct regmap_access_table mcp47fvb02_writable_table = { + .yes_ranges = mcp47fvb02_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_writable_ranges), +}; + +static const struct regmap_access_table mcp47fvb02_volatile_table = { + .yes_ranges = mcp47fvb02_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_volatile_ranges), +}; + +static const struct regmap_config mcp47fvb02_regmap_config = { + .name = "mcp47fvb02_regmap", + .reg_bits = 8, + .val_bits = 16, + .rd_table = &mcp47fvb02_readable_table, + .wr_table = &mcp47fvb02_writable_table, + .volatile_table = &mcp47fvb02_volatile_table, + .max_register = MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR, + .read_flag_mask = READFLAG_MASK, + .cache_type = REGCACHE_MAPLE, + .val_format_endian = REGMAP_ENDIAN_BIG, +}; + +static int mcp47feb02_write_to_eeprom(struct mcp47feb02_data *data, unsigned int reg, + unsigned int val) +{ + int eewa_val, ret; + + /* + * Wait until the currently occurring EEPROM Write Cycle is completed. + * Only serial commands to the volatile memory are allowed. + */ + guard(mutex)(&data->lock); + + ret = regmap_read_poll_timeout(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, + eewa_val, + !(eewa_val & MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK), + USEC_PER_MSEC, USEC_PER_MSEC * 5); + if (ret) + return ret; + + return regmap_write(data->regmap, reg, val); +} + +static ssize_t store_eeprom_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + struct mcp47feb02_data *data = iio_priv(dev_to_iio_dev(dev)); + unsigned int i, val, val1, eewa_val; + bool state; + int ret; + + ret = kstrtobool(buf, &state); + if (ret) + return ret; + + if (!state) + return 0; + + /* + * Verify DAC Wiper and DAC Configuration are unlocked. If both are disabled, + * writing to EEPROM is available. + */ + ret = regmap_read(data->regmap, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR, &val); + if (ret) + return ret; + + if (val) { + dev_err(dev, "DAC Wiper and DAC Configuration not are unlocked.\n"); + return -EINVAL; + } + + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { + ret = mcp47feb02_write_to_eeprom(data, NV_REG_ADDR(i), + data->chdata[i].dac_data); + if (ret) + return ret; + } + + ret = regmap_read(data->regmap, MCP47FEB02_VREF_REG_ADDR, &val); + if (ret) + return ret; + + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_VREF_REG_ADDR, val); + if (ret) + return ret; + + ret = regmap_read(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, &val); + if (ret) + return ret; + + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_POWER_DOWN_REG_ADDR, val); + if (ret) + return ret; + + ret = regmap_read_poll_timeout(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, eewa_val, + !(eewa_val & MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK), + USEC_PER_MSEC, USEC_PER_MSEC * 5); + if (ret) + return ret; + + ret = regmap_read(data->regmap, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, &val); + if (ret) + return ret; + + ret = regmap_read(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, &val1); + if (ret) + return ret; + + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, + (val1 & MCP47FEB02_GAIN_BITS_MASK) | + (val & MCP47FEB02_NV_I2C_SLAVE_ADDR_MASK)); + if (ret) + return ret; + + return len; +} + +static IIO_DEVICE_ATTR_WO(store_eeprom, 0); + +static struct attribute *mcp47feb02_attributes[] = { + &iio_dev_attr_store_eeprom.dev_attr.attr, + NULL +}; + +static const struct attribute_group mcp47feb02_attribute_group = { + .attrs = mcp47feb02_attributes, +}; + +static int mcp47feb02_suspend(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct mcp47feb02_data *data = iio_priv(indio_dev); + int ret; + u8 ch; + + guard(mutex)(&data->lock); + + for_each_set_bit(ch, &data->active_channels_mask, data->phys_channels) { + u8 pd_mode; + + data->chdata[ch].powerdown = true; + pd_mode = data->chdata[ch].powerdown_mode + 1; + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, pd_mode)); + if (ret) + return ret; + + ret = regmap_write(data->regmap, REG_ADDR(ch), data->chdata[ch].dac_data); + if (ret) + return ret; + } + + return 0; +} + +static int mcp47feb02_resume(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct mcp47feb02_data *data = iio_priv(indio_dev); + u8 ch; + + guard(mutex)(&data->lock); + + for_each_set_bit(ch, &data->active_channels_mask, data->phys_channels) { + u8 pd_mode; + int ret; + + data->chdata[ch].powerdown = false; + pd_mode = data->chdata[ch].powerdown_mode + 1; + + ret = regmap_write(data->regmap, REG_ADDR(ch), data->chdata[ch].dac_data); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, MCP47FEB02_VREF_REG_ADDR, + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, pd_mode)); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, + DAC_GAIN_MASK(ch), + DAC_GAIN_VAL(ch, data->chdata[ch].use_2x_gain)); + if (ret) + return ret; + + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, + DAC_CTRL_MASK(ch), + DAC_CTRL_VAL(ch, MCP47FEB02_NORMAL_OPERATION)); + if (ret) + return ret; + } + + return 0; +} + +static int mcp47feb02_get_powerdown_mode(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + + return data->chdata[chan->address].powerdown_mode; +} + +static int mcp47feb02_set_powerdown_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *ch, + unsigned int mode) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + + data->chdata[ch->address].powerdown_mode = mode; + + return 0; +} + +static ssize_t mcp47feb02_read_powerdown(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *ch, char *buf) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + + /* Print if channel is in a power-down mode or not */ + return sysfs_emit(buf, "%d\n", data->chdata[ch->address].powerdown); +} + +static ssize_t mcp47feb02_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, + const struct iio_chan_spec *ch, const char *buf, + size_t len) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + u32 reg = ch->address; + u8 tmp_pd_mode; + bool state; + int ret; + + guard(mutex)(&data->lock); + + ret = kstrtobool(buf, &state); + if (ret) + return ret; + + /* + * Set the channel to the specified power-down mode. Exiting power-down mode + * requires writing normal operation mode (0) to the channel-specific register bits. + */ + tmp_pd_mode = state ? (data->chdata[reg].powerdown_mode + 1) : MCP47FEB02_NORMAL_OPERATION; + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, + DAC_CTRL_MASK(reg), DAC_CTRL_VAL(reg, tmp_pd_mode)); + if (ret) + return ret; + + data->chdata[reg].powerdown = state; + + return len; +} + +static DEFINE_SIMPLE_DEV_PM_OPS(mcp47feb02_pm_ops, mcp47feb02_suspend, mcp47feb02_resume); + +static const struct iio_enum mcp47febxx_powerdown_mode_enum = { + .items = mcp47feb02_powerdown_modes, + .num_items = ARRAY_SIZE(mcp47feb02_powerdown_modes), + .get = mcp47feb02_get_powerdown_mode, + .set = mcp47feb02_set_powerdown_mode, +}; + +static const struct iio_chan_spec_ext_info mcp47feb02_ext_info[] = { + { + .name = "powerdown", + .read = mcp47feb02_read_powerdown, + .write = mcp47feb02_write_powerdown, + .shared = IIO_SEPARATE, + }, + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp47febxx_powerdown_mode_enum), + IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &mcp47febxx_powerdown_mode_enum), + { } +}; + +static const struct iio_chan_spec mcp47febxx_ch_template = { + .type = IIO_VOLTAGE, + .output = 1, + .indexed = 1, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE), + .ext_info = mcp47feb02_ext_info, +}; + +static void mcp47feb02_init_scale(struct mcp47feb02_data *data, enum mcp47feb02_scale scale, + int vref_mV, int scale_avail[]) +{ + u32 value_micro, value_int; + u64 tmp; + + /* vref_mV should not be negative */ + tmp = (u64)vref_mV * MICRO >> data->chip_features->resolution; + value_int = div_u64_rem(tmp, MICRO, &value_micro); + scale_avail[scale * 2] = value_int; + scale_avail[scale * 2 + 1] = value_micro; +} + +static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, + int vref_mV, int vref1_mV) +{ + struct device *dev = regmap_get_device(data->regmap); + int tmp_vref; + + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); + + if (data->use_vref) + tmp_vref = vref_mV; + else + tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; + + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); + + if (data->phys_channels >= 4) { + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); + + if (data->use_vref1 && vref1_mV <= 0) + return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); + + if (data->use_vref1) + tmp_vref = vref1_mV; + else + tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; + + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, + tmp_vref, data->scale_1); + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, + tmp_vref * 2, data->scale_1); + } + + return 0; +} + +static int mcp47feb02_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, + const int **vals, int *type, int *length, long info) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + + switch (info) { + case IIO_CHAN_INFO_SCALE: + switch (ch->type) { + case IIO_VOLTAGE: + if (data->phys_channels >= 4 && (ch->address % 2)) + *vals = data->scale_1; + else + *vals = data->scale; + + *length = 2 * MCP47FEB02_MAX_SCALES_CH; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } + default: + return -EINVAL; + } +} + +static void mcp47feb02_get_scale(int ch, struct mcp47feb02_data *data, int *val, int *val2) +{ + enum mcp47feb02_scale current_scale; + + if (data->chdata[ch].ref_mode == MCP47FEB02_VREF_VDD) + current_scale = MCP47FEB02_SCALE_VDD; + else if (data->chdata[ch].use_2x_gain) + current_scale = MCP47FEB02_SCALE_GAIN_X2; + else + current_scale = MCP47FEB02_SCALE_GAIN_X1; + + if (data->phys_channels >= 4 && (ch % 2)) { + *val = data->scale_1[current_scale * 2]; + *val2 = data->scale_1[current_scale * 2 + 1]; + } else { + *val = data->scale[current_scale * 2]; + *val2 = data->scale[current_scale * 2 + 1]; + } +} + +static int mcp47feb02_check_scale(struct mcp47feb02_data *data, int val, int val2, int scale[]) +{ + unsigned int i; + + for (i = 0; i < MCP47FEB02_MAX_SCALES_CH; i++) { + if (scale[i * 2] == val && scale[i * 2 + 1] == val2) + return i; + } + + return -EINVAL; +} + +static int mcp47feb02_ch_scale(struct mcp47feb02_data *data, int ch, int scale) +{ + int tmp_val, ret; + + if (scale == MCP47FEB02_SCALE_VDD) { + tmp_val = MCP47FEB02_VREF_VDD; + } else if (data->phys_channels >= 4 && (ch % 2)) { + if (data->use_vref1) { + if (data->vref1_buffered) + tmp_val = MCP47FEB02_EXTERNAL_VREF_BUFFERED; + else + tmp_val = MCP47FEB02_EXTERNAL_VREF_UNBUFFERED; + } else { + tmp_val = MCP47FEB02_INTERNAL_BAND_GAP; + } + } else if (data->use_vref) { + if (data->vref_buffered) + tmp_val = MCP47FEB02_EXTERNAL_VREF_BUFFERED; + else + tmp_val = MCP47FEB02_EXTERNAL_VREF_UNBUFFERED; + } else { + tmp_val = MCP47FEB02_INTERNAL_BAND_GAP; + } + + ret = regmap_update_bits(data->regmap, MCP47FEB02_VREF_REG_ADDR, + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, tmp_val)); + if (ret) + return ret; + + data->chdata[ch].ref_mode = tmp_val; + + return 0; +} + +/* + * Setting the scale in order to choose between VDD and (Vref or Band Gap) from the user + * space. The VREF pin is either an input or an output, therefore the user cannot + * simultaneously connect an external voltage reference to the pin and select the + * internal Band Gap. + * When the DAC’s voltage reference is configured as the VREF pin, the pin is an input. + * When the DAC’s voltage reference is configured as the internal Band Gap, + * the VREF pin is an output. + * If Vref/Vref1 voltage is not available, then the internal Band Gap will be used + * to calculate the values for the scale. + */ +static int mcp47feb02_set_scale(struct mcp47feb02_data *data, int ch, int scale) +{ + int tmp_val, ret; + + ret = mcp47feb02_ch_scale(data, ch, scale); + if (ret) + return ret; + + if (scale == MCP47FEB02_SCALE_GAIN_X2) + tmp_val = MCP47FEB02_GAIN_BIT_X2; + else + tmp_val = MCP47FEB02_GAIN_BIT_X1; + + ret = regmap_update_bits(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, + DAC_GAIN_MASK(ch), DAC_GAIN_VAL(ch, tmp_val)); + if (ret) + return ret; + + data->chdata[ch].use_2x_gain = tmp_val; + + return 0; +} + +static int mcp47feb02_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, + int *val, int *val2, long mask) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = regmap_read(data->regmap, REG_ADDR(ch->address), val); + if (ret) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + mcp47feb02_get_scale(ch->address, data, val, val2); + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int mcp47feb02_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, + int val, int val2, long mask) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + int *tmp_scale, ret; + + guard(mutex)(&data->lock); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = regmap_write(data->regmap, REG_ADDR(ch->address), val); + if (ret) + return ret; + + data->chdata[ch->address].dac_data = val; + return 0; + case IIO_CHAN_INFO_SCALE: + if (data->phys_channels >= 4 && (ch->address % 2)) + tmp_scale = data->scale_1; + else + tmp_scale = data->scale; + + ret = mcp47feb02_check_scale(data, val, val2, tmp_scale); + if (ret < 0) + return ret; + + return mcp47feb02_set_scale(data, ch->address, ret); + default: + return -EINVAL; + } +} + +static int mcp47feb02_read_label(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, + char *label) +{ + struct mcp47feb02_data *data = iio_priv(indio_dev); + + return sysfs_emit(label, "%s\n", data->labels[ch->address]); +} + +static const struct iio_info mcp47feb02_info = { + .read_raw = mcp47feb02_read_raw, + .write_raw = mcp47feb02_write_raw, + .read_label = mcp47feb02_read_label, + .read_avail = &mcp47feb02_read_avail, + .attrs = &mcp47feb02_attribute_group, +}; + +static const struct iio_info mcp47fvb02_info = { + .read_raw = mcp47feb02_read_raw, + .write_raw = mcp47feb02_write_raw, + .read_label = mcp47feb02_read_label, + .read_avail = &mcp47feb02_read_avail, +}; + +static int mcp47feb02_parse_fw(struct iio_dev *indio_dev, + const struct mcp47feb02_features *chip_features) +{ + struct iio_chan_spec chanspec = mcp47febxx_ch_template; + struct mcp47feb02_data *data = iio_priv(indio_dev); + struct device *dev = regmap_get_device(data->regmap); + struct iio_chan_spec *channels; + u32 num_channels; + u8 chan_idx = 0; + + guard(mutex)(&data->lock); + + num_channels = device_get_child_node_count(dev); + if (num_channels > chip_features->phys_channels) + return dev_err_probe(dev, -EINVAL, "More channels than the chip supports\n"); + + if (!num_channels) + return dev_err_probe(dev, -EINVAL, "No channel specified in the devicetree.\n"); + + channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL); + if (!channels) + return -ENOMEM; + + device_for_each_child_node_scoped(dev, child) { + u32 reg = 0; + int ret; + + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret) + return dev_err_probe(dev, ret, "Invalid channel number\n"); + + if (reg >= chip_features->phys_channels) + return dev_err_probe(dev, -EINVAL, + "The index of the channels does not match the chip\n"); + + set_bit(reg, &data->active_channels_mask); + + ret = fwnode_property_read_string(child, "label", &data->labels[reg]); + if (ret) + return dev_err_probe(dev, ret, "%pfw: invalid label\n", + fwnode_get_name(child)); + + chanspec.address = reg; + chanspec.channel = reg; + channels[chan_idx] = chanspec; + chan_idx++; + } + + indio_dev->num_channels = num_channels; + indio_dev->channels = channels; + indio_dev->modes = INDIO_DIRECT_MODE; + data->phys_channels = chip_features->phys_channels; + + data->vref_buffered = device_property_read_bool(dev, "microchip,vref-buffered"); + + if (chip_features->have_ext_vref1) + data->vref1_buffered = device_property_read_bool(dev, "microchip,vref1-buffered"); + + return 0; +} + +static int mcp47feb02_init_ctrl_regs(struct mcp47feb02_data *data) +{ + unsigned int i, vref_ch, gain_ch, pd_ch; + int ret; + + ret = regmap_read(data->regmap, MCP47FEB02_VREF_REG_ADDR, &vref_ch); + if (ret) + return ret; + + ret = regmap_read(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, &gain_ch); + if (ret) + return ret; + + ret = regmap_read(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, &pd_ch); + if (ret) + return ret; + + gain_ch = gain_ch & MCP47FEB02_GAIN_BITS_MASK; + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { + struct device *dev = regmap_get_device(data->regmap); + unsigned int pd_tmp; + + data->chdata[i].ref_mode = (vref_ch >> (2 * i)) & MCP47FEB02_DAC_CTRL_MASK; + data->chdata[i].use_2x_gain = (gain_ch >> i) & MCP47FEB02_GAIN_BIT_MASK; + + /* + * Inform the user that the current voltage reference read from the volatile + * register of the chip is different from the one specified in the device tree. + * Considering that the user cannot have an external voltage reference connected + * to the pin and select the internal Band Gap at the same time, in order to avoid + * miscofiguring the reference voltage, the volatile register will not be written. + * In order to overwrite the setting from volatile register with the one from the + * device tree, the user needs to write the chosen scale. + */ + switch (data->chdata[i].ref_mode) { + case MCP47FEB02_INTERNAL_BAND_GAP: + if (data->phys_channels >= 4 && (i % 2) && data->use_vref1) { + dev_dbg(dev, "ch[%u]: was configured to use internal band gap", i); + dev_dbg(dev, "ch[%u]: reference voltage set to VREF1", i); + break; + } + if ((data->phys_channels < 4 || (data->phys_channels >= 4 && !(i % 2))) && + data->use_vref) { + dev_dbg(dev, "ch[%u]: was configured to use internal band gap", i); + dev_dbg(dev, "ch[%u]: reference voltage set to VREF", i); + break; + } + break; + case MCP47FEB02_EXTERNAL_VREF_UNBUFFERED: + case MCP47FEB02_EXTERNAL_VREF_BUFFERED: + if (data->phys_channels >= 4 && (i % 2) && !data->use_vref1) { + dev_dbg(dev, "ch[%u]: was configured to use VREF1", i); + dev_dbg(dev, + "ch[%u]: reference voltage set to internal band gap", i); + break; + } + if ((data->phys_channels < 4 || (data->phys_channels >= 4 && !(i % 2))) && + !data->use_vref) { + dev_dbg(dev, "ch[%u]: was configured to use VREF", i); + dev_dbg(dev, + "ch[%u]: reference voltage set to internal band gap", i); + break; + } + break; + } + + pd_tmp = (pd_ch >> (2 * i)) & MCP47FEB02_DAC_CTRL_MASK; + data->chdata[i].powerdown_mode = pd_tmp ? (pd_tmp - 1) : pd_tmp; + data->chdata[i].powerdown = !!(data->chdata[i].powerdown_mode); + } + + return 0; +} + +static int mcp47feb02_init_ch_scales(struct mcp47feb02_data *data, int vdd_mV, + int vref_mV, int vref1_mV) +{ + unsigned int i; + + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { + struct device *dev = regmap_get_device(data->regmap); + int ret; + + ret = mcp47feb02_init_scales_avail(data, vdd_mV, vref_mV, vref1_mV); + if (ret) + return dev_err_probe(dev, ret, "failed to init scales for ch %u\n", i); + } + + return 0; +} + +static int mcp47feb02_probe(struct i2c_client *client) +{ + const struct mcp47feb02_features *chip_features; + struct device *dev = &client->dev; + struct mcp47feb02_data *data; + struct iio_dev *indio_dev; + int vref1_mV = 0; + int vref_mV = 0; + int vdd_mV; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + chip_features = i2c_get_match_data(client); + if (!chip_features) + return -EINVAL; + + data->chip_features = chip_features; + + if (chip_features->have_eeprom) { + data->regmap = devm_regmap_init_i2c(client, &mcp47feb02_regmap_config); + indio_dev->info = &mcp47feb02_info; + } else { + data->regmap = devm_regmap_init_i2c(client, &mcp47fvb02_regmap_config); + indio_dev->info = &mcp47fvb02_info; + } + if (IS_ERR(data->regmap)) + return dev_err_probe(dev, PTR_ERR(data->regmap), "Error initializing i2c regmap\n"); + + indio_dev->name = chip_features->name; + + ret = mcp47feb02_parse_fw(indio_dev, chip_features); + if (ret) + return dev_err_probe(dev, ret, "Error parsing firmware data\n"); + + ret = devm_mutex_init(dev, &data->lock); + if (ret) + return ret; + + ret = devm_regulator_get_enable_read_voltage(dev, "vdd"); + if (ret < 0) + return ret; + + vdd_mV = ret / MILLI; + + ret = devm_regulator_get_enable_read_voltage(dev, "vref"); + if (ret > 0) { + vref_mV = ret / MILLI; + data->use_vref = true; + } else { + dev_dbg(dev, "using internal band gap as voltage reference.\n"); + dev_dbg(dev, "Vref is unavailable.\n"); + } + + if (chip_features->have_ext_vref1) { + ret = devm_regulator_get_enable_read_voltage(dev, "vref1"); + if (ret > 0) { + vref1_mV = ret / MILLI; + data->use_vref1 = true; + } else { + dev_dbg(dev, "using internal band gap as voltage reference 1.\n"); + dev_dbg(dev, "Vref1 is unavailable.\n"); + } + } + + ret = mcp47feb02_init_ctrl_regs(data); + if (ret) + return dev_err_probe(dev, ret, "Error initialising vref register\n"); + + ret = mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV); + if (ret) + return ret; + + return devm_iio_device_register(dev, indio_dev); +} + +static const struct i2c_device_id mcp47feb02_id[] = { + { "mcp47feb01", (kernel_ulong_t)&mcp47feb01_chip_features }, + { "mcp47feb02", (kernel_ulong_t)&mcp47feb02_chip_features }, + { "mcp47feb04", (kernel_ulong_t)&mcp47feb04_chip_features }, + { "mcp47feb08", (kernel_ulong_t)&mcp47feb08_chip_features }, + { "mcp47feb11", (kernel_ulong_t)&mcp47feb11_chip_features }, + { "mcp47feb12", (kernel_ulong_t)&mcp47feb12_chip_features }, + { "mcp47feb14", (kernel_ulong_t)&mcp47feb14_chip_features }, + { "mcp47feb18", (kernel_ulong_t)&mcp47feb18_chip_features }, + { "mcp47feb21", (kernel_ulong_t)&mcp47feb21_chip_features }, + { "mcp47feb22", (kernel_ulong_t)&mcp47feb22_chip_features }, + { "mcp47feb24", (kernel_ulong_t)&mcp47feb24_chip_features }, + { "mcp47feb28", (kernel_ulong_t)&mcp47feb28_chip_features }, + { "mcp47fvb01", (kernel_ulong_t)&mcp47fvb01_chip_features }, + { "mcp47fvb02", (kernel_ulong_t)&mcp47fvb02_chip_features }, + { "mcp47fvb04", (kernel_ulong_t)&mcp47fvb04_chip_features }, + { "mcp47fvb08", (kernel_ulong_t)&mcp47fvb08_chip_features }, + { "mcp47fvb11", (kernel_ulong_t)&mcp47fvb11_chip_features }, + { "mcp47fvb12", (kernel_ulong_t)&mcp47fvb12_chip_features }, + { "mcp47fvb14", (kernel_ulong_t)&mcp47fvb14_chip_features }, + { "mcp47fvb18", (kernel_ulong_t)&mcp47fvb18_chip_features }, + { "mcp47fvb21", (kernel_ulong_t)&mcp47fvb21_chip_features }, + { "mcp47fvb22", (kernel_ulong_t)&mcp47fvb22_chip_features }, + { "mcp47fvb24", (kernel_ulong_t)&mcp47fvb24_chip_features }, + { "mcp47fvb28", (kernel_ulong_t)&mcp47fvb28_chip_features }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mcp47feb02_id); + +static const struct of_device_id mcp47feb02_of_match[] = { + { .compatible = "microchip,mcp47feb01", .data = &mcp47feb01_chip_features }, + { .compatible = "microchip,mcp47feb02", .data = &mcp47feb02_chip_features }, + { .compatible = "microchip,mcp47feb04", .data = &mcp47feb04_chip_features }, + { .compatible = "microchip,mcp47feb08", .data = &mcp47feb08_chip_features }, + { .compatible = "microchip,mcp47feb11", .data = &mcp47feb11_chip_features }, + { .compatible = "microchip,mcp47feb12", .data = &mcp47feb12_chip_features }, + { .compatible = "microchip,mcp47feb14", .data = &mcp47feb14_chip_features }, + { .compatible = "microchip,mcp47feb18", .data = &mcp47feb18_chip_features }, + { .compatible = "microchip,mcp47feb21", .data = &mcp47feb21_chip_features }, + { .compatible = "microchip,mcp47feb22", .data = &mcp47feb22_chip_features }, + { .compatible = "microchip,mcp47feb24", .data = &mcp47feb24_chip_features }, + { .compatible = "microchip,mcp47feb28", .data = &mcp47feb28_chip_features }, + { .compatible = "microchip,mcp47fvb01", .data = &mcp47fvb01_chip_features }, + { .compatible = "microchip,mcp47fvb02", .data = &mcp47fvb02_chip_features }, + { .compatible = "microchip,mcp47fvb04", .data = &mcp47fvb04_chip_features }, + { .compatible = "microchip,mcp47fvb08", .data = &mcp47fvb08_chip_features }, + { .compatible = "microchip,mcp47fvb11", .data = &mcp47fvb11_chip_features }, + { .compatible = "microchip,mcp47fvb12", .data = &mcp47fvb12_chip_features }, + { .compatible = "microchip,mcp47fvb14", .data = &mcp47fvb14_chip_features }, + { .compatible = "microchip,mcp47fvb18", .data = &mcp47fvb18_chip_features }, + { .compatible = "microchip,mcp47fvb21", .data = &mcp47fvb21_chip_features }, + { .compatible = "microchip,mcp47fvb22", .data = &mcp47fvb22_chip_features }, + { .compatible = "microchip,mcp47fvb24", .data = &mcp47fvb24_chip_features }, + { .compatible = "microchip,mcp47fvb28", .data = &mcp47fvb28_chip_features }, + { } +}; +MODULE_DEVICE_TABLE(of, mcp47feb02_of_match); + +static struct i2c_driver mcp47feb02_driver = { + .driver = { + .name = "mcp47feb02", + .of_match_table = mcp47feb02_of_match, + .pm = pm_sleep_ptr(&mcp47feb02_pm_ops), + }, + .probe = mcp47feb02_probe, + .id_table = mcp47feb02_id, +}; +module_i2c_driver(mcp47feb02_driver); + +MODULE_AUTHOR("Ariana Lazar "); +MODULE_DESCRIPTION("IIO driver for MCP47FEB02 Multi-Channel DAC with I2C interface"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/dummy/iio_dummy_evgen.c b/drivers/iio/dummy/iio_dummy_evgen.c index 16d3f144dda0..30f0ae7c5116 100644 --- a/drivers/iio/dummy/iio_dummy_evgen.c +++ b/drivers/iio/dummy/iio_dummy_evgen.c @@ -47,7 +47,7 @@ static int iio_dummy_evgen_create(void) { int ret; - iio_evgen = kzalloc(sizeof(*iio_evgen), GFP_KERNEL); + iio_evgen = kzalloc_obj(*iio_evgen); if (!iio_evgen) return -ENOMEM; diff --git a/drivers/iio/dummy/iio_simple_dummy.c b/drivers/iio/dummy/iio_simple_dummy.c index 8575d4a08963..19fcdbbc11c6 100644 --- a/drivers/iio/dummy/iio_simple_dummy.c +++ b/drivers/iio/dummy/iio_simple_dummy.c @@ -588,7 +588,7 @@ static struct iio_sw_device *iio_dummy_probe(const char *name) * parent = &client->dev; */ - swd = kzalloc(sizeof(*swd), GFP_KERNEL); + swd = kzalloc_obj(*swd); if (!swd) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/dummy/iio_simple_dummy_buffer.c b/drivers/iio/dummy/iio_simple_dummy_buffer.c index e35e0596cbfb..57f3611a86d9 100644 --- a/drivers/iio/dummy/iio_simple_dummy_buffer.c +++ b/drivers/iio/dummy/iio_simple_dummy_buffer.c @@ -60,7 +60,7 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p) * - A buffer at the end of the structure accessed via iio_priv() * that is marked __aligned(IIO_DMA_MINALIGN). */ - scan = kzalloc(sizeof(*scan), GFP_KERNEL); + scan = kzalloc_obj(*scan); if (!scan) goto done; diff --git a/drivers/iio/frequency/adf4377.c b/drivers/iio/frequency/adf4377.c index 08833b7035e4..8e2da218d48a 100644 --- a/drivers/iio/frequency/adf4377.c +++ b/drivers/iio/frequency/adf4377.c @@ -8,7 +8,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -435,9 +437,14 @@ struct adf4377_state { struct gpio_desc *gpio_ce; struct gpio_desc *gpio_enclk1; struct gpio_desc *gpio_enclk2; + struct clk *clk; + struct clk *clkout; + struct clk_hw hw; u8 buf[2] __aligned(IIO_DMA_MINALIGN); }; +#define to_adf4377_state(h) container_of(h, struct adf4377_state, hw) + static const char * const adf4377_muxout_modes[] = { [ADF4377_MUXOUT_HIGH_Z] = "high_z", [ADF4377_MUXOUT_LKDET] = "lock_detect", @@ -501,7 +508,7 @@ static int adf4377_soft_reset(struct adf4377_state *st) return ret; return regmap_read_poll_timeout(st->regmap, 0x0, read_val, - !(read_val & (ADF4377_0000_SOFT_RESET_R_MSK | + !(read_val & (ADF4377_0000_SOFT_RESET_MSK | ADF4377_0000_SOFT_RESET_R_MSK)), 200, 200 * 100); } @@ -929,6 +936,110 @@ static int adf4377_freq_change(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; } +static unsigned long adf4377_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct adf4377_state *st = to_adf4377_state(hw); + u64 freq; + int ret; + + ret = adf4377_get_freq(st, &freq); + if (ret) + return 0; + + return freq; +} + +static int adf4377_clk_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct adf4377_state *st = to_adf4377_state(hw); + + return adf4377_set_freq(st, rate); +} + +static int adf4377_clk_prepare(struct clk_hw *hw) +{ + struct adf4377_state *st = to_adf4377_state(hw); + + return regmap_update_bits(st->regmap, 0x1a, ADF4377_001A_PD_CLKOUT1_MSK | + ADF4377_001A_PD_CLKOUT2_MSK, + FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 0) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 0)); +} + +static void adf4377_clk_unprepare(struct clk_hw *hw) +{ + struct adf4377_state *st = to_adf4377_state(hw); + + regmap_update_bits(st->regmap, 0x1a, ADF4377_001A_PD_CLKOUT1_MSK | + ADF4377_001A_PD_CLKOUT2_MSK, + FIELD_PREP(ADF4377_001A_PD_CLKOUT1_MSK, 1) | + FIELD_PREP(ADF4377_001A_PD_CLKOUT2_MSK, 1)); +} + +static int adf4377_clk_is_prepared(struct clk_hw *hw) +{ + struct adf4377_state *st = to_adf4377_state(hw); + unsigned int readval; + int ret; + + ret = regmap_read(st->regmap, 0x1a, &readval); + if (ret) + return ret; + + return !(readval & (ADF4377_001A_PD_CLKOUT1_MSK | ADF4377_001A_PD_CLKOUT2_MSK)); +} + +static const struct clk_ops adf4377_clk_ops = { + .recalc_rate = adf4377_clk_recalc_rate, + .set_rate = adf4377_clk_set_rate, + .prepare = adf4377_clk_prepare, + .unprepare = adf4377_clk_unprepare, + .is_prepared = adf4377_clk_is_prepared, +}; + +static int adf4377_clk_register(struct adf4377_state *st) +{ + struct spi_device *spi = st->spi; + struct device *dev = &spi->dev; + struct clk_init_data init; + struct clk_parent_data parent_data; + int ret; + + if (!device_property_present(dev, "#clock-cells")) + return 0; + + ret = device_property_read_string(dev, "clock-output-names", &init.name); + if (ret) { + init.name = devm_kasprintf(dev, GFP_KERNEL, "%pfw-clk", + dev_fwnode(dev)); + if (!init.name) + return -ENOMEM; + } + + parent_data.fw_name = "ref_in"; + + init.ops = &adf4377_clk_ops; + init.parent_data = &parent_data; + init.num_parents = 1; + init.flags = CLK_SET_RATE_PARENT; + + st->hw.init = &init; + ret = devm_clk_hw_register(dev, &st->hw); + if (ret) + return ret; + + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &st->hw); + if (ret) + return ret; + + st->clkout = st->hw.clk; + + return 0; +} + static const struct adf4377_chip_info adf4377_chip_info = { .name = "adf4377", .has_gpio_enclk2 = true, @@ -958,8 +1069,6 @@ static int adf4377_probe(struct spi_device *spi) indio_dev->info = &adf4377_info; indio_dev->name = "adf4377"; - indio_dev->channels = adf4377_channels; - indio_dev->num_channels = ARRAY_SIZE(adf4377_channels); st->regmap = regmap; st->spi = spi; @@ -979,6 +1088,15 @@ static int adf4377_probe(struct spi_device *spi) if (ret) return ret; + ret = adf4377_clk_register(st); + if (ret) + return ret; + + if (!st->clkout) { + indio_dev->channels = adf4377_channels; + indio_dev->num_channels = ARRAY_SIZE(adf4377_channels); + } + return devm_iio_device_register(&spi->dev, indio_dev); } diff --git a/drivers/iio/gyro/adxrs290.c b/drivers/iio/gyro/adxrs290.c index 8fcb41f45baa..3efe385ebedc 100644 --- a/drivers/iio/gyro/adxrs290.c +++ b/drivers/iio/gyro/adxrs290.c @@ -597,7 +597,7 @@ static int adxrs290_probe_trigger(struct iio_dev *indio_dev) ret = devm_request_irq(&st->spi->dev, st->spi->irq, &iio_trigger_generic_data_rdy_poll, - IRQF_ONESHOT, "adxrs290_irq", st->dready_trig); + IRQF_NO_THREAD, "adxrs290_irq", st->dready_trig); if (ret < 0) return dev_err_probe(&st->spi->dev, ret, "request irq %d failed\n", st->spi->irq); diff --git a/drivers/iio/gyro/itg3200_buffer.c b/drivers/iio/gyro/itg3200_buffer.c index a624400a239c..cf97adfa9727 100644 --- a/drivers/iio/gyro/itg3200_buffer.c +++ b/drivers/iio/gyro/itg3200_buffer.c @@ -118,11 +118,9 @@ int itg3200_probe_trigger(struct iio_dev *indio_dev) if (!st->trig) return -ENOMEM; - ret = request_irq(st->i2c->irq, - &iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_RISING, - "itg3200_data_rdy", - st->trig); + ret = request_irq(st->i2c->irq, &iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + "itg3200_data_rdy", st->trig); if (ret) goto error_free_trig; diff --git a/drivers/iio/gyro/itg3200_core.c b/drivers/iio/gyro/itg3200_core.c index cd8a2dae56cd..bfe95ec1abda 100644 --- a/drivers/iio/gyro/itg3200_core.c +++ b/drivers/iio/gyro/itg3200_core.c @@ -93,6 +93,8 @@ static int itg3200_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_RAW: reg = (u8)chan->address; ret = itg3200_read_reg_s16(indio_dev, reg, val); + if (ret) + return ret; return IIO_VAL_INT; case IIO_CHAN_INFO_SCALE: *val = 0; diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c index 67ae7d1012bc..317e7b217ec6 100644 --- a/drivers/iio/gyro/mpu3050-core.c +++ b/drivers/iio/gyro/mpu3050-core.c @@ -322,7 +322,9 @@ static int mpu3050_read_raw(struct iio_dev *indio_dev, } case IIO_CHAN_INFO_RAW: /* Resume device */ - pm_runtime_get_sync(mpu3050->dev); + ret = pm_runtime_resume_and_get(mpu3050->dev); + if (ret) + return ret; mutex_lock(&mpu3050->lock); ret = mpu3050_set_8khz_samplerate(mpu3050); @@ -647,14 +649,20 @@ static irqreturn_t mpu3050_trigger_handler(int irq, void *p) static int mpu3050_buffer_preenable(struct iio_dev *indio_dev) { struct mpu3050 *mpu3050 = iio_priv(indio_dev); + int ret; - pm_runtime_get_sync(mpu3050->dev); + ret = pm_runtime_resume_and_get(mpu3050->dev); + if (ret) + return ret; /* Unless we have OUR trigger active, run at full speed */ - if (!mpu3050->hw_irq_trigger) - return mpu3050_set_8khz_samplerate(mpu3050); + if (!mpu3050->hw_irq_trigger) { + ret = mpu3050_set_8khz_samplerate(mpu3050); + if (ret) + pm_runtime_put_autosuspend(mpu3050->dev); + } - return 0; + return ret; } static int mpu3050_buffer_postdisable(struct iio_dev *indio_dev) @@ -1162,10 +1170,8 @@ int mpu3050_common_probe(struct device *dev, mpu3050->regs[1].supply = mpu3050_reg_vlogic; ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(mpu3050->regs), mpu3050->regs); - if (ret) { - dev_err(dev, "Cannot get regulators\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "Cannot get regulators\n"); ret = mpu3050_power_up(mpu3050); if (ret) diff --git a/drivers/iio/gyro/mpu3050-i2c.c b/drivers/iio/gyro/mpu3050-i2c.c index 092878f2c886..6549b22e643d 100644 --- a/drivers/iio/gyro/mpu3050-i2c.c +++ b/drivers/iio/gyro/mpu3050-i2c.c @@ -19,8 +19,7 @@ static int mpu3050_i2c_bypass_select(struct i2c_mux_core *mux, u32 chan_id) struct mpu3050 *mpu3050 = i2c_mux_priv(mux); /* Just power up the device, that is all that is needed */ - pm_runtime_get_sync(mpu3050->dev); - return 0; + return pm_runtime_resume_and_get(mpu3050->dev); } static int mpu3050_i2c_bypass_deselect(struct i2c_mux_core *mux, u32 chan_id) diff --git a/drivers/iio/health/afe4403.c b/drivers/iio/health/afe4403.c index 0e5a512e3bb8..d358f4d5e5da 100644 --- a/drivers/iio/health/afe4403.c +++ b/drivers/iio/health/afe4403.c @@ -540,11 +540,10 @@ static int afe4403_probe(struct spi_device *spi) return ret; } - ret = devm_request_threaded_irq(dev, afe->irq, - iio_trigger_generic_data_rdy_poll, - NULL, IRQF_ONESHOT, - AFE4403_DRIVER_NAME, - afe->trig); + ret = devm_request_irq(dev, afe->irq, + iio_trigger_generic_data_rdy_poll, + IRQF_NO_THREAD, AFE4403_DRIVER_NAME, + afe->trig); if (ret) { dev_err(dev, "Unable to request IRQ\n"); return ret; diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c index 768d794e574b..032da52a96d0 100644 --- a/drivers/iio/health/afe4404.c +++ b/drivers/iio/health/afe4404.c @@ -547,11 +547,10 @@ static int afe4404_probe(struct i2c_client *client) return ret; } - ret = devm_request_threaded_irq(dev, afe->irq, - iio_trigger_generic_data_rdy_poll, - NULL, IRQF_ONESHOT, - AFE4404_DRIVER_NAME, - afe->trig); + ret = devm_request_irq(dev, afe->irq, + iio_trigger_generic_data_rdy_poll, + IRQF_NO_THREAD, AFE4404_DRIVER_NAME, + afe->trig); if (ret) { dev_err(dev, "Unable to request IRQ\n"); return ret; diff --git a/drivers/iio/health/max30100.c b/drivers/iio/health/max30100.c index 3d441013893c..7dfdb5eb305e 100644 --- a/drivers/iio/health/max30100.c +++ b/drivers/iio/health/max30100.c @@ -417,13 +417,7 @@ static int max30100_read_raw(struct iio_dev *indio_dev, * Temperature reading can only be acquired while engine * is running */ - if (iio_device_claim_buffer_mode(indio_dev)) { - /* - * Replacing -EBUSY or other error code - * returned by iio_device_claim_buffer_mode() - * because user space may rely on the current - * one. - */ + if (!iio_device_try_claim_buffer_mode(indio_dev)) { ret = -EAGAIN; } else { ret = max30100_get_temp(data, val); diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index a48c0881a4c7..47da44efd68b 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -467,44 +467,29 @@ static int max30102_read_raw(struct iio_dev *indio_dev, int *val, int *val2, long mask) { struct max30102_data *data = iio_priv(indio_dev); - int ret = -EINVAL; + int ret; switch (mask) { - case IIO_CHAN_INFO_RAW: + case IIO_CHAN_INFO_RAW: { /* * Temperature reading can only be acquired when not in * shutdown; leave shutdown briefly when buffer not running */ -any_mode_retry: - if (iio_device_claim_buffer_mode(indio_dev)) { - /* - * This one is a *bit* hacky. If we cannot claim buffer - * mode, then try direct mode so that we make sure - * things cannot concurrently change. And we just keep - * trying until we get one of the modes... - */ - if (!iio_device_claim_direct(indio_dev)) - goto any_mode_retry; + IIO_DEV_GUARD_CURRENT_MODE(indio_dev); - ret = max30102_get_temp(data, val, true); - iio_device_release_direct(indio_dev); - } else { - ret = max30102_get_temp(data, val, false); - iio_device_release_buffer_mode(indio_dev); - } + ret = max30102_get_temp(data, val, !iio_buffer_enabled(indio_dev)); if (ret) return ret; - ret = IIO_VAL_INT; - break; + return IIO_VAL_INT; + } case IIO_CHAN_INFO_SCALE: *val = 1000; /* 62.5 */ *val2 = 16; - ret = IIO_VAL_FRACTIONAL; - break; + return IIO_VAL_FRACTIONAL; + default: + return -EINVAL; } - - return ret; } static const struct iio_info max30102_info = { diff --git a/drivers/iio/imu/adis.c b/drivers/iio/imu/adis.c index d160147cce0b..a2bc1d14ed91 100644 --- a/drivers/iio/imu/adis.c +++ b/drivers/iio/imu/adis.c @@ -526,7 +526,7 @@ int adis_init(struct adis *adis, struct iio_dev *indio_dev, adis->spi = spi; adis->data = data; - if (!adis->ops->write && !adis->ops->read && !adis->ops->reset) + if (!adis->ops) adis->ops = &adis_default_ops; else if (!adis->ops->write || !adis->ops->read || !adis->ops->reset) return -EINVAL; diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index cd3db2388164..501da4eaef69 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -33,7 +33,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, else burst_max_length = burst_length; - adis->xfer = kcalloc(2, sizeof(*adis->xfer), GFP_KERNEL); + adis->xfer = kzalloc_objs(*adis->xfer, 2); if (!adis->xfer) return -ENOMEM; @@ -81,7 +81,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, scan_count = indio_dev->scan_bytes / 2; - adis->xfer = kcalloc(scan_count + 1, sizeof(*adis->xfer), GFP_KERNEL); + adis->xfer = kzalloc_objs(*adis->xfer, scan_count + 1); if (!adis->xfer) return -ENOMEM; diff --git a/drivers/iio/imu/bmi270/bmi270_i2c.c b/drivers/iio/imu/bmi270/bmi270_i2c.c index b909a421ad01..b92da4e0776f 100644 --- a/drivers/iio/imu/bmi270/bmi270_i2c.c +++ b/drivers/iio/imu/bmi270/bmi270_i2c.c @@ -37,6 +37,7 @@ static const struct i2c_device_id bmi270_i2c_id[] = { { "bmi270", (kernel_ulong_t)&bmi270_chip_info }, { } }; +MODULE_DEVICE_TABLE(i2c, bmi270_i2c_id); static const struct acpi_device_id bmi270_acpi_match[] = { /* GPD Win Mini, Aya Neo AIR Pro, OXP Mini Pro, etc. */ @@ -45,12 +46,14 @@ static const struct acpi_device_id bmi270_acpi_match[] = { { "BMI0260", (kernel_ulong_t)&bmi260_chip_info }, { } }; +MODULE_DEVICE_TABLE(acpi, bmi270_acpi_match); static const struct of_device_id bmi270_of_match[] = { { .compatible = "bosch,bmi260", .data = &bmi260_chip_info }, { .compatible = "bosch,bmi270", .data = &bmi270_chip_info }, { } }; +MODULE_DEVICE_TABLE(of, bmi270_of_match); static struct i2c_driver bmi270_i2c_driver = { .driver = { diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 54760d8f92a2..0ab6eddf0543 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -651,6 +651,8 @@ static int inv_icm42600_accel_write_odr(struct iio_dev *indio_dev, return -EINVAL; conf.odr = inv_icm42600_accel_odr_conv[idx / 2]; + if (conf.odr == st->conf.accel.odr) + return 0; pm_runtime_get_sync(dev); mutex_lock(&st->lock); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c index ada968be954d..68a395758031 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c @@ -371,6 +371,8 @@ static int inv_icm42600_buffer_predisable(struct iio_dev *indio_dev) static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_sensor_state *sensor_st = iio_priv(indio_dev); + struct inv_sensors_timestamp *ts = &sensor_st->ts; struct device *dev = regmap_get_device(st->map); unsigned int sensor; unsigned int *watermark; @@ -392,6 +394,8 @@ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) mutex_lock(&st->lock); + inv_sensors_timestamp_apply_odr(ts, 0, 0, 0); + ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor); if (ret) goto out_unlock; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index 7ef0a25ec74f..11339ddf1da3 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -358,6 +358,8 @@ static int inv_icm42600_gyro_write_odr(struct iio_dev *indio_dev, return -EINVAL; conf.odr = inv_icm42600_gyro_odr_conv[idx / 2]; + if (conf.odr == st->conf.gyro.odr) + return 0; pm_runtime_get_sync(dev); mutex_lock(&st->lock); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c index 30f6a9595eea..727b03d541a5 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c @@ -59,10 +59,7 @@ int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (!iio_device_claim_direct(indio_dev)) - return -EBUSY; ret = inv_icm42600_temp_read(st, &temp); - iio_device_release_direct(indio_dev); if (ret) return ret; *val = temp; diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600.h b/drivers/iio/imu/inv_icm45600/inv_icm45600.h index c5b5446f6c3b..1c796d4b2a40 100644 --- a/drivers/iio/imu/inv_icm45600/inv_icm45600.h +++ b/drivers/iio/imu/inv_icm45600/inv_icm45600.h @@ -205,7 +205,7 @@ struct inv_icm45600_sensor_state { #define INV_ICM45600_SPI_SLEW_RATE_38NS 0 #define INV_ICM45600_REG_INT1_CONFIG2 0x0018 -#define INV_ICM45600_INT1_CONFIG2_PUSH_PULL BIT(2) +#define INV_ICM45600_INT1_CONFIG2_OPEN_DRAIN BIT(2) #define INV_ICM45600_INT1_CONFIG2_LATCHED BIT(1) #define INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH BIT(0) #define INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW 0x00 diff --git a/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c b/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c index 25bd9757a594..d49053161a65 100644 --- a/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c +++ b/drivers/iio/imu/inv_icm45600/inv_icm45600_core.c @@ -637,8 +637,8 @@ static int inv_icm45600_irq_init(struct inv_icm45600_state *st, int irq, break; } - if (!open_drain) - val |= INV_ICM45600_INT1_CONFIG2_PUSH_PULL; + if (open_drain) + val |= INV_ICM45600_INT1_CONFIG2_OPEN_DRAIN; ret = regmap_write(st->map, INV_ICM45600_REG_INT1_CONFIG2, val); if (ret) @@ -744,6 +744,11 @@ int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chi */ fsleep(5 * USEC_PER_MSEC); + /* set pm_runtime active early for disable vddio resource cleanup */ + ret = pm_runtime_set_active(dev); + if (ret) + return ret; + ret = inv_icm45600_enable_regulator_vddio(st); if (ret) return ret; @@ -776,7 +781,7 @@ int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chi if (ret) return ret; - ret = devm_pm_runtime_set_active_enabled(dev); + ret = devm_pm_runtime_enable(dev); if (ret) return ret; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index b2fa1f4957a5..5796896d54cd 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1943,6 +1943,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, irq_type); return -EINVAL; } + + /* + * Acking interrupts by status register does not work reliably + * but seem to work when this bit is set. + */ + if (st->chip_type == INV_MPU9150) + st->irq_mask |= INV_MPU6050_INT_RD_CLEAR; + device_set_wakeup_capable(dev, true); st->vdd_supply = devm_regulator_get(dev, "vdd"); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 211901f8b8eb..6239b1a803f7 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -390,6 +390,8 @@ struct inv_mpu6050_state { /* enable level triggering */ #define INV_MPU6050_LATCH_INT_EN 0x20 #define INV_MPU6050_BIT_BYPASS_EN 0x2 +/* allow acking interrupts by any register read */ +#define INV_MPU6050_INT_RD_CLEAR 0x10 /* Allowed timestamp period jitter in percent */ #define INV_MPU6050_TS_PERIOD_JITTER 4 diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c index 10a473342075..22c1ce66f99e 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c @@ -248,7 +248,6 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p) switch (st->chip_type) { case INV_MPU6000: case INV_MPU6050: - case INV_MPU9150: /* * WoM is not supported and interrupt status read seems to be broken for * some chips. Since data ready is the only interrupt, bypass interrupt @@ -257,6 +256,10 @@ static irqreturn_t inv_mpu6050_interrupt_handle(int irq, void *p) wom_bits = 0; int_status = INV_MPU6050_BIT_RAW_DATA_RDY_INT; goto data_ready_interrupt; + case INV_MPU9150: + /* IRQ needs to be acked */ + wom_bits = 0; + break; case INV_MPU6500: case INV_MPU6515: case INV_MPU6880: diff --git a/drivers/iio/imu/smi330/smi330_core.c b/drivers/iio/imu/smi330/smi330_core.c index 7564f12543e0..7ec5ae7f521a 100644 --- a/drivers/iio/imu/smi330/smi330_core.c +++ b/drivers/iio/imu/smi330/smi330_core.c @@ -67,10 +67,6 @@ #define SMI330_CHIP_ID 0x42 #define SMI330_SOFT_RESET_DELAY 2000 -/* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */ -#define smi330_field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) -#define smi330_field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) - #define SMI330_ACCEL_CHANNEL(_axis) { \ .type = IIO_ACCEL, \ .modified = 1, \ @@ -361,7 +357,7 @@ static int smi330_get_sensor_config(struct smi330_data *data, if (ret) return ret; - reg_val = smi330_field_get(attr->mask, reg_val); + reg_val = field_get(attr->mask, reg_val); if (attr->type == IIO_VAL_INT) { for (i = 0; i < attr->len; i++) { @@ -410,7 +406,7 @@ static int smi330_set_sensor_config(struct smi330_data *data, if (ret) return ret; - reg_val = smi330_field_prep(attr->mask, reg_val); + reg_val = field_prep(attr->mask, reg_val); ret = regmap_update_bits(data->regmap, reg, attr->mask, reg_val); if (ret) return ret; @@ -475,7 +471,6 @@ static int smi330_read_avail(struct iio_dev *indio_dev, *vals = smi330_average_attr.vals; *length = smi330_average_attr.len; *type = smi330_average_attr.type; - *type = IIO_VAL_INT; return IIO_AVAIL_LIST; case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: *vals = smi330_bandwidth_attr.vals; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index 6405a5367d76..07b1773c87bd 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -79,10 +79,11 @@ enum st_lsm6dsx_hw_id { #define ST_LSM6DSX_MAX_TAGGED_WORD_LEN ((32 / ST_LSM6DSX_TAGGED_SAMPLE_SIZE) \ * ST_LSM6DSX_TAGGED_SAMPLE_SIZE) #define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask)) +#define st_lsm6dsx_field_get(mask, reg) ((reg & mask) >> __ffs(mask)) -#define ST_LSM6DSX_CHANNEL_ACC(chan_type, addr, mod, scan_idx) \ +#define ST_LSM6DSX_CHANNEL_ACC(addr, mod, scan_idx, events) \ { \ - .type = chan_type, \ + .type = IIO_ACCEL, \ .address = addr, \ .modified = 1, \ .channel2 = mod, \ @@ -96,9 +97,9 @@ enum st_lsm6dsx_hw_id { .storagebits = 16, \ .endianness = IIO_LE, \ }, \ - .event_spec = &st_lsm6dsx_event, \ + .event_spec = events, \ + .num_event_specs = ARRAY_SIZE(events), \ .ext_info = st_lsm6dsx_ext_info, \ - .num_event_specs = 1, \ } #define ST_LSM6DSX_CHANNEL(chan_type, addr, mod, scan_idx) \ @@ -260,14 +261,31 @@ struct st_lsm6dsx_shub_settings { u8 pause; }; +enum st_lsm6dsx_event_id { + ST_LSM6DSX_EVENT_WAKEUP, + ST_LSM6DSX_EVENT_TAP, + ST_LSM6DSX_EVENT_MAX +}; + +struct st_lsm6dsx_event_src { + struct st_lsm6dsx_reg value; + struct st_lsm6dsx_reg x_value; + struct st_lsm6dsx_reg y_value; + struct st_lsm6dsx_reg z_value; + u8 enable_mask; + u8 enable_axis_reg; + u8 enable_x_mask; + u8 enable_y_mask; + u8 enable_z_mask; + struct st_lsm6dsx_reg status; + u8 status_x_mask; + u8 status_y_mask; + u8 status_z_mask; +}; + struct st_lsm6dsx_event_settings { struct st_lsm6dsx_reg enable_reg; - struct st_lsm6dsx_reg wakeup_reg; - u8 wakeup_src_reg; - u8 wakeup_src_status_mask; - u8 wakeup_src_z_mask; - u8 wakeup_src_y_mask; - u8 wakeup_src_x_mask; + struct st_lsm6dsx_event_src sources[ST_LSM6DSX_EVENT_MAX]; }; enum st_lsm6dsx_sensor_id { @@ -353,8 +371,8 @@ struct st_lsm6dsx_settings { struct { struct st_lsm6dsx_reg irq1; struct st_lsm6dsx_reg irq2; - struct st_lsm6dsx_reg irq1_func; - struct st_lsm6dsx_reg irq2_func; + u8 irq1_func; + u8 irq2_func; struct st_lsm6dsx_reg lir; struct st_lsm6dsx_reg clear_on_read; struct st_lsm6dsx_reg hla; @@ -430,7 +448,6 @@ struct st_lsm6dsx_sensor { * @sip: Total number of samples (acc/gyro/ts) in a given pattern. * @buff: Device read buffer. * @irq_routing: pointer to interrupt routing configuration. - * @event_threshold: wakeup event threshold. * @enable_event: enabled event bitmask. * @iio_devs: Pointers to acc/gyro iio_dev instances. * @settings: Pointer to the specific sensor settings in use. @@ -453,9 +470,8 @@ struct st_lsm6dsx_hw { u8 ts_sip; u8 sip; - const struct st_lsm6dsx_reg *irq_routing; - u8 event_threshold; - u8 enable_event; + u8 irq_routing; + u8 enable_event[ST_LSM6DSX_EVENT_MAX]; u8 *buff; @@ -471,13 +487,6 @@ struct st_lsm6dsx_hw { } scan[ST_LSM6DSX_ID_MAX]; }; -static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { - .type = IIO_EV_TYPE_THRESH, - .dir = IIO_EV_DIR_EITHER, - .mask_separate = BIT(IIO_EV_INFO_VALUE) | - BIT(IIO_EV_INFO_ENABLE) -}; - static __maybe_unused const unsigned long st_lsm6dsx_available_scan_masks[] = { 0x7, 0x0, }; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index dc78227952a7..450cb5b47346 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -94,10 +94,41 @@ #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f +static const struct iio_event_spec st_lsm6dsx_ev_motion[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + +static const struct iio_event_spec st_lsm6dsx_ev_motion_tap[] = { + { + .type = IIO_EV_TYPE_THRESH, + .dir = IIO_EV_DIR_EITHER, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, + { + .type = IIO_EV_TYPE_GESTURE, + .dir = IIO_EV_DIR_SINGLETAP, + .mask_separate = BIT(IIO_EV_INFO_VALUE) | + BIT(IIO_EV_INFO_ENABLE), + }, +}; + static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { - ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), - ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), - ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), + ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion), + ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion), + ST_LSM6DSX_CHANNEL_ACC(0x2c, IIO_MOD_Z, 2, st_lsm6dsx_ev_motion), + IIO_CHAN_SOFT_TIMESTAMP(3), +}; + +static const struct iio_chan_spec st_lsm6dsx_acc_tap_channels[] = { + ST_LSM6DSX_CHANNEL_ACC(0x28, IIO_MOD_X, 0, st_lsm6dsx_ev_motion_tap), + ST_LSM6DSX_CHANNEL_ACC(0x2a, IIO_MOD_Y, 1, st_lsm6dsx_ev_motion_tap), + ST_LSM6DSX_CHANNEL_ACC(0x2c, IIO_MOD_Z, 2, st_lsm6dsx_ev_motion_tap), IIO_CHAN_SOFT_TIMESTAMP(3), }; @@ -326,14 +357,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(0), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x12, .mask = BIT(5), @@ -386,15 +411,22 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, }, .event_settings = { - .wakeup_reg = { - .addr = 0x5B, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x1b, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, }, - .wakeup_src_reg = 0x1b, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -492,14 +524,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(0), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x12, .mask = BIT(5), @@ -552,15 +578,22 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, }, .event_settings = { - .wakeup_reg = { - .addr = 0x5B, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x1b, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, }, - .wakeup_src_reg = 0x1b, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -688,14 +721,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(0), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x12, .mask = BIT(5), @@ -789,15 +816,22 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(7), }, - .wakeup_reg = { - .addr = 0x5B, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x1b, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, }, - .wakeup_src_reg = 0x1b, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -937,14 +971,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x56, .mask = BIT(6), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x12, .mask = BIT(5), @@ -1028,15 +1056,22 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(7), }, - .wakeup_reg = { - .addr = 0x5b, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x1b, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, }, - .wakeup_src_reg = 0x1b, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -1152,14 +1187,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x56, .mask = BIT(6), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x12, .mask = BIT(5), @@ -1211,15 +1240,22 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x58, .mask = BIT(7), }, - .wakeup_reg = { - .addr = 0x5B, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x1b, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, }, - .wakeup_src_reg = 0x1b, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -1248,8 +1284,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6dsx_acc_tap_channels, + .len = ARRAY_SIZE(st_lsm6dsx_acc_tap_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6dsx_gyro_channels, @@ -1329,14 +1365,8 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x56, .mask = BIT(0), }, - .irq1_func = { - .addr = 0x5e, - .mask = BIT(5), - }, - .irq2_func = { - .addr = 0x5f, - .mask = BIT(5), - }, + .irq1_func = 0x5e, + .irq2_func = 0x5f, .hla = { .addr = 0x03, .mask = BIT(4), @@ -1419,15 +1449,48 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x50, .mask = BIT(7), }, - .wakeup_reg = { - .addr = 0x5b, - .mask = GENMASK(5, 0), + .sources = { + [ST_LSM6DSX_EVENT_WAKEUP] = { + .value = { + .addr = 0x5b, + .mask = GENMASK(5, 0), + }, + .enable_mask = BIT(5), + .status = { + .addr = 0x45, + .mask = BIT(3), + }, + .status_z_mask = BIT(0), + .status_y_mask = BIT(1), + .status_x_mask = BIT(2), + }, + [ST_LSM6DSX_EVENT_TAP] = { + .x_value = { + .addr = 0x57, + .mask = GENMASK(4, 0), + }, + .y_value = { + .addr = 0x58, + .mask = GENMASK(4, 0), + }, + .z_value = { + .addr = 0x59, + .mask = GENMASK(4, 0), + }, + .enable_mask = BIT(6), + .enable_axis_reg = 0x56, + .enable_x_mask = BIT(3), + .enable_y_mask = BIT(2), + .enable_z_mask = BIT(1), + .status = { + .addr = 0x46, + .mask = BIT(5), + }, + .status_x_mask = BIT(2), + .status_y_mask = BIT(1), + .status_z_mask = BIT(0), + }, }, - .wakeup_src_reg = 0x45, - .wakeup_src_status_mask = BIT(3), - .wakeup_src_z_mask = BIT(0), - .wakeup_src_y_mask = BIT(1), - .wakeup_src_x_mask = BIT(2), }, }, { @@ -1754,20 +1817,25 @@ __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, } static int -st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable) +st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor) { struct st_lsm6dsx_hw *hw = sensor->hw; + int event; - if (sensor->id == ST_LSM6DSX_ID_GYRO || enable) + if (sensor->id != ST_LSM6DSX_ID_ACC) return 0; - return hw->enable_event; + for (event = 0; event < ST_LSM6DSX_EVENT_MAX; event++) { + if (hw->enable_event[event]) + return true; + } + return false; } int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) { - if (st_lsm6dsx_check_events(sensor, enable)) + if (st_lsm6dsx_check_events(sensor)) return 0; return __st_lsm6dsx_sensor_set_enable(sensor, enable); @@ -1795,11 +1863,9 @@ static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, if (err < 0) return err; - if (!hw->enable_event) { - err = st_lsm6dsx_sensor_set_enable(sensor, false); - if (err < 0) - return err; - } + err = st_lsm6dsx_sensor_set_enable(sensor, false); + if (err < 0) + return err; *val = (s16)le16_to_cpu(data); @@ -1876,28 +1942,106 @@ static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, return err; } -static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, bool state) +static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, + enum st_lsm6dsx_event_id event, int axis, + bool state) { - const struct st_lsm6dsx_reg *reg; + const struct st_lsm6dsx_event_src *src; unsigned int data; int err; + u8 old_enable, new_enable; - if (!hw->settings->irq_config.irq1_func.addr) + if (!hw->irq_routing) return -ENOTSUPP; - reg = &hw->settings->event_settings.enable_reg; - if (reg->addr) { - data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask); - err = st_lsm6dsx_update_bits_locked(hw, reg->addr, - reg->mask, data); - if (err < 0) - return err; + /* Enable/disable event interrupt */ + src = &hw->settings->event_settings.sources[event]; + if (src->enable_axis_reg) { + u8 enable_mask; + + switch (axis) { + case IIO_MOD_X: + enable_mask = src->enable_x_mask; + break; + case IIO_MOD_Y: + enable_mask = src->enable_y_mask; + break; + case IIO_MOD_Z: + enable_mask = src->enable_z_mask; + break; + default: + enable_mask = 0; + } + if (enable_mask) { + data = ST_LSM6DSX_SHIFT_VAL(state, enable_mask); + err = st_lsm6dsx_update_bits_locked(hw, + src->enable_axis_reg, + enable_mask, data); + if (err < 0) + return err; + } } - /* Enable wakeup interrupt */ - data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask); - return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr, - hw->irq_routing->mask, data); + /* + * If the set of axes for which the event source is enabled does not + * change from empty to non-empty or vice versa, there is nothing else + * to do. + */ + old_enable = hw->enable_event[event]; + new_enable = state ? (old_enable | BIT(axis)) : + (old_enable & ~BIT(axis)); + if (!old_enable == !new_enable) + return 0; + + data = ST_LSM6DSX_SHIFT_VAL(state, src->enable_mask); + return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing, + src->enable_mask, data); +} + +static enum st_lsm6dsx_event_id +st_lsm6dsx_get_event_id(enum iio_event_type type) +{ + switch (type) { + case IIO_EV_TYPE_THRESH: + return ST_LSM6DSX_EVENT_WAKEUP; + case IIO_EV_TYPE_GESTURE: + return ST_LSM6DSX_EVENT_TAP; + default: + return ST_LSM6DSX_EVENT_MAX; + } +} + +static const struct st_lsm6dsx_reg * +st_lsm6dsx_get_event_reg(struct st_lsm6dsx_hw *hw, + enum st_lsm6dsx_event_id event, + const struct iio_chan_spec *chan) +{ + const struct st_lsm6dsx_event_src *src; + const struct st_lsm6dsx_reg *reg; + + src = &hw->settings->event_settings.sources[event]; + switch (chan->channel2) { + case IIO_MOD_X: + reg = &src->x_value; + break; + case IIO_MOD_Y: + reg = &src->y_value; + break; + case IIO_MOD_Z: + reg = &src->z_value; + break; + default: + return NULL; + } + if (reg->addr) + return reg; + + /* + * The sensor does not support configuring this event source on a per + * axis basis: return the register to configure the event source for all + * axes. + */ + return &src->value; } static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, @@ -1907,14 +2051,26 @@ static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, enum iio_event_info info, int *val, int *val2) { + enum st_lsm6dsx_event_id event = st_lsm6dsx_get_event_id(type); struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; + const struct st_lsm6dsx_reg *reg; + u8 data; + int err; - if (type != IIO_EV_TYPE_THRESH) + if (event == ST_LSM6DSX_EVENT_MAX) return -EINVAL; + reg = st_lsm6dsx_get_event_reg(hw, event, chan); + if (!reg) + return -EINVAL; + + err = st_lsm6dsx_read_locked(hw, reg->addr, &data, sizeof(data)); + if (err < 0) + return err; + *val2 = 0; - *val = hw->event_threshold; + *val = st_lsm6dsx_field_get(reg->mask, data); return IIO_VAL_INT; } @@ -1927,27 +2083,29 @@ st_lsm6dsx_write_event(struct iio_dev *iio_dev, enum iio_event_info info, int val, int val2) { + enum st_lsm6dsx_event_id event = st_lsm6dsx_get_event_id(type); struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; const struct st_lsm6dsx_reg *reg; unsigned int data; int err; - if (type != IIO_EV_TYPE_THRESH) + if (event == ST_LSM6DSX_EVENT_MAX) return -EINVAL; if (val < 0 || val > 31) return -EINVAL; - reg = &hw->settings->event_settings.wakeup_reg; + reg = st_lsm6dsx_get_event_reg(hw, event, chan); + if (!reg) + return -EINVAL; + data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); err = st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); if (err < 0) return -EINVAL; - hw->event_threshold = val; - return 0; } @@ -1957,13 +2115,56 @@ st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, enum iio_event_type type, enum iio_event_direction dir) { + enum st_lsm6dsx_event_id event = st_lsm6dsx_get_event_id(type); struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; - if (type != IIO_EV_TYPE_THRESH) + if (event == ST_LSM6DSX_EVENT_MAX) return -EINVAL; - return !!(hw->enable_event & BIT(chan->channel2)); + return !!(hw->enable_event[event] & BIT(chan->channel2)); +} + +/** + * st_lsm6dsx_check_other_events - Check for enabled sensor events. + * @hw: Sensor hardware instance. + * @curr: Current event type. + * + * Return: whether any events other than @curr are enabled. + */ +static bool st_lsm6dsx_check_other_events(struct st_lsm6dsx_hw *hw, + enum st_lsm6dsx_event_id curr) +{ + enum st_lsm6dsx_event_id other; + + for (other = 0; other < ST_LSM6DSX_EVENT_MAX; other++) { + if (other != curr && hw->enable_event[other]) + return true; + } + + return false; +} + +static int st_lsm6dsx_events_enable(struct st_lsm6dsx_sensor *sensor, + bool state) +{ + struct st_lsm6dsx_hw *hw = sensor->hw; + const struct st_lsm6dsx_reg *reg; + + reg = &hw->settings->event_settings.enable_reg; + if (reg->addr) { + int err; + + err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, + ST_LSM6DSX_SHIFT_VAL(state, reg->mask)); + if (err) + return err; + } + + if (state || !(hw->fifo_mask & BIT(sensor->id))) + return __st_lsm6dsx_sensor_set_enable(sensor, state); + + return 0; } static int @@ -1972,45 +2173,38 @@ st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, enum iio_event_type type, enum iio_event_direction dir, bool state) { + enum st_lsm6dsx_event_id event = st_lsm6dsx_get_event_id(type); struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); struct st_lsm6dsx_hw *hw = sensor->hw; u8 enable_event; int err; - if (type != IIO_EV_TYPE_THRESH) + if (event == ST_LSM6DSX_EVENT_MAX) return -EINVAL; - if (state) { - enable_event = hw->enable_event | BIT(chan->channel2); - - /* do not enable events if they are already enabled */ - if (hw->enable_event) - goto out; - } else { - enable_event = hw->enable_event & ~BIT(chan->channel2); - - /* only turn off sensor if no events is enabled */ - if (enable_event) - goto out; - } + if (state) + enable_event = hw->enable_event[event] | BIT(chan->channel2); + else + enable_event = hw->enable_event[event] & ~BIT(chan->channel2); /* stop here if no changes have been made */ - if (hw->enable_event == enable_event) + if (hw->enable_event[event] == enable_event) return 0; - err = st_lsm6dsx_event_setup(hw, state); + err = st_lsm6dsx_event_setup(hw, event, chan->channel2, state); if (err < 0) return err; mutex_lock(&hw->conf_lock); - if (enable_event || !(hw->fifo_mask & BIT(sensor->id))) - err = __st_lsm6dsx_sensor_set_enable(sensor, state); + if (enable_event) + err = st_lsm6dsx_events_enable(sensor, true); + else if (!st_lsm6dsx_check_other_events(hw, event)) + err = st_lsm6dsx_events_enable(sensor, false); mutex_unlock(&hw->conf_lock); if (err < 0) return err; -out: - hw->enable_event = enable_event; + hw->enable_event[event] = enable_event; return 0; } @@ -2151,11 +2345,11 @@ st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, switch (drdy_pin) { case 1: - hw->irq_routing = &hw->settings->irq_config.irq1_func; + hw->irq_routing = hw->settings->irq_config.irq1_func; *drdy_reg = &hw->settings->irq_config.irq1; break; case 2: - hw->irq_routing = &hw->settings->irq_config.irq2_func; + hw->irq_routing = hw->settings->irq_config.irq2_func; *drdy_reg = &hw->settings->irq_config.irq2; break; default: @@ -2414,53 +2608,70 @@ static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, } static bool -st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) +st_lsm6dsx_report_events(struct st_lsm6dsx_hw *hw, enum st_lsm6dsx_event_id id, + enum iio_event_type type, enum iio_event_direction dir) { const struct st_lsm6dsx_event_settings *event_settings; + const struct st_lsm6dsx_event_src *src; int err, data; s64 timestamp; - if (!hw->enable_event) + if (!hw->enable_event[id]) return false; event_settings = &hw->settings->event_settings; - err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, + src = &event_settings->sources[id]; + err = st_lsm6dsx_read_locked(hw, src->status.addr, &data, sizeof(data)); if (err < 0) return false; timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); - if ((data & hw->settings->event_settings.wakeup_src_z_mask) && - (hw->enable_event & BIT(IIO_MOD_Z))) + if ((data & src->status_z_mask) && + (hw->enable_event[id] & BIT(IIO_MOD_Z))) iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Z, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_EITHER), + type, + dir), timestamp); - if ((data & hw->settings->event_settings.wakeup_src_y_mask) && - (hw->enable_event & BIT(IIO_MOD_Y))) + if ((data & src->status_y_mask) && + (hw->enable_event[id] & BIT(IIO_MOD_Y))) iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_Y, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_EITHER), + type, + dir), timestamp); - if ((data & hw->settings->event_settings.wakeup_src_x_mask) && - (hw->enable_event & BIT(IIO_MOD_X))) + if ((data & src->status_x_mask) && + (hw->enable_event[id] & BIT(IIO_MOD_X))) iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, IIO_MOD_X, - IIO_EV_TYPE_THRESH, - IIO_EV_DIR_EITHER), + type, + dir), timestamp); - return data & event_settings->wakeup_src_status_mask; + return data & src->status.mask; +} + +static bool st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) +{ + bool events_found; + + events_found = st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_WAKEUP, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_EITHER); + events_found |= st_lsm6dsx_report_events(hw, ST_LSM6DSX_EVENT_TAP, + IIO_EV_TYPE_GESTURE, + IIO_EV_DIR_SINGLETAP); + + return events_found; } static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) @@ -2749,7 +2960,7 @@ static int st_lsm6dsx_suspend(struct device *dev) continue; if (device_may_wakeup(dev) && - sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { + st_lsm6dsx_check_events(sensor)) { /* Enable wake from IRQ */ enable_irq_wake(hw->irq); continue; @@ -2780,7 +2991,7 @@ static int st_lsm6dsx_resume(struct device *dev) sensor = iio_priv(hw->iio_devs[i]); if (device_may_wakeup(dev) && - sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) + st_lsm6dsx_check_events(sensor)) disable_irq_wake(hw->irq); if (!(hw->suspend_mask & BIT(sensor->id))) diff --git a/drivers/iio/industrialio-buffer.c b/drivers/iio/industrialio-buffer.c index c6259213e150..46f36a6ed271 100644 --- a/drivers/iio/industrialio-buffer.c +++ b/drivers/iio/industrialio-buffer.c @@ -228,8 +228,10 @@ static ssize_t iio_buffer_write(struct file *filp, const char __user *buf, written = 0; add_wait_queue(&rb->pollq, &wait); do { - if (!indio_dev->info) - return -ENODEV; + if (!indio_dev->info) { + ret = -ENODEV; + break; + } if (!iio_buffer_space_available(rb)) { if (signal_pending(current)) { @@ -1024,7 +1026,7 @@ static int iio_buffer_add_demux(struct iio_buffer *buffer, (*p)->to + (*p)->length == out_loc) { (*p)->length += length; } else { - *p = kmalloc(sizeof(**p), GFP_KERNEL); + *p = kmalloc_obj(**p); if (!(*p)) return -ENOMEM; (*p)->from = in_loc; @@ -1478,7 +1480,7 @@ static struct attribute *iio_buffer_wrap_attr(struct iio_buffer *buffer, struct device_attribute *dattr = to_dev_attr(attr); struct iio_dev_attr *iio_attr; - iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL); + iio_attr = kzalloc_obj(*iio_attr); if (!iio_attr) return NULL; @@ -1507,7 +1509,7 @@ static int iio_buffer_register_legacy_sysfs_groups(struct iio_dev *indio_dev, struct attribute **attrs; int ret; - attrs = kcalloc(buffer_attrcount + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, buffer_attrcount + 1); if (!attrs) return -ENOMEM; @@ -1521,7 +1523,7 @@ static int iio_buffer_register_legacy_sysfs_groups(struct iio_dev *indio_dev, if (ret) goto error_free_buffer_attrs; - attrs = kcalloc(scan_el_attrcount + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, scan_el_attrcount + 1); if (!attrs) { ret = -ENOMEM; goto error_free_buffer_attrs; @@ -1674,7 +1676,7 @@ static int iio_buffer_attach_dmabuf(struct iio_dev_buffer_pair *ib, if (copy_from_user(&fd, user_fd, sizeof(fd))) return -EFAULT; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -1862,7 +1864,7 @@ static int iio_buffer_enqueue_dmabuf(struct iio_dev_buffer_pair *ib, priv = attach->importer_priv; - fence = kmalloc(sizeof(*fence), GFP_KERNEL); + fence = kmalloc_obj(*fence); if (!fence) { ret = -ENOMEM; goto err_attachment_put; @@ -2035,7 +2037,7 @@ static long iio_device_buffer_getfd(struct iio_dev *indio_dev, unsigned long arg goto error_iio_dev_put; } - ib = kzalloc(sizeof(*ib), GFP_KERNEL); + ib = kzalloc_obj(*ib); if (!ib) { ret = -ENOMEM; goto error_clear_busy_bit; @@ -2182,7 +2184,7 @@ static int __iio_buffer_alloc_sysfs_and_mask(struct iio_buffer *buffer, } attrn = buffer_attrcount + scan_el_attrcount; - attr = kcalloc(attrn + 1, sizeof(*attr), GFP_KERNEL); + attr = kzalloc_objs(*attr, attrn + 1); if (!attr) { ret = -ENOMEM; goto error_free_scan_mask; diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c index 117ffad4f376..22eefd048ba9 100644 --- a/drivers/iio/industrialio-core.c +++ b/drivers/iio/industrialio-core.c @@ -1192,7 +1192,7 @@ int __iio_add_chan_devattr(const char *postfix, int ret; struct iio_dev_attr *iio_attr, *t; - iio_attr = kzalloc(sizeof(*iio_attr), GFP_KERNEL); + iio_attr = kzalloc_obj(*iio_attr); if (iio_attr == NULL) return -ENOMEM; ret = __iio_device_attr_init(&iio_attr->dev_attr, @@ -1586,9 +1586,8 @@ static int iio_device_register_sysfs(struct iio_dev *indio_dev) attrcount++; iio_dev_opaque->chan_attr_group.attrs = - kcalloc(attrcount + 1, - sizeof(iio_dev_opaque->chan_attr_group.attrs[0]), - GFP_KERNEL); + kzalloc_objs(iio_dev_opaque->chan_attr_group.attrs[0], + attrcount + 1); if (iio_dev_opaque->chan_attr_group.attrs == NULL) { ret = -ENOMEM; goto error_clear_attrs; @@ -1797,7 +1796,7 @@ static int iio_chrdev_open(struct inode *inode, struct file *filp) iio_device_get(indio_dev); - ib = kmalloc(sizeof(*ib), GFP_KERNEL); + ib = kmalloc_obj(*ib); if (!ib) { iio_device_put(indio_dev); clear_bit(IIO_BUSY_BIT_POS, &iio_dev_opaque->flags); @@ -2174,88 +2173,34 @@ int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, EXPORT_SYMBOL_GPL(__devm_iio_device_register); /** - * __iio_device_claim_direct - Keep device in direct mode - * @indio_dev: the iio_dev associated with the device + * __iio_dev_mode_lock() - Locks the current IIO device mode + * @indio_dev: the iio_dev associated with the device * - * If the device is in direct mode it is guaranteed to stay - * that way until __iio_device_release_direct() is called. + * If the device is either in direct or buffer mode, it's guaranteed to stay + * that way until __iio_dev_mode_unlock() is called. * - * Use with __iio_device_release_direct(). + * This function is not meant to be used directly by drivers to protect internal + * state; a driver should have it's own mechanisms for that matter. * - * Drivers should only call iio_device_claim_direct(). - * - * Returns: true on success, false on failure. + * There are very few cases where a driver actually needs to lock the current + * mode unconditionally. It's recommended to use iio_device_claim_direct() or + * iio_device_try_claim_buffer_mode() pairs or related helpers instead. */ -bool __iio_device_claim_direct(struct iio_dev *indio_dev) +void __iio_dev_mode_lock(struct iio_dev *indio_dev) { - struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); - - mutex_lock(&iio_dev_opaque->mlock); - - if (iio_buffer_enabled(indio_dev)) { - mutex_unlock(&iio_dev_opaque->mlock); - return false; - } - return true; + mutex_lock(&to_iio_dev_opaque(indio_dev)->mlock); } -EXPORT_SYMBOL_GPL(__iio_device_claim_direct); +EXPORT_SYMBOL_GPL(__iio_dev_mode_lock); /** - * __iio_device_release_direct - releases claim on direct mode - * @indio_dev: the iio_dev associated with the device - * - * Release the claim. Device is no longer guaranteed to stay - * in direct mode. - * - * Drivers should only call iio_device_release_direct(). - * - * Use with __iio_device_claim_direct() + * __iio_dev_mode_unlock() - Unlocks the current IIO device mode + * @indio_dev: the iio_dev associated with the device */ -void __iio_device_release_direct(struct iio_dev *indio_dev) +void __iio_dev_mode_unlock(struct iio_dev *indio_dev) { mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); } -EXPORT_SYMBOL_GPL(__iio_device_release_direct); - -/** - * iio_device_claim_buffer_mode - Keep device in buffer mode - * @indio_dev: the iio_dev associated with the device - * - * If the device is in buffer mode it is guaranteed to stay - * that way until iio_device_release_buffer_mode() is called. - * - * Use with iio_device_release_buffer_mode(). - * - * Returns: 0 on success, -EBUSY on failure. - */ -int iio_device_claim_buffer_mode(struct iio_dev *indio_dev) -{ - struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); - - mutex_lock(&iio_dev_opaque->mlock); - - if (iio_buffer_enabled(indio_dev)) - return 0; - - mutex_unlock(&iio_dev_opaque->mlock); - return -EBUSY; -} -EXPORT_SYMBOL_GPL(iio_device_claim_buffer_mode); - -/** - * iio_device_release_buffer_mode - releases claim on buffer mode - * @indio_dev: the iio_dev associated with the device - * - * Release the claim. Device is no longer guaranteed to stay - * in buffer mode. - * - * Use with iio_device_claim_buffer_mode(). - */ -void iio_device_release_buffer_mode(struct iio_dev *indio_dev) -{ - mutex_unlock(&to_iio_dev_opaque(indio_dev)->mlock); -} -EXPORT_SYMBOL_GPL(iio_device_release_buffer_mode); +EXPORT_SYMBOL_GPL(__iio_dev_mode_unlock); /** * iio_device_get_current_mode() - helper function providing read-only access to diff --git a/drivers/iio/industrialio-event.c b/drivers/iio/industrialio-event.c index 06295cfc2da8..4149efcd5539 100644 --- a/drivers/iio/industrialio-event.c +++ b/drivers/iio/industrialio-event.c @@ -583,7 +583,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) iio_check_for_dynamic_events(indio_dev))) return 0; - ev_int = kzalloc(sizeof(*ev_int), GFP_KERNEL); + ev_int = kzalloc_obj(*ev_int); if (!ev_int) return -ENOMEM; @@ -606,9 +606,8 @@ int iio_device_register_eventset(struct iio_dev *indio_dev) } ev_int->group.name = iio_event_group_name; - ev_int->group.attrs = kcalloc(attrcount + 1, - sizeof(ev_int->group.attrs[0]), - GFP_KERNEL); + ev_int->group.attrs = kzalloc_objs(ev_int->group.attrs[0], + attrcount + 1); if (ev_int->group.attrs == NULL) { ret = -ENOMEM; goto error_free_setup_event_lines; diff --git a/drivers/iio/industrialio-gts-helper.c b/drivers/iio/industrialio-gts-helper.c index f35c36fd4a55..4f52dc373abf 100644 --- a/drivers/iio/industrialio-gts-helper.c +++ b/drivers/iio/industrialio-gts-helper.c @@ -250,12 +250,12 @@ static int iio_gts_alloc_int_table_array(int ***arr, int num_tables, int num_tab { int i, **tmp; - tmp = kcalloc(num_tables, sizeof(**arr), GFP_KERNEL); + tmp = kzalloc_objs(**arr, num_tables); if (!tmp) return -ENOMEM; for (i = 0; i < num_tables; i++) { - tmp[i] = kcalloc(num_table_items, sizeof(int), GFP_KERNEL); + tmp[i] = kzalloc_objs(int, num_table_items); if (!tmp[i]) goto err_free; } @@ -432,7 +432,7 @@ static int iio_gts_build_avail_time_table(struct iio_gts *gts) if (!gts->num_itime) return 0; - times = kcalloc(gts->num_itime, sizeof(int), GFP_KERNEL); + times = kzalloc_objs(int, gts->num_itime); if (!times) return -ENOMEM; diff --git a/drivers/iio/industrialio-sw-device.c b/drivers/iio/industrialio-sw-device.c index cdaf30a3f233..3582524de0b8 100644 --- a/drivers/iio/industrialio-sw-device.c +++ b/drivers/iio/industrialio-sw-device.c @@ -148,7 +148,7 @@ static void device_drop_group(struct config_group *group, config_item_put(item); } -static struct configfs_group_operations device_ops = { +static const struct configfs_group_operations device_ops = { .make_group = &device_make_group, .drop_item = &device_drop_group, }; diff --git a/drivers/iio/industrialio-sw-trigger.c b/drivers/iio/industrialio-sw-trigger.c index d86a3305d9e8..334b6b10a784 100644 --- a/drivers/iio/industrialio-sw-trigger.c +++ b/drivers/iio/industrialio-sw-trigger.c @@ -152,7 +152,7 @@ static void trigger_drop_group(struct config_group *group, config_item_put(item); } -static struct configfs_group_operations trigger_ops = { +static const struct configfs_group_operations trigger_ops = { .make_group = &trigger_make_group, .drop_item = &trigger_drop_group, }; diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c index 54416a384232..7f34fe7bad07 100644 --- a/drivers/iio/industrialio-trigger.c +++ b/drivers/iio/industrialio-trigger.c @@ -372,7 +372,7 @@ struct iio_poll_func va_list vargs; struct iio_poll_func *pf; - pf = kmalloc(sizeof(*pf), GFP_KERNEL); + pf = kmalloc_obj(*pf); if (!pf) return NULL; va_start(vargs, fmt); @@ -557,7 +557,7 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent, struct iio_trigger *trig; int i; - trig = kzalloc(sizeof(*trig), GFP_KERNEL); + trig = kzalloc_obj(*trig); if (!trig) return NULL; diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 1e5eb5a41271..0df0ab3de270 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c @@ -55,7 +55,7 @@ int iio_map_array_register(struct iio_dev *indio_dev, const struct iio_map *maps guard(mutex)(&iio_map_list_lock); while (maps[i].consumer_dev_name) { - mapi = kzalloc(sizeof(*mapi), GFP_KERNEL); + mapi = kzalloc_obj(*mapi); if (!mapi) { ret = -ENOMEM; goto error_ret; @@ -188,7 +188,7 @@ static struct iio_channel *fwnode_iio_channel_get(struct fwnode_handle *fwnode, return ERR_PTR(-EINVAL); struct iio_channel *channel __free(kfree) = - kzalloc(sizeof(*channel), GFP_KERNEL); + kzalloc_obj(*channel); if (!channel) return ERR_PTR(-ENOMEM); @@ -302,7 +302,7 @@ static struct iio_channel *fwnode_iio_channel_get_all(struct device *dev) /* NULL terminated array to save passing size */ struct iio_channel *chans __free(kfree) = - kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); + kzalloc_objs(*chans, nummaps + 1); if (!chans) return ERR_PTR(-ENOMEM); @@ -474,7 +474,7 @@ struct iio_channel *iio_channel_get_all(struct device *dev) /* NULL terminated array to save passing size */ struct iio_channel *chans __free(kfree) = - kcalloc(nummaps + 1, sizeof(*chans), GFP_KERNEL); + kzalloc_objs(*chans, nummaps + 1); if (!chans) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/light/bh1780.c b/drivers/iio/light/bh1780.c index 5d3c6d5276ba..a740d1f992a8 100644 --- a/drivers/iio/light/bh1780.c +++ b/drivers/iio/light/bh1780.c @@ -109,9 +109,9 @@ static int bh1780_read_raw(struct iio_dev *indio_dev, case IIO_LIGHT: pm_runtime_get_sync(&bh1780->client->dev); value = bh1780_read_word(bh1780, BH1780_REG_DLOW); + pm_runtime_put_autosuspend(&bh1780->client->dev); if (value < 0) return value; - pm_runtime_put_autosuspend(&bh1780->client->dev); *val = value; return IIO_VAL_INT; diff --git a/drivers/iio/light/isl29018.c b/drivers/iio/light/isl29018.c index 1b4c18423048..b6ab726d1dae 100644 --- a/drivers/iio/light/isl29018.c +++ b/drivers/iio/light/isl29018.c @@ -273,9 +273,9 @@ static ssize_t in_illuminance_scale_available_show mutex_lock(&chip->lock); for (i = 0; i < ARRAY_SIZE(isl29018_scales[chip->int_time]); ++i) - len += sprintf(buf + len, "%d.%06d ", - isl29018_scales[chip->int_time][i].scale, - isl29018_scales[chip->int_time][i].uscale); + len += sysfs_emit_at(buf, len, "%d.%06d ", + isl29018_scales[chip->int_time][i].scale, + isl29018_scales[chip->int_time][i].uscale); mutex_unlock(&chip->lock); buf[len - 1] = '\n'; @@ -293,8 +293,8 @@ static ssize_t in_illuminance_integration_time_available_show int len = 0; for (i = 0; i < ARRAY_SIZE(isl29018_int_utimes[chip->type]); ++i) - len += sprintf(buf + len, "0.%06d ", - isl29018_int_utimes[chip->type][i]); + len += sysfs_emit_at(buf, len, "0.%06d ", + isl29018_int_utimes[chip->type][i]); buf[len - 1] = '\n'; @@ -330,7 +330,7 @@ static ssize_t proximity_on_chip_ambient_infrared_suppression_show * Return the "proximity scheme" i.e. if the chip does on chip * infrared suppression (1 means perform on chip suppression) */ - return sprintf(buf, "%d\n", chip->prox_scheme); + return sysfs_emit(buf, "%d\n", chip->prox_scheme); } static ssize_t proximity_on_chip_ambient_infrared_suppression_store diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c index 981c704e7df5..d6e915ab355d 100644 --- a/drivers/iio/light/opt4060.c +++ b/drivers/iio/light/opt4060.c @@ -302,41 +302,23 @@ static int opt4060_set_driver_state(struct iio_dev *indio_dev, bool continuous_irq) { struct opt4060_chip *chip = iio_priv(indio_dev); - int ret = 0; -any_mode_retry: - if (iio_device_claim_buffer_mode(indio_dev)) { - /* - * This one is a *bit* hacky. If we cannot claim buffer mode, - * then try direct mode so that we make sure things cannot - * concurrently change. And we just keep trying until we get one - * of the modes... - */ - if (!iio_device_claim_direct(indio_dev)) - goto any_mode_retry; - /* - * This path means that we managed to claim direct mode. In - * this case the buffer isn't enabled and it's okay to leave - * continuous mode for sampling and/or irq. - */ - ret = opt4060_set_state_common(chip, continuous_sampling, - continuous_irq); - iio_device_release_direct(indio_dev); - return ret; - } else { - /* - * This path means that we managed to claim buffer mode. In - * this case the buffer is enabled and irq and sampling must go - * to or remain continuous, but only if the trigger is from this - * device. - */ - if (!iio_trigger_validate_own_device(indio_dev->trig, indio_dev)) - ret = opt4060_set_state_common(chip, true, true); - else - ret = opt4060_set_state_common(chip, continuous_sampling, - continuous_irq); - iio_device_release_buffer_mode(indio_dev); - } - return ret; + + IIO_DEV_GUARD_CURRENT_MODE(indio_dev); + + /* + * If we manage to claim buffer mode and we are using our own trigger, + * IRQ and sampling must go to or remain continuous. + */ + if (iio_buffer_enabled(indio_dev) && + iio_trigger_validate_own_device(indio_dev->trig, indio_dev)) + return opt4060_set_state_common(chip, true, true); + + /* + * This path means that we managed to claim direct mode. In this case + * the buffer isn't enabled and it's okay to leave continuous mode for + * sampling and/or irq. + */ + return opt4060_set_state_common(chip, continuous_sampling, continuous_irq); } /* diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c index f8eb251eca8d..ef0abc4499b7 100644 --- a/drivers/iio/light/si1145.c +++ b/drivers/iio/light/si1145.c @@ -1248,7 +1248,7 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev) ret = devm_request_irq(&client->dev, client->irq, iio_trigger_generic_data_rdy_poll, - IRQF_TRIGGER_FALLING, + IRQF_TRIGGER_FALLING | IRQF_NO_THREAD, "si1145_irq", trig); if (ret < 0) { diff --git a/drivers/iio/light/vcnl4000.c b/drivers/iio/light/vcnl4000.c index 4dbb2294a843..a36c23813679 100644 --- a/drivers/iio/light/vcnl4000.c +++ b/drivers/iio/light/vcnl4000.c @@ -1078,20 +1078,17 @@ static int vcnl4010_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - case IIO_CHAN_INFO_SCALE: - if (!iio_device_claim_direct(indio_dev)) + case IIO_CHAN_INFO_SCALE: { + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + if (IIO_DEV_ACQUIRE_FAILED(claim)) return -EBUSY; /* Protect against event capture. */ - if (vcnl4010_is_in_periodic_mode(data)) { - ret = -EBUSY; - } else { - ret = vcnl4000_read_raw(indio_dev, chan, val, val2, - mask); - } + if (vcnl4010_is_in_periodic_mode(data)) + return -EBUSY; - iio_device_release_direct(indio_dev); - return ret; + return vcnl4000_read_raw(indio_dev, chan, val, val2, mask); + } case IIO_CHAN_INFO_SAMP_FREQ: switch (chan->type) { case IIO_PROXIMITY: @@ -1148,36 +1145,27 @@ static int vcnl4010_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) { - int ret; struct vcnl4000_data *data = iio_priv(indio_dev); - if (!iio_device_claim_direct(indio_dev)) + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + if (IIO_DEV_ACQUIRE_FAILED(claim)) return -EBUSY; /* Protect against event capture. */ - if (vcnl4010_is_in_periodic_mode(data)) { - ret = -EBUSY; - goto end; - } + if (vcnl4010_is_in_periodic_mode(data)) + return -EBUSY; switch (mask) { case IIO_CHAN_INFO_SAMP_FREQ: switch (chan->type) { case IIO_PROXIMITY: - ret = vcnl4010_write_proxy_samp_freq(data, val, val2); - goto end; + return vcnl4010_write_proxy_samp_freq(data, val, val2); default: - ret = -EINVAL; - goto end; + return -EINVAL; } default: - ret = -EINVAL; - goto end; + return -EINVAL; } - -end: - iio_device_release_direct(indio_dev); - return ret; } static int vcnl4010_read_event(struct iio_dev *indio_dev, @@ -1438,14 +1426,13 @@ static int vcnl4010_config_threshold_disable(struct vcnl4000_data *data) static int vcnl4010_config_threshold(struct iio_dev *indio_dev, bool state) { struct vcnl4000_data *data = iio_priv(indio_dev); - int ret; if (state) { - if (!iio_device_claim_direct(indio_dev)) + IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + if (IIO_DEV_ACQUIRE_FAILED(claim)) return -EBUSY; - ret = vcnl4010_config_threshold_enable(data); - iio_device_release_direct(indio_dev); - return ret; + + return vcnl4010_config_threshold_enable(data); } else { return vcnl4010_config_threshold_disable(data); } diff --git a/drivers/iio/magnetometer/Kconfig b/drivers/iio/magnetometer/Kconfig index 81b812a29044..fb313e591e85 100644 --- a/drivers/iio/magnetometer/Kconfig +++ b/drivers/iio/magnetometer/Kconfig @@ -139,6 +139,18 @@ config MMC35240 To compile this driver as a module, choose M here: the module will be called mmc35240. +config MMC5633 + tristate "MEMSIC MMC5633 3-axis magnetic sensor" + select REGMAP_I2C + select REGMAP_I3C if I3C + depends on I3C_OR_I2C + help + Say yes here to build support for the MEMSIC MMC5633 3-axis + magnetic sensor. + + To compile this driver as a module, choose M here: the module + will be called mmc5633 + config IIO_ST_MAGN_3AXIS tristate "STMicroelectronics magnetometers 3-Axis Driver" depends on (I2C || SPI_MASTER) && SYSFS diff --git a/drivers/iio/magnetometer/Makefile b/drivers/iio/magnetometer/Makefile index dfe970fcacb8..5bd227f8c120 100644 --- a/drivers/iio/magnetometer/Makefile +++ b/drivers/iio/magnetometer/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_BMC150_MAGN_SPI) += bmc150_magn_spi.o obj-$(CONFIG_MAG3110) += mag3110.o obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o obj-$(CONFIG_MMC35240) += mmc35240.o +obj-$(CONFIG_MMC5633) += mmc5633.o obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o st_magn-y := st_magn_core.o diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index 3fd0171e5d69..d30315ad85de 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c @@ -581,7 +581,7 @@ static int ak8975_setup_irq(struct ak8975_data *data) irq = gpiod_to_irq(data->eoc_gpiod); rc = devm_request_irq(&client->dev, irq, ak8975_irq_handler, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, + IRQF_TRIGGER_RISING, dev_name(&client->dev), data); if (rc < 0) { dev_err(&client->dev, "irq %d request failed: %d\n", irq, rc); diff --git a/drivers/iio/magnetometer/bmc150_magn.c b/drivers/iio/magnetometer/bmc150_magn.c index 6a73f6e2f1f0..a022e1805dff 100644 --- a/drivers/iio/magnetometer/bmc150_magn.c +++ b/drivers/iio/magnetometer/bmc150_magn.c @@ -906,12 +906,9 @@ int bmc150_magn_probe(struct device *dev, struct regmap *regmap, goto err_poweroff; } - ret = request_threaded_irq(irq, - iio_trigger_generic_data_rdy_poll, - NULL, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - "bmc150_magn_event", - data->dready_trig); + ret = request_irq(irq, iio_trigger_generic_data_rdy_poll, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + "bmc150_magn_event", data->dready_trig); if (ret < 0) { dev_err(dev, "request irq %d failed\n", irq); goto err_trigger_unregister; diff --git a/drivers/iio/magnetometer/mmc5633.c b/drivers/iio/magnetometer/mmc5633.c new file mode 100644 index 000000000000..9d8e27486963 --- /dev/null +++ b/drivers/iio/magnetometer/mmc5633.c @@ -0,0 +1,586 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * MMC5633 - MEMSIC 3-axis Magnetic Sensor + * + * Copyright (c) 2015, Intel Corporation. + * Copyright (c) 2025, NXP + * + * IIO driver for MMC5633, base on mmc35240.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MMC5633_REG_XOUT0 0x00 +#define MMC5633_REG_XOUT1 0x01 +#define MMC5633_REG_YOUT0 0x02 +#define MMC5633_REG_YOUT1 0x03 +#define MMC5633_REG_ZOUT0 0x04 +#define MMC5633_REG_ZOUT1 0x05 +#define MMC5633_REG_XOUT2 0x06 +#define MMC5633_REG_YOUT2 0x07 +#define MMC5633_REG_ZOUT2 0x08 +#define MMC5633_REG_TOUT 0x09 + +#define MMC5633_REG_STATUS1 0x18 +#define MMC5633_REG_STATUS0 0x19 +#define MMC5633_REG_CTRL0 0x1b +#define MMC5633_REG_CTRL1 0x1c +#define MMC5633_REG_CTRL2 0x1d + +#define MMC5633_REG_ID 0x39 + +#define MMC5633_STATUS1_MEAS_T_DONE_BIT BIT(7) +#define MMC5633_STATUS1_MEAS_M_DONE_BIT BIT(6) + +#define MMC5633_CTRL0_CMM_FREQ_EN BIT(7) +#define MMC5633_CTRL0_AUTO_ST_EN BIT(6) +#define MMC5633_CTRL0_AUTO_SR_EN BIT(5) +#define MMC5633_CTRL0_RESET BIT(4) +#define MMC5633_CTRL0_SET BIT(3) +#define MMC5633_CTRL0_MEAS_T BIT(1) +#define MMC5633_CTRL0_MEAS_M BIT(0) + +#define MMC5633_CTRL1_BW_MASK GENMASK(1, 0) + +#define MMC5633_WAIT_SET_RESET_US (1 * USEC_PER_MSEC) + +#define MMC5633_HDR_CTRL0_MEAS_M 0x01 +#define MMC5633_HDR_CTRL0_MEAS_T 0x03 +#define MMC5633_HDR_CTRL0_SET 0x05 +#define MMC5633_HDR_CTRL0_RESET 0x07 + +enum mmc5633_axis { + MMC5633_AXIS_X, + MMC5633_AXIS_Y, + MMC5633_AXIS_Z, + MMC5633_TEMPERATURE, +}; + +struct mmc5633_data { + struct regmap *regmap; + struct i3c_device *i3cdev; + struct mutex mutex; /* protect to finish one whole measurement */ +}; + +static int mmc5633_samp_freq[][2] = { + { 1, 200000 }, + { 2, 0 }, + { 3, 500000 }, + { 6, 600000 }, +}; + +#define MMC5633_CHANNEL(_axis) { \ + .type = IIO_MAGN, \ + .modified = 1, \ + .channel2 = IIO_MOD_ ## _axis, \ + .address = MMC5633_AXIS_ ## _axis, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ + BIT(IIO_CHAN_INFO_SCALE), \ +} + +static const struct iio_chan_spec mmc5633_channels[] = { + MMC5633_CHANNEL(X), + MMC5633_CHANNEL(Y), + MMC5633_CHANNEL(Z), + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .address = MMC5633_TEMPERATURE, + }, +}; + +static int mmc5633_get_samp_freq_index(struct mmc5633_data *data, + int val, int val2) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(mmc5633_samp_freq); i++) + if (mmc5633_samp_freq[i][0] == val && + mmc5633_samp_freq[i][1] == val2) + return i; + return -EINVAL; +} + +static int mmc5633_init(struct mmc5633_data *data) +{ + unsigned int reg_id; + int ret; + + ret = regmap_read(data->regmap, MMC5633_REG_ID, ®_id); + if (ret) + return dev_err_probe(regmap_get_device(data->regmap), ret, + "Error reading product id\n"); + + /* + * Make sure we restore sensor characteristics, by doing + * a SET/RESET sequence, the axis polarity being naturally + * aligned after RESET. + */ + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_SET); + if (ret) + return ret; + + /* + * Minimum time interval between SET or RESET to other operations is + * 1ms according to Operating Timing Diagram in datasheet. + */ + fsleep(MMC5633_WAIT_SET_RESET_US); + + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_RESET); + if (ret) + return ret; + + /* set default sampling frequency */ + return regmap_update_bits(data->regmap, MMC5633_REG_CTRL1, + MMC5633_CTRL1_BW_MASK, + FIELD_PREP(MMC5633_CTRL1_BW_MASK, 0)); +} + +static int mmc5633_take_measurement(struct mmc5633_data *data, int address) +{ + unsigned int reg_status, val; + int ret; + + val = (address == MMC5633_TEMPERATURE) ? MMC5633_CTRL0_MEAS_T : MMC5633_CTRL0_MEAS_M; + ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, val); + if (ret < 0) + return ret; + + val = (address == MMC5633_TEMPERATURE) ? + MMC5633_STATUS1_MEAS_T_DONE_BIT : MMC5633_STATUS1_MEAS_M_DONE_BIT; + ret = regmap_read_poll_timeout(data->regmap, MMC5633_REG_STATUS1, reg_status, + reg_status & val, + 10 * USEC_PER_MSEC, + 100 * 10 * USEC_PER_MSEC); + if (ret) { + dev_err(regmap_get_device(data->regmap), "data not ready\n"); + return ret; + } + + return 0; +} + +static bool mmc5633_is_support_hdr(struct mmc5633_data *data) +{ + if (!data->i3cdev) + return false; + + return i3c_device_get_supported_xfer_mode(data->i3cdev) & BIT(I3C_HDR_DDR); +} + +static int mmc5633_read_measurement(struct mmc5633_data *data, int address, void *buf, size_t sz) +{ + struct device *dev = regmap_get_device(data->regmap); + u8 data_cmd[2], status[2]; + unsigned int val, ready; + int ret; + + if (mmc5633_is_support_hdr(data)) { + struct i3c_xfer xfers_wr_cmd[] = { + { + .cmd = 0x3b, + .len = 2, + .data.out = data_cmd, + } + }; + struct i3c_xfer xfers_rd_sta_cmd[] = { + { + .cmd = 0x23 | BIT(7), /* RDSTA CMD */ + .len = 2, + .data.in = status, + }, + }; + struct i3c_xfer xfers_rd_data_cmd[] = { + { + .cmd = 0x22 | BIT(7), /* RDLONG CMD */ + .len = sz, + .data.in = buf, + }, + }; + + data_cmd[0] = 0; + data_cmd[1] = (address == MMC5633_TEMPERATURE) ? + MMC5633_HDR_CTRL0_MEAS_T : MMC5633_HDR_CTRL0_MEAS_M; + + ret = i3c_device_do_xfers(data->i3cdev, xfers_wr_cmd, + ARRAY_SIZE(xfers_wr_cmd), I3C_HDR_DDR); + if (ret < 0) + return ret; + + ready = (address == MMC5633_TEMPERATURE) ? + MMC5633_STATUS1_MEAS_T_DONE_BIT : MMC5633_STATUS1_MEAS_M_DONE_BIT; + ret = read_poll_timeout(i3c_device_do_xfers, val, + val || (status[0] & ready), + 10 * USEC_PER_MSEC, + 100 * 10 * USEC_PER_MSEC, 0, + data->i3cdev, xfers_rd_sta_cmd, + ARRAY_SIZE(xfers_rd_sta_cmd), I3C_HDR_DDR); + if (ret) { + dev_err(dev, "data not ready\n"); + return ret; + } + if (val) { + dev_err(dev, "i3c transfer error\n"); + return val; + } + return i3c_device_do_xfers(data->i3cdev, xfers_rd_data_cmd, + ARRAY_SIZE(xfers_rd_data_cmd), I3C_HDR_DDR); + } + + /* Fallback to use SDR/I2C mode */ + ret = mmc5633_take_measurement(data, address); + if (ret < 0) + return ret; + + if (address == MMC5633_TEMPERATURE) + /* + * Put tempeature to last byte of buff to align HDR case. + * I3C will early terminate data read if previous data is not + * available. + */ + return regmap_bulk_read(data->regmap, MMC5633_REG_TOUT, buf + sz - 1, 1); + + return regmap_bulk_read(data->regmap, MMC5633_REG_XOUT0, buf, sz); +} + +/* X,Y,Z 3 channels, each channel has 3 byte and TEMP */ +#define MMC5633_ALL_SIZE (3 * 3 + 1) + +static int mmc5633_get_raw(struct mmc5633_data *data, int index, unsigned char *buf, int *val) +{ + if (index == MMC5633_TEMPERATURE) { + *val = buf[MMC5633_ALL_SIZE - 1]; + return 0; + } + /* + * X[19..12] X[11..4] Y[19..12] Y[11..4] Z[19..12] Z[11..4] X[3..0] Y[3..0] Z[3..0] + */ + *val = get_unaligned_be16(buf + 2 * index) << 4; + *val |= buf[index + 6] >> 4; + + return 0; +} + +static int mmc5633_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int *val, + int *val2, long mask) +{ + struct mmc5633_data *data = iio_priv(indio_dev); + char buf[MMC5633_ALL_SIZE]; + unsigned int reg, i; + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + scoped_guard(mutex, &data->mutex) { + ret = mmc5633_read_measurement(data, chan->address, buf, MMC5633_ALL_SIZE); + if (ret < 0) + return ret; + } + + ret = mmc5633_get_raw(data, chan->address, buf, val); + if (ret < 0) + return ret; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + if (chan->type == IIO_MAGN) { + *val = 0; + *val2 = 62500; + } else { + *val = 0; + *val2 = 800000000; /* 0.8C */ + } + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_OFFSET: + if (chan->type == IIO_TEMP) { + *val = -75; + return IIO_VAL_INT; + } + return -EINVAL; + case IIO_CHAN_INFO_SAMP_FREQ: + scoped_guard(mutex, &data->mutex) { + ret = regmap_read(data->regmap, MMC5633_REG_CTRL1, ®); + if (ret < 0) + return ret; + } + + i = FIELD_GET(MMC5633_CTRL1_BW_MASK, reg); + if (i >= ARRAY_SIZE(mmc5633_samp_freq)) + return -EINVAL; + + *val = mmc5633_samp_freq[i][0]; + *val2 = mmc5633_samp_freq[i][1]; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} + +static int mmc5633_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, int val, + int val2, long mask) +{ + struct mmc5633_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: { + ret = mmc5633_get_samp_freq_index(data, val, val2); + if (ret < 0) + return ret; + + guard(mutex)(&data->mutex); + + return regmap_update_bits(data->regmap, MMC5633_REG_CTRL1, + MMC5633_CTRL1_BW_MASK, + FIELD_PREP(MMC5633_CTRL1_BW_MASK, ret)); + } + default: + return -EINVAL; + } +} + +static int mmc5633_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = (const int *)mmc5633_samp_freq; + *length = ARRAY_SIZE(mmc5633_samp_freq) * 2; + *type = IIO_VAL_INT_PLUS_MICRO; + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static const struct iio_info mmc5633_info = { + .read_raw = mmc5633_read_raw, + .write_raw = mmc5633_write_raw, + .read_avail = mmc5633_read_avail, +}; + +static bool mmc5633_is_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MMC5633_REG_CTRL0: + case MMC5633_REG_CTRL1: + return true; + default: + return false; + } +} + +static bool mmc5633_is_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MMC5633_REG_XOUT0: + case MMC5633_REG_XOUT1: + case MMC5633_REG_YOUT0: + case MMC5633_REG_YOUT1: + case MMC5633_REG_ZOUT0: + case MMC5633_REG_ZOUT1: + case MMC5633_REG_XOUT2: + case MMC5633_REG_YOUT2: + case MMC5633_REG_ZOUT2: + case MMC5633_REG_TOUT: + case MMC5633_REG_STATUS1: + case MMC5633_REG_ID: + return true; + default: + return false; + } +} + +static bool mmc5633_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case MMC5633_REG_CTRL0: + case MMC5633_REG_CTRL1: + return false; + default: + return true; + } +} + +static const struct reg_default mmc5633_reg_defaults[] = { + { MMC5633_REG_CTRL0, 0x00 }, + { MMC5633_REG_CTRL1, 0x00 }, +}; + +static const struct regmap_config mmc5633_regmap_config = { + .name = "mmc5633_regmap", + + .reg_bits = 8, + .val_bits = 8, + + .max_register = MMC5633_REG_ID, + .cache_type = REGCACHE_MAPLE, + + .writeable_reg = mmc5633_is_writeable_reg, + .readable_reg = mmc5633_is_readable_reg, + .volatile_reg = mmc5633_is_volatile_reg, + + .reg_defaults = mmc5633_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(mmc5633_reg_defaults), +}; + +static int mmc5633_common_probe(struct regmap *regmap, char *name, + struct i3c_device *i3cdev) +{ + struct device *dev = regmap_get_device(regmap); + struct mmc5633_data *data; + struct iio_dev *indio_dev; + int ret; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + + data->regmap = regmap; + data->i3cdev = i3cdev; + + ret = devm_mutex_init(dev, &data->mutex); + if (ret) + return ret; + + indio_dev->info = &mmc5633_info; + indio_dev->name = name; + indio_dev->channels = mmc5633_channels; + indio_dev->num_channels = ARRAY_SIZE(mmc5633_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = mmc5633_init(data); + if (ret < 0) + return dev_err_probe(dev, ret, "mmc5633 chip init failed\n"); + + return devm_iio_device_register(dev, indio_dev); +} + +static int mmc5633_suspend(struct device *dev) +{ + struct regmap *regmap = dev_get_regmap(dev, NULL); + + regcache_cache_only(regmap, true); + + return 0; +} + +static int mmc5633_resume(struct device *dev) +{ + struct regmap *regmap = dev_get_regmap(dev, NULL); + int ret; + + regcache_mark_dirty(regmap); + ret = regcache_sync_region(regmap, MMC5633_REG_CTRL0, MMC5633_REG_CTRL1); + if (ret) + dev_err(dev, "Failed to restore control registers\n"); + + regcache_cache_only(regmap, false); + + return 0; +} + +static int mmc5633_i2c_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct regmap *regmap; + + regmap = devm_regmap_init_i2c(client, &mmc5633_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "regmap init failed\n"); + + return mmc5633_common_probe(regmap, client->name, NULL); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(mmc5633_pm_ops, mmc5633_suspend, mmc5633_resume); + +static const struct of_device_id mmc5633_of_match[] = { + { .compatible = "memsic,mmc5603" }, + { .compatible = "memsic,mmc5633" }, + { } +}; +MODULE_DEVICE_TABLE(of, mmc5633_of_match); + +static const struct i2c_device_id mmc5633_i2c_id[] = { + { "mmc5603" }, + { "mmc5633" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mmc5633_i2c_id); + +static struct i2c_driver mmc5633_i2c_driver = { + .driver = { + .name = "mmc5633_i2c", + .of_match_table = mmc5633_of_match, + .pm = pm_sleep_ptr(&mmc5633_pm_ops), + }, + .probe = mmc5633_i2c_probe, + .id_table = mmc5633_i2c_id, +}; + +static const struct i3c_device_id mmc5633_i3c_ids[] = { + I3C_DEVICE(0x0251, 0x0000, NULL), + { } +}; +MODULE_DEVICE_TABLE(i3c, mmc5633_i3c_ids); + +static int mmc5633_i3c_probe(struct i3c_device *i3cdev) +{ + struct device *dev = i3cdev_to_dev(i3cdev); + struct regmap *regmap; + char *name; + + name = devm_kasprintf(dev, GFP_KERNEL, "mmc5633_%s", dev_name(dev)); + if (!name) + return -ENOMEM; + + regmap = devm_regmap_init_i3c(i3cdev, &mmc5633_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "Failed to register i3c regmap\n"); + + return mmc5633_common_probe(regmap, name, i3cdev); +} + +static struct i3c_driver mmc5633_i3c_driver = { + .driver = { + .name = "mmc5633_i3c", + }, + .probe = mmc5633_i3c_probe, + .id_table = mmc5633_i3c_ids, +}; +module_i3c_i2c_driver(mmc5633_i3c_driver, &mmc5633_i2c_driver) + +MODULE_AUTHOR("Frank Li "); +MODULE_DESCRIPTION("MEMSIC MMC5633 magnetic sensor driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/magnetometer/tlv493d.c b/drivers/iio/magnetometer/tlv493d.c index ec53fd40277b..e5e050af2b74 100644 --- a/drivers/iio/magnetometer/tlv493d.c +++ b/drivers/iio/magnetometer/tlv493d.c @@ -171,7 +171,7 @@ static s16 tlv493d_get_channel_data(u8 *b, enum tlv493d_channels ch) switch (ch) { case TLV493D_AXIS_X: val = FIELD_GET(TLV493D_BX_MAG_X_AXIS_MSB, b[TLV493D_RD_REG_BX]) << 4 | - FIELD_GET(TLV493D_BX2_MAG_X_AXIS_LSB, b[TLV493D_RD_REG_BX2]) >> 4; + FIELD_GET(TLV493D_BX2_MAG_X_AXIS_LSB, b[TLV493D_RD_REG_BX2]); break; case TLV493D_AXIS_Y: val = FIELD_GET(TLV493D_BY_MAG_Y_AXIS_MSB, b[TLV493D_RD_REG_BY]) << 4 | diff --git a/drivers/iio/potentiometer/mcp4131.c b/drivers/iio/potentiometer/mcp4131.c index ad082827aad5..56c9111ef5e8 100644 --- a/drivers/iio/potentiometer/mcp4131.c +++ b/drivers/iio/potentiometer/mcp4131.c @@ -221,7 +221,7 @@ static int mcp4131_write_raw(struct iio_dev *indio_dev, mutex_lock(&data->lock); - data->buf[0] = address << MCP4131_WIPER_SHIFT; + data->buf[0] = address; data->buf[0] |= MCP4131_WRITE | (val >> 8); data->buf[1] = val & 0xFF; /* 8 bits here */ diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig index 2fe9dc90cceb..838a8340c4c0 100644 --- a/drivers/iio/pressure/Kconfig +++ b/drivers/iio/pressure/Kconfig @@ -16,6 +16,35 @@ config ABP060MG To compile this driver as a module, choose M here: the module will be called abp060mg. +config ABP2030PA + tristate + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER + +config ABP2030PA_I2C + tristate "Honeywell ABP2 pressure sensor series I2C driver" + depends on I2C + select ABP2030PA + help + Say Y here to build I2C bus support for the Honeywell ABP2 + series pressure and temperature digital sensor. + + To compile this driver as a module, choose M here: the module + will be called abp2030pa_i2c and you will also get abp2030pa + for the core module. + +config ABP2030PA_SPI + tristate "Honeywell ABP2 pressure sensor series SPI driver" + depends on SPI_MASTER + select ABP2030PA + help + Say Y here to build SPI bus support for the Honeywell ABP2 + series pressure and temperature digital sensor. + + To compile this driver as a module, choose M here: the module + will be called abp2030pa_spi and you will also get abp2030pa + for the core module. + config ROHM_BM1390 tristate "ROHM BM1390GLV-Z pressure sensor driver" depends on I2C @@ -187,29 +216,33 @@ config MPL3115 will be called mpl3115. config MPRLS0025PA - tristate "Honeywell MPRLS0025PA (MicroPressure sensors series)" - depends on (I2C || SPI_MASTER) - select MPRLS0025PA_I2C if I2C - select MPRLS0025PA_SPI if SPI_MASTER + tristate select IIO_BUFFER select IIO_TRIGGERED_BUFFER - help - Say Y here to build support for the Honeywell MicroPressure pressure - sensor series. There are many different types with different pressure - range. These ranges can be set up in the device tree. - - To compile this driver as a module, choose M here: the module will be - called mprls0025pa. config MPRLS0025PA_I2C - tristate - depends on MPRLS0025PA + tristate "Honeywell MPR pressure sensor series I2C driver" depends on I2C + select MPRLS0025PA + help + Say Y here to build I2C bus support for the Honeywell MicroPressure + series sensor. + + To compile this driver as a module, choose M here: the module + will be called mprls0025pa_i2c and you will also get mprls0025pa + for the core module. config MPRLS0025PA_SPI - tristate - depends on MPRLS0025PA + tristate "Honeywell MPR pressure sensor series SPI driver" depends on SPI_MASTER + select MPRLS0025PA + help + Say Y here to build SPI bus support for the Honeywell MicroPressure + series sensor. + + To compile this driver as a module, choose M here: the module + will be called mprls0025pa_spi and you will also get mprls0025pa + for the core module. config MS5611 tristate "Measurement Specialties MS5611 pressure sensor driver" diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile index a21443e992b9..bc0d11a20acc 100644 --- a/drivers/iio/pressure/Makefile +++ b/drivers/iio/pressure/Makefile @@ -5,6 +5,9 @@ # When adding new entries keep the list in alphabetical order obj-$(CONFIG_ABP060MG) += abp060mg.o +obj-$(CONFIG_ABP2030PA) += abp2030pa.o +obj-$(CONFIG_ABP2030PA_I2C) += abp2030pa_i2c.o +obj-$(CONFIG_ABP2030PA_SPI) += abp2030pa_spi.o obj-$(CONFIG_ADP810) += adp810.o obj-$(CONFIG_ROHM_BM1390) += rohm-bm1390.o obj-$(CONFIG_BMP280) += bmp280.o diff --git a/drivers/iio/pressure/abp2030pa.c b/drivers/iio/pressure/abp2030pa.c new file mode 100644 index 000000000000..4ca056a73cef --- /dev/null +++ b/drivers/iio/pressure/abp2030pa.c @@ -0,0 +1,544 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + * + * Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/basic-abp2-series/documents/sps-siot-abp2-series-datasheet-32350268-en.pdf + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "abp2030pa.h" + +/* Status byte flags */ +#define ABP2_ST_POWER BIT(6) /* 1 if device is powered */ +#define ABP2_ST_BUSY BIT(5) /* 1 if device is busy */ + +#define ABP2_CMD_NOP 0xf0 +#define ABP2_CMD_SYNC 0xaa +#define ABP2_PKT_SYNC_LEN 3 +#define ABP2_PKT_NOP_LEN ABP2_MEASUREMENT_RD_SIZE + +struct abp2_func_spec { + u32 output_min; + u32 output_max; +}; + +/* transfer function A: 10% to 90% of 2^24 */ +static const struct abp2_func_spec abp2_func_spec[] = { + [ABP2_FUNCTION_A] = { .output_min = 1677722, .output_max = 15099494 }, +}; + +enum abp2_variants { + ABP2001BA, ABP21_6BA, ABP22_5BA, ABP2004BA, ABP2006BA, ABP2008BA, + ABP2010BA, ABP2012BA, ABP2001BD, ABP21_6BD, ABP22_5BD, ABP2004BD, + ABP2001BG, ABP21_6BG, ABP22_5BG, ABP2004BG, ABP2006BG, ABP2008BG, + ABP2010BG, ABP2012BG, ABP2001GG, ABP21_2GG, ABP2100KA, ABP2160KA, + ABP2250KA, ABP2001KD, ABP21_6KD, ABP22_5KD, ABP2004KD, ABP2006KD, + ABP2010KD, ABP2016KD, ABP2025KD, ABP2040KD, ABP2060KD, ABP2100KD, + ABP2160KD, ABP2250KD, ABP2400KD, ABP2001KG, ABP21_6KG, ABP22_5KG, + ABP2004KG, ABP2006KG, ABP2010KG, ABP2016KG, ABP2025KG, ABP2040KG, + ABP2060KG, ABP2100KG, ABP2160KG, ABP2250KG, ABP2400KG, ABP2600KG, + ABP2800KG, ABP2250LD, ABP2600LD, ABP2600LG, ABP22_5MD, ABP2006MD, + ABP2010MD, ABP2016MD, ABP2025MD, ABP2040MD, ABP2060MD, ABP2100MD, + ABP2160MD, ABP2250MD, ABP2400MD, ABP2600MD, ABP2006MG, ABP2010MG, + ABP2016MG, ABP2025MG, ABP2040MG, ABP2060MG, ABP2100MG, ABP2160MG, + ABP2250MG, ABP2400MG, ABP2600MG, ABP2001ND, ABP2002ND, ABP2004ND, + ABP2005ND, ABP2010ND, ABP2020ND, ABP2030ND, ABP2002NG, ABP2004NG, + ABP2005NG, ABP2010NG, ABP2020NG, ABP2030NG, ABP2015PA, ABP2030PA, + ABP2060PA, ABP2100PA, ABP2150PA, ABP2175PA, ABP2001PD, ABP2005PD, + ABP2015PD, ABP2030PD, ABP2060PD, ABP2001PG, ABP2005PG, ABP2015PG, + ABP2030PG, ABP2060PG, ABP2100PG, ABP2150PG, ABP2175PG, +}; + +static const char * const abp2_triplet_variants[] = { + [ABP2001BA] = "001BA", [ABP21_6BA] = "1.6BA", [ABP22_5BA] = "2.5BA", + [ABP2004BA] = "004BA", [ABP2006BA] = "006BA", [ABP2008BA] = "008BA", + [ABP2010BA] = "010BA", [ABP2012BA] = "012BA", [ABP2001BD] = "001BD", + [ABP21_6BD] = "1.6BD", [ABP22_5BD] = "2.5BD", [ABP2004BD] = "004BD", + [ABP2001BG] = "001BG", [ABP21_6BG] = "1.6BG", [ABP22_5BG] = "2.5BG", + [ABP2004BG] = "004BG", [ABP2006BG] = "006BG", [ABP2008BG] = "008BG", + [ABP2010BG] = "010BG", [ABP2012BG] = "012BG", [ABP2001GG] = "001GG", + [ABP21_2GG] = "1.2GG", [ABP2100KA] = "100KA", [ABP2160KA] = "160KA", + [ABP2250KA] = "250KA", [ABP2001KD] = "001KD", [ABP21_6KD] = "1.6KD", + [ABP22_5KD] = "2.5KD", [ABP2004KD] = "004KD", [ABP2006KD] = "006KD", + [ABP2010KD] = "010KD", [ABP2016KD] = "016KD", [ABP2025KD] = "025KD", + [ABP2040KD] = "040KD", [ABP2060KD] = "060KD", [ABP2100KD] = "100KD", + [ABP2160KD] = "160KD", [ABP2250KD] = "250KD", [ABP2400KD] = "400KD", + [ABP2001KG] = "001KG", [ABP21_6KG] = "1.6KG", [ABP22_5KG] = "2.5KG", + [ABP2004KG] = "004KG", [ABP2006KG] = "006KG", [ABP2010KG] = "010KG", + [ABP2016KG] = "016KG", [ABP2025KG] = "025KG", [ABP2040KG] = "040KG", + [ABP2060KG] = "060KG", [ABP2100KG] = "100KG", [ABP2160KG] = "160KG", + [ABP2250KG] = "250KG", [ABP2400KG] = "400KG", [ABP2600KG] = "600KG", + [ABP2800KG] = "800KG", [ABP2250LD] = "250LD", [ABP2600LD] = "600LD", + [ABP2600LG] = "600LG", [ABP22_5MD] = "2.5MD", [ABP2006MD] = "006MD", + [ABP2010MD] = "010MD", [ABP2016MD] = "016MD", [ABP2025MD] = "025MD", + [ABP2040MD] = "040MD", [ABP2060MD] = "060MD", [ABP2100MD] = "100MD", + [ABP2160MD] = "160MD", [ABP2250MD] = "250MD", [ABP2400MD] = "400MD", + [ABP2600MD] = "600MD", [ABP2006MG] = "006MG", [ABP2010MG] = "010MG", + [ABP2016MG] = "016MG", [ABP2025MG] = "025MG", [ABP2040MG] = "040MG", + [ABP2060MG] = "060MG", [ABP2100MG] = "100MG", [ABP2160MG] = "160MG", + [ABP2250MG] = "250MG", [ABP2400MG] = "400MG", [ABP2600MG] = "600MG", + [ABP2001ND] = "001ND", [ABP2002ND] = "002ND", [ABP2004ND] = "004ND", + [ABP2005ND] = "005ND", [ABP2010ND] = "010ND", [ABP2020ND] = "020ND", + [ABP2030ND] = "030ND", [ABP2002NG] = "002NG", [ABP2004NG] = "004NG", + [ABP2005NG] = "005NG", [ABP2010NG] = "010NG", [ABP2020NG] = "020NG", + [ABP2030NG] = "030NG", [ABP2015PA] = "015PA", [ABP2030PA] = "030PA", + [ABP2060PA] = "060PA", [ABP2100PA] = "100PA", [ABP2150PA] = "150PA", + [ABP2175PA] = "175PA", [ABP2001PD] = "001PD", [ABP2005PD] = "005PD", + [ABP2015PD] = "015PD", [ABP2030PD] = "030PD", [ABP2060PD] = "060PD", + [ABP2001PG] = "001PG", [ABP2005PG] = "005PG", [ABP2015PG] = "015PG", + [ABP2030PG] = "030PG", [ABP2060PG] = "060PG", [ABP2100PG] = "100PG", + [ABP2150PG] = "150PG", [ABP2175PG] = "175PG", +}; + +/** + * struct abp2_range_config - list of pressure ranges based on nomenclature + * @pmin: lowest pressure that can be measured + * @pmax: highest pressure that can be measured + */ +struct abp2_range_config { + s32 pmin; + s32 pmax; +}; + +/* All min max limits have been converted to pascals */ +static const struct abp2_range_config abp2_range_config[] = { + [ABP2001BA] = { .pmin = 0, .pmax = 100000 }, + [ABP21_6BA] = { .pmin = 0, .pmax = 160000 }, + [ABP22_5BA] = { .pmin = 0, .pmax = 250000 }, + [ABP2004BA] = { .pmin = 0, .pmax = 400000 }, + [ABP2006BA] = { .pmin = 0, .pmax = 600000 }, + [ABP2008BA] = { .pmin = 0, .pmax = 800000 }, + [ABP2010BA] = { .pmin = 0, .pmax = 1000000 }, + [ABP2012BA] = { .pmin = 0, .pmax = 1200000 }, + [ABP2001BD] = { .pmin = -100000, .pmax = 100000 }, + [ABP21_6BD] = { .pmin = -160000, .pmax = 160000 }, + [ABP22_5BD] = { .pmin = -250000, .pmax = 250000 }, + [ABP2004BD] = { .pmin = -400000, .pmax = 400000 }, + [ABP2001BG] = { .pmin = 0, .pmax = 100000 }, + [ABP21_6BG] = { .pmin = 0, .pmax = 160000 }, + [ABP22_5BG] = { .pmin = 0, .pmax = 250000 }, + [ABP2004BG] = { .pmin = 0, .pmax = 400000 }, + [ABP2006BG] = { .pmin = 0, .pmax = 600000 }, + [ABP2008BG] = { .pmin = 0, .pmax = 800000 }, + [ABP2010BG] = { .pmin = 0, .pmax = 1000000 }, + [ABP2012BG] = { .pmin = 0, .pmax = 1200000 }, + [ABP2001GG] = { .pmin = 0, .pmax = 1000000 }, + [ABP21_2GG] = { .pmin = 0, .pmax = 1200000 }, + [ABP2100KA] = { .pmin = 0, .pmax = 100000 }, + [ABP2160KA] = { .pmin = 0, .pmax = 160000 }, + [ABP2250KA] = { .pmin = 0, .pmax = 250000 }, + [ABP2001KD] = { .pmin = -1000, .pmax = 1000 }, + [ABP21_6KD] = { .pmin = -1600, .pmax = 1600 }, + [ABP22_5KD] = { .pmin = -2500, .pmax = 2500 }, + [ABP2004KD] = { .pmin = -4000, .pmax = 4000 }, + [ABP2006KD] = { .pmin = -6000, .pmax = 6000 }, + [ABP2010KD] = { .pmin = -10000, .pmax = 10000 }, + [ABP2016KD] = { .pmin = -16000, .pmax = 16000 }, + [ABP2025KD] = { .pmin = -25000, .pmax = 25000 }, + [ABP2040KD] = { .pmin = -40000, .pmax = 40000 }, + [ABP2060KD] = { .pmin = -60000, .pmax = 60000 }, + [ABP2100KD] = { .pmin = -100000, .pmax = 100000 }, + [ABP2160KD] = { .pmin = -160000, .pmax = 160000 }, + [ABP2250KD] = { .pmin = -250000, .pmax = 250000 }, + [ABP2400KD] = { .pmin = -400000, .pmax = 400000 }, + [ABP2001KG] = { .pmin = 0, .pmax = 1000 }, + [ABP21_6KG] = { .pmin = 0, .pmax = 1600 }, + [ABP22_5KG] = { .pmin = 0, .pmax = 2500 }, + [ABP2004KG] = { .pmin = 0, .pmax = 4000 }, + [ABP2006KG] = { .pmin = 0, .pmax = 6000 }, + [ABP2010KG] = { .pmin = 0, .pmax = 10000 }, + [ABP2016KG] = { .pmin = 0, .pmax = 16000 }, + [ABP2025KG] = { .pmin = 0, .pmax = 25000 }, + [ABP2040KG] = { .pmin = 0, .pmax = 40000 }, + [ABP2060KG] = { .pmin = 0, .pmax = 60000 }, + [ABP2100KG] = { .pmin = 0, .pmax = 100000 }, + [ABP2160KG] = { .pmin = 0, .pmax = 160000 }, + [ABP2250KG] = { .pmin = 0, .pmax = 250000 }, + [ABP2400KG] = { .pmin = 0, .pmax = 400000 }, + [ABP2600KG] = { .pmin = 0, .pmax = 600000 }, + [ABP2800KG] = { .pmin = 0, .pmax = 800000 }, + [ABP2250LD] = { .pmin = -250, .pmax = 250 }, + [ABP2600LD] = { .pmin = -600, .pmax = 600 }, + [ABP2600LG] = { .pmin = 0, .pmax = 600 }, + [ABP22_5MD] = { .pmin = -250, .pmax = 250 }, + [ABP2006MD] = { .pmin = -600, .pmax = 600 }, + [ABP2010MD] = { .pmin = -1000, .pmax = 1000 }, + [ABP2016MD] = { .pmin = -1600, .pmax = 1600 }, + [ABP2025MD] = { .pmin = -2500, .pmax = 2500 }, + [ABP2040MD] = { .pmin = -4000, .pmax = 4000 }, + [ABP2060MD] = { .pmin = -6000, .pmax = 6000 }, + [ABP2100MD] = { .pmin = -10000, .pmax = 10000 }, + [ABP2160MD] = { .pmin = -16000, .pmax = 16000 }, + [ABP2250MD] = { .pmin = -25000, .pmax = 25000 }, + [ABP2400MD] = { .pmin = -40000, .pmax = 40000 }, + [ABP2600MD] = { .pmin = -60000, .pmax = 60000 }, + [ABP2006MG] = { .pmin = 0, .pmax = 600 }, + [ABP2010MG] = { .pmin = 0, .pmax = 1000 }, + [ABP2016MG] = { .pmin = 0, .pmax = 1600 }, + [ABP2025MG] = { .pmin = 0, .pmax = 2500 }, + [ABP2040MG] = { .pmin = 0, .pmax = 4000 }, + [ABP2060MG] = { .pmin = 0, .pmax = 6000 }, + [ABP2100MG] = { .pmin = 0, .pmax = 10000 }, + [ABP2160MG] = { .pmin = 0, .pmax = 16000 }, + [ABP2250MG] = { .pmin = 0, .pmax = 25000 }, + [ABP2400MG] = { .pmin = 0, .pmax = 40000 }, + [ABP2600MG] = { .pmin = 0, .pmax = 60000 }, + [ABP2001ND] = { .pmin = -249, .pmax = 249 }, + [ABP2002ND] = { .pmin = -498, .pmax = 498 }, + [ABP2004ND] = { .pmin = -996, .pmax = 996 }, + [ABP2005ND] = { .pmin = -1245, .pmax = 1245 }, + [ABP2010ND] = { .pmin = -2491, .pmax = 2491 }, + [ABP2020ND] = { .pmin = -4982, .pmax = 4982 }, + [ABP2030ND] = { .pmin = -7473, .pmax = 7473 }, + [ABP2002NG] = { .pmin = 0, .pmax = 498 }, + [ABP2004NG] = { .pmin = 0, .pmax = 996 }, + [ABP2005NG] = { .pmin = 0, .pmax = 1245 }, + [ABP2010NG] = { .pmin = 0, .pmax = 2491 }, + [ABP2020NG] = { .pmin = 0, .pmax = 4982 }, + [ABP2030NG] = { .pmin = 0, .pmax = 7473 }, + [ABP2015PA] = { .pmin = 0, .pmax = 103421 }, + [ABP2030PA] = { .pmin = 0, .pmax = 206843 }, + [ABP2060PA] = { .pmin = 0, .pmax = 413685 }, + [ABP2100PA] = { .pmin = 0, .pmax = 689476 }, + [ABP2150PA] = { .pmin = 0, .pmax = 1034214 }, + [ABP2175PA] = { .pmin = 0, .pmax = 1206583 }, + [ABP2001PD] = { .pmin = -6895, .pmax = 6895 }, + [ABP2005PD] = { .pmin = -34474, .pmax = 34474 }, + [ABP2015PD] = { .pmin = -103421, .pmax = 103421 }, + [ABP2030PD] = { .pmin = -206843, .pmax = 206843 }, + [ABP2060PD] = { .pmin = -413685, .pmax = 413685 }, + [ABP2001PG] = { .pmin = 0, .pmax = 6895 }, + [ABP2005PG] = { .pmin = 0, .pmax = 34474 }, + [ABP2015PG] = { .pmin = 0, .pmax = 103421 }, + [ABP2030PG] = { .pmin = 0, .pmax = 206843 }, + [ABP2060PG] = { .pmin = 0, .pmax = 413685 }, + [ABP2100PG] = { .pmin = 0, .pmax = 689476 }, + [ABP2150PG] = { .pmin = 0, .pmax = 1034214 }, + [ABP2175PG] = { .pmin = 0, .pmax = 1206583 }, +}; + +static_assert(ARRAY_SIZE(abp2_triplet_variants) == ARRAY_SIZE(abp2_range_config)); + +static int abp2_get_measurement(struct abp2_data *data) +{ + struct device *dev = data->dev; + int ret; + + reinit_completion(&data->completion); + + ret = data->ops->write(data, ABP2_CMD_SYNC, ABP2_PKT_SYNC_LEN); + if (ret < 0) + return ret; + + if (data->irq > 0) { + ret = wait_for_completion_timeout(&data->completion, HZ); + if (!ret) { + dev_err(dev, "timeout waiting for EOC interrupt\n"); + return -ETIMEDOUT; + } + } else { + fsleep(5 * USEC_PER_MSEC); + } + + memset(data->rx_buf, 0, sizeof(data->rx_buf)); + ret = data->ops->read(data, ABP2_CMD_NOP, ABP2_PKT_NOP_LEN); + if (ret < 0) + return ret; + + /* + * Status byte flags + * bit7 SANITY_CHK - must always be 0 + * bit6 ABP2_ST_POWER - 1 if device is powered + * bit5 ABP2_ST_BUSY - 1 if device has no new conversion ready + * bit4 SANITY_CHK - must always be 0 + * bit3 SANITY_CHK - must always be 0 + * bit2 MEMORY_ERR - 1 if integrity test has failed + * bit1 SANITY_CHK - must always be 0 + * bit0 MATH_ERR - 1 during internal math saturation error + */ + + if (data->rx_buf[0] == (ABP2_ST_POWER | ABP2_ST_BUSY)) + return -EBUSY; + + /* + * The ABP2 sensor series seem to have a noticeable latch-up sensitivity. + * A partial latch-up condition manifests as either + * - output of invalid status bytes + * - zeroed out conversions (despite a normal status byte) + * - the MOSI line being pulled low randomly in sync with the SCLK + * signal (visible during the ABP2_CMD_NOP command). + * https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1588325/am3358-spi-tx-data-corruption + */ + + if (data->rx_buf[0] != ABP2_ST_POWER) { + dev_err(data->dev, + "unexpected status byte 0x%02x\n", data->rx_buf[0]); + return -EIO; + } + + return 0; +} + +static irqreturn_t abp2_eoc_handler(int irq, void *private) +{ + struct abp2_data *data = private; + + complete(&data->completion); + + return IRQ_HANDLED; +} + +static irqreturn_t abp2_trigger_handler(int irq, void *private) +{ + int ret; + struct iio_poll_func *pf = private; + struct iio_dev *indio_dev = pf->indio_dev; + struct abp2_data *data = iio_priv(indio_dev); + + ret = abp2_get_measurement(data); + if (ret < 0) + goto out_notify_done; + + data->scan.chan[0] = get_unaligned_be24(&data->rx_buf[1]); + data->scan.chan[1] = get_unaligned_be24(&data->rx_buf[4]); + + iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), + iio_get_time_ns(indio_dev)); + +out_notify_done: + iio_trigger_notify_done(indio_dev->trig); + + return IRQ_HANDLED; +} + +/* + * IIO ABI expects + * value = (conv + offset) * scale + * + * temp[C] = conv * a + b + * where a = 200/16777215; b = -50 + * + * temp[C] = (conv + (b/a)) * a * (1000) + * => + * scale = a * 1000 = .0000119209296 * 1000 = .01192092966562 + * offset = b/a = -50 * 16777215 / 200 = -4194303.75 + * + * pressure = (conv - Omin) * Q + Pmin = + * ((conv - Omin) + Pmin/Q) * Q + * => + * scale = Q = (Pmax - Pmin) / (Omax - Omin) + * offset = Pmin/Q - Omin = Pmin * (Omax - Omin) / (Pmax - Pmin) - Omin + */ +static int abp2_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *channel, int *val, + int *val2, long mask) +{ + struct abp2_data *data = iio_priv(indio_dev); + int ret; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = abp2_get_measurement(data); + if (ret < 0) + return ret; + + switch (channel->type) { + case IIO_PRESSURE: + *val = get_unaligned_be24(&data->rx_buf[1]); + return IIO_VAL_INT; + case IIO_TEMP: + *val = get_unaligned_be24(&data->rx_buf[4]); + return IIO_VAL_INT; + default: + return -EINVAL; + } + return IIO_VAL_INT; + + case IIO_CHAN_INFO_SCALE: + switch (channel->type) { + case IIO_TEMP: + *val = 0; + *val2 = 11920929; + return IIO_VAL_INT_PLUS_NANO; + case IIO_PRESSURE: + *val = data->p_scale; + *val2 = data->p_scale_dec; + return IIO_VAL_INT_PLUS_NANO; + default: + return -EINVAL; + } + + case IIO_CHAN_INFO_OFFSET: + switch (channel->type) { + case IIO_TEMP: + *val = -4194304; + return IIO_VAL_INT; + case IIO_PRESSURE: + *val = data->p_offset; + return IIO_VAL_INT; + default: + return -EINVAL; + } + + default: + return -EINVAL; + } +} + +static const struct iio_info abp2_info = { + .read_raw = &abp2_read_raw, +}; + +static const unsigned long abp2_scan_masks[] = {0x3, 0}; + +static const struct iio_chan_spec abp2_channels[] = { + { + .type = IIO_PRESSURE, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .scan_index = 0, + .scan_type = { + .sign = 'u', + .realbits = 24, + .storagebits = 32, + .endianness = IIO_CPU, + }, + }, + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .scan_index = 1, + .scan_type = { + .sign = 'u', + .realbits = 24, + .storagebits = 32, + .endianness = IIO_CPU, + }, + }, + IIO_CHAN_SOFT_TIMESTAMP(2), +}; + +int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int irq) +{ + int ret; + struct abp2_data *data; + struct iio_dev *indio_dev; + const char *triplet; + s32 tmp; + s64 odelta, pdelta; + + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); + if (!indio_dev) + return -ENOMEM; + + data = iio_priv(indio_dev); + data->dev = dev; + data->ops = ops; + data->irq = irq; + + init_completion(&data->completion); + + indio_dev->name = "abp2030pa"; + indio_dev->info = &abp2_info; + indio_dev->channels = abp2_channels; + indio_dev->num_channels = ARRAY_SIZE(abp2_channels); + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->available_scan_masks = abp2_scan_masks; + + ret = devm_regulator_get_enable(dev, "vdd"); + if (ret) + return dev_err_probe(dev, ret, "can't get and enable vdd supply\n"); + + ret = device_property_read_string(dev, "honeywell,pressure-triplet", + &triplet); + if (ret) { + ret = device_property_read_u32(dev, "honeywell,pmin-pascal", + &data->pmin); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmin-pascal could not be read\n"); + + ret = device_property_read_u32(dev, "honeywell,pmax-pascal", + &data->pmax); + if (ret) + return dev_err_probe(dev, ret, + "honeywell,pmax-pascal could not be read\n"); + } else { + ret = device_property_match_property_string(dev, + "honeywell,pressure-triplet", + abp2_triplet_variants, + ARRAY_SIZE(abp2_triplet_variants)); + if (ret < 0) + return dev_err_probe(dev, -EINVAL, "honeywell,pressure-triplet is invalid\n"); + + data->pmin = abp2_range_config[ret].pmin; + data->pmax = abp2_range_config[ret].pmax; + } + + if (data->pmin >= data->pmax) + return dev_err_probe(dev, -EINVAL, "pressure limits are invalid\n"); + + data->outmin = abp2_func_spec[data->function].output_min; + data->outmax = abp2_func_spec[data->function].output_max; + + odelta = data->outmax - data->outmin; + pdelta = data->pmax - data->pmin; + + data->p_scale = div_s64_rem(div_s64(pdelta * NANO, odelta), NANO, &tmp); + data->p_scale_dec = tmp; + + data->p_offset = div_s64(odelta * data->pmin, pdelta) - data->outmin; + + if (data->irq > 0) { + ret = devm_request_irq(dev, irq, abp2_eoc_handler, IRQF_ONESHOT, + dev_name(dev), data); + if (ret) + return ret; + } + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + abp2_trigger_handler, NULL); + if (ret) + return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n"); + + ret = devm_iio_device_register(dev, indio_dev); + if (ret) + return dev_err_probe(dev, ret, "unable to register iio device\n"); + + return 0; +} +EXPORT_SYMBOL_NS_GPL(abp2_common_probe, "IIO_HONEYWELL_ABP2030PA"); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor core driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/iio/pressure/abp2030pa.h b/drivers/iio/pressure/abp2030pa.h new file mode 100644 index 000000000000..57e5ed784686 --- /dev/null +++ b/drivers/iio/pressure/abp2030pa.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#ifndef _ABP2030PA_H +#define _ABP2030PA_H + +#include +#include + +#include + +#define ABP2_MEASUREMENT_RD_SIZE 7 + +struct device; + +struct abp2_data; +struct abp2_ops; + +enum abp2_func_id { + ABP2_FUNCTION_A, +}; + +/** + * struct abp2_data + * @dev: current device structure + * @ops: pointers for bus specific read and write functions + * @pmin: minimal pressure in pascal + * @pmax: maximal pressure in pascal + * @outmin: minimum raw pressure in counts (based on transfer function) + * @outmax: maximum raw pressure in counts (based on transfer function) + * @function: transfer function + * @p_scale: pressure scale + * @p_scale_dec: pressure scale, decimal number + * @p_offset: pressure offset + * @irq: end of conversion - applies only to the i2c sensor + * @completion: handshake from irq to read + * @scan: channel values for buffered mode + * @tx_buf: transmit buffer used during the SPI communication + * @rx_buf: raw data provided by sensor + */ +struct abp2_data { + struct device *dev; + const struct abp2_ops *ops; + s32 pmin; + s32 pmax; + u32 outmin; + u32 outmax; + enum abp2_func_id function; + int p_scale; + int p_scale_dec; + int p_offset; + int irq; + struct completion completion; + struct { + u32 chan[2]; + aligned_s64 timestamp; + } scan; + u8 rx_buf[ABP2_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 tx_buf[ABP2_MEASUREMENT_RD_SIZE]; +}; + +struct abp2_ops { + int (*read)(struct abp2_data *data, u8 cmd, u8 nbytes); + int (*write)(struct abp2_data *data, u8 cmd, u8 nbytes); +}; + +int abp2_common_probe(struct device *dev, const struct abp2_ops *ops, int irq); + +#endif diff --git a/drivers/iio/pressure/abp2030pa_i2c.c b/drivers/iio/pressure/abp2030pa_i2c.c new file mode 100644 index 000000000000..9f1c1c8a9afb --- /dev/null +++ b/drivers/iio/pressure/abp2030pa_i2c.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#include +#include +#include +#include +#include +#include + +#include "abp2030pa.h" + +static int abp2_i2c_read(struct abp2_data *data, u8 unused, u8 nbytes) +{ + struct i2c_client *client = to_i2c_client(data->dev); + int ret; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + ret = i2c_master_recv(client, data->rx_buf, nbytes); + if (ret < 0) + return ret; + if (ret != nbytes) + return -EIO; + + return 0; +} + +static int abp2_i2c_write(struct abp2_data *data, u8 cmd, u8 nbytes) +{ + struct i2c_client *client = to_i2c_client(data->dev); + int ret; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + data->tx_buf[0] = cmd; + ret = i2c_master_send(client, data->tx_buf, nbytes); + if (ret < 0) + return ret; + if (ret != nbytes) + return -EIO; + + return 0; +} + +static const struct abp2_ops abp2_i2c_ops = { + .read = abp2_i2c_read, + .write = abp2_i2c_write, +}; + +static int abp2_i2c_probe(struct i2c_client *client) +{ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EOPNOTSUPP; + + return abp2_common_probe(&client->dev, &abp2_i2c_ops, client->irq); +} + +static const struct of_device_id abp2_i2c_match[] = { + { .compatible = "honeywell,abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(of, abp2_i2c_match); + +static const struct i2c_device_id abp2_i2c_id[] = { + { "abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, abp2_i2c_id); + +static struct i2c_driver abp2_i2c_driver = { + .driver = { + .name = "abp2030pa", + .of_match_table = abp2_i2c_match, + }, + .probe = abp2_i2c_probe, + .id_table = abp2_i2c_id, +}; +module_i2c_driver(abp2_i2c_driver); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor i2c driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_HONEYWELL_ABP2030PA"); diff --git a/drivers/iio/pressure/abp2030pa_spi.c b/drivers/iio/pressure/abp2030pa_spi.c new file mode 100644 index 000000000000..eaea9a3ebf11 --- /dev/null +++ b/drivers/iio/pressure/abp2030pa_spi.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Honeywell ABP2 series pressure sensor driver + * + * Copyright (c) 2025 Petre Rodan + */ + +#include +#include +#include +#include +#include + +#include "abp2030pa.h" + +static int abp2_spi_xfer(struct abp2_data *data, u8 cmd, u8 nbytes) +{ + struct spi_device *spi = to_spi_device(data->dev); + struct spi_transfer xfer = { }; + + if (nbytes > ABP2_MEASUREMENT_RD_SIZE) + return -EOVERFLOW; + + data->tx_buf[0] = cmd; + xfer.tx_buf = data->tx_buf; + xfer.rx_buf = data->rx_buf; + xfer.len = nbytes; + + return spi_sync_transfer(spi, &xfer, 1); +} + +static const struct abp2_ops abp2_spi_ops = { + .read = abp2_spi_xfer, + .write = abp2_spi_xfer, +}; + +static int abp2_spi_probe(struct spi_device *spi) +{ + return abp2_common_probe(&spi->dev, &abp2_spi_ops, spi->irq); +} + +static const struct of_device_id abp2_spi_match[] = { + { .compatible = "honeywell,abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(of, abp2_spi_match); + +static const struct spi_device_id abp2_spi_id[] = { + { "abp2030pa" }, + { } +}; +MODULE_DEVICE_TABLE(spi, abp2_spi_id); + +static struct spi_driver abp2_spi_driver = { + .driver = { + .name = "abp2030pa", + .of_match_table = abp2_spi_match, + }, + .probe = abp2_spi_probe, + .id_table = abp2_spi_id, +}; +module_spi_driver(abp2_spi_driver); + +MODULE_AUTHOR("Petre Rodan "); +MODULE_DESCRIPTION("Honeywell ABP2 pressure sensor spi driver"); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS("IIO_HONEYWELL_ABP2030PA"); diff --git a/drivers/iio/pressure/dlhl60d.c b/drivers/iio/pressure/dlhl60d.c index 8bad7162fec6..46feb27fe632 100644 --- a/drivers/iio/pressure/dlhl60d.c +++ b/drivers/iio/pressure/dlhl60d.c @@ -306,10 +306,9 @@ static int dlh_probe(struct i2c_client *client) indio_dev->num_channels = ARRAY_SIZE(dlh_channels); if (client->irq > 0) { - ret = devm_request_threaded_irq(&client->dev, client->irq, - dlh_interrupt, NULL, - IRQF_TRIGGER_RISING | IRQF_ONESHOT, - st->info->name, indio_dev); + ret = devm_request_irq(&client->dev, client->irq, dlh_interrupt, + IRQF_TRIGGER_RISING | IRQF_NO_THREAD, + st->info->name, indio_dev); if (ret) { dev_err(&client->dev, "failed to allocate threaded irq"); return ret; diff --git a/drivers/iio/pressure/mprls0025pa.c b/drivers/iio/pressure/mprls0025pa.c index 2336f2760eae..e8c495f336ff 100644 --- a/drivers/iio/pressure/mprls0025pa.c +++ b/drivers/iio/pressure/mprls0025pa.c @@ -3,6 +3,7 @@ * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver * * Copyright (c) Andreas Klinger + * Copyright (c) 2023-2025 Petre Rodan * * Data sheet: * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf @@ -12,15 +13,24 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include #include #include #include +#include +#include #include #include #include +#include #include #include @@ -33,10 +43,6 @@ /* bits in status byte */ #define MPR_ST_POWER BIT(6) /* device is powered */ #define MPR_ST_BUSY BIT(5) /* device is busy */ -#define MPR_ST_MEMORY BIT(2) /* integrity test passed */ -#define MPR_ST_MATH BIT(0) /* internal math saturation */ - -#define MPR_ST_ERR_FLAG (MPR_ST_BUSY | MPR_ST_MEMORY | MPR_ST_MATH) /* * support _RAW sysfs interface: @@ -59,7 +65,7 @@ * * Values given to the userspace in sysfs interface: * * raw - press_cnt - * * offset - (-1 * outputmin) - pmin / scale + * * offset - (-1 * outputmin) + pmin / scale * note: With all sensors from the datasheet pmin = 0 * which reduces the offset to (-1 * outputmin) */ @@ -160,8 +166,8 @@ static const struct iio_chan_spec mpr_channels[] = { BIT(IIO_CHAN_INFO_OFFSET), .scan_index = 0, .scan_type = { - .sign = 's', - .realbits = 32, + .sign = 'u', + .realbits = 24, .storagebits = 32, .endianness = IIO_CPU, }, @@ -190,15 +196,15 @@ static void mpr_reset(struct mpr_data *data) * * Context: The function can sleep and data->lock should be held when calling it * Return: - * * 0 - OK, the pressure value could be read - * * -ETIMEDOUT - Timeout while waiting for the EOC interrupt or busy flag is - * still set after nloops attempts of reading + * * 0 - OK, the pressure value could be read + * * -EBUSY - Sensor does not have a new conversion ready + * * -ETIMEDOUT - Timeout while waiting for the EOC interrupt + * * -EIO - Invalid status byte received from sensor */ static int mpr_read_pressure(struct mpr_data *data, s32 *press) { struct device *dev = data->dev; - int ret, i; - int nloops = 10; + int ret; reinit_completion(&data->completion); @@ -215,44 +221,38 @@ static int mpr_read_pressure(struct mpr_data *data, s32 *press) return -ETIMEDOUT; } } else { - /* wait until status indicates data is ready */ - for (i = 0; i < nloops; i++) { - /* - * datasheet only says to wait at least 5 ms for the - * data but leave the maximum response time open - * --> let's try it nloops (10) times which seems to be - * quite long - */ - usleep_range(5000, 10000); - ret = data->ops->read(data, MPR_CMD_NOP, 1); - if (ret < 0) { - dev_err(dev, - "error while reading, status: %d\n", - ret); - return ret; - } - if (!(data->buffer[0] & MPR_ST_ERR_FLAG)) - break; - } - if (i == nloops) { - dev_err(dev, "timeout while reading\n"); - return -ETIMEDOUT; - } + fsleep(5 * USEC_PER_MSEC); } + memset(data->rx_buf, 0, sizeof(data->rx_buf)); ret = data->ops->read(data, MPR_CMD_NOP, MPR_PKT_NOP_LEN); if (ret < 0) return ret; - if (data->buffer[0] & MPR_ST_ERR_FLAG) { + /* + * Status byte flags + * bit7 SANITY_CHK - must always be 0 + * bit6 MPR_ST_POWER - 1 if device is powered + * bit5 MPR_ST_BUSY - 1 if device has no new conversion ready + * bit4 SANITY_CHK - must always be 0 + * bit3 SANITY_CHK - must always be 0 + * bit2 MEMORY_ERR - 1 if integrity test has failed + * bit1 SANITY_CHK - must always be 0 + * bit0 MATH_ERR - 1 during internal math saturation error + */ + + if (data->rx_buf[0] == (MPR_ST_POWER | MPR_ST_BUSY)) + return -EBUSY; + + if (data->rx_buf[0] != MPR_ST_POWER) { dev_err(data->dev, - "unexpected status byte %02x\n", data->buffer[0]); - return -ETIMEDOUT; + "unexpected status byte 0x%02x\n", data->rx_buf[0]); + return -EIO; } - *press = get_unaligned_be24(&data->buffer[1]); + *press = get_unaligned_be24(&data->rx_buf[1]); - dev_dbg(dev, "received: %*ph cnt: %d\n", ret, data->buffer, *press); + dev_dbg(dev, "received: %*ph cnt: %d\n", ret, data->rx_buf, *press); return 0; } @@ -313,8 +313,7 @@ static int mpr_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_OFFSET: *val = data->offset; - *val2 = data->offset2; - return IIO_VAL_INT_PLUS_NANO; + return IIO_VAL_INT; default: return -EINVAL; } @@ -330,8 +329,9 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) struct mpr_data *data; struct iio_dev *indio_dev; const char *triplet; - s64 scale, offset; + s64 odelta, pdelta; u32 func; + s32 tmp; indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); if (!indio_dev) @@ -356,10 +356,6 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) return dev_err_probe(dev, ret, "can't get and enable vdd supply\n"); - ret = data->ops->init(data->dev); - if (ret) - return ret; - ret = device_property_read_u32(dev, "honeywell,transfer-function", &func); if (ret) @@ -405,26 +401,19 @@ int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) data->outmin = mpr_func_spec[data->function].output_min; data->outmax = mpr_func_spec[data->function].output_max; - /* use 64 bit calculation for preserving a reasonable precision */ - scale = div_s64(((s64)(data->pmax - data->pmin)) * NANO, - data->outmax - data->outmin); - data->scale = div_s64_rem(scale, NANO, &data->scale2); - /* - * multiply with NANO before dividing by scale and later divide by NANO - * again. - */ - offset = ((-1LL) * (s64)data->outmin) * NANO - - div_s64(div_s64((s64)data->pmin * NANO, scale), NANO); - data->offset = div_s64_rem(offset, NANO, &data->offset2); + odelta = data->outmax - data->outmin; + pdelta = data->pmax - data->pmin; + + data->scale = div_s64_rem(div_s64(pdelta * NANO, odelta), NANO, &tmp); + data->scale2 = tmp; + + data->offset = div_s64(odelta * data->pmin, pdelta) - data->outmin; if (data->irq > 0) { - ret = devm_request_irq(dev, data->irq, mpr_eoc_handler, - IRQF_TRIGGER_RISING, - dev_name(dev), - data); + ret = devm_request_irq(dev, data->irq, mpr_eoc_handler, 0, + dev_name(dev), data); if (ret) - return dev_err_probe(dev, ret, - "request irq %d failed\n", data->irq); + return ret; } data->gpiod_reset = devm_gpiod_get_optional(dev, "reset", diff --git a/drivers/iio/pressure/mprls0025pa.h b/drivers/iio/pressure/mprls0025pa.h index d62a018eaff3..9f43273e635f 100644 --- a/drivers/iio/pressure/mprls0025pa.h +++ b/drivers/iio/pressure/mprls0025pa.h @@ -12,10 +12,7 @@ #define _MPRLS0025PA_H #include -#include -#include #include -#include #include #include @@ -28,9 +25,6 @@ struct device; -struct iio_chan_spec; -struct iio_dev; - struct mpr_data; struct mpr_ops; @@ -53,7 +47,6 @@ enum mpr_func_id { * @scale: pressure scale * @scale2: pressure scale, decimal number * @offset: pressure offset - * @offset2: pressure offset, decimal number * @gpiod_reset: reset * @irq: end of conversion irq. used to distinguish between irq mode and * reading in a loop until data is ready @@ -61,7 +54,8 @@ enum mpr_func_id { * @chan: channel values for buffered mode * @chan.pres: pressure value * @chan.ts: timestamp - * @buffer: raw conversion data + * @rx_buf: raw conversion data + * @tx_buf: output buffer */ struct mpr_data { struct device *dev; @@ -75,7 +69,6 @@ struct mpr_data { int scale; int scale2; int offset; - int offset2; struct gpio_desc *gpiod_reset; int irq; struct completion completion; @@ -83,11 +76,11 @@ struct mpr_data { s32 pres; aligned_s64 ts; } chan; - u8 buffer[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 rx_buf[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); + u8 tx_buf[MPR_MEASUREMENT_RD_SIZE]; }; struct mpr_ops { - int (*init)(struct device *dev); int (*read)(struct mpr_data *data, const u8 cmd, const u8 cnt); int (*write)(struct mpr_data *data, const u8 cmd, const u8 cnt); }; diff --git a/drivers/iio/pressure/mprls0025pa_i2c.c b/drivers/iio/pressure/mprls0025pa_i2c.c index 79811fd4a02b..0fe8cfe0d7e7 100644 --- a/drivers/iio/pressure/mprls0025pa_i2c.c +++ b/drivers/iio/pressure/mprls0025pa_i2c.c @@ -17,11 +17,6 @@ #include "mprls0025pa.h" -static int mpr_i2c_init(struct device *unused) -{ - return 0; -} - static int mpr_i2c_read(struct mpr_data *data, const u8 unused, const u8 cnt) { int ret; @@ -30,8 +25,7 @@ static int mpr_i2c_read(struct mpr_data *data, const u8 unused, const u8 cnt) if (cnt > MPR_MEASUREMENT_RD_SIZE) return -EOVERFLOW; - memset(data->buffer, 0, MPR_MEASUREMENT_RD_SIZE); - ret = i2c_master_recv(client, data->buffer, cnt); + ret = i2c_master_recv(client, data->rx_buf, cnt); if (ret < 0) return ret; else if (ret != cnt) @@ -44,9 +38,9 @@ static int mpr_i2c_write(struct mpr_data *data, const u8 cmd, const u8 unused) { int ret; struct i2c_client *client = to_i2c_client(data->dev); - u8 wdata[MPR_PKT_SYNC_LEN] = { cmd }; - ret = i2c_master_send(client, wdata, MPR_PKT_SYNC_LEN); + data->tx_buf[0] = cmd; + ret = i2c_master_send(client, data->tx_buf, MPR_PKT_SYNC_LEN); if (ret < 0) return ret; else if (ret != MPR_PKT_SYNC_LEN) @@ -56,7 +50,6 @@ static int mpr_i2c_write(struct mpr_data *data, const u8 cmd, const u8 unused) } static const struct mpr_ops mpr_i2c_ops = { - .init = mpr_i2c_init, .read = mpr_i2c_read, .write = mpr_i2c_write, }; diff --git a/drivers/iio/pressure/mprls0025pa_spi.c b/drivers/iio/pressure/mprls0025pa_spi.c index d04102f8a4a0..8c8c726f703f 100644 --- a/drivers/iio/pressure/mprls0025pa_spi.c +++ b/drivers/iio/pressure/mprls0025pa_spi.c @@ -8,6 +8,7 @@ * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf */ +#include #include #include #include @@ -18,43 +19,31 @@ #include "mprls0025pa.h" -struct mpr_spi_buf { - u8 tx[MPR_MEASUREMENT_RD_SIZE] __aligned(IIO_DMA_MINALIGN); -}; - -static int mpr_spi_init(struct device *dev) -{ - struct spi_device *spi = to_spi_device(dev); - struct mpr_spi_buf *buf; - - buf = devm_kzalloc(dev, sizeof(*buf), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - spi_set_drvdata(spi, buf); - - return 0; -} - static int mpr_spi_xfer(struct mpr_data *data, const u8 cmd, const u8 pkt_len) { struct spi_device *spi = to_spi_device(data->dev); - struct mpr_spi_buf *buf = spi_get_drvdata(spi); - struct spi_transfer xfer; + struct spi_transfer xfers[2] = { }; if (pkt_len > MPR_MEASUREMENT_RD_SIZE) return -EOVERFLOW; - buf->tx[0] = cmd; - xfer.tx_buf = buf->tx; - xfer.rx_buf = data->buffer; - xfer.len = pkt_len; + data->tx_buf[0] = cmd; - return spi_sync_transfer(spi, &xfer, 1); + /* + * Dummy transfer with no data, just cause a 2.5us+ delay between the CS assert + * and the first clock edge as per the datasheet tHDSS timing requirement. + */ + xfers[0].delay.value = 2500; + xfers[0].delay.unit = SPI_DELAY_UNIT_NSECS; + + xfers[1].tx_buf = data->tx_buf; + xfers[1].rx_buf = data->rx_buf; + xfers[1].len = pkt_len; + + return spi_sync_transfer(spi, xfers, ARRAY_SIZE(xfers)); } static const struct mpr_ops mpr_spi_ops = { - .init = mpr_spi_init, .read = mpr_spi_xfer, .write = mpr_spi_xfer, }; diff --git a/drivers/iio/proximity/hx9023s.c b/drivers/iio/proximity/hx9023s.c index 2918dfc0df54..17e00ee2b6f8 100644 --- a/drivers/iio/proximity/hx9023s.c +++ b/drivers/iio/proximity/hx9023s.c @@ -719,6 +719,9 @@ static int hx9023s_set_samp_freq(struct hx9023s_data *data, int val, int val2) struct device *dev = regmap_get_device(data->regmap); unsigned int i, period_ms; + if (!val && !val2) + return -EINVAL; + period_ms = div_u64(NANO, (val * MEGA + val2)); for (i = 0; i < ARRAY_SIZE(hx9023s_samp_freq_table); i++) { @@ -1034,9 +1037,8 @@ static int hx9023s_send_cfg(const struct firmware *fw, struct hx9023s_data *data if (!bin) return -ENOMEM; - memcpy(bin->data, fw->data, fw->size); - bin->fw_size = fw->size; + memcpy(bin->data, fw->data, bin->fw_size); bin->fw_ver = bin->data[FW_VER_OFFSET]; bin->reg_count = get_unaligned_le16(bin->data + FW_REG_CNT_OFFSET); diff --git a/drivers/iio/proximity/rfd77402.c b/drivers/iio/proximity/rfd77402.c index aff60a3c1a6f..6afdbfca3e5a 100644 --- a/drivers/iio/proximity/rfd77402.c +++ b/drivers/iio/proximity/rfd77402.c @@ -6,19 +6,28 @@ * * 7-bit I2C slave address 0x4c * - * TODO: interrupt * https://media.digikey.com/pdf/Data%20Sheets/RF%20Digital%20PDFs/RFD77402.pdf */ -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include #define RFD77402_DRV_NAME "rfd77402" #define RFD77402_ICSR 0x00 /* Interrupt Control Status Register */ +#define RFD77402_ICSR_CLR_CFG BIT(0) +#define RFD77402_ICSR_CLR_TYPE BIT(1) #define RFD77402_ICSR_INT_MODE BIT(2) #define RFD77402_ICSR_INT_POL BIT(3) #define RFD77402_ICSR_RESULT BIT(4) @@ -26,6 +35,12 @@ #define RFD77402_ICSR_H2M_MSG BIT(6) #define RFD77402_ICSR_RESET BIT(7) +#define RFD77402_IER 0x02 +#define RFD77402_IER_RESULT BIT(0) +#define RFD77402_IER_M2H_MSG BIT(1) +#define RFD77402_IER_H2M_MSG BIT(2) +#define RFD77402_IER_RESET BIT(3) + #define RFD77402_CMD_R 0x04 #define RFD77402_CMD_SINGLE 0x01 #define RFD77402_CMD_STANDBY 0x10 @@ -76,10 +91,18 @@ static const struct { {RFD77402_HFCFG_3, 0x45d4}, }; +/** + * struct rfd77402_data - device-specific data for the RFD77402 sensor + * @client: I2C client handle + * @lock: mutex to serialize sensor reads + * @completion: completion used for interrupt-driven measurements + * @irq_en: indicates whether interrupt mode is enabled + */ struct rfd77402_data { struct i2c_client *client; - /* Serialize reads from the sensor */ struct mutex lock; + struct completion completion; + bool irq_en; }; static const struct iio_chan_spec rfd77402_channels[] = { @@ -90,6 +113,41 @@ static const struct iio_chan_spec rfd77402_channels[] = { }, }; +static irqreturn_t rfd77402_interrupt_handler(int irq, void *pdata) +{ + struct rfd77402_data *data = pdata; + int ret; + + ret = i2c_smbus_read_byte_data(data->client, RFD77402_ICSR); + if (ret < 0) + return IRQ_NONE; + + /* Check if the interrupt is from our device */ + if (!(ret & RFD77402_ICSR_RESULT)) + return IRQ_NONE; + + /* Signal completion of measurement */ + complete(&data->completion); + return IRQ_HANDLED; +} + +static int rfd77402_wait_for_irq(struct rfd77402_data *data) +{ + int ret; + + /* + * According to RFD77402 Datasheet v1.8, + * Section 3.1.1 "Single Measure" (Figure: Single Measure Flow Chart), + * the suggested timeout for single measure is 100 ms. + */ + ret = wait_for_completion_timeout(&data->completion, + msecs_to_jiffies(100)); + if (ret == 0) + return -ETIMEDOUT; + + return 0; +} + static int rfd77402_set_state(struct i2c_client *client, u8 state, u16 check) { int ret; @@ -110,10 +168,36 @@ static int rfd77402_set_state(struct i2c_client *client, u8 state, u16 check) return 0; } -static int rfd77402_measure(struct i2c_client *client) +static int rfd77402_wait_for_result(struct rfd77402_data *data) { + struct i2c_client *client = data->client; + int val, ret; + + if (data->irq_en) { + reinit_completion(&data->completion); + return rfd77402_wait_for_irq(data); + } + + /* + * As per RFD77402 datasheet section '3.1.1 Single Measure', the + * suggested timeout value for single measure is 100ms. + */ + ret = read_poll_timeout(i2c_smbus_read_byte_data, val, + (val < 0) || (val & RFD77402_ICSR_RESULT), + 10 * USEC_PER_MSEC, + 10 * 10 * USEC_PER_MSEC, + false, + client, RFD77402_ICSR); + if (val < 0) + return val; + + return ret; +} + +static int rfd77402_measure(struct rfd77402_data *data) +{ + struct i2c_client *client = data->client; int ret; - int tries = 10; ret = rfd77402_set_state(client, RFD77402_CMD_MCPU_ON, RFD77402_STATUS_MCPU_ON); @@ -126,19 +210,9 @@ static int rfd77402_measure(struct i2c_client *client) if (ret < 0) goto err; - while (tries-- > 0) { - ret = i2c_smbus_read_byte_data(client, RFD77402_ICSR); - if (ret < 0) - goto err; - if (ret & RFD77402_ICSR_RESULT) - break; - msleep(20); - } - - if (tries < 0) { - ret = -ETIMEDOUT; + ret = rfd77402_wait_for_result(data); + if (ret < 0) goto err; - } ret = i2c_smbus_read_word_data(client, RFD77402_RESULT_R); if (ret < 0) @@ -168,7 +242,7 @@ static int rfd77402_read_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: mutex_lock(&data->lock); - ret = rfd77402_measure(data->client); + ret = rfd77402_measure(data); mutex_unlock(&data->lock); if (ret < 0) return ret; @@ -188,8 +262,20 @@ static const struct iio_info rfd77402_info = { .read_raw = rfd77402_read_raw, }; -static int rfd77402_init(struct i2c_client *client) +static int rfd77402_config_irq(struct i2c_client *client, u8 csr, u8 ier) { + int ret; + + ret = i2c_smbus_write_byte_data(client, RFD77402_ICSR, csr); + if (ret) + return ret; + + return i2c_smbus_write_byte_data(client, RFD77402_IER, ier); +} + +static int rfd77402_init(struct rfd77402_data *data) +{ + struct i2c_client *client = data->client; int ret, i; ret = rfd77402_set_state(client, RFD77402_CMD_STANDBY, @@ -197,10 +283,26 @@ static int rfd77402_init(struct i2c_client *client) if (ret < 0) return ret; - /* configure INT pad as push-pull, active low */ - ret = i2c_smbus_write_byte_data(client, RFD77402_ICSR, - RFD77402_ICSR_INT_MODE); - if (ret < 0) + if (data->irq_en) { + /* + * Enable interrupt mode: + * - Configure ICSR for auto-clear on read and + * push-pull output + * - Enable "result ready" interrupt in IER + */ + ret = rfd77402_config_irq(client, + RFD77402_ICSR_CLR_CFG | + RFD77402_ICSR_INT_MODE, + RFD77402_IER_RESULT); + } else { + /* + * Disable all interrupts: + * - Clear ICSR configuration + * - Disable all interrupts in IER + */ + ret = rfd77402_config_irq(client, 0, 0); + } + if (ret) return ret; /* I2C configuration */ @@ -275,7 +377,26 @@ static int rfd77402_probe(struct i2c_client *client) data = iio_priv(indio_dev); data->client = client; - mutex_init(&data->lock); + + ret = devm_mutex_init(&client->dev, &data->lock); + if (ret) + return ret; + + init_completion(&data->completion); + + if (client->irq > 0) { + ret = devm_request_threaded_irq(&client->dev, client->irq, + NULL, rfd77402_interrupt_handler, + IRQF_ONESHOT, + "rfd77402", data); + if (ret) + return ret; + + data->irq_en = true; + dev_dbg(&client->dev, "Using interrupt mode\n"); + } else { + dev_dbg(&client->dev, "Using polling mode\n"); + } indio_dev->info = &rfd77402_info; indio_dev->channels = rfd77402_channels; @@ -283,7 +404,7 @@ static int rfd77402_probe(struct i2c_client *client) indio_dev->name = RFD77402_DRV_NAME; indio_dev->modes = INDIO_DIRECT_MODE; - ret = rfd77402_init(client); + ret = rfd77402_init(data); if (ret < 0) return ret; @@ -301,7 +422,10 @@ static int rfd77402_suspend(struct device *dev) static int rfd77402_resume(struct device *dev) { - return rfd77402_init(to_i2c_client(dev)); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct rfd77402_data *data = iio_priv(indio_dev); + + return rfd77402_init(data); } static DEFINE_SIMPLE_DEV_PM_OPS(rfd77402_pm_ops, rfd77402_suspend, @@ -313,10 +437,17 @@ static const struct i2c_device_id rfd77402_id[] = { }; MODULE_DEVICE_TABLE(i2c, rfd77402_id); +static const struct of_device_id rfd77402_of_match[] = { + { .compatible = "rfdigital,rfd77402" }, + { } +}; +MODULE_DEVICE_TABLE(of, rfd77402_of_match); + static struct i2c_driver rfd77402_driver = { .driver = { .name = RFD77402_DRV_NAME, .pm = pm_sleep_ptr(&rfd77402_pm_ops), + .of_match_table = rfd77402_of_match, }, .probe = rfd77402_probe, .id_table = rfd77402_id, diff --git a/drivers/iio/temperature/tmp006.c b/drivers/iio/temperature/tmp006.c index 10bd3f221929..d8d8c8936d17 100644 --- a/drivers/iio/temperature/tmp006.c +++ b/drivers/iio/temperature/tmp006.c @@ -356,12 +356,10 @@ static int tmp006_probe(struct i2c_client *client) indio_dev->trig = iio_trigger_get(data->drdy_trig); - ret = devm_request_threaded_irq(&client->dev, client->irq, - iio_trigger_generic_data_rdy_poll, - NULL, - IRQF_ONESHOT, - "tmp006_irq", - data->drdy_trig); + ret = devm_request_irq(&client->dev, client->irq, + iio_trigger_generic_data_rdy_poll, + IRQF_NO_THREAD, "tmp006_irq", + data->drdy_trig); if (ret < 0) return ret; } diff --git a/drivers/iio/test/Kconfig b/drivers/iio/test/Kconfig index 6e65e929791c..4fc17dd0dcd7 100644 --- a/drivers/iio/test/Kconfig +++ b/drivers/iio/test/Kconfig @@ -8,7 +8,6 @@ config IIO_GTS_KUNIT_TEST tristate "Test IIO gain-time-scale helpers" if !KUNIT_ALL_TESTS depends on KUNIT select IIO_GTS_HELPER - select TEST_KUNIT_DEVICE_HELPERS default KUNIT_ALL_TESTS help build unit tests for the IIO light sensor gain-time-scale helpers. diff --git a/drivers/iio/trigger/iio-trig-hrtimer.c b/drivers/iio/trigger/iio-trig-hrtimer.c index 82c72baccb62..57550b581593 100644 --- a/drivers/iio/trigger/iio-trig-hrtimer.c +++ b/drivers/iio/trigger/iio-trig-hrtimer.c @@ -131,7 +131,7 @@ static struct iio_sw_trigger *iio_trig_hrtimer_probe(const char *name) struct iio_hrtimer_info *trig_info; int ret; - trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + trig_info = kzalloc_obj(*trig_info); if (!trig_info) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/trigger/iio-trig-interrupt.c b/drivers/iio/trigger/iio-trig-interrupt.c index 21c6b6292a72..a100c2e3a0d9 100644 --- a/drivers/iio/trigger/iio-trig-interrupt.c +++ b/drivers/iio/trigger/iio-trig-interrupt.c @@ -48,7 +48,7 @@ static int iio_interrupt_trigger_probe(struct platform_device *pdev) goto error_ret; } - trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + trig_info = kzalloc_obj(*trig_info); if (!trig_info) { ret = -ENOMEM; goto error_free_trigger; diff --git a/drivers/iio/trigger/iio-trig-loop.c b/drivers/iio/trigger/iio-trig-loop.c index 7aaed0611899..580a465035d1 100644 --- a/drivers/iio/trigger/iio-trig-loop.c +++ b/drivers/iio/trigger/iio-trig-loop.c @@ -80,7 +80,7 @@ static struct iio_sw_trigger *iio_trig_loop_probe(const char *name) struct iio_loop_info *trig_info; int ret; - trig_info = kzalloc(sizeof(*trig_info), GFP_KERNEL); + trig_info = kzalloc_obj(*trig_info); if (!trig_info) return ERR_PTR(-ENOMEM); diff --git a/drivers/iio/trigger/iio-trig-sysfs.c b/drivers/iio/trigger/iio-trig-sysfs.c index 575d725696a9..b242b050ba18 100644 --- a/drivers/iio/trigger/iio-trig-sysfs.c +++ b/drivers/iio/trigger/iio-trig-sysfs.c @@ -140,7 +140,7 @@ static int iio_sysfs_trigger_probe(int id) ret = -EINVAL; goto err_unlock; } - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (t == NULL) { ret = -ENOMEM; goto err_unlock; diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 794b9778816b..78ac2ff5befd 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig @@ -6,6 +6,7 @@ menuconfig INFINIBAND depends on INET depends on m || IPV6 != m depends on !ALPHA + select DMA_SHARED_BUFFER select IRQ_POLL select DIMLIB help diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 35ba852a172a..866746695712 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -646,7 +646,7 @@ int rdma_resolve_ip(struct sockaddr *src_addr, const struct sockaddr *dst_addr, struct addr_req *req; int ret = 0; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index 25a060a28301..7847ede210bf 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c @@ -162,7 +162,7 @@ int ib_agent_port_open(struct ib_device *device, int port_num) int ret; /* Create new device info */ - port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); + port_priv = kzalloc_obj(*port_priv); if (!port_priv) { ret = -ENOMEM; goto error1; diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c index 0fc1c5bce2f0..ee4a2bc68fb2 100644 --- a/drivers/infiniband/core/cache.c +++ b/drivers/infiniband/core/cache.c @@ -296,14 +296,13 @@ alloc_gid_entry(const struct ib_gid_attr *attr) struct ib_gid_table_entry *entry; struct net_device *ndev; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; ndev = rcu_dereference_protected(attr->ndev, 1); if (ndev) { - entry->ndev_storage = kzalloc(sizeof(*entry->ndev_storage), - GFP_KERNEL); + entry->ndev_storage = kzalloc_obj(*entry->ndev_storage); if (!entry->ndev_storage) { kfree(entry); return NULL; @@ -771,12 +770,12 @@ const struct ib_gid_attr *rdma_find_gid_by_filter( static struct ib_gid_table *alloc_gid_table(int sz) { - struct ib_gid_table *table = kzalloc(sizeof(*table), GFP_KERNEL); + struct ib_gid_table *table = kzalloc_obj(*table); if (!table) return NULL; - table->data_vec = kcalloc(sz, sizeof(*table->data_vec), GFP_KERNEL); + table->data_vec = kzalloc_objs(*table->data_vec, sz); if (!table->data_vec) goto err_free_table; @@ -927,6 +926,13 @@ static int gid_table_setup_one(struct ib_device *ib_dev) if (err) return err; + /* + * Mark the device as ready for GID cache updates. This allows netdev + * event handlers to update the GID cache even before the device is + * fully registered. + */ + ib_device_enable_gid_updates(ib_dev); + rdma_roce_rescan_device(ib_dev); return err; @@ -1452,7 +1458,7 @@ ib_cache_update(struct ib_device *device, u32 port, bool update_gids, if (!rdma_is_port_valid(device, port)) return -EINVAL; - tprops = kmalloc(sizeof *tprops, GFP_KERNEL); + tprops = kmalloc_obj(*tprops); if (!tprops) return -ENOMEM; @@ -1472,9 +1478,8 @@ ib_cache_update(struct ib_device *device, u32 port, bool update_gids, update_pkeys &= !!tprops->pkey_tbl_len; if (update_pkeys) { - pkey_cache = kmalloc(struct_size(pkey_cache, table, - tprops->pkey_tbl_len), - GFP_KERNEL); + pkey_cache = kmalloc_flex(*pkey_cache, table, + tprops->pkey_tbl_len); if (!pkey_cache) { ret = -ENOMEM; goto err; @@ -1583,7 +1588,7 @@ void ib_dispatch_event(const struct ib_event *event) { struct ib_update_work *work; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return; @@ -1639,6 +1644,12 @@ void ib_cache_release_one(struct ib_device *device) void ib_cache_cleanup_one(struct ib_device *device) { + /* + * Clear the GID updates mark first to prevent event handlers from + * accessing the device while it's being torn down. + */ + ib_device_disable_gid_updates(device); + /* The cleanup function waits for all in-progress workqueue * elements and cleans up the GID cache. This function should be * called after the device was removed from the devices list and diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 024df6ee239d..6ab9a0aee1ec 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -827,7 +827,7 @@ static struct cm_id_private *cm_alloc_id_priv(struct ib_device *device, u32 id; int ret; - cm_id_priv = kzalloc(sizeof *cm_id_priv, GFP_KERNEL); + cm_id_priv = kzalloc_obj(*cm_id_priv); if (!cm_id_priv) return ERR_PTR(-ENOMEM); @@ -976,7 +976,7 @@ static struct cm_timewait_info *cm_create_timewait_info(__be32 local_id) { struct cm_timewait_info *timewait_info; - timewait_info = kzalloc(sizeof *timewait_info, GFP_KERNEL); + timewait_info = kzalloc_obj(*timewait_info); if (!timewait_info) return ERR_PTR(-ENOMEM); @@ -3902,7 +3902,7 @@ static int cm_establish(struct ib_cm_id *cm_id) if (!cm_dev) return -ENODEV; - work = kmalloc(sizeof *work, GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return -ENOMEM; @@ -4050,7 +4050,7 @@ static void cm_recv_handler(struct ib_mad_agent *mad_agent, attr_id = be16_to_cpu(mad_recv_wc->recv_buf.mad->mad_hdr.attr_id); atomic_long_inc(&port->counters[CM_RECV][attr_id - CM_ATTR_ID_OFFSET]); - work = kmalloc(struct_size(work, path, paths), GFP_KERNEL); + work = kmalloc_flex(*work, path, paths); if (!work) { ib_free_recv_mad(mad_recv_wc); return; @@ -4348,8 +4348,7 @@ static int cm_add_one(struct ib_device *ib_device) int count = 0; u32 i; - cm_dev = kzalloc(struct_size(cm_dev, port, ib_device->phys_port_cnt), - GFP_KERNEL); + cm_dev = kzalloc_flex(*cm_dev, port, ib_device->phys_port_cnt); if (!cm_dev) return -ENOMEM; @@ -4366,7 +4365,7 @@ static int cm_add_one(struct ib_device *ib_device) if (!rdma_cap_ib_cm(ib_device, i)) continue; - port = kzalloc(sizeof *port, GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) { ret = -ENOMEM; goto error1; diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index 0ee855a71ed4..9480d1a51c11 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -490,7 +490,7 @@ static int cma_add_id_to_tree(struct rdma_id_private *node_id_priv) unsigned long flags; int result; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOMEM; @@ -1013,7 +1013,7 @@ __rdma_create_id(struct net *net, rdma_cm_event_handler event_handler, { struct rdma_id_private *id_priv; - id_priv = kzalloc(sizeof *id_priv, GFP_KERNEL); + id_priv = kzalloc_obj(*id_priv); if (!id_priv) return ERR_PTR(-ENOMEM); @@ -2300,8 +2300,7 @@ cma_ib_new_conn_id(const struct rdma_cm_id *listen_id, rt = &id->route; rt->num_pri_alt_paths = ib_event->param.req_rcvd.alternate_path ? 2 : 1; - rt->path_rec = kmalloc_array(rt->num_pri_alt_paths, - sizeof(*rt->path_rec), GFP_KERNEL); + rt->path_rec = kmalloc_objs(*rt->path_rec, rt->num_pri_alt_paths); if (!rt->path_rec) goto err; @@ -2730,6 +2729,9 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv, *to_destroy = NULL; if (cma_family(id_priv) == AF_IB && !rdma_cap_ib_cm(cma_dev->device, 1)) return 0; + if (id_priv->restricted_node_type != RDMA_NODE_UNSPECIFIED && + id_priv->restricted_node_type != cma_dev->device->node_type) + return 0; dev_id_priv = __rdma_create_id(net, cma_listen_handler, id_priv, @@ -2737,6 +2739,7 @@ static int cma_listen_on_dev(struct rdma_id_private *id_priv, if (IS_ERR(dev_id_priv)) return PTR_ERR(dev_id_priv); + dev_id_priv->restricted_node_type = id_priv->restricted_node_type; dev_id_priv->state = RDMA_CM_ADDR_BOUND; memcpy(cma_src_addr(dev_id_priv), cma_src_addr(id_priv), rdma_addr_size(cma_src_addr(id_priv))); @@ -2880,8 +2883,7 @@ static int route_set_path_rec_inbound(struct cma_work *work, struct rdma_route *route = &work->id->id.route; if (!route->path_rec_inbound) { - route->path_rec_inbound = - kzalloc(sizeof(*route->path_rec_inbound), GFP_KERNEL); + route->path_rec_inbound = kzalloc_obj(*route->path_rec_inbound); if (!route->path_rec_inbound) return -ENOMEM; } @@ -2896,8 +2898,7 @@ static int route_set_path_rec_outbound(struct cma_work *work, struct rdma_route *route = &work->id->id.route; if (!route->path_rec_outbound) { - route->path_rec_outbound = - kzalloc(sizeof(*route->path_rec_outbound), GFP_KERNEL); + route->path_rec_outbound = kzalloc_obj(*route->path_rec_outbound); if (!route->path_rec_outbound) return -ENOMEM; } @@ -3083,14 +3084,14 @@ static int cma_resolve_ib_route(struct rdma_id_private *id_priv, struct cma_work *work; int ret; - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; cma_init_resolve_route_work(work, id_priv); if (!route->path_rec) - route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL); + route->path_rec = kmalloc_obj(*route->path_rec); if (!route->path_rec) { ret = -ENOMEM; goto err1; @@ -3204,7 +3205,7 @@ static int cma_resolve_iw_route(struct rdma_id_private *id_priv) { struct cma_work *work; - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; @@ -3311,11 +3312,11 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) tos = id_priv->tos_set ? id_priv->tos : default_roce_tos; mutex_unlock(&id_priv->qp_mutex); - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; - route->path_rec = kzalloc(sizeof *route->path_rec, GFP_KERNEL); + route->path_rec = kzalloc_obj(*route->path_rec); if (!route->path_rec) { ret = -ENOMEM; goto err1; @@ -3560,7 +3561,7 @@ static int cma_resolve_loopback(struct rdma_id_private *id_priv) union ib_gid gid; int ret; - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; @@ -3585,7 +3586,7 @@ static int cma_resolve_ib_addr(struct rdma_id_private *id_priv) struct cma_work *work; int ret; - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; @@ -3685,7 +3686,7 @@ static int cma_alloc_port(enum rdma_ucm_port_space ps, lockdep_assert_held(&lock); - bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); + bind_list = kzalloc_obj(*bind_list); if (!bind_list) return -ENOMEM; @@ -4197,7 +4198,7 @@ int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type) } mutex_lock(&lock); - if (id_priv->cma_dev) + if (READ_ONCE(id_priv->state) != RDMA_CM_IDLE) ret = -EALREADY; else id_priv->restricted_node_type = node_type; @@ -5100,7 +5101,7 @@ int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr, if (id_priv->id.qp_type != IB_QPT_UD) return -EINVAL; - mc = kzalloc(sizeof(*mc), GFP_KERNEL); + mc = kzalloc_obj(*mc); if (!mc) return -ENOMEM; @@ -5166,7 +5167,7 @@ static int cma_netdev_change(struct net_device *ndev, struct rdma_id_private *id memcmp(dev_addr->src_dev_addr, ndev->dev_addr, ndev->addr_len)) { pr_info("RDMA CM addr change for ndev %s used by id %p\n", ndev->name, &id_priv->id); - work = kzalloc(sizeof *work, GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; @@ -5373,14 +5374,13 @@ static int cma_add_one(struct ib_device *device) if (!cma_supported(device)) return -EOPNOTSUPP; - cma_dev = kmalloc(sizeof(*cma_dev), GFP_KERNEL); + cma_dev = kmalloc_obj(*cma_dev); if (!cma_dev) return -ENOMEM; cma_dev->device = device; - cma_dev->default_gid_type = kcalloc(device->phys_port_cnt, - sizeof(*cma_dev->default_gid_type), - GFP_KERNEL); + cma_dev->default_gid_type = kzalloc_objs(*cma_dev->default_gid_type, + device->phys_port_cnt); if (!cma_dev->default_gid_type) { ret = -ENOMEM; goto free_cma_dev; @@ -5570,7 +5570,7 @@ static void cma_query_ib_service_handler(int status, } id_priv->id.route.service_recs = - kmalloc_array(num_recs, sizeof(*recs), GFP_KERNEL); + kmalloc_objs(*recs, num_recs); if (!id_priv->id.route.service_recs) { status = -ENOMEM; goto fail; @@ -5610,7 +5610,7 @@ static int cma_resolve_ib_service(struct rdma_id_private *id_priv, ib_sa_comp_mask mask = 0; struct cma_work *work; - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; diff --git a/drivers/infiniband/core/cma_configfs.c b/drivers/infiniband/core/cma_configfs.c index f2fb2d8a6597..819927ce4f0e 100644 --- a/drivers/infiniband/core/cma_configfs.c +++ b/drivers/infiniband/core/cma_configfs.c @@ -210,8 +210,7 @@ static int make_cma_ports(struct cma_dev_group *cma_dev_group, return -ENODEV; ports_num = ibdev->phys_port_cnt; - ports = kcalloc(ports_num, sizeof(*cma_dev_group->ports), - GFP_KERNEL); + ports = kzalloc_objs(*cma_dev_group->ports, ports_num); if (!ports) return -ENOMEM; @@ -285,7 +284,7 @@ static struct config_group *make_cma_dev(struct config_group *group, if (!cma_dev) goto fail; - cma_dev_group = kzalloc(sizeof(*cma_dev_group), GFP_KERNEL); + cma_dev_group = kzalloc_obj(*cma_dev_group); if (!cma_dev_group) { err = -ENOMEM; diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 05102769a918..a2c36666e6fc 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -100,6 +100,9 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter, roce_netdev_callback cb, void *cookie); +void ib_device_enable_gid_updates(struct ib_device *device); +void ib_device_disable_gid_updates(struct ib_device *device); + typedef int (*nldev_callback)(struct ib_device *device, struct sk_buff *skb, struct netlink_callback *cb, diff --git a/drivers/infiniband/core/cq.c b/drivers/infiniband/core/cq.c index 584537c71545..81316228f614 100644 --- a/drivers/infiniband/core/cq.c +++ b/drivers/infiniband/core/cq.c @@ -58,7 +58,7 @@ static void rdma_dim_init(struct ib_cq *cq) cq->poll_ctx == IB_POLL_DIRECT) return; - dim = kzalloc(sizeof(struct dim), GFP_KERNEL); + dim = kzalloc_obj(struct dim); if (!dim) return; @@ -230,7 +230,7 @@ struct ib_cq *__ib_alloc_cq(struct ib_device *dev, void *private, int nr_cqe, atomic_set(&cq->usecnt, 0); cq->comp_vector = comp_vector; - cq->wc = kmalloc_array(IB_POLL_BATCH, sizeof(*cq->wc), GFP_KERNEL); + cq->wc = kmalloc_objs(*cq->wc, IB_POLL_BATCH); if (!cq->wc) goto out_free_cq; diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 2f2081e75bce..558b73940d66 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -93,6 +93,7 @@ static struct workqueue_struct *ib_unreg_wq; static DEFINE_XARRAY_FLAGS(devices, XA_FLAGS_ALLOC); static DECLARE_RWSEM(devices_rwsem); #define DEVICE_REGISTERED XA_MARK_1 +#define DEVICE_GID_UPDATES XA_MARK_2 static u32 highest_client_id; #define CLIENT_REGISTERED XA_MARK_1 @@ -811,9 +812,8 @@ static int alloc_port_data(struct ib_device *device) * Therefore port_data is declared as a 1 based array with potential * empty slots at the beginning. */ - pdata_rcu = kzalloc(struct_size(pdata_rcu, pdata, - size_add(rdma_end_port(device), 1)), - GFP_KERNEL); + pdata_rcu = kzalloc_flex(*pdata_rcu, pdata, + size_add(rdma_end_port(device), 1)); if (!pdata_rcu) return -ENOMEM; /* @@ -958,7 +958,7 @@ static int add_one_compat_dev(struct ib_device *device, if (ret) goto done; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) { ret = -ENOMEM; goto cdev_err; @@ -2413,11 +2413,42 @@ void ib_enum_all_roce_netdevs(roce_netdev_filter filter, unsigned long index; down_read(&devices_rwsem); - xa_for_each_marked (&devices, index, dev, DEVICE_REGISTERED) + xa_for_each_marked(&devices, index, dev, DEVICE_GID_UPDATES) ib_enum_roce_netdev(dev, filter, filter_cookie, cb, cookie); up_read(&devices_rwsem); } +/** + * ib_device_enable_gid_updates - Mark device as ready for GID cache updates + * @device: Device to mark + * + * Called after GID table is allocated and initialized. After this mark is set, + * netdevice event handlers can update the device's GID cache. This allows + * events that arrive during device registration to be processed, avoiding + * stale GID entries when netdev properties change during the device + * registration process. + */ +void ib_device_enable_gid_updates(struct ib_device *device) +{ + down_write(&devices_rwsem); + xa_set_mark(&devices, device->index, DEVICE_GID_UPDATES); + up_write(&devices_rwsem); +} + +/** + * ib_device_disable_gid_updates - Clear the GID updates mark + * @device: Device to unmark + * + * Called before GID table cleanup to prevent event handlers from accessing + * the device while it's being torn down. + */ +void ib_device_disable_gid_updates(struct ib_device *device) +{ + down_write(&devices_rwsem); + xa_clear_mark(&devices, device->index, DEVICE_GID_UPDATES); + up_write(&devices_rwsem); +} + /* * ib_enum_all_devs - enumerate all ib_devices * @cb: Callback to call for each found ib_device diff --git a/drivers/infiniband/core/ib_core_uverbs.c b/drivers/infiniband/core/ib_core_uverbs.c index 1de72ff4610c..d3836a62a004 100644 --- a/drivers/infiniband/core/ib_core_uverbs.c +++ b/drivers/infiniband/core/ib_core_uverbs.c @@ -87,7 +87,7 @@ int rdma_user_mmap_io(struct ib_ucontext *ucontext, struct vm_area_struct *vma, return -EINVAL; lockdep_assert_held(&ufile->device->disassociate_srcu); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index eb942ab9c405..9761d9365ffd 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -171,7 +171,7 @@ static int alloc_work_entries(struct iwcm_id_private *cm_id_priv, int count) BUG_ON(!list_empty(&cm_id_priv->work_free_list)); while (count--) { - work = kmalloc(sizeof(struct iwcm_work), GFP_KERNEL); + work = kmalloc_obj(struct iwcm_work); if (!work) { dealloc_work_entries(cm_id_priv); return -ENOMEM; @@ -242,7 +242,7 @@ struct iw_cm_id *iw_create_cm_id(struct ib_device *device, { struct iwcm_id_private *cm_id_priv; - cm_id_priv = kzalloc(sizeof(*cm_id_priv), GFP_KERNEL); + cm_id_priv = kzalloc_obj(*cm_id_priv); if (!cm_id_priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/core/iwpm_msg.c b/drivers/infiniband/core/iwpm_msg.c index 3c9a9869212b..69c85249b465 100644 --- a/drivers/infiniband/core/iwpm_msg.c +++ b/drivers/infiniband/core/iwpm_msg.c @@ -649,7 +649,7 @@ int iwpm_remote_info_cb(struct sk_buff *skb, struct netlink_callback *cb) __func__); return ret; } - rem_info = kzalloc(sizeof(struct iwpm_remote_info), GFP_ATOMIC); + rem_info = kzalloc_obj(struct iwpm_remote_info, GFP_ATOMIC); if (!rem_info) { ret = -ENOMEM; return ret; diff --git a/drivers/infiniband/core/iwpm_util.c b/drivers/infiniband/core/iwpm_util.c index eecb369898f5..990cf928b32a 100644 --- a/drivers/infiniband/core/iwpm_util.c +++ b/drivers/infiniband/core/iwpm_util.c @@ -58,13 +58,13 @@ static struct iwpm_admin_data iwpm_admin; */ int iwpm_init(u8 nl_client) { - iwpm_hash_bucket = kcalloc(IWPM_MAPINFO_HASH_SIZE, - sizeof(struct hlist_head), GFP_KERNEL); + iwpm_hash_bucket = kzalloc_objs(struct hlist_head, + IWPM_MAPINFO_HASH_SIZE); if (!iwpm_hash_bucket) return -ENOMEM; - iwpm_reminfo_bucket = kcalloc(IWPM_REMINFO_HASH_SIZE, - sizeof(struct hlist_head), GFP_KERNEL); + iwpm_reminfo_bucket = kzalloc_objs(struct hlist_head, + IWPM_REMINFO_HASH_SIZE); if (!iwpm_reminfo_bucket) { kfree(iwpm_hash_bucket); return -ENOMEM; @@ -113,7 +113,7 @@ int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr, unsigned long flags; int ret = -EINVAL; - map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL); + map_info = kzalloc_obj(struct iwpm_mapping_info); if (!map_info) return -ENOMEM; @@ -310,7 +310,7 @@ struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq, struct iwpm_nlmsg_request *nlmsg_request; unsigned long flags; - nlmsg_request = kzalloc(sizeof(struct iwpm_nlmsg_request), gfp); + nlmsg_request = kzalloc_obj(struct iwpm_nlmsg_request, gfp); if (!nlmsg_request) return NULL; diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 8f26bfb69586..8d19613179e3 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -386,7 +386,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, } /* Allocate structures */ - mad_agent_priv = kzalloc(sizeof *mad_agent_priv, GFP_KERNEL); + mad_agent_priv = kzalloc_obj(*mad_agent_priv); if (!mad_agent_priv) { ret = ERR_PTR(-ENOMEM); goto error1; @@ -698,7 +698,7 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv, goto out; } - local = kmalloc(sizeof *local, GFP_ATOMIC); + local = kmalloc_obj(*local, GFP_ATOMIC); if (!local) { ret = -ENOMEM; goto out; @@ -1400,7 +1400,7 @@ static int method_in_use(struct ib_mad_mgmt_method_table **method, static int allocate_method_table(struct ib_mad_mgmt_method_table **method) { /* Allocate management method table */ - *method = kzalloc(sizeof **method, GFP_ATOMIC); + *method = kzalloc_obj(**method, GFP_ATOMIC); return (*method) ? 0 : (-ENOMEM); } @@ -1488,7 +1488,7 @@ static int add_nonoui_reg_req(struct ib_mad_reg_req *mad_reg_req, class = &port_priv->version[mad_reg_req->mgmt_class_version].class; if (!*class) { /* Allocate management class table for "new" class version */ - *class = kzalloc(sizeof **class, GFP_ATOMIC); + *class = kzalloc_obj(**class, GFP_ATOMIC); if (!*class) { ret = -ENOMEM; goto error1; @@ -1553,7 +1553,7 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, mad_reg_req->mgmt_class_version].vendor; if (!*vendor_table) { /* Allocate mgmt vendor class table for "new" class version */ - vendor = kzalloc(sizeof *vendor, GFP_ATOMIC); + vendor = kzalloc_obj(*vendor, GFP_ATOMIC); if (!vendor) goto error1; @@ -1561,7 +1561,7 @@ static int add_oui_reg_req(struct ib_mad_reg_req *mad_reg_req, } if (!(*vendor_table)->vendor_class[vclass]) { /* Allocate table for this management vendor class */ - vendor_class = kzalloc(sizeof *vendor_class, GFP_ATOMIC); + vendor_class = kzalloc_obj(*vendor_class, GFP_ATOMIC); if (!vendor_class) goto error2; @@ -2612,7 +2612,7 @@ static bool ib_mad_send_error(struct ib_mad_port_private *port_priv, struct ib_qp_attr *attr; /* Transition QP to RTS and fail offending send */ - attr = kmalloc(sizeof *attr, GFP_KERNEL); + attr = kmalloc_obj(*attr); if (attr) { attr->qp_state = IB_QPS_RTS; attr->cur_qp_state = IB_QPS_SQE; @@ -3042,7 +3042,7 @@ static int ib_mad_port_start(struct ib_mad_port_private *port_priv) struct ib_qp *qp; u16 pkey_index; - attr = kmalloc(sizeof *attr, GFP_KERNEL); + attr = kmalloc_obj(*attr); if (!attr) return -ENOMEM; @@ -3207,7 +3207,7 @@ static int ib_mad_port_open(struct ib_device *device, return -EFAULT; /* Create new device info */ - port_priv = kzalloc(sizeof *port_priv, GFP_KERNEL); + port_priv = kzalloc_obj(*port_priv); if (!port_priv) return -ENOMEM; diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 1c5e0eaf1c94..17c4c52a19e4 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -279,7 +279,7 @@ create_rmpp_recv(struct ib_mad_agent_private *agent, struct mad_rmpp_recv *rmpp_recv; struct ib_mad_hdr *mad_hdr; - rmpp_recv = kmalloc(sizeof *rmpp_recv, GFP_KERNEL); + rmpp_recv = kmalloc_obj(*rmpp_recv); if (!rmpp_recv) return NULL; diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index a236532a9026..bea7df3dd8f3 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -570,7 +570,7 @@ static struct mcast_group *acquire_group(struct mcast_port *port, spin_unlock_irqrestore(&port->lock, flags); } - group = kzalloc(sizeof *group, gfp_mask); + group = kzalloc_obj(*group, gfp_mask); if (!group) return NULL; @@ -621,7 +621,7 @@ ib_sa_join_multicast(struct ib_sa_client *client, if (!dev) return ERR_PTR(-ENODEV); - member = kmalloc(sizeof *member, gfp_mask); + member = kmalloc_obj(*member, gfp_mask); if (!member) return ERR_PTR(-ENOMEM); @@ -823,8 +823,7 @@ static int mcast_add_one(struct ib_device *device) int i; int count = 0; - dev = kmalloc(struct_size(dev, port, device->phys_port_cnt), - GFP_KERNEL); + dev = kmalloc_flex(*dev, port, device->phys_port_cnt); if (!dev) return -ENOMEM; diff --git a/drivers/infiniband/core/restrack.c b/drivers/infiniband/core/restrack.c index b097cfcade1c..ac3688952cab 100644 --- a/drivers/infiniband/core/restrack.c +++ b/drivers/infiniband/core/restrack.c @@ -25,7 +25,7 @@ int rdma_restrack_init(struct ib_device *dev) struct rdma_restrack_root *rt; int i; - dev->res = kcalloc(RDMA_RESTRACK_MAX, sizeof(*rt), GFP_KERNEL); + dev->res = kzalloc_objs(*rt, RDMA_RESTRACK_MAX); if (!dev->res) return -ENOMEM; diff --git a/drivers/infiniband/core/roce_gid_mgmt.c b/drivers/infiniband/core/roce_gid_mgmt.c index a9f2c6b1b29e..4a2a4638b476 100644 --- a/drivers/infiniband/core/roce_gid_mgmt.c +++ b/drivers/infiniband/core/roce_gid_mgmt.c @@ -352,7 +352,7 @@ static void enum_netdev_ipv4_ips(struct ib_device *ib_dev, } in_dev_for_each_ifa_rcu(ifa, in_dev) { - struct sin_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + struct sin_list *entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) continue; @@ -395,7 +395,7 @@ static void enum_netdev_ipv6_ips(struct ib_device *ib_dev, read_lock_bh(&in6_dev->lock); list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { - struct sin6_list *entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + struct sin6_list *entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) continue; @@ -556,7 +556,7 @@ struct upper_list { static int netdev_upper_walk(struct net_device *upper, struct netdev_nested_priv *priv) { - struct upper_list *entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + struct upper_list *entry = kmalloc_obj(*entry, GFP_ATOMIC); struct list_head *upper_list = (struct list_head *)priv->data; if (!entry) @@ -660,8 +660,7 @@ static int netdevice_queue_work(struct netdev_event_work_cmd *cmds, struct net_device *ndev) { unsigned int i; - struct netdev_event_work *ndev_work = - kmalloc(sizeof(*ndev_work), GFP_KERNEL); + struct netdev_event_work *ndev_work = kmalloc_obj(*ndev_work); if (!ndev_work) return NOTIFY_DONE; @@ -858,7 +857,7 @@ static int addr_event(struct notifier_block *this, unsigned long event, return NOTIFY_DONE; } - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; diff --git a/drivers/infiniband/core/rw.c b/drivers/infiniband/core/rw.c index 518095d82d5d..fc45c384833f 100644 --- a/drivers/infiniband/core/rw.c +++ b/drivers/infiniband/core/rw.c @@ -162,7 +162,7 @@ static int rdma_rw_init_mr_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp, int i, j, ret = 0, count = 0; ctx->nr_ops = DIV_ROUND_UP(sg_cnt, pages_per_mr); - ctx->reg = kcalloc(ctx->nr_ops, sizeof(*ctx->reg), GFP_KERNEL); + ctx->reg = kzalloc_objs(*ctx->reg, ctx->nr_ops); if (!ctx->reg) { ret = -ENOMEM; goto out; @@ -213,8 +213,7 @@ static int rdma_rw_init_mr_wrs_bvec(struct rdma_rw_ctx *ctx, struct ib_qp *qp, int i, ret, count = 0; u32 nents = 0; - ctx->reg = kcalloc(DIV_ROUND_UP(nr_bvec, pages_per_mr), - sizeof(*ctx->reg), GFP_KERNEL); + ctx->reg = kzalloc_objs(*ctx->reg, DIV_ROUND_UP(nr_bvec, pages_per_mr)); if (!ctx->reg) return -ENOMEM; @@ -222,9 +221,7 @@ static int rdma_rw_init_mr_wrs_bvec(struct rdma_rw_ctx *ctx, struct ib_qp *qp, * Build scatterlist from bvecs using the iterator. This follows * the pattern from __blk_rq_map_sg. */ - ctx->reg[0].sgt.sgl = kmalloc_array(nr_bvec, - sizeof(*ctx->reg[0].sgt.sgl), - GFP_KERNEL); + ctx->reg[0].sgt.sgl = kmalloc_objs(*ctx->reg[0].sgt.sgl, nr_bvec); if (!ctx->reg[0].sgt.sgl) { ret = -ENOMEM; goto out_free_reg; @@ -298,11 +295,11 @@ static int rdma_rw_init_map_wrs(struct rdma_rw_ctx *ctx, struct ib_qp *qp, ctx->nr_ops = DIV_ROUND_UP(sg_cnt, max_sge); - ctx->map.sges = sge = kcalloc(sg_cnt, sizeof(*sge), GFP_KERNEL); + ctx->map.sges = sge = kzalloc_objs(*sge, sg_cnt); if (!ctx->map.sges) goto out; - ctx->map.wrs = kcalloc(ctx->nr_ops, sizeof(*ctx->map.wrs), GFP_KERNEL); + ctx->map.wrs = kzalloc_objs(*ctx->map.wrs, ctx->nr_ops); if (!ctx->map.wrs) goto out_free_sges; @@ -757,7 +754,7 @@ int rdma_rw_ctx_signature_init(struct rdma_rw_ctx *ctx, struct ib_qp *qp, ctx->type = RDMA_RW_SIG_MR; ctx->nr_ops = 1; - ctx->reg = kzalloc(sizeof(*ctx->reg), GFP_KERNEL); + ctx->reg = kzalloc_obj(*ctx->reg); if (!ctx->reg) { ret = -ENOMEM; goto out_unmap_prot_sg; diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index c23e9c847314..c6c295f5b783 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -1607,7 +1607,7 @@ static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query, int status, return; } - rec = kmalloc_array(num_services, sizeof(*rec), GFP_KERNEL); + rec = kmalloc_objs(*rec, num_services); if (!rec) { query->callback(-ENOMEM, NULL, 0, query->context); return; @@ -1689,7 +1689,7 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, port = &sa_dev->port[port_num - sa_dev->start_port]; agent = port->agent; - query = kzalloc(sizeof(*query), gfp_mask); + query = kzalloc_obj(*query, gfp_mask); if (!query) return -ENOMEM; @@ -1702,8 +1702,7 @@ int ib_sa_path_rec_get(struct ib_sa_client *client, } else if (status == PR_OPA_SUPPORTED) { query->sa_query.flags |= IB_SA_QUERY_OPA; } else { - query->conv_pr = - kmalloc(sizeof(*query->conv_pr), gfp_mask); + query->conv_pr = kmalloc_obj(*query->conv_pr, gfp_mask); if (!query->conv_pr) { ret = -ENOMEM; goto err1; @@ -1814,7 +1813,7 @@ int ib_sa_service_rec_get(struct ib_sa_client *client, port = &sa_dev->port[port_num - sa_dev->start_port]; agent = port->agent; - query = kzalloc(sizeof(*query), gfp_mask); + query = kzalloc_obj(*query, gfp_mask); if (!query) return -ENOMEM; @@ -1906,7 +1905,7 @@ int ib_sa_mcmember_rec_query(struct ib_sa_client *client, port = &sa_dev->port[port_num - sa_dev->start_port]; agent = port->agent; - query = kzalloc(sizeof(*query), gfp_mask); + query = kzalloc_obj(*query, gfp_mask); if (!query) return -ENOMEM; @@ -2002,7 +2001,7 @@ int ib_sa_guid_info_rec_query(struct ib_sa_client *client, port = &sa_dev->port[port_num - sa_dev->start_port]; agent = port->agent; - query = kzalloc(sizeof(*query), gfp_mask); + query = kzalloc_obj(*query, gfp_mask); if (!query) return -ENOMEM; @@ -2131,7 +2130,7 @@ static int ib_sa_classport_info_rec_query(struct ib_sa_port *port, agent = port->agent; - query = kzalloc(sizeof(*query), gfp_mask); + query = kzalloc_obj(*query, gfp_mask); if (!query) return -ENOMEM; @@ -2189,7 +2188,7 @@ static void update_ib_cpi(struct work_struct *work) } spin_unlock_irqrestore(&port->classport_lock, flags); - cb_context = kmalloc(sizeof(*cb_context), GFP_KERNEL); + cb_context = kmalloc_obj(*cb_context); if (!cb_context) goto err_nomem; @@ -2307,7 +2306,7 @@ static void update_sm_ah(struct work_struct *work) return; } - new_ah = kmalloc(sizeof(*new_ah), GFP_KERNEL); + new_ah = kmalloc_obj(*new_ah); if (!new_ah) return; @@ -2415,9 +2414,7 @@ static int ib_sa_add_one(struct ib_device *device) s = rdma_start_port(device); e = rdma_end_port(device); - sa_dev = kzalloc(struct_size(sa_dev, port, - size_add(size_sub(e, s), 1)), - GFP_KERNEL); + sa_dev = kzalloc_flex(*sa_dev, port, size_add(size_sub(e, s), 1)); if (!sa_dev) return -ENOMEM; diff --git a/drivers/infiniband/core/security.c b/drivers/infiniband/core/security.c index 3512c2e54efc..9af31d1d9d70 100644 --- a/drivers/infiniband/core/security.c +++ b/drivers/infiniband/core/security.c @@ -258,7 +258,7 @@ static int port_pkey_list_insert(struct ib_port_pkey *pp) if (!pkey) { bool found = false; - pkey = kzalloc(sizeof(*pkey), GFP_KERNEL); + pkey = kzalloc_obj(*pkey); if (!pkey) return -ENOMEM; @@ -335,7 +335,7 @@ static struct ib_ports_pkeys *get_new_pps(const struct ib_qp *qp, struct ib_ports_pkeys *new_pps; struct ib_ports_pkeys *qp_pps = qp->qp_sec->ports_pkeys; - new_pps = kzalloc(sizeof(*new_pps), GFP_KERNEL); + new_pps = kzalloc_obj(*new_pps); if (!new_pps) return NULL; @@ -428,7 +428,7 @@ int ib_create_qp_security(struct ib_qp *qp, struct ib_device *dev) if (!is_ib) return 0; - qp->qp_sec = kzalloc(sizeof(*qp->qp_sec), GFP_KERNEL); + qp->qp_sec = kzalloc_obj(*qp->qp_sec); if (!qp->qp_sec) return -ENOMEM; diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c index bfaca07933d8..69df8b703cbd 100644 --- a/drivers/infiniband/core/sysfs.c +++ b/drivers/infiniband/core/sysfs.c @@ -515,8 +515,8 @@ static int get_perf_mad(struct ib_device *dev, int port_num, __be16 attr, if (!dev->ops.process_mad) return -ENOSYS; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kzalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kzalloc_obj(*out_mad); if (!in_mad || !out_mad) { ret = -ENOMEM; goto out; @@ -855,12 +855,11 @@ alloc_hw_stats_device(struct ib_device *ibdev) * Two extra attribue elements here, one for the lifespan entry and * one to NULL terminate the list for the sysfs core code */ - data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), - GFP_KERNEL); + data = kzalloc_flex(*data, attrs, size_add(stats->num_counters, 1)); if (!data) goto err_free_stats; - data->group.attrs = kcalloc(stats->num_counters + 2, - sizeof(*data->group.attrs), GFP_KERNEL); + data->group.attrs = kzalloc_objs(*data->group.attrs, + stats->num_counters + 2); if (!data->group.attrs) goto err_free_data; @@ -962,12 +961,10 @@ alloc_hw_stats_port(struct ib_port *port, struct attribute_group *group) * Two extra attribue elements here, one for the lifespan entry and * one to NULL terminate the list for the sysfs core code */ - data = kzalloc(struct_size(data, attrs, size_add(stats->num_counters, 1)), - GFP_KERNEL); + data = kzalloc_flex(*data, attrs, size_add(stats->num_counters, 1)); if (!data) goto err_free_stats; - group->attrs = kcalloc(stats->num_counters + 2, - sizeof(*group->attrs), GFP_KERNEL); + group->attrs = kzalloc_objs(*group->attrs, stats->num_counters + 2); if (!group->attrs) goto err_free_data; @@ -1054,7 +1051,7 @@ alloc_port_table_group(const char *name, struct attribute_group *group, struct attribute **attr_list; int i; - attr_list = kcalloc(num + 1, sizeof(*attr_list), GFP_KERNEL); + attr_list = kzalloc_objs(*attr_list, num + 1); if (!attr_list) return -ENOMEM; @@ -1092,9 +1089,8 @@ static int setup_gid_attrs(struct ib_port *port, struct gid_attr_group *gid_attr_group; int ret; - gid_attr_group = kzalloc(struct_size(gid_attr_group, attrs_list, - size_mul(attr->gid_tbl_len, 2)), - GFP_KERNEL); + gid_attr_group = kzalloc_flex(*gid_attr_group, attrs_list, + size_mul(attr->gid_tbl_len, 2)); if (!gid_attr_group) return -ENOMEM; gid_attr_group->port = port; @@ -1157,9 +1153,8 @@ static struct ib_port *setup_port(struct ib_core_device *coredev, int port_num, struct ib_port *p; int ret; - p = kvzalloc(struct_size(p, attrs_list, - size_add(attr->gid_tbl_len, attr->pkey_tbl_len)), - GFP_KERNEL); + p = kvzalloc_flex(*p, attrs_list, + size_add(attr->gid_tbl_len, attr->pkey_tbl_len)); if (!p) return ERR_PTR(-ENOMEM); p->ibdev = device; diff --git a/drivers/infiniband/core/ucaps.c b/drivers/infiniband/core/ucaps.c index de5cb8bf0a61..948093260dbd 100644 --- a/drivers/infiniband/core/ucaps.c +++ b/drivers/infiniband/core/ucaps.c @@ -160,7 +160,7 @@ int ib_create_ucap(enum rdma_user_cap type) return 0; } - ucap = kzalloc(sizeof(*ucap), GFP_KERNEL); + ucap = kzalloc_obj(*ucap); if (!ucap) { ret = -ENOMEM; goto unlock; diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index ec3be65a2b88..878561fa1cb5 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -195,7 +195,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file) { struct ucma_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -262,7 +262,7 @@ static struct ucma_event *ucma_create_uevent(struct ucma_context *ctx, { struct ucma_event *uevent; - uevent = kzalloc(sizeof(*uevent), GFP_KERNEL); + uevent = kzalloc_obj(*uevent); if (!uevent) return NULL; @@ -1529,7 +1529,7 @@ static ssize_t ucma_process_join(struct ucma_file *file, if (IS_ERR(ctx)) return PTR_ERR(ctx); - mc = kzalloc(sizeof(*mc), GFP_KERNEL); + mc = kzalloc_obj(*mc); if (!mc) { ret = -ENOMEM; goto err_put_ctx; @@ -1770,7 +1770,7 @@ static ssize_t ucma_write_cm_event(struct ucma_file *file, event.status = cmd.status; event.param.arg = cmd.param.arg; - uevent = kzalloc(sizeof(*uevent), GFP_KERNEL); + uevent = kzalloc_obj(*uevent); if (!uevent) { ret = -ENOMEM; goto out; @@ -1885,7 +1885,7 @@ static int ucma_open(struct inode *inode, struct file *filp) { struct ucma_file *file; - file = kmalloc(sizeof *file, GFP_KERNEL); + file = kmalloc_obj(*file); if (!file) return -ENOMEM; diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 8137031c2a65..cff4fcca2c34 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -189,7 +189,7 @@ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr, if (access & IB_ACCESS_ON_DEMAND) return ERR_PTR(-EOPNOTSUPP); - umem = kzalloc(sizeof(*umem), GFP_KERNEL); + umem = kzalloc_obj(*umem); if (!umem) return ERR_PTR(-ENOMEM); umem->ibdev = device; diff --git a/drivers/infiniband/core/umem_dmabuf.c b/drivers/infiniband/core/umem_dmabuf.c index 939da49b0dcc..d30f24b90bca 100644 --- a/drivers/infiniband/core/umem_dmabuf.c +++ b/drivers/infiniband/core/umem_dmabuf.c @@ -136,7 +136,7 @@ ib_umem_dmabuf_get_with_dma_device(struct ib_device *device, if (dmabuf->size < end) goto out_release_dmabuf; - umem_dmabuf = kzalloc(sizeof(*umem_dmabuf), GFP_KERNEL); + umem_dmabuf = kzalloc_obj(*umem_dmabuf); if (!umem_dmabuf) { ret = ERR_PTR(-ENOMEM); goto out_release_dmabuf; @@ -218,13 +218,11 @@ ib_umem_dmabuf_get_pinned_with_dma_device(struct ib_device *device, err = ib_umem_dmabuf_map_pages(umem_dmabuf); if (err) - goto err_unpin; + goto err_release; dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); return umem_dmabuf; -err_unpin: - dma_buf_unpin(umem_dmabuf->attach); err_release: dma_resv_unlock(umem_dmabuf->attach->dmabuf->resv); ib_umem_release(&umem_dmabuf->umem); diff --git a/drivers/infiniband/core/umem_odp.c b/drivers/infiniband/core/umem_odp.c index 32267258a19c..404fa1cc3254 100644 --- a/drivers/infiniband/core/umem_odp.c +++ b/drivers/infiniband/core/umem_odp.c @@ -140,7 +140,7 @@ struct ib_umem_odp *ib_umem_odp_alloc_implicit(struct ib_device *device, if (access & IB_ACCESS_HUGETLB) return ERR_PTR(-EINVAL); - umem_odp = kzalloc(sizeof(*umem_odp), GFP_KERNEL); + umem_odp = kzalloc_obj(*umem_odp); if (!umem_odp) return ERR_PTR(-ENOMEM); umem = &umem_odp->umem; @@ -181,7 +181,7 @@ ib_umem_odp_alloc_child(struct ib_umem_odp *root, unsigned long addr, if (WARN_ON(!root->is_implicit_odp)) return ERR_PTR(-EINVAL); - odp_data = kzalloc(sizeof(*odp_data), GFP_KERNEL); + odp_data = kzalloc_obj(*odp_data); if (!odp_data) return ERR_PTR(-ENOMEM); umem = &odp_data->umem; @@ -241,7 +241,7 @@ struct ib_umem_odp *ib_umem_odp_get(struct ib_device *device, if (WARN_ON_ONCE(!(access & IB_ACCESS_ON_DEMAND))) return ERR_PTR(-EINVAL); - umem_odp = kzalloc(sizeof(struct ib_umem_odp), GFP_KERNEL); + umem_odp = kzalloc_obj(struct ib_umem_odp); if (!umem_odp) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 2f7e3c4483fc..c3ef9f85c7eb 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -247,7 +247,7 @@ static void recv_handler(struct ib_mad_agent *agent, if (mad_recv_wc->wc->status != IB_WC_SUCCESS) goto err1; - packet = kzalloc(sizeof *packet, GFP_KERNEL); + packet = kzalloc_obj(*packet); if (!packet) goto err1; @@ -1018,7 +1018,7 @@ static int ib_umad_open(struct inode *inode, struct file *filp) goto out; } - file = kzalloc(sizeof(*file), GFP_KERNEL); + file = kzalloc_obj(*file); if (!file) { ret = -ENOMEM; goto out; @@ -1396,9 +1396,7 @@ static int ib_umad_add_one(struct ib_device *device) s = rdma_start_port(device); e = rdma_end_port(device); - umad_dev = kzalloc(struct_size(umad_dev, ports, - size_add(size_sub(e, s), 1)), - GFP_KERNEL); + umad_dev = kzalloc_flex(*umad_dev, ports, size_add(size_sub(e, s), 1)); if (!umad_dev) return -ENOMEM; diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index f4616deeca54..758ed4ae5f7a 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -510,7 +510,7 @@ static int xrcd_table_insert(struct ib_uverbs_device *dev, struct rb_node **p = &dev->xrcd_tree.rb_node; struct rb_node *parent = NULL; - entry = kmalloc(sizeof *entry, GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1672,8 +1672,8 @@ static int ib_uverbs_query_qp(struct uverbs_attr_bundle *attrs) if (ret) return ret; - attr = kmalloc(sizeof *attr, GFP_KERNEL); - init_attr = kmalloc(sizeof *init_attr, GFP_KERNEL); + attr = kmalloc_obj(*attr); + init_attr = kmalloc_obj(*init_attr); if (!attr || !init_attr) { ret = -ENOMEM; goto out; @@ -1780,7 +1780,7 @@ static int modify_qp(struct uverbs_attr_bundle *attrs, struct ib_qp *qp; int ret; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return -ENOMEM; @@ -2525,7 +2525,7 @@ static int ib_uverbs_attach_mcast(struct uverbs_attr_bundle *attrs) goto out_put; } - mcast = kmalloc(sizeof *mcast, GFP_KERNEL); + mcast = kmalloc_obj(*mcast); if (!mcast) { ret = -ENOMEM; goto out_put; @@ -2595,7 +2595,7 @@ struct ib_uflow_resources *flow_resources_alloc(size_t num_specs) { struct ib_uflow_resources *resources; - resources = kzalloc(sizeof(*resources), GFP_KERNEL); + resources = kzalloc_obj(*resources); if (!resources) return NULL; @@ -2604,9 +2604,9 @@ struct ib_uflow_resources *flow_resources_alloc(size_t num_specs) goto out; resources->counters = - kcalloc(num_specs, sizeof(*resources->counters), GFP_KERNEL); + kzalloc_objs(*resources->counters, num_specs); resources->collection = - kcalloc(num_specs, sizeof(*resources->collection), GFP_KERNEL); + kzalloc_objs(*resources->collection, num_specs); if (!resources->counters || !resources->collection) goto err; @@ -3116,7 +3116,7 @@ static int ib_uverbs_ex_create_rwq_ind_table(struct uverbs_attr_bundle *attrs) if (err) goto err_free; - wqs = kcalloc(num_wq_handles, sizeof(*wqs), GFP_KERNEL); + wqs = kzalloc_objs(*wqs, num_wq_handles); if (!wqs) { err = -ENOMEM; goto err_free; @@ -3292,8 +3292,7 @@ static int ib_uverbs_ex_create_flow(struct uverbs_attr_bundle *attrs) goto err_put; } - flow_attr = kzalloc(struct_size(flow_attr, flows, - cmd.flow_attr.num_of_specs), GFP_KERNEL); + flow_attr = kzalloc_flex(*flow_attr, flows, cmd.flow_attr.num_of_specs); if (!flow_attr) { err = -ENOMEM; goto err_put; diff --git a/drivers/infiniband/core/uverbs_ioctl.c b/drivers/infiniband/core/uverbs_ioctl.c index f80da6a67e24..f37bb447c230 100644 --- a/drivers/infiniband/core/uverbs_ioctl.c +++ b/drivers/infiniband/core/uverbs_ioctl.c @@ -120,7 +120,7 @@ __malloc void *_uverbs_alloc(struct uverbs_attr_bundle *bundle, size_t size, if (new_used > pbundle->internal_avail) { struct bundle_alloc_head *buf; - buf = kvmalloc(struct_size(buf, data, size), flags); + buf = kvmalloc_flex(*buf, data, size, flags); if (!buf) return ERR_PTR(-ENOMEM); buf->next = pbundle->allocated_mem; diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 973fe2c7ef53..7b68967a6301 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -382,7 +382,7 @@ void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context) return; } - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) { spin_unlock_irqrestore(&ev_queue->lock, flags); return; @@ -417,7 +417,7 @@ void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, return; } - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) { spin_unlock_irqrestore(&async_file->ev_queue.lock, flags); return; @@ -737,7 +737,7 @@ static void rdma_umap_open(struct vm_area_struct *vma) if (!ufile->ucontext) goto out_unlock; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) goto out_unlock; rdma_umap_priv_init(priv, vma, opriv->entry); @@ -966,7 +966,7 @@ static int ib_uverbs_open(struct inode *inode, struct file *filp) } } - file = kzalloc(sizeof(*file), GFP_KERNEL); + file = kzalloc_obj(*file); if (!file) { ret = -ENOMEM; if (module_dependent) @@ -1154,7 +1154,7 @@ static int ib_uverbs_add_one(struct ib_device *device) device->type == RDMA_DEVICE_TYPE_SMI) return -EOPNOTSUPP; - uverbs_dev = kzalloc(sizeof(*uverbs_dev), GFP_KERNEL); + uverbs_dev = kzalloc_obj(*uverbs_dev); if (!uverbs_dev) return -ENOMEM; diff --git a/drivers/infiniband/core/uverbs_std_types_dmabuf.c b/drivers/infiniband/core/uverbs_std_types_dmabuf.c index dfdfcd1d1a44..4a7f8b6f9dc8 100644 --- a/drivers/infiniband/core/uverbs_std_types_dmabuf.c +++ b/drivers/infiniband/core/uverbs_std_types_dmabuf.c @@ -10,6 +10,8 @@ #include "rdma_core.h" #include "uverbs.h" +MODULE_IMPORT_NS("DMA_BUF"); + static int uverbs_dmabuf_attach(struct dma_buf *dmabuf, struct dma_buf_attachment *attachment) { diff --git a/drivers/infiniband/core/uverbs_uapi.c b/drivers/infiniband/core/uverbs_uapi.c index 38d0bbbee796..31b248295854 100644 --- a/drivers/infiniband/core/uverbs_uapi.c +++ b/drivers/infiniband/core/uverbs_uapi.c @@ -445,8 +445,8 @@ static int uapi_finalize(struct uverbs_api *uapi) uapi->notsupp_method.handler = ib_uverbs_notsupp; uapi->num_write = max_write + 1; uapi->num_write_ex = max_write_ex + 1; - data = kmalloc_array(uapi->num_write + uapi->num_write_ex, - sizeof(*uapi->write_methods), GFP_KERNEL); + data = kmalloc_objs(*uapi->write_methods, + uapi->num_write + uapi->num_write_ex); if (!data) return -ENOMEM; @@ -648,7 +648,7 @@ struct uverbs_api *uverbs_alloc_api(struct ib_device *ibdev) struct uverbs_api *uapi; int rc; - uapi = kzalloc(sizeof(*uapi), GFP_KERNEL); + uapi = kzalloc_obj(*uapi); if (!uapi) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c index a2670a031faf..575b4a4b200b 100644 --- a/drivers/infiniband/core/verbs.c +++ b/drivers/infiniband/core/verbs.c @@ -1186,7 +1186,7 @@ static struct ib_qp *__ib_open_qp(struct ib_qp *real_qp, unsigned long flags; int err; - qp = kzalloc(sizeof *qp, GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return ERR_PTR(-ENOMEM); @@ -2420,7 +2420,7 @@ struct ib_mr *ib_alloc_mr_integrity(struct ib_pd *pd, goto out; } - sig_attrs = kzalloc(sizeof(struct ib_sig_attrs), GFP_KERNEL); + sig_attrs = kzalloc_obj(struct ib_sig_attrs); if (!sig_attrs) { mr = ERR_PTR(-ENOMEM); goto out; @@ -3205,7 +3205,7 @@ struct rdma_hw_stats *rdma_alloc_hw_stats_struct( { struct rdma_hw_stats *stats; - stats = kzalloc(struct_size(stats, value, num_counters), GFP_KERNEL); + stats = kzalloc_flex(*stats, value, num_counters); if (!stats) return NULL; diff --git a/drivers/infiniband/hw/bng_re/bng_dev.c b/drivers/infiniband/hw/bng_re/bng_dev.c index d8f8d7f7075f..d34b5f88cd40 100644 --- a/drivers/infiniband/hw/bng_re/bng_dev.c +++ b/drivers/infiniband/hw/bng_re/bng_dev.c @@ -54,9 +54,6 @@ static void bng_re_destroy_chip_ctx(struct bng_re_dev *rdev) { struct bng_re_chip_ctx *chip_ctx; - if (!rdev->chip_ctx) - return; - kfree(rdev->dev_attr); rdev->dev_attr = NULL; @@ -77,7 +74,7 @@ static int bng_re_setup_chip_ctx(struct bng_re_dev *rdev) aux_dev = rdev->aux_dev; rdev->bng_res.pdev = aux_dev->pdev; rdev->rcfw.res = &rdev->bng_res; - chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL); + chip_ctx = kzalloc_obj(*chip_ctx); if (!chip_ctx) return -ENOMEM; chip_ctx->chip_num = aux_dev->chip_num; @@ -85,7 +82,7 @@ static int bng_re_setup_chip_ctx(struct bng_re_dev *rdev) rdev->chip_ctx = chip_ctx; rdev->bng_res.cctx = rdev->chip_ctx; - rdev->dev_attr = kzalloc(sizeof(*rdev->dev_attr), GFP_KERNEL); + rdev->dev_attr = kzalloc_obj(*rdev->dev_attr); if (!rdev->dev_attr) goto free_chip_ctx; rdev->bng_res.dattr = rdev->dev_attr; @@ -124,12 +121,6 @@ static int bng_re_net_ring_free(struct bng_re_dev *rdev, struct bnge_fw_msg fw_msg = {}; int rc = -EINVAL; - if (!rdev) - return rc; - - if (!aux_dev) - return rc; - bng_re_init_hwrm_hdr((void *)&req, HWRM_RING_FREE); req.ring_type = type; req.ring_id = cpu_to_le16(fw_ring_id); @@ -150,10 +141,7 @@ static int bng_re_net_ring_alloc(struct bng_re_dev *rdev, struct hwrm_ring_alloc_input req = {}; struct hwrm_ring_alloc_output resp; struct bnge_fw_msg fw_msg = {}; - int rc = -EINVAL; - - if (!aux_dev) - return rc; + int rc; bng_re_init_hwrm_hdr((void *)&req, HWRM_RING_ALLOC); req.enables = 0; @@ -184,10 +172,7 @@ static int bng_re_stats_ctx_free(struct bng_re_dev *rdev) struct hwrm_stat_ctx_free_input req = {}; struct hwrm_stat_ctx_free_output resp = {}; struct bnge_fw_msg fw_msg = {}; - int rc = -EINVAL; - - if (!aux_dev) - return rc; + int rc; bng_re_init_hwrm_hdr((void *)&req, HWRM_STAT_CTX_FREE); req.stat_ctx_id = cpu_to_le32(rdev->stats_ctx.fw_id); @@ -208,13 +193,10 @@ static int bng_re_stats_ctx_alloc(struct bng_re_dev *rdev) struct hwrm_stat_ctx_alloc_output resp = {}; struct hwrm_stat_ctx_alloc_input req = {}; struct bnge_fw_msg fw_msg = {}; - int rc = -EINVAL; + int rc; stats->fw_id = BNGE_INVALID_STATS_CTX_ID; - if (!aux_dev) - return rc; - bng_re_init_hwrm_hdr((void *)&req, HWRM_STAT_CTX_ALLOC); req.update_period_ms = cpu_to_le32(1000); req.stats_dma_addr = cpu_to_le64(stats->dma_map); @@ -303,7 +285,7 @@ static int bng_re_dev_init(struct bng_re_dev *rdev) if (rc) { ibdev_err(&rdev->ibdev, "Failed to register with netedev: %#x\n", rc); - return -EINVAL; + goto reg_netdev_fail; } set_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); @@ -312,19 +294,16 @@ static int bng_re_dev_init(struct bng_re_dev *rdev) ibdev_err(&rdev->ibdev, "RoCE requires minimum 2 MSI-X vectors, but only %d reserved\n", rdev->aux_dev->auxr_info->msix_requested); - bnge_unregister_dev(rdev->aux_dev); - clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); - return -EINVAL; + rc = -EINVAL; + goto msix_ctx_fail; } ibdev_dbg(&rdev->ibdev, "Got %d MSI-X vectors\n", rdev->aux_dev->auxr_info->msix_requested); rc = bng_re_setup_chip_ctx(rdev); if (rc) { - bnge_unregister_dev(rdev->aux_dev); - clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); ibdev_err(&rdev->ibdev, "Failed to get chip context\n"); - return -EINVAL; + goto msix_ctx_fail; } bng_re_query_hwrm_version(rdev); @@ -333,16 +312,14 @@ static int bng_re_dev_init(struct bng_re_dev *rdev) if (rc) { ibdev_err(&rdev->ibdev, "Failed to allocate RCFW Channel: %#x\n", rc); - goto fail; + goto alloc_fw_chl_fail; } /* Allocate nq record memory */ - rdev->nqr = kzalloc(sizeof(*rdev->nqr), GFP_KERNEL); + rdev->nqr = kzalloc_obj(*rdev->nqr); if (!rdev->nqr) { - bng_re_destroy_chip_ctx(rdev); - bnge_unregister_dev(rdev->aux_dev); - clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); - return -ENOMEM; + rc = -ENOMEM; + goto nq_alloc_fail; } rdev->nqr->num_msix = rdev->aux_dev->auxr_info->msix_requested; @@ -411,9 +388,15 @@ static int bng_re_dev_init(struct bng_re_dev *rdev) free_ring: bng_re_net_ring_free(rdev, rdev->rcfw.creq.ring_id, type); free_rcfw: + kfree(rdev->nqr); +nq_alloc_fail: bng_re_free_rcfw_channel(&rdev->rcfw); -fail: - bng_re_dev_uninit(rdev); +alloc_fw_chl_fail: + bng_re_destroy_chip_ctx(rdev); +msix_ctx_fail: + bnge_unregister_dev(rdev->aux_dev); + clear_bit(BNG_RE_FLAG_NETDEV_REGISTERED, &rdev->flags); +reg_netdev_fail: return rc; } @@ -464,7 +447,7 @@ static int bng_re_probe(struct auxiliary_device *adev, struct bng_re_en_dev_info *en_info; int rc; - en_info = kzalloc(sizeof(*en_info), GFP_KERNEL); + en_info = kzalloc_obj(*en_info); if (!en_info) return -ENOMEM; @@ -486,8 +469,7 @@ static void bng_re_remove(struct auxiliary_device *adev) rdev = dev_info->rdev; - if (rdev) - bng_re_remove_device(rdev, adev); + bng_re_remove_device(rdev, adev); kfree(dev_info); } diff --git a/drivers/infiniband/hw/bng_re/bng_fw.c b/drivers/infiniband/hw/bng_re/bng_fw.c index 01b3e1cbe719..17d7cc3aa11d 100644 --- a/drivers/infiniband/hw/bng_re/bng_fw.c +++ b/drivers/infiniband/hw/bng_re/bng_fw.c @@ -98,8 +98,7 @@ int bng_re_alloc_fw_channel(struct bng_re_res *res, goto fail; } - rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements, - sizeof(*rcfw->crsqe_tbl), GFP_KERNEL); + rcfw->crsqe_tbl = kzalloc_objs(*rcfw->crsqe_tbl, cmdq->hwq.max_elements); if (!rcfw->crsqe_tbl) goto fail; diff --git a/drivers/infiniband/hw/bnxt_re/debugfs.c b/drivers/infiniband/hw/bnxt_re/debugfs.c index e025217861c2..a2ad79c3bbd0 100644 --- a/drivers/infiniband/hw/bnxt_re/debugfs.c +++ b/drivers/infiniband/hw/bnxt_re/debugfs.c @@ -467,7 +467,7 @@ static void bnxt_re_init_cq_coal_debugfs(struct bnxt_re_dev *rdev) if (!_is_cq_coalescing_supported(rdev->dev_attr->dev_cap_flags2)) return; - dbg_cq_coal_params = kzalloc(sizeof(*dbg_cq_coal_params), GFP_KERNEL); + dbg_cq_coal_params = kzalloc_obj(*dbg_cq_coal_params); if (!dbg_cq_coal_params) return; @@ -497,7 +497,7 @@ void bnxt_re_debugfs_add_pdev(struct bnxt_re_dev *rdev) bnxt_re_debugfs_add_info(rdev); - rdev->cc_config_params = kzalloc(sizeof(*cc_params), GFP_KERNEL); + rdev->cc_config_params = kzalloc_obj(*cc_params); for (i = 0; i < BNXT_RE_CC_PARAM_GEN0; i++) { struct bnxt_re_cc_param *tmp_params = &rdev->cc_config_params->gen0_parms[i]; diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c index be3c3f1f87f7..5c5ecfacf506 100644 --- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c +++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c @@ -461,7 +461,7 @@ int bnxt_re_add_gid(const struct ib_gid_attr *attr, void **context) return rc; } - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx_tbl = sgid_tbl->ctx; @@ -593,7 +593,7 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd) fence->dma_addr = dma_addr; /* Allocate a MR */ - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { rc = -ENOMEM; goto fail; @@ -651,7 +651,7 @@ bnxt_re_mmap_entry_insert(struct bnxt_re_ucontext *uctx, u64 mem_offset, struct bnxt_re_user_mmap_entry *entry; int ret; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -1190,7 +1190,7 @@ static struct bnxt_re_ah *bnxt_re_create_shadow_qp_ah union ib_gid sgid; int rc; - ah = kzalloc(sizeof(*ah), GFP_KERNEL); + ah = kzalloc_obj(*ah); if (!ah) return NULL; @@ -1237,7 +1237,7 @@ static struct bnxt_re_qp *bnxt_re_create_shadow_qp struct bnxt_re_qp *qp; int rc; - qp = kzalloc(sizeof(*qp), GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return NULL; @@ -1547,8 +1547,7 @@ static int bnxt_re_create_shadow_gsi(struct bnxt_re_qp *qp, rdev = qp->rdev; /* Create a shadow QP to handle the QP1 traffic */ - sqp_tbl = kcalloc(BNXT_RE_MAX_GSI_SQP_ENTRIES, sizeof(*sqp_tbl), - GFP_KERNEL); + sqp_tbl = kzalloc_objs(*sqp_tbl, BNXT_RE_MAX_GSI_SQP_ENTRIES); if (!sqp_tbl) return -ENOMEM; rdev->gsi_ctx.sqp_tbl = sqp_tbl; @@ -2359,7 +2358,7 @@ int bnxt_re_query_qp(struct ib_qp *ib_qp, struct ib_qp_attr *qp_attr, struct bnxt_qplib_qp *qplib_qp; int rc; - qplib_qp = kzalloc(sizeof(*qplib_qp), GFP_KERNEL); + qplib_qp = kzalloc_obj(*qplib_qp); if (!qplib_qp) return -ENOMEM; @@ -3194,8 +3193,7 @@ int bnxt_re_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, cq->qplib_cq.dpi = &uctx->dpi; } else { cq->max_cql = min_t(u32, entries, MAX_CQL_PER_POLL); - cq->cql = kcalloc(cq->max_cql, sizeof(struct bnxt_qplib_cqe), - GFP_KERNEL); + cq->cql = kzalloc_objs(struct bnxt_qplib_cqe, cq->max_cql); if (!cq->cql) { rc = -ENOMEM; goto fail; @@ -4030,7 +4028,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *ib_pd, int mr_access_flags) u32 active_mrs; int rc; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -4133,7 +4131,7 @@ struct ib_mr *bnxt_re_alloc_mr(struct ib_pd *ib_pd, enum ib_mr_type type, if (max_num_sg > MAX_PBL_LVL_1_PGS) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -4185,7 +4183,7 @@ struct ib_mw *bnxt_re_alloc_mw(struct ib_pd *ib_pd, enum ib_mw_type type, u32 active_mws; int rc; - mw = kzalloc(sizeof(*mw), GFP_KERNEL); + mw = kzalloc_obj(*mw); if (!mw) return ERR_PTR(-ENOMEM); mw->rdev = rdev; @@ -4250,7 +4248,7 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64 return ERR_PTR(-EINVAL); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -4507,7 +4505,7 @@ struct ib_flow *bnxt_re_create_flow(struct ib_qp *ib_qp, return ERR_PTR(-EBUSY); } - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (!flow) { mutex_unlock(&rdev->qp_lock); return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/bnxt_re/main.c b/drivers/infiniband/hw/bnxt_re/main.c index ee882456319d..b576f05e3b26 100644 --- a/drivers/infiniband/hw/bnxt_re/main.c +++ b/drivers/infiniband/hw/bnxt_re/main.c @@ -171,7 +171,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) en_dev = rdev->en_dev; rdev->qplib_res.pdev = en_dev->pdev; - chip_ctx = kzalloc(sizeof(*chip_ctx), GFP_KERNEL); + chip_ctx = kzalloc_obj(*chip_ctx); if (!chip_ctx) return -ENOMEM; chip_ctx->chip_num = en_dev->chip_num; @@ -182,7 +182,7 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) rdev->qplib_res.cctx = rdev->chip_ctx; rdev->rcfw.res = &rdev->qplib_res; - rdev->dev_attr = kzalloc(sizeof(*rdev->dev_attr), GFP_KERNEL); + rdev->dev_attr = kzalloc_obj(*rdev->dev_attr); if (!rdev->dev_attr) goto free_chip_ctx; rdev->qplib_res.dattr = rdev->dev_attr; @@ -420,7 +420,7 @@ static void bnxt_re_async_notifier(void *handle, struct hwrm_async_event_cmpl *c switch (event_id) { case ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE: - dcb_work = kzalloc(sizeof(*dcb_work), GFP_ATOMIC); + dcb_work = kzalloc_obj(*dcb_work, GFP_ATOMIC); if (!dcb_work) break; @@ -2033,7 +2033,7 @@ static int bnxt_re_ib_init(struct bnxt_re_dev *rdev) static int bnxt_re_alloc_nqr_mem(struct bnxt_re_dev *rdev) { - rdev->nqr = kzalloc(sizeof(*rdev->nqr), GFP_KERNEL); + rdev->nqr = kzalloc_obj(*rdev->nqr); if (!rdev->nqr) return -ENOMEM; @@ -2491,7 +2491,7 @@ static int bnxt_re_probe(struct auxiliary_device *adev, en_dev = aux_priv->edev; mutex_lock(&bnxt_re_mutex); - en_info = kzalloc(sizeof(*en_info), GFP_KERNEL); + en_info = kzalloc_obj(*en_info); if (!en_info) { mutex_unlock(&bnxt_re_mutex); return -ENOMEM; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_fp.c b/drivers/infiniband/hw/bnxt_re/qplib_fp.c index 3e44311bf939..2d7932b3c492 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_fp.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_fp.c @@ -688,8 +688,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, srq->start_idx = 0; srq->last_idx = srq->hwq.max_elements - 1; if (!srq->hwq.is_user) { - srq->swq = kcalloc(srq->hwq.max_elements, sizeof(*srq->swq), - GFP_KERNEL); + srq->swq = kzalloc_objs(*srq->swq, srq->hwq.max_elements); if (!srq->swq) { rc = -ENOMEM; goto fail; @@ -799,7 +798,7 @@ static int bnxt_qplib_alloc_init_swq(struct bnxt_qplib_q *que) { int indx; - que->swq = kcalloc(que->max_sw_wqe, sizeof(*que->swq), GFP_KERNEL); + que->swq = kzalloc_objs(*que->swq, que->max_sw_wqe); if (!que->swq) return -ENOMEM; @@ -2096,7 +2095,7 @@ int bnxt_qplib_post_send(struct bnxt_qplib_qp *qp, qp->wqe_cnt++; done: if (sch_handler) { - nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC); + nq_work = kzalloc_obj(*nq_work, GFP_ATOMIC); if (nq_work) { nq_work->cq = qp->scq; nq_work->nq = qp->scq->nq; @@ -2183,7 +2182,7 @@ int bnxt_qplib_post_recv(struct bnxt_qplib_qp *qp, bnxt_qplib_hwq_incr_prod(&rq->dbinfo, hwq, swq->slots); done: if (sch_handler) { - nq_work = kzalloc(sizeof(*nq_work), GFP_ATOMIC); + nq_work = kzalloc_obj(*nq_work, GFP_ATOMIC); if (nq_work) { nq_work->cq = qp->rcq; nq_work->nq = qp->rcq->nq; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c index 4dad0cfcfa98..9ee0d500436c 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c @@ -968,8 +968,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, goto fail; } - rcfw->crsqe_tbl = kcalloc(cmdq->hwq.max_elements, - sizeof(*rcfw->crsqe_tbl), GFP_KERNEL); + rcfw->crsqe_tbl = kzalloc_objs(*rcfw->crsqe_tbl, cmdq->hwq.max_elements); if (!rcfw->crsqe_tbl) goto fail; diff --git a/drivers/infiniband/hw/bnxt_re/qplib_res.c b/drivers/infiniband/hw/bnxt_re/qplib_res.c index 4d674a3aee1a..341bae3d8a1d 100644 --- a/drivers/infiniband/hw/bnxt_re/qplib_res.c +++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c @@ -556,7 +556,7 @@ static int bnxt_qplib_alloc_sgid_tbl(struct bnxt_qplib_res *res, struct bnxt_qplib_sgid_tbl *sgid_tbl, u16 max) { - sgid_tbl->tbl = kcalloc(max, sizeof(*sgid_tbl->tbl), GFP_KERNEL); + sgid_tbl->tbl = kzalloc_objs(*sgid_tbl->tbl, max); if (!sgid_tbl->tbl) return -ENOMEM; @@ -872,8 +872,8 @@ int bnxt_qplib_alloc_res(struct bnxt_qplib_res *res, struct net_device *netdev) /* Allocate one extra to hold the QP1 entries */ rcfw->qp_tbl_size = max_t(u32, BNXT_RE_MAX_QPC_COUNT + 1, dev_attr->max_qp); - rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node), - GFP_KERNEL); + rcfw->qp_tbl = kzalloc_objs(struct bnxt_qplib_qp_node, + rcfw->qp_tbl_size); if (!rcfw->qp_tbl) return -ENOMEM; diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c index 14ced7b667fa..e31fb9134aa8 100644 --- a/drivers/infiniband/hw/cxgb4/cq.c +++ b/drivers/infiniband/hw/cxgb4/cq.c @@ -1095,10 +1095,10 @@ int c4iw_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, if (ucontext) { ret = -ENOMEM; - mm = kmalloc(sizeof(*mm), GFP_KERNEL); + mm = kmalloc_obj(*mm); if (!mm) goto err_remove_handle; - mm2 = kmalloc(sizeof(*mm2), GFP_KERNEL); + mm2 = kmalloc_obj(*mm2); if (!mm2) goto err_free_mm; diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c index d892f55febe2..102c5646b9ed 100644 --- a/drivers/infiniband/hw/cxgb4/device.c +++ b/drivers/infiniband/hw/cxgb4/device.c @@ -330,7 +330,7 @@ static int qp_open(struct inode *inode, struct file *file) unsigned long index; int count = 1; - qpd = kmalloc(sizeof(*qpd), GFP_KERNEL); + qpd = kmalloc_obj(*qpd); if (!qpd) return -ENOMEM; @@ -424,7 +424,7 @@ static int stag_open(struct inode *inode, struct file *file) int ret = 0; int count = 1; - stagd = kmalloc(sizeof(*stagd), GFP_KERNEL); + stagd = kmalloc_obj(*stagd); if (!stagd) { ret = -ENOMEM; goto out; @@ -675,7 +675,7 @@ static int ep_open(struct inode *inode, struct file *file) int ret = 0; int count = 1; - epd = kmalloc(sizeof(*epd), GFP_KERNEL); + epd = kmalloc_obj(*epd); if (!epd) { ret = -ENOMEM; goto out; @@ -881,9 +881,8 @@ static int c4iw_rdev_open(struct c4iw_rdev *rdev) rdev->status_page->write_cmpl_supported = rdev->lldi.write_cmpl_support; if (c4iw_wr_log) { - rdev->wr_log = kcalloc(1 << c4iw_wr_log_size_order, - sizeof(*rdev->wr_log), - GFP_KERNEL); + rdev->wr_log = kzalloc_objs(*rdev->wr_log, + 1 << c4iw_wr_log_size_order); if (rdev->wr_log) { rdev->wr_log_size = 1 << c4iw_wr_log_size_order; atomic_set(&rdev->wr_log_idx, 0); @@ -1078,7 +1077,7 @@ static void *c4iw_uld_add(const struct cxgb4_lld_info *infop) pr_info("Chelsio T4/T5 RDMA Driver - version %s\n", DRV_VERSION); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ctx = ERR_PTR(-ENOMEM); goto out; @@ -1439,7 +1438,7 @@ static void recover_queues(struct uld_ctx *ctx) xa_for_each(&ctx->dev->qps, index, qp) count++; - qp_list.qps = kcalloc(count, sizeof(*qp_list.qps), GFP_ATOMIC); + qp_list.qps = kzalloc_objs(*qp_list.qps, count, GFP_ATOMIC); if (!qp_list.qps) { xa_unlock_irq(&ctx->dev->qps); return; @@ -1522,7 +1521,7 @@ struct c4iw_wr_wait *c4iw_alloc_wr_wait(gfp_t gfp) { struct c4iw_wr_wait *wr_waitp; - wr_waitp = kzalloc(sizeof(*wr_waitp), gfp); + wr_waitp = kzalloc_obj(*wr_waitp, gfp); if (wr_waitp) { kref_init(&wr_waitp->kref); pr_debug("wr_wait %p\n", wr_waitp); diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c index adeed7447e7b..b8d49abde099 100644 --- a/drivers/infiniband/hw/cxgb4/mem.c +++ b/drivers/infiniband/hw/cxgb4/mem.c @@ -282,7 +282,7 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry, if (c4iw_fatal_error(rdev)) return -EIO; - tpt = kmalloc(sizeof(*tpt), GFP_KERNEL); + tpt = kmalloc_obj(*tpt); if (!tpt) return -ENOMEM; @@ -439,7 +439,7 @@ struct ib_mr *c4iw_get_dma_mr(struct ib_pd *pd, int acc) php = to_c4iw_pd(pd); rhp = php->rhp; - mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); + mhp = kzalloc_obj(*mhp); if (!mhp) return ERR_PTR(-ENOMEM); mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL); @@ -517,7 +517,7 @@ struct ib_mr *c4iw_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (mr_exceeds_hw_limits(rhp, length)) return ERR_PTR(-EINVAL); - mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); + mhp = kzalloc_obj(*mhp); if (!mhp) return ERR_PTR(-ENOMEM); mhp->wr_waitp = c4iw_alloc_wr_wait(GFP_KERNEL); @@ -618,7 +618,7 @@ struct ib_mr *c4iw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, use_dsgl)) return ERR_PTR(-EINVAL); - mhp = kzalloc(sizeof(*mhp), GFP_KERNEL); + mhp = kzalloc_obj(*mhp); if (!mhp) { ret = -ENOMEM; goto err; diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c index e059f92d90fd..616019ac1da5 100644 --- a/drivers/infiniband/hw/cxgb4/provider.c +++ b/drivers/infiniband/hw/cxgb4/provider.c @@ -92,7 +92,7 @@ static int c4iw_alloc_ucontext(struct ib_ucontext *ucontext, pr_err_once("Warning - downlevel libcxgb4 (non-fatal), device status page disabled\n"); rhp->rdev.flags |= T4_STATUS_PAGE_DISABLED; } else { - mm = kmalloc(sizeof(*mm), GFP_KERNEL); + mm = kmalloc_obj(*mm); if (!mm) { ret = -ENOMEM; goto err; diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c index 955f061a55e9..d9a86e4c5461 100644 --- a/drivers/infiniband/hw/cxgb4/qp.c +++ b/drivers/infiniband/hw/cxgb4/qp.c @@ -223,17 +223,14 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq, } if (!user) { - wq->sq.sw_sq = kcalloc(wq->sq.size, sizeof(*wq->sq.sw_sq), - GFP_KERNEL); + wq->sq.sw_sq = kzalloc_objs(*wq->sq.sw_sq, wq->sq.size); if (!wq->sq.sw_sq) { ret = -ENOMEM; goto free_rq_qid;//FIXME } if (need_rq) { - wq->rq.sw_rq = kcalloc(wq->rq.size, - sizeof(*wq->rq.sw_rq), - GFP_KERNEL); + wq->rq.sw_rq = kzalloc_objs(*wq->rq.sw_rq, wq->rq.size); if (!wq->rq.sw_rq) { ret = -ENOMEM; goto free_sw_sq; @@ -2221,26 +2218,25 @@ int c4iw_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, goto err_destroy_qp; if (udata && ucontext) { - sq_key_mm = kmalloc(sizeof(*sq_key_mm), GFP_KERNEL); + sq_key_mm = kmalloc_obj(*sq_key_mm); if (!sq_key_mm) { ret = -ENOMEM; goto err_remove_handle; } if (!attrs->srq) { - rq_key_mm = kmalloc(sizeof(*rq_key_mm), GFP_KERNEL); + rq_key_mm = kmalloc_obj(*rq_key_mm); if (!rq_key_mm) { ret = -ENOMEM; goto err_free_sq_key; } } - sq_db_key_mm = kmalloc(sizeof(*sq_db_key_mm), GFP_KERNEL); + sq_db_key_mm = kmalloc_obj(*sq_db_key_mm); if (!sq_db_key_mm) { ret = -ENOMEM; goto err_free_rq_key; } if (!attrs->srq) { - rq_db_key_mm = - kmalloc(sizeof(*rq_db_key_mm), GFP_KERNEL); + rq_db_key_mm = kmalloc_obj(*rq_db_key_mm); if (!rq_db_key_mm) { ret = -ENOMEM; goto err_free_sq_db_key; @@ -2248,8 +2244,7 @@ int c4iw_create_qp(struct ib_qp *qp, struct ib_qp_init_attr *attrs, } memset(&uresp, 0, sizeof(uresp)); if (t4_sq_onchip(&qhp->wq.sq)) { - ma_sync_key_mm = kmalloc(sizeof(*ma_sync_key_mm), - GFP_KERNEL); + ma_sync_key_mm = kmalloc_obj(*ma_sync_key_mm); if (!ma_sync_key_mm) { ret = -ENOMEM; goto err_free_rq_db_key; @@ -2552,13 +2547,11 @@ static int alloc_srq_queue(struct c4iw_srq *srq, struct c4iw_dev_ucontext *uctx, goto err; if (!user) { - wq->sw_rq = kcalloc(wq->size, sizeof(*wq->sw_rq), - GFP_KERNEL); + wq->sw_rq = kzalloc_objs(*wq->sw_rq, wq->size); if (!wq->sw_rq) goto err_put_qpid; - wq->pending_wrs = kcalloc(srq->wq.size, - sizeof(*srq->wq.pending_wrs), - GFP_KERNEL); + wq->pending_wrs = kzalloc_objs(*srq->wq.pending_wrs, + srq->wq.size); if (!wq->pending_wrs) goto err_free_sw_rq; } @@ -2761,12 +2754,12 @@ int c4iw_create_srq(struct ib_srq *ib_srq, struct ib_srq_init_attr *attrs, srq->flags = T4_SRQ_LIMIT_SUPPORT; if (udata) { - srq_key_mm = kmalloc(sizeof(*srq_key_mm), GFP_KERNEL); + srq_key_mm = kmalloc_obj(*srq_key_mm); if (!srq_key_mm) { ret = -ENOMEM; goto err_free_queue; } - srq_db_key_mm = kmalloc(sizeof(*srq_db_key_mm), GFP_KERNEL); + srq_db_key_mm = kmalloc_obj(*srq_db_key_mm); if (!srq_db_key_mm) { ret = -ENOMEM; goto err_free_srq_key_mm; diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c index e800e8e8bed5..479d12824c72 100644 --- a/drivers/infiniband/hw/cxgb4/resource.c +++ b/drivers/infiniband/hw/cxgb4/resource.c @@ -126,7 +126,7 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) rdev->stats.qid.cur += rdev->qpmask + 1; mutex_unlock(&rdev->stats.lock); for (i = qid+1; i & rdev->qpmask; i++) { - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = i; @@ -137,13 +137,13 @@ u32 c4iw_get_cqid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) * now put the same ids on the qp list since they all * map to the same db/gts page. */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = qid; list_add_tail(&entry->entry, &uctx->qpids); for (i = qid+1; i & rdev->qpmask; i++) { - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = i; @@ -165,7 +165,7 @@ void c4iw_put_cqid(struct c4iw_rdev *rdev, u32 qid, { struct c4iw_qid_list *entry; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return; pr_debug("qid 0x%x\n", qid); @@ -200,7 +200,7 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) rdev->stats.qid.cur += rdev->qpmask + 1; mutex_unlock(&rdev->stats.lock); for (i = qid+1; i & rdev->qpmask; i++) { - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = i; @@ -211,13 +211,13 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx) * now put the same ids on the cq list since they all * map to the same db/gts page. */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = qid; list_add_tail(&entry->entry, &uctx->cqids); for (i = qid + 1; i & rdev->qpmask; i++) { - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) goto out; entry->qid = i; @@ -239,7 +239,7 @@ void c4iw_put_qpid(struct c4iw_rdev *rdev, u32 qid, { struct c4iw_qid_list *entry; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return; pr_debug("qid 0x%x\n", qid); diff --git a/drivers/infiniband/hw/cxgb4/restrack.c b/drivers/infiniband/hw/cxgb4/restrack.c index fd22c85d35f4..4f45d961d913 100644 --- a/drivers/infiniband/hw/cxgb4/restrack.c +++ b/drivers/infiniband/hw/cxgb4/restrack.c @@ -209,7 +209,7 @@ int c4iw_fill_res_cm_id_entry(struct sk_buff *msg, epcp = (struct c4iw_ep_common *)iw_cm_id->provider_data; if (!epcp) return 0; - uep = kzalloc(sizeof(*uep), GFP_KERNEL); + uep = kzalloc_obj(*uep); if (!uep) return 0; diff --git a/drivers/infiniband/hw/efa/efa_main.c b/drivers/infiniband/hw/efa/efa_main.c index 6c415b9adb5f..c1397086dc47 100644 --- a/drivers/infiniband/hw/efa/efa_main.c +++ b/drivers/infiniband/hw/efa/efa_main.c @@ -332,7 +332,7 @@ static int efa_create_eqs(struct efa_dev *dev) neqs = min_t(u32, neqs, dev->num_irq_vectors - EFA_COMP_EQS_VEC_BASE); dev->neqs = neqs; - dev->eqs = kcalloc(neqs, sizeof(*dev->eqs), GFP_KERNEL); + dev->eqs = kzalloc_objs(*dev->eqs, neqs); if (!dev->eqs) return -ENOMEM; diff --git a/drivers/infiniband/hw/efa/efa_verbs.c b/drivers/infiniband/hw/efa/efa_verbs.c index 755bba8d58bb..b0aa7c0238ed 100644 --- a/drivers/infiniband/hw/efa/efa_verbs.c +++ b/drivers/infiniband/hw/efa/efa_verbs.c @@ -525,7 +525,7 @@ efa_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address, size_t length, u8 mmap_flag, u64 *offset) { - struct efa_user_mmap_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct efa_user_mmap_entry *entry = kzalloc_obj(*entry); int err; if (!entry) @@ -1335,7 +1335,7 @@ static struct scatterlist *efa_vmalloc_buf_to_sg(u64 *buf, int page_cnt) struct page *pg; int i; - sglist = kmalloc_array(page_cnt, sizeof(*sglist), GFP_KERNEL); + sglist = kmalloc_objs(*sglist, page_cnt); if (!sglist) return NULL; sg_init_table(sglist, page_cnt); @@ -1374,9 +1374,7 @@ static int pbl_chunk_list_create(struct efa_dev *dev, struct pbl_context *pbl) chunk_list_size = DIV_ROUND_UP(page_cnt, EFA_PTRS_PER_CHUNK); chunk_list->size = chunk_list_size; - chunk_list->chunks = kcalloc(chunk_list_size, - sizeof(*chunk_list->chunks), - GFP_KERNEL); + chunk_list->chunks = kzalloc_objs(*chunk_list->chunks, chunk_list_size); if (!chunk_list->chunks) return -ENOMEM; @@ -1663,7 +1661,7 @@ static struct efa_mr *efa_alloc_mr(struct ib_pd *ibpd, int access_flags, struct efa_mr *mr; if (udata && udata->inlen && - !ib_is_udata_cleared(udata, 0, sizeof(udata->inlen))) { + !ib_is_udata_cleared(udata, 0, udata->inlen)) { ibdev_dbg(&dev->ibdev, "Incompatible ABI params, udata not cleared\n"); return ERR_PTR(-EINVAL); @@ -1682,7 +1680,7 @@ static struct efa_mr *efa_alloc_mr(struct ib_pd *ibpd, int access_flags, return ERR_PTR(-EOPNOTSUPP); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/erdma/erdma_cm.c b/drivers/infiniband/hw/erdma/erdma_cm.c index ed21ba0037a4..5c7d3a8f8038 100644 --- a/drivers/infiniband/hw/erdma/erdma_cm.c +++ b/drivers/infiniband/hw/erdma/erdma_cm.c @@ -91,7 +91,7 @@ static void erdma_disassoc_listen_cep(struct erdma_cep *cep) static struct erdma_cep *erdma_cep_alloc(struct erdma_dev *dev) { - struct erdma_cep *cep = kzalloc(sizeof(*cep), GFP_KERNEL); + struct erdma_cep *cep = kzalloc_obj(*cep); unsigned long flags; if (!cep) @@ -217,7 +217,7 @@ static int erdma_cm_alloc_work(struct erdma_cep *cep, int num) struct erdma_cm_work *work; while (num--) { - work = kmalloc(sizeof(*work), GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) { if (!(list_empty(&cep->work_freelist))) erdma_cm_free_work(cep); @@ -1340,7 +1340,7 @@ int erdma_create_listen(struct iw_cm_id *id, int backlog) if (!id->provider_data) { id->provider_data = - kmalloc(sizeof(struct list_head), GFP_KERNEL); + kmalloc_obj(struct list_head); if (!id->provider_data) { ret = -ENOMEM; goto error; diff --git a/drivers/infiniband/hw/erdma/erdma_verbs.c b/drivers/infiniband/hw/erdma/erdma_verbs.c index 109a3f3de911..9f74aadc3047 100644 --- a/drivers/infiniband/hw/erdma/erdma_verbs.c +++ b/drivers/infiniband/hw/erdma/erdma_verbs.c @@ -291,8 +291,7 @@ static struct rdma_user_mmap_entry * erdma_user_mmap_entry_insert(struct erdma_ucontext *uctx, void *address, u32 size, u8 mmap_flag, u64 *mmap_offset) { - struct erdma_user_mmap_entry *entry = - kzalloc(sizeof(*entry), GFP_KERNEL); + struct erdma_user_mmap_entry *entry = kzalloc_obj(*entry); int ret; if (!entry) @@ -600,7 +599,7 @@ static struct erdma_mtt *erdma_create_cont_mtt(struct erdma_dev *dev, { struct erdma_mtt *mtt; - mtt = kzalloc(sizeof(*mtt), GFP_KERNEL); + mtt = kzalloc_obj(*mtt); if (!mtt) return ERR_PTR(-ENOMEM); @@ -725,7 +724,7 @@ static struct erdma_mtt *erdma_create_scatter_mtt(struct erdma_dev *dev, struct erdma_mtt *mtt; int ret = -ENOMEM; - mtt = kzalloc(sizeof(*mtt), GFP_KERNEL); + mtt = kzalloc_obj(*mtt); if (!mtt) return ERR_PTR(-ENOMEM); @@ -888,7 +887,7 @@ static int erdma_map_user_dbrecords(struct erdma_ucontext *ctx, if (page->va == (dbrecords_va & PAGE_MASK)) goto found; - page = kmalloc(sizeof(*page), GFP_KERNEL); + page = kmalloc_obj(*page); if (!page) { rv = -ENOMEM; goto out; @@ -1116,7 +1115,7 @@ struct ib_mr *erdma_get_dma_mr(struct ib_pd *ibpd, int acc) u32 stag; int ret; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1160,7 +1159,7 @@ struct ib_mr *erdma_ib_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, if (max_num_sg > ERDMA_MR_MAX_MTT_CNT) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1246,7 +1245,7 @@ struct ib_mr *erdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, if (!len || len > dev->attrs.max_mr_size) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/hfi1/affinity.c b/drivers/infiniband/hw/hfi1/affinity.c index ee7fedc67b86..2b20907c9c12 100644 --- a/drivers/infiniband/hw/hfi1/affinity.c +++ b/drivers/infiniband/hw/hfi1/affinity.c @@ -199,7 +199,7 @@ static struct hfi1_affinity_node *node_affinity_allocate(int node) { struct hfi1_affinity_node *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; entry->node = node; @@ -406,9 +406,8 @@ static int _dev_comp_vect_mappings_create(struct hfi1_devdata *dd, return -ENOMEM; } - dd->comp_vect_mappings = kcalloc(dd->comp_vect_possible_cpus, - sizeof(*dd->comp_vect_mappings), - GFP_KERNEL); + dd->comp_vect_mappings = kzalloc_objs(*dd->comp_vect_mappings, + dd->comp_vect_possible_cpus); if (!dd->comp_vect_mappings) { ret = -ENOMEM; goto fail; diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c index 0781ab756d44..6a9db4d17c5a 100644 --- a/drivers/infiniband/hw/hfi1/chip.c +++ b/drivers/infiniband/hw/hfi1/chip.c @@ -14221,7 +14221,7 @@ static struct rsm_map_table *alloc_rsm_map_table(struct hfi1_devdata *dd) struct rsm_map_table *rmt; u8 rxcontext = is_ax(dd) ? 0 : 0xff; /* 0 is default if a0 ver. */ - rmt = kmalloc(sizeof(*rmt), GFP_KERNEL); + rmt = kmalloc_obj(*rmt); if (rmt) { memset(rmt->map, rxcontext, sizeof(rmt->map)); rmt->used = 0; @@ -14872,7 +14872,7 @@ static int init_asic_data(struct hfi1_devdata *dd) int ret = 0; /* pre-allocate the asic structure in case we are the first device */ - asic_data = kzalloc(sizeof(*dd->asic_data), GFP_KERNEL); + asic_data = kzalloc_obj(*dd->asic_data); if (!asic_data) return -ENOMEM; diff --git a/drivers/infiniband/hw/hfi1/efivar.c b/drivers/infiniband/hw/hfi1/efivar.c index 9ed05e10020e..c4974c3bea5e 100644 --- a/drivers/infiniband/hw/hfi1/efivar.c +++ b/drivers/infiniband/hw/hfi1/efivar.c @@ -41,7 +41,7 @@ static int read_efi_var(const char *name, unsigned long *size, if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) return -EOPNOTSUPP; - uni_name = kcalloc(strlen(name) + 1, sizeof(efi_char16_t), GFP_KERNEL); + uni_name = kzalloc_objs(efi_char16_t, strlen(name) + 1); temp_buffer = kzalloc(EFI_DATA_SIZE, GFP_KERNEL); if (!uni_name || !temp_buffer) { diff --git a/drivers/infiniband/hw/hfi1/fault.c b/drivers/infiniband/hw/hfi1/fault.c index a45cbffd52c7..4ab72ef03ba1 100644 --- a/drivers/infiniband/hw/hfi1/fault.c +++ b/drivers/infiniband/hw/hfi1/fault.c @@ -209,7 +209,7 @@ int hfi1_fault_init_debugfs(struct hfi1_ibdev *ibd) struct dentry *parent = ibd->hfi1_ibdev_dbg; struct dentry *fault_dir; - ibd->fault = kzalloc(sizeof(*ibd->fault), GFP_KERNEL); + ibd->fault = kzalloc_obj(*ibd->fault); if (!ibd->fault) return -ENOMEM; diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index 503abec709c9..56031becb273 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -158,7 +158,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) /* The real work is performed later in assign_ctxt() */ - fd = kzalloc(sizeof(*fd), GFP_KERNEL); + fd = kzalloc_obj(*fd); if (!fd || init_srcu_struct(&fd->pq_srcu)) goto nomem; diff --git a/drivers/infiniband/hw/hfi1/init.c b/drivers/infiniband/hw/hfi1/init.c index e4aef102dac0..07333dd37652 100644 --- a/drivers/infiniband/hw/hfi1/init.c +++ b/drivers/infiniband/hw/hfi1/init.c @@ -646,7 +646,7 @@ void hfi1_init_pportdata(struct pci_dev *pdev, struct hfi1_pportdata *ppd, spin_lock_init(&ppd->cc_state_lock); spin_lock_init(&ppd->cc_log_lock); - cc_state = kzalloc(sizeof(*cc_state), GFP_KERNEL); + cc_state = kzalloc_obj(*cc_state); RCU_INIT_POINTER(ppd->cc_state, cc_state); if (!cc_state) goto bail; @@ -1282,7 +1282,7 @@ static struct hfi1_devdata *hfi1_alloc_devdata(struct pci_dev *pdev, goto bail; } - dd->comp_vect = kzalloc(sizeof(*dd->comp_vect), GFP_KERNEL); + dd->comp_vect = kzalloc_obj(*dd->comp_vect); if (!dd->comp_vect) { ret = -ENOMEM; goto bail; diff --git a/drivers/infiniband/hw/hfi1/mad.c b/drivers/infiniband/hw/hfi1/mad.c index 961fa07116f0..03467e6c19a0 100644 --- a/drivers/infiniband/hw/hfi1/mad.c +++ b/drivers/infiniband/hw/hfi1/mad.c @@ -390,7 +390,7 @@ static struct trap_node *create_trap_node(u8 type, __be16 trap_num, u32 lid) { struct trap_node *trap; - trap = kzalloc(sizeof(*trap), GFP_ATOMIC); + trap = kzalloc_obj(*trap, GFP_ATOMIC); if (!trap) return NULL; @@ -3736,7 +3736,7 @@ static void apply_cc_state(struct hfi1_pportdata *ppd) { struct cc_state *old_cc_state, *new_cc_state; - new_cc_state = kzalloc(sizeof(*new_cc_state), GFP_KERNEL); + new_cc_state = kzalloc_obj(*new_cc_state); if (!new_cc_state) return; diff --git a/drivers/infiniband/hw/hfi1/msix.c b/drivers/infiniband/hw/hfi1/msix.c index 77d2ece9a9cb..3ac50ca4afcc 100644 --- a/drivers/infiniband/hw/hfi1/msix.c +++ b/drivers/infiniband/hw/hfi1/msix.c @@ -38,8 +38,7 @@ int msix_initialize(struct hfi1_devdata *dd) return ret; } - entries = kcalloc(total, sizeof(*dd->msix_info.msix_entries), - GFP_KERNEL); + entries = kzalloc_objs(*dd->msix_info.msix_entries, total); if (!entries) { pci_free_irq_vectors(dd->pcidev); return -ENOMEM; diff --git a/drivers/infiniband/hw/hfi1/pin_system.c b/drivers/infiniband/hw/hfi1/pin_system.c index cce56134519b..e62b4d9c7a0f 100644 --- a/drivers/infiniband/hw/hfi1/pin_system.c +++ b/drivers/infiniband/hw/hfi1/pin_system.c @@ -119,7 +119,7 @@ static int pin_system_pages(struct user_sdma_request *req, int pinned, cleared; struct page **pages; - pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, npages); if (!pages) return -ENOMEM; @@ -173,7 +173,7 @@ static int add_system_pinning(struct user_sdma_request *req, struct sdma_mmu_node *node; int ret; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOMEM; diff --git a/drivers/infiniband/hw/hfi1/pio.c b/drivers/infiniband/hw/hfi1/pio.c index 764286da2ce8..51afaac88c72 100644 --- a/drivers/infiniband/hw/hfi1/pio.c +++ b/drivers/infiniband/hw/hfi1/pio.c @@ -407,9 +407,8 @@ int init_send_contexts(struct hfi1_devdata *dd) dd->hw_to_sw = kmalloc_array(TXE_NUM_CONTEXTS, sizeof(u8), GFP_KERNEL); - dd->send_contexts = kcalloc(dd->num_send_contexts, - sizeof(struct send_context_info), - GFP_KERNEL); + dd->send_contexts = kzalloc_objs(struct send_context_info, + dd->num_send_contexts); if (!dd->send_contexts || !dd->hw_to_sw) { kfree(dd->hw_to_sw); kfree(dd->send_contexts); @@ -1883,8 +1882,7 @@ int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_scontexts) vl_scontexts[i] = sc_per_vl + (extra > 0 ? 1 : 0); } /* build new map */ - newmap = kzalloc(struct_size(newmap, map, roundup_pow_of_two(num_vls)), - GFP_KERNEL); + newmap = kzalloc_flex(*newmap, map, roundup_pow_of_two(num_vls)); if (!newmap) goto bail; newmap->actual_vls = num_vls; @@ -1898,9 +1896,7 @@ int pio_map_init(struct hfi1_devdata *dd, u8 port, u8 num_vls, u8 *vl_scontexts) int sz = roundup_pow_of_two(vl_scontexts[i]); /* only allocate once */ - newmap->map[i] = kzalloc(struct_size(newmap->map[i], - ksc, sz), - GFP_KERNEL); + newmap->map[i] = kzalloc_flex(*newmap->map[i], ksc, sz); if (!newmap->map[i]) goto bail; newmap->map[i]->mask = (1 << ilog2(sz)) - 1; @@ -2054,10 +2050,8 @@ int init_credit_return(struct hfi1_devdata *dd) int ret; int i; - dd->cr_base = kcalloc( - node_affinity.num_possible_nodes, - sizeof(struct credit_return_base), - GFP_KERNEL); + dd->cr_base = kzalloc_objs(struct credit_return_base, + node_affinity.num_possible_nodes); if (!dd->cr_base) { ret = -ENOMEM; goto done; diff --git a/drivers/infiniband/hw/hfi1/qsfp.c b/drivers/infiniband/hw/hfi1/qsfp.c index 3b7842a7f634..2b6d45d092bc 100644 --- a/drivers/infiniband/hw/hfi1/qsfp.c +++ b/drivers/infiniband/hw/hfi1/qsfp.c @@ -107,7 +107,7 @@ static struct hfi1_i2c_bus *init_i2c_bus(struct hfi1_devdata *dd, struct hfi1_i2c_bus *bus; int ret; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) return NULL; diff --git a/drivers/infiniband/hw/hfi1/sdma.c b/drivers/infiniband/hw/hfi1/sdma.c index 5cfa4f8fbf3d..e5f442938177 100644 --- a/drivers/infiniband/hw/hfi1/sdma.c +++ b/drivers/infiniband/hw/hfi1/sdma.c @@ -937,7 +937,7 @@ ssize_t sdma_set_cpu_to_sde_map(struct sdma_engine *sde, const char *buf, rht_node = rhashtable_lookup_fast(dd->sdma_rht, &cpu, sdma_rht_params); if (!rht_node) { - rht_node = kzalloc(sizeof(*rht_node), GFP_KERNEL); + rht_node = kzalloc_obj(*rht_node); if (!rht_node) { ret = -ENOMEM; goto out; @@ -1481,7 +1481,7 @@ int sdma_init(struct hfi1_devdata *dd, u8 port) if (ret < 0) goto bail; - tmp_sdma_rht = kzalloc(sizeof(*tmp_sdma_rht), GFP_KERNEL); + tmp_sdma_rht = kzalloc_obj(*tmp_sdma_rht); if (!tmp_sdma_rht) { ret = -ENOMEM; goto bail; @@ -3017,7 +3017,7 @@ static int _extend_sdma_tx_descs(struct hfi1_devdata *dd, struct sdma_txreq *tx) if (unlikely(tx->num_desc == MAX_DESC)) goto enomem; - descp = kmalloc_array(MAX_DESC, sizeof(struct sdma_desc), GFP_ATOMIC); + descp = kmalloc_objs(struct sdma_desc, MAX_DESC, GFP_ATOMIC); if (!descp) goto enomem; tx->descp = descp; diff --git a/drivers/infiniband/hw/hfi1/tid_rdma.c b/drivers/infiniband/hw/hfi1/tid_rdma.c index eafd2f157e32..90ddd59f1e1b 100644 --- a/drivers/infiniband/hw/hfi1/tid_rdma.c +++ b/drivers/infiniband/hw/hfi1/tid_rdma.c @@ -233,7 +233,7 @@ bool tid_rdma_conn_reply(struct rvt_qp *qp, u64 data) * * at the responder, 0 being returned to the requester so as to * disable TID RDMA at both the requester and the responder */ - remote = kzalloc(sizeof(*remote), GFP_ATOMIC); + remote = kzalloc_obj(*remote, GFP_ATOMIC); if (!remote) { ret = false; goto null; diff --git a/drivers/infiniband/hw/hfi1/user_exp_rcv.c b/drivers/infiniband/hw/hfi1/user_exp_rcv.c index 62b4f16dab27..5b01070ed66f 100644 --- a/drivers/infiniband/hw/hfi1/user_exp_rcv.c +++ b/drivers/infiniband/hw/hfi1/user_exp_rcv.c @@ -52,17 +52,14 @@ int hfi1_user_exp_rcv_init(struct hfi1_filedata *fd, { int ret = 0; - fd->entry_to_rb = kcalloc(uctxt->expected_count, - sizeof(*fd->entry_to_rb), - GFP_KERNEL); + fd->entry_to_rb = kzalloc_objs(*fd->entry_to_rb, uctxt->expected_count); if (!fd->entry_to_rb) return -ENOMEM; if (!HFI1_CAP_UGET_MASK(uctxt->flags, TID_UNMAP)) { fd->invalid_tid_idx = 0; - fd->invalid_tids = kcalloc(uctxt->expected_count, - sizeof(*fd->invalid_tids), - GFP_KERNEL); + fd->invalid_tids = kzalloc_objs(*fd->invalid_tids, + uctxt->expected_count); if (!fd->invalid_tids) { kfree(fd->entry_to_rb); fd->entry_to_rb = NULL; @@ -170,7 +167,7 @@ static int pin_rcv_pages(struct hfi1_filedata *fd, struct tid_user_buf *tidbuf) } /* Allocate the array of struct page pointers needed for pinning */ - pages = kcalloc(npages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, npages); if (!pages) return -ENOMEM; @@ -736,7 +733,7 @@ static int set_rcvarray_entry(struct hfi1_filedata *fd, * Allocate the node first so we can handle a potential * failure before we've programmed anything. */ - node = kzalloc(struct_size(node, pages, npages), GFP_KERNEL); + node = kzalloc_flex(*node, pages, npages); if (!node) return -ENOMEM; diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index 9b1aece1b080..8ea5ed918a02 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -120,7 +120,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, dd = uctxt->dd; - pq = kzalloc(sizeof(*pq), GFP_KERNEL); + pq = kzalloc_obj(*pq); if (!pq) return -ENOMEM; pq->dd = dd; @@ -135,9 +135,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, activate_packet_queue, NULL, NULL); pq->reqidx = 0; - pq->reqs = kcalloc(hfi1_sdma_comp_ring_size, - sizeof(*pq->reqs), - GFP_KERNEL); + pq->reqs = kzalloc_objs(*pq->reqs, hfi1_sdma_comp_ring_size); if (!pq->reqs) goto pq_reqs_nomem; @@ -158,7 +156,7 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, goto pq_txreq_nomem; } - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_obj(*cq); if (!cq) goto cq_nomem; diff --git a/drivers/infiniband/hw/hns/hns_roce_alloc.c b/drivers/infiniband/hw/hns/hns_roce_alloc.c index 6ee911f6885b..8e802f118bc9 100644 --- a/drivers/infiniband/hw/hns/hns_roce_alloc.c +++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c @@ -77,7 +77,7 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, return ERR_PTR(-EINVAL); gfp_flags = (flags & HNS_ROCE_BUF_NOSLEEP) ? GFP_ATOMIC : GFP_KERNEL; - buf = kzalloc(sizeof(*buf), gfp_flags); + buf = kzalloc_obj(*buf, gfp_flags); if (!buf) return ERR_PTR(-ENOMEM); @@ -93,7 +93,7 @@ struct hns_roce_buf *hns_roce_buf_alloc(struct hns_roce_dev *hr_dev, u32 size, ntrunk = DIV_ROUND_UP(size, 1 << buf->trunk_shift); } - trunks = kcalloc(ntrunk, sizeof(*trunks), gfp_flags); + trunks = kzalloc_objs(*trunks, ntrunk, gfp_flags); if (!trunks) { kfree(buf); return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/hns/hns_roce_bond.c b/drivers/infiniband/hw/hns/hns_roce_bond.c index cc85f3ce1f3e..f2b12ae13a58 100644 --- a/drivers/infiniband/hw/hns/hns_roce_bond.c +++ b/drivers/infiniband/hw/hns/hns_roce_bond.c @@ -253,7 +253,7 @@ static struct hns_roce_die_info *alloc_die_info(int bus_num) struct hns_roce_die_info *die_info; int ret; - die_info = kzalloc(sizeof(*die_info), GFP_KERNEL); + die_info = kzalloc_obj(*die_info); if (!die_info) return NULL; @@ -855,7 +855,7 @@ int hns_roce_alloc_bond_grp(struct hns_roce_dev *hr_dev) return 0; for (i = 0; i < ROCE_BOND_NUM_MAX; i++) { - bond_grp = kvzalloc(sizeof(*bond_grp), GFP_KERNEL); + bond_grp = kvzalloc_obj(*bond_grp); if (!bond_grp) { ret = -ENOMEM; goto mem_err; diff --git a/drivers/infiniband/hw/hns/hns_roce_cmd.c b/drivers/infiniband/hw/hns/hns_roce_cmd.c index 873e8a69a1b9..1943031b0dbe 100644 --- a/drivers/infiniband/hw/hns/hns_roce_cmd.c +++ b/drivers/infiniband/hw/hns/hns_roce_cmd.c @@ -219,7 +219,7 @@ int hns_roce_cmd_use_events(struct hns_roce_dev *hr_dev) int i; hr_cmd->context = - kcalloc(hr_cmd->max_cmds, sizeof(*hr_cmd->context), GFP_KERNEL); + kzalloc_objs(*hr_cmd->context, hr_cmd->max_cmds); if (!hr_cmd->context) { hr_dev->cmd_mod = 0; return -ENOMEM; @@ -254,7 +254,7 @@ hns_roce_alloc_cmd_mailbox(struct hns_roce_dev *hr_dev) { struct hns_roce_cmd_mailbox *mailbox; - mailbox = kmalloc(sizeof(*mailbox), GFP_KERNEL); + mailbox = kmalloc_obj(*mailbox); if (!mailbox) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/hns/hns_roce_db.c b/drivers/infiniband/hw/hns/hns_roce_db.c index 5c4c0480832b..f64023f5cf0a 100644 --- a/drivers/infiniband/hw/hns/hns_roce_db.c +++ b/drivers/infiniband/hw/hns/hns_roce_db.c @@ -21,7 +21,7 @@ int hns_roce_db_map_user(struct hns_roce_ucontext *context, unsigned long virt, if (page->user_virt == page_addr) goto found; - page = kmalloc(sizeof(*page), GFP_KERNEL); + page = kmalloc_obj(*page); if (!page) { ret = -ENOMEM; goto out; @@ -72,7 +72,7 @@ static struct hns_roce_db_pgdir *hns_roce_alloc_db_pgdir( { struct hns_roce_db_pgdir *pgdir; - pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL); + pgdir = kzalloc_obj(*pgdir); if (!pgdir) return NULL; diff --git a/drivers/infiniband/hw/hns/hns_roce_hem.c b/drivers/infiniband/hw/hns/hns_roce_hem.c index 3d479c63b117..4eaaedcc7652 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hem.c +++ b/drivers/infiniband/hw/hns/hns_roce_hem.c @@ -262,7 +262,7 @@ static struct hns_roce_hem *hns_roce_alloc_hem(struct hns_roce_dev *hr_dev, return NULL; } - hem = kmalloc(sizeof(*hem), GFP_KERNEL); + hem = kmalloc_obj(*hem); if (!hem) return NULL; @@ -737,7 +737,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, obj_per_chunk = table->table_chunk_size / obj_size; num_hem = DIV_ROUND_UP(nobj, obj_per_chunk); - table->hem = kcalloc(num_hem, sizeof(*table->hem), GFP_KERNEL); + table->hem = kzalloc_objs(*table->hem, num_hem); if (!table->hem) return -ENOMEM; } else { @@ -763,8 +763,7 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, if (type >= HEM_TYPE_MTT) num_bt_l0 = bt_chunk_num; - table->hem = kcalloc(num_hem, sizeof(*table->hem), - GFP_KERNEL); + table->hem = kzalloc_objs(*table->hem, num_hem); if (!table->hem) goto err_kcalloc_hem_buf; @@ -778,9 +777,8 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, if (!table->bt_l1) goto err_kcalloc_bt_l1; - table->bt_l1_dma_addr = kcalloc(num_bt_l1, - sizeof(*table->bt_l1_dma_addr), - GFP_KERNEL); + table->bt_l1_dma_addr = kzalloc_objs(*table->bt_l1_dma_addr, + num_bt_l1); if (!table->bt_l1_dma_addr) goto err_kcalloc_l1_dma; @@ -793,9 +791,8 @@ int hns_roce_init_hem_table(struct hns_roce_dev *hr_dev, if (!table->bt_l0) goto err_kcalloc_bt_l0; - table->bt_l0_dma_addr = kcalloc(num_bt_l0, - sizeof(*table->bt_l0_dma_addr), - GFP_KERNEL); + table->bt_l0_dma_addr = kzalloc_objs(*table->bt_l0_dma_addr, + num_bt_l0); if (!table->bt_l0_dma_addr) goto err_kcalloc_l0_dma; } @@ -939,7 +936,7 @@ hem_list_alloc_item(struct hns_roce_dev *hr_dev, int start, int end, int count, { struct hns_roce_hem_item *hem; - hem = kzalloc(sizeof(*hem), GFP_KERNEL); + hem = kzalloc_obj(*hem); if (!hem) return NULL; diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c index 5d0a8662249d..fa36700d0db2 100644 --- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.c @@ -1948,7 +1948,7 @@ static int hns_roce_hw_v2_query_counter(struct hns_roce_dev *hr_dev, return -EINVAL; desc_num = DIV_ROUND_UP(HNS_ROCE_HW_CNT_TOTAL, CNT_PER_DESC); - desc = kcalloc(desc_num, sizeof(*desc), GFP_KERNEL); + desc = kzalloc_objs(*desc, desc_num); if (!desc) return -ENOMEM; @@ -2881,7 +2881,7 @@ static struct ib_pd *free_mr_init_pd(struct hns_roce_dev *hr_dev) struct hns_roce_pd *hr_pd; struct ib_pd *pd; - hr_pd = kzalloc(sizeof(*hr_pd), GFP_KERNEL); + hr_pd = kzalloc_obj(*hr_pd); if (!hr_pd) return NULL; pd = &hr_pd->ibpd; @@ -2912,7 +2912,7 @@ static struct ib_cq *free_mr_init_cq(struct hns_roce_dev *hr_dev) cq_init_attr.cqe = HNS_ROCE_FREE_MR_USED_CQE_NUM; - hr_cq = kzalloc(sizeof(*hr_cq), GFP_KERNEL); + hr_cq = kzalloc_obj(*hr_cq); if (!hr_cq) return NULL; @@ -2945,7 +2945,7 @@ static int free_mr_init_qp(struct hns_roce_dev *hr_dev, struct ib_cq *cq, struct ib_qp *qp; int ret; - hr_qp = kzalloc(sizeof(*hr_qp), GFP_KERNEL); + hr_qp = kzalloc_obj(*hr_qp); if (!hr_qp) return -ENOMEM; @@ -5021,7 +5021,7 @@ static int alloc_dip_entry(struct xarray *dip_xa, u32 qpn) if (hr_dip) return 0; - hr_dip = kzalloc(sizeof(*hr_dip), GFP_KERNEL); + hr_dip = kzalloc_obj(*hr_dip); if (!hr_dip) return -ENOMEM; @@ -5635,8 +5635,8 @@ static int hns_roce_v2_modify_qp(struct ib_qp *ibqp, * we should set all bits of the relevant fields in context mask to * 0 at the same time, else set them to 0x1. */ - context = kvzalloc(sizeof(*context), GFP_KERNEL); - qpc_mask = kvzalloc(sizeof(*qpc_mask), GFP_KERNEL); + context = kvzalloc_obj(*context); + qpc_mask = kvzalloc_obj(*qpc_mask); if (!context || !qpc_mask) goto out; @@ -6450,7 +6450,7 @@ static void hns_roce_v2_init_irq_work(struct hns_roce_dev *hr_dev, { struct hns_roce_work *irq_work; - irq_work = kzalloc(sizeof(struct hns_roce_work), GFP_ATOMIC); + irq_work = kzalloc_obj(struct hns_roce_work, GFP_ATOMIC); if (!irq_work) return; @@ -7107,7 +7107,7 @@ static int hns_roce_v2_init_eq_table(struct hns_roce_dev *hr_dev) eq_num = comp_num + aeq_num; irq_num = eq_num + other_num; - eq_table->eq = kcalloc(eq_num, sizeof(*eq_table->eq), GFP_KERNEL); + eq_table->eq = kzalloc_objs(*eq_table->eq, eq_num); if (!eq_table->eq) return -ENOMEM; @@ -7309,7 +7309,7 @@ static int __hns_roce_hw_v2_init_instance(struct hnae3_handle *handle) if (!hr_dev) return -ENOMEM; - hr_dev->priv = kzalloc(sizeof(struct hns_roce_v2_priv), GFP_KERNEL); + hr_dev->priv = kzalloc_obj(struct hns_roce_v2_priv); if (!hr_dev->priv) { ret = -ENOMEM; goto error_failed_kzalloc; diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c index a3490bab297a..1148d732f94f 100644 --- a/drivers/infiniband/hw/hns/hns_roce_main.c +++ b/drivers/infiniband/hw/hns/hns_roce_main.c @@ -366,7 +366,7 @@ hns_roce_user_mmap_entry_insert(struct ib_ucontext *ucontext, u64 address, struct hns_user_mmap_entry *entry; int ret; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -1153,8 +1153,7 @@ void hns_roce_handle_device_err(struct hns_roce_dev *hr_dev) static int hns_roce_alloc_dfx_cnt(struct hns_roce_dev *hr_dev) { - hr_dev->dfx_cnt = kvcalloc(HNS_ROCE_DFX_CNT_TOTAL, sizeof(atomic64_t), - GFP_KERNEL); + hr_dev->dfx_cnt = kvzalloc_objs(atomic64_t, HNS_ROCE_DFX_CNT_TOTAL); if (!hr_dev->dfx_cnt) return -ENOMEM; diff --git a/drivers/infiniband/hw/hns/hns_roce_mr.c b/drivers/infiniband/hw/hns/hns_roce_mr.c index 31cb8699e198..896af1828a38 100644 --- a/drivers/infiniband/hw/hns/hns_roce_mr.c +++ b/drivers/infiniband/hw/hns/hns_roce_mr.c @@ -200,7 +200,7 @@ struct ib_mr *hns_roce_get_dma_mr(struct ib_pd *pd, int acc) struct hns_roce_mr *mr; int ret; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -243,7 +243,7 @@ struct ib_mr *hns_roce_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_out; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { ret = -ENOMEM; goto err_out; @@ -395,7 +395,7 @@ struct ib_mr *hns_roce_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, return ERR_PTR(-EINVAL); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -458,8 +458,8 @@ int hns_roce_map_mr_sg(struct ib_mr *ibmr, struct scatterlist *sg, int sg_nents, return sg_num; mr->npages = 0; - mr->page_list = kvcalloc(mr->pbl_mtr.hem_cfg.buf_pg_count, - sizeof(dma_addr_t), GFP_KERNEL); + mr->page_list = kvzalloc_objs(dma_addr_t, + mr->pbl_mtr.hem_cfg.buf_pg_count); if (!mr->page_list) return sg_num; @@ -650,7 +650,7 @@ static int mtr_map_bufs(struct hns_roce_dev *hr_dev, struct hns_roce_mtr *mtr) page_shift = need_split_huge_page(mtr) ? HNS_HW_PAGE_SHIFT : mtr->hem_cfg.buf_pg_shift; /* alloc a tmp array to store buffer's dma address */ - pages = kvcalloc(page_count, sizeof(dma_addr_t), GFP_KERNEL); + pages = kvzalloc_objs(dma_addr_t, page_count); if (!pages) return -ENOMEM; diff --git a/drivers/infiniband/hw/ionic/ionic_admin.c b/drivers/infiniband/hw/ionic/ionic_admin.c index 2537aa55d12d..37e24450d129 100644 --- a/drivers/infiniband/hw/ionic/ionic_admin.c +++ b/drivers/infiniband/hw/ionic/ionic_admin.c @@ -520,7 +520,7 @@ static struct ionic_vcq *ionic_create_rdma_admincq(struct ionic_ibdev *dev, struct ionic_cq *cq; int rc; - vcq = kzalloc(sizeof(*vcq), GFP_KERNEL); + vcq = kzalloc_obj(*vcq); if (!vcq) return ERR_PTR(-ENOMEM); @@ -558,7 +558,7 @@ static struct ionic_aq *__ionic_create_rdma_adminq(struct ionic_ibdev *dev, struct ionic_aq *aq; int rc; - aq = kzalloc(sizeof(*aq), GFP_KERNEL); + aq = kzalloc_obj(*aq); if (!aq) return ERR_PTR(-ENOMEM); @@ -575,7 +575,7 @@ static struct ionic_aq *__ionic_create_rdma_adminq(struct ionic_ibdev *dev, ionic_queue_dbell_init(&aq->q, aq->aqid); - aq->q_wr = kcalloc((u32)aq->q.mask + 1, sizeof(*aq->q_wr), GFP_KERNEL); + aq->q_wr = kzalloc_objs(*aq->q_wr, (u32)aq->q.mask + 1); if (!aq->q_wr) { rc = -ENOMEM; goto err_wr; @@ -983,7 +983,7 @@ static struct ionic_eq *ionic_create_eq(struct ionic_ibdev *dev, int eqid) struct ionic_eq *eq; int rc; - eq = kzalloc(sizeof(*eq), GFP_KERNEL); + eq = kzalloc_obj(*eq); if (!eq) return ERR_PTR(-ENOMEM); @@ -1095,8 +1095,7 @@ int ionic_create_rdma_admin(struct ionic_ibdev *dev) goto out; } - dev->eq_vec = kmalloc_array(dev->lif_cfg.eq_count, sizeof(*dev->eq_vec), - GFP_KERNEL); + dev->eq_vec = kmalloc_objs(*dev->eq_vec, dev->lif_cfg.eq_count); if (!dev->eq_vec) { rc = -ENOMEM; goto out; @@ -1126,8 +1125,7 @@ int ionic_create_rdma_admin(struct ionic_ibdev *dev) dev->lif_cfg.eq_count = eq_i; - dev->aq_vec = kmalloc_array(dev->lif_cfg.aq_count, sizeof(*dev->aq_vec), - GFP_KERNEL); + dev->aq_vec = kmalloc_objs(*dev->aq_vec, dev->lif_cfg.aq_count); if (!dev->aq_vec) { rc = -ENOMEM; goto out; diff --git a/drivers/infiniband/hw/ionic/ionic_controlpath.c b/drivers/infiniband/hw/ionic/ionic_controlpath.c index ea12d9b8e125..4842931f5316 100644 --- a/drivers/infiniband/hw/ionic/ionic_controlpath.c +++ b/drivers/infiniband/hw/ionic/ionic_controlpath.c @@ -343,7 +343,7 @@ ionic_mmap_entry_insert(struct ionic_ctx *ctx, unsigned long size, struct ionic_mmap_entry *entry; int rc; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -852,7 +852,7 @@ struct ib_mr *ionic_get_dma_mr(struct ib_pd *ibpd, int access) struct ionic_pd *pd = to_ionic_pd(ibpd); struct ionic_mr *mr; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -878,7 +878,7 @@ struct ib_mr *ionic_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, if (dmah) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -945,7 +945,7 @@ struct ib_mr *ionic_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 offset, if (dmah) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1039,7 +1039,7 @@ struct ib_mr *ionic_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type type, if (type != IB_MR_TYPE_MEM_REG) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1218,7 +1218,7 @@ int ionic_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, rdma_udata_to_drv_context(udata, struct ionic_ctx, ibctx); struct ionic_vcq *vcq = to_ionic_vcq(ibcq); struct ionic_tbl_buf buf = {}; - struct ionic_cq_resp resp; + struct ionic_cq_resp resp = {}; struct ionic_cq_req req; int udma_idx = 0, rc; @@ -1868,9 +1868,7 @@ static int ionic_qp_sq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx, ionic_queue_dbell_init(&qp->sq, qp->qpid); - qp->sq_meta = kmalloc_array((u32)qp->sq.mask + 1, - sizeof(*qp->sq_meta), - GFP_KERNEL); + qp->sq_meta = kmalloc_objs(*qp->sq_meta, (u32)qp->sq.mask + 1); if (!qp->sq_meta) { rc = -ENOMEM; goto err_sq_meta; @@ -2083,9 +2081,7 @@ static int ionic_qp_rq_init(struct ionic_ibdev *dev, struct ionic_ctx *ctx, ionic_queue_dbell_init(&qp->rq, qp->qpid); - qp->rq_meta = kmalloc_array((u32)qp->rq.mask + 1, - sizeof(*qp->rq_meta), - GFP_KERNEL); + qp->rq_meta = kmalloc_objs(*qp->rq_meta, (u32)qp->rq.mask + 1); if (!qp->rq_meta) { rc = -ENOMEM; goto err_rq_meta; @@ -2205,7 +2201,7 @@ int ionic_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attr, qp->has_ah = attr->qp_type == IB_QPT_RC; if (qp->has_ah) { - qp->hdr = kzalloc(sizeof(*qp->hdr), GFP_KERNEL); + qp->hdr = kzalloc_obj(*qp->hdr); if (!qp->hdr) { rc = -ENOMEM; goto err_ah_alloc; diff --git a/drivers/infiniband/hw/ionic/ionic_hw_stats.c b/drivers/infiniband/hw/ionic/ionic_hw_stats.c index 244a80dde08f..f72c9837e135 100644 --- a/drivers/infiniband/hw/ionic/ionic_hw_stats.c +++ b/drivers/infiniband/hw/ionic/ionic_hw_stats.c @@ -155,9 +155,7 @@ static int ionic_init_hw_stats(struct ionic_ibdev *dev) dev->hw_stats_count = hw_stats_count; /* alloc and init array of names, for alloc_hw_stats */ - dev->hw_stats_hdrs = kcalloc(hw_stats_count, - sizeof(*dev->hw_stats_hdrs), - GFP_KERNEL); + dev->hw_stats_hdrs = kzalloc_objs(*dev->hw_stats_hdrs, hw_stats_count); if (!dev->hw_stats_hdrs) { rc = -ENOMEM; goto err_dma; @@ -241,7 +239,7 @@ ionic_counter_alloc_stats(struct rdma_counter *counter) struct ionic_counter *cntr; int err; - cntr = kzalloc(sizeof(*cntr), GFP_KERNEL); + cntr = kzalloc_obj(*cntr); if (!cntr) return NULL; @@ -402,8 +400,7 @@ static int ionic_alloc_counters(struct ionic_ibdev *dev) cs->queue_stats_count = hw_stats_count; /* alloc and init array of names */ - cs->stats_hdrs = kcalloc(hw_stats_count, sizeof(*cs->stats_hdrs), - GFP_KERNEL); + cs->stats_hdrs = kzalloc_objs(*cs->stats_hdrs, hw_stats_count); if (!cs->stats_hdrs) { rc = -ENOMEM; goto err_dma; @@ -449,8 +446,7 @@ void ionic_stats_init(struct ionic_ibdev *dev) } if (stats_type & IONIC_LIF_RDMA_STAT_QP) { - dev->counter_stats = kzalloc(sizeof(*dev->counter_stats), - GFP_KERNEL); + dev->counter_stats = kzalloc_obj(*dev->counter_stats); if (!dev->counter_stats) return; diff --git a/drivers/infiniband/hw/ionic/ionic_ibdev.c b/drivers/infiniband/hw/ionic/ionic_ibdev.c index 164046d00e5d..bd4c73e530d0 100644 --- a/drivers/infiniband/hw/ionic/ionic_ibdev.c +++ b/drivers/infiniband/hw/ionic/ionic_ibdev.c @@ -81,6 +81,8 @@ static int ionic_query_port(struct ib_device *ibdev, u32 port, return -EINVAL; ndev = ib_device_get_netdev(ibdev, port); + if (!ndev) + return -ENODEV; if (netif_running(ndev) && netif_carrier_ok(ndev)) { attr->state = IB_PORT_ACTIVE; diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c index f4f4f92ba63a..3d084d4ff577 100644 --- a/drivers/infiniband/hw/irdma/cm.c +++ b/drivers/infiniband/hw/irdma/cm.c @@ -234,7 +234,7 @@ static struct irdma_cm_event *irdma_create_event(struct irdma_cm_node *cm_node, if (!cm_node->cm_id) return NULL; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return NULL; @@ -1136,7 +1136,7 @@ int irdma_schedule_cm_timer(struct irdma_cm_node *cm_node, u32 was_timer_set; unsigned long flags; - new_send = kzalloc(sizeof(*new_send), GFP_ATOMIC); + new_send = kzalloc_obj(*new_send, GFP_ATOMIC); if (!new_send) { if (type != IRDMA_TIMER_TYPE_CLOSE) irdma_free_sqbuf(vsi, sqbuf); @@ -1683,7 +1683,7 @@ static int irdma_add_mqh_6(struct irdma_device *iwdev, ibdev_dbg(&iwdev->ibdev, "CM: IP=%pI6, vlan_id=%d, MAC=%pM\n", &ifp->addr, rdma_vlan_dev_vlan_id(ip_dev), ip_dev->dev_addr); - child_listen_node = kzalloc(sizeof(*child_listen_node), GFP_KERNEL); + child_listen_node = kzalloc_obj(*child_listen_node); ibdev_dbg(&iwdev->ibdev, "CM: Allocating child listener %p\n", child_listen_node); if (!child_listen_node) { @@ -1771,7 +1771,7 @@ static int irdma_add_mqh_4(struct irdma_device *iwdev, "CM: Allocating child CM Listener forIP=%pI4, vlan_id=%d, MAC=%pM\n", &ifa->ifa_address, rdma_vlan_dev_vlan_id(ip_dev), ip_dev->dev_addr); - child_listen_node = kzalloc(sizeof(*child_listen_node), GFP_KERNEL); + child_listen_node = kzalloc_obj(*child_listen_node); cm_parent_listen_node->cm_core->stats_listen_nodes_created++; ibdev_dbg(&iwdev->ibdev, "CM: Allocating child listener %p\n", child_listen_node); @@ -2243,7 +2243,7 @@ irdma_make_cm_node(struct irdma_cm_core *cm_core, struct irdma_device *iwdev, struct net_device *netdev = iwdev->netdev; /* create an hte and cm_node for this instance */ - cm_node = kzalloc(sizeof(*cm_node), GFP_ATOMIC); + cm_node = kzalloc_obj(*cm_node, GFP_ATOMIC); if (!cm_node) return NULL; @@ -2967,7 +2967,7 @@ irdma_make_listen_node(struct irdma_cm_core *cm_core, /* create a CM listen node * 1/2 node to compare incoming traffic to */ - listener = kzalloc(sizeof(*listener), GFP_KERNEL); + listener = kzalloc_obj(*listener); if (!listener) return NULL; cm_core->stats_listen_nodes_created++; @@ -3444,7 +3444,7 @@ void irdma_cm_disconn(struct irdma_qp *iwqp) struct disconn_work *work; unsigned long flags; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return; diff --git a/drivers/infiniband/hw/irdma/hw.c b/drivers/infiniband/hw/irdma/hw.c index 31c67b753fc0..f4ae530f56db 100644 --- a/drivers/infiniband/hw/irdma/hw.c +++ b/drivers/infiniband/hw/irdma/hw.c @@ -1029,7 +1029,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) u16 maj_err, min_err; int i, status; - cqp->cqp_requests = kcalloc(sqsize, sizeof(*cqp->cqp_requests), GFP_KERNEL); + cqp->cqp_requests = kzalloc_objs(*cqp->cqp_requests, sqsize); if (!cqp->cqp_requests) return -ENOMEM; @@ -1039,8 +1039,7 @@ static int irdma_create_cqp(struct irdma_pci_f *rf) goto err_scratch; } - cqp->oop_op_array = kcalloc(sqsize, sizeof(*cqp->oop_op_array), - GFP_KERNEL); + cqp->oop_op_array = kzalloc_objs(*cqp->oop_op_array, sqsize); if (!cqp->oop_op_array) { status = -ENOMEM; goto err_oop; @@ -1366,7 +1365,7 @@ static int irdma_setup_ceq_0(struct irdma_pci_f *rf) u32 num_ceqs; num_ceqs = min(rf->msix_count, rf->sc_dev.hmc_fpm_misc.max_ceqs); - rf->ceqlist = kcalloc(num_ceqs, sizeof(*rf->ceqlist), GFP_KERNEL); + rf->ceqlist = kzalloc_objs(*rf->ceqlist, num_ceqs); if (!rf->ceqlist) { status = -ENOMEM; goto exit; @@ -2466,7 +2465,7 @@ struct irdma_apbvt_entry *irdma_add_apbvt(struct irdma_device *iwdev, u16 port) return entry; } - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) { spin_unlock_irqrestore(&cm_core->apbvt_lock, flags); return NULL; diff --git a/drivers/infiniband/hw/irdma/i40iw_if.c b/drivers/infiniband/hw/irdma/i40iw_if.c index 15e036ddaffb..4ff3ad7856aa 100644 --- a/drivers/infiniband/hw/irdma/i40iw_if.c +++ b/drivers/infiniband/hw/irdma/i40iw_if.c @@ -120,7 +120,7 @@ static int i40iw_open(struct i40e_info *cdev_info, struct i40e_client *client) if (!iwdev) return -ENOMEM; - iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL); + iwdev->rf = kzalloc_obj(*rf); if (!iwdev->rf) { ib_dealloc_device(&iwdev->ibdev); return -ENOMEM; diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c b/drivers/infiniband/hw/irdma/icrdma_if.c index b49fd9cf2476..2172a2092e3f 100644 --- a/drivers/infiniband/hw/irdma/icrdma_if.c +++ b/drivers/infiniband/hw/irdma/icrdma_if.c @@ -167,8 +167,7 @@ static int icrdma_init_interrupts(struct irdma_pci_f *rf, struct iidc_rdma_core_ int i; rf->msix_count = num_online_cpus() + IRDMA_NUM_AEQ_MSIX; - rf->msix_entries = kcalloc(rf->msix_count, sizeof(*rf->msix_entries), - GFP_KERNEL); + rf->msix_entries = kzalloc_objs(*rf->msix_entries, rf->msix_count); if (!rf->msix_entries) return -ENOMEM; @@ -258,7 +257,7 @@ static int icrdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary iwdev = ib_alloc_device(irdma_device, ibdev); if (!iwdev) return -ENOMEM; - iwdev->rf = kzalloc(sizeof(*rf), GFP_KERNEL); + iwdev->rf = kzalloc_obj(*rf); if (!iwdev->rf) { ib_dealloc_device(&iwdev->ibdev); return -ENOMEM; diff --git a/drivers/infiniband/hw/irdma/ig3rdma_if.c b/drivers/infiniband/hw/irdma/ig3rdma_if.c index e1d6670d9396..b3e49e5bef10 100644 --- a/drivers/infiniband/hw/irdma/ig3rdma_if.c +++ b/drivers/infiniband/hw/irdma/ig3rdma_if.c @@ -101,8 +101,7 @@ static int ig3rdma_cfg_regions(struct irdma_hw *hw, return -ENOMEM; hw->num_io_regions = le16_to_cpu(idc_priv->num_memory_regions); - hw->io_regs = kcalloc(hw->num_io_regions, - sizeof(struct irdma_mmio_region), GFP_KERNEL); + hw->io_regs = kzalloc_objs(struct irdma_mmio_region, hw->num_io_regions); if (!hw->io_regs) { iounmap(hw->rdma_reg.addr); @@ -175,7 +174,7 @@ static int ig3rdma_core_probe(struct auxiliary_device *aux_dev, struct irdma_pci_f *rf; int err; - rf = kzalloc(sizeof(*rf), GFP_KERNEL); + rf = kzalloc_obj(*rf); if (!rf) return -ENOMEM; diff --git a/drivers/infiniband/hw/irdma/utils.c b/drivers/infiniband/hw/irdma/utils.c index 960432bf7fc9..ab8c5284d4be 100644 --- a/drivers/infiniband/hw/irdma/utils.c +++ b/drivers/infiniband/hw/irdma/utils.c @@ -438,7 +438,7 @@ struct irdma_cqp_request *irdma_alloc_and_get_cqp_request(struct irdma_cqp *cqp, } spin_unlock_irqrestore(&cqp->req_lock, flags); if (!cqp_request) { - cqp_request = kzalloc(sizeof(*cqp_request), GFP_ATOMIC); + cqp_request = kzalloc_obj(*cqp_request, GFP_ATOMIC); if (cqp_request) { cqp_request->dynamic = true; if (wait) @@ -2025,7 +2025,7 @@ int irdma_puda_create_ah(struct irdma_sc_dev *dev, struct irdma_pci_f *rf = dev_to_rf(dev); int err; - ah = kzalloc(sizeof(*ah), GFP_ATOMIC); + ah = kzalloc_obj(*ah, GFP_ATOMIC); *ah_ret = ah; if (!ah) return -ENOMEM; @@ -2431,7 +2431,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp) spin_lock_irqsave(&iwqp->lock, flags2); while (IRDMA_RING_MORE_WORK(*sq_ring)) { - cmpl = kzalloc(sizeof(*cmpl), GFP_ATOMIC); + cmpl = kzalloc_obj(*cmpl, GFP_ATOMIC); if (!cmpl) { spin_unlock_irqrestore(&iwqp->lock, flags2); spin_unlock_irqrestore(&iwscq->lock, flags1); @@ -2475,7 +2475,7 @@ void irdma_generate_flush_completions(struct irdma_qp *iwqp) spin_lock_irqsave(&iwqp->lock, flags2); while (IRDMA_RING_MORE_WORK(*rq_ring)) { - cmpl = kzalloc(sizeof(*cmpl), GFP_ATOMIC); + cmpl = kzalloc_obj(*cmpl, GFP_ATOMIC); if (!cmpl) { spin_unlock_irqrestore(&iwqp->lock, flags2); spin_unlock_irqrestore(&iwrcq->lock, flags1); diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c index cf8d19150574..7251cd7a2147 100644 --- a/drivers/infiniband/hw/irdma/verbs.c +++ b/drivers/infiniband/hw/irdma/verbs.c @@ -157,7 +157,7 @@ static struct rdma_user_mmap_entry* irdma_user_mmap_entry_insert(struct irdma_ucontext *ucontext, u64 bar_offset, enum irdma_mmap_flag mmap_flag, u64 *mmap_offset) { - struct irdma_user_mmap_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct irdma_user_mmap_entry *entry = kzalloc_obj(*entry); int ret; if (!entry) @@ -709,12 +709,12 @@ static int irdma_setup_kmode_qp(struct irdma_device *iwdev, return status; iwqp->kqp.sq_wrid_mem = - kcalloc(ukinfo->sq_depth, sizeof(*iwqp->kqp.sq_wrid_mem), GFP_KERNEL); + kzalloc_objs(*iwqp->kqp.sq_wrid_mem, ukinfo->sq_depth); if (!iwqp->kqp.sq_wrid_mem) return -ENOMEM; iwqp->kqp.rq_wrid_mem = - kcalloc(ukinfo->rq_depth, sizeof(*iwqp->kqp.rq_wrid_mem), GFP_KERNEL); + kzalloc_objs(*iwqp->kqp.rq_wrid_mem, ukinfo->rq_depth); if (!iwqp->kqp.rq_wrid_mem) { kfree(iwqp->kqp.sq_wrid_mem); @@ -2109,7 +2109,7 @@ static int irdma_resize_cq(struct ib_cq *ibcq, int entries, info.cq_base = kmem_buf.va; info.cq_pa = kmem_buf.pa; - cq_buf = kzalloc(sizeof(*cq_buf), GFP_KERNEL); + cq_buf = kzalloc_obj(*cq_buf); if (!cq_buf) { ret = -ENOMEM; goto error; @@ -3151,7 +3151,7 @@ static struct ib_mr *irdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, u32 stag; int err_code; - iwmr = kzalloc(sizeof(*iwmr), GFP_KERNEL); + iwmr = kzalloc_obj(*iwmr); if (!iwmr) return ERR_PTR(-ENOMEM); @@ -3368,7 +3368,7 @@ static struct irdma_mr *irdma_alloc_iwmr(struct ib_umem *region, struct irdma_mr *iwmr; unsigned long pgsz_bitmap; - iwmr = kzalloc(sizeof(*iwmr), GFP_KERNEL); + iwmr = kzalloc_obj(*iwmr); if (!iwmr) return ERR_PTR(-ENOMEM); @@ -3807,7 +3807,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access u32 stag; int ret; - iwmr = kzalloc(sizeof(*iwmr), GFP_KERNEL); + iwmr = kzalloc_obj(*iwmr); if (!iwmr) return ERR_PTR(-ENOMEM); @@ -4849,7 +4849,7 @@ static int irdma_attach_mcast(struct ib_qp *ibqp, union ib_gid *ibgid, u16 lid) struct irdma_dma_mem *dma_mem_mc; spin_unlock_irqrestore(&rf->qh_list_lock, flags); - mc_qht_elem = kzalloc(sizeof(*mc_qht_elem), GFP_KERNEL); + mc_qht_elem = kzalloc_obj(*mc_qht_elem); if (!mc_qht_elem) return -ENOMEM; @@ -5212,7 +5212,7 @@ static int irdma_create_user_ah(struct ib_ah *ibah, #define IRDMA_CREATE_AH_MIN_RESP_LEN offsetofend(struct irdma_create_ah_resp, rsvd) struct irdma_ah *ah = container_of(ibah, struct irdma_ah, ibah); struct irdma_device *iwdev = to_iwdev(ibah->pd->device); - struct irdma_create_ah_resp uresp; + struct irdma_create_ah_resp uresp = {}; struct irdma_ah *parent_ah; int err; diff --git a/drivers/infiniband/hw/mana/cq.c b/drivers/infiniband/hw/mana/cq.c index 974dd610dcbf..b2749f971cd0 100644 --- a/drivers/infiniband/hw/mana/cq.c +++ b/drivers/infiniband/hw/mana/cq.c @@ -147,7 +147,7 @@ int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq) if (cq->queue.kmem) gdma_cq = cq->queue.kmem; else - gdma_cq = kzalloc(sizeof(*gdma_cq), GFP_KERNEL); + gdma_cq = kzalloc_obj(*gdma_cq); if (!gdma_cq) return -ENOMEM; diff --git a/drivers/infiniband/hw/mana/main.c b/drivers/infiniband/hw/mana/main.c index fac159f7128d..8d99cd00f002 100644 --- a/drivers/infiniband/hw/mana/main.c +++ b/drivers/infiniband/hw/mana/main.c @@ -793,8 +793,8 @@ int mana_ib_create_eqs(struct mana_ib_dev *mdev) if (err) return err; - mdev->eqs = kcalloc(mdev->ib_dev.num_comp_vectors, sizeof(struct gdma_queue *), - GFP_KERNEL); + mdev->eqs = kzalloc_objs(struct gdma_queue *, + mdev->ib_dev.num_comp_vectors); if (!mdev->eqs) { err = -ENOMEM; goto destroy_fatal_eq; diff --git a/drivers/infiniband/hw/mana/mr.c b/drivers/infiniband/hw/mana/mr.c index f979f26adc3b..9613b225dad4 100644 --- a/drivers/infiniband/hw/mana/mr.c +++ b/drivers/infiniband/hw/mana/mr.c @@ -137,7 +137,7 @@ struct ib_mr *mana_ib_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, if (access_flags & ~VALID_MR_FLAGS) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -221,7 +221,7 @@ struct ib_mr *mana_ib_reg_user_mr_dmabuf(struct ib_pd *ibpd, u64 start, u64 leng if (access_flags & ~VALID_MR_FLAGS) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -286,7 +286,7 @@ struct ib_mr *mana_ib_get_dma_mr(struct ib_pd *ibpd, int access_flags) if (access_flags & ~VALID_DMA_MR_FLAGS) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -360,7 +360,7 @@ struct ib_dm *mana_ib_alloc_dm(struct ib_device *ibdev, struct mana_ib_dm *dm; int err; - dm = kzalloc(sizeof(*dm), GFP_KERNEL); + dm = kzalloc_obj(*dm); if (!dm) return ERR_PTR(-ENOMEM); @@ -425,7 +425,7 @@ struct ib_mr *mana_ib_reg_dm_mr(struct ib_pd *ibpd, struct ib_dm *ibdm, if (attr->access_flags & ~VALID_MR_FLAGS) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mana/qp.c b/drivers/infiniband/hw/mana/qp.c index 48c1f4977f21..82f84f7ad37a 100644 --- a/drivers/infiniband/hw/mana/qp.c +++ b/drivers/infiniband/hw/mana/qp.c @@ -164,8 +164,7 @@ static int mana_ib_create_qp_rss(struct ib_qp *ibqp, struct ib_pd *pd, ibdev_dbg(&mdev->ib_dev, "rx_hash_function %d port %d\n", ucmd.rx_hash_function, port); - mana_ind_table = kcalloc(ind_tbl_size, sizeof(mana_handle_t), - GFP_KERNEL); + mana_ind_table = kzalloc_objs(mana_handle_t, ind_tbl_size); if (!mana_ind_table) { ret = -ENOMEM; goto fail; diff --git a/drivers/infiniband/hw/mana/wq.c b/drivers/infiniband/hw/mana/wq.c index f959f4b9244f..6206244f762e 100644 --- a/drivers/infiniband/hw/mana/wq.c +++ b/drivers/infiniband/hw/mana/wq.c @@ -25,7 +25,7 @@ struct ib_wq *mana_ib_create_wq(struct ib_pd *pd, return ERR_PTR(err); } - wq = kzalloc(sizeof(*wq), GFP_KERNEL); + wq = kzalloc_obj(*wq); if (!wq) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mlx4/alias_GUID.c b/drivers/infiniband/hw/mlx4/alias_GUID.c index d7327735b8d0..c6e1b9e4122a 100644 --- a/drivers/infiniband/hw/mlx4/alias_GUID.c +++ b/drivers/infiniband/hw/mlx4/alias_GUID.c @@ -513,7 +513,7 @@ static int set_guid_rec(struct ib_device *ibdev, goto new_schedule; } - callback_context = kmalloc(sizeof *callback_context, GFP_KERNEL); + callback_context = kmalloc_obj(*callback_context); if (!callback_context) { err = -ENOMEM; resched_delay = HZ * 5; @@ -754,7 +754,7 @@ static void alias_guid_work(struct work_struct *work) alias_guid); struct mlx4_ib_dev *dev = container_of(ib_sriov, struct mlx4_ib_dev, sriov); - rec = kzalloc(sizeof *rec, GFP_KERNEL); + rec = kzalloc_obj(*rec); if (!rec) return; @@ -835,8 +835,7 @@ int mlx4_ib_init_alias_guid_service(struct mlx4_ib_dev *dev) if (!mlx4_is_master(dev->dev)) return 0; - dev->sriov.alias_guid.sa_client = - kzalloc(sizeof *dev->sriov.alias_guid.sa_client, GFP_KERNEL); + dev->sriov.alias_guid.sa_client = kzalloc_obj(*dev->sriov.alias_guid.sa_client); if (!dev->sriov.alias_guid.sa_client) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c index 03aacd526860..63a868a3822f 100644 --- a/drivers/infiniband/hw/mlx4/cm.c +++ b/drivers/infiniband/hw/mlx4/cm.c @@ -235,7 +235,7 @@ id_map_alloc(struct ib_device *ibdev, int slave_id, u32 sl_cm_id) struct id_map_entry *ent; struct mlx4_ib_sriov *sriov = &to_mdev(ibdev)->sriov; - ent = kmalloc(sizeof (struct id_map_entry), GFP_KERNEL); + ent = kmalloc_obj(struct id_map_entry); if (!ent) return ERR_PTR(-ENOMEM); @@ -376,7 +376,7 @@ static int alloc_rej_tmout(struct mlx4_ib_sriov *sriov, u32 rem_pv_cm_id, int sl } xa_unlock(&sriov->xa_rej_tmout); - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index c592374f4a58..d98892283065 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -300,7 +300,7 @@ static int mlx4_alloc_resize_buf(struct mlx4_ib_dev *dev, struct mlx4_ib_cq *cq, if (cq->resize_buf) return -EBUSY; - cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_KERNEL); + cq->resize_buf = kmalloc_obj(*cq->resize_buf); if (!cq->resize_buf) return -ENOMEM; @@ -328,7 +328,7 @@ static int mlx4_alloc_resize_umem(struct mlx4_ib_dev *dev, struct mlx4_ib_cq *cq if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) return -EFAULT; - cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_KERNEL); + cq->resize_buf = kmalloc_obj(*cq->resize_buf); if (!cq->resize_buf) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/doorbell.c b/drivers/infiniband/hw/mlx4/doorbell.c index 9bbd695a9fd5..8ba86b1e4e46 100644 --- a/drivers/infiniband/hw/mlx4/doorbell.c +++ b/drivers/infiniband/hw/mlx4/doorbell.c @@ -56,7 +56,7 @@ int mlx4_ib_db_map_user(struct ib_udata *udata, unsigned long virt, if (page->user_virt == (virt & PAGE_MASK)) goto found; - page = kmalloc(sizeof *page, GFP_KERNEL); + page = kmalloc_obj(*page); if (!page) { err = -ENOMEM; goto out; diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 91c714f72099..9aa6817aaf16 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -1133,8 +1133,8 @@ static void handle_slaves_guid_change(struct mlx4_ib_dev *dev, u32 port_num, if (!mlx4_is_mfunc(dev->dev) || !mlx4_is_master(dev->dev)) return; - in_mad = kmalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kmalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -1612,15 +1612,11 @@ static int mlx4_ib_alloc_pv_bufs(struct mlx4_ib_demux_pv_ctx *ctx, tun_qp = &ctx->qp[qp_type]; - tun_qp->ring = kcalloc(nmbr_bufs, - sizeof(struct mlx4_ib_buf), - GFP_KERNEL); + tun_qp->ring = kzalloc_objs(struct mlx4_ib_buf, nmbr_bufs); if (!tun_qp->ring) return -ENOMEM; - tun_qp->tx_ring = kcalloc(nmbr_bufs, - sizeof (struct mlx4_ib_tun_tx_buf), - GFP_KERNEL); + tun_qp->tx_ring = kzalloc_objs(struct mlx4_ib_tun_tx_buf, nmbr_bufs); if (!tun_qp->tx_ring) { kfree(tun_qp->ring); tun_qp->ring = NULL; @@ -1958,7 +1954,7 @@ static int alloc_pv_object(struct mlx4_ib_dev *dev, int slave, int port, struct mlx4_ib_demux_pv_ctx *ctx; *ret_ctx = NULL; - ctx = kzalloc(sizeof (struct mlx4_ib_demux_pv_ctx), GFP_KERNEL); + ctx = kzalloc_obj(struct mlx4_ib_demux_pv_ctx); if (!ctx) return -ENOMEM; @@ -2161,8 +2157,8 @@ static int mlx4_ib_alloc_demux_ctx(struct mlx4_ib_dev *dev, int ret = 0; int i; - ctx->tun = kcalloc(dev->dev->caps.sqp_demux, - sizeof (struct mlx4_ib_demux_pv_ctx *), GFP_KERNEL); + ctx->tun = kzalloc_objs(struct mlx4_ib_demux_pv_ctx *, + dev->dev->caps.sqp_demux); if (!ctx->tun) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index dd35e03402ab..63360c5a73c7 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c @@ -295,7 +295,8 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) if (free < 0) { ret = -ENOSPC; } else { - port_gid_table->gids[free].ctx = kmalloc(sizeof(*port_gid_table->gids[free].ctx), GFP_ATOMIC); + port_gid_table->gids[free].ctx = kmalloc_obj(*port_gid_table->gids[free].ctx, + GFP_ATOMIC); if (!port_gid_table->gids[free].ctx) { ret = -ENOMEM; } else { @@ -314,8 +315,7 @@ static int mlx4_ib_add_gid(const struct ib_gid_attr *attr, void **context) ctx->refcount++; } if (!ret && hw_update) { - gids = kmalloc_array(MLX4_MAX_PORT_GIDS, sizeof(*gids), - GFP_ATOMIC); + gids = kmalloc_objs(*gids, MLX4_MAX_PORT_GIDS, GFP_ATOMIC); if (!gids) { ret = -ENOMEM; *context = NULL; @@ -373,8 +373,7 @@ static int mlx4_ib_del_gid(const struct ib_gid_attr *attr, void **context) if (!ret && hw_update) { int i; - gids = kmalloc_array(MLX4_MAX_PORT_GIDS, sizeof(*gids), - GFP_ATOMIC); + gids = kmalloc_objs(*gids, MLX4_MAX_PORT_GIDS, GFP_ATOMIC); if (!gids) { ret = -ENOMEM; } else { @@ -462,8 +461,8 @@ static int mlx4_ib_query_device(struct ib_device *ibdev, resp.response_length = offsetof(typeof(resp), response_length) + sizeof(resp.response_length); - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); err = -ENOMEM; if (!in_mad || !out_mad) goto out; @@ -661,8 +660,8 @@ static int ib_link_query_port(struct ib_device *ibdev, u32 port, int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -840,8 +839,8 @@ int __mlx4_ib_query_gid(struct ib_device *ibdev, u32 port, int index, int clear = 0; int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -909,8 +908,8 @@ static int mlx4_ib_query_sl2vl(struct ib_device *ibdev, u32 port, return 0; } - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -963,8 +962,8 @@ int __mlx4_ib_query_pkey(struct ib_device *ibdev, u32 port, u16 index, int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -1268,7 +1267,7 @@ static int add_gid_entry(struct ib_qp *ibqp, union ib_gid *gid) struct mlx4_ib_dev *mdev = to_mdev(ibqp->device); struct mlx4_ib_gid_entry *ge; - ge = kzalloc(sizeof *ge, GFP_KERNEL); + ge = kzalloc_obj(*ge); if (!ge) return -ENOMEM; @@ -1708,7 +1707,7 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp, memset(type, 0, sizeof(type)); - mflow = kzalloc(sizeof(*mflow), GFP_KERNEL); + mflow = kzalloc_obj(*mflow); if (!mflow) { err = -ENOMEM; goto err_free; @@ -1845,7 +1844,7 @@ static int mlx4_ib_mcg_attach(struct ib_qp *ibqp, union ib_gid *gid, u16 lid) if (mdev->dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { - ib_steering = kmalloc(sizeof(*ib_steering), GFP_KERNEL); + ib_steering = kmalloc_obj(*ib_steering); if (!ib_steering) return -ENOMEM; } @@ -1979,8 +1978,8 @@ static int init_node_data(struct mlx4_ib_dev *dev) int mad_ifc_flags = MLX4_MAD_IFC_IGNORE_KEYS; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -2158,8 +2157,7 @@ static int __mlx4_ib_alloc_diag_counters(struct mlx4_ib_dev *ibdev, if (!port) num_counters += ARRAY_SIZE(diag_device_only); - *pdescs = kcalloc(num_counters, sizeof(struct rdma_stat_desc), - GFP_KERNEL); + *pdescs = kzalloc_objs(struct rdma_stat_desc, num_counters); if (!*pdescs) return -ENOMEM; @@ -2427,8 +2425,8 @@ static void mlx4_ib_alloc_eqs(struct mlx4_dev *dev, struct mlx4_ib_dev *ibdev) { int i, j, eq = 0, total_eqs = 0; - ibdev->eq_table = kcalloc(dev->caps.num_comp_vectors, - sizeof(ibdev->eq_table[0]), GFP_KERNEL); + ibdev->eq_table = kzalloc_objs(ibdev->eq_table[0], + dev->caps.num_comp_vectors); if (!ibdev->eq_table) return; @@ -2732,8 +2730,7 @@ static int mlx4_ib_probe(struct auxiliary_device *adev, counter_index = mlx4_get_default_counter_index(dev, i + 1); } - new_counter_index = kmalloc(sizeof(*new_counter_index), - GFP_KERNEL); + new_counter_index = kmalloc_obj(*new_counter_index); if (!new_counter_index) { err = -ENOMEM; if (allocated) @@ -2751,8 +2748,7 @@ static int mlx4_ib_probe(struct auxiliary_device *adev, if (mlx4_is_bonded(dev)) for (i = 1; i < ibdev->num_ports ; ++i) { new_counter_index = - kmalloc(sizeof(struct counter_index), - GFP_KERNEL); + kmalloc_obj(struct counter_index); if (!new_counter_index) { err = -ENOMEM; goto err_counter; @@ -3035,12 +3031,12 @@ static void do_slave_init(struct mlx4_ib_dev *ibdev, int slave, int do_init) ports = bitmap_weight(actv_ports.ports, dev->caps.num_ports); first_port = find_first_bit(actv_ports.ports, dev->caps.num_ports); - dm = kcalloc(ports, sizeof(*dm), GFP_ATOMIC); + dm = kzalloc_objs(*dm, ports, GFP_ATOMIC); if (!dm) return; for (i = 0; i < ports; i++) { - dm[i] = kmalloc(sizeof (struct mlx4_ib_demux_work), GFP_ATOMIC); + dm[i] = kmalloc_obj(struct mlx4_ib_demux_work, GFP_ATOMIC); if (!dm[i]) { while (--i >= 0) kfree(dm[i]); @@ -3195,7 +3191,7 @@ void mlx4_sched_ib_sl2vl_update_work(struct mlx4_ib_dev *ibdev, { struct ib_event_work *ew; - ew = kmalloc(sizeof(*ew), GFP_ATOMIC); + ew = kmalloc_obj(*ew, GFP_ATOMIC); if (ew) { INIT_WORK(&ew->work, ib_sl2vl_update_work); ew->port = port; @@ -3218,7 +3214,7 @@ static int mlx4_ib_event(struct notifier_block *this, unsigned long event, if (mlx4_is_bonded(dev) && ((event == MLX4_DEV_EVENT_PORT_UP) || (event == MLX4_DEV_EVENT_PORT_DOWN))) { - ew = kmalloc(sizeof(*ew), GFP_ATOMIC); + ew = kmalloc_obj(*ew, GFP_ATOMIC); if (!ew) return NOTIFY_DONE; INIT_WORK(&ew->work, handle_bonded_port_state_event); @@ -3267,7 +3263,7 @@ static int mlx4_ib_event(struct notifier_block *this, unsigned long event, break; case MLX4_DEV_EVENT_PORT_MGMT_CHANGE: - ew = kmalloc(sizeof *ew, GFP_ATOMIC); + ew = kmalloc_obj(*ew, GFP_ATOMIC); if (!ew) return NOTIFY_DONE; diff --git a/drivers/infiniband/hw/mlx4/mcg.c b/drivers/infiniband/hw/mlx4/mcg.c index e279e69b9a51..dc7c0daaaba5 100644 --- a/drivers/infiniband/hw/mlx4/mcg.c +++ b/drivers/infiniband/hw/mlx4/mcg.c @@ -824,7 +824,7 @@ static struct mcast_group *acquire_group(struct mlx4_ib_demux_ctx *ctx, if (!create) return ERR_PTR(-ENOENT); - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return ERR_PTR(-ENOMEM); @@ -946,7 +946,7 @@ int mlx4_ib_mcg_multiplex_handler(struct ib_device *ibdev, int port, may_create = 1; fallthrough; case IB_SA_METHOD_DELETE: - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -1150,7 +1150,7 @@ void mlx4_ib_mcg_port_cleanup(struct mlx4_ib_demux_ctx *ctx, int destroy_wq) return; } - work = kmalloc(sizeof *work, GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) { ctx->flushing = 0; return; @@ -1211,7 +1211,7 @@ static int push_deleteing_req(struct mcast_group *group, int slave) if (!group->func[slave].join_state) return 0; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 94464f1694d9..77a72d2b0dd2 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c @@ -60,7 +60,7 @@ struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) struct mlx4_ib_mr *mr; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -151,7 +151,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, if (dmah) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -394,7 +394,7 @@ struct ib_mr *mlx4_ib_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, max_num_sg > MLX4_MAX_FAST_REG_PAGES) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f2887ae6390e..1cb890d3d93c 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -267,7 +267,7 @@ static void mlx4_ib_qp_event(struct mlx4_qp *qp, enum mlx4_event type) if (!ibqp->event_handler) goto out_no_handler; - qpe_work = kzalloc(sizeof(*qpe_work), GFP_ATOMIC); + qpe_work = kzalloc_obj(*qpe_work, GFP_ATOMIC); if (!qpe_work) goto out_no_handler; @@ -472,14 +472,12 @@ static int alloc_proxy_bufs(struct ib_device *dev, struct mlx4_ib_qp *qp) int i; qp->sqp_proxy_rcv = - kmalloc_array(qp->rq.wqe_cnt, sizeof(struct mlx4_ib_buf), - GFP_KERNEL); + kmalloc_objs(struct mlx4_ib_buf, qp->rq.wqe_cnt); if (!qp->sqp_proxy_rcv) return -ENOMEM; for (i = 0; i < qp->rq.wqe_cnt; i++) { qp->sqp_proxy_rcv[i].addr = - kmalloc(sizeof (struct mlx4_ib_proxy_sqp_hdr), - GFP_KERNEL); + kmalloc_obj(struct mlx4_ib_proxy_sqp_hdr); if (!qp->sqp_proxy_rcv[i].addr) goto err; qp->sqp_proxy_rcv[i].map = @@ -683,7 +681,7 @@ static int create_qp_rss(struct mlx4_ib_dev *dev, qp->mtt = (to_mqp( (struct ib_qp *)init_attr->rwq_ind_tbl->ind_tbl[0]))->mtt; - qp->rss_ctx = kzalloc(sizeof(*qp->rss_ctx), GFP_KERNEL); + qp->rss_ctx = kzalloc_obj(*qp->rss_ctx); if (!qp->rss_ctx) { err = -ENOMEM; goto err_qp_alloc; @@ -793,7 +791,7 @@ static int mlx4_ib_alloc_wqn(struct mlx4_ib_ucontext *context, struct mlx4_wqn_range, list); if (!range || (range->refcount == range->size) || range->dirty) { - range = kzalloc(sizeof(*range), GFP_KERNEL); + range = kzalloc_obj(*range); if (!range) { err = -ENOMEM; goto out; @@ -1051,7 +1049,7 @@ static int create_qp_common(struct ib_pd *pd, struct ib_qp_init_attr *init_attr, qp_type == MLX4_IB_QPT_GSI || (qp_type & (MLX4_IB_QPT_PROXY_SMI | MLX4_IB_QPT_PROXY_SMI_OWNER | MLX4_IB_QPT_PROXY_GSI | MLX4_IB_QPT_TUN_SMI_OWNER))) { - qp->sqp = kzalloc(sizeof(struct mlx4_ib_sqp), GFP_KERNEL); + qp->sqp = kzalloc_obj(struct mlx4_ib_sqp); if (!qp->sqp) return -ENOMEM; } @@ -1972,7 +1970,7 @@ static int create_qp_lb_counter(struct mlx4_ib_dev *dev, struct mlx4_ib_qp *qp) if (err) return err; - new_counter_index = kmalloc(sizeof(*new_counter_index), GFP_KERNEL); + new_counter_index = kmalloc_obj(*new_counter_index); if (!new_counter_index) { mlx4_counter_free(dev->dev, tmp_idx); return -ENOMEM; @@ -2165,7 +2163,7 @@ static int __mlx4_ib_modify_qp(void *src, enum mlx4_ib_source_type src_type, IB_LINK_LAYER_ETHERNET) return -ENOTSUPP; - context = kzalloc(sizeof *context, GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return -ENOMEM; @@ -4167,7 +4165,7 @@ struct ib_wq *mlx4_ib_create_wq(struct ib_pd *pd, return ERR_PTR(-EOPNOTSUPP); } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mlx4/sysfs.c b/drivers/infiniband/hw/mlx4/sysfs.c index 88f534cf690e..b8fa4ecfc961 100644 --- a/drivers/infiniband/hw/mlx4/sysfs.c +++ b/drivers/infiniband/hw/mlx4/sysfs.c @@ -244,8 +244,7 @@ static int add_port_entries(struct mlx4_ib_dev *device, int port_num) * gids (operational) * mcg_table */ - port->dentr_ar = kzalloc(sizeof (struct mlx4_ib_iov_sysfs_attr_ar), - GFP_KERNEL); + port->dentr_ar = kzalloc_obj(struct mlx4_ib_iov_sysfs_attr_ar); if (!port->dentr_ar) { ret = -ENOMEM; goto err; @@ -500,13 +499,12 @@ alloc_group_attrs(ssize_t (*show)(struct mlx4_port *, struct port_table_attribute *element; int i; - tab_attr = kcalloc(1 + len, sizeof (struct attribute *), GFP_KERNEL); + tab_attr = kzalloc_objs(struct attribute *, 1 + len); if (!tab_attr) return NULL; for (i = 0; i < len; i++) { - element = kzalloc(sizeof (struct port_table_attribute), - GFP_KERNEL); + element = kzalloc_obj(struct port_table_attribute); if (!element) goto err; if (snprintf(element->name, sizeof (element->name), @@ -630,7 +628,7 @@ static int add_port(struct mlx4_ib_dev *dev, int port_num, int slave) int is_eth = rdma_port_get_link_layer(&dev->ib_dev, port_num) == IB_LINK_LAYER_ETHERNET; - p = kzalloc(sizeof *p, GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/cong.c b/drivers/infiniband/hw/mlx5/cong.c index a78a067e3ce7..d0edf83a2f20 100644 --- a/drivers/infiniband/hw/mlx5/cong.c +++ b/drivers/infiniband/hw/mlx5/cong.c @@ -449,7 +449,7 @@ void mlx5_ib_init_cong_debugfs(struct mlx5_ib_dev *dev, u32 port_num) !MLX5_CAP_GEN(mdev, cc_modify_allowed)) goto put_mdev; - dbg_cc_params = kzalloc(sizeof(*dbg_cc_params), GFP_KERNEL); + dbg_cc_params = kzalloc_obj(*dbg_cc_params); if (!dbg_cc_params) goto err; diff --git a/drivers/infiniband/hw/mlx5/counters.c b/drivers/infiniband/hw/mlx5/counters.c index e042e0719ead..5b4482dd6274 100644 --- a/drivers/infiniband/hw/mlx5/counters.c +++ b/drivers/infiniband/hw/mlx5/counters.c @@ -858,13 +858,11 @@ static int __mlx5_ib_alloc_counters(struct mlx5_ib_dev *dev, skip_non_qcounters: cnts->num_op_counters = num_op_counters; num_counters += num_op_counters; - cnts->descs = kcalloc(num_counters, - sizeof(struct rdma_stat_desc), GFP_KERNEL); + cnts->descs = kzalloc_objs(struct rdma_stat_desc, num_counters); if (!cnts->descs) return -ENOMEM; - cnts->offsets = kcalloc(num_counters, - sizeof(*cnts->offsets), GFP_KERNEL); + cnts->offsets = kzalloc_objs(*cnts->offsets, num_counters); if (!cnts->offsets) goto err; @@ -1074,9 +1072,7 @@ int mlx5_ib_flow_counters_set_data(struct ib_counters *ibcounters, if (cntrs_data->ncounters > MAX_COUNTERS_NUM) return -EINVAL; - desc_data = kcalloc(cntrs_data->ncounters, - sizeof(*desc_data), - GFP_KERNEL); + desc_data = kzalloc_objs(*desc_data, cntrs_data->ncounters); if (!desc_data) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c index 651d76bca114..d0cd3f805bcb 100644 --- a/drivers/infiniband/hw/mlx5/cq.c +++ b/drivers/infiniband/hw/mlx5/cq.c @@ -1210,7 +1210,7 @@ static int resize_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_cq *cq, { int err; - cq->resize_buf = kzalloc(sizeof(*cq->resize_buf), GFP_KERNEL); + cq->resize_buf = kzalloc_obj(*cq->resize_buf); if (!cq->resize_buf) return -ENOMEM; @@ -1449,7 +1449,7 @@ int mlx5_ib_generate_wc(struct ib_cq *ibcq, struct ib_wc *wc) struct mlx5_ib_cq *cq = to_mcq(ibcq); unsigned long flags; - soft_wc = kmalloc(sizeof(*soft_wc), GFP_ATOMIC); + soft_wc = kmalloc_obj(*soft_wc, GFP_ATOMIC); if (!soft_wc) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/data_direct.c b/drivers/infiniband/hw/mlx5/data_direct.c index b81ac5709b56..8e89dbe40c23 100644 --- a/drivers/infiniband/hw/mlx5/data_direct.c +++ b/drivers/infiniband/hw/mlx5/data_direct.c @@ -83,7 +83,7 @@ int mlx5_data_direct_ib_reg(struct mlx5_ib_dev *ibdev, char *vuid) struct mlx5_data_direct_registration *reg; struct mlx5_data_direct_dev *dev; - reg = kzalloc(sizeof(*reg), GFP_KERNEL); + reg = kzalloc_obj(*reg); if (!reg) return -ENOMEM; @@ -160,7 +160,7 @@ static int mlx5_data_direct_probe(struct pci_dev *pdev, const struct pci_device_ struct mlx5_data_direct_dev *dev; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/devx.c b/drivers/infiniband/hw/mlx5/devx.c index d31d7f3005c6..0066b2738ac8 100644 --- a/drivers/infiniband/hw/mlx5/devx.c +++ b/drivers/infiniband/hw/mlx5/devx.c @@ -1950,7 +1950,7 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table, event = xa_load(&devx_event_table->event_xa, key_level1); if (!event) { - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) return -ENOMEM; @@ -1972,7 +1972,7 @@ subscribe_event_xa_alloc(struct mlx5_devx_event_table *devx_event_table, obj_event = xa_load(&event->object_ids, key_level2); if (!obj_event) { - obj_event = kzalloc(sizeof(*obj_event), GFP_KERNEL); + obj_event = kzalloc_obj(*obj_event); if (!obj_event) /* Level1 is valid for future use, no need to free */ return -ENOMEM; @@ -2697,7 +2697,7 @@ void mlx5_ib_ufile_hw_cleanup(struct ib_uverbs_file *ufile) int head = 0; int tail = 0; - async_cmd = kcalloc(MAX_ASYNC_CMDS, sizeof(*async_cmd), GFP_KERNEL); + async_cmd = kzalloc_objs(*async_cmd, MAX_ASYNC_CMDS); if (!async_cmd) return; diff --git a/drivers/infiniband/hw/mlx5/dm.c b/drivers/infiniband/hw/mlx5/dm.c index 9ded2b7c1e31..9972f38ba88a 100644 --- a/drivers/infiniband/hw/mlx5/dm.c +++ b/drivers/infiniband/hw/mlx5/dm.c @@ -285,7 +285,7 @@ static struct ib_dm *handle_alloc_dm_memic(struct ib_ucontext *ctx, if (!dm_db || !MLX5_CAP_DEV_MEM(dm_db->dev, memic)) return ERR_PTR(-EOPNOTSUPP); - dm = kzalloc(sizeof(*dm), GFP_KERNEL); + dm = kzalloc_obj(*dm); if (!dm) return ERR_PTR(-ENOMEM); @@ -382,7 +382,7 @@ static struct ib_dm *handle_alloc_dm_sw_icm(struct ib_ucontext *ctx, return ERR_PTR(-EOPNOTSUPP); } - dm = kzalloc(sizeof(*dm), GFP_KERNEL); + dm = kzalloc_obj(*dm); if (!dm) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mlx5/doorbell.c b/drivers/infiniband/hw/mlx5/doorbell.c index e32111117a5e..bd68fcf011f4 100644 --- a/drivers/infiniband/hw/mlx5/doorbell.c +++ b/drivers/infiniband/hw/mlx5/doorbell.c @@ -58,7 +58,7 @@ int mlx5_ib_db_map_user(struct mlx5_ib_ucontext *context, unsigned long virt, (page->user_virt == (virt & PAGE_MASK))) goto found; - page = kmalloc(sizeof(*page), GFP_KERNEL); + page = kmalloc_obj(*page); if (!page) { err = -ENOMEM; goto out; diff --git a/drivers/infiniband/hw/mlx5/fs.c b/drivers/infiniband/hw/mlx5/fs.c index d17823ce7f38..cbccb0b9ac10 100644 --- a/drivers/infiniband/hw/mlx5/fs.c +++ b/drivers/infiniband/hw/mlx5/fs.c @@ -1021,7 +1021,7 @@ static struct mlx5_per_qp_opfc *get_per_qp_opfc(struct xarray *qpn_opfc_xa, per_qp_opfc = xa_load(qpn_opfc_xa, qp_num); if (per_qp_opfc) return per_qp_opfc; - per_qp_opfc = kzalloc(sizeof(*per_qp_opfc), GFP_KERNEL); + per_qp_opfc = kzalloc_obj(*per_qp_opfc); if (!per_qp_opfc) return NULL; @@ -1057,7 +1057,7 @@ static int add_op_fc_rules(struct mlx5_ib_dev *dev, opfc->fc = fc_arr[type]; - spec = kcalloc(MAX_OPFC_RULES, sizeof(*spec), GFP_KERNEL); + spec = kzalloc_objs(*spec, MAX_OPFC_RULES); if (!spec) { err = -ENOMEM; goto null_fc; @@ -1231,7 +1231,7 @@ int mlx5_ib_fs_add_op_fc(struct mlx5_ib_dev *dev, u32 port_num, struct mlx5_ib_flow_prio *prio; struct mlx5_flow_spec *spec; - spec = kcalloc(MAX_OPFC_RULES, sizeof(*spec), GFP_KERNEL); + spec = kzalloc_objs(*spec, MAX_OPFC_RULES); if (!spec) return -ENOMEM; @@ -1532,8 +1532,8 @@ static struct mlx5_ib_flow_handler *_create_flow_rule(struct mlx5_ib_dev *dev, if (dev->is_rep && is_egress) return ERR_PTR(-EINVAL); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); - handler = kzalloc(sizeof(*handler), GFP_KERNEL); + spec = kvzalloc_obj(*spec); + handler = kzalloc_obj(*handler); if (!handler || !spec) { err = -ENOMEM; goto free; @@ -1792,7 +1792,7 @@ static struct ib_flow *mlx5_ib_create_flow(struct ib_qp *qp, goto free_ucmd; } - dst = kzalloc(sizeof(*dst), GFP_KERNEL); + dst = kzalloc_obj(*dst); if (!dst) { err = -ENOMEM; goto free_ucmd; @@ -2060,8 +2060,8 @@ _create_raw_flow_rule(struct mlx5_ib_dev *dev, struct mlx5_flow_table *ft = ft_prio->flow_table; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); - handler = kzalloc(sizeof(*handler), GFP_KERNEL); + spec = kvzalloc_obj(*spec); + handler = kzalloc_obj(*handler); if (!handler || !spec) { err = -ENOMEM; goto free; @@ -2153,7 +2153,7 @@ static struct mlx5_ib_flow_handler *raw_fs_rule_add( if (fs_matcher->priority > MLX5_IB_FLOW_LAST_PRIO) return ERR_PTR(-ENOMEM); - dst = kcalloc(2, sizeof(*dst), GFP_KERNEL); + dst = kzalloc_objs(*dst, 2); if (!dst) return ERR_PTR(-ENOMEM); @@ -3080,7 +3080,7 @@ mlx5_ib_create_modify_header(struct mlx5_ib_dev *dev, if (ret) return ERR_PTR(-EINVAL); - maction = kzalloc(sizeof(*maction), GFP_KERNEL); + maction = kzalloc_obj(*maction); if (!maction) return ERR_PTR(-ENOMEM); @@ -3479,23 +3479,21 @@ int mlx5_ib_fs_init(struct mlx5_ib_dev *dev) { int i, j; - dev->flow_db = kzalloc(sizeof(*dev->flow_db), GFP_KERNEL); + dev->flow_db = kzalloc_obj(*dev->flow_db); if (!dev->flow_db) return -ENOMEM; for (i = 0; i < MLX5_RDMA_TRANSPORT_BYPASS_PRIO; i++) { dev->flow_db->rdma_transport_rx[i] = - kcalloc(dev->num_ports, - sizeof(struct mlx5_ib_flow_prio), GFP_KERNEL); + kzalloc_objs(struct mlx5_ib_flow_prio, dev->num_ports); if (!dev->flow_db->rdma_transport_rx[i]) goto free_rdma_transport_rx; } for (j = 0; j < MLX5_RDMA_TRANSPORT_BYPASS_PRIO; j++) { dev->flow_db->rdma_transport_tx[j] = - kcalloc(dev->num_ports, - sizeof(struct mlx5_ib_flow_prio), GFP_KERNEL); + kzalloc_objs(struct mlx5_ib_flow_prio, dev->num_ports); if (!dev->flow_db->rdma_transport_tx[j]) goto free_rdma_transport_tx; } diff --git a/drivers/infiniband/hw/mlx5/gsi.c b/drivers/infiniband/hw/mlx5/gsi.c index d5487834ed25..b2e2a219639d 100644 --- a/drivers/infiniband/hw/mlx5/gsi.c +++ b/drivers/infiniband/hw/mlx5/gsi.c @@ -104,13 +104,12 @@ int mlx5_ib_create_gsi(struct ib_pd *pd, struct mlx5_ib_qp *mqp, } gsi = &mqp->gsi; - gsi->tx_qps = kcalloc(num_qps, sizeof(*gsi->tx_qps), GFP_KERNEL); + gsi->tx_qps = kzalloc_objs(*gsi->tx_qps, num_qps); if (!gsi->tx_qps) return -ENOMEM; gsi->outstanding_wrs = - kcalloc(attr->cap.max_send_wr, sizeof(*gsi->outstanding_wrs), - GFP_KERNEL); + kzalloc_objs(*gsi->outstanding_wrs, attr->cap.max_send_wr); if (!gsi->outstanding_wrs) { ret = -ENOMEM; goto err_free_tx; diff --git a/drivers/infiniband/hw/mlx5/ib_rep.c b/drivers/infiniband/hw/mlx5/ib_rep.c index bbecca405171..621834d75205 100644 --- a/drivers/infiniband/hw/mlx5/ib_rep.c +++ b/drivers/infiniband/hw/mlx5/ib_rep.c @@ -158,8 +158,7 @@ mlx5_ib_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) goto release_transport; } - ibdev->port = kcalloc(num_ports, sizeof(*ibdev->port), - GFP_KERNEL); + ibdev->port = kzalloc_objs(*ibdev->port, num_ports); if (!ibdev->port) { ret = -ENOMEM; goto fail_port; diff --git a/drivers/infiniband/hw/mlx5/ib_virt.c b/drivers/infiniband/hw/mlx5/ib_virt.c index afeb5e53254f..2c81a4e6712e 100644 --- a/drivers/infiniband/hw/mlx5/ib_virt.c +++ b/drivers/infiniband/hw/mlx5/ib_virt.c @@ -55,7 +55,7 @@ int mlx5_ib_get_vf_config(struct ib_device *device, int vf, u32 port, struct mlx5_hca_vport_context *rep; int err; - rep = kzalloc(sizeof(*rep), GFP_KERNEL); + rep = kzalloc_obj(*rep); if (!rep) return -ENOMEM; @@ -98,7 +98,7 @@ int mlx5_ib_set_vf_link_state(struct ib_device *device, int vf, struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx; int err; - in = kzalloc(sizeof(*in), GFP_KERNEL); + in = kzalloc_obj(*in); if (!in) return -ENOMEM; @@ -157,7 +157,7 @@ static int set_vf_node_guid(struct ib_device *device, int vf, u32 port, struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx; int err; - in = kzalloc(sizeof(*in), GFP_KERNEL); + in = kzalloc_obj(*in); if (!in) return -ENOMEM; @@ -181,7 +181,7 @@ static int set_vf_port_guid(struct ib_device *device, int vf, u32 port, struct mlx5_vf_context *vfs_ctx = mdev->priv.sriov.vfs_ctx; int err; - in = kzalloc(sizeof(*in), GFP_KERNEL); + in = kzalloc_obj(*in); if (!in) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/macsec.c b/drivers/infiniband/hw/mlx5/macsec.c index 3c56eb5eddf3..b44832025ab7 100644 --- a/drivers/infiniband/hw/mlx5/macsec.c +++ b/drivers/infiniband/hw/mlx5/macsec.c @@ -52,7 +52,7 @@ static struct mlx5_macsec_device *get_macsec_device(void *macdev, if (macsec_device) return macsec_device; - macsec_device = kzalloc(sizeof(*macsec_device), GFP_KERNEL); + macsec_device = kzalloc_obj(*macsec_device); if (!macsec_device) return NULL; @@ -82,7 +82,7 @@ static void mlx5_macsec_save_roce_gid(struct mlx5_macsec_device *macsec_device, { struct mlx5_roce_gids *roce_gids; - roce_gids = kzalloc(sizeof(*roce_gids), GFP_KERNEL); + roce_gids = kzalloc_obj(*roce_gids); if (!roce_gids) return; @@ -180,9 +180,8 @@ int mlx5r_macsec_init_gids_and_devlist(struct mlx5_ib_dev *dev) max_gids = MLX5_CAP_ROCE(dev->mdev, roce_address_table_size); for (i = 0; i < dev->num_ports; i++) { - dev->port[i].reserved_gids = kcalloc(max_gids, - sizeof(*dev->port[i].reserved_gids), - GFP_KERNEL); + dev->port[i].reserved_gids = kzalloc_objs(*dev->port[i].reserved_gids, + max_gids); if (!dev->port[i].reserved_gids) goto err; diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c index 2453ae4384a7..8925331855ff 100644 --- a/drivers/infiniband/hw/mlx5/mad.c +++ b/drivers/infiniband/hw/mlx5/mad.c @@ -367,8 +367,8 @@ int mlx5_query_ext_port_caps(struct mlx5_ib_dev *dev, unsigned int port) int err = -ENOMEM; u16 packet_error; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -395,7 +395,7 @@ static int mlx5_query_mad_ifc_smp_attr_node_info(struct ib_device *ibdev, struct ib_smp *in_mad; int err; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); if (!in_mad) return -ENOMEM; @@ -415,7 +415,7 @@ int mlx5_query_mad_ifc_system_image_guid(struct ib_device *ibdev, struct ib_smp *out_mad; int err; - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + out_mad = kmalloc_obj(*out_mad); if (!out_mad) return -ENOMEM; @@ -437,7 +437,7 @@ int mlx5_query_mad_ifc_max_pkeys(struct ib_device *ibdev, struct ib_smp *out_mad; int err; - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + out_mad = kmalloc_obj(*out_mad); if (!out_mad) return -ENOMEM; @@ -459,7 +459,7 @@ int mlx5_query_mad_ifc_vendor_id(struct ib_device *ibdev, struct ib_smp *out_mad; int err; - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + out_mad = kmalloc_obj(*out_mad); if (!out_mad) return -ENOMEM; @@ -481,8 +481,8 @@ int mlx5_query_mad_ifc_node_desc(struct mlx5_ib_dev *dev, char *node_desc) struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -506,8 +506,8 @@ int mlx5_query_mad_ifc_node_guid(struct mlx5_ib_dev *dev, __be64 *node_guid) struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -532,8 +532,8 @@ int mlx5_query_mad_ifc_pkey(struct ib_device *ibdev, u32 port, u16 index, struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -561,8 +561,8 @@ int mlx5_query_mad_ifc_gids(struct ib_device *ibdev, u32 port, int index, struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -604,8 +604,8 @@ int mlx5_query_mad_ifc_port(struct ib_device *ibdev, u32 port, int ext_active_speed; int err = -ENOMEM; - in_mad = kzalloc(sizeof(*in_mad), GFP_KERNEL); - out_mad = kmalloc(sizeof(*out_mad), GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 5e06177ace26..635002e684a5 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c @@ -1460,7 +1460,7 @@ static int mlx5_query_hca_port(struct ib_device *ibdev, u32 port, int err; u16 ib_link_width_oper; - rep = kzalloc(sizeof(*rep), GFP_KERNEL); + rep = kzalloc_obj(*rep); if (!rep) { err = -ENOMEM; goto out; @@ -3121,7 +3121,7 @@ static int mlx5_ib_event(struct notifier_block *nb, { struct mlx5_ib_event_work *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; @@ -3141,7 +3141,7 @@ static int mlx5_ib_event_slave_port(struct notifier_block *nb, { struct mlx5_ib_event_work *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; @@ -3188,7 +3188,7 @@ static int mlx5_ib_sys_error_event(struct notifier_block *nb, if (event != MLX5_DEV_EVENT_SYS_ERROR) return NOTIFY_DONE; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; @@ -4042,7 +4042,7 @@ static int mlx5_ib_init_multiport_master(struct mlx5_ib_dev *dev) /* build a stub multiport info struct for the native port. */ if (i == port_num) { - mpi = kzalloc(sizeof(*mpi), GFP_KERNEL); + mpi = kzalloc_obj(*mpi); if (!mpi) { mutex_unlock(&mlx5_ib_multiport_mutex); mlx5_nic_vport_disable_roce(dev->mdev); @@ -4148,7 +4148,7 @@ alloc_var_entry(struct mlx5_ib_ucontext *c) int err; var_table = &to_mdev(c->ibucontext.device)->var_table; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -4269,7 +4269,7 @@ alloc_uar_entry(struct mlx5_ib_ucontext *c, u32 uar_index; int err; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -5204,8 +5204,8 @@ static struct ib_device *mlx5_ib_add_sub_dev(struct ib_device *parent, if (!mplane) return ERR_PTR(-ENOMEM); - mplane->port = kcalloc(mparent->num_plane * mparent->num_ports, - sizeof(*mplane->port), GFP_KERNEL); + mplane->port = kzalloc_objs(*mplane->port, + mparent->num_plane * mparent->num_ports); if (!mplane->port) { ret = -ENOMEM; goto fail_kcalloc; @@ -5249,7 +5249,7 @@ static int mlx5r_mp_probe(struct auxiliary_device *adev, bool bound = false; int err; - mpi = kzalloc(sizeof(*mpi), GFP_KERNEL); + mpi = kzalloc_obj(*mpi); if (!mpi) return -ENOMEM; @@ -5325,8 +5325,7 @@ static int mlx5r_probe(struct auxiliary_device *adev, goto fail; } - dev->port = kcalloc(num_ports, sizeof(*dev->port), - GFP_KERNEL); + dev->port = kzalloc_objs(*dev->port, num_ports); if (!dev->port) { ret = -ENOMEM; goto fail; diff --git a/drivers/infiniband/hw/mlx5/mr.c b/drivers/infiniband/hw/mlx5/mr.c index a7b37e3df072..665323b90b64 100644 --- a/drivers/infiniband/hw/mlx5/mr.c +++ b/drivers/infiniband/hw/mlx5/mr.c @@ -156,7 +156,7 @@ static int push_mkey_locked(struct mlx5_cache_ent *ent, u32 mkey) lockdep_assert_held(&ent->mkeys_queue.lock); if (ent->mkeys_queue.ci >= ent->mkeys_queue.num_pages * NUM_MKEYS_PER_PAGE) { - page = kzalloc(sizeof(*page), GFP_ATOMIC); + page = kzalloc_obj(*page, GFP_ATOMIC); if (!page) return -ENOMEM; ent->mkeys_queue.num_pages++; @@ -276,8 +276,7 @@ static int add_keys(struct mlx5_cache_ent *ent, unsigned int num) int i; for (i = 0; i < num; i++) { - async_create = kzalloc(sizeof(struct mlx5r_async_create_mkey), - GFP_KERNEL); + async_create = kzalloc_obj(struct mlx5r_async_create_mkey); if (!async_create) return -ENOMEM; mkc = MLX5_ADDR_OF(create_mkey_in, async_create->in, @@ -742,7 +741,7 @@ static struct mlx5_ib_mr *_mlx5_mr_cache_alloc(struct mlx5_ib_dev *dev, struct mlx5_ib_mr *mr; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -867,7 +866,7 @@ static int mlx5r_mkeys_init(struct mlx5_cache_ent *ent) { struct mlx5_mkeys_page *page; - page = kzalloc(sizeof(*page), GFP_KERNEL); + page = kzalloc_obj(*page); if (!page) return -ENOMEM; INIT_LIST_HEAD(&ent->mkeys_queue.pages_list); @@ -897,7 +896,7 @@ mlx5r_cache_create_ent_locked(struct mlx5_ib_dev *dev, int order; int ret; - ent = kzalloc(sizeof(*ent), GFP_KERNEL); + ent = kzalloc_obj(*ent); if (!ent) return ERR_PTR(-ENOMEM); @@ -1059,7 +1058,7 @@ struct ib_mr *mlx5_ib_get_dma_mr(struct ib_pd *pd, int acc) u32 *in; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1207,7 +1206,7 @@ reg_create_crossing_vhca_mr(struct ib_pd *pd, u64 iova, u64 length, int access_f if (!MLX5_CAP_GEN(dev->mdev, crossing_vhca_mkey)) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1272,7 +1271,7 @@ static struct mlx5_ib_mr *reg_create(struct ib_pd *pd, struct ib_umem *umem, if (!page_size) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1370,7 +1369,7 @@ static struct ib_mr *mlx5_ib_get_dm_mr(struct ib_pd *pd, u64 start_addr, u32 *in; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -2343,7 +2342,7 @@ static struct mlx5_ib_mr *mlx5_ib_alloc_pi_mr(struct ib_pd *pd, u32 *in; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -2400,7 +2399,7 @@ static int mlx5_alloc_integrity_descs(struct ib_pd *pd, struct mlx5_ib_mr *mr, void *mkc; int err; - mr->sig = kzalloc(sizeof(*mr->sig), GFP_KERNEL); + mr->sig = kzalloc_obj(*mr->sig); if (!mr->sig) return -ENOMEM; @@ -2480,7 +2479,7 @@ static struct ib_mr *__mlx5_ib_alloc_mr(struct ib_pd *pd, u32 *in; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mlx5/odp.c b/drivers/infiniband/hw/mlx5/odp.c index e71ee3d52eb0..4c1dea4fd526 100644 --- a/drivers/infiniband/hw/mlx5/odp.c +++ b/drivers/infiniband/hw/mlx5/odp.c @@ -1092,7 +1092,7 @@ static int pagefault_single_data_segment(struct mlx5_ib_dev *dev, continue; } - frame = kzalloc(sizeof(*frame), GFP_KERNEL); + frame = kzalloc_obj(*frame); if (!frame) { ret = -ENOMEM; goto end; @@ -2097,7 +2097,7 @@ int mlx5_ib_advise_mr_prefetch(struct ib_pd *pd, return mlx5_ib_prefetch_sg_list(pd, advice, pf_flags, sg_list, num_sge); - work = kvzalloc(struct_size(work, frags, num_sge), GFP_KERNEL); + work = kvzalloc_flex(*work, frags, num_sge); if (!work) return -ENOMEM; diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 0324909e3151..47de8cc9937e 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -416,7 +416,7 @@ static void mlx5_ib_qp_event(struct mlx5_core_qp *qp, int type) if (!ibqp->event_handler) goto out_no_handler; - qpe_work = kzalloc(sizeof(*qpe_work), GFP_ATOMIC); + qpe_work = kzalloc_obj(*qpe_work, GFP_ATOMIC); if (!qpe_work) goto out_no_handler; @@ -1185,8 +1185,7 @@ static int _create_kernel_qp(struct mlx5_ib_dev *dev, sizeof(*qp->sq.wr_data), GFP_KERNEL); qp->rq.wrid = kvmalloc_array(qp->rq.wqe_cnt, sizeof(*qp->rq.wrid), GFP_KERNEL); - qp->sq.w_list = kvmalloc_array(qp->sq.wqe_cnt, - sizeof(*qp->sq.w_list), GFP_KERNEL); + qp->sq.w_list = kvmalloc_objs(*qp->sq.w_list, qp->sq.wqe_cnt); qp->sq.wqe_head = kvmalloc_array(qp->sq.wqe_cnt, sizeof(*qp->sq.wqe_head), GFP_KERNEL); @@ -5488,7 +5487,7 @@ struct ib_wq *mlx5_ib_create_wq(struct ib_pd *pd, dev = to_mdev(pd->device); switch (init_attr->wq_type) { case IB_WQT_RQ: - rwq = kzalloc(sizeof(*rwq), GFP_KERNEL); + rwq = kzalloc_obj(*rwq); if (!rwq) return ERR_PTR(-ENOMEM); err = prepare_user_rq(pd, init_attr, udata, rwq); diff --git a/drivers/infiniband/hw/mlx5/srq.c b/drivers/infiniband/hw/mlx5/srq.c index bcb6b324af50..17e018554d81 100644 --- a/drivers/infiniband/hw/mlx5/srq.c +++ b/drivers/infiniband/hw/mlx5/srq.c @@ -358,7 +358,7 @@ int mlx5_ib_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr) int ret; struct mlx5_srq_attr *out; - out = kzalloc(sizeof(*out), GFP_KERNEL); + out = kzalloc_obj(*out); if (!out) return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c index 9f0f79d02d3c..dedc301235a0 100644 --- a/drivers/infiniband/hw/mthca/mthca_allocator.c +++ b/drivers/infiniband/hw/mthca/mthca_allocator.c @@ -157,8 +157,7 @@ int mthca_array_init(struct mthca_array *array, int nent) int npage = (nent * sizeof (void *) + PAGE_SIZE - 1) / PAGE_SIZE; int i; - array->page_list = kmalloc_array(npage, sizeof(*array->page_list), - GFP_KERNEL); + array->page_list = kmalloc_objs(*array->page_list, npage); if (!array->page_list) return -ENOMEM; @@ -231,9 +230,7 @@ int mthca_buf_alloc(struct mthca_dev *dev, int size, int max_direct, if (!dma_list) return -ENOMEM; - buf->page_list = kmalloc_array(npages, - sizeof(*buf->page_list), - GFP_KERNEL); + buf->page_list = kmalloc_objs(*buf->page_list, npages); if (!buf->page_list) goto err_out; diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index 3df1f5ff7932..83a7ba41fa04 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c @@ -161,7 +161,7 @@ int mthca_create_ah(struct mthca_dev *dev, ah->type = MTHCA_AH_PCI_POOL; if (mthca_is_memfree(dev)) { - ah->av = kmalloc(sizeof *ah->av, GFP_ATOMIC); + ah->av = kmalloc_obj(*ah->av, GFP_ATOMIC); if (!ah->av) return -ENOMEM; @@ -175,7 +175,7 @@ int mthca_create_ah(struct mthca_dev *dev, if (index == -1) goto on_hca_fail; - av = kmalloc(sizeof *av, GFP_ATOMIC); + av = kmalloc_obj(*av, GFP_ATOMIC); if (!av) goto on_hca_fail; diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index 8fe0cef7e2be..c50a50be6c61 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c @@ -559,9 +559,8 @@ int mthca_cmd_use_events(struct mthca_dev *dev) { int i; - dev->cmd.context = kmalloc_array(dev->cmd.max_cmds, - sizeof(struct mthca_cmd_context), - GFP_KERNEL); + dev->cmd.context = kmalloc_objs(struct mthca_cmd_context, + dev->cmd.max_cmds); if (!dev->cmd.context) return -ENOMEM; @@ -611,7 +610,7 @@ struct mthca_mailbox *mthca_alloc_mailbox(struct mthca_dev *dev, { struct mthca_mailbox *mailbox; - mailbox = kmalloc(sizeof *mailbox, gfp_mask); + mailbox = kmalloc_obj(*mailbox, gfp_mask); if (!mailbox) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mthca/mthca_eq.c b/drivers/infiniband/hw/mthca/mthca_eq.c index 97287c544da8..70adcd54e20e 100644 --- a/drivers/infiniband/hw/mthca/mthca_eq.c +++ b/drivers/infiniband/hw/mthca/mthca_eq.c @@ -479,8 +479,7 @@ static int mthca_create_eq(struct mthca_dev *dev, eq->nent = roundup_pow_of_two(max(nent, 2)); npages = ALIGN(eq->nent * MTHCA_EQ_ENTRY_SIZE, PAGE_SIZE) / PAGE_SIZE; - eq->page_list = kmalloc_array(npages, sizeof(*eq->page_list), - GFP_KERNEL); + eq->page_list = kmalloc_objs(*eq->page_list, npages); if (!eq->page_list) goto err_out; diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index 04252700790e..6d8d436de2f3 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c @@ -52,7 +52,7 @@ static int mthca_update_rate(struct mthca_dev *dev, u8 port_num) struct ib_port_attr *tprops = NULL; int ret; - tprops = kmalloc(sizeof *tprops, GFP_KERNEL); + tprops = kmalloc_obj(*tprops); if (!tprops) return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c index f2734a5c5f26..9c5eb03f354d 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c @@ -145,7 +145,7 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages, /* We use sg_set_buf for coherent allocs, which assumes low memory */ BUG_ON(coherent && (gfp_mask & __GFP_HIGHMEM)); - icm = kmalloc(sizeof *icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); + icm = kmalloc_obj(*icm, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); if (!icm) return icm; @@ -156,8 +156,8 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages, while (npages > 0) { if (!chunk) { - chunk = kmalloc(sizeof *chunk, - gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); + chunk = kmalloc_obj(*chunk, + gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); if (!chunk) goto fail; @@ -367,7 +367,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev, obj_per_chunk = MTHCA_TABLE_CHUNK_SIZE / obj_size; num_icm = DIV_ROUND_UP(nobj, obj_per_chunk); - table = kmalloc(struct_size(table, icm, num_icm), GFP_KERNEL); + table = kmalloc_flex(*table, icm, num_icm); if (!table) return NULL; @@ -532,7 +532,7 @@ struct mthca_user_db_table *mthca_init_user_db_tab(struct mthca_dev *dev) return NULL; npages = dev->uar_table.uarc_size / MTHCA_ICM_PAGE_SIZE; - db_tab = kmalloc(struct_size(db_tab, page, npages), GFP_KERNEL); + db_tab = kmalloc_flex(*db_tab, page, npages); if (!db_tab) return ERR_PTR(-ENOMEM); @@ -707,7 +707,7 @@ int mthca_init_db_tab(struct mthca_dev *dev) if (!mthca_is_memfree(dev)) return 0; - dev->db_tab = kmalloc(sizeof *dev->db_tab, GFP_KERNEL); + dev->db_tab = kmalloc_obj(*dev->db_tab); if (!dev->db_tab) return -ENOMEM; @@ -717,9 +717,8 @@ int mthca_init_db_tab(struct mthca_dev *dev) dev->db_tab->max_group1 = 0; dev->db_tab->min_group2 = dev->db_tab->npages - 1; - dev->db_tab->page = kmalloc_array(dev->db_tab->npages, - sizeof(*dev->db_tab->page), - GFP_KERNEL); + dev->db_tab->page = kmalloc_objs(*dev->db_tab->page, + dev->db_tab->npages); if (!dev->db_tab->page) { kfree(dev->db_tab); return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_mr.c b/drivers/infiniband/hw/mthca/mthca_mr.c index dacb8ceeebe0..bca908054e1b 100644 --- a/drivers/infiniband/hw/mthca/mthca_mr.c +++ b/drivers/infiniband/hw/mthca/mthca_mr.c @@ -146,8 +146,7 @@ static int mthca_buddy_init(struct mthca_buddy *buddy, int max_order) buddy->bits = kcalloc(buddy->max_order + 1, sizeof(*buddy->bits), GFP_KERNEL); - buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, - GFP_KERNEL); + buddy->num_free = kzalloc_objs(*buddy->num_free, (buddy->max_order + 1)); if (!buddy->bits || !buddy->num_free) goto err_out; @@ -212,7 +211,7 @@ static struct mthca_mtt *__mthca_alloc_mtt(struct mthca_dev *dev, int size, if (size <= 0) return ERR_PTR(-EINVAL); - mtt = kmalloc(sizeof *mtt, GFP_KERNEL); + mtt = kmalloc_obj(*mtt); if (!mtt) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/mthca/mthca_profile.c b/drivers/infiniband/hw/mthca/mthca_profile.c index 69af65f1b332..5a0643ddefdd 100644 --- a/drivers/infiniband/hw/mthca/mthca_profile.c +++ b/drivers/infiniband/hw/mthca/mthca_profile.c @@ -77,7 +77,7 @@ s64 mthca_make_profile(struct mthca_dev *dev, struct mthca_resource *profile; int i, j; - profile = kcalloc(MTHCA_RES_NUM, sizeof(*profile), GFP_KERNEL); + profile = kzalloc_objs(*profile, MTHCA_RES_NUM); if (!profile) return -ENOMEM; diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index dd572d76866c..5c182ae4fc2f 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c @@ -61,8 +61,8 @@ static int mthca_query_device(struct ib_device *ibdev, struct ib_device_attr *pr if (uhw->inlen || uhw->outlen) return -EINVAL; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -125,8 +125,8 @@ static int mthca_query_port(struct ib_device *ibdev, struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -221,8 +221,8 @@ static int mthca_query_pkey(struct ib_device *ibdev, struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -250,8 +250,8 @@ static int mthca_query_gid(struct ib_device *ibdev, u32 port, struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; @@ -428,6 +428,8 @@ static int mthca_create_srq(struct ib_srq *ibsrq, if (context && ib_copy_to_udata(udata, &srq->srqn, sizeof(__u32))) { mthca_free_srq(to_mdev(ibsrq->device), srq); + mthca_unmap_user_db(to_mdev(ibsrq->device), &context->uar, + context->db_tab, ucmd.db_index); return -EFAULT; } @@ -436,6 +438,7 @@ static int mthca_create_srq(struct ib_srq *ibsrq, static int mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata) { + mthca_free_srq(to_mdev(srq->device), to_msrq(srq)); if (udata) { struct mthca_ucontext *context = rdma_udata_to_drv_context( @@ -446,8 +449,6 @@ static int mthca_destroy_srq(struct ib_srq *srq, struct ib_udata *udata) mthca_unmap_user_db(to_mdev(srq->device), &context->uar, context->db_tab, to_msrq(srq)->db_index); } - - mthca_free_srq(to_mdev(srq->device), to_msrq(srq)); return 0; } @@ -516,7 +517,7 @@ static int mthca_create_qp(struct ib_qp *ibqp, case IB_QPT_SMI: case IB_QPT_GSI: { - qp->sqp = kzalloc(sizeof(struct mthca_sqp), GFP_KERNEL); + qp->sqp = kzalloc_obj(struct mthca_sqp); if (!qp->sqp) return -ENOMEM; @@ -660,7 +661,7 @@ static int mthca_alloc_resize_buf(struct mthca_dev *dev, struct mthca_cq *cq, goto unlock; } - cq->resize_buf = kmalloc(sizeof *cq->resize_buf, GFP_ATOMIC); + cq->resize_buf = kmalloc_obj(*cq->resize_buf, GFP_ATOMIC); if (!cq->resize_buf) { ret = -ENOMEM; goto unlock; @@ -806,7 +807,7 @@ static struct ib_mr *mthca_get_dma_mr(struct ib_pd *pd, int acc) struct mthca_mr *mr; int err; - mr = kmalloc(sizeof *mr, GFP_KERNEL); + mr = kmalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -853,7 +854,7 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd)) return ERR_PTR(-EFAULT); - mr = kmalloc(sizeof *mr, GFP_KERNEL); + mr = kmalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -998,8 +999,8 @@ static int mthca_init_node_data(struct mthca_dev *dev) struct ib_smp *out_mad; int err = -ENOMEM; - in_mad = kzalloc(sizeof *in_mad, GFP_KERNEL); - out_mad = kmalloc(sizeof *out_mad, GFP_KERNEL); + in_mad = kzalloc_obj(*in_mad); + out_mad = kmalloc_obj(*out_mad); if (!in_mad || !out_mad) goto out; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c index 56f06c68f31a..006ef2e6b5f3 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_hw.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_hw.c @@ -355,7 +355,7 @@ static void *ocrdma_init_emb_mqe(u8 opcode, u32 cmd_len) { struct ocrdma_mqe *mqe; - mqe = kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL); + mqe = kzalloc_obj(struct ocrdma_mqe); if (!mqe) return NULL; mqe->hdr.spcl_sge_cnt_emb |= @@ -1289,7 +1289,7 @@ int ocrdma_mbx_rdma_stats(struct ocrdma_dev *dev, bool reset) struct ocrdma_rdma_stats_resp *old_stats; int status; - old_stats = kmalloc(sizeof(*old_stats), GFP_KERNEL); + old_stats = kmalloc_obj(*old_stats); if (old_stats == NULL) return -ENOMEM; @@ -1332,7 +1332,7 @@ static int ocrdma_mbx_get_ctrl_attribs(struct ocrdma_dev *dev) struct ocrdma_get_ctrl_attribs_rsp *ctrl_attr_rsp; struct mgmt_hba_attribs *hba_attribs; - mqe = kzalloc(sizeof(struct ocrdma_mqe), GFP_KERNEL); + mqe = kzalloc_obj(struct ocrdma_mqe); if (!mqe) return status; @@ -1592,8 +1592,7 @@ void ocrdma_alloc_pd_pool(struct ocrdma_dev *dev) { int status; - dev->pd_mgr = kzalloc(sizeof(struct ocrdma_pd_resource_mgr), - GFP_KERNEL); + dev->pd_mgr = kzalloc_obj(struct ocrdma_pd_resource_mgr); if (!dev->pd_mgr) return; @@ -3082,7 +3081,7 @@ static int ocrdma_create_eqs(struct ocrdma_dev *dev) if (!num_eq) return -EINVAL; - dev->eq_tbl = kcalloc(num_eq, sizeof(struct ocrdma_eq), GFP_KERNEL); + dev->eq_tbl = kzalloc_objs(struct ocrdma_eq, num_eq); if (!dev->eq_tbl) return -ENOMEM; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 5d4b3bc16493..b62a9bf160c5 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c @@ -219,15 +219,12 @@ static int ocrdma_register_device(struct ocrdma_dev *dev) static int ocrdma_alloc_resources(struct ocrdma_dev *dev) { mutex_init(&dev->dev_lock); - dev->cq_tbl = kcalloc(OCRDMA_MAX_CQ, sizeof(struct ocrdma_cq *), - GFP_KERNEL); + dev->cq_tbl = kzalloc_objs(struct ocrdma_cq *, OCRDMA_MAX_CQ); if (!dev->cq_tbl) goto alloc_err; if (dev->attr.max_qp) { - dev->qp_tbl = kcalloc(OCRDMA_MAX_QP, - sizeof(struct ocrdma_qp *), - GFP_KERNEL); + dev->qp_tbl = kzalloc_objs(struct ocrdma_qp *, OCRDMA_MAX_QP); if (!dev->qp_tbl) goto alloc_err; } @@ -271,7 +268,7 @@ static struct ocrdma_dev *ocrdma_add(struct be_dev_info *dev_info) return NULL; } - dev->mbx_cmd = kzalloc(sizeof(struct ocrdma_mqe_emb_cmd), GFP_KERNEL); + dev->mbx_cmd = kzalloc_obj(struct ocrdma_mqe_emb_cmd); if (!dev->mbx_cmd) goto init_err; diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c index 46d911fd38de..e89be2fbd5eb 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c @@ -195,7 +195,7 @@ static int ocrdma_add_mmap(struct ocrdma_ucontext *uctx, u64 phy_addr, { struct ocrdma_mm *mm; - mm = kzalloc(sizeof(*mm), GFP_KERNEL); + mm = kzalloc_obj(*mm); if (mm == NULL) return -ENOMEM; mm->key.phy_addr = phy_addr; @@ -727,7 +727,7 @@ struct ib_mr *ocrdma_get_dma_mr(struct ib_pd *ibpd, int acc) return ERR_PTR(-EINVAL); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -794,8 +794,7 @@ static int ocrdma_build_pbl_tbl(struct ocrdma_dev *dev, struct ocrdma_hw_mr *mr) void *va; dma_addr_t pa; - mr->pbl_table = kcalloc(mr->num_pbls, sizeof(struct ocrdma_pbl), - GFP_KERNEL); + mr->pbl_table = kzalloc_objs(struct ocrdma_pbl, mr->num_pbls); if (!mr->pbl_table) return -ENOMEM; @@ -863,7 +862,7 @@ struct ib_mr *ocrdma_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(status); mr->umem = ib_umem_get(ibpd->device, start, len, acc); @@ -1255,8 +1254,7 @@ static void ocrdma_set_qp_db(struct ocrdma_dev *dev, struct ocrdma_qp *qp, static int ocrdma_alloc_wr_id_tbl(struct ocrdma_qp *qp) { qp->wqe_wr_id_tbl = - kcalloc(qp->sq.max_cnt, sizeof(*(qp->wqe_wr_id_tbl)), - GFP_KERNEL); + kzalloc_objs(*(qp->wqe_wr_id_tbl), qp->sq.max_cnt); if (qp->wqe_wr_id_tbl == NULL) return -ENOMEM; qp->rqe_wr_id_tbl = @@ -2911,7 +2909,7 @@ struct ib_mr *ocrdma_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, if (max_num_sg > dev->attr.max_pages_per_frmr) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/qedr/main.c b/drivers/infiniband/hw/qedr/main.c index ecdfeff3d44f..8f7f01e8fe08 100644 --- a/drivers/infiniband/hw/qedr/main.c +++ b/drivers/infiniband/hw/qedr/main.c @@ -333,8 +333,7 @@ static int qedr_alloc_resources(struct qedr_dev *dev) __le16 *cons_pi; int i, rc; - dev->sgid_tbl = kcalloc(QEDR_MAX_SGID, sizeof(union ib_gid), - GFP_KERNEL); + dev->sgid_tbl = kzalloc_objs(union ib_gid, QEDR_MAX_SGID); if (!dev->sgid_tbl) return -ENOMEM; @@ -351,15 +350,13 @@ static int qedr_alloc_resources(struct qedr_dev *dev) } /* Allocate Status blocks for CNQ */ - dev->sb_array = kcalloc(dev->num_cnq, sizeof(*dev->sb_array), - GFP_KERNEL); + dev->sb_array = kzalloc_objs(*dev->sb_array, dev->num_cnq); if (!dev->sb_array) { rc = -ENOMEM; goto err_destroy_wq; } - dev->cnq_array = kcalloc(dev->num_cnq, - sizeof(*dev->cnq_array), GFP_KERNEL); + dev->cnq_array = kzalloc_objs(*dev->cnq_array, dev->num_cnq); if (!dev->cnq_array) { rc = -ENOMEM; goto err2; @@ -789,7 +786,7 @@ static int qedr_init_hw(struct qedr_dev *dev) int rc = 0; int i; - in_params = kzalloc(sizeof(*in_params), GFP_KERNEL); + in_params = kzalloc_obj(*in_params); if (!in_params) { rc = -ENOMEM; goto out; diff --git a/drivers/infiniband/hw/qedr/qedr_iw_cm.c b/drivers/infiniband/hw/qedr/qedr_iw_cm.c index 259303b9907c..8d38e74f1b12 100644 --- a/drivers/infiniband/hw/qedr/qedr_iw_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_iw_cm.c @@ -108,7 +108,7 @@ qedr_iw_mpa_request(void *context, struct qed_iwarp_cm_event_params *params) struct iw_cm_event event; struct qedr_iw_ep *ep; - ep = kzalloc(sizeof(*ep), GFP_ATOMIC); + ep = kzalloc_obj(*ep, GFP_ATOMIC); if (!ep) return; @@ -258,7 +258,7 @@ qedr_iw_disconnect_event(void *context, struct qedr_iw_ep *ep = (struct qedr_iw_ep *)context; struct qedr_dev *dev = ep->dev; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return; @@ -560,7 +560,7 @@ int qedr_iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) if (!laddr->sin_port || !raddr->sin_port) return -EINVAL; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -672,7 +672,7 @@ int qedr_iw_create_listen(struct iw_cm_id *cm_id, int backlog) DP_DEBUG(dev, QEDR_MSG_IWARP, "Create Listener address: %pISpc\n", &cm_id->local_addr); - listener = kzalloc(sizeof(*listener), GFP_KERNEL); + listener = kzalloc_obj(*listener); if (!listener) return -ENOMEM; diff --git a/drivers/infiniband/hw/qedr/qedr_roce_cm.c b/drivers/infiniband/hw/qedr/qedr_roce_cm.c index 859f66a51bd2..c7273ed7aa6c 100644 --- a/drivers/infiniband/hw/qedr/qedr_roce_cm.c +++ b/drivers/infiniband/hw/qedr/qedr_roce_cm.c @@ -339,12 +339,10 @@ int qedr_create_gsi_qp(struct qedr_dev *dev, struct ib_qp_init_attr *attrs, qp->rq.max_wr = attrs->cap.max_recv_wr; qp->sq.max_wr = attrs->cap.max_send_wr; - qp->rqe_wr_id = kcalloc(qp->rq.max_wr, sizeof(*qp->rqe_wr_id), - GFP_KERNEL); + qp->rqe_wr_id = kzalloc_objs(*qp->rqe_wr_id, qp->rq.max_wr); if (!qp->rqe_wr_id) goto err; - qp->wqe_wr_id = kcalloc(qp->sq.max_wr, sizeof(*qp->wqe_wr_id), - GFP_KERNEL); + qp->wqe_wr_id = kzalloc_objs(*qp->wqe_wr_id, qp->sq.max_wr); if (!qp->wqe_wr_id) goto err; @@ -507,7 +505,7 @@ static inline int qedr_gsi_build_packet(struct qedr_dev *dev, header_size = ib_ud_header_pack(&udh, &ud_header_buffer); - packet = kzalloc(sizeof(*packet), GFP_ATOMIC); + packet = kzalloc_obj(*packet, GFP_ATOMIC); if (!packet) return -ENOMEM; diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c index ab9bf0922979..33b4a0e6d3a8 100644 --- a/drivers/infiniband/hw/qedr/verbs.c +++ b/drivers/infiniband/hw/qedr/verbs.c @@ -296,7 +296,7 @@ int qedr_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) ctx->dpi_addr = oparams.dpi_addr; ctx->dpi_phys_addr = oparams.dpi_phys_addr; ctx->dpi_size = oparams.dpi_size; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { rc = -ENOMEM; goto err; @@ -537,7 +537,7 @@ static struct qedr_pbl *qedr_alloc_pbl_tbl(struct qedr_dev *dev, void *va; int i; - pbl_table = kcalloc(pbl_info->num_pbls, sizeof(*pbl_table), flags); + pbl_table = kzalloc_objs(*pbl_table, pbl_info->num_pbls, flags); if (!pbl_table) return ERR_PTR(-ENOMEM); @@ -761,7 +761,7 @@ static int qedr_init_user_db_rec(struct ib_udata *udata, return -ENOMEM; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) goto err_free_db_data; @@ -820,7 +820,7 @@ static inline int qedr_init_user_queue(struct ib_udata *udata, qedr_populate_pbls(dev, q->umem, q->pbl_tbl, &q->pbl_info, FW_PAGE_SHIFT); } else { - q->pbl_tbl = kzalloc(sizeof(*q->pbl_tbl), GFP_KERNEL); + q->pbl_tbl = kzalloc_obj(*q->pbl_tbl); if (!q->pbl_tbl) { rc = -ENOMEM; goto err0; @@ -2187,8 +2187,7 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev, qp->sq.max_wr = min_t(u32, attrs->cap.max_send_wr * dev->wq_multiplier, dev->attr.max_sqe); - qp->wqe_wr_id = kcalloc(qp->sq.max_wr, sizeof(*qp->wqe_wr_id), - GFP_KERNEL); + qp->wqe_wr_id = kzalloc_objs(*qp->wqe_wr_id, qp->sq.max_wr); if (!qp->wqe_wr_id) { DP_ERR(dev, "create qp: failed SQ shadow memory allocation\n"); return -ENOMEM; @@ -2205,8 +2204,7 @@ static int qedr_create_kernel_qp(struct qedr_dev *dev, qp->rq.max_wr = (u16) max_t(u32, attrs->cap.max_recv_wr, 1); /* Allocate driver internal RQ array */ - qp->rqe_wr_id = kcalloc(qp->rq.max_wr, sizeof(*qp->rqe_wr_id), - GFP_KERNEL); + qp->rqe_wr_id = kzalloc_objs(*qp->rqe_wr_id, qp->rq.max_wr); if (!qp->rqe_wr_id) { DP_ERR(dev, "create qp: failed RQ shadow memory allocation\n"); @@ -2972,7 +2970,7 @@ struct ib_mr *qedr_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 len, if (acc & IB_ACCESS_REMOTE_WRITE && !(acc & IB_ACCESS_LOCAL_WRITE)) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(rc); @@ -3080,7 +3078,7 @@ static struct qedr_mr *__qedr_alloc_mr(struct ib_pd *ibpd, "qedr_alloc_frmr pd = %d max_page_list_len= %d\n", pd->pd_id, max_page_list_len); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(rc); @@ -3221,7 +3219,7 @@ struct ib_mr *qedr_get_dma_mr(struct ib_pd *ibpd, int acc) struct qedr_mr *mr; int rc; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/usnic/usnic_fwd.c b/drivers/infiniband/hw/usnic/usnic_fwd.c index 18a70850b738..39cdd72eabf6 100644 --- a/drivers/infiniband/hw/usnic/usnic_fwd.c +++ b/drivers/infiniband/hw/usnic/usnic_fwd.c @@ -85,7 +85,7 @@ struct usnic_fwd_dev *usnic_fwd_dev_alloc(struct pci_dev *pdev) { struct usnic_fwd_dev *ufdev; - ufdev = kzalloc(sizeof(*ufdev), GFP_KERNEL); + ufdev = kzalloc_obj(*ufdev); if (!ufdev) return NULL; @@ -210,7 +210,7 @@ usnic_fwd_alloc_flow(struct usnic_fwd_dev *ufdev, struct filter *filter, tlv_size = (2*sizeof(struct filter_tlv) + sizeof(struct filter) + sizeof(struct filter_action)); - flow = kzalloc(sizeof(*flow), GFP_ATOMIC); + flow = kzalloc_obj(*flow, GFP_ATOMIC); if (!flow) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/usnic/usnic_ib_main.c b/drivers/infiniband/hw/usnic/usnic_ib_main.c index 11eca39b73a9..9336dff81cc4 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_main.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_main.c @@ -556,7 +556,7 @@ static int usnic_ib_pci_probe(struct pci_dev *pdev, return -EPERM; } - vf = kzalloc(sizeof(*vf), GFP_KERNEL); + vf = kzalloc_obj(*vf); if (!vf) return -ENOMEM; diff --git a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c index 59bfbfaee325..a7327c7a7465 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_qp_grp.c @@ -232,7 +232,7 @@ create_roce_custom_flow(struct usnic_ib_qp_grp *qp_grp, } /* Create Flow Handle */ - qp_flow = kzalloc(sizeof(*qp_flow), GFP_ATOMIC); + qp_flow = kzalloc_obj(*qp_flow, GFP_ATOMIC); if (!qp_flow) { err = -ENOMEM; goto out_dealloc_flow; @@ -305,7 +305,7 @@ create_udp_flow(struct usnic_ib_qp_grp *qp_grp, } /* Create qp_flow */ - qp_flow = kzalloc(sizeof(*qp_flow), GFP_ATOMIC); + qp_flow = kzalloc_obj(*qp_flow, GFP_ATOMIC); if (!qp_flow) { err = -ENOMEM; goto out_dealloc_flow; @@ -542,8 +542,8 @@ alloc_res_chunk_list(struct usnic_vnic *vnic, /* Do Nothing */ } - res_chunk_list = kcalloc(res_lst_sz + 1, sizeof(*res_chunk_list), - GFP_ATOMIC); + res_chunk_list = kzalloc_objs(*res_chunk_list, res_lst_sz + 1, + GFP_ATOMIC); if (!res_chunk_list) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c index ae5df96589d9..16b269128f52 100644 --- a/drivers/infiniband/hw/usnic/usnic_ib_verbs.c +++ b/drivers/infiniband/hw/usnic/usnic_ib_verbs.c @@ -604,7 +604,7 @@ struct ib_mr *usnic_ib_reg_mr(struct ib_pd *pd, u64 start, u64 length, if (dmah) return ERR_PTR(-EOPNOTSUPP); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/usnic/usnic_uiom.c b/drivers/infiniband/hw/usnic/usnic_uiom.c index 3fbf99757b11..691c64a73516 100644 --- a/drivers/infiniband/hw/usnic/usnic_uiom.c +++ b/drivers/infiniband/hw/usnic/usnic_uiom.c @@ -149,9 +149,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable, off = 0; while (ret) { - chunk = kmalloc(struct_size(chunk, page_list, - min_t(int, ret, USNIC_UIOM_PAGE_CHUNK)), - GFP_KERNEL); + chunk = kmalloc_flex(*chunk, page_list, + min_t(int, ret, USNIC_UIOM_PAGE_CHUNK)); if (!chunk) { ret = -ENOMEM; goto out; @@ -351,7 +350,7 @@ struct usnic_uiom_reg *usnic_uiom_reg_get(struct usnic_uiom_pd *pd, vpn_start = (addr & PAGE_MASK) >> PAGE_SHIFT; vpn_last = vpn_start + npages - 1; - uiomr = kmalloc(sizeof(*uiomr), GFP_KERNEL); + uiomr = kmalloc_obj(*uiomr); if (!uiomr) return ERR_PTR(-ENOMEM); @@ -439,7 +438,7 @@ struct usnic_uiom_pd *usnic_uiom_alloc_pd(struct device *dev) struct usnic_uiom_pd *pd; void *domain; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return ERR_PTR(-ENOMEM); @@ -469,7 +468,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev) struct usnic_uiom_dev *uiom_dev; int err; - uiom_dev = kzalloc(sizeof(*uiom_dev), GFP_ATOMIC); + uiom_dev = kzalloc_obj(*uiom_dev, GFP_ATOMIC); if (!uiom_dev) return -ENOMEM; uiom_dev->dev = dev; @@ -533,7 +532,7 @@ struct device **usnic_uiom_get_dev_list(struct usnic_uiom_pd *pd) int i = 0; spin_lock(&pd->lock); - devs = kcalloc(pd->dev_cnt + 1, sizeof(*devs), GFP_ATOMIC); + devs = kzalloc_objs(*devs, pd->dev_cnt + 1, GFP_ATOMIC); if (!devs) { devs = ERR_PTR(-ENOMEM); goto out; diff --git a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c index 29d71267af78..235d3a124242 100644 --- a/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c +++ b/drivers/infiniband/hw/usnic/usnic_uiom_interval_tree.c @@ -70,7 +70,7 @@ static struct usnic_uiom_interval_node* usnic_uiom_interval_node_alloc(long int start, long int last, int ref_cnt, int flags) { - struct usnic_uiom_interval_node *interval = kzalloc(sizeof(*interval), + struct usnic_uiom_interval_node *interval = kzalloc_obj(*interval, GFP_ATOMIC); if (!interval) return NULL; diff --git a/drivers/infiniband/hw/usnic/usnic_vnic.c b/drivers/infiniband/hw/usnic/usnic_vnic.c index 0c47f73aaed5..70517a458926 100644 --- a/drivers/infiniband/hw/usnic/usnic_vnic.c +++ b/drivers/infiniband/hw/usnic/usnic_vnic.c @@ -239,12 +239,12 @@ usnic_vnic_get_resources(struct usnic_vnic *vnic, enum usnic_vnic_res_type type, if (usnic_vnic_res_free_cnt(vnic, type) < cnt || cnt < 0 || !owner) return ERR_PTR(-EINVAL); - ret = kzalloc(sizeof(*ret), GFP_ATOMIC); + ret = kzalloc_obj(*ret, GFP_ATOMIC); if (!ret) return ERR_PTR(-ENOMEM); if (cnt > 0) { - ret->res = kcalloc(cnt, sizeof(*(ret->res)), GFP_ATOMIC); + ret->res = kzalloc_objs(*(ret->res), cnt, GFP_ATOMIC); if (!ret->res) { kfree(ret); return ERR_PTR(-ENOMEM); @@ -311,12 +311,12 @@ static int usnic_vnic_alloc_res_chunk(struct usnic_vnic *vnic, } chunk->cnt = chunk->free_cnt = cnt; - chunk->res = kcalloc(cnt, sizeof(*(chunk->res)), GFP_KERNEL); + chunk->res = kzalloc_objs(*(chunk->res), cnt); if (!chunk->res) return -ENOMEM; for (i = 0; i < cnt; i++) { - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) { err = -ENOMEM; goto fail; @@ -445,7 +445,7 @@ struct usnic_vnic *usnic_vnic_alloc(struct pci_dev *pdev) return ERR_PTR(-EINVAL); } - vnic = kzalloc(sizeof(*vnic), GFP_KERNEL); + vnic = kzalloc_obj(*vnic); if (!vnic) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c index 1664d1d7d969..cc889b4889d8 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_main.c @@ -257,14 +257,12 @@ static int pvrdma_register_device(struct pvrdma_dev *dev) mutex_init(&dev->port_mutex); spin_lock_init(&dev->desc_lock); - dev->cq_tbl = kcalloc(dev->dsr->caps.max_cq, sizeof(struct pvrdma_cq *), - GFP_KERNEL); + dev->cq_tbl = kzalloc_objs(struct pvrdma_cq *, dev->dsr->caps.max_cq); if (!dev->cq_tbl) return ret; spin_lock_init(&dev->cq_tbl_lock); - dev->qp_tbl = kcalloc(dev->dsr->caps.max_qp, sizeof(struct pvrdma_qp *), - GFP_KERNEL); + dev->qp_tbl = kzalloc_objs(struct pvrdma_qp *, dev->dsr->caps.max_qp); if (!dev->qp_tbl) goto err_cq_free; spin_lock_init(&dev->qp_tbl_lock); @@ -273,9 +271,8 @@ static int pvrdma_register_device(struct pvrdma_dev *dev) if (dev->dsr->caps.max_srq) { ib_set_device_ops(&dev->ib_dev, &pvrdma_dev_srq_ops); - dev->srq_tbl = kcalloc(dev->dsr->caps.max_srq, - sizeof(struct pvrdma_srq *), - GFP_KERNEL); + dev->srq_tbl = kzalloc_objs(struct pvrdma_srq *, + dev->dsr->caps.max_srq); if (!dev->srq_tbl) goto err_qp_free; } @@ -752,7 +749,7 @@ static int pvrdma_netdevice_event(struct notifier_block *this, struct net_device *event_netdev = netdev_notifier_info_to_dev(ptr); struct pvrdma_netdevice_work *netdev_work; - netdev_work = kmalloc(sizeof(*netdev_work), GFP_ATOMIC); + netdev_work = kmalloc_obj(*netdev_work, GFP_ATOMIC); if (!netdev_work) return NOTIFY_BAD; @@ -985,8 +982,7 @@ static int pvrdma_pci_probe(struct pci_dev *pdev, } /* Allocate GID table */ - dev->sgid_tbl = kcalloc(dev->dsr->caps.gid_tbl_len, - sizeof(union ib_gid), GFP_KERNEL); + dev->sgid_tbl = kzalloc_objs(union ib_gid, dev->dsr->caps.gid_tbl_len); if (!dev->sgid_tbl) { ret = -ENOMEM; goto err_free_uar_table; diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c index ba43ad07898c..0864ad25b9d2 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_misc.c @@ -81,8 +81,7 @@ int pvrdma_page_dir_init(struct pvrdma_dev *dev, struct pvrdma_page_dir *pdir, pdir->npages = npages; if (alloc_pages) { - pdir->pages = kcalloc(npages, sizeof(*pdir->pages), - GFP_KERNEL); + pdir->pages = kzalloc_objs(*pdir->pages, npages); if (!pdir->pages) goto err; diff --git a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c index ec7a00c8285b..05a6bd991502 100644 --- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c +++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma_mr.c @@ -72,7 +72,7 @@ struct ib_mr *pvrdma_get_dma_mr(struct ib_pd *pd, int acc) return ERR_PTR(-EOPNOTSUPP); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -146,7 +146,7 @@ struct ib_mr *pvrdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, goto err_umem; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { ret = -ENOMEM; goto err_umem; @@ -222,7 +222,7 @@ struct ib_mr *pvrdma_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, max_num_sg > PVRDMA_MAX_FAST_REG_PAGES) return ERR_PTR(-EINVAL); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/sw/rdmavt/mcast.c b/drivers/infiniband/sw/rdmavt/mcast.c index 59045bdce2a9..1fda344d2056 100644 --- a/drivers/infiniband/sw/rdmavt/mcast.c +++ b/drivers/infiniband/sw/rdmavt/mcast.c @@ -34,7 +34,7 @@ static struct rvt_mcast_qp *rvt_mcast_qp_alloc(struct rvt_qp *qp) { struct rvt_mcast_qp *mqp; - mqp = kmalloc(sizeof(*mqp), GFP_KERNEL); + mqp = kmalloc_obj(*mqp); if (!mqp) goto bail; @@ -66,7 +66,7 @@ static struct rvt_mcast *rvt_mcast_alloc(union ib_gid *mgid, u16 lid) { struct rvt_mcast *mcast; - mcast = kzalloc(sizeof(*mcast), GFP_KERNEL); + mcast = kzalloc_obj(*mcast); if (!mcast) goto bail; diff --git a/drivers/infiniband/sw/rdmavt/mr.c b/drivers/infiniband/sw/rdmavt/mr.c index 86e482593a85..15f1ff917d6c 100644 --- a/drivers/infiniband/sw/rdmavt/mr.c +++ b/drivers/infiniband/sw/rdmavt/mr.c @@ -242,7 +242,7 @@ static struct rvt_mr *__rvt_alloc_mr(int count, struct ib_pd *pd) /* Allocate struct plus pointers to first level page tables. */ m = (count + RVT_SEGSZ - 1) / RVT_SEGSZ; - mr = kzalloc(struct_size(mr, mr.map, m), GFP_KERNEL); + mr = kzalloc_flex(*mr, mr.map, m); if (!mr) goto bail; @@ -292,7 +292,7 @@ struct ib_mr *rvt_get_dma_mr(struct ib_pd *pd, int acc) if (ibpd_to_rvtpd(pd)->user) return ERR_PTR(-EPERM); - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { ret = ERR_PTR(-ENOMEM); goto bail; diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c index 134a79eecfcb..c1199ea5d41f 100644 --- a/drivers/infiniband/sw/rdmavt/qp.c +++ b/drivers/infiniband/sw/rdmavt/qp.c @@ -2650,7 +2650,7 @@ struct rvt_qp_iter *rvt_qp_iter_init(struct rvt_dev_info *rdi, { struct rvt_qp_iter *i; - i = kzalloc(sizeof(*i), GFP_KERNEL); + i = kzalloc_obj(*i); if (!i) return NULL; diff --git a/drivers/infiniband/sw/rdmavt/vt.c b/drivers/infiniband/sw/rdmavt/vt.c index d22d610c2696..0c28b412d81a 100644 --- a/drivers/infiniband/sw/rdmavt/vt.c +++ b/drivers/infiniband/sw/rdmavt/vt.c @@ -53,7 +53,7 @@ struct rvt_dev_info *rvt_alloc_device(size_t size, int nports) if (!rdi) return rdi; - rdi->ports = kcalloc(nports, sizeof(*rdi->ports), GFP_KERNEL); + rdi->ports = kzalloc_objs(*rdi->ports, nports); if (!rdi->ports) ib_dealloc_device(&rdi->ibdev); diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 07ff47bae31d..5cad72073eca 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -223,7 +223,7 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) } /* speculative alloc of new mcg */ - mcg = kzalloc(sizeof(*mcg), GFP_KERNEL); + mcg = kzalloc_obj(*mcg); if (!mcg) { err = -ENOMEM; goto err_dec; @@ -363,7 +363,7 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) spin_unlock_bh(&rxe->mcg_lock); /* speculative alloc new mca without using GFP_ATOMIC */ - mca = kzalloc(sizeof(*mca), GFP_KERNEL); + mca = kzalloc_obj(*mca); if (!mca) return -ENOMEM; diff --git a/drivers/infiniband/sw/rxe/rxe_mmap.c b/drivers/infiniband/sw/rxe/rxe_mmap.c index 6b7f2bd69879..db380302149e 100644 --- a/drivers/infiniband/sw/rxe/rxe_mmap.c +++ b/drivers/infiniband/sw/rxe/rxe_mmap.c @@ -120,7 +120,7 @@ struct rxe_mmap_info *rxe_create_mmap_info(struct rxe_dev *rxe, u32 size, if (!udata) return ERR_PTR(-EINVAL); - ip = kmalloc(sizeof(*ip), GFP_KERNEL); + ip = kmalloc_obj(*ip); if (!ip) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index c71ab780e379..c696ff874980 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -156,8 +156,7 @@ static int rxe_mr_fill_pages_from_sgt(struct rxe_mr *mr, struct sg_table *sgt) static int __alloc_mr_page_info(struct rxe_mr *mr, int num_pages) { - mr->page_info = kcalloc(num_pages, sizeof(struct rxe_mr_page), - GFP_KERNEL); + mr->page_info = kzalloc_objs(struct rxe_mr_page, num_pages); if (!mr->page_info) return -ENOMEM; diff --git a/drivers/infiniband/sw/rxe/rxe_odp.c b/drivers/infiniband/sw/rxe/rxe_odp.c index d3a54bfaf92f..bc11b1ec59ac 100644 --- a/drivers/infiniband/sw/rxe/rxe_odp.c +++ b/drivers/infiniband/sw/rxe/rxe_odp.c @@ -523,7 +523,7 @@ static int rxe_ib_advise_mr_prefetch(struct ib_pd *ibpd, num_sge); /* Asynchronous call is "best-effort" and allowed to fail */ - work = kvzalloc(struct_size(work, frags, num_sge), GFP_KERNEL); + work = kvzalloc_flex(*work, frags, num_sge); if (!work) return -ENOMEM; diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 845bdd03ca28..f3dff1aea96a 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -152,7 +152,7 @@ static int alloc_rd_atomic_resources(struct rxe_qp *qp, unsigned int n) { qp->resp.res_head = 0; qp->resp.res_tail = 0; - qp->resp.resources = kcalloc(n, sizeof(struct resp_res), GFP_KERNEL); + qp->resp.resources = kzalloc_objs(struct resp_res, n); if (!qp->resp.resources) return -ENOMEM; diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c index 9611ee191a46..63a569d8df2b 100644 --- a/drivers/infiniband/sw/rxe/rxe_queue.c +++ b/drivers/infiniband/sw/rxe/rxe_queue.c @@ -63,7 +63,7 @@ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe, int *num_elem, if (*num_elem < 0) return NULL; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index 38d8c408320f..fe41362c5144 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -1245,7 +1245,7 @@ static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) struct rxe_mr *mr; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1288,7 +1288,7 @@ static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, return ERR_PTR(-EOPNOTSUPP); } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); @@ -1373,7 +1373,7 @@ static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, goto err_out; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c index 1d3de8209bfa..f7ac81c0f267 100644 --- a/drivers/infiniband/sw/siw/siw_cm.c +++ b/drivers/infiniband/sw/siw/siw_cm.c @@ -205,7 +205,7 @@ static void siw_cep_socket_assoc(struct siw_cep *cep, struct socket *s) static struct siw_cep *siw_cep_alloc(struct siw_device *sdev) { - struct siw_cep *cep = kzalloc(sizeof(*cep), GFP_KERNEL); + struct siw_cep *cep = kzalloc_obj(*cep); unsigned long flags; if (!cep) @@ -334,7 +334,7 @@ static int siw_cm_alloc_work(struct siw_cep *cep, int num) struct siw_cm_work *work; while (num--) { - work = kmalloc(sizeof(*work), GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) { if (!(list_empty(&cep->work_freelist))) siw_cm_free_work(cep); @@ -1915,7 +1915,7 @@ int siw_create_listen(struct iw_cm_id *id, int backlog) */ if (!id->provider_data) { id->provider_data = - kmalloc(sizeof(struct list_head), GFP_KERNEL); + kmalloc_obj(struct list_head); if (!id->provider_data) { rv = -ENOMEM; goto error; diff --git a/drivers/infiniband/sw/siw/siw_main.c b/drivers/infiniband/sw/siw/siw_main.c index 5168307229a9..9735b75ac933 100644 --- a/drivers/infiniband/sw/siw/siw_main.c +++ b/drivers/infiniband/sw/siw/siw_main.c @@ -128,14 +128,14 @@ static int siw_init_cpulist(void) siw_cpu_info.num_nodes = num_nodes; siw_cpu_info.tx_valid_cpus = - kcalloc(num_nodes, sizeof(struct cpumask *), GFP_KERNEL); + kzalloc_objs(struct cpumask *, num_nodes); if (!siw_cpu_info.tx_valid_cpus) { siw_cpu_info.num_nodes = 0; return -ENOMEM; } for (i = 0; i < siw_cpu_info.num_nodes; i++) { siw_cpu_info.tx_valid_cpus[i] = - kzalloc(sizeof(struct cpumask), GFP_KERNEL); + kzalloc_obj(struct cpumask); if (!siw_cpu_info.tx_valid_cpus[i]) goto out_err; diff --git a/drivers/infiniband/sw/siw/siw_mem.c b/drivers/infiniband/sw/siw/siw_mem.c index d5ddeb17bd22..98c802b3ed72 100644 --- a/drivers/infiniband/sw/siw/siw_mem.c +++ b/drivers/infiniband/sw/siw/siw_mem.c @@ -58,7 +58,7 @@ int siw_mr_add_mem(struct siw_mr *mr, struct ib_pd *pd, void *mem_obj, u64 start, u64 len, int rights) { struct siw_device *sdev = to_siw_dev(pd->device); - struct siw_mem *mem = kzalloc(sizeof(*mem), GFP_KERNEL); + struct siw_mem *mem = kzalloc_obj(*mem); struct xa_limit limit = XA_LIMIT(1, SIW_STAG_MAX_INDEX); u32 id, next; @@ -321,7 +321,7 @@ struct siw_pbl *siw_pbl_alloc(u32 num_buf) if (num_buf == 0) return ERR_PTR(-EINVAL); - pbl = kzalloc(struct_size(pbl, pbe, num_buf), GFP_KERNEL); + pbl = kzalloc_flex(*pbl, pbe, num_buf); if (!pbl) return ERR_PTR(-ENOMEM); @@ -347,12 +347,12 @@ struct siw_umem *siw_umem_get(struct ib_device *base_dev, u64 start, num_pages = PAGE_ALIGN(start + len - first_page_va) >> PAGE_SHIFT; num_chunks = (num_pages >> CHUNK_SHIFT) + 1; - umem = kzalloc(sizeof(*umem), GFP_KERNEL); + umem = kzalloc_obj(*umem); if (!umem) return ERR_PTR(-ENOMEM); umem->page_chunk = - kcalloc(num_chunks, sizeof(struct siw_page_chunk), GFP_KERNEL); + kzalloc_objs(struct siw_page_chunk, num_chunks); if (!umem->page_chunk) { rv = -ENOMEM; goto err_out; @@ -376,7 +376,7 @@ struct siw_umem *siw_umem_get(struct ib_device *base_dev, u64 start, for (i = 0; num_pages > 0; i++) { int nents = min_t(int, num_pages, PAGES_PER_CHUNK); struct page **plist = - kcalloc(nents, sizeof(struct page *), GFP_KERNEL); + kzalloc_objs(struct page *, nents); if (!plist) { rv = -ENOMEM; diff --git a/drivers/infiniband/sw/siw/siw_qp.c b/drivers/infiniband/sw/siw/siw_qp.c index c1e6e7d6e32f..bb780e3904a2 100644 --- a/drivers/infiniband/sw/siw/siw_qp.c +++ b/drivers/infiniband/sw/siw/siw_qp.c @@ -391,7 +391,7 @@ void siw_send_terminate(struct siw_qp *qp) return; } - term = kzalloc(sizeof(*term), GFP_KERNEL); + term = kzalloc_obj(*term); if (!term) return; @@ -405,7 +405,7 @@ void siw_send_terminate(struct siw_qp *qp) if ((qp->term_info.layer == TERM_ERROR_LAYER_DDP) || ((qp->term_info.layer == TERM_ERROR_LAYER_RDMAP) && (qp->term_info.etype != RDMAP_ETYPE_CATASTROPHIC))) { - err_hdr = kzalloc(sizeof(*err_hdr), GFP_KERNEL); + err_hdr = kzalloc_obj(*err_hdr); if (!err_hdr) { kfree(term); return; diff --git a/drivers/infiniband/sw/siw/siw_verbs.c b/drivers/infiniband/sw/siw/siw_verbs.c index efa2f097b582..ef504db8f2b4 100644 --- a/drivers/infiniband/sw/siw/siw_verbs.c +++ b/drivers/infiniband/sw/siw/siw_verbs.c @@ -274,7 +274,7 @@ siw_mmap_entry_insert(struct siw_ucontext *uctx, void *address, size_t length, u64 *offset) { - struct siw_user_mmap_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct siw_user_mmap_entry *entry = kzalloc_obj(*entry); int rv; *offset = SIW_INVAL_UOBJ_KEY; @@ -1360,7 +1360,7 @@ struct ib_mr *siw_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, umem = NULL; goto err_out; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { rv = -ENOMEM; goto err_out; @@ -1441,7 +1441,7 @@ struct ib_mr *siw_alloc_mr(struct ib_pd *pd, enum ib_mr_type mr_type, pbl = NULL; goto err_out; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { rv = -ENOMEM; goto err_out; @@ -1556,7 +1556,7 @@ struct ib_mr *siw_get_dma_mr(struct ib_pd *pd, int rights) rv = -ENOMEM; goto err_out; } - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { rv = -ENOMEM; goto err_out; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index b610d36295bb..57fec88a1629 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c @@ -360,7 +360,7 @@ static int ipoib_cm_nonsrq_init_rx(struct net_device *dev, struct ib_cm_id *cm_i if (!rx->rx_ring) return -ENOMEM; - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) { ret = -ENOMEM; goto err_free_1; @@ -449,7 +449,7 @@ static int ipoib_cm_req_handler(struct ib_cm_id *cm_id, int ret; ipoib_dbg(priv, "REQ arrived\n"); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; p->dev = dev; @@ -1304,7 +1304,7 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path struct ipoib_dev_priv *priv = ipoib_priv(dev); struct ipoib_cm_tx *tx; - tx = kzalloc(sizeof(*tx), GFP_ATOMIC); + tx = kzalloc_obj(*tx, GFP_ATOMIC); if (!tx) return NULL; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index 10b0dbda6cd5..5061d52a7b12 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -59,7 +59,7 @@ struct ipoib_ah *ipoib_create_ah(struct net_device *dev, struct ipoib_ah *ah; struct ib_ah *vah; - ah = kmalloc(sizeof(*ah), GFP_KERNEL); + ah = kmalloc_obj(*ah); if (!ah) return ERR_PTR(-ENOMEM); @@ -422,7 +422,7 @@ static void ipoib_ib_handle_tx_wc(struct net_device *dev, struct ib_wc *wc) ipoib_warn(priv, "failed send event (status=%d, wrid=%d vend_err %#x)\n", wc->status, wr_id, wc->vendor_err); - qp_work = kzalloc(sizeof(*qp_work), GFP_ATOMIC); + qp_work = kzalloc_obj(*qp_work, GFP_ATOMIC); if (!qp_work) return; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 4a504b7c4293..402671567736 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -169,7 +169,7 @@ static void ipoib_schedule_ifupdown_task(struct net_device *dev, bool up) (!up && !(dev->flags & IFF_UP))) return; - work = kmalloc(sizeof(*work), GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) return; work->dev = dev; @@ -673,7 +673,7 @@ struct ipoib_path_iter *ipoib_path_iter_init(struct net_device *dev) { struct ipoib_path_iter *iter; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return NULL; @@ -924,7 +924,7 @@ static struct ipoib_path *path_rec_create(struct net_device *dev, void *gid) if (!priv->broadcast) return NULL; - path = kzalloc(sizeof(*path), GFP_ATOMIC); + path = kzalloc_obj(*path, GFP_ATOMIC); if (!path) return NULL; @@ -1443,7 +1443,7 @@ static struct ipoib_neigh *ipoib_neigh_ctor(u8 *daddr, { struct ipoib_neigh *neigh; - neigh = kzalloc(sizeof(*neigh), GFP_ATOMIC); + neigh = kzalloc_obj(*neigh, GFP_ATOMIC); if (!neigh) return NULL; @@ -1593,11 +1593,11 @@ static int ipoib_neigh_hash_init(struct ipoib_dev_priv *priv) clear_bit(IPOIB_NEIGH_TBL_FLUSH, &priv->flags); ntbl->htbl = NULL; - htbl = kzalloc(sizeof(*htbl), GFP_KERNEL); + htbl = kzalloc_obj(*htbl); if (!htbl) return -ENOMEM; size = roundup_pow_of_two(arp_tbl.gc_thresh3); - buckets = kvcalloc(size, sizeof(*buckets), GFP_KERNEL); + buckets = kvzalloc_objs(*buckets, size); if (!buckets) { kfree(htbl); return -ENOMEM; @@ -1773,9 +1773,7 @@ static int ipoib_dev_init_default(struct net_device *dev) ipoib_napi_add(dev); /* Allocate RX/TX "rings" to hold queued skbs */ - priv->rx_ring = kcalloc(ipoib_recvq_size, - sizeof(*priv->rx_ring), - GFP_KERNEL); + priv->rx_ring = kzalloc_objs(*priv->rx_ring, ipoib_recvq_size); if (!priv->rx_ring) goto out; @@ -2278,7 +2276,7 @@ int ipoib_intf_init(struct ib_device *hca, u32 port, const char *name, struct ipoib_dev_priv *priv; int rc; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -2664,7 +2662,7 @@ static int ipoib_add_one(struct ib_device *device) unsigned int p; int count = 0; - dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL); + dev_list = kmalloc_obj(*dev_list); if (!dev_list) return -ENOMEM; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index 8a4ab9ff0a68..6401af2fd548 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -139,7 +139,7 @@ static struct ipoib_mcast *ipoib_mcast_alloc(struct net_device *dev) { struct ipoib_mcast *mcast; - mcast = kzalloc(sizeof(*mcast), GFP_ATOMIC); + mcast = kzalloc_obj(*mcast, GFP_ATOMIC); if (!mcast) return NULL; @@ -980,7 +980,7 @@ struct ipoib_mcast_iter *ipoib_mcast_iter_init(struct net_device *dev) { struct ipoib_mcast_iter *iter; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return NULL; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 86983080d28b..3ed1ea566690 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -52,7 +52,7 @@ int ipoib_mcast_attach(struct net_device *dev, struct ib_device *hca, if (set_qkey) { ret = -ENOMEM; - qp_attr = kmalloc(sizeof(*qp_attr), GFP_KERNEL); + qp_attr = kmalloc_obj(*qp_attr); if (!qp_attr) goto out; diff --git a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c index 243e8f555eca..ba3b45152907 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_vlan.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_vlan.c @@ -274,7 +274,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey) priv->child_type == IPOIB_LEGACY_CHILD) { struct ipoib_vlan_delete_work *work; - work = kmalloc(sizeof(*work), GFP_KERNEL); + work = kmalloc_obj(*work); if (!work) { rc = -ENOMEM; goto out; diff --git a/drivers/infiniband/ulp/iser/iscsi_iser.c b/drivers/infiniband/ulp/iser/iscsi_iser.c index dc531fad73de..7df441685780 100644 --- a/drivers/infiniband/ulp/iser/iscsi_iser.c +++ b/drivers/infiniband/ulp/iser/iscsi_iser.c @@ -802,7 +802,7 @@ static struct iscsi_endpoint *iscsi_iser_ep_connect(struct Scsi_Host *shost, if (!ep) return ERR_PTR(-ENOMEM); - iser_conn = kzalloc(sizeof(*iser_conn), GFP_KERNEL); + iser_conn = kzalloc_obj(*iser_conn); if (!iser_conn) { err = -ENOMEM; goto failure; diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index f5f090dc4f1e..12a2d12fef07 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -240,9 +240,8 @@ int iser_alloc_rx_descriptors(struct iser_conn *iser_conn, goto alloc_login_buf_fail; iser_conn->num_rx_descs = session->cmds_max; - iser_conn->rx_descs = kmalloc_array(iser_conn->num_rx_descs, - sizeof(struct iser_rx_desc), - GFP_KERNEL); + iser_conn->rx_descs = kmalloc_objs(struct iser_rx_desc, + iser_conn->num_rx_descs); if (!iser_conn->rx_descs) goto rx_desc_alloc_fail; diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 6801b70dc9e0..f03b3bb3c0c4 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -105,7 +105,7 @@ iser_create_fastreg_desc(struct iser_device *device, enum ib_mr_type mr_type; int ret; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return ERR_PTR(-ENOMEM); @@ -305,7 +305,7 @@ struct iser_device *iser_device_find_by_ib_device(struct rdma_cm_id *cma_id) if (device->ib_device->node_guid == cma_id->device->node_guid) goto inc_refcnt; - device = kzalloc(sizeof *device, GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) goto out; diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index af811d060cc8..348005e71891 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -152,9 +152,8 @@ isert_alloc_rx_descriptors(struct isert_conn *isert_conn) u64 dma_addr; int i, j; - isert_conn->rx_descs = kcalloc(ISERT_QP_MAX_RECV_DTOS, - sizeof(struct iser_rx_desc), - GFP_KERNEL); + isert_conn->rx_descs = kzalloc_objs(struct iser_rx_desc, + ISERT_QP_MAX_RECV_DTOS); if (!isert_conn->rx_descs) return -ENOMEM; @@ -275,7 +274,7 @@ isert_device_get(struct rdma_cm_id *cma_id) } } - device = kzalloc(sizeof(struct isert_device), GFP_KERNEL); + device = kzalloc_obj(struct isert_device); if (!device) { mutex_unlock(&device_list_mutex); return ERR_PTR(-ENOMEM); @@ -333,8 +332,7 @@ isert_alloc_login_buf(struct isert_conn *isert_conn, { int ret; - isert_conn->login_desc = kzalloc(sizeof(*isert_conn->login_desc), - GFP_KERNEL); + isert_conn->login_desc = kzalloc_obj(*isert_conn->login_desc); if (!isert_conn->login_desc) return -ENOMEM; @@ -429,7 +427,7 @@ isert_connect_request(struct rdma_cm_id *cma_id, struct rdma_cm_event *event) isert_dbg("cma_id: %p, portal: %p\n", cma_id, cma_id->context); - isert_conn = kzalloc(sizeof(struct isert_conn), GFP_KERNEL); + isert_conn = kzalloc_obj(struct isert_conn); if (!isert_conn) return -ENOMEM; @@ -2269,7 +2267,7 @@ isert_setup_np(struct iscsi_np *np, struct rdma_cm_id *isert_lid; int ret; - isert_np = kzalloc(sizeof(struct isert_np), GFP_KERNEL); + isert_np = kzalloc_obj(struct isert_np); if (!isert_np) return -ENOMEM; diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c index 31cd361416ac..53dcf06fbee0 100644 --- a/drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c +++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_encap.c @@ -238,7 +238,7 @@ int opa_vnic_update_mac_tbl(struct opa_vnic_adapter *adapter, if (!memcmp(mac_addr, empty_mac, ARRAY_SIZE(empty_mac))) continue; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) { rc = -ENOMEM; goto updt_done; @@ -265,7 +265,7 @@ int opa_vnic_update_mac_tbl(struct opa_vnic_adapter *adapter, (node->index < (loffset + lnum_entries))) continue; - new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); + new_node = kzalloc_obj(*new_node); if (!new_node) { rc = -ENOMEM; goto updt_done; diff --git a/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c index 071f35711468..1c3e7251f0f4 100644 --- a/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c +++ b/drivers/infiniband/ulp/opa_vnic/opa_vnic_netdev.c @@ -337,7 +337,7 @@ struct opa_vnic_adapter *opa_vnic_add_netdev(struct ib_device *ibdev, return ERR_CAST(netdev); rn = netdev_priv(netdev); - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) { rc = -ENOMEM; goto adapter_err; diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c index 59e30640f94a..3362362f9e2e 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c @@ -1364,9 +1364,7 @@ static int alloc_path_reqs(struct rtrs_clt_path *clt_path) enum ib_mr_type mr_type; int i, err = -ENOMEM; - clt_path->reqs = kcalloc(clt_path->queue_depth, - sizeof(*clt_path->reqs), - GFP_KERNEL); + clt_path->reqs = kzalloc_objs(*clt_path->reqs, clt_path->queue_depth); if (!clt_path->reqs) return -ENOMEM; @@ -1384,7 +1382,7 @@ static int alloc_path_reqs(struct rtrs_clt_path *clt_path) if (!req->iu) goto out; - req->sge = kcalloc(2, sizeof(*req->sge), GFP_KERNEL); + req->sge = kzalloc_objs(*req->sge, 2); if (!req->sge) goto out; @@ -1538,7 +1536,7 @@ static struct rtrs_clt_path *alloc_path(struct rtrs_clt_sess *clt, int cpu; size_t total_con; - clt_path = kzalloc(sizeof(*clt_path), GFP_KERNEL); + clt_path = kzalloc_obj(*clt_path); if (!clt_path) goto err; @@ -1547,15 +1545,14 @@ static struct rtrs_clt_path *alloc_path(struct rtrs_clt_sess *clt, * +1: Extra connection for user messages */ total_con = con_num + nr_poll_queues + 1; - clt_path->s.con = kcalloc(total_con, sizeof(*clt_path->s.con), - GFP_KERNEL); + clt_path->s.con = kzalloc_objs(*clt_path->s.con, total_con); if (!clt_path->s.con) goto err_free_path; clt_path->s.con_num = total_con; clt_path->s.irq_con_num = con_num + 1; - clt_path->stats = kzalloc(sizeof(*clt_path->stats), GFP_KERNEL); + clt_path->stats = kzalloc_obj(*clt_path->stats); if (!clt_path->stats) goto err_free_con; @@ -1622,7 +1619,7 @@ static int create_con(struct rtrs_clt_path *clt_path, unsigned int cid) { struct rtrs_clt_con *con; - con = kzalloc(sizeof(*con), GFP_KERNEL); + con = kzalloc_obj(*con); if (!con) return -ENOMEM; @@ -1873,9 +1870,8 @@ static int rtrs_rdma_conn_established(struct rtrs_clt_con *con, } if (!clt_path->rbufs) { - clt_path->rbufs = kcalloc(queue_depth, - sizeof(*clt_path->rbufs), - GFP_KERNEL); + clt_path->rbufs = kzalloc_objs(*clt_path->rbufs, + queue_depth); if (!clt_path->rbufs) return -ENOMEM; } @@ -2730,7 +2726,7 @@ static struct rtrs_clt_sess *alloc_clt(const char *sessname, size_t paths_num, if (strlen(sessname) >= sizeof(clt->sessname)) return ERR_PTR(-EINVAL); - clt = kzalloc(sizeof(*clt), GFP_KERNEL); + clt = kzalloc_obj(*clt); if (!clt) return ERR_PTR(-ENOMEM); diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c index 2e09811a10b2..0140bfaed721 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c +++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c @@ -138,14 +138,12 @@ static int rtrs_srv_alloc_ops_ids(struct rtrs_srv_path *srv_path) struct rtrs_srv_op *id; int i, ret; - srv_path->ops_ids = kcalloc(srv->queue_depth, - sizeof(*srv_path->ops_ids), - GFP_KERNEL); + srv_path->ops_ids = kzalloc_objs(*srv_path->ops_ids, srv->queue_depth); if (!srv_path->ops_ids) goto err; for (i = 0; i < srv->queue_depth; ++i) { - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) goto err; @@ -589,7 +587,7 @@ static int map_cont_bufs(struct rtrs_srv_path *srv_path) chunks_per_mr = DIV_ROUND_UP(srv->queue_depth, mrs_num); } - srv_path->mrs = kcalloc(mrs_num, sizeof(*srv_path->mrs), GFP_KERNEL); + srv_path->mrs = kzalloc_objs(*srv_path->mrs, mrs_num); if (!srv_path->mrs) return -ENOMEM; @@ -837,7 +835,7 @@ static int process_info_req(struct rtrs_srv_con *con, strscpy(srv_path->s.sessname, msg->pathname, sizeof(srv_path->s.sessname)); - rwr = kcalloc(srv_path->mrs_num, sizeof(*rwr), GFP_KERNEL); + rwr = kzalloc_objs(*rwr, srv_path->mrs_num); if (!rwr) return -ENOMEM; @@ -1436,7 +1434,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, } /* need to allocate a new srv */ - srv = kzalloc(sizeof(*srv), GFP_KERNEL); + srv = kzalloc_obj(*srv); if (!srv) return ERR_PTR(-ENOMEM); @@ -1449,8 +1447,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, device_initialize(&srv->dev); srv->dev.release = rtrs_srv_dev_release; - srv->chunks = kcalloc(srv->queue_depth, sizeof(*srv->chunks), - GFP_KERNEL); + srv->chunks = kzalloc_objs(*srv->chunks, srv->queue_depth); if (!srv->chunks) goto err_free_srv; @@ -1715,7 +1712,7 @@ static int create_con(struct rtrs_srv_path *srv_path, u32 cq_num, max_send_wr, max_recv_wr, wr_limit; int err, cq_vector; - con = kzalloc(sizeof(*con), GFP_KERNEL); + con = kzalloc_obj(*con); if (!con) { err = -ENOMEM; goto err; @@ -1808,11 +1805,11 @@ static struct rtrs_srv_path *__alloc_path(struct rtrs_srv_sess *srv, err = -EEXIST; goto err; } - srv_path = kzalloc(sizeof(*srv_path), GFP_KERNEL); + srv_path = kzalloc_obj(*srv_path); if (!srv_path) goto err; - srv_path->stats = kzalloc(sizeof(*srv_path->stats), GFP_KERNEL); + srv_path->stats = kzalloc_obj(*srv_path->stats); if (!srv_path->stats) goto err_free_sess; @@ -1822,14 +1819,11 @@ static struct rtrs_srv_path *__alloc_path(struct rtrs_srv_sess *srv, srv_path->stats->srv_path = srv_path; - srv_path->dma_addr = kcalloc(srv->queue_depth, - sizeof(*srv_path->dma_addr), - GFP_KERNEL); + srv_path->dma_addr = kzalloc_objs(*srv_path->dma_addr, srv->queue_depth); if (!srv_path->dma_addr) goto err_free_percpu; - srv_path->s.con = kcalloc(con_num, sizeof(*srv_path->s.con), - GFP_KERNEL); + srv_path->s.con = kzalloc_objs(*srv_path->s.con, con_num); if (!srv_path->s.con) goto err_free_dma_addr; @@ -2162,7 +2156,7 @@ static struct rtrs_srv_ctx *alloc_srv_ctx(struct rtrs_srv_ops *ops) { struct rtrs_srv_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; diff --git a/drivers/infiniband/ulp/rtrs/rtrs.c b/drivers/infiniband/ulp/rtrs/rtrs.c index bc1208ae8216..a642626e0ecb 100644 --- a/drivers/infiniband/ulp/rtrs/rtrs.c +++ b/drivers/infiniband/ulp/rtrs/rtrs.c @@ -26,7 +26,7 @@ struct rtrs_iu *rtrs_iu_alloc(u32 iu_num, size_t size, gfp_t gfp_mask, struct rtrs_iu *ius, *iu; int i; - ius = kcalloc(iu_num, sizeof(*ius), gfp_mask); + ius = kzalloc_objs(*ius, iu_num, gfp_mask); if (!ius) return NULL; for (i = 0; i < iu_num; i++) { @@ -618,7 +618,7 @@ rtrs_ib_dev_find_or_add(struct ib_device *ib_dev, goto out_unlock; } mutex_unlock(&pool->mutex); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto out_err; diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 510f16004ecd..30339dcabb4d 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -225,7 +225,7 @@ static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, { struct srp_iu *iu; - iu = kmalloc(sizeof *iu, gfp_mask); + iu = kmalloc_obj(*iu, gfp_mask); if (!iu) goto out; @@ -274,7 +274,7 @@ static int srp_init_ib_qp(struct srp_target_port *target, struct ib_qp_attr *attr; int ret; - attr = kmalloc(sizeof *attr, GFP_KERNEL); + attr = kmalloc_obj(*attr); if (!attr) return -ENOMEM; @@ -418,7 +418,7 @@ static struct srp_fr_pool *srp_create_fr_pool(struct ib_device *device, if (pool_size <= 0) goto err; ret = -ENOMEM; - pool = kzalloc(struct_size(pool, desc, pool_size), GFP_KERNEL); + pool = kzalloc_flex(*pool, desc, pool_size); if (!pool) goto err; pool->size = pool_size; @@ -533,7 +533,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch) const int m = 1 + dev->use_fast_reg * target->mr_per_cmd * 2; int ret; - init_attr = kzalloc(sizeof *init_attr, GFP_KERNEL); + init_attr = kzalloc_obj(*init_attr); if (!init_attr) return -ENOMEM; @@ -806,7 +806,7 @@ static int srp_send_req(struct srp_rdma_ch *ch, uint32_t max_iu_len, char *ipi, *tpi; int status; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2257,12 +2257,10 @@ static int srp_alloc_iu_bufs(struct srp_rdma_ch *ch) struct srp_target_port *target = ch->target; int i; - ch->rx_ring = kcalloc(target->queue_size, sizeof(*ch->rx_ring), - GFP_KERNEL); + ch->rx_ring = kzalloc_objs(*ch->rx_ring, target->queue_size); if (!ch->rx_ring) goto err_no_ring; - ch->tx_ring = kcalloc(target->queue_size, sizeof(*ch->tx_ring), - GFP_KERNEL); + ch->tx_ring = kzalloc_objs(*ch->tx_ring, target->queue_size); if (!ch->tx_ring) goto err_no_ring; @@ -2387,7 +2385,7 @@ static void srp_cm_rep_handler(struct ib_cm_id *cm_id, if (!target->using_rdma_cm) { ret = -ENOMEM; - qp_attr = kmalloc(sizeof(*qp_attr), GFP_KERNEL); + qp_attr = kmalloc_obj(*qp_attr); if (!qp_attr) goto error; @@ -3824,8 +3822,7 @@ static ssize_t add_target_store(struct device *dev, num_online_cpus()); } - target->ch = kcalloc(target->ch_count, sizeof(*target->ch), - GFP_KERNEL); + target->ch = kzalloc_objs(*target->ch, target->ch_count); if (!target->ch) goto out; @@ -3960,7 +3957,7 @@ static struct srp_host *srp_add_port(struct srp_device *device, u32 port) { struct srp_host *host; - host = kzalloc(sizeof *host, GFP_KERNEL); + host = kzalloc_obj(*host); if (!host) return NULL; @@ -4010,7 +4007,7 @@ static int srp_add_one(struct ib_device *device) u64 max_pages_per_mr; unsigned int flags = 0; - srp_dev = kzalloc(sizeof(*srp_dev), GFP_KERNEL); + srp_dev = kzalloc_obj(*srp_dev); if (!srp_dev) return -ENOMEM; diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index e314e6a84d96..e00b87acf481 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c @@ -127,7 +127,7 @@ static struct kmem_cache *srpt_cache_get(unsigned int object_size) return e->c; } snprintf(name, sizeof(name), "srpt-%u", object_size); - e = kmalloc(sizeof(*e), GFP_KERNEL); + e = kmalloc_obj(*e); if (!e) return NULL; refcount_set(&e->ref, 1); @@ -790,7 +790,7 @@ static struct srpt_ioctx **srpt_alloc_ioctx_ring(struct srpt_device *sdev, WARN_ON(ioctx_size != sizeof(struct srpt_recv_ioctx) && ioctx_size != sizeof(struct srpt_send_ioctx)); - ring = kvmalloc_array(ring_size, sizeof(ring[0]), GFP_KERNEL); + ring = kvmalloc_objs(ring[0], ring_size); if (!ring) goto out; for (i = 0; i < ring_size; ++i) { @@ -965,8 +965,7 @@ static int srpt_alloc_rw_ctxs(struct srpt_send_ioctx *ioctx, if (nbufs == 1) { ioctx->rw_ctxs = &ioctx->s_rw_ctx; } else { - ioctx->rw_ctxs = kmalloc_array(nbufs, sizeof(*ioctx->rw_ctxs), - GFP_KERNEL); + ioctx->rw_ctxs = kmalloc_objs(*ioctx->rw_ctxs, nbufs); if (!ioctx->rw_ctxs) return -ENOMEM; } @@ -1181,7 +1180,7 @@ static int srpt_init_ch_qp(struct srpt_rdma_ch *ch, struct ib_qp *qp) WARN_ON_ONCE(ch->using_rdma_cm); - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return -ENOMEM; @@ -1857,7 +1856,7 @@ static int srpt_create_ch_ib(struct srpt_rdma_ch *ch) WARN_ON(ch->rq_size < 1); ret = -ENOMEM; - qp_init = kzalloc(sizeof(*qp_init), GFP_KERNEL); + qp_init = kzalloc_obj(*qp_init); if (!qp_init) goto out; @@ -2089,7 +2088,7 @@ static struct srpt_nexus *srpt_get_nexus(struct srpt_port *sport, if (nexus) break; - tmp_nexus = kzalloc(sizeof(*nexus), GFP_KERNEL); + tmp_nexus = kzalloc_obj(*nexus); if (!tmp_nexus) { nexus = ERR_PTR(-ENOMEM); break; @@ -2241,9 +2240,9 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, } ret = -ENOMEM; - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); - rej = kzalloc(sizeof(*rej), GFP_KERNEL); - rep_param = kzalloc(sizeof(*rep_param), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); + rej = kzalloc_obj(*rej); + rep_param = kzalloc_obj(*rep_param); if (!rsp || !rej || !rep_param) goto out; @@ -2273,7 +2272,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, } ret = -ENOMEM; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) { rej->reason = cpu_to_be32(SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES); pr_err("rejected SRP_LOGIN_REQ because out of memory.\n"); @@ -3210,8 +3209,7 @@ static int srpt_add_one(struct ib_device *device) pr_debug("device = %p\n", device); - sdev = kzalloc(struct_size(sdev, port, device->phys_port_cnt), - GFP_KERNEL); + sdev = kzalloc_flex(*sdev, port, device->phys_port_cnt); if (!sdev) return -ENOMEM; @@ -3790,7 +3788,7 @@ static struct se_portal_group *srpt_make_tpg(struct se_wwn *wwn, struct srpt_tpg *stpg; int res = -ENOMEM; - stpg = kzalloc(sizeof(*stpg), GFP_KERNEL); + stpg = kzalloc_obj(*stpg); if (!stpg) return ERR_PTR(res); stpg->sport_id = sport_id; @@ -3847,7 +3845,7 @@ static struct se_wwn *srpt_make_tport(struct target_fabric_configfs *tf, WARN_ON_ONCE(true); return &(*papi.port_id)->wwn; } - port_id = kzalloc(sizeof(*port_id), GFP_KERNEL); + port_id = kzalloc_obj(*port_id); if (!port_id) { srpt_sdev_put(sport->sdev); return ERR_PTR(-ENOMEM); diff --git a/drivers/input/apm-power.c b/drivers/input/apm-power.c index 70a9e1dfba33..028fcaf4c142 100644 --- a/drivers/input/apm-power.c +++ b/drivers/input/apm-power.c @@ -52,7 +52,7 @@ static int apmpower_connect(struct input_handler *handler, struct input_handle *handle; int error; - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + handle = kzalloc_obj(struct input_handle); if (!handle) return -ENOMEM; diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 90ff6be85cf4..c7325226cb86 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -465,7 +465,7 @@ static int evdev_open(struct inode *inode, struct file *file) struct evdev_client *client; int error; - client = kvzalloc(struct_size(client, buffer, bufsize), GFP_KERNEL); + client = kvzalloc_flex(*client, buffer, bufsize); if (!client) return -ENOMEM; @@ -1346,7 +1346,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, return error; } - evdev = kzalloc(sizeof(struct evdev), GFP_KERNEL); + evdev = kzalloc_obj(struct evdev); if (!evdev) { error = -ENOMEM; goto err_free_minor; diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c index 66f7ffe8c7e0..0e5d1d1ceb46 100644 --- a/drivers/input/ff-core.c +++ b/drivers/input/ff-core.c @@ -303,12 +303,11 @@ int input_ff_create(struct input_dev *dev, unsigned int max_effects) } struct ff_device *ff __free(kfree) = - kzalloc(struct_size(ff, effect_owners, max_effects), - GFP_KERNEL); + kzalloc_flex(*ff, effect_owners, max_effects); if (!ff) return -ENOMEM; - ff->effects = kcalloc(max_effects, sizeof(*ff->effects), GFP_KERNEL); + ff->effects = kzalloc_objs(*ff->effects, max_effects); if (!ff->effects) return -ENOMEM; diff --git a/drivers/input/ff-memless.c b/drivers/input/ff-memless.c index e0c1c61aae71..937370d04928 100644 --- a/drivers/input/ff-memless.c +++ b/drivers/input/ff-memless.c @@ -508,7 +508,7 @@ int input_ff_create_memless(struct input_dev *dev, void *data, int error; int i; - struct ml_device *ml __free(kfree) = kzalloc(sizeof(*ml), GFP_KERNEL); + struct ml_device *ml __free(kfree) = kzalloc_obj(*ml); if (!ml) return -ENOMEM; diff --git a/drivers/input/gameport/emu10k1-gp.c b/drivers/input/gameport/emu10k1-gp.c index 4f4583048f24..ee97621df59d 100644 --- a/drivers/input/gameport/emu10k1-gp.c +++ b/drivers/input/gameport/emu10k1-gp.c @@ -43,7 +43,7 @@ static int emu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct gameport *port; int error; - emu = kzalloc(sizeof(*emu), GFP_KERNEL); + emu = kzalloc_obj(*emu); port = gameport_allocate_port(); if (!emu || !port) { printk(KERN_ERR "emu10k1-gp: Memory allocation failed\n"); diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 7ae5009385cc..423cccdea34f 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c @@ -68,7 +68,7 @@ static int fm801_gp_probe(struct pci_dev *pci, const struct pci_device_id *id) struct gameport *port; int error; - gp = kzalloc(sizeof(*gp), GFP_KERNEL); + gp = kzalloc_obj(*gp); port = gameport_allocate_port(); if (!gp || !port) { printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index f4f12dd00fff..9707b155bc94 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -374,7 +374,7 @@ static int gameport_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) { pr_err("Not enough memory to queue event %d\n", event_type); retval = -ENOMEM; diff --git a/drivers/input/gameport/ns558.c b/drivers/input/gameport/ns558.c index 880e714b49bc..fdece6ec1df3 100644 --- a/drivers/input/gameport/ns558.c +++ b/drivers/input/gameport/ns558.c @@ -120,7 +120,7 @@ static int ns558_isa_probe(int io) return -EBUSY; } - ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL); + ns558 = kzalloc_obj(*ns558); port = gameport_allocate_port(); if (!ns558 || !port) { printk(KERN_ERR "ns558: Memory allocation failed.\n"); @@ -192,7 +192,7 @@ static int ns558_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *did) if (!request_region(ioport, iolen, "ns558-pnp")) return -EBUSY; - ns558 = kzalloc(sizeof(*ns558), GFP_KERNEL); + ns558 = kzalloc_obj(*ns558); port = gameport_allocate_port(); if (!ns558 || !port) { printk(KERN_ERR "ns558: Memory allocation failed\n"); diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 6bbf3806ea37..b08d1d08d0b4 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c @@ -101,7 +101,7 @@ static int input_leds_connect(struct input_handler *handler, if (!num_leds) return -ENXIO; - leds = kzalloc(struct_size(leds, leds, num_leds), GFP_KERNEL); + leds = kzalloc_flex(*leds, leds, num_leds); if (!leds) return -ENOMEM; diff --git a/drivers/input/input-mt.c b/drivers/input/input-mt.c index 09f518897d4a..c06e98fbd77c 100644 --- a/drivers/input/input-mt.c +++ b/drivers/input/input-mt.c @@ -50,7 +50,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, return -EINVAL; struct input_mt *mt __free(kfree) = - kzalloc(struct_size(mt, slots, num_slots), GFP_KERNEL); + kzalloc_flex(*mt, slots, num_slots); if (!mt) return -ENOMEM; @@ -84,7 +84,7 @@ int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); if (flags & INPUT_MT_TRACK) { unsigned int n2 = num_slots * num_slots; - mt->red = kcalloc(n2, sizeof(*mt->red), GFP_KERNEL); + mt->red = kzalloc_objs(*mt->red, n2); if (!mt->red) return -ENOMEM; } diff --git a/drivers/input/input-poller.c b/drivers/input/input-poller.c index 1ce83d6521bb..54dc07fcae0b 100644 --- a/drivers/input/input-poller.c +++ b/drivers/input/input-poller.c @@ -71,7 +71,7 @@ int input_setup_polling(struct input_dev *dev, { struct input_dev_poller *poller; - poller = kzalloc(sizeof(*poller), GFP_KERNEL); + poller = kzalloc_obj(*poller); if (!poller) { /* * We want to show message even though kzalloc() may have diff --git a/drivers/input/input.c b/drivers/input/input.c index a500e1e276c2..7b7490a1fbc6 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -439,7 +439,7 @@ void input_alloc_absinfo(struct input_dev *dev) if (dev->absinfo) return; - dev->absinfo = kcalloc(ABS_CNT, sizeof(*dev->absinfo), GFP_KERNEL); + dev->absinfo = kzalloc_objs(*dev->absinfo, ABS_CNT); if (!dev->absinfo) { dev_err(dev->dev.parent ?: &dev->dev, "%s: unable to allocate memory\n", __func__); @@ -1887,7 +1887,7 @@ struct input_dev *input_allocate_device(void) static atomic_t input_no = ATOMIC_INIT(-1); struct input_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -1897,7 +1897,7 @@ struct input_dev *input_allocate_device(void) * when we register the device. */ dev->max_vals = 10; - dev->vals = kcalloc(dev->max_vals, sizeof(*dev->vals), GFP_KERNEL); + dev->vals = kzalloc_objs(*dev->vals, dev->max_vals); if (!dev->vals) { kfree(dev); return NULL; diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index ba2b17288bcd..32459fd8a7c1 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -261,7 +261,7 @@ static int joydev_open(struct inode *inode, struct file *file) struct joydev_client *client; int error; - client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL); + client = kzalloc_obj(struct joydev_client); if (!client) return -ENOMEM; @@ -921,7 +921,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, return error; } - joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL); + joydev = kzalloc_obj(struct joydev); if (!joydev) { error = -ENOMEM; goto err_free_minor; diff --git a/drivers/input/joystick/a3d.c b/drivers/input/joystick/a3d.c index 15182f16ed19..48a1457961ef 100644 --- a/drivers/input/joystick/a3d.c +++ b/drivers/input/joystick/a3d.c @@ -249,7 +249,7 @@ static int a3d_connect(struct gameport *gameport, struct gameport_driver *drv) int i; int err; - a3d = kzalloc(sizeof(*a3d), GFP_KERNEL); + a3d = kzalloc_obj(*a3d); input_dev = input_allocate_device(); if (!a3d || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/adi.c b/drivers/input/joystick/adi.c index 963250de24b7..e07b71978509 100644 --- a/drivers/input/joystick/adi.c +++ b/drivers/input/joystick/adi.c @@ -456,7 +456,7 @@ static int adi_connect(struct gameport *gameport, struct gameport_driver *drv) int i; int err; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index c709b58d770a..b6f7bce1c14f 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -582,7 +582,7 @@ static int analog_connect(struct gameport *gameport, struct gameport_driver *drv int i; int err; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/input/joystick/as5011.c b/drivers/input/joystick/as5011.c index 49a0dfbbeb49..7b4d61626898 100644 --- a/drivers/input/joystick/as5011.c +++ b/drivers/input/joystick/as5011.c @@ -237,7 +237,7 @@ static int as5011_probe(struct i2c_client *client) return -ENODEV; } - as5011 = kmalloc(sizeof(*as5011), GFP_KERNEL); + as5011 = kmalloc_obj(*as5011); input_dev = input_allocate_device(); if (!as5011 || !input_dev) { dev_err(&client->dev, diff --git a/drivers/input/joystick/cobra.c b/drivers/input/joystick/cobra.c index 5a0ea3ad5efa..ffa6d49c81fe 100644 --- a/drivers/input/joystick/cobra.c +++ b/drivers/input/joystick/cobra.c @@ -141,7 +141,7 @@ static int cobra_connect(struct gameport *gameport, struct gameport_driver *drv) int i, j; int err; - cobra = kzalloc(sizeof(*cobra), GFP_KERNEL); + cobra = kzalloc_obj(*cobra); if (!cobra) return -ENOMEM; diff --git a/drivers/input/joystick/db9.c b/drivers/input/joystick/db9.c index d5c67a927404..e5d9b71aab99 100644 --- a/drivers/input/joystick/db9.c +++ b/drivers/input/joystick/db9.c @@ -585,7 +585,7 @@ static void db9_attach(struct parport *pp) return; } - db9 = kzalloc(sizeof(*db9), GFP_KERNEL); + db9 = kzalloc_obj(*db9); if (!db9) goto err_unreg_pardev; diff --git a/drivers/input/joystick/fsia6b.c b/drivers/input/joystick/fsia6b.c index 7e3bc99d766f..b0d73648477e 100644 --- a/drivers/input/joystick/fsia6b.c +++ b/drivers/input/joystick/fsia6b.c @@ -132,7 +132,7 @@ static int fsia6b_serio_connect(struct serio *serio, struct serio_driver *drv) int i, j; int sw_id = 0; - fsia6b = kzalloc(sizeof(*fsia6b), GFP_KERNEL); + fsia6b = kzalloc_obj(*fsia6b); if (!fsia6b) return -ENOMEM; diff --git a/drivers/input/joystick/gamecon.c b/drivers/input/joystick/gamecon.c index ae95cb3d0ae9..d84d453b51af 100644 --- a/drivers/input/joystick/gamecon.c +++ b/drivers/input/joystick/gamecon.c @@ -291,7 +291,7 @@ static int gc_n64_init_ff(struct input_dev *dev, int i) struct gc_subdev *sdev; int err; - sdev = kmalloc(sizeof(*sdev), GFP_KERNEL); + sdev = kmalloc_obj(*sdev); if (!sdev) return -ENOMEM; @@ -948,7 +948,7 @@ static void gc_attach(struct parport *pp) return; } - gc = kzalloc(sizeof(*gc), GFP_KERNEL); + gc = kzalloc_obj(*gc); if (!gc) { pr_err("Not enough memory\n"); goto err_unreg_pardev; diff --git a/drivers/input/joystick/gf2k.c b/drivers/input/joystick/gf2k.c index e7ff7bdb1a3a..5a1cdce0bc48 100644 --- a/drivers/input/joystick/gf2k.c +++ b/drivers/input/joystick/gf2k.c @@ -222,7 +222,7 @@ static int gf2k_connect(struct gameport *gameport, struct gameport_driver *drv) unsigned char data[GF2K_LENGTH]; int i, err; - gf2k = kzalloc(sizeof(*gf2k), GFP_KERNEL); + gf2k = kzalloc_obj(*gf2k); input_dev = input_allocate_device(); if (!gf2k || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/grip.c b/drivers/input/joystick/grip.c index f339ce2b7a33..2a3f768a7218 100644 --- a/drivers/input/joystick/grip.c +++ b/drivers/input/joystick/grip.c @@ -284,7 +284,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) int i, j, t; int err; - grip = kzalloc(sizeof(*grip), GFP_KERNEL); + grip = kzalloc_obj(*grip); if (!grip) return -ENOMEM; diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c index 5eadb5a3ca37..62fdd0831c83 100644 --- a/drivers/input/joystick/grip_mp.c +++ b/drivers/input/joystick/grip_mp.c @@ -632,7 +632,7 @@ static int grip_connect(struct gameport *gameport, struct gameport_driver *drv) struct grip_mp *grip; int err; - grip = kzalloc(sizeof(*grip), GFP_KERNEL); + grip = kzalloc_obj(*grip); if (!grip) return -ENOMEM; diff --git a/drivers/input/joystick/guillemot.c b/drivers/input/joystick/guillemot.c index 1c5a76f72239..13f0fa4d3938 100644 --- a/drivers/input/joystick/guillemot.c +++ b/drivers/input/joystick/guillemot.c @@ -163,7 +163,7 @@ static int guillemot_connect(struct gameport *gameport, struct gameport_driver * int i, t; int err; - guillemot = kzalloc(sizeof(*guillemot), GFP_KERNEL); + guillemot = kzalloc_obj(*guillemot); input_dev = input_allocate_device(); if (!guillemot || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/iforce/iforce-serio.c b/drivers/input/joystick/iforce/iforce-serio.c index 75b85c46dfa4..e235834888d2 100644 --- a/drivers/input/joystick/iforce/iforce-serio.c +++ b/drivers/input/joystick/iforce/iforce-serio.c @@ -185,7 +185,7 @@ static int iforce_serio_connect(struct serio *serio, struct serio_driver *drv) struct iforce_serio *iforce_serio; int err; - iforce_serio = kzalloc(sizeof(*iforce_serio), GFP_KERNEL); + iforce_serio = kzalloc_obj(*iforce_serio); if (!iforce_serio) return -ENOMEM; diff --git a/drivers/input/joystick/iforce/iforce-usb.c b/drivers/input/joystick/iforce/iforce-usb.c index 1f00f76b0174..0482eaaecf39 100644 --- a/drivers/input/joystick/iforce/iforce-usb.c +++ b/drivers/input/joystick/iforce/iforce-usb.c @@ -207,7 +207,7 @@ static int iforce_usb_probe(struct usb_interface *intf, if (!usb_endpoint_is_int_out(epout)) return -ENODEV; - iforce_usb = kzalloc(sizeof(*iforce_usb), GFP_KERNEL); + iforce_usb = kzalloc_obj(*iforce_usb); if (!iforce_usb) goto fail; diff --git a/drivers/input/joystick/interact.c b/drivers/input/joystick/interact.c index 262f022e5695..507cec36b220 100644 --- a/drivers/input/joystick/interact.c +++ b/drivers/input/joystick/interact.c @@ -192,7 +192,7 @@ static int interact_connect(struct gameport *gameport, struct gameport_driver *d int i, t; int err; - interact = kzalloc(sizeof(*interact), GFP_KERNEL); + interact = kzalloc_obj(*interact); input_dev = input_allocate_device(); if (!interact || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/joystick/joydump.c b/drivers/input/joystick/joydump.c index 865652a7821d..c9cbdcc7f31f 100644 --- a/drivers/input/joystick/joydump.c +++ b/drivers/input/joystick/joydump.c @@ -61,7 +61,7 @@ static int joydump_connect(struct gameport *gameport, struct gameport_driver *dr timeout = gameport_time(gameport, 10000); /* 10 ms */ - buf = kmalloc_array(BUF_SIZE, sizeof(struct joydump), GFP_KERNEL); + buf = kmalloc_objs(struct joydump, BUF_SIZE); if (!buf) { printk(KERN_INFO "joydump: no memory for testing\n"); goto jd_end; diff --git a/drivers/input/joystick/magellan.c b/drivers/input/joystick/magellan.c index 7622638e5bb8..201a049c8c06 100644 --- a/drivers/input/joystick/magellan.c +++ b/drivers/input/joystick/magellan.c @@ -132,7 +132,7 @@ static int magellan_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - magellan = kzalloc(sizeof(*magellan), GFP_KERNEL); + magellan = kzalloc_obj(*magellan); input_dev = input_allocate_device(); if (!magellan || !input_dev) goto fail1; diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c index 8b54f9b18e7c..7f36f73844a9 100644 --- a/drivers/input/joystick/maplecontrol.c +++ b/drivers/input/joystick/maplecontrol.c @@ -102,7 +102,7 @@ static int probe_maple_controller(struct device *dev) struct input_dev *idev; unsigned long data = be32_to_cpu(mdev->devinfo.function_data[0]); - pad = kzalloc(sizeof(*pad), GFP_KERNEL); + pad = kzalloc_obj(*pad); idev = input_allocate_device(); if (!pad || !idev) { error = -ENOMEM; diff --git a/drivers/input/joystick/n64joy.c b/drivers/input/joystick/n64joy.c index 94d2f4e96fe6..43a02bb99fc2 100644 --- a/drivers/input/joystick/n64joy.c +++ b/drivers/input/joystick/n64joy.c @@ -243,7 +243,7 @@ static int __init n64joy_probe(struct platform_device *pdev) int err = 0; u32 i, j, found = 0; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; mutex_init(&priv->n64joy_mutex); diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c index 3a5873e5fcb3..7f37d18c8477 100644 --- a/drivers/input/joystick/sidewinder.c +++ b/drivers/input/joystick/sidewinder.c @@ -578,7 +578,7 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv) comment[0] = 0; - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = kzalloc_obj(*sw); buf = kmalloc(SW_LENGTH, GFP_KERNEL); idbuf = kmalloc(SW_LENGTH, GFP_KERNEL); if (!sw || !buf || !idbuf) { diff --git a/drivers/input/joystick/spaceball.c b/drivers/input/joystick/spaceball.c index 4f2221001a95..1af299a41d13 100644 --- a/drivers/input/joystick/spaceball.c +++ b/drivers/input/joystick/spaceball.c @@ -199,7 +199,7 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv) if ((id = serio->id.id) > SPACEBALL_MAX_ID) return -ENODEV; - spaceball = kmalloc(sizeof(*spaceball), GFP_KERNEL); + spaceball = kmalloc_obj(*spaceball); input_dev = input_allocate_device(); if (!spaceball || !input_dev) goto fail1; diff --git a/drivers/input/joystick/spaceorb.c b/drivers/input/joystick/spaceorb.c index 7250d74d62a1..ba5b318993ec 100644 --- a/drivers/input/joystick/spaceorb.c +++ b/drivers/input/joystick/spaceorb.c @@ -147,7 +147,7 @@ static int spaceorb_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - spaceorb = kzalloc(sizeof(*spaceorb), GFP_KERNEL); + spaceorb = kzalloc_obj(*spaceorb); input_dev = input_allocate_device(); if (!spaceorb || !input_dev) goto fail1; diff --git a/drivers/input/joystick/stinger.c b/drivers/input/joystick/stinger.c index 1b24ea21aa30..011f9b137dca 100644 --- a/drivers/input/joystick/stinger.c +++ b/drivers/input/joystick/stinger.c @@ -118,7 +118,7 @@ static int stinger_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - stinger = kmalloc(sizeof(*stinger), GFP_KERNEL); + stinger = kmalloc_obj(*stinger); input_dev = input_allocate_device(); if (!stinger || !input_dev) goto fail1; diff --git a/drivers/input/joystick/tmdc.c b/drivers/input/joystick/tmdc.c index 514b1026e379..d419f41e62ac 100644 --- a/drivers/input/joystick/tmdc.c +++ b/drivers/input/joystick/tmdc.c @@ -264,7 +264,7 @@ static int tmdc_setup_port(struct tmdc *tmdc, int idx, unsigned char *data) int i, j, b = 0; int err; - tmdc->port[idx] = port = kzalloc(sizeof (struct tmdc_port), GFP_KERNEL); + tmdc->port[idx] = port = kzalloc_obj(struct tmdc_port); input_dev = input_allocate_device(); if (!port || !input_dev) { err = -ENOMEM; @@ -348,7 +348,7 @@ static int tmdc_connect(struct gameport *gameport, struct gameport_driver *drv) int i; int err; - tmdc = kzalloc(sizeof(*tmdc), GFP_KERNEL); + tmdc = kzalloc_obj(*tmdc); if (!tmdc) return -ENOMEM; diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index 5f69aef01791..4ee45f27290a 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c @@ -170,7 +170,7 @@ static void tgfx_attach(struct parport *pp) return; } - tgfx = kzalloc(sizeof(*tgfx), GFP_KERNEL); + tgfx = kzalloc_obj(*tgfx); if (!tgfx) { printk(KERN_ERR "turbografx.c: Not enough memory\n"); goto err_unreg_pardev; diff --git a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c index ab99d76e5d8d..fb452552ceb2 100644 --- a/drivers/input/joystick/twidjoy.c +++ b/drivers/input/joystick/twidjoy.c @@ -171,7 +171,7 @@ static int twidjoy_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - twidjoy = kzalloc(sizeof(*twidjoy), GFP_KERNEL); + twidjoy = kzalloc_obj(*twidjoy); input_dev = input_allocate_device(); if (!twidjoy || !input_dev) goto fail1; diff --git a/drivers/input/joystick/warrior.c b/drivers/input/joystick/warrior.c index ebeab441e9ec..2e1c6df98e24 100644 --- a/drivers/input/joystick/warrior.c +++ b/drivers/input/joystick/warrior.c @@ -124,7 +124,7 @@ static int warrior_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - warrior = kzalloc(sizeof(*warrior), GFP_KERNEL); + warrior = kzalloc_obj(*warrior); input_dev = input_allocate_device(); if (!warrior || !input_dev) goto fail1; diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 363d50949386..bf4accf3f581 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -1744,7 +1744,7 @@ static int xpad_led_probe(struct usb_xpad *xpad) if (xpad->xtype != XTYPE_XBOX360 && xpad->xtype != XTYPE_XBOX360W) return 0; - xpad->led = led = kzalloc(sizeof(*led), GFP_KERNEL); + xpad->led = led = kzalloc_obj(*led); if (!led) return -ENOMEM; @@ -2077,7 +2077,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id break; } - xpad = kzalloc(sizeof(*xpad), GFP_KERNEL); + xpad = kzalloc_obj(*xpad); if (!xpad) return -ENOMEM; diff --git a/drivers/input/joystick/zhenhua.c b/drivers/input/joystick/zhenhua.c index cc0e2a77ac5e..8ca1896639de 100644 --- a/drivers/input/joystick/zhenhua.c +++ b/drivers/input/joystick/zhenhua.c @@ -131,7 +131,7 @@ static int zhenhua_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - zhenhua = kzalloc(sizeof(*zhenhua), GFP_KERNEL); + zhenhua = kzalloc_obj(*zhenhua); input_dev = input_allocate_device(); if (!zhenhua || !input_dev) goto fail1; diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 422e28ad1e8e..840cdf5878dc 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c @@ -1277,7 +1277,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *dev; int err = -ENOMEM; - atkbd = kzalloc(sizeof(*atkbd), GFP_KERNEL); + atkbd = kzalloc_obj(*atkbd); dev = input_allocate_device(); if (!atkbd || !dev) goto fail1; diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 1c6b0461dc35..2822c592880b 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -269,7 +269,8 @@ static int cros_ec_keyb_work(struct notifier_block *nb, if (ckdev->ec->event_size != ckdev->cols) { dev_err(ckdev->dev, - "Discarded incomplete key matrix event.\n"); + "Discarded key matrix event, unexpected length: %d != %d\n", + ckdev->ec->event_size, ckdev->cols); return NOTIFY_OK; } diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index f9db86da0818..e19617485679 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -434,7 +434,7 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id) ms_to_ktime(bdata->software_debounce), HRTIMER_MODE_REL); } else { - mod_delayed_work(system_wq, + mod_delayed_work(system_dfl_wq, &bdata->work, msecs_to_jiffies(bdata->software_debounce)); } @@ -616,12 +616,19 @@ static int gpio_keys_setup_key(struct platform_device *pdev, break; } } else { - if (!button->irq) { - dev_err(dev, "Found button without gpio or irq\n"); - return -EINVAL; - } + if (button->irq) { + bdata->irq = button->irq; + } else { + irq = platform_get_irq_optional(pdev, idx); + if (irq < 0) { + error = irq; + return dev_err_probe(dev, error, + "Unable to determine IRQ# for button #%d", + idx); + } - bdata->irq = button->irq; + bdata->irq = irq; + } if (button->type && button->type != EV_KEY) { dev_err(dev, "Only EV_KEY allowed for IRQ buttons.\n"); diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 54afb38601b9..5ebde20df755 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c @@ -447,7 +447,7 @@ static int hil_dev_connect(struct serio *serio, struct serio_driver *drv) uint8_t did, *idd; int error; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); input_dev = input_allocate_device(); if (!dev || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 2f130f819363..f5c2267a2c00 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -608,7 +608,7 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) int i; int err; - lk = kzalloc(sizeof(*lk), GFP_KERNEL); + lk = kzalloc_obj(*lk); input_dev = input_allocate_device(); if (!lk || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/keyboard/locomokbd.c b/drivers/input/keyboard/locomokbd.c index 58d4f2096cf9..6351562ebf8d 100644 --- a/drivers/input/keyboard/locomokbd.c +++ b/drivers/input/keyboard/locomokbd.c @@ -224,7 +224,7 @@ static int locomokbd_probe(struct locomo_dev *dev) struct input_dev *input_dev; int i, err; - locomokbd = kzalloc(sizeof(*locomokbd), GFP_KERNEL); + locomokbd = kzalloc_obj(*locomokbd); input_dev = input_allocate_device(); if (!locomokbd || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 1a8f1fa53fbb..80a5181313e1 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -151,7 +151,7 @@ static int probe_maple_kbd(struct device *dev) mdev = to_maple_dev(dev); mdrv = to_maple_driver(dev->driver); - kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); + kbd = kzalloc_obj(*kbd); if (!kbd) { error = -ENOMEM; goto fail; diff --git a/drivers/input/keyboard/newtonkbd.c b/drivers/input/keyboard/newtonkbd.c index 71e0a3f830dd..e60d1181dad0 100644 --- a/drivers/input/keyboard/newtonkbd.c +++ b/drivers/input/keyboard/newtonkbd.c @@ -68,7 +68,7 @@ static int nkbd_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - nkbd = kzalloc(sizeof(*nkbd), GFP_KERNEL); + nkbd = kzalloc_obj(*nkbd); input_dev = input_allocate_device(); if (!nkbd || !input_dev) goto fail1; diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index 9e13f3f70a81..589f51d430c7 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c @@ -193,7 +193,7 @@ static int omap_kp_probe(struct platform_device *pdev) row_shift = get_count_order(pdata->cols); keycodemax = pdata->rows << row_shift; - omap_kp = kzalloc(struct_size(omap_kp, keymap, keycodemax), GFP_KERNEL); + omap_kp = kzalloc_flex(*omap_kp, keymap, keycodemax); input_dev = input_allocate_device(); if (!omap_kp || !input_dev) { kfree(omap_kp); diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index bffe89c0717a..e783244d0c91 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -193,7 +193,6 @@ static irqreturn_t omap4_keypad_irq_thread_fn(int irq, void *dev_id) kbd_write_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS, kbd_read_irqreg(keypad_data, OMAP4_KBD_IRQSTATUS)); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return IRQ_HANDLED; @@ -231,7 +230,6 @@ static int omap4_keypad_open(struct input_dev *input) enable_irq(keypad_data->irq); out: - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return error; @@ -265,7 +263,6 @@ static void omap4_keypad_close(struct input_dev *input) enable_irq(keypad_data->irq); clk_disable_unprepare(keypad_data->fck); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); } @@ -404,7 +401,6 @@ static int omap4_keypad_probe(struct platform_device *pdev) omap4_keypad_stop(keypad_data); } - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); if (error) return error; diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c index 159f41eedd41..6937f3576c05 100644 --- a/drivers/input/keyboard/sh_keysc.c +++ b/drivers/input/keyboard/sh_keysc.c @@ -184,7 +184,7 @@ static int sh_keysc_probe(struct platform_device *pdev) if (irq < 0) goto err0; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) { dev_err(&pdev->dev, "failed to allocate driver data\n"); error = -ENOMEM; diff --git a/drivers/input/keyboard/stowaway.c b/drivers/input/keyboard/stowaway.c index 7ef0b3f4f549..eade05542ed6 100644 --- a/drivers/input/keyboard/stowaway.c +++ b/drivers/input/keyboard/stowaway.c @@ -72,7 +72,7 @@ static int skbd_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - skbd = kzalloc(sizeof(*skbd), GFP_KERNEL); + skbd = kzalloc_obj(*skbd); input_dev = input_allocate_device(); if (!skbd || !input_dev) goto fail1; diff --git a/drivers/input/keyboard/sunkbd.c b/drivers/input/keyboard/sunkbd.c index 3299e1919b37..5a0020827047 100644 --- a/drivers/input/keyboard/sunkbd.c +++ b/drivers/input/keyboard/sunkbd.c @@ -262,7 +262,7 @@ static int sunkbd_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - sunkbd = kzalloc(sizeof(*sunkbd), GFP_KERNEL); + sunkbd = kzalloc_obj(*sunkbd); input_dev = input_allocate_device(); if (!sunkbd || !input_dev) goto fail1; diff --git a/drivers/input/keyboard/xtkbd.c b/drivers/input/keyboard/xtkbd.c index befa713268ae..c0b4978a8cd5 100644 --- a/drivers/input/keyboard/xtkbd.c +++ b/drivers/input/keyboard/xtkbd.c @@ -70,7 +70,7 @@ static int xtkbd_connect(struct serio *serio, struct serio_driver *drv) int err = -ENOMEM; int i; - xtkbd = kmalloc(sizeof(*xtkbd), GFP_KERNEL); + xtkbd = kmalloc_obj(*xtkbd); input_dev = input_allocate_device(); if (!xtkbd || !input_dev) goto fail1; diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c index 9159b5fec129..fee28e537898 100644 --- a/drivers/input/misc/88pm80x_onkey.c +++ b/drivers/input/misc/88pm80x_onkey.c @@ -57,7 +57,7 @@ static int pm80x_onkey_probe(struct platform_device *pdev) struct pm80x_onkey_info *info; int err; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index e84649af801d..8db2dca84975 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -772,7 +772,7 @@ static int ati_remote2_probe(struct usb_interface *interface, const struct usb_d if (alt->desc.bInterfaceNumber) return -ENODEV; - ar2 = kzalloc(sizeof (struct ati_remote2), GFP_KERNEL); + ar2 = kzalloc_obj(struct ati_remote2); if (!ar2) return -ENOMEM; diff --git a/drivers/input/misc/cm109.c b/drivers/input/misc/cm109.c index 0cfe5d4a573c..353d3c1d347d 100644 --- a/drivers/input/misc/cm109.c +++ b/drivers/input/misc/cm109.c @@ -696,7 +696,7 @@ static int cm109_usb_probe(struct usb_interface *intf, if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; @@ -721,7 +721,7 @@ static int cm109_usb_probe(struct usb_interface *intf, if (!dev->ctl_data) goto err_out; - dev->ctl_req = kmalloc(sizeof(*(dev->ctl_req)), GFP_KERNEL); + dev->ctl_req = kmalloc_obj(*(dev->ctl_req)); if (!dev->ctl_req) goto err_out; diff --git a/drivers/input/misc/cma3000_d0x.c b/drivers/input/misc/cma3000_d0x.c index b4232b0a3957..a641453188d9 100644 --- a/drivers/input/misc/cma3000_d0x.c +++ b/drivers/input/misc/cma3000_d0x.c @@ -285,7 +285,7 @@ struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, goto err_out; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); input_dev = input_allocate_device(); if (!data || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/misc/cs40l50-vibra.c b/drivers/input/misc/cs40l50-vibra.c index 7aa7d577e01b..996d6c38cca4 100644 --- a/drivers/input/misc/cs40l50-vibra.c +++ b/drivers/input/misc/cs40l50-vibra.c @@ -276,7 +276,7 @@ static void cs40l50_add_worker(struct work_struct *work) /* Update effect if already uploaded, otherwise create new effect */ effect = cs40l50_find_effect(work_data->effect->id, &vib->effect_head); if (!effect) { - effect = kzalloc(sizeof(*effect), GFP_KERNEL); + effect = kzalloc_obj(*effect); if (!effect) { error = -ENOMEM; goto err_pm; @@ -308,7 +308,6 @@ static void cs40l50_add_worker(struct work_struct *work) list_add(&effect->list, &vib->effect_head); } err_pm: - pm_runtime_mark_last_busy(vib->dev); pm_runtime_put_autosuspend(vib->dev); err_exit: work_data->error = error; @@ -368,7 +367,6 @@ static void cs40l50_start_worker(struct work_struct *work) dev_err(vib->dev, "Effect to play not found\n"); } - pm_runtime_mark_last_busy(vib->dev); pm_runtime_put_autosuspend(vib->dev); err_free: kfree(work_data); @@ -384,7 +382,6 @@ static void cs40l50_stop_worker(struct work_struct *work) vib->dsp.write(vib->dev, vib->regmap, vib->dsp.stop_cmd); - pm_runtime_mark_last_busy(vib->dev); pm_runtime_put_autosuspend(vib->dev); kfree(work_data); @@ -395,7 +392,7 @@ static int cs40l50_playback(struct input_dev *dev, int effect_id, int val) struct cs40l50_vibra *vib = input_get_drvdata(dev); struct cs40l50_work *work_data; - work_data = kzalloc(sizeof(*work_data), GFP_ATOMIC); + work_data = kzalloc_obj(*work_data, GFP_ATOMIC); if (!work_data) return -ENOMEM; @@ -456,7 +453,6 @@ static void cs40l50_erase_worker(struct work_struct *work) list_del(&erase_effect->list); kfree(erase_effect); err_pm: - pm_runtime_mark_last_busy(vib->dev); pm_runtime_put_autosuspend(vib->dev); err_exit: work_data->error = error; diff --git a/drivers/input/misc/da9052_onkey.c b/drivers/input/misc/da9052_onkey.c index cc23625019e3..180b3bc76525 100644 --- a/drivers/input/misc/da9052_onkey.c +++ b/drivers/input/misc/da9052_onkey.c @@ -80,7 +80,7 @@ static int da9052_onkey_probe(struct platform_device *pdev) return -EINVAL; } - onkey = kzalloc(sizeof(*onkey), GFP_KERNEL); + onkey = kzalloc_obj(*onkey); input_dev = input_allocate_device(); if (!onkey || !input_dev) { dev_err(&pdev->dev, "Failed to allocate memory\n"); diff --git a/drivers/input/misc/gpio_decoder.c b/drivers/input/misc/gpio_decoder.c index ee668eba302f..f0759dd39b35 100644 --- a/drivers/input/misc/gpio_decoder.c +++ b/drivers/input/misc/gpio_decoder.c @@ -6,13 +6,18 @@ * encoded numeric value into an input event. */ -#include +#include +#include +#include +#include #include #include -#include +#include +#include #include -#include #include +#include +#include struct gpio_decoder { struct gpio_descs *input_gpios; @@ -24,23 +29,18 @@ struct gpio_decoder { static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder) { struct gpio_descs *gpios = decoder->input_gpios; - unsigned int ret = 0; - int i, val; + DECLARE_BITMAP(values, 32); + unsigned int size; + int err; - for (i = 0; i < gpios->ndescs; i++) { - val = gpiod_get_value_cansleep(gpios->desc[i]); - if (val < 0) { - dev_err(decoder->dev, - "Error reading gpio %d: %d\n", - desc_to_gpio(gpios->desc[i]), val); - return val; - } - - val = !!val; - ret = (ret << 1) | val; + size = min(gpios->ndescs, 32U); + err = gpiod_get_array_value_cansleep(size, gpios->desc, gpios->info, values); + if (err) { + dev_err(decoder->dev, "Error reading GPIO: %d\n", err); + return err; } - return ret; + return bitmap_read(values, 0, size); } static void gpio_decoder_poll_gpios(struct input_dev *input) @@ -61,7 +61,7 @@ static int gpio_decoder_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct gpio_decoder *decoder; struct input_dev *input; - u32 max; + u32 max; int err; decoder = devm_kzalloc(dev, sizeof(*decoder), GFP_KERNEL); @@ -72,18 +72,18 @@ static int gpio_decoder_probe(struct platform_device *pdev) device_property_read_u32(dev, "linux,axis", &decoder->axis); decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); - if (IS_ERR(decoder->input_gpios)) { - dev_err(dev, "unable to acquire input gpios\n"); - return PTR_ERR(decoder->input_gpios); - } + if (IS_ERR(decoder->input_gpios)) + return dev_err_probe(dev, PTR_ERR(decoder->input_gpios), + "unable to acquire input gpios\n"); - if (decoder->input_gpios->ndescs < 2) { - dev_err(dev, "not enough gpios found\n"); - return -EINVAL; - } + if (decoder->input_gpios->ndescs < 2) + return dev_err_probe(dev, -EINVAL, "not enough gpios found\n"); + + if (decoder->input_gpios->ndescs > 31) + return dev_err_probe(dev, -EINVAL, "too many gpios found\n"); if (device_property_read_u32(dev, "decoder-max-value", &max)) - max = (1U << decoder->input_gpios->ndescs) - 1; + max = BIT(decoder->input_gpios->ndescs) - 1; input = devm_input_allocate_device(dev); if (!input) @@ -96,33 +96,27 @@ static int gpio_decoder_probe(struct platform_device *pdev) input_set_abs_params(input, decoder->axis, 0, max, 0, 0); err = input_setup_polling(input, gpio_decoder_poll_gpios); - if (err) { - dev_err(dev, "failed to set up polling\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, "failed to set up polling\n"); err = input_register_device(input); - if (err) { - dev_err(dev, "failed to register input device\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, "failed to register input device\n"); return 0; } -#ifdef CONFIG_OF static const struct of_device_id gpio_decoder_of_match[] = { { .compatible = "gpio-decoder", }, - { }, + { } }; MODULE_DEVICE_TABLE(of, gpio_decoder_of_match); -#endif static struct platform_driver gpio_decoder_driver = { .probe = gpio_decoder_probe, .driver = { .name = "gpio-decoder", - .of_match_table = of_match_ptr(gpio_decoder_of_match), + .of_match_table = gpio_decoder_of_match, } }; module_platform_driver(gpio_decoder_driver); diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c index 4581f1c53644..f69de9762c4e 100644 --- a/drivers/input/misc/ims-pcu.c +++ b/drivers/input/misc/ims-pcu.c @@ -286,7 +286,7 @@ static int ims_pcu_setup_gamepad(struct ims_pcu *pcu) struct input_dev *input; int error; - gamepad = kzalloc(sizeof(*gamepad), GFP_KERNEL); + gamepad = kzalloc_obj(*gamepad); input = input_allocate_device(); if (!gamepad || !input) { dev_err(pcu->dev, @@ -1991,7 +1991,7 @@ static int ims_pcu_probe(struct usb_interface *intf, struct ims_pcu *pcu; int error; - pcu = kzalloc(sizeof(*pcu), GFP_KERNEL); + pcu = kzalloc_obj(*pcu); if (!pcu) return -ENOMEM; diff --git a/drivers/input/misc/keyspan_remote.c b/drivers/input/misc/keyspan_remote.c index bee4b1376491..152633bd2266 100644 --- a/drivers/input/misc/keyspan_remote.c +++ b/drivers/input/misc/keyspan_remote.c @@ -453,7 +453,7 @@ static int keyspan_probe(struct usb_interface *interface, const struct usb_devic if (!endpoint) return -ENODEV; - remote = kzalloc(sizeof(*remote), GFP_KERNEL); + remote = kzalloc_obj(*remote); input_dev = input_allocate_device(); if (!remote || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/misc/max8997_haptic.c b/drivers/input/misc/max8997_haptic.c index d5e051a25a74..975c3ba023f5 100644 --- a/drivers/input/misc/max8997_haptic.c +++ b/drivers/input/misc/max8997_haptic.c @@ -247,7 +247,7 @@ static int max8997_haptic_probe(struct platform_device *pdev) return -EINVAL; } - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); input_dev = input_allocate_device(); if (!chip || !input_dev) { dev_err(&pdev->dev, "unable to allocate memory\n"); diff --git a/drivers/input/misc/mc13783-pwrbutton.c b/drivers/input/misc/mc13783-pwrbutton.c index b83d762ae2e9..cb781ce967ca 100644 --- a/drivers/input/misc/mc13783-pwrbutton.c +++ b/drivers/input/misc/mc13783-pwrbutton.c @@ -108,7 +108,7 @@ static int mc13783_pwrbutton_probe(struct platform_device *pdev) return -ENOMEM; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { err = -ENOMEM; dev_dbg(&pdev->dev, "Can't allocate power button\n"); diff --git a/drivers/input/misc/palmas-pwrbutton.c b/drivers/input/misc/palmas-pwrbutton.c index 39fc451c56e9..f22083f44d91 100644 --- a/drivers/input/misc/palmas-pwrbutton.c +++ b/drivers/input/misc/palmas-pwrbutton.c @@ -91,7 +91,7 @@ static irqreturn_t pwron_irq(int irq, void *palmas_pwron) pm_wakeup_event(input_dev->dev.parent, 0); input_sync(input_dev); - mod_delayed_work(system_wq, &pwron->input_work, + mod_delayed_work(system_dfl_wq, &pwron->input_work, msecs_to_jiffies(PALMAS_PWR_KEY_Q_TIME_MS)); return IRQ_HANDLED; @@ -164,7 +164,7 @@ static int palmas_pwron_probe(struct platform_device *pdev) palmas_pwron_params_ofinit(dev, &config); - pwron = kzalloc(sizeof(*pwron), GFP_KERNEL); + pwron = kzalloc_obj(*pwron); if (!pwron) return -ENOMEM; diff --git a/drivers/input/misc/pcap_keys.c b/drivers/input/misc/pcap_keys.c index fe43fd72ba7b..b19899b50d0b 100644 --- a/drivers/input/misc/pcap_keys.c +++ b/drivers/input/misc/pcap_keys.c @@ -49,7 +49,7 @@ static int pcap_keys_probe(struct platform_device *pdev) struct pcap_keys *pcap_keys; struct input_dev *input_dev; - pcap_keys = kmalloc(sizeof(*pcap_keys), GFP_KERNEL); + pcap_keys = kmalloc_obj(*pcap_keys); if (!pcap_keys) return err; diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 3632cb206e34..14fc6c6cf699 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -91,7 +91,7 @@ static int pcf8574_kp_probe(struct i2c_client *client) return -ENODEV; } - lp = kzalloc(sizeof(*lp), GFP_KERNEL); + lp = kzalloc_obj(*lp); if (!lp) return -ENOMEM; diff --git a/drivers/input/misc/pf1550-onkey.c b/drivers/input/misc/pf1550-onkey.c index 9be6377151cb..0d1b570bbe47 100644 --- a/drivers/input/misc/pf1550-onkey.c +++ b/drivers/input/misc/pf1550-onkey.c @@ -173,7 +173,7 @@ static int pf1550_onkey_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(pf1550_onkey_pm_ops, pf1550_onkey_suspend, pf1550_onkey_resume); static const struct platform_device_id pf1550_onkey_id[] = { diff --git a/drivers/input/misc/powermate.c b/drivers/input/misc/powermate.c index ecb92ee5ebbc..754379d2625c 100644 --- a/drivers/input/misc/powermate.c +++ b/drivers/input/misc/powermate.c @@ -275,7 +275,7 @@ static int powermate_alloc_buffers(struct usb_device *udev, struct powermate_dev if (!pm->data) return -1; - pm->configcr = kmalloc(sizeof(*(pm->configcr)), GFP_KERNEL); + pm->configcr = kmalloc_obj(*(pm->configcr)); if (!pm->configcr) return -ENOMEM; @@ -313,7 +313,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i 0, interface->desc.bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); - pm = kzalloc(sizeof(*pm), GFP_KERNEL); + pm = kzalloc_obj(*pm); input_dev = input_allocate_device(); if (!pm || !input_dev) goto fail1; diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index f85cc289c053..b0feef19515d 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -20,27 +20,43 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include #include #include #include -#include +#include +#include #include #include -#define PWR_PWRON_IRQ (1 << 0) +#define PWR_PWRON_IRQ BIT(0) -#define STS_HW_CONDITIONS 0xf +struct twl_pwrbutton_chipdata { + u8 status_reg; + bool need_manual_irq; +}; + +static const struct twl_pwrbutton_chipdata twl4030_chipdata = { + .status_reg = 0xf, + .need_manual_irq = false, +}; + +static const struct twl_pwrbutton_chipdata twl6030_chipdata = { + .status_reg = 0x2, + .need_manual_irq = true, +}; static irqreturn_t powerbutton_irq(int irq, void *_pwr) { struct input_dev *pwr = _pwr; + const struct twl_pwrbutton_chipdata *pdata = dev_get_drvdata(pwr->dev.parent); int err; u8 value; - err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &value, STS_HW_CONDITIONS); + err = twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &value, pdata->status_reg); if (!err) { pm_wakeup_event(pwr->dev.parent, 0); input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); @@ -55,10 +71,17 @@ static irqreturn_t powerbutton_irq(int irq, void *_pwr) static int twl4030_pwrbutton_probe(struct platform_device *pdev) { + const struct twl_pwrbutton_chipdata *pdata; struct input_dev *pwr; int irq = platform_get_irq(pdev, 0); int err; + pdata = device_get_match_data(&pdev->dev); + if (!pdata) + return -EINVAL; + + platform_set_drvdata(pdev, (void *)pdata); + pwr = devm_input_allocate_device(&pdev->dev); if (!pwr) { dev_err(&pdev->dev, "Can't allocate power button\n"); @@ -85,24 +108,50 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev) return err; } + if (pdata->need_manual_irq) { + err = twl6030_interrupt_unmask(0x01, REG_INT_MSK_LINE_A); + if (err) + return err; + + err = twl6030_interrupt_unmask(0x01, REG_INT_MSK_STS_A); + if (err) + return err; + } + device_init_wakeup(&pdev->dev, true); return 0; } -#ifdef CONFIG_OF +static void twl4030_pwrbutton_remove(struct platform_device *pdev) +{ + const struct twl_pwrbutton_chipdata *pdata = platform_get_drvdata(pdev); + + if (pdata->need_manual_irq) { + twl6030_interrupt_mask(0x01, REG_INT_MSK_LINE_A); + twl6030_interrupt_mask(0x01, REG_INT_MSK_STS_A); + } +} + static const struct of_device_id twl4030_pwrbutton_dt_match_table[] = { - { .compatible = "ti,twl4030-pwrbutton" }, - {}, + { + .compatible = "ti,twl4030-pwrbutton", + .data = &twl4030_chipdata, + }, + { + .compatible = "ti,twl6030-pwrbutton", + .data = &twl6030_chipdata, + }, + { } }; MODULE_DEVICE_TABLE(of, twl4030_pwrbutton_dt_match_table); -#endif static struct platform_driver twl4030_pwrbutton_driver = { .probe = twl4030_pwrbutton_probe, + .remove = twl4030_pwrbutton_remove, .driver = { .name = "twl4030_pwrbutton", - .of_match_table = of_match_ptr(twl4030_pwrbutton_dt_match_table), + .of_match_table = twl4030_pwrbutton_dt_match_table, }, }; module_platform_driver(twl4030_pwrbutton_driver); diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 13336a2fd49c..e589060db280 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c @@ -379,7 +379,7 @@ static int uinput_open(struct inode *inode, struct file *file) { struct uinput_device *newdev; - newdev = kzalloc(sizeof(*newdev), GFP_KERNEL); + newdev = kzalloc_obj(*newdev); if (!newdev) return -ENOMEM; diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 67f1c7364c95..6471d836f6fe 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c @@ -205,7 +205,7 @@ static int xenkbd_probe(struct xenbus_device *dev, struct xenkbd_info *info; struct input_dev *kbd, *ptr, *mtouch; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); return -ENOMEM; diff --git a/drivers/input/misc/yealink.c b/drivers/input/misc/yealink.c index 08dc53ae1b3c..8786ed8b3565 100644 --- a/drivers/input/misc/yealink.c +++ b/drivers/input/misc/yealink.c @@ -831,7 +831,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; - yld = kzalloc(sizeof(*yld), GFP_KERNEL); + yld = kzalloc_obj(*yld); if (!yld) return -ENOMEM; @@ -854,7 +854,7 @@ static int usb_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!yld->ctl_data) return usb_cleanup(yld, -ENOMEM); - yld->ctl_req = kmalloc(sizeof(*(yld->ctl_req)), GFP_KERNEL); + yld->ctl_req = kmalloc_obj(*(yld->ctl_req)); if (yld->ctl_req == NULL) return usb_cleanup(yld, -ENOMEM); diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index df8953a5196e..f3d3b6b4e02d 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -3206,7 +3206,7 @@ int alps_detect(struct psmouse *psmouse, bool set_properties) */ psmouse_reset(psmouse); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index e669f86f1882..87d8f5afdfd9 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c @@ -200,7 +200,6 @@ struct atp { u8 *data; /* transferred data */ struct input_dev *input; /* input dev */ const struct atp_info *info; /* touchpad model */ - bool open; bool valid; /* are the samples valid? */ bool size_detect_done; bool overflow_warned; @@ -800,7 +799,6 @@ static int atp_open(struct input_dev *input) if (usb_submit_urb(dev->urb, GFP_KERNEL)) return -EIO; - dev->open = true; return 0; } @@ -810,7 +808,6 @@ static void atp_close(struct input_dev *input) usb_kill_urb(dev->urb); cancel_work_sync(&dev->work); - dev->open = false; } static int atp_handle_geyser(struct atp *dev) @@ -855,7 +852,7 @@ static int atp_probe(struct usb_interface *iface, } /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "Out of memory\n"); @@ -963,7 +960,8 @@ static int atp_recover(struct atp *dev) if (error) return error; - if (dev->open && usb_submit_urb(dev->urb, GFP_KERNEL)) + guard(mutex)(&dev->input->mutex); + if (input_device_enabled(dev->input) && usb_submit_urb(dev->urb, GFP_KERNEL)) return -EIO; return 0; @@ -981,7 +979,8 @@ static int atp_resume(struct usb_interface *iface) { struct atp *dev = usb_get_intfdata(iface); - if (dev->open && usb_submit_urb(dev->urb, GFP_KERNEL)) + guard(mutex)(&dev->input->mutex); + if (input_device_enabled(dev->input) && usb_submit_urb(dev->urb, GFP_KERNEL)) return -EIO; return 0; diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index dfdfb59cc8b5..8e3cea9db365 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -895,7 +895,7 @@ static int bcm5974_probe(struct usb_interface *iface, cfg = bcm5974_get_config(udev); /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); input_dev = input_allocate_device(); if (!dev || !input_dev) { dev_err(&iface->dev, "out of memory\n"); diff --git a/drivers/input/mouse/byd.c b/drivers/input/mouse/byd.c index 71aa23dd7d8d..f5770a3af2f1 100644 --- a/drivers/input/mouse/byd.c +++ b/drivers/input/mouse/byd.c @@ -314,10 +314,8 @@ static psmouse_ret_t byd_process_byte(struct psmouse *psmouse) break; } default: - psmouse_warn(psmouse, - "Unrecognized Z: pkt = %02x %02x %02x %02x\n", - psmouse->packet[0], psmouse->packet[1], - psmouse->packet[2], psmouse->packet[3]); + psmouse_warn(psmouse, "Unrecognized Z: pkt = %*ph\n", + 4, psmouse->packet); return PSMOUSE_BAD_DATA; } @@ -471,7 +469,7 @@ int byd_init(struct psmouse *psmouse) if (byd_reset_touchpad(psmouse)) return -EIO; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index 00c87c0532a6..6e0d956617a1 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -403,7 +403,6 @@ static int cyapa_open(struct input_dev *input) } pm_runtime_get_sync(dev); - pm_runtime_mark_last_busy(dev); pm_runtime_put_sync_autosuspend(dev); out: mutex_unlock(&cyapa->state_sync_lock); @@ -666,7 +665,6 @@ static int cyapa_reinitialize(struct cyapa *cyapa) pm_runtime_enable(dev); pm_runtime_get_sync(dev); - pm_runtime_mark_last_busy(dev); pm_runtime_put_sync_autosuspend(dev); } @@ -710,7 +708,6 @@ static irqreturn_t cyapa_irq(int irq, void *dev_id) * process. */ pm_runtime_get_sync(dev); - pm_runtime_mark_last_busy(dev); pm_runtime_put_sync_autosuspend(dev); } diff --git a/drivers/input/mouse/cyapa_gen5.c b/drivers/input/mouse/cyapa_gen5.c index 3b4439f10635..59f6e97d5482 100644 --- a/drivers/input/mouse/cyapa_gen5.c +++ b/drivers/input/mouse/cyapa_gen5.c @@ -2833,7 +2833,6 @@ static int cyapa_pip_event_process(struct cyapa *cyapa, * process. */ pm_runtime_get_sync(dev); - pm_runtime_mark_last_busy(dev); pm_runtime_put_sync_autosuspend(dev); return 0; } else if (report_id != PIP_TOUCH_REPORT_ID && diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 9446657a5f35..309063d07b4d 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -624,7 +624,7 @@ int cypress_init(struct psmouse *psmouse) struct cytp_data *cytp; int error; - cytp = kzalloc(sizeof(*cytp), GFP_KERNEL); + cytp = kzalloc_obj(*cytp); if (!cytp) return -ENOMEM; diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 79ad98cc1e79..f8575b80d19d 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -2074,7 +2074,7 @@ static int elantech_setup_ps2(struct psmouse *psmouse, int error = -EINVAL; struct input_dev *tp_dev; - psmouse->private = etd = kzalloc(sizeof(*etd), GFP_KERNEL); + psmouse->private = etd = kzalloc_obj(*etd); if (!etd) return -ENOMEM; diff --git a/drivers/input/mouse/focaltech.c b/drivers/input/mouse/focaltech.c index 356b99d48544..43f9939b7c63 100644 --- a/drivers/input/mouse/focaltech.c +++ b/drivers/input/mouse/focaltech.c @@ -408,7 +408,7 @@ int focaltech_init(struct psmouse *psmouse) struct focaltech_data *priv; int error; - psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); + psmouse->private = priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 6125652e5ad8..3c4d16ed88a9 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -981,7 +981,7 @@ int hgpk_init(struct psmouse *psmouse) struct hgpk_data *priv; int err; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { err = -ENOMEM; goto alloc_fail; diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 283ef46f039f..ef11b7b19833 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c @@ -273,7 +273,7 @@ static int lifebook_create_relative_device(struct psmouse *psmouse) struct lifebook_data *priv; int error = -ENOMEM; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); dev2 = input_allocate_device(); if (!priv || !dev2) goto err_out; diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index baef4be14b54..c99f7e234219 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c @@ -73,7 +73,7 @@ static int probe_maple_mouse(struct device *dev) struct input_dev *input_dev; struct dc_mouse *mse; - mse = kzalloc(sizeof(*mse), GFP_KERNEL); + mse = kzalloc_obj(*mse); if (!mse) { error = -ENOMEM; goto fail; diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 77ea7da3b1c5..ff8cd2d68a3c 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c @@ -1591,7 +1591,7 @@ static int psmouse_connect(struct serio *serio, struct serio_driver *drv) psmouse_deactivate(parent); } - psmouse = kzalloc(sizeof(*psmouse), GFP_KERNEL); + psmouse = kzalloc_obj(*psmouse); input_dev = input_allocate_device(); if (!psmouse || !input_dev) goto err_free; diff --git a/drivers/input/mouse/psmouse-smbus.c b/drivers/input/mouse/psmouse-smbus.c index 93420f07b7d0..7fb4cbb2aca2 100644 --- a/drivers/input/mouse/psmouse-smbus.c +++ b/drivers/input/mouse/psmouse-smbus.c @@ -154,7 +154,7 @@ static void psmouse_smbus_schedule_remove(struct i2c_client *client) { struct psmouse_smbus_removal_work *rwork; - rwork = kzalloc(sizeof(*rwork), GFP_KERNEL); + rwork = kzalloc_obj(*rwork); if (rwork) { INIT_WORK(&rwork->work, psmouse_smbus_remove_i2c_device); rwork->client = client; @@ -299,7 +299,7 @@ int __init psmouse_smbus_module_init(void) { int error; - psmouse_smbus_wq = alloc_workqueue("psmouse-smbus", 0, 0); + psmouse_smbus_wq = alloc_workqueue("psmouse-smbus", WQ_UNBOUND, 0); if (!psmouse_smbus_wq) return -ENOMEM; diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 44b136fc29aa..cda6febe3faf 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c @@ -1028,7 +1028,7 @@ int fsp_init(struct psmouse *psmouse) "Finger Sensing Pad, hw: %d.%d.%d, sn: %x, sw: %s\n", ver >> 4, ver & 0x0F, rev, sn, fsp_drv_ver); - psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); + psmouse->private = priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index 218c8432a13b..c334a488700f 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c @@ -231,7 +231,7 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) unsigned char c = serio->id.extra; int err = -ENOMEM; - sermouse = kzalloc(sizeof(*sermouse), GFP_KERNEL); + sermouse = kzalloc_obj(*sermouse); input_dev = input_allocate_device(); if (!sermouse || !input_dev) goto fail1; diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c5c88a75a019..26071128f43a 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c @@ -741,7 +741,7 @@ static void synaptics_pt_create(struct psmouse *psmouse) { struct serio *serio; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) { psmouse_err(psmouse, "not enough memory for pass-through port\n"); @@ -1597,7 +1597,7 @@ static int synaptics_init_ps2(struct psmouse *psmouse, synaptics_apply_quirks(psmouse, info); - psmouse->private = priv = kzalloc(sizeof(*priv), GFP_KERNEL); + psmouse->private = priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c index a0d707e47d93..6f3d5c33b807 100644 --- a/drivers/input/mouse/synaptics_i2c.c +++ b/drivers/input/mouse/synaptics_i2c.c @@ -240,52 +240,57 @@ static inline void set_scan_rate(struct synaptics_i2c *touch, int scan_rate) */ static s32 synaptics_i2c_reg_get(struct i2c_client *client, u16 reg) { - int ret; + int error; - ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); - if (ret == 0) - ret = i2c_smbus_read_byte_data(client, reg & 0xff); + error = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); + if (error) + return error; - return ret; + return i2c_smbus_read_byte_data(client, reg & 0xff); } static s32 synaptics_i2c_reg_set(struct i2c_client *client, u16 reg, u8 val) { - int ret; + int error; - ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); - if (ret == 0) - ret = i2c_smbus_write_byte_data(client, reg & 0xff, val); + error = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); + if (error) + return error; - return ret; + error = i2c_smbus_write_byte_data(client, reg & 0xff, val); + if (error) + return error; + + return error; } static s32 synaptics_i2c_word_get(struct i2c_client *client, u16 reg) { - int ret; + int error; - ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); - if (ret == 0) - ret = i2c_smbus_read_word_data(client, reg & 0xff); + error = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); + if (error) + return error; - return ret; + return i2c_smbus_read_word_data(client, reg & 0xff); } static int synaptics_i2c_config(struct i2c_client *client) { - int ret, control; + int control; + int error; u8 int_en; /* set Report Rate to Device Highest (>=80) and Sleep to normal */ - ret = synaptics_i2c_reg_set(client, DEV_CONTROL_REG, 0xc1); - if (ret) - return ret; + error = synaptics_i2c_reg_set(client, DEV_CONTROL_REG, 0xc1); + if (error) + return error; /* set Interrupt Disable to Func20 / Enable to Func10) */ int_en = (polling_req) ? 0 : INT_ENA_ABS_MSK | INT_ENA_REL_MSK; - ret = synaptics_i2c_reg_set(client, INTERRUPT_EN_REG, int_en); - if (ret) - return ret; + error = synaptics_i2c_reg_set(client, INTERRUPT_EN_REG, int_en); + if (error) + return error; control = synaptics_i2c_reg_get(client, GENERAL_2D_CONTROL_REG); /* No Deceleration */ @@ -294,42 +299,49 @@ static int synaptics_i2c_config(struct i2c_client *client) control |= reduce_report ? 1 << REDUCE_REPORTING : 0; /* No Filter */ control |= no_filter ? 1 << NO_FILTER : 0; - ret = synaptics_i2c_reg_set(client, GENERAL_2D_CONTROL_REG, control); - if (ret) - return ret; + error = synaptics_i2c_reg_set(client, GENERAL_2D_CONTROL_REG, control); + if (error) + return error; return 0; } static int synaptics_i2c_reset_config(struct i2c_client *client) { - int ret; + int error; /* Reset the Touchpad */ - ret = synaptics_i2c_reg_set(client, DEV_COMMAND_REG, RESET_COMMAND); - if (ret) { + error = synaptics_i2c_reg_set(client, DEV_COMMAND_REG, RESET_COMMAND); + if (error) { dev_err(&client->dev, "Unable to reset device\n"); - } else { - usleep_range(SOFT_RESET_DELAY_US, SOFT_RESET_DELAY_US + 100); - ret = synaptics_i2c_config(client); - if (ret) - dev_err(&client->dev, "Unable to config device\n"); + return error; } - return ret; + usleep_range(SOFT_RESET_DELAY_US, SOFT_RESET_DELAY_US + 100); + error = synaptics_i2c_config(client); + if (error) { + dev_err(&client->dev, "Unable to config device\n"); + return error; + } + + return 0; } static int synaptics_i2c_check_error(struct i2c_client *client) { - int status, ret = 0; + int status; + int error; status = i2c_smbus_read_byte_data(client, DEVICE_STATUS_REG) & (CONFIGURED_MSK | ERROR_MSK); - if (status != CONFIGURED_MSK) - ret = synaptics_i2c_reset_config(client); + if (status != CONFIGURED_MSK) { + error = synaptics_i2c_reset_config(client); + if (error) + return error; + } - return ret; + return 0; } static bool synaptics_i2c_get_input(struct synaptics_i2c *touch) @@ -372,7 +384,7 @@ static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) { struct synaptics_i2c *touch = dev_id; - mod_delayed_work(system_wq, &touch->dwork, 0); + mod_delayed_work(system_dfl_wq, &touch->dwork, 0); return IRQ_HANDLED; } @@ -421,10 +433,10 @@ static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, delay = NO_DATA_SLEEP_MSECS; } return msecs_to_jiffies(delay); - } else { - delay = msecs_to_jiffies(THREAD_IRQ_SLEEP_MSECS); - return round_jiffies_relative(delay); } + + delay = msecs_to_jiffies(THREAD_IRQ_SLEEP_MSECS); + return round_jiffies_relative(delay); } /* Work Handler */ @@ -448,21 +460,21 @@ static void synaptics_i2c_work_handler(struct work_struct *work) * We poll the device once in THREAD_IRQ_SLEEP_SECS and * if error is detected, we try to reset and reconfigure the touchpad. */ - mod_delayed_work(system_wq, &touch->dwork, delay); + mod_delayed_work(system_dfl_wq, &touch->dwork, delay); } static int synaptics_i2c_open(struct input_dev *input) { struct synaptics_i2c *touch = input_get_drvdata(input); - int ret; + int error; - ret = synaptics_i2c_reset_config(touch->client); - if (ret) - return ret; + error = synaptics_i2c_reset_config(touch->client); + if (error) + return error; if (polling_req) - mod_delayed_work(system_wq, &touch->dwork, - msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); + mod_delayed_work(system_dfl_wq, &touch->dwork, + msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); return 0; } @@ -489,28 +501,27 @@ static void synaptics_i2c_set_input_params(struct synaptics_i2c *touch) input->id.bustype = BUS_I2C; input->id.version = synaptics_i2c_word_get(touch->client, INFO_QUERY_REG0); - input->dev.parent = &touch->client->dev; input->open = synaptics_i2c_open; input->close = synaptics_i2c_close; input_set_drvdata(input, touch); /* Register the device as mouse */ - __set_bit(EV_REL, input->evbit); - __set_bit(REL_X, input->relbit); - __set_bit(REL_Y, input->relbit); + input_set_capability(input, EV_REL, REL_X); + input_set_capability(input, EV_REL, REL_Y); /* Register device's buttons and keys */ - __set_bit(EV_KEY, input->evbit); - __set_bit(BTN_LEFT, input->keybit); + input_set_capability(input, EV_KEY, BTN_LEFT); } -static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) +static int synaptics_i2c_probe(struct i2c_client *client) { + struct device *dev = &client->dev; struct synaptics_i2c *touch; + int error; - touch = kzalloc(sizeof(*touch), GFP_KERNEL); + touch = devm_kzalloc(dev, sizeof(*touch), GFP_KERNEL); if (!touch) - return NULL; + return -ENOMEM; touch->client = client; touch->no_decel_param = no_decel; @@ -518,83 +529,46 @@ static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *clien set_scan_rate(touch, scan_rate); INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); - return touch; -} + error = synaptics_i2c_reset_config(client); + if (error) + return error; -static int synaptics_i2c_probe(struct i2c_client *client) -{ - int ret; - struct synaptics_i2c *touch; - - touch = synaptics_i2c_touch_create(client); - if (!touch) - return -ENOMEM; - - ret = synaptics_i2c_reset_config(client); - if (ret) - goto err_mem_free; - - if (client->irq < 1) + if (client->irq <= 0) polling_req = true; - touch->input = input_allocate_device(); - if (!touch->input) { - ret = -ENOMEM; - goto err_mem_free; - } + touch->input = devm_input_allocate_device(dev); + if (!touch->input) + return -ENOMEM; synaptics_i2c_set_input_params(touch); if (!polling_req) { - dev_dbg(&touch->client->dev, - "Requesting IRQ: %d\n", touch->client->irq); + dev_dbg(dev, "Requesting IRQ: %d\n", client->irq); - ret = request_irq(touch->client->irq, synaptics_i2c_irq, - IRQ_TYPE_EDGE_FALLING, - DRIVER_NAME, touch); - if (ret) { - dev_warn(&touch->client->dev, - "IRQ request failed: %d, " - "falling back to polling\n", ret); + error = devm_request_irq(dev, client->irq, synaptics_i2c_irq, + IRQ_TYPE_EDGE_FALLING, + DRIVER_NAME, touch); + if (error) { + dev_warn(dev, "IRQ request failed: %d, falling back to polling\n", + error); polling_req = true; - synaptics_i2c_reg_set(touch->client, - INTERRUPT_EN_REG, 0); + synaptics_i2c_reg_set(client, INTERRUPT_EN_REG, 0); } } if (polling_req) - dev_dbg(&touch->client->dev, - "Using polling at rate: %d times/sec\n", scan_rate); + dev_dbg(dev, "Using polling at rate: %d times/sec\n", scan_rate); /* Register the device in input subsystem */ - ret = input_register_device(touch->input); - if (ret) { - dev_err(&client->dev, - "Input device register failed: %d\n", ret); - goto err_input_free; + error = input_register_device(touch->input); + if (error) { + dev_err(dev, "Input device register failed: %d\n", error); + return error; } i2c_set_clientdata(client, touch); return 0; - -err_input_free: - input_free_device(touch->input); -err_mem_free: - kfree(touch); - - return ret; -} - -static void synaptics_i2c_remove(struct i2c_client *client) -{ - struct synaptics_i2c *touch = i2c_get_clientdata(client); - - if (!polling_req) - free_irq(client->irq, touch); - - input_unregister_device(touch->input); - kfree(touch); } static int synaptics_i2c_suspend(struct device *dev) @@ -612,16 +586,19 @@ static int synaptics_i2c_suspend(struct device *dev) static int synaptics_i2c_resume(struct device *dev) { - int ret; struct i2c_client *client = to_i2c_client(dev); struct synaptics_i2c *touch = i2c_get_clientdata(client); + struct input_dev *input = touch->input; + int error; - ret = synaptics_i2c_reset_config(client); - if (ret) - return ret; + error = synaptics_i2c_reset_config(client); + if (error) + return error; - mod_delayed_work(system_wq, &touch->dwork, - msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); + guard(mutex)(&input->mutex); + if (input_device_enabled(input)) + mod_delayed_work(system_dfl_wq, &touch->dwork, + msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); return 0; } @@ -651,8 +628,6 @@ static struct i2c_driver synaptics_i2c_driver = { }, .probe = synaptics_i2c_probe, - .remove = synaptics_i2c_remove, - .id_table = synaptics_i2c_id_table, }; diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index 75e45f3ae675..5a86f6f387d8 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c @@ -311,7 +311,7 @@ static int synusb_probe(struct usb_interface *intf, if (!ep) return -ENODEV; - synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); + synusb = kzalloc_obj(*synusb); input_dev = input_allocate_device(); if (!synusb || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 5f6643b69a2c..b06c7ad721fe 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -409,7 +409,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) if (!set_properties) return 0; - tp = kzalloc(sizeof(*tp), GFP_KERNEL); + tp = kzalloc_obj(*tp); if (!tp) return -ENOMEM; diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c index fb1d986a6895..aaecdd3d50b6 100644 --- a/drivers/input/mouse/vmmouse.c +++ b/drivers/input/mouse/vmmouse.c @@ -409,7 +409,7 @@ int vmmouse_init(struct psmouse *psmouse) if (error) return error; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); abs_dev = input_allocate_device(); if (!priv || !abs_dev) { error = -ENOMEM; diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index 707cd28f4ba6..042a17fe81db 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c @@ -456,7 +456,7 @@ static int vsxxxaa_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - mouse = kzalloc(sizeof(*mouse), GFP_KERNEL); + mouse = kzalloc_obj(*mouse); input_dev = input_allocate_device(); if (!mouse || !input_dev) goto fail1; diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 505c562a5daa..d5c9b0a09fcf 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -543,7 +543,7 @@ static int mousedev_open(struct inode *inode, struct file *file) #endif mousedev = container_of(inode->i_cdev, struct mousedev, cdev); - client = kzalloc(sizeof(struct mousedev_client), GFP_KERNEL); + client = kzalloc_obj(struct mousedev_client); if (!client) return -ENOMEM; @@ -853,7 +853,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev, goto err_out; } - mousedev = kzalloc(sizeof(struct mousedev), GFP_KERNEL); + mousedev = kzalloc_obj(struct mousedev); if (!mousedev) { error = -ENOMEM; goto err_free_minor; diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c index b85ee9db87b0..687cb987bc13 100644 --- a/drivers/input/rmi4/rmi_bus.c +++ b/drivers/input/rmi4/rmi_bus.c @@ -78,7 +78,7 @@ int rmi_register_transport_device(struct rmi_transport_dev *xport) struct rmi_device *rmi_dev; int error; - rmi_dev = kzalloc(sizeof(struct rmi_device), GFP_KERNEL); + rmi_dev = kzalloc_obj(struct rmi_device); if (!rmi_dev) return -ENOMEM; diff --git a/drivers/input/rmi4/rmi_f03.c b/drivers/input/rmi4/rmi_f03.c index e1157ff0f00a..04f0e5578861 100644 --- a/drivers/input/rmi4/rmi_f03.c +++ b/drivers/input/rmi4/rmi_f03.c @@ -171,7 +171,7 @@ static int rmi_f03_register_pt(struct f03_data *f03) { struct serio *serio; - serio = kzalloc(sizeof(struct serio), GFP_KERNEL); + serio = kzalloc_obj(struct serio); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/altera_ps2.c b/drivers/input/serio/altera_ps2.c index aa445b1941e9..4bf37db65b76 100644 --- a/drivers/input/serio/altera_ps2.c +++ b/drivers/input/serio/altera_ps2.c @@ -81,7 +81,7 @@ static int altera_ps2_probe(struct platform_device *pdev) struct serio *serio; int error, irq; - ps2if = devm_kzalloc(&pdev->dev, sizeof(struct ps2if), GFP_KERNEL); + ps2if = devm_kzalloc(&pdev->dev, sizeof(*ps2if), GFP_KERNEL); if (!ps2if) return -ENOMEM; @@ -100,7 +100,7 @@ static int altera_ps2_probe(struct platform_device *pdev) return error; } - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c index de4b3915c37d..046b8f388eb6 100644 --- a/drivers/input/serio/ambakmi.c +++ b/drivers/input/serio/ambakmi.c @@ -114,8 +114,8 @@ static int amba_kmi_probe(struct amba_device *dev, if (ret) return ret; - kmi = kzalloc(sizeof(*kmi), GFP_KERNEL); - io = kzalloc(sizeof(*io), GFP_KERNEL); + kmi = kzalloc_obj(*kmi); + io = kzalloc_obj(*io); if (!kmi || !io) { ret = -ENOMEM; goto out; diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 81b3a053df81..e346bf53eb16 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -150,7 +150,7 @@ static int ams_delta_serio_init(struct platform_device *pdev) return err; } - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/apbps2.c b/drivers/input/serio/apbps2.c index b815337be2f4..0aa4ab00af35 100644 --- a/drivers/input/serio/apbps2.c +++ b/drivers/input/serio/apbps2.c @@ -67,7 +67,7 @@ static irqreturn_t apbps2_isr(int irq, void *dev_id) rxflags = (status & APBPS2_STATUS_PE) ? SERIO_PARITY : 0; rxflags |= (status & APBPS2_STATUS_FE) ? SERIO_FRAME : 0; - /* clear error bits? */ + /* Clear error bits */ if (rxflags) iowrite32be(0, &priv->regs->status); @@ -82,9 +82,9 @@ static irqreturn_t apbps2_isr(int irq, void *dev_id) static int apbps2_write(struct serio *io, unsigned char val) { struct apbps2_priv *priv = io->port_data; - unsigned int tleft = 10000; /* timeout in 100ms */ + unsigned int tleft = 10000; /* Timeout in 100ms */ - /* delay until PS/2 controller has room for more chars */ + /* Delay until PS/2 controller has room for more chars */ while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_TF) && tleft--) udelay(10); @@ -104,7 +104,7 @@ static int apbps2_open(struct serio *io) struct apbps2_priv *priv = io->port_data; int limit; - /* clear error flags */ + /* Clear error flags */ iowrite32be(0, &priv->regs->status); /* Clear old data if available (unlikely) */ @@ -112,7 +112,7 @@ static int apbps2_open(struct serio *io) while ((ioread32be(&priv->regs->status) & APBPS2_STATUS_DR) && --limit) ioread32be(&priv->regs->data); - /* Enable reciever and it's interrupt */ + /* Enable receiver and its interrupt */ iowrite32be(APBPS2_CTRL_RE | APBPS2_CTRL_RI, &priv->regs->ctrl); return 0; @@ -122,7 +122,7 @@ static void apbps2_close(struct serio *io) { struct apbps2_priv *priv = io->port_data; - /* stop interrupts at PS/2 HW level */ + /* Stop interrupts at PS/2 HW level */ iowrite32be(0, &priv->regs->ctrl); } @@ -139,7 +139,7 @@ static int apbps2_of_probe(struct platform_device *ofdev) return -ENOMEM; } - /* Find Device Address */ + /* Find device address */ priv->regs = devm_platform_get_and_ioremap_resource(ofdev, 0, NULL); if (IS_ERR(priv->regs)) return PTR_ERR(priv->regs); @@ -165,7 +165,7 @@ static int apbps2_of_probe(struct platform_device *ofdev) /* Set reload register to core freq in kHz/10 */ iowrite32be(freq_hz / 10000, &priv->regs->reload); - priv->io = kzalloc(sizeof(*priv->io), GFP_KERNEL); + priv->io = kzalloc_obj(*priv->io); if (!priv->io) return -ENOMEM; diff --git a/drivers/input/serio/arc_ps2.c b/drivers/input/serio/arc_ps2.c index e991c72296c9..2eb069a0f054 100644 --- a/drivers/input/serio/arc_ps2.c +++ b/drivers/input/serio/arc_ps2.c @@ -155,7 +155,7 @@ static int arc_ps2_create_port(struct platform_device *pdev, struct arc_ps2_port *port = &arc_ps2->port[index]; struct serio *io; - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kzalloc_obj(*io); if (!io) return -ENOMEM; @@ -189,8 +189,7 @@ static int arc_ps2_probe(struct platform_device *pdev) if (irq < 0) return -EINVAL; - arc_ps2 = devm_kzalloc(&pdev->dev, sizeof(struct arc_ps2_data), - GFP_KERNEL); + arc_ps2 = devm_kzalloc(&pdev->dev, sizeof(*arc_ps2), GFP_KERNEL); if (!arc_ps2) { dev_err(&pdev->dev, "out of memory\n"); return -ENOMEM; diff --git a/drivers/input/serio/ct82c710.c b/drivers/input/serio/ct82c710.c index 053a15988c45..fe5f9eda4b77 100644 --- a/drivers/input/serio/ct82c710.c +++ b/drivers/input/serio/ct82c710.c @@ -158,7 +158,7 @@ static int __init ct82c710_detect(void) static int ct82c710_probe(struct platform_device *dev) { - ct82c710_port = kzalloc(sizeof(*ct82c710_port), GFP_KERNEL); + ct82c710_port = kzalloc_obj(*ct82c710_port); if (!ct82c710_port) return -ENOMEM; diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c index 9c6ff04c46cf..22b2f57fd91f 100644 --- a/drivers/input/serio/gscps2.c +++ b/drivers/input/serio/gscps2.c @@ -350,8 +350,8 @@ static int __init gscps2_probe(struct parisc_device *dev) if (dev->id.sversion == 0x96) hpa += GSC_DINO_OFFSET; - ps2port = kzalloc(sizeof(*ps2port), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + ps2port = kzalloc_obj(*ps2port); + serio = kzalloc_obj(*serio); if (!ps2port || !serio) { ret = -ENOMEM; goto fail_nomem; diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index 3fedfc5abc73..2680a816c393 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -939,7 +939,7 @@ int hil_mlc_register(hil_mlc *mlc) for (i = 0; i < HIL_MLC_DEVMEM; i++) { struct serio *mlc_serio; hil_mlc_copy_di_scratch(mlc, i); - mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); + mlc_serio = kzalloc_obj(*mlc_serio); mlc->serio[i] = mlc_serio; if (!mlc->serio[i]) { for (; i >= 0; i--) diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index 0ee7505427ac..13434b9330c8 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -316,8 +316,8 @@ static int hv_kbd_probe(struct hv_device *hv_dev, struct serio *hv_serio; int error; - kbd_dev = kzalloc(sizeof(*kbd_dev), GFP_KERNEL); - hv_serio = kzalloc(sizeof(*hv_serio), GFP_KERNEL); + kbd_dev = kzalloc_obj(*kbd_dev); + hv_serio = kzalloc_obj(*hv_serio); if (!kbd_dev || !hv_serio) { error = -ENOMEM; goto err_free_mem; diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index c135254665b6..8bcce11cb7ce 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -1324,7 +1324,7 @@ static int i8042_create_kbd_port(void) struct serio *serio; struct i8042_port *port = &i8042_ports[I8042_KBD_PORT_NO]; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; @@ -1354,7 +1354,7 @@ static int i8042_create_aux_port(int idx) int port_no = idx < 0 ? I8042_AUX_PORT_NO : I8042_MUX_PORT_NO + idx; struct i8042_port *port = &i8042_ports[port_no]; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c index d2c7ffb9a946..4ef60c24e788 100644 --- a/drivers/input/serio/ioc3kbd.c +++ b/drivers/input/serio/ioc3kbd.c @@ -139,11 +139,11 @@ static int ioc3kbd_probe(struct platform_device *pdev) if (!d) return -ENOMEM; - sk = kzalloc(sizeof(*sk), GFP_KERNEL); + sk = kzalloc_obj(*sk); if (!sk) return -ENOMEM; - sa = kzalloc(sizeof(*sa), GFP_KERNEL); + sa = kzalloc_obj(*sa); if (!sa) { kfree(sk); return -ENOMEM; diff --git a/drivers/input/serio/maceps2.c b/drivers/input/serio/maceps2.c index 3d28a5cddd61..fb41e7f5af46 100644 --- a/drivers/input/serio/maceps2.c +++ b/drivers/input/serio/maceps2.c @@ -117,7 +117,7 @@ static struct serio *maceps2_allocate_port(int idx) { struct serio *serio; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (serio) { serio->id.type = SERIO_8042; serio->write = maceps2_write; diff --git a/drivers/input/serio/olpc_apsp.c b/drivers/input/serio/olpc_apsp.c index a24324830021..ccc40634f582 100644 --- a/drivers/input/serio/olpc_apsp.c +++ b/drivers/input/serio/olpc_apsp.c @@ -171,7 +171,7 @@ static int olpc_apsp_probe(struct platform_device *pdev) struct olpc_apsp *priv; int error; - priv = devm_kzalloc(&pdev->dev, sizeof(struct olpc_apsp), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -188,7 +188,7 @@ static int olpc_apsp_probe(struct platform_device *pdev) return priv->irq; /* KEYBOARD */ - kb_serio = kzalloc(sizeof(*kb_serio), GFP_KERNEL); + kb_serio = kzalloc_obj(*kb_serio); if (!kb_serio) return -ENOMEM; kb_serio->id.type = SERIO_8042_XL; @@ -203,7 +203,7 @@ static int olpc_apsp_probe(struct platform_device *pdev) serio_register_port(kb_serio); /* TOUCHPAD */ - pad_serio = kzalloc(sizeof(*pad_serio), GFP_KERNEL); + pad_serio = kzalloc_obj(*pad_serio); if (!pad_serio) { error = -ENOMEM; goto err_pad; diff --git a/drivers/input/serio/parkbd.c b/drivers/input/serio/parkbd.c index 22fe55490572..09a24413d940 100644 --- a/drivers/input/serio/parkbd.c +++ b/drivers/input/serio/parkbd.c @@ -165,7 +165,7 @@ static struct serio *parkbd_allocate_serio(void) { struct serio *serio; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (serio) { serio->id.type = parkbd_mode; serio->write = parkbd_write; diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c index 6b9abb2e18c9..78f47b0ca125 100644 --- a/drivers/input/serio/pcips2.c +++ b/drivers/input/serio/pcips2.c @@ -137,8 +137,8 @@ static int pcips2_probe(struct pci_dev *dev, const struct pci_device_id *id) if (ret) goto disable; - ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + ps2if = kzalloc_obj(*ps2if); + serio = kzalloc_obj(*serio); if (!ps2if || !serio) { ret = -ENOMEM; goto release; diff --git a/drivers/input/serio/ps2-gpio.c b/drivers/input/serio/ps2-gpio.c index 46fb7667b244..6cde0d88c6f4 100644 --- a/drivers/input/serio/ps2-gpio.c +++ b/drivers/input/serio/ps2-gpio.c @@ -405,7 +405,7 @@ static int ps2_gpio_probe(struct platform_device *pdev) int error; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!drvdata || !serio) { error = -ENOMEM; goto err_free_serio; diff --git a/drivers/input/serio/ps2mult.c b/drivers/input/serio/ps2mult.c index b96cee52fc52..27d554b59658 100644 --- a/drivers/input/serio/ps2mult.c +++ b/drivers/input/serio/ps2mult.c @@ -122,7 +122,7 @@ static int ps2mult_create_port(struct ps2mult *psm, int i) struct serio *mx_serio = psm->mx_serio; struct serio *serio; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; @@ -160,7 +160,7 @@ static int ps2mult_connect(struct serio *serio, struct serio_driver *drv) if (!serio->write) return -EINVAL; - psm = kzalloc(sizeof(*psm), GFP_KERNEL); + psm = kzalloc_obj(*psm); if (!psm) return -ENOMEM; diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index ae55c4de092f..2f553efbe649 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -102,8 +102,8 @@ static int q40kbd_probe(struct platform_device *pdev) struct serio *port; int error; - q40kbd = kzalloc(sizeof(*q40kbd), GFP_KERNEL); - port = kzalloc(sizeof(*port), GFP_KERNEL); + q40kbd = kzalloc_obj(*q40kbd); + port = kzalloc_obj(*port); if (!q40kbd || !port) { error = -ENOMEM; goto err_free_mem; diff --git a/drivers/input/serio/rpckbd.c b/drivers/input/serio/rpckbd.c index c65c552b0c45..4d817850ba3b 100644 --- a/drivers/input/serio/rpckbd.c +++ b/drivers/input/serio/rpckbd.c @@ -108,8 +108,8 @@ static int rpckbd_probe(struct platform_device *dev) if (tx_irq < 0) return tx_irq; - serio = kzalloc(sizeof(*serio), GFP_KERNEL); - rpckbd = kzalloc(sizeof(*rpckbd), GFP_KERNEL); + serio = kzalloc_obj(*serio); + rpckbd = kzalloc_obj(*rpckbd); if (!serio || !rpckbd) { kfree(rpckbd); kfree(serio); diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c index 375c6f5f905c..e3a463c157d1 100644 --- a/drivers/input/serio/sa1111ps2.c +++ b/drivers/input/serio/sa1111ps2.c @@ -254,8 +254,8 @@ static int ps2_probe(struct sa1111_dev *dev) struct serio *serio; int ret; - ps2if = kzalloc(sizeof(*ps2if), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + ps2if = kzalloc_obj(*ps2if); + serio = kzalloc_obj(*serio); if (!ps2if || !serio) { ret = -ENOMEM; goto free; diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 2b5ddc5dac19..54dd26249b02 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -244,7 +244,7 @@ static int serio_queue_event(void *object, struct module *owner, } } - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) { pr_err("Not enough memory to queue event %d\n", event_type); return -ENOMEM; diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 4d6395088986..a7ccedfa459c 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c @@ -270,7 +270,7 @@ static int serio_raw_connect(struct serio *serio, struct serio_driver *drv) struct serio_raw *serio_raw; int err; - serio_raw = kzalloc(sizeof(*serio_raw), GFP_KERNEL); + serio_raw = kzalloc_obj(*serio_raw); if (!serio_raw) { dev_dbg(&serio->dev, "can't allocate memory for a device\n"); return -ENOMEM; diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 74ac88796187..cabe3876c168 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c @@ -78,7 +78,7 @@ static int serport_ldisc_open(struct tty_struct *tty) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - serport = kzalloc(sizeof(*serport), GFP_KERNEL); + serport = kzalloc_obj(*serport); if (!serport) return -ENOMEM; @@ -159,7 +159,7 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) return -EBUSY; - serport->serio = serio = kzalloc(sizeof(*serio), GFP_KERNEL); + serport->serio = serio = kzalloc_obj(*serio); if (!serio) return -ENOMEM; diff --git a/drivers/input/serio/sun4i-ps2.c b/drivers/input/serio/sun4i-ps2.c index 524929ce1cae..a9812789771c 100644 --- a/drivers/input/serio/sun4i-ps2.c +++ b/drivers/input/serio/sun4i-ps2.c @@ -209,8 +209,8 @@ static int sun4i_ps2_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int error; - drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + drvdata = kzalloc_obj(*drvdata); + serio = kzalloc_obj(*serio); if (!drvdata || !serio) { error = -ENOMEM; goto err_free_mem; diff --git a/drivers/input/serio/userio.c b/drivers/input/serio/userio.c index 7f627b08055e..91cb7a177b2d 100644 --- a/drivers/input/serio/userio.c +++ b/drivers/input/serio/userio.c @@ -73,7 +73,7 @@ static int userio_device_write(struct serio *id, unsigned char val) static int userio_char_open(struct inode *inode, struct file *file) { struct userio_device *userio __free(kfree) = - kzalloc(sizeof(*userio), GFP_KERNEL); + kzalloc_obj(*userio); if (!userio) return -ENOMEM; @@ -81,7 +81,7 @@ static int userio_char_open(struct inode *inode, struct file *file) spin_lock_init(&userio->buf_lock); init_waitqueue_head(&userio->waitq); - userio->serio = kzalloc(sizeof(*userio->serio), GFP_KERNEL); + userio->serio = kzalloc_obj(*userio->serio); if (!userio->serio) return -ENOMEM; diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 01433f0b48f1..411d55ca1a66 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -247,8 +247,8 @@ static int xps2_of_probe(struct platform_device *ofdev) return -ENODEV; } - drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); - serio = kzalloc(sizeof(*serio), GFP_KERNEL); + drvdata = kzalloc_obj(*drvdata); + serio = kzalloc_obj(*serio); if (!drvdata || !serio) { error = -ENOMEM; goto failed1; diff --git a/drivers/input/tablet/acecad.c b/drivers/input/tablet/acecad.c index 0ac16f32b31f..ba79dff21aac 100644 --- a/drivers/input/tablet/acecad.c +++ b/drivers/input/tablet/acecad.c @@ -129,7 +129,7 @@ static int usb_acecad_probe(struct usb_interface *intf, const struct usb_device_ pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); maxp = usb_maxpacket(dev, pipe); - acecad = kzalloc(sizeof(*acecad), GFP_KERNEL); + acecad = kzalloc_obj(*acecad); input_dev = input_allocate_device(); if (!acecad || !input_dev) { err = -ENOMEM; diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 2b3fbb0455d5..6df24cee3c9d 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c @@ -1673,7 +1673,7 @@ aiptek_probe(struct usb_interface *intf, const struct usb_device_id *id) */ speeds[0] = programmableDelay; - aiptek = kzalloc(sizeof(*aiptek), GFP_KERNEL); + aiptek = kzalloc_obj(*aiptek); inputdev = input_allocate_device(); if (!aiptek || !inputdev) { dev_warn(&intf->dev, diff --git a/drivers/input/tablet/hanwang.c b/drivers/input/tablet/hanwang.c index 42c1e5eaddd5..fd5a7e761dcc 100644 --- a/drivers/input/tablet/hanwang.c +++ b/drivers/input/tablet/hanwang.c @@ -322,7 +322,7 @@ static int hanwang_probe(struct usb_interface *intf, const struct usb_device_id if (intf->cur_altsetting->desc.bNumEndpoints < 1) return -ENODEV; - hanwang = kzalloc(sizeof(*hanwang), GFP_KERNEL); + hanwang = kzalloc_obj(*hanwang); input_dev = input_allocate_device(); if (!hanwang || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/tablet/kbtab.c b/drivers/input/tablet/kbtab.c index 794caa102909..6ce70c8e2d7c 100644 --- a/drivers/input/tablet/kbtab.c +++ b/drivers/input/tablet/kbtab.c @@ -121,7 +121,7 @@ static int kbtab_probe(struct usb_interface *intf, const struct usb_device_id *i if (!usb_endpoint_is_int_in(endpoint)) return -ENODEV; - kbtab = kzalloc(sizeof(*kbtab), GFP_KERNEL); + kbtab = kzalloc_obj(*kbtab); input_dev = input_allocate_device(); if (!kbtab || !input_dev) goto fail1; diff --git a/drivers/input/tablet/pegasus_notetaker.c b/drivers/input/tablet/pegasus_notetaker.c index eabb4a0b8a0d..4ce20befc657 100644 --- a/drivers/input/tablet/pegasus_notetaker.c +++ b/drivers/input/tablet/pegasus_notetaker.c @@ -293,7 +293,7 @@ static int pegasus_probe(struct usb_interface *intf, endpoint = &intf->cur_altsetting->endpoint[0].desc; - pegasus = kzalloc(sizeof(*pegasus), GFP_KERNEL); + pegasus = kzalloc_obj(*pegasus); input_dev = input_allocate_device(); if (!pegasus || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/tablet/wacom_serial4.c b/drivers/input/tablet/wacom_serial4.c index cf7cea77dabc..bc0c77e5487f 100644 --- a/drivers/input/tablet/wacom_serial4.c +++ b/drivers/input/tablet/wacom_serial4.c @@ -521,7 +521,7 @@ static int wacom_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err = -ENOMEM; - wacom = kzalloc(sizeof(*wacom), GFP_KERNEL); + wacom = kzalloc_obj(*wacom); input_dev = input_allocate_device(); if (!wacom || !input_dev) goto free_device; diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index c9aa1847265a..33c5eb522389 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -201,7 +201,7 @@ static int ad7877_read(struct spi_device *spi, u16 reg) struct ser_req *req; int status, ret; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -232,7 +232,7 @@ static int ad7877_write(struct spi_device *spi, u16 reg, u16 val) struct ser_req *req; int status; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -259,7 +259,7 @@ static int ad7877_read_adc(struct spi_device *spi, unsigned command) int sample; int i; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 67264c5b49cb..0963b1a78a0c 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -357,7 +357,7 @@ static int ads7846_read12_ser(struct device *dev, unsigned command) struct ser_req *req; int status; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -442,7 +442,7 @@ static int ads7845_read12_ser(struct device *dev, unsigned command) struct ads7845_ser_req *req; int status; - req = kzalloc(sizeof *req, GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/input/touchscreen/da9052_tsi.c b/drivers/input/touchscreen/da9052_tsi.c index c2d3252f8466..a8e3d85eece7 100644 --- a/drivers/input/touchscreen/da9052_tsi.c +++ b/drivers/input/touchscreen/da9052_tsi.c @@ -232,7 +232,7 @@ static int da9052_ts_probe(struct platform_device *pdev) if (!da9052) return -EINVAL; - tsi = kzalloc(sizeof(*tsi), GFP_KERNEL); + tsi = kzalloc_obj(*tsi); input_dev = input_allocate_device(); if (!tsi || !input_dev) { error = -ENOMEM; diff --git a/drivers/input/touchscreen/dynapro.c b/drivers/input/touchscreen/dynapro.c index fe626a226b85..943ba8c2fb6c 100644 --- a/drivers/input/touchscreen/dynapro.c +++ b/drivers/input/touchscreen/dynapro.c @@ -110,7 +110,7 @@ static int dynapro_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - pdynapro = kzalloc(sizeof(*pdynapro), GFP_KERNEL); + pdynapro = kzalloc_obj(*pdynapro); input_dev = input_allocate_device(); if (!pdynapro || !input_dev) { err = -ENOMEM; @@ -119,8 +119,8 @@ static int dynapro_connect(struct serio *serio, struct serio_driver *drv) pdynapro->serio = serio; pdynapro->dev = input_dev; - snprintf(pdynapro->phys, sizeof(pdynapro->phys), - "%s/input0", serio->phys); + scnprintf(pdynapro->phys, sizeof(pdynapro->phys), + "%s/input0", serio->phys); input_dev->name = "Dynapro Serial TouchScreen"; input_dev->phys = pdynapro->phys; diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index bf498bd4dea9..d0ab644be006 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -1475,6 +1475,10 @@ static const struct edt_i2c_chip_data edt_ft5x06_data = { .max_support_points = 5, }; +static const struct edt_i2c_chip_data edt_ft3518_data = { + .max_support_points = 10, +}; + static const struct edt_i2c_chip_data edt_ft5452_data = { .max_support_points = 5, }; @@ -1503,6 +1507,7 @@ static const struct i2c_device_id edt_ft5x06_ts_id[] = { { .name = "edt-ft5x06", .driver_data = (long)&edt_ft5x06_data }, { .name = "edt-ft5506", .driver_data = (long)&edt_ft5506_data }, { .name = "ev-ft5726", .driver_data = (long)&edt_ft5506_data }, + { .name = "ft3518", .driver_data = (long)&edt_ft3518_data }, { .name = "ft5452", .driver_data = (long)&edt_ft5452_data }, /* Note no edt- prefix for compatibility with the ft6236.c driver */ { .name = "ft6236", .driver_data = (long)&edt_ft6236_data }, @@ -1519,6 +1524,7 @@ static const struct of_device_id edt_ft5x06_of_match[] = { { .compatible = "edt,edt-ft5406", .data = &edt_ft5x06_data }, { .compatible = "edt,edt-ft5506", .data = &edt_ft5506_data }, { .compatible = "evervision,ev-ft5726", .data = &edt_ft5506_data }, + { .compatible = "focaltech,ft3518", .data = &edt_ft3518_data }, { .compatible = "focaltech,ft5426", .data = &edt_ft5506_data }, { .compatible = "focaltech,ft5452", .data = &edt_ft5452_data }, /* Note focaltech vendor prefix for compatibility with ft6236.c */ diff --git a/drivers/input/touchscreen/egalax_ts_serial.c b/drivers/input/touchscreen/egalax_ts_serial.c index 07a4aa1c19bb..e04ea1fea4ad 100644 --- a/drivers/input/touchscreen/egalax_ts_serial.c +++ b/drivers/input/touchscreen/egalax_ts_serial.c @@ -99,7 +99,7 @@ static int egalax_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int error; - egalax = kzalloc(sizeof(*egalax), GFP_KERNEL); + egalax = kzalloc_obj(*egalax); input_dev = input_allocate_device(); if (!egalax || !input_dev) { error = -ENOMEM; @@ -108,8 +108,7 @@ static int egalax_connect(struct serio *serio, struct serio_driver *drv) egalax->serio = serio; egalax->input = input_dev; - snprintf(egalax->phys, sizeof(egalax->phys), - "%s/input0", serio->phys); + scnprintf(egalax->phys, sizeof(egalax->phys), "%s/input0", serio->phys); input_dev->name = "EETI eGalaxTouch Serial TouchScreen"; input_dev->phys = egalax->phys; diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index ad209e6e82a6..434b9b47e964 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c @@ -307,7 +307,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - elo = kzalloc(sizeof(*elo), GFP_KERNEL); + elo = kzalloc_obj(*elo); input_dev = input_allocate_device(); if (!elo || !input_dev) { err = -ENOMEM; @@ -320,7 +320,7 @@ static int elo_connect(struct serio *serio, struct serio_driver *drv) elo->expected_packet = ELO10_TOUCH_PACKET; mutex_init(&elo->cmd_mutex); init_completion(&elo->cmd_done); - snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); + scnprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); input_dev->name = "Elo Serial TouchScreen"; input_dev->phys = elo->phys; diff --git a/drivers/input/touchscreen/fujitsu_ts.c b/drivers/input/touchscreen/fujitsu_ts.c index 1a3e14ea2e08..8ed592294b17 100644 --- a/drivers/input/touchscreen/fujitsu_ts.c +++ b/drivers/input/touchscreen/fujitsu_ts.c @@ -99,7 +99,7 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - fujitsu = kzalloc(sizeof(*fujitsu), GFP_KERNEL); + fujitsu = kzalloc_obj(*fujitsu); input_dev = input_allocate_device(); if (!fujitsu || !input_dev) { err = -ENOMEM; @@ -108,8 +108,7 @@ static int fujitsu_connect(struct serio *serio, struct serio_driver *drv) fujitsu->serio = serio; fujitsu->dev = input_dev; - snprintf(fujitsu->phys, sizeof(fujitsu->phys), - "%s/input0", serio->phys); + scnprintf(fujitsu->phys, sizeof(fujitsu->phys), "%s/input0", serio->phys); input_dev->name = "Fujitsu Serial Touchscreen"; input_dev->phys = fujitsu->phys; diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index dbf92fb02f80..2baeb4f3b941 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c @@ -97,7 +97,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - gunze = kzalloc(sizeof(*gunze), GFP_KERNEL); + gunze = kzalloc_obj(*gunze); input_dev = input_allocate_device(); if (!gunze || !input_dev) { err = -ENOMEM; @@ -106,7 +106,7 @@ static int gunze_connect(struct serio *serio, struct serio_driver *drv) gunze->serio = serio; gunze->dev = input_dev; - snprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); + scnprintf(gunze->phys, sizeof(serio->phys), "%s/input0", serio->phys); input_dev->name = "Gunze AHL-51S TouchScreen"; input_dev->phys = gunze->phys; diff --git a/drivers/input/touchscreen/hampshire.c b/drivers/input/touchscreen/hampshire.c index dc0a2482ddd6..394ae8c88d50 100644 --- a/drivers/input/touchscreen/hampshire.c +++ b/drivers/input/touchscreen/hampshire.c @@ -109,7 +109,7 @@ static int hampshire_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - phampshire = kzalloc(sizeof(*phampshire), GFP_KERNEL); + phampshire = kzalloc_obj(*phampshire); input_dev = input_allocate_device(); if (!phampshire || !input_dev) { err = -ENOMEM; @@ -118,8 +118,8 @@ static int hampshire_connect(struct serio *serio, struct serio_driver *drv) phampshire->serio = serio; phampshire->dev = input_dev; - snprintf(phampshire->phys, sizeof(phampshire->phys), - "%s/input0", serio->phys); + scnprintf(phampshire->phys, sizeof(phampshire->phys), + "%s/input0", serio->phys); input_dev->name = "Hampshire Serial TouchScreen"; input_dev->phys = phampshire->phys; diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index fa38d70aded7..3bf524a6ee20 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -327,9 +327,8 @@ static bool ili210x_report_events(struct ili210x *priv, u8 *touchdata) return contact; } -static irqreturn_t ili210x_irq(int irq, void *irq_data) +static void ili210x_process_events(struct ili210x *priv) { - struct ili210x *priv = irq_data; struct i2c_client *client = priv->client; const struct ili2xxx_chip *chip = priv->chip; u8 touchdata[ILI210X_DATA_SIZE] = { 0 }; @@ -356,8 +355,22 @@ static irqreturn_t ili210x_irq(int irq, void *irq_data) usleep_range(time_delta, time_delta + 1000); } } while (!priv->stop && keep_polling); +} + +static irqreturn_t ili210x_irq(int irq, void *irq_data) +{ + struct ili210x *priv = irq_data; + + ili210x_process_events(priv); return IRQ_HANDLED; +}; + +static void ili210x_work_i2c_poll(struct input_dev *input) +{ + struct ili210x *priv = input_get_drvdata(input); + + ili210x_process_events(priv); } static int ili251x_firmware_update_resolution(struct device *dev) @@ -829,12 +842,32 @@ static int ili210x_do_firmware_update(struct ili210x *priv, return 0; } +static ssize_t ili210x_firmware_update(struct device *dev, const u8 *fwbuf, + u16 ac_end, u16 df_end) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ili210x *priv = i2c_get_clientdata(client); + const char *fwname = ILI251X_FW_FILENAME; + int error; + + dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); + + ili210x_hardware_reset(priv->reset_gpio); + + error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); + + ili210x_hardware_reset(priv->reset_gpio); + + dev_dbg(dev, "Firmware update ended, error=%i\n", error); + + return error; +} + static ssize_t ili210x_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); - struct ili210x *priv = i2c_get_clientdata(client); const char *fwname = ILI251X_FW_FILENAME; u16 ac_end, df_end; int error; @@ -860,16 +893,11 @@ static ssize_t ili210x_firmware_update_store(struct device *dev, * the touch controller to disable the IRQs during update, so we have * to do it this way here. */ - scoped_guard(disable_irq, &client->irq) { - dev_dbg(dev, "Firmware update started, firmware=%s\n", fwname); - - ili210x_hardware_reset(priv->reset_gpio); - - error = ili210x_do_firmware_update(priv, fwbuf, ac_end, df_end); - - ili210x_hardware_reset(priv->reset_gpio); - - dev_dbg(dev, "Firmware update ended, error=%i\n", error); + if (client->irq > 0) { + guard(disable_irq)(&client->irq); + error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end); + } else { + error = ili210x_firmware_update(dev, fwbuf, ac_end, df_end); } return error ?: count; @@ -942,15 +970,8 @@ static int ili210x_i2c_probe(struct i2c_client *client) chip = device_get_match_data(dev); if (!chip && id) chip = (const struct ili2xxx_chip *)id->driver_data; - if (!chip) { - dev_err(&client->dev, "unknown device model\n"); - return -ENODEV; - } - - if (client->irq <= 0) { - dev_err(dev, "No IRQ!\n"); - return -EINVAL; - } + if (!chip) + return dev_err_probe(&client->dev, -ENODEV, "unknown device model\n"); reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset_gpio)) @@ -998,17 +1019,22 @@ static int ili210x_i2c_probe(struct i2c_client *client) error = input_mt_init_slots(input, priv->chip->max_touches, INPUT_MT_DIRECT); - if (error) { - dev_err(dev, "Unable to set up slots, err: %d\n", error); - return error; - } + if (error) + return dev_err_probe(dev, error, "Unable to set up slots\n"); - error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, - IRQF_ONESHOT, client->name, priv); - if (error) { - dev_err(dev, "Unable to request touchscreen IRQ, err: %d\n", - error); - return error; + input_set_drvdata(input, priv); + + if (client->irq > 0) { + error = devm_request_threaded_irq(dev, client->irq, NULL, ili210x_irq, + IRQF_ONESHOT, client->name, priv); + if (error) + return dev_err_probe(dev, error, "Unable to request touchscreen IRQ\n"); + } else { + error = input_setup_polling(input, ili210x_work_i2c_poll); + if (error) + return dev_err_probe(dev, error, "Could not set up polling mode\n"); + + input_set_poll_interval(input, ILI2XXX_POLL_PERIOD); } error = devm_add_action_or_reset(dev, ili210x_stop, priv); @@ -1016,10 +1042,8 @@ static int ili210x_i2c_probe(struct i2c_client *client) return error; error = input_register_device(priv->input); - if (error) { - dev_err(dev, "Cannot register input device, err: %d\n", error); - return error; - } + if (error) + return dev_err_probe(dev, error, "Cannot register input device\n"); return 0; } diff --git a/drivers/input/touchscreen/ilitek_ts_i2c.c b/drivers/input/touchscreen/ilitek_ts_i2c.c index 0dd632724a00..0706443792ba 100644 --- a/drivers/input/touchscreen/ilitek_ts_i2c.c +++ b/drivers/input/touchscreen/ilitek_ts_i2c.c @@ -122,7 +122,7 @@ static int ilitek_i2c_write_and_read(struct ilitek_ts_data *ts, return error; } if (delay > 0) - mdelay(delay); + fsleep(delay * 1000); if (read_len > 0) { error = i2c_transfer(client->adapter, msgs + 1, 1); @@ -396,10 +396,10 @@ static const struct ilitek_protocol_map ptl_func_map[] = { static void ilitek_reset(struct ilitek_ts_data *ts, int delay) { if (ts->reset_gpio) { - gpiod_set_value(ts->reset_gpio, 1); - mdelay(10); - gpiod_set_value(ts->reset_gpio, 0); - mdelay(delay); + gpiod_set_value_cansleep(ts->reset_gpio, 1); + fsleep(10000); + gpiod_set_value_cansleep(ts->reset_gpio, 0); + fsleep(delay * 1000); } } diff --git a/drivers/input/touchscreen/inexio.c b/drivers/input/touchscreen/inexio.c index 82f7ac62a4f2..ac3836ff2a30 100644 --- a/drivers/input/touchscreen/inexio.c +++ b/drivers/input/touchscreen/inexio.c @@ -114,7 +114,7 @@ static int inexio_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - pinexio = kzalloc(sizeof(*pinexio), GFP_KERNEL); + pinexio = kzalloc_obj(*pinexio); input_dev = input_allocate_device(); if (!pinexio || !input_dev) { err = -ENOMEM; @@ -123,7 +123,7 @@ static int inexio_connect(struct serio *serio, struct serio_driver *drv) pinexio->serio = serio; pinexio->dev = input_dev; - snprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys); + scnprintf(pinexio->phys, sizeof(pinexio->phys), "%s/input0", serio->phys); input_dev->name = "iNexio Serial TouchScreen"; input_dev->phys = pinexio->phys; diff --git a/drivers/input/touchscreen/mc13783_ts.c b/drivers/input/touchscreen/mc13783_ts.c index 47b8da00027f..4b7e70a4c6d5 100644 --- a/drivers/input/touchscreen/mc13783_ts.c +++ b/drivers/input/touchscreen/mc13783_ts.c @@ -168,7 +168,7 @@ static int __init mc13783_ts_probe(struct platform_device *pdev) struct input_dev *idev; int ret = -ENOMEM; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); idev = input_allocate_device(); if (!priv || !idev) goto err_free_mem; diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c index 7511a134e302..993d945dcd23 100644 --- a/drivers/input/touchscreen/migor_ts.c +++ b/drivers/input/touchscreen/migor_ts.c @@ -122,7 +122,7 @@ static int migor_ts_probe(struct i2c_client *client) struct input_dev *input; int error; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); input = input_allocate_device(); if (!priv || !input) { dev_err(&client->dev, "failed to allocate memory\n"); diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index eefae96a2d40..cc2d206d2f3d 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c @@ -128,7 +128,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - mtouch = kzalloc(sizeof(*mtouch), GFP_KERNEL); + mtouch = kzalloc_obj(*mtouch); input_dev = input_allocate_device(); if (!mtouch || !input_dev) { err = -ENOMEM; @@ -137,7 +137,7 @@ static int mtouch_connect(struct serio *serio, struct serio_driver *drv) mtouch->serio = serio; mtouch->dev = input_dev; - snprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); + scnprintf(mtouch->phys, sizeof(mtouch->phys), "%s/input0", serio->phys); input_dev->name = "MicroTouch Serial TouchScreen"; input_dev->phys = mtouch->phys; diff --git a/drivers/input/touchscreen/novatek-nvt-ts.c b/drivers/input/touchscreen/novatek-nvt-ts.c index 44b58e0dc1ad..3e6e2ee0ba8f 100644 --- a/drivers/input/touchscreen/novatek-nvt-ts.c +++ b/drivers/input/touchscreen/novatek-nvt-ts.c @@ -27,7 +27,6 @@ #define NVT_TS_PARAMS_MAX_TOUCH 0x09 #define NVT_TS_PARAMS_MAX_BUTTONS 0x0a #define NVT_TS_PARAMS_IRQ_TYPE 0x0b -#define NVT_TS_PARAMS_WAKE_TYPE 0x0c #define NVT_TS_PARAMS_CHIP_ID 0x0e #define NVT_TS_PARAMS_SIZE 0x0f @@ -49,7 +48,6 @@ static const int nvt_ts_irq_type[4] = { }; struct nvt_ts_i2c_chip_data { - u8 wake_type; u8 chip_id; }; @@ -261,7 +259,6 @@ static int nvt_ts_probe(struct i2c_client *client) if (width > NVT_TS_MAX_SIZE || height >= NVT_TS_MAX_SIZE || data->max_touches > NVT_TS_MAX_TOUCHES || irq_type >= ARRAY_SIZE(nvt_ts_irq_type) || - data->buf[NVT_TS_PARAMS_WAKE_TYPE] != chip->wake_type || data->buf[NVT_TS_PARAMS_CHIP_ID] != chip->chip_id) { dev_err(dev, "Unsupported touchscreen parameters: %*ph\n", NVT_TS_PARAMS_SIZE, data->buf); @@ -314,12 +311,10 @@ static int nvt_ts_probe(struct i2c_client *client) } static const struct nvt_ts_i2c_chip_data nvt_nt11205_ts_data = { - .wake_type = 0x05, .chip_id = 0x05, }; static const struct nvt_ts_i2c_chip_data nvt_nt36672a_ts_data = { - .wake_type = 0x01, .chip_id = 0x08, }; diff --git a/drivers/input/touchscreen/pcap_ts.c b/drivers/input/touchscreen/pcap_ts.c index 083206a3457b..7b89eb74b9de 100644 --- a/drivers/input/touchscreen/pcap_ts.c +++ b/drivers/input/touchscreen/pcap_ts.c @@ -138,7 +138,7 @@ static int pcap_ts_probe(struct platform_device *pdev) struct pcap_ts *pcap_ts; int err = -ENOMEM; - pcap_ts = kzalloc(sizeof(*pcap_ts), GFP_KERNEL); + pcap_ts = kzalloc_obj(*pcap_ts); if (!pcap_ts) return err; diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 95adede26703..4b57b6664e37 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c @@ -199,7 +199,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) int max_x, max_y; int err; - pm = kzalloc(sizeof(*pm), GFP_KERNEL); + pm = kzalloc_obj(*pm); input_dev = input_allocate_device(); if (!pm || !input_dev) { err = -ENOMEM; @@ -208,7 +208,7 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) pm->serio = serio; pm->dev = input_dev; - snprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); + scnprintf(pm->phys, sizeof(pm->phys), "%s/input0", serio->phys); pm->maxcontacts = 1; input_dev->name = "PenMount Serial TouchScreen"; diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c index 119cd26851cf..4b166b0a9a5a 100644 --- a/drivers/input/touchscreen/stmfts.c +++ b/drivers/input/touchscreen/stmfts.c @@ -120,7 +120,7 @@ static int stmfts_brightness_set(struct led_classdev *led_cdev, err = regulator_enable(sdata->ledvdd); if (err) { dev_warn(&sdata->client->dev, - "failed to disable ledvdd regulator: %d\n", + "failed to enable ledvdd regulator: %d\n", err); return err; } @@ -141,7 +141,7 @@ static enum led_brightness stmfts_brightness_get(struct led_classdev *led_cdev) /* * We can't simply use i2c_smbus_read_i2c_block_data because we - * need to read more than 255 bytes ( + * need to read 256 bytes, which exceeds the 255-byte SMBus block limit. */ static int stmfts_read_events(struct stmfts_data *sdata) { @@ -410,7 +410,7 @@ static ssize_t stmfts_sysfs_chip_id(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%#x\n", sdata->chip_id); + return sysfs_emit(buf, "%#x\n", sdata->chip_id); } static ssize_t stmfts_sysfs_chip_version(struct device *dev, @@ -418,7 +418,7 @@ static ssize_t stmfts_sysfs_chip_version(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", sdata->chip_ver); + return sysfs_emit(buf, "%u\n", sdata->chip_ver); } static ssize_t stmfts_sysfs_fw_ver(struct device *dev, @@ -426,7 +426,7 @@ static ssize_t stmfts_sysfs_fw_ver(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", sdata->fw_ver); + return sysfs_emit(buf, "%u\n", sdata->fw_ver); } static ssize_t stmfts_sysfs_config_id(struct device *dev, @@ -434,7 +434,7 @@ static ssize_t stmfts_sysfs_config_id(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%#x\n", sdata->config_id); + return sysfs_emit(buf, "%#x\n", sdata->config_id); } static ssize_t stmfts_sysfs_config_version(struct device *dev, @@ -442,7 +442,7 @@ static ssize_t stmfts_sysfs_config_version(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", sdata->config_ver); + return sysfs_emit(buf, "%u\n", sdata->config_ver); } static ssize_t stmfts_sysfs_read_status(struct device *dev, @@ -457,7 +457,7 @@ static ssize_t stmfts_sysfs_read_status(struct device *dev, if (err) return err; - return sprintf(buf, "%#02x\n", status[0]); + return sysfs_emit(buf, "%#02x\n", status[0]); } static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev, @@ -465,7 +465,7 @@ static ssize_t stmfts_sysfs_hover_enable_read(struct device *dev, { struct stmfts_data *sdata = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", sdata->hover_enabled); + return sysfs_emit(buf, "%u\n", sdata->hover_enabled); } static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev, @@ -594,9 +594,6 @@ static void stmfts_power_off(void *data) sdata->regulators); } -/* This function is void because I don't want to prevent using the touch key - * only because the LEDs don't get registered - */ static int stmfts_enable_led(struct stmfts_data *sdata) { int err; diff --git a/drivers/input/touchscreen/sur40.c b/drivers/input/touchscreen/sur40.c index 7b3b10cbfcfc..877eae34fb5a 100644 --- a/drivers/input/touchscreen/sur40.c +++ b/drivers/input/touchscreen/sur40.c @@ -672,7 +672,7 @@ static int sur40_probe(struct usb_interface *interface, return -ENODEV; /* Allocate memory for our device state and initialize it. */ - sur40 = kzalloc(sizeof(*sur40), GFP_KERNEL); + sur40 = kzalloc_obj(*sur40); if (!sur40) return -ENOMEM; diff --git a/drivers/input/touchscreen/ti_am335x_tsc.c b/drivers/input/touchscreen/ti_am335x_tsc.c index 0534b2ba650b..623546e80668 100644 --- a/drivers/input/touchscreen/ti_am335x_tsc.c +++ b/drivers/input/touchscreen/ti_am335x_tsc.c @@ -422,7 +422,7 @@ static int titsc_probe(struct platform_device *pdev) int err; /* Allocate memory for device */ - ts_dev = kzalloc(sizeof(*ts_dev), GFP_KERNEL); + ts_dev = kzalloc_obj(*ts_dev); input_dev = input_allocate_device(); if (!ts_dev || !input_dev) { dev_err(&pdev->dev, "failed to allocate memory.\n"); diff --git a/drivers/input/touchscreen/touchit213.c b/drivers/input/touchscreen/touchit213.c index c2718350815c..6d4a1acf57c9 100644 --- a/drivers/input/touchscreen/touchit213.c +++ b/drivers/input/touchscreen/touchit213.c @@ -139,7 +139,7 @@ static int touchit213_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - touchit213 = kzalloc(sizeof(*touchit213), GFP_KERNEL); + touchit213 = kzalloc_obj(*touchit213); input_dev = input_allocate_device(); if (!touchit213 || !input_dev) { err = -ENOMEM; @@ -148,8 +148,8 @@ static int touchit213_connect(struct serio *serio, struct serio_driver *drv) touchit213->serio = serio; touchit213->dev = input_dev; - snprintf(touchit213->phys, sizeof(touchit213->phys), - "%s/input0", serio->phys); + scnprintf(touchit213->phys, sizeof(touchit213->phys), + "%s/input0", serio->phys); input_dev->name = "Sahara Touch-iT213 Serial TouchScreen"; input_dev->phys = touchit213->phys; diff --git a/drivers/input/touchscreen/touchright.c b/drivers/input/touchscreen/touchright.c index 30ba97bd00a1..d7fdf201e4d1 100644 --- a/drivers/input/touchscreen/touchright.c +++ b/drivers/input/touchscreen/touchright.c @@ -102,7 +102,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - tr = kzalloc(sizeof(*tr), GFP_KERNEL); + tr = kzalloc_obj(*tr); input_dev = input_allocate_device(); if (!tr || !input_dev) { err = -ENOMEM; @@ -111,7 +111,7 @@ static int tr_connect(struct serio *serio, struct serio_driver *drv) tr->serio = serio; tr->dev = input_dev; - snprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); + scnprintf(tr->phys, sizeof(tr->phys), "%s/input0", serio->phys); input_dev->name = "Touchright Serial TouchScreen"; input_dev->phys = tr->phys; diff --git a/drivers/input/touchscreen/touchwin.c b/drivers/input/touchscreen/touchwin.c index fbd72789ea80..099fd88e65d8 100644 --- a/drivers/input/touchscreen/touchwin.c +++ b/drivers/input/touchscreen/touchwin.c @@ -109,7 +109,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int err; - tw = kzalloc(sizeof(*tw), GFP_KERNEL); + tw = kzalloc_obj(*tw); input_dev = input_allocate_device(); if (!tw || !input_dev) { err = -ENOMEM; @@ -118,7 +118,7 @@ static int tw_connect(struct serio *serio, struct serio_driver *drv) tw->serio = serio; tw->dev = input_dev; - snprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); + scnprintf(tw->phys, sizeof(tw->phys), "%s/input0", serio->phys); input_dev->name = "Touchwindow Serial TouchScreen"; input_dev->phys = tw->phys; diff --git a/drivers/input/touchscreen/tsc40.c b/drivers/input/touchscreen/tsc40.c index 9f485cf57a72..2a28a309eab5 100644 --- a/drivers/input/touchscreen/tsc40.c +++ b/drivers/input/touchscreen/tsc40.c @@ -83,7 +83,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) struct input_dev *input_dev; int error; - ptsc = kzalloc(sizeof(*ptsc), GFP_KERNEL); + ptsc = kzalloc_obj(*ptsc); input_dev = input_allocate_device(); if (!ptsc || !input_dev) { error = -ENOMEM; @@ -92,7 +92,7 @@ static int tsc_connect(struct serio *serio, struct serio_driver *drv) ptsc->serio = serio; ptsc->dev = input_dev; - snprintf(ptsc->phys, sizeof(ptsc->phys), "%s/input0", serio->phys); + scnprintf(ptsc->phys, sizeof(ptsc->phys), "%s/input0", serio->phys); input_dev->name = "TSC-10/25/40 Serial TouchScreen"; input_dev->phys = ptsc->phys; diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 7567efabe014..657555c8796c 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c @@ -378,7 +378,7 @@ static int mtouch_alloc(struct usbtouch_usb *usbtouch) { struct mtouch_priv *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -938,7 +938,7 @@ static int nexio_alloc(struct usbtouch_usb *usbtouch) struct nexio_priv *priv; int ret = -ENOMEM; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) goto out_buf; @@ -1458,7 +1458,7 @@ static int usbtouch_probe(struct usb_interface *intf, if (!endpoint) return -ENXIO; - usbtouch = kzalloc(sizeof(*usbtouch), GFP_KERNEL); + usbtouch = kzalloc_obj(*usbtouch); input_dev = input_allocate_device(); if (!usbtouch || !input_dev) goto out_free; diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c index ed2ca8a689d5..45930d731873 100644 --- a/drivers/input/touchscreen/wacom_w8001.c +++ b/drivers/input/touchscreen/wacom_w8001.c @@ -596,7 +596,7 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv) char basename[64] = "Wacom Serial"; int err, err_pen, err_touch; - w8001 = kzalloc(sizeof(*w8001), GFP_KERNEL); + w8001 = kzalloc_obj(*w8001); input_dev_pen = input_allocate_device(); input_dev_touch = input_allocate_device(); if (!w8001 || !input_dev_pen || !input_dev_touch) { diff --git a/drivers/input/touchscreen/wdt87xx_i2c.c b/drivers/input/touchscreen/wdt87xx_i2c.c index 88d376090e6e..1e2a6bbb88cb 100644 --- a/drivers/input/touchscreen/wdt87xx_i2c.c +++ b/drivers/input/touchscreen/wdt87xx_i2c.c @@ -1026,10 +1026,8 @@ static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt) int error; input = devm_input_allocate_device(dev); - if (!input) { - dev_err(dev, "failed to allocate input device\n"); + if (!input) return -ENOMEM; - } wdt->input = input; input->name = "WDT87xx Touchscreen"; @@ -1053,10 +1051,8 @@ static int wdt87xx_ts_create_input_device(struct wdt87xx_data *wdt) INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); error = input_register_device(input); - if (error) { - dev_err(dev, "failed to register input device: %d\n", error); - return error; - } + if (error) + return dev_err_probe(dev, error, "failed to register input device\n"); return 0; } @@ -1096,10 +1092,8 @@ static int wdt87xx_ts_probe(struct i2c_client *client) NULL, wdt87xx_ts_interrupt, IRQF_ONESHOT, client->name, wdt); - if (error) { - dev_err(&client->dev, "request irq failed: %d\n", error); + if (error) return error; - } return 0; } diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig index f2e49bd97d31..882dcb0b4a5b 100644 --- a/drivers/interconnect/Kconfig +++ b/drivers/interconnect/Kconfig @@ -22,4 +22,18 @@ config INTERCONNECT_CLK help Support for wrapping clocks into the interconnect nodes. +config INTERCONNECT_KUNIT_TEST + tristate "KUnit tests for Interconnect framework" + depends on KUNIT + default KUNIT_ALL_TESTS + help + This builds the KUnit test suite for the generic system interconnect + framework. + + The tests cover the core functionality of the interconnect subsystem, + including provider/consumer APIs, topology management, and bandwidth + aggregation logic. + + If unsure, say N. + endif diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile index b0a9a6753b9d..dc4c7b657c9d 100644 --- a/drivers/interconnect/Makefile +++ b/drivers/interconnect/Makefile @@ -10,3 +10,5 @@ obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/ obj-$(CONFIG_INTERCONNECT_SAMSUNG) += samsung/ obj-$(CONFIG_INTERCONNECT_CLK) += icc-clk.o + +obj-$(CONFIG_INTERCONNECT_KUNIT_TEST) += icc-kunit.o diff --git a/drivers/interconnect/core.c b/drivers/interconnect/core.c index 6cc979b26151..8569b78a1851 100644 --- a/drivers/interconnect/core.c +++ b/drivers/interconnect/core.c @@ -172,7 +172,7 @@ static struct icc_path *path_init(struct device *dev, struct icc_node *dst, struct icc_path *path; int i; - path = kzalloc(struct_size(path, reqs, num_nodes), GFP_KERNEL); + path = kzalloc_flex(*path, reqs, num_nodes); if (!path) return ERR_PTR(-ENOMEM); @@ -408,7 +408,7 @@ struct icc_node_data *of_icc_get_from_provider(const struct of_phandle_args *spe return ERR_CAST(node); if (!data) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); data->node = node; @@ -827,7 +827,7 @@ static struct icc_node *icc_node_create_nolock(int id) if (node) return node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return ERR_PTR(-ENOMEM); diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c index 24d7b5a57794..5107bff53173 100644 --- a/drivers/interconnect/debugfs-client.c +++ b/drivers/interconnect/debugfs-client.c @@ -86,7 +86,7 @@ static int icc_get_set(void *data, u64 val) goto err_free; } - debugfs_path = kzalloc(sizeof(*debugfs_path), GFP_KERNEL); + debugfs_path = kzalloc_obj(*debugfs_path); if (!debugfs_path) { ret = -ENOMEM; goto err_put; diff --git a/drivers/interconnect/icc-kunit.c b/drivers/interconnect/icc-kunit.c new file mode 100644 index 000000000000..bad2b583737b --- /dev/null +++ b/drivers/interconnect/icc-kunit.c @@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for the Interconnect framework. + * + * Copyright (c) 2025 Kuan-Wei Chiu + * + * This suite verifies the behavior of the interconnect core, including + * topology construction, bandwidth aggregation, and path lifecycle. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +enum { + NODE_CPU, + NODE_GPU, + NODE_BUS, + NODE_DDR, + NODE_MAX +}; + +struct test_node_data { + int id; + const char *name; + int num_links; + int links[2]; +}; + +/* + * Static Topology: + * CPU -\ + * -> BUS -> DDR + * GPU -/ + */ +static const struct test_node_data test_topology[] = { + { NODE_CPU, "cpu", 1, { NODE_BUS } }, + { NODE_GPU, "gpu", 1, { NODE_BUS } }, + { NODE_BUS, "bus", 1, { NODE_DDR } }, + { NODE_DDR, "ddr", 0, { } }, +}; + +struct icc_test_priv { + struct icc_provider provider; + struct platform_device *pdev; + struct icc_node *nodes[NODE_MAX]; +}; + +static struct icc_node *get_node(struct icc_test_priv *priv, int id) +{ + int idx = id - NODE_CPU; + + if (idx < 0 || idx >= ARRAY_SIZE(test_topology)) + return NULL; + return priv->nodes[idx]; +} + +static int icc_test_set(struct icc_node *src, struct icc_node *dst) +{ + return 0; +} + +static int icc_test_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, + u32 peak_bw, u32 *agg_avg, u32 *agg_peak) +{ + return icc_std_aggregate(node, tag, avg_bw, peak_bw, agg_avg, agg_peak); +} + +static struct icc_node *icc_test_xlate(const struct of_phandle_args *spec, void *data) +{ + return NULL; +} + +static int icc_test_get_bw(struct icc_node *node, u32 *avg, u32 *peak) +{ + *avg = 0; + *peak = 0; + + return 0; +} + +static int icc_test_init(struct kunit *test) +{ + struct icc_test_priv *priv; + struct icc_node *node; + int i, j, ret; + + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + test->priv = priv; + + priv->pdev = kunit_platform_device_alloc(test, "icc-test-dev", -1); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->pdev); + KUNIT_ASSERT_EQ(test, kunit_platform_device_add(test, priv->pdev), 0); + + priv->provider.set = icc_test_set; + priv->provider.aggregate = icc_test_aggregate; + priv->provider.xlate = icc_test_xlate; + priv->provider.get_bw = icc_test_get_bw; + priv->provider.dev = &priv->pdev->dev; + priv->provider.data = priv; + INIT_LIST_HEAD(&priv->provider.nodes); + + ret = icc_provider_register(&priv->provider); + KUNIT_ASSERT_EQ(test, ret, 0); + + for (i = 0; i < ARRAY_SIZE(test_topology); i++) { + const struct test_node_data *data = &test_topology[i]; + + node = icc_node_create(data->id); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, node); + + node->name = data->name; + icc_node_add(node, &priv->provider); + priv->nodes[i] = node; + } + + for (i = 0; i < ARRAY_SIZE(test_topology); i++) { + const struct test_node_data *data = &test_topology[i]; + struct icc_node *src = get_node(priv, data->id); + + for (j = 0; j < data->num_links; j++) { + ret = icc_link_create(src, data->links[j]); + KUNIT_ASSERT_EQ_MSG(test, ret, 0, "Failed to link %s->%d", + src->name, data->links[j]); + } + } + + icc_sync_state(&priv->pdev->dev); + + return 0; +} + +static void icc_test_exit(struct kunit *test) +{ + struct icc_test_priv *priv = test->priv; + + icc_nodes_remove(&priv->provider); + icc_provider_deregister(&priv->provider); +} + +/* + * Helper to construct a mock path. + * + * Because we are bypassing icc_get(), we must manually link the requests + * to the nodes' req_list so that icc_std_aggregate() can discover them. + */ +static struct icc_path *icc_test_create_path(struct kunit *test, + struct icc_node **nodes, int num) +{ + struct icc_path *path; + int i; + + path = kunit_kzalloc(test, struct_size(path, reqs, num), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, path); + + path->num_nodes = num; + for (i = 0; i < num; i++) { + path->reqs[i].node = nodes[i]; + hlist_add_head(&path->reqs[i].req_node, &nodes[i]->req_list); + } + path->name = "mock-path"; + + return path; +} + +static void icc_test_destroy_path(struct kunit *test, struct icc_path *path) +{ + int i; + + for (i = 0; i < path->num_nodes; i++) + hlist_del(&path->reqs[i].req_node); + + kunit_kfree(test, path); +} + +static void icc_test_topology_integrity(struct kunit *test) +{ + struct icc_test_priv *priv = test->priv; + struct icc_node *cpu = get_node(priv, NODE_CPU); + struct icc_node *bus = get_node(priv, NODE_BUS); + + KUNIT_EXPECT_EQ(test, cpu->num_links, 1); + KUNIT_EXPECT_PTR_EQ(test, cpu->links[0], bus); + KUNIT_EXPECT_PTR_EQ(test, cpu->provider, &priv->provider); +} + +static void icc_test_set_bw(struct kunit *test) +{ + struct icc_test_priv *priv = test->priv; + struct icc_path *path; + struct icc_node *path_nodes[3]; + int ret; + + /* Path: CPU -> BUS -> DDR */ + path_nodes[0] = get_node(priv, NODE_CPU); + path_nodes[1] = get_node(priv, NODE_BUS); + path_nodes[2] = get_node(priv, NODE_DDR); + + path = icc_test_create_path(test, path_nodes, 3); + + ret = icc_enable(path); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = icc_set_bw(path, 1000, 2000); + KUNIT_EXPECT_EQ(test, ret, 0); + + KUNIT_EXPECT_EQ(test, path_nodes[0]->avg_bw, 1000); + KUNIT_EXPECT_EQ(test, path_nodes[0]->peak_bw, 2000); + KUNIT_EXPECT_EQ(test, path_nodes[1]->avg_bw, 1000); + KUNIT_EXPECT_EQ(test, path_nodes[1]->peak_bw, 2000); + + icc_set_tag(path, 0xABC); + KUNIT_EXPECT_EQ(test, path->reqs[0].tag, 0xABC); + + icc_disable(path); + KUNIT_EXPECT_EQ(test, path_nodes[0]->avg_bw, 0); + + icc_test_destroy_path(test, path); +} + +static void icc_test_aggregation(struct kunit *test) +{ + struct icc_test_priv *priv = test->priv; + struct icc_path *path_cpu, *path_gpu; + struct icc_node *nodes_cpu[3], *nodes_gpu[2]; + struct icc_node *bus = get_node(priv, NODE_BUS); + int ret; + + nodes_cpu[0] = get_node(priv, NODE_CPU); + nodes_cpu[1] = bus; + nodes_cpu[2] = get_node(priv, NODE_DDR); + path_cpu = icc_test_create_path(test, nodes_cpu, 3); + + nodes_gpu[0] = get_node(priv, NODE_GPU); + nodes_gpu[1] = bus; + path_gpu = icc_test_create_path(test, nodes_gpu, 2); + + icc_enable(path_cpu); + icc_enable(path_gpu); + + ret = icc_set_bw(path_cpu, 1000, 1000); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, bus->avg_bw, 1000); + + ret = icc_set_bw(path_gpu, 2000, 2000); + KUNIT_EXPECT_EQ(test, ret, 0); + + /* Bus aggregates: CPU(1000) + GPU(2000) */ + KUNIT_EXPECT_EQ(test, bus->avg_bw, 3000); + /* Peak aggregates: max(CPU, GPU) */ + KUNIT_EXPECT_EQ(test, bus->peak_bw, 2000); + + icc_test_destroy_path(test, path_cpu); + icc_test_destroy_path(test, path_gpu); +} + +static void icc_test_bulk_ops(struct kunit *test) +{ + struct icc_test_priv *priv = test->priv; + struct icc_node *nodes_cpu[3], *nodes_gpu[2]; + struct icc_bulk_data bulk[2]; + int ret; + + nodes_cpu[0] = get_node(priv, NODE_CPU); + nodes_cpu[1] = get_node(priv, NODE_BUS); + nodes_cpu[2] = get_node(priv, NODE_DDR); + + nodes_gpu[0] = get_node(priv, NODE_GPU); + nodes_gpu[1] = get_node(priv, NODE_BUS); + + bulk[0].path = icc_test_create_path(test, nodes_cpu, 3); + bulk[0].avg_bw = 500; + bulk[0].peak_bw = 500; + + bulk[1].path = icc_test_create_path(test, nodes_gpu, 2); + bulk[1].avg_bw = 600; + bulk[1].peak_bw = 600; + + ret = icc_bulk_set_bw(2, bulk); + KUNIT_EXPECT_EQ(test, ret, 0); + /* Paths disabled, bandwidth should be 0 */ + KUNIT_EXPECT_EQ(test, get_node(priv, NODE_BUS)->avg_bw, 0); + + ret = icc_bulk_enable(2, bulk); + KUNIT_EXPECT_EQ(test, ret, 0); + /* Paths enabled, aggregation applies */ + KUNIT_EXPECT_EQ(test, get_node(priv, NODE_BUS)->avg_bw, 1100); + + icc_bulk_disable(2, bulk); + KUNIT_EXPECT_EQ(test, get_node(priv, NODE_BUS)->avg_bw, 0); + + icc_test_destroy_path(test, bulk[0].path); + icc_test_destroy_path(test, bulk[1].path); +} + +static struct kunit_case icc_test_cases[] = { + KUNIT_CASE(icc_test_topology_integrity), + KUNIT_CASE(icc_test_set_bw), + KUNIT_CASE(icc_test_aggregation), + KUNIT_CASE(icc_test_bulk_ops), + {} +}; + +static struct kunit_suite icc_test_suite = { + .name = "interconnect", + .init = icc_test_init, + .exit = icc_test_exit, + .test_cases = icc_test_cases, +}; + +kunit_test_suite(icc_test_suite); + +MODULE_AUTHOR("Kuan-Wei Chiu "); +MODULE_DESCRIPTION("KUnit tests for the Interconnect framework"); +MODULE_LICENSE("GPL"); diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig index 985c849efac3..9fd3f2170443 100644 --- a/drivers/interconnect/mediatek/Kconfig +++ b/drivers/interconnect/mediatek/Kconfig @@ -27,3 +27,10 @@ config INTERCONNECT_MTK_MT8195 help This is a driver for the MediaTek bus interconnect on MT8195-based platforms. + +config INTERCONNECT_MTK_MT8196 + tristate "MediaTek MT8196 interconnect driver" + depends on INTERCONNECT_MTK_DVFSRC_EMI + help + This is a driver for the MediaTek bus interconnect on MT8196-based + platforms. diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile index 8e2283a9a5b5..6bd656668f5d 100644 --- a/drivers/interconnect/mediatek/Makefile +++ b/drivers/interconnect/mediatek/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_INTERCONNECT_MTK_DVFSRC_EMI) += icc-emi.o obj-$(CONFIG_INTERCONNECT_MTK_MT8183) += mt8183.o obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8195.o +obj-$(CONFIG_INTERCONNECT_MTK_MT8195) += mt8196.o diff --git a/drivers/interconnect/mediatek/icc-emi.c b/drivers/interconnect/mediatek/icc-emi.c index 7da740b5fa8d..dfa3a9cd9399 100644 --- a/drivers/interconnect/mediatek/icc-emi.c +++ b/drivers/interconnect/mediatek/icc-emi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -22,7 +23,9 @@ static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, { struct mtk_icc_node *in = node->data; - *agg_avg += avg_bw; + if (check_add_overflow(*agg_avg, avg_bw, agg_avg)) + *agg_avg = U32_MAX; + *agg_peak = max_t(u32, *agg_peak, peak_bw); in->sum_avg = *agg_avg; @@ -40,7 +43,7 @@ static int mtk_emi_icc_set(struct icc_node *src, struct icc_node *dst) if (unlikely(!src->provider)) return -EINVAL; - dev = src->provider->dev; + dev = src->provider->dev->parent; switch (node->ep) { case 0: @@ -97,7 +100,7 @@ int mtk_emi_icc_probe(struct platform_device *pdev) if (!data) return -ENOMEM; - provider->dev = pdev->dev.parent; + provider->dev = dev; provider->set = mtk_emi_icc_set; provider->aggregate = mtk_emi_icc_aggregate; provider->xlate = of_icc_xlate_onecell; diff --git a/drivers/interconnect/mediatek/mt8196.c b/drivers/interconnect/mediatek/mt8196.c new file mode 100644 index 000000000000..e9af32065be1 --- /dev/null +++ b/drivers/interconnect/mediatek/mt8196.c @@ -0,0 +1,383 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Collabora Ltd. + * AngeloGioacchino Del Regno + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "icc-emi.h" + +static struct mtk_icc_node ddr_emi = { + .name = "ddr-emi", + .id = SLAVE_DDR_EMI, + .ep = 1, +}; + +static struct mtk_icc_node mcusys = { + .name = "mcusys", + .id = MASTER_MCUSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mcu_port0 = { + .name = "mcu-port0", + .id = MASTER_MCU_0, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mcu_port1 = { + .name = "mcu-port1", + .id = MASTER_MCU_1, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mcu_port2 = { + .name = "mcu-port2", + .id = MASTER_MCU_2, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mcu_port3 = { + .name = "mcu-port3", + .id = MASTER_MCU_3, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mcu_port4 = { + .name = "mcu-port4", + .id = MASTER_MCU_4, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node gpu = { + .name = "gpu", + .id = MASTER_GPUSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mmsys = { + .name = "mmsys", + .id = MASTER_MMSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mm_vpu = { + .name = "mm-vpu", + .id = MASTER_MM_VPU, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_disp = { + .name = "mm-disp", + .id = MASTER_MM_DISP, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_vdec = { + .name = "mm-vdec", + .id = MASTER_MM_VDEC, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_venc = { + .name = "mm-venc", + .id = MASTER_MM_VENC, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_cam = { + .name = "mm-cam", + .id = MASTER_MM_CAM, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_img = { + .name = "mm-img", + .id = MASTER_MM_IMG, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node mm_mdp = { + .name = "mm-mdp", + .id = MASTER_MM_MDP, + .ep = 0, + .num_links = 1, + .links = { MASTER_MMSYS } +}; + +static struct mtk_icc_node vpusys = { + .name = "vpusys", + .id = MASTER_VPUSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node vpu_port0 = { + .name = "vpu-port0", + .id = MASTER_VPU_0, + .ep = 0, + .num_links = 1, + .links = { MASTER_VPUSYS } +}; + +static struct mtk_icc_node vpu_port1 = { + .name = "vpu-port1", + .id = MASTER_VPU_1, + .ep = 0, + .num_links = 1, + .links = { MASTER_VPUSYS } +}; + +static struct mtk_icc_node mdlasys = { + .name = "mdlasys", + .id = MASTER_MDLASYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node mdla_port0 = { + .name = "mdla-port0", + .id = MASTER_MDLA_0, + .ep = 0, + .num_links = 1, + .links = { MASTER_MDLASYS } +}; + +static struct mtk_icc_node ufs = { + .name = "ufs", + .id = MASTER_UFS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node pcie = { + .name = "pcie", + .id = MASTER_PCIE, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node usb = { + .name = "usb", + .id = MASTER_USB, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node wifi = { + .name = "wifi", + .id = MASTER_WIFI, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node bt = { + .name = "bt", + .id = MASTER_BT, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node netsys = { + .name = "netsys", + .id = MASTER_NETSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node dbgif = { + .name = "dbgif", + .id = MASTER_DBGIF, + .ep = 0, + .num_links = 1, + .links = { SLAVE_DDR_EMI } +}; + +static struct mtk_icc_node hrt_ddr_emi = { + .name = "hrt-ddr-emi", + .id = SLAVE_HRT_DDR_EMI, + .ep = 2, +}; + +static struct mtk_icc_node hrt_mmsys = { + .name = "hrt-mmsys", + .id = MASTER_HRT_MMSYS, + .ep = 0, + .num_links = 1, + .links = { SLAVE_HRT_DDR_EMI } +}; + +static struct mtk_icc_node hrt_mm_disp = { + .name = "hrt-mm-disp", + .id = MASTER_HRT_MM_DISP, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_mm_vdec = { + .name = "hrt-mm-vdec", + .id = MASTER_HRT_MM_VDEC, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_mm_venc = { + .name = "hrt-mm-venc", + .id = MASTER_HRT_MM_VENC, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_mm_cam = { + .name = "hrt-mm-cam", + .id = MASTER_HRT_MM_CAM, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_mm_img = { + .name = "hrt-mm-img", + .id = MASTER_HRT_MM_IMG, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_mm_mdp = { + .name = "hrt-mm-mdp", + .id = MASTER_HRT_MM_MDP, + .ep = 0, + .num_links = 1, + .links = { MASTER_HRT_MMSYS } +}; + +static struct mtk_icc_node hrt_adsp = { + .name = "hrt-adsp", + .id = MASTER_HRT_ADSP, + .ep = 0, + .num_links = 1, + .links = { SLAVE_HRT_DDR_EMI } +}; + +static struct mtk_icc_node hrt_dbgif = { + .name = "hrt-dbgif", + .id = MASTER_HRT_DBGIF, + .ep = 0, + .num_links = 1, + .links = { SLAVE_HRT_DDR_EMI } +}; + +static struct mtk_icc_node *mt8196_emi_icc_nodes[] = { + [SLAVE_DDR_EMI] = &ddr_emi, + [MASTER_MCUSYS] = &mcusys, + [MASTER_MCU_0] = &mcu_port0, + [MASTER_MCU_1] = &mcu_port1, + [MASTER_MCU_2] = &mcu_port2, + [MASTER_MCU_3] = &mcu_port3, + [MASTER_MCU_4] = &mcu_port4, + [MASTER_GPUSYS] = &gpu, + [MASTER_MMSYS] = &mmsys, + [MASTER_MM_VPU] = &mm_vpu, + [MASTER_MM_DISP] = &mm_disp, + [MASTER_MM_VDEC] = &mm_vdec, + [MASTER_MM_VENC] = &mm_venc, + [MASTER_MM_CAM] = &mm_cam, + [MASTER_MM_IMG] = &mm_img, + [MASTER_MM_MDP] = &mm_mdp, + [MASTER_VPUSYS] = &vpusys, + [MASTER_VPU_0] = &vpu_port0, + [MASTER_VPU_1] = &vpu_port1, + [MASTER_MDLASYS] = &mdlasys, + [MASTER_MDLA_0] = &mdla_port0, + [MASTER_UFS] = &ufs, + [MASTER_PCIE] = &pcie, + [MASTER_USB] = &usb, + [MASTER_WIFI] = &wifi, + [MASTER_BT] = &bt, + [MASTER_NETSYS] = &netsys, + [MASTER_DBGIF] = &dbgif, + [SLAVE_HRT_DDR_EMI] = &hrt_ddr_emi, + [MASTER_HRT_MMSYS] = &hrt_mmsys, + [MASTER_HRT_MM_DISP] = &hrt_mm_disp, + [MASTER_HRT_MM_VDEC] = &hrt_mm_vdec, + [MASTER_HRT_MM_VENC] = &hrt_mm_venc, + [MASTER_HRT_MM_CAM] = &hrt_mm_cam, + [MASTER_HRT_MM_IMG] = &hrt_mm_img, + [MASTER_HRT_MM_MDP] = &hrt_mm_mdp, + [MASTER_HRT_ADSP] = &hrt_adsp, + [MASTER_HRT_DBGIF] = &hrt_dbgif +}; + +static struct mtk_icc_desc mt8196_emi_icc = { + .nodes = mt8196_emi_icc_nodes, + .num_nodes = ARRAY_SIZE(mt8196_emi_icc_nodes), +}; + +static const struct of_device_id mtk_mt8196_emi_icc_of_match[] = { + { .compatible = "mediatek,mt8196-emi", .data = &mt8196_emi_icc }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, mtk_mt8196_emi_icc_of_match); + +static struct platform_driver mtk_emi_icc_mt8196_driver = { + .driver = { + .name = "emi-icc-mt8196", + .of_match_table = mtk_mt8196_emi_icc_of_match, + .sync_state = icc_sync_state, + }, + .probe = mtk_emi_icc_probe, + .remove = mtk_emi_icc_remove, + +}; +module_platform_driver(mtk_emi_icc_mt8196_driver); + +MODULE_AUTHOR("AngeloGioacchino Del Regno "); +MODULE_DESCRIPTION("MediaTek MT8196 EMI ICC driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/interconnect/qcom/icc-common.c b/drivers/interconnect/qcom/icc-common.c index 9b8a9c69e0cb..a25564fe1ebd 100644 --- a/drivers/interconnect/qcom/icc-common.c +++ b/drivers/interconnect/qcom/icc-common.c @@ -19,7 +19,7 @@ struct icc_node_data *qcom_icc_xlate_extended(const struct of_phandle_args *spec if (IS_ERR(node)) return ERR_CAST(node); - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/interconnect/qcom/msm8974.c b/drivers/interconnect/qcom/msm8974.c index 469fc48ebfe9..3239edc37f02 100644 --- a/drivers/interconnect/qcom/msm8974.c +++ b/drivers/interconnect/qcom/msm8974.c @@ -173,9 +173,6 @@ enum { MSM8974_SNOC_SLV_QDSS_STM, }; -#define RPM_BUS_MASTER_REQ 0x73616d62 -#define RPM_BUS_SLAVE_REQ 0x766c7362 - #define to_msm8974_icc_provider(_provider) \ container_of(_provider, struct msm8974_icc_provider, provider) diff --git a/drivers/interconnect/qcom/qcs8300.c b/drivers/interconnect/qcom/qcs8300.c index 70a377bbcf29..bc403a9bf68c 100644 --- a/drivers/interconnect/qcom/qcs8300.c +++ b/drivers/interconnect/qcom/qcs8300.c @@ -629,7 +629,7 @@ static struct qcom_icc_node qxm_nsp = { .name = "qxm_nsp", .channels = 2, .buswidth = 32, - .num_links = 1, + .num_links = 2, .link_nodes = { &qns_hcp, &qns_nsp_gemnoc }, }; diff --git a/drivers/interconnect/qcom/smd-rpm.c b/drivers/interconnect/qcom/smd-rpm.c index 8316c87a2c60..dbc7ae50b02b 100644 --- a/drivers/interconnect/qcom/smd-rpm.c +++ b/drivers/interconnect/qcom/smd-rpm.c @@ -14,7 +14,6 @@ #include "icc-rpm.h" #define RPM_KEY_BW 0x00007762 -#define QCOM_RPM_SMD_KEY_RATE 0x007a484b static struct qcom_smd_rpm *icc_smd_rpm; diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 5a797c1b31e2..f3fd7f39efb4 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -659,9 +659,8 @@ static inline void free_dev_table(struct amd_iommu_pci_seg *pci_seg) /* Allocate per PCI segment IOMMU rlookup table. */ static inline int __init alloc_rlookup_table(struct amd_iommu_pci_seg *pci_seg) { - pci_seg->rlookup_table = kvcalloc(pci_seg->last_bdf + 1, - sizeof(*pci_seg->rlookup_table), - GFP_KERNEL); + pci_seg->rlookup_table = kvzalloc_objs(*pci_seg->rlookup_table, + pci_seg->last_bdf + 1); if (pci_seg->rlookup_table == NULL) return -ENOMEM; @@ -676,9 +675,8 @@ static inline void free_rlookup_table(struct amd_iommu_pci_seg *pci_seg) static inline int __init alloc_irq_lookup_table(struct amd_iommu_pci_seg *pci_seg) { - pci_seg->irq_lookup_table = kvcalloc(pci_seg->last_bdf + 1, - sizeof(*pci_seg->irq_lookup_table), - GFP_KERNEL); + pci_seg->irq_lookup_table = kvzalloc_objs(*pci_seg->irq_lookup_table, + pci_seg->last_bdf + 1); if (pci_seg->irq_lookup_table == NULL) return -ENOMEM; @@ -695,9 +693,8 @@ static int __init alloc_alias_table(struct amd_iommu_pci_seg *pci_seg) { int i; - pci_seg->alias_table = kvmalloc_array(pci_seg->last_bdf + 1, - sizeof(*pci_seg->alias_table), - GFP_KERNEL); + pci_seg->alias_table = kvmalloc_objs(*pci_seg->alias_table, + pci_seg->last_bdf + 1); if (!pci_seg->alias_table) return -ENOMEM; @@ -1285,7 +1282,7 @@ set_dev_entry_from_acpi_range(struct amd_iommu *iommu, u16 first, u16 last, if (search_ivhd_dte_flags(iommu->pci_seg->id, first, last)) return; - d = kzalloc(sizeof(struct ivhd_dte_flags), GFP_KERNEL); + d = kzalloc_obj(struct ivhd_dte_flags); if (!d) return; @@ -1357,7 +1354,7 @@ int __init add_special_device(u8 type, u8 id, u32 *devid, bool cmd_line) return 0; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1388,7 +1385,7 @@ static int __init add_acpi_hid_device(u8 *hid, u8 *uid, u32 *devid, return 0; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1721,7 +1718,7 @@ static struct amd_iommu_pci_seg *__init alloc_pci_segment(u16 id, if (last_bdf < 0) return NULL; - pci_seg = kzalloc(sizeof(struct amd_iommu_pci_seg), GFP_KERNEL); + pci_seg = kzalloc_obj(struct amd_iommu_pci_seg); if (pci_seg == NULL) return NULL; @@ -2041,7 +2038,7 @@ static int __init init_iommu_all(struct acpi_table_header *table) DUMP_printk(" mmio-addr: %016llx\n", h->mmio_phys); - iommu = kzalloc(sizeof(struct amd_iommu), GFP_KERNEL); + iommu = kzalloc_obj(struct amd_iommu); if (iommu == NULL) return -ENOMEM; @@ -2642,7 +2639,7 @@ static int __init init_unity_map_range(struct ivmd_header *m, if (pci_seg == NULL) return -ENOMEM; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (e == NULL) return -ENOMEM; diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index ab61ef61e670..81c4d7733872 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -372,7 +372,7 @@ static struct iommu_dev_data *alloc_dev_data(struct amd_iommu *iommu, u16 devid) struct iommu_dev_data *dev_data; struct amd_iommu_pci_seg *pci_seg = iommu->pci_seg; - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kzalloc_obj(*dev_data); if (!dev_data) return NULL; @@ -2277,7 +2277,7 @@ static int pdom_attach_iommu(struct amd_iommu *iommu, goto out_unlock; } - pdom_iommu_info = kzalloc(sizeof(*pdom_iommu_info), GFP_ATOMIC); + pdom_iommu_info = kzalloc_obj(*pdom_iommu_info, GFP_ATOMIC); if (!pdom_iommu_info) { ret = -ENOMEM; goto out_unlock; @@ -2547,7 +2547,7 @@ struct protection_domain *protection_domain_alloc(void) struct protection_domain *domain; int domid; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return NULL; @@ -3248,7 +3248,7 @@ static struct irq_remap_table *__alloc_irq_table(int nid, size_t size) { struct irq_remap_table *table; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return NULL; @@ -3799,15 +3799,14 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq, } ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto out_free_data; if (!AMD_IOMMU_GUEST_IR_GA(amd_iommu_guest_ir)) - data->entry = kzalloc(sizeof(union irte), GFP_KERNEL); + data->entry = kzalloc_obj(union irte); else - data->entry = kzalloc(sizeof(struct irte_ga), - GFP_KERNEL); + data->entry = kzalloc_obj(struct irte_ga); if (!data->entry) { kfree(data); goto out_free_data; diff --git a/drivers/iommu/amd/iommufd.c b/drivers/iommu/amd/iommufd.c index 96ec6a4a760d..52300b867c1f 100644 --- a/drivers/iommu/amd/iommufd.c +++ b/drivers/iommu/amd/iommufd.c @@ -19,7 +19,7 @@ void *amd_iommufd_hw_info(struct device *dev, u32 *length, enum iommu_hw_info_ty *type != IOMMU_HW_INFO_TYPE_AMD) return ERR_PTR(-EOPNOTSUPP); - hwinfo = kzalloc(sizeof(*hwinfo), GFP_KERNEL); + hwinfo = kzalloc_obj(*hwinfo); if (!hwinfo) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/amd/nested.c b/drivers/iommu/amd/nested.c index 66cc36133c8b..5b902598e68a 100644 --- a/drivers/iommu/amd/nested.c +++ b/drivers/iommu/amd/nested.c @@ -68,7 +68,7 @@ static void *gdom_info_load_or_alloc_locked(struct xarray *xa, unsigned long ind return elm; xa_unlock(xa); - elm = kzalloc(sizeof(struct guest_domain_mapping_info), GFP_KERNEL); + elm = kzalloc_obj(struct guest_domain_mapping_info); xa_lock(xa); if (!elm) return ERR_PTR(-ENOMEM); @@ -102,7 +102,7 @@ amd_iommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags, if (user_data->type != IOMMU_HWPT_DATA_AMD_GUEST) return ERR_PTR(-EOPNOTSUPP); - ndom = kzalloc(sizeof(*ndom), GFP_KERNEL); + ndom = kzalloc_obj(*ndom); if (!ndom) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/amd/pasid.c b/drivers/iommu/amd/pasid.c index 77c8e9a91cbc..67eace9809f1 100644 --- a/drivers/iommu/amd/pasid.c +++ b/drivers/iommu/amd/pasid.c @@ -121,7 +121,7 @@ int iommu_sva_set_dev_pasid(struct iommu_domain *domain, return ret; /* Add PASID to protection domain pasid list */ - pdom_dev_data = kzalloc(sizeof(*pdom_dev_data), GFP_KERNEL); + pdom_dev_data = kzalloc_obj(*pdom_dev_data); if (pdom_dev_data == NULL) return ret; diff --git a/drivers/iommu/apple-dart.c b/drivers/iommu/apple-dart.c index 83a5aabcd15d..17bdadb6b504 100644 --- a/drivers/iommu/apple-dart.c +++ b/drivers/iommu/apple-dart.c @@ -768,7 +768,7 @@ static struct iommu_domain *apple_dart_domain_alloc_paging(struct device *dev) { struct apple_dart_domain *dart_domain; - dart_domain = kzalloc(sizeof(*dart_domain), GFP_KERNEL); + dart_domain = kzalloc_obj(*dart_domain); if (!dart_domain) return NULL; @@ -812,7 +812,7 @@ static int apple_dart_of_xlate(struct device *dev, sid = args->args[0]; if (!cfg) { - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; /* Will be ANDed with DART capabilities */ diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c index 823461a26659..ddae0b07c76b 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c @@ -23,7 +23,7 @@ void *arm_smmu_hw_info(struct device *dev, u32 *length, return impl_ops->hw_info(master->smmu, length, type); } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); @@ -121,7 +121,7 @@ int arm_smmu_attach_prepare_vmaster(struct arm_smmu_attach_state *state, return ret; } - vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); + vmaster = kzalloc_obj(*vmaster); if (!vmaster) return -ENOMEM; vmaster->vsmmu = nested_domain->vsmmu; @@ -261,7 +261,7 @@ arm_vsmmu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags, if (ret) return ERR_PTR(ret); - nested_domain = kzalloc(sizeof(*nested_domain), GFP_KERNEL_ACCOUNT); + nested_domain = kzalloc_obj(*nested_domain, GFP_KERNEL_ACCOUNT); if (!nested_domain) return ERR_PTR(-ENOMEM); @@ -361,7 +361,7 @@ int arm_vsmmu_cache_invalidate(struct iommufd_viommu *viommu, struct arm_vsmmu_invalidation_cmd *end; int ret; - cmds = kcalloc(array->entry_num, sizeof(*cmds), GFP_KERNEL); + cmds = kzalloc_objs(*cmds, array->entry_num); if (!cmds) return -ENOMEM; cur = cmds; diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index b397d1714d97..4d00d796f078 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1514,9 +1514,8 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) cd_table->l2.num_l1_ents = DIV_ROUND_UP(max_contexts, CTXDESC_L2_ENTRIES); - cd_table->l2.l2ptrs = kcalloc(cd_table->l2.num_l1_ents, - sizeof(*cd_table->l2.l2ptrs), - GFP_KERNEL); + cd_table->l2.l2ptrs = kzalloc_objs(*cd_table->l2.l2ptrs, + cd_table->l2.num_l1_ents); if (!cd_table->l2.l2ptrs) return -ENOMEM; @@ -2524,7 +2523,7 @@ struct arm_smmu_domain *arm_smmu_domain_alloc(void) { struct arm_smmu_domain *smmu_domain; - smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL); + smmu_domain = kzalloc_obj(*smmu_domain); if (!smmu_domain) return ERR_PTR(-ENOMEM); @@ -2965,7 +2964,7 @@ int arm_smmu_attach_prepare(struct arm_smmu_attach_state *state, return ret; } - master_domain = kzalloc(sizeof(*master_domain), GFP_KERNEL); + master_domain = kzalloc_obj(*master_domain); if (!master_domain) { ret = -ENOMEM; goto err_free_vmaster; @@ -3517,8 +3516,7 @@ static int arm_smmu_insert_master(struct arm_smmu_device *smmu, int ret = 0; struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev); - master->streams = kcalloc(fwspec->num_ids, sizeof(*master->streams), - GFP_KERNEL); + master->streams = kzalloc_objs(*master->streams, fwspec->num_ids); if (!master->streams) return -ENOMEM; master->num_streams = fwspec->num_ids; @@ -3597,7 +3595,7 @@ static struct iommu_device *arm_smmu_probe_device(struct device *dev) if (!smmu) return ERR_PTR(-ENODEV); - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c index 156b87fe456d..6fe5563eaf9e 100644 --- a/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c +++ b/drivers/iommu/arm/arm-smmu-v3/tegra241-cmdqv.c @@ -693,7 +693,7 @@ tegra241_vintf_alloc_lvcmdq(struct tegra241_vintf *vintf, u16 lidx) char header[64]; int ret; - vcmdq = kzalloc(sizeof(*vcmdq), GFP_KERNEL); + vcmdq = kzalloc_obj(*vcmdq); if (!vcmdq) return ERR_PTR(-ENOMEM); @@ -742,8 +742,8 @@ static int tegra241_cmdqv_init_vintf(struct tegra241_cmdqv *cmdqv, u16 max_idx, vintf->cmdqv = cmdqv; vintf->base = cmdqv->base + TEGRA241_VINTF(idx); - vintf->lvcmdqs = kcalloc(cmdqv->num_lvcmdqs_per_vintf, - sizeof(*vintf->lvcmdqs), GFP_KERNEL); + vintf->lvcmdqs = kzalloc_objs(*vintf->lvcmdqs, + cmdqv->num_lvcmdqs_per_vintf); if (!vintf->lvcmdqs) { ida_free(&cmdqv->vintf_ids, idx); return -ENOMEM; @@ -818,7 +818,7 @@ static void *tegra241_cmdqv_hw_info(struct arm_smmu_device *smmu, u32 *length, if (*type != IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV) return ERR_PTR(-EOPNOTSUPP); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); @@ -860,7 +860,7 @@ static int tegra241_cmdqv_init_structures(struct arm_smmu_device *smmu) int lidx; int ret; - vintf = kzalloc(sizeof(*vintf), GFP_KERNEL); + vintf = kzalloc_obj(*vintf); if (!vintf) return -ENOMEM; @@ -947,7 +947,7 @@ __tegra241_cmdqv_probe(struct arm_smmu_device *smmu, struct resource *res, 1 << FIELD_GET(CMDQV_NUM_SID_PER_VM_LOG2, regval); cmdqv->vintfs = - kcalloc(cmdqv->num_vintfs, sizeof(*cmdqv->vintfs), GFP_KERNEL); + kzalloc_objs(*cmdqv->vintfs, cmdqv->num_vintfs); if (!cmdqv->vintfs) goto free_irq; diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c index 1e218fbea35a..0bd21d206eb3 100644 --- a/drivers/iommu/arm/arm-smmu/arm-smmu.c +++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c @@ -927,7 +927,7 @@ static struct iommu_domain *arm_smmu_domain_alloc_paging(struct device *dev) * We can't really do anything meaningful until we've added a * master. */ - smmu_domain = kzalloc(sizeof(*smmu_domain), GFP_KERNEL); + smmu_domain = kzalloc_obj(*smmu_domain); if (!smmu_domain) return NULL; diff --git a/drivers/iommu/arm/arm-smmu/qcom_iommu.c b/drivers/iommu/arm/arm-smmu/qcom_iommu.c index c98bed38c58a..a1e8cf29f594 100644 --- a/drivers/iommu/arm/arm-smmu/qcom_iommu.c +++ b/drivers/iommu/arm/arm-smmu/qcom_iommu.c @@ -329,7 +329,7 @@ static struct iommu_domain *qcom_iommu_domain_alloc_paging(struct device *dev) * We can't really do anything meaningful until we've added a * master. */ - qcom_domain = kzalloc(sizeof(*qcom_domain), GFP_KERNEL); + qcom_domain = kzalloc_obj(*qcom_domain); if (!qcom_domain) return NULL; diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index aeaf8fad985c..5dac64be61bb 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -372,7 +372,7 @@ int iommu_get_dma_cookie(struct iommu_domain *domain) if (domain->cookie_type != IOMMU_COOKIE_NONE) return -EEXIST; - cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); + cookie = kzalloc_obj(*cookie); if (!cookie) return -ENOMEM; @@ -404,7 +404,7 @@ int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base) if (domain->cookie_type != IOMMU_COOKIE_NONE) return -EEXIST; - cookie = kzalloc(sizeof(*cookie), GFP_KERNEL); + cookie = kzalloc_obj(*cookie); if (!cookie) return -ENOMEM; @@ -480,7 +480,7 @@ static int cookie_init_hw_msi_region(struct iommu_dma_cookie *cookie, num_pages = iova_align(iovad, end - start) >> iova_shift(iovad); for (i = 0; i < num_pages; i++) { - msi_page = kmalloc(sizeof(*msi_page), GFP_KERNEL); + msi_page = kmalloc_obj(*msi_page); if (!msi_page) return -ENOMEM; @@ -880,7 +880,7 @@ static struct page **__iommu_dma_alloc_pages(struct device *dev, if (!order_mask) return NULL; - pages = kvcalloc(count, sizeof(*pages), GFP_KERNEL); + pages = kvzalloc_objs(*pages, count); if (!pages) return NULL; @@ -1045,7 +1045,7 @@ struct sg_table *iommu_dma_alloc_noncontiguous(struct device *dev, size_t size, { struct dma_sgt_handle *sh; - sh = kmalloc(sizeof(*sh), gfp); + sh = kmalloc_obj(*sh, gfp); if (!sh) return NULL; @@ -2157,7 +2157,7 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, if (msi_page->phys == msi_addr) return msi_page; - msi_page = kzalloc(sizeof(*msi_page), GFP_KERNEL); + msi_page = kzalloc_obj(*msi_page); if (!msi_page) return NULL; diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index b512c6b939ac..874d05f4b396 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c @@ -899,7 +899,7 @@ static struct iommu_domain *exynos_iommu_domain_alloc_paging(struct device *dev) /* Check if correct PTE offsets are initialized */ BUG_ON(PG_ENT_SHIFT < 0 || !dma_dev); - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return NULL; @@ -1451,7 +1451,7 @@ static int exynos_iommu_of_xlate(struct device *dev, return -ENODEV; if (!owner) { - owner = kzalloc(sizeof(*owner), GFP_KERNEL); + owner = kzalloc_obj(*owner); if (!owner) return -ENOMEM; diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c index f37d3b044131..25aa477a95a9 100644 --- a/drivers/iommu/fsl_pamu.c +++ b/drivers/iommu/fsl_pamu.c @@ -785,7 +785,7 @@ static int fsl_pamu_probe(struct platform_device *pdev) goto error; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { ret = -ENOMEM; goto error; diff --git a/drivers/iommu/hyperv-iommu.c b/drivers/iommu/hyperv-iommu.c index 0961ac805944..479103261ae6 100644 --- a/drivers/iommu/hyperv-iommu.c +++ b/drivers/iommu/hyperv-iommu.c @@ -276,7 +276,7 @@ static int hyperv_root_irq_remapping_alloc(struct irq_domain *domain, if (ret < 0) return ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { irq_domain_free_irqs_common(domain, virq, nr_irqs); return -ENOMEM; diff --git a/drivers/iommu/intel/cache.c b/drivers/iommu/intel/cache.c index 385ae5cfb30d..249ab5886c73 100644 --- a/drivers/iommu/intel/cache.c +++ b/drivers/iommu/intel/cache.c @@ -49,7 +49,7 @@ int cache_tag_assign(struct dmar_domain *domain, u16 did, struct device *dev, struct list_head *prev; unsigned long flags; - tag = kzalloc(sizeof(*tag), GFP_KERNEL); + tag = kzalloc_obj(*tag); if (!tag) return -ENOMEM; @@ -123,7 +123,7 @@ static int domain_qi_batch_alloc(struct dmar_domain *domain) if (domain->qi_batch) goto out_unlock; - domain->qi_batch = kzalloc(sizeof(*domain->qi_batch), GFP_ATOMIC); + domain->qi_batch = kzalloc_obj(*domain->qi_batch, GFP_ATOMIC); if (!domain->qi_batch) ret = -ENOMEM; out_unlock: diff --git a/drivers/iommu/intel/dmar.c b/drivers/iommu/intel/dmar.c index ec975c73cfe6..d68c06025cac 100644 --- a/drivers/iommu/intel/dmar.c +++ b/drivers/iommu/intel/dmar.c @@ -99,7 +99,7 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) if (*cnt == 0) return NULL; - return kcalloc(*cnt, sizeof(struct dmar_dev_scope), GFP_KERNEL); + return kzalloc_objs(struct dmar_dev_scope, *cnt); } void dmar_free_dev_scope(struct dmar_dev_scope **devices, int *cnt) @@ -1046,7 +1046,7 @@ static int alloc_iommu(struct dmar_drhd_unit *drhd) return -EINVAL; } - iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + iommu = kzalloc_obj(*iommu); if (!iommu) return -ENOMEM; @@ -1692,7 +1692,7 @@ int dmar_enable_qi(struct intel_iommu *iommu) if (iommu->qi) return 0; - iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC); + iommu->qi = kmalloc_obj(*qi, GFP_ATOMIC); if (!iommu->qi) return -ENOMEM; @@ -1713,7 +1713,7 @@ int dmar_enable_qi(struct intel_iommu *iommu) qi->desc = desc; - qi->desc_status = kcalloc(QI_LENGTH, sizeof(int), GFP_ATOMIC); + qi->desc_status = kzalloc_objs(int, QI_LENGTH, GFP_ATOMIC); if (!qi->desc_status) { iommu_free_pages(qi->desc); kfree(qi); diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c index 705828b06e32..ef7613b177b9 100644 --- a/drivers/iommu/intel/iommu.c +++ b/drivers/iommu/intel/iommu.c @@ -1030,7 +1030,7 @@ int domain_attach_iommu(struct dmar_domain *domain, struct intel_iommu *iommu) if (domain->domain.type == IOMMU_DOMAIN_SVA) return 0; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -1926,7 +1926,7 @@ int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg) add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); } - rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL); + rmrru = kzalloc_obj(*rmrru); if (!rmrru) goto out; @@ -2779,7 +2779,7 @@ static struct dmar_domain *paging_domain_alloc(void) { struct dmar_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return ERR_PTR(-ENOMEM); @@ -3237,7 +3237,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev) if (!iommu || !iommu->iommu.ops) return ERR_PTR(-ENODEV); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); @@ -3576,7 +3576,7 @@ domain_add_dev_pasid(struct iommu_domain *domain, unsigned long flags; int ret; - dev_pasid = kzalloc(sizeof(*dev_pasid), GFP_KERNEL); + dev_pasid = kzalloc_obj(*dev_pasid); if (!dev_pasid) return ERR_PTR(-ENOMEM); @@ -3672,7 +3672,7 @@ static void *intel_iommu_hw_info(struct device *dev, u32 *length, *type != IOMMU_HW_INFO_TYPE_INTEL_VTD) return ERR_PTR(-EOPNOTSUPP); - vtd = kzalloc(sizeof(*vtd), GFP_KERNEL); + vtd = kzalloc_obj(*vtd); if (!vtd) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/intel/irq_remapping.c b/drivers/iommu/intel/irq_remapping.c index ecb591e98565..1cd2101610df 100644 --- a/drivers/iommu/intel/irq_remapping.c +++ b/drivers/iommu/intel/irq_remapping.c @@ -533,7 +533,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu) if (iommu->ir_table) return 0; - ir_table = kzalloc(sizeof(struct ir_table), GFP_KERNEL); + ir_table = kzalloc_obj(struct ir_table); if (!ir_table) return -ENOMEM; @@ -1426,7 +1426,7 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain, return ret; ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto out_free_parent; @@ -1448,7 +1448,7 @@ static int intel_irq_remapping_alloc(struct irq_domain *domain, } if (i > 0) { - ird = kzalloc(sizeof(*ird), GFP_KERNEL); + ird = kzalloc_obj(*ird); if (!ird) goto out_free_data; /* Initialize the common data */ diff --git a/drivers/iommu/intel/nested.c b/drivers/iommu/intel/nested.c index e9a440e9c960..2b979bec56ce 100644 --- a/drivers/iommu/intel/nested.c +++ b/drivers/iommu/intel/nested.c @@ -218,7 +218,7 @@ intel_iommu_domain_alloc_nested(struct device *dev, struct iommu_domain *parent, if (ret) return ERR_PTR(ret); - domain = kzalloc(sizeof(*domain), GFP_KERNEL_ACCOUNT); + domain = kzalloc_obj(*domain, GFP_KERNEL_ACCOUNT); if (!domain) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c index b63a71904cfb..9d30015b8940 100644 --- a/drivers/iommu/intel/pasid.c +++ b/drivers/iommu/intel/pasid.c @@ -50,7 +50,7 @@ int intel_pasid_alloc_table(struct device *dev) if (WARN_ON(info->pasid_table)) return -EEXIST; - pasid_table = kzalloc(sizeof(*pasid_table), GFP_KERNEL); + pasid_table = kzalloc_obj(*pasid_table); if (!pasid_table) return -ENOMEM; diff --git a/drivers/iommu/intel/perf.c b/drivers/iommu/intel/perf.c index dceeadc3ee7c..02168f2f20a4 100644 --- a/drivers/iommu/intel/perf.c +++ b/drivers/iommu/intel/perf.c @@ -33,8 +33,8 @@ int dmar_latency_enable(struct intel_iommu *iommu, enum latency_type type) spin_lock_irqsave(&latency_lock, flags); if (!iommu->perf_statistic) { - iommu->perf_statistic = kcalloc(DMAR_LATENCY_NUM, sizeof(*lstat), - GFP_ATOMIC); + iommu->perf_statistic = kzalloc_objs(*lstat, DMAR_LATENCY_NUM, + GFP_ATOMIC); if (!iommu->perf_statistic) { ret = -ENOMEM; goto unlock_out; diff --git a/drivers/iommu/intel/perfmon.c b/drivers/iommu/intel/perfmon.c index 75f493bcb353..fec51b6036b6 100644 --- a/drivers/iommu/intel/perfmon.c +++ b/drivers/iommu/intel/perfmon.c @@ -591,7 +591,7 @@ int alloc_iommu_pmu(struct intel_iommu *iommu) if (!ecmd_has_pmu_essential(iommu)) return -ENODEV; - iommu_pmu = kzalloc(sizeof(*iommu_pmu), GFP_KERNEL); + iommu_pmu = kzalloc_obj(*iommu_pmu); if (!iommu_pmu) return -ENOMEM; diff --git a/drivers/iommu/intel/svm.c b/drivers/iommu/intel/svm.c index 71de7947971f..fea10acd4f02 100644 --- a/drivers/iommu/intel/svm.c +++ b/drivers/iommu/intel/svm.c @@ -210,7 +210,7 @@ struct iommu_domain *intel_svm_domain_alloc(struct device *dev, if (ret) return ERR_PTR(ret); - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/io-pgfault.c b/drivers/iommu/io-pgfault.c index 8b5926c1452e..cca52a34d0ed 100644 --- a/drivers/iommu/io-pgfault.c +++ b/drivers/iommu/io-pgfault.c @@ -65,7 +65,7 @@ static int report_partial_fault(struct iommu_fault_param *fault_param, { struct iopf_fault *iopf; - iopf = kzalloc(sizeof(*iopf), GFP_KERNEL); + iopf = kzalloc_obj(*iopf); if (!iopf) return -ENOMEM; @@ -85,7 +85,7 @@ static struct iopf_group *iopf_group_alloc(struct iommu_fault_param *iopf_param, struct iopf_fault *iopf, *next; struct iopf_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) { /* * We always need to construct the group as we need it to abort @@ -400,7 +400,7 @@ int iopf_queue_add_device(struct iopf_queue *queue, struct device *dev) goto done_unlock; } - fault_param = kzalloc(sizeof(*fault_param), GFP_KERNEL); + fault_param = kzalloc_obj(*fault_param); if (!fault_param) { ret = -ENOMEM; goto done_unlock; @@ -503,7 +503,7 @@ struct iopf_queue *iopf_queue_alloc(const char *name) { struct iopf_queue *queue; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return NULL; diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c index 523355e91a2c..40e33257d3c2 100644 --- a/drivers/iommu/io-pgtable-arm-v7s.c +++ b/drivers/iommu/io-pgtable-arm-v7s.c @@ -692,7 +692,7 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg, !arm_v7s_is_mtk_enabled(cfg)) return NULL; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return NULL; diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c index 05d63fe92e43..0208e5897c29 100644 --- a/drivers/iommu/io-pgtable-arm.c +++ b/drivers/iommu/io-pgtable-arm.c @@ -930,7 +930,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg) if (cfg->oas > ARM_LPAE_MAX_ADDR_BITS) return NULL; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return NULL; diff --git a/drivers/iommu/io-pgtable-dart.c b/drivers/iommu/io-pgtable-dart.c index 54d287cc0dd1..cbc5d6aa2daa 100644 --- a/drivers/iommu/io-pgtable-dart.c +++ b/drivers/iommu/io-pgtable-dart.c @@ -388,7 +388,7 @@ dart_alloc_pgtable(struct io_pgtable_cfg *cfg) if (tbl_bits > max_tbl_bits) return NULL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c index e1e63c2be82b..07d64908a05f 100644 --- a/drivers/iommu/iommu-sva.c +++ b/drivers/iommu/iommu-sva.c @@ -35,7 +35,7 @@ static struct iommu_mm_data *iommu_alloc_mm_data(struct mm_struct *mm, struct de return iommu_mm; } - iommu_mm = kzalloc(sizeof(struct iommu_mm_data), GFP_KERNEL); + iommu_mm = kzalloc_obj(struct iommu_mm_data); if (!iommu_mm) return ERR_PTR(-ENOMEM); @@ -108,7 +108,7 @@ struct iommu_sva *iommu_sva_bind_device(struct device *dev, struct mm_struct *mm goto out_unlock; } - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/iommu/iommu-sysfs.c b/drivers/iommu/iommu-sysfs.c index 170022c09536..937d1c749843 100644 --- a/drivers/iommu/iommu-sysfs.c +++ b/drivers/iommu/iommu-sysfs.c @@ -59,7 +59,7 @@ int iommu_device_sysfs_add(struct iommu_device *iommu, va_list vargs; int ret; - iommu->dev = kzalloc(sizeof(*iommu->dev), GFP_KERNEL); + iommu->dev = kzalloc_obj(*iommu->dev); if (!iommu->dev) return -ENOMEM; diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 4926a43118e6..35db51780954 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -233,7 +233,7 @@ static int __init iommu_subsys_init(void) (iommu_cmd_line & IOMMU_CMD_LINE_STRICT) ? " (set via kernel command line)" : ""); - nb = kcalloc(ARRAY_SIZE(iommu_buses), sizeof(*nb), GFP_KERNEL); + nb = kzalloc_objs(*nb, ARRAY_SIZE(iommu_buses)); if (!nb) return -ENOMEM; @@ -383,7 +383,7 @@ static struct dev_iommu *dev_iommu_get(struct device *dev) if (param) return param; - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) return NULL; @@ -1053,7 +1053,7 @@ struct iommu_group *iommu_group_alloc(void) struct iommu_group *group; int ret; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return ERR_PTR(-ENOMEM); @@ -1244,7 +1244,7 @@ static struct group_device *iommu_group_alloc_device(struct iommu_group *group, int ret, i = 0; struct group_device *device; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return ERR_PTR(-ENOMEM); @@ -2939,7 +2939,7 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start, { struct iommu_resv_region *region; - region = kzalloc(sizeof(*region), gfp); + region = kzalloc_obj(*region, gfp); if (!region) return NULL; @@ -3010,7 +3010,7 @@ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode) return -ENOMEM; /* Preallocate for the overwhelmingly common case of 1 ID */ - fwspec = kzalloc(struct_size(fwspec, ids, 1), GFP_KERNEL); + fwspec = kzalloc_flex(*fwspec, ids, 1); if (!fwspec) return -ENOMEM; diff --git a/drivers/iommu/iommufd/device.c b/drivers/iommu/iommufd/device.c index 4c842368289f..344d620cdecc 100644 --- a/drivers/iommu/iommufd/device.c +++ b/drivers/iommu/iommufd/device.c @@ -87,7 +87,7 @@ static struct iommufd_group *iommufd_get_group(struct iommufd_ctx *ictx, } xa_unlock(&ictx->groups); - new_igroup = kzalloc(sizeof(*new_igroup), GFP_KERNEL); + new_igroup = kzalloc_obj(*new_igroup); if (!new_igroup) { iommu_group_put(group); return ERR_PTR(-ENOMEM); @@ -508,7 +508,7 @@ static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt, if (rc) return rc; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; @@ -575,7 +575,7 @@ static int iommufd_hwpt_replace_device(struct iommufd_device *idev, old_handle = iommufd_device_get_attach_handle(idev, pasid); - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; @@ -619,7 +619,7 @@ int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt, } if (!attach) { - attach = kzalloc(sizeof(*attach), GFP_KERNEL); + attach = kzalloc_obj(*attach); if (!attach) { rc = -ENOMEM; goto err_release_pasid; diff --git a/drivers/iommu/iommufd/driver.c b/drivers/iommu/iommufd/driver.c index 21d4a35538f6..61e6b02601d1 100644 --- a/drivers/iommu/iommufd/driver.c +++ b/drivers/iommu/iommufd/driver.c @@ -155,7 +155,7 @@ int iommufd_viommu_report_event(struct iommufd_viommu *viommu, goto out_set_header; } - vevent = kzalloc(struct_size(vevent, event_data, data_len), GFP_ATOMIC); + vevent = kzalloc_flex(*vevent, event_data, data_len, GFP_ATOMIC); if (!vevent) { rc = -ENOMEM; vevent = &veventq->lost_events_header; @@ -202,7 +202,7 @@ iommufd_sw_msi_get_map(struct iommufd_ctx *ictx, phys_addr_t msi_addr, BITS_PER_BYTE * sizeof_field(struct iommufd_sw_msi_maps, bitmap)) return ERR_PTR(-EOVERFLOW); - cur = kzalloc(sizeof(*cur), GFP_KERNEL); + cur = kzalloc_obj(*cur); if (!cur) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/iommufd/eventq.c b/drivers/iommu/iommufd/eventq.c index e23d9ee4fe38..f1e686b3a265 100644 --- a/drivers/iommu/iommufd/eventq.c +++ b/drivers/iommu/iommufd/eventq.c @@ -262,7 +262,7 @@ iommufd_veventq_deliver_fetch(struct iommufd_veventq *veventq) next = list_first_entry(list, struct iommufd_vevent, node); /* Make a copy of the lost_events_header for copy_to_user */ if (next == &veventq->lost_events_header) { - vevent = kzalloc(sizeof(*vevent), GFP_ATOMIC); + vevent = kzalloc_obj(*vevent, GFP_ATOMIC); if (!vevent) goto out_unlock; } diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c index 436992331111..ee003bb2f647 100644 --- a/drivers/iommu/iommufd/io_pagetable.c +++ b/drivers/iommu/iommufd/io_pagetable.c @@ -245,7 +245,7 @@ static struct iopt_area *iopt_area_alloc(void) { struct iopt_area *area; - area = kzalloc(sizeof(*area), GFP_KERNEL_ACCOUNT); + area = kzalloc_obj(*area, GFP_KERNEL_ACCOUNT); if (!area) return NULL; RB_CLEAR_NODE(&area->node.rb); @@ -715,7 +715,7 @@ int iopt_get_pages(struct io_pagetable *iopt, unsigned long iova, struct iopt_pages_list *elm; unsigned long last = min(last_iova, iopt_area_last_iova(area)); - elm = kzalloc(sizeof(*elm), GFP_KERNEL_ACCOUNT); + elm = kzalloc_obj(*elm, GFP_KERNEL_ACCOUNT); if (!elm) { rc = -ENOMEM; goto err_free; @@ -888,7 +888,7 @@ int iopt_reserve_iova(struct io_pagetable *iopt, unsigned long start, iopt_allowed_iter_first(iopt, start, last)) return -EADDRINUSE; - reserved = kzalloc(sizeof(*reserved), GFP_KERNEL_ACCOUNT); + reserved = kzalloc_obj(*reserved, GFP_KERNEL_ACCOUNT); if (!reserved) return -ENOMEM; reserved->node.start = start; diff --git a/drivers/iommu/iommufd/ioas.c b/drivers/iommu/iommufd/ioas.c index f4721afedadc..fed06c2b728e 100644 --- a/drivers/iommu/iommufd/ioas.c +++ b/drivers/iommu/iommufd/ioas.c @@ -132,7 +132,7 @@ static int iommufd_ioas_load_iovas(struct rb_root_cached *itree, if (interval_tree_iter_first(itree, range.start, range.last)) return -EINVAL; - allowed = kzalloc(sizeof(*allowed), GFP_KERNEL_ACCOUNT); + allowed = kzalloc_obj(*allowed, GFP_KERNEL_ACCOUNT); if (!allowed) return -ENOMEM; allowed->node.start = range.start; diff --git a/drivers/iommu/iommufd/iova_bitmap.c b/drivers/iommu/iommufd/iova_bitmap.c index b5b67a9d3fb3..dac3e657d498 100644 --- a/drivers/iommu/iommufd/iova_bitmap.c +++ b/drivers/iommu/iommufd/iova_bitmap.c @@ -247,7 +247,7 @@ struct iova_bitmap *iova_bitmap_alloc(unsigned long iova, size_t length, struct iova_bitmap *bitmap; int rc; - bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); + bitmap = kzalloc_obj(*bitmap); if (!bitmap) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/iommufd/main.c b/drivers/iommu/iommufd/main.c index 5cc4b08c25f5..8c6d43601afb 100644 --- a/drivers/iommu/iommufd/main.c +++ b/drivers/iommu/iommufd/main.c @@ -296,7 +296,7 @@ static int iommufd_fops_open(struct inode *inode, struct file *filp) { struct iommufd_ctx *ictx; - ictx = kzalloc(sizeof(*ictx), GFP_KERNEL_ACCOUNT); + ictx = kzalloc_obj(*ictx, GFP_KERNEL_ACCOUNT); if (!ictx) return -ENOMEM; diff --git a/drivers/iommu/iommufd/pages.c b/drivers/iommu/iommufd/pages.c index f863fea75b98..9b49f0c5b459 100644 --- a/drivers/iommu/iommufd/pages.c +++ b/drivers/iommu/iommufd/pages.c @@ -1372,7 +1372,7 @@ static struct iopt_pages *iopt_alloc_pages(unsigned long start_byte, if (length > SIZE_MAX - PAGE_SIZE || length == 0) return ERR_PTR(-EINVAL); - pages = kzalloc(sizeof(*pages), GFP_KERNEL_ACCOUNT); + pages = kzalloc_obj(*pages, GFP_KERNEL_ACCOUNT); if (!pages) return ERR_PTR(-ENOMEM); @@ -1575,7 +1575,7 @@ int iopt_dmabuf_track_domain(struct iopt_pages *pages, struct iopt_area *area, if (WARN_ON(track->domain == domain && track->area == area)) return -EINVAL; - track = kzalloc(sizeof(*track), GFP_KERNEL); + track = kzalloc_obj(*track); if (!track) return -ENOMEM; track->domain = domain; @@ -2455,7 +2455,7 @@ int iopt_area_add_access(struct iopt_area *area, unsigned long start_index, return 0; } - access = kzalloc(sizeof(*access), GFP_KERNEL_ACCOUNT); + access = kzalloc_obj(*access, GFP_KERNEL_ACCOUNT); if (!access) { rc = -ENOMEM; goto err_unlock; diff --git a/drivers/iommu/iommufd/selftest.c b/drivers/iommu/iommufd/selftest.c index 989d8c4c60a7..7823142097d4 100644 --- a/drivers/iommu/iommufd/selftest.c +++ b/drivers/iommu/iommufd/selftest.c @@ -308,7 +308,7 @@ static void *mock_domain_hw_info(struct device *dev, u32 *length, *type != IOMMU_HW_INFO_TYPE_SELFTEST) return ERR_PTR(-EOPNOTSUPP); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); @@ -353,7 +353,7 @@ __mock_domain_alloc_nested(const struct iommu_user_data *user_data) if (rc) return ERR_PTR(rc); - mock_nested = kzalloc(sizeof(*mock_nested), GFP_KERNEL); + mock_nested = kzalloc_obj(*mock_nested); if (!mock_nested) return ERR_PTR(-ENOMEM); mock_nested->domain.ops = &domain_nested_ops; @@ -441,7 +441,7 @@ mock_domain_alloc_pgtable(struct device *dev, struct mock_iommu_domain *mock; int rc; - mock = kzalloc(sizeof(*mock), GFP_KERNEL); + mock = kzalloc_obj(*mock); if (!mock) return ERR_PTR(-ENOMEM); mock->domain.type = IOMMU_DOMAIN_UNMANAGED; @@ -674,7 +674,7 @@ static int mock_viommu_cache_invalidate(struct iommufd_viommu *viommu, return 0; } - cmds = kcalloc(array->entry_num, sizeof(*cmds), GFP_KERNEL); + cmds = kzalloc_objs(*cmds, array->entry_num); if (!cmds) return -ENOMEM; cur = cmds; @@ -1023,7 +1023,7 @@ static struct mock_dev *mock_dev_create(unsigned long dev_flags) if (dev_flags & ~valid_flags) return ERR_PTR(-EINVAL); - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return ERR_PTR(-ENOMEM); @@ -1448,7 +1448,7 @@ static struct selftest_access *iommufd_test_alloc_access(void) struct selftest_access *staccess; struct file *filep; - staccess = kzalloc(sizeof(*staccess), GFP_KERNEL_ACCOUNT); + staccess = kzalloc_obj(*staccess, GFP_KERNEL_ACCOUNT); if (!staccess) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&staccess->items); @@ -1592,7 +1592,7 @@ static int iommufd_test_access_pages(struct iommufd_ucmd *ucmd, npages = (ALIGN(iova + length, PAGE_SIZE) - ALIGN_DOWN(iova, PAGE_SIZE)) / PAGE_SIZE; - pages = kvcalloc(npages, sizeof(*pages), GFP_KERNEL_ACCOUNT); + pages = kvzalloc_objs(*pages, npages, GFP_KERNEL_ACCOUNT); if (!pages) { rc = -ENOMEM; goto out_put; @@ -1622,7 +1622,7 @@ static int iommufd_test_access_pages(struct iommufd_ucmd *ucmd, goto out_unaccess; } - item = kzalloc(sizeof(*item), GFP_KERNEL_ACCOUNT); + item = kzalloc_obj(*item, GFP_KERNEL_ACCOUNT); if (!item) { rc = -ENOMEM; goto out_unaccess; @@ -2032,7 +2032,7 @@ static int iommufd_test_dmabuf_get(struct iommufd_ucmd *ucmd, if (len == 0 || len > PAGE_SIZE * 512) return -EINVAL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/iommu/iommufd/viommu.c b/drivers/iommu/iommufd/viommu.c index 462b457ffd0c..4081deda9b33 100644 --- a/drivers/iommu/iommufd/viommu.c +++ b/drivers/iommu/iommufd/viommu.c @@ -312,7 +312,7 @@ iommufd_hw_queue_alloc_phys(struct iommu_hw_queue_alloc *cmd, * Use kvcalloc() to avoid memory fragmentation for a large page array. * Set __GFP_NOWARN to avoid syzkaller blowups */ - pages = kvcalloc(max_npages, sizeof(*pages), GFP_KERNEL | __GFP_NOWARN); + pages = kvzalloc_objs(*pages, max_npages, GFP_KERNEL | __GFP_NOWARN); if (!pages) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index 18f839721813..f9cd18316d16 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -715,9 +715,8 @@ int iova_domain_init_rcaches(struct iova_domain *iovad) unsigned int cpu; int i, ret; - iovad->rcaches = kcalloc(IOVA_RANGE_CACHE_MAX_SIZE, - sizeof(struct iova_rcache), - GFP_KERNEL); + iovad->rcaches = kzalloc_objs(struct iova_rcache, + IOVA_RANGE_CACHE_MAX_SIZE); if (!iovad->rcaches) return -ENOMEM; diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index ca848288dbf2..9386b752dea2 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -566,7 +566,7 @@ static struct iommu_domain *ipmmu_domain_alloc_paging(struct device *dev) { struct ipmmu_vmsa_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return NULL; diff --git a/drivers/iommu/msm_iommu.c b/drivers/iommu/msm_iommu.c index 819add75a665..0ad5ff431d5b 100644 --- a/drivers/iommu/msm_iommu.c +++ b/drivers/iommu/msm_iommu.c @@ -306,7 +306,7 @@ static struct iommu_domain *msm_iommu_domain_alloc_paging(struct device *dev) { struct msm_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) goto fail_nomem; @@ -605,7 +605,7 @@ static int insert_iommu_master(struct device *dev, int sid; if (list_empty(&(*iommu)->ctx_list)) { - master = kzalloc(sizeof(*master), GFP_ATOMIC); + master = kzalloc_obj(*master, GFP_ATOMIC); if (!master) { dev_err(dev, "Failed to allocate iommu_master\n"); return -ENOMEM; diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c index 60fcd3d3b5eb..2be990c108de 100644 --- a/drivers/iommu/mtk_iommu.c +++ b/drivers/iommu/mtk_iommu.c @@ -704,7 +704,7 @@ static struct iommu_domain *mtk_iommu_domain_alloc_paging(struct device *dev) { struct mtk_iommu_domain *dom; - dom = kzalloc(sizeof(*dom), GFP_KERNEL); + dom = kzalloc_obj(*dom); if (!dom) return NULL; mutex_init(&dom->mutex); diff --git a/drivers/iommu/mtk_iommu_v1.c b/drivers/iommu/mtk_iommu_v1.c index c8d8eff5373d..ac97dd2868d4 100644 --- a/drivers/iommu/mtk_iommu_v1.c +++ b/drivers/iommu/mtk_iommu_v1.c @@ -284,7 +284,7 @@ static struct iommu_domain *mtk_iommu_v1_domain_alloc_paging(struct device *dev) { struct mtk_iommu_v1_domain *dom; - dom = kzalloc(sizeof(*dom), GFP_KERNEL); + dom = kzalloc_obj(*dom); if (!dom) return NULL; diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 259f65291d90..34c0a45f73d8 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c @@ -147,7 +147,7 @@ static size_t omap_dump_tlb_entries(struct omap_iommu *obj, struct seq_file *s) num = obj->nr_tlb_entries; - cr = kcalloc(num, sizeof(*cr), GFP_KERNEL); + cr = kzalloc_objs(*cr, num); if (!cr) return 0; diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index 768973b7e511..8231d7d6bb6a 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c @@ -311,7 +311,7 @@ static struct cr_regs *iotlb_alloc_cr(struct omap_iommu *obj, return ERR_PTR(-EINVAL); } - cr = kmalloc(sizeof(*cr), GFP_KERNEL); + cr = kmalloc_obj(*cr); if (!cr) return ERR_PTR(-ENOMEM); @@ -1395,8 +1395,7 @@ static int omap_iommu_attach_init(struct device *dev, if (!odomain->num_iommus) return -ENODEV; - odomain->iommus = kcalloc(odomain->num_iommus, sizeof(*iommu), - GFP_ATOMIC); + odomain->iommus = kzalloc_objs(*iommu, odomain->num_iommus, GFP_ATOMIC); if (!odomain->iommus) return -ENOMEM; @@ -1564,7 +1563,7 @@ static struct iommu_domain *omap_iommu_domain_alloc_paging(struct device *dev) { struct omap_iommu_domain *omap_domain; - omap_domain = kzalloc(sizeof(*omap_domain), GFP_KERNEL); + omap_domain = kzalloc_obj(*omap_domain); if (!omap_domain) return NULL; @@ -1656,7 +1655,7 @@ static struct iommu_device *omap_iommu_probe_device(struct device *dev) if (num_iommus < 0) return ERR_PTR(-ENODEV); - arch_data = kcalloc(num_iommus + 1, sizeof(*arch_data), GFP_KERNEL); + arch_data = kzalloc_objs(*arch_data, num_iommus + 1); if (!arch_data) return ERR_PTR(-ENOMEM); diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index 2d8fb0859f30..fa2ebfd2f912 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -853,7 +853,7 @@ static int riscv_iommu_bond_link(struct riscv_iommu_domain *domain, struct riscv_iommu_bond *bond; struct list_head *bonds; - bond = kzalloc(sizeof(*bond), GFP_KERNEL); + bond = kzalloc_obj(*bond); if (!bond) return -ENOMEM; bond->dev = dev; @@ -1380,7 +1380,7 @@ static struct iommu_domain *riscv_iommu_alloc_paging_domain(struct device *dev) return ERR_PTR(-ENODEV); } - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return ERR_PTR(-ENOMEM); @@ -1504,7 +1504,7 @@ static struct iommu_device *riscv_iommu_probe_device(struct device *dev) if (iommu->ddt_mode <= RISCV_IOMMU_DDTP_IOMMU_MODE_BARE) return ERR_PTR(-ENODEV); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); /* diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c index 85f3667e797c..0013cf196c57 100644 --- a/drivers/iommu/rockchip-iommu.c +++ b/drivers/iommu/rockchip-iommu.c @@ -1064,7 +1064,7 @@ static struct iommu_domain *rk_iommu_domain_alloc_paging(struct device *dev) struct rk_iommu_domain *rk_domain; struct rk_iommu *iommu; - rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL); + rk_domain = kzalloc_obj(*rk_domain); if (!rk_domain) return NULL; diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c index fe679850af28..f148f559ac56 100644 --- a/drivers/iommu/s390-iommu.c +++ b/drivers/iommu/s390-iommu.c @@ -531,7 +531,7 @@ static struct iommu_domain *s390_domain_alloc_paging(struct device *dev) struct s390_domain *s390_domain; u64 aperture_size; - s390_domain = kzalloc(sizeof(*s390_domain), GFP_KERNEL); + s390_domain = kzalloc_obj(*s390_domain); if (!s390_domain) return NULL; diff --git a/drivers/iommu/sprd-iommu.c b/drivers/iommu/sprd-iommu.c index 555d4505c747..c1a34445d244 100644 --- a/drivers/iommu/sprd-iommu.c +++ b/drivers/iommu/sprd-iommu.c @@ -137,7 +137,7 @@ static struct iommu_domain *sprd_iommu_domain_alloc_paging(struct device *dev) { struct sprd_iommu_domain *dom; - dom = kzalloc(sizeof(*dom), GFP_KERNEL); + dom = kzalloc_obj(*dom); if (!dom) return NULL; diff --git a/drivers/iommu/sun50i-iommu.c b/drivers/iommu/sun50i-iommu.c index 90b26fe21817..be3f1ce696ba 100644 --- a/drivers/iommu/sun50i-iommu.c +++ b/drivers/iommu/sun50i-iommu.c @@ -686,7 +686,7 @@ sun50i_iommu_domain_alloc_paging(struct device *dev) { struct sun50i_iommu_domain *sun50i_domain; - sun50i_domain = kzalloc(sizeof(*sun50i_domain), GFP_KERNEL); + sun50i_domain = kzalloc_obj(*sun50i_domain); if (!sun50i_domain) return NULL; diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index c391e7f2cde6..67e7a7b925f0 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c @@ -289,7 +289,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc_paging(struct device *dev) { struct tegra_smmu_as *as; - as = kzalloc(sizeof(*as), GFP_KERNEL); + as = kzalloc_obj(*as); if (!as) return NULL; @@ -308,7 +308,7 @@ static struct iommu_domain *tegra_smmu_domain_alloc_paging(struct device *dev) return NULL; } - as->pts = kcalloc(SMMU_NUM_PDE, sizeof(*as->pts), GFP_KERNEL); + as->pts = kzalloc_objs(*as->pts, SMMU_NUM_PDE); if (!as->pts) { kfree(as->count); iommu_free_pages(as->pd); diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index d314fa5cd847..587fc13197f1 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -231,7 +231,7 @@ static int __viommu_add_req(struct viommu_dev *viommu, void *buf, size_t len, if (write_offset <= 0) return -EINVAL; - req = kzalloc(struct_size(req, buf, len), GFP_ATOMIC); + req = kzalloc_flex(*req, buf, len, GFP_ATOMIC); if (!req) return -ENOMEM; @@ -333,7 +333,7 @@ static int viommu_add_mapping(struct viommu_domain *vdomain, u64 iova, u64 end, unsigned long irqflags; struct viommu_mapping *mapping; - mapping = kzalloc(sizeof(*mapping), GFP_ATOMIC); + mapping = kzalloc_obj(*mapping, GFP_ATOMIC); if (!mapping) return -ENOMEM; @@ -670,7 +670,7 @@ static struct iommu_domain *viommu_domain_alloc_paging(struct device *dev) return ERR_PTR(-ENODEV); } - vdomain = kzalloc(sizeof(*vdomain), GFP_KERNEL); + vdomain = kzalloc_obj(*vdomain); if (!vdomain) return ERR_PTR(-ENOMEM); @@ -1028,7 +1028,7 @@ static struct iommu_device *viommu_probe_device(struct device *dev) if (!viommu) return ERR_PTR(-ENODEV); - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/ipack/carriers/tpci200.c b/drivers/ipack/carriers/tpci200.c index cbfdadecb23b..05dcb6675cd6 100644 --- a/drivers/ipack/carriers/tpci200.c +++ b/drivers/ipack/carriers/tpci200.c @@ -209,7 +209,7 @@ static int tpci200_request_irq(struct ipack_device *dev, goto out_unlock; } - slot_irq = kzalloc(sizeof(struct slot_irq), GFP_KERNEL); + slot_irq = kzalloc_obj(struct slot_irq); if (slot_irq == NULL) { dev_err(&dev->dev, "Slot [%d:%d] unable to allocate memory for IRQ !\n", @@ -461,8 +461,7 @@ static int tpci200_install(struct tpci200_board *tpci200) { int res; - tpci200->slots = kcalloc(TPCI200_NB_SLOT, sizeof(struct tpci200_slot), - GFP_KERNEL); + tpci200->slots = kzalloc_objs(struct tpci200_slot, TPCI200_NB_SLOT); if (tpci200->slots == NULL) return -ENOMEM; @@ -487,7 +486,7 @@ static int tpci200_create_device(struct tpci200_board *tpci200, int i) int ret; enum ipack_space space; struct ipack_device *dev = - kzalloc(sizeof(struct ipack_device), GFP_KERNEL); + kzalloc_obj(struct ipack_device); if (!dev) return -ENOMEM; dev->slot = i; @@ -521,11 +520,11 @@ static int tpci200_pci_probe(struct pci_dev *pdev, struct tpci200_board *tpci200; u32 reg32; - tpci200 = kzalloc(sizeof(struct tpci200_board), GFP_KERNEL); + tpci200 = kzalloc_obj(struct tpci200_board); if (!tpci200) return -ENOMEM; - tpci200->info = kzalloc(sizeof(struct tpci200_infos), GFP_KERNEL); + tpci200->info = kzalloc_obj(struct tpci200_infos); if (!tpci200->info) { ret = -ENOMEM; goto err_tpci200; diff --git a/drivers/ipack/devices/ipoctal.c b/drivers/ipack/devices/ipoctal.c index ba2e9e52d72b..1bbefc6de708 100644 --- a/drivers/ipack/devices/ipoctal.c +++ b/drivers/ipack/devices/ipoctal.c @@ -688,7 +688,7 @@ static int ipoctal_probe(struct ipack_device *dev) int res; struct ipoctal *ipoctal; - ipoctal = kzalloc(sizeof(struct ipoctal), GFP_KERNEL); + ipoctal = kzalloc_obj(struct ipoctal); if (ipoctal == NULL) return -ENOMEM; diff --git a/drivers/ipack/ipack.c b/drivers/ipack/ipack.c index 57d232c909f9..28214f862ab1 100644 --- a/drivers/ipack/ipack.c +++ b/drivers/ipack/ipack.c @@ -203,7 +203,7 @@ struct ipack_bus_device *ipack_bus_register(struct device *parent, int slots, int bus_nr; struct ipack_bus_device *bus; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) return NULL; diff --git a/drivers/irqchip/exynos-combiner.c b/drivers/irqchip/exynos-combiner.c index 495848442b35..11d105457798 100644 --- a/drivers/irqchip/exynos-combiner.c +++ b/drivers/irqchip/exynos-combiner.c @@ -176,7 +176,7 @@ static void __init combiner_init(void __iomem *combiner_base, nr_irq = max_nr * IRQ_IN_COMBINER; - combiner_data = kcalloc(max_nr, sizeof (*combiner_data), GFP_KERNEL); + combiner_data = kzalloc_objs(*combiner_data, max_nr); if (!combiner_data) return; diff --git a/drivers/irqchip/irq-al-fic.c b/drivers/irqchip/irq-al-fic.c index 8f300843bbca..d10ac9b63c99 100644 --- a/drivers/irqchip/irq-al-fic.c +++ b/drivers/irqchip/irq-al-fic.c @@ -194,7 +194,7 @@ static struct al_fic *al_fic_wire_init(struct device_node *node, int ret; u32 control = CONTROL_MASK_MSI_X; - fic = kzalloc(sizeof(*fic), GFP_KERNEL); + fic = kzalloc_obj(*fic); if (!fic) return ERR_PTR(-ENOMEM); diff --git a/drivers/irqchip/irq-alpine-msi.c b/drivers/irqchip/irq-alpine-msi.c index 159d9ec7c0dd..6764d64e7950 100644 --- a/drivers/irqchip/irq-alpine-msi.c +++ b/drivers/irqchip/irq-alpine-msi.c @@ -192,7 +192,7 @@ static int alpine_msix_init_domains(struct alpine_msix_data *priv, struct device static int alpine_msix_init(struct device_node *node, struct device_node *parent) { - struct alpine_msix_data *priv __free(kfree) = kzalloc(sizeof(*priv), GFP_KERNEL); + struct alpine_msix_data *priv __free(kfree) = kzalloc_obj(*priv); struct resource res; int ret; diff --git a/drivers/irqchip/irq-apple-aic.c b/drivers/irqchip/irq-apple-aic.c index 3c70364e7cdd..2b24c82bb0df 100644 --- a/drivers/irqchip/irq-apple-aic.c +++ b/drivers/irqchip/irq-apple-aic.c @@ -921,7 +921,7 @@ static void build_fiq_affinity(struct aic_irq_chip *ic, struct device_node *aff) if (WARN_ON(n < 0)) return; - ic->fiq_aff[fiq] = kzalloc(sizeof(*ic->fiq_aff[fiq]), GFP_KERNEL); + ic->fiq_aff[fiq] = kzalloc_obj(*ic->fiq_aff[fiq]); if (!ic->fiq_aff[fiq]) return; @@ -959,7 +959,7 @@ static int __init aic_of_ic_init(struct device_node *node, struct device_node *p if (WARN_ON(!regs)) return -EIO; - irqc = kzalloc(sizeof(*irqc), GFP_KERNEL); + irqc = kzalloc_obj(*irqc); if (!irqc) { iounmap(regs); return -ENOMEM; diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index a4d03a2d1569..1ba82ac0c26b 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -835,7 +835,7 @@ static int __init mpic_of_init(struct device_node *node, struct device_node *par struct mpic *mpic; int err; - mpic = kzalloc(sizeof(*mpic), GFP_KERNEL); + mpic = kzalloc_obj(*mpic); if (WARN_ON(!mpic)) return -ENOMEM; diff --git a/drivers/irqchip/irq-aspeed-i2c-ic.c b/drivers/irqchip/irq-aspeed-i2c-ic.c index 87c1feb999ff..7996fd5cbae6 100644 --- a/drivers/irqchip/irq-aspeed-i2c-ic.c +++ b/drivers/irqchip/irq-aspeed-i2c-ic.c @@ -66,7 +66,7 @@ static int __init aspeed_i2c_ic_of_init(struct device_node *node, struct aspeed_i2c_ic *i2c_ic; int ret = 0; - i2c_ic = kzalloc(sizeof(*i2c_ic), GFP_KERNEL); + i2c_ic = kzalloc_obj(*i2c_ic); if (!i2c_ic) return -ENOMEM; diff --git a/drivers/irqchip/irq-aspeed-intc.c b/drivers/irqchip/irq-aspeed-intc.c index 8330221799a0..4fb0dd8349da 100644 --- a/drivers/irqchip/irq-aspeed-intc.c +++ b/drivers/irqchip/irq-aspeed-intc.c @@ -89,7 +89,7 @@ static int __init aspeed_intc_ic_of_init(struct device_node *node, struct aspeed_intc_ic *intc_ic; int irq, i, ret = 0; - intc_ic = kzalloc(sizeof(*intc_ic), GFP_KERNEL); + intc_ic = kzalloc_obj(*intc_ic); if (!intc_ic) return -ENOMEM; diff --git a/drivers/irqchip/irq-aspeed-scu-ic.c b/drivers/irqchip/irq-aspeed-scu-ic.c index 7398c3b9eace..097cf45b2126 100644 --- a/drivers/irqchip/irq-aspeed-scu-ic.c +++ b/drivers/irqchip/irq-aspeed-scu-ic.c @@ -270,7 +270,7 @@ static int __init aspeed_scu_ic_of_init(struct device_node *node, struct device_ if (!variant) return -ENODEV; - scu_ic = kzalloc(sizeof(*scu_ic), GFP_KERNEL); + scu_ic = kzalloc_obj(*scu_ic); if (!scu_ic) return -ENOMEM; diff --git a/drivers/irqchip/irq-aspeed-vic.c b/drivers/irqchip/irq-aspeed-vic.c index 9b665b5bb531..6649b893f39c 100644 --- a/drivers/irqchip/irq-aspeed-vic.c +++ b/drivers/irqchip/irq-aspeed-vic.c @@ -196,7 +196,7 @@ static int __init avic_of_init(struct device_node *node, if (WARN_ON(!regs)) return -EIO; - vic = kzalloc(sizeof(struct aspeed_vic), GFP_KERNEL); + vic = kzalloc_obj(struct aspeed_vic); if (WARN_ON(!vic)) { iounmap(regs); return -ENOMEM; diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c index e68853815c7a..7a1d60ee0d51 100644 --- a/drivers/irqchip/irq-atmel-aic-common.c +++ b/drivers/irqchip/irq-atmel-aic-common.c @@ -213,7 +213,7 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node, if (!reg_base) return ERR_PTR(-ENOMEM); - aic = kcalloc(nchips, sizeof(*aic), GFP_KERNEL); + aic = kzalloc_objs(*aic, nchips); if (!aic) { ret = -ENOMEM; goto err_iounmap; diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c index 4761974ad650..06a6ab6270ad 100644 --- a/drivers/irqchip/irq-bcm2712-mip.c +++ b/drivers/irqchip/irq-bcm2712-mip.c @@ -238,7 +238,7 @@ static int mip_msi_probe(struct platform_device *pdev, struct device_node *paren struct mip_priv *mip; int ret; - mip = kzalloc(sizeof(*mip), GFP_KERNEL); + mip = kzalloc_obj(*mip); if (!mip) return -ENOMEM; diff --git a/drivers/irqchip/irq-bcm6345-l1.c b/drivers/irqchip/irq-bcm6345-l1.c index ca4e141c5bc2..d446d8124a8b 100644 --- a/drivers/irqchip/irq-bcm6345-l1.c +++ b/drivers/irqchip/irq-bcm6345-l1.c @@ -238,8 +238,7 @@ static int __init bcm6345_l1_init_one(struct device_node *dn, else if (intc->n_words != n_words) return -EINVAL; - cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, enable_cache, n_words), - GFP_KERNEL); + cpu = intc->cpus[idx] = kzalloc_flex(*cpu, enable_cache, n_words); if (!cpu) return -ENOMEM; @@ -296,7 +295,7 @@ static int __init bcm6345_l1_of_init(struct device_node *dn, unsigned int idx; int ret; - intc = kzalloc(sizeof(*intc), GFP_KERNEL); + intc = kzalloc_obj(*intc); if (!intc) return -ENOMEM; diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c index 45c4824be92f..54a8557ef557 100644 --- a/drivers/irqchip/irq-bcm7038-l1.c +++ b/drivers/irqchip/irq-bcm7038-l1.c @@ -242,8 +242,7 @@ static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, return -EINVAL; } - cpu = intc->cpus[idx] = kzalloc(struct_size(cpu, mask_cache, n_words), - GFP_KERNEL); + cpu = intc->cpus[idx] = kzalloc_flex(*cpu, mask_cache, n_words); if (!cpu) return -ENOMEM; @@ -398,7 +397,7 @@ static int bcm7038_l1_probe(struct platform_device *pdev, struct device_node *pa struct bcm7038_l1_chip *intc; int idx, ret; - intc = kzalloc(sizeof(*intc), GFP_KERNEL); + intc = kzalloc_obj(*intc); if (!intc) return -ENOMEM; diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c index 518c9d4366a5..a98f0ee46b6c 100644 --- a/drivers/irqchip/irq-bcm7120-l2.c +++ b/drivers/irqchip/irq-bcm7120-l2.c @@ -220,7 +220,7 @@ static int bcm7120_l2_intc_probe(struct platform_device *pdev, struct device_nod unsigned int idx, irq, flags; u32 valid_mask[MAX_WORDS] = { }; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -231,8 +231,7 @@ static int bcm7120_l2_intc_probe(struct platform_device *pdev, struct device_nod goto out_unmap; } - data->l1_data = kcalloc(data->num_parent_irqs, sizeof(*data->l1_data), - GFP_KERNEL); + data->l1_data = kzalloc_objs(*data->l1_data, data->num_parent_irqs); if (!data->l1_data) { ret = -ENOMEM; goto out_free_l1_data; diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c index bb7078d6524f..d336ac822ea0 100644 --- a/drivers/irqchip/irq-brcmstb-l2.c +++ b/drivers/irqchip/irq-brcmstb-l2.c @@ -151,7 +151,7 @@ static int brcmstb_l2_intc_probe(struct platform_device *pdev, struct device_nod int parent_irq; void __iomem *base; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/irqchip/irq-clps711x.c b/drivers/irqchip/irq-clps711x.c index c4b73ba2323b..995bbd126f90 100644 --- a/drivers/irqchip/irq-clps711x.c +++ b/drivers/irqchip/irq-clps711x.c @@ -155,7 +155,7 @@ static int __init _clps711x_intc_init(struct device_node *np, { int err; - clps711x_intc = kzalloc(sizeof(*clps711x_intc), GFP_KERNEL); + clps711x_intc = kzalloc_obj(*clps711x_intc); if (!clps711x_intc) return -ENOMEM; diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 66bb39e24a52..cd1134101ace 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c @@ -199,7 +199,7 @@ static int __init crossbar_of_init(struct device_node *node) const __be32 *irqsr; int ret = -ENOMEM; - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc_obj(*cb); if (!cb) return ret; @@ -268,7 +268,7 @@ static int __init crossbar_of_init(struct device_node *node) } - cb->register_offsets = kcalloc(max, sizeof(int), GFP_KERNEL); + cb->register_offsets = kzalloc_objs(int, max); if (!cb->register_offsets) goto err_irq_map; diff --git a/drivers/irqchip/irq-gic-v2m.c b/drivers/irqchip/irq-gic-v2m.c index 8a3410c2b7b5..bd85bd344f25 100644 --- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -293,7 +293,7 @@ static int __init gicv2m_init_one(struct fwnode_handle *fwnode, int ret; struct v2m_data *v2m; - v2m = kzalloc(sizeof(struct v2m_data), GFP_KERNEL); + v2m = kzalloc_obj(struct v2m_data); if (!v2m) return -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 2988def30972..291d7668cc8d 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -1926,8 +1926,8 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info) if (!its_dev->event_map.vm) { struct its_vlpi_map *maps; - maps = kcalloc(its_dev->event_map.nr_lpis, sizeof(*maps), - GFP_ATOMIC); + maps = kzalloc_objs(*maps, its_dev->event_map.nr_lpis, + GFP_ATOMIC); if (!maps) return -ENOMEM; @@ -2108,7 +2108,7 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span) { struct lpi_range *range; - range = kmalloc(sizeof(*range), GFP_KERNEL); + range = kmalloc_obj(*range); if (range) { range->base_id = base; range->span = span; @@ -2927,7 +2927,7 @@ static int allocate_vpe_l1_table(void) if (val & GICR_VPROPBASER_4_1_VALID) goto out; - gic_data_rdist()->vpe_table_mask = kzalloc(sizeof(cpumask_t), GFP_ATOMIC); + gic_data_rdist()->vpe_table_mask = kzalloc_obj(cpumask_t, GFP_ATOMIC); if (!gic_data_rdist()->vpe_table_mask) return -ENOMEM; @@ -3025,8 +3025,7 @@ static int its_alloc_collections(struct its_node *its) { int i; - its->collections = kcalloc(nr_cpu_ids, sizeof(*its->collections), - GFP_KERNEL); + its->collections = kzalloc_objs(*its->collections, nr_cpu_ids); if (!its->collections) return -ENOMEM; @@ -3475,6 +3474,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, int lpi_base; int nr_lpis; int nr_ites; + int id_bits; int sz; if (!its_alloc_device_table(its, dev_id)) @@ -3486,14 +3486,17 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, /* * Even if the device wants a single LPI, the ITT must be * sized as a power of two (and you need at least one bit...). + * Also honor the ITS's own EID limit. */ + id_bits = FIELD_GET(GITS_TYPER_IDBITS, its->typer) + 1; + nvecs = min_t(unsigned int, nvecs, BIT(id_bits)); nr_ites = max(2, nvecs); sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); sz = max(sz, ITS_ITT_ALIGN); itt = itt_alloc_pool(its->numa_node, sz); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (alloc_lpis) { lpi_map = its_lpi_alloc(nvecs, &lpi_base, &nr_lpis); @@ -5139,7 +5142,7 @@ static int its_init_domain(struct its_node *its) }; struct msi_domain_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -5169,8 +5172,7 @@ static int its_init_vpe_domain(void) its = list_first_entry(&its_nodes, struct its_node, entry); entries = roundup_pow_of_two(nr_cpu_ids); - vpe_proxy.vpes = kcalloc(entries, sizeof(*vpe_proxy.vpes), - GFP_KERNEL); + vpe_proxy.vpes = kzalloc_objs(*vpe_proxy.vpes, entries); if (!vpe_proxy.vpes) return -ENOMEM; @@ -5514,7 +5516,7 @@ static struct its_node __init *its_node_init(struct resource *res, pr_info("ITS %pR\n", res); - its = kzalloc(sizeof(*its), GFP_KERNEL); + its = kzalloc_obj(*its); if (!its) goto out_unmap; @@ -5680,8 +5682,7 @@ static void __init acpi_table_parse_srat_its(void) if (count <= 0) return; - its_srat_maps = kmalloc_array(count, sizeof(struct its_srat_map), - GFP_KERNEL); + its_srat_maps = kmalloc_objs(struct its_srat_map, count); if (!its_srat_maps) return; diff --git a/drivers/irqchip/irq-gic-v3-mbi.c b/drivers/irqchip/irq-gic-v3-mbi.c index aa11bbe8026a..62504deb6cd3 100644 --- a/drivers/irqchip/irq-gic-v3-mbi.c +++ b/drivers/irqchip/irq-gic-v3-mbi.c @@ -231,7 +231,7 @@ int __init mbi_init(struct fwnode_handle *fwnode, struct irq_domain *parent) return -EINVAL; mbi_range_nr = n / 2; - mbi_ranges = kcalloc(mbi_range_nr, sizeof(*mbi_ranges), GFP_KERNEL); + mbi_ranges = kzalloc_objs(*mbi_ranges, mbi_range_nr); if (!mbi_ranges) return -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index 6607ab58f72e..20f13b686ab2 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -2090,7 +2090,7 @@ static void __init gic_populate_ppi_partitions(struct device_node *gic_node) if (!nr_parts) goto out_put_node; - parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, nr_parts); if (WARN_ON(!parts)) goto out_put_node; @@ -2218,8 +2218,7 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare if (of_property_read_u32(node, "#redistributor-regions", &nr_redist_regions)) nr_redist_regions = 1; - rdist_regs = kcalloc(nr_redist_regions, sizeof(*rdist_regs), - GFP_KERNEL); + rdist_regs = kzalloc_objs(*rdist_regs, nr_redist_regions); if (!rdist_regs) { err = -ENOMEM; goto out_unmap_dist; diff --git a/drivers/irqchip/irq-gic-v5-irs.c b/drivers/irqchip/irq-gic-v5-irs.c index 8bc4bb121088..f3fce0b1e25d 100644 --- a/drivers/irqchip/irq-gic-v5-irs.c +++ b/drivers/irqchip/irq-gic-v5-irs.c @@ -699,7 +699,7 @@ static int __init gicv5_irs_init(struct gicv5_irs_chip_data *irs_data) */ if (list_empty(&irs_nodes)) { idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR0); - gicv5_global_data.virt_capable = !FIELD_GET(GICV5_IRS_IDR0_VIRT, idr); + gicv5_global_data.virt_capable = !!FIELD_GET(GICV5_IRS_IDR0_VIRT, idr); idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1); irs_setup_pri_bits(idr); @@ -727,7 +727,7 @@ static int __init gicv5_irs_of_init(struct device_node *node) u32 idr; int ret; - irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); + irs_data = kzalloc_obj(*irs_data); if (!irs_data) return -ENOMEM; @@ -913,7 +913,7 @@ static int __init gic_acpi_parse_madt_irs(union acpi_subtable_headers *header, int ret; /* Per-IRS data structure */ - irs_data = kzalloc(sizeof(*irs_data), GFP_KERNEL); + irs_data = kzalloc_obj(*irs_data); if (!irs_data) return -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v5-its.c b/drivers/irqchip/irq-gic-v5-its.c index 8c4cf8430871..36a8d1368f0e 100644 --- a/drivers/irqchip/irq-gic-v5-its.c +++ b/drivers/irqchip/irq-gic-v5-its.c @@ -757,7 +757,7 @@ static struct gicv5_its_dev *gicv5_its_alloc_device(struct gicv5_its_chip_data * return ERR_PTR(-EBUSY); } - its_dev = kzalloc(sizeof(*its_dev), GFP_KERNEL); + its_dev = kzalloc_obj(*its_dev); if (!its_dev) return ERR_PTR(-ENOMEM); @@ -1100,7 +1100,7 @@ static int gicv5_its_init_domain(struct gicv5_its_chip_data *its, struct irq_dom }; struct msi_domain_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -1125,7 +1125,7 @@ static int __init gicv5_its_init_bases(void __iomem *its_base, struct fwnode_han bool enabled; int ret; - its_node = kzalloc(sizeof(*its_node), GFP_KERNEL); + its_node = kzalloc_obj(*its_node); if (!its_node) return -ENOMEM; diff --git a/drivers/irqchip/irq-gic-v5-iwb.c b/drivers/irqchip/irq-gic-v5-iwb.c index c7d5fd34d053..9103feb70ce8 100644 --- a/drivers/irqchip/irq-gic-v5-iwb.c +++ b/drivers/irqchip/irq-gic-v5-iwb.c @@ -219,8 +219,7 @@ gicv5_iwb_init_bases(void __iomem *iwb_base, struct platform_device *pdev) unsigned int n; int ret; - struct gicv5_iwb_chip_data *iwb_node __free(kfree) = kzalloc(sizeof(*iwb_node), - GFP_KERNEL); + struct gicv5_iwb_chip_data *iwb_node __free(kfree) = kzalloc_obj(*iwb_node); if (!iwb_node) return ERR_PTR(-ENOMEM); diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c index a8b23b507ecd..d458cf898f8e 100644 --- a/drivers/irqchip/irq-goldfish-pic.c +++ b/drivers/irqchip/irq-goldfish-pic.c @@ -61,7 +61,7 @@ static int __init goldfish_pic_of_init(struct device_node *of_node, unsigned int parent_irq; int ret = 0; - gfpic = kzalloc(sizeof(*gfpic), GFP_KERNEL); + gfpic = kzalloc_obj(*gfpic); if (!gfpic) { ret = -ENOMEM; goto out_err; diff --git a/drivers/irqchip/irq-idt3243x.c b/drivers/irqchip/irq-idt3243x.c index f8324fb1fe8f..8b150c7f7e46 100644 --- a/drivers/irqchip/irq-idt3243x.c +++ b/drivers/irqchip/irq-idt3243x.c @@ -52,7 +52,7 @@ static int idt_pic_init(struct device_node *of_node, struct device_node *parent) unsigned int parent_irq; int ret = 0; - idtpic = kzalloc(sizeof(*idtpic), GFP_KERNEL); + idtpic = kzalloc_obj(*idtpic); if (!idtpic) { ret = -ENOMEM; goto out_err; diff --git a/drivers/irqchip/irq-imx-gpcv2.c b/drivers/irqchip/irq-imx-gpcv2.c index 04f7ba0657be..6ea10d3356a7 100644 --- a/drivers/irqchip/irq-imx-gpcv2.c +++ b/drivers/irqchip/irq-imx-gpcv2.c @@ -231,7 +231,7 @@ static int __init imx_gpcv2_irqchip_init(struct device_node *node, return -ENXIO; } - cd = kzalloc(sizeof(struct gpcv2_irqchip_data), GFP_KERNEL); + cd = kzalloc_obj(struct gpcv2_irqchip_data); if (!cd) return -ENOMEM; diff --git a/drivers/irqchip/irq-ingenic-tcu.c b/drivers/irqchip/irq-ingenic-tcu.c index 794ecba717c9..eebfdf107bd9 100644 --- a/drivers/irqchip/irq-ingenic-tcu.c +++ b/drivers/irqchip/irq-ingenic-tcu.c @@ -96,7 +96,7 @@ static int __init ingenic_tcu_irq_init(struct device_node *np, if (IS_ERR(map)) return PTR_ERR(map); - tcu = kzalloc(sizeof(*tcu), GFP_KERNEL); + tcu = kzalloc_obj(*tcu); if (!tcu) return -ENOMEM; diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c index 52393724f213..27d8c7f87dad 100644 --- a/drivers/irqchip/irq-ingenic.c +++ b/drivers/irqchip/irq-ingenic.c @@ -67,7 +67,7 @@ static int __init ingenic_intc_of_init(struct device_node *node, int parent_irq, err = 0; unsigned i; - intc = kzalloc(sizeof(*intc), GFP_KERNEL); + intc = kzalloc_obj(*intc); if (!intc) { err = -ENOMEM; goto out_err; diff --git a/drivers/irqchip/irq-loongarch-avec.c b/drivers/irqchip/irq-loongarch-avec.c index fb8efde95393..758262fd5bd6 100644 --- a/drivers/irqchip/irq-loongarch-avec.c +++ b/drivers/irqchip/irq-loongarch-avec.c @@ -276,7 +276,7 @@ static int avecintc_domain_alloc(struct irq_domain *domain, unsigned int virq, { for (unsigned int i = 0; i < nr_irqs; i++) { struct irq_data *irqd = irq_domain_get_irq_data(domain, virq + i); - struct avecintc_data *adata = kzalloc(sizeof(*adata), GFP_KERNEL); + struct avecintc_data *adata = kzalloc_obj(*adata); int ret; if (!adata) diff --git a/drivers/irqchip/irq-loongson-eiointc.c b/drivers/irqchip/irq-loongson-eiointc.c index 37e7e1f9bbe3..a9e8b481d31d 100644 --- a/drivers/irqchip/irq-loongson-eiointc.c +++ b/drivers/irqchip/irq-loongson-eiointc.c @@ -584,7 +584,7 @@ int __init eiointc_acpi_init(struct irq_domain *parent, struct eiointc_priv *priv; int node; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -633,7 +633,7 @@ static int __init eiointc_of_init(struct device_node *of_node, struct irq_data *irq_data; int parent_irq, ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-htpic.c b/drivers/irqchip/irq-loongson-htpic.c index 1c691c4be989..2d78112f7fc7 100644 --- a/drivers/irqchip/irq-loongson-htpic.c +++ b/drivers/irqchip/irq-loongson-htpic.c @@ -95,7 +95,7 @@ static int __init htpic_of_init(struct device_node *node, struct device_node *pa return -ENODEV; } - htpic = kzalloc(sizeof(*htpic), GFP_KERNEL); + htpic = kzalloc_obj(*htpic); if (!htpic) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-htvec.c b/drivers/irqchip/irq-loongson-htvec.c index 5a3339da97ad..75e40ba6069d 100644 --- a/drivers/irqchip/irq-loongson-htvec.c +++ b/drivers/irqchip/irq-loongson-htvec.c @@ -192,7 +192,7 @@ static int htvec_init(phys_addr_t addr, unsigned long size, int i; struct htvec *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-liointc.c b/drivers/irqchip/irq-loongson-liointc.c index 551597e2c428..cf44a333b9c8 100644 --- a/drivers/irqchip/irq-loongson-liointc.c +++ b/drivers/irqchip/irq-loongson-liointc.c @@ -205,7 +205,7 @@ static int liointc_init(phys_addr_t addr, unsigned long size, int revision, struct irq_domain *domain; struct liointc_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-pch-lpc.c b/drivers/irqchip/irq-loongson-pch-lpc.c index 3a125f3e4287..3ad46ec94e3c 100644 --- a/drivers/irqchip/irq-loongson-pch-lpc.c +++ b/drivers/irqchip/irq-loongson-pch-lpc.c @@ -183,7 +183,7 @@ int __init pch_lpc_acpi_init(struct irq_domain *parent, struct irq_fwspec fwspec; struct fwnode_handle *irq_handle; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-pch-msi.c b/drivers/irqchip/irq-loongson-pch-msi.c index 91c856c65d9d..99a8dd88c48a 100644 --- a/drivers/irqchip/irq-loongson-pch-msi.c +++ b/drivers/irqchip/irq-loongson-pch-msi.c @@ -177,7 +177,7 @@ static int pch_msi_init(phys_addr_t msg_address, int irq_base, int irq_count, int ret; struct pch_msi_data *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-loongson-pch-pic.c b/drivers/irqchip/irq-loongson-pch-pic.c index f2acaf93f552..98fc1770e2a5 100644 --- a/drivers/irqchip/irq-loongson-pch-pic.c +++ b/drivers/irqchip/irq-loongson-pch-pic.c @@ -329,7 +329,7 @@ static int pch_pic_init(phys_addr_t addr, unsigned long size, int vec_base, struct pch_pic *priv; int i; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-lpc32xx.c b/drivers/irqchip/irq-lpc32xx.c index 14cca44baa14..6ff93df614f8 100644 --- a/drivers/irqchip/irq-lpc32xx.c +++ b/drivers/irqchip/irq-lpc32xx.c @@ -198,7 +198,7 @@ static int __init lpc32xx_of_ic_init(struct device_node *node, const __be32 *reg = of_get_property(node, "reg", NULL); u32 parent_irq, i, addr = reg ? be32_to_cpu(*reg) : 0; - irqc = kzalloc(sizeof(*irqc), GFP_KERNEL); + irqc = kzalloc_obj(*irqc); if (!irqc) return -ENOMEM; diff --git a/drivers/irqchip/irq-ls-extirq.c b/drivers/irqchip/irq-ls-extirq.c index a7e9c3885b09..d724fe843980 100644 --- a/drivers/irqchip/irq-ls-extirq.c +++ b/drivers/irqchip/irq-ls-extirq.c @@ -125,32 +125,45 @@ static const struct irq_domain_ops extirq_domain_ops = { static int ls_extirq_parse_map(struct ls_extirq_data *priv, struct device_node *node) { - struct of_imap_parser imap_parser; - struct of_imap_item imap_item; + const __be32 *map; + u32 mapsize; int ret; - ret = of_imap_parser_init(&imap_parser, node, &imap_item); - if (ret) - return ret; + map = of_get_property(node, "interrupt-map", &mapsize); + if (!map) + return -ENOENT; + if (mapsize % sizeof(*map)) + return -EINVAL; + mapsize /= sizeof(*map); - for_each_of_imap_item(&imap_parser, &imap_item) { + while (mapsize) { struct device_node *ipar; - u32 hwirq; - int i; + u32 hwirq, intsize, j; - hwirq = imap_item.child_imap[0]; - if (hwirq >= MAXIRQ) { - of_node_put(imap_item.parent_args.np); + if (mapsize < 3) + return -EINVAL; + hwirq = be32_to_cpup(map); + if (hwirq >= MAXIRQ) return -EINVAL; - } priv->nirq = max(priv->nirq, hwirq + 1); - ipar = of_node_get(imap_item.parent_args.np); - priv->map[hwirq].fwnode = of_fwnode_handle(ipar); + ipar = of_find_node_by_phandle(be32_to_cpup(map + 2)); + map += 3; + mapsize -= 3; + if (!ipar) + return -EINVAL; + priv->map[hwirq].fwnode = &ipar->fwnode; + ret = of_property_read_u32(ipar, "#interrupt-cells", &intsize); + if (ret) + return ret; - priv->map[hwirq].param_count = imap_item.parent_args.args_count; - for (i = 0; i < priv->map[hwirq].param_count; i++) - priv->map[hwirq].param[i] = imap_item.parent_args.args[i]; + if (intsize > mapsize) + return -EINVAL; + + priv->map[hwirq].param_count = intsize; + for (j = 0; j < intsize; ++j) + priv->map[hwirq].param[j] = be32_to_cpup(map++); + mapsize -= intsize; } return 0; } @@ -177,8 +190,10 @@ static int ls_extirq_probe(struct platform_device *pdev) return dev_err_probe(dev, -ENOMEM, "Failed to allocate memory\n"); priv->intpcr = devm_of_iomap(dev, node, 0, NULL); - if (!priv->intpcr) - return dev_err_probe(dev, -ENOMEM, "Cannot ioremap OF node %pOF\n", node); + if (IS_ERR(priv->intpcr)) { + return dev_err_probe(dev, PTR_ERR(priv->intpcr), + "Cannot ioremap OF node %pOF\n", node); + } ret = ls_extirq_parse_map(priv, node); if (ret) diff --git a/drivers/irqchip/irq-ls1x.c b/drivers/irqchip/irq-ls1x.c index 589d32007fca..208f9d4cd99f 100644 --- a/drivers/irqchip/irq-ls1x.c +++ b/drivers/irqchip/irq-ls1x.c @@ -108,7 +108,7 @@ static int __init ls1x_intc_of_init(struct device_node *node, struct ls1x_intc_priv *priv; int parent_irq, err = 0; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c index 31093a8ab67c..be007d325e67 100644 --- a/drivers/irqchip/irq-mchp-eic.c +++ b/drivers/irqchip/irq-mchp-eic.c @@ -209,7 +209,7 @@ static int mchp_eic_probe(struct platform_device *pdev, struct device_node *pare struct irq_domain *parent_domain = NULL; int ret, i; - eic = kzalloc(sizeof(*eic), GFP_KERNEL); + eic = kzalloc_obj(*eic); if (!eic) return -ENOMEM; diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c index 3fcbb044ae60..f722e9c57e2e 100644 --- a/drivers/irqchip/irq-meson-gpio.c +++ b/drivers/irqchip/irq-meson-gpio.c @@ -601,7 +601,7 @@ static int meson_gpio_irq_probe(struct platform_device *pdev, struct device_node return -ENXIO; } - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kzalloc_obj(*ctl); if (!ctl) return -ENOMEM; diff --git a/drivers/irqchip/irq-mips-cpu.c b/drivers/irqchip/irq-mips-cpu.c index ac784ef3ed4b..c5ae8920acda 100644 --- a/drivers/irqchip/irq-mips-cpu.c +++ b/drivers/irqchip/irq-mips-cpu.c @@ -237,7 +237,7 @@ static void mips_cpu_register_ipi_domain(struct device_node *of_node) { struct cpu_ipi_domain_state *ipi_domain_state; - ipi_domain_state = kzalloc(sizeof(*ipi_domain_state), GFP_KERNEL); + ipi_domain_state = kzalloc_obj(*ipi_domain_state); ipi_domain = irq_domain_create_hierarchy(irq_domain, IRQ_DOMAIN_FLAG_IPI_SINGLE, 2, of_fwnode_handle(of_node), &mips_cpu_ipi_chip_ops, ipi_domain_state); diff --git a/drivers/irqchip/irq-mmp.c b/drivers/irqchip/irq-mmp.c index 09e640430208..8e210cb451be 100644 --- a/drivers/irqchip/irq-mmp.c +++ b/drivers/irqchip/irq-mmp.c @@ -136,7 +136,7 @@ static void icu_unmask_irq(struct irq_data *d) } } -struct irq_chip icu_irq_chip = { +static const struct irq_chip icu_irq_chip = { .name = "icu_irq", .irq_mask = icu_mask_irq, .irq_mask_ack = icu_mask_ack_irq, diff --git a/drivers/irqchip/irq-mst-intc.c b/drivers/irqchip/irq-mst-intc.c index 7f760f555a76..b5335f6fd6d6 100644 --- a/drivers/irqchip/irq-mst-intc.c +++ b/drivers/irqchip/irq-mst-intc.c @@ -263,7 +263,7 @@ static int __init mst_intc_of_init(struct device_node *dn, of_property_read_u32_index(dn, "mstar,irqs-map-range", 1, &irq_end)) return -EINVAL; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) return -ENOMEM; diff --git a/drivers/irqchip/irq-mtk-cirq.c b/drivers/irqchip/irq-mtk-cirq.c index 9571f622774e..914d1d639fe3 100644 --- a/drivers/irqchip/irq-mtk-cirq.c +++ b/drivers/irqchip/irq-mtk-cirq.c @@ -311,7 +311,7 @@ static int __init mtk_cirq_of_init(struct device_node *node, return -EINVAL; } - cirq_data = kzalloc(sizeof(*cirq_data), GFP_KERNEL); + cirq_data = kzalloc_obj(*cirq_data); if (!cirq_data) return -ENOMEM; diff --git a/drivers/irqchip/irq-mtk-sysirq.c b/drivers/irqchip/irq-mtk-sysirq.c index 6895e7096b27..50f88293b4cc 100644 --- a/drivers/irqchip/irq-mtk-sysirq.c +++ b/drivers/irqchip/irq-mtk-sysirq.c @@ -133,7 +133,7 @@ static int __init mtk_sysirq_of_init(struct device_node *node, return -EINVAL; } - chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); + chip_data = kzalloc_obj(*chip_data); if (!chip_data) return -ENOMEM; @@ -154,9 +154,8 @@ static int __init mtk_sysirq_of_init(struct device_node *node, goto out_free_chip; } - chip_data->intpol_bases = kcalloc(nr_intpol_bases, - sizeof(*chip_data->intpol_bases), - GFP_KERNEL); + chip_data->intpol_bases = kzalloc_objs(*chip_data->intpol_bases, + nr_intpol_bases); if (!chip_data->intpol_bases) { ret = -ENOMEM; goto out_free_intpol_words; diff --git a/drivers/irqchip/irq-mvebu-odmi.c b/drivers/irqchip/irq-mvebu-odmi.c index e5b2bde3d933..b99ab9dcc14b 100644 --- a/drivers/irqchip/irq-mvebu-odmi.c +++ b/drivers/irqchip/irq-mvebu-odmi.c @@ -178,7 +178,7 @@ static int __init mvebu_odmi_init(struct device_node *node, if (of_property_read_u32(node, "marvell,odmi-frames", &odmis_count)) return -EINVAL; - odmis = kcalloc(odmis_count, sizeof(struct odmi_data), GFP_KERNEL); + odmis = kzalloc_objs(struct odmi_data, odmis_count); if (!odmis) return -ENOMEM; diff --git a/drivers/irqchip/irq-owl-sirq.c b/drivers/irqchip/irq-owl-sirq.c index 3d93d21f6732..cf14780488be 100644 --- a/drivers/irqchip/irq-owl-sirq.c +++ b/drivers/irqchip/irq-owl-sirq.c @@ -288,7 +288,7 @@ static int __init owl_sirq_init(const struct owl_sirq_params *params, return -ENXIO; } - chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); + chip_data = kzalloc_obj(*chip_data); if (!chip_data) return -ENOMEM; diff --git a/drivers/irqchip/irq-pic32-evic.c b/drivers/irqchip/irq-pic32-evic.c index 5dfda8e8df10..e85c3e300701 100644 --- a/drivers/irqchip/irq-pic32-evic.c +++ b/drivers/irqchip/irq-pic32-evic.c @@ -13,10 +13,10 @@ #include #include #include +#include #include #include -#include #define REG_INTCON 0x0000 #define REG_INTSTAT 0x0020 @@ -221,7 +221,7 @@ static int __init pic32_of_init(struct device_node *node, if (!evic_base) return -ENOMEM; - priv = kcalloc(nchips, sizeof(*priv), GFP_KERNEL); + priv = kzalloc_objs(*priv, nchips); if (!priv) { ret = -ENOMEM; goto err_iounmap; diff --git a/drivers/irqchip/irq-riscv-aplic-main.c b/drivers/irqchip/irq-riscv-aplic-main.c index 4495ca26abf5..9f53979b6962 100644 --- a/drivers/irqchip/irq-riscv-aplic-main.c +++ b/drivers/irqchip/irq-riscv-aplic-main.c @@ -116,6 +116,16 @@ static struct syscore aplic_syscore = { .ops = &aplic_syscore_ops, }; +static bool aplic_syscore_registered __ro_after_init; + +static void aplic_syscore_init(void) +{ + if (!aplic_syscore_registered) { + register_syscore(&aplic_syscore); + aplic_syscore_registered = true; + } +} + static int aplic_pm_notifier(struct notifier_block *nb, unsigned long action, void *data) { struct aplic_priv *priv = container_of(nb, struct aplic_priv, genpd_nb); @@ -372,18 +382,21 @@ static int aplic_probe(struct platform_device *pdev) rc = aplic_msi_setup(dev, regs); else rc = aplic_direct_setup(dev, regs); - if (rc) + + if (rc) { dev_err_probe(dev, rc, "failed to setup APLIC in %s mode\n", msi_mode ? "MSI" : "direct"); - else - register_syscore(&aplic_syscore); + return rc; + } + + aplic_syscore_init(); #ifdef CONFIG_ACPI if (!acpi_disabled) acpi_dev_clear_dependencies(ACPI_COMPANION(dev)); #endif - return rc; + return 0; } static const struct of_device_id aplic_match[] = { diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip/irq-riscv-imsic-state.c index 7566c8aa2d48..e3ed874d89e7 100644 --- a/drivers/irqchip/irq-riscv-imsic-state.c +++ b/drivers/irqchip/irq-riscv-imsic-state.c @@ -512,8 +512,8 @@ static int __init imsic_local_init(void) #endif /* Allocate vector array */ - lpriv->vectors = kcalloc(global->nr_ids + 1, sizeof(*lpriv->vectors), - GFP_KERNEL); + lpriv->vectors = kzalloc_objs(*lpriv->vectors, + global->nr_ids + 1); if (!lpriv->vectors) goto fail_local_cleanup; @@ -810,7 +810,7 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque) return -ENODEV; } - imsic = kzalloc(sizeof(*imsic), GFP_KERNEL); + imsic = kzalloc_obj(*imsic); if (!imsic) return -ENOMEM; imsic->fwnode = fwnode; @@ -828,14 +828,14 @@ int __init imsic_setup_state(struct fwnode_handle *fwnode, void *opaque) goto out_free_local; /* Allocate MMIO resource array */ - mmios = kcalloc(nr_mmios, sizeof(*mmios), GFP_KERNEL); + mmios = kzalloc_objs(*mmios, nr_mmios); if (!mmios) { rc = -ENOMEM; goto out_free_local; } /* Allocate MMIO virtual address array */ - mmios_va = kcalloc(nr_mmios, sizeof(*mmios_va), GFP_KERNEL); + mmios_va = kzalloc_objs(*mmios_va, nr_mmios); if (!mmios_va) { rc = -ENOMEM; goto out_iounmap; diff --git a/drivers/irqchip/irq-riscv-intc.c b/drivers/irqchip/irq-riscv-intc.c index 70290b35b317..84418dbd5a27 100644 --- a/drivers/irqchip/irq-riscv-intc.c +++ b/drivers/irqchip/irq-riscv-intc.c @@ -349,13 +349,13 @@ static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, if (count <= 0) return -EINVAL; - rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL); + rintc_acpi_data = kzalloc_objs(*rintc_acpi_data, count); if (!rintc_acpi_data) return -ENOMEM; } rintc = (struct acpi_madt_rintc *)header; - rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); + rintc_acpi_data[nr_rintc] = kzalloc_obj(*rintc_acpi_data[0]); if (!rintc_acpi_data[nr_rintc]) return -ENOMEM; diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c index 60fd8f91762b..5b0dac104814 100644 --- a/drivers/irqchip/irq-sifive-plic.c +++ b/drivers/irqchip/irq-sifive-plic.c @@ -172,8 +172,13 @@ static void plic_irq_disable(struct irq_data *d) static void plic_irq_eoi(struct irq_data *d) { struct plic_handler *handler = this_cpu_ptr(&plic_handlers); + u32 __iomem *reg; + bool enabled; - if (unlikely(irqd_irq_disabled(d))) { + reg = handler->enable_base + (d->hwirq / 32) * sizeof(u32); + enabled = readl(reg) & BIT(d->hwirq % 32); + + if (unlikely(!enabled)) { plic_toggle(handler, d->hwirq, 1); writel(d->hwirq, handler->hart_base + CONTEXT_CLAIM); plic_toggle(handler, d->hwirq, 0); @@ -640,7 +645,7 @@ static int plic_probe(struct fwnode_handle *fwnode) if (error) goto fail_free_regs; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { error = -ENOMEM; goto fail_free_regs; diff --git a/drivers/irqchip/irq-sni-exiu.c b/drivers/irqchip/irq-sni-exiu.c index 0cad68aa8388..bfd2adedf8f3 100644 --- a/drivers/irqchip/irq-sni-exiu.c +++ b/drivers/irqchip/irq-sni-exiu.c @@ -199,7 +199,7 @@ static struct exiu_irq_data *exiu_init(const struct fwnode_handle *fwnode, struct exiu_irq_data *data; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c index 705361b4ebe0..bb62ef363d0b 100644 --- a/drivers/irqchip/irq-starfive-jh8100-intc.c +++ b/drivers/irqchip/irq-starfive-jh8100-intc.c @@ -123,7 +123,7 @@ static int starfive_intc_probe(struct platform_device *pdev, struct device_node int parent_irq; int ret; - irqc = kzalloc(sizeof(*irqc), GFP_KERNEL); + irqc = kzalloc_obj(*irqc); if (!irqc) return -ENOMEM; diff --git a/drivers/irqchip/irq-stm32-exti.c b/drivers/irqchip/irq-stm32-exti.c index 978811f2abe8..5fdf335acb46 100644 --- a/drivers/irqchip/irq-stm32-exti.c +++ b/drivers/irqchip/irq-stm32-exti.c @@ -269,14 +269,13 @@ stm32_exti_host_data *stm32_exti_host_init(const struct stm32_exti_drv_data *dd, { struct stm32_exti_host_data *host_data; - host_data = kzalloc(sizeof(*host_data), GFP_KERNEL); + host_data = kzalloc_obj(*host_data); if (!host_data) return NULL; host_data->drv_data = dd; - host_data->chips_data = kcalloc(dd->bank_nr, - sizeof(struct stm32_exti_chip_data), - GFP_KERNEL); + host_data->chips_data = kzalloc_objs(struct stm32_exti_chip_data, + dd->bank_nr); if (!host_data->chips_data) goto free_host_data; diff --git a/drivers/irqchip/irq-sun4i.c b/drivers/irqchip/irq-sun4i.c index 9c2c9caeca2a..b095d45da75d 100644 --- a/drivers/irqchip/irq-sun4i.c +++ b/drivers/irqchip/irq-sun4i.c @@ -146,7 +146,7 @@ static int __init sun4i_of_init(struct device_node *node, static int __init sun4i_ic_of_init(struct device_node *node, struct device_node *parent) { - irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL); + irq_ic_data = kzalloc_obj(struct sun4i_irq_chip_data); if (!irq_ic_data) return -ENOMEM; @@ -161,7 +161,7 @@ IRQCHIP_DECLARE(allwinner_sun4i_ic, "allwinner,sun4i-a10-ic", sun4i_ic_of_init); static int __init suniv_ic_of_init(struct device_node *node, struct device_node *parent) { - irq_ic_data = kzalloc(sizeof(struct sun4i_irq_chip_data), GFP_KERNEL); + irq_ic_data = kzalloc_obj(struct sun4i_irq_chip_data); if (!irq_ic_data) return -ENOMEM; diff --git a/drivers/irqchip/irq-tegra.c b/drivers/irqchip/irq-tegra.c index b6382cf6359a..b449e9cc4034 100644 --- a/drivers/irqchip/irq-tegra.c +++ b/drivers/irqchip/irq-tegra.c @@ -302,7 +302,7 @@ static int __init tegra_ictlr_init(struct device_node *node, soc = match->data; - lic = kzalloc(sizeof(*lic), GFP_KERNEL); + lic = kzalloc_obj(*lic); if (!lic) return -ENOMEM; diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c index 01963d36cfaf..f1eb2f92f0ca 100644 --- a/drivers/irqchip/irq-ti-sci-inta.c +++ b/drivers/irqchip/irq-ti-sci-inta.c @@ -222,7 +222,7 @@ static struct ti_sci_inta_vint_desc *ti_sci_inta_alloc_parent_irq(struct irq_dom goto free_vint; } - vint_desc = kzalloc(sizeof(*vint_desc), GFP_KERNEL); + vint_desc = kzalloc_obj(*vint_desc); if (!vint_desc) { ret = -ENOMEM; goto free_vint; diff --git a/drivers/irqchip/irq-vf610-mscm-ir.c b/drivers/irqchip/irq-vf610-mscm-ir.c index 5d9c7503aa7f..415a54b27566 100644 --- a/drivers/irqchip/irq-vf610-mscm-ir.c +++ b/drivers/irqchip/irq-vf610-mscm-ir.c @@ -188,7 +188,7 @@ static int __init vf610_mscm_ir_of_init(struct device_node *node, return -EINVAL; } - mscm_ir_data = kzalloc(sizeof(*mscm_ir_data), GFP_KERNEL); + mscm_ir_data = kzalloc_obj(*mscm_ir_data); if (!mscm_ir_data) return -ENOMEM; diff --git a/drivers/irqchip/irq-vt8500.c b/drivers/irqchip/irq-vt8500.c index 3b742590aec8..b159e17ed1df 100644 --- a/drivers/irqchip/irq-vt8500.c +++ b/drivers/irqchip/irq-vt8500.c @@ -203,7 +203,7 @@ static int __init vt8500_irq_init(struct device_node *node, struct vt8500_irq_data *intc; int irq, i, ret = 0; - intc = kzalloc(sizeof(*intc), GFP_KERNEL); + intc = kzalloc_obj(*intc); if (!intc) return -ENOMEM; diff --git a/drivers/irqchip/irq-wpcm450-aic.c b/drivers/irqchip/irq-wpcm450-aic.c index a8ed4894d29e..be585ab0306b 100644 --- a/drivers/irqchip/irq-wpcm450-aic.c +++ b/drivers/irqchip/irq-wpcm450-aic.c @@ -139,7 +139,7 @@ static int __init wpcm450_aic_of_init(struct device_node *node, if (parent) return -EINVAL; - aic = kzalloc(sizeof(*aic), GFP_KERNEL); + aic = kzalloc_obj(*aic); if (!aic) return -ENOMEM; diff --git a/drivers/irqchip/irq-xilinx-intc.c b/drivers/irqchip/irq-xilinx-intc.c index 92dcb9fdcb25..bba6f6dc405e 100644 --- a/drivers/irqchip/irq-xilinx-intc.c +++ b/drivers/irqchip/irq-xilinx-intc.c @@ -171,7 +171,7 @@ static int __init xilinx_intc_of_init(struct device_node *intc, struct xintc_irq_chip *irqc; int ret, irq; - irqc = kzalloc(sizeof(*irqc), GFP_KERNEL); + irqc = kzalloc_obj(*irqc); if (!irqc) return -ENOMEM; irqc->base = of_iomap(intc, 0); diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c index 518f7f0f3dab..32b77fa93f73 100644 --- a/drivers/irqchip/qcom-pdc.c +++ b/drivers/irqchip/qcom-pdc.c @@ -318,7 +318,7 @@ static int pdc_setup_pin_mapping(struct device_node *np) return -EINVAL; pdc_region_cnt = n / 3; - pdc_region = kcalloc(pdc_region_cnt, sizeof(*pdc_region), GFP_KERNEL); + pdc_region = kzalloc_objs(*pdc_region, pdc_region_cnt); if (!pdc_region) { pdc_region_cnt = 0; return -ENOMEM; diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 78e6e7748fb9..aa28b1d32c4e 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -148,7 +148,7 @@ static int capiminor_add_ack(struct capiminor *mp, u16 datahandle) { struct ackqueue_entry *n; - n = kmalloc(sizeof(*n), GFP_ATOMIC); + n = kmalloc_obj(*n, GFP_ATOMIC); if (unlikely(!n)) { printk(KERN_ERR "capi: alloc datahandle failed\n"); return -1; @@ -215,7 +215,7 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) struct device *dev; unsigned int minor; - mp = kzalloc(sizeof(*mp), GFP_KERNEL); + mp = kzalloc_obj(*mp); if (!mp) { printk(KERN_ERR "capi: can't alloc capiminor\n"); return NULL; @@ -341,7 +341,7 @@ static struct capincci *capincci_alloc(struct capidev *cdev, u32 ncci) { struct capincci *np; - np = kzalloc(sizeof(*np), GFP_KERNEL); + np = kzalloc_obj(*np); if (!np) return NULL; np->ncci = ncci; @@ -981,7 +981,7 @@ static int capi_open(struct inode *inode, struct file *file) { struct capidev *cdev; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return -ENOMEM; @@ -1259,8 +1259,7 @@ static int __init capinc_tty_init(void) if (capi_ttyminors <= 0) capi_ttyminors = CAPINC_NR_PORTS; - capiminors = kcalloc(capi_ttyminors, sizeof(struct capiminor *), - GFP_KERNEL); + capiminors = kzalloc_objs(struct capiminor *, capi_ttyminors); if (!capiminors) return -ENOMEM; diff --git a/drivers/isdn/capi/capiutil.c b/drivers/isdn/capi/capiutil.c index d7ae42edc4a8..eec9b36343b7 100644 --- a/drivers/isdn/capi/capiutil.c +++ b/drivers/isdn/capi/capiutil.c @@ -538,7 +538,7 @@ static _cdebbuf *cdebbuf_alloc(void) cdb = g_debbuf; goto init; } else - cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC); + cdb = kmalloc_obj(_cdebbuf, GFP_ATOMIC); if (!cdb) return NULL; cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC); @@ -592,7 +592,7 @@ _cdebbuf *capi_message2str(u8 *msg) if (likely(cdb == g_debbuf)) cmsg = g_cmsg; else - cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC); + cmsg = kmalloc_obj(_cmsg, GFP_ATOMIC); if (unlikely(!cmsg)) { cdebbuf_free(cdb); return NULL; @@ -618,10 +618,10 @@ _cdebbuf *capi_message2str(u8 *msg) int __init cdebug_init(void) { - g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL); + g_cmsg = kmalloc_obj(_cmsg); if (!g_cmsg) return -ENOMEM; - g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); + g_debbuf = kmalloc_obj(_cdebbuf); if (!g_debbuf) { kfree(g_cmsg); return -ENOMEM; diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index e8f7e52354bc..f9fa17d68095 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -253,7 +253,7 @@ static void do_notify_work(struct work_struct *work) static int notify_push(unsigned int event_type, u32 controller) { - struct capictr_event *event = kmalloc(sizeof(*event), GFP_ATOMIC); + struct capictr_event *event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return -ENOMEM; diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index 044e4961376c..55e0b9efa194 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c @@ -1090,7 +1090,7 @@ fritzpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err = -ENOMEM; struct fritzcard *card; - card = kzalloc(sizeof(struct fritzcard), GFP_KERNEL); + card = kzalloc_obj(struct fritzcard); if (!card) { pr_info("No kmem for fritzcard\n"); return err; diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index f6c27ca92c01..b3d28976b33a 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c @@ -4777,7 +4777,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt) char name[MISDN_MAX_IDLEN]; int bcount = 0; - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); + dch = kzalloc_obj(struct dchannel); if (!dch) return -ENOMEM; dch->debug = debug; @@ -4795,7 +4795,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m, int pt) for (ch = 1; ch <= 31; ch++) { if (!((1 << ch) & hc->bmask[pt])) /* skip unused channel */ continue; - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); + bch = kzalloc_obj(struct bchannel); if (!bch) { printk(KERN_ERR "%s: no memory for bchannel\n", __func__); @@ -4850,7 +4850,7 @@ init_multi_port(struct hfc_multi *hc, int pt) int ch, i, ret = 0; char name[MISDN_MAX_IDLEN]; - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); + dch = kzalloc_obj(struct dchannel); if (!dch) return -ENOMEM; dch->debug = debug; @@ -4868,7 +4868,7 @@ init_multi_port(struct hfc_multi *hc, int pt) hc->chan[i + 2].port = pt; hc->chan[i + 2].nt_timer = -1; for (ch = 0; ch < dch->dev.nrbchan; ch++) { - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); + bch = kzalloc_obj(struct bchannel); if (!bch) { printk(KERN_ERR "%s: no memory for bchannel\n", __func__); @@ -4991,7 +4991,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, type[HFC_cnt]); /* allocate card+fifo structure */ - hc = kzalloc(sizeof(struct hfc_multi), GFP_KERNEL); + hc = kzalloc_obj(struct hfc_multi); if (!hc) { printk(KERN_ERR "No kmem for HFC-Multi card\n"); return -ENOMEM; diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index ea8a0ab47afd..554a1c640321 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -2225,7 +2225,7 @@ hfc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct hfc_pci *card; struct _hfc_map *m = (struct _hfc_map *)ent->driver_data; - card = kzalloc(sizeof(struct hfc_pci), GFP_KERNEL); + card = kzalloc_obj(struct hfc_pci); if (!card) { printk(KERN_ERR "No kmem for HFC card\n"); return err; diff --git a/drivers/isdn/hardware/mISDN/hfcsusb.c b/drivers/isdn/hardware/mISDN/hfcsusb.c index 541a20cb58f1..227babe83879 100644 --- a/drivers/isdn/hardware/mISDN/hfcsusb.c +++ b/drivers/isdn/hardware/mISDN/hfcsusb.c @@ -249,7 +249,7 @@ hfcsusb_ph_info(struct hfcsusb *hw) struct dchannel *dch = &hw->dch; int i; - phi = kzalloc(struct_size(phi, bch, dch->dev.nrbchan), GFP_ATOMIC); + phi = kzalloc_flex(*phi, bch, dch->dev.nrbchan, GFP_ATOMIC); if (!phi) return -ENOMEM; @@ -1696,7 +1696,7 @@ hfcsusb_stop_endpoint(struct hfcsusb *hw, int channel) static int setup_hfcsusb(struct hfcsusb *hw) { - void *dmabuf = kmalloc(sizeof(u_char), GFP_KERNEL); + void *dmabuf = kmalloc_obj(u_char); u_char b; int ret; @@ -2018,7 +2018,7 @@ hfcsusb_probe(struct usb_interface *intf, const struct usb_device_id *id) return -EIO; iface = iface_used; - hw = kzalloc(sizeof(struct hfcsusb), GFP_KERNEL); + hw = kzalloc_obj(struct hfcsusb); if (!hw) return -ENOMEM; /* got no mem */ snprintf(hw->name, MISDN_MAX_IDLEN - 1, "%s", DRIVER_NAME); diff --git a/drivers/isdn/hardware/mISDN/mISDNinfineon.c b/drivers/isdn/hardware/mISDN/mISDNinfineon.c index 30876a012711..aaa639ad5526 100644 --- a/drivers/isdn/hardware/mISDN/mISDNinfineon.c +++ b/drivers/isdn/hardware/mISDN/mISDNinfineon.c @@ -1074,7 +1074,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) int err = -ENOMEM; struct inf_hw *card; - card = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); + card = kzalloc_obj(struct inf_hw); if (!card) { pr_info("No memory for Infineon ISDN card\n"); return err; @@ -1108,7 +1108,7 @@ inf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct inf_hw *sc; for (i = 1; i < 4; i++) { - sc = kzalloc(sizeof(struct inf_hw), GFP_KERNEL); + sc = kzalloc_obj(struct inf_hw); if (!sc) { release_card(card); pci_disable_device(pdev); diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index d163850c295e..8d740d8eacec 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c @@ -1070,7 +1070,7 @@ nj_probe(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENODEV; } - card = kzalloc(sizeof(struct tiger_hw), GFP_KERNEL); + card = kzalloc_obj(struct tiger_hw); if (!card) { pr_info("No kmem for Netjet\n"); return err; diff --git a/drivers/isdn/hardware/mISDN/speedfax.c b/drivers/isdn/hardware/mISDN/speedfax.c index 0c405261d940..ab24c3c460e6 100644 --- a/drivers/isdn/hardware/mISDN/speedfax.c +++ b/drivers/isdn/hardware/mISDN/speedfax.c @@ -443,7 +443,7 @@ static int sfaxpci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = -ENOMEM; - struct sfax_hw *card = kzalloc(sizeof(struct sfax_hw), GFP_KERNEL); + struct sfax_hw *card = kzalloc_obj(struct sfax_hw); if (!card) { pr_info("No memory for Speedfax+ PCI\n"); diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 168fc345dcdc..a341470c042f 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c @@ -1342,7 +1342,7 @@ w6692_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct w6692_hw *card; struct w6692map *m = (struct w6692map *)ent->driver_data; - card = kzalloc(sizeof(struct w6692_hw), GFP_KERNEL); + card = kzalloc_obj(struct w6692_hw); if (!card) { pr_info("No kmem for w6692 card\n"); return err; diff --git a/drivers/isdn/mISDN/clock.c b/drivers/isdn/mISDN/clock.c index f71eb61db131..2668be9de20a 100644 --- a/drivers/isdn/mISDN/clock.c +++ b/drivers/isdn/mISDN/clock.c @@ -91,7 +91,7 @@ struct mISDNclock if (*debug & (DEBUG_CORE | DEBUG_CLOCK)) printk(KERN_DEBUG "%s: %s %d\n", __func__, name, pri); - iclock = kzalloc(sizeof(struct mISDNclock), GFP_ATOMIC); + iclock = kzalloc_obj(struct mISDNclock, GFP_ATOMIC); if (!iclock) { printk(KERN_ERR "%s: No memory for clock entry.\n", __func__); return NULL; diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index 53fad9487574..d5eb2349c414 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -226,7 +226,7 @@ dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf) return -EINVAL; } - member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC); + member = kzalloc_obj(struct dsp_conf_member, GFP_ATOMIC); if (!member) { printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n"); return -ENOMEM; @@ -305,7 +305,7 @@ static struct dsp_conf return NULL; } - conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC); + conf = kzalloc_obj(struct dsp_conf, GFP_ATOMIC); if (!conf) { printk(KERN_ERR "kzalloc struct dsp_conf failed\n"); return NULL; diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c index b4ed0bb8ddfb..55693dc7206b 100644 --- a/drivers/isdn/mISDN/dsp_pipeline.c +++ b/drivers/isdn/mISDN/dsp_pipeline.c @@ -75,7 +75,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem) if (!elem) return -EINVAL; - entry = kzalloc(sizeof(struct dsp_element_entry), GFP_ATOMIC); + entry = kzalloc_obj(struct dsp_element_entry, GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -223,8 +223,8 @@ int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg) if (!strcmp(entry->elem->name, name)) { elem = entry->elem; - pipeline_entry = kmalloc(sizeof(struct - dsp_pipeline_entry), GFP_ATOMIC); + pipeline_entry = kmalloc_obj(struct dsp_pipeline_entry, + GFP_ATOMIC); if (!pipeline_entry) { printk(KERN_ERR "%s: failed to add " "entry to pipeline: %s (out of " diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 6ab036e4a35f..6866a0d6b382 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -1370,7 +1370,7 @@ init_card(struct l1oip *hc, int pri, int bundle) (hc->remoteip >> 8) & 0xff, hc->remoteip & 0xff, hc->remoteport, hc->ondemand); - dch = kzalloc(sizeof(struct dchannel), GFP_KERNEL); + dch = kzalloc_obj(struct dchannel); if (!dch) return -ENOMEM; dch->debug = debug; @@ -1391,7 +1391,7 @@ init_card(struct l1oip *hc, int pri, int bundle) for (ch = 0; ch < dch->dev.nrbchan; ch++) { if (ch == 15) i++; - bch = kzalloc(sizeof(struct bchannel), GFP_KERNEL); + bch = kzalloc_obj(struct bchannel); if (!bch) { printk(KERN_ERR "%s: no memory for bchannel\n", __func__); @@ -1477,7 +1477,7 @@ l1oip_init(void) bundle ? "bundled IP packet for all B-channels" : "separate IP packets for every B-channel"); - hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC); + hc = kzalloc_obj(struct l1oip, GFP_ATOMIC); if (!hc) { printk(KERN_ERR "No kmem for L1-over-IP driver.\n"); l1oip_cleanup(); diff --git a/drivers/isdn/mISDN/layer1.c b/drivers/isdn/mISDN/layer1.c index 7b31c25a550e..3fbc170acf9a 100644 --- a/drivers/isdn/mISDN/layer1.c +++ b/drivers/isdn/mISDN/layer1.c @@ -374,7 +374,7 @@ int create_l1(struct dchannel *dch, dchannel_l1callback *dcb) { struct layer1 *nl1; - nl1 = kzalloc(sizeof(struct layer1), GFP_ATOMIC); + nl1 = kzalloc_obj(struct layer1, GFP_ATOMIC); if (!nl1) { printk(KERN_ERR "kmalloc struct layer1 failed\n"); return -ENOMEM; diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index 5bf7fcb282c4..b75869c9f78f 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c @@ -2111,7 +2111,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, struct layer2 *l2; struct channel_req rq; - l2 = kzalloc(sizeof(struct layer2), GFP_KERNEL); + l2 = kzalloc_obj(struct layer2); if (!l2) { printk(KERN_ERR "kzalloc layer2 failed\n"); return NULL; diff --git a/drivers/isdn/mISDN/stack.c b/drivers/isdn/mISDN/stack.c index c2f76f398613..4e96684af0aa 100644 --- a/drivers/isdn/mISDN/stack.c +++ b/drivers/isdn/mISDN/stack.c @@ -366,7 +366,7 @@ create_stack(struct mISDNdevice *dev) int err; DECLARE_COMPLETION_ONSTACK(done); - newst = kzalloc(sizeof(struct mISDNstack), GFP_KERNEL); + newst = kzalloc_obj(struct mISDNstack); if (!newst) { printk(KERN_ERR "kmalloc mISDN_stack failed\n"); return -ENOMEM; diff --git a/drivers/isdn/mISDN/tei.c b/drivers/isdn/mISDN/tei.c index 59d28cb19738..2bad3083be90 100644 --- a/drivers/isdn/mISDN/tei.c +++ b/drivers/isdn/mISDN/tei.c @@ -803,7 +803,7 @@ create_new_tei(struct manager *mgr, int tei, int sapi) printk(KERN_WARNING "%s:no memory for layer2\n", __func__); return NULL; } - l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); + l2->tm = kzalloc_obj(struct teimgr); if (!l2->tm) { kfree(l2); printk(KERN_WARNING "%s:no memory for teimgr\n", __func__); @@ -1046,7 +1046,7 @@ create_teimgr(struct manager *mgr, struct channel_req *crq) crq->adr.tei, crq->adr.sapi); if (!l2) return -ENOMEM; - l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL); + l2->tm = kzalloc_obj(struct teimgr); if (!l2->tm) { kfree(l2); printk(KERN_ERR "kmalloc teimgr failed\n"); @@ -1345,7 +1345,7 @@ create_teimanager(struct mISDNdevice *dev) { struct manager *mgr; - mgr = kzalloc(sizeof(struct manager), GFP_KERNEL); + mgr = kzalloc_obj(struct manager); if (!mgr) return -ENOMEM; INIT_LIST_HEAD(&mgr->layer2); diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index 33521c328a82..a18845755633 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -47,7 +47,7 @@ mISDN_open(struct inode *ino, struct file *filep) if (*debug & DEBUG_TIMER) printk(KERN_DEBUG "%s(%p,%p)\n", __func__, ino, filep); - dev = kmalloc(sizeof(struct mISDNtimerdev) , GFP_KERNEL); + dev = kmalloc_obj(struct mISDNtimerdev); if (!dev) return -ENOMEM; dev->next_id = 1; @@ -179,7 +179,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) wake_up_interruptible(&dev->wait); id = 0; } else { - timer = kzalloc(sizeof(struct mISDNtimer), GFP_KERNEL); + timer = kzalloc_obj(struct mISDNtimer); if (!timer) return -ENOMEM; timer->dev = dev; diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 11e7282dc297..597d7a79c988 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -107,6 +107,19 @@ config LEDS_ARIEL Say Y to if your machine is a Dell Wyse 3020 thin client. +config LEDS_OSRAM_AMS_AS3668 + tristate "LED support for Osram AMS AS3668" + depends on LEDS_CLASS + depends on I2C + help + This option enables support for the Osram AMS AS3668 LED controller. + The AS3668 provides up to four LED channels and is controlled via + the I2C bus. This driver offers basic brightness control for each + channel, without support for blinking or other advanced features. + + To compile this driver as a module, choose M here: the module + will be called leds-as3668. + config LEDS_AW200XX tristate "LED support for Awinic AW20036/AW20054/AW20072/AW20108" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 9a0333ec1a86..8fdb45d5b439 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -15,6 +15,7 @@ obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o obj-$(CONFIG_LEDS_APU) += leds-apu.o obj-$(CONFIG_LEDS_ARIEL) += leds-ariel.o +obj-$(CONFIG_LEDS_AS3668) += leds-as3668.o obj-$(CONFIG_LEDS_AW200XX) += leds-aw200xx.o obj-$(CONFIG_LEDS_AW2013) += leds-aw2013.o obj-$(CONFIG_LEDS_BCM6328) += leds-bcm6328.o diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 3799dcc1cf07..b1223218bda1 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -486,7 +486,7 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp) struct led_trigger *trig; int err; - trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); + trig = kzalloc_obj(struct led_trigger); if (trig) { trig->name = name; diff --git a/drivers/leds/leds-as3668.c b/drivers/leds/leds-as3668.c new file mode 100644 index 000000000000..b2794492370e --- /dev/null +++ b/drivers/leds/leds-as3668.c @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Osram AMS AS3668 LED Driver IC + * + * Copyright (C) 2025 Lukas Timmermann + */ + +#include +#include +#include +#include +#include + +#define AS3668_MAX_LEDS 4 + +/* Chip Ident */ + +#define AS3668_CHIP_ID1_REG 0x3e +#define AS3668_CHIP_ID 0xa5 + +/* Current Control */ + +#define AS3668_CURR_MODE_REG 0x01 +#define AS3668_CURR_MODE_OFF 0x0 +#define AS3668_CURR_MODE_ON 0x1 +#define AS3668_CURR1_MODE_MASK GENMASK(1, 0) +#define AS3668_CURR2_MODE_MASK GENMASK(3, 2) +#define AS3668_CURR3_MODE_MASK GENMASK(5, 4) +#define AS3668_CURR4_MODE_MASK GENMASK(7, 6) +#define AS3668_CURR1_REG 0x02 +#define AS3668_CURR2_REG 0x03 +#define AS3668_CURR3_REG 0x04 +#define AS3668_CURR4_REG 0x05 + +#define AS3668_CURR_MODE_PACK(mode) (((mode) << 0) | \ + ((mode) << 2) | \ + ((mode) << 4) | \ + ((mode) << 6)) + +struct as3668_led { + struct led_classdev cdev; + struct as3668 *chip; + struct fwnode_handle *fwnode; + u8 mode_mask; + u8 current_reg; +}; + +struct as3668 { + struct i2c_client *client; + struct as3668_led leds[AS3668_MAX_LEDS]; +}; + +static int as3668_channel_mode_set(struct as3668_led *led, u8 mode) +{ + int ret; + u8 channel_modes; + + ret = i2c_smbus_read_byte_data(led->chip->client, AS3668_CURR_MODE_REG); + if (ret < 0) { + dev_err(led->cdev.dev, "failed to read channel modes\n"); + return ret; + } + channel_modes = (u8)ret; + + channel_modes &= ~led->mode_mask; + channel_modes |= led->mode_mask & (AS3668_CURR_MODE_PACK(mode)); + + return i2c_smbus_write_byte_data(led->chip->client, AS3668_CURR_MODE_REG, channel_modes); +} + +static enum led_brightness as3668_brightness_get(struct led_classdev *cdev) +{ + struct as3668_led *led = container_of(cdev, struct as3668_led, cdev); + + return i2c_smbus_read_byte_data(led->chip->client, led->current_reg); +} + +static void as3668_brightness_set(struct led_classdev *cdev, enum led_brightness brightness) +{ + struct as3668_led *led = container_of(cdev, struct as3668_led, cdev); + int err; + + err = as3668_channel_mode_set(led, !!brightness); + if (err) + dev_err(cdev->dev, "failed to set channel mode: %d\n", err); + + err = i2c_smbus_write_byte_data(led->chip->client, led->current_reg, brightness); + if (err) + dev_err(cdev->dev, "failed to set brightness: %d\n", err); +} + +static int as3668_dt_init(struct as3668 *as3668) +{ + struct device *dev = &as3668->client->dev; + struct as3668_led *led; + struct led_init_data init_data = {}; + int err; + u32 reg; + + for_each_available_child_of_node_scoped(dev_of_node(dev), child) { + err = of_property_read_u32(child, "reg", ®); + if (err) + return dev_err_probe(dev, err, "failed to read 'reg' property"); + + if (reg < 0 || reg >= AS3668_MAX_LEDS) + return dev_err_probe(dev, -EINVAL, + "unsupported LED: %d\n", reg); + + led = &as3668->leds[reg]; + led->fwnode = of_fwnode_handle(child); + + led->current_reg = reg + AS3668_CURR1_REG; + led->mode_mask = AS3668_CURR1_MODE_MASK << (reg * 2); + led->chip = as3668; + + led->cdev.max_brightness = U8_MAX; + led->cdev.brightness_get = as3668_brightness_get; + led->cdev.brightness_set = as3668_brightness_set; + + init_data.fwnode = led->fwnode; + init_data.default_label = ":"; + + err = devm_led_classdev_register_ext(dev, &led->cdev, &init_data); + if (err) + return dev_err_probe(dev, err, "failed to register LED %d\n", reg); + } + + return 0; +} + +static int as3668_probe(struct i2c_client *client) +{ + struct as3668 *as3668; + int err; + u8 chip_id; + + chip_id = i2c_smbus_read_byte_data(client, AS3668_CHIP_ID1_REG); + if (chip_id != AS3668_CHIP_ID) + return dev_err_probe(&client->dev, -ENODEV, + "expected chip ID 0x%02x, got 0x%02x\n", + AS3668_CHIP_ID, chip_id); + + as3668 = devm_kzalloc(&client->dev, sizeof(*as3668), GFP_KERNEL); + if (!as3668) + return -ENOMEM; + + as3668->client = client; + + err = as3668_dt_init(as3668); + if (err) + return err; + + /* Set all four channel modes to 'off' */ + err = i2c_smbus_write_byte_data(client, AS3668_CURR_MODE_REG, + FIELD_PREP(AS3668_CURR1_MODE_MASK, AS3668_CURR_MODE_OFF) | + FIELD_PREP(AS3668_CURR2_MODE_MASK, AS3668_CURR_MODE_OFF) | + FIELD_PREP(AS3668_CURR3_MODE_MASK, AS3668_CURR_MODE_OFF) | + FIELD_PREP(AS3668_CURR4_MODE_MASK, AS3668_CURR_MODE_OFF)); + + /* Set initial currents to 0mA */ + err |= i2c_smbus_write_byte_data(client, AS3668_CURR1_REG, 0); + err |= i2c_smbus_write_byte_data(client, AS3668_CURR2_REG, 0); + err |= i2c_smbus_write_byte_data(client, AS3668_CURR3_REG, 0); + err |= i2c_smbus_write_byte_data(client, AS3668_CURR4_REG, 0); + + if (err) + return dev_err_probe(&client->dev, -EIO, "failed to set zero initial current levels\n"); + + return 0; +} + +static void as3668_remove(struct i2c_client *client) +{ + i2c_smbus_write_byte_data(client, AS3668_CURR_MODE_REG, 0); +} + +static const struct i2c_device_id as3668_idtable[] = { + { "as3668" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, as3668_idtable); + +static const struct of_device_id as3668_match_table[] = { + { .compatible = "ams,as3668" }, + { } +}; +MODULE_DEVICE_TABLE(of, as3668_match_table); + +static struct i2c_driver as3668_driver = { + .driver = { + .name = "leds_as3668", + .of_match_table = as3668_match_table, + }, + .probe = as3668_probe, + .remove = as3668_remove, + .id_table = as3668_idtable, +}; +module_i2c_driver(as3668_driver); + +MODULE_AUTHOR("Lukas Timmermann "); +MODULE_DESCRIPTION("AS3668 LED driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/leds-expresswire.c b/drivers/leds/leds-expresswire.c index bb69be228a6d..25c6b159a6ee 100644 --- a/drivers/leds/leds-expresswire.c +++ b/drivers/leds/leds-expresswire.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -16,37 +17,41 @@ void expresswire_power_off(struct expresswire_common_props *props) { gpiod_set_value_cansleep(props->ctrl_gpio, 0); - usleep_range(props->timing.poweroff_us, props->timing.poweroff_us * 2); + fsleep(props->timing.poweroff_us); } EXPORT_SYMBOL_NS_GPL(expresswire_power_off, "EXPRESSWIRE"); void expresswire_enable(struct expresswire_common_props *props) { + unsigned long flags; + + local_irq_save(flags); + gpiod_set_value(props->ctrl_gpio, 1); udelay(props->timing.detect_delay_us); gpiod_set_value(props->ctrl_gpio, 0); udelay(props->timing.detect_us); gpiod_set_value(props->ctrl_gpio, 1); + + local_irq_restore(flags); } EXPORT_SYMBOL_NS_GPL(expresswire_enable, "EXPRESSWIRE"); -void expresswire_start(struct expresswire_common_props *props) +static void expresswire_start(struct expresswire_common_props *props) { gpiod_set_value(props->ctrl_gpio, 1); udelay(props->timing.data_start_us); } -EXPORT_SYMBOL_NS_GPL(expresswire_start, "EXPRESSWIRE"); -void expresswire_end(struct expresswire_common_props *props) +static void expresswire_end(struct expresswire_common_props *props) { gpiod_set_value(props->ctrl_gpio, 0); udelay(props->timing.end_of_data_low_us); gpiod_set_value(props->ctrl_gpio, 1); udelay(props->timing.end_of_data_high_us); } -EXPORT_SYMBOL_NS_GPL(expresswire_end, "EXPRESSWIRE"); -void expresswire_set_bit(struct expresswire_common_props *props, bool bit) +static void expresswire_set_bit(struct expresswire_common_props *props, bool bit) { if (bit) { gpiod_set_value(props->ctrl_gpio, 0); @@ -60,13 +65,18 @@ void expresswire_set_bit(struct expresswire_common_props *props, bool bit) udelay(props->timing.short_bitset_us); } } -EXPORT_SYMBOL_NS_GPL(expresswire_set_bit, "EXPRESSWIRE"); void expresswire_write_u8(struct expresswire_common_props *props, u8 val) { + unsigned long flags; + + local_irq_save(flags); + expresswire_start(props); for (int i = 7; i >= 0; i--) expresswire_set_bit(props, val & BIT(i)); expresswire_end(props); + + local_irq_restore(flags); } EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, "EXPRESSWIRE"); diff --git a/drivers/leds/leds-is31fl32xx.c b/drivers/leds/leds-is31fl32xx.c index dc9349f9d350..fe07acbb103a 100644 --- a/drivers/leds/leds-is31fl32xx.c +++ b/drivers/leds/leds-is31fl32xx.c @@ -34,10 +34,26 @@ #define IS31FL32XX_PWM_FREQUENCY_22KHZ 0x01 +/* Registers for IS31FL3293 */ +#define IS31FL3293_SHUTDOWN_REG 0x01 +#define IS31FL3293_SHUTDOWN_SSD_DISABLE BIT(0) +#define IS31FL3293_SHUTDOWN_EN1 BIT(4) +#define IS31FL3293_SHUTDOWN_EN2 BIT(5) +#define IS31FL3293_SHUTDOWN_EN3 BIT(6) +#define IS31FL3293_GCC_REG 0x03 +#define IS31FL3293_GCC_LEVEL_MAX 0x3f +#define IS31FL3293_CL_REG 0x10 +#define IS31FL3293_COLOR_UPDATE_REG 0x27 +#define IS31FL3293_COLOR_UPDATE_MAGIC 0xc5 +#define IS31FL3293_RESET_REG 0x3c +#define IS31FL3293_RESET_MAGIC 0xc5 +#define IS31FL3293_MAX_MICROAMP 20000 + struct is31fl32xx_priv; struct is31fl32xx_led_data { struct led_classdev cdev; u8 channel; /* 1-based, max priv->cdef->channels */ + u32 max_microamp; struct is31fl32xx_priv *priv; }; @@ -53,6 +69,7 @@ struct is31fl32xx_priv { * @channels : Number of LED channels * @shutdown_reg : address of Shutdown register (optional) * @pwm_update_reg : address of PWM Update register + * @pwm_update_value : value to write to PWM Update register * @global_control_reg : address of Global Control register (optional) * @reset_reg : address of Reset register (optional) * @output_frequency_setting_reg: address of output frequency register (optional) @@ -60,6 +77,7 @@ struct is31fl32xx_priv { * @pwm_registers_reversed: : true if PWM registers count down instead of up * @led_control_register_base : address of first LED control register (optional) * @enable_bits_per_led_control_register: number of LEDs enable bits in each + * @brightness_steps : number of brightness steps supported by the chip * @reset_func : pointer to reset function * @sw_shutdown_func : pointer to software shutdown function * @@ -77,6 +95,7 @@ struct is31fl32xx_chipdef { u8 channels; u8 shutdown_reg; u8 pwm_update_reg; + u8 pwm_update_value; u8 global_control_reg; u8 reset_reg; u8 output_frequency_setting_reg; @@ -84,76 +103,11 @@ struct is31fl32xx_chipdef { bool pwm_registers_reversed; u8 led_control_register_base; u8 enable_bits_per_led_control_register; + u16 brightness_steps; int (*reset_func)(struct is31fl32xx_priv *priv); int (*sw_shutdown_func)(struct is31fl32xx_priv *priv, bool enable); }; -static const struct is31fl32xx_chipdef is31fl3236_cdef = { - .channels = 36, - .shutdown_reg = 0x00, - .pwm_update_reg = 0x25, - .global_control_reg = 0x4a, - .reset_reg = 0x4f, - .output_frequency_setting_reg = IS31FL32XX_REG_NONE, - .pwm_register_base = 0x01, - .led_control_register_base = 0x26, - .enable_bits_per_led_control_register = 1, -}; - -static const struct is31fl32xx_chipdef is31fl3236a_cdef = { - .channels = 36, - .shutdown_reg = 0x00, - .pwm_update_reg = 0x25, - .global_control_reg = 0x4a, - .reset_reg = 0x4f, - .output_frequency_setting_reg = 0x4b, - .pwm_register_base = 0x01, - .led_control_register_base = 0x26, - .enable_bits_per_led_control_register = 1, -}; - -static const struct is31fl32xx_chipdef is31fl3235_cdef = { - .channels = 28, - .shutdown_reg = 0x00, - .pwm_update_reg = 0x25, - .global_control_reg = 0x4a, - .reset_reg = 0x4f, - .output_frequency_setting_reg = IS31FL32XX_REG_NONE, - .pwm_register_base = 0x05, - .led_control_register_base = 0x2a, - .enable_bits_per_led_control_register = 1, -}; - -static const struct is31fl32xx_chipdef is31fl3218_cdef = { - .channels = 18, - .shutdown_reg = 0x00, - .pwm_update_reg = 0x16, - .global_control_reg = IS31FL32XX_REG_NONE, - .reset_reg = 0x17, - .output_frequency_setting_reg = IS31FL32XX_REG_NONE, - .pwm_register_base = 0x01, - .led_control_register_base = 0x13, - .enable_bits_per_led_control_register = 6, -}; - -static int is31fl3216_reset(struct is31fl32xx_priv *priv); -static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv, - bool enable); -static const struct is31fl32xx_chipdef is31fl3216_cdef = { - .channels = 16, - .shutdown_reg = IS31FL32XX_REG_NONE, - .pwm_update_reg = 0xB0, - .global_control_reg = IS31FL32XX_REG_NONE, - .reset_reg = IS31FL32XX_REG_NONE, - .output_frequency_setting_reg = IS31FL32XX_REG_NONE, - .pwm_register_base = 0x10, - .pwm_registers_reversed = true, - .led_control_register_base = 0x01, - .enable_bits_per_led_control_register = 8, - .reset_func = is31fl3216_reset, - .sw_shutdown_func = is31fl3216_software_shutdown, -}; - static int is31fl32xx_write(struct is31fl32xx_priv *priv, u8 reg, u8 val) { int ret; @@ -218,6 +172,62 @@ static int is31fl3216_software_shutdown(struct is31fl32xx_priv *priv, return is31fl32xx_write(priv, IS31FL3216_CONFIG_REG, value); } +/* + * Custom Reset function for IS31FL3293. We need to set the global current limit + * and write to the color update register once. + */ +static int is31fl3293_reset(struct is31fl32xx_priv *priv) +{ + int i, ret; + + ret = is31fl32xx_write(priv, IS31FL3293_RESET_REG, + IS31FL3293_RESET_MAGIC); + if (ret) + return ret; + + /* Set the global current limit to maximum */ + ret = is31fl32xx_write(priv, IS31FL3293_GCC_REG, + IS31FL3293_GCC_LEVEL_MAX); + if (ret) + return ret; + + for (i = 0; i < priv->num_leds; i++) { + struct is31fl32xx_led_data *led_data = &priv->leds[i]; + int current_level_reg = IS31FL3293_CL_REG + led_data->channel - 1; + int microamp = max(led_data->max_microamp, IS31FL3293_MAX_MICROAMP); + int current_level = (microamp * 0xff) / IS31FL3293_MAX_MICROAMP; + + ret = is31fl32xx_write(priv, current_level_reg, current_level); + if (ret) + return ret; + } + + ret = is31fl32xx_write(priv, IS31FL3293_COLOR_UPDATE_REG, + IS31FL3293_COLOR_UPDATE_MAGIC); + if (ret) + return ret; + + return 0; +} + +/* + * Custom Software-Shutdown function for IS31FL3293 because the SHUTDOWN + * register of this device also has bits to enable the channels. + */ +static int is31fl3293_software_shutdown(struct is31fl32xx_priv *priv, + bool enable) +{ + u8 value = 0; + + if (!enable) + value = IS31FL3293_SHUTDOWN_SSD_DISABLE | + IS31FL3293_SHUTDOWN_EN1 | + IS31FL3293_SHUTDOWN_EN2 | + IS31FL3293_SHUTDOWN_EN3; + + return is31fl32xx_write(priv, IS31FL3293_SHUTDOWN_REG, value); +} + /* * NOTE: A mutex is not needed in this function because: * - All referenced data is read-only after probe() @@ -256,13 +266,36 @@ static int is31fl32xx_brightness_set(struct led_classdev *led_cdev, else pwm_register_offset = led_data->channel - 1; - ret = is31fl32xx_write(led_data->priv, - cdef->pwm_register_base + pwm_register_offset, - brightness); - if (ret) - return ret; + switch (cdef->brightness_steps) { + case 256: + ret = is31fl32xx_write(led_data->priv, + cdef->pwm_register_base + pwm_register_offset, + brightness); + if (ret) + return ret; - return is31fl32xx_write(led_data->priv, cdef->pwm_update_reg, 0); + break; + case 4096: + /* IS31FL329x devices use two registers to store 12 bits of brightness */ + pwm_register_offset *= 2; + + ret = is31fl32xx_write(led_data->priv, + cdef->pwm_register_base + pwm_register_offset, + brightness & 0xff); + if (ret) + return ret; + + ret = is31fl32xx_write(led_data->priv, + cdef->pwm_register_base + pwm_register_offset + 1, + (brightness >> 8) & 0xf); + if (ret) + return ret; + + break; + } + + return is31fl32xx_write(led_data->priv, cdef->pwm_update_reg, + cdef->pwm_update_value); } static int is31fl32xx_reset_regs(struct is31fl32xx_priv *priv) @@ -361,6 +394,8 @@ static int is31fl32xx_parse_child_dt(const struct device *dev, } led_data->channel = reg; + of_property_read_u32(child, "led-max-microamp", &led_data->max_microamp); + cdev->brightness_set_blocking = is31fl32xx_brightness_set; return 0; @@ -405,6 +440,7 @@ static int is31fl32xx_parse_dt(struct device *dev, const struct is31fl32xx_led_data *other_led_data; led_data->priv = priv; + led_data->cdev.max_brightness = priv->cdef->brightness_steps - 1; ret = is31fl32xx_parse_child_dt(dev, child, led_data); if (ret) @@ -435,8 +471,89 @@ static int is31fl32xx_parse_dt(struct device *dev, return 0; } +static const struct is31fl32xx_chipdef is31fl3236_cdef = { + .channels = 36, + .shutdown_reg = 0x00, + .pwm_update_reg = 0x25, + .global_control_reg = 0x4a, + .reset_reg = 0x4f, + .output_frequency_setting_reg = IS31FL32XX_REG_NONE, + .pwm_register_base = 0x01, + .led_control_register_base = 0x26, + .enable_bits_per_led_control_register = 1, +}; + +static const struct is31fl32xx_chipdef is31fl3236a_cdef = { + .channels = 36, + .shutdown_reg = 0x00, + .pwm_update_reg = 0x25, + .global_control_reg = 0x4a, + .reset_reg = 0x4f, + .output_frequency_setting_reg = 0x4b, + .pwm_register_base = 0x01, + .led_control_register_base = 0x26, + .enable_bits_per_led_control_register = 1, + .brightness_steps = 256, +}; + +static const struct is31fl32xx_chipdef is31fl3235_cdef = { + .channels = 28, + .shutdown_reg = 0x00, + .pwm_update_reg = 0x25, + .global_control_reg = 0x4a, + .reset_reg = 0x4f, + .output_frequency_setting_reg = IS31FL32XX_REG_NONE, + .pwm_register_base = 0x05, + .led_control_register_base = 0x2a, + .enable_bits_per_led_control_register = 1, + .brightness_steps = 256, +}; + +static const struct is31fl32xx_chipdef is31fl3218_cdef = { + .channels = 18, + .shutdown_reg = 0x00, + .pwm_update_reg = 0x16, + .global_control_reg = IS31FL32XX_REG_NONE, + .reset_reg = 0x17, + .output_frequency_setting_reg = IS31FL32XX_REG_NONE, + .pwm_register_base = 0x01, + .led_control_register_base = 0x13, + .enable_bits_per_led_control_register = 6, + .brightness_steps = 256, +}; + +static const struct is31fl32xx_chipdef is31fl3216_cdef = { + .channels = 16, + .shutdown_reg = IS31FL32XX_REG_NONE, + .pwm_update_reg = 0xB0, + .global_control_reg = IS31FL32XX_REG_NONE, + .reset_reg = IS31FL32XX_REG_NONE, + .output_frequency_setting_reg = IS31FL32XX_REG_NONE, + .pwm_register_base = 0x10, + .pwm_registers_reversed = true, + .led_control_register_base = 0x01, + .enable_bits_per_led_control_register = 8, + .reset_func = is31fl3216_reset, + .sw_shutdown_func = is31fl3216_software_shutdown, + .brightness_steps = 256, +}; + +static const struct is31fl32xx_chipdef is31fl3293_cdef = { + .channels = 3, + .shutdown_reg = IS31FL32XX_REG_NONE, + .pwm_update_reg = 0x28, + .pwm_update_value = 0xc5, + .global_control_reg = IS31FL32XX_REG_NONE, + .reset_reg = IS31FL32XX_REG_NONE, + .pwm_register_base = 0x19, + .led_control_register_base = IS31FL32XX_REG_NONE, + .brightness_steps = 4096, + .reset_func = is31fl3293_reset, + .sw_shutdown_func = is31fl3293_software_shutdown, +}; static const struct of_device_id of_is31fl32xx_match[] = { + { .compatible = "issi,is31fl3293", .data = &is31fl3293_cdef, }, { .compatible = "issi,is31fl3236", .data = &is31fl3236_cdef, }, { .compatible = "issi,is31fl3236a", .data = &is31fl3236a_cdef, }, { .compatible = "issi,is31fl3235", .data = &is31fl3235_cdef, }, @@ -472,11 +589,11 @@ static int is31fl32xx_probe(struct i2c_client *client) priv->cdef = cdef; i2c_set_clientdata(client, priv); - ret = is31fl32xx_init_regs(priv); + ret = is31fl32xx_parse_dt(dev, priv); if (ret) return ret; - ret = is31fl32xx_parse_dt(dev, priv); + ret = is31fl32xx_init_regs(priv); if (ret) return ret; @@ -499,6 +616,7 @@ static void is31fl32xx_remove(struct i2c_client *client) * even though it is not used for DeviceTree based instantiation. */ static const struct i2c_device_id is31fl32xx_id[] = { + { "is31fl3293" }, { "is31fl3236" }, { "is31fl3236a" }, { "is31fl3235" }, diff --git a/drivers/leds/leds-lm3692x.c b/drivers/leds/leds-lm3692x.c index c319ff4d70b2..1d64ceb5ac85 100644 --- a/drivers/leds/leds-lm3692x.c +++ b/drivers/leds/leds-lm3692x.c @@ -104,6 +104,9 @@ * @regulator: LED supply regulator pointer * @led_enable: LED sync to be enabled * @model_id: Current device model ID enumerated + * @boost_ctrl: Cached configuration for the boost control register + * @brightness_ctrl: Cached configuration for brightness/brightness control + * @enabled: Cached enable state of the device */ struct lm3692x_led { struct mutex lock; diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c index fd447eb7eb15..ea131177de96 100644 --- a/drivers/leds/leds-lp55xx-common.c +++ b/drivers/leds/leds-lp55xx-common.c @@ -1204,7 +1204,6 @@ static struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, struct device_node *np, struct lp55xx_chip *chip) { - struct device_node *child; struct lp55xx_platform_data *pdata; struct lp55xx_led_config *cfg; int num_channels; @@ -1229,12 +1228,10 @@ static struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, pdata->num_channels = num_channels; cfg->max_channel = chip->cfg->max_channel; - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { ret = lp55xx_parse_logical_led(child, cfg, i); - if (ret) { - of_node_put(child); + if (ret) return ERR_PTR(-EINVAL); - } i++; } diff --git a/drivers/leds/rgb/Kconfig b/drivers/leds/rgb/Kconfig index 222d943d826a..28ef4c487367 100644 --- a/drivers/leds/rgb/Kconfig +++ b/drivers/leds/rgb/Kconfig @@ -26,6 +26,19 @@ config LEDS_KTD202X To compile this driver as a module, choose M here: the module will be called leds-ktd202x. +config LEDS_LP5812 + tristate "LED support for Texas Instruments LP5812" + depends on I2C + help + If you say Y here you get support for TI LP5812 LED driver. + The LP5812 is a 4x3 matrix RGB LED driver with autonomous + animation engine control. + + To compile this driver as a module, choose M here: the + module will be called leds-lp5812. + + If unsure, say N. + config LEDS_NCP5623 tristate "LED support for NCP5623" depends on I2C diff --git a/drivers/leds/rgb/Makefile b/drivers/leds/rgb/Makefile index a501fd27f179..be45991f63f5 100644 --- a/drivers/leds/rgb/Makefile +++ b/drivers/leds/rgb/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_LEDS_GROUP_MULTICOLOR) += leds-group-multicolor.o obj-$(CONFIG_LEDS_KTD202X) += leds-ktd202x.o +obj-$(CONFIG_LEDS_LP5812) += leds-lp5812.o obj-$(CONFIG_LEDS_NCP5623) += leds-ncp5623.o obj-$(CONFIG_LEDS_PWM_MULTICOLOR) += leds-pwm-multicolor.o obj-$(CONFIG_LEDS_QCOM_LPG) += leds-qcom-lpg.o diff --git a/drivers/leds/rgb/leds-lp5812.c b/drivers/leds/rgb/leds-lp5812.c new file mode 100644 index 000000000000..ce6d703641e8 --- /dev/null +++ b/drivers/leds/rgb/leds-lp5812.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * LP5812 LED driver + * + * Copyright (C) 2025 Texas Instruments + * + * Author: Jared Zhou + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "leds-lp5812.h" + +static const struct lp5812_mode_mapping chip_mode_map[] = { + {"direct_mode", 0, 0, 0, 0, 0, 0}, + {"tcm:1:0", 1, 0, 0, 0, 0, 0}, + {"tcm:1:1", 1, 1, 0, 0, 0, 0}, + {"tcm:1:2", 1, 2, 0, 0, 0, 0}, + {"tcm:1:3", 1, 3, 0, 0, 0, 0}, + {"tcm:2:0:1", 2, 0, 1, 0, 0, 0}, + {"tcm:2:0:2", 2, 0, 2, 0, 0, 0}, + {"tcm:2:0:3", 2, 0, 3, 0, 0, 0}, + {"tcm:2:1:2", 2, 1, 2, 0, 0, 0}, + {"tcm:2:1:3", 2, 1, 3, 0, 0, 0}, + {"tcm:2:2:3", 2, 2, 3, 0, 0, 0}, + {"tcm:3:0:1:2", 3, 0, 1, 2, 0, 0}, + {"tcm:3:0:1:3", 3, 0, 1, 3, 0, 0}, + {"tcm:3:0:2:3", 3, 0, 2, 3, 0, 0}, + {"tcm:4:0:1:2:3", 4, 0, 1, 2, 3, 0}, + {"mix:1:0:1", 5, 1, 0, 0, 0, 0}, + {"mix:1:0:2", 5, 2, 0, 0, 0, 0}, + {"mix:1:0:3", 5, 3, 0, 0, 0, 0}, + {"mix:1:1:0", 5, 0, 0, 0, 0, 1}, + {"mix:1:1:2", 5, 2, 0, 0, 0, 1}, + {"mix:1:1:3", 5, 3, 0, 0, 0, 1}, + {"mix:1:2:0", 5, 0, 0, 0, 0, 2}, + {"mix:1:2:1", 5, 1, 0, 0, 0, 2}, + {"mix:1:2:3", 5, 3, 0, 0, 0, 2}, + {"mix:1:3:0", 5, 0, 0, 0, 0, 3}, + {"mix:1:3:1", 5, 1, 0, 0, 0, 3}, + {"mix:1:3:2", 5, 2, 0, 0, 0, 3}, + {"mix:2:0:1:2", 6, 1, 2, 0, 0, 0}, + {"mix:2:0:1:3", 6, 1, 3, 0, 0, 0}, + {"mix:2:0:2:3", 6, 2, 3, 0, 0, 0}, + {"mix:2:1:0:2", 6, 0, 2, 0, 0, 1}, + {"mix:2:1:0:3", 6, 0, 3, 0, 0, 1}, + {"mix:2:1:2:3", 6, 2, 3, 0, 0, 1}, + {"mix:2:2:0:1", 6, 0, 1, 0, 0, 2}, + {"mix:2:2:0:3", 6, 0, 3, 0, 0, 2}, + {"mix:2:2:1:3", 6, 1, 3, 0, 0, 2}, + {"mix:2:3:0:1", 6, 0, 1, 0, 0, 3}, + {"mix:2:3:0:2", 6, 0, 2, 0, 0, 3}, + {"mix:2:3:1:2", 6, 1, 2, 0, 0, 3}, + {"mix:3:0:1:2:3", 7, 1, 2, 3, 0, 0}, + {"mix:3:1:0:2:3", 7, 0, 2, 3, 0, 1}, + {"mix:3:2:0:1:3", 7, 0, 1, 3, 0, 2}, + {"mix:3:3:0:1:2", 7, 0, 1, 2, 0, 3} +}; + +static int lp5812_write(struct lp5812_chip *chip, u16 reg, u8 val) +{ + struct device *dev = &chip->client->dev; + struct i2c_msg msg; + u8 buf[LP5812_DATA_LENGTH]; + u8 reg_addr_bit8_9; + int ret; + + /* Extract register address bits 9 and 8 for Address Byte 1 */ + reg_addr_bit8_9 = (reg >> LP5812_REG_ADDR_HIGH_SHIFT) & LP5812_REG_ADDR_BIT_8_9_MASK; + + /* Prepare payload: Address Byte 2 (bits [7:0]) and value to write */ + buf[LP5812_DATA_BYTE_0_IDX] = (u8)(reg & LP5812_REG_ADDR_LOW_MASK); + buf[LP5812_DATA_BYTE_1_IDX] = val; + + /* Construct I2C message for a write operation */ + msg.addr = (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; + msg.flags = 0; + msg.len = sizeof(buf); + msg.buf = buf; + + ret = i2c_transfer(chip->client->adapter, &msg, 1); + if (ret == 1) + return 0; + + dev_err(dev, "I2C write error, ret=%d\n", ret); + return ret < 0 ? ret : -EIO; +} + +static int lp5812_read(struct lp5812_chip *chip, u16 reg, u8 *val) +{ + struct device *dev = &chip->client->dev; + struct i2c_msg msgs[LP5812_READ_MSG_LENGTH]; + u8 ret_val; + u8 reg_addr_bit8_9; + u8 converted_reg; + int ret; + + /* Extract register address bits 9 and 8 for Address Byte 1 */ + reg_addr_bit8_9 = (reg >> LP5812_REG_ADDR_HIGH_SHIFT) & LP5812_REG_ADDR_BIT_8_9_MASK; + + /* Lower 8 bits go in Address Byte 2 */ + converted_reg = (u8)(reg & LP5812_REG_ADDR_LOW_MASK); + + /* Prepare I2C write message to set register address */ + msgs[LP5812_MSG_0_IDX].addr = + (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; + msgs[LP5812_MSG_0_IDX].flags = 0; + msgs[LP5812_MSG_0_IDX].len = 1; + msgs[LP5812_MSG_0_IDX].buf = &converted_reg; + + /* Prepare I2C read message to retrieve register value */ + msgs[LP5812_MSG_1_IDX].addr = + (chip->client->addr << LP5812_CHIP_ADDR_SHIFT) | reg_addr_bit8_9; + msgs[LP5812_MSG_1_IDX].flags = I2C_M_RD; + msgs[LP5812_MSG_1_IDX].len = 1; + msgs[LP5812_MSG_1_IDX].buf = &ret_val; + + ret = i2c_transfer(chip->client->adapter, msgs, LP5812_READ_MSG_LENGTH); + if (ret == LP5812_READ_MSG_LENGTH) { + *val = ret_val; + return 0; + } + + dev_err(dev, "I2C read error, ret=%d\n", ret); + *val = 0; + return ret < 0 ? ret : -EIO; +} + +static int lp5812_read_tsd_config_status(struct lp5812_chip *chip, u8 *reg_val) +{ + return lp5812_read(chip, LP5812_TSD_CONFIG_STATUS, reg_val); +} + +static int lp5812_update_regs_config(struct lp5812_chip *chip) +{ + u8 reg_val; + int ret; + + ret = lp5812_write(chip, LP5812_CMD_UPDATE, LP5812_UPDATE_CMD_VAL); + if (ret) + return ret; + + ret = lp5812_read_tsd_config_status(chip, ®_val); + if (ret) + return ret; + + return reg_val & LP5812_CFG_ERR_STATUS_MASK; +} + +static ssize_t parse_drive_mode(struct lp5812_chip *chip, const char *str) +{ + int i; + + chip->drive_mode.bits.mix_sel_led_0 = false; + chip->drive_mode.bits.mix_sel_led_1 = false; + chip->drive_mode.bits.mix_sel_led_2 = false; + chip->drive_mode.bits.mix_sel_led_3 = false; + + if (sysfs_streq(str, LP5812_MODE_DIRECT_NAME)) { + chip->drive_mode.bits.led_mode = LP5812_MODE_DIRECT_VALUE; + return 0; + } + + for (i = 0; i < ARRAY_SIZE(chip_mode_map); i++) { + if (!sysfs_streq(str, chip_mode_map[i].mode_name)) + continue; + + chip->drive_mode.bits.led_mode = chip_mode_map[i].mode; + chip->scan_order.bits.order0 = chip_mode_map[i].scan_order_0; + chip->scan_order.bits.order1 = chip_mode_map[i].scan_order_1; + chip->scan_order.bits.order2 = chip_mode_map[i].scan_order_2; + chip->scan_order.bits.order3 = chip_mode_map[i].scan_order_3; + + switch (chip_mode_map[i].selection_led) { + case LP5812_MODE_MIX_SELECT_LED_0: + chip->drive_mode.bits.mix_sel_led_0 = true; + break; + case LP5812_MODE_MIX_SELECT_LED_1: + chip->drive_mode.bits.mix_sel_led_1 = true; + break; + case LP5812_MODE_MIX_SELECT_LED_2: + chip->drive_mode.bits.mix_sel_led_2 = true; + break; + case LP5812_MODE_MIX_SELECT_LED_3: + chip->drive_mode.bits.mix_sel_led_3 = true; + break; + default: + return -EINVAL; + } + + return 0; + } + + return -EINVAL; +} + +static int lp5812_set_drive_mode_scan_order(struct lp5812_chip *chip) +{ + u8 val; + int ret; + + val = chip->drive_mode.val; + ret = lp5812_write(chip, LP5812_DEV_CONFIG1, val); + if (ret) + return ret; + + val = chip->scan_order.val; + ret = lp5812_write(chip, LP5812_DEV_CONFIG2, val); + + return ret; +} + +static int lp5812_set_led_mode(struct lp5812_chip *chip, int led_number, + enum control_mode mode) +{ + u8 reg_val; + u16 reg; + int ret; + + /* + * Select device configuration register. + * Reg3 for LED_0–LED_3, LED_A0–A2, LED_B0 + * Reg4 for LED_B1–B2, LED_C0–C2, LED_D0–D2 + */ + if (led_number < LP5812_NUMBER_LED_IN_REG) + reg = LP5812_DEV_CONFIG3; + else + reg = LP5812_DEV_CONFIG4; + + ret = lp5812_read(chip, reg, ®_val); + if (ret) + return ret; + + if (mode == LP5812_MODE_MANUAL) + reg_val &= ~(LP5812_ENABLE << (led_number % LP5812_NUMBER_LED_IN_REG)); + else + reg_val |= (LP5812_ENABLE << (led_number % LP5812_NUMBER_LED_IN_REG)); + + ret = lp5812_write(chip, reg, reg_val); + if (ret) + return ret; + + ret = lp5812_update_regs_config(chip); + + return ret; +} + +static int lp5812_manual_dc_pwm_control(struct lp5812_chip *chip, int led_number, + u8 val, enum dimming_type dimming_type) +{ + u16 led_base_reg; + int ret; + + if (dimming_type == LP5812_DIMMING_ANALOG) + led_base_reg = LP5812_MANUAL_DC_BASE; + else + led_base_reg = LP5812_MANUAL_PWM_BASE; + + ret = lp5812_write(chip, led_base_reg + led_number, val); + + return ret; +} + +static int lp5812_multicolor_brightness(struct lp5812_led *led) +{ + struct lp5812_chip *chip = led->chip; + int ret, i; + + guard(mutex)(&chip->lock); + for (i = 0; i < led->mc_cdev.num_colors; i++) { + ret = lp5812_manual_dc_pwm_control(chip, led->mc_cdev.subled_info[i].channel, + led->mc_cdev.subled_info[i].brightness, + LP5812_DIMMING_PWM); + if (ret) + return ret; + } + + return 0; +} + +static int lp5812_led_brightness(struct lp5812_led *led) +{ + struct lp5812_chip *chip = led->chip; + struct lp5812_led_config *led_cfg; + int ret; + + led_cfg = &chip->led_config[led->chan_nr]; + + guard(mutex)(&chip->lock); + ret = lp5812_manual_dc_pwm_control(chip, led_cfg->led_id[0], + led->brightness, LP5812_DIMMING_PWM); + + return ret; +} + +static int lp5812_set_brightness(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct lp5812_led *led = container_of(cdev, struct lp5812_led, cdev); + + led->brightness = (u8)brightness; + + return lp5812_led_brightness(led); +} + +static int lp5812_set_mc_brightness(struct led_classdev *cdev, + enum led_brightness brightness) +{ + struct led_classdev_mc *mc_dev = lcdev_to_mccdev(cdev); + struct lp5812_led *led = container_of(mc_dev, struct lp5812_led, mc_cdev); + + led_mc_calc_color_components(&led->mc_cdev, brightness); + + return lp5812_multicolor_brightness(led); +} + +static int lp5812_init_led(struct lp5812_led *led, struct lp5812_chip *chip, int chan) +{ + struct device *dev = &chip->client->dev; + struct mc_subled *mc_led_info; + struct led_classdev *led_cdev; + int i, ret; + + if (chip->led_config[chan].name) { + led->cdev.name = chip->led_config[chan].name; + } else { + led->cdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s:channel%d", + chip->label ? : chip->client->name, chan); + if (!led->cdev.name) + return -ENOMEM; + } + + if (!chip->led_config[chan].is_sc_led) { + mc_led_info = devm_kcalloc(dev, chip->led_config[chan].num_colors, + sizeof(*mc_led_info), GFP_KERNEL); + if (!mc_led_info) + return -ENOMEM; + + led_cdev = &led->mc_cdev.led_cdev; + led_cdev->name = led->cdev.name; + led_cdev->brightness_set_blocking = lp5812_set_mc_brightness; + led->mc_cdev.num_colors = chip->led_config[chan].num_colors; + + for (i = 0; i < led->mc_cdev.num_colors; i++) { + mc_led_info[i].color_index = chip->led_config[chan].color_id[i]; + mc_led_info[i].channel = chip->led_config[chan].led_id[i]; + } + + led->mc_cdev.subled_info = mc_led_info; + } else { + led->cdev.brightness_set_blocking = lp5812_set_brightness; + } + + led->chan_nr = chan; + + if (chip->led_config[chan].is_sc_led) { + ret = devm_led_classdev_register(dev, &led->cdev); + if (ret == 0) + led->cdev.dev->platform_data = led; + } else { + ret = devm_led_classdev_multicolor_register(dev, &led->mc_cdev); + if (ret == 0) + led->mc_cdev.led_cdev.dev->platform_data = led; + } + + return ret; +} + +static int lp5812_register_leds(struct lp5812_led *leds, struct lp5812_chip *chip) +{ + struct lp5812_led *led; + int num_channels = chip->num_channels; + u8 reg_val; + u16 reg; + int ret, i, j; + + for (i = 0; i < num_channels; i++) { + led = &leds[i]; + ret = lp5812_init_led(led, chip, i); + if (ret) + goto err_init_led; + + led->chip = chip; + + for (j = 0; j < chip->led_config[i].num_colors; j++) { + ret = lp5812_write(chip, + LP5812_AUTO_DC_BASE + chip->led_config[i].led_id[j], + chip->led_config[i].max_current[j]); + if (ret) + goto err_init_led; + + ret = lp5812_manual_dc_pwm_control(chip, chip->led_config[i].led_id[j], + chip->led_config[i].max_current[j], + LP5812_DIMMING_ANALOG); + if (ret) + goto err_init_led; + + ret = lp5812_set_led_mode(chip, chip->led_config[i].led_id[j], + LP5812_MODE_MANUAL); + if (ret) + goto err_init_led; + + reg = (chip->led_config[i].led_id[j] < LP5812_NUMBER_LED_IN_REG) ? + LP5812_LED_EN_1 : LP5812_LED_EN_2; + + ret = lp5812_read(chip, reg, ®_val); + if (ret) + goto err_init_led; + + reg_val |= (LP5812_ENABLE << (chip->led_config[i].led_id[j] % + LP5812_NUMBER_LED_IN_REG)); + + ret = lp5812_write(chip, reg, reg_val); + if (ret) + goto err_init_led; + } + } + + return 0; + +err_init_led: + return ret; +} + +static int lp5812_init_device(struct lp5812_chip *chip) +{ + int ret; + + usleep_range(LP5812_WAIT_DEVICE_STABLE_MIN, LP5812_WAIT_DEVICE_STABLE_MAX); + + ret = lp5812_write(chip, LP5812_REG_ENABLE, LP5812_ENABLE); + if (ret) { + dev_err(&chip->client->dev, "failed to enable LP5812 device\n"); + return ret; + } + + ret = lp5812_write(chip, LP5812_DEV_CONFIG12, LP5812_LSD_LOD_START_UP); + if (ret) { + dev_err(&chip->client->dev, "failed to configure device safety thresholds\n"); + return ret; + } + + ret = parse_drive_mode(chip, chip->scan_mode); + if (ret) + return ret; + + ret = lp5812_set_drive_mode_scan_order(chip); + if (ret) + return ret; + + ret = lp5812_update_regs_config(chip); + if (ret) { + dev_err(&chip->client->dev, "failed to apply configuration updates\n"); + return ret; + } + + return 0; +} + +static void lp5812_deinit_device(struct lp5812_chip *chip) +{ + lp5812_write(chip, LP5812_LED_EN_1, LP5812_DISABLE); + lp5812_write(chip, LP5812_LED_EN_2, LP5812_DISABLE); + lp5812_write(chip, LP5812_REG_ENABLE, LP5812_DISABLE); +} + +static int lp5812_parse_led_channel(struct device_node *np, + struct lp5812_led_config *cfg, + int color_number) +{ + int color_id, reg, ret; + u32 max_cur; + + ret = of_property_read_u32(np, "reg", ®); + if (ret) + return ret; + + cfg->led_id[color_number] = reg; + + ret = of_property_read_u32(np, "led-max-microamp", &max_cur); + if (ret) + max_cur = 0; + /* Convert microamps to driver units */ + cfg->max_current[color_number] = max_cur / 100; + + ret = of_property_read_u32(np, "color", &color_id); + if (ret) + color_id = 0; + cfg->color_id[color_number] = color_id; + + return 0; +} + +static int lp5812_parse_led(struct device_node *np, + struct lp5812_led_config *cfg, + int led_index) +{ + int num_colors, ret; + + of_property_read_string(np, "label", &cfg[led_index].name); + + ret = of_property_read_u32(np, "reg", &cfg[led_index].chan_nr); + if (ret) + return ret; + + num_colors = 0; + for_each_available_child_of_node_scoped(np, child) { + ret = lp5812_parse_led_channel(child, &cfg[led_index], num_colors); + if (ret) + return ret; + + num_colors++; + } + + if (num_colors == 0) { + ret = lp5812_parse_led_channel(np, &cfg[led_index], 0); + if (ret) + return ret; + + num_colors = 1; + cfg[led_index].is_sc_led = true; + } else { + cfg[led_index].is_sc_led = false; + } + + cfg[led_index].num_colors = num_colors; + + return 0; +} + +static int lp5812_of_probe(struct device *dev, + struct device_node *np, + struct lp5812_chip *chip) +{ + struct lp5812_led_config *cfg; + int num_channels, i = 0, ret; + + num_channels = of_get_available_child_count(np); + if (num_channels == 0) { + dev_err(dev, "no LED channels\n"); + return -EINVAL; + } + + cfg = devm_kcalloc(dev, num_channels, sizeof(*cfg), GFP_KERNEL); + if (!cfg) + return -ENOMEM; + + chip->led_config = &cfg[0]; + chip->num_channels = num_channels; + + for_each_available_child_of_node_scoped(np, child) { + ret = lp5812_parse_led(child, cfg, i); + if (ret) + return -EINVAL; + i++; + } + + ret = of_property_read_string(np, "ti,scan-mode", &chip->scan_mode); + if (ret) + chip->scan_mode = LP5812_MODE_DIRECT_NAME; + + of_property_read_string(np, "label", &chip->label); + + return 0; +} + +static int lp5812_probe(struct i2c_client *client) +{ + struct lp5812_chip *chip; + struct device_node *np = dev_of_node(&client->dev); + struct lp5812_led *leds; + int ret; + + if (!np) + return -EINVAL; + + chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + ret = lp5812_of_probe(&client->dev, np, chip); + if (ret) + return ret; + + leds = devm_kcalloc(&client->dev, chip->num_channels, sizeof(*leds), GFP_KERNEL); + if (!leds) + return -ENOMEM; + + chip->client = client; + mutex_init(&chip->lock); + i2c_set_clientdata(client, chip); + + ret = lp5812_init_device(chip); + if (ret) + return ret; + + ret = lp5812_register_leds(leds, chip); + if (ret) + goto err_out; + + return 0; + +err_out: + lp5812_deinit_device(chip); + return ret; +} + +static void lp5812_remove(struct i2c_client *client) +{ + struct lp5812_chip *chip = i2c_get_clientdata(client); + + lp5812_deinit_device(chip); +} + +static const struct of_device_id of_lp5812_match[] = { + { .compatible = "ti,lp5812" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, of_lp5812_match); + +static struct i2c_driver lp5812_driver = { + .driver = { + .name = "lp5812", + .of_match_table = of_lp5812_match, + }, + .probe = lp5812_probe, + .remove = lp5812_remove, +}; +module_i2c_driver(lp5812_driver); + +MODULE_DESCRIPTION("Texas Instruments LP5812 LED Driver"); +MODULE_AUTHOR("Jared Zhou "); +MODULE_LICENSE("GPL"); diff --git a/drivers/leds/rgb/leds-lp5812.h b/drivers/leds/rgb/leds-lp5812.h new file mode 100644 index 000000000000..d8728ecd90b3 --- /dev/null +++ b/drivers/leds/rgb/leds-lp5812.h @@ -0,0 +1,172 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * LP5812 Driver Header + * + * Copyright (C) 2025 Texas Instruments + * + * Author: Jared Zhou + */ + +#ifndef _LP5812_H_ +#define _LP5812_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LP5812_REG_ENABLE 0x0000 +#define LP5812_REG_RESET 0x0023 +#define LP5812_DEV_CONFIG0 0x0001 +#define LP5812_DEV_CONFIG1 0x0002 +#define LP5812_DEV_CONFIG2 0x0003 +#define LP5812_DEV_CONFIG3 0x0004 +#define LP5812_DEV_CONFIG4 0x0005 +#define LP5812_DEV_CONFIG5 0x0006 +#define LP5812_DEV_CONFIG6 0x0007 +#define LP5812_DEV_CONFIG7 0x0008 +#define LP5812_DEV_CONFIG8 0x0009 +#define LP5812_DEV_CONFIG9 0x000A +#define LP5812_DEV_CONFIG10 0x000B +#define LP5812_DEV_CONFIG11 0x000c +#define LP5812_DEV_CONFIG12 0x000D +#define LP5812_CMD_UPDATE 0x0010 +#define LP5812_LED_EN_1 0x0020 +#define LP5812_LED_EN_2 0x0021 +#define LP5812_FAULT_CLEAR 0x0022 +#define LP5812_MANUAL_DC_BASE 0x0030 +#define LP5812_AUTO_DC_BASE 0x0050 +#define LP5812_MANUAL_PWM_BASE 0x0040 + +#define LP5812_TSD_CONFIG_STATUS 0x0300 +#define LP5812_LOD_STATUS 0x0301 +#define LP5812_LSD_STATUS 0x0303 + +#define LP5812_ENABLE 0x01 +#define LP5812_DISABLE 0x00 +#define FAULT_CLEAR_ALL 0x07 +#define TSD_CLEAR_VAL 0x04 +#define LSD_CLEAR_VAL 0x02 +#define LOD_CLEAR_VAL 0x01 +#define LP5812_RESET 0x66 +#define LP5812_DEV_CONFIG12_DEFAULT 0x08 + +#define LP5812_UPDATE_CMD_VAL 0x55 +#define LP5812_REG_ADDR_HIGH_SHIFT 8 +#define LP5812_REG_ADDR_BIT_8_9_MASK 0x03 +#define LP5812_REG_ADDR_LOW_MASK 0xFF +#define LP5812_CHIP_ADDR_SHIFT 2 +#define LP5812_DATA_LENGTH 2 +#define LP5812_DATA_BYTE_0_IDX 0 +#define LP5812_DATA_BYTE_1_IDX 1 + +#define LP5812_READ_MSG_LENGTH 2 +#define LP5812_MSG_0_IDX 0 +#define LP5812_MSG_1_IDX 1 +#define LP5812_CFG_ERR_STATUS_MASK 0x01 +#define LP5812_CFG_TSD_STATUS_SHIFT 1 +#define LP5812_CFG_TSD_STATUS_MASK 0x01 + +#define LP5812_FAULT_CLEAR_LOD 0 +#define LP5812_FAULT_CLEAR_LSD 1 +#define LP5812_FAULT_CLEAR_TSD 2 +#define LP5812_FAULT_CLEAR_ALL 3 +#define LP5812_NUMBER_LED_IN_REG 8 + +#define LP5812_WAIT_DEVICE_STABLE_MIN 1000 +#define LP5812_WAIT_DEVICE_STABLE_MAX 1100 + +#define LP5812_LSD_LOD_START_UP 0x0B +#define LP5812_MODE_NAME_MAX_LEN 20 +#define LP5812_MODE_DIRECT_NAME "direct_mode" +#define LP5812_MODE_DIRECT_VALUE 0 +#define LP5812_MODE_MIX_SELECT_LED_0 0 +#define LP5812_MODE_MIX_SELECT_LED_1 1 +#define LP5812_MODE_MIX_SELECT_LED_2 2 +#define LP5812_MODE_MIX_SELECT_LED_3 3 + +enum control_mode { + LP5812_MODE_MANUAL = 0, + LP5812_MODE_AUTONOMOUS +}; + +enum dimming_type { + LP5812_DIMMING_ANALOG, + LP5812_DIMMING_PWM +}; + +union lp5812_scan_order { + struct { + u8 order0:2; + u8 order1:2; + u8 order2:2; + u8 order3:2; + } bits; + u8 val; +}; + +union lp5812_drive_mode { + struct { + u8 mix_sel_led_0:1; + u8 mix_sel_led_1:1; + u8 mix_sel_led_2:1; + u8 mix_sel_led_3:1; + u8 led_mode:3; + u8 pwm_fre:1; + } bits; + u8 val; +}; + +struct lp5812_reg { + u16 addr; + union { + u8 val; + u8 mask; + u8 shift; + }; +}; + +struct lp5812_mode_mapping { + char mode_name[LP5812_MODE_NAME_MAX_LEN]; + u8 mode; + u8 scan_order_0; + u8 scan_order_1; + u8 scan_order_2; + u8 scan_order_3; + u8 selection_led; +}; + +struct lp5812_led_config { + bool is_sc_led; + const char *name; + u8 color_id[LED_COLOR_ID_MAX]; + u32 max_current[LED_COLOR_ID_MAX]; + int chan_nr; + int num_colors; + int led_id[LED_COLOR_ID_MAX]; +}; + +struct lp5812_chip { + u8 num_channels; + struct i2c_client *client; + struct mutex lock; /* Protects register access */ + struct lp5812_led_config *led_config; + const char *label; + const char *scan_mode; + union lp5812_scan_order scan_order; + union lp5812_drive_mode drive_mode; +}; + +struct lp5812_led { + u8 brightness; + int chan_nr; + struct led_classdev cdev; + struct led_classdev_mc mc_cdev; + struct lp5812_chip *chip; +}; + +#endif /*_LP5812_H_*/ diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c index 72da0bf469ad..016bf468e094 100644 --- a/drivers/leds/rgb/leds-qcom-lpg.c +++ b/drivers/leds/rgb/leds-qcom-lpg.c @@ -369,7 +369,7 @@ static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern, { unsigned int idx; u16 val; - int i; + int i, ret; idx = bitmap_find_next_zero_area(lpg->lut_bitmap, lpg->lut_size, 0, len, 0); @@ -379,8 +379,10 @@ static int lpg_lut_store(struct lpg *lpg, struct led_pattern *pattern, for (i = 0; i < len; i++) { val = pattern[i].brightness; - regmap_bulk_write(lpg->map, lpg->lut_base + LPG_LUT_REG(idx + i), - &val, sizeof(val)); + ret = regmap_bulk_write(lpg->map, lpg->lut_base + LPG_LUT_REG(idx + i), + &val, sizeof(val)); + if (ret) + return ret; } bitmap_set(lpg->lut_bitmap, idx, len); @@ -994,7 +996,7 @@ static int lpg_pattern_set(struct lpg_led *led, struct led_pattern *led_pattern, if (len % 2) return -EINVAL; - pattern = kcalloc(len / 2, sizeof(*pattern), GFP_KERNEL); + pattern = kzalloc_objs(*pattern, len / 2); if (!pattern) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-activity.c b/drivers/leds/trigger/ledtrig-activity.c index c973246a57f9..3674bceda718 100644 --- a/drivers/leds/trigger/ledtrig-activity.c +++ b/drivers/leds/trigger/ledtrig-activity.c @@ -188,7 +188,7 @@ static int activity_activate(struct led_classdev *led_cdev) { struct activity_data *activity_data; - activity_data = kzalloc(sizeof(*activity_data), GFP_KERNEL); + activity_data = kzalloc_obj(*activity_data); if (!activity_data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-backlight.c b/drivers/leds/trigger/ledtrig-backlight.c index c1f0f5becaee..e67bc7c2aecb 100644 --- a/drivers/leds/trigger/ledtrig-backlight.c +++ b/drivers/leds/trigger/ledtrig-backlight.c @@ -102,7 +102,7 @@ static int bl_trig_activate(struct led_classdev *led) { struct bl_trig_notifier *n; - n = kzalloc(sizeof(struct bl_trig_notifier), GFP_KERNEL); + n = kzalloc_obj(struct bl_trig_notifier); if (!n) return -ENOMEM; led_set_trigger_data(led, n); diff --git a/drivers/leds/trigger/ledtrig-gpio.c b/drivers/leds/trigger/ledtrig-gpio.c index 7f6a2352b0ac..fc911dfec0ef 100644 --- a/drivers/leds/trigger/ledtrig-gpio.c +++ b/drivers/leds/trigger/ledtrig-gpio.c @@ -78,7 +78,7 @@ static int gpio_trig_activate(struct led_classdev *led) struct device *dev = led->dev; int ret; - gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL); + gpio_data = kzalloc_obj(*gpio_data); if (!gpio_data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-heartbeat.c b/drivers/leds/trigger/ledtrig-heartbeat.c index 40eb61b6d54e..efe0042b3157 100644 --- a/drivers/leds/trigger/ledtrig-heartbeat.c +++ b/drivers/leds/trigger/ledtrig-heartbeat.c @@ -129,7 +129,7 @@ static int heartbeat_trig_activate(struct led_classdev *led_cdev) { struct heartbeat_trig_data *heartbeat_data; - heartbeat_data = kzalloc(sizeof(*heartbeat_data), GFP_KERNEL); + heartbeat_data = kzalloc_obj(*heartbeat_data); if (!heartbeat_data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-input-events.c b/drivers/leds/trigger/ledtrig-input-events.c index 3c6414259c27..d057b2a23967 100644 --- a/drivers/leds/trigger/ledtrig-input-events.c +++ b/drivers/leds/trigger/ledtrig-input-events.c @@ -75,7 +75,7 @@ static int input_events_connect(struct input_handler *handler, struct input_dev struct input_handle *handle; int ret; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c index c15efe3e5078..12cb3311ea22 100644 --- a/drivers/leds/trigger/ledtrig-netdev.c +++ b/drivers/leds/trigger/ledtrig-netdev.c @@ -691,7 +691,7 @@ static int netdev_trig_activate(struct led_classdev *led_cdev) struct device *dev; int rc; - trigger_data = kzalloc(sizeof(struct led_netdev_data), GFP_KERNEL); + trigger_data = kzalloc_obj(struct led_netdev_data); if (!trigger_data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-oneshot.c b/drivers/leds/trigger/ledtrig-oneshot.c index bee3bd452abf..9068e3bb0bdb 100644 --- a/drivers/leds/trigger/ledtrig-oneshot.c +++ b/drivers/leds/trigger/ledtrig-oneshot.c @@ -159,7 +159,7 @@ static int oneshot_trig_activate(struct led_classdev *led_cdev) { struct oneshot_trig_data *oneshot_data; - oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL); + oneshot_data = kzalloc_obj(*oneshot_data); if (!oneshot_data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-pattern.c b/drivers/leds/trigger/ledtrig-pattern.c index 9af3c18f14f4..8f9cbe54e231 100644 --- a/drivers/leds/trigger/ledtrig-pattern.c +++ b/drivers/leds/trigger/ledtrig-pattern.c @@ -465,7 +465,7 @@ static int pattern_trig_activate(struct led_classdev *led_cdev) { struct pattern_trig_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-transient.c b/drivers/leds/trigger/ledtrig-transient.c index 20f1351464b1..8d928bb2a0c5 100644 --- a/drivers/leds/trigger/ledtrig-transient.c +++ b/drivers/leds/trigger/ledtrig-transient.c @@ -164,7 +164,7 @@ static int transient_trig_activate(struct led_classdev *led_cdev) { struct transient_trig_data *tdata; - tdata = kzalloc(sizeof(struct transient_trig_data), GFP_KERNEL); + tdata = kzalloc_obj(struct transient_trig_data); if (!tdata) return -ENOMEM; diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c index 8cf1485e8165..8eb6286b33ac 100644 --- a/drivers/leds/trigger/ledtrig-tty.c +++ b/drivers/leds/trigger/ledtrig-tty.c @@ -312,7 +312,7 @@ static int ledtrig_tty_activate(struct led_classdev *led_cdev) { struct ledtrig_tty_data *trigger_data; - trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL); + trigger_data = kzalloc_obj(*trigger_data); if (!trigger_data) return -ENOMEM; diff --git a/drivers/leds/uleds.c b/drivers/leds/uleds.c index 374a841f18c3..ace71ffc0591 100644 --- a/drivers/leds/uleds.c +++ b/drivers/leds/uleds.c @@ -53,7 +53,7 @@ static int uleds_open(struct inode *inode, struct file *file) { struct uleds_device *udev; - udev = kzalloc(sizeof(*udev), GFP_KERNEL); + udev = kzalloc_obj(*udev); if (!udev) return -ENOMEM; diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 88adee42ba82..fe150125e099 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -674,7 +674,7 @@ static int adb_open(struct inode *inode, struct file *file) ret = -ENXIO; goto out; } - state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL); + state = kmalloc_obj(struct adbdev_state); if (!state) { ret = -ENOMEM; goto out; @@ -783,8 +783,7 @@ static ssize_t adb_write(struct file *file, const char __user *buf, if (adb_controller == NULL) return -ENXIO; - req = kmalloc(sizeof(struct adb_request), - GFP_KERNEL); + req = kmalloc_obj(struct adb_request); if (req == NULL) return -ENOMEM; diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index c5aabf238d0a..6155da58091b 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -764,7 +764,7 @@ adbhid_input_register(int id, int default_id, int original_handler_id, return -EEXIST; } - adbhid[id] = hid = kzalloc(sizeof(struct adbhid), GFP_KERNEL); + adbhid[id] = hid = kzalloc_obj(struct adbhid); input_dev = input_allocate_device(); if (!hid || !input_dev) { err = -ENOMEM; diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 06fd910b3fd1..1fdf3855f9bb 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -102,7 +102,7 @@ static int mac_hid_emumouse_connect(struct input_handler *handler, if (dev == mac_hid_emumouse_dev) return -ENODEV; - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + handle = kzalloc_obj(struct input_handle); if (!handle) return -ENOMEM; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index bede200e32e8..ee3caa3d87d1 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -368,7 +368,7 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, if (np == NULL) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c index 896a43bd819f..8a1e2c08b096 100644 --- a/drivers/macintosh/rack-meter.c +++ b/drivers/macintosh/rack-meter.c @@ -396,7 +396,7 @@ static int rackmeter_probe(struct macio_dev* mdev, } /* Create and initialize our instance data */ - rm = kzalloc(sizeof(*rm), GFP_KERNEL); + rm = kzalloc_obj(*rm); if (rm == NULL) { printk(KERN_ERR "rackmeter: failed to allocate memory !\n"); rc = -ENOMEM; diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index a1534cc6c641..3e6dfb99a5ce 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -1081,7 +1081,7 @@ static int smu_open(struct inode *inode, struct file *file) struct smu_private *pp; unsigned long flags; - pp = kzalloc(sizeof(struct smu_private), GFP_KERNEL); + pp = kzalloc_obj(struct smu_private); if (!pp) return -ENOMEM; spin_lock_init(&pp->lock); diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 00693741f744..1ac29a5cd324 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -498,7 +498,7 @@ static int probe_thermostat(struct i2c_client *client) } } - th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); + th = kzalloc_obj(struct thermostat); if (!th) return -ENOMEM; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 5fe47e784d43..8c652c15018c 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2147,7 +2147,7 @@ pmu_open(struct inode *inode, struct file *file) struct pmu_private *pp; unsigned long flags; - pp = kmalloc(sizeof(struct pmu_private), GFP_KERNEL); + pp = kmalloc_obj(struct pmu_private); if (!pp) return -ENOMEM; pp->rb_get = pp->rb_put = 0; diff --git a/drivers/macintosh/windfarm_ad7417_sensor.c b/drivers/macintosh/windfarm_ad7417_sensor.c index 3ff4577ba847..4bae07ca6669 100644 --- a/drivers/macintosh/windfarm_ad7417_sensor.c +++ b/drivers/macintosh/windfarm_ad7417_sensor.c @@ -260,7 +260,7 @@ static int wf_ad7417_probe(struct i2c_client *client) return -ENXIO; } - pv = kzalloc(sizeof(struct wf_ad7417_priv), GFP_KERNEL); + pv = kzalloc_obj(struct wf_ad7417_priv); if (pv == NULL) return -ENODEV; diff --git a/drivers/macintosh/windfarm_cpufreq_clamp.c b/drivers/macintosh/windfarm_cpufreq_clamp.c index 28d18ef22bbb..13ba7488c5c5 100644 --- a/drivers/macintosh/windfarm_cpufreq_clamp.c +++ b/drivers/macintosh/windfarm_cpufreq_clamp.c @@ -94,7 +94,7 @@ static int __init wf_cpufreq_clamp_init(void) goto fail; } - clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL); + clamp = kmalloc_obj(struct wf_control); if (clamp == NULL) { ret = -ENOMEM; goto fail; diff --git a/drivers/macintosh/windfarm_fcu_controls.c b/drivers/macintosh/windfarm_fcu_controls.c index 82365f19adb4..9def86e0cd04 100644 --- a/drivers/macintosh/windfarm_fcu_controls.c +++ b/drivers/macintosh/windfarm_fcu_controls.c @@ -363,7 +363,7 @@ static void wf_fcu_add_fan(struct wf_fcu_priv *pv, const char *name, { struct wf_fcu_fan *fan; - fan = kzalloc(sizeof(*fan), GFP_KERNEL); + fan = kzalloc_obj(*fan); if (!fan) return; fan->fcu_priv = pv; @@ -518,7 +518,7 @@ static int wf_fcu_probe(struct i2c_client *client) { struct wf_fcu_priv *pv; - pv = kzalloc(sizeof(*pv), GFP_KERNEL); + pv = kzalloc_obj(*pv); if (!pv) return -ENOMEM; diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c index b5d9c2e40148..128e9944429a 100644 --- a/drivers/macintosh/windfarm_lm75_sensor.c +++ b/drivers/macintosh/windfarm_lm75_sensor.c @@ -130,7 +130,7 @@ static int wf_lm75_probe(struct i2c_client *client) return -ENXIO; - lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); + lm = kzalloc_obj(struct wf_lm75_sensor); if (lm == NULL) return -ENODEV; diff --git a/drivers/macintosh/windfarm_lm87_sensor.c b/drivers/macintosh/windfarm_lm87_sensor.c index 16635e2b180b..a571035daff6 100644 --- a/drivers/macintosh/windfarm_lm87_sensor.c +++ b/drivers/macintosh/windfarm_lm87_sensor.c @@ -128,7 +128,7 @@ static int wf_lm87_probe(struct i2c_client *client) return -ENODEV; } - lm = kzalloc(sizeof(struct wf_lm87_sensor), GFP_KERNEL); + lm = kzalloc_obj(struct wf_lm87_sensor); if (lm == NULL) return -ENODEV; diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c index d734b31b8236..26b6436e0bb2 100644 --- a/drivers/macintosh/windfarm_max6690_sensor.c +++ b/drivers/macintosh/windfarm_max6690_sensor.c @@ -85,7 +85,7 @@ static int wf_max6690_probe(struct i2c_client *client) else return -ENXIO; - max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); + max = kzalloc_obj(struct wf_6690_sensor); if (max == NULL) { printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: " "no memory\n"); diff --git a/drivers/macintosh/windfarm_pm121.c b/drivers/macintosh/windfarm_pm121.c index 660180c843a3..ccdacb6d36a9 100644 --- a/drivers/macintosh/windfarm_pm121.c +++ b/drivers/macintosh/windfarm_pm121.c @@ -531,8 +531,7 @@ static void pm121_create_sys_fans(int loop_id) control = controls[param->control_id]; /* Alloc & initialize state */ - pm121_sys_state[loop_id] = kmalloc(sizeof(struct pm121_sys_state), - GFP_KERNEL); + pm121_sys_state[loop_id] = kmalloc_obj(struct pm121_sys_state); if (pm121_sys_state[loop_id] == NULL) { printk(KERN_WARNING "pm121: Memory allocation error\n"); goto fail; @@ -668,8 +667,7 @@ static void pm121_create_cpu_fans(void) tmax = 0x5e0000; /* 94 degree default */ /* Alloc & initialize state */ - pm121_cpu_state = kmalloc(sizeof(struct pm121_cpu_state), - GFP_KERNEL); + pm121_cpu_state = kmalloc_obj(struct pm121_cpu_state); if (pm121_cpu_state == NULL) goto fail; pm121_cpu_state->ticks = 1; diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index ada97377e19e..2a4a3746f6a0 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c @@ -283,8 +283,7 @@ static void wf_smu_create_sys_fans(void) } /* Alloc & initialize state */ - wf_smu_sys_fans = kmalloc(sizeof(struct wf_smu_sys_fans_state), - GFP_KERNEL); + wf_smu_sys_fans = kmalloc_obj(struct wf_smu_sys_fans_state); if (wf_smu_sys_fans == NULL) { printk(KERN_WARNING "windfarm: Memory allocation error" " max fan speed\n"); @@ -419,8 +418,7 @@ static void wf_smu_create_cpu_fans(void) tmax = 0x5e0000; /* 94 degree default */ /* Alloc & initialize state */ - wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state), - GFP_KERNEL); + wf_smu_cpu_fans = kmalloc_obj(struct wf_smu_cpu_fans_state); if (wf_smu_cpu_fans == NULL) goto fail; wf_smu_cpu_fans->ticks = 1; diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 108d7938e714..14089d57e5f7 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c @@ -168,8 +168,7 @@ static void wf_smu_create_cpu_fans(void) tmax = 0x5e0000; /* 94 degree default */ /* Alloc & initialize state */ - wf_smu_cpu_fans = kmalloc(sizeof(struct wf_smu_cpu_fans_state), - GFP_KERNEL); + wf_smu_cpu_fans = kmalloc_obj(struct wf_smu_cpu_fans_state); if (wf_smu_cpu_fans == NULL) goto fail; wf_smu_cpu_fans->ticks = 1; @@ -300,8 +299,7 @@ static void wf_smu_create_drive_fans(void) }; /* Alloc & initialize state */ - wf_smu_drive_fans = kmalloc(sizeof(struct wf_smu_drive_fans_state), - GFP_KERNEL); + wf_smu_drive_fans = kmalloc_obj(struct wf_smu_drive_fans_state); if (wf_smu_drive_fans == NULL) { printk(KERN_WARNING "windfarm: Memory allocation error" " max fan speed\n"); @@ -381,8 +379,7 @@ static void wf_smu_create_slots_fans(void) }; /* Alloc & initialize state */ - wf_smu_slots_fans = kmalloc(sizeof(struct wf_smu_slots_fans_state), - GFP_KERNEL); + wf_smu_slots_fans = kmalloc_obj(struct wf_smu_slots_fans_state); if (wf_smu_slots_fans == NULL) { printk(KERN_WARNING "windfarm: Memory allocation error" " max fan speed\n"); diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index bdd92b27da2a..9adceae74345 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c @@ -162,7 +162,7 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, const u32 *reg; const char *l; - fct = kmalloc(sizeof(struct smu_fan_control), GFP_KERNEL); + fct = kmalloc_obj(struct smu_fan_control); if (fct == NULL) return NULL; fct->ctrl.ops = &smu_fan_ops; diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index ff8805ecf2e5..256c1654c295 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -203,7 +203,7 @@ static int wf_sat_probe(struct i2c_client *client) char *name; int vsens[2], isens[2]; - sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); + sat = kzalloc_obj(struct wf_sat); if (sat == NULL) return -ENOMEM; sat->nr = -1; diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 2bdb73b34d29..03fda09deb53 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c @@ -200,7 +200,7 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) const char *l; const u32 *v; - ads = kmalloc(sizeof(struct smu_ad_sensor), GFP_KERNEL); + ads = kmalloc_obj(struct smu_ad_sensor); if (ads == NULL) return NULL; l = of_get_property(node, "location", NULL); @@ -338,7 +338,7 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) { struct smu_cpu_power_sensor *pow; - pow = kmalloc(sizeof(struct smu_cpu_power_sensor), GFP_KERNEL); + pow = kmalloc_obj(struct smu_cpu_power_sensor); if (pow == NULL) return NULL; pow->sens.ops = &smu_cpu_power_ops; diff --git a/drivers/mailbox/Kconfig b/drivers/mailbox/Kconfig index 29f16f220384..5bf4155b090a 100644 --- a/drivers/mailbox/Kconfig +++ b/drivers/mailbox/Kconfig @@ -199,7 +199,7 @@ config POLARFIRE_SOC_MAILBOX tristate "PolarFire SoC (MPFS) Mailbox" depends on HAS_IOMEM depends on MFD_SYSCON - depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST + depends on ARCH_MICROCHIP || COMPILE_TEST help This driver adds support for the PolarFire SoC (MPFS) mailbox controller. @@ -279,7 +279,7 @@ config MTK_ADSP_MBOX tristate "MediaTek ADSP Mailbox Controller" depends on ARCH_MEDIATEK || COMPILE_TEST help - Say yes here to add support for "MediaTek ADSP Mailbox Controller. + Say yes here to add support for MediaTek ADSP Mailbox Controller. This mailbox driver is used to send notification or short message between processors with ADSP. It will place the message to share buffer and will access the ipc control. @@ -304,6 +304,15 @@ config MTK_GPUEB_MBOX Say Y or m here if you want to support the MT8196 SoC in your kernel build. +config MTK_VCP_MBOX + tristate "MediaTek VCP Mailbox Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + help + Say yes here to add support for the MediaTek VCP mailbox driver. + The mailbox implementation provides access from the application + processor to Video Companion Processor Unit. + If unsure say N. + config ZYNQMP_IPI_MBOX tristate "Xilinx ZynqMP IPI Mailbox" depends on ARCH_ZYNQMP && OF @@ -387,7 +396,7 @@ config RISCV_SBI_MPXY_MBOX Mailbox driver implementation for RISC-V SBI Message Proxy (MPXY) extension. This mailbox driver is used to send messages to the remote processor through the SBI implementation (M-mode firmware - or HS-mode hypervisor). Say Y here if you want to have this support. - If unsure say N. + or HS-mode hypervisor). Say Y here, unless you are sure you do not + need this. endif diff --git a/drivers/mailbox/Makefile b/drivers/mailbox/Makefile index 81820a4f5528..944d8ea39f34 100644 --- a/drivers/mailbox/Makefile +++ b/drivers/mailbox/Makefile @@ -65,6 +65,8 @@ obj-$(CONFIG_MTK_CMDQ_MBOX) += mtk-cmdq-mailbox.o obj-$(CONFIG_MTK_GPUEB_MBOX) += mtk-gpueb-mailbox.o +obj-$(CONFIG_MTK_VCP_MBOX) += mtk-vcp-mailbox.o + obj-$(CONFIG_ZYNQMP_IPI_MBOX) += zynqmp-ipi-mailbox.o obj-$(CONFIG_SUN6I_MSGBOX) += sun6i-msgbox.o diff --git a/drivers/mailbox/arm_mhuv3.c b/drivers/mailbox/arm_mhuv3.c index 0910da67f8a1..a1c528be47f3 100644 --- a/drivers/mailbox/arm_mhuv3.c +++ b/drivers/mailbox/arm_mhuv3.c @@ -333,7 +333,7 @@ struct mhuv3_extension { * @rev: MHUv3 controller IIDR revision. * @var: MHUv3 controller IIDR variant. * @prod_id: MHUv3 controller IIDR product_id. - * @num_chans: The total number of channnels discovered across all extensions. + * @num_chans: The total number of channels discovered across all extensions. * @cmb_irq: Combined IRQ number if any found defined. * @ctrl: A reference to the MHUv3 control page for this block. * @pbx: Base address of the PBX register mapping region. diff --git a/drivers/mailbox/bcm-flexrm-mailbox.c b/drivers/mailbox/bcm-flexrm-mailbox.c index 4255fefc3a5a..04c47eadf950 100644 --- a/drivers/mailbox/bcm-flexrm-mailbox.c +++ b/drivers/mailbox/bcm-flexrm-mailbox.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mailbox/bcm74110-mailbox.c b/drivers/mailbox/bcm74110-mailbox.c index 2e7e86f3e6a4..344cfc35984b 100644 --- a/drivers/mailbox/bcm74110-mailbox.c +++ b/drivers/mailbox/bcm74110-mailbox.c @@ -140,7 +140,7 @@ static void bcm74110_rx_push_init_msg(struct bcm74110_mbox *mbox, u32 val) { struct bcm74110_mbox_msg *msg; - msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + msg = kzalloc_obj(*msg, GFP_ATOMIC); if (!msg) return; diff --git a/drivers/mailbox/cix-mailbox.c b/drivers/mailbox/cix-mailbox.c index 5bb1416c26a5..443620e8ae37 100644 --- a/drivers/mailbox/cix-mailbox.c +++ b/drivers/mailbox/cix-mailbox.c @@ -346,7 +346,7 @@ static void cix_mbox_isr_fifo(struct mbox_chan *chan) /* FIFO overflow is generated */ if (int_status & CIX_FIFO_OFLOW_INT) { status = cix_mbox_read(priv, CIX_FIFO_STAS); - dev_err(priv->dev, "fifo overlow: int_stats %d\n", status); + dev_err(priv->dev, "fifo overflow: int_stats %d\n", status); cix_mbox_write(priv, CIX_FIFO_OFLOW_INT, CIX_INT_CLEAR); } } diff --git a/drivers/mailbox/cv1800-mailbox.c b/drivers/mailbox/cv1800-mailbox.c index 4761191acf78..4bca9d8be4ba 100644 --- a/drivers/mailbox/cv1800-mailbox.c +++ b/drivers/mailbox/cv1800-mailbox.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mailbox/exynos-mailbox.c b/drivers/mailbox/exynos-mailbox.c index 2320649bf60c..5f2d3b81c1db 100644 --- a/drivers/mailbox/exynos-mailbox.c +++ b/drivers/mailbox/exynos-mailbox.c @@ -35,12 +35,10 @@ * struct exynos_mbox - driver's private data. * @regs: mailbox registers base address. * @mbox: pointer to the mailbox controller. - * @pclk: pointer to the mailbox peripheral clock. */ struct exynos_mbox { void __iomem *regs; struct mbox_controller *mbox; - struct clk *pclk; }; static int exynos_mbox_send_data(struct mbox_chan *chan, void *data) @@ -100,6 +98,7 @@ static int exynos_mbox_probe(struct platform_device *pdev) struct exynos_mbox *exynos_mbox; struct mbox_controller *mbox; struct mbox_chan *chans; + struct clk *pclk; int i; exynos_mbox = devm_kzalloc(dev, sizeof(*exynos_mbox), GFP_KERNEL); @@ -119,9 +118,9 @@ static int exynos_mbox_probe(struct platform_device *pdev) if (IS_ERR(exynos_mbox->regs)) return PTR_ERR(exynos_mbox->regs); - exynos_mbox->pclk = devm_clk_get_enabled(dev, "pclk"); - if (IS_ERR(exynos_mbox->pclk)) - return dev_err_probe(dev, PTR_ERR(exynos_mbox->pclk), + pclk = devm_clk_get_enabled(dev, "pclk"); + if (IS_ERR(pclk)) + return dev_err_probe(dev, PTR_ERR(pclk), "Failed to enable clock.\n"); mbox->num_chans = EXYNOS_MBOX_CHAN_COUNT; diff --git a/drivers/mailbox/imx-mailbox.c b/drivers/mailbox/imx-mailbox.c index 6778afc64a04..003f9236c35e 100644 --- a/drivers/mailbox/imx-mailbox.c +++ b/drivers/mailbox/imx-mailbox.c @@ -122,6 +122,7 @@ struct imx_mu_dcfg { u32 xRR; /* Receive Register0 */ u32 xSR[IMX_MU_xSR_MAX]; /* Status Registers */ u32 xCR[IMX_MU_xCR_MAX]; /* Control Registers */ + bool skip_suspend_flag; }; #define IMX_MU_xSR_GIPn(type, x) (type & IMX_MU_V2 ? BIT(x) : BIT(28 + (3 - (x)))) @@ -988,6 +989,7 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx7ulp = { .xRR = 0x40, .xSR = {0x60, 0x60, 0x60, 0x60}, .xCR = {0x64, 0x64, 0x64, 0x64, 0x64}, + .skip_suspend_flag = true, }; static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { @@ -1071,7 +1073,8 @@ static int __maybe_unused imx_mu_suspend_noirq(struct device *dev) priv->xcr[i] = imx_mu_read(priv, priv->dcfg->xCR[i]); } - priv->suspend = true; + if (!priv->dcfg->skip_suspend_flag) + priv->suspend = true; return 0; } @@ -1094,7 +1097,8 @@ static int __maybe_unused imx_mu_resume_noirq(struct device *dev) imx_mu_write(priv, priv->xcr[i], priv->dcfg->xCR[i]); } - priv->suspend = false; + if (!priv->dcfg->skip_suspend_flag) + priv->suspend = false; return 0; } diff --git a/drivers/mailbox/mailbox-mchp-ipc-sbi.c b/drivers/mailbox/mailbox-mchp-ipc-sbi.c index a6e52009a424..b87bf2fb4b9b 100644 --- a/drivers/mailbox/mailbox-mchp-ipc-sbi.c +++ b/drivers/mailbox/mailbox-mchp-ipc-sbi.c @@ -174,26 +174,30 @@ static irqreturn_t mchp_ipc_cluster_aggr_isr(int irq, void *data) struct mchp_ipc_msg ipc_msg; struct mchp_ipc_status status_msg; int ret; - unsigned long hartid; u32 i, chan_index, chan_id; + bool found = false; /* Find out the hart that originated the irq */ for_each_online_cpu(i) { - hartid = cpuid_to_hartid_map(i); - if (irq == ipc->cluster_cfg[hartid].irq) + if (irq == ipc->cluster_cfg[i].irq) { + found = true; break; + } } - status_msg.cluster = hartid; - memcpy(ipc->cluster_cfg[hartid].buf_base, &status_msg, sizeof(struct mchp_ipc_status)); + if (unlikely(!found)) + return IRQ_NONE; - ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[hartid].buf_base_addr); + status_msg.cluster = cpuid_to_hartid_map(i); + memcpy(ipc->cluster_cfg[i].buf_base, &status_msg, sizeof(struct mchp_ipc_status)); + + ret = mchp_ipc_sbi_send(SBI_EXT_IPC_STATUS, ipc->cluster_cfg[i].buf_base_addr); if (ret < 0) { dev_err_ratelimited(ipc->dev, "could not get IHC irq status ret=%d\n", ret); return IRQ_HANDLED; } - memcpy(&status_msg, ipc->cluster_cfg[hartid].buf_base, sizeof(struct mchp_ipc_status)); + memcpy(&status_msg, ipc->cluster_cfg[i].buf_base, sizeof(struct mchp_ipc_status)); /* * Iterate over each bit set in the IHC interrupt status register (IRQ_STATUS) to identify @@ -321,13 +325,6 @@ static int mchp_ipc_startup(struct mbox_chan *chan) goto fail_free_buf_msg_rx; } - if (ret) { - dev_err(ipc->dev, "failed to register interrupt(s)\n"); - goto fail_free_buf_msg_rx; - } - - return ret; - fail_free_buf_msg_rx: kfree(chan_info->msg_buf_rx); fail_free_buf_msg_tx: @@ -385,21 +382,21 @@ static int mchp_ipc_get_cluster_aggr_irq(struct mchp_ipc_sbi_mbox *ipc) if (ret <= 0) continue; - ipc->cluster_cfg[hartid].irq = ret; - ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[hartid].irq, + ipc->cluster_cfg[cpuid].irq = ret; + ret = devm_request_irq(ipc->dev, ipc->cluster_cfg[cpuid].irq, mchp_ipc_cluster_aggr_isr, IRQF_SHARED, "miv-ihc-irq", ipc); if (ret) return ret; - ipc->cluster_cfg[hartid].buf_base = devm_kmalloc(ipc->dev, - sizeof(struct mchp_ipc_status), - GFP_KERNEL); + ipc->cluster_cfg[cpuid].buf_base = devm_kmalloc(ipc->dev, + sizeof(struct mchp_ipc_status), + GFP_KERNEL); - if (!ipc->cluster_cfg[hartid].buf_base) + if (!ipc->cluster_cfg[cpuid].buf_base) return -ENOMEM; - ipc->cluster_cfg[hartid].buf_base_addr = __pa(ipc->cluster_cfg[hartid].buf_base); + ipc->cluster_cfg[cpuid].buf_base_addr = __pa(ipc->cluster_cfg[cpuid].buf_base); irq_found = true; } @@ -419,7 +416,7 @@ static int mchp_ipc_probe(struct platform_device *pdev) ret = sbi_probe_extension(SBI_EXT_MICROCHIP_TECHNOLOGY); if (ret <= 0) - return dev_err_probe(dev, ret, "Microchip SBI extension not detected\n"); + return dev_err_probe(dev, -ENODEV, "Microchip SBI extension not detected\n"); ipc = devm_kzalloc(dev, sizeof(*ipc), GFP_KERNEL); if (!ipc) diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 2acc6ec229a4..617ba505691d 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -489,12 +489,10 @@ EXPORT_SYMBOL_GPL(mbox_free_channel); static struct mbox_chan *fw_mbox_index_xlate(struct mbox_controller *mbox, const struct fwnode_reference_args *sp) { - int ind = sp->args[0]; - - if (ind >= mbox->num_chans) + if (sp->nargs < 1 || sp->args[0] >= mbox->num_chans) return ERR_PTR(-EINVAL); - return &mbox->chans[ind]; + return &mbox->chans[sp->args[0]]; } /** diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index 1bf6984948ef..d7c6b38888a3 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c @@ -456,7 +456,7 @@ static int cmdq_mbox_send_data(struct mbox_chan *chan, void *data) /* Client should not flush new tasks if suspended. */ WARN_ON(cmdq->suspended); - task = kzalloc(sizeof(*task), GFP_ATOMIC); + task = kzalloc_obj(*task, GFP_ATOMIC); if (!task) return -ENOMEM; @@ -636,7 +636,7 @@ static struct mbox_chan *cmdq_xlate(struct mbox_controller *mbox, static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq) { static const char * const gce_name = "gce"; - struct device_node *node, *parent = dev->of_node->parent; + struct device_node *parent = dev->of_node->parent; struct clk_bulk_data *clks; cmdq->clocks = devm_kcalloc(dev, cmdq->pdata->gce_num, @@ -661,7 +661,7 @@ static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq) * as the clock of the main GCE must be enabled for additional IPs * to be reachable. */ - for_each_child_of_node(parent, node) { + for_each_child_of_node_scoped(parent, node) { int alias_id = of_alias_get_id(node, gce_name); if (alias_id < 0 || alias_id >= cmdq->pdata->gce_num) @@ -670,17 +670,13 @@ static int cmdq_get_clocks(struct device *dev, struct cmdq *cmdq) clks = &cmdq->clocks[alias_id]; clks->id = devm_kasprintf(dev, GFP_KERNEL, "gce%d", alias_id); - if (!clks->id) { - of_node_put(node); + if (!clks->id) return -ENOMEM; - } clks->clk = of_clk_get(node, 0); - if (IS_ERR(clks->clk)) { - of_node_put(node); + if (IS_ERR(clks->clk)) return dev_err_probe(dev, PTR_ERR(clks->clk), "failed to get gce%d clock\n", alias_id); - } } return 0; diff --git a/drivers/mailbox/mtk-vcp-mailbox.c b/drivers/mailbox/mtk-vcp-mailbox.c new file mode 100644 index 000000000000..cedad575528f --- /dev/null +++ b/drivers/mailbox/mtk-vcp-mailbox.c @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 MediaTek Corporation. All rights reserved. + * Author: Jjian Zhou + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mtk_vcp_mbox { + struct mbox_controller mbox; + void __iomem *base; + struct device *dev; + const struct mtk_vcp_mbox_cfg *cfg; + struct mtk_ipi_info ipi_recv; + struct mbox_chan chans; +}; + +struct mtk_vcp_mbox_cfg { + u16 set_in; + u16 clr_out; +}; + +static irqreturn_t mtk_vcp_mbox_irq_thread(int irq, void *data) +{ + struct mtk_vcp_mbox *priv = data; + + /* get irq status */ + priv->ipi_recv.irq_status = readl(priv->base + priv->cfg->clr_out); + + __ioread32_copy(priv->ipi_recv.msg, priv->base, + MTK_VCP_MBOX_SLOT_MAX_SIZE / 4); + + mbox_chan_received_data(&priv->chans, &priv->ipi_recv); + + /* clear irq status */ + writel(priv->ipi_recv.irq_status, priv->base + priv->cfg->clr_out); + + return IRQ_HANDLED; +} + +static struct mbox_chan *mtk_vcp_mbox_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *sp) +{ + if (sp->args_count) + return NULL; + + return &mbox->chans[0]; +} + +static int mtk_vcp_mbox_send_data(struct mbox_chan *chan, void *data) +{ + struct mtk_vcp_mbox *priv = chan->con_priv; + struct mtk_ipi_info *ipi_info = data; + u32 status; + + if (!ipi_info->msg) { + dev_err(priv->dev, "msg buffer is NULL.\n"); + return -EINVAL; + } + + status = readl(priv->base + priv->cfg->set_in); + if (status & BIT(ipi_info->index)) { + dev_warn(priv->dev, "mailbox IPI %d is busy.\n", ipi_info->id); + return -EBUSY; + } + + if (ipi_info->slot_ofs + ipi_info->len > MTK_VCP_MBOX_SLOT_MAX_SIZE) + return -EINVAL; + __iowrite32_copy(priv->base + ipi_info->slot_ofs, ipi_info->msg, + ipi_info->len); + + writel(BIT(ipi_info->index), priv->base + priv->cfg->set_in); + + return 0; +} + +static bool mtk_vcp_mbox_last_tx_done(struct mbox_chan *chan) +{ + struct mtk_ipi_info *ipi_info = chan->active_req; + struct mtk_vcp_mbox *priv = chan->con_priv; + + return !(readl(priv->base + priv->cfg->set_in) & BIT(ipi_info->index)); +} + +static const struct mbox_chan_ops mtk_vcp_mbox_chan_ops = { + .send_data = mtk_vcp_mbox_send_data, + .last_tx_done = mtk_vcp_mbox_last_tx_done, +}; + +static int mtk_vcp_mbox_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mtk_vcp_mbox *priv; + struct mbox_controller *mbox; + int ret, irq; + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->chans.con_priv = priv; + mbox = &priv->mbox; + mbox->dev = dev; + mbox->ops = &mtk_vcp_mbox_chan_ops; + mbox->txdone_irq = false; + mbox->txdone_poll = true; + mbox->of_xlate = mtk_vcp_mbox_xlate; + mbox->num_chans = 1; + mbox->chans = &priv->chans; + + priv->ipi_recv.msg = devm_kzalloc(dev, MTK_VCP_MBOX_SLOT_MAX_SIZE, + GFP_KERNEL); + if (!priv->ipi_recv.msg) + return -ENOMEM; + + priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); + + priv->cfg = of_device_get_match_data(dev); + if (!priv->cfg) + return -EINVAL; + + platform_set_drvdata(pdev, priv); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + ret = devm_request_threaded_irq(dev, irq, NULL, + mtk_vcp_mbox_irq_thread, IRQF_ONESHOT, + dev_name(dev), priv); + if (ret < 0) + return ret; + + return devm_mbox_controller_register(dev, &priv->mbox); +} + +static const struct mtk_vcp_mbox_cfg mt8196_cfg = { + .set_in = 0x100, + .clr_out = 0x10c, +}; + +static const struct of_device_id mtk_vcp_mbox_of_match[] = { + { .compatible = "mediatek,mt8196-vcp-mbox", .data = &mt8196_cfg }, + {}, +}; +MODULE_DEVICE_TABLE(of, mtk_vcp_mbox_of_match); + +static struct platform_driver mtk_vcp_mbox_driver = { + .probe = mtk_vcp_mbox_probe, + .driver = { + .name = "mtk_vcp_mbox", + .of_match_table = mtk_vcp_mbox_of_match, + }, +}; +module_platform_driver(mtk_vcp_mbox_driver); + +MODULE_AUTHOR("Jjian Zhou "); +MODULE_DESCRIPTION("MTK VCP Mailbox Controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mailbox/omap-mailbox.c b/drivers/mailbox/omap-mailbox.c index 17fe6545875d..d9f100c18895 100644 --- a/drivers/mailbox/omap-mailbox.c +++ b/drivers/mailbox/omap-mailbox.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "mailbox.h" diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index ff292b9e0be9..22e70af1ae5d 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -305,22 +305,6 @@ static void pcc_chan_acknowledge(struct pcc_chan_info *pchan) pcc_chan_reg_read_modify_write(&pchan->db); } -static void *write_response(struct pcc_chan_info *pchan) -{ - struct pcc_header pcc_header; - void *buffer; - int data_len; - - memcpy_fromio(&pcc_header, pchan->chan.shmem, - sizeof(pcc_header)); - data_len = pcc_header.length - sizeof(u32) + sizeof(struct pcc_header); - - buffer = pchan->chan.rx_alloc(pchan->chan.mchan->cl, data_len); - if (buffer != NULL) - memcpy_fromio(buffer, pchan->chan.shmem, data_len); - return buffer; -} - /** * pcc_mbox_irq - PCC mailbox interrupt handler * @irq: interrupt number @@ -332,8 +316,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) { struct pcc_chan_info *pchan; struct mbox_chan *chan = p; - struct pcc_header *pcc_header = chan->active_req; - void *handle = NULL; pchan = chan->con_priv; @@ -357,17 +339,8 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) * required to avoid any possible race in updatation of this flag. */ pchan->chan_in_use = false; - - if (pchan->chan.rx_alloc) - handle = write_response(pchan); - - if (chan->active_req) { - pcc_header = chan->active_req; - if (pcc_header->flags & PCC_CMD_COMPLETION_NOTIFY) - mbox_chan_txdone(chan, 0); - } - - mbox_chan_received_data(chan, handle); + mbox_chan_received_data(chan, NULL); + mbox_chan_txdone(chan, 0); pcc_chan_acknowledge(pchan); @@ -404,33 +377,20 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) return ERR_PTR(-EBUSY); } - rc = mbox_bind_client(chan, cl); - if (rc) - return ERR_PTR(rc); - pcc_mchan = &pchan->chan; pcc_mchan->shmem = acpi_os_ioremap(pcc_mchan->shmem_base_addr, pcc_mchan->shmem_size); if (!pcc_mchan->shmem) - goto err; + return ERR_PTR(-ENXIO); - pcc_mchan->manage_writes = false; - - /* This indicates that the channel is ready to accept messages. - * This needs to happen after the channel has registered - * its callback. There is no access point to do that in - * the mailbox API. That implies that the mailbox client must - * have set the allocate callback function prior to - * sending any messages. - */ - if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE) - pcc_chan_reg_read_modify_write(&pchan->cmd_update); + rc = mbox_bind_client(chan, cl); + if (rc) { + iounmap(pcc_mchan->shmem); + pcc_mchan->shmem = NULL; + return ERR_PTR(rc); + } return pcc_mchan; - -err: - mbox_free_channel(chan); - return ERR_PTR(-ENXIO); } EXPORT_SYMBOL_GPL(pcc_mbox_request_channel); @@ -459,38 +419,8 @@ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan) } EXPORT_SYMBOL_GPL(pcc_mbox_free_channel); -static int pcc_write_to_buffer(struct mbox_chan *chan, void *data) -{ - struct pcc_chan_info *pchan = chan->con_priv; - struct pcc_mbox_chan *pcc_mbox_chan = &pchan->chan; - struct pcc_header *pcc_header = data; - - if (!pchan->chan.manage_writes) - return 0; - - /* The PCC header length includes the command field - * but not the other values from the header. - */ - int len = pcc_header->length - sizeof(u32) + sizeof(struct pcc_header); - u64 val; - - pcc_chan_reg_read(&pchan->cmd_complete, &val); - if (!val) { - pr_info("%s pchan->cmd_complete not set", __func__); - return -1; - } - memcpy_toio(pcc_mbox_chan->shmem, data, len); - return 0; -} - - /** - * pcc_send_data - Called from Mailbox Controller code. If - * pchan->chan.rx_alloc is set, then the command complete - * flag is checked and the data is written to the shared - * buffer io memory. - * - * If pchan->chan.rx_alloc is not set, then it is used + * pcc_send_data - Called from Mailbox Controller code. Used * here only to ring the channel doorbell. The PCC client * specific read/write is done in the client driver in * order to maintain atomicity over PCC channel once @@ -506,37 +436,24 @@ static int pcc_send_data(struct mbox_chan *chan, void *data) int ret; struct pcc_chan_info *pchan = chan->con_priv; - ret = pcc_write_to_buffer(chan, data); - if (ret) - return ret; - ret = pcc_chan_reg_read_modify_write(&pchan->cmd_update); if (ret) return ret; ret = pcc_chan_reg_read_modify_write(&pchan->db); - if (!ret && pchan->plat_irq > 0) pchan->chan_in_use = true; return ret; } - static bool pcc_last_tx_done(struct mbox_chan *chan) { struct pcc_chan_info *pchan = chan->con_priv; - u64 val; - pcc_chan_reg_read(&pchan->cmd_complete, &val); - if (!val) - return false; - else - return true; + return pcc_mbox_cmd_complete_check(pchan); } - - /** * pcc_startup - Called from Mailbox Controller code. Used here * to request the interrupt. @@ -550,9 +467,15 @@ static int pcc_startup(struct mbox_chan *chan) unsigned long irqflags; int rc; + /* + * Clear and acknowledge any pending interrupts on responder channel + * before enabling the interrupt + */ + pcc_chan_acknowledge(pchan); + if (pchan->plat_irq > 0) { irqflags = pcc_chan_plat_irq_can_be_shared(pchan) ? - IRQF_SHARED | IRQF_ONESHOT : 0; + IRQF_SHARED : 0; rc = devm_request_irq(chan->mbox->dev, pchan->plat_irq, pcc_mbox_irq, irqflags, MBOX_IRQ_NAME, chan); if (unlikely(rc)) { @@ -877,8 +800,13 @@ static int pcc_mbox_probe(struct platform_device *pdev) (unsigned long) pcct_tbl + sizeof(struct acpi_table_pcct)); acpi_pcct_tbl = (struct acpi_table_pcct *) pcct_tbl; - if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) + if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL) { pcc_mbox_ctrl->txdone_irq = true; + pcc_mbox_ctrl->txdone_poll = false; + } else { + pcc_mbox_ctrl->txdone_irq = false; + pcc_mbox_ctrl->txdone_poll = true; + } for (i = 0; i < count; i++) { struct pcc_chan_info *pchan = chan_info + i; diff --git a/drivers/mailbox/sprd-mailbox.c b/drivers/mailbox/sprd-mailbox.c index ee8539dfcef5..565502904e1f 100644 --- a/drivers/mailbox/sprd-mailbox.c +++ b/drivers/mailbox/sprd-mailbox.c @@ -24,7 +24,8 @@ #define SPRD_MBOX_IRQ_STS 0x18 #define SPRD_MBOX_IRQ_MSK 0x1c #define SPRD_MBOX_LOCK 0x20 -#define SPRD_MBOX_FIFO_DEPTH 0x24 +#define SPRD_MBOX_FIFO_DEPTH 0x24 /* outbox only */ +#define SPRD_MBOX_IN_FIFO_STS2 0x24 /* inbox only, revision 2 */ /* Bit and mask definition for inbox's SPRD_MBOX_FIFO_STS register */ #define SPRD_INBOX_FIFO_DELIVER_MASK GENMASK(23, 16) @@ -32,8 +33,18 @@ #define SPRD_INBOX_FIFO_DELIVER_SHIFT 16 #define SPRD_INBOX_FIFO_BUSY_MASK GENMASK(7, 0) +/* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_RST register */ +#define SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST GENMASK(31, 0) + +/* Bit and mask definition for R2 inbox's SPRD_MBOX_FIFO_STS register */ +#define SPRD_INBOX_R2_FIFO_DELIVER_MASK GENMASK(15, 0) + +/* Bit and mask definition for SPRD_MBOX_IN_FIFO_STS2 register */ +#define SPRD_INBOX_R2_FIFO_OVERFLOW_MASK GENMASK(31, 16) +#define SPRD_INBOX_R2_FIFO_BUSY_MASK GENMASK(15, 0) + /* Bit and mask definition for SPRD_MBOX_IRQ_STS register */ -#define SPRD_MBOX_IRQ_CLR BIT(0) +#define SPRD_MBOX_IRQ_CLR GENMASK(31, 0) /* Bit and mask definition for outbox's SPRD_MBOX_FIFO_STS register */ #define SPRD_OUTBOX_FIFO_FULL BIT(2) @@ -52,8 +63,18 @@ #define SPRD_OUTBOX_FIFO_IRQ_MASK GENMASK(4, 0) #define SPRD_OUTBOX_BASE_SPAN 0x1000 -#define SPRD_MBOX_CHAN_MAX 8 -#define SPRD_SUPP_INBOX_ID_SC9863A 7 +#define SPRD_MBOX_R1_CHAN_MAX 8 +#define SPRD_MBOX_R2_CHAN_MAX 16 + +enum sprd_mbox_version { + SPRD_MBOX_R1, + SPRD_MBOX_R2, +}; + +struct sprd_mbox_info { + enum sprd_mbox_version version; + unsigned long supp_id; +}; struct sprd_mbox_priv { struct mbox_controller mbox; @@ -64,9 +85,11 @@ struct sprd_mbox_priv { void __iomem *supp_base; u32 outbox_fifo_depth; + const struct sprd_mbox_info *info; + struct mutex lock; u32 refcnt; - struct mbox_chan chan[SPRD_MBOX_CHAN_MAX]; + struct mbox_chan chan[SPRD_MBOX_R2_CHAN_MAX]; }; static struct sprd_mbox_priv *to_sprd_mbox_priv(struct mbox_controller *mbox) @@ -154,18 +177,35 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data) { struct sprd_mbox_priv *priv = data; struct mbox_chan *chan; - u32 fifo_sts, send_sts, busy, id; + u32 fifo_sts, fifo_sts2, send_sts, busy, id; fifo_sts = readl(priv->inbox_base + SPRD_MBOX_FIFO_STS); + if (priv->info->version == SPRD_MBOX_R2) + fifo_sts2 = readl(priv->inbox_base + SPRD_MBOX_IN_FIFO_STS2); + /* Get the inbox data delivery status */ - send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >> - SPRD_INBOX_FIFO_DELIVER_SHIFT; + if (priv->info->version == SPRD_MBOX_R2) { + send_sts = fifo_sts & SPRD_INBOX_R2_FIFO_DELIVER_MASK; + } else { + send_sts = (fifo_sts & SPRD_INBOX_FIFO_DELIVER_MASK) >> + SPRD_INBOX_FIFO_DELIVER_SHIFT; + } + if (!send_sts) { dev_warn_ratelimited(priv->dev, "spurious inbox interrupt\n"); return IRQ_NONE; } + /* Clear FIFO delivery and overflow status first */ + if (priv->info->version == SPRD_MBOX_R2) { + writel(SPRD_INBOX_R2_FIFO_OVERFLOW_DELIVER_RST, + priv->inbox_base + SPRD_MBOX_FIFO_RST); + } else { + writel(fifo_sts & (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK), + priv->inbox_base + SPRD_MBOX_FIFO_RST); + } + while (send_sts) { id = __ffs(send_sts); send_sts &= (send_sts - 1); @@ -176,16 +216,15 @@ static irqreturn_t sprd_mbox_inbox_isr(int irq, void *data) * Check if the message was fetched by remote target, if yes, * that means the transmission has been completed. */ - busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK; + if (priv->info->version == SPRD_MBOX_R2) + busy = fifo_sts2 & SPRD_INBOX_R2_FIFO_BUSY_MASK; + else + busy = fifo_sts & SPRD_INBOX_FIFO_BUSY_MASK; + if (!(busy & BIT(id))) mbox_chan_txdone(chan, 0); } - /* Clear FIFO delivery and overflow status */ - writel(fifo_sts & - (SPRD_INBOX_FIFO_DELIVER_MASK | SPRD_INBOX_FIFO_OVERLOW_MASK), - priv->inbox_base + SPRD_MBOX_FIFO_RST); - /* Clear irq status */ writel(SPRD_MBOX_IRQ_CLR, priv->inbox_base + SPRD_MBOX_IRQ_STS); @@ -243,21 +282,19 @@ static int sprd_mbox_startup(struct mbox_chan *chan) /* Select outbox FIFO mode and reset the outbox FIFO status */ writel(0x0, priv->outbox_base + SPRD_MBOX_FIFO_RST); - /* Enable inbox FIFO overflow and delivery interrupt */ - val = readl(priv->inbox_base + SPRD_MBOX_IRQ_MSK); - val &= ~(SPRD_INBOX_FIFO_OVERFLOW_IRQ | SPRD_INBOX_FIFO_DELIVER_IRQ); + /* Enable inbox FIFO delivery interrupt */ + val = SPRD_INBOX_FIFO_IRQ_MASK; + val &= ~SPRD_INBOX_FIFO_DELIVER_IRQ; writel(val, priv->inbox_base + SPRD_MBOX_IRQ_MSK); /* Enable outbox FIFO not empty interrupt */ - val = readl(priv->outbox_base + SPRD_MBOX_IRQ_MSK); + val = SPRD_OUTBOX_FIFO_IRQ_MASK; val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ; writel(val, priv->outbox_base + SPRD_MBOX_IRQ_MSK); /* Enable supplementary outbox as the fundamental one */ if (priv->supp_base) { writel(0x0, priv->supp_base + SPRD_MBOX_FIFO_RST); - val = readl(priv->supp_base + SPRD_MBOX_IRQ_MSK); - val &= ~SPRD_OUTBOX_FIFO_NOT_EMPTY_IRQ; writel(val, priv->supp_base + SPRD_MBOX_IRQ_MSK); } } @@ -295,7 +332,7 @@ static int sprd_mbox_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct sprd_mbox_priv *priv; int ret, inbox_irq, outbox_irq, supp_irq; - unsigned long id, supp; + unsigned long id; struct clk *clk; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -305,6 +342,10 @@ static int sprd_mbox_probe(struct platform_device *pdev) priv->dev = dev; mutex_init(&priv->lock); + priv->info = of_device_get_match_data(dev); + if (!priv->info) + return -EINVAL; + /* * Unisoc mailbox uses an inbox to send messages to the target * core, and uses (an) outbox(es) to receive messages from other @@ -362,12 +403,12 @@ static int sprd_mbox_probe(struct platform_device *pdev) return ret; } - supp = (unsigned long) of_device_get_match_data(dev); - if (!supp) { + if (!priv->info->supp_id) { dev_err(dev, "no supplementary outbox specified\n"); return -ENODEV; } - priv->supp_base = priv->outbox_base + (SPRD_OUTBOX_BASE_SPAN * supp); + priv->supp_base = priv->outbox_base + + (SPRD_OUTBOX_BASE_SPAN * priv->info->supp_id); } /* Get the default outbox FIFO depth */ @@ -375,11 +416,15 @@ static int sprd_mbox_probe(struct platform_device *pdev) readl(priv->outbox_base + SPRD_MBOX_FIFO_DEPTH) + 1; priv->mbox.dev = dev; priv->mbox.chans = &priv->chan[0]; - priv->mbox.num_chans = SPRD_MBOX_CHAN_MAX; priv->mbox.ops = &sprd_mbox_ops; priv->mbox.txdone_irq = true; - for (id = 0; id < SPRD_MBOX_CHAN_MAX; id++) + if (priv->info->version == SPRD_MBOX_R2) + priv->mbox.num_chans = SPRD_MBOX_R2_CHAN_MAX; + else + priv->mbox.num_chans = SPRD_MBOX_R1_CHAN_MAX; + + for (id = 0; id < priv->mbox.num_chans; id++) priv->chan[id].con_priv = (void *)id; ret = devm_mbox_controller_register(dev, &priv->mbox); @@ -391,10 +436,24 @@ static int sprd_mbox_probe(struct platform_device *pdev) return 0; } +static const struct sprd_mbox_info sc9860_mbox_info = { + .version = SPRD_MBOX_R1, +}; + +static const struct sprd_mbox_info sc9863a_mbox_info = { + .version = SPRD_MBOX_R1, + .supp_id = 7, +}; + +static const struct sprd_mbox_info ums9230_mbox_info = { + .version = SPRD_MBOX_R2, + .supp_id = 6, +}; + static const struct of_device_id sprd_mbox_of_match[] = { - { .compatible = "sprd,sc9860-mailbox" }, - { .compatible = "sprd,sc9863a-mailbox", - .data = (void *)SPRD_SUPP_INBOX_ID_SC9863A }, + { .compatible = "sprd,sc9860-mailbox", .data = &sc9860_mbox_info }, + { .compatible = "sprd,sc9863a-mailbox", .data = &sc9863a_mbox_info }, + { .compatible = "sprd,ums9230-mailbox", .data = &ums9230_mbox_info }, { }, }; MODULE_DEVICE_TABLE(of, sprd_mbox_of_match); diff --git a/drivers/mailbox/zynqmp-ipi-mailbox.c b/drivers/mailbox/zynqmp-ipi-mailbox.c index 967967b2b8a9..42d2583e44ca 100644 --- a/drivers/mailbox/zynqmp-ipi-mailbox.c +++ b/drivers/mailbox/zynqmp-ipi-mailbox.c @@ -904,7 +904,7 @@ static void zynqmp_ipi_free_mboxes(struct zynqmp_ipi_pdata *pdata) static int zynqmp_ipi_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *nc, *np = pdev->dev.of_node; + struct device_node *np = pdev->dev.of_node; struct zynqmp_ipi_pdata *pdata; struct of_phandle_args out_irq; struct zynqmp_ipi_mbox *mbox; @@ -940,13 +940,12 @@ static int zynqmp_ipi_probe(struct platform_device *pdev) pdata->num_mboxes = num_mboxes; mbox = pdata->ipi_mboxes; - for_each_available_child_of_node(np, nc) { + for_each_available_child_of_node_scoped(np, nc) { mbox->pdata = pdata; mbox->setup_ipi_fn = ipi_fn; ret = zynqmp_ipi_mbox_probe(mbox, nc); if (ret) { - of_node_put(nc); dev_err(dev, "failed to probe subdev.\n"); ret = -EINVAL; goto free_mbox_dev; diff --git a/drivers/mcb/mcb-core.c b/drivers/mcb/mcb-core.c index c1367223e71a..e6e7c11bac6c 100644 --- a/drivers/mcb/mcb-core.c +++ b/drivers/mcb/mcb-core.c @@ -85,7 +85,8 @@ static void mcb_remove(struct device *dev) struct mcb_device *mdev = to_mcb_device(dev); struct module *carrier_mod; - mdrv->remove(mdev); + if (mdrv->remove) + mdrv->remove(mdev); carrier_mod = mdev->dev.parent->driver->owner; module_put(carrier_mod); @@ -176,13 +177,13 @@ static const struct device_type mcb_carrier_device_type = { * @owner: The @mcb_driver's module * @mod_name: The name of the @mcb_driver's module * - * Register a @mcb_driver at the system. Perform some sanity checks, if - * the .probe and .remove methods are provided by the driver. + * Register a @mcb_driver at the system. Perform a sanity check, if + * .probe method is provided by the driver. */ int __mcb_register_driver(struct mcb_driver *drv, struct module *owner, const char *mod_name) { - if (!drv->probe || !drv->remove) + if (!drv->probe) return -EINVAL; drv->driver.owner = owner; @@ -273,7 +274,7 @@ struct mcb_bus *mcb_alloc_bus(struct device *carrier) int bus_nr; int rc; - bus = kzalloc(sizeof(struct mcb_bus), GFP_KERNEL); + bus = kzalloc_obj(struct mcb_bus); if (!bus) return ERR_PTR(-ENOMEM); @@ -365,7 +366,7 @@ struct mcb_device *mcb_alloc_dev(struct mcb_bus *bus) { struct mcb_device *dev; - dev = kzalloc(sizeof(struct mcb_device), GFP_KERNEL); + dev = kzalloc_obj(struct mcb_device); if (!dev) return NULL; diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c index bf0d7d58c8b0..7e09a0ea80f8 100644 --- a/drivers/mcb/mcb-parse.c +++ b/drivers/mcb/mcb-parse.c @@ -146,15 +146,14 @@ static int chameleon_get_bar(void __iomem **base, phys_addr_t mapbase, if (bar_count <= 0 || bar_count > CHAMELEON_BAR_MAX) return -ENODEV; - c = kcalloc(bar_count, sizeof(struct chameleon_bar), - GFP_KERNEL); + c = kzalloc_objs(struct chameleon_bar, bar_count); if (!c) return -ENOMEM; chameleon_parse_bar(*base, c, bar_count); *base += BAR_DESC_SIZE(bar_count); } else { - c = kzalloc(sizeof(struct chameleon_bar), GFP_KERNEL); + c = kzalloc_obj(struct chameleon_bar); if (!c) return -ENOMEM; diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index 7708d92df23e..3ec240ec685d 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -697,7 +697,7 @@ int bch_open_buckets_alloc(struct cache_set *c) spin_lock_init(&c->data_bucket_lock); for (i = 0; i < MAX_OPEN_BUCKETS; i++) { - struct open_bucket *b = kzalloc(sizeof(*b), GFP_KERNEL); + struct open_bucket *b = kzalloc_obj(*b); if (!b) return -ENOMEM; diff --git a/drivers/md/bcache/btree.c b/drivers/md/bcache/btree.c index 3ed39c823826..27a129d47d0a 100644 --- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -585,7 +585,7 @@ static struct btree *mca_bucket_alloc(struct cache_set *c, * kzalloc() is necessary here for initialization, * see code comments in bch_btree_keys_init(). */ - struct btree *b = kzalloc(sizeof(struct btree), gfp); + struct btree *b = kzalloc_obj(struct btree, gfp); if (!b) return NULL; diff --git a/drivers/md/bcache/debug.c b/drivers/md/bcache/debug.c index f327456fc4e0..2691a5da3368 100644 --- a/drivers/md/bcache/debug.c +++ b/drivers/md/bcache/debug.c @@ -208,7 +208,7 @@ static int bch_dump_open(struct inode *inode, struct file *file) struct cache_set *c = inode->i_private; struct dump_iterator *i; - i = kzalloc(sizeof(struct dump_iterator), GFP_KERNEL); + i = kzalloc_obj(struct dump_iterator); if (!i) return -ENOMEM; diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 238d12ffdae8..64bb38c95895 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1527,8 +1527,7 @@ static CLOSURE_CALLBACK(flash_dev_flush) static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) { int err = -ENOMEM; - struct bcache_device *d = kzalloc(sizeof(struct bcache_device), - GFP_KERNEL); + struct bcache_device *d = kzalloc_obj(struct bcache_device); if (!d) goto err_ret; @@ -1864,7 +1863,7 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) { int iter_size; struct cache *ca = container_of(sb, struct cache, sb); - struct cache_set *c = kzalloc(sizeof(struct cache_set), GFP_KERNEL); + struct cache_set *c = kzalloc_obj(struct cache_set); if (!c) return NULL; @@ -2543,8 +2542,8 @@ static void register_device_async(struct async_reg_args *args) static void *alloc_holder_object(struct cache_sb *sb) { if (SB_IS_BDEV(sb)) - return kzalloc(sizeof(struct cached_dev), GFP_KERNEL); - return kzalloc(sizeof(struct cache), GFP_KERNEL); + return kzalloc_obj(struct cached_dev); + return kzalloc_obj(struct cache); } static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, @@ -2581,7 +2580,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, if (!path) goto out_module_put; - sb = kmalloc(sizeof(struct cache_sb), GFP_KERNEL); + sb = kmalloc_obj(struct cache_sb); if (!sb) goto out_free_path; @@ -2633,7 +2632,7 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, if (async_registration) { /* register in asynchronous way */ struct async_reg_args *args = - kzalloc(sizeof(struct async_reg_args), GFP_KERNEL); + kzalloc_obj(struct async_reg_args); if (!args) { ret = -ENOMEM; @@ -2710,7 +2709,7 @@ static ssize_t bch_pending_bdevs_cleanup(struct kobject *k, mutex_lock(&bch_register_lock); list_for_each_entry_safe(dc, tdc, &uncached_devices, list) { - pdev = kmalloc(sizeof(struct pdev), GFP_KERNEL); + pdev = kmalloc_obj(struct pdev); if (!pdev) break; pdev->dc = dc; diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c index 72f38e5b6f5c..cfac56caa804 100644 --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -415,7 +415,7 @@ STORE(__cached_dev) buf, SB_LABEL_SIZE); bch_uuid_write(dc->disk.c); } - env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); + env = kzalloc_obj(struct kobj_uevent_env); if (!env) return -ENOMEM; add_uevent_var(env, "DRIVER=bcache"); diff --git a/drivers/md/dm-bio-prison-v1.c b/drivers/md/dm-bio-prison-v1.c index b4d1c4329df3..4d1464dae5eb 100644 --- a/drivers/md/dm-bio-prison-v1.c +++ b/drivers/md/dm-bio-prison-v1.c @@ -44,7 +44,7 @@ struct dm_bio_prison *dm_bio_prison_create(void) struct dm_bio_prison *prison; num_locks = dm_num_hash_locks(); - prison = kzalloc(struct_size(prison, regions, num_locks), GFP_KERNEL); + prison = kzalloc_flex(*prison, regions, num_locks); if (!prison) return NULL; prison->num_locks = num_locks; @@ -301,7 +301,7 @@ struct dm_deferred_set *dm_deferred_set_create(void) int i; struct dm_deferred_set *ds; - ds = kmalloc(sizeof(*ds), GFP_KERNEL); + ds = kmalloc_obj(*ds); if (!ds) return NULL; diff --git a/drivers/md/dm-bio-prison-v2.c b/drivers/md/dm-bio-prison-v2.c index cf433b0cf742..4e2af53ad99e 100644 --- a/drivers/md/dm-bio-prison-v2.c +++ b/drivers/md/dm-bio-prison-v2.c @@ -36,7 +36,7 @@ static struct kmem_cache *_cell_cache; */ struct dm_bio_prison_v2 *dm_bio_prison_create_v2(struct workqueue_struct *wq) { - struct dm_bio_prison_v2 *prison = kzalloc(sizeof(*prison), GFP_KERNEL); + struct dm_bio_prison_v2 *prison = kzalloc_obj(*prison); int ret; if (!prison) diff --git a/drivers/md/dm-cache-background-tracker.c b/drivers/md/dm-cache-background-tracker.c index b4165f172d62..2ca3a3e2e50e 100644 --- a/drivers/md/dm-cache-background-tracker.c +++ b/drivers/md/dm-cache-background-tracker.c @@ -26,7 +26,7 @@ struct kmem_cache *btracker_work_cache = NULL; struct background_tracker *btracker_create(unsigned int max_work) { - struct background_tracker *b = kmalloc(sizeof(*b), GFP_KERNEL); + struct background_tracker *b = kmalloc_obj(*b); if (!b) { DMERR("couldn't create background_tracker"); diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index a9a1ab284076..57158c02d096 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -760,7 +760,7 @@ static struct dm_cache_metadata *metadata_open(struct block_device *bdev, int r; struct dm_cache_metadata *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { DMERR("could not allocate metadata struct"); return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-cache-policy-smq.c b/drivers/md/dm-cache-policy-smq.c index 7e1e8cc0e33a..b328d9601046 100644 --- a/drivers/md/dm-cache-policy-smq.c +++ b/drivers/md/dm-cache-policy-smq.c @@ -1735,7 +1735,7 @@ __smq_create(dm_cblock_t cache_size, sector_t origin_size, sector_t cache_block_ unsigned int i; unsigned int nr_sentinels_per_queue = 2u * NR_CACHE_LEVELS; unsigned int total_sentinels = 2u * nr_sentinels_per_queue; - struct smq_policy *mq = kzalloc(sizeof(*mq), GFP_KERNEL); + struct smq_policy *mq = kzalloc_obj(*mq); if (!mq) return NULL; diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 62d1060619dd..935ab79b1d0c 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2387,7 +2387,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) struct dm_cache_metadata *cmd; bool may_format = ca->features.mode == CM_WRITE; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (!cache) return -ENOMEM; @@ -2612,7 +2612,7 @@ static int cache_ctr(struct dm_target *ti, unsigned int argc, char **argv) struct cache_args *ca; struct cache *cache = NULL; - ca = kzalloc(sizeof(*ca), GFP_KERNEL); + ca = kzalloc_obj(*ca); if (!ca) { ti->error = "Error allocating memory for cache"; return -ENOMEM; diff --git a/drivers/md/dm-clone-metadata.c b/drivers/md/dm-clone-metadata.c index 14c5c28d938b..e50a5b5a4aea 100644 --- a/drivers/md/dm-clone-metadata.c +++ b/drivers/md/dm-clone-metadata.c @@ -553,7 +553,7 @@ struct dm_clone_metadata *dm_clone_metadata_open(struct block_device *bdev, int r; struct dm_clone_metadata *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { DMERR("Failed to allocate memory for dm-clone metadata"); return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-clone-target.c b/drivers/md/dm-clone-target.c index a7f73861a8cd..c0f9b93983d4 100644 --- a/drivers/md/dm-clone-target.c +++ b/drivers/md/dm-clone-target.c @@ -580,7 +580,7 @@ static int hash_table_init(struct clone *clone) sz = 1 << HASH_TABLE_BITS; - clone->ht = kvmalloc_array(sz, sizeof(struct hash_table_bucket), GFP_KERNEL); + clone->ht = kvmalloc_objs(struct hash_table_bucket, sz); if (!clone->ht) return -ENOMEM; @@ -1766,7 +1766,7 @@ static int clone_ctr(struct dm_target *ti, unsigned int argc, char **argv) as.argc = argc; as.argv = argv; - clone = kzalloc(sizeof(*clone), GFP_KERNEL); + clone = kzalloc_obj(*clone); if (!clone) { ti->error = "Failed to allocate clone structure"; return -ENOMEM; diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index cd279a4f335d..54823341c9fd 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -2334,9 +2334,8 @@ static int crypt_alloc_tfms_skcipher(struct crypt_config *cc, char *ciphermode) unsigned int i; int err; - cc->cipher_tfm.tfms = kcalloc(cc->tfms_count, - sizeof(struct crypto_skcipher *), - GFP_KERNEL); + cc->cipher_tfm.tfms = kzalloc_objs(struct crypto_skcipher *, + cc->tfms_count); if (!cc->cipher_tfm.tfms) return -ENOMEM; @@ -2364,7 +2363,7 @@ static int crypt_alloc_tfms_aead(struct crypt_config *cc, char *ciphermode) { int err; - cc->cipher_tfm.tfms = kmalloc(sizeof(struct crypto_aead *), GFP_KERNEL); + cc->cipher_tfm.tfms = kmalloc_obj(struct crypto_skcipher *); if (!cc->cipher_tfm.tfms) return -ENOMEM; @@ -3238,7 +3237,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - cc = kzalloc(struct_size(cc, key, key_size), GFP_KERNEL); + cc = kzalloc_flex(*cc, key, key_size); if (!cc) { ti->error = "Cannot allocate encryption context"; return -ENOMEM; diff --git a/drivers/md/dm-delay.c b/drivers/md/dm-delay.c index 029f04776490..4864671c2222 100644 --- a/drivers/md/dm-delay.c +++ b/drivers/md/dm-delay.c @@ -224,7 +224,7 @@ static int delay_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - dc = kzalloc(sizeof(*dc), GFP_KERNEL); + dc = kzalloc_obj(*dc); if (!dc) { ti->error = "Cannot allocate context"; return -ENOMEM; diff --git a/drivers/md/dm-dust.c b/drivers/md/dm-dust.c index e75310232bbf..c7e3077fb1f5 100644 --- a/drivers/md/dm-dust.c +++ b/drivers/md/dm-dust.c @@ -108,7 +108,7 @@ static int dust_add_block(struct dust_device *dd, unsigned long long block, struct badblock *bblock; unsigned long flags; - bblock = kmalloc(sizeof(*bblock), GFP_KERNEL); + bblock = kmalloc_obj(*bblock); if (bblock == NULL) { if (!dd->quiet_mode) DMERR("%s: badblock allocation failed", __func__); @@ -360,7 +360,7 @@ static int dust_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - dd = kzalloc(sizeof(struct dust_device), GFP_KERNEL); + dd = kzalloc_obj(struct dust_device); if (dd == NULL) { ti->error = "Cannot allocate context"; return -ENOMEM; diff --git a/drivers/md/dm-ebs-target.c b/drivers/md/dm-ebs-target.c index b354e74a670e..1e52bde48b91 100644 --- a/drivers/md/dm-ebs-target.c +++ b/drivers/md/dm-ebs-target.c @@ -257,7 +257,7 @@ static int ebs_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - ec = ti->private = kzalloc(sizeof(*ec), GFP_KERNEL); + ec = ti->private = kzalloc_obj(*ec); if (!ec) { ti->error = "Cannot allocate ebs context"; return -ENOMEM; diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c index 9c84e9d13eca..05285c04ff2c 100644 --- a/drivers/md/dm-era-target.c +++ b/drivers/md/dm-era-target.c @@ -808,7 +808,7 @@ static struct era_metadata *metadata_open(struct block_device *bdev, bool may_format) { int r; - struct era_metadata *md = kzalloc(sizeof(*md), GFP_KERNEL); + struct era_metadata *md = kzalloc_obj(*md); if (!md) return NULL; @@ -1473,7 +1473,7 @@ static int era_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - era = kzalloc(sizeof(*era), GFP_KERNEL); + era = kzalloc_obj(*era); if (!era) { ti->error = "Error allocating era structure"; return -ENOMEM; diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c index 88f119a0a2ae..58cbc5e5475b 100644 --- a/drivers/md/dm-exception-store.c +++ b/drivers/md/dm-exception-store.c @@ -204,7 +204,7 @@ int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, return -EINVAL; } - tmp_store = kzalloc(sizeof(*tmp_store), GFP_KERNEL); + tmp_store = kzalloc_obj(*tmp_store); if (!tmp_store) { ti->error = "Exception store allocation failed"; return -ENOMEM; diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 08925aca838c..572225b0e691 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -277,7 +277,7 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - fc = kzalloc(sizeof(*fc), GFP_KERNEL); + fc = kzalloc_obj(*fc); if (!fc) { ti->error = "Cannot allocate context"; return -ENOMEM; diff --git a/drivers/md/dm-init.c b/drivers/md/dm-init.c index b37bbe762500..7403823384c5 100644 --- a/drivers/md/dm-init.c +++ b/drivers/md/dm-init.c @@ -127,7 +127,7 @@ static char __init *dm_parse_table_entry(struct dm_device *dev, char *str) /* Delimit last field that can be terminated by comma */ next = str_field_delimit(&field[i], ','); - sp = kzalloc(sizeof(*sp), GFP_KERNEL); + sp = kzalloc_obj(*sp); if (!sp) return ERR_PTR(-ENOMEM); dev->table[n] = sp; @@ -244,7 +244,7 @@ static int __init dm_parse_devices(struct list_head *devices, char *str) DMDEBUG("parsing \"%s\"", str); while (device) { - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; list_add_tail(&dev->list, devices); diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index 681b00958d42..06e805902151 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -4243,7 +4243,8 @@ static struct page_list *dm_integrity_alloc_page_list(unsigned int n_pages) struct page_list *pl; unsigned int i; - pl = kvmalloc_array(n_pages + 1, sizeof(struct page_list), GFP_KERNEL | __GFP_ZERO); + pl = kvmalloc_objs(struct page_list, n_pages + 1, + GFP_KERNEL | __GFP_ZERO); if (!pl) return NULL; @@ -4277,9 +4278,8 @@ static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_int struct scatterlist **sl; unsigned int i; - sl = kvmalloc_array(ic->journal_sections, - sizeof(struct scatterlist *), - GFP_KERNEL | __GFP_ZERO); + sl = kvmalloc_objs(struct scatterlist *, ic->journal_sections, + GFP_KERNEL | __GFP_ZERO); if (!sl) return NULL; @@ -4296,8 +4296,7 @@ static struct scatterlist **dm_integrity_alloc_journal_scatterlist(struct dm_int n_pages = (end_index - start_index + 1); - s = kvmalloc_array(n_pages, sizeof(struct scatterlist), - GFP_KERNEL); + s = kvmalloc_objs(struct scatterlist, n_pages); if (!s) { dm_integrity_free_journal_scatterlist(ic, sl); return NULL; @@ -4500,9 +4499,8 @@ static int create_journal(struct dm_integrity_c *ic, char **error) goto bad; } - sg = kvmalloc_array(ic->journal_pages + 1, - sizeof(struct scatterlist), - GFP_KERNEL); + sg = kvmalloc_objs(struct scatterlist, + ic->journal_pages + 1); if (!sg) { *error = "Unable to allocate sg list"; r = -ENOMEM; @@ -4569,9 +4567,9 @@ static int create_journal(struct dm_integrity_c *ic, char **error) r = -ENOMEM; goto bad; } - ic->sk_requests = kvmalloc_array(ic->journal_sections, - sizeof(struct skcipher_request *), - GFP_KERNEL | __GFP_ZERO); + ic->sk_requests = kvmalloc_objs(struct skcipher_request *, + ic->journal_sections, + GFP_KERNEL | __GFP_ZERO); if (!ic->sk_requests) { *error = "Unable to allocate sk requests"; r = -ENOMEM; @@ -4703,7 +4701,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv return -EINVAL; } - ic = kzalloc(sizeof(struct dm_integrity_c), GFP_KERNEL); + ic = kzalloc_obj(struct dm_integrity_c); if (!ic) { ti->error = "Cannot allocate integrity context"; return -ENOMEM; @@ -5272,7 +5270,8 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned int argc, char **argv r = -ENOMEM; goto bad; } - ic->bbs = kvmalloc_array(ic->n_bitmap_blocks, sizeof(struct bitmap_block_status), GFP_KERNEL); + ic->bbs = kvmalloc_objs(struct bitmap_block_status, + ic->n_bitmap_blocks); if (!ic->bbs) { ti->error = "Could not allocate memory for bitmap"; r = -ENOMEM; diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index c37668790577..1db565b37620 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c @@ -52,7 +52,7 @@ struct dm_io_client *dm_io_client_create(void) unsigned int min_ios = dm_get_reserved_bio_based_ios(); int ret; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index fd4bf8e1d73e..3ab8b4beff86 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c @@ -218,7 +218,7 @@ static struct hash_cell *alloc_cell(const char *name, const char *uuid, { struct hash_cell *hc; - hc = kmalloc(sizeof(*hc), GFP_KERNEL); + hc = kmalloc_obj(*hc); if (!hc) return NULL; @@ -2136,7 +2136,7 @@ static int dm_open(struct inode *inode, struct file *filp) if (unlikely(r)) return r; - priv = filp->private_data = kmalloc(sizeof(struct dm_file), GFP_KERNEL); + priv = filp->private_data = kmalloc_obj(struct dm_file); if (!priv) return -ENOMEM; diff --git a/drivers/md/dm-kcopyd.c b/drivers/md/dm-kcopyd.c index cec9a60227b6..96c8b8ff61c2 100644 --- a/drivers/md/dm-kcopyd.c +++ b/drivers/md/dm-kcopyd.c @@ -219,7 +219,7 @@ static struct page_list *alloc_pl(gfp_t gfp) { struct page_list *pl; - pl = kmalloc(sizeof(*pl), gfp); + pl = kmalloc_obj(*pl, gfp); if (!pl) return NULL; @@ -918,7 +918,7 @@ struct dm_kcopyd_client *dm_kcopyd_client_create(struct dm_kcopyd_throttle *thro unsigned int reserve_pages; struct dm_kcopyd_client *kc; - kc = kzalloc(sizeof(*kc), GFP_KERNEL); + kc = kzalloc_obj(*kc); if (!kc) return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c index 73bf290af181..38c17846deb0 100644 --- a/drivers/md/dm-linear.c +++ b/drivers/md/dm-linear.c @@ -39,7 +39,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - lc = kmalloc(sizeof(*lc), GFP_KERNEL); + lc = kmalloc_obj(*lc); if (lc == NULL) { ti->error = "Cannot allocate linear context"; return -ENOMEM; diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c index 607436804a8b..9d5918eb0a30 100644 --- a/drivers/md/dm-log-userspace-base.c +++ b/drivers/md/dm-log-userspace-base.c @@ -205,7 +205,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti, return -EINVAL; } - lc = kzalloc(sizeof(*lc), GFP_KERNEL); + lc = kzalloc_obj(*lc); if (!lc) { DMWARN("Unable to allocate userspace log context."); return -ENOMEM; diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c index f0c84e7a5daa..c72e07c3f5a0 100644 --- a/drivers/md/dm-log-writes.c +++ b/drivers/md/dm-log-writes.c @@ -519,7 +519,7 @@ static int log_writes_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - lc = kzalloc(sizeof(struct log_writes_c), GFP_KERNEL); + lc = kzalloc_obj(struct log_writes_c); if (!lc) { ti->error = "Cannot allocate context"; return -ENOMEM; @@ -587,7 +587,7 @@ static int log_mark(struct log_writes_c *lc, char *data) struct pending_block *block; size_t maxsize = lc->sectorsize - sizeof(struct log_write_entry); - block = kzalloc(sizeof(struct pending_block), GFP_KERNEL); + block = kzalloc_obj(struct pending_block); if (!block) { DMERR("Error allocating pending block"); return -ENOMEM; diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index bced5a783ee3..1aa6a4a7d232 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -153,7 +153,7 @@ struct dm_dirty_log *dm_dirty_log_create(const char *type_name, struct dm_dirty_log_type *type; struct dm_dirty_log *log; - log = kmalloc(sizeof(*log), GFP_KERNEL); + log = kmalloc_obj(*log); if (!log) return NULL; @@ -402,7 +402,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, region_count = dm_sector_div_up(ti->len, region_size); - lc = kmalloc(sizeof(*lc), GFP_KERNEL); + lc = kmalloc_obj(*lc); if (!lc) { DMWARN("couldn't allocate core log"); return -ENOMEM; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index de03f9b06584..8f4ae2f51545 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -160,7 +160,7 @@ static bool mpath_double_check_test_bit(int MPATHF_bit, struct multipath *m) */ static struct pgpath *alloc_pgpath(void) { - struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); + struct pgpath *pgpath = kzalloc_obj(*pgpath); if (!pgpath) return NULL; @@ -179,7 +179,7 @@ static struct priority_group *alloc_priority_group(void) { struct priority_group *pg; - pg = kzalloc(sizeof(*pg), GFP_KERNEL); + pg = kzalloc_obj(*pg); if (pg) INIT_LIST_HEAD(&pg->pgpaths); @@ -216,7 +216,7 @@ static struct multipath *alloc_multipath(struct dm_target *ti) { struct multipath *m; - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (m) { INIT_LIST_HEAD(&m->priority_groups); spin_lock_init(&m->lock); diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c index 2b0ac200f1c0..006a7991f45b 100644 --- a/drivers/md/dm-path-selector.c +++ b/drivers/md/dm-path-selector.c @@ -87,7 +87,7 @@ void dm_put_path_selector(struct path_selector_type *pst) static struct ps_internal *_alloc_path_selector(struct path_selector_type *pst) { - struct ps_internal *psi = kzalloc(sizeof(*psi), GFP_KERNEL); + struct ps_internal *psi = kzalloc_obj(*psi); if (psi) psi->pst = *pst; diff --git a/drivers/md/dm-pcache/cache.c b/drivers/md/dm-pcache/cache.c index 534bf07b794f..bb1ada31e483 100644 --- a/drivers/md/dm-pcache/cache.c +++ b/drivers/md/dm-pcache/cache.c @@ -138,7 +138,8 @@ static int cache_init(struct dm_pcache *pcache) struct pcache_cache_dev *cache_dev = &pcache->cache_dev; int ret; - cache->segments = kvcalloc(cache_dev->seg_num, sizeof(struct pcache_cache_segment), GFP_KERNEL); + cache->segments = kvzalloc_objs(struct pcache_cache_segment, + cache_dev->seg_num); if (!cache->segments) { ret = -ENOMEM; goto err; diff --git a/drivers/md/dm-pcache/cache_key.c b/drivers/md/dm-pcache/cache_key.c index 2b77e121f89b..e068e878231b 100644 --- a/drivers/md/dm-pcache/cache_key.c +++ b/drivers/md/dm-pcache/cache_key.c @@ -837,7 +837,8 @@ int cache_tree_init(struct pcache_cache *cache, struct pcache_cache_tree *cache_ * Each element is a cache tree structure that contains * an RB tree root and a spinlock for protecting its contents. */ - cache_tree->subtrees = kvcalloc(cache_tree->n_subtrees, sizeof(struct pcache_cache_subtree), GFP_KERNEL); + cache_tree->subtrees = kvzalloc_objs(struct pcache_cache_subtree, + cache_tree->n_subtrees); if (!cache_tree->subtrees) { ret = -ENOMEM; goto key_pool_exit; diff --git a/drivers/md/dm-pcache/dm_pcache.c b/drivers/md/dm-pcache/dm_pcache.c index e5f5936fa6f0..81c795c0400e 100644 --- a/drivers/md/dm-pcache/dm_pcache.c +++ b/drivers/md/dm-pcache/dm_pcache.c @@ -281,7 +281,7 @@ static int dm_pcache_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Allocate memory for the cache structure */ - pcache = kzalloc(sizeof(struct dm_pcache), GFP_KERNEL); + pcache = kzalloc_obj(struct dm_pcache); if (!pcache) return -ENOMEM; diff --git a/drivers/md/dm-ps-historical-service-time.c b/drivers/md/dm-ps-historical-service-time.c index f07e773d9cc0..c4755112287a 100644 --- a/drivers/md/dm-ps-historical-service-time.c +++ b/drivers/md/dm-ps-historical-service-time.c @@ -129,7 +129,7 @@ static u64 fixed_ema(u64 last, u64 next, u64 weight) static struct selector *alloc_selector(void) { - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct selector *s = kmalloc_obj(*s); if (s) { INIT_LIST_HEAD(&s->valid_paths); @@ -289,7 +289,7 @@ static int hst_add_path(struct path_selector *ps, struct dm_path *path, } /* allocate the path */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); + pi = kmalloc_obj(*pi); if (!pi) { *error = "historical-service-time ps: Error allocating path context"; return -ENOMEM; diff --git a/drivers/md/dm-ps-io-affinity.c b/drivers/md/dm-ps-io-affinity.c index 80415a045c68..526d94d138f9 100644 --- a/drivers/md/dm-ps-io-affinity.c +++ b/drivers/md/dm-ps-io-affinity.c @@ -53,7 +53,7 @@ static int ioa_add_path(struct path_selector *ps, struct dm_path *path, return -EINVAL; } - pi = kzalloc(sizeof(*pi), GFP_KERNEL); + pi = kzalloc_obj(*pi); if (!pi) { *error = "io-affinity ps: Error allocating path context"; return -ENOMEM; @@ -112,12 +112,11 @@ static int ioa_create(struct path_selector *ps, unsigned int argc, char **argv) { struct selector *s; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; - s->path_map = kcalloc(nr_cpu_ids, sizeof(struct path_info *), - GFP_KERNEL); + s->path_map = kzalloc_objs(struct path_info *, nr_cpu_ids); if (!s->path_map) goto free_selector; diff --git a/drivers/md/dm-ps-queue-length.c b/drivers/md/dm-ps-queue-length.c index 9c68701ed7a4..4afea160afab 100644 --- a/drivers/md/dm-ps-queue-length.c +++ b/drivers/md/dm-ps-queue-length.c @@ -42,7 +42,7 @@ struct path_info { static struct selector *alloc_selector(void) { - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct selector *s = kmalloc_obj(*s); if (s) { INIT_LIST_HEAD(&s->valid_paths); @@ -142,7 +142,7 @@ static int ql_add_path(struct path_selector *ps, struct dm_path *path, } /* Allocate the path information structure */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); + pi = kmalloc_obj(*pi); if (!pi) { *error = "queue-length ps: Error allocating path information"; return -ENOMEM; diff --git a/drivers/md/dm-ps-round-robin.c b/drivers/md/dm-ps-round-robin.c index 0c12f4073461..81c89cda3158 100644 --- a/drivers/md/dm-ps-round-robin.c +++ b/drivers/md/dm-ps-round-robin.c @@ -55,7 +55,7 @@ struct selector { static struct selector *alloc_selector(void) { - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct selector *s = kmalloc_obj(*s); if (s) { INIT_LIST_HEAD(&s->valid_paths); @@ -144,7 +144,7 @@ static int rr_add_path(struct path_selector *ps, struct dm_path *path, } /* allocate the path */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); + pi = kmalloc_obj(*pi); if (!pi) { *error = "round-robin ps: Error allocating path context"; return -ENOMEM; diff --git a/drivers/md/dm-ps-service-time.c b/drivers/md/dm-ps-service-time.c index 0543fe7969c4..83721910e5ea 100644 --- a/drivers/md/dm-ps-service-time.c +++ b/drivers/md/dm-ps-service-time.c @@ -38,7 +38,7 @@ struct path_info { static struct selector *alloc_selector(void) { - struct selector *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct selector *s = kmalloc_obj(*s); if (s) { INIT_LIST_HEAD(&s->valid_paths); @@ -153,7 +153,7 @@ static int st_add_path(struct path_selector *ps, struct dm_path *path, } /* allocate the path */ - pi = kmalloc(sizeof(*pi), GFP_KERNEL); + pi = kmalloc_obj(*pi); if (!pi) { *error = "service-time ps: Error allocating path context"; return -ENOMEM; diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 4bacdc499984..c5dc083c7244 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -744,7 +744,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r return ERR_PTR(-EINVAL); } - rs = kzalloc(struct_size(rs, dev, raid_devs), GFP_KERNEL); + rs = kzalloc_flex(*rs, dev, raid_devs); if (!rs) { ti->error = "Cannot allocate raid context"; return ERR_PTR(-ENOMEM); diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index 943c0c6b2087..80a5c4127707 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -890,7 +890,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors, struct dm_dirty_log *dl) { struct mirror_set *ms = - kzalloc(struct_size(ms, mirror, nr_mirrors), GFP_KERNEL); + kzalloc_flex(*ms, mirror, nr_mirrors); if (!ms) { ti->error = "Cannot allocate mirror context"; diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c index e9b47b659976..3ad3aecfdff7 100644 --- a/drivers/md/dm-region-hash.c +++ b/drivers/md/dm-region-hash.c @@ -184,7 +184,7 @@ struct dm_region_hash *dm_region_hash_create( ; nr_buckets >>= 1; - rh = kzalloc(sizeof(*rh), GFP_KERNEL); + rh = kzalloc_obj(*rh); if (!rh) { DMERR("unable to allocate region hash memory"); return ERR_PTR(-ENOMEM); @@ -294,7 +294,7 @@ static struct dm_region *__rh_alloc(struct dm_region_hash *rh, region_t region) nreg = mempool_alloc(&rh->region_pool, GFP_ATOMIC); if (unlikely(!nreg)) - nreg = kmalloc(sizeof(*nreg), GFP_NOIO | __GFP_NOFAIL); + nreg = kmalloc_obj(*nreg, GFP_NOIO | __GFP_NOFAIL); nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? DM_RH_CLEAN : DM_RH_NOSYNC; diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c index 0e13d60bfdd1..aa239ccda270 100644 --- a/drivers/md/dm-snap-persistent.c +++ b/drivers/md/dm-snap-persistent.c @@ -626,8 +626,7 @@ static int persistent_read_metadata(struct dm_exception_store *store, */ ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / sizeof(struct disk_exception); - ps->callbacks = kvcalloc(ps->exceptions_per_area, - sizeof(*ps->callbacks), GFP_KERNEL); + ps->callbacks = kvzalloc_objs(*ps->callbacks, ps->exceptions_per_area); if (!ps->callbacks) return -ENOMEM; @@ -854,7 +853,7 @@ static int persistent_ctr(struct dm_exception_store *store, char *options) int r; /* allocate the pstore */ - ps = kzalloc(sizeof(*ps), GFP_KERNEL); + ps = kzalloc_obj(*ps); if (!ps) return -ENOMEM; diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c index 1e07a745bedd..8680d38cdfcc 100644 --- a/drivers/md/dm-snap-transient.c +++ b/drivers/md/dm-snap-transient.c @@ -77,7 +77,7 @@ static int transient_ctr(struct dm_exception_store *store, char *options) { struct transient_c *tc; - tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL); + tc = kmalloc_obj(struct transient_c); if (!tc) return -ENOMEM; diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index dbd148967de4..1489fda9d24a 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -354,8 +354,7 @@ static int init_origin_hash(void) { int i; - _origins = kmalloc_array(ORIGIN_HASH_SIZE, sizeof(struct list_head), - GFP_KERNEL); + _origins = kmalloc_objs(struct list_head, ORIGIN_HASH_SIZE); if (!_origins) { DMERR("unable to allocate memory for _origins"); return -ENOMEM; @@ -363,9 +362,7 @@ static int init_origin_hash(void) for (i = 0; i < ORIGIN_HASH_SIZE; i++) INIT_LIST_HEAD(_origins + i); - _dm_origins = kmalloc_array(ORIGIN_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + _dm_origins = kmalloc_objs(struct list_head, ORIGIN_HASH_SIZE); if (!_dm_origins) { DMERR("unable to allocate memory for _dm_origins"); kfree(_origins); @@ -559,7 +556,7 @@ static int register_snapshot(struct dm_snapshot *snap) struct block_device *bdev = snap->origin->bdev; int r = 0; - new_o = kmalloc(sizeof(*new_o), GFP_KERNEL); + new_o = kmalloc_obj(*new_o); if (!new_o) return -ENOMEM; @@ -666,8 +663,7 @@ static int dm_exception_table_init(struct dm_exception_table *et, et->hash_shift = hash_shift; et->hash_mask = size - 1; - et->table = kvmalloc_array(size, sizeof(struct dm_hlist_head), - GFP_KERNEL); + et->table = kvmalloc_objs(struct dm_hlist_head, size); if (!et->table) return -ENOMEM; @@ -1252,7 +1248,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) origin_mode = BLK_OPEN_WRITE; } - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) { ti->error = "Cannot allocate private snapshot structure"; r = -ENOMEM; @@ -2626,7 +2622,7 @@ static int origin_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - o = kmalloc(sizeof(struct dm_origin), GFP_KERNEL); + o = kmalloc_obj(struct dm_origin); if (!o) { ti->error = "Cannot allocate private origin structure"; r = -ENOMEM; diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c index 1e5d988f44da..c53cf07ab7b0 100644 --- a/drivers/md/dm-stats.c +++ b/drivers/md/dm-stats.c @@ -971,9 +971,8 @@ static int parse_histogram(const char *h, unsigned int *n_histogram_entries, if (*q == ',') (*n_histogram_entries)++; - *histogram_boundaries = kmalloc_array(*n_histogram_entries, - sizeof(unsigned long long), - GFP_KERNEL); + *histogram_boundaries = kmalloc_objs(unsigned long long, + *n_histogram_entries); if (!*histogram_boundaries) return -ENOMEM; diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c index 20cce876d80c..750865fd3ae7 100644 --- a/drivers/md/dm-stripe.c +++ b/drivers/md/dm-stripe.c @@ -129,7 +129,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - sc = kmalloc(struct_size(sc, stripe, stripes), GFP_KERNEL); + sc = kmalloc_flex(*sc, stripe, stripes); if (!sc) { ti->error = "Memory allocation for striped context failed"; return -ENOMEM; diff --git a/drivers/md/dm-switch.c b/drivers/md/dm-switch.c index 50a52ca50b34..5952f02de1e6 100644 --- a/drivers/md/dm-switch.c +++ b/drivers/md/dm-switch.c @@ -62,7 +62,7 @@ static struct switch_ctx *alloc_switch_ctx(struct dm_target *ti, unsigned int nr { struct switch_ctx *sctx; - sctx = kzalloc(struct_size(sctx, path_list, nr_paths), GFP_KERNEL); + sctx = kzalloc_flex(*sctx, path_list, nr_paths); if (!sctx) return NULL; diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 7be1d8dc8bdd..dc2eff6b739d 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -133,7 +133,7 @@ int dm_table_create(struct dm_table **result, blk_mode_t mode, if (num_targets > DM_MAX_TARGETS) return -EOVERFLOW; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) return -ENOMEM; @@ -381,7 +381,7 @@ int dm_get_device(struct dm_target *ti, const char *path, blk_mode_t mode, dd = find_device(&t->devices, dev); if (!dd) { - dd = kmalloc(sizeof(*dd), GFP_KERNEL); + dd = kmalloc_obj(*dd); if (!dd) return -ENOMEM; @@ -1391,7 +1391,7 @@ static int dm_table_construct_crypto_profile(struct dm_table *t) unsigned int i; bool empty_profile = true; - dmcp = kmalloc(sizeof(*dmcp), GFP_KERNEL); + dmcp = kmalloc_obj(*dmcp); if (!dmcp) return -ENOMEM; dmcp->md = t->md; diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c index 1fd41289de36..3d294365e3ba 100644 --- a/drivers/md/dm-target.c +++ b/drivers/md/dm-target.c @@ -128,7 +128,7 @@ static int io_err_get_args(struct dm_target *tt, unsigned int argc, char **args) char dummy; int ret; - ioec = kmalloc(sizeof(*ioec), GFP_KERNEL); + ioec = kmalloc_obj(*ioec); if (!ioec) { tt->error = "Cannot allocate io_err context"; return -ENOMEM; diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index f90679cfec5b..b6a2d2081a24 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c @@ -957,7 +957,7 @@ struct dm_pool_metadata *dm_pool_metadata_open(struct block_device *bdev, int r; struct dm_pool_metadata *pmd; - pmd = kmalloc(sizeof(*pmd), GFP_KERNEL); + pmd = kmalloc_obj(*pmd); if (!pmd) { DMERR("could not allocate metadata struct"); return ERR_PTR(-ENOMEM); @@ -1077,7 +1077,7 @@ static int __open_device(struct dm_pool_metadata *pmd, details_le.snapshotted_time = cpu_to_le32(pmd->time); } - *td = kmalloc(sizeof(**td), GFP_NOIO); + *td = kmalloc_obj(**td, GFP_NOIO); if (!*td) return -ENOMEM; diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 52ffb495f5a8..59392de7a477 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2949,7 +2949,7 @@ static struct pool *pool_create(struct mapped_device *pool_md, return ERR_CAST(pmd); } - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) { *error = "Error allocating memory for pool"; err_p = ERR_PTR(-ENOMEM); @@ -3354,7 +3354,7 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto out; } - pt = kzalloc(sizeof(*pt), GFP_KERNEL); + pt = kzalloc_obj(*pt); if (!pt) { r = -ENOMEM; goto out; @@ -4193,7 +4193,7 @@ static int thin_ctr(struct dm_target *ti, unsigned int argc, char **argv) goto out_unlock; } - tc = ti->private = kzalloc(sizeof(*tc), GFP_KERNEL); + tc = ti->private = kzalloc_obj(*tc); if (!tc) { ti->error = "Out of memory"; r = -ENOMEM; diff --git a/drivers/md/dm-unstripe.c b/drivers/md/dm-unstripe.c index 17be48359564..bfcbe6bfa71a 100644 --- a/drivers/md/dm-unstripe.c +++ b/drivers/md/dm-unstripe.c @@ -48,7 +48,7 @@ static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv) return -EINVAL; } - uc = kzalloc(sizeof(*uc), GFP_KERNEL); + uc = kzalloc_obj(*uc); if (!uc) { ti->error = "Memory allocation for unstriped context failed"; return -ENOMEM; diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c index 7583607a8aa6..14be4d888af3 100644 --- a/drivers/md/dm-verity-fec.c +++ b/drivers/md/dm-verity-fec.c @@ -607,7 +607,7 @@ int verity_fec_ctr_alloc(struct dm_verity *v) { struct dm_verity_fec *f; - f = kzalloc(sizeof(struct dm_verity_fec), GFP_KERNEL); + f = kzalloc_obj(struct dm_verity_fec); if (!f) { v->ti->error = "Cannot allocate FEC structure"; return -ENOMEM; diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c index 8089cb74b75d..61073cd01d13 100644 --- a/drivers/md/dm-verity-target.c +++ b/drivers/md/dm-verity-target.c @@ -764,8 +764,8 @@ static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io, return; } - pw = kmalloc(sizeof(struct dm_verity_prefetch_work), - GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); + pw = kmalloc_obj(struct dm_verity_prefetch_work, + GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (!pw) return; @@ -1369,7 +1369,7 @@ static int verity_setup_salt_and_hashstate(struct dm_verity *v, const char *arg) if (likely(v->use_sha256_lib)) { /* Implies version 1: salt at beginning */ v->initial_hashstate.sha256 = - kmalloc(sizeof(struct sha256_ctx), GFP_KERNEL); + kmalloc_obj(struct sha256_ctx); if (!v->initial_hashstate.sha256) { ti->error = "Cannot allocate initial hash state"; return -ENOMEM; @@ -1430,7 +1430,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv) char dummy; char *root_hash_digest_to_validate; - v = kzalloc(sizeof(struct dm_verity), GFP_KERNEL); + v = kzalloc_obj(struct dm_verity); if (!v) { ti->error = "Cannot allocate verity structure"; return -ENOMEM; diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c index af54e289bceb..98bd945f6da7 100644 --- a/drivers/md/dm-writecache.c +++ b/drivers/md/dm-writecache.c @@ -1848,9 +1848,8 @@ static void __writecache_writeback_pmem(struct dm_writecache *wc, struct writeba bio->bi_iter.bi_sector = read_original_sector(wc, e); if (unlikely(max_pages > WB_LIST_INLINE)) - wb->wc_list = kmalloc_array(max_pages, sizeof(struct wc_entry *), - GFP_NOIO | __GFP_NORETRY | - __GFP_NOMEMALLOC | __GFP_NOWARN); + wb->wc_list = kmalloc_objs(struct wc_entry *, max_pages, + GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); if (likely(max_pages <= WB_LIST_INLINE) || unlikely(!wb->wc_list)) { wb->wc_list = wb->wc_list_inline; @@ -2246,7 +2245,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned int argc, char **argv) as.argc = argc; as.argv = argv; - wc = kzalloc(sizeof(struct dm_writecache), GFP_KERNEL); + wc = kzalloc_obj(struct dm_writecache); if (!wc) { ti->error = "Cannot allocate writecache structure"; r = -ENOMEM; diff --git a/drivers/md/dm-zoned-metadata.c b/drivers/md/dm-zoned-metadata.c index deff22ecccbb..ec605acddd88 100644 --- a/drivers/md/dm-zoned-metadata.c +++ b/drivers/md/dm-zoned-metadata.c @@ -303,7 +303,7 @@ static struct dm_zone *dmz_get(struct dmz_metadata *zmd, unsigned int zone_id) static struct dm_zone *dmz_insert(struct dmz_metadata *zmd, unsigned int zone_id, struct dmz_dev *dev) { - struct dm_zone *zone = kzalloc(sizeof(struct dm_zone), GFP_KERNEL); + struct dm_zone *zone = kzalloc_obj(struct dm_zone); if (!zone) return ERR_PTR(-ENOMEM); @@ -419,7 +419,7 @@ static struct dmz_mblock *dmz_alloc_mblock(struct dmz_metadata *zmd, } /* Allocate a new block */ - mblk = kmalloc(sizeof(struct dmz_mblock), GFP_NOIO); + mblk = kmalloc_obj(struct dmz_mblock, GFP_NOIO); if (!mblk) return NULL; @@ -1311,7 +1311,7 @@ static int dmz_load_sb(struct dmz_metadata *zmd) int i; struct dmz_sb *sb; - sb = kzalloc(sizeof(struct dmz_sb), GFP_KERNEL); + sb = kzalloc_obj(struct dmz_sb); if (!sb) return -ENOMEM; for (i = 1; i < zmd->nr_devs; i++) { @@ -1686,8 +1686,7 @@ static int dmz_load_mapping(struct dmz_metadata *zmd) unsigned int bzone_id; /* Metadata block array for the chunk mapping table */ - zmd->map_mblk = kcalloc(zmd->nr_map_blocks, - sizeof(struct dmz_mblk *), GFP_KERNEL); + zmd->map_mblk = kzalloc_objs(struct dmz_mblock *, zmd->nr_map_blocks); if (!zmd->map_mblk) return -ENOMEM; @@ -2868,7 +2867,7 @@ int dmz_ctr_metadata(struct dmz_dev *dev, int num_dev, struct dm_zone *zone; int ret; - zmd = kzalloc(sizeof(struct dmz_metadata), GFP_KERNEL); + zmd = kzalloc_obj(struct dmz_metadata); if (!zmd) return -ENOMEM; diff --git a/drivers/md/dm-zoned-reclaim.c b/drivers/md/dm-zoned-reclaim.c index 76e2c6868548..ad9c7bc21d54 100644 --- a/drivers/md/dm-zoned-reclaim.c +++ b/drivers/md/dm-zoned-reclaim.c @@ -556,7 +556,7 @@ int dmz_ctr_reclaim(struct dmz_metadata *zmd, struct dmz_reclaim *zrc; int ret; - zrc = kzalloc(sizeof(struct dmz_reclaim), GFP_KERNEL); + zrc = kzalloc_obj(struct dmz_reclaim); if (!zrc) return -ENOMEM; diff --git a/drivers/md/dm-zoned-target.c b/drivers/md/dm-zoned-target.c index 9da329078ea4..d55500fc88ef 100644 --- a/drivers/md/dm-zoned-target.c +++ b/drivers/md/dm-zoned-target.c @@ -545,7 +545,7 @@ static int dmz_queue_chunk_work(struct dmz_target *dmz, struct bio *bio) dmz_get_chunk_work(cw); } else { /* Create a new chunk work */ - cw = kmalloc(sizeof(struct dm_chunk_work), GFP_NOIO); + cw = kmalloc_obj(struct dm_chunk_work, GFP_NOIO); if (unlikely(!cw)) { ret = -ENOMEM; goto out; @@ -838,18 +838,18 @@ static int dmz_ctr(struct dm_target *ti, unsigned int argc, char **argv) } /* Allocate and initialize the target descriptor */ - dmz = kzalloc(sizeof(struct dmz_target), GFP_KERNEL); + dmz = kzalloc_obj(struct dmz_target); if (!dmz) { ti->error = "Unable to allocate the zoned target descriptor"; return -ENOMEM; } - dmz->dev = kcalloc(argc, sizeof(struct dmz_dev), GFP_KERNEL); + dmz->dev = kzalloc_objs(struct dmz_dev, argc); if (!dmz->dev) { ti->error = "Unable to allocate the zoned device descriptors"; kfree(dmz); return -ENOMEM; } - dmz->ddev = kcalloc(argc, sizeof(struct dm_dev *), GFP_KERNEL); + dmz->ddev = kzalloc_objs(struct dm_dev *, argc); if (!dmz->ddev) { ti->error = "Unable to allocate the dm device descriptors"; ret = -ENOMEM; diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 1d4a050dab3a..83378c033c72 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -1025,8 +1025,7 @@ static int md_bitmap_storage_alloc(struct bitmap_storage *store, num_pages = DIV_ROUND_UP(bytes, PAGE_SIZE); offset = slot_number * num_pages; - store->filemap = kmalloc_array(num_pages, sizeof(struct page *), - GFP_KERNEL); + store->filemap = kmalloc_objs(struct page *, num_pages); if (!store->filemap) return -ENOMEM; @@ -2121,7 +2120,7 @@ static struct bitmap *__bitmap_create(struct mddev *mddev, int slot) return ERR_PTR(-EBUSY); } - bitmap = kzalloc(sizeof(*bitmap), GFP_KERNEL); + bitmap = kzalloc_obj(*bitmap); if (!bitmap) return ERR_PTR(-ENOMEM); @@ -2436,7 +2435,7 @@ static int __bitmap_resize(struct bitmap *bitmap, sector_t blocks, pages = DIV_ROUND_UP(chunks, PAGE_COUNTER_RATIO); - new_bp = kcalloc(pages, sizeof(*new_bp), GFP_KERNEL); + new_bp = kzalloc_objs(*new_bp, pages); ret = -ENOMEM; if (!new_bp) { md_bitmap_file_unmap(&store); diff --git a/drivers/md/md-cluster.c b/drivers/md/md-cluster.c index 896279988dfd..24dac6f09da8 100644 --- a/drivers/md/md-cluster.c +++ b/drivers/md/md-cluster.c @@ -196,7 +196,7 @@ static struct dlm_lock_resource *lockres_init(struct mddev *mddev, int ret, namelen; struct md_cluster_info *cinfo = mddev->cluster_info; - res = kzalloc(sizeof(struct dlm_lock_resource), GFP_KERNEL); + res = kzalloc_obj(struct dlm_lock_resource); if (!res) return NULL; init_waitqueue_head(&res->sync_locking); @@ -886,7 +886,7 @@ static int join(struct mddev *mddev, int nodes) int ret, ops_rv; char str[64]; - cinfo = kzalloc(sizeof(struct md_cluster_info), GFP_KERNEL); + cinfo = kzalloc_obj(struct md_cluster_info); if (!cinfo) return -ENOMEM; @@ -1543,8 +1543,8 @@ static int lock_all_bitmaps(struct mddev *mddev) struct md_cluster_info *cinfo = mddev->cluster_info; cinfo->other_bitmap_lockres = - kcalloc(mddev->bitmap_info.nodes - 1, - sizeof(struct dlm_lock_resource *), GFP_KERNEL); + kzalloc_objs(struct dlm_lock_resource *, + mddev->bitmap_info.nodes - 1); if (!cinfo->other_bitmap_lockres) { pr_err("md: can't alloc mem for other bitmap locks\n"); return 0; diff --git a/drivers/md/md-linear.c b/drivers/md/md-linear.c index 8d7b82c4a723..fdff250d0d51 100644 --- a/drivers/md/md-linear.c +++ b/drivers/md/md-linear.c @@ -92,7 +92,7 @@ static struct linear_conf *linear_conf(struct mddev *mddev, int raid_disks) int cnt; int i; - conf = kzalloc(struct_size(conf, disks, raid_disks), GFP_KERNEL); + conf = kzalloc_flex(*conf, disks, raid_disks); if (!conf) return ERR_PTR(-ENOMEM); diff --git a/drivers/md/md-llbitmap.c b/drivers/md/md-llbitmap.c index cd713a7dc270..bf398d7476b3 100644 --- a/drivers/md/md-llbitmap.c +++ b/drivers/md/md-llbitmap.c @@ -982,7 +982,7 @@ static int llbitmap_create(struct mddev *mddev) if (ret) return ret; - llbitmap = kzalloc(sizeof(*llbitmap), GFP_KERNEL); + llbitmap = kzalloc_obj(*llbitmap); if (!llbitmap) return -ENOMEM; diff --git a/drivers/md/md.c b/drivers/md/md.c index 9ca5d74fd2b2..3ce6f9e9d38e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -853,7 +853,7 @@ static struct mddev *mddev_alloc(dev_t unit) if (unit && MAJOR(unit) != MD_MAJOR) unit &= ~((1 << MdpMinorShift) - 1); - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return ERR_PTR(-ENOMEM); @@ -1222,8 +1222,8 @@ static int md_sb_equal(mdp_super_t *sb1, mdp_super_t *sb2) int ret; mdp_super_t *tmp1, *tmp2; - tmp1 = kmalloc(sizeof(*tmp1),GFP_KERNEL); - tmp2 = kmalloc(sizeof(*tmp2),GFP_KERNEL); + tmp1 = kmalloc_obj(*tmp1); + tmp2 = kmalloc_obj(*tmp2); if (!tmp1 || !tmp2) { ret = 0; @@ -3817,7 +3817,7 @@ static struct md_rdev *md_import_device(dev_t newdev, int super_format, int supe sector_t size; int err; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); @@ -7238,7 +7238,7 @@ static int get_bitmap_file(struct mddev *mddev, void __user * arg) char *ptr; int err; - file = kzalloc(sizeof(*file), GFP_NOIO); + file = kzalloc_obj(*file, GFP_NOIO); if (!file) return -ENOMEM; @@ -8541,7 +8541,7 @@ struct md_thread *md_register_thread(void (*run) (struct md_thread *), { struct md_thread *thread; - thread = kzalloc(sizeof(struct md_thread), GFP_KERNEL); + thread = kzalloc_obj(struct md_thread); if (!thread) return NULL; @@ -9179,8 +9179,8 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, { struct bio *discard_bio = NULL; - if (__blkdev_issue_discard(rdev->bdev, start, size, GFP_NOIO, - &discard_bio) || !discard_bio) + __blkdev_issue_discard(rdev->bdev, start, size, GFP_NOIO, &discard_bio); + if (!discard_bio) return; bio_chain(discard_bio, bio); @@ -10749,7 +10749,7 @@ void md_autodetect_dev(dev_t dev) { struct detected_devices_node *node_detected_dev; - node_detected_dev = kzalloc(sizeof(*node_detected_dev), GFP_KERNEL); + node_detected_dev = kzalloc_obj(*node_detected_dev); if (node_detected_dev) { node_detected_dev->dev = dev; mutex_lock(&detected_devices_mutex); diff --git a/drivers/md/persistent-data/dm-block-manager.c b/drivers/md/persistent-data/dm-block-manager.c index 1ef71e5fcde7..a5003774f8bf 100644 --- a/drivers/md/persistent-data/dm-block-manager.c +++ b/drivers/md/persistent-data/dm-block-manager.c @@ -388,7 +388,7 @@ struct dm_block_manager *dm_block_manager_create(struct block_device *bdev, int r; struct dm_block_manager *bm; - bm = kmalloc(sizeof(*bm), GFP_KERNEL); + bm = kmalloc_obj(*bm); if (!bm) { r = -ENOMEM; goto bad; diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c index 0c7a2e8d1846..dd02eee4a23c 100644 --- a/drivers/md/persistent-data/dm-btree.c +++ b/drivers/md/persistent-data/dm-btree.c @@ -280,7 +280,7 @@ int dm_btree_del(struct dm_btree_info *info, dm_block_t root) * considered an FS op. We can't recurse back into the FS, so we * allocate GFP_NOFS. */ - s = kmalloc(sizeof(*s), GFP_NOFS); + s = kmalloc_obj(*s, GFP_NOFS); if (!s) return -ENOMEM; s->info = info; diff --git a/drivers/md/persistent-data/dm-space-map-disk.c b/drivers/md/persistent-data/dm-space-map-disk.c index f4241f54e20e..27c0be9c5a37 100644 --- a/drivers/md/persistent-data/dm-space-map-disk.c +++ b/drivers/md/persistent-data/dm-space-map-disk.c @@ -220,7 +220,7 @@ struct dm_space_map *dm_sm_disk_create(struct dm_transaction_manager *tm, int r; struct sm_disk *smd; - smd = kmalloc(sizeof(*smd), GFP_KERNEL); + smd = kmalloc_obj(*smd); if (!smd) return ERR_PTR(-ENOMEM); @@ -254,7 +254,7 @@ struct dm_space_map *dm_sm_disk_open(struct dm_transaction_manager *tm, int r; struct sm_disk *smd; - smd = kmalloc(sizeof(*smd), GFP_KERNEL); + smd = kmalloc_obj(*smd); if (!smd) return ERR_PTR(-ENOMEM); diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c index d48c4fafc779..4bffddeed8ec 100644 --- a/drivers/md/persistent-data/dm-space-map-metadata.c +++ b/drivers/md/persistent-data/dm-space-map-metadata.c @@ -772,7 +772,7 @@ struct dm_space_map *dm_sm_metadata_init(void) { struct sm_metadata *smm; - smm = kvmalloc(sizeof(*smm), GFP_KERNEL); + smm = kvmalloc_obj(*smm); if (!smm) return ERR_PTR(-ENOMEM); diff --git a/drivers/md/persistent-data/dm-transaction-manager.c b/drivers/md/persistent-data/dm-transaction-manager.c index 98c745d90f48..7401add01d12 100644 --- a/drivers/md/persistent-data/dm-transaction-manager.c +++ b/drivers/md/persistent-data/dm-transaction-manager.c @@ -137,7 +137,7 @@ static void insert_shadow(struct dm_transaction_manager *tm, dm_block_t b) unsigned int bucket; struct shadow_info *si; - si = kmalloc(sizeof(*si), GFP_NOIO); + si = kmalloc_obj(*si, GFP_NOIO); if (si) { struct rb_node **node, *parent; si->where = b; @@ -185,7 +185,7 @@ static struct dm_transaction_manager *dm_tm_create(struct dm_block_manager *bm, unsigned int i; struct dm_transaction_manager *tm; - tm = kmalloc(sizeof(*tm), GFP_KERNEL); + tm = kmalloc_obj(*tm); if (!tm) return ERR_PTR(-ENOMEM); @@ -207,7 +207,7 @@ struct dm_transaction_manager *dm_tm_create_non_blocking_clone(struct dm_transac { struct dm_transaction_manager *tm; - tm = kmalloc(sizeof(*tm), GFP_KERNEL); + tm = kmalloc_obj(*tm); if (tm) { tm->is_clone = 1; tm->real = real; diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d83b2b1c0049..ef0045db409f 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -69,7 +69,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) struct md_rdev *smallest, *rdev1, *rdev2, *rdev, **dev; struct strip_zone *zone; int cnt; - struct r0conf *conf = kzalloc(sizeof(*conf), GFP_KERNEL); + struct r0conf *conf = kzalloc_obj(*conf); unsigned int blksize = 512; if (!mddev_is_dm(mddev)) @@ -143,9 +143,7 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) } err = -ENOMEM; - conf->strip_zone = kcalloc(conf->nr_strip_zones, - sizeof(struct strip_zone), - GFP_KERNEL); + conf->strip_zone = kzalloc_objs(struct strip_zone, conf->nr_strip_zones); if (!conf->strip_zone) goto abort; conf->devlist = kzalloc(array3_size(sizeof(struct md_rdev *), diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 867db18bc3ba..181400e147c0 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -155,8 +155,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data) if (!r1_bio) return NULL; - rps = kmalloc_array(conf->raid_disks * 2, sizeof(struct resync_pages), - gfp_flags); + rps = kmalloc_objs(struct resync_pages, conf->raid_disks * 2, gfp_flags); if (!rps) goto out_free_r1bio; @@ -3070,27 +3069,23 @@ static struct r1conf *setup_conf(struct mddev *mddev) size_t r1bio_size; int err = -ENOMEM; - conf = kzalloc(sizeof(struct r1conf), GFP_KERNEL); + conf = kzalloc_obj(struct r1conf); if (!conf) goto abort; - conf->nr_pending = kcalloc(BARRIER_BUCKETS_NR, - sizeof(atomic_t), GFP_KERNEL); + conf->nr_pending = kzalloc_objs(atomic_t, BARRIER_BUCKETS_NR); if (!conf->nr_pending) goto abort; - conf->nr_waiting = kcalloc(BARRIER_BUCKETS_NR, - sizeof(atomic_t), GFP_KERNEL); + conf->nr_waiting = kzalloc_objs(atomic_t, BARRIER_BUCKETS_NR); if (!conf->nr_waiting) goto abort; - conf->nr_queued = kcalloc(BARRIER_BUCKETS_NR, - sizeof(atomic_t), GFP_KERNEL); + conf->nr_queued = kzalloc_objs(atomic_t, BARRIER_BUCKETS_NR); if (!conf->nr_queued) goto abort; - conf->barrier = kcalloc(BARRIER_BUCKETS_NR, - sizeof(atomic_t), GFP_KERNEL); + conf->barrier = kzalloc_objs(atomic_t, BARRIER_BUCKETS_NR); if (!conf->barrier) goto abort; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9debb20cf129..0653b5d8545a 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -152,7 +152,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data) nalloc_rp = nalloc; else nalloc_rp = nalloc * 2; - rps = kmalloc_array(nalloc_rp, sizeof(struct resync_pages), gfp_flags); + rps = kmalloc_objs(struct resync_pages, nalloc_rp, gfp_flags); if (!rps) goto out_free_r10bio; @@ -3852,14 +3852,13 @@ static struct r10conf *setup_conf(struct mddev *mddev) } err = -ENOMEM; - conf = kzalloc(sizeof(struct r10conf), GFP_KERNEL); + conf = kzalloc_obj(struct r10conf); if (!conf) goto out; /* FIXME calc properly */ - conf->mirrors = kcalloc(mddev->raid_disks + max(0, -mddev->delta_disks), - sizeof(struct raid10_info), - GFP_KERNEL); + conf->mirrors = kzalloc_objs(struct raid10_info, + mddev->raid_disks + max(0, -mddev->delta_disks)); if (!conf->mirrors) goto out; @@ -4281,9 +4280,8 @@ static int raid10_check_reshape(struct mddev *mddev) if (mddev->delta_disks > 0) { /* allocate new 'mirrors' list */ conf->mirrors_new = - kcalloc(mddev->raid_disks + mddev->delta_disks, - sizeof(struct raid10_info), - GFP_KERNEL); + kzalloc_objs(struct raid10_info, + mddev->raid_disks + mddev->delta_disks); if (!conf->mirrors_new) return -ENOMEM; } @@ -4918,7 +4916,7 @@ static int handle_reshape_read_error(struct mddev *mddev, int idx = 0; struct page **pages; - r10b = kmalloc(struct_size(r10b, devs, conf->copies), GFP_NOIO); + r10b = kmalloc_flex(*r10b, devs, conf->copies, GFP_NOIO); if (!r10b) { set_bit(MD_RECOVERY_INTR, &mddev->recovery); return -ENOMEM; diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c index e29e69335c69..66b10cbda96d 100644 --- a/drivers/md/raid5-cache.c +++ b/drivers/md/raid5-cache.c @@ -2447,7 +2447,7 @@ static int r5l_recovery_log(struct r5l_log *log) int ret; sector_t pos; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -3071,7 +3071,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev) return -EINVAL; } - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) return -ENOMEM; log->rdev = rdev; diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c index 56b234683ee6..7be1648c4e4f 100644 --- a/drivers/md/raid5-ppl.c +++ b/drivers/md/raid5-ppl.c @@ -1352,7 +1352,7 @@ int ppl_init_log(struct r5conf *conf) return -EINVAL; } - ppl_conf = kzalloc(sizeof(struct ppl_conf), GFP_KERNEL); + ppl_conf = kzalloc_obj(struct ppl_conf); if (!ppl_conf) return -ENOMEM; @@ -1378,8 +1378,7 @@ int ppl_init_log(struct r5conf *conf) goto err; ppl_conf->count = conf->raid_disks; - ppl_conf->child_logs = kcalloc(ppl_conf->count, sizeof(struct ppl_log), - GFP_KERNEL); + ppl_conf->child_logs = kzalloc_objs(struct ppl_log, ppl_conf->count); if (!ppl_conf->child_logs) { ret = -ENOMEM; goto err; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 8854e024f311..a8e8d431071b 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -513,7 +513,7 @@ init_stripe_shared_pages(struct stripe_head *sh, struct r5conf *conf, int disks) cnt = PAGE_SIZE / conf->stripe_size; nr_pages = (disks + cnt - 1) / cnt; - sh->pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + sh->pages = kzalloc_objs(struct page *, nr_pages); if (!sh->pages) return -ENOMEM; sh->nr_pages = nr_pages; @@ -2610,7 +2610,7 @@ static int resize_stripes(struct r5conf *conf, int newsize) * is completely stalled, so now is a good time to resize * conf->disks and the scribble region */ - ndisks = kcalloc(newsize, sizeof(struct disk_info), GFP_NOIO); + ndisks = kzalloc_objs(struct disk_info, newsize, GFP_NOIO); if (ndisks) { for (i = 0; i < conf->pool_size; i++) ndisks[i] = conf->disks[i]; @@ -7267,8 +7267,8 @@ static int alloc_thread_groups(struct r5conf *conf, int cnt, int *group_cnt, *group_cnt = num_possible_nodes(); size = sizeof(struct r5worker) * cnt; workers = kcalloc(size, *group_cnt, GFP_NOIO); - *worker_groups = kcalloc(*group_cnt, sizeof(struct r5worker_group), - GFP_NOIO); + *worker_groups = kzalloc_objs(struct r5worker_group, *group_cnt, + GFP_NOIO); if (!*worker_groups || !workers) { kfree(workers); kfree(*worker_groups); @@ -7497,7 +7497,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) return ERR_PTR(-EINVAL); } - conf = kzalloc(sizeof(struct r5conf), GFP_KERNEL); + conf = kzalloc_obj(struct r5conf); if (conf == NULL) goto abort; @@ -7508,9 +7508,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) #endif INIT_LIST_HEAD(&conf->free_list); INIT_LIST_HEAD(&conf->pending_list); - conf->pending_data = kcalloc(PENDING_IO_MAX, - sizeof(struct r5pending_data), - GFP_KERNEL); + conf->pending_data = kzalloc_objs(struct r5pending_data, PENDING_IO_MAX); if (!conf->pending_data) goto abort; for (i = 0; i < PENDING_IO_MAX; i++) @@ -7557,8 +7555,7 @@ static struct r5conf *setup_conf(struct mddev *mddev) conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks; max_disks = max(conf->raid_disks, conf->previous_raid_disks); - conf->disks = kcalloc(max_disks, sizeof(struct disk_info), - GFP_KERNEL); + conf->disks = kzalloc_objs(struct disk_info, max_disks); if (!conf->disks) goto abort; diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c index ba6828ef540e..8f7244ac1d43 100644 --- a/drivers/media/cec/core/cec-adap.c +++ b/drivers/media/cec/core/cec-adap.c @@ -95,7 +95,7 @@ void cec_queue_event_fh(struct cec_fh *fh, if (ev_idx < CEC_NUM_CORE_EVENTS) entry = &fh->core_events[ev_idx]; else - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (entry) { if (new_ev->event == CEC_EVENT_LOST_MSGS && fh->queued_events[ev_idx]) { @@ -218,7 +218,7 @@ static void cec_queue_msg_fh(struct cec_fh *fh, const struct cec_msg *msg) struct cec_msg_entry *entry; mutex_lock(&fh->lock); - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (entry) { entry->msg = *msg; /* Add new msg at the end of the queue */ @@ -922,7 +922,7 @@ int cec_transmit_msg_fh(struct cec_adapter *adap, struct cec_msg *msg, return -EBUSY; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c index 2b50578d107e..103ded79526f 100644 --- a/drivers/media/cec/core/cec-api.c +++ b/drivers/media/cec/core/cec-api.c @@ -555,7 +555,7 @@ static int cec_open(struct inode *inode, struct file *filp) struct cec_devnode *devnode = container_of(inode->i_cdev, struct cec_devnode, cdev); struct cec_adapter *adap = to_cec_adapter(devnode); - struct cec_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + struct cec_fh *fh = kzalloc_obj(*fh); /* * Initial events that are automatically sent when the cec device is * opened. diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c index dd6e24a0899b..1953ce559eca 100644 --- a/drivers/media/cec/core/cec-core.c +++ b/drivers/media/cec/core/cec-core.c @@ -237,7 +237,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, return ERR_PTR(-EINVAL); if (WARN_ON(!available_las || available_las > CEC_MAX_LOG_ADDRS)) return ERR_PTR(-EINVAL); - adap = kzalloc(sizeof(*adap), GFP_KERNEL); + adap = kzalloc_obj(*adap); if (!adap) return ERR_PTR(-ENOMEM); strscpy(adap->name, name, sizeof(adap->name)); diff --git a/drivers/media/cec/core/cec-notifier.c b/drivers/media/cec/core/cec-notifier.c index 1fed0b1c71e9..8cf1474d0361 100644 --- a/drivers/media/cec/core/cec-notifier.c +++ b/drivers/media/cec/core/cec-notifier.c @@ -63,7 +63,7 @@ cec_notifier_get_conn(struct device *hdmi_dev, const char *port_name) return n; } } - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) goto unlock; n->hdmi_dev = hdmi_dev; diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c index 4d7155281daa..6e1c39102832 100644 --- a/drivers/media/cec/core/cec-pin.c +++ b/drivers/media/cec/core/cec-pin.c @@ -1367,7 +1367,7 @@ struct cec_adapter *cec_pin_allocate_adapter(const struct cec_pin_ops *pin_ops, void *priv, const char *name, u32 caps) { struct cec_adapter *adap; - struct cec_pin *pin = kzalloc(sizeof(*pin), GFP_KERNEL); + struct cec_pin *pin = kzalloc_obj(*pin); if (pin == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c index bf92576bb2fc..3381d86096a1 100644 --- a/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c +++ b/drivers/media/cec/usb/extron-da-hd-4k-plus/extron-da-hd-4k-plus.c @@ -1494,7 +1494,7 @@ static int extron_setup(struct extron *extron) if (vendor_id) caps &= ~CEC_CAP_LOG_ADDRS; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -1769,7 +1769,7 @@ static int extron_connect(struct serio *serio, struct serio_driver *drv) manufacturer_name[0] = 0; } - extron = kzalloc(sizeof(*extron), GFP_KERNEL); + extron = kzalloc_obj(*extron); if (!extron) return -ENOMEM; diff --git a/drivers/media/cec/usb/pulse8/pulse8-cec.c b/drivers/media/cec/usb/pulse8/pulse8-cec.c index 60569f1670fe..0df3af152762 100644 --- a/drivers/media/cec/usb/pulse8/pulse8-cec.c +++ b/drivers/media/cec/usb/pulse8/pulse8-cec.c @@ -840,7 +840,7 @@ static int pulse8_connect(struct serio *serio, struct serio_driver *drv) struct cec_log_addrs log_addrs = {}; u16 pa = CEC_PHYS_ADDR_INVALID; - pulse8 = kzalloc(sizeof(*pulse8), GFP_KERNEL); + pulse8 = kzalloc_obj(*pulse8); if (!pulse8) return -ENOMEM; diff --git a/drivers/media/cec/usb/rainshadow/rainshadow-cec.c b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c index 6c0cee4b066f..764551e060c5 100644 --- a/drivers/media/cec/usb/rainshadow/rainshadow-cec.c +++ b/drivers/media/cec/usb/rainshadow/rainshadow-cec.c @@ -313,7 +313,7 @@ static int rain_connect(struct serio *serio, struct serio_driver *drv) struct cec_log_addrs log_addrs = {}; u16 pa = CEC_PHYS_ADDR_INVALID; - rain = kzalloc(sizeof(*rain), GFP_KERNEL); + rain = kzalloc_obj(*rain); if (!rain) return -ENOMEM; diff --git a/drivers/media/common/b2c2/flexcop.c b/drivers/media/common/b2c2/flexcop.c index 8506de48ba45..abd3d21a18ca 100644 --- a/drivers/media/common/b2c2/flexcop.c +++ b/drivers/media/common/b2c2/flexcop.c @@ -214,8 +214,7 @@ void flexcop_reset_block_300(struct flexcop_device *fc) struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) { void *bus; - struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), - GFP_KERNEL); + struct flexcop_device *fc = kzalloc_obj(struct flexcop_device); if (!fc) { err("no memory"); return NULL; diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c index cdc7050ed3ac..66274fdf5243 100644 --- a/drivers/media/common/cypress_firmware.c +++ b/drivers/media/common/cypress_firmware.c @@ -75,7 +75,7 @@ int cypress_load_firmware(struct usb_device *udev, struct hexline *hx; int ret, pos = 0; - hx = kmalloc(sizeof(*hx), GFP_KERNEL); + hx = kmalloc_obj(*hx); if (!hx) return -ENOMEM; diff --git a/drivers/media/common/saa7146/saa7146_core.c b/drivers/media/common/saa7146/saa7146_core.c index 27c53eed8fe3..c297d019f2b3 100644 --- a/drivers/media/common/saa7146/saa7146_core.c +++ b/drivers/media/common/saa7146/saa7146_core.c @@ -141,7 +141,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages) struct page *pg; int i; - sglist = kmalloc_array(nr_pages, sizeof(struct scatterlist), GFP_KERNEL); + sglist = kmalloc_objs(struct scatterlist, nr_pages); if (NULL == sglist) return NULL; sg_init_table(sglist, nr_pages); @@ -334,7 +334,7 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent int err = -ENOMEM; /* clear out mem for sure */ - dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL); + dev = kzalloc_obj(struct saa7146_dev); if (!dev) { ERR("out of memory\n"); goto out; diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c index a9e3bad76d54..fd12ef10409c 100644 --- a/drivers/media/common/saa7146/saa7146_fops.c +++ b/drivers/media/common/saa7146/saa7146_fops.c @@ -266,7 +266,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) } dev->v4l2_dev.ctrl_handler = hdl; - vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); + vv = kzalloc_obj(struct saa7146_vv); if (vv == NULL) { ERR("out of memory. aborting.\n"); v4l2_ctrl_handler_free(hdl); diff --git a/drivers/media/common/siano/smscoreapi.c b/drivers/media/common/siano/smscoreapi.c index 3732367e0c62..017629e3cf84 100644 --- a/drivers/media/common/siano/smscoreapi.c +++ b/drivers/media/common/siano/smscoreapi.c @@ -439,7 +439,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath) return entry; } } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (entry) { entry->mode = default_mode; strscpy(entry->devpath, devpath, sizeof(entry->devpath)); @@ -528,7 +528,7 @@ int smscore_register_hotplug(hotplug_t hotplug) int rc = 0; mutex_lock(&g_smscore_deviceslock); - notifyee = kmalloc(sizeof(*notifyee), GFP_KERNEL); + notifyee = kmalloc_obj(*notifyee); if (notifyee) { /* now notify callback about existing devices */ first = &g_smscore_devices; @@ -617,7 +617,7 @@ smscore_buffer_t *smscore_createbuffer(u8 *buffer, void *common_buffer, { struct smscore_buffer_t *cb; - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc_obj(*cb); if (!cb) return NULL; @@ -647,7 +647,7 @@ int smscore_register_device(struct smsdevice_params_t *params, struct smscore_device_t *dev; u8 *buffer; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; @@ -1678,7 +1678,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev, pr_err("The msg ID already registered to another client.\n"); return -EEXIST; } - listentry = kzalloc(sizeof(*listentry), GFP_KERNEL); + listentry = kzalloc_obj(*listentry); if (!listentry) return -ENOMEM; @@ -1715,7 +1715,7 @@ int smscore_register_client(struct smscore_device_t *coredev, return -EEXIST; } - newclient = kzalloc(sizeof(*newclient), GFP_KERNEL); + newclient = kzalloc_obj(*newclient); if (!newclient) return -ENOMEM; diff --git a/drivers/media/common/siano/smsdvb-debugfs.c b/drivers/media/common/siano/smsdvb-debugfs.c index d14ba271db50..c482777e1c60 100644 --- a/drivers/media/common/siano/smsdvb-debugfs.c +++ b/drivers/media/common/siano/smsdvb-debugfs.c @@ -358,7 +358,7 @@ int smsdvb_debugfs_create(struct smsdvb_client_t *client) if (!smsdvb_debugfs_usb_root || !coredev->is_usb_device) return -ENODEV; - debug_data = kzalloc(sizeof(*client->debug_data), GFP_KERNEL); + debug_data = kzalloc_obj(*client->debug_data); if (!debug_data) return -ENOMEM; diff --git a/drivers/media/common/siano/smsdvb-main.c b/drivers/media/common/siano/smsdvb-main.c index 9b1a650ed055..415c24fbbb65 100644 --- a/drivers/media/common/siano/smsdvb-main.c +++ b/drivers/media/common/siano/smsdvb-main.c @@ -1110,7 +1110,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, /* device removal handled by onremove callback */ if (!arrival) return 0; - client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL); + client = kzalloc_obj(struct smsdvb_client_t); if (!client) return -ENOMEM; diff --git a/drivers/media/common/videobuf2/videobuf2-core.c b/drivers/media/common/videobuf2/videobuf2-core.c index 2d1f253b4929..adf668b213c2 100644 --- a/drivers/media/common/videobuf2/videobuf2-core.c +++ b/drivers/media/common/videobuf2/videobuf2-core.c @@ -841,7 +841,7 @@ static bool verify_coherency_flags(struct vb2_queue *q, bool non_coherent_mem) static int vb2_core_allocated_buffers_storage(struct vb2_queue *q) { if (!q->bufs) - q->bufs = kcalloc(q->max_num_buffers, sizeof(*q->bufs), GFP_KERNEL); + q->bufs = kzalloc_objs(*q->bufs, q->max_num_buffers); if (!q->bufs) return -ENOMEM; @@ -2861,7 +2861,7 @@ static int __vb2_init_fileio(struct vb2_queue *q, int read) (read) ? "read" : "write", q->min_reqbufs_allocation, q->fileio_read_once, q->fileio_write_immediately); - fileio = kzalloc(sizeof(*fileio), GFP_KERNEL); + fileio = kzalloc_obj(*fileio); if (fileio == NULL) return -ENOMEM; @@ -3256,7 +3256,7 @@ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, if (WARN_ON(q->fileio)) return -EBUSY; - threadio = kzalloc(sizeof(*threadio), GFP_KERNEL); + threadio = kzalloc_obj(*threadio); if (threadio == NULL) return -ENOMEM; threadio->fnc = fnc; diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c index 7123c5fae92c..9ce6284cd5f2 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c @@ -238,7 +238,7 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb, if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof *buf, GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); @@ -325,7 +325,7 @@ static int vb2_dc_dmabuf_ops_attach(struct dma_buf *dbuf, struct vb2_dc_buf *buf = dbuf->priv; int ret; - attach = kzalloc(sizeof(*attach), GFP_KERNEL); + attach = kzalloc_obj(*attach); if (!attach) return -ENOMEM; @@ -479,7 +479,7 @@ static struct sg_table *vb2_dc_get_base_sgt(struct vb2_dc_buf *buf) if (buf->non_coherent_mem) return buf->dma_sgt; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { dev_err(buf->dev, "failed to alloc sg table\n"); return NULL; @@ -587,7 +587,7 @@ static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof *buf, GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); @@ -624,7 +624,7 @@ static void *vb2_dc_get_userptr(struct vb2_buffer *vb, struct device *dev, goto out; } - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) { pr_err("failed to allocate sg table\n"); ret = -ENOMEM; @@ -779,7 +779,7 @@ static void *vb2_dc_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/common/videobuf2/videobuf2-dma-sg.c b/drivers/media/common/videobuf2/videobuf2-dma-sg.c index b3bf2173c14e..982021d547e5 100644 --- a/drivers/media/common/videobuf2/videobuf2-dma-sg.c +++ b/drivers/media/common/videobuf2/videobuf2-dma-sg.c @@ -109,7 +109,7 @@ static void *vb2_dma_sg_alloc(struct vb2_buffer *vb, struct device *dev, if (WARN_ON(!dev) || WARN_ON(!size)) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof *buf, GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); @@ -126,7 +126,7 @@ static void *vb2_dma_sg_alloc(struct vb2_buffer *vb, struct device *dev, * there is no memory consistency guarantee, hence dma-sg ignores DMA * attributes passed from the upper layer. */ - buf->pages = kvcalloc(buf->num_pages, sizeof(struct page *), GFP_KERNEL); + buf->pages = kvzalloc_objs(struct page *, buf->num_pages); if (!buf->pages) goto fail_pages_array_alloc; @@ -230,7 +230,7 @@ static void *vb2_dma_sg_get_userptr(struct vb2_buffer *vb, struct device *dev, if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof *buf, GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); @@ -375,7 +375,7 @@ static int vb2_dma_sg_dmabuf_ops_attach(struct dma_buf *dbuf, struct vb2_dma_sg_buf *buf = dbuf->priv; int ret; - attach = kzalloc(sizeof(*attach), GFP_KERNEL); + attach = kzalloc_obj(*attach); if (!attach) return -ENOMEM; @@ -626,7 +626,7 @@ static void *vb2_dma_sg_attach_dmabuf(struct vb2_buffer *vb, struct device *dev, if (dbuf->size < size) return ERR_PTR(-EFAULT); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/common/videobuf2/videobuf2-dvb.c b/drivers/media/common/videobuf2/videobuf2-dvb.c index 3746bf6d1c15..ef30a032d9d4 100644 --- a/drivers/media/common/videobuf2/videobuf2-dvb.c +++ b/drivers/media/common/videobuf2/videobuf2-dvb.c @@ -299,7 +299,7 @@ struct vb2_dvb_frontend *vb2_dvb_alloc_frontend( { struct vb2_dvb_frontend *fe; - fe = kzalloc(sizeof(struct vb2_dvb_frontend), GFP_KERNEL); + fe = kzalloc_obj(struct vb2_dvb_frontend); if (fe == NULL) return NULL; diff --git a/drivers/media/common/videobuf2/videobuf2-vmalloc.c b/drivers/media/common/videobuf2/videobuf2-vmalloc.c index 3f777068cd34..63f023696f3e 100644 --- a/drivers/media/common/videobuf2/videobuf2-vmalloc.c +++ b/drivers/media/common/videobuf2/videobuf2-vmalloc.c @@ -39,7 +39,7 @@ static void *vb2_vmalloc_alloc(struct vb2_buffer *vb, struct device *dev, { struct vb2_vmalloc_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL | vb->vb2_queue->gfp_flags); + buf = kzalloc_obj(*buf, GFP_KERNEL | vb->vb2_queue->gfp_flags); if (!buf) return ERR_PTR(-ENOMEM); @@ -78,7 +78,7 @@ static void *vb2_vmalloc_get_userptr(struct vb2_buffer *vb, struct device *dev, int n_pages, offset, i; int ret = -ENOMEM; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); @@ -221,7 +221,7 @@ static int vb2_vmalloc_dmabuf_ops_attach(struct dma_buf *dbuf, int ret; int i; - attach = kzalloc(sizeof(*attach), GFP_KERNEL); + attach = kzalloc_obj(*attach); if (!attach) return -ENOMEM; @@ -409,7 +409,7 @@ static void *vb2_vmalloc_attach_dmabuf(struct vb2_buffer *vb, if (dbuf->size < size) return ERR_PTR(-EFAULT); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c index c946c8ea6e39..3c8bc75e4d6c 100644 --- a/drivers/media/dvb-core/dmxdev.c +++ b/drivers/media/dvb-core/dmxdev.c @@ -168,7 +168,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) mutex_unlock(&dmxdev->mutex); return -ENOMEM; } - dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE); + dmxdev->dvr_buffer.data = mem; + dmxdev->dvr_buffer.size = DVR_BUFFER_SIZE; + dvb_ringbuffer_reset(&dmxdev->dvr_buffer); if (dmxdev->may_do_mmap) dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr", &dmxdev->mutex, @@ -892,7 +894,7 @@ static int dvb_dmxdev_add_pid(struct dmxdev *dmxdev, (!list_empty(&filter->feed.ts))) return -EINVAL; - feed = kzalloc(sizeof(struct dmxdev_feed), GFP_KERNEL); + feed = kzalloc_obj(struct dmxdev_feed); if (feed == NULL) return -ENOMEM; diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 7b591aa1179f..1b91ebb8f667 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -1880,7 +1880,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, return -EINVAL; /* initialise the system data */ - ca = kzalloc(sizeof(*ca), GFP_KERNEL); + ca = kzalloc_obj(*ca); if (!ca) { ret = -ENOMEM; goto exit; @@ -1889,8 +1889,7 @@ int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, ca->pub = pubca; ca->flags = flags; ca->slot_count = slot_count; - ca->slot_info = kcalloc(slot_count, sizeof(struct dvb_ca_slot), - GFP_KERNEL); + ca->slot_info = kzalloc_objs(struct dvb_ca_slot, slot_count); if (!ca->slot_info) { ret = -ENOMEM; goto free_ca; diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index a05aa271a1ba..d082b6c57c76 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -3021,7 +3021,7 @@ int dvb_register_frontend(struct dvb_adapter *dvb, if (mutex_lock_interruptible(&frontend_mutex)) return -ERESTARTSYS; - fe->frontend_priv = kzalloc(sizeof(struct dvb_frontend_private), GFP_KERNEL); + fe->frontend_priv = kzalloc_obj(struct dvb_frontend_private); if (!fe->frontend_priv) { mutex_unlock(&frontend_mutex); return -ENOMEM; diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c index 8bb8dd34c223..a2159b2bc176 100644 --- a/drivers/media/dvb-core/dvb_net.c +++ b/drivers/media/dvb-core/dvb_net.c @@ -228,6 +228,9 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) unsigned char hlen = (p->ule_sndu_type & 0x0700) >> 8; unsigned char htype = p->ule_sndu_type & 0x00FF; + if (htype >= ARRAY_SIZE(ule_mandatory_ext_handlers)) + return -1; + /* Discriminate mandatory and optional extension headers. */ if (hlen == 0) { /* Mandatory extension header */ diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 8b980d371a45..d753d329502a 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -251,13 +251,11 @@ static int dvb_create_tsout_entity(struct dvb_device *dvbdev, { int i; - dvbdev->tsout_pads = kcalloc(npads, sizeof(*dvbdev->tsout_pads), - GFP_KERNEL); + dvbdev->tsout_pads = kzalloc_objs(*dvbdev->tsout_pads, npads); if (!dvbdev->tsout_pads) return -ENOMEM; - dvbdev->tsout_entity = kcalloc(npads, sizeof(*dvbdev->tsout_entity), - GFP_KERNEL); + dvbdev->tsout_entity = kzalloc_objs(*dvbdev->tsout_entity, npads); if (!dvbdev->tsout_entity) return -ENOMEM; @@ -328,15 +326,14 @@ static int dvb_create_media_entity(struct dvb_device *dvbdev, return 0; } - dvbdev->entity = kzalloc(sizeof(*dvbdev->entity), GFP_KERNEL); + dvbdev->entity = kzalloc_obj(*dvbdev->entity); if (!dvbdev->entity) return -ENOMEM; dvbdev->entity->name = dvbdev->name; if (npads) { - dvbdev->pads = kcalloc(npads, sizeof(*dvbdev->pads), - GFP_KERNEL); + dvbdev->pads = kzalloc_objs(*dvbdev->pads, npads); if (!dvbdev->pads) { kfree(dvbdev->entity); dvbdev->entity = NULL; @@ -472,7 +469,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENFILE; } - *pdvbdev = dvbdev = kzalloc(sizeof(*dvbdev), GFP_KERNEL); + *pdvbdev = dvbdev = kzalloc_obj(*dvbdev); if (!dvbdev) { mutex_unlock(&dvbdev_register_lock); return -ENOMEM; @@ -500,7 +497,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, return -ENOMEM; } - new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); + new_node = kzalloc_obj(*new_node); if (!new_node) { kfree(dvbdevfops); kfree(dvbdev); @@ -712,12 +709,12 @@ int dvb_create_media_graph(struct dvb_adapter *adap, demod = NULL; if (create_rf_connector) { - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) return -ENOMEM; adap->conn = conn; - adap->conn_pads = kzalloc(sizeof(*adap->conn_pads), GFP_KERNEL); + adap->conn_pads = kzalloc_obj(*adap->conn_pads); if (!adap->conn_pads) return -ENOMEM; @@ -1027,7 +1024,7 @@ struct i2c_client *dvb_module_probe(const char *module_name, struct i2c_client *client; struct i2c_board_info *board_info; - board_info = kzalloc(sizeof(*board_info), GFP_KERNEL); + board_info = kzalloc_obj(*board_info); if (!board_info) return NULL; diff --git a/drivers/media/dvb-frontends/a8293.c b/drivers/media/dvb-frontends/a8293.c index bf2773c5b97a..7c0963054a8f 100644 --- a/drivers/media/dvb-frontends/a8293.c +++ b/drivers/media/dvb-frontends/a8293.c @@ -218,7 +218,7 @@ static int a8293_probe(struct i2c_client *client) int ret; u8 buf[2]; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/af9013.c b/drivers/media/dvb-frontends/af9013.c index befd6a4eafd9..75f3063c193e 100644 --- a/drivers/media/dvb-frontends/af9013.c +++ b/drivers/media/dvb-frontends/af9013.c @@ -1447,7 +1447,7 @@ static int af9013_probe(struct i2c_client *client) .val_bits = 8, }; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/af9033.c b/drivers/media/dvb-frontends/af9033.c index eed2ea4da8fa..9a3a4d6513dd 100644 --- a/drivers/media/dvb-frontends/af9033.c +++ b/drivers/media/dvb-frontends/af9033.c @@ -1062,7 +1062,7 @@ static int af9033_probe(struct i2c_client *client) }; /* Allocate memory for the internal state */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/as102_fe.c b/drivers/media/dvb-frontends/as102_fe.c index bc72d954dc1f..fecb0735d753 100644 --- a/drivers/media/dvb-frontends/as102_fe.c +++ b/drivers/media/dvb-frontends/as102_fe.c @@ -447,7 +447,7 @@ struct dvb_frontend *as102_attach(const char *name, struct as102_state *state; struct dvb_frontend *fe; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/ascot2e.c b/drivers/media/dvb-frontends/ascot2e.c index cf8e5f1bd101..3bdb4d12f8b7 100644 --- a/drivers/media/dvb-frontends/ascot2e.c +++ b/drivers/media/dvb-frontends/ascot2e.c @@ -477,7 +477,7 @@ struct dvb_frontend *ascot2e_attach(struct dvb_frontend *fe, u8 data[4]; struct ascot2e_priv *priv = NULL; - priv = kzalloc(sizeof(struct ascot2e_priv), GFP_KERNEL); + priv = kzalloc_obj(struct ascot2e_priv); if (priv == NULL) return NULL; priv->i2c_address = (config->i2c_address >> 1); diff --git a/drivers/media/dvb-frontends/atbm8830.c b/drivers/media/dvb-frontends/atbm8830.c index 778c865085bf..9ef8adbf9f7d 100644 --- a/drivers/media/dvb-frontends/atbm8830.c +++ b/drivers/media/dvb-frontends/atbm8830.c @@ -458,7 +458,7 @@ struct dvb_frontend *atbm8830_attach(const struct atbm8830_config *config, if (config == NULL || i2c == NULL) return NULL; - priv = kzalloc(sizeof(struct atbm_state), GFP_KERNEL); + priv = kzalloc_obj(struct atbm_state); if (priv == NULL) goto error_out; diff --git a/drivers/media/dvb-frontends/bcm3510.c b/drivers/media/dvb-frontends/bcm3510.c index d935fb10e620..7f91156d02c7 100644 --- a/drivers/media/dvb-frontends/bcm3510.c +++ b/drivers/media/dvb-frontends/bcm3510.c @@ -800,7 +800,7 @@ struct dvb_frontend* bcm3510_attach(const struct bcm3510_config *config, bcm3510_register_value v; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct bcm3510_state), GFP_KERNEL); + state = kzalloc_obj(struct bcm3510_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/cx22700.c b/drivers/media/dvb-frontends/cx22700.c index 1d04c0a652b2..cb1c30aee684 100644 --- a/drivers/media/dvb-frontends/cx22700.c +++ b/drivers/media/dvb-frontends/cx22700.c @@ -376,7 +376,7 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, struct cx22700_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx22700_state), GFP_KERNEL); + state = kzalloc_obj(struct cx22700_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/cx22702.c b/drivers/media/dvb-frontends/cx22702.c index 61ad34b7004b..cbfe156e018a 100644 --- a/drivers/media/dvb-frontends/cx22702.c +++ b/drivers/media/dvb-frontends/cx22702.c @@ -582,7 +582,7 @@ struct dvb_frontend *cx22702_attach(const struct cx22702_config *config, struct cx22702_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx22702_state), GFP_KERNEL); + state = kzalloc_obj(struct cx22702_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/cx24110.c b/drivers/media/dvb-frontends/cx24110.c index 65dd9b72ea55..fb81a2f264f4 100644 --- a/drivers/media/dvb-frontends/cx24110.c +++ b/drivers/media/dvb-frontends/cx24110.c @@ -588,7 +588,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, int ret; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx24110_state), GFP_KERNEL); + state = kzalloc_obj(struct cx24110_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/cx24113.c b/drivers/media/dvb-frontends/cx24113.c index 203cb6b3f941..22f8544f1907 100644 --- a/drivers/media/dvb-frontends/cx24113.c +++ b/drivers/media/dvb-frontends/cx24113.c @@ -542,7 +542,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, const struct cx24113_config *config, struct i2c_adapter *i2c) { /* allocate memory for the internal state */ - struct cx24113_state *state = kzalloc(sizeof(*state), GFP_KERNEL); + struct cx24113_state *state = kzalloc_obj(*state); int rc; if (!state) diff --git a/drivers/media/dvb-frontends/cx24116.c b/drivers/media/dvb-frontends/cx24116.c index f5dd3a81725a..c10053a7cb82 100644 --- a/drivers/media/dvb-frontends/cx24116.c +++ b/drivers/media/dvb-frontends/cx24116.c @@ -1116,7 +1116,7 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/cx24117.c b/drivers/media/dvb-frontends/cx24117.c index 75fc7ad263d0..eed03276b3b5 100644 --- a/drivers/media/dvb-frontends/cx24117.c +++ b/drivers/media/dvb-frontends/cx24117.c @@ -1184,7 +1184,7 @@ struct dvb_frontend *cx24117_attach(const struct cx24117_config *config, } /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct cx24117_state), GFP_KERNEL); + state = kzalloc_obj(struct cx24117_state); if (state == NULL) goto error2; diff --git a/drivers/media/dvb-frontends/cx24120.c b/drivers/media/dvb-frontends/cx24120.c index 44515fdbe91d..438a436762a7 100644 --- a/drivers/media/dvb-frontends/cx24120.c +++ b/drivers/media/dvb-frontends/cx24120.c @@ -268,7 +268,7 @@ struct dvb_frontend *cx24120_attach(const struct cx24120_config *config, int demod_rev; info("Conexant cx24120/cx24118 - DVBS/S2 Satellite demod/tuner\n"); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { err("Unable to allocate memory for cx24120_state\n"); goto error; diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index 539889e638cc..2706f3831c63 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -1043,7 +1043,7 @@ struct dvb_frontend *cx24123_attach(const struct cx24123_config *config, { /* allocate memory for the internal state */ struct cx24123_state *state = - kzalloc(sizeof(struct cx24123_state), GFP_KERNEL); + kzalloc_obj(struct cx24123_state); dprintk("\n"); if (state == NULL) { diff --git a/drivers/media/dvb-frontends/cxd2099.c b/drivers/media/dvb-frontends/cxd2099.c index 5e6e18819a0d..f95950a61307 100644 --- a/drivers/media/dvb-frontends/cxd2099.c +++ b/drivers/media/dvb-frontends/cxd2099.c @@ -609,7 +609,7 @@ static int cxd2099_probe(struct i2c_client *client) unsigned int val; int ret; - ci = kzalloc(sizeof(*ci), GFP_KERNEL); + ci = kzalloc_obj(*ci); if (!ci) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/cxd2820r_core.c b/drivers/media/dvb-frontends/cxd2820r_core.c index 5aa3d45a691a..3deefeff4bd1 100644 --- a/drivers/media/dvb-frontends/cxd2820r_core.c +++ b/drivers/media/dvb-frontends/cxd2820r_core.c @@ -594,7 +594,7 @@ static int cxd2820r_probe(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/cxd2841er.c b/drivers/media/dvb-frontends/cxd2841er.c index 8fcb4417ba22..593107f428ce 100644 --- a/drivers/media/dvb-frontends/cxd2841er.c +++ b/drivers/media/dvb-frontends/cxd2841er.c @@ -3844,7 +3844,7 @@ static struct dvb_frontend *cxd2841er_attach(struct cxd2841er_config *cfg, struct cxd2841er_priv *priv = NULL; /* allocate memory for the internal state */ - priv = kzalloc(sizeof(struct cxd2841er_priv), GFP_KERNEL); + priv = kzalloc_obj(struct cxd2841er_priv); if (!priv) return NULL; priv->i2c = i2c; diff --git a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c index a06d8368ca79..0d058b59a472 100644 --- a/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c +++ b/drivers/media/dvb-frontends/cxd2880/cxd2880_top.c @@ -1887,7 +1887,7 @@ struct dvb_frontend *cxd2880_attach(struct dvb_frontend *fe, return NULL; } - priv = kzalloc(sizeof(struct cxd2880_priv), GFP_KERNEL); + priv = kzalloc_obj(struct cxd2880_priv); if (!priv) return NULL; diff --git a/drivers/media/dvb-frontends/dib0070.c b/drivers/media/dvb-frontends/dib0070.c index 9a8e7cdd2a24..ebb0c4b98f3c 100644 --- a/drivers/media/dvb-frontends/dib0070.c +++ b/drivers/media/dvb-frontends/dib0070.c @@ -738,7 +738,7 @@ static const struct dvb_tuner_ops dib0070_ops = { struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) { - struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); + struct dib0070_state *state = kzalloc_obj(struct dib0070_state); if (state == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/dib0090.c b/drivers/media/dvb-frontends/dib0090.c index 6cbbb351d545..e2a48059e854 100644 --- a/drivers/media/dvb-frontends/dib0090.c +++ b/drivers/media/dvb-frontends/dib0090.c @@ -2606,7 +2606,7 @@ static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = { struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { - struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); + struct dib0090_state *st = kzalloc_obj(struct dib0090_state); if (st == NULL) return NULL; @@ -2638,7 +2638,7 @@ EXPORT_SYMBOL_GPL(dib0090_register); struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) { - struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL); + struct dib0090_fw_state *st = kzalloc_obj(struct dib0090_fw_state); if (st == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/dib3000mb.c b/drivers/media/dvb-frontends/dib3000mb.c index 63bc7b74bc8b..251410842b18 100644 --- a/drivers/media/dvb-frontends/dib3000mb.c +++ b/drivers/media/dvb-frontends/dib3000mb.c @@ -746,7 +746,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, struct dib3000_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); + state = kzalloc_obj(struct dib3000_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/dib3000mc.c b/drivers/media/dvb-frontends/dib3000mc.c index c2fca8289aba..544e5a0a5873 100644 --- a/drivers/media/dvb-frontends/dib3000mc.c +++ b/drivers/media/dvb-frontends/dib3000mc.c @@ -861,7 +861,7 @@ int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defa static const u8 DIB3000MC_I2C_ADDRESS[] = { 20, 22, 24, 26 }; - dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); + dmcst = kzalloc_obj(struct dib3000mc_state); if (dmcst == NULL) return -ENOMEM; @@ -910,7 +910,7 @@ struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr { struct dvb_frontend *demod; struct dib3000mc_state *st; - st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); + st = kzalloc_obj(struct dib3000mc_state); if (st == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/dib7000m.c b/drivers/media/dvb-frontends/dib7000m.c index fdb22f32e3a1..44a78c7539a6 100644 --- a/drivers/media/dvb-frontends/dib7000m.c +++ b/drivers/media/dvb-frontends/dib7000m.c @@ -1403,7 +1403,7 @@ struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, { struct dvb_frontend *demod; struct dib7000m_state *st; - st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL); + st = kzalloc_obj(struct dib7000m_state); if (st == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/dib7000p.c b/drivers/media/dvb-frontends/dib7000p.c index 7d3a994b7cc4..48d84a05ddfa 100644 --- a/drivers/media/dvb-frontends/dib7000p.c +++ b/drivers/media/dvb-frontends/dib7000p.c @@ -2081,7 +2081,7 @@ static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u int k = 0; u8 new_addr = 0; - dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); + dpst = kzalloc_obj(struct dib7000p_state); if (!dpst) return -ENOMEM; @@ -2741,7 +2741,7 @@ static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_a { struct dvb_frontend *demod; struct dib7000p_state *st; - st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL); + st = kzalloc_obj(struct dib7000p_state); if (st == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c index d90f1b0b2051..ebef27bcc989 100644 --- a/drivers/media/dvb-frontends/dib8000.c +++ b/drivers/media/dvb-frontends/dib8000.c @@ -4307,7 +4307,7 @@ static int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, ret = -ENOMEM; goto error_memory_read; } - client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); + client.i2c_buffer_lock = kzalloc_obj(struct mutex); if (!client.i2c_buffer_lock) { dprintk("%s: not enough memory\n", __func__); ret = -ENOMEM; @@ -4448,10 +4448,10 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad dprintk("dib8000_init\n"); - state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); + state = kzalloc_obj(struct dib8000_state); if (state == NULL) return NULL; - fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL); + fe = kzalloc_obj(struct dvb_frontend); if (fe == NULL) goto error; diff --git a/drivers/media/dvb-frontends/dib9000.c b/drivers/media/dvb-frontends/dib9000.c index 83cf6eadd49c..cb7c943225bd 100644 --- a/drivers/media/dvb-frontends/dib9000.c +++ b/drivers/media/dvb-frontends/dib9000.c @@ -2474,10 +2474,10 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c { struct dvb_frontend *fe; struct dib9000_state *st; - st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL); + st = kzalloc_obj(struct dib9000_state); if (st == NULL) return NULL; - fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL); + fe = kzalloc_obj(struct dvb_frontend); if (fe == NULL) { kfree(st); return NULL; diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index 428b31e60874..367acb59b4a3 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -12276,7 +12276,7 @@ struct dvb_frontend *drx39xxj_attach(struct i2c_adapter *i2c) int result; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct drx39xxj_state), GFP_KERNEL); + state = kzalloc_obj(struct drx39xxj_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/drxd_hard.c b/drivers/media/dvb-frontends/drxd_hard.c index 6a531937f4bb..4d673a108f61 100644 --- a/drivers/media/dvb-frontends/drxd_hard.c +++ b/drivers/media/dvb-frontends/drxd_hard.c @@ -2910,7 +2910,7 @@ struct dvb_frontend *drxd_attach(const struct drxd_config *config, { struct drxd_state *state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index 9ef367918824..47786d0610f0 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -6722,7 +6722,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, int status; dprintk(1, "\n"); - state = kzalloc(sizeof(struct drxk_state), GFP_KERNEL); + state = kzalloc_obj(struct drxk_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/ds3000.c b/drivers/media/dvb-frontends/ds3000.c index 515aa7c7baf2..ce7ae424b27c 100644 --- a/drivers/media/dvb-frontends/ds3000.c +++ b/drivers/media/dvb-frontends/ds3000.c @@ -827,7 +827,7 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/dvb-pll.c b/drivers/media/dvb-frontends/dvb-pll.c index 1775a4aa0a18..f8fd23f60e3f 100644 --- a/drivers/media/dvb-frontends/dvb-pll.c +++ b/drivers/media/dvb-frontends/dvb-pll.c @@ -820,7 +820,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, fe->ops.i2c_gate_ctrl(fe, 0); } - priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); + priv = kzalloc_obj(struct dvb_pll_priv); if (!priv) goto out; diff --git a/drivers/media/dvb-frontends/dvb_dummy_fe.c b/drivers/media/dvb-frontends/dvb_dummy_fe.c index 9ff1ebaa5e04..6a34cdc28727 100644 --- a/drivers/media/dvb-frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb-frontends/dvb_dummy_fe.c @@ -114,7 +114,7 @@ struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void) struct dvb_dummy_fe_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct dvb_dummy_fe_state); if (!state) return NULL; @@ -135,7 +135,7 @@ struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void) struct dvb_dummy_fe_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct dvb_dummy_fe_state); if (!state) return NULL; @@ -156,7 +156,7 @@ struct dvb_frontend *dvb_dummy_fe_qam_attach(void) struct dvb_dummy_fe_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct dvb_dummy_fe_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/ec100.c b/drivers/media/dvb-frontends/ec100.c index 2ad0a3c2f756..b7a3572f8a58 100644 --- a/drivers/media/dvb-frontends/ec100.c +++ b/drivers/media/dvb-frontends/ec100.c @@ -276,7 +276,7 @@ struct dvb_frontend *ec100_attach(const struct ec100_config *config, u8 tmp; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL); + state = kzalloc_obj(struct ec100_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/gp8psk-fe.c b/drivers/media/dvb-frontends/gp8psk-fe.c index ed671e951a17..aad311ffd2b5 100644 --- a/drivers/media/dvb-frontends/gp8psk-fe.c +++ b/drivers/media/dvb-frontends/gp8psk-fe.c @@ -332,7 +332,7 @@ struct dvb_frontend *gp8psk_fe_attach(const struct gp8psk_fe_ops *ops, return NULL; } - st = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL); + st = kzalloc_obj(struct gp8psk_fe_state); if (!st) return NULL; diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index f127adee3ebb..1402d124544e 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c @@ -997,7 +997,7 @@ struct dvb_frontend *helene_attach_s(struct dvb_frontend *fe, { struct helene_priv *priv = NULL; - priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL); + priv = kzalloc_obj(struct helene_priv); if (priv == NULL) return NULL; priv->i2c_address = (config->i2c_address >> 1); @@ -1033,7 +1033,7 @@ struct dvb_frontend *helene_attach(struct dvb_frontend *fe, { struct helene_priv *priv = NULL; - priv = kzalloc(sizeof(struct helene_priv), GFP_KERNEL); + priv = kzalloc_obj(struct helene_priv); if (priv == NULL) return NULL; priv->i2c_address = (config->i2c_address >> 1); diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c index 0330b78a5b3f..63579d6e24e5 100644 --- a/drivers/media/dvb-frontends/horus3a.c +++ b/drivers/media/dvb-frontends/horus3a.c @@ -339,7 +339,7 @@ struct dvb_frontend *horus3a_attach(struct dvb_frontend *fe, u8 buf[3], val; struct horus3a_priv *priv = NULL; - priv = kzalloc(sizeof(struct horus3a_priv), GFP_KERNEL); + priv = kzalloc_obj(struct horus3a_priv); if (priv == NULL) return NULL; priv->i2c_address = (config->i2c_address >> 1); diff --git a/drivers/media/dvb-frontends/isl6405.c b/drivers/media/dvb-frontends/isl6405.c index 7d28a743f97e..2e681e2ba0c3 100644 --- a/drivers/media/dvb-frontends/isl6405.c +++ b/drivers/media/dvb-frontends/isl6405.c @@ -106,7 +106,7 @@ static void isl6405_release(struct dvb_frontend *fe) struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear) { - struct isl6405 *isl6405 = kmalloc(sizeof(struct isl6405), GFP_KERNEL); + struct isl6405 *isl6405 = kmalloc_obj(struct isl6405); if (!isl6405) return NULL; diff --git a/drivers/media/dvb-frontends/isl6421.c b/drivers/media/dvb-frontends/isl6421.c index 2e9f6f12f849..b3c130e7dbe5 100644 --- a/drivers/media/dvb-frontends/isl6421.c +++ b/drivers/media/dvb-frontends/isl6421.c @@ -177,7 +177,7 @@ static void isl6421_release(struct dvb_frontend *fe) struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, u8 override_set, u8 override_clear, bool override_tone) { - struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); + struct isl6421 *isl6421 = kmalloc_obj(struct isl6421); if (!isl6421) return NULL; diff --git a/drivers/media/dvb-frontends/isl6423.c b/drivers/media/dvb-frontends/isl6423.c index a0d0a3834057..48f15cca07d3 100644 --- a/drivers/media/dvb-frontends/isl6423.c +++ b/drivers/media/dvb-frontends/isl6423.c @@ -258,7 +258,7 @@ struct dvb_frontend *isl6423_attach(struct dvb_frontend *fe, { struct isl6423_dev *isl6423; - isl6423 = kzalloc(sizeof(struct isl6423_dev), GFP_KERNEL); + isl6423 = kzalloc_obj(struct isl6423_dev); if (!isl6423) return NULL; diff --git a/drivers/media/dvb-frontends/itd1000.c b/drivers/media/dvb-frontends/itd1000.c index f8f362f50e78..f5f02363917e 100644 --- a/drivers/media/dvb-frontends/itd1000.c +++ b/drivers/media/dvb-frontends/itd1000.c @@ -365,7 +365,7 @@ struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter struct itd1000_state *state = NULL; u8 i = 0; - state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL); + state = kzalloc_obj(struct itd1000_state); if (state == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/ix2505v.c b/drivers/media/dvb-frontends/ix2505v.c index 3212e333d472..832c998a3d99 100644 --- a/drivers/media/dvb-frontends/ix2505v.c +++ b/drivers/media/dvb-frontends/ix2505v.c @@ -267,7 +267,7 @@ struct dvb_frontend *ix2505v_attach(struct dvb_frontend *fe, goto error; } - state = kzalloc(sizeof(struct ix2505v_state), GFP_KERNEL); + state = kzalloc_obj(struct ix2505v_state); if (NULL == state) return NULL; diff --git a/drivers/media/dvb-frontends/l64781.c b/drivers/media/dvb-frontends/l64781.c index fe5af2453d55..ff686c132eaf 100644 --- a/drivers/media/dvb-frontends/l64781.c +++ b/drivers/media/dvb-frontends/l64781.c @@ -497,7 +497,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct l64781_state), GFP_KERNEL); + state = kzalloc_obj(struct l64781_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/lg2160.c b/drivers/media/dvb-frontends/lg2160.c index fe700aa56bff..41c4aae0cb49 100644 --- a/drivers/media/dvb-frontends/lg2160.c +++ b/drivers/media/dvb-frontends/lg2160.c @@ -1396,7 +1396,7 @@ struct dvb_frontend *lg2160_attach(const struct lg2160_config *config, i2c_adap ? i2c_adapter_id(i2c_adap) : 0, config ? config->i2c_addr : 0); - state = kzalloc(sizeof(struct lg216x_state), GFP_KERNEL); + state = kzalloc_obj(struct lg216x_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/lgdt3305.c b/drivers/media/dvb-frontends/lgdt3305.c index bdc8311e1c0b..e08ee89c4c26 100644 --- a/drivers/media/dvb-frontends/lgdt3305.c +++ b/drivers/media/dvb-frontends/lgdt3305.c @@ -1103,7 +1103,7 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config, i2c_adap ? i2c_adapter_id(i2c_adap) : 0, config ? config->i2c_addr : 0); - state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL); + state = kzalloc_obj(struct lgdt3305_state); if (state == NULL) goto fail; diff --git a/drivers/media/dvb-frontends/lgdt3306a.c b/drivers/media/dvb-frontends/lgdt3306a.c index 6ab9d4de65ce..b6a66e122ed5 100644 --- a/drivers/media/dvb-frontends/lgdt3306a.c +++ b/drivers/media/dvb-frontends/lgdt3306a.c @@ -1802,7 +1802,7 @@ struct dvb_frontend *lgdt3306a_attach(const struct lgdt3306a_config *config, i2c_adap ? i2c_adapter_id(i2c_adap) : 0, config ? config->i2c_addr : 0); - state = kzalloc(sizeof(struct lgdt3306a_state), GFP_KERNEL); + state = kzalloc_obj(struct lgdt3306a_state); if (state == NULL) goto fail; diff --git a/drivers/media/dvb-frontends/lgdt330x.c b/drivers/media/dvb-frontends/lgdt330x.c index 8c34a5b850bc..19a4a05b3499 100644 --- a/drivers/media/dvb-frontends/lgdt330x.c +++ b/drivers/media/dvb-frontends/lgdt330x.c @@ -863,7 +863,7 @@ static int lgdt330x_probe(struct i2c_client *client) u8 buf[1]; /* Allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) goto error; diff --git a/drivers/media/dvb-frontends/lgs8gl5.c b/drivers/media/dvb-frontends/lgs8gl5.c index 872abb70d1b6..3ee12a9e4526 100644 --- a/drivers/media/dvb-frontends/lgs8gl5.c +++ b/drivers/media/dvb-frontends/lgs8gl5.c @@ -375,7 +375,7 @@ lgs8gl5_attach(const struct lgs8gl5_config *config, struct i2c_adapter *i2c) dprintk("%s\n", __func__); /* Allocate memory for the internal state */ - state = kzalloc(sizeof(struct lgs8gl5_state), GFP_KERNEL); + state = kzalloc_obj(struct lgs8gl5_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/lgs8gxx.c b/drivers/media/dvb-frontends/lgs8gxx.c index ffaf60e16ecd..285ac9ddd419 100644 --- a/drivers/media/dvb-frontends/lgs8gxx.c +++ b/drivers/media/dvb-frontends/lgs8gxx.c @@ -1012,7 +1012,7 @@ struct dvb_frontend *lgs8gxx_attach(const struct lgs8gxx_config *config, if (config == NULL || i2c == NULL) return NULL; - priv = kzalloc(sizeof(struct lgs8gxx_state), GFP_KERNEL); + priv = kzalloc_obj(struct lgs8gxx_state); if (priv == NULL) goto error_out; diff --git a/drivers/media/dvb-frontends/lnbh25.c b/drivers/media/dvb-frontends/lnbh25.c index 41bec050642b..8a0b9efd17db 100644 --- a/drivers/media/dvb-frontends/lnbh25.c +++ b/drivers/media/dvb-frontends/lnbh25.c @@ -148,7 +148,7 @@ struct dvb_frontend *lnbh25_attach(struct dvb_frontend *fe, struct lnbh25_priv *priv; dev_dbg(&i2c->dev, "%s()\n", __func__); - priv = kzalloc(sizeof(struct lnbh25_priv), GFP_KERNEL); + priv = kzalloc_obj(struct lnbh25_priv); if (!priv) return NULL; priv->i2c_address = (cfg->i2c_address >> 1); diff --git a/drivers/media/dvb-frontends/lnbh29.c b/drivers/media/dvb-frontends/lnbh29.c index 410bae099c32..1fcb7ad16508 100644 --- a/drivers/media/dvb-frontends/lnbh29.c +++ b/drivers/media/dvb-frontends/lnbh29.c @@ -135,7 +135,7 @@ struct dvb_frontend *lnbh29_attach(struct dvb_frontend *fe, { struct lnbh29_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; diff --git a/drivers/media/dvb-frontends/lnbp21.c b/drivers/media/dvb-frontends/lnbp21.c index 32593b1f75a3..2007c2713cfb 100644 --- a/drivers/media/dvb-frontends/lnbp21.c +++ b/drivers/media/dvb-frontends/lnbp21.c @@ -113,7 +113,7 @@ static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear, u8 i2c_addr, u8 config) { - struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); + struct lnbp21 *lnbp21 = kmalloc_obj(struct lnbp21); if (!lnbp21) return NULL; diff --git a/drivers/media/dvb-frontends/lnbp22.c b/drivers/media/dvb-frontends/lnbp22.c index cb4ea5d3fad4..9daef48d1569 100644 --- a/drivers/media/dvb-frontends/lnbp22.c +++ b/drivers/media/dvb-frontends/lnbp22.c @@ -96,7 +96,7 @@ static void lnbp22_release(struct dvb_frontend *fe) struct dvb_frontend *lnbp22_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c) { - struct lnbp22 *lnbp22 = kmalloc(sizeof(struct lnbp22), GFP_KERNEL); + struct lnbp22 *lnbp22 = kmalloc_obj(struct lnbp22); if (!lnbp22) return NULL; diff --git a/drivers/media/dvb-frontends/m88ds3103.c b/drivers/media/dvb-frontends/m88ds3103.c index 5a03485686d9..be156180e5ef 100644 --- a/drivers/media/dvb-frontends/m88ds3103.c +++ b/drivers/media/dvb-frontends/m88ds3103.c @@ -1775,7 +1775,7 @@ static int m88ds3103_probe(struct i2c_client *client) int ret; unsigned int utmp; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/m88rs2000.c b/drivers/media/dvb-frontends/m88rs2000.c index 2aa98203cd65..9c9f34c6d3a2 100644 --- a/drivers/media/dvb-frontends/m88rs2000.c +++ b/drivers/media/dvb-frontends/m88rs2000.c @@ -786,7 +786,7 @@ struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config, struct m88rs2000_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL); + state = kzalloc_obj(struct m88rs2000_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/mb86a16.c b/drivers/media/dvb-frontends/mb86a16.c index 9033e39d75f4..50737e6f81dc 100644 --- a/drivers/media/dvb-frontends/mb86a16.c +++ b/drivers/media/dvb-frontends/mb86a16.c @@ -1833,7 +1833,7 @@ struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config, u8 dev_id = 0; struct mb86a16_state *state = NULL; - state = kmalloc(sizeof(struct mb86a16_state), GFP_KERNEL); + state = kmalloc_obj(struct mb86a16_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index f8e4bbee5bd5..0d9bfc5b3761 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -2052,7 +2052,7 @@ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config, dev_dbg(&i2c->dev, "%s called.\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c index 729751671c3d..275c404ce286 100644 --- a/drivers/media/dvb-frontends/mn88472.c +++ b/drivers/media/dvb-frontends/mn88472.c @@ -586,7 +586,7 @@ static int mn88472_probe(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c index fefc640d8afb..40a0cb1d9c67 100644 --- a/drivers/media/dvb-frontends/mn88473.c +++ b/drivers/media/dvb-frontends/mn88473.c @@ -626,7 +626,7 @@ static int mn88473_probe(struct i2c_client *client) goto err; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/mt312.c b/drivers/media/dvb-frontends/mt312.c index fb867dd8a26b..8fe850a8d914 100644 --- a/drivers/media/dvb-frontends/mt312.c +++ b/drivers/media/dvb-frontends/mt312.c @@ -780,7 +780,7 @@ struct dvb_frontend *mt312_attach(const struct mt312_config *config, struct mt312_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL); + state = kzalloc_obj(struct mt312_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/mt352.c b/drivers/media/dvb-frontends/mt352.c index 1b2889f5cf67..7ae4d93f1f19 100644 --- a/drivers/media/dvb-frontends/mt352.c +++ b/drivers/media/dvb-frontends/mt352.c @@ -533,7 +533,7 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config, struct mt352_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct mt352_state), GFP_KERNEL); + state = kzalloc_obj(struct mt352_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/mxl5xx.c b/drivers/media/dvb-frontends/mxl5xx.c index 930da176e5bf..64d83589dfc4 100644 --- a/drivers/media/dvb-frontends/mxl5xx.c +++ b/drivers/media/dvb-frontends/mxl5xx.c @@ -1829,7 +1829,7 @@ struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, struct mxl *state; struct mxl_base *base; - state = kzalloc(sizeof(struct mxl), GFP_KERNEL); + state = kzalloc_obj(struct mxl); if (!state) return NULL; @@ -1845,7 +1845,7 @@ struct dvb_frontend *mxl5xx_attach(struct i2c_adapter *i2c, goto fail; state->base = base; } else { - base = kzalloc(sizeof(struct mxl_base), GFP_KERNEL); + base = kzalloc_obj(struct mxl_base); if (!base) goto fail; base->i2c = i2c; diff --git a/drivers/media/dvb-frontends/mxl692.c b/drivers/media/dvb-frontends/mxl692.c index bbc2bc778225..2d8eaa20723f 100644 --- a/drivers/media/dvb-frontends/mxl692.c +++ b/drivers/media/dvb-frontends/mxl692.c @@ -1314,7 +1314,7 @@ static int mxl692_probe(struct i2c_client *client) struct mxl692_dev *dev; int ret = 0; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; dev_dbg(&client->dev, "kzalloc() failed\n"); diff --git a/drivers/media/dvb-frontends/nxt200x.c b/drivers/media/dvb-frontends/nxt200x.c index 1c549ada6ebf..d1f93ac18888 100644 --- a/drivers/media/dvb-frontends/nxt200x.c +++ b/drivers/media/dvb-frontends/nxt200x.c @@ -1128,7 +1128,7 @@ struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, u8 buf [] = {0,0,0,0,0}; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL); + state = kzalloc_obj(struct nxt200x_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/nxt6000.c b/drivers/media/dvb-frontends/nxt6000.c index e8d4940370dd..99cfa610e263 100644 --- a/drivers/media/dvb-frontends/nxt6000.c +++ b/drivers/media/dvb-frontends/nxt6000.c @@ -560,7 +560,7 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, struct nxt6000_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL); + state = kzalloc_obj(struct nxt6000_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c index 74e04c7cca1e..e908d33d7e72 100644 --- a/drivers/media/dvb-frontends/or51132.c +++ b/drivers/media/dvb-frontends/or51132.c @@ -552,7 +552,7 @@ struct dvb_frontend* or51132_attach(const struct or51132_config* config, struct or51132_state* state = NULL; /* Allocate memory for the internal state */ - state = kzalloc(sizeof(struct or51132_state), GFP_KERNEL); + state = kzalloc_obj(struct or51132_state); if (state == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/or51211.c b/drivers/media/dvb-frontends/or51211.c index 2e8e7071a67a..8c4aabef2d99 100644 --- a/drivers/media/dvb-frontends/or51211.c +++ b/drivers/media/dvb-frontends/or51211.c @@ -501,7 +501,7 @@ struct dvb_frontend* or51211_attach(const struct or51211_config* config, struct or51211_state* state = NULL; /* Allocate memory for the internal state */ - state = kzalloc(sizeof(struct or51211_state), GFP_KERNEL); + state = kzalloc_obj(struct or51211_state); if (state == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/rtl2830.c b/drivers/media/dvb-frontends/rtl2830.c index aa4ef9aedf17..f0ee7c38ee79 100644 --- a/drivers/media/dvb-frontends/rtl2830.c +++ b/drivers/media/dvb-frontends/rtl2830.c @@ -807,7 +807,7 @@ static int rtl2830_probe(struct i2c_client *client) } /* allocate memory for the internal state */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/rtl2832.c b/drivers/media/dvb-frontends/rtl2832.c index 3b4e46dac1bf..d8e1546aea5e 100644 --- a/drivers/media/dvb-frontends/rtl2832.c +++ b/drivers/media/dvb-frontends/rtl2832.c @@ -1043,7 +1043,7 @@ static int rtl2832_probe(struct i2c_client *client) dev_dbg(&client->dev, "\n"); /* allocate memory for the internal state */ - dev = kzalloc(sizeof(struct rtl2832_dev), GFP_KERNEL); + dev = kzalloc_obj(struct rtl2832_dev); if (dev == NULL) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/rtl2832_sdr.c b/drivers/media/dvb-frontends/rtl2832_sdr.c index 0357624968f1..422d1a7b5456 100644 --- a/drivers/media/dvb-frontends/rtl2832_sdr.c +++ b/drivers/media/dvb-frontends/rtl2832_sdr.c @@ -1330,7 +1330,7 @@ static int rtl2832_sdr_probe(struct platform_device *pdev) ret = -EINVAL; goto err; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { ret = -ENOMEM; goto err_module_put; diff --git a/drivers/media/dvb-frontends/s5h1409.c b/drivers/media/dvb-frontends/s5h1409.c index 28b1dca077ea..370824589ab5 100644 --- a/drivers/media/dvb-frontends/s5h1409.c +++ b/drivers/media/dvb-frontends/s5h1409.c @@ -946,7 +946,7 @@ struct dvb_frontend *s5h1409_attach(const struct s5h1409_config *config, u16 reg; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct s5h1409_state), GFP_KERNEL); + state = kzalloc_obj(struct s5h1409_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/s5h1411.c b/drivers/media/dvb-frontends/s5h1411.c index fc48e659c2d8..bffd3a492c65 100644 --- a/drivers/media/dvb-frontends/s5h1411.c +++ b/drivers/media/dvb-frontends/s5h1411.c @@ -861,7 +861,7 @@ struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config, u16 reg; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct s5h1411_state), GFP_KERNEL); + state = kzalloc_obj(struct s5h1411_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/s5h1420.c b/drivers/media/dvb-frontends/s5h1420.c index d700de1ea6c2..99fb5c088a45 100644 --- a/drivers/media/dvb-frontends/s5h1420.c +++ b/drivers/media/dvb-frontends/s5h1420.c @@ -872,7 +872,7 @@ struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config, struct i2c_adapter *i2c) { /* allocate memory for the internal state */ - struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL); + struct s5h1420_state *state = kzalloc_obj(struct s5h1420_state); u8 i; if (state == NULL) diff --git a/drivers/media/dvb-frontends/s5h1432.c b/drivers/media/dvb-frontends/s5h1432.c index ff5d3bdf3bc6..3046ee8cc0bc 100644 --- a/drivers/media/dvb-frontends/s5h1432.c +++ b/drivers/media/dvb-frontends/s5h1432.c @@ -337,7 +337,7 @@ struct dvb_frontend *s5h1432_attach(const struct s5h1432_config *config, printk(KERN_INFO " Enter s5h1432_attach(). attach success!\n"); /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct s5h1432_state), GFP_KERNEL); + state = kmalloc_obj(struct s5h1432_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c index 7e461ac159fc..41ac1d3a64dc 100644 --- a/drivers/media/dvb-frontends/s921.c +++ b/drivers/media/dvb-frontends/s921.c @@ -476,7 +476,7 @@ struct dvb_frontend *s921_attach(const struct s921_config *config, { /* allocate memory for the internal state */ struct s921_state *state = - kzalloc(sizeof(struct s921_state), GFP_KERNEL); + kzalloc_obj(struct s921_state); dprintk("\n"); if (!state) { diff --git a/drivers/media/dvb-frontends/si2165.c b/drivers/media/dvb-frontends/si2165.c index f87c9357cee3..4170696af9f0 100644 --- a/drivers/media/dvb-frontends/si2165.c +++ b/drivers/media/dvb-frontends/si2165.c @@ -1158,7 +1158,7 @@ static int si2165_probe(struct i2c_client *client) }; /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { ret = -ENOMEM; goto error; diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c index d6b6b8bc7d4e..c4bbcd127cac 100644 --- a/drivers/media/dvb-frontends/si2168.c +++ b/drivers/media/dvb-frontends/si2168.c @@ -681,7 +681,7 @@ static int si2168_probe(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/si21xx.c b/drivers/media/dvb-frontends/si21xx.c index 210ccd356e2b..e64ced2d6c21 100644 --- a/drivers/media/dvb-frontends/si21xx.c +++ b/drivers/media/dvb-frontends/si21xx.c @@ -902,7 +902,7 @@ struct dvb_frontend *si21xx_attach(const struct si21xx_config *config, dprintk("%s\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL); + state = kzalloc_obj(struct si21xx_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/sp2.c b/drivers/media/dvb-frontends/sp2.c index 75adf2a4589f..071c7371c699 100644 --- a/drivers/media/dvb-frontends/sp2.c +++ b/drivers/media/dvb-frontends/sp2.c @@ -371,7 +371,7 @@ static int sp2_probe(struct i2c_client *client) dev_dbg(&client->dev, "\n"); - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/sp887x.c b/drivers/media/dvb-frontends/sp887x.c index f59c0f96416b..13cb736760d3 100644 --- a/drivers/media/dvb-frontends/sp887x.c +++ b/drivers/media/dvb-frontends/sp887x.c @@ -568,7 +568,7 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, struct sp887x_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct sp887x_state), GFP_KERNEL); + state = kzalloc_obj(struct sp887x_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/stb0899_drv.c b/drivers/media/dvb-frontends/stb0899_drv.c index 35634f9a8ab5..4f0f31d248d6 100644 --- a/drivers/media/dvb-frontends/stb0899_drv.c +++ b/drivers/media/dvb-frontends/stb0899_drv.c @@ -1613,7 +1613,7 @@ struct dvb_frontend *stb0899_attach(struct stb0899_config *config, struct i2c_ad { struct stb0899_state *state = NULL; - state = kzalloc(sizeof (struct stb0899_state), GFP_KERNEL); + state = kzalloc_obj(struct stb0899_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/stb6000.c b/drivers/media/dvb-frontends/stb6000.c index d74e34677b92..c66d4ac17f85 100644 --- a/drivers/media/dvb-frontends/stb6000.c +++ b/drivers/media/dvb-frontends/stb6000.c @@ -218,7 +218,7 @@ struct dvb_frontend *stb6000_attach(struct dvb_frontend *fe, int addr, if (ret != 2) return NULL; - priv = kzalloc(sizeof(struct stb6000_priv), GFP_KERNEL); + priv = kzalloc_obj(struct stb6000_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/stb6100.c b/drivers/media/dvb-frontends/stb6100.c index c5818a15a0d7..ff7b0c780256 100644 --- a/drivers/media/dvb-frontends/stb6100.c +++ b/drivers/media/dvb-frontends/stb6100.c @@ -534,7 +534,7 @@ struct dvb_frontend *stb6100_attach(struct dvb_frontend *fe, { struct stb6100_state *state = NULL; - state = kzalloc(sizeof (struct stb6100_state), GFP_KERNEL); + state = kzalloc_obj(struct stb6100_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/stv0288.c b/drivers/media/dvb-frontends/stv0288.c index a5581bd60f9e..09992f6f09cc 100644 --- a/drivers/media/dvb-frontends/stv0288.c +++ b/drivers/media/dvb-frontends/stv0288.c @@ -557,7 +557,7 @@ struct dvb_frontend *stv0288_attach(const struct stv0288_config *config, int id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0288_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0288_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/stv0297.c b/drivers/media/dvb-frontends/stv0297.c index 9d4dbd99a5a7..dd0ecc050ad5 100644 --- a/drivers/media/dvb-frontends/stv0297.c +++ b/drivers/media/dvb-frontends/stv0297.c @@ -654,7 +654,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, struct stv0297_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0297_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0297_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/stv0299.c b/drivers/media/dvb-frontends/stv0299.c index ba4bb3685095..0d0bd076dd32 100644 --- a/drivers/media/dvb-frontends/stv0299.c +++ b/drivers/media/dvb-frontends/stv0299.c @@ -671,7 +671,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, int id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0299_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0299_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/stv0367.c b/drivers/media/dvb-frontends/stv0367.c index 72540ef4e5f8..592ada5c77fe 100644 --- a/drivers/media/dvb-frontends/stv0367.c +++ b/drivers/media/dvb-frontends/stv0367.c @@ -1698,10 +1698,10 @@ struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config, struct stv0367ter_state *ter_state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0367_state); if (state == NULL) goto error; - ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL); + ter_state = kzalloc_obj(struct stv0367ter_state); if (ter_state == NULL) goto error; @@ -2865,10 +2865,10 @@ struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config, struct stv0367cab_state *cab_state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0367_state); if (state == NULL) goto error; - cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL); + cab_state = kzalloc_obj(struct stv0367cab_state); if (cab_state == NULL) goto error; @@ -3274,13 +3274,13 @@ struct dvb_frontend *stv0367ddb_attach(const struct stv0367_config *config, struct stv0367cab_state *cab_state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0367_state); if (state == NULL) goto error; - ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL); + ter_state = kzalloc_obj(struct stv0367ter_state); if (ter_state == NULL) goto error; - cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL); + cab_state = kzalloc_obj(struct stv0367cab_state); if (cab_state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/stv0900_core.c b/drivers/media/dvb-frontends/stv0900_core.c index e7b9b9b11d7d..d15c55de2723 100644 --- a/drivers/media/dvb-frontends/stv0900_core.c +++ b/drivers/media/dvb-frontends/stv0900_core.c @@ -85,14 +85,13 @@ static struct stv0900_inode *append_internal(struct stv0900_internal *internal) struct stv0900_inode *new_node = stv0900_first_inode; if (new_node == NULL) { - new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL); + new_node = kmalloc_obj(struct stv0900_inode); stv0900_first_inode = new_node; } else { while (new_node->next_inode != NULL) new_node = new_node->next_inode; - new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), - GFP_KERNEL); + new_node->next_inode = kmalloc_obj(struct stv0900_inode); if (new_node->next_inode != NULL) new_node = new_node->next_inode; else @@ -1348,8 +1347,7 @@ static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe, dprintk("%s: Find Internal Structure!\n", __func__); return STV0900_NO_ERROR; } else { - state->internal = kmalloc(sizeof(struct stv0900_internal), - GFP_KERNEL); + state->internal = kmalloc_obj(struct stv0900_internal); if (state->internal == NULL) return STV0900_INVALID_HANDLE; temp_int = append_internal(state->internal); @@ -1903,7 +1901,7 @@ struct dvb_frontend *stv0900_attach(const struct stv0900_config *config, struct stv0900_init_params init_params; enum fe_stv0900_error err_stv0900; - state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL); + state = kzalloc_obj(struct stv0900_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/stv090x.c b/drivers/media/dvb-frontends/stv090x.c index f273efa330cf..657df713865e 100644 --- a/drivers/media/dvb-frontends/stv090x.c +++ b/drivers/media/dvb-frontends/stv090x.c @@ -85,7 +85,7 @@ static struct stv090x_dev *append_internal(struct stv090x_internal *internal) struct stv090x_dev *new_dev; struct stv090x_dev *temp_dev; - new_dev = kmalloc(sizeof(struct stv090x_dev), GFP_KERNEL); + new_dev = kmalloc_obj(struct stv090x_dev); if (new_dev != NULL) { new_dev->internal = internal; new_dev->next_dev = NULL; @@ -4906,7 +4906,7 @@ static int stv090x_setup_compound(struct stv090x_state *state) state->internal->num_used++; dprintk(FE_INFO, 1, "Found Internal Structure!"); } else { - state->internal = kmalloc(sizeof(*state->internal), GFP_KERNEL); + state->internal = kmalloc_obj(*state->internal); if (!state->internal) goto error; temp_int = append_internal(state->internal); @@ -5002,7 +5002,7 @@ static int stv090x_probe(struct i2c_client *client) struct stv090x_state *state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { ret = -ENOMEM; goto error; @@ -5050,7 +5050,7 @@ struct dvb_frontend *stv090x_attach(struct stv090x_config *config, int ret = 0; struct stv090x_state *state = NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) goto error; diff --git a/drivers/media/dvb-frontends/stv0910.c b/drivers/media/dvb-frontends/stv0910.c index 069dec75129c..b841f7e9c664 100644 --- a/drivers/media/dvb-frontends/stv0910.c +++ b/drivers/media/dvb-frontends/stv0910.c @@ -1766,7 +1766,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, struct stv *state; struct stv_base *base; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; @@ -1788,7 +1788,7 @@ struct dvb_frontend *stv0910_attach(struct i2c_adapter *i2c, base->count++; state->base = base; } else { - base = kzalloc(sizeof(*base), GFP_KERNEL); + base = kzalloc_obj(*base); if (!base) goto fail; base->i2c = i2c; diff --git a/drivers/media/dvb-frontends/stv6110.c b/drivers/media/dvb-frontends/stv6110.c index 1cf9c095dbff..87019aa57a16 100644 --- a/drivers/media/dvb-frontends/stv6110.c +++ b/drivers/media/dvb-frontends/stv6110.c @@ -408,7 +408,7 @@ struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe, if (ret != 1) return NULL; - priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL); + priv = kzalloc_obj(struct stv6110_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/stv6110x.c b/drivers/media/dvb-frontends/stv6110x.c index 33c8105da1c3..7506f39ead55 100644 --- a/drivers/media/dvb-frontends/stv6110x.c +++ b/drivers/media/dvb-frontends/stv6110x.c @@ -412,7 +412,7 @@ static int stv6110x_probe(struct i2c_client *client) struct stv6110x_state *stv6110x; - stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL); + stv6110x = kzalloc_obj(*stv6110x); if (!stv6110x) return -ENOMEM; @@ -448,7 +448,7 @@ const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, { struct stv6110x_state *stv6110x; - stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL); + stv6110x = kzalloc_obj(*stv6110x); if (!stv6110x) return NULL; diff --git a/drivers/media/dvb-frontends/stv6111.c b/drivers/media/dvb-frontends/stv6111.c index 0ac15273922d..876e254c6fbb 100644 --- a/drivers/media/dvb-frontends/stv6111.c +++ b/drivers/media/dvb-frontends/stv6111.c @@ -653,7 +653,7 @@ struct dvb_frontend *stv6111_attach(struct dvb_frontend *fe, int stat = -ENODEV; int gatestat = 0; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; state->adr = adr; diff --git a/drivers/media/dvb-frontends/tc90522.c b/drivers/media/dvb-frontends/tc90522.c index 1f8cbf45554a..f1343ba67b97 100644 --- a/drivers/media/dvb-frontends/tc90522.c +++ b/drivers/media/dvb-frontends/tc90522.c @@ -647,7 +647,7 @@ tc90522_master_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) for (i = 0; i < num; i++) if (msgs[i].flags & I2C_M_RD) rd_num++; - new_msgs = kmalloc_array(num + rd_num, sizeof(*new_msgs), GFP_KERNEL); + new_msgs = kmalloc_objs(*new_msgs, num + rd_num); if (!new_msgs) return -ENOMEM; @@ -788,7 +788,7 @@ static int tc90522_probe(struct i2c_client *client) struct i2c_adapter *adap; int ret; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; state->i2c_client = client; diff --git a/drivers/media/dvb-frontends/tda10021.c b/drivers/media/dvb-frontends/tda10021.c index 462e12ab6bd1..3c09b7e4a966 100644 --- a/drivers/media/dvb-frontends/tda10021.c +++ b/drivers/media/dvb-frontends/tda10021.c @@ -451,7 +451,7 @@ struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config, u8 id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10021_state), GFP_KERNEL); + state = kzalloc_obj(struct tda10021_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/tda10023.c b/drivers/media/dvb-frontends/tda10023.c index 4c2541ecd743..3284fc46e97f 100644 --- a/drivers/media/dvb-frontends/tda10023.c +++ b/drivers/media/dvb-frontends/tda10023.c @@ -511,7 +511,7 @@ struct dvb_frontend *tda10023_attach(const struct tda10023_config *config, struct tda10023_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10023_state), GFP_KERNEL); + state = kzalloc_obj(struct tda10023_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c index 1f87eb0dcf2a..c29eda634c85 100644 --- a/drivers/media/dvb-frontends/tda10048.c +++ b/drivers/media/dvb-frontends/tda10048.c @@ -1097,7 +1097,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, dprintk(1, "%s()\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10048_state), GFP_KERNEL); + state = kzalloc_obj(struct tda10048_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/tda1004x.c b/drivers/media/dvb-frontends/tda1004x.c index 6f306db6c615..7eefc8814243 100644 --- a/drivers/media/dvb-frontends/tda1004x.c +++ b/drivers/media/dvb-frontends/tda1004x.c @@ -1271,7 +1271,7 @@ struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, int id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL); + state = kzalloc_obj(struct tda1004x_state); if (!state) { printk(KERN_ERR "Can't allocate memory for tda10045 state\n"); return NULL; @@ -1341,7 +1341,7 @@ struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, int id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda1004x_state), GFP_KERNEL); + state = kzalloc_obj(struct tda1004x_state); if (!state) { printk(KERN_ERR "Can't allocate memory for tda10046 state\n"); return NULL; diff --git a/drivers/media/dvb-frontends/tda10071.c b/drivers/media/dvb-frontends/tda10071.c index e23794b821cd..6e6c2e5c427e 100644 --- a/drivers/media/dvb-frontends/tda10071.c +++ b/drivers/media/dvb-frontends/tda10071.c @@ -1156,7 +1156,7 @@ static int tda10071_probe(struct i2c_client *client) .val_bits = 8, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/tda10086.c b/drivers/media/dvb-frontends/tda10086.c index b449514ae585..d43d0eb73721 100644 --- a/drivers/media/dvb-frontends/tda10086.c +++ b/drivers/media/dvb-frontends/tda10086.c @@ -737,7 +737,7 @@ struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, dprintk ("%s\n", __func__); /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda10086_state), GFP_KERNEL); + state = kzalloc_obj(struct tda10086_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/tda18271c2dd.c b/drivers/media/dvb-frontends/tda18271c2dd.c index c11563853c07..25005e4359ad 100644 --- a/drivers/media/dvb-frontends/tda18271c2dd.c +++ b/drivers/media/dvb-frontends/tda18271c2dd.c @@ -1215,7 +1215,7 @@ struct dvb_frontend *tda18271c2dd_attach(struct dvb_frontend *fe, { struct tda_state *state; - state = kzalloc(sizeof(struct tda_state), GFP_KERNEL); + state = kzalloc_obj(struct tda_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/tda665x.c b/drivers/media/dvb-frontends/tda665x.c index 346be5011fb7..b2201ec14091 100644 --- a/drivers/media/dvb-frontends/tda665x.c +++ b/drivers/media/dvb-frontends/tda665x.c @@ -207,7 +207,7 @@ struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe, struct tda665x_state *state = NULL; struct dvb_tuner_info *info; - state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL); + state = kzalloc_obj(struct tda665x_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/tda8083.c b/drivers/media/dvb-frontends/tda8083.c index 44f53624557b..5a1b3599afa4 100644 --- a/drivers/media/dvb-frontends/tda8083.c +++ b/drivers/media/dvb-frontends/tda8083.c @@ -417,7 +417,7 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, struct tda8083_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL); + state = kzalloc_obj(struct tda8083_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/tda8261.c b/drivers/media/dvb-frontends/tda8261.c index 8b06f92745dc..55f898f6a6f7 100644 --- a/drivers/media/dvb-frontends/tda8261.c +++ b/drivers/media/dvb-frontends/tda8261.c @@ -168,7 +168,7 @@ struct dvb_frontend *tda8261_attach(struct dvb_frontend *fe, { struct tda8261_state *state = NULL; - if ((state = kzalloc(sizeof (struct tda8261_state), GFP_KERNEL)) == NULL) + if ((state = kzalloc_obj(struct tda8261_state)) == NULL) goto exit; state->config = config; diff --git a/drivers/media/dvb-frontends/tda826x.c b/drivers/media/dvb-frontends/tda826x.c index eafcf5f7da3d..9ee6bc4e6637 100644 --- a/drivers/media/dvb-frontends/tda826x.c +++ b/drivers/media/dvb-frontends/tda826x.c @@ -150,7 +150,7 @@ struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2 if (!(b1[1] & 0x80)) return NULL; - priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tda826x_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/ts2020.c b/drivers/media/dvb-frontends/ts2020.c index e25add6cc38e..8b6006635e49 100644 --- a/drivers/media/dvb-frontends/ts2020.c +++ b/drivers/media/dvb-frontends/ts2020.c @@ -566,7 +566,7 @@ static int ts2020_probe(struct i2c_client *client) } fe = pdata->fe; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/tua6100.c b/drivers/media/dvb-frontends/tua6100.c index 41dd9b6d3190..d7ca25afd6a6 100644 --- a/drivers/media/dvb-frontends/tua6100.c +++ b/drivers/media/dvb-frontends/tua6100.c @@ -175,7 +175,7 @@ struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2 if (ret != 2) return NULL; - priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tua6100_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/dvb-frontends/ves1820.c b/drivers/media/dvb-frontends/ves1820.c index ee5620e731e9..c9461c8c55c7 100644 --- a/drivers/media/dvb-frontends/ves1820.c +++ b/drivers/media/dvb-frontends/ves1820.c @@ -366,7 +366,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, struct ves1820_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct ves1820_state), GFP_KERNEL); + state = kzalloc_obj(struct ves1820_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/ves1x93.c b/drivers/media/dvb-frontends/ves1x93.c index c60e21d26b88..304d877f966a 100644 --- a/drivers/media/dvb-frontends/ves1x93.c +++ b/drivers/media/dvb-frontends/ves1x93.c @@ -450,7 +450,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, u8 identity; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct ves1x93_state), GFP_KERNEL); + state = kzalloc_obj(struct ves1x93_state); if (state == NULL) goto error; /* setup the state */ diff --git a/drivers/media/dvb-frontends/zd1301_demod.c b/drivers/media/dvb-frontends/zd1301_demod.c index e8b9e67a8717..13936a311e56 100644 --- a/drivers/media/dvb-frontends/zd1301_demod.c +++ b/drivers/media/dvb-frontends/zd1301_demod.c @@ -470,7 +470,7 @@ static int zd1301_demod_probe(struct platform_device *pdev) goto err; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/dvb-frontends/zl10036.c b/drivers/media/dvb-frontends/zl10036.c index 5ad987c6861b..88ca49242925 100644 --- a/drivers/media/dvb-frontends/zl10036.c +++ b/drivers/media/dvb-frontends/zl10036.c @@ -457,7 +457,7 @@ struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe, return NULL; } - state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL); + state = kzalloc_obj(struct zl10036_state); if (!state) return NULL; diff --git a/drivers/media/dvb-frontends/zl10039.c b/drivers/media/dvb-frontends/zl10039.c index a3e4d219400c..696831d7544b 100644 --- a/drivers/media/dvb-frontends/zl10039.c +++ b/drivers/media/dvb-frontends/zl10039.c @@ -254,7 +254,7 @@ struct dvb_frontend *zl10039_attach(struct dvb_frontend *fe, struct zl10039_state *state = NULL; dprintk("%s\n", __func__); - state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL); + state = kmalloc_obj(struct zl10039_state); if (state == NULL) goto error; diff --git a/drivers/media/dvb-frontends/zl10353.c b/drivers/media/dvb-frontends/zl10353.c index 8849d05475c2..6dd8d95651f6 100644 --- a/drivers/media/dvb-frontends/zl10353.c +++ b/drivers/media/dvb-frontends/zl10353.c @@ -598,7 +598,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config, int id; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL); + state = kzalloc_obj(struct zl10353_state); if (state == NULL) goto error; diff --git a/drivers/media/firewire/firedtv-fw.c b/drivers/media/firewire/firedtv-fw.c index 5f6e97a8d1c0..c348526a4c45 100644 --- a/drivers/media/firewire/firedtv-fw.c +++ b/drivers/media/firewire/firedtv-fw.c @@ -135,7 +135,7 @@ int fdtv_start_iso(struct firedtv *fdtv) struct fw_device *device = device_of(fdtv); int i, err; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -255,7 +255,7 @@ static int node_probe(struct fw_unit *unit, const struct ieee1394_device_id *id) char name[MAX_MODEL_NAME_LEN]; int name_len, i, err; - fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL); + fdtv = kzalloc_obj(*fdtv); if (!fdtv) return -ENOMEM; diff --git a/drivers/media/i2c/alvium-csi2.c b/drivers/media/i2c/alvium-csi2.c index 1f088acecf36..e6fa2f961177 100644 --- a/drivers/media/i2c/alvium-csi2.c +++ b/drivers/media/i2c/alvium-csi2.c @@ -1094,7 +1094,7 @@ static int alvium_setup_mipi_fmt(struct alvium_dev *alvium) /* init alvium_csi2_fmt array */ alvium->alvium_csi2_fmt_n = sz; alvium->alvium_csi2_fmt = - kmalloc_array(sz, sizeof(struct alvium_pixfmt), GFP_KERNEL); + kmalloc_objs(struct alvium_pixfmt, sz); if (!alvium->alvium_csi2_fmt) return -ENOMEM; diff --git a/drivers/media/i2c/cs3308.c b/drivers/media/i2c/cs3308.c index 078e0066ce4b..3f2f993e16a6 100644 --- a/drivers/media/i2c/cs3308.c +++ b/drivers/media/i2c/cs3308.c @@ -79,7 +79,7 @@ static int cs3308_probe(struct i2c_client *client) v4l_info(client, "chip found @ 0x%x (%s)\n", client->addr << 1, client->adapter->name); - sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); + sd = kzalloc_obj(struct v4l2_subdev); if (sd == NULL) return -ENOMEM; diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c index 3156f6d6c6de..e133127397f4 100644 --- a/drivers/media/i2c/ds90ub960.c +++ b/drivers/media/i2c/ds90ub960.c @@ -1379,7 +1379,7 @@ static int ub960_parse_dt_txport(struct ub960_data *priv, struct ub960_txport *txport; int ret; - txport = kzalloc(sizeof(*txport), GFP_KERNEL); + txport = kzalloc_obj(*txport); if (!txport) return -ENOMEM; @@ -4573,7 +4573,7 @@ static int ub960_parse_dt_rxport(struct ub960_data *priv, unsigned int nport, struct ub960_rxport *rxport; int ret; - rxport = kzalloc(sizeof(*rxport), GFP_KERNEL); + rxport = kzalloc_obj(*rxport); if (!rxport) return -ENOMEM; diff --git a/drivers/media/i2c/tda1997x.c b/drivers/media/i2c/tda1997x.c index 3532766cd795..5c6dda5338f5 100644 --- a/drivers/media/i2c/tda1997x.c +++ b/drivers/media/i2c/tda1997x.c @@ -2538,7 +2538,7 @@ static int tda1997x_probe(struct i2c_client *client) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -EIO; - state = kzalloc(sizeof(struct tda1997x_state), GFP_KERNEL); + state = kzalloc_obj(struct tda1997x_state); if (!state) return -ENOMEM; diff --git a/drivers/media/i2c/video-i2c.c b/drivers/media/i2c/video-i2c.c index 1eee2d4f5b40..fef3993f4e2d 100644 --- a/drivers/media/i2c/video-i2c.c +++ b/drivers/media/i2c/video-i2c.c @@ -750,7 +750,7 @@ static int video_i2c_probe(struct i2c_client *client) struct vb2_queue *queue; int ret = -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/media/mc/mc-dev-allocator.c b/drivers/media/mc/mc-dev-allocator.c index ae17887dec59..b700ea73517e 100644 --- a/drivers/media/mc/mc-dev-allocator.c +++ b/drivers/media/mc/mc-dev-allocator.c @@ -81,7 +81,7 @@ static struct media_device *__media_device_get(struct device *dev, return &mdi->mdev; } - mdi = kzalloc(sizeof(*mdi), GFP_KERNEL); + mdi = kzalloc_obj(*mdi); if (!mdi) return NULL; diff --git a/drivers/media/mc/mc-device.c b/drivers/media/mc/mc-device.c index 5a4465b290f0..f8ea7cfe10b2 100644 --- a/drivers/media/mc/mc-device.c +++ b/drivers/media/mc/mc-device.c @@ -737,7 +737,7 @@ int __must_check __media_device_register(struct media_device *mdev, struct media_devnode *devnode; int ret; - devnode = kzalloc(sizeof(*devnode), GFP_KERNEL); + devnode = kzalloc_obj(*devnode); if (!devnode) return -ENOMEM; diff --git a/drivers/media/mc/mc-entity.c b/drivers/media/mc/mc-entity.c index 9519a537bfa2..3fa0bc687851 100644 --- a/drivers/media/mc/mc-entity.c +++ b/drivers/media/mc/mc-entity.c @@ -587,7 +587,7 @@ static int media_pipeline_add_pad(struct media_pipeline *pipe, } } - ppad = kzalloc(sizeof(*ppad), GFP_KERNEL); + ppad = kzalloc_obj(*ppad); if (!ppad) return -ENOMEM; @@ -977,7 +977,7 @@ __must_check int media_pipeline_alloc_start(struct media_pad *pad) */ pipe = media_pad_pipeline(pad); if (!pipe) { - new_pipe = kzalloc(sizeof(*new_pipe), GFP_KERNEL); + new_pipe = kzalloc_obj(*new_pipe); if (!new_pipe) { ret = -ENOMEM; goto out; @@ -1061,7 +1061,7 @@ static struct media_link *media_add_link(struct list_head *head) { struct media_link *link; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (link == NULL) return NULL; @@ -1547,7 +1547,7 @@ struct media_intf_devnode *media_devnode_create(struct media_device *mdev, { struct media_intf_devnode *devnode; - devnode = kzalloc(sizeof(*devnode), GFP_KERNEL); + devnode = kzalloc_obj(*devnode); if (!devnode) return NULL; diff --git a/drivers/media/mc/mc-request.c b/drivers/media/mc/mc-request.c index 8ad10c72f9db..c7c7d4a86c6b 100644 --- a/drivers/media/mc/mc-request.c +++ b/drivers/media/mc/mc-request.c @@ -293,7 +293,7 @@ int media_request_alloc(struct media_device *mdev, int *alloc_fd) if (mdev->ops->req_alloc) req = mdev->ops->req_alloc(mdev); else - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/media/mmc/siano/smssdio.c b/drivers/media/mmc/siano/smssdio.c index 8199077faf36..41dcab816216 100644 --- a/drivers/media/mmc/siano/smssdio.c +++ b/drivers/media/mmc/siano/smssdio.c @@ -244,7 +244,7 @@ static int smssdio_probe(struct sdio_func *func, board_id = id->driver_data; - smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL); + smsdev = kzalloc_obj(struct smssdio_device); if (!smsdev) return -ENOMEM; diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index 17e4529e537a..663469208271 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -3216,7 +3216,7 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) if (bttv_num == BTTV_MAX) return -ENOMEM; pr_info("Bt8xx card found (%d)\n", bttv_num); - bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL); + bttvs[bttv_num] = btv = kzalloc_obj(*btv); if (btv == NULL) { pr_err("out of memory\n"); return -ENOMEM; diff --git a/drivers/media/pci/bt8xx/bttv-gpio.c b/drivers/media/pci/bt8xx/bttv-gpio.c index 59a6f160aac7..b79daa2d440f 100644 --- a/drivers/media/pci/bt8xx/bttv-gpio.c +++ b/drivers/media/pci/bt8xx/bttv-gpio.c @@ -73,7 +73,7 @@ int bttv_sub_add_device(struct bttv_core *core, char *name) struct bttv_sub_device *sub; int err; - sub = kzalloc(sizeof(*sub),GFP_KERNEL); + sub = kzalloc_obj(*sub); if (NULL == sub) return -ENOMEM; diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 84aa269248fd..373b6c6817d7 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -416,7 +416,7 @@ int bttv_input_init(struct bttv *btv) if (!btv->has_remote) return -ENODEV; - ir = kzalloc(sizeof(*ir),GFP_KERNEL); + ir = kzalloc_obj(*ir); rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!ir || !rc) goto err_out_free; diff --git a/drivers/media/pci/bt8xx/dst_ca.c b/drivers/media/pci/bt8xx/dst_ca.c index a9cc6e7a57f9..6da75c6ed77b 100644 --- a/drivers/media/pci/bt8xx/dst_ca.c +++ b/drivers/media/pci/bt8xx/dst_ca.c @@ -454,7 +454,7 @@ static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer; int result = 0; - hw_buffer = kmalloc(sizeof(*hw_buffer), GFP_KERNEL); + hw_buffer = kmalloc_obj(*hw_buffer); if (!hw_buffer) return -ENOMEM; dprintk(verbose, DST_CA_DEBUG, 1, " "); @@ -535,9 +535,9 @@ static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioct mutex_lock(&dst_ca_mutex); dvbdev = file->private_data; state = dvbdev->priv; - p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL); - p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL); - p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL); + p_ca_message = kmalloc_obj(struct ca_msg); + p_ca_slot_info = kmalloc_obj(struct ca_slot_info); + p_ca_caps = kmalloc_obj(struct ca_caps); if (!p_ca_message || !p_ca_slot_info || !p_ca_caps) { result = -ENOMEM; goto free_mem_and_exit; diff --git a/drivers/media/pci/bt8xx/dvb-bt8xx.c b/drivers/media/pci/bt8xx/dvb-bt8xx.c index f0fbb468aea2..935503acab7d 100644 --- a/drivers/media/pci/bt8xx/dvb-bt8xx.c +++ b/drivers/media/pci/bt8xx/dvb-bt8xx.c @@ -657,7 +657,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) case BTTV_BOARD_TWINHAN_DST: /* DST is not a frontend driver !!! */ - state = kmalloc(sizeof (struct dst_state), GFP_KERNEL); + state = kmalloc_obj(struct dst_state); if (!state) { pr_err("No memory\n"); break; @@ -809,7 +809,7 @@ static int dvb_bt8xx_probe(struct bttv_sub_device *sub) struct pci_dev* bttv_pci_dev; int ret; - if (!(card = kzalloc(sizeof(struct dvb_bt8xx_card), GFP_KERNEL))) + if (!(card = kzalloc_obj(struct dvb_bt8xx_card))) return -ENOMEM; mutex_init(&card->lock); diff --git a/drivers/media/pci/cobalt/cobalt-alsa-main.c b/drivers/media/pci/cobalt/cobalt-alsa-main.c index c57f87a68269..7bb7f13c70c0 100644 --- a/drivers/media/pci/cobalt/cobalt-alsa-main.c +++ b/drivers/media/pci/cobalt/cobalt-alsa-main.c @@ -45,7 +45,7 @@ static int snd_cobalt_card_create(struct cobalt_stream *s, struct snd_card *sc, struct snd_cobalt_card **cobsc) { - *cobsc = kzalloc(sizeof(struct snd_cobalt_card), GFP_KERNEL); + *cobsc = kzalloc_obj(struct snd_cobalt_card); if (*cobsc == NULL) return -ENOMEM; diff --git a/drivers/media/pci/cobalt/cobalt-driver.c b/drivers/media/pci/cobalt/cobalt-driver.c index b7695705fdee..9b9f69ff4016 100644 --- a/drivers/media/pci/cobalt/cobalt-driver.c +++ b/drivers/media/pci/cobalt/cobalt-driver.c @@ -663,7 +663,7 @@ static int cobalt_probe(struct pci_dev *pci_dev, /* FIXME - module parameter arrays constrain max instances */ i = atomic_inc_return(&cobalt_instance) - 1; - cobalt = kzalloc(sizeof(struct cobalt), GFP_KERNEL); + cobalt = kzalloc_obj(struct cobalt); if (cobalt == NULL) return -ENOMEM; cobalt->pci_dev = pci_dev; diff --git a/drivers/media/pci/cx18/cx18-alsa-main.c b/drivers/media/pci/cx18/cx18-alsa-main.c index 9dc361886284..b77f5375f3ff 100644 --- a/drivers/media/pci/cx18/cx18-alsa-main.c +++ b/drivers/media/pci/cx18/cx18-alsa-main.c @@ -77,7 +77,7 @@ static int snd_cx18_card_create(struct v4l2_device *v4l2_dev, struct snd_card *sc, struct snd_cx18_card **cxsc) { - *cxsc = kzalloc(sizeof(struct snd_cx18_card), GFP_KERNEL); + *cxsc = kzalloc_obj(struct snd_cx18_card); if (*cxsc == NULL) return -ENOMEM; diff --git a/drivers/media/pci/cx18/cx18-driver.c b/drivers/media/pci/cx18/cx18-driver.c index 74c59a94b2b0..f778f79b921d 100644 --- a/drivers/media/pci/cx18/cx18-driver.c +++ b/drivers/media/pci/cx18/cx18-driver.c @@ -314,7 +314,7 @@ void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) memset(tv, 0, sizeof(*tv)); - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) return; @@ -899,7 +899,7 @@ static int cx18_probe(struct pci_dev *pci_dev, return -ENOMEM; } - cx = kzalloc(sizeof(*cx), GFP_KERNEL); + cx = kzalloc_obj(*cx); if (!cx) return -ENOMEM; diff --git a/drivers/media/pci/cx18/cx18-fileops.c b/drivers/media/pci/cx18/cx18-fileops.c index 4944033dbb20..445afcd3092b 100644 --- a/drivers/media/pci/cx18/cx18-fileops.c +++ b/drivers/media/pci/cx18/cx18-fileops.c @@ -732,7 +732,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) CX18_DEBUG_FILE("open %s\n", s->name); /* Allocate memory */ - item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL); + item = kzalloc_obj(struct cx18_open_id); if (NULL == item) { CX18_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; diff --git a/drivers/media/pci/cx18/cx18-queue.c b/drivers/media/pci/cx18/cx18-queue.c index eeb5513b1d52..04d6828f0259 100644 --- a/drivers/media/pci/cx18/cx18-queue.c +++ b/drivers/media/pci/cx18/cx18-queue.c @@ -361,12 +361,11 @@ int cx18_stream_alloc(struct cx18_stream *s) struct cx18_buffer *buf; /* 1 MDL per buffer to handle the worst & also default case */ - mdl = kzalloc(sizeof(struct cx18_mdl), GFP_KERNEL|__GFP_NOWARN); + mdl = kzalloc_obj(struct cx18_mdl, GFP_KERNEL | __GFP_NOWARN); if (mdl == NULL) break; - buf = kzalloc(sizeof(struct cx18_buffer), - GFP_KERNEL|__GFP_NOWARN); + buf = kzalloc_obj(struct cx18_buffer, GFP_KERNEL | __GFP_NOWARN); if (buf == NULL) { kfree(mdl); break; diff --git a/drivers/media/pci/cx18/cx18-streams.c b/drivers/media/pci/cx18/cx18-streams.c index 48203ba16387..5da1a5d69eed 100644 --- a/drivers/media/pci/cx18/cx18-streams.c +++ b/drivers/media/pci/cx18/cx18-streams.c @@ -343,7 +343,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type) /* Allocate the cx18_dvb struct only for the TS on cards with DTV */ if (type == CX18_ENC_STREAM_TYPE_TS) { if (cx->card->hw_all & CX18_HW_DVB) { - s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL); + s->dvb = kzalloc_obj(struct cx18_dvb); if (s->dvb == NULL) { CX18_ERR("Couldn't allocate cx18_dvb structure for %s\n", s->name); diff --git a/drivers/media/pci/cx23885/altera-ci.c b/drivers/media/pci/cx23885/altera-ci.c index 0dc348215b72..20a3b6c51b35 100644 --- a/drivers/media/pci/cx23885/altera-ci.c +++ b/drivers/media/pci/cx23885/altera-ci.c @@ -224,14 +224,14 @@ static struct fpga_inode *append_internal(struct fpga_internal *internal) struct fpga_inode *new_node = fpga_first_inode; if (new_node == NULL) { - new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL); + new_node = kmalloc_obj(struct fpga_inode); fpga_first_inode = new_node; } else { while (new_node->next_inode != NULL) new_node = new_node->next_inode; new_node->next_inode = - kmalloc(sizeof(struct fpga_inode), GFP_KERNEL); + kmalloc_obj(struct fpga_inode); if (new_node->next_inode != NULL) new_node = new_node->next_inode; else @@ -634,7 +634,7 @@ static int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr) struct fpga_internal *inter = NULL; int ret = 0; - pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL); + pid_filt = kzalloc_obj(struct netup_hw_pid_filter); ci_dbg_print("%s\n", __func__); @@ -648,7 +648,7 @@ static int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr) (inter->filts_used)++; ci_dbg_print("%s: Find Internal Structure!\n", __func__); } else { - inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL); + inter = kzalloc_obj(struct fpga_internal); if (!inter) { ret = -ENOMEM; goto err; @@ -706,7 +706,7 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr) int ret = 0; u8 store = 0; - state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL); + state = kzalloc_obj(struct altera_ci_state); ci_dbg_print("%s\n", __func__); @@ -721,7 +721,7 @@ int altera_ci_init(struct altera_ci_config *config, int ci_nr) inter->fpga_rw = config->fpga_rw; ci_dbg_print("%s: Find Internal Structure!\n", __func__); } else { - inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL); + inter = kzalloc_obj(struct fpga_internal); if (!inter) { ret = -ENOMEM; goto err; diff --git a/drivers/media/pci/cx23885/cimax2.c b/drivers/media/pci/cx23885/cimax2.c index 06e41f92092d..154918984534 100644 --- a/drivers/media/pci/cx23885/cimax2.c +++ b/drivers/media/pci/cx23885/cimax2.c @@ -451,7 +451,7 @@ int netup_ci_init(struct cx23885_tsport *port) int ret; ci_dbg_print("%s\n", __func__); - state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL); + state = kzalloc_obj(struct netup_ci_state); if (!state) { ci_dbg_print("%s: Unable create CI structure!\n", __func__); ret = -ENOMEM; diff --git a/drivers/media/pci/cx23885/cx23885-alsa.c b/drivers/media/pci/cx23885/cx23885-alsa.c index 717fc6c9ef21..29f6df0e6de4 100644 --- a/drivers/media/pci/cx23885/cx23885-alsa.c +++ b/drivers/media/pci/cx23885/cx23885-alsa.c @@ -374,7 +374,7 @@ static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, BUG_ON(!chip->dma_size); BUG_ON(chip->num_periods & (chip->num_periods-1)); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (NULL == buf) return -ENOMEM; diff --git a/drivers/media/pci/cx23885/cx23885-core.c b/drivers/media/pci/cx23885/cx23885-core.c index a39f445ce22a..0892a5fd137d 100644 --- a/drivers/media/pci/cx23885/cx23885-core.c +++ b/drivers/media/pci/cx23885/cx23885-core.c @@ -2124,7 +2124,7 @@ static int cx23885_initdev(struct pci_dev *pci_dev, struct v4l2_ctrl_handler *hdl; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (NULL == dev) return -ENOMEM; diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index d2e84c6457e0..ffbbeca8a8e5 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -327,7 +327,7 @@ int cx23885_input_init(struct cx23885_dev *dev) } /* cx23885 board instance kernel IR state */ - kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL); + kernel_ir = kzalloc_obj(struct cx23885_kernel_ir); if (kernel_ir == NULL) return -ENOMEM; diff --git a/drivers/media/pci/cx23885/cx23888-ir.c b/drivers/media/pci/cx23885/cx23888-ir.c index 222d04421468..087beb82a1f1 100644 --- a/drivers/media/pci/cx23885/cx23888-ir.c +++ b/drivers/media/pci/cx23885/cx23888-ir.c @@ -1142,7 +1142,7 @@ int cx23888_ir_probe(struct cx23885_dev *dev) struct v4l2_subdev_ir_parameters default_params; int ret; - state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL); + state = kzalloc_obj(struct cx23888_ir_state); if (state == NULL) return -ENOMEM; diff --git a/drivers/media/pci/cx25821/cx25821-alsa.c b/drivers/media/pci/cx25821/cx25821-alsa.c index f463365163b7..3f73391f9098 100644 --- a/drivers/media/pci/cx25821/cx25821-alsa.c +++ b/drivers/media/pci/cx25821/cx25821-alsa.c @@ -512,7 +512,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream, BUG_ON(!chip->dma_size); BUG_ON(chip->num_periods & (chip->num_periods - 1)); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (NULL == buf) return -ENOMEM; diff --git a/drivers/media/pci/cx25821/cx25821-core.c b/drivers/media/pci/cx25821/cx25821-core.c index a7336be44474..5acb1dc00ae8 100644 --- a/drivers/media/pci/cx25821/cx25821-core.c +++ b/drivers/media/pci/cx25821/cx25821-core.c @@ -1266,7 +1266,7 @@ static int cx25821_initdev(struct pci_dev *pci_dev, struct cx25821_dev *dev; int err = 0; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (NULL == dev) return -ENOMEM; diff --git a/drivers/media/pci/cx88/cx88-alsa.c b/drivers/media/pci/cx88/cx88-alsa.c index 4e574d8390b4..dce041a5e47a 100644 --- a/drivers/media/pci/cx88/cx88-alsa.c +++ b/drivers/media/pci/cx88/cx88-alsa.c @@ -465,7 +465,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream *substream, WARN_ON(!chip->dma_size); WARN_ON(chip->num_periods & (chip->num_periods - 1)); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return -ENOMEM; diff --git a/drivers/media/pci/cx88/cx88-cards.c b/drivers/media/pci/cx88/cx88-cards.c index f01e48c23f8e..7567c2388d95 100644 --- a/drivers/media/pci/cx88/cx88-cards.c +++ b/drivers/media/pci/cx88/cx88-cards.c @@ -3700,7 +3700,7 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr) struct cx88_core *core; int i; - core = kzalloc(sizeof(*core), GFP_KERNEL); + core = kzalloc_obj(*core); if (!core) return NULL; diff --git a/drivers/media/pci/cx88/cx88-dsp.c b/drivers/media/pci/cx88/cx88-dsp.c index e378f3b215c7..958e4637fa4a 100644 --- a/drivers/media/pci/cx88/cx88-dsp.c +++ b/drivers/media/pci/cx88/cx88-dsp.c @@ -252,7 +252,7 @@ static s16 *read_rds_samples(struct cx88_core *core, u32 *N) current_address, current_address - srch->fifo_start, sample_count, cx_read(MO_AUD_INTSTAT)); - samples = kmalloc_array(sample_count, sizeof(*samples), GFP_KERNEL); + samples = kmalloc_objs(*samples, sample_count); if (!samples) return NULL; diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index b9f2c14d62b4..e958eecb29c5 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -267,7 +267,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) * used with a full-code IR table */ - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); dev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!ir || !dev) goto err_out_free; diff --git a/drivers/media/pci/cx88/cx88-mpeg.c b/drivers/media/pci/cx88/cx88-mpeg.c index 2c1d5137ac47..676160e9554d 100644 --- a/drivers/media/pci/cx88/cx88-mpeg.c +++ b/drivers/media/pci/cx88/cx88-mpeg.c @@ -619,7 +619,7 @@ int cx8802_register_driver(struct cx8802_driver *drv) dev->core->boardnr); /* Bring up a new struct for each driver instance */ - driver = kzalloc(sizeof(*drv), GFP_KERNEL); + driver = kzalloc_obj(*drv); if (!driver) { err = -ENOMEM; goto out; @@ -715,7 +715,7 @@ static int cx8802_probe(struct pci_dev *pci_dev, goto fail_core; err = -ENOMEM; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto fail_core; dev->pci = pci_dev; diff --git a/drivers/media/pci/cx88/cx88-video.c b/drivers/media/pci/cx88/cx88-video.c index 0c87327689d3..c78b156c5cda 100644 --- a/drivers/media/pci/cx88/cx88-video.c +++ b/drivers/media/pci/cx88/cx88-video.c @@ -1261,7 +1261,7 @@ static int cx8800_initdev(struct pci_dev *pci_dev, int err; int i; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/pci/cx88/cx88-vp3054-i2c.c b/drivers/media/pci/cx88/cx88-vp3054-i2c.c index ac7f76dc5e21..dbec12588a39 100644 --- a/drivers/media/pci/cx88/cx88-vp3054-i2c.c +++ b/drivers/media/pci/cx88/cx88-vp3054-i2c.c @@ -97,7 +97,7 @@ int vp3054_i2c_probe(struct cx8802_dev *dev) if (core->boardnr != CX88_BOARD_DNTV_LIVE_DVB_T_PRO) return 0; - vp3054_i2c = kzalloc(sizeof(*vp3054_i2c), GFP_KERNEL); + vp3054_i2c = kzalloc_obj(*vp3054_i2c); if (!vp3054_i2c) return -ENOMEM; dev->vp3054 = vp3054_i2c; diff --git a/drivers/media/pci/ddbridge/ddbridge-ci.c b/drivers/media/pci/ddbridge/ddbridge-ci.c index ee20813c33ff..e1d1f277fa9d 100644 --- a/drivers/media/pci/ddbridge/ddbridge-ci.c +++ b/drivers/media/pci/ddbridge/ddbridge-ci.c @@ -155,7 +155,7 @@ static void ci_attach(struct ddb_port *port) { struct ddb_ci *ci; - ci = kzalloc(sizeof(*ci), GFP_KERNEL); + ci = kzalloc_obj(*ci); if (!ci) return; memcpy(&ci->en, &en_templ, sizeof(en_templ)); @@ -288,7 +288,7 @@ static void ci_xo2_attach(struct ddb_port *port) { struct ddb_ci *ci; - ci = kzalloc(sizeof(*ci), GFP_KERNEL); + ci = kzalloc_obj(*ci); if (!ci) return; memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ)); diff --git a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c index 520ebd16b0c4..d2e876a2ca71 100644 --- a/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c +++ b/drivers/media/pci/ddbridge/ddbridge-dummy-fe.c @@ -100,7 +100,7 @@ struct dvb_frontend *ddbridge_dummy_fe_qam_attach(void) struct ddbridge_dummy_fe_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct ddbridge_dummy_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct ddbridge_dummy_fe_state); if (!state) return NULL; diff --git a/drivers/media/pci/dm1105/dm1105.c b/drivers/media/pci/dm1105/dm1105.c index 9e9c7c071acc..de05d8b0f9dc 100644 --- a/drivers/media/pci/dm1105/dm1105.c +++ b/drivers/media/pci/dm1105/dm1105.c @@ -976,7 +976,7 @@ static int dm1105_probe(struct pci_dev *pdev, if (dm1105_devcount >= ARRAY_SIZE(card)) return -ENODEV; - dev = kzalloc(sizeof(struct dm1105_dev), GFP_KERNEL); + dev = kzalloc_obj(struct dm1105_dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c index b2b710094914..32cc95a766b7 100644 --- a/drivers/media/pci/intel/ipu-bridge.c +++ b/drivers/media/pci/intel/ipu-bridge.c @@ -638,7 +638,7 @@ int ipu_bridge_instantiate_vcm(struct device *sensor) return 0; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { fwnode_handle_put(vcm_fwnode); return -ENOMEM; @@ -851,7 +851,7 @@ int ipu_bridge_init(struct device *dev, return dev_err_probe(dev, -EPROBE_DEFER, "waiting for IVSC to become ready\n"); - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return -ENOMEM; diff --git a/drivers/media/pci/intel/ipu6/ipu6-bus.c b/drivers/media/pci/intel/ipu6/ipu6-bus.c index 5cee2748983b..173616381f62 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-bus.c +++ b/drivers/media/pci/intel/ipu6/ipu6-bus.c @@ -90,7 +90,7 @@ ipu6_bus_initialize_device(struct pci_dev *pdev, struct device *parent, struct ipu6_device *isp = pci_get_drvdata(pdev); int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c index 103386c4f6ae..e0ecb4c8b081 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c @@ -552,7 +552,7 @@ int ipu6_buttress_map_fw_image(struct ipu6_bus_device *sys, n_pages = PFN_UP(fw->size); - pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, n_pages); if (!pages) return -ENOMEM; diff --git a/drivers/media/pci/intel/ipu6/ipu6-dma.c b/drivers/media/pci/intel/ipu6/ipu6-dma.c index 7296373d36b0..fdcdb15b073c 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-dma.c +++ b/drivers/media/pci/intel/ipu6/ipu6-dma.c @@ -164,7 +164,7 @@ void *ipu6_dma_alloc(struct ipu6_bus_device *sys, size_t size, unsigned int i; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return NULL; diff --git a/drivers/media/pci/intel/ipu6/ipu6-fw-com.c b/drivers/media/pci/intel/ipu6/ipu6-fw-com.c index 40d8ce138a67..51567c5fc139 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-fw-com.c +++ b/drivers/media/pci/intel/ipu6/ipu6-fw-com.c @@ -170,7 +170,7 @@ void *ipu6_fw_com_prepare(struct ipu6_fw_com_cfg *cfg, if (!cfg || !cfg->cell_start || !cfg->cell_ready) return NULL; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; ctx->dmem_addr = base + cfg->dmem_addr + REGMEM_OFFSET; diff --git a/drivers/media/pci/intel/ipu6/ipu6-mmu.c b/drivers/media/pci/intel/ipu6/ipu6-mmu.c index 85cc6d5b4dd1..0e6dca36b6ba 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-mmu.c +++ b/drivers/media/pci/intel/ipu6/ipu6-mmu.c @@ -549,7 +549,7 @@ static struct ipu6_mmu_info *ipu6_mmu_alloc(struct ipu6_device *isp) struct ipu6_mmu_info *mmu_info; int ret; - mmu_info = kzalloc(sizeof(*mmu_info), GFP_KERNEL); + mmu_info = kzalloc_obj(*mmu_info); if (!mmu_info) return NULL; @@ -613,7 +613,7 @@ static struct ipu6_dma_mapping *alloc_dma_mapping(struct ipu6_device *isp) { struct ipu6_dma_mapping *dmap; - dmap = kzalloc(sizeof(*dmap), GFP_KERNEL); + dmap = kzalloc_obj(*dmap); if (!dmap) return NULL; diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c index 24238f8311a6..34f67f4f1bb5 100644 --- a/drivers/media/pci/intel/ipu6/ipu6.c +++ b/drivers/media/pci/intel/ipu6/ipu6.c @@ -381,7 +381,7 @@ ipu6_isys_init(struct pci_dev *pdev, struct device *parent, return ERR_PTR(ret); } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return ERR_PTR(-ENOMEM); @@ -425,7 +425,7 @@ ipu6_psys_init(struct pci_dev *pdev, struct device *parent, struct ipu6_psys_pdata *pdata; int ret; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/pci/ivtv/ivtv-alsa-main.c b/drivers/media/pci/ivtv/ivtv-alsa-main.c index 9e13a7128a53..59573debd19e 100644 --- a/drivers/media/pci/ivtv/ivtv-alsa-main.c +++ b/drivers/media/pci/ivtv/ivtv-alsa-main.c @@ -74,7 +74,7 @@ static int snd_ivtv_card_create(struct v4l2_device *v4l2_dev, struct snd_card *sc, struct snd_ivtv_card **itvsc) { - *itvsc = kzalloc(sizeof(struct snd_ivtv_card), GFP_KERNEL); + *itvsc = kzalloc_obj(struct snd_ivtv_card); if (*itvsc == NULL) return -ENOMEM; diff --git a/drivers/media/pci/ivtv/ivtv-driver.c b/drivers/media/pci/ivtv/ivtv-driver.c index 459eb6cc370c..e0091a8e5c88 100644 --- a/drivers/media/pci/ivtv/ivtv-driver.c +++ b/drivers/media/pci/ivtv/ivtv-driver.c @@ -953,7 +953,7 @@ static int ivtv_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) int vbi_buf_size; struct ivtv *itv; - itv = kzalloc(sizeof(struct ivtv), GFP_KERNEL); + itv = kzalloc_obj(struct ivtv); if (itv == NULL) return -ENOMEM; itv->pdev = pdev; diff --git a/drivers/media/pci/ivtv/ivtv-fileops.c b/drivers/media/pci/ivtv/ivtv-fileops.c index ef9ec062c03a..e7fed9698758 100644 --- a/drivers/media/pci/ivtv/ivtv-fileops.c +++ b/drivers/media/pci/ivtv/ivtv-fileops.c @@ -990,7 +990,7 @@ static int ivtv_open(struct file *filp) } /* Allocate memory */ - item = kzalloc(sizeof(struct ivtv_open_id), GFP_KERNEL); + item = kzalloc_obj(struct ivtv_open_id); if (NULL == item) { IVTV_DEBUG_WARN("nomem on v4l2 open\n"); return -ENOMEM; diff --git a/drivers/media/pci/ivtv/ivtv-queue.c b/drivers/media/pci/ivtv/ivtv-queue.c index f7d2d159d800..9e339ef0c82d 100644 --- a/drivers/media/pci/ivtv/ivtv-queue.c +++ b/drivers/media/pci/ivtv/ivtv-queue.c @@ -207,8 +207,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s) } s->sg_processing_size = 0; - s->sg_dma = kzalloc(sizeof(struct ivtv_sg_element), - GFP_KERNEL|__GFP_NOWARN); + s->sg_dma = kzalloc_obj(struct ivtv_sg_element, + GFP_KERNEL | __GFP_NOWARN); if (s->sg_dma == NULL) { IVTV_ERR("Could not allocate sg_dma for %s stream\n", s->name); kfree(s->sg_pending); @@ -226,8 +226,8 @@ int ivtv_stream_alloc(struct ivtv_stream *s) /* allocate stream buffers. Initially all buffers are in q_free. */ for (i = 0; i < s->buffers; i++) { - struct ivtv_buffer *buf = kzalloc(sizeof(struct ivtv_buffer), - GFP_KERNEL|__GFP_NOWARN); + struct ivtv_buffer *buf = kzalloc_obj(struct ivtv_buffer, + GFP_KERNEL | __GFP_NOWARN); if (buf == NULL) break; diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c index 90c584cf97c2..4f55b44738c9 100644 --- a/drivers/media/pci/ivtv/ivtvfb.c +++ b/drivers/media/pci/ivtv/ivtvfb.c @@ -1176,8 +1176,7 @@ static int ivtvfb_init_card(struct ivtv *itv) return -EBUSY; } - itv->osd_info = kzalloc(sizeof(struct osd_info), - GFP_KERNEL|__GFP_NOWARN); + itv->osd_info = kzalloc_obj(struct osd_info, GFP_KERNEL | __GFP_NOWARN); if (itv->osd_info == NULL) { IVTVFB_ERR("Failed to allocate memory for osd_info\n"); return -ENOMEM; diff --git a/drivers/media/pci/mantis/hopper_cards.c b/drivers/media/pci/mantis/hopper_cards.c index b85aef4e2b24..050068308c10 100644 --- a/drivers/media/pci/mantis/hopper_cards.c +++ b/drivers/media/pci/mantis/hopper_cards.c @@ -149,7 +149,7 @@ static int hopper_pci_probe(struct pci_dev *pdev, struct mantis_hwconfig *config; int err; - mantis = kzalloc(sizeof(*mantis), GFP_KERNEL); + mantis = kzalloc_obj(*mantis); if (!mantis) { err = -ENOMEM; goto fail0; diff --git a/drivers/media/pci/mantis/mantis_ca.c b/drivers/media/pci/mantis/mantis_ca.c index 0fad0a923e35..96fee641d16e 100644 --- a/drivers/media/pci/mantis/mantis_ca.c +++ b/drivers/media/pci/mantis/mantis_ca.c @@ -137,7 +137,7 @@ int mantis_ca_init(struct mantis_pci *mantis) int ca_flags = 0, result; dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA"); - ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL); + ca = kzalloc_obj(struct mantis_ca); if (!ca) { dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting .."); result = -ENOMEM; diff --git a/drivers/media/pci/mantis/mantis_cards.c b/drivers/media/pci/mantis/mantis_cards.c index b44b4cf42f86..5625260b6aec 100644 --- a/drivers/media/pci/mantis/mantis_cards.c +++ b/drivers/media/pci/mantis/mantis_cards.c @@ -158,7 +158,7 @@ static int mantis_pci_probe(struct pci_dev *pdev, struct mantis_hwconfig *config; int err; - mantis = kzalloc(sizeof(*mantis), GFP_KERNEL); + mantis = kzalloc_obj(*mantis); if (!mantis) return -ENOMEM; diff --git a/drivers/media/pci/mgb4/mgb4_core.c b/drivers/media/pci/mgb4/mgb4_core.c index a7cb8dc50b53..a7351a469386 100644 --- a/drivers/media/pci/mgb4/mgb4_core.c +++ b/drivers/media/pci/mgb4/mgb4_core.c @@ -522,7 +522,7 @@ static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id) }; int irqs = pci_msix_vec_count(pdev); - mgbdev = kzalloc(sizeof(*mgbdev), GFP_KERNEL); + mgbdev = kzalloc_obj(*mgbdev); if (!mgbdev) return -ENOMEM; diff --git a/drivers/media/pci/mgb4/mgb4_vin.c b/drivers/media/pci/mgb4/mgb4_vin.c index e782db79686f..74fb00c4a408 100644 --- a/drivers/media/pci/mgb4/mgb4_vin.c +++ b/drivers/media/pci/mgb4/mgb4_vin.c @@ -946,7 +946,7 @@ struct mgb4_vin_dev *mgb4_vin_create(struct mgb4_dev *mgbdev, int id) struct device *dev = &pdev->dev; int vin_irq, err_irq; - vindev = kzalloc(sizeof(*vindev), GFP_KERNEL); + vindev = kzalloc_obj(*vindev); if (!vindev) return NULL; diff --git a/drivers/media/pci/mgb4/mgb4_vout.c b/drivers/media/pci/mgb4/mgb4_vout.c index 44e9565d4d06..7725bcd55e4c 100644 --- a/drivers/media/pci/mgb4/mgb4_vout.c +++ b/drivers/media/pci/mgb4/mgb4_vout.c @@ -761,7 +761,7 @@ struct mgb4_vout_dev *mgb4_vout_create(struct mgb4_dev *mgbdev, int id) struct pci_dev *pdev = mgbdev->pdev; struct device *dev = &pdev->dev; - voutdev = kzalloc(sizeof(*voutdev), GFP_KERNEL); + voutdev = kzalloc_obj(*voutdev); if (!voutdev) return NULL; diff --git a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c index 9f2ac33cffa7..ec08023b5d5e 100644 --- a/drivers/media/pci/netup_unidvb/netup_unidvb_core.c +++ b/drivers/media/pci/netup_unidvb/netup_unidvb_core.c @@ -799,7 +799,7 @@ static int netup_unidvb_initdev(struct pci_dev *pci_dev, } /* allocate device context */ - ndev = kzalloc(sizeof(*ndev), GFP_KERNEL); + ndev = kzalloc_obj(*ndev); if (!ndev) goto dev_alloc_err; diff --git a/drivers/media/pci/pluto2/pluto2.c b/drivers/media/pci/pluto2/pluto2.c index 6ac9b9bd7435..22c2222d5c4d 100644 --- a/drivers/media/pci/pluto2/pluto2.c +++ b/drivers/media/pci/pluto2/pluto2.c @@ -582,7 +582,7 @@ static int pluto2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct dmx_demux *dmx; int ret = -ENOMEM; - pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL); + pluto = kzalloc_obj(struct pluto); if (!pluto) goto out; diff --git a/drivers/media/pci/pt1/pt1.c b/drivers/media/pci/pt1/pt1.c index 1ced093583ac..7cce6576b4cb 100644 --- a/drivers/media/pci/pt1/pt1.c +++ b/drivers/media/pci/pt1/pt1.c @@ -833,7 +833,7 @@ pt1_alloc_adapter(struct pt1 *pt1) struct dmxdev *dmxdev; int ret; - adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL); + adap = kzalloc_obj(struct pt1_adapter); if (!adap) { ret = -ENOMEM; goto err; @@ -1356,7 +1356,7 @@ static int pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_pci_release_regions; } - pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL); + pt1 = kzalloc_obj(struct pt1); if (!pt1) { ret = -ENOMEM; goto err_pci_iounmap; diff --git a/drivers/media/pci/pt3/pt3.c b/drivers/media/pci/pt3/pt3.c index c55aa782b72c..753161889092 100644 --- a/drivers/media/pci/pt3/pt3.c +++ b/drivers/media/pci/pt3/pt3.c @@ -529,7 +529,7 @@ static int pt3_alloc_adapter(struct pt3_board *pt3, int index) struct pt3_adapter *adap; struct dvb_adapter *da; - adap = kzalloc(sizeof(*adap), GFP_KERNEL); + adap = kzalloc_obj(*adap); if (!adap) return -ENOMEM; diff --git a/drivers/media/pci/saa7134/saa7134-alsa.c b/drivers/media/pci/saa7134/saa7134-alsa.c index f86a44dfe6e3..147985bb0261 100644 --- a/drivers/media/pci/saa7134/saa7134-alsa.c +++ b/drivers/media/pci/saa7134/saa7134-alsa.c @@ -816,7 +816,7 @@ static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream) mutex_unlock(&dev->dmasound.lock); - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + pcm = kzalloc_obj(*pcm); if (pcm == NULL) return -ENOMEM; diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index 537aa65acdc8..2f5b258d682b 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -1010,7 +1010,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (saa7134_devcount == SAA7134_MAXBOARDS) return -ENOMEM; - dev = kzalloc(sizeof(*dev),GFP_KERNEL); + dev = kzalloc_obj(*dev); if (NULL == dev) return -ENOMEM; @@ -1018,7 +1018,7 @@ static int saa7134_initdev(struct pci_dev *pci_dev, sprintf(dev->name, "saa%x[%d]", pci_dev->device, dev->nr); #ifdef CONFIG_MEDIA_CONTROLLER - dev->media_dev = kzalloc(sizeof(*dev->media_dev), GFP_KERNEL); + dev->media_dev = kzalloc_obj(*dev->media_dev); if (!dev->media_dev) { err = -ENOMEM; goto err_free_dev; diff --git a/drivers/media/pci/saa7134/saa7134-go7007.c b/drivers/media/pci/saa7134/saa7134-go7007.c index bd37db5ce363..1f4d771793a2 100644 --- a/drivers/media/pci/saa7134/saa7134-go7007.c +++ b/drivers/media/pci/saa7134/saa7134-go7007.c @@ -414,7 +414,7 @@ static int saa7134_go7007_init(struct saa7134_dev *dev) if (go == NULL) return -ENOMEM; - saa = kzalloc(sizeof(struct saa7134_go7007), GFP_KERNEL); + saa = kzalloc_obj(struct saa7134_go7007); if (saa == NULL) { kfree(go); return -ENOMEM; diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index 468dbe8d552f..5b7101415780 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -768,7 +768,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) return -ENODEV; } - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); rc = rc_allocate_device(RC_DRIVER_SCANCODE); if (!ir || !rc) { err = -ENOMEM; diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c index 40b35098f3ea..1eef4e102972 100644 --- a/drivers/media/pci/saa7146/hexium_gemini.c +++ b/drivers/media/pci/saa7146/hexium_gemini.c @@ -250,7 +250,7 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d DEB_EE("\n"); - hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); + hexium = kzalloc_obj(*hexium); if (!hexium) return -ENOMEM; diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c index a2076728c621..6f1b4bff7596 100644 --- a/drivers/media/pci/saa7146/hexium_orion.c +++ b/drivers/media/pci/saa7146/hexium_orion.c @@ -209,7 +209,7 @@ static int hexium_probe(struct saa7146_dev *dev) return -EFAULT; } - hexium = kzalloc(sizeof(*hexium), GFP_KERNEL); + hexium = kzalloc_obj(*hexium); if (!hexium) return -ENOMEM; diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c index a14b839098b8..d931b4e3052f 100644 --- a/drivers/media/pci/saa7146/mxb.c +++ b/drivers/media/pci/saa7146/mxb.c @@ -226,7 +226,7 @@ static int mxb_probe(struct saa7146_dev *dev) V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); if (hdl->error) return hdl->error; - mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); + mxb = kzalloc_obj(struct mxb); if (mxb == NULL) { DEB_D("not enough kernel memory\n"); return -ENOMEM; diff --git a/drivers/media/pci/saa7164/saa7164-buffer.c b/drivers/media/pci/saa7164/saa7164-buffer.c index 7820e4f47fd5..1f961bdfc041 100644 --- a/drivers/media/pci/saa7164/saa7164-buffer.c +++ b/drivers/media/pci/saa7164/saa7164-buffer.c @@ -68,7 +68,7 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port, goto ret; } - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) goto ret; @@ -252,7 +252,7 @@ struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev, { struct saa7164_user_buffer *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return NULL; diff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0..74406d5ea0a5 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -1238,7 +1238,7 @@ static int saa7164_initdev(struct pci_dev *pci_dev, int err, i; u32 version; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (NULL == dev) return -ENOMEM; diff --git a/drivers/media/pci/saa7164/saa7164-encoder.c b/drivers/media/pci/saa7164/saa7164-encoder.c index 66d650b5f69a..64380741b984 100644 --- a/drivers/media/pci/saa7164/saa7164-encoder.c +++ b/drivers/media/pci/saa7164/saa7164-encoder.c @@ -719,7 +719,7 @@ static int fops_open(struct file *file) dprintk(DBGLVL_ENC, "%s()\n", __func__); /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); + fh = kzalloc_obj(*fh); if (NULL == fh) return -ENOMEM; diff --git a/drivers/media/pci/saa7164/saa7164-vbi.c b/drivers/media/pci/saa7164/saa7164-vbi.c index 57e4362c0d19..bfa6ee295a22 100644 --- a/drivers/media/pci/saa7164/saa7164-vbi.c +++ b/drivers/media/pci/saa7164/saa7164-vbi.c @@ -422,7 +422,7 @@ static int fops_open(struct file *file) dprintk(DBGLVL_VBI, "%s()\n", __func__); /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); + fh = kzalloc_obj(*fh); if (NULL == fh) return -ENOMEM; diff --git a/drivers/media/pci/smipcie/smipcie-main.c b/drivers/media/pci/smipcie/smipcie-main.c index 7db6d443fc54..387c29958c98 100644 --- a/drivers/media/pci/smipcie/smipcie-main.c +++ b/drivers/media/pci/smipcie/smipcie-main.c @@ -946,7 +946,7 @@ static int smi_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (pci_enable_device(pdev) < 0) return -ENODEV; - dev = kzalloc(sizeof(struct smi_dev), GFP_KERNEL); + dev = kzalloc_obj(struct smi_dev); if (!dev) { ret = -ENOMEM; goto err_pci_disable_device; diff --git a/drivers/media/pci/solo6x10/solo6x10-core.c b/drivers/media/pci/solo6x10/solo6x10-core.c index d1d3a83d0122..11cddf4b4312 100644 --- a/drivers/media/pci/solo6x10/solo6x10-core.c +++ b/drivers/media/pci/solo6x10/solo6x10-core.c @@ -449,7 +449,7 @@ static int solo_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) int ret; u8 chip_id; - solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); + solo_dev = kzalloc_obj(*solo_dev); if (solo_dev == NULL) return -ENOMEM; diff --git a/drivers/media/pci/solo6x10/solo6x10-g723.c b/drivers/media/pci/solo6x10/solo6x10-g723.c index 1db9f40ee0c0..e41b8d90a30e 100644 --- a/drivers/media/pci/solo6x10/solo6x10-g723.c +++ b/drivers/media/pci/solo6x10/solo6x10-g723.c @@ -120,7 +120,7 @@ static int snd_solo_pcm_open(struct snd_pcm_substream *ss) struct solo_dev *solo_dev = snd_pcm_substream_chip(ss); struct solo_snd_pcm *solo_pcm; - solo_pcm = kzalloc(sizeof(*solo_pcm), GFP_KERNEL); + solo_pcm = kzalloc_obj(*solo_pcm); if (solo_pcm == NULL) goto oom; diff --git a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c index 5ee59b3844cc..91b5c4161930 100644 --- a/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c +++ b/drivers/media/pci/solo6x10/solo6x10-v4l2-enc.c @@ -1208,7 +1208,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo_dev *solo_dev, struct v4l2_ctrl_handler *hdl; int ret; - solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL); + solo_enc = kzalloc_obj(*solo_enc); if (!solo_enc) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/pci/ttpci/budget-av.c b/drivers/media/pci/ttpci/budget-av.c index 69f5e810f9b5..55542cfbc6bb 100644 --- a/drivers/media/pci/ttpci/budget-av.c +++ b/drivers/media/pci/ttpci/budget-av.c @@ -1437,7 +1437,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio dprintk(2, "dev: %p\n", dev); - budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL); + budget_av = kzalloc_obj(struct budget_av); if (!budget_av) return -ENOMEM; diff --git a/drivers/media/pci/ttpci/budget-ci.c b/drivers/media/pci/ttpci/budget-ci.c index 33f08adf4feb..3709c0fb23b0 100644 --- a/drivers/media/pci/ttpci/budget-ci.c +++ b/drivers/media/pci/ttpci/budget-ci.c @@ -1456,7 +1456,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio struct budget_ci *budget_ci; int err; - budget_ci = kzalloc(sizeof(struct budget_ci), GFP_KERNEL); + budget_ci = kzalloc_obj(struct budget_ci); if (!budget_ci) { err = -ENOMEM; goto out1; diff --git a/drivers/media/pci/ttpci/budget.c b/drivers/media/pci/ttpci/budget.c index f623c250909b..95370156aff5 100644 --- a/drivers/media/pci/ttpci/budget.c +++ b/drivers/media/pci/ttpci/budget.c @@ -788,7 +788,7 @@ static int budget_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d struct budget *budget = NULL; int err; - budget = kmalloc(sizeof(struct budget), GFP_KERNEL); + budget = kmalloc_obj(struct budget); if (budget == NULL) return -ENOMEM; diff --git a/drivers/media/pci/tw686x/tw686x-core.c b/drivers/media/pci/tw686x/tw686x-core.c index f39e0e34deb6..a10e38221817 100644 --- a/drivers/media/pci/tw686x/tw686x-core.c +++ b/drivers/media/pci/tw686x/tw686x-core.c @@ -243,22 +243,22 @@ static int tw686x_probe(struct pci_dev *pci_dev, struct tw686x_dev *dev; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; dev->type = pci_id->driver_data; dev->dma_mode = dma_mode; sprintf(dev->name, "tw%04X", pci_dev->device); - dev->video_channels = kcalloc(max_channels(dev), - sizeof(*dev->video_channels), GFP_KERNEL); + dev->video_channels = kzalloc_objs(*dev->video_channels, + max_channels(dev)); if (!dev->video_channels) { err = -ENOMEM; goto free_dev; } - dev->audio_channels = kcalloc(max_channels(dev), - sizeof(*dev->audio_channels), GFP_KERNEL); + dev->audio_channels = kzalloc_objs(*dev->audio_channels, + max_channels(dev)); if (!dev->audio_channels) { err = -ENOMEM; goto free_video; diff --git a/drivers/media/pci/zoran/videocodec.c b/drivers/media/pci/zoran/videocodec.c index 8efc5e06b0f7..85fe60065b4d 100644 --- a/drivers/media/pci/zoran/videocodec.c +++ b/drivers/media/pci/zoran/videocodec.c @@ -73,7 +73,7 @@ struct videocodec *videocodec_attach(struct videocodec_master *master) res = codec->setup(codec); if (res == 0) { zrdev_dbg(zr, "%s: '%s'\n", __func__, codec->name); - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); if (!ptr) goto out_kfree; ptr->codec = codec; @@ -180,7 +180,7 @@ int videocodec_register(const struct videocodec *codec) "videocodec: register '%s', type: %x, flags %lx, magic %lx\n", codec->name, codec->type, codec->flags, codec->magic); - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); if (!ptr) return -ENOMEM; ptr->codec = codec; diff --git a/drivers/media/pci/zoran/zr36016.c b/drivers/media/pci/zoran/zr36016.c index d2e136c48a1b..bb2d92743229 100644 --- a/drivers/media/pci/zoran/zr36016.c +++ b/drivers/media/pci/zoran/zr36016.c @@ -344,7 +344,7 @@ static int zr36016_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/media/pci/zoran/zr36050.c b/drivers/media/pci/zoran/zr36050.c index c17965073557..eac4a6c32e93 100644 --- a/drivers/media/pci/zoran/zr36050.c +++ b/drivers/media/pci/zoran/zr36050.c @@ -741,7 +741,7 @@ static int zr36050_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/media/pci/zoran/zr36060.c b/drivers/media/pci/zoran/zr36060.c index d6c12efc5bb6..c383dcddf7cd 100644 --- a/drivers/media/pci/zoran/zr36060.c +++ b/drivers/media/pci/zoran/zr36060.c @@ -796,7 +796,7 @@ static int zr36060_setup(struct videocodec *codec) return -ENOSPC; } //mem structure init - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); codec->data = ptr; if (!ptr) return -ENOMEM; diff --git a/drivers/media/platform/allegro-dvt/allegro-core.c b/drivers/media/platform/allegro-dvt/allegro-core.c index eec0b8b30b7f..eac3bc9af990 100644 --- a/drivers/media/platform/allegro-dvt/allegro-core.c +++ b/drivers/media/platform/allegro-dvt/allegro-core.c @@ -967,7 +967,7 @@ static int allegro_mbox_notify(struct allegro_mbox *mbox) u32 *tmp; int err; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -1551,7 +1551,7 @@ static int allocate_buffers_internal(struct allegro_channel *channel, struct allegro_buffer *buffer, *tmp; for (i = 0; i < n; i++) { - buffer = kmalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kmalloc_obj(*buffer); if (!buffer) { err = -ENOMEM; goto err; @@ -1632,7 +1632,7 @@ static ssize_t allegro_h264_write_sps(struct allegro_channel *channel, unsigned int cpb_size; unsigned int cpb_size_scale; - sps = kzalloc(sizeof(*sps), GFP_KERNEL); + sps = kzalloc_obj(*sps); if (!sps) return -ENOMEM; @@ -1729,7 +1729,7 @@ static ssize_t allegro_h264_write_pps(struct allegro_channel *channel, struct nal_h264_pps *pps; ssize_t size; - pps = kzalloc(sizeof(*pps), GFP_KERNEL); + pps = kzalloc_obj(*pps); if (!pps) return -ENOMEM; @@ -1780,7 +1780,7 @@ static ssize_t allegro_hevc_write_vps(struct allegro_channel *channel, s32 level = v4l2_ctrl_g_ctrl(channel->mpeg_video_hevc_level); s32 tier = v4l2_ctrl_g_ctrl(channel->mpeg_video_hevc_tier); - vps = kzalloc(sizeof(*vps), GFP_KERNEL); + vps = kzalloc_obj(*vps); if (!vps) return -ENOMEM; @@ -1822,7 +1822,7 @@ static ssize_t allegro_hevc_write_sps(struct allegro_channel *channel, s32 level = v4l2_ctrl_g_ctrl(channel->mpeg_video_hevc_level); s32 tier = v4l2_ctrl_g_ctrl(channel->mpeg_video_hevc_tier); - sps = kzalloc(sizeof(*sps), GFP_KERNEL); + sps = kzalloc_obj(*sps); if (!sps) return -ENOMEM; @@ -1929,7 +1929,7 @@ static ssize_t allegro_hevc_write_pps(struct allegro_channel *channel, ssize_t size; int i; - pps = kzalloc(sizeof(*pps), GFP_KERNEL); + pps = kzalloc_obj(*pps); if (!pps) return -ENOMEM; diff --git a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c index c51c6f4e41dc..c5dc03905ce0 100644 --- a/drivers/media/platform/amlogic/meson-ge2d/ge2d.c +++ b/drivers/media/platform/amlogic/meson-ge2d/ge2d.c @@ -834,7 +834,7 @@ static int ge2d_open(struct file *file) struct ge2d_ctx *ctx = NULL; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->ge2d = ge2d; diff --git a/drivers/media/platform/amphion/vdec.c b/drivers/media/platform/amphion/vdec.c index adf53b49020e..a9f0521f2e1a 100644 --- a/drivers/media/platform/amphion/vdec.c +++ b/drivers/media/platform/amphion/vdec.c @@ -1927,19 +1927,18 @@ static int vdec_open(struct file *file) struct vdec_t *vdec; int ret; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; - vdec = kzalloc(sizeof(*vdec), GFP_KERNEL); + vdec = kzalloc_obj(*vdec); if (!vdec) { kfree(inst); return -ENOMEM; } - vdec->slots = kmalloc_array(VDEC_SLOT_CNT_DFT, - sizeof(*vdec->slots), - GFP_KERNEL | __GFP_ZERO); + vdec->slots = kmalloc_objs(*vdec->slots, VDEC_SLOT_CNT_DFT, + GFP_KERNEL | __GFP_ZERO); if (!vdec->slots) { kfree(vdec); kfree(inst); diff --git a/drivers/media/platform/amphion/venc.c b/drivers/media/platform/amphion/venc.c index 9e5cbc2b0d3f..0b3d58b9f2f7 100644 --- a/drivers/media/platform/amphion/venc.c +++ b/drivers/media/platform/amphion/venc.c @@ -858,7 +858,7 @@ static int venc_frame_encoded(struct vpu_inst *inst, void *arg) if (!info) return -EINVAL; venc = inst->priv; - frame = kzalloc(sizeof(*frame), GFP_KERNEL); + frame = kzalloc_obj(*frame); if (!frame) return -ENOMEM; @@ -1307,11 +1307,11 @@ static int venc_open(struct file *file) struct venc_t *venc; int ret; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; - venc = kzalloc(sizeof(*venc), GFP_KERNEL); + venc = kzalloc_obj(*venc); if (!venc) { kfree(inst); return -ENOMEM; diff --git a/drivers/media/platform/amphion/vpu_cmds.c b/drivers/media/platform/amphion/vpu_cmds.c index ab69412e0aa7..615680f1cb94 100644 --- a/drivers/media/platform/amphion/vpu_cmds.c +++ b/drivers/media/platform/amphion/vpu_cmds.c @@ -83,11 +83,11 @@ static struct vpu_cmd_t *vpu_alloc_cmd(struct vpu_inst *inst, u32 id, void *data int i; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return NULL; - cmd->pkt = kzalloc(sizeof(*cmd->pkt), GFP_KERNEL); + cmd->pkt = kzalloc_obj(*cmd->pkt); if (!cmd->pkt) { kfree(cmd); return NULL; diff --git a/drivers/media/platform/broadcom/bcm2835-unicam.c b/drivers/media/platform/broadcom/bcm2835-unicam.c index f10064107d54..53a342853be6 100644 --- a/drivers/media/platform/broadcom/bcm2835-unicam.c +++ b/drivers/media/platform/broadcom/bcm2835-unicam.c @@ -2642,7 +2642,7 @@ static int unicam_probe(struct platform_device *pdev) struct unicam_device *unicam; int ret; - unicam = kzalloc(sizeof(*unicam), GFP_KERNEL); + unicam = kzalloc_obj(*unicam); if (!unicam) return -ENOMEM; diff --git a/drivers/media/platform/cadence/cdns-csi2rx.c b/drivers/media/platform/cadence/cdns-csi2rx.c index 8c19f125da3e..cde690c6fdee 100644 --- a/drivers/media/platform/cadence/cdns-csi2rx.c +++ b/drivers/media/platform/cadence/cdns-csi2rx.c @@ -824,7 +824,7 @@ static int csi2rx_probe(struct platform_device *pdev) unsigned int i; int ret; - csi2rx = kzalloc(sizeof(*csi2rx), GFP_KERNEL); + csi2rx = kzalloc_obj(*csi2rx); if (!csi2rx) return -ENOMEM; platform_set_drvdata(pdev, csi2rx); diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index e22b133f346d..629b0fa838a2 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -573,7 +573,7 @@ static int csi2tx_probe(struct platform_device *pdev) unsigned int i; int ret; - csi2tx = kzalloc(sizeof(*csi2tx), GFP_KERNEL); + csi2tx = kzalloc_obj(*csi2tx); if (!csi2tx) return -ENOMEM; platform_set_drvdata(pdev, csi2tx); diff --git a/drivers/media/platform/chips-media/coda/coda-bit.c b/drivers/media/platform/chips-media/coda/coda-bit.c index fa6b72c3bd93..b0559303c40f 100644 --- a/drivers/media/platform/chips-media/coda/coda-bit.c +++ b/drivers/media/platform/chips-media/coda/coda-bit.c @@ -397,7 +397,7 @@ void coda_fill_bitstream(struct coda_ctx *ctx, struct list_head *buffer_list) */ src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); - meta = kmalloc(sizeof(*meta), GFP_KERNEL); + meta = kmalloc_obj(*meta); if (meta) { meta->sequence = src_buf->sequence; meta->timecode = src_buf->timecode; diff --git a/drivers/media/platform/chips-media/coda/coda-common.c b/drivers/media/platform/chips-media/coda/coda-common.c index 33f712ff8556..be37ea568bfe 100644 --- a/drivers/media/platform/chips-media/coda/coda-common.c +++ b/drivers/media/platform/chips-media/coda/coda-common.c @@ -2606,7 +2606,7 @@ static int coda_open(struct file *file) int ret; int idx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/chips-media/coda/coda-jpeg.c b/drivers/media/platform/chips-media/coda/coda-jpeg.c index fb150b87c773..835225383aa1 100644 --- a/drivers/media/platform/chips-media/coda/coda-jpeg.c +++ b/drivers/media/platform/chips-media/coda/coda-jpeg.c @@ -355,7 +355,7 @@ int coda_jpeg_decode_header(struct coda_ctx *ctx, struct vb2_buffer *vb) } huff_tab = ctx->params.jpeg_huff_tab; if (!huff_tab) { - huff_tab = kzalloc(sizeof(struct coda_huff_tab), GFP_KERNEL); + huff_tab = kzalloc_obj(struct coda_huff_tab); if (!huff_tab) return -ENOMEM; ctx->params.jpeg_huff_tab = huff_tab; @@ -593,7 +593,7 @@ static int coda9_jpeg_gen_enc_huff_tab(struct coda_ctx *ctx, int tab_num, }; int ret = -EINVAL; - huff = kzalloc(sizeof(*huff), GFP_KERNEL); + huff = kzalloc_obj(*huff); if (!huff) return -ENOMEM; @@ -723,7 +723,7 @@ static int coda9_jpeg_load_huff_tab(struct coda_ctx *ctx) int i, j; int ret; - huff = kzalloc(sizeof(*huff), GFP_KERNEL); + huff = kzalloc_obj(*huff); if (!huff) return -ENOMEM; diff --git a/drivers/media/platform/chips-media/coda/imx-vdoa.c b/drivers/media/platform/chips-media/coda/imx-vdoa.c index c3561fcecb98..be874f18a365 100644 --- a/drivers/media/platform/chips-media/coda/imx-vdoa.c +++ b/drivers/media/platform/chips-media/coda/imx-vdoa.c @@ -201,7 +201,7 @@ struct vdoa_ctx *vdoa_context_create(struct vdoa_data *vdoa) struct vdoa_ctx *ctx; int err; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c index 8917542b993c..80e1831a42e0 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c @@ -1822,7 +1822,7 @@ static int wave5_vpu_open_dec(struct file *filp) struct v4l2_m2m_ctx *m2m_ctx; int ret = 0; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; @@ -1834,7 +1834,7 @@ static int wave5_vpu_open_dec(struct file *filp) mutex_init(&inst->feed_lock); INIT_LIST_HEAD(&inst->avail_src_bufs); - inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL); + inst->codec_info = kzalloc_obj(*inst->codec_info); if (!inst->codec_info) { kfree(inst); return -ENOMEM; diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c index 24fc0d0d3f4a..7613fcdbafed 100644 --- a/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c +++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-enc.c @@ -1571,7 +1571,7 @@ static int wave5_vpu_open_enc(struct file *filp) struct v4l2_ctrl_handler *v4l2_ctrl_hdl; int ret = 0; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; v4l2_ctrl_hdl = &inst->v4l2_ctrl_hdl; @@ -1580,7 +1580,7 @@ static int wave5_vpu_open_enc(struct file *filp) inst->type = VPU_INST_TYPE_ENC; inst->ops = &wave5_vpu_enc_inst_ops; - inst->codec_info = kzalloc(sizeof(*inst->codec_info), GFP_KERNEL); + inst->codec_info = kzalloc_obj(*inst->codec_info); if (!inst->codec_info) { kfree(inst); return -ENOMEM; diff --git a/drivers/media/platform/imagination/e5010-jpeg-enc.c b/drivers/media/platform/imagination/e5010-jpeg-enc.c index 1c6e076033ec..42ad9ee3993b 100644 --- a/drivers/media/platform/imagination/e5010-jpeg-enc.c +++ b/drivers/media/platform/imagination/e5010-jpeg-enc.c @@ -728,7 +728,7 @@ static int e5010_open(struct file *file) struct e5010_context *ctx; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/intel/pxa_camera.c b/drivers/media/platform/intel/pxa_camera.c index bef1e7137f23..2269d852ab0e 100644 --- a/drivers/media/platform/intel/pxa_camera.c +++ b/drivers/media/platform/intel/pxa_camera.c @@ -741,7 +741,7 @@ static struct pxa_camera_format_xlate *pxa_mbus_build_fmts_xlate( if (!fmts) return ERR_PTR(-ENXIO); - user_formats = kcalloc(fmts + 1, sizeof(*user_formats), GFP_KERNEL); + user_formats = kzalloc_objs(*user_formats, fmts + 1); if (!user_formats) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index af098874ead5..1d0e70eaea3d 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -835,7 +835,7 @@ static int deinterlace_open(struct file *file) struct deinterlace_dev *pcdev = video_drvdata(file); struct deinterlace_ctx *ctx = NULL; - ctx = kzalloc(sizeof *ctx, GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/marvell/cafe-driver.c b/drivers/media/platform/marvell/cafe-driver.c index f9796de92aa7..632c15572aa8 100644 --- a/drivers/media/platform/marvell/cafe-driver.c +++ b/drivers/media/platform/marvell/cafe-driver.c @@ -327,7 +327,7 @@ static int cafe_smbus_setup(struct cafe_camera *cam) struct i2c_adapter *adap; int ret; - adap = kzalloc(sizeof(*adap), GFP_KERNEL); + adap = kzalloc_obj(*adap); if (adap == NULL) return -ENOMEM; adap->owner = THIS_MODULE; @@ -485,7 +485,7 @@ static int cafe_pci_probe(struct pci_dev *pdev, * Start putting together one of our big camera structures. */ ret = -ENOMEM; - cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL); + cam = kzalloc_obj(struct cafe_camera); if (cam == NULL) goto out; pci_set_drvdata(pdev, cam); diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c index d08fe365cbb2..c01124a349f6 100644 --- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c +++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c @@ -1151,7 +1151,7 @@ static int mtk_jpeg_open(struct file *file) struct mtk_jpeg_ctx *ctx; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c b/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c index 03c07948dfdd..d2813890cceb 100644 --- a/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c +++ b/drivers/media/platform/mediatek/mdp/mtk_mdp_m2m.c @@ -1053,7 +1053,7 @@ static int mtk_mdp_m2m_open(struct file *file) int ret; struct v4l2_format default_format; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c index e5ccf673e152..d30a05782ab9 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-cmdq.c @@ -564,7 +564,7 @@ static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp, goto err_uninit; } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto err_uninit; @@ -583,13 +583,13 @@ static struct mdp_cmdq_cmd *mdp_cmdq_prepare(struct mdp_dev *mdp, goto err_destroy_pkt; } - comps = kcalloc(num_comp, sizeof(*comps), GFP_KERNEL); + comps = kzalloc_objs(*comps, num_comp); if (!comps) { ret = -ENOMEM; goto err_destroy_pkt; } - path = kzalloc(sizeof(*path), GFP_KERNEL); + path = kzalloc_obj(*path); if (!path) { ret = -ENOMEM; goto err_free_comps; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c index f20d2ed1f2bb..8f4da4cf55d2 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-core.c @@ -221,7 +221,7 @@ static int mdp_probe(struct platform_device *pdev) struct resource *res; int ret, i, mutex_id; - mdp = kzalloc(sizeof(*mdp), GFP_KERNEL); + mdp = kzalloc_obj(*mdp); if (!mdp) { ret = -ENOMEM; goto err_return; diff --git a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c index 44140987cf5f..ad3ae89c231c 100644 --- a/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c +++ b/drivers/media/platform/mediatek/mdp3/mtk-mdp3-m2m.c @@ -568,7 +568,7 @@ static int mdp_m2m_open(struct file *file) struct v4l2_format default_format = {}; const struct mdp_limit *limit = mdp->mdp_data->def_limit; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c index 643d6fff088b..2da11521fc7b 100644 --- a/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c +++ b/drivers/media/platform/mediatek/vcodec/common/mtk_vcodec_dbgfs.c @@ -149,7 +149,7 @@ void mtk_vcodec_dbgfs_create(struct mtk_vcodec_dec_ctx *ctx) struct mtk_vcodec_dbgfs_inst *dbgfs_inst; struct mtk_vcodec_dec_dev *vcodec_dev = ctx->dev; - dbgfs_inst = kzalloc(sizeof(*dbgfs_inst), GFP_KERNEL); + dbgfs_inst = kzalloc_obj(*dbgfs_inst); if (!dbgfs_inst) return; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c index 3b81fae9f913..e936ed8dffba 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_drv.c @@ -200,7 +200,7 @@ static int fops_vcodec_open(struct file *file) struct vb2_queue *src_vq; unsigned long flags; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c index 8e1cf16a168a..ab1894fba0d9 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/mtk_vcodec_dec_stateless.c @@ -735,7 +735,7 @@ static struct media_request *fops_media_request_alloc(struct media_device *mdev) { struct mtk_vcodec_dec_request *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); return &req->req; } diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c index 7be4b6086920..2d622e85f827 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c @@ -1879,7 +1879,7 @@ static int vdec_av1_slice_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_av1_slice_init_vsi *vsi; int ret; - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c index 795cb19b075d..a95327388f57 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_if.c @@ -270,7 +270,7 @@ static int vdec_h264_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_h264_inst *inst = NULL; int err; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c index b9a5ea7887d3..1f691cd2f4c3 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_if.c @@ -273,7 +273,7 @@ static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_h264_slice_inst *inst; int err; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c index 9a9dc2f88d6e..10359ce9b934 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_h264_req_multi_if.c @@ -1208,7 +1208,7 @@ static int vdec_h264_slice_init(struct mtk_vcodec_dec_ctx *ctx) int err, vsi_size; unsigned char *temp; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c index 88eca50c2017..02f39954a4c2 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_hevc_req_multi_if.c @@ -858,7 +858,7 @@ static int vdec_hevc_slice_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_hevc_slice_inst *inst; int err, vsi_size; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c index 5f848691cea4..fd15d462b168 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_if.c @@ -390,7 +390,7 @@ static int vdec_vp8_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_vp8_inst *inst; int err; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c index e1d4960553f2..391e789a5a13 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp8_req_if.c @@ -275,7 +275,7 @@ static int vdec_vp8_slice_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_vp8_slice_inst *inst; int err; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c index cd1935014d76..adbacabdbebc 100644 --- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c +++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_vp9_req_lat_if.c @@ -1848,7 +1848,7 @@ static int vdec_vp9_slice_init(struct mtk_vcodec_dec_ctx *ctx) struct vdec_vp9_slice_init_vsi *vsi; int ret; - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c index 82b8ff38e8f1..c977ed0c09b6 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/mtk_vcodec_enc_drv.c @@ -119,7 +119,7 @@ static int fops_vcodec_open(struct file *file) struct vb2_queue *src_vq; unsigned long flags; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c index 0f63657d8bad..d2f4d732d2f7 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_h264_if.c @@ -588,7 +588,7 @@ static int h264_enc_init(struct mtk_vcodec_enc_ctx *ctx) int ret = 0; struct venc_h264_inst *inst; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c index 05abca91e742..f739fd5fafcc 100644 --- a/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c +++ b/drivers/media/platform/mediatek/vcodec/encoder/venc/venc_vp8_if.c @@ -316,7 +316,7 @@ static int vp8_enc_init(struct mtk_vcodec_enc_ctx *ctx) int ret = 0; struct venc_vp8_inst *inst; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/nuvoton/npcm-video.c b/drivers/media/platform/nuvoton/npcm-video.c index 44e904e61801..b2a562e1ee1c 100644 --- a/drivers/media/platform/nuvoton/npcm-video.c +++ b/drivers/media/platform/nuvoton/npcm-video.c @@ -411,7 +411,7 @@ static unsigned int npcm_video_add_rect(struct npcm_video *video, struct rect_list *list = NULL; struct v4l2_rect *r; - list = kzalloc(sizeof(*list), GFP_KERNEL); + list = kzalloc_obj(*list); if (!list) return 0; @@ -466,7 +466,7 @@ static struct rect_list *npcm_video_new_rect(struct npcm_video *video, struct rect_list *list = NULL; struct v4l2_rect *r; - list = kzalloc(sizeof(*list), GFP_KERNEL); + list = kzalloc_obj(*list); if (!list) return NULL; @@ -1733,7 +1733,7 @@ static int npcm_video_init(struct npcm_video *video) static int npcm_video_probe(struct platform_device *pdev) { - struct npcm_video *video = kzalloc(sizeof(*video), GFP_KERNEL); + struct npcm_video *video = kzalloc_obj(*video); int rc; void __iomem *regs; diff --git a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c index b34244ea14dd..7752064be783 100644 --- a/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c +++ b/drivers/media/platform/nvidia/tegra-vde/dmabuf-cache.c @@ -115,7 +115,7 @@ int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde, goto err_unmap; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto err_unmap; diff --git a/drivers/media/platform/nvidia/tegra-vde/v4l2.c b/drivers/media/platform/nvidia/tegra-vde/v4l2.c index d94978ae2baf..f2ca1c7ed9ba 100644 --- a/drivers/media/platform/nvidia/tegra-vde/v4l2.c +++ b/drivers/media/platform/nvidia/tegra-vde/v4l2.c @@ -811,8 +811,7 @@ static int tegra_open(struct file *file) struct tegra_ctx *ctx; int err; - ctx = kzalloc(struct_size(ctx, ctrls, ARRAY_SIZE(ctrl_cfgs)), - GFP_KERNEL); + ctx = kzalloc_flex(*ctx, ctrls, ARRAY_SIZE(ctrl_cfgs)); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/nvidia/tegra-vde/vde.c b/drivers/media/platform/nvidia/tegra-vde/vde.c index 3232392c60e2..2b3898828304 100644 --- a/drivers/media/platform/nvidia/tegra-vde/vde.c +++ b/drivers/media/platform/nvidia/tegra-vde/vde.c @@ -61,7 +61,7 @@ int tegra_vde_alloc_bo(struct tegra_vde *vde, struct tegra_vde_bo *bo; int err; - bo = kzalloc(sizeof(*bo), GFP_KERNEL); + bo = kzalloc_obj(*bo); if (!bo) return -ENOMEM; diff --git a/drivers/media/platform/nxp/dw100/dw100.c b/drivers/media/platform/nxp/dw100/dw100.c index 4aaf9c3fff53..bdebbe3f4198 100644 --- a/drivers/media/platform/nxp/dw100/dw100.c +++ b/drivers/media/platform/nxp/dw100/dw100.c @@ -601,7 +601,7 @@ static int dw100_open(struct file *file) struct v4l2_pix_format_mplane *pix_fmt; int ret, i; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c index b558700d1d96..b442dcba02e7 100644 --- a/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c +++ b/drivers/media/platform/nxp/imx-jpeg/mxc-jpeg.c @@ -2200,7 +2200,7 @@ static int mxc_jpeg_open(struct file *file) struct mxc_jpeg_ctx *ctx; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/nxp/imx-pxp.c b/drivers/media/platform/nxp/imx-pxp.c index 3f9a67a6bd4d..740fcd8fb952 100644 --- a/drivers/media/platform/nxp/imx-pxp.c +++ b/drivers/media/platform/nxp/imx-pxp.c @@ -1646,7 +1646,7 @@ static int pxp_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto open_unlock; diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c index 18146978bdf5..16392420903a 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-core.c @@ -474,8 +474,7 @@ static int mxc_isi_probe(struct platform_device *pdev) isi->pdata = of_device_get_match_data(dev); - isi->pipes = kcalloc(isi->pdata->num_channels, sizeof(isi->pipes[0]), - GFP_KERNEL); + isi->pipes = kzalloc_objs(isi->pipes[0], isi->pdata->num_channels); if (!isi->pipes) return -ENOMEM; diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c index 3c26cfef93d1..605a45124103 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-crossbar.c @@ -189,7 +189,7 @@ static int mxc_isi_crossbar_init_state(struct v4l2_subdev *sd, * pipelines by default. */ routing.num_routes = min(xbar->num_sinks - 1, xbar->num_sources); - routes = kcalloc(routing.num_routes, sizeof(*routes), GFP_KERNEL); + routes = kzalloc_objs(*routes, routing.num_routes); if (!routes) return -ENOMEM; @@ -454,12 +454,11 @@ int mxc_isi_crossbar_init(struct mxc_isi_dev *isi) xbar->num_sources = isi->pdata->num_channels; num_pads = xbar->num_sinks + xbar->num_sources; - xbar->pads = kcalloc(num_pads, sizeof(*xbar->pads), GFP_KERNEL); + xbar->pads = kzalloc_objs(*xbar->pads, num_pads); if (!xbar->pads) return -ENOMEM; - xbar->inputs = kcalloc(xbar->num_sinks, sizeof(*xbar->inputs), - GFP_KERNEL); + xbar->inputs = kzalloc_objs(*xbar->inputs, xbar->num_sinks); if (!xbar->inputs) { ret = -ENOMEM; goto err_free; diff --git a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c index f425ac786854..a39ad7a1ab18 100644 --- a/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c +++ b/drivers/media/platform/nxp/imx8-isi/imx8-isi-m2m.c @@ -624,7 +624,7 @@ static int mxc_isi_m2m_open(struct file *file) struct mxc_isi_m2m_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/nxp/mx2_emmaprp.c b/drivers/media/platform/nxp/mx2_emmaprp.c index 02d57229b9b3..d51a62100778 100644 --- a/drivers/media/platform/nxp/mx2_emmaprp.c +++ b/drivers/media/platform/nxp/mx2_emmaprp.c @@ -718,7 +718,7 @@ static int emmaprp_open(struct file *file) struct emmaprp_dev *pcdev = video_drvdata(file); struct emmaprp_ctx *ctx; - ctx = kzalloc(sizeof *ctx, GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index f1f003a787bf..9151f43bc6b9 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -342,7 +342,7 @@ static int iris_create_internal_buffer(struct iris_inst *inst, if (!buffers->size) return 0; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return -ENOMEM; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index 11815f6f5bac..e42d17653c2c 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -1087,5 +1087,5 @@ void iris_hfi_gen1_command_ops_init(struct iris_core *core) struct iris_inst *iris_hfi_gen1_get_instance(void) { - return kzalloc(sizeof(struct iris_inst), GFP_KERNEL); + return kzalloc_obj(struct iris_inst); } diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index 715ec9575b90..30bfd90d423b 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -1329,7 +1329,7 @@ struct iris_inst *iris_hfi_gen2_get_instance(void) struct iris_inst_hfi_gen2 *out; /* The allocation is intentionally larger than struct iris_inst. */ - out = kzalloc(sizeof(*out), GFP_KERNEL); + out = kzalloc_obj(*out); return &out->inst; } diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index 467d00044a2f..719217399a30 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -21,8 +21,8 @@ int iris_vdec_inst_init(struct iris_inst *inst) struct iris_core *core = inst->core; struct v4l2_format *f; - inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); - inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); + inst->fmt_src = kzalloc_obj(*inst->fmt_src); + inst->fmt_dst = kzalloc_obj(*inst->fmt_dst); inst->fw_min_count = MIN_BUFFERS; diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c index 6461d9c9d598..aa27b22704eb 100644 --- a/drivers/media/platform/qcom/iris/iris_venc.c +++ b/drivers/media/platform/qcom/iris/iris_venc.c @@ -19,8 +19,8 @@ int iris_venc_inst_init(struct iris_inst *inst) struct iris_core *core = inst->core; struct v4l2_format *f; - inst->fmt_src = kzalloc(sizeof(*inst->fmt_src), GFP_KERNEL); - inst->fmt_dst = kzalloc(sizeof(*inst->fmt_dst), GFP_KERNEL); + inst->fmt_src = kzalloc_obj(*inst->fmt_src); + inst->fmt_dst = kzalloc_obj(*inst->fmt_dst); if (!inst->fmt_src || !inst->fmt_dst) { kfree(inst->fmt_src); kfree(inst->fmt_dst); diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 24d2b2fd0340..7e639760c41d 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -213,7 +213,7 @@ static int venus_enumerate_codecs(struct venus_core *core, u32 type) if (core->res->hfi_version != HFI_VERSION_1XX) return 0; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; @@ -329,7 +329,7 @@ static int venus_add_dynamic_nodes(struct venus_core *core) struct device *dev = core->dev; int ret; - core->ocs = kmalloc(sizeof(*core->ocs), GFP_KERNEL); + core->ocs = kmalloc_obj(*core->ocs); if (!core->ocs) return -ENOMEM; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 2e4363f82231..747c388fe25f 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -192,7 +192,7 @@ int venus_helper_alloc_dpb_bufs(struct venus_inst *inst) count = hfi_bufreq_get_count_min(&bufreq, ver); for (i = 0; i < count; i++) { - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) { ret = -ENOMEM; goto fail; @@ -248,7 +248,7 @@ static int intbufs_set_buffer(struct venus_inst *inst, u32 type) return 0; for (i = 0; i < bufreq.count_actual; i++) { - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) { ret = -ENOMEM; goto fail; diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c index d3da35f67fd5..bd82066bb6e7 100644 --- a/drivers/media/platform/qcom/venus/hfi_venus.c +++ b/drivers/media/platform/qcom/venus/hfi_venus.c @@ -1702,7 +1702,7 @@ int venus_hfi_create(struct venus_core *core) struct venus_hfi_device *hdev; int ret; - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); + hdev = kzalloc_obj(*hdev); if (!hdev) return -ENOMEM; diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 21ca4947a849..daa8f56610c7 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -1684,7 +1684,7 @@ static int vdec_open(struct file *file) struct venus_inst *inst; int ret; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index 0b5843ba536f..bf53267cb68d 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -1466,7 +1466,7 @@ static int venc_open(struct file *file) struct venus_inst *inst; int ret; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c index 62dca76b468d..8375ed3e97b9 100644 --- a/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c +++ b/drivers/media/platform/raspberrypi/rp1-cfe/cfe.c @@ -2279,7 +2279,7 @@ static int cfe_probe(struct platform_device *pdev) char debugfs_name[32]; int ret; - cfe = kzalloc(sizeof(*cfe), GFP_KERNEL); + cfe = kzalloc_obj(*cfe); if (!cfe) return -ENOMEM; diff --git a/drivers/media/platform/renesas/rcar-vin/rcar-core.c b/drivers/media/platform/renesas/rcar-vin/rcar-core.c index 100105b620e3..c8d564aa1eba 100644 --- a/drivers/media/platform/renesas/rcar-vin/rcar-core.c +++ b/drivers/media/platform/renesas/rcar-vin/rcar-core.c @@ -128,7 +128,7 @@ static int rvin_group_get(struct rvin_dev *vin, group = rvin_group_data; kref_get(&group->refcount); } else { - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) { ret = -ENOMEM; goto err_group; diff --git a/drivers/media/platform/renesas/rcar_fdp1.c b/drivers/media/platform/renesas/rcar_fdp1.c index 672869815f63..013e0666170a 100644 --- a/drivers/media/platform/renesas/rcar_fdp1.c +++ b/drivers/media/platform/renesas/rcar_fdp1.c @@ -2078,7 +2078,7 @@ static int fdp1_open(struct file *file) if (mutex_lock_interruptible(&fdp1->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto done; diff --git a/drivers/media/platform/renesas/rcar_jpu.c b/drivers/media/platform/renesas/rcar_jpu.c index a6d26b446494..93d54325e420 100644 --- a/drivers/media/platform/renesas/rcar_jpu.c +++ b/drivers/media/platform/renesas/rcar_jpu.c @@ -1212,7 +1212,7 @@ static int jpu_open(struct file *file) struct jpu_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/renesas/renesas-ceu.c b/drivers/media/platform/renesas/renesas-ceu.c index deed49d0fb10..65f7659a9e02 100644 --- a/drivers/media/platform/renesas/renesas-ceu.c +++ b/drivers/media/platform/renesas/renesas-ceu.c @@ -1616,7 +1616,7 @@ static int ceu_probe(struct platform_device *pdev) int num_subdevs; int ret; - ceudev = kzalloc(sizeof(*ceudev), GFP_KERNEL); + ceudev = kzalloc_obj(*ceudev); if (!ceudev) return -ENOMEM; diff --git a/drivers/media/platform/renesas/vsp1/vsp1_dl.c b/drivers/media/platform/renesas/vsp1/vsp1_dl.c index d732b4ed1180..6c5578d9d2de 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_dl.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_dl.c @@ -259,7 +259,7 @@ vsp1_dl_body_pool_create(struct vsp1_device *vsp1, unsigned int num_bodies, size_t dlb_size; unsigned int i; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -274,7 +274,7 @@ vsp1_dl_body_pool_create(struct vsp1_device *vsp1, unsigned int num_bodies, dlb_size = num_entries * sizeof(struct vsp1_dl_entry) + extra_size; pool->size = dlb_size * num_bodies; - pool->bodies = kcalloc(num_bodies, sizeof(*pool->bodies), GFP_KERNEL); + pool->bodies = kzalloc_objs(*pool->bodies, num_bodies); if (!pool->bodies) { kfree(pool); return NULL; @@ -434,7 +434,7 @@ vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type, unsigned int i; size_t cmd_size; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -443,7 +443,7 @@ vsp1_dl_cmd_pool_create(struct vsp1_device *vsp1, enum vsp1_extcmd_type type, spin_lock_init(&pool->lock); INIT_LIST_HEAD(&pool->free); - pool->cmds = kcalloc(num_cmds, sizeof(*pool->cmds), GFP_KERNEL); + pool->cmds = kzalloc_objs(*pool->cmds, num_cmds); if (!pool->cmds) { kfree(pool); return NULL; @@ -557,7 +557,7 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm) struct vsp1_dl_list *dl; size_t header_offset; - dl = kzalloc(sizeof(*dl), GFP_KERNEL); + dl = kzalloc_obj(*dl); if (!dl) return NULL; diff --git a/drivers/media/platform/renesas/vsp1/vsp1_video.c b/drivers/media/platform/renesas/vsp1/vsp1_video.c index 75f9a1a85d55..fe1dac11d4ae 100644 --- a/drivers/media/platform/renesas/vsp1/vsp1_video.c +++ b/drivers/media/platform/renesas/vsp1/vsp1_video.c @@ -565,7 +565,7 @@ static struct vsp1_pipeline *vsp1_video_pipeline_get(struct vsp1_video *video) * when the last reference is released. */ if (!video->rwpf->entity.pipe) { - pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); + pipe = kzalloc_obj(*pipe); if (!pipe) return ERR_PTR(-ENOMEM); @@ -720,8 +720,7 @@ static int vsp1_video_pipeline_setup_partitions(struct vsp1_pipeline *pipe) } pipe->partitions = DIV_ROUND_UP(format->width, div_size); - pipe->part_table = kcalloc(pipe->partitions, sizeof(*pipe->part_table), - GFP_KERNEL); + pipe->part_table = kzalloc_objs(*pipe->part_table, pipe->partitions); if (!pipe->part_table) return -ENOMEM; @@ -1074,7 +1073,7 @@ static int vsp1_video_open(struct file *file) struct v4l2_fh *vfh; int ret = 0; - vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); + vfh = kzalloc_obj(*vfh); if (vfh == NULL) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 43f6a8d99381..fea63b94c5f3 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -370,7 +370,7 @@ static int rga_open(struct file *file) struct rga_ctx *ctx = NULL; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->rga = rga; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c index a1af12c97914..d3202cecb988 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-h264.c @@ -375,7 +375,7 @@ static int rkvdec_h264_start(struct rkvdec_ctx *ctx) if (ret) return ret; - h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); + h264_ctx = kzalloc_obj(*h264_ctx); if (!h264_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c index 3276f584f5c7..ac8b825d080a 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c @@ -528,7 +528,7 @@ static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) struct rkvdec_hevc_priv_tbl *priv_tbl; struct rkvdec_hevc_ctx *hevc_ctx; - hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL); + hevc_ctx = kzalloc_obj(*hevc_ctx); if (!hevc_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c index cd0aa3f3a13d..b961fddc8583 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-h264.c @@ -383,7 +383,7 @@ static int rkvdec_h264_start(struct rkvdec_ctx *ctx) if (ret) return ret; - h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); + h264_ctx = kzalloc_obj(*h264_ctx); if (!h264_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c index 5f1c11ffb9f0..fe6414a17551 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c @@ -551,7 +551,7 @@ static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) if (ret) return ret; - hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL); + hevc_ctx = kzalloc_obj(*hevc_ctx); if (!hevc_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c index 6ab3167addc8..97f1efde2e47 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-h264.c @@ -447,7 +447,7 @@ static int rkvdec_h264_start(struct rkvdec_ctx *ctx) if (ret) return ret; - h264_ctx = kzalloc(sizeof(*h264_ctx), GFP_KERNEL); + h264_ctx = kzalloc_obj(*h264_ctx); if (!h264_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c index 085c0a63a80c..96d938ee70b0 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu383-hevc.c @@ -559,7 +559,7 @@ static int rkvdec_hevc_start(struct rkvdec_ctx *ctx) if (ret) return ret; - hevc_ctx = kzalloc(sizeof(*hevc_ctx), GFP_KERNEL); + hevc_ctx = kzalloc_obj(*hevc_ctx); if (!hevc_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c index ba51a7c2fe55..e4cdd2122873 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vp9.c @@ -971,7 +971,7 @@ static int rkvdec_vp9_start(struct rkvdec_ctx *ctx) unsigned char *count_tbl; int ret; - vp9_ctx = kzalloc(sizeof(*vp9_ctx), GFP_KERNEL); + vp9_ctx = kzalloc_obj(*vp9_ctx); if (!vp9_ctx) return -ENOMEM; diff --git a/drivers/media/platform/rockchip/rkvdec/rkvdec.c b/drivers/media/platform/rockchip/rkvdec/rkvdec.c index 967c452ab61f..1d1e9bfef8e9 100644 --- a/drivers/media/platform/rockchip/rkvdec/rkvdec.c +++ b/drivers/media/platform/rockchip/rkvdec/rkvdec.c @@ -1282,7 +1282,7 @@ static int rkvdec_open(struct file *filp) struct rkvdec_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c b/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c index 722e2531e23f..3c7cc00c9803 100644 --- a/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c +++ b/drivers/media/platform/samsung/exynos-gsc/gsc-m2m.c @@ -612,7 +612,7 @@ static int gsc_m2m_open(struct file *file) if (mutex_lock_interruptible(&gsc->lock)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto unlock; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c index 5b412afd7d60..d85811f4b8c5 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-capture.c @@ -1718,7 +1718,7 @@ static int fimc_register_capture_device(struct fimc_dev *fimc, struct fimc_ctx *ctx; int ret = -ENOMEM; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c index 562c57f186c6..81deafecf1d7 100644 --- a/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/samsung/exynos4-is/fimc-m2m.c @@ -616,7 +616,7 @@ static int fimc_m2m_open(struct file *file) if (test_bit(ST_CAPT_BUSY, &fimc->state)) goto unlock; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto unlock; diff --git a/drivers/media/platform/samsung/exynos4-is/media-dev.c b/drivers/media/platform/samsung/exynos4-is/media-dev.c index bc7087eb761a..2e08c4435859 100644 --- a/drivers/media/platform/samsung/exynos4-is/media-dev.c +++ b/drivers/media/platform/samsung/exynos4-is/media-dev.c @@ -373,7 +373,7 @@ static struct exynos_media_pipeline *fimc_md_pipeline_create( { struct fimc_pipeline *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return NULL; diff --git a/drivers/media/platform/samsung/s5p-g2d/g2d.c b/drivers/media/platform/samsung/s5p-g2d/g2d.c index e765dfcc2830..a18b13db19d5 100644 --- a/drivers/media/platform/samsung/s5p-g2d/g2d.c +++ b/drivers/media/platform/samsung/s5p-g2d/g2d.c @@ -237,7 +237,7 @@ static int g2d_open(struct file *file) struct g2d_ctx *ctx = NULL; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->dev = dev; diff --git a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c index ff28482759ec..fdc9d7e0be66 100644 --- a/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/samsung/s5p-jpeg/jpeg-core.c @@ -953,7 +953,7 @@ static int s5p_jpeg_open(struct file *file) struct s5p_jpeg_fmt *out_fmt, *cap_fmt; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c index 4948d734eb02..32eb402d439c 100644 --- a/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c +++ b/drivers/media/platform/samsung/s5p-mfc/s5p_mfc.c @@ -794,7 +794,7 @@ static int s5p_mfc_open(struct file *file) } dev->num_inst++; /* It is guarded by mfc_mutex in vfd */ /* Allocate memory for context */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto err_alloc; diff --git a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c index 56169b70652d..ee6d686cba49 100644 --- a/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/st/sti/bdisp/bdisp-v4l2.c @@ -583,7 +583,7 @@ static int bdisp_open(struct file *file) return -ERESTARTSYS; /* Allocate memory for both context and node */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto unlock; diff --git a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c index a078f1107300..58a529ed8d95 100644 --- a/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c +++ b/drivers/media/platform/st/sti/delta/delta-mjpeg-dec.c @@ -324,7 +324,7 @@ static int delta_mjpeg_open(struct delta_ctx *pctx) { struct delta_mjpeg_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; pctx->priv = ctx; diff --git a/drivers/media/platform/st/sti/delta/delta-v4l2.c b/drivers/media/platform/st/sti/delta/delta-v4l2.c index 6c1a53c771f7..7dd27de37b78 100644 --- a/drivers/media/platform/st/sti/delta/delta-v4l2.c +++ b/drivers/media/platform/st/sti/delta/delta-v4l2.c @@ -164,7 +164,7 @@ static void delta_push_dts(struct delta_ctx *ctx, u64 val) { struct delta_dts *dts; - dts = kzalloc(sizeof(*dts), GFP_KERNEL); + dts = kzalloc_obj(*dts); if (!dts) return; @@ -1629,7 +1629,7 @@ static int delta_open(struct file *file) mutex_lock(&delta->lock); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto err; diff --git a/drivers/media/platform/st/sti/hva/hva-v4l2.c b/drivers/media/platform/st/sti/hva/hva-v4l2.c index 3581b73a99b8..645e4f155dd0 100644 --- a/drivers/media/platform/st/sti/hva/hva-v4l2.c +++ b/drivers/media/platform/st/sti/hva/hva-v4l2.c @@ -1165,7 +1165,7 @@ static int hva_open(struct file *file) struct hva_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { ret = -ENOMEM; goto out; diff --git a/drivers/media/platform/st/stm32/dma2d/dma2d.c b/drivers/media/platform/st/stm32/dma2d/dma2d.c index 72488aa922fc..a3ad19256859 100644 --- a/drivers/media/platform/st/stm32/dma2d/dma2d.c +++ b/drivers/media/platform/st/stm32/dma2d/dma2d.c @@ -280,7 +280,7 @@ static int dma2d_open(struct file *file) struct dma2d_ctx *ctx = NULL; int ret = 0; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->dev = dev; diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c index 19e6b187be22..a42f43d19f9e 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-bytecap.c @@ -867,7 +867,7 @@ struct dcmipp_ent_device *dcmipp_bytecap_ent_init(struct device *dev, int ret = 0; /* Allocate the dcmipp_bytecap_device struct */ - vcap = kzalloc(sizeof(*vcap), GFP_KERNEL); + vcap = kzalloc_obj(*vcap); if (!vcap) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c index f9e4a3a9ef3f..0c7aeb0888f6 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-byteproc.c @@ -581,7 +581,7 @@ dcmipp_byteproc_ent_init(struct device *dev, const char *entity_name, int ret; /* Allocate the byteproc struct */ - byteproc = kzalloc(sizeof(*byteproc), GFP_KERNEL); + byteproc = kzalloc_obj(*byteproc); if (!byteproc) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.c index 562933e08d62..99bcb2a71f77 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-common.c @@ -20,7 +20,7 @@ struct media_pad *dcmipp_pads_init(u16 num_pads, const unsigned long *pads_flags unsigned int i; /* Allocate memory for the pads */ - pads = kcalloc(num_pads, sizeof(*pads), GFP_KERNEL); + pads = kzalloc_objs(*pads, num_pads); if (!pads) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c index c4bc76909b1c..7d3f5857cbfe 100644 --- a/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c +++ b/drivers/media/platform/st/stm32/stm32-dcmipp/dcmipp-input.c @@ -527,7 +527,7 @@ struct dcmipp_ent_device *dcmipp_inp_ent_init(struct device *dev, int ret; /* Allocate the inp struct */ - inp = kzalloc(sizeof(*inp), GFP_KERNEL); + inp = kzalloc_obj(*inp); if (!inp) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c index 7c4dd1ac772d..f4075576ef1d 100644 --- a/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c +++ b/drivers/media/platform/sunxi/sun8i-di/sun8i-di.c @@ -709,7 +709,7 @@ static int deinterlace_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { mutex_unlock(&dev->dev_mutex); return -ENOMEM; diff --git a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c index 2deab920884a..12e438c678f9 100644 --- a/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c +++ b/drivers/media/platform/sunxi/sun8i-rotate/sun8i_rotate.c @@ -642,7 +642,7 @@ static int rotate_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { mutex_unlock(&dev->dev_mutex); return -ENOMEM; diff --git a/drivers/media/platform/ti/cal/cal.c b/drivers/media/platform/ti/cal/cal.c index 3e25ce0c3c3b..b7e77b6b8950 100644 --- a/drivers/media/platform/ti/cal/cal.c +++ b/drivers/media/platform/ti/cal/cal.c @@ -1012,7 +1012,7 @@ static struct cal_ctx *cal_ctx_create(struct cal_dev *cal, int inst) struct cal_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; diff --git a/drivers/media/platform/ti/davinci/vpif.c b/drivers/media/platform/ti/davinci/vpif.c index 969d623fc842..cc0b0b8cdb89 100644 --- a/drivers/media/platform/ti/davinci/vpif.c +++ b/drivers/media/platform/ti/davinci/vpif.c @@ -450,7 +450,7 @@ static int vpif_probe(struct platform_device *pdev) if (IS_ERR(vpif_base)) return PTR_ERR(vpif_base); - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -482,7 +482,7 @@ static int vpif_probe(struct platform_device *pdev) res_irq = DEFINE_RES_IRQ_NAMED(irq, of_node_full_name(pdev->dev.of_node)); res_irq.flags |= irq_get_trigger_type(irq); - pdev_capture = kzalloc(sizeof(*pdev_capture), GFP_KERNEL); + pdev_capture = kzalloc_obj(*pdev_capture); if (!pdev_capture) { ret = -ENOMEM; goto err_put_rpm; @@ -501,7 +501,7 @@ static int vpif_probe(struct platform_device *pdev) if (ret) goto err_put_pdev_capture; - pdev_display = kzalloc(sizeof(*pdev_display), GFP_KERNEL); + pdev_display = kzalloc_obj(*pdev_display); if (!pdev_display) { ret = -ENOMEM; goto err_del_pdev_capture; diff --git a/drivers/media/platform/ti/davinci/vpif_capture.c b/drivers/media/platform/ti/davinci/vpif_capture.c index 243c6196b024..15df3ea2f77e 100644 --- a/drivers/media/platform/ti/davinci/vpif_capture.c +++ b/drivers/media/platform/ti/davinci/vpif_capture.c @@ -1335,8 +1335,7 @@ static int initialize_vpif(void) /* Allocate memory for six channel objects */ for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { - vpif_obj.dev[i] = - kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL); + vpif_obj.dev[i] = kzalloc_obj(*vpif_obj.dev[i]); /* If memory allocation fails, return error */ if (!vpif_obj.dev[i]) { free_channel_objects_index = i; @@ -1651,7 +1650,7 @@ static int vpif_probe(struct platform_device *pdev) vpif_obj.config = pdev->dev.platform_data; subdev_count = vpif_obj.config->subdev_count; - vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); + vpif_obj.sd = kzalloc_objs(*vpif_obj.sd, subdev_count); if (!vpif_obj.sd) { err = -ENOMEM; goto probe_subdev_out; diff --git a/drivers/media/platform/ti/davinci/vpif_display.c b/drivers/media/platform/ti/davinci/vpif_display.c index 1e7815e9f8e0..08877ae1513a 100644 --- a/drivers/media/platform/ti/davinci/vpif_display.c +++ b/drivers/media/platform/ti/davinci/vpif_display.c @@ -1089,7 +1089,7 @@ static int initialize_vpif(void) /* Allocate memory for six channel objects */ for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { vpif_obj.dev[i] = - kzalloc(sizeof(struct channel_obj), GFP_KERNEL); + kzalloc_obj(struct channel_obj); /* If memory allocation fails, return error */ if (!vpif_obj.dev[i]) { free_channel_objects_index = i; @@ -1264,7 +1264,7 @@ static int vpif_probe(struct platform_device *pdev) vpif_obj.config = pdev->dev.platform_data; subdev_count = vpif_obj.config->subdev_count; subdevdata = vpif_obj.config->subdevinfo; - vpif_obj.sd = kcalloc(subdev_count, sizeof(*vpif_obj.sd), GFP_KERNEL); + vpif_obj.sd = kzalloc_objs(*vpif_obj.sd, subdev_count); if (!vpif_obj.sd) { err = -ENOMEM; goto vpif_unregister; diff --git a/drivers/media/platform/ti/omap/omap_vout.c b/drivers/media/platform/ti/omap/omap_vout.c index 22782e9f1f4e..8d0319a37ba8 100644 --- a/drivers/media/platform/ti/omap/omap_vout.c +++ b/drivers/media/platform/ti/omap/omap_vout.c @@ -1452,7 +1452,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) for (k = 0; k < pdev->num_resources; k++) { - vout = kzalloc(sizeof(struct omap_vout_device), GFP_KERNEL); + vout = kzalloc_obj(struct omap_vout_device); if (!vout) { dev_err(&pdev->dev, ": could not allocate memory\n"); return -ENOMEM; @@ -1611,7 +1611,7 @@ static int __init omap_vout_probe(struct platform_device *pdev) goto err_dss_init; } - vid_dev = kzalloc(sizeof(struct omap2video_device), GFP_KERNEL); + vid_dev = kzalloc_obj(struct omap2video_device); if (vid_dev == NULL) { ret = -ENOMEM; goto err_dss_init; diff --git a/drivers/media/platform/ti/omap3isp/isp.c b/drivers/media/platform/ti/omap3isp/isp.c index 8ac2bdcdf87b..8214f8ef2da8 100644 --- a/drivers/media/platform/ti/omap3isp/isp.c +++ b/drivers/media/platform/ti/omap3isp/isp.c @@ -2231,7 +2231,7 @@ static int isp_probe(struct platform_device *pdev) int ret; int i, m; - isp = kzalloc(sizeof(*isp), GFP_KERNEL); + isp = kzalloc_obj(*isp); if (!isp) { dev_err(&pdev->dev, "could not allocate memory\n"); return -ENOMEM; diff --git a/drivers/media/platform/ti/omap3isp/ispccdc.c b/drivers/media/platform/ti/omap3isp/ispccdc.c index 9dbf06ac058d..4708b6303493 100644 --- a/drivers/media/platform/ti/omap3isp/ispccdc.c +++ b/drivers/media/platform/ti/omap3isp/ispccdc.c @@ -419,7 +419,7 @@ static int ccdc_lsc_config(struct isp_ccdc_device *ccdc, return -EINVAL; } - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (req == NULL) return -ENOMEM; diff --git a/drivers/media/platform/ti/omap3isp/isph3a_aewb.c b/drivers/media/platform/ti/omap3isp/isph3a_aewb.c index ae93da9c4542..6674718dffc8 100644 --- a/drivers/media/platform/ti/omap3isp/isph3a_aewb.c +++ b/drivers/media/platform/ti/omap3isp/isph3a_aewb.c @@ -291,7 +291,7 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp) struct omap3isp_h3a_aewb_config *aewb_recover_cfg = NULL; int ret; - aewb_cfg = kzalloc(sizeof(*aewb_cfg), GFP_KERNEL); + aewb_cfg = kzalloc_obj(*aewb_cfg); if (!aewb_cfg) return -ENOMEM; @@ -301,7 +301,7 @@ int omap3isp_h3a_aewb_init(struct isp_device *isp) aewb->isp = isp; /* Set recover state configuration */ - aewb_recover_cfg = kzalloc(sizeof(*aewb_recover_cfg), GFP_KERNEL); + aewb_recover_cfg = kzalloc_obj(*aewb_recover_cfg); if (!aewb_recover_cfg) { dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for recover configuration.\n"); diff --git a/drivers/media/platform/ti/omap3isp/isph3a_af.c b/drivers/media/platform/ti/omap3isp/isph3a_af.c index ca478da4ad34..52fb4122a3b4 100644 --- a/drivers/media/platform/ti/omap3isp/isph3a_af.c +++ b/drivers/media/platform/ti/omap3isp/isph3a_af.c @@ -354,7 +354,7 @@ int omap3isp_h3a_af_init(struct isp_device *isp) struct omap3isp_h3a_af_config *af_recover_cfg = NULL; int ret; - af_cfg = kzalloc(sizeof(*af_cfg), GFP_KERNEL); + af_cfg = kzalloc_obj(*af_cfg); if (af_cfg == NULL) return -ENOMEM; @@ -364,7 +364,7 @@ int omap3isp_h3a_af_init(struct isp_device *isp) af->isp = isp; /* Set recover state configuration */ - af_recover_cfg = kzalloc(sizeof(*af_recover_cfg), GFP_KERNEL); + af_recover_cfg = kzalloc_obj(*af_recover_cfg); if (!af_recover_cfg) { dev_err(af->isp->dev, "AF: cannot allocate memory for recover configuration.\n"); diff --git a/drivers/media/platform/ti/omap3isp/isphist.c b/drivers/media/platform/ti/omap3isp/isphist.c index 7851ad13d84f..fbfdcbfdb050 100644 --- a/drivers/media/platform/ti/omap3isp/isphist.c +++ b/drivers/media/platform/ti/omap3isp/isphist.c @@ -477,7 +477,7 @@ int omap3isp_hist_init(struct isp_device *isp) struct omap3isp_hist_config *hist_cfg; int ret; - hist_cfg = kzalloc(sizeof(*hist_cfg), GFP_KERNEL); + hist_cfg = kzalloc_obj(*hist_cfg); if (hist_cfg == NULL) return -ENOMEM; diff --git a/drivers/media/platform/ti/omap3isp/ispstat.c b/drivers/media/platform/ti/omap3isp/ispstat.c index 64bc71d830c4..63faa3d305dc 100644 --- a/drivers/media/platform/ti/omap3isp/ispstat.c +++ b/drivers/media/platform/ti/omap3isp/ispstat.c @@ -1047,7 +1047,7 @@ int omap3isp_stat_init(struct ispstat *stat, const char *name, { int ret; - stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL); + stat->buf = kzalloc_objs(*stat->buf, STAT_MAX_BUFS); if (!stat->buf) return -ENOMEM; diff --git a/drivers/media/platform/ti/omap3isp/ispvideo.c b/drivers/media/platform/ti/omap3isp/ispvideo.c index 86cb27b6ca4e..64e76e3576a8 100644 --- a/drivers/media/platform/ti/omap3isp/ispvideo.c +++ b/drivers/media/platform/ti/omap3isp/ispvideo.c @@ -1371,7 +1371,7 @@ static int isp_video_open(struct file *file) struct vb2_queue *queue; int ret = 0; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (handle == NULL) return -ENOMEM; diff --git a/drivers/media/platform/ti/vpe/vip.c b/drivers/media/platform/ti/vpe/vip.c index d4236ac6d867..a4b616a5ece7 100644 --- a/drivers/media/platform/ti/vpe/vip.c +++ b/drivers/media/platform/ti/vpe/vip.c @@ -3035,7 +3035,7 @@ static int alloc_stream(struct vip_port *port, int stream_id, int vfl_type) struct list_head *pos, *tmp; int ret, i; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; @@ -3079,7 +3079,7 @@ static int alloc_stream(struct vip_port *port, int stream_id, int vfl_type) /* Allocate/populate Drop queue entries */ INIT_LIST_HEAD(&stream->dropq); for (i = 0; i < VIP_DROPQ_SIZE; i++) { - buf = kzalloc(sizeof(*buf), GFP_ATOMIC); + buf = kzalloc_obj(*buf, GFP_ATOMIC); if (!buf) { ret = -ENOMEM; goto do_free_dropq; diff --git a/drivers/media/platform/ti/vpe/vpe.c b/drivers/media/platform/ti/vpe/vpe.c index 1a549775cabe..a7e5a85e72a1 100644 --- a/drivers/media/platform/ti/vpe/vpe.c +++ b/drivers/media/platform/ti/vpe/vpe.c @@ -2272,7 +2272,7 @@ static int vpe_open(struct file *file) vpe_dbg(dev, "vpe_open\n"); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/verisilicon/hantro_drv.c b/drivers/media/platform/verisilicon/hantro_drv.c index 94f58f4e4a4e..2e81877f640f 100644 --- a/drivers/media/platform/verisilicon/hantro_drv.c +++ b/drivers/media/platform/verisilicon/hantro_drv.c @@ -640,7 +640,7 @@ static int hantro_open(struct file *filp) * helper functions used here. */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/media/platform/via/via-camera.c b/drivers/media/platform/via/via-camera.c index 5702eff664d4..1b81acba7da0 100644 --- a/drivers/media/platform/via/via-camera.c +++ b/drivers/media/platform/via/via-camera.c @@ -1164,7 +1164,7 @@ static int viacam_probe(struct platform_device *pdev) /* * Basic structure initialization. */ - cam = kzalloc (sizeof(struct via_camera), GFP_KERNEL); + cam = kzalloc_obj(struct via_camera); if (cam == NULL) return -ENOMEM; via_cam_info = cam; diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c index 9a45cda05779..b8e0835a1998 100644 --- a/drivers/media/radio/dsbr100.c +++ b/drivers/media/radio/dsbr100.c @@ -338,7 +338,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf, struct v4l2_device *v4l2_dev; int retval; - radio = kzalloc(sizeof(struct dsbr100_device), GFP_KERNEL); + radio = kzalloc_obj(struct dsbr100_device); if (!radio) return -ENOMEM; diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 2c1d413e8636..1395f76b01dd 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c @@ -67,7 +67,7 @@ struct rtrack { static struct radio_isa_card *rtrack_alloc(void) { - struct rtrack *rt = kzalloc(sizeof(struct rtrack), GFP_KERNEL); + struct rtrack *rt = kzalloc_obj(struct rtrack); if (rt) rt->curvol = 0xff; diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index 0a4667bb7034..175ef2b0c6f4 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c @@ -82,7 +82,7 @@ static void aztech_set_pins(void *handle, u8 pins) static struct radio_isa_card *aztech_alloc(void) { - struct aztech *az = kzalloc(sizeof(*az), GFP_KERNEL); + struct aztech *az = kzalloc_obj(*az); return az ? &az->isa : NULL; } diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index a3265f1dd189..3d1d0b46195b 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c @@ -179,7 +179,7 @@ static unsigned long gemtek_convfreq(unsigned long freq) static struct radio_isa_card *gemtek_alloc(void) { - struct gemtek *gt = kzalloc(sizeof(*gt), GFP_KERNEL); + struct gemtek *gt = kzalloc_obj(*gt); if (gt) gt->muted = true; diff --git a/drivers/media/radio/radio-keene.c b/drivers/media/radio/radio-keene.c index c133305fd019..8cfef3a778cf 100644 --- a/drivers/media/radio/radio-keene.c +++ b/drivers/media/radio/radio-keene.c @@ -311,7 +311,7 @@ static int usb_keene_probe(struct usb_interface *intf, if (dev->product && strcmp(dev->product, "B-LINK USB Audio ")) return -ENODEV; - radio = kzalloc(sizeof(struct keene_device), GFP_KERNEL); + radio = kzalloc_obj(struct keene_device); if (radio) radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); diff --git a/drivers/media/radio/radio-ma901.c b/drivers/media/radio/radio-ma901.c index 657c3dda6648..11c5d103c4c5 100644 --- a/drivers/media/radio/radio-ma901.c +++ b/drivers/media/radio/radio-ma901.c @@ -346,7 +346,7 @@ static int usb_ma901radio_probe(struct usb_interface *intf, || strncmp(dev->manufacturer, "www.masterkit.ru", 16) != 0)) return -ENODEV; - radio = kzalloc(sizeof(struct ma901radio_device), GFP_KERNEL); + radio = kzalloc_obj(struct ma901radio_device); if (!radio) { dev_err(&intf->dev, "kzalloc for ma901radio_device failed\n"); retval = -ENOMEM; diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 1a5dbae24ef4..8ab1dacf89aa 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -122,7 +122,7 @@ static int maxiradio_probe(struct pci_dev *pdev, struct v4l2_device *v4l2_dev; int retval = -ENOMEM; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { dev_err(&pdev->dev, "not enough memory\n"); return -ENOMEM; diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c index cb0437b4c331..d5a6053e1d53 100644 --- a/drivers/media/radio/radio-mr800.c +++ b/drivers/media/radio/radio-mr800.c @@ -501,7 +501,7 @@ static int usb_amradio_probe(struct usb_interface *intf, struct amradio_device *radio; int retval; - radio = kzalloc(sizeof(struct amradio_device), GFP_KERNEL); + radio = kzalloc_obj(struct amradio_device); if (!radio) { dev_err(&intf->dev, "kmalloc for amradio_device failed\n"); diff --git a/drivers/media/radio/radio-raremono.c b/drivers/media/radio/radio-raremono.c index f60775b005e1..6aa7c09780f4 100644 --- a/drivers/media/radio/radio-raremono.c +++ b/drivers/media/radio/radio-raremono.c @@ -301,7 +301,7 @@ static int usb_raremono_probe(struct usb_interface *intf, struct raremono_device *radio; int retval = 0; - radio = kzalloc(sizeof(*radio), GFP_KERNEL); + radio = kzalloc_obj(*radio); if (!radio) return -ENOMEM; radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index efc02069bf9d..2891446901a0 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c @@ -47,7 +47,7 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); static struct radio_isa_card *rtrack2_alloc(void) { - return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL); + return kzalloc_obj(struct radio_isa_card); } static void zero(struct radio_isa_card *isa) diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index d0dde55b7930..2cc91e576fcd 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -252,7 +252,7 @@ static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) static int fmr2_isa_match(struct device *pdev, unsigned int ndev) { - struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); + struct fmr2 *fmr2 = kzalloc_obj(*fmr2); if (!fmr2) return 0; @@ -269,7 +269,7 @@ static int fmr2_isa_match(struct device *pdev, unsigned int ndev) static int fmr2_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id) { int ret; - struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); + struct fmr2 *fmr2 = kzalloc_obj(*fmr2); if (!fmr2) return -ENOMEM; diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index 127a3be0e0f0..c1f356c5f41e 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c @@ -327,7 +327,7 @@ static int usb_shark_probe(struct usb_interface *intf, return -EINVAL; } - shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); + shark = kzalloc_obj(struct shark_device); if (!shark) return retval; diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index e3e6aa87fe08..7cc173e21074 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c @@ -293,7 +293,7 @@ static int usb_shark_probe(struct usb_interface *intf, return -EINVAL; } - shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); + shark = kzalloc_obj(struct shark_device); if (!shark) return retval; diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index dd85b0b1bcd9..156cca2866aa 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c @@ -420,7 +420,7 @@ static int tea5764_i2c_probe(struct i2c_client *client) int ret; PDEBUG("probe"); - radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL); + radio = kzalloc_obj(struct tea5764_device); if (!radio) return -ENOMEM; diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index 43817dd0a0fe..9231a19d5544 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c @@ -56,7 +56,7 @@ MODULE_PARM_DESC(radio_nr, "Radio device number"); static struct radio_isa_card *terratec_alloc(void) { - return kzalloc(sizeof(struct radio_isa_card), GFP_KERNEL); + return kzalloc_obj(struct radio_isa_card); } static int terratec_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol) diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index dfb8b62f0e2b..c7b30d430a70 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c @@ -55,7 +55,7 @@ struct trust { static struct radio_isa_card *trust_alloc(void) { - struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL); + struct trust *tr = kzalloc_obj(*tr); return tr ? &tr->isa : NULL; } diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index 1aa856df70df..3454c9a6fda3 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c @@ -75,7 +75,7 @@ struct typhoon { static struct radio_isa_card *typhoon_alloc(void) { - struct typhoon *ty = kzalloc(sizeof(*ty), GFP_KERNEL); + struct typhoon *ty = kzalloc_obj(*ty); return ty ? &ty->isa : NULL; } diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index e043bee52384..b92b249737a4 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c @@ -79,7 +79,7 @@ struct zoltrix { static struct radio_isa_card *zoltrix_alloc(void) { - struct zoltrix *zol = kzalloc(sizeof(*zol), GFP_KERNEL); + struct zoltrix *zol = kzalloc_obj(*zol); return zol ? &zol->isa : NULL; } diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c index d9eecddffd91..9572a866defb 100644 --- a/drivers/media/radio/saa7706h.c +++ b/drivers/media/radio/saa7706h.c @@ -344,7 +344,7 @@ static int saa7706h_probe(struct i2c_client *client) v4l_info(client, "chip found @ 0x%02x (%s)\n", client->addr << 1, client->adapter->name); - state = kzalloc(sizeof(struct saa7706h_state), GFP_KERNEL); + state = kzalloc_obj(struct saa7706h_state); if (state == NULL) return -ENOMEM; sd = &state->sd; diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index aa7a580dbecc..318b5f6d4202 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c @@ -570,7 +570,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf, unsigned char version_warning = 0; /* private data allocation and initialization */ - radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); + radio = kzalloc_obj(struct si470x_device); if (!radio) { retval = -ENOMEM; goto err_initial; diff --git a/drivers/media/radio/si4713/radio-usb-si4713.c b/drivers/media/radio/si4713/radio-usb-si4713.c index 2cf36c8abdde..6e6764143e21 100644 --- a/drivers/media/radio/si4713/radio-usb-si4713.c +++ b/drivers/media/radio/si4713/radio-usb-si4713.c @@ -420,7 +420,7 @@ static int usb_si4713_probe(struct usb_interface *intf, id->idVendor, id->idProduct); /* Initialize local device structure */ - radio = kzalloc(sizeof(struct si4713_usb_device), GFP_KERNEL); + radio = kzalloc_obj(struct si4713_usb_device); if (radio) radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL); diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index b00ccf651922..3a6d7926e856 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c @@ -153,7 +153,7 @@ static int tef6862_probe(struct i2c_client *client) v4l_info(client, "chip found @ 0x%02x (%s)\n", client->addr << 1, client->adapter->name); - state = kzalloc(sizeof(struct tef6862_state), GFP_KERNEL); + state = kzalloc_obj(struct tef6862_state); if (state == NULL) return -ENOMEM; state->freq = TEF6862_LO_FREQ; diff --git a/drivers/media/rc/ati_remote.c b/drivers/media/rc/ati_remote.c index a733914a2574..78abe810a88e 100644 --- a/drivers/media/rc/ati_remote.c +++ b/drivers/media/rc/ati_remote.c @@ -839,7 +839,7 @@ static int ati_remote_probe(struct usb_interface *interface, return -ENODEV; } - ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); + ati_remote = kzalloc_obj(struct ati_remote); rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); if (!ati_remote || !rc_dev) goto exit_free_dev_rdev; diff --git a/drivers/media/rc/ene_ir.c b/drivers/media/rc/ene_ir.c index d6c54a3bccc2..f8120605501a 100644 --- a/drivers/media/rc/ene_ir.c +++ b/drivers/media/rc/ene_ir.c @@ -993,7 +993,7 @@ static int ene_probe(struct pnp_dev *pnp_dev, const struct pnp_device_id *id) struct ene_device *dev; /* allocate memory */ - dev = kzalloc(sizeof(struct ene_device), GFP_KERNEL); + dev = kzalloc_obj(struct ene_device); rdev = rc_allocate_device(RC_DRIVER_IR_RAW); if (!dev || !rdev) goto exit_free_dev_rdev; diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 3fb0968efd57..f7cfa8a073eb 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c @@ -465,7 +465,7 @@ static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id struct rc_dev *rdev; int ret = -ENOMEM; - fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL); + fintek = kzalloc_obj(struct fintek_dev); if (!fintek) return ret; diff --git a/drivers/media/rc/iguanair.c b/drivers/media/rc/iguanair.c index 8af94246e591..c508f2536243 100644 --- a/drivers/media/rc/iguanair.c +++ b/drivers/media/rc/iguanair.c @@ -392,7 +392,7 @@ static int iguanair_probe(struct usb_interface *intf, if (idesc->desc.bNumEndpoints < 2) return -ENODEV; - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!ir || !rc) { ret = -ENOMEM; diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 35b9e07003d8..7e92161105d5 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -614,7 +614,7 @@ static int send_packet(struct imon_context *ictx) ictx->tx_urb->actual_length = 0; } else { /* fill request into kmalloc'ed space: */ - control_req = kmalloc(sizeof(*control_req), GFP_KERNEL); + control_req = kmalloc_obj(*control_req); if (control_req == NULL) return -ENOMEM; @@ -2233,7 +2233,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf, struct usb_host_interface *iface_desc; int ret = -ENOMEM; - ictx = kzalloc(sizeof(*ictx), GFP_KERNEL); + ictx = kzalloc_obj(*ictx); if (!ictx) goto exit; diff --git a/drivers/media/rc/ir_toy.c b/drivers/media/rc/ir_toy.c index 533faa117517..d6472de5da87 100644 --- a/drivers/media/rc/ir_toy.c +++ b/drivers/media/rc/ir_toy.c @@ -418,7 +418,7 @@ static int irtoy_probe(struct usb_interface *intf, return -ENODEV; } - irtoy = kzalloc(sizeof(*irtoy), GFP_KERNEL); + irtoy = kzalloc_obj(*irtoy); if (!irtoy) return -ENOMEM; diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index 2bacecb02262..bf544517c67a 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c @@ -1304,7 +1304,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id int model_no; int io_rsrc_no; - itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL); + itdev = kzalloc_obj(struct ite_dev); if (!itdev) return ret; diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index 7d4942925993..183f1939b941 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -128,7 +128,7 @@ static int lirc_open(struct inode *inode, struct file *file) { struct rc_dev *dev = container_of(inode->i_cdev, struct rc_dev, lirc_cdev); - struct lirc_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + struct lirc_fh *fh = kzalloc_obj(*fh); unsigned long flags; int retval; @@ -267,7 +267,7 @@ static ssize_t lirc_transmit(struct file *file, const char __user *buf, goto out_unlock; } - raw = kmalloc_array(LIRCBUF_SIZE, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, LIRCBUF_SIZE); if (!raw) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 044767eb3a38..ed55e9ec3c57 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -1715,7 +1715,7 @@ static int mceusb_dev_probe(struct usb_interface *intf, pipe = usb_rcvbulkpipe(dev, ep_in->bEndpointAddress); maxp = usb_maxpacket(dev, pipe); - ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL); + ir = kzalloc_obj(struct mceusb_dev); if (!ir) goto mem_alloc_fail; diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index 2214d41ef579..4e5a0c8dc9a0 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -639,7 +639,7 @@ static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev, if (!sc_filter->mask) return 0; - raw = kmalloc_array(WAKEUP_MAX_SIZE, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, WAKEUP_MAX_SIZE); if (!raw) return -ENOMEM; diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 5dafe11f61c6..2e269ef5e26b 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -615,7 +615,7 @@ int ir_raw_event_prepare(struct rc_dev *dev) if (!dev) return -EINVAL; - dev->raw = kzalloc(sizeof(*dev->raw), GFP_KERNEL); + dev->raw = kzalloc_obj(*dev->raw); if (!dev->raw) return -ENOMEM; diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index 8288366f891f..78ac09b3cbd3 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -185,7 +185,7 @@ static int loop_set_wakeup_filter(struct rc_dev *dev, return 0; /* encode the specified filter and loop it back */ - raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL); + raw = kmalloc_objs(*raw, max); if (!raw) return -ENOMEM; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index b9bf5cdcde4a..821607504008 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -1701,7 +1701,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type) { struct rc_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c index a49173f54a4d..3b917a2a8918 100644 --- a/drivers/media/rc/redrat3.c +++ b/drivers/media/rc/redrat3.c @@ -502,7 +502,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus) __be32 *timeout; int ret; - timeout = kmalloc(sizeof(*timeout), GFP_KERNEL); + timeout = kmalloc_obj(*timeout); if (!timeout) return -ENOMEM; @@ -768,13 +768,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, /* rr3 will disable rc detector on transmit */ rr3->transmitting = true; - sample_lens = kcalloc(RR3_DRIVER_MAXLENS, - sizeof(*sample_lens), - GFP_KERNEL); + sample_lens = kzalloc_objs(*sample_lens, RR3_DRIVER_MAXLENS); if (!sample_lens) return -ENOMEM; - irdata = kzalloc(sizeof(*irdata), GFP_KERNEL); + irdata = kzalloc_obj(*irdata); if (!irdata) { ret = -ENOMEM; goto out; @@ -1022,7 +1020,7 @@ static int redrat3_dev_probe(struct usb_interface *intf, } /* allocate memory for our device state and initialize it */ - rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL); + rr3 = kzalloc_obj(*rr3); if (!rr3) goto no_endpoints; diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c index d3b48a0dd1f4..5a18603f9a95 100644 --- a/drivers/media/rc/streamzap.c +++ b/drivers/media/rc/streamzap.c @@ -285,7 +285,7 @@ static int streamzap_probe(struct usb_interface *intf, int pipe, maxp; /* Allocate space for device driver specific data */ - sz = kzalloc(sizeof(struct streamzap_ir), GFP_KERNEL); + sz = kzalloc_obj(struct streamzap_ir); if (!sz) return -ENOMEM; diff --git a/drivers/media/rc/ttusbir.c b/drivers/media/rc/ttusbir.c index 560a26f3965c..110a46900114 100644 --- a/drivers/media/rc/ttusbir.c +++ b/drivers/media/rc/ttusbir.c @@ -187,7 +187,7 @@ static int ttusbir_probe(struct usb_interface *intf, int i, j, ret; int altsetting = -1; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!tt || !rc) { ret = -ENOMEM; diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c index 25884a79985c..515469dd82d4 100644 --- a/drivers/media/rc/winbond-cir.c +++ b/drivers/media/rc/winbond-cir.c @@ -1017,7 +1017,7 @@ wbcir_probe(struct pnp_dev *device, const struct pnp_device_id *dev_id) return -ENODEV; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { err = -ENOMEM; goto exit; diff --git a/drivers/media/rc/xbox_remote.c b/drivers/media/rc/xbox_remote.c index a1572381d097..3e3da70cf8da 100644 --- a/drivers/media/rc/xbox_remote.c +++ b/drivers/media/rc/xbox_remote.c @@ -213,7 +213,7 @@ static int xbox_remote_probe(struct usb_interface *interface, return -ENODEV; } - xbox_remote = kzalloc(sizeof(*xbox_remote), GFP_KERNEL); + xbox_remote = kzalloc_obj(*xbox_remote); rc_dev = rc_allocate_device(RC_DRIVER_SCANCODE); if (!xbox_remote || !rc_dev) goto exit_free_dev_rdev; diff --git a/drivers/media/spi/cxd2880-spi.c b/drivers/media/spi/cxd2880-spi.c index 65fa7f857fca..36207940b689 100644 --- a/drivers/media/spi/cxd2880-spi.c +++ b/drivers/media/spi/cxd2880-spi.c @@ -516,7 +516,7 @@ cxd2880_spi_probe(struct spi_device *spi) return -EINVAL; } - dvb_spi = kzalloc(sizeof(struct cxd2880_dvb_spi), GFP_KERNEL); + dvb_spi = kzalloc_obj(struct cxd2880_dvb_spi); if (!dvb_spi) return -ENOMEM; diff --git a/drivers/media/test-drivers/vicodec/vicodec-core.c b/drivers/media/test-drivers/vicodec/vicodec-core.c index be846f711969..318e8330f16a 100644 --- a/drivers/media/test-drivers/vicodec/vicodec-core.c +++ b/drivers/media/test-drivers/vicodec/vicodec-core.c @@ -1836,7 +1836,7 @@ static int vicodec_open(struct file *file) if (mutex_lock_interruptible(vfd->lock)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto open_unlock; @@ -2105,7 +2105,7 @@ static int vicodec_probe(struct platform_device *pdev) struct vicodec_dev *dev; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/test-drivers/vidtv/vidtv_bridge.c b/drivers/media/test-drivers/vidtv/vidtv_bridge.c index 438483c62fac..b6203e10e37a 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_bridge.c +++ b/drivers/media/test-drivers/vidtv/vidtv_bridge.c @@ -490,7 +490,7 @@ static int vidtv_bridge_probe(struct platform_device *pdev) struct vidtv_dvb *dvb; int ret; - dvb = kzalloc(sizeof(*dvb), GFP_KERNEL); + dvb = kzalloc_obj(*dvb); if (!dvb) return -ENOMEM; diff --git a/drivers/media/test-drivers/vidtv/vidtv_channel.c b/drivers/media/test-drivers/vidtv/vidtv_channel.c index 3541155c6fc6..da20657adc74 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_channel.c +++ b/drivers/media/test-drivers/vidtv/vidtv_channel.c @@ -67,7 +67,7 @@ struct vidtv_channel const u16 s302m_beethoven_event_id = 1; struct vidtv_channel *s302m; - s302m = kzalloc(sizeof(*s302m), GFP_KERNEL); + s302m = kzalloc_obj(*s302m); if (!s302m) return NULL; @@ -389,7 +389,7 @@ static struct vidtv_psi_desc_service_list_entry s_desc = (struct vidtv_psi_desc_service *)desc; - curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + curr_e = kzalloc_obj(*curr_e); if (!curr_e) { vidtv_channel_destroy_service_list(head_e); return NULL; diff --git a/drivers/media/test-drivers/vidtv/vidtv_demod.c b/drivers/media/test-drivers/vidtv/vidtv_demod.c index 505f96fccbf3..c382e9e94c32 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_demod.c +++ b/drivers/media/test-drivers/vidtv/vidtv_demod.c @@ -418,7 +418,7 @@ static int vidtv_demod_i2c_probe(struct i2c_client *client) struct vidtv_demod_state *state; /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/media/test-drivers/vidtv/vidtv_mux.c b/drivers/media/test-drivers/vidtv/vidtv_mux.c index f99878eff7ac..403fbedb8663 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_mux.c +++ b/drivers/media/test-drivers/vidtv/vidtv_mux.c @@ -50,7 +50,7 @@ static struct vidtv_mux_pid_ctx if (ctx) return ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -480,7 +480,7 @@ struct vidtv_mux *vidtv_mux_init(struct dvb_frontend *fe, { struct vidtv_mux *m; - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (!m) return NULL; diff --git a/drivers/media/test-drivers/vidtv/vidtv_psi.c b/drivers/media/test-drivers/vidtv/vidtv_psi.c index 2a51c898c11e..685a1f7b2fb1 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_psi.c +++ b/drivers/media/test-drivers/vidtv/vidtv_psi.c @@ -285,7 +285,7 @@ struct vidtv_psi_desc_service *vidtv_psi_service_desc_init(struct vidtv_psi_desc u32 service_name_len = service_name ? strlen(service_name) : 0; u32 provider_name_len = provider_name ? strlen(provider_name) : 0; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return NULL; @@ -360,7 +360,7 @@ struct vidtv_psi_desc_network_name u32 network_name_len = network_name ? strlen(network_name) : 0; struct vidtv_psi_desc_network_name *desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return NULL; @@ -390,14 +390,14 @@ struct vidtv_psi_desc_service_list struct vidtv_psi_desc_service_list *desc; u16 length = 0; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return NULL; desc->type = SERVICE_LIST_DESCRIPTOR; while (entry) { - curr_e = kzalloc(sizeof(*curr_e), GFP_KERNEL); + curr_e = kzalloc_obj(*curr_e); if (!curr_e) { while (head_e) { curr_e = head_e; @@ -441,7 +441,7 @@ struct vidtv_psi_desc_short_event struct vidtv_psi_desc_short_event *desc; u32 text_len = text ? strlen(text) : 0; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return NULL; @@ -895,7 +895,7 @@ vidtv_psi_pat_program_init(struct vidtv_psi_table_pat_program *head, struct vidtv_psi_table_pat_program *program; const u16 RESERVED = 0x07; - program = kzalloc(sizeof(*program), GFP_KERNEL); + program = kzalloc_obj(*program); if (!program) return NULL; @@ -967,7 +967,7 @@ struct vidtv_psi_table_pat *vidtv_psi_pat_table_init(u16 transport_stream_id) const u16 ZERO = 0x0; const u16 ONES = 0x03; - pat = kzalloc(sizeof(*pat), GFP_KERNEL); + pat = kzalloc_obj(*pat); if (!pat) return NULL; @@ -1067,7 +1067,7 @@ vidtv_psi_pmt_stream_init(struct vidtv_psi_table_pmt_stream *head, const u16 ZERO = 0x0; u16 desc_loop_len; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return NULL; @@ -1153,7 +1153,7 @@ struct vidtv_psi_table_pmt *vidtv_psi_pmt_table_init(u16 program_number, const u16 ZERO = 0x0; u16 desc_loop_len; - pmt = kzalloc(sizeof(*pmt), GFP_KERNEL); + pmt = kzalloc_obj(*pmt); if (!pmt) return NULL; @@ -1298,7 +1298,7 @@ struct vidtv_psi_table_sdt *vidtv_psi_sdt_table_init(u16 network_id, const u16 ONES = 0x03; const u16 ONE = 0x1; - sdt = kzalloc(sizeof(*sdt), GFP_KERNEL); + sdt = kzalloc_obj(*sdt); if (!sdt) return NULL; @@ -1438,7 +1438,7 @@ struct vidtv_psi_table_sdt_service { struct vidtv_psi_table_sdt_service *service; - service = kzalloc(sizeof(*service), GFP_KERNEL); + service = kzalloc_obj(*service); if (!service) return NULL; @@ -1523,9 +1523,7 @@ vidtv_psi_pmt_create_sec_for_each_pat_entry(struct vidtv_psi_table_pat *pat, program = program->next; } - pmt_secs = kcalloc(num_pmt, - sizeof(struct vidtv_psi_table_pmt *), - GFP_KERNEL); + pmt_secs = kzalloc_objs(struct vidtv_psi_table_pmt *, num_pmt); if (!pmt_secs) return NULL; @@ -1622,11 +1620,11 @@ struct vidtv_psi_table_nit const u16 ONES = 0x03; const u16 ONE = 0x1; - nit = kzalloc(sizeof(*nit), GFP_KERNEL); + nit = kzalloc_obj(*nit); if (!nit) return NULL; - transport = kzalloc(sizeof(*transport), GFP_KERNEL); + transport = kzalloc_obj(*transport); if (!transport) goto free_nit; @@ -1857,7 +1855,7 @@ struct vidtv_psi_table_eit const u16 ONE = 0x1; const u16 ONES = 0x03; - eit = kzalloc(sizeof(*eit), GFP_KERNEL); + eit = kzalloc_obj(*eit); if (!eit) return NULL; @@ -1982,7 +1980,7 @@ struct vidtv_psi_table_eit_event int mjd, l; __be16 mjd_be; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return NULL; diff --git a/drivers/media/test-drivers/vidtv/vidtv_s302m.c b/drivers/media/test-drivers/vidtv/vidtv_s302m.c index 9da18eac04b5..581497644940 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_s302m.c +++ b/drivers/media/test-drivers/vidtv/vidtv_s302m.c @@ -148,7 +148,7 @@ static struct vidtv_access_unit *vidtv_s302m_access_unit_init(struct vidtv_acces { struct vidtv_access_unit *au; - au = kzalloc(sizeof(*au), GFP_KERNEL); + au = kzalloc_obj(*au); if (!au) return NULL; @@ -445,7 +445,7 @@ struct vidtv_encoder struct vidtv_s302m_ctx *ctx; struct vidtv_encoder *e; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return NULL; diff --git a/drivers/media/test-drivers/vidtv/vidtv_tuner.c b/drivers/media/test-drivers/vidtv/vidtv_tuner.c index 4ba302d569d6..ee55df4029bc 100644 --- a/drivers/media/test-drivers/vidtv/vidtv_tuner.c +++ b/drivers/media/test-drivers/vidtv/vidtv_tuner.c @@ -396,7 +396,7 @@ static int vidtv_tuner_i2c_probe(struct i2c_client *client) struct dvb_frontend *fe = config->fe; struct vidtv_tuner_dev *tuner_dev = NULL; - tuner_dev = kzalloc(sizeof(*tuner_dev), GFP_KERNEL); + tuner_dev = kzalloc_obj(*tuner_dev); if (!tuner_dev) return -ENOMEM; diff --git a/drivers/media/test-drivers/vim2m.c b/drivers/media/test-drivers/vim2m.c index c33c18ea5210..bb2dd11eef0e 100644 --- a/drivers/media/test-drivers/vim2m.c +++ b/drivers/media/test-drivers/vim2m.c @@ -1365,7 +1365,7 @@ static int vim2m_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto open_unlock; @@ -1492,7 +1492,7 @@ static int vim2m_probe(struct platform_device *pdev) struct video_device *vfd; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/test-drivers/vimc/vimc-capture.c b/drivers/media/test-drivers/vimc/vimc-capture.c index 7f6124025fc9..e0c6bc9f8f20 100644 --- a/drivers/media/test-drivers/vimc/vimc-capture.c +++ b/drivers/media/test-drivers/vimc/vimc-capture.c @@ -397,7 +397,7 @@ static struct vimc_ent_device *vimc_capture_add(struct vimc_device *vimc, int ret; /* Allocate the vimc_capture_device struct */ - vcapture = kzalloc(sizeof(*vcapture), GFP_KERNEL); + vcapture = kzalloc_obj(*vcapture); if (!vcapture) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/test-drivers/vimc/vimc-core.c b/drivers/media/test-drivers/vimc/vimc-core.c index f632c77e52f5..15167e127461 100644 --- a/drivers/media/test-drivers/vimc/vimc-core.c +++ b/drivers/media/test-drivers/vimc/vimc-core.c @@ -287,8 +287,7 @@ static int vimc_register_devices(struct vimc_device *vimc) return ret; } /* allocate ent_devs */ - vimc->ent_devs = kcalloc(vimc->pipe_cfg->num_ents, - sizeof(*vimc->ent_devs), GFP_KERNEL); + vimc->ent_devs = kzalloc_objs(*vimc->ent_devs, vimc->pipe_cfg->num_ents); if (!vimc->ent_devs) { ret = -ENOMEM; goto err_v4l2_unregister; @@ -354,7 +353,7 @@ static int vimc_probe(struct platform_device *pdev) if (vimc_allocator == VIMC_ALLOCATOR_DMA_CONTIG) dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); - vimc = kzalloc(sizeof(*vimc), GFP_KERNEL); + vimc = kzalloc_obj(*vimc); if (!vimc) return -ENOMEM; diff --git a/drivers/media/test-drivers/vimc/vimc-debayer.c b/drivers/media/test-drivers/vimc/vimc-debayer.c index bbb7c7a86df0..0c2e715a8a16 100644 --- a/drivers/media/test-drivers/vimc/vimc-debayer.c +++ b/drivers/media/test-drivers/vimc/vimc-debayer.c @@ -564,7 +564,7 @@ static struct vimc_ent_device *vimc_debayer_add(struct vimc_device *vimc, int ret; /* Allocate the vdebayer struct */ - vdebayer = kzalloc(sizeof(*vdebayer), GFP_KERNEL); + vdebayer = kzalloc_obj(*vdebayer); if (!vdebayer) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/test-drivers/vimc/vimc-lens.c b/drivers/media/test-drivers/vimc/vimc-lens.c index 96399057a2b5..a08fa3d5c52c 100644 --- a/drivers/media/test-drivers/vimc/vimc-lens.c +++ b/drivers/media/test-drivers/vimc/vimc-lens.c @@ -54,7 +54,7 @@ static struct vimc_ent_device *vimc_lens_add(struct vimc_device *vimc, int ret; /* Allocate the vlens struct */ - vlens = kzalloc(sizeof(*vlens), GFP_KERNEL); + vlens = kzalloc_obj(*vlens); if (!vlens) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/test-drivers/vimc/vimc-scaler.c b/drivers/media/test-drivers/vimc/vimc-scaler.c index 47d0d63865a0..e2037c67e423 100644 --- a/drivers/media/test-drivers/vimc/vimc-scaler.c +++ b/drivers/media/test-drivers/vimc/vimc-scaler.c @@ -392,7 +392,7 @@ static struct vimc_ent_device *vimc_scaler_add(struct vimc_device *vimc, int ret; /* Allocate the vscaler struct */ - vscaler = kzalloc(sizeof(*vscaler), GFP_KERNEL); + vscaler = kzalloc_obj(*vscaler); if (!vscaler) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/test-drivers/vimc/vimc-sensor.c b/drivers/media/test-drivers/vimc/vimc-sensor.c index 027767777763..69e714d4f228 100644 --- a/drivers/media/test-drivers/vimc/vimc-sensor.c +++ b/drivers/media/test-drivers/vimc/vimc-sensor.c @@ -382,7 +382,7 @@ static struct vimc_ent_device *vimc_sensor_add(struct vimc_device *vimc, int ret; /* Allocate the vsensor struct */ - vsensor = kzalloc(sizeof(*vsensor), GFP_KERNEL); + vsensor = kzalloc_obj(*vsensor); if (!vsensor) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/test-drivers/visl/visl-core.c b/drivers/media/test-drivers/visl/visl-core.c index 26c6c6835f79..127ab18bce99 100644 --- a/drivers/media/test-drivers/visl/visl-core.c +++ b/drivers/media/test-drivers/visl/visl-core.c @@ -332,7 +332,7 @@ static int visl_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto unlock; @@ -437,7 +437,7 @@ static int visl_probe(struct platform_device *pdev) int ret; int rc; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/test-drivers/visl/visl-debugfs.c b/drivers/media/test-drivers/visl/visl-debugfs.c index 45f2a8268014..dd0ca5d8126c 100644 --- a/drivers/media/test-drivers/visl/visl-debugfs.c +++ b/drivers/media/test-drivers/visl/visl-debugfs.c @@ -45,7 +45,7 @@ void visl_trace_bitstream(struct visl_ctx *ctx, struct visl_run *run) struct dentry *dentry; char name[32]; - blob = kzalloc(sizeof(*blob), GFP_KERNEL); + blob = kzalloc_obj(*blob); if (!blob) return; diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index 9c0b1a32b5c9..c8bf9b4d406c 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -1814,7 +1814,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) int i; /* allocate main vivid state structure */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/media/tuners/e4000.c b/drivers/media/tuners/e4000.c index 549b2009f974..b83f37a77224 100644 --- a/drivers/media/tuners/e4000.c +++ b/drivers/media/tuners/e4000.c @@ -621,7 +621,7 @@ static int e4000_probe(struct i2c_client *client) .val_bits = 8, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c index 3d3b54be2955..33a283adad51 100644 --- a/drivers/media/tuners/fc0011.c +++ b/drivers/media/tuners/fc0011.c @@ -485,7 +485,7 @@ struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe, { struct fc0011_priv *priv; - priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL); + priv = kzalloc_obj(struct fc0011_priv); if (!priv) return NULL; diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c index 81e65acbdb17..89317c88e94a 100644 --- a/drivers/media/tuners/fc0012.c +++ b/drivers/media/tuners/fc0012.c @@ -435,7 +435,7 @@ struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe, if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); - priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL); + priv = kzalloc_obj(struct fc0012_priv); if (!priv) { ret = -ENOMEM; dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c index 90d2ef067594..70815abdee96 100644 --- a/drivers/media/tuners/fc0013.c +++ b/drivers/media/tuners/fc0013.c @@ -526,7 +526,7 @@ struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe, { struct fc0013_priv *priv = NULL; - priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL); + priv = kzalloc_obj(struct fc0013_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/fc2580.c b/drivers/media/tuners/fc2580.c index 046389896dc5..75087d9b224f 100644 --- a/drivers/media/tuners/fc2580.c +++ b/drivers/media/tuners/fc2580.c @@ -518,7 +518,7 @@ static int fc2580_probe(struct i2c_client *client) .val_bits = 8, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/tuners/it913x.c b/drivers/media/tuners/it913x.c index 9186174a46fd..22e29913d904 100644 --- a/drivers/media/tuners/it913x.c +++ b/drivers/media/tuners/it913x.c @@ -385,7 +385,7 @@ static int it913x_probe(struct platform_device *pdev) int ret; char *chip_ver_str; - dev = kzalloc(sizeof(struct it913x_dev), GFP_KERNEL); + dev = kzalloc_obj(struct it913x_dev); if (dev == NULL) { ret = -ENOMEM; dev_err(&pdev->dev, "kzalloc() failed\n"); diff --git a/drivers/media/tuners/m88rs6000t.c b/drivers/media/tuners/m88rs6000t.c index cc57980ed417..0a724cdf0f6d 100644 --- a/drivers/media/tuners/m88rs6000t.c +++ b/drivers/media/tuners/m88rs6000t.c @@ -612,7 +612,7 @@ static int m88rs6000t_probe(struct i2c_client *client) {0x75, 0xFC}, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; dev_err(&client->dev, "kzalloc() failed\n"); diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c index 1575ab94e1c8..c070cd2161fd 100644 --- a/drivers/media/tuners/max2165.c +++ b/drivers/media/tuners/max2165.c @@ -394,7 +394,7 @@ struct dvb_frontend *max2165_attach(struct dvb_frontend *fe, i2c ? i2c_adapter_id(i2c) : -1, cfg ? cfg->i2c_address : -1); - priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL); + priv = kzalloc_obj(struct max2165_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c index ed8bdf7ebd99..4d5429f916ec 100644 --- a/drivers/media/tuners/mc44s803.c +++ b/drivers/media/tuners/mc44s803.c @@ -315,7 +315,7 @@ struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe, reg = 0; - priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL); + priv = kzalloc_obj(struct mc44s803_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c index ad6c72c1ed04..d7e6d64478d1 100644 --- a/drivers/media/tuners/msi001.c +++ b/drivers/media/tuners/msi001.c @@ -426,7 +426,7 @@ static int msi001_probe(struct spi_device *spi) dev_dbg(&spi->dev, "\n"); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c index 4b9dca2f17cc..ef3196e6bd30 100644 --- a/drivers/media/tuners/mt2060.c +++ b/drivers/media/tuners/mt2060.c @@ -407,7 +407,7 @@ struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter struct mt2060_priv *priv = NULL; u8 id = 0; - priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL); + priv = kzalloc_obj(struct mt2060_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c index 2c8ce74ddca4..3feb19fba4b2 100644 --- a/drivers/media/tuners/mt2063.c +++ b/drivers/media/tuners/mt2063.c @@ -2212,7 +2212,7 @@ struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe, dprintk(2, "\n"); - state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL); + state = kzalloc_obj(struct mt2063_state); if (!state) return NULL; diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c index baf708f42428..6c4333b1d9e4 100644 --- a/drivers/media/tuners/mt20xx.c +++ b/drivers/media/tuners/mt20xx.c @@ -596,7 +596,7 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe, unsigned char buf[21]; int company_code; - priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL); + priv = kzalloc_obj(struct microtune_priv); if (priv == NULL) return NULL; fe->tuner_priv = priv; diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c index eebc06088341..fa59f572d515 100644 --- a/drivers/media/tuners/mt2131.c +++ b/drivers/media/tuners/mt2131.c @@ -248,7 +248,7 @@ struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe, dprintk(1, "%s()\n", __func__); - priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL); + priv = kzalloc_obj(struct mt2131_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c index 2e92885a6bcb..68111f7e7917 100644 --- a/drivers/media/tuners/mt2266.c +++ b/drivers/media/tuners/mt2266.c @@ -313,7 +313,7 @@ struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter struct mt2266_priv *priv = NULL; u8 id = 0; - priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL); + priv = kzalloc_obj(struct mt2266_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/mxl301rf.c b/drivers/media/tuners/mxl301rf.c index 3b61c3afed18..cfc78891ce03 100644 --- a/drivers/media/tuners/mxl301rf.c +++ b/drivers/media/tuners/mxl301rf.c @@ -289,7 +289,7 @@ static int mxl301rf_probe(struct i2c_client *client) struct mxl301rf_config *cfg; struct dvb_frontend *fe; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c index 0e811c5eae6c..ba22bf594ac7 100644 --- a/drivers/media/tuners/mxl5005s.c +++ b/drivers/media/tuners/mxl5005s.c @@ -4103,7 +4103,7 @@ struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe, struct mxl5005s_state *state = NULL; dprintk(1, "%s()\n", __func__); - state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL); + state = kzalloc_obj(struct mxl5005s_state); if (state == NULL) return NULL; diff --git a/drivers/media/tuners/qm1d1b0004.c b/drivers/media/tuners/qm1d1b0004.c index c53aeb558413..07ad84f42c9f 100644 --- a/drivers/media/tuners/qm1d1b0004.c +++ b/drivers/media/tuners/qm1d1b0004.c @@ -208,7 +208,7 @@ qm1d1b0004_probe(struct i2c_client *client) fe = cfg->fe; i2c_set_clientdata(client, fe); - fe->tuner_priv = kzalloc(sizeof(struct qm1d1b0004_state), GFP_KERNEL); + fe->tuner_priv = kzalloc_obj(struct qm1d1b0004_state); if (!fe->tuner_priv) { ret = -ENOMEM; goto err_mem; diff --git a/drivers/media/tuners/qm1d1c0042.c b/drivers/media/tuners/qm1d1c0042.c index c58f5b6526f1..db60562ad698 100644 --- a/drivers/media/tuners/qm1d1c0042.c +++ b/drivers/media/tuners/qm1d1c0042.c @@ -407,7 +407,7 @@ static int qm1d1c0042_probe(struct i2c_client *client) struct qm1d1c0042_config *cfg; struct dvb_frontend *fe; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; state->i2c = client; diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c index 48fc79cd4027..cd6025fc95cd 100644 --- a/drivers/media/tuners/qt1010.c +++ b/drivers/media/tuners/qt1010.c @@ -411,7 +411,7 @@ struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe, struct qt1010_priv *priv = NULL; u8 id; - priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL); + priv = kzalloc_obj(struct qt1010_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c index def06c262ea2..4ca42114da8a 100644 --- a/drivers/media/tuners/si2157.c +++ b/drivers/media/tuners/si2157.c @@ -884,7 +884,7 @@ static int si2157_probe(struct i2c_client *client) struct si2157_cmd cmd; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; dev_err(&client->dev, "kzalloc() failed\n"); diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c index 39f2dc9c2845..5f583c010408 100644 --- a/drivers/media/tuners/tda18212.c +++ b/drivers/media/tuners/tda18212.c @@ -186,7 +186,7 @@ static int tda18212_probe(struct i2c_client *client) .val_bits = 8, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { ret = -ENOMEM; dev_err(&client->dev, "kzalloc() failed\n"); diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c index 7d8d84dcb245..503af47a8e62 100644 --- a/drivers/media/tuners/tda18218.c +++ b/drivers/media/tuners/tda18218.c @@ -292,7 +292,7 @@ struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6 }; - priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tda18218_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/tda18250.c b/drivers/media/tuners/tda18250.c index 68d0275f29e1..caaf5e0d0c9b 100644 --- a/drivers/media/tuners/tda18250.c +++ b/drivers/media/tuners/tda18250.c @@ -769,7 +769,7 @@ static int tda18250_probe(struct i2c_client *client) .volatile_table = &tda18250_volatile_table, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c index ad68ee6c5ed4..0ac40f1f13a7 100644 --- a/drivers/media/tuners/tda827x.c +++ b/drivers/media/tuners/tda827x.c @@ -873,7 +873,7 @@ struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr, struct tda827x_priv *priv = NULL; dprintk("%s:\n", __func__); - priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tda827x_priv); if (priv == NULL) return NULL; diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c index 98851482c0cc..9ff0aa8cb80c 100644 --- a/drivers/media/tuners/tda8290.c +++ b/drivers/media/tuners/tda8290.c @@ -734,7 +734,7 @@ struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe, struct tda8290_priv *priv = NULL; char *name; - priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tda8290_priv); if (priv == NULL) return NULL; fe->analog_demod_priv = priv; diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c index 425e9fd3f3d4..3abe7745e80b 100644 --- a/drivers/media/tuners/tea5761.c +++ b/drivers/media/tuners/tea5761.c @@ -315,7 +315,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, if (tea5761_autodetection(i2c_adap, i2c_addr) != 0) return NULL; - priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tea5761_priv); if (priv == NULL) return NULL; fe->tuner_priv = priv; diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c index ef4acb1f1bfa..97ad85c16775 100644 --- a/drivers/media/tuners/tea5767.c +++ b/drivers/media/tuners/tea5767.c @@ -441,7 +441,7 @@ struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe, { struct tea5767_priv *priv = NULL; - priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL); + priv = kzalloc_obj(struct tea5767_priv); if (priv == NULL) return NULL; fe->tuner_priv = priv; diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c index 562a7a5c26f5..c0aed1b441e2 100644 --- a/drivers/media/tuners/tua9001.c +++ b/drivers/media/tuners/tua9001.c @@ -178,7 +178,7 @@ static int tua9001_probe(struct i2c_client *client) .val_bits = 16, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h index 724952e001cd..4efc825eda9b 100644 --- a/drivers/media/tuners/tuner-i2c.h +++ b/drivers/media/tuners/tuner-i2c.h @@ -132,7 +132,7 @@ static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props, } \ } \ if (0 == __ret) { \ - state = kzalloc(sizeof(type), GFP_KERNEL); \ + state = kzalloc_obj(type); \ if (NULL == state) \ goto __fail; \ state->i2c_props.addr = i2caddr; \ diff --git a/drivers/media/tuners/xc2028.c b/drivers/media/tuners/xc2028.c index 807585d2dfde..27b18ab0d44f 100644 --- a/drivers/media/tuners/xc2028.c +++ b/drivers/media/tuners/xc2028.c @@ -332,7 +332,7 @@ static int load_all_firmwares(struct dvb_frontend *fe, n_array, priv->fname, name, priv->firm_version >> 8, priv->firm_version & 0xff); - priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); + priv->firm = kzalloc_objs(*priv->firm, n_array); if (priv->firm == NULL) { tuner_err("Not enough memory to load firmware file.\n"); rc = -ENOMEM; diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c index b44c97e4e5ec..900c5f2438fc 100644 --- a/drivers/media/tuners/xc4000.c +++ b/drivers/media/tuners/xc4000.c @@ -763,7 +763,7 @@ static int xc4000_fwupload(struct dvb_frontend *fe) n_array, fname, name, priv->firm_version >> 8, priv->firm_version & 0xff); - priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL); + priv->firm = kzalloc_objs(*priv->firm, n_array); if (priv->firm == NULL) { printk(KERN_ERR "Not enough memory to load firmware file.\n"); rc = -ENOMEM; diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c index 08f0920cf6ca..8f6b721ba107 100644 --- a/drivers/media/usb/airspy/airspy.c +++ b/drivers/media/usb/airspy/airspy.c @@ -968,7 +968,7 @@ static int airspy_probe(struct usb_interface *intf, buf = NULL; ret = -ENOMEM; - s = kzalloc(sizeof(struct airspy), GFP_KERNEL); + s = kzalloc_obj(struct airspy); if (s == NULL) { dev_err(&intf->dev, "Could not allocate memory for state\n"); return -ENOMEM; diff --git a/drivers/media/usb/as102/as102_fw.c b/drivers/media/usb/as102/as102_fw.c index 514764247588..d2d432789f55 100644 --- a/drivers/media/usb/as102/as102_fw.c +++ b/drivers/media/usb/as102/as102_fw.c @@ -96,7 +96,7 @@ static int as102_firmware_upload(struct as10x_bus_adapter_t *bus_adap, int total_read_bytes = 0, errno = 0; unsigned char addr_has_changed = 0; - fw_pkt = kmalloc(sizeof(*fw_pkt), GFP_KERNEL); + fw_pkt = kmalloc_obj(*fw_pkt); if (!fw_pkt) return -ENOMEM; diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c index e0ef66a522e2..8e480ab78f9b 100644 --- a/drivers/media/usb/as102/as102_usb_drv.c +++ b/drivers/media/usb/as102/as102_usb_drv.c @@ -345,7 +345,7 @@ static int as102_usb_probe(struct usb_interface *intf, return -EINVAL; } - as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL); + as102_dev = kzalloc_obj(struct as102_dev_t); if (as102_dev == NULL) return -ENOMEM; diff --git a/drivers/media/usb/au0828/au0828-core.c b/drivers/media/usb/au0828/au0828-core.c index 1e246b47766d..445cbeb7abae 100644 --- a/drivers/media/usb/au0828/au0828-core.c +++ b/drivers/media/usb/au0828/au0828-core.c @@ -670,7 +670,7 @@ static int au0828_usb_probe(struct usb_interface *interface, return -ENODEV; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { pr_err("%s() Unable to allocate memory\n", __func__); return -ENOMEM; diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 3d3368202cd0..7dec1a360da6 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -283,7 +283,7 @@ int au0828_rc_register(struct au0828_dev *dev) if (!i2c_rc_dev_addr) return -ENODEV; - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!ir || !rc) goto error; diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c index 691f073892b3..b64a37d1acf4 100644 --- a/drivers/media/usb/cx231xx/cx231xx-cards.c +++ b/drivers/media/usb/cx231xx/cx231xx-cards.c @@ -1295,7 +1295,7 @@ void cx231xx_card_setup(struct cx231xx *dev) u8 eeprom[256]; struct i2c_client client; }; - struct eeprom *e = kzalloc(sizeof(*e), GFP_KERNEL); + struct eeprom *e = kzalloc_obj(*e); if (e == NULL) { dev_err(dev->dev, @@ -1381,7 +1381,7 @@ static int cx231xx_media_device_init(struct cx231xx *dev, #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 0037b4b1381e..472a4405a105 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -627,7 +627,7 @@ static int dvb_init(struct cx231xx *dev) return 0; } - dvb = kzalloc(sizeof(struct cx231xx_dvb), GFP_KERNEL); + dvb = kzalloc_obj(struct cx231xx_dvb); if (dvb == NULL) { dev_info(dev->dev, diff --git a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c index f1c79f351ec8..600cff8a4abd 100644 --- a/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c +++ b/drivers/media/usb/dvb-usb-v2/dvb_usb_core.c @@ -392,7 +392,7 @@ static int dvb_usbv2_media_device_init(struct dvb_usb_adapter *adap) struct dvb_usb_device *d = adap_to_d(adap); struct usb_device *udev = d->udev; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; @@ -904,7 +904,7 @@ int dvb_usbv2_probe(struct usb_interface *intf, goto err; } - d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL); + d = kzalloc_obj(struct dvb_usb_device); if (!d) { dev_err(&udev->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); ret = -ENOMEM; diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c index a6ad5f477520..0b184080565a 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-demod.c @@ -577,7 +577,7 @@ struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state, mxl_dbg("()"); - state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL); + state = kzalloc_obj(struct mxl111sf_demod_state); if (state == NULL) return NULL; diff --git a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c index 6686f75cbd94..cdae66b834a7 100644 --- a/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c +++ b/drivers/media/usb/dvb-usb-v2/mxl111sf-tuner.c @@ -482,7 +482,7 @@ struct dvb_frontend *mxl111sf_tuner_attach(struct dvb_frontend *fe, mxl_dbg("()"); - state = kzalloc(sizeof(struct mxl111sf_tuner_state), GFP_KERNEL); + state = kzalloc_obj(struct mxl111sf_tuner_state); if (state == NULL) return NULL; diff --git a/drivers/media/usb/dvb-usb/af9005-fe.c b/drivers/media/usb/dvb-usb/af9005-fe.c index 404e56b32145..7f237dfecc3b 100644 --- a/drivers/media/usb/dvb-usb/af9005-fe.c +++ b/drivers/media/usb/dvb-usb/af9005-fe.c @@ -1423,7 +1423,7 @@ struct dvb_frontend *af9005_fe_attach(struct dvb_usb_device *d) struct af9005_fe_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct af9005_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct af9005_fe_state); if (state == NULL) goto error; diff --git a/drivers/media/usb/dvb-usb/cinergyT2-fe.c b/drivers/media/usb/dvb-usb/cinergyT2-fe.c index efb207c23a64..803e433536e4 100644 --- a/drivers/media/usb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/usb/dvb-usb/cinergyT2-fe.c @@ -268,8 +268,7 @@ static const struct dvb_frontend_ops cinergyt2_fe_ops; struct dvb_frontend *cinergyt2_fe_attach(struct dvb_usb_device *d) { - struct cinergyt2_fe_state *s = kzalloc(sizeof( - struct cinergyt2_fe_state), GFP_KERNEL); + struct cinergyt2_fe_state *s = kzalloc_obj(struct cinergyt2_fe_state); if (s == NULL) return NULL; diff --git a/drivers/media/usb/dvb-usb/dtt200u-fe.c b/drivers/media/usb/dvb-usb/dtt200u-fe.c index 586afe22d817..7d827ea83937 100644 --- a/drivers/media/usb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/usb/dvb-usb/dtt200u-fe.c @@ -206,7 +206,7 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) struct dtt200u_fe_state* state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(struct dtt200u_fe_state), GFP_KERNEL); + state = kzalloc_obj(struct dtt200u_fe_state); if (state == NULL) goto error; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c index 0a7f8ba90992..029dad86a059 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-dvb.c @@ -103,7 +103,7 @@ static int dvb_usb_media_device_init(struct dvb_usb_adapter *adap) struct dvb_usb_device *d = adap->dev; struct usb_device *udev = d->udev; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; diff --git a/drivers/media/usb/dvb-usb/dvb-usb-init.c b/drivers/media/usb/dvb-usb/dvb-usb-init.c index fbf58012becd..6d2672bcc69b 100644 --- a/drivers/media/usb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/usb/dvb-usb/dvb-usb-init.c @@ -278,7 +278,7 @@ int dvb_usb_device_init(struct usb_interface *intf, if (du != NULL) *du = NULL; - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { err("no memory for 'struct dvb_usb_device'"); return -ENOMEM; diff --git a/drivers/media/usb/dvb-usb/vp702x-fe.c b/drivers/media/usb/dvb-usb/vp702x-fe.c index c1e7931900ee..0d600a5f7267 100644 --- a/drivers/media/usb/dvb-usb/vp702x-fe.c +++ b/drivers/media/usb/dvb-usb/vp702x-fe.c @@ -323,7 +323,7 @@ static const struct dvb_frontend_ops vp702x_fe_ops; struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) { - struct vp702x_fe_state *s = kzalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL); + struct vp702x_fe_state *s = kzalloc_obj(struct vp702x_fe_state); if (s == NULL) goto error; diff --git a/drivers/media/usb/dvb-usb/vp7045-fe.c b/drivers/media/usb/dvb-usb/vp7045-fe.c index e99740ec2650..88c678687981 100644 --- a/drivers/media/usb/dvb-usb/vp7045-fe.c +++ b/drivers/media/usb/dvb-usb/vp7045-fe.c @@ -140,7 +140,7 @@ static const struct dvb_frontend_ops vp7045_fe_ops; struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) { - struct vp7045_fe_state *s = kzalloc(sizeof(struct vp7045_fe_state), GFP_KERNEL); + struct vp7045_fe_state *s = kzalloc_obj(struct vp7045_fe_state); if (s == NULL) goto error; diff --git a/drivers/media/usb/em28xx/em28xx-audio.c b/drivers/media/usb/em28xx/em28xx-audio.c index ce1b0d9e0741..ccff6be5599e 100644 --- a/drivers/media/usb/em28xx/em28xx-audio.c +++ b/drivers/media/usb/em28xx/em28xx-audio.c @@ -750,7 +750,7 @@ static int em28xx_audio_urb_init(struct em28xx *dev) if (!dev->adev.transfer_buffer) return -ENOMEM; - dev->adev.urb = kcalloc(num_urb, sizeof(*dev->adev.urb), GFP_KERNEL); + dev->adev.urb = kzalloc_objs(*dev->adev.urb, num_urb); if (!dev->adev.urb) { kfree(dev->adev.transfer_buffer); return -ENOMEM; diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c index a51cbcf429e1..59a2e4db75b7 100644 --- a/drivers/media/usb/em28xx/em28xx-cards.c +++ b/drivers/media/usb/em28xx/em28xx-cards.c @@ -3488,7 +3488,7 @@ static int em28xx_media_device_init(struct em28xx *dev, #ifdef CONFIG_MEDIA_CONTROLLER struct media_device *mdev; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; @@ -3905,7 +3905,7 @@ static int em28xx_usb_probe(struct usb_interface *intf, } /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { retval = -ENOMEM; goto err; diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index b94f5c70ab75..2eb9a88e595e 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1500,7 +1500,7 @@ static int em28xx_dvb_init(struct em28xx *dev) dev_info(&dev->intf->dev, "Binding DVB extension\n"); - dvb = kzalloc(sizeof(*dvb), GFP_KERNEL); + dvb = kzalloc_obj(*dvb); if (!dvb) return -ENOMEM; diff --git a/drivers/media/usb/em28xx/em28xx-input.c b/drivers/media/usb/em28xx/em28xx-input.c index 5f3b00869bdb..20fdd59b5518 100644 --- a/drivers/media/usb/em28xx/em28xx-input.c +++ b/drivers/media/usb/em28xx/em28xx-input.c @@ -724,7 +724,7 @@ static int em28xx_ir_init(struct em28xx *dev) dev_info(&dev->intf->dev, "Registering input extension\n"); - ir = kzalloc(sizeof(*ir), GFP_KERNEL); + ir = kzalloc_obj(*ir); if (!ir) goto ref_put; rc = rc_allocate_device(RC_DRIVER_SCANCODE); @@ -765,7 +765,7 @@ static int em28xx_ir_init(struct em28xx *dev) goto error; } - ir->i2c_client = kzalloc(sizeof(*ir->i2c_client), GFP_KERNEL); + ir->i2c_client = kzalloc_obj(*ir->i2c_client); if (!ir->i2c_client) goto error; ir->i2c_client->adapter = &ir->dev->i2c_adap[dev->def_i2c_bus]; diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c index 2dfa3242a7ab..b0c184f237a7 100644 --- a/drivers/media/usb/em28xx/em28xx-video.c +++ b/drivers/media/usb/em28xx/em28xx-video.c @@ -2529,7 +2529,7 @@ static int em28xx_v4l2_init(struct em28xx *dev) mutex_lock(&dev->lock); - v4l2 = kzalloc(sizeof(*v4l2), GFP_KERNEL); + v4l2 = kzalloc_obj(*v4l2); if (!v4l2) { mutex_unlock(&dev->lock); return -ENOMEM; diff --git a/drivers/media/usb/go7007/go7007-driver.c b/drivers/media/usb/go7007/go7007-driver.c index 468406302cd5..25b3ee25aaa4 100644 --- a/drivers/media/usb/go7007/go7007-driver.c +++ b/drivers/media/usb/go7007/go7007-driver.c @@ -694,7 +694,7 @@ struct go7007 *go7007_alloc(const struct go7007_board_info *board, { struct go7007 *go; - go = kzalloc(sizeof(struct go7007), GFP_KERNEL); + go = kzalloc_obj(struct go7007); if (go == NULL) return NULL; go->dev = dev; diff --git a/drivers/media/usb/go7007/go7007-usb.c b/drivers/media/usb/go7007/go7007-usb.c index 334cdde81a5c..c0cb92fa6ab9 100644 --- a/drivers/media/usb/go7007/go7007-usb.c +++ b/drivers/media/usb/go7007/go7007-usb.c @@ -1115,7 +1115,7 @@ static int go7007_usb_probe(struct usb_interface *intf, if (go == NULL) return -ENOMEM; - usb = kzalloc(sizeof(struct go7007_usb), GFP_KERNEL); + usb = kzalloc_obj(struct go7007_usb); if (usb == NULL) { kfree(go); return -ENOMEM; diff --git a/drivers/media/usb/go7007/s2250-board.c b/drivers/media/usb/go7007/s2250-board.c index a155b987282f..567f851d5896 100644 --- a/drivers/media/usb/go7007/s2250-board.c +++ b/drivers/media/usb/go7007/s2250-board.c @@ -509,7 +509,7 @@ static int s2250_probe(struct i2c_client *client) if (IS_ERR(audio)) return PTR_ERR(audio); - state = kzalloc(sizeof(struct s2250), GFP_KERNEL); + state = kzalloc_obj(struct s2250); if (state == NULL) { i2c_unregister_device(audio); return -ENOMEM; diff --git a/drivers/media/usb/go7007/snd-go7007.c b/drivers/media/usb/go7007/snd-go7007.c index 9a6bd87fce03..e4b9f37be77b 100644 --- a/drivers/media/usb/go7007/snd-go7007.c +++ b/drivers/media/usb/go7007/snd-go7007.c @@ -207,7 +207,7 @@ int go7007_snd_init(struct go7007 *go) dev++; return -ENOENT; } - gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL); + gosnd = kmalloc_obj(struct go7007_snd); if (gosnd == NULL) return -ENOMEM; spin_lock_init(&gosnd->lock); diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c index 303b055fefea..bd0c62a926b9 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_hdcs.c @@ -368,7 +368,7 @@ static int hdcs_probe_1x00(struct sd *sd) sd->gspca_dev.cam.cam_mode = hdcs1x00_mode; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode); - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); + hdcs = kmalloc_obj(struct hdcs); if (!hdcs) return -ENOMEM; @@ -425,7 +425,7 @@ static int hdcs_probe_1020(struct sd *sd) sd->gspca_dev.cam.cam_mode = hdcs1020_mode; sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode); - hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL); + hdcs = kmalloc_obj(struct hdcs); if (!hdcs) return -ENOMEM; diff --git a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c index ae382b3b5f7f..d30a76df52cf 100644 --- a/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c +++ b/drivers/media/usb/gspca/stv06xx/stv06xx_pb0100.c @@ -126,7 +126,7 @@ static int pb0100_init_controls(struct sd *sd) .def = 1, }; - ctrls = kzalloc(sizeof(*ctrls), GFP_KERNEL); + ctrls = kzalloc_obj(*ctrls); if (!ctrls) return -ENOMEM; diff --git a/drivers/media/usb/hackrf/hackrf.c b/drivers/media/usb/hackrf/hackrf.c index 0b50de8775a3..94d356fba612 100644 --- a/drivers/media/usb/hackrf/hackrf.c +++ b/drivers/media/usb/hackrf/hackrf.c @@ -1348,7 +1348,7 @@ static int hackrf_probe(struct usb_interface *intf, int ret; u8 u8tmp, buf[BUF_SIZE]; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/usb/hdpvr/hdpvr-core.c b/drivers/media/usb/hdpvr/hdpvr-core.c index 52e05a69c46e..d42336836b18 100644 --- a/drivers/media/usb/hdpvr/hdpvr-core.c +++ b/drivers/media/usb/hdpvr/hdpvr-core.c @@ -276,7 +276,7 @@ static int hdpvr_probe(struct usb_interface *interface, int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { dev_err(&interface->dev, "Out of memory\n"); goto error; diff --git a/drivers/media/usb/hdpvr/hdpvr-video.c b/drivers/media/usb/hdpvr/hdpvr-video.c index 8c7ae362d992..4290b2367fa3 100644 --- a/drivers/media/usb/hdpvr/hdpvr-video.c +++ b/drivers/media/usb/hdpvr/hdpvr-video.c @@ -147,7 +147,7 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count) for (i = 0; i < count; i++) { - buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL); + buf = kzalloc_obj(struct hdpvr_buffer); if (!buf) { v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n"); goto exit; @@ -379,7 +379,7 @@ static int hdpvr_stop_streaming(struct hdpvr_device *dev) static int hdpvr_open(struct file *file) { - struct hdpvr_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + struct hdpvr_fh *fh = kzalloc_obj(*fh); if (fh == NULL) return -ENOMEM; diff --git a/drivers/media/usb/msi2500/msi2500.c b/drivers/media/usb/msi2500/msi2500.c index 33099f39146a..1ff98956b680 100644 --- a/drivers/media/usb/msi2500/msi2500.c +++ b/drivers/media/usb/msi2500/msi2500.c @@ -1170,7 +1170,7 @@ static int msi2500_probe(struct usb_interface *intf, .max_speed_hz = 12000000, }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto err; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-context.c b/drivers/media/usb/pvrusb2/pvrusb2-context.c index 73c95ba2328a..93f5da65ead9 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-context.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-context.c @@ -204,7 +204,7 @@ struct pvr2_context *pvr2_context_create( void (*setup_func)(struct pvr2_context *)) { struct pvr2_context *mp = NULL; - mp = kzalloc(sizeof(*mp),GFP_KERNEL); + mp = kzalloc_obj(*mp); if (!mp) goto done; pvr2_trace(PVR2_TRACE_CTXT,"pvr2_context %p (create)",mp); mp->setup_func = setup_func; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c index 3610139fb9ad..721075989d57 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-dvb.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-dvb.c @@ -449,7 +449,7 @@ struct pvr2_dvb_adapter *pvr2_dvb_create(struct pvr2_context *pvr) the DVB side of the driver either. For now. */ return NULL; } - adap = kzalloc(sizeof(*adap), GFP_KERNEL); + adap = kzalloc_obj(*adap); if (!adap) return adap; pvr2_channel_init(&adap->channel, pvr); adap->channel.check_func = pvr2_dvb_internal_check; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c index 5807734ae26c..3c270ef00752 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c @@ -2367,7 +2367,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, goto fail; } - hdw = kzalloc(sizeof(*hdw),GFP_KERNEL); + hdw = kzalloc_obj(*hdw); pvr2_trace(PVR2_TRACE_INIT,"pvr2_hdw_create: hdw=%p, type \"%s\"", hdw,hdw_desc->description); pvr2_trace(PVR2_TRACE_INFO, "Hardware description: %s", @@ -2424,8 +2424,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, hdw->control_cnt = CTRLDEF_COUNT; hdw->control_cnt += MPEGDEF_COUNT; - hdw->controls = kcalloc(hdw->control_cnt, sizeof(struct pvr2_ctrl), - GFP_KERNEL); + hdw->controls = kzalloc_objs(struct pvr2_ctrl, hdw->control_cnt); if (!hdw->controls) goto fail; hdw->hdw_desc = hdw_desc; hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme; @@ -2450,9 +2449,8 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, } /* Define and configure additional controls from cx2341x module. */ - hdw->mpeg_ctrl_info = kcalloc(MPEGDEF_COUNT, - sizeof(*(hdw->mpeg_ctrl_info)), - GFP_KERNEL); + hdw->mpeg_ctrl_info = kzalloc_objs(*(hdw->mpeg_ctrl_info), + MPEGDEF_COUNT); if (!hdw->mpeg_ctrl_info) goto fail; for (idx = 0; idx < MPEGDEF_COUNT; idx++) { cptr = hdw->controls + idx + CTRLDEF_COUNT; diff --git a/drivers/media/usb/pvrusb2/pvrusb2-io.c b/drivers/media/usb/pvrusb2/pvrusb2-io.c index 28ffe7981f8c..af192aefef92 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-io.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-io.c @@ -299,7 +299,7 @@ static int pvr2_stream_buffer_count(struct pvr2_stream *sp, unsigned int cnt) if (scnt > sp->buffer_slot_count) { struct pvr2_buffer **nb; - nb = kmalloc_array(scnt, sizeof(*nb), GFP_KERNEL); + nb = kmalloc_objs(*nb, scnt); if (!nb) return -ENOMEM; if (sp->buffer_slot_count) { memcpy(nb, sp->buffers, @@ -311,7 +311,7 @@ static int pvr2_stream_buffer_count(struct pvr2_stream *sp, unsigned int cnt) } while (sp->buffer_total_count < cnt) { struct pvr2_buffer *bp; - bp = kmalloc(sizeof(*bp), GFP_KERNEL); + bp = kmalloc_obj(*bp); if (!bp) return -ENOMEM; ret = pvr2_buffer_init(bp, sp, sp->buffer_total_count); if (ret) { @@ -460,7 +460,7 @@ static void buffer_complete(struct urb *urb) struct pvr2_stream *pvr2_stream_create(void) { struct pvr2_stream *sp; - sp = kzalloc(sizeof(*sp), GFP_KERNEL); + sp = kzalloc_obj(*sp); if (!sp) return sp; pvr2_trace(PVR2_TRACE_INIT, "pvr2_stream_create: sp=%p", sp); pvr2_stream_init(sp); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c index 46f8013849b9..31f9305c0212 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-ioread.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-ioread.c @@ -73,7 +73,7 @@ static void pvr2_ioread_done(struct pvr2_ioread *cp) struct pvr2_ioread *pvr2_ioread_create(void) { struct pvr2_ioread *cp; - cp = kzalloc(sizeof(*cp),GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return NULL; pvr2_trace(PVR2_TRACE_STRUCT,"pvr2_ioread_create id=%p",cp); if (pvr2_ioread_init(cp) < 0) { diff --git a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c index 3077399901aa..dba43d4c24f2 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-sysfs.c @@ -289,7 +289,7 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id) cptr = pvr2_hdw_get_ctrl_by_index(sfp->channel.hdw,ctl_id); if (!cptr) return; - cip = kzalloc(sizeof(*cip),GFP_KERNEL); + cip = kzalloc_obj(*cip); if (!cip) return; pvr2_sysfs_trace("Creating pvr2_sysfs_ctl_item id=%p",cip); @@ -411,7 +411,7 @@ static void pvr2_sysfs_add_debugifc(struct pvr2_sysfs *sfp) struct pvr2_sysfs_debugifc *dip; int ret; - dip = kzalloc(sizeof(*dip),GFP_KERNEL); + dip = kzalloc_obj(*dip); if (!dip) return; sysfs_attr_init(&dip->attr_debugcmd.attr); dip->attr_debugcmd.attr.name = "debugcmd"; @@ -615,7 +615,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp) usb_dev = pvr2_hdw_get_dev(sfp->channel.hdw); if (!usb_dev) return; - class_dev = kzalloc(sizeof(*class_dev),GFP_KERNEL); + class_dev = kzalloc_obj(*class_dev); if (!class_dev) return; pvr2_sysfs_trace("Creating class_dev id=%p",class_dev); @@ -748,7 +748,7 @@ static void pvr2_sysfs_internal_check(struct pvr2_channel *chp) void pvr2_sysfs_create(struct pvr2_context *mp) { struct pvr2_sysfs *sfp; - sfp = kzalloc(sizeof(*sfp),GFP_KERNEL); + sfp = kzalloc_obj(*sfp); if (!sfp) return; pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_sysfs id=%p",sfp); diff --git a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c index f9535a484738..101b2e9fbaab 100644 --- a/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c @@ -944,7 +944,7 @@ static int pvr2_v4l2_open(struct file *file) return -EIO; } - fhp = kzalloc(sizeof(*fhp),GFP_KERNEL); + fhp = kzalloc_obj(*fhp); if (!fhp) { return -ENOMEM; } @@ -1236,7 +1236,7 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) { struct pvr2_v4l2 *vp; - vp = kzalloc(sizeof(*vp),GFP_KERNEL); + vp = kzalloc_obj(*vp); if (!vp) return vp; pvr2_channel_init(&vp->channel,mnp); pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp); @@ -1244,12 +1244,12 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp) vp->channel.check_func = pvr2_v4l2_internal_check; /* register streams */ - vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL); + vp->dev_video = kzalloc_obj(*vp->dev_video); if (!vp->dev_video) goto fail; pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_VIDEO); if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) & (1 << PVR2_CVAL_INPUT_RADIO)) { - vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL); + vp->dev_radio = kzalloc_obj(*vp->dev_radio); if (!vp->dev_radio) goto fail; pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO); } diff --git a/drivers/media/usb/pwc/pwc-if.c b/drivers/media/usb/pwc/pwc-if.c index c6e5d031f068..c416e2fc5754 100644 --- a/drivers/media/usb/pwc/pwc-if.c +++ b/drivers/media/usb/pwc/pwc-if.c @@ -1026,7 +1026,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id PWC_WARNING("Warning: more than 1 configuration available.\n"); /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ - pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); + pdev = kzalloc_obj(struct pwc_device); if (pdev == NULL) { PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); return -ENOMEM; diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c index 8332f2c5aed7..2c02873d09b5 100644 --- a/drivers/media/usb/s2255/s2255drv.c +++ b/drivers/media/usb/s2255/s2255drv.c @@ -2207,7 +2207,7 @@ static int s2255_probe(struct usb_interface *interface, int fw_size; /* allocate memory for our device state and initialize it to zero */ - dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL); + dev = kzalloc_obj(struct s2255_dev); if (dev == NULL) { s2255_dev_err(&interface->dev, "out of memory\n"); return -ENOMEM; @@ -2221,7 +2221,7 @@ static int s2255_probe(struct usb_interface *interface, refcount_set(&dev->num_channels, 0); dev->pid = id->idProduct; - dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL); + dev->fw_data = kzalloc_obj(struct s2255_fw); if (!dev->fw_data) goto errorFWDATA1; mutex_init(&dev->lock); diff --git a/drivers/media/usb/siano/smsusb.c b/drivers/media/usb/siano/smsusb.c index 2c8179a84991..0fdc2e0950b7 100644 --- a/drivers/media/usb/siano/smsusb.c +++ b/drivers/media/usb/siano/smsusb.c @@ -367,7 +367,7 @@ static void *siano_media_device_register(struct smsusb_device_t *dev, struct sms_board *board = sms_get_board(board_id); int ret; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return NULL; @@ -397,7 +397,7 @@ static int smsusb_init_device(struct usb_interface *intf, int board_id) int align = 0; /* create device object */ - dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL); + dev = kzalloc_obj(struct smsusb_device_t); if (!dev) return -ENOMEM; diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c index 25d725c2ab3c..f9462a9ca761 100644 --- a/drivers/media/usb/stk1160/stk1160-core.c +++ b/drivers/media/usb/stk1160/stk1160-core.c @@ -295,7 +295,7 @@ static int stk1160_probe(struct usb_interface *interface, return rc; } - dev = kzalloc(sizeof(struct stk1160), GFP_KERNEL); + dev = kzalloc_obj(struct stk1160); if (dev == NULL) { kfree(alt_max_pkt_size); return -ENOMEM; diff --git a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c index 9e016b71aa91..7a4d28cc3242 100644 --- a/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c @@ -1606,7 +1606,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV; - if (!(ttusb = kzalloc(sizeof(struct ttusb), GFP_KERNEL))) + if (!(ttusb = kzalloc_obj(struct ttusb))) return -ENOMEM; ttusb->dev = udev; diff --git a/drivers/media/usb/ttusb-dec/ttusb_dec.c b/drivers/media/usb/ttusb-dec/ttusb_dec.c index b4575fe89c95..825a3875989d 100644 --- a/drivers/media/usb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/usb/ttusb-dec/ttusb_dec.c @@ -809,8 +809,7 @@ static void ttusb_dec_process_urb(struct urb *urb) b = urb->transfer_buffer + d->offset; length = d->actual_length; - if ((frame = kmalloc(sizeof(struct urb_frame), - GFP_ATOMIC))) { + if ((frame = kmalloc_obj(struct urb_frame, GFP_ATOMIC))) { unsigned long flags; memcpy(frame->data, b, length); @@ -1061,8 +1060,7 @@ static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) if (!result) { if (c_length == 2) { - if (!(finfo = kmalloc(sizeof(struct filter_info), - GFP_ATOMIC))) + if (!(finfo = kmalloc_obj(struct filter_info, GFP_ATOMIC))) return -ENOMEM; finfo->stream_id = c[1]; @@ -1644,7 +1642,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); - if (!(dec = kzalloc(sizeof(struct ttusb_dec), GFP_KERNEL))) { + if (!(dec = kzalloc_obj(struct ttusb_dec))) { printk("%s: couldn't allocate memory.\n", __func__); return -ENOMEM; } diff --git a/drivers/media/usb/ttusb-dec/ttusbdecfe.c b/drivers/media/usb/ttusb-dec/ttusbdecfe.c index dff6bf532ce3..215221370c19 100644 --- a/drivers/media/usb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/usb/ttusb-dec/ttusbdecfe.c @@ -198,7 +198,7 @@ struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* conf struct ttusbdecfe_state* state = NULL; /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); + state = kmalloc_obj(struct ttusbdecfe_state); if (state == NULL) return NULL; @@ -218,7 +218,7 @@ struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* conf struct ttusbdecfe_state* state = NULL; /* allocate memory for the internal state */ - state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); + state = kmalloc_obj(struct ttusbdecfe_state); if (state == NULL) return NULL; diff --git a/drivers/media/usb/usbtv/usbtv-core.c b/drivers/media/usb/usbtv/usbtv-core.c index 1f7620cd2996..c4bfadbe63c9 100644 --- a/drivers/media/usb/usbtv/usbtv-core.c +++ b/drivers/media/usb/usbtv/usbtv-core.c @@ -87,7 +87,7 @@ static int usbtv_probe(struct usb_interface *intf, size = size * usb_endpoint_maxp_mult(&ep->desc); /* Device structure */ - usbtv = kzalloc(sizeof(struct usbtv), GFP_KERNEL); + usbtv = kzalloc_obj(struct usbtv); if (usbtv == NULL) return -ENOMEM; usbtv->dev = dev; diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index f0f6f8454d9c..b9a3d9257a11 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -600,7 +600,7 @@ static const struct uvc_control_mapping *uvc_ctrl_filter_plf_mapping( u8 init_val; int ret; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) return NULL; @@ -3339,8 +3339,7 @@ static int uvc_ctrl_init_chain(struct uvc_video_chain *chain) if (ncontrols == 0) continue; - entity->controls = kcalloc(ncontrols, sizeof(*ctrl), - GFP_KERNEL); + entity->controls = kzalloc_objs(*ctrl, ncontrols); if (entity->controls == NULL) return -ENOMEM; entity->ncontrols = ncontrols; diff --git a/drivers/media/usb/uvc/uvc_debugfs.c b/drivers/media/usb/uvc/uvc_debugfs.c index 14fa41cb8148..e8f20dd7eda4 100644 --- a/drivers/media/usb/uvc/uvc_debugfs.c +++ b/drivers/media/usb/uvc/uvc_debugfs.c @@ -29,7 +29,7 @@ static int uvc_debugfs_stats_open(struct inode *inode, struct file *file) struct uvc_streaming *stream = inode->i_private; struct uvc_debugfs_buffer *buf; - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (buf == NULL) return -ENOMEM; diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c index aa3e8d295e0f..b0ca81d924b6 100644 --- a/drivers/media/usb/uvc/uvc_driver.c +++ b/drivers/media/usb/uvc/uvc_driver.c @@ -200,7 +200,7 @@ static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev, { struct uvc_streaming *stream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (stream == NULL) return NULL; @@ -1761,7 +1761,7 @@ static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev) { struct uvc_video_chain *chain; - chain = kzalloc(sizeof(*chain), GFP_KERNEL); + chain = kzalloc_obj(*chain); if (chain == NULL) return NULL; @@ -2193,7 +2193,7 @@ static int uvc_probe(struct usb_interface *intf, int ret; /* Allocate memory for the device and initialize it. */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) return -ENOMEM; diff --git a/drivers/media/usb/uvc/uvc_metadata.c b/drivers/media/usb/uvc/uvc_metadata.c index c23b174965c3..0a906ae3f971 100644 --- a/drivers/media/usb/uvc/uvc_metadata.c +++ b/drivers/media/usb/uvc/uvc_metadata.c @@ -181,7 +181,7 @@ static int uvc_meta_detect_msxu(struct uvc_device *dev) * USB requires buffers aligned in a special way, simplest way is to * make sure that query_ctrl will work is to kmalloc() them. */ - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/media/usb/uvc/uvc_status.c b/drivers/media/usb/uvc/uvc_status.c index 231cfee8e7c2..65f5356bebb3 100644 --- a/drivers/media/usb/uvc/uvc_status.c +++ b/drivers/media/usb/uvc/uvc_status.c @@ -263,7 +263,7 @@ int uvc_status_init(struct uvc_device *dev) if (ep == NULL) return 0; - dev->status = kzalloc(sizeof(*dev->status), GFP_KERNEL); + dev->status = kzalloc_obj(*dev->status); if (!dev->status) return -ENOMEM; diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 30c160daed8c..d5860661c115 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -133,7 +133,7 @@ static int uvc_ioctl_xu_ctrl_map(struct uvc_video_chain *chain, return -EINVAL; } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) return -ENOMEM; @@ -572,7 +572,7 @@ static int uvc_v4l2_open(struct file *file) uvc_dbg(stream->dev, CALLS, "%s\n", __func__); /* Create the device handle. */ - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c index 59eb95a4b70c..40c76c051da2 100644 --- a/drivers/media/usb/uvc/uvc_video.c +++ b/drivers/media/usb/uvc/uvc_video.c @@ -682,8 +682,7 @@ static int uvc_video_clock_init(struct uvc_clock *clock) spin_lock_init(&clock->lock); clock->size = 32; - clock->samples = kmalloc_array(clock->size, sizeof(*clock->samples), - GFP_KERNEL); + clock->samples = kmalloc_objs(*clock->samples, clock->size); if (clock->samples == NULL) return -ENOMEM; diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 5687089bea6e..004ec4d7beea 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -633,7 +633,7 @@ static int tuner_probe(struct i2c_client *client) int ret; #endif - t = kzalloc(sizeof(struct tuner), GFP_KERNEL); + t = kzalloc_obj(struct tuner); if (NULL == t) return -ENOMEM; v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops); diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index 1c08bba9ecb9..888a2e213b08 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -779,7 +779,7 @@ int v4l2_async_subdev_endpoint_add(struct v4l2_subdev *sd, { struct v4l2_async_subdev_endpoint *ase; - ase = kmalloc(sizeof(*ase), GFP_KERNEL); + ase = kmalloc_obj(*ase); if (!ase) return -ENOMEM; diff --git a/drivers/media/v4l2-core/v4l2-ctrls-api.c b/drivers/media/v4l2-core/v4l2-ctrls-api.c index 0078a04c5445..93d8d4012d0f 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-api.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-api.c @@ -431,8 +431,7 @@ int v4l2_g_ext_ctrls_common(struct v4l2_ctrl_handler *hdl, return class_check(hdl, cs->which); if (cs->count > ARRAY_SIZE(helper)) { - helpers = kvmalloc_array(cs->count, sizeof(helper[0]), - GFP_KERNEL); + helpers = kvmalloc_objs(helper[0], cs->count); if (!helpers) return -ENOMEM; } @@ -617,8 +616,7 @@ int try_set_ext_ctrls_common(struct v4l2_fh *fh, return class_check(hdl, cs->which); if (cs->count > ARRAY_SIZE(helper)) { - helpers = kvmalloc_array(cs->count, sizeof(helper[0]), - GFP_KERNEL); + helpers = kvmalloc_objs(helper[0], cs->count); if (!helpers) return -ENOMEM; } diff --git a/drivers/media/v4l2-core/v4l2-ctrls-core.c b/drivers/media/v4l2-core/v4l2-ctrls-core.c index 79a157975f70..6b375720e395 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-core.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c @@ -1725,8 +1725,7 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, INIT_LIST_HEAD(&hdl->ctrls); INIT_LIST_HEAD(&hdl->ctrl_refs); hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8; - hdl->buckets = kvcalloc(hdl->nr_of_buckets, sizeof(hdl->buckets[0]), - GFP_KERNEL); + hdl->buckets = kvzalloc_objs(hdl->buckets[0], hdl->nr_of_buckets); hdl->error = hdl->buckets ? 0 : -ENOMEM; v4l2_ctrl_handler_init_request(hdl); return hdl->error; diff --git a/drivers/media/v4l2-core/v4l2-ctrls-request.c b/drivers/media/v4l2-core/v4l2-ctrls-request.c index e77f722b36a4..4b7e6981b8d6 100644 --- a/drivers/media/v4l2-core/v4l2-ctrls-request.c +++ b/drivers/media/v4l2-core/v4l2-ctrls-request.c @@ -198,7 +198,7 @@ v4l2_ctrls_find_req_obj(struct v4l2_ctrl_handler *hdl, if (!set) return ERR_PTR(-ENOMEM); - new_hdl = kzalloc(sizeof(*new_hdl), GFP_KERNEL); + new_hdl = kzalloc_obj(*new_hdl); if (!new_hdl) return ERR_PTR(-ENOMEM); @@ -341,7 +341,7 @@ void v4l2_ctrl_request_complete(struct media_request *req, int ret; /* Create a new request so the driver can return controls */ - hdl = kzalloc(sizeof(*hdl), GFP_KERNEL); + hdl = kzalloc_obj(*hdl); if (!hdl) return; diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index 10a126e50c1c..6ce623a1245a 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c @@ -146,7 +146,7 @@ static inline int devnode_find(struct video_device *vdev, int from, int to) struct video_device *video_device_alloc(void) { - return kzalloc(sizeof(struct video_device), GFP_KERNEL); + return kzalloc_obj(struct video_device); } EXPORT_SYMBOL(video_device_alloc); diff --git a/drivers/media/v4l2-core/v4l2-device.c b/drivers/media/v4l2-core/v4l2-device.c index 63b12ef9d4d9..67e3073de132 100644 --- a/drivers/media/v4l2-core/v4l2-device.c +++ b/drivers/media/v4l2-core/v4l2-device.c @@ -205,7 +205,7 @@ int __v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev, if (sd->devnode) continue; - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) { err = -ENOMEM; goto clean_up; diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 346d1b0e10ce..3fea06443a65 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -1237,7 +1237,7 @@ struct v4l2_debugfs_if *v4l2_debugfs_if_alloc(struct dentry *root, u32 if_types, if (IS_ERR_OR_NULL(root) || !if_types || !if_read) return NULL; - infoframes = kzalloc(sizeof(*infoframes), GFP_KERNEL); + infoframes = kzalloc_obj(*infoframes); if (!infoframes) return NULL; diff --git a/drivers/media/v4l2-core/v4l2-event.c b/drivers/media/v4l2-core/v4l2-event.c index 3898ff7edddb..9dd2aaa95a67 100644 --- a/drivers/media/v4l2-core/v4l2-event.c +++ b/drivers/media/v4l2-core/v4l2-event.c @@ -235,7 +235,7 @@ int v4l2_event_subscribe(struct v4l2_fh *fh, if (elems < 1) elems = 1; - sev = kvzalloc(struct_size(sev, events, elems), GFP_KERNEL); + sev = kvzalloc_flex(*sev, events, elems); if (!sev) return -ENOMEM; sev->elems = elems; diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c index df3ba9d4674b..b184bed8aca9 100644 --- a/drivers/media/v4l2-core/v4l2-fh.c +++ b/drivers/media/v4l2-core/v4l2-fh.c @@ -57,7 +57,7 @@ EXPORT_SYMBOL_GPL(v4l2_fh_add); int v4l2_fh_open(struct file *filp) { struct video_device *vdev = video_devdata(filp); - struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL); + struct v4l2_fh *fh = kzalloc_obj(*fh); if (fh == NULL) return -ENOMEM; diff --git a/drivers/media/v4l2-core/v4l2-flash-led-class.c b/drivers/media/v4l2-core/v4l2-flash-led-class.c index 355595a0fefa..163badeef76f 100644 --- a/drivers/media/v4l2-core/v4l2-flash-led-class.c +++ b/drivers/media/v4l2-core/v4l2-flash-led-class.c @@ -443,8 +443,7 @@ static int v4l2_flash_init_controls(struct v4l2_flash *v4l2_flash, return -ENOMEM; /* allocate memory dynamically so as not to exceed stack frame size */ - ctrl_init_data = kcalloc(NUM_FLASH_CTRLS, sizeof(*ctrl_init_data), - GFP_KERNEL); + ctrl_init_data = kzalloc_objs(*ctrl_init_data, NUM_FLASH_CTRLS); if (!ctrl_init_data) return -ENOMEM; diff --git a/drivers/media/v4l2-core/v4l2-fwnode.c b/drivers/media/v4l2-core/v4l2-fwnode.c index 22ec702a4567..03daa8c4ff7a 100644 --- a/drivers/media/v4l2-core/v4l2-fwnode.c +++ b/drivers/media/v4l2-core/v4l2-fwnode.c @@ -785,7 +785,7 @@ int v4l2_fwnode_connector_add_link(struct fwnode_handle *fwnode, if (!connector_ep) return -ENOTCONN; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) { err = -ENOMEM; goto err; @@ -1257,7 +1257,7 @@ int v4l2_async_register_subdev_sensor(struct v4l2_subdev *sd) if (WARN_ON(!sd->dev)) return -ENODEV; - notifier = kzalloc(sizeof(*notifier), GFP_KERNEL); + notifier = kzalloc_obj(*notifier); if (!notifier) return -ENOMEM; diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index b661f483dad3..a65cbb124cfe 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -1190,7 +1190,7 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops) if (!m2m_ops || WARN_ON(!m2m_ops->device_run)) return ERR_PTR(-EINVAL); - m2m_dev = kzalloc(sizeof *m2m_dev, GFP_KERNEL); + m2m_dev = kzalloc_obj(*m2m_dev); if (!m2m_dev) return ERR_PTR(-ENOMEM); @@ -1238,7 +1238,7 @@ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx; int ret; - m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL); + m2m_ctx = kzalloc_obj(*m2m_ctx); if (!m2m_ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 66842b975f91..32e6f60e26c7 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -99,7 +99,7 @@ static int subdev_open(struct file *file) struct v4l2_subdev_fh *subdev_fh; int ret; - subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL); + subdev_fh = kzalloc_obj(*subdev_fh); if (subdev_fh == NULL) return -ENOMEM; @@ -1606,7 +1606,7 @@ __v4l2_subdev_state_alloc(struct v4l2_subdev *sd, const char *lock_name, struct v4l2_subdev_state *state; int ret; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); @@ -1620,8 +1620,7 @@ __v4l2_subdev_state_alloc(struct v4l2_subdev *sd, const char *lock_name, /* Drivers that support streams do not need the legacy pad config */ if (!(sd->flags & V4L2_SUBDEV_FL_STREAMS) && sd->entity.num_pads) { - state->pads = kvcalloc(sd->entity.num_pads, - sizeof(*state->pads), GFP_KERNEL); + state->pads = kvzalloc_objs(*state->pads, sd->entity.num_pads); if (!state->pads) { ret = -ENOMEM; goto err; @@ -1889,9 +1888,8 @@ v4l2_subdev_init_stream_configs(struct v4l2_subdev_stream_configs *stream_config } if (new_configs.num_configs) { - new_configs.configs = kvcalloc(new_configs.num_configs, - sizeof(*new_configs.configs), - GFP_KERNEL); + new_configs.configs = kvzalloc_objs(*new_configs.configs, + new_configs.num_configs); if (!new_configs.configs) return -ENOMEM; diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c index d913fb901973..fcef4aed0292 100644 --- a/drivers/memory/samsung/exynos-srom.c +++ b/drivers/memory/samsung/exynos-srom.c @@ -54,7 +54,7 @@ exynos_srom_alloc_reg_dump(const unsigned long *rdump, struct exynos_srom_reg_dump *rd; unsigned int i; - rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL); + rd = kzalloc_objs(*rd, nr_rdump); if (!rd) return NULL; diff --git a/drivers/memory/tegra/tegra124-emc.c b/drivers/memory/tegra/tegra124-emc.c index 9978ff911c47..ff26815e51f1 100644 --- a/drivers/memory/tegra/tegra124-emc.c +++ b/drivers/memory/tegra/tegra124-emc.c @@ -1291,7 +1291,7 @@ emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) if (node->id != TEGRA_ICC_EMEM) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/memory/tegra/tegra124.c b/drivers/memory/tegra/tegra124.c index 9d7393e19f12..991d4f7bc070 100644 --- a/drivers/memory/tegra/tegra124.c +++ b/drivers/memory/tegra/tegra124.c @@ -1182,7 +1182,7 @@ tegra124_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data if (node->id != idx) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/memory/tegra/tegra20-emc.c b/drivers/memory/tegra/tegra20-emc.c index 398cb8ae2e38..a1fadefee7fd 100644 --- a/drivers/memory/tegra/tegra20-emc.c +++ b/drivers/memory/tegra/tegra20-emc.c @@ -958,7 +958,7 @@ emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) if (node->id != TEGRA_ICC_EMEM) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/memory/tegra/tegra20.c b/drivers/memory/tegra/tegra20.c index a3022e715dee..4748113bfe9d 100644 --- a/drivers/memory/tegra/tegra20.c +++ b/drivers/memory/tegra/tegra20.c @@ -401,7 +401,7 @@ tegra20_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) if (node->id != idx) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); @@ -615,7 +615,7 @@ static int tegra20_mc_stats_show(struct seq_file *s, void *unused) struct tegra20_mc_client_stat *stats; unsigned int i; - stats = kcalloc(mc->soc->num_clients + 1, sizeof(*stats), GFP_KERNEL); + stats = kzalloc_objs(*stats, mc->soc->num_clients + 1); if (!stats) return -ENOMEM; diff --git a/drivers/memory/tegra/tegra30-emc.c b/drivers/memory/tegra/tegra30-emc.c index 914116d8ec16..606106dd2b32 100644 --- a/drivers/memory/tegra/tegra30-emc.c +++ b/drivers/memory/tegra/tegra30-emc.c @@ -1476,7 +1476,7 @@ emc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) if (node->id != TEGRA_ICC_EMEM) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/memory/tegra/tegra30.c b/drivers/memory/tegra/tegra30.c index d3e685c8431f..a6bcde4b92c0 100644 --- a/drivers/memory/tegra/tegra30.c +++ b/drivers/memory/tegra/tegra30.c @@ -1344,7 +1344,7 @@ tegra30_mc_of_icc_xlate_extended(const struct of_phandle_args *spec, void *data) if (node->id != idx) continue; - ndata = kzalloc(sizeof(*ndata), GFP_KERNEL); + ndata = kzalloc_obj(*ndata); if (!ndata) return ERR_PTR(-ENOMEM); diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index acafc910bbac..e03989c4e99e 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -380,8 +380,7 @@ EXPORT_SYMBOL(memstick_set_rw_addr); static struct memstick_dev *memstick_alloc_card(struct memstick_host *host) { - struct memstick_dev *card = kzalloc(sizeof(struct memstick_dev), - GFP_KERNEL); + struct memstick_dev *card = kzalloc_obj(struct memstick_dev); struct memstick_dev *old_card = host->card; struct ms_id_register id_reg; diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 1af157ce0a63..a01fe313558e 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c @@ -1203,8 +1203,7 @@ static int msb_read_boot_blocks(struct msb_data *msb) dbg_verbose("Start of a scan for the boot blocks"); if (!msb->boot_page) { - page = kmalloc_array(2, sizeof(struct ms_boot_page), - GFP_KERNEL); + page = kmalloc_objs(struct ms_boot_page, 2); if (!page) return -ENOMEM; @@ -2151,7 +2150,7 @@ static int msb_probe(struct memstick_dev *card) struct msb_data *msb; int rc = 0; - msb = kzalloc(sizeof(struct msb_data), GFP_KERNEL); + msb = kzalloc_obj(struct msb_data); if (!msb) return -ENOMEM; memstick_set_drvdata(card, msb); @@ -2225,7 +2224,7 @@ static int msb_resume(struct memstick_dev *card) #endif mutex_lock(&card->host->lock); - new_msb = kzalloc(sizeof(struct msb_data), GFP_KERNEL); + new_msb = kzalloc_obj(struct msb_data); if (!new_msb) goto out; diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index e507bb11c802..4a52830026c5 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -939,9 +939,8 @@ static int mspro_block_read_attributes(struct memstick_dev *card) } else attr_count = attr->count; - msb->attr_group.attrs = kcalloc(attr_count + 1, - sizeof(*msb->attr_group.attrs), - GFP_KERNEL); + msb->attr_group.attrs = kzalloc_objs(*msb->attr_group.attrs, + attr_count + 1); if (!msb->attr_group.attrs) { rc = -ENOMEM; goto out_free_attr; @@ -955,7 +954,7 @@ static int mspro_block_read_attributes(struct memstick_dev *card) } for (cnt = 0; cnt < attr_count; ++cnt) { - s_attr = kzalloc(sizeof(struct mspro_sys_attr), GFP_KERNEL); + s_attr = kzalloc_obj(struct mspro_sys_attr); if (!s_attr) { rc = -ENOMEM; goto out_free_buffer; @@ -1211,7 +1210,7 @@ static int mspro_block_probe(struct memstick_dev *card) struct mspro_block_data *msb; int rc = 0; - msb = kzalloc(sizeof(struct mspro_block_data), GFP_KERNEL); + msb = kzalloc_obj(struct mspro_block_data); if (!msb) return -ENOMEM; memstick_set_drvdata(card, msb); @@ -1298,7 +1297,7 @@ static int mspro_block_resume(struct memstick_dev *card) unsigned char cnt; mutex_lock(&host->lock); - new_msb = kzalloc(sizeof(struct mspro_block_data), GFP_KERNEL); + new_msb = kzalloc_obj(struct mspro_block_data); if (!new_msb) { rc = -ENOMEM; goto out_unlock; diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 79e66e30417c..d93ba5e8662c 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -926,7 +926,7 @@ static int jmb38x_ms_probe(struct pci_dev *pdev, goto err_out_int; } - jm = kzalloc(struct_size(jm, hosts, cnt), GFP_KERNEL); + jm = kzalloc_flex(*jm, hosts, cnt); if (!jm) { rc = -ENOMEM; goto err_out_int; diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index e60a8d3947c9..3a431ffd3e2e 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -1771,7 +1771,7 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) struct proc_dir_entry *dent; #endif - ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_KERNEL); + ioc = kzalloc_obj(MPT_ADAPTER); if (ioc == NULL) { printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); return -ENOMEM; @@ -5700,8 +5700,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) continue; - if ((component_info = kmalloc(sizeof (*component_info), - GFP_KERNEL)) == NULL) + if ((component_info = kmalloc_obj(*component_info)) == NULL) continue; component_info->volumeID = id; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index cd52db6fe76c..b55deb988ad9 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -484,7 +484,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0) } } if (new_ri) { /* allocate one */ - ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); + ri = kzalloc_obj(struct mptfc_rport_info); if (!ri) return; list_add_tail(&ri->list, &ioc->fc_rports); @@ -572,7 +572,7 @@ mptfc_target_alloc(struct scsi_target *starget) struct mptfc_rport_info *ri; int rc; - vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); + vtarget = kzalloc_obj(VirtTarget); if (!vtarget) return -ENOMEM; starget->hostdata = vtarget; @@ -650,7 +650,7 @@ mptfc_sdev_init(struct scsi_device *sdev) hd = shost_priv(sdev->host); ioc = hd->ioc; - vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + vdevice = kzalloc_obj(VirtDevice); if (!vdevice) { printk(MYIOC_s_ERR_FMT "sdev_init kmalloc(%zd) FAILED!\n", ioc->name, sizeof(VirtDevice)); diff --git a/drivers/message/fusion/mptlan.c b/drivers/message/fusion/mptlan.c index de2e7bcf4784..f7fc5cc04b92 100644 --- a/drivers/message/fusion/mptlan.c +++ b/drivers/message/fusion/mptlan.c @@ -391,14 +391,12 @@ mpt_lan_open(struct net_device *dev) "a moment.\n"); } - priv->mpt_txfidx = kmalloc_array(priv->tx_max_out, sizeof(int), - GFP_KERNEL); + priv->mpt_txfidx = kmalloc_objs(int, priv->tx_max_out); if (priv->mpt_txfidx == NULL) goto out; priv->mpt_txfidx_tail = -1; - priv->SendCtl = kcalloc(priv->tx_max_out, sizeof(struct BufferControl), - GFP_KERNEL); + priv->SendCtl = kzalloc_objs(struct BufferControl, priv->tx_max_out); if (priv->SendCtl == NULL) goto out_mpt_txfidx; for (i = 0; i < priv->tx_max_out; i++) @@ -406,15 +404,12 @@ mpt_lan_open(struct net_device *dev) dlprintk((KERN_INFO MYNAM "@lo: Finished initializing SendCtl\n")); - priv->mpt_rxfidx = kmalloc_array(priv->max_buckets_out, sizeof(int), - GFP_KERNEL); + priv->mpt_rxfidx = kmalloc_objs(int, priv->max_buckets_out); if (priv->mpt_rxfidx == NULL) goto out_SendCtl; priv->mpt_rxfidx_tail = -1; - priv->RcvCtl = kcalloc(priv->max_buckets_out, - sizeof(struct BufferControl), - GFP_KERNEL); + priv->RcvCtl = kzalloc_objs(struct BufferControl, priv->max_buckets_out); if (priv->RcvCtl == NULL) goto out_mpt_rxfidx; for (i = 0; i < priv->max_buckets_out; i++) diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 5276bdb7acc2..c362f09a8c55 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -603,7 +603,7 @@ mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id, } } - sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL); + sas_info = kzalloc_obj(struct mptsas_device_info); if (!sas_info) goto out; @@ -756,7 +756,7 @@ mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc, } } - sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL); + sas_info = kzalloc_obj(struct mptsas_device_info); if (sas_info) { sas_info->fw.id = starget->id; sas_info->os.id = starget->id; @@ -907,8 +907,7 @@ mptsas_setup_wide_ports(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) * Forming a port */ if (!port_details) { - port_details = kzalloc(sizeof(struct - mptsas_portinfo_details), GFP_KERNEL); + port_details = kzalloc_obj(struct mptsas_portinfo_details); if (!port_details) goto out; port_details->num_phys = 1; @@ -1038,7 +1037,7 @@ mptsas_queue_rescan(MPT_ADAPTER *ioc) { struct fw_event_work *fw_event; - fw_event = kzalloc(sizeof(*fw_event), GFP_ATOMIC); + fw_event = kzalloc_obj(*fw_event, GFP_ATOMIC); if (!fw_event) { printk(MYIOC_s_WARN_FMT "%s: failed at (line=%d)\n", ioc->name, __func__, __LINE__); @@ -1150,8 +1149,8 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, vtarget->deleted = 1; /* block IO */ } - target_reset_list = kzalloc(sizeof(struct mptsas_target_reset_event), - GFP_ATOMIC); + target_reset_list = kzalloc_obj(struct mptsas_target_reset_event, + GFP_ATOMIC); if (!target_reset_list) { dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, failed to allocate mem @%d..!!\n", @@ -1751,7 +1750,7 @@ mptsas_target_alloc(struct scsi_target *starget) int i; MPT_ADAPTER *ioc = hd->ioc; - vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); + vtarget = kzalloc_obj(VirtTarget); if (!vtarget) return -ENOMEM; @@ -1878,7 +1877,7 @@ mptsas_sdev_init(struct scsi_device *sdev) int i; MPT_ADAPTER *ioc = hd->ioc; - vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + vdevice = kzalloc_obj(VirtDevice); if (!vdevice) { printk(MYIOC_s_ERR_FMT "sdev_init kzalloc(%zd) FAILED!\n", ioc->name, sizeof(VirtDevice)); @@ -2428,8 +2427,8 @@ mptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info) goto out_free_consistent; port_info->num_phys = buffer->NumPhys; - port_info->phy_info = kcalloc(port_info->num_phys, - sizeof(struct mptsas_phyinfo), GFP_KERNEL); + port_info->phy_info = kzalloc_objs(struct mptsas_phyinfo, + port_info->num_phys); if (!port_info->phy_info) { error = -ENOMEM; goto out_free_consistent; @@ -2719,8 +2718,8 @@ mptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, /* save config data */ port_info->num_phys = (buffer->NumPhys) ? buffer->NumPhys : 1; - port_info->phy_info = kcalloc(port_info->num_phys, - sizeof(struct mptsas_phyinfo), GFP_KERNEL); + port_info->phy_info = kzalloc_objs(struct mptsas_phyinfo, + port_info->num_phys); if (!port_info->phy_info) { error = -ENOMEM; goto out_free_consistent; @@ -3309,7 +3308,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc) struct mptsas_portinfo *port_info, *hba; int error = -ENOMEM, i; - hba = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL); + hba = kzalloc_obj(struct mptsas_portinfo); if (! hba) goto out; @@ -3444,12 +3443,12 @@ mptsas_expander_event_add(MPT_ADAPTER *ioc, int i; __le64 sas_address; - port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL); + port_info = kzalloc_obj(struct mptsas_portinfo); BUG_ON(!port_info); port_info->num_phys = (expander_data->NumPhys) ? expander_data->NumPhys : 1; - port_info->phy_info = kcalloc(port_info->num_phys, - sizeof(struct mptsas_phyinfo), GFP_KERNEL); + port_info->phy_info = kzalloc_objs(struct mptsas_phyinfo, + port_info->num_phys); BUG_ON(!port_info->phy_info); memcpy(&sas_address, &expander_data->SASAddress, sizeof(__le64)); for (i = 0; i < port_info->num_phys; i++) { @@ -3677,7 +3676,7 @@ mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle) MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle))) return NULL; - port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL); + port_info = kzalloc_obj(struct mptsas_portinfo); if (!port_info) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, @@ -3945,7 +3944,7 @@ mptsas_probe_expanders(MPT_ADAPTER *ioc) continue; } - port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL); + port_info = kzalloc_obj(struct mptsas_portinfo); if (!port_info) { dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: exit at line=%d\n", ioc->name, diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 14707d19fbbd..56892b1f3de2 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -405,7 +405,7 @@ static int mptspi_target_alloc(struct scsi_target *starget) return -ENODEV; ioc = hd->ioc; - vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL); + vtarget = kzalloc_obj(VirtTarget); if (!vtarget) return -ENOMEM; @@ -725,7 +725,7 @@ static int mptspi_sdev_init(struct scsi_device *sdev) mptscsih_is_phys_disk(ioc, 0, sdev->id) == 0) return -ENXIO; - vdevice = kzalloc(sizeof(VirtDevice), GFP_KERNEL); + vdevice = kzalloc_obj(VirtDevice); if (!vdevice) { printk(MYIOC_s_ERR_FMT "sdev_init kmalloc(%zd) FAILED!\n", ioc->name, sizeof(VirtDevice)); @@ -1152,7 +1152,7 @@ static void mpt_work_wrapper(struct work_struct *work) static void mpt_dv_raid(struct _MPT_SCSI_HOST *hd, int disk) { - struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); + struct work_queue_wrapper *wqw = kmalloc_obj(*wqw, GFP_ATOMIC); MPT_ADAPTER *ioc = hd->ioc; if (!wqw) { @@ -1288,7 +1288,7 @@ mptspi_dv_renegotiate_work(struct work_struct *work) static void mptspi_dv_renegotiate(struct _MPT_SCSI_HOST *hd) { - struct work_queue_wrapper *wqw = kmalloc(sizeof(*wqw), GFP_ATOMIC); + struct work_queue_wrapper *wqw = kmalloc_obj(*wqw, GFP_ATOMIC); if (!wqw) return; diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 699f095f831e..7192c9d1d268 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -407,6 +407,17 @@ config MFD_CS47L92 help Support for Cirrus Logic CS42L92, CS47L92 and CS47L93 Smart Codecs +config MFD_TN48M_CPLD + tristate "Delta Networks TN48M switch CPLD driver" + depends on I2C + depends on ARCH_MVEBU || COMPILE_TEST + select MFD_SIMPLE_MFD_I2C + help + Select this option to enable support for Delta Networks TN48M switch + CPLD. It consists of reset and GPIO drivers. CPLD provides GPIOS-s + for the SFP slots as well as power supply related information. + SFP support depends on the GPIO driver being selected. + config PMIC_DA903X bool "Dialog Semiconductor DA9030/DA9034 PMIC Support" depends on I2C=y @@ -1276,6 +1287,7 @@ config MFD_SPACEMIT_P1 depends on ARCH_SPACEMIT || COMPILE_TEST depends on I2C select MFD_SIMPLE_MFD_I2C + default m if ARCH_SPACEMIT help This option supports the I2C-based SpacemiT P1 PMIC, which contains regulators, a power switch, GPIOs, an RTC, and more. @@ -1371,15 +1383,15 @@ config MFD_RK8XX select MFD_CORE config MFD_RK8XX_I2C - tristate "Rockchip RK805/RK808/RK809/RK816/RK817/RK818 Power Management Chip" + tristate "Rockchip RK8xx Power Management Chips" depends on I2C && OF select MFD_CORE select REGMAP_I2C select REGMAP_IRQ select MFD_RK8XX help - If you say yes here you get support for the RK805, RK808, RK809, - RK816, RK817 and RK818 Power Management chips. + If you say yes here you get support for the RK801, RK805, RK808, + RK809, RK816, RK817 and RK818 Power Management chips. This driver provides common support for accessing the device through I2C interface. The device supports multiple sub-devices including interrupts, RTC, LDO & DCDC regulators, and onkey. diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index 85ff8717d850..91975536d14d 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c @@ -1100,7 +1100,7 @@ int arizona_dev_init(struct arizona *arizona) } else if (val & 0x01) { ret = wm5102_clear_write_sequencer(arizona); if (ret) - return ret; + goto err_reset; } break; default: diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c index 4c4e35d404f3..c3f3d39bf584 100644 --- a/drivers/mfd/atmel-hlcdc.c +++ b/drivers/mfd/atmel-hlcdc.c @@ -140,6 +140,7 @@ static const struct of_device_id atmel_hlcdc_match[] = { { .compatible = "atmel,sama5d4-hlcdc" }, { .compatible = "microchip,sam9x60-hlcdc" }, { .compatible = "microchip,sam9x75-xlcdc" }, + { .compatible = "microchip,sama7d65-xlcdc" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, atmel_hlcdc_match); diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c index c5f0ebae327f..679364189ea5 100644 --- a/drivers/mfd/axp20x.c +++ b/drivers/mfd/axp20x.c @@ -229,6 +229,8 @@ static const struct regmap_range axp717_writeable_ranges[] = { regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL), regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL), regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL), + regmap_reg_range(AXP717_TYPEC_CC_AA_EN, AXP717_TYPEC_CC_AA_EN), + regmap_reg_range(AXP717_TYPEC_CC_MODE_CONTROL, AXP717_TYPEC_CC_MODE_CONTROL), }; static const struct regmap_range axp717_volatile_ranges[] = { @@ -237,6 +239,7 @@ static const struct regmap_range axp717_volatile_ranges[] = { regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA), regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L), regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L), + regmap_reg_range(AXP717_TYPEC_CC_STATUS, AXP717_TYPEC_CC_STATUS), }; static const struct regmap_access_table axp717_writeable_table = { @@ -458,7 +461,7 @@ static const struct regmap_config axp717_regmap_config = { .val_bits = 8, .wr_table = &axp717_writeable_table, .volatile_table = &axp717_volatile_table, - .max_register = AXP717_ADC_DATA_L, + .max_register = AXP717_TYPEC_CC_STATUS, .cache_type = REGCACHE_MAPLE, }; diff --git a/drivers/mfd/cgbc-core.c b/drivers/mfd/cgbc-core.c index 4782ff1114a9..10bb4b414c34 100644 --- a/drivers/mfd/cgbc-core.c +++ b/drivers/mfd/cgbc-core.c @@ -237,6 +237,7 @@ static struct mfd_cell cgbc_devs[] = { { .name = "cgbc-i2c", .id = 1 }, { .name = "cgbc-i2c", .id = 2 }, { .name = "cgbc-hwmon" }, + { .name = "cgbc-backlight" }, }; static int cgbc_map(struct cgbc_device_data *cgbc) diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index dc80a272726b..39430dd44e30 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c @@ -188,7 +188,7 @@ static int ec_device_probe(struct platform_device *pdev) struct device_node *node; struct device *dev = &pdev->dev; struct cros_ec_platform *ec_platform = dev_get_platdata(dev); - struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); + struct cros_ec_dev *ec = kzalloc_obj(*ec); struct ec_response_pchg_count pchg_count; int i; diff --git a/drivers/mfd/da9052-spi.c b/drivers/mfd/da9052-spi.c index 80fc5c0cac2f..be5f2b34e18a 100644 --- a/drivers/mfd/da9052-spi.c +++ b/drivers/mfd/da9052-spi.c @@ -37,7 +37,7 @@ static int da9052_spi_probe(struct spi_device *spi) spi_set_drvdata(spi, da9052); config = da9052_regmap_config; - config.write_flag_mask = 1; + config.read_flag_mask = 1; config.reg_bits = 7; config.pad_bits = 1; config.val_bits = 8; diff --git a/drivers/mfd/dln2.c b/drivers/mfd/dln2.c index fbbe82c6e75b..d12510e391c8 100644 --- a/drivers/mfd/dln2.c +++ b/drivers/mfd/dln2.c @@ -125,7 +125,7 @@ int dln2_register_event_cb(struct platform_device *pdev, u16 id, unsigned long flags; int ret = 0; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -778,7 +778,7 @@ static int dln2_probe(struct usb_interface *interface, if (ret) return ret; - dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL); + dln2 = kzalloc_obj(*dln2); if (!dln2) return -ENOMEM; diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 1be4557b7bdd..24ca140d6a48 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c @@ -302,7 +302,7 @@ int pcap_adc_async(struct pcap_chip *pcap, u8 bank, u32 flags, u8 ch[], unsigned long irq_flags; /* This will be freed after we have a result */ - req = kmalloc(sizeof(struct pcap_adc_request), GFP_KERNEL); + req = kmalloc_obj(struct pcap_adc_request); if (!req) return -ENOMEM; diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 8d92c895d3ae..713a5bfb1a3c 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c @@ -437,6 +437,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_spi_info }, { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_spi_info }, { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, + /* NVL-S */ + { PCI_VDEVICE(INTEL, 0x6e28), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x6e29), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x6e2a), (kernel_ulong_t)&tgl_spi_info }, + { PCI_VDEVICE(INTEL, 0x6e2b), (kernel_ulong_t)&tgl_spi_info }, + { PCI_VDEVICE(INTEL, 0x6e4c), (kernel_ulong_t)&ehl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x6e4d), (kernel_ulong_t)&ehl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x6e4e), (kernel_ulong_t)&ehl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x6e4f), (kernel_ulong_t)&ehl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x6e5c), (kernel_ulong_t)&bxt_uart_info }, + { PCI_VDEVICE(INTEL, 0x6e5e), (kernel_ulong_t)&tgl_spi_info }, + { PCI_VDEVICE(INTEL, 0x6e7a), (kernel_ulong_t)&ehl_i2c_info }, + { PCI_VDEVICE(INTEL, 0x6e7b), (kernel_ulong_t)&ehl_i2c_info }, /* ARL-H */ { PCI_VDEVICE(INTEL, 0x7725), (kernel_ulong_t)&bxt_uart_info }, { PCI_VDEVICE(INTEL, 0x7726), (kernel_ulong_t)&bxt_uart_info }, diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c index e42f1de9e641..408056bfb2fe 100644 --- a/drivers/mfd/ls2k-bmc-core.c +++ b/drivers/mfd/ls2k-bmc-core.c @@ -464,53 +464,36 @@ static int ls2k_bmc_probe(struct pci_dev *dev, const struct pci_device_id *id) resource_size_t base; int ret; - ret = pci_enable_device(dev); + ret = pcim_enable_device(dev); if (ret) return ret; ddata = devm_kzalloc(&dev->dev, sizeof(*ddata), GFP_KERNEL); - if (!ddata) { - ret = -ENOMEM; - goto disable_pci; - } + if (!ddata) + return -ENOMEM; ddata->dev = &dev->dev; ret = ls2k_bmc_init(ddata); if (ret) - goto disable_pci; + return ret; ret = ls2k_bmc_parse_mode(dev, &pd); if (ret) - goto disable_pci; + return ret; ls2k_bmc_cells[LS2K_BMC_DISPLAY].platform_data = &pd; ls2k_bmc_cells[LS2K_BMC_DISPLAY].pdata_size = sizeof(pd); - base = dev->resource[0].start + LS2K_DISPLAY_RES_START; + base = pci_resource_start(dev, 0) + LS2K_DISPLAY_RES_START; /* Remove conflicting efifb device */ ret = aperture_remove_conflicting_devices(base, SZ_4M, "simple-framebuffer"); - if (ret) { - dev_err(&dev->dev, "Failed to removed firmware framebuffers: %d\n", ret); - goto disable_pci; - } - - ret = devm_mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, - ls2k_bmc_cells, ARRAY_SIZE(ls2k_bmc_cells), - &dev->resource[0], 0, NULL); if (ret) - goto disable_pci; + return dev_err_probe(&dev->dev, ret, "Failed to removed firmware framebuffers\n"); - return 0; - -disable_pci: - pci_disable_device(dev); - return ret; -} - -static void ls2k_bmc_remove(struct pci_dev *dev) -{ - pci_disable_device(dev); + return devm_mfd_add_devices(&dev->dev, PLATFORM_DEVID_AUTO, + ls2k_bmc_cells, ARRAY_SIZE(ls2k_bmc_cells), + pci_resource_n(dev, 0), 0, NULL); } static struct pci_device_id ls2k_bmc_devices[] = { @@ -523,7 +506,6 @@ static struct pci_driver ls2k_bmc_driver = { .name = "ls2k-bmc", .id_table = ls2k_bmc_devices, .probe = ls2k_bmc_probe, - .remove = ls2k_bmc_remove, }; module_pci_driver(ls2k_bmc_driver); diff --git a/drivers/mfd/macsmc.c b/drivers/mfd/macsmc.c index e3893e255ce5..1b7e7b3e785f 100644 --- a/drivers/mfd/macsmc.c +++ b/drivers/mfd/macsmc.c @@ -45,8 +45,11 @@ #define SMC_TIMEOUT_MS 500 static const struct mfd_cell apple_smc_devs[] = { + MFD_CELL_NAME("macsmc-input"), MFD_CELL_OF("macsmc-gpio", NULL, NULL, 0, 0, "apple,smc-gpio"), + MFD_CELL_OF("macsmc-hwmon", NULL, NULL, 0, 0, "apple,smc-hwmon"), MFD_CELL_OF("macsmc-reboot", NULL, NULL, 0, 0, "apple,smc-reboot"), + MFD_CELL_OF("macsmc-rtc", NULL, NULL, 0, 0, "apple,smc-rtc"), }; static int apple_smc_cmd_locked(struct apple_smc *smc, u64 cmd, u64 arg, @@ -413,6 +416,7 @@ static int apple_smc_probe(struct platform_device *pdev) if (!smc) return -ENOMEM; + mutex_init(&smc->mutex); smc->dev = &pdev->dev; smc->sram_base = devm_platform_get_and_ioremap_resource(pdev, 1, &smc->sram); if (IS_ERR(smc->sram_base)) diff --git a/drivers/mfd/max77759.c b/drivers/mfd/max77759.c index 6cf6306c4a3b..a7efe233ec8c 100644 --- a/drivers/mfd/max77759.c +++ b/drivers/mfd/max77759.c @@ -587,9 +587,7 @@ static int max77759_add_chained_charger(struct i2c_client *client, static int max77759_probe(struct i2c_client *client) { struct regmap_irq_chip_data *irq_chip_data_pmic; - struct irq_data *irq_data; struct max77759 *max77759; - unsigned long irq_flags; unsigned int pmic_id; int ret; @@ -628,16 +626,8 @@ static int max77759_probe(struct i2c_client *client) return ret; } - irq_data = irq_get_irq_data(client->irq); - if (!irq_data) - return dev_err_probe(&client->dev, -EINVAL, - "invalid IRQ: %d\n", client->irq); - - irq_flags = IRQF_ONESHOT | IRQF_SHARED; - irq_flags |= irqd_get_trigger_type(irq_data); - ret = devm_regmap_add_irq_chip(&client->dev, max77759->regmap_top, - client->irq, irq_flags, 0, + client->irq, IRQF_ONESHOT | IRQF_SHARED, 0, &max77759_pmic_irq_chip, &irq_chip_data_pmic); if (ret) diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 7d14a1e7631e..6be58eb5a746 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c @@ -22,6 +22,7 @@ #include static LIST_HEAD(mfd_of_node_list); +static DEFINE_MUTEX(mfd_of_node_mutex); struct mfd_of_node_entry { struct list_head list; @@ -100,14 +101,15 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev, struct device_node *np, const struct mfd_cell *cell) { -#if IS_ENABLED(CONFIG_OF) struct mfd_of_node_entry *of_entry; u64 of_node_addr; /* Skip if OF node has previously been allocated to a device */ - list_for_each_entry(of_entry, &mfd_of_node_list, list) - if (of_entry->np == np) - return -EAGAIN; + scoped_guard(mutex, &mfd_of_node_mutex) { + list_for_each_entry(of_entry, &mfd_of_node_list, list) + if (of_entry->np == np) + return -EAGAIN; + } if (!cell->use_of_reg) /* No of_reg defined - allocate first free compatible match */ @@ -128,12 +130,11 @@ static int mfd_match_of_node_to_dev(struct platform_device *pdev, return -ENOMEM; of_entry->dev = &pdev->dev; - of_entry->np = np; - list_add_tail(&of_entry->list, &mfd_of_node_list); + of_entry->np = of_node_get(np); + scoped_guard(mutex, &mfd_of_node_mutex) + list_add_tail(&of_entry->list, &mfd_of_node_list); - of_node_get(np); device_set_node(&pdev->dev, of_fwnode_handle(np)); -#endif return 0; } @@ -144,7 +145,6 @@ static int mfd_add_device(struct device *parent, int id, { struct resource *res; struct platform_device *pdev; - struct device_node *np = NULL; struct mfd_of_node_entry *of_entry, *tmp; bool disabled = false; int ret = -ENOMEM; @@ -182,7 +182,7 @@ static int mfd_add_device(struct device *parent, int id, goto fail_res; if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) { - for_each_child_of_node(parent->of_node, np) { + for_each_child_of_node_scoped(parent->of_node, np) { if (of_device_is_compatible(np, cell->of_compatible)) { /* Skip 'disabled' devices */ if (!of_device_is_available(np)) { @@ -193,7 +193,6 @@ static int mfd_add_device(struct device *parent, int id, ret = mfd_match_of_node_to_dev(pdev, np, cell); if (ret == -EAGAIN) continue; - of_node_put(np); if (ret) goto fail_alias; @@ -286,11 +285,13 @@ static int mfd_add_device(struct device *parent, int id, if (cell->swnode) device_remove_software_node(&pdev->dev); fail_of_entry: - list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) - if (of_entry->dev == &pdev->dev) { - list_del(&of_entry->list); - kfree(of_entry); - } + scoped_guard(mutex, &mfd_of_node_mutex) { + list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) + if (of_entry->dev == &pdev->dev) { + list_del(&of_entry->list); + kfree(of_entry); + } + } fail_alias: regulator_bulk_unregister_supply_alias(&pdev->dev, cell->parent_supplies, @@ -360,11 +361,13 @@ static int mfd_remove_devices_fn(struct device *dev, void *data) if (cell->swnode) device_remove_software_node(&pdev->dev); - list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) - if (of_entry->dev == &pdev->dev) { - list_del(&of_entry->list); - kfree(of_entry); - } + scoped_guard(mutex, &mfd_of_node_mutex) { + list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list) + if (of_entry->dev == &pdev->dev) { + list_del(&of_entry->list); + kfree(of_entry); + } + } regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies, cell->num_parent_supplies); diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index a77b6fc790f2..4d29a6e2ed87 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -819,8 +819,10 @@ static void usbhs_omap_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - /* remove children */ - device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child); + if (pdev->dev.of_node) + of_platform_depopulate(&pdev->dev); + else + device_for_each_child(&pdev->dev, NULL, usbhs_omap_remove_child); } static const struct dev_pm_ops usbhsomap_dev_pm_ops = { diff --git a/drivers/mfd/qcom-pm8xxx.c b/drivers/mfd/qcom-pm8xxx.c index 1149f7102a36..0cf374c015ce 100644 --- a/drivers/mfd/qcom-pm8xxx.c +++ b/drivers/mfd/qcom-pm8xxx.c @@ -577,17 +577,11 @@ static int pm8xxx_probe(struct platform_device *pdev) return rc; } -static int pm8xxx_remove_child(struct device *dev, void *unused) -{ - platform_device_unregister(to_platform_device(dev)); - return 0; -} - static void pm8xxx_remove(struct platform_device *pdev) { struct pm_irq_chip *chip = platform_get_drvdata(pdev); - device_for_each_child(&pdev->dev, NULL, pm8xxx_remove_child); + of_platform_depopulate(&pdev->dev); irq_domain_remove(chip->irqdomain); } diff --git a/drivers/mfd/qnap-mcu.c b/drivers/mfd/qnap-mcu.c index f81c69f22254..8de974ddac3e 100644 --- a/drivers/mfd/qnap-mcu.c +++ b/drivers/mfd/qnap-mcu.c @@ -316,6 +316,14 @@ static int qnap_mcu_power_off(struct sys_off_data *data) return NOTIFY_DONE; } +static const struct qnap_mcu_variant qnap_ts133_mcu = { + .baud_rate = 115200, + .num_drives = 1, + .fan_pwm_min = 51, /* Specified in original model.conf */ + .fan_pwm_max = 255, + .usb_led = false, +}; + static const struct qnap_mcu_variant qnap_ts233_mcu = { .baud_rate = 115200, .num_drives = 2, @@ -397,6 +405,7 @@ static int qnap_mcu_probe(struct serdev_device *serdev) } static const struct of_device_id qnap_mcu_dt_ids[] = { + { .compatible = "qnap,ts133-mcu", .data = &qnap_ts133_mcu }, { .compatible = "qnap,ts233-mcu", .data = &qnap_ts233_mcu }, { .compatible = "qnap,ts433-mcu", .data = &qnap_ts433_mcu }, { /* sentinel */ } diff --git a/drivers/mfd/rk8xx-core.c b/drivers/mfd/rk8xx-core.c index def4587fdfb8..3dcf6abfda74 100644 --- a/drivers/mfd/rk8xx-core.c +++ b/drivers/mfd/rk8xx-core.c @@ -37,6 +37,11 @@ static const struct resource rk817_rtc_resources[] = { DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM), }; +static const struct resource rk801_key_resources[] = { + DEFINE_RES_IRQ(RK801_IRQ_PWRON_FALL), + DEFINE_RES_IRQ(RK801_IRQ_PWRON_RISE), +}; + static const struct resource rk805_key_resources[] = { DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE), DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL), @@ -57,6 +62,14 @@ static const struct resource rk817_charger_resources[] = { DEFINE_RES_IRQ(RK817_IRQ_PLUG_OUT), }; +static const struct mfd_cell rk801s[] = { + { .name = "rk808-regulator", }, + { .name = "rk805-pwrkey", + .num_resources = ARRAY_SIZE(rk801_key_resources), + .resources = &rk801_key_resources[0], + }, +}; + static const struct mfd_cell rk805s[] = { { .name = "rk808-clkout", }, { .name = "rk808-regulator", }, @@ -139,6 +152,15 @@ static const struct mfd_cell rk818s[] = { }, }; +static const struct rk808_reg_data rk801_pre_init_reg[] = { + { RK801_SLEEP_CFG_REG, RK801_SLEEP_FUN_MSK, RK801_NONE_FUN }, + { RK801_SYS_CFG2_REG, RK801_RST_MSK, RK801_RST_RESTART_REG_RESETB }, + { RK801_INT_CONFIG_REG, RK801_INT_POL_MSK, RK801_INT_ACT_L }, + { RK801_POWER_FPWM_EN_REG, RK801_PLDO_HRDEC_EN, RK801_PLDO_HRDEC_EN }, + { RK801_BUCK_DEBUG5_REG, MASK_ALL, 0x54 }, + { RK801_CON_BACK1_REG, MASK_ALL, 0x18 }, +}; + static const struct rk808_reg_data rk805_pre_init_reg[] = { {RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK, RK805_BUCK1_2_ILMAX_4000MA}, @@ -284,6 +306,37 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = { VB_LO_SEL_3500MV }, }; +static const struct regmap_irq rk801_irqs[] = { + [RK801_IRQ_PWRON_FALL] = { + .mask = RK801_IRQ_PWRON_FALL_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON_RISE] = { + .mask = RK801_IRQ_PWRON_RISE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON] = { + .mask = RK801_IRQ_PWRON_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_PWRON_LP] = { + .mask = RK801_IRQ_PWRON_LP_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_HOTDIE] = { + .mask = RK801_IRQ_HOTDIE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_VDC_RISE] = { + .mask = RK801_IRQ_VDC_RISE_MSK, + .reg_offset = 0, + }, + [RK801_IRQ_VDC_FALL] = { + .mask = RK801_IRQ_VDC_FALL_MSK, + .reg_offset = 0, + }, +}; + static const struct regmap_irq rk805_irqs[] = { [RK805_IRQ_PWRON_RISE] = { .mask = RK805_IRQ_PWRON_RISE_MSK, @@ -532,6 +585,17 @@ static const struct regmap_irq rk817_irqs[RK817_IRQ_END] = { REGMAP_IRQ_REG_LINE(23, 8) }; +static const struct regmap_irq_chip rk801_irq_chip = { + .name = "rk801", + .irqs = rk801_irqs, + .num_irqs = ARRAY_SIZE(rk801_irqs), + .num_regs = 1, + .status_base = RK801_INT_STS0_REG, + .mask_base = RK801_INT_MASK0_REG, + .ack_base = RK801_INT_STS0_REG, + .init_ack_masked = true, +}; + static const struct regmap_irq_chip rk805_irq_chip = { .name = "rk805", .irqs = rk805_irqs, @@ -610,6 +674,10 @@ static int rk808_power_off(struct sys_off_data *data) unsigned int reg, bit; switch (rk808->variant) { + case RK801_ID: + reg = RK801_SYS_CFG2_REG; + bit = DEV_OFF; + break; case RK805_ID: reg = RK805_DEV_CTRL_REG; bit = DEV_OFF; @@ -714,6 +782,13 @@ int rk8xx_probe(struct device *dev, int variant, unsigned int irq, struct regmap dev_set_drvdata(dev, rk808); switch (rk808->variant) { + case RK801_ID: + rk808->regmap_irq_chip = &rk801_irq_chip; + pre_init_reg = rk801_pre_init_reg; + nr_pre_init_regs = ARRAY_SIZE(rk801_pre_init_reg); + cells = rk801s; + nr_cells = ARRAY_SIZE(rk801s); + break; case RK805_ID: rk808->regmap_irq_chip = &rk805_irq_chip; pre_init_reg = rk805_pre_init_reg; @@ -831,6 +906,12 @@ int rk8xx_suspend(struct device *dev) int ret = 0; switch (rk808->variant) { + case RK801_ID: + ret = regmap_update_bits(rk808->regmap, + RK801_SLEEP_CFG_REG, + RK801_SLEEP_FUN_MSK, + RK801_SLEEP_FUN); + break; case RK805_ID: ret = regmap_update_bits(rk808->regmap, RK805_GPIO_IO_POL_REG, diff --git a/drivers/mfd/rk8xx-i2c.c b/drivers/mfd/rk8xx-i2c.c index 37287b06dab0..2951b2911a37 100644 --- a/drivers/mfd/rk8xx-i2c.c +++ b/drivers/mfd/rk8xx-i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Rockchip RK805/RK808/RK816/RK817/RK818 Core (I2C) driver + * Rockchip RK801/RK805/RK808/RK816/RK817/RK818 Core (I2C) driver * * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd * Copyright (C) 2016 PHYTEC Messtechnik GmbH @@ -21,6 +21,23 @@ struct rk8xx_i2c_platform_data { int variant; }; +static bool rk801_is_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case RK801_SYS_STS_REG: + case RK801_INT_STS0_REG: + case RK801_SYS_CFG0_REG: + case RK801_SYS_CFG1_REG: + case RK801_SYS_CFG2_REG: + case RK801_SYS_CFG3_REG: + case RK801_SYS_CFG4_REG: + case RK801_SLEEP_CFG_REG: + return true; + } + + return false; +} + static bool rk806_is_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { @@ -124,6 +141,14 @@ static const struct regmap_config rk818_regmap_config = { .volatile_reg = rk808_is_volatile_reg, }; +static const struct regmap_config rk801_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = RK801_SYS_CFG3_OTP_REG, + .cache_type = REGCACHE_RBTREE, + .volatile_reg = rk801_is_volatile_reg, +}; + static const struct regmap_config rk805_regmap_config = { .reg_bits = 8, .val_bits = 8, @@ -164,6 +189,11 @@ static const struct regmap_config rk817_regmap_config = { .volatile_reg = rk817_is_volatile_reg, }; +static const struct rk8xx_i2c_platform_data rk801_data = { + .regmap_cfg = &rk801_regmap_config, + .variant = RK801_ID, +}; + static const struct rk8xx_i2c_platform_data rk805_data = { .regmap_cfg = &rk805_regmap_config, .variant = RK805_ID, @@ -224,6 +254,7 @@ static void rk8xx_i2c_shutdown(struct i2c_client *client) static SIMPLE_DEV_PM_OPS(rk8xx_i2c_pm_ops, rk8xx_suspend, rk8xx_resume); static const struct of_device_id rk8xx_i2c_of_match[] = { + { .compatible = "rockchip,rk801", .data = &rk801_data }, { .compatible = "rockchip,rk805", .data = &rk805_data }, { .compatible = "rockchip,rk806", .data = &rk806_data }, { .compatible = "rockchip,rk808", .data = &rk808_data }, diff --git a/drivers/mfd/sec-irq.c b/drivers/mfd/sec-irq.c index ee722fa35f3b..133188391f7c 100644 --- a/drivers/mfd/sec-irq.c +++ b/drivers/mfd/sec-irq.c @@ -257,6 +257,7 @@ static const struct regmap_irq_chip s2mpg10_irq_chip = { static const struct regmap_irq_chip s2mpg10_irq_chip_pmic = { .name = "s2mpg10-pmic", + .domain_suffix = "pmic", .status_base = S2MPG10_PMIC_INT1, .mask_base = S2MPG10_PMIC_INT1M, .num_regs = 6, diff --git a/drivers/mfd/simple-mfd-i2c.c b/drivers/mfd/simple-mfd-i2c.c index 8b751d8e3b5a..7315fad618e4 100644 --- a/drivers/mfd/simple-mfd-i2c.c +++ b/drivers/mfd/simple-mfd-i2c.c @@ -116,6 +116,7 @@ static const struct simple_mfd_data spacemit_p1 = { }; static const struct of_device_id simple_mfd_i2c_of_match[] = { + { .compatible = "delta,tn48m-cpld" }, { .compatible = "fsl,ls1028aqds-fpga" }, { .compatible = "fsl,lx2160aqds-fpga" }, { .compatible = "fsl,lx2160ardb-fpga" }, diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 50bf3260f65d..0ee6d8940e69 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c @@ -1335,7 +1335,7 @@ static int sm501_plat_probe(struct platform_device *dev) struct sm501_devdata *sm; int ret; - sm = kzalloc(sizeof(*sm), GFP_KERNEL); + sm = kzalloc_obj(*sm); if (!sm) { ret = -ENOMEM; goto err1; @@ -1518,7 +1518,7 @@ static int sm501_pci_probe(struct pci_dev *dev, struct sm501_devdata *sm; int err; - sm = kzalloc(sizeof(*sm), GFP_KERNEL); + sm = kzalloc_obj(*sm); if (!sm) { err = -ENOMEM; goto err1; diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index e5d5def594f6..21a7fcdd2737 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c @@ -51,7 +51,7 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_res) WARN_ON(!mutex_is_locked(&syscon_list_lock)); - struct syscon *syscon __free(kfree) = kzalloc(sizeof(*syscon), GFP_KERNEL); + struct syscon *syscon __free(kfree) = kzalloc_obj(*syscon); if (!syscon) return ERR_PTR(-ENOMEM); @@ -212,7 +212,7 @@ int of_syscon_register_regmap(struct device_node *np, struct regmap *regmap) if (!np || !regmap) return -EINVAL; - syscon = kzalloc(sizeof(*syscon), GFP_KERNEL); + syscon = kzalloc_obj(*syscon); if (!syscon) return -ENOMEM; diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index b059713db875..a4d9c070d481 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c @@ -649,7 +649,7 @@ static int timb_probe(struct pci_dev *dev, struct msix_entry *msix_entries = NULL; u8 ip_setup; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -698,8 +698,7 @@ static int timb_probe(struct pci_dev *dev, goto err_config; } - msix_entries = kcalloc(TIMBERDALE_NR_IRQS, sizeof(*msix_entries), - GFP_KERNEL); + msix_entries = kzalloc_objs(*msix_entries, TIMBERDALE_NR_IRQS); if (!msix_entries) goto err_config; diff --git a/drivers/mfd/tps65219.c b/drivers/mfd/tps65219.c index 65a952555218..7275dcdb7c44 100644 --- a/drivers/mfd/tps65219.c +++ b/drivers/mfd/tps65219.c @@ -498,6 +498,15 @@ static int tps65219_probe(struct i2c_client *client) return ret; } + if (chip_id == TPS65214) { + ret = i2c_smbus_write_byte_data(client, TPS65214_REG_LOCK, + TPS65214_LOCK_ACCESS_CMD); + if (ret) { + dev_err(tps->dev, "Failed to unlock registers %d\n", ret); + return ret; + } + } + ret = devm_regmap_add_irq_chip(tps->dev, tps->regmap, client->irq, IRQF_ONESHOT, 0, pmic->irq_chip, &tps->irq_data); diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index d3ab40651307..06809f68b007 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c @@ -631,7 +631,7 @@ int twl4030_sih_setup(struct device *dev, int module, int irq_base) return status; } - agent = kzalloc(sizeof(*agent), GFP_KERNEL); + agent = kzalloc_obj(*agent); if (!agent) return -ENOMEM; diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index 4b450d78a65f..16f64e2b2f77 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c @@ -395,7 +395,7 @@ static int ucb1x00_add_dev(struct ucb1x00 *ucb, struct ucb1x00_driver *drv) struct ucb1x00_dev *dev; int ret; - dev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL); + dev = kmalloc_obj(struct ucb1x00_dev); if (!dev) return -ENOMEM; @@ -513,7 +513,7 @@ static int ucb1x00_probe(struct mcp *mcp) goto out; } - ucb = kzalloc(sizeof(struct ucb1x00), GFP_KERNEL); + ucb = kzalloc_obj(struct ucb1x00); ret = -ENOMEM; if (!ucb) goto out; diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 6e1b38f9f26c..39fe187eea1f 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c @@ -367,7 +367,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) struct input_dev *idev; int err; - ts = kzalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL); + ts = kzalloc_obj(struct ucb1x00_ts); idev = input_allocate_device(); if (!ts || !idev) { err = -ENOMEM; diff --git a/drivers/mfd/viperboard.c b/drivers/mfd/viperboard.c index ba867b7ecfad..f964bcfa0796 100644 --- a/drivers/mfd/viperboard.c +++ b/drivers/mfd/viperboard.c @@ -53,7 +53,7 @@ static int vprbrd_probe(struct usb_interface *interface, int pipe, ret; /* allocate memory for our device state and initialize it */ - vb = kzalloc(sizeof(*vb), GFP_KERNEL); + vb = kzalloc_obj(*vb); if (!vb) return -ENOMEM; diff --git a/drivers/mfd/wm831x-auxadc.c b/drivers/mfd/wm831x-auxadc.c index 18618a8f9206..744e1d161c5a 100644 --- a/drivers/mfd/wm831x-auxadc.c +++ b/drivers/mfd/wm831x-auxadc.c @@ -35,7 +35,7 @@ static int wm831x_auxadc_read_irq(struct wm831x *wm831x, int ret; bool ena = false; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/misc/ad525x_dpot.c b/drivers/misc/ad525x_dpot.c index 04683b981e54..57bead9fba1b 100644 --- a/drivers/misc/ad525x_dpot.c +++ b/drivers/misc/ad525x_dpot.c @@ -686,7 +686,7 @@ int ad_dpot_probe(struct device *dev, struct dpot_data *data; int i, err = 0; - data = kzalloc(sizeof(struct dpot_data), GFP_KERNEL); + data = kzalloc_obj(struct dpot_data); if (!data) { err = -ENOMEM; goto exit; diff --git a/drivers/misc/altera-stapl/altera.c b/drivers/misc/altera-stapl/altera.c index bbe3967c3a4c..4fa6c90624e5 100644 --- a/drivers/misc/altera-stapl/altera.c +++ b/drivers/misc/altera-stapl/altera.c @@ -290,13 +290,13 @@ static int altera_execute(struct altera_state *astate, if (sym_count <= 0) goto exit_done; - vars = kcalloc(sym_count, sizeof(long), GFP_KERNEL); + vars = kzalloc_objs(long, sym_count); if (vars == NULL) status = -ENOMEM; if (status == 0) { - var_size = kcalloc(sym_count, sizeof(s32), GFP_KERNEL); + var_size = kzalloc_objs(s32, sym_count); if (var_size == NULL) status = -ENOMEM; @@ -1098,8 +1098,7 @@ static int altera_execute(struct altera_state *astate, /* Allocate a writable buffer for this array */ count = var_size[variable_id]; long_tmp = vars[variable_id]; - longptr_tmp = kcalloc(count, sizeof(long), - GFP_KERNEL); + longptr_tmp = kzalloc_objs(long, count); vars[variable_id] = (long)longptr_tmp; if (vars[variable_id] == 0) { @@ -2342,8 +2341,7 @@ static int altera_get_act_info(u8 *p, (p[proc_table + (13 * act_proc_id) + 8] & 0x03); procptr = - kzalloc(sizeof(struct altera_procinfo), - GFP_KERNEL); + kzalloc_obj(struct altera_procinfo); if (procptr == NULL) status = -ENOMEM; @@ -2399,7 +2397,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) retval = -ENOMEM; goto free_key; } - astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL); + astate = kzalloc_obj(struct altera_state); if (!astate) { retval = -ENOMEM; goto free_value; diff --git a/drivers/misc/amd-sbi/Kconfig b/drivers/misc/amd-sbi/Kconfig index be022c71a90c..30e7fad7356c 100644 --- a/drivers/misc/amd-sbi/Kconfig +++ b/drivers/misc/amd-sbi/Kconfig @@ -1,10 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only config AMD_SBRMI_I2C tristate "AMD side band RMI support" - depends on I2C + depends on I3C_OR_I2C depends on ARM || ARM64 || COMPILE_TEST select REGMAP_I2C - depends on I3C || !I3C select REGMAP_I3C if I3C help Side band RMI over I2C/I3C support for AMD out of band management. diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 6db4db975b9a..fc504bd8d916 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -217,7 +217,7 @@ static int apds9802als_probe(struct i2c_client *client) int res; struct als_data *data; - data = kzalloc(sizeof(struct als_data), GFP_KERNEL); + data = kzalloc_obj(struct als_data); if (data == NULL) { dev_err(&client->dev, "Memory allocation failed\n"); return -ENOMEM; diff --git a/drivers/misc/apds990x.c b/drivers/misc/apds990x.c index 58946c4ff1a5..b69c3a1c94d1 100644 --- a/drivers/misc/apds990x.c +++ b/drivers/misc/apds990x.c @@ -1055,7 +1055,7 @@ static int apds990x_probe(struct i2c_client *client) struct apds990x_chip *chip; int err; - chip = kzalloc(sizeof *chip, GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; diff --git a/drivers/misc/bcm-vk/bcm_vk_dev.c b/drivers/misc/bcm-vk/bcm_vk_dev.c index d4a96137728d..5773ffb46f0f 100644 --- a/drivers/misc/bcm-vk/bcm_vk_dev.c +++ b/drivers/misc/bcm-vk/bcm_vk_dev.c @@ -1289,7 +1289,7 @@ static int bcm_vk_probe(struct pci_dev *pdev, const struct pci_device_id *ent) u32 boot_status; /* allocate vk structure which is tied to kref for freeing */ - vk = kzalloc(sizeof(*vk), GFP_KERNEL); + vk = kzalloc_obj(*vk); if (!vk) return -ENOMEM; diff --git a/drivers/misc/bcm-vk/bcm_vk_msg.c b/drivers/misc/bcm-vk/bcm_vk_msg.c index 1f42d1d5a630..3916ec07ecad 100644 --- a/drivers/misc/bcm-vk/bcm_vk_msg.c +++ b/drivers/misc/bcm-vk/bcm_vk_msg.c @@ -700,7 +700,7 @@ int bcm_vk_send_shutdown_msg(struct bcm_vk *vk, u32 shut_type, return -EINVAL; } - entry = kzalloc(struct_size(entry, to_v_msg, 1), GFP_KERNEL); + entry = kzalloc_flex(*entry, to_v_msg, 1); if (!entry) return -ENOMEM; entry->to_v_blks = 1; /* always 1 block */ @@ -1010,6 +1010,9 @@ ssize_t bcm_vk_read(struct file *p_file, struct device *dev = &vk->pdev->dev; struct bcm_vk_msg_chan *chan = &vk->to_h_msg_chan; struct bcm_vk_wkent *entry = NULL, *iter; + struct vk_msg_blk tmp_msg; + u32 tmp_usr_msg_id; + u32 tmp_blks; u32 q_num; u32 rsp_length; @@ -1034,6 +1037,9 @@ ssize_t bcm_vk_read(struct file *p_file, entry = iter; } else { /* buffer not big enough */ + tmp_msg = iter->to_h_msg[0]; + tmp_usr_msg_id = iter->usr_msg_id; + tmp_blks = iter->to_h_blks; rc = -EMSGSIZE; } goto read_loop_exit; @@ -1052,14 +1058,12 @@ ssize_t bcm_vk_read(struct file *p_file, bcm_vk_free_wkent(dev, entry); } else if (rc == -EMSGSIZE) { - struct vk_msg_blk tmp_msg = entry->to_h_msg[0]; - /* * in this case, return just the first block, so * that app knows what size it is looking for. */ - set_msg_id(&tmp_msg, entry->usr_msg_id); - tmp_msg.size = entry->to_h_blks - 1; + set_msg_id(&tmp_msg, tmp_usr_msg_id); + tmp_msg.size = tmp_blks - 1; if (copy_to_user(buf, &tmp_msg, VK_MSGQ_BLK_SIZE) != 0) { dev_err(dev, "Error return 1st block in -EMSGSIZE\n"); rc = -EFAULT; diff --git a/drivers/misc/bcm-vk/bcm_vk_sg.c b/drivers/misc/bcm-vk/bcm_vk_sg.c index d309216ee181..8662bb865129 100644 --- a/drivers/misc/bcm-vk/bcm_vk_sg.c +++ b/drivers/misc/bcm-vk/bcm_vk_sg.c @@ -60,9 +60,7 @@ static int bcm_vk_dma_alloc(struct device *dev, dma->nr_pages = last - first + 1; /* Allocate DMA pages */ - dma->pages = kmalloc_array(dma->nr_pages, - sizeof(struct page *), - GFP_KERNEL); + dma->pages = kmalloc_objs(struct page *, dma->nr_pages); if (!dma->pages) return -ENOMEM; diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index babdb60cc46c..54742e849d33 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c @@ -912,7 +912,7 @@ struct c2port_device *c2port_device_register(char *name, unlikely(!ops->c2d_get) || unlikely(!ops->c2d_set)) return ERR_PTR(-EINVAL); - c2dev = kzalloc(sizeof(struct c2port_device), GFP_KERNEL); + c2dev = kzalloc_obj(struct c2port_device); if (unlikely(!c2dev)) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/cardreader/rtsx_pcr.c b/drivers/misc/cardreader/rtsx_pcr.c index f9952d76d6ed..2b6a994c6fe1 100644 --- a/drivers/misc/cardreader/rtsx_pcr.c +++ b/drivers/misc/cardreader/rtsx_pcr.c @@ -1385,8 +1385,7 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr) pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n", PCI_PID(pcr), pcr->ic_version); - pcr->slots = kcalloc(pcr->num_slots, sizeof(struct rtsx_slot), - GFP_KERNEL); + pcr->slots = kzalloc_objs(struct rtsx_slot, pcr->num_slots); if (!pcr->slots) return -ENOMEM; @@ -1494,13 +1493,13 @@ static int rtsx_pci_probe(struct pci_dev *pcidev, if (ret) goto disable; - pcr = kzalloc(sizeof(*pcr), GFP_KERNEL); + pcr = kzalloc_obj(*pcr); if (!pcr) { ret = -ENOMEM; goto release_pci; } - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) { ret = -ENOMEM; goto free_pcr; diff --git a/drivers/misc/cs5535-mfgpt.c b/drivers/misc/cs5535-mfgpt.c index 2b6778d8d166..cdd0e7bda68d 100644 --- a/drivers/misc/cs5535-mfgpt.c +++ b/drivers/misc/cs5535-mfgpt.c @@ -187,7 +187,7 @@ struct cs5535_mfgpt_timer *cs5535_mfgpt_alloc_timer(int timer_nr, int domain) if (timer_nr < 0) goto done; - timer = kmalloc(sizeof(*timer), GFP_KERNEL); + timer = kmalloc_obj(*timer); if (!timer) { /* aw hell */ spin_lock_irqsave(&mfgpt->lock, flags); diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index f721825199ce..0200288d3a7a 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -657,10 +657,8 @@ static int at24_probe(struct i2c_client *client) if (!i2c_fn_i2c && !i2c_fn_block) page_size = 1; - if (!page_size) { - dev_err(dev, "page_size must not be 0!\n"); - return -EINVAL; - } + if (!page_size) + return dev_err_probe(dev, -EINVAL, "page_size must not be 0!\n"); if (!is_power_of_2(page_size)) dev_warn(dev, "page_size looks suspicious (no power of 2)!\n"); @@ -674,11 +672,9 @@ static int at24_probe(struct i2c_client *client) (flags & AT24_FLAG_ADDR16) ? 65536 : 256); } - if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) { - dev_err(dev, - "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); - return -EINVAL; - } + if ((flags & AT24_FLAG_SERIAL) && (flags & AT24_FLAG_MAC)) + return dev_err_probe(dev, -EINVAL, + "invalid device data - cannot have both AT24_FLAG_SERIAL & AT24_FLAG_MAC."); regmap_config.val_bits = 8; regmap_config.reg_bits = (flags & AT24_FLAG_ADDR16) ? 16 : 8; @@ -759,10 +755,8 @@ static int at24_probe(struct i2c_client *client) full_power = acpi_dev_state_d0(&client->dev); if (full_power) { err = regulator_enable(at24->vcc_reg); - if (err) { - dev_err(dev, "Failed to enable vcc regulator\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, "Failed to enable vcc regulator\n"); pm_runtime_set_active(dev); } diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index 883dfd0ed658..bc2cfb75d9bb 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -34,6 +34,7 @@ */ #define FM25_SN_LEN 8 /* serial number length */ +#define FM25_MAX_ID_LEN 9 /* ID length */ #define EE_MAXADDRLEN 3 /* 24 bit addresses, up to 2 MBytes */ struct at25_data { @@ -44,6 +45,8 @@ struct at25_data { struct nvmem_config nvmem_config; struct nvmem_device *nvmem; u8 sernum[FM25_SN_LEN]; + u8 id[FM25_MAX_ID_LEN]; + u8 id_len; }; #define AT25_WREN 0x06 /* latch the write enable */ @@ -64,8 +67,6 @@ struct at25_data { #define AT25_INSTR_BIT3 0x08 /* additional address bit in instr */ -#define FM25_ID_LEN 9 /* ID length */ - /* * Specs often allow 5ms for a page write, sometimes 20ms; * it's important to recover from write timeouts. @@ -180,11 +181,25 @@ static ssize_t sernum_show(struct device *dev, struct device_attribute *attr, ch } static DEVICE_ATTR_RO(sernum); -static struct attribute *sernum_attrs[] = { +static ssize_t jedec_id_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct at25_data *at25; + + at25 = dev_get_drvdata(dev); + + if (!at25->id_len) + return -EOPNOTSUPP; + + return sysfs_emit(buf, "%*phN\n", at25->id_len, at25->id); +} +static DEVICE_ATTR_RO(jedec_id); + +static struct attribute *at25_attrs[] = { &dev_attr_sernum.attr, + &dev_attr_jedec_id.attr, NULL, }; -ATTRIBUTE_GROUPS(sernum); +ATTRIBUTE_GROUPS(at25); /* * Poll Read Status Register with timeout @@ -378,7 +393,7 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip) { struct at25_data *at25 = container_of(chip, struct at25_data, chip); u8 sernum[FM25_SN_LEN]; - u8 id[FM25_ID_LEN]; + u8 id[FM25_MAX_ID_LEN]; u32 val; int i; @@ -388,7 +403,12 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip) chip->byte_len = val; } else { /* Get ID of chip */ - fm25_aux_read(at25, id, FM25_RDID, FM25_ID_LEN); + fm25_aux_read(at25, id, FM25_RDID, FM25_MAX_ID_LEN); + + /* Store the unprocessed ID for exposing via sysfs */ + memcpy(at25->id, id, FM25_MAX_ID_LEN); + at25->id_len = FM25_MAX_ID_LEN; + /* There are inside-out FRAM variations, detect them and reverse the ID bytes */ if (id[6] == 0x7f && id[2] == 0xc2) for (i = 0; i < ARRAY_SIZE(id) / 2; i++) { @@ -398,30 +418,42 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip) id[i] = id[j]; id[j] = tmp; } - if (id[6] != 0xc2) { - dev_err(dev, "Error: no Cypress FRAM with device ID (manufacturer ID bank 7: %02x)\n", id[6]); + + if (id[6] == 0xc2) { + at25->id_len = 9; + switch (id[7]) { + case 0x21 ... 0x26: + chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024; + break; + case 0x2a ... 0x30: + /* CY15B102QN ... CY15B116QN */ + chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13); + break; + default: + dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]); + return -ENODEV; + } + } else if (id[2] == 0x82 && id[3] == 0x06) { + at25->id_len = 8; + switch (id[1]) { + case 0x51 ... 0x54: + /* CY15B102QSN ... CY15B204QSN */ + chip->byte_len = BIT(((id[0] >> 3) & 0x1F) + 9); + break; + default: + dev_err(dev, "Error: unsupported product id %02x\n", id[1]); + return -ENODEV; + } + } else { + dev_err(dev, "Error: unrecognized JEDEC ID format: %*ph\n", + FM25_MAX_ID_LEN, id); return -ENODEV; } - switch (id[7]) { - case 0x21 ... 0x26: - chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024; - break; - case 0x2a ... 0x30: - /* CY15B102QN ... CY15B116QN */ - chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13); - break; - default: - dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]); - return -ENODEV; - } - - if (id[8]) { - fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN); - /* Swap byte order */ - for (i = 0; i < FM25_SN_LEN; i++) - at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i]; - } + fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN); + /* Swap byte order */ + for (i = 0; i < FM25_SN_LEN; i++) + at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i]; } if (chip->byte_len > 64 * 1024) @@ -539,7 +571,7 @@ static struct spi_mem_driver at25_driver = { .driver = { .name = "at25", .of_match_table = at25_of_match, - .dev_groups = sernum_groups, + .dev_groups = at25_groups, }, .id_table = at25_spi_ids, }, diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 9cae6f530679..5230e910a1d1 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -45,6 +45,7 @@ struct eeprom_93xx46_platform_data { #define OP_START 0x4 #define OP_WRITE (OP_START | 0x1) #define OP_READ (OP_START | 0x2) +/* The following addresses are offset for the 1K EEPROM variant in 16-bit mode */ #define ADDR_EWDS 0x00 #define ADDR_ERAL 0x20 #define ADDR_EWEN 0x30 @@ -191,10 +192,7 @@ static int eeprom_93xx46_ew(struct eeprom_93xx46_dev *edev, int is_on) bits = edev->addrlen + 3; cmd_addr = OP_START << edev->addrlen; - if (edev->pdata->flags & EE_ADDR8) - cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << 1; - else - cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS); + cmd_addr |= (is_on ? ADDR_EWEN : ADDR_EWDS) << (edev->addrlen - 6); if (has_quirk_instruction_length(edev)) { cmd_addr <<= 2; @@ -328,10 +326,7 @@ static int eeprom_93xx46_eral(struct eeprom_93xx46_dev *edev) bits = edev->addrlen + 3; cmd_addr = OP_START << edev->addrlen; - if (edev->pdata->flags & EE_ADDR8) - cmd_addr |= ADDR_ERAL << 1; - else - cmd_addr |= ADDR_ERAL; + cmd_addr |= ADDR_ERAL << (edev->addrlen - 6); if (has_quirk_instruction_length(edev)) { cmd_addr <<= 2; diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index a3e4cada3b51..5731d2dc8a57 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -144,7 +144,7 @@ static int max6875_probe(struct i2c_client *client) if (client->addr & 1) return -ENODEV; - data = kzalloc(sizeof(struct max6875_data), GFP_KERNEL); + data = kzalloc_obj(struct max6875_data); if (!data) return -ENOMEM; diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index ca4c420e4a2f..cf6382981777 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -117,7 +117,7 @@ enclosure_register(struct device *dev, const char *name, int components, struct enclosure_component_callbacks *cb) { struct enclosure_device *edev = - kzalloc(struct_size(edev, component, components), GFP_KERNEL); + kzalloc_flex(*edev, component, components); int err, i; BUG_ON(!cb); diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c index ee652ef01534..47356a5d5804 100644 --- a/drivers/misc/fastrpc.c +++ b/drivers/misc/fastrpc.c @@ -22,6 +22,7 @@ #include #include #include +#include #define ADSP_DOMAIN_ID (0) #define MDSP_DOMAIN_ID (1) @@ -33,7 +34,6 @@ #define FASTRPC_ALIGN 128 #define FASTRPC_MAX_FDLIST 16 #define FASTRPC_MAX_CRCLIST 64 -#define FASTRPC_PHYS(p) ((p) & 0xffffffff) #define FASTRPC_CTX_MAX (256) #define FASTRPC_INIT_HANDLE 1 #define FASTRPC_DSP_UTILITIES_HANDLE 2 @@ -106,7 +106,7 @@ #define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev) struct fastrpc_phy_page { - u64 addr; /* physical address */ + dma_addr_t addr; /* dma address */ u64 size; /* size of contiguous region */ }; @@ -171,7 +171,7 @@ struct fastrpc_msg { u64 ctx; /* invoke caller context */ u32 handle; /* handle to invoke */ u32 sc; /* scalars structure describing the data */ - u64 addr; /* physical address */ + dma_addr_t addr; /* dma address */ u64 size; /* size of contiguous region */ }; @@ -194,7 +194,7 @@ struct fastrpc_buf { struct dma_buf *dmabuf; struct device *dev; void *virt; - u64 phys; + dma_addr_t dma_addr; u64 size; /* Lock for dma buf attachments */ struct mutex lock; @@ -217,7 +217,7 @@ struct fastrpc_map { struct dma_buf *buf; struct sg_table *table; struct dma_buf_attachment *attach; - u64 phys; + dma_addr_t dma_addr; u64 size; void *va; u64 len; @@ -257,6 +257,12 @@ struct fastrpc_session_ctx { bool valid; }; +struct fastrpc_soc_data { + u32 sid_pos; + u32 dma_addr_bits_cdsp; + u32 dma_addr_bits_default; +}; + struct fastrpc_channel_ctx { int domain_id; int sesscount; @@ -278,6 +284,7 @@ struct fastrpc_channel_ctx { bool secure; bool unsigned_support; u64 dma_mask; + const struct fastrpc_soc_data *soc_data; }; struct fastrpc_device { @@ -305,6 +312,24 @@ struct fastrpc_user { struct mutex mutex; }; +/* Extract SMMU PA from consolidated IOVA */ +static inline dma_addr_t fastrpc_ipa_to_dma_addr(struct fastrpc_channel_ctx *cctx, dma_addr_t iova) +{ + if (!cctx->soc_data->sid_pos) + return 0; + return iova & GENMASK_ULL(cctx->soc_data->sid_pos - 1, 0); +} + +/* + * Prepare the consolidated iova to send to DSP by prepending the SID + * to smmu PA at the appropriate position + */ +static inline u64 fastrpc_sid_offset(struct fastrpc_channel_ctx *cctx, + struct fastrpc_session_ctx *sctx) +{ + return (u64)sctx->sid << cctx->soc_data->sid_pos; +} + static void fastrpc_free_map(struct kref *ref) { struct fastrpc_map *map; @@ -320,11 +345,12 @@ static void fastrpc_free_map(struct kref *ref) perm.vmid = QCOM_SCM_VMID_HLOS; perm.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(map->phys, map->len, + err = qcom_scm_assign_mem(map->dma_addr, map->len, &src_perms, &perm, 1); if (err) { - dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - map->phys, map->len, err); + dev_err(map->fl->sctx->dev, + "Failed to assign memory dma_addr %pad size 0x%llx err %d\n", + &map->dma_addr, map->len, err); return; } } @@ -389,7 +415,7 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd, static void fastrpc_buf_free(struct fastrpc_buf *buf) { dma_free_coherent(buf->dev, buf->size, buf->virt, - FASTRPC_PHYS(buf->phys)); + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr)); kfree(buf); } @@ -398,7 +424,7 @@ static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, { struct fastrpc_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return -ENOMEM; @@ -408,12 +434,12 @@ static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf->fl = fl; buf->virt = NULL; - buf->phys = 0; + buf->dma_addr = 0; buf->size = size; buf->dev = dev; buf->raddr = 0; - buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys, + buf->virt = dma_alloc_coherent(dev, buf->size, &buf->dma_addr, GFP_KERNEL); if (!buf->virt) { mutex_destroy(&buf->lock); @@ -439,7 +465,7 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev, buf = *obuf; if (fl->sctx && fl->sctx->sid) - buf->phys += ((u64)fl->sctx->sid << 32); + buf->dma_addr += fastrpc_sid_offset(fl->cctx, fl->sctx); return 0; } @@ -574,7 +600,7 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( unsigned long flags; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); @@ -585,14 +611,12 @@ static struct fastrpc_invoke_ctx *fastrpc_context_alloc( REMOTE_SCALARS_OUTBUFS(sc); if (ctx->nscalars) { - ctx->maps = kcalloc(ctx->nscalars, - sizeof(*ctx->maps), GFP_KERNEL); + ctx->maps = kzalloc_objs(*ctx->maps, ctx->nscalars); if (!ctx->maps) { kfree(ctx); return ERR_PTR(-ENOMEM); } - ctx->olaps = kcalloc(ctx->nscalars, - sizeof(*ctx->olaps), GFP_KERNEL); + ctx->olaps = kzalloc_objs(*ctx->olaps, ctx->nscalars); if (!ctx->olaps) { kfree(ctx->maps); kfree(ctx); @@ -679,12 +703,13 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf, struct fastrpc_buf *buffer = dmabuf->priv; int ret; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return -ENOMEM; ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt, - FASTRPC_PHYS(buffer->phys), buffer->size); + fastrpc_ipa_to_dma_addr(buffer->fl->cctx, buffer->dma_addr), + buffer->size); if (ret < 0) { dev_err(buffer->dev, "failed to get scatterlist from DMA API\n"); kfree(a); @@ -733,7 +758,7 @@ static int fastrpc_mmap(struct dma_buf *dmabuf, dma_resv_assert_held(dmabuf->resv); return dma_mmap_coherent(buf->dev, vma, buf->virt, - FASTRPC_PHYS(buf->phys), size); + fastrpc_ipa_to_dma_addr(buf->fl->cctx, buf->dma_addr), size); } static const struct dma_buf_ops fastrpc_dma_buf_ops = { @@ -746,6 +771,11 @@ static const struct dma_buf_ops fastrpc_dma_buf_ops = { .release = fastrpc_release, }; +static dma_addr_t fastrpc_compute_dma_addr(struct fastrpc_user *fl, dma_addr_t sg_dma_addr) +{ + return sg_dma_addr + fastrpc_sid_offset(fl->cctx, fl->sctx); +} + static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, u64 len, u32 attr, struct fastrpc_map **ppmap) { @@ -755,7 +785,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, struct scatterlist *sgl = NULL; int err = 0, sgl_index = 0; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return -ENOMEM; @@ -784,12 +814,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, } map->table = table; - if (attr & FASTRPC_ATTR_SECUREMAP) { - map->phys = sg_phys(map->table->sgl); - } else { - map->phys = sg_dma_address(map->table->sgl); - map->phys += ((u64)fl->sctx->sid << 32); - } + if (attr & FASTRPC_ATTR_SECUREMAP) + map->dma_addr = sg_phys(map->table->sgl); + else + map->dma_addr = fastrpc_compute_dma_addr(fl, sg_dma_address(map->table->sgl)); for_each_sg(map->table->sgl, sgl, map->table->nents, sgl_index) map->size += sg_dma_len(sgl); @@ -815,10 +843,11 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd, dst_perms[1].vmid = fl->cctx->vmperms[0].vmid; dst_perms[1].perm = QCOM_SCM_PERM_RWX; map->attr = attr; - err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2); + err = qcom_scm_assign_mem(map->dma_addr, (u64)map->len, &src_perms, dst_perms, 2); if (err) { - dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - map->phys, map->len, err); + dev_err(sess->dev, + "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n", + &map->dma_addr, map->len, err); goto map_err; } } @@ -1009,7 +1038,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) struct vm_area_struct *vma = NULL; rpra[i].buf.pv = (u64) ctx->args[i].ptr; - pages[i].addr = ctx->maps[i]->phys; + pages[i].addr = ctx->maps[i]->dma_addr; mmap_read_lock(current->mm); vma = find_vma(current->mm, ctx->args[i].ptr); @@ -1036,7 +1065,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) goto bail; rpra[i].buf.pv = args - ctx->olaps[oix].offset; - pages[i].addr = ctx->buf->phys - + pages[i].addr = ctx->buf->dma_addr - ctx->olaps[oix].offset + (pkt_size - rlen); pages[i].addr = pages[i].addr & PAGE_MASK; @@ -1068,7 +1097,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx) list[i].num = ctx->args[i].length ? 1 : 0; list[i].pgidx = i; if (ctx->maps[i]) { - pages[i].addr = ctx->maps[i]->phys; + pages[i].addr = ctx->maps[i]->dma_addr; pages[i].size = ctx->maps[i]->size; } rpra[i].dma.fd = ctx->args[i].fd; @@ -1150,7 +1179,7 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx, msg->ctx = ctx->ctxid | fl->pd; msg->handle = handle; msg->sc = ctx->sc; - msg->addr = ctx->buf ? ctx->buf->phys : 0; + msg->addr = ctx->buf ? ctx->buf->dma_addr : 0; msg->size = roundup(ctx->msg_sz, PAGE_SIZE); fastrpc_context_get(ctx); @@ -1276,7 +1305,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, } inbuf; u32 sc; - args = kcalloc(FASTRPC_CREATE_STATIC_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); + args = kzalloc_objs(*args, FASTRPC_CREATE_STATIC_PROCESS_NARGS); if (!args) return -ENOMEM; @@ -1306,13 +1335,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, if (fl->cctx->vmcount) { u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, + err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr, (u64)fl->cctx->remote_heap->size, &src_perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, + "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n", + &fl->cctx->remote_heap->dma_addr, + fl->cctx->remote_heap->size, err); goto err_map; } scm_done = true; @@ -1332,7 +1363,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, args[1].length = inbuf.namelen; args[1].fd = -1; - pages[0].addr = fl->cctx->remote_heap->phys; + pages[0].addr = fl->cctx->remote_heap->dma_addr; pages[0].size = fl->cctx->remote_heap->size; args[2].ptr = (u64)(uintptr_t) pages; @@ -1361,12 +1392,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl, dst_perms.vmid = QCOM_SCM_VMID_HLOS; dst_perms.perm = QCOM_SCM_PERM_RWX; - err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys, + err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr, (u64)fl->cctx->remote_heap->size, &src_perms, &dst_perms, 1); if (err) - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n", - fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err); + dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n", + &fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err); } err_map: fastrpc_buf_free(fl->cctx->remote_heap); @@ -1399,7 +1430,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, u32 sc; bool unsigned_module = false; - args = kcalloc(FASTRPC_CREATE_PROCESS_NARGS, sizeof(*args), GFP_KERNEL); + args = kzalloc_objs(*args, FASTRPC_CREATE_PROCESS_NARGS); if (!args) return -ENOMEM; @@ -1455,7 +1486,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl, args[2].length = inbuf.filelen; args[2].fd = init.filefd; - pages[0].addr = imem->phys; + pages[0].addr = imem->dma_addr; pages[0].size = imem->size; args[3].ptr = (u64)(uintptr_t) pages; @@ -1594,7 +1625,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) fdevice = miscdev_to_fdevice(filp->private_data); cctx = fdevice->cctx; - fl = kzalloc(sizeof(*fl), GFP_KERNEL); + fl = kzalloc_obj(*fl); if (!fl) return -ENOMEM; @@ -1701,7 +1732,7 @@ static int fastrpc_invoke(struct fastrpc_user *fl, char __user *argp) /* nscalars is truncated here to max supported value */ nscalars = REMOTE_SCALARS_LENGTH(inv.sc); if (nscalars) { - args = kcalloc(nscalars, sizeof(*args), GFP_KERNEL); + args = kzalloc_objs(*args, nscalars); if (!args) return -ENOMEM; @@ -1913,7 +1944,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - pages.addr = buf->phys; + pages.addr = buf->dma_addr; pages.size = buf->size; args[1].ptr = (u64) (uintptr_t) &pages; @@ -1941,11 +1972,12 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp) if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { u64 src_perms = BIT(QCOM_SCM_VMID_HLOS); - err = qcom_scm_assign_mem(buf->phys, (u64)buf->size, + err = qcom_scm_assign_mem(buf->dma_addr, (u64)buf->size, &src_perms, fl->cctx->vmperms, fl->cctx->vmcount); if (err) { - dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d", - buf->phys, buf->size, err); + dev_err(fl->sctx->dev, + "Failed to assign memory dma_addr %pad size 0x%llx err %d", + &buf->dma_addr, buf->size, err); goto err_assign; } } @@ -2059,7 +2091,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp) args[0].ptr = (u64) (uintptr_t) &req_msg; args[0].length = sizeof(req_msg); - pages.addr = map->phys; + pages.addr = map->dma_addr; pages.size = map->len; args[1].ptr = (u64) (uintptr_t) &pages; @@ -2165,6 +2197,7 @@ static int fastrpc_cb_probe(struct platform_device *pdev) int i, sessions = 0; unsigned long flags; int rc; + u32 dma_bits; cctx = dev_get_drvdata(dev->parent); if (!cctx) @@ -2178,12 +2211,16 @@ static int fastrpc_cb_probe(struct platform_device *pdev) spin_unlock_irqrestore(&cctx->lock, flags); return -ENOSPC; } + dma_bits = cctx->soc_data->dma_addr_bits_default; sess = &cctx->session[cctx->sesscount++]; sess->used = false; sess->valid = true; sess->dev = dev; dev_set_drvdata(dev, sess); + if (cctx->domain_id == CDSP_DOMAIN_ID) + dma_bits = cctx->soc_data->dma_addr_bits_cdsp; + if (of_property_read_u32(dev->of_node, "reg", &sess->sid)) dev_info(dev, "FastRPC Session ID not specified in DT\n"); @@ -2198,9 +2235,9 @@ static int fastrpc_cb_probe(struct platform_device *pdev) } } spin_unlock_irqrestore(&cctx->lock, flags); - rc = dma_set_mask(dev, DMA_BIT_MASK(32)); + rc = dma_set_mask(dev, DMA_BIT_MASK(dma_bits)); if (rc) { - dev_err(dev, "32-bit DMA enable failed\n"); + dev_err(dev, "%u-bit DMA enable failed\n", dma_bits); return rc; } @@ -2285,6 +2322,18 @@ static int fastrpc_get_domain_id(const char *domain) return -EINVAL; } +static const struct fastrpc_soc_data kaanapali_soc_data = { + .sid_pos = 56, + .dma_addr_bits_cdsp = 34, + .dma_addr_bits_default = 32, +}; + +static const struct fastrpc_soc_data default_soc_data = { + .sid_pos = 32, + .dma_addr_bits_cdsp = 32, + .dma_addr_bits_default = 32, +}; + static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) { struct device *rdev = &rpdev->dev; @@ -2293,6 +2342,9 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) const char *domain; bool secure_dsp; unsigned int vmids[FASTRPC_MAX_VMIDS]; + const struct fastrpc_soc_data *soc_data; + + soc_data = device_get_match_data(rdev); err = of_property_read_string(rdev->of_node, "label", &domain); if (err) { @@ -2317,7 +2369,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) else if (!qcom_scm_is_available()) return -EPROBE_DEFER; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -2345,6 +2397,7 @@ static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev) secure_dsp = !(of_property_read_bool(rdev->of_node, "qcom,non-secure-domain")); data->secure = secure_dsp; + data->soc_data = soc_data; switch (domain_id) { case ADSP_DOMAIN_ID: @@ -2482,7 +2535,8 @@ static int fastrpc_rpmsg_callback(struct rpmsg_device *rpdev, void *data, } static const struct of_device_id fastrpc_rpmsg_of_match[] = { - { .compatible = "qcom,fastrpc" }, + { .compatible = "qcom,kaanapali-fastrpc", .data = &kaanapali_soc_data }, + { .compatible = "qcom,fastrpc", .data = &default_soc_data }, { }, }; MODULE_DEVICE_TABLE(of, fastrpc_rpmsg_of_match); diff --git a/drivers/misc/genwqe/card_base.c b/drivers/misc/genwqe/card_base.c index 224a7e97cbea..86bfa82723ff 100644 --- a/drivers/misc/genwqe/card_base.c +++ b/drivers/misc/genwqe/card_base.c @@ -141,7 +141,7 @@ static struct genwqe_dev *genwqe_dev_alloc(void) if (i >= GENWQE_CARD_NO_MAX) return ERR_PTR(-ENODEV); - cd = kzalloc(sizeof(struct genwqe_dev), GFP_KERNEL); + cd = kzalloc_obj(struct genwqe_dev); if (!cd) return ERR_PTR(-ENOMEM); @@ -403,8 +403,7 @@ static int genwqe_ffdc_buffs_alloc(struct genwqe_dev *cd) /* currently support only the debug units mentioned here */ cd->ffdc[type].entries = e; cd->ffdc[type].regs = - kmalloc_array(e, sizeof(struct genwqe_reg), - GFP_KERNEL); + kmalloc_objs(struct genwqe_reg, e); /* * regs == NULL is ok, the using code treats this as no regs, * Printing warning is ok in this case. diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c index fd7d5cd50d39..969178573940 100644 --- a/drivers/misc/genwqe/card_ddcb.c +++ b/drivers/misc/genwqe/card_ddcb.c @@ -194,7 +194,7 @@ struct genwqe_ddcb_cmd *ddcb_requ_alloc(void) { struct ddcb_requ *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return NULL; @@ -1046,16 +1046,13 @@ static int setup_ddcb_queue(struct genwqe_dev *cd, struct ddcb_queue *queue) "[%s] **err: could not allocate DDCB **\n", __func__); return -ENOMEM; } - queue->ddcb_req = kcalloc(queue->ddcb_max, sizeof(struct ddcb_requ *), - GFP_KERNEL); + queue->ddcb_req = kzalloc_objs(struct ddcb_requ *, queue->ddcb_max); if (!queue->ddcb_req) { rc = -ENOMEM; goto free_ddcbs; } - queue->ddcb_waitqs = kcalloc(queue->ddcb_max, - sizeof(wait_queue_head_t), - GFP_KERNEL); + queue->ddcb_waitqs = kzalloc_objs(wait_queue_head_t, queue->ddcb_max); if (!queue->ddcb_waitqs) { rc = -ENOMEM; goto free_requs; diff --git a/drivers/misc/genwqe/card_debugfs.c b/drivers/misc/genwqe/card_debugfs.c index 491fb4482da2..53cc17306b22 100644 --- a/drivers/misc/genwqe/card_debugfs.c +++ b/drivers/misc/genwqe/card_debugfs.c @@ -53,7 +53,7 @@ static int curr_dbg_uidn_show(struct seq_file *s, void *unused, int uid) if (entries == 0) return 0; - regs = kcalloc(entries, sizeof(*regs), GFP_KERNEL); + regs = kzalloc_objs(*regs, entries); if (regs == NULL) return -ENOMEM; @@ -122,7 +122,7 @@ static int curr_regs_show(struct seq_file *s, void *unused) unsigned int i; struct genwqe_reg *regs; - regs = kcalloc(GENWQE_FFDC_REGS, sizeof(*regs), GFP_KERNEL); + regs = kzalloc_objs(*regs, GENWQE_FFDC_REGS); if (regs == NULL) return -ENOMEM; diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 4441aca2280a..5a07e8403e97 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -301,7 +301,7 @@ static int genwqe_open(struct inode *inode, struct file *filp) struct genwqe_dev *cd; struct genwqe_file *cfile; - cfile = kzalloc(sizeof(*cfile), GFP_KERNEL); + cfile = kzalloc_obj(*cfile); if (cfile == NULL) return -ENOMEM; @@ -446,7 +446,7 @@ static int genwqe_mmap(struct file *filp, struct vm_area_struct *vma) if (get_order(vsize) > MAX_PAGE_ORDER) return -ENOMEM; - dma_map = kzalloc(sizeof(struct dma_mapping), GFP_KERNEL); + dma_map = kzalloc_obj(struct dma_mapping); if (dma_map == NULL) return -ENOMEM; @@ -783,7 +783,7 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m) map_addr = (m->addr & PAGE_MASK); map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE); - dma_map = kzalloc(sizeof(struct dma_mapping), GFP_KERNEL); + dma_map = kzalloc_obj(struct dma_mapping); if (dma_map == NULL) return -ENOMEM; diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c index 04bd34c8c506..ff3f03ea577e 100644 --- a/drivers/misc/hpilo.c +++ b/drivers/misc/hpilo.c @@ -570,7 +570,7 @@ static int ilo_open(struct inode *ip, struct file *fp) hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev); /* new ccb allocation */ - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -798,7 +798,7 @@ static int ilo_probe(struct pci_dev *pdev, /* track global allocations for this device */ error = -ENOMEM; - ilo_hw = kzalloc(sizeof(*ilo_hw), GFP_KERNEL); + ilo_hw = kzalloc_obj(*ilo_hw); if (!ilo_hw) goto out; diff --git a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c index 733dd30fbacc..6b037675ff45 100644 --- a/drivers/misc/ibmasm/command.c +++ b/drivers/misc/ibmasm/command.c @@ -24,7 +24,7 @@ struct command *ibmasm_new_command(struct service_processor *sp, size_t buffer_s if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE) return NULL; - cmd = kzalloc(sizeof(struct command), GFP_KERNEL); + cmd = kzalloc_obj(struct command); if (cmd == NULL) return NULL; diff --git a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c index 40ce75f8970c..3990bf2b1728 100644 --- a/drivers/misc/ibmasm/event.c +++ b/drivers/misc/ibmasm/event.c @@ -139,7 +139,7 @@ int ibmasm_event_buffer_init(struct service_processor *sp) struct ibmasm_event *event; int i; - buffer = kmalloc(sizeof(struct event_buffer), GFP_KERNEL); + buffer = kmalloc_obj(struct event_buffer); if (!buffer) return -ENOMEM; diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 824c5b664985..f68a8957b98f 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -235,7 +235,7 @@ static int command_file_open(struct inode *inode, struct file *file) if (!inode->i_private) return -ENODEV; - command_data = kmalloc(sizeof(struct ibmasmfs_command_data), GFP_KERNEL); + command_data = kmalloc_obj(struct ibmasmfs_command_data); if (!command_data) return -ENOMEM; @@ -344,7 +344,7 @@ static int event_file_open(struct inode *inode, struct file *file) sp = inode->i_private; - event_data = kmalloc(sizeof(struct ibmasmfs_event_data), GFP_KERNEL); + event_data = kmalloc_obj(struct ibmasmfs_event_data); if (!event_data) return -ENOMEM; @@ -430,7 +430,7 @@ static int r_heartbeat_file_open(struct inode *inode, struct file *file) if (!inode->i_private) return -ENODEV; - rhbeat = kmalloc(sizeof(struct ibmasmfs_heartbeat_data), GFP_KERNEL); + rhbeat = kmalloc_obj(struct ibmasmfs_heartbeat_data); if (!rhbeat) return -ENOMEM; diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c index dc8a06c06c63..4509c15a76a8 100644 --- a/drivers/misc/ibmasm/module.c +++ b/drivers/misc/ibmasm/module.c @@ -64,7 +64,7 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id) /* vnc client won't work without bus-mastering */ pci_set_master(pdev); - sp = kzalloc(sizeof(struct service_processor), GFP_KERNEL); + sp = kzalloc_obj(struct service_processor); if (sp == NULL) { dev_err(&pdev->dev, "Failed to allocate memory\n"); result = -ENOMEM; diff --git a/drivers/misc/ibmvmc.c b/drivers/misc/ibmvmc.c index e5f935b5249d..beb18c34f20d 100644 --- a/drivers/misc/ibmvmc.c +++ b/drivers/misc/ibmvmc.c @@ -830,7 +830,7 @@ static int ibmvmc_open(struct inode *inode, struct file *file) (unsigned long)inode, (unsigned long)file, ibmvmc.state); - session = kzalloc(sizeof(*session), GFP_KERNEL); + session = kzalloc_obj(*session); if (!session) return -ENOMEM; diff --git a/drivers/misc/ics932s401.c b/drivers/misc/ics932s401.c index 4cdb1087838f..015710762a65 100644 --- a/drivers/misc/ics932s401.c +++ b/drivers/misc/ics932s401.c @@ -433,7 +433,7 @@ static int ics932s401_probe(struct i2c_client *client) struct ics932s401_data *data; int err; - data = kzalloc(sizeof(struct ics932s401_data), GFP_KERNEL); + data = kzalloc_obj(struct ics932s401_data); if (!data) { err = -ENOMEM; goto exit; diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index 9f26db467a81..95480e16ae5f 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -383,7 +383,7 @@ static int isl29003_probe(struct i2c_client *client) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) return -EIO; - data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL); + data = kzalloc_obj(struct isl29003_data); if (!data) return -ENOMEM; diff --git a/drivers/misc/keba/cp500.c b/drivers/misc/keba/cp500.c index d0c6113dcff3..6c65fbf22e75 100644 --- a/drivers/misc/keba/cp500.c +++ b/drivers/misc/keba/cp500.c @@ -335,7 +335,7 @@ static int cp500_register_i2c(struct cp500 *cp500) { int ret; - cp500->i2c = kzalloc(sizeof(*cp500->i2c), GFP_KERNEL); + cp500->i2c = kzalloc_obj(*cp500->i2c); if (!cp500->i2c) return -ENOMEM; @@ -386,7 +386,7 @@ static int cp500_register_spi(struct cp500 *cp500, u8 esc_type) int info_size; int ret; - cp500->spi = kzalloc(sizeof(*cp500->spi), GFP_KERNEL); + cp500->spi = kzalloc_obj(*cp500->spi); if (!cp500->spi) return -ENOMEM; @@ -443,7 +443,7 @@ static int cp500_register_fan(struct cp500 *cp500) { int ret; - cp500->fan = kzalloc(sizeof(*cp500->fan), GFP_KERNEL); + cp500->fan = kzalloc_obj(*cp500->fan); if (!cp500->fan) return -ENOMEM; @@ -491,7 +491,7 @@ static int cp500_register_batt(struct cp500 *cp500) { int ret; - cp500->batt = kzalloc(sizeof(*cp500->batt), GFP_KERNEL); + cp500->batt = kzalloc_obj(*cp500->batt); if (!cp500->batt) return -ENOMEM; @@ -541,7 +541,7 @@ static int cp500_register_uart(struct cp500 *cp500, { int ret; - *uart = kzalloc(sizeof(**uart), GFP_KERNEL); + *uart = kzalloc_obj(**uart); if (!*uart) return -ENOMEM; diff --git a/drivers/misc/kgdbts.c b/drivers/misc/kgdbts.c index 3b7a041ea351..9d3218330f0a 100644 --- a/drivers/misc/kgdbts.c +++ b/drivers/misc/kgdbts.c @@ -1067,7 +1067,7 @@ static void kgdbts_run_tests(void) configured = 0; } -static int kgdbts_option_setup(char *opt) +static int __init kgdbts_option_setup(char *opt) { if (strlen(opt) >= MAX_CONFIG_LEN) { printk(KERN_ERR "kgdbts: config string too long\n"); diff --git a/drivers/misc/lan966x_pci.c b/drivers/misc/lan966x_pci.c index 9c79b58137e5..0bb90c0943bf 100644 --- a/drivers/misc/lan966x_pci.c +++ b/drivers/misc/lan966x_pci.c @@ -58,7 +58,7 @@ static struct pci_dev_intr_ctrl *pci_dev_create_intr_ctrl(struct pci_dev *pdev) if (!fwnode) return ERR_PTR(-ENODEV); - intr_ctrl = kmalloc(sizeof(*intr_ctrl), GFP_KERNEL); + intr_ctrl = kmalloc_obj(*intr_ctrl); if (!intr_ctrl) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 1a634ac1a241..9c68f8b1d5d6 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c @@ -952,7 +952,7 @@ int lis3lv02d_init_dt(struct lis3lv02d *lis3) if (!lis3->of_node) return 0; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return -ENOMEM; diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index b2aee36b956d..e0098f314570 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -477,7 +477,7 @@ static void lkdtm_FAM_BOUNDS(void) { struct lkdtm_cb_fam *inst; - inst = kzalloc(struct_size(inst, array, element_count + 1), GFP_KERNEL); + inst = kzalloc_flex(*inst, array, element_count + 1); if (!inst) { pr_err("FAIL: could not allocate test struct!\n"); return; @@ -533,7 +533,7 @@ static void lkdtm_PTR_BOUNDS(void) { struct lkdtm_cb_ptr *inst; - inst = kzalloc(sizeof(*inst), GFP_KERNEL); + inst = kzalloc_obj(*inst); if (!inst) { pr_err("FAIL: could not allocate struct lkdtm_cb_ptr!\n"); return; @@ -547,7 +547,7 @@ static void lkdtm_PTR_BOUNDS(void) inst->len = element_count; /* Double element_count */ - inst->extra = kcalloc(element_count * 2, sizeof(*inst->extra), GFP_KERNEL); + inst->extra = kzalloc_objs(*inst->extra, element_count * 2); inst->nr_extra = element_count * 2; pr_info("Pointer access within bounds ...\n"); diff --git a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c index 34c9be437432..48bea1117771 100644 --- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c +++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gp.c @@ -42,8 +42,7 @@ static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id if (!aux_bus) return -ENOMEM; - aux_bus->aux_device_wrapper[0] = kzalloc(sizeof(*aux_bus->aux_device_wrapper[0]), - GFP_KERNEL); + aux_bus->aux_device_wrapper[0] = kzalloc_obj(*aux_bus->aux_device_wrapper[0]); if (!aux_bus->aux_device_wrapper[0]) return -ENOMEM; @@ -67,8 +66,7 @@ static int gp_aux_bus_probe(struct pci_dev *pdev, const struct pci_device_id *id if (retval) goto err_aux_dev_add_0; - aux_bus->aux_device_wrapper[1] = kzalloc(sizeof(*aux_bus->aux_device_wrapper[1]), - GFP_KERNEL); + aux_bus->aux_device_wrapper[1] = kzalloc_obj(*aux_bus->aux_device_wrapper[1]); if (!aux_bus->aux_device_wrapper[1]) { retval = -ENOMEM; goto err_aux_dev_add_0; diff --git a/drivers/misc/mei/Kconfig b/drivers/misc/mei/Kconfig index f4eb307cd35e..5902dd1ee44b 100644 --- a/drivers/misc/mei/Kconfig +++ b/drivers/misc/mei/Kconfig @@ -2,7 +2,7 @@ # Copyright (c) 2003-2019, Intel Corporation. All rights reserved. config INTEL_MEI tristate "Intel Management Engine Interface" - depends on X86 && PCI + depends on PCI default X86_64 || MATOM help The Intel Management Engine (Intel ME) provides Manageability, @@ -49,7 +49,7 @@ config INTEL_MEI_TXE config INTEL_MEI_GSC tristate "Intel MEI GSC embedded device" depends on INTEL_MEI_ME - depends on DRM_I915 || DRM_XE + depends on DRM_I915!=n || DRM_XE!=n || COMPILE_TEST help Intel auxiliary driver for GSC devices embedded in Intel graphics devices. @@ -84,7 +84,7 @@ config INTEL_MEI_VSC config INTEL_MEI_LB tristate "Intel Late Binding (LB) support on ME Interface" depends on INTEL_MEI_ME - depends on DRM_XE + depends on DRM_XE!=n || COMPILE_TEST help Enable support for Intel Late Binding (LB) via the MEI interface. diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index 2c810ab12e62..f739dbcdb04c 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c @@ -1363,7 +1363,7 @@ static struct mei_cl_device *mei_cl_bus_dev_alloc(struct mei_device *bus, struct mei_cl_device *cldev; struct mei_cl *cl; - cldev = kzalloc(sizeof(*cldev), GFP_KERNEL); + cldev = kzalloc_obj(*cldev); if (!cldev) return NULL; diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c index 5dc665515263..643b0039cc72 100644 --- a/drivers/misc/mei/client.c +++ b/drivers/misc/mei/client.c @@ -370,7 +370,7 @@ static struct mei_cl_cb *mei_io_cb_init(struct mei_cl *cl, { struct mei_cl_cb *cb; - cb = kzalloc(sizeof(*cb), GFP_KERNEL); + cb = kzalloc_obj(*cb); if (!cb) return NULL; @@ -605,7 +605,7 @@ struct mei_cl *mei_cl_allocate(struct mei_device *dev) { struct mei_cl *cl; - cl = kmalloc(sizeof(*cl), GFP_KERNEL); + cl = kmalloc_obj(*cl); if (!cl) return NULL; @@ -1273,7 +1273,7 @@ struct mei_cl_vtag *mei_cl_vtag_alloc(struct file *fp, u8 vtag) { struct mei_cl_vtag *cl_vtag; - cl_vtag = kzalloc(sizeof(*cl_vtag), GFP_KERNEL); + cl_vtag = kzalloc_obj(*cl_vtag); if (!cl_vtag) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/mei/gsc_proxy/Kconfig b/drivers/misc/mei/gsc_proxy/Kconfig index ac78b9d1eccd..bd8f955f548e 100644 --- a/drivers/misc/mei/gsc_proxy/Kconfig +++ b/drivers/misc/mei/gsc_proxy/Kconfig @@ -4,7 +4,7 @@ config INTEL_MEI_GSC_PROXY tristate "Intel GSC Proxy services of ME Interface" depends on INTEL_MEI_ME - depends on DRM_I915 + depends on DRM_I915!=n || DRM_XE!=n || COMPILE_TEST help MEI Support for GSC Proxy Services on Intel platforms. diff --git a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c index f52fe23a6c0b..a5a15a62a356 100644 --- a/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c +++ b/drivers/misc/mei/gsc_proxy/mei_gsc_proxy.c @@ -141,7 +141,7 @@ static int mei_gsc_proxy_probe(struct mei_cl_device *cldev, goto enable_err_exit; } - comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL); + comp_master = kzalloc_obj(*comp_master); if (!comp_master) { ret = -ENOMEM; goto err_exit; diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c index ccd9df5d1c7d..a864ac7121b2 100644 --- a/drivers/misc/mei/hbm.c +++ b/drivers/misc/mei/hbm.c @@ -409,7 +409,7 @@ static int mei_hbm_me_cl_add(struct mei_device *dev, mei_me_cl_rm_by_uuid(dev, uuid); - me_cl = kzalloc(sizeof(*me_cl), GFP_KERNEL); + me_cl = kzalloc_obj(*me_cl); if (!me_cl) return -ENOMEM; diff --git a/drivers/misc/mei/hdcp/Kconfig b/drivers/misc/mei/hdcp/Kconfig index 631dd9651d7c..b9d5205c5b1a 100644 --- a/drivers/misc/mei/hdcp/Kconfig +++ b/drivers/misc/mei/hdcp/Kconfig @@ -4,7 +4,7 @@ config INTEL_MEI_HDCP tristate "Intel HDCP2.2 services of ME Interface" depends on INTEL_MEI_ME - depends on DRM_I915 || DRM_XE + depends on DRM_I915!=n || DRM_XE!=n || COMPILE_TEST help MEI Support for HDCP2.2 Services on Intel platforms. diff --git a/drivers/misc/mei/hdcp/mei_hdcp.c b/drivers/misc/mei/hdcp/mei_hdcp.c index 323f10620d90..d498ef5c2dc4 100644 --- a/drivers/misc/mei/hdcp/mei_hdcp.c +++ b/drivers/misc/mei/hdcp/mei_hdcp.c @@ -819,7 +819,7 @@ static int mei_hdcp_probe(struct mei_cl_device *cldev, goto enable_err_exit; } - comp_arbiter = kzalloc(sizeof(*comp_arbiter), GFP_KERNEL); + comp_arbiter = kzalloc_obj(*comp_arbiter); if (!comp_arbiter) { ret = -ENOMEM; goto err_exit; diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index 3f210413fd32..4262965c4f99 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c @@ -133,7 +133,7 @@ static int mei_cl_irq_read_msg(struct mei_cl *cl, break; case MEI_EXT_HDR_GSC: gsc_f2h = (struct mei_ext_hdr_gsc_f2h *)ext; - cb->ext_hdr = (struct mei_ext_hdr *)kzalloc(sizeof(*gsc_f2h), GFP_KERNEL); + cb->ext_hdr = (struct mei_ext_hdr *) kzalloc_obj(*gsc_f2h); if (!cb->ext_hdr) { cb->status = -ENOMEM; goto discard; diff --git a/drivers/misc/mei/pxp/Kconfig b/drivers/misc/mei/pxp/Kconfig index aa2dece4a927..2c5c00dc4b6f 100644 --- a/drivers/misc/mei/pxp/Kconfig +++ b/drivers/misc/mei/pxp/Kconfig @@ -4,7 +4,7 @@ config INTEL_MEI_PXP tristate "Intel PXP services of ME Interface" depends on INTEL_MEI_ME - depends on DRM_I915 || DRM_XE + depends on DRM_I915!=n || DRM_XE!=n || COMPILE_TEST help MEI Support for PXP Services on Intel platforms. diff --git a/drivers/misc/mei/pxp/mei_pxp.c b/drivers/misc/mei/pxp/mei_pxp.c index 2820d389c88e..7c2629e12819 100644 --- a/drivers/misc/mei/pxp/mei_pxp.c +++ b/drivers/misc/mei/pxp/mei_pxp.c @@ -273,7 +273,7 @@ static int mei_pxp_probe(struct mei_cl_device *cldev, goto enable_err_exit; } - comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL); + comp_master = kzalloc_obj(*comp_master); if (!comp_master) { ret = -ENOMEM; goto err_exit; diff --git a/drivers/misc/mei/vsc-fw-loader.c b/drivers/misc/mei/vsc-fw-loader.c index 43abefa806e1..7b347248921d 100644 --- a/drivers/misc/mei/vsc-fw-loader.c +++ b/drivers/misc/mei/vsc-fw-loader.c @@ -721,7 +721,7 @@ int vsc_tp_init(struct vsc_tp *tp, struct device *dev) void *rx_buf __free(kfree) = NULL; int ret; - fw_loader = kzalloc(sizeof(*fw_loader), GFP_KERNEL); + fw_loader = kzalloc_obj(*fw_loader); if (!fw_loader) return -ENOMEM; diff --git a/drivers/misc/ntsync.c b/drivers/misc/ntsync.c index 9087f045e362..30af282262ef 100644 --- a/drivers/misc/ntsync.c +++ b/drivers/misc/ntsync.c @@ -705,7 +705,7 @@ static struct ntsync_obj *ntsync_alloc_obj(struct ntsync_device *dev, { struct ntsync_obj *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; obj->type = type; @@ -884,7 +884,7 @@ static int setup_wait(struct ntsync_device *dev, if (args->alert) fds[count] = args->alert; - q = kmalloc(struct_size(q, entries, total_count), GFP_KERNEL); + q = kmalloc_flex(*q, entries, total_count); if (!q) return -ENOMEM; q->task = current; @@ -1145,7 +1145,7 @@ static int ntsync_char_open(struct inode *inode, struct file *file) { struct ntsync_device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/misc/ocxl/afu_irq.c b/drivers/misc/ocxl/afu_irq.c index f6b821fc274c..ade7913a35e1 100644 --- a/drivers/misc/ocxl/afu_irq.c +++ b/drivers/misc/ocxl/afu_irq.c @@ -107,7 +107,7 @@ int ocxl_afu_irq_alloc(struct ocxl_context *ctx, int *irq_id) struct afu_irq *irq; int rc; - irq = kzalloc(sizeof(struct afu_irq), GFP_KERNEL); + irq = kzalloc_obj(struct afu_irq); if (!irq) return -ENOMEM; diff --git a/drivers/misc/ocxl/context.c b/drivers/misc/ocxl/context.c index cded7d1caf32..33f25be46247 100644 --- a/drivers/misc/ocxl/context.c +++ b/drivers/misc/ocxl/context.c @@ -10,7 +10,7 @@ int ocxl_context_alloc(struct ocxl_context **context, struct ocxl_afu *afu, int pasid; struct ocxl_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/misc/ocxl/core.c b/drivers/misc/ocxl/core.c index aebfc53a2d09..92466b7fa954 100644 --- a/drivers/misc/ocxl/core.c +++ b/drivers/misc/ocxl/core.c @@ -17,7 +17,7 @@ static struct ocxl_afu *alloc_afu(struct ocxl_fn *fn) { struct ocxl_afu *afu; - afu = kzalloc(sizeof(struct ocxl_afu), GFP_KERNEL); + afu = kzalloc_obj(struct ocxl_afu); if (!afu) return NULL; @@ -300,7 +300,7 @@ static struct ocxl_fn *alloc_function(void) { struct ocxl_fn *fn; - fn = kzalloc(sizeof(struct ocxl_fn), GFP_KERNEL); + fn = kzalloc_obj(struct ocxl_fn); if (!fn) return NULL; diff --git a/drivers/misc/ocxl/file.c b/drivers/misc/ocxl/file.c index 7eb74711ac96..1abbde33e974 100644 --- a/drivers/misc/ocxl/file.c +++ b/drivers/misc/ocxl/file.c @@ -526,7 +526,7 @@ int ocxl_file_register_afu(struct ocxl_afu *afu) struct ocxl_fn *fn = afu->fn; struct pci_dev *pci_dev = to_pci_dev(fn->dev.parent); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info == NULL) return -ENOMEM; diff --git a/drivers/misc/ocxl/link.c b/drivers/misc/ocxl/link.c index 03402203cacd..7749dcd16117 100644 --- a/drivers/misc/ocxl/link.c +++ b/drivers/misc/ocxl/link.c @@ -345,7 +345,7 @@ static int alloc_spa(struct pci_dev *dev, struct ocxl_link *link) { struct spa *spa; - spa = kzalloc(sizeof(struct spa), GFP_KERNEL); + spa = kzalloc_obj(struct spa); if (!spa) return -ENOMEM; @@ -387,7 +387,7 @@ static int alloc_link(struct pci_dev *dev, int PE_mask, struct ocxl_link **out_l struct ocxl_link *link; int rc; - link = kzalloc(sizeof(struct ocxl_link), GFP_KERNEL); + link = kzalloc_obj(struct ocxl_link); if (!link) return -ENOMEM; @@ -559,7 +559,7 @@ int ocxl_link_add_pe(void *link_handle, int pasid, u32 pidr, u32 tidr, goto unlock; } - pe_data = kmalloc(sizeof(*pe_data), GFP_KERNEL); + pe_data = kmalloc_obj(*pe_data); if (!pe_data) { rc = -ENOMEM; goto unlock; diff --git a/drivers/misc/ocxl/pasid.c b/drivers/misc/ocxl/pasid.c index d14cb56e6920..c9a50eb926da 100644 --- a/drivers/misc/ocxl/pasid.c +++ b/drivers/misc/ocxl/pasid.c @@ -28,7 +28,7 @@ static int range_alloc(struct list_head *head, u32 size, int max_id, struct id_range *cur, *new; int rc, last_end; - new = kmalloc(sizeof(struct id_range), GFP_KERNEL); + new = kmalloc_obj(struct id_range); if (!new) return -ENOMEM; diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c index 0d63e834dbe7..fd147fd2800f 100644 --- a/drivers/misc/pch_phub.c +++ b/drivers/misc/pch_phub.c @@ -666,7 +666,7 @@ static int pch_phub_probe(struct pci_dev *pdev, int ret; struct pch_phub_reg *chip; - chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); + chip = kzalloc_obj(struct pch_phub_reg); if (chip == NULL) return -ENOMEM; diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index 701db2c5859b..34a5054a6b40 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c @@ -362,7 +362,7 @@ static int phantom_probe(struct pci_dev *pdev, } retval = -ENOMEM; - pht = kzalloc(sizeof(*pht), GFP_KERNEL); + pht = kzalloc_obj(*pht); if (pht == NULL) { dev_err(&pdev->dev, "unable to allocate device\n"); goto err_reg; diff --git a/drivers/misc/rpmb-core.c b/drivers/misc/rpmb-core.c index 2d653926cdbb..ecf14acf230a 100644 --- a/drivers/misc/rpmb-core.c +++ b/drivers/misc/rpmb-core.c @@ -161,7 +161,7 @@ struct rpmb_dev *rpmb_dev_register(struct device *dev, !descr->dev_id_len) return ERR_PTR(-EINVAL); - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); rdev->descr = *descr; diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c index 3036c15f3689..8d749f345246 100644 --- a/drivers/misc/sgi-gru/grumain.c +++ b/drivers/misc/sgi-gru/grumain.c @@ -356,7 +356,7 @@ struct gru_vma_data *gru_alloc_vma_data(struct vm_area_struct *vma, int tsid) { struct gru_vma_data *vdata = NULL; - vdata = kmalloc(sizeof(*vdata), GFP_KERNEL); + vdata = kmalloc_obj(*vdata); if (!vdata) return NULL; diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c index 1107dd3e2e9f..a8121d40be68 100644 --- a/drivers/misc/sgi-gru/grutlbpurge.c +++ b/drivers/misc/sgi-gru/grutlbpurge.c @@ -237,7 +237,7 @@ static struct mmu_notifier *gru_alloc_notifier(struct mm_struct *mm) { struct gru_mm_struct *gms; - gms = kzalloc(sizeof(*gms), GFP_KERNEL); + gms = kzalloc_obj(*gms); if (!gms) return ERR_PTR(-ENOMEM); STAT(gms_alloc); diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index 9fe816bf3957..15b6a8e35681 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c @@ -400,9 +400,7 @@ xpc_setup_ch_structures(struct xpc_partition *part) * memory. */ DBUG_ON(part->channels != NULL); - part->channels = kcalloc(XPC_MAX_NCHANNELS, - sizeof(struct xpc_channel), - GFP_KERNEL); + part->channels = kzalloc_objs(struct xpc_channel, XPC_MAX_NCHANNELS); if (part->channels == NULL) { dev_err(xpc_chan, "can't get memory for channels\n"); return xpNoMemory; @@ -890,9 +888,7 @@ xpc_setup_partitions(void) short partid; struct xpc_partition *part; - xpc_partitions = kcalloc(xp_max_npartitions, - sizeof(struct xpc_partition), - GFP_KERNEL); + xpc_partitions = kzalloc_objs(struct xpc_partition, xp_max_npartitions); if (xpc_partitions == NULL) { dev_err(xpc_part, "can't get memory for partition structure\n"); return -ENOMEM; diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 2f03a7080d96..772c78726893 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c @@ -147,7 +147,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, struct xpc_gru_mq_uv *mq; struct uv_IO_APIC_route_entry *mmr_value; - mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL); + mq = kmalloc_obj(struct xpc_gru_mq_uv); if (mq == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " "a xpc_gru_mq_uv structure\n"); @@ -155,8 +155,7 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, goto out_0; } - mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc), - GFP_KERNEL); + mq->gru_mq_desc = kzalloc_obj(struct gru_message_queue_desc); if (mq->gru_mq_desc == NULL) { dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() " "a gru_message_queue_desc structure\n"); @@ -623,9 +622,8 @@ xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size, if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) { gru_mq_desc = part_uv->cached_activate_gru_mq_desc; if (gru_mq_desc == NULL) { - gru_mq_desc = kmalloc(sizeof(struct - gru_message_queue_desc), - GFP_ATOMIC); + gru_mq_desc = kmalloc_obj(struct gru_message_queue_desc, + GFP_ATOMIC); if (gru_mq_desc == NULL) { ret = xpNoMemory; goto done; @@ -1075,9 +1073,7 @@ xpc_setup_msg_structures_uv(struct xpc_channel *ch) DBUG_ON(ch->flags & XPC_C_SETUP); - ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct - gru_message_queue_desc), - GFP_KERNEL); + ch_uv->cached_notify_gru_mq_desc = kmalloc_obj(struct gru_message_queue_desc); if (ch_uv->cached_notify_gru_mq_desc == NULL) return xpNoMemory; diff --git a/drivers/misc/sgi-xp/xpnet.c b/drivers/misc/sgi-xp/xpnet.c index 2396ba3b03bd..1533b72d57b1 100644 --- a/drivers/misc/sgi-xp/xpnet.c +++ b/drivers/misc/sgi-xp/xpnet.c @@ -431,7 +431,7 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) * xpc_send_notifies are relying on this skb. When none * remain, release the skb. */ - queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC); + queued_msg = kmalloc_obj(struct xpnet_pending_msg, GFP_ATOMIC); if (queued_msg == NULL) { dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping " "packet\n", sizeof(struct xpnet_pending_msg)); diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index c98ff8aa221c..1919d24c8236 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -191,7 +191,7 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) * after the reserved blocks from the dt are processed. */ nblocks = (np) ? of_get_available_child_count(np) + 1 : 1; - rblocks = kcalloc(nblocks, sizeof(*rblocks), GFP_KERNEL); + rblocks = kzalloc_objs(*rblocks, nblocks); if (!rblocks) return -ENOMEM; diff --git a/drivers/misc/ti_fpc202.c b/drivers/misc/ti_fpc202.c index 7964e46c7448..8eb2b5ac9850 100644 --- a/drivers/misc/ti_fpc202.c +++ b/drivers/misc/ti_fpc202.c @@ -309,7 +309,6 @@ static void fpc202_remove_port(struct fpc202_priv *priv, int port_id) static int fpc202_probe(struct i2c_client *client) { struct device *dev = &client->dev; - struct device_node *i2c_handle; struct fpc202_priv *priv; int ret, port_id; @@ -357,7 +356,7 @@ static int fpc202_probe(struct i2c_client *client) bitmap_zero(priv->probed_ports, FPC202_NUM_PORTS); - for_each_child_of_node(dev->of_node, i2c_handle) { + for_each_child_of_node_scoped(dev->of_node, i2c_handle) { ret = of_property_read_u32(i2c_handle, "reg", &port_id); if (ret) { if (ret == -EINVAL) diff --git a/drivers/misc/tifm_core.c b/drivers/misc/tifm_core.c index 12355d34e193..da0827724a61 100644 --- a/drivers/misc/tifm_core.c +++ b/drivers/misc/tifm_core.c @@ -176,7 +176,7 @@ struct tifm_adapter *tifm_alloc_adapter(unsigned int num_sockets, { struct tifm_adapter *fm; - fm = kzalloc(struct_size(fm, sockets, num_sockets), GFP_KERNEL); + fm = kzalloc_flex(*fm, sockets, num_sockets); if (fm) { fm->dev.class = &tifm_adapter_class; fm->dev.parent = dev; @@ -252,7 +252,7 @@ struct tifm_dev *tifm_alloc_device(struct tifm_adapter *fm, unsigned int id, if (!tifm_media_type_name(type, 0)) return sock; - sock = kzalloc(sizeof(struct tifm_dev), GFP_KERNEL); + sock = kzalloc_obj(struct tifm_dev); if (sock) { spin_lock_init(&sock->lock); sock->type = type; diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 1a7796ab3fad..03f19eda641e 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -343,7 +343,7 @@ static int tsl2550_probe(struct i2c_client *client) goto exit; } - data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL); + data = kzalloc_obj(struct tsl2550_data); if (!data) { err = -ENOMEM; goto exit; diff --git a/drivers/misc/uacce/uacce.c b/drivers/misc/uacce/uacce.c index 6d71355528d3..45521d4a56d1 100644 --- a/drivers/misc/uacce/uacce.c +++ b/drivers/misc/uacce/uacce.c @@ -158,7 +158,7 @@ static int uacce_fops_open(struct inode *inode, struct file *filep) if (!uacce) return -ENODEV; - q = kzalloc(sizeof(struct uacce_queue), GFP_KERNEL); + q = kzalloc_obj(struct uacce_queue); if (!q) return -ENOMEM; @@ -251,7 +251,7 @@ static int uacce_fops_mmap(struct file *filep, struct vm_area_struct *vma) else return -EINVAL; - qfr = kzalloc(sizeof(*qfr), GFP_KERNEL); + qfr = kzalloc_obj(*qfr); if (!qfr) return -ENOMEM; @@ -506,7 +506,7 @@ struct uacce_device *uacce_alloc(struct device *parent, struct uacce_device *uacce; int ret; - uacce = kzalloc(sizeof(struct uacce_device), GFP_KERNEL); + uacce = kzalloc_obj(struct uacce_device); if (!uacce) return ERR_PTR(-ENOMEM); diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c index 216a16395968..3edb934dd7fd 100644 --- a/drivers/misc/vmw_balloon.c +++ b/drivers/misc/vmw_balloon.c @@ -1616,7 +1616,7 @@ static int vmballoon_enable_stats(struct vmballoon *b) if (b->stats) goto out; - b->stats = kzalloc(sizeof(*b->stats), GFP_KERNEL); + b->stats = kzalloc_obj(*b->stats); if (!b->stats) { /* allocation failed */ diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index 8069d271ed81..19ca00feed6e 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -104,7 +104,7 @@ struct vmci_ctx *vmci_ctx_create(u32 cid, u32 priv_flags, goto err_out; } - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) { pr_warn("Failed to allocate memory for VMCI context\n"); error = -ENOMEM; @@ -294,7 +294,7 @@ int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg) } /* Allocate guest call entry and add it to the target VM's queue. */ - dq_entry = kmalloc(sizeof(*dq_entry), GFP_KERNEL); + dq_entry = kmalloc_obj(*dq_entry); if (dq_entry == NULL) { pr_warn("Failed to allocate memory for datagram\n"); vmci_ctx_put(context); @@ -598,7 +598,7 @@ int vmci_ctx_add_notification(u32 context_id, u32 remote_cid) goto out; } - notifier = kmalloc(sizeof(struct vmci_handle_list), GFP_KERNEL); + notifier = kmalloc_obj(struct vmci_handle_list); if (!notifier) { result = VMCI_ERROR_NO_MEM; goto out; diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c b/drivers/misc/vmw_vmci/vmci_datagram.c index 3964d9e5a39b..6193a22c3ab5 100644 --- a/drivers/misc/vmw_vmci/vmci_datagram.c +++ b/drivers/misc/vmw_vmci/vmci_datagram.c @@ -71,7 +71,7 @@ static int dg_create_handle(u32 resource_id, handle = vmci_make_handle(context_id, resource_id); - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { pr_warn("Failed allocating memory for datagram entry\n"); return VMCI_ERROR_NO_MEM; @@ -224,8 +224,8 @@ static int dg_dispatch_as_host(u32 context_id, struct vmci_datagram *dg) return VMCI_ERROR_NO_MEM; } - dg_info = kmalloc(struct_size(dg_info, msg_payload, dg->payload_size), - GFP_ATOMIC); + dg_info = kmalloc_flex(*dg_info, msg_payload, + dg->payload_size, GFP_ATOMIC); if (!dg_info) { atomic_dec(&delayed_dg_host_queue_size); vmci_resource_put(resource); diff --git a/drivers/misc/vmw_vmci/vmci_doorbell.c b/drivers/misc/vmw_vmci/vmci_doorbell.c index 53eeb9e6cb56..30303e0f5f68 100644 --- a/drivers/misc/vmw_vmci/vmci_doorbell.c +++ b/drivers/misc/vmw_vmci/vmci_doorbell.c @@ -402,7 +402,7 @@ int vmci_doorbell_create(struct vmci_handle *handle, priv_flags & ~VMCI_PRIVILEGE_ALL_FLAGS) return VMCI_ERROR_INVALID_ARGS; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (entry == NULL) { pr_warn("Failed allocating memory for datagram entry\n"); return VMCI_ERROR_NO_MEM; diff --git a/drivers/misc/vmw_vmci/vmci_event.c b/drivers/misc/vmw_vmci/vmci_event.c index 9a41ab65378d..fffe068a26eb 100644 --- a/drivers/misc/vmw_vmci/vmci_event.c +++ b/drivers/misc/vmw_vmci/vmci_event.c @@ -151,7 +151,7 @@ int vmci_event_subscribe(u32 event, return VMCI_ERROR_INVALID_ARGS; } - sub = kzalloc(sizeof(*sub), GFP_KERNEL); + sub = kzalloc_obj(*sub); if (!sub) return VMCI_ERROR_NO_MEM; diff --git a/drivers/misc/vmw_vmci/vmci_handle_array.c b/drivers/misc/vmw_vmci/vmci_handle_array.c index 681b3500125a..fd94e4f90322 100644 --- a/drivers/misc/vmw_vmci/vmci_handle_array.c +++ b/drivers/misc/vmw_vmci/vmci_handle_array.c @@ -19,7 +19,7 @@ struct vmci_handle_arr *vmci_handle_arr_create(u32 capacity, u32 max_capacity) capacity = min((u32)VMCI_HANDLE_ARRAY_DEFAULT_CAPACITY, max_capacity); - array = kmalloc(struct_size(array, entries, capacity), GFP_ATOMIC); + array = kmalloc_flex(*array, entries, capacity, GFP_ATOMIC); if (!array) return NULL; diff --git a/drivers/misc/vmw_vmci/vmci_host.c b/drivers/misc/vmw_vmci/vmci_host.c index b64944367ac5..b71ca1bf0a20 100644 --- a/drivers/misc/vmw_vmci/vmci_host.c +++ b/drivers/misc/vmw_vmci/vmci_host.c @@ -120,7 +120,7 @@ static int vmci_host_open(struct inode *inode, struct file *filp) { struct vmci_host_dev *vmci_host_dev; - vmci_host_dev = kzalloc(sizeof(struct vmci_host_dev), GFP_KERNEL); + vmci_host_dev = kzalloc_obj(struct vmci_host_dev); if (vmci_host_dev == NULL) return -ENOMEM; diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index b88ac144ad32..872aad355dbe 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -895,7 +895,7 @@ qp_guest_endpoint_create(struct vmci_handle handle, handle = vmci_make_handle(context_id, VMCI_INVALID_ID); } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (entry) { entry->qp.peer = peer; entry->qp.flags = flags; @@ -1318,7 +1318,7 @@ static int qp_broker_create(struct vmci_handle handle, if (is_local && peer != VMCI_INVALID_ID && context_id != peer) return VMCI_ERROR_NO_ACCESS; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return VMCI_ERROR_NO_MEM; @@ -2722,7 +2722,7 @@ int vmci_qpair_alloc(struct vmci_qp **qpair, return VMCI_ERROR_INVALID_ARGS; } - my_qpair = kzalloc(sizeof(*my_qpair), GFP_KERNEL); + my_qpair = kzalloc_obj(*my_qpair); if (!my_qpair) return VMCI_ERROR_NO_MEM; diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index fb6eb2d79b4f..05ee76cb0a08 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -422,7 +422,7 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( struct mmc_blk_ioc_data *idata; int err; - idata = kzalloc(sizeof(*idata), GFP_KERNEL); + idata = kzalloc_obj(*idata); if (!idata) { err = -ENOMEM; goto out; @@ -737,7 +737,7 @@ static int mmc_blk_ioctl_multi_cmd(struct mmc_blk_data *md, return -EINVAL; n = num_of_cmds; - idata = kcalloc(n, sizeof(*idata), GFP_KERNEL); + idata = kzalloc_objs(*idata, n); if (!idata) return -ENOMEM; @@ -2562,7 +2562,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, return ERR_PTR(devidx); } - md = kzalloc(sizeof(*md), GFP_KERNEL); + md = kzalloc_obj(*md); if (!md) { ret = -ENOMEM; goto out; @@ -2794,12 +2794,12 @@ static struct mmc_blk_ioc_data **alloc_idata(struct mmc_rpmb_data *rpmb, struct mmc_blk_ioc_data **idata; unsigned int n; - idata = kcalloc(cmd_count, sizeof(*idata), GFP_KERNEL); + idata = kzalloc_objs(*idata, cmd_count); if (!idata) return NULL; for (n = 0; n < cmd_count; n++) { - idata[n] = kcalloc(1, sizeof(**idata), GFP_KERNEL); + idata[n] = kzalloc_objs(**idata, 1); if (!idata[n]) { free_idata(idata, n); return NULL; @@ -2942,7 +2942,7 @@ static int mmc_blk_alloc_rpmb_part(struct mmc_card *card, if (devidx < 0) return devidx; - rpmb = kzalloc(sizeof(*rpmb), GFP_KERNEL); + rpmb = kzalloc_obj(*rpmb); if (!rpmb) { ida_free(&mmc_rpmb_ida, devidx); return -ENOMEM; diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index ec4f3462bf80..be5cf338bdeb 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -279,7 +279,7 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host, const struct device_type { struct mmc_card *card; - card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); + card = kzalloc_obj(struct mmc_card); if (!card) return ERR_PTR(-ENOMEM); diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c index 01d1e62c2ce7..43fdb67d5407 100644 --- a/drivers/mmc/core/mmc_test.c +++ b/drivers/mmc/core/mmc_test.c @@ -348,11 +348,11 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz, if (max_segs > max_page_cnt) max_segs = max_page_cnt; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return NULL; - mem->arr = kcalloc(max_segs, sizeof(*mem->arr), GFP_KERNEL); + mem->arr = kzalloc_objs(*mem->arr, max_segs); if (!mem->arr) goto out_free; @@ -533,7 +533,7 @@ static void mmc_test_save_transfer_result(struct mmc_test_card *test, if (!test->gr) return; - tr = kmalloc(sizeof(*tr), GFP_KERNEL); + tr = kmalloc_obj(*tr); if (!tr) return; @@ -765,7 +765,7 @@ static void mmc_test_req_reset(struct mmc_test_req *rq) static struct mmc_test_req *mmc_test_req_alloc(void) { - struct mmc_test_req *rq = kmalloc(sizeof(*rq), GFP_KERNEL); + struct mmc_test_req *rq = kmalloc_obj(*rq); if (rq) mmc_test_req_reset(rq); @@ -1570,14 +1570,13 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) if (!t->mem) return -ENOMEM; - t->sg = kmalloc_array(t->max_segs, sizeof(*t->sg), GFP_KERNEL); + t->sg = kmalloc_objs(*t->sg, t->max_segs); if (!t->sg) { ret = -ENOMEM; goto out_free; } - t->sg_areq = kmalloc_array(t->max_segs, sizeof(*t->sg_areq), - GFP_KERNEL); + t->sg_areq = kmalloc_objs(*t->sg_areq, t->max_segs); if (!t->sg_areq) { ret = -ENOMEM; goto out_free; @@ -2968,7 +2967,7 @@ static void mmc_test_run(struct mmc_test_card *test, int testcase) } } - gr = kzalloc(sizeof(*gr), GFP_KERNEL); + gr = kzalloc_obj(*gr); if (gr) { INIT_LIST_HEAD(&gr->tr_lst); @@ -3100,7 +3099,7 @@ static ssize_t mtf_test_write(struct file *file, const char __user *buf, if (ret) return ret; - test = kzalloc(sizeof(*test), GFP_KERNEL); + test = kzalloc_obj(*test); if (!test) return -ENOMEM; @@ -3189,7 +3188,7 @@ static int __mmc_test_register_dbgfs_file(struct mmc_card *card, file = debugfs_create_file(name, mode, card->debugfs_root, card, fops); - df = kmalloc(sizeof(*df), GFP_KERNEL); + df = kmalloc_obj(*df); if (!df) { debugfs_remove(file); return -ENOMEM; diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index 284856c8f655..13000fc57e2e 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c @@ -167,7 +167,7 @@ static struct scatterlist *mmc_alloc_sg(unsigned short sg_len, gfp_t gfp) { struct scatterlist *sg; - sg = kmalloc_array(sg_len, sizeof(*sg), gfp); + sg = kmalloc_objs(*sg, sg_len, gfp); if (sg) sg_init_table(sg, sg_len); diff --git a/drivers/mmc/core/sdio_bus.c b/drivers/mmc/core/sdio_bus.c index 6e5bdc2f0cc8..4b07098c33c3 100644 --- a/drivers/mmc/core/sdio_bus.c +++ b/drivers/mmc/core/sdio_bus.c @@ -337,7 +337,7 @@ struct sdio_func *sdio_alloc_func(struct mmc_card *card) { struct sdio_func *func; - func = kzalloc(sizeof(struct sdio_func), GFP_KERNEL); + func = kzalloc_obj(struct sdio_func); if (!func) return ERR_PTR(-ENOMEM); diff --git a/drivers/mmc/core/sdio_uart.c b/drivers/mmc/core/sdio_uart.c index 7423a601e1e5..7fd5dedf3ac0 100644 --- a/drivers/mmc/core/sdio_uart.c +++ b/drivers/mmc/core/sdio_uart.c @@ -1021,7 +1021,7 @@ static int sdio_uart_probe(struct sdio_func *func, struct sdio_uart_port *port; int ret; - port = kzalloc(sizeof(struct sdio_uart_port), GFP_KERNEL); + port = kzalloc_obj(struct sdio_uart_port); if (!port) return -ENOMEM; diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 62c68cda1e21..ac069d0c42b2 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c @@ -36,6 +36,8 @@ struct dw_mci_rockchip_priv_data { int default_sample_phase; int num_phases; bool internal_phase; + int sample_phase; + int drv_phase; }; /* @@ -306,8 +308,7 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode) return -EIO; } - ranges = kmalloc_array(priv->num_phases / 2 + 1, - sizeof(*ranges), GFP_KERNEL); + ranges = kmalloc_objs(*ranges, priv->num_phases / 2 + 1); if (!ranges) return -ENOMEM; @@ -574,9 +575,43 @@ static void dw_mci_rockchip_remove(struct platform_device *pdev) dw_mci_pltfm_remove(pdev); } +static int dw_mci_rockchip_runtime_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct dw_mci *host = platform_get_drvdata(pdev); + struct dw_mci_rockchip_priv_data *priv = host->priv; + + if (priv->internal_phase) { + priv->sample_phase = rockchip_mmc_get_phase(host, true); + priv->drv_phase = rockchip_mmc_get_phase(host, false); + } + + return dw_mci_runtime_suspend(dev); +} + +static int dw_mci_rockchip_runtime_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct dw_mci *host = platform_get_drvdata(pdev); + struct dw_mci_rockchip_priv_data *priv = host->priv; + int ret; + + ret = dw_mci_runtime_resume(dev); + if (ret) + return ret; + + if (priv->internal_phase) { + rockchip_mmc_set_phase(host, true, priv->sample_phase); + rockchip_mmc_set_phase(host, false, priv->drv_phase); + mci_writel(host, MISC_CON, MEM_CLK_AUTOGATE_ENABLE); + } + + return ret; +} + static const struct dev_pm_ops dw_mci_rockchip_dev_pm_ops = { SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) - RUNTIME_PM_OPS(dw_mci_runtime_suspend, dw_mci_runtime_resume, NULL) + RUNTIME_PM_OPS(dw_mci_rockchip_runtime_suspend, dw_mci_rockchip_runtime_resume, NULL) }; static struct platform_driver dw_mci_rockchip_pltfm_driver = { diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 9e74b675e92d..07eb9f23b9d6 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -834,7 +834,7 @@ static int dw_mci_edmac_start_dma(struct dw_mci *host, static int dw_mci_edmac_init(struct dw_mci *host) { /* Request external dma channel */ - host->dms = kzalloc(sizeof(struct dw_mci_dma_slave), GFP_KERNEL); + host->dms = kzalloc_obj(struct dw_mci_dma_slave); if (!host->dms) return -ENOMEM; diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 42936e248c55..b471a7795b4d 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c @@ -1236,7 +1236,7 @@ static int mmc_spi_probe(struct spi_device *spi) } /* Preallocate buffers */ - host->data = kmalloc(sizeof(*host->data), GFP_KERNEL); + host->data = kmalloc_obj(*host->data); if (!host->data) goto fail_nobuf1; diff --git a/drivers/mmc/host/mmci_qcom_dml.c b/drivers/mmc/host/mmci_qcom_dml.c index 3da6112fbe39..67371389cc33 100644 --- a/drivers/mmc/host/mmci_qcom_dml.c +++ b/drivers/mmc/host/mmci_qcom_dml.c @@ -109,6 +109,7 @@ static int of_get_dml_pipe_index(struct device_node *np, const char *name) &dma_spec)) return -ENODEV; + of_node_put(dma_spec.np); if (dma_spec.args_count) return dma_spec.args[0]; diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index 05939f30a5ae..8131a1703f28 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -57,7 +57,7 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) if (dev->platform_data || !dev_fwnode(dev)) return dev->platform_data; - oms = kzalloc(sizeof(*oms), GFP_KERNEL); + oms = kzalloc_obj(*oms); if (!oms) return NULL; diff --git a/drivers/mmc/host/sdhci-brcmstb.c b/drivers/mmc/host/sdhci-brcmstb.c index c9442499876c..57e45951644e 100644 --- a/drivers/mmc/host/sdhci-brcmstb.c +++ b/drivers/mmc/host/sdhci-brcmstb.c @@ -116,7 +116,7 @@ static void sdhci_brcmstb_restore_regs(struct mmc_host *mmc, enum cfg_core_ver v writel(sr->boot_main_ctl, priv->boot_regs + SDIO_BOOT_MAIN_CTL); if (ver == SDIO_CFG_CORE_V1) { - writel(sr->sd_pin_sel, cr + SDIO_CFG_SD_PIN_SEL); + writel(sr->sd_pin_sel, cr + SDIO_CFG_V1_SD_PIN_SEL); return; } diff --git a/drivers/mmc/host/sdhci-pic32.c b/drivers/mmc/host/sdhci-pic32.c index 7ddac0befed8..2cc632e91fe4 100644 --- a/drivers/mmc/host/sdhci-pic32.c +++ b/drivers/mmc/host/sdhci-pic32.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -25,7 +26,6 @@ #include #include "sdhci.h" #include "sdhci-pltfm.h" -#include #define SDH_SHARED_BUS_CTRL 0x000000E0 #define SDH_SHARED_BUS_NR_CLK_PINS_MASK 0x7 diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index 2b7456e942f7..7e8af5a06ac9 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c @@ -462,7 +462,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ret = -ENOMEM; goto err; } - ushc->int_data = kzalloc(sizeof(struct ushc_int_data), GFP_KERNEL); + ushc->int_data = kzalloc_obj(struct ushc_int_data); if (ushc->int_data == NULL) { ret = -ENOMEM; goto err; @@ -479,7 +479,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ret = -ENOMEM; goto err; } - ushc->cbw = kzalloc(sizeof(struct ushc_cbw), GFP_KERNEL); + ushc->cbw = kzalloc_obj(struct ushc_cbw); if (ushc->cbw == NULL) { ret = -ENOMEM; goto err; @@ -501,7 +501,7 @@ static int ushc_probe(struct usb_interface *intf, const struct usb_device_id *id ret = -ENOMEM; goto err; } - ushc->csw = kzalloc(sizeof(struct ushc_csw), GFP_KERNEL); + ushc->csw = kzalloc_obj(struct ushc_csw); if (ushc->csw == NULL) { ret = -ENOMEM; goto err; diff --git a/drivers/most/configfs.c b/drivers/most/configfs.c index 36d8c917f65f..8f5158d95bc3 100644 --- a/drivers/most/configfs.c +++ b/drivers/most/configfs.c @@ -426,7 +426,7 @@ static struct config_item *most_common_make_item(struct config_group *group, struct mdev_link *mdev_link; struct most_common *mc = to_most_common(group->cg_subsys); - mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL); + mdev_link = kzalloc_obj(*mdev_link); if (!mdev_link) return ERR_PTR(-ENOMEM); @@ -526,7 +526,7 @@ static struct config_item *most_snd_grp_make_item(struct config_group *group, { struct mdev_link *mdev_link; - mdev_link = kzalloc(sizeof(*mdev_link), GFP_KERNEL); + mdev_link = kzalloc_obj(*mdev_link); if (!mdev_link) return ERR_PTR(-ENOMEM); @@ -607,7 +607,7 @@ static struct config_group *most_sound_make_group(struct config_group *group, } if (!try_module_get(ms->mod)) return ERR_PTR(-ENOLCK); - most = kzalloc(sizeof(*most), GFP_KERNEL); + most = kzalloc_obj(*most); if (!most) { module_put(ms->mod); return ERR_PTR(-ENOMEM); diff --git a/drivers/most/core.c b/drivers/most/core.c index da319d108ea1..c2616da8bceb 100644 --- a/drivers/most/core.c +++ b/drivers/most/core.c @@ -880,7 +880,7 @@ static int arm_mbo_chain(struct most_channel *c, int dir, atomic_set(&c->mbo_nq_level, 0); for (i = 0; i < c->cfg.num_buffers; i++) { - mbo = kzalloc(sizeof(*mbo), GFP_KERNEL); + mbo = kzalloc_obj(*mbo); if (!mbo) goto flush_fifos; @@ -1282,19 +1282,28 @@ int most_register_interface(struct most_interface *iface) int id; struct most_channel *c; - if (!iface || !iface->enqueue || !iface->configure || - !iface->poison_channel || (iface->num_channels > MAX_CHANNELS)) + if (!iface) return -EINVAL; + device_initialize(iface->dev); + + if (!iface->enqueue || !iface->configure || !iface->poison_channel || + (iface->num_channels > MAX_CHANNELS)) { + put_device(iface->dev); + return -EINVAL; + } + id = ida_alloc(&mdev_id, GFP_KERNEL); if (id < 0) { dev_err(iface->dev, "Failed to allocate device ID\n"); + put_device(iface->dev); return id; } - iface->p = kzalloc(sizeof(*iface->p), GFP_KERNEL); + iface->p = kzalloc_obj(*iface->p); if (!iface->p) { ida_free(&mdev_id, id); + put_device(iface->dev); return -ENOMEM; } @@ -1304,7 +1313,7 @@ int most_register_interface(struct most_interface *iface) iface->dev->bus = &mostbus; iface->dev->groups = interface_attr_groups; dev_set_drvdata(iface->dev, iface); - if (device_register(iface->dev)) { + if (device_add(iface->dev)) { dev_err(iface->dev, "Failed to register interface device\n"); kfree(iface->p); put_device(iface->dev); @@ -1315,7 +1324,7 @@ int most_register_interface(struct most_interface *iface) for (i = 0; i < iface->num_channels; i++) { const char *name_suffix = iface->channel_vector[i].name_suffix; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) goto err_free_resources; if (!name_suffix) diff --git a/drivers/most/most_cdev.c b/drivers/most/most_cdev.c index b9423f82373d..b31dc824466f 100644 --- a/drivers/most/most_cdev.c +++ b/drivers/most/most_cdev.c @@ -429,7 +429,7 @@ static int comp_probe(struct most_interface *iface, int channel_id, if (current_minor < 0) return current_minor; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) { retval = -ENOMEM; goto err_remove_ida; diff --git a/drivers/most/most_snd.c b/drivers/most/most_snd.c index 45d762804c5e..68b9e6c64033 100644 --- a/drivers/most/most_snd.c +++ b/drivers/most/most_snd.c @@ -542,7 +542,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id, adpt->pcm_dev_idx++; goto skip_adpt_alloc; } - adpt = kzalloc(sizeof(*adpt), GFP_KERNEL); + adpt = kzalloc_obj(*adpt); if (!adpt) return -ENOMEM; @@ -574,7 +574,7 @@ static int audio_probe_channel(struct most_interface *iface, int channel_id, capture_count = 1; direction = SNDRV_PCM_STREAM_CAPTURE; } - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) { ret = -ENOMEM; goto err_free_adpt; diff --git a/drivers/most/most_usb.c b/drivers/most/most_usb.c index 41ee169f80c5..d2c0875727a3 100644 --- a/drivers/most/most_usb.c +++ b/drivers/most/most_usb.c @@ -142,7 +142,7 @@ static inline int drci_rd_reg(struct usb_device *dev, u16 reg, u16 *buf) __le16 *dma_buf; u8 req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE; - dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL); + dma_buf = kzalloc_obj(*dma_buf); if (!dma_buf) return -ENOMEM; @@ -960,7 +960,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) struct usb_endpoint_descriptor *ep_desc; int ret = -ENOMEM; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; @@ -1000,11 +1000,11 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) mdev->dev.init_name = mdev->description; mdev->dev.parent = &interface->dev; mdev->dev.release = release_mdev; - mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL); + mdev->conf = kzalloc_objs(*mdev->conf, num_endpoints); if (!mdev->conf) goto err_free_mdev; - mdev->cap = kcalloc(num_endpoints, sizeof(*mdev->cap), GFP_KERNEL); + mdev->cap = kzalloc_objs(*mdev->cap, num_endpoints); if (!mdev->cap) goto err_free_conf; @@ -1015,7 +1015,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) goto err_free_cap; mdev->busy_urbs = - kcalloc(num_endpoints, sizeof(*mdev->busy_urbs), GFP_KERNEL); + kzalloc_objs(*mdev->busy_urbs, num_endpoints); if (!mdev->busy_urbs) goto err_free_ep_address; @@ -1064,7 +1064,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) { - mdev->dci = kzalloc(sizeof(*mdev->dci), GFP_KERNEL); + mdev->dci = kzalloc_obj(*mdev->dci); if (!mdev->dci) { mutex_unlock(&mdev->io_mutex); most_deregister_interface(&mdev->iface); diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index c10693ba265b..b73596a8e021 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -501,7 +501,7 @@ struct mtd_info *cfi_cmdset_0001(struct map_info *map, int primary) struct mtd_info *mtd; int i; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) return NULL; mtd->priv = map; @@ -627,9 +627,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kcalloc(mtd->numeraseregions, - sizeof(struct mtd_erase_region_info), - GFP_KERNEL); + mtd->eraseregions = kzalloc_objs(struct mtd_erase_region_info, + mtd->numeraseregions); if (!mtd->eraseregions) goto setup_err; @@ -777,13 +776,10 @@ static int cfi_intelext_partition_fixup(struct mtd_info *mtd, } numvirtchips = cfi->numchips * numparts; - newcfi = kmalloc(struct_size(newcfi, chips, numvirtchips), - GFP_KERNEL); + newcfi = kmalloc_flex(*newcfi, chips, numvirtchips); if (!newcfi) return -ENOMEM; - shared = kmalloc_array(cfi->numchips, - sizeof(struct flchip_shared), - GFP_KERNEL); + shared = kmalloc_objs(struct flchip_shared, cfi->numchips); if (!shared) { kfree(newcfi); return -ENOMEM; diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 7c91429a670b..a38aceb6612d 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -604,7 +604,7 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) struct mtd_info *mtd; int i; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) return NULL; mtd->priv = map; @@ -776,9 +776,8 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc_array(mtd->numeraseregions, - sizeof(struct mtd_erase_region_info), - GFP_KERNEL); + mtd->eraseregions = kmalloc_objs(struct mtd_erase_region_info, + mtd->numeraseregions); if (!mtd->eraseregions) goto setup_err; @@ -2819,7 +2818,7 @@ static int __maybe_unused cfi_ppb_unlock(struct mtd_info *mtd, loff_t ofs, for (i = 0; i < mtd->numeraseregions; i++) max_sectors += regions[i].numblocks; - sect = kcalloc(max_sectors, sizeof(struct ppb_lock), GFP_KERNEL); + sect = kzalloc_objs(struct ppb_lock, max_sectors); if (!sect) return -ENOMEM; diff --git a/drivers/mtd/chips/cfi_cmdset_0020.c b/drivers/mtd/chips/cfi_cmdset_0020.c index 5e5266e2c2e1..6b5727eaae69 100644 --- a/drivers/mtd/chips/cfi_cmdset_0020.c +++ b/drivers/mtd/chips/cfi_cmdset_0020.c @@ -172,7 +172,7 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) int i,j; unsigned long devsize = (1<cfiq->DevSize) * cfi->interleave; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); //printk(KERN_DEBUG "number of CFI chips: %d\n", cfi->numchips); if (!mtd) { @@ -185,9 +185,8 @@ static struct mtd_info *cfi_staa_setup(struct map_info *map) mtd->size = devsize * cfi->numchips; mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; - mtd->eraseregions = kmalloc_array(mtd->numeraseregions, - sizeof(struct mtd_erase_region_info), - GFP_KERNEL); + mtd->eraseregions = kmalloc_objs(struct mtd_erase_region_info, + mtd->numeraseregions); if (!mtd->eraseregions) { kfree(cfi->cmdset_priv); kfree(mtd); diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index e254f9cd2796..bdc04a6ec9c7 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -208,7 +208,7 @@ static int __xipram cfi_chip_setup(struct map_info *map, if (!num_erase_regions) return 0; - cfi->cfiq = kmalloc(struct_size(cfi->cfiq, EraseRegionInfo, num_erase_regions), GFP_KERNEL); + cfi->cfiq = kmalloc_flex(*cfi->cfiq, EraseRegionInfo, num_erase_regions); if (!cfi->cfiq) return 0; diff --git a/drivers/mtd/chips/gen_probe.c b/drivers/mtd/chips/gen_probe.c index 9e53fcd7600d..433194a76e2a 100644 --- a/drivers/mtd/chips/gen_probe.c +++ b/drivers/mtd/chips/gen_probe.c @@ -134,7 +134,7 @@ static struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chi * our caller, and copy the appropriate data into them. */ - retcfi = kmalloc(struct_size(retcfi, chips, cfi.numchips), GFP_KERNEL); + retcfi = kmalloc_flex(*retcfi, chips, cfi.numchips); if (!retcfi) { kfree(cfi.cfiq); diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c index 3c631608f6d6..a49ef682dc13 100644 --- a/drivers/mtd/chips/jedec_probe.c +++ b/drivers/mtd/chips/jedec_probe.c @@ -1985,7 +1985,7 @@ static int cfi_jedec_setup(struct map_info *map, struct cfi_private *cfi, int in num_erase_regions = jedec_table[index].nr_regions; - cfi->cfiq = kmalloc(struct_size(cfi->cfiq, EraseRegionInfo, num_erase_regions), GFP_KERNEL); + cfi->cfiq = kmalloc_flex(*cfi->cfiq, EraseRegionInfo, num_erase_regions); if (!cfi->cfiq) { //xx printk(KERN_WARNING "%s: kmalloc failed for CFI ident structure\n", map->name); return 0; diff --git a/drivers/mtd/chips/map_absent.c b/drivers/mtd/chips/map_absent.c index fc68557f49c0..1804a44b3eab 100644 --- a/drivers/mtd/chips/map_absent.c +++ b/drivers/mtd/chips/map_absent.c @@ -46,7 +46,7 @@ static struct mtd_info *map_absent_probe(struct map_info *map) { struct mtd_info *mtd; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) { return NULL; } diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c index f9d3e32ef8e9..2dde70e742c5 100644 --- a/drivers/mtd/chips/map_ram.c +++ b/drivers/mtd/chips/map_ram.c @@ -57,7 +57,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map) #endif /* OK. It seems to be RAM. */ - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) return NULL; diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c index 0823b15aaadb..dbc34e886b57 100644 --- a/drivers/mtd/chips/map_rom.c +++ b/drivers/mtd/chips/map_rom.c @@ -45,7 +45,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map) { struct mtd_info *mtd; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) return NULL; diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index b06c8dd51562..03e80b2c4f5a 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -271,7 +271,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size, if (!devname) return NULL; - dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL); + dev = kzalloc_obj(struct block2mtd_dev); if (!dev) return NULL; diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index c93769c233d9..33050a2a80f7 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -1810,10 +1810,10 @@ doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) struct mtd_info *mtd; ret = -ENOMEM; - docg3 = kzalloc(sizeof(struct docg3), GFP_KERNEL); + docg3 = kzalloc_obj(struct docg3); if (!docg3) goto nomem1; - mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); + mtd = kzalloc_obj(struct mtd_info); if (!mtd) goto nomem2; mtd->priv = docg3; diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 08f76ff839a7..453b3e05feb7 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -117,7 +117,7 @@ static int __init ms02nv_init_one(ulong addr) int ret = -ENODEV; /* The module decodes 8MiB of address space. */ - mod_res = kzalloc(sizeof(*mod_res), GFP_KERNEL); + mod_res = kzalloc_obj(*mod_res); if (!mod_res) return -ENOMEM; @@ -138,10 +138,10 @@ static int __init ms02nv_init_one(ulong addr) } ret = -ENOMEM; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) goto err_out_mod_res_rel; - mp = kzalloc(sizeof(*mp), GFP_KERNEL); + mp = kzalloc_obj(*mp); if (!mp) goto err_out_mtd; @@ -149,7 +149,7 @@ static int __init ms02nv_init_one(ulong addr) mp->resource.module = mod_res; /* Firmware's diagnostic NVRAM area. */ - diag_res = kzalloc(sizeof(*diag_res), GFP_KERNEL); + diag_res = kzalloc_obj(*diag_res); if (!diag_res) goto err_out_mp; @@ -162,7 +162,7 @@ static int __init ms02nv_init_one(ulong addr) mp->resource.diag_ram = diag_res; /* User-available general-purpose NVRAM area. */ - user_res = kzalloc(sizeof(*user_res), GFP_KERNEL); + user_res = kzalloc_obj(*user_res); if (!user_res) goto err_out_diag_res; @@ -175,7 +175,7 @@ static int __init ms02nv_init_one(ulong addr) mp->resource.user_ram = user_res; /* Control and status register. */ - csr_res = kzalloc(sizeof(*csr_res), GFP_KERNEL); + csr_res = kzalloc_obj(*csr_res); if (!csr_res) goto err_out_user_res; diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index ec52277e3dd5..e766258d76f7 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -627,7 +627,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, char *otp_tag = ""; int err = 0; - priv = kzalloc(sizeof *priv, GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/mtd/devices/mtd_intel_dg.c b/drivers/mtd/devices/mtd_intel_dg.c index 7f751c48a76d..f2fa8f68d190 100644 --- a/drivers/mtd/devices/mtd_intel_dg.c +++ b/drivers/mtd/devices/mtd_intel_dg.c @@ -720,7 +720,7 @@ static int intel_dg_nvm_init_mtd(struct intel_dg_nvm *nvm, struct device *device nvm->mtd.erasesize = SZ_4K; /* 4K bytes granularity */ nvm->mtd.size = nvm->size; - parts = kcalloc(nvm->nregions, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, nvm->nregions); if (!parts) return -ENOMEM; @@ -764,7 +764,7 @@ static int intel_dg_mtd_probe(struct auxiliary_device *aux_dev, return -ENODEV; } - nvm = kzalloc(struct_size(nvm, regions, nregions), GFP_KERNEL); + nvm = kzalloc_flex(*nvm, regions, nregions); if (!nvm) return -ENOMEM; diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index 1c97fabc4bf9..3fff3cdd9834 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c @@ -158,7 +158,7 @@ static int __init init_mtdram(void) return -EINVAL; /* Allocate some memory */ - mtd_info = kmalloc(sizeof(struct mtd_info), GFP_KERNEL); + mtd_info = kmalloc_obj(struct mtd_info); if (!mtd_info) return -ENOMEM; diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index fd9ec165e61a..b42cadcd76b1 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -130,7 +130,7 @@ static int register_device(struct platform_device *pdev, const char *name, struct phram_mtd_list *new; int ret = -ENOMEM; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) goto out0; diff --git a/drivers/mtd/devices/pmc551.c b/drivers/mtd/devices/pmc551.c index 6597fc2aad34..dc0ebfeb846e 100644 --- a/drivers/mtd/devices/pmc551.c +++ b/drivers/mtd/devices/pmc551.c @@ -715,11 +715,11 @@ static int __init init_pmc551(void) msize = length; } - mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); + mtd = kzalloc_obj(struct mtd_info); if (!mtd) break; - priv = kzalloc(sizeof(struct mypriv), GFP_KERNEL); + priv = kzalloc_obj(struct mypriv); if (!priv) { kfree(mtd); break; diff --git a/drivers/mtd/devices/slram.c b/drivers/mtd/devices/slram.c index 8297b366a066..69cb63d99f57 100644 --- a/drivers/mtd/devices/slram.c +++ b/drivers/mtd/devices/slram.c @@ -135,17 +135,17 @@ static int register_device(char *name, unsigned long start, unsigned long length curmtd = &(*curmtd)->next; } - *curmtd = kmalloc(sizeof(slram_mtd_list_t), GFP_KERNEL); + *curmtd = kmalloc_obj(slram_mtd_list_t); if (!(*curmtd)) { E("slram: Cannot allocate new MTD device.\n"); return(-ENOMEM); } - (*curmtd)->mtdinfo = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); + (*curmtd)->mtdinfo = kzalloc_obj(struct mtd_info); (*curmtd)->next = NULL; if ((*curmtd)->mtdinfo) { (*curmtd)->mtdinfo->priv = - kzalloc(sizeof(slram_priv_t), GFP_KERNEL); + kzalloc_obj(slram_priv_t); if (!(*curmtd)->mtdinfo->priv) { kfree((*curmtd)->mtdinfo); diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index 59a901549257..fc9185d44d92 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -201,16 +201,13 @@ static int build_maps(partition_t *part) /* Set up erase unit maps */ part->DataUnits = le16_to_cpu(part->header.NumEraseUnits) - part->header.NumTransferUnits; - part->EUNInfo = kmalloc_array(part->DataUnits, sizeof(struct eun_info_t), - GFP_KERNEL); + part->EUNInfo = kmalloc_objs(struct eun_info_t, part->DataUnits); if (!part->EUNInfo) goto out; for (i = 0; i < part->DataUnits; i++) part->EUNInfo[i].Offset = 0xffffffff; part->XferInfo = - kmalloc_array(part->header.NumTransferUnits, - sizeof(struct xfer_info_t), - GFP_KERNEL); + kmalloc_objs(struct xfer_info_t, part->header.NumTransferUnits); if (!part->XferInfo) goto out_EUNInfo; @@ -339,7 +336,7 @@ static int erase_xfer(partition_t *part, /* Is there a free erase slot? Always in MTD. */ - erase=kmalloc(sizeof(struct erase_info), GFP_KERNEL); + erase=kmalloc_obj(struct erase_info); if (!erase) return -ENOMEM; @@ -1007,7 +1004,7 @@ static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { partition_t *partition; - partition = kzalloc(sizeof(partition_t), GFP_KERNEL); + partition = kzalloc_obj(partition_t); if (!partition) { printk(KERN_WARNING "No memory to scan for FTL on %s\n", diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c index 58c6e1743f5c..1fb924a47227 100644 --- a/drivers/mtd/inftlcore.c +++ b/drivers/mtd/inftlcore.c @@ -52,7 +52,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) pr_debug("INFTL: add_mtd for %s\n", mtd->name); - inftl = kzalloc(sizeof(*inftl), GFP_KERNEL); + inftl = kzalloc_obj(*inftl); if (!inftl) return; diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index cd37d58abacb..a4167ee5e415 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c @@ -41,7 +41,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) int numchips; int i, j; - mtd = kzalloc(sizeof(*mtd), GFP_KERNEL); + mtd = kzalloc_obj(*mtd); if (!mtd) return NULL; mtd->priv = map; @@ -65,8 +65,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) mtd->erasesize = 1 << lpddr->qinfo->UniformBlockSizeShift; mtd->writesize = 1 << lpddr->qinfo->BufSizeShift; - shared = kmalloc_array(lpddr->numchips, sizeof(struct flchip_shared), - GFP_KERNEL); + shared = kmalloc_objs(struct flchip_shared, lpddr->numchips); if (!shared) { kfree(mtd); return NULL; diff --git a/drivers/mtd/lpddr/qinfo_probe.c b/drivers/mtd/lpddr/qinfo_probe.c index 42281e460c62..f041913a7112 100644 --- a/drivers/mtd/lpddr/qinfo_probe.c +++ b/drivers/mtd/lpddr/qinfo_probe.c @@ -120,7 +120,7 @@ static int lpddr_pfow_present(struct map_info *map, struct lpddr_private *lpddr) static int lpddr_chip_setup(struct map_info *map, struct lpddr_private *lpddr) { - lpddr->qinfo = kzalloc(sizeof(struct qinfo_chip), GFP_KERNEL); + lpddr->qinfo = kzalloc_obj(struct qinfo_chip); if (!lpddr->qinfo) return 0; @@ -167,8 +167,7 @@ static struct lpddr_private *lpddr_probe_chip(struct map_info *map) lpddr.numchips = 1; numvirtchips = lpddr.numchips * lpddr.qinfo->HWPartsNum; - retlpddr = kzalloc(struct_size(retlpddr, chips, numvirtchips), - GFP_KERNEL); + retlpddr = kzalloc_flex(*retlpddr, chips, numvirtchips); if (!retlpddr) return NULL; diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 281fcbaa74e7..95f9b99ce5fc 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -188,7 +188,7 @@ static int amd76xrom_init_one(struct pci_dev *pdev, int i; if (!map) { - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) goto out; } diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index c0216bc740cc..5e44134caa8e 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -218,7 +218,7 @@ static int __init ck804xrom_init_one(struct pci_dev *pdev, int i; if (!map) { - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) goto out; } diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index 15d5b76ff504..fc7f2c3a62b0 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c @@ -278,7 +278,7 @@ static int __init esb2rom_init_one(struct pci_dev *pdev, int i; if (!map) { - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) goto out; } diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index c8b2793691db..6608b782149b 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c @@ -212,7 +212,7 @@ static int __init ichxrom_init_one(struct pci_dev *pdev, int i; if (!map) { - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) goto out; } diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index ca00d211e73e..4a84ca8aed40 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -264,7 +264,7 @@ static int mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) if (err) goto out; - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); err = -ENOMEM; if (!map) goto release; diff --git a/drivers/mtd/maps/pcmciamtd.c b/drivers/mtd/maps/pcmciamtd.c index 206a3c463e6e..a2e5a63e5d18 100644 --- a/drivers/mtd/maps/pcmciamtd.c +++ b/drivers/mtd/maps/pcmciamtd.c @@ -674,7 +674,7 @@ static int pcmciamtd_probe(struct pcmcia_device *link) struct pcmciamtd_dev *dev; /* Create new memory card device */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; pr_debug("dev=0x%p\n", dev); diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index ecf68922da73..b0310fddcaa3 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c @@ -218,7 +218,7 @@ static int pismo_probe(struct i2c_client *client) return -EIO; } - pismo = kzalloc(sizeof(*pismo), GFP_KERNEL); + pismo = kzalloc_obj(*pismo); if (!pismo) return -ENOMEM; diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c index 1c541eaf477a..816111031cf1 100644 --- a/drivers/mtd/maps/plat-ram.c +++ b/drivers/mtd/maps/plat-ram.c @@ -109,7 +109,7 @@ static int platram_probe(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info == NULL) { err = -ENOMEM; goto exit_error; diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index f27c25db6778..bc303a9909d4 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c @@ -51,7 +51,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) if (!res) return -ENODEV; - info = kzalloc(sizeof(struct pxa2xx_flash_info), GFP_KERNEL); + info = kzalloc_obj(struct pxa2xx_flash_info); if (!info) return -ENOMEM; diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index 6a54a84d0d9c..4506b27a905e 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c @@ -170,7 +170,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, /* * Allocate the map_info structs in one go. */ - info = kzalloc(struct_size(info, subdev, nr), GFP_KERNEL); + info = kzalloc_flex(*info, subdev, nr); if (!info) { ret = -ENOMEM; goto out; @@ -222,7 +222,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, } else if (info->num_subdev > 1) { struct mtd_info **cdev; - cdev = kmalloc_array(nr, sizeof(*cdev), GFP_KERNEL); + cdev = kmalloc_objs(*cdev, nr); if (!cdev) { ret = -ENOMEM; goto err; diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index ea3aa026b55b..cac780cd23f9 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c @@ -61,7 +61,7 @@ static int uflash_devinit(struct platform_device *op, struct device_node *dp) return -ENODEV; } - up = kzalloc(sizeof(struct uflash_dev), GFP_KERNEL); + up = kzalloc_obj(struct uflash_dev); if (!up) return -ENOMEM; diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 53019d313db7..75e06d249ce9 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c @@ -73,7 +73,7 @@ static struct vmu_block *ofs_to_block(unsigned long src_ofs, if (num > card->parts[partition].numblocks) goto failed; - vblock = kmalloc(sizeof(struct vmu_block), GFP_KERNEL); + vblock = kmalloc_obj(struct vmu_block); if (!vblock) goto failed; @@ -539,7 +539,7 @@ static void vmu_queryblocks(struct mapleq *mq) mtd_cur->_sync = vmu_flash_sync; mtd_cur->writesize = card->blocklen; - mpart = kmalloc(sizeof(struct mdev_part), GFP_KERNEL); + mpart = kmalloc_obj(struct mdev_part); if (!mpart) goto fail_mpart; @@ -548,7 +548,7 @@ static void vmu_queryblocks(struct mapleq *mq) mtd_cur->priv = mpart; mtd_cur->owner = THIS_MODULE; - pcache = kzalloc(sizeof(struct vmu_cache), GFP_KERNEL); + pcache = kzalloc_obj(struct vmu_cache); if (!pcache) goto fail_cache_create; part_cur->pcache = pcache; @@ -609,7 +609,7 @@ static int vmu_connect(struct maple_device *mdev) basic_flash_data = be32_to_cpu(mdev->devinfo.function_data[c - 1]); - card = kmalloc(sizeof(struct memcard), GFP_KERNEL); + card = kmalloc_obj(struct memcard); if (!card) { error = -ENOMEM; goto fail_nomem; @@ -627,15 +627,13 @@ static int vmu_connect(struct maple_device *mdev) * Not sure there are actually any multi-partition devices in the * real world, but the hardware supports them, so, so will we */ - card->parts = kmalloc_array(card->partitions, sizeof(struct vmupart), - GFP_KERNEL); + card->parts = kmalloc_objs(struct vmupart, card->partitions); if (!card->parts) { error = -ENOMEM; goto fail_partitions; } - card->mtd = kmalloc_array(card->partitions, sizeof(struct mtd_info), - GFP_KERNEL); + card->mtd = kmalloc_objs(struct mtd_info, card->partitions); if (!card->mtd) { error = -ENOMEM; goto fail_mtd_info; diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 28e09d080440..4d2e7b7774e9 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -324,7 +324,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) new->readonly = 1; ret = -ENOMEM; - new->tag_set = kzalloc(sizeof(*new->tag_set), GFP_KERNEL); + new->tag_set = kzalloc_obj(*new->tag_set); if (!new->tag_set) goto out_list_del; diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index 9751416c2a91..c9143711fa39 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -316,7 +316,7 @@ static int mtdblock_flush(struct mtd_blktrans_dev *dev) static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { - struct mtdblk_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct mtdblk_dev *dev = kzalloc_obj(*dev); if (!dev) return; diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index ef6299af60e4..e564521d6911 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro.c @@ -36,7 +36,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) { - struct mtd_blktrans_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct mtd_blktrans_dev *dev = kzalloc_obj(*dev); if (!dev) return; diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 335c702633ff..55a43682c567 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -72,7 +72,7 @@ static int mtdchar_open(struct inode *inode, struct file *file) goto out1; } - mfi = kzalloc(sizeof(*mfi), GFP_KERNEL); + mfi = kzalloc_obj(*mfi); if (!mfi) { ret = -ENOMEM; goto out1; @@ -923,7 +923,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg) { struct erase_info *erase; - erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL); + erase=kzalloc_obj(struct erase_info); if (!erase) ret = -ENOMEM; else { @@ -1162,7 +1162,7 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg) if (!master->ooblayout) return -EOPNOTSUPP; - usrlay = kmalloc(sizeof(*usrlay), GFP_KERNEL); + usrlay = kmalloc_obj(*usrlay); if (!usrlay) return -ENOMEM; diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c index f56f44aa8625..9eb5d919d9ba 100644 --- a/drivers/mtd/mtdconcat.c +++ b/drivers/mtd/mtdconcat.c @@ -416,7 +416,7 @@ static int concat_erase(struct mtd_info *mtd, struct erase_info *instr) } /* make a local copy of instr to avoid modifying the caller's struct */ - erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL); + erase = kmalloc_obj(struct erase_info); if (!erase) return -ENOMEM; @@ -823,9 +823,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c concat->mtd.erasesize = max_erasesize; concat->mtd.numeraseregions = num_erase_region; concat->mtd.eraseregions = erase_region_p = - kmalloc_array(num_erase_region, - sizeof(struct mtd_erase_region_info), - GFP_KERNEL); + kmalloc_objs(struct mtd_erase_region_info, num_erase_region); if (!erase_region_p) { kfree(concat); printk diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 2876501a7814..e016cfbc7224 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -53,7 +53,7 @@ static struct mtd_info *allocate_partition(struct mtd_info *parent, u64 tmp; /* allocate the partition structure */ - child = kzalloc(sizeof(*child), GFP_KERNEL); + child = kzalloc_obj(*child); name = kstrdup(part->name, GFP_KERNEL); if (!name || !child) { printk(KERN_ERR"memory allocation error while creating partitions for \"%s\"\n", diff --git a/drivers/mtd/mtdswap.c b/drivers/mtd/mtdswap.c index d8f2e5be2d31..866933fc8426 100644 --- a/drivers/mtd/mtdswap.c +++ b/drivers/mtd/mtdswap.c @@ -1413,11 +1413,11 @@ static void mtdswap_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) "%u spare, %u bad blocks\n", MTDSWAP_PREFIX, part, swap_size / 1024, spare_cnt, bad_blocks); - d = kzalloc(sizeof(struct mtdswap_dev), GFP_KERNEL); + d = kzalloc_obj(struct mtdswap_dev); if (!d) return; - mbd_dev = kzalloc(sizeof(struct mtd_blktrans_dev), GFP_KERNEL); + mbd_dev = kzalloc_obj(struct mtd_blktrans_dev); if (!mbd_dev) { kfree(d); return; diff --git a/drivers/mtd/nand/ecc-sw-bch.c b/drivers/mtd/nand/ecc-sw-bch.c index 0d9310dd6f52..26d5f3f10964 100644 --- a/drivers/mtd/nand/ecc-sw-bch.c +++ b/drivers/mtd/nand/ecc-sw-bch.c @@ -227,7 +227,7 @@ int nand_ecc_sw_bch_init_ctx(struct nand_device *nand) return -EINVAL; } - engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL); + engine_conf = kzalloc_obj(*engine_conf); if (!engine_conf) return -ENOMEM; diff --git a/drivers/mtd/nand/ecc-sw-hamming.c b/drivers/mtd/nand/ecc-sw-hamming.c index bc62a71f9fdd..460acc1029c3 100644 --- a/drivers/mtd/nand/ecc-sw-hamming.c +++ b/drivers/mtd/nand/ecc-sw-hamming.c @@ -496,7 +496,7 @@ int nand_ecc_sw_hamming_init_ctx(struct nand_device *nand) if (conf->step_size != 256 && conf->step_size != 512) conf->step_size = 256; - engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL); + engine_conf = kzalloc_obj(*engine_conf); if (!engine_conf) return -ENOMEM; diff --git a/drivers/mtd/nand/onenand/generic.c b/drivers/mtd/nand/onenand/generic.c index 4e6fd1c34484..3191904ced14 100644 --- a/drivers/mtd/nand/onenand/generic.c +++ b/drivers/mtd/nand/onenand/generic.c @@ -37,7 +37,7 @@ static int generic_onenand_probe(struct platform_device *pdev) unsigned long size = resource_size(res); int err; - info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL); + info = kzalloc_obj(struct onenand_info); if (!info) return -ENOMEM; diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c index 0dc2ea4fc857..d08aeac86f9f 100644 --- a/drivers/mtd/nand/onenand/onenand_base.c +++ b/drivers/mtd/nand/onenand/onenand_base.c @@ -3728,9 +3728,8 @@ static int onenand_probe(struct mtd_info *mtd) /* Maximum possible erase regions */ mtd->numeraseregions = this->dies << 1; mtd->eraseregions = - kcalloc(this->dies << 1, - sizeof(struct mtd_erase_region_info), - GFP_KERNEL); + kzalloc_objs(struct mtd_erase_region_info, + this->dies << 1); if (!mtd->eraseregions) return -ENOMEM; } diff --git a/drivers/mtd/nand/onenand/onenand_bbt.c b/drivers/mtd/nand/onenand/onenand_bbt.c index d7fe35bc45cb..012163fb6add 100644 --- a/drivers/mtd/nand/onenand/onenand_bbt.c +++ b/drivers/mtd/nand/onenand/onenand_bbt.c @@ -231,7 +231,7 @@ int onenand_default_bbt(struct mtd_info *mtd) struct onenand_chip *this = mtd->priv; struct bbm_info *bbm; - this->bbm = kzalloc(sizeof(struct bbm_info), GFP_KERNEL); + this->bbm = kzalloc_obj(struct bbm_info); if (!this->bbm) return -ENOMEM; diff --git a/drivers/mtd/nand/qpic_common.c b/drivers/mtd/nand/qpic_common.c index db6c46a6fe01..4f3e4dd766da 100644 --- a/drivers/mtd/nand/qpic_common.c +++ b/drivers/mtd/nand/qpic_common.c @@ -156,7 +156,7 @@ int qcom_prepare_bam_async_desc(struct qcom_nand_controller *nandc, enum dma_transfer_direction dir_eng; struct dma_async_tx_descriptor *dma_desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return -ENOMEM; @@ -364,7 +364,7 @@ int qcom_prep_adm_dma_desc(struct qcom_nand_controller *nandc, bool read, struct scatterlist *sgl; int ret; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c index 04d64724c400..f1e99197ab84 100644 --- a/drivers/mtd/nand/raw/au1550nd.c +++ b/drivers/mtd/nand/raw/au1550nd.c @@ -266,7 +266,7 @@ static int au1550nd_probe(struct platform_device *pdev) return -ENODEV; } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c index 66385c4fb994..65a36d5de742 100644 --- a/drivers/mtd/nand/raw/cafe_nand.c +++ b/drivers/mtd/nand/raw/cafe_nand.c @@ -678,7 +678,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, pci_set_master(pdev); - cafe = kzalloc(sizeof(*cafe), GFP_KERNEL); + cafe = kzalloc_obj(*cafe); if (!cafe) { err = -ENOMEM; goto out_disable_device; diff --git a/drivers/mtd/nand/raw/cs553x_nand.c b/drivers/mtd/nand/raw/cs553x_nand.c index ec95d787001b..0b872b1e3b04 100644 --- a/drivers/mtd/nand/raw/cs553x_nand.c +++ b/drivers/mtd/nand/raw/cs553x_nand.c @@ -273,7 +273,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) } /* Allocate memory for MTD device structure and private data */ - controller = kzalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc_obj(*controller); if (!controller) { err = -ENOMEM; goto out; diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index 03dbe37df021..c655d27bc4cc 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c @@ -895,13 +895,13 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) return -ENODEV; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; mutex_lock(&fsl_elbc_nand_mutex); if (!fsl_lbc_ctrl_dev->nand) { - elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL); + elbc_fcm_ctrl = kzalloc_obj(*elbc_fcm_ctrl); if (!elbc_fcm_ctrl) { mutex_unlock(&fsl_elbc_nand_mutex); ret = -ENOMEM; diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c index 7be95d0be248..dd88b22a91bd 100644 --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c @@ -1018,7 +1018,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) mutex_lock(&fsl_ifc_nand_mutex); if (!fsl_ifc_ctrl_dev->nand) { - ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL); + ifc_nand_ctrl = kzalloc_obj(*ifc_nand_ctrl); if (!ifc_nand_ctrl) { mutex_unlock(&fsl_ifc_nand_mutex); return -ENOMEM; diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index f2322de93ab4..38429363251c 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -1062,7 +1062,7 @@ static int nand_choose_interface_config(struct nand_chip *chip) if (!nand_controller_can_setup_interface(chip)) return 0; - iface = kzalloc(sizeof(*iface), GFP_KERNEL); + iface = kzalloc_obj(*iface); if (!iface) return -ENOMEM; @@ -5429,8 +5429,8 @@ static int of_get_nand_secure_regions(struct nand_chip *chip) return nr_elem; chip->nr_secure_regions = nr_elem / 2; - chip->secure_regions = kcalloc(chip->nr_secure_regions, sizeof(*chip->secure_regions), - GFP_KERNEL); + chip->secure_regions = kzalloc_objs(*chip->secure_regions, + chip->nr_secure_regions); if (!chip->secure_regions) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 3050ab7e6eb6..b0e7592a2ab7 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -1375,7 +1375,7 @@ static int nand_create_badblock_pattern(struct nand_chip *this) pr_warn("Bad block pattern already allocated; not replacing\n"); return -EINVAL; } - bd = kzalloc(sizeof(*bd), GFP_KERNEL); + bd = kzalloc_obj(*bd); if (!bd) return -ENOMEM; bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index b663659b2f49..0510ceff591d 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -705,7 +705,7 @@ static int hynix_nand_init(struct nand_chip *chip) else chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; - hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); + hynix = kzalloc_obj(*hynix); if (!hynix) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c index 89e6dd8ed1a8..b523bf65746b 100644 --- a/drivers/mtd/nand/raw/nand_jedec.c +++ b/drivers/mtd/nand/raw/nand_jedec.c @@ -42,7 +42,7 @@ int nand_jedec_detect(struct nand_chip *chip) return 0; /* JEDEC chip: allocate a buffer to hold its parameter page */ - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index c0192881906b..8807b8aade41 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -484,7 +484,7 @@ static int micron_nand_init(struct nand_chip *chip) int ondie; int ret; - micron = kzalloc(sizeof(*micron), GFP_KERNEL); + micron = kzalloc_obj(*micron); if (!micron) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c index 11954440e4de..cd3ad373883e 100644 --- a/drivers/mtd/nand/raw/nand_onfi.c +++ b/drivers/mtd/nand/raw/nand_onfi.c @@ -306,7 +306,7 @@ int nand_onfi_detect(struct nand_chip *chip) if (le16_to_cpu(p->opt_cmd) & ONFI_OPT_CMD_READ_CACHE) chip->parameters.supports_read_cache = true; - onfi = kzalloc(sizeof(*onfi), GFP_KERNEL); + onfi = kzalloc_obj(*onfi); if (!onfi) { ret = -ENOMEM; goto free_model; diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 84942e7e528f..fe968037f75a 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -851,7 +851,7 @@ static int ns_parse_weakblocks(void) } if (*w == ',') w += 1; - wb = kzalloc(sizeof(*wb), GFP_KERNEL); + wb = kzalloc_obj(*wb); if (!wb) { NS_ERR("unable to allocate memory.\n"); return -ENOMEM; @@ -902,7 +902,7 @@ static int ns_parse_weakpages(void) } if (*w == ',') w += 1; - wp = kzalloc(sizeof(*wp), GFP_KERNEL); + wp = kzalloc_obj(*wp); if (!wp) { NS_ERR("unable to allocate memory.\n"); return -ENOMEM; @@ -953,7 +953,7 @@ static int ns_parse_gravepages(void) } if (*g == ',') g += 1; - gp = kzalloc(sizeof(*gp), GFP_KERNEL); + gp = kzalloc_obj(*gp); if (!gp) { NS_ERR("unable to allocate memory.\n"); return -ENOMEM; @@ -2268,7 +2268,7 @@ static int __init ns_init_module(void) return -EINVAL; } - ns = kzalloc(sizeof(struct nandsim), GFP_KERNEL); + ns = kzalloc_obj(struct nandsim); if (!ns) { NS_ERR("unable to allocate core structures.\n"); return -ENOMEM; diff --git a/drivers/mtd/nand/raw/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c index 0b1f7670660e..09409b703d93 100644 --- a/drivers/mtd/nand/raw/pasemi_nand.c +++ b/drivers/mtd/nand/raw/pasemi_nand.c @@ -113,7 +113,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev) dev_dbg(dev, "pasemi_nand at %pR\n", &res); /* Allocate memory for MTD device structure and private data */ - ddata = kzalloc(sizeof(*ddata), GFP_KERNEL); + ddata = kzalloc_obj(*ddata); if (!ddata) { err = -ENOMEM; goto out; diff --git a/drivers/mtd/nand/raw/r852.c b/drivers/mtd/nand/raw/r852.c index 918974d088cf..8a5572b30893 100644 --- a/drivers/mtd/nand/raw/r852.c +++ b/drivers/mtd/nand/raw/r852.c @@ -867,7 +867,7 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) error = -ENOMEM; /* init nand chip, but register it only on card insert */ - chip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); + chip = kzalloc_obj(struct nand_chip); if (!chip) goto error4; @@ -883,7 +883,7 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) chip->legacy.write_buf = r852_write_buf; /* init our device structure */ - dev = kzalloc(sizeof(struct r852_device), GFP_KERNEL); + dev = kzalloc_obj(struct r852_device); if (!dev) goto error5; diff --git a/drivers/mtd/nand/raw/sharpsl.c b/drivers/mtd/nand/raw/sharpsl.c index 142e93b200a3..4154ab74f169 100644 --- a/drivers/mtd/nand/raw/sharpsl.c +++ b/drivers/mtd/nand/raw/sharpsl.c @@ -132,7 +132,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) } /* Allocate memory for MTD device structure and private data */ - sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL); + sharpsl = kzalloc_obj(struct sharpsl_nand); if (!sharpsl) return -ENOMEM; diff --git a/drivers/mtd/nand/raw/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c index 907fb5de4269..4cc6e91dbc23 100644 --- a/drivers/mtd/nand/raw/txx9ndfmc.c +++ b/drivers/mtd/nand/raw/txx9ndfmc.c @@ -319,8 +319,7 @@ static int txx9ndfmc_probe(struct platform_device *dev) if (!(plat->ch_mask & (1 << i))) continue; - txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv), - GFP_KERNEL); + txx9_priv = kzalloc_obj(struct txx9ndfmc_priv); if (!txx9_priv) continue; chip = &txx9_priv->chip; diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 29fb2ac19569..8aa3753aaaa1 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -350,7 +350,7 @@ static int spinand_ondie_ecc_init_ctx(struct nand_device *nand) nand->ecc.ctx.conf.step_size = nand->ecc.requirements.step_size; nand->ecc.ctx.conf.strength = nand->ecc.requirements.strength; - engine_conf = kzalloc(sizeof(*engine_conf), GFP_KERNEL); + engine_conf = kzalloc_obj(*engine_conf); if (!engine_conf) return -ENOMEM; diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index e4380208edd0..a6d6d6e0cc37 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -642,7 +642,7 @@ static int gd5fxgm9_spinand_init(struct spinand_device *spinand) { struct gigadevice_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c index 84be5e0402b5..67cafa1bb8ef 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c @@ -499,7 +499,7 @@ static int macronix_spinand_init(struct spinand_device *spinand) { struct macronix_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index 868aa3d35d09..6b29b9c7a6a6 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c @@ -45,7 +45,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) pr_debug("NFTL: add_mtd for %s\n", mtd->name); - nftl = kzalloc(sizeof(struct NFTLrecord), GFP_KERNEL); + nftl = kzalloc_obj(struct NFTLrecord); if (!nftl) return; diff --git a/drivers/mtd/parsers/bcm47xxpart.c b/drivers/mtd/parsers/bcm47xxpart.c index 49c8e7f27f21..a412c0e7bd4e 100644 --- a/drivers/mtd/parsers/bcm47xxpart.c +++ b/drivers/mtd/parsers/bcm47xxpart.c @@ -106,8 +106,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, blocksize = 0x1000; /* Alloc */ - parts = kcalloc(BCM47XXPART_MAX_PARTS, sizeof(struct mtd_partition), - GFP_KERNEL); + parts = kzalloc_objs(struct mtd_partition, BCM47XXPART_MAX_PARTS); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/brcm_u-boot.c b/drivers/mtd/parsers/brcm_u-boot.c index 984f98923446..cd78e432f1de 100644 --- a/drivers/mtd/parsers/brcm_u-boot.c +++ b/drivers/mtd/parsers/brcm_u-boot.c @@ -37,7 +37,7 @@ static int brcm_u_boot_parse(struct mtd_info *mtd, int err; int i = 0; - parts = kcalloc(BRCM_U_BOOT_MAX_PARTS, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, BRCM_U_BOOT_MAX_PARTS); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/ofpart_core.c b/drivers/mtd/parsers/ofpart_core.c index 599adb69eba6..0029bda165bd 100644 --- a/drivers/mtd/parsers/ofpart_core.c +++ b/drivers/mtd/parsers/ofpart_core.c @@ -102,7 +102,7 @@ static int parse_fixed_partitions(struct mtd_info *master, return 0; } - parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, nr_parts); if (!parts) { if (dedicated) of_node_put(ofpart_node); @@ -249,7 +249,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, nr_parts = plen / sizeof(part[0]); - parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, nr_parts); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/parser_trx.c b/drivers/mtd/parsers/parser_trx.c index 4814cf218e17..cf3bc9735238 100644 --- a/drivers/mtd/parsers/parser_trx.c +++ b/drivers/mtd/parsers/parser_trx.c @@ -65,8 +65,7 @@ static int parser_trx_parse(struct mtd_info *mtd, if (err != 0 && err != -EINVAL) pr_err("failed to parse \"brcm,trx-magic\" DT attribute, using default: %d\n", err); - parts = kcalloc(TRX_PARSER_MAX_PARTS, sizeof(struct mtd_partition), - GFP_KERNEL); + parts = kzalloc_objs(struct mtd_partition, TRX_PARSER_MAX_PARTS); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/qcomsmempart.c b/drivers/mtd/parsers/qcomsmempart.c index 4311b89d8df0..d4fdc46a0073 100644 --- a/drivers/mtd/parsers/qcomsmempart.c +++ b/drivers/mtd/parsers/qcomsmempart.c @@ -123,7 +123,7 @@ static int parse_qcomsmem_part(struct mtd_info *mtd, numparts++; } - parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, numparts); if (!parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/redboot.c b/drivers/mtd/parsers/redboot.c index 3b55b676ca6b..558905160ddb 100644 --- a/drivers/mtd/parsers/redboot.c +++ b/drivers/mtd/parsers/redboot.c @@ -203,7 +203,7 @@ static int parse_redboot_partitions(struct mtd_info *master, if (!redboot_checksum(&buf[i])) break; - new_fl = kmalloc(sizeof(struct fis_list), GFP_KERNEL); + new_fl = kmalloc_obj(struct fis_list); namelen += strlen(buf[i].name) + 1; if (!new_fl) { ret = -ENOMEM; diff --git a/drivers/mtd/parsers/scpart.c b/drivers/mtd/parsers/scpart.c index 6e5e11c37078..ad6e9d5c3daa 100644 --- a/drivers/mtd/parsers/scpart.c +++ b/drivers/mtd/parsers/scpart.c @@ -80,7 +80,7 @@ static int scpart_scan_partmap(struct mtd_info *master, loff_t partmap_offs, if (cnt > 0) { int bytes = cnt * sizeof(*pdesc); - pdesc = kcalloc(cnt, sizeof(*pdesc), GFP_KERNEL); + pdesc = kzalloc_objs(*pdesc, cnt); if (!pdesc) { res = -ENOMEM; goto free; @@ -171,8 +171,7 @@ static int scpart_parse(struct mtd_info *master, goto free; } - parts = kcalloc(of_get_child_count(ofpart_node), sizeof(*parts), - GFP_KERNEL); + parts = kzalloc_objs(*parts, of_get_child_count(ofpart_node)); if (!parts) { res = -ENOMEM; goto free; diff --git a/drivers/mtd/parsers/sharpslpart.c b/drivers/mtd/parsers/sharpslpart.c index 671a61845bd5..3833b887c667 100644 --- a/drivers/mtd/parsers/sharpslpart.c +++ b/drivers/mtd/parsers/sharpslpart.c @@ -362,9 +362,8 @@ static int sharpsl_parse_mtd_partitions(struct mtd_info *master, return err; } - sharpsl_nand_parts = kcalloc(SHARPSL_NAND_PARTS, - sizeof(*sharpsl_nand_parts), - GFP_KERNEL); + sharpsl_nand_parts = kzalloc_objs(*sharpsl_nand_parts, + SHARPSL_NAND_PARTS); if (!sharpsl_nand_parts) return -ENOMEM; diff --git a/drivers/mtd/parsers/tplink_safeloader.c b/drivers/mtd/parsers/tplink_safeloader.c index 4fcaf92d22e4..b770f41ef874 100644 --- a/drivers/mtd/parsers/tplink_safeloader.c +++ b/drivers/mtd/parsers/tplink_safeloader.c @@ -82,7 +82,7 @@ static int mtd_parser_tplink_safeloader_parse(struct mtd_info *mtd, int idx; int err; - parts = kcalloc(TPLINK_SAFELOADER_MAX_PARTS, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, TPLINK_SAFELOADER_MAX_PARTS); if (!parts) { err = -ENOMEM; goto err_out; diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index be26cc67a1c4..9f7efdab6e90 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -185,8 +185,7 @@ static int scan_header(struct partition *part) if (!part->header_cache) goto err; - part->blocks = kcalloc(part->total_blocks, sizeof(struct block), - GFP_KERNEL); + part->blocks = kzalloc_objs(struct block, part->total_blocks); if (!part->blocks) goto err; @@ -270,7 +269,7 @@ static int erase_block(struct partition *part, int block) struct erase_info *erase; int rc; - erase = kmalloc(sizeof(struct erase_info), GFP_KERNEL); + erase = kmalloc_obj(struct erase_info); if (!erase) return -ENOMEM; @@ -752,7 +751,7 @@ static void rfd_ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) mtd->size > UINT_MAX) return; - part = kzalloc(sizeof(struct partition), GFP_KERNEL); + part = kzalloc_obj(struct partition); if (!part) return; diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 5988cba30eb3..c8032755f9a4 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -64,7 +64,7 @@ static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) /* Initialize sysfs attributes */ vendor_attribute = - kzalloc(sizeof(struct sm_sysfs_attribute), GFP_KERNEL); + kzalloc_obj(struct sm_sysfs_attribute); if (!vendor_attribute) goto error2; @@ -78,14 +78,13 @@ static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl) /* Create array of pointers to the attributes */ - attributes = kcalloc(NUM_ATTRIBUTES + 1, sizeof(struct attribute *), - GFP_KERNEL); + attributes = kzalloc_objs(struct attribute *, NUM_ATTRIBUTES + 1); if (!attributes) goto error3; attributes[0] = &vendor_attribute->dev_attr.attr; /* Finally create the attribute group */ - attr_group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL); + attr_group = kzalloc_obj(struct attribute_group); if (!attr_group) goto error4; attr_group->attrs = attributes; @@ -1134,7 +1133,7 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) struct sm_ftl *ftl; /* Allocate & initialize our private structure */ - ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL); + ftl = kzalloc_obj(struct sm_ftl); if (!ftl) goto error1; @@ -1156,8 +1155,7 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) goto error2; /* Allocate zone array, it will be initialized on demand */ - ftl->zones = kcalloc(ftl->zone_count, sizeof(struct ftl_zone), - GFP_KERNEL); + ftl->zones = kzalloc_objs(struct ftl_zone, ftl->zone_count); if (!ftl->zones) goto error3; @@ -1171,7 +1169,7 @@ static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) /* Allocate upper layer structure and initialize it */ - trans = kzalloc(sizeof(struct mtd_blktrans_dev), GFP_KERNEL); + trans = kzalloc_obj(struct mtd_blktrans_dev); if (!trans) goto error5; diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index d3f8a78efd3b..8ffeb41c3e08 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1553,7 +1553,7 @@ spi_nor_init_erase_cmd(const struct spi_nor_erase_region *region, { struct spi_nor_erase_command *cmd; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kmalloc_obj(*cmd); if (!cmd) return ERR_PTR(-ENOMEM); diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index a8324c2da0ac..4600983cb579 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -760,7 +760,7 @@ static const u32 *spi_nor_get_map_in_use(struct spi_nor *nor, const u32 *smpt, u8 read_data_mask, map_id; /* Use a kmalloc'ed bounce buffer to guarantee it is DMA-able. */ - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) return ERR_PTR(-ENOMEM); diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c index 46c01fa2ec46..4a5225699a54 100644 --- a/drivers/mtd/ssfdc.c +++ b/drivers/mtd/ssfdc.c @@ -295,7 +295,7 @@ static void ssfdcr_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) if (cis_sector == -1) return; - ssfdc = kzalloc(sizeof(*ssfdc), GFP_KERNEL); + ssfdc = kzalloc_obj(*ssfdc); if (!ssfdc) return; diff --git a/drivers/mtd/tests/stresstest.c b/drivers/mtd/tests/stresstest.c index 8062098930d6..944f960a4bbf 100644 --- a/drivers/mtd/tests/stresstest.c +++ b/drivers/mtd/tests/stresstest.c @@ -178,7 +178,7 @@ static int __init mtd_stresstest_init(void) err = -ENOMEM; readbuf = vmalloc(bufsize); writebuf = vmalloc(bufsize); - offsets = kmalloc_array(ebcnt, sizeof(int), GFP_KERNEL); + offsets = kmalloc_objs(int, ebcnt); if (!readbuf || !writebuf || !offsets) goto out; for (i = 0; i < ebcnt; i++) diff --git a/drivers/mtd/ubi/attach.c b/drivers/mtd/ubi/attach.c index 884171871d0e..0fa115cbf3ad 100644 --- a/drivers/mtd/ubi/attach.c +++ b/drivers/mtd/ubi/attach.c @@ -131,7 +131,7 @@ static struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai, return NULL; /* The volume is absent - add it */ - av = kzalloc(sizeof(*av), GFP_KERNEL); + av = kzalloc_obj(*av); if (!av) return ERR_PTR(-ENOMEM); @@ -1451,7 +1451,7 @@ static struct ubi_attach_info *alloc_ai(const char *slab_name) { struct ubi_attach_info *ai; - ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); + ai = kzalloc_obj(struct ubi_attach_info); if (!ai) return ai; diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index b53fd147fa65..8880a783c3bc 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c @@ -368,7 +368,7 @@ int ubiblock_create(struct ubi_volume_info *vi) goto out_unlock; } - dev = kzalloc(sizeof(struct ubiblock), GFP_KERNEL); + dev = kzalloc_obj(struct ubiblock); if (!dev) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index ef6a22f372f9..674ad87809df 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -930,7 +930,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, } } - ubi = kzalloc(sizeof(struct ubi_device), GFP_KERNEL); + ubi = kzalloc_obj(struct ubi_device); if (!ubi) return -ENOMEM; diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index b700a0efaa93..fd39030dbf89 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c @@ -727,7 +727,7 @@ static int rename_volumes(struct ubi_device *ubi, int name_len = req->ents[i].name_len; const char *name = req->ents[i].name; - re = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); + re = kzalloc_obj(struct ubi_rename_entry); if (!re) { err = -ENOMEM; goto out_free; @@ -801,7 +801,7 @@ static int rename_volumes(struct ubi_device *ubi, goto out_free; } - re1 = kzalloc(sizeof(struct ubi_rename_entry), GFP_KERNEL); + re1 = kzalloc_obj(struct ubi_rename_entry); if (!re1) { err = -ENOMEM; ubi_close_volume(desc); @@ -1007,7 +1007,7 @@ static long ubi_cdev_ioctl(struct file *file, unsigned int cmd, struct ubi_rnvol_req *req; dbg_gen("re-name volumes"); - req = kmalloc(sizeof(struct ubi_rnvol_req), GFP_KERNEL); + req = kmalloc_obj(struct ubi_rnvol_req); if (!req) { err = -ENOMEM; break; diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c index c7ba7a15c9f7..f0c549e62c55 100644 --- a/drivers/mtd/ubi/eba.c +++ b/drivers/mtd/ubi/eba.c @@ -124,12 +124,11 @@ struct ubi_eba_table *ubi_eba_create_table(struct ubi_volume *vol, int err = -ENOMEM; int i; - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (!tbl) return ERR_PTR(-ENOMEM); - tbl->entries = kmalloc_array(nentries, sizeof(*tbl->entries), - GFP_KERNEL); + tbl->entries = kmalloc_objs(*tbl->entries, nentries); if (!tbl->entries) goto err; @@ -248,7 +247,7 @@ static struct ubi_ltree_entry *ltree_add_entry(struct ubi_device *ubi, { struct ubi_ltree_entry *le, *le1, *le_free; - le = kmalloc(sizeof(struct ubi_ltree_entry), GFP_NOFS); + le = kmalloc_obj(struct ubi_ltree_entry, GFP_NOFS); if (!le) return ERR_PTR(-ENOMEM); @@ -1536,11 +1535,11 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, num_volumes = ubi->vtbl_slots + UBI_INT_VOL_COUNT; - scan_eba = kmalloc_array(num_volumes, sizeof(*scan_eba), GFP_KERNEL); + scan_eba = kmalloc_objs(*scan_eba, num_volumes); if (!scan_eba) return -ENOMEM; - fm_eba = kmalloc_array(num_volumes, sizeof(*fm_eba), GFP_KERNEL); + fm_eba = kmalloc_objs(*fm_eba, num_volumes); if (!fm_eba) { kfree(scan_eba); return -ENOMEM; @@ -1551,17 +1550,13 @@ int self_check_eba(struct ubi_device *ubi, struct ubi_attach_info *ai_fastmap, if (!vol) continue; - scan_eba[i] = kmalloc_array(vol->reserved_pebs, - sizeof(**scan_eba), - GFP_KERNEL); + scan_eba[i] = kmalloc_objs(**scan_eba, vol->reserved_pebs); if (!scan_eba[i]) { ret = -ENOMEM; goto out_free; } - fm_eba[i] = kmalloc_array(vol->reserved_pebs, - sizeof(**fm_eba), - GFP_KERNEL); + fm_eba[i] = kmalloc_objs(**fm_eba, vol->reserved_pebs); if (!fm_eba[i]) { ret = -ENOMEM; kfree(scan_eba[i]); diff --git a/drivers/mtd/ubi/fastmap-wl.c b/drivers/mtd/ubi/fastmap-wl.c index e2bc1122bfd3..a0f750411f9d 100644 --- a/drivers/mtd/ubi/fastmap-wl.c +++ b/drivers/mtd/ubi/fastmap-wl.c @@ -466,7 +466,7 @@ int ubi_ensure_anchor_pebs(struct ubi_device *ubi) ubi->wl_scheduled = 1; spin_unlock(&ubi->wl_lock); - wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + wrk = kmalloc_obj(struct ubi_work, GFP_NOFS); if (!wrk) { spin_lock(&ubi->wl_lock); ubi->wl_scheduled = 0; diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c index 9a4940874be5..3bce1b4d8464 100644 --- a/drivers/mtd/ubi/fastmap.c +++ b/drivers/mtd/ubi/fastmap.c @@ -889,13 +889,13 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai, down_write(&ubi->fm_protect); memset(ubi->fm_buf, 0, ubi->fm_size); - fmsb = kmalloc(sizeof(*fmsb), GFP_KERNEL); + fmsb = kmalloc_obj(*fmsb); if (!fmsb) { ret = -ENOMEM; goto out; } - fm = kzalloc(sizeof(*fm), GFP_KERNEL); + fm = kzalloc_obj(*fm); if (!fm) { ret = -ENOMEM; kfree(fmsb); @@ -1416,7 +1416,7 @@ static int invalidate_fastmap(struct ubi_device *ubi) ubi->fm = NULL; ret = -ENOMEM; - fm = kzalloc(sizeof(*fm), GFP_NOFS); + fm = kzalloc_obj(*fm, GFP_NOFS); if (!fm) goto out; @@ -1501,7 +1501,7 @@ int ubi_update_fastmap(struct ubi_device *ubi) return 0; } - new_fm = kzalloc(sizeof(*new_fm), GFP_NOFS); + new_fm = kzalloc_obj(*new_fm, GFP_NOFS); if (!new_fm) { up_write(&ubi->fm_eba_sem); up_write(&ubi->work_sem); diff --git a/drivers/mtd/ubi/gluebi.c b/drivers/mtd/ubi/gluebi.c index 1b980d15d9fb..e3891ae82dfa 100644 --- a/drivers/mtd/ubi/gluebi.c +++ b/drivers/mtd/ubi/gluebi.c @@ -281,7 +281,7 @@ static int gluebi_create(struct ubi_device_info *di, struct gluebi_device *gluebi, *g; struct mtd_info *mtd; - gluebi = kzalloc(sizeof(struct gluebi_device), GFP_KERNEL); + gluebi = kzalloc_obj(struct gluebi_device); if (!gluebi) return -ENOMEM; diff --git a/drivers/mtd/ubi/kapi.c b/drivers/mtd/ubi/kapi.c index df0a5a57b072..9626990f67cb 100644 --- a/drivers/mtd/ubi/kapi.c +++ b/drivers/mtd/ubi/kapi.c @@ -140,7 +140,7 @@ struct ubi_volume_desc *ubi_open_volume(int ubi_num, int vol_id, int mode) goto out_put_ubi; } - desc = kmalloc(sizeof(struct ubi_volume_desc), GFP_KERNEL); + desc = kmalloc_obj(struct ubi_volume_desc); if (!desc) { err = -ENOMEM; goto out_put_ubi; diff --git a/drivers/mtd/ubi/nvmem.c b/drivers/mtd/ubi/nvmem.c index 34f8c1d3cdee..2dade9727cf2 100644 --- a/drivers/mtd/ubi/nvmem.c +++ b/drivers/mtd/ubi/nvmem.c @@ -75,7 +75,7 @@ static int ubi_nvmem_add(struct ubi_volume_info *vi) WARN_ON_ONCE(vi->size <= 0)) return -EINVAL; - unv = kzalloc(sizeof(struct ubi_nvmem), GFP_KERNEL); + unv = kzalloc_obj(struct ubi_nvmem); if (!unv) return -ENOMEM; diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 44803d3329f4..af466cd83ae0 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h @@ -1100,7 +1100,7 @@ ubi_alloc_vid_buf(const struct ubi_device *ubi, gfp_t gfp_flags) struct ubi_vid_io_buf *vidb; void *buf; - vidb = kzalloc(sizeof(*vidb), gfp_flags); + vidb = kzalloc_obj(*vidb, gfp_flags); if (!vidb) return NULL; diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index e5cf3bdca3b0..50192b95b6e4 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -172,7 +172,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (ubi->ro_mode) return -EROFS; - vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + vol = kzalloc_obj(struct ubi_volume); if (!vol) return -ENOMEM; diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 6e5489e233dd..06d87a3013a5 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -531,7 +531,7 @@ static int init_volumes(struct ubi_device *ubi, if (be32_to_cpu(vtbl[i].reserved_pebs) == 0) continue; /* Empty record */ - vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + vol = kzalloc_obj(struct ubi_volume); if (!vol) return -ENOMEM; @@ -623,7 +623,7 @@ static int init_volumes(struct ubi_device *ubi, } /* And add the layout volume */ - vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); + vol = kzalloc_obj(struct ubi_volume); if (!vol) return -ENOMEM; diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index fbd399cf6503..e3705db8e570 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c @@ -602,7 +602,7 @@ static int schedule_erase(struct ubi_device *ubi, struct ubi_wl_entry *e, dbg_wl("schedule erasure of PEB %d, EC %d, torture %d", e->pnum, e->ec, torture); - wl_wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + wl_wrk = kmalloc_obj(struct ubi_work, GFP_NOFS); if (!wl_wrk) return -ENOMEM; @@ -1071,7 +1071,7 @@ static int ensure_wear_leveling(struct ubi_device *ubi, int nested) ubi->wl_scheduled = 1; spin_unlock(&ubi->wl_lock); - wrk = kmalloc(sizeof(struct ubi_work), GFP_NOFS); + wrk = kmalloc_obj(struct ubi_work, GFP_NOFS); if (!wrk) { err = -ENOMEM; goto out_cancel; diff --git a/drivers/mux/core.c b/drivers/mux/core.c index a3840fe0995f..f09ee8782e3d 100644 --- a/drivers/mux/core.c +++ b/drivers/mux/core.c @@ -681,7 +681,7 @@ static struct mux_state *mux_state_get(struct device *dev, const char *mux_name) { struct mux_state *mstate; - mstate = kzalloc(sizeof(*mstate), GFP_KERNEL); + mstate = kzalloc_obj(*mstate); if (!mstate) return ERR_PTR(-ENOMEM); diff --git a/drivers/mux/mmio.c b/drivers/mux/mmio.c index 3409af1ffb80..0611ef28bb69 100644 --- a/drivers/mux/mmio.c +++ b/drivers/mux/mmio.c @@ -72,7 +72,7 @@ static int mux_mmio_probe(struct platform_device *pdev) if (IS_ERR(base)) regmap = ERR_PTR(-ENODEV); else - regmap = regmap_init_mmio(dev, base, &mux_mmio_regmap_cfg); + regmap = devm_regmap_init_mmio(dev, base, &mux_mmio_regmap_cfg); /* Fallback to checking the parent node on "real" errors. */ if (IS_ERR(regmap) && regmap != ERR_PTR(-EPROBE_DEFER)) { regmap = dev_get_regmap(dev->parent, NULL); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 7e9becad91df..17108c359216 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -333,6 +333,7 @@ config MACSEC config NETCONSOLE tristate "Network console logging support" + depends on PRINTK help If you want to log kernel messages over the network, enable this. See for details. diff --git a/drivers/net/amt.c b/drivers/net/amt.c index 902c817a0dea..f2f3139e38a5 100644 --- a/drivers/net/amt.c +++ b/drivers/net/amt.c @@ -368,7 +368,7 @@ static struct amt_source_node *amt_alloc_snode(struct amt_group_node *gnode, { struct amt_source_node *snode; - snode = kzalloc(sizeof(*snode), GFP_ATOMIC); + snode = kzalloc_obj(*snode, GFP_ATOMIC); if (!snode) return NULL; diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c index 19e411b2e3a7..dbadda08dce2 100644 --- a/drivers/net/arcnet/com20020-pci.c +++ b/drivers/net/arcnet/com20020-pci.c @@ -115,6 +115,8 @@ static const struct attribute_group com20020_state_group = { .attrs = com20020_state_attrs, }; +static struct com20020_pci_card_info card_info_2p5mbit; + static void com20020pci_remove(struct pci_dev *pdev); static int com20020pci_probe(struct pci_dev *pdev, @@ -140,7 +142,7 @@ static int com20020pci_probe(struct pci_dev *pdev, ci = (struct com20020_pci_card_info *)id->driver_data; if (!ci) - return -EINVAL; + ci = &card_info_2p5mbit; priv->ci = ci; mm = &ci->misc_map; @@ -347,6 +349,18 @@ static struct com20020_pci_card_info card_info_5mbit = { .flags = ARC_IS_5MBIT, }; +static struct com20020_pci_card_info card_info_2p5mbit = { + .name = "ARC-PCI", + .devcount = 1, + .chan_map_tbl = { + { + .bar = 2, + .offset = 0x00, + .size = 0x08, + }, + }, +}; + static struct com20020_pci_card_info card_info_sohard = { .name = "SOHARD SH ARC-PCI", .devcount = 1, diff --git a/drivers/net/arcnet/com20020_cs.c b/drivers/net/arcnet/com20020_cs.c index 75f08aa7528b..5c3c91677b62 100644 --- a/drivers/net/arcnet/com20020_cs.c +++ b/drivers/net/arcnet/com20020_cs.c @@ -119,7 +119,7 @@ static int com20020_probe(struct pcmcia_device *p_dev) dev_dbg(&p_dev->dev, "com20020_attach()\n"); /* Create new network device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) goto fail_alloc_info; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 78cff904cdc3..707419270ebf 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -324,7 +324,7 @@ static bool bond_sk_check(struct bonding *bond) } } -bool bond_xdp_check(struct bonding *bond, int mode) +bool __bond_xdp_check(int mode, int xmit_policy) { switch (mode) { case BOND_MODE_ROUNDROBIN: @@ -335,7 +335,7 @@ bool bond_xdp_check(struct bonding *bond, int mode) /* vlan+srcmac is not supported with XDP as in most cases the 802.1q * payload is not in the packet due to hardware offload. */ - if (bond->params.xmit_policy != BOND_XMIT_POLICY_VLAN_SRCMAC) + if (xmit_policy != BOND_XMIT_POLICY_VLAN_SRCMAC) return true; fallthrough; default: @@ -343,6 +343,11 @@ bool bond_xdp_check(struct bonding *bond, int mode) } } +bool bond_xdp_check(struct bonding *bond, int mode) +{ + return __bond_xdp_check(mode, bond->params.xmit_policy); +} + /*---------------------------------- VLAN -----------------------------------*/ /* In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid, @@ -491,7 +496,7 @@ static int bond_ipsec_add_sa(struct net_device *bond_dev, goto out; } - ipsec = kmalloc(sizeof(*ipsec), GFP_KERNEL); + ipsec = kmalloc_obj(*ipsec); if (!ipsec) { err = -ENOMEM; goto out; @@ -1387,7 +1392,7 @@ static inline int slave_enable_netpoll(struct slave *slave) struct netpoll *np; int err = 0; - np = kzalloc(sizeof(*np), GFP_KERNEL); + np = kzalloc_obj(*np); err = -ENOMEM; if (!np) goto out; @@ -1504,6 +1509,50 @@ static netdev_features_t bond_fix_features(struct net_device *dev, return features; } +static int bond_header_create(struct sk_buff *skb, struct net_device *bond_dev, + unsigned short type, const void *daddr, + const void *saddr, unsigned int len) +{ + struct bonding *bond = netdev_priv(bond_dev); + const struct header_ops *slave_ops; + struct slave *slave; + int ret = 0; + + rcu_read_lock(); + slave = rcu_dereference(bond->curr_active_slave); + if (slave) { + slave_ops = READ_ONCE(slave->dev->header_ops); + if (slave_ops && slave_ops->create) + ret = slave_ops->create(skb, slave->dev, + type, daddr, saddr, len); + } + rcu_read_unlock(); + return ret; +} + +static int bond_header_parse(const struct sk_buff *skb, unsigned char *haddr) +{ + struct bonding *bond = netdev_priv(skb->dev); + const struct header_ops *slave_ops; + struct slave *slave; + int ret = 0; + + rcu_read_lock(); + slave = rcu_dereference(bond->curr_active_slave); + if (slave) { + slave_ops = READ_ONCE(slave->dev->header_ops); + if (slave_ops && slave_ops->parse) + ret = slave_ops->parse(skb, haddr); + } + rcu_read_unlock(); + return ret; +} + +static const struct header_ops bond_header_ops = { + .create = bond_header_create, + .parse = bond_header_parse, +}; + static void bond_setup_by_slave(struct net_device *bond_dev, struct net_device *slave_dev) { @@ -1511,7 +1560,8 @@ static void bond_setup_by_slave(struct net_device *bond_dev, dev_close(bond_dev); - bond_dev->header_ops = slave_dev->header_ops; + bond_dev->header_ops = slave_dev->header_ops ? + &bond_header_ops : NULL; bond_dev->type = slave_dev->type; bond_dev->hard_header_len = slave_dev->hard_header_len; @@ -1711,7 +1761,7 @@ static struct slave *bond_alloc_slave(struct bonding *bond, { struct slave *slave = NULL; - slave = kzalloc(sizeof(*slave), GFP_KERNEL); + slave = kzalloc_obj(*slave); if (!slave) return NULL; @@ -1723,8 +1773,7 @@ static struct slave *bond_alloc_slave(struct bonding *bond, return NULL; if (BOND_MODE(bond) == BOND_MODE_8023AD) { - SLAVE_AD_INFO(slave) = kzalloc(sizeof(struct ad_slave_info), - GFP_KERNEL); + SLAVE_AD_INFO(slave) = kzalloc_obj(struct ad_slave_info); if (!SLAVE_AD_INFO(slave)) { kobject_put(&slave->kobj); return NULL; @@ -2797,8 +2846,14 @@ static void bond_miimon_commit(struct bonding *bond) continue; + case BOND_LINK_FAIL: + case BOND_LINK_BACK: + slave_dbg(bond->dev, slave->dev, "link_new_state %d on slave\n", + slave->link_new_state); + continue; + default: - slave_err(bond->dev, slave->dev, "invalid new link %d on slave\n", + slave_err(bond->dev, slave->dev, "invalid link_new_state %d on slave\n", slave->link_new_state); bond_propose_link_state(slave, BOND_LINK_NOCHANGE); @@ -2982,7 +3037,7 @@ struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, struct list_head *iter; if (start_dev == end_dev) { - tags = kcalloc(level + 1, sizeof(*tags), GFP_ATOMIC); + tags = kzalloc_objs(*tags, level + 1, GFP_ATOMIC); if (!tags) return ERR_PTR(-ENOMEM); tags[level].vlan_proto = BOND_VLAN_PROTO_NONE; @@ -3373,7 +3428,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond, } else if (is_arp) { return bond_arp_rcv(skb, bond, slave); #if IS_ENABLED(CONFIG_IPV6) - } else if (is_ipv6) { + } else if (is_ipv6 && likely(ipv6_mod_enabled())) { return bond_na_rcv(skb, bond, slave); #endif } else { @@ -4343,9 +4398,13 @@ static int bond_close(struct net_device *bond_dev) bond_work_cancel_all(bond); bond->send_peer_notif = 0; + WRITE_ONCE(bond->recv_probe, NULL); + + /* Wait for any in-flight RX handlers */ + synchronize_net(); + if (bond_is_lb(bond)) bond_alb_deinitialize(bond); - bond->recv_probe = NULL; if (BOND_MODE(bond) == BOND_MODE_8023AD && bond->params.broadcast_neighbor) @@ -5061,13 +5120,18 @@ static void bond_set_slave_arr(struct bonding *bond, { struct bond_up_slave *usable, *all; - usable = rtnl_dereference(bond->usable_slaves); - rcu_assign_pointer(bond->usable_slaves, usable_slaves); - kfree_rcu(usable, rcu); - all = rtnl_dereference(bond->all_slaves); rcu_assign_pointer(bond->all_slaves, all_slaves); kfree_rcu(all, rcu); + + if (BOND_MODE(bond) == BOND_MODE_BROADCAST) { + kfree_rcu(usable_slaves, rcu); + return; + } + + usable = rtnl_dereference(bond->usable_slaves); + rcu_assign_pointer(bond->usable_slaves, usable_slaves); + kfree_rcu(usable, rcu); } static void bond_reset_slave_arr(struct bonding *bond) @@ -5093,10 +5157,8 @@ int bond_update_slave_arr(struct bonding *bond, struct slave *skipslave) might_sleep(); - usable_slaves = kzalloc(struct_size(usable_slaves, arr, - bond->slave_cnt), GFP_KERNEL); - all_slaves = kzalloc(struct_size(all_slaves, arr, - bond->slave_cnt), GFP_KERNEL); + usable_slaves = kzalloc_flex(*usable_slaves, arr, bond->slave_cnt); + all_slaves = kzalloc_flex(*all_slaves, arr, bond->slave_cnt); if (!usable_slaves || !all_slaves) { ret = -ENOMEM; goto out; diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index dcee384c2f06..7380cc4ee75a 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -1575,6 +1575,8 @@ static int bond_option_fail_over_mac_set(struct bonding *bond, static int bond_option_xmit_hash_policy_set(struct bonding *bond, const struct bond_opt_value *newval) { + if (bond->xdp_prog && !__bond_xdp_check(BOND_MODE(bond), newval->value)) + return -EOPNOTSUPP; netdev_dbg(bond->dev, "Setting xmit hash policy to %s (%llu)\n", newval->string, newval->value); bond->params.xmit_policy = newval->value; diff --git a/drivers/net/caif/caif_serial.c b/drivers/net/caif/caif_serial.c index b90890030751..1873d8287bb9 100644 --- a/drivers/net/caif/caif_serial.c +++ b/drivers/net/caif/caif_serial.c @@ -297,6 +297,7 @@ static void ser_release(struct work_struct *work) dev_close(ser->dev); unregister_netdevice(ser->dev); debugfs_deinit(ser); + tty_kref_put(tty->link); tty_kref_put(tty); } rtnl_unlock(); @@ -331,6 +332,7 @@ static int ldisc_open(struct tty_struct *tty) ser = netdev_priv(dev); ser->tty = tty_kref_get(tty); + tty_kref_get(tty->link); ser->dev = dev; debugfs_init(ser, tty); tty->receive_room = 4096; @@ -339,6 +341,7 @@ static int ldisc_open(struct tty_struct *tty) rtnl_lock(); result = register_netdevice(dev); if (result) { + tty_kref_put(tty->link); tty_kref_put(tty); rtnl_unlock(); free_netdev(dev); diff --git a/drivers/net/caif/caif_virtio.c b/drivers/net/caif/caif_virtio.c index c60386bf2d1a..8ac1a4b8e055 100644 --- a/drivers/net/caif/caif_virtio.c +++ b/drivers/net/caif/caif_virtio.c @@ -493,7 +493,7 @@ static struct buf_info *cfv_alloc_and_copy_to_shm(struct cfv_info *cfv, goto err; } - buf_info = kmalloc(sizeof(struct buf_info), GFP_ATOMIC); + buf_info = kmalloc_obj(struct buf_info, GFP_ATOMIC); if (unlikely(!buf_info)) goto err; diff --git a/drivers/net/can/ctucanfd/ctucanfd_pci.c b/drivers/net/can/ctucanfd/ctucanfd_pci.c index 9da09e7dd63a..7b847b667973 100644 --- a/drivers/net/can/ctucanfd/ctucanfd_pci.c +++ b/drivers/net/can/ctucanfd/ctucanfd_pci.c @@ -153,7 +153,7 @@ static int ctucan_pci_probe(struct pci_dev *pdev, ntxbufs = 4; - bdata = kzalloc(sizeof(*bdata), GFP_KERNEL); + bdata = kzalloc_obj(*bdata); if (!bdata) { ret = -ENOMEM; goto err_pci_iounmap_bar0; diff --git a/drivers/net/can/dev/calc_bittiming.c b/drivers/net/can/dev/calc_bittiming.c index cc4022241553..42498e9d3f38 100644 --- a/drivers/net/can/dev/calc_bittiming.c +++ b/drivers/net/can/dev/calc_bittiming.c @@ -8,7 +8,7 @@ #include #include -#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */ +#define CAN_CALC_MAX_ERROR 500 /* max error 5% */ /* CiA recommended sample points for Non Return to Zero encoding. */ static int can_calc_sample_point_nrz(const struct can_bittiming *bt) diff --git a/drivers/net/can/dummy_can.c b/drivers/net/can/dummy_can.c index 41953655e3d3..cd23de488edc 100644 --- a/drivers/net/can/dummy_can.c +++ b/drivers/net/can/dummy_can.c @@ -241,6 +241,7 @@ static int __init dummy_can_init(void) dev->netdev_ops = &dummy_can_netdev_ops; dev->ethtool_ops = &dummy_can_ethtool_ops; + dev->flags |= IFF_ECHO; /* enable echo handling */ priv = netdev_priv(dev); priv->can.bittiming_const = &dummy_can_bittiming_const; priv->can.bitrate_max = 20 * MEGA /* BPS */; diff --git a/drivers/net/can/grcan.c b/drivers/net/can/grcan.c index 3b1b09943436..ce12fa6df56d 100644 --- a/drivers/net/can/grcan.c +++ b/drivers/net/can/grcan.c @@ -1054,8 +1054,7 @@ static int grcan_open(struct net_device *dev) return err; } - priv->echo_skb = kcalloc(dma->tx.size, sizeof(*priv->echo_skb), - GFP_KERNEL); + priv->echo_skb = kzalloc_objs(*priv->echo_skb, dma->tx.size); if (!priv->echo_skb) { err = -ENOMEM; goto exit_free_dma_buffers; diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c index 5bca719d61f5..986fc8786fac 100644 --- a/drivers/net/can/sja1000/ems_pci.c +++ b/drivers/net/can/sja1000/ems_pci.c @@ -260,7 +260,7 @@ static int ems_pci_add_card(struct pci_dev *pdev, } /* Allocating card structures to hold addresses, ... */ - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) { pci_disable_device(pdev); return -ENOMEM; diff --git a/drivers/net/can/sja1000/ems_pcmcia.c b/drivers/net/can/sja1000/ems_pcmcia.c index 4642b6d4aaf7..3cae1cd1a104 100644 --- a/drivers/net/can/sja1000/ems_pcmcia.c +++ b/drivers/net/can/sja1000/ems_pcmcia.c @@ -165,7 +165,7 @@ static int ems_pcmcia_add_card(struct pcmcia_device *pdev, unsigned long base) int err, i; /* Allocating card structures to hold addresses, ... */ - card = kzalloc(sizeof(struct ems_pcmcia_card), GFP_KERNEL); + card = kzalloc_obj(struct ems_pcmcia_card); if (!card) return -ENOMEM; diff --git a/drivers/net/can/sja1000/peak_pci.c b/drivers/net/can/sja1000/peak_pci.c index 10d88cbda465..4cc4a1581dd1 100644 --- a/drivers/net/can/sja1000/peak_pci.c +++ b/drivers/net/can/sja1000/peak_pci.c @@ -452,7 +452,7 @@ static int peak_pciec_probe(struct pci_dev *pdev, struct net_device *dev) /* channel is the first one: do the init part */ } else { /* create the bit banging I2C adapter structure */ - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) return -ENOMEM; diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c index e1610b527d13..42a77d435b39 100644 --- a/drivers/net/can/sja1000/peak_pcmcia.c +++ b/drivers/net/can/sja1000/peak_pcmcia.c @@ -650,7 +650,7 @@ static int pcan_probe(struct pcmcia_device *pdev) goto probe_err_1; } - card = kzalloc(sizeof(struct pcan_pccard), GFP_KERNEL); + card = kzalloc_obj(struct pcan_pccard); if (!card) { err = -ENOMEM; goto probe_err_2; diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index 67e5316c6372..08183833c9bc 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -629,7 +629,7 @@ static int plx_pci_add_card(struct pci_dev *pdev, ci->name, PCI_SLOT(pdev->devfn)); /* Allocate card structures to hold addresses, ... */ - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) { pci_disable_device(pdev); return -ENOMEM; diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c index e5c939b63fa6..3cea14cf055a 100644 --- a/drivers/net/can/softing/softing_cs.c +++ b/drivers/net/can/softing/softing_cs.c @@ -256,7 +256,7 @@ static int softingcs_probe(struct pcmcia_device *pcmcia) } /* create softing platform device */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { ret = -ENOMEM; goto mem_failed; diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c index 79bc64395ac4..519ab3097f86 100644 --- a/drivers/net/can/softing/softing_main.c +++ b/drivers/net/can/softing/softing_main.c @@ -767,7 +767,7 @@ static int softing_pdev_probe(struct platform_device *pdev) return -EINVAL; } - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) return -ENOMEM; card->pdat = pdat; diff --git a/drivers/net/can/spi/hi311x.c b/drivers/net/can/spi/hi311x.c index e00d3dbc4cf4..91b1fa970f8f 100644 --- a/drivers/net/can/spi/hi311x.c +++ b/drivers/net/can/spi/hi311x.c @@ -755,7 +755,9 @@ static int hi3110_open(struct net_device *net) return ret; mutex_lock(&priv->hi3110_lock); - hi3110_power_enable(priv->transceiver, 1); + ret = hi3110_power_enable(priv->transceiver, 1); + if (ret) + goto out_close_candev; priv->force_quit = 0; priv->tx_skb = NULL; @@ -790,6 +792,7 @@ static int hi3110_open(struct net_device *net) hi3110_hw_sleep(spi); out_close: hi3110_power_enable(priv->transceiver, 0); + out_close_candev: close_candev(net); mutex_unlock(&priv->hi3110_lock); return ret; diff --git a/drivers/net/can/spi/mcp251x.c b/drivers/net/can/spi/mcp251x.c index fa97adf25b73..bb7782582f40 100644 --- a/drivers/net/can/spi/mcp251x.c +++ b/drivers/net/can/spi/mcp251x.c @@ -1214,6 +1214,7 @@ static int mcp251x_open(struct net_device *net) { struct mcp251x_priv *priv = netdev_priv(net); struct spi_device *spi = priv->spi; + bool release_irq = false; unsigned long flags = 0; int ret; @@ -1257,12 +1258,24 @@ static int mcp251x_open(struct net_device *net) return 0; out_free_irq: - free_irq(spi->irq, priv); + /* The IRQ handler might be running, and if so it will be waiting + * for the lock. But free_irq() must wait for the handler to finish + * so calling it here would deadlock. + * + * Setting priv->force_quit will let the handler exit right away + * without any access to the hardware. This make it safe to call + * free_irq() after the lock is released. + */ + priv->force_quit = 1; + release_irq = true; + mcp251x_hw_sleep(spi); out_close: mcp251x_power_enable(priv->transceiver, 0); close_candev(net); mutex_unlock(&priv->mcp_lock); + if (release_irq) + free_irq(spi->irq, priv); return ret; } diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c index 5134ebb85880..9c86df08c2c5 100644 --- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c +++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c @@ -1961,11 +1961,11 @@ mcp251xfd_register_get_dev_id(const struct mcp251xfd_priv *priv, u32 *dev_id, struct spi_transfer xfer[2] = { }; int err; - buf_rx = kzalloc(sizeof(*buf_rx), GFP_KERNEL); + buf_rx = kzalloc_obj(*buf_rx); if (!buf_rx) return -ENOMEM; - buf_tx = kzalloc(sizeof(*buf_tx), GFP_KERNEL); + buf_tx = kzalloc_obj(*buf_tx); if (!buf_tx) { err = -ENOMEM; goto out_kfree_buf_rx; diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 4c219a5b139b..9b25dda7c183 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -445,6 +445,11 @@ static void ems_usb_read_bulk_callback(struct urb *urb) start = CPC_HEADER_SIZE; while (msg_count) { + if (start + CPC_MSG_HEADER_LEN > urb->actual_length) { + netdev_err(netdev, "format error\n"); + break; + } + msg = (struct ems_cpc_msg *)&ibuf[start]; switch (msg->type) { @@ -474,7 +479,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) start += CPC_MSG_HEADER_LEN + msg->length; msg_count--; - if (start > urb->transfer_buffer_length) { + if (start > urb->actual_length) { netdev_err(netdev, "format error\n"); break; } diff --git a/drivers/net/can/usb/esd_usb.c b/drivers/net/can/usb/esd_usb.c index 8cc924c47042..d257440fa01f 100644 --- a/drivers/net/can/usb/esd_usb.c +++ b/drivers/net/can/usb/esd_usb.c @@ -272,6 +272,9 @@ struct esd_usb { struct usb_anchor rx_submitted; + unsigned int rx_pipe; + unsigned int tx_pipe; + int net_count; u32 version; int rxinitdone; @@ -537,7 +540,7 @@ static void esd_usb_read_bulk_callback(struct urb *urb) } resubmit_urb: - usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1), + usb_fill_bulk_urb(urb, dev->udev, dev->rx_pipe, urb->transfer_buffer, ESD_USB_RX_BUFFER_SIZE, esd_usb_read_bulk_callback, dev); @@ -626,9 +629,7 @@ static int esd_usb_send_msg(struct esd_usb *dev, union esd_usb_msg *msg) { int actual_length; - return usb_bulk_msg(dev->udev, - usb_sndbulkpipe(dev->udev, 2), - msg, + return usb_bulk_msg(dev->udev, dev->tx_pipe, msg, msg->hdr.len * sizeof(u32), /* convert to # of bytes */ &actual_length, 1000); @@ -639,12 +640,8 @@ static int esd_usb_wait_msg(struct esd_usb *dev, { int actual_length; - return usb_bulk_msg(dev->udev, - usb_rcvbulkpipe(dev->udev, 1), - msg, - sizeof(*msg), - &actual_length, - 1000); + return usb_bulk_msg(dev->udev, dev->rx_pipe, msg, + sizeof(*msg), &actual_length, 1000); } static int esd_usb_setup_rx_urbs(struct esd_usb *dev) @@ -677,8 +674,7 @@ static int esd_usb_setup_rx_urbs(struct esd_usb *dev) urb->transfer_dma = buf_dma; - usb_fill_bulk_urb(urb, dev->udev, - usb_rcvbulkpipe(dev->udev, 1), + usb_fill_bulk_urb(urb, dev->udev, dev->rx_pipe, buf, ESD_USB_RX_BUFFER_SIZE, esd_usb_read_bulk_callback, dev); urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -726,7 +722,7 @@ static int esd_usb_start(struct esd_usb_net_priv *priv) union esd_usb_msg *msg; int err, i; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) { err = -ENOMEM; goto out; @@ -903,7 +899,7 @@ static netdev_tx_t esd_usb_start_xmit(struct sk_buff *skb, /* hnd must not be 0 - MSB is stripped in txdone handling */ msg->tx.hnd = BIT(31) | i; /* returned in TX done message */ - usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, + usb_fill_bulk_urb(urb, dev->udev, dev->tx_pipe, buf, msg->hdr.len * sizeof(u32), /* convert to # of bytes */ esd_usb_write_bulk_callback, context); @@ -962,7 +958,7 @@ static int esd_usb_stop(struct esd_usb_net_priv *priv) int err; int i; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -1068,7 +1064,7 @@ static int esd_usb_2_set_bittiming(struct net_device *netdev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) canbtr |= ESD_USB_TRIPLE_SAMPLES; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -1130,7 +1126,7 @@ static int esd_usb_3_set_bittiming(struct net_device *netdev) u16 flags = 0; int err; - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -1298,23 +1294,31 @@ static int esd_usb_probe_one_net(struct usb_interface *intf, int index) static int esd_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct usb_endpoint_descriptor *ep_in, *ep_out; struct esd_usb *dev; union esd_usb_msg *msg; int i, err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + err = usb_find_common_endpoints(intf->cur_altsetting, &ep_in, &ep_out, + NULL, NULL); + if (err) + return err; + + dev = kzalloc_obj(*dev); if (!dev) { err = -ENOMEM; goto done; } dev->udev = interface_to_usbdev(intf); + dev->rx_pipe = usb_rcvbulkpipe(dev->udev, ep_in->bEndpointAddress); + dev->tx_pipe = usb_sndbulkpipe(dev->udev, ep_out->bEndpointAddress); init_usb_anchor(&dev->rx_submitted); usb_set_intfdata(intf, dev); - msg = kmalloc(sizeof(*msg), GFP_KERNEL); + msg = kmalloc_obj(*msg); if (!msg) { err = -ENOMEM; goto free_msg; diff --git a/drivers/net/can/usb/etas_es58x/es58x_core.c b/drivers/net/can/usb/etas_es58x/es58x_core.c index 2d248deb69dc..b259f6109808 100644 --- a/drivers/net/can/usb/etas_es58x/es58x_core.c +++ b/drivers/net/can/usb/etas_es58x/es58x_core.c @@ -1461,12 +1461,18 @@ static void es58x_read_bulk_callback(struct urb *urb) } resubmit_urb: + usb_anchor_urb(urb, &es58x_dev->rx_urbs); ret = usb_submit_urb(urb, GFP_ATOMIC); + if (!ret) + return; + + usb_unanchor_urb(urb); + if (ret == -ENODEV) { for (i = 0; i < es58x_dev->num_can_ch; i++) if (es58x_dev->netdev[i]) netif_device_detach(es58x_dev->netdev[i]); - } else if (ret) + } else dev_err_ratelimited(dev, "Failed resubmitting read bulk urb: %pe\n", ERR_PTR(ret)); diff --git a/drivers/net/can/usb/f81604.c b/drivers/net/can/usb/f81604.c index efe61ece79ea..f12318268e46 100644 --- a/drivers/net/can/usb/f81604.c +++ b/drivers/net/can/usb/f81604.c @@ -413,6 +413,7 @@ static void f81604_read_bulk_callback(struct urb *urb) { struct f81604_can_frame *frame = urb->transfer_buffer; struct net_device *netdev = urb->context; + struct f81604_port_priv *priv = netdev_priv(netdev); int ret; if (!netif_device_present(netdev)) @@ -445,10 +446,15 @@ static void f81604_read_bulk_callback(struct urb *urb) f81604_process_rx_packet(netdev, frame); resubmit_urb: + usb_anchor_urb(urb, &priv->urbs_anchor); ret = usb_submit_urb(urb, GFP_ATOMIC); + if (!ret) + return; + usb_unanchor_urb(urb); + if (ret == -ENODEV) netif_device_detach(netdev); - else if (ret) + else netdev_err(netdev, "%s: failed to resubmit read bulk urb: %pe\n", __func__, ERR_PTR(ret)); @@ -620,6 +626,12 @@ static void f81604_read_int_callback(struct urb *urb) netdev_info(netdev, "%s: Int URB aborted: %pe\n", __func__, ERR_PTR(urb->status)); + if (urb->actual_length < sizeof(*data)) { + netdev_warn(netdev, "%s: short int URB: %u < %zu\n", + __func__, urb->actual_length, sizeof(*data)); + goto resubmit_urb; + } + switch (urb->status) { case 0: /* success */ break; @@ -646,10 +658,15 @@ static void f81604_read_int_callback(struct urb *urb) f81604_handle_tx(priv, data); resubmit_urb: + usb_anchor_urb(urb, &priv->urbs_anchor); ret = usb_submit_urb(urb, GFP_ATOMIC); + if (!ret) + return; + usb_unanchor_urb(urb); + if (ret == -ENODEV) netif_device_detach(netdev); - else if (ret) + else netdev_err(netdev, "%s: failed to resubmit int urb: %pe\n", __func__, ERR_PTR(ret)); } @@ -678,7 +695,7 @@ static int f81604_register_urbs(struct f81604_port_priv *priv) break; } - frame = kmalloc(sizeof(*frame), GFP_KERNEL); + frame = kmalloc_obj(*frame); if (!frame) { usb_free_urb(rx_urb); ret = -ENOMEM; @@ -717,7 +734,7 @@ static int f81604_register_urbs(struct f81604_port_priv *priv) goto error; } - int_data = kmalloc(sizeof(*int_data), GFP_KERNEL); + int_data = kmalloc_obj(*int_data); if (!int_data) { usb_free_urb(int_urb); ret = -ENOMEM; @@ -874,9 +891,27 @@ static void f81604_write_bulk_callback(struct urb *urb) if (!netif_device_present(netdev)) return; - if (urb->status) - netdev_info(netdev, "%s: Tx URB error: %pe\n", __func__, - ERR_PTR(urb->status)); + if (!urb->status) + return; + + switch (urb->status) { + case -ENOENT: + case -ECONNRESET: + case -ESHUTDOWN: + return; + default: + break; + } + + if (net_ratelimit()) + netdev_err(netdev, "%s: Tx URB error: %pe\n", __func__, + ERR_PTR(urb->status)); + + can_free_echo_skb(netdev, 0, NULL); + netdev->stats.tx_dropped++; + netdev->stats.tx_errors++; + + netif_wake_queue(netdev); } static void f81604_clear_reg_work(struct work_struct *work) @@ -919,7 +954,7 @@ static netdev_tx_t f81604_start_xmit(struct sk_buff *skb, if (!write_urb) goto nomem_urb; - frame = kzalloc(sizeof(*frame), GFP_ATOMIC); + frame = kzalloc_obj(*frame, GFP_ATOMIC); if (!frame) goto nomem_buf; diff --git a/drivers/net/can/usb/gs_usb.c b/drivers/net/can/usb/gs_usb.c index d8b2dd74b3a1..ec9a7cbbbc69 100644 --- a/drivers/net/can/usb/gs_usb.c +++ b/drivers/net/can/usb/gs_usb.c @@ -772,9 +772,8 @@ static void gs_usb_receive_bulk_callback(struct urb *urb) } } -static int gs_usb_set_bittiming(struct net_device *netdev) +static int gs_usb_set_bittiming(struct gs_can *dev) { - struct gs_can *dev = netdev_priv(netdev); struct can_bittiming *bt = &dev->can.bittiming; struct gs_device_bittiming dbt = { .prop_seg = cpu_to_le32(bt->prop_seg), @@ -791,9 +790,8 @@ static int gs_usb_set_bittiming(struct net_device *netdev) GFP_KERNEL); } -static int gs_usb_set_data_bittiming(struct net_device *netdev) +static int gs_usb_set_data_bittiming(struct gs_can *dev) { - struct gs_can *dev = netdev_priv(netdev); struct can_bittiming *bt = &dev->can.fd.data_bittiming; struct gs_device_bittiming dbt = { .prop_seg = cpu_to_le32(bt->prop_seg), @@ -1057,6 +1055,20 @@ static int gs_can_open(struct net_device *netdev) if (dev->feature & GS_CAN_FEATURE_HW_TIMESTAMP) flags |= GS_CAN_MODE_HW_TIMESTAMP; + rc = gs_usb_set_bittiming(dev); + if (rc) { + netdev_err(netdev, "failed to set bittiming: %pe\n", ERR_PTR(rc)); + goto out_usb_kill_anchored_urbs; + } + + if (ctrlmode & CAN_CTRLMODE_FD) { + rc = gs_usb_set_data_bittiming(dev); + if (rc) { + netdev_err(netdev, "failed to set data bittiming: %pe\n", ERR_PTR(rc)); + goto out_usb_kill_anchored_urbs; + } + } + /* finally start device */ dev->can.state = CAN_STATE_ERROR_ACTIVE; dm.flags = cpu_to_le32(flags); @@ -1370,7 +1382,6 @@ static struct gs_can *gs_make_candev(unsigned int channel, dev->can.state = CAN_STATE_STOPPED; dev->can.clock.freq = le32_to_cpu(bt_const.fclk_can); dev->can.bittiming_const = &dev->bt_const; - dev->can.do_set_bittiming = gs_usb_set_bittiming; dev->can.ctrlmode_supported = CAN_CTRLMODE_CC_LEN8_DLC; @@ -1394,7 +1405,6 @@ static struct gs_can *gs_make_candev(unsigned int channel, * GS_CAN_FEATURE_BT_CONST_EXT is set. */ dev->can.fd.data_bittiming_const = &dev->bt_const; - dev->can.fd.do_set_data_bittiming = gs_usb_set_data_bittiming; } if (feature & GS_CAN_FEATURE_TERMINATION) { @@ -1560,7 +1570,7 @@ static int gs_usb_probe(struct usb_interface *intf, return -EINVAL; } - parent = kzalloc(struct_size(parent, canch, icount), GFP_KERNEL); + parent = kzalloc_flex(*parent, canch, icount); if (!parent) return -ENOMEM; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c index a59f20dad692..e09d663e362f 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_hydra.c @@ -580,7 +580,7 @@ static int kvaser_usb_hydra_send_simple_cmd(struct kvaser_usb *dev, size_t cmd_len; int err; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -621,7 +621,7 @@ kvaser_usb_hydra_send_simple_cmd_async(struct kvaser_usb_net_priv *priv, size_t cmd_len; int err; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return -ENOMEM; @@ -742,7 +742,7 @@ static int kvaser_usb_hydra_map_channel(struct kvaser_usb *dev, u16 transid, struct kvaser_cmd *cmd; int err; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -784,7 +784,7 @@ static int kvaser_usb_hydra_get_single_capability(struct kvaser_usb *dev, int err; int i; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1465,7 +1465,7 @@ kvaser_usb_hydra_frame_to_cmd_ext(const struct kvaser_usb_net_priv *priv, u32 kcan_id; u32 kcan_header; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return NULL; @@ -1544,7 +1544,7 @@ kvaser_usb_hydra_frame_to_cmd_std(const struct kvaser_usb_net_priv *priv, u32 flags; u32 id; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return NULL; @@ -1610,7 +1610,7 @@ static int kvaser_usb_hydra_get_busparams(struct kvaser_usb_net_priv *priv, if (!hydra) return -EINVAL; - cmd = kcalloc(1, sizeof(struct kvaser_cmd), GFP_KERNEL); + cmd = kzalloc_objs(struct kvaser_cmd, 1); if (!cmd) return -ENOMEM; @@ -1655,7 +1655,7 @@ static int kvaser_usb_hydra_set_bittiming(const struct net_device *netdev, size_t cmd_len; int err; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1685,7 +1685,7 @@ static int kvaser_usb_hydra_set_data_bittiming(const struct net_device *netdev, size_t cmd_len; int err; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1842,7 +1842,7 @@ static int kvaser_usb_hydra_get_software_details(struct kvaser_usb *dev) u32 fw_version; struct kvaser_usb_dev_card_data *card_data = &dev->card_data; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1985,7 +1985,7 @@ static int kvaser_usb_hydra_set_led(struct kvaser_usb_net_priv *priv, size_t cmd_len; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -2021,7 +2021,7 @@ static int kvaser_usb_hydra_set_opt_mode(const struct kvaser_usb_net_priv *priv) return -EINVAL; } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c index 1167d38344f1..fd191ec5738b 100644 --- a/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c +++ b/drivers/net/can/usb/kvaser_usb/kvaser_usb_leaf.c @@ -616,7 +616,7 @@ kvaser_usb_leaf_frame_to_cmd(const struct kvaser_usb_net_priv *priv, u8 *cmd_tx_can_flags = NULL; /* GCC */ struct can_frame *cf = (struct can_frame *)skb->data; - cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kmalloc_obj(*cmd, GFP_ATOMIC); if (cmd) { cmd->u.tx_can.tid = transid & 0xff; cmd->len = *cmd_len = CMD_HEADER_LEN + @@ -723,7 +723,7 @@ static int kvaser_usb_leaf_send_simple_cmd(const struct kvaser_usb *dev, struct kvaser_cmd *cmd; int rc; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kmalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -873,7 +873,7 @@ static int kvaser_usb_leaf_get_single_capability(struct kvaser_usb *dev, int err; int i; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -970,7 +970,7 @@ static int kvaser_usb_leaf_set_led(struct kvaser_usb_net_priv *priv, struct kvaser_cmd *cmd; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1079,7 +1079,7 @@ static int kvaser_usb_leaf_simple_cmd_async(struct kvaser_usb_net_priv *priv, struct kvaser_cmd *cmd; int err; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return -ENOMEM; @@ -1752,7 +1752,7 @@ static int kvaser_usb_leaf_set_opt_mode(const struct kvaser_usb_net_priv *priv) struct kvaser_cmd *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1824,7 +1824,7 @@ static int kvaser_usb_leaf_flush_queue(struct kvaser_usb_net_priv *priv) struct kvaser_cmd *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1881,7 +1881,7 @@ static int kvaser_usb_leaf_set_bittiming(const struct net_device *netdev, struct kvaser_cmd *cmd; int rc; - cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kmalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/can/usb/nct6694_canfd.c b/drivers/net/can/usb/nct6694_canfd.c index dd6df2ec3742..e5f7f8849a73 100644 --- a/drivers/net/can/usb/nct6694_canfd.c +++ b/drivers/net/can/usb/nct6694_canfd.c @@ -527,7 +527,7 @@ static int nct6694_canfd_start(struct net_device *ndev) u32 en_tdc; int ret; - setting = kzalloc(sizeof(*setting), GFP_KERNEL); + setting = kzalloc_obj(*setting); if (!setting) return -ENOMEM; @@ -596,7 +596,7 @@ static void nct6694_canfd_stop(struct net_device *ndev) * mode allows the device to monitor bus activity without actively * participating in communication. */ - setting = kzalloc(sizeof(*setting), GFP_KERNEL); + setting = kzalloc_obj(*setting); if (!setting) return; @@ -707,7 +707,7 @@ static int nct6694_canfd_get_clock(struct nct6694_canfd_priv *priv) }; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c index be84191cde56..eb4f5884ad73 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c @@ -939,7 +939,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev) /* do this for 1st channel only */ if (!dev->prev_siblings) { /* allocate netdevices common structure attached to first one */ - pdev->usb_if = kzalloc(sizeof(*pdev->usb_if), GFP_KERNEL); + pdev->usb_if = kzalloc_obj(*pdev->usb_if); if (!pdev->usb_if) goto err_out; diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c index 7be286293b1a..4bfa8d0fbb32 100644 --- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c +++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c @@ -870,10 +870,9 @@ static int pcan_usb_pro_init(struct peak_usb_device *dev) /* do this for 1st channel only */ if (!dev->prev_siblings) { /* allocate netdevices common structure attached to first one */ - usb_if = kzalloc(sizeof(struct pcan_usb_pro_interface), - GFP_KERNEL); - fi = kmalloc(sizeof(struct pcan_usb_pro_fwinfo), GFP_KERNEL); - bi = kmalloc(sizeof(struct pcan_usb_pro_blinfo), GFP_KERNEL); + usb_if = kzalloc_obj(struct pcan_usb_pro_interface); + fi = kmalloc_obj(struct pcan_usb_pro_fwinfo); + bi = kmalloc_obj(struct pcan_usb_pro_blinfo); if (!usb_if || !fi || !bi) { err = -ENOMEM; goto err_out; diff --git a/drivers/net/can/usb/ucan.c b/drivers/net/can/usb/ucan.c index de61d9da99e3..0ea0ac75e42f 100644 --- a/drivers/net/can/usb/ucan.c +++ b/drivers/net/can/usb/ucan.c @@ -330,9 +330,8 @@ static int ucan_alloc_context_array(struct ucan_priv *up) /* release contexts if any */ ucan_release_context_array(up); - up->context_array = kcalloc(up->device_info.tx_fifo, - sizeof(*up->context_array), - GFP_KERNEL); + up->context_array = kzalloc_objs(*up->context_array, + up->device_info.tx_fifo); if (!up->context_array) { netdev_err(up->netdev, "Not enough memory to allocate tx contexts\n"); @@ -749,7 +748,7 @@ static void ucan_read_bulk_callback(struct urb *urb) len = le16_to_cpu(m->len); /* check sanity (length of content) */ - if (urb->actual_length - pos < len) { + if ((len == 0) || (urb->actual_length - pos < len)) { netdev_warn(up->netdev, "invalid message (short; no data; l:%d)\n", urb->actual_length); diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index e22362e6f0cd..50d3a818eb1b 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c @@ -950,7 +950,7 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, if (ret == 0) return -EEXIST; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c index dd5f263ab984..b369c1cc89e8 100644 --- a/drivers/net/dsa/hirschmann/hellcreek.c +++ b/drivers/net/dsa/hirschmann/hellcreek.c @@ -1265,7 +1265,7 @@ static int hellcreek_devlink_region_vlan_snapshot(struct devlink *dl, struct hellcreek *hellcreek = ds->priv; int i; - table = kcalloc(VLAN_N_VID, sizeof(*entry), GFP_KERNEL); + table = kzalloc_objs(*entry, VLAN_N_VID); if (!table) return -ENOMEM; @@ -1293,7 +1293,7 @@ static int hellcreek_devlink_region_fdb_snapshot(struct devlink *dl, struct hellcreek *hellcreek = ds->priv; size_t i; - table = kcalloc(hellcreek->fdb_entries, sizeof(*entry), GFP_KERNEL); + table = kzalloc_objs(*entry, hellcreek->fdb_entries); if (!table) return -ENOMEM; diff --git a/drivers/net/dsa/microchip/ksz9477_acl.c b/drivers/net/dsa/microchip/ksz9477_acl.c index 7ba778df63ac..d3e974602193 100644 --- a/drivers/net/dsa/microchip/ksz9477_acl.c +++ b/drivers/net/dsa/microchip/ksz9477_acl.c @@ -1060,7 +1060,7 @@ int ksz9477_port_acl_init(struct ksz_device *dev, int port) struct ksz9477_acl_priv *acl; int ret, i; - acl = kzalloc(sizeof(*acl), GFP_KERNEL); + acl = kzalloc_obj(*acl); if (!acl) return -ENOMEM; diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index e5fa1f5fc09b..c517478cc476 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -4835,7 +4835,7 @@ int ksz_switch_macaddr_get(struct dsa_switch *ds, int port, return 0; } - switch_macaddr = kzalloc(sizeof(*switch_macaddr), GFP_KERNEL); + switch_macaddr = kzalloc_obj(*switch_macaddr); if (!switch_macaddr) return -ENOMEM; diff --git a/drivers/net/dsa/microchip/ksz_ptp.c b/drivers/net/dsa/microchip/ksz_ptp.c index 4a2cc57a628f..8b98039320ad 100644 --- a/drivers/net/dsa/microchip/ksz_ptp.c +++ b/drivers/net/dsa/microchip/ksz_ptp.c @@ -1108,6 +1108,7 @@ static int ksz_ptp_msg_irq_setup(struct ksz_port *port, u8 n) const struct ksz_dev_ops *ops = port->ksz_dev->dev_ops; struct ksz_irq *ptpirq = &port->ptpirq; struct ksz_ptp_irq *ptpmsg_irq; + int ret; ptpmsg_irq = &port->ptpmsg_irq[n]; ptpmsg_irq->num = irq_create_mapping(ptpirq->domain, n); @@ -1119,9 +1120,13 @@ static int ksz_ptp_msg_irq_setup(struct ksz_port *port, u8 n) strscpy(ptpmsg_irq->name, name[n]); - return request_threaded_irq(ptpmsg_irq->num, NULL, - ksz_ptp_msg_thread_fn, IRQF_ONESHOT, - ptpmsg_irq->name, ptpmsg_irq); + ret = request_threaded_irq(ptpmsg_irq->num, NULL, + ksz_ptp_msg_thread_fn, IRQF_ONESHOT, + ptpmsg_irq->name, ptpmsg_irq); + if (ret) + irq_dispose_mapping(ptpmsg_irq->num); + + return ret; } int ksz_ptp_irq_setup(struct dsa_switch *ds, u8 p) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 09002c853b78..6fcd7181116a 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2024,7 +2024,7 @@ static int mv88e6xxx_mst_get(struct mv88e6xxx_chip *chip, struct net_device *br, if (err) goto err; - mst = kzalloc(sizeof(*mst), GFP_KERNEL); + mst = kzalloc_obj(*mst); if (!mst) { err = -ENOMEM; goto err; diff --git a/drivers/net/dsa/mv88e6xxx/devlink.c b/drivers/net/dsa/mv88e6xxx/devlink.c index da69e0b85879..0f84bffc8ef1 100644 --- a/drivers/net/dsa/mv88e6xxx/devlink.c +++ b/drivers/net/dsa/mv88e6xxx/devlink.c @@ -378,9 +378,8 @@ static int mv88e6xxx_region_atu_snapshot(struct devlink *dl, struct mv88e6xxx_chip *chip = ds->priv; int fid = -1, err = 0, count = 0; - table = kcalloc(mv88e6xxx_num_databases(chip), - sizeof(struct mv88e6xxx_devlink_atu_entry), - GFP_KERNEL); + table = kzalloc_objs(struct mv88e6xxx_devlink_atu_entry, + mv88e6xxx_num_databases(chip)); if (!table) return -ENOMEM; @@ -440,9 +439,8 @@ static int mv88e6xxx_region_vtu_snapshot(struct devlink *dl, struct mv88e6xxx_vtu_entry vlan; int err; - table = kcalloc(mv88e6xxx_max_vid(chip) + 1, - sizeof(struct mv88e6xxx_devlink_vtu_entry), - GFP_KERNEL); + table = kzalloc_objs(struct mv88e6xxx_devlink_vtu_entry, + mv88e6xxx_max_vid(chip) + 1); if (!table) return -ENOMEM; @@ -523,9 +521,8 @@ static int mv88e6xxx_region_stu_snapshot(struct devlink *dl, struct mv88e6xxx_stu_entry stu; int err; - table = kcalloc(mv88e6xxx_max_sid(chip) + 1, - sizeof(struct mv88e6xxx_devlink_stu_entry), - GFP_KERNEL); + table = kzalloc_objs(struct mv88e6xxx_devlink_stu_entry, + mv88e6xxx_max_sid(chip) + 1); if (!table) return -ENOMEM; diff --git a/drivers/net/dsa/mv88e6xxx/pcs-6185.c b/drivers/net/dsa/mv88e6xxx/pcs-6185.c index af7e06d265f7..7e52cb88554e 100644 --- a/drivers/net/dsa/mv88e6xxx/pcs-6185.c +++ b/drivers/net/dsa/mv88e6xxx/pcs-6185.c @@ -131,7 +131,7 @@ static int mv88e6185_pcs_init(struct mv88e6xxx_chip *chip, int port) dev = chip->dev; - mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); + mpcs = kzalloc_obj(*mpcs); if (!mpcs) return -ENOMEM; diff --git a/drivers/net/dsa/mv88e6xxx/pcs-6352.c b/drivers/net/dsa/mv88e6xxx/pcs-6352.c index 36993400837e..9ebf0f89f817 100644 --- a/drivers/net/dsa/mv88e6xxx/pcs-6352.c +++ b/drivers/net/dsa/mv88e6xxx/pcs-6352.c @@ -267,7 +267,7 @@ static struct marvell_c22_pcs *marvell_c22_pcs_alloc(struct device *dev, { struct marvell_c22_pcs *mpcs; - mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); + mpcs = kzalloc_obj(*mpcs); if (!mpcs) return NULL; diff --git a/drivers/net/dsa/mv88e6xxx/pcs-639x.c b/drivers/net/dsa/mv88e6xxx/pcs-639x.c index 5db17c0b77f5..a5fd187a7bf3 100644 --- a/drivers/net/dsa/mv88e6xxx/pcs-639x.c +++ b/drivers/net/dsa/mv88e6xxx/pcs-639x.c @@ -67,7 +67,7 @@ mv88e639x_pcs_alloc(struct device *dev, struct mii_bus *bus, unsigned int addr, { struct mv88e639x_pcs *mpcs; - mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); + mpcs = kzalloc_obj(*mpcs); if (!mpcs) return NULL; diff --git a/drivers/net/dsa/mxl862xx/Kconfig b/drivers/net/dsa/mxl862xx/Kconfig index 4db7bab21a71..3e772298cc89 100644 --- a/drivers/net/dsa/mxl862xx/Kconfig +++ b/drivers/net/dsa/mxl862xx/Kconfig @@ -2,7 +2,6 @@ config NET_DSA_MXL862 tristate "MaxLinear MxL862xx" depends on NET_DSA - select MAXLINEAR_GPHY select NET_DSA_TAG_MXL_862XX help This enables support for the MaxLinear MxL862xx switch family. diff --git a/drivers/net/dsa/mxl862xx/mxl862xx.c b/drivers/net/dsa/mxl862xx/mxl862xx.c index b1e2094b5816..d7ab04f5afef 100644 --- a/drivers/net/dsa/mxl862xx/mxl862xx.c +++ b/drivers/net/dsa/mxl862xx/mxl862xx.c @@ -149,7 +149,6 @@ static int mxl862xx_setup_mdio(struct dsa_switch *ds) return -ENOMEM; bus->priv = priv; - ds->user_mii_bus = bus; bus->name = KBUILD_MODNAME "-mii"; snprintf(bus->id, MII_BUS_ID_SIZE, "%s-mii", dev_name(dev)); bus->read_c45 = mxl862xx_phy_read_c45_mii_bus; diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 5d34eb82e639..84cf8e7fb17a 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -109,8 +109,7 @@ static int felix_tag_8021q_vlan_add_rx(struct dsa_switch *ds, int port, key_length = ocelot->vcap[VCAP_ES0].keys[VCAP_ES0_IGR_PORT].length; - outer_tagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), - GFP_KERNEL); + outer_tagging_rule = kzalloc_obj(struct ocelot_vcap_filter); if (!outer_tagging_rule) return -ENOMEM; @@ -178,11 +177,11 @@ static int felix_tag_8021q_vlan_add_tx(struct dsa_switch *ds, int port, unsigned long cookie; int err; - untagging_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL); + untagging_rule = kzalloc_obj(struct ocelot_vcap_filter); if (!untagging_rule) return -ENOMEM; - redirect_rule = kzalloc(sizeof(struct ocelot_vcap_filter), GFP_KERNEL); + redirect_rule = kzalloc_obj(struct ocelot_vcap_filter); if (!redirect_rule) { kfree(untagging_rule); return -ENOMEM; @@ -1540,8 +1539,7 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) ocelot->npi_xtr_prefix = OCELOT_TAG_PREFIX_SHORT; ocelot->devlink = felix->ds->devlink; - port_phy_modes = kcalloc(num_phys_ports, sizeof(phy_interface_t), - GFP_KERNEL); + port_phy_modes = kzalloc_objs(phy_interface_t, num_phys_ports); if (!port_phy_modes) return -ENOMEM; diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 8cf4c8986587..8387dd208adb 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -2201,7 +2201,7 @@ static int vsc9959_psfp_sgi_table_add(struct ocelot *ocelot, return 0; } - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index c575e164368c..31fa94dac627 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -769,7 +769,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy, out: rtl83xx_unlock(priv); - return 0; + return ret; } static int rtl8365mb_phy_read(struct realtek_priv *priv, int phy, int regnum) @@ -1480,8 +1480,7 @@ static void rtl8365mb_stats_update(struct realtek_priv *priv, int port) stats->rx_packets = cnt[RTL8365MB_MIB_ifInUcastPkts] + cnt[RTL8365MB_MIB_ifInMulticastPkts] + - cnt[RTL8365MB_MIB_ifInBroadcastPkts] - - cnt[RTL8365MB_MIB_ifOutDiscards]; + cnt[RTL8365MB_MIB_ifInBroadcastPkts]; stats->tx_packets = cnt[RTL8365MB_MIB_ifOutUcastPkts] + cnt[RTL8365MB_MIB_ifOutMulticastPkts] + diff --git a/drivers/net/dsa/realtek/rtl8366rb-leds.c b/drivers/net/dsa/realtek/rtl8366rb-leds.c index 99c890681ae6..509ffd3f8db5 100644 --- a/drivers/net/dsa/realtek/rtl8366rb-leds.c +++ b/drivers/net/dsa/realtek/rtl8366rb-leds.c @@ -12,11 +12,11 @@ static inline u32 rtl8366rb_led_group_port_mask(u8 led_group, u8 port) case 0: return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); case 1: - return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); + return FIELD_PREP(RTL8366RB_LED_X_1_CTRL_MASK, BIT(port)); case 2: - return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); + return FIELD_PREP(RTL8366RB_LED_2_X_CTRL_MASK, BIT(port)); case 3: - return FIELD_PREP(RTL8366RB_LED_0_X_CTRL_MASK, BIT(port)); + return FIELD_PREP(RTL8366RB_LED_X_3_CTRL_MASK, BIT(port)); default: return 0; } diff --git a/drivers/net/dsa/sja1105/sja1105_devlink.c b/drivers/net/dsa/sja1105/sja1105_devlink.c index 30b1f1ba762f..f8580508e0e2 100644 --- a/drivers/net/dsa/sja1105/sja1105_devlink.c +++ b/drivers/net/dsa/sja1105/sja1105_devlink.c @@ -82,8 +82,7 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds) struct devlink_region *region; u64 size; - priv->regions = kcalloc(num_regions, sizeof(struct devlink_region *), - GFP_KERNEL); + priv->regions = kzalloc_objs(struct devlink_region *, num_regions); if (!priv->regions) return -ENOMEM; diff --git a/drivers/net/dsa/sja1105/sja1105_flower.c b/drivers/net/dsa/sja1105/sja1105_flower.c index 05d8ed3121e7..fba926f85b47 100644 --- a/drivers/net/dsa/sja1105/sja1105_flower.c +++ b/drivers/net/dsa/sja1105/sja1105_flower.c @@ -41,7 +41,7 @@ static int sja1105_setup_bcast_policer(struct sja1105_private *priv, int rc; if (!rule) { - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -112,7 +112,7 @@ static int sja1105_setup_tc_policer(struct sja1105_private *priv, int rc; if (!rule) { - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 71a817c07a90..c72c2bfdcffb 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -2278,6 +2278,12 @@ int sja1105_static_config_reload(struct sja1105_private *priv, * change it through the dynamic interface later. */ dsa_switch_for_each_available_port(dp, ds) { + /* May be called during unbind when we unoffload a VLAN-aware + * bridge from port 1 while port 0 was already torn down + */ + if (!dp->pl) + continue; + phylink_replay_link_begin(dp->pl); mac[dp->index].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; } @@ -2333,13 +2339,13 @@ int sja1105_static_config_reload(struct sja1105_private *priv, goto out; } - dsa_switch_for_each_available_port(dp, ds) - phylink_replay_link_end(dp->pl); - rc = sja1105_reload_cbs(priv); - if (rc < 0) - goto out; + out: + dsa_switch_for_each_available_port(dp, ds) + if (dp->pl) + phylink_replay_link_end(dp->pl); + mutex_unlock(&priv->mgmt_lock); mutex_unlock(&priv->fdb_lock); diff --git a/drivers/net/dsa/sja1105/sja1105_tas.c b/drivers/net/dsa/sja1105/sja1105_tas.c index d5949d2c3e71..e47967b12d5d 100644 --- a/drivers/net/dsa/sja1105/sja1105_tas.c +++ b/drivers/net/dsa/sja1105/sja1105_tas.c @@ -477,7 +477,7 @@ bool sja1105_gating_check_conflicts(struct sja1105_private *priv, int port, if (list_empty(&gating_cfg->entries)) return false; - dummy = kzalloc(struct_size(dummy, entries, num_entries), GFP_KERNEL); + dummy = kzalloc_flex(*dummy, entries, num_entries); if (!dummy) { NL_SET_ERR_MSG_MOD(extack, "Failed to allocate memory"); return true; diff --git a/drivers/net/dsa/sja1105/sja1105_vl.c b/drivers/net/dsa/sja1105/sja1105_vl.c index b7e95d60a6e4..0ae9cb5ea8d1 100644 --- a/drivers/net/dsa/sja1105/sja1105_vl.c +++ b/drivers/net/dsa/sja1105/sja1105_vl.c @@ -16,7 +16,7 @@ static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg, struct sja1105_gate_entry *e; int rc; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; @@ -524,7 +524,7 @@ int sja1105_vl_redirect(struct sja1105_private *priv, int port, } if (!rule) { - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -622,7 +622,7 @@ int sja1105_vl_gate(struct sja1105_private *priv, int port, } if (!rule) { - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -635,9 +635,8 @@ int sja1105_vl_gate(struct sja1105_private *priv, int port, rule->vl.base_time = base_time; rule->vl.cycle_time = cycle_time; rule->vl.num_entries = num_entries; - rule->vl.entries = kcalloc(num_entries, - sizeof(struct action_gate_entry), - GFP_KERNEL); + rule->vl.entries = kzalloc_objs(struct action_gate_entry, + num_entries); if (!rule->vl.entries) { rc = -ENOMEM; goto out; diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index 9d31b8258268..6f586d3da9d4 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -1664,7 +1664,7 @@ static int vsc73xx_port_vlan_add(struct dsa_switch *ds, int port, vsc73xx_vlan = vsc73xx_bridge_vlan_find(vsc, vlan->vid); if (!vsc73xx_vlan) { - vsc73xx_vlan = kzalloc(sizeof(*vsc73xx_vlan), GFP_KERNEL); + vsc73xx_vlan = kzalloc_obj(*vsc73xx_vlan); if (!vsc73xx_vlan) return -ENOMEM; diff --git a/drivers/net/eql.c b/drivers/net/eql.c index 9ba10efd3794..06083b9841ba 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -425,7 +425,7 @@ static int eql_enslave(struct net_device *master_dev, slaving_request_t __user * if ((master_dev->flags & IFF_UP) == IFF_UP) { /* slave is not a master & not already a slave: */ if (!eql_is_master(slave_dev) && !eql_is_slave(slave_dev)) { - slave_t *s = kzalloc(sizeof(*s), GFP_KERNEL); + slave_t *s = kzalloc_obj(*s); equalizer_t *eql = netdev_priv(master_dev); int ret; diff --git a/drivers/net/ethernet/adi/adin1110.c b/drivers/net/ethernet/adi/adin1110.c index 1b4e37d000b9..53fac3dc8be6 100644 --- a/drivers/net/ethernet/adi/adin1110.c +++ b/drivers/net/ethernet/adi/adin1110.c @@ -1492,7 +1492,7 @@ static int adin1110_switchdev_event(struct notifier_block *unused, if (!adin1110_port_dev_check(netdev)) return NOTIFY_DONE; - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; diff --git a/drivers/net/ethernet/agere/et131x.c b/drivers/net/ethernet/agere/et131x.c index 5c8217638dda..0f6e5373029a 100644 --- a/drivers/net/ethernet/agere/et131x.c +++ b/drivers/net/ethernet/agere/et131x.c @@ -1866,10 +1866,10 @@ static int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) struct fbr_lookup *fbr; /* Alloc memory for the lookup table */ - rx_ring->fbr[0] = kzalloc(sizeof(*fbr), GFP_KERNEL); + rx_ring->fbr[0] = kzalloc_obj(*fbr); if (rx_ring->fbr[0] == NULL) return -ENOMEM; - rx_ring->fbr[1] = kzalloc(sizeof(*fbr), GFP_KERNEL); + rx_ring->fbr[1] = kzalloc_obj(*fbr); if (rx_ring->fbr[1] == NULL) return -ENOMEM; @@ -2089,7 +2089,7 @@ static int et131x_init_recv(struct et131x_adapter *adapter) /* Setup each RFD */ for (rfdct = 0; rfdct < rx_ring->num_rfd; rfdct++) { - rfd = kzalloc(sizeof(*rfd), GFP_ATOMIC | GFP_DMA); + rfd = kzalloc_obj(*rfd, GFP_ATOMIC | GFP_DMA); if (!rfd) return -ENOMEM; @@ -2357,8 +2357,8 @@ static int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter) struct tx_ring *tx_ring = &adapter->tx_ring; /* Allocate memory for the TCB's (Transmit Control Block) */ - tx_ring->tcb_ring = kcalloc(NUM_TCB, sizeof(struct tcb), - GFP_KERNEL | GFP_DMA); + tx_ring->tcb_ring = kzalloc_objs(struct tcb, NUM_TCB, + GFP_KERNEL | GFP_DMA); if (!tx_ring->tcb_ring) return -ENOMEM; diff --git a/drivers/net/ethernet/airoha/airoha_npu.c b/drivers/net/ethernet/airoha/airoha_npu.c index 89f22f3f47dc..17dbdc832533 100644 --- a/drivers/net/ethernet/airoha/airoha_npu.c +++ b/drivers/net/ethernet/airoha/airoha_npu.c @@ -333,7 +333,7 @@ static int airoha_npu_ppe_init(struct airoha_npu *npu) struct ppe_mbox_data *ppe_data; int err; - ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); + ppe_data = kzalloc_obj(*ppe_data); if (!ppe_data) return -ENOMEM; @@ -354,7 +354,7 @@ static int airoha_npu_ppe_deinit(struct airoha_npu *npu) struct ppe_mbox_data *ppe_data; int err; - ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); + ppe_data = kzalloc_obj(*ppe_data); if (!ppe_data) return -ENOMEM; @@ -375,7 +375,7 @@ static int airoha_npu_ppe_flush_sram_entries(struct airoha_npu *npu, struct ppe_mbox_data *ppe_data; int err; - ppe_data = kzalloc(sizeof(*ppe_data), GFP_KERNEL); + ppe_data = kzalloc_obj(*ppe_data); if (!ppe_data) return -ENOMEM; @@ -399,7 +399,7 @@ static int airoha_npu_foe_commit_entry(struct airoha_npu *npu, struct ppe_mbox_data *ppe_data; int err; - ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); + ppe_data = kzalloc_obj(*ppe_data, GFP_ATOMIC); if (!ppe_data) return -ENOMEM; @@ -434,7 +434,7 @@ static int airoha_npu_ppe_stats_setup(struct airoha_npu *npu, int err, size = num_stats_entries * sizeof(*npu->stats); struct ppe_mbox_data *ppe_data; - ppe_data = kzalloc(sizeof(*ppe_data), GFP_ATOMIC); + ppe_data = kzalloc_obj(*ppe_data, GFP_ATOMIC); if (!ppe_data) return -ENOMEM; diff --git a/drivers/net/ethernet/airoha/airoha_ppe.c b/drivers/net/ethernet/airoha/airoha_ppe.c index 2221bafaf7c9..42dbe8f93231 100644 --- a/drivers/net/ethernet/airoha/airoha_ppe.c +++ b/drivers/net/ethernet/airoha/airoha_ppe.c @@ -778,7 +778,7 @@ airoha_ppe_foe_commit_subflow_entry(struct airoha_ppe *ppe, if (!hwe_p) return -EINVAL; - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return -ENOMEM; @@ -1173,7 +1173,7 @@ static int airoha_ppe_flow_offload_replace(struct airoha_eth *eth, return err; } - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; diff --git a/drivers/net/ethernet/alacritech/slicoss.c b/drivers/net/ethernet/alacritech/slicoss.c index 7488fb6ace0b..c1949ca060ca 100644 --- a/drivers/net/ethernet/alacritech/slicoss.c +++ b/drivers/net/ethernet/alacritech/slicoss.c @@ -192,7 +192,7 @@ static int slic_new_upr(struct slic_device *sdev, unsigned int type, { struct slic_upr *upr; - upr = kmalloc(sizeof(*upr), GFP_ATOMIC); + upr = kmalloc_obj(*upr, GFP_ATOMIC); if (!upr) return -ENOMEM; upr->type = type; @@ -845,7 +845,7 @@ static int slic_init_tx_queue(struct slic_device *sdev) txq->put_idx = 0; txq->done_idx = 0; - txq->txbuffs = kcalloc(txq->len, sizeof(*buff), GFP_KERNEL); + txq->txbuffs = kzalloc_objs(*buff, txq->len); if (!txq->txbuffs) return -ENOMEM; @@ -922,7 +922,7 @@ static int slic_init_rx_queue(struct slic_device *sdev) rxq->done_idx = 0; rxq->put_idx = 0; - buff = kcalloc(rxq->len, sizeof(*buff), GFP_KERNEL); + buff = kzalloc_objs(*buff, rxq->len); if (!buff) return -ENOMEM; diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c index 2f516b950f4e..fc7341a5cbb7 100644 --- a/drivers/net/ethernet/allwinner/sun4i-emac.c +++ b/drivers/net/ethernet/allwinner/sun4i-emac.c @@ -223,7 +223,7 @@ emac_alloc_dma_req(struct emac_board_info *db, { struct emac_dma_req *req; - req = kzalloc(sizeof(struct emac_dma_req), GFP_ATOMIC); + req = kzalloc_obj(struct emac_dma_req, GFP_ATOMIC); if (!req) return NULL; diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index 9e6f91df2ba0..455ee8930824 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -1149,7 +1149,7 @@ static int ace_init(struct net_device *dev) /* * Get the memory for the skb rings. */ - if (!(ap->skb = kzalloc(sizeof(struct ace_skb), GFP_KERNEL))) { + if (!(ap->skb = kzalloc_obj(struct ace_skb))) { ecode = -EAGAIN; goto init_error; } diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index ca55c5fd11df..4342e2d026f8 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c @@ -258,14 +258,12 @@ static int alloc_init_skbufs(struct altera_tse_private *priv) int i; /* Create Rx ring buffer */ - priv->rx_ring = kcalloc(rx_descs, sizeof(struct tse_buffer), - GFP_KERNEL); + priv->rx_ring = kzalloc_objs(struct tse_buffer, rx_descs); if (!priv->rx_ring) goto err_rx_ring; /* Create Tx ring buffer */ - priv->tx_ring = kcalloc(tx_descs, sizeof(struct tse_buffer), - GFP_KERNEL); + priv->tx_ring = kzalloc_objs(struct tse_buffer, tx_descs); if (!priv->tx_ring) goto err_tx_ring; diff --git a/drivers/net/ethernet/amd/lance.c b/drivers/net/ethernet/amd/lance.c index b1e6620ad41d..98afd8cb0efb 100644 --- a/drivers/net/ethernet/amd/lance.c +++ b/drivers/net/ethernet/amd/lance.c @@ -551,7 +551,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int dev->base_addr = ioaddr; /* Make certain the data structures used by the LANCE are aligned and DMAble. */ - lp = kzalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL); + lp = kzalloc_obj(*lp, GFP_DMA | GFP_KERNEL); if (!lp) return -ENOMEM; if (lance_debug > 6) printk(" (#0x%05lx)", (unsigned long)lp); diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 9eaefa0f5e80..911808ab13a7 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -491,11 +491,11 @@ static void pcnet32_realloc_tx_ring(struct net_device *dev, if (!new_tx_ring) return; - new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC); + new_dma_addr_list = kzalloc_objs(dma_addr_t, entries, GFP_ATOMIC); if (!new_dma_addr_list) goto free_new_tx_ring; - new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC); + new_skb_list = kzalloc_objs(struct sk_buff *, entries, GFP_ATOMIC); if (!new_skb_list) goto free_new_lists; @@ -550,11 +550,11 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev, if (!new_rx_ring) return; - new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC); + new_dma_addr_list = kzalloc_objs(dma_addr_t, entries, GFP_ATOMIC); if (!new_dma_addr_list) goto free_new_rx_ring; - new_skb_list = kcalloc(entries, sizeof(struct sk_buff *), GFP_ATOMIC); + new_skb_list = kzalloc_objs(struct sk_buff *, entries, GFP_ATOMIC); if (!new_skb_list) goto free_new_lists; @@ -2035,23 +2035,19 @@ static int pcnet32_alloc_ring(struct net_device *dev, const char *name) return -ENOMEM; } - lp->tx_dma_addr = kcalloc(lp->tx_ring_size, sizeof(dma_addr_t), - GFP_KERNEL); + lp->tx_dma_addr = kzalloc_objs(dma_addr_t, lp->tx_ring_size); if (!lp->tx_dma_addr) return -ENOMEM; - lp->rx_dma_addr = kcalloc(lp->rx_ring_size, sizeof(dma_addr_t), - GFP_KERNEL); + lp->rx_dma_addr = kzalloc_objs(dma_addr_t, lp->rx_ring_size); if (!lp->rx_dma_addr) return -ENOMEM; - lp->tx_skbuff = kcalloc(lp->tx_ring_size, sizeof(struct sk_buff *), - GFP_KERNEL); + lp->tx_skbuff = kzalloc_objs(struct sk_buff *, lp->tx_ring_size); if (!lp->tx_skbuff) return -ENOMEM; - lp->rx_skbuff = kcalloc(lp->rx_ring_size, sizeof(struct sk_buff *), - GFP_KERNEL); + lp->rx_skbuff = kzalloc_objs(struct sk_buff *, lp->rx_ring_size); if (!lp->rx_skbuff) return -ENOMEM; diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c index 92f359f2b449..73b3481220b1 100644 --- a/drivers/net/ethernet/amd/pds_core/auxbus.c +++ b/drivers/net/ethernet/amd/pds_core/auxbus.c @@ -140,7 +140,7 @@ static struct pds_auxiliary_dev *pdsc_auxbus_dev_register(struct pdsc *cf, struct pds_auxiliary_dev *padev; int err; - padev = kzalloc(sizeof(*padev), GFP_KERNEL); + padev = kzalloc_obj(*padev); if (!padev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c index 076dfe2910c7..705cab7b0727 100644 --- a/drivers/net/ethernet/amd/pds_core/core.c +++ b/drivers/net/ethernet/amd/pds_core/core.c @@ -415,9 +415,8 @@ static int pdsc_viftypes_init(struct pdsc *pdsc) { enum pds_core_vif_types vt; - pdsc->viftype_status = kcalloc(ARRAY_SIZE(pdsc_viftype_defaults), - sizeof(*pdsc->viftype_status), - GFP_KERNEL); + pdsc->viftype_status = kzalloc_objs(*pdsc->viftype_status, + ARRAY_SIZE(pdsc_viftype_defaults)); if (!pdsc->viftype_status) return -ENOMEM; diff --git a/drivers/net/ethernet/amd/pds_core/dev.c b/drivers/net/ethernet/amd/pds_core/dev.c index 495ef4ef8c10..2e1d0d01d03a 100644 --- a/drivers/net/ethernet/amd/pds_core/dev.c +++ b/drivers/net/ethernet/amd/pds_core/dev.c @@ -359,7 +359,7 @@ int pdsc_dev_init(struct pdsc *pdsc) nintrs = min_t(unsigned int, num_online_cpus(), nintrs); /* Get intr_info struct array for tracking */ - pdsc->intr_info = kcalloc(nintrs, sizeof(*pdsc->intr_info), GFP_KERNEL); + pdsc->intr_info = kzalloc_objs(*pdsc->intr_info, nintrs); if (!pdsc->intr_info) return -ENOMEM; diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c index c7a2eff57632..22db78343eb0 100644 --- a/drivers/net/ethernet/amd/pds_core/main.c +++ b/drivers/net/ethernet/amd/pds_core/main.c @@ -146,8 +146,7 @@ static int pdsc_sriov_configure(struct pci_dev *pdev, int num_vfs) int ret = 0; if (num_vfs > 0) { - pdsc->vfs = kcalloc(num_vfs, sizeof(struct pdsc_vf), - GFP_KERNEL); + pdsc->vfs = kzalloc_objs(struct pdsc_vf, num_vfs); if (!pdsc->vfs) return -ENOMEM; pdsc->num_vfs = num_vfs; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h index 711f295eb777..80c2c27ac9dc 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h @@ -431,7 +431,7 @@ #define MAC_SSIR_SSINC_INDEX 16 #define MAC_SSIR_SSINC_WIDTH 8 #define MAC_TCR_SS_INDEX 29 -#define MAC_TCR_SS_WIDTH 2 +#define MAC_TCR_SS_WIDTH 3 #define MAC_TCR_TE_INDEX 0 #define MAC_TCR_TE_WIDTH 1 #define MAC_TCR_VNE_INDEX 24 diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c index 62bb4b8a68e1..23beea48ae26 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -1120,7 +1120,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller) { struct xgbe_prv_data *pdata = netdev_priv(netdev); struct xgbe_hw_if *hw_if = &pdata->hw_if; - unsigned long flags; DBGPR("-->xgbe_powerdown\n"); @@ -1131,8 +1130,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller) return -EINVAL; } - spin_lock_irqsave(&pdata->lock, flags); - if (caller == XGMAC_DRIVER_CONTEXT) netif_device_detach(netdev); @@ -1148,8 +1145,6 @@ int xgbe_powerdown(struct net_device *netdev, unsigned int caller) pdata->power_down = 1; - spin_unlock_irqrestore(&pdata->lock, flags); - DBGPR("<--xgbe_powerdown\n"); return 0; @@ -1159,7 +1154,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller) { struct xgbe_prv_data *pdata = netdev_priv(netdev); struct xgbe_hw_if *hw_if = &pdata->hw_if; - unsigned long flags; DBGPR("-->xgbe_powerup\n"); @@ -1170,8 +1164,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller) return -EINVAL; } - spin_lock_irqsave(&pdata->lock, flags); - pdata->power_down = 0; xgbe_napi_enable(pdata, 0); @@ -1186,8 +1178,6 @@ int xgbe_powerup(struct net_device *netdev, unsigned int caller) xgbe_start_timers(pdata); - spin_unlock_irqrestore(&pdata->lock, flags); - DBGPR("<--xgbe_powerup\n"); return 0; @@ -1281,20 +1271,25 @@ static int xgbe_start(struct xgbe_prv_data *pdata) if (ret) goto err_napi; + /* Reset the phy settings */ + ret = xgbe_phy_reset(pdata); + if (ret) + goto err_irqs; + + /* Start the phy */ ret = phy_if->phy_start(pdata); if (ret) goto err_irqs; hw_if->enable_tx(pdata); hw_if->enable_rx(pdata); + /* Synchronize flag with hardware state after enabling TX/RX. + * This prevents stale state after device restart cycles. + */ + pdata->data_path_stopped = false; udp_tunnel_nic_reset_ntf(netdev); - /* Reset the phy settings */ - ret = xgbe_phy_reset(pdata); - if (ret) - goto err_txrx; - netif_tx_start_all_queues(netdev); xgbe_start_timers(pdata); @@ -1304,10 +1299,6 @@ static int xgbe_start(struct xgbe_prv_data *pdata) return 0; -err_txrx: - hw_if->disable_rx(pdata); - hw_if->disable_tx(pdata); - err_irqs: xgbe_free_irqs(pdata); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-main.c b/drivers/net/ethernet/amd/xgbe/xgbe-main.c index d1f0419edb23..7d45ea22a02e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-main.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-main.c @@ -76,7 +76,6 @@ struct xgbe_prv_data *xgbe_alloc_pdata(struct device *dev) pdata->netdev = netdev; pdata->dev = dev; - spin_lock_init(&pdata->lock); spin_lock_init(&pdata->xpcs_lock); mutex_init(&pdata->rss_mutex); spin_lock_init(&pdata->tstamp_lock); diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c index c63ddb12237e..b8cf6ccfe641 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c @@ -1942,7 +1942,7 @@ static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata, static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata) { struct xgbe_phy_data *phy_data = pdata->phy_data; - unsigned int reg; + int reg; /* step 2: force PCS to send RX_ADAPT Req to PHY */ XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, @@ -1964,11 +1964,20 @@ static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata) /* Step 4: Check for Block lock */ - /* Link status is latched low, so read once to clear - * and then read again to get current state + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + if (reg < 0) + goto set_mode; + + /* Link status is latched low so that momentary link drops + * can be detected. If link was already down read again + * to get the latest state. */ - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + if (!pdata->phy.link && !(reg & MDIO_STAT1_LSTATUS)) { + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + if (reg < 0) + goto set_mode; + } + if (reg & MDIO_STAT1_LSTATUS) { /* If the block lock is found, update the helpers * and declare the link up @@ -2008,6 +2017,48 @@ static void xgbe_phy_rx_adaptation(struct xgbe_prv_data *pdata) xgbe_rx_adaptation(pdata); } +/* + * xgbe_phy_stop_data_path - Stop TX/RX to prevent packet corruption + * @pdata: driver private data + * + * This function stops the data path (TX and RX) to prevent packet + * corruption during critical PHY operations like RX adaptation. + * Must be called before initiating RX adaptation when link goes down. + */ +static void xgbe_phy_stop_data_path(struct xgbe_prv_data *pdata) +{ + if (pdata->data_path_stopped) + return; + + /* Stop TX/RX to prevent packet corruption during RX adaptation */ + pdata->hw_if.disable_tx(pdata); + pdata->hw_if.disable_rx(pdata); + pdata->data_path_stopped = true; + + netif_dbg(pdata, link, pdata->netdev, + "stopping data path for RX adaptation\n"); +} + +/* + * xgbe_phy_start_data_path - Re-enable TX/RX after RX adaptation + * @pdata: driver private data + * + * This function re-enables the data path (TX and RX) after RX adaptation + * has completed successfully. Only called when link is confirmed up. + */ +static void xgbe_phy_start_data_path(struct xgbe_prv_data *pdata) +{ + if (!pdata->data_path_stopped) + return; + + pdata->hw_if.enable_rx(pdata); + pdata->hw_if.enable_tx(pdata); + pdata->data_path_stopped = false; + + netif_dbg(pdata, link, pdata->netdev, + "restarting data path after RX adaptation\n"); +} + static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) { int reg; @@ -2801,13 +2852,27 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) if (pdata->en_rx_adap) { /* if the link is available and adaptation is done, * declare link up + * + * Note: When link is up and adaptation is done, we can + * safely re-enable the data path if it was stopped + * for adaptation. */ - if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) + if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) { + xgbe_phy_start_data_path(pdata); return 1; + } /* If either link is not available or adaptation is not done, * retrigger the adaptation logic. (if the mode is not set, * then issue mailbox command first) */ + + /* CRITICAL: Stop data path BEFORE triggering RX adaptation + * to prevent CRC errors from packets corrupted during + * the adaptation process. This is especially important + * when AN is OFF in 10G KR mode. + */ + xgbe_phy_stop_data_path(pdata); + if (pdata->mode_set) { xgbe_phy_rx_adaptation(pdata); } else { @@ -2815,8 +2880,11 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) xgbe_phy_set_mode(pdata, phy_data->cur_mode); } - if (pdata->rx_adapt_done) + if (pdata->rx_adapt_done) { + /* Adaptation complete, safe to re-enable data path */ + xgbe_phy_start_data_path(pdata); return 1; + } } else if (reg & MDIO_STAT1_LSTATUS) return 1; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c index 55e5e467facd..cfdbd4639a1e 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-selftest.c @@ -112,7 +112,7 @@ static int __xgbe_test_loopback(struct xgbe_prv_data *pdata, struct sk_buff *skb = NULL; int ret = 0; - tdata = kzalloc(sizeof(*tdata), GFP_KERNEL); + tdata = kzalloc_obj(*tdata); if (!tdata) return -ENOMEM; diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h index 1269b8ce9249..438033a71523 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe.h +++ b/drivers/net/ethernet/amd/xgbe/xgbe.h @@ -1004,9 +1004,6 @@ struct xgbe_prv_data { unsigned int pp3; unsigned int pp4; - /* Overall device lock */ - spinlock_t lock; - /* XPCS indirect addressing lock */ spinlock_t xpcs_lock; unsigned int xpcs_window_def_reg; @@ -1246,6 +1243,10 @@ struct xgbe_prv_data { bool en_rx_adap; int rx_adapt_retries; bool rx_adapt_done; + /* Flag to track if data path (TX/RX) was stopped for RX adaptation. + * This prevents packet corruption during the adaptation window. + */ + bool data_path_stopped; bool mode_set; bool sph; }; diff --git a/drivers/net/ethernet/apm/xgene-v2/main.c b/drivers/net/ethernet/apm/xgene-v2/main.c index d7ca847d44c7..b51f320149e5 100644 --- a/drivers/net/ethernet/apm/xgene-v2/main.c +++ b/drivers/net/ethernet/apm/xgene-v2/main.c @@ -405,7 +405,7 @@ static struct xge_desc_ring *xge_create_desc_ring(struct net_device *ndev) struct xge_desc_ring *ring; u16 size; - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) return NULL; @@ -417,8 +417,7 @@ static struct xge_desc_ring *xge_create_desc_ring(struct net_device *ndev) if (!ring->desc_addr) goto err; - ring->pkt_info = kcalloc(XGENE_ENET_NUM_DESC, sizeof(*ring->pkt_info), - GFP_KERNEL); + ring->pkt_info = kzalloc_objs(*ring->pkt_info, XGENE_ENET_NUM_DESC); if (!ring->pkt_info) goto err; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c index 30a573db02bb..e419c73b32ce 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -688,7 +688,7 @@ int aq_add_rxnfc_rule(struct aq_nic_s *aq_nic, const struct ethtool_rxnfc *cmd) if (err) goto err_exit; - aq_rx_fltr = kzalloc(sizeof(*aq_rx_fltr), GFP_KERNEL); + aq_rx_fltr = kzalloc_obj(*aq_rx_fltr); if (unlikely(!aq_rx_fltr)) { err = -ENOMEM; goto err_exit; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c index 6afff8af5e86..3ca072360ec7 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_macsec.c @@ -1462,7 +1462,7 @@ int aq_macsec_init(struct aq_nic_s *nic) if (!(caps_lo & BIT(CAPS_LO_MACSEC))) return 0; - nic->macsec_cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + nic->macsec_cfg = kzalloc_obj(*cfg); if (!nic->macsec_cfg) return -ENOMEM; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c index ed5231dece3f..e9e38af680c3 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c @@ -244,7 +244,7 @@ static int aq_pci_probe(struct pci_dev *pdev, if (err) goto err_ioremap; - self->aq_hw = kzalloc(sizeof(*self->aq_hw), GFP_KERNEL); + self->aq_hw = kzalloc_obj(*self->aq_hw); if (!self->aq_hw) { err = -ENOMEM; goto err_ioremap; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c index 0fa0f891c0e0..9df8918216f6 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ptp.c @@ -1130,8 +1130,7 @@ static void aq_ptp_gpio_init(struct ptp_clock_info *info, if (!info->n_pins) return; - info->pin_config = kcalloc(info->n_pins, sizeof(struct ptp_pin_desc), - GFP_KERNEL); + info->pin_config = kzalloc_objs(struct ptp_pin_desc, info->n_pins); if (!info->pin_config) return; @@ -1183,7 +1182,7 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec) aq_ptp_offset_init(&mbox.info.ptp_offset); - aq_ptp = kzalloc(sizeof(*aq_ptp), GFP_KERNEL); + aq_ptp = kzalloc_obj(*aq_ptp); if (!aq_ptp) { err = -ENOMEM; goto err_exit; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index d23d23bed39f..e270327e47fd 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -138,7 +138,7 @@ static int aq_ring_alloc(struct aq_ring_s *self, int err = 0; self->buff_ring = - kcalloc(self->size, sizeof(struct aq_ring_buff_s), GFP_KERNEL); + kzalloc_objs(struct aq_ring_buff_s, self->size); if (!self->buff_ring) { err = -ENOMEM; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c index 9769ab4f9bef..2f9033ceed8c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -104,7 +104,7 @@ struct aq_vec_s *aq_vec_alloc(struct aq_nic_s *aq_nic, unsigned int idx, { struct aq_vec_s *self = NULL; - self = kzalloc(sizeof(*self), GFP_KERNEL); + self = kzalloc_obj(*self); if (!self) goto err_exit; diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index 8283aeee35fb..dde4046cbf01 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c @@ -934,6 +934,17 @@ int arc_emac_probe(struct net_device *ndev, int interface) /* Set poll rate so that it polls every 1 ms */ arc_reg_set(priv, R_POLLRATE, clock_frequency / 1000000); + /* + * Put the device into a known quiescent state before requesting + * the IRQ. Clear only EMAC interrupt status bits here; leave the + * MDIO completion bit alone and avoid writing TXPL_MASK, which is + * used to force TX polling rather than acknowledge interrupts. + */ + arc_reg_set(priv, R_ENABLE, 0); + arc_reg_set(priv, R_STATUS, RXINT_MASK | TXINT_MASK | ERR_MASK | + TXCH_MASK | MSER_MASK | RXCR_MASK | + RXFR_MASK | RXFL_MASK); + ndev->irq = irq; dev_info(dev, "IRQ is %d\n", ndev->irq); diff --git a/drivers/net/ethernet/atheros/ag71xx.c b/drivers/net/ethernet/atheros/ag71xx.c index cbc730c7cff2..a5ab99474179 100644 --- a/drivers/net/ethernet/atheros/ag71xx.c +++ b/drivers/net/ethernet/atheros/ag71xx.c @@ -1305,7 +1305,7 @@ static int ag71xx_rings_init(struct ag71xx *ag) ring_size = BIT(tx->order) + BIT(rx->order); tx_size = BIT(tx->order); - tx->buf = kcalloc(ring_size, sizeof(*tx->buf), GFP_KERNEL); + tx->buf = kzalloc_objs(*tx->buf, ring_size); if (!tx->buf) return -ENOMEM; diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c index ad6d6abd885f..ab262e66f986 100644 --- a/drivers/net/ethernet/atheros/alx/main.c +++ b/drivers/net/ethernet/atheros/alx/main.c @@ -616,7 +616,7 @@ static int alx_set_mac_address(struct net_device *netdev, void *data) static int alx_alloc_tx_ring(struct alx_priv *alx, struct alx_tx_queue *txq, int offset) { - txq->bufs = kcalloc(txq->count, sizeof(struct alx_buffer), GFP_KERNEL); + txq->bufs = kzalloc_objs(struct alx_buffer, txq->count); if (!txq->bufs) return -ENOMEM; @@ -630,7 +630,7 @@ static int alx_alloc_tx_ring(struct alx_priv *alx, struct alx_tx_queue *txq, static int alx_alloc_rx_ring(struct alx_priv *alx, struct alx_rx_queue *rxq, int offset) { - rxq->bufs = kcalloc(rxq->count, sizeof(struct alx_buffer), GFP_KERNEL); + rxq->bufs = kzalloc_objs(struct alx_buffer, rxq->count); if (!rxq->bufs) return -ENOMEM; @@ -746,7 +746,7 @@ static int alx_alloc_napis(struct alx_priv *alx) /* allocate alx_napi structures */ for (i = 0; i < alx->num_napi; i++) { - np = kzalloc(sizeof(struct alx_napi), GFP_KERNEL); + np = kzalloc_obj(struct alx_napi); if (!np) goto err_out; @@ -758,7 +758,7 @@ static int alx_alloc_napis(struct alx_priv *alx) /* allocate tx queues */ for (i = 0; i < alx->num_txq; i++) { np = alx->qnapi[i]; - txq = kzalloc(sizeof(*txq), GFP_KERNEL); + txq = kzalloc_obj(*txq); if (!txq) goto err_out; @@ -775,7 +775,7 @@ static int alx_alloc_napis(struct alx_priv *alx) /* allocate rx queues */ np = alx->qnapi[0]; - rxq = kzalloc(sizeof(*rxq), GFP_KERNEL); + rxq = kzalloc_obj(*rxq); if (!rxq) goto err_out; diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c index d0a480430a95..b368ec2fea43 100644 --- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c +++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c @@ -689,8 +689,7 @@ static int bcmasp_alloc_buffers(struct bcmasp_intf *intf) if (!intf->tx_spb_cpu) goto free_rx_edpkt_dma; - intf->tx_cbs = kcalloc(DESC_RING_COUNT, sizeof(struct bcmasp_tx_cb), - GFP_KERNEL); + intf->tx_cbs = kzalloc_objs(struct bcmasp_tx_cb, DESC_RING_COUNT); if (!intf->tx_cbs) goto free_tx_spb_dma; diff --git a/drivers/net/ethernet/broadcom/bcm4908_enet.c b/drivers/net/ethernet/broadcom/bcm4908_enet.c index 203e8d0dd04b..fd2715f84af9 100644 --- a/drivers/net/ethernet/broadcom/bcm4908_enet.c +++ b/drivers/net/ethernet/broadcom/bcm4908_enet.c @@ -181,7 +181,7 @@ static int bcm4908_dma_alloc_buf_descs(struct bcm4908_enet *enet, goto err_free_buf_descs; } - ring->slots = kcalloc(ring->length, sizeof(*ring->slots), GFP_KERNEL); + ring->slots = kzalloc_objs(*ring->slots, ring->length); if (!ring->slots) goto err_free_buf_descs; diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 92204fea1f08..7ef1babfeca6 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -981,8 +981,7 @@ static int bcm_enet_open(struct net_device *dev) priv->tx_desc_alloc_size = size; priv->tx_desc_cpu = p; - priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *), - GFP_KERNEL); + priv->tx_skb = kzalloc_objs(struct sk_buff *, priv->tx_ring_size); if (!priv->tx_skb) { ret = -ENOMEM; goto out_free_tx_ring; @@ -2149,8 +2148,7 @@ static int bcm_enetsw_open(struct net_device *dev) priv->tx_desc_alloc_size = size; priv->tx_desc_cpu = p; - priv->tx_skb = kcalloc(priv->tx_ring_size, sizeof(struct sk_buff *), - GFP_KERNEL); + priv->tx_skb = kzalloc_objs(struct sk_buff *, priv->tx_ring_size); if (!priv->tx_skb) { dev_err(kdev, "cannot allocate tx skb queue\n"); ret = -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c index bc4e1f3b3752..4d06c6ba6641 100644 --- a/drivers/net/ethernet/broadcom/bcmsysport.c +++ b/drivers/net/ethernet/broadcom/bcmsysport.c @@ -1486,7 +1486,7 @@ static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv, /* Simple descriptors partitioning for now */ size = 256; - ring->cbs = kcalloc(size, sizeof(struct bcm_sysport_cb), GFP_KERNEL); + ring->cbs = kzalloc_objs(struct bcm_sysport_cb, size); if (!ring->cbs) { netif_err(priv, hw, priv->netdev, "CB allocation failed\n"); return -ENOMEM; @@ -1665,8 +1665,7 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv) priv->rx_bds = priv->base + SYS_PORT_RDMA_OFFSET; priv->rx_c_index = 0; priv->rx_read_ptr = 0; - priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct bcm_sysport_cb), - GFP_KERNEL); + priv->rx_cbs = kzalloc_objs(struct bcm_sysport_cb, priv->num_rx_bds); if (!priv->rx_cbs) { netif_err(priv, hw, priv->netdev, "CB allocation failed\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_auxr.c b/drivers/net/ethernet/broadcom/bnge/bnge_auxr.c index 5f4cb4991964..b942076762ef 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_auxr.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_auxr.c @@ -210,7 +210,7 @@ void bnge_rdma_aux_device_init(struct bnge_dev *bd) if (!bnge_is_roce_en(bd)) return; - aux_priv = kzalloc(sizeof(*aux_priv), GFP_KERNEL); + aux_priv = kzalloc_obj(*aux_priv); if (!aux_priv) goto exit; @@ -235,13 +235,13 @@ void bnge_rdma_aux_device_init(struct bnge_dev *bd) } bd->aux_priv = aux_priv; - auxr_dev = kzalloc(sizeof(*auxr_dev), GFP_KERNEL); + auxr_dev = kzalloc_obj(*auxr_dev); if (!auxr_dev) goto aux_dev_uninit; aux_priv->auxr_dev = auxr_dev; - auxr_info = kzalloc(sizeof(*auxr_info), GFP_KERNEL); + auxr_info = kzalloc_obj(*auxr_info); if (!auxr_info) goto aux_dev_uninit; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm.c index c3087e5cd875..80231286d29a 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm.c @@ -229,7 +229,7 @@ bnge_hwrm_create_token(struct bnge_dev *bd, enum bnge_hwrm_chnl dst) { struct bnge_hwrm_wait_token *token; - token = kzalloc(sizeof(*token), GFP_KERNEL); + token = kzalloc_obj(*token); if (!token) return NULL; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c index 84c90a957719..c46da3413417 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c @@ -242,7 +242,7 @@ static int bnge_alloc_all_ctx_pg_info(struct bnge_dev *bd, int ctx_max) if (ctxm->instance_bmap) n = hweight32(ctxm->instance_bmap); - ctxm->pg_info = kcalloc(n, sizeof(*ctxm->pg_info), GFP_KERNEL); + ctxm->pg_info = kzalloc_objs(*ctxm->pg_info, n); if (!ctxm->pg_info) return -ENOMEM; } @@ -269,7 +269,7 @@ int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd) if (rc) return rc; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; bd->ctx = ctx; @@ -442,7 +442,7 @@ __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr) struct hwrm_func_cfg_input *req; u32 enables = 0; - if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG)) + if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_CFG)) return NULL; req->fid = cpu_to_le16(0xffff); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c index 6ab317f1c16e..a20dc3ca640c 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -128,11 +127,11 @@ static void bnge_free_cp_desc_arr(struct bnge_cp_ring_info *cpr) static int bnge_alloc_nq_desc_arr(struct bnge_nq_ring_info *nqr, int n) { - nqr->desc_ring = kcalloc(n, sizeof(*nqr->desc_ring), GFP_KERNEL); + nqr->desc_ring = kzalloc_objs(*nqr->desc_ring, n); if (!nqr->desc_ring) return -ENOMEM; - nqr->desc_mapping = kcalloc(n, sizeof(*nqr->desc_mapping), GFP_KERNEL); + nqr->desc_mapping = kzalloc_objs(*nqr->desc_mapping, n); if (!nqr->desc_mapping) goto err_free_desc_ring; return 0; @@ -145,11 +144,11 @@ static int bnge_alloc_nq_desc_arr(struct bnge_nq_ring_info *nqr, int n) static int bnge_alloc_cp_desc_arr(struct bnge_cp_ring_info *cpr, int n) { - cpr->desc_ring = kcalloc(n, sizeof(*cpr->desc_ring), GFP_KERNEL); + cpr->desc_ring = kzalloc_objs(*cpr->desc_ring, n); if (!cpr->desc_ring) return -ENOMEM; - cpr->desc_mapping = kcalloc(n, sizeof(*cpr->desc_mapping), GFP_KERNEL); + cpr->desc_mapping = kzalloc_objs(*cpr->desc_mapping, n); if (!cpr->desc_mapping) goto err_free_desc_ring; return 0; @@ -288,8 +287,7 @@ static int bnge_alloc_nq_tree(struct bnge_net *bn) tx = 1; } - nqr->cp_ring_arr = kcalloc(cp_count, sizeof(*cpr), - GFP_KERNEL); + nqr->cp_ring_arr = kzalloc_objs(*cpr, cp_count); if (!nqr->cp_ring_arr) { rc = -ENOMEM; goto err_free_nq_tree; @@ -511,21 +509,19 @@ static int bnge_alloc_tpa_info(struct bnge_net *bn) for (i = 0; i < bd->rx_nr_rings; i++) { struct bnge_rx_ring_info *rxr = &bn->rx_ring[i]; - rxr->rx_tpa = kcalloc(bn->max_tpa, sizeof(struct bnge_tpa_info), - GFP_KERNEL); + rxr->rx_tpa = kzalloc_objs(struct bnge_tpa_info, bn->max_tpa); if (!rxr->rx_tpa) goto err_free_tpa_info; for (j = 0; j < bn->max_tpa; j++) { struct rx_agg_cmp *agg; - agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); + agg = kzalloc_objs(*agg, MAX_SKB_FRAGS); if (!agg) goto err_free_tpa_info; rxr->rx_tpa[j].agg_arr = agg; } - rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), - GFP_KERNEL); + rxr->rx_tpa_idx_map = kzalloc_obj(*rxr->rx_tpa_idx_map); if (!rxr->rx_tpa_idx_map) goto err_free_tpa_info; } @@ -814,8 +810,7 @@ static int bnge_alloc_vnics(struct bnge_net *bn) */ num_vnics = 1; - bn->vnic_info = kcalloc(num_vnics, sizeof(struct bnge_vnic_info), - GFP_KERNEL); + bn->vnic_info = kzalloc_objs(struct bnge_vnic_info, num_vnics); if (!bn->vnic_info) return -ENOMEM; @@ -842,9 +837,7 @@ static int bnge_init_ring_grps(struct bnge_net *bn) struct bnge_dev *bd = bn->bd; int i; - bn->grp_info = kcalloc(bd->nq_nr_rings, - sizeof(struct bnge_ring_grp_info), - GFP_KERNEL); + bn->grp_info = kzalloc_objs(struct bnge_ring_grp_info, bd->nq_nr_rings); if (!bn->grp_info) return -ENOMEM; for (i = 0; i < bd->nq_nr_rings; i++) { @@ -904,9 +897,7 @@ static int bnge_alloc_core(struct bnge_net *bn) nqr->ring_struct.ring_mem.flags = BNGE_RMEM_RING_PTE_FLAG; } - bn->rx_ring = kcalloc(bd->rx_nr_rings, - sizeof(struct bnge_rx_ring_info), - GFP_KERNEL); + bn->rx_ring = kzalloc_objs(struct bnge_rx_ring_info, bd->rx_nr_rings); if (!bn->rx_ring) goto err_free_core; @@ -921,9 +912,7 @@ static int bnge_alloc_core(struct bnge_net *bn) bn->bnapi[i]->rx_ring = &bn->rx_ring[i]; } - bn->tx_ring = kcalloc(bd->tx_nr_rings, - sizeof(struct bnge_tx_ring_info), - GFP_KERNEL); + bn->tx_ring = kzalloc_objs(struct bnge_tx_ring_info, bd->tx_nr_rings); if (!bn->tx_ring) goto err_free_core; @@ -1779,7 +1768,7 @@ static struct bnge_l2_filter *bnge_alloc_l2_filter(struct bnge_net *bn, if (fltr) return fltr; - fltr = kzalloc(sizeof(*fltr), gfp); + fltr = kzalloc_obj(*fltr, gfp); if (!fltr) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c index 943df5f60f01..0e94f092813e 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_resc.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_resc.c @@ -389,7 +389,7 @@ int bnge_alloc_irqs(struct bnge_dev *bd) num_entries = irqs_demand; if (pci_msix_can_alloc_dyn(bd->pdev)) num_entries = max; - bd->irq_tbl = kcalloc(num_entries, sizeof(*bd->irq_tbl), GFP_KERNEL); + bd->irq_tbl = kzalloc_objs(*bd->irq_tbl, num_entries); if (!bd->irq_tbl) { rc = -ENOMEM; goto err_free_irqs; diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_rmem.c b/drivers/net/ethernet/broadcom/bnge/bnge_rmem.c index ee97be440c33..94f15e08a88c 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_rmem.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_rmem.c @@ -158,8 +158,7 @@ static int bnge_alloc_ctx_pg_tbls(struct bnge_dev *bd, int nr_tbls, i; rmem->depth = 2; - ctx_pg->ctx_pg_tbl = kcalloc(MAX_CTX_PAGES, sizeof(ctx_pg), - GFP_KERNEL); + ctx_pg->ctx_pg_tbl = kzalloc_objs(ctx_pg, MAX_CTX_PAGES); if (!ctx_pg->ctx_pg_tbl) return -ENOMEM; nr_tbls = DIV_ROUND_UP(ctx_pg->nr_pages, MAX_CTX_PAGES); @@ -170,7 +169,7 @@ static int bnge_alloc_ctx_pg_tbls(struct bnge_dev *bd, for (i = 0; i < nr_tbls; i++) { struct bnge_ctx_pg_info *pg_tbl; - pg_tbl = kzalloc(sizeof(*pg_tbl), GFP_KERNEL); + pg_tbl = kzalloc_obj(*pg_tbl); if (!pg_tbl) return -ENOMEM; ctx_pg->ctx_pg_tbl[i] = pg_tbl; diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 805daae9dd36..f5722e929833 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -8084,7 +8084,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->phy_flags = 0; bp->temp_stats_blk = - kzalloc(sizeof(struct statistics_block), GFP_KERNEL); + kzalloc_obj(struct statistics_block); if (!bp->temp_stats_blk) { rc = -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index e59530357e2c..19e078479b0d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -4582,9 +4582,8 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) "allocating tx memory of fp %d cos %d\n", index, cos); - txdata->tx_buf_ring = kcalloc(NUM_TX_BD, - sizeof(struct sw_tx_bd), - GFP_KERNEL); + txdata->tx_buf_ring = kzalloc_objs(struct sw_tx_bd, + NUM_TX_BD); if (!txdata->tx_buf_ring) goto alloc_mem_err; txdata->tx_desc_ring = BNX2X_PCI_ALLOC(&txdata->tx_desc_mapping, @@ -4598,7 +4597,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) if (!skip_rx_queue(bp, index)) { /* fastpath rx rings: rx_buf rx_desc rx_comp */ bnx2x_fp(bp, index, rx_buf_ring) = - kcalloc(NUM_RX_BD, sizeof(struct sw_rx_bd), GFP_KERNEL); + kzalloc_objs(struct sw_rx_bd, NUM_RX_BD); if (!bnx2x_fp(bp, index, rx_buf_ring)) goto alloc_mem_err; bnx2x_fp(bp, index, rx_desc_ring) = @@ -4616,8 +4615,7 @@ static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index) /* SGE ring */ bnx2x_fp(bp, index, rx_page_ring) = - kcalloc(NUM_RX_SGE, sizeof(struct sw_rx_page), - GFP_KERNEL); + kzalloc_objs(struct sw_rx_page, NUM_RX_SGE); if (!bnx2x_fp(bp, index, rx_page_ring)) goto alloc_mem_err; bnx2x_fp(bp, index, rx_sge_ring) = @@ -4747,13 +4745,13 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp) bp->fp_array_size = fp_array_size; BNX2X_DEV_INFO("fp_array_size %d\n", bp->fp_array_size); - fp = kcalloc(bp->fp_array_size, sizeof(*fp), GFP_KERNEL); + fp = kzalloc_objs(*fp, bp->fp_array_size); if (!fp) goto alloc_err; for (i = 0; i < bp->fp_array_size; i++) { fp[i].tpa_info = - kcalloc(ETH_MAX_AGGREGATION_QUEUES_E1H_E2, - sizeof(struct bnx2x_agg_info), GFP_KERNEL); + kzalloc_objs(struct bnx2x_agg_info, + ETH_MAX_AGGREGATION_QUEUES_E1H_E2); if (!(fp[i].tpa_info)) goto alloc_err; } @@ -4761,14 +4759,12 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp) bp->fp = fp; /* allocate sp objs */ - bp->sp_objs = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_sp_objs), - GFP_KERNEL); + bp->sp_objs = kzalloc_objs(struct bnx2x_sp_objs, bp->fp_array_size); if (!bp->sp_objs) goto alloc_err; /* allocate fp_stats */ - bp->fp_stats = kcalloc(bp->fp_array_size, sizeof(struct bnx2x_fp_stats), - GFP_KERNEL); + bp->fp_stats = kzalloc_objs(struct bnx2x_fp_stats, bp->fp_array_size); if (!bp->fp_stats) goto alloc_err; @@ -4777,19 +4773,18 @@ int bnx2x_alloc_mem_bp(struct bnx2x *bp) BNX2X_MAX_RSS_COUNT(bp) * BNX2X_MULTI_TX_COS + CNIC_SUPPORT(bp); BNX2X_DEV_INFO("txq_array_size %d", txq_array_size); - bp->bnx2x_txq = kcalloc(txq_array_size, sizeof(struct bnx2x_fp_txdata), - GFP_KERNEL); + bp->bnx2x_txq = kzalloc_objs(struct bnx2x_fp_txdata, txq_array_size); if (!bp->bnx2x_txq) goto alloc_err; /* msix table */ - tbl = kcalloc(msix_table_size, sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_objs(*tbl, msix_table_size); if (!tbl) goto alloc_err; bp->msix_table = tbl; /* ilt */ - ilt = kzalloc(sizeof(*ilt), GFP_KERNEL); + ilt = kzalloc_obj(*ilt); if (!ilt) goto alloc_err; bp->ilt = ilt; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 6a1cc2032bf3..da0f8c353e6a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -6577,7 +6577,7 @@ static int bnx2x_gunzip_init(struct bnx2x *bp) if (bp->gunzip_buf == NULL) goto gunzip_nomem1; - bp->strm = kmalloc(sizeof(*bp->strm), GFP_KERNEL); + bp->strm = kmalloc_obj(*bp->strm); if (bp->strm == NULL) goto gunzip_nomem2; @@ -8396,8 +8396,7 @@ int bnx2x_alloc_mem(struct bnx2x *bp) goto alloc_mem_err; allocated += bp->context[i].size; } - bp->ilt->lines = kcalloc(ILT_MAX_LINES, sizeof(struct ilt_line), - GFP_KERNEL); + bp->ilt->lines = kzalloc_objs(struct ilt_line, ILT_MAX_LINES); if (!bp->ilt->lines) goto alloc_mem_err; @@ -10660,7 +10659,7 @@ static int bnx2x_prev_mark_path(struct bnx2x *bp, bool after_undi) up(&bnx2x_prev_sem); /* Create an entry for this path and add it */ - tmp_list = kmalloc(sizeof(struct bnx2x_prev_path_list), GFP_KERNEL); + tmp_list = kmalloc_obj(struct bnx2x_prev_path_list); if (!tmp_list) { BNX2X_ERR("Failed to allocate 'bnx2x_prev_path_list'\n"); return -ENOMEM; @@ -12954,7 +12953,7 @@ static int bnx2x_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) DP(NETIF_MSG_IFUP, "Adding VLAN %d\n", vid); - vlan = kmalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kmalloc_obj(*vlan); if (!vlan) return -ENOMEM; @@ -14841,7 +14840,7 @@ static int bnx2x_get_fc_npiv(struct net_device *dev, DP(BNX2X_MSG_MCP, "About to read the FC-NPIV table\n"); - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kmalloc_obj(*tbl); if (!tbl) { BNX2X_ERR("Failed to allocate fc_npiv table\n"); goto out; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 02c8213915a5..07a908a2c72f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -251,7 +251,7 @@ static inline struct bnx2x_exeq_elem *bnx2x_exe_queue_alloc_elem( struct bnx2x *bp) { DP(BNX2X_MSG_SP, "Allocating a new exe_queue element\n"); - return kzalloc(sizeof(struct bnx2x_exeq_elem), GFP_ATOMIC); + return kzalloc_obj(struct bnx2x_exeq_elem, GFP_ATOMIC); } /************************ raw_obj functions ***********************************/ @@ -1736,7 +1736,7 @@ static inline int bnx2x_vlan_mac_get_registry_elem( /* Allocate a new registry element if needed. */ if (!restore && ((cmd == BNX2X_VLAN_MAC_ADD) || (cmd == BNX2X_VLAN_MAC_MOVE))) { - reg_elem = kzalloc(sizeof(*reg_elem), GFP_ATOMIC); + reg_elem = kzalloc_obj(*reg_elem, GFP_ATOMIC); if (!reg_elem) return -ENOMEM; @@ -2688,7 +2688,7 @@ static int bnx2x_mcast_enqueue_cmd(struct bnx2x *bp, return 0; /* Add mcast is called under spin_lock, thus calling with GFP_ATOMIC */ - new_cmd = kzalloc(sizeof(*new_cmd), GFP_ATOMIC); + new_cmd = kzalloc_obj(*new_cmd, GFP_ATOMIC); if (!new_cmd) return -ENOMEM; @@ -3846,7 +3846,7 @@ static inline int bnx2x_mcast_refresh_registry_e1(struct bnx2x *bp, if (!list_empty(&o->registry.exact_match.macs)) return 0; - elem = kcalloc(len, sizeof(*elem), GFP_ATOMIC); + elem = kzalloc_objs(*elem, len, GFP_ATOMIC); if (!elem) { BNX2X_ERR("Failed to allocate registry memory\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 12198fc3ab22..b8af508f9c98 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c @@ -551,8 +551,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, else set_bit(RAMROD_COMP_WAIT, &mcast.ramrod_flags); if (mc_num) { - mc = kcalloc(mc_num, sizeof(struct bnx2x_mcast_list_elem), - GFP_KERNEL); + mc = kzalloc_objs(struct bnx2x_mcast_list_elem, mc_num); if (!mc) { BNX2X_ERR("Cannot Configure multicasts due to lack of memory\n"); return -ENOMEM; @@ -1218,7 +1217,7 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, } /* allocate the vfs database */ - bp->vfdb = kzalloc(sizeof(*(bp->vfdb)), GFP_KERNEL); + bp->vfdb = kzalloc_obj(*(bp->vfdb)); if (!bp->vfdb) { BNX2X_ERR("failed to allocate vf database\n"); err = -ENOMEM; @@ -1247,9 +1246,7 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, num_vfs_param, iov->nr_virtfn); /* allocate the vf array */ - bp->vfdb->vfs = kcalloc(BNX2X_NR_VIRTFN(bp), - sizeof(struct bnx2x_virtf), - GFP_KERNEL); + bp->vfdb->vfs = kzalloc_objs(struct bnx2x_virtf, BNX2X_NR_VIRTFN(bp)); if (!bp->vfdb->vfs) { BNX2X_ERR("failed to allocate vf array\n"); err = -ENOMEM; @@ -1275,9 +1272,8 @@ int bnx2x_iov_init_one(struct bnx2x *bp, int int_mode_param, } /* allocate the queue arrays for all VFs */ - bp->vfdb->vfqs = kcalloc(BNX2X_MAX_NUM_VF_QUEUES, - sizeof(struct bnx2x_vf_queue), - GFP_KERNEL); + bp->vfdb->vfqs = kzalloc_objs(struct bnx2x_vf_queue, + BNX2X_MAX_NUM_VF_QUEUES); if (!bp->vfdb->vfqs) { BNX2X_ERR("failed to allocate vf queue array\n"); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 8946a931e87e..f13dfceb065c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c @@ -1654,8 +1654,7 @@ static int bnx2x_vf_mbx_macvlan_list(struct bnx2x *bp, int i, j; struct bnx2x_vf_mac_vlan_filters *fl = NULL; - fl = kzalloc(struct_size(fl, filters, tlv->n_mac_vlan_filters), - GFP_KERNEL); + fl = kzalloc_flex(*fl, filters, tlv->n_mac_vlan_filters); if (!fl) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index fb45e1dd1dd7..c426a41c3663 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -3752,21 +3752,19 @@ static int bnxt_alloc_one_tpa_info(struct bnxt *bp, struct rx_agg_cmp *agg; int i; - rxr->rx_tpa = kcalloc(bp->max_tpa, sizeof(struct bnxt_tpa_info), - GFP_KERNEL); + rxr->rx_tpa = kzalloc_objs(struct bnxt_tpa_info, bp->max_tpa); if (!rxr->rx_tpa) return -ENOMEM; if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS)) return 0; for (i = 0; i < bp->max_tpa; i++) { - agg = kcalloc(MAX_SKB_FRAGS, sizeof(*agg), GFP_KERNEL); + agg = kzalloc_objs(*agg, MAX_SKB_FRAGS); if (!agg) return -ENOMEM; rxr->rx_tpa[i].agg_arr = agg; } - rxr->rx_tpa_idx_map = kzalloc(sizeof(*rxr->rx_tpa_idx_map), - GFP_KERNEL); + rxr->rx_tpa_idx_map = kzalloc_obj(*rxr->rx_tpa_idx_map); if (!rxr->rx_tpa_idx_map) return -ENOMEM; @@ -4081,11 +4079,10 @@ static void bnxt_free_cp_arrays(struct bnxt_cp_ring_info *cpr) static int bnxt_alloc_cp_arrays(struct bnxt_cp_ring_info *cpr, int n) { - cpr->cp_desc_ring = kcalloc(n, sizeof(*cpr->cp_desc_ring), GFP_KERNEL); + cpr->cp_desc_ring = kzalloc_objs(*cpr->cp_desc_ring, n); if (!cpr->cp_desc_ring) return -ENOMEM; - cpr->cp_desc_mapping = kcalloc(n, sizeof(*cpr->cp_desc_mapping), - GFP_KERNEL); + cpr->cp_desc_mapping = kzalloc_objs(*cpr->cp_desc_mapping, n); if (!cpr->cp_desc_mapping) return -ENOMEM; return 0; @@ -4232,8 +4229,7 @@ static int bnxt_alloc_cp_rings(struct bnxt *bp) tx = 1; } - cpr->cp_ring_arr = kcalloc(cp_count, sizeof(*cpr), - GFP_KERNEL); + cpr->cp_ring_arr = kzalloc_objs(*cpr, cp_count); if (!cpr->cp_ring_arr) return -ENOMEM; cpr->cp_ring_count = cp_count; @@ -4627,9 +4623,8 @@ static int bnxt_init_ring_grps(struct bnxt *bp, bool irq_re_init) int i; if (irq_re_init) { - bp->grp_info = kcalloc(bp->cp_nr_rings, - sizeof(struct bnxt_ring_grp_info), - GFP_KERNEL); + bp->grp_info = kzalloc_objs(struct bnxt_ring_grp_info, + bp->cp_nr_rings); if (!bp->grp_info) return -ENOMEM; } @@ -4667,8 +4662,7 @@ static int bnxt_alloc_vnics(struct bnxt *bp) if (BNXT_CHIP_TYPE_NITRO_A0(bp)) num_vnics++; - bp->vnic_info = kcalloc(num_vnics, sizeof(struct bnxt_vnic_info), - GFP_KERNEL); + bp->vnic_info = kzalloc_objs(struct bnxt_vnic_info, num_vnics); if (!bp->vnic_info) return -ENOMEM; @@ -5248,7 +5242,7 @@ static int bnxt_alloc_stats(struct bnxt *bp) struct bnxt_napi *bnapi = bp->bnapi[i]; struct bnxt_cp_ring_info *cpr = &bnapi->cp_ring; - cpr->sw_stats = kzalloc(sizeof(*cpr->sw_stats), GFP_KERNEL); + cpr->sw_stats = kzalloc_obj(*cpr->sw_stats); if (!cpr->sw_stats) return -ENOMEM; @@ -5516,9 +5510,8 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init) } } - bp->rx_ring = kcalloc(bp->rx_nr_rings, - sizeof(struct bnxt_rx_ring_info), - GFP_KERNEL); + bp->rx_ring = kzalloc_objs(struct bnxt_rx_ring_info, + bp->rx_nr_rings); if (!bp->rx_ring) return -ENOMEM; @@ -5537,9 +5530,8 @@ static int bnxt_alloc_mem(struct bnxt *bp, bool irq_re_init) bp->bnapi[i]->rx_ring = &bp->rx_ring[i]; } - bp->tx_ring = kcalloc(bp->tx_nr_rings, - sizeof(struct bnxt_tx_ring_info), - GFP_KERNEL); + bp->tx_ring = kzalloc_objs(struct bnxt_tx_ring_info, + bp->tx_nr_rings); if (!bp->tx_ring) return -ENOMEM; @@ -6096,7 +6088,7 @@ static struct bnxt_l2_filter *bnxt_alloc_l2_filter(struct bnxt *bp, if (fltr) return fltr; - fltr = kzalloc(sizeof(*fltr), gfp); + fltr = kzalloc_obj(*fltr, gfp); if (!fltr) return ERR_PTR(-ENOMEM); spin_lock_bh(&bp->ntp_fltr_lock); @@ -6125,7 +6117,7 @@ struct bnxt_l2_filter *bnxt_alloc_new_l2_filter(struct bnxt *bp, fltr = ERR_PTR(-EEXIST); goto l2_filter_exit; } - fltr = kzalloc(sizeof(*fltr), GFP_ATOMIC); + fltr = kzalloc_obj(*fltr, GFP_ATOMIC); if (!fltr) { fltr = ERR_PTR(-ENOMEM); goto l2_filter_exit; @@ -6240,6 +6232,9 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, int rc; set_bit(BNXT_FLTR_FW_DELETED, &fltr->base.state); + if (!test_bit(BNXT_STATE_OPEN, &bp->state)) + return 0; + rc = hwrm_req_init(bp, req, HWRM_CFA_NTUPLE_FILTER_FREE); if (rc) return rc; @@ -8655,7 +8650,7 @@ static int bnxt_alloc_all_ctx_pg_info(struct bnxt *bp, int ctx_max) if (ctxm->instance_bmap) n = hweight32(ctxm->instance_bmap); - ctxm->pg_info = kcalloc(n, sizeof(*ctxm->pg_info), GFP_KERNEL); + ctxm->pg_info = kzalloc_objs(*ctxm->pg_info, n); if (!ctxm->pg_info) return -ENOMEM; } @@ -8682,7 +8677,7 @@ static int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp) return rc; if (!ctx) { - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; bp->ctx = ctx; @@ -8769,7 +8764,7 @@ static int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) ctx = bp->ctx; if (!ctx) { - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto ctx_err; @@ -9048,8 +9043,7 @@ static int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp, int nr_tbls, i; rmem->depth = 2; - ctx_pg->ctx_pg_tbl = kcalloc(MAX_CTX_PAGES, sizeof(ctx_pg), - GFP_KERNEL); + ctx_pg->ctx_pg_tbl = kzalloc_objs(ctx_pg, MAX_CTX_PAGES); if (!ctx_pg->ctx_pg_tbl) return -ENOMEM; nr_tbls = DIV_ROUND_UP(ctx_pg->nr_pages, MAX_CTX_PAGES); @@ -9060,7 +9054,7 @@ static int bnxt_alloc_ctx_pg_tbls(struct bnxt *bp, for (i = 0; i < nr_tbls; i++) { struct bnxt_ctx_pg_info *pg_tbl; - pg_tbl = kzalloc(sizeof(*pg_tbl), GFP_KERNEL); + pg_tbl = kzalloc_obj(*pg_tbl); if (!pg_tbl) return -ENOMEM; ctx_pg->ctx_pg_tbl[i] = pg_tbl; @@ -9569,8 +9563,7 @@ static int bnxt_alloc_crash_dump_mem(struct bnxt *bp) if (bp->fw_crash_mem) bnxt_free_ctx_pg_tbls(bp, bp->fw_crash_mem); else - bp->fw_crash_mem = kzalloc(sizeof(*bp->fw_crash_mem), - GFP_KERNEL); + bp->fw_crash_mem = kzalloc_obj(*bp->fw_crash_mem); if (!bp->fw_crash_mem) return -ENOMEM; @@ -9677,7 +9670,7 @@ static int __bnxt_hwrm_ptp_qcfg(struct bnxt *bp) goto exit; } if (!ptp) { - ptp = kzalloc(sizeof(*ptp), GFP_KERNEL); + ptp = kzalloc_obj(*ptp); if (!ptp) { rc = -ENOMEM; goto exit; @@ -9949,7 +9942,7 @@ static int __bnxt_alloc_fw_health(struct bnxt *bp) if (bp->fw_health) return 0; - bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL); + bp->fw_health = kzalloc_obj(*bp->fw_health); if (!bp->fw_health) return -ENOMEM; @@ -10889,12 +10882,10 @@ void bnxt_del_one_rss_ctx(struct bnxt *bp, struct bnxt_rss_ctx *rss_ctx, struct bnxt_ntuple_filter *ntp_fltr; int i; - if (netif_running(bp->dev)) { - bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic); - for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) { - if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID) - bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i); - } + bnxt_hwrm_vnic_free_one(bp, &rss_ctx->vnic); + for (i = 0; i < BNXT_MAX_CTX_PER_VNIC; i++) { + if (vnic->fw_rss_cos_lb_ctx[i] != INVALID_HW_RING_ID) + bnxt_hwrm_vnic_ctx_free_one(bp, vnic, i); } if (!all) return; @@ -11460,7 +11451,7 @@ static int bnxt_init_int_mode(struct bnxt *bp) tbl_size = total_vecs; if (pci_msix_can_alloc_dyn(bp->pdev)) tbl_size = max; - bp->irq_tbl = kcalloc(tbl_size, sizeof(*bp->irq_tbl), GFP_KERNEL); + bp->irq_tbl = kzalloc_objs(*bp->irq_tbl, tbl_size); if (bp->irq_tbl) { for (i = 0; i < total_vecs; i++) bp->irq_tbl[i].vector = pci_irq_vector(bp->pdev, i); @@ -12957,7 +12948,7 @@ static int bnxt_set_xps_mapping(struct bnxt *bp) cpumask_t *q_map; int rc = 0; - q_map = kcalloc(bp->tx_nr_rings_per_tc, sizeof(*q_map), GFP_KERNEL); + q_map = kzalloc_objs(*q_map, bp->tx_nr_rings_per_tc); if (!q_map) return -ENOMEM; @@ -15650,7 +15641,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, return -EINVAL; } } - new_fltr = kzalloc(sizeof(*new_fltr), GFP_ATOMIC); + new_fltr = kzalloc_obj(*new_fltr, GFP_ATOMIC); if (!new_fltr) { bnxt_del_l2_filter(bp, l2_fltr); return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c index a00b67334f9b..1ad2143d0e56 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c @@ -529,7 +529,7 @@ static int bnxt_dcbnl_ieee_getets(struct net_device *dev, struct ieee_ets *ets) if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) return 0; - my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); + my_ets = kzalloc_obj(*my_ets); if (!my_ets) return -ENOMEM; rc = bnxt_hwrm_queue_cos2bw_qcfg(bp, my_ets); @@ -568,7 +568,7 @@ static int bnxt_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets) rc = bnxt_ets_validate(bp, ets, &max_tc); if (!rc) { if (!my_ets) { - my_ets = kzalloc(sizeof(*my_ets), GFP_KERNEL); + my_ets = kzalloc_obj(*my_ets); if (!my_ets) return -ENOMEM; /* initialize PRI2TC mappings to invalid value */ @@ -604,7 +604,7 @@ static int bnxt_dcbnl_ieee_getpfc(struct net_device *dev, struct ieee_pfc *pfc) if (bp->dcbx_cap & DCB_CAP_DCBX_HOST) return 0; - my_pfc = kzalloc(sizeof(*my_pfc), GFP_KERNEL); + my_pfc = kzalloc_obj(*my_pfc); if (!my_pfc) return 0; bp->ieee_pfc = my_pfc; @@ -642,7 +642,7 @@ static int bnxt_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) return -EINVAL; if (!my_pfc) { - my_pfc = kzalloc(sizeof(*my_pfc), GFP_KERNEL); + my_pfc = kzalloc_obj(*my_pfc); if (!my_pfc) return -ENOMEM; bp->ieee_pfc = my_pfc; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 53a83b6680c4..28d0ece2e7b1 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -979,8 +979,8 @@ static int bnxt_set_channels(struct net_device *dev, if (bnxt_get_nr_rss_ctxs(bp, req_rx_rings) != bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings) && - netif_is_rxfh_configured(dev)) { - netdev_warn(dev, "RSS table size change required, RSS table entries must be default to proceed\n"); + (netif_is_rxfh_configured(dev) || bp->num_rss_ctx)) { + netdev_warn(dev, "RSS table size change required, RSS table entries must be default (with no additional RSS contexts present) to proceed\n"); return -EINVAL; } @@ -1371,7 +1371,7 @@ static int bnxt_add_ntuple_cls_rule(struct bnxt *bp, return -EOPNOTSUPP; } - new_fltr = kzalloc(sizeof(*new_fltr), GFP_KERNEL); + new_fltr = kzalloc_obj(*new_fltr); if (!new_fltr) return -ENOMEM; @@ -5485,7 +5485,7 @@ void bnxt_ethtool_init(struct bnxt *bp) test_info = bp->test_info; if (!test_info) { - test_info = kzalloc(sizeof(*bp->test_info), GFP_KERNEL); + test_info = kzalloc_obj(*bp->test_info); if (!test_info) return; bp->test_info = test_info; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c index 5ce190f50120..5bfabdca7d0e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c @@ -371,7 +371,7 @@ __hwrm_acquire_token(struct bnxt *bp, enum bnxt_hwrm_chnl dst) { struct bnxt_hwrm_wait_token *token; - token = kzalloc(sizeof(*token), GFP_KERNEL); + token = kzalloc_obj(*token); if (!token) return NULL; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index ad89c5fa9b40..53f336db4fcc 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -983,9 +983,8 @@ static int bnxt_ptp_pps_init(struct bnxt *bp) pps_info = &ptp->pps_info; pps_info->num_pins = resp->num_pins; ptp_info->n_pins = pps_info->num_pins; - ptp_info->pin_config = kcalloc(ptp_info->n_pins, - sizeof(*ptp_info->pin_config), - GFP_KERNEL); + ptp_info->pin_config = kzalloc_objs(*ptp_info->pin_config, + ptp_info->n_pins); if (!ptp_info->pin_config) { hwrm_req_drop(bp, req); return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index be7deb9cc410..7f9829287c49 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -459,7 +459,7 @@ static int bnxt_alloc_vf_resources(struct bnxt *bp, int num_vfs) struct pci_dev *pdev = bp->pdev; u32 nr_pages, size, i, j, k = 0; - bp->pf.vf = kcalloc(num_vfs, sizeof(struct bnxt_vf_info), GFP_KERNEL); + bp->pf.vf = kzalloc_objs(struct bnxt_vf_info, num_vfs); if (!bp->pf.vf) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c index 2d66bf59cd64..c6b4a14c0e6e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c @@ -977,7 +977,7 @@ bnxt_tc_get_l2_node(struct bnxt *bp, struct rhashtable *l2_table, l2_node = rhashtable_lookup_fast(l2_table, l2_key, ht_params); if (!l2_node) { - l2_node = kzalloc(sizeof(*l2_node), GFP_KERNEL); + l2_node = kzalloc_obj(*l2_node); if (!l2_node) { rc = -ENOMEM; return NULL; @@ -1128,7 +1128,7 @@ bnxt_tc_get_tunnel_node(struct bnxt *bp, struct rhashtable *tunnel_table, tunnel_node = rhashtable_lookup_fast(tunnel_table, tun_key, *ht_params); if (!tunnel_node) { - tunnel_node = kzalloc(sizeof(*tunnel_node), GFP_KERNEL); + tunnel_node = kzalloc_obj(*tunnel_node); if (!tunnel_node) { rc = -ENOMEM; goto err; @@ -1535,7 +1535,7 @@ static int bnxt_tc_add_flow(struct bnxt *bp, u16 src_fid, int rc; /* allocate memory for the new flow and it's node */ - new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); + new_node = kzalloc_obj(*new_node); if (!new_node) { rc = -ENOMEM; goto done; @@ -1915,7 +1915,7 @@ static int bnxt_tc_setup_indr_block(struct net_device *netdev, struct Qdisc *sch switch (f->command) { case FLOW_BLOCK_BIND: - cb_priv = kmalloc(sizeof(*cb_priv), GFP_KERNEL); + cb_priv = kmalloc_obj(*cb_priv); if (!cb_priv) return -ENOMEM; @@ -2018,7 +2018,7 @@ int bnxt_init_tc(struct bnxt *bp) if (bp->hwrm_spec_code < 0x10803) return 0; - tc_info = kzalloc(sizeof(*tc_info), GFP_KERNEL); + tc_info = kzalloc_obj(*tc_info); if (!tc_info) return -ENOMEM; mutex_init(&tc_info->lock); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index 927971c362f1..e1e82a72cf1b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -333,8 +333,7 @@ void bnxt_ulp_irq_restart(struct bnxt *bp, int err) return; if (!err) { - ent = kcalloc(ulp->msix_requested, sizeof(*ent), - GFP_KERNEL); + ent = kzalloc_objs(*ent, ulp->msix_requested); if (!ent) return; bnxt_fill_msix_vecs(bp, ent); @@ -479,7 +478,7 @@ void bnxt_rdma_aux_device_init(struct bnxt *bp) if (!(bp->flags & BNXT_FLAG_ROCE_CAP)) return; - aux_priv = kzalloc(sizeof(*bp->aux_priv), GFP_KERNEL); + aux_priv = kzalloc_obj(*bp->aux_priv); if (!aux_priv) goto exit; @@ -509,13 +508,13 @@ void bnxt_rdma_aux_device_init(struct bnxt *bp) * any error unwinding will need to include a call to * auxiliary_device_uninit. */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = kzalloc_obj(*edev); if (!edev) goto aux_dev_uninit; aux_priv->edev = edev; - ulp = kzalloc(sizeof(*ulp), GFP_KERNEL); + ulp = kzalloc_obj(*ulp); if (!ulp) goto aux_dev_uninit; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c index bd116fd578d8..18e33144f345 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_vfr.c @@ -496,7 +496,7 @@ int bnxt_vf_reps_create(struct bnxt *bp) if (!(bp->flags & BNXT_FLAG_DSN_VALID)) return -ENODEV; - bp->vf_reps = kcalloc(num_vfs, sizeof(vf_rep), GFP_KERNEL); + bp->vf_reps = kzalloc_objs(vf_rep, num_vfs); if (!bp->vf_reps) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index 6e97a5a7daaf..51addf829188 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -1062,7 +1062,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) } } - udev = kzalloc(sizeof(struct cnic_uio_dev), GFP_ATOMIC); + udev = kzalloc_obj(struct cnic_uio_dev, GFP_ATOMIC); if (!udev) return -ENOMEM; @@ -1208,7 +1208,7 @@ static int cnic_alloc_bnx2x_context(struct cnic_dev *dev) if (blks > cp->ethdev->ctx_tbl_len) return -ENOMEM; - cp->ctx_arr = kcalloc(blks, sizeof(struct cnic_ctx), GFP_KERNEL); + cp->ctx_arr = kzalloc_objs(struct cnic_ctx, blks); if (cp->ctx_arr == NULL) return -ENOMEM; @@ -1261,13 +1261,11 @@ static int cnic_alloc_bnx2x_resc(struct cnic_dev *dev) cp->fcoe_init_cid = 0x10; } - cp->iscsi_tbl = kcalloc(MAX_ISCSI_TBL_SZ, sizeof(struct cnic_iscsi), - GFP_KERNEL); + cp->iscsi_tbl = kzalloc_objs(struct cnic_iscsi, MAX_ISCSI_TBL_SZ); if (!cp->iscsi_tbl) goto error; - cp->ctx_tbl = kcalloc(cp->max_cid_space, sizeof(struct cnic_context), - GFP_KERNEL); + cp->ctx_tbl = kzalloc_objs(struct cnic_context, cp->max_cid_space); if (!cp->ctx_tbl) goto error; @@ -4105,8 +4103,7 @@ static int cnic_cm_alloc_mem(struct cnic_dev *dev) u32 port_id; int i; - cp->csk_tbl = kvcalloc(MAX_CM_SK_TBL_SZ, sizeof(struct cnic_sock), - GFP_KERNEL); + cp->csk_tbl = kvzalloc_objs(struct cnic_sock, MAX_CM_SK_TBL_SZ); if (!cp->csk_tbl) return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c index 05512aa10c20..482a31e7b72b 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c @@ -1342,8 +1342,7 @@ static void bcmgenet_get_ethtool_stats(struct net_device *dev, } } -void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, - bool tx_lpi_enabled) +void bcmgenet_eee_enable_set(struct net_device *dev, bool enable) { struct bcmgenet_priv *priv = netdev_priv(dev); u32 off = priv->hw_params->tbuf_offset + TBUF_ENERGY_CTRL; @@ -1363,7 +1362,7 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, /* Enable EEE and switch to a 27Mhz clock automatically */ reg = bcmgenet_readl(priv->base + off); - if (tx_lpi_enabled) + if (enable) reg |= TBUF_EEE_EN | TBUF_PM_EN; else reg &= ~(TBUF_EEE_EN | TBUF_PM_EN); @@ -1382,14 +1381,12 @@ void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, priv->clk_eee_enabled = false; } - priv->eee.eee_enabled = enable; - priv->eee.tx_lpi_enabled = tx_lpi_enabled; } static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_keee *e) { struct bcmgenet_priv *priv = netdev_priv(dev); - struct ethtool_keee *p = &priv->eee; + int ret; if (GENET_IS_V1(priv)) return -EOPNOTSUPP; @@ -1397,17 +1394,21 @@ static int bcmgenet_get_eee(struct net_device *dev, struct ethtool_keee *e) if (!dev->phydev) return -ENODEV; - e->tx_lpi_enabled = p->tx_lpi_enabled; + ret = phy_ethtool_get_eee(dev->phydev, e); + if (ret) + return ret; + + /* tx_lpi_timer is maintained by the MAC hardware register; the + * PHY-level eee_cfg timer is not set for GENET. + */ e->tx_lpi_timer = bcmgenet_umac_readl(priv, UMAC_EEE_LPI_TIMER); - return phy_ethtool_get_eee(dev->phydev, e); + return 0; } static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e) { struct bcmgenet_priv *priv = netdev_priv(dev); - struct ethtool_keee *p = &priv->eee; - bool active; if (GENET_IS_V1(priv)) return -EOPNOTSUPP; @@ -1415,15 +1416,7 @@ static int bcmgenet_set_eee(struct net_device *dev, struct ethtool_keee *e) if (!dev->phydev) return -ENODEV; - p->eee_enabled = e->eee_enabled; - - if (!p->eee_enabled) { - bcmgenet_eee_enable_set(dev, false, false); - } else { - active = phy_init_eee(dev->phydev, false) >= 0; - bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER); - bcmgenet_eee_enable_set(dev, active, e->tx_lpi_enabled); - } + bcmgenet_umac_writel(priv, e->tx_lpi_timer, UMAC_EEE_LPI_TIMER); return phy_ethtool_set_eee(dev->phydev, e); } @@ -3083,8 +3076,7 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv, bool flush_rx) /* Initialize common Rx ring structures */ priv->rx_bds = priv->base + priv->hw_params->rdma_offset; priv->num_rx_bds = TOTAL_DESC; - priv->rx_cbs = kcalloc(priv->num_rx_bds, sizeof(struct enet_cb), - GFP_KERNEL); + priv->rx_cbs = kzalloc_objs(struct enet_cb, priv->num_rx_bds); if (!priv->rx_cbs) return -ENOMEM; @@ -3096,8 +3088,7 @@ static int bcmgenet_init_dma(struct bcmgenet_priv *priv, bool flush_rx) /* Initialize common TX ring structures */ priv->tx_bds = priv->base + priv->hw_params->tdma_offset; priv->num_tx_bds = TOTAL_DESC; - priv->tx_cbs = kcalloc(priv->num_tx_bds, sizeof(struct enet_cb), - GFP_KERNEL); + priv->tx_cbs = kzalloc_objs(struct enet_cb, priv->num_tx_bds); if (!priv->tx_cbs) { kfree(priv->rx_cbs); return -ENOMEM; diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.h b/drivers/net/ethernet/broadcom/genet/bcmgenet.h index 5ec3979779ec..9e4110c7fdf6 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.h +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.h @@ -665,8 +665,6 @@ struct bcmgenet_priv { u8 sopass[SOPASS_MAX]; struct bcmgenet_mib_counters mib; - - struct ethtool_keee eee; }; static inline bool bcmgenet_has_40bits(struct bcmgenet_priv *priv) @@ -749,7 +747,6 @@ int bcmgenet_wol_power_down_cfg(struct bcmgenet_priv *priv, int bcmgenet_wol_power_up_cfg(struct bcmgenet_priv *priv, enum bcmgenet_power_mode mode); -void bcmgenet_eee_enable_set(struct net_device *dev, bool enable, - bool tx_lpi_enabled); +void bcmgenet_eee_enable_set(struct net_device *dev, bool enable); #endif /* __BCMGENET_H__ */ diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 38f854b94a79..a4e0d5a68268 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -29,7 +29,6 @@ static void bcmgenet_mac_config(struct net_device *dev) struct bcmgenet_priv *priv = netdev_priv(dev); struct phy_device *phydev = dev->phydev; u32 reg, cmd_bits = 0; - bool active; /* speed */ if (phydev->speed == SPEED_1000) @@ -90,10 +89,6 @@ static void bcmgenet_mac_config(struct net_device *dev) bcmgenet_umac_writel(priv, reg, UMAC_CMD); spin_unlock_bh(&priv->reg_lock); - active = phy_init_eee(phydev, 0) >= 0; - bcmgenet_eee_enable_set(dev, - priv->eee.eee_enabled && active, - priv->eee.tx_lpi_enabled); } /* setup netdev link state when PHY link status change and @@ -113,6 +108,8 @@ void bcmgenet_mii_setup(struct net_device *dev) bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL); } + bcmgenet_eee_enable_set(dev, phydev->enable_tx_lpi); + phy_print_status(phydev); } @@ -412,6 +409,9 @@ int bcmgenet_mii_probe(struct net_device *dev) /* Indicate that the MAC is responsible for PHY PM */ dev->phydev->mac_managed_pm = true; + if (!GENET_IS_V1(priv)) + phy_support_eee(dev->phydev); + return 0; } diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index 30865fe03eeb..c839dd9804d3 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -622,9 +622,8 @@ static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, d->sbdma_maxdescr = maxdescr; - d->sbdma_dscrtable_unaligned = kcalloc(d->sbdma_maxdescr + 1, - sizeof(*d->sbdma_dscrtable), - GFP_KERNEL); + d->sbdma_dscrtable_unaligned = kzalloc_objs(*d->sbdma_dscrtable, + d->sbdma_maxdescr + 1); /* * The descriptor table must be aligned to at least 16 bytes or the @@ -642,8 +641,7 @@ static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, * And context table */ - d->sbdma_ctxtable = kcalloc(d->sbdma_maxdescr, - sizeof(*d->sbdma_ctxtable), GFP_KERNEL); + d->sbdma_ctxtable = kzalloc_objs(*d->sbdma_ctxtable, d->sbdma_maxdescr); #ifdef CONFIG_SBMAC_COALESCE /* diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 75f66587983d..2328fce33644 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8729,9 +8729,8 @@ static int tg3_mem_tx_acquire(struct tg3 *tp) tnapi++; for (i = 0; i < tp->txq_cnt; i++, tnapi++) { - tnapi->tx_buffers = kcalloc(TG3_TX_RING_SIZE, - sizeof(struct tg3_tx_ring_info), - GFP_KERNEL); + tnapi->tx_buffers = kzalloc_objs(struct tg3_tx_ring_info, + TG3_TX_RING_SIZE); if (!tnapi->tx_buffers) goto err_out; diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 9bed33295839..8e19add764db 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -1345,8 +1345,7 @@ bnad_mem_alloc(struct bnad *bnad, return 0; } - mem_info->mdl = kcalloc(mem_info->num, sizeof(struct bna_mem_descr), - GFP_KERNEL); + mem_info->mdl = kzalloc_objs(struct bna_mem_descr, mem_info->num); if (mem_info->mdl == NULL) return -ENOMEM; @@ -1458,9 +1457,8 @@ bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src, if (cfg_flags & BNAD_CF_MSIX) { intr_info->intr_type = BNA_INTR_T_MSIX; - intr_info->idl = kcalloc(intr_info->num, - sizeof(struct bna_intr_descr), - GFP_KERNEL); + intr_info->idl = kzalloc_objs(struct bna_intr_descr, + intr_info->num); if (!intr_info->idl) return -ENOMEM; @@ -1484,9 +1482,8 @@ bnad_txrx_irq_alloc(struct bnad *bnad, enum bnad_intr_source src, } else { intr_info->intr_type = BNA_INTR_T_INTX; intr_info->num = 1; - intr_info->idl = kcalloc(intr_info->num, - sizeof(struct bna_intr_descr), - GFP_KERNEL); + intr_info->idl = kzalloc_objs(struct bna_intr_descr, + intr_info->num); if (!intr_info->idl) return -ENOMEM; @@ -2642,7 +2639,7 @@ bnad_enable_msix(struct bnad *bnad) return; bnad->msix_table = - kcalloc(bnad->msix_num, sizeof(struct msix_entry), GFP_KERNEL); + kzalloc_objs(struct msix_entry, bnad->msix_num); if (!bnad->msix_table) goto intx_mode; diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 8f0972e6737c..ba3c1033a0b0 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -45,7 +45,7 @@ bnad_debugfs_open_fwtrc(struct inode *inode, struct file *file) unsigned long flags; int rc; - fw_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL); + fw_debug = kzalloc_obj(struct bnad_debug_info); if (!fw_debug) return -ENOMEM; @@ -85,7 +85,7 @@ bnad_debugfs_open_fwsave(struct inode *inode, struct file *file) unsigned long flags; int rc; - fw_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL); + fw_debug = kzalloc_obj(struct bnad_debug_info); if (!fw_debug) return -ENOMEM; @@ -122,7 +122,7 @@ bnad_debugfs_open_reg(struct inode *inode, struct file *file) { struct bnad_debug_info *reg_debug; - reg_debug = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL); + reg_debug = kzalloc_obj(struct bnad_debug_info); if (!reg_debug) return -ENOMEM; @@ -185,7 +185,7 @@ bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file) struct bnad_debug_info *drv_info; int rc; - drv_info = kzalloc(sizeof(struct bnad_debug_info), GFP_KERNEL); + drv_info = kzalloc_obj(struct bnad_debug_info); if (!drv_info) return -ENOMEM; diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index 216e25f26dbb..466e2ea7a740 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c @@ -285,7 +285,7 @@ bnad_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) strscpy(drvinfo->driver, BNAD_NAME, sizeof(drvinfo->driver)); - ioc_attr = kzalloc(sizeof(*ioc_attr), GFP_KERNEL); + ioc_attr = kzalloc_obj(*ioc_attr); if (ioc_attr) { spin_lock_irqsave(&bnad->bna_lock, flags); bfa_nw_ioc_get_attr(&bnad->bna.ioceth.ioc, ioc_attr); @@ -900,7 +900,7 @@ bnad_get_flash_partition_by_offset(struct bnad *bnad, u32 offset, u32 i, flash_part = 0, ret; unsigned long flags = 0; - flash_attr = kzalloc(sizeof(struct bfa_flash_attr), GFP_KERNEL); + flash_attr = kzalloc_obj(struct bfa_flash_attr); if (!flash_attr) return 0; diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 43cd013bb70e..f290d608b409 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "macb.h" @@ -668,6 +669,97 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode, netif_tx_stop_all_queues(ndev); } +/* Use juggling algorithm to left rotate tx ring and tx skb array */ +static void gem_shuffle_tx_one_ring(struct macb_queue *queue) +{ + unsigned int head, tail, count, ring_size, desc_size; + struct macb_tx_skb tx_skb, *skb_curr, *skb_next; + struct macb_dma_desc *desc_curr, *desc_next; + unsigned int i, cycles, shift, curr, next; + struct macb *bp = queue->bp; + unsigned char desc[24]; + unsigned long flags; + + desc_size = macb_dma_desc_get_size(bp); + + if (WARN_ON_ONCE(desc_size > ARRAY_SIZE(desc))) + return; + + spin_lock_irqsave(&queue->tx_ptr_lock, flags); + head = queue->tx_head; + tail = queue->tx_tail; + ring_size = bp->tx_ring_size; + count = CIRC_CNT(head, tail, ring_size); + + if (!(tail % ring_size)) + goto unlock; + + if (!count) { + queue->tx_head = 0; + queue->tx_tail = 0; + goto unlock; + } + + shift = tail % ring_size; + cycles = gcd(ring_size, shift); + + for (i = 0; i < cycles; i++) { + memcpy(&desc, macb_tx_desc(queue, i), desc_size); + memcpy(&tx_skb, macb_tx_skb(queue, i), + sizeof(struct macb_tx_skb)); + + curr = i; + next = (curr + shift) % ring_size; + + while (next != i) { + desc_curr = macb_tx_desc(queue, curr); + desc_next = macb_tx_desc(queue, next); + + memcpy(desc_curr, desc_next, desc_size); + + if (next == ring_size - 1) + desc_curr->ctrl &= ~MACB_BIT(TX_WRAP); + if (curr == ring_size - 1) + desc_curr->ctrl |= MACB_BIT(TX_WRAP); + + skb_curr = macb_tx_skb(queue, curr); + skb_next = macb_tx_skb(queue, next); + memcpy(skb_curr, skb_next, sizeof(struct macb_tx_skb)); + + curr = next; + next = (curr + shift) % ring_size; + } + + desc_curr = macb_tx_desc(queue, curr); + memcpy(desc_curr, &desc, desc_size); + if (i == ring_size - 1) + desc_curr->ctrl &= ~MACB_BIT(TX_WRAP); + if (curr == ring_size - 1) + desc_curr->ctrl |= MACB_BIT(TX_WRAP); + memcpy(macb_tx_skb(queue, curr), &tx_skb, + sizeof(struct macb_tx_skb)); + } + + queue->tx_head = count; + queue->tx_tail = 0; + + /* Make descriptor updates visible to hardware */ + wmb(); + +unlock: + spin_unlock_irqrestore(&queue->tx_ptr_lock, flags); +} + +/* Rotate the queue so that the tail is at index 0 */ +static void gem_shuffle_tx_rings(struct macb *bp) +{ + struct macb_queue *queue; + int q; + + for (q = 0, queue = bp->queues; q < bp->num_queues; q++, queue++) + gem_shuffle_tx_one_ring(queue); +} + static void macb_mac_link_up(struct phylink_config *config, struct phy_device *phy, unsigned int mode, phy_interface_t interface, @@ -706,8 +798,6 @@ static void macb_mac_link_up(struct phylink_config *config, ctrl |= MACB_BIT(PAE); for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) { - queue->tx_head = 0; - queue->tx_tail = 0; queue_writel(queue, IER, bp->rx_intr_mask | MACB_TX_INT_FLAGS | MACB_BIT(HRESP)); } @@ -721,8 +811,10 @@ static void macb_mac_link_up(struct phylink_config *config, spin_unlock_irqrestore(&bp->lock, flags); - if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) + if (!(bp->caps & MACB_CAPS_MACB_IS_EMAC)) { macb_set_tx_clk(bp, speed); + gem_shuffle_tx_rings(bp); + } /* Enable Rx and Tx; Enable PTP unicast */ ctrl = macb_readl(bp, NCR); @@ -3734,7 +3826,7 @@ static int gem_add_flow_filter(struct net_device *netdev, int ret = -EINVAL; bool added = false; - newfs = kmalloc(sizeof(*newfs), GFP_KERNEL); + newfs = kmalloc_obj(*newfs); if (newfs == NULL) return -ENOMEM; memcpy(&newfs->fs, fs, sizeof(newfs->fs)); diff --git a/drivers/net/ethernet/calxeda/xgmac.c b/drivers/net/ethernet/calxeda/xgmac.c index 331ac6a3dc38..ef5174eb01ec 100644 --- a/drivers/net/ethernet/calxeda/xgmac.c +++ b/drivers/net/ethernet/calxeda/xgmac.c @@ -729,8 +729,7 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev) netdev_dbg(priv->dev, "mtu [%d] bfsize [%d]\n", dev->mtu, bfsize); - priv->rx_skbuff = kcalloc(DMA_RX_RING_SZ, sizeof(struct sk_buff *), - GFP_KERNEL); + priv->rx_skbuff = kzalloc_objs(struct sk_buff *, DMA_RX_RING_SZ); if (!priv->rx_skbuff) return -ENOMEM; @@ -742,8 +741,7 @@ static int xgmac_dma_desc_rings_init(struct net_device *dev) if (!priv->dma_rx) goto err_dma_rx; - priv->tx_skbuff = kcalloc(DMA_TX_RING_SZ, sizeof(struct sk_buff *), - GFP_KERNEL); + priv->tx_skbuff = kzalloc_objs(struct sk_buff *, DMA_TX_RING_SZ); if (!priv->tx_skbuff) goto err_tx_skb; diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c index 215dac201b4a..93b06d599eed 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_core.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c @@ -89,12 +89,12 @@ int lio_setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) int i, j; lio->glist_lock = - kcalloc(num_iqs, sizeof(*lio->glist_lock), GFP_KERNEL); + kzalloc_objs(*lio->glist_lock, num_iqs); if (!lio->glist_lock) return -ENOMEM; lio->glist = - kcalloc(num_iqs, sizeof(*lio->glist), GFP_KERNEL); + kzalloc_objs(*lio->glist, num_iqs); if (!lio->glist) { kfree(lio->glist_lock); lio->glist_lock = NULL; @@ -107,10 +107,8 @@ int lio_setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) /* allocate memory to store virtual and dma base address of * per glist consistent memory */ - lio->glists_virt_base = kcalloc(num_iqs, sizeof(*lio->glists_virt_base), - GFP_KERNEL); - lio->glists_dma_base = kcalloc(num_iqs, sizeof(*lio->glists_dma_base), - GFP_KERNEL); + lio->glists_virt_base = kzalloc_objs(*lio->glists_virt_base, num_iqs); + lio->glists_dma_base = kzalloc_objs(*lio->glists_dma_base, num_iqs); if (!lio->glists_virt_base || !lio->glists_dma_base) { lio_delete_glists(lio); @@ -138,7 +136,7 @@ int lio_setup_glists(struct octeon_device *oct, struct lio *lio, int num_iqs) g = kzalloc_node(sizeof(*g), GFP_KERNEL, numa_node); if (!g) - g = kzalloc(sizeof(*g), GFP_KERNEL); + g = kzalloc_obj(*g); if (!g) break; @@ -1051,9 +1049,8 @@ int octeon_setup_interrupt(struct octeon_device *oct, u32 num_ioqs) aux_irq_name = &queue_irq_names [IRQ_NAME_OFF(MAX_IOQ_INTERRUPTS_PER_PF)]; - oct->msix_entries = kcalloc(oct->num_msix_irqs, - sizeof(struct msix_entry), - GFP_KERNEL); + oct->msix_entries = kzalloc_objs(struct msix_entry, + oct->num_msix_irqs); if (!oct->msix_entries) { dev_err(&oct->pci_dev->dev, "Memory Alloc failed...\n"); kfree(oct->irq_name_storage); diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_device.c b/drivers/net/ethernet/cavium/liquidio/octeon_device.c index 1753bb87dfbd..e98118e7b9fd 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_device.c +++ b/drivers/net/ethernet/cavium/liquidio/octeon_device.c @@ -1164,7 +1164,7 @@ octeon_register_dispatch_fn(struct octeon_device *oct, dev_dbg(&oct->pci_dev->dev, "Adding opcode to dispatch list linked list\n"); - dispatch = kmalloc(sizeof(*dispatch), GFP_KERNEL); + dispatch = kmalloc_obj(*dispatch); if (!dispatch) return 1; diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_main.c b/drivers/net/ethernet/cavium/thunder/nicvf_main.c index 0b6e30a8feb0..1c183827cb9e 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c @@ -1465,7 +1465,7 @@ int nicvf_open(struct net_device *netdev) /* Register NAPI handler for processing CQEs */ for (qidx = 0; qidx < qs->cq_cnt; qidx++) { - cq_poll = kzalloc(sizeof(*cq_poll), GFP_KERNEL); + cq_poll = kzalloc_obj(*cq_poll); if (!cq_poll) { err = -ENOMEM; goto napi_del; @@ -2052,9 +2052,9 @@ static void nicvf_set_rx_mode(struct net_device *netdev) mode |= BGX_XCAST_MCAST_FILTER; /* here we need to copy mc addrs */ if (netdev_mc_count(netdev)) { - mc_list = kmalloc(struct_size(mc_list, mc, - netdev_mc_count(netdev)), - GFP_ATOMIC); + mc_list = kmalloc_flex(*mc_list, mc, + netdev_mc_count(netdev), + GFP_ATOMIC); if (unlikely(!mc_list)) return; mc_list->count = 0; diff --git a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c index 5211759bfe47..062ac4a5fa12 100644 --- a/drivers/net/ethernet/cavium/thunder/nicvf_queues.c +++ b/drivers/net/ethernet/cavium/thunder/nicvf_queues.c @@ -289,8 +289,7 @@ static int nicvf_init_rbdr(struct nicvf *nic, struct rbdr *rbdr, rbdr->is_xdp = true; } rbdr->pgcnt = roundup_pow_of_two(rbdr->pgcnt); - rbdr->pgcache = kcalloc(rbdr->pgcnt, sizeof(*rbdr->pgcache), - GFP_KERNEL); + rbdr->pgcache = kzalloc_objs(*rbdr->pgcache, rbdr->pgcnt); if (!rbdr->pgcache) return -ENOMEM; rbdr->pgidx = 0; diff --git a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c index 9efb60842ad1..b6303999902f 100644 --- a/drivers/net/ethernet/cavium/thunder/thunder_bgx.c +++ b/drivers/net/ethernet/cavium/thunder/thunder_bgx.c @@ -1086,8 +1086,7 @@ static int bgx_lmac_enable(struct bgx *bgx, u8 lmacid) /* actual number of filters available to exact LMAC */ lmac->dmacs_count = (RX_DMAC_COUNT / bgx->lmac_count); - lmac->dmacs = kcalloc(lmac->dmacs_count, sizeof(*lmac->dmacs), - GFP_KERNEL); + lmac->dmacs = kzalloc_objs(*lmac->dmacs, lmac->dmacs_count); if (!lmac->dmacs) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb/espi.c b/drivers/net/ethernet/chelsio/cxgb/espi.c index ef70569435be..282409fefd39 100644 --- a/drivers/net/ethernet/chelsio/cxgb/espi.c +++ b/drivers/net/ethernet/chelsio/cxgb/espi.c @@ -280,7 +280,7 @@ void t1_espi_destroy(struct peespi *espi) struct peespi *t1_espi_create(adapter_t *adapter) { - struct peespi *espi = kzalloc(sizeof(*espi), GFP_KERNEL); + struct peespi *espi = kzalloc_obj(*espi); if (espi) espi->adapter = adapter; diff --git a/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c b/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c index 30b003484fc1..dc412801bd31 100644 --- a/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c +++ b/drivers/net/ethernet/chelsio/cxgb/mv88e1xxx.c @@ -358,7 +358,7 @@ static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { struct adapter *adapter = netdev_priv(dev); - struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); + struct cphy *cphy = kzalloc_obj(*cphy); if (!cphy) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb/mv88x201x.c b/drivers/net/ethernet/chelsio/cxgb/mv88x201x.c index 556c8ad68fa8..c378c9b2156c 100644 --- a/drivers/net/ethernet/chelsio/cxgb/mv88x201x.c +++ b/drivers/net/ethernet/chelsio/cxgb/mv88x201x.c @@ -203,7 +203,7 @@ static struct cphy *mv88x201x_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { u32 val; - struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL); + struct cphy *cphy = kzalloc_obj(*cphy); if (!cphy) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb/my3126.c b/drivers/net/ethernet/chelsio/cxgb/my3126.c index 60aa45b375b6..bd1eb3a7bb33 100644 --- a/drivers/net/ethernet/chelsio/cxgb/my3126.c +++ b/drivers/net/ethernet/chelsio/cxgb/my3126.c @@ -171,7 +171,7 @@ static const struct cphy_ops my3126_ops = { static struct cphy *my3126_phy_create(struct net_device *dev, int phy_addr, const struct mdio_ops *mdio_ops) { - struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL); + struct cphy *cphy = kzalloc_obj(*cphy); if (!cphy) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb/sge.c b/drivers/net/ethernet/chelsio/cxgb/sge.c index 5f354cf62cdd..d8fca697874a 100644 --- a/drivers/net/ethernet/chelsio/cxgb/sge.c +++ b/drivers/net/ethernet/chelsio/cxgb/sge.c @@ -366,7 +366,7 @@ static int tx_sched_init(struct sge *sge) struct sched *s; int i; - s = kzalloc(sizeof (struct sched), GFP_KERNEL); + s = kzalloc_obj(struct sched); if (!s) return -ENOMEM; @@ -2095,7 +2095,7 @@ static void espibug_workaround(struct timer_list *t) */ struct sge *t1_sge_create(struct adapter *adapter, struct sge_params *p) { - struct sge *sge = kzalloc(sizeof(*sge), GFP_KERNEL); + struct sge *sge = kzalloc_obj(*sge); int i; if (!sge) diff --git a/drivers/net/ethernet/chelsio/cxgb/tp.c b/drivers/net/ethernet/chelsio/cxgb/tp.c index 4337cee0763e..0d741e374f71 100644 --- a/drivers/net/ethernet/chelsio/cxgb/tp.c +++ b/drivers/net/ethernet/chelsio/cxgb/tp.c @@ -58,7 +58,7 @@ void t1_tp_destroy(struct petp *tp) struct petp *t1_tp_create(adapter_t *adapter, struct tp_params *p) { - struct petp *tp = kzalloc(sizeof(*tp), GFP_KERNEL); + struct petp *tp = kzalloc_obj(*tp); if (!tp) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c index 3b1321c8ed14..88b6d76817e9 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c @@ -3242,7 +3242,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) mmio_len = pci_resource_len(pdev, 0); ai = t3_get_adapter_info(ent->driver_data); - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) { err = -ENOMEM; goto out_release_regions; diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c index 5a9f6925e1fa..1e544047fa3a 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c +++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c @@ -1185,7 +1185,7 @@ int cxgb3_offload_activate(struct adapter *adapter) unsigned int l2t_capacity; struct l2t_data *l2td; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.c b/drivers/net/ethernet/chelsio/cxgb3/l2t.c index 5d5f3380ecca..e27c6ff67cbd 100644 --- a/drivers/net/ethernet/chelsio/cxgb3/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.c @@ -408,7 +408,7 @@ struct l2t_data *t3_init_l2t(unsigned int l2t_capacity) struct l2t_data *d; int i; - d = kvzalloc(struct_size(d, l2tab, l2t_capacity), GFP_KERNEL); + d = kvzalloc_flex(*d, l2tab, l2t_capacity); if (!d) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c index 5060d3998889..6954c15d2b82 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c +++ b/drivers/net/ethernet/chelsio/cxgb4/clip_tbl.c @@ -287,7 +287,7 @@ struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start, if (clipt_size < CLIPT_MIN_HASH_BUCKETS) return NULL; - ctbl = kvzalloc(struct_size(ctbl, hash_list, clipt_size), GFP_KERNEL); + ctbl = kvzalloc_flex(*ctbl, hash_list, clipt_size); if (!ctbl) return NULL; @@ -301,7 +301,7 @@ struct clip_tbl *t4_init_clip_tbl(unsigned int clipt_start, for (i = 0; i < ctbl->clipt_size; ++i) INIT_LIST_HEAD(&ctbl->hash_list[i]); - cl_list = kvcalloc(clipt_size, sizeof(struct clip_entry), GFP_KERNEL); + cl_list = kvzalloc_objs(struct clip_entry, clipt_size); if (!cl_list) { kvfree(ctbl); return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index 14e0d989c3ba..f521737d1275 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -860,7 +860,7 @@ static int cctrl_tbl_show(struct seq_file *seq, void *v) u16 (*incr)[NCCTRL_WIN]; struct adapter *adap = seq->private; - incr = kmalloc_array(NMTUS, sizeof(*incr), GFP_KERNEL); + incr = kmalloc_objs(*incr, NMTUS); if (!incr) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c index faf8f7e86520..0092bc16f887 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_ethtool.c @@ -2250,13 +2250,11 @@ int cxgb4_init_ethtool_filters(struct adapter *adap) u32 nentries, i; int ret; - eth_filter = kzalloc(sizeof(*eth_filter), GFP_KERNEL); + eth_filter = kzalloc_obj(*eth_filter); if (!eth_filter) return -ENOMEM; - eth_filter_info = kcalloc(adap->params.nports, - sizeof(*eth_filter_info), - GFP_KERNEL); + eth_filter_info = kzalloc_objs(*eth_filter_info, adap->params.nports); if (!eth_filter_info) { ret = -ENOMEM; goto free_eth_filter; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c index dd9e68465e69..657d96b9e2f6 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_filter.c @@ -1389,7 +1389,7 @@ static int cxgb4_set_hash_filter(struct net_device *dev, if (iq < 0) return iq; - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 043733c5c812..10694d5924ee 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -388,7 +388,7 @@ static int cxgb4_mac_sync(struct net_device *netdev, const u8 *mac_addr) * list and program it */ if (uhash || mhash) { - new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); + new_entry = kzalloc_obj(*new_entry, GFP_ATOMIC); if (!new_entry) return -ENOMEM; ether_addr_copy(new_entry->addr, mac_addr); @@ -478,7 +478,7 @@ int cxgb4_change_mac(struct port_info *pi, unsigned int viid, goto set_hash; } } - new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); + new_entry = kzalloc_obj(*new_entry); if (!new_entry) return -ENOMEM; ether_addr_copy(new_entry->addr, addr); @@ -1330,7 +1330,7 @@ static int cxgb4_port_mirror_alloc_queues(struct net_device *dev) if (s->mirror_rxq[pi->port_id]) return 0; - mirror_rxq = kcalloc(pi->nmirrorqsets, sizeof(*mirror_rxq), GFP_KERNEL); + mirror_rxq = kzalloc_objs(*mirror_rxq, pi->nmirrorqsets); if (!mirror_rxq) return -ENOMEM; @@ -4057,7 +4057,7 @@ static int adap_config_hma(struct adapter *adapter) page_size = HMA_PAGE_SIZE; page_order = HMA_PAGE_ORDER; - adapter->hma.sgt = kzalloc(sizeof(*adapter->hma.sgt), GFP_KERNEL); + adapter->hma.sgt = kzalloc_obj(*adapter->hma.sgt); if (unlikely(!adapter->hma.sgt)) { dev_err(adapter->pdev_dev, "HMA SG table allocation failed\n"); return -ENOMEM; @@ -4097,8 +4097,7 @@ static int adap_config_hma(struct adapter *adapter) } adapter->hma.flags |= HMA_DMA_MAPPED_FLAG; - adapter->hma.phy_addr = kcalloc(sgt->nents, sizeof(dma_addr_t), - GFP_KERNEL); + adapter->hma.phy_addr = kzalloc_objs(dma_addr_t, sgt->nents); if (unlikely(!adapter->hma.phy_addr)) goto free_hma; @@ -4812,7 +4811,7 @@ static int adap_init0(struct adapter *adap, int vpd_skip) /* allocate memory to read the header of the firmware on the * card */ - card_fw = kvzalloc(sizeof(*card_fw), GFP_KERNEL); + card_fw = kvzalloc_obj(*card_fw); if (!card_fw) { ret = -ENOMEM; goto bye; @@ -5022,15 +5021,14 @@ static int adap_init0(struct adapter *adap, int vpd_skip) adap->sge.egr_sz = val[0] - adap->sge.egr_start + 1; adap->sge.ingr_sz = val[1] - adap->sge.ingr_start + 1; - adap->sge.egr_map = kcalloc(adap->sge.egr_sz, - sizeof(*adap->sge.egr_map), GFP_KERNEL); + adap->sge.egr_map = kzalloc_objs(*adap->sge.egr_map, adap->sge.egr_sz); if (!adap->sge.egr_map) { ret = -ENOMEM; goto bye; } - adap->sge.ingr_map = kcalloc(adap->sge.ingr_sz, - sizeof(*adap->sge.ingr_map), GFP_KERNEL); + adap->sge.ingr_map = kzalloc_objs(*adap->sge.ingr_map, + adap->sge.ingr_sz); if (!adap->sge.ingr_map) { ret = -ENOMEM; goto bye; @@ -5836,7 +5834,7 @@ static int alloc_msix_info(struct adapter *adap, u32 num_vec) { struct msix_info *msix_info; - msix_info = kcalloc(num_vec, sizeof(*msix_info), GFP_KERNEL); + msix_info = kzalloc_objs(*msix_info, num_vec); if (!msix_info) return -ENOMEM; @@ -5935,7 +5933,7 @@ static int enable_msix(struct adapter *adap) want += EXTRA_VECS; need += EXTRA_VECS; - entries = kmalloc_array(want, sizeof(*entries), GFP_KERNEL); + entries = kmalloc_objs(*entries, want); if (!entries) return -ENOMEM; @@ -6350,8 +6348,8 @@ static int cxgb4_iov_configure(struct pci_dev *pdev, int num_vfs) return err; } /* Allocate and set up VF Information. */ - adap->vfinfo = kcalloc(pci_sriov_get_totalvfs(pdev), - sizeof(struct vf_info), GFP_KERNEL); + adap->vfinfo = kzalloc_objs(struct vf_info, + pci_sriov_get_totalvfs(pdev)); if (!adap->vfinfo) { unregister_netdev(adap->port[0]); free_netdev(adap->port[0]); @@ -6604,7 +6602,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_device; } - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) { err = -ENOMEM; goto out_unmap_bar0; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c index 60f4d5b5eb3a..94c8ce39310b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_mps.c @@ -42,7 +42,7 @@ static int cxgb4_mps_ref_inc(struct adapter *adap, const u8 *mac_addr, goto unlock; } } - mps_entry = kzalloc(sizeof(*mps_entry), GFP_ATOMIC); + mps_entry = kzalloc_obj(*mps_entry, GFP_ATOMIC); if (!mps_entry) { ret = -ENOMEM; goto unlock; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c index e2b5554531b5..3307e5042681 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c @@ -145,7 +145,7 @@ static void cxgb4_action_natmode_tweak(struct ch_filter_specification *fs, static struct ch_tc_flower_entry *allocate_flower_entry(void) { - struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL); + struct ch_tc_flower_entry *new = kzalloc_obj(*new); if (new) spin_lock_init(&new->lock); return new; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c index f8dcf0b4abcd..bc290430245e 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_matchall.c @@ -531,13 +531,11 @@ int cxgb4_init_tc_matchall(struct adapter *adap) struct cxgb4_tc_matchall *tc_matchall; int ret; - tc_matchall = kzalloc(sizeof(*tc_matchall), GFP_KERNEL); + tc_matchall = kzalloc_obj(*tc_matchall); if (!tc_matchall) return -ENOMEM; - tc_port_matchall = kcalloc(adap->params.nports, - sizeof(*tc_port_matchall), - GFP_KERNEL); + tc_port_matchall = kzalloc_objs(*tc_port_matchall, adap->params.nports); if (!tc_port_matchall) { ret = -ENOMEM; goto out_free_matchall; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c index a2dcd2e24263..0f67d94e7f3b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_mqprio.c @@ -100,8 +100,7 @@ static int cxgb4_init_eosw_txq(struct net_device *dev, memset(eosw_txq, 0, sizeof(*eosw_txq)); - ring = kcalloc(CXGB4_EOSW_TXQ_DEFAULT_DESC_NUM, - sizeof(*ring), GFP_KERNEL); + ring = kzalloc_objs(*ring, CXGB4_EOSW_TXQ_DEFAULT_DESC_NUM); if (!ring) return -ENOMEM; @@ -157,15 +156,13 @@ static int cxgb4_mqprio_alloc_hw_resources(struct net_device *dev) /* Allocate ETHOFLD hardware queue structures if not done already */ if (!refcount_read(&adap->tc_mqprio->refcnt)) { - adap->sge.eohw_rxq = kcalloc(adap->sge.eoqsets, - sizeof(struct sge_ofld_rxq), - GFP_KERNEL); + adap->sge.eohw_rxq = kzalloc_objs(struct sge_ofld_rxq, + adap->sge.eoqsets); if (!adap->sge.eohw_rxq) return -ENOMEM; - adap->sge.eohw_txq = kcalloc(adap->sge.eoqsets, - sizeof(struct sge_eohw_txq), - GFP_KERNEL); + adap->sge.eohw_txq = kzalloc_objs(struct sge_eohw_txq, + adap->sge.eoqsets); if (!adap->sge.eohw_txq) { kfree(adap->sge.eohw_rxq); return -ENOMEM; @@ -657,12 +654,11 @@ int cxgb4_init_tc_mqprio(struct adapter *adap) int ret = 0; u8 i; - tc_mqprio = kzalloc(sizeof(*tc_mqprio), GFP_KERNEL); + tc_mqprio = kzalloc_obj(*tc_mqprio); if (!tc_mqprio) return -ENOMEM; - tc_port_mqprio = kcalloc(adap->params.nports, sizeof(*tc_port_mqprio), - GFP_KERNEL); + tc_port_mqprio = kzalloc_objs(*tc_port_mqprio, adap->params.nports); if (!tc_port_mqprio) { ret = -ENOMEM; goto out_free_mqprio; @@ -673,8 +669,7 @@ int cxgb4_init_tc_mqprio(struct adapter *adap) tc_mqprio->port_mqprio = tc_port_mqprio; for (i = 0; i < adap->params.nports; i++) { port_mqprio = &tc_mqprio->port_mqprio[i]; - eosw_txq = kcalloc(adap->tids.neotids, sizeof(*eosw_txq), - GFP_KERNEL); + eosw_txq = kzalloc_objs(*eosw_txq, adap->tids.neotids); if (!eosw_txq) { ret = -ENOMEM; goto out_free_ports; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c index 8524246fd67e..1c1a7bc5a896 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_u32.c @@ -501,7 +501,7 @@ struct cxgb4_tc_u32_table *cxgb4_init_tc_u32(struct adapter *adap) if (!max_tids) return NULL; - t = kvzalloc(struct_size(t, table, max_tids), GFP_KERNEL); + t = kvzalloc_flex(*t, table, max_tids); if (!t) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c index 5c13bcb4550d..23244cdfc1bc 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c @@ -241,7 +241,7 @@ static int cfg_queues_uld(struct adapter *adap, unsigned int uld_type, struct sge_uld_rxq_info *rxq_info; int i, nrxq, ciq_size; - rxq_info = kzalloc(sizeof(*rxq_info), GFP_KERNEL); + rxq_info = kzalloc_obj(*rxq_info); if (!rxq_info) return -ENOMEM; @@ -269,8 +269,7 @@ static int cfg_queues_uld(struct adapter *adap, unsigned int uld_type, } nrxq = rxq_info->nrxq + rxq_info->nciq; /* total rxq's */ - rxq_info->uldrxq = kcalloc(nrxq, sizeof(struct sge_ofld_rxq), - GFP_KERNEL); + rxq_info->uldrxq = kzalloc_objs(struct sge_ofld_rxq, nrxq); if (!rxq_info->uldrxq) { kfree(rxq_info); return -ENOMEM; @@ -472,7 +471,7 @@ setup_sge_txq_uld(struct adapter *adap, unsigned int uld_type, (atomic_inc_return(&txq_info->users) > 1)) return 0; - txq_info = kzalloc(sizeof(*txq_info), GFP_KERNEL); + txq_info = kzalloc_obj(*txq_info); if (!txq_info) return -ENOMEM; if (uld_type == CXGB4_ULD_CRYPTO) { @@ -489,8 +488,7 @@ setup_sge_txq_uld(struct adapter *adap, unsigned int uld_type, i = min_t(int, uld_info->ntxq, num_online_cpus()); txq_info->ntxq = roundup(i, adap->params.nports); } - txq_info->uldtxq = kcalloc(txq_info->ntxq, sizeof(struct sge_uld_txq), - GFP_KERNEL); + txq_info->uldtxq = kzalloc_objs(struct sge_uld_txq, txq_info->ntxq); if (!txq_info->uldtxq) { kfree(txq_info); return -ENOMEM; @@ -525,19 +523,15 @@ int t4_uld_mem_alloc(struct adapter *adap) { struct sge *s = &adap->sge; - adap->uld = kcalloc(CXGB4_ULD_MAX, sizeof(*adap->uld), GFP_KERNEL); + adap->uld = kzalloc_objs(*adap->uld, CXGB4_ULD_MAX); if (!adap->uld) return -ENOMEM; - s->uld_rxq_info = kcalloc(CXGB4_ULD_MAX, - sizeof(struct sge_uld_rxq_info *), - GFP_KERNEL); + s->uld_rxq_info = kzalloc_objs(struct sge_uld_rxq_info *, CXGB4_ULD_MAX); if (!s->uld_rxq_info) goto err_uld; - s->uld_txq_info = kcalloc(CXGB4_TX_MAX, - sizeof(struct sge_uld_txq_info *), - GFP_KERNEL); + s->uld_txq_info = kzalloc_objs(struct sge_uld_txq_info *, CXGB4_TX_MAX); if (!s->uld_txq_info) goto err_uld_rx; return 0; @@ -805,7 +799,7 @@ void cxgb4_register_uld(enum cxgb4_uld type, if (type >= CXGB4_ULD_MAX) return; - uld_entry = kzalloc(sizeof(*uld_entry), GFP_KERNEL); + uld_entry = kzalloc_obj(*uld_entry); if (!uld_entry) return; diff --git a/drivers/net/ethernet/chelsio/cxgb4/l2t.c b/drivers/net/ethernet/chelsio/cxgb4/l2t.c index c02b4e9c06b2..426189d6c25a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/l2t.c +++ b/drivers/net/ethernet/chelsio/cxgb4/l2t.c @@ -620,7 +620,7 @@ struct l2t_data *t4_init_l2t(unsigned int l2t_start, unsigned int l2t_end) if (l2t_size < L2T_MIN_HASH_BUCKETS) return NULL; - d = kvzalloc(struct_size(d, l2tab, l2t_size), GFP_KERNEL); + d = kvzalloc_flex(*d, l2tab, l2t_size); if (!d) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/sched.c b/drivers/net/ethernet/chelsio/cxgb4/sched.c index 38a30aeee122..442d63bece59 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/sched.c +++ b/drivers/net/ethernet/chelsio/cxgb4/sched.c @@ -225,7 +225,7 @@ static int t4_sched_queue_bind(struct port_info *pi, struct ch_sched_queue *p) if (p->queue < 0 || p->queue >= pi->nqsets) return -ERANGE; - qe = kvzalloc(sizeof(struct sched_queue_entry), GFP_KERNEL); + qe = kvzalloc_obj(struct sched_queue_entry); if (!qe) return -ENOMEM; @@ -294,7 +294,7 @@ static int t4_sched_flowc_bind(struct port_info *pi, struct ch_sched_flowc *p) if (p->tid < 0 || p->tid >= adap->tids.neotids) return -ERANGE; - fe = kvzalloc(sizeof(*fe), GFP_KERNEL); + fe = kvzalloc_obj(*fe); if (!fe) return -ENOMEM; @@ -653,7 +653,7 @@ struct sched_table *t4_init_sched(unsigned int sched_size) struct sched_table *s; unsigned int i; - s = kvzalloc(struct_size(s, tab, sched_size), GFP_KERNEL); + s = kvzalloc_flex(*s, tab, sched_size); if (!s) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4/smt.c b/drivers/net/ethernet/chelsio/cxgb4/smt.c index e617e4aabbcc..21c7ec34b788 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/smt.c +++ b/drivers/net/ethernet/chelsio/cxgb4/smt.c @@ -47,7 +47,7 @@ struct smt_data *t4_init_smt(void) smt_size = SMT_SIZE; - s = kvzalloc(struct_size(s, smtab, smt_size), GFP_KERNEL); + s = kvzalloc_flex(*s, smtab, smt_size); if (!s) return NULL; s->smt_size = smt_size; diff --git a/drivers/net/ethernet/chelsio/cxgb4/srq.c b/drivers/net/ethernet/chelsio/cxgb4/srq.c index a77d6ac1ee8c..2a110494c363 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/srq.c +++ b/drivers/net/ethernet/chelsio/cxgb4/srq.c @@ -40,7 +40,7 @@ struct srq_data *t4_init_srq(int srq_size) { struct srq_data *s; - s = kvzalloc(sizeof(*s), GFP_KERNEL); + s = kvzalloc_obj(*s); if (!s) return NULL; diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index 2fbe0f059a0b..9eaa9aadee33 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -288,7 +288,7 @@ static int cxgb4vf_change_mac(struct port_info *pi, unsigned int viid, goto set_hash; } } - new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); + new_entry = kzalloc_obj(*new_entry); if (!new_entry) return -ENOMEM; ether_addr_copy(new_entry->addr, addr); @@ -953,7 +953,7 @@ static int cxgb4vf_mac_sync(struct net_device *netdev, const u8 *mac_addr) * list and program it */ if (uhash || mhash) { - new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); + new_entry = kzalloc_obj(*new_entry, GFP_ATOMIC); if (!new_entry) return -ENOMEM; ether_addr_copy(new_entry->addr, mac_addr); @@ -2935,7 +2935,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev, /* * Allocate our adapter data structure and attach it to the device. */ - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) { err = -ENOMEM; goto err_release_regions; diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c index 074717d4bb16..efbe07a3ba07 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c @@ -104,7 +104,7 @@ static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop) pr_info_once("%s - version %s\n", CHIPSEC_DRV_DESC, CHIPSEC_DRV_VERSION); - u_ctx = kzalloc(sizeof(*u_ctx), GFP_KERNEL); + u_ctx = kzalloc_obj(*u_ctx); if (!u_ctx) { u_ctx = ERR_PTR(-ENOMEM); goto out; @@ -295,7 +295,7 @@ static int ch_ipsec_xfrm_add_state(struct net_device *dev, return -ENODEV; } - sa_entry = kzalloc(sizeof(*sa_entry), GFP_KERNEL); + sa_entry = kzalloc_obj(*sa_entry); if (!sa_entry) { res = -ENOMEM; module_put(THIS_MODULE); diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c index b8ebb56de65e..f5acd4be1e69 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c @@ -442,7 +442,7 @@ static int chcr_ktls_dev_add(struct net_device *netdev, struct sock *sk, if (u_ctx && u_ctx->detach) goto out; - tx_info = kvzalloc(sizeof(*tx_info), GFP_KERNEL); + tx_info = kvzalloc_obj(*tx_info); if (!tx_info) goto out; @@ -2117,7 +2117,7 @@ static void *chcr_ktls_uld_add(const struct cxgb4_lld_info *lldi) pr_info_once("%s - version %s\n", CHCR_KTLS_DRV_DESC, CHCR_KTLS_DRV_VERSION); - u_ctx = kzalloc(sizeof(*u_ctx), GFP_KERNEL); + u_ctx = kzalloc_obj(*u_ctx); if (!u_ctx) { u_ctx = ERR_PTR(-ENOMEM); goto out; diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c index ee0154337a9c..0e3e5cf52c2c 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_cm.c @@ -57,7 +57,7 @@ static unsigned char new_state[16] = { static struct chtls_sock *chtls_sock_create(struct chtls_dev *cdev) { - struct chtls_sock *csk = kzalloc(sizeof(*csk), GFP_ATOMIC); + struct chtls_sock *csk = kzalloc_obj(*csk, GFP_ATOMIC); if (!csk) return NULL; @@ -548,7 +548,7 @@ static struct listen_info *listen_hash_add(struct chtls_dev *cdev, struct sock *sk, unsigned int stid) { - struct listen_info *p = kmalloc(sizeof(*p), GFP_KERNEL); + struct listen_info *p = kmalloc_obj(*p); if (p) { int key = listen_hashfn(sk); @@ -666,7 +666,7 @@ int chtls_listen_start(struct chtls_dev *cdev, struct sock *sk) if (listen_hash_find(cdev, sk) >= 0) /* already have it */ return -EADDRINUSE; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c index daa1ebaef511..2570575434f9 100644 --- a/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c +++ b/drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_main.c @@ -95,7 +95,7 @@ static int chtls_start_listen(struct chtls_dev *cdev, struct sock *sk) return -EADDRNOTAVAIL; sk->sk_backlog_rcv = listen_backlog_rcv; - clisten = kmalloc(sizeof(*clisten), GFP_KERNEL); + clisten = kmalloc_obj(*clisten); if (!clisten) return -ENOMEM; clisten->cdev = cdev; @@ -114,7 +114,7 @@ static void chtls_stop_listen(struct chtls_dev *cdev, struct sock *sk) if (sk->sk_protocol != IPPROTO_TCP) return; - clisten = kmalloc(sizeof(*clisten), GFP_KERNEL); + clisten = kmalloc_obj(*clisten); if (!clisten) return; clisten->cdev = cdev; @@ -238,11 +238,11 @@ static void *chtls_uld_add(const struct cxgb4_lld_info *info) struct chtls_dev *cdev; int i, j; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) goto out; - lldi = kzalloc(sizeof(*lldi), GFP_KERNEL); + lldi = kzalloc_obj(*lldi); if (!lldi) goto out_lldi; diff --git a/drivers/net/ethernet/cisco/enic/enic_clsf.c b/drivers/net/ethernet/cisco/enic/enic_clsf.c index 837f954873ee..581e89da9091 100644 --- a/drivers/net/ethernet/cisco/enic/enic_clsf.c +++ b/drivers/net/ethernet/cisco/enic/enic_clsf.c @@ -235,7 +235,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, struct hlist_head *head; head = &enic->rfs_h.ht_head[tbl_idx]; - d = kmalloc(sizeof(*d), GFP_ATOMIC); + d = kmalloc_obj(*d, GFP_ATOMIC); if (d) { d->fltr_id = n->fltr_id; INIT_HLIST_NODE(&d->node); @@ -257,7 +257,7 @@ int enic_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, goto ret_unlock; } - n = kmalloc(sizeof(*n), GFP_ATOMIC); + n = kmalloc_obj(*n, GFP_ATOMIC); if (!n) { res = -ENOMEM; enic->rfs_h.free++; diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 6bc8dfdb3d4b..e839081f9ee4 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2456,35 +2456,32 @@ static void enic_free_enic_resources(struct enic *enic) static int enic_alloc_enic_resources(struct enic *enic) { - enic->wq = kcalloc(enic->wq_avail, sizeof(struct enic_wq), GFP_KERNEL); + enic->wq = kzalloc_objs(struct enic_wq, enic->wq_avail); if (!enic->wq) goto free_queues; - enic->rq = kcalloc(enic->rq_avail, sizeof(struct enic_rq), GFP_KERNEL); + enic->rq = kzalloc_objs(struct enic_rq, enic->rq_avail); if (!enic->rq) goto free_queues; - enic->cq = kcalloc(enic->cq_avail, sizeof(struct vnic_cq), GFP_KERNEL); + enic->cq = kzalloc_objs(struct vnic_cq, enic->cq_avail); if (!enic->cq) goto free_queues; - enic->napi = kcalloc(enic->wq_avail + enic->rq_avail, - sizeof(struct napi_struct), GFP_KERNEL); + enic->napi = kzalloc_objs(struct napi_struct, + enic->wq_avail + enic->rq_avail); if (!enic->napi) goto free_queues; - enic->msix_entry = kcalloc(enic->intr_avail, sizeof(struct msix_entry), - GFP_KERNEL); + enic->msix_entry = kzalloc_objs(struct msix_entry, enic->intr_avail); if (!enic->msix_entry) goto free_queues; - enic->msix = kcalloc(enic->intr_avail, sizeof(struct enic_msix_entry), - GFP_KERNEL); + enic->msix = kzalloc_objs(struct enic_msix_entry, enic->intr_avail); if (!enic->msix) goto free_queues; - enic->intr = kcalloc(enic->intr_avail, sizeof(struct vnic_intr), - GFP_KERNEL); + enic->intr = kzalloc_objs(struct vnic_intr, enic->intr_avail); if (!enic->intr) goto free_queues; @@ -2737,7 +2734,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #endif /* Allocate structure for port profiles */ - enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL); + enic->pp = kzalloc_objs(*enic->pp, num_pps); if (!enic->pp) { err = -ENOMEM; goto err_out_disable_sriov_pp; diff --git a/drivers/net/ethernet/cisco/enic/vnic_dev.c b/drivers/net/ethernet/cisco/enic/vnic_dev.c index 9f6089e81608..c72452749f5e 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_dev.c +++ b/drivers/net/ethernet/cisco/enic/vnic_dev.c @@ -371,7 +371,7 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev) if (vdev->devcmd2) return 0; - vdev->devcmd2 = kzalloc(sizeof(*vdev->devcmd2), GFP_KERNEL); + vdev->devcmd2 = kzalloc_obj(*vdev->devcmd2); if (!vdev->devcmd2) return -ENOMEM; @@ -1053,7 +1053,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, unsigned int num_bars) { if (!vdev) { - vdev = kzalloc(sizeof(struct vnic_dev), GFP_KERNEL); + vdev = kzalloc_obj(struct vnic_dev); if (!vdev) return NULL; } diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c index 6a2004bbe87f..4824232f4890 100644 --- a/drivers/net/ethernet/cortina/gemini.c +++ b/drivers/net/ethernet/cortina/gemini.c @@ -554,7 +554,7 @@ static int gmac_setup_txqs(struct net_device *netdev) rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; - skb_tab = kcalloc(len, sizeof(*skb_tab), GFP_KERNEL); + skb_tab = kzalloc_objs(*skb_tab, len); if (!skb_tab) return -ENOMEM; @@ -940,8 +940,7 @@ static int geth_setup_freeq(struct gemini_ethernet *geth) } /* Allocate a mapping to page look-up index */ - geth->freeq_pages = kcalloc(pages, sizeof(*geth->freeq_pages), - GFP_KERNEL); + geth->freeq_pages = kzalloc_objs(*geth->freeq_pages, pages); if (!geth->freeq_pages) goto err_freeq; geth->num_freeq_pages = pages; diff --git a/drivers/net/ethernet/ec_bhf.c b/drivers/net/ethernet/ec_bhf.c index 67275aa4f65b..0c86cbb0313c 100644 --- a/drivers/net/ethernet/ec_bhf.c +++ b/drivers/net/ethernet/ec_bhf.c @@ -423,7 +423,7 @@ static int ec_bhf_open(struct net_device *net_dev) error_rx_free: dma_free_coherent(dev, priv->rx_buf.alloc_len, priv->rx_buf.alloc, - priv->rx_buf.alloc_len); + priv->rx_buf.alloc_phys); out: return err; } diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 52e10467b3e4..ed302f5ec476 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -4207,8 +4207,7 @@ static int be_vf_setup_init(struct be_adapter *adapter) struct be_vf_cfg *vf_cfg; int vf; - adapter->vf_cfg = kcalloc(adapter->num_vfs, sizeof(*vf_cfg), - GFP_KERNEL); + adapter->vf_cfg = kzalloc_objs(*vf_cfg, adapter->num_vfs); if (!adapter->vf_cfg) return -ENOMEM; @@ -4686,13 +4685,11 @@ static int be_if_create(struct be_adapter *adapter) if (!adapter->pmac_id) return -ENOMEM; - adapter->mc_list = kcalloc(be_max_mc(adapter), - sizeof(*adapter->mc_list), GFP_KERNEL); + adapter->mc_list = kzalloc_objs(*adapter->mc_list, be_max_mc(adapter)); if (!adapter->mc_list) return -ENOMEM; - adapter->uc_list = kcalloc(be_max_uc(adapter), - sizeof(*adapter->uc_list), GFP_KERNEL); + adapter->uc_list = kzalloc_objs(*adapter->uc_list, be_max_uc(adapter)); if (!adapter->uc_list) return -ENOMEM; @@ -5048,7 +5045,7 @@ static struct be_cmd_work *be_alloc_work(struct be_adapter *adapter, { struct be_cmd_work *work; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { dev_err(&adapter->pdev->dev, "be_work memory allocation failed\n"); diff --git a/drivers/net/ethernet/engleder/tsnep_main.c b/drivers/net/ethernet/engleder/tsnep_main.c index b118407c30e8..5db04e209dc6 100644 --- a/drivers/net/ethernet/engleder/tsnep_main.c +++ b/drivers/net/ethernet/engleder/tsnep_main.c @@ -2102,14 +2102,12 @@ int tsnep_enable_xsk(struct tsnep_queue *queue, struct xsk_buff_pool *pool) if (frame_size < TSNEP_XSK_RX_BUF_SIZE) return -EOPNOTSUPP; - queue->rx->page_buffer = kcalloc(TSNEP_RING_SIZE, - sizeof(*queue->rx->page_buffer), - GFP_KERNEL); + queue->rx->page_buffer = kzalloc_objs(*queue->rx->page_buffer, + TSNEP_RING_SIZE); if (!queue->rx->page_buffer) return -ENOMEM; - queue->rx->xdp_batch = kcalloc(TSNEP_RING_SIZE, - sizeof(*queue->rx->xdp_batch), - GFP_KERNEL); + queue->rx->xdp_batch = kzalloc_objs(*queue->rx->xdp_batch, + TSNEP_RING_SIZE); if (!queue->rx->xdp_batch) { kfree(queue->rx->page_buffer); queue->rx->page_buffer = NULL; diff --git a/drivers/net/ethernet/engleder/tsnep_rxnfc.c b/drivers/net/ethernet/engleder/tsnep_rxnfc.c index 9ac2a0cf3833..43c550d3983c 100644 --- a/drivers/net/ethernet/engleder/tsnep_rxnfc.c +++ b/drivers/net/ethernet/engleder/tsnep_rxnfc.c @@ -231,7 +231,7 @@ int tsnep_rxnfc_add_rule(struct tsnep_adapter *adapter, return -EINVAL; } - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/ethernet/engleder/tsnep_selftests.c b/drivers/net/ethernet/engleder/tsnep_selftests.c index 8a9145f93147..f153da750c43 100644 --- a/drivers/net/ethernet/engleder/tsnep_selftests.c +++ b/drivers/net/ethernet/engleder/tsnep_selftests.c @@ -354,7 +354,7 @@ static bool tsnep_test_taprio(struct tsnep_adapter *adapter) struct tc_taprio_qopt_offload *qopt; int i; - qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); + qopt = kzalloc_flex(*qopt, entries, 255); if (!qopt) return false; for (i = 0; i < 255; i++) @@ -451,7 +451,7 @@ static bool tsnep_test_taprio_change(struct tsnep_adapter *adapter) struct tc_taprio_qopt_offload *qopt; int i; - qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); + qopt = kzalloc_flex(*qopt, entries, 255); if (!qopt) return false; for (i = 0; i < 255; i++) @@ -604,7 +604,7 @@ static bool tsnep_test_taprio_extension(struct tsnep_adapter *adapter) struct tc_taprio_qopt_offload *qopt; int i; - qopt = kzalloc(struct_size(qopt, entries, 255), GFP_KERNEL); + qopt = kzalloc_flex(*qopt, entries, 255); if (!qopt) return false; for (i = 0; i < 255; i++) diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index ed3fa80af8c3..f2c3c5f3b461 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -421,7 +421,7 @@ static int dpaa_set_coalesce(struct net_device *dev, bool *needs_revert; int cpu, res; - needs_revert = kcalloc(num_possible_cpus(), sizeof(bool), GFP_KERNEL); + needs_revert = kzalloc_objs(bool, num_possible_cpus()); if (!needs_revert) return -ENOMEM; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c index 76f808d38066..8775c931106b 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth-devlink.c @@ -237,14 +237,13 @@ int dpaa2_eth_dl_traps_register(struct dpaa2_eth_priv *priv) struct device *dev = net_dev->dev.parent; int err; - dpaa2_eth_trap_data = kzalloc(sizeof(*dpaa2_eth_trap_data), GFP_KERNEL); + dpaa2_eth_trap_data = kzalloc_obj(*dpaa2_eth_trap_data); if (!dpaa2_eth_trap_data) return -ENOMEM; priv->trap_data = dpaa2_eth_trap_data; - dpaa2_eth_trap_data->trap_items_arr = kcalloc(ARRAY_SIZE(dpaa2_eth_traps_arr), - sizeof(struct dpaa2_eth_trap_item), - GFP_KERNEL); + dpaa2_eth_trap_data->trap_items_arr = kzalloc_objs(struct dpaa2_eth_trap_item, + ARRAY_SIZE(dpaa2_eth_traps_arr)); if (!dpaa2_eth_trap_data->trap_items_arr) { err = -ENOMEM; goto trap_data_free; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 18d86badd6ea..9335703768a9 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -920,7 +920,7 @@ static int dpaa2_eth_build_sg_fd(struct dpaa2_eth_priv *priv, if (unlikely(PAGE_SIZE / sizeof(struct scatterlist) < nr_frags + 1)) return -EINVAL; - scl = kmalloc_array(nr_frags + 1, sizeof(struct scatterlist), GFP_ATOMIC); + scl = kmalloc_objs(struct scatterlist, nr_frags + 1, GFP_ATOMIC); if (unlikely(!scl)) return -ENOMEM; @@ -3125,7 +3125,7 @@ static struct dpaa2_eth_channel *dpaa2_eth_alloc_channel(struct dpaa2_eth_priv * struct device *dev = priv->net_dev->dev.parent; int err; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return NULL; @@ -3392,7 +3392,7 @@ struct dpaa2_eth_bp *dpaa2_eth_allocate_dpbp(struct dpaa2_eth_priv *priv) return ERR_PTR(err); } - bp = kzalloc(sizeof(*bp), GFP_KERNEL); + bp = kzalloc_obj(*bp); if (!bp) { err = -ENOMEM; goto err_alloc; @@ -4673,7 +4673,7 @@ static int dpaa2_eth_connect_mac(struct dpaa2_eth_priv *priv) goto out_put_device; } - mac = kzalloc(sizeof(struct dpaa2_mac), GFP_KERNEL); + mac = kzalloc_obj(struct dpaa2_mac); if (!mac) { err = -ENOMEM; goto out_put_device; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c index 701a87370737..5b0f0ac1518a 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c @@ -505,7 +505,7 @@ dpaa2_switch_cls_flower_replace_acl(struct dpaa2_switch_filter_block *block, return -ENOMEM; } - acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); + acl_entry = kzalloc_obj(*acl_entry); if (!acl_entry) return -ENOMEM; @@ -633,7 +633,7 @@ dpaa2_switch_cls_flower_replace_mirror(struct dpaa2_switch_filter_block *block, } } - mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL); + mirror_entry = kzalloc_obj(*mirror_entry); if (!mirror_entry) return -ENOMEM; @@ -708,7 +708,7 @@ dpaa2_switch_cls_matchall_replace_acl(struct dpaa2_switch_filter_block *block, return -ENOMEM; } - acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); + acl_entry = kzalloc_obj(*acl_entry); if (!acl_entry) return -ENOMEM; @@ -780,7 +780,7 @@ dpaa2_switch_cls_matchall_replace_mirror(struct dpaa2_switch_filter_block *block } } - mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL); + mirror_entry = kzalloc_obj(*mirror_entry); if (!mirror_entry) return -ENOMEM; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 66240c340492..52c1cb9cb7e0 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -1456,7 +1456,7 @@ static int dpaa2_switch_port_connect_mac(struct ethsw_port_priv *port_priv) goto out_put_device; } - mac = kzalloc(sizeof(*mac), GFP_KERNEL); + mac = kzalloc_obj(*mac); if (!mac) { err = -ENOMEM; goto out_put_device; @@ -1533,7 +1533,7 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) if_id = (status & 0xFFFF0000) >> 16; if (if_id >= ethsw->sw_attr.num_ifs) { dev_err(dev, "Invalid if_id %d in IRQ status\n", if_id); - goto out; + goto out_clear; } port_priv = ethsw->ports[if_id]; @@ -1553,6 +1553,7 @@ static irqreturn_t dpaa2_switch_irq0_handler_thread(int irq_num, void *arg) dpaa2_switch_port_connect_mac(port_priv); } +out_clear: err = dpsw_clear_irq_status(ethsw->mc_io, 0, ethsw->dpsw_handle, DPSW_IRQ_INDEX_IF, status); if (err) @@ -2334,7 +2335,7 @@ static int dpaa2_switch_port_event(struct notifier_block *nb, if (!dpaa2_switch_port_dev_check(dev)) return NOTIFY_DONE; - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; @@ -3034,6 +3035,13 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) goto err_close; } + if (ethsw->sw_attr.num_ifs >= DPSW_MAX_IF) { + dev_err(dev, "DPSW num_ifs %u exceeds max %u\n", + ethsw->sw_attr.num_ifs, DPSW_MAX_IF); + err = -EINVAL; + goto err_close; + } + err = dpsw_get_api_version(ethsw->mc_io, 0, ðsw->major, ðsw->minor); @@ -3385,7 +3393,7 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) int i, err; /* Allocate switch core*/ - ethsw = kzalloc(sizeof(*ethsw), GFP_KERNEL); + ethsw = kzalloc_obj(*ethsw); if (!ethsw) return -ENOMEM; @@ -3408,23 +3416,20 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) if (err) goto err_free_cmdport; - ethsw->ports = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->ports), - GFP_KERNEL); + ethsw->ports = kzalloc_objs(*ethsw->ports, ethsw->sw_attr.num_ifs); if (!(ethsw->ports)) { err = -ENOMEM; goto err_teardown; } - ethsw->fdbs = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->fdbs), - GFP_KERNEL); + ethsw->fdbs = kzalloc_objs(*ethsw->fdbs, ethsw->sw_attr.num_ifs); if (!ethsw->fdbs) { err = -ENOMEM; goto err_free_ports; } - ethsw->filter_blocks = kcalloc(ethsw->sw_attr.num_ifs, - sizeof(*ethsw->filter_blocks), - GFP_KERNEL); + ethsw->filter_blocks = kzalloc_objs(*ethsw->filter_blocks, + ethsw->sw_attr.num_ifs); if (!ethsw->filter_blocks) { err = -ENOMEM; goto err_free_fdbs; diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index e380a4f39855..a146ceaf2ed6 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -2268,7 +2268,7 @@ enetc_alloc_tx_resources(struct enetc_ndev_priv *priv) struct enetc_bdr_resource *tx_res; int i, err; - tx_res = kcalloc(priv->num_tx_rings, sizeof(*tx_res), GFP_KERNEL); + tx_res = kzalloc_objs(*tx_res, priv->num_tx_rings); if (!tx_res) return ERR_PTR(-ENOMEM); @@ -2340,7 +2340,7 @@ enetc_alloc_rx_resources(struct enetc_ndev_priv *priv, bool extended) struct enetc_bdr_resource *rx_res; int i, err; - rx_res = kcalloc(priv->num_rx_rings, sizeof(*rx_res), GFP_KERNEL); + rx_res = kzalloc_objs(*rx_res, priv->num_rx_rings); if (!rx_res) return ERR_PTR(-ENOMEM); @@ -2469,7 +2469,7 @@ static int enetc_setup_default_rss_table(struct enetc_si *si, int num_groups) int *rss_table; int i; - rss_table = kmalloc_array(si->num_rss, sizeof(*rss_table), GFP_KERNEL); + rss_table = kmalloc_objs(*rss_table, si->num_rss); if (!rss_table) return -ENOMEM; @@ -2562,8 +2562,7 @@ int enetc_alloc_si_resources(struct enetc_ndev_priv *priv) { struct enetc_si *si = priv->si; - priv->cls_rules = kcalloc(si->num_fs_entries, sizeof(*priv->cls_rules), - GFP_KERNEL); + priv->cls_rules = kzalloc_objs(*priv->cls_rules, si->num_fs_entries); if (!priv->cls_rules) return -ENOMEM; @@ -3454,7 +3453,7 @@ static int enetc_int_vector_init(struct enetc_ndev_priv *priv, int i, struct enetc_bdr *bdr; int j, err; - v = kzalloc(struct_size(v, tx_ring, v_tx_rings), GFP_KERNEL); + v = kzalloc_flex(*v, tx_ring, v_tx_rings); if (!v) return -ENOMEM; @@ -3468,7 +3467,7 @@ static int enetc_int_vector_init(struct enetc_ndev_priv *priv, int i, priv->rx_ring[i] = bdr; err = __xdp_rxq_info_reg(&bdr->xdp.rxq, priv->ndev, i, 0, - ENETC_RXB_DMA_SIZE_XDP); + ENETC_RXB_TRUESIZE); if (err) goto free_vector; diff --git a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c index 5850540634b0..689b9f13c5eb 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc4_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc4_pf.c @@ -192,7 +192,7 @@ static int enetc4_pf_set_uc_exact_filter(struct enetc_pf *pf) goto unlock_netif_addr; } - mac_tbl = kcalloc(mac_cnt, sizeof(*mac_tbl), GFP_ATOMIC); + mac_tbl = kzalloc_objs(*mac_tbl, mac_cnt, GFP_ATOMIC); if (!mac_tbl) { err = -ENOMEM; goto unlock_netif_addr; diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c index de0fb272c847..a12fd54a475f 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c @@ -814,7 +814,7 @@ static int enetc_init_port_rss_memory(struct enetc_si *si) if (!num_rss) return 0; - rss_table = kcalloc(num_rss, sizeof(*rss_table), GFP_KERNEL); + rss_table = kzalloc_objs(*rss_table, num_rss); if (!rss_table) return -ENOMEM; @@ -958,8 +958,8 @@ static int enetc_pf_probe(struct pci_dev *pdev, pf->total_vfs = pci_sriov_get_totalvfs(pdev); if (pf->total_vfs) { - pf->vf_state = kcalloc(pf->total_vfs, sizeof(struct enetc_vf_state), - GFP_KERNEL); + pf->vf_state = kzalloc_objs(struct enetc_vf_state, + pf->total_vfs); if (!pf->vf_state) goto err_alloc_vf_state; } diff --git a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c index b8413d3b4f16..162cbc801730 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_ptp.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_ptp.c @@ -53,7 +53,7 @@ static int enetc_ptp_probe(struct pci_dev *pdev, pci_set_master(pdev); - ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL); + ptp_qoriq = kzalloc_obj(*ptp_qoriq); if (!ptp_qoriq) { err = -ENOMEM; goto err_alloc_ptp; diff --git a/drivers/net/ethernet/freescale/enetc/enetc_qos.c b/drivers/net/ethernet/freescale/enetc/enetc_qos.c index ccf86651455c..7b17bca24f26 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_qos.c +++ b/drivers/net/ethernet/freescale/enetc/enetc_qos.c @@ -1153,7 +1153,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, if (!entryg) return -EINVAL; - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; @@ -1266,7 +1266,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, filter->sgi_index = sgi->index; - sfi = kzalloc(sizeof(*sfi), GFP_KERNEL); + sfi = kzalloc_obj(*sfi); if (!sfi) { err = -ENOMEM; goto free_gate; @@ -1283,7 +1283,7 @@ static int enetc_psfp_parse_clsflower(struct enetc_ndev_priv *priv, goto free_sfi; if (entryp->police.burst) { - fmi = kzalloc(sizeof(*fmi), GFP_KERNEL); + fmi = kzalloc_obj(*fmi); if (!fmi) { err = -ENOMEM; goto free_sfi; diff --git a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c index 7fd39f895290..92a0f824dae7 100644 --- a/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c +++ b/drivers/net/ethernet/freescale/enetc/netc_blk_ctrl.c @@ -333,11 +333,13 @@ static int netc_get_phy_addr(struct device_node *np) mdio_node = of_get_child_by_name(np, "mdio"); if (!mdio_node) - return 0; + return -ENODEV; phy_node = of_get_next_child(mdio_node, NULL); - if (!phy_node) + if (!phy_node) { + err = -ENODEV; goto of_put_mdio_node; + } err = of_property_read_u32(phy_node, "reg", &addr); if (err) @@ -423,6 +425,9 @@ static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev) addr = netc_get_phy_addr(gchild); if (addr < 0) { + if (addr == -ENODEV) + continue; + dev_err(dev, "Failed to get PHY address\n"); return addr; } @@ -433,12 +438,6 @@ static int imx95_enetc_mdio_phyaddr_config(struct platform_device *pdev) return -EINVAL; } - /* The default value of LaBCR[MDIO_PHYAD_PRTAD ] is - * 0, so no need to set the register. - */ - if (!addr) - continue; - switch (bus_devfn) { case IMX95_ENETC0_BUS_DEVFN: netc_reg_write(priv->ierb, IERB_LBCR(0), @@ -578,16 +577,13 @@ static int imx94_enetc_mdio_phyaddr_config(struct netc_blk_ctrl *priv, addr = netc_get_phy_addr(np); if (addr < 0) { + if (addr == -ENODEV) + return 0; + dev_err(dev, "Failed to get PHY address\n"); return addr; } - /* The default value of LaBCR[MDIO_PHYAD_PRTAD] is 0, - * so no need to set the register. - */ - if (!addr) - return 0; - if (phy_mask & BIT(addr)) { dev_err(dev, "Find same PHY address in EMDIO and ENETC node\n"); diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 0d926bf18195..f89aa94ce020 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3952,7 +3952,7 @@ static int fec_enet_alloc_queue(struct net_device *ndev) struct fec_enet_priv_tx_q *txq; for (i = 0; i < fep->num_tx_queues; i++) { - txq = kzalloc(sizeof(*txq), GFP_KERNEL); + txq = kzalloc_obj(*txq); if (!txq) { ret = -ENOMEM; goto alloc_failed; @@ -3975,8 +3975,7 @@ static int fec_enet_alloc_queue(struct net_device *ndev) } for (i = 0; i < fep->num_rx_queues; i++) { - fep->rx_queue[i] = kzalloc(sizeof(*fep->rx_queue[i]), - GFP_KERNEL); + fep->rx_queue[i] = kzalloc_obj(*fep->rx_queue[i]); if (!fep->rx_queue[i]) { ret = -ENOMEM; goto alloc_failed; @@ -4426,7 +4425,7 @@ fec_alloc_new_rxq_xsk(struct fec_enet_private *fep, int queue, union fec_rx_buffer *buf; int i; - rxq = kzalloc(sizeof(*rxq), GFP_KERNEL); + rxq = kzalloc_obj(*rxq); if (!rxq) return NULL; @@ -4467,7 +4466,7 @@ fec_alloc_new_rxq_pp(struct fec_enet_private *fep, int queue) union fec_rx_buffer *buf; int i = 0; - rxq = kzalloc(sizeof(*rxq), GFP_KERNEL); + rxq = kzalloc_obj(*rxq); if (!rxq) return NULL; diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c index 3d073f0fae63..d48a1c4d0431 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c +++ b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c @@ -74,7 +74,7 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of) bus = mdiobus_alloc(); if (bus == NULL) return -ENOMEM; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) { err = -ENOMEM; goto out_free; diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c index 11887458f050..013273a2de32 100644 --- a/drivers/net/ethernet/freescale/fman/fman.c +++ b/drivers/net/ethernet/freescale/fman/fman.c @@ -1688,12 +1688,12 @@ static int fman_config(struct fman *fman) base_addr = fman->dts_params.base_addr; - fman->state = kzalloc(sizeof(*fman->state), GFP_KERNEL); + fman->state = kzalloc_obj(*fman->state); if (!fman->state) goto err_fm_state; /* Allocate the FM driver's parameters structure */ - fman->cfg = kzalloc(sizeof(*fman->cfg), GFP_KERNEL); + fman->cfg = kzalloc_obj(*fman->cfg); if (!fman->cfg) goto err_fm_drv; @@ -2697,7 +2697,7 @@ static struct fman *read_dts_node(struct platform_device *of_dev) struct clk *clk; u32 clk_rate; - fman = kzalloc(sizeof(*fman), GFP_KERNEL); + fman = kzalloc_obj(*fman); if (!fman) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c index 51402dff72c5..fe35703c509e 100644 --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c @@ -1055,7 +1055,7 @@ static int dtsec_add_hash_mac_address(struct fman_mac *dtsec, set_bucket(dtsec->regs, bucket, true); /* Create element to be added to the driver hash table */ - hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC); + hash_entry = kmalloc_obj(*hash_entry, GFP_ATOMIC); if (!hash_entry) return -ENOMEM; hash_entry->addr = addr; @@ -1348,12 +1348,12 @@ static struct fman_mac *dtsec_config(struct mac_device *mac_dev, struct dtsec_cfg *dtsec_drv_param; /* allocate memory for the UCC GETH data structure. */ - dtsec = kzalloc(sizeof(*dtsec), GFP_KERNEL); + dtsec = kzalloc_obj(*dtsec); if (!dtsec) return NULL; /* allocate memory for the d_tsec driver parameters data structure. */ - dtsec_drv_param = kzalloc(sizeof(*dtsec_drv_param), GFP_KERNEL); + dtsec_drv_param = kzalloc_obj(*dtsec_drv_param); if (!dtsec_drv_param) goto err_dtsec; diff --git a/drivers/net/ethernet/freescale/fman/fman_keygen.c b/drivers/net/ethernet/freescale/fman/fman_keygen.c index e73f6ef3c6ee..74641348d49a 100644 --- a/drivers/net/ethernet/freescale/fman/fman_keygen.c +++ b/drivers/net/ethernet/freescale/fman/fman_keygen.c @@ -629,7 +629,7 @@ struct fman_keygen *keygen_init(struct fman_kg_regs __iomem *keygen_regs) int i; /* Allocate memory for KeyGen driver */ - keygen = kzalloc(sizeof(*keygen), GFP_KERNEL); + keygen = kzalloc_obj(*keygen); if (!keygen) return NULL; diff --git a/drivers/net/ethernet/freescale/fman/fman_mac.h b/drivers/net/ethernet/freescale/fman/fman_mac.h index e5d6cddea731..85444f6f8f9d 100644 --- a/drivers/net/ethernet/freescale/fman/fman_mac.h +++ b/drivers/net/ethernet/freescale/fman/fman_mac.h @@ -224,14 +224,13 @@ static inline struct eth_hash_t *alloc_hash_table(u16 size) struct eth_hash_t *hash; /* Allocate address hash table */ - hash = kmalloc(sizeof(*hash), GFP_KERNEL); + hash = kmalloc_obj(*hash); if (!hash) return NULL; hash->size = size; - hash->lsts = kmalloc_array(hash->size, sizeof(struct list_head), - GFP_KERNEL); + hash->lsts = kmalloc_objs(struct list_head, hash->size); if (!hash->lsts) { kfree(hash); return NULL; diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c index c84f0336c94c..e2d8c58deef0 100644 --- a/drivers/net/ethernet/freescale/fman/fman_memac.c +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c @@ -811,7 +811,7 @@ static int memac_add_hash_mac_address(struct fman_mac *memac, hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; /* Create element to be added to the driver hash table */ - hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC); + hash_entry = kmalloc_obj(*hash_entry, GFP_ATOMIC); if (!hash_entry) return -ENOMEM; hash_entry->addr = addr; @@ -1086,12 +1086,12 @@ static struct fman_mac *memac_config(struct mac_device *mac_dev, struct memac_cfg *memac_drv_param; /* allocate memory for the m_emac data structure */ - memac = kzalloc(sizeof(*memac), GFP_KERNEL); + memac = kzalloc_obj(*memac); if (!memac) return NULL; /* allocate memory for the m_emac driver parameters data structure */ - memac_drv_param = kzalloc(sizeof(*memac_drv_param), GFP_KERNEL); + memac_drv_param = kzalloc_obj(*memac_drv_param); if (!memac_drv_param) { memac_free(memac); return NULL; diff --git a/drivers/net/ethernet/freescale/fman/fman_muram.c b/drivers/net/ethernet/freescale/fman/fman_muram.c index 1ed245a2ee01..6ac7c2b0cb19 100644 --- a/drivers/net/ethernet/freescale/fman/fman_muram.c +++ b/drivers/net/ethernet/freescale/fman/fman_muram.c @@ -40,7 +40,7 @@ struct muram_info *fman_muram_init(phys_addr_t base, size_t size) void __iomem *vaddr; int ret; - muram = kzalloc(sizeof(*muram), GFP_KERNEL); + muram = kzalloc_obj(*muram); if (!muram) return NULL; diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c index e977389f7088..1b8fef69114e 100644 --- a/drivers/net/ethernet/freescale/fman/fman_port.c +++ b/drivers/net/ethernet/freescale/fman/fman_port.c @@ -1297,7 +1297,7 @@ int fman_port_config(struct fman_port *port, struct fman_port_params *params) int err; /* Allocate the FM driver's parameters structure */ - port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL); + port->cfg = kzalloc_obj(*port->cfg); if (!port->cfg) return -EINVAL; @@ -1753,7 +1753,7 @@ static int fman_port_probe(struct platform_device *of_dev) u16 port_speed; u8 port_id; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c index fecfca6eba03..23db0bc6656c 100644 --- a/drivers/net/ethernet/freescale/fman/fman_tgec.c +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c @@ -505,7 +505,7 @@ static int tgec_add_hash_mac_address(struct fman_mac *tgec, hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK; /* Create element to be added to the driver hash table */ - hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC); + hash_entry = kmalloc_obj(*hash_entry, GFP_ATOMIC); if (!hash_entry) return -ENOMEM; hash_entry->addr = addr; @@ -711,12 +711,12 @@ static struct fman_mac *tgec_config(struct mac_device *mac_dev, struct tgec_cfg *cfg; /* allocate memory for the UCC GETH data structure. */ - tgec = kzalloc(sizeof(*tgec), GFP_KERNEL); + tgec = kzalloc_obj(*tgec); if (!tgec) return NULL; /* allocate memory for the 10G MAC driver parameters data structure. */ - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) { tgec_free(tgec); return NULL; diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c index f563692a4a00..2cbcc29408e3 100644 --- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c +++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c @@ -866,7 +866,7 @@ static int fs_enet_probe(struct platform_device *ofdev) if (!ops) return -EINVAL; - fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); + fpi = kzalloc_obj(*fpi); if (!fpi) return -ENOMEM; diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 66038e2a4ae3..33a3eef41723 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c @@ -152,7 +152,7 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev) struct bb_info *bitbang; int ret = -ENOMEM; - bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); + bitbang = kzalloc_obj(struct bb_info); if (!bitbang) goto out; diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index dec31b638941..4774dc49c331 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c @@ -108,7 +108,7 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev) if (!new_bus) goto out; - fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL); + fec = kzalloc_obj(struct fec_info); if (!fec) goto out_mii; diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 7c0f049f0938..3271de5844f8 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -413,8 +413,7 @@ static int gfar_alloc_tx_queues(struct gfar_private *priv) int i; for (i = 0; i < priv->num_tx_queues; i++) { - priv->tx_queue[i] = kzalloc(sizeof(struct gfar_priv_tx_q), - GFP_KERNEL); + priv->tx_queue[i] = kzalloc_obj(struct gfar_priv_tx_q); if (!priv->tx_queue[i]) return -ENOMEM; @@ -431,8 +430,7 @@ static int gfar_alloc_rx_queues(struct gfar_private *priv) int i; for (i = 0; i < priv->num_rx_queues; i++) { - priv->rx_queue[i] = kzalloc(sizeof(struct gfar_priv_rx_q), - GFP_KERNEL); + priv->rx_queue[i] = kzalloc_obj(struct gfar_priv_rx_q); if (!priv->rx_queue[i]) return -ENOMEM; @@ -507,8 +505,7 @@ static int gfar_parse_group(struct device_node *np, int i; for (i = 0; i < GFAR_NUM_IRQS; i++) { - grp->irqinfo[i] = kzalloc(sizeof(struct gfar_irqinfo), - GFP_KERNEL); + grp->irqinfo[i] = kzalloc_obj(struct gfar_irqinfo); if (!grp->irqinfo[i]) return -ENOMEM; } @@ -1376,9 +1373,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) for (i = 0; i < priv->num_tx_queues; i++) { tx_queue = priv->tx_queue[i]; tx_queue->tx_skbuff = - kmalloc_array(tx_queue->tx_ring_size, - sizeof(*tx_queue->tx_skbuff), - GFP_KERNEL); + kmalloc_objs(*tx_queue->tx_skbuff, + tx_queue->tx_ring_size); if (!tx_queue->tx_skbuff) goto cleanup; @@ -1388,9 +1384,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev) for (i = 0; i < priv->num_rx_queues; i++) { rx_queue = priv->rx_queue[i]; - rx_queue->rx_buff = kcalloc(rx_queue->rx_ring_size, - sizeof(*rx_queue->rx_buff), - GFP_KERNEL); + rx_queue->rx_buff = kzalloc_objs(*rx_queue->rx_buff, + rx_queue->rx_ring_size); if (!rx_queue->rx_buff) goto cleanup; } diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 6fa752d3b60d..e8edef6505bf 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1241,7 +1241,7 @@ static int gfar_process_filer_changes(struct gfar_private *priv) s32 ret = 0; /* So index is set to zero, too! */ - tab = kzalloc(sizeof(*tab), GFP_KERNEL); + tab = kzalloc_obj(*tab); if (tab == NULL) return -ENOMEM; @@ -1293,7 +1293,7 @@ static int gfar_add_cls(struct gfar_private *priv, struct ethtool_flow_spec_container *temp, *comp; int ret = 0; - temp = kmalloc(sizeof(*temp), GFP_KERNEL); + temp = kmalloc_obj(*temp); if (temp == NULL) return -ENOMEM; memcpy(&temp->fs, flow, sizeof(temp->fs)); diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 131d1210dc4a..3607681650ce 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -2071,8 +2071,8 @@ static int ucc_geth_alloc_tx(struct ucc_geth_private *ugeth) for (j = 0; j < ucc_geth_tx_queues(ug_info); j++) { /* Setup the skbuff rings */ ugeth->tx_skbuff[j] = - kcalloc(ugeth->ug_info->bdRingLenTx[j], - sizeof(struct sk_buff *), GFP_KERNEL); + kzalloc_objs(struct sk_buff *, + ugeth->ug_info->bdRingLenTx[j]); if (ugeth->tx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) @@ -2129,8 +2129,8 @@ static int ucc_geth_alloc_rx(struct ucc_geth_private *ugeth) for (j = 0; j < ucc_geth_rx_queues(ug_info); j++) { /* Setup the skbuff rings */ ugeth->rx_skbuff[j] = - kcalloc(ugeth->ug_info->bdRingLenRx[j], - sizeof(struct sk_buff *), GFP_KERNEL); + kzalloc_objs(struct sk_buff *, + ugeth->ug_info->bdRingLenRx[j]); if (ugeth->rx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) @@ -2677,7 +2677,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) * allocated resources can be released when the channel is freed. */ if (!(ugeth->p_init_enet_param_shadow = - kzalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) { + kzalloc_obj(struct ucc_geth_init_pram))) { if (netif_msg_ifup(ugeth)) pr_err("Can not allocate memory for p_UccInitEnetParamShadows\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/fungible/funcore/fun_dev.c b/drivers/net/ethernet/fungible/funcore/fun_dev.c index ce97b76f9ae0..a62ae88800f7 100644 --- a/drivers/net/ethernet/fungible/funcore/fun_dev.c +++ b/drivers/net/ethernet/fungible/funcore/fun_dev.c @@ -210,7 +210,7 @@ static int fun_init_cmd_ctx(struct fun_dev *fdev, unsigned int ntags) { unsigned int i; - fdev->cmd_ctx = kvcalloc(ntags, sizeof(*fdev->cmd_ctx), GFP_KERNEL); + fdev->cmd_ctx = kvzalloc_objs(*fdev->cmd_ctx, ntags); if (!fdev->cmd_ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/fungible/funcore/fun_queue.c b/drivers/net/ethernet/fungible/funcore/fun_queue.c index d07ee3e4f52a..0eca751a9534 100644 --- a/drivers/net/ethernet/fungible/funcore/fun_queue.c +++ b/drivers/net/ethernet/fungible/funcore/fun_queue.c @@ -405,7 +405,7 @@ void fun_free_queue(struct fun_queue *funq) struct fun_queue *fun_alloc_queue(struct fun_dev *fdev, int qid, const struct fun_queue_alloc_req *req) { - struct fun_queue *funq = kzalloc(sizeof(*funq), GFP_KERNEL); + struct fun_queue *funq = kzalloc_obj(*funq); if (!funq) return NULL; diff --git a/drivers/net/ethernet/fungible/funeth/funeth_main.c b/drivers/net/ethernet/fungible/funeth/funeth_main.c index 792cddac6f1b..bad8276d26b0 100644 --- a/drivers/net/ethernet/fungible/funeth/funeth_main.c +++ b/drivers/net/ethernet/fungible/funeth/funeth_main.c @@ -424,7 +424,7 @@ static struct funeth_txq **alloc_xdpqs(struct net_device *dev, unsigned int nqs, unsigned int i; int err; - xdpqs = kcalloc(nqs, sizeof(*xdpqs), GFP_KERNEL); + xdpqs = kzalloc_objs(*xdpqs, nqs); if (!xdpqs) return ERR_PTR(-ENOMEM); @@ -486,7 +486,7 @@ static int fun_alloc_rings(struct net_device *netdev, struct fun_qset *qset) if (err) return err; - rxqs = kcalloc(qset->ntxqs + qset->nrxqs, sizeof(*rxqs), GFP_KERNEL); + rxqs = kzalloc_objs(*rxqs, qset->ntxqs + qset->nrxqs); if (!rxqs) return -ENOMEM; @@ -1175,7 +1175,7 @@ static int fun_init_vports(struct fun_ethdev *ed, unsigned int n) if (ed->num_vports) return -EINVAL; - ed->vport_info = kvcalloc(n, sizeof(*ed->vport_info), GFP_KERNEL); + ed->vport_info = kvzalloc_objs(*ed->vport_info, n); if (!ed->vport_info) return -ENOMEM; ed->num_vports = n; @@ -1833,7 +1833,7 @@ static int fun_create_ports(struct fun_ethdev *ed, unsigned int nports) return -EINVAL; } - ed->netdevs = kcalloc(nports, sizeof(*ed->netdevs), GFP_KERNEL); + ed->netdevs = kzalloc_objs(*ed->netdevs, nports); if (!ed->netdevs) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_ethtool.c b/drivers/net/ethernet/google/gve/gve_ethtool.c index 42a0a6f7b296..dc2213b5ce24 100644 --- a/drivers/net/ethernet/google/gve/gve_ethtool.c +++ b/drivers/net/ethernet/google/gve/gve_ethtool.c @@ -176,8 +176,7 @@ gve_get_ethtool_stats(struct net_device *netdev, priv = netdev_priv(netdev); num_tx_queues = gve_num_tx_queues(priv); report_stats = priv->stats_report->stats; - rx_qid_to_stats_idx = kmalloc_array(priv->rx_cfg.num_queues, - sizeof(int), GFP_KERNEL); + rx_qid_to_stats_idx = kmalloc_objs(int, priv->rx_cfg.num_queues); if (!rx_qid_to_stats_idx) return; for (ring = 0; ring < priv->rx_cfg.num_queues; ring++) { @@ -185,8 +184,7 @@ gve_get_ethtool_stats(struct net_device *netdev, if (!gve_rx_was_added_to_block(priv, ring)) num_stopped_rxqs++; } - tx_qid_to_stats_idx = kmalloc_array(num_tx_queues, - sizeof(int), GFP_KERNEL); + tx_qid_to_stats_idx = kmalloc_objs(int, num_tx_queues); if (!tx_qid_to_stats_idx) { kfree(rx_qid_to_stats_idx); return; diff --git a/drivers/net/ethernet/google/gve/gve_flow_rule.c b/drivers/net/ethernet/google/gve/gve_flow_rule.c index 0bb8cd1876a3..2c80cda28ef3 100644 --- a/drivers/net/ethernet/google/gve/gve_flow_rule.c +++ b/drivers/net/ethernet/google/gve/gve_flow_rule.c @@ -269,7 +269,7 @@ int gve_add_flow_rule(struct gve_priv *priv, struct ethtool_rxnfc *cmd) if (!priv->max_flow_rules) return -EOPNOTSUPP; - rule = kvzalloc(sizeof(*rule), GFP_KERNEL); + rule = kvzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_main.c b/drivers/net/ethernet/google/gve/gve_main.c index 0ee864b0afe0..9eb4b3614c4f 100644 --- a/drivers/net/ethernet/google/gve/gve_main.c +++ b/drivers/net/ethernet/google/gve/gve_main.c @@ -151,8 +151,8 @@ static int gve_alloc_flow_rule_caches(struct gve_priv *priv) return 0; flow_rules_cache->rules_cache = - kvcalloc(GVE_FLOW_RULES_CACHE_SIZE, sizeof(*flow_rules_cache->rules_cache), - GFP_KERNEL); + kvzalloc_objs(*flow_rules_cache->rules_cache, + GVE_FLOW_RULES_CACHE_SIZE); if (!flow_rules_cache->rules_cache) { dev_err(&priv->pdev->dev, "Cannot alloc flow rules cache\n"); return -ENOMEM; @@ -485,8 +485,8 @@ static int gve_alloc_notify_blocks(struct gve_priv *priv) int i, j; int err; - priv->msix_vectors = kvcalloc(num_vecs_requested, - sizeof(*priv->msix_vectors), GFP_KERNEL); + priv->msix_vectors = kvzalloc_objs(*priv->msix_vectors, + num_vecs_requested); if (!priv->msix_vectors) return -ENOMEM; for (i = 0; i < num_vecs_requested; i++) @@ -666,8 +666,7 @@ static int gve_setup_device_resources(struct gve_priv *priv) } if (!gve_is_gqi(priv)) { - priv->ptype_lut_dqo = kvzalloc(sizeof(*priv->ptype_lut_dqo), - GFP_KERNEL); + priv->ptype_lut_dqo = kvzalloc_obj(*priv->ptype_lut_dqo); if (!priv->ptype_lut_dqo) { err = -ENOMEM; goto abort_with_stats_report; @@ -1090,17 +1089,17 @@ struct gve_queue_page_list *gve_alloc_queue_page_list(struct gve_priv *priv, int err; int i; - qpl = kvzalloc(sizeof(*qpl), GFP_KERNEL); + qpl = kvzalloc_obj(*qpl); if (!qpl) return NULL; qpl->id = id; qpl->num_entries = 0; - qpl->pages = kvcalloc(pages, sizeof(*qpl->pages), GFP_KERNEL); + qpl->pages = kvzalloc_objs(*qpl->pages, pages); if (!qpl->pages) goto abort; - qpl->page_buses = kvcalloc(pages, sizeof(*qpl->page_buses), GFP_KERNEL); + qpl->page_buses = kvzalloc_objs(*qpl->page_buses, pages); if (!qpl->page_buses) goto abort; diff --git a/drivers/net/ethernet/google/gve/gve_ptp.c b/drivers/net/ethernet/google/gve/gve_ptp.c index de42fc2c19a1..06b1cf4a5efc 100644 --- a/drivers/net/ethernet/google/gve/gve_ptp.c +++ b/drivers/net/ethernet/google/gve/gve_ptp.c @@ -70,7 +70,7 @@ static int gve_ptp_init(struct gve_priv *priv) struct gve_ptp *ptp; int err; - priv->ptp = kzalloc(sizeof(*priv->ptp), GFP_KERNEL); + priv->ptp = kzalloc_obj(*priv->ptp); if (!priv->ptp) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_rx.c b/drivers/net/ethernet/google/gve/gve_rx.c index ec424d2f4f57..4eb6ed29d3cc 100644 --- a/drivers/net/ethernet/google/gve/gve_rx.c +++ b/drivers/net/ethernet/google/gve/gve_rx.c @@ -390,8 +390,7 @@ int gve_rx_alloc_rings_gqi(struct gve_priv *priv, int err = 0; int i, j; - rx = kvcalloc(cfg->qcfg_rx->max_queues, sizeof(struct gve_rx_ring), - GFP_KERNEL); + rx = kvzalloc_objs(struct gve_rx_ring, cfg->qcfg_rx->max_queues); if (!rx) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_rx_dqo.c b/drivers/net/ethernet/google/gve/gve_rx_dqo.c index 63a96106a693..c706c7932159 100644 --- a/drivers/net/ethernet/google/gve/gve_rx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_rx_dqo.c @@ -320,8 +320,7 @@ int gve_rx_alloc_rings_dqo(struct gve_priv *priv, int err; int i; - rx = kvcalloc(cfg->qcfg_rx->max_queues, sizeof(struct gve_rx_ring), - GFP_KERNEL); + rx = kvzalloc_objs(struct gve_rx_ring, cfg->qcfg_rx->max_queues); if (!rx) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_tx.c b/drivers/net/ethernet/google/gve/gve_tx.c index 97efc8d27e6f..0b856e269eac 100644 --- a/drivers/net/ethernet/google/gve/gve_tx.c +++ b/drivers/net/ethernet/google/gve/gve_tx.c @@ -345,8 +345,7 @@ int gve_tx_alloc_rings_gqi(struct gve_priv *priv, return -EINVAL; } - tx = kvcalloc(cfg->qcfg->max_queues, sizeof(struct gve_tx_ring), - GFP_KERNEL); + tx = kvzalloc_objs(struct gve_tx_ring, cfg->qcfg->max_queues); if (!tx) return -ENOMEM; diff --git a/drivers/net/ethernet/google/gve/gve_tx_dqo.c b/drivers/net/ethernet/google/gve/gve_tx_dqo.c index 28e85730f785..4db9d4f9ed6f 100644 --- a/drivers/net/ethernet/google/gve/gve_tx_dqo.c +++ b/drivers/net/ethernet/google/gve/gve_tx_dqo.c @@ -167,6 +167,25 @@ gve_free_pending_packet(struct gve_tx_ring *tx, } } +static void gve_unmap_packet(struct device *dev, + struct gve_tx_pending_packet_dqo *pkt) +{ + int i; + + if (!pkt->num_bufs) + return; + + /* SKB linear portion is guaranteed to be mapped */ + dma_unmap_single(dev, dma_unmap_addr(pkt, dma[0]), + dma_unmap_len(pkt, len[0]), DMA_TO_DEVICE); + for (i = 1; i < pkt->num_bufs; i++) { + netmem_dma_unmap_page_attrs(dev, dma_unmap_addr(pkt, dma[i]), + dma_unmap_len(pkt, len[i]), + DMA_TO_DEVICE, 0); + } + pkt->num_bufs = 0; +} + /* gve_tx_free_desc - Cleans up all pending tx requests and buffers. */ static void gve_tx_clean_pending_packets(struct gve_tx_ring *tx) @@ -176,21 +195,12 @@ static void gve_tx_clean_pending_packets(struct gve_tx_ring *tx) for (i = 0; i < tx->dqo.num_pending_packets; i++) { struct gve_tx_pending_packet_dqo *cur_state = &tx->dqo.pending_packets[i]; - int j; - for (j = 0; j < cur_state->num_bufs; j++) { - if (j == 0) { - dma_unmap_single(tx->dev, - dma_unmap_addr(cur_state, dma[j]), - dma_unmap_len(cur_state, len[j]), - DMA_TO_DEVICE); - } else { - dma_unmap_page(tx->dev, - dma_unmap_addr(cur_state, dma[j]), - dma_unmap_len(cur_state, len[j]), - DMA_TO_DEVICE); - } - } + if (tx->dqo.qpl) + gve_free_tx_qpl_bufs(tx, cur_state); + else + gve_unmap_packet(tx->dev, cur_state); + if (cur_state->skb) { dev_consume_skb_any(cur_state->skb); cur_state->skb = NULL; @@ -266,9 +276,8 @@ static int gve_tx_qpl_buf_init(struct gve_tx_ring *tx) tx->dqo.qpl->num_entries; int i; - tx->dqo.tx_qpl_buf_next = kvcalloc(num_tx_qpl_bufs, - sizeof(tx->dqo.tx_qpl_buf_next[0]), - GFP_KERNEL); + tx->dqo.tx_qpl_buf_next = kvzalloc_objs(tx->dqo.tx_qpl_buf_next[0], + num_tx_qpl_bufs); if (!tx->dqo.tx_qpl_buf_next) return -ENOMEM; @@ -337,9 +346,8 @@ static int gve_tx_alloc_ring_dqo(struct gve_priv *priv, num_pending_packets /= 2; tx->dqo.num_pending_packets = min_t(int, num_pending_packets, S16_MAX); - tx->dqo.pending_packets = kvcalloc(tx->dqo.num_pending_packets, - sizeof(tx->dqo.pending_packets[0]), - GFP_KERNEL); + tx->dqo.pending_packets = kvzalloc_objs(tx->dqo.pending_packets[0], + tx->dqo.num_pending_packets); if (!tx->dqo.pending_packets) goto err; @@ -417,8 +425,7 @@ int gve_tx_alloc_rings_dqo(struct gve_priv *priv, return -EINVAL; } - tx = kvcalloc(cfg->qcfg->max_queues, sizeof(struct gve_tx_ring), - GFP_KERNEL); + tx = kvzalloc_objs(struct gve_tx_ring, cfg->qcfg->max_queues); if (!tx) return -ENOMEM; @@ -1157,22 +1164,6 @@ static void remove_from_list(struct gve_tx_ring *tx, } } -static void gve_unmap_packet(struct device *dev, - struct gve_tx_pending_packet_dqo *pkt) -{ - int i; - - /* SKB linear portion is guaranteed to be mapped */ - dma_unmap_single(dev, dma_unmap_addr(pkt, dma[0]), - dma_unmap_len(pkt, len[0]), DMA_TO_DEVICE); - for (i = 1; i < pkt->num_bufs; i++) { - netmem_dma_unmap_page_attrs(dev, dma_unmap_addr(pkt, dma[i]), - dma_unmap_len(pkt, len[i]), - DMA_TO_DEVICE, 0); - } - pkt->num_bufs = 0; -} - /* Completion types and expected behavior: * No Miss compl + Packet compl = Packet completed normally. * Miss compl + Re-inject compl = Packet completed normally. diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index d4293f76d69d..f7653aa9a24a 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -208,8 +208,7 @@ hnae_init_ring(struct hnae_queue *q, struct hnae_ring *ring, int flags) assert(ring->next_to_use == 0); assert(ring->next_to_clean == 0); - ring->desc_cb = kcalloc(ring->desc_num, sizeof(ring->desc_cb[0]), - GFP_KERNEL); + ring->desc_cb = kzalloc_objs(ring->desc_cb[0], ring->desc_num); if (!ring->desc_cb) { ret = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index 8ce910f8d0cc..47c25692b91c 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -81,8 +81,7 @@ static struct hnae_handle *hns_ae_get_handle(struct hnae_ae_dev *dev, vfnum_per_port = hns_ae_get_vf_num_per_port(dsaf_dev, port_id); qnum_per_vf = hns_ae_get_q_num_per_vf(dsaf_dev, port_id); - vf_cb = kzalloc(struct_size(vf_cb, ae_handle.qs, qnum_per_vf), - GFP_KERNEL); + vf_cb = kzalloc_flex(*vf_cb, ae_handle.qs, qnum_per_vf); if (unlikely(!vf_cb)) { dev_err(dsaf_dev->dev, "malloc vf_cb fail!\n"); ae_handle = ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c index 6d746a9fb687..9cb7ce9fd311 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c @@ -1099,8 +1099,8 @@ static struct hns3_enet_ring *hns3_backup_ringparam(struct hns3_nic_priv *priv) struct hns3_enet_ring *tmp_rings; int i; - tmp_rings = kcalloc(handle->kinfo.num_tqps * 2, - sizeof(struct hns3_enet_ring), GFP_KERNEL); + tmp_rings = kzalloc_objs(struct hns3_enet_ring, + handle->kinfo.num_tqps * 2); if (!tmp_rings) return NULL; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c index b76d25074e99..3dab3a271aa6 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c @@ -800,7 +800,7 @@ hclge_dbg_dump_reg_tqp(struct hclge_dev *hdev, if (ret) return ret; - desc_src = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc_src = kzalloc_objs(struct hclge_desc, bd_num); if (!desc_src) return -ENOMEM; @@ -852,7 +852,7 @@ hclge_dbg_dump_reg_common(struct hclge_dev *hdev, if (ret) return ret; - desc_src = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc_src = kzalloc_objs(struct hclge_desc, bd_num); if (!desc_src) return -ENOMEM; @@ -2278,7 +2278,7 @@ static int hclge_dbg_get_imp_stats_info(struct seq_file *s, void *data) return -EINVAL; } - desc_src = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc_src = kzalloc_objs(struct hclge_desc, bd_num); if (!desc_src) return -ENOMEM; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c index cc7f46c0b35f..dac051e798da 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c @@ -2481,7 +2481,7 @@ static int hclge_handle_all_ras_errors(struct hclge_dev *hdev) return ret; bd_num = max_t(u32, mpf_bd_num, pf_bd_num); - desc = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc = kzalloc_objs(struct hclge_desc, bd_num); if (!desc) return -ENOMEM; @@ -3038,7 +3038,7 @@ static int hclge_handle_all_hw_msix_error(struct hclge_dev *hdev, goto out; bd_num = max_t(u32, mpf_bd_num, pf_bd_num); - desc = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc = kzalloc_objs(struct hclge_desc, bd_num); if (!desc) return -ENOMEM; @@ -3127,7 +3127,7 @@ void hclge_handle_all_hns_hw_errors(struct hnae3_ae_dev *ae_dev) return; bd_num = max_t(u32, mpf_bd_num, pf_bd_num); - desc = kcalloc(bd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc = kzalloc_objs(struct hclge_desc, bd_num); if (!desc) return; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c index edec994981c7..dd4045c773d4 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c @@ -492,7 +492,7 @@ static int hclge_mac_update_stats_complete(struct hclge_dev *hdev) /* This may be called inside atomic sections, * so GFP_ATOMIC is more suitable here */ - desc = kcalloc(desc_num, sizeof(struct hclge_desc), GFP_ATOMIC); + desc = kzalloc_objs(struct hclge_desc, desc_num, GFP_ATOMIC); if (!desc) return -ENOMEM; @@ -2418,7 +2418,7 @@ int hclge_buffer_alloc(struct hclge_dev *hdev) struct hclge_pkt_buf_alloc *pkt_buf; int ret; - pkt_buf = kzalloc(sizeof(*pkt_buf), GFP_KERNEL); + pkt_buf = kzalloc_obj(*pkt_buf); if (!pkt_buf) return -ENOMEM; @@ -6582,7 +6582,7 @@ static int hclge_add_fd_entry(struct hnae3_handle *handle, if (ret) return ret; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -7124,7 +7124,7 @@ static int hclge_add_fd_entry_by_arfs(struct hnae3_handle *handle, u16 queue_id, return -ENOSPC; } - rule = kzalloc(sizeof(*rule), GFP_ATOMIC); + rule = kzalloc_obj(*rule, GFP_ATOMIC); if (!rule) { spin_unlock_bh(&hdev->fd_rule_lock); return -ENOMEM; @@ -7410,7 +7410,7 @@ static int hclge_add_cls_flower(struct hnae3_handle *handle, return ret; } - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -8578,7 +8578,7 @@ int hclge_update_mac_list(struct hclge_vport *vport, return -ENOENT; } - mac_node = kzalloc(sizeof(*mac_node), GFP_ATOMIC); + mac_node = kzalloc_obj(*mac_node, GFP_ATOMIC); if (!mac_node) { spin_unlock_bh(&vport->mac_list_lock); return -ENOMEM; @@ -8986,7 +8986,7 @@ static void hclge_sync_vport_mac_table(struct hclge_vport *vport, list_move_tail(&mac_node->node, &tmp_del_list); break; case HCLGE_MAC_TO_ADD: - new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); + new_node = kzalloc_obj(*new_node, GFP_ATOMIC); if (!new_node) goto stop_traverse; ether_addr_copy(new_node->mac_addr, mac_node->mac_addr); @@ -9328,7 +9328,7 @@ int hclge_update_mac_node_for_dev_addr(struct hclge_vport *vport, new_node = hclge_find_mac_node(list, new_addr); if (!new_node) { - new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); + new_node = kzalloc_obj(*new_node, GFP_ATOMIC); if (!new_node) return -ENOMEM; @@ -10093,7 +10093,7 @@ static void hclge_add_vport_vlan_table(struct hclge_vport *vport, u16 vlan_id, } } - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) { mutex_unlock(&hdev->vport_lock); return; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c index b7d4e06a55d4..30e38cb4843a 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c @@ -212,7 +212,7 @@ static int hclge_get_ring_chain_from_mbx( cur_chain = ring_chain; for (i = 1; i < ring_num; i++) { - new_chain = kzalloc(sizeof(*new_chain), GFP_KERNEL); + new_chain = kzalloc_obj(*new_chain); if (!new_chain) goto err; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c index 8c057192aae6..85bac9b27b98 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_regs.c @@ -190,7 +190,7 @@ static int hclge_get_32_bit_regs(struct hclge_dev *hdev, u32 regs_num, nodata_num = HCLGE_32_BIT_DESC_NODATA_LEN; cmd_num = DIV_ROUND_UP(regs_num + nodata_num, HCLGE_32_BIT_REG_RTN_DATANUM); - desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc = kzalloc_objs(struct hclge_desc, cmd_num); if (!desc) return -ENOMEM; @@ -244,7 +244,7 @@ static int hclge_get_64_bit_regs(struct hclge_dev *hdev, u32 regs_num, nodata_len = HCLGE_64_BIT_DESC_NODATA_LEN; cmd_num = DIV_ROUND_UP(regs_num + nodata_len, HCLGE_64_BIT_REG_RTN_DATANUM); - desc = kcalloc(cmd_num, sizeof(struct hclge_desc), GFP_KERNEL); + desc = kzalloc_objs(struct hclge_desc, cmd_num); if (!desc) return -ENOMEM; @@ -394,7 +394,7 @@ static int hclge_get_dfx_reg_len(struct hclge_dev *hdev, int *len) int ret; u32 i; - bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); + bd_num_list = kzalloc_objs(int, dfx_reg_type_num); if (!bd_num_list) return -ENOMEM; @@ -455,7 +455,7 @@ static int hclge_get_dfx_reg(struct hclge_dev *hdev, void *data) int ret; u32 i; - bd_num_list = kcalloc(dfx_reg_type_num, sizeof(int), GFP_KERNEL); + bd_num_list = kzalloc_objs(int, dfx_reg_type_num); if (!bd_num_list) return -ENOMEM; diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c index 70327a73dee3..0cc911e6c732 100644 --- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c @@ -977,7 +977,7 @@ static int hclgevf_update_mac_list(struct hnae3_handle *handle, return -ENOENT; } - mac_node = kzalloc(sizeof(*mac_node), GFP_ATOMIC); + mac_node = kzalloc_obj(*mac_node, GFP_ATOMIC); if (!mac_node) { spin_unlock_bh(&hdev->mac_table.mac_list_lock); return -ENOMEM; @@ -1156,7 +1156,7 @@ static void hclgevf_sync_mac_list(struct hclgevf_dev *hdev, list_move_tail(&mac_node->node, &tmp_del_list); break; case HCLGEVF_MAC_TO_ADD: - new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); + new_node = kzalloc_obj(*new_node, GFP_ATOMIC); if (!new_node) goto stop_traverse; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c index 061952c6c21a..bd23c4888a0f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_debugfs.c @@ -88,7 +88,7 @@ static int hinic_dbg_get_func_table(struct hinic_dev *nic_dev, int idx) int ret = ~0; int err; - read_data = kzalloc(sizeof(*read_data), GFP_KERNEL); + read_data = kzalloc_obj(*read_data); if (!read_data) return ~0; @@ -182,7 +182,7 @@ static int create_dbg_files(struct hinic_dev *dev, enum hinic_dbg_type type, voi struct hinic_debug_priv *tmp; int i; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c index 300bc267a259..c977c43e5d5a 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c @@ -130,7 +130,7 @@ static int hinic_flash_fw(struct hinic_devlink_priv *priv, const u8 *data, int total_len_flag = 0; int err; - fw_update_msg = kzalloc(sizeof(*fw_update_msg), GFP_KERNEL); + fw_update_msg = kzalloc_obj(*fw_update_msg); if (!fw_update_msg) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index f28528df5aac..a8b129ce1b7e 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -1392,7 +1392,7 @@ static void hinic_get_ethtool_stats(struct net_device *netdev, sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } - port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); + port_stats = kzalloc_obj(*port_stats); if (!port_stats) { memset(&data[i], 0, ARRAY_SIZE(hinic_port_stats) * sizeof(*data)); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c index 97c1584dc05b..2784127327e6 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c @@ -487,7 +487,7 @@ static void recv_mbox_handler(struct hinic_mbox_func_to_func *func_to_func, if (!rcv_mbox_temp->buf_out) goto err_alloc_rcv_mbox_buf; - mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL); + mbox_work = kzalloc_obj(*mbox_work); if (!mbox_work) goto err_alloc_mbox_work; @@ -603,7 +603,7 @@ static bool check_vf_mbox_random_id(struct hinic_mbox_func_to_func *func_to_func "The mailbox random id(0x%x) of func_id(0x%x) doesn't match with pf reservation(0x%x)\n", random_id, src, func_to_func->vf_mbx_rand_id[src]); - mbox_work = kzalloc(sizeof(*mbox_work), GFP_KERNEL); + mbox_work = kzalloc_obj(*mbox_work); if (!mbox_work) return false; @@ -1402,7 +1402,7 @@ int hinic_func_to_func_init(struct hinic_hwdev *hwdev) int err; pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev); - func_to_func = kzalloc(sizeof(*func_to_func), GFP_KERNEL); + func_to_func = kzalloc_obj(*func_to_func); if (!func_to_func) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c index 4aa1f433ed24..1a59fcc482d8 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mgmt.c @@ -441,7 +441,7 @@ static void mgmt_recv_msg_handler(struct hinic_pf_to_mgmt *pf_to_mgmt, { struct hinic_mgmt_msg_handle_work *mgmt_work = NULL; - mgmt_work = kzalloc(sizeof(*mgmt_work), GFP_KERNEL); + mgmt_work = kzalloc_obj(*mgmt_work); if (!mgmt_work) return; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_port.c b/drivers/net/ethernet/huawei/hinic/hinic_port.c index 486fb0e20bef..7bb6eb2a8917 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_port.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_port.c @@ -1032,7 +1032,7 @@ int hinic_get_phy_port_stats(struct hinic_dev *nic_dev, struct pci_dev *pdev = hwif->pdev; int err; - port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); + port_stats = kzalloc_obj(*port_stats); if (!port_stats) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c b/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c index 86720bb119e9..bc5b80c31693 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_cmdq.c @@ -123,7 +123,7 @@ struct hinic3_cmd_buf *hinic3_alloc_cmd_buf(struct hinic3_hwdev *hwdev) cmdqs = hwdev->cmdqs; - cmd_buf = kmalloc(sizeof(*cmd_buf), GFP_ATOMIC); + cmd_buf = kmalloc_obj(*cmd_buf, GFP_ATOMIC); if (!cmd_buf) return NULL; @@ -614,8 +614,7 @@ static int init_cmdq(struct hinic3_cmdq *cmdq, struct hinic3_hwdev *hwdev, spin_lock_init(&cmdq->cmdq_lock); - cmdq->cmd_infos = kcalloc(cmdq->wq.q_depth, sizeof(*cmdq->cmd_infos), - GFP_KERNEL); + cmdq->cmd_infos = kzalloc_objs(*cmdq->cmd_infos, cmdq->wq.q_depth); if (!cmdq->cmd_infos) { err = -ENOMEM; return err; @@ -738,7 +737,7 @@ static int init_cmdqs(struct hinic3_hwdev *hwdev) { struct hinic3_cmdqs *cmdqs; - cmdqs = kzalloc(sizeof(*cmdqs), GFP_KERNEL); + cmdqs = kzalloc_obj(*cmdqs); if (!cmdqs) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_eqs.c b/drivers/net/ethernet/huawei/hinic3/hinic3_eqs.c index a2c3962116d5..13a0c6b07660 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_eqs.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_eqs.c @@ -648,7 +648,7 @@ int hinic3_aeqs_init(struct hinic3_hwdev *hwdev, u16 num_aeqs, u16 q_id; int err; - aeqs = kzalloc(sizeof(*aeqs), GFP_KERNEL); + aeqs = kzalloc_obj(*aeqs); if (!aeqs) return -ENOMEM; @@ -720,7 +720,7 @@ int hinic3_ceqs_init(struct hinic3_hwdev *hwdev, u16 num_ceqs, u16 q_id; int err; - ceqs = kzalloc(sizeof(*ceqs), GFP_KERNEL); + ceqs = kzalloc_obj(*ceqs); if (!ceqs) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c index 6349d71f574b..6d378c86aabd 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_filter.c @@ -75,7 +75,7 @@ static void hinic3_add_filter(struct net_device *netdev, struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); struct hinic3_mac_filter *f; - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return; @@ -110,7 +110,7 @@ hinic3_mac_filter_entry_clone(const struct hinic3_mac_filter *src) { struct hinic3_mac_filter *f; - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return NULL; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c index 7827c1f626db..ca60cf4b6282 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hw_cfg.c @@ -86,8 +86,7 @@ static int hinic3_init_irq_info(struct hinic3_hwdev *hwdev) } irq_info = &cfg_mgmt->irq_info; - irq_info->irq = kcalloc(intr_num, sizeof(struct hinic3_irq), - GFP_KERNEL); + irq_info->irq = kzalloc_objs(struct hinic3_irq, intr_num); if (!irq_info->irq) return -ENOMEM; @@ -130,7 +129,7 @@ int hinic3_init_cfg_mgmt(struct hinic3_hwdev *hwdev) struct hinic3_cfg_mgmt_info *cfg_mgmt; int err; - cfg_mgmt = kzalloc(sizeof(*cfg_mgmt), GFP_KERNEL); + cfg_mgmt = kzalloc_obj(*cfg_mgmt); if (!cfg_mgmt) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c index 7906d4057cf2..0074d0c6dbaf 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwdev.c @@ -528,7 +528,7 @@ int hinic3_init_hwdev(struct pci_dev *pdev) struct hinic3_hwdev *hwdev; int err; - hwdev = kzalloc(sizeof(*hwdev), GFP_KERNEL); + hwdev = kzalloc_obj(*hwdev); if (!hwdev) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c b/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c index 801f48e241f8..771883174b3b 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_hwif.c @@ -432,7 +432,7 @@ int hinic3_init_hwif(struct hinic3_hwdev *hwdev) u32 attr1, attr4, attr5; int err; - hwif = kzalloc(sizeof(*hwif), GFP_KERNEL); + hwif = kzalloc_obj(*hwif); if (!hwif) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c index 87413e192f10..a8b89eeed753 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_lld.c @@ -60,7 +60,7 @@ static struct hinic3_adev *hinic3_add_one_adev(struct hinic3_hwdev *hwdev, const char *svc_name; int ret; - hadev = kzalloc(sizeof(*hadev), GFP_KERNEL); + hadev = kzalloc_obj(*hadev); if (!hadev) return NULL; @@ -250,7 +250,7 @@ static int hinic3_pci_init(struct pci_dev *pdev) struct hinic3_pcidev *pci_adapter; int err; - pci_adapter = kzalloc(sizeof(*pci_adapter), GFP_KERNEL); + pci_adapter = kzalloc_obj(*pci_adapter); if (!pci_adapter) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c index 6275d94dfefd..6039fcf3c1dd 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_main.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_main.c @@ -57,9 +57,8 @@ static int hinic3_init_intr_coalesce(struct net_device *netdev) { struct hinic3_nic_dev *nic_dev = netdev_priv(netdev); - nic_dev->intr_coalesce = kcalloc(nic_dev->max_qps, - sizeof(*nic_dev->intr_coalesce), - GFP_KERNEL); + nic_dev->intr_coalesce = kzalloc_objs(*nic_dev->intr_coalesce, + nic_dev->max_qps); if (!nic_dev->intr_coalesce) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c index c871fd0fb109..826fa8879a11 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mbox.c @@ -320,7 +320,7 @@ static int hinic3_init_func_mbox_msg_channel(struct hinic3_hwdev *hwdev) int err; mbox = hwdev->mbox; - mbox->func_msg = kzalloc(sizeof(*mbox->func_msg), GFP_KERNEL); + mbox->func_msg = kzalloc_obj(*mbox->func_msg); if (!mbox->func_msg) return -ENOMEM; @@ -412,7 +412,7 @@ int hinic3_init_mbox(struct hinic3_hwdev *hwdev) struct hinic3_mbox *mbox; int err; - mbox = kzalloc(sizeof(*mbox), GFP_KERNEL); + mbox = kzalloc_obj(*mbox); if (!mbox) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c index be2a2ae75fc0..71c6a064d054 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_mgmt.c @@ -120,7 +120,7 @@ static void hinic3_init_mgmt_msg_work(struct hinic3_msg_pf_to_mgmt *pf_to_mgmt, { struct mgmt_msg_handle_work *mgmt_work; - mgmt_work = kmalloc(sizeof(*mgmt_work), GFP_KERNEL); + mgmt_work = kmalloc_obj(*mgmt_work); if (!mgmt_work) return; @@ -252,7 +252,7 @@ int hinic3_pf_to_mgmt_init(struct hinic3_hwdev *hwdev) struct hinic3_msg_pf_to_mgmt *pf_to_mgmt; int err; - pf_to_mgmt = kzalloc(sizeof(*pf_to_mgmt), GFP_KERNEL); + pf_to_mgmt = kzalloc_obj(*pf_to_mgmt); if (!pf_to_mgmt) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c index 75adfe897e81..cabb8523f246 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_netdev_ops.c @@ -99,9 +99,8 @@ static int hinic3_setup_num_qps(struct net_device *netdev) nic_dev->num_qp_irq = 0; - nic_dev->qps_msix_entries = kcalloc(nic_dev->max_qps, - sizeof(struct msix_entry), - GFP_KERNEL); + nic_dev->qps_msix_entries = kzalloc_objs(struct msix_entry, + nic_dev->max_qps); if (!nic_dev->qps_msix_entries) return -ENOMEM; @@ -127,20 +126,19 @@ static int hinic3_alloc_txrxq_resources(struct net_device *netdev, { int err; - q_params->txqs_res = kcalloc(q_params->num_qps, - sizeof(*q_params->txqs_res), GFP_KERNEL); + q_params->txqs_res = kzalloc_objs(*q_params->txqs_res, + q_params->num_qps); if (!q_params->txqs_res) return -ENOMEM; - q_params->rxqs_res = kcalloc(q_params->num_qps, - sizeof(*q_params->rxqs_res), GFP_KERNEL); + q_params->rxqs_res = kzalloc_objs(*q_params->rxqs_res, + q_params->num_qps); if (!q_params->rxqs_res) { err = -ENOMEM; goto err_free_txqs_res_arr; } - q_params->irq_cfg = kcalloc(q_params->num_qps, - sizeof(*q_params->irq_cfg), GFP_KERNEL); + q_params->irq_cfg = kzalloc_objs(*q_params->irq_cfg, q_params->num_qps); if (!q_params->irq_cfg) { err = -ENOMEM; goto err_free_rxqs_res_arr; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c index 90887d2bb127..87e736adba02 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_nic_io.c @@ -212,7 +212,7 @@ int hinic3_init_nic_io(struct hinic3_nic_dev *nic_dev) struct hinic3_nic_io *nic_io; int err; - nic_io = kzalloc(sizeof(*nic_io), GFP_KERNEL); + nic_io = kzalloc_obj(*nic_io); if (!nic_io) return -ENOMEM; @@ -408,13 +408,13 @@ int hinic3_alloc_qps(struct hinic3_nic_dev *nic_dev, if (qp_params->num_qps > nic_io->max_qps || !qp_params->num_qps) return -EINVAL; - sqs = kcalloc(qp_params->num_qps, sizeof(*sqs), GFP_KERNEL); + sqs = kzalloc_objs(*sqs, qp_params->num_qps); if (!sqs) { err = -ENOMEM; goto err_out; } - rqs = kcalloc(qp_params->num_qps, sizeof(*rqs), GFP_KERNEL); + rqs = kzalloc_objs(*rqs, qp_params->num_qps); if (!rqs) { err = -ENOMEM; goto err_free_sqs; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_queue_common.c b/drivers/net/ethernet/huawei/hinic3/hinic3_queue_common.c index fab9011de9ad..4ac3ad681ffa 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_queue_common.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_queue_common.c @@ -44,8 +44,7 @@ int hinic3_queue_pages_alloc(struct hinic3_hwdev *hwdev, u32 pg_idx; int err; - qpages->pages = kcalloc(qpages->num_pages, sizeof(qpages->pages[0]), - GFP_KERNEL); + qpages->pages = kzalloc_objs(qpages->pages[0], qpages->num_pages); if (!qpages->pages) return -ENOMEM; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c index 159c291fa293..1236ec233b7f 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_rx.c @@ -66,7 +66,7 @@ int hinic3_alloc_rxqs(struct net_device *netdev) struct hinic3_rxq *rxq; u16 q_id; - nic_dev->rxqs = kcalloc(num_rxqs, sizeof(*nic_dev->rxqs), GFP_KERNEL); + nic_dev->rxqs = kzalloc_objs(*nic_dev->rxqs, num_rxqs); if (!nic_dev->rxqs) return -ENOMEM; @@ -419,8 +419,7 @@ int hinic3_alloc_rxqs_res(struct net_device *netdev, u16 num_rq, for (idx = 0; idx < num_rq; idx++) { rqres = &rxqs_res[idx]; - rqres->rx_info = kcalloc(rq_depth, sizeof(*rqres->rx_info), - GFP_KERNEL); + rqres->rx_info = kzalloc_objs(*rqres->rx_info, rq_depth); if (!rqres->rx_info) goto err_free_rqres; diff --git a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c index 6d3dc930ca97..9306bf0020ca 100644 --- a/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c +++ b/drivers/net/ethernet/huawei/hinic3/hinic3_tx.c @@ -48,7 +48,7 @@ int hinic3_alloc_txqs(struct net_device *netdev) struct pci_dev *pdev = nic_dev->pdev; struct hinic3_txq *txq; - nic_dev->txqs = kcalloc(num_txqs, sizeof(*nic_dev->txqs), GFP_KERNEL); + nic_dev->txqs = kzalloc_objs(*nic_dev->txqs, num_txqs); if (!nic_dev->txqs) return -ENOMEM; @@ -681,14 +681,12 @@ int hinic3_alloc_txqs_res(struct net_device *netdev, u16 num_sq, for (idx = 0; idx < num_sq; idx++) { tqres = &txqs_res[idx]; - tqres->tx_info = kcalloc(sq_depth, sizeof(*tqres->tx_info), - GFP_KERNEL); + tqres->tx_info = kzalloc_objs(*tqres->tx_info, sq_depth); if (!tqres->tx_info) goto err_free_tqres; - tqres->bds = kcalloc(sq_depth * HINIC3_BDS_PER_SQ_WQEBB + - HINIC3_MAX_SQ_SGE, sizeof(*tqres->bds), - GFP_KERNEL); + tqres->bds = kzalloc_objs(*tqres->bds, + sq_depth * HINIC3_BDS_PER_SQ_WQEBB + HINIC3_MAX_SQ_SGE); if (!tqres->bds) { kfree(tqres->tx_info); goto err_free_tqres; diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 9b006bc353a1..ff67c4fd66a3 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -173,7 +173,7 @@ static void ehea_update_firmware_handles(void) num_portres * EHEA_NUM_PORTRES_FW_HANDLES; if (num_fw_handles) { - arr = kcalloc(num_fw_handles, sizeof(*arr), GFP_KERNEL); + arr = kzalloc_objs(*arr, num_fw_handles); if (!arr) goto out; /* Keep the existing array */ } else @@ -256,7 +256,7 @@ static void ehea_update_bcmc_registrations(void) } if (num_registrations) { - arr = kcalloc(num_registrations, sizeof(*arr), GFP_ATOMIC); + arr = kzalloc_objs(*arr, num_registrations, GFP_ATOMIC); if (!arr) goto out; /* Keep the existing array */ } else @@ -1487,7 +1487,7 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr, pr->send_cq->attr.act_nr_of_cqes, pr->recv_cq->attr.act_nr_of_cqes); - init_attr = kzalloc(sizeof(*init_attr), GFP_KERNEL); + init_attr = kzalloc_obj(*init_attr); if (!init_attr) { ret = -ENOMEM; pr_err("no mem for ehea_qp_init_attr\n"); @@ -1899,7 +1899,7 @@ static void ehea_add_multicast_entry(struct ehea_port *port, u8 *mc_mac_addr) struct ehea_mc_list *ehea_mcl_entry; u64 hret; - ehea_mcl_entry = kzalloc(sizeof(*ehea_mcl_entry), GFP_ATOMIC); + ehea_mcl_entry = kzalloc_obj(*ehea_mcl_entry, GFP_ATOMIC); if (!ehea_mcl_entry) return; @@ -2968,7 +2968,7 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, port->msg_enable = netif_msg_init(msg_level, EHEA_MSG_DEFAULT); - port->mc_list = kzalloc(sizeof(struct ehea_mc_list), GFP_KERNEL); + port->mc_list = kzalloc_obj(struct ehea_mc_list); if (!port->mc_list) { ret = -ENOMEM; goto out_free_ethdev; diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c index db45373ea31c..60629a0032b2 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c @@ -114,7 +114,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, int ret; void *vpage; - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_obj(*cq); if (!cq) goto out_nomem; @@ -235,7 +235,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, void *vpage; struct ehea_eq *eq; - eq = kzalloc(sizeof(*eq), GFP_KERNEL); + eq = kzalloc_obj(*eq); if (!eq) return NULL; @@ -404,7 +404,7 @@ struct ehea_qp *ehea_create_qp(struct ehea_adapter *adapter, u32 wqe_size_in_bytes_rq2, wqe_size_in_bytes_rq3; - qp = kzalloc(sizeof(*qp), GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return NULL; @@ -542,7 +542,7 @@ static inline int ehea_init_top_bmap(struct ehea_top_bmap *ehea_top_bmap, { if (!ehea_top_bmap->dir[dir]) { ehea_top_bmap->dir[dir] = - kzalloc(sizeof(struct ehea_dir_bmap), GFP_KERNEL); + kzalloc_obj(struct ehea_dir_bmap); if (!ehea_top_bmap->dir[dir]) return -ENOMEM; } @@ -553,7 +553,7 @@ static inline int ehea_init_bmap(struct ehea_bmap *ehea_bmap, int top, int dir) { if (!ehea_bmap->top[top]) { ehea_bmap->top[top] = - kzalloc(sizeof(struct ehea_top_bmap), GFP_KERNEL); + kzalloc_obj(struct ehea_top_bmap); if (!ehea_bmap->top[top]) return -ENOMEM; } @@ -613,7 +613,7 @@ static int ehea_update_busmap(unsigned long pfn, unsigned long nr_pages, int add return 0; if (!ehea_bmap) { - ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); + ehea_bmap = kzalloc_obj(struct ehea_bmap); if (!ehea_bmap) return -ENOMEM; } diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 6f0821f1e798..4d6b9e83e341 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c @@ -169,7 +169,7 @@ static int ibmveth_alloc_buffer_pool(struct ibmveth_buff_pool *pool) if (!pool->free_map) return -1; - pool->dma_addr = kcalloc(pool->size, sizeof(dma_addr_t), GFP_KERNEL); + pool->dma_addr = kzalloc_objs(dma_addr_t, pool->size); if (!pool->dma_addr) { kfree(pool->free_map); pool->free_map = NULL; diff --git a/drivers/net/ethernet/ibm/ibmvnic.c b/drivers/net/ethernet/ibm/ibmvnic.c index 3808148c1fc7..5a510eed335e 100644 --- a/drivers/net/ethernet/ibm/ibmvnic.c +++ b/drivers/net/ethernet/ibm/ibmvnic.c @@ -932,16 +932,14 @@ static void release_stats_buffers(struct ibmvnic_adapter *adapter) static int init_stats_buffers(struct ibmvnic_adapter *adapter) { adapter->tx_stats_buffers = - kcalloc(IBMVNIC_MAX_QUEUES, - sizeof(struct ibmvnic_tx_queue_stats), - GFP_KERNEL); + kzalloc_objs(struct ibmvnic_tx_queue_stats, + IBMVNIC_MAX_QUEUES); if (!adapter->tx_stats_buffers) return -ENOMEM; adapter->rx_stats_buffers = - kcalloc(IBMVNIC_MAX_QUEUES, - sizeof(struct ibmvnic_rx_queue_stats), - GFP_KERNEL); + kzalloc_objs(struct ibmvnic_rx_queue_stats, + IBMVNIC_MAX_QUEUES); if (!adapter->rx_stats_buffers) return -ENOMEM; @@ -1096,9 +1094,7 @@ static int init_rx_pools(struct net_device *netdev) /* Allocate/populate the pools. */ release_rx_pools(adapter); - adapter->rx_pool = kcalloc(num_pools, - sizeof(struct ibmvnic_rx_pool), - GFP_KERNEL); + adapter->rx_pool = kzalloc_objs(struct ibmvnic_rx_pool, num_pools); if (!adapter->rx_pool) { dev_err(dev, "Failed to allocate rx pools\n"); return -ENOMEM; @@ -1120,17 +1116,15 @@ static int init_rx_pools(struct net_device *netdev) rx_pool->index = i; rx_pool->buff_size = ALIGN(buff_size, L1_CACHE_BYTES); - rx_pool->free_map = kcalloc(rx_pool->size, sizeof(int), - GFP_KERNEL); + rx_pool->free_map = kzalloc_objs(int, rx_pool->size); if (!rx_pool->free_map) { dev_err(dev, "Couldn't alloc free_map %d\n", i); rc = -ENOMEM; goto out_release; } - rx_pool->rx_buff = kcalloc(rx_pool->size, - sizeof(struct ibmvnic_rx_buff), - GFP_KERNEL); + rx_pool->rx_buff = kzalloc_objs(struct ibmvnic_rx_buff, + rx_pool->size); if (!rx_pool->rx_buff) { dev_err(dev, "Couldn't alloc rx buffers\n"); rc = -ENOMEM; @@ -1243,13 +1237,11 @@ static int init_one_tx_pool(struct net_device *netdev, { int i; - tx_pool->tx_buff = kcalloc(pool_size, - sizeof(struct ibmvnic_tx_buff), - GFP_KERNEL); + tx_pool->tx_buff = kzalloc_objs(struct ibmvnic_tx_buff, pool_size); if (!tx_pool->tx_buff) return -ENOMEM; - tx_pool->free_map = kcalloc(pool_size, sizeof(int), GFP_KERNEL); + tx_pool->free_map = kzalloc_objs(int, pool_size); if (!tx_pool->free_map) { kfree(tx_pool->tx_buff); tx_pool->tx_buff = NULL; @@ -1341,13 +1333,11 @@ static int init_tx_pools(struct net_device *netdev) pool_size = adapter->req_tx_entries_per_subcrq; num_pools = adapter->num_active_tx_scrqs; - adapter->tx_pool = kcalloc(num_pools, - sizeof(struct ibmvnic_tx_pool), GFP_KERNEL); + adapter->tx_pool = kzalloc_objs(struct ibmvnic_tx_pool, num_pools); if (!adapter->tx_pool) return -ENOMEM; - adapter->tso_pool = kcalloc(num_pools, - sizeof(struct ibmvnic_tx_pool), GFP_KERNEL); + adapter->tso_pool = kzalloc_objs(struct ibmvnic_tx_pool, num_pools); /* To simplify release_tx_pools() ensure that ->tx_pool and * ->tso_pool are either both NULL or both non-NULL. */ @@ -1471,8 +1461,7 @@ static int init_napi(struct ibmvnic_adapter *adapter) { int i; - adapter->napi = kcalloc(adapter->req_rx_queues, - sizeof(struct napi_struct), GFP_KERNEL); + adapter->napi = kzalloc_objs(struct napi_struct, adapter->req_rx_queues); if (!adapter->napi) return -ENOMEM; @@ -1859,7 +1848,7 @@ static int init_resources(struct ibmvnic_adapter *adapter) if (rc) return rc; - adapter->vpd = kzalloc(sizeof(*adapter->vpd), GFP_KERNEL); + adapter->vpd = kzalloc_obj(*adapter->vpd); if (!adapter->vpd) return -ENOMEM; @@ -3450,7 +3439,7 @@ static int ibmvnic_reset(struct ibmvnic_adapter *adapter, } } - rwi = kzalloc(sizeof(*rwi), GFP_ATOMIC); + rwi = kzalloc_obj(*rwi, GFP_ATOMIC); if (!rwi) { ret = ENOMEM; goto err; @@ -4055,7 +4044,7 @@ static struct ibmvnic_sub_crq_queue *init_sub_crq_queue(struct ibmvnic_adapter struct ibmvnic_sub_crq_queue *scrq; int rc; - scrq = kzalloc(sizeof(*scrq), GFP_KERNEL); + scrq = kzalloc_obj(*scrq); if (!scrq) return NULL; @@ -4447,7 +4436,7 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter) total_queues = adapter->req_tx_queues + adapter->req_rx_queues; - allqueues = kcalloc(total_queues, sizeof(*allqueues), GFP_KERNEL); + allqueues = kzalloc_objs(*allqueues, total_queues); if (!allqueues) return -ENOMEM; @@ -4486,8 +4475,8 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter) } } - adapter->tx_scrq = kcalloc(adapter->req_tx_queues, - sizeof(*adapter->tx_scrq), GFP_KERNEL); + adapter->tx_scrq = kzalloc_objs(*adapter->tx_scrq, + adapter->req_tx_queues); if (!adapter->tx_scrq) goto tx_failed; @@ -4497,8 +4486,8 @@ static int init_sub_crqs(struct ibmvnic_adapter *adapter) adapter->num_active_tx_scrqs++; } - adapter->rx_scrq = kcalloc(adapter->req_rx_queues, - sizeof(*adapter->rx_scrq), GFP_KERNEL); + adapter->rx_scrq = kzalloc_objs(*adapter->rx_scrq, + adapter->req_rx_queues); if (!adapter->rx_scrq) goto rx_failed; diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 5c56c1edd492..9074b558de35 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -2156,7 +2156,7 @@ static int e100_rx_alloc_list(struct nic *nic) nic->rx_to_use = nic->rx_to_clean = NULL; nic->ru_running = RU_UNINITIALIZED; - if (!(nic->rxs = kcalloc(count, sizeof(struct rx), GFP_KERNEL))) + if (!(nic->rxs = kzalloc_objs(struct rx, count))) return -ENOMEM; for (rx = nic->rxs, i = 0; i < count; rx++, i++) { diff --git a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c index 726365c567ef..ab232b3fbbd0 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_ethtool.c +++ b/drivers/net/ethernet/intel/e1000/e1000_ethtool.c @@ -582,13 +582,11 @@ static int e1000_set_ringparam(struct net_device *netdev, rx_old = adapter->rx_ring; err = -ENOMEM; - txdr = kcalloc(adapter->num_tx_queues, sizeof(struct e1000_tx_ring), - GFP_KERNEL); + txdr = kzalloc_objs(struct e1000_tx_ring, adapter->num_tx_queues); if (!txdr) goto err_alloc_tx; - rxdr = kcalloc(adapter->num_rx_queues, sizeof(struct e1000_rx_ring), - GFP_KERNEL); + rxdr = kzalloc_objs(struct e1000_rx_ring, adapter->num_rx_queues); if (!rxdr) goto err_alloc_rx; @@ -984,8 +982,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) if (!txdr->count) txdr->count = E1000_DEFAULT_TXD; - txdr->buffer_info = kcalloc(txdr->count, sizeof(struct e1000_tx_buffer), - GFP_KERNEL); + txdr->buffer_info = kzalloc_objs(struct e1000_tx_buffer, txdr->count); if (!txdr->buffer_info) { ret_val = 1; goto err_nomem; @@ -1043,8 +1040,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) if (!rxdr->count) rxdr->count = E1000_DEFAULT_RXD; - rxdr->buffer_info = kcalloc(rxdr->count, sizeof(struct e1000_rx_buffer), - GFP_KERNEL); + rxdr->buffer_info = kzalloc_objs(struct e1000_rx_buffer, rxdr->count); if (!rxdr->buffer_info) { ret_val = 5; goto err_nomem; diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 7f078ec9c14c..9b09eb144b81 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -1322,13 +1322,13 @@ static int e1000_sw_init(struct e1000_adapter *adapter) **/ static int e1000_alloc_queues(struct e1000_adapter *adapter) { - adapter->tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct e1000_tx_ring), GFP_KERNEL); + adapter->tx_ring = kzalloc_objs(struct e1000_tx_ring, + adapter->num_tx_queues); if (!adapter->tx_ring) return -ENOMEM; - adapter->rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct e1000_rx_ring), GFP_KERNEL); + adapter->rx_ring = kzalloc_objs(struct e1000_rx_ring, + adapter->num_rx_queues); if (!adapter->rx_ring) { kfree(adapter->tx_ring); return -ENOMEM; @@ -2952,8 +2952,6 @@ static int e1000_tx_map(struct e1000_adapter *adapter, dma_error: dev_err(&pdev->dev, "TX DMA map failed\n"); buffer_info->dma = 0; - if (count) - count--; while (count--) { if (i == 0) diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index ba331899d186..d4a1041e456d 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -33,6 +33,7 @@ /* Extended Device Control */ #define E1000_CTRL_EXT_LPCD 0x00000004 /* LCD Power Cycle Done */ +#define E1000_CTRL_EXT_DPG_EN 0x00000008 /* Dynamic Power Gating Enable */ #define E1000_CTRL_EXT_SDP3_DATA 0x00000080 /* Value of SW Definable Pin 3 */ #define E1000_CTRL_EXT_FORCE_SMBUS 0x00000800 /* Force SMBus mode */ #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index aa08f397988e..63ebe00376f5 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -117,7 +117,8 @@ enum e1000_boards { board_pch_cnp, board_pch_tgp, board_pch_adp, - board_pch_mtp + board_pch_mtp, + board_pch_ptp }; struct e1000_ps_page { @@ -527,6 +528,7 @@ extern const struct e1000_info e1000_pch_cnp_info; extern const struct e1000_info e1000_pch_tgp_info; extern const struct e1000_info e1000_pch_adp_info; extern const struct e1000_info e1000_pch_mtp_info; +extern const struct e1000_info e1000_pch_ptp_info; extern const struct e1000_info e1000_es2_info; void e1000e_ptp_init(struct e1000_adapter *adapter); diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 7b1ac90b3de4..dbed30943ef4 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1173,8 +1173,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) if (!tx_ring->count) tx_ring->count = E1000_DEFAULT_TXD; - tx_ring->buffer_info = kcalloc(tx_ring->count, - sizeof(struct e1000_buffer), GFP_KERNEL); + tx_ring->buffer_info = kzalloc_objs(struct e1000_buffer, tx_ring->count); if (!tx_ring->buffer_info) { ret_val = 1; goto err_nomem; @@ -1234,8 +1233,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) if (!rx_ring->count) rx_ring->count = E1000_DEFAULT_RXD; - rx_ring->buffer_info = kcalloc(rx_ring->count, - sizeof(struct e1000_buffer), GFP_KERNEL); + rx_ring->buffer_info = kzalloc_objs(struct e1000_buffer, rx_ring->count); if (!rx_ring->buffer_info) { ret_val = 5; goto err_nomem; diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index fc8ed38aa095..c7ac599e5a7a 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -118,8 +118,6 @@ struct e1000_hw; #define E1000_DEV_ID_PCH_ARL_I219_V24 0x57A1 #define E1000_DEV_ID_PCH_PTP_I219_LM25 0x57B3 #define E1000_DEV_ID_PCH_PTP_I219_V25 0x57B4 -#define E1000_DEV_ID_PCH_PTP_I219_LM26 0x57B5 -#define E1000_DEV_ID_PCH_PTP_I219_V26 0x57B6 #define E1000_DEV_ID_PCH_PTP_I219_LM27 0x57B7 #define E1000_DEV_ID_PCH_PTP_I219_V27 0x57B8 #define E1000_DEV_ID_PCH_NVL_I219_LM29 0x57B9 diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 0ff8688ac3b8..dea208db1be5 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -528,7 +528,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->id = e1000_phy_unknown; - if (hw->mac.type == e1000_pch_mtp) { + if (hw->mac.type == e1000_pch_mtp || hw->mac.type == e1000_pch_ptp) { phy->retry_count = 2; e1000e_enable_phy_retry(hw); } @@ -4932,6 +4932,15 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) reg |= E1000_KABGTXD_BGSQLBIAS; ew32(KABGTXD, reg); + /* The hardware reset value of the DPG_EN bit is 1. + * Clear DPG_EN to prevent unexpected autonomous power gating. + */ + if (hw->mac.type >= e1000_pch_ptp) { + reg = er32(CTRL_EXT); + reg &= ~E1000_CTRL_EXT_DPG_EN; + ew32(CTRL_EXT, reg); + } + return 0; } @@ -6208,3 +6217,23 @@ const struct e1000_info e1000_pch_mtp_info = { .phy_ops = &ich8_phy_ops, .nvm_ops = &spt_nvm_ops, }; + +const struct e1000_info e1000_pch_ptp_info = { + .mac = e1000_pch_ptp, + .flags = FLAG_IS_ICH + | FLAG_HAS_WOL + | FLAG_HAS_HW_TIMESTAMP + | FLAG_HAS_CTRLEXT_ON_LOAD + | FLAG_HAS_AMT + | FLAG_HAS_FLASH + | FLAG_HAS_JUMBO_FRAMES + | FLAG_APME_IN_WUC, + .flags2 = FLAG2_HAS_PHY_STATS + | FLAG2_HAS_EEE, + .pba = 26, + .max_hw_frame_size = 9022, + .get_variants = e1000_get_variants_ich8lan, + .mac_ops = &ich8_mac_ops, + .phy_ops = &ich8_phy_ops, + .nvm_ops = &spt_nvm_ops, +}; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index ddbe2f7d8112..9befdacd6730 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -55,6 +55,7 @@ static const struct e1000_info *e1000_info_tbl[] = { [board_pch_tgp] = &e1000_pch_tgp_info, [board_pch_adp] = &e1000_pch_adp_info, [board_pch_mtp] = &e1000_pch_mtp_info, + [board_pch_ptp] = &e1000_pch_ptp_info, }; struct e1000_reg_info { @@ -2050,10 +2051,8 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) case E1000E_INT_MODE_MSIX: if (adapter->flags & FLAG_HAS_MSIX) { adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */ - adapter->msix_entries = kcalloc(adapter->num_vectors, - sizeof(struct - msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, + adapter->num_vectors); if (adapter->msix_entries) { struct e1000_adapter *a = adapter; @@ -2370,9 +2369,8 @@ int e1000e_setup_rx_resources(struct e1000_ring *rx_ring) for (i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; - buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS, - sizeof(struct e1000_ps_page), - GFP_KERNEL); + buffer_info->ps_pages = kzalloc_objs(struct e1000_ps_page, + PS_PAGE_BUFFERS); if (!buffer_info->ps_pages) goto err_pages; } @@ -5654,8 +5652,6 @@ static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, dma_error: dev_err(&pdev->dev, "Tx DMA map failed\n"); buffer_info->dma = 0; - if (count) - count--; while (count--) { if (i == 0) @@ -7925,14 +7921,12 @@ static const struct pci_device_id e1000_pci_tbl[] = { { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V21), board_pch_mtp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ARL_I219_LM24), board_pch_mtp }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ARL_I219_V24), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM25), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V25), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM26), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V26), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM27), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V27), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_NVL_I219_LM29), board_pch_mtp }, - { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_NVL_I219_V29), board_pch_mtp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM25), board_pch_ptp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V25), board_pch_ptp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_LM27), board_pch_ptp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_PTP_I219_V27), board_pch_ptp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_NVL_I219_LM29), board_pch_ptp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_NVL_I219_V29), board_pch_ptp }, { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ }; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_main.c b/drivers/net/ethernet/intel/fm10k/fm10k_main.c index b8c15b837fda..898deb3f11c4 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_main.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_main.c @@ -1597,7 +1597,7 @@ static int fm10k_alloc_q_vector(struct fm10k_intfc *interface, ring_count = txr_count + rxr_count; /* allocate q_vector and rings */ - q_vector = kzalloc(struct_size(q_vector, ring, ring_count), GFP_KERNEL); + q_vector = kzalloc_flex(*q_vector, ring, ring_count); if (!q_vector) return -ENOMEM; @@ -1825,8 +1825,7 @@ static int fm10k_init_msix_capability(struct fm10k_intfc *interface) v_budget = min_t(int, v_budget, hw->mac.max_msix_vectors); /* A failure in MSI-X entry allocation is fatal. */ - interface->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), - GFP_KERNEL); + interface->msix_entries = kzalloc_objs(struct msix_entry, v_budget); if (!interface->msix_entries) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 34ab5ff9823b..c86701be4364 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -649,7 +649,7 @@ int fm10k_queue_vlan_request(struct fm10k_intfc *interface, /* This must be atomic since we may be called while the netdev * addr_list_lock is held */ - request = kzalloc(sizeof(*request), GFP_ATOMIC); + request = kzalloc_obj(*request, GFP_ATOMIC); if (!request) return -ENOMEM; @@ -688,7 +688,7 @@ int fm10k_queue_mac_request(struct fm10k_intfc *interface, u16 glort, /* This must be atomic since we may be called while the netdev * addr_list_lock is held */ - request = kzalloc(sizeof(*request), GFP_ATOMIC); + request = kzalloc_obj(*request, GFP_ATOMIC); if (!request) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c index 518bc738ea3b..84a97ca8a6d8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_client.c +++ b/drivers/net/ethernet/intel/i40e/i40e_client.c @@ -291,7 +291,7 @@ static int i40e_register_auxiliary_dev(struct i40e_info *ldev, const char *name) struct auxiliary_device *aux_dev; int ret; - i40e_aux_dev = kzalloc(sizeof(*i40e_aux_dev), GFP_KERNEL); + i40e_aux_dev = kzalloc_obj(*i40e_aux_dev); if (!i40e_aux_dev) return -ENOMEM; @@ -337,7 +337,7 @@ static void i40e_client_add_instance(struct i40e_pf *pf) struct i40e_client_instance *cdev = NULL; struct netdev_hw_addr *mac = NULL; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return; @@ -466,7 +466,7 @@ int i40e_lan_add_device(struct i40e_pf *pf) goto out; } } - ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + ldev = kzalloc_obj(*ldev); if (!ldev) { ret = -ENOMEM; goto out; @@ -566,8 +566,8 @@ static int i40e_client_setup_qvlist(struct i40e_info *ldev, struct i40e_qv_info *qv_info; u32 v_idx, i, reg_idx, reg; - ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info, - qvlist_info->num_vectors), GFP_KERNEL); + ldev->qvlist_info = kzalloc_flex(*ldev->qvlist_info, qv_info, + qvlist_info->num_vectors); if (!ldev->qvlist_info) return -ENOMEM; ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c index c17b5d290f0a..0b52509cb14c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c +++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c @@ -983,9 +983,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, int i, ret; u16 switch_id; - bw_data = kzalloc(sizeof( - struct i40e_aqc_query_port_ets_config_resp), - GFP_KERNEL); + bw_data = kzalloc_obj(struct i40e_aqc_query_port_ets_config_resp); if (!bw_data) { ret = -ENOMEM; goto command_write_done; @@ -1229,7 +1227,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, struct libie_aq_desc *desc; int ret; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) goto command_write_done; cnt = sscanf(&cmd_buf[11], @@ -1277,7 +1275,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp, u8 *buff; int ret; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) goto command_write_done; cnt = sscanf(&cmd_buf[20], diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 6a47ea0927e9..8c27f7ba4adc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -2120,8 +2120,7 @@ static int i40e_set_ringparam(struct net_device *netdev, netdev_info(netdev, "Changing Tx descriptor count from %d to %d.\n", vsi->tx_rings[0]->count, new_tx_count); - tx_rings = kcalloc(tx_alloc_queue_pairs, - sizeof(struct i40e_ring), GFP_KERNEL); + tx_rings = kzalloc_objs(struct i40e_ring, tx_alloc_queue_pairs); if (!tx_rings) { err = -ENOMEM; goto done; @@ -2159,8 +2158,8 @@ static int i40e_set_ringparam(struct net_device *netdev, netdev_info(netdev, "Changing Rx descriptor count from %d to %d\n", vsi->rx_rings[0]->count, new_rx_count); - rx_rings = kcalloc(vsi->alloc_queue_pairs, - sizeof(struct i40e_ring), GFP_KERNEL); + rx_rings = kzalloc_objs(struct i40e_ring, + vsi->alloc_queue_pairs); if (!rx_rings) { err = -ENOMEM; goto free_tx; @@ -3976,7 +3975,7 @@ static int i40e_add_flex_offset(struct list_head *flex_pit_list, { struct i40e_flex_pit *new_pit, *entry; - new_pit = kzalloc(sizeof(*entry), GFP_KERNEL); + new_pit = kzalloc_obj(*entry); if (!new_pit) return -ENOMEM; @@ -4867,7 +4866,7 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi, q_index = ring; } - input = kzalloc(sizeof(*input), GFP_KERNEL); + input = kzalloc_obj(*input); if (!input) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index d3bc3207054f..926d001b2150 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -75,7 +75,13 @@ static const struct pci_device_id i40e_pci_tbl[] = { {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T4), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T_BC), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_SFP), 0}, - {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_B), 0}, + /* + * This ID conflicts with ipw2200, but the devices can be differentiated + * because i40e devices use PCI_CLASS_NETWORK_ETHERNET and ipw2200 + * devices use PCI_CLASS_NETWORK_OTHER. + */ + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_10G_B), + PCI_CLASS_NETWORK_ETHERNET << 8, 0xffff00, 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_X722), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_X722), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0}, @@ -1456,7 +1462,7 @@ static int i40e_correct_mac_vlan_filters(struct i40e_vsi *vsi, return -ENOMEM; /* Create a temporary i40e_new_mac_filter */ - new = kzalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc_obj(*new, GFP_ATOMIC); if (!new) return -ENOMEM; @@ -1568,7 +1574,7 @@ static int i40e_correct_vf_mac_vlan_filters(struct i40e_vsi *vsi, if (!add_head) return -ENOMEM; /* Create a temporary i40e_new_mac_filter */ - new_mac = kzalloc(sizeof(*new_mac), GFP_ATOMIC); + new_mac = kzalloc_obj(*new_mac, GFP_ATOMIC); if (!new_mac) return -ENOMEM; new_mac->f = add_head; @@ -1645,7 +1651,7 @@ struct i40e_mac_filter *i40e_add_filter(struct i40e_vsi *vsi, f = i40e_find_filter(vsi, macaddr, vlan); if (!f) { - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return NULL; @@ -2600,7 +2606,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi) } if (f->state == I40E_FILTER_NEW) { /* Create a temporary i40e_new_mac_filter */ - new = kzalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc_obj(*new, GFP_ATOMIC); if (!new) goto err_no_memory_locked; @@ -3563,6 +3569,7 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) u16 pf_q = vsi->base_queue + ring->queue_index; struct i40e_hw *hw = &vsi->back->hw; struct i40e_hmc_obj_rxq rx_ctx; + u32 xdp_frame_sz; int err = 0; bool ok; @@ -3572,49 +3579,47 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) memset(&rx_ctx, 0, sizeof(rx_ctx)); ring->rx_buf_len = vsi->rx_buf_len; + xdp_frame_sz = i40e_rx_pg_size(ring) / 2; /* XDP RX-queue info only needed for RX rings exposed to XDP */ if (ring->vsi->type != I40E_VSI_MAIN) goto skip; - if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { - err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, - ring->queue_index, - ring->q_vector->napi.napi_id, - ring->rx_buf_len); - if (err) - return err; - } - ring->xsk_pool = i40e_xsk_pool(ring); if (ring->xsk_pool) { - xdp_rxq_info_unreg(&ring->xdp_rxq); + xdp_frame_sz = xsk_pool_get_rx_frag_step(ring->xsk_pool); ring->rx_buf_len = xsk_pool_get_rx_frame_size(ring->xsk_pool); err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, ring->queue_index, ring->q_vector->napi.napi_id, - ring->rx_buf_len); + xdp_frame_sz); if (err) return err; err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_XSK_BUFF_POOL, NULL); if (err) - return err; + goto unreg_xdp; dev_info(&vsi->back->pdev->dev, "Registered XDP mem model MEM_TYPE_XSK_BUFF_POOL on Rx ring %d\n", ring->queue_index); } else { + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->queue_index, + ring->q_vector->napi.napi_id, + xdp_frame_sz); + if (err) + return err; err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, MEM_TYPE_PAGE_SHARED, NULL); if (err) - return err; + goto unreg_xdp; } skip: - xdp_init_buff(&ring->xdp, i40e_rx_pg_size(ring) / 2, &ring->xdp_rxq); + xdp_init_buff(&ring->xdp, xdp_frame_sz, &ring->xdp_rxq); rx_ctx.dbuff = DIV_ROUND_UP(ring->rx_buf_len, BIT_ULL(I40E_RXQ_CTX_DBUFF_SHIFT)); @@ -3648,7 +3653,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) dev_info(&vsi->back->pdev->dev, "Failed to clear LAN Rx queue context on Rx ring %d (pf_q %d), error: %d\n", ring->queue_index, pf_q, err); - return -ENOMEM; + err = -ENOMEM; + goto unreg_xdp; } /* set the context in the HMC */ @@ -3657,7 +3663,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) dev_info(&vsi->back->pdev->dev, "Failed to set LAN Rx queue context on Rx ring %d (pf_q %d), error: %d\n", ring->queue_index, pf_q, err); - return -ENOMEM; + err = -ENOMEM; + goto unreg_xdp; } /* configure Rx buffer alignment */ @@ -3665,7 +3672,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) if (I40E_2K_TOO_SMALL_WITH_PADDING) { dev_info(&vsi->back->pdev->dev, "2k Rx buffer is too small to fit standard MTU and skb_shared_info\n"); - return -EOPNOTSUPP; + err = -EOPNOTSUPP; + goto unreg_xdp; } clear_ring_build_skb_enabled(ring); } else { @@ -3695,6 +3703,11 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring) } return 0; +unreg_xdp: + if (ring->vsi->type == I40E_VSI_MAIN) + xdp_rxq_info_unreg(&ring->xdp_rxq); + + return err; } /** @@ -6680,7 +6693,7 @@ static int i40e_configure_queue_channels(struct i40e_vsi *vsi) vsi->tc_seid_map[0] = vsi->seid; for (i = 1; i < I40E_MAX_TRAFFIC_CLASS; i++) { if (vsi->tc_config.enabled_tc & BIT(i)) { - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) { ret = -ENOMEM; goto err_free; @@ -7956,7 +7969,7 @@ static int i40e_setup_macvlans(struct i40e_vsi *vsi, u16 macvlan_cnt, u16 qcnt, /* Create channels for macvlans */ INIT_LIST_HEAD(&vsi->macvlan_list); for (i = 0; i < macvlan_cnt; i++) { - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) { ret = -ENOMEM; goto err_free; @@ -8068,7 +8081,7 @@ static void *i40e_fwd_add(struct net_device *netdev, struct net_device *vdev) return ERR_PTR(-EBUSY); /* create the fwd struct */ - fwd = kzalloc(sizeof(*fwd), GFP_KERNEL); + fwd = kzalloc_obj(*fwd); if (!fwd) return ERR_PTR(-ENOMEM); @@ -8829,7 +8842,7 @@ static int i40e_configure_clsflower(struct i40e_vsi *vsi, clear_bit(I40E_FLAG_FD_SB_TO_CLOUD_FILTER, vsi->back->flags); } - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; @@ -11534,7 +11547,7 @@ static int i40e_vsi_mem_alloc(struct i40e_pf *pf, enum i40e_vsi_type type) } pf->next_vsi = ++i; - vsi = kzalloc(sizeof(*vsi), GFP_KERNEL); + vsi = kzalloc_obj(*vsi); if (!vsi) { ret = -ENOMEM; goto unlock_pf; @@ -11705,7 +11718,7 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi) /* Set basic values in the rings to be used later during open() */ for (i = 0; i < vsi->alloc_queue_pairs; i++) { /* allocate space for both Tx and Rx in one shot */ - ring = kcalloc(qpv, sizeof(struct i40e_ring), GFP_KERNEL); + ring = kzalloc_objs(struct i40e_ring, qpv); if (!ring) goto err_out; @@ -11908,8 +11921,7 @@ static int i40e_init_msix(struct i40e_pf *pf) "Calculation of remaining vectors underflowed. This is an accounting bug when determining total MSI-X vectors.\n"); v_budget += pf->num_lan_msix; - pf->msix_entries = kcalloc(v_budget, sizeof(struct msix_entry), - GFP_KERNEL); + pf->msix_entries = kzalloc_objs(struct msix_entry, v_budget); if (!pf->msix_entries) return -ENOMEM; @@ -12022,7 +12034,7 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx) struct i40e_q_vector *q_vector; /* allocate q_vector */ - q_vector = kzalloc(sizeof(struct i40e_q_vector), GFP_KERNEL); + q_vector = kzalloc_obj(struct i40e_q_vector); if (!q_vector) return -ENOMEM; @@ -14575,7 +14587,7 @@ static int i40e_veb_mem_alloc(struct i40e_pf *pf) goto err_alloc_veb; /* out of VEB slots! */ } - veb = kzalloc(sizeof(*veb), GFP_KERNEL); + veb = kzalloc_obj(*veb); if (!veb) { ret = -ENOMEM; goto err_alloc_veb; @@ -15435,8 +15447,7 @@ static int i40e_init_recovery_mode(struct i40e_pf *pf, struct i40e_hw *hw) pf->num_alloc_vsi = pf->hw.func_caps.num_vsis; /* Set up the vsi struct and our local tracking of the MAIN PF vsi. */ - pf->vsi = kcalloc(pf->num_alloc_vsi, sizeof(struct i40e_vsi *), - GFP_KERNEL); + pf->vsi = kzalloc_objs(struct i40e_vsi *, pf->num_alloc_vsi); if (!pf->vsi) { err = -ENOMEM; goto err_switch_setup; @@ -15859,8 +15870,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Set up the *vsi struct and our local tracking of the MAIN PF vsi. */ - pf->vsi = kcalloc(pf->num_alloc_vsi, sizeof(struct i40e_vsi *), - GFP_KERNEL); + pf->vsi = kzalloc_objs(struct i40e_vsi *, pf->num_alloc_vsi); if (!pf->vsi) { err = -ENOMEM; goto err_switch_setup; diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index 33535418178b..404a716db8da 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c @@ -1132,7 +1132,7 @@ int i40e_ptp_alloc_pins(struct i40e_pf *pf) return 0; pf->ptp_pins = - kzalloc(sizeof(struct i40e_ptp_pins_settings), GFP_KERNEL); + kzalloc_obj(struct i40e_ptp_pins_settings); if (!pf->ptp_pins) { dev_warn(&pf->pdev->dev, "Cannot allocate memory for PTP pins structure.\n"); @@ -1344,9 +1344,8 @@ static int i40e_init_pin_config(struct i40e_pf *pf) pf->ptp_caps.pps = 1; pf->ptp_caps.n_per_out = 2; - pf->ptp_caps.pin_config = kcalloc(pf->ptp_caps.n_pins, - sizeof(*pf->ptp_caps.pin_config), - GFP_KERNEL); + pf->ptp_caps.pin_config = kzalloc_objs(*pf->ptp_caps.pin_config, + pf->ptp_caps.n_pins); if (!pf->ptp_caps.pin_config) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/i40e/i40e_trace.h b/drivers/net/ethernet/intel/i40e/i40e_trace.h index 759f3d1c4c8f..dde0ccd789ed 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_trace.h +++ b/drivers/net/ethernet/intel/i40e/i40e_trace.h @@ -88,7 +88,7 @@ TRACE_EVENT(i40e_napi_poll, __entry->rx_clean_complete = rx_clean_complete; __entry->tx_clean_complete = tx_clean_complete; __entry->irq_num = q->irq_num; - __entry->curr_cpu = get_cpu(); + __entry->curr_cpu = smp_processor_id(); __assign_str(qname); __assign_str(dev_name); __assign_bitmask(irq_affinity, cpumask_bits(&q->affinity_mask), diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index cc0b9efc2637..894f2d06d39d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1470,6 +1470,9 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring) if (!rx_ring->rx_bi) return; + if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); + if (rx_ring->xsk_pool) { i40e_xsk_clean_rx_ring(rx_ring); goto skip_free; @@ -1527,8 +1530,6 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring) void i40e_free_rx_resources(struct i40e_ring *rx_ring) { i40e_clean_rx_ring(rx_ring); - if (rx_ring->vsi->type == I40E_VSI_MAIN) - xdp_rxq_info_unreg(&rx_ring->xdp_rxq); rx_ring->xdp_prog = NULL; kfree(rx_ring->rx_bi); rx_ring->rx_bi = NULL; @@ -1572,7 +1573,7 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring) rx_ring->xdp_prog = rx_ring->vsi->xdp_prog; rx_ring->rx_bi = - kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL); + kzalloc_objs(*rx_ring->rx_bi, rx_ring->count); if (!rx_ring->rx_bi) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 1fa877b52f61..a26c3d47ec15 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -1261,7 +1261,7 @@ static void i40e_get_vlan_list_sync(struct i40e_vsi *vsi, u16 *num_vlans, spin_lock_bh(&vsi->mac_filter_hash_lock); *num_vlans = __i40e_getnum_vf_vsi_vlan_filters(vsi); - *vlan_list = kcalloc(*num_vlans, sizeof(**vlan_list), GFP_ATOMIC); + *vlan_list = kzalloc_objs(**vlan_list, *num_vlans, GFP_ATOMIC); if (!(*vlan_list)) goto err; @@ -1844,7 +1844,7 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs) } } /* allocate memory */ - vfs = kcalloc(num_alloc_vfs, sizeof(struct i40e_vf), GFP_KERNEL); + vfs = kzalloc_objs(struct i40e_vf, num_alloc_vfs); if (!vfs) { ret = -ENOMEM; goto err_alloc; @@ -3833,10 +3833,10 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) cfilter.n_proto = ETH_P_IP; if (mask.dst_ip[0] & tcf.dst_ip[0]) memcpy(&cfilter.ip.v4.dst_ip, tcf.dst_ip, - ARRAY_SIZE(tcf.dst_ip)); - else if (mask.src_ip[0] & tcf.dst_ip[0]) + sizeof(cfilter.ip.v4.dst_ip)); + else if (mask.src_ip[0] & tcf.src_ip[0]) memcpy(&cfilter.ip.v4.src_ip, tcf.src_ip, - ARRAY_SIZE(tcf.dst_ip)); + sizeof(cfilter.ip.v4.src_ip)); break; case VIRTCHNL_TCP_V6_FLOW: cfilter.n_proto = ETH_P_IPV6; @@ -3891,7 +3891,7 @@ static int i40e_vc_del_cloud_filter(struct i40e_vf *vf, u8 *msg) /* for ipv6, mask is set for all sixteen bytes (4 words) */ if (cfilter.n_proto == ETH_P_IPV6 && mask.dst_ip[3]) if (memcmp(&cfilter.ip.v6.dst_ip6, &cf->ip.v6.dst_ip6, - sizeof(cfilter.ip.v6.src_ip6))) + sizeof(cfilter.ip.v6.dst_ip6))) continue; if (mask.vlan_id) if (cfilter.vlan_id != cf->vlan_id) @@ -3956,7 +3956,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) goto err_out; } - cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL); + cfilter = kzalloc_obj(*cfilter); if (!cfilter) { aq_ret = -ENOMEM; goto err_out; @@ -3979,10 +3979,10 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) cfilter->n_proto = ETH_P_IP; if (mask.dst_ip[0] & tcf.dst_ip[0]) memcpy(&cfilter->ip.v4.dst_ip, tcf.dst_ip, - ARRAY_SIZE(tcf.dst_ip)); - else if (mask.src_ip[0] & tcf.dst_ip[0]) + sizeof(cfilter->ip.v4.dst_ip)); + else if (mask.src_ip[0] & tcf.src_ip[0]) memcpy(&cfilter->ip.v4.src_ip, tcf.src_ip, - ARRAY_SIZE(tcf.dst_ip)); + sizeof(cfilter->ip.v4.src_ip)); break; case VIRTCHNL_TCP_V6_FLOW: cfilter->n_proto = ETH_P_IPV6; diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index a87e0c6d4017..e9fb0a0919e3 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -260,7 +260,6 @@ struct iavf_adapter { struct work_struct adminq_task; struct work_struct finish_config; wait_queue_head_t down_waitqueue; - wait_queue_head_t reset_waitqueue; wait_queue_head_t vc_waitqueue; struct iavf_q_vector *q_vectors; struct list_head vlan_filter_list; @@ -626,5 +625,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, const u8 *macaddr); -int iavf_wait_for_reset(struct iavf_adapter *adapter); +void iavf_reset_step(struct iavf_adapter *adapter); #endif /* _IAVF_H_ */ diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 2cc21289a707..ab67c709d5a0 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -492,7 +492,6 @@ static int iavf_set_ringparam(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev); u32 new_rx_count, new_tx_count; - int ret = 0; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -537,13 +536,11 @@ static int iavf_set_ringparam(struct net_device *netdev, } if (netif_running(netdev)) { - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - ret = iavf_wait_for_reset(adapter); - if (ret) - netdev_warn(netdev, "Changing ring parameters timeout or interrupted waiting for reset"); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); } - return ret; + return 0; } /** @@ -1276,7 +1273,7 @@ static int iavf_add_fdir_ethtool(struct iavf_adapter *adapter, struct ethtool_rx } spin_unlock_bh(&adapter->fdir_fltr_lock); - fltr = kzalloc(sizeof(*fltr), GFP_KERNEL); + fltr = kzalloc_obj(*fltr); if (!fltr) return -ENOMEM; @@ -1519,7 +1516,7 @@ iavf_set_rxfh_fields(struct net_device *netdev, if (hash_flds == IAVF_ADV_RSS_HASH_INVALID) return -EINVAL; - rss_new = kzalloc(sizeof(*rss_new), GFP_KERNEL); + rss_new = kzalloc_obj(*rss_new); if (!rss_new) return -ENOMEM; @@ -1723,7 +1720,6 @@ static int iavf_set_channels(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev); u32 num_req = ch->combined_count; - int ret = 0; if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && adapter->num_tc) { @@ -1745,13 +1741,10 @@ static int iavf_set_channels(struct net_device *netdev, adapter->num_req_queues = num_req; adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); - ret = iavf_wait_for_reset(adapter); - if (ret) - netdev_warn(netdev, "Changing channel count timeout or interrupted waiting for reset"); - - return ret; + return 0; } /** diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 4b0fc8f354bc..7925ee152c76 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -185,31 +185,6 @@ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) return false; } -/** - * iavf_wait_for_reset - Wait for reset to finish. - * @adapter: board private structure - * - * Returns 0 if reset finished successfully, negative on timeout or interrupt. - */ -int iavf_wait_for_reset(struct iavf_adapter *adapter) -{ - int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, - !iavf_is_reset_in_progress(adapter), - msecs_to_jiffies(5000)); - - /* If ret < 0 then it means wait was interrupted. - * If ret == 0 then it means we got a timeout while waiting - * for reset to finish. - * If ret > 0 it means reset has finished. - */ - if (ret > 0) - return 0; - else if (ret < 0) - return -EINTR; - else - return -EBUSY; -} - /** * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code * @hw: pointer to the HW structure @@ -771,7 +746,7 @@ iavf_vlan_filter *iavf_add_vlan(struct iavf_adapter *adapter, f = iavf_find_vlan(adapter, vlan); if (!f) { - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) goto clearout; @@ -978,7 +953,7 @@ struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, f = iavf_find_filter(adapter, macaddr); if (!f) { - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) return f; @@ -1585,12 +1560,10 @@ static int iavf_alloc_queues(struct iavf_adapter *adapter) (int)(num_online_cpus())); - adapter->tx_rings = kcalloc(num_active_queues, - sizeof(struct iavf_ring), GFP_KERNEL); + adapter->tx_rings = kzalloc_objs(struct iavf_ring, num_active_queues); if (!adapter->tx_rings) goto err_out; - adapter->rx_rings = kcalloc(num_active_queues, - sizeof(struct iavf_ring), GFP_KERNEL); + adapter->rx_rings = kzalloc_objs(struct iavf_ring, num_active_queues); if (!adapter->rx_rings) goto err_out; @@ -1653,8 +1626,7 @@ static int iavf_set_interrupt_capability(struct iavf_adapter *adapter) v_budget = min_t(int, pairs + NONQ_VECS, (int)adapter->vf_res->max_vectors); - adapter->msix_entries = kcalloc(v_budget, - sizeof(struct msix_entry), GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, v_budget); if (!adapter->msix_entries) { err = -ENOMEM; goto out; @@ -1812,8 +1784,7 @@ static int iavf_alloc_q_vectors(struct iavf_adapter *adapter) struct iavf_q_vector *q_vector; num_q_vectors = adapter->num_msix_vectors - NONQ_VECS; - adapter->q_vectors = kcalloc(num_q_vectors, sizeof(*q_vector), - GFP_KERNEL); + adapter->q_vectors = kzalloc_objs(*q_vector, num_q_vectors); if (!adapter->q_vectors) return -ENOMEM; @@ -2797,7 +2768,22 @@ static void iavf_init_config_adapter(struct iavf_adapter *adapter) netdev->watchdog_timeo = 5 * HZ; netdev->min_mtu = ETH_MIN_MTU; - netdev->max_mtu = LIBIE_MAX_MTU; + + /* PF/VF API: vf_res->max_mtu is max frame size (not MTU). + * Convert to MTU. + */ + if (!adapter->vf_res->max_mtu) { + netdev->max_mtu = LIBIE_MAX_MTU; + } else if (adapter->vf_res->max_mtu < LIBETH_RX_LL_LEN + ETH_MIN_MTU || + adapter->vf_res->max_mtu > + LIBETH_RX_LL_LEN + LIBIE_MAX_MTU) { + netdev_warn_once(adapter->netdev, + "invalid max frame size %d from PF, using default MTU %d", + adapter->vf_res->max_mtu, LIBIE_MAX_MTU); + netdev->max_mtu = LIBIE_MAX_MTU; + } else { + netdev->max_mtu = adapter->vf_res->max_mtu - LIBETH_RX_LL_LEN; + } if (!is_valid_ether_addr(adapter->hw.mac.addr)) { dev_info(&pdev->dev, "Invalid MAC address %pM, using random\n", @@ -3025,6 +3011,8 @@ static void iavf_disable_vf(struct iavf_adapter *adapter) adapter->flags |= IAVF_FLAG_PF_COMMS_FAILED; + iavf_ptp_release(adapter); + /* We don't use netif_running() because it may be true prior to * ndo_open() returning, so we can't assume it means all our open * tasks have finished, since we're not holding the rtnl_lock here. @@ -3100,18 +3088,16 @@ static void iavf_reconfig_qs_bw(struct iavf_adapter *adapter) } /** - * iavf_reset_task - Call-back task to handle hardware reset - * @work: pointer to work_struct + * iavf_reset_step - Perform the VF reset sequence + * @adapter: board private structure * - * During reset we need to shut down and reinitialize the admin queue - * before we can use it to communicate with the PF again. We also clear - * and reinit the rings because that context is lost as well. - **/ -static void iavf_reset_task(struct work_struct *work) + * Requests a reset from PF, polls for completion, and reconfigures + * the driver. Caller must hold the netdev instance lock. + * + * This can sleep for several seconds while polling HW registers. + */ +void iavf_reset_step(struct iavf_adapter *adapter) { - struct iavf_adapter *adapter = container_of(work, - struct iavf_adapter, - reset_task); struct virtchnl_vf_resource *vfres = adapter->vf_res; struct net_device *netdev = adapter->netdev; struct iavf_hw *hw = &adapter->hw; @@ -3122,7 +3108,7 @@ static void iavf_reset_task(struct work_struct *work) int i = 0, err; bool running; - netdev_lock(netdev); + netdev_assert_locked(netdev); iavf_misc_irq_disable(adapter); if (adapter->flags & IAVF_FLAG_RESET_NEEDED) { @@ -3167,7 +3153,6 @@ static void iavf_reset_task(struct work_struct *work) dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", reg_val); iavf_disable_vf(adapter); - netdev_unlock(netdev); return; /* Do not attempt to reinit. It's dead, Jim. */ } @@ -3179,7 +3164,6 @@ static void iavf_reset_task(struct work_struct *work) iavf_startup(adapter); queue_delayed_work(adapter->wq, &adapter->watchdog_task, msecs_to_jiffies(30)); - netdev_unlock(netdev); return; } @@ -3200,6 +3184,8 @@ static void iavf_reset_task(struct work_struct *work) iavf_change_state(adapter, __IAVF_RESETTING); adapter->flags &= ~IAVF_FLAG_RESET_PENDING; + iavf_ptp_release(adapter); + /* free the Tx/Rx rings and descriptors, might be better to just * re-use them sometime in the future */ @@ -3320,9 +3306,6 @@ static void iavf_reset_task(struct work_struct *work) adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; - wake_up(&adapter->reset_waitqueue); - netdev_unlock(netdev); - return; reset_err: if (running) { @@ -3331,10 +3314,21 @@ static void iavf_reset_task(struct work_struct *work) } iavf_disable_vf(adapter); - netdev_unlock(netdev); dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); } +static void iavf_reset_task(struct work_struct *work) +{ + struct iavf_adapter *adapter = container_of(work, + struct iavf_adapter, + reset_task); + struct net_device *netdev = adapter->netdev; + + netdev_lock(netdev); + iavf_reset_step(adapter); + netdev_unlock(netdev); +} + /** * iavf_adminq_task - worker thread to clean the admin queue * @work: pointer to work_struct containing our data @@ -4119,7 +4113,7 @@ static int iavf_configure_clsflower(struct iavf_adapter *adapter, return -EINVAL; } - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; filter->cookie = cls_flower->cookie; @@ -4234,7 +4228,7 @@ static int iavf_add_cls_u32(struct iavf_adapter *adapter, return -EOPNOTSUPP; } - fltr = kzalloc(sizeof(*fltr), GFP_KERNEL); + fltr = kzalloc_obj(*fltr); if (!fltr) return -ENOMEM; @@ -4600,22 +4594,17 @@ static int iavf_close(struct net_device *netdev) static int iavf_change_mtu(struct net_device *netdev, int new_mtu) { struct iavf_adapter *adapter = netdev_priv(netdev); - int ret = 0; netdev_dbg(netdev, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); WRITE_ONCE(netdev->mtu, new_mtu); if (netif_running(netdev)) { - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - ret = iavf_wait_for_reset(adapter); - if (ret < 0) - netdev_warn(netdev, "MTU change interrupted waiting for reset"); - else if (ret) - netdev_warn(netdev, "MTU change timed out waiting for reset"); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); } - return ret; + return 0; } /** @@ -5420,9 +5409,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* Setup the wait queue for indicating transition to down status */ init_waitqueue_head(&adapter->down_waitqueue); - /* Setup the wait queue for indicating transition to running state */ - init_waitqueue_head(&adapter->reset_waitqueue); - /* Setup the wait queue for indicating virtchannel events */ init_waitqueue_head(&adapter->vc_waitqueue); diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.c b/drivers/net/ethernet/intel/iavf/iavf_ptp.c index 9cbd8c154031..87b97e09df14 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ptp.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.c @@ -133,7 +133,7 @@ static struct iavf_ptp_aq_cmd *iavf_allocate_ptp_cmd(enum virtchnl_ops v_opcode, { struct iavf_ptp_aq_cmd *cmd; - cmd = kzalloc(struct_size(cmd, msg, msglen), GFP_KERNEL); + cmd = kzalloc_flex(*cmd, msg, msglen); if (!cmd) return NULL; diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c index 88156082a41d..a52c100dcbc5 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c +++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c @@ -2736,7 +2736,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter, case VIRTCHNL_OP_ENABLE_QUEUES: /* enable transmits */ iavf_irq_enable(adapter, true); - wake_up(&adapter->reset_waitqueue); adapter->flags &= ~IAVF_FLAG_QUEUES_DISABLED; break; case VIRTCHNL_OP_DISABLE_QUEUES: diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c index 2ef39cc70c21..6144cee8034d 100644 --- a/drivers/net/ethernet/intel/ice/devlink/devlink.c +++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c @@ -285,7 +285,7 @@ static int ice_devlink_info_get(struct devlink *devlink, return err; } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -1360,7 +1360,7 @@ ice_devlink_enable_roce_get(struct devlink *devlink, u32 id, cdev = pf->cdev_info; if (!cdev) - return -ENODEV; + return -EOPNOTSUPP; ctx->val.vbool = !!(cdev->rdma_protocol & IIDC_RDMA_PROTOCOL_ROCEV2); @@ -1427,7 +1427,7 @@ ice_devlink_enable_iw_get(struct devlink *devlink, u32 id, cdev = pf->cdev_info; if (!cdev) - return -ENODEV; + return -EOPNOTSUPP; ctx->val.vbool = !!(cdev->rdma_protocol & IIDC_RDMA_PROTOCOL_IWARP); diff --git a/drivers/net/ethernet/intel/ice/devlink/port.c b/drivers/net/ethernet/intel/ice/devlink/port.c index 63fb36fc4b3d..2a2e56777f9f 100644 --- a/drivers/net/ethernet/intel/ice/devlink/port.c +++ b/drivers/net/ethernet/intel/ice/devlink/port.c @@ -58,8 +58,8 @@ static void ice_devlink_port_options_print(struct ice_pf *pf) const char *str; int status; - options = kcalloc(ICE_AQC_PORT_OPT_MAX * ICE_MAX_PORT_PER_PCI_DEV, - sizeof(*options), GFP_KERNEL); + options = kzalloc_objs(*options, + ICE_AQC_PORT_OPT_MAX * ICE_MAX_PORT_PER_PCI_DEV); if (!options) return; @@ -920,7 +920,7 @@ ice_alloc_dynamic_port(struct ice_pf *pf, if (err) return err; - dyn_port = kzalloc(sizeof(*dyn_port), GFP_KERNEL); + dyn_port = kzalloc_obj(*dyn_port); if (!dyn_port) { err = -ENOMEM; goto unroll_reserve_sf_num; diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h index def7efa15447..2b2b22af42be 100644 --- a/drivers/net/ethernet/intel/ice/ice.h +++ b/drivers/net/ethernet/intel/ice/ice.h @@ -987,6 +987,7 @@ int ice_schedule_reset(struct ice_pf *pf, enum ice_reset_req reset); void ice_print_link_msg(struct ice_vsi *vsi, bool isup); int ice_plug_aux_dev(struct ice_pf *pf); void ice_unplug_aux_dev(struct ice_pf *pf); +void ice_rdma_finalize_setup(struct ice_pf *pf); int ice_init_rdma(struct ice_pf *pf); void ice_deinit_rdma(struct ice_pf *pf); bool ice_is_wol_supported(struct ice_hw *hw); diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c index 0a8a48cd4bce..cbb57060bd56 100644 --- a/drivers/net/ethernet/intel/ice/ice_adapter.c +++ b/drivers/net/ethernet/intel/ice/ice_adapter.c @@ -55,7 +55,7 @@ static struct ice_adapter *ice_adapter_new(struct pci_dev *pdev) { struct ice_adapter *adapter; - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) return NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_arfs.c b/drivers/net/ethernet/intel/ice/ice_arfs.c index 1f7834c03550..53b6e2b09eb9 100644 --- a/drivers/net/ethernet/intel/ice/ice_arfs.c +++ b/drivers/net/ethernet/intel/ice/ice_arfs.c @@ -534,13 +534,11 @@ static int ice_init_arfs_cntrs(struct ice_vsi *vsi) if (!vsi || vsi->type != ICE_VSI_PF) return -EINVAL; - vsi->arfs_fltr_cntrs = kzalloc(sizeof(*vsi->arfs_fltr_cntrs), - GFP_KERNEL); + vsi->arfs_fltr_cntrs = kzalloc_obj(*vsi->arfs_fltr_cntrs); if (!vsi->arfs_fltr_cntrs) return -ENOMEM; - vsi->arfs_last_fltr_id = kzalloc(sizeof(*vsi->arfs_last_fltr_id), - GFP_KERNEL); + vsi->arfs_last_fltr_id = kzalloc_obj(*vsi->arfs_last_fltr_id); if (!vsi->arfs_last_fltr_id) { kfree(vsi->arfs_fltr_cntrs); vsi->arfs_fltr_cntrs = NULL; @@ -562,8 +560,7 @@ void ice_init_arfs(struct ice_vsi *vsi) if (!vsi || vsi->type != ICE_VSI_PF || ice_is_arfs_active(vsi)) return; - arfs_fltr_list = kcalloc(ICE_MAX_ARFS_LIST, sizeof(*arfs_fltr_list), - GFP_KERNEL); + arfs_fltr_list = kzalloc_objs(*arfs_fltr_list, ICE_MAX_ARFS_LIST); if (!arfs_fltr_list) return; diff --git a/drivers/net/ethernet/intel/ice/ice_base.c b/drivers/net/ethernet/intel/ice/ice_base.c index afbff8aa9ceb..1667f686ff75 100644 --- a/drivers/net/ethernet/intel/ice/ice_base.c +++ b/drivers/net/ethernet/intel/ice/ice_base.c @@ -107,7 +107,7 @@ static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx) int err; /* allocate q_vector */ - q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); + q_vector = kzalloc_obj(*q_vector); if (!q_vector) return -ENOMEM; @@ -124,6 +124,8 @@ static int ice_vsi_alloc_q_vector(struct ice_vsi *vsi, u16 v_idx) if (vsi->type == ICE_VSI_VF) { ice_calc_vf_reg_idx(vsi->vf, q_vector); goto out; + } else if (vsi->type == ICE_VSI_LB) { + goto skip_alloc; } else if (vsi->type == ICE_VSI_CTRL && vsi->vf) { struct ice_vsi *ctrl_vsi = ice_get_vf_ctrl_vsi(pf, vsi); @@ -659,33 +661,22 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring) { struct device *dev = ice_pf_to_dev(ring->vsi->back); u32 num_bufs = ICE_DESC_UNUSED(ring); - u32 rx_buf_len; int err; - if (ring->vsi->type == ICE_VSI_PF || ring->vsi->type == ICE_VSI_SF) { - if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { - err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, - ring->q_index, - ring->q_vector->napi.napi_id, - ring->rx_buf_len); - if (err) - return err; - } - + if (ring->vsi->type == ICE_VSI_PF || ring->vsi->type == ICE_VSI_SF || + ring->vsi->type == ICE_VSI_LB) { ice_rx_xsk_pool(ring); err = ice_realloc_rx_xdp_bufs(ring, ring->xsk_pool); if (err) return err; if (ring->xsk_pool) { - xdp_rxq_info_unreg(&ring->xdp_rxq); - - rx_buf_len = - xsk_pool_get_rx_frame_size(ring->xsk_pool); + u32 frag_size = + xsk_pool_get_rx_frag_step(ring->xsk_pool); err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, ring->q_index, ring->q_vector->napi.napi_id, - rx_buf_len); + frag_size); if (err) return err; err = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq, @@ -702,14 +693,13 @@ static int ice_vsi_cfg_rxq(struct ice_rx_ring *ring) if (err) return err; - if (!xdp_rxq_info_is_reg(&ring->xdp_rxq)) { - err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, - ring->q_index, - ring->q_vector->napi.napi_id, - ring->rx_buf_len); - if (err) - goto err_destroy_fq; - } + err = __xdp_rxq_info_reg(&ring->xdp_rxq, ring->netdev, + ring->q_index, + ring->q_vector->napi.napi_id, + ring->truesize); + if (err) + goto err_destroy_fq; + xdp_rxq_info_attach_page_pool(&ring->xdp_rxq, ring->pp); } diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c index 64e798b8f18f..ce11fea122d0 100644 --- a/drivers/net/ethernet/intel/ice/ice_common.c +++ b/drivers/net/ethernet/intel/ice/ice_common.c @@ -1067,7 +1067,7 @@ int ice_init_hw(struct ice_hw *hw) if (status) goto err_unroll_sched; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) { status = -ENOMEM; goto err_unroll_sched; @@ -1103,8 +1103,7 @@ int ice_init_hw(struct ice_hw *hw) /* Get MAC information */ /* A single port can report up to two (LAN and WoL) addresses */ - mac_buf = kcalloc(2, sizeof(struct ice_aqc_manage_mac_read_resp), - GFP_KERNEL); + mac_buf = kzalloc_objs(struct ice_aqc_manage_mac_read_resp, 2); if (!mac_buf) { status = -ENOMEM; goto err_unroll_fltr_mgmt_struct; @@ -1817,6 +1816,7 @@ static bool ice_should_retry_sq_send_cmd(u16 opcode) case ice_aqc_opc_lldp_stop: case ice_aqc_opc_lldp_start: case ice_aqc_opc_lldp_filter_ctrl: + case ice_aqc_opc_sff_eeprom: return true; } @@ -1842,6 +1842,7 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq, { struct libie_aq_desc desc_cpy; bool is_cmd_for_retry; + u8 *buf_cpy = NULL; u8 idx = 0; u16 opcode; int status; @@ -1851,8 +1852,11 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq, memset(&desc_cpy, 0, sizeof(desc_cpy)); if (is_cmd_for_retry) { - /* All retryable cmds are direct, without buf. */ - WARN_ON(buf); + if (buf) { + buf_cpy = kmemdup(buf, buf_size, GFP_KERNEL); + if (!buf_cpy) + return -ENOMEM; + } memcpy(&desc_cpy, desc, sizeof(desc_cpy)); } @@ -1864,12 +1868,14 @@ ice_sq_send_cmd_retry(struct ice_hw *hw, struct ice_ctl_q_info *cq, hw->adminq.sq_last_status != LIBIE_AQ_RC_EBUSY) break; + if (buf_cpy) + memcpy(buf, buf_cpy, buf_size); memcpy(desc, &desc_cpy, sizeof(desc_cpy)); - msleep(ICE_SQ_SEND_DELAY_TIME_MS); } while (++idx < ICE_SQ_SEND_MAX_EXECUTE); + kfree(buf_cpy); return status; } @@ -3630,7 +3636,7 @@ int ice_update_link_info(struct ice_port_info *pi) if (li->link_info & ICE_AQ_MEDIA_AVAILABLE) { struct ice_aqc_get_phy_caps_data *pcaps __free(kfree) = NULL; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -3881,7 +3887,7 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) *aq_failures = 0; hw = pi->hw; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -4020,7 +4026,7 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, hw = pi->hw; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -4358,7 +4364,7 @@ int ice_get_phy_lane_number(struct ice_hw *hw) hw->device_id == ICE_DEV_ID_E825C_SGMII) return hw->pf_id; - options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL); + options = kzalloc_objs(*options, ICE_AQC_PORT_OPT_MAX); if (!options) return -ENOMEM; @@ -6392,7 +6398,7 @@ int ice_lldp_fltr_add_remove(struct ice_hw *hw, struct ice_vsi *vsi, bool add) struct ice_aqc_lldp_filter_ctrl *cmd; struct libie_aq_desc desc; - if (vsi->type != ICE_VSI_PF || !ice_fw_supports_lldp_fltr_ctrl(hw)) + if (!ice_fw_supports_lldp_fltr_ctrl(hw)) return -EOPNOTSUPP; cmd = libie_aq_raw(&desc); diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c index 9fc8681cc58e..bd77f1c001ee 100644 --- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c @@ -399,7 +399,7 @@ int ice_pf_dcb_cfg(struct ice_pf *pf, struct ice_dcbx_cfg *new_cfg, bool locked) } /* Notify AUX drivers about impending change to TCs */ - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) { ret = -ENOMEM; goto free_cfg; @@ -575,7 +575,7 @@ void ice_dcb_rebuild(struct ice_pf *pf) dcb_error: dev_err(dev, "Disabling DCB until new settings occur\n"); - err_cfg = kzalloc(sizeof(*err_cfg), GFP_KERNEL); + err_cfg = kzalloc_obj(*err_cfg); if (!err_cfg) { mutex_unlock(&pf->tc_mutex); return; @@ -641,7 +641,7 @@ int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool ets_willing, bool locked) hw = &pf->hw; pi = hw->port_info; - dcbcfg = kzalloc(sizeof(*dcbcfg), GFP_KERNEL); + dcbcfg = kzalloc_obj(*dcbcfg); if (!dcbcfg) return -ENOMEM; @@ -791,7 +791,7 @@ void ice_pf_dcb_recfg(struct ice_pf *pf, bool locked) privd = cdev->iidc_priv; ice_setup_dcb_qos_info(pf, &privd->qos_info); /* Notify the AUX drivers that TC change is finished */ - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) return; diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c index baf02512d041..62f75701d652 100644 --- a/drivers/net/ethernet/intel/ice/ice_dpll.c +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c @@ -3276,7 +3276,7 @@ static int ice_dpll_pin_notify(struct notifier_block *nb, unsigned long action, if (pin->fwnode != info->fwnode) return NOTIFY_DONE; /* Not this pin */ - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return NOTIFY_DONE; @@ -4145,7 +4145,7 @@ static int ice_dpll_init_info_e825c(struct ice_pf *pf) d->clock_id = ice_generate_clock_id(pf); d->num_inputs = ICE_SYNCE_CLK_NUM; - d->inputs = kcalloc(d->num_inputs, sizeof(*d->inputs), GFP_KERNEL); + d->inputs = kzalloc_objs(*d->inputs, d->num_inputs); if (!d->inputs) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c index cccb7ddf61c9..1d8a6b95ccda 100644 --- a/drivers/net/ethernet/intel/ice/ice_eswitch_br.c +++ b/drivers/net/ethernet/intel/ice/ice_eswitch_br.c @@ -129,11 +129,11 @@ ice_eswitch_br_fwd_rule_create(struct ice_hw *hw, int vsi_idx, int port_type, lkups_cnt = ice_eswitch_br_get_lkups_cnt(vid); - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return ERR_PTR(-ENOMEM); - list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC); + list = kzalloc_objs(*list, lkups_cnt, GFP_ATOMIC); if (!list) { err = -ENOMEM; goto err_list_alloc; @@ -190,11 +190,11 @@ ice_eswitch_br_guard_rule_create(struct ice_hw *hw, u16 vsi_idx, lkups_cnt = ice_eswitch_br_get_lkups_cnt(vid); - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) goto err_exit; - list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC); + list = kzalloc_objs(*list, lkups_cnt, GFP_ATOMIC); if (!list) goto err_list_alloc; @@ -233,7 +233,7 @@ ice_eswitch_br_flow_create(struct device *dev, struct ice_hw *hw, int vsi_idx, struct ice_esw_br_flow *flow; int err; - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (!flow) return ERR_PTR(-ENOMEM); @@ -418,7 +418,7 @@ ice_eswitch_br_fdb_entry_create(struct net_device *netdev, if (fdb_entry) ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, fdb_entry); - fdb_entry = kzalloc(sizeof(*fdb_entry), GFP_KERNEL); + fdb_entry = kzalloc_obj(*fdb_entry); if (!fdb_entry) { err = -ENOMEM; goto err_exit; @@ -513,7 +513,7 @@ ice_eswitch_br_fdb_work_alloc(struct switchdev_notifier_fdb_info *fdb_info, struct ice_esw_br_fdb_work *work; unsigned char *mac; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return ERR_PTR(-ENOMEM); @@ -698,7 +698,7 @@ ice_eswitch_br_vlan_create(u16 vid, u16 flags, struct ice_esw_br_port *port) struct ice_esw_br_vlan *vlan; int err; - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return ERR_PTR(-ENOMEM); @@ -916,7 +916,7 @@ ice_eswitch_br_port_init(struct ice_esw_br *bridge) { struct ice_esw_br_port *br_port; - br_port = kzalloc(sizeof(*br_port), GFP_KERNEL); + br_port = kzalloc_obj(*br_port); if (!br_port) return ERR_PTR(-ENOMEM); @@ -1013,7 +1013,7 @@ ice_eswitch_br_init(struct ice_esw_br_offloads *br_offloads, int ifindex) struct ice_esw_br *bridge; int err; - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return ERR_PTR(-ENOMEM); @@ -1217,7 +1217,7 @@ ice_eswitch_br_offloads_alloc(struct ice_pf *pf) if (pf->eswitch.br_offloads) return ERR_PTR(-EEXIST); - br_offloads = kzalloc(sizeof(*br_offloads), GFP_KERNEL); + br_offloads = kzalloc_obj(*br_offloads); if (!br_offloads) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index c6bc29cfb8e6..301947d53ede 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -1289,6 +1289,10 @@ static u64 ice_loopback_test(struct net_device *netdev) test_vsi->netdev = netdev; tx_ring = test_vsi->tx_rings[0]; rx_ring = test_vsi->rx_rings[0]; + /* Dummy q_vector and napi. Fill the minimum required for + * ice_rxq_pp_create(). + */ + rx_ring->q_vector->napi.dev = netdev; if (ice_lbtest_prepare_rings(test_vsi)) { ret = 2; @@ -1652,7 +1656,7 @@ ice_get_fecparam(struct net_device *netdev, struct ethtool_fecparam *fecparam) break; } - caps = kzalloc(sizeof(*caps), GFP_KERNEL); + caps = kzalloc_obj(*caps); if (!caps) return -ENOMEM; @@ -2364,7 +2368,7 @@ ice_get_link_ksettings(struct net_device *netdev, /* flow control is symmetric and always supported */ ethtool_link_ksettings_add_link_mode(ks, supported, Pause); - caps = kzalloc(sizeof(*caps), GFP_KERNEL); + caps = kzalloc_obj(*caps); if (!caps) return -ENOMEM; @@ -2629,7 +2633,7 @@ ice_set_link_ksettings(struct net_device *netdev, pi->phy.link_info.link_info & ICE_AQ_LINK_UP) return -EOPNOTSUPP; - phy_caps = kzalloc(sizeof(*phy_caps), GFP_KERNEL); + phy_caps = kzalloc_obj(*phy_caps); if (!phy_caps) return -ENOMEM; @@ -3265,7 +3269,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, netdev_info(netdev, "Changing Tx descriptor count from %d to %d\n", vsi->tx_rings[0]->count, new_tx_cnt); - tx_rings = kcalloc(vsi->num_txq, sizeof(*tx_rings), GFP_KERNEL); + tx_rings = kzalloc_objs(*tx_rings, vsi->num_txq); if (!tx_rings) { err = -ENOMEM; goto done; @@ -3295,7 +3299,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, netdev_info(netdev, "Changing XDP descriptor count from %d to %d\n", vsi->xdp_rings[0]->count, new_tx_cnt); - xdp_rings = kcalloc(vsi->num_xdp_txq, sizeof(*xdp_rings), GFP_KERNEL); + xdp_rings = kzalloc_objs(*xdp_rings, vsi->num_xdp_txq); if (!xdp_rings) { err = -ENOMEM; goto free_tx; @@ -3325,10 +3329,10 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, netdev_info(netdev, "Changing Rx descriptor count from %d to %d\n", vsi->rx_rings[0]->count, new_rx_cnt); - rx_rings = kcalloc(vsi->num_rxq, sizeof(*rx_rings), GFP_KERNEL); + rx_rings = kzalloc_objs(*rx_rings, vsi->num_rxq); if (!rx_rings) { err = -ENOMEM; - goto done; + goto free_xdp; } ice_for_each_rxq(vsi, i) { @@ -3338,6 +3342,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, rx_rings[i].cached_phctime = pf->ptp.cached_phc_time; rx_rings[i].desc = NULL; rx_rings[i].xdp_buf = NULL; + rx_rings[i].xdp_rxq = (struct xdp_rxq_info){ }; /* this is to allow wr32 to have something to write to * during early allocation of Rx buffers @@ -3355,7 +3360,7 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, } kfree(rx_rings); err = -ENOMEM; - goto free_tx; + goto free_xdp; } } @@ -3407,6 +3412,13 @@ ice_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring, } goto done; +free_xdp: + if (xdp_rings) { + ice_for_each_xdp_txq(vsi, i) + ice_free_tx_ring(&xdp_rings[i]); + kfree(xdp_rings); + } + free_tx: /* error cleanup if the Rx allocations failed after getting Tx */ if (tx_rings) { @@ -3445,7 +3457,7 @@ ice_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) dcbx_cfg = &pi->qos_cfg.local_dcbx_cfg; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return; @@ -3511,7 +3523,7 @@ ice_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) * so compare pause->autoneg with SW configured to prevent the user from * using set pause param to chance autoneg. */ - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -4505,7 +4517,7 @@ ice_get_module_eeprom(struct net_device *netdev, u8 addr = ICE_I2C_EEPROM_DEV_ADDR; struct ice_hw *hw = &pf->hw; bool is_sfp = false; - unsigned int i, j; + unsigned int i; u16 offset = 0; u8 page = 0; int status; @@ -4547,26 +4559,19 @@ ice_get_module_eeprom(struct net_device *netdev, if (page == 0 || !(data[0x2] & 0x4)) { u32 copy_len; - /* If i2c bus is busy due to slow page change or - * link management access, call can fail. This is normal. - * So we retry this a few times. - */ - for (j = 0; j < 4; j++) { - status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, - !is_sfp, value, - SFF_READ_BLOCK_SIZE, - 0, NULL); - netdev_dbg(netdev, "SFF %02X %02X %02X %X = %02X%02X%02X%02X.%02X%02X%02X%02X (%X)\n", - addr, offset, page, is_sfp, - value[0], value[1], value[2], value[3], - value[4], value[5], value[6], value[7], - status); - if (status) { - usleep_range(1500, 2500); - memset(value, 0, SFF_READ_BLOCK_SIZE); - continue; - } - break; + status = ice_aq_sff_eeprom(hw, 0, addr, offset, page, + !is_sfp, value, + SFF_READ_BLOCK_SIZE, + 0, NULL); + netdev_dbg(netdev, "SFF %02X %02X %02X %X = %02X%02X%02X%02X.%02X%02X%02X%02X (%pe)\n", + addr, offset, page, is_sfp, + value[0], value[1], value[2], value[3], + value[4], value[5], value[6], value[7], + ERR_PTR(status)); + if (status) { + netdev_err(netdev, "%s: error reading module EEPROM: status %pe\n", + __func__, ERR_PTR(status)); + return status; } /* Make sure we have enough room for the new block */ diff --git a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c index c0dbec369366..bb1d12f952cf 100644 --- a/drivers/net/ethernet/intel/ice/ice_flex_pipe.c +++ b/drivers/net/ethernet/intel/ice/ice_flex_pipe.c @@ -3734,7 +3734,7 @@ ice_adj_prof_priorities(struct ice_hw *hw, enum ice_block blk, u16 vsig, int status = 0; u16 idx; - attr_used = kcalloc(ICE_MAX_PTG_ATTRS, sizeof(*attr_used), GFP_KERNEL); + attr_used = kzalloc_objs(*attr_used, ICE_MAX_PTG_ATTRS); if (!attr_used) return -ENOMEM; @@ -4021,7 +4021,7 @@ ice_find_prof_vsig(struct ice_hw *hw, enum ice_block blk, u64 hdl, u16 *vsig) INIT_LIST_HEAD(&lst); - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) return false; diff --git a/drivers/net/ethernet/intel/ice/ice_flow.c b/drivers/net/ethernet/intel/ice/ice_flow.c index c9b6d0a84bd1..121552c644cd 100644 --- a/drivers/net/ethernet/intel/ice/ice_flow.c +++ b/drivers/net/ethernet/intel/ice/ice_flow.c @@ -1468,7 +1468,7 @@ ice_flow_add_prof_sync(struct ice_hw *hw, enum ice_block blk, if (prof_id >= ids->count) return -ENOSPC; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -1661,7 +1661,7 @@ ice_flow_set_parser_prof(struct ice_hw *hw, u16 dest_vsi, u16 fdir_vsi, int status; int i, idx; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -2552,7 +2552,7 @@ ice_add_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; - segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); + segs = kzalloc_objs(*segs, segs_cnt); if (!segs) return -ENOMEM; @@ -2699,7 +2699,7 @@ ice_rem_rss_cfg_sync(struct ice_hw *hw, u16 vsi_handle, segs_cnt = (cfg->hdr_type == ICE_RSS_OUTER_HEADERS) ? ICE_FLOW_SEG_SINGLE : ICE_FLOW_SEG_MAX; - segs = kcalloc(segs_cnt, sizeof(*segs), GFP_KERNEL); + segs = kzalloc_objs(*segs, segs_cnt); if (!segs) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.c b/drivers/net/ethernet/intel/ice/ice_fw_update.c index 973a13d3d92a..c143e546dd8c 100644 --- a/drivers/net/ethernet/intel/ice/ice_fw_update.c +++ b/drivers/net/ethernet/intel/ice/ice_fw_update.c @@ -862,7 +862,7 @@ int ice_get_pending_updates(struct ice_pf *pf, u8 *pending, struct ice_hw *hw = &pf->hw; int err; - dev_caps = kzalloc(sizeof(*dev_caps), GFP_KERNEL); + dev_caps = kzalloc_obj(*dev_caps); if (!dev_caps) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_gnss.c b/drivers/net/ethernet/intel/ice/ice_gnss.c index 6b26290452d4..8fd954f1ebd6 100644 --- a/drivers/net/ethernet/intel/ice/ice_gnss.c +++ b/drivers/net/ethernet/intel/ice/ice_gnss.c @@ -174,7 +174,7 @@ static struct gnss_serial *ice_gnss_struct_init(struct ice_pf *pf) struct kthread_worker *kworker; struct gnss_serial *gnss; - gnss = kzalloc(sizeof(*gnss), GFP_KERNEL); + gnss = kzalloc_obj(*gnss); if (!gnss) return NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_idc.c b/drivers/net/ethernet/intel/ice/ice_idc.c index 420d45c2558b..102d63c3018b 100644 --- a/drivers/net/ethernet/intel/ice/ice_idc.c +++ b/drivers/net/ethernet/intel/ice/ice_idc.c @@ -308,7 +308,7 @@ int ice_plug_aux_dev(struct ice_pf *pf) if (!cdev) return -ENODEV; - iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); + iadev = kzalloc_obj(*iadev); if (!iadev) return -ENOMEM; @@ -360,6 +360,39 @@ void ice_unplug_aux_dev(struct ice_pf *pf) auxiliary_device_uninit(adev); } +/** + * ice_rdma_finalize_setup - Complete RDMA setup after VSI is ready + * @pf: ptr to ice_pf + * + * Sets VSI-dependent information and plugs aux device. + * Must be called after ice_init_rdma(), ice_vsi_rebuild(), and + * ice_dcb_rebuild() complete. + */ +void ice_rdma_finalize_setup(struct ice_pf *pf) +{ + struct device *dev = ice_pf_to_dev(pf); + struct iidc_rdma_priv_dev_info *privd; + int ret; + + if (!ice_is_rdma_ena(pf) || !pf->cdev_info) + return; + + privd = pf->cdev_info->iidc_priv; + if (!privd || !pf->vsi || !pf->vsi[0] || !pf->vsi[0]->netdev) + return; + + /* Assign VSI info now that VSI is valid */ + privd->netdev = pf->vsi[0]->netdev; + privd->vport_id = pf->vsi[0]->vsi_num; + + /* Update QoS info after DCB has been rebuilt */ + ice_setup_dcb_qos_info(pf, &privd->qos_info); + + ret = ice_plug_aux_dev(pf); + if (ret) + dev_warn(dev, "Failed to plug RDMA aux device: %d\n", ret); +} + /** * ice_init_rdma - initializes PF for RDMA use * @pf: ptr to ice_pf @@ -376,13 +409,13 @@ int ice_init_rdma(struct ice_pf *pf) return 0; } - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return -ENOMEM; pf->cdev_info = cdev; - privd = kzalloc(sizeof(*privd), GFP_KERNEL); + privd = kzalloc_obj(*privd); if (!privd) { ret = -ENOMEM; goto err_privd_alloc; @@ -398,22 +431,14 @@ int ice_init_rdma(struct ice_pf *pf) } cdev->iidc_priv = privd; - privd->netdev = pf->vsi[0]->netdev; privd->hw_addr = (u8 __iomem *)pf->hw.hw_addr; cdev->pdev = pf->pdev; - privd->vport_id = pf->vsi[0]->vsi_num; pf->cdev_info->rdma_protocol |= IIDC_RDMA_PROTOCOL_ROCEV2; - ice_setup_dcb_qos_info(pf, &privd->qos_info); - ret = ice_plug_aux_dev(pf); - if (ret) - goto err_plug_aux_dev; + return 0; -err_plug_aux_dev: - pf->cdev_info->adev = NULL; - xa_erase(&ice_aux_id, pf->aux_idx); err_alloc_xa: kfree(privd); err_privd_alloc: @@ -432,7 +457,6 @@ void ice_deinit_rdma(struct ice_pf *pf) if (!ice_is_rdma_ena(pf)) return; - ice_unplug_aux_dev(pf); xa_erase(&ice_aux_id, pf->aux_idx); kfree(pf->cdev_info->iidc_priv); kfree(pf->cdev_info); diff --git a/drivers/net/ethernet/intel/ice/ice_irq.c b/drivers/net/ethernet/intel/ice/ice_irq.c index 1d9b2d646474..cd59579568b7 100644 --- a/drivers/net/ethernet/intel/ice/ice_irq.c +++ b/drivers/net/ethernet/intel/ice/ice_irq.c @@ -81,7 +81,7 @@ static struct ice_irq_entry *ice_get_irq_res(struct ice_pf *pf, unsigned int index; int ret; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; diff --git a/drivers/net/ethernet/intel/ice/ice_lag.c b/drivers/net/ethernet/intel/ice/ice_lag.c index d2576d606e10..310e8fe2925c 100644 --- a/drivers/net/ethernet/intel/ice/ice_lag.c +++ b/drivers/net/ethernet/intel/ice/ice_lag.c @@ -742,7 +742,7 @@ static void ice_lag_build_netdev_list(struct ice_lag *lag, INIT_LIST_HEAD(&ndlist->node); rcu_read_lock(); for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) { - nl = kzalloc(sizeof(*nl), GFP_ATOMIC); + nl = kzalloc_obj(*nl, GFP_ATOMIC); if (!nl) break; @@ -2310,7 +2310,7 @@ ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event, return NOTIFY_DONE; /* This memory will be freed at the end of ice_lag_process_event */ - lag_work = kzalloc(sizeof(*lag_work), GFP_KERNEL); + lag_work = kzalloc_obj(*lag_work); if (!lag_work) return -ENOMEM; @@ -2332,7 +2332,7 @@ ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event, rcu_read_lock(); for_each_netdev_in_bond_rcu(upper_netdev, tmp_nd) { - nd_list = kzalloc(sizeof(*nd_list), GFP_ATOMIC); + nd_list = kzalloc_obj(*nd_list, GFP_ATOMIC); if (!nd_list) break; @@ -2577,7 +2577,7 @@ int ice_init_lag(struct ice_pf *pf) if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) return 0; - pf->lag = kzalloc(sizeof(*lag), GFP_KERNEL); + pf->lag = kzalloc_obj(*lag); if (!pf->lag) return -ENOMEM; lag = pf->lag; diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index d921269e1fe7..689c6025ea82 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -107,10 +107,6 @@ static int ice_vsi_alloc_arrays(struct ice_vsi *vsi) if (!vsi->rxq_map) goto err_rxq_map; - /* There is no need to allocate q_vectors for a loopback VSI. */ - if (vsi->type == ICE_VSI_LB) - return 0; - /* allocate memory for q_vector pointers */ vsi->q_vectors = devm_kcalloc(dev, vsi->num_q_vectors, sizeof(*vsi->q_vectors), GFP_KERNEL); @@ -241,6 +237,8 @@ static void ice_vsi_set_num_qs(struct ice_vsi *vsi) case ICE_VSI_LB: vsi->alloc_txq = 1; vsi->alloc_rxq = 1; + /* A dummy q_vector, no actual IRQ. */ + vsi->num_q_vectors = 1; break; default: dev_warn(ice_pf_to_dev(pf), "Unknown VSI type %d\n", vsi_type); @@ -290,7 +288,7 @@ static void ice_vsi_delete_from_hw(struct ice_vsi *vsi) int status; ice_fltr_remove_all(vsi); - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return; @@ -396,7 +394,7 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi) ring_stats = tx_ring_stats[i]; if (!ring_stats) { - ring_stats = kzalloc(sizeof(*ring_stats), GFP_KERNEL); + ring_stats = kzalloc_obj(*ring_stats); if (!ring_stats) goto err_out; @@ -417,7 +415,7 @@ static int ice_vsi_alloc_ring_stats(struct ice_vsi *vsi) ring_stats = rx_ring_stats[i]; if (!ring_stats) { - ring_stats = kzalloc(sizeof(*ring_stats), GFP_KERNEL); + ring_stats = kzalloc_obj(*ring_stats); if (!ring_stats) goto err_out; @@ -533,19 +531,17 @@ static int ice_vsi_alloc_stat_arrays(struct ice_vsi *vsi) /* realloc will happen in rebuild path */ return 0; - vsi_stat = kzalloc(sizeof(*vsi_stat), GFP_KERNEL); + vsi_stat = kzalloc_obj(*vsi_stat); if (!vsi_stat) return -ENOMEM; vsi_stat->tx_ring_stats = - kcalloc(vsi->alloc_txq, sizeof(*vsi_stat->tx_ring_stats), - GFP_KERNEL); + kzalloc_objs(*vsi_stat->tx_ring_stats, vsi->alloc_txq); if (!vsi_stat->tx_ring_stats) goto err_alloc_tx; vsi_stat->rx_ring_stats = - kcalloc(vsi->alloc_rxq, sizeof(*vsi_stat->rx_ring_stats), - GFP_KERNEL); + kzalloc_objs(*vsi_stat->rx_ring_stats, vsi->alloc_rxq); if (!vsi_stat->rx_ring_stats) goto err_alloc_rx; @@ -1239,7 +1235,7 @@ static int ice_vsi_init(struct ice_vsi *vsi, u32 vsi_flags) int ret = 0; dev = ice_pf_to_dev(pf); - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -1403,7 +1399,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) struct ice_tx_ring *ring; /* allocate with kzalloc(), free with kfree_rcu() */ - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) goto err_out; @@ -1427,7 +1423,7 @@ static int ice_vsi_alloc_rings(struct ice_vsi *vsi) struct ice_rx_ring *ring; /* allocate with kzalloc(), free with kfree_rcu() */ - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) goto err_out; @@ -2428,14 +2424,21 @@ static int ice_vsi_cfg_def(struct ice_vsi *vsi) } break; case ICE_VSI_LB: - ret = ice_vsi_alloc_rings(vsi); + ret = ice_vsi_alloc_q_vectors(vsi); if (ret) goto unroll_vsi_init; + ret = ice_vsi_alloc_rings(vsi); + if (ret) + goto unroll_alloc_q_vector; + ret = ice_vsi_alloc_ring_stats(vsi); if (ret) goto unroll_vector_base; + /* Simply map the dummy q_vector to the only rx_ring */ + vsi->rx_rings[0]->q_vector = vsi->q_vectors[0]; + break; default: /* clean up the resources and exit */ @@ -3104,8 +3107,7 @@ int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags) if (ret) goto unlock; - coalesce = kcalloc(vsi->num_q_vectors, - sizeof(struct ice_coalesce_stored), GFP_KERNEL); + coalesce = kzalloc_objs(struct ice_coalesce_stored, vsi->num_q_vectors); if (!coalesce) { ret = -ENOMEM; goto decfg; @@ -3387,7 +3389,7 @@ int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc) vsi->tc_cfg.ena_tc = ena_tc; vsi->tc_cfg.numtc = num_tc; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c index 4da37caa3ec9..e7308e381e2f 100644 --- a/drivers/net/ethernet/intel/ice/ice_main.c +++ b/drivers/net/ethernet/intel/ice/ice_main.c @@ -875,7 +875,7 @@ void ice_print_link_msg(struct ice_vsi *vsi, bool isup) an = "False"; /* Get FEC mode requested based on PHY caps last SW configuration */ - caps = kzalloc(sizeof(*caps), GFP_KERNEL); + caps = kzalloc_obj(*caps); if (!caps) { fec_req = "Unknown"; an_advertised = "Unknown"; @@ -1951,7 +1951,7 @@ static int ice_force_phys_link_state(struct ice_vsi *vsi, bool link_up) pi = vsi->port_info; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -2010,7 +2010,7 @@ static int ice_init_nvm_phy_type(struct ice_port_info *pi) struct ice_pf *pf = pi->hw->back; int err; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -2122,7 +2122,7 @@ static int ice_init_phy_user_cfg(struct ice_port_info *pi) if (!(phy->link_info.link_info & ICE_AQ_MEDIA_AVAILABLE)) return -EIO; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -2202,7 +2202,7 @@ static int ice_configure_phy(struct ice_vsi *vsi) if (test_bit(ICE_FLAG_LINK_DOWN_ON_CLOSE_ENA, pf->flags)) return ice_force_phys_link_state(vsi, true); - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; @@ -2236,7 +2236,7 @@ static int ice_configure_phy(struct ice_vsi *vsi) goto done; } - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) { err = -ENOMEM; goto done; @@ -2385,7 +2385,7 @@ static void ice_service_task(struct work_struct *work) if (test_and_clear_bit(ICE_AUX_ERR_PENDING, pf->state)) { struct iidc_rdma_event *event; - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (event) { set_bit(IIDC_RDMA_EVENT_CRIT_ERR, event->type); /* report the entire OICR value to AUX driver */ @@ -2408,7 +2408,7 @@ static void ice_service_task(struct work_struct *work) if (test_and_clear_bit(ICE_FLAG_MTU_CHANGED, pf->flags)) { struct iidc_rdma_event *event; - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (event) { set_bit(IIDC_RDMA_EVENT_AFTER_MTU_CHANGE, event->type); ice_send_event_to_aux(pf, event); @@ -2609,11 +2609,11 @@ static int ice_xdp_alloc_setup_rings(struct ice_vsi *vsi) struct ice_ring_stats *ring_stats; struct ice_tx_ring *xdp_ring; - xdp_ring = kzalloc(sizeof(*xdp_ring), GFP_KERNEL); + xdp_ring = kzalloc_obj(*xdp_ring); if (!xdp_ring) goto free_xdp_rings; - ring_stats = kzalloc(sizeof(*ring_stats), GFP_KERNEL); + ring_stats = kzalloc_obj(*ring_stats); if (!ring_stats) { ice_free_tx_ring(xdp_ring); goto free_xdp_rings; @@ -4204,7 +4204,7 @@ static void ice_set_safe_mode_vlan_cfg(struct ice_pf *pf) if (!vsi) return; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return; @@ -4910,7 +4910,7 @@ static int ice_init_pf_sw(struct ice_pf *pf) int err; /* create switch struct for the switch element created by FW on boot */ - pf->first_sw = kzalloc(sizeof(*pf->first_sw), GFP_KERNEL); + pf->first_sw = kzalloc_obj(*pf->first_sw); if (!pf->first_sw) return -ENOMEM; @@ -5138,6 +5138,9 @@ int ice_load(struct ice_pf *pf) if (err) goto err_init_rdma; + /* Finalize RDMA: VSI already created, assign info and plug device */ + ice_rdma_finalize_setup(pf); + ice_service_task_restart(pf); clear_bit(ICE_DOWN, pf->state); @@ -5169,6 +5172,7 @@ void ice_unload(struct ice_pf *pf) devl_assert_locked(priv_to_devlink(pf)); + ice_unplug_aux_dev(pf); ice_deinit_rdma(pf); ice_deinit_features(pf); ice_tc_indir_block_unregister(vsi); @@ -5595,6 +5599,7 @@ static int ice_suspend(struct device *dev) */ disabled = ice_service_task_stop(pf); + ice_unplug_aux_dev(pf); ice_deinit_rdma(pf); /* Already suspended?, then there is nothing to do */ @@ -7859,7 +7864,7 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) ice_health_clear(pf); - ice_plug_aux_dev(pf); + ice_rdma_finalize_setup(pf); if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) ice_lag_rebuild(pf); @@ -8096,7 +8101,7 @@ int ice_set_rss_hfunc(struct ice_vsi *vsi, u8 hfunc) hfunc != ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ) return -EOPNOTSUPP; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -8168,7 +8173,7 @@ static int ice_vsi_update_bridge_mode(struct ice_vsi *vsi, u16 bmode) vsi_props = &vsi->info; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -9142,7 +9147,7 @@ static int ice_create_q_channels(struct ice_vsi *vsi) if (!(vsi->all_enatc & BIT(i))) continue; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) { ret = -ENOMEM; goto err_free; @@ -9573,7 +9578,7 @@ ice_indr_setup_tc_block(struct net_device *netdev, struct Qdisc *sch, if (indr_priv) return -EEXIST; - indr_priv = kzalloc(sizeof(*indr_priv), GFP_KERNEL); + indr_priv = kzalloc_obj(*indr_priv); if (!indr_priv) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c index 664beb64f557..f8e69630fb72 100644 --- a/drivers/net/ethernet/intel/ice/ice_parser.c +++ b/drivers/net/ethernet/intel/ice/ice_parser.c @@ -1895,7 +1895,7 @@ static struct ice_xlt_kb *ice_xlt_kb_get(struct ice_hw *hw, u32 sect_type) if (!seg) return ERR_PTR(-EINVAL); - kb = kzalloc(sizeof(*kb), GFP_KERNEL); + kb = kzalloc_obj(*kb); if (!kb) return ERR_PTR(-ENOMEM); @@ -2000,7 +2000,7 @@ struct ice_parser *ice_parser_create(struct ice_hw *hw) struct ice_parser *p; void *err; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 22c3986b910a..094e96219f45 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -706,7 +706,7 @@ ice_ptp_alloc_tx_tracker(struct ice_ptp_tx *tx) unsigned long *in_use, *stale; struct ice_tx_tstamp *tstamps; - tstamps = kcalloc(tx->len, sizeof(*tstamps), GFP_KERNEL); + tstamps = kzalloc_objs(*tstamps, tx->len); in_use = bitmap_zalloc(tx->len, GFP_KERNEL); stale = bitmap_zalloc(tx->len, GFP_KERNEL); diff --git a/drivers/net/ethernet/intel/ice/ice_repr.c b/drivers/net/ethernet/intel/ice/ice_repr.c index cb08746556a6..90f99443a922 100644 --- a/drivers/net/ethernet/intel/ice/ice_repr.c +++ b/drivers/net/ethernet/intel/ice/ice_repr.c @@ -369,7 +369,7 @@ static struct ice_repr *ice_repr_create(struct ice_vsi *src_vsi) struct ice_repr *repr; int err; - repr = kzalloc(sizeof(*repr), GFP_KERNEL); + repr = kzalloc_obj(*repr); if (!repr) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/intel/ice/ice_sf_eth.c b/drivers/net/ethernet/intel/ice/ice_sf_eth.c index 1a2c94375ca7..2cf04bc6edce 100644 --- a/drivers/net/ethernet/intel/ice/ice_sf_eth.c +++ b/drivers/net/ethernet/intel/ice/ice_sf_eth.c @@ -273,7 +273,7 @@ ice_sf_eth_activate(struct ice_dynamic_port *dyn_port, return err; } - sf_dev = kzalloc(sizeof(*sf_dev), GFP_KERNEL); + sf_dev = kzalloc_obj(*sf_dev); if (!sf_dev) { err = -ENOMEM; NL_SET_ERR_MSG_MOD(extack, "Could not allocate SF memory"); diff --git a/drivers/net/ethernet/intel/ice/ice_sriov.c b/drivers/net/ethernet/intel/ice/ice_sriov.c index 6b1126ddb561..7e00e091756d 100644 --- a/drivers/net/ethernet/intel/ice/ice_sriov.c +++ b/drivers/net/ethernet/intel/ice/ice_sriov.c @@ -695,7 +695,7 @@ static int ice_create_vf_entries(struct ice_pf *pf, u16 num_vfs) pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_pdev_id); for (u16 vf_id = 0; vf_id < num_vfs; vf_id++) { - vf = kzalloc(sizeof(*vf), GFP_KERNEL); + vf = kzalloc_obj(*vf); if (!vf) { err = -ENOMEM; goto err_free_entries; diff --git a/drivers/net/ethernet/intel/ice/ice_switch.c b/drivers/net/ethernet/intel/ice/ice_switch.c index 84848f0123e7..bb0f990fa2c6 100644 --- a/drivers/net/ethernet/intel/ice/ice_switch.c +++ b/drivers/net/ethernet/intel/ice/ice_switch.c @@ -1847,7 +1847,7 @@ ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable) if (!cached_ctx) return -ENOENT; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -2069,7 +2069,7 @@ ice_update_recipe_lkup_idx(struct ice_hw *hw, u16 num_recps = ICE_MAX_NUM_RECIPES; int status; - rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL); + rcp_list = kzalloc_objs(*rcp_list, num_recps); if (!rcp_list) return -ENOMEM; @@ -2326,7 +2326,7 @@ ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, bitmap_zero(result_bm, ICE_MAX_FV_WORDS); /* we need a buffer big enough to accommodate all the recipes */ - tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_objs(*tmp, ICE_MAX_NUM_RECIPES); if (!tmp) return -ENOMEM; @@ -5096,7 +5096,7 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, if (recp_cnt > ICE_MAX_CHAIN_RECIPE_RES) return -E2BIG; - buf = kcalloc(recp_cnt, sizeof(*buf), GFP_KERNEL); + buf = kzalloc_objs(*buf, recp_cnt); if (!buf) return -ENOMEM; @@ -5324,7 +5324,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, if (!lkups_cnt) return -EINVAL; - lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL); + lkup_exts = kzalloc_obj(*lkup_exts); if (!lkup_exts) return -ENOMEM; @@ -5346,7 +5346,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, } } - rm = kzalloc(sizeof(*rm), GFP_KERNEL); + rm = kzalloc_obj(*rm); if (!rm) { status = -ENOMEM; goto err_free_lkup_exts; @@ -5530,7 +5530,7 @@ ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off, dummy_pkt->pkt_len - etype_off); - profile = kzalloc(sizeof(*profile), GFP_KERNEL); + profile = kzalloc_obj(*profile); if (!profile) { kfree(offsets); kfree(pkt); diff --git a/drivers/net/ethernet/intel/ice/ice_tc_lib.c b/drivers/net/ethernet/intel/ice/ice_tc_lib.c index fb9ea7f8ef44..d20357c04127 100644 --- a/drivers/net/ethernet/intel/ice/ice_tc_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_tc_lib.c @@ -931,7 +931,7 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr) return ice_pass_vf_tx_lldp(vsi, false); lkups_cnt = ice_tc_count_lkups(flags, fltr); - list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC); + list = kzalloc_objs(*list, lkups_cnt, GFP_ATOMIC); if (!list) return -ENOMEM; @@ -1177,7 +1177,7 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi, } lkups_cnt = ice_tc_count_lkups(flags, tc_fltr); - list = kcalloc(lkups_cnt, sizeof(*list), GFP_ATOMIC); + list = kzalloc_objs(*list, lkups_cnt, GFP_ATOMIC); if (!list) return -ENOMEM; @@ -2191,7 +2191,7 @@ ice_add_tc_fltr(struct net_device *netdev, struct ice_vsi *vsi, /* by default, set output to be INVALID */ *__fltr = NULL; - fltr = kzalloc(sizeof(*fltr), GFP_KERNEL); + fltr = kzalloc_obj(*fltr); if (!fltr) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c index 6fa201a14f51..a2cd4cf37734 100644 --- a/drivers/net/ethernet/intel/ice/ice_txrx.c +++ b/drivers/net/ethernet/intel/ice/ice_txrx.c @@ -397,7 +397,7 @@ static int ice_alloc_tstamp_ring(struct ice_tx_ring *tx_ring) struct ice_tstamp_ring *tstamp_ring; /* allocate with kzalloc(), free with kfree_rcu() */ - tstamp_ring = kzalloc(sizeof(*tstamp_ring), GFP_KERNEL); + tstamp_ring = kzalloc_obj(*tstamp_ring); if (!tstamp_ring) return -ENOMEM; @@ -560,7 +560,9 @@ void ice_clean_rx_ring(struct ice_rx_ring *rx_ring) i = 0; } - if (rx_ring->vsi->type == ICE_VSI_PF && + if ((rx_ring->vsi->type == ICE_VSI_PF || + rx_ring->vsi->type == ICE_VSI_SF || + rx_ring->vsi->type == ICE_VSI_LB) && xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) { xdp_rxq_info_detach_mem_model(&rx_ring->xdp_rxq); xdp_rxq_info_unreg(&rx_ring->xdp_rxq); diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c index de9e81ccee66..c8bc952f05cd 100644 --- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c @@ -1112,7 +1112,7 @@ static int ice_cfg_mac_antispoof(struct ice_vsi *vsi, bool enable) struct ice_vsi_ctx *ctx; int err; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c b/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c index ada78f83b3ac..54984966851d 100644 --- a/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_vsi_vlan_lib.c @@ -94,7 +94,7 @@ static int ice_vsi_manage_vlan_insertion(struct ice_vsi *vsi) struct ice_vsi_ctx *ctxt; int err; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -141,7 +141,7 @@ static int ice_vsi_manage_vlan_stripping(struct ice_vsi *vsi, bool ena) if (vsi->info.port_based_inner_vlan) return 0; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -239,7 +239,7 @@ static int __ice_vsi_set_inner_port_vlan(struct ice_vsi *vsi, u16 pvid_info) struct ice_vsi_ctx *ctxt; int ret; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -292,7 +292,7 @@ int ice_vsi_clear_inner_port_vlan(struct ice_vsi *vsi) struct ice_vsi_ctx *ctxt; int ret; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -336,7 +336,7 @@ static int ice_cfg_vlan_pruning(struct ice_vsi *vsi, bool ena) return 0; pf = vsi->back; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -382,7 +382,7 @@ static int ice_cfg_vlan_antispoof(struct ice_vsi *vsi, bool enable) struct ice_vsi_ctx *ctx; int err; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -478,7 +478,7 @@ int ice_vsi_ena_outer_stripping(struct ice_vsi *vsi, u16 tpid) if (tpid_to_vsi_outer_vlan_type(tpid, &tag_type)) return -EINVAL; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -529,7 +529,7 @@ int ice_vsi_dis_outer_stripping(struct ice_vsi *vsi) if (vsi->info.port_based_outer_vlan) return 0; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -584,7 +584,7 @@ int ice_vsi_ena_outer_insertion(struct ice_vsi *vsi, u16 tpid) if (tpid_to_vsi_outer_vlan_type(tpid, &tag_type)) return -EINVAL; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -636,7 +636,7 @@ int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi) if (vsi->info.port_based_outer_vlan) return 0; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -694,7 +694,7 @@ __ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, u16 vlan_info, u16 tpid) if (tpid_to_vsi_outer_vlan_type(tpid, &tag_type)) return -EINVAL; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -767,7 +767,7 @@ int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi) struct ice_vsi_ctx *ctxt; int err; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; @@ -794,7 +794,7 @@ int ice_vsi_clear_port_vlan(struct ice_vsi *vsi) struct ice_vsi_ctx *ctxt; int err; - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/ice_xsk.c b/drivers/net/ethernet/intel/ice/ice_xsk.c index 953e68ed0f9a..0643017541c3 100644 --- a/drivers/net/ethernet/intel/ice/ice_xsk.c +++ b/drivers/net/ethernet/intel/ice/ice_xsk.c @@ -174,9 +174,8 @@ int ice_realloc_rx_xdp_bufs(struct ice_rx_ring *rx_ring, bool pool_present) { if (pool_present) { - rx_ring->xdp_buf = kcalloc(rx_ring->count, - sizeof(*rx_ring->xdp_buf), - GFP_KERNEL); + rx_ring->xdp_buf = kzalloc_objs(*rx_ring->xdp_buf, + rx_ring->count); if (!rx_ring->xdp_buf) return -ENOMEM; } else { @@ -900,6 +899,9 @@ void ice_xsk_clean_rx_ring(struct ice_rx_ring *rx_ring) u16 ntc = rx_ring->next_to_clean; u16 ntu = rx_ring->next_to_use; + if (xdp_rxq_info_is_reg(&rx_ring->xdp_rxq)) + xdp_rxq_info_unreg(&rx_ring->xdp_rxq); + while (ntc != ntu) { struct xdp_buff *xdp = *ice_xdp_buf(rx_ring, ntc); diff --git a/drivers/net/ethernet/intel/ice/virt/fdir.c b/drivers/net/ethernet/intel/ice/virt/fdir.c index ae83c3914e29..4f1f3442e52c 100644 --- a/drivers/net/ethernet/intel/ice/virt/fdir.c +++ b/drivers/net/ethernet/intel/ice/virt/fdir.c @@ -875,7 +875,7 @@ ice_vc_fdir_parse_raw(struct ice_vf *vf, if (hw->debug_mask & ICE_DBG_PARSER) ice_parser_result_dump(hw, &rslt); - conf->prof = kzalloc(sizeof(*conf->prof), GFP_KERNEL); + conf->prof = kzalloc_obj(*conf->prof); if (!conf->prof) { status = -ENOMEM; goto err_parser_destroy; @@ -2128,7 +2128,7 @@ int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg) goto err_exit; } - stat = kzalloc(sizeof(*stat), GFP_KERNEL); + stat = kzalloc_obj(*stat); if (!stat) { v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id); @@ -2332,7 +2332,7 @@ int ice_vc_del_fdir_fltr(struct ice_vf *vf, u8 *msg) goto err_exit; } - stat = kzalloc(sizeof(*stat), GFP_KERNEL); + stat = kzalloc_obj(*stat); if (!stat) { v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; dev_dbg(dev, "Alloc stat for VF %d failed\n", vf->vf_id); diff --git a/drivers/net/ethernet/intel/ice/virt/rss.c b/drivers/net/ethernet/intel/ice/virt/rss.c index 085e69ec0cfc..960012ca91b5 100644 --- a/drivers/net/ethernet/intel/ice/virt/rss.c +++ b/drivers/net/ethernet/intel/ice/virt/rss.c @@ -380,7 +380,7 @@ ice_vc_rss_hash_update(struct ice_hw *hw, struct ice_vsi *vsi, u8 hash_type) struct ice_vsi_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ice/virt/virtchnl.c b/drivers/net/ethernet/intel/ice/virt/virtchnl.c index f3f921134379..ca8018e3dd42 100644 --- a/drivers/net/ethernet/intel/ice/virt/virtchnl.c +++ b/drivers/net/ethernet/intel/ice/virt/virtchnl.c @@ -1658,7 +1658,7 @@ static int ice_vc_get_offload_vlan_v2_caps(struct ice_vf *vf) goto out; } - caps = kzalloc(sizeof(*caps), GFP_KERNEL); + caps = kzalloc_obj(*caps); if (!caps) { v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; goto out; @@ -2477,7 +2477,7 @@ static int ice_vc_get_phc_time(struct ice_vf *vf) v_ret = VIRTCHNL_STATUS_SUCCESS; - phc_time = kzalloc(sizeof(*phc_time), GFP_KERNEL); + phc_time = kzalloc_obj(*phc_time); if (!phc_time) { v_ret = VIRTCHNL_STATUS_ERR_NO_MEMORY; goto err; diff --git a/drivers/net/ethernet/intel/idpf/idpf_controlq.c b/drivers/net/ethernet/intel/idpf/idpf_controlq.c index 67894eda2d29..d2dde43269e9 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_controlq.c +++ b/drivers/net/ethernet/intel/idpf/idpf_controlq.c @@ -127,7 +127,7 @@ int idpf_ctlq_add(struct idpf_hw *hw, bool is_rxq = false; int err; - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_obj(*cq); if (!cq) return -ENOMEM; @@ -159,9 +159,7 @@ int idpf_ctlq_add(struct idpf_hw *hw, idpf_ctlq_init_rxq_bufs(cq); } else { /* Allocate the array of msg pointers for TX queues */ - cq->bi.tx_msg = kcalloc(qinfo->len, - sizeof(struct idpf_ctlq_msg *), - GFP_KERNEL); + cq->bi.tx_msg = kzalloc_objs(struct idpf_ctlq_msg *, qinfo->len); if (!cq->bi.tx_msg) { err = -ENOMEM; goto init_dealloc_q_mem; diff --git a/drivers/net/ethernet/intel/idpf/idpf_controlq_setup.c b/drivers/net/ethernet/intel/idpf/idpf_controlq_setup.c index a942a6385d06..d4d488c7cfd6 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_controlq_setup.c +++ b/drivers/net/ethernet/intel/idpf/idpf_controlq_setup.c @@ -40,8 +40,7 @@ static int idpf_ctlq_alloc_bufs(struct idpf_hw *hw, /* We'll be allocating the buffer info memory first, then we can * allocate the mapped buffers for the event processing */ - cq->bi.rx_buff = kcalloc(cq->ring_size, sizeof(struct idpf_dma_mem *), - GFP_KERNEL); + cq->bi.rx_buff = kzalloc_objs(struct idpf_dma_mem *, cq->ring_size); if (!cq->bi.rx_buff) return -ENOMEM; @@ -50,8 +49,7 @@ static int idpf_ctlq_alloc_bufs(struct idpf_hw *hw, struct idpf_dma_mem *bi; int num = 1; /* number of idpf_dma_mem to be allocated */ - cq->bi.rx_buff[i] = kcalloc(num, sizeof(struct idpf_dma_mem), - GFP_KERNEL); + cq->bi.rx_buff[i] = kzalloc_objs(struct idpf_dma_mem, num); if (!cq->bi.rx_buff[i]) goto unwind_alloc_cq_bufs; diff --git a/drivers/net/ethernet/intel/idpf/idpf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_dev.c index a4625638cf3f..1a0c71c95ef1 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_dev.c +++ b/drivers/net/ethernet/intel/idpf/idpf_dev.c @@ -83,8 +83,7 @@ static int idpf_intr_reg_init(struct idpf_vport *vport, u16 total_vecs; total_vecs = idpf_get_reserved_vecs(vport->adapter); - reg_vals = kcalloc(total_vecs, sizeof(struct idpf_vec_regs), - GFP_KERNEL); + reg_vals = kzalloc_objs(struct idpf_vec_regs, total_vecs); if (!reg_vals) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c index 1d78a621d65b..bb99d9e7c65d 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_ethtool.c +++ b/drivers/net/ethernet/intel/idpf/idpf_ethtool.c @@ -200,11 +200,11 @@ static int idpf_add_flow_steer(struct net_device *netdev, if (q_index >= num_rxq) return -EINVAL; - rule = kzalloc(struct_size(rule, rule_info, 1), GFP_KERNEL); + rule = kzalloc_flex(*rule, rule_info, 1); if (!rule) return -ENOMEM; - fltr = kzalloc(sizeof(*fltr), GFP_KERNEL); + fltr = kzalloc_obj(*fltr); if (!fltr) { err = -ENOMEM; goto out_free_rule; @@ -307,10 +307,7 @@ static int idpf_del_flow_steer(struct net_device *netdev, vport_config = vport->adapter->vport_config[np->vport_idx]; user_config = &vport_config->user_config; - if (!idpf_sideband_action_ena(vport, fsp)) - return -EOPNOTSUPP; - - rule = kzalloc(struct_size(rule, rule_info, 1), GFP_KERNEL); + rule = kzalloc_flex(*rule, rule_info, 1); if (!rule) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_idc.c b/drivers/net/ethernet/intel/idpf/idpf_idc.c index 6dad0593f7f2..bd4785fb8d3e 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_idc.c +++ b/drivers/net/ethernet/intel/idpf/idpf_idc.c @@ -60,7 +60,7 @@ static int idpf_plug_vport_aux_dev(struct iidc_rdma_core_dev_info *cdev_info, struct auxiliary_device *adev; int ret; - iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); + iadev = kzalloc_obj(*iadev); if (!iadev) return -ENOMEM; @@ -120,7 +120,7 @@ static int idpf_idc_init_aux_vport_dev(struct idpf_vport *vport) if (!(le16_to_cpu(vport_msg->vport_flags) & VIRTCHNL2_VPORT_ENABLE_RDMA)) return 0; - vport->vdev_info = kzalloc(sizeof(*vdev_info), GFP_KERNEL); + vport->vdev_info = kzalloc_obj(*vdev_info); if (!vport->vdev_info) return -ENOMEM; @@ -198,7 +198,7 @@ static int idpf_plug_core_aux_dev(struct iidc_rdma_core_dev_info *cdev_info) struct auxiliary_device *adev; int ret; - iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); + iadev = kzalloc_obj(*iadev); if (!iadev) return -ENOMEM; @@ -414,12 +414,12 @@ int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter, struct iidc_rdma_priv_dev_info *privd; int err, i; - adapter->cdev_info = kzalloc(sizeof(*cdev_info), GFP_KERNEL); + adapter->cdev_info = kzalloc_obj(*cdev_info); if (!adapter->cdev_info) return -ENOMEM; cdev_info = adapter->cdev_info; - privd = kzalloc(sizeof(*privd), GFP_KERNEL); + privd = kzalloc_obj(*privd); if (!privd) { err = -ENOMEM; goto err_privd_alloc; @@ -431,9 +431,8 @@ int idpf_idc_init_aux_core_dev(struct idpf_adapter *adapter, privd->ftype = ftype; privd->mapped_mem_regions = - kcalloc(adapter->hw.num_lan_regs, - sizeof(struct iidc_rdma_lan_mapped_mem_region), - GFP_KERNEL); + kzalloc_objs(struct iidc_rdma_lan_mapped_mem_region, + adapter->hw.num_lan_regs); if (!privd->mapped_mem_regions) { err = -ENOMEM; goto err_plug_aux_dev; diff --git a/drivers/net/ethernet/intel/idpf/idpf_lib.c b/drivers/net/ethernet/intel/idpf/idpf_lib.c index 94da5fbd56f1..cf966fe6c759 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_lib.c +++ b/drivers/net/ethernet/intel/idpf/idpf_lib.c @@ -359,9 +359,8 @@ int idpf_intr_req(struct idpf_adapter *adapter) num_rdma_vecs = IDPF_MIN_RDMA_VEC; } - adapter->rdma_msix_entries = kcalloc(num_rdma_vecs, - sizeof(struct msix_entry), - GFP_KERNEL); + adapter->rdma_msix_entries = kzalloc_objs(struct msix_entry, + num_rdma_vecs); if (!adapter->rdma_msix_entries) { err = -ENOMEM; goto free_irq; @@ -369,8 +368,7 @@ int idpf_intr_req(struct idpf_adapter *adapter) } num_lan_vecs = actual_vecs - num_rdma_vecs; - adapter->msix_entries = kcalloc(num_lan_vecs, sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, num_lan_vecs); if (!adapter->msix_entries) { err = -ENOMEM; goto free_rdma_msix; @@ -577,7 +575,7 @@ static int __idpf_add_mac_filter(struct idpf_vport_config *vport_config, return 0; } - f = kzalloc(sizeof(*f), GFP_ATOMIC); + f = kzalloc_obj(*f, GFP_ATOMIC); if (!f) { spin_unlock_bh(&vport_config->mac_filter_list_lock); @@ -1239,7 +1237,7 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, if (idx == IDPF_NO_FREE_SLOT) return NULL; - vport = kzalloc(sizeof(*vport), GFP_KERNEL); + vport = kzalloc_obj(*vport); if (!vport) return vport; @@ -1248,14 +1246,14 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, struct idpf_vport_config *vport_config; struct idpf_q_coalesce *q_coal; - vport_config = kzalloc(sizeof(*vport_config), GFP_KERNEL); + vport_config = kzalloc_obj(*vport_config); if (!vport_config) { kfree(vport); return NULL; } - q_coal = kcalloc(num_max_q, sizeof(*q_coal), GFP_KERNEL); + q_coal = kzalloc_objs(*q_coal, num_max_q); if (!q_coal) { kfree(vport_config); kfree(vport); @@ -1320,6 +1318,7 @@ static struct idpf_vport *idpf_vport_alloc(struct idpf_adapter *adapter, free_rss_key: kfree(rss_data->rss_key); + rss_data->rss_key = NULL; free_qreg_chunks: idpf_vport_deinit_queue_reg_chunks(adapter->vport_config[idx]); free_vector_idxs: @@ -2027,7 +2026,7 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport, * error occurred, the existing vport will be untouched. * */ - new_vport = kzalloc(sizeof(*vport), GFP_KERNEL); + new_vport = kzalloc_obj(*vport); if (!new_vport) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_main.c b/drivers/net/ethernet/intel/idpf/idpf_main.c index de5d722cc21d..0dd741dcfcdb 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_main.c +++ b/drivers/net/ethernet/intel/idpf/idpf_main.c @@ -238,7 +238,7 @@ static int idpf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct idpf_adapter *adapter; int err; - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_ptp.c index 4a805a9541f0..eec91c4f0a75 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_ptp.c +++ b/drivers/net/ethernet/intel/idpf/idpf_ptp.c @@ -936,7 +936,7 @@ int idpf_ptp_init(struct idpf_adapter *adapter) return -EOPNOTSUPP; } - adapter->ptp = kzalloc(sizeof(*adapter->ptp), GFP_KERNEL); + adapter->ptp = kzalloc_obj(*adapter->ptp); if (!adapter->ptp) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c index 376050308b06..252259993022 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c +++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c @@ -183,8 +183,7 @@ static int idpf_tx_buf_alloc_all(struct idpf_tx_queue *tx_q) tx_q->buf_pool_size = U16_MAX; else tx_q->buf_pool_size = tx_q->desc_count; - tx_q->tx_buf = kcalloc(tx_q->buf_pool_size, sizeof(*tx_q->tx_buf), - GFP_KERNEL); + tx_q->tx_buf = kzalloc_objs(*tx_q->tx_buf, tx_q->buf_pool_size); if (!tx_q->tx_buf) return -ENOMEM; @@ -1204,9 +1203,8 @@ static int idpf_qp_enable(const struct idpf_vport *vport, if (!rsrc->xdp_txq_offset) goto config; - q_vector->xsksq = kcalloc(DIV_ROUND_UP(rsrc->num_rxq_grp, - rsrc->num_q_vectors), - sizeof(*q_vector->xsksq), GFP_KERNEL); + q_vector->xsksq = kzalloc_objs(*q_vector->xsksq, + DIV_ROUND_UP(rsrc->num_rxq_grp, rsrc->num_q_vectors)); if (!q_vector->xsksq) return -ENOMEM; @@ -1316,6 +1314,9 @@ static void idpf_txq_group_rel(struct idpf_q_vec_rsrc *rsrc) struct idpf_txq_group *txq_grp = &rsrc->txq_grps[i]; for (unsigned int j = 0; j < txq_grp->num_txq; j++) { + if (!txq_grp->txqs[j]) + continue; + if (idpf_queue_has(FLOW_SCH_EN, txq_grp->txqs[j])) { kfree(txq_grp->txqs[j]->refillq); txq_grp->txqs[j]->refillq = NULL; @@ -1341,6 +1342,9 @@ static void idpf_txq_group_rel(struct idpf_q_vec_rsrc *rsrc) */ static void idpf_rxq_sw_queue_rel(struct idpf_rxq_group *rx_qgrp) { + if (!rx_qgrp->splitq.bufq_sets) + return; + for (unsigned int i = 0; i < rx_qgrp->splitq.num_bufq_sets; i++) { struct idpf_bufq_set *bufq_set = &rx_qgrp->splitq.bufq_sets[i]; @@ -1439,8 +1443,7 @@ static int idpf_vport_init_fast_path_txqs(struct idpf_vport *vport, struct work_struct *tstamp_task = &vport->tstamp_task; int k = 0; - vport->txqs = kcalloc(rsrc->num_txq, sizeof(*vport->txqs), - GFP_KERNEL); + vport->txqs = kzalloc_objs(*vport->txqs, rsrc->num_txq); if (!vport->txqs) return -ENOMEM; @@ -1711,8 +1714,7 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, { bool split, flow_sch_en; - rsrc->txq_grps = kcalloc(rsrc->num_txq_grp, - sizeof(*rsrc->txq_grps), GFP_KERNEL); + rsrc->txq_grps = kzalloc_objs(*rsrc->txq_grps, rsrc->num_txq_grp); if (!rsrc->txq_grps) return -ENOMEM; @@ -1728,8 +1730,7 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, tx_qgrp->num_txq = num_txq; for (unsigned int j = 0; j < tx_qgrp->num_txq; j++) { - tx_qgrp->txqs[j] = kzalloc(sizeof(*tx_qgrp->txqs[j]), - GFP_KERNEL); + tx_qgrp->txqs[j] = kzalloc_obj(*tx_qgrp->txqs[j]); if (!tx_qgrp->txqs[j]) goto err_alloc; } @@ -1756,7 +1757,7 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, idpf_queue_set(FLOW_SCH_EN, q); - q->refillq = kzalloc(sizeof(*q->refillq), GFP_KERNEL); + q->refillq = kzalloc_obj(*q->refillq); if (!q->refillq) goto err_alloc; @@ -1767,9 +1768,8 @@ static int idpf_txq_group_alloc(struct idpf_vport *vport, if (!split) continue; - tx_qgrp->complq = kcalloc(IDPF_COMPLQ_PER_GROUP, - sizeof(*tx_qgrp->complq), - GFP_KERNEL); + tx_qgrp->complq = kzalloc_objs(*tx_qgrp->complq, + IDPF_COMPLQ_PER_GROUP); if (!tx_qgrp->complq) goto err_alloc; @@ -1806,8 +1806,7 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, bool hs, rsc; int err = 0; - rsrc->rxq_grps = kcalloc(rsrc->num_rxq_grp, - sizeof(struct idpf_rxq_group), GFP_KERNEL); + rsrc->rxq_grps = kzalloc_objs(struct idpf_rxq_group, rsrc->num_rxq_grp); if (!rsrc->rxq_grps) return -ENOMEM; @@ -1821,9 +1820,7 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, if (!idpf_is_queue_model_split(rsrc->rxq_model)) { rx_qgrp->singleq.num_rxq = num_rxq; for (unsigned int j = 0; j < num_rxq; j++) { - rx_qgrp->singleq.rxqs[j] = - kzalloc(sizeof(*rx_qgrp->singleq.rxqs[j]), - GFP_KERNEL); + rx_qgrp->singleq.rxqs[j] = kzalloc_obj(*rx_qgrp->singleq.rxqs[j]); if (!rx_qgrp->singleq.rxqs[j]) { err = -ENOMEM; goto err_alloc; @@ -1835,17 +1832,15 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, for (unsigned int j = 0; j < num_rxq; j++) { rx_qgrp->splitq.rxq_sets[j] = - kzalloc(sizeof(struct idpf_rxq_set), - GFP_KERNEL); + kzalloc_obj(struct idpf_rxq_set); if (!rx_qgrp->splitq.rxq_sets[j]) { err = -ENOMEM; goto err_alloc; } } - rx_qgrp->splitq.bufq_sets = kcalloc(rsrc->num_bufqs_per_qgrp, - sizeof(struct idpf_bufq_set), - GFP_KERNEL); + rx_qgrp->splitq.bufq_sets = kzalloc_objs(struct idpf_bufq_set, + rsrc->num_bufqs_per_qgrp); if (!rx_qgrp->splitq.bufq_sets) { err = -ENOMEM; goto err_alloc; @@ -1880,9 +1875,8 @@ static int idpf_rxq_group_alloc(struct idpf_vport *vport, rsrc->bufq_desc_count[j]; idpf_queue_set(GEN_CHK, refillq); idpf_queue_set(RFL_GEN_CHK, refillq); - refillq->ring = kcalloc(refillq->desc_count, - sizeof(*refillq->ring), - GFP_KERNEL); + refillq->ring = kzalloc_objs(*refillq->ring, + refillq->desc_count); if (!refillq->ring) { err = -ENOMEM; goto err_alloc; @@ -2348,7 +2342,7 @@ void idpf_wait_for_sw_marker_completion(const struct idpf_tx_queue *txq) do { struct idpf_splitq_4b_tx_compl_desc *tx_desc; - struct idpf_tx_queue *target; + struct idpf_tx_queue *target = NULL; u32 ctype_gen, id; tx_desc = flow ? &complq->comp[ntc].common : @@ -2368,14 +2362,14 @@ void idpf_wait_for_sw_marker_completion(const struct idpf_tx_queue *txq) target = complq->txq_grp->txqs[id]; idpf_queue_clear(SW_MARKER, target); - if (target == txq) - break; next: if (unlikely(++ntc == complq->desc_count)) { ntc = 0; gen_flag = !gen_flag; } + if (target == txq) + break; } while (time_before(jiffies, timeout)); idpf_queue_assign(GEN_CHK, complq, gen_flag); @@ -4071,7 +4065,7 @@ static int idpf_vport_intr_req_irq(struct idpf_vport *vport, continue; name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name, if_name, - vec_name, vidx); + vec_name, vector); err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0, name, q_vector); @@ -4567,8 +4561,8 @@ int idpf_vport_intr_alloc(struct idpf_vport *vport, user_config = &vport->adapter->vport_config[idx]->user_config; - rsrc->q_vectors = kcalloc(rsrc->num_q_vectors, - sizeof(struct idpf_q_vector), GFP_KERNEL); + rsrc->q_vectors = kzalloc_objs(struct idpf_q_vector, + rsrc->num_q_vectors); if (!rsrc->q_vectors) return -ENOMEM; @@ -4595,37 +4589,31 @@ int idpf_vport_intr_alloc(struct idpf_vport *vport, q_vector->rx_intr_mode = q_coal->rx_intr_mode; q_vector->rx_itr_idx = VIRTCHNL2_ITR_IDX_0; - q_vector->tx = kcalloc(txqs_per_vector, sizeof(*q_vector->tx), - GFP_KERNEL); + q_vector->tx = kzalloc_objs(*q_vector->tx, txqs_per_vector); if (!q_vector->tx) goto error; - q_vector->rx = kcalloc(rxqs_per_vector, sizeof(*q_vector->rx), - GFP_KERNEL); + q_vector->rx = kzalloc_objs(*q_vector->rx, rxqs_per_vector); if (!q_vector->rx) goto error; if (!idpf_is_queue_model_split(rsrc->rxq_model)) continue; - q_vector->bufq = kcalloc(bufqs_per_vector, - sizeof(*q_vector->bufq), - GFP_KERNEL); + q_vector->bufq = kzalloc_objs(*q_vector->bufq, bufqs_per_vector); if (!q_vector->bufq) goto error; - q_vector->complq = kcalloc(complqs_per_vector, - sizeof(*q_vector->complq), - GFP_KERNEL); + q_vector->complq = kzalloc_objs(*q_vector->complq, + complqs_per_vector); if (!q_vector->complq) goto error; if (!rsrc->xdp_txq_offset) continue; - q_vector->xsksq = kcalloc(rxqs_per_vector, - sizeof(*q_vector->xsksq), - GFP_KERNEL); + q_vector->xsksq = kzalloc_objs(*q_vector->xsksq, + rxqs_per_vector); if (!q_vector->xsksq) goto error; } diff --git a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c index 7527b967e2e7..a07d7e808ca9 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c +++ b/drivers/net/ethernet/intel/idpf/idpf_vf_dev.c @@ -82,8 +82,7 @@ static int idpf_vf_intr_reg_init(struct idpf_vport *vport, u16 total_vecs; total_vecs = idpf_get_reserved_vecs(vport->adapter); - reg_vals = kcalloc(total_vecs, sizeof(struct idpf_vec_regs), - GFP_KERNEL); + reg_vals = kzalloc_objs(struct idpf_vec_regs, total_vecs); if (!reg_vals) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c index d46affaf7185..d5a877e1fef8 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl.c @@ -132,7 +132,7 @@ static int idpf_mb_clean(struct idpf_adapter *adapter, struct idpf_dma_mem *dma_mem; int err; - q_msg = kcalloc(num_q_msg, sizeof(struct idpf_ctlq_msg *), GFP_ATOMIC); + q_msg = kzalloc_objs(struct idpf_ctlq_msg *, num_q_msg, GFP_ATOMIC); if (!q_msg) return -ENOMEM; @@ -238,11 +238,11 @@ int idpf_send_mb_msg(struct idpf_adapter *adapter, struct idpf_ctlq_info *asq, if (err) return err; - ctlq_msg = kzalloc(sizeof(*ctlq_msg), GFP_ATOMIC); + ctlq_msg = kzalloc_obj(*ctlq_msg, GFP_ATOMIC); if (!ctlq_msg) return -ENOMEM; - dma_mem = kzalloc(sizeof(*dma_mem), GFP_ATOMIC); + dma_mem = kzalloc_obj(*dma_mem, GFP_ATOMIC); if (!dma_mem) { err = -ENOMEM; goto dma_mem_error; @@ -740,7 +740,7 @@ struct idpf_queue_set *idpf_alloc_queue_set(struct idpf_adapter *adapter, { struct idpf_queue_set *qp; - qp = kzalloc(struct_size(qp, qs, num), GFP_KERNEL); + qp = kzalloc_flex(*qp, qs, num); if (!qp) return NULL; @@ -1059,7 +1059,7 @@ static int idpf_send_get_lan_memory_regions(struct idpf_adapter *adapter) return -EINVAL; hw = &adapter->hw; - hw->lan_regs = kcalloc(num_regions, sizeof(*hw->lan_regs), GFP_KERNEL); + hw->lan_regs = kzalloc_objs(*hw->lan_regs, num_regions); if (!hw->lan_regs) return -ENOMEM; @@ -1091,8 +1091,7 @@ static int idpf_calc_remaining_mmio_regs(struct idpf_adapter *adapter) struct idpf_hw *hw = &adapter->hw; hw->num_lan_regs = IDPF_MMIO_MAP_FALLBACK_MAX_REMAINING; - hw->lan_regs = kcalloc(hw->num_lan_regs, sizeof(*hw->lan_regs), - GFP_KERNEL); + hw->lan_regs = kzalloc_objs(*hw->lan_regs, hw->num_lan_regs); if (!hw->lan_regs) return -ENOMEM; @@ -1291,8 +1290,7 @@ idpf_vport_init_queue_reg_chunks(struct idpf_vport_config *vport_config, kfree(q_info->queue_chunks); - q_info->queue_chunks = kcalloc(num_chunks, sizeof(*q_info->queue_chunks), - GFP_KERNEL); + q_info->queue_chunks = kzalloc_objs(*q_info->queue_chunks, num_chunks); if (!q_info->queue_chunks) { q_info->num_chunks = 0; return -ENOMEM; @@ -1845,7 +1843,7 @@ static int idpf_send_config_tx_queue_set_msg(const struct idpf_queue_set *qs) .chunk_sz = sizeof(*qi), }; - qi = kcalloc(qs->num, sizeof(*qi), GFP_KERNEL); + qi = kzalloc_objs(*qi, qs->num); if (!qi) return -ENOMEM; @@ -2034,7 +2032,7 @@ static int idpf_send_config_rx_queue_set_msg(const struct idpf_queue_set *qs) .chunk_sz = sizeof(*qi), }; - qi = kcalloc(qs->num, sizeof(*qi), GFP_KERNEL); + qi = kzalloc_objs(*qi, qs->num); if (!qi) return -ENOMEM; @@ -2161,7 +2159,7 @@ static int idpf_send_ena_dis_queue_set_msg(const struct idpf_queue_set *qs, .num_chunks = qs->num, }; - qc = kcalloc(qs->num, sizeof(*qc), GFP_KERNEL); + qc = kzalloc_objs(*qc, qs->num); if (!qc) return -ENOMEM; @@ -2328,7 +2326,7 @@ idpf_send_map_unmap_queue_set_vector_msg(const struct idpf_queue_set *qs, }; bool split; - vqv = kcalloc(qs->num, sizeof(*vqv), GFP_KERNEL); + vqv = kzalloc_objs(*vqv, qs->num); if (!vqv) return -ENOMEM; @@ -3198,16 +3196,15 @@ static int idpf_send_get_rx_ptype_msg(struct idpf_adapter *adapter) u16 next_ptype_id = 0; ssize_t reply_sz; - singleq_pt_lkup = kcalloc(IDPF_RX_MAX_BASE_PTYPE, - sizeof(*singleq_pt_lkup), GFP_KERNEL); + singleq_pt_lkup = kzalloc_objs(*singleq_pt_lkup, IDPF_RX_MAX_BASE_PTYPE); if (!singleq_pt_lkup) return -ENOMEM; - splitq_pt_lkup = kcalloc(max_ptype, sizeof(*splitq_pt_lkup), GFP_KERNEL); + splitq_pt_lkup = kzalloc_objs(*splitq_pt_lkup, max_ptype); if (!splitq_pt_lkup) return -ENOMEM; - get_ptype_info = kzalloc(sizeof(*get_ptype_info), GFP_KERNEL); + get_ptype_info = kzalloc_obj(*get_ptype_info); if (!get_ptype_info) return -ENOMEM; @@ -3435,15 +3432,13 @@ static int idpf_vport_params_buf_alloc(struct idpf_adapter *adapter) { u16 num_max_vports = idpf_get_max_vports(adapter); - adapter->vport_params_reqd = kcalloc(num_max_vports, - sizeof(*adapter->vport_params_reqd), - GFP_KERNEL); + adapter->vport_params_reqd = kzalloc_objs(*adapter->vport_params_reqd, + num_max_vports); if (!adapter->vport_params_reqd) return -ENOMEM; - adapter->vport_params_recvd = kcalloc(num_max_vports, - sizeof(*adapter->vport_params_recvd), - GFP_KERNEL); + adapter->vport_params_recvd = kzalloc_objs(*adapter->vport_params_recvd, + num_max_vports); if (!adapter->vport_params_recvd) goto err_mem; @@ -3454,9 +3449,8 @@ static int idpf_vport_params_buf_alloc(struct idpf_adapter *adapter) if (adapter->vport_config) return 0; - adapter->vport_config = kcalloc(num_max_vports, - sizeof(*adapter->vport_config), - GFP_KERNEL); + adapter->vport_config = kzalloc_objs(*adapter->vport_config, + num_max_vports); if (!adapter->vport_config) goto err_mem; @@ -3488,7 +3482,7 @@ int idpf_vc_core_init(struct idpf_adapter *adapter) int err = 0; if (!adapter->vcxn_mngr) { - adapter->vcxn_mngr = kzalloc(sizeof(*adapter->vcxn_mngr), GFP_KERNEL); + adapter->vcxn_mngr = kzalloc_obj(*adapter->vcxn_mngr); if (!adapter->vcxn_mngr) { err = -ENOMEM; goto init_failed; @@ -3560,15 +3554,13 @@ int idpf_vc_core_init(struct idpf_adapter *adapter) pci_sriov_set_totalvfs(adapter->pdev, idpf_get_max_vfs(adapter)); num_max_vports = idpf_get_max_vports(adapter); adapter->max_vports = num_max_vports; - adapter->vports = kcalloc(num_max_vports, sizeof(*adapter->vports), - GFP_KERNEL); + adapter->vports = kzalloc_objs(*adapter->vports, num_max_vports); if (!adapter->vports) return -ENOMEM; if (!adapter->netdevs) { - adapter->netdevs = kcalloc(num_max_vports, - sizeof(struct net_device *), - GFP_KERNEL); + adapter->netdevs = kzalloc_objs(struct net_device *, + num_max_vports); if (!adapter->netdevs) { err = -ENOMEM; goto err_netdev_alloc; @@ -4335,8 +4327,8 @@ int idpf_add_del_mac_filters(struct idpf_adapter *adapter, } /* Fill all the new filters into virtchannel message */ - mac_addr = kcalloc(total_filters, sizeof(struct virtchnl2_mac_addr), - GFP_ATOMIC); + mac_addr = kzalloc_objs(struct virtchnl2_mac_addr, total_filters, + GFP_ATOMIC); if (!mac_addr) { spin_unlock_bh(&vport_config->mac_filter_list_lock); diff --git a/drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c b/drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c index 61cedb6f2854..d9bcc3f61c65 100644 --- a/drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c +++ b/drivers/net/ethernet/intel/idpf/idpf_virtchnl_ptp.c @@ -39,8 +39,7 @@ int idpf_ptp_get_caps(struct idpf_adapter *adapter) u32 temp_offset; int reply_sz; - recv_ptp_caps_msg = kzalloc(sizeof(struct virtchnl2_ptp_get_caps), - GFP_KERNEL); + recv_ptp_caps_msg = kzalloc_obj(struct virtchnl2_ptp_get_caps); if (!recv_ptp_caps_msg) return -ENOMEM; @@ -395,7 +394,7 @@ int idpf_ptp_get_vport_tstamps_caps(struct idpf_vport *vport) for (u16 i = 0; i < tstamp_caps->num_entries; i++) { __le32 offset_l, offset_h; - ptp_tx_tstamp = kzalloc(sizeof(*ptp_tx_tstamp), GFP_KERNEL); + ptp_tx_tstamp = kzalloc_obj(*ptp_tx_tstamp); if (!ptp_tx_tstamp) { err = -ENOMEM; goto err_free_ptp_tx_stamp_list; diff --git a/drivers/net/ethernet/intel/idpf/xdp.c b/drivers/net/ethernet/intel/idpf/xdp.c index 2b60f2a78684..cbccd4546768 100644 --- a/drivers/net/ethernet/intel/idpf/xdp.c +++ b/drivers/net/ethernet/intel/idpf/xdp.c @@ -47,12 +47,16 @@ static int __idpf_xdp_rxq_info_init(struct idpf_rx_queue *rxq, void *arg) { const struct idpf_vport *vport = rxq->q_vector->vport; const struct idpf_q_vec_rsrc *rsrc; + u32 frag_size = 0; bool split; int err; + if (idpf_queue_has(XSK, rxq)) + frag_size = rxq->bufq_sets[0].bufq.truesize; + err = __xdp_rxq_info_reg(&rxq->xdp_rxq, vport->netdev, rxq->idx, rxq->q_vector->napi.napi_id, - rxq->rx_buf_size); + frag_size); if (err) return err; @@ -154,7 +158,7 @@ int idpf_xdpsqs_get(const struct idpf_vport *vport) if (!idpf_xdp_enabled(vport)) return 0; - timers = kvcalloc(vport->num_xdp_txq, sizeof(*timers), GFP_KERNEL); + timers = kvzalloc_objs(*timers, vport->num_xdp_txq); if (!timers) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/idpf/xsk.c b/drivers/net/ethernet/intel/idpf/xsk.c index 676cbd80774d..d95d3efdfd36 100644 --- a/drivers/net/ethernet/intel/idpf/xsk.c +++ b/drivers/net/ethernet/intel/idpf/xsk.c @@ -403,6 +403,7 @@ int idpf_xskfq_init(struct idpf_buf_queue *bufq) bufq->pending = fq.pending; bufq->thresh = fq.thresh; bufq->rx_buf_size = fq.buf_len; + bufq->truesize = fq.truesize; if (!idpf_xskfq_refill(bufq)) netdev_err(bufq->pool->netdev, diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index b507576b28b2..f7938c1da835 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c @@ -2919,7 +2919,7 @@ static int igb_add_ethtool_nfc_entry(struct igb_adapter *adapter, if ((fsp->flow_type & ~FLOW_EXT) != ETHER_FLOW) return -EINVAL; - input = kzalloc(sizeof(*input), GFP_KERNEL); + input = kzalloc_obj(*input); if (!input) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index dbea37269d2c..ee99fd8fd513 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -2711,7 +2711,7 @@ static int igb_configure_clsflower(struct igb_adapter *adapter, return -EINVAL; } - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; @@ -3775,8 +3775,8 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit) } else adapter->vfs_allocated_count = num_vfs; - adapter->vf_data = kcalloc(adapter->vfs_allocated_count, - sizeof(struct vf_data_storage), GFP_KERNEL); + adapter->vf_data = kzalloc_objs(struct vf_data_storage, + adapter->vfs_allocated_count); /* if allocation failed then we do not support SR-IOV */ if (!adapter->vf_data) { @@ -3794,9 +3794,8 @@ static int igb_enable_sriov(struct pci_dev *pdev, int num_vfs, bool reinit) (1 + IGB_PF_MAC_FILTERS_RESERVED + adapter->vfs_allocated_count); - adapter->vf_mac_list = kcalloc(num_vf_mac_filters, - sizeof(struct vf_mac_filter), - GFP_KERNEL); + adapter->vf_mac_list = kzalloc_objs(struct vf_mac_filter, + num_vf_mac_filters); mac_list = adapter->vf_mac_list; INIT_LIST_HEAD(&adapter->vf_macs.l); @@ -4091,9 +4090,8 @@ static int igb_sw_init(struct igb_adapter *adapter) /* Assume MSI-X interrupts, will be checked during IRQ allocation */ adapter->flags |= IGB_FLAG_HAS_MSIX; - adapter->mac_table = kcalloc(hw->mac.rar_entry_count, - sizeof(struct igb_mac_addr), - GFP_KERNEL); + adapter->mac_table = kzalloc_objs(struct igb_mac_addr, + hw->mac.rar_entry_count); if (!adapter->mac_table) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igb/igb_xsk.c b/drivers/net/ethernet/intel/igb/igb_xsk.c index 30ce5fbb5b77..ce4a7b58cad2 100644 --- a/drivers/net/ethernet/intel/igb/igb_xsk.c +++ b/drivers/net/ethernet/intel/igb/igb_xsk.c @@ -524,6 +524,16 @@ bool igb_xmit_zc(struct igb_ring *tx_ring, struct xsk_buff_pool *xsk_pool) return nb_pkts < budget; } +static u32 igb_sw_irq_prep(struct igb_q_vector *q_vector) +{ + u32 eics = 0; + + if (!napi_if_scheduled_mark_missed(&q_vector->napi)) + eics = q_vector->eims_value; + + return eics; +} + int igb_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags) { struct igb_adapter *adapter = netdev_priv(dev); @@ -542,20 +552,32 @@ int igb_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags) ring = adapter->tx_ring[qid]; - if (test_bit(IGB_RING_FLAG_TX_DISABLED, &ring->flags)) - return -ENETDOWN; - if (!READ_ONCE(ring->xsk_pool)) return -EINVAL; - if (!napi_if_scheduled_mark_missed(&ring->q_vector->napi)) { + if (flags & XDP_WAKEUP_TX) { + if (test_bit(IGB_RING_FLAG_TX_DISABLED, &ring->flags)) + return -ENETDOWN; + + eics |= igb_sw_irq_prep(ring->q_vector); + } + + if (flags & XDP_WAKEUP_RX) { + /* If IGB_FLAG_QUEUE_PAIRS is active, the q_vector + * and NAPI is shared between RX and TX. + * If NAPI is already running it would be marked as missed + * from the TX path, making this RX call a NOP + */ + ring = adapter->rx_ring[qid]; + eics |= igb_sw_irq_prep(ring->q_vector); + } + + if (eics) { /* Cause software interrupt */ - if (adapter->flags & IGB_FLAG_HAS_MSIX) { - eics |= ring->q_vector->eims_value; + if (adapter->flags & IGB_FLAG_HAS_MSIX) wr32(E1000_EICS, eics); - } else { + else wr32(E1000_ICS, E1000_ICS_RXDMT0); - } } return 0; diff --git a/drivers/net/ethernet/intel/igbvf/netdev.c b/drivers/net/ethernet/intel/igbvf/netdev.c index ac57212ab02b..5d04541072b3 100644 --- a/drivers/net/ethernet/intel/igbvf/netdev.c +++ b/drivers/net/ethernet/intel/igbvf/netdev.c @@ -1017,8 +1017,7 @@ static void igbvf_set_interrupt_capability(struct igbvf_adapter *adapter) int i; /* we allocate 3 vectors, 1 for Tx, 1 for Rx, one for PF messages */ - adapter->msix_entries = kcalloc(3, sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, 3); if (adapter->msix_entries) { for (i = 0; i < 3; i++) adapter->msix_entries[i].entry = i; @@ -1098,11 +1097,11 @@ static int igbvf_alloc_queues(struct igbvf_adapter *adapter) { struct net_device *netdev = adapter->netdev; - adapter->tx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL); + adapter->tx_ring = kzalloc_obj(struct igbvf_ring); if (!adapter->tx_ring) return -ENOMEM; - adapter->rx_ring = kzalloc(sizeof(struct igbvf_ring), GFP_KERNEL); + adapter->rx_ring = kzalloc_obj(struct igbvf_ring); if (!adapter->rx_ring) { kfree(adapter->tx_ring); return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igc/igc_ethtool.c b/drivers/net/ethernet/intel/igc/igc_ethtool.c index 3172cdbca9cc..0122009bedd0 100644 --- a/drivers/net/ethernet/intel/igc/igc_ethtool.c +++ b/drivers/net/ethernet/intel/igc/igc_ethtool.c @@ -1395,7 +1395,7 @@ static int igc_ethtool_add_nfc_rule(struct igc_adapter *adapter, return -EINVAL; } - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igc/igc_leds.c b/drivers/net/ethernet/intel/igc/igc_leds.c index 3929b25b6ae6..fdb9692516e8 100644 --- a/drivers/net/ethernet/intel/igc/igc_leds.c +++ b/drivers/net/ethernet/intel/igc/igc_leds.c @@ -268,7 +268,7 @@ int igc_led_setup(struct igc_adapter *adapter) mutex_init(&adapter->led_mutex); - leds = kcalloc(IGC_NUM_LEDS, sizeof(*leds), GFP_KERNEL); + leds = kzalloc_objs(*leds, IGC_NUM_LEDS); if (!leds) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c index 89a321a344d2..b2e8d0c0f827 100644 --- a/drivers/net/ethernet/intel/igc/igc_main.c +++ b/drivers/net/ethernet/intel/igc/igc_main.c @@ -4633,8 +4633,7 @@ static void igc_set_interrupt_capability(struct igc_adapter *adapter, /* add 1 vector for link status interrupts */ numvecs++; - adapter->msix_entries = kcalloc(numvecs, sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, numvecs); if (!adapter->msix_entries) return; @@ -4863,8 +4862,7 @@ static int igc_alloc_q_vector(struct igc_adapter *adapter, /* allocate q_vector and rings */ q_vector = adapter->q_vector[v_idx]; if (!q_vector) - q_vector = kzalloc(struct_size(q_vector, ring, ring_count), - GFP_KERNEL); + q_vector = kzalloc_flex(*q_vector, ring, ring_count); else memset(q_vector, 0, struct_size(q_vector, ring, ring_count)); if (!q_vector) @@ -6908,28 +6906,29 @@ static int igc_xdp_xmit(struct net_device *dev, int num_frames, return nxmit; } -static void igc_trigger_rxtxq_interrupt(struct igc_adapter *adapter, - struct igc_q_vector *q_vector) +static u32 igc_sw_irq_prep(struct igc_q_vector *q_vector) { - struct igc_hw *hw = &adapter->hw; u32 eics = 0; - eics |= q_vector->eims_value; - wr32(IGC_EICS, eics); + if (!napi_if_scheduled_mark_missed(&q_vector->napi)) + eics = q_vector->eims_value; + + return eics; } int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags) { struct igc_adapter *adapter = netdev_priv(dev); - struct igc_q_vector *q_vector; + struct igc_hw *hw = &adapter->hw; struct igc_ring *ring; + u32 eics = 0; if (test_bit(__IGC_DOWN, &adapter->state)) return -ENETDOWN; if (!igc_xdp_is_enabled(adapter)) return -ENXIO; - + /* Check if queue_id is valid. Tx and Rx queue numbers are always same */ if (queue_id >= adapter->num_rx_queues) return -EINVAL; @@ -6938,9 +6937,22 @@ int igc_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags) if (!ring->xsk_pool) return -ENXIO; - q_vector = adapter->q_vector[queue_id]; - if (!napi_if_scheduled_mark_missed(&q_vector->napi)) - igc_trigger_rxtxq_interrupt(adapter, q_vector); + if (flags & XDP_WAKEUP_RX) + eics |= igc_sw_irq_prep(ring->q_vector); + + if (flags & XDP_WAKEUP_TX) { + /* If IGC_FLAG_QUEUE_PAIRS is active, the q_vector + * and NAPI is shared between RX and TX. + * If NAPI is already running it would be marked as missed + * from the RX path, making this TX call a NOP + */ + ring = adapter->tx_ring[queue_id]; + eics |= igc_sw_irq_prep(ring->q_vector); + } + + if (eics) + /* Cause software interrupt */ + wr32(IGC_EICS, eics); return 0; } diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c index 7aae83c108fd..44ee19386766 100644 --- a/drivers/net/ethernet/intel/igc/igc_ptp.c +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c @@ -550,7 +550,8 @@ static void igc_ptp_free_tx_buffer(struct igc_adapter *adapter, tstamp->buffer_type = 0; /* Trigger txrx interrupt for transmit completion */ - igc_xsk_wakeup(adapter->netdev, tstamp->xsk_queue_index, 0); + igc_xsk_wakeup(adapter->netdev, tstamp->xsk_queue_index, + XDP_WAKEUP_TX); return; } diff --git a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c index d227f4d2a2d1..b0404f37271a 100644 --- a/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c +++ b/drivers/net/ethernet/intel/ixgbe/devlink/devlink.c @@ -318,7 +318,7 @@ static int ixgbe_devlink_info_get(struct devlink *devlink, struct ixgbe_info_ctx *ctx; int err; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index 3dd5a16a14df..382d097e4b11 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -516,8 +516,7 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, return -EINVAL; if (!adapter->ixgbe_ieee_ets) { - adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), - GFP_KERNEL); + adapter->ixgbe_ieee_ets = kmalloc_obj(struct ieee_ets); if (!adapter->ixgbe_ieee_ets) return -ENOMEM; @@ -593,8 +592,7 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return -EINVAL; if (!adapter->ixgbe_ieee_pfc) { - adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), - GFP_KERNEL); + adapter->ixgbe_ieee_pfc = kmalloc_obj(struct ieee_pfc); if (!adapter->ixgbe_ieee_pfc) return -ENOMEM; } diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c index c2f8189a0738..52f73142ff75 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_e610.c @@ -1285,7 +1285,7 @@ int ixgbe_update_link_info(struct ixgbe_hw *hw) if (!(li->link_info & IXGBE_ACI_MEDIA_AVAILABLE)) return 0; - pcaps = kzalloc(sizeof(*pcaps), GFP_KERNEL); + pcaps = kzalloc_obj(*pcaps); if (!pcaps) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c index bb4b53fee234..56aabaa5caec 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c @@ -2981,7 +2981,7 @@ static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter, return -EINVAL; } - input = kzalloc(sizeof(*input), GFP_ATOMIC); + input = kzalloc_obj(*input, GFP_ATOMIC); if (!input) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c index e5479fc07a07..ffceaef8502f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fw_update.c @@ -516,7 +516,7 @@ int ixgbe_get_pending_updates(struct ixgbe_adapter *adapter, u8 *pending, struct ixgbe_hw *hw = &adapter->hw; int err; - dev_caps = kzalloc(sizeof(*dev_caps), GFP_KERNEL); + dev_caps = kzalloc_obj(*dev_caps); if (!dev_caps) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c index d1f4073b36f9..bd397b3d7dea 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c @@ -904,7 +904,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) goto err_out; } - xs = kzalloc(sizeof(*xs), GFP_ATOMIC); + xs = kzalloc_obj(*xs, GFP_ATOMIC); if (unlikely(!xs)) { err = -ENOMEM; goto err_out; @@ -1233,7 +1233,7 @@ void ixgbe_init_ipsec_offload(struct ixgbe_adapter *adapter) if (t_dis || r_dis) return; - ipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL); + ipsec = kzalloc_obj(*ipsec); if (!ipsec) goto err1; hash_init(ipsec->rx_sa_list); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c index a1d04914fbbc..87abb36f50c1 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_lib.c @@ -768,9 +768,7 @@ static int ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter) */ vector_threshold = MIN_MSIX_COUNT; - adapter->msix_entries = kcalloc(vectors, - sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, vectors); if (!adapter->msix_entries) return -ENOMEM; @@ -859,8 +857,7 @@ static int ixgbe_alloc_q_vector(struct ixgbe_adapter *adapter, q_vector = kzalloc_node(struct_size(q_vector, ring, ring_count), GFP_KERNEL, node); if (!q_vector) - q_vector = kzalloc(struct_size(q_vector, ring, ring_count), - GFP_KERNEL); + q_vector = kzalloc_flex(*q_vector, ring, ring_count); if (!q_vector) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index c58051e4350b..e4101c59074d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -6895,8 +6895,7 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter, #endif /* IXGBE_FCOE */ /* initialize static ixgbe jump table entries */ - adapter->jump_tables[0] = kzalloc(sizeof(*adapter->jump_tables[0]), - GFP_KERNEL); + adapter->jump_tables[0] = kzalloc_obj(*adapter->jump_tables[0]); if (!adapter->jump_tables[0]) return -ENOMEM; adapter->jump_tables[0]->mat = ixgbe_ipv4_fields; @@ -6904,9 +6903,8 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter, for (i = 1; i < IXGBE_MAX_LINK_HANDLE; i++) adapter->jump_tables[i] = NULL; - adapter->mac_table = kcalloc(hw->mac.num_rar_entries, - sizeof(struct ixgbe_mac_addr), - GFP_KERNEL); + adapter->mac_table = kzalloc_objs(struct ixgbe_mac_addr, + hw->mac.num_rar_entries); if (!adapter->mac_table) return -ENOMEM; @@ -10273,15 +10271,15 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, (__force u32)cls->knode.sel->offmask) return err; - jump = kzalloc(sizeof(*jump), GFP_KERNEL); + jump = kzalloc_obj(*jump); if (!jump) return -ENOMEM; - input = kzalloc(sizeof(*input), GFP_KERNEL); + input = kzalloc_obj(*input); if (!input) { err = -ENOMEM; goto free_jump; } - mask = kzalloc(sizeof(*mask), GFP_KERNEL); + mask = kzalloc_obj(*mask); if (!mask) { err = -ENOMEM; goto free_input; @@ -10305,10 +10303,10 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, return 0; } - input = kzalloc(sizeof(*input), GFP_KERNEL); + input = kzalloc_obj(*input); if (!input) return -ENOMEM; - mask = kzalloc(sizeof(*mask), GFP_KERNEL); + mask = kzalloc_obj(*mask); if (!mask) { err = -ENOMEM; goto free_input; @@ -10786,7 +10784,7 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev) return ERR_PTR(-ENOMEM); } - accel = kzalloc(sizeof(*accel), GFP_KERNEL); + accel = kzalloc_obj(*accel); if (!accel) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c index ee133d6749b3..431d77da15a5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c @@ -37,8 +37,7 @@ static inline void ixgbe_alloc_vf_macvlans(struct ixgbe_adapter *adapter, if (!num_vf_macvlans) return; - mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), - GFP_KERNEL); + mv_list = kzalloc_objs(struct vf_macvlans, num_vf_macvlans); if (mv_list) { for (i = 0; i < num_vf_macvlans; i++) { mv_list[i].vf = -1; @@ -65,8 +64,7 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter, IXGBE_FLAG_VMDQ_ENABLED; /* Allocate memory for per VF control structures */ - adapter->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage), - GFP_KERNEL); + adapter->vfinfo = kzalloc_objs(struct vf_data_storage, num_vfs); if (!adapter->vfinfo) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c index fce35924ff8b..076fd0a24858 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c +++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c @@ -628,7 +628,7 @@ void ixgbevf_init_ipsec_offload(struct ixgbevf_adapter *adapter) return; } - ipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL); + ipsec = kzalloc_obj(*ipsec); if (!ipsec) goto err1; hash_init(ipsec->rx_sa_list); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index d5ce20f47def..42f89a179a3f 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2716,8 +2716,7 @@ static int ixgbevf_set_interrupt_capability(struct ixgbevf_adapter *adapter) v_budget = min_t(int, v_budget, num_online_cpus()); v_budget += NON_Q_VECTORS; - adapter->msix_entries = kcalloc(v_budget, - sizeof(struct msix_entry), GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, v_budget); if (!adapter->msix_entries) return -ENOMEM; diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index 74d320879513..b67b580f7f1c 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c @@ -852,7 +852,8 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw, if (!mac->get_link_status) goto out; - if (hw->mac.type == ixgbe_mac_e610_vf) { + if (hw->mac.type == ixgbe_mac_e610_vf && + hw->api_version >= ixgbe_mbox_api_16) { ret_val = ixgbevf_get_pf_link_state(hw, speed, link_up); if (ret_val) goto out; diff --git a/drivers/net/ethernet/intel/libeth/xsk.c b/drivers/net/ethernet/intel/libeth/xsk.c index 846e902e31b6..4882951d5c9c 100644 --- a/drivers/net/ethernet/intel/libeth/xsk.c +++ b/drivers/net/ethernet/intel/libeth/xsk.c @@ -167,6 +167,7 @@ int libeth_xskfq_create(struct libeth_xskfq *fq) fq->pending = fq->count; fq->thresh = libeth_xdp_queue_threshold(fq->count); fq->buf_len = xsk_pool_get_rx_frame_size(fq->pool); + fq->truesize = xsk_pool_get_rx_frag_step(fq->pool); return 0; } diff --git a/drivers/net/ethernet/intel/libie/fwlog.c b/drivers/net/ethernet/intel/libie/fwlog.c index f39cc11cb7c5..4d0c8370386b 100644 --- a/drivers/net/ethernet/intel/libie/fwlog.c +++ b/drivers/net/ethernet/intel/libie/fwlog.c @@ -153,7 +153,7 @@ static void libie_fwlog_realloc_rings(struct libie_fwlog *fwlog, int index) * old rings and buffers. that way if we don't have enough * memory then we at least have what we had before */ - ring.rings = kcalloc(ring_size, sizeof(*ring.rings), GFP_KERNEL); + ring.rings = kzalloc_objs(*ring.rings, ring_size); if (!ring.rings) return; @@ -208,7 +208,7 @@ libie_aq_fwlog_set(struct libie_fwlog *fwlog, int status; int i; - fw_modules = kcalloc(num_entries, sizeof(*fw_modules), GFP_KERNEL); + fw_modules = kzalloc_objs(*fw_modules, num_entries); if (!fw_modules) return -ENOMEM; @@ -838,8 +838,7 @@ static void libie_debugfs_fwlog_init(struct libie_fwlog *fwlog, /* allocate space for this first because if it fails then we don't * need to unwind */ - fw_modules = kcalloc(LIBIE_NR_FW_LOG_MODULES, sizeof(*fw_modules), - GFP_KERNEL); + fw_modules = kzalloc_objs(*fw_modules, LIBIE_NR_FW_LOG_MODULES); if (!fw_modules) return; @@ -978,7 +977,7 @@ static void libie_fwlog_set_supported(struct libie_fwlog *fwlog) fwlog->supported = false; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return; @@ -1013,9 +1012,8 @@ int libie_fwlog_init(struct libie_fwlog *fwlog, struct libie_fwlog_api *api) if (status) return status; - fwlog->ring.rings = kcalloc(LIBIE_FWLOG_RING_SIZE_DFLT, - sizeof(*fwlog->ring.rings), - GFP_KERNEL); + fwlog->ring.rings = kzalloc_objs(*fwlog->ring.rings, + LIBIE_FWLOG_RING_SIZE_DFLT); if (!fwlog->ring.rings) { dev_warn(&fwlog->pdev->dev, "Unable to allocate memory for FW log rings\n"); return -ENOMEM; @@ -1051,6 +1049,10 @@ void libie_fwlog_deinit(struct libie_fwlog *fwlog) { int status; + /* if FW logging isn't supported it means no configuration was done */ + if (!libie_fwlog_supported(fwlog)) + return; + /* make sure FW logging is disabled to not put the FW in a weird state * for the next driver load */ diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index d8be0e4dcb07..25ec5f757c68 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -576,9 +576,9 @@ jme_setup_tx_resources(struct jme_adapter *jme) atomic_set(&txring->next_to_clean, 0); atomic_set(&txring->nr_free, jme->tx_ring_size); - txring->bufinf = kcalloc(jme->tx_ring_size, - sizeof(struct jme_buffer_info), - GFP_ATOMIC); + txring->bufinf = kzalloc_objs(struct jme_buffer_info, + jme->tx_ring_size, + GFP_ATOMIC); if (unlikely(!(txring->bufinf))) goto err_free_txring; @@ -819,9 +819,9 @@ jme_setup_rx_resources(struct jme_adapter *jme) rxring->next_to_use = 0; atomic_set(&rxring->next_to_clean, 0); - rxring->bufinf = kcalloc(jme->rx_ring_size, - sizeof(struct jme_buffer_info), - GFP_ATOMIC); + rxring->bufinf = kzalloc_objs(struct jme_buffer_info, + jme->rx_ring_size, + GFP_ATOMIC); if (unlikely(!(rxring->bufinf))) goto err_free_rxring; diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 0ab52c57c648..f9055b3d6fb1 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1967,8 +1967,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) memset(rxq->rx_desc_area, 0, size); rxq->rx_desc_area_size = size; - rxq->rx_skb = kcalloc(rxq->rx_ring_size, sizeof(*rxq->rx_skb), - GFP_KERNEL); + rxq->rx_skb = kzalloc_objs(*rxq->rx_skb, rxq->rx_ring_size); if (rxq->rx_skb == NULL) goto out_free; diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 7af44f858fa3..9ba4aef7080c 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -3554,7 +3554,7 @@ static int mvneta_txq_sw_init(struct mvneta_port *pp, txq->last_desc = txq->size - 1; - txq->buf = kmalloc_array(txq->size, sizeof(*txq->buf), GFP_KERNEL); + txq->buf = kmalloc_objs(*txq->buf, txq->size); if (!txq->buf) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c index c116da7d7f18..80d15d7a5ec3 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -1367,7 +1367,7 @@ int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port, if (info->fs.location >= MVPP2_N_RFS_ENTRIES_PER_FLOW) return -EINVAL; - efs = kzalloc(sizeof(*efs), GFP_KERNEL); + efs = kzalloc_obj(*efs); if (!efs) return -ENOMEM; @@ -1503,8 +1503,7 @@ static int mvpp22_rss_context_create(struct mvpp2_port *port, u32 *rss_ctx) if (ctx == MVPP22_N_RSS_TABLES) return -EINVAL; - priv->rss_tables[ctx] = kzalloc(sizeof(*priv->rss_tables[ctx]), - GFP_KERNEL); + priv->rss_tables[ctx] = kzalloc_obj(*priv->rss_tables[ctx]); if (!priv->rss_tables[ctx]) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c index 0f9bc4f8ec3b..7adc9cd54bf6 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c @@ -706,7 +706,7 @@ void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name) mvpp2_dir = debugfs_create_dir(name, mvpp2_root); priv->dbgfs_dir = mvpp2_dir; - priv->dbgfs_entries = kzalloc(sizeof(*priv->dbgfs_entries), GFP_KERNEL); + priv->dbgfs_entries = kzalloc_obj(*priv->dbgfs_entries); if (!priv->dbgfs_entries) goto err; diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 33426fded919..d1b8650cb4b4 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -3151,9 +3151,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port, for (thread = 0; thread < port->priv->nthreads; thread++) { txq_pcpu = per_cpu_ptr(txq->pcpu, thread); txq_pcpu->size = txq->size; - txq_pcpu->buffs = kmalloc_array(txq_pcpu->size, - sizeof(*txq_pcpu->buffs), - GFP_KERNEL); + txq_pcpu->buffs = kmalloc_objs(*txq_pcpu->buffs, txq_pcpu->size); if (!txq_pcpu->buffs) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c index 57db7ea2f5be..028dd55604ea 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_main.c @@ -115,8 +115,7 @@ static int octep_enable_msix_range(struct octep_device *oct) /* Generic interrupts apart from input/output queues */ num_msix = oct->num_oqs + CFG_GET_NON_IOQ_MSIX(oct->conf); - oct->msix_entries = kcalloc(num_msix, - sizeof(struct msix_entry), GFP_KERNEL); + oct->msix_entries = kzalloc_objs(struct msix_entry, num_msix); if (!oct->msix_entries) goto msix_alloc_err; @@ -554,6 +553,36 @@ static void octep_clean_irqs(struct octep_device *oct) octep_free_ioq_vectors(oct); } +/** + * octep_update_pkt() - Update IQ/OQ IN/OUT_CNT registers. + * + * @iq: Octeon Tx queue data structure. + * @oq: Octeon Rx queue data structure. + */ +static void octep_update_pkt(struct octep_iq *iq, struct octep_oq *oq) +{ + u32 pkts_pend = READ_ONCE(oq->pkts_pending); + u32 last_pkt_count = READ_ONCE(oq->last_pkt_count); + u32 pkts_processed = READ_ONCE(iq->pkts_processed); + u32 pkt_in_done = READ_ONCE(iq->pkt_in_done); + + netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no); + if (pkts_processed) { + writel(pkts_processed, iq->inst_cnt_reg); + readl(iq->inst_cnt_reg); + WRITE_ONCE(iq->pkt_in_done, (pkt_in_done - pkts_processed)); + WRITE_ONCE(iq->pkts_processed, 0); + } + if (last_pkt_count - pkts_pend) { + writel(last_pkt_count - pkts_pend, oq->pkts_sent_reg); + readl(oq->pkts_sent_reg); + WRITE_ONCE(oq->last_pkt_count, pkts_pend); + } + + /* Flush the previous wrties before writing to RESEND bit */ + smp_wmb(); +} + /** * octep_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue. * @@ -562,21 +591,6 @@ static void octep_clean_irqs(struct octep_device *oct) */ static void octep_enable_ioq_irq(struct octep_iq *iq, struct octep_oq *oq) { - u32 pkts_pend = oq->pkts_pending; - - netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no); - if (iq->pkts_processed) { - writel(iq->pkts_processed, iq->inst_cnt_reg); - iq->pkt_in_done -= iq->pkts_processed; - iq->pkts_processed = 0; - } - if (oq->last_pkt_count - pkts_pend) { - writel(oq->last_pkt_count - pkts_pend, oq->pkts_sent_reg); - oq->last_pkt_count = pkts_pend; - } - - /* Flush the previous wrties before writing to RESEND bit */ - wmb(); writeq(1UL << OCTEP_OQ_INTR_RESEND_BIT, oq->pkts_sent_reg); writeq(1UL << OCTEP_IQ_INTR_RESEND_BIT, iq->inst_cnt_reg); } @@ -602,7 +616,8 @@ static int octep_napi_poll(struct napi_struct *napi, int budget) if (tx_pending || rx_done >= budget) return budget; - napi_complete(napi); + octep_update_pkt(ioq_vector->iq, ioq_vector->oq); + napi_complete_done(napi, rx_done); octep_enable_ioq_irq(ioq_vector->iq, ioq_vector->oq); return rx_done; } @@ -1293,7 +1308,7 @@ int octep_device_setup(struct octep_device *oct) int i, ret; /* allocate memory for oct->conf */ - oct->conf = kzalloc(sizeof(*oct->conf), GFP_KERNEL); + oct->conf = kzalloc_obj(*oct->conf); if (!oct->conf) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c index f2a7c6a76c74..74de19166488 100644 --- a/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c +++ b/drivers/net/ethernet/marvell/octeon_ep/octep_rx.c @@ -324,10 +324,16 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, struct octep_oq *oq) { u32 pkt_count, new_pkts; + u32 last_pkt_count, pkts_pending; pkt_count = readl(oq->pkts_sent_reg); - new_pkts = pkt_count - oq->last_pkt_count; + last_pkt_count = READ_ONCE(oq->last_pkt_count); + new_pkts = pkt_count - last_pkt_count; + if (pkt_count < last_pkt_count) { + dev_err(oq->dev, "OQ-%u pkt_count(%u) < oq->last_pkt_count(%u)\n", + oq->q_no, pkt_count, last_pkt_count); + } /* Clear the hardware packets counter register if the rx queue is * being processed continuously with-in a single interrupt and * reached half its max value. @@ -338,8 +344,9 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, pkt_count = readl(oq->pkts_sent_reg); new_pkts += pkt_count; } - oq->last_pkt_count = pkt_count; - oq->pkts_pending += new_pkts; + WRITE_ONCE(oq->last_pkt_count, pkt_count); + pkts_pending = READ_ONCE(oq->pkts_pending); + WRITE_ONCE(oq->pkts_pending, (pkts_pending + new_pkts)); return new_pkts; } @@ -414,7 +421,7 @@ static int __octep_oq_process_rx(struct octep_device *oct, u16 rx_ol_flags; u32 read_idx; - read_idx = oq->host_read_idx; + read_idx = READ_ONCE(oq->host_read_idx); rx_bytes = 0; desc_used = 0; for (pkt = 0; pkt < pkts_to_process; pkt++) { @@ -499,7 +506,7 @@ static int __octep_oq_process_rx(struct octep_device *oct, napi_gro_receive(oq->napi, skb); } - oq->host_read_idx = read_idx; + WRITE_ONCE(oq->host_read_idx, read_idx); oq->refill_count += desc_used; oq->stats->packets += pkt; oq->stats->bytes += rx_bytes; @@ -522,22 +529,26 @@ int octep_oq_process_rx(struct octep_oq *oq, int budget) { u32 pkts_available, pkts_processed, total_pkts_processed; struct octep_device *oct = oq->octep_dev; + u32 pkts_pending; pkts_available = 0; pkts_processed = 0; total_pkts_processed = 0; while (total_pkts_processed < budget) { /* update pending count only when current one exhausted */ - if (oq->pkts_pending == 0) + pkts_pending = READ_ONCE(oq->pkts_pending); + if (pkts_pending == 0) octep_oq_check_hw_for_pkts(oct, oq); + pkts_pending = READ_ONCE(oq->pkts_pending); pkts_available = min(budget - total_pkts_processed, - oq->pkts_pending); + pkts_pending); if (!pkts_available) break; pkts_processed = __octep_oq_process_rx(oct, oq, pkts_available); - oq->pkts_pending -= pkts_processed; + pkts_pending = READ_ONCE(oq->pkts_pending); + WRITE_ONCE(oq->pkts_pending, (pkts_pending - pkts_processed)); total_pkts_processed += pkts_processed; } diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c index 1d9760b4b8f4..7f1b93cffb98 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_main.c @@ -113,7 +113,7 @@ static int octep_vf_enable_msix_range(struct octep_vf_device *oct) /* Generic interrupts apart from input/output queues */ //num_msix = oct->num_oqs + CFG_GET_NON_IOQ_MSIX(oct->conf); num_msix = oct->num_oqs; - oct->msix_entries = kcalloc(num_msix, sizeof(struct msix_entry), GFP_KERNEL); + oct->msix_entries = kzalloc_objs(struct msix_entry, num_msix); if (!oct->msix_entries) goto msix_alloc_err; @@ -285,29 +285,46 @@ static void octep_vf_clean_irqs(struct octep_vf_device *oct) octep_vf_free_ioq_vectors(oct); } +/** + * octep_vf_update_pkt() - Update IQ/OQ IN/OUT_CNT registers. + * + * @iq: Octeon Tx queue data structure. + * @oq: Octeon Rx queue data structure. + */ + +static void octep_vf_update_pkt(struct octep_vf_iq *iq, struct octep_vf_oq *oq) +{ + u32 pkts_pend = READ_ONCE(oq->pkts_pending); + u32 last_pkt_count = READ_ONCE(oq->last_pkt_count); + u32 pkts_processed = READ_ONCE(iq->pkts_processed); + u32 pkt_in_done = READ_ONCE(iq->pkt_in_done); + + netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no); + if (pkts_processed) { + writel(pkts_processed, iq->inst_cnt_reg); + readl(iq->inst_cnt_reg); + WRITE_ONCE(iq->pkt_in_done, (pkt_in_done - pkts_processed)); + WRITE_ONCE(iq->pkts_processed, 0); + } + if (last_pkt_count - pkts_pend) { + writel(last_pkt_count - pkts_pend, oq->pkts_sent_reg); + readl(oq->pkts_sent_reg); + WRITE_ONCE(oq->last_pkt_count, pkts_pend); + } + + /* Flush the previous wrties before writing to RESEND bit */ + smp_wmb(); +} + /** * octep_vf_enable_ioq_irq() - Enable MSI-x interrupt of a Tx/Rx queue. * * @iq: Octeon Tx queue data structure. * @oq: Octeon Rx queue data structure. */ -static void octep_vf_enable_ioq_irq(struct octep_vf_iq *iq, struct octep_vf_oq *oq) +static void octep_vf_enable_ioq_irq(struct octep_vf_iq *iq, + struct octep_vf_oq *oq) { - u32 pkts_pend = oq->pkts_pending; - - netdev_dbg(iq->netdev, "enabling intr for Q-%u\n", iq->q_no); - if (iq->pkts_processed) { - writel(iq->pkts_processed, iq->inst_cnt_reg); - iq->pkt_in_done -= iq->pkts_processed; - iq->pkts_processed = 0; - } - if (oq->last_pkt_count - pkts_pend) { - writel(oq->last_pkt_count - pkts_pend, oq->pkts_sent_reg); - oq->last_pkt_count = pkts_pend; - } - - /* Flush the previous wrties before writing to RESEND bit */ - smp_wmb(); writeq(1UL << OCTEP_VF_OQ_INTR_RESEND_BIT, oq->pkts_sent_reg); writeq(1UL << OCTEP_VF_IQ_INTR_RESEND_BIT, iq->inst_cnt_reg); } @@ -333,6 +350,7 @@ static int octep_vf_napi_poll(struct napi_struct *napi, int budget) if (tx_pending || rx_done >= budget) return budget; + octep_vf_update_pkt(ioq_vector->iq, ioq_vector->oq); if (likely(napi_complete_done(napi, rx_done))) octep_vf_enable_ioq_irq(ioq_vector->iq, ioq_vector->oq); @@ -951,7 +969,7 @@ int octep_vf_device_setup(struct octep_vf_device *oct) struct pci_dev *pdev = oct->pdev; /* allocate memory for oct->conf */ - oct->conf = kzalloc(sizeof(*oct->conf), GFP_KERNEL); + oct->conf = kzalloc_obj(*oct->conf); if (!oct->conf) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c index 6f865dbbba6c..b579d5b545c4 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c @@ -325,9 +325,16 @@ static int octep_vf_oq_check_hw_for_pkts(struct octep_vf_device *oct, struct octep_vf_oq *oq) { u32 pkt_count, new_pkts; + u32 last_pkt_count, pkts_pending; pkt_count = readl(oq->pkts_sent_reg); - new_pkts = pkt_count - oq->last_pkt_count; + last_pkt_count = READ_ONCE(oq->last_pkt_count); + new_pkts = pkt_count - last_pkt_count; + + if (pkt_count < last_pkt_count) { + dev_err(oq->dev, "OQ-%u pkt_count(%u) < oq->last_pkt_count(%u)\n", + oq->q_no, pkt_count, last_pkt_count); + } /* Clear the hardware packets counter register if the rx queue is * being processed continuously with-in a single interrupt and @@ -339,8 +346,9 @@ static int octep_vf_oq_check_hw_for_pkts(struct octep_vf_device *oct, pkt_count = readl(oq->pkts_sent_reg); new_pkts += pkt_count; } - oq->last_pkt_count = pkt_count; - oq->pkts_pending += new_pkts; + WRITE_ONCE(oq->last_pkt_count, pkt_count); + pkts_pending = READ_ONCE(oq->pkts_pending); + WRITE_ONCE(oq->pkts_pending, (pkts_pending + new_pkts)); return new_pkts; } @@ -369,7 +377,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct, struct sk_buff *skb; u32 read_idx; - read_idx = oq->host_read_idx; + read_idx = READ_ONCE(oq->host_read_idx); rx_bytes = 0; desc_used = 0; for (pkt = 0; pkt < pkts_to_process; pkt++) { @@ -463,7 +471,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct, napi_gro_receive(oq->napi, skb); } - oq->host_read_idx = read_idx; + WRITE_ONCE(oq->host_read_idx, read_idx); oq->refill_count += desc_used; oq->stats->packets += pkt; oq->stats->bytes += rx_bytes; @@ -486,22 +494,26 @@ int octep_vf_oq_process_rx(struct octep_vf_oq *oq, int budget) { u32 pkts_available, pkts_processed, total_pkts_processed; struct octep_vf_device *oct = oq->octep_vf_dev; + u32 pkts_pending; pkts_available = 0; pkts_processed = 0; total_pkts_processed = 0; while (total_pkts_processed < budget) { /* update pending count only when current one exhausted */ - if (oq->pkts_pending == 0) + pkts_pending = READ_ONCE(oq->pkts_pending); + if (pkts_pending == 0) octep_vf_oq_check_hw_for_pkts(oct, oq); + pkts_pending = READ_ONCE(oq->pkts_pending); pkts_available = min(budget - total_pkts_processed, - oq->pkts_pending); + pkts_pending); if (!pkts_available) break; pkts_processed = __octep_vf_oq_process_rx(oct, oq, pkts_available); - oq->pkts_pending -= pkts_processed; + pkts_pending = READ_ONCE(oq->pkts_pending); + WRITE_ONCE(oq->pkts_pending, (pkts_pending - pkts_processed)); total_pkts_processed += pkts_processed; } diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c index fd4792e432bf..6000795823a3 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c @@ -1725,7 +1725,7 @@ static int cgx_lmac_init(struct cgx *cgx) cgx->lmac_count = cgx->max_lmac_per_mac; for (i = 0; i < cgx->lmac_count; i++) { - lmac = kzalloc(sizeof(struct lmac), GFP_KERNEL); + lmac = kzalloc_obj(struct lmac); if (!lmac) return -ENOMEM; lmac->name = kcalloc(1, sizeof("cgx_fwi_xxx_yyy"), GFP_KERNEL); diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c index 75872d257eca..d343f1704d07 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.c @@ -133,7 +133,7 @@ int cn20k_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev, mbox->reg_base = reg_base; mbox->pdev = pdev; - mbox->dev = kcalloc(ndevs, sizeof(struct otx2_mbox_dev), GFP_KERNEL); + mbox->dev = kzalloc_objs(struct otx2_mbox_dev, ndevs); if (!mbox->dev) { otx2_mbox_destroy(mbox); return -ENOMEM; @@ -211,7 +211,7 @@ static int otx2_mbox_setup(struct otx2_mbox *mbox, struct pci_dev *pdev, mbox->reg_base = reg_base; mbox->pdev = pdev; - mbox->dev = kcalloc(ndevs, sizeof(struct otx2_mbox_dev), GFP_KERNEL); + mbox->dev = kzalloc_objs(struct otx2_mbox_dev, ndevs); if (!mbox->dev) { otx2_mbox_destroy(mbox); return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c index a80c8e7c94f2..d98b49f47970 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs_rvu_if.c @@ -105,7 +105,7 @@ int mcs_add_intr_wq_entry(struct mcs *mcs, struct mcs_intr_event *event) if (!(pfvf->intr_mask && event->intr_mask)) return 0; - qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); + qentry = kmalloc_obj(*qentry, GFP_ATOMIC); if (!qentry) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c index 66749b3649c1..58e62e955554 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c @@ -520,7 +520,7 @@ static int ptp_probe(struct pci_dev *pdev, struct ptp *ptp; int err; - ptp = kzalloc(sizeof(*ptp), GFP_KERNEL); + ptp = kzalloc_obj(*ptp); if (!ptp) { err = -ENOMEM; goto error; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c index 8530df8b3fda..5b1129558e8b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c @@ -2516,7 +2516,7 @@ static int rvu_mbox_init(struct rvu *rvu, struct mbox_wq_info *mw, if (!pf_bmap) return -ENOMEM; - ng_rvu_mbox = kzalloc(sizeof(*ng_rvu_mbox), GFP_KERNEL); + ng_rvu_mbox = kzalloc_obj(*ng_rvu_mbox); if (!ng_rvu_mbox) { err = -ENOMEM; goto free_bitmap; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c index 3d91a34f8b57..4ff3935ed3fe 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_cgx.c @@ -184,7 +184,7 @@ static int rvu_cgx_send_link_info(int cgx_id, int lmac_id, struct rvu *rvu) unsigned long flags; int err; - qentry = kmalloc(sizeof(*qentry), GFP_KERNEL); + qentry = kmalloc_obj(*qentry); if (!qentry) return -ENOMEM; @@ -215,7 +215,7 @@ static int cgx_lmac_postevent(struct cgx_link_event *event, void *data) struct rvu *rvu = data; /* post event to the event queue */ - qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); + qentry = kmalloc_obj(*qentry, GFP_ATOMIC); if (!qentry) return -ENOMEM; qentry->link_event = *event; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c index 0f9953eaf1b0..a29f1ea04c7d 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_devlink.c @@ -327,10 +327,10 @@ static int rvu_nix_report_show(struct devlink_fmsg *fmsg, void *ctx, rvu_report_pair_end(fmsg); break; case NIX_AF_RVU_RAS: - intr_val = nix_event_context->nix_af_rvu_err; + intr_val = nix_event_context->nix_af_rvu_ras; rvu_report_pair_start(fmsg, "NIX_AF_RAS"); devlink_fmsg_u64_pair_put(fmsg, "\tNIX RAS Interrupt Reg ", - nix_event_context->nix_af_rvu_err); + nix_event_context->nix_af_rvu_ras); devlink_fmsg_string_put(fmsg, "\n\tPoison Data on:"); if (intr_val & BIT_ULL(34)) devlink_fmsg_string_put(fmsg, "\n\tNIX_AQ_INST_S"); @@ -475,7 +475,7 @@ static int rvu_hw_nix_ras_recover(struct devlink_health_reporter *reporter, if (blkaddr < 0) return blkaddr; - if (nix_event_ctx->nix_af_rvu_int) + if (nix_event_ctx->nix_af_rvu_ras) rvu_write64(rvu, blkaddr, NIX_AF_RAS_ENA_W1S, ~0ULL); return 0; @@ -494,12 +494,12 @@ static int rvu_nix_register_reporters(struct rvu_devlink *rvu_dl) struct rvu_nix_event_ctx *nix_event_context; struct rvu *rvu = rvu_dl->rvu; - rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL); + rvu_reporters = kzalloc_obj(*rvu_reporters); if (!rvu_reporters) return -ENOMEM; rvu_dl->rvu_nix_health_reporter = rvu_reporters; - nix_event_context = kzalloc(sizeof(*nix_event_context), GFP_KERNEL); + nix_event_context = kzalloc_obj(*nix_event_context); if (!nix_event_context) return -ENOMEM; @@ -1048,12 +1048,12 @@ static int rvu_npa_register_reporters(struct rvu_devlink *rvu_dl) struct rvu_npa_event_ctx *npa_event_context; struct rvu *rvu = rvu_dl->rvu; - rvu_reporters = kzalloc(sizeof(*rvu_reporters), GFP_KERNEL); + rvu_reporters = kzalloc_obj(*rvu_reporters); if (!rvu_reporters) return -ENOMEM; rvu_dl->rvu_npa_health_reporter = rvu_reporters; - npa_event_context = kzalloc(sizeof(*npa_event_context), GFP_KERNEL); + npa_event_context = kzalloc_obj(*npa_event_context); if (!npa_event_context) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c index 49f7ff5eddfc..98dd68137a09 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c @@ -2455,7 +2455,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, } /* XOFF all TL2s whose parent TL1 matches SMQ tree TL1 */ - smq_flush_ctx = kzalloc(sizeof(*smq_flush_ctx), GFP_KERNEL); + smq_flush_ctx = kzalloc_obj(*smq_flush_ctx); if (!smq_flush_ctx) return -ENOMEM; nix_smq_flush_fill_ctx(rvu, blkaddr, smq, smq_flush_ctx); @@ -3373,7 +3373,7 @@ static int nix_add_mce_list_entry(struct rvu *rvu, mce_list = &elem->mcast_mce_list; for (i = 0; i < num_entry; i++) { - mce = kzalloc(sizeof(*mce), GFP_KERNEL); + mce = kzalloc_obj(*mce); if (!mce) goto free_mce; @@ -3435,7 +3435,7 @@ static int nix_update_mce_list_entry(struct nix_mce_list *mce_list, return 0; /* Add a new one to the list, at the tail */ - mce = kzalloc(sizeof(*mce), GFP_KERNEL); + mce = kzalloc_obj(*mce); if (!mce) return -ENOMEM; mce->pcifunc = pcifunc; @@ -6420,7 +6420,7 @@ int rvu_mbox_handler_nix_mcast_grp_create(struct rvu *rvu, return err; mcast_grp = &nix_hw->mcast_grp; - elem = kzalloc(sizeof(*elem), GFP_KERNEL); + elem = kzalloc_obj(*elem); if (!elem) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c index c7c70429eb6c..8658cb2143df 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c @@ -1042,32 +1042,35 @@ void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, rvu_write64(rvu, blkaddr, NPC_AF_MCAMEX_BANKX_ACTION(index, bank), *(u64 *)&action); - /* update the VF flow rule action with the VF default entry action */ - if (mcam_index < 0) - npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, - *(u64 *)&action); - /* update the action change in default rule */ pfvf = rvu_get_pfvf(rvu, pcifunc); if (pfvf->def_ucast_rule) pfvf->def_ucast_rule->rx_action = action; - index = npc_get_nixlf_mcam_index(mcam, pcifunc, - nixlf, NIXLF_PROMISC_ENTRY); + if (mcam_index < 0) { + /* update the VF flow rule action with the VF default + * entry action + */ + npc_update_vf_flow_entry(rvu, mcam, blkaddr, pcifunc, + *(u64 *)&action); - /* If PF's promiscuous entry is enabled, - * Set RSS action for that entry as well - */ - npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, - alg_idx); + index = npc_get_nixlf_mcam_index(mcam, pcifunc, + nixlf, NIXLF_PROMISC_ENTRY); - index = npc_get_nixlf_mcam_index(mcam, pcifunc, - nixlf, NIXLF_ALLMULTI_ENTRY); - /* If PF's allmulti entry is enabled, - * Set RSS action for that entry as well - */ - npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, blkaddr, - alg_idx); + /* If PF's promiscuous entry is enabled, + * Set RSS action for that entry as well + */ + npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, + blkaddr, alg_idx); + + index = npc_get_nixlf_mcam_index(mcam, pcifunc, + nixlf, NIXLF_ALLMULTI_ENTRY); + /* If PF's allmulti entry is enabled, + * Set RSS action for that entry as well + */ + npc_update_rx_action_with_alg_idx(rvu, action, pfvf, index, + blkaddr, alg_idx); + } } void npc_enadis_default_mce_entry(struct rvu *rvu, u16 pcifunc, diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c index b56395ac5a74..1930b54e72f2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c @@ -1297,7 +1297,7 @@ static int npc_install_flow(struct rvu *rvu, int blkaddr, u16 target, find_rule: rule = rvu_mcam_find_rule(mcam, entry_index); if (!rule) { - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; new = true; @@ -1741,7 +1741,7 @@ int npc_install_mcam_drop_rule(struct rvu *rvu, int mcam_idx, u16 *counter_idx, } /* Add this entry to mcam rules list */ - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c index 999f6d93c7fe..906d712cef19 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_hash.c @@ -796,7 +796,7 @@ static int rvu_npc_exact_add_to_list(struct rvu *rvu, enum npc_exact_opc_type op return -EFAULT; } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { rvu_npc_exact_free_id(rvu, *seq_id); dev_err(rvu->dev, "%s: Memory allocation failed\n", __func__); @@ -1896,7 +1896,7 @@ int rvu_npc_exact_init(struct rvu *rvu) /* Set capability to true */ rvu->hw->cap.npc_exact_match_enabled = true; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c index 4415d0ce9aef..901f6fd40fd4 100644 --- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c +++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c @@ -97,7 +97,7 @@ int rvu_mbox_handler_rep_event_notify(struct rvu *rvu, struct rep_event *req, { struct rep_evtq_ent *qentry; - qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); + qentry = kmalloc_obj(*qentry, GFP_ATOMIC); if (!qentry) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c index 060c715ebad0..4649996dc7da 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_macsec.c @@ -914,7 +914,7 @@ static struct cn10k_mcs_txsc *cn10k_mcs_create_txsc(struct otx2_nic *pfvf) struct cn10k_mcs_txsc *txsc; int ret; - txsc = kzalloc(sizeof(*txsc), GFP_KERNEL); + txsc = kzalloc_obj(*txsc); if (!txsc) return ERR_PTR(-ENOMEM); @@ -987,7 +987,7 @@ static struct cn10k_mcs_rxsc *cn10k_mcs_create_rxsc(struct otx2_nic *pfvf) struct cn10k_mcs_rxsc *rxsc; int ret; - rxsc = kzalloc(sizeof(*rxsc), GFP_KERNEL); + rxsc = kzalloc_obj(*rxsc); if (!rxsc) return ERR_PTR(-ENOMEM); @@ -1772,7 +1772,7 @@ int cn10k_mcs_init(struct otx2_nic *pfvf) if (!test_bit(CN10K_HW_MACSEC, &pfvf->hw.cap_flag)) return 0; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c index 75ebb17419c4..971fcab1c248 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c @@ -1005,7 +1005,7 @@ int otx2_sq_init(struct otx2_nic *pfvf, u16 qidx, u16 sqb_aura) } sq->sqe_base = sq->sqe->base; - sq->sg = kcalloc(qset->sqe_cnt, sizeof(struct sg_list), GFP_KERNEL); + sq->sg = kzalloc_objs(struct sg_list, qset->sqe_cnt); if (!sq->sg) return -ENOMEM; @@ -1585,7 +1585,7 @@ int otx2_sq_aura_pool_init(struct otx2_nic *pfvf) sq = &qset->sq[qidx]; sq->sqb_count = 0; - sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL); + sq->sqb_ptrs = kzalloc_objs(*sq->sqb_ptrs, num_sqbs); if (!sq->sqb_ptrs) { err = -ENOMEM; goto err_mem; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c index 64c6d9162ef6..12c001ee34e2 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_flows.c @@ -1063,7 +1063,7 @@ static int otx2_add_flow_with_pfmac(struct otx2_nic *pfvf, struct otx2_flow *pf_mac; struct ethhdr *eth_hdr; - pf_mac = kzalloc(sizeof(*pf_mac), GFP_KERNEL); + pf_mac = kzalloc_obj(*pf_mac); if (!pf_mac) return -ENOMEM; @@ -1131,7 +1131,7 @@ int otx2_add_flow(struct otx2_nic *pfvf, struct ethtool_rxnfc *nfc) flow = otx2_find_flow(pfvf, fsp->location); if (!flow) { - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (!flow) return -ENOMEM; flow->location = fsp->location; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c index 444bb67494ab..ee623476e5ff 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c @@ -1936,7 +1936,7 @@ int otx2_alloc_queue_mem(struct otx2_nic *pf) pf->qset.cq_cnt = pf->hw.rx_queues + otx2_get_total_tx_queues(pf); - qset->napi = kcalloc(pf->hw.cint_cnt, sizeof(*cq_poll), GFP_KERNEL); + qset->napi = kzalloc_objs(*cq_poll, pf->hw.cint_cnt); if (!qset->napi) return -ENOMEM; @@ -1945,18 +1945,16 @@ int otx2_alloc_queue_mem(struct otx2_nic *pf) /* CQ size of SQ */ qset->sqe_cnt = qset->sqe_cnt ? qset->sqe_cnt : Q_COUNT(Q_SIZE_4K); - qset->cq = kcalloc(pf->qset.cq_cnt, - sizeof(struct otx2_cq_queue), GFP_KERNEL); + qset->cq = kzalloc_objs(struct otx2_cq_queue, pf->qset.cq_cnt); if (!qset->cq) goto err_free_mem; - qset->sq = kcalloc(otx2_get_total_tx_queues(pf), - sizeof(struct otx2_snd_queue), GFP_KERNEL); + qset->sq = kzalloc_objs(struct otx2_snd_queue, + otx2_get_total_tx_queues(pf)); if (!qset->sq) goto err_free_mem; - qset->rq = kcalloc(pf->hw.rx_queues, - sizeof(struct otx2_rcv_queue), GFP_KERNEL); + qset->rq = kzalloc_objs(struct otx2_rcv_queue, pf->hw.rx_queues); if (!qset->rq) goto err_free_mem; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c index dedd586ed310..95b0a1e7c936 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c @@ -408,7 +408,7 @@ int otx2_ptp_init(struct otx2_nic *pfvf) } mutex_unlock(&pfvf->mbox.lock); - ptp_ptr = kzalloc(sizeof(*ptp_ptr), GFP_KERNEL); + ptp_ptr = kzalloc_obj(*ptp_ptr); if (!ptp_ptr) { err = -ENOMEM; goto error; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c index 26a08d2cfbb1..04fcfbdcf69b 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c @@ -1271,7 +1271,7 @@ static int otx2_tc_add_flow(struct otx2_nic *nic, } /* allocate memory for the new flow and it's node */ - new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); + new_node = kzalloc_obj(*new_node); if (!new_node) return -ENOMEM; spin_lock_init(&new_node->lock); diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c index 5765bac119f0..69c0911e28e9 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c @@ -407,7 +407,7 @@ otx2_qos_alloc_root(struct otx2_nic *pfvf) { struct otx2_qos_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return ERR_PTR(-ENOMEM); @@ -463,7 +463,7 @@ static int otx2_qos_alloc_txschq_node(struct otx2_nic *pfvf, parent = node; for (lvl = node->level - 1; lvl >= NIX_TXSCH_LVL_MDQ; lvl--) { - txschq_node = kzalloc(sizeof(*txschq_node), GFP_KERNEL); + txschq_node = kzalloc_obj(*txschq_node); if (!txschq_node) goto err_out; @@ -508,7 +508,7 @@ otx2_qos_sw_create_leaf_node(struct otx2_nic *pfvf, struct otx2_qos_node *node; int err; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return ERR_PTR(-ENOMEM); @@ -1045,7 +1045,7 @@ static int otx2_qos_root_add(struct otx2_nic *pfvf, u16 htb_maj_id, u16 htb_defc } /* allocate txschq queue */ - new_cfg = kzalloc(sizeof(*new_cfg), GFP_KERNEL); + new_cfg = kzalloc_obj(*new_cfg); if (!new_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); err = -ENOMEM; @@ -1279,7 +1279,7 @@ static int otx2_qos_leaf_alloc_queue(struct otx2_nic *pfvf, u16 classid, set_bit(prio, parent->prio_bmap); /* read current txschq configuration */ - old_cfg = kzalloc(sizeof(*old_cfg), GFP_KERNEL); + old_cfg = kzalloc_obj(*old_cfg); if (!old_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); ret = -ENOMEM; @@ -1308,7 +1308,7 @@ static int otx2_qos_leaf_alloc_queue(struct otx2_nic *pfvf, u16 classid, } /* push new txschq config to hw */ - new_cfg = kzalloc(sizeof(*new_cfg), GFP_KERNEL); + new_cfg = kzalloc_obj(*new_cfg); if (!new_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); ret = -ENOMEM; @@ -1417,7 +1417,7 @@ static int otx2_qos_leaf_to_inner(struct otx2_nic *pfvf, u16 classid, qid = node->qid; /* read current txschq configuration */ - old_cfg = kzalloc(sizeof(*old_cfg), GFP_KERNEL); + old_cfg = kzalloc_obj(*old_cfg); if (!old_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); ret = -ENOMEM; @@ -1445,7 +1445,7 @@ static int otx2_qos_leaf_to_inner(struct otx2_nic *pfvf, u16 classid, } /* push new txschq config to hw */ - new_cfg = kzalloc(sizeof(*new_cfg), GFP_KERNEL); + new_cfg = kzalloc_obj(*new_cfg); if (!new_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); ret = -ENOMEM; @@ -1668,7 +1668,7 @@ static int otx2_qos_leaf_del_last(struct otx2_nic *pfvf, u16 classid, bool force __set_bit(qid, pfvf->qos.qos_sq_bmap); /* push new txschq config to hw */ - new_cfg = kzalloc(sizeof(*new_cfg), GFP_KERNEL); + new_cfg = kzalloc_obj(*new_cfg); if (!new_cfg) { NL_SET_ERR_MSG_MOD(extack, "Memory allocation error"); return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c index b476733a0234..94f155ffb17f 100644 --- a/drivers/net/ethernet/marvell/octeontx2/nic/rep.c +++ b/drivers/net/ethernet/marvell/octeontx2/nic/rep.c @@ -40,7 +40,7 @@ static int rvu_rep_mcam_flow_init(struct rep_dev *rep) int ent, allocated = 0; int count; - rep->flow_cfg = kcalloc(1, sizeof(struct otx2_flow_config), GFP_KERNEL); + rep->flow_cfg = kzalloc_objs(struct otx2_flow_config, 1); if (!rep->flow_cfg) return -ENOMEM; @@ -504,7 +504,7 @@ static int rvu_rep_napi_init(struct otx2_nic *priv, int err = 0, qidx, vec; char *irq_name; - qset->napi = kcalloc(hw->cint_cnt, sizeof(*cq_poll), GFP_KERNEL); + qset->napi = kzalloc_objs(*cq_poll, hw->cint_cnt); if (!qset->napi) return -ENOMEM; @@ -656,7 +656,7 @@ int rvu_rep_create(struct otx2_nic *priv, struct netlink_ext_ack *extack) if (err) return -ENOMEM; - priv->reps = kcalloc(rep_cnt, sizeof(struct rep_dev *), GFP_KERNEL); + priv->reps = kzalloc_objs(struct rep_dev *, rep_cnt); if (!priv->reps) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_acl.c b/drivers/net/ethernet/marvell/prestera/prestera_acl.c index cba89fda504b..31fe63a0a97d 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_acl.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_acl.c @@ -144,7 +144,7 @@ prestera_acl_ruleset_create(struct prestera_acl *acl, if (!prestera_acl_chain_is_supported(chain_index, block->ingress)) return ERR_PTR(-EINVAL); - ruleset = kzalloc(sizeof(*ruleset), GFP_KERNEL); + ruleset = kzalloc_obj(*ruleset); if (!ruleset) return ERR_PTR(-ENOMEM); @@ -438,7 +438,7 @@ prestera_acl_rule_create(struct prestera_acl_ruleset *ruleset, { struct prestera_acl_rule *rule; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return ERR_PTR(-ENOMEM); @@ -713,7 +713,7 @@ prestera_acl_rule_entry_create(struct prestera_acl *acl, struct prestera_acl_rule_entry *e; int err; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) goto err_kzalloc; @@ -816,7 +816,7 @@ int prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup, u8 dir, } /* vtcam not found, try to create new one */ - vtcam = kzalloc(sizeof(*vtcam), GFP_KERNEL); + vtcam = kzalloc_obj(*vtcam); if (!vtcam) return -ENOMEM; @@ -880,7 +880,7 @@ int prestera_acl_init(struct prestera_switch *sw) struct prestera_acl *acl; int err; - acl = kzalloc(sizeof(*acl), GFP_KERNEL); + acl = kzalloc_obj(*acl); if (!acl) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_counter.c b/drivers/net/ethernet/marvell/prestera/prestera_counter.c index 634f4543c1d7..3a762d17ba6c 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_counter.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_counter.c @@ -147,7 +147,7 @@ prestera_counter_block_get(struct prestera_counter *counter, u32 client) if (block) return block; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return ERR_PTR(-ENOMEM); @@ -157,8 +157,7 @@ prestera_counter_block_get(struct prestera_counter *counter, u32 client) if (err) goto err_block; - block->stats = kcalloc(block->num_counters, - sizeof(*block->stats), GFP_KERNEL); + block->stats = kzalloc_objs(*block->stats, block->num_counters); if (!block->stats) { err = -ENOMEM; goto err_stats; @@ -437,11 +436,11 @@ int prestera_counter_init(struct prestera_switch *sw) { struct prestera_counter *counter; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc_obj(*counter); if (!counter) return -ENOMEM; - counter->block_list = kzalloc(sizeof(*counter->block_list), GFP_KERNEL); + counter->block_list = kzalloc_obj(*counter->block_list); if (!counter->block_list) { kfree(counter); return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c index e63d95c1842f..33dea101bc67 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_devlink.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_devlink.c @@ -451,13 +451,12 @@ int prestera_devlink_traps_register(struct prestera_switch *sw) struct prestera_trap *prestera_trap; int err, i; - trap_data = kzalloc(sizeof(*trap_data), GFP_KERNEL); + trap_data = kzalloc_obj(*trap_data); if (!trap_data) return -ENOMEM; - trap_data->trap_items_arr = kcalloc(traps_count, - sizeof(struct prestera_trap_item), - GFP_KERNEL); + trap_data->trap_items_arr = kzalloc_objs(struct prestera_trap_item, + traps_count); if (!trap_data->trap_items_arr) { err = -ENOMEM; goto err_trap_items_alloc; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flow.c b/drivers/net/ethernet/marvell/prestera/prestera_flow.c index 9f4267f326b0..88db1a59a57b 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_flow.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_flow.c @@ -82,7 +82,7 @@ prestera_flow_block_create(struct prestera_switch *sw, { struct prestera_flow_block *block; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return NULL; @@ -130,7 +130,7 @@ static int prestera_flow_block_bind(struct prestera_flow_block *block, struct prestera_flow_block_binding *binding; int err; - binding = kzalloc(sizeof(*binding), GFP_KERNEL); + binding = kzalloc_obj(*binding); if (!binding) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_flower.c b/drivers/net/ethernet/marvell/prestera/prestera_flower.c index 418101a93149..58b116cabd48 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_flower.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_flower.c @@ -495,7 +495,7 @@ int prestera_flower_tmplt_create(struct prestera_flow_block *block, if (err) return err; - template = kmalloc(sizeof(*template), GFP_KERNEL); + template = kmalloc_obj(*template); if (!template) { err = -ENOMEM; goto err_malloc; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c index 197198ba61b1..7695cbb2ce62 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c @@ -2256,7 +2256,7 @@ int prestera_hw_event_handler_register(struct prestera_switch *sw, if (eh) return -EEXIST; - eh = kmalloc(sizeof(*eh), GFP_KERNEL); + eh = kmalloc_obj(*eh); if (!eh) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_main.c b/drivers/net/ethernet/marvell/prestera/prestera_main.c index 65e7ef033bde..41e19e9ad28d 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_main.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_main.c @@ -1014,7 +1014,7 @@ static int prestera_lag_init(struct prestera_switch *sw) { u16 id; - sw->lags = kcalloc(sw->lag_max, sizeof(*sw->lags), GFP_KERNEL); + sw->lags = kzalloc_objs(*sw->lags, sw->lag_max); if (!sw->lags) return -ENOMEM; @@ -1209,7 +1209,7 @@ prestera_mdb_entry_create(struct prestera_switch *sw, struct prestera_flood_domain *flood_domain; struct prestera_mdb_entry *mdb_entry; - mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL); + mdb_entry = kzalloc_obj(*mdb_entry); if (!mdb_entry) goto err_mdb_alloc; @@ -1247,7 +1247,7 @@ prestera_flood_domain_create(struct prestera_switch *sw) { struct prestera_flood_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return NULL; @@ -1279,7 +1279,7 @@ prestera_flood_domain_port_create(struct prestera_flood_domain *flood_domain, bool is_first_port_in_list = false; int err; - flood_domain_port = kzalloc(sizeof(*flood_domain_port), GFP_KERNEL); + flood_domain_port = kzalloc_obj(*flood_domain_port); if (!flood_domain_port) { err = -ENOMEM; goto err_port_alloc; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router.c b/drivers/net/ethernet/marvell/prestera/prestera_router.c index de317179a7dc..b036b173a308 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_router.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_router.c @@ -485,7 +485,7 @@ __prestera_kern_neigh_cache_create(struct prestera_switch *sw, struct prestera_kern_neigh_cache *n_cache; int err; - n_cache = kzalloc(sizeof(*n_cache), GFP_KERNEL); + n_cache = kzalloc_obj(*n_cache); if (!n_cache) goto err_kzalloc; @@ -623,7 +623,7 @@ prestera_kern_fib_cache_create(struct prestera_switch *sw, struct prestera_kern_fib_cache *fib_cache; int err; - fib_cache = kzalloc(sizeof(*fib_cache), GFP_KERNEL); + fib_cache = kzalloc_obj(*fib_cache); if (!fib_cache) goto err_kzalloc; @@ -1448,7 +1448,7 @@ static int __prestera_router_fib_event(struct notifier_block *nb, if (!fen_info->fi) return NOTIFY_DONE; - fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); + fib_work = kzalloc_obj(*fib_work, GFP_ATOMIC); if (WARN_ON(!fib_work)) return NOTIFY_BAD; @@ -1503,7 +1503,7 @@ static int prestera_router_netevent_event(struct notifier_block *nb, if (n->tbl->family != AF_INET) return NOTIFY_DONE; - net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC); + net_work = kzalloc_obj(*net_work, GFP_ATOMIC); if (WARN_ON(!net_work)) return NOTIFY_BAD; @@ -1550,7 +1550,7 @@ int prestera_router_init(struct prestera_switch *sw) struct prestera_router *router; int err, nhgrp_cache_bytes; - router = kzalloc(sizeof(*sw->router), GFP_KERNEL); + router = kzalloc_obj(*sw->router); if (!router) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c index 02faaea2aefa..ccf6cf98920f 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c @@ -127,7 +127,7 @@ static struct prestera_vr *__prestera_vr_create(struct prestera_switch *sw, struct prestera_vr *vr; int err; - vr = kzalloc(sizeof(*vr), GFP_KERNEL); + vr = kzalloc_obj(*vr); if (!vr) { err = -ENOMEM; goto err_alloc_vr; @@ -252,7 +252,7 @@ prestera_rif_entry_create(struct prestera_switch *sw, struct prestera_rif_entry *e; struct prestera_iface iface; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) goto err_kzalloc; @@ -301,7 +301,7 @@ __prestera_nh_neigh_create(struct prestera_switch *sw, struct prestera_nh_neigh *neigh; int err; - neigh = kzalloc(sizeof(*neigh), GFP_KERNEL); + neigh = kzalloc_obj(*neigh); if (!neigh) goto err_kzalloc; @@ -397,7 +397,7 @@ __prestera_nexthop_group_create(struct prestera_switch *sw, struct prestera_nh_neigh *nh_neigh; int nh_cnt, err, gid; - nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL); + nh_grp = kzalloc_obj(*nh_grp); if (!nh_grp) goto err_kzalloc; @@ -628,7 +628,7 @@ prestera_fib_node_create(struct prestera_switch *sw, struct prestera_vr *vr; int err; - fib_node = kzalloc(sizeof(*fib_node), GFP_KERNEL); + fib_node = kzalloc_obj(*fib_node); if (!fib_node) goto err_kzalloc; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c index 39d9bf82c115..c4ea247d2470 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_rxtx.c @@ -379,7 +379,7 @@ static int prestera_sdma_rx_init(struct prestera_sdma *sdma) struct prestera_sdma_buf *head, *tail, *next, *prev; struct prestera_rx_ring *ring = &sdma->rx_ring[q]; - ring->bufs = kmalloc_array(bnum, sizeof(*head), GFP_KERNEL); + ring->bufs = kmalloc_objs(*head, bnum); if (!ring->bufs) return -ENOMEM; @@ -529,7 +529,7 @@ static int prestera_sdma_tx_init(struct prestera_sdma *sdma) INIT_WORK(&sdma->tx_work, prestera_sdma_tx_recycle_work_fn); spin_lock_init(&sdma->tx_lock); - tx_ring->bufs = kmalloc_array(bnum, sizeof(*head), GFP_KERNEL); + tx_ring->bufs = kmalloc_objs(*head, bnum); if (!tx_ring->bufs) return -ENOMEM; @@ -784,7 +784,7 @@ int prestera_rxtx_switch_init(struct prestera_switch *sw) struct prestera_rxtx *rxtx; int err; - rxtx = kzalloc(sizeof(*rxtx), GFP_KERNEL); + rxtx = kzalloc_obj(*rxtx); if (!rxtx) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_span.c b/drivers/net/ethernet/marvell/prestera/prestera_span.c index 1005182ce3bc..bb2f74524e1c 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_span.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_span.c @@ -27,7 +27,7 @@ prestera_span_entry_create(struct prestera_port *port, u8 span_id) { struct prestera_span_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -170,7 +170,7 @@ int prestera_span_init(struct prestera_switch *sw) { struct prestera_span *span; - span = kzalloc(sizeof(*span), GFP_KERNEL); + span = kzalloc_obj(*span); if (!span) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c index e548cd32582e..2012d00fabec 100644 --- a/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c +++ b/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c @@ -180,7 +180,7 @@ prestera_bridge_vlan_create(struct prestera_bridge_port *br_port, u16 vid) { struct prestera_bridge_vlan *br_vlan; - br_vlan = kzalloc(sizeof(*br_vlan), GFP_KERNEL); + br_vlan = kzalloc_obj(*br_vlan); if (!br_vlan) return NULL; @@ -263,7 +263,7 @@ prestera_port_vlan_create(struct prestera_port *port, u16 vid, bool untagged) if (err) return ERR_PTR(err); - port_vlan = kzalloc(sizeof(*port_vlan), GFP_KERNEL); + port_vlan = kzalloc_obj(*port_vlan); if (!port_vlan) { err = -ENOMEM; goto err_port_vlan_alloc; @@ -443,7 +443,7 @@ prestera_bridge_create(struct prestera_switchdev *swdev, struct net_device *dev) return ERR_PTR(-EINVAL); } - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return ERR_PTR(-ENOMEM); @@ -562,7 +562,7 @@ prestera_bridge_port_create(struct prestera_bridge *bridge, { struct prestera_bridge_port *br_port; - br_port = kzalloc(sizeof(*br_port), GFP_KERNEL); + br_port = kzalloc_obj(*br_port); if (!br_port) return NULL; @@ -1313,7 +1313,7 @@ static int prestera_switchdev_event(struct notifier_block *unused, if (!netif_is_bridge_master(upper)) return NOTIFY_DONE; - swdev_work = kzalloc(sizeof(*swdev_work), GFP_ATOMIC); + swdev_work = kzalloc_obj(*swdev_work, GFP_ATOMIC); if (!swdev_work) return NOTIFY_BAD; @@ -1498,7 +1498,7 @@ prestera_br_mdb_entry_create(struct prestera_switch *sw, struct prestera_br_mdb_entry *br_mdb_entry; struct prestera_mdb_entry *mdb_entry; - br_mdb_entry = kzalloc(sizeof(*br_mdb_entry), GFP_KERNEL); + br_mdb_entry = kzalloc_obj(*br_mdb_entry); if (!br_mdb_entry) return NULL; @@ -1530,7 +1530,7 @@ static int prestera_br_mdb_port_add(struct prestera_br_mdb_entry *br_mdb, if (br_mdb_port->br_port == br_port) return 0; - br_mdb_port = kzalloc(sizeof(*br_mdb_port), GFP_KERNEL); + br_mdb_port = kzalloc_obj(*br_mdb_port); if (!br_mdb_port) return -ENOMEM; @@ -1873,7 +1873,7 @@ int prestera_switchdev_init(struct prestera_switch *sw) struct prestera_switchdev *swdev; int err; - swdev = kzalloc(sizeof(*swdev), GFP_KERNEL); + swdev = kzalloc_obj(*swdev); if (!swdev) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 68f8a1e36aa6..bbbbbba63e15 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1024,7 +1024,7 @@ static int rxq_init(struct net_device *dev) int rx_desc_num = pep->rx_ring_size; /* Allocate RX skb rings */ - pep->rx_skb = kcalloc(rx_desc_num, sizeof(*pep->rx_skb), GFP_KERNEL); + pep->rx_skb = kzalloc_objs(*pep->rx_skb, rx_desc_num); if (!pep->rx_skb) return -ENOMEM; @@ -1083,7 +1083,7 @@ static int txq_init(struct net_device *dev) int size = 0, i = 0; int tx_desc_num = pep->tx_ring_size; - pep->tx_skb = kcalloc(tx_desc_num, sizeof(*pep->tx_skb), GFP_KERNEL); + pep->tx_skb = kzalloc_objs(*pep->tx_skb, tx_desc_num); if (!pep->tx_skb) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index cf4e26d337bb..e386c8314e21 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -918,7 +918,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u32 base) struct skge_element *e; int i; - ring->start = kcalloc(ring->count, sizeof(*e), GFP_KERNEL); + ring->start = kzalloc_objs(*e, ring->count); if (!ring->start) return -ENOMEM; diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 3831f533b9db..30facdece3e2 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1601,8 +1601,7 @@ static int sky2_alloc_buffers(struct sky2_port *sky2) if (!sky2->tx_le) goto nomem; - sky2->tx_ring = kcalloc(sky2->tx_ring_size, sizeof(struct tx_ring_info), - GFP_KERNEL); + sky2->tx_ring = kzalloc_objs(struct tx_ring_info, sky2->tx_ring_size); if (!sky2->tx_ring) goto nomem; @@ -1611,8 +1610,7 @@ static int sky2_alloc_buffers(struct sky2_port *sky2) if (!sky2->rx_le) goto nomem; - sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct rx_ring_info), - GFP_KERNEL); + sky2->rx_ring = kzalloc_objs(struct rx_ring_info, sky2->rx_pending); if (!sky2->rx_ring) goto nomem; diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 35fef28ee2f9..ddc321a02fda 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -2647,8 +2647,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth) else ring_size = soc->tx.dma_size; - ring->buf = kcalloc(ring_size, sizeof(*ring->buf), - GFP_KERNEL); + ring->buf = kzalloc_objs(*ring->buf, ring_size); if (!ring->buf) goto no_tx_mem; @@ -3749,12 +3748,21 @@ static int mtk_xdp_setup(struct net_device *dev, struct bpf_prog *prog, mtk_stop(dev); old_prog = rcu_replace_pointer(eth->prog, prog, lockdep_rtnl_is_held()); + + if (netif_running(dev) && need_update) { + int err; + + err = mtk_open(dev); + if (err) { + rcu_assign_pointer(eth->prog, old_prog); + + return err; + } + } + if (old_prog) bpf_prog_put(old_prog); - if (netif_running(dev) && need_update) - return mtk_open(dev); - return 0; } diff --git a/drivers/net/ethernet/mediatek/mtk_ppe.c b/drivers/net/ethernet/mediatek/mtk_ppe.c index ada852adc5f7..75f7728fc796 100644 --- a/drivers/net/ethernet/mediatek/mtk_ppe.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe.c @@ -705,7 +705,7 @@ mtk_foe_entry_commit_subflow(struct mtk_ppe *ppe, struct mtk_flow_entry *entry, u32 ib1_mask = mtk_get_ib1_pkt_type_mask(ppe->eth) | MTK_FOE_IB1_UDP; int type; - flow_info = kzalloc(sizeof(*flow_info), GFP_ATOMIC); + flow_info = kzalloc_obj(*flow_info, GFP_ATOMIC); if (!flow_info) return; diff --git a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c index e9bd32741983..cb30108f2bf6 100644 --- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c +++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c @@ -469,7 +469,7 @@ mtk_flow_offload_replace(struct mtk_eth *eth, struct flow_cls_offload *f, if (wed_index >= 0 && (err = mtk_wed_flow_add(wed_index)) < 0) return err; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/net/ethernet/mediatek/mtk_wed.c b/drivers/net/ethernet/mediatek/mtk_wed.c index 1ed1f88dd7f8..10d9beaae372 100644 --- a/drivers/net/ethernet/mediatek/mtk_wed.c +++ b/drivers/net/ethernet/mediatek/mtk_wed.c @@ -656,7 +656,7 @@ mtk_wed_tx_buffer_alloc(struct mtk_wed_device *dev) } n_pages = dev->tx_buf_ring.size / MTK_WED_BUF_PER_PAGE; - page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); + page_list = kzalloc_objs(*page_list, n_pages); if (!page_list) return -ENOMEM; @@ -780,7 +780,7 @@ mtk_wed_hwrro_buffer_alloc(struct mtk_wed_device *dev) if (!dev->wlan.hw_rro) return 0; - page_list = kcalloc(n_pages, sizeof(*page_list), GFP_KERNEL); + page_list = kzalloc_objs(*page_list, n_pages); if (!page_list) return -ENOMEM; @@ -2718,7 +2718,7 @@ mtk_wed_setup_tc_block(struct mtk_wed_hw *hw, struct net_device *dev, return 0; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -2822,7 +2822,7 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth, if (WARN_ON(hw_list[index])) goto unlock; - hw = kzalloc(sizeof(*hw), GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) goto unlock; diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c index 07b061a97a6e..7ed4452e20a9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c @@ -223,7 +223,7 @@ struct mlx4_zone_entry { struct mlx4_zone_allocator *mlx4_zone_allocator_create(enum mlx4_zone_alloc_flags flags) { - struct mlx4_zone_allocator *zones = kmalloc(sizeof(*zones), GFP_KERNEL); + struct mlx4_zone_allocator *zones = kmalloc_obj(*zones); if (NULL == zones) return NULL; @@ -247,7 +247,7 @@ int mlx4_zone_add_one(struct mlx4_zone_allocator *zone_alloc, { u32 mask = mlx4_bitmap_masked_value(bitmap, (u32)-1); struct mlx4_zone_entry *it; - struct mlx4_zone_entry *zone = kmalloc(sizeof(*zone), GFP_KERNEL); + struct mlx4_zone_entry *zone = kmalloc_obj(*zone); if (NULL == zone) return -ENOMEM; @@ -594,8 +594,7 @@ int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, buf->nbufs = DIV_ROUND_UP(size, PAGE_SIZE); buf->npages = buf->nbufs; buf->page_shift = PAGE_SHIFT; - buf->page_list = kcalloc(buf->nbufs, sizeof(*buf->page_list), - GFP_KERNEL); + buf->page_list = kzalloc_objs(*buf->page_list, buf->nbufs); if (!buf->page_list) return -ENOMEM; @@ -642,7 +641,7 @@ static struct mlx4_db_pgdir *mlx4_alloc_db_pgdir(struct device *dma_device) { struct mlx4_db_pgdir *pgdir; - pgdir = kzalloc(sizeof(*pgdir), GFP_KERNEL); + pgdir = kzalloc_obj(*pgdir); if (!pgdir) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx4/cmd.c b/drivers/net/ethernet/mellanox/mlx4/cmd.c index 7f20813456e2..de0193d82ec1 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx4/cmd.c @@ -1674,7 +1674,7 @@ static int mlx4_master_process_vhcr(struct mlx4_dev *dev, int slave, int err = 0; /* Create sw representation of Virtual HCR */ - vhcr = kzalloc(sizeof(struct mlx4_vhcr), GFP_KERNEL); + vhcr = kzalloc_obj(struct mlx4_vhcr); if (!vhcr) return -ENOMEM; @@ -1873,7 +1873,7 @@ static int mlx4_master_immediate_activate_vlan_qos(struct mlx4_priv *priv, vp_admin->default_vlan, vp_admin->default_qos, vp_admin->link_state); - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; @@ -2368,23 +2368,18 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) struct mlx4_vf_admin_state *vf_admin; priv->mfunc.master.slave_state = - kcalloc(dev->num_slaves, - sizeof(struct mlx4_slave_state), - GFP_KERNEL); + kzalloc_objs(struct mlx4_slave_state, dev->num_slaves); if (!priv->mfunc.master.slave_state) goto err_comm; priv->mfunc.master.vf_admin = - kcalloc(dev->num_slaves, - sizeof(struct mlx4_vf_admin_state), - GFP_KERNEL); + kzalloc_objs(struct mlx4_vf_admin_state, + dev->num_slaves); if (!priv->mfunc.master.vf_admin) goto err_comm_admin; priv->mfunc.master.vf_oper = - kcalloc(dev->num_slaves, - sizeof(struct mlx4_vf_oper_state), - GFP_KERNEL); + kzalloc_objs(struct mlx4_vf_oper_state, dev->num_slaves); if (!priv->mfunc.master.vf_oper) goto err_comm_oper; @@ -2408,8 +2403,7 @@ int mlx4_multi_func_init(struct mlx4_dev *dev) struct mlx4_vport_state *oper_vport; s_state->vlan_filter[port] = - kzalloc(sizeof(struct mlx4_vlan_fltr), - GFP_KERNEL); + kzalloc_obj(struct mlx4_vlan_fltr); if (!s_state->vlan_filter[port]) { if (--port) kfree(s_state->vlan_filter[port]); @@ -2625,9 +2619,8 @@ int mlx4_cmd_use_events(struct mlx4_dev *dev) int i; int err = 0; - priv->cmd.context = kmalloc_array(priv->cmd.max_cmds, - sizeof(struct mlx4_cmd_context), - GFP_KERNEL); + priv->cmd.context = kmalloc_objs(struct mlx4_cmd_context, + priv->cmd.max_cmds); if (!priv->cmd.context) return -ENOMEM; @@ -2693,7 +2686,7 @@ struct mlx4_cmd_mailbox *mlx4_alloc_cmd_mailbox(struct mlx4_dev *dev) { struct mlx4_cmd_mailbox *mailbox; - mailbox = kmalloc(sizeof(*mailbox), GFP_KERNEL); + mailbox = kmalloc_obj(*mailbox); if (!mailbox) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index ad6298456639..4ba19470df1e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c @@ -1158,7 +1158,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev, tx_size == priv->tx_ring[TX][0]->size) return 0; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -1452,8 +1452,8 @@ static int add_ip_rule(struct mlx4_en_priv *priv, struct mlx4_spec_list *spec_l3; struct ethtool_usrip4_spec *l3_mask = &cmd->fs.m_u.usr_ip4_spec; - spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL); - spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); + spec_l3 = kzalloc_obj(*spec_l3); + spec_l2 = kzalloc_obj(*spec_l2); if (!spec_l2 || !spec_l3) { err = -ENOMEM; goto free_spec; @@ -1491,9 +1491,9 @@ static int add_tcp_udp_rule(struct mlx4_en_priv *priv, struct mlx4_spec_list *spec_l4; struct ethtool_tcpip4_spec *l4_mask = &cmd->fs.m_u.tcp_ip4_spec; - spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); - spec_l3 = kzalloc(sizeof(*spec_l3), GFP_KERNEL); - spec_l4 = kzalloc(sizeof(*spec_l4), GFP_KERNEL); + spec_l2 = kzalloc_obj(*spec_l2); + spec_l3 = kzalloc_obj(*spec_l3); + spec_l4 = kzalloc_obj(*spec_l4); if (!spec_l2 || !spec_l3 || !spec_l4) { err = -ENOMEM; goto free_spec; @@ -1564,7 +1564,7 @@ static int mlx4_en_ethtool_to_net_trans_rule(struct net_device *dev, switch (cmd->fs.flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) { case ETHER_FLOW: - spec_l2 = kzalloc(sizeof(*spec_l2), GFP_KERNEL); + spec_l2 = kzalloc_obj(*spec_l2); if (!spec_l2) return -ENOMEM; @@ -1833,7 +1833,7 @@ static int mlx4_en_set_channels(struct net_device *dev, if (!channel->tx_count || !channel->rx_count) return -EINVAL; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c index d8f4d00ad26b..a106c0e1e9ad 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c @@ -271,7 +271,7 @@ static int mlx4_en_probe(struct auxiliary_device *adev, printk_once(KERN_INFO "%s", mlx4_en_version); - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) { err = -ENOMEM; goto err_free_res; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 81bf8908b897..071564c54522 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -99,7 +99,7 @@ int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc) int port_up = 0; int err = 0; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -295,7 +295,7 @@ mlx4_en_filter_alloc(struct mlx4_en_priv *priv, int rxq_index, __be32 src_ip, { struct mlx4_en_filter *filter; - filter = kzalloc(sizeof(struct mlx4_en_filter), GFP_ATOMIC); + filter = kzalloc_obj(struct mlx4_en_filter, GFP_ATOMIC); if (!filter) return NULL; @@ -827,7 +827,7 @@ static void mlx4_en_cache_mclist(struct net_device *dev) mlx4_en_clear_list(dev); netdev_for_each_mc_addr(ha, dev) { - tmp = kzalloc(sizeof(struct mlx4_en_mc_list), GFP_ATOMIC); + tmp = kzalloc_obj(struct mlx4_en_mc_list, GFP_ATOMIC); if (!tmp) { mlx4_en_clear_list(dev); return; @@ -1209,7 +1209,7 @@ static void mlx4_en_do_uc_filter(struct mlx4_en_priv *priv, } if (!found) { - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { en_err(priv, "Failed adding MAC %pM on port:%d (out of memory)\n", ha->addr, priv->port); @@ -1317,7 +1317,7 @@ static int mlx4_en_set_rss_steer_rules(struct mlx4_en_priv *priv) if (err) goto tunnel_err; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto alloc_err; @@ -2240,15 +2240,12 @@ static int mlx4_en_copy_priv(struct mlx4_en_priv *dst, if (!dst->tx_ring_num[t]) continue; - dst->tx_ring[t] = kcalloc(MAX_TX_RINGS, - sizeof(struct mlx4_en_tx_ring *), - GFP_KERNEL); + dst->tx_ring[t] = kzalloc_objs(struct mlx4_en_tx_ring *, + MAX_TX_RINGS); if (!dst->tx_ring[t]) goto err_free_tx; - dst->tx_cq[t] = kcalloc(MAX_TX_RINGS, - sizeof(struct mlx4_en_cq *), - GFP_KERNEL); + dst->tx_cq[t] = kzalloc_objs(struct mlx4_en_cq *, MAX_TX_RINGS); if (!dst->tx_cq[t]) { kfree(dst->tx_ring[t]); goto err_free_tx; @@ -2754,7 +2751,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog) if (!mlx4_en_check_xdp_mtu(dev, dev->mtu)) return -EOPNOTSUPP; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -3217,16 +3214,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, if (!priv->tx_ring_num[t]) continue; - priv->tx_ring[t] = kcalloc(MAX_TX_RINGS, - sizeof(struct mlx4_en_tx_ring *), - GFP_KERNEL); + priv->tx_ring[t] = kzalloc_objs(struct mlx4_en_tx_ring *, + MAX_TX_RINGS); if (!priv->tx_ring[t]) { err = -ENOMEM; goto out; } - priv->tx_cq[t] = kcalloc(MAX_TX_RINGS, - sizeof(struct mlx4_en_cq *), - GFP_KERNEL); + priv->tx_cq[t] = kzalloc_objs(struct mlx4_en_cq *, MAX_TX_RINGS); if (!priv->tx_cq[t]) { err = -ENOMEM; goto out; @@ -3525,7 +3519,7 @@ int mlx4_en_reset_config(struct net_device *dev, return -EINVAL; } - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 13666d50b90f..96f97fa0f548 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -1094,7 +1094,7 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv, int qpn, struct mlx4_qp_context *context; int err = 0; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return -ENOMEM; @@ -1208,7 +1208,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv) return 0; } - rss_map->indir_qp = kzalloc(sizeof(*rss_map->indir_qp), GFP_KERNEL); + rss_map->indir_qp = kzalloc_obj(*rss_map->indir_qp); if (!rss_map->indir_qp) { err = -ENOMEM; goto rss_err; diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 9572a45f6143..f1c3da04de7f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -987,8 +987,7 @@ static int mlx4_create_eq(struct mlx4_dev *dev, int nent, */ npages = PAGE_ALIGN(eq->nent * dev->caps.eqe_size) / PAGE_SIZE; - eq->page_list = kmalloc_array(npages, sizeof(*eq->page_list), - GFP_KERNEL); + eq->page_list = kmalloc_objs(*eq->page_list, npages); if (!eq->page_list) goto err_out; @@ -1158,8 +1157,8 @@ int mlx4_alloc_eq_table(struct mlx4_dev *dev) { struct mlx4_priv *priv = mlx4_priv(dev); - priv->eq_table.eq = kcalloc(dev->caps.num_eqs - dev->caps.reserved_eqs, - sizeof(*priv->eq_table.eq), GFP_KERNEL); + priv->eq_table.eq = kzalloc_objs(*priv->eq_table.eq, + dev->caps.num_eqs - dev->caps.reserved_eqs); if (!priv->eq_table.eq) return -ENOMEM; @@ -1177,9 +1176,8 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) int err; int i; - priv->eq_table.uar_map = kcalloc(mlx4_num_eq_uar(dev), - sizeof(*priv->eq_table.uar_map), - GFP_KERNEL); + priv->eq_table.uar_map = kzalloc_objs(*priv->eq_table.uar_map, + mlx4_num_eq_uar(dev)); if (!priv->eq_table.uar_map) { err = -ENOMEM; goto err_out_free; diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 59b8b3c73582..f159eea5ad56 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c @@ -145,8 +145,8 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN), dev->numa_node); if (!icm) { - icm = kmalloc(sizeof(*icm), - gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); + icm = kmalloc_obj(*icm, + gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); if (!icm) return NULL; } @@ -163,9 +163,8 @@ struct mlx4_icm *mlx4_alloc_icm(struct mlx4_dev *dev, int npages, __GFP_NOWARN), dev->numa_node); if (!chunk) { - chunk = kzalloc(sizeof(*chunk), - gfp_mask & ~(__GFP_HIGHMEM | - __GFP_NOWARN)); + chunk = kzalloc_obj(*chunk, + gfp_mask & ~(__GFP_HIGHMEM | __GFP_NOWARN)); if (!chunk) goto fail; } @@ -427,7 +426,7 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, return -EINVAL; num_icm = DIV_ROUND_UP(nobj, obj_per_chunk); - table->icm = kvcalloc(num_icm, sizeof(*table->icm), GFP_KERNEL); + table->icm = kvzalloc_objs(*table->icm, num_icm); if (!table->icm) return -ENOMEM; table->virt = virt; diff --git a/drivers/net/ethernet/mellanox/mlx4/intf.c b/drivers/net/ethernet/mellanox/mlx4/intf.c index a371b970ac1e..82e467c45d23 100644 --- a/drivers/net/ethernet/mellanox/mlx4/intf.c +++ b/drivers/net/ethernet/mellanox/mlx4/intf.c @@ -78,8 +78,8 @@ int mlx4_adev_init(struct mlx4_dev *dev) if (priv->adev_idx < 0) return priv->adev_idx; - priv->adev = kcalloc(ARRAY_SIZE(mlx4_adev_devices), - sizeof(struct mlx4_adev *), GFP_KERNEL); + priv->adev = kzalloc_objs(struct mlx4_adev *, + ARRAY_SIZE(mlx4_adev_devices)); if (!priv->adev) { ida_free(&mlx4_adev_ida, priv->adev_idx); return -ENOMEM; @@ -115,7 +115,7 @@ static struct mlx4_adev *add_adev(struct mlx4_dev *dev, int idx) struct mlx4_adev *madev; int ret; - madev = kzalloc(sizeof(*madev), GFP_KERNEL); + madev = kzalloc_obj(*madev); if (!madev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 4293f8e33f44..e6b7e75894ff 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -867,8 +867,8 @@ static int mlx4_slave_special_qp_cap(struct mlx4_dev *dev) struct mlx4_caps *caps = &dev->caps; int i, err = 0; - func_cap = kzalloc(sizeof(*func_cap), GFP_KERNEL); - caps->spec_qps = kcalloc(caps->num_ports, sizeof(*caps->spec_qps), GFP_KERNEL); + func_cap = kzalloc_obj(*func_cap); + caps->spec_qps = kzalloc_objs(*caps->spec_qps, caps->num_ports); if (!func_cap || !caps->spec_qps) { mlx4_err(dev, "Failed to allocate memory for special qps cap\n"); @@ -911,9 +911,9 @@ static int mlx4_slave_cap(struct mlx4_dev *dev) struct mlx4_func_cap *func_cap; struct mlx4_init_hca_param *hca_param; - hca_param = kzalloc(sizeof(*hca_param), GFP_KERNEL); - func_cap = kzalloc(sizeof(*func_cap), GFP_KERNEL); - dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); + hca_param = kzalloc_obj(*hca_param); + func_cap = kzalloc_obj(*func_cap); + dev_cap = kzalloc_obj(*dev_cap); if (!hca_param || !func_cap || !dev_cap) { mlx4_err(dev, "Failed to allocate memory for slave_cap\n"); err = -ENOMEM; @@ -1548,7 +1548,7 @@ int mlx4_queue_bond_work(struct mlx4_dev *dev, int is_bonded, u8 v2p_p1, { struct mlx4_bond *bond; - bond = kzalloc(sizeof(*bond), GFP_ATOMIC); + bond = kzalloc_obj(*bond, GFP_ATOMIC); if (!bond) return -ENOMEM; @@ -2323,8 +2323,8 @@ static int mlx4_init_hca(struct mlx4_dev *dev) int err; if (!mlx4_is_slave(dev)) { - dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); - init_hca = kzalloc(sizeof(*init_hca), GFP_KERNEL); + dev_cap = kzalloc_obj(*dev_cap); + init_hca = kzalloc_obj(*init_hca); if (!dev_cap || !init_hca) { err = -ENOMEM; @@ -2965,7 +2965,7 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) if (msi_x > 1) nreq = min_t(int, nreq, msi_x); - entries = kcalloc(nreq, sizeof(*entries), GFP_KERNEL); + entries = kzalloc_objs(*entries, nreq); if (!entries) goto no_msi; @@ -3173,8 +3173,7 @@ static int mlx4_init_steering(struct mlx4_dev *dev) int num_entries = dev->caps.num_ports; int i, j; - priv->steer = kcalloc(num_entries, sizeof(struct mlx4_steer), - GFP_KERNEL); + priv->steer = kzalloc_objs(struct mlx4_steer, num_entries); if (!priv->steer) return -ENOMEM; @@ -3279,8 +3278,7 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, MLX4_MAX_NUM_VF); if (reset_flow) { - dev->dev_vfs = kcalloc(total_vfs, sizeof(*dev->dev_vfs), - GFP_KERNEL); + dev->dev_vfs = kzalloc_objs(*dev->dev_vfs, total_vfs); if (!dev->dev_vfs) goto free_mem; return dev_flags; @@ -3295,7 +3293,7 @@ static u64 mlx4_enable_sriov(struct mlx4_dev *dev, struct pci_dev *pdev, } } - dev->dev_vfs = kcalloc(total_vfs, sizeof(*dev->dev_vfs), GFP_KERNEL); + dev->dev_vfs = kzalloc_objs(*dev->dev_vfs, total_vfs); if (NULL == dev->dev_vfs) { mlx4_err(dev, "Failed to allocate memory for VFs\n"); goto disable_sriov; @@ -3494,7 +3492,7 @@ static int mlx4_load_one(struct pci_dev *pdev, int pci_dev_data, if (mlx4_is_master(dev)) { /* when we hit the goto slave_start below, dev_cap already initialized */ if (!dev_cap) { - dev_cap = kzalloc(sizeof(*dev_cap), GFP_KERNEL); + dev_cap = kzalloc_obj(*dev_cap); if (!dev_cap) { err = -ENOMEM; @@ -4034,7 +4032,7 @@ static int mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) priv = devlink_priv(devlink); dev = &priv->dev; - dev->persist = kzalloc(sizeof(*dev->persist), GFP_KERNEL); + dev->persist = kzalloc_obj(*dev->persist); if (!dev->persist) { ret = -ENOMEM; goto err_devlink_free; diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 24d0c7c46878..791ef30053b9 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c @@ -162,7 +162,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, return -EINVAL; s_steer = &mlx4_priv(dev)->steer[port - 1]; - new_entry = kzalloc(sizeof(*new_entry), GFP_KERNEL); + new_entry = kzalloc_obj(*new_entry); if (!new_entry) return -ENOMEM; @@ -175,7 +175,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, */ pqp = get_promisc_qp(dev, port, steer, qpn); if (pqp) { - dqp = kmalloc(sizeof(*dqp), GFP_KERNEL); + dqp = kmalloc_obj(*dqp); if (!dqp) { err = -ENOMEM; goto out_alloc; @@ -274,7 +274,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, } /* add the qp as a duplicate on this index */ - dqp = kmalloc(sizeof(*dqp), GFP_KERNEL); + dqp = kmalloc_obj(*dqp); if (!dqp) return -ENOMEM; dqp->qpn = qpn; @@ -443,7 +443,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, goto out_mutex; } - pqp = kmalloc(sizeof(*pqp), GFP_KERNEL); + pqp = kmalloc_obj(*pqp); if (!pqp) { err = -ENOMEM; goto out_mutex; @@ -479,7 +479,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, /* Entry already exists. * Add to duplicates. */ - dqp = kmalloc(sizeof(*dqp), GFP_KERNEL); + dqp = kmalloc_obj(*dqp); if (!dqp) { err = -ENOMEM; goto out_mailbox; diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c index 6fc156a3918d..6bf850b07d1c 100644 --- a/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/drivers/net/ethernet/mellanox/mlx4/pd.c @@ -189,7 +189,7 @@ int mlx4_bf_alloc(struct mlx4_dev *dev, struct mlx4_bf *bf, int node) } uar = kmalloc_node(sizeof(*uar), GFP_KERNEL, node); if (!uar) { - uar = kmalloc(sizeof(*uar), GFP_KERNEL); + uar = kmalloc_obj(*uar); if (!uar) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index ba361c5fbda3..1cff4aa13284 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c @@ -85,7 +85,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, struct sysinfo si; int i, j; - profile = kcalloc(MLX4_RES_NUM, sizeof(*profile), GFP_KERNEL); + profile = kzalloc_objs(*profile, MLX4_RES_NUM); if (!profile) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 913ed255990f..807a2f091aa6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -564,7 +564,7 @@ static int mlx4_create_zones(struct mlx4_dev *dev, if (NULL == qp_table->zones) return -ENOMEM; - bitmap = kmalloc(sizeof(*bitmap), GFP_KERNEL); + bitmap = kmalloc_obj(*bitmap); if (NULL == bitmap) { err = -ENOMEM; @@ -853,9 +853,8 @@ int mlx4_init_qp_table(struct mlx4_dev *dev) /* In mfunc, calculate proxy and tunnel qp offsets for the PF here, * since the PF does not call mlx4_slave_caps */ - dev->caps.spec_qps = kcalloc(dev->caps.num_ports, - sizeof(*dev->caps.spec_qps), - GFP_KERNEL); + dev->caps.spec_qps = kzalloc_objs(*dev->caps.spec_qps, + dev->caps.num_ports); if (!dev->caps.spec_qps) { err = -ENOMEM; goto err_mem; diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 771b92019af1..83b88bb96f52 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -505,8 +505,7 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) int t; priv->mfunc.master.res_tracker.slave_list = - kcalloc(dev->num_slaves, sizeof(struct slave_list), - GFP_KERNEL); + kzalloc_objs(struct slave_list, dev->num_slaves); if (!priv->mfunc.master.res_tracker.slave_list) return -ENOMEM; @@ -525,21 +524,16 @@ int mlx4_init_resource_tracker(struct mlx4_dev *dev) for (i = 0; i < MLX4_NUM_OF_RESOURCE_TYPE; i++) { struct resource_allocator *res_alloc = &priv->mfunc.master.res_tracker.res_alloc[i]; - res_alloc->quota = kmalloc_array(dev->persist->num_vfs + 1, - sizeof(int), - GFP_KERNEL); - res_alloc->guaranteed = kmalloc_array(dev->persist->num_vfs + 1, - sizeof(int), - GFP_KERNEL); + res_alloc->quota = kmalloc_objs(int, dev->persist->num_vfs + 1); + res_alloc->guaranteed = kmalloc_objs(int, + dev->persist->num_vfs + 1); if (i == RES_MAC || i == RES_VLAN) res_alloc->allocated = - kcalloc(MLX4_MAX_PORTS * - (dev->persist->num_vfs + 1), - sizeof(int), GFP_KERNEL); + kzalloc_objs(int, + MLX4_MAX_PORTS * (dev->persist->num_vfs + 1)); else res_alloc->allocated = - kcalloc(dev->persist->num_vfs + 1, - sizeof(int), GFP_KERNEL); + kzalloc_objs(int, dev->persist->num_vfs + 1); /* Reduce the sink counter */ if (i == RES_COUNTER) res_alloc->res_free = dev->caps.max_counters - 1; @@ -1051,7 +1045,7 @@ static struct res_common *alloc_qp_tr(int id) { struct res_qp *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1069,7 +1063,7 @@ static struct res_common *alloc_mtt_tr(int id, int order) { struct res_mtt *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1085,7 +1079,7 @@ static struct res_common *alloc_mpt_tr(int id, int key) { struct res_mpt *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1100,7 +1094,7 @@ static struct res_common *alloc_eq_tr(int id) { struct res_eq *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1114,7 +1108,7 @@ static struct res_common *alloc_cq_tr(int id) { struct res_cq *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1129,7 +1123,7 @@ static struct res_common *alloc_srq_tr(int id) { struct res_srq *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1144,7 +1138,7 @@ static struct res_common *alloc_counter_tr(int id, int port) { struct res_counter *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1159,7 +1153,7 @@ static struct res_common *alloc_xrcdn_tr(int id) { struct res_xrcdn *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1173,7 +1167,7 @@ static struct res_common *alloc_fs_rule_tr(u64 id, int qpn) { struct res_fs_rule *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -1240,8 +1234,7 @@ int mlx4_calc_vf_counters(struct mlx4_dev *dev, int slave, int port, memset(data, 0, sizeof(*data)); - counters_arr = kmalloc_array(dev->caps.max_counters, - sizeof(*counters_arr), GFP_KERNEL); + counters_arr = kmalloc_objs(*counters_arr, dev->caps.max_counters); if (!counters_arr) return -ENOMEM; @@ -1285,7 +1278,7 @@ static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count, struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; struct rb_root *root = &tracker->res_tree[type]; - res_arr = kcalloc(count, sizeof(*res_arr), GFP_KERNEL); + res_arr = kzalloc_objs(*res_arr, count); if (!res_arr) return -ENOMEM; @@ -2038,7 +2031,7 @@ static int mac_add_to_slave(struct mlx4_dev *dev, int slave, u64 mac, int port, if (mlx4_grant_resource(dev, slave, RES_MAC, 1, port)) return -EINVAL; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) { mlx4_release_resource(dev, slave, RES_MAC, 1, port); return -ENOMEM; @@ -2145,7 +2138,7 @@ static int vlan_add_to_slave(struct mlx4_dev *dev, int slave, u16 vlan, if (mlx4_grant_resource(dev, slave, RES_VLAN, 1, port)) return -EINVAL; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) { mlx4_release_resource(dev, slave, RES_VLAN, 1, port); return -ENOMEM; @@ -4032,7 +4025,7 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, struct res_gid *res; int err; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return -ENOMEM; @@ -5187,8 +5180,7 @@ static void rem_slave_counters(struct mlx4_dev *dev, int slave) mlx4_warn(dev, "rem_slave_counters: Could not move all counters - too busy for slave %d\n", slave); - counters_arr = kmalloc_array(dev->caps.max_counters, - sizeof(*counters_arr), GFP_KERNEL); + counters_arr = kmalloc_objs(*counters_arr, dev->caps.max_counters); if (!counters_arr) return; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c index 6aca004e88cd..202feab1558a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/alloc.c @@ -79,8 +79,7 @@ int mlx5_frag_buf_alloc_node(struct mlx5_core_dev *dev, int size, buf->size = size; buf->npages = DIV_ROUND_UP(size, PAGE_SIZE); buf->page_shift = PAGE_SHIFT; - buf->frags = kcalloc(buf->npages, sizeof(struct mlx5_buf_list), - GFP_KERNEL); + buf->frags = kzalloc_objs(struct mlx5_buf_list, buf->npages); if (!buf->frags) goto err_out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c index 5b08e5ffe0e2..6c99c7f36163 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c @@ -123,7 +123,7 @@ cmd_alloc_ent(struct mlx5_cmd *cmd, struct mlx5_cmd_msg *in, gfp_t alloc_flags = cbk ? GFP_ATOMIC : GFP_KERNEL; struct mlx5_cmd_work_ent *ent; - ent = kzalloc(sizeof(*ent), alloc_flags); + ent = kzalloc_obj(*ent, alloc_flags); if (!ent) return ERR_PTR(-ENOMEM); @@ -1436,7 +1436,7 @@ static struct mlx5_cmd_mailbox *alloc_cmd_box(struct mlx5_core_dev *dev, { struct mlx5_cmd_mailbox *mailbox; - mailbox = kmalloc(sizeof(*mailbox), flags); + mailbox = kmalloc_obj(*mailbox, flags); if (!mailbox) return ERR_PTR(-ENOMEM); @@ -1470,7 +1470,7 @@ static struct mlx5_cmd_msg *mlx5_alloc_cmd_msg(struct mlx5_core_dev *dev, int n; int i; - msg = kzalloc(sizeof(*msg), flags); + msg = kzalloc_obj(*msg, flags); if (!msg) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c index 1301c56e20d6..8fe263190d38 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c @@ -201,7 +201,7 @@ static const struct file_operations slots_fops = { static struct mlx5_cmd_stats * mlx5_cmdif_alloc_stats(struct xarray *stats_xa, int opcode) { - struct mlx5_cmd_stats *stats = kzalloc(sizeof(*stats), GFP_KERNEL); + struct mlx5_cmd_stats *stats = kzalloc_obj(*stats); int err; if (!stats) @@ -509,7 +509,7 @@ static int add_res_tree(struct mlx5_core_dev *dev, enum dbg_rsc_type type, char resn[32]; int i; - d = kzalloc(struct_size(d, fields, nfile), GFP_KERNEL); + d = kzalloc_flex(*d, fields, nfile); if (!d) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/dev.c index 781e39b5aa1d..df2e3ad01819 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dev.c @@ -277,8 +277,8 @@ int mlx5_adev_init(struct mlx5_core_dev *dev) { struct mlx5_priv *priv = &dev->priv; - priv->adev = kcalloc(ARRAY_SIZE(mlx5_adev_devices), - sizeof(struct mlx5_adev *), GFP_KERNEL); + priv->adev = kzalloc_objs(struct mlx5_adev *, + ARRAY_SIZE(mlx5_adev_devices)); if (!priv->adev) return -ENOMEM; @@ -310,7 +310,7 @@ static struct mlx5_adev *add_adev(struct mlx5_core_dev *dev, int idx) struct mlx5_adev *madev; int ret; - madev = kzalloc(sizeof(*madev), GFP_KERNEL); + madev = kzalloc_obj(*madev); if (!madev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c index ea77fbd98396..6698ac55a4bf 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c @@ -294,7 +294,7 @@ static int mlx5_devlink_trap_init(struct devlink *devlink, const struct devlink_ struct mlx5_core_dev *dev = devlink_priv(devlink); struct mlx5_devlink_trap *dl_trap; - dl_trap = kzalloc(sizeof(*dl_trap), GFP_KERNEL); + dl_trap = kzalloc_obj(*dl_trap); if (!dl_trap) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c index 6b4ec457ce22..adcc73e2a5b3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/fw_tracer.c @@ -412,7 +412,7 @@ static struct tracer_string_format *mlx5_tracer_message_insert(struct mlx5_fw_tr &tracer->hash[mlx5_tracer_message_hash(tracer_event->string_event.tmsn)]; struct tracer_string_format *cur_string; - cur_string = kzalloc(sizeof(*cur_string), GFP_KERNEL); + cur_string = kzalloc_obj(*cur_string); if (!cur_string) return NULL; @@ -1023,7 +1023,7 @@ struct mlx5_fw_tracer *mlx5_fw_tracer_create(struct mlx5_core_dev *dev) return NULL; } - tracer = kvzalloc(sizeof(*tracer), GFP_KERNEL); + tracer = kvzalloc_obj(*tracer); if (!tracer) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c index c5b560a8b026..e770088de129 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/diag/rsc_dump.c @@ -137,7 +137,7 @@ struct mlx5_rsc_dump_cmd *mlx5_rsc_dump_cmd_create(struct mlx5_core_dev *dev, if (!sgmt_type && key->rsc != MLX5_SGMT_TYPE_MENU) return ERR_PTR(-EOPNOTSUPP); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { mlx5_core_err(dev, "Resource dump: Failed to allocate command\n"); return ERR_PTR(-ENOMEM); @@ -255,7 +255,7 @@ struct mlx5_rsc_dump *mlx5_rsc_dump_create(struct mlx5_core_dev *dev) mlx5_core_dbg(dev, "Resource dump: capability not present\n"); return NULL; } - rsc_dump = kzalloc(sizeof(*rsc_dump), GFP_KERNEL); + rsc_dump = kzalloc_obj(*rsc_dump); if (!rsc_dump) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c index 3981dd81d4c1..bce72e8d1bc3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/dpll.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/dpll.c @@ -433,7 +433,7 @@ static int mlx5_dpll_probe(struct auxiliary_device *adev, if (err) return err; - mdpll = kzalloc(sizeof(*mdpll), GFP_KERNEL); + mdpll = kzalloc_obj(*mdpll); if (!mdpll) return -ENOMEM; mdpll->mdev = mdev; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h index a7de3a3efc49..ea2cd1f5d1d0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h @@ -180,7 +180,8 @@ static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size) } /* Use this function to get max num channels (rxqs/txqs) only to create netdev */ -static inline int mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) +static inline unsigned int +mlx5e_get_max_num_channels(struct mlx5_core_dev *mdev) { return is_kdump_kernel() ? MLX5E_MIN_NUM_CHANNELS : @@ -1103,6 +1104,7 @@ int mlx5e_open_locked(struct net_device *netdev); int mlx5e_close_locked(struct net_device *netdev); void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c); +void mlx5e_trigger_napi_async_icosq(struct mlx5e_channel *c); void mlx5e_trigger_napi_sched(struct napi_struct *napi); int mlx5e_open_channels(struct mlx5e_priv *priv, diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c b/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c index 671adbad0a40..884f1dff0952 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs_tt_redirect.c @@ -90,7 +90,7 @@ mlx5e_fs_tt_redirect_udp_add_rule(struct mlx5e_flow_steering *fs, if (type == FS_UDP_NUM_TYPES) return ERR_PTR(-EINVAL); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -150,7 +150,7 @@ static int fs_udp_create_groups(struct mlx5e_flow_table *ft, enum fs_udp_type ty int err; u8 *mc; - ft->g = kcalloc(MLX5E_FS_UDP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_FS_UDP_NUM_GROUPS); in = kvzalloc(inlen, GFP_KERNEL); if (!in || !ft->g) { kfree(ft->g); @@ -325,7 +325,7 @@ int mlx5e_fs_tt_redirect_udp_create(struct mlx5e_flow_steering *fs) return 0; } - udp = kzalloc(sizeof(*udp), GFP_KERNEL); + udp = kzalloc_obj(*udp); if (!udp) return -ENOMEM; mlx5e_fs_set_udp(fs, udp); @@ -372,7 +372,7 @@ mlx5e_fs_tt_redirect_any_add_rule(struct mlx5e_flow_steering *fs, struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -432,7 +432,7 @@ static int fs_any_create_groups(struct mlx5e_flow_table *ft) int err; u8 *mc; - ft->g = kcalloc(MLX5E_FS_UDP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_FS_UDP_NUM_GROUPS); in = kvzalloc(inlen, GFP_KERNEL); if (!in || !ft->g) { kfree(ft->g); @@ -589,7 +589,7 @@ int mlx5e_fs_tt_redirect_any_create(struct mlx5e_flow_steering *fs) return 0; } - fs_any = kzalloc(sizeof(*fs_any), GFP_KERNEL); + fs_any = kzalloc_obj(*fs_any); if (!fs_any) return -ENOMEM; mlx5e_fs_set_any(fs, fs_any); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c b/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c index 09d441ecb9f6..ac27f6260f99 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/htb.c @@ -72,7 +72,7 @@ mlx5e_htb_node_create_leaf(struct mlx5e_htb *htb, u16 classid, u16 qid, { struct mlx5e_qos_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return ERR_PTR(-ENOMEM); @@ -93,7 +93,7 @@ static struct mlx5e_qos_node *mlx5e_htb_node_create_root(struct mlx5e_htb *htb) { struct mlx5e_qos_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return ERR_PTR(-ENOMEM); @@ -694,7 +694,7 @@ mlx5e_htb_node_modify(struct mlx5e_htb *htb, u16 classid, u64 rate, u64 ceil, struct mlx5e_htb *mlx5e_htb_alloc(void) { - return kvzalloc(sizeof(struct mlx5e_htb), GFP_KERNEL); + return kvzalloc_obj(struct mlx5e_htb); } void mlx5e_htb_free(struct mlx5e_htb *htb) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/mapping.c b/drivers/net/ethernet/mellanox/mlx5/core/en/mapping.c index 1de18c7e96ec..4bab696b7250 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/mapping.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/mapping.c @@ -198,7 +198,7 @@ mapping_create(size_t data_size, u32 max_id, bool delayed_removal) { struct mapping_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c index 424f8a2728a3..1b76647f3194 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c @@ -457,22 +457,8 @@ static void mlx5e_ptpsq_unhealthy_work(struct work_struct *work) { struct mlx5e_ptpsq *ptpsq = container_of(work, struct mlx5e_ptpsq, report_unhealthy_work); - struct mlx5e_txqsq *sq = &ptpsq->txqsq; - - /* Recovering the PTP SQ means re-enabling NAPI, which requires the - * netdev instance lock. However, SQ closing has to wait for this work - * task to finish while also holding the same lock. So either get the - * lock or find that the SQ is no longer enabled and thus this work is - * not relevant anymore. - */ - while (!netdev_trylock(sq->netdev)) { - if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) - return; - msleep(20); - } mlx5e_reporter_tx_ptpsq_unhealthy(ptpsq); - netdev_unlock(sq->netdev); } static int mlx5e_ptp_open_txqsq(struct mlx5e_ptp *c, u32 tisn, @@ -897,7 +883,7 @@ int mlx5e_ptp_open(struct mlx5e_priv *priv, struct mlx5e_params *params, c = kvzalloc_node(sizeof(*c), GFP_KERNEL, dev_to_node(mlx5_core_dma_dev(mdev))); - cparams = kvzalloc(sizeof(*cparams), GFP_KERNEL); + cparams = kvzalloc_obj(*cparams); if (!c || !cparams) { err = -ENOMEM; goto err_free; @@ -1002,7 +988,7 @@ int mlx5e_ptp_alloc_rx_fs(struct mlx5e_flow_steering *fs, if (!mlx5e_profile_feature_cap(profile, PTP_RX)) return 0; - ptp_fs = kzalloc(sizeof(*ptp_fs), GFP_KERNEL); + ptp_fs = kzalloc_obj(*ptp_fs); if (!ptp_fs) return -ENOMEM; mlx5e_fs_set_ptp(fs, ptp_fs); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c index 4e461cb03b83..ac4979087e0d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/qos.c @@ -87,8 +87,8 @@ int mlx5e_open_qos_sq(struct mlx5e_priv *priv, struct mlx5e_channels *chs, if (!priv->htb_qos_sq_stats) { struct mlx5e_sq_stats **stats_list; - stats_list = kvcalloc(mlx5e_qos_max_leaf_nodes(priv->mdev), - sizeof(*stats_list), GFP_KERNEL); + stats_list = kvzalloc_objs(*stats_list, + mlx5e_qos_max_leaf_nodes(priv->mdev)); if (!stats_list) return -ENOMEM; @@ -98,7 +98,7 @@ int mlx5e_open_qos_sq(struct mlx5e_priv *priv, struct mlx5e_channels *chs, if (!priv->htb_qos_sq_stats[node_qid]) { struct mlx5e_sq_stats *stats; - stats = kzalloc(sizeof(*stats), GFP_KERNEL); + stats = kzalloc_obj(*stats); if (!stats) return -ENOMEM; @@ -114,7 +114,7 @@ int mlx5e_open_qos_sq(struct mlx5e_priv *priv, struct mlx5e_channels *chs, c = chs->c[ix]; qos_sqs = mlx5e_state_dereference(priv, c->qos_sqs); - sq = kzalloc(sizeof(*sq), GFP_KERNEL); + sq = kzalloc_obj(*sq); if (!sq) return -ENOMEM; @@ -276,7 +276,7 @@ int mlx5e_qos_alloc_queues(struct mlx5e_priv *priv, struct mlx5e_channels *chs) for (i = 0; i < chs->num; i++) { struct mlx5e_txqsq **sqs; - sqs = kvcalloc(qos_sqs_size, sizeof(struct mlx5e_txqsq *), GFP_KERNEL); + sqs = kvzalloc_objs(struct mlx5e_txqsq *, qos_sqs_size); if (!sqs) goto err_free; @@ -460,7 +460,7 @@ struct mlx5e_mqprio_rl { struct mlx5e_mqprio_rl *mlx5e_mqprio_rl_alloc(void) { - return kvzalloc(sizeof(struct mlx5e_mqprio_rl), GFP_KERNEL); + return kvzalloc_obj(struct mlx5e_mqprio_rl); } void mlx5e_mqprio_rl_free(struct mlx5e_mqprio_rl *rl) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c index 016a61c52c45..9799bdd7d8d6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bond.c @@ -92,7 +92,7 @@ int mlx5e_rep_bond_enslave(struct mlx5_eswitch *esw, struct net_device *netdev, mdata = mlx5e_lookup_rep_bond_metadata(&rpriv->uplink_priv, lag_dev); if (!mdata) { /* First netdev becomes slave, no metadata presents the lag_dev. Create one */ - mdata = kzalloc(sizeof(*mdata), GFP_KERNEL); + mdata = kzalloc_obj(*mdata); if (!mdata) return -ENOMEM; @@ -110,7 +110,7 @@ int mlx5e_rep_bond_enslave(struct mlx5_eswitch *esw, struct net_device *netdev, mdata->metadata_reg_c_0); } - s_entry = kzalloc(sizeof(*s_entry), GFP_KERNEL); + s_entry = kzalloc_obj(*s_entry); if (!s_entry) { err = -ENOMEM; goto entry_alloc_err; @@ -315,7 +315,7 @@ int mlx5e_rep_bond_init(struct mlx5e_rep_priv *rpriv) if (!mlx5_esw_acl_egress_fwd2vport_supported(priv->mdev->priv.eswitch)) goto out; - uplink_priv->bond = kvzalloc(sizeof(*uplink_priv->bond), GFP_KERNEL); + uplink_priv->bond = kvzalloc_obj(*uplink_priv->bond); if (!uplink_priv->bond) { ret = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c index 87a2ad69526d..baac38bece14 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/bridge.c @@ -394,7 +394,7 @@ mlx5_esw_bridge_init_switchdev_fdb_work(struct net_device *dev, bool add, struct mlx5_bridge_switchdev_fdb_work *work; u8 *addr; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c index 2e9bee4e5209..d220b045b331 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/neigh.c @@ -173,7 +173,7 @@ static struct neigh_update_work *mlx5e_alloc_neigh_update_work(struct mlx5e_priv struct mlx5e_neigh_hash_entry *nhe; struct mlx5e_neigh m_neigh = {}; - update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC); + update_work = kzalloc_obj(*update_work, GFP_ATOMIC); if (WARN_ON(!update_work)) return NULL; @@ -376,7 +376,7 @@ int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv, { int err; - *nhe = kzalloc(sizeof(**nhe), GFP_KERNEL); + *nhe = kzalloc_obj(**nhe); if (!*nhe) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c index a55452c69f06..e1ebc9b2d061 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c @@ -503,7 +503,7 @@ mlx5e_rep_indr_setup_block(struct net_device *netdev, struct Qdisc *sch, if (indr_priv) return -EEXIST; - indr_priv = kmalloc(sizeof(*indr_priv), GFP_KERNEL); + indr_priv = kmalloc_obj(*indr_priv); if (!indr_priv) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c index 0686fbdd5a05..6efb626b5506 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (c) 2019 Mellanox Technologies. +#include + #include "health.h" #include "params.h" #include "txrx.h" @@ -177,6 +179,16 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) rq = ctx; priv = rq->priv; + /* Acquire netdev instance lock to synchronize with channel close and + * reopen flows. Either successfully obtain the lock, or detect that + * channels are closing for another reason, making this work no longer + * necessary. + */ + while (!netdev_trylock(rq->netdev)) { + if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) + return 0; + msleep(20); + } mutex_lock(&priv->state_lock); eq = rq->cq.mcq.eq; @@ -186,6 +198,7 @@ static int mlx5e_rx_reporter_timeout_recover(void *ctx) clear_bit(MLX5E_SQ_STATE_ENABLED, &rq->icosq->state); mutex_unlock(&priv->state_lock); + netdev_unlock(rq->netdev); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c index 4adc1adf9897..afdeb1b3d425 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* Copyright (c) 2019 Mellanox Technologies. */ +#include + #include "health.h" #include "en/ptp.h" #include "en/devlink.h" @@ -45,7 +47,6 @@ static void mlx5e_reset_txqsq_cc_pc(struct mlx5e_txqsq *sq) "SQ 0x%x: cc (0x%x) != pc (0x%x)\n", sq->sqn, sq->cc, sq->pc); sq->cc = 0; - sq->dma_fifo_cc = 0; sq->pc = 0; } @@ -79,6 +80,18 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) if (!test_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state)) return 0; + /* Recovering queues means re-enabling NAPI, which requires the netdev + * instance lock. However, SQ closing flows have to wait for work tasks + * to finish while also holding the netdev instance lock. So either get + * the lock or find that the SQ is no longer enabled and thus this work + * is not relevant anymore. + */ + while (!netdev_trylock(dev)) { + if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) + return 0; + msleep(20); + } + err = mlx5_core_query_sq_state(mdev, sq->sqn, &state); if (err) { netdev_err(dev, "Failed to query SQ 0x%x state. err = %d\n", @@ -114,9 +127,11 @@ static int mlx5e_tx_reporter_err_cqe_recover(void *ctx) else mlx5e_trigger_napi_sched(sq->cq.napi); + netdev_unlock(dev); return 0; out: clear_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state); + netdev_unlock(dev); return err; } @@ -137,10 +152,24 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) sq = to_ctx->sq; eq = sq->cq.mcq.eq; priv = sq->priv; + + /* Recovering the TX queues implies re-enabling NAPI, which requires + * the netdev instance lock. + * However, channel closing flows have to wait for this work to finish + * while holding the same lock. So either get the lock or find that + * channels are being closed for other reason and this work is not + * relevant anymore. + */ + while (!netdev_trylock(sq->netdev)) { + if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) + return 0; + msleep(20); + } + err = mlx5e_health_channel_eq_recover(sq->netdev, eq, sq->cq.ch_stats); if (!err) { to_ctx->status = 0; /* this sq recovered */ - return err; + goto out; } mutex_lock(&priv->state_lock); @@ -148,7 +177,7 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) mutex_unlock(&priv->state_lock); if (!err) { to_ctx->status = 1; /* all channels recovered */ - return err; + goto out; } to_ctx->status = err; @@ -156,7 +185,8 @@ static int mlx5e_tx_reporter_timeout_recover(void *ctx) netdev_err(priv->netdev, "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n", err); - +out: + netdev_unlock(sq->netdev); return err; } @@ -173,10 +203,22 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) return 0; priv = ptpsq->txqsq.priv; + netdev = priv->netdev; + + /* Recovering the PTP SQ means re-enabling NAPI, which requires the + * netdev instance lock. However, SQ closing has to wait for this work + * task to finish while also holding the same lock. So either get the + * lock or find that the SQ is no longer enabled and thus this work is + * not relevant anymore. + */ + while (!netdev_trylock(netdev)) { + if (!test_bit(MLX5E_SQ_STATE_ENABLED, &ptpsq->txqsq.state)) + return 0; + msleep(20); + } mutex_lock(&priv->state_lock); chs = &priv->channels; - netdev = priv->netdev; carrier_ok = netif_carrier_ok(netdev); netif_carrier_off(netdev); @@ -193,6 +235,7 @@ static int mlx5e_tx_reporter_ptpsq_unhealthy_recover(void *ctx) netif_carrier_on(netdev); mutex_unlock(&priv->state_lock); + netdev_unlock(netdev); return err; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c index 88b0e1050d1a..a2ec67a122d9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rss.c @@ -93,7 +93,7 @@ void mlx5e_rss_params_indir_modify_actual_size(struct mlx5e_rss *rss, u32 num_ch int mlx5e_rss_params_indir_init(struct mlx5e_rss_params_indir *indir, u32 actual_table_size, u32 max_table_size) { - indir->table = kvmalloc_array(max_table_size, sizeof(*indir->table), GFP_KERNEL); + indir->table = kvmalloc_objs(*indir->table, max_table_size); if (!indir->table) return -ENOMEM; @@ -134,7 +134,7 @@ static struct mlx5e_rss *mlx5e_rss_init_copy(const struct mlx5e_rss *from) struct mlx5e_rss *rss; int err; - rss = kvzalloc(sizeof(*rss), GFP_KERNEL); + rss = kvzalloc_obj(*rss); if (!rss) return ERR_PTR(-ENOMEM); @@ -216,7 +216,7 @@ mlx5e_rss_create_tir(struct mlx5e_rss *rss, enum mlx5_traffic_types tt, if (*tir_p) return -EINVAL; - tir = kvzalloc(sizeof(*tir), GFP_KERNEL); + tir = kvzalloc_obj(*tir); if (!tir) return -ENOMEM; @@ -372,7 +372,7 @@ mlx5e_rss_init(struct mlx5_core_dev *mdev, struct mlx5e_rss *rss; int err; - rss = kvzalloc(sizeof(*rss), GFP_KERNEL); + rss = kvzalloc_obj(*rss); if (!rss) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c index 55c117b7d8c4..92974b11ec75 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/rx_res.c @@ -325,7 +325,7 @@ static struct mlx5e_rx_res *mlx5e_rx_res_alloc(struct mlx5_core_dev *mdev, unsig { struct mlx5e_rx_res *rx_res; - rx_res = kvzalloc(sizeof(*rx_res), GFP_KERNEL); + rx_res = kvzalloc_obj(*rx_res); if (!rx_res) return NULL; @@ -359,7 +359,7 @@ static int mlx5e_rx_res_channels_init(struct mlx5e_rx_res *res) if (!builder) return -ENOMEM; - res->channels = kvcalloc(res->max_nch, sizeof(*res->channels), GFP_KERNEL); + res->channels = kvzalloc_objs(*res->channels, res->max_nch); if (!res->channels) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c b/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c index f66bbc846464..8318a26bc263 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/selq.c @@ -30,11 +30,11 @@ int mlx5e_selq_init(struct mlx5e_selq *selq, struct mutex *state_lock) selq->state_lock = state_lock; - selq->standby = kvzalloc(sizeof(*selq->standby), GFP_KERNEL); + selq->standby = kvzalloc_obj(*selq->standby); if (!selq->standby) return -ENOMEM; - init_params = kvzalloc(sizeof(*selq->active), GFP_KERNEL); + init_params = kvzalloc_obj(*selq->active); if (!init_params) { kvfree(selq->standby); selq->standby = NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c index 7aa926e542d3..4b1c6c99c724 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/act_stats.c @@ -36,7 +36,7 @@ mlx5e_tc_act_stats_create(void) struct mlx5e_tc_act_stats_handle *handle; int err; - handle = kvzalloc(sizeof(*handle), GFP_KERNEL); + handle = kvzalloc_obj(*handle); if (!handle) return ERR_PTR(-ENOMEM); @@ -67,7 +67,7 @@ mlx5e_tc_act_stats_add(struct mlx5e_tc_act_stats_handle *handle, u64 lastused; int err = 0; - act_stats = kvzalloc(sizeof(*act_stats), GFP_KERNEL); + act_stats = kvzalloc_obj(*act_stats); if (!act_stats) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c index 64a82aafaaca..52f96010f0d7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_dmfs.c @@ -34,7 +34,7 @@ mlx5_ct_fs_dmfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec, struct mlx5_ct_fs_dmfs_rule *dmfs_rule; int err; - dmfs_rule = kzalloc(sizeof(*dmfs_rule), GFP_KERNEL); + dmfs_rule = kzalloc_obj(*dmfs_rule); if (!dmfs_rule) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c index d3db6146fcad..822c79f2de72 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_hmfs.c @@ -203,7 +203,7 @@ mlx5_ct_fs_hmfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec, if (!mlx5e_tc_ct_is_valid_flow_rule(fs->netdev, flow_rule)) return ERR_PTR(-EOPNOTSUPP); - hmfs_rule = kzalloc(sizeof(*hmfs_rule), GFP_KERNEL); + hmfs_rule = kzalloc_obj(*hmfs_rule); if (!hmfs_rule) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c index 4d6924b644c9..5a2c24ef517b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/ct_fs_smfs.c @@ -92,7 +92,7 @@ mlx5_ct_fs_smfs_matcher_create(struct mlx5_ct_fs *fs, struct mlx5dr_table *tbl, struct mlx5dr_matcher *dr_matcher; struct mlx5_flow_spec *spec; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -234,7 +234,7 @@ mlx5_ct_fs_smfs_ct_rule_add(struct mlx5_ct_fs *fs, struct mlx5_flow_spec *spec, if (!mlx5e_tc_ct_is_valid_flow_rule(fs->netdev, flow_rule)) return ERR_PTR(-EOPNOTSUPP); - smfs_rule = kzalloc(sizeof(*smfs_rule), GFP_KERNEL); + smfs_rule = kzalloc_obj(*smfs_rule); if (!smfs_rule) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c index 991f47050643..7f0b7c5560fb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/int_port.c @@ -69,7 +69,7 @@ mlx5e_int_port_create_rx_rule(struct mlx5_eswitch *esw, struct mlx5_flow_spec *spec; void *misc; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -167,7 +167,7 @@ mlx5e_int_port_add(struct mlx5e_tc_int_port_priv *priv, return ERR_PTR(-ENOSPC); } - int_port = kzalloc(sizeof(*int_port), GFP_KERNEL); + int_port = kzalloc_obj(*int_port); if (!int_port) return ERR_PTR(-ENOMEM); @@ -313,7 +313,7 @@ mlx5e_tc_int_port_init(struct mlx5e_priv *priv) if (!mlx5e_tc_int_port_supported(esw)) return NULL; - int_port_priv = kzalloc(sizeof(*int_port_priv), GFP_KERNEL); + int_port_priv = kzalloc_obj(*int_port_priv); if (!int_port_priv) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c index 7819fb297280..a62b09dddc01 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/meter.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB // Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +#include #include #include "lib/aso.h" #include "en/tc/post_act.h" @@ -115,7 +116,6 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev, struct mlx5e_flow_meters *flow_meters; u8 cir_man, cir_exp, cbs_man, cbs_exp; struct mlx5_aso_wqe *aso_wqe; - unsigned long expires; struct mlx5_aso *aso; u64 rate, burst; u8 ds_cnt; @@ -187,12 +187,8 @@ mlx5e_tc_meter_modify(struct mlx5_core_dev *mdev, mlx5_aso_post_wqe(aso, true, &aso_wqe->ctrl); /* With newer FW, the wait for the first ASO WQE is more than 2us, put the wait 10ms. */ - expires = jiffies + msecs_to_jiffies(10); - do { - err = mlx5_aso_poll_cq(aso, true); - if (err) - usleep_range(2, 10); - } while (err && time_is_after_jiffies(expires)); + read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, + false, aso, true); mutex_unlock(&flow_meters->aso_lock); return err; @@ -251,7 +247,7 @@ __mlx5e_flow_meter_alloc(struct mlx5e_flow_meters *flow_meters, bool alloc_aso) int err, pos, total; u32 id; - meter = kzalloc(sizeof(*meter), GFP_KERNEL); + meter = kzalloc_obj(*meter); if (!meter) return ERR_PTR(-ENOMEM); @@ -530,7 +526,7 @@ mlx5e_flow_meters_init(struct mlx5e_priv *priv, return ERR_PTR(-EOPNOTSUPP); } - flow_meters = kzalloc(sizeof(*flow_meters), GFP_KERNEL); + flow_meters = kzalloc_obj(*flow_meters); if (!flow_meters) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c index b500cc2c9689..18b6c1360552 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_act.c @@ -42,7 +42,7 @@ mlx5e_tc_post_act_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains, goto err_check; } - post_act = kzalloc(sizeof(*post_act), GFP_KERNEL); + post_act = kzalloc_obj(*post_act); if (!post_act) { err = -ENOMEM; goto err_check; @@ -86,7 +86,7 @@ mlx5e_tc_post_act_offload(struct mlx5e_post_act *post_act, if (IS_ERR(post_act)) return PTR_ERR(post_act); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -117,7 +117,7 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *po if (IS_ERR(post_act)) return ERR_CAST(post_act); - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.c index 50b60fd00946..d03376d7bb31 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/post_meter.c @@ -156,7 +156,7 @@ mlx5e_post_meter_rate_rules_create(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -402,7 +402,7 @@ mlx5e_post_meter_init(struct mlx5e_priv *priv, struct mlx5e_post_meter_priv *post_meter; int err; - post_meter = kzalloc(sizeof(*post_meter), GFP_KERNEL); + post_meter = kzalloc_obj(*post_meter); if (!post_meter) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c index 5db239cae814..89490f687a9c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c @@ -183,7 +183,7 @@ sampler_get(struct mlx5e_tc_psample *tc_psample, u32 sample_ratio, u32 default_t sample_ratio, default_table_id)) goto add_ref; - sampler = kzalloc(sizeof(*sampler), GFP_KERNEL); + sampler = kzalloc_obj(*sampler); if (!sampler) { err = -ENOMEM; goto err_alloc; @@ -273,7 +273,7 @@ sample_restore_get(struct mlx5e_tc_psample *tc_psample, u32 obj_id, if (restore->obj_id == obj_id) goto add_ref; - restore = kzalloc(sizeof(*restore), GFP_KERNEL); + restore = kzalloc_obj(*restore); if (!restore) { err = -ENOMEM; goto err_alloc; @@ -485,7 +485,7 @@ mlx5e_tc_sample_offload(struct mlx5e_tc_psample *tc_psample, if (IS_ERR_OR_NULL(tc_psample)) return ERR_PTR(-EOPNOTSUPP); - sample_flow = kzalloc(sizeof(*sample_flow), GFP_KERNEL); + sample_flow = kzalloc_obj(*sample_flow); if (!sample_flow) return ERR_PTR(-ENOMEM); sample_attr = &attr->sample_attr; @@ -619,7 +619,7 @@ mlx5e_tc_sample_init(struct mlx5_eswitch *esw, struct mlx5e_post_act *post_act) struct mlx5e_tc_psample *tc_psample; int err; - tc_psample = kzalloc(sizeof(*tc_psample), GFP_KERNEL); + tc_psample = kzalloc_obj(*tc_psample); if (!tc_psample) return ERR_PTR(-ENOMEM); if (IS_ERR_OR_NULL(post_act)) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c index fc0e57403d25..6c87a1c7db09 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c @@ -812,7 +812,7 @@ mlx5_tc_ct_entry_add_rule(struct mlx5_tc_ct_priv *ct_priv, zone_rule->nat = nat; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -887,7 +887,7 @@ mlx5_tc_ct_entry_update_rule(struct mlx5_tc_ct_priv *ct_priv, struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1021,7 +1021,7 @@ mlx5_tc_ct_counter_create(struct mlx5_tc_ct_priv *ct_priv) struct mlx5_ct_counter *counter; int ret; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc_obj(*counter); if (!counter) return ERR_PTR(-ENOMEM); @@ -1219,7 +1219,7 @@ mlx5_tc_ct_block_flow_offload_add(struct mlx5_ct_ft *ft, } spin_unlock_bh(&ct_priv->ht_lock); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1620,7 +1620,7 @@ static int tc_ct_pre_ct_add_rules(struct mlx5_ct_ft *ct_ft, u16 zone; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1856,7 +1856,7 @@ mlx5_tc_ct_add_ft_cb(struct mlx5_tc_ct_priv *ct_priv, u16 zone, return ft; } - ft = kzalloc(sizeof(*ft), GFP_KERNEL); + ft = kzalloc_obj(*ft); if (!ft) return ERR_PTR(-ENOMEM); @@ -2298,7 +2298,7 @@ mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains, if (err) goto err_support; - ct_priv = kzalloc(sizeof(*ct_priv), GFP_KERNEL); + ct_priv = kzalloc_obj(*ct_priv); if (!ct_priv) goto err_alloc; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c index 0735d10f2bac..bfd401bee9e8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c @@ -87,7 +87,7 @@ int mlx5e_tc_set_attr_rx_tun(struct mlx5e_tc_flow *flow, void *daddr, *saddr; u8 ip_version; - tun_attr = kvzalloc(sizeof(*tun_attr), GFP_KERNEL); + tun_attr = kvzalloc_obj(*tun_attr); if (!tun_attr) return -ENOMEM; @@ -864,7 +864,7 @@ int mlx5e_attach_encap(struct mlx5e_priv *priv, goto attach_flow; } - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { err = -ENOMEM; goto out_err; @@ -976,7 +976,7 @@ int mlx5e_attach_decap(struct mlx5e_priv *priv, goto found; } - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { err = -ENOMEM; goto out_err; @@ -1205,7 +1205,7 @@ mlx5e_route_get_create(struct mlx5e_priv *priv, return r; } - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) return ERR_PTR(-ENOMEM); @@ -1251,7 +1251,7 @@ mlx5e_tc_init_fib_work(unsigned long event, struct net_device *ul_dev, gfp_t fla { struct mlx5e_tc_fib_event_data *fib_work; - fib_work = kzalloc(sizeof(*fib_work), flags); + fib_work = kzalloc_obj(*fib_work, flags); if (WARN_ON(!fib_work)) return NULL; @@ -1862,7 +1862,7 @@ struct mlx5e_tc_tun_encap *mlx5e_tc_tun_init(struct mlx5e_priv *priv) struct mlx5e_tc_tun_encap *encap; int err; - encap = kvzalloc(sizeof(*encap), GFP_KERNEL); + encap = kvzalloc_obj(*encap); if (!encap) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c index 0b55e77f19c8..376ba6b29027 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tir.c @@ -22,7 +22,7 @@ struct mlx5e_tir_builder *mlx5e_tir_builder_alloc(bool modify) { struct mlx5e_tir_builder *builder; - builder = kvzalloc(sizeof(*builder), GFP_KERNEL); + builder = kvzalloc_obj(*builder); if (!builder) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c index db776e515b6a..c5ba22eed8f1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c @@ -23,8 +23,7 @@ static void mlx5e_xsk_unmap_pool(struct mlx5e_priv *priv, static int mlx5e_xsk_get_pools(struct mlx5e_xsk *xsk) { if (!xsk->pools) { - xsk->pools = kcalloc(MLX5E_MAX_NUM_CHANNELS, - sizeof(*xsk->pools), GFP_KERNEL); + xsk->pools = kzalloc_objs(*xsk->pools, MLX5E_MAX_NUM_CHANNELS); if (unlikely(!xsk->pools)) return -ENOMEM; } @@ -127,7 +126,7 @@ static int mlx5e_xsk_enable_locked(struct mlx5e_priv *priv, goto err_remove_pool; mlx5e_activate_xsk(c); - mlx5e_trigger_napi_icosq(c); + mlx5e_trigger_napi_async_icosq(c); /* Don't wait for WQEs, because the newer xdpsock sample doesn't provide * any Fill Ring entries at the setup stage. @@ -179,7 +178,7 @@ static int mlx5e_xsk_disable_locked(struct mlx5e_priv *priv, u16 ix) c = priv->channels.c[ix]; mlx5e_activate_rq(&c->rq); - mlx5e_trigger_napi_icosq(c); + mlx5e_trigger_napi_async_icosq(c); mlx5e_wait_for_min_rx_wqes(&c->rq, MLX5E_RQ_WQES_TIMEOUT); mlx5e_rx_res_xsk_update(priv->rx_res, &priv->channels, ix, false); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c index 5981c71cae2d..d39f778ecd85 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c @@ -123,7 +123,7 @@ int mlx5e_open_xsk(struct mlx5e_priv *priv, struct mlx5e_params *params, if (!mlx5e_validate_xsk_param(params, xsk, priv->mdev)) return -EINVAL; - cparam = kvzalloc(sizeof(*cparam), GFP_KERNEL); + cparam = kvzalloc_obj(*cparam); if (!cparam) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c index 9e33156fac8a..8aeab4b21035 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/tx.c @@ -34,7 +34,7 @@ int mlx5e_xsk_wakeup(struct net_device *dev, u32 qid, u32 flags) &c->async_icosq->state)) return 0; - mlx5e_trigger_napi_icosq(c); + mlx5e_trigger_napi_async_icosq(c); } return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c index 1febdc5b81f9..e21b7c8f2e81 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/fs_tcp.c @@ -82,7 +82,7 @@ struct mlx5_flow_handle *mlx5e_accel_fs_add_sk(struct mlx5e_flow_steering *fs, struct mlx5_flow_handle *flow; struct mlx5_flow_spec *spec; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -186,7 +186,7 @@ static int accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft, int err; u8 *mc; - ft->g = kcalloc(MLX5E_ACCEL_FS_TCP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_ACCEL_FS_TCP_NUM_GROUPS); in = kvzalloc(inlen, GFP_KERNEL); if (!in || !ft->g) { kfree(ft->g); @@ -378,7 +378,7 @@ int mlx5e_accel_fs_tcp_create(struct mlx5e_flow_steering *fs) if (!MLX5_CAP_FLOWTABLE_NIC_RX(mlx5e_fs_get_mdev(fs), ft_field_support.outer_ip_version)) return -EOPNOTSUPP; - accel_tcp = kzalloc(sizeof(*accel_tcp), GFP_KERNEL); + accel_tcp = kzalloc_obj(*accel_tcp); if (!accel_tcp) return -ENOMEM; mlx5e_fs_set_accel_tcp(fs, accel_tcp); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c index 9c7064187ed0..64e13747084e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c @@ -259,7 +259,6 @@ static void mlx5e_ipsec_init_limits(struct mlx5e_ipsec_sa_entry *sa_entry, static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, struct mlx5_accel_esp_xfrm_attrs *attrs) { - struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry); struct mlx5e_ipsec_addr *addrs = &attrs->addrs; struct net_device *netdev = sa_entry->dev; struct xfrm_state *x = sa_entry->x; @@ -276,7 +275,7 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry, attrs->type != XFRM_DEV_OFFLOAD_PACKET) return; - mlx5_query_mac_address(mdev, addr); + ether_addr_copy(addr, netdev->dev_addr); switch (attrs->dir) { case XFRM_DEV_OFFLOAD_IN: src = attrs->dmac; @@ -712,21 +711,20 @@ static int mlx5_ipsec_create_work(struct mlx5e_ipsec_sa_entry *sa_entry) break; } - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; switch (x->xso.type) { case XFRM_DEV_OFFLOAD_CRYPTO: - data = kzalloc(sizeof(*sa_entry), GFP_KERNEL); + data = kzalloc_obj(*sa_entry); if (!data) goto free_work; INIT_WORK(&work->work, mlx5e_ipsec_modify_state); break; case XFRM_DEV_OFFLOAD_PACKET: - data = kzalloc(sizeof(struct mlx5e_ipsec_netevent_data), - GFP_KERNEL); + data = kzalloc_obj(struct mlx5e_ipsec_netevent_data); if (!data) goto free_work; @@ -760,7 +758,7 @@ static int mlx5e_ipsec_create_dwork(struct mlx5e_ipsec_sa_entry *sa_entry) x->lft.hard_byte_limit == XFRM_INF) return 0; - dwork = kzalloc(sizeof(*dwork), GFP_KERNEL); + dwork = kzalloc_obj(*dwork); if (!dwork) return -ENOMEM; @@ -787,7 +785,7 @@ static int mlx5e_xfrm_add_state(struct net_device *dev, ipsec = priv->ipsec; gfp = (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ) ? GFP_ATOMIC : GFP_KERNEL; - sa_entry = kzalloc(sizeof(*sa_entry), gfp); + sa_entry = kzalloc_obj(*sa_entry, gfp); if (!sa_entry) return -ENOMEM; @@ -989,7 +987,7 @@ void mlx5e_ipsec_init(struct mlx5e_priv *priv) return; } - ipsec = kzalloc(sizeof(*ipsec), GFP_KERNEL); + ipsec = kzalloc_obj(*ipsec); if (!ipsec) return; @@ -1277,7 +1275,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x, if (err) return err; - pol_entry = kzalloc(sizeof(*pol_entry), GFP_KERNEL); + pol_entry = kzalloc_obj(*pol_entry); if (!pol_entry) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c index feef86fff4bf..329608c59313 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c @@ -208,7 +208,7 @@ static int rx_add_rule_drop_auth_trailer(struct mlx5e_ipsec_sa_entry *sa_entry, struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -287,7 +287,7 @@ static int rx_add_rule_drop_replay(struct mlx5e_ipsec_sa_entry *sa_entry, struct struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -347,7 +347,7 @@ static int ipsec_rx_status_drop_all_create(struct mlx5e_ipsec *ipsec, int err = 0; flow_group_in = kvzalloc(inlen, GFP_KERNEL); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!flow_group_in || !spec) { err = -ENOMEM; goto err_out; @@ -454,7 +454,7 @@ ipsec_rx_status_pass_create(struct mlx5e_ipsec *ipsec, struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -554,7 +554,7 @@ static int ipsec_miss_create(struct mlx5_core_dev *mdev, int err = 0; flow_group_in = kvzalloc(inlen, GFP_KERNEL); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!flow_group_in || !spec) { err = -ENOMEM; goto out; @@ -1226,7 +1226,7 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_ struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1962,7 +1962,7 @@ static int rx_add_rule_sa_selector(struct mlx5e_ipsec_sa_entry *sa_entry, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -2046,7 +2046,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) if (IS_ERR(rx)) return PTR_ERR(rx); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto err_alloc; @@ -2176,7 +2176,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) if (IS_ERR(tx)) return PTR_ERR(tx); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto err_alloc; @@ -2267,7 +2267,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) if (IS_ERR(ft)) return PTR_ERR(ft); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto err_alloc; @@ -2354,7 +2354,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry) rx = ipsec_rx(pol_entry->ipsec, attrs->addrs.family, attrs->type); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto err_alloc; @@ -2434,7 +2434,7 @@ static struct mlx5e_ipsec_fc *ipsec_fs_init_single_counter(struct mlx5_core_dev struct mlx5_fc *counter; int err; - fc = kzalloc(sizeof(*fc), GFP_KERNEL); + fc = kzalloc_obj(*fc); if (!fc) return ERR_PTR(-ENOMEM); @@ -2778,24 +2778,24 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec, if (!ns_esw) return -EOPNOTSUPP; - ipsec->tx_esw = kzalloc(sizeof(*ipsec->tx_esw), GFP_KERNEL); + ipsec->tx_esw = kzalloc_obj(*ipsec->tx_esw); if (!ipsec->tx_esw) return -ENOMEM; - ipsec->rx_esw = kzalloc(sizeof(*ipsec->rx_esw), GFP_KERNEL); + ipsec->rx_esw = kzalloc_obj(*ipsec->rx_esw); if (!ipsec->rx_esw) goto err_rx_esw; } - ipsec->tx = kzalloc(sizeof(*ipsec->tx), GFP_KERNEL); + ipsec->tx = kzalloc_obj(*ipsec->tx); if (!ipsec->tx) goto err_tx; - ipsec->rx_ipv4 = kzalloc(sizeof(*ipsec->rx_ipv4), GFP_KERNEL); + ipsec->rx_ipv4 = kzalloc_obj(*ipsec->rx_ipv4); if (!ipsec->rx_ipv4) goto err_rx_ipv4; - ipsec->rx_ipv6 = kzalloc(sizeof(*ipsec->rx_ipv6), GFP_KERNEL); + ipsec->rx_ipv6 = kzalloc_obj(*ipsec->rx_ipv6); if (!ipsec->rx_ipv6) goto err_rx_ipv6; @@ -2912,7 +2912,7 @@ void mlx5e_ipsec_disable_events(struct mlx5e_priv *priv) goto out; peer_priv = mlx5_devcom_get_next_peer_data(priv->devcom, &tmp); - if (peer_priv) + if (peer_priv && peer_priv->ipsec) complete_all(&peer_priv->ipsec->comp); mlx5_devcom_for_each_peer_end(priv->devcom); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c index ef7322d381af..33344e00719b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c @@ -503,7 +503,7 @@ static int mlx5e_ipsec_event(struct notifier_block *nb, unsigned long event, if (!sa_entry) return NOTIFY_DONE; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; @@ -522,7 +522,7 @@ int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec) struct device *pdev; int err; - aso = kzalloc(sizeof(*ipsec->aso), GFP_KERNEL); + aso = kzalloc_obj(*ipsec->aso); if (!aso) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c index 1c2cc2aad2b0..337201f12895 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.c @@ -199,7 +199,7 @@ int mlx5e_ktls_init(struct mlx5e_priv *priv) if (!mlx5e_is_ktls_device(priv->mdev)) return 0; - tls = kzalloc(sizeof(*tls), GFP_KERNEL); + tls = kzalloc_obj(*tls); if (!tls) return -ENOMEM; tls->mdev = priv->mdev; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c index 5d8fe252799e..ac8168ebb38c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c @@ -90,7 +90,7 @@ mlx5e_ktls_rx_resync_create_resp_list(void) { struct mlx5e_ktls_resync_resp *resp_list; - resp_list = kvzalloc(sizeof(*resp_list), GFP_KERNEL); + resp_list = kvzalloc_obj(*resp_list); if (!resp_list) return ERR_PTR(-ENOMEM); @@ -261,7 +261,7 @@ resync_post_get_progress_params(struct mlx5e_icosq *sq, int err; u16 pi; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (unlikely(!buf)) { err = -ENOMEM; goto err_out; @@ -643,7 +643,7 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, tls_ctx = tls_get_ctx(sk); priv = netdev_priv(netdev); - priv_rx = kzalloc(sizeof(*priv_rx), GFP_KERNEL); + priv_rx = kzalloc_obj(*priv_rx); if (unlikely(!priv_rx)) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c index 08f06984407b..29769fc99c4b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c @@ -196,7 +196,7 @@ mlx5e_tls_priv_tx_init(struct mlx5_core_dev *mdev, struct mlx5e_tls_sw_stats *sw struct mlx5e_ktls_offload_context_tx *priv_tx; int err; - priv_tx = kzalloc(sizeof(*priv_tx), GFP_KERNEL); + priv_tx = kzalloc_obj(*priv_tx); if (!priv_tx) return ERR_PTR(-ENOMEM); @@ -360,7 +360,7 @@ static struct mlx5e_tls_tx_pool *mlx5e_tls_tx_pool_init(struct mlx5_core_dev *md BUILD_BUG_ON(MLX5E_TLS_TX_POOL_LOW + MLX5E_TLS_TX_POOL_BULK >= MLX5E_TLS_TX_POOL_HIGH); - pool = kvzalloc(sizeof(*pool), GFP_KERNEL); + pool = kvzalloc_obj(*pool); if (!pool) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c index 528b04d4de41..71b3a059c964 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/macsec.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "en.h" #include "lib/aso.h" @@ -164,7 +165,7 @@ static int mlx5e_macsec_aso_reg_mr(struct mlx5_core_dev *mdev, struct mlx5e_macs dma_addr_t dma_addr; int err; - umr = kzalloc(sizeof(*umr), GFP_KERNEL); + umr = kzalloc_obj(*umr); if (!umr) { err = -ENOMEM; return err; @@ -529,7 +530,7 @@ static int mlx5e_macsec_add_txsa(struct macsec_context *ctx) goto out; } - tx_sa = kzalloc(sizeof(*tx_sa), GFP_KERNEL); + tx_sa = kzalloc_obj(*tx_sa); if (!tx_sa) { err = -ENOMEM; goto out; @@ -700,13 +701,13 @@ static int mlx5e_macsec_add_rxsc(struct macsec_context *ctx) goto out; } - rx_sc = kzalloc(sizeof(*rx_sc), GFP_KERNEL); + rx_sc = kzalloc_obj(*rx_sc); if (!rx_sc) { err = -ENOMEM; goto out; } - sc_xarray_element = kzalloc(sizeof(*sc_xarray_element), GFP_KERNEL); + sc_xarray_element = kzalloc_obj(*sc_xarray_element); if (!sc_xarray_element) { err = -ENOMEM; goto destroy_rx_sc; @@ -911,7 +912,7 @@ static int mlx5e_macsec_add_rxsa(struct macsec_context *ctx) goto out; } - rx_sa = kzalloc(sizeof(*rx_sa), GFP_KERNEL); + rx_sa = kzalloc_obj(*rx_sa); if (!rx_sa) { err = -ENOMEM; goto out; @@ -1092,7 +1093,7 @@ static int mlx5e_macsec_add_secy(struct macsec_context *ctx) goto out; } - macsec_device = kzalloc(sizeof(*macsec_device), GFP_KERNEL); + macsec_device = kzalloc_obj(*macsec_device); if (!macsec_device) { err = -ENOMEM; goto out; @@ -1385,7 +1386,8 @@ static int macsec_aso_set_arm_event(struct mlx5_core_dev *mdev, struct mlx5e_mac MLX5_ACCESS_ASO_OPC_MOD_MACSEC); macsec_aso_build_ctrl(aso, &aso_wqe->aso_ctrl, in); mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl); - err = mlx5_aso_poll_cq(maso, false); + read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, + false, maso, false); mutex_unlock(&aso->aso_lock); return err; @@ -1397,7 +1399,6 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac struct mlx5e_macsec_aso *aso; struct mlx5_aso_wqe *aso_wqe; struct mlx5_aso *maso; - unsigned long expires; int err; aso = &macsec->aso; @@ -1411,12 +1412,8 @@ static int macsec_aso_query(struct mlx5_core_dev *mdev, struct mlx5e_macsec *mac macsec_aso_build_wqe_ctrl_seg(aso, &aso_wqe->aso_ctrl, NULL); mlx5_aso_post_wqe(maso, false, &aso_wqe->ctrl); - expires = jiffies + msecs_to_jiffies(10); - do { - err = mlx5_aso_poll_cq(maso, false); - if (err) - usleep_range(2, 10); - } while (err && time_is_after_jiffies(expires)); + read_poll_timeout(mlx5_aso_poll_cq, err, !err, 10, 10 * USEC_PER_MSEC, + false, maso, false); if (err) goto err_out; @@ -1568,7 +1565,7 @@ static int macsec_obj_change_event(struct notifier_block *nb, unsigned long even if (obj_type != MLX5_GENERAL_OBJECT_TYPES_MACSEC) return NOTIFY_DONE; - async_work = kzalloc(sizeof(*async_work), GFP_ATOMIC); + async_work = kzalloc_obj(*async_work, GFP_ATOMIC); if (!async_work) return NOTIFY_DONE; @@ -1733,7 +1730,7 @@ int mlx5e_macsec_init(struct mlx5e_priv *priv) return 0; } - macsec = kzalloc(sizeof(*macsec), GFP_KERNEL); + macsec = kzalloc_obj(*macsec); if (!macsec) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c index 9a74438ce10a..6a50b6dec0fa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c @@ -142,7 +142,7 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs, struct mlx5_flow_spec *spec; int err = 0; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -344,7 +344,7 @@ static int accel_psp_fs_rx_create_ft(struct mlx5e_psp_fs *fs, int err = 0; flow_group_in = kvzalloc(inlen, GFP_KERNEL); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!flow_group_in || !spec) { err = -ENOMEM; goto out; @@ -560,7 +560,7 @@ static int accel_psp_fs_init_rx(struct mlx5e_psp_fs *fs) enum accel_fs_psp_type i; int err; - accel_psp = kzalloc(sizeof(*accel_psp), GFP_KERNEL); + accel_psp = kzalloc_obj(*accel_psp); if (!accel_psp) return -ENOMEM; @@ -686,7 +686,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs) struct mlx5_flow_group *fg; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); in = kvzalloc(inlen, GFP_KERNEL); if (!spec || !in) { err = -ENOMEM; @@ -815,7 +815,7 @@ static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs) if (!ns) return -EOPNOTSUPP; - tx_fs = kzalloc(sizeof(*tx_fs), GFP_KERNEL); + tx_fs = kzalloc_obj(*tx_fs); if (!tx_fs) return -ENOMEM; @@ -896,7 +896,7 @@ static struct mlx5e_psp_fs *mlx5e_accel_psp_fs_init(struct mlx5e_priv *priv) struct mlx5e_psp_fs *fs; int err = 0; - fs = kzalloc(sizeof(*fs), GFP_KERNEL); + fs = kzalloc_obj(*fs); if (!fs) return ERR_PTR(-ENOMEM); @@ -1127,7 +1127,7 @@ int mlx5e_psp_init(struct mlx5e_priv *priv) return 0; } - psp = kzalloc(sizeof(*psp), GFP_KERNEL); + psp = kzalloc_obj(*psp); if (!psp) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c index 93cf23278d93..c5e62d7d4908 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_arfs.c @@ -260,8 +260,7 @@ static int arfs_create_groups(struct mlx5e_flow_table *ft, int err; u8 *mc; - ft->g = kcalloc(MLX5E_ARFS_NUM_GROUPS, - sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_ARFS_NUM_GROUPS); if (!ft->g) return -ENOMEM; @@ -392,7 +391,7 @@ int mlx5e_arfs_create_tables(struct mlx5e_flow_steering *fs, if (!ntuple) return 0; - arfs = kvzalloc(sizeof(*arfs), GFP_KERNEL); + arfs = kvzalloc_obj(*arfs); if (!arfs) return -ENOMEM; @@ -523,7 +522,7 @@ static struct mlx5_flow_handle *arfs_add_rule(struct mlx5e_priv *priv, struct mlx5_flow_table *ft; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { priv->channel_stats[arfs_rule->rxq]->rq.arfs_err++; err = -ENOMEM; @@ -662,7 +661,7 @@ static struct arfs_rule *arfs_alloc_rule(struct mlx5e_priv *priv, struct arfs_rule *rule; struct arfs_tuple *tuple; - rule = kzalloc(sizeof(*rule), GFP_ATOMIC); + rule = kzalloc_obj(*rule, GFP_ATOMIC); if (!rule) { priv->channel_stats[rxq]->rq.arfs_err++; return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c index 5a2ac7b6f260..c2d4bae533de 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_common.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_common.c @@ -179,7 +179,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev, bool create_tises) num_doorbells = min(mlx5e_get_devlink_param_num_doorbells(mdev), mlx5e_get_max_num_channels(mdev)); - res->bfregs = kcalloc(num_doorbells, sizeof(*res->bfregs), GFP_KERNEL); + res->bfregs = kzalloc_objs(*res->bfregs, num_doorbells); if (!res->bfregs) { err = -ENOMEM; goto err_destroy_mkey; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c index 8928d2dcd43f..9352e2183312 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c @@ -128,7 +128,7 @@ static void mlx5e_add_l2_to_hash(struct hlist_head *hash, const u8 *addr) return; } - hn = kzalloc(sizeof(*hn), GFP_ATOMIC); + hn = kzalloc_obj(*hn, GFP_ATOMIC); if (!hn) return; @@ -295,7 +295,7 @@ static int mlx5e_add_vlan_rule(struct mlx5e_flow_steering *fs, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -372,7 +372,7 @@ mlx5e_add_trap_rule(struct mlx5_flow_table *ft, int trap_id, int tir_num) struct mlx5_flow_handle *rule; struct mlx5_flow_spec *spec; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); spec->flow_context.flags |= FLOW_CONTEXT_HAS_TAG; @@ -754,7 +754,7 @@ static int mlx5e_add_promisc_rule(struct mlx5e_flow_steering *fs) struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; @@ -984,7 +984,7 @@ static int mlx5e_add_l2_flow_rule(struct mlx5e_flow_steering *fs, u8 *mc_dmac; u8 *mv_dmac; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1039,7 +1039,7 @@ static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table) int err; u8 *mc; - ft->g = kcalloc(MLX5E_NUM_L2_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_NUM_L2_GROUPS); if (!ft->g) return -ENOMEM; in = kvzalloc(inlen, GFP_KERNEL); @@ -1251,7 +1251,7 @@ static int mlx5e_fs_create_vlan_table(struct mlx5e_flow_steering *fs) if (IS_ERR(ft->t)) return PTR_ERR(ft->t); - ft->g = kcalloc(MLX5E_NUM_VLAN_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, MLX5E_NUM_VLAN_GROUPS); if (!ft->g) { err = -ENOMEM; goto err_destroy_vlan_table; @@ -1394,7 +1394,7 @@ void mlx5e_destroy_flow_steering(struct mlx5e_flow_steering *fs, bool ntuple, static int mlx5e_fs_vlan_alloc(struct mlx5e_flow_steering *fs) { - fs->vlan = kvzalloc(sizeof(*fs->vlan), GFP_KERNEL); + fs->vlan = kvzalloc_obj(*fs->vlan); if (!fs->vlan) return -ENOMEM; return 0; @@ -1466,7 +1466,7 @@ struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile, struct mlx5e_flow_steering *fs; int err; - fs = kvzalloc(sizeof(*fs), GFP_KERNEL); + fs = kvzalloc_obj(*fs); if (!fs) goto err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c index 63bdef5b4ba5..aecfba7deeb0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c @@ -465,7 +465,7 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); err = set_flow_attrs(spec->match_criteria, spec->match_value, @@ -476,7 +476,7 @@ add_ethtool_flow_rule(struct mlx5e_priv *priv, if (fs->ring_cookie == RX_CLS_FLOW_DISC) { flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; } else { - dst = kzalloc(sizeof(*dst), GFP_KERNEL); + dst = kzalloc_obj(*dst); if (!dst) { err = -ENOMEM; goto free; @@ -541,7 +541,7 @@ static struct mlx5e_ethtool_rule *get_ethtool_rule(struct mlx5e_priv *priv, if (eth_rule) del_ethtool_rule(priv->fs, eth_rule); - eth_rule = kzalloc(sizeof(*eth_rule), GFP_KERNEL); + eth_rule = kzalloc_obj(*eth_rule); if (!eth_rule) return ERR_PTR(-ENOMEM); @@ -836,7 +836,7 @@ mlx5e_ethtool_get_all_flows(struct mlx5e_priv *priv, int mlx5e_ethtool_alloc(struct mlx5e_ethtool_steering **ethtool) { - *ethtool = kvzalloc(sizeof(**ethtool), GFP_KERNEL); + *ethtool = kvzalloc_obj(**ethtool); if (!*ethtool) return -ENOMEM; return 0; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 4b8084420816..b6c12460b54a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -631,19 +631,7 @@ static void mlx5e_rq_timeout_work(struct work_struct *timeout_work) struct mlx5e_rq, rx_timeout_work); - /* Acquire netdev instance lock to synchronize with channel close and - * reopen flows. Either successfully obtain the lock, or detect that - * channels are closing for another reason, making this work no longer - * necessary. - */ - while (!netdev_trylock(rq->netdev)) { - if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &rq->priv->state)) - return; - msleep(20); - } - mlx5e_reporter_rx_timeout(rq); - netdev_unlock(rq->netdev); } static int mlx5e_alloc_mpwqe_rq_drop_page(struct mlx5e_rq *rq) @@ -1952,20 +1940,7 @@ void mlx5e_tx_err_cqe_work(struct work_struct *recover_work) struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq, recover_work); - /* Recovering queues means re-enabling NAPI, which requires the netdev - * instance lock. However, SQ closing flows have to wait for work tasks - * to finish while also holding the netdev instance lock. So either get - * the lock or find that the SQ is no longer enabled and thus this work - * is not relevant anymore. - */ - while (!netdev_trylock(sq->netdev)) { - if (!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)) - return; - msleep(20); - } - mlx5e_reporter_tx_err_cqe(sq); - netdev_unlock(sq->netdev); } static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode) @@ -2744,16 +2719,26 @@ static int mlx5e_channel_stats_alloc(struct mlx5e_priv *priv, int ix, int cpu) void mlx5e_trigger_napi_icosq(struct mlx5e_channel *c) { + struct mlx5e_icosq *sq = &c->icosq; bool locked; - if (!test_and_set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &c->icosq.state)) - synchronize_net(); + set_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state); + synchronize_net(); - locked = mlx5e_icosq_sync_lock(&c->icosq); - mlx5e_trigger_irq(&c->icosq); - mlx5e_icosq_sync_unlock(&c->icosq, locked); + locked = mlx5e_icosq_sync_lock(sq); + mlx5e_trigger_irq(sq); + mlx5e_icosq_sync_unlock(sq, locked); - clear_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &c->icosq.state); + clear_bit(MLX5E_SQ_STATE_LOCK_NEEDED, &sq->state); +} + +void mlx5e_trigger_napi_async_icosq(struct mlx5e_channel *c) +{ + struct mlx5e_icosq *sq = c->async_icosq; + + spin_lock_bh(&sq->lock); + mlx5e_trigger_irq(sq); + spin_unlock_bh(&sq->lock); } void mlx5e_trigger_napi_sched(struct napi_struct *napi) @@ -2806,7 +2791,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, return err; c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu)); - cparam = kvzalloc(sizeof(*cparam), GFP_KERNEL); + cparam = kvzalloc_obj(*cparam); if (!c || !cparam) { err = -ENOMEM; goto err_free; @@ -2836,7 +2821,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix, netif_napi_add_config_locked(netdev, &c->napi, mlx5e_napi_poll, ix); netif_napi_set_irq_locked(&c->napi, irq); - async_icosq_needed = !!xsk_pool || priv->ktls_rx_was_enabled; + async_icosq_needed = !!params->xdp_prog || priv->ktls_rx_was_enabled; err = mlx5e_open_queues(c, params, cparam, async_icosq_needed); if (unlikely(err)) goto err_napi_del; @@ -2926,7 +2911,7 @@ int mlx5e_open_channels(struct mlx5e_priv *priv, chs->num = chs->params.num_channels; - chs->c = kcalloc(chs->num, sizeof(struct mlx5e_channel *), GFP_KERNEL); + chs->c = kzalloc_objs(struct mlx5e_channel *, chs->num); if (!chs->c) goto err_out; @@ -3430,8 +3415,8 @@ int mlx5e_safe_switch_params(struct mlx5e_priv *priv, if (!reset) return mlx5e_switch_priv_params(priv, params, preactivate, context); - old_chs = kzalloc(sizeof(*old_chs), GFP_KERNEL); - new_chs = kzalloc(sizeof(*new_chs), GFP_KERNEL); + old_chs = kzalloc_obj(*old_chs); + new_chs = kzalloc_obj(*new_chs); if (!old_chs || !new_chs) { err = -ENOMEM; goto err_free_chs; @@ -5105,19 +5090,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) struct net_device *netdev = priv->netdev; int i; - /* Recovering the TX queues implies re-enabling NAPI, which requires - * the netdev instance lock. - * However, channel closing flows have to wait for this work to finish - * while holding the same lock. So either get the lock or find that - * channels are being closed for other reason and this work is not - * relevant anymore. - */ - while (!netdev_trylock(netdev)) { - if (!test_bit(MLX5E_STATE_CHANNELS_ACTIVE, &priv->state)) - return; - msleep(20); - } - for (i = 0; i < netdev->real_num_tx_queues; i++) { struct netdev_queue *dev_queue = netdev_get_tx_queue(netdev, i); @@ -5130,8 +5102,6 @@ static void mlx5e_tx_timeout_work(struct work_struct *work) /* break if tried to reopened channels */ break; } - - netdev_unlock(netdev); } static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue) @@ -6288,8 +6258,7 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, if (!priv->channel_stats) goto err_free_tx_rates; - priv->fec_ranges = kcalloc(ETHTOOL_FEC_HIST_MAX, - sizeof(*priv->fec_ranges), GFP_KERNEL); + priv->fec_ranges = kzalloc_objs(*priv->fec_ranges, ETHTOOL_FEC_HIST_MAX); if (!priv->fec_ranges) goto err_free_channel_stats; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 6eec88fa6d10..1db4ecb2356f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -476,7 +476,7 @@ static int mlx5e_sqs2vport_add_peers_rules(struct mlx5_eswitch *esw, struct mlx5 struct mlx5e_rep_sq_peer *sq_peer; int err; - sq_peer = kzalloc(sizeof(*sq_peer), GFP_KERNEL); + sq_peer = kzalloc_obj(*sq_peer); if (!sq_peer) return -ENOMEM; @@ -521,7 +521,7 @@ static int mlx5e_sqs2vport_start(struct mlx5_eswitch *esw, devcom_locked = true; for (i = 0; i < sqns_num; i++) { - rep_sq = kzalloc(sizeof(*rep_sq), GFP_KERNEL); + rep_sq = kzalloc_obj(*rep_sq); if (!rep_sq) { err = -ENOMEM; goto out_err; @@ -1621,7 +1621,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) struct mlx5e_rep_priv *rpriv; int err; - rpriv = kvzalloc(sizeof(*rpriv), GFP_KERNEL); + rpriv = kvzalloc_obj(*rpriv); if (!rpriv) return -ENOMEM; @@ -1731,7 +1731,7 @@ static int mlx5e_vport_rep_event_pair(struct mlx5_eswitch *esw, sq_peer->peer = peer_esw; continue; } - sq_peer = kzalloc(sizeof(*sq_peer), GFP_KERNEL); + sq_peer = kzalloc_obj(*sq_peer); if (!sq_peer) { err = -ENOMEM; goto err_sq_alloc; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c index efcfcddab376..268e20884757 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c @@ -1589,6 +1589,7 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi struct skb_shared_info *sinfo; u32 frag_consumed_bytes; struct bpf_prog *prog; + u8 nr_frags_free = 0; struct sk_buff *skb; dma_addr_t addr; u32 truesize; @@ -1631,15 +1632,13 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi prog = rcu_dereference(rq->xdp_prog); if (prog) { - u8 nr_frags_free, old_nr_frags = sinfo->nr_frags; + u8 old_nr_frags = sinfo->nr_frags; if (mlx5e_xdp_handle(rq, prog, mxbuf)) { if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) { struct mlx5e_wqe_frag_info *pwi; - wi -= old_nr_frags - sinfo->nr_frags; - for (pwi = head_wi; pwi < wi; pwi++) pwi->frag_page->frags++; } @@ -1647,10 +1646,8 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi } nr_frags_free = old_nr_frags - sinfo->nr_frags; - if (unlikely(nr_frags_free)) { - wi -= nr_frags_free; + if (unlikely(nr_frags_free)) truesize -= nr_frags_free * frag_info->frag_stride; - } } skb = mlx5e_build_linear_skb( @@ -1666,7 +1663,7 @@ mlx5e_skb_from_cqe_nonlinear(struct mlx5e_rq *rq, struct mlx5e_wqe_frag_info *wi if (xdp_buff_has_frags(&mxbuf->xdp)) { /* sinfo->nr_frags is reset by build_skb, calculate again. */ - xdp_update_skb_frags_info(skb, wi - head_wi - 1, + xdp_update_skb_frags_info(skb, wi - head_wi - nr_frags_free - 1, sinfo->xdp_frags_size, truesize, xdp_buff_get_skb_flags(&mxbuf->xdp)); @@ -1957,14 +1954,13 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w if (prog) { u8 nr_frags_free, old_nr_frags = sinfo->nr_frags; + u8 new_nr_frags; u32 len; if (mlx5e_xdp_handle(rq, prog, mxbuf)) { if (__test_and_clear_bit(MLX5E_RQ_FLAG_XDP_XMIT, rq->flags)) { struct mlx5e_frag_page *pfp; - frag_page -= old_nr_frags - sinfo->nr_frags; - for (pfp = head_page; pfp < frag_page; pfp++) pfp->frags++; @@ -1975,13 +1971,12 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w return NULL; /* page/packet was consumed by XDP */ } - nr_frags_free = old_nr_frags - sinfo->nr_frags; - if (unlikely(nr_frags_free)) { - frag_page -= nr_frags_free; + new_nr_frags = sinfo->nr_frags; + nr_frags_free = old_nr_frags - new_nr_frags; + if (unlikely(nr_frags_free)) truesize -= (nr_frags_free - 1) * PAGE_SIZE + ALIGN(pg_consumed_bytes, BIT(rq->mpwqe.log_stride_sz)); - } len = mxbuf->xdp.data_end - mxbuf->xdp.data; @@ -2003,7 +1998,7 @@ mlx5e_skb_from_cqe_mpwrq_nonlinear(struct mlx5e_rq *rq, struct mlx5e_mpw_info *w struct mlx5e_frag_page *pagep; /* sinfo->nr_frags is reset by build_skb, calculate again. */ - xdp_update_skb_frags_info(skb, frag_page - head_page, + xdp_update_skb_frags_info(skb, new_nr_frags, sinfo->xdp_frags_size, truesize, xdp_buff_get_skb_flags(&mxbuf->xdp)); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c index fcad464bc4d5..accc26d1a872 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_selftest.c @@ -270,7 +270,7 @@ static int mlx5e_test_loopback(struct mlx5e_priv *priv) return -ENODEV; } - lbtp = kzalloc(sizeof(*lbtp), GFP_KERNEL); + lbtp = kzalloc_obj(*lbtp); if (!lbtp) return -ENOMEM; lbtp->loopback_ok = false; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c index 424786f489ec..1434b65d4746 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c @@ -153,7 +153,7 @@ struct mlx5e_tc_table *mlx5e_tc_table_alloc(void) { struct mlx5e_tc_table *tc; - tc = kvzalloc(sizeof(*tc), GFP_KERNEL); + tc = kvzalloc_obj(*tc); return tc ? tc : ERR_PTR(-ENOMEM); } @@ -905,7 +905,7 @@ mlx5e_hairpin_create(struct mlx5e_priv *priv, struct mlx5_hairpin_params *params struct mlx5_hairpin *pair; int err; - hp = kzalloc(sizeof(*hp), GFP_KERNEL); + hp = kzalloc_obj(*hp); if (!hp) return ERR_PTR(-ENOMEM); @@ -1139,7 +1139,7 @@ static int mlx5e_hairpin_flow_add(struct mlx5e_priv *priv, goto attach_flow; } - hpe = kzalloc(sizeof(*hpe), GFP_KERNEL); + hpe = kzalloc_obj(*hpe); if (!hpe) { mutex_unlock(&tc->hairpin_tbl_lock); return -ENOMEM; @@ -1794,7 +1794,7 @@ extra_split_attr_dests(struct mlx5e_tc_flow *flow, return PTR_ERR(post_act); attr2 = mlx5_alloc_flow_attr(mlx5e_get_flow_namespace(flow)); - parse_attr2 = kvzalloc(sizeof(*parse_attr), GFP_KERNEL); + parse_attr2 = kvzalloc_obj(*parse_attr); if (!attr2 || !parse_attr2) { err = -ENOMEM; goto err_free; @@ -2570,7 +2570,7 @@ static int parse_tunnel_attr(struct mlx5e_priv *priv, } else if (tunnel) { struct mlx5_flow_spec *tmp_spec; - tmp_spec = kvzalloc(sizeof(*tmp_spec), GFP_KERNEL); + tmp_spec = kvzalloc_obj(*tmp_spec); if (!tmp_spec) { NL_SET_ERR_MSG_MOD(extack, "Failed to allocate memory for tunnel tmp spec"); netdev_warn(priv->netdev, "Failed to allocate memory for tunnel tmp spec"); @@ -3671,7 +3671,7 @@ mlx5e_clone_flow_attr_for_post_act(struct mlx5_flow_attr *attr, struct mlx5_flow_attr *attr2; attr2 = mlx5_alloc_flow_attr(ns_type); - parse_attr = kvzalloc(sizeof(*parse_attr), GFP_KERNEL); + parse_attr = kvzalloc_obj(*parse_attr); if (!attr2 || !parse_attr) { kvfree(parse_attr); kfree(attr2); @@ -4448,8 +4448,8 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, int err = -ENOMEM; int out_index; - flow = kzalloc(sizeof(*flow), GFP_KERNEL); - parse_attr = kvzalloc(sizeof(*parse_attr), GFP_KERNEL); + flow = kzalloc_obj(*flow); + parse_attr = kvzalloc_obj(*parse_attr); if (!parse_attr || !flow) goto err_free; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c index 25499da177bc..22a637111aa2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c @@ -881,7 +881,7 @@ static int comp_irq_request_sf(struct mlx5_core_dev *dev, u16 vecidx) if (!mlx5_irq_pool_is_sf_pool(pool)) return comp_irq_request_pci(dev, vecidx); - af_desc = kvzalloc(sizeof(*af_desc), GFP_KERNEL); + af_desc = kvzalloc_obj(*af_desc); if (!af_desc) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c index 3ce455c2535c..ba5cce706ea2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/helper.c @@ -58,7 +58,7 @@ int esw_egress_acl_vlan_create(struct mlx5_eswitch *esw, if (vport->egress.allowed_vlan) return -EEXIST; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c index 49a637829c59..4410e57acfc7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_lgcy.c @@ -200,7 +200,7 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, "vport[%d] configure ingress rules, vlan(%d) qos(%d)\n", vport->vport, vport->info.vlan, vport->info.qos); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c index a436ce895e45..197324788799 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/ingress_ofld.c @@ -29,7 +29,7 @@ static int esw_acl_ingress_prio_tag_create(struct mlx5_eswitch *esw, * required, allow * Unmatched traffic is allowed by default */ - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c index 60e10047770f..87b5fd349594 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge.c @@ -586,7 +586,7 @@ mlx5_esw_bridge_ingress_flow_with_esw_create(u16 vport_num, const unsigned char struct mlx5_flow_handle *handle; u8 *smac_v, *smac_c; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -700,7 +700,7 @@ mlx5_esw_bridge_ingress_filter_flow_create(u16 vport_num, const unsigned char *a struct mlx5_flow_handle *handle; u8 *smac_v, *smac_c; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -753,7 +753,7 @@ mlx5_esw_bridge_egress_flow_create(u16 vport_num, u16 esw_owner_vhca_id, const u struct mlx5_flow_handle *handle; u8 *dmac_v, *dmac_c; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -821,7 +821,7 @@ mlx5_esw_bridge_egress_miss_flow_create(struct mlx5_flow_table *egress_ft, struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -844,7 +844,7 @@ static struct mlx5_esw_bridge *mlx5_esw_bridge_create(struct net_device *br_netd struct mlx5_esw_bridge *bridge; int err; - bridge = kvzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kvzalloc_obj(*bridge); if (!bridge) return ERR_PTR(-ENOMEM); @@ -1179,7 +1179,7 @@ mlx5_esw_bridge_vlan_create(u16 vlan_proto, u16 vid, u16 flags, struct mlx5_esw_ struct mlx5_esw_bridge_vlan *vlan; int err; - vlan = kvzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kvzalloc_obj(*vlan); if (!vlan) return ERR_PTR(-ENOMEM); @@ -1365,7 +1365,7 @@ mlx5_esw_bridge_fdb_entry_init(struct net_device *dev, u16 vport_num, u16 esw_ow if (entry) mlx5_esw_bridge_fdb_entry_notify_and_cleanup(entry, bridge); - entry = kvzalloc(sizeof(*entry), GFP_KERNEL); + entry = kvzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -1550,7 +1550,7 @@ static int mlx5_esw_bridge_vport_init(u16 vport_num, u16 esw_owner_vhca_id, u16 struct mlx5_esw_bridge_port *port; int err; - port = kvzalloc(sizeof(*port), GFP_KERNEL); + port = kvzalloc_obj(*port); if (!port) return -ENOMEM; @@ -1924,7 +1924,7 @@ struct mlx5_esw_bridge_offloads *mlx5_esw_bridge_init(struct mlx5_eswitch *esw) ASSERT_RTNL(); - br_offloads = kvzalloc(sizeof(*br_offloads), GFP_KERNEL); + br_offloads = kvzalloc_obj(*br_offloads); if (!br_offloads) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c index 22dd30cf8033..092cd62a9137 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/bridge_mcast.c @@ -65,11 +65,11 @@ mlx5_esw_bridge_mdb_flow_create(u16 esw_owner_vhca_id, struct mlx5_esw_bridge_md u8 *dmac_v, *dmac_c; unsigned long idx; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); - dests = kvcalloc(num_dests, sizeof(*dests), GFP_KERNEL); + dests = kvzalloc_objs(*dests, num_dests); if (!dests) { kvfree(rule_spec); return ERR_PTR(-ENOMEM); @@ -152,7 +152,7 @@ mlx5_esw_bridge_port_mdb_entry_init(struct mlx5_esw_bridge_port *port, struct mlx5_esw_bridge_mdb_entry *entry; int err; - entry = kvzalloc(sizeof(*entry), GFP_KERNEL); + entry = kvzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -516,7 +516,7 @@ mlx5_esw_bridge_mcast_flow_with_esw_create(struct mlx5_esw_bridge_port *port, struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -584,7 +584,7 @@ mlx5_esw_bridge_mcast_vlan_flow_create(u16 vlan_proto, struct mlx5_esw_bridge_po struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -656,7 +656,7 @@ mlx5_esw_bridge_mcast_fwd_flow_create(struct mlx5_esw_bridge_port *port) struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -890,7 +890,7 @@ mlx5_esw_bridge_ingress_igmp_fh_create(struct mlx5_flow_table *ingress_ft, struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); @@ -922,7 +922,7 @@ mlx5_esw_bridge_ingress_mld_fh_create(u8 type, struct mlx5_flow_table *ingress_f struct mlx5_flow_spec *rule_spec; struct mlx5_flow_handle *handle; - rule_spec = kvzalloc(sizeof(*rule_spec), GFP_KERNEL); + rule_spec = kvzalloc_obj(*rule_spec); if (!rule_spec) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c index cd60bc500ec5..8bffba85f21f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c @@ -70,7 +70,7 @@ int mlx5_esw_offloads_pf_vf_devlink_port_init(struct mlx5_eswitch *esw, if (!mlx5_esw_devlink_port_supported(esw, vport_num)) return 0; - dl_port = kzalloc(sizeof(*dl_port), GFP_KERNEL); + dl_port = kzalloc_obj(*dl_port); if (!dl_port) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c index 9959e9fd15a1..b80999608f8d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/indir_table.c @@ -46,7 +46,7 @@ struct mlx5_esw_indir_table { struct mlx5_esw_indir_table * mlx5_esw_indir_table_init(void) { - struct mlx5_esw_indir_table *indir = kvzalloc(sizeof(*indir), GFP_KERNEL); + struct mlx5_esw_indir_table *indir = kvzalloc_obj(*indir); if (!indir) return ERR_PTR(-ENOMEM); @@ -111,7 +111,7 @@ static int mlx5_esw_indir_table_rule_get(struct mlx5_eswitch *esw, return 0; } - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return -ENOMEM; @@ -258,7 +258,7 @@ mlx5_esw_indir_table_entry_create(struct mlx5_eswitch *esw, struct mlx5_flow_att if (!root_ns) return ERR_PTR(-ENOENT); - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c index 929adeb50a98..7c62f7938bfb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c @@ -259,7 +259,7 @@ static int _mlx5_eswitch_set_vepa_locked(struct mlx5_eswitch *esw, if (err) return err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c index 4278bcb04c72..26178d0bac92 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/qos.c @@ -38,7 +38,7 @@ static struct mlx5_qos_domain *esw_qos_domain_alloc(void) { struct mlx5_qos_domain *qos_domain; - qos_domain = kzalloc(sizeof(*qos_domain), GFP_KERNEL); + qos_domain = kzalloc_obj(*qos_domain); if (!qos_domain) return NULL; @@ -518,7 +518,7 @@ __esw_qos_alloc_node(struct mlx5_eswitch *esw, u32 tsar_ix, enum sched_node_type { struct mlx5_esw_sched_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return NULL; @@ -916,9 +916,8 @@ esw_qos_create_vport_tc_sched_elements(struct mlx5_vport *vport, int err, num_tcs = esw_qos_num_tcs(vport_node->esw->dev); u32 rate_limit_elem_ix; - vport->qos.sched_nodes = kcalloc(num_tcs, - sizeof(struct mlx5_esw_sched_node *), - GFP_KERNEL); + vport->qos.sched_nodes = kzalloc_objs(struct mlx5_esw_sched_node *, + num_tcs); if (!vport->qos.sched_nodes) { NL_SET_ERR_MSG_MOD(extack, "Allocating the vport TC scheduling elements failed."); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c index 407062096a82..ad2b9edbc0b9 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/vporttbl.c @@ -96,7 +96,7 @@ mlx5_esw_vporttbl_get(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr goto out; } - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { fdb = ERR_PTR(-ENOMEM); goto err_alloc; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 5fbfabe28bdb..123c96716a54 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c @@ -221,7 +221,7 @@ __esw_fdb_set_vport_rule(struct mlx5_eswitch *esw, u16 vport, bool rx_rule, if (rx_rule) match_header |= MLX5_MATCH_MISC_PARAMETERS; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return NULL; @@ -1072,10 +1072,11 @@ static void mlx5_eswitch_event_handler_register(struct mlx5_eswitch *esw) static void mlx5_eswitch_event_handler_unregister(struct mlx5_eswitch *esw) { - if (esw->mode == MLX5_ESWITCH_OFFLOADS && mlx5_eswitch_is_funcs_handler(esw->dev)) + if (esw->mode == MLX5_ESWITCH_OFFLOADS && + mlx5_eswitch_is_funcs_handler(esw->dev)) { mlx5_eq_notifier_unregister(esw->dev, &esw->esw_funcs.nb); - - flush_workqueue(esw->work_queue); + atomic_inc(&esw->esw_funcs.generation); + } } static void mlx5_eswitch_clear_vf_vports_info(struct mlx5_eswitch *esw) @@ -1862,7 +1863,7 @@ int mlx5_esw_vport_alloc(struct mlx5_eswitch *esw, int index, u16 vport_num) struct mlx5_vport *vport; int err; - vport = kzalloc(sizeof(*vport), GFP_KERNEL); + vport = kzalloc_obj(*vport); if (!vport) return -ENOMEM; @@ -2022,7 +2023,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) if (!MLX5_VPORT_MANAGER(dev) && !MLX5_ESWITCH_MANAGER(dev)) return 0; - esw = kzalloc(sizeof(*esw), GFP_KERNEL); + esw = kzalloc_obj(*esw); if (!esw) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index 6841caef02d1..c2563bee74df 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h @@ -335,10 +335,12 @@ struct esw_mc_addr { /* SRIOV only */ struct mlx5_host_work { struct work_struct work; struct mlx5_eswitch *esw; + int work_gen; }; struct mlx5_esw_functions { struct mlx5_nb nb; + atomic_t generation; bool host_funcs_disabled; u16 num_vfs; u16 num_ec_vfs; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c index 1b439cef3719..7a9ee36b8dca 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c @@ -680,7 +680,7 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw, if (!esw_flow_dests_fwd_ipsec_check(esw, esw_attr)) return ERR_PTR(-EOPNOTSUPP); - dest = kcalloc(MLX5_MAX_FLOW_FWD_VPORTS + 1, sizeof(*dest), GFP_KERNEL); + dest = kzalloc_objs(*dest, MLX5_MAX_FLOW_FWD_VPORTS + 1); if (!dest) return ERR_PTR(-ENOMEM); @@ -808,7 +808,7 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw, struct mlx5_flow_handle *rule; int i, err = 0; - dest = kcalloc(MLX5_MAX_FLOW_FWD_VPORTS + 1, sizeof(*dest), GFP_KERNEL); + dest = kzalloc_objs(*dest, MLX5_MAX_FLOW_FWD_VPORTS + 1); if (!dest) return ERR_PTR(-ENOMEM); @@ -947,7 +947,7 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw, void *misc; u16 vport; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { flow_rule = ERR_PTR(-ENOMEM); goto out; @@ -1044,7 +1044,7 @@ mlx5_eswitch_add_send_to_vport_meta_rule(struct mlx5_eswitch *esw, u16 vport_num struct mlx5_flow_handle *flow_rule; struct mlx5_flow_spec *spec; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -1198,13 +1198,13 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, !mlx5_core_is_ecpf_esw_manager(peer_dev)) return 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; peer_miss_rules_setup(esw, peer_dev, spec, &dest); - flows = kvcalloc(peer_esw->total_vports, sizeof(*flows), GFP_KERNEL); + flows = kvzalloc_objs(*flows, peer_esw->total_vports); if (!flows) { err = -ENOMEM; goto alloc_flows_err; @@ -1241,21 +1241,17 @@ static int esw_add_fdb_peer_miss_rules(struct mlx5_eswitch *esw, flows[peer_vport->index] = flow; } - if (mlx5_esw_host_functions_enabled(esw->dev)) { - mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, - mlx5_core_max_vfs(peer_dev)) { - esw_set_peer_miss_rule_source_port(esw, peer_esw, - spec, - peer_vport->vport); - - flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), - spec, &flow_act, &dest, 1); - if (IS_ERR(flow)) { - err = PTR_ERR(flow); - goto add_vf_flow_err; - } - flows[peer_vport->index] = flow; + mlx5_esw_for_each_vf_vport(peer_esw, i, peer_vport, + mlx5_core_max_vfs(peer_dev)) { + esw_set_peer_miss_rule_source_port(esw, peer_esw, spec, + peer_vport->vport); + flow = mlx5_add_flow_rules(mlx5_eswitch_get_slow_fdb(esw), + spec, &flow_act, &dest, 1); + if (IS_ERR(flow)) { + err = PTR_ERR(flow); + goto add_vf_flow_err; } + flows[peer_vport->index] = flow; } if (mlx5_core_ec_sriov_enabled(peer_dev)) { @@ -1347,7 +1343,8 @@ static void esw_del_fdb_peer_miss_rules(struct mlx5_eswitch *esw, mlx5_del_flow_rules(flows[peer_vport->index]); } - if (mlx5_core_is_ecpf_esw_manager(peer_dev)) { + if (mlx5_core_is_ecpf_esw_manager(peer_dev) && + mlx5_esw_host_functions_enabled(peer_dev)) { peer_vport = mlx5_eswitch_get_vport(peer_esw, MLX5_VPORT_PF); mlx5_del_flow_rules(flows[peer_vport->index]); } @@ -1368,7 +1365,7 @@ static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw) u8 *dmac_c; u8 *dmac_v; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { err = -ENOMEM; goto out; @@ -1430,7 +1427,7 @@ esw_add_restore_rule(struct mlx5_eswitch *esw, u32 tag) if (!mlx5_eswitch_reg_c1_loopback_supported(esw)) return ERR_PTR(-EOPNOTSUPP); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -2148,7 +2145,7 @@ mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, u16 vport, struct mlx5_flow_handle *flow_rule; struct mlx5_flow_spec *spec; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { flow_rule = ERR_PTR(-ENOMEM); goto out; @@ -2525,7 +2522,7 @@ int mlx5_esw_offloads_rep_add(struct mlx5_eswitch *esw, int rep_type; int err; - rep = kzalloc(sizeof(*rep), GFP_KERNEL); + rep = kzalloc_obj(*rep); if (!rep) return -ENOMEM; @@ -2861,7 +2858,7 @@ static int __esw_set_master_egress_rule(struct mlx5_core_dev *master, int err = 0; void *misc; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -3582,22 +3579,28 @@ static void esw_offloads_steering_cleanup(struct mlx5_eswitch *esw) } static void -esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out) +esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, int work_gen, + const u32 *out) { struct devlink *devlink; bool host_pf_disabled; u16 new_num_vfs; + devlink = priv_to_devlink(esw->dev); + devl_lock(devlink); + + /* Stale work from one or more mode changes ago. Bail out. */ + if (work_gen != atomic_read(&esw->esw_funcs.generation)) + goto unlock; + new_num_vfs = MLX5_GET(query_esw_functions_out, out, host_params_context.host_num_of_vfs); host_pf_disabled = MLX5_GET(query_esw_functions_out, out, host_params_context.host_pf_disabled); if (new_num_vfs == esw->esw_funcs.num_vfs || host_pf_disabled) - return; + goto unlock; - devlink = priv_to_devlink(esw->dev); - devl_lock(devlink); /* Number of VFs can only change from "0 to x" or "x to 0". */ if (esw->esw_funcs.num_vfs > 0) { mlx5_eswitch_unload_vf_vports(esw, esw->esw_funcs.num_vfs); @@ -3612,6 +3615,7 @@ esw_vfs_changed_event_handler(struct mlx5_eswitch *esw, const u32 *out) } } esw->esw_funcs.num_vfs = new_num_vfs; +unlock: devl_unlock(devlink); } @@ -3628,7 +3632,7 @@ static void esw_functions_changed_event_handler(struct work_struct *work) if (IS_ERR(out)) goto out; - esw_vfs_changed_event_handler(esw, out); + esw_vfs_changed_event_handler(esw, host_work->work_gen, out); kvfree(out); out: kfree(host_work); @@ -3640,7 +3644,7 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type struct mlx5_host_work *host_work; struct mlx5_eswitch *esw; - host_work = kzalloc(sizeof(*host_work), GFP_ATOMIC); + host_work = kzalloc_obj(*host_work, GFP_ATOMIC); if (!host_work) return NOTIFY_DONE; @@ -3648,6 +3652,7 @@ int mlx5_esw_funcs_changed_handler(struct notifier_block *nb, unsigned long type esw = container_of(esw_funcs, struct mlx5_eswitch, esw_funcs); host_work->esw = esw; + host_work->work_gen = atomic_read(&esw_funcs->generation); INIT_WORK(&host_work->work, esw_functions_changed_event_handler); queue_work(esw->work_queue, &host_work->work); @@ -4068,6 +4073,8 @@ int mlx5_devlink_eswitch_mode_set(struct devlink *devlink, u16 mode, if (mlx5_mode == MLX5_ESWITCH_LEGACY) esw->dev->priv.flags |= MLX5_PRIV_FLAGS_SWITCH_LEGACY; + if (mlx5_mode == MLX5_ESWITCH_OFFLOADS) + esw->dev->priv.flags &= ~MLX5_PRIV_FLAGS_SWITCH_LEGACY; mlx5_eswitch_disable_locked(esw); if (mlx5_mode == MLX5_ESWITCH_OFFLOADS) { if (mlx5_devlink_trap_get_num_active(esw->dev)) { @@ -4470,7 +4477,7 @@ int mlx5_esw_vport_vhca_id_map(struct mlx5_eswitch *esw, } vhca_id = vport->vhca_id; - vhca_map_entry = kmalloc(sizeof(*vhca_map_entry), GFP_KERNEL); + vhca_map_entry = kmalloc_obj(*vhca_map_entry); if (!vhca_map_entry) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c index 40bdc677f051..19f65d4c4def 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c @@ -132,7 +132,7 @@ mlx5_eswitch_termtbl_get_create(struct mlx5_eswitch *esw, if (found) goto tt_add_ref; - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); if (!tt) { err = -ENOMEM; goto tt_create_err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/events.c b/drivers/net/ethernet/mellanox/mlx5/core/events.c index 01c5f5990f9a..4d7f35b96876 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/events.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/events.c @@ -374,7 +374,7 @@ static int forward_event(struct notifier_block *nb, unsigned long event, void *d int mlx5_events_init(struct mlx5_core_dev *dev) { - struct mlx5_events *events = kzalloc(sizeof(*events), GFP_KERNEL); + struct mlx5_events *events = kzalloc_obj(*events); if (!events) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c index ccef64fb40b6..1f6bde5d7626 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/conn.c @@ -531,17 +531,13 @@ static int mlx5_fpga_conn_create_qp(struct mlx5_fpga_conn *conn, if (err) goto out; - conn->qp.rq.bufs = kvcalloc(conn->qp.rq.size, - sizeof(conn->qp.rq.bufs[0]), - GFP_KERNEL); + conn->qp.rq.bufs = kvzalloc_objs(conn->qp.rq.bufs[0], conn->qp.rq.size); if (!conn->qp.rq.bufs) { err = -ENOMEM; goto err_wq; } - conn->qp.sq.bufs = kvcalloc(conn->qp.sq.size, - sizeof(conn->qp.sq.bufs[0]), - GFP_KERNEL); + conn->qp.sq.bufs = kvzalloc_objs(conn->qp.sq.bufs[0], conn->qp.sq.size); if (!conn->qp.sq.bufs) { err = -ENOMEM; goto err_rq_bufs; @@ -816,7 +812,7 @@ struct mlx5_fpga_conn *mlx5_fpga_conn_create(struct mlx5_fpga_device *fdev, if (!attr->recv_cb) return ERR_PTR(-EINVAL); - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c index 1ec61164e6b5..4f0046cf6a1a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fpga/core.c @@ -59,7 +59,7 @@ static struct mlx5_fpga_device *mlx5_fpga_device_alloc(void) { struct mlx5_fpga_device *fdev; - fdev = kzalloc(sizeof(*fdev), GFP_KERNEL); + fdev = kzalloc_obj(*fdev); if (!fdev) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 0a6031a64c6f..2c3544880a30 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -947,7 +947,7 @@ alloc_flow_table(struct mlx5_flow_table_attr *ft_attr, u16 vport, struct mlx5_flow_table *ft; int ret; - ft = kzalloc(sizeof(*ft), GFP_KERNEL); + ft = kzalloc_obj(*ft); if (!ft) return ERR_PTR(-ENOMEM); @@ -1530,7 +1530,7 @@ static struct mlx5_flow_rule *alloc_rule(struct mlx5_flow_destination *dest) { struct mlx5_flow_rule *rule; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return NULL; @@ -1548,7 +1548,7 @@ static struct mlx5_flow_handle *alloc_handle(int num_rules) { struct mlx5_flow_handle *handle; - handle = kzalloc(struct_size(handle, rule, num_rules), GFP_KERNEL); + handle = kzalloc_flex(*handle, rule, num_rules); if (!handle) return NULL; @@ -2096,7 +2096,7 @@ static int build_match_list(struct match_list *match_head, if (unlikely(!tree_get_node(&g->node))) continue; - curr_match = kmalloc(sizeof(*curr_match), GFP_ATOMIC); + curr_match = kmalloc_obj(*curr_match, GFP_ATOMIC); if (!curr_match) { rcu_read_unlock(); free_match_list(match_head, ft_locked); @@ -2178,7 +2178,7 @@ add_rule_dup_match_fte(struct fs_fte *fte, int i = 0; if (!fte->dup) { - dup = kvzalloc(sizeof(*dup), GFP_KERNEL); + dup = kvzalloc_obj(*dup); if (!dup) return ERR_PTR(-ENOMEM); /* dup will be freed when the fte is freed @@ -2471,8 +2471,7 @@ mlx5_add_flow_rules(struct mlx5_flow_table *ft, goto unlock; } - gen_dest = kcalloc(num_dest + 1, sizeof(*dest), - GFP_KERNEL); + gen_dest = kzalloc_objs(*dest, num_dest + 1); if (!gen_dest) { handle = ERR_PTR(-ENOMEM); goto unlock; @@ -2849,7 +2848,7 @@ static struct fs_prio *_fs_create_prio(struct mlx5_flow_namespace *ns, { struct fs_prio *fs_prio; - fs_prio = kzalloc(sizeof(*fs_prio), GFP_KERNEL); + fs_prio = kzalloc_obj(*fs_prio); if (!fs_prio) return ERR_PTR(-ENOMEM); @@ -2889,7 +2888,7 @@ static struct mlx5_flow_namespace *fs_create_namespace(struct fs_prio *prio, { struct mlx5_flow_namespace *ns; - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_obj(*ns); if (!ns) return ERR_PTR(-ENOMEM); @@ -3020,7 +3019,7 @@ static struct mlx5_flow_root_namespace struct mlx5_flow_namespace *ns; /* Create the root namespace */ - root_ns = kzalloc(sizeof(*root_ns), GFP_KERNEL); + root_ns = kzalloc_obj(*root_ns); if (!root_ns) return NULL; @@ -3375,9 +3374,8 @@ static int init_rdma_transport_rx_root_ns(struct mlx5_flow_steering *steering) total_vports = mlx5_eswitch_get_total_vports(dev) ?: 1; steering->rdma_transport_rx_root_ns = - kcalloc(total_vports, - sizeof(*steering->rdma_transport_rx_root_ns), - GFP_KERNEL); + kzalloc_objs(*steering->rdma_transport_rx_root_ns, + total_vports); if (!steering->rdma_transport_rx_root_ns) return -ENOMEM; @@ -3408,9 +3406,8 @@ static int init_rdma_transport_tx_root_ns(struct mlx5_flow_steering *steering) total_vports = mlx5_eswitch_get_total_vports(dev) ?: 1; steering->rdma_transport_tx_root_ns = - kcalloc(total_vports, - sizeof(*steering->rdma_transport_tx_root_ns), - GFP_KERNEL); + kzalloc_objs(*steering->rdma_transport_tx_root_ns, + total_vports); if (!steering->rdma_transport_tx_root_ns) return -ENOMEM; @@ -3518,9 +3515,8 @@ static int create_fdb_fast_path(struct mlx5_flow_steering *steering) { int err; - steering->fdb_sub_ns = kcalloc(FDB_NUM_CHAINS, - sizeof(*steering->fdb_sub_ns), - GFP_KERNEL); + steering->fdb_sub_ns = kzalloc_objs(*steering->fdb_sub_ns, + FDB_NUM_CHAINS); if (!steering->fdb_sub_ns) return -ENOMEM; @@ -3674,7 +3670,7 @@ mlx5_fs_add_vport_acl_root_ns(struct mlx5_flow_steering *steering, if (xa_load(esw_acl_root_ns, vport_idx)) return -EEXIST; - vport_ns = kzalloc(sizeof(*vport_ns), GFP_KERNEL); + vport_ns = kzalloc_obj(*vport_ns); if (!vport_ns) return -ENOMEM; @@ -3993,7 +3989,7 @@ int mlx5_fs_core_alloc(struct mlx5_core_dev *dev) if (err) goto err; - steering = kzalloc(sizeof(*steering), GFP_KERNEL); + steering = kzalloc_obj(*steering); if (!steering) { err = -ENOMEM; goto err; @@ -4034,7 +4030,7 @@ int mlx5_fs_add_rx_underlay_qpn(struct mlx5_core_dev *dev, u32 underlay_qpn) struct mlx5_ft_underlay_qp *new_uqp; int err = 0; - new_uqp = kzalloc(sizeof(*new_uqp), GFP_KERNEL); + new_uqp = kzalloc_obj(*new_uqp); if (!new_uqp) return -ENOMEM; @@ -4137,7 +4133,7 @@ struct mlx5_modify_hdr *mlx5_modify_header_alloc(struct mlx5_core_dev *dev, if (!root) return ERR_PTR(-EOPNOTSUPP); - modify_hdr = kzalloc(sizeof(*modify_hdr), GFP_KERNEL); + modify_hdr = kzalloc_obj(*modify_hdr); if (!modify_hdr) return ERR_PTR(-ENOMEM); @@ -4178,7 +4174,7 @@ struct mlx5_pkt_reformat *mlx5_packet_reformat_alloc(struct mlx5_core_dev *dev, if (!root) return ERR_PTR(-EOPNOTSUPP); - pkt_reformat = kzalloc(sizeof(*pkt_reformat), GFP_KERNEL); + pkt_reformat = kzalloc_obj(*pkt_reformat); if (!pkt_reformat) return ERR_PTR(-ENOMEM); @@ -4226,7 +4222,7 @@ mlx5_create_match_definer(struct mlx5_core_dev *dev, if (!root) return ERR_PTR(-EOPNOTSUPP); - definer = kzalloc(sizeof(*definer), GFP_KERNEL); + definer = kzalloc_obj(*definer); if (!definer) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c index fe7caa910219..fdbdcadef63b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_counters.c @@ -234,11 +234,11 @@ static struct mlx5_fc *mlx5_fc_single_alloc(struct mlx5_core_dev *dev) struct mlx5_fc *counter; int err; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc_obj(*counter); if (!counter) return ERR_PTR(-ENOMEM); - fc_bulk = kzalloc(sizeof(*fc_bulk), GFP_KERNEL); + fc_bulk = kzalloc_obj(*fc_bulk); if (!fc_bulk) { err = -ENOMEM; goto free_counter; @@ -328,7 +328,7 @@ int mlx5_init_fc_stats(struct mlx5_core_dev *dev) { struct mlx5_fc_stats *fc_stats; - fc_stats = kzalloc(sizeof(*fc_stats), GFP_KERNEL); + fc_stats = kzalloc_obj(*fc_stats); if (!fc_stats) return -ENOMEM; dev->priv.fc_stats = fc_stats; @@ -460,7 +460,7 @@ static struct mlx5_fs_bulk *mlx5_fc_bulk_create(struct mlx5_core_dev *dev, alloc_bitmask = MLX5_CAP_GEN(dev, flow_counter_bulk_alloc); bulk_len = alloc_bitmask > 0 ? MLX5_FC_BULK_NUM_FCS(alloc_bitmask) : 1; - fc_bulk = kvzalloc(struct_size(fc_bulk, fcs, bulk_len), GFP_KERNEL); + fc_bulk = kvzalloc_flex(*fc_bulk, fcs, bulk_len); if (!fc_bulk) return NULL; @@ -572,10 +572,10 @@ mlx5_fc_local_create(u32 counter_id, u32 offset, u32 bulk_size) struct mlx5_fc_bulk *fc_bulk; struct mlx5_fc *counter; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc_obj(*counter); if (!counter) return ERR_PTR(-ENOMEM); - fc_bulk = kzalloc(sizeof(*fc_bulk), GFP_KERNEL); + fc_bulk = kzalloc_obj(*fc_bulk); if (!fc_bulk) { kfree(counter); return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c index f6abfd00d7e6..fbe11d5a1603 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_ft_pool.c @@ -26,7 +26,7 @@ int mlx5_ft_pool_init(struct mlx5_core_dev *dev) struct mlx5_ft_pool *ft_pool; int i; - ft_pool = kzalloc(sizeof(*ft_pool), GFP_KERNEL); + ft_pool = kzalloc_obj(*ft_pool); if (!ft_pool) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c index ae10665c53f3..07440c58713a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fw_reset.c @@ -899,7 +899,7 @@ int mlx5_fw_reset_init(struct mlx5_core_dev *dev) if (!MLX5_CAP_MCAM_REG(dev, mfrl)) return 0; - fw_reset = kzalloc(sizeof(*fw_reset), GFP_KERNEL); + fw_reset = kzalloc_obj(*fw_reset); if (!fw_reset) return -ENOMEM; fw_reset->wq = create_singlethread_workqueue("mlx5_fw_reset_events"); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/hwmon.c b/drivers/net/ethernet/mellanox/mlx5/core/hwmon.c index 4ba2636d7fb6..afcdebac9c4f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/hwmon.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/hwmon.c @@ -298,7 +298,7 @@ static struct mlx5_hwmon *mlx5_hwmon_alloc(struct mlx5_core_dev *mdev) u32 sensors_count; int err; - hwmon = kzalloc(sizeof(*mdev->hwmon), GFP_KERNEL); + hwmon = kzalloc_obj(*mdev->hwmon); if (!hwmon) return ERR_PTR(-ENOMEM); @@ -313,8 +313,8 @@ static struct mlx5_hwmon *mlx5_hwmon_alloc(struct mlx5_core_dev *mdev) hwmon->module_scount = mon_cap ? 1 : 0; sensors_count = hwmon->asic_platform_scount + hwmon->module_scount; - hwmon->temp_channel_desc = kcalloc(sensors_count, sizeof(*hwmon->temp_channel_desc), - GFP_KERNEL); + hwmon->temp_channel_desc = kzalloc_objs(*hwmon->temp_channel_desc, + sensors_count); if (!hwmon->temp_channel_desc) { err = -ENOMEM; goto err_free_hwmon; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c index 04444dad3a0d..4120afd097c3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c @@ -51,7 +51,7 @@ int mlx5i_pkey_qpn_ht_init(struct net_device *netdev) struct mlx5i_priv *ipriv = netdev_priv(netdev); struct mlx5i_pkey_qpn_ht *qpn_htbl; - qpn_htbl = kzalloc(sizeof(*qpn_htbl), GFP_KERNEL); + qpn_htbl = kzalloc_obj(*qpn_htbl); if (!qpn_htbl) return -ENOMEM; @@ -89,7 +89,7 @@ int mlx5i_pkey_add_qpn(struct net_device *netdev, u32 qpn) u8 key = hash_32(qpn, MLX5I_MAX_LOG_PKEY_SUP); struct qpn_to_netdev *new_node; - new_node = kzalloc(sizeof(*new_node), GFP_KERNEL); + new_node = kzalloc_obj(*new_node); if (!new_node) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c index 14d339eceb92..994fe83da4be 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/irq_affinity.c @@ -52,7 +52,7 @@ irq_pool_request_irq(struct mlx5_irq_pool *pool, struct irq_affinity_desc *af_de u32 irq_index; int err; - auto_desc = kvzalloc(sizeof(*auto_desc), GFP_KERNEL); + auto_desc = kvzalloc_obj(*auto_desc); if (!auto_desc) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c index 9fe47c836ebd..044adfdf9aa2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c @@ -272,7 +272,7 @@ static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev) struct mlx5_lag *ldev; int err; - ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + ldev = kzalloc_obj(*ldev); if (!ldev) return NULL; @@ -1869,8 +1869,12 @@ void mlx5_lag_disable_change(struct mlx5_core_dev *dev) mutex_lock(&ldev->lock); ldev->mode_changes_in_progress++; - if (__mlx5_lag_is_active(ldev)) - mlx5_disable_lag(ldev); + if (__mlx5_lag_is_active(ldev)) { + if (ldev->mode == MLX5_LAG_MODE_MPESW) + mlx5_lag_disable_mpesw(ldev); + else + mlx5_disable_lag(ldev); + } mutex_unlock(&ldev->lock); mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c index cdc99fe5c956..c4c2bf33ef35 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c @@ -291,7 +291,7 @@ mlx5_lag_init_fib_work(struct mlx5_lag *ldev, unsigned long event) { struct mlx5_fib_event_work *fib_work; - fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); + fib_work = kzalloc_obj(*fib_work, GFP_ATOMIC); if (WARN_ON(!fib_work)) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c index 04762562d7d9..74d5c2ed14ff 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.c @@ -65,7 +65,7 @@ static int mlx5_mpesw_metadata_set(struct mlx5_lag *ldev) return err; } -static int enable_mpesw(struct mlx5_lag *ldev) +static int mlx5_lag_enable_mpesw(struct mlx5_lag *ldev) { struct mlx5_core_dev *dev0; int err; @@ -126,7 +126,7 @@ static int enable_mpesw(struct mlx5_lag *ldev) return err; } -static void disable_mpesw(struct mlx5_lag *ldev) +void mlx5_lag_disable_mpesw(struct mlx5_lag *ldev) { if (ldev->mode == MLX5_LAG_MODE_MPESW) { mlx5_mpesw_metadata_cleanup(ldev); @@ -152,9 +152,9 @@ static void mlx5_mpesw_work(struct work_struct *work) } if (mpesww->op == MLX5_MPESW_OP_ENABLE) - mpesww->result = enable_mpesw(ldev); + mpesww->result = mlx5_lag_enable_mpesw(ldev); else if (mpesww->op == MLX5_MPESW_OP_DISABLE) - disable_mpesw(ldev); + mlx5_lag_disable_mpesw(ldev); unlock: mutex_unlock(&ldev->lock); mlx5_devcom_comp_unlock(devcom); @@ -171,7 +171,7 @@ static int mlx5_lag_mpesw_queue_work(struct mlx5_core_dev *dev, if (!ldev) return 0; - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); if (!work) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h index f5d9b5c97b0d..b767dbb4f457 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/mpesw.h @@ -31,6 +31,11 @@ int mlx5_lag_mpesw_do_mirred(struct mlx5_core_dev *mdev, bool mlx5_lag_is_mpesw(struct mlx5_core_dev *dev); void mlx5_lag_mpesw_disable(struct mlx5_core_dev *dev); int mlx5_lag_mpesw_enable(struct mlx5_core_dev *dev); +#ifdef CONFIG_MLX5_ESWITCH +void mlx5_lag_disable_mpesw(struct mlx5_lag *ldev); +#else +static inline void mlx5_lag_disable_mpesw(struct mlx5_lag *ldev) {} +#endif /* CONFIG_MLX5_ESWITCH */ #ifdef CONFIG_MLX5_ESWITCH void mlx5_mpesw_speed_update_work(struct work_struct *work); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c index d832a12ffec0..16c7d16215c4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c @@ -308,7 +308,7 @@ mlx5_lag_create_definer(struct mlx5_lag *ldev, enum netdev_lag_hash hash, return ERR_PTR(-EINVAL); dev = ldev->pf[first_idx].dev; - lag_definer = kzalloc(sizeof(*lag_definer), GFP_KERNEL); + lag_definer = kzalloc_obj(*lag_definer); if (!lag_definer) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c index 129725159a93..614cd57a40d7 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/aso.c @@ -311,7 +311,7 @@ struct mlx5_aso *mlx5_aso_create(struct mlx5_core_dev *mdev, u32 pdn) struct mlx5_aso *aso; int err; - aso = kzalloc(sizeof(*aso), GFP_KERNEL); + aso = kzalloc_obj(*aso); if (!aso) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 0ba0ef8bae42..bd4e042077af 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -1082,9 +1082,8 @@ static void mlx5_init_pin_config(struct mlx5_core_dev *mdev) return; clock->ptp_info.pin_config = - kcalloc(clock->ptp_info.n_pins, - sizeof(*clock->ptp_info.pin_config), - GFP_KERNEL); + kzalloc_objs(*clock->ptp_info.pin_config, + clock->ptp_info.n_pins); if (!clock->ptp_info.pin_config) return; clock->ptp_info.enable = mlx5_ptp_enable; @@ -1407,7 +1406,7 @@ static int mlx5_clock_alloc(struct mlx5_core_dev *mdev, bool shared) struct mlx5_clock_priv *cpriv; struct mlx5_clock *clock; - cpriv = kzalloc(sizeof(*cpriv), GFP_KERNEL); + cpriv = kzalloc_obj(*cpriv); if (!cpriv) return -ENOMEM; @@ -1604,7 +1603,7 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) return 0; } - clock_state = kzalloc(sizeof(*clock_state), GFP_KERNEL); + clock_state = kzalloc_obj(*clock_state); if (!clock_state) return -ENOMEM; clock_state->mdev = mdev; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c index 3a94b8f8031e..1c3607c5fa93 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/crypto.c @@ -293,7 +293,7 @@ mlx5_crypto_dek_bulk_create(struct mlx5_crypto_dek_pool *pool) int num_deks, base_obj_id; int err; - bulk = kzalloc(sizeof(*bulk), GFP_KERNEL); + bulk = kzalloc_obj(*bulk); if (!bulk) return ERR_PTR(-ENOMEM); @@ -611,7 +611,7 @@ struct mlx5_crypto_dek *mlx5_crypto_dek_create(struct mlx5_crypto_dek_pool *dek_ int obj_offset; int err; - dek = kzalloc(sizeof(*dek), GFP_KERNEL); + dek = kzalloc_obj(*dek); if (!dek) return ERR_PTR(-ENOMEM); @@ -683,7 +683,7 @@ mlx5_crypto_dek_pool_create(struct mlx5_core_dev *mdev, int key_purpose) { struct mlx5_crypto_dek_pool *pool; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); @@ -748,7 +748,7 @@ struct mlx5_crypto_dek_priv *mlx5_crypto_dek_init(struct mlx5_core_dev *mdev) if (!MLX5_CAP_CRYPTO(mdev, log_dek_max_alloc)) return NULL; - dek_priv = kzalloc(sizeof(*dek_priv), GFP_KERNEL); + dek_priv = kzalloc_obj(*dek_priv); if (!dek_priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c index e749618229bc..4b5ac2db55ce 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.c @@ -64,7 +64,7 @@ mlx5_devcom_dev_alloc(struct mlx5_core_dev *dev) { struct mlx5_devcom_dev *devc; - devc = kzalloc(sizeof(*devc), GFP_KERNEL); + devc = kzalloc_obj(*devc); if (!devc) return NULL; @@ -120,7 +120,7 @@ mlx5_devcom_comp_alloc(u64 id, const struct mlx5_devcom_match_attr *attr, { struct mlx5_devcom_comp *comp; - comp = kzalloc(sizeof(*comp), GFP_KERNEL); + comp = kzalloc_obj(*comp); if (!comp) return NULL; @@ -158,7 +158,7 @@ devcom_alloc_comp_dev(struct mlx5_devcom_dev *devc, { struct mlx5_devcom_comp_dev *devcom; - devcom = kzalloc(sizeof(*devcom), GFP_KERNEL); + devcom = kzalloc_obj(*devcom); if (!devcom) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c index 8115071c34a4..c7438b727823 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/dm.c @@ -28,7 +28,7 @@ struct mlx5_dm *mlx5_dm_create(struct mlx5_core_dev *dev) if (!(MLX5_CAP_GEN_64(dev, general_obj_types) & MLX5_GENERAL_OBJ_TYPES_CAP_SW_ICM)) return NULL; - dm = kzalloc(sizeof(*dm), GFP_KERNEL); + dm = kzalloc_obj(*dm); if (!dm) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c index 0a3c260af377..684cd9b5ffde 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_chains.c @@ -314,7 +314,7 @@ mlx5_chains_create_chain(struct mlx5_fs_chains *chains, u32 chain) struct fs_chain *chain_s = NULL; int err; - chain_s = kvzalloc(sizeof(*chain_s), GFP_KERNEL); + chain_s = kvzalloc_obj(*chain_s); if (!chain_s) return ERR_PTR(-ENOMEM); @@ -481,7 +481,7 @@ mlx5_chains_create_prio(struct mlx5_fs_chains *chains, if (IS_ERR(chain_s)) return ERR_CAST(chain_s); - prio_s = kvzalloc(sizeof(*prio_s), GFP_KERNEL); + prio_s = kvzalloc_obj(*prio_s); flow_group_in = kvzalloc(inlen, GFP_KERNEL); if (!prio_s || !flow_group_in) { err = -ENOMEM; @@ -728,7 +728,7 @@ mlx5_chains_init(struct mlx5_core_dev *dev, struct mlx5_chains_attr *attr) struct mlx5_fs_chains *chains; int err; - chains = kzalloc(sizeof(*chains), GFP_KERNEL); + chains = kzalloc_obj(*chains); if (!chains) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c index 7adad784ad46..14c339d02e99 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c @@ -359,7 +359,7 @@ mlx5_generate_ttc_rule(struct mlx5_core_dev *dev, struct mlx5_flow_table *ft, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -536,7 +536,7 @@ static int mlx5_create_ttc_table_groups(struct mlx5_ttc_table *ttc, int err; u8 *mc; - ttc->g = kcalloc(groups->num_groups, sizeof(*ttc->g), GFP_KERNEL); + ttc->g = kzalloc_objs(*ttc->g, groups->num_groups); if (!ttc->g) return -ENOMEM; in = kvzalloc(inlen, GFP_KERNEL); @@ -630,7 +630,7 @@ mlx5_generate_inner_ttc_rule(struct mlx5_core_dev *dev, int err = 0; u8 ipv; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -713,7 +713,7 @@ static int mlx5_create_inner_ttc_table_groups(struct mlx5_ttc_table *ttc, int err; u8 *mc; - ttc->g = kcalloc(groups->num_groups, sizeof(*ttc->g), GFP_KERNEL); + ttc->g = kzalloc_objs(*ttc->g, groups->num_groups); if (!ttc->g) return -ENOMEM; in = kvzalloc(inlen, GFP_KERNEL); @@ -804,7 +804,7 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev, return ERR_PTR(-EINVAL); } - ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); + ttc = kvzalloc_obj(*ttc); if (!ttc) return ERR_PTR(-ENOMEM); @@ -882,7 +882,7 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev, return ERR_PTR(-EINVAL); } - ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); + ttc = kvzalloc_obj(*ttc); if (!ttc) return ERR_PTR(-ENOMEM); @@ -1029,7 +1029,7 @@ mlx5_ttc_create_ipsec_outer_rule(struct mlx5_ttc_table *ttc, if (err) return ERR_PTR(err); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); @@ -1070,7 +1070,7 @@ mlx5_ttc_create_ipsec_inner_rule(struct mlx5_ttc_table *ttc, if (err) return ERR_PTR(err); - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c index 6dc83e871cd7..b90fea2b5d53 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/geneve.c @@ -134,8 +134,7 @@ void mlx5_geneve_tlv_option_del(struct mlx5_geneve *geneve) struct mlx5_geneve *mlx5_geneve_create(struct mlx5_core_dev *mdev) { - struct mlx5_geneve *geneve = - kzalloc(sizeof(*geneve), GFP_KERNEL); + struct mlx5_geneve *geneve = kzalloc_obj(*geneve); if (!geneve) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c index 30564d9b00e9..d6dc7bce855e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/hv_vhca.c @@ -42,7 +42,7 @@ struct mlx5_hv_vhca *mlx5_hv_vhca_create(struct mlx5_core_dev *dev) { struct mlx5_hv_vhca *hv_vhca; - hv_vhca = kzalloc(sizeof(*hv_vhca), GFP_KERNEL); + hv_vhca = kzalloc_obj(*hv_vhca); if (!hv_vhca) return ERR_PTR(-ENOMEM); @@ -98,7 +98,7 @@ void mlx5_hv_vhca_invalidate(void *context, u64 block_mask) struct mlx5_hv_vhca *hv_vhca = (struct mlx5_hv_vhca *)context; struct mlx5_hv_vhca_work *work; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return; @@ -152,7 +152,7 @@ mlx5_hv_vhca_control_agent_invalidate(struct mlx5_hv_vhca_agent *agent, u32 capabilities = 0; int err; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return; @@ -273,7 +273,7 @@ mlx5_hv_vhca_agent_create(struct mlx5_hv_vhca *hv_vhca, } mutex_unlock(&hv_vhca->agents_lock); - agent = kzalloc(sizeof(*agent), GFP_KERNEL); + agent = kzalloc_obj(*agent); if (!agent) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c index d524f0220513..28cb670ba33e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c @@ -139,7 +139,7 @@ ipsec_fs_roce_rx_rule_setup(struct mlx5_core_dev *mdev, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -242,7 +242,7 @@ static int ipsec_fs_roce_tx_mpv_rule_setup(struct mlx5_core_dev *mdev, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -850,7 +850,7 @@ struct mlx5_ipsec_fs *mlx5_ipsec_fs_roce_init(struct mlx5_core_dev *mdev, return NULL; } - roce_ipsec = kzalloc(sizeof(*roce_ipsec), GFP_KERNEL); + roce_ipsec = kzalloc_obj(*roce_ipsec); if (!roce_ipsec) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c index e6be2f01daf4..efc5167493c1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/macsec_fs.c @@ -267,7 +267,7 @@ static int macsec_fs_tx_create_crypto_table_groups(struct mlx5_macsec_flow_table int err; u8 *mc; - ft->g = kcalloc(TX_CRYPTO_TABLE_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, TX_CRYPTO_TABLE_NUM_GROUPS); if (!ft->g) return -ENOMEM; in = kvzalloc(inlen, GFP_KERNEL); @@ -404,7 +404,7 @@ static int macsec_fs_tx_create(struct mlx5_macsec_fs *macsec_fs) if (!ns) return -ENOMEM; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -713,7 +713,7 @@ static int macsec_fs_id_add(struct list_head *macsec_devices_list, u32 fs_id, rcu_read_unlock(); } - fs_id_iter = kzalloc(sizeof(*fs_id_iter), GFP_KERNEL); + fs_id_iter = kzalloc_obj(*fs_id_iter); if (!fs_id_iter) return -ENOMEM; @@ -725,7 +725,7 @@ static int macsec_fs_id_add(struct list_head *macsec_devices_list, u32 fs_id, } if (!macsec_device) { /* first time adding a SA to that device */ - macsec_device = kzalloc(sizeof(*macsec_device), GFP_KERNEL); + macsec_device = kzalloc_obj(*macsec_device); if (!macsec_device) { err = -ENOMEM; goto err_alloc_dev; @@ -813,7 +813,7 @@ macsec_fs_tx_add_rule(struct mlx5_macsec_fs *macsec_fs, tx_tables = &tx_fs->tables; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return NULL; @@ -821,7 +821,7 @@ macsec_fs_tx_add_rule(struct mlx5_macsec_fs *macsec_fs, if (err) goto out_spec; - macsec_rule = kzalloc(sizeof(*macsec_rule), GFP_KERNEL); + macsec_rule = kzalloc_obj(*macsec_rule); if (!macsec_rule) { macsec_fs_tx_ft_put(macsec_fs); goto out_spec; @@ -931,7 +931,7 @@ static int macsec_fs_tx_init(struct mlx5_macsec_fs *macsec_fs) struct mlx5_fc *flow_counter; int err; - tx_fs = kzalloc(sizeof(*tx_fs), GFP_KERNEL); + tx_fs = kzalloc_obj(*tx_fs); if (!tx_fs) return -ENOMEM; @@ -1055,7 +1055,7 @@ static int macsec_fs_rx_create_crypto_table_groups(struct mlx5_macsec_flow_table int err; u8 *mc; - ft->g = kcalloc(RX_CRYPTO_TABLE_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + ft->g = kzalloc_objs(*ft->g, RX_CRYPTO_TABLE_NUM_GROUPS); if (!ft->g) return -ENOMEM; @@ -1327,7 +1327,7 @@ static int macsec_fs_rx_roce_jump_to_rdma_rules_create(struct mlx5_macsec_fs *ma struct mlx5_flow_spec *spec; int err; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1510,7 +1510,7 @@ static int macsec_fs_rx_create(struct mlx5_macsec_fs *macsec_fs) if (!ns) return -ENOMEM; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -1739,7 +1739,7 @@ macsec_fs_rx_add_rule(struct mlx5_macsec_fs *macsec_fs, struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return NULL; @@ -1747,7 +1747,7 @@ macsec_fs_rx_add_rule(struct mlx5_macsec_fs *macsec_fs, if (err) goto out_spec; - macsec_rule = kzalloc(sizeof(*macsec_rule), GFP_KERNEL); + macsec_rule = kzalloc_obj(*macsec_rule); if (!macsec_rule) { macsec_fs_rx_ft_put(macsec_fs); goto out_spec; @@ -1847,7 +1847,7 @@ static int macsec_fs_rx_init(struct mlx5_macsec_fs *macsec_fs) struct mlx5_fc *flow_counter; int err; - rx_fs = kzalloc(sizeof(*rx_fs), GFP_KERNEL); + rx_fs = kzalloc_obj(*rx_fs); if (!rx_fs) return -ENOMEM; @@ -2132,11 +2132,11 @@ static int mlx5_macsec_fs_add_roce_rule_rx(struct mlx5_macsec_fs *macsec_fs, u32 struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; - rx_rule = kzalloc(sizeof(*rx_rule), GFP_KERNEL); + rx_rule = kzalloc_obj(*rx_rule); if (!rx_rule) { err = -ENOMEM; goto out; @@ -2201,11 +2201,11 @@ static int mlx5_macsec_fs_add_roce_rule_tx(struct mlx5_macsec_fs *macsec_fs, u32 struct mlx5_flow_spec *spec; int err = 0; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; - tx_rule = kzalloc(sizeof(*tx_rule), GFP_KERNEL); + tx_rule = kzalloc_obj(*tx_rule); if (!tx_rule) { err = -ENOMEM; goto out; @@ -2361,7 +2361,7 @@ mlx5_macsec_fs_init(struct mlx5_core_dev *mdev) struct mlx5_macsec_fs *macsec_fs; int err; - macsec_fs = kzalloc(sizeof(*macsec_fs), GFP_KERNEL); + macsec_fs = kzalloc_obj(*macsec_fs); if (!macsec_fs) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c index 4a88a42ae4f7..d408a5e63209 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.c @@ -103,7 +103,7 @@ int mlx5_mpfs_init(struct mlx5_core_dev *dev) if (!MLX5_ESWITCH_MANAGER(dev) || l2table_size == 1) return 0; - mpfs = kzalloc(sizeof(*mpfs), GFP_KERNEL); + mpfs = kzalloc_obj(*mpfs); if (!mpfs) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h index 9c63838ce1f3..051f68ab4cef 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/mpfs.h @@ -72,7 +72,7 @@ struct l2addr_node { int ix = MLX5_L2_ADDR_HASH(mac); \ type *ptr = NULL; \ \ - ptr = kzalloc(sizeof(type), gfp); \ + ptr = kzalloc_obj(type, gfp); \ if (ptr) { \ ether_addr_copy(ptr->node.addr, mac); \ hlist_add_head(&ptr->node.hlist, &(hash)[ix]);\ diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c index 8e17daae48af..954942ad93c5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/sd.c @@ -187,7 +187,7 @@ static int sd_init(struct mlx5_core_dev *dev) return 0; } - sd = kzalloc(sizeof(*sd), GFP_KERNEL); + sd = kzalloc_obj(*sd); if (!sd) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c index ef06fe6cbb51..997be91f0a13 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/st.c @@ -59,7 +59,7 @@ struct mlx5_st *mlx5_st_create(struct mlx5_core_dev *dev) if (ret) return NULL; - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) goto end; @@ -124,7 +124,7 @@ int mlx5_st_alloc_index(struct mlx5_core_dev *dev, enum tph_mem_type mem_type, } } - idx_data = kzalloc(sizeof(*idx_data), GFP_KERNEL); + idx_data = kzalloc_obj(*idx_data); if (!idx_data) { ret = -ENOMEM; goto end; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c index e223e0e46433..d9be0d9c9a13 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/tout.c @@ -37,7 +37,7 @@ int mlx5_tout_init(struct mlx5_core_dev *dev) { int i; - dev->timeouts = kmalloc(sizeof(*dev->timeouts), GFP_KERNEL); + dev->timeouts = kmalloc_obj(*dev->timeouts); if (!dev->timeouts) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c index 304912637c35..c2292cab4592 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c @@ -103,7 +103,7 @@ int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port) struct mlx5_vxlan_port *vxlanp; int ret; - vxlanp = kzalloc(sizeof(*vxlanp), GFP_KERNEL); + vxlanp = kzalloc_obj(*vxlanp); if (!vxlanp) return -ENOMEM; vxlanp->udp_port = port; @@ -151,7 +151,7 @@ struct mlx5_vxlan *mlx5_vxlan_create(struct mlx5_core_dev *mdev) if (!MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan) || !mlx5_core_is_pf(mdev)) return ERR_PTR(-EOPNOTSUPP); - vxlan = kzalloc(sizeof(*vxlan), GFP_KERNEL); + vxlan = kzalloc_obj(*vxlan); if (!vxlan) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 55b4e0cceae2..fdc3ba20912e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1792,7 +1792,7 @@ static int mlx5_hca_caps_alloc(struct mlx5_core_dev *dev) int i; for (i = 0; i < ARRAY_SIZE(types); i++) { - cap = kzalloc(sizeof(*cap), GFP_KERNEL); + cap = kzalloc_obj(*cap); if (!cap) goto err; type = types[i]; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c index cd68c4b2c0bf..5ccb3ce98acb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pagealloc.c @@ -107,7 +107,7 @@ static struct rb_root *page_root_per_function(struct mlx5_core_dev *dev, u32 fun if (root) return root; - root = kzalloc(sizeof(*root), GFP_KERNEL); + root = kzalloc_obj(*root); if (!root) return ERR_PTR(-ENOMEM); @@ -148,7 +148,7 @@ static int insert_page(struct mlx5_core_dev *dev, u64 addr, struct page *page, u return -EEXIST; } - nfp = kzalloc(sizeof(*nfp), GFP_KERNEL); + nfp = kzalloc_obj(*nfp); if (!nfp) return -ENOMEM; @@ -639,7 +639,7 @@ static int req_pages_handler(struct notifier_block *nb, RELEASE_ALL_PAGES_MASK; mlx5_core_dbg(dev, "page request for func 0x%x, npages %d, release_all %d\n", func_id, npages, release_all); - req = kzalloc(sizeof(*req), GFP_ATOMIC); + req = kzalloc_obj(*req, GFP_ATOMIC); if (!req) { mlx5_core_warn(dev, "failed to allocate pages request\n"); return NOTIFY_DONE; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c index aa3b5878e3da..e051b9a939ee 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/pci_irq.c @@ -261,7 +261,7 @@ struct mlx5_irq *mlx5_irq_alloc(struct mlx5_irq_pool *pool, int i, struct mlx5_irq *irq; int err; - irq = kzalloc(sizeof(*irq), GFP_KERNEL); + irq = kzalloc_obj(*irq); if (!irq || !zalloc_cpumask_var(&irq->mask, GFP_KERNEL)) { kfree(irq); return ERR_PTR(-ENOMEM); @@ -471,7 +471,7 @@ struct mlx5_irq *mlx5_ctrl_irq_request(struct mlx5_core_dev *dev) struct irq_affinity_desc *af_desc; struct mlx5_irq *irq; - af_desc = kvzalloc(sizeof(*af_desc), GFP_KERNEL); + af_desc = kvzalloc_obj(*af_desc); if (!af_desc) return ERR_PTR(-ENOMEM); @@ -556,7 +556,7 @@ struct mlx5_irq *mlx5_irq_request_vector(struct mlx5_core_dev *dev, u16 cpu, struct irq_affinity_desc *af_desc; struct mlx5_irq *irq; - af_desc = kvzalloc(sizeof(*af_desc), GFP_KERNEL); + af_desc = kvzalloc_obj(*af_desc); if (!af_desc) return ERR_PTR(-ENOMEM); @@ -578,7 +578,7 @@ static struct mlx5_irq_pool * irq_pool_alloc(struct mlx5_core_dev *dev, int start, int size, char *name, u32 min_threshold, u32 max_threshold) { - struct mlx5_irq_pool *pool = kvzalloc(sizeof(*pool), GFP_KERNEL); + struct mlx5_irq_pool *pool = kvzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c index 5c552b71e371..e372484960ca 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/rdma.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/rdma.c @@ -41,7 +41,7 @@ static int mlx5_rdma_enable_roce_steering(struct mlx5_core_dev *dev) flow_group_in = kvzalloc(inlen, GFP_KERNEL); if (!flow_group_in) return -ENOMEM; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) { kvfree(flow_group_in); return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/rl.c b/drivers/net/ethernet/mellanox/mlx5/core/rl.c index 39a209b9b684..f2a96d5b45f5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/rl.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/rl.c @@ -247,8 +247,7 @@ static int mlx5_rl_table_get(struct mlx5_rl_table *table) return 0; } - table->rl_entry = kcalloc(table->max_size, sizeof(struct mlx5_rl_entry), - GFP_KERNEL); + table->rl_entry = kzalloc_objs(struct mlx5_rl_entry, table->max_size); if (!table->rl_entry) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c index f310bde3d11f..e75cbf333898 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c @@ -99,7 +99,7 @@ static void mlx5_sf_dev_add(struct mlx5_core_dev *dev, u16 sf_index, u16 fn_id, goto add_err; } - sf_dev = kzalloc(sizeof(*sf_dev), GFP_KERNEL); + sf_dev = kzalloc_obj(*sf_dev); if (!sf_dev) { mlx5_adev_idx_free(id); err = -ENOMEM; @@ -280,7 +280,7 @@ static void mlx5_sf_dev_queue_active_works(struct work_struct *_work) continue; sw_func_id = MLX5_GET(query_vhca_state_out, out, vhca_state_context.sw_function_id); - work_ctx = kzalloc(sizeof(*work_ctx), GFP_KERNEL); + work_ctx = kzalloc_obj(*work_ctx); if (!work_ctx) return; @@ -336,7 +336,7 @@ void mlx5_sf_dev_table_create(struct mlx5_core_dev *dev) if (!mlx5_sf_dev_supported(dev)) return; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) { err = -ENOMEM; goto table_err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c index b82323b8449e..8503e532f423 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c @@ -70,7 +70,7 @@ mlx5_sf_alloc(struct mlx5_sf_table *table, struct mlx5_eswitch *esw, goto id_err; } - sf = kzalloc(sizeof(*sf), GFP_KERNEL); + sf = kzalloc_obj(*sf); if (!sf) { err = -ENOMEM; goto alloc_err; @@ -509,7 +509,7 @@ int mlx5_sf_table_init(struct mlx5_core_dev *dev) if (!mlx5_sf_table_supported(dev) || !mlx5_vhca_event_supported(dev)) return 0; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c index bd968f3b3855..049dfd431618 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/hw_table.c @@ -233,7 +233,7 @@ static int mlx5_sf_hw_table_hwc_init(struct mlx5_sf_hwc_table *hwc, u16 max_fn, if (!max_fn) return 0; - sfs = kcalloc(max_fn, sizeof(*sfs), GFP_KERNEL); + sfs = kzalloc_objs(*sfs, max_fn); if (!sfs) return -ENOMEM; @@ -298,7 +298,7 @@ int mlx5_sf_hw_table_init(struct mlx5_core_dev *dev) if (!max_fn && !max_ext_fn) return 0; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) { err = -ENOMEM; goto alloc_err; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/vhca_event.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/vhca_event.c index b04cf6cf8956..9c4a559d268c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sf/vhca_event.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/vhca_event.c @@ -114,7 +114,7 @@ mlx5_vhca_state_change_notifier(struct notifier_block *nb, unsigned long type, v struct mlx5_eqe *eqe = data; int wq_idx; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return NOTIFY_DONE; INIT_WORK(&work->work, &mlx5_vhca_state_work_handler); @@ -153,7 +153,7 @@ int mlx5_vhca_event_init(struct mlx5_core_dev *dev) if (!mlx5_vhca_event_supported(dev)) return 0; - events = kzalloc(sizeof(*events), GFP_KERNEL); + events = kzalloc_obj(*events); if (!events) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c index a2fc937d5461..bf6f631cf2ce 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/sriov.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/sriov.c @@ -47,7 +47,7 @@ static int sriov_restore_guids(struct mlx5_core_dev *dev, int vf, u16 func_id) if (sriov->vfs_ctx[vf].node_guid || sriov->vfs_ctx[vf].port_guid || sriov->vfs_ctx[vf].policy != MLX5_POLICY_INVALID) { - in = kzalloc(sizeof(*in), GFP_KERNEL); + in = kzalloc_obj(*in); if (!in) return -ENOMEM; @@ -193,7 +193,9 @@ static int mlx5_sriov_enable(struct pci_dev *pdev, int num_vfs) err = pci_enable_sriov(pdev, num_vfs); if (err) { mlx5_core_warn(dev, "pci_enable_sriov failed : %d\n", err); + devl_lock(devlink); mlx5_device_disable_sriov(dev, num_vfs, true, true); + devl_unlock(devlink); } return err; } @@ -305,7 +307,7 @@ int mlx5_sriov_init(struct mlx5_core_dev *dev) sriov->max_vfs = mlx5_get_max_vfs(dev); sriov->num_vfs = pci_num_vf(pdev); sriov->max_ec_vfs = mlx5_core_ec_sriov_enabled(dev) ? pci_sriov_get_totalvfs(dev->pdev) : 0; - sriov->vfs_ctx = kcalloc(total_vfs, sizeof(*sriov->vfs_ctx), GFP_KERNEL); + sriov->vfs_ctx = kzalloc_objs(*sriov->vfs_ctx, total_vfs); if (!sriov->vfs_ctx) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c index fe56b59e24c5..23e86f292022 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action.c @@ -92,7 +92,7 @@ static int hws_action_get_shared_stc_nic(struct mlx5hws_context *ctx, return 0; } - shared_stc = kzalloc(sizeof(*shared_stc), GFP_KERNEL); + shared_stc = kzalloc_obj(*shared_stc); if (!shared_stc) { ret = -ENOMEM; goto unlock_and_out; @@ -632,7 +632,7 @@ hws_action_create_generic_bulk(struct mlx5hws_context *ctx, if (!hws_action_validate_hws_action(ctx, flags)) return NULL; - action = kcalloc(bulk_sz, sizeof(*action), GFP_KERNEL); + action = kzalloc_objs(*action, bulk_sz); if (!action) return NULL; @@ -1383,7 +1383,7 @@ mlx5hws_action_create_dest_array(struct mlx5hws_context *ctx, size_t num_dest, return NULL; } - dest_list = kcalloc(num_dest, sizeof(*dest_list), GFP_KERNEL); + dest_list = kzalloc_objs(*dest_list, num_dest); if (!dest_list) return NULL; @@ -1477,7 +1477,7 @@ mlx5hws_action_create_insert_header(struct mlx5hws_context *ctx, if (!action) return NULL; - reformat_hdrs = kcalloc(num_of_hdrs, sizeof(*reformat_hdrs), GFP_KERNEL); + reformat_hdrs = kzalloc_objs(*reformat_hdrs, num_of_hdrs); if (!reformat_hdrs) goto free_action; @@ -1557,7 +1557,7 @@ hws_action_create_dest_match_range_definer(struct mlx5hws_context *ctx) __be32 *tag; int ret; - definer = kzalloc(sizeof(*definer), GFP_KERNEL); + definer = kzalloc_obj(*definer); if (!definer) return NULL; @@ -1600,7 +1600,7 @@ hws_action_create_dest_match_range_table(struct mlx5hws_context *ctx, return NULL; } - table_ste = kzalloc(sizeof(*table_ste), GFP_KERNEL); + table_ste = kzalloc_obj(*table_ste); if (!table_ste) return NULL; @@ -2019,7 +2019,7 @@ __must_hold(&ctx->ctrl_lock) return 0; } - default_stc = kzalloc(sizeof(*default_stc), GFP_KERNEL); + default_stc = kzalloc_obj(*default_stc); if (!default_stc) return -ENOMEM; @@ -2621,7 +2621,7 @@ mlx5hws_action_template_create(enum mlx5hws_action_type action_type[]) u8 num_actions = 0; int i; - at = kzalloc(sizeof(*at), GFP_KERNEL); + at = kzalloc_obj(*at); if (!at) return NULL; @@ -2629,7 +2629,7 @@ mlx5hws_action_template_create(enum mlx5hws_action_type action_type[]) ; at->num_actions = num_actions - 1; - at->action_type_arr = kcalloc(num_actions, sizeof(*action_type), GFP_KERNEL); + at->action_type_arr = kzalloc_objs(*action_type, num_actions); if (!at->action_type_arr) goto free_at; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action_ste_pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action_ste_pool.c index 5766a9c82f96..6145f71442e4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action_ste_pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/action_ste_pool.c @@ -141,7 +141,7 @@ hws_action_ste_table_alloc(struct mlx5hws_action_ste_pool_element *parent_elem) MLX5HWS_ACTION_STE_TABLE_INIT_LOG_SZ, MLX5HWS_ACTION_STE_TABLE_MAX_LOG_SZ); - action_tbl = kzalloc(sizeof(*action_tbl), GFP_KERNEL); + action_tbl = kzalloc_obj(*action_tbl); if (!action_tbl) return ERR_PTR(-ENOMEM); @@ -329,7 +329,7 @@ int mlx5hws_action_ste_pool_init(struct mlx5hws_context *ctx) size_t queues = ctx->queues; int i, err; - pool = kcalloc(queues, sizeof(*pool), GFP_KERNEL); + pool = kzalloc_objs(*pool, queues); if (!pool) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/buddy.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/buddy.c index b9aef80ba094..02736ecf817d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/buddy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/buddy.c @@ -54,7 +54,7 @@ struct mlx5hws_buddy_mem *mlx5hws_buddy_create(u32 max_order) { struct mlx5hws_buddy_mem *buddy; - buddy = kzalloc(sizeof(*buddy), GFP_KERNEL); + buddy = kzalloc_obj(*buddy); if (!buddy) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c index 6ef0c4be27e1..6dcd9c2a78aa 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc.c @@ -236,7 +236,7 @@ int mlx5hws_bwc_matcher_create_simple(struct mlx5hws_bwc_matcher *bwc_matcher, struct mlx5hws_matcher_attr attr = {0}; int i; - bwc_matcher->rules = kcalloc(bwc_queues, sizeof(*bwc_matcher->rules), GFP_KERNEL); + bwc_matcher->rules = kzalloc_objs(*bwc_matcher->rules, bwc_queues); if (!bwc_matcher->rules) goto err; @@ -253,8 +253,8 @@ int mlx5hws_bwc_matcher_create_simple(struct mlx5hws_bwc_matcher *bwc_matcher, bwc_matcher->priority = priority; bwc_matcher->size_of_at_array = MLX5HWS_BWC_MATCHER_ATTACH_AT_NUM; - bwc_matcher->at = kcalloc(bwc_matcher->size_of_at_array, - sizeof(*bwc_matcher->at), GFP_KERNEL); + bwc_matcher->at = kzalloc_objs(*bwc_matcher->at, + bwc_matcher->size_of_at_array); if (!bwc_matcher->at) goto free_bwc_matcher_rules; @@ -332,7 +332,7 @@ mlx5hws_bwc_matcher_create(struct mlx5hws_table *table, return NULL; } - bwc_matcher = kzalloc(sizeof(*bwc_matcher), GFP_KERNEL); + bwc_matcher = kzalloc_obj(*bwc_matcher); if (!bwc_matcher) return NULL; @@ -481,11 +481,11 @@ mlx5hws_bwc_rule_alloc(struct mlx5hws_bwc_matcher *bwc_matcher) { struct mlx5hws_bwc_rule *bwc_rule; - bwc_rule = kzalloc(sizeof(*bwc_rule), GFP_KERNEL); + bwc_rule = kzalloc_obj(*bwc_rule); if (unlikely(!bwc_rule)) goto out_err; - bwc_rule->rule = kzalloc(sizeof(*bwc_rule->rule), GFP_KERNEL); + bwc_rule->rule = kzalloc_obj(*bwc_rule->rule); if (unlikely(!bwc_rule->rule)) goto free_rule; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c index f22eaf506d28..e624f5da96c8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/cmd.c @@ -299,7 +299,7 @@ mlx5hws_cmd_forward_tbl_create(struct mlx5_core_dev *mdev, struct mlx5hws_cmd_forward_tbl *tbl; int ret; - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (!tbl) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c index 428dae869706..c1a81f78d349 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/context.c @@ -192,7 +192,7 @@ struct mlx5hws_context *mlx5hws_context_open(struct mlx5_core_dev *mdev, struct mlx5hws_context *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -201,7 +201,7 @@ struct mlx5hws_context *mlx5hws_context_open(struct mlx5_core_dev *mdev, mutex_init(&ctx->ctrl_lock); xa_init(&ctx->peer_ctx_xa); - ctx->caps = kzalloc(sizeof(*ctx->caps), GFP_KERNEL); + ctx->caps = kzalloc_obj(*ctx->caps); if (!ctx->caps) goto free_ctx; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c index 82fd122d4284..bcbd86a88b6b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c @@ -1688,7 +1688,7 @@ hws_definer_alloc_compressed_fc(struct mlx5hws_definer_fc *fc) u32 fc_sz = 0; int i; - compressed_fc = kcalloc(definer_size, sizeof(*compressed_fc), GFP_KERNEL); + compressed_fc = kzalloc_objs(*compressed_fc, definer_size); if (!compressed_fc) return NULL; @@ -1731,7 +1731,7 @@ hws_definer_alloc_fc(struct mlx5hws_context *ctx, struct mlx5hws_definer_fc *fc; int i; - fc = kcalloc(len, sizeof(*fc), GFP_KERNEL); + fc = kzalloc_objs(*fc, len); if (!fc) return NULL; @@ -2139,7 +2139,7 @@ int mlx5hws_definer_init_cache(struct mlx5hws_definer_cache **cache) { struct mlx5hws_definer_cache *new_cache; - new_cache = kzalloc(sizeof(*new_cache), GFP_KERNEL); + new_cache = kzalloc_obj(*new_cache); if (!new_cache) return -ENOMEM; @@ -2183,7 +2183,7 @@ int mlx5hws_definer_get_obj(struct mlx5hws_context *ctx, if (ret) return -1; - cached_definer = kzalloc(sizeof(*cached_definer), GFP_KERNEL); + cached_definer = kzalloc_obj(*cached_definer); if (!cached_definer) goto free_definer_obj; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c index 6a4c4cccd643..aca77853abb8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws.c @@ -478,7 +478,7 @@ mlx5_fs_get_cached_hws_data(struct xarray *cache_xa, unsigned long index) xa_lock(cache_xa); fs_hws_data = xa_load(cache_xa, index); if (!fs_hws_data) { - fs_hws_data = kzalloc(sizeof(*fs_hws_data), GFP_ATOMIC); + fs_hws_data = kzalloc_obj(*fs_hws_data, GFP_ATOMIC); if (!fs_hws_data) { xa_unlock(cache_xa); return NULL; @@ -759,22 +759,19 @@ static int mlx5_fs_fte_get_hws_actions(struct mlx5_flow_root_namespace *ns, int num_actions = 0; int err; - *ractions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, sizeof(**ractions), - GFP_KERNEL); + *ractions = kzalloc_objs(**ractions, MLX5_FLOW_CONTEXT_ACTION_MAX); if (!*ractions) { err = -ENOMEM; goto out_err; } - fs_actions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, - sizeof(*fs_actions), GFP_KERNEL); + fs_actions = kzalloc_objs(*fs_actions, MLX5_FLOW_CONTEXT_ACTION_MAX); if (!fs_actions) { err = -ENOMEM; goto free_actions_alloc; } - dest_actions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, - sizeof(*dest_actions), GFP_KERNEL); + dest_actions = kzalloc_objs(*dest_actions, MLX5_FLOW_CONTEXT_ACTION_MAX); if (!dest_actions) { err = -ENOMEM; goto free_fs_actions_alloc; @@ -1239,7 +1236,7 @@ mlx5_fs_get_pr_encap_pool(struct mlx5_core_dev *dev, struct xarray *pr_pools, if (pr_pool) return pr_pool; - pr_pool = kzalloc(sizeof(*pr_pool), GFP_KERNEL); + pr_pool = kzalloc_obj(*pr_pool); if (!pr_pool) return ERR_PTR(-ENOMEM); err = mlx5_fs_hws_pr_pool_init(pr_pool, dev, size, reformat_type); @@ -1430,7 +1427,7 @@ mlx5_fs_create_mh_pool(struct mlx5_core_dev *dev, struct mlx5_fs_pool *pool; int err; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); err = mlx5_fs_hws_mh_pool_init(pool, dev, pattern); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.c index 5bc8e97ecf1c..86828e329187 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/fs_hws_pools.c @@ -117,7 +117,7 @@ mlx5_fs_hws_pr_bulk_create(struct mlx5_core_dev *dev, void *pool_ctx) return NULL; pr_pool_ctx = pool_ctx; bulk_len = MLX5_FS_HWS_DEFAULT_BULK_LEN; - pr_bulk = kvzalloc(struct_size(pr_bulk, prs_data, bulk_len), GFP_KERNEL); + pr_bulk = kvzalloc_flex(*pr_bulk, prs_data, bulk_len); if (!pr_bulk) return NULL; @@ -186,7 +186,7 @@ int mlx5_fs_hws_pr_pool_init(struct mlx5_fs_pool *pr_pool, reformat_type != MLX5HWS_ACTION_TYP_REFORMAT_L2_TO_TNL_L2) return -EOPNOTSUPP; - pr_pool_ctx = kzalloc(sizeof(*pr_pool_ctx), GFP_KERNEL); + pr_pool_ctx = kzalloc_obj(*pr_pool_ctx); if (!pr_pool_ctx) return -ENOMEM; pr_pool_ctx->reformat_type = reformat_type; @@ -273,7 +273,7 @@ mlx5_fs_hws_mh_bulk_create(struct mlx5_core_dev *dev, void *pool_ctx) pattern = pool_ctx; bulk_len = MLX5_FS_HWS_DEFAULT_BULK_LEN; - mh_bulk = kvzalloc(struct_size(mh_bulk, mhs_data, bulk_len), GFP_KERNEL); + mh_bulk = kvzalloc_flex(*mh_bulk, mhs_data, bulk_len); if (!mh_bulk) return NULL; @@ -331,7 +331,7 @@ int mlx5_fs_hws_mh_pool_init(struct mlx5_fs_pool *fs_hws_mh_pool, { struct mlx5hws_action_mh_pattern *pool_pattern; - pool_pattern = kzalloc(sizeof(*pool_pattern), GFP_KERNEL); + pool_pattern = kzalloc_obj(*pool_pattern); if (!pool_pattern) return -ENOMEM; pool_pattern->data = kmemdup(pattern->data, pattern->sz, GFP_KERNEL); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c index 32f87fdf3213..51aae5a6857a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/matcher.c @@ -912,7 +912,7 @@ hws_matcher_create_col_matcher(struct mlx5hws_matcher *matcher) !hws_matcher_requires_col_tbl(size_tx->rule.num_log)) return 0; - col_matcher = kzalloc(sizeof(*matcher), GFP_KERNEL); + col_matcher = kzalloc_obj(*matcher); if (!col_matcher) return -ENOMEM; @@ -1084,14 +1084,13 @@ hws_matcher_set_templates(struct mlx5hws_matcher *matcher, return -EOPNOTSUPP; } - matcher->mt = kcalloc(num_of_mt, sizeof(*matcher->mt), GFP_KERNEL); + matcher->mt = kzalloc_objs(*matcher->mt, num_of_mt); if (!matcher->mt) return -ENOMEM; matcher->size_of_at_array = num_of_at + matcher->attr.max_num_of_at_attach; - matcher->at = kvcalloc(matcher->size_of_at_array, sizeof(*matcher->at), - GFP_KERNEL); + matcher->at = kvzalloc_objs(*matcher->at, matcher->size_of_at_array); if (!matcher->at) { mlx5hws_err(ctx, "Failed to allocate action template array\n"); ret = -ENOMEM; @@ -1133,7 +1132,7 @@ mlx5hws_matcher_create(struct mlx5hws_table *tbl, struct mlx5hws_matcher *matcher; int ret; - matcher = kzalloc(sizeof(*matcher), GFP_KERNEL); + matcher = kzalloc_obj(*matcher); if (!matcher) return NULL; @@ -1179,7 +1178,7 @@ mlx5hws_match_template_create(struct mlx5hws_context *ctx, { struct mlx5hws_match_template *mt; - mt = kzalloc(sizeof(*mt), GFP_KERNEL); + mt = kzalloc_obj(*mt); if (!mt) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c index d56271a9e4f0..9af449c2b4d5 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pat_arg.c @@ -78,7 +78,7 @@ int mlx5hws_pat_init_pattern_cache(struct mlx5hws_pattern_cache **cache) { struct mlx5hws_pattern_cache *new_cache; - new_cache = kzalloc(sizeof(*new_cache), GFP_KERNEL); + new_cache = kzalloc_obj(*new_cache); if (!new_cache) return -ENOMEM; @@ -168,7 +168,7 @@ mlx5hws_pat_add_pattern_to_cache(struct mlx5hws_pattern_cache *cache, { struct mlx5hws_pattern_cache_item *cached_pattern; - cached_pattern = kzalloc(sizeof(*cached_pattern), GFP_KERNEL); + cached_pattern = kzalloc_obj(*cached_pattern); if (!cached_pattern) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c index 7b5071c3df36..3a549c9db71a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/pool.c @@ -41,7 +41,7 @@ hws_pool_create_one_resource(struct mlx5hws_pool *pool, u32 log_range, u32 obj_id = 0; int ret; - resource = kzalloc(sizeof(*resource), GFP_KERNEL); + resource = kzalloc_obj(*resource); if (!resource) return NULL; @@ -347,7 +347,7 @@ mlx5hws_pool_create(struct mlx5hws_context *ctx, struct mlx5hws_pool_attr *pool_ enum mlx5hws_db_type res_db_type; struct mlx5hws_pool *pool; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/rule.c index a94f094e72ba..0d4cb2b2393b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/rule.c @@ -136,7 +136,7 @@ hws_rule_save_resize_info(struct mlx5hws_rule *rule, /* resize_info might already exist (if we're in update flow) */ if (likely(!rule->resize_info)) { - rule->resize_info = kzalloc(sizeof(*rule->resize_info), GFP_KERNEL); + rule->resize_info = kzalloc_obj(*rule->resize_info); if (unlikely(!rule->resize_info)) { pr_warn("HWS: resize info isn't allocated for rule\n"); return; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c index 7510c46e58a5..aed009aec4fe 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c @@ -701,7 +701,7 @@ static int hws_send_ring_alloc_sq(struct mlx5_core_dev *mdev, wq->db = &wq->db[MLX5_SND_DBR]; buf_sz = queue->num_entries * MAX_WQES_PER_RULE; - sq->dep_wqe = kcalloc(queue->num_entries, sizeof(*sq->dep_wqe), GFP_KERNEL); + sq->dep_wqe = kzalloc_objs(*sq->dep_wqe, queue->num_entries); if (!sq->dep_wqe) { err = -ENOMEM; goto destroy_wq_cyc; @@ -1033,9 +1033,8 @@ static int mlx5hws_send_queue_open(struct mlx5hws_context *ctx, queue->num_entries = roundup_pow_of_two(queue_size); queue->used_entries = 0; - queue->completed.entries = kcalloc(queue->num_entries, - sizeof(queue->completed.entries[0]), - GFP_KERNEL); + queue->completed.entries = kzalloc_objs(queue->completed.entries[0], + queue->num_entries); if (!queue->completed.entries) return -ENOMEM; @@ -1094,16 +1093,14 @@ static int hws_bwc_send_queues_init(struct mlx5hws_context *ctx) ctx->queues += bwc_queues; - ctx->bwc_send_queue_locks = kcalloc(bwc_queues, - sizeof(*ctx->bwc_send_queue_locks), - GFP_KERNEL); + ctx->bwc_send_queue_locks = kzalloc_objs(*ctx->bwc_send_queue_locks, + bwc_queues); if (!ctx->bwc_send_queue_locks) return -ENOMEM; - ctx->bwc_lock_class_keys = kcalloc(bwc_queues, - sizeof(*ctx->bwc_lock_class_keys), - GFP_KERNEL); + ctx->bwc_lock_class_keys = kzalloc_objs(*ctx->bwc_lock_class_keys, + bwc_queues); if (!ctx->bwc_lock_class_keys) goto err_lock_class_keys; @@ -1135,7 +1132,7 @@ int mlx5hws_send_queues_open(struct mlx5hws_context *ctx, if (err) return err; - ctx->send_queue = kcalloc(ctx->queues, sizeof(*ctx->send_queue), GFP_KERNEL); + ctx->send_queue = kzalloc_objs(*ctx->send_queue, ctx->queues); if (!ctx->send_queue) { err = -ENOMEM; goto free_bwc_locks; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c index 6113383ae47b..bd292485a25b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/table.c @@ -238,7 +238,7 @@ struct mlx5hws_table *mlx5hws_table_create(struct mlx5hws_context *ctx, return NULL; } - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (!tbl) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_action.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_action.c index 2ebb61ef3ea9..2020b5eeb8f4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_action.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_action.c @@ -1194,14 +1194,14 @@ mlx5dr_action_create_mult_dest_tbl(struct mlx5dr_domain *dmn, return NULL; } - hw_dests = kcalloc(num_of_dests, sizeof(*hw_dests), GFP_KERNEL); + hw_dests = kzalloc_objs(*hw_dests, num_of_dests); if (!hw_dests) return NULL; if (unlikely(check_mul_overflow(num_of_dests, 2u, &ref_act_cnt))) goto free_hw_dests; - ref_actions = kcalloc(ref_act_cnt, sizeof(*ref_actions), GFP_KERNEL); + ref_actions = kzalloc_objs(*ref_actions, ref_act_cnt); if (!ref_actions) goto free_hw_dests; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c index 01ed6442095d..e1f156448fb0 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_arg.c @@ -68,7 +68,7 @@ static int dr_arg_pool_alloc_objs(struct dr_arg_pool *pool) } for (i = 0; i < num_of_objects; i++) { - arg_obj = kzalloc(sizeof(*arg_obj), GFP_KERNEL); + arg_obj = kzalloc_obj(*arg_obj); if (!arg_obj) { ret = -ENOMEM; goto clean_arg_obj; @@ -132,7 +132,7 @@ static struct dr_arg_pool *dr_arg_pool_create(struct mlx5dr_domain *dmn, { struct dr_arg_pool *pool; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -235,7 +235,7 @@ mlx5dr_arg_mgr_create(struct mlx5dr_domain *dmn) if (!mlx5dr_domain_is_support_ptrn_arg(dmn)) return NULL; - pool_mgr = kzalloc(sizeof(*pool_mgr), GFP_KERNEL); + pool_mgr = kzalloc_obj(*pool_mgr); if (!pool_mgr) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_buddy.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_buddy.c index fe228d948b47..bd3cf1a4cee1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_buddy.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_buddy.c @@ -16,12 +16,8 @@ int mlx5dr_buddy_init(struct mlx5dr_icm_buddy_mem *buddy, INIT_LIST_HEAD(&buddy->list_node); - buddy->bitmap = kcalloc(buddy->max_order + 1, - sizeof(*buddy->bitmap), - GFP_KERNEL); - buddy->num_free = kcalloc(buddy->max_order + 1, - sizeof(*buddy->num_free), - GFP_KERNEL); + buddy->bitmap = kzalloc_objs(*buddy->bitmap, buddy->max_order + 1); + buddy->num_free = kzalloc_objs(*buddy->num_free, buddy->max_order + 1); if (!buddy->bitmap || !buddy->num_free) goto err_free_all; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_dbg.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_dbg.c index 8803fa071c50..0ed81353f2e3 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_dbg.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_dbg.c @@ -60,7 +60,7 @@ mlx5dr_dbg_dump_data_init_new_buff(struct mlx5dr_dbg_dump_data *dump_data) { struct mlx5dr_dbg_dump_buff *new_buff; - new_buff = kzalloc(sizeof(*new_buff), GFP_KERNEL); + new_buff = kzalloc_obj(*new_buff); if (!new_buff) return NULL; @@ -81,7 +81,7 @@ mlx5dr_dbg_create_dump_data(void) { struct mlx5dr_dbg_dump_data *dump_data; - dump_data = kzalloc(sizeof(*dump_data), GFP_KERNEL); + dump_data = kzalloc_obj(*dump_data); if (!dump_data) return NULL; @@ -1051,8 +1051,8 @@ static int dr_dump_domain_all(struct seq_file *file, struct mlx5dr_domain *dmn) struct mlx5dr_table *tbl; int ret; - mutex_lock(&dmn->dump_info.dbg_mutex); mlx5dr_domain_lock(dmn); + mutex_lock(&dmn->dump_info.dbg_mutex); ret = dr_dump_domain(file, dmn); if (ret < 0) @@ -1065,8 +1065,8 @@ static int dr_dump_domain_all(struct seq_file *file, struct mlx5dr_domain *dmn) } unlock_mutex: - mlx5dr_domain_unlock(dmn); mutex_unlock(&dmn->dump_info.dbg_mutex); + mlx5dr_domain_unlock(dmn); return ret; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.c index d5ea97751945..ddbb62d8ac96 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_definer.c @@ -60,7 +60,7 @@ dr_definer_create_obj(struct mlx5dr_domain *dmn, u16 format_id, struct dr_definer_object *definer_obj; int ret = 0; - definer_obj = kzalloc(sizeof(*definer_obj), GFP_KERNEL); + definer_obj = kzalloc_obj(*definer_obj); if (!definer_obj) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c index e8c67ed9f748..fedefb565a21 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c @@ -282,7 +282,7 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) struct mlx5dr_cmd_vport_cap *vport_caps; int ret; - vport_caps = kvzalloc(sizeof(*vport_caps), GFP_KERNEL); + vport_caps = kvzalloc_obj(*vport_caps); if (!vport_caps) return NULL; @@ -467,7 +467,7 @@ mlx5dr_domain_create(struct mlx5_core_dev *mdev, enum mlx5dr_domain_type type) if (type > MLX5DR_DOMAIN_TYPE_FDB) return NULL; - dmn = kzalloc(sizeof(*dmn), GFP_KERNEL); + dmn = kzalloc_obj(*dmn); if (!dmn) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_fw.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_fw.c index f05ef0cd54ba..094fcd9cd770 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_fw.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_fw.c @@ -13,7 +13,7 @@ mlx5dr_fw_create_recalc_cs_ft(struct mlx5dr_domain *dmn, u16 vport_num) u64 rx_icm_addr, modify_ttl_action; int ret; - recalc_cs_ft = kzalloc(sizeof(*recalc_cs_ft), GFP_KERNEL); + recalc_cs_ft = kzalloc_obj(*recalc_cs_ft); if (!recalc_cs_ft) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_icm_pool.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_icm_pool.c index 0b5af9f3f605..7a0a15822392 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_icm_pool.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_icm_pool.c @@ -116,7 +116,7 @@ dr_icm_pool_mr_create(struct mlx5dr_icm_pool *pool) size_t log_align_base = 0; int err; - icm_mr = kvzalloc(sizeof(*icm_mr), GFP_KERNEL); + icm_mr = kvzalloc_obj(*icm_mr); if (!icm_mr) return NULL; @@ -227,8 +227,7 @@ static int dr_icm_buddy_init_ste_cache(struct mlx5dr_icm_buddy_mem *buddy) int num_of_entries = mlx5dr_icm_pool_chunk_size_to_entries(buddy->pool->max_log_chunk_sz); - buddy->ste_arr = kvcalloc(num_of_entries, - sizeof(struct mlx5dr_ste), GFP_KERNEL); + buddy->ste_arr = kvzalloc_objs(struct mlx5dr_ste, num_of_entries); if (!buddy->ste_arr) return -ENOMEM; @@ -269,7 +268,7 @@ static int dr_icm_buddy_create(struct mlx5dr_icm_pool *pool) if (!icm_mr) return -ENOMEM; - buddy = kvzalloc(sizeof(*buddy), GFP_KERNEL); + buddy = kvzalloc_obj(*buddy); if (!buddy) goto free_mr; @@ -509,7 +508,7 @@ struct mlx5dr_icm_pool *mlx5dr_icm_pool_create(struct mlx5dr_domain *dmn, struct mlx5dr_icm_pool *pool; u32 max_hot_size = 0; - pool = kvzalloc(sizeof(*pool), GFP_KERNEL); + pool = kvzalloc_obj(*pool); if (!pool) return NULL; @@ -548,9 +547,8 @@ struct mlx5dr_icm_pool *mlx5dr_icm_pool_create(struct mlx5dr_domain *dmn, num_of_chunks = DIV_ROUND_UP(max_hot_size, entry_size) + 1; pool->th = max_hot_size; - pool->hot_chunks_arr = kvcalloc(num_of_chunks, - sizeof(struct mlx5dr_icm_hot_chunk), - GFP_KERNEL); + pool->hot_chunks_arr = kvzalloc_objs(struct mlx5dr_icm_hot_chunk, + num_of_chunks); if (!pool->hot_chunks_arr) goto free_pool; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_matcher.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_matcher.c index 0726848eb3ff..be0c476b1113 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_matcher.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_matcher.c @@ -996,7 +996,7 @@ mlx5dr_matcher_create(struct mlx5dr_table *tbl, refcount_inc(&tbl->refcount); - matcher = kzalloc(sizeof(*matcher), GFP_KERNEL); + matcher = kzalloc_obj(*matcher); if (!matcher) goto dec_ref; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c index 8ca534ef5d03..ed7eb0f40b57 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ptrn.c @@ -94,7 +94,7 @@ dr_ptrn_alloc_pattern(struct mlx5dr_ptrn_mgr *mgr, mgr->dmn->info.caps.hdr_modify_pattern_icm_addr) / DR_ACTION_CACHE_LINE_SIZE; - pattern = kzalloc(sizeof(*pattern), GFP_KERNEL); + pattern = kzalloc_obj(*pattern); if (!pattern) goto free_chunk; @@ -201,7 +201,7 @@ struct mlx5dr_ptrn_mgr *mlx5dr_ptrn_mgr_create(struct mlx5dr_domain *dmn) if (!mlx5dr_domain_is_support_ptrn_arg(dmn)) return NULL; - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (!mgr) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_rule.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_rule.c index d1db04baa1fa..00156ceed5ea 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_rule.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_rule.c @@ -593,7 +593,7 @@ static int dr_rule_add_action_members(struct mlx5dr_rule *rule, int i; for (i = 0; i < num_actions; i++) { - action_mem = kvzalloc(sizeof(*action_mem), GFP_KERNEL); + action_mem = kvzalloc_obj(*action_mem); if (!action_mem) goto free_action_members; @@ -1298,7 +1298,7 @@ dr_rule_create_rule(struct mlx5dr_matcher *matcher, if (!dr_rule_verify(matcher, value, ¶m)) return NULL; - rule = kzalloc(sizeof(*rule), GFP_KERNEL); + rule = kzalloc_obj(*rule); if (!rule) return NULL; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c index d034372fa047..79e3c29d1044 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_send.c @@ -72,7 +72,7 @@ static int dr_send_info_pool_fill(struct mlx5dr_send_info_pool *pool) int i; for (i = 0; i < DR_SEND_INFO_POOL_SIZE; i++) { - pool_obj = kzalloc(sizeof(*pool_obj), GFP_KERNEL); + pool_obj = kzalloc_obj(*pool_obj); if (!pool_obj) goto clean_pool; @@ -114,7 +114,7 @@ static struct mlx5dr_send_info_pool *dr_send_info_pool_create(void) struct mlx5dr_send_info_pool *pool; int ret; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -258,7 +258,7 @@ static struct mlx5dr_qp *dr_create_rc_qp(struct mlx5_core_dev *mdev, void *in; int err; - dr_qp = kzalloc(sizeof(*dr_qp), GFP_KERNEL); + dr_qp = kzalloc_obj(*dr_qp); if (!dr_qp) return NULL; @@ -1063,7 +1063,7 @@ static struct mlx5dr_cq *dr_create_cq(struct mlx5_core_dev *mdev, __be64 *pas; u32 i; - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_obj(*cq); if (!cq) return NULL; @@ -1158,7 +1158,7 @@ static int dr_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, u32 *mkey) static struct mlx5dr_mr *dr_reg_mr(struct mlx5_core_dev *mdev, u32 pdn, void *buf, size_t size) { - struct mlx5dr_mr *mr = kzalloc(sizeof(*mr), GFP_KERNEL); + struct mlx5dr_mr *mr = kzalloc_obj(*mr); struct device *dma_device; dma_addr_t dma_addr; int err; @@ -1207,7 +1207,7 @@ int mlx5dr_send_ring_alloc(struct mlx5dr_domain *dmn) int size; int ret; - dmn->send_ring = kzalloc(sizeof(*dmn->send_ring), GFP_KERNEL); + dmn->send_ring = kzalloc_obj(*dmn->send_ring); if (!dmn->send_ring) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_table.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_table.c index 69294a66fd7f..740aac71d4cb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_table.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_table.c @@ -255,7 +255,7 @@ struct mlx5dr_table *mlx5dr_table_create(struct mlx5dr_domain *dmn, u32 level, refcount_inc(&dmn->refcount); - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (!tbl) goto dec_ref; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/fs_dr.c b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/fs_dr.c index f367997ab61e..d15dcb30368f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/fs_dr.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/fs_dr.c @@ -275,22 +275,20 @@ static int mlx5_cmd_dr_create_fte(struct mlx5_flow_root_namespace *ns, if (mlx5_fs_cmd_is_fw_term_table(ft)) return mlx5_fs_cmd_get_fw_cmds()->create_fte(ns, ft, group, fte); - actions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, sizeof(*actions), - GFP_KERNEL); + actions = kzalloc_objs(*actions, MLX5_FLOW_CONTEXT_ACTION_MAX); if (!actions) { err = -ENOMEM; goto out_err; } - fs_dr_actions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, - sizeof(*fs_dr_actions), GFP_KERNEL); + fs_dr_actions = kzalloc_objs(*fs_dr_actions, + MLX5_FLOW_CONTEXT_ACTION_MAX); if (!fs_dr_actions) { err = -ENOMEM; goto free_actions_alloc; } - term_actions = kcalloc(MLX5_FLOW_CONTEXT_ACTION_MAX, - sizeof(*term_actions), GFP_KERNEL); + term_actions = kzalloc_objs(*term_actions, MLX5_FLOW_CONTEXT_ACTION_MAX); if (!term_actions) { err = -ENOMEM; goto free_fs_dr_actions_alloc; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/vport.c b/drivers/net/ethernet/mellanox/mlx5/core/vport.c index cb098d3eb2fa..4effe37fd455 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/vport.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/vport.c @@ -832,7 +832,7 @@ int mlx5_query_hca_vport_system_image_guid(struct mlx5_core_dev *dev, struct mlx5_hca_vport_context *rep; int err; - rep = kvzalloc(sizeof(*rep), GFP_KERNEL); + rep = kvzalloc_obj(*rep); if (!rep) return -ENOMEM; @@ -851,7 +851,7 @@ int mlx5_query_hca_vport_node_guid(struct mlx5_core_dev *dev, struct mlx5_hca_vport_context *rep; int err; - rep = kvzalloc(sizeof(*rep), GFP_KERNEL); + rep = kvzalloc_obj(*rep); if (!rep) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c index 815a7c97d6b0..7d3d4d739e2c 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c @@ -2,6 +2,7 @@ // Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include +#include #include #include "lib/clock.h" #include "mlx5_core.h" @@ -15,7 +16,7 @@ #define TEST_WC_NUM_WQES 255 #define TEST_WC_LOG_CQ_SZ (order_base_2(TEST_WC_NUM_WQES)) #define TEST_WC_SQ_LOG_WQ_SZ TEST_WC_LOG_CQ_SZ -#define TEST_WC_POLLING_MAX_TIME_JIFFIES msecs_to_jiffies(100) +#define TEST_WC_POLLING_MAX_TIME_USEC (100 * USEC_PER_MSEC) struct mlx5_wc_cq { /* data path - accessed per cqe */ @@ -359,14 +360,13 @@ static int mlx5_wc_poll_cq(struct mlx5_wc_sq *sq) static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) { unsigned int offset = 0; - unsigned long expires; struct mlx5_wc_sq *sq; int i, err; if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED) return; - sq = kzalloc(sizeof(*sq), GFP_KERNEL); + sq = kzalloc_obj(*sq); if (!sq) return; @@ -389,13 +389,9 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) mlx5_wc_post_nop(sq, &offset, true); - expires = jiffies + TEST_WC_POLLING_MAX_TIME_JIFFIES; - do { - err = mlx5_wc_poll_cq(sq); - if (err) - usleep_range(2, 10); - } while (mdev->wc_state == MLX5_WC_STATE_UNINITIALIZED && - time_is_after_jiffies(expires)); + poll_timeout_us(mlx5_wc_poll_cq(sq), + mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED, 10, + TEST_WC_POLLING_MAX_TIME_USEC, false); mlx5_wc_destroy_sq(sq); diff --git a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c index e6f677e42007..002560c46150 100644 --- a/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c +++ b/drivers/net/ethernet/mellanox/mlxfw/mlxfw_mfa2.c @@ -267,7 +267,7 @@ struct mlxfw_mfa2_file *mlxfw_mfa2_file_init(const struct firmware *fw) const void *first_tlv_ptr; const void *cb_top_ptr; - mfa2_file = kzalloc(sizeof(*mfa2_file), GFP_KERNEL); + mfa2_file = kzalloc_obj(*mfa2_file); if (!mfa2_file) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c index 83c7cf3bbea3..d76246301f67 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core.c @@ -150,8 +150,8 @@ static int mlxsw_ports_init(struct mlxsw_core *mlxsw_core, bool reload) else mlxsw_core->max_ports = MLXSW_PORT_MAX_PORTS_DEFAULT + 1; - mlxsw_core->ports = kcalloc(mlxsw_core->max_ports, - sizeof(struct mlxsw_core_port), GFP_KERNEL); + mlxsw_core->ports = kzalloc_objs(struct mlxsw_core_port, + mlxsw_core->max_ports); if (!mlxsw_core->ports) return -ENOMEM; @@ -1793,7 +1793,7 @@ static void mlxsw_core_health_listener_func(const struct mlxsw_reg_info *reg, struct mlxsw_core_health_event *event; struct mlxsw_core *mlxsw_core = priv; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; event->mlxsw_core = mlxsw_core; @@ -2376,7 +2376,7 @@ int mlxsw_core_rx_listener_register(struct mlxsw_core *mlxsw_core, rxl_item = __find_rx_listener_item(mlxsw_core, rxl); if (rxl_item) return -EEXIST; - rxl_item = kmalloc(sizeof(*rxl_item), GFP_KERNEL); + rxl_item = kmalloc_obj(*rxl_item); if (!rxl_item) return -ENOMEM; rxl_item->rxl = *rxl; @@ -2475,7 +2475,7 @@ int mlxsw_core_event_listener_register(struct mlxsw_core *mlxsw_core, el_item = __find_event_listener_item(mlxsw_core, el); if (el_item) return -EEXIST; - el_item = kmalloc(sizeof(*el_item), GFP_KERNEL); + el_item = kmalloc_obj(*el_item); if (!el_item) return -ENOMEM; el_item->mlxsw_core = mlxsw_core; @@ -2684,7 +2684,7 @@ static int mlxsw_core_reg_access_emad(struct mlxsw_core *mlxsw_core, struct mlxsw_reg_trans *trans; int err; - trans = kzalloc(sizeof(*trans), GFP_KERNEL); + trans = kzalloc_obj(*trans); if (!trans) return -ENOMEM; @@ -2785,7 +2785,7 @@ int mlxsw_core_irq_event_handler_register(struct mlxsw_core *mlxsw_core, { struct mlxsw_core_irq_event_handler_item *item; - item = kzalloc(sizeof(*item), GFP_KERNEL); + item = kzalloc_obj(*item); if (!item) return -ENOMEM; item->cb = cb; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c index 1915fa41c622..f03dffc39005 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c @@ -201,7 +201,7 @@ struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set, struct mlxsw_afa *mlxsw_afa; int err; - mlxsw_afa = kzalloc(sizeof(*mlxsw_afa), GFP_KERNEL); + mlxsw_afa = kzalloc_obj(*mlxsw_afa); if (!mlxsw_afa) return ERR_PTR(-ENOMEM); err = rhashtable_init(&mlxsw_afa->set_ht, &mlxsw_afa_set_ht_params); @@ -276,7 +276,7 @@ static struct mlxsw_afa_set *mlxsw_afa_set_create(bool is_first) { struct mlxsw_afa_set *set; - set = kzalloc(sizeof(*set), GFP_KERNEL); + set = kzalloc_obj(*set); if (!set) return NULL; /* Need to initialize the set to pass by default */ @@ -406,7 +406,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa) { struct mlxsw_afa_block *block; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&block->resource_list); @@ -560,7 +560,7 @@ mlxsw_afa_fwd_entry_create(struct mlxsw_afa *mlxsw_afa, u16 local_port) struct mlxsw_afa_fwd_entry *fwd_entry; int err; - fwd_entry = kzalloc(sizeof(*fwd_entry), GFP_KERNEL); + fwd_entry = kzalloc_obj(*fwd_entry); if (!fwd_entry) return ERR_PTR(-ENOMEM); fwd_entry->ht_key.local_port = local_port; @@ -653,7 +653,7 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u16 local_port) struct mlxsw_afa_fwd_entry *fwd_entry; int err; - fwd_entry_ref = kzalloc(sizeof(*fwd_entry_ref), GFP_KERNEL); + fwd_entry_ref = kzalloc_obj(*fwd_entry_ref); if (!fwd_entry_ref) return ERR_PTR(-ENOMEM); fwd_entry = mlxsw_afa_fwd_entry_get(block->afa, local_port); @@ -702,7 +702,7 @@ mlxsw_afa_counter_create(struct mlxsw_afa_block *block) struct mlxsw_afa_counter *counter; int err; - counter = kzalloc(sizeof(*counter), GFP_KERNEL); + counter = kzalloc_obj(*counter); if (!counter) return ERR_PTR(-ENOMEM); @@ -847,7 +847,7 @@ mlxsw_afa_cookie_ref_create(struct mlxsw_afa_block *block, struct mlxsw_afa_cookie *cookie; int err; - cookie_ref = kzalloc(sizeof(*cookie_ref), GFP_KERNEL); + cookie_ref = kzalloc_obj(*cookie_ref); if (!cookie_ref) return ERR_PTR(-ENOMEM); cookie = mlxsw_afa_cookie_get(block->afa, fa_cookie); @@ -873,7 +873,7 @@ mlxsw_afa_policer_create(struct mlxsw_afa *mlxsw_afa, u32 fa_index, struct mlxsw_afa_policer *policer; int err; - policer = kzalloc(sizeof(*policer), GFP_KERNEL); + policer = kzalloc_obj(*policer); if (!policer) return ERR_PTR(-ENOMEM); @@ -974,7 +974,7 @@ mlxsw_afa_policer_ref_create(struct mlxsw_afa_block *block, u32 fa_index, struct mlxsw_afa_policer *policer; int err; - policer_ref = kzalloc(sizeof(*policer_ref), GFP_KERNEL); + policer_ref = kzalloc_obj(*policer_ref); if (!policer_ref) return ERR_PTR(-ENOMEM); @@ -1386,7 +1386,7 @@ mlxsw_afa_mirror_create(struct mlxsw_afa_block *block, u16 local_in_port, struct mlxsw_afa_mirror *mirror; int err; - mirror = kzalloc(sizeof(*mirror), GFP_KERNEL); + mirror = kzalloc_obj(*mirror); if (!mirror) return ERR_PTR(-ENOMEM); @@ -2187,7 +2187,7 @@ mlxsw_afa_sampler_create(struct mlxsw_afa_block *block, u16 local_port, struct mlxsw_afa_sampler *sampler; int err; - sampler = kzalloc(sizeof(*sampler), GFP_KERNEL); + sampler = kzalloc_obj(*sampler); if (!sampler) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c index 7aa1a462a103..6722de0a3315 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c @@ -86,7 +86,7 @@ struct mlxsw_afk *mlxsw_afk_create(unsigned int max_blocks, { struct mlxsw_afk *mlxsw_afk; - mlxsw_afk = kzalloc(sizeof(*mlxsw_afk), GFP_KERNEL); + mlxsw_afk = kzalloc_obj(*mlxsw_afk); if (!mlxsw_afk) return NULL; INIT_LIST_HEAD(&mlxsw_afk->key_info_list); @@ -262,7 +262,7 @@ static int mlxsw_afk_picker(struct mlxsw_afk *mlxsw_afk, enum mlxsw_afk_element element; int err; - picker = kcalloc(mlxsw_afk->blocks_count, sizeof(*picker), GFP_KERNEL); + picker = kzalloc_objs(*picker, mlxsw_afk->blocks_count); if (!picker) return -ENOMEM; @@ -327,8 +327,7 @@ mlxsw_afk_key_info_create(struct mlxsw_afk *mlxsw_afk, struct mlxsw_afk_key_info *key_info; int err; - key_info = kzalloc(struct_size(key_info, blocks, mlxsw_afk->max_blocks), - GFP_KERNEL); + key_info = kzalloc_flex(*key_info, blocks, mlxsw_afk->max_blocks); if (!key_info) return ERR_PTR(-ENOMEM); err = mlxsw_afk_picker(mlxsw_afk, key_info, elusage); diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_env.c b/drivers/net/ethernet/mellanox/mlxsw/core_env.c index 294e758f1067..ffef5310f8b0 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_env.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_env.c @@ -986,7 +986,7 @@ mlxsw_env_mtwe_listener_func(const struct mlxsw_reg_info *reg, char *mtwe_pl, struct mlxsw_env_module_temp_warn_event *event; struct mlxsw_env *mlxsw_env = priv; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; @@ -1080,7 +1080,7 @@ mlxsw_env_pmpe_listener_func(const struct mlxsw_reg_info *reg, char *pmpe_pl, if (module_status != MLXSW_REG_PMPE_MODULE_STATUS_PLUGGED_ENABLED) return; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; @@ -1243,10 +1243,9 @@ static int mlxsw_env_line_cards_alloc(struct mlxsw_env *env) int i, j; for (i = 0; i < env->num_of_slots; i++) { - env->line_cards[i] = kzalloc(struct_size(env->line_cards[i], - module_info, - env->max_module_count), - GFP_KERNEL); + env->line_cards[i] = kzalloc_flex(*env->line_cards[i], + module_info, + env->max_module_count); if (!env->line_cards[i]) goto kzalloc_err; @@ -1453,8 +1452,7 @@ int mlxsw_env_init(struct mlxsw_core *mlxsw_core, mlxsw_reg_mgpir_max_modules_per_slot_get(mgpir_pl) : module_count; - env = kzalloc(struct_size(env, line_cards, num_of_slots + 1), - GFP_KERNEL); + env = kzalloc_flex(*env, line_cards, num_of_slots + 1); if (!env) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c index 9c12e1feb643..30f172ce822c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c @@ -871,8 +871,7 @@ int mlxsw_hwmon_init(struct mlxsw_core *mlxsw_core, mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL, &num_of_slots); - mlxsw_hwmon = kzalloc(struct_size(mlxsw_hwmon, line_cards, - num_of_slots + 1), GFP_KERNEL); + mlxsw_hwmon = kzalloc_flex(*mlxsw_hwmon, line_cards, num_of_slots + 1); if (!mlxsw_hwmon) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecard_dev.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecard_dev.c index e8d6fe35bf36..c4816488e4d7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_linecard_dev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecard_dev.c @@ -57,7 +57,7 @@ int mlxsw_linecard_bdev_add(struct mlxsw_linecard *linecard) if (id < 0) return id; - linecard_bdev = kzalloc(sizeof(*linecard_bdev), GFP_KERNEL); + linecard_bdev = kzalloc_obj(*linecard_bdev); if (!linecard_bdev) { mlxsw_linecard_bdev_id_free(id); return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c index 10f5bc4892fc..f801f04cafb7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_linecards.c @@ -531,7 +531,7 @@ int mlxsw_linecards_event_ops_register(struct mlxsw_core *mlxsw_core, if (!linecards) return 0; - item = kzalloc(sizeof(*item), GFP_KERNEL); + item = kzalloc_obj(*item); if (!item) return -ENOMEM; item->event_ops = ops; @@ -1192,7 +1192,7 @@ mlxsw_linecard_status_listener_func(const struct mlxsw_reg_info *reg, struct mlxsw_linecard_status_event *event; struct mlxsw_core *mlxsw_core = priv; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; event->mlxsw_core = mlxsw_core; @@ -1225,7 +1225,7 @@ mlxsw_linecard_bct_listener_func(const struct mlxsw_reg_info *reg, struct mlxsw_linecard_bct_event *event; struct mlxsw_core *mlxsw_core = priv; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; event->mlxsw_core = mlxsw_core; @@ -1446,7 +1446,7 @@ static int mlxsw_linecard_types_init(struct mlxsw_core *mlxsw_core, return 0; } - types_info = kzalloc(sizeof(*types_info), GFP_KERNEL); + types_info = kzalloc_obj(*types_info); if (!types_info) { release_firmware(firmware); return -ENOMEM; @@ -1469,9 +1469,8 @@ static int mlxsw_linecard_types_init(struct mlxsw_core *mlxsw_core, goto err_type_file_file_validate; } - types_info->ini_files = kmalloc_array(types_info->count, - sizeof(struct mlxsw_linecard_ini_file *), - GFP_KERNEL); + types_info->ini_files = kmalloc_objs(struct mlxsw_linecard_ini_file *, + types_info->count); if (!types_info->ini_files) { err = -ENOMEM; goto err_ini_files_alloc; diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c index eac9a14a6058..c43382cd1f72 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c +++ b/drivers/net/ethernet/mellanox/mlxsw/core_thermal.c @@ -431,9 +431,8 @@ mlxsw_thermal_modules_init(struct device *dev, struct mlxsw_core *core, if (!area->tz_module_num) return 0; - area->tz_module_arr = kcalloc(area->tz_module_num, - sizeof(*area->tz_module_arr), - GFP_KERNEL); + area->tz_module_arr = kzalloc_objs(*area->tz_module_arr, + area->tz_module_num); if (!area->tz_module_arr) return -ENOMEM; @@ -522,9 +521,8 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core, return 0; area->tz_gearbox_num = gbox_num; - area->tz_gearbox_arr = kcalloc(area->tz_gearbox_num, - sizeof(*area->tz_gearbox_arr), - GFP_KERNEL); + area->tz_gearbox_arr = kzalloc_objs(*area->tz_gearbox_arr, + area->tz_gearbox_num); if (!area->tz_gearbox_arr) return -ENOMEM; @@ -644,8 +642,7 @@ int mlxsw_thermal_init(struct mlxsw_core *core, mlxsw_reg_mgpir_unpack(mgpir_pl, NULL, NULL, NULL, NULL, &num_of_slots); - thermal = kzalloc(struct_size(thermal, line_cards, num_of_slots + 1), - GFP_KERNEL); + thermal = kzalloc_flex(*thermal, line_cards, num_of_slots + 1); if (!thermal) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/minimal.c b/drivers/net/ethernet/mellanox/mlxsw/minimal.c index 828c65036a4c..512933dbab9a 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/minimal.c +++ b/drivers/net/ethernet/mellanox/mlxsw/minimal.c @@ -398,14 +398,12 @@ static int mlxsw_m_linecards_init(struct mlxsw_m *mlxsw_m) /* Add slot for main board. */ mlxsw_m->num_of_slots += 1; - mlxsw_m->ports = kcalloc(max_ports, sizeof(*mlxsw_m->ports), - GFP_KERNEL); + mlxsw_m->ports = kzalloc_objs(*mlxsw_m->ports, max_ports); if (!mlxsw_m->ports) return -ENOMEM; - mlxsw_m->line_cards = kcalloc(mlxsw_m->num_of_slots, - sizeof(*mlxsw_m->line_cards), - GFP_KERNEL); + mlxsw_m->line_cards = kzalloc_objs(*mlxsw_m->line_cards, + mlxsw_m->num_of_slots); if (!mlxsw_m->line_cards) { err = -ENOMEM; goto err_kcalloc; @@ -413,10 +411,8 @@ static int mlxsw_m_linecards_init(struct mlxsw_m *mlxsw_m) for (i = 0; i < mlxsw_m->num_of_slots; i++) { mlxsw_m->line_cards[i] = - kzalloc(struct_size(mlxsw_m->line_cards[i], - module_to_port, - mlxsw_m->max_modules_per_slot), - GFP_KERNEL); + kzalloc_flex(*mlxsw_m->line_cards[i], module_to_port, + mlxsw_m->max_modules_per_slot); if (!mlxsw_m->line_cards[i]) { err = -ENOMEM; goto err_kmalloc_array; diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c index 7da9ef254b72..0da85d36647d 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/pci.c +++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c @@ -1264,7 +1264,7 @@ static int mlxsw_pci_queue_init(struct mlxsw_pci *mlxsw_pci, char *mbox, if (!mem_item->buf) return -ENOMEM; - q->elem_info = kcalloc(q->count, sizeof(*q->elem_info), GFP_KERNEL); + q->elem_info = kzalloc_objs(*q->elem_info, q->count); if (!q->elem_info) { err = -ENOMEM; goto err_elem_info_alloc; @@ -1316,7 +1316,7 @@ static int mlxsw_pci_queue_group_init(struct mlxsw_pci *mlxsw_pci, char *mbox, int err; queue_group = mlxsw_pci_queue_type_group_get(mlxsw_pci, q_ops->type); - queue_group->q = kcalloc(num_qs, sizeof(*queue_group->q), GFP_KERNEL); + queue_group->q = kzalloc_objs(*queue_group->q, num_qs); if (!queue_group->q) return -ENOMEM; @@ -1667,8 +1667,7 @@ static int mlxsw_pci_fw_area_init(struct mlxsw_pci *mlxsw_pci, char *mbox, int i; int err; - mlxsw_pci->fw_area.items = kcalloc(num_pages, sizeof(*mem_item), - GFP_KERNEL); + mlxsw_pci->fw_area.items = kzalloc_objs(*mem_item, num_pages); if (!mlxsw_pci->fw_area.items) return -ENOMEM; mlxsw_pci->fw_area.count = num_pages; @@ -2414,7 +2413,7 @@ static int mlxsw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct mlxsw_pci *mlxsw_pci; int err; - mlxsw_pci = kzalloc(sizeof(*mlxsw_pci), GFP_KERNEL); + mlxsw_pci = kzalloc_obj(*mlxsw_pci); if (!mlxsw_pci) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index 9a2d64a0a858..3a65420fa1ad 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -972,7 +972,7 @@ mlxsw_sp_port_vlan_create(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid) if (err) return ERR_PTR(err); - mlxsw_sp_port_vlan = kzalloc(sizeof(*mlxsw_sp_port_vlan), GFP_KERNEL); + mlxsw_sp_port_vlan = kzalloc_obj(*mlxsw_sp_port_vlan); if (!mlxsw_sp_port_vlan) { err = -ENOMEM; goto err_port_vlan_alloc; @@ -1776,7 +1776,7 @@ static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_port *mlxsw_sp_port; int err; - mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL); + mlxsw_sp_port = kzalloc_obj(*mlxsw_sp_port); if (!mlxsw_sp_port) return -ENOMEM; @@ -1898,7 +1898,7 @@ mlxsw_sp_port_mapping_listener_func(const struct mlxsw_reg_info *reg, return; events = &mlxsw_sp->port_mapping_events; - event = kmalloc(sizeof(*event), GFP_ATOMIC); + event = kmalloc_obj(*event, GFP_ATOMIC); if (!event) return; memcpy(event->pmlp_pl, pmlp_pl, sizeof(event->pmlp_pl)); @@ -2019,9 +2019,8 @@ static int mlxsw_sp_port_module_info_init(struct mlxsw_sp *mlxsw_sp) int i; int err; - mlxsw_sp->port_mapping = kcalloc(max_ports, - sizeof(struct mlxsw_sp_port_mapping), - GFP_KERNEL); + mlxsw_sp->port_mapping = kzalloc_objs(struct mlxsw_sp_port_mapping, + max_ports); if (!mlxsw_sp->port_mapping) return -ENOMEM; @@ -2490,8 +2489,7 @@ static int mlxsw_sp_traps_init(struct mlxsw_sp *mlxsw_sp) if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_CPU_POLICERS)) return -EIO; max_policers = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_CPU_POLICERS); - trap = kzalloc(struct_size(trap, policers_usage, - BITS_TO_LONGS(max_policers)), GFP_KERNEL); + trap = kzalloc_flex(*trap, policers_usage, BITS_TO_LONGS(max_policers)); if (!trap) return -ENOMEM; trap->max_policers = max_policers; @@ -2624,8 +2622,7 @@ static int mlxsw_sp_lag_init(struct mlxsw_sp *mlxsw_sp) if (err) return err; - mlxsw_sp->lags = kcalloc(mlxsw_sp->max_lag, sizeof(struct mlxsw_sp_lag), - GFP_KERNEL); + mlxsw_sp->lags = kzalloc_objs(struct mlxsw_sp_lag, mlxsw_sp->max_lag); if (!mlxsw_sp->lags) { err = -ENOMEM; goto err_kcalloc; @@ -2748,7 +2745,7 @@ mlxsw_sp_sample_trigger_node_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_sample_trigger_node *trigger_node; int err; - trigger_node = kzalloc(sizeof(*trigger_node), GFP_KERNEL); + trigger_node = kzalloc_obj(*trigger_node); if (!trigger_node) return -ENOMEM; @@ -2894,7 +2891,7 @@ mlxsw_sp_ipv6_addr_init(struct mlxsw_sp *mlxsw_sp, const struct in6_addr *addr6, if (err) goto err_rips_write; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) { err = -ENOMEM; goto err_node_alloc; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c index 1e3fc989393c..5ede8e7b91f3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_kvdl.c @@ -224,8 +224,7 @@ mlxsw_sp1_kvdl_part_init(struct mlxsw_sp *mlxsw_sp, } nr_entries = div_u64(resource_size, info->alloc_size); - part = kzalloc(struct_size(part, usage, BITS_TO_LONGS(nr_entries)), - GFP_KERNEL); + part = kzalloc_flex(*part, usage, BITS_TO_LONGS(nr_entries)); if (!part) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_mr_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_mr_tcam.c index c8c67536917b..ffde7c4fe140 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum1_mr_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum1_mr_tcam.c @@ -259,8 +259,8 @@ mlxsw_sp1_mr_tcam_region_init(struct mlxsw_sp *mlxsw_sp, } mr_tcam_region->parman = parman; - parman_prios = kmalloc_array(MLXSW_SP_MR_ROUTE_PRIO_MAX + 1, - sizeof(*parman_prios), GFP_KERNEL); + parman_prios = kmalloc_objs(*parman_prios, + MLXSW_SP_MR_ROUTE_PRIO_MAX + 1); if (!parman_prios) { err = -ENOMEM; goto err_parman_prios_alloc; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c index 3e70cee4d2f3..cb232accb296 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c @@ -318,7 +318,7 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl, struct mlxsw_sp_acl_rule_info *rulei; int err; - rulei = kzalloc(sizeof(*rulei), GFP_KERNEL); + rulei = kzalloc_obj(*rulei); if (!rulei) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c index 07cb1e26ca3e..748929287904 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_atcam.c @@ -74,7 +74,7 @@ mlxsw_sp_acl_atcam_region_generic_init(struct mlxsw_sp_acl_atcam_region *aregion { struct mlxsw_sp_acl_atcam_region_generic *region_generic; - region_generic = kzalloc(sizeof(*region_generic), GFP_KERNEL); + region_generic = kzalloc_obj(*region_generic); if (!region_generic) return -ENOMEM; @@ -126,7 +126,7 @@ mlxsw_sp_acl_atcam_region_12kb_init(struct mlxsw_sp_acl_atcam_region *aregion) return -EIO; max_lkey_id = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_LARGE_KEY_ID); - region_12kb = kzalloc(sizeof(*region_12kb), GFP_KERNEL); + region_12kb = kzalloc_obj(*region_12kb); if (!region_12kb) return -ENOMEM; @@ -179,7 +179,7 @@ mlxsw_sp_acl_atcam_lkey_id_create(struct mlxsw_sp_acl_atcam_region *aregion, else return ERR_PTR(-ENOBUFS); - lkey_id = kzalloc(sizeof(*lkey_id), GFP_KERNEL); + lkey_id = kzalloc_obj(*lkey_id); if (!lkey_id) { err = -ENOMEM; goto err_lkey_id_alloc; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c index 067f0055a55a..275763642529 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_bloom_filter.c @@ -513,8 +513,7 @@ mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks) * is 2^ACL_MAX_BF_LOG */ bf_bank_size = 1 << MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_MAX_BF_LOG); - bf = kzalloc(struct_size(bf, refcnt, size_mul(bf_bank_size, num_erp_banks)), - GFP_KERNEL); + bf = kzalloc_flex(*bf, refcnt, size_mul(bf_bank_size, num_erp_banks)); if (!bf) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c index 9eee229303cc..cbb272a96359 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -254,7 +254,7 @@ mlxsw_sp_acl_erp_generic_create(struct mlxsw_sp_acl_erp_table *erp_table, struct mlxsw_sp_acl_erp *erp; int err; - erp = kzalloc(sizeof(*erp), GFP_KERNEL); + erp = kzalloc_obj(*erp); if (!erp) return ERR_PTR(-ENOMEM); @@ -798,7 +798,7 @@ mlxsw_sp_acl_erp_ctcam_mask_create(struct mlxsw_sp_acl_erp_table *erp_table, struct mlxsw_sp_acl_erp *erp; int err; - erp = kzalloc(sizeof(*erp), GFP_KERNEL); + erp = kzalloc_obj(*erp); if (!erp) return ERR_PTR(-ENOMEM); @@ -1236,7 +1236,7 @@ static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj, if (err) return ERR_PTR(-EINVAL); - delta = kzalloc(sizeof(*delta), GFP_KERNEL); + delta = kzalloc_obj(*delta); if (!delta) return ERR_PTR(-ENOMEM); delta->start = delta_start; @@ -1309,7 +1309,7 @@ mlxsw_sp_acl_erp_table_create(struct mlxsw_sp_acl_atcam_region *aregion, struct mlxsw_sp_acl_erp_table *erp_table; int err; - erp_table = kzalloc(sizeof(*erp_table), GFP_KERNEL); + erp_table = kzalloc_obj(*erp_table); if (!erp_table) return ERR_PTR(-ENOMEM); @@ -1563,7 +1563,7 @@ int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_erp_core *erp_core; int err; - erp_core = kzalloc(sizeof(*erp_core), GFP_KERNEL); + erp_core = kzalloc_obj(*erp_core); if (!erp_core) return -ENOMEM; erp_core->mlxsw_sp = mlxsw_sp; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c index 69f9da9fb305..3232ff3ad3c3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.c @@ -778,7 +778,7 @@ mlxsw_sp_acl_tcam_vregion_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_tcam_vregion *vregion; int err; - vregion = kzalloc(sizeof(*vregion), GFP_KERNEL); + vregion = kzalloc_obj(*vregion); if (!vregion) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&vregion->vchunk_list); @@ -939,7 +939,7 @@ mlxsw_sp_acl_tcam_vchunk_create(struct mlxsw_sp *mlxsw_sp, if (priority == MLXSW_SP_ACL_TCAM_CATCHALL_PRIO) return ERR_PTR(-EINVAL); - vchunk = kzalloc(sizeof(*vchunk), GFP_KERNEL); + vchunk = kzalloc_obj(*vchunk); if (!vchunk) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&vchunk->ventry_list); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c index 2c0cfa79d138..e2ba919fa6fd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c @@ -628,8 +628,7 @@ static int mlxsw_sp_sb_port_init(struct mlxsw_sp *mlxsw_sp, { struct mlxsw_sp_sb_pm *pms; - pms = kcalloc(mlxsw_sp->sb_vals->pool_count, sizeof(*pms), - GFP_KERNEL); + pms = kzalloc_objs(*pms, mlxsw_sp->sb_vals->pool_count); if (!pms) return -ENOMEM; sb_port->pms = pms; @@ -648,14 +647,11 @@ static int mlxsw_sp_sb_ports_init(struct mlxsw_sp *mlxsw_sp) int i; int err; - mlxsw_sp->sb->ports = kcalloc(max_ports, - sizeof(struct mlxsw_sp_sb_port), - GFP_KERNEL); + mlxsw_sp->sb->ports = kzalloc_objs(struct mlxsw_sp_sb_port, max_ports); if (!mlxsw_sp->sb->ports) return -ENOMEM; - prs = kcalloc(mlxsw_sp->sb_vals->pool_count, sizeof(*prs), - GFP_KERNEL); + prs = kzalloc_objs(*prs, mlxsw_sp->sb_vals->pool_count); if (!prs) { err = -ENOMEM; goto err_alloc_prs; @@ -1264,7 +1260,7 @@ int mlxsw_sp_buffers_init(struct mlxsw_sp *mlxsw_sp) if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, MAX_HEADROOM_SIZE)) return -EIO; - mlxsw_sp->sb = kzalloc(sizeof(*mlxsw_sp->sb), GFP_KERNEL); + mlxsw_sp->sb = kzalloc_obj(*mlxsw_sp->sb); if (!mlxsw_sp->sb) return -ENOMEM; mlxsw_sp->sb->cell_size = MLXSW_CORE_RES_GET(mlxsw_sp->core, CELL_SIZE); @@ -1327,7 +1323,7 @@ int mlxsw_sp_port_buffers_init(struct mlxsw_sp_port *mlxsw_sp_port) { int err; - mlxsw_sp_port->hdroom = kzalloc(sizeof(*mlxsw_sp_port->hdroom), GFP_KERNEL); + mlxsw_sp_port->hdroom = kzalloc_obj(*mlxsw_sp_port->hdroom); if (!mlxsw_sp_port->hdroom) return -ENOMEM; mlxsw_sp_port->hdroom->mtu = mlxsw_sp_port->dev->mtu; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c index b1094aaffa5f..c08b3ec2b600 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c @@ -124,8 +124,7 @@ int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_counter_pool *pool; int err; - pool = kzalloc(struct_size(pool, sub_pools, sub_pools_count), - GFP_KERNEL); + pool = kzalloc_flex(*pool, sub_pools, sub_pools_count); if (!pool) return -ENOMEM; mlxsw_sp->counter_pool = pool; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c index aff6d4f35cd2..f1ad937405a3 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_dcb.c @@ -654,8 +654,7 @@ static const struct dcbnl_rtnl_ops mlxsw_sp_dcbnl_ops = { static int mlxsw_sp_port_ets_init(struct mlxsw_sp_port *mlxsw_sp_port) { - mlxsw_sp_port->dcb.ets = kzalloc(sizeof(*mlxsw_sp_port->dcb.ets), - GFP_KERNEL); + mlxsw_sp_port->dcb.ets = kzalloc_obj(*mlxsw_sp_port->dcb.ets); if (!mlxsw_sp_port->dcb.ets) return -ENOMEM; @@ -673,8 +672,7 @@ static int mlxsw_sp_port_maxrate_init(struct mlxsw_sp_port *mlxsw_sp_port) { int i; - mlxsw_sp_port->dcb.maxrate = kmalloc(sizeof(*mlxsw_sp_port->dcb.maxrate), - GFP_KERNEL); + mlxsw_sp_port->dcb.maxrate = kmalloc_obj(*mlxsw_sp_port->dcb.maxrate); if (!mlxsw_sp_port->dcb.maxrate) return -ENOMEM; @@ -691,8 +689,7 @@ static void mlxsw_sp_port_maxrate_fini(struct mlxsw_sp_port *mlxsw_sp_port) static int mlxsw_sp_port_pfc_init(struct mlxsw_sp_port *mlxsw_sp_port) { - mlxsw_sp_port->dcb.pfc = kzalloc(sizeof(*mlxsw_sp_port->dcb.pfc), - GFP_KERNEL); + mlxsw_sp_port->dcb.pfc = kzalloc_obj(*mlxsw_sp_port->dcb.pfc); if (!mlxsw_sp_port->dcb.pfc) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c index 65562ab208b3..4f921bbc1e77 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c @@ -1022,7 +1022,7 @@ mlxsw_sp_fid_port_vid_list_add(struct mlxsw_sp_fid *fid, u16 local_port, { struct mlxsw_sp_fid_port_vid *port_vid, *tmp_port_vid; - port_vid = kzalloc(sizeof(*port_vid), GFP_KERNEL); + port_vid = kzalloc_obj(*port_vid); if (!port_vid) return -ENOMEM; @@ -2295,7 +2295,7 @@ mlxsw_sp_fids_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fid_core *fid_core; int err, i; - fid_core = kzalloc(sizeof(*mlxsw_sp->fid_core), GFP_KERNEL); + fid_core = kzalloc_obj(*mlxsw_sp->fid_core); if (!fid_core) return -ENOMEM; mlxsw_sp->fid_core = fid_core; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c index 9e50c823a354..f1b8d2868a22 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_flow.c @@ -14,7 +14,7 @@ mlxsw_sp_flow_block_create(struct mlxsw_sp *mlxsw_sp, struct net *net) { struct mlxsw_sp_flow_block *block; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return NULL; INIT_LIST_HEAD(&block->binding_list); @@ -75,7 +75,7 @@ static int mlxsw_sp_flow_block_bind(struct mlxsw_sp *mlxsw_sp, if (err) return err; - binding = kzalloc(sizeof(*binding), GFP_KERNEL); + binding = kzalloc_obj(*binding); if (!binding) { err = -ENOMEM; goto err_binding_alloc; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c index 07b371cd9818..fefd39a96320 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c @@ -243,7 +243,7 @@ int mlxsw_sp_mall_replace(struct mlxsw_sp *mlxsw_sp, return -EOPNOTSUPP; } - mall_entry = kzalloc(sizeof(*mall_entry), GFP_KERNEL); + mall_entry = kzalloc_obj(*mall_entry); if (!mall_entry) return -ENOMEM; mall_entry->cookie = f->cookie; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c index 81935f87bfcd..e700e9ac33b7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr.c @@ -172,7 +172,7 @@ static int mlxsw_sp_mr_route_evif_link(struct mlxsw_sp_mr_route *mr_route, { struct mlxsw_sp_mr_route_vif_entry *rve; - rve = kzalloc(sizeof(*rve), GFP_KERNEL); + rve = kzalloc_obj(*rve); if (!rve) return -ENOMEM; rve->mr_route = mr_route; @@ -305,7 +305,7 @@ mlxsw_sp_mr_route_create(struct mlxsw_sp_mr_table *mr_table, int i; /* Allocate and init a new route and fill it with parameters */ - mr_route = kzalloc(sizeof(*mr_route), GFP_KERNEL); + mr_route = kzalloc_obj(*mr_route); if (!mr_route) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&mr_route->evif_list); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c index 01d81ae3662a..34f8a6fabfe7 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c @@ -52,7 +52,7 @@ mlxsw_sp_mr_erif_sublist_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_mr_erif_sublist *erif_sublist; int err; - erif_sublist = kzalloc(sizeof(*erif_sublist), GFP_KERNEL); + erif_sublist = kzalloc_obj(*erif_sublist); if (!erif_sublist) return ERR_PTR(-ENOMEM); err = mlxsw_sp_kvdl_alloc(mlxsw_sp, MLXSW_SP_KVDL_ENTRY_TYPE_MCRIGR, diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c index 5479a1c19d2e..84942c1ea726 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve.c @@ -216,7 +216,7 @@ mlxsw_sp_nve_mc_list_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nve_mc_list *mc_list; int err; - mc_list = kmalloc(sizeof(*mc_list), GFP_KERNEL); + mc_list = kmalloc_obj(*mc_list); if (!mc_list) return ERR_PTR(-ENOMEM); @@ -277,8 +277,7 @@ mlxsw_sp_nve_mc_record_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nve_mc_record *mc_record; int err; - mc_record = kzalloc(struct_size(mc_record, entries, num_max_entries), - GFP_KERNEL); + mc_record = kzalloc_flex(*mc_record, entries, num_max_entries); if (!mc_record) return ERR_PTR(-ENOMEM); @@ -848,7 +847,7 @@ static int mlxsw_sp_nve_ipv6_ht_insert(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nve *nve = mlxsw_sp->nve; int err; - ipv6_ht_node = kzalloc(sizeof(*ipv6_ht_node), GFP_KERNEL); + ipv6_ht_node = kzalloc_obj(*ipv6_ht_node); if (!ipv6_ht_node) return -ENOMEM; @@ -1119,7 +1118,7 @@ int mlxsw_sp_nve_init(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_nve *nve; int err; - nve = kzalloc(sizeof(*mlxsw_sp->nve), GFP_KERNEL); + nve = kzalloc_obj(*mlxsw_sp->nve); if (!nve) return -ENOMEM; mlxsw_sp->nve = nve; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c index 4ef81bac17d6..0cef30fafddd 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_pgt.c @@ -116,7 +116,7 @@ mlxsw_sp_pgt_entry_create(struct mlxsw_sp_pgt *pgt, u16 mid, u16 smpe) void *ret; int err; - pgt_entry = kzalloc(sizeof(*pgt_entry), GFP_KERNEL); + pgt_entry = kzalloc_obj(*pgt_entry); if (!pgt_entry) return ERR_PTR(-ENOMEM); @@ -211,7 +211,7 @@ mlxsw_sp_pgt_entry_port_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_pgt_entry_port *pgt_entry_port; int err; - pgt_entry_port = kzalloc(sizeof(*pgt_entry_port), GFP_KERNEL); + pgt_entry_port = kzalloc_obj(*pgt_entry_port); if (!pgt_entry_port) return ERR_PTR(-ENOMEM); @@ -315,7 +315,7 @@ int mlxsw_sp_pgt_init(struct mlxsw_sp *mlxsw_sp) if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, PGT_SIZE)) return -EIO; - pgt = kzalloc(sizeof(*mlxsw_sp->pgt), GFP_KERNEL); + pgt = kzalloc_obj(*mlxsw_sp->pgt); if (!pgt) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c index 22ebb207ce4d..cbad1af0cd80 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_policer.c @@ -243,7 +243,7 @@ int mlxsw_sp_policer_add(struct mlxsw_sp *mlxsw_sp, if (err) return err; - policer = kmalloc(sizeof(*policer), GFP_KERNEL); + policer = kmalloc_obj(*policer); if (!policer) return -ENOMEM; policer->params = *params; @@ -357,7 +357,7 @@ int mlxsw_sp_policers_init(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_policer_core *policer_core; int i, err; - policer_core = kzalloc(sizeof(*policer_core), GFP_KERNEL); + policer_core = kzalloc_obj(*policer_core); if (!policer_core) return -ENOMEM; mlxsw_sp->policer_core = policer_core; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c index 2d193de12be6..a330d1c0c47c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c @@ -52,7 +52,7 @@ mlxsw_sp_port_range_reg_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_port_range_reg *prr; int err; - prr = kzalloc(sizeof(*prr), GFP_KERNEL); + prr = kzalloc_obj(*prr); if (!prr) return ERR_PTR(-ENOMEM); @@ -172,7 +172,7 @@ int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp) */ WARN_ON(max > BITS_PER_BYTE * sizeof(u16)); - pr_core = kzalloc(sizeof(*mlxsw_sp->pr_core), GFP_KERNEL); + pr_core = kzalloc_obj(*mlxsw_sp->pr_core); if (!pr_core) return -ENOMEM; mlxsw_sp->pr_core = pr_core; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c index 5b9f0844b8f6..9939749c47bc 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c @@ -277,7 +277,7 @@ mlxsw_sp1_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev) struct mlxsw_sp1_ptp_clock *clock; int err; - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) return ERR_PTR(-ENOMEM); @@ -446,7 +446,7 @@ mlxsw_sp2_ptp_clock_init(struct mlxsw_sp *mlxsw_sp, struct device *dev) struct mlxsw_sp_ptp_clock *clock; int err; - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) return ERR_PTR(-ENOMEM); @@ -524,7 +524,7 @@ mlxsw_sp1_ptp_unmatched_save(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp1_ptp_unmatched *unmatched; int err; - unmatched = kzalloc(sizeof(*unmatched), GFP_ATOMIC); + unmatched = kzalloc_obj(*unmatched, GFP_ATOMIC); if (!unmatched) return -ENOMEM; @@ -1032,7 +1032,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp1_ptp_init(struct mlxsw_sp *mlxsw_sp) if (err) return ERR_PTR(err); - ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL); + ptp_state = kzalloc_obj(*ptp_state); if (!ptp_state) return ERR_PTR(-ENOMEM); ptp_state->common.mlxsw_sp = mlxsw_sp; @@ -1358,7 +1358,7 @@ struct mlxsw_sp_ptp_state *mlxsw_sp2_ptp_init(struct mlxsw_sp *mlxsw_sp) if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, FID)) return ERR_PTR(-EIO); - ptp_state = kzalloc(sizeof(*ptp_state), GFP_KERNEL); + ptp_state = kzalloc_obj(*ptp_state); if (!ptp_state) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c index 4243d3b883ff..73519301b744 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c @@ -365,9 +365,8 @@ static int mlxsw_sp_qdisc_create(struct mlxsw_sp_port *mlxsw_sp_port, return err; if (ops->num_classes) { - mlxsw_sp_qdisc->qdiscs = kcalloc(ops->num_classes, - sizeof(*mlxsw_sp_qdisc->qdiscs), - GFP_KERNEL); + mlxsw_sp_qdisc->qdiscs = kzalloc_objs(*mlxsw_sp_qdisc->qdiscs, + ops->num_classes); if (!mlxsw_sp_qdisc->qdiscs) return -ENOMEM; @@ -1332,7 +1331,7 @@ __mlxsw_sp_qdisc_ets_replace(struct mlxsw_sp_port *mlxsw_sp_port, int err; if (!ets_data) { - ets_data = kzalloc(sizeof(*ets_data), GFP_KERNEL); + ets_data = kzalloc_obj(*ets_data); if (!ets_data) return -ENOMEM; mlxsw_sp_qdisc->ets_data = ets_data; @@ -2021,7 +2020,7 @@ static int mlxsw_sp_qevent_mall_replace(struct mlxsw_sp *mlxsw_sp, return -EOPNOTSUPP; } - mall_entry = kzalloc(sizeof(*mall_entry), GFP_KERNEL); + mall_entry = kzalloc_obj(*mall_entry); if (!mall_entry) return -ENOMEM; mall_entry->cookie = f->cookie; @@ -2100,7 +2099,7 @@ static struct mlxsw_sp_qevent_block *mlxsw_sp_qevent_block_create(struct mlxsw_s { struct mlxsw_sp_qevent_block *qevent_block; - qevent_block = kzalloc(sizeof(*qevent_block), GFP_KERNEL); + qevent_block = kzalloc_obj(*qevent_block); if (!qevent_block) return NULL; @@ -2132,7 +2131,7 @@ mlxsw_sp_qevent_binding_create(struct mlxsw_sp_port *mlxsw_sp_port, u32 handle, { struct mlxsw_sp_qevent_binding *binding; - binding = kzalloc(sizeof(*binding), GFP_KERNEL); + binding = kzalloc_obj(*binding); if (!binding) return ERR_PTR(-ENOMEM); @@ -2321,7 +2320,7 @@ int mlxsw_sp_tc_qdisc_init(struct mlxsw_sp_port *mlxsw_sp_port) { struct mlxsw_sp_qdisc_state *qdisc_state; - qdisc_state = kzalloc(sizeof(*qdisc_state), GFP_KERNEL); + qdisc_state = kzalloc_obj(*qdisc_state); if (!qdisc_state) return -ENOMEM; diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c index 2d0e89bd2fb9..7bd87d0547d8 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c @@ -538,7 +538,7 @@ static struct mlxsw_sp_fib *mlxsw_sp_fib_create(struct mlxsw_sp *mlxsw_sp, int err; lpm_tree = mlxsw_sp->router->lpm.proto_trees[proto]; - fib = kzalloc(sizeof(*fib), GFP_KERNEL); + fib = kzalloc_obj(*fib); if (!fib) return ERR_PTR(-ENOMEM); err = rhashtable_init(&fib->ht, &mlxsw_sp_fib_ht_params); @@ -717,9 +717,8 @@ static int mlxsw_sp_lpm_init(struct mlxsw_sp *mlxsw_sp) max_trees = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_LPM_TREES); mlxsw_sp->router->lpm.tree_count = max_trees - MLXSW_SP_LPM_TREE_MIN; - mlxsw_sp->router->lpm.trees = kcalloc(mlxsw_sp->router->lpm.tree_count, - sizeof(struct mlxsw_sp_lpm_tree), - GFP_KERNEL); + mlxsw_sp->router->lpm.trees = kzalloc_objs(struct mlxsw_sp_lpm_tree, + mlxsw_sp->router->lpm.tree_count); if (!mlxsw_sp->router->lpm.trees) return -ENOMEM; @@ -1038,8 +1037,7 @@ static int mlxsw_sp_vrs_init(struct mlxsw_sp *mlxsw_sp) return -EIO; max_vrs = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_VRS); - mlxsw_sp->router->vrs = kcalloc(max_vrs, sizeof(struct mlxsw_sp_vr), - GFP_KERNEL); + mlxsw_sp->router->vrs = kzalloc_objs(struct mlxsw_sp_vr, max_vrs); if (!mlxsw_sp->router->vrs) return -ENOMEM; @@ -1095,7 +1093,7 @@ mlxsw_sp_crif_alloc(struct net_device *dev) { struct mlxsw_sp_crif *crif; - crif = kzalloc(sizeof(*crif), GFP_KERNEL); + crif = kzalloc_obj(*crif); if (!crif) return NULL; @@ -1178,7 +1176,7 @@ mlxsw_sp_ipip_entry_alloc(struct mlxsw_sp *mlxsw_sp, int err; ipip_ops = mlxsw_sp->router->ipip_ops_arr[ipipt]; - ipip_entry = kzalloc(sizeof(*ipip_entry), GFP_KERNEL); + ipip_entry = kzalloc_obj(*ipip_entry); if (!ipip_entry) return ERR_PTR(-ENOMEM); @@ -2261,7 +2259,7 @@ mlxsw_sp_neigh_entry_alloc(struct mlxsw_sp *mlxsw_sp, struct neighbour *n, { struct mlxsw_sp_neigh_entry *neigh_entry; - neigh_entry = kzalloc(sizeof(*neigh_entry), GFP_KERNEL); + neigh_entry = kzalloc_obj(*neigh_entry); if (!neigh_entry) return NULL; @@ -2856,7 +2854,7 @@ static int mlxsw_sp_router_schedule_work(struct net *net, if (!net_eq(net, mlxsw_sp_net(router->mlxsw_sp))) return NOTIFY_DONE; - net_work = kzalloc(sizeof(*net_work), GFP_ATOMIC); + net_work = kzalloc_obj(*net_work, GFP_ATOMIC); if (!net_work) return NOTIFY_BAD; @@ -3172,7 +3170,7 @@ mlxsw_sp_nexthop_counter_alloc(struct mlxsw_sp *mlxsw_sp) struct mlxsw_sp_nexthop_counter *nhct; int err; - nhct = kzalloc(sizeof(*nhct), GFP_KERNEL); + nhct = kzalloc_obj(*nhct); if (!nhct) return ERR_PTR(-ENOMEM); @@ -3404,7 +3402,7 @@ mlxsw_sp_nexthop_group_vr_entry_create(struct mlxsw_sp_nexthop_group *nh_grp, struct mlxsw_sp_nexthop_group_vr_entry *vr_entry; int err; - vr_entry = kzalloc(sizeof(*vr_entry), GFP_KERNEL); + vr_entry = kzalloc_obj(*vr_entry); if (!vr_entry) return -ENOMEM; @@ -5198,7 +5196,7 @@ mlxsw_sp_nexthop_obj_group_info_init(struct mlxsw_sp *mlxsw_sp, return -EINVAL; } - nhgi = kzalloc(struct_size(nhgi, nexthops, nhs), GFP_KERNEL); + nhgi = kzalloc_flex(*nhgi, nexthops, nhs); if (!nhgi) return -ENOMEM; nh_grp->nhgi = nhgi; @@ -5304,7 +5302,7 @@ mlxsw_sp_nexthop_obj_group_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop_group *nh_grp; int err; - nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL); + nh_grp = kzalloc_obj(*nh_grp); if (!nh_grp) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&nh_grp->vr_list); @@ -5779,7 +5777,7 @@ mlxsw_sp_nexthop4_group_info_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop *nh; int err, i; - nhgi = kzalloc(struct_size(nhgi, nexthops, nhs), GFP_KERNEL); + nhgi = kzalloc_flex(*nhgi, nexthops, nhs); if (!nhgi) return -ENOMEM; nh_grp->nhgi = nhgi; @@ -5841,7 +5839,7 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi) struct mlxsw_sp_nexthop_group *nh_grp; int err; - nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL); + nh_grp = kzalloc_obj(*nh_grp); if (!nh_grp) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&nh_grp->vr_list); @@ -6481,7 +6479,7 @@ mlxsw_sp_fib4_entry_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_fib_entry *fib_entry; int err; - fib4_entry = kzalloc(sizeof(*fib4_entry), GFP_KERNEL); + fib4_entry = kzalloc_obj(*fib4_entry); if (!fib4_entry) return ERR_PTR(-ENOMEM); fib_entry = &fib4_entry->common; @@ -6601,7 +6599,7 @@ mlxsw_sp_fib_node_create(struct mlxsw_sp_fib *fib, const void *addr, { struct mlxsw_sp_fib_node *fib_node; - fib_node = kzalloc(sizeof(*fib_node), GFP_KERNEL); + fib_node = kzalloc_obj(*fib_node); if (!fib_node) return NULL; @@ -6906,7 +6904,7 @@ static struct mlxsw_sp_rt6 *mlxsw_sp_rt6_create(struct fib6_info *rt) { struct mlxsw_sp_rt6 *mlxsw_sp_rt6; - mlxsw_sp_rt6 = kzalloc(sizeof(*mlxsw_sp_rt6), GFP_KERNEL); + mlxsw_sp_rt6 = kzalloc_obj(*mlxsw_sp_rt6); if (!mlxsw_sp_rt6) return ERR_PTR(-ENOMEM); @@ -7032,8 +7030,7 @@ mlxsw_sp_nexthop6_group_info_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop *nh; int err, i; - nhgi = kzalloc(struct_size(nhgi, nexthops, fib6_entry->nrt6), - GFP_KERNEL); + nhgi = kzalloc_flex(*nhgi, nexthops, fib6_entry->nrt6); if (!nhgi) return -ENOMEM; nh_grp->nhgi = nhgi; @@ -7099,7 +7096,7 @@ mlxsw_sp_nexthop6_group_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_nexthop_group *nh_grp; int err; - nh_grp = kzalloc(sizeof(*nh_grp), GFP_KERNEL); + nh_grp = kzalloc_obj(*nh_grp); if (!nh_grp) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&nh_grp->vr_list); @@ -7378,7 +7375,7 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_rt6 *mlxsw_sp_rt6; int err, i; - fib6_entry = kzalloc(sizeof(*fib6_entry), GFP_KERNEL); + fib6_entry = kzalloc_obj(*fib6_entry); if (!fib6_entry) return ERR_PTR(-ENOMEM); fib_entry = &fib6_entry->common; @@ -7827,7 +7824,7 @@ mlxsw_sp_router_fib6_work_init(struct mlxsw_sp_fib6_event_work *fib6_work, nrt6 = fen6_info->nsiblings + 1; - rt_arr = kcalloc(nrt6, sizeof(struct fib6_info *), GFP_ATOMIC); + rt_arr = kzalloc_objs(struct fib6_info *, nrt6, GFP_ATOMIC); if (!rt_arr) return -ENOMEM; @@ -8139,7 +8136,7 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb, break; } - fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); + fib_work = kzalloc_obj(*fib_work, GFP_ATOMIC); if (!fib_work) return NOTIFY_BAD; @@ -8542,7 +8539,7 @@ mlxsw_sp_router_hwstats_notify_schedule(struct net_device *dev) * later. */ - hws_work = kzalloc(sizeof(*hws_work), GFP_KERNEL); + hws_work = kzalloc_obj(*hws_work); if (!hws_work) return; @@ -8947,7 +8944,7 @@ mlxsw_sp_rif_mac_profile_alloc(const char *mac) { struct mlxsw_sp_rif_mac_profile *profile; - profile = kzalloc(sizeof(*profile), GFP_KERNEL); + profile = kzalloc_obj(*profile); if (!profile) return NULL; @@ -9594,7 +9591,7 @@ static int mlxsw_sp_inet6addr_event(struct notifier_block *nb, if (event == NETDEV_UP) return NOTIFY_DONE; - inet6addr_work = kzalloc(sizeof(*inet6addr_work), GFP_ATOMIC); + inet6addr_work = kzalloc_obj(*inet6addr_work, GFP_ATOMIC); if (!inet6addr_work) return NOTIFY_BAD; @@ -11069,9 +11066,7 @@ static int mlxsw_sp_rifs_init(struct mlxsw_sp *mlxsw_sp) mlxsw_sp->router->max_rif_mac_profile = MLXSW_CORE_RES_GET(core, MAX_RIF_MAC_PROFILES); - mlxsw_sp->router->rifs = kcalloc(max_rifs, - sizeof(struct mlxsw_sp_rif *), - GFP_KERNEL); + mlxsw_sp->router->rifs = kzalloc_objs(struct mlxsw_sp_rif *, max_rifs); if (!mlxsw_sp->router->rifs) return -ENOMEM; @@ -11584,7 +11579,7 @@ int mlxsw_sp_router_init(struct mlxsw_sp *mlxsw_sp, struct notifier_block *nb; int err; - router = kzalloc(sizeof(*mlxsw_sp->router), GFP_KERNEL); + router = kzalloc_obj(*mlxsw_sp->router); if (!router) return -ENOMEM; mutex_init(&router->lock); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c index 32d2e61f2b82..ae63d549b542 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c @@ -87,7 +87,7 @@ int mlxsw_sp_span_init(struct mlxsw_sp *mlxsw_sp) return -EIO; entries_count = MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_SPAN); - span = kzalloc(struct_size(span, entries, entries_count), GFP_KERNEL); + span = kzalloc_flex(*span, entries, entries_count); if (!span) return -ENOMEM; refcount_set(&span->policer_id_base_ref_count, 0); @@ -1120,7 +1120,7 @@ mlxsw_sp_span_analyzed_port_create(struct mlxsw_sp_span *span, struct mlxsw_sp_span_analyzed_port *analyzed_port; int err; - analyzed_port = kzalloc(sizeof(*analyzed_port), GFP_KERNEL); + analyzed_port = kzalloc_obj(*analyzed_port); if (!analyzed_port) return ERR_PTR(-ENOMEM); @@ -1505,7 +1505,7 @@ mlxsw_sp_span_trigger_entry_create(struct mlxsw_sp_span *span, struct mlxsw_sp_span_trigger_entry *trigger_entry; int err; - trigger_entry = kzalloc(sizeof(*trigger_entry), GFP_KERNEL); + trigger_entry = kzalloc_obj(*trigger_entry); if (!trigger_entry) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c index a48bf342084d..fe45e533a4b2 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c @@ -262,7 +262,7 @@ mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge, return ERR_PTR(-EINVAL); } - bridge_device = kzalloc(sizeof(*bridge_device), GFP_KERNEL); + bridge_device = kzalloc_obj(*bridge_device); if (!bridge_device) return ERR_PTR(-ENOMEM); @@ -478,7 +478,7 @@ mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device, struct mlxsw_sp_port *mlxsw_sp_port; int err; - bridge_port = kzalloc(sizeof(*bridge_port), GFP_KERNEL); + bridge_port = kzalloc_obj(*bridge_port); if (!bridge_port) return ERR_PTR(-ENOMEM); @@ -625,7 +625,7 @@ mlxsw_sp_bridge_vlan_create(struct mlxsw_sp_bridge_port *bridge_port, u16 vid) { struct mlxsw_sp_bridge_vlan *bridge_vlan; - bridge_vlan = kzalloc(sizeof(*bridge_vlan), GFP_KERNEL); + bridge_vlan = kzalloc_obj(*bridge_vlan); if (!bridge_vlan) return NULL; @@ -1131,7 +1131,7 @@ mlxsw_sp_mdb_entry_port_get(struct mlxsw_sp *mlxsw_sp, if (err) return ERR_PTR(err); - mdb_entry_port = kzalloc(sizeof(*mdb_entry_port), GFP_KERNEL); + mdb_entry_port = kzalloc_obj(*mdb_entry_port); if (!mdb_entry_port) { err = -ENOMEM; goto err_mdb_entry_port_alloc; @@ -1195,7 +1195,7 @@ mlxsw_sp_mdb_entry_mrouter_port_get(struct mlxsw_sp *mlxsw_sp, if (err) return ERR_PTR(err); - mdb_entry_port = kzalloc(sizeof(*mdb_entry_port), GFP_KERNEL); + mdb_entry_port = kzalloc_obj(*mdb_entry_port); if (!mdb_entry_port) { err = -ENOMEM; goto err_mdb_entry_port_alloc; @@ -2027,7 +2027,7 @@ mlxsw_sp_mc_mdb_entry_init(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_mdb_entry *mdb_entry; int err; - mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL); + mdb_entry = kzalloc_obj(*mdb_entry); if (!mdb_entry) return ERR_PTR(-ENOMEM); @@ -3784,7 +3784,7 @@ static int mlxsw_sp_switchdev_event(struct notifier_block *unused, if (!mlxsw_sp_port_dev_lower_find_rcu(br_dev)) return NOTIFY_DONE; - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; @@ -4169,7 +4169,7 @@ int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp) { struct mlxsw_sp_bridge *bridge; - bridge = kzalloc(sizeof(*mlxsw_sp->bridge), GFP_KERNEL); + bridge = kzalloc_obj(*mlxsw_sp->bridge); if (!bridge) return -ENOMEM; mlxsw_sp->bridge = bridge; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c index 11745a2d8a44..401c2196b9ff 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c @@ -1145,6 +1145,9 @@ static int fbnic_set_cls_rule_ins(struct fbnic_net *fbn, return -EINVAL; } + dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, + FBNIC_RCD_HDR_AL_DMA_HINT_L4); + /* Write action table values */ act_tcam->dest = dest; act_tcam->rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, hash_idx); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c index 85a883dba385..d8a9a7d7c237 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_fw_log.c @@ -51,8 +51,6 @@ int fbnic_fw_log_init(struct fbnic_dev *fbd) log->data_start = data; log->data_end = data + FBNIC_FW_LOG_SIZE; - fbnic_fw_log_enable(fbd, true); - return 0; } @@ -63,7 +61,6 @@ void fbnic_fw_log_free(struct fbnic_dev *fbd) if (!fbnic_fw_log_ready(fbd)) return; - fbnic_fw_log_disable(fbd); INIT_LIST_HEAD(&log->entries); log->size = 0; vfree(log->data_start); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c index 81c9d5c9a4b2..b4b396ca9bce 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_netdev.c @@ -262,6 +262,23 @@ static int fbnic_set_mac(struct net_device *netdev, void *p) return 0; } +static int fbnic_change_mtu(struct net_device *dev, int new_mtu) +{ + struct fbnic_net *fbn = netdev_priv(dev); + + if (fbnic_check_split_frames(fbn->xdp_prog, new_mtu, fbn->hds_thresh)) { + dev_err(&dev->dev, + "MTU %d is larger than HDS threshold %d in XDP mode\n", + new_mtu, fbn->hds_thresh); + + return -EINVAL; + } + + WRITE_ONCE(dev->mtu, new_mtu); + + return 0; +} + void fbnic_clear_rx_mode(struct fbnic_dev *fbd) { struct net_device *netdev = fbd->netdev; @@ -533,6 +550,7 @@ static const struct net_device_ops fbnic_netdev_ops = { .ndo_start_xmit = fbnic_xmit_frame, .ndo_features_check = fbnic_features_check, .ndo_set_mac_address = fbnic_set_mac, + .ndo_change_mtu = fbnic_change_mtu, .ndo_set_rx_mode = fbnic_set_rx_mode, .ndo_get_stats64 = fbnic_get_stats64, .ndo_bpf = fbnic_bpf, @@ -787,6 +805,8 @@ struct net_device *fbnic_netdev_alloc(struct fbnic_dev *fbd) netdev->hw_enc_features |= netdev->features; netdev->features |= NETIF_F_NTUPLE; + netdev->xdp_features = NETDEV_XDP_ACT_BASIC | NETDEV_XDP_ACT_RX_SG; + netdev->min_mtu = IPV6_MIN_MTU; netdev->max_mtu = FBNIC_MAX_JUMBO_FRAME_SIZE - ETH_HLEN; diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c index 6f9389748a7d..3fa9d1910daa 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_pci.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_pci.c @@ -311,11 +311,17 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto free_irqs; } + err = fbnic_fw_log_init(fbd); + if (err) + dev_warn(fbd->dev, + "Unable to initialize firmware log buffer: %d\n", + err); + err = fbnic_fw_request_mbx(fbd); if (err) { dev_err(&pdev->dev, "Firmware mailbox initialization failure\n"); - goto free_irqs; + goto free_fw_log; } /* Send the request to enable the FW logging to host. Note if this @@ -323,11 +329,7 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * possible the FW is just too old to support the logging and needs * to be updated. */ - err = fbnic_fw_log_init(fbd); - if (err) - dev_warn(fbd->dev, - "Unable to initialize firmware log buffer: %d\n", - err); + fbnic_fw_log_enable(fbd, true); fbnic_devlink_register(fbd); fbnic_devlink_otp_check(fbd, "error detected during probe"); @@ -374,6 +376,8 @@ static int fbnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) * firmware updates for fixes. */ return 0; +free_fw_log: + fbnic_fw_log_free(fbd); free_irqs: fbnic_free_irqs(fbd); err_destroy_health: @@ -408,8 +412,9 @@ static void fbnic_remove(struct pci_dev *pdev) fbnic_hwmon_unregister(fbd); fbnic_dbg_fbd_exit(fbd); fbnic_devlink_unregister(fbd); - fbnic_fw_log_free(fbd); + fbnic_fw_log_disable(fbd); fbnic_fw_free_mbx(fbd); + fbnic_fw_log_free(fbd); fbnic_free_irqs(fbd); fbnic_devlink_health_destroy(fbd); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c index 7f31e890031c..42a186db43ea 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_rpc.c @@ -338,9 +338,8 @@ void fbnic_rss_reinit(struct fbnic_dev *fbd, struct fbnic_net *fbn) else if (tstamp_mask & (1u << flow_type)) dest |= FBNIC_RPC_ACT_TBL0_TS_ENA; - if (act1_value[flow_type] & FBNIC_RPC_TCAM_ACT1_L4_VALID) - dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, - FBNIC_RCD_HDR_AL_DMA_HINT_L4); + dest |= FIELD_PREP(FBNIC_RPC_ACT_TBL0_DMA_HINT, + FBNIC_RCD_HDR_AL_DMA_HINT_L4); rss_en_mask = fbnic_flow_hash_2_rss_en_mask(fbn, flow_type); diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c index e29959241ff3..9fb91d4f3971 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c +++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.c @@ -1640,7 +1640,7 @@ static int fbnic_alloc_napi_vector(struct fbnic_dev *fbd, struct fbnic_net *fbn, return -EIO; /* Allocate NAPI vector and queue triads */ - nv = kzalloc(struct_size(nv, qt, qt_count), GFP_KERNEL); + nv = kzalloc_flex(*nv, qt, qt_count); if (!nv) return -ENOMEM; @@ -2591,7 +2591,8 @@ static void fbnic_enable_bdq(struct fbnic_ring *hpq, struct fbnic_ring *ppq) } static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, - struct fbnic_ring *rcq, bool tx_pause) + struct fbnic_ring *rcq, bool tx_pause, + bool hdr_split) { struct fbnic_net *fbn = netdev_priv(nv->napi.dev); u32 drop_mode, rcq_ctl; @@ -2604,22 +2605,26 @@ static void fbnic_config_drop_mode_rcq(struct fbnic_napi_vector *nv, /* Specify packet layout */ rcq_ctl = FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_DROP_MODE_MASK, drop_mode) | FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_HROOM_MASK, FBNIC_RX_HROOM) | - FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM); + FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_MIN_TROOM_MASK, FBNIC_RX_TROOM) | + FIELD_PREP(FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT, hdr_split); fbnic_ring_wr32(rcq, FBNIC_QUEUE_RDE_CTL0, rcq_ctl); } -void fbnic_config_drop_mode(struct fbnic_net *fbn, bool tx_pause) +void fbnic_config_drop_mode(struct fbnic_net *fbn, bool txp) { + bool hds; int i, t; + hds = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; + for (i = 0; i < fbn->num_napi; i++) { struct fbnic_napi_vector *nv = fbn->napi[i]; for (t = 0; t < nv->rxt_count; t++) { struct fbnic_q_triad *qt = &nv->qt[nv->txt_count + t]; - fbnic_config_drop_mode_rcq(nv, &qt->cmpl, tx_pause); + fbnic_config_drop_mode_rcq(nv, &qt->cmpl, txp, hds); } } } @@ -2670,20 +2675,18 @@ static void fbnic_enable_rcq(struct fbnic_napi_vector *nv, { struct fbnic_net *fbn = netdev_priv(nv->napi.dev); u32 log_size = fls(rcq->size_mask); - u32 hds_thresh = fbn->hds_thresh; u32 rcq_ctl = 0; - - fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause); + bool hdr_split; + u32 hds_thresh; /* Force lower bound on MAX_HEADER_BYTES. Below this, all frames should * be split at L4. It would also result in the frames being split at * L2/L3 depending on the frame size. */ - if (fbn->hds_thresh < FBNIC_HDR_BYTES_MIN) { - rcq_ctl = FBNIC_QUEUE_RDE_CTL0_EN_HDR_SPLIT; - hds_thresh = FBNIC_HDR_BYTES_MIN; - } + hdr_split = fbn->hds_thresh < FBNIC_HDR_BYTES_MIN; + fbnic_config_drop_mode_rcq(nv, rcq, fbn->tx_pause, hdr_split); + hds_thresh = max(fbn->hds_thresh, FBNIC_HDR_BYTES_MIN); rcq_ctl |= FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PADLEN_MASK, FBNIC_RX_PAD) | FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_MAX_HDR_MASK, hds_thresh) | FIELD_PREP(FBNIC_QUEUE_RDE_CTL1_PAYLD_OFF_MASK, diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h index b9560103ab86..980965274079 100644 --- a/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +++ b/drivers/net/ethernet/meta/fbnic/fbnic_txrx.h @@ -66,7 +66,7 @@ struct fbnic_net; (4096 - FBNIC_RX_HROOM - FBNIC_RX_TROOM - FBNIC_RX_PAD) #define FBNIC_HDS_THRESH_DEFAULT \ (1536 - FBNIC_RX_PAD) -#define FBNIC_HDR_BYTES_MIN 128 +#define FBNIC_HDR_BYTES_MIN 256 struct fbnic_pkt_buff { struct xdp_buff buff; diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 491e9ce3d9b0..26557cd32008 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -3991,8 +3991,7 @@ static void ksz_update_timer(struct ksz_timer_info *info) */ static int ksz_alloc_soft_desc(struct ksz_desc_info *desc_info, int transmit) { - desc_info->ring = kcalloc(desc_info->alloc, sizeof(struct ksz_desc), - GFP_KERNEL); + desc_info->ring = kzalloc_objs(struct ksz_desc, desc_info->alloc); if (!desc_info->ring) return 1; hw_init_desc(desc_info, transmit); @@ -6577,7 +6576,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) result = -ENOMEM; - info = kzalloc(sizeof(struct platform_info), GFP_KERNEL); + info = kzalloc_obj(struct platform_info); if (!info) goto pcidev_init_dev_err; @@ -6630,7 +6629,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) mib_port_count = SWITCH_PORT_NUM; } hw->mib_port_cnt = TOTAL_PORT_NUM; - hw->ksz_switch = kzalloc(sizeof(struct ksz_switch), GFP_KERNEL); + hw->ksz_switch = kzalloc_obj(struct ksz_switch); if (!hw->ksz_switch) goto pcidev_init_alloc_err; diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index e4c542fc6c2b..a3845edf0e48 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c @@ -2141,7 +2141,7 @@ static int lan743x_tx_ring_init(struct lan743x_tx *tx) tx->ring_cpu_ptr = (struct lan743x_tx_descriptor *)cpu_ptr; tx->ring_dma_ptr = dma_ptr; - cpu_ptr = kcalloc(tx->ring_size, sizeof(*tx->buffer_info), GFP_KERNEL); + cpu_ptr = kzalloc_objs(*tx->buffer_info, tx->ring_size); if (!cpu_ptr) { ret = -ENOMEM; goto cleanup; @@ -2686,8 +2686,7 @@ static int lan743x_rx_ring_init(struct lan743x_rx *rx) rx->ring_cpu_ptr = (struct lan743x_rx_descriptor *)cpu_ptr; rx->ring_dma_ptr = dma_ptr; - cpu_ptr = kcalloc(rx->ring_size, sizeof(*rx->buffer_info), - GFP_KERNEL); + cpu_ptr = kzalloc_objs(*rx->buffer_info, rx->ring_size); if (!cpu_ptr) { ret = -ENOMEM; goto cleanup; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdb.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdb.c index 2ea263e893ee..95cbbe5b513a 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdb.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdb.c @@ -46,7 +46,7 @@ static void lan966x_fdb_add_entry(struct lan966x *lan966x, return; } - fdb_entry = kzalloc(sizeof(*fdb_entry), GFP_KERNEL); + fdb_entry = kzalloc_obj(*fdb_entry); if (!fdb_entry) return; @@ -262,7 +262,7 @@ int lan966x_handle_fdb(struct net_device *dev, !fdb_info->added_by_user) break; - fdb_work = kzalloc(sizeof(*fdb_work), GFP_ATOMIC); + fdb_work = kzalloc_obj(*fdb_work, GFP_ATOMIC); if (!fdb_work) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c index 502670718104..7b6369e43451 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_fdma.c @@ -200,8 +200,7 @@ static int lan966x_fdma_tx_alloc(struct lan966x_tx *tx) struct fdma *fdma = &tx->fdma; int err; - tx->dcbs_buf = kcalloc(fdma->n_dcbs, sizeof(struct lan966x_tx_dcb_buf), - GFP_KERNEL); + tx->dcbs_buf = kzalloc_objs(struct lan966x_tx_dcb_buf, fdma->n_dcbs); if (!tx->dcbs_buf) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c index baa3a30c039f..7a2294a0d099 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mac.c @@ -206,7 +206,7 @@ static struct lan966x_mac_entry *lan966x_mac_alloc_entry(struct lan966x_port *po { struct lan966x_mac_entry *mac_entry; - mac_entry = kzalloc(sizeof(*mac_entry), GFP_ATOMIC); + mac_entry = kzalloc_obj(*mac_entry, GFP_ATOMIC); if (!mac_entry) return NULL; diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_mdb.c b/drivers/net/ethernet/microchip/lan966x/lan966x_mdb.c index 2af55268bf4d..a4722140675d 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_mdb.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_mdb.c @@ -74,7 +74,7 @@ lan966x_mdb_entry_add(struct lan966x *lan966x, { struct lan966x_mdb_entry *mdb_entry; - mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL); + mdb_entry = kzalloc_obj(*mdb_entry); if (!mdb_entry) return ERR_PTR(-ENOMEM); @@ -184,7 +184,7 @@ lan966x_pgid_entry_add(struct lan966x *lan966x, int index, u16 ports) { struct lan966x_pgid_entry *pgid_entry; - pgid_entry = kzalloc(sizeof(*pgid_entry), GFP_KERNEL); + pgid_entry = kzalloc_obj(*pgid_entry); if (!pgid_entry) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c b/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c index 2a37fc1ba4bc..72e3b189bac5 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_vcap_impl.c @@ -611,7 +611,7 @@ lan966x_vcap_admin_alloc(struct lan966x *lan966x, struct vcap_control *ctrl, { struct vcap_admin *admin; - admin = kzalloc(sizeof(*admin), GFP_KERNEL); + admin = kzalloc_obj(*admin); if (!admin) return ERR_PTR(-ENOMEM); @@ -712,7 +712,7 @@ int lan966x_vcap_init(struct lan966x *lan966x) struct vcap_admin *admin; struct dentry *dir; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c index 1282f5c3ee6d..c7e0e58ff0f7 100644 --- a/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c +++ b/drivers/net/ethernet/microchip/sparx5/lan969x/lan969x_fdma.c @@ -186,9 +186,7 @@ static int lan969x_fdma_tx_alloc(struct sparx5 *sparx5) struct fdma *fdma = &tx->fdma; int err; - tx->dbs = kcalloc(fdma->n_dcbs, - sizeof(struct sparx5_tx_buf), - GFP_KERNEL); + tx->dbs = kzalloc_objs(struct sparx5_tx_buf, fdma->n_dcbs); if (!tx->dbs) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c index 5c46d81de530..8c67ff1d411b 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_calendar.c @@ -585,7 +585,7 @@ int sparx5_config_dsm_calendar(struct sparx5 *sparx5) struct sparx5_calendar_data *data; int err = 0; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c index 582145713cfd..9befd0719f74 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c @@ -889,8 +889,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev) } sparx5->port_count = of_get_child_count(ports); - configs = kcalloc(sparx5->port_count, - sizeof(struct initial_port_config), GFP_KERNEL); + configs = kzalloc_objs(struct initial_port_config, sparx5->port_count); if (!configs) { err = -ENOMEM; goto cleanup_pnode; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c index 2f168700f63c..8b2e07821a95 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_ptp.c @@ -576,7 +576,7 @@ static int sparx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) static struct ptp_clock_info sparx5_ptp_clock_info = { .owner = THIS_MODULE, .name = "sparx5 ptp", - .max_adj = 200000, + .max_adj = 10000000, .gettime64 = sparx5_ptp_gettime64, .settime64 = sparx5_ptp_settime64, .adjtime = sparx5_ptp_adjtime, diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h index 1231a80335d7..04f76f1e23f6 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_qos.h @@ -35,7 +35,7 @@ #define SPX5_SE_BURST_UNIT 4096 /* Dwrr */ -#define SPX5_DWRR_COST_MAX 63 +#define SPX5_DWRR_COST_MAX 31 struct sparx5_shaper { u32 mode; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c index 0a71abbd3da5..644458108dd2 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_switchdev.c @@ -398,7 +398,7 @@ static int sparx5_switchdev_event(struct notifier_block *nb, case SWITCHDEV_FDB_ADD_TO_DEVICE: fallthrough; case SWITCHDEV_FDB_DEL_TO_DEVICE: - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (!switchdev_work) return NOTIFY_BAD; @@ -465,7 +465,7 @@ static int sparx5_alloc_mdb_entry(struct sparx5 *sparx5, u16 pgid_idx; int err; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index 4dc1ebd5d510..f779a5c00803 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c @@ -1464,7 +1464,7 @@ static int sparx5_tc_flower_template_create(struct net_device *ndev, return -EBUSY; } - ftp = kzalloc(sizeof(*ftp), GFP_KERNEL); + ftp = kzalloc_obj(*ftp); if (!ftp) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c index 6b4d1d7b9730..702257979462 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_matchall.c @@ -60,7 +60,7 @@ static int sparx5_tc_matchall_replace(struct net_device *ndev, } action = &tmo->rule->action.entries[0]; - mall_entry = kzalloc(sizeof(*mall_entry), GFP_KERNEL); + mall_entry = kzalloc_obj(*mall_entry); if (!mall_entry) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c index 25066ddb8d4d..3d64a0448d43 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c @@ -1944,7 +1944,7 @@ sparx5_vcap_admin_alloc(struct sparx5 *sparx5, struct vcap_control *ctrl, { struct vcap_admin *admin; - admin = kzalloc(sizeof(*admin), GFP_KERNEL); + admin = kzalloc_obj(*admin); if (!admin) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&admin->list); @@ -2047,7 +2047,7 @@ int sparx5_vcap_init(struct sparx5 *sparx5) * - Initialize VCAP blocks * - Configure port keysets */ - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index 2687765abe52..0fdb5e363bad 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -1004,7 +1004,7 @@ static struct vcap_rule_internal *vcap_dup_rule(struct vcap_rule_internal *ri, struct vcap_rule_internal *duprule; /* Allocate the client part */ - duprule = kzalloc(sizeof(*duprule), GFP_KERNEL); + duprule = kzalloc_obj(*duprule); if (!duprule) return ERR_PTR(-ENOMEM); *duprule = *ri; @@ -1309,7 +1309,7 @@ static void vcap_rule_alloc_keyfield(struct vcap_rule_internal *ri, { struct vcap_client_keyfield *field; - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) return; INIT_LIST_HEAD(&field->ctrl.list); @@ -1418,7 +1418,7 @@ static void vcap_rule_alloc_actionfield(struct vcap_rule_internal *ri, { struct vcap_client_actionfield *field; - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) return; INIT_LIST_HEAD(&field->ctrl.list); @@ -2345,7 +2345,7 @@ struct vcap_rule *vcap_alloc_rule(struct vcap_control *vctrl, } /* Create a container for the rule and return it */ - ri = kzalloc(sizeof(*ri), GFP_KERNEL); + ri = kzalloc_obj(*ri); if (!ri) { err = -ENOMEM; goto out_unlock; @@ -2689,7 +2689,7 @@ static int vcap_rule_add_key(struct vcap_rule *rule, return -EINVAL; } - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) return -ENOMEM; memcpy(&field->data, data, sizeof(field->data)); @@ -2857,7 +2857,7 @@ static int vcap_rule_add_action(struct vcap_rule *rule, return -EINVAL; } - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) return -ENOMEM; memcpy(&field->data, data, sizeof(field->data)); @@ -3125,7 +3125,7 @@ static int vcap_enable(struct vcap_control *vctrl, struct net_device *ndev, if (!admin) return -ENOENT; - eport = kzalloc(sizeof(*eport), GFP_KERNEL); + eport = kzalloc_obj(*eport); if (!eport) return -ENOMEM; diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c index 16eb3de60eb6..ce26ccbdccdf 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c @@ -2037,7 +2037,7 @@ static void vcap_api_filter_unsupported_keys_test(struct kunit *test) /* Add all keys to the rule */ INIT_LIST_HEAD(&ri.data.keyfields); for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { - ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); + ckf = kzalloc_obj(*ckf); if (ckf) { ckf->ctrl.key = keylist[idx]; list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); @@ -2161,7 +2161,7 @@ static void vcap_api_filter_keylist_test(struct kunit *test) /* Add all keys to the rule */ INIT_LIST_HEAD(&ri.data.keyfields); for (idx = 0; idx < ARRAY_SIZE(keylist); idx++) { - ckf = kzalloc(sizeof(*ckf), GFP_KERNEL); + ckf = kzalloc_obj(*ckf); if (ckf) { ckf->ctrl.key = keylist[idx]; list_add_tail(&ckf->ctrl.list, &ri.data.keyfields); diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c b/drivers/net/ethernet/microsoft/mana/gdma_main.c index 0055c231acf6..786186c9a115 100644 --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c @@ -634,7 +634,7 @@ static void mana_gd_process_eqe(struct gdma_queue *eq) break; } - mns_wk = kzalloc(sizeof(*mns_wk), GFP_ATOMIC); + mns_wk = kzalloc_obj(*mns_wk, GFP_ATOMIC); if (!mns_wk) { module_put(THIS_MODULE); break; @@ -923,7 +923,7 @@ int mana_gd_create_hwc_queue(struct gdma_dev *gd, struct gdma_queue *queue; int err; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return -ENOMEM; @@ -1062,7 +1062,7 @@ int mana_gd_create_mana_eq(struct gdma_dev *gd, if (spec->type != GDMA_EQ) return -EINVAL; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return -ENOMEM; @@ -1115,7 +1115,7 @@ int mana_gd_create_mana_wq_cq(struct gdma_dev *gd, spec->type != GDMA_RQ) return -EINVAL; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return -ENOMEM; @@ -1625,7 +1625,7 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec) bool skip_first_cpu = false; int *irqs, irq, err, i; - irqs = kmalloc_array(nvec, sizeof(int), GFP_KERNEL); + irqs = kmalloc_objs(int, nvec); if (!irqs) return -ENOMEM; @@ -1636,7 +1636,7 @@ static int mana_gd_setup_dyn_irqs(struct pci_dev *pdev, int nvec) * further used in irq_setup() */ for (i = 1; i <= nvec; i++) { - gic = kzalloc(sizeof(*gic), GFP_KERNEL); + gic = kzalloc_obj(*gic); if (!gic) { err = -ENOMEM; goto free_irq; @@ -1707,14 +1707,14 @@ static int mana_gd_setup_irqs(struct pci_dev *pdev, int nvec) unsigned int cpu; int err, i; - irqs = kmalloc_array(nvec, sizeof(int), GFP_KERNEL); + irqs = kmalloc_objs(int, nvec); if (!irqs) return -ENOMEM; start_irqs = irqs; for (i = 0; i < nvec; i++) { - gic = kzalloc(sizeof(*gic), GFP_KERNEL); + gic = kzalloc_obj(*gic); if (!gic) { err = -ENOMEM; goto free_irq; @@ -1934,6 +1934,7 @@ static int mana_gd_setup(struct pci_dev *pdev) mana_gd_remove_irqs(pdev); free_workqueue: destroy_workqueue(gc->service_wq); + gc->service_wq = NULL; dev_err(&pdev->dev, "%s failed (error %d)\n", __func__, err); return err; } @@ -1946,7 +1947,10 @@ static void mana_gd_cleanup(struct pci_dev *pdev) mana_gd_remove_irqs(pdev); - destroy_workqueue(gc->service_wq); + if (gc->service_wq) { + destroy_workqueue(gc->service_wq); + gc->service_wq = NULL; + } dev_dbg(&pdev->dev, "mana gdma cleanup successful\n"); } @@ -2071,7 +2075,7 @@ static int mana_gd_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_info(&pdev->dev, "Start MANA recovery mode\n"); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return err; diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c index aa4e2731e2ba..ba3467f1e2ea 100644 --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c @@ -407,7 +407,7 @@ static int mana_hwc_create_cq(struct hw_channel_context *hwc, u16 q_depth, if (cq_size < MANA_MIN_QSIZE) cq_size = MANA_MIN_QSIZE; - hwc_cq = kzalloc(sizeof(*hwc_cq), GFP_KERNEL); + hwc_cq = kzalloc_obj(*hwc_cq); if (!hwc_cq) return -ENOMEM; @@ -426,7 +426,7 @@ static int mana_hwc_create_cq(struct hw_channel_context *hwc, u16 q_depth, } hwc_cq->gdma_cq = cq; - comp_buf = kcalloc(q_depth, sizeof(*comp_buf), GFP_KERNEL); + comp_buf = kzalloc_objs(*comp_buf, q_depth); if (!comp_buf) { err = -ENOMEM; goto out; @@ -461,7 +461,7 @@ static int mana_hwc_alloc_dma_buf(struct hw_channel_context *hwc, u16 q_depth, int err; u16 i; - dma_buf = kzalloc(struct_size(dma_buf, reqs, q_depth), GFP_KERNEL); + dma_buf = kzalloc_flex(*dma_buf, reqs, q_depth); if (!dma_buf) return -ENOMEM; @@ -539,7 +539,7 @@ static int mana_hwc_create_wq(struct hw_channel_context *hwc, if (queue_size < MANA_MIN_QSIZE) queue_size = MANA_MIN_QSIZE; - hwc_wq = kzalloc(sizeof(*hwc_wq), GFP_KERNEL); + hwc_wq = kzalloc_obj(*hwc_wq); if (!hwc_wq) return -ENOMEM; @@ -644,7 +644,7 @@ static int mana_hwc_test_channel(struct hw_channel_context *hwc, u16 q_depth, return err; } - ctx = kcalloc(q_depth, sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_objs(*ctx, q_depth); if (!ctx) return -ENOMEM; @@ -750,7 +750,7 @@ int mana_hwc_create_channel(struct gdma_context *gc) u16 q_depth_max; int err; - hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); + hwc = kzalloc_obj(*hwc); if (!hwc) return -ENOMEM; diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c index 9b5a72ada5c4..9017e806ecda 100644 --- a/drivers/net/ethernet/microsoft/mana/mana_en.c +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c @@ -491,9 +491,8 @@ netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev) if (pkg.wqe_req.num_sge <= ARRAY_SIZE(pkg.sgl_array)) { pkg.wqe_req.sgl = pkg.sgl_array; } else { - pkg.sgl_ptr = kmalloc_array(pkg.wqe_req.num_sge, - sizeof(struct gdma_sge), - GFP_ATOMIC); + pkg.sgl_ptr = kmalloc_objs(struct gdma_sge, pkg.wqe_req.num_sge, + GFP_ATOMIC); if (!pkg.sgl_ptr) goto tx_drop_count; @@ -804,7 +803,7 @@ int mana_pre_alloc_rxbufs(struct mana_port_context *mpc, int new_mtu, int num_qu if (!mpc->rxbufs_pre) goto error; - mpc->das_pre = kmalloc_array(num_rxb, sizeof(dma_addr_t), GFP_KERNEL); + mpc->das_pre = kmalloc_objs(dma_addr_t, num_rxb); if (!mpc->das_pre) goto error; @@ -996,8 +995,7 @@ static void mana_cleanup_indir_table(struct mana_port_context *apc) static int mana_init_port_context(struct mana_port_context *apc) { - apc->rxqs = kcalloc(apc->num_queues, sizeof(struct mana_rxq *), - GFP_KERNEL); + apc->rxqs = kzalloc_objs(struct mana_rxq *, apc->num_queues); return !apc->rxqs ? -ENOMEM : 0; } @@ -1634,8 +1632,7 @@ static int mana_create_eq(struct mana_context *ac) int err; int i; - ac->eqs = kcalloc(gc->max_num_queues, sizeof(struct mana_eq), - GFP_KERNEL); + ac->eqs = kzalloc_objs(struct mana_eq, gc->max_num_queues); if (!ac->eqs) return -ENOMEM; @@ -1773,8 +1770,14 @@ static void mana_poll_tx_cq(struct mana_cq *cq) ndev = txq->ndev; apc = netdev_priv(ndev); + /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the + * doorbell can be rung in time for the hardware's requirement + * of at least one doorbell ring every 8 wraparounds. + */ comp_read = mana_gd_poll_cq(cq->gdma_cq, completions, - CQE_POLLING_BUFFER); + min((cq->gdma_cq->queue_size / + COMP_ENTRY_SIZE) * 4, + CQE_POLLING_BUFFER)); if (comp_read < 1) return; @@ -2159,7 +2162,14 @@ static void mana_poll_rx_cq(struct mana_cq *cq) struct mana_rxq *rxq = cq->rxq; int comp_read, i; - comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, CQE_POLLING_BUFFER); + /* Limit CQEs polled to 4 wraparounds of the CQ to ensure the + * doorbell can be rung in time for the hardware's requirement + * of at least one doorbell ring every 8 wraparounds. + */ + comp_read = mana_gd_poll_cq(cq->gdma_cq, comp, + min((cq->gdma_cq->queue_size / + COMP_ENTRY_SIZE) * 4, + CQE_POLLING_BUFFER)); WARN_ON_ONCE(comp_read > CQE_POLLING_BUFFER); rxq->xdp_flush = false; @@ -2204,11 +2214,11 @@ static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue) mana_gd_ring_cq(gdma_queue, SET_ARM_BIT); cq->work_done_since_doorbell = 0; napi_complete_done(&cq->napi, w); - } else if (cq->work_done_since_doorbell > - cq->gdma_cq->queue_size / COMP_ENTRY_SIZE * 4) { + } else if (cq->work_done_since_doorbell >= + (cq->gdma_cq->queue_size / COMP_ENTRY_SIZE) * 4) { /* MANA hardware requires at least one doorbell ring every 8 * wraparounds of CQ even if there is no need to arm the CQ. - * This driver rings the doorbell as soon as we have exceeded + * This driver rings the doorbell as soon as it has processed * 4 wraparounds. */ mana_gd_ring_cq(gdma_queue, 0); @@ -2329,8 +2339,7 @@ static int mana_create_txq(struct mana_port_context *apc, int err; int i; - apc->tx_qp = kcalloc(apc->num_queues, sizeof(struct mana_tx_qp), - GFP_KERNEL); + apc->tx_qp = kzalloc_objs(struct mana_tx_qp, apc->num_queues); if (!apc->tx_qp) return -ENOMEM; @@ -2640,8 +2649,7 @@ static struct mana_rxq *mana_create_rxq(struct mana_port_context *apc, gc = gd->gdma_context; - rxq = kzalloc(struct_size(rxq, rx_oobs, apc->rx_queue_size), - GFP_KERNEL); + rxq = kzalloc_flex(*rxq, rx_oobs, apc->rx_queue_size); if (!rxq) return NULL; @@ -2856,7 +2864,7 @@ static int mana_rss_table_alloc(struct mana_port_context *apc) if (!apc->indir_table) return -ENOMEM; - apc->rxobj_table = kcalloc(apc->indir_table_sz, sizeof(mana_handle_t), GFP_KERNEL); + apc->rxobj_table = kzalloc_objs(mana_handle_t, apc->indir_table_sz); if (!apc->rxobj_table) { kfree(apc->indir_table); return -ENOMEM; @@ -3418,7 +3426,7 @@ static int add_adev(struct gdma_dev *gd, const char *name) struct mana_adev *madev; int ret; - madev = kzalloc(sizeof(*madev), GFP_KERNEL); + madev = kzalloc_obj(*madev); if (!madev) return -ENOMEM; @@ -3511,7 +3519,7 @@ int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type even return 0; } - serv_work = kzalloc(sizeof(*serv_work), GFP_ATOMIC); + serv_work = kzalloc_obj(*serv_work, GFP_ATOMIC); if (!serv_work) return -ENOMEM; @@ -3562,7 +3570,7 @@ int mana_probe(struct gdma_dev *gd, bool resuming) return err; if (!resuming) { - ac = kzalloc(sizeof(*ac), GFP_KERNEL); + ac = kzalloc_obj(*ac); if (!ac) return -ENOMEM; @@ -3762,7 +3770,9 @@ void mana_rdma_remove(struct gdma_dev *gd) } WRITE_ONCE(gd->rdma_teardown, true); - flush_workqueue(gc->service_wq); + + if (gc->service_wq) + flush_workqueue(gc->service_wq); if (gd->adev) remove_adev(gd); diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index c345d9b17c89..67ecd0e91002 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -576,7 +576,7 @@ static int ocelot_update_vlan_reclassify_rule(struct ocelot *ocelot, int port) } /* Filter doesn't exist, create it */ - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; @@ -682,7 +682,7 @@ static int ocelot_vlan_member_add(struct ocelot *ocelot, int port, u16 vid, return 0; } - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return -ENOMEM; @@ -1664,7 +1664,7 @@ int ocelot_trap_add(struct ocelot *ocelot, int port, trap = ocelot_vcap_block_find_filter_by_id(block_vcap_is2, cookie, false); if (!trap) { - trap = kzalloc(sizeof(*trap), GFP_KERNEL); + trap = kzalloc_obj(*trap); if (!trap) return -ENOMEM; @@ -2046,7 +2046,7 @@ static struct ocelot_pgid *ocelot_pgid_alloc(struct ocelot *ocelot, int index, { struct ocelot_pgid *pgid; - pgid = kzalloc(sizeof(*pgid), GFP_KERNEL); + pgid = kzalloc_obj(*pgid); if (!pgid) return ERR_PTR(-ENOMEM); @@ -2563,7 +2563,7 @@ int ocelot_lag_fdb_add(struct ocelot *ocelot, struct net_device *bond, struct ocelot_lag_fdb *fdb; int lag, err; - fdb = kzalloc(sizeof(*fdb), GFP_KERNEL); + fdb = kzalloc_obj(*fdb); if (!fdb) return -ENOMEM; @@ -2894,7 +2894,7 @@ struct ocelot_mirror *ocelot_mirror_get(struct ocelot *ocelot, int to, return m; } - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (!m) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 986b1f150e3b..844292eb7422 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -833,7 +833,7 @@ static struct ocelot_vcap_filter { struct ocelot_vcap_filter *filter; - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return NULL; diff --git a/drivers/net/ethernet/mscc/ocelot_mrp.c b/drivers/net/ethernet/mscc/ocelot_mrp.c index 3ccec488a304..51e0157c4dac 100644 --- a/drivers/net/ethernet/mscc/ocelot_mrp.c +++ b/drivers/net/ethernet/mscc/ocelot_mrp.c @@ -54,7 +54,7 @@ static int ocelot_mrp_redirect_add_vcap(struct ocelot *ocelot, int src_port, struct ocelot_vcap_filter *filter; int err; - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) return -ENOMEM; diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index 469784d3a1a6..1b8269320464 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -551,7 +551,28 @@ static int ocelot_port_stop(struct net_device *dev) return 0; } -static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) +static bool ocelot_xmit_timestamp(struct ocelot *ocelot, int port, + struct sk_buff *skb, u32 *rew_op) +{ + if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { + struct sk_buff *clone = NULL; + + if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { + kfree_skb(skb); + return false; + } + + if (clone) + OCELOT_SKB_CB(skb)->clone = clone; + + *rew_op = ocelot_ptp_rew_op(skb); + } + + return true; +} + +static netdev_tx_t ocelot_port_xmit_fdma(struct sk_buff *skb, + struct net_device *dev) { struct ocelot_port_private *priv = netdev_priv(dev); struct ocelot_port *ocelot_port = &priv->port; @@ -559,36 +580,52 @@ static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) int port = priv->port.index; u32 rew_op = 0; - if (!static_branch_unlikely(&ocelot_fdma_enabled) && - !ocelot_can_inject(ocelot, 0)) - return NETDEV_TX_BUSY; + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) + return NETDEV_TX_OK; - /* Check if timestamping is needed */ - if (ocelot->ptp && (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) { - struct sk_buff *clone = NULL; - - if (ocelot_port_txtstamp_request(ocelot, port, skb, &clone)) { - kfree_skb(skb); - return NETDEV_TX_OK; - } - - if (clone) - OCELOT_SKB_CB(skb)->clone = clone; - - rew_op = ocelot_ptp_rew_op(skb); - } - - if (static_branch_unlikely(&ocelot_fdma_enabled)) { - ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); - } else { - ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); - - consume_skb(skb); - } + ocelot_fdma_inject_frame(ocelot, port, rew_op, skb, dev); return NETDEV_TX_OK; } +static netdev_tx_t ocelot_port_xmit_inj(struct sk_buff *skb, + struct net_device *dev) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + int port = priv->port.index; + u32 rew_op = 0; + + ocelot_lock_inj_grp(ocelot, 0); + + if (!ocelot_can_inject(ocelot, 0)) { + ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_BUSY; + } + + if (!ocelot_xmit_timestamp(ocelot, port, skb, &rew_op)) { + ocelot_unlock_inj_grp(ocelot, 0); + return NETDEV_TX_OK; + } + + ocelot_port_inject_frame(ocelot, port, 0, rew_op, skb); + + ocelot_unlock_inj_grp(ocelot, 0); + + consume_skb(skb); + + return NETDEV_TX_OK; +} + +static netdev_tx_t ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) +{ + if (static_branch_unlikely(&ocelot_fdma_enabled)) + return ocelot_port_xmit_fdma(skb, dev); + + return ocelot_port_xmit_inj(skb, dev); +} + enum ocelot_action_type { OCELOT_MACT_LEARN, OCELOT_MACT_FORGET, diff --git a/drivers/net/ethernet/mscc/ocelot_vcap.c b/drivers/net/ethernet/mscc/ocelot_vcap.c index 5734b86aed5b..25e533e91d71 100644 --- a/drivers/net/ethernet/mscc/ocelot_vcap.c +++ b/drivers/net/ethernet/mscc/ocelot_vcap.c @@ -910,7 +910,7 @@ int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix, return 0; } - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 2f0cdbd4e2ac..e5e51d021b2c 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -688,9 +688,9 @@ static int myri10ge_get_firmware_capabilities(struct myri10ge_priv *mgp) /* probe for IPv6 TSO support */ mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO; - cmd.data0 = 0, - cmd.data1 = 0, - cmd.data2 = 0, + cmd.data0 = 0; + cmd.data1 = 0; + cmd.data2 = 0; status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE, &cmd, 0); if (status == 0) { @@ -821,9 +821,9 @@ static int myri10ge_change_pause(struct myri10ge_priv *mgp, int pause) int status, ctl; ctl = pause ? MXGEFW_ENABLE_FLOW_CONTROL : MXGEFW_DISABLE_FLOW_CONTROL; - cmd.data0 = 0, - cmd.data1 = 0, - cmd.data2 = 0, + cmd.data0 = 0; + cmd.data1 = 0; + cmd.data2 = 0; status = myri10ge_send_cmd(mgp, ctl, &cmd, 0); if (status) { @@ -3703,8 +3703,7 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp) * slices. We give up on MSI-X if we can only get a single * vector. */ - mgp->msix_vectors = kcalloc(mgp->num_slices, sizeof(*mgp->msix_vectors), - GFP_KERNEL); + mgp->msix_vectors = kzalloc_objs(*mgp->msix_vectors, mgp->num_slices); if (mgp->msix_vectors == NULL) goto no_msix; for (i = 0; i < mgp->num_slices; i++) { diff --git a/drivers/net/ethernet/netronome/nfp/abm/cls.c b/drivers/net/ethernet/netronome/nfp/abm/cls.c index 23ebddfb9532..f7894c415a2f 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/cls.c +++ b/drivers/net/ethernet/netronome/nfp/abm/cls.c @@ -203,7 +203,7 @@ nfp_abm_u32_knode_replace(struct nfp_abm_link *alink, } if (!match) { - match = kzalloc(sizeof(*match), GFP_KERNEL); + match = kzalloc_obj(*match); if (!match) return -ENOMEM; list_add(&match->list, &alink->dscp_map); diff --git a/drivers/net/ethernet/netronome/nfp/abm/main.c b/drivers/net/ethernet/netronome/nfp/abm/main.c index 5d3df28c648f..9b6bda523191 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/main.c +++ b/drivers/net/ethernet/netronome/nfp/abm/main.c @@ -317,7 +317,7 @@ nfp_abm_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) struct nfp_abm_link *alink; int err; - alink = kzalloc(sizeof(*alink), GFP_KERNEL); + alink = kzalloc_obj(*alink); if (!alink) return -ENOMEM; nn->app_priv = alink; @@ -461,7 +461,7 @@ static int nfp_abm_init(struct nfp_app *app) return -EINVAL; } - abm = kzalloc(sizeof(*abm), GFP_KERNEL); + abm = kzalloc_obj(*abm); if (!abm) return -ENOMEM; app->priv = abm; diff --git a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c index 2a5cc64227e9..900d416bcf8b 100644 --- a/drivers/net/ethernet/netronome/nfp/abm/qdisc.c +++ b/drivers/net/ethernet/netronome/nfp/abm/qdisc.c @@ -344,7 +344,7 @@ nfp_abm_qdisc_alloc(struct net_device *netdev, struct nfp_abm_link *alink, struct nfp_qdisc *qdisc; int err; - qdisc = kzalloc(sizeof(*qdisc), GFP_KERNEL); + qdisc = kzalloc_obj(*qdisc); if (!qdisc) return NULL; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c index f469950c7265..608c1bcaa641 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c @@ -76,7 +76,7 @@ nfp_bpf_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, unsigned int id) return -EINVAL; } - bv = kzalloc(sizeof(*bv), GFP_KERNEL); + bv = kzalloc_obj(*bv); if (!bv) return -ENOMEM; nn->app_priv = bv; @@ -458,7 +458,7 @@ static int nfp_bpf_init(struct nfp_app *app) struct nfp_app_bpf *bpf; int err; - bpf = kzalloc(sizeof(*bpf), GFP_KERNEL); + bpf = kzalloc_obj(*bpf); if (!bpf) return -ENOMEM; bpf->app = app; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c index c03558adda91..8a1773defd1b 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c @@ -48,7 +48,7 @@ nfp_map_ptr_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog, */ bpf_map_inc(map); - record = kmalloc(sizeof(*record), GFP_KERNEL); + record = kmalloc_obj(*record); if (!record) { err = -ENOMEM; goto err_map_put; @@ -123,9 +123,7 @@ nfp_map_ptrs_record(struct nfp_app_bpf *bpf, struct nfp_prog *nfp_prog, if (!cnt) goto out; - nfp_prog->map_records = kmalloc_array(cnt, - sizeof(nfp_prog->map_records[0]), - GFP_KERNEL); + nfp_prog->map_records = kmalloc_objs(nfp_prog->map_records[0], cnt); if (!nfp_prog->map_records) { err = -ENOMEM; goto out; @@ -155,7 +153,7 @@ nfp_prog_prepare(struct nfp_prog *nfp_prog, const struct bpf_insn *prog, unsigned int i; for (i = 0; i < cnt; i++) { - meta = kzalloc(sizeof(*meta), GFP_KERNEL); + meta = kzalloc_obj(*meta); if (!meta) return -ENOMEM; @@ -193,7 +191,7 @@ static int nfp_bpf_verifier_prep(struct bpf_prog *prog) struct nfp_prog *nfp_prog; int ret; - nfp_prog = kzalloc(sizeof(*nfp_prog), GFP_KERNEL); + nfp_prog = kzalloc_obj(*nfp_prog); if (!nfp_prog) return -ENOMEM; prog->aux->offload->dev_priv = nfp_prog; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 9d235c0ce46a..bc594860e2b5 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -770,8 +770,8 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env) nfp_prog = env->prog->aux->offload->dev_priv; nfp_prog->subprog_cnt = env->subprog_cnt; - nfp_prog->subprog = kcalloc(nfp_prog->subprog_cnt, - sizeof(nfp_prog->subprog[0]), GFP_KERNEL); + nfp_prog->subprog = kzalloc_objs(nfp_prog->subprog[0], + nfp_prog->subprog_cnt); if (!nfp_prog->subprog) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c index 15180538b80a..c983e8b1799d 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/conntrack.c +++ b/drivers/net/ethernet/netronome/nfp/flower/conntrack.c @@ -1355,7 +1355,7 @@ nfp_fl_ct_zone_entry *get_nfp_zone_entry(struct nfp_flower_priv *priv, if (IS_ERR(zt) || zt->priv) return zt; } else { - zt = kzalloc(sizeof(*zt), GFP_KERNEL); + zt = kzalloc_obj(*zt); if (!zt) return ERR_PTR(-ENOMEM); } @@ -1487,7 +1487,7 @@ nfp_fl_ct_flow_entry *nfp_fl_ct_add_flow(struct nfp_fl_ct_zone_entry *zt, struct flow_action_entry *act; int err, i; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -1501,7 +1501,7 @@ nfp_fl_ct_flow_entry *nfp_fl_ct_add_flow(struct nfp_fl_ct_zone_entry *zt, * to do a full copy instead of just a reference. */ if (is_nft) { - nft_match = kzalloc(sizeof(*nft_match), GFP_KERNEL); + nft_match = kzalloc_obj(*nft_match); if (!nft_match) { err = -ENOMEM; goto err_pre_ct_act; diff --git a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c index 2c7bd6e80d99..eb436362d384 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/lag_conf.c @@ -119,7 +119,7 @@ nfp_fl_lag_group_create(struct nfp_fl_lag *lag, struct net_device *master) return ERR_PTR(id); } - group = kmalloc(sizeof(*group), GFP_KERNEL); + group = kmalloc_obj(*group); if (!group) { ida_free(&lag->ida_handle, id); return ERR_PTR(-ENOMEM); @@ -335,8 +335,7 @@ static void nfp_fl_lag_do_work(struct work_struct *work) continue; } - acti_netdevs = kmalloc_array(entry->slave_cnt, - sizeof(*acti_netdevs), GFP_KERNEL); + acti_netdevs = kmalloc_objs(*acti_netdevs, entry->slave_cnt); if (!acti_netdevs) { schedule_delayed_work(&lag->work, NFP_FL_LAG_DELAY); diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c index 83eaa5ae3cd4..5c5fc640d65b 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/main.c +++ b/drivers/net/ethernet/netronome/nfp/flower/main.c @@ -182,7 +182,7 @@ nfp_flower_non_repr_priv_get(struct nfp_app *app, struct net_device *netdev) if (entry) goto inc_ref; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -406,7 +406,7 @@ nfp_flower_spawn_vnic_reprs(struct nfp_app *app, goto err_reprs_clean; } - repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL); + repr_priv = kzalloc_obj(*repr_priv); if (!repr_priv) { err = -ENOMEM; nfp_repr_free(repr); @@ -524,7 +524,7 @@ nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv) goto err_reprs_clean; } - repr_priv = kzalloc(sizeof(*repr_priv), GFP_KERNEL); + repr_priv = kzalloc_obj(*repr_priv); if (!repr_priv) { err = -ENOMEM; nfp_repr_free(repr); diff --git a/drivers/net/ethernet/netronome/nfp/flower/metadata.c b/drivers/net/ethernet/netronome/nfp/flower/metadata.c index dde60c4572fa..cc9a5aea6df0 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/metadata.c +++ b/drivers/net/ethernet/netronome/nfp/flower/metadata.c @@ -214,7 +214,7 @@ nfp_add_mask_table(struct nfp_app *app, char *mask_data, u32 mask_len) if (nfp_mask_alloc(app, &mask_id)) return -ENOENT; - mask_entry = kmalloc(sizeof(*mask_entry), GFP_KERNEL); + mask_entry = kmalloc_obj(*mask_entry); if (!mask_entry) { nfp_release_mask_id(app, mask_id); return -ENOMEM; @@ -324,7 +324,7 @@ int nfp_compile_flow_metadata(struct nfp_app *app, u32 cookie, nfp_flow->meta.host_cookie = cpu_to_be64(cookie); nfp_flow->ingress_dev = netdev; - ctx_entry = kzalloc(sizeof(*ctx_entry), GFP_KERNEL); + ctx_entry = kzalloc_obj(*ctx_entry); if (!ctx_entry) { err = -ENOMEM; goto err_release_stats; @@ -557,8 +557,8 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, /* Init timestamps for mask id*/ priv->mask_ids.last_used = - kmalloc_array(NFP_FLOWER_MASK_ENTRY_RS, - sizeof(*priv->mask_ids.last_used), GFP_KERNEL); + kmalloc_objs(*priv->mask_ids.last_used, + NFP_FLOWER_MASK_ENTRY_RS); if (!priv->mask_ids.last_used) goto err_free_mask_id; @@ -573,8 +573,7 @@ int nfp_flower_metadata_init(struct nfp_app *app, u64 host_ctx_count, stats_size = FIELD_PREP(NFP_FL_STAT_ID_STAT, host_ctx_count) | FIELD_PREP(NFP_FL_STAT_ID_MU_NUM, host_num_mems - 1); - priv->stats = kvmalloc_array(stats_size, sizeof(struct nfp_fl_stats), - GFP_KERNEL); + priv->stats = kvmalloc_objs(struct nfp_fl_stats, stats_size); if (!priv->stats) goto err_free_ring_buf; diff --git a/drivers/net/ethernet/netronome/nfp/flower/offload.c b/drivers/net/ethernet/netronome/nfp/flower/offload.c index 46ffc2c20893..161190200dbd 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/offload.c +++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c @@ -549,7 +549,7 @@ nfp_flower_allocate_new(struct nfp_fl_key_ls *key_layer) { struct nfp_fl_payload *flow_pay; - flow_pay = kmalloc(sizeof(*flow_pay), GFP_KERNEL); + flow_pay = kmalloc_obj(*flow_pay); if (!flow_pay) return NULL; @@ -979,7 +979,7 @@ static int nfp_flower_link_flows(struct nfp_fl_payload *merge_flow, { struct nfp_fl_payload_link *link; - link = kmalloc(sizeof(*link), GFP_KERNEL); + link = kmalloc_obj(*link); if (!link) return -ENOMEM; @@ -1067,7 +1067,7 @@ int nfp_flower_merge_offloaded_flows(struct nfp_app *app, if (err) goto err_release_metadata; - merge_info = kmalloc(sizeof(*merge_info), GFP_KERNEL); + merge_info = kmalloc_obj(*merge_info); if (!merge_info) { err = -ENOMEM; goto err_remove_rhash; @@ -1354,7 +1354,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, if (!offload_pre_check(flow)) return -EOPNOTSUPP; - key_layer = kmalloc(sizeof(*key_layer), GFP_KERNEL); + key_layer = kmalloc_obj(*key_layer); if (!key_layer) return -ENOMEM; @@ -1400,7 +1400,7 @@ nfp_flower_add_offload(struct nfp_app *app, struct net_device *netdev, if (priv->flower_ext_feats & NFP_FL_FEATS_DECAP_V2) { struct nfp_predt_entry *predt; - predt = kzalloc(sizeof(*predt), GFP_KERNEL); + predt = kzalloc_obj(*predt); if (!predt) { err = -ENOMEM; goto err_remove_rhash; @@ -1901,7 +1901,7 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct Qdisc *sch, str &nfp_block_cb_list)) return -EBUSY; - cb_priv = kmalloc(sizeof(*cb_priv), GFP_KERNEL); + cb_priv = kmalloc_obj(*cb_priv); if (!cb_priv) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c index e7180b4793c7..8c7d838920cb 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/qos_conf.c @@ -579,7 +579,7 @@ nfp_flower_add_meter_entry(struct nfp_app *app, u32 meter_id) if (meter_entry) return meter_entry; - meter_entry = kzalloc(sizeof(*meter_entry), GFP_KERNEL); + meter_entry = kzalloc_obj(*meter_entry); if (!meter_entry) return NULL; diff --git a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c index 0d7d138d6e0d..0cef0e2b85d0 100644 --- a/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c +++ b/drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c @@ -696,7 +696,7 @@ nfp_tun_alloc_neigh_update_work(struct nfp_app *app, struct neighbour *n) { struct nfp_neigh_update_work *update_work; - update_work = kzalloc(sizeof(*update_work), GFP_ATOMIC); + update_work = kzalloc_obj(*update_work, GFP_ATOMIC); if (!update_work) return NULL; @@ -884,7 +884,7 @@ void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4) } } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { mutex_unlock(&priv->tun.ipv4_off_lock); nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n"); @@ -959,7 +959,7 @@ nfp_tunnel_add_ipv6_off(struct nfp_app *app, struct in6_addr *ipv6) return entry; } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { mutex_unlock(&priv->tun.ipv6_off_lock); nfp_flower_cmsg_warn(app, "Mem error when offloading IP address.\n"); @@ -1117,7 +1117,7 @@ nfp_tunnel_add_shared_mac(struct nfp_app *app, struct net_device *netdev, } if (!entry) { - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto err_free_ida; diff --git a/drivers/net/ethernet/netronome/nfp/nfd3/rings.c b/drivers/net/ethernet/netronome/nfp/nfd3/rings.c index a03190c9313c..2560c4edee2e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfd3/rings.c +++ b/drivers/net/ethernet/netronome/nfp/nfd3/rings.c @@ -140,8 +140,7 @@ nfp_nfd3_tx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring) goto err_alloc; } - tx_ring->txbufs = kvcalloc(tx_ring->cnt, sizeof(*tx_ring->txbufs), - GFP_KERNEL); + tx_ring->txbufs = kvzalloc_objs(*tx_ring->txbufs, tx_ring->cnt); if (!tx_ring->txbufs) goto err_alloc; diff --git a/drivers/net/ethernet/netronome/nfp/nfdk/rings.c b/drivers/net/ethernet/netronome/nfp/nfdk/rings.c index fdb8144a63e0..10d162e7ae11 100644 --- a/drivers/net/ethernet/netronome/nfp/nfdk/rings.c +++ b/drivers/net/ethernet/netronome/nfp/nfdk/rings.c @@ -105,8 +105,7 @@ nfp_nfdk_tx_ring_alloc(struct nfp_net_dp *dp, struct nfp_net_tx_ring *tx_ring) goto err_alloc; } - tx_ring->ktxbufs = kvcalloc(tx_ring->cnt, sizeof(*tx_ring->ktxbufs), - GFP_KERNEL); + tx_ring->ktxbufs = kvzalloc_objs(*tx_ring->ktxbufs, tx_ring->cnt); if (!tx_ring->ktxbufs) goto err_alloc; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c index bb3f46c74f77..ad70c9c2e333 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_app.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c @@ -239,7 +239,7 @@ struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id) if (WARN_ON(!apps[id]->ctrl_msg_rx && apps[id]->ctrl_msg_rx_raw)) return ERR_PTR(-EINVAL); - app = kzalloc(sizeof(*app), GFP_KERNEL); + app = kzalloc_obj(*app); if (!app) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c index 9ef72f294117..7928e76da723 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c @@ -1554,7 +1554,7 @@ struct nfp_net_dp *nfp_net_clone_dp(struct nfp_net *nn) { struct nfp_net_dp *new; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) return NULL; @@ -2537,8 +2537,7 @@ nfp_net_alloc(struct pci_dev *pdev, const struct nfp_dev_info *dev_info, nn->dp.num_r_vecs, num_online_cpus()); nn->max_r_vecs = nn->dp.num_r_vecs; - nn->dp.xsk_pools = kcalloc(nn->max_r_vecs, sizeof(*nn->dp.xsk_pools), - GFP_KERNEL); + nn->dp.xsk_pools = kzalloc_objs(*nn->dp.xsk_pools, nn->max_r_vecs); if (!nn->dp.xsk_pools) { err = -ENOMEM; goto err_free_nn; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_dp.c b/drivers/net/ethernet/netronome/nfp/nfp_net_dp.c index 550df83b798c..3e8222886fe4 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_dp.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_dp.c @@ -184,8 +184,7 @@ int nfp_net_tx_rings_prepare(struct nfp_net *nn, struct nfp_net_dp *dp) { unsigned int r; - dp->tx_rings = kcalloc(dp->num_tx_rings, sizeof(*dp->tx_rings), - GFP_KERNEL); + dp->tx_rings = kzalloc_objs(*dp->tx_rings, dp->num_tx_rings); if (!dp->tx_rings) return -ENOMEM; @@ -340,8 +339,7 @@ int nfp_net_rx_rings_prepare(struct nfp_net *nn, struct nfp_net_dp *dp) { unsigned int r; - dp->rx_rings = kcalloc(dp->num_rx_rings, sizeof(*dp->rx_rings), - GFP_KERNEL); + dp->rx_rings = kzalloc_objs(*dp->rx_rings, dp->num_rx_rings); if (!dp->rx_rings) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c index e88b1c4732a5..a2a89d48e3ca 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c @@ -713,7 +713,7 @@ static int nfp_test_nsp(struct net_device *netdev) goto exit_close_nsp; } - nspi = kzalloc(sizeof(*nspi), GFP_KERNEL); + nspi = kzalloc_obj(*nspi); if (!nspi) { err = -ENOMEM; goto exit_close_nsp; @@ -1676,7 +1676,7 @@ static int nfp_net_fs_add(struct nfp_net *nn, struct ethtool_rxnfc *cmd) if (unsupp_mask) return -EOPNOTSUPP; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c index cbe4972ba104..06cfabfaa0f7 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_main.c @@ -229,8 +229,7 @@ static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf) wanted_irqs = 0; list_for_each_entry(nn, &pf->vnics, vnic_list) wanted_irqs += NFP_NET_NON_Q_VECTORS + nn->dp.num_r_vecs; - pf->irq_entries = kcalloc(wanted_irqs, sizeof(*pf->irq_entries), - GFP_KERNEL); + pf->irq_entries = kzalloc_objs(*pf->irq_entries, wanted_irqs); if (!pf->irq_entries) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c index 227e7a5d712e..6f9f67a31d2f 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c @@ -500,7 +500,7 @@ struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs) { struct nfp_reprs *reprs; - reprs = kzalloc(struct_size(reprs, reprs, num_reprs), GFP_KERNEL); + reprs = kzalloc_flex(*reprs, reprs, num_reprs); if (!reprs) return NULL; reprs->num_reprs = num_reprs; diff --git a/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c b/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c index e19bb0150cb5..b5646c884371 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_netvf_main.c @@ -93,7 +93,7 @@ static int nfp_netvf_pci_probe(struct pci_dev *pdev, dev_info = &nfp_dev_info[pci_id->driver_data]; - vf = kzalloc(sizeof(*vf), GFP_KERNEL); + vf = kzalloc_obj(*vf); if (!vf) return -ENOMEM; pci_set_drvdata(pdev, vf); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_port.c b/drivers/net/ethernet/netronome/nfp/nfp_port.c index 54640bcb70fb..7f5de6bd7218 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_port.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_port.c @@ -203,7 +203,7 @@ nfp_port_alloc(struct nfp_app *app, enum nfp_port_type type, { struct nfp_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/netronome/nfp/nfp_shared_buf.c b/drivers/net/ethernet/netronome/nfp/nfp_shared_buf.c index ea2e3f829aba..4ca692727b11 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_shared_buf.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_shared_buf.c @@ -99,8 +99,7 @@ int nfp_shared_buf_register(struct nfp_pf *pf) entry_sz = nfp_cpp_area_size(sb_desc_area) / num_entries; - pf->shared_bufs = kmalloc_array(num_entries, sizeof(pf->shared_bufs[0]), - GFP_KERNEL); + pf->shared_bufs = kmalloc_objs(pf->shared_bufs[0], num_entries); if (!pf->shared_bufs) { err = -ENOMEM; goto err_release_area; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c index 7c2200b49ce4..0bc9e517c4fd 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp6000_pcie.c @@ -1320,7 +1320,7 @@ nfp_cpp_from_nfp6000_pcie(struct pci_dev *pdev, const struct nfp_dev_info *dev_i dev_info->chip_names); pcie_print_link_status(pdev); - nfp = kzalloc(sizeof(*nfp), GFP_KERNEL); + nfp = kzalloc_obj(*nfp); if (!nfp) { err = -ENOMEM; goto err_ret; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c index 669f9f8fb507..85d3554a79a9 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_cppcore.c @@ -802,7 +802,7 @@ int nfp_cpp_area_cache_add(struct nfp_cpp *cpp, size_t size) if (!area) return -ENOMEM; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (!cache) { nfp_cpp_area_free(area); return -ENOMEM; @@ -1170,7 +1170,7 @@ nfp_cpp_from_operations(const struct nfp_cpp_operations *ops, u32 xpbaddr; size_t tgt; - cpp = kzalloc(sizeof(*cpp), GFP_KERNEL); + cpp = kzalloc_obj(*cpp); if (!cpp) { err = -ENOMEM; goto err_malloc; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c index 79e17943519e..aa787c502913 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mip.c @@ -101,7 +101,7 @@ const struct nfp_mip *nfp_mip_open(struct nfp_cpp *cpp) struct nfp_mip *mip; int err; - mip = kmalloc(sizeof(*mip), GFP_KERNEL); + mip = kmalloc_obj(*mip); if (!mip) return NULL; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c index 7bc17b94ac60..f079284c0ecd 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_mutex.c @@ -140,7 +140,7 @@ struct nfp_cpp_mutex *nfp_cpp_mutex_alloc(struct nfp_cpp *cpp, int target, if (tmp != key) return NULL; - mutex = kzalloc(sizeof(*mutex), GFP_KERNEL); + mutex = kzalloc_obj(*mutex); if (!mutex) return NULL; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c index e2e5fd003ad6..69c2fb9bea48 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nffw.c @@ -163,7 +163,7 @@ struct nfp_nffw_info *nfp_nffw_info_open(struct nfp_cpp *cpp) u32 info_ver; int err; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c index 0bd6477292a6..5a1aadf6e17e 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c @@ -280,7 +280,7 @@ struct nfp_nsp *nfp_nsp_open(struct nfp_cpp *cpp) if (IS_ERR(res)) return ERR_CAST(res); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { nfp_resource_release(res); return ERR_PTR(-ENOMEM); @@ -514,7 +514,7 @@ nfp_nsp_command_buf_dma_sg(struct nfp_nsp *nsp, dma_size = BIT_ULL(dma_order); nseg = DIV_ROUND_UP(max_size, chunk_size); - chunks = kcalloc(nseg, sizeof(*chunks), GFP_KERNEL); + chunks = kzalloc_objs(*chunks, nseg); if (!chunks) return -ENOMEM; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c index 0997d127144f..d39c8f282199 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_cmds.c @@ -29,7 +29,7 @@ struct nfp_nsp_identify *__nfp_nsp_identify(struct nfp_nsp *nsp) if (nfp_nsp_get_abi_ver_minor(nsp) < 15) return NULL; - ni = kzalloc(sizeof(*ni), GFP_KERNEL); + ni = kzalloc_obj(*ni); if (!ni) return NULL; @@ -40,7 +40,7 @@ struct nfp_nsp_identify *__nfp_nsp_identify(struct nfp_nsp *nsp) goto exit_free; } - nspi = kzalloc(sizeof(*nspi), GFP_KERNEL); + nspi = kzalloc_obj(*nspi); if (!nspi) goto exit_free; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c index 5cfddc9a5d87..b0c799fb3013 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c @@ -319,7 +319,7 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp) goto err; } - table = kzalloc(struct_size(table, ports, cnt), GFP_KERNEL); + table = kzalloc_flex(*table, ports, cnt); if (!table) goto err; diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c index 279ea0b56955..6d5833479d12 100644 --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_resource.c @@ -155,7 +155,7 @@ nfp_resource_acquire(struct nfp_cpp *cpp, const char *name) struct nfp_resource *res; int err; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/netronome/nfp/nic/main.c b/drivers/net/ethernet/netronome/nfp/nic/main.c index 9dd5afe37f6e..f7a4d76899c2 100644 --- a/drivers/net/ethernet/netronome/nfp/nic/main.c +++ b/drivers/net/ethernet/netronome/nfp/nic/main.c @@ -51,7 +51,7 @@ static int nfp_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, return err; if (sizeof(*app_pri)) { - nn->app_priv = kzalloc(sizeof(*app_pri), GFP_KERNEL); + nn->app_priv = kzalloc_obj(*app_pri); if (!nn->app_priv) return -ENOMEM; } diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c index 19aa1f1538aa..5b0435d7bc39 100644 --- a/drivers/net/ethernet/nvidia/forcedeth.c +++ b/drivers/net/ethernet/nvidia/forcedeth.c @@ -5854,8 +5854,8 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) goto out_unmap; np->tx_ring.ex = &np->rx_ring.ex[np->rx_ring_size]; } - np->rx_skb = kcalloc(np->rx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL); - np->tx_skb = kcalloc(np->tx_ring_size, sizeof(struct nv_skb_map), GFP_KERNEL); + np->rx_skb = kzalloc_objs(struct nv_skb_map, np->rx_ring_size); + np->tx_skb = kzalloc_objs(struct nv_skb_map, np->tx_ring_size); if (!np->rx_skb || !np->tx_skb) goto out_freering; diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 00909372ea61..3c798e598bc5 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -381,9 +381,7 @@ static int pasemi_mac_setup_rx_resources(const struct net_device *dev) spin_lock_init(&ring->lock); ring->size = RX_RING_SIZE; - ring->ring_info = kcalloc(RX_RING_SIZE, - sizeof(struct pasemi_mac_buffer), - GFP_KERNEL); + ring->ring_info = kzalloc_objs(struct pasemi_mac_buffer, RX_RING_SIZE); if (!ring->ring_info) goto out_ring_info; @@ -465,9 +463,7 @@ pasemi_mac_setup_tx_resources(const struct net_device *dev) spin_lock_init(&ring->lock); ring->size = TX_RING_SIZE; - ring->ring_info = kcalloc(TX_RING_SIZE, - sizeof(struct pasemi_mac_buffer), - GFP_KERNEL); + ring->ring_info = kzalloc_objs(struct pasemi_mac_buffer, TX_RING_SIZE); if (!ring->ring_info) goto out_ring_info; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_aux.c b/drivers/net/ethernet/pensando/ionic/ionic_aux.c index a2be338eb3e5..4f193d0ee87a 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_aux.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_aux.c @@ -26,7 +26,7 @@ int ionic_auxbus_register(struct ionic_lif *lif) if (!(le64_to_cpu(lif->ionic->ident.lif.capabilities) & IONIC_LIF_CAP_RDMA)) return 0; - ionic_adev = kzalloc(sizeof(*ionic_adev), GFP_KERNEL); + ionic_adev = kzalloc_obj(*ionic_adev); if (!ionic_adev) return -ENOMEM; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c index 0671deae9a28..05f19489ec5c 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_bus_pci.c @@ -151,7 +151,7 @@ static int ionic_vf_alloc(struct ionic *ionic, int num_vfs) down_write(&ionic->vf_op_lock); - ionic->vfs = kcalloc(num_vfs, sizeof(struct ionic_vf), GFP_KERNEL); + ionic->vfs = kzalloc_objs(struct ionic_vf, num_vfs); if (!ionic->vfs) { err = -ENOMEM; goto out; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_dev.c b/drivers/net/ethernet/pensando/ionic/ionic_dev.c index ab27e9225c1e..3838c4a70766 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_dev.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_dev.c @@ -35,7 +35,7 @@ static void ionic_watchdog_cb(struct timer_list *t) if (test_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state) && !test_bit(IONIC_LIF_F_FW_RESET, lif->state)) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { netdev_err(lif->netdev, "rxmode change dropped\n"); return; @@ -577,7 +577,7 @@ int ionic_heartbeat_check(struct ionic *ionic) if (trigger) { struct ionic_deferred_work *work; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (work) { work->type = IONIC_DW_TYPE_LIF_RESET; work->fw_status = fw_status_ready; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_lif.c b/drivers/net/ethernet/pensando/ionic/ionic_lif.c index 058eea86e141..8d040e611d5a 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_lif.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_lif.c @@ -203,7 +203,7 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep) return; if (!can_sleep) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state); return; @@ -1427,7 +1427,7 @@ static void ionic_ndo_set_rx_mode(struct net_device *netdev) /* Shove off the rest of the rxmode work to the work task * which will include syncing the filters to the firmware. */ - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { netdev_err(lif->netdev, "rxmode change dropped\n"); return; @@ -2694,7 +2694,7 @@ static int ionic_register_rxq_info(struct ionic_queue *q, unsigned int napi_id) struct xdp_rxq_info *rxq_info; int err; - rxq_info = kzalloc(sizeof(*rxq_info), GFP_KERNEL); + rxq_info = kzalloc_obj(*rxq_info); if (!rxq_info) return -ENOMEM; @@ -3177,7 +3177,7 @@ static int ionic_affinity_masks_alloc(struct ionic *ionic) int nintrs = ionic->nintrs; int i; - affinity_masks = kcalloc(nintrs, sizeof(cpumask_var_t), GFP_KERNEL); + affinity_masks = kzalloc_objs(cpumask_var_t, nintrs); if (!affinity_masks) return -ENOMEM; @@ -3218,7 +3218,7 @@ int ionic_lif_alloc(struct ionic *ionic) int tbl_sz; int err; - lid = kzalloc(sizeof(*lid), GFP_KERNEL); + lid = kzalloc_obj(*lid); if (!lid) return -ENOMEM; diff --git a/drivers/net/ethernet/pensando/ionic/ionic_main.c b/drivers/net/ethernet/pensando/ionic/ionic_main.c index 14dc055be3e9..3c5200e2fdb7 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_main.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_main.c @@ -283,7 +283,7 @@ bool ionic_notifyq_service(struct ionic_cq *cq) if (lif->ionic->idev.fw_status_ready && !test_bit(IONIC_LIF_F_FW_RESET, lif->state) && !test_and_set_bit(IONIC_LIF_F_FW_STOPPING, lif->state)) { - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { netdev_err(lif->netdev, "Reset event dropped\n"); clear_bit(IONIC_LIF_F_FW_STOPPING, lif->state); diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c index 89c8b2349694..fff8dc84212d 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_hw.c @@ -634,7 +634,7 @@ static int nx_p3_nic_add_mac(struct netxen_adapter *adapter, } } - cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC); + cur = kzalloc_obj(nx_mac_list_t, GFP_ATOMIC); if (cur == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index 51fa880eaf6c..8bc4e2b69569 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -185,7 +185,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) struct netxen_cmd_buffer *cmd_buf_arr; struct net_device *netdev = adapter->netdev; - tx_ring = kzalloc(sizeof(struct nx_host_tx_ring), GFP_KERNEL); + tx_ring = kzalloc_obj(struct nx_host_tx_ring); if (tx_ring == NULL) return -ENOMEM; @@ -202,8 +202,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) recv_ctx = &adapter->recv_ctx; - rds_ring = kcalloc(adapter->max_rds_rings, - sizeof(struct nx_host_rds_ring), GFP_KERNEL); + rds_ring = kzalloc_objs(struct nx_host_rds_ring, adapter->max_rds_rings); if (rds_ring == NULL) goto err_out; @@ -451,7 +450,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) return -EIO; } - buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kzalloc_objs(struct crb_addr_pair, n); if (buf == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index e8ff661fa4a5..5ee2bd9d6886 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -3198,7 +3198,7 @@ netxen_list_config_ip(struct netxen_adapter *adapter, goto out; } - cur = kzalloc(sizeof(struct nx_ip_list), GFP_ATOMIC); + cur = kzalloc_obj(struct nx_ip_list, GFP_ATOMIC); if (cur == NULL) goto out; if (is_vlan_dev(dev)) diff --git a/drivers/net/ethernet/qlogic/qed/qed_cxt.c b/drivers/net/ethernet/qlogic/qed/qed_cxt.c index 33f4f58ee51c..9861daa82d9e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_cxt.c +++ b/drivers/net/ethernet/qlogic/qed/qed_cxt.c @@ -845,8 +845,7 @@ static int qed_cxt_src_t2_alloc(struct qed_hwfn *p_hwfn) p_t2->num_pages = DIV_ROUND_UP(total_size, psz); /* allocate t2 */ - p_t2->dma_mem = kcalloc(p_t2->num_pages, sizeof(struct phys_mem_desc), - GFP_KERNEL); + p_t2->dma_mem = kzalloc_objs(struct phys_mem_desc, p_t2->num_pages); if (!p_t2->dma_mem) { DP_NOTICE(p_hwfn, "Failed to allocate t2 table\n"); rc = -ENOMEM; @@ -994,8 +993,7 @@ static int qed_ilt_shadow_alloc(struct qed_hwfn *p_hwfn) int rc; size = qed_cxt_ilt_shadow_size(clients); - p_mngr->ilt_shadow = kcalloc(size, sizeof(struct phys_mem_desc), - GFP_KERNEL); + p_mngr->ilt_shadow = kzalloc_objs(struct phys_mem_desc, size); if (!p_mngr->ilt_shadow) { rc = -ENOMEM; goto ilt_shadow_fail; @@ -1114,7 +1112,7 @@ int qed_cxt_mngr_alloc(struct qed_hwfn *p_hwfn) struct qed_cxt_mngr *p_mngr; u32 i; - p_mngr = kzalloc(sizeof(*p_mngr), GFP_KERNEL); + p_mngr = kzalloc_obj(*p_mngr); if (!p_mngr) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index dc93ddea8906..3a5c25026858 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -915,7 +915,7 @@ qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn, int qed_dcbx_info_alloc(struct qed_hwfn *p_hwfn) { - p_hwfn->p_dcbx_info = kzalloc(sizeof(*p_hwfn->p_dcbx_info), GFP_KERNEL); + p_hwfn->p_dcbx_info = kzalloc_obj(*p_hwfn->p_dcbx_info); if (!p_hwfn->p_dcbx_info) return -ENOMEM; @@ -1244,7 +1244,7 @@ int qed_dcbx_get_config_params(struct qed_hwfn *p_hwfn, return 0; } - dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_KERNEL); + dcbx_info = kzalloc_obj(*dcbx_info); if (!dcbx_info) return -ENOMEM; @@ -1283,7 +1283,7 @@ static struct qed_dcbx_get *qed_dcbnl_get_dcbx(struct qed_hwfn *hwfn, { struct qed_dcbx_get *dcbx_info; - dcbx_info = kzalloc(sizeof(*dcbx_info), GFP_ATOMIC); + dcbx_info = kzalloc_obj(*dcbx_info, GFP_ATOMIC); if (!dcbx_info) return NULL; diff --git a/drivers/net/ethernet/qlogic/qed/qed_debug.c b/drivers/net/ethernet/qlogic/qed/qed_debug.c index 1f0cea3cae92..4fb38e47c652 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_debug.c +++ b/drivers/net/ethernet/qlogic/qed/qed_debug.c @@ -6821,9 +6821,7 @@ qed_mcp_trace_alloc_meta_data(struct qed_hwfn *p_hwfn, /* Read number of formats and allocate memory for all formats */ meta->formats_num = qed_read_dword_from_buf(meta_buf_bytes, &offset); - meta->formats = kcalloc(meta->formats_num, - sizeof(struct mcp_trace_format), - GFP_KERNEL); + meta->formats = kzalloc_objs(struct mcp_trace_format, meta->formats_num); if (!meta->formats) return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; @@ -7536,8 +7534,7 @@ enum dbg_status qed_dbg_user_set_bin_ptr(struct qed_hwfn *p_hwfn, enum dbg_status qed_dbg_alloc_user_data(struct qed_hwfn *p_hwfn, void **user_data_ptr) { - *user_data_ptr = kzalloc(sizeof(struct dbg_tools_user_data), - GFP_KERNEL); + *user_data_ptr = kzalloc_obj(struct dbg_tools_user_data); if (!(*user_data_ptr)) return DBG_STATUS_VIRT_MEM_ALLOC_FAILED; diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index f3d2b2b3bad5..42c6dcfb1f0f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -146,7 +146,7 @@ int qed_db_recovery_add(struct qed_dev *cdev, p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr); /* Create entry */ - db_entry = kzalloc(sizeof(*db_entry), GFP_KERNEL); + db_entry = kzalloc_obj(*db_entry); if (!db_entry) { DP_NOTICE(cdev, "Failed to allocate a db recovery entry\n"); return -ENOMEM; @@ -383,7 +383,7 @@ static int qed_llh_alloc(struct qed_dev *cdev) struct qed_llh_info *p_llh_info; u32 size, i; - p_llh_info = kzalloc(sizeof(*p_llh_info), GFP_KERNEL); + p_llh_info = kzalloc_obj(*p_llh_info); if (!p_llh_info) return -ENOMEM; cdev->p_llh_info = p_llh_info; @@ -2108,27 +2108,23 @@ static int qed_alloc_qm_data(struct qed_hwfn *p_hwfn) if (rc) goto alloc_err; - qm_info->qm_pq_params = kcalloc(qed_init_qm_get_num_pqs(p_hwfn), - sizeof(*qm_info->qm_pq_params), - GFP_KERNEL); + qm_info->qm_pq_params = kzalloc_objs(*qm_info->qm_pq_params, + qed_init_qm_get_num_pqs(p_hwfn)); if (!qm_info->qm_pq_params) goto alloc_err; - qm_info->qm_vport_params = kcalloc(qed_init_qm_get_num_vports(p_hwfn), - sizeof(*qm_info->qm_vport_params), - GFP_KERNEL); + qm_info->qm_vport_params = kzalloc_objs(*qm_info->qm_vport_params, + qed_init_qm_get_num_vports(p_hwfn)); if (!qm_info->qm_vport_params) goto alloc_err; - qm_info->qm_port_params = kcalloc(p_hwfn->cdev->num_ports_in_engine, - sizeof(*qm_info->qm_port_params), - GFP_KERNEL); + qm_info->qm_port_params = kzalloc_objs(*qm_info->qm_port_params, + p_hwfn->cdev->num_ports_in_engine); if (!qm_info->qm_port_params) goto alloc_err; - qm_info->wfq_data = kcalloc(qed_init_qm_get_num_vports(p_hwfn), - sizeof(*qm_info->wfq_data), - GFP_KERNEL); + qm_info->wfq_data = kzalloc_objs(*qm_info->wfq_data, + qed_init_qm_get_num_vports(p_hwfn)); if (!qm_info->wfq_data) goto alloc_err; @@ -2155,7 +2151,7 @@ int qed_resc_alloc(struct qed_dev *cdev) return rc; } - cdev->fw_data = kzalloc(sizeof(*cdev->fw_data), GFP_KERNEL); + cdev->fw_data = kzalloc_obj(*cdev->fw_data); if (!cdev->fw_data) return -ENOMEM; @@ -2345,7 +2341,7 @@ int qed_resc_alloc(struct qed_dev *cdev) goto alloc_err; } - cdev->reset_stats = kzalloc(sizeof(*cdev->reset_stats), GFP_KERNEL); + cdev->reset_stats = kzalloc_obj(*cdev->reset_stats); if (!cdev->reset_stats) goto alloc_no_mem; @@ -2642,7 +2638,7 @@ static int qed_hw_init_common(struct qed_hwfn *p_hwfn, u32 concrete_fid; int rc = 0; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) { DP_NOTICE(p_hwfn->cdev, "Failed to allocate common init params\n"); diff --git a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c index 04602ac94708..5bdbe331ac8e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_fcoe.c +++ b/drivers/net/ethernet/qlogic/qed/qed_fcoe.c @@ -383,7 +383,7 @@ qed_fcoe_allocate_connection(struct qed_hwfn *p_hwfn, } spin_unlock_bh(&p_hwfn->p_fcoe_info->lock); - p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); + p_conn = kzalloc_obj(*p_conn); if (!p_conn) return -ENOMEM; @@ -535,7 +535,7 @@ int qed_fcoe_alloc(struct qed_hwfn *p_hwfn) struct qed_fcoe_info *p_fcoe_info; /* Allocate LL2's set struct */ - p_fcoe_info = kzalloc(sizeof(*p_fcoe_info), GFP_KERNEL); + p_fcoe_info = kzalloc_obj(*p_fcoe_info); if (!p_fcoe_info) { DP_NOTICE(p_hwfn, "Failed to allocate qed_fcoe_info'\n"); return -ENOMEM; @@ -817,8 +817,8 @@ static int qed_fcoe_start(struct qed_dev *cdev, struct qed_fcoe_tid *tasks) hash_init(cdev->connections); if (tasks) { - struct qed_tid_mem *tid_info = kzalloc(sizeof(*tid_info), - GFP_ATOMIC); + struct qed_tid_mem *tid_info = kzalloc_obj(*tid_info, + GFP_ATOMIC); if (!tid_info) { DP_NOTICE(cdev, @@ -855,7 +855,7 @@ static int qed_fcoe_acquire_conn(struct qed_dev *cdev, int rc; /* Allocate a hashed connection */ - hash_con = kzalloc(sizeof(*hash_con), GFP_KERNEL); + hash_con = kzalloc_obj(*hash_con); if (!hash_con) { DP_NOTICE(cdev, "Failed to allocate hashed connection\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_hw.c b/drivers/net/ethernet/qlogic/qed/qed_hw.c index 9907973399dc..77c240d27fe9 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hw.c +++ b/drivers/net/ethernet/qlogic/qed/qed_hw.c @@ -46,7 +46,7 @@ struct qed_ptt_pool { int qed_ptt_pool_alloc(struct qed_hwfn *p_hwfn) { - struct qed_ptt_pool *p_pool = kmalloc(sizeof(*p_pool), GFP_KERNEL); + struct qed_ptt_pool *p_pool = kmalloc_obj(*p_pool); int i; if (!p_pool) diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c index aa20bb8caa9a..79ea53bc1a32 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c +++ b/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c @@ -1692,8 +1692,7 @@ struct phys_mem_desc *qed_fw_overlay_mem_alloc(struct qed_hwfn *p_hwfn, if (!buf_size) return NULL; - allocated_mem = kcalloc(NUM_STORMS, sizeof(struct phys_mem_desc), - GFP_KERNEL); + allocated_mem = kzalloc_objs(struct phys_mem_desc, NUM_STORMS); if (!allocated_mem) return NULL; diff --git a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c index b3bf9899c1a1..edcaecf5b679 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_init_ops.c +++ b/drivers/net/ethernet/qlogic/qed/qed_init_ops.c @@ -210,8 +210,7 @@ int qed_init_alloc(struct qed_hwfn *p_hwfn) if (IS_VF(p_hwfn->cdev)) return 0; - rt_data->b_valid = kcalloc(RUNTIME_ARRAY_SIZE, sizeof(bool), - GFP_KERNEL); + rt_data->b_valid = kzalloc_objs(bool, RUNTIME_ARRAY_SIZE); if (!rt_data->b_valid) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 2661c483c67e..db3b0bc4ed93 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -1412,7 +1412,7 @@ static int qed_int_sb_attn_alloc(struct qed_hwfn *p_hwfn, void *p_virt; /* SB struct */ - p_sb = kmalloc(sizeof(*p_sb), GFP_KERNEL); + p_sb = kmalloc_obj(*p_sb); if (!p_sb) return -ENOMEM; @@ -1765,7 +1765,7 @@ static int qed_int_sp_sb_alloc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) void *p_virt; /* SB struct */ - p_sb = kmalloc(sizeof(*p_sb), GFP_KERNEL); + p_sb = kmalloc_obj(*p_sb); if (!p_sb) return -ENOMEM; @@ -2188,7 +2188,7 @@ int qed_int_igu_read_cam(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) u32 min_vf = 0, max_vf = 0; u16 igu_sb_id; - p_hwfn->hw_info.p_igu_info = kzalloc(sizeof(*p_igu_info), GFP_KERNEL); + p_hwfn->hw_info.p_igu_info = kzalloc_obj(*p_igu_info); if (!p_hwfn->hw_info.p_igu_info) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c index 980e7289b481..34f1217227bc 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iscsi.c +++ b/drivers/net/ethernet/qlogic/qed/qed_iscsi.c @@ -710,7 +710,7 @@ static int qed_iscsi_allocate_connection(struct qed_hwfn *p_hwfn, /* Need to allocate a new connection */ p_params = &p_hwfn->pf_params.iscsi_pf_params; - p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); + p_conn = kzalloc_obj(*p_conn); if (!p_conn) return -ENOMEM; @@ -845,7 +845,7 @@ int qed_iscsi_alloc(struct qed_hwfn *p_hwfn) { struct qed_iscsi_info *p_iscsi_info; - p_iscsi_info = kzalloc(sizeof(*p_iscsi_info), GFP_KERNEL); + p_iscsi_info = kzalloc_obj(*p_iscsi_info); if (!p_iscsi_info) return -ENOMEM; @@ -1125,7 +1125,7 @@ static int qed_iscsi_start(struct qed_dev *cdev, if (!tasks) return 0; - tid_info = kzalloc(sizeof(*tid_info), GFP_KERNEL); + tid_info = kzalloc_obj(*tid_info); if (!tid_info) { qed_iscsi_stop(cdev); @@ -1159,7 +1159,7 @@ static int qed_iscsi_acquire_conn(struct qed_dev *cdev, int rc; /* Allocate a hashed connection */ - hash_con = kzalloc(sizeof(*hash_con), GFP_ATOMIC); + hash_con = kzalloc_obj(*hash_con, GFP_ATOMIC); if (!hash_con) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c index 1d1d4caad680..4d1ce9b1a3f2 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_iwarp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_iwarp.c @@ -546,7 +546,7 @@ qed_iwarp_create_ep(struct qed_hwfn *p_hwfn, struct qed_iwarp_ep **ep_out) struct qed_iwarp_ep *ep; int rc; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -2602,7 +2602,7 @@ qed_iwarp_ll2_alloc_buffers(struct qed_hwfn *p_hwfn, int i; for (i = 0; i < num_rx_bufs; i++) { - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) { rc = -ENOMEM; break; @@ -2759,9 +2759,8 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn, if (rc) goto err; - iwarp_info->partial_fpdus = kcalloc((u16)p_hwfn->p_rdma_info->num_qps, - sizeof(*iwarp_info->partial_fpdus), - GFP_KERNEL); + iwarp_info->partial_fpdus = kzalloc_objs(*iwarp_info->partial_fpdus, + (u16)p_hwfn->p_rdma_info->num_qps); if (!iwarp_info->partial_fpdus) { rc = -ENOMEM; goto err; @@ -2780,9 +2779,8 @@ qed_iwarp_ll2_start(struct qed_hwfn *p_hwfn, * processing. We can't fail on allocation of such a struct therefore * we allocate enough to take care of all rx packets */ - iwarp_info->mpa_bufs = kcalloc(data.input.rx_num_desc, - sizeof(*iwarp_info->mpa_bufs), - GFP_KERNEL); + iwarp_info->mpa_bufs = kzalloc_objs(*iwarp_info->mpa_bufs, + data.input.rx_num_desc); if (!iwarp_info->mpa_bufs) { rc = -ENOMEM; goto err; @@ -3167,7 +3165,7 @@ qed_iwarp_create_listen(void *rdma_cxt, struct qed_hwfn *p_hwfn = rdma_cxt; struct qed_iwarp_listener *listener; - listener = kzalloc(sizeof(*listener), GFP_KERNEL); + listener = kzalloc_obj(*listener); if (!listener) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_l2.c b/drivers/net/ethernet/qlogic/qed/qed_l2.c index 970b9aabbc3d..0f6905e33df6 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_l2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_l2.c @@ -58,7 +58,7 @@ int qed_l2_alloc(struct qed_hwfn *p_hwfn) if (!QED_IS_L2_PERSONALITY(p_hwfn)) return 0; - p_l2_info = kzalloc(sizeof(*p_l2_info), GFP_KERNEL); + p_l2_info = kzalloc_obj(*p_l2_info); if (!p_l2_info) return -ENOMEM; p_hwfn->p_l2_info = p_l2_info; diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c index ab5ef254a748..52f50c7228ed 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c @@ -1195,8 +1195,7 @@ qed_ll2_acquire_connection_rx(struct qed_hwfn *p_hwfn, } capacity = qed_chain_get_capacity(&p_ll2_info->rx_queue.rxq_chain); - p_descq = kcalloc(capacity, sizeof(struct qed_ll2_rx_packet), - GFP_KERNEL); + p_descq = kzalloc_objs(struct qed_ll2_rx_packet, capacity); if (!p_descq) { rc = -ENOMEM; DP_NOTICE(p_hwfn, "Failed to allocate ll2 Rx desc\n"); @@ -1291,7 +1290,7 @@ qed_ll2_acquire_connection_ooo(struct qed_hwfn *p_hwfn, for (buf_idx = 0; buf_idx < p_ll2_info->input.rx_num_ooo_buffers; buf_idx++) { - p_buf = kzalloc(sizeof(*p_buf), GFP_KERNEL); + p_buf = kzalloc_obj(*p_buf); if (!p_buf) { rc = -ENOMEM; goto out; @@ -2200,8 +2199,8 @@ int qed_ll2_alloc(struct qed_hwfn *p_hwfn) u8 i; /* Allocate LL2's set struct */ - p_ll2_connections = kcalloc(QED_MAX_NUM_OF_LL2_CONNECTIONS, - sizeof(struct qed_ll2_info), GFP_KERNEL); + p_ll2_connections = kzalloc_objs(struct qed_ll2_info, + QED_MAX_NUM_OF_LL2_CONNECTIONS); if (!p_ll2_connections) { DP_NOTICE(p_hwfn, "Failed to allocate `struct qed_ll2'\n"); return -ENOMEM; @@ -2603,7 +2602,7 @@ static int qed_ll2_start(struct qed_dev *cdev, struct qed_ll2_params *params) DP_INFO(cdev, "Allocating %d LL2 buffers of size %08x bytes\n", rx_num_desc, cdev->ll2->rx_size); for (i = 0; i < rx_num_desc; i++) { - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) { DP_INFO(cdev, "Failed to allocate LL2 buffers\n"); rc = -ENOMEM; @@ -2811,7 +2810,7 @@ const struct qed_ll2_ops qed_ll2_ops_pass = { int qed_ll2_alloc_if(struct qed_dev *cdev) { - cdev->ll2 = kzalloc(sizeof(*cdev->ll2), GFP_KERNEL); + cdev->ll2 = kzalloc_obj(*cdev->ll2); return cdev->ll2 ? 0 : -ENOMEM; } diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index d4685ad4b169..28a8a2b9d501 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -461,7 +461,7 @@ static struct qed_dev *qed_alloc_cdev(struct pci_dev *pdev) { struct qed_dev *cdev; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return cdev; @@ -612,7 +612,7 @@ static int qed_set_int_mode(struct qed_dev *cdev, bool force_mode) case QED_INT_MODE_MSIX: /* Allocate MSIX table */ cnt = int_params->in.num_vectors; - int_params->msix_table = kcalloc(cnt, sizeof(*tbl), GFP_KERNEL); + int_params->msix_table = kzalloc_objs(*tbl, cnt); if (!int_params->msix_table) { rc = -ENOMEM; goto out; @@ -1050,7 +1050,7 @@ static int qed_alloc_stream_mem(struct qed_dev *cdev) for_each_hwfn(cdev, i) { struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; - p_hwfn->stream = kzalloc(sizeof(*p_hwfn->stream), GFP_KERNEL); + p_hwfn->stream = kzalloc_obj(*p_hwfn->stream); if (!p_hwfn->stream) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index c7f497c36f66..7e37fe631a58 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -104,7 +104,7 @@ qed_mcp_cmd_add_elem(struct qed_hwfn *p_hwfn, { struct qed_mcp_cmd_elem *p_cmd_elem = NULL; - p_cmd_elem = kzalloc(sizeof(*p_cmd_elem), GFP_ATOMIC); + p_cmd_elem = kzalloc_obj(*p_cmd_elem, GFP_ATOMIC); if (!p_cmd_elem) goto out; @@ -241,7 +241,7 @@ int qed_mcp_cmd_init(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) u32 size; /* Allocate mcp_info structure */ - p_hwfn->mcp_info = kzalloc(sizeof(*p_hwfn->mcp_info), GFP_KERNEL); + p_hwfn->mcp_info = kzalloc_obj(*p_hwfn->mcp_info); if (!p_hwfn->mcp_info) goto err; p_info = p_hwfn->mcp_info; @@ -3365,9 +3365,8 @@ int qed_mcp_nvm_info_populate(struct qed_hwfn *p_hwfn) goto err0; } - nvm_info.image_att = kmalloc_array(nvm_info.num_images, - sizeof(struct bist_nvm_image_att), - GFP_KERNEL); + nvm_info.image_att = kmalloc_objs(struct bist_nvm_image_att, + nvm_info.num_images); if (!nvm_info.image_att) { rc = -ENOMEM; goto err0; diff --git a/drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c b/drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c index f19128c8d9cc..b28128c4398c 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_nvmetcp.c @@ -218,7 +218,7 @@ static int qed_nvmetcp_start(struct qed_dev *cdev, if (!tasks) return 0; - tid_info = kzalloc(sizeof(*tid_info), GFP_KERNEL); + tid_info = kzalloc_obj(*tid_info); if (!tid_info) { qed_nvmetcp_stop(cdev); @@ -477,7 +477,7 @@ static int qed_nvmetcp_allocate_connection(struct qed_hwfn *p_hwfn, /* Need to allocate a new connection */ p_params = &p_hwfn->pf_params.nvmetcp_pf_params; - p_conn = kzalloc(sizeof(*p_conn), GFP_KERNEL); + p_conn = kzalloc_obj(*p_conn); if (!p_conn) return -ENOMEM; @@ -568,7 +568,7 @@ int qed_nvmetcp_alloc(struct qed_hwfn *p_hwfn) { struct qed_nvmetcp_info *p_nvmetcp_info; - p_nvmetcp_info = kzalloc(sizeof(*p_nvmetcp_info), GFP_KERNEL); + p_nvmetcp_info = kzalloc_obj(*p_nvmetcp_info); if (!p_nvmetcp_info) return -ENOMEM; @@ -611,7 +611,7 @@ static int qed_nvmetcp_acquire_conn(struct qed_dev *cdev, int rc; /* Allocate a hashed connection */ - hash_con = kzalloc(sizeof(*hash_con), GFP_ATOMIC); + hash_con = kzalloc_obj(*hash_con, GFP_ATOMIC); if (!hash_con) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_ooo.c b/drivers/net/ethernet/qlogic/qed/qed_ooo.c index 8be567a6ad44..b29bbfb7748e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_ooo.c +++ b/drivers/net/ethernet/qlogic/qed/qed_ooo.c @@ -107,7 +107,7 @@ int qed_ooo_alloc(struct qed_hwfn *p_hwfn) return -EINVAL; } - p_ooo_info = kzalloc(sizeof(*p_ooo_info), GFP_KERNEL); + p_ooo_info = kzalloc_obj(*p_ooo_info); if (!p_ooo_info) return -ENOMEM; @@ -118,9 +118,8 @@ int qed_ooo_alloc(struct qed_hwfn *p_hwfn) INIT_LIST_HEAD(&p_ooo_info->ready_buffers_list); INIT_LIST_HEAD(&p_ooo_info->free_isles_list); - p_ooo_info->p_isles_mem = kcalloc(max_num_isles, - sizeof(struct qed_ooo_isle), - GFP_KERNEL); + p_ooo_info->p_isles_mem = kzalloc_objs(struct qed_ooo_isle, + max_num_isles); if (!p_ooo_info->p_isles_mem) goto no_isles_mem; @@ -131,9 +130,8 @@ int qed_ooo_alloc(struct qed_hwfn *p_hwfn) } p_ooo_info->p_archipelagos_mem = - kcalloc(max_num_archipelagos, - sizeof(struct qed_ooo_archipelago), - GFP_KERNEL); + kzalloc_objs(struct qed_ooo_archipelago, + max_num_archipelagos); if (!p_ooo_info->p_archipelagos_mem) goto no_archipelagos_mem; @@ -141,9 +139,8 @@ int qed_ooo_alloc(struct qed_hwfn *p_hwfn) INIT_LIST_HEAD(&p_ooo_info->p_archipelagos_mem[i].isles_list); p_ooo_info->ooo_history.p_cqes = - kcalloc(QED_MAX_NUM_OOO_HISTORY_ENTRIES, - sizeof(struct ooo_opaque), - GFP_KERNEL); + kzalloc_objs(struct ooo_opaque, + QED_MAX_NUM_OOO_HISTORY_ENTRIES); if (!p_ooo_info->ooo_history.p_cqes) goto no_history_mem; diff --git a/drivers/net/ethernet/qlogic/qed/qed_rdma.c b/drivers/net/ethernet/qlogic/qed/qed_rdma.c index 9a1660a12c57..24e2bdf42817 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_rdma.c +++ b/drivers/net/ethernet/qlogic/qed/qed_rdma.c @@ -119,7 +119,7 @@ int qed_rdma_info_alloc(struct qed_hwfn *p_hwfn) { struct qed_rdma_info *p_rdma_info; - p_rdma_info = kzalloc(sizeof(*p_rdma_info), GFP_KERNEL); + p_rdma_info = kzalloc_obj(*p_rdma_info); if (!p_rdma_info) return -ENOMEM; @@ -168,12 +168,12 @@ static int qed_rdma_alloc(struct qed_hwfn *p_hwfn) p_rdma_info->max_queue_zones = (u16)RESC_NUM(p_hwfn, QED_L2_QUEUE); /* Allocate a struct with device params and fill it */ - p_rdma_info->dev = kzalloc(sizeof(*p_rdma_info->dev), GFP_KERNEL); + p_rdma_info->dev = kzalloc_obj(*p_rdma_info->dev); if (!p_rdma_info->dev) return rc; /* Allocate a struct with port params and fill it */ - p_rdma_info->port = kzalloc(sizeof(*p_rdma_info->port), GFP_KERNEL); + p_rdma_info->port = kzalloc_obj(*p_rdma_info->port); if (!p_rdma_info->port) goto free_rdma_dev; @@ -1293,7 +1293,7 @@ qed_rdma_create_qp(void *rdma_cxt, } } - qp = kzalloc(sizeof(*qp), GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return NULL; diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index d01b9245f811..9b1beb5af517 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c @@ -407,7 +407,7 @@ int qed_eq_alloc(struct qed_hwfn *p_hwfn, u16 num_elem) int ret; /* Allocate EQ struct */ - p_eq = kzalloc(sizeof(*p_eq), GFP_KERNEL); + p_eq = kzalloc_obj(*p_eq); if (!p_eq) return -ENOMEM; @@ -562,7 +562,7 @@ int qed_spq_alloc(struct qed_hwfn *p_hwfn) int ret; /* SPQ struct */ - p_spq = kzalloc(sizeof(*p_spq), GFP_KERNEL); + p_spq = kzalloc_obj(*p_spq); if (!p_spq) return -ENOMEM; @@ -633,7 +633,7 @@ int qed_spq_get_entry(struct qed_hwfn *p_hwfn, struct qed_spq_entry **pp_ent) spin_lock_bh(&p_spq->lock); if (list_empty(&p_spq->free_pool)) { - p_ent = kzalloc(sizeof(*p_ent), GFP_ATOMIC); + p_ent = kzalloc_obj(*p_ent, GFP_ATOMIC); if (!p_ent) { DP_NOTICE(p_hwfn, "Failed to allocate an SPQ entry for a pending ramrod\n"); @@ -1013,7 +1013,7 @@ int qed_consq_alloc(struct qed_hwfn *p_hwfn) int ret; /* Allocate ConsQ struct */ - p_consq = kzalloc(sizeof(*p_consq), GFP_KERNEL); + p_consq = kzalloc_obj(*p_consq); if (!p_consq) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index 5222a035fd19..96a1d9e01096 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -543,7 +543,7 @@ int qed_iov_alloc(struct qed_hwfn *p_hwfn) return 0; } - p_sriov = kzalloc(sizeof(*p_sriov), GFP_KERNEL); + p_sriov = kzalloc_obj(*p_sriov); if (!p_sriov) return -ENOMEM; @@ -600,7 +600,7 @@ int qed_iov_hw_info(struct qed_hwfn *p_hwfn) } /* Allocate a new struct for IOV information */ - cdev->p_iov_info = kzalloc(sizeof(*cdev->p_iov_info), GFP_KERNEL); + cdev->p_iov_info = kzalloc_obj(*cdev->p_iov_info); if (!cdev->p_iov_info) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qed/qed_vf.c b/drivers/net/ethernet/qlogic/qed/qed_vf.c index 0e265ed1f501..315e313d91b1 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_vf.c +++ b/drivers/net/ethernet/qlogic/qed/qed_vf.c @@ -454,7 +454,7 @@ int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn) p_hwfn->hw_info.concrete_fid = REG_RD(p_hwfn, reg); /* Allocate vf sriov info */ - p_iov = kzalloc(sizeof(*p_iov), GFP_KERNEL); + p_iov = kzalloc_obj(*p_iov); if (!p_iov) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qede/qede_filter.c b/drivers/net/ethernet/qlogic/qede/qede_filter.c index 7e341e026489..ab8b818588e2 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_filter.c +++ b/drivers/net/ethernet/qlogic/qede/qede_filter.c @@ -413,7 +413,7 @@ qede_alloc_filter(struct qede_dev *edev, int min_hlen) if (bit_id >= QEDE_RFS_MAX_FLTR) return NULL; - n = kzalloc(sizeof(*n), GFP_ATOMIC); + n = kzalloc_obj(*n, GFP_ATOMIC); if (!n) return NULL; @@ -682,7 +682,7 @@ int qede_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) DP_VERBOSE(edev, NETIF_MSG_IFUP, "Adding vlan 0x%04x\n", vid); - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) { DP_INFO(edev, "Failed to allocate struct for vlan\n"); return -ENOMEM; @@ -1916,7 +1916,7 @@ int qede_add_tc_flower_fltr(struct qede_dev *edev, __be16 proto, goto unlock; } - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) { rc = -ENOMEM; goto unlock; @@ -2059,7 +2059,7 @@ int qede_add_cls_rule(struct qede_dev *edev, struct ethtool_rxnfc *info) goto unlock; } - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) { rc = -ENOMEM; goto unlock; diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c index 66ab1b9d65a1..39842eb73bc3 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_main.c +++ b/drivers/net/ethernet/qlogic/qede/qede_main.c @@ -963,17 +963,15 @@ static int qede_alloc_fp_array(struct qede_dev *edev) struct qede_fastpath *fp; int i; - edev->fp_array = kcalloc(QEDE_QUEUE_CNT(edev), - sizeof(*edev->fp_array), GFP_KERNEL); + edev->fp_array = kzalloc_objs(*edev->fp_array, QEDE_QUEUE_CNT(edev)); if (!edev->fp_array) { DP_NOTICE(edev, "fp array allocation failed\n"); goto err; } if (!edev->coal_entry) { - edev->coal_entry = kcalloc(QEDE_MAX_RSS_CNT(edev), - sizeof(*edev->coal_entry), - GFP_KERNEL); + edev->coal_entry = kzalloc_objs(*edev->coal_entry, + QEDE_MAX_RSS_CNT(edev)); if (!edev->coal_entry) { DP_ERR(edev, "coalesce entry allocation failed\n"); goto err; @@ -990,7 +988,7 @@ static int qede_alloc_fp_array(struct qede_dev *edev) for_each_queue(i) { fp = &edev->fp_array[i]; - fp->sb_info = kzalloc(sizeof(*fp->sb_info), GFP_KERNEL); + fp->sb_info = kzalloc_obj(*fp->sb_info); if (!fp->sb_info) { DP_NOTICE(edev, "sb info struct allocation failed\n"); goto err; @@ -1007,20 +1005,18 @@ static int qede_alloc_fp_array(struct qede_dev *edev) } if (fp->type & QEDE_FASTPATH_TX) { - fp->txq = kcalloc(edev->dev_info.num_tc, - sizeof(*fp->txq), GFP_KERNEL); + fp->txq = kzalloc_objs(*fp->txq, edev->dev_info.num_tc); if (!fp->txq) goto err; } if (fp->type & QEDE_FASTPATH_RX) { - fp->rxq = kzalloc(sizeof(*fp->rxq), GFP_KERNEL); + fp->rxq = kzalloc_obj(*fp->rxq); if (!fp->rxq) goto err; if (edev->xdp_prog) { - fp->xdp_tx = kzalloc(sizeof(*fp->xdp_tx), - GFP_KERNEL); + fp->xdp_tx = kzalloc_obj(*fp->xdp_tx); if (!fp->xdp_tx) goto err; fp->type |= QEDE_FASTPATH_XDP; diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index d351be5fbda1..e3fe6306a85c 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -446,7 +446,7 @@ int qede_ptp_enable(struct qede_dev *edev) struct qede_ptp *ptp; int rc; - ptp = kzalloc(sizeof(*ptp), GFP_KERNEL); + ptp = kzalloc_obj(*ptp); if (!ptp) { DP_INFO(edev, "Failed to allocate struct for PTP\n"); return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qede/qede_rdma.c b/drivers/net/ethernet/qlogic/qede/qede_rdma.c index 6304514a6f2c..d0fff415871e 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_rdma.c +++ b/drivers/net/ethernet/qlogic/qede/qede_rdma.c @@ -258,7 +258,7 @@ qede_rdma_get_free_event_node(struct qede_dev *edev) } if (!found) { - event_node = kzalloc(sizeof(*event_node), GFP_ATOMIC); + event_node = kzalloc_obj(*event_node, GFP_ATOMIC); if (!event_node) { DP_NOTICE(edev, "qedr: Could not allocate memory for rdma work\n"); diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index fca94a69c777..861a13ad7e1a 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -2578,9 +2578,8 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev) else qdev->lrg_buf_q_alloc_size = qdev->lrg_buf_q_size * 2; - qdev->lrg_buf = kmalloc_array(qdev->num_large_buffers, - sizeof(struct ql_rcv_buf_cb), - GFP_KERNEL); + qdev->lrg_buf = kmalloc_objs(struct ql_rcv_buf_cb, + qdev->num_large_buffers); if (qdev->lrg_buf == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 91e7b38143ea..bc82cecd0fe2 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -1732,7 +1732,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) return -EIO; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return -ENOMEM; @@ -2103,7 +2103,7 @@ int qlcnic_83xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr, if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) return -EIO; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return -ENOMEM; @@ -4164,7 +4164,7 @@ int qlcnic_83xx_init_mailbox_work(struct qlcnic_adapter *adapter) struct qlcnic_hardware_context *ahw = adapter->ahw; struct qlcnic_mailbox *mbx; - ahw->mailbox = kzalloc(sizeof(*mbx), GFP_KERNEL); + ahw->mailbox = kzalloc_obj(*mbx); if (!ahw->mailbox) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 6145252d8ff8..45ed8705c7ca 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c @@ -2388,7 +2388,7 @@ static int qlcnic_83xx_get_fw_info(struct qlcnic_adapter *adapter) struct qlc_83xx_fw_info *fw_info; int err = 0; - ahw->fw_info = kzalloc(sizeof(*fw_info), GFP_KERNEL); + ahw->fw_info = kzalloc_obj(*fw_info); if (!ahw->fw_info) { err = -ENOMEM; } else { diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c index 4d638f60f237..576340315e0d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_dcb.c @@ -259,7 +259,7 @@ int qlcnic_register_dcb(struct qlcnic_adapter *adapter) if (qlcnic_sriov_vf_check(adapter)) return 0; - dcb = kzalloc(sizeof(struct qlcnic_dcb), GFP_ATOMIC); + dcb = kzalloc_obj(struct qlcnic_dcb, GFP_ATOMIC); if (!dcb) return -ENOMEM; @@ -317,13 +317,13 @@ static int __qlcnic_dcb_attach(struct qlcnic_dcb *dcb) return -1; } - dcb->cfg = kzalloc(sizeof(struct qlcnic_dcb_cfg), GFP_ATOMIC); + dcb->cfg = kzalloc_obj(struct qlcnic_dcb_cfg, GFP_ATOMIC); if (!dcb->cfg) { err = -ENOMEM; goto out_free_wq; } - dcb->param = kzalloc(sizeof(struct qlcnic_dcb_mbx_params), GFP_ATOMIC); + dcb->param = kzalloc_obj(struct qlcnic_dcb_mbx_params, GFP_ATOMIC); if (!dcb->param) { err = -ENOMEM; goto out_free_cfg; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index ae4ee0326ee1..e58176badc1f 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -489,7 +489,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan, return 0; } - cur = kzalloc(sizeof(*cur), GFP_ATOMIC); + cur = kzalloc_obj(*cur, GFP_ATOMIC); if (cur == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c index 09f20c794754..9192c5ad5a16 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c @@ -189,8 +189,8 @@ int qlcnic_alloc_sw_resources(struct qlcnic_adapter *adapter) recv_ctx = adapter->recv_ctx; - rds_ring = kcalloc(adapter->max_rds_rings, - sizeof(struct qlcnic_host_rds_ring), GFP_KERNEL); + rds_ring = kzalloc_objs(struct qlcnic_host_rds_ring, + adapter->max_rds_rings); if (rds_ring == NULL) goto err_out; @@ -454,7 +454,7 @@ int qlcnic_pinit_from_rom(struct qlcnic_adapter *adapter) return -EIO; } - buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kzalloc_objs(struct crb_addr_pair, n); if (buf == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c index b9dc0071c5de..537fd26da904 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c @@ -220,7 +220,7 @@ static void qlcnic_add_lb_filter(struct qlcnic_adapter *adapter, return; } - fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); + fil = kzalloc_obj(struct qlcnic_filter, GFP_ATOMIC); if (!fil) return; @@ -346,7 +346,7 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter, return; } - fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC); + fil = kzalloc_obj(struct qlcnic_filter, GFP_ATOMIC); if (!fil) return; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index e051d8c7a28d..ff4f7cd20c79 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -679,9 +679,8 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter) num_msix += 1; if (!adapter->msix_entries) { - adapter->msix_entries = kcalloc(num_msix, - sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, + num_msix); if (!adapter->msix_entries) return -ENOMEM; } @@ -734,9 +733,8 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) int err, vector; if (!adapter->msix_entries) { - adapter->msix_entries = kcalloc(num_msix, - sizeof(struct msix_entry), - GFP_KERNEL); + adapter->msix_entries = kzalloc_objs(struct msix_entry, + num_msix); if (!adapter->msix_entries) return -ENOMEM; } @@ -952,7 +950,7 @@ static int qlcnic_get_act_pci_func(struct qlcnic_adapter *adapter) if (ahw->op_mode == QLCNIC_MGMT_FUNC) return 0; - pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); + pci_info = kzalloc_objs(*pci_info, ahw->max_vnic_func); if (!pci_info) return -ENOMEM; @@ -986,7 +984,7 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) u16 act_pci_func; u8 pfn; - pci_info = kcalloc(ahw->max_vnic_func, sizeof(*pci_info), GFP_KERNEL); + pci_info = kzalloc_objs(*pci_info, ahw->max_vnic_func); if (!pci_info) return -ENOMEM; @@ -996,17 +994,14 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter) act_pci_func = ahw->total_nic_func; - adapter->npars = kcalloc(act_pci_func, - sizeof(struct qlcnic_npar_info), - GFP_KERNEL); + adapter->npars = kzalloc_objs(struct qlcnic_npar_info, act_pci_func); if (!adapter->npars) { ret = -ENOMEM; goto err_pci_info; } - adapter->eswitch = kcalloc(QLCNIC_NIU_MAX_XG_PORTS, - sizeof(struct qlcnic_eswitch), - GFP_KERNEL); + adapter->eswitch = kzalloc_objs(struct qlcnic_eswitch, + QLCNIC_NIU_MAX_XG_PORTS); if (!adapter->eswitch) { ret = -ENOMEM; goto err_npars; @@ -2059,8 +2054,7 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) struct qlcnic_hardware_context *ahw = adapter->ahw; int err = 0; - adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), - GFP_KERNEL); + adapter->recv_ctx = kzalloc_obj(struct qlcnic_recv_context); if (!adapter->recv_ctx) { err = -ENOMEM; goto err_out; @@ -2356,8 +2350,8 @@ int qlcnic_alloc_tx_rings(struct qlcnic_adapter *adapter, struct qlcnic_host_tx_ring *tx_ring; struct qlcnic_cmd_buffer *cmd_buf_arr; - tx_ring = kcalloc(adapter->drv_tx_rings, - sizeof(struct qlcnic_host_tx_ring), GFP_KERNEL); + tx_ring = kzalloc_objs(struct qlcnic_host_tx_ring, + adapter->drv_tx_rings); if (tx_ring == NULL) return -ENOMEM; @@ -2444,7 +2438,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_master(pdev); - ahw = kzalloc(sizeof(struct qlcnic_hardware_context), GFP_KERNEL); + ahw = kzalloc_obj(struct qlcnic_hardware_context); if (!ahw) { err = -ENOMEM; goto err_out_free_res; @@ -2851,8 +2845,8 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) adapter->fhash.fbucket_size = QLC_83XX_LB_BUCKET_SIZE; } - head = kcalloc(adapter->fhash.fbucket_size, - sizeof(struct hlist_head), GFP_ATOMIC); + head = kzalloc_objs(struct hlist_head, adapter->fhash.fbucket_size, + GFP_ATOMIC); if (!head) return; @@ -2868,8 +2862,8 @@ void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter) adapter->rx_fhash.fbucket_size = adapter->fhash.fbucket_size; - head = kcalloc(adapter->rx_fhash.fbucket_size, - sizeof(struct hlist_head), GFP_ATOMIC); + head = kzalloc_objs(struct hlist_head, adapter->rx_fhash.fbucket_size, + GFP_ATOMIC); if (!head) return; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c index 7ecb3dfe30bd..44d16a303555 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_minidump.c @@ -792,8 +792,7 @@ static u32 qlcnic_read_memory_pexdma(struct qlcnic_adapter *adapter, } /* Create DMA descriptor */ - dma_descr = kzalloc(sizeof(struct qlcnic_pex_dma_descriptor), - GFP_KERNEL); + dma_descr = kzalloc_obj(struct qlcnic_pex_dma_descriptor); if (!dma_descr) { *ret = -ENOMEM; return 0; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index d57b976b9040..0704dbc52d82 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c @@ -149,15 +149,14 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) if (!qlcnic_sriov_enable_check(adapter)) return -EIO; - sriov = kzalloc(sizeof(struct qlcnic_sriov), GFP_KERNEL); + sriov = kzalloc_obj(struct qlcnic_sriov); if (!sriov) return -ENOMEM; adapter->ahw->sriov = sriov; sriov->num_vfs = num_vfs; bc = &sriov->bc; - sriov->vf_info = kcalloc(num_vfs, sizeof(struct qlcnic_vf_info), - GFP_KERNEL); + sriov->vf_info = kzalloc_objs(struct qlcnic_vf_info, num_vfs); if (!sriov->vf_info) { err = -ENOMEM; goto qlcnic_free_sriov; @@ -201,7 +200,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs) INIT_WORK(&vf->trans_work, qlcnic_sriov_process_bc_cmd); if (qlcnic_sriov_pf_check(adapter)) { - vp = kzalloc(sizeof(struct qlcnic_vport), GFP_KERNEL); + vp = kzalloc_obj(struct qlcnic_vport); if (!vp) { err = -ENOMEM; goto qlcnic_destroy_async_wq; @@ -699,7 +698,7 @@ int qlcnic_sriov_func_to_index(struct qlcnic_adapter *adapter, u8 pci_func) static inline int qlcnic_sriov_alloc_bc_trans(struct qlcnic_bc_trans **trans) { - *trans = kzalloc(sizeof(struct qlcnic_bc_trans), GFP_ATOMIC); + *trans = kzalloc_obj(struct qlcnic_bc_trans, GFP_ATOMIC); if (!*trans) return -ENOMEM; @@ -710,7 +709,7 @@ static inline int qlcnic_sriov_alloc_bc_trans(struct qlcnic_bc_trans **trans) static inline int qlcnic_sriov_alloc_bc_msg(struct qlcnic_bc_hdr **hdr, u32 size) { - *hdr = kcalloc(size, sizeof(struct qlcnic_bc_hdr), GFP_ATOMIC); + *hdr = kzalloc_objs(struct qlcnic_bc_hdr, size, GFP_ATOMIC); if (!*hdr) return -ENOMEM; @@ -1634,7 +1633,7 @@ qlcnic_sriov_alloc_async_cmd(struct qlcnic_back_channel *bc, { struct qlcnic_async_cmd *entry = NULL; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return NULL; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c index 8dd7aa08ecfb..7052d34aad45 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c @@ -799,7 +799,7 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter, vp = vf->vp; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (!cmd) return -ENOMEM; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c index 5296d9a6ee83..6f0d6376607d 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c @@ -909,7 +909,7 @@ static ssize_t qlcnic_sysfs_read_pci_config(struct file *file, int i, ret; u32 count; - pci_info = kcalloc(size, sizeof(*pci_info), GFP_KERNEL); + pci_info = kzalloc_objs(*pci_info, size); if (!pci_info) return -ENOMEM; diff --git a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c index ba8763cac9d9..269c0449760c 100644 --- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c @@ -68,7 +68,7 @@ static int rmnet_register_real_device(struct net_device *real_dev, return 0; } - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -143,7 +143,7 @@ static int rmnet_newlink(struct net_device *dev, return -ENODEV; } - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; diff --git a/drivers/net/ethernet/realtek/r8169_leds.c b/drivers/net/ethernet/realtek/r8169_leds.c index e10bee706bc6..1999e81f0bca 100644 --- a/drivers/net/ethernet/realtek/r8169_leds.c +++ b/drivers/net/ethernet/realtek/r8169_leds.c @@ -154,7 +154,7 @@ struct r8169_led_classdev *rtl8168_init_leds(struct net_device *ndev) struct r8169_led_classdev *leds; int i; - leds = kcalloc(RTL8168_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL); + leds = kzalloc_objs(*leds, RTL8168_NUM_LEDS + 1); if (!leds) return NULL; @@ -253,7 +253,7 @@ struct r8169_led_classdev *rtl8125_init_leds(struct net_device *ndev) struct r8169_led_classdev *leds; int i; - leds = kcalloc(RTL8125_NUM_LEDS + 1, sizeof(*leds), GFP_KERNEL); + leds = kzalloc_objs(*leds, RTL8125_NUM_LEDS + 1); if (!leds) return NULL; diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index 2f7d9809c373..58788d196c57 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -2683,7 +2683,7 @@ static void rtl_request_firmware(struct rtl8169_private *tp) if (tp->rtl_fw || !tp->fw_name) return; - rtl_fw = kzalloc(sizeof(*rtl_fw), GFP_KERNEL); + rtl_fw = kzalloc_obj(*rtl_fw); if (!rtl_fw) return; diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c index 57b0db314fb5..84b657fc2e15 100644 --- a/drivers/net/ethernet/renesas/ravb_main.c +++ b/drivers/net/ethernet/renesas/ravb_main.c @@ -436,14 +436,13 @@ static int ravb_ring_init(struct net_device *ndev, int q) goto error; /* Allocate RX buffers */ - priv->rx_buffers[q] = kcalloc(priv->num_rx_ring[q], - sizeof(*priv->rx_buffers[q]), GFP_KERNEL); + priv->rx_buffers[q] = kzalloc_objs(*priv->rx_buffers[q], + priv->num_rx_ring[q]); if (!priv->rx_buffers[q]) goto error; /* Allocate TX skb rings */ - priv->tx_skb[q] = kcalloc(priv->num_tx_ring[q], - sizeof(*priv->tx_skb[q]), GFP_KERNEL); + priv->tx_skb[q] = kzalloc_objs(*priv->tx_skb[q], priv->num_tx_ring[q]); if (!priv->tx_skb[q]) goto error; @@ -2199,7 +2198,7 @@ static netdev_tx_t ravb_start_xmit(struct sk_buff *skb, struct net_device *ndev) /* TX timestamp required */ if (info->gptp || info->ccc_gac) { if (q == RAVB_NC) { - ts_skb = kmalloc(sizeof(*ts_skb), GFP_ATOMIC); + ts_skb = kmalloc_obj(*ts_skb, GFP_ATOMIC); if (!ts_skb) { if (num_tx_desc > 1) { desc--; diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c index 433eb2b00d10..6fe964816322 100644 --- a/drivers/net/ethernet/renesas/rswitch_main.c +++ b/drivers/net/ethernet/renesas/rswitch_main.c @@ -346,7 +346,7 @@ static int rswitch_gwca_queue_alloc(struct net_device *ndev, gq->ndev = ndev; if (!dir_tx) { - gq->rx_bufs = kcalloc(gq->ring_size, sizeof(*gq->rx_bufs), GFP_KERNEL); + gq->rx_bufs = kzalloc_objs(*gq->rx_bufs, gq->ring_size); if (!gq->rx_bufs) return -ENOMEM; if (rswitch_gwca_queue_alloc_rx_buf(gq, 0, gq->ring_size) < 0) @@ -356,10 +356,10 @@ static int rswitch_gwca_queue_alloc(struct net_device *ndev, sizeof(struct rswitch_ext_ts_desc) * (gq->ring_size + 1), &gq->ring_dma, GFP_KERNEL); } else { - gq->skbs = kcalloc(gq->ring_size, sizeof(*gq->skbs), GFP_KERNEL); + gq->skbs = kzalloc_objs(*gq->skbs, gq->ring_size); if (!gq->skbs) return -ENOMEM; - gq->unmap_addrs = kcalloc(gq->ring_size, sizeof(*gq->unmap_addrs), GFP_KERNEL); + gq->unmap_addrs = kzalloc_objs(*gq->unmap_addrs, gq->ring_size); if (!gq->unmap_addrs) goto out; gq->tx_ring = dma_alloc_coherent(ndev->dev.parent, diff --git a/drivers/net/ethernet/renesas/rtsn.c b/drivers/net/ethernet/renesas/rtsn.c index 85052b47afb9..03a2669f0518 100644 --- a/drivers/net/ethernet/renesas/rtsn.c +++ b/drivers/net/ethernet/renesas/rtsn.c @@ -349,8 +349,8 @@ static int rtsn_chain_init(struct rtsn_private *priv, int tx_size, int rx_size) priv->num_tx_ring = tx_size; priv->num_rx_ring = rx_size; - priv->tx_skb = kcalloc(tx_size, sizeof(*priv->tx_skb), GFP_KERNEL); - priv->rx_skb = kcalloc(rx_size, sizeof(*priv->rx_skb), GFP_KERNEL); + priv->tx_skb = kzalloc_objs(*priv->tx_skb, tx_size); + priv->rx_skb = kzalloc_objs(*priv->rx_skb, rx_size); if (!priv->rx_skb || !priv->tx_skb) goto error; diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6fb0ffc1c844..bfaa9aa63fa1 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1410,13 +1410,11 @@ static int sh_eth_ring_init(struct net_device *ndev) mdp->rx_buf_sz += NET_IP_ALIGN; /* Allocate RX and TX skb rings */ - mdp->rx_skbuff = kcalloc(mdp->num_rx_ring, sizeof(*mdp->rx_skbuff), - GFP_KERNEL); + mdp->rx_skbuff = kzalloc_objs(*mdp->rx_skbuff, mdp->num_rx_ring); if (!mdp->rx_skbuff) return -ENOMEM; - mdp->tx_skbuff = kcalloc(mdp->num_tx_ring, sizeof(*mdp->tx_skbuff), - GFP_KERNEL); + mdp->tx_skbuff = kzalloc_objs(*mdp->tx_skbuff, mdp->num_tx_ring); if (!mdp->tx_skbuff) goto ring_free; diff --git a/drivers/net/ethernet/rocker/rocker_main.c b/drivers/net/ethernet/rocker/rocker_main.c index 2794f75df8fc..ff6ca7b2cd4f 100644 --- a/drivers/net/ethernet/rocker/rocker_main.c +++ b/drivers/net/ethernet/rocker/rocker_main.c @@ -66,7 +66,7 @@ static struct rocker_wait *rocker_wait_create(void) { struct rocker_wait *wait; - wait = kzalloc(sizeof(*wait), GFP_KERNEL); + wait = kzalloc_obj(*wait); if (!wait) return NULL; return wait; @@ -435,8 +435,7 @@ static int rocker_dma_ring_create(const struct rocker *rocker, info->type = type; info->head = 0; info->tail = 0; - info->desc_info = kcalloc(info->size, sizeof(*info->desc_info), - GFP_KERNEL); + info->desc_info = kzalloc_objs(*info->desc_info, info->size); if (!info->desc_info) return -ENOMEM; @@ -2155,7 +2154,7 @@ static int rocker_router_fib_event(struct notifier_block *nb, if (info->family != AF_INET) return NOTIFY_DONE; - fib_work = kzalloc(sizeof(*fib_work), GFP_ATOMIC); + fib_work = kzalloc_obj(*fib_work, GFP_ATOMIC); if (WARN_ON(!fib_work)) return NOTIFY_BAD; @@ -2648,9 +2647,7 @@ static int rocker_msix_init(struct rocker *rocker) if (msix_entries != ROCKER_MSIX_VEC_COUNT(rocker->port_count)) return -EINVAL; - rocker->msix_entries = kmalloc_array(msix_entries, - sizeof(struct msix_entry), - GFP_KERNEL); + rocker->msix_entries = kmalloc_objs(struct msix_entry, msix_entries); if (!rocker->msix_entries) return -ENOMEM; @@ -2764,7 +2761,7 @@ static int rocker_switchdev_event(struct notifier_block *unused, return rocker_switchdev_port_attr_set_event(dev, ptr); rocker_port = netdev_priv(dev); - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; @@ -2850,7 +2847,7 @@ static int rocker_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct rocker *rocker; int err; - rocker = kzalloc(sizeof(*rocker), GFP_KERNEL); + rocker = kzalloc_obj(*rocker); if (!rocker) return -ENOMEM; diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c index 61e50517c05b..50ea5f9ef63a 100644 --- a/drivers/net/ethernet/rocker/rocker_ofdpa.c +++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c @@ -838,7 +838,7 @@ static int ofdpa_flow_tbl_ig_port(struct ofdpa_port *ofdpa_port, int flags, { struct ofdpa_flow_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -860,7 +860,7 @@ static int ofdpa_flow_tbl_vlan(struct ofdpa_port *ofdpa_port, { struct ofdpa_flow_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -886,7 +886,7 @@ static int ofdpa_flow_tbl_term_mac(struct ofdpa_port *ofdpa_port, { struct ofdpa_flow_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -926,7 +926,7 @@ static int ofdpa_flow_tbl_bridge(struct ofdpa_port *ofdpa_port, bool dflt = !eth_dst || eth_dst_mask; bool wild = false; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -976,7 +976,7 @@ static int ofdpa_flow_tbl_ucast4_routing(struct ofdpa_port *ofdpa_port, { struct ofdpa_flow_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1006,7 +1006,7 @@ static int ofdpa_flow_tbl_acl(struct ofdpa_port *ofdpa_port, int flags, u32 priority; struct ofdpa_flow_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1150,7 +1150,7 @@ static int ofdpa_group_l2_interface(struct ofdpa_port *ofdpa_port, { struct ofdpa_group_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1166,7 +1166,7 @@ static int ofdpa_group_l2_fan_out(struct ofdpa_port *ofdpa_port, { struct ofdpa_group_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1199,7 +1199,7 @@ static int ofdpa_group_l3_unicast(struct ofdpa_port *ofdpa_port, int flags, { struct ofdpa_group_tbl_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1273,7 +1273,7 @@ static int ofdpa_port_ipv4_neigh(struct ofdpa_port *ofdpa_port, bool removing; int err = 0; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -1386,7 +1386,7 @@ static int ofdpa_port_ipv4_nh(struct ofdpa_port *ofdpa_port, bool resolved = true; int err = 0; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1866,7 +1866,7 @@ static int ofdpa_port_fdb_learn(struct ofdpa_port *ofdpa_port, if (!(flags & OFDPA_OP_FLAG_LEARNED)) return 0; - lw = kzalloc(sizeof(*lw), GFP_ATOMIC); + lw = kzalloc_obj(*lw, GFP_ATOMIC); if (!lw) return -ENOMEM; @@ -1904,7 +1904,7 @@ static int ofdpa_port_fdb(struct ofdpa_port *ofdpa_port, bool removing = (flags & OFDPA_OP_FLAG_REMOVE); unsigned long lock_flags; - fdb = kzalloc(sizeof(*fdb), GFP_KERNEL); + fdb = kzalloc_obj(*fdb); if (!fdb) return -ENOMEM; @@ -2232,7 +2232,7 @@ static __be16 ofdpa_port_internal_vlan_id_get(struct ofdpa_port *ofdpa_port, unsigned long lock_flags; int i; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return 0; diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 849c5a6c2af1..5051ada43d2f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -489,15 +489,13 @@ static int init_rx_ring(struct net_device *dev, u8 queue_no, return -ENOMEM; /* allocate memory for RX skbuff array */ - rx_ring->rx_skbuff_dma = kmalloc_array(rx_rsize, - sizeof(dma_addr_t), GFP_KERNEL); + rx_ring->rx_skbuff_dma = kmalloc_objs(dma_addr_t, rx_rsize); if (!rx_ring->rx_skbuff_dma) { ret = -ENOMEM; goto err_free_dma_rx; } - rx_ring->rx_skbuff = kmalloc_array(rx_rsize, - sizeof(struct sk_buff *), GFP_KERNEL); + rx_ring->rx_skbuff = kmalloc_objs(struct sk_buff *, rx_rsize); if (!rx_ring->rx_skbuff) { ret = -ENOMEM; goto err_free_skbuff_dma; @@ -2007,7 +2005,7 @@ static int sxgbe_hw_init(struct sxgbe_priv_data * const priv) { u32 ctrl_ids; - priv->hw = kmalloc(sizeof(*priv->hw), GFP_KERNEL); + priv->hw = kmalloc_obj(*priv->hw); if(!priv->hw) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index fcec81f862ec..7e04f115bbaa 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -431,7 +431,7 @@ static int efx_ef10_add_vlan(struct efx_nic *efx, u16 vid) } rc = -ENOMEM; - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) goto fail_alloc; @@ -527,7 +527,7 @@ static int efx_ef10_probe(struct efx_nic *efx) struct efx_ef10_nic_data *nic_data; int i, rc; - nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); + nic_data = kzalloc_obj(*nic_data); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; @@ -3591,7 +3591,7 @@ static int efx_ef10_mtd_probe(struct efx_nic *efx) MCDI_VAR_ARRAY_LEN(outlen, NVRAM_PARTITIONS_OUT_TYPE_ID)) return -EIO; - parts = kcalloc(n_parts_total, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, n_parts_total); if (!parts) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/ef100.c b/drivers/net/ethernet/sfc/ef100.c index 6334992b0af4..0dd5364506d7 100644 --- a/drivers/net/ethernet/sfc/ef100.c +++ b/drivers/net/ethernet/sfc/ef100.c @@ -453,7 +453,7 @@ static int ef100_pci_probe(struct pci_dev *pci_dev, int rc; /* Allocate probe data and struct efx_nic */ - probe_data = kzalloc(sizeof(*probe_data), GFP_KERNEL); + probe_data = kzalloc_obj(*probe_data); if (!probe_data) return -ENOMEM; probe_data->pci_dev = pci_dev; diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 3ad95a4c8af2..00050f786cae 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -351,7 +351,7 @@ int ef100_phy_probe(struct efx_nic *efx) int rc; /* Probe for the PHY */ - efx->phy_data = kzalloc(sizeof(struct efx_mcdi_phy_data), GFP_KERNEL); + efx->phy_data = kzalloc_obj(struct efx_mcdi_phy_data); if (!efx->phy_data) return -ENOMEM; @@ -1020,7 +1020,7 @@ static int ef100_probe_main(struct efx_nic *efx) if (WARN_ON(bar_size == 0)) return -EIO; - nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); + nic_data = kzalloc_obj(*nic_data); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; diff --git a/drivers/net/ethernet/sfc/ef10_sriov.c b/drivers/net/ethernet/sfc/ef10_sriov.c index 9aae0d8b713f..f98f1707d1a9 100644 --- a/drivers/net/ethernet/sfc/ef10_sriov.c +++ b/drivers/net/ethernet/sfc/ef10_sriov.c @@ -189,8 +189,7 @@ static int efx_ef10_sriov_alloc_vf_vswitching(struct efx_nic *efx) unsigned int i; int rc; - nic_data->vf = kcalloc(efx->vf_count, sizeof(struct ef10_vf), - GFP_KERNEL); + nic_data->vf = kzalloc_objs(struct ef10_vf, efx->vf_count); if (!nic_data->vf) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 112e55b98ed3..8f136a11d396 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1155,7 +1155,7 @@ static int efx_pci_probe(struct pci_dev *pci_dev, int rc; /* Allocate probe data and struct efx_nic */ - probe_data = kzalloc(sizeof(*probe_data), GFP_KERNEL); + probe_data = kzalloc_obj(*probe_data); if (!probe_data) return -ENOMEM; probe_data->pci_dev = pci_dev; diff --git a/drivers/net/ethernet/sfc/efx_channels.c b/drivers/net/ethernet/sfc/efx_channels.c index ed3a96ebc7f3..f4dc3f3f4416 100644 --- a/drivers/net/ethernet/sfc/efx_channels.c +++ b/drivers/net/ethernet/sfc/efx_channels.c @@ -534,7 +534,7 @@ static struct efx_channel *efx_alloc_channel(struct efx_nic *efx, int i) struct efx_channel *channel; int j; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return NULL; @@ -604,7 +604,7 @@ struct efx_channel *efx_copy_channel(const struct efx_channel *old_channel) struct efx_channel *channel; int j; - channel = kmalloc(sizeof(*channel), GFP_KERNEL); + channel = kmalloc_obj(*channel); if (!channel) return NULL; @@ -934,9 +934,8 @@ int efx_set_channels(struct efx_nic *efx) EFX_WARN_ON_PARANOID(efx->xdp_tx_queues); /* Allocate array for XDP TX queue lookup. */ - efx->xdp_tx_queues = kcalloc(efx->xdp_tx_queue_count, - sizeof(*efx->xdp_tx_queues), - GFP_KERNEL); + efx->xdp_tx_queues = kzalloc_objs(*efx->xdp_tx_queues, + efx->xdp_tx_queue_count); if (!efx->xdp_tx_queues) return -ENOMEM; } diff --git a/drivers/net/ethernet/sfc/efx_common.c b/drivers/net/ethernet/sfc/efx_common.c index e8fdbb62d872..3afaec36642f 100644 --- a/drivers/net/ethernet/sfc/efx_common.c +++ b/drivers/net/ethernet/sfc/efx_common.c @@ -996,8 +996,8 @@ int efx_init_struct(struct efx_nic *efx, struct pci_dev *pci_dev) mutex_init(&efx->rps_mutex); spin_lock_init(&efx->rps_hash_lock); /* Failure to allocate is not fatal, but may degrade ARFS performance */ - efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE, - sizeof(*efx->rps_hash_table), GFP_KERNEL); + efx->rps_hash_table = kzalloc_objs(*efx->rps_hash_table, + EFX_ARFS_HASH_TABLE_SIZE); #endif spin_lock_init(&efx->vf_reps_lock); INIT_LIST_HEAD(&efx->vf_reps); diff --git a/drivers/net/ethernet/sfc/ethtool_common.c b/drivers/net/ethernet/sfc/ethtool_common.c index 2fc42b1a2bfb..54f8e4626568 100644 --- a/drivers/net/ethernet/sfc/ethtool_common.c +++ b/drivers/net/ethernet/sfc/ethtool_common.c @@ -133,7 +133,7 @@ void efx_ethtool_self_test(struct net_device *net_dev, bool already_up; int rc = -ENOMEM; - efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); + efx_tests = kzalloc_obj(*efx_tests); if (!efx_tests) goto fail; diff --git a/drivers/net/ethernet/sfc/falcon/efx.c b/drivers/net/ethernet/sfc/falcon/efx.c index 6ea41f6c9ef5..0c197b448645 100644 --- a/drivers/net/ethernet/sfc/falcon/efx.c +++ b/drivers/net/ethernet/sfc/falcon/efx.c @@ -423,7 +423,7 @@ ef4_alloc_channel(struct ef4_nic *efx, int i, struct ef4_channel *old_channel) struct ef4_tx_queue *tx_queue; int j; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return NULL; @@ -456,7 +456,7 @@ ef4_copy_channel(const struct ef4_channel *old_channel) struct ef4_tx_queue *tx_queue; int j; - channel = kmalloc(sizeof(*channel), GFP_KERNEL); + channel = kmalloc_obj(*channel); if (!channel) return NULL; diff --git a/drivers/net/ethernet/sfc/falcon/ethtool.c b/drivers/net/ethernet/sfc/falcon/ethtool.c index 049364031545..3d81b3ca61e9 100644 --- a/drivers/net/ethernet/sfc/falcon/ethtool.c +++ b/drivers/net/ethernet/sfc/falcon/ethtool.c @@ -493,7 +493,7 @@ static void ef4_ethtool_self_test(struct net_device *net_dev, bool already_up; int rc = -ENOMEM; - ef4_tests = kzalloc(sizeof(*ef4_tests), GFP_KERNEL); + ef4_tests = kzalloc_obj(*ef4_tests); if (!ef4_tests) goto fail; diff --git a/drivers/net/ethernet/sfc/falcon/falcon.c b/drivers/net/ethernet/sfc/falcon/falcon.c index c44df8e4dd30..fb1d19b7c419 100644 --- a/drivers/net/ethernet/sfc/falcon/falcon.c +++ b/drivers/net/ethernet/sfc/falcon/falcon.c @@ -929,7 +929,7 @@ static int falcon_mtd_probe(struct ef4_nic *efx) ASSERT_RTNL(); /* Allocate space for maximum number of partitions */ - parts = kcalloc(2, sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, 2); if (!parts) return -ENOMEM; n_parts = 0; @@ -2180,7 +2180,7 @@ static int falcon_probe_nvconfig(struct ef4_nic *efx) struct falcon_nvconfig *nvconfig; int rc; - nvconfig = kmalloc(sizeof(*nvconfig), GFP_KERNEL); + nvconfig = kmalloc_obj(*nvconfig); if (!nvconfig) return -ENOMEM; @@ -2289,7 +2289,7 @@ static int falcon_probe_nic(struct ef4_nic *efx) efx->primary = efx; /* only one usable function per controller */ /* Allocate storage for hardware specific data */ - nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); + nic_data = kzalloc_obj(*nic_data); if (!nic_data) return -ENOMEM; efx->nic_data = nic_data; diff --git a/drivers/net/ethernet/sfc/falcon/farch.c b/drivers/net/ethernet/sfc/falcon/farch.c index 01017c41338e..23d507a3820d 100644 --- a/drivers/net/ethernet/sfc/falcon/farch.c +++ b/drivers/net/ethernet/sfc/falcon/farch.c @@ -2701,7 +2701,7 @@ int ef4_farch_filter_table_probe(struct ef4_nic *efx) struct ef4_farch_filter_table *table; unsigned table_id; - state = kzalloc(sizeof(struct ef4_farch_filter_state), GFP_KERNEL); + state = kzalloc_obj(struct ef4_farch_filter_state); if (!state) return -ENOMEM; efx->filter_state = state; diff --git a/drivers/net/ethernet/sfc/falcon/qt202x_phy.c b/drivers/net/ethernet/sfc/falcon/qt202x_phy.c index 21af67e42296..2dd7d7ba1559 100644 --- a/drivers/net/ethernet/sfc/falcon/qt202x_phy.c +++ b/drivers/net/ethernet/sfc/falcon/qt202x_phy.c @@ -340,7 +340,7 @@ static int qt202x_phy_probe(struct ef4_nic *efx) { struct qt202x_phy_data *phy_data; - phy_data = kzalloc(sizeof(struct qt202x_phy_data), GFP_KERNEL); + phy_data = kzalloc_obj(struct qt202x_phy_data); if (!phy_data) return -ENOMEM; efx->phy_data = phy_data; diff --git a/drivers/net/ethernet/sfc/falcon/rx.c b/drivers/net/ethernet/sfc/falcon/rx.c index f69fcf6caca8..e7e955bc9631 100644 --- a/drivers/net/ethernet/sfc/falcon/rx.c +++ b/drivers/net/ethernet/sfc/falcon/rx.c @@ -701,8 +701,7 @@ int ef4_probe_rx_queue(struct ef4_rx_queue *rx_queue) rx_queue->ptr_mask); /* Allocate RX buffers */ - rx_queue->buffer = kcalloc(entries, sizeof(*rx_queue->buffer), - GFP_KERNEL); + rx_queue->buffer = kzalloc_objs(*rx_queue->buffer, entries); if (!rx_queue->buffer) return -ENOMEM; @@ -734,8 +733,7 @@ static void ef4_init_rx_recycle_ring(struct ef4_nic *efx, page_ring_size = roundup_pow_of_two(bufs_in_recycle_ring / efx->rx_bufs_per_page); - rx_queue->page_ring = kcalloc(page_ring_size, - sizeof(*rx_queue->page_ring), GFP_KERNEL); + rx_queue->page_ring = kzalloc_objs(*rx_queue->page_ring, page_ring_size); if (!rx_queue->page_ring) rx_queue->page_ptr_mask = 0; else diff --git a/drivers/net/ethernet/sfc/falcon/selftest.c b/drivers/net/ethernet/sfc/falcon/selftest.c index c3dc88e6c26c..db4dd7fb77f5 100644 --- a/drivers/net/ethernet/sfc/falcon/selftest.c +++ b/drivers/net/ethernet/sfc/falcon/selftest.c @@ -545,8 +545,7 @@ ef4_test_loopback(struct ef4_tx_queue *tx_queue, /* Determine how many packets to send */ state->packet_count = efx->txq_entries / 3; state->packet_count = min(1 << (i << 2), state->packet_count); - state->skbs = kcalloc(state->packet_count, - sizeof(state->skbs[0]), GFP_KERNEL); + state->skbs = kzalloc_objs(state->skbs[0], state->packet_count); if (!state->skbs) return -ENOMEM; state->flush = false; @@ -635,7 +634,7 @@ static int ef4_test_loopbacks(struct ef4_nic *efx, struct ef4_self_tests *tests, /* Set the port loopback_selftest member. From this point on * all received packets will be dropped. Mark the state as * "flushing" so all inflight packets are dropped */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return -ENOMEM; BUG_ON(efx->loopback_selftest); diff --git a/drivers/net/ethernet/sfc/falcon/tenxpress.c b/drivers/net/ethernet/sfc/falcon/tenxpress.c index e27824ef121f..db9d35bde75d 100644 --- a/drivers/net/ethernet/sfc/falcon/tenxpress.c +++ b/drivers/net/ethernet/sfc/falcon/tenxpress.c @@ -165,7 +165,7 @@ static int tenxpress_phy_probe(struct ef4_nic *efx) struct tenxpress_phy_data *phy_data; /* Allocate phy private storage */ - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + phy_data = kzalloc_obj(*phy_data); if (!phy_data) return -ENOMEM; efx->phy_data = phy_data; diff --git a/drivers/net/ethernet/sfc/falcon/tx.c b/drivers/net/ethernet/sfc/falcon/tx.c index e6e80b039ca2..9e18aaf44bad 100644 --- a/drivers/net/ethernet/sfc/falcon/tx.c +++ b/drivers/net/ethernet/sfc/falcon/tx.c @@ -544,13 +544,12 @@ int ef4_probe_tx_queue(struct ef4_tx_queue *tx_queue) tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask); /* Allocate software ring */ - tx_queue->buffer = kcalloc(entries, sizeof(*tx_queue->buffer), - GFP_KERNEL); + tx_queue->buffer = kzalloc_objs(*tx_queue->buffer, entries); if (!tx_queue->buffer) return -ENOMEM; - tx_queue->cb_page = kcalloc(ef4_tx_cb_page_count(tx_queue), - sizeof(tx_queue->cb_page[0]), GFP_KERNEL); + tx_queue->cb_page = kzalloc_objs(tx_queue->cb_page[0], + ef4_tx_cb_page_count(tx_queue)); if (!tx_queue->cb_page) { rc = -ENOMEM; goto fail1; diff --git a/drivers/net/ethernet/sfc/falcon/txc43128_phy.c b/drivers/net/ethernet/sfc/falcon/txc43128_phy.c index f3503965c52c..f20f9166d730 100644 --- a/drivers/net/ethernet/sfc/falcon/txc43128_phy.c +++ b/drivers/net/ethernet/sfc/falcon/txc43128_phy.c @@ -323,7 +323,7 @@ static int txc43128_phy_probe(struct ef4_nic *efx) struct txc43128_data *phy_data; /* Allocate phy private storage */ - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + phy_data = kzalloc_obj(*phy_data); if (!phy_data) return -ENOMEM; efx->phy_data = phy_data; diff --git a/drivers/net/ethernet/sfc/mae.c b/drivers/net/ethernet/sfc/mae.c index 7cfd9000f79d..7a8606efd492 100644 --- a/drivers/net/ethernet/sfc/mae.c +++ b/drivers/net/ethernet/sfc/mae.c @@ -255,14 +255,12 @@ static int efx_mae_table_get_desc(struct efx_nic *efx, if (desc->scheme) goto fail; rc = -ENOMEM; - desc->keys = kcalloc(desc->n_keys, - sizeof(struct efx_tc_table_field_fmt), - GFP_KERNEL); + desc->keys = kzalloc_objs(struct efx_tc_table_field_fmt, + desc->n_keys); if (!desc->keys) goto fail; - desc->resps = kcalloc(desc->n_resps, - sizeof(struct efx_tc_table_field_fmt), - GFP_KERNEL); + desc->resps = kzalloc_objs(struct efx_tc_table_field_fmt, + desc->n_resps); if (!desc->resps) goto fail; } @@ -1160,7 +1158,7 @@ int efx_mae_enumerate_mports(struct efx_nic *efx) for (i = 0; i < count; i++) { struct mae_mport_desc *d; - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) { rc = -ENOMEM; goto fail; @@ -2315,7 +2313,7 @@ int efx_init_mae(struct efx_nic *efx) if (!nic_data->have_mport) return -EINVAL; - mae = kmalloc(sizeof(*mae), GFP_KERNEL); + mae = kmalloc_obj(*mae); if (!mae) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 5e9b8def5e42..e65db9b70724 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -63,7 +63,7 @@ int efx_mcdi_init(struct efx_nic *efx) bool already_attached; int rc = -ENOMEM; - efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); + efx->mcdi = kzalloc_obj(*efx->mcdi); if (!efx->mcdi) goto fail; diff --git a/drivers/net/ethernet/sfc/mcdi_filters.c b/drivers/net/ethernet/sfc/mcdi_filters.c index 3db589b90b68..e10c868b987f 100644 --- a/drivers/net/ethernet/sfc/mcdi_filters.c +++ b/drivers/net/ethernet/sfc/mcdi_filters.c @@ -459,7 +459,7 @@ static s32 efx_mcdi_filter_insert_locked(struct efx_nic *efx, replacing = true; priv_flags = efx_mcdi_filter_entry_flags(table, ins_index); } else { - saved_spec = kmalloc(sizeof(*spec), GFP_ATOMIC); + saved_spec = kmalloc_obj(*spec, GFP_ATOMIC); if (!saved_spec) { rc = -ENOMEM; goto out_unlock; @@ -1310,7 +1310,7 @@ int efx_mcdi_filter_table_probe(struct efx_nic *efx, bool multicast_chaining) if (efx->filter_state) /* already probed */ return 0; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return -ENOMEM; @@ -1586,7 +1586,7 @@ int efx_mcdi_filter_add_vlan(struct efx_nic *efx, u16 vid) return -EALREADY; } - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c index f5128db7c7e7..e574f91f624c 100644 --- a/drivers/net/ethernet/sfc/mcdi_mon.c +++ b/drivers/net/ethernet/sfc/mcdi_mon.c @@ -350,13 +350,12 @@ int efx_mcdi_mon_probe(struct efx_nic *efx) * value, min, max, crit, alarm and label for each sensor. */ n_attrs = 6 * n_sensors; - hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); + hwmon->attrs = kzalloc_objs(*hwmon->attrs, n_attrs); if (!hwmon->attrs) { rc = -ENOMEM; goto fail; } - hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *), - GFP_KERNEL); + hwmon->group.attrs = kzalloc_objs(struct attribute *, n_attrs + 1); if (!hwmon->group.attrs) { rc = -ENOMEM; goto fail; diff --git a/drivers/net/ethernet/sfc/mcdi_port_common.c b/drivers/net/ethernet/sfc/mcdi_port_common.c index dae684194ac8..8d3d5cdfbdfc 100644 --- a/drivers/net/ethernet/sfc/mcdi_port_common.c +++ b/drivers/net/ethernet/sfc/mcdi_port_common.c @@ -429,7 +429,7 @@ int efx_mcdi_phy_probe(struct efx_nic *efx) int rc; /* Initialise and populate phy_data */ - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + phy_data = kzalloc_obj(*phy_data); if (phy_data == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c index 4c7222bf26be..6ca9a75af01d 100644 --- a/drivers/net/ethernet/sfc/ptp.c +++ b/drivers/net/ethernet/sfc/ptp.c @@ -1263,7 +1263,7 @@ static int efx_ptp_insert_filter(struct efx_nic *efx, return 0; } - rxfilter = kzalloc(sizeof(*rxfilter), GFP_KERNEL); + rxfilter = kzalloc_obj(*rxfilter); if (!rxfilter) return -ENOMEM; @@ -1565,7 +1565,7 @@ int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) return 0; } - ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); + ptp = kzalloc_obj(struct efx_ptp_data); efx->ptp_data = ptp; if (!efx->ptp_data) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/rx_common.c b/drivers/net/ethernet/sfc/rx_common.c index 5306f4c44be4..fd0a1a8ac2a1 100644 --- a/drivers/net/ethernet/sfc/rx_common.c +++ b/drivers/net/ethernet/sfc/rx_common.c @@ -138,8 +138,7 @@ static void efx_init_rx_recycle_ring(struct efx_rx_queue *rx_queue) bufs_in_recycle_ring = efx_rx_recycle_ring_size(efx); page_ring_size = roundup_pow_of_two(bufs_in_recycle_ring / efx->rx_bufs_per_page); - rx_queue->page_ring = kcalloc(page_ring_size, - sizeof(*rx_queue->page_ring), GFP_KERNEL); + rx_queue->page_ring = kzalloc_objs(*rx_queue->page_ring, page_ring_size); if (!rx_queue->page_ring) rx_queue->page_ptr_mask = 0; else @@ -204,8 +203,7 @@ int efx_probe_rx_queue(struct efx_rx_queue *rx_queue) rx_queue->ptr_mask); /* Allocate RX buffers */ - rx_queue->buffer = kcalloc(entries, sizeof(*rx_queue->buffer), - GFP_KERNEL); + rx_queue->buffer = kzalloc_objs(*rx_queue->buffer, entries); if (!rx_queue->buffer) return -ENOMEM; @@ -709,7 +707,7 @@ struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx, return rule; } } - rule = kmalloc(sizeof(*rule), GFP_ATOMIC); + rule = kmalloc_obj(*rule, GFP_ATOMIC); *new = true; if (rule) { memcpy(&rule->spec, spec, sizeof(rule->spec)); diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 894fad0bb5ea..8ec76329237a 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -542,8 +542,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, /* Determine how many packets to send */ state->packet_count = efx->txq_entries / 3; state->packet_count = min(1 << (i << 2), state->packet_count); - state->skbs = kcalloc(state->packet_count, - sizeof(state->skbs[0]), GFP_KERNEL); + state->skbs = kzalloc_objs(state->skbs[0], state->packet_count); if (!state->skbs) return -ENOMEM; state->flush = false; @@ -628,7 +627,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, /* Set the port loopback_selftest member. From this point on * all received packets will be dropped. Mark the state as * "flushing" so all inflight packets are dropped */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return -ENOMEM; BUG_ON(efx->loopback_selftest); diff --git a/drivers/net/ethernet/sfc/siena/efx_channels.c b/drivers/net/ethernet/sfc/siena/efx_channels.c index fc075ab6b7b5..1fc343598771 100644 --- a/drivers/net/ethernet/sfc/siena/efx_channels.c +++ b/drivers/net/ethernet/sfc/siena/efx_channels.c @@ -536,7 +536,7 @@ static struct efx_channel *efx_alloc_channel(struct efx_nic *efx, int i) struct efx_channel *channel; int j; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return NULL; @@ -607,7 +607,7 @@ struct efx_channel *efx_copy_channel(const struct efx_channel *old_channel) struct efx_channel *channel; int j; - channel = kmalloc(sizeof(*channel), GFP_KERNEL); + channel = kmalloc_obj(*channel); if (!channel) return NULL; @@ -966,9 +966,8 @@ int efx_siena_set_channels(struct efx_nic *efx) EFX_WARN_ON_PARANOID(efx->xdp_tx_queues); /* Allocate array for XDP TX queue lookup. */ - efx->xdp_tx_queues = kcalloc(efx->xdp_tx_queue_count, - sizeof(*efx->xdp_tx_queues), - GFP_KERNEL); + efx->xdp_tx_queues = kzalloc_objs(*efx->xdp_tx_queues, + efx->xdp_tx_queue_count); if (!efx->xdp_tx_queues) return -ENOMEM; } diff --git a/drivers/net/ethernet/sfc/siena/efx_common.c b/drivers/net/ethernet/sfc/siena/efx_common.c index 35036cc902fe..f91e5f8c0b35 100644 --- a/drivers/net/ethernet/sfc/siena/efx_common.c +++ b/drivers/net/ethernet/sfc/siena/efx_common.c @@ -1023,8 +1023,8 @@ int efx_siena_init_struct(struct efx_nic *efx, mutex_init(&efx->rps_mutex); spin_lock_init(&efx->rps_hash_lock); /* Failure to allocate is not fatal, but may degrade ARFS performance */ - efx->rps_hash_table = kcalloc(EFX_ARFS_HASH_TABLE_SIZE, - sizeof(*efx->rps_hash_table), GFP_KERNEL); + efx->rps_hash_table = kzalloc_objs(*efx->rps_hash_table, + EFX_ARFS_HASH_TABLE_SIZE); #endif efx->mdio.dev = net_dev; INIT_WORK(&efx->mac_work, efx_mac_work); diff --git a/drivers/net/ethernet/sfc/siena/ethtool_common.c b/drivers/net/ethernet/sfc/siena/ethtool_common.c index c56e0b54d854..76cbce2b9592 100644 --- a/drivers/net/ethernet/sfc/siena/ethtool_common.c +++ b/drivers/net/ethernet/sfc/siena/ethtool_common.c @@ -355,7 +355,7 @@ void efx_siena_ethtool_self_test(struct net_device *net_dev, bool already_up; int rc = -ENOMEM; - efx_tests = kzalloc(sizeof(*efx_tests), GFP_KERNEL); + efx_tests = kzalloc_obj(*efx_tests); if (!efx_tests) goto fail; diff --git a/drivers/net/ethernet/sfc/siena/farch.c b/drivers/net/ethernet/sfc/siena/farch.c index 562a038e38a7..7613d7988894 100644 --- a/drivers/net/ethernet/sfc/siena/farch.c +++ b/drivers/net/ethernet/sfc/siena/farch.c @@ -2790,7 +2790,7 @@ int efx_farch_filter_table_probe(struct efx_nic *efx) struct efx_farch_filter_table *table; unsigned table_id; - state = kzalloc(sizeof(struct efx_farch_filter_state), GFP_KERNEL); + state = kzalloc_obj(struct efx_farch_filter_state); if (!state) return -ENOMEM; efx->filter_state = state; diff --git a/drivers/net/ethernet/sfc/siena/mcdi.c b/drivers/net/ethernet/sfc/siena/mcdi.c index c8f0fb43e285..4d0d6bd5d3d1 100644 --- a/drivers/net/ethernet/sfc/siena/mcdi.c +++ b/drivers/net/ethernet/sfc/siena/mcdi.c @@ -65,7 +65,7 @@ int efx_siena_mcdi_init(struct efx_nic *efx) bool already_attached; int rc = -ENOMEM; - efx->mcdi = kzalloc(sizeof(*efx->mcdi), GFP_KERNEL); + efx->mcdi = kzalloc_obj(*efx->mcdi); if (!efx->mcdi) goto fail; diff --git a/drivers/net/ethernet/sfc/siena/mcdi_mon.c b/drivers/net/ethernet/sfc/siena/mcdi_mon.c index 56a9c56ed9e3..0216a2a600a3 100644 --- a/drivers/net/ethernet/sfc/siena/mcdi_mon.c +++ b/drivers/net/ethernet/sfc/siena/mcdi_mon.c @@ -350,13 +350,12 @@ int efx_siena_mcdi_mon_probe(struct efx_nic *efx) * value, min, max, crit, alarm and label for each sensor. */ n_attrs = 6 * n_sensors; - hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); + hwmon->attrs = kzalloc_objs(*hwmon->attrs, n_attrs); if (!hwmon->attrs) { rc = -ENOMEM; goto fail; } - hwmon->group.attrs = kcalloc(n_attrs + 1, sizeof(struct attribute *), - GFP_KERNEL); + hwmon->group.attrs = kzalloc_objs(struct attribute *, n_attrs + 1); if (!hwmon->group.attrs) { rc = -ENOMEM; goto fail; diff --git a/drivers/net/ethernet/sfc/siena/mcdi_port_common.c b/drivers/net/ethernet/sfc/siena/mcdi_port_common.c index 067fe0f4393a..72d07a2ec553 100644 --- a/drivers/net/ethernet/sfc/siena/mcdi_port_common.c +++ b/drivers/net/ethernet/sfc/siena/mcdi_port_common.c @@ -430,7 +430,7 @@ int efx_siena_mcdi_phy_probe(struct efx_nic *efx) int rc; /* Initialise and populate phy_data */ - phy_data = kzalloc(sizeof(*phy_data), GFP_KERNEL); + phy_data = kzalloc_obj(*phy_data); if (phy_data == NULL) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/siena/ptp.c b/drivers/net/ethernet/sfc/siena/ptp.c index 062c77c92077..0b723a127364 100644 --- a/drivers/net/ethernet/sfc/siena/ptp.c +++ b/drivers/net/ethernet/sfc/siena/ptp.c @@ -1443,7 +1443,7 @@ static int efx_ptp_probe(struct efx_nic *efx, struct efx_channel *channel) int rc = 0; unsigned int pos; - ptp = kzalloc(sizeof(struct efx_ptp_data), GFP_KERNEL); + ptp = kzalloc_obj(struct efx_ptp_data); efx->ptp_data = ptp; if (!efx->ptp_data) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/siena/rx_common.c b/drivers/net/ethernet/sfc/siena/rx_common.c index 4ae09505e417..4ceb108fad48 100644 --- a/drivers/net/ethernet/sfc/siena/rx_common.c +++ b/drivers/net/ethernet/sfc/siena/rx_common.c @@ -141,8 +141,7 @@ static void efx_init_rx_recycle_ring(struct efx_rx_queue *rx_queue) bufs_in_recycle_ring = efx_rx_recycle_ring_size(efx); page_ring_size = roundup_pow_of_two(bufs_in_recycle_ring / efx->rx_bufs_per_page); - rx_queue->page_ring = kcalloc(page_ring_size, - sizeof(*rx_queue->page_ring), GFP_KERNEL); + rx_queue->page_ring = kzalloc_objs(*rx_queue->page_ring, page_ring_size); if (!rx_queue->page_ring) rx_queue->page_ptr_mask = 0; else @@ -207,8 +206,7 @@ int efx_siena_probe_rx_queue(struct efx_rx_queue *rx_queue) rx_queue->ptr_mask); /* Allocate RX buffers */ - rx_queue->buffer = kcalloc(entries, sizeof(*rx_queue->buffer), - GFP_KERNEL); + rx_queue->buffer = kzalloc_objs(*rx_queue->buffer, entries); if (!rx_queue->buffer) return -ENOMEM; @@ -696,7 +694,7 @@ static struct efx_arfs_rule *efx_rps_hash_add(struct efx_nic *efx, return rule; } } - rule = kmalloc(sizeof(*rule), GFP_ATOMIC); + rule = kmalloc_obj(*rule, GFP_ATOMIC); *new = true; if (rule) { memcpy(&rule->spec, spec, sizeof(rule->spec)); diff --git a/drivers/net/ethernet/sfc/siena/selftest.c b/drivers/net/ethernet/sfc/siena/selftest.c index 526da43d4b61..930643612df5 100644 --- a/drivers/net/ethernet/sfc/siena/selftest.c +++ b/drivers/net/ethernet/sfc/siena/selftest.c @@ -543,8 +543,7 @@ efx_test_loopback(struct efx_tx_queue *tx_queue, /* Determine how many packets to send */ state->packet_count = efx->txq_entries / 3; state->packet_count = min(1 << (i << 2), state->packet_count); - state->skbs = kcalloc(state->packet_count, - sizeof(state->skbs[0]), GFP_KERNEL); + state->skbs = kzalloc_objs(state->skbs[0], state->packet_count); if (!state->skbs) return -ENOMEM; state->flush = false; @@ -633,7 +632,7 @@ static int efx_test_loopbacks(struct efx_nic *efx, struct efx_self_tests *tests, /* Set the port loopback_selftest member. From this point on * all received packets will be dropped. Mark the state as * "flushing" so all inflight packets are dropped */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return -ENOMEM; BUG_ON(efx->loopback_selftest); diff --git a/drivers/net/ethernet/sfc/siena/siena.c b/drivers/net/ethernet/sfc/siena/siena.c index 49f0c8a1a90a..dbd1417f803f 100644 --- a/drivers/net/ethernet/sfc/siena/siena.c +++ b/drivers/net/ethernet/sfc/siena/siena.c @@ -266,7 +266,7 @@ static int siena_probe_nic(struct efx_nic *efx) int rc; /* Allocate storage for hardware specific data */ - nic_data = kzalloc(sizeof(struct siena_nic_data), GFP_KERNEL); + nic_data = kzalloc_obj(struct siena_nic_data); if (!nic_data) return -ENOMEM; nic_data->efx = efx; @@ -923,7 +923,7 @@ static int siena_mtd_probe(struct efx_nic *efx) if (rc) return rc; - parts = kcalloc(hweight32(nvram_types), sizeof(*parts), GFP_KERNEL); + parts = kzalloc_objs(*parts, hweight32(nvram_types)); if (!parts) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/siena/siena_sriov.c b/drivers/net/ethernet/sfc/siena/siena_sriov.c index 8353c15dc233..d9789330f8dc 100644 --- a/drivers/net/ethernet/sfc/siena/siena_sriov.c +++ b/drivers/net/ethernet/sfc/siena/siena_sriov.c @@ -1123,7 +1123,7 @@ static void efx_siena_sriov_peer_work(struct work_struct *data) ++peer_count; if (--peer_space == 0) { if (list_empty(&pages)) { - epp = kmalloc(sizeof(*epp), GFP_KERNEL); + epp = kmalloc_obj(*epp); if (!epp) break; epp->ptr = dma_alloc_coherent( @@ -1197,8 +1197,7 @@ static int efx_siena_sriov_vf_alloc(struct efx_nic *efx) struct siena_vf *vf; struct siena_nic_data *nic_data = efx->nic_data; - nic_data->vf = kcalloc(efx->vf_count, sizeof(*nic_data->vf), - GFP_KERNEL); + nic_data->vf = kzalloc_objs(*nic_data->vf, efx->vf_count); if (!nic_data->vf) return -ENOMEM; diff --git a/drivers/net/ethernet/sfc/siena/tx_common.c b/drivers/net/ethernet/sfc/siena/tx_common.c index 71f9b5ec5ae4..bcdf8c561579 100644 --- a/drivers/net/ethernet/sfc/siena/tx_common.c +++ b/drivers/net/ethernet/sfc/siena/tx_common.c @@ -36,13 +36,12 @@ int efx_siena_probe_tx_queue(struct efx_tx_queue *tx_queue) tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask); /* Allocate software ring */ - tx_queue->buffer = kcalloc(entries, sizeof(*tx_queue->buffer), - GFP_KERNEL); + tx_queue->buffer = kzalloc_objs(*tx_queue->buffer, entries); if (!tx_queue->buffer) return -ENOMEM; - tx_queue->cb_page = kcalloc(efx_tx_cb_page_count(tx_queue), - sizeof(tx_queue->cb_page[0]), GFP_KERNEL); + tx_queue->cb_page = kzalloc_objs(tx_queue->cb_page[0], + efx_tx_cb_page_count(tx_queue)); if (!tx_queue->cb_page) { rc = -ENOMEM; goto fail1; diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c index fa94aa3cd5fe..25341acfb472 100644 --- a/drivers/net/ethernet/sfc/tc.c +++ b/drivers/net/ethernet/sfc/tc.c @@ -126,7 +126,7 @@ static struct efx_tc_mac_pedit_action *efx_tc_flower_get_mac(struct efx_nic *efx struct efx_tc_mac_pedit_action *ped, *old; int rc; - ped = kzalloc(sizeof(*ped), GFP_USER); + ped = kzalloc_obj(*ped, GFP_USER); if (!ped) return ERR_PTR(-ENOMEM); memcpy(ped->h_addr, h_addr, ETH_ALEN); @@ -571,7 +571,7 @@ static int efx_tc_flower_record_encap_match(struct efx_nic *efx, if (rc) goto fail_pseudo; - encap = kzalloc(sizeof(*encap), GFP_USER); + encap = kzalloc_obj(*encap, GFP_USER); if (!encap) { rc = -ENOMEM; goto fail_pseudo; @@ -694,7 +694,7 @@ static struct efx_tc_recirc_id *efx_tc_get_recirc_id(struct efx_nic *efx, struct efx_tc_recirc_id *rid, *old; int rc; - rid = kzalloc(sizeof(*rid), GFP_USER); + rid = kzalloc_obj(*rid, GFP_USER); if (!rid) return ERR_PTR(-ENOMEM); rid->chain_index = chain_index; @@ -1505,7 +1505,7 @@ static int efx_tc_flower_replace_foreign_lhs_ar(struct efx_nic *efx, if (rc) goto release_encap_match; - rule = kzalloc(sizeof(*rule), GFP_USER); + rule = kzalloc_obj(*rule, GFP_USER); if (!rule) { rc = -ENOMEM; goto release_encap_match; @@ -1618,7 +1618,7 @@ static int efx_tc_flower_replace_foreign_lhs(struct efx_nic *efx, if (rc) goto release_encap_match; - rule = kzalloc(sizeof(*rule), GFP_USER); + rule = kzalloc_obj(*rule, GFP_USER); if (!rule) { rc = -ENOMEM; goto release_encap_match; @@ -1794,7 +1794,7 @@ static int efx_tc_flower_replace_foreign(struct efx_nic *efx, goto release; } - rule = kzalloc(sizeof(*rule), GFP_USER); + rule = kzalloc_obj(*rule, GFP_USER); if (!rule) { rc = -ENOMEM; goto release; @@ -1815,7 +1815,7 @@ static int efx_tc_flower_replace_foreign(struct efx_nic *efx, goto release; } - act = kzalloc(sizeof(*act), GFP_USER); + act = kzalloc_obj(*act, GFP_USER); if (!act) { rc = -ENOMEM; goto release; @@ -1901,7 +1901,7 @@ static int efx_tc_flower_replace_foreign(struct efx_nic *efx, if (fa->id == FLOW_ACTION_REDIRECT) break; /* end of the line */ /* Mirror, so continue on with saved act */ - act = kzalloc(sizeof(*act), GFP_USER); + act = kzalloc_obj(*act, GFP_USER); if (!act) { rc = -ENOMEM; goto release; @@ -2016,7 +2016,7 @@ static int efx_tc_flower_replace_lhs(struct efx_nic *efx, if (rc) return rc; - rule = kzalloc(sizeof(*rule), GFP_USER); + rule = kzalloc_obj(*rule, GFP_USER); if (!rule) return -ENOMEM; rule->cookie = tc->cookie; @@ -2177,7 +2177,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx, if (rc) goto release; - rule = kzalloc(sizeof(*rule), GFP_USER); + rule = kzalloc_obj(*rule, GFP_USER); if (!rule) { rc = -ENOMEM; goto release; @@ -2199,7 +2199,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx, } /* Parse actions */ - act = kzalloc(sizeof(*act), GFP_USER); + act = kzalloc_obj(*act, GFP_USER); if (!act) { rc = -ENOMEM; goto release; @@ -2340,7 +2340,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx, break; /* end of the line */ /* Mirror, so continue on with saved act */ save.count = NULL; - act = kzalloc(sizeof(*act), GFP_USER); + act = kzalloc_obj(*act, GFP_USER); if (!act) { rc = -ENOMEM; goto release; @@ -2380,7 +2380,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx, break; /* end of the line */ /* Mirror, so continue on with saved act */ save.count = NULL; - act = kzalloc(sizeof(*act), GFP_USER); + act = kzalloc_obj(*act, GFP_USER); if (!act) { rc = -ENOMEM; goto release; @@ -2672,7 +2672,7 @@ static int efx_tc_configure_default_rule(struct efx_nic *efx, u32 ing_port, match->value.ingress_port = ing_port; match->mask.ingress_port = ~0; - act = kzalloc(sizeof(*act), GFP_KERNEL); + act = kzalloc_obj(*act); if (!act) return -ENOMEM; act->deliver = 1; @@ -2745,7 +2745,7 @@ static int efx_tc_configure_fallback_acts(struct efx_nic *efx, u32 eg_port, struct efx_tc_action_set *act; int rc; - act = kzalloc(sizeof(*act), GFP_KERNEL); + act = kzalloc_obj(*act); if (!act) return -ENOMEM; act->deliver = 1; @@ -2988,10 +2988,10 @@ int efx_init_struct_tc(struct efx_nic *efx) if (efx->type->is_vf) return 0; - efx->tc = kzalloc(sizeof(*efx->tc), GFP_KERNEL); + efx->tc = kzalloc_obj(*efx->tc); if (!efx->tc) return -ENOMEM; - efx->tc->caps = kzalloc(sizeof(struct mae_caps), GFP_KERNEL); + efx->tc->caps = kzalloc_obj(struct mae_caps); if (!efx->tc->caps) { rc = -ENOMEM; goto fail_alloc_caps; diff --git a/drivers/net/ethernet/sfc/tc_bindings.c b/drivers/net/ethernet/sfc/tc_bindings.c index 1b79c535c54e..5c02aa738239 100644 --- a/drivers/net/ethernet/sfc/tc_bindings.c +++ b/drivers/net/ethernet/sfc/tc_bindings.c @@ -59,7 +59,7 @@ static struct efx_tc_block_binding *efx_tc_create_binding( struct efx_nic *efx, struct efx_rep *efv, struct net_device *otherdev, struct flow_block *block) { - struct efx_tc_block_binding *binding = kmalloc(sizeof(*binding), GFP_KERNEL); + struct efx_tc_block_binding *binding = kmalloc_obj(*binding); if (!binding) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/sfc/tc_conntrack.c b/drivers/net/ethernet/sfc/tc_conntrack.c index c0603f54cec3..77ce2eca43f2 100644 --- a/drivers/net/ethernet/sfc/tc_conntrack.c +++ b/drivers/net/ethernet/sfc/tc_conntrack.c @@ -365,7 +365,7 @@ static int efx_tc_ct_replace(struct efx_tc_ct_zone *ct_zone, if (WARN_ON(!efx->tc->up)) return -ENETDOWN; - conn = kzalloc(sizeof(*conn), GFP_USER); + conn = kzalloc_obj(*conn, GFP_USER); if (!conn) return -ENOMEM; conn->cookie = tc->cookie; @@ -562,7 +562,7 @@ struct efx_tc_ct_zone *efx_tc_ct_register_zone(struct efx_nic *efx, u16 zone, struct efx_tc_ct_zone *ct_zone, *old; int rc; - ct_zone = kzalloc(sizeof(*ct_zone), GFP_USER); + ct_zone = kzalloc_obj(*ct_zone, GFP_USER); if (!ct_zone) return ERR_PTR(-ENOMEM); ct_zone->zone = zone; diff --git a/drivers/net/ethernet/sfc/tc_counters.c b/drivers/net/ethernet/sfc/tc_counters.c index a421b0123506..d168282f30bf 100644 --- a/drivers/net/ethernet/sfc/tc_counters.c +++ b/drivers/net/ethernet/sfc/tc_counters.c @@ -135,7 +135,7 @@ struct efx_tc_counter *efx_tc_flower_allocate_counter(struct efx_nic *efx, struct efx_tc_counter *cnt; int rc, rc2; - cnt = kzalloc(sizeof(*cnt), GFP_USER); + cnt = kzalloc_obj(*cnt, GFP_USER); if (!cnt) return ERR_PTR(-ENOMEM); @@ -226,7 +226,7 @@ struct efx_tc_counter_index *efx_tc_flower_get_counter_index( struct efx_tc_counter_index *ctr, *old; struct efx_tc_counter *cnt; - ctr = kzalloc(sizeof(*ctr), GFP_USER); + ctr = kzalloc_obj(*ctr, GFP_USER); if (!ctr) return ERR_PTR(-ENOMEM); ctr->cookie = cookie; diff --git a/drivers/net/ethernet/sfc/tc_encap_actions.c b/drivers/net/ethernet/sfc/tc_encap_actions.c index eef06e48185d..da35705cc5e1 100644 --- a/drivers/net/ethernet/sfc/tc_encap_actions.c +++ b/drivers/net/ethernet/sfc/tc_encap_actions.c @@ -120,7 +120,7 @@ static int efx_bind_neigh(struct efx_nic *efx, return -EOPNOTSUPP; } - neigh = kzalloc(sizeof(*neigh), GFP_KERNEL_ACCOUNT); + neigh = kzalloc_obj(*neigh, GFP_KERNEL_ACCOUNT); if (!neigh) return -ENOMEM; neigh->net = get_net_track(net, &neigh->ns_tracker, GFP_KERNEL_ACCOUNT); @@ -632,7 +632,7 @@ struct efx_tc_encap_action *efx_tc_flower_create_encap_md( info->mode); return ERR_PTR(-EOPNOTSUPP); } - encap = kzalloc(sizeof(*encap), GFP_KERNEL_ACCOUNT); + encap = kzalloc_obj(*encap, GFP_KERNEL_ACCOUNT); if (!encap) return ERR_PTR(-ENOMEM); encap->type = type; diff --git a/drivers/net/ethernet/sfc/tx_common.c b/drivers/net/ethernet/sfc/tx_common.c index a22a0d634ffc..71c96499f602 100644 --- a/drivers/net/ethernet/sfc/tx_common.c +++ b/drivers/net/ethernet/sfc/tx_common.c @@ -36,13 +36,12 @@ int efx_probe_tx_queue(struct efx_tx_queue *tx_queue) tx_queue->queue, efx->txq_entries, tx_queue->ptr_mask); /* Allocate software ring */ - tx_queue->buffer = kcalloc(entries, sizeof(*tx_queue->buffer), - GFP_KERNEL); + tx_queue->buffer = kzalloc_objs(*tx_queue->buffer, entries); if (!tx_queue->buffer) return -ENOMEM; - tx_queue->cb_page = kcalloc(efx_tx_cb_page_count(tx_queue), - sizeof(tx_queue->cb_page[0]), GFP_KERNEL); + tx_queue->cb_page = kzalloc_objs(tx_queue->cb_page[0], + efx_tx_cb_page_count(tx_queue)); if (!tx_queue->cb_page) { rc = -ENOMEM; goto fail1; diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 15e46e6ac262..12ddea514910 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c @@ -1407,7 +1407,7 @@ static int sis190_mii_probe(struct net_device *dev) if (status == 0xffff || status == 0x0000) continue; - phy = kmalloc(sizeof(*phy), GFP_KERNEL); + phy = kmalloc_obj(*phy); if (!phy) { sis190_free_phy(&tp->first_phy); rc = -ENOMEM; diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index d85ac8cbeb00..1349ef50cd26 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -619,7 +619,7 @@ static int sis900_mii_probe(struct net_device *net_dev) continue; } - if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) { + if ((mii_phy = kmalloc_obj(struct mii_phy)) == NULL) { mii_phy = sis_priv->first_mii; while (mii_phy) { struct mii_phy *phy; diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index f30d4b17c7fb..0c97211b6254 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -1179,9 +1179,7 @@ static int smsc9420_alloc_tx_ring(struct smsc9420_pdata *pd) BUG_ON(!pd->tx_ring); - pd->tx_buffers = kmalloc_array(TX_RING_SIZE, - sizeof(struct smsc9420_ring_info), - GFP_KERNEL); + pd->tx_buffers = kmalloc_objs(struct smsc9420_ring_info, TX_RING_SIZE); if (!pd->tx_buffers) return -ENOMEM; @@ -1212,9 +1210,7 @@ static int smsc9420_alloc_rx_ring(struct smsc9420_pdata *pd) BUG_ON(!pd->rx_ring); - pd->rx_buffers = kmalloc_array(RX_RING_SIZE, - sizeof(struct smsc9420_ring_info), - GFP_KERNEL); + pd->rx_buffers = kmalloc_objs(struct smsc9420_ring_info, RX_RING_SIZE); if (pd->rx_buffers == NULL) goto out; diff --git a/drivers/net/ethernet/socionext/netsec.c b/drivers/net/ethernet/socionext/netsec.c index ee890de69ffe..d14a6584473c 100644 --- a/drivers/net/ethernet/socionext/netsec.c +++ b/drivers/net/ethernet/socionext/netsec.c @@ -1263,7 +1263,7 @@ static int netsec_alloc_dring(struct netsec_priv *priv, enum ring_id id) if (!dring->vaddr) goto err; - dring->desc = kcalloc(DESC_NUM, sizeof(*dring->desc), GFP_KERNEL); + dring->desc = kzalloc_objs(*dring->desc, DESC_NUM); if (!dring->desc) goto err; diff --git a/drivers/net/ethernet/socionext/sni_ave.c b/drivers/net/ethernet/socionext/sni_ave.c index 4700998c4837..84cb2f4f0648 100644 --- a/drivers/net/ethernet/socionext/sni_ave.c +++ b/drivers/net/ethernet/socionext/sni_ave.c @@ -1273,15 +1273,13 @@ static int ave_open(struct net_device *ndev) if (ret) return ret; - priv->tx.desc = kcalloc(priv->tx.ndesc, sizeof(*priv->tx.desc), - GFP_KERNEL); + priv->tx.desc = kzalloc_objs(*priv->tx.desc, priv->tx.ndesc); if (!priv->tx.desc) { ret = -ENOMEM; goto out_free_irq; } - priv->rx.desc = kcalloc(priv->rx.ndesc, sizeof(*priv->rx.desc), - GFP_KERNEL); + priv->rx.desc = kzalloc_objs(*priv->rx.desc, priv->rx.ndesc); if (!priv->rx.desc) { kfree(priv->tx.desc); ret = -ENOMEM; diff --git a/drivers/net/ethernet/spacemit/k1_emac.c b/drivers/net/ethernet/spacemit/k1_emac.c index dab0772c5b9d..15d43e4a748b 100644 --- a/drivers/net/ethernet/spacemit/k1_emac.c +++ b/drivers/net/ethernet/spacemit/k1_emac.c @@ -391,9 +391,8 @@ static int emac_alloc_tx_resources(struct emac_priv *priv) struct emac_desc_ring *tx_ring = &priv->tx_ring; struct platform_device *pdev = priv->pdev; - tx_ring->tx_desc_buf = kcalloc(tx_ring->total_cnt, - sizeof(*tx_ring->tx_desc_buf), - GFP_KERNEL); + tx_ring->tx_desc_buf = kzalloc_objs(*tx_ring->tx_desc_buf, + tx_ring->total_cnt); if (!tx_ring->tx_desc_buf) return -ENOMEM; @@ -420,9 +419,8 @@ static int emac_alloc_rx_resources(struct emac_priv *priv) struct emac_desc_ring *rx_ring = &priv->rx_ring; struct platform_device *pdev = priv->pdev; - rx_ring->rx_desc_buf = kcalloc(rx_ring->total_cnt, - sizeof(*rx_ring->rx_desc_buf), - GFP_KERNEL); + rx_ring->rx_desc_buf = kzalloc_objs(*rx_ring->rx_desc_buf, + rx_ring->total_cnt); if (!rx_ring->rx_desc_buf) return -ENOMEM; @@ -567,7 +565,9 @@ static void emac_alloc_rx_desc_buffers(struct emac_priv *priv) DMA_FROM_DEVICE); if (dma_mapping_error(&priv->pdev->dev, rx_buf->dma_addr)) { dev_err_ratelimited(&ndev->dev, "Mapping skb failed\n"); - goto err_free_skb; + dev_kfree_skb_any(skb); + rx_buf->skb = NULL; + break; } rx_desc_addr = &((struct emac_desc *)rx_ring->desc_addr)[i]; @@ -592,10 +592,6 @@ static void emac_alloc_rx_desc_buffers(struct emac_priv *priv) rx_ring->head = i; return; - -err_free_skb: - dev_kfree_skb_any(skb); - rx_buf->skb = NULL; } /* Returns number of packets received */ @@ -737,7 +733,7 @@ static void emac_tx_mem_map(struct emac_priv *priv, struct sk_buff *skb) struct emac_desc tx_desc, *tx_desc_addr; struct device *dev = &priv->pdev->dev; struct emac_tx_desc_buffer *tx_buf; - u32 head, old_head, frag_num, f; + u32 head, old_head, frag_num, f, i; bool buf_idx; frag_num = skb_shinfo(skb)->nr_frags; @@ -805,6 +801,15 @@ static void emac_tx_mem_map(struct emac_priv *priv, struct sk_buff *skb) err_free_skb: dev_dstats_tx_dropped(priv->ndev); + + i = old_head; + while (i != head) { + emac_free_tx_buf(priv, i); + + if (++i == tx_ring->total_cnt) + i = 0; + } + dev_kfree_skb_any(skb); } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 51c96a738151..33667a26708c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -323,6 +323,7 @@ struct stmmac_priv { void __iomem *ptpaddr; void __iomem *estaddr; unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)]; + unsigned int num_double_vlans; int sfty_irq; int sfty_ce_irq; int sfty_ue_irq; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index c63099a77cc0..6827c99bde8c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -156,6 +156,7 @@ static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue); static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue); static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode, u32 rxmode, u32 chan); +static int stmmac_vlan_restore(struct stmmac_priv *priv); #ifdef CONFIG_DEBUG_FS static const struct net_device_ops stmmac_netdev_ops; @@ -853,6 +854,7 @@ static int stmmac_init_timestamping(struct stmmac_priv *priv) netdev_info(priv->dev, "IEEE 1588-2008 Advanced Timestamp supported\n"); + memset(&priv->tstamp_config, 0, sizeof(priv->tstamp_config)); priv->hwts_tx_en = 0; priv->hwts_rx_en = 0; @@ -2212,9 +2214,7 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, return ret; } - rx_q->buf_pool = kcalloc(dma_conf->dma_rx_size, - sizeof(*rx_q->buf_pool), - GFP_KERNEL); + rx_q->buf_pool = kzalloc_objs(*rx_q->buf_pool, dma_conf->dma_rx_size); if (!rx_q->buf_pool) return -ENOMEM; @@ -2297,15 +2297,12 @@ static int __alloc_dma_tx_desc_resources(struct stmmac_priv *priv, tx_q->queue_index = queue; tx_q->priv_data = priv; - tx_q->tx_skbuff_dma = kcalloc(dma_conf->dma_tx_size, - sizeof(*tx_q->tx_skbuff_dma), - GFP_KERNEL); + tx_q->tx_skbuff_dma = kzalloc_objs(*tx_q->tx_skbuff_dma, + dma_conf->dma_tx_size); if (!tx_q->tx_skbuff_dma) return -ENOMEM; - tx_q->tx_skbuff = kcalloc(dma_conf->dma_tx_size, - sizeof(struct sk_buff *), - GFP_KERNEL); + tx_q->tx_skbuff = kzalloc_objs(struct sk_buff *, dma_conf->dma_tx_size); if (!tx_q->tx_skbuff) return -ENOMEM; @@ -4016,7 +4013,7 @@ stmmac_setup_dma_desc(struct stmmac_priv *priv, unsigned int mtu) struct stmmac_dma_conf *dma_conf; int chan, bfsize, ret; - dma_conf = kzalloc(sizeof(*dma_conf), GFP_KERNEL); + dma_conf = kzalloc_obj(*dma_conf); if (!dma_conf) { netdev_err(priv->dev, "%s: DMA conf allocation failed\n", __func__); @@ -4111,6 +4108,8 @@ static int __stmmac_open(struct net_device *dev, phylink_start(priv->phylink); + stmmac_vlan_restore(priv); + ret = stmmac_request_irq(dev); if (ret) goto irq_error; @@ -5040,13 +5039,27 @@ static unsigned int stmmac_rx_buf2_len(struct stmmac_priv *priv, if (!priv->sph_active) return 0; - /* Not last descriptor */ - if (status & rx_not_ls) + /* For GMAC4, when split header is enabled, in some rare cases, the + * hardware does not fill buf2 of the first descriptor with payload. + * Thus we cannot assume buf2 is always fully filled if it is not + * the last descriptor. Otherwise, the length of buf2 of the second + * descriptor will be calculated wrong and cause an oops. + * + * If this is the last descriptor, 'plen' is the length of the + * received packet that was transferred to system memory. + * Otherwise, it is the accumulated number of bytes that have been + * transferred for the current packet. + * + * Thus 'plen - len' always gives the correct length of buf2. + */ + + /* Not GMAC4 and not last descriptor */ + if (priv->plat->core_type != DWMAC_CORE_GMAC4 && (status & rx_not_ls)) return priv->dma_conf.dma_buf_sz; + /* GMAC4 or last descriptor */ plen = stmmac_get_rx_frame_len(priv, p, coe); - /* Last descriptor */ return plen - len; } @@ -6756,6 +6769,9 @@ static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double) hash = 0; } + if (!netif_running(priv->dev)) + return 0; + return stmmac_update_vlan_hash(priv, priv->hw, hash, pmatch, is_double); } @@ -6765,6 +6781,7 @@ static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double) static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct stmmac_priv *priv = netdev_priv(ndev); + unsigned int num_double_vlans; bool is_double = false; int ret; @@ -6776,7 +6793,8 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid is_double = true; set_bit(vid, priv->active_vlans); - ret = stmmac_vlan_update(priv, is_double); + num_double_vlans = priv->num_double_vlans + is_double; + ret = stmmac_vlan_update(priv, num_double_vlans); if (ret) { clear_bit(vid, priv->active_vlans); goto err_pm_put; @@ -6784,9 +6802,15 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid if (priv->hw->num_vlan) { ret = stmmac_add_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid); - if (ret) + if (ret) { + clear_bit(vid, priv->active_vlans); + stmmac_vlan_update(priv, priv->num_double_vlans); goto err_pm_put; + } } + + priv->num_double_vlans = num_double_vlans; + err_pm_put: pm_runtime_put(priv->device); @@ -6799,6 +6823,7 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct stmmac_priv *priv = netdev_priv(ndev); + unsigned int num_double_vlans; bool is_double = false; int ret; @@ -6810,14 +6835,23 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi is_double = true; clear_bit(vid, priv->active_vlans); + num_double_vlans = priv->num_double_vlans - is_double; + ret = stmmac_vlan_update(priv, num_double_vlans); + if (ret) { + set_bit(vid, priv->active_vlans); + goto del_vlan_error; + } if (priv->hw->num_vlan) { ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid); - if (ret) + if (ret) { + set_bit(vid, priv->active_vlans); + stmmac_vlan_update(priv, priv->num_double_vlans); goto del_vlan_error; + } } - ret = stmmac_vlan_update(priv, is_double); + priv->num_double_vlans = num_double_vlans; del_vlan_error: pm_runtime_put(priv->device); @@ -6825,6 +6859,23 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi return ret; } +static int stmmac_vlan_restore(struct stmmac_priv *priv) +{ + int ret; + + if (!(priv->dev->features & NETIF_F_VLAN_FEATURES)) + return 0; + + if (priv->hw->num_vlan) + stmmac_restore_hw_vlan_rx_fltr(priv, priv->dev, priv->hw); + + ret = stmmac_vlan_update(priv, priv->num_double_vlans); + if (ret) + netdev_err(priv->dev, "Failed to restore VLANs\n"); + + return ret; +} + static int stmmac_bpf(struct net_device *dev, struct netdev_bpf *bpf) { struct stmmac_priv *priv = netdev_priv(dev); @@ -8249,10 +8300,10 @@ int stmmac_resume(struct device *dev) stmmac_init_coalesce(priv); phylink_rx_clk_stop_block(priv->phylink); stmmac_set_rx_mode(ndev); - - stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw); phylink_rx_clk_stop_unblock(priv->phylink); + stmmac_vlan_restore(priv); + stmmac_enable_all_queues(priv); stmmac_enable_all_dma_irq(priv); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c index 08b60b7d5fd6..a0c75886587c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_selftests.c @@ -324,7 +324,7 @@ static int __stmmac_test_loopback(struct stmmac_priv *priv, struct sk_buff *skb = NULL; int ret = 0; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; @@ -434,11 +434,11 @@ static int stmmac_test_eee(struct stmmac_priv *priv) if (!priv->dma_cap.eee || !priv->eee_active) return -EOPNOTSUPP; - initial = kzalloc(sizeof(*initial), GFP_KERNEL); + initial = kzalloc_obj(*initial); if (!initial) return -ENOMEM; - final = kzalloc(sizeof(*final), GFP_KERNEL); + final = kzalloc_obj(*final); if (!final) { ret = -ENOMEM; goto out_free_initial; @@ -744,7 +744,7 @@ static int stmmac_test_flowctrl(struct stmmac_priv *priv) if (!phydev || (!phydev->pause && !phydev->asym_pause)) return -EOPNOTSUPP; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; @@ -898,7 +898,7 @@ static int __stmmac_test_vlanfilt(struct stmmac_priv *priv) struct sk_buff *skb = NULL; int ret = 0, i; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; @@ -991,7 +991,7 @@ static int __stmmac_test_dvlanfilt(struct stmmac_priv *priv) struct sk_buff *skb = NULL; int ret = 0, i; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; @@ -1095,23 +1095,23 @@ static int stmmac_test_rxp(struct stmmac_priv *priv) if (!priv->dma_cap.frpsel) return -EOPNOTSUPP; - sel = kzalloc(struct_size(sel, keys, nk), GFP_KERNEL); + sel = kzalloc_flex(*sel, keys, nk); if (!sel) return -ENOMEM; - exts = kzalloc(sizeof(*exts), GFP_KERNEL); + exts = kzalloc_obj(*exts); if (!exts) { ret = -ENOMEM; goto cleanup_sel; } - actions = kcalloc(nk, sizeof(*actions), GFP_KERNEL); + actions = kzalloc_objs(*actions, nk); if (!actions) { ret = -ENOMEM; goto cleanup_exts; } - gact = kcalloc(nk, sizeof(*gact), GFP_KERNEL); + gact = kzalloc_objs(*gact, nk); if (!gact) { ret = -ENOMEM; goto cleanup_actions; @@ -1266,7 +1266,7 @@ static int stmmac_test_vlanoff_common(struct stmmac_priv *priv, bool svlan) if (!priv->dma_cap.vlins) return -EOPNOTSUPP; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; @@ -1349,7 +1349,7 @@ static int __stmmac_test_l3filt(struct stmmac_priv *priv, u32 dst, u32 src, priv->plat->rx_queues_to_use); } - dissector = kzalloc(sizeof(*dissector), GFP_KERNEL); + dissector = kzalloc_obj(*dissector); if (!dissector) { ret = -ENOMEM; goto cleanup_rss; @@ -1358,7 +1358,7 @@ static int __stmmac_test_l3filt(struct stmmac_priv *priv, u32 dst, u32 src, dissector->used_keys |= (1ULL << FLOW_DISSECTOR_KEY_IPV4_ADDRS); dissector->offset[FLOW_DISSECTOR_KEY_IPV4_ADDRS] = 0; - cls = kzalloc(sizeof(*cls), GFP_KERNEL); + cls = kzalloc_obj(*cls); if (!cls) { ret = -ENOMEM; goto cleanup_dissector; @@ -1368,7 +1368,7 @@ static int __stmmac_test_l3filt(struct stmmac_priv *priv, u32 dst, u32 src, cls->command = FLOW_CLS_REPLACE; cls->cookie = dummy_cookie; - rule = kzalloc(struct_size(rule, action.entries, 1), GFP_KERNEL); + rule = kzalloc_flex(*rule, action.entries, 1); if (!rule) { ret = -ENOMEM; goto cleanup_cls; @@ -1475,7 +1475,7 @@ static int __stmmac_test_l4filt(struct stmmac_priv *priv, u32 dst, u32 src, priv->plat->rx_queues_to_use); } - dissector = kzalloc(sizeof(*dissector), GFP_KERNEL); + dissector = kzalloc_obj(*dissector); if (!dissector) { ret = -ENOMEM; goto cleanup_rss; @@ -1486,7 +1486,7 @@ static int __stmmac_test_l4filt(struct stmmac_priv *priv, u32 dst, u32 src, dissector->offset[FLOW_DISSECTOR_KEY_BASIC] = 0; dissector->offset[FLOW_DISSECTOR_KEY_PORTS] = offsetof(typeof(keys), key); - cls = kzalloc(sizeof(*cls), GFP_KERNEL); + cls = kzalloc_obj(*cls); if (!cls) { ret = -ENOMEM; goto cleanup_dissector; @@ -1496,7 +1496,7 @@ static int __stmmac_test_l4filt(struct stmmac_priv *priv, u32 dst, u32 src, cls->command = FLOW_CLS_REPLACE; cls->cookie = dummy_cookie; - rule = kzalloc(struct_size(rule, action.entries, 1), GFP_KERNEL); + rule = kzalloc_flex(*rule, action.entries, 1); if (!rule) { ret = -ENOMEM; goto cleanup_cls; @@ -1628,7 +1628,7 @@ static int stmmac_test_arpoffload(struct stmmac_priv *priv) if (!priv->dma_cap.arpoffsel) return -EOPNOTSUPP; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c index b18404dd5a8b..e24efe3bfedb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c @@ -76,7 +76,9 @@ static int vlan_add_hw_rx_fltr(struct net_device *dev, } hw->vlan_filter[0] = vid; - vlan_write_single(dev, vid); + + if (netif_running(dev)) + vlan_write_single(dev, vid); return 0; } @@ -97,12 +99,15 @@ static int vlan_add_hw_rx_fltr(struct net_device *dev, return -EPERM; } - ret = vlan_write_filter(dev, hw, index, val); + if (netif_running(dev)) { + ret = vlan_write_filter(dev, hw, index, val); + if (ret) + return ret; + } - if (!ret) - hw->vlan_filter[index] = val; + hw->vlan_filter[index] = val; - return ret; + return 0; } static int vlan_del_hw_rx_fltr(struct net_device *dev, @@ -115,7 +120,9 @@ static int vlan_del_hw_rx_fltr(struct net_device *dev, if (hw->num_vlan == 1) { if ((hw->vlan_filter[0] & VLAN_TAG_VID) == vid) { hw->vlan_filter[0] = 0; - vlan_write_single(dev, 0); + + if (netif_running(dev)) + vlan_write_single(dev, 0); } return 0; } @@ -124,25 +131,23 @@ static int vlan_del_hw_rx_fltr(struct net_device *dev, for (i = 0; i < hw->num_vlan; i++) { if ((hw->vlan_filter[i] & VLAN_TAG_DATA_VEN) && ((hw->vlan_filter[i] & VLAN_TAG_DATA_VID) == vid)) { - ret = vlan_write_filter(dev, hw, i, 0); - if (!ret) - hw->vlan_filter[i] = 0; - else - return ret; + if (netif_running(dev)) { + ret = vlan_write_filter(dev, hw, i, 0); + if (ret) + return ret; + } + + hw->vlan_filter[i] = 0; } } - return ret; + return 0; } static void vlan_restore_hw_rx_fltr(struct net_device *dev, struct mac_device_info *hw) { - void __iomem *ioaddr = hw->pcsr; - u32 value; - u32 hash; - u32 val; int i; /* Single Rx VLAN Filter */ @@ -152,19 +157,8 @@ static void vlan_restore_hw_rx_fltr(struct net_device *dev, } /* Extended Rx VLAN Filter Enable */ - for (i = 0; i < hw->num_vlan; i++) { - if (hw->vlan_filter[i] & VLAN_TAG_DATA_VEN) { - val = hw->vlan_filter[i]; - vlan_write_filter(dev, hw, i, val); - } - } - - hash = readl(ioaddr + VLAN_HASH_TABLE); - if (hash & VLAN_VLHT) { - value = readl(ioaddr + VLAN_TAG); - value |= VLAN_VTHM; - writel(value, ioaddr + VLAN_TAG); - } + for (i = 0; i < hw->num_vlan; i++) + vlan_write_filter(dev, hw, i, hw->vlan_filter[i]); } static void vlan_update_hash(struct mac_device_info *hw, u32 hash, @@ -183,6 +177,10 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, value |= VLAN_EDVLP; value |= VLAN_ESVL; value |= VLAN_DOVLTC; + } else { + value &= ~VLAN_EDVLP; + value &= ~VLAN_ESVL; + value &= ~VLAN_DOVLTC; } writel(value, ioaddr + VLAN_TAG); @@ -193,6 +191,10 @@ static void vlan_update_hash(struct mac_device_info *hw, u32 hash, value |= VLAN_EDVLP; value |= VLAN_ESVL; value |= VLAN_DOVLTC; + } else { + value &= ~VLAN_EDVLP; + value &= ~VLAN_ESVL; + value &= ~VLAN_DOVLTC; } writel(value | perfect_match, ioaddr + VLAN_TAG); diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index acfb523214b9..fe00e7dd3fe4 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -465,7 +465,7 @@ static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags) { cas_page_t *page; - page = kmalloc(sizeof(cas_page_t), flags); + page = kmalloc_obj(cas_page_t, flags); if (!page) return NULL; diff --git a/drivers/net/ethernet/sun/ldmvsw.c b/drivers/net/ethernet/sun/ldmvsw.c index 6fc37ab27f7b..05689e62ca83 100644 --- a/drivers/net/ethernet/sun/ldmvsw.c +++ b/drivers/net/ethernet/sun/ldmvsw.c @@ -202,7 +202,7 @@ static struct vnet *vsw_get_vnet(struct mdesc_handle *hp, } if (!vp) { - vp = kzalloc(sizeof(*vp), GFP_KERNEL); + vp = kzalloc_obj(*vp); if (unlikely(!vp)) { mutex_unlock(&vnet_list_mutex); return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index f035e3bbbef8..88df15e6dd74 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -4341,8 +4341,7 @@ static int niu_alloc_rx_ring_info(struct niu *np, { BUILD_BUG_ON(sizeof(struct rxdma_mailbox) != 64); - rp->rxhash = kcalloc(MAX_RBR_RING_SIZE, sizeof(struct page *), - GFP_KERNEL); + rp->rxhash = kzalloc_objs(struct page *, MAX_RBR_RING_SIZE); if (!rp->rxhash) return -ENOMEM; @@ -4485,8 +4484,7 @@ static int niu_alloc_channels(struct niu *np) num_rx_rings = parent->rxchan_per_port[port]; num_tx_rings = parent->txchan_per_port[port]; - rx_rings = kcalloc(num_rx_rings, sizeof(struct rx_ring_info), - GFP_KERNEL); + rx_rings = kzalloc_objs(struct rx_ring_info, num_rx_rings); err = -ENOMEM; if (!rx_rings) goto out_err; @@ -4525,8 +4523,7 @@ static int niu_alloc_channels(struct niu *np) goto out_err; } - tx_rings = kcalloc(num_tx_rings, sizeof(struct tx_ring_info), - GFP_KERNEL); + tx_rings = kzalloc_objs(struct tx_ring_info, num_tx_rings); err = -ENOMEM; if (!tx_rings) goto out_err; @@ -9514,7 +9511,7 @@ static struct niu_parent *niu_new_parent(struct niu *np, goto fail_unregister; } - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) goto fail_unregister; diff --git a/drivers/net/ethernet/sun/sunhme.c b/drivers/net/ethernet/sun/sunhme.c index 666998082998..4c9d5d4dd8a0 100644 --- a/drivers/net/ethernet/sun/sunhme.c +++ b/drivers/net/ethernet/sun/sunhme.c @@ -2248,7 +2248,7 @@ static struct quattro *quattro_sbus_find(struct platform_device *child) if (qp) return qp; - qp = kzalloc(sizeof(*qp), GFP_KERNEL); + qp = kzalloc_obj(*qp); if (!qp) return NULL; @@ -2278,7 +2278,7 @@ static struct quattro *quattro_pci_find(struct pci_dev *pdev) return qp; } - qp = kmalloc(sizeof(struct quattro), GFP_KERNEL); + qp = kmalloc_obj(struct quattro); if (!qp) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ethernet/sun/sunqe.c b/drivers/net/ethernet/sun/sunqe.c index 2920341b14a0..acef22cb9134 100644 --- a/drivers/net/ethernet/sun/sunqe.c +++ b/drivers/net/ethernet/sun/sunqe.c @@ -771,7 +771,7 @@ static struct sunqec *get_qec(struct platform_device *child) qecp = platform_get_drvdata(op); if (!qecp) { - qecp = kzalloc(sizeof(struct sunqec), GFP_KERNEL); + qecp = kzalloc_obj(struct sunqec); if (qecp) { u32 ctrl; diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index a2a3e94da4b8..6d477401f179 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -436,7 +436,7 @@ static int vnet_port_probe(struct vio_dev *vdev, const struct vio_device_id *id) goto err_out_put_mdesc; } - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); err = -ENOMEM; if (!port) goto err_out_put_mdesc; diff --git a/drivers/net/ethernet/sun/sunvnet_common.c b/drivers/net/ethernet/sun/sunvnet_common.c index 0212853c9430..5cca95869052 100644 --- a/drivers/net/ethernet/sun/sunvnet_common.c +++ b/drivers/net/ethernet/sun/sunvnet_common.c @@ -1571,7 +1571,7 @@ static void __update_mc_list(struct vnet *vp, struct net_device *dev) } if (!m) { - m = kzalloc(sizeof(*m), GFP_ATOMIC); + m = kzalloc_obj(*m, GFP_ATOMIC); if (!m) continue; memcpy(m->addr, ha->addr, ETH_ALEN); diff --git a/drivers/net/ethernet/sunplus/spl2sw_desc.c b/drivers/net/ethernet/sunplus/spl2sw_desc.c index 3f0d9f78b37d..f6b42cda693a 100644 --- a/drivers/net/ethernet/sunplus/spl2sw_desc.c +++ b/drivers/net/ethernet/sunplus/spl2sw_desc.c @@ -129,8 +129,9 @@ int spl2sw_rx_descs_init(struct spl2sw_common *comm) u32 i, j; for (i = 0; i < RX_DESC_QUEUE_NUM; i++) { - comm->rx_skb_info[i] = kcalloc(comm->rx_desc_num[i], sizeof(*rx_skbinfo), - GFP_KERNEL | GFP_DMA); + comm->rx_skb_info[i] = kzalloc_objs(*rx_skbinfo, + comm->rx_desc_num[i], + GFP_KERNEL | GFP_DMA); if (!comm->rx_skb_info[i]) goto mem_alloc_fail; diff --git a/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c b/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c index 589797bad1f9..2a40257ab47c 100644 --- a/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c +++ b/drivers/net/ethernet/synopsys/dwc-xlgmac-desc.c @@ -140,9 +140,8 @@ static int xlgmac_init_ring(struct xlgmac_pdata *pdata, return -ENOMEM; /* Array of descriptor data */ - ring->desc_data_head = kcalloc(dma_desc_count, - sizeof(struct xlgmac_desc_data), - GFP_KERNEL); + ring->desc_data_head = kzalloc_objs(struct xlgmac_desc_data, + dma_desc_count); if (!ring->desc_data_head) return -ENOMEM; @@ -234,21 +233,18 @@ static int xlgmac_alloc_channels(struct xlgmac_pdata *pdata) int ret = -ENOMEM; unsigned int i; - channel_head = kcalloc(pdata->channel_count, - sizeof(struct xlgmac_channel), GFP_KERNEL); + channel_head = kzalloc_objs(struct xlgmac_channel, pdata->channel_count); if (!channel_head) return ret; netif_dbg(pdata, drv, pdata->netdev, "channel_head=%p\n", channel_head); - tx_ring = kcalloc(pdata->tx_ring_count, sizeof(struct xlgmac_ring), - GFP_KERNEL); + tx_ring = kzalloc_objs(struct xlgmac_ring, pdata->tx_ring_count); if (!tx_ring) goto err_tx_ring; - rx_ring = kcalloc(pdata->rx_ring_count, sizeof(struct xlgmac_ring), - GFP_KERNEL); + rx_ring = kzalloc_objs(struct xlgmac_ring, pdata->rx_ring_count); if (!rx_ring) goto err_rx_ring; diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.c b/drivers/net/ethernet/ti/am65-cpsw-nuss.c index 5924db6be3fe..265ce5479915 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.c +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.c @@ -391,7 +391,7 @@ static void am65_cpsw_nuss_ndo_slave_set_rx_mode(struct net_device *ndev) cpsw_ale_set_allmulti(common->ale, ndev->flags & IFF_ALLMULTI, port->port_id); - port_mask = ALE_PORT_HOST; + port_mask = BIT(port->port_id) | ALE_PORT_HOST; /* Clear all mcast from ALE */ cpsw_ale_flush_multicast(common->ale, port_mask, -1); @@ -1351,7 +1351,7 @@ static int am65_cpsw_nuss_rx_packets(struct am65_cpsw_rx_flow *flow, ndev_priv = netdev_priv(ndev); am65_cpsw_nuss_set_offload_fwd_mark(skb, ndev_priv->offload_fwd_mark); skb_put(skb, pkt_len); - if (port->rx_ts_enabled) + if (port->rx_ts_filter) am65_cpts_rx_timestamp(common->cpts, skb); skb_mark_for_recycle(skb); skb->protocol = eth_type_trans(skb, ndev); @@ -1811,11 +1811,14 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev, switch (cfg->rx_filter) { case HWTSTAMP_FILTER_NONE: - port->rx_ts_enabled = false; + port->rx_ts_filter = HWTSTAMP_FILTER_NONE; break; case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: + port->rx_ts_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT; + break; case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: @@ -1825,8 +1828,8 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev, case HWTSTAMP_FILTER_PTP_V2_EVENT: case HWTSTAMP_FILTER_PTP_V2_SYNC: case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: - port->rx_ts_enabled = true; - cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT | HWTSTAMP_FILTER_PTP_V1_L4_EVENT; + port->rx_ts_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; + cfg->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT; break; case HWTSTAMP_FILTER_ALL: case HWTSTAMP_FILTER_SOME: @@ -1863,7 +1866,7 @@ static int am65_cpsw_nuss_hwtstamp_set(struct net_device *ndev, ts_ctrl |= AM65_CPSW_TS_TX_ANX_ALL_EN | AM65_CPSW_PN_TS_CTL_TX_VLAN_LT1_EN; - if (port->rx_ts_enabled) + if (port->rx_ts_filter) ts_ctrl |= AM65_CPSW_TS_RX_ANX_ALL_EN | AM65_CPSW_PN_TS_CTL_RX_VLAN_LT1_EN; @@ -1888,8 +1891,7 @@ static int am65_cpsw_nuss_hwtstamp_get(struct net_device *ndev, cfg->flags = 0; cfg->tx_type = port->tx_ts_enabled ? HWTSTAMP_TX_ON : HWTSTAMP_TX_OFF; - cfg->rx_filter = port->rx_ts_enabled ? HWTSTAMP_FILTER_PTP_V2_EVENT | - HWTSTAMP_FILTER_PTP_V1_L4_EVENT : HWTSTAMP_FILTER_NONE; + cfg->rx_filter = port->rx_ts_filter; return 0; } diff --git a/drivers/net/ethernet/ti/am65-cpsw-nuss.h b/drivers/net/ethernet/ti/am65-cpsw-nuss.h index 917c37e4e89b..7750448e4746 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-nuss.h +++ b/drivers/net/ethernet/ti/am65-cpsw-nuss.h @@ -52,7 +52,7 @@ struct am65_cpsw_port { bool disabled; struct am65_cpsw_slave_data slave; bool tx_ts_enabled; - bool rx_ts_enabled; + enum hwtstamp_rx_filters rx_ts_filter; struct am65_cpsw_qos qos; struct devlink_port devlink_port; struct bpf_prog *xdp_prog; diff --git a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c index d4c56da98a6a..53cdac272b58 100644 --- a/drivers/net/ethernet/ti/am65-cpsw-switchdev.c +++ b/drivers/net/ethernet/ti/am65-cpsw-switchdev.c @@ -435,7 +435,7 @@ static int am65_cpsw_switchdev_event(struct notifier_block *unused, if (!am65_cpsw_port_dev_check(ndev)) return NOTIFY_DONE; - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c index bb969dd435b4..be7b69319221 100644 --- a/drivers/net/ethernet/ti/cpsw_ale.c +++ b/drivers/net/ethernet/ti/cpsw_ale.c @@ -450,14 +450,13 @@ static void cpsw_ale_flush_mcast(struct cpsw_ale *ale, u32 *ale_entry, ale->port_mask_bits); if ((mask & port_mask) == 0) return; /* ports dont intersect, not interested */ - mask &= ~port_mask; + mask &= (~port_mask | ALE_PORT_HOST); - /* free if only remaining port is host port */ - if (mask) + if (mask == 0x0 || mask == ALE_PORT_HOST) + cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); + else cpsw_ale_set_port_mask(ale_entry, mask, ale->port_mask_bits); - else - cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE); } int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask, int vid) diff --git a/drivers/net/ethernet/ti/cpsw_switchdev.c b/drivers/net/ethernet/ti/cpsw_switchdev.c index ce85f7610273..7e06aac388a6 100644 --- a/drivers/net/ethernet/ti/cpsw_switchdev.c +++ b/drivers/net/ethernet/ti/cpsw_switchdev.c @@ -445,7 +445,7 @@ static int cpsw_switchdev_event(struct notifier_block *unused, if (!cpsw_port_dev_check(ndev)) return NOTIFY_DONE; - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c index 0939994c932f..42a881bee109 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c +++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c @@ -273,6 +273,14 @@ static int prueth_emac_common_start(struct prueth *prueth) if (ret) goto disable_class; + /* Reset link state to force reconfiguration in + * emac_adjust_link(). Without this, if the link was already up + * before restart, emac_adjust_link() won't detect any state + * change and will skip critical configuration like writing + * speed to firmware. + */ + emac->link = 0; + mutex_lock(&emac->ndev->phydev->lock); emac_adjust_link(emac->ndev); mutex_unlock(&emac->ndev->phydev->lock); diff --git a/drivers/net/ethernet/ti/icssg/icssg_switchdev.c b/drivers/net/ethernet/ti/icssg/icssg_switchdev.c index 67e2927e176d..26a57be04665 100644 --- a/drivers/net/ethernet/ti/icssg/icssg_switchdev.c +++ b/drivers/net/ethernet/ti/icssg/icssg_switchdev.c @@ -193,7 +193,7 @@ static int prueth_switchdev_event(struct notifier_block *unused, return notifier_from_errno(err); } - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; diff --git a/drivers/net/ethernet/ti/icssm/icssm_prueth_switch.c b/drivers/net/ethernet/ti/icssm/icssm_prueth_switch.c index 07c08564386e..66866ea37913 100644 --- a/drivers/net/ethernet/ti/icssm/icssm_prueth_switch.c +++ b/drivers/net/ethernet/ti/icssm/icssm_prueth_switch.c @@ -748,7 +748,7 @@ int icssm_prueth_sw_init_fdb_table(struct prueth *prueth) if (prueth->emac_configured) return 0; - prueth->fdb_tbl = kmalloc(sizeof(*prueth->fdb_tbl), GFP_KERNEL); + prueth->fdb_tbl = kmalloc_obj(*prueth->fdb_tbl); if (!prueth->fdb_tbl) return -ENOMEM; @@ -816,7 +816,7 @@ int icssm_prueth_sw_learn_fdb(struct prueth_emac *emac, u8 *src_mac) { struct icssm_prueth_sw_fdb_work *fdb_work; - fdb_work = kzalloc(sizeof(*fdb_work), GFP_ATOMIC); + fdb_work = kzalloc_obj(*fdb_work, GFP_ATOMIC); if (WARN_ON(!fdb_work)) return -ENOMEM; @@ -835,7 +835,7 @@ int icssm_prueth_sw_purge_fdb(struct prueth_emac *emac) { struct icssm_prueth_sw_fdb_work *fdb_work; - fdb_work = kzalloc(sizeof(*fdb_work), GFP_ATOMIC); + fdb_work = kzalloc_obj(*fdb_work, GFP_ATOMIC); if (WARN_ON(!fdb_work)) return -ENOMEM; diff --git a/drivers/net/ethernet/ti/icssm/icssm_switchdev.c b/drivers/net/ethernet/ti/icssm/icssm_switchdev.c index 414ec9fc02a0..1c48023031dc 100644 --- a/drivers/net/ethernet/ti/icssm/icssm_switchdev.c +++ b/drivers/net/ethernet/ti/icssm/icssm_switchdev.c @@ -167,7 +167,7 @@ static int icssm_prueth_sw_switchdev_event(struct notifier_block *unused, return notifier_from_errno(err); } - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (WARN_ON(!switchdev_work)) return NOTIFY_BAD; diff --git a/drivers/net/ethernet/ti/k3-cppi-desc-pool.c b/drivers/net/ethernet/ti/k3-cppi-desc-pool.c index 739bae8e11ee..71de14abf6f9 100644 --- a/drivers/net/ethernet/ti/k3-cppi-desc-pool.c +++ b/drivers/net/ethernet/ti/k3-cppi-desc-pool.c @@ -55,7 +55,7 @@ k3_cppi_desc_pool_create_name(struct device *dev, size_t size, const char *pool_name = NULL; int ret = -ENOMEM; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(ret); @@ -77,8 +77,7 @@ k3_cppi_desc_pool_create_name(struct device *dev, size_t size, pool->gen_pool->name = pool_name; - pool->desc_infos = kcalloc(pool->num_desc, - sizeof(*pool->desc_infos), GFP_KERNEL); + pool->desc_infos = kzalloc_objs(*pool->desc_infos, pool->num_desc); if (!pool->desc_infos) goto gen_pool_desc_infos_alloc_fail; diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index 4fbe4b7cd12a..88669aa53f65 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -209,7 +209,7 @@ static struct gelic_eurus_cmd *gelic_eurus_sync_cmd(struct gelic_wl_info *wl, struct gelic_eurus_cmd *cmd; /* allocate cmd */ - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return NULL; @@ -2305,9 +2305,8 @@ static struct net_device *gelic_wl_alloc(struct gelic_card *card) pr_debug("%s: wl=%p port=%p\n", __func__, wl, port); /* allocate scan list */ - wl->networks = kcalloc(GELIC_WL_BSS_MAX_ENT, - sizeof(struct gelic_wl_scan_info), - GFP_KERNEL); + wl->networks = kzalloc_objs(struct gelic_wl_scan_info, + GELIC_WL_BSS_MAX_ENT); if (!wl->networks) goto fail_bss; diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 5aa93144a4f5..6d7b6f3b4633 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -1631,8 +1631,8 @@ static int velocity_init_rd_ring(struct velocity_info *vptr) { int ret = -ENOMEM; - vptr->rx.info = kcalloc(vptr->options.numrx, - sizeof(struct velocity_rd_info), GFP_KERNEL); + vptr->rx.info = kzalloc_objs(struct velocity_rd_info, + vptr->options.numrx); if (!vptr->rx.info) goto out; @@ -1664,9 +1664,8 @@ static int velocity_init_td_ring(struct velocity_info *vptr) /* Init the TD ring entries */ for (j = 0; j < vptr->tx.numq; j++) { - vptr->tx.infos[j] = kcalloc(vptr->options.numtx, - sizeof(struct velocity_td_info), - GFP_KERNEL); + vptr->tx.infos[j] = kzalloc_objs(struct velocity_td_info, + vptr->options.numtx); if (!vptr->tx.infos[j]) { while (--j >= 0) kfree(vptr->tx.infos[j]); @@ -2304,7 +2303,7 @@ static int velocity_change_mtu(struct net_device *dev, int new_mtu) struct rx_info rx; struct tx_info tx; - tmp_vptr = kzalloc(sizeof(*tmp_vptr), GFP_KERNEL); + tmp_vptr = kzalloc_obj(*tmp_vptr); if (!tmp_vptr) { ret = -ENOMEM; goto out_0; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_hw.c b/drivers/net/ethernet/wangxun/libwx/wx_hw.c index 58b8300e3d2c..bee9e245e792 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_hw.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_hw.c @@ -2505,9 +2505,8 @@ int wx_sw_init(struct wx *wx) wx->rss_flags = WX_RSS_FIELD_IPV4 | WX_RSS_FIELD_IPV4_TCP | WX_RSS_FIELD_IPV6 | WX_RSS_FIELD_IPV6_TCP; - wx->mac_table = kcalloc(wx->mac.num_rar_entries, - sizeof(struct wx_mac_addr), - GFP_KERNEL); + wx->mac_table = kzalloc_objs(struct wx_mac_addr, + wx->mac.num_rar_entries); if (!wx->mac_table) { wx_err(wx, "mac_table allocation failed\n"); kfree(wx->rss_key); diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c index b31b48d26575..746623fa59b4 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -1905,16 +1905,14 @@ static int wx_acquire_msix_vectors(struct wx *wx) nvecs = min_t(int, nvecs, num_online_cpus()); nvecs = min_t(int, nvecs, wx->mac.max_msix_vectors); - wx->msix_q_entries = kcalloc(nvecs, sizeof(struct msix_entry), - GFP_KERNEL); + wx->msix_q_entries = kzalloc_objs(struct msix_entry, nvecs); if (!wx->msix_q_entries) return -ENOMEM; /* One for non-queue interrupts */ nvecs += 1; - wx->msix_entry = kcalloc(1, sizeof(struct msix_entry), - GFP_KERNEL); + wx->msix_entry = kzalloc_objs(struct msix_entry, 1); if (!wx->msix_entry) { kfree(wx->msix_q_entries); wx->msix_q_entries = NULL; @@ -2097,8 +2095,7 @@ static int wx_alloc_q_vector(struct wx *wx, /* note this will allocate space for the ring structure as well! */ ring_count = txr_count + rxr_count; - q_vector = kzalloc(struct_size(q_vector, ring, ring_count), - GFP_KERNEL); + q_vector = kzalloc_flex(*q_vector, ring, ring_count); if (!q_vector) return -ENOMEM; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_mbx.c b/drivers/net/ethernet/wangxun/libwx/wx_mbx.c index 2aa03eadf064..761aa4f713bd 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_mbx.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_mbx.c @@ -403,8 +403,7 @@ int wx_read_mbx_vf(struct wx *wx, u32 *msg, u16 size) int wx_init_mbx_params_vf(struct wx *wx) { - wx->vfinfo = kzalloc(sizeof(struct vf_data_storage), - GFP_KERNEL); + wx->vfinfo = kzalloc_obj(struct vf_data_storage); if (!wx->vfinfo) return -ENOMEM; diff --git a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c index 493da5fffdb6..a360b06a086a 100644 --- a/drivers/net/ethernet/wangxun/libwx/wx_sriov.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_sriov.c @@ -32,8 +32,7 @@ static int wx_alloc_vf_macvlans(struct wx *wx, u8 num_vfs) if (!num_vf_macvlans) return -EINVAL; - mv_list = kcalloc(num_vf_macvlans, sizeof(struct vf_macvlans), - GFP_KERNEL); + mv_list = kzalloc_objs(struct vf_macvlans, num_vf_macvlans); if (!mv_list) return -ENOMEM; @@ -88,8 +87,7 @@ static int __wx_enable_sriov(struct wx *wx, u8 num_vfs) wx->ring_feature[RING_F_VMDQ].limit = 1; wx->ring_feature[RING_F_VMDQ].offset = num_vfs; - wx->vfinfo = kcalloc(num_vfs, sizeof(struct vf_data_storage), - GFP_KERNEL); + wx->vfinfo = kzalloc_objs(struct vf_data_storage, num_vfs); if (!wx->vfinfo) return -ENOMEM; diff --git a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c index 662f28bdde8a..fc04040957bf 100644 --- a/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/ngbe/ngbe_ethtool.c @@ -81,7 +81,7 @@ static int ngbe_set_ringparam(struct net_device *netdev, /* allocate temporary buffer to store rings in */ i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); - temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL); + temp_ring = kvmalloc_objs(struct wx_ring, i); if (!temp_ring) { err = -ENOMEM; goto clear_reset; diff --git a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c index 59d758acccf0..9157b8275be1 100644 --- a/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c +++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_ethtool.c @@ -73,7 +73,7 @@ static int txgbe_set_ringparam(struct net_device *netdev, /* allocate temporary buffer to store rings in */ i = max_t(int, wx->num_tx_queues, wx->num_rx_queues); - temp_ring = kvmalloc_array(i, sizeof(struct wx_ring), GFP_KERNEL); + temp_ring = kvmalloc_objs(struct wx_ring, i); if (!temp_ring) { err = -ENOMEM; goto clear_reset; @@ -390,7 +390,7 @@ static int txgbe_add_ethtool_fdir_entry(struct txgbe *txgbe, return -EINVAL; } - input = kzalloc(sizeof(*input), GFP_ATOMIC); + input = kzalloc_obj(*input, GFP_ATOMIC); if (!input) return -ENOMEM; diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index 998bacd508b8..b06e4c37ff61 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1542,14 +1542,13 @@ static int axienet_init_dmaengine(struct net_device *ndev) lp->tx_ring_head = 0; lp->rx_ring_tail = 0; lp->rx_ring_head = 0; - lp->tx_skb_ring = kcalloc(TX_BD_NUM_MAX, sizeof(*lp->tx_skb_ring), - GFP_KERNEL); + lp->tx_skb_ring = kzalloc_objs(*lp->tx_skb_ring, TX_BD_NUM_MAX); if (!lp->tx_skb_ring) { ret = -ENOMEM; goto err_dma_release_rx; } for (i = 0; i < TX_BD_NUM_MAX; i++) { - skbuf_dma = kzalloc(sizeof(*skbuf_dma), GFP_KERNEL); + skbuf_dma = kzalloc_obj(*skbuf_dma); if (!skbuf_dma) { ret = -ENOMEM; goto err_free_tx_skb_ring; @@ -1557,14 +1556,13 @@ static int axienet_init_dmaengine(struct net_device *ndev) lp->tx_skb_ring[i] = skbuf_dma; } - lp->rx_skb_ring = kcalloc(RX_BUF_NUM_DEFAULT, sizeof(*lp->rx_skb_ring), - GFP_KERNEL); + lp->rx_skb_ring = kzalloc_objs(*lp->rx_skb_ring, RX_BUF_NUM_DEFAULT); if (!lp->rx_skb_ring) { ret = -ENOMEM; goto err_free_tx_skb_ring; } for (i = 0; i < RX_BUF_NUM_DEFAULT; i++) { - skbuf_dma = kzalloc(sizeof(*skbuf_dma), GFP_KERNEL); + skbuf_dma = kzalloc_obj(*skbuf_dma); if (!skbuf_dma) { ret = -ENOMEM; goto err_free_rx_skb_ring; diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index e1e7f65553e7..b0faa0f1780d 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -403,15 +403,12 @@ static int ixp4xx_hwtstamp_set(struct net_device *netdev, int ret; int ch; - if (!cpu_is_ixp46x()) - return -EOPNOTSUPP; - if (!netif_running(netdev)) return -EINVAL; ret = ixp46x_ptp_find(&port->timesync_regs, &port->phc_index); if (ret) - return ret; + return -EOPNOTSUPP; ch = PORT2CHANNEL(port); regs = port->timesync_regs; diff --git a/drivers/net/ethernet/xscale/ptp_ixp46x.c b/drivers/net/ethernet/xscale/ptp_ixp46x.c index 94203eb46e6b..93c64db22a69 100644 --- a/drivers/net/ethernet/xscale/ptp_ixp46x.c +++ b/drivers/net/ethernet/xscale/ptp_ixp46x.c @@ -232,6 +232,9 @@ static struct ixp_clock ixp_clock; int ixp46x_ptp_find(struct ixp46x_ts_regs *__iomem *regs, int *phc_index) { + if (!cpu_is_ixp46x()) + return -ENODEV; + *regs = ixp_clock.regs; *phc_index = ptp_clock_index(ixp_clock.ptp_clock); diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c index 5ad2673f213d..774eac1c11c0 100644 --- a/drivers/net/fjes/fjes_hw.c +++ b/drivers/net/fjes/fjes_hw.c @@ -212,8 +212,7 @@ static int fjes_hw_setup(struct fjes_hw *hw) hw->hw_info.max_epid = &hw->max_epid; hw->hw_info.my_epid = &hw->my_epid; - buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info), - GFP_KERNEL); + buf = kzalloc_objs(struct ep_share_mem_info, hw->max_epid); if (!buf) return -ENOMEM; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 0949d4579171..01cdd06102e0 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c @@ -980,7 +980,7 @@ static struct geneve_sock *geneve_socket_create(struct net *net, __be16 port, struct udp_tunnel_sock_cfg tunnel_cfg; int h; - gs = kzalloc(sizeof(*gs), GFP_KERNEL); + gs = kzalloc_obj(*gs); if (!gs) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index 4213c3b2d532..e8949f556209 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1623,13 +1623,13 @@ static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize) { int i; - gtp->addr_hash = kmalloc_array(hsize, sizeof(struct hlist_head), - GFP_KERNEL | __GFP_NOWARN); + gtp->addr_hash = kmalloc_objs(struct hlist_head, hsize, + GFP_KERNEL | __GFP_NOWARN); if (gtp->addr_hash == NULL) return -ENOMEM; - gtp->tid_hash = kmalloc_array(hsize, sizeof(struct hlist_head), - GFP_KERNEL | __GFP_NOWARN); + gtp->tid_hash = kmalloc_objs(struct hlist_head, hsize, + GFP_KERNEL | __GFP_NOWARN); if (gtp->tid_hash == NULL) goto err1; @@ -1917,7 +1917,7 @@ static struct pdp_ctx *gtp_pdp_add(struct gtp_dev *gtp, struct sock *sk, } - pctx = kmalloc(sizeof(*pctx), GFP_ATOMIC); + pctx = kmalloc_obj(*pctx, GFP_ATOMIC); if (pctx == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index f29997b20fd7..4106f0301ab4 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -386,7 +386,7 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate, } /* Allocate a new mcs */ - if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) { + if ((p = kmalloc_obj(struct yam_mcs)) == NULL) { release_firmware(fw); return NULL; } diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 60a4629fe6ba..59e95341f9b1 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -129,7 +129,7 @@ static struct netvsc_device *alloc_net_device(void) { struct netvsc_device *net_device; - net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); + net_device = kzalloc_obj(struct netvsc_device); if (!net_device) return NULL; @@ -1025,9 +1025,8 @@ static int netvsc_dma_map(struct hv_device *hv_dev, if (!hv_is_isolation_supported()) return 0; - packet->dma_range = kcalloc(page_count, - sizeof(*packet->dma_range), - GFP_ATOMIC); + packet->dma_range = kzalloc_objs(*packet->dma_range, page_count, + GFP_ATOMIC); if (!packet->dma_range) return -ENOMEM; diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index cbd52cb79268..ee5ab5ceb2be 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -712,7 +712,7 @@ void netvsc_linkstatus_callback(struct net_device *net, if (net->reg_state != NETREG_REGISTERED) return; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return; event->event = indicate->status; @@ -931,7 +931,7 @@ struct netvsc_device_info *netvsc_devinfo_get(struct netvsc_device *nvdev) struct netvsc_device_info *dev_info; struct bpf_prog *prog; - dev_info = kzalloc(sizeof(*dev_info), GFP_ATOMIC); + dev_info = kzalloc_obj(*dev_info, GFP_ATOMIC); if (!dev_info) return NULL; @@ -1524,9 +1524,7 @@ static void netvsc_get_ethtool_stats(struct net_device *dev, data[i++] = xdp_tx; } - pcpu_sum = kvmalloc_array(nr_cpu_ids, - sizeof(struct netvsc_ethtool_pcpu_stats), - GFP_KERNEL); + pcpu_sum = kvmalloc_objs(struct netvsc_ethtool_pcpu_stats, nr_cpu_ids); if (!pcpu_sum) return; diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c index c35f9685b6bf..9b6c44979b4e 100644 --- a/drivers/net/hyperv/rndis_filter.c +++ b/drivers/net/hyperv/rndis_filter.c @@ -64,7 +64,7 @@ static struct rndis_device *get_rndis_device(void) { struct rndis_device *device; - device = kzalloc(sizeof(struct rndis_device), GFP_KERNEL); + device = kzalloc_obj(struct rndis_device); if (!device) return NULL; @@ -87,7 +87,7 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev, struct rndis_set_request *set; unsigned long flags; - request = kzalloc(sizeof(struct rndis_request), GFP_KERNEL); + request = kzalloc_obj(struct rndis_request); if (!request) return NULL; diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index fd91f8a45bce..6156cf379916 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -788,7 +788,7 @@ static irqreturn_t at86rf230_isr(int irq, void *data) disable_irq_nosync(irq); - ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); + ctx = kzalloc_obj(*ctx, GFP_ATOMIC); if (!ctx) { enable_irq(irq); return IRQ_NONE; diff --git a/drivers/net/ieee802154/ca8210.c b/drivers/net/ieee802154/ca8210.c index ebc4f1b18e7b..ed4178155a5d 100644 --- a/drivers/net/ieee802154/ca8210.c +++ b/drivers/net/ieee802154/ca8210.c @@ -720,8 +720,7 @@ static void ca8210_rx_done(struct cas_control *cas_ctl) &priv->spi->dev, "Resetting MAC...\n"); - mlme_reset_wpc = kmalloc(sizeof(*mlme_reset_wpc), - GFP_KERNEL); + mlme_reset_wpc = kmalloc_obj(*mlme_reset_wpc); if (!mlme_reset_wpc) goto finish; INIT_WORK( @@ -884,7 +883,7 @@ static int ca8210_spi_transfer( dev_dbg(&spi->dev, "%s called\n", __func__); - cas_ctl = kzalloc(sizeof(*cas_ctl), GFP_ATOMIC); + cas_ctl = kzalloc_obj(*cas_ctl, GFP_ATOMIC); if (!cas_ctl) return -ENOMEM; @@ -3067,7 +3066,7 @@ static int ca8210_probe(struct spi_device *spi_device) ca8210_hw_setup(hw); ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); - pdata = kmalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kmalloc_obj(*pdata); if (!pdata) { ret = -ENOMEM; goto error; diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c index 1cab20b5a885..6daa0f198b9f 100644 --- a/drivers/net/ieee802154/mac802154_hwsim.c +++ b/drivers/net/ieee802154/mac802154_hwsim.c @@ -98,7 +98,7 @@ static int hwsim_update_pib(struct ieee802154_hw *hw, u8 page, u8 channel, struct hwsim_phy *phy = hw->priv; struct hwsim_pib *pib, *pib_old; - pib = kzalloc(sizeof(*pib), GFP_ATOMIC); + pib = kzalloc_obj(*pib, GFP_ATOMIC); if (!pib) return -ENOMEM; @@ -545,11 +545,11 @@ static struct hwsim_edge *hwsim_alloc_edge(struct hwsim_phy *endpoint, u8 lqi) struct hwsim_edge_info *einfo; struct hwsim_edge *e; - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return NULL; - einfo = kzalloc(sizeof(*einfo), GFP_KERNEL); + einfo = kzalloc_obj(*einfo); if (!einfo) { kfree(e); return NULL; @@ -713,7 +713,7 @@ static int hwsim_set_edge_lqi(struct sk_buff *msg, struct genl_info *info) return -ENOENT; } - einfo = kzalloc(sizeof(*einfo), GFP_KERNEL); + einfo = kzalloc_obj(*einfo); if (!einfo) { mutex_unlock(&hwsim_phys_lock); return -ENOMEM; @@ -946,7 +946,7 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev, /* hwsim phy channel 13 as default */ hw->phy->current_channel = 13; - pib = kzalloc(sizeof(*pib), GFP_KERNEL); + pib = kzalloc_obj(*pib); if (!pib) { err = -ENOMEM; goto err_pib; diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index 6da801748189..5407d2ed71b3 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c @@ -187,7 +187,7 @@ static int ifb_dev_init(struct net_device *dev) struct ifb_q_private *txp; int i; - txp = kcalloc(dev->num_tx_queues, sizeof(*txp), GFP_KERNEL); + txp = kzalloc_objs(*txp, dev->num_tx_queues); if (!txp) return -ENOMEM; dp->tx_private = txp; diff --git a/drivers/net/ipa/gsi_trans.c b/drivers/net/ipa/gsi_trans.c index 19531883864a..ecd9a3b8754f 100644 --- a/drivers/net/ipa/gsi_trans.c +++ b/drivers/net/ipa/gsi_trans.c @@ -730,8 +730,7 @@ int gsi_channel_trans_init(struct gsi *gsi, u32 channel_id) * modulo that number to determine the next one that's free. * Transactions are allocated one at a time. */ - trans_info->trans = kcalloc(tre_count, sizeof(*trans_info->trans), - GFP_KERNEL); + trans_info->trans = kzalloc_objs(*trans_info->trans, tre_count); if (!trans_info->trans) return -ENOMEM; trans_info->free_id = 0; /* all modulo channel->tre_count */ @@ -746,8 +745,7 @@ int gsi_channel_trans_init(struct gsi *gsi, u32 channel_id) * Each entry in this map records the transaction associated * with a corresponding completed TRE. */ - trans_info->map = kcalloc(tre_count, sizeof(*trans_info->map), - GFP_KERNEL); + trans_info->map = kzalloc_objs(*trans_info->map, tre_count); if (!trans_info->map) { ret = -ENOMEM; goto err_trans_free; diff --git a/drivers/net/ipa/ipa_interrupt.c b/drivers/net/ipa/ipa_interrupt.c index 8336596b1247..131b9cc94201 100644 --- a/drivers/net/ipa/ipa_interrupt.c +++ b/drivers/net/ipa/ipa_interrupt.c @@ -329,7 +329,7 @@ struct ipa_interrupt *ipa_interrupt_init(struct platform_device *pdev) if (irq <= 0) return ERR_PTR(irq ? : -EINVAL); - interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); + interrupt = kzalloc_obj(*interrupt); if (!interrupt) return ERR_PTR(-ENOMEM); interrupt->irq = irq; diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c index 95a61bae3124..edead9c48d1f 100644 --- a/drivers/net/ipa/ipa_main.c +++ b/drivers/net/ipa/ipa_main.c @@ -830,7 +830,7 @@ static int ipa_probe(struct platform_device *pdev) } /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */ - ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); + ipa = kzalloc_obj(*ipa); if (!ipa) { ret = -ENOMEM; goto err_power_exit; diff --git a/drivers/net/ipa/ipa_smp2p.c b/drivers/net/ipa/ipa_smp2p.c index 420098796eec..2f0ccdd937cc 100644 --- a/drivers/net/ipa/ipa_smp2p.c +++ b/drivers/net/ipa/ipa_smp2p.c @@ -242,7 +242,7 @@ ipa_smp2p_init(struct ipa *ipa, struct platform_device *pdev, bool modem_init) if (enabled_bit >= 32) /* BITS_PER_U32 */ return -EINVAL; - smp2p = kzalloc(sizeof(*smp2p), GFP_KERNEL); + smp2p = kzalloc_obj(*smp2p); if (!smp2p) return -ENOMEM; diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c index baccdad695fd..ed46439a9f4e 100644 --- a/drivers/net/ipvlan/ipvlan_main.c +++ b/drivers/net/ipvlan/ipvlan_main.c @@ -64,7 +64,7 @@ static int ipvlan_port_create(struct net_device *dev) struct ipvl_port *port; int err, idx; - port = kzalloc(sizeof(struct ipvl_port), GFP_KERNEL); + port = kzalloc_obj(struct ipvl_port); if (!port) return -ENOMEM; @@ -820,7 +820,7 @@ static int ipvlan_add_addr(struct ipvl_dev *ipvlan, void *iaddr, bool is_v6) assert_spin_locked(&ipvlan->port->addrs_lock); - addr = kzalloc(sizeof(struct ipvl_addr), GFP_ATOMIC); + addr = kzalloc_obj(struct ipvl_addr, GFP_ATOMIC); if (!addr) return -ENOMEM; diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index c2cb2d20976b..f6cad0746a02 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -1465,7 +1465,7 @@ static struct macsec_rx_sc *create_rx_sc(struct net_device *dev, sci_t sci, return ERR_PTR(-EEXIST); } - rx_sc = kzalloc(sizeof(*rx_sc), GFP_KERNEL); + rx_sc = kzalloc_obj(*rx_sc); if (!rx_sc) return ERR_PTR(-ENOMEM); @@ -1797,7 +1797,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) return -EBUSY; } - rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); + rx_sa = kmalloc_obj(*rx_sa); if (!rx_sa) { rtnl_unlock(); return -ENOMEM; @@ -2005,7 +2005,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) return -EBUSY; } - tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); + tx_sa = kmalloc_obj(*tx_sa); if (!tx_sa) { rtnl_unlock(); return -ENOMEM; @@ -4013,7 +4013,7 @@ static int register_macsec_dev(struct net_device *real_dev, if (!rxd) { int err; - rxd = kmalloc(sizeof(*rxd), GFP_KERNEL); + rxd = kmalloc_obj(*rxd); if (!rxd) return -ENOMEM; diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c509228be84d..a71f058eceef 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -163,7 +163,7 @@ static int macvlan_hash_add_source(struct macvlan_dev *vlan, if (entry) return 0; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1131,7 +1131,7 @@ static int macvlan_dev_netpoll_setup(struct net_device *dev) struct netpoll *netpoll; int err; - netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); + netpoll = kzalloc_obj(*netpoll); err = -ENOMEM; if (!netpoll) goto out; @@ -1249,7 +1249,7 @@ static int macvlan_port_create(struct net_device *dev) if (netdev_is_rx_handler_busy(dev)) return -EBUSY; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (port == NULL) return -ENOMEM; @@ -1572,6 +1572,11 @@ int macvlan_common_newlink(struct net_device *dev, if (create) macvlan_port_destroy(port->dev); } + /* @dev might have been made visible before an error was detected. + * Make sure to observe an RCU grace period before our caller + * (rtnl_newlink()) frees it. + */ + synchronize_net(); return err; } EXPORT_SYMBOL_GPL(macvlan_common_newlink); diff --git a/drivers/net/mctp/mctp-i2c.c b/drivers/net/mctp/mctp-i2c.c index 8043b57bdf25..15fe4d1163c1 100644 --- a/drivers/net/mctp/mctp-i2c.c +++ b/drivers/net/mctp/mctp-i2c.c @@ -154,7 +154,7 @@ static struct mctp_i2c_client *mctp_i2c_new_client(struct i2c_client *client) goto err; } - mcli = kzalloc(sizeof(*mcli), GFP_KERNEL); + mcli = kzalloc_obj(*mcli); if (!mcli) { rc = -ENOMEM; goto err; @@ -343,6 +343,7 @@ static int mctp_i2c_recv(struct mctp_i2c_dev *midev) } else { status = NET_RX_DROP; spin_unlock_irqrestore(&midev->lock, flags); + kfree_skb(skb); } if (status == NET_RX_SUCCESS) { diff --git a/drivers/net/mctp/mctp-i3c.c b/drivers/net/mctp/mctp-i3c.c index 36c2405677c2..6d2bbae7477b 100644 --- a/drivers/net/mctp/mctp-i3c.c +++ b/drivers/net/mctp/mctp-i3c.c @@ -259,7 +259,7 @@ __must_hold(&busdevs_lock) struct mctp_i3c_device *mi = NULL; int rc; - mi = kzalloc(sizeof(*mi), GFP_KERNEL); + mi = kzalloc_obj(*mi); if (!mi) { rc = -ENOMEM; goto err; diff --git a/drivers/net/mctp/mctp-usb.c b/drivers/net/mctp/mctp-usb.c index ef860cfc629f..3b5dff144177 100644 --- a/drivers/net/mctp/mctp-usb.c +++ b/drivers/net/mctp/mctp-usb.c @@ -329,7 +329,7 @@ static int mctp_usb_probe(struct usb_interface *intf, SET_NETDEV_DEV(netdev, &intf->dev); dev = netdev_priv(netdev); dev->netdev = netdev; - dev->usbdev = usb_get_dev(interface_to_usbdev(intf)); + dev->usbdev = interface_to_usbdev(intf); dev->intf = intf; usb_set_intfdata(intf, dev); @@ -365,7 +365,6 @@ static void mctp_usb_disconnect(struct usb_interface *intf) mctp_unregister_netdev(dev->netdev); usb_free_urb(dev->tx_urb); usb_free_urb(dev->rx_urb); - usb_put_dev(dev->usbdev); free_netdev(dev->netdev); } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index d144787b2947..3c9acd6e49e8 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -348,7 +348,7 @@ static struct netconsole_target *alloc_and_init(void) { struct netconsole_target *nt; - nt = kzalloc(sizeof(*nt), GFP_KERNEL); + nt = kzalloc_obj(*nt); if (!nt) return nt; @@ -617,7 +617,7 @@ static ssize_t sysdata_release_enabled_show(struct config_item *item, bool release_enabled; dynamic_netconsole_mutex_lock(); - release_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME); + release_enabled = !!(nt->sysdata_fields & SYSDATA_RELEASE); dynamic_netconsole_mutex_unlock(); return sysfs_emit(buf, "%d\n", release_enabled); @@ -1270,7 +1270,7 @@ static struct config_item *userdatum_make_item(struct config_group *group, if (count_userdata_entries(nt) >= MAX_USERDATA_ITEMS) return ERR_PTR(-ENOSPC); - udm = kzalloc(sizeof(*udm), GFP_KERNEL); + udm = kzalloc_obj(*udm); if (!udm) return ERR_PTR(-ENOMEM); @@ -1679,7 +1679,8 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt, if (release_len) { release = init_utsname()->release; - scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%s", release, msg); + scnprintf(nt->buf, MAX_PRINT_CHUNK, "%s,%.*s", release, + msg_len, msg); msg_len += release_len; } else { memcpy(nt->buf, msg, msg_len); diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index 5f17f68f3c08..8eebcc933ddb 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c @@ -222,7 +222,7 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev, char name[16]; int ret; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -501,7 +501,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap) if (offmap->map.map_flags) return -EINVAL; - nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT); + nmap = kzalloc_obj(*nmap, GFP_KERNEL_ACCOUNT); if (!nmap) return -ENOMEM; diff --git a/drivers/net/netdevsim/bus.c b/drivers/net/netdevsim/bus.c index d16b95304aa7..f85b1c261dfb 100644 --- a/drivers/net/netdevsim/bus.c +++ b/drivers/net/netdevsim/bus.c @@ -451,7 +451,7 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count, unsigned int num_queu struct nsim_bus_dev *nsim_bus_dev; int err; - nsim_bus_dev = kzalloc(sizeof(*nsim_bus_dev), GFP_KERNEL); + nsim_bus_dev = kzalloc_obj(*nsim_bus_dev); if (!nsim_bus_dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c index f7b32446d3b8..e82de0fd3157 100644 --- a/drivers/net/netdevsim/dev.c +++ b/drivers/net/netdevsim/dev.c @@ -267,8 +267,8 @@ static ssize_t nsim_bus_dev_max_vfs_write(struct file *file, if (val > NSIM_DEV_VF_PORT_INDEX_MAX - NSIM_DEV_VF_PORT_INDEX_BASE) return -ERANGE; - vfconfigs = kcalloc(val, sizeof(struct nsim_vf_config), - GFP_KERNEL | __GFP_NOWARN); + vfconfigs = kzalloc_objs(struct nsim_vf_config, val, + GFP_KERNEL | __GFP_NOWARN); if (!vfconfigs) return -ENOMEM; @@ -935,13 +935,12 @@ static int nsim_dev_traps_init(struct devlink *devlink) struct nsim_trap_data *nsim_trap_data; int err; - nsim_trap_data = kzalloc(sizeof(*nsim_trap_data), GFP_KERNEL); + nsim_trap_data = kzalloc_obj(*nsim_trap_data); if (!nsim_trap_data) return -ENOMEM; - nsim_trap_data->trap_items_arr = kcalloc(ARRAY_SIZE(nsim_traps_arr), - sizeof(struct nsim_trap_item), - GFP_KERNEL); + nsim_trap_data->trap_items_arr = kzalloc_objs(struct nsim_trap_item, + ARRAY_SIZE(nsim_traps_arr)); if (!nsim_trap_data->trap_items_arr) { err = -ENOMEM; goto err_trap_data_free; @@ -1348,7 +1347,7 @@ static int nsim_rate_node_new(struct devlink_rate *node, void **priv, return -EOPNOTSUPP; } - nsim_node = kzalloc(sizeof(*nsim_node), GFP_KERNEL); + nsim_node = kzalloc_obj(*nsim_node); if (!nsim_node) return -ENOMEM; @@ -1464,7 +1463,7 @@ static int __nsim_dev_port_add(struct nsim_dev *nsim_dev, enum nsim_dev_port_typ if (type == NSIM_DEV_PORT_TYPE_VF && !nsim_dev_get_vfs(nsim_dev)) return -EINVAL; - nsim_dev_port = kzalloc(sizeof(*nsim_dev_port), GFP_KERNEL); + nsim_dev_port = kzalloc_obj(*nsim_dev_port); if (!nsim_dev_port) return -ENOMEM; nsim_dev_port->port_index = nsim_dev_port_index(type, port_index); @@ -1652,9 +1651,9 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) dev_set_drvdata(&nsim_bus_dev->dev, nsim_dev); - nsim_dev->vfconfigs = kcalloc(nsim_bus_dev->max_vfs, - sizeof(struct nsim_vf_config), - GFP_KERNEL | __GFP_NOWARN); + nsim_dev->vfconfigs = kzalloc_objs(struct nsim_vf_config, + nsim_bus_dev->max_vfs, + GFP_KERNEL | __GFP_NOWARN); if (!nsim_dev->vfconfigs) { err = -ENOMEM; goto err_devlink_unlock; diff --git a/drivers/net/netdevsim/fib.c b/drivers/net/netdevsim/fib.c index 16c382c42227..1a42bdbfaa41 100644 --- a/drivers/net/netdevsim/fib.c +++ b/drivers/net/netdevsim/fib.c @@ -277,7 +277,7 @@ nsim_fib4_rt_create(struct nsim_fib_data *data, { struct nsim_fib4_rt *fib4_rt; - fib4_rt = kzalloc(sizeof(*fib4_rt), GFP_KERNEL); + fib4_rt = kzalloc_obj(*fib4_rt); if (!fib4_rt) return NULL; @@ -497,7 +497,7 @@ static int nsim_fib6_rt_nh_add(struct nsim_fib6_rt *fib6_rt, { struct nsim_fib6_rt_nh *fib6_rt_nh; - fib6_rt_nh = kzalloc(sizeof(*fib6_rt_nh), GFP_KERNEL); + fib6_rt_nh = kzalloc_obj(*fib6_rt_nh); if (!fib6_rt_nh) return -ENOMEM; @@ -544,7 +544,7 @@ nsim_fib6_rt_create(struct nsim_fib_data *data, int i = 0; int err; - fib6_rt = kzalloc(sizeof(*fib6_rt), GFP_KERNEL); + fib6_rt = kzalloc_obj(*fib6_rt); if (!fib6_rt) return ERR_PTR(-ENOMEM); @@ -807,7 +807,7 @@ static int nsim_fib6_event_init(struct nsim_fib6_event *fib6_event, nrt6 = fen6_info->nsiblings + 1; - rt_arr = kcalloc(nrt6, sizeof(struct fib6_info *), GFP_ATOMIC); + rt_arr = kzalloc_objs(struct fib6_info *, nrt6, GFP_ATOMIC); if (!rt_arr) return -ENOMEM; @@ -987,7 +987,7 @@ static int nsim_fib_event_schedule_work(struct nsim_fib_data *data, */ return NOTIFY_DONE; - fib_event = kzalloc(sizeof(*fib_event), GFP_ATOMIC); + fib_event = kzalloc_obj(*fib_event, GFP_ATOMIC); if (!fib_event) goto err_fib_event_alloc; @@ -1116,7 +1116,7 @@ static struct nsim_nexthop *nsim_nexthop_create(struct nsim_fib_data *data, u64 occ = 0; int i; - nexthop = kzalloc(sizeof(*nexthop), GFP_KERNEL); + nexthop = kzalloc_obj(*nexthop); if (!nexthop) return ERR_PTR(-ENOMEM); @@ -1556,7 +1556,7 @@ struct nsim_fib_data *nsim_fib_create(struct devlink *devlink, struct nsim_dev *nsim_dev; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); data->devlink = devlink; diff --git a/drivers/net/netdevsim/hwstats.c b/drivers/net/netdevsim/hwstats.c index 1abe48e35ca3..14234a4cc244 100644 --- a/drivers/net/netdevsim/hwstats.c +++ b/drivers/net/netdevsim/hwstats.c @@ -238,7 +238,7 @@ nsim_dev_hwstats_enable_ifindex(struct nsim_dev_hwstats *hwstats, goto out_unlock_list; } - hwsdev = kzalloc(sizeof(*hwsdev), GFP_KERNEL); + hwsdev = kzalloc_obj(*hwsdev); if (!hwsdev) { err = -ENOMEM; goto out_put_netdev; diff --git a/drivers/net/netdevsim/netdev.c b/drivers/net/netdevsim/netdev.c index 6285fbefe38a..5ec028a00c62 100644 --- a/drivers/net/netdevsim/netdev.c +++ b/drivers/net/netdevsim/netdev.c @@ -723,7 +723,7 @@ static struct nsim_rq *nsim_queue_alloc(void) { struct nsim_rq *rq; - rq = kzalloc(sizeof(*rq), GFP_KERNEL_ACCOUNT); + rq = kzalloc_obj(*rq, GFP_KERNEL_ACCOUNT); if (!rq) return NULL; @@ -997,8 +997,7 @@ static int nsim_queue_init(struct netdevsim *ns) struct net_device *dev = ns->netdev; int i; - ns->rq = kcalloc(dev->num_rx_queues, sizeof(*ns->rq), - GFP_KERNEL_ACCOUNT); + ns->rq = kzalloc_objs(*ns->rq, dev->num_rx_queues, GFP_KERNEL_ACCOUNT); if (!ns->rq) return -ENOMEM; diff --git a/drivers/net/netdevsim/psample.c b/drivers/net/netdevsim/psample.c index f0c6477dd0ae..47d24bc64ee4 100644 --- a/drivers/net/netdevsim/psample.c +++ b/drivers/net/netdevsim/psample.c @@ -200,7 +200,7 @@ int nsim_dev_psample_init(struct nsim_dev *nsim_dev) struct nsim_dev_psample *psample; int err; - psample = kzalloc(sizeof(*psample), GFP_KERNEL); + psample = kzalloc_obj(*psample); if (!psample) return -ENOMEM; nsim_dev->psample = psample; diff --git a/drivers/net/netkit.c b/drivers/net/netkit.c index 0a2fef7caccb..5c0e01396e06 100644 --- a/drivers/net/netkit.c +++ b/drivers/net/netkit.c @@ -796,7 +796,7 @@ int netkit_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) ret = PTR_ERR(dev); goto out; } - nkl = kzalloc(sizeof(*nkl), GFP_KERNEL_ACCOUNT); + nkl = kzalloc_obj(*nkl, GFP_KERNEL_ACCOUNT); if (!nkl) { ret = -ENOMEM; goto out; diff --git a/drivers/net/ovpn/bind.c b/drivers/net/ovpn/bind.c index 24d2788a277e..e42b60cd04a9 100644 --- a/drivers/net/ovpn/bind.c +++ b/drivers/net/ovpn/bind.c @@ -32,7 +32,7 @@ struct ovpn_bind *ovpn_bind_from_sockaddr(const struct sockaddr_storage *ss) else return ERR_PTR(-EAFNOSUPPORT); - bind = kzalloc(sizeof(*bind), GFP_ATOMIC); + bind = kzalloc_obj(*bind, GFP_ATOMIC); if (unlikely(!bind)) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ovpn/crypto_aead.c b/drivers/net/ovpn/crypto_aead.c index 2cca759feffa..77be0942a269 100644 --- a/drivers/net/ovpn/crypto_aead.c +++ b/drivers/net/ovpn/crypto_aead.c @@ -328,7 +328,7 @@ ovpn_aead_crypto_key_slot_new(const struct ovpn_key_config *kc) return ERR_PTR(-EINVAL); /* build the key slot */ - ks = kmalloc(sizeof(*ks), GFP_KERNEL); + ks = kmalloc_obj(*ks); if (!ks) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c index 3e9e7f8444b3..955c9a37e1f8 100644 --- a/drivers/net/ovpn/io.c +++ b/drivers/net/ovpn/io.c @@ -355,6 +355,7 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) struct ovpn_priv *ovpn = netdev_priv(dev); struct sk_buff *segments, *curr, *next; struct sk_buff_head skb_list; + unsigned int tx_bytes = 0; struct ovpn_peer *peer; __be16 proto; int ret; @@ -365,7 +366,27 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) /* verify IP header size in network packet */ proto = ovpn_ip_check_protocol(skb); if (unlikely(!proto || skb->protocol != proto)) - goto drop; + goto drop_no_peer; + + /* retrieve peer serving the destination IP of this packet */ + peer = ovpn_peer_get_by_dst(ovpn, skb); + if (unlikely(!peer)) { + switch (skb->protocol) { + case htons(ETH_P_IP): + net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", + netdev_name(ovpn->dev), + &ip_hdr(skb)->daddr); + break; + case htons(ETH_P_IPV6): + net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", + netdev_name(ovpn->dev), + &ipv6_hdr(skb)->daddr); + break; + } + goto drop_no_peer; + } + /* dst was needed for peer selection - it can now be dropped */ + skb_dst_drop(skb); if (skb_is_gso(skb)) { segments = skb_gso_segment(skb, 0); @@ -394,36 +415,28 @@ netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev) continue; } + /* only count what we actually send */ + tx_bytes += curr->len; __skb_queue_tail(&skb_list, curr); } + + /* no segments survived: don't jump to 'drop' because we already + * incremented the counter for each failure in the loop + */ + if (unlikely(skb_queue_empty(&skb_list))) { + ovpn_peer_put(peer); + return NETDEV_TX_OK; + } skb_list.prev->next = NULL; - /* retrieve peer serving the destination IP of this packet */ - peer = ovpn_peer_get_by_dst(ovpn, skb); - if (unlikely(!peer)) { - switch (skb->protocol) { - case htons(ETH_P_IP): - net_dbg_ratelimited("%s: no peer to send data to dst=%pI4\n", - netdev_name(ovpn->dev), - &ip_hdr(skb)->daddr); - break; - case htons(ETH_P_IPV6): - net_dbg_ratelimited("%s: no peer to send data to dst=%pI6c\n", - netdev_name(ovpn->dev), - &ipv6_hdr(skb)->daddr); - break; - } - goto drop; - } - /* dst was needed for peer selection - it can now be dropped */ - skb_dst_drop(skb); - - ovpn_peer_stats_increment_tx(&peer->vpn_stats, skb->len); + ovpn_peer_stats_increment_tx(&peer->vpn_stats, tx_bytes); ovpn_send(ovpn, skb_list.next, peer); return NETDEV_TX_OK; drop: + ovpn_peer_put(peer); +drop_no_peer: dev_dstats_tx_dropped(ovpn->dev); skb_tx_error(skb); kfree_skb_list(skb); diff --git a/drivers/net/ovpn/main.c b/drivers/net/ovpn/main.c index 1bb1afe766a4..2e0420febda0 100644 --- a/drivers/net/ovpn/main.c +++ b/drivers/net/ovpn/main.c @@ -57,7 +57,7 @@ static int ovpn_mp_alloc(struct ovpn_priv *ovpn) /* the peer container is fairly large, therefore we allocate it only in * MP mode */ - ovpn->peers = kzalloc(sizeof(*ovpn->peers), GFP_KERNEL); + ovpn->peers = kzalloc_obj(*ovpn->peers); if (!ovpn->peers) return -ENOMEM; diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 0463b5b0542f..3716a1d82801 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -95,7 +95,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id) int ret; /* alloc and init peer object */ - peer = kzalloc(sizeof(*peer), GFP_KERNEL); + peer = kzalloc_obj(*peer); if (!peer) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ovpn/socket.c b/drivers/net/ovpn/socket.c index 9750871ab65c..517caa64a4fe 100644 --- a/drivers/net/ovpn/socket.c +++ b/drivers/net/ovpn/socket.c @@ -191,7 +191,7 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) /* socket is not owned: attach to this ovpn instance */ - ovpn_sock = kzalloc(sizeof(*ovpn_sock), GFP_KERNEL); + ovpn_sock = kzalloc_obj(*ovpn_sock); if (!ovpn_sock) { ovpn_sock = ERR_PTR(-ENOMEM); goto sock_release; @@ -200,24 +200,6 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) ovpn_sock->sk = sk; kref_init(&ovpn_sock->refcount); - /* the newly created ovpn_socket is holding reference to sk, - * therefore we increase its refcounter. - * - * This ovpn_socket instance is referenced by all peers - * using the same socket. - * - * ovpn_socket_release() will take care of dropping the reference. - */ - sock_hold(sk); - - ret = ovpn_socket_attach(ovpn_sock, sock, peer); - if (ret < 0) { - sock_put(sk); - kfree(ovpn_sock); - ovpn_sock = ERR_PTR(ret); - goto sock_release; - } - /* TCP sockets are per-peer, therefore they are linked to their unique * peer */ @@ -234,7 +216,28 @@ struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) GFP_KERNEL); } - rcu_assign_sk_user_data(sk, ovpn_sock); + /* the newly created ovpn_socket is holding reference to sk, + * therefore we increase its refcounter. + * + * This ovpn_socket instance is referenced by all peers + * using the same socket. + * + * ovpn_socket_release() will take care of dropping the reference. + */ + sock_hold(sk); + + ret = ovpn_socket_attach(ovpn_sock, sock, peer); + if (ret < 0) { + if (sk->sk_protocol == IPPROTO_TCP) + ovpn_peer_put(peer); + else if (sk->sk_protocol == IPPROTO_UDP) + netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker); + + sock_put(sk); + kfree(ovpn_sock); + ovpn_sock = ERR_PTR(ret); + } + sock_release: release_sock(sk); return ovpn_sock; diff --git a/drivers/net/ovpn/tcp.c b/drivers/net/ovpn/tcp.c index 0d7f30360d87..5499c1572f3e 100644 --- a/drivers/net/ovpn/tcp.c +++ b/drivers/net/ovpn/tcp.c @@ -70,37 +70,56 @@ static void ovpn_tcp_to_userspace(struct ovpn_peer *peer, struct sock *sk, peer->tcp.sk_cb.sk_data_ready(sk); } +static struct sk_buff *ovpn_tcp_skb_packet(const struct ovpn_peer *peer, + struct sk_buff *orig_skb, + const int pkt_len, const int pkt_off) +{ + struct sk_buff *ovpn_skb; + int err; + + /* create a new skb with only the content of the current packet */ + ovpn_skb = netdev_alloc_skb(peer->ovpn->dev, pkt_len); + if (unlikely(!ovpn_skb)) + goto err; + + skb_copy_header(ovpn_skb, orig_skb); + err = skb_copy_bits(orig_skb, pkt_off, skb_put(ovpn_skb, pkt_len), + pkt_len); + if (unlikely(err)) { + net_warn_ratelimited("%s: skb_copy_bits failed for peer %u\n", + netdev_name(peer->ovpn->dev), peer->id); + kfree_skb(ovpn_skb); + goto err; + } + + consume_skb(orig_skb); + return ovpn_skb; +err: + kfree_skb(orig_skb); + return NULL; +} + static void ovpn_tcp_rcv(struct strparser *strp, struct sk_buff *skb) { struct ovpn_peer *peer = container_of(strp, struct ovpn_peer, tcp.strp); struct strp_msg *msg = strp_msg(skb); - size_t pkt_len = msg->full_len - 2; - size_t off = msg->offset + 2; + int pkt_len = msg->full_len - 2; u8 opcode; - /* ensure skb->data points to the beginning of the openvpn packet */ - if (!pskb_pull(skb, off)) { - net_warn_ratelimited("%s: packet too small for peer %u\n", - netdev_name(peer->ovpn->dev), peer->id); - goto err; - } - - /* strparser does not trim the skb for us, therefore we do it now */ - if (pskb_trim(skb, pkt_len) != 0) { - net_warn_ratelimited("%s: trimming skb failed for peer %u\n", - netdev_name(peer->ovpn->dev), peer->id); - goto err; - } - - /* we need the first 4 bytes of data to be accessible + /* we need at least 4 bytes of data in the packet * to extract the opcode and the key ID later on */ - if (!pskb_may_pull(skb, OVPN_OPCODE_SIZE)) { + if (unlikely(pkt_len < OVPN_OPCODE_SIZE)) { net_warn_ratelimited("%s: packet too small to fetch opcode for peer %u\n", netdev_name(peer->ovpn->dev), peer->id); goto err; } + /* extract the packet into a new skb */ + skb = ovpn_tcp_skb_packet(peer, skb, pkt_len, msg->offset + 2); + if (unlikely(!skb)) + goto err; + /* DATA_V2 packets are handled in kernel, the rest goes to user space */ opcode = ovpn_opcode_from_skb(skb, 0); if (unlikely(opcode != OVPN_DATA_V2)) { @@ -113,7 +132,7 @@ static void ovpn_tcp_rcv(struct strparser *strp, struct sk_buff *skb) /* The packet size header must be there when sending the packet * to userspace, therefore we put it back */ - skb_push(skb, 2); + *(__be16 *)__skb_push(skb, sizeof(u16)) = htons(pkt_len); ovpn_tcp_to_userspace(peer, strp->sk, skb); return; } @@ -199,7 +218,19 @@ void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock) sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready; sk->sk_write_space = peer->tcp.sk_cb.sk_write_space; sk->sk_prot = peer->tcp.sk_cb.prot; - sk->sk_socket->ops = peer->tcp.sk_cb.ops; + + /* tcp_close() may race this function and could set + * sk->sk_socket to NULL. It does so by invoking + * sock_orphan(), which holds sk_callback_lock before + * doing the assignment. + * + * For this reason we acquire the same lock to avoid + * sk_socket to disappear under our feet + */ + write_lock_bh(&sk->sk_callback_lock); + if (sk->sk_socket) + sk->sk_socket->ops = peer->tcp.sk_cb.ops; + write_unlock_bh(&sk->sk_callback_lock); rcu_assign_sk_user_data(sk, NULL); } @@ -487,6 +518,7 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, /* make sure no pre-existing encapsulation handler exists */ if (ovpn_sock->sk->sk_user_data) return -EBUSY; + rcu_assign_sk_user_data(ovpn_sock->sk, ovpn_sock); /* only a fully connected socket is expected. Connection should be * handled in userspace @@ -495,13 +527,14 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n", netdev_name(peer->ovpn->dev), ovpn_sock->sk->sk_state); - return -EINVAL; + ret = -EINVAL; + goto err; } ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb); if (ret < 0) { DEBUG_NET_WARN_ON_ONCE(1); - return ret; + goto err; } INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work); @@ -536,6 +569,9 @@ int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock, strp_check_rcv(&peer->tcp.strp); return 0; +err: + rcu_assign_sk_user_data(ovpn_sock->sk, NULL); + return ret; } static void ovpn_tcp_close(struct sock *sk, long timeout) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index d6a0f7a0b75d..272b535ecaad 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -386,6 +386,7 @@ int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, struct socket *sock, struct ovpn_priv *ovpn) { struct udp_tunnel_sock_cfg cfg = { + .sk_user_data = ovpn_sock, .encap_type = UDP_ENCAP_OVPNINUDP, .encap_rcv = ovpn_udp_encap_recv, .encap_destroy = ovpn_udp_encap_destroy, diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c index 73e1364ad1ed..a92081560e64 100644 --- a/drivers/net/pcs/pcs-lynx.c +++ b/drivers/net/pcs/pcs-lynx.c @@ -288,7 +288,7 @@ static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio) struct lynx_pcs *lynx; int i; - lynx = kzalloc(sizeof(*lynx), GFP_KERNEL); + lynx = kzalloc_obj(*lynx); if (!lynx) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c index 44006bb6ac0b..c12f8087af9b 100644 --- a/drivers/net/pcs/pcs-mtk-lynxi.c +++ b/drivers/net/pcs/pcs-mtk-lynxi.c @@ -334,7 +334,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, dev_dbg(dev, "MediaTek LynxI SGMII PCS (id 0x%08x, ver 0x%04x)\n", id, ver); - mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL); + mpcs = kzalloc_obj(*mpcs); if (!mpcs) return NULL; diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c index 8d7f82c1df2f..2b72fa98ddf1 100644 --- a/drivers/net/pcs/pcs-rzn1-miic.c +++ b/drivers/net/pcs/pcs-rzn1-miic.c @@ -487,7 +487,7 @@ struct phylink_pcs *miic_create(struct device *dev, struct device_node *np) return ERR_PTR(-EINVAL); } - miic_port = kzalloc(sizeof(*miic_port), GFP_KERNEL); + miic_port = kzalloc_obj(*miic_port); if (!miic_port) { put_device(&pdev->dev); return ERR_PTR(-ENOMEM); @@ -679,8 +679,7 @@ static int miic_parse_dt(struct miic *miic, u32 *mode_cfg) s8 *dt_val; u32 conf; - dt_val = kmalloc_array(miic->of_data->conf_conv_count, - sizeof(*dt_val), GFP_KERNEL); + dt_val = kmalloc_objs(*dt_val, miic->of_data->conf_conv_count); if (!dt_val) return -ENOMEM; diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 9679f2b35a44..e69fa2f0a0e8 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -1528,7 +1528,7 @@ static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev) { struct dw_xpcs *xpcs; - xpcs = kzalloc(sizeof(*xpcs), GFP_KERNEL); + xpcs = kzalloc_obj(*xpcs); if (!xpcs) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/phy/as21xxx.c b/drivers/net/phy/as21xxx.c index 005277360656..d5738117eca6 100644 --- a/drivers/net/phy/as21xxx.c +++ b/drivers/net/phy/as21xxx.c @@ -907,7 +907,7 @@ static int as21xxx_match_phy_device(struct phy_device *phydev, return phy_id == phydrv->phy_id; /* Allocate temp priv and load the firmware */ - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index b950acc9c49b..98472abdd392 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c @@ -1027,13 +1027,12 @@ static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus) if (clock) goto out; - clock = kzalloc(sizeof(struct dp83640_clock), GFP_KERNEL); + clock = kzalloc_obj(struct dp83640_clock); if (!clock) goto out; - clock->caps.pin_config = kcalloc(DP83640_N_PINS, - sizeof(struct ptp_pin_desc), - GFP_KERNEL); + clock->caps.pin_config = kzalloc_objs(struct ptp_pin_desc, + DP83640_N_PINS); if (!clock->caps.pin_config) { kfree(clock); clock = NULL; @@ -1412,7 +1411,7 @@ static int dp83640_probe(struct phy_device *phydev) if (!clock) goto no_clock; - dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL); + dp83640 = kzalloc_obj(struct dp83640_private); if (!dp83640) goto no_memory; diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c index 65636070a222..b8a5a1838196 100644 --- a/drivers/net/phy/mdio_device.c +++ b/drivers/net/phy/mdio_device.c @@ -41,7 +41,7 @@ struct mdio_device *mdio_device_create(struct mii_bus *bus, int addr) struct mdio_device *mdiodev; /* We allocate the device, and initialize the default values */ - mdiodev = kzalloc(sizeof(*mdiodev), GFP_KERNEL); + mdiodev = kzalloc_obj(*mdiodev); if (!mdiodev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 663dcdc92204..c6b011a9d636 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -4114,7 +4114,7 @@ static void lan8814_get_rx_ts(struct kszphy_ptp_priv *ptp_priv) u32 reg; do { - rx_ts = kzalloc(sizeof(*rx_ts), GFP_KERNEL); + rx_ts = kzalloc_obj(*rx_ts); if (!rx_ts) return; diff --git a/drivers/net/phy/microchip_rds_ptp.c b/drivers/net/phy/microchip_rds_ptp.c index f5f2928e705f..2ad95d5c9d86 100644 --- a/drivers/net/phy/microchip_rds_ptp.c +++ b/drivers/net/phy/microchip_rds_ptp.c @@ -999,7 +999,7 @@ static struct mchp_rds_ptp_rx_ts if (rc < 0) goto error; - rx_ts = kmalloc(sizeof(*rx_ts), GFP_KERNEL); + rx_ts = kmalloc_obj(*rx_ts); if (!rx_ts) return NULL; diff --git a/drivers/net/phy/mii_timestamper.c b/drivers/net/phy/mii_timestamper.c index 51ae0593a04f..3ad10e9e36d0 100644 --- a/drivers/net/phy/mii_timestamper.c +++ b/drivers/net/phy/mii_timestamper.c @@ -28,7 +28,7 @@ int register_mii_tstamp_controller(struct device *device, { struct mii_timestamping_desc *desc; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return -ENOMEM; diff --git a/drivers/net/phy/mscc/mscc_macsec.c b/drivers/net/phy/mscc/mscc_macsec.c index 9a38a29cf397..2ae5eed6da1a 100644 --- a/drivers/net/phy/mscc/mscc_macsec.c +++ b/drivers/net/phy/mscc/mscc_macsec.c @@ -610,7 +610,7 @@ static struct macsec_flow *vsc8584_macsec_alloc_flow(struct vsc8531_private *pri if (index == MSCC_MS_MAX_FLOWS) return ERR_PTR(-ENOMEM); - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (!flow) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/phy/nxp-c45-tja11xx-macsec.c b/drivers/net/phy/nxp-c45-tja11xx-macsec.c index fc897ba79b03..63e3934be653 100644 --- a/drivers/net/phy/nxp-c45-tja11xx-macsec.c +++ b/drivers/net/phy/nxp-c45-tja11xx-macsec.c @@ -431,7 +431,7 @@ static struct nxp_c45_sa *nxp_c45_sa_alloc(struct list_head *sa_list, void *sa, return ERR_PTR(-ENOSPC); } - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return ERR_PTR(-ENOMEM); @@ -991,7 +991,7 @@ static int nxp_c45_mdo_add_secy(struct macsec_context *ctx) if (idx == TX_SC_MAX) return -ENOSPC; - phy_secy = kzalloc(sizeof(*phy_secy), GFP_KERNEL); + phy_secy = kzalloc_obj(*phy_secy); if (!phy_secy) return -ENOMEM; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 13dd1691886d..1f1039084f51 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -736,7 +736,7 @@ int phy_ethtool_set_plca_cfg(struct phy_device *phydev, goto out; } - curr_plca_cfg = kmalloc(sizeof(*curr_plca_cfg), GFP_KERNEL); + curr_plca_cfg = kmalloc_obj(*curr_plca_cfg); if (!curr_plca_cfg) { ret = -ENOMEM; goto out; diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 8a3eb1839a3d..3bd415710bf3 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -438,7 +438,7 @@ static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend, static int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask, int (*run)(struct phy_device *)) { - struct phy_fixup *fixup = kzalloc(sizeof(*fixup), GFP_KERNEL); + struct phy_fixup *fixup = kzalloc_obj(*fixup); if (!fixup) return -ENOMEM; @@ -754,7 +754,7 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id, int ret = 0; /* We allocate the device, and initialize the default values */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -1866,8 +1866,6 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, goto error; phy_resume(phydev); - if (!phydev->is_on_sfp_module) - phy_led_triggers_register(phydev); /** * If the external phy used by current mac interface is managed by @@ -1982,9 +1980,6 @@ void phy_detach(struct phy_device *phydev) phydev->phy_link_change = NULL; phydev->phylink = NULL; - if (!phydev->is_on_sfp_module) - phy_led_triggers_unregister(phydev); - if (phydev->mdio.dev.driver) module_put(phydev->mdio.dev.driver->owner); @@ -3499,6 +3494,9 @@ static int of_phy_ports(struct phy_device *phydev) port->parent_type = PHY_PORT_PHY; port->phy = phydev; + + linkmode_copy(port->supported, phydev->supported); + err = phy_add_port(phydev, port); if (err) { phy_port_destroy(port); @@ -3775,16 +3773,27 @@ static int phy_probe(struct device *dev) /* Set the state to READY by default */ phydev->state = PHY_READY; + /* Register the PHY LED triggers */ + if (!phydev->is_on_sfp_module) + phy_led_triggers_register(phydev); + /* Get the LEDs from the device tree, and instantiate standard * LEDs for them. */ - if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev)) + if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev)) { err = of_phy_leds(phydev); + if (err) + goto out; + } + + return 0; out: + if (!phydev->is_on_sfp_module) + phy_led_triggers_unregister(phydev); + /* Re-assert the reset signal on error */ - if (err) - phy_device_reset(phydev, 1); + phy_device_reset(phydev, 1); return err; } @@ -3798,6 +3807,9 @@ static int phy_remove(struct device *dev) if (IS_ENABLED(CONFIG_PHYLIB_LEDS) && !phy_driver_is_genphy(phydev)) phy_leds_unregister(phydev); + if (!phydev->is_on_sfp_module) + phy_led_triggers_unregister(phydev); + phydev->state = PHY_DOWN; phy_cleanup_ports(phydev); diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c index 60893691d4c3..4eb7716bb9d6 100644 --- a/drivers/net/phy/phy_led_triggers.c +++ b/drivers/net/phy/phy_led_triggers.c @@ -93,8 +93,7 @@ int phy_led_triggers_register(struct phy_device *phy) if (!phy->phy_num_led_triggers) return 0; - phy->led_link_trigger = kzalloc(sizeof(*phy->led_link_trigger), - GFP_KERNEL); + phy->led_link_trigger = kzalloc_obj(*phy->led_link_trigger); if (!phy->led_link_trigger) { err = -ENOMEM; goto out_clear; @@ -104,9 +103,8 @@ int phy_led_triggers_register(struct phy_device *phy) if (err) goto out_free_link; - phy->phy_led_triggers = kcalloc(phy->phy_num_led_triggers, - sizeof(struct phy_led_trigger), - GFP_KERNEL); + phy->phy_led_triggers = kzalloc_objs(struct phy_led_trigger, + phy->phy_num_led_triggers); if (!phy->phy_led_triggers) { err = -ENOMEM; goto out_unreg_link; diff --git a/drivers/net/phy/phy_link_topology.c b/drivers/net/phy/phy_link_topology.c index 0e9e987f37dd..1f1eb5d59b38 100644 --- a/drivers/net/phy/phy_link_topology.c +++ b/drivers/net/phy/phy_link_topology.c @@ -15,7 +15,7 @@ static int netdev_alloc_phy_link_topology(struct net_device *dev) { struct phy_link_topology *topo; - topo = kzalloc(sizeof(*topo), GFP_KERNEL); + topo = kzalloc_obj(*topo); if (!topo) return -ENOMEM; @@ -43,7 +43,7 @@ int phy_link_topo_add_phy(struct net_device *dev, topo = dev->link_topo; } - pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); + pdn = kzalloc_obj(*pdn); if (!pdn) return -ENOMEM; diff --git a/drivers/net/phy/phy_package.c b/drivers/net/phy/phy_package.c index 3024da0bbf7b..63e4f862f731 100644 --- a/drivers/net/phy/phy_package.c +++ b/drivers/net/phy/phy_package.c @@ -219,7 +219,7 @@ int phy_package_join(struct phy_device *phydev, int base_addr, size_t priv_size) shared = bus->shared[base_addr]; if (!shared) { ret = -ENOMEM; - shared = kzalloc(sizeof(*shared), GFP_KERNEL); + shared = kzalloc_obj(*shared); if (!shared) goto err_unlock; if (priv_size) { diff --git a/drivers/net/phy/phy_port.c b/drivers/net/phy/phy_port.c index ec93c8ca051e..e56e29d0e9fa 100644 --- a/drivers/net/phy/phy_port.c +++ b/drivers/net/phy/phy_port.c @@ -19,7 +19,7 @@ struct phy_port *phy_port_alloc(void) { struct phy_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return NULL; @@ -53,7 +53,7 @@ struct phy_port *phy_of_parse_port(struct device_node *dn) enum ethtool_link_medium medium; struct phy_port *port; const char *med_str; - u32 pairs = 0, mediums = 0; + u32 pairs = 0; int ret; ret = fwnode_property_read_string(fwnode, "media", &med_str); @@ -85,17 +85,12 @@ struct phy_port *phy_of_parse_port(struct device_node *dn) return ERR_PTR(-EINVAL); } - mediums |= BIT(medium); - - if (!mediums) - return ERR_PTR(-EINVAL); - port = phy_port_alloc(); if (!port) return ERR_PTR(-ENOMEM); port->pairs = pairs; - port->mediums = mediums; + port->mediums = BIT(medium); return port; } @@ -113,16 +108,10 @@ EXPORT_SYMBOL_GPL(phy_of_parse_port); */ void phy_port_update_supported(struct phy_port *port) { - __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0 }; + __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = {0}; unsigned long mode; int i; - for_each_set_bit(i, &port->mediums, __ETHTOOL_LINK_MEDIUM_LAST) { - linkmode_zero(supported); - phy_caps_medium_get_supported(supported, i, port->pairs); - linkmode_or(port->supported, port->supported, supported); - } - /* If there's no pairs specified, we grab the default number of * pairs as the max of the default pairs for each linkmode */ @@ -132,6 +121,22 @@ void phy_port_update_supported(struct phy_port *port) port->pairs = max_t(int, port->pairs, ethtool_linkmode_n_pairs(mode)); + for_each_set_bit(i, &port->mediums, __ETHTOOL_LINK_MEDIUM_LAST) { + __ETHTOOL_DECLARE_LINK_MODE_MASK(med_supported) = {0}; + + phy_caps_medium_get_supported(med_supported, i, port->pairs); + linkmode_or(supported, supported, med_supported); + } + + /* If port->supported is already populated, filter it out with the + * medium/pair support. Otherwise, let's just use this medium-based + * support as the port's supported list. + */ + if (linkmode_empty(port->supported)) + linkmode_copy(port->supported, supported); + else + linkmode_and(port->supported, supported, port->supported); + /* Serdes ports supported through SFP may not have any medium set, * as they will output PHY_INTERFACE_MODE_XXX modes. In that case, derive * the supported list based on these interfaces diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index e1f01d7fc4da..aba1b35c7cd7 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -1853,7 +1853,7 @@ struct phylink *phylink_create(struct phylink_config *config, return ERR_PTR(-EINVAL); } - pl = kzalloc(sizeof(*pl), GFP_KERNEL); + pl = kzalloc_obj(*pl); if (!pl) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c index d8f1ce5a7128..6004da5741af 100644 --- a/drivers/net/phy/qcom/qca807x.c +++ b/drivers/net/phy/qcom/qca807x.c @@ -375,7 +375,7 @@ static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); - return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); + return !!FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); } static int qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index b945d75966d5..8679d27bf1ba 100644 --- a/drivers/net/phy/sfp-bus.c +++ b/drivers/net/phy/sfp-bus.c @@ -388,7 +388,7 @@ static struct sfp_bus *sfp_bus_get(const struct fwnode_handle *fwnode) { struct sfp_bus *sfp, *new, *found = NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); mutex_lock(&sfp_mutex); diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c index 43aefdd8b70f..5db841377199 100644 --- a/drivers/net/phy/sfp.c +++ b/drivers/net/phy/sfp.c @@ -367,6 +367,12 @@ static void sfp_fixup_ignore_tx_fault(struct sfp *sfp) sfp->state_ignore_mask |= SFP_F_TX_FAULT; } +static void sfp_fixup_ignore_tx_fault_and_los(struct sfp *sfp) +{ + sfp_fixup_ignore_tx_fault(sfp); + sfp_fixup_ignore_los(sfp); +} + static void sfp_fixup_ignore_hw(struct sfp *sfp, unsigned int mask) { sfp->state_hw_mask &= ~mask; @@ -530,7 +536,7 @@ static const struct sfp_quirk sfp_quirks[] = { // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in // their EEPROM SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex, - sfp_fixup_ignore_tx_fault), + sfp_fixup_ignore_tx_fault_and_los), // Lantech 8330-262D-E and 8330-265D can operate at 2500base-X, but // incorrectly report 2500MBd NRZ in their EEPROM. @@ -3029,7 +3035,7 @@ static struct sfp *sfp_alloc(struct device *dev) { struct sfp *sfp; - sfp = kzalloc(sizeof(*sfp), GFP_KERNEL); + sfp = kzalloc_obj(*sfp); if (!sfp) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/ppp/bsd_comp.c b/drivers/net/ppp/bsd_comp.c index f385b759d5cf..63a6d251c746 100644 --- a/drivers/net/ppp/bsd_comp.c +++ b/drivers/net/ppp/bsd_comp.c @@ -395,8 +395,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) * Allocate the main control structure for this instance. */ maxmaxcode = MAXCODE(bits); - db = kzalloc(sizeof (struct bsd_db), - GFP_KERNEL); + db = kzalloc_obj(struct bsd_db); if (!db) { return NULL; diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c index c97406c6004d..b4cf2d09c6bd 100644 --- a/drivers/net/ppp/ppp_async.c +++ b/drivers/net/ppp/ppp_async.c @@ -163,7 +163,7 @@ ppp_asynctty_open(struct tty_struct *tty) return -EOPNOTSUPP; err = -ENOMEM; - ap = kzalloc(sizeof(*ap), GFP_KERNEL); + ap = kzalloc_obj(*ap); if (!ap) goto out; diff --git a/drivers/net/ppp/ppp_deflate.c b/drivers/net/ppp/ppp_deflate.c index d93aeacc0dba..d6d5e656b3f4 100644 --- a/drivers/net/ppp/ppp_deflate.c +++ b/drivers/net/ppp/ppp_deflate.c @@ -97,8 +97,7 @@ static void *z_comp_alloc(unsigned char *options, int opt_len) if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) return NULL; - state = kzalloc(sizeof(*state), - GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return NULL; @@ -313,7 +312,7 @@ static void *z_decomp_alloc(unsigned char *options, int opt_len) if (w_size < DEFLATE_MIN_SIZE || w_size > DEFLATE_MAX_SIZE) return NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return NULL; diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index f8814d7be6f1..e9b41777be80 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -2926,7 +2926,7 @@ int ppp_register_net_channel(struct net *net, struct ppp_channel *chan) struct channel *pch; struct ppp_net *pn; - pch = kzalloc(sizeof(struct channel), GFP_KERNEL); + pch = kzalloc_obj(struct channel); if (!pch) return -ENOMEM; @@ -3277,7 +3277,7 @@ ppp_register_compressor(struct compressor *cp) if (find_comp_entry(cp->compress_proto)) goto out; ret = -ENOMEM; - ce = kmalloc(sizeof(struct compressor_entry), GFP_ATOMIC); + ce = kmalloc_obj(struct compressor_entry, GFP_ATOMIC); if (!ce) goto out; ret = 0; diff --git a/drivers/net/ppp/ppp_mppe.c b/drivers/net/ppp/ppp_mppe.c index 630cbf71c147..3900279b4819 100644 --- a/drivers/net/ppp/ppp_mppe.c +++ b/drivers/net/ppp/ppp_mppe.c @@ -158,7 +158,7 @@ static void *mppe_alloc(unsigned char *options, int optlen) fips_enabled) return NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (state == NULL) return NULL; diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c index 9c4932198931..c2063961f395 100644 --- a/drivers/net/ppp/ppp_synctty.c +++ b/drivers/net/ppp/ppp_synctty.c @@ -162,7 +162,7 @@ ppp_sync_open(struct tty_struct *tty) if (tty->ops->write == NULL) return -EOPNOTSUPP; - ap = kzalloc(sizeof(*ap), GFP_KERNEL); + ap = kzalloc_obj(*ap); err = -ENOMEM; if (!ap) goto out; diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c index 134435e90073..4a3c852780f5 100644 --- a/drivers/net/pse-pd/pd692x0.c +++ b/drivers/net/pse-pd/pd692x0.c @@ -646,9 +646,8 @@ pd692x0_pi_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id, int i; pw_table = pd692x0_class_pw_table; - c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE, - sizeof(*c33_pw_limit_ranges), - GFP_KERNEL); + c33_pw_limit_ranges = kzalloc_objs(*c33_pw_limit_ranges, + PD692X0_CLASS_PW_TABLE_SIZE); if (!c33_pw_limit_ranges) return -ENOMEM; @@ -1259,7 +1258,7 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev) struct pd692x0_manager *manager; int ret; - manager = kcalloc(PD692X0_MAX_MANAGERS, sizeof(*manager), GFP_KERNEL); + manager = kzalloc_objs(*manager, PD692X0_MAX_MANAGERS); if (!manager) return -ENOMEM; diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c index 23eb3c9d0bcd..3beaaaeec9e1 100644 --- a/drivers/net/pse-pd/pse_core.c +++ b/drivers/net/pse-pd/pse_core.c @@ -162,7 +162,7 @@ static int of_load_pse_pis(struct pse_controller_dev *pcdev) if (!np) return -ENODEV; - pcdev->pi = kcalloc(pcdev->nr_lines, sizeof(*pcdev->pi), GFP_KERNEL); + pcdev->pi = kzalloc_objs(*pcdev->pi, pcdev->nr_lines); if (!pcdev->pi) return -ENOMEM; @@ -1408,7 +1408,7 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index, } } - psec = kzalloc(sizeof(*psec), GFP_KERNEL); + psec = kzalloc_obj(*psec); if (!psec) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c index 76ec1555d60d..d40cb35a2547 100644 --- a/drivers/net/pse-pd/tps23881.c +++ b/drivers/net/pse-pd/tps23881.c @@ -523,8 +523,7 @@ tps23881_pi_get_pw_limit_ranges(struct pse_controller_dev *pcdev, int id, { struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges; - c33_pw_limit_ranges = kzalloc(sizeof(*c33_pw_limit_ranges), - GFP_KERNEL); + c33_pw_limit_ranges = kzalloc_obj(*c33_pw_limit_ranges); if (!c33_pw_limit_ranges) return -ENOMEM; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 318a0ef1af50..64b5d0a8ae4a 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -603,7 +603,7 @@ static int rionet_add_dev(struct device *dev, struct subsys_interface *sif) rnet = netdev_priv(nets[netid].ndev); - peer = kzalloc(sizeof(*peer), GFP_KERNEL); + peer = kzalloc_obj(*peer); if (!peer) { rc = -ENOMEM; goto out; diff --git a/drivers/net/slip/slhc.c b/drivers/net/slip/slhc.c index ee9fd3a94b96..e3c785da3eef 100644 --- a/drivers/net/slip/slhc.c +++ b/drivers/net/slip/slhc.c @@ -98,7 +98,7 @@ slhc_init(int rslots, int tslots) if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255) return ERR_PTR(-EINVAL); - comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL); + comp = kzalloc_obj(struct slcompress); if (! comp) goto out_fail; diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index c889fb374703..820e1a8fc956 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1297,8 +1297,7 @@ static int __init slip_init(void) printk(KERN_INFO "SLIP linefill/keepalive option.\n"); #endif - slip_devs = kcalloc(slip_maxdev, sizeof(struct net_device *), - GFP_KERNEL); + slip_devs = kzalloc_objs(struct net_device *, slip_maxdev); if (!slip_devs) return -ENOMEM; diff --git a/drivers/net/tap.c b/drivers/net/tap.c index 1197f245e873..b8240737dc51 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c @@ -1197,7 +1197,7 @@ int tap_queue_resize(struct tap_dev *tap) int n = tap->numqueues; int ret, i = 0; - rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL); + rings = kmalloc_objs(*rings, n); if (!rings) return -ENOMEM; @@ -1217,7 +1217,7 @@ static int tap_list_add(dev_t major, const char *device_name) { struct major_info *tap_major; - tap_major = kzalloc(sizeof(*tap_major), GFP_ATOMIC); + tap_major = kzalloc_obj(*tap_major, GFP_ATOMIC); if (!tap_major) return -ENOMEM; diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index c08a5c1bd6e4..b7282f5c9632 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -157,7 +157,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option, array_size = 1; /* No array but still need one instance */ for (i = 0; i < array_size; i++) { - opt_inst = kmalloc(sizeof(*opt_inst), GFP_KERNEL); + opt_inst = kmalloc_obj(*opt_inst); if (!opt_inst) return -ENOMEM; opt_inst->option = option; @@ -256,8 +256,7 @@ static int __team_options_register(struct team *team, struct team_option **dst_opts; int err; - dst_opts = kcalloc(option_count, sizeof(struct team_option *), - GFP_KERNEL); + dst_opts = kzalloc_objs(struct team_option *, option_count); if (!dst_opts) return -ENOMEM; for (i = 0; i < option_count; i++, option++) { @@ -434,7 +433,7 @@ int team_mode_register(const struct team_mode *mode) mode->priv_size > TEAM_MODE_PRIV_SIZE) return -EINVAL; - mitem = kmalloc(sizeof(*mitem), GFP_KERNEL); + mitem = kmalloc_obj(*mitem); if (!mitem) return -ENOMEM; @@ -780,8 +779,7 @@ static int team_queue_override_init(struct team *team) if (!queue_cnt) return 0; - listarr = kmalloc_array(queue_cnt, sizeof(struct list_head), - GFP_KERNEL); + listarr = kmalloc_objs(struct list_head, queue_cnt); if (!listarr) return -ENOMEM; team->qom_lists = listarr; @@ -1017,7 +1015,7 @@ static int __team_port_enable_netpoll(struct team_port *port) struct netpoll *np; int err; - np = kzalloc(sizeof(*np), GFP_KERNEL); + np = kzalloc_obj(*np); if (!np) return -ENOMEM; @@ -1292,7 +1290,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev, static void __team_port_change_port_removed(struct team_port *port); -static int team_port_del(struct team *team, struct net_device *port_dev) +static int team_port_del(struct team *team, struct net_device *port_dev, bool unregister) { struct net_device *dev = team->dev; struct team_port *port; @@ -1330,7 +1328,13 @@ static int team_port_del(struct team *team, struct net_device *port_dev) __team_port_change_port_removed(port); team_port_set_orig_dev_addr(port); - dev_set_mtu(port_dev, port->orig.mtu); + if (unregister) { + netdev_lock_ops(port_dev); + __netif_set_mtu(port_dev, port->orig.mtu); + netdev_unlock_ops(port_dev); + } else { + dev_set_mtu(port_dev, port->orig.mtu); + } kfree_rcu(port, rcu); netdev_info(dev, "Port device %s removed\n", portname); netdev_compute_master_upper_features(team->dev, true); @@ -1634,7 +1638,7 @@ static void team_uninit(struct net_device *dev) ASSERT_RTNL(); list_for_each_entry_safe(port, tmp, &team->port_list, list) - team_port_del(team, port->dev); + team_port_del(team, port->dev, false); __team_change_mode(team, NULL); /* cleanup */ __team_options_unregister(team, team_options, ARRAY_SIZE(team_options)); @@ -1933,7 +1937,16 @@ static int team_del_slave(struct net_device *dev, struct net_device *port_dev) ASSERT_RTNL(); - return team_port_del(team, port_dev); + return team_port_del(team, port_dev, false); +} + +static int team_del_slave_on_unregister(struct net_device *dev, struct net_device *port_dev) +{ + struct team *team = netdev_priv(dev); + + ASSERT_RTNL(); + + return team_port_del(team, port_dev, true); } static netdev_features_t team_fix_features(struct net_device *dev, @@ -2926,7 +2939,7 @@ static int team_device_event(struct notifier_block *unused, !!netif_oper_up(port->dev)); break; case NETDEV_UNREGISTER: - team_del_slave(port->team->dev, dev); + team_del_slave_on_unregister(port->team->dev, dev); break; case NETDEV_FEAT_CHANGE: if (!port->team->notifier_ctx) { @@ -2999,3 +3012,4 @@ MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Jiri Pirko "); MODULE_DESCRIPTION("Ethernet team device driver"); MODULE_ALIAS_RTNL_LINK(DRV_NAME); +MODULE_IMPORT_NS("NETDEV_INTERNAL"); diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c index b14538bde2f8..684954c2a8de 100644 --- a/drivers/net/team/team_mode_loadbalance.c +++ b/drivers/net/team/team_mode_loadbalance.c @@ -259,7 +259,7 @@ static int __fprog_create(struct sock_fprog_kern **pfprog, u32 data_len, if (data_len % sizeof(struct sock_filter)) return -EINVAL; - fprog = kmalloc(sizeof(*fprog), GFP_KERNEL); + fprog = kmalloc_obj(*fprog); if (!fprog) return -ENOMEM; fprog->filter = kmemdup(filter, data_len, GFP_KERNEL); @@ -594,7 +594,7 @@ static int lb_init(struct team *team) BUG_ON(!func); rcu_assign_pointer(lb_priv->select_tx_port_func, func); - lb_priv->ex = kzalloc(sizeof(*lb_priv->ex), GFP_KERNEL); + lb_priv->ex = kzalloc_obj(*lb_priv->ex); if (!lb_priv->ex) return -ENOMEM; lb_priv->ex->team = team; diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 8192740357a0..c492fda6fc15 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -318,7 +318,7 @@ static struct tun_flow_entry *tun_flow_create(struct tun_struct *tun, struct hlist_head *head, u32 rxhash, u16 queue_index) { - struct tun_flow_entry *e = kmalloc(sizeof(*e), GFP_ATOMIC); + struct tun_flow_entry *e = kmalloc_obj(*e, GFP_ATOMIC); if (e) { netif_info(tun, tx_queued, tun->dev, @@ -2228,7 +2228,7 @@ static int __tun_set_ebpf(struct tun_struct *tun, struct tun_prog *old, *new = NULL; if (prog) { - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) return -ENOMEM; new->prog = prog; @@ -3605,7 +3605,7 @@ static int tun_queue_resize(struct tun_struct *tun) int n = tun->numqueues + tun->numdisabled; int ret, i; - rings = kmalloc_array(n, sizeof(*rings), GFP_KERNEL); + rings = kmalloc_objs(*rings, n); if (!rings) return -ENOMEM; diff --git a/drivers/net/usb/aqc111.c b/drivers/net/usb/aqc111.c index 0722050dbe32..cbffa9ae1bb6 100644 --- a/drivers/net/usb/aqc111.c +++ b/drivers/net/usb/aqc111.c @@ -703,7 +703,7 @@ static int aqc111_bind(struct usbnet *dev, struct usb_interface *intf) return ret; } - aqc111_data = kzalloc(sizeof(*aqc111_data), GFP_KERNEL); + aqc111_data = kzalloc_obj(*aqc111_data); if (!aqc111_data) return -ENOMEM; diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 7eb6e86adb16..df0bcfedddbc 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -1314,7 +1314,7 @@ static int ax88178_bind(struct usbnet *dev, struct usb_interface *intf) dev->rx_urb_size = 2048; } - dev->driver_priv = kzalloc(sizeof(struct asix_common_private), GFP_KERNEL); + dev->driver_priv = kzalloc_obj(struct asix_common_private); if (!dev->driver_priv) return -ENOMEM; diff --git a/drivers/net/usb/ax88172a.c b/drivers/net/usb/ax88172a.c index 3100fbe153c0..6b14bce2a552 100644 --- a/drivers/net/usb/ax88172a.c +++ b/drivers/net/usb/ax88172a.c @@ -165,7 +165,7 @@ static int ax88172a_bind(struct usbnet *dev, struct usb_interface *intf) if (ret) return ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c index 0e9ae89b840e..98f899ea2e94 100644 --- a/drivers/net/usb/ax88179_178a.c +++ b/drivers/net/usb/ax88179_178a.c @@ -1287,7 +1287,7 @@ static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) if (ret < 0) return ret; - ax179_data = kzalloc(sizeof(*ax179_data), GFP_KERNEL); + ax179_data = kzalloc_obj(*ax179_data); if (!ax179_data) return -ENOMEM; diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c index 5c7f19cbacf6..96e82f94edcf 100644 --- a/drivers/net/usb/catc.c +++ b/drivers/net/usb/catc.c @@ -58,6 +58,16 @@ static const char driver_name[] = "catc"; #define CTRL_QUEUE 16 /* Max control requests in flight (power of two) */ #define RX_PKT_SZ 1600 /* Max size of receive packet for F5U011 */ +/* + * USB endpoints. + */ + +enum catc_usb_ep { + CATC_USB_EP_CONTROL = 0, + CATC_USB_EP_BULK = 1, + CATC_USB_EP_INT_IN = 2, +}; + /* * Control requests. */ @@ -765,6 +775,13 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id u8 broadcast[ETH_ALEN]; u8 *macbuf; int pktsz, ret = -ENOMEM; + static const u8 bulk_ep_addr[] = { + CATC_USB_EP_BULK | USB_DIR_OUT, + CATC_USB_EP_BULK | USB_DIR_IN, + 0}; + static const u8 int_ep_addr[] = { + CATC_USB_EP_INT_IN | USB_DIR_IN, + 0}; macbuf = kmalloc(ETH_ALEN, GFP_KERNEL); if (!macbuf) @@ -777,6 +794,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id goto fail_mem; } + /* Verify that all required endpoints are present */ + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) { + dev_err(dev, "Missing or invalid endpoints\n"); + ret = -ENODEV; + goto fail_mem; + } + netdev = alloc_etherdev(sizeof(struct catc)); if (!netdev) goto fail_mem; @@ -821,14 +846,14 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id usb_fill_control_urb(catc->ctrl_urb, usbdev, usb_sndctrlpipe(usbdev, 0), NULL, NULL, 0, catc_ctrl_done, catc); - usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, 1), - NULL, 0, catc_tx_done, catc); + usb_fill_bulk_urb(catc->tx_urb, usbdev, usb_sndbulkpipe(usbdev, CATC_USB_EP_BULK), + NULL, 0, catc_tx_done, catc); - usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, 1), - catc->rx_buf, pktsz, catc_rx_done, catc); + usb_fill_bulk_urb(catc->rx_urb, usbdev, usb_rcvbulkpipe(usbdev, CATC_USB_EP_BULK), + catc->rx_buf, pktsz, catc_rx_done, catc); - usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, 2), - catc->irq_buf, 2, catc_irq_done, catc, 1); + usb_fill_int_urb(catc->irq_urb, usbdev, usb_rcvintpipe(usbdev, CATC_USB_EP_INT_IN), + catc->irq_buf, 2, catc_irq_done, catc, 1); if (!catc->is_f5u011) { u32 *buf; diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 5d123df0a866..7057c6c0cfc6 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -827,7 +827,7 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_ u8 iface_no; struct usb_cdc_parsed_header hdr; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c index 79a47e2fd437..068acb052adb 100644 --- a/drivers/net/usb/cx82310_eth.c +++ b/drivers/net/usb/cx82310_eth.c @@ -173,7 +173,7 @@ static int cx82310_bind(struct usbnet *dev, struct usb_interface *intf) if (!dev->partial_data) return -ENOMEM; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto err_partial; diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 1aeb36119d3f..1825f7cf5dc0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -2313,7 +2313,7 @@ static struct hso_device *hso_create_device(struct usb_interface *intf, { struct hso_device *hso_dev; - hso_dev = kzalloc(sizeof(*hso_dev), GFP_KERNEL); + hso_dev = kzalloc_obj(*hso_dev); if (!hso_dev) return NULL; @@ -2617,7 +2617,7 @@ static struct hso_device *hso_create_bulk_serial_device( if (!hso_dev) return NULL; - serial = kzalloc(sizeof(*serial), GFP_KERNEL); + serial = kzalloc_obj(*serial); if (!serial) goto exit; @@ -2626,13 +2626,11 @@ static struct hso_device *hso_create_bulk_serial_device( if ((port & HSO_PORT_MASK) == HSO_PORT_MODEM) { num_urbs = 2; - serial->tiocmget = kzalloc(sizeof(struct hso_tiocmget), - GFP_KERNEL); + serial->tiocmget = kzalloc_obj(struct hso_tiocmget); if (!serial->tiocmget) goto exit; serial->tiocmget->serial_state_notification - = kzalloc(sizeof(struct hso_serial_state_notification), - GFP_KERNEL); + = kzalloc_obj(struct hso_serial_state_notification); if (!serial->tiocmget->serial_state_notification) goto exit; tiocmget = serial->tiocmget; @@ -2711,7 +2709,7 @@ struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface, if (!hso_dev) return NULL; - serial = kzalloc(sizeof(*serial), GFP_KERNEL); + serial = kzalloc_obj(*serial); if (!serial) goto err_free_dev; @@ -2755,7 +2753,7 @@ static void hso_free_shared_int(struct hso_shared_int *mux) static struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) { - struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL); + struct hso_shared_int *mux = kzalloc_obj(*mux); if (!mux) return NULL; diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index 613fc6910f14..ee9c48f7f68f 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -132,11 +132,18 @@ kalmia_bind(struct usbnet *dev, struct usb_interface *intf) { int status; u8 ethernet_addr[ETH_ALEN]; + static const u8 ep_addr[] = { + 1 | USB_DIR_IN, + 2 | USB_DIR_OUT, + 0}; /* Don't bind to AT command interface */ if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC) return -EINVAL; + if (!usb_check_bulk_endpoints(intf, ep_addr)) + return -ENODEV; + dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK); dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK); dev->status = NULL; diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index c9efb7df892e..cb2472b59e10 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c @@ -765,7 +765,6 @@ static void kaweth_set_rx_mode(struct net_device *net) netdev_dbg(net, "Setting Rx mode to %d\n", packet_filter_bitmap); - netif_stop_queue(net); if (net->flags & IFF_PROMISC) { packet_filter_bitmap |= KAWETH_PACKET_FILTER_PROMISCUOUS; @@ -775,7 +774,6 @@ static void kaweth_set_rx_mode(struct net_device *net) } kaweth->packet_filter_bitmap = packet_filter_bitmap; - netif_wake_queue(net); } /**************************************************************** @@ -885,6 +883,13 @@ static int kaweth_probe( const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; int result = 0; int rv = -EIO; + static const u8 bulk_ep_addr[] = { + 1 | USB_DIR_IN, + 2 | USB_DIR_OUT, + 0}; + static const u8 int_ep_addr[] = { + 3 | USB_DIR_IN, + 0}; dev_dbg(dev, "Kawasaki Device Probe (Device number:%d): 0x%4.4x:0x%4.4x:0x%4.4x\n", @@ -898,6 +903,12 @@ static int kaweth_probe( (int)udev->descriptor.bLength, (int)udev->descriptor.bDescriptorType); + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) { + dev_err(dev, "couldn't find required endpoints\n"); + return -ENODEV; + } + netdev = alloc_etherdev(sizeof(*kaweth)); if (!netdev) return -ENOMEM; diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 00397a807393..19cdf69fa589 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c @@ -682,7 +682,7 @@ static int lan78xx_read_stats(struct lan78xx_net *dev, u32 *src; u32 *dst; - stats = kmalloc(sizeof(*stats), GFP_KERNEL); + stats = kmalloc_obj(*stats); if (!stats) return -ENOMEM; @@ -2094,8 +2094,6 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev) dev->mdiobus->phy_mask = ~(1 << 1); break; case ID_REV_CHIP_ID_7801_: - /* scan thru PHYAD[2..0] */ - dev->mdiobus->phy_mask = ~(0xFF); break; } @@ -3121,6 +3119,10 @@ static int lan78xx_init_ltm(struct lan78xx_net *dev) int ret; u32 buf; + /* LAN7850 is USB 2.0 and does not support LTM */ + if (dev->chipid == ID_REV_CHIP_ID_7850_) + return 0; + ret = lan78xx_read_reg(dev, USB_CFG1, &buf); if (ret < 0) goto init_ltm_failed; @@ -3728,7 +3730,7 @@ static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf) int ret; int i; - dev->data[0] = (unsigned long)kzalloc(sizeof(*pdata), GFP_KERNEL); + dev->data[0] = (unsigned long) kzalloc_obj(*pdata); pdata = (struct lan78xx_priv *)(dev->data[0]); if (!pdata) { @@ -3831,6 +3833,7 @@ static void lan78xx_rx_csum_offload(struct lan78xx_net *dev, */ if (!(dev->net->features & NETIF_F_RXCSUM) || unlikely(rx_cmd_a & RX_CMD_A_ICSM_) || + unlikely(rx_cmd_a & RX_CMD_A_CSE_MASK_) || ((rx_cmd_a & RX_CMD_A_FVTG_) && !(dev->net->features & NETIF_F_HW_VLAN_CTAG_RX))) { skb->ip_summed = CHECKSUM_NONE; @@ -3903,7 +3906,8 @@ static int lan78xx_rx(struct lan78xx_net *dev, struct sk_buff *skb, return 0; } - if (unlikely(rx_cmd_a & RX_CMD_A_RED_)) { + if (unlikely(rx_cmd_a & RX_CMD_A_RED_) && + (rx_cmd_a & RX_CMD_A_RX_HARD_ERRS_MASK_)) { netif_dbg(dev, rx_err, dev->net, "Error rx_cmd_a=0x%08x", rx_cmd_a); } else { @@ -4178,7 +4182,7 @@ static struct skb_data *lan78xx_tx_buf_fill(struct lan78xx_net *dev, } tx_data += len; - entry->length += len; + entry->length += max_t(unsigned int, len, ETH_ZLEN); entry->num_of_packet += skb_shinfo(skb)->gso_segs ?: 1; dev_kfree_skb_any(skb); @@ -4548,8 +4552,6 @@ static void lan78xx_disconnect(struct usb_interface *intf) phylink_disconnect_phy(dev->phylink); rtnl_unlock(); - netif_napi_del(&dev->napi); - unregister_netdev(net); timer_shutdown_sync(&dev->stat_monitor); diff --git a/drivers/net/usb/lan78xx.h b/drivers/net/usb/lan78xx.h index 968e5e5faee0..17a934acff3d 100644 --- a/drivers/net/usb/lan78xx.h +++ b/drivers/net/usb/lan78xx.h @@ -74,6 +74,9 @@ #define RX_CMD_A_ICSM_ (0x00004000) #define RX_CMD_A_LEN_MASK_ (0x00003FFF) +#define RX_CMD_A_RX_HARD_ERRS_MASK_ \ + (RX_CMD_A_RX_ERRS_MASK_ & ~RX_CMD_A_CSE_MASK_) + /* Rx Command B */ #define RX_CMD_B_CSUM_SHIFT_ (16) #define RX_CMD_B_CSUM_MASK_ (0xFFFF0000) diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c index b2495fa80171..c4ad2d9f6f4f 100644 --- a/drivers/net/usb/lg-vl600.c +++ b/drivers/net/usb/lg-vl600.c @@ -56,7 +56,7 @@ struct vl600_state { static int vl600_bind(struct usbnet *dev, struct usb_interface *intf) { int ret; - struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL); + struct vl600_state *s = kzalloc_obj(struct vl600_state); if (!s) return -ENOMEM; diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 7b6d6eb60709..db85f40734d7 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -28,6 +28,17 @@ static const char driver_name[] = "pegasus"; BMSR_100FULL | BMSR_ANEGCAPABLE) #define CARRIER_CHECK_DELAY (2 * HZ) +/* + * USB endpoints. + */ + +enum pegasus_usb_ep { + PEGASUS_USB_EP_CONTROL = 0, + PEGASUS_USB_EP_BULK_IN = 1, + PEGASUS_USB_EP_BULK_OUT = 2, + PEGASUS_USB_EP_INT_IN = 3, +}; + static bool loopback; static bool mii_mode; static char *devid; @@ -140,7 +151,7 @@ static int update_eth_regs_async(pegasus_t *pegasus) struct urb *async_urb; struct usb_ctrlrequest *req; - req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); + req = kmalloc_obj(struct usb_ctrlrequest, GFP_ATOMIC); if (req == NULL) return ret; @@ -542,7 +553,7 @@ static void read_bulk_callback(struct urb *urb) goto tl_sched; goon: usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), + usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN), pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); rx_status = usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC); @@ -582,7 +593,7 @@ static void rx_fixup(struct tasklet_struct *t) return; } usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), + usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN), pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); try_again: @@ -710,7 +721,7 @@ static netdev_tx_t pegasus_start_xmit(struct sk_buff *skb, ((__le16 *) pegasus->tx_buff)[0] = cpu_to_le16(l16); skb_copy_from_linear_data(skb, pegasus->tx_buff + 2, skb->len); usb_fill_bulk_urb(pegasus->tx_urb, pegasus->usb, - usb_sndbulkpipe(pegasus->usb, 2), + usb_sndbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_OUT), pegasus->tx_buff, count, write_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->tx_urb, GFP_ATOMIC))) { @@ -801,8 +812,19 @@ static void unlink_all_urbs(pegasus_t *pegasus) static int alloc_urbs(pegasus_t *pegasus) { + static const u8 bulk_ep_addr[] = { + 1 | USB_DIR_IN, + 2 | USB_DIR_OUT, + 0}; + static const u8 int_ep_addr[] = { + 3 | USB_DIR_IN, + 0}; int res = -ENOMEM; + if (!usb_check_bulk_endpoints(pegasus->intf, bulk_ep_addr) || + !usb_check_int_endpoints(pegasus->intf, int_ep_addr)) + return -ENODEV; + pegasus->rx_urb = usb_alloc_urb(0, GFP_KERNEL); if (!pegasus->rx_urb) { return res; @@ -837,7 +859,7 @@ static int pegasus_open(struct net_device *net) set_registers(pegasus, EthID, 6, net->dev_addr); usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, - usb_rcvbulkpipe(pegasus->usb, 1), + usb_rcvbulkpipe(pegasus->usb, PEGASUS_USB_EP_BULK_IN), pegasus->rx_skb->data, PEGASUS_MTU, read_bulk_callback, pegasus); if ((res = usb_submit_urb(pegasus->rx_urb, GFP_KERNEL))) { @@ -848,7 +870,7 @@ static int pegasus_open(struct net_device *net) } usb_fill_int_urb(pegasus->intr_urb, pegasus->usb, - usb_rcvintpipe(pegasus->usb, 3), + usb_rcvintpipe(pegasus->usb, PEGASUS_USB_EP_INT_IN), pegasus->intr_buff, sizeof(pegasus->intr_buff), intr_callback, pegasus, pegasus->intr_interval); if ((res = usb_submit_urb(pegasus->intr_urb, GFP_KERNEL))) { @@ -1133,16 +1155,31 @@ static int pegasus_probe(struct usb_interface *intf, pegasus_t *pegasus; int dev_index = id - pegasus_ids; int res = -ENOMEM; + static const u8 bulk_ep_addr[] = { + PEGASUS_USB_EP_BULK_IN | USB_DIR_IN, + PEGASUS_USB_EP_BULK_OUT | USB_DIR_OUT, + 0}; + static const u8 int_ep_addr[] = { + PEGASUS_USB_EP_INT_IN | USB_DIR_IN, + 0}; if (pegasus_blacklisted(dev)) return -ENODEV; + /* Verify that all required endpoints are present */ + if (!usb_check_bulk_endpoints(intf, bulk_ep_addr) || + !usb_check_int_endpoints(intf, int_ep_addr)) { + dev_err(&intf->dev, "Missing or invalid endpoints\n"); + return -ENODEV; + } + net = alloc_etherdev(sizeof(struct pegasus)); if (!net) goto out; pegasus = netdev_priv(net); pegasus->dev_index = dev_index; + pegasus->intf = intf; res = alloc_urbs(pegasus); if (res < 0) { @@ -1154,7 +1191,6 @@ static int pegasus_probe(struct usb_interface *intf, INIT_DELAYED_WORK(&pegasus->carrier_check, check_carrier); - pegasus->intf = intf; pegasus->usb = dev; pegasus->net = net; diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 3a4985b582cb..05acac10cd2b 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -928,7 +928,7 @@ static int qmi_wwan_resume(struct usb_interface *intf) static const struct driver_info qmi_wwan_info = { .description = "WWAN/QMI device", - .flags = FLAG_WWAN | FLAG_SEND_ZLP, + .flags = FLAG_WWAN | FLAG_NOMAXMTU | FLAG_SEND_ZLP, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, @@ -937,7 +937,7 @@ static const struct driver_info qmi_wwan_info = { static const struct driver_info qmi_wwan_info_quirk_dtr = { .description = "WWAN/QMI device", - .flags = FLAG_WWAN | FLAG_SEND_ZLP, + .flags = FLAG_WWAN | FLAG_NOMAXMTU | FLAG_SEND_ZLP, .bind = qmi_wwan_bind, .unbind = qmi_wwan_unbind, .manage_power = qmi_wwan_manage_power, diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 8d36162f36df..0c83bbbea2e7 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -9647,7 +9647,7 @@ static u8 __rtl_get_hw_ver(struct usb_device *udev) int ret; int i; - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kmalloc_obj(*tmp); if (!tmp) return 0; @@ -10054,6 +10054,7 @@ static const struct usb_device_id rtl8152_table[] = { { USB_DEVICE(VENDOR_ID_DLINK, 0xb301) }, { USB_DEVICE(VENDOR_ID_DELL, 0xb097) }, { USB_DEVICE(VENDOR_ID_ASUS, 0x1976) }, + { USB_DEVICE(VENDOR_ID_TRENDNET, 0xe02b) }, {} }; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 2f1f134b5b48..4cda0643afb6 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -187,7 +187,7 @@ static int async_set_registers(rtl8150_t *dev, u16 indx, u16 size, u16 reg) struct urb *async_urb; struct async_req *req; - req = kmalloc(sizeof(struct async_req), GFP_ATOMIC); + req = kmalloc_obj(struct async_req, GFP_ATOMIC); if (req == NULL) return res; async_urb = usb_alloc_urb(0, GFP_ATOMIC); diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 3ca60ebdd468..4d3ed642b3e7 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -683,7 +683,7 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) return -ENODEV; } /* Initialize sierra private data */ - priv = kzalloc(sizeof *priv, GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/net/usb/smsc75xx.c b/drivers/net/usb/smsc75xx.c index 1a61a8bcf5d3..6f72a3f15907 100644 --- a/drivers/net/usb/smsc75xx.c +++ b/drivers/net/usb/smsc75xx.c @@ -1450,8 +1450,7 @@ static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf) return ret; } - dev->data[0] = (unsigned long)kzalloc(sizeof(struct smsc75xx_priv), - GFP_KERNEL); + dev->data[0] = (unsigned long) kzalloc_obj(struct smsc75xx_priv); pdata = (struct smsc75xx_priv *)(dev->data[0]); if (!pdata) diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index 7ecf98d97493..42e4048b574b 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -1157,7 +1157,7 @@ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf) return ret; } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return -ENOMEM; diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8e44feaf7ff1..b72ba0803392 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1377,8 +1377,7 @@ static int build_dma_sg(const struct sk_buff *skb, struct urb *urb) return 0; /* reserve one for zero packet */ - urb->sg = kmalloc_array(num_sgs + 1, sizeof(struct scatterlist), - GFP_ATOMIC); + urb->sg = kmalloc_objs(struct scatterlist, num_sgs + 1, GFP_ATOMIC); if (!urb->sg) return -ENOMEM; @@ -1830,11 +1829,12 @@ usbnet_probe(struct usb_interface *udev, const struct usb_device_id *prod) if ((dev->driver_info->flags & FLAG_NOARP) != 0) net->flags |= IFF_NOARP; - if (net->max_mtu > (dev->hard_mtu - net->hard_header_len)) + if ((dev->driver_info->flags & FLAG_NOMAXMTU) == 0 && + net->max_mtu > (dev->hard_mtu - net->hard_header_len)) net->max_mtu = dev->hard_mtu - net->hard_header_len; - if (net->mtu > net->max_mtu) - net->mtu = net->max_mtu; + if (net->mtu > (dev->hard_mtu - net->hard_header_len)) + net->mtu = dev->hard_mtu - net->hard_header_len; } else if (!info->in || !info->out) status = usbnet_get_endpoints(dev, udev); @@ -2234,7 +2234,7 @@ int usbnet_write_cmd_async(struct usbnet *dev, u8 cmd, u8 reqtype, } } - req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); + req = kmalloc_obj(struct usb_ctrlrequest, GFP_ATOMIC); if (!req) goto fail_free_buf; diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 9982412fd7f2..e35df717e65e 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -1434,8 +1434,8 @@ static int veth_alloc_queues(struct net_device *dev) struct veth_priv *priv = netdev_priv(dev); int i; - priv->rq = kvcalloc(dev->num_rx_queues, sizeof(*priv->rq), - GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); + priv->rq = kvzalloc_objs(*priv->rq, dev->num_rx_queues, + GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); if (!priv->rq) return -ENOMEM; diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index db88dcaefb20..72d6a9c6a5a2 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3732,7 +3732,7 @@ static int virtnet_set_queues(struct virtnet_info *vi, u16 queue_pairs) goto succ; } - mq = kzalloc(sizeof(*mq), GFP_KERNEL); + mq = kzalloc_obj(*mq); if (!mq) return -ENOMEM; @@ -3799,7 +3799,7 @@ static void virtnet_rx_mode_work(struct work_struct *work) if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_RX)) return; - promisc_allmulti = kzalloc(sizeof(*promisc_allmulti), GFP_KERNEL); + promisc_allmulti = kzalloc_obj(*promisc_allmulti); if (!promisc_allmulti) { dev_warn(&dev->dev, "Failed to set RX mode, no memory.\n"); return; @@ -3885,7 +3885,7 @@ static int virtnet_vlan_rx_add_vid(struct net_device *dev, __virtio16 *_vid __free(kfree) = NULL; struct scatterlist sg; - _vid = kzalloc(sizeof(*_vid), GFP_KERNEL); + _vid = kzalloc_obj(*_vid); if (!_vid) return -ENOMEM; @@ -3905,7 +3905,7 @@ static int virtnet_vlan_rx_kill_vid(struct net_device *dev, __virtio16 *_vid __free(kfree) = NULL; struct scatterlist sg; - _vid = kzalloc(sizeof(*_vid), GFP_KERNEL); + _vid = kzalloc_obj(*_vid); if (!_vid) return -ENOMEM; @@ -4028,7 +4028,7 @@ static int virtnet_send_ctrl_coal_vq_cmd(struct virtnet_info *vi, struct virtio_net_ctrl_coal_vq *coal_vq __free(kfree) = NULL; struct scatterlist sgs; - coal_vq = kzalloc(sizeof(*coal_vq), GFP_KERNEL); + coal_vq = kzalloc_obj(*coal_vq); if (!coal_vq) return -ENOMEM; @@ -4987,7 +4987,7 @@ static int virtnet_get_hw_stats(struct virtnet_info *vi, qnum += 1; } - req = kcalloc(qnum, sizeof(*req), GFP_KERNEL); + req = kzalloc_objs(*req, qnum); if (!req) return -ENOMEM; @@ -5127,7 +5127,7 @@ static int virtnet_send_tx_notf_coal_cmds(struct virtnet_info *vi, struct scatterlist sgs_tx; int i; - coal_tx = kzalloc(sizeof(*coal_tx), GFP_KERNEL); + coal_tx = kzalloc_obj(*coal_tx); if (!coal_tx) return -ENOMEM; @@ -5175,7 +5175,7 @@ static int virtnet_send_rx_notf_coal_cmds(struct virtnet_info *vi, return 0; } - coal_rx = kzalloc(sizeof(*coal_rx), GFP_KERNEL); + coal_rx = kzalloc_obj(*coal_rx); if (!coal_rx) return -ENOMEM; @@ -5738,7 +5738,7 @@ static int virtnet_set_guest_offloads(struct virtnet_info *vi, u64 offloads) __virtio64 *_offloads __free(kfree) = NULL; struct scatterlist sg; - _offloads = kzalloc(sizeof(*_offloads), GFP_KERNEL); + _offloads = kzalloc_obj(*_offloads); if (!_offloads) return -ENOMEM; @@ -5882,7 +5882,7 @@ static int virtnet_xsk_pool_enable(struct net_device *dev, size = virtqueue_get_vring_size(rq->vq); - rq->xsk_buffs = kvcalloc(size, sizeof(*rq->xsk_buffs), GFP_KERNEL); + rq->xsk_buffs = kvzalloc_objs(*rq->xsk_buffs, size); if (!rq->xsk_buffs) return -ENOMEM; @@ -6395,14 +6395,14 @@ static int virtnet_find_vqs(struct virtnet_info *vi) virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ); /* Allocate space for find_vqs parameters */ - vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL); + vqs = kzalloc_objs(*vqs, total_vqs); if (!vqs) goto err_vq; - vqs_info = kcalloc(total_vqs, sizeof(*vqs_info), GFP_KERNEL); + vqs_info = kzalloc_objs(*vqs_info, total_vqs); if (!vqs_info) goto err_vqs_info; if (!vi->big_packets || vi->mergeable_rx_bufs) { - ctx = kcalloc(total_vqs, sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_objs(*ctx, total_vqs); if (!ctx) goto err_ctx; } else { @@ -6460,16 +6460,16 @@ static int virtnet_alloc_queues(struct virtnet_info *vi) int i; if (vi->has_cvq) { - vi->ctrl = kzalloc(sizeof(*vi->ctrl), GFP_KERNEL); + vi->ctrl = kzalloc_obj(*vi->ctrl); if (!vi->ctrl) goto err_ctrl; } else { vi->ctrl = NULL; } - vi->sq = kcalloc(vi->max_queue_pairs, sizeof(*vi->sq), GFP_KERNEL); + vi->sq = kzalloc_objs(*vi->sq, vi->max_queue_pairs); if (!vi->sq) goto err_sq; - vi->rq = kcalloc(vi->max_queue_pairs, sizeof(*vi->rq), GFP_KERNEL); + vi->rq = kzalloc_objs(*vi->rq, vi->max_queue_pairs); if (!vi->rq) goto err_rq; @@ -7016,7 +7016,7 @@ static int virtnet_probe(struct virtio_device *vdev) struct scatterlist sg; __le64 v; - stats_cap = kzalloc(sizeof(*stats_cap), GFP_KERNEL); + stats_cap = kzalloc_obj(*stats_cap); if (!stats_cap) { rtnl_unlock(); err = -ENOMEM; diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index 571847a7f86d..8c009bcaa8e7 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -158,7 +158,7 @@ static struct vrf_map_elem *vrf_map_elem_alloc(gfp_t flags) { struct vrf_map_elem *me; - me = kmalloc(sizeof(*me), flags); + me = kmalloc_obj(*me, flags); if (!me) return NULL; diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c index 7bd0ae0a6a33..17c941aac32d 100644 --- a/drivers/net/vxlan/vxlan_core.c +++ b/drivers/net/vxlan/vxlan_core.c @@ -580,7 +580,7 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, if (rd) return 0; - rd = kmalloc(sizeof(*rd), GFP_ATOMIC); + rd = kmalloc_obj(*rd, GFP_ATOMIC); if (rd == NULL) return -ENOMEM; @@ -774,7 +774,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan, const u8 *mac, { struct vxlan_fdb *f; - f = kmalloc(sizeof(*f), GFP_ATOMIC); + f = kmalloc_obj(*f, GFP_ATOMIC); if (!f) return NULL; memset(&f->key, 0, sizeof(f->key)); @@ -2130,6 +2130,11 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb) { struct ipv6hdr *pip6; + /* check if nd_tbl is not initiliazed due to + * ipv6.disable=1 set during boot + */ + if (!ipv6_stub->nd_tbl) + return false; if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) return false; pip6 = ipv6_hdr(skb); @@ -3578,7 +3583,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6, ASSERT_RTNL(); - vs = kzalloc(sizeof(*vs), GFP_KERNEL); + vs = kzalloc_obj(*vs); if (!vs) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/vxlan/vxlan_mdb.c b/drivers/net/vxlan/vxlan_mdb.c index 816ab1aa0526..055a4969f593 100644 --- a/drivers/net/vxlan/vxlan_mdb.c +++ b/drivers/net/vxlan/vxlan_mdb.c @@ -430,7 +430,7 @@ static int vxlan_mdb_config_src_entry_init(struct vxlan_mdb_config *cfg, extack)) return -EINVAL; - src = kzalloc(sizeof(*src), GFP_KERNEL); + src = kzalloc_obj(*src); if (!src) return -ENOMEM; @@ -697,7 +697,7 @@ static int vxlan_mdb_remote_rdst_init(const struct vxlan_mdb_config *cfg, struct vxlan_rdst *rd; int err; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; @@ -767,7 +767,7 @@ vxlan_mdb_remote_src_entry_add(struct vxlan_mdb_remote *remote, { struct vxlan_mdb_src_entry *ent; - ent = kzalloc(sizeof(*ent), GFP_KERNEL); + ent = kzalloc_obj(*ent); if (!ent) return NULL; @@ -1139,7 +1139,7 @@ static int vxlan_mdb_remote_add(const struct vxlan_mdb_config *cfg, return -ENOENT; } - remote = kzalloc(sizeof(*remote), GFP_KERNEL); + remote = kzalloc_obj(*remote); if (!remote) return -ENOMEM; @@ -1187,7 +1187,7 @@ vxlan_mdb_entry_get(struct vxlan_dev *vxlan, if (mdb_entry) return mdb_entry; - mdb_entry = kzalloc(sizeof(*mdb_entry), GFP_KERNEL); + mdb_entry = kzalloc_obj(*mdb_entry); if (!mdb_entry) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/vxlan/vxlan_vnifilter.c b/drivers/net/vxlan/vxlan_vnifilter.c index cde897d92f24..2042369379ff 100644 --- a/drivers/net/vxlan/vxlan_vnifilter.c +++ b/drivers/net/vxlan/vxlan_vnifilter.c @@ -697,7 +697,7 @@ static struct vxlan_vni_node *vxlan_vni_alloc(struct vxlan_dev *vxlan, { struct vxlan_vni_node *vninode; - vninode = kzalloc(sizeof(*vninode), GFP_KERNEL); + vninode = kzalloc_obj(*vninode); if (!vninode) return NULL; vninode->stats = netdev_alloc_pcpu_stats(struct vxlan_vni_stats_pcpu); @@ -925,7 +925,7 @@ int vxlan_vnigroup_init(struct vxlan_dev *vxlan) struct vxlan_vni_group *vg; int ret; - vg = kzalloc(sizeof(*vg), GFP_KERNEL); + vg = kzalloc_obj(*vg); if (!vg) return -ENOMEM; ret = rhashtable_init(&vg->vni_hash, &vxlan_vni_rht_params); diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 8dd14d916c3a..f35a15cf5dd9 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -313,7 +313,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) return -ENODEV; } - card = kzalloc(sizeof(card_t), GFP_KERNEL); + card = kzalloc_obj(card_t); if (!card) return -ENOBUFS; diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c index 5b01642ca44e..73f393900710 100644 --- a/drivers/net/wan/farsync.c +++ b/drivers/net/wan/farsync.c @@ -2359,7 +2359,7 @@ fst_add_one(struct pci_dev *pdev, const struct pci_device_id *ent) } /* Allocate driver private data */ - card = kzalloc(sizeof(struct fst_card_info), GFP_KERNEL); + card = kzalloc_obj(struct fst_card_info); if (!card) return -ENOMEM; @@ -2550,6 +2550,8 @@ fst_remove_one(struct pci_dev *pdev) fst_disable_intr(card); free_irq(card->irq, card); + tasklet_kill(&fst_tx_task); + tasklet_kill(&fst_int_task); iounmap(card->ctlmem); iounmap(card->mem); diff --git a/drivers/net/wan/framer/framer-core.c b/drivers/net/wan/framer/framer-core.c index bf7ac7dd2804..d779b03a9e1b 100644 --- a/drivers/net/wan/framer/framer-core.c +++ b/drivers/net/wan/framer/framer-core.c @@ -615,7 +615,7 @@ struct framer *framer_create(struct device *dev, struct device_node *node, if (WARN_ON((ops->flags & FRAMER_FLAG_POLL_STATUS) && !ops->get_status)) return ERR_PTR(-EINVAL); - framer = kzalloc(sizeof(*framer), GFP_KERNEL); + framer = kzalloc_obj(*framer); if (!framer) return ERR_PTR(-ENOMEM); @@ -771,7 +771,7 @@ __framer_provider_of_register(struct device *dev, struct module *owner, { struct framer_provider *framer_provider; - framer_provider = kzalloc(sizeof(*framer_provider), GFP_KERNEL); + framer_provider = kzalloc_obj(*framer_provider); if (!framer_provider) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wan/framer/pef2256/pef2256.c b/drivers/net/wan/framer/pef2256/pef2256.c index c058cc79137d..6938316bf82b 100644 --- a/drivers/net/wan/framer/pef2256/pef2256.c +++ b/drivers/net/wan/framer/pef2256/pef2256.c @@ -638,7 +638,7 @@ static int pef2256_add_audio_devices(struct pef2256 *pef2256) if (!count) return 0; - audio_devs = kcalloc(count, sizeof(*audio_devs), GFP_KERNEL); + audio_devs = kzalloc_objs(*audio_devs, count); if (!audio_devs) return -ENOMEM; diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index dff84731343c..b72ab9951875 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -203,17 +203,13 @@ static int uhdlc_init(struct ucc_hdlc_private *priv) goto free_tx_bd; } - priv->rx_skbuff = kcalloc(priv->rx_ring_size, - sizeof(*priv->rx_skbuff), - GFP_KERNEL); + priv->rx_skbuff = kzalloc_objs(*priv->rx_skbuff, priv->rx_ring_size); if (!priv->rx_skbuff) { ret = -ENOMEM; goto free_ucc_pram; } - priv->tx_skbuff = kcalloc(priv->tx_ring_size, - sizeof(*priv->tx_skbuff), - GFP_KERNEL); + priv->tx_skbuff = kzalloc_objs(*priv->tx_skbuff, priv->tx_ring_size); if (!priv->tx_skbuff) { ret = -ENOMEM; goto free_rx_skbuff; @@ -900,8 +896,7 @@ static int uhdlc_suspend(struct device *dev) priv->gumr = ioread32be(&uf_regs->gumr); priv->guemr = ioread8(&uf_regs->guemr); - priv->ucc_pram_bak = kmalloc(sizeof(*priv->ucc_pram_bak), - GFP_KERNEL); + priv->ucc_pram_bak = kmalloc_obj(*priv->ucc_pram_bak); if (!priv->ucc_pram_bak) return -ENOMEM; @@ -1173,7 +1168,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) ut_info->uf_info.regs = res.start; ut_info->uf_info.irq = irq_of_parse_and_map(np, 0); - uhdlc_priv = kzalloc(sizeof(*uhdlc_priv), GFP_KERNEL); + uhdlc_priv = kzalloc_obj(*uhdlc_priv); if (!uhdlc_priv) return -ENOMEM; @@ -1186,7 +1181,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) uhdlc_priv->hdlc_bus = of_property_read_bool(np, "fsl,hdlc-bus"); if (uhdlc_priv->tsa == 1) { - utdm = kzalloc(sizeof(*utdm), GFP_KERNEL); + utdm = kzalloc_obj(*utdm); if (!utdm) { ret = -ENOMEM; dev_err(&pdev->dev, "No mem to alloc ucc tdm data\n"); diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c index 08a0ba5ca471..5f0e54ed1ee1 100644 --- a/drivers/net/wan/hdlc_fr.c +++ b/drivers/net/wan/hdlc_fr.c @@ -192,7 +192,7 @@ static struct pvc_device *add_pvc(struct net_device *dev, u16 dlci) pvc_p = &(*pvc_p)->next; } - pvc = kzalloc(sizeof(*pvc), GFP_ATOMIC); + pvc = kzalloc_obj(*pvc, GFP_ATOMIC); #ifdef DEBUG_PVC printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev); #endif diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index f3e80722ba1d..0e405fb307f9 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -340,7 +340,7 @@ static int __init n2_run(unsigned long io, unsigned long irq, return -ENODEV; } - card = kzalloc(sizeof(card_t), GFP_KERNEL); + card = kzalloc_obj(card_t); if (!card) return -ENOBUFS; diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index 4766446f0fa0..7e57d289b62c 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -300,7 +300,7 @@ static int pc300_pci_init_one(struct pci_dev *pdev, return i; } - card = kzalloc(sizeof(card_t), GFP_KERNEL); + card = kzalloc_obj(card_t); if (!card) { pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index ea86c7035653..89f4b4584a33 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -281,7 +281,7 @@ static int pci200_pci_init_one(struct pci_dev *pdev, return i; } - card = kzalloc(sizeof(card_t), GFP_KERNEL); + card = kzalloc_obj(card_t); if (!card) { pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 5a9e262188ef..3f7707118450 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -598,7 +598,7 @@ static int wanxl_pci_init_one(struct pci_dev *pdev, ports = 4; } - card = kzalloc(struct_size(card, ports, ports), GFP_KERNEL); + card = kzalloc_flex(*card, ports, ports); if (!card) { pci_release_regions(pdev); pci_disable_device(pdev); diff --git a/drivers/net/wireguard/noise.c b/drivers/net/wireguard/noise.c index 1fe8468f0bef..9c0a09bf6c95 100644 --- a/drivers/net/wireguard/noise.c +++ b/drivers/net/wireguard/noise.c @@ -97,7 +97,7 @@ void wg_noise_handshake_clear(struct noise_handshake *handshake) static struct noise_keypair *keypair_create(struct wg_peer *peer) { - struct noise_keypair *keypair = kzalloc(sizeof(*keypair), GFP_KERNEL); + struct noise_keypair *keypair = kzalloc_obj(*keypair); if (unlikely(!keypair)) return NULL; diff --git a/drivers/net/wireguard/peerlookup.c b/drivers/net/wireguard/peerlookup.c index f2783aa7a88f..99651a86ac95 100644 --- a/drivers/net/wireguard/peerlookup.c +++ b/drivers/net/wireguard/peerlookup.c @@ -21,7 +21,7 @@ static struct hlist_head *pubkey_bucket(struct pubkey_hashtable *table, struct pubkey_hashtable *wg_pubkey_hashtable_alloc(void) { - struct pubkey_hashtable *table = kvmalloc(sizeof(*table), GFP_KERNEL); + struct pubkey_hashtable *table = kvmalloc_obj(*table); if (!table) return NULL; @@ -82,7 +82,7 @@ static struct hlist_head *index_bucket(struct index_hashtable *table, struct index_hashtable *wg_index_hashtable_alloc(void) { - struct index_hashtable *table = kvmalloc(sizeof(*table), GFP_KERNEL); + struct index_hashtable *table = kvmalloc_obj(*table); if (!table) return NULL; diff --git a/drivers/net/wireguard/ratelimiter.c b/drivers/net/wireguard/ratelimiter.c index dd55e5c26f46..2b3867f692ab 100644 --- a/drivers/net/wireguard/ratelimiter.c +++ b/drivers/net/wireguard/ratelimiter.c @@ -176,12 +176,12 @@ int wg_ratelimiter_init(void) (1U << 14) / sizeof(struct hlist_head))); max_entries = table_size * 8; - table_v4 = kvcalloc(table_size, sizeof(*table_v4), GFP_KERNEL); + table_v4 = kvzalloc_objs(*table_v4, table_size); if (unlikely(!table_v4)) goto err_kmemcache; #if IS_ENABLED(CONFIG_IPV6) - table_v6 = kvcalloc(table_size, sizeof(*table_v6), GFP_KERNEL); + table_v6 = kvzalloc_objs(*table_v6, table_size); if (unlikely(!table_v6)) { kvfree(table_v4); goto err_kmemcache; diff --git a/drivers/net/wireguard/selftest/allowedips.c b/drivers/net/wireguard/selftest/allowedips.c index 41837efa70cb..2da3008c3a01 100644 --- a/drivers/net/wireguard/selftest/allowedips.c +++ b/drivers/net/wireguard/selftest/allowedips.c @@ -181,7 +181,7 @@ static __init int horrible_allowedips_insert_v4(struct horrible_allowedips *table, struct in_addr *ip, u8 cidr, void *value) { - struct horrible_allowedips_node *node = kzalloc(sizeof(*node), GFP_KERNEL); + struct horrible_allowedips_node *node = kzalloc_obj(*node); if (unlikely(!node)) return -ENOMEM; @@ -198,7 +198,7 @@ static __init int horrible_allowedips_insert_v6(struct horrible_allowedips *table, struct in6_addr *ip, u8 cidr, void *value) { - struct horrible_allowedips_node *node = kzalloc(sizeof(*node), GFP_KERNEL); + struct horrible_allowedips_node *node = kzalloc_obj(*node); if (unlikely(!node)) return -ENOMEM; @@ -266,13 +266,13 @@ static __init bool randomized_test(void) wg_allowedips_init(&t); horrible_allowedips_init(&h); - peers = kcalloc(NUM_PEERS, sizeof(*peers), GFP_KERNEL); + peers = kzalloc_objs(*peers, NUM_PEERS); if (unlikely(!peers)) { pr_err("allowedips random self-test malloc: FAIL\n"); goto free; } for (i = 0; i < NUM_PEERS; ++i) { - peers[i] = kzalloc(sizeof(*peers[i]), GFP_KERNEL); + peers[i] = kzalloc_obj(*peers[i]); if (unlikely(!peers[i])) { pr_err("allowedips random self-test malloc: FAIL\n"); goto free; @@ -447,7 +447,7 @@ static __init inline struct in6_addr *ip6(u32 a, u32 b, u32 c, u32 d) static __init struct wg_peer *init_peer(void) { - struct wg_peer *peer = kzalloc(sizeof(*peer), GFP_KERNEL); + struct wg_peer *peer = kzalloc_obj(*peer); if (!peer) return NULL; diff --git a/drivers/net/wireguard/selftest/counter.c b/drivers/net/wireguard/selftest/counter.c index ec3c156bf91b..8595ab697869 100644 --- a/drivers/net/wireguard/selftest/counter.c +++ b/drivers/net/wireguard/selftest/counter.c @@ -10,7 +10,7 @@ bool __init wg_packet_counter_selftest(void) unsigned int test_num = 0, i; bool success = true; - counter = kmalloc(sizeof(*counter), GFP_KERNEL); + counter = kmalloc_obj(*counter); if (unlikely(!counter)) { pr_err("nonce counter self-test malloc: FAIL\n"); return false; diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c index 1230e6278f23..66ac396858a5 100644 --- a/drivers/net/wireless/ath/ar5523/ar5523.c +++ b/drivers/net/wireless/ath/ar5523/ar5523.c @@ -1512,11 +1512,11 @@ static int ar5523_load_firmware(struct usb_device *dev) return -ENOENT; } - txblock = kzalloc(sizeof(*txblock), GFP_KERNEL); + txblock = kzalloc_obj(*txblock); if (!txblock) goto out; - rxblock = kmalloc(sizeof(*rxblock), GFP_KERNEL); + rxblock = kmalloc_obj(*rxblock); if (!rxblock) goto out_free_txblock; diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 82f120ee1c66..a9cbe955e084 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c @@ -1461,8 +1461,7 @@ ath10k_ce_alloc_src_ring(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(nentries); - src_ring = kzalloc(struct_size(src_ring, per_transfer_context, - nentries), GFP_KERNEL); + src_ring = kzalloc_flex(*src_ring, per_transfer_context, nentries); if (src_ring == NULL) return ERR_PTR(-ENOMEM); @@ -1519,8 +1518,7 @@ ath10k_ce_alloc_src_ring_64(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(nentries); - src_ring = kzalloc(struct_size(src_ring, per_transfer_context, - nentries), GFP_KERNEL); + src_ring = kzalloc_flex(*src_ring, per_transfer_context, nentries); if (!src_ring) return ERR_PTR(-ENOMEM); @@ -1575,8 +1573,7 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(attr->dest_nentries); - dest_ring = kzalloc(struct_size(dest_ring, per_transfer_context, - nentries), GFP_KERNEL); + dest_ring = kzalloc_flex(*dest_ring, per_transfer_context, nentries); if (dest_ring == NULL) return ERR_PTR(-ENOMEM); @@ -1619,8 +1616,7 @@ ath10k_ce_alloc_dest_ring_64(struct ath10k *ar, unsigned int ce_id, nentries = roundup_pow_of_two(attr->dest_nentries); - dest_ring = kzalloc(struct_size(dest_ring, per_transfer_context, - nentries), GFP_KERNEL); + dest_ring = kzalloc_flex(*dest_ring, per_transfer_context, nentries); if (!dest_ring) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c index d7e429041065..25ab945fecef 100644 --- a/drivers/net/wireless/ath/ath10k/htt_rx.c +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c @@ -807,8 +807,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt) } htt->rx_ring.netbufs_ring = - kcalloc(htt->rx_ring.size, sizeof(struct sk_buff *), - GFP_KERNEL); + kzalloc_objs(struct sk_buff *, htt->rx_ring.size); if (!htt->rx_ring.netbufs_ring) goto err_netbuf; diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index da6f7957a0ae..8e604697d6c2 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -6431,7 +6431,7 @@ static int ath10k_hw_scan(struct ieee80211_hw *hw, if (ret) goto exit; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) { ret = -ENOMEM; goto exit; @@ -7559,8 +7559,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw, } if (ath10k_debug_is_extd_tx_stats_enabled(ar)) { - arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), - GFP_KERNEL); + arsta->tx_stats = kzalloc_obj(*arsta->tx_stats); if (!arsta->tx_stats) { ath10k_mac_dec_num_stations(arvif, sta); ret = -ENOMEM; @@ -7972,7 +7971,7 @@ static int ath10k_remain_on_channel(struct ieee80211_hw *hw, scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) { ret = -ENOMEM; goto exit; @@ -8954,8 +8953,7 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw, if (arg.n_vifs == 0) goto radar; - arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]), - GFP_KERNEL); + arg.vifs = kzalloc_objs(arg.vifs[0], arg.n_vifs); if (!arg.vifs) goto radar; diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 8275345631a0..eebd78e7ff6b 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -245,7 +245,7 @@ static int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi) const u8 *temp; int ret; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -437,7 +437,7 @@ ath10k_qmi_cfg_send_sync_msg(struct ath10k *ar, int ret; u32 i; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -578,7 +578,7 @@ static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) struct qmi_txn txn; int ret; - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) return -ENOMEM; @@ -877,7 +877,7 @@ ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi, { struct ath10k_qmi_driver_event *event; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return -ENOMEM; @@ -1075,7 +1075,7 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) struct ath10k_qmi *qmi; int ret; - qmi = kzalloc(sizeof(*qmi), GFP_KERNEL); + qmi = kzalloc_obj(*qmi); if (!qmi) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath10k/sdio.c b/drivers/net/wireless/ath/ath10k/sdio.c index 00d0556dafef..43a6b1ba8fb8 100644 --- a/drivers/net/wireless/ath/ath10k/sdio.c +++ b/drivers/net/wireless/ath/ath10k/sdio.c @@ -246,7 +246,7 @@ static int ath10k_sdio_writesb32(struct ath10k *ar, u32 addr, u32 val) __le32 *buf; int ret; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return -ENOMEM; @@ -1766,7 +1766,7 @@ static int ath10k_sdio_diag_read32(struct ath10k *ar, u32 address, __le32 *val; int ret; - val = kzalloc(sizeof(*val), GFP_KERNEL); + val = kzalloc_obj(*val); if (!val) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c index 493bfb410aff..50a3498a0bfd 100644 --- a/drivers/net/wireless/ath/ath10k/txrx.c +++ b/drivers/net/wireless/ath/ath10k/txrx.c @@ -230,7 +230,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt, spin_lock_bh(&ar->data_lock); peer = ath10k_peer_find(ar, ev->vdev_id, ev->addr); if (!peer) { - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + peer = kzalloc_obj(*peer, GFP_ATOMIC); if (!peer) goto exit; diff --git a/drivers/net/wireless/ath/ath10k/usb.c b/drivers/net/wireless/ath/ath10k/usb.c index 1732a4f98418..6661fff326e0 100644 --- a/drivers/net/wireless/ath/ath10k/usb.c +++ b/drivers/net/wireless/ath/ath10k/usb.c @@ -799,7 +799,7 @@ static int ath10k_usb_alloc_pipe_resources(struct ath10k *ar, init_usb_anchor(&pipe->urb_submitted); for (i = 0; i < urb_cnt; i++) { - urb_context = kzalloc(sizeof(*urb_context), GFP_KERNEL); + urb_context = kzalloc_obj(*urb_context); if (!urb_context) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c index 16d07d619b4d..ec8e91707f84 100644 --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c @@ -145,7 +145,7 @@ ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr, const void **tb; int ret; - tb = kcalloc(WMI_TLV_TAG_MAX, sizeof(*tb), gfp); + tb = kzalloc_objs(*tb, WMI_TLV_TAG_MAX, gfp); if (!tb) return ERR_PTR(-ENOMEM); @@ -1546,7 +1546,7 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, data += sizeof(*src); data_len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -1569,7 +1569,7 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, data += sizeof(*src); data_len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -1590,7 +1590,7 @@ static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, data += sizeof(*src); data_len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3063,7 +3063,7 @@ ath10k_wmi_mgmt_tx_alloc_msdu_id(struct ath10k *ar, struct sk_buff *skb, struct ath10k_mgmt_tx_pkt_addr *pkt_addr; int ret; - pkt_addr = kmalloc(sizeof(*pkt_addr), GFP_ATOMIC); + pkt_addr = kmalloc_obj(*pkt_addr, GFP_ATOMIC); if (!pkt_addr) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ce22141e5efd..0bdb38edd915 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c @@ -3046,7 +3046,7 @@ static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3067,7 +3067,7 @@ static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3100,7 +3100,7 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3122,7 +3122,7 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3161,7 +3161,7 @@ static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3198,7 +3198,7 @@ static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3238,7 +3238,7 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3281,7 +3281,7 @@ static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, stats_len)) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3330,7 +3330,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3376,7 +3376,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3409,7 +3409,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -3429,7 +3429,7 @@ static int ath10k_wmi_10_4_op_pull_fw_stats(struct ath10k *ar, if (!skb_pull(skb, sizeof(*src))) return -EPROTO; - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; ath10k_wmi_10_4_pull_vdev_stats(src, dst); @@ -4912,7 +4912,7 @@ void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) rate_max = WMI_TPC_RATE_MAX; } - tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); + tpc_stats = kzalloc_obj(*tpc_stats, GFP_ATOMIC); if (!tpc_stats) return; @@ -5168,7 +5168,7 @@ void ath10k_wmi_event_tpc_final_table(struct ath10k *ar, struct sk_buff *skb) rate_max = WMI_TPC_FINAL_RATE_MAX; } - tpc_stats = kzalloc(sizeof(*tpc_stats), GFP_ATOMIC); + tpc_stats = kzalloc_obj(*tpc_stats, GFP_ATOMIC); if (!tpc_stats) return; diff --git a/drivers/net/wireless/ath/ath10k/wow.c b/drivers/net/wireless/ath/ath10k/wow.c index aa7b2e703f3d..78653f257925 100644 --- a/drivers/net/wireless/ath/ath10k/wow.c +++ b/drivers/net/wireless/ath/ath10k/wow.c @@ -301,7 +301,7 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif, struct wmi_pno_scan_req *pno; int ret; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; @@ -413,7 +413,7 @@ static int ath10k_vif_wow_clean_nlo(struct ath10k_vif *arvif) if (ar->nlo_enabled) { struct wmi_pno_scan_req *pno; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c index a7a163621b21..f2d5106adb01 100644 --- a/drivers/net/wireless/ath/ath11k/ce.c +++ b/drivers/net/wireless/ath/ath11k/ce.c @@ -615,7 +615,7 @@ ath11k_ce_alloc_ring(struct ath11k_base *ab, int nentries, int desc_sz) struct ath11k_ce_ring *ce_ring; dma_addr_t base_addr; - ce_ring = kzalloc(struct_size(ce_ring, skb, nentries), GFP_KERNEL); + ce_ring = kzalloc_flex(*ce_ring, skb, nentries); if (ce_ring == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/ath/ath11k/cfr.c b/drivers/net/wireless/ath/ath11k/cfr.c index 61bf1c0884f7..a91f25fb6c6b 100644 --- a/drivers/net/wireless/ath/ath11k/cfr.c +++ b/drivers/net/wireless/ath/ath11k/cfr.c @@ -975,8 +975,7 @@ int ath11k_cfr_init(struct ath11k_base *ab) spin_lock_init(&cfr->lut_lock); num_lut_entries = min_t(u32, CFR_MAX_LUT_ENTRIES, db_cap.min_elem); - cfr->lut = kcalloc(num_lut_entries, sizeof(*cfr->lut), - GFP_KERNEL); + cfr->lut = kzalloc_objs(*cfr->lut, num_lut_entries); if (!cfr->lut) { ret = -ENOMEM; goto err; diff --git a/drivers/net/wireless/ath/ath11k/dbring.c b/drivers/net/wireless/ath/ath11k/dbring.c index d6994ce6ebff..6ac18f8a1e5f 100644 --- a/drivers/net/wireless/ath/ath11k/dbring.c +++ b/drivers/net/wireless/ath/ath11k/dbring.c @@ -127,7 +127,7 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar, size = ring->buf_sz + align - 1; while (num_remain > 0) { - buff = kzalloc(sizeof(*buff), GFP_ATOMIC); + buff = kzalloc_obj(*buff, GFP_ATOMIC); if (!buff) break; diff --git a/drivers/net/wireless/ath/ath11k/debugfs.c b/drivers/net/wireless/ath/ath11k/debugfs.c index 50f344803e8f..0c1138407838 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs.c +++ b/drivers/net/wireless/ath/ath11k/debugfs.c @@ -1193,8 +1193,7 @@ static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id) if (ar->debug.dbr_debug[dbr_id]) return 0; - ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug), - GFP_KERNEL); + ar->debug.dbr_debug[dbr_id] = kzalloc_obj(*dbr_debug); if (!ar->debug.dbr_debug[dbr_id]) return -ENOMEM; @@ -1216,9 +1215,8 @@ static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id) dbr_debug->dbr_debug_enabled = true; dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX; dbr_dbg_data->dbr_debug_idx = 0; - dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX, - sizeof(struct ath11k_dbg_dbr_entry), - GFP_KERNEL); + dbr_dbg_data->entries = kzalloc_objs(struct ath11k_dbg_dbr_entry, + ATH11K_DEBUG_DBR_ENTRIES_MAX); if (!dbr_dbg_data->entries) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index b9e976ddcbbf..49d959b2e148 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -772,7 +772,7 @@ static void ath11k_dp_rx_tid_del_func(struct ath11k_dp *dp, void *ctx, return; } - elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + elem = kzalloc_obj(*elem, GFP_ATOMIC); if (!elem) goto free_desc; @@ -1542,7 +1542,7 @@ struct htt_ppdu_stats_info *ath11k_dp_htt_get_ppdu_desc(struct ath11k *ar, } } - ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); + ppdu_info = kzalloc_obj(*ppdu_info, GFP_ATOMIC); if (!ppdu_info) return NULL; @@ -5485,7 +5485,7 @@ static int ath11k_dp_rx_full_mon_prepare_mpdu(struct ath11k_dp *dp, struct sk_buff *head, struct sk_buff *tail) { - mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); + mon_mpdu = kzalloc_obj(*mon_mpdu, GFP_ATOMIC); if (!mon_mpdu) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index 86e1e6c27b36..9c2310665713 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -796,7 +796,7 @@ int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid, * for tid delete command to free up the resource on the command status * indication? */ - dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); + dp_cmd = kzalloc_obj(*dp_cmd, GFP_ATOMIC); if (!dp_cmd) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 4dfd08b58416..e4ee2ba1f669 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -4221,7 +4221,7 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, if (ret) goto exit; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) { ret = -ENOMEM; @@ -7876,7 +7876,7 @@ ath11k_mac_update_active_vif_chan(struct ath11k *ar, if (arg.n_vifs == 0) return; - arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]), GFP_KERNEL); + arg.vifs = kzalloc_objs(arg.vifs[0], arg.n_vifs); if (!arg.vifs) return; @@ -9729,7 +9729,7 @@ static int ath11k_mac_op_remain_on_channel(struct ieee80211_hw *hw, scan_time_msec = ar->hw->wiphy->max_remain_on_channel_duration * 2; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) { ret = -ENOMEM; goto exit; @@ -9823,7 +9823,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, arvif->reinstall_group_keys = false; } - arsta->rx_stats = kzalloc(sizeof(*arsta->rx_stats), GFP_KERNEL); + arsta->rx_stats = kzalloc_obj(*arsta->rx_stats); if (!arsta->rx_stats) { ret = -ENOMEM; goto dec_num_station; @@ -9844,7 +9844,7 @@ static int ath11k_mac_station_add(struct ath11k *ar, sta->addr, arvif->vdev_id); if (ath11k_debugfs_is_extd_tx_stats_enabled(ar)) { - arsta->tx_stats = kzalloc(sizeof(*arsta->tx_stats), GFP_KERNEL); + arsta->tx_stats = kzalloc_obj(*arsta->tx_stats); if (!arsta->tx_stats) { ret = -ENOMEM; goto free_peer; @@ -10278,7 +10278,7 @@ static void ath11k_mac_setup_mac_address_list(struct ath11k *ar) return; n_addresses = ar->ab->hw_params.num_vdevs; - addresses = kcalloc(n_addresses, sizeof(*addresses), GFP_KERNEL); + addresses = kzalloc_objs(*addresses, n_addresses); if (!addresses) return; @@ -10310,7 +10310,7 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) else n_combos = 1; - combinations = kcalloc(n_combos, sizeof(*combinations), GFP_KERNEL); + combinations = kzalloc_objs(*combinations, n_combos); if (!combinations) return -ENOMEM; @@ -10319,7 +10319,7 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar) else n_limits = 2; - limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL); + limits = kzalloc_objs(*limits, n_limits); if (!limits) { kfree(combinations); return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/mhi.c b/drivers/net/wireless/ath/ath11k/mhi.c index acd76e9392d3..f994233df2bb 100644 --- a/drivers/net/wireless/ath/ath11k/mhi.c +++ b/drivers/net/wireless/ath/ath11k/mhi.c @@ -34,7 +34,6 @@ static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, }, { .num = 21, @@ -48,7 +47,6 @@ static const struct mhi_channel_config ath11k_mhi_channels_qca6390[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, }, }; @@ -99,7 +97,6 @@ static const struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, }, { .num = 21, @@ -113,7 +110,6 @@ static const struct mhi_channel_config ath11k_mhi_channels_qcn9074[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, }, }; @@ -211,7 +207,7 @@ static int ath11k_mhi_get_msi(struct ath11k_pci *ab_pci) ath11k_dbg(ab, ATH11K_DBG_PCI, "num_vectors %d base_vector %d\n", num_vectors, base_vector); - irq = kcalloc(num_vectors, sizeof(int), GFP_KERNEL); + irq = kzalloc_objs(int, num_vectors); if (!irq) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/peer.c b/drivers/net/wireless/ath/ath11k/peer.c index 6d0126c39301..027cc7aa58c8 100644 --- a/drivers/net/wireless/ath/ath11k/peer.c +++ b/drivers/net/wireless/ath/ath11k/peer.c @@ -125,7 +125,7 @@ void ath11k_peer_map_event(struct ath11k_base *ab, u8 vdev_id, u16 peer_id, spin_lock_bh(&ab->base_lock); peer = ath11k_peer_find(ab, vdev_id, mac_addr); if (!peer) { - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + peer = kzalloc_obj(*peer, GFP_ATOMIC); if (!peer) goto exit; diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c index ff6a97e328b8..feebbc30f3df 100644 --- a/drivers/net/wireless/ath/ath11k/qmi.c +++ b/drivers/net/wireless/ath/ath11k/qmi.c @@ -1799,11 +1799,11 @@ static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab) struct qmi_txn txn; int ret; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) { ret = -ENOMEM; goto resp_out; @@ -1878,7 +1878,7 @@ static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) int ret = 0, i; bool delayed; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2306,7 +2306,7 @@ static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab, int ret = 0; u32 remaining = len; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2705,7 +2705,7 @@ static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab) ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce; svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2929,7 +2929,7 @@ ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi, { struct ath11k_qmi_driver_event *event; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c index 49b79648752c..0879a132b67c 100644 --- a/drivers/net/wireless/ath/ath11k/reg.c +++ b/drivers/net/wireless/ath/ath11k/reg.c @@ -146,8 +146,7 @@ int ath11k_reg_update_chan_list(struct ath11k *ar, bool wait) if (WARN_ON(!num_channels)) return -EINVAL; - params = kzalloc(struct_size(params, ch_param, num_channels), - GFP_KERNEL); + params = kzalloc_flex(*params, ch_param, num_channels); if (!params) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index 451cc4c719ae..40747fba3b0c 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -249,7 +249,7 @@ const void **ath11k_wmi_tlv_parse_alloc(struct ath11k_base *ab, const void **tb; int ret; - tb = kcalloc(WMI_TAG_MAX, sizeof(*tb), gfp); + tb = kzalloc_objs(*tb, WMI_TAG_MAX, gfp); if (!tb) return ERR_PTR(-ENOMEM); @@ -4918,9 +4918,8 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc, } if (!soc->reg_info_store) { - soc->reg_info_store = kcalloc(soc->num_radios, - sizeof(*soc->reg_info_store), - GFP_ATOMIC); + soc->reg_info_store = kzalloc_objs(*soc->reg_info_store, + soc->num_radios, GFP_ATOMIC); if (!soc->reg_info_store) return -ENOMEM; } @@ -5238,8 +5237,7 @@ static struct cur_reg_rule struct cur_reg_rule *reg_rule_ptr; u32 count; - reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), - GFP_ATOMIC); + reg_rule_ptr = kzalloc_objs(*reg_rule_ptr, num_reg_rules, GFP_ATOMIC); if (!reg_rule_ptr) return NULL; @@ -5388,7 +5386,7 @@ static struct cur_reg_rule struct cur_reg_rule *reg_rule_ptr; u32 count; - reg_rule_ptr = kcalloc(num_reg_rules, sizeof(*reg_rule_ptr), GFP_ATOMIC); + reg_rule_ptr = kzalloc_objs(*reg_rule_ptr, num_reg_rules, GFP_ATOMIC); if (!reg_rule_ptr) return NULL; @@ -6694,7 +6692,7 @@ static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab, data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -6737,7 +6735,7 @@ static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab, data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -6760,7 +6758,7 @@ static int ath11k_wmi_tlv_fw_stats_data_parse(struct ath11k_base *ab, data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -7247,7 +7245,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk struct cur_regulatory_info *reg_info; int ret; - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); + reg_info = kzalloc_obj(*reg_info, GFP_ATOMIC); if (!reg_info) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath11k/wow.c b/drivers/net/wireless/ath/ath11k/wow.c index b6f08755129f..f02edc9b8a9e 100644 --- a/drivers/net/wireless/ath/ath11k/wow.c +++ b/drivers/net/wireless/ath/ath11k/wow.c @@ -381,7 +381,7 @@ static int ath11k_vif_wow_set_wakeups(struct ath11k_vif *arvif, struct wmi_pno_scan_req *pno; int ret; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; @@ -495,7 +495,7 @@ static int ath11k_vif_wow_clean_nlo(struct ath11k_vif *arvif) if (ar->nlo_enabled) { struct wmi_pno_scan_req *pno; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/ce.c b/drivers/net/wireless/ath/ath12k/ce.c index f13b260c5c96..67bbc6d8d0c9 100644 --- a/drivers/net/wireless/ath/ath12k/ce.c +++ b/drivers/net/wireless/ath/ath12k/ce.c @@ -332,7 +332,7 @@ ath12k_ce_alloc_ring(struct ath12k_base *ab, int nentries, int desc_sz) struct ath12k_ce_ring *ce_ring; dma_addr_t base_addr; - ce_ring = kzalloc(struct_size(ce_ring, skb, nentries), GFP_KERNEL); + ce_ring = kzalloc_flex(*ce_ring, skb, nentries); if (!ce_ring) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c index 9d6c50a94e64..4ed608ba3c30 100644 --- a/drivers/net/wireless/ath/ath12k/core.c +++ b/drivers/net/wireless/ath/ath12k/core.c @@ -1805,7 +1805,7 @@ static struct ath12k_hw_group *ath12k_core_hw_group_alloc(struct ath12k_base *ab list_for_each_entry(ag, &ath12k_hw_group_list, list) count++; - ag = kzalloc(sizeof(*ag), GFP_KERNEL); + ag = kzalloc_obj(*ag); if (!ag) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/dp.c b/drivers/net/wireless/ath/ath12k/dp.c index ab54c8a84d3e..1c82d927d27b 100644 --- a/drivers/net/wireless/ath/ath12k/dp.c +++ b/drivers/net/wireless/ath/ath12k/dp.c @@ -407,9 +407,8 @@ static int ath12k_dp_init_bank_profiles(struct ath12k_base *ab) int i; dp->num_bank_profiles = num_tcl_banks; - dp->bank_profiles = kmalloc_array(num_tcl_banks, - sizeof(struct ath12k_dp_tx_bank_profile), - GFP_KERNEL); + dp->bank_profiles = kmalloc_objs(struct ath12k_dp_tx_bank_profile, + num_tcl_banks); if (!dp->bank_profiles) return -ENOMEM; @@ -1215,8 +1214,8 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) spin_lock_bh(&dp->rx_desc_lock); - dp->rxbaddr = kcalloc(num_rx_spt_pages, - sizeof(struct ath12k_rx_desc_info *), GFP_ATOMIC); + dp->rxbaddr = kzalloc_objs(struct ath12k_rx_desc_info *, + num_rx_spt_pages, GFP_ATOMIC); if (!dp->rxbaddr) { spin_unlock_bh(&dp->rx_desc_lock); @@ -1227,8 +1226,8 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) * RX */ for (i = 0; i < num_rx_spt_pages; i++) { - rx_descs = kcalloc(ATH12K_MAX_SPT_ENTRIES, sizeof(*rx_descs), - GFP_ATOMIC); + rx_descs = kzalloc_objs(*rx_descs, ATH12K_MAX_SPT_ENTRIES, + GFP_ATOMIC); if (!rx_descs) { spin_unlock_bh(&dp->rx_desc_lock); @@ -1253,8 +1252,8 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) spin_unlock_bh(&dp->rx_desc_lock); - dp->txbaddr = kcalloc(ATH12K_NUM_TX_SPT_PAGES(ab), - sizeof(struct ath12k_tx_desc_info *), GFP_ATOMIC); + dp->txbaddr = kzalloc_objs(struct ath12k_tx_desc_info *, + ATH12K_NUM_TX_SPT_PAGES(ab), GFP_ATOMIC); if (!dp->txbaddr) return -ENOMEM; @@ -1262,8 +1261,9 @@ static int ath12k_dp_cc_desc_init(struct ath12k_base *ab) for (pool_id = 0; pool_id < ATH12K_HW_MAX_QUEUES; pool_id++) { spin_lock_bh(&dp->tx_desc_lock[pool_id]); for (i = 0; i < ATH12K_TX_SPT_PAGES_PER_POOL(ab); i++) { - tx_descs = kcalloc(ATH12K_MAX_SPT_ENTRIES, sizeof(*tx_descs), - GFP_ATOMIC); + tx_descs = kzalloc_objs(*tx_descs, + ATH12K_MAX_SPT_ENTRIES, + GFP_ATOMIC); if (!tx_descs) { spin_unlock_bh(&dp->tx_desc_lock[pool_id]); @@ -1362,8 +1362,7 @@ static int ath12k_dp_cc_init(struct ath12k_base *ab) if (dp->num_spt_pages > ATH12K_MAX_PPT_ENTRIES) dp->num_spt_pages = ATH12K_MAX_PPT_ENTRIES; - dp->spt_info = kcalloc(dp->num_spt_pages, sizeof(struct ath12k_spt_info), - GFP_KERNEL); + dp->spt_info = kzalloc_objs(struct ath12k_spt_info, dp->num_spt_pages); if (!dp->spt_info) { ath12k_warn(ab, "SPT page allocation failure"); diff --git a/drivers/net/wireless/ath/ath12k/dp_htt.c b/drivers/net/wireless/ath/ath12k/dp_htt.c index cc71c5c5de5a..e71bb71a6020 100644 --- a/drivers/net/wireless/ath/ath12k/dp_htt.c +++ b/drivers/net/wireless/ath/ath12k/dp_htt.c @@ -386,7 +386,7 @@ struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *d } } - ppdu_info = kzalloc(sizeof(*ppdu_info), GFP_ATOMIC); + ppdu_info = kzalloc_obj(*ppdu_info, GFP_ATOMIC); if (!ppdu_info) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/dp_peer.c b/drivers/net/wireless/ath/ath12k/dp_peer.c index 2e66872b5572..a1100782d45e 100644 --- a/drivers/net/wireless/ath/ath12k/dp_peer.c +++ b/drivers/net/wireless/ath/ath12k/dp_peer.c @@ -165,7 +165,7 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ spin_lock_bh(&dp->dp_lock); peer = ath12k_dp_link_peer_find_by_vdev_and_addr(dp, vdev_id, mac_addr); if (!peer) { - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + peer = kzalloc_obj(*peer, GFP_ATOMIC); if (!peer) goto exit; @@ -179,8 +179,8 @@ void ath12k_dp_link_peer_map_event(struct ath12k_base *ab, u8 vdev_id, u16 peer_ ar = ath12k_mac_get_ar_by_vdev_id(ab, vdev_id); if (ar && ath12k_debugfs_is_extd_rx_stats_enabled(ar) && !peer->peer_stats.rx_stats) { - peer->peer_stats.rx_stats = - kzalloc(sizeof(*peer->peer_stats.rx_stats), GFP_ATOMIC); + peer->peer_stats.rx_stats = kzalloc_obj(*peer->peer_stats.rx_stats, + GFP_ATOMIC); } rcu_read_unlock(); @@ -233,7 +233,7 @@ static int ath12k_dp_link_peer_rhash_addr_tbl_init(struct ath12k_dp *dp) lockdep_assert_held(&dp->link_peer_rhash_tbl_lock); - rhash_addr_tbl = kzalloc(sizeof(*dp->rhead_peer_addr), GFP_KERNEL); + rhash_addr_tbl = kzalloc_obj(*dp->rhead_peer_addr); if (!rhash_addr_tbl) return -ENOMEM; @@ -463,7 +463,7 @@ int ath12k_dp_peer_create(struct ath12k_dp_hw *dp_hw, u8 *addr, } spin_unlock_bh(&dp_hw->peer_lock); - dp_peer = kzalloc(sizeof(*dp_peer), GFP_ATOMIC); + dp_peer = kzalloc_obj(*dp_peer, GFP_ATOMIC); if (!dp_peer) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c index a32ee9f8061a..5a82ede65dd3 100644 --- a/drivers/net/wireless/ath/ath12k/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/dp_rx.c @@ -464,7 +464,7 @@ void ath12k_dp_rx_tid_del_func(struct ath12k_dp *dp, void *ctx, ath12k_dp_rx_process_reo_cmd_update_rx_queue_list(dp); spin_unlock_bh(&dp->dp_lock); - elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + elem = kzalloc_obj(*elem, GFP_ATOMIC); if (!elem) goto free_desc; @@ -565,7 +565,7 @@ static int ath12k_dp_prepare_reo_update_elem(struct ath12k_dp *dp, lockdep_assert_held(&dp->dp_lock); - elem = kzalloc(sizeof(*elem), GFP_ATOMIC); + elem = kzalloc_obj(*elem, GFP_ATOMIC); if (!elem) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 68431a0e128e..b253d1e3f405 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -3838,7 +3838,7 @@ static void ath12k_bss_assoc(struct ath12k *ar, lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); struct ath12k_wmi_peer_assoc_arg *peer_arg __free(kfree) = - kzalloc(sizeof(*peer_arg), GFP_KERNEL); + kzalloc_obj(*peer_arg); if (!peer_arg) return; @@ -4217,7 +4217,7 @@ static struct ath12k_link_vif *ath12k_mac_assign_link_vif(struct ath12k_hw *ah, if (vif->type == NL80211_IFTYPE_STATION) arvif->is_sta_assoc_link = true; } else { - arvif = kzalloc(sizeof(*arvif), GFP_KERNEL); + arvif = kzalloc_obj(*arvif); if (!arvif) return NULL; } @@ -5024,7 +5024,7 @@ static struct ath12k_vif_cache *ath12k_ahvif_get_link_cache(struct ath12k_vif *a u8 link_id) { if (!ahvif->cache[link_id]) { - ahvif->cache[link_id] = kzalloc(sizeof(*ahvif->cache[0]), GFP_KERNEL); + ahvif->cache[link_id] = kzalloc_obj(*ahvif->cache[0]); if (ahvif->cache[link_id]) INIT_LIST_HEAD(&ahvif->cache[link_id]->key_conf.list); } @@ -5430,7 +5430,7 @@ int ath12k_mac_op_get_txpower(struct ieee80211_hw *hw, ar->last_tx_power_update)) goto send_tx_power; - params.pdev_id = ar->pdev->pdev_id; + params.pdev_id = ath12k_mac_get_target_pdev_id(ar); params.vdev_id = arvif->vdev_id; params.stats_id = WMI_REQUEST_PDEV_STAT; ret = ath12k_mac_get_fw_stats(ar, ¶ms); @@ -5602,7 +5602,7 @@ static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, if (ret) goto exit; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) { ret = -ENOMEM; goto exit; @@ -5692,7 +5692,7 @@ int ath12k_mac_op_hw_scan(struct ieee80211_hw *hw, lockdep_assert_wiphy(hw->wiphy); - chan_list = kcalloc(hw_req->req.n_channels, sizeof(*chan_list), GFP_KERNEL); + chan_list = kzalloc_objs(*chan_list, hw_req->req.n_channels); if (!chan_list) return -ENOMEM; @@ -6122,7 +6122,7 @@ static int ath12k_mac_update_key_cache(struct ath12k_vif_cache *cache, } if (cmd == SET_KEY) { - key_conf = kzalloc(sizeof(*key_conf), GFP_KERNEL); + key_conf = kzalloc_obj(*key_conf); if (!key_conf) return -ENOMEM; @@ -6456,7 +6456,7 @@ static int ath12k_mac_station_assoc(struct ath12k *ar, mask = &arvif->bitrate_mask; struct ath12k_wmi_peer_assoc_arg *peer_arg __free(kfree) = - kzalloc(sizeof(*peer_arg), GFP_KERNEL); + kzalloc_obj(*peer_arg); if (!peer_arg) return -ENOMEM; @@ -6619,7 +6619,7 @@ static void ath12k_sta_rc_update_wk(struct wiphy *wiphy, struct wiphy_work *wk) nss = min(nss, mac_nss); struct ath12k_wmi_peer_assoc_arg *peer_arg __free(kfree) = - kzalloc(sizeof(*peer_arg), GFP_KERNEL); + kzalloc_obj(*peer_arg); if (!peer_arg) return; @@ -7974,7 +7974,7 @@ static struct ath12k_link_sta *ath12k_mac_alloc_assign_link_sta(struct ath12k_hw if (arsta) return NULL; - arsta = kmalloc(sizeof(*arsta), GFP_KERNEL); + arsta = kmalloc_obj(*arsta); if (!arsta) return NULL; @@ -11549,7 +11549,7 @@ ath12k_mac_update_active_vif_chan(struct ath12k *ar, if (arg.n_vifs == 0) return; - arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]), GFP_KERNEL); + arg.vifs = kzalloc_objs(arg.vifs[0], arg.n_vifs); if (!arg.vifs) return; @@ -13452,7 +13452,7 @@ void ath12k_mac_op_sta_statistics(struct ieee80211_hw *hw, /* TODO: Use real NF instead of default one. */ signal = rate_info.rssi_comb; - params.pdev_id = ar->pdev->pdev_id; + params.pdev_id = ath12k_mac_get_target_pdev_id(ar); params.vdev_id = 0; params.stats_id = WMI_REQUEST_VDEV_STAT; @@ -13580,7 +13580,7 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, spin_unlock_bh(&ar->ab->dp->dp_lock); if (!signal && ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA) { - params.pdev_id = ar->pdev->pdev_id; + params.pdev_id = ath12k_mac_get_target_pdev_id(ar); params.vdev_id = 0; params.stats_id = WMI_REQUEST_VDEV_STAT; @@ -13714,7 +13714,7 @@ int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, scan_time_msec = hw->wiphy->max_remain_on_channel_duration * 2; struct ath12k_wmi_scan_req_arg *arg __free(kfree) = - kzalloc(sizeof(*arg), GFP_KERNEL); + kzalloc_obj(*arg); if (!arg) return -ENOMEM; @@ -14122,7 +14122,7 @@ ath12k_mac_setup_radio_iface_comb(struct ath12k *ar, max_interfaces = 1; } - limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL); + limits = kzalloc_objs(*limits, n_limits); if (!limits) return -ENOMEM; @@ -14186,7 +14186,7 @@ ath12k_mac_setup_global_iface_comb(struct ath12k_hw *ah, else n_limits = 1; - limits = kcalloc(n_limits, sizeof(*limits), GFP_KERNEL); + limits = kzalloc_objs(*limits, n_limits); if (!limits) return -ENOMEM; @@ -14249,8 +14249,7 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah) if (ar->ab->hw_params->single_pdev_only) n_combinations = 2; - combinations = kcalloc(n_combinations, sizeof(*combinations), - GFP_KERNEL); + combinations = kzalloc_objs(*combinations, n_combinations); if (!combinations) return -ENOMEM; @@ -14271,20 +14270,20 @@ static int ath12k_mac_setup_iface_combinations(struct ath12k_hw *ah) goto out; } - combinations = kcalloc(n_combinations, sizeof(*combinations), GFP_KERNEL); + combinations = kzalloc_objs(*combinations, n_combinations); if (!combinations) return -ENOMEM; /* there are multiple radios */ - radio = kcalloc(ah->num_radio, sizeof(*radio), GFP_KERNEL); + radio = kzalloc_objs(*radio, ah->num_radio); if (!radio) { ret = -ENOMEM; goto err_free_combinations; } for_each_ar(ah, ar, i) { - comb = kzalloc(sizeof(*comb), GFP_KERNEL); + comb = kzalloc_obj(*comb); if (!comb) { ret = -ENOMEM; goto err_free_radios; diff --git a/drivers/net/wireless/ath/ath12k/mhi.c b/drivers/net/wireless/ath/ath12k/mhi.c index 45c0f66dcc5e..ee87f00bc5de 100644 --- a/drivers/net/wireless/ath/ath12k/mhi.c +++ b/drivers/net/wireless/ath/ath12k/mhi.c @@ -80,7 +80,7 @@ static int ath12k_mhi_get_msi(struct ath12k_pci *ab_pci) ath12k_dbg(ab, ATH12K_DBG_PCI, "Number of assigned MSI for MHI is %d, base vector is %d\n", num_vectors, base_vector); - irq = kcalloc(num_vectors, sizeof(*irq), GFP_KERNEL); + irq = kzalloc_objs(*irq, num_vectors); if (!irq) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/peer.c b/drivers/net/wireless/ath/ath12k/peer.c index 5f3bd3b9a3e9..2e875176baaa 100644 --- a/drivers/net/wireless/ath/ath12k/peer.c +++ b/drivers/net/wireless/ath/ath12k/peer.c @@ -413,7 +413,7 @@ int ath12k_link_sta_rhash_tbl_init(struct ath12k_base *ab) struct rhashtable *rhash_addr_tbl; int ret; - rhash_addr_tbl = kzalloc(sizeof(*ab->rhead_sta_addr), GFP_KERNEL); + rhash_addr_tbl = kzalloc_obj(*ab->rhead_sta_addr); if (!rhash_addr_tbl) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index cfde4147c8fc..c11b84b56f8f 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -2344,11 +2344,11 @@ static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab) struct qmi_txn txn; int ret; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) { ret = -ENOMEM; goto resp_out; @@ -2416,7 +2416,7 @@ int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab) int ret = 0, i; bool delayed; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -2968,7 +2968,7 @@ static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab, int ret = 0; u32 remaining = len; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -3465,7 +3465,7 @@ static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab) ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce; svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -3636,7 +3636,7 @@ ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi, { struct ath12k_qmi_driver_event *event; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c index 7898f6981e5a..d784d9ec5061 100644 --- a/drivers/net/wireless/ath/ath12k/reg.c +++ b/drivers/net/wireless/ath/ath12k/reg.c @@ -170,7 +170,7 @@ int ath12k_reg_update_chan_list(struct ath12k *ar, bool wait) return -EINVAL; } - arg = kzalloc(struct_size(arg, channel, num_channels), GFP_KERNEL); + arg = kzalloc_flex(*arg, channel, num_channels); if (!arg) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp.c b/drivers/net/wireless/ath/ath12k/wifi7/dp.c index 2b194879ee80..c72f604661ce 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp.c @@ -161,7 +161,7 @@ struct ath12k_dp *ath12k_wifi7_dp_device_alloc(struct ath12k_base *ab) struct ath12k_dp *dp; /* TODO: align dp later if cache alignment becomes a bottleneck */ - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); if (!dp) return NULL; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c index bd741532b7dc..c9cea597a92e 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_mon.c @@ -1800,7 +1800,7 @@ ath12k_wifi7_dp_mon_parse_rx_dest_tlv(struct ath12k_pdev_dp *dp_pdev, if (WARN_ON_ONCE(pmon->mon_mpdu)) break; - pmon->mon_mpdu = kzalloc(sizeof(*pmon->mon_mpdu), GFP_ATOMIC); + pmon->mon_mpdu = kzalloc_obj(*pmon->mon_mpdu, GFP_ATOMIC); if (!pmon->mon_mpdu) return -ENOMEM; break; @@ -1849,7 +1849,7 @@ ath12k_wifi7_dp_mon_tx_get_ppdu_info(struct ath12k_mon_data *pmon, } /* allocate new tx_ppdu_info */ - tx_ppdu_info = kzalloc(sizeof(*tx_ppdu_info), GFP_ATOMIC); + tx_ppdu_info = kzalloc_obj(*tx_ppdu_info, GFP_ATOMIC); if (!tx_ppdu_info) return NULL; @@ -2383,7 +2383,7 @@ ath12k_wifi7_dp_mon_tx_parse_status_tlv(struct ath12k_base *ab, case HAL_TX_MPDU_START: { struct dp_mon_mpdu *mon_mpdu = tx_ppdu_info->tx_mon_mpdu; - mon_mpdu = kzalloc(sizeof(*mon_mpdu), GFP_ATOMIC); + mon_mpdu = kzalloc_obj(*mon_mpdu, GFP_ATOMIC); if (!mon_mpdu) return DP_MON_TX_STATUS_PPDU_NOT_DONE; status = DP_MON_TX_MPDU_START; @@ -2853,7 +2853,7 @@ ath12k_wifi7_dp_rx_mon_dest_process(struct ath12k *ar, int mac_id, } if (head_msdu && tail_msdu) { - tmp_mpdu = kzalloc(sizeof(*tmp_mpdu), GFP_ATOMIC); + tmp_mpdu = kzalloc_obj(*tmp_mpdu, GFP_ATOMIC); if (!tmp_mpdu) break; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c index 7450938adf65..038e339e8fb1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/dp_rx.c @@ -165,7 +165,7 @@ int ath12k_wifi7_dp_reo_cmd_send(struct ath12k_base *ab, * for tid delete command to free up the resource on the command status * indication? */ - dp_cmd = kzalloc(sizeof(*dp_cmd), GFP_ATOMIC); + dp_cmd = kzalloc_obj(*dp_cmd, GFP_ATOMIC); if (!dp_cmd) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c index b8d972659314..988affafcfd1 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/mhi.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/mhi.c @@ -20,7 +20,6 @@ static const struct mhi_channel_config ath12k_wifi7_mhi_channels_qcn9274[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, }, { .num = 21, @@ -34,7 +33,6 @@ static const struct mhi_channel_config ath12k_wifi7_mhi_channels_qcn9274[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, }, }; @@ -85,7 +83,6 @@ static const struct mhi_channel_config ath12k_wifi7_mhi_channels_wcn7850[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = false, }, { .num = 21, @@ -99,7 +96,6 @@ static const struct mhi_channel_config ath12k_wifi7_mhi_channels_wcn7850[] = { .lpm_notify = false, .offload_channel = false, .doorbell_mode_switch = false, - .auto_queue = true, }, }; diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c index 7617fc3a2479..48fee9346de8 100644 --- a/drivers/net/wireless/ath/ath12k/wmi.c +++ b/drivers/net/wireless/ath/ath12k/wmi.c @@ -303,7 +303,7 @@ ath12k_wmi_tlv_parse_alloc(struct ath12k_base *ab, const void **tb; int ret; - tb = kcalloc(WMI_TAG_MAX, sizeof(*tb), gfp); + tb = kzalloc_objs(*tb, WMI_TAG_MAX, gfp); if (!tb) return ERR_PTR(-ENOMEM); @@ -6867,7 +6867,7 @@ static int ath12k_reg_chan_list_event(struct ath12k_base *ab, struct sk_buff *sk u8 pdev_idx = 255; int ret; - reg_info = kzalloc(sizeof(*reg_info), GFP_ATOMIC); + reg_info = kzalloc_obj(*reg_info, GFP_ATOMIC); if (!reg_info) { ret = -ENOMEM; goto fallback; @@ -8241,8 +8241,6 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab, struct ath12k_fw_stats *stats = parse->stats; struct ath12k *ar; struct ath12k_link_vif *arvif; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; struct ath12k_link_sta *arsta; int i, ret = 0; const void *data = ptr; @@ -8278,26 +8276,24 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab, arvif = ath12k_mac_get_arvif(ar, le32_to_cpu(src->vdev_id)); if (arvif) { - sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar), - arvif->bssid, - NULL); - if (sta) { - ahsta = ath12k_sta_to_ahsta(sta); - arsta = &ahsta->deflink; + spin_lock_bh(&ab->base_lock); + arsta = ath12k_link_sta_find_by_addr(ab, arvif->bssid); + if (arsta) { arsta->rssi_beacon = le32_to_cpu(src->beacon_snr); ath12k_dbg(ab, ATH12K_DBG_WMI, "wmi stats vdev id %d snr %d\n", src->vdev_id, src->beacon_snr); } else { - ath12k_dbg(ab, ATH12K_DBG_WMI, - "not found station bssid %pM for vdev stat\n", - arvif->bssid); + ath12k_warn(ab, + "not found link sta with bssid %pM for vdev stat\n", + arvif->bssid); } + spin_unlock_bh(&ab->base_lock); } data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; ath12k_wmi_pull_vdev_stats(src, dst); @@ -8316,7 +8312,7 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab, data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; ath12k_wmi_pull_bcn_stats(src, dst); @@ -8338,7 +8334,7 @@ static int ath12k_wmi_tlv_fw_stats_data_parse(struct ath12k_base *ab, data += sizeof(*src); len -= sizeof(*src); - dst = kzalloc(sizeof(*dst), GFP_ATOMIC); + dst = kzalloc_obj(*dst, GFP_ATOMIC); if (!dst) continue; @@ -8363,8 +8359,6 @@ static int ath12k_wmi_tlv_rssi_chain_parse(struct ath12k_base *ab, struct ath12k_fw_stats *stats = parse->stats; struct ath12k_link_vif *arvif; struct ath12k_link_sta *arsta; - struct ieee80211_sta *sta; - struct ath12k_sta *ahsta; struct ath12k *ar; int vdev_id; int j; @@ -8400,19 +8394,15 @@ static int ath12k_wmi_tlv_rssi_chain_parse(struct ath12k_base *ab, "stats bssid %pM vif %p\n", arvif->bssid, arvif->ahvif->vif); - sta = ieee80211_find_sta_by_ifaddr(ath12k_ar_to_hw(ar), - arvif->bssid, - NULL); - if (!sta) { - ath12k_dbg(ab, ATH12K_DBG_WMI, - "not found station of bssid %pM for rssi chain\n", - arvif->bssid); + guard(spinlock_bh)(&ab->base_lock); + arsta = ath12k_link_sta_find_by_addr(ab, arvif->bssid); + if (!arsta) { + ath12k_warn(ab, + "not found link sta with bssid %pM for rssi chain\n", + arvif->bssid); return -EPROTO; } - ahsta = ath12k_sta_to_ahsta(sta); - arsta = &ahsta->deflink; - BUILD_BUG_ON(ARRAY_SIZE(arsta->chain_signal) > ARRAY_SIZE(stats_rssi->rssi_avg_beacon)); @@ -9559,8 +9549,7 @@ static void ath12k_wmi_process_tpc_stats(struct ath12k_base *ab, goto unlock; } ar->debug.tpc_stats = - kzalloc(sizeof(struct wmi_tpc_stats_arg), - GFP_ATOMIC); + kzalloc_obj(struct wmi_tpc_stats_arg, GFP_ATOMIC); if (!ar->debug.tpc_stats) { ath12k_warn(ab, "Failed to allocate memory for tpc stats\n"); diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c index bb08e1740582..d8789104d886 100644 --- a/drivers/net/wireless/ath/ath12k/wow.c +++ b/drivers/net/wireless/ath/ath12k/wow.c @@ -395,7 +395,7 @@ static int ath12k_wow_vif_set_wakeups(struct ath12k_link_vif *arvif, struct wmi_pno_scan_req_arg *pno; int ret; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; @@ -507,7 +507,7 @@ static int ath12k_wow_vdev_clean_nlo(struct ath12k *ar, u32 vdev_id) if (!ar->nlo_enabled) return 0; - pno = kzalloc(sizeof(*pno), GFP_KERNEL); + pno = kzalloc_obj(*pno); if (!pno) return -ENOMEM; @@ -748,7 +748,7 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy); - offload = kmalloc(sizeof(*offload), GFP_KERNEL); + offload = kmalloc_obj(*offload); if (!offload) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4d88b02ffa79..05c9c07591fc 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -919,8 +919,8 @@ ath5k_desc_alloc(struct ath5k_hw *ah) ATH5K_DBG(ah, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n", ds, ah->desc_len, (unsigned long long)ah->desc_daddr); - bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF, - sizeof(struct ath5k_buf), GFP_KERNEL); + bf = kzalloc_objs(struct ath5k_buf, + 1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF); if (bf == NULL) { ATH5K_ERR(ah, "can't allocate bufptr\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index ec130510aeb2..25edc35dc7b9 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c @@ -928,7 +928,7 @@ static int open_file_eeprom(struct inode *inode, struct file *file) /* Create private struct and assign to file */ - ep = kmalloc(sizeof(*ep), GFP_KERNEL); + ep = kmalloc_obj(*ep); if (!ep) { ret = -ENOMEM; goto freebuf; diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 58d3e86f6256..e163706f8728 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -727,9 +727,8 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); + kzalloc_objs(struct ath5k_pdgain_info, + AR5K_EEPROM_N_PD_CURVES); if (!chinfo[pier].pd_curves) goto err_out; @@ -761,8 +760,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode, if (!pd->pd_step) goto err_out; - pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111, - sizeof(s16), GFP_KERNEL); + pd->pd_pwr = kzalloc_objs(s16, AR5K_EEPROM_N_PWR_POINTS_5111); if (!pd->pd_pwr) goto err_out; @@ -917,9 +915,8 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); + kzalloc_objs(struct ath5k_pdgain_info, + AR5K_EEPROM_N_PD_CURVES); if (!chinfo[pier].pd_curves) goto err_out; @@ -943,8 +940,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, if (!pd->pd_step) goto err_out; - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); + pd->pd_pwr = kzalloc_objs(s16, pd->pd_points); if (!pd->pd_pwr) goto err_out; @@ -981,8 +977,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode, if (!pd->pd_step) goto err_out; - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); + pd->pd_pwr = kzalloc_objs(s16, pd->pd_points); if (!pd->pd_pwr) goto err_out; @@ -1209,9 +1204,8 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, /* Allocate pd_curves for this cal pier */ chinfo[pier].pd_curves = - kcalloc(AR5K_EEPROM_N_PD_CURVES, - sizeof(struct ath5k_pdgain_info), - GFP_KERNEL); + kzalloc_objs(struct ath5k_pdgain_info, + AR5K_EEPROM_N_PD_CURVES); if (!chinfo[pier].pd_curves) goto err_out; @@ -1237,8 +1231,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode, if (!pd->pd_step) goto err_out; - pd->pd_pwr = kcalloc(pd->pd_points, - sizeof(s16), GFP_KERNEL); + pd->pd_pwr = kzalloc_objs(s16, pd->pd_points); if (!pd->pd_pwr) goto err_out; diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 830350bda531..648110cd313f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -311,7 +311,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev) ar->sta_list[ctr].mgmt_psq_len = 0; INIT_LIST_HEAD(&ar->sta_list[ctr].mgmt_psq); ar->sta_list[ctr].aggr_conn = - kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + kzalloc_obj(struct aggr_info_conn); if (!ar->sta_list[ctr].aggr_conn) { ath6kl_err("Failed to allocate memory for sta aggregation information\n"); ath6kl_core_destroy(ar); diff --git a/drivers/net/wireless/ath/ath6kl/htc_mbox.c b/drivers/net/wireless/ath/ath6kl/htc_mbox.c index 122e07ef3965..9ece8f9983f1 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_mbox.c +++ b/drivers/net/wireless/ath/ath6kl/htc_mbox.c @@ -2792,7 +2792,7 @@ static int ath6kl_htc_reset(struct htc_target *target) (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH); for (i = 0; i < NUM_CONTROL_BUFFERS; i++) { - packet = kzalloc(sizeof(*packet), GFP_KERNEL); + packet = kzalloc_obj(*packet); if (!packet) return -ENOMEM; @@ -2842,13 +2842,13 @@ static void *ath6kl_htc_mbox_create(struct ath6kl *ar) struct htc_target *target = NULL; int status = 0; - target = kzalloc(sizeof(*target), GFP_KERNEL); + target = kzalloc_obj(*target); if (!target) { ath6kl_err("unable to allocate memory\n"); return NULL; } - target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL); + target->dev = kzalloc_obj(*target->dev); if (!target->dev) { ath6kl_err("unable to allocate memory\n"); kfree(target); diff --git a/drivers/net/wireless/ath/ath6kl/htc_pipe.c b/drivers/net/wireless/ath/ath6kl/htc_pipe.c index 7b823be9d846..5183e3029886 100644 --- a/drivers/net/wireless/ath/ath6kl/htc_pipe.c +++ b/drivers/net/wireless/ath/ath6kl/htc_pipe.c @@ -510,7 +510,7 @@ static struct htc_packet *build_htc_txctrl_packet(void) struct htc_packet *packet = NULL; struct sk_buff *skb; - packet = kzalloc(sizeof(struct htc_packet), GFP_KERNEL); + packet = kzalloc_obj(struct htc_packet); if (packet == NULL) return NULL; @@ -1409,7 +1409,7 @@ static void *ath6kl_htc_pipe_create(struct ath6kl *ar) struct htc_packet *packet; int i; - target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); + target = kzalloc_obj(struct htc_target); if (target == NULL) { ath6kl_err("htc create unable to allocate memory\n"); status = -ENOMEM; @@ -1423,13 +1423,13 @@ static void *ath6kl_htc_pipe_create(struct ath6kl *ar) reset_endpoint_states(target); for (i = 0; i < HTC_PACKET_CONTAINER_ALLOCATION; i++) { - packet = kzalloc(sizeof(struct htc_packet), GFP_KERNEL); + packet = kzalloc_obj(struct htc_packet); if (packet != NULL) free_htc_packet_container(target, packet); } - target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL); + target->dev = kzalloc_obj(*target->dev); if (!target->dev) { ath6kl_err("unable to allocate memory\n"); status = -ENOMEM; diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 59068ea3879b..85d6ad53cf94 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -485,7 +485,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, keymgmt, ucipher, auth, apsd_info); /* send event to application */ - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return; @@ -1249,8 +1249,8 @@ static void ath6kl_set_multicast_list(struct net_device *ndev) } if (!found) { - mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter), - GFP_ATOMIC); + mc_filter = kzalloc_obj(struct ath6kl_mc_filter, + GFP_ATOMIC); if (!mc_filter) { WARN_ON(1); goto out; diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 83de40bc4445..56929e965bd6 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1316,7 +1316,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize); - ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL); + ar_sdio = kzalloc_obj(struct ath6kl_sdio); if (!ar_sdio) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index c3b06b515c4f..97fdac7237e2 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1770,13 +1770,13 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) { struct aggr_info *p_aggr = NULL; - p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); + p_aggr = kzalloc_obj(struct aggr_info); if (!p_aggr) { ath6kl_err("failed to alloc memory for aggr_node\n"); return NULL; } - p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + p_aggr->aggr_conn = kzalloc_obj(struct aggr_info_conn); if (!p_aggr->aggr_conn) { ath6kl_err("failed to alloc memory for connection specific aggr info\n"); kfree(p_aggr); diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index 38bb501fc553..852e77e41bde 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -190,8 +190,7 @@ static int ath6kl_usb_alloc_pipe_resources(struct ath6kl_usb_pipe *pipe, init_usb_anchor(&pipe->urb_submitted); for (i = 0; i < urb_cnt; i++) { - urb_context = kzalloc(sizeof(struct ath6kl_urb_context), - GFP_KERNEL); + urb_context = kzalloc_obj(struct ath6kl_urb_context); if (urb_context == NULL) { status = -ENOMEM; goto fail_alloc_pipe_resources; @@ -634,7 +633,7 @@ static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) int i; /* ath6kl_usb_destroy() needs ar_usb != NULL && ar_usb->wq != NULL. */ - ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); + ar_usb = kzalloc_obj(struct ath6kl_usb); if (ar_usb == NULL) return NULL; ar_usb->wq = alloc_workqueue("ath6kl_wq", 0, 0); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 08a154bce139..72611a2ceb9d 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -4135,7 +4135,7 @@ void *ath6kl_wmi_init(struct ath6kl *dev) { struct wmi *wmi; - wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL); + wmi = kzalloc_obj(struct wmi); if (!wmi) return NULL; diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index fe9abe8cd268..8533b88974b2 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -107,7 +107,7 @@ static int hif_usb_send_regout(struct hif_device_usb *hif_dev, if (urb == NULL) return -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) { usb_free_urb(urb); return -ENOMEM; @@ -190,7 +190,7 @@ static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev, if (urb == NULL) return -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC); + cmd = kzalloc_obj(*cmd, GFP_ATOMIC); if (cmd == NULL) { usb_free_urb(urb); return -ENOMEM; @@ -849,7 +849,7 @@ static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) init_usb_anchor(&hif_dev->mgmt_submitted); for (i = 0; i < MAX_TX_URB_NUM; i++) { - tx_buf = kzalloc(sizeof(*tx_buf), GFP_KERNEL); + tx_buf = kzalloc_obj(*tx_buf); if (!tx_buf) goto err; @@ -897,7 +897,7 @@ static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) for (i = 0; i < MAX_RX_URB_NUM; i++) { - rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + rx_buf = kzalloc_obj(*rx_buf); if (!rx_buf) { ret = -ENOMEM; goto err_rxb; @@ -972,7 +972,7 @@ static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev) for (i = 0; i < MAX_REG_IN_URB_NUM; i++) { - rx_buf = kzalloc(sizeof(*rx_buf), GFP_KERNEL); + rx_buf = kzalloc_obj(*rx_buf); if (!rx_buf) { ret = -ENOMEM; goto err_rxb; @@ -1376,7 +1376,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, if (id->driver_info == STORAGE_DEVICE) return send_eject_command(interface); - hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); + hif_dev = kzalloc_obj(struct hif_device_usb); if (!hif_dev) { ret = -ENOMEM; goto err_alloc; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 3633f9eb2c55..5270d0c0af17 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -611,7 +611,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, struct ath_common *common; int i, ret = 0, csz = 0; - ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); + ah = kzalloc_obj(struct ath_hw); if (!ah) return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index ee5945cfc10e..bed7ea2425a0 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -664,8 +664,8 @@ void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event) * Store this event, so that the TX cleanup * routine can check later for the needed packet. */ - tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event), - GFP_ATOMIC); + tx_pend = kzalloc_obj(struct ath9k_htc_tx_event, + GFP_ATOMIC); if (!tx_pend) continue; @@ -1193,7 +1193,7 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv) for (i = 0; i < ATH9K_HTC_RXBUF; i++) { struct ath9k_htc_rxbuf *rxbuf = - kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL); + kzalloc_obj(struct ath9k_htc_rxbuf); if (rxbuf == NULL) goto err; diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index b5257b2b4aa5..efd73f2ffda6 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -499,7 +499,7 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct htc_endpoint *endpoint; struct htc_target *target; - target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); + target = kzalloc_obj(struct htc_target); if (!target) return NULL; diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 14de62c1a32b..a45351afcf6e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -3128,7 +3128,7 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, !AR_SREV_9300_20_OR_LATER(ah)) return NULL; - timer = kzalloc(sizeof(struct ath_gen_timer), GFP_KERNEL); + timer = kzalloc_obj(struct ath_gen_timer); if (timer == NULL) return NULL; diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index a0845002d6fe..f82bb2349928 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -53,7 +53,7 @@ static bool ath_mci_add_profile(struct ath_common *common, (info->type != MCI_GPM_COEX_PROFILE_VOICE)) return false; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return false; diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c index 805ad31edba2..284e8c13b043 100644 --- a/drivers/net/wireless/ath/ath9k/wmi.c +++ b/drivers/net/wireless/ath/ath9k/wmi.c @@ -92,7 +92,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) { struct wmi *wmi; - wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL); + wmi = kzalloc_obj(struct wmi); if (!wmi) return NULL; diff --git a/drivers/net/wireless/ath/carl9170/cmd.c b/drivers/net/wireless/ath/carl9170/cmd.c index b8ed193c0195..402fd0633e09 100644 --- a/drivers/net/wireless/ath/carl9170/cmd.c +++ b/drivers/net/wireless/ath/carl9170/cmd.c @@ -120,7 +120,7 @@ struct carl9170_cmd *carl9170_cmd_buf(struct ar9170 *ar, { struct carl9170_cmd *tmp; - tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); + tmp = kzalloc_obj(*tmp, GFP_ATOMIC); if (tmp) { tmp->hdr.cmd = cmd; tmp->hdr.len = len; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a7a9345f3483..af632418fa06 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1412,8 +1412,7 @@ static int carl9170_op_ampdu_action(struct ieee80211_hw *hw, if (!sta_info->ht_sta) return -EOPNOTSUPP; - tid_info = kzalloc(sizeof(struct carl9170_sta_tid), - GFP_KERNEL); + tid_info = kzalloc_obj(struct carl9170_sta_tid); if (!tid_info) return -ENOMEM; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b7717f9e1e9b..59caf1e4b158 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -1328,7 +1328,7 @@ static void carl9170_bar_check(struct ar9170 *ar, struct sk_buff *skb) struct carl9170_bar_list_entry *entry; unsigned int queue = skb_get_queue_mapping(skb); - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!WARN_ON_ONCE(!entry)) { entry->skb = skb; spin_lock_bh(&ar->bar_list_lock[queue]); diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c index 700da9f4531e..ce5a6a39c0ad 100644 --- a/drivers/net/wireless/ath/dfs_pattern_detector.c +++ b/drivers/net/wireless/ath/dfs_pattern_detector.c @@ -199,7 +199,7 @@ channel_detector_create(struct dfs_pattern_detector *dpd, u16 freq) u32 i; struct channel_detector *cd; - cd = kzalloc(struct_size(cd, detectors, dpd->num_radar_types), GFP_ATOMIC); + cd = kzalloc_flex(*cd, detectors, dpd->num_radar_types, GFP_ATOMIC); if (cd == NULL) goto fail; @@ -354,7 +354,7 @@ dfs_pattern_detector_init(struct ath_common *common, if (!IS_ENABLED(CONFIG_CFG80211_CERTIFICATION_ONUS)) return NULL; - dpd = kmalloc(sizeof(*dpd), GFP_KERNEL); + dpd = kmalloc_obj(*dpd); if (dpd == NULL) return NULL; diff --git a/drivers/net/wireless/ath/dfs_pri_detector.c b/drivers/net/wireless/ath/dfs_pri_detector.c index d07c454c9c00..388f9d1913bd 100644 --- a/drivers/net/wireless/ath/dfs_pri_detector.c +++ b/drivers/net/wireless/ath/dfs_pri_detector.c @@ -202,7 +202,7 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts) { struct pulse_elem *p = pool_get_pulse_elem(); if (p == NULL) { - p = kmalloc(sizeof(*p), GFP_ATOMIC); + p = kmalloc_obj(*p, GFP_ATOMIC); if (p == NULL) { DFS_POOL_STAT_INC(pulse_alloc_error); return false; @@ -284,7 +284,7 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde, ps.deadline_ts = ps.first_ts + ps.dur; new_ps = pool_get_pseq_elem(); if (new_ps == NULL) { - new_ps = kmalloc(sizeof(*new_ps), GFP_ATOMIC); + new_ps = kmalloc_obj(*new_ps, GFP_ATOMIC); if (new_ps == NULL) { DFS_POOL_STAT_INC(pseq_alloc_error); return false; @@ -418,7 +418,7 @@ struct pri_detector *pri_detector_init(const struct radar_detector_specs *rs) { struct pri_detector *de; - de = kzalloc(sizeof(*de), GFP_ATOMIC); + de = kzalloc_obj(*de, GFP_ATOMIC); if (de == NULL) return NULL; de->exit = pri_detector_exit; diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index 0f4df5585fd9..5a0ef2295a3a 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c @@ -74,7 +74,7 @@ static int wcn36xx_dxe_allocate_ctl_block(struct wcn36xx_dxe_ch *ch) spin_lock_init(&ch->lock); for (i = 0; i < ch->desc_num; i++) { - cur_ctl = kzalloc(sizeof(*cur_ctl), GFP_KERNEL); + cur_ctl = kzalloc_obj(*cur_ctl); if (!cur_ctl) goto out_fail; diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 02a525645bfa..c3f0860873de 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -462,7 +462,7 @@ static u64 wcn36xx_prepare_multicast(struct ieee80211_hw *hw, struct netdev_hw_addr *ha; wcn36xx_dbg(WCN36XX_DBG_MAC, "mac prepare multicast list\n"); - fp = kzalloc(sizeof(*fp), GFP_ATOMIC); + fp = kzalloc_obj(*fp, GFP_ATOMIC); if (!fp) { wcn36xx_err("Out of memory setting filters.\n"); return 0; diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c index 136acc414714..813553edcb78 100644 --- a/drivers/net/wireless/ath/wcn36xx/smd.c +++ b/drivers/net/wireless/ath/wcn36xx/smd.c @@ -847,7 +847,7 @@ int wcn36xx_smd_start_hw_scan(struct wcn36xx *wcn, struct ieee80211_vif *vif, return -EINVAL; mutex_lock(&wcn->hal_mutex); - msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); + msg_body = kzalloc_obj(*msg_body); if (!msg_body) { ret = -ENOMEM; goto out; @@ -942,7 +942,7 @@ int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_re struct wcn36xx_hal_update_channel_list_req_msg *msg_body; int ret, i; - msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); + msg_body = kzalloc_obj(*msg_body); if (!msg_body) return -ENOMEM; @@ -1624,7 +1624,7 @@ static int wcn36xx_smd_config_bss_v1(struct wcn36xx *wcn, struct cfg80211_chan_def *chandef; int ret; - msg_body = kzalloc(sizeof(*msg_body), GFP_KERNEL); + msg_body = kzalloc_obj(*msg_body); if (!msg_body) return -ENOMEM; @@ -1744,7 +1744,7 @@ static int wcn36xx_smd_config_bss_v0(struct wcn36xx *wcn, struct wcn36xx_hal_config_sta_params *sta_params; int ret; - msg = kzalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc_obj(*msg); if (!msg) return -ENOMEM; @@ -3306,7 +3306,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev, case WCN36XX_HAL_DELETE_STA_CONTEXT_IND: case WCN36XX_HAL_PRINT_REG_INFO_IND: case WCN36XX_HAL_SCAN_OFFLOAD_IND: - msg_ind = kmalloc(struct_size(msg_ind, msg, len), GFP_ATOMIC); + msg_ind = kmalloc_flex(*msg_ind, msg, len, GFP_ATOMIC); if (!msg_ind) { wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n", msg_header->msg_type); diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index 7218fe70f3bc..c74f5e66166d 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c @@ -691,7 +691,7 @@ wil_cfg80211_add_iface(struct wiphy *wiphy, const char *name, return ERR_PTR(-EINVAL); } - p2p_wdev = kzalloc(sizeof(*p2p_wdev), GFP_KERNEL); + p2p_wdev = kzalloc_obj(*p2p_wdev); if (!p2p_wdev) return ERR_PTR(-ENOMEM); @@ -2394,7 +2394,7 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy, if (cid < 0) return -ENOLINK; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index c021ebcddee7..b8cb736a7185 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c @@ -1392,7 +1392,7 @@ static int link_show(struct seq_file *s, void *data) struct station_info *sinfo; int i, rc = 0; - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return -ENOMEM; @@ -2441,9 +2441,8 @@ int wil6210_debugfs_init(struct wil6210_priv *wil) if (IS_ERR_OR_NULL(dbg)) return -ENODEV; - wil->dbg_data.data_arr = kcalloc(dbg_off_count, - sizeof(struct wil_debugfs_iomem_data), - GFP_KERNEL); + wil->dbg_data.data_arr = kzalloc_objs(struct wil_debugfs_iomem_data, + dbg_off_count); if (!wil->dbg_data.data_arr) { debugfs_remove_recursive(dbg); wil->debug = NULL; diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c index c3c0b289dcf3..e998627141a0 100644 --- a/drivers/net/wireless/ath/wil6210/fw_inc.c +++ b/drivers/net/wireless/ath/wil6210/fw_inc.c @@ -160,8 +160,7 @@ fw_handle_brd_file(struct wil6210_priv *wil, const void *data, return -EINVAL; } - wil->brd_info = kcalloc(max_num_ent, sizeof(struct wil_brd_info), - GFP_KERNEL); + wil->brd_info = kzalloc_objs(struct wil_brd_info, max_num_ent); if (!wil->brd_info) return -ENOMEM; diff --git a/drivers/net/wireless/ath/wil6210/pmc.c b/drivers/net/wireless/ath/wil6210/pmc.c index a2f7b4c1da48..cdc38ebf8d41 100644 --- a/drivers/net/wireless/ath/wil6210/pmc.c +++ b/drivers/net/wireless/ath/wil6210/pmc.c @@ -85,9 +85,7 @@ void wil_pmc_alloc(struct wil6210_priv *wil, num_descriptors, descriptor_size); /* allocate descriptors info list in pmc context*/ - pmc->descriptors = kcalloc(num_descriptors, - sizeof(struct desc_alloc_info), - GFP_KERNEL); + pmc->descriptors = kzalloc_objs(struct desc_alloc_info, num_descriptors); if (!pmc->descriptors) { wil_err(wil, "ERROR allocating pmc skb list\n"); goto no_release_err; diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c index d385bc03033a..5841098ff8f9 100644 --- a/drivers/net/wireless/ath/wil6210/rx_reorder.c +++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c @@ -241,13 +241,13 @@ void wil_rx_bar(struct wil6210_priv *wil, struct wil6210_vif *vif, struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, int size, u16 ssn) { - struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL); + struct wil_tid_ampdu_rx *r = kzalloc_obj(*r); if (!r) return NULL; r->reorder_buf = - kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL); + kzalloc_objs(struct sk_buff *, size); if (!r->reorder_buf) { kfree(r); return NULL; diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 19702b6f09c3..e8320607603e 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c @@ -119,7 +119,7 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct wil_ring *vring) vring->swhead = 0; vring->swtail = 0; - vring->ctx = kcalloc(vring->size, sizeof(vring->ctx[0]), GFP_KERNEL); + vring->ctx = kzalloc_objs(vring->ctx[0], vring->size); if (!vring->ctx) { vring->va = NULL; return -ENOMEM; diff --git a/drivers/net/wireless/ath/wil6210/txrx_edma.c b/drivers/net/wireless/ath/wil6210/txrx_edma.c index 1ba1f21ebea2..1c54f50d0cc5 100644 --- a/drivers/net/wireless/ath/wil6210/txrx_edma.c +++ b/drivers/net/wireless/ath/wil6210/txrx_edma.c @@ -314,9 +314,7 @@ static int wil_init_rx_buff_arr(struct wil6210_priv *wil, struct list_head *free = &wil->rx_buff_mgmt.free; int i; - wil->rx_buff_mgmt.buff_arr = kcalloc(size + 1, - sizeof(struct wil_rx_buff), - GFP_KERNEL); + wil->rx_buff_mgmt.buff_arr = kzalloc_objs(struct wil_rx_buff, size + 1); if (!wil->rx_buff_mgmt.buff_arr) return -ENOMEM; @@ -382,7 +380,7 @@ static int wil_ring_alloc_desc_ring(struct wil6210_priv *wil, ring->swhead = 0; ring->swtail = 0; - ring->ctx = kcalloc(ring->size, sizeof(ring->ctx[0]), GFP_KERNEL); + ring->ctx = kzalloc_objs(ring->ctx[0], ring->size); if (!ring->ctx) goto err; diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index 6d376f85fbde..05b040c684e8 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c @@ -1080,7 +1080,7 @@ static void wmi_evt_connect(struct wil6210_vif *vif, int id, void *d, int len) goto out; } - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) { rc = -ENOMEM; goto out; diff --git a/drivers/net/wireless/atmel/at76c50x-usb.c b/drivers/net/wireless/atmel/at76c50x-usb.c index aa683eacaf38..6445332801a4 100644 --- a/drivers/net/wireless/atmel/at76c50x-usb.c +++ b/drivers/net/wireless/atmel/at76c50x-usb.c @@ -378,7 +378,7 @@ static int at76_usbdfu_download(struct usb_device *udev, u8 *buf, u32 size, return -EINVAL; } - dfu_stat_buf = kmalloc(sizeof(*dfu_stat_buf), GFP_KERNEL); + dfu_stat_buf = kmalloc_obj(*dfu_stat_buf); if (!dfu_stat_buf) { ret = -ENOMEM; goto exit; @@ -607,7 +607,7 @@ static inline int at76_get_hw_cfg_intersil(struct usb_device *udev, static int at76_get_hw_config(struct at76_priv *priv) { int ret; - union at76_hwcfg *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL); + union at76_hwcfg *hwcfg = kmalloc_obj(*hwcfg); if (!hwcfg) return -ENOMEM; @@ -931,7 +931,7 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) { int i; int ret; - struct mib_mac_addr *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_mac_addr *m = kmalloc_obj(*m); if (!m) return; @@ -959,7 +959,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) int i; int ret; int key_len; - struct mib_mac_wep *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_mac_wep *m = kmalloc_obj(*m); if (!m) return; @@ -994,7 +994,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) { int ret; - struct mib_mac_mgmt *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_mac_mgmt *m = kmalloc_obj(*m); if (!m) return; @@ -1030,7 +1030,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) static void at76_dump_mib_mac(struct at76_priv *priv) { int ret; - struct mib_mac *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_mac *m = kmalloc_obj(*m); if (!m) return; @@ -1067,7 +1067,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) static void at76_dump_mib_phy(struct at76_priv *priv) { int ret; - struct mib_phy *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_phy *m = kmalloc_obj(*m); if (!m) return; @@ -1100,7 +1100,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv) static void at76_dump_mib_local(struct at76_priv *priv) { int ret; - struct mib_local *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_local *m = kmalloc_obj(*m); if (!m) return; @@ -1125,7 +1125,7 @@ static void at76_dump_mib_local(struct at76_priv *priv) static void at76_dump_mib_mdomain(struct at76_priv *priv) { int ret; - struct mib_mdomain *m = kmalloc(sizeof(*m), GFP_KERNEL); + struct mib_mdomain *m = kmalloc_obj(*m); if (!m) return; @@ -2442,7 +2442,7 @@ static int at76_probe(struct usb_interface *interface, udev = usb_get_dev(interface_to_usbdev(interface)); - fwv = kmalloc(sizeof(*fwv), GFP_KERNEL); + fwv = kmalloc_obj(*fwv); if (!fwv) { ret = -ENOMEM; goto exit; diff --git a/drivers/net/wireless/broadcom/b43/bus.c b/drivers/net/wireless/broadcom/b43/bus.c index fdb1c82892d6..3ed329a39daf 100644 --- a/drivers/net/wireless/broadcom/b43/bus.c +++ b/drivers/net/wireless/broadcom/b43/bus.c @@ -74,7 +74,7 @@ void b43_bus_bcma_block_write(struct b43_bus_dev *dev, const void *buffer, struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core) { - struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct b43_bus_dev *dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -179,7 +179,7 @@ struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) { struct b43_bus_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/drivers/net/wireless/broadcom/b43/debugfs.c b/drivers/net/wireless/broadcom/b43/debugfs.c index 5a49970afc8c..acddae68947a 100644 --- a/drivers/net/wireless/broadcom/b43/debugfs.c +++ b/drivers/net/wireless/broadcom/b43/debugfs.c @@ -670,15 +670,14 @@ void b43_debugfs_add_device(struct b43_wldev *dev) char devdir[16]; B43_WARN_ON(!dev); - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { b43err(dev->wl, "debugfs: add device OOM\n"); return; } e->dev = dev; log = &e->txstatlog; - log->log = kcalloc(B43_NR_LOGGED_TXSTATUS, - sizeof(struct b43_txstatus), GFP_KERNEL); + log->log = kzalloc_objs(struct b43_txstatus, B43_NR_LOGGED_TXSTATUS); if (!log->log) { b43err(dev->wl, "debugfs: add device txstatus OOM\n"); kfree(e); diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c index 6ac7dcebfff9..3a8df7a18042 100644 --- a/drivers/net/wireless/broadcom/b43/dma.c +++ b/drivers/net/wireless/broadcom/b43/dma.c @@ -838,7 +838,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, int i, err; dma_addr_t dma_test; - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) goto out; @@ -846,8 +846,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, if (for_tx) ring->nr_slots = B43_TXRING_SLOTS; - ring->meta = kcalloc(ring->nr_slots, sizeof(struct b43_dmadesc_meta), - GFP_KERNEL); + ring->meta = kzalloc_objs(struct b43_dmadesc_meta, ring->nr_slots); if (!ring->meta) goto err_kfree_ring; for (i = 0; i < ring->nr_slots; i++) diff --git a/drivers/net/wireless/broadcom/b43/lo.c b/drivers/net/wireless/broadcom/b43/lo.c index 338b6545a1e7..f86e8969673f 100644 --- a/drivers/net/wireless/broadcom/b43/lo.c +++ b/drivers/net/wireless/broadcom/b43/lo.c @@ -766,7 +766,7 @@ struct b43_lo_calib *b43_calibrate_lo_setting(struct b43_wldev *dev, loctl.i, loctl.q); } - cal = kmalloc(sizeof(*cal), GFP_KERNEL); + cal = kmalloc_obj(*cal); if (!cal) { b43warn(dev->wl, "LO calib: out of memory\n"); return NULL; diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c index f1a77c4c445f..b0e6aeb0b872 100644 --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c @@ -2555,7 +2555,7 @@ static void b43_request_firmware(struct work_struct *work) int err; const char *errmsg; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return; ctx->dev = dev; @@ -5494,7 +5494,7 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) struct b43_wldev *wldev; int err = -ENOMEM; - wldev = kzalloc(sizeof(*wldev), GFP_KERNEL); + wldev = kzalloc_obj(*wldev); if (!wldev) goto out; diff --git a/drivers/net/wireless/broadcom/b43/phy_ac.c b/drivers/net/wireless/broadcom/b43/phy_ac.c index 756cd44a8104..fe102ea3d1fa 100644 --- a/drivers/net/wireless/broadcom/b43/phy_ac.c +++ b/drivers/net/wireless/broadcom/b43/phy_ac.c @@ -17,7 +17,7 @@ static int b43_phy_ac_op_allocate(struct b43_wldev *dev) { struct b43_phy_ac *phy_ac; - phy_ac = kzalloc(sizeof(*phy_ac), GFP_KERNEL); + phy_ac = kzalloc_obj(*phy_ac); if (!phy_ac) return -ENOMEM; dev->phy.ac = phy_ac; diff --git a/drivers/net/wireless/broadcom/b43/phy_g.c b/drivers/net/wireless/broadcom/b43/phy_g.c index ac72ca39e409..9e292a349674 100644 --- a/drivers/net/wireless/broadcom/b43/phy_g.c +++ b/drivers/net/wireless/broadcom/b43/phy_g.c @@ -2422,14 +2422,14 @@ static int b43_gphy_op_allocate(struct b43_wldev *dev) struct b43_txpower_lo_control *lo; int err; - gphy = kzalloc(sizeof(*gphy), GFP_KERNEL); + gphy = kzalloc_obj(*gphy); if (!gphy) { err = -ENOMEM; goto error; } dev->phy.g = gphy; - lo = kzalloc(sizeof(*lo), GFP_KERNEL); + lo = kzalloc_obj(*lo); if (!lo) { err = -ENOMEM; goto err_free_gphy; diff --git a/drivers/net/wireless/broadcom/b43/phy_ht.c b/drivers/net/wireless/broadcom/b43/phy_ht.c index 26a226126bc4..fab8399c64f7 100644 --- a/drivers/net/wireless/broadcom/b43/phy_ht.c +++ b/drivers/net/wireless/broadcom/b43/phy_ht.c @@ -842,7 +842,7 @@ static int b43_phy_ht_op_allocate(struct b43_wldev *dev) { struct b43_phy_ht *phy_ht; - phy_ht = kzalloc(sizeof(*phy_ht), GFP_KERNEL); + phy_ht = kzalloc_obj(*phy_ht); if (!phy_ht) return -ENOMEM; dev->phy.ht = phy_ht; diff --git a/drivers/net/wireless/broadcom/b43/phy_lcn.c b/drivers/net/wireless/broadcom/b43/phy_lcn.c index 63bd29f070f7..dd726894738c 100644 --- a/drivers/net/wireless/broadcom/b43/phy_lcn.c +++ b/drivers/net/wireless/broadcom/b43/phy_lcn.c @@ -669,7 +669,7 @@ static int b43_phy_lcn_op_allocate(struct b43_wldev *dev) { struct b43_phy_lcn *phy_lcn; - phy_lcn = kzalloc(sizeof(*phy_lcn), GFP_KERNEL); + phy_lcn = kzalloc_obj(*phy_lcn); if (!phy_lcn) return -ENOMEM; dev->phy.lcn = phy_lcn; diff --git a/drivers/net/wireless/broadcom/b43/phy_lp.c b/drivers/net/wireless/broadcom/b43/phy_lp.c index 0e5c076e7544..8e0058072242 100644 --- a/drivers/net/wireless/broadcom/b43/phy_lp.c +++ b/drivers/net/wireless/broadcom/b43/phy_lp.c @@ -43,7 +43,7 @@ static int b43_lpphy_op_allocate(struct b43_wldev *dev) { struct b43_phy_lp *lpphy; - lpphy = kzalloc(sizeof(*lpphy), GFP_KERNEL); + lpphy = kzalloc_obj(*lpphy); if (!lpphy) return -ENOMEM; dev->phy.lp = lpphy; diff --git a/drivers/net/wireless/broadcom/b43/phy_n.c b/drivers/net/wireless/broadcom/b43/phy_n.c index 4bb005b93f2c..bbc30cbad0bb 100644 --- a/drivers/net/wireless/broadcom/b43/phy_n.c +++ b/drivers/net/wireless/broadcom/b43/phy_n.c @@ -1549,7 +1549,7 @@ static u16 b43_nphy_gen_load_samples(struct b43_wldev *dev, u32 freq, u16 max, len = bw << 1; } - samples = kcalloc(len, sizeof(struct cordic_iq), GFP_KERNEL); + samples = kzalloc_objs(struct cordic_iq, len); if (!samples) { b43err(dev->wl, "allocation for samples generation failed\n"); return 0; @@ -6417,7 +6417,7 @@ static int b43_nphy_op_allocate(struct b43_wldev *dev) { struct b43_phy_n *nphy; - nphy = kzalloc(sizeof(*nphy), GFP_KERNEL); + nphy = kzalloc_obj(*nphy); if (!nphy) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/b43/pio.c b/drivers/net/wireless/broadcom/b43/pio.c index e41f2f5b4c26..8358b1d5c298 100644 --- a/drivers/net/wireless/broadcom/b43/pio.c +++ b/drivers/net/wireless/broadcom/b43/pio.c @@ -127,7 +127,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, struct b43_pio_txpacket *p; unsigned int i; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; q->dev = dev; @@ -161,7 +161,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, { struct b43_pio_rxqueue *q; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; q->dev = dev; diff --git a/drivers/net/wireless/broadcom/b43/sdio.c b/drivers/net/wireless/broadcom/b43/sdio.c index 02b0cfd535ab..dda8d894aebe 100644 --- a/drivers/net/wireless/broadcom/b43/sdio.c +++ b/drivers/net/wireless/broadcom/b43/sdio.c @@ -139,7 +139,7 @@ static int b43_sdio_probe(struct sdio_func *func, } sdio_release_host(func); - sdio = kzalloc(sizeof(*sdio), GFP_KERNEL); + sdio = kzalloc_obj(*sdio); if (!sdio) { error = -ENOMEM; dev_err(&func->dev, "failed to allocate ssb bus\n"); diff --git a/drivers/net/wireless/broadcom/b43legacy/debugfs.c b/drivers/net/wireless/broadcom/b43legacy/debugfs.c index 5d04bcc216e5..3ad99124d522 100644 --- a/drivers/net/wireless/broadcom/b43legacy/debugfs.c +++ b/drivers/net/wireless/broadcom/b43legacy/debugfs.c @@ -358,15 +358,15 @@ void b43legacy_debugfs_add_device(struct b43legacy_wldev *dev) char devdir[16]; B43legacy_WARN_ON(!dev); - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { b43legacyerr(dev->wl, "debugfs: add device OOM\n"); return; } e->dev = dev; log = &e->txstatlog; - log->log = kcalloc(B43legacy_NR_LOGGED_TXSTATUS, - sizeof(struct b43legacy_txstatus), GFP_KERNEL); + log->log = kzalloc_objs(struct b43legacy_txstatus, + B43legacy_NR_LOGGED_TXSTATUS); if (!log->log) { b43legacyerr(dev->wl, "debugfs: add device txstatus OOM\n"); kfree(e); diff --git a/drivers/net/wireless/broadcom/b43legacy/dma.c b/drivers/net/wireless/broadcom/b43legacy/dma.c index 60e41de72f29..a9557356c9ab 100644 --- a/drivers/net/wireless/broadcom/b43legacy/dma.c +++ b/drivers/net/wireless/broadcom/b43legacy/dma.c @@ -610,7 +610,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, int nr_slots; dma_addr_t dma_test; - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) goto out; ring->type = type; @@ -620,8 +620,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, if (for_tx) nr_slots = B43legacy_TXRING_SLOTS; - ring->meta = kcalloc(nr_slots, sizeof(struct b43legacy_dmadesc_meta), - GFP_KERNEL); + ring->meta = kzalloc_objs(struct b43legacy_dmadesc_meta, nr_slots); if (!ring->meta) goto err_kfree_ring; if (for_tx) { diff --git a/drivers/net/wireless/broadcom/b43legacy/main.c b/drivers/net/wireless/broadcom/b43legacy/main.c index aada342e0b80..6b3e0b2bbca7 100644 --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c @@ -3269,9 +3269,8 @@ static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev) if ((phy->type == B43legacy_PHYTYPE_B) || (phy->type == B43legacy_PHYTYPE_G)) { - phy->_lo_pairs = kcalloc(B43legacy_LO_COUNT, - sizeof(struct b43legacy_lopair), - GFP_KERNEL); + phy->_lo_pairs = kzalloc_objs(struct b43legacy_lopair, + B43legacy_LO_COUNT); if (!phy->_lo_pairs) return -ENOMEM; } @@ -3739,7 +3738,7 @@ static int b43legacy_one_core_attach(struct ssb_device *dev, struct b43legacy_wldev *wldev; int err = -ENOMEM; - wldev = kzalloc(sizeof(*wldev), GFP_KERNEL); + wldev = kzalloc_obj(*wldev); if (!wldev) goto out; diff --git a/drivers/net/wireless/broadcom/b43legacy/pio.c b/drivers/net/wireless/broadcom/b43legacy/pio.c index aac413d0f629..0274fe47ca7e 100644 --- a/drivers/net/wireless/broadcom/b43legacy/pio.c +++ b/drivers/net/wireless/broadcom/b43legacy/pio.c @@ -320,7 +320,7 @@ struct b43legacy_pioqueue *b43legacy_setup_pioqueue(struct b43legacy_wldev *dev, u32 value; u16 qsize; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) goto out; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c index f471c962104a..6cb8343da936 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bca/core.c @@ -23,8 +23,7 @@ static int brcmf_bca_alloc_fweh_info(struct brcmf_pub *drvr) { struct brcmf_fweh_info *fweh; - fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_BCA_E_LAST), - GFP_KERNEL); + fweh = kzalloc_flex(*fweh, evt_handler, BRCMF_BCA_E_LAST); if (!fweh) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c index 9ec0c60b6da1..1817adc29cd8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c @@ -444,7 +444,7 @@ int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { struct brcmf_bcdc *bcdc; - bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC); + bcdc = kzalloc_obj(*bcdc, GFP_ATOMIC); if (!bcdc) goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 6a3f187320fc..d24b80e492e0 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -794,7 +794,7 @@ static int brcmf_sdiod_freezer_attach(struct brcmf_sdio_dev *sdiodev) if (!IS_ENABLED(CONFIG_PM_SLEEP)) return 0; - sdiodev->freezer = kzalloc(sizeof(*sdiodev->freezer), GFP_KERNEL); + sdiodev->freezer = kzalloc_obj(*sdiodev->freezer); if (!sdiodev->freezer) return -ENOMEM; atomic_set(&sdiodev->freezer->thread_count, 0); @@ -951,11 +951,10 @@ int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) goto out; /* try to attach to the target device */ - sdiodev->bus = brcmf_sdio_probe(sdiodev); - if (IS_ERR(sdiodev->bus)) { - ret = PTR_ERR(sdiodev->bus); + ret = brcmf_sdio_probe(sdiodev); + if (ret) goto out; - } + brcmf_sdiod_host_fixup(sdiodev->func2->card->host); out: if (ret) @@ -1067,10 +1066,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, if (func->num != 2) return -ENODEV; - bus_if = kzalloc(sizeof(*bus_if), GFP_KERNEL); + bus_if = kzalloc_obj(*bus_if); if (!bus_if) return -ENOMEM; - sdiodev = kzalloc(sizeof(*sdiodev), GFP_KERNEL); + sdiodev = kzalloc_obj(*sdiodev); if (!sdiodev) { kfree(bus_if); return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c index 67c0c5a92f99..0ca7f8672803 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/btcoex.c @@ -362,7 +362,7 @@ int brcmf_btcoex_attach(struct brcmf_cfg80211_info *cfg) struct brcmf_btcoex_info *btci; brcmf_dbg(TRACE, "enter\n"); - btci = kmalloc(sizeof(*btci), GFP_KERNEL); + btci = kmalloc_obj(*btci); if (!btci) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 61f7e620cab3..cea02b33b798 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -2527,7 +2527,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, offsetof(struct brcmf_assoc_params_le, chanspec_list); if (cfg->channel) join_params_size += sizeof(u16); - ext_join_params = kzalloc(sizeof(*ext_join_params), GFP_KERNEL); + ext_join_params = kzalloc_obj(*ext_join_params); if (ext_join_params == NULL) { err = -ENOMEM; goto done; @@ -4330,7 +4330,7 @@ brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa, int length = offsetof(struct brcmf_pmk_op_v3_le, pmk); int ret; - pmk_op = kzalloc(sizeof(*pmk_op), GFP_KERNEL); + pmk_op = kzalloc_obj(*pmk_op); if (!pmk_op) return -ENOMEM; @@ -5588,7 +5588,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, err = -EINVAL; goto exit; } - af_params = kzalloc(sizeof(*af_params), GFP_KERNEL); + af_params = kzalloc_obj(*af_params); if (af_params == NULL) { bphy_err(drvr, "unable to allocate frame\n"); err = -ENOMEM; @@ -6050,7 +6050,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", sizeof(*vif)); - vif = kzalloc(sizeof(*vif), GFP_KERNEL); + vif = kzalloc_obj(*vif); if (!vif) return ERR_PTR(-ENOMEM); @@ -6540,7 +6540,7 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, return -EINVAL; } - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return -ENOMEM; @@ -6828,7 +6828,7 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) { - cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); + cfg->conf = kzalloc_obj(*cfg->conf); if (!cfg->conf) goto init_priv_mem_out; cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); @@ -7486,7 +7486,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN); n_combos = 1 + !!(p2p && !rsdb) + !!mbss; - combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL); + combo = kzalloc_objs(*combo, n_combos); if (!combo) goto err; @@ -7503,7 +7503,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) c = 0; i = 0; n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p); - c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL); + c0_limits = kzalloc_objs(*c0_limits, n_limits); if (!c0_limits) goto err; @@ -7542,7 +7542,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) if (p2p && !rsdb) { c++; i = 0; - p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); + p2p_limits = kzalloc_objs(*p2p_limits, 4); if (!p2p_limits) goto err; p2p_limits[i].max = 1; @@ -7563,8 +7563,7 @@ static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) c++; i = 0; n_limits = 1 + mon_flag; - mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits), - GFP_KERNEL); + mbss_limits = kzalloc_objs(*mbss_limits, n_limits); if (!mbss_limits) goto err; mbss_limits[i].max = 4; @@ -8322,7 +8321,7 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, return NULL; } - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) { bphy_err(drvr, "Could not allocate wiphy device\n"); return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c index 4239f2b21e54..a790f1693b82 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c @@ -507,7 +507,7 @@ static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci, { struct brcmf_core_priv *core; - core = kzalloc(sizeof(*core), GFP_KERNEL); + core = kzalloc_obj(*core); if (!core) return ERR_PTR(-ENOMEM); @@ -1137,7 +1137,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx, u16 devid, if (err < 0) return ERR_PTR(-EINVAL); - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 688f16c51319..b6027d83e6ab 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -132,8 +132,7 @@ static int brcmf_c_download_blob(struct brcmf_if *ifp, brcmf_dbg(TRACE, "Enter\n"); - chunk_buf = kzalloc(struct_size(chunk_buf, data, MAX_CHUNK_LEN), - GFP_KERNEL); + chunk_buf = kzalloc_flex(*chunk_buf, data, MAX_CHUNK_LEN); if (!chunk_buf) { err = -ENOMEM; return -ENOMEM; @@ -521,7 +520,7 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip, chiprev); - settings = kzalloc(sizeof(*settings), GFP_ATOMIC); + settings = kzalloc_obj(*settings, GFP_ATOMIC); if (!settings) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 616885d6db3f..ec170647800d 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -879,7 +879,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, if (!drvr->settings->p2p_enable && is_p2pdev) { /* this is P2P_DEVICE interface */ brcmf_dbg(INFO, "allocate non-netdev interface\n"); - ifp = kzalloc(sizeof(*ifp), GFP_KERNEL); + ifp = kzalloc_obj(*ifp); if (!ifp) return ERR_PTR(-ENOMEM); } else { diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c index 4f0ea4347840..ce09d44fa73c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cyw/core.c @@ -66,8 +66,7 @@ static int brcmf_cyw_alloc_fweh_info(struct brcmf_pub *drvr) { struct brcmf_fweh_info *fweh; - fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_CYW_E_LAST), - GFP_KERNEL); + fweh = kzalloc_flex(*fweh, evt_handler, BRCMF_CYW_E_LAST); if (!fweh) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c index ef79924fd8f4..4bacd83db052 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c @@ -765,7 +765,7 @@ int brcmf_fw_get_firmwares(struct device *dev, struct brcmf_fw_request *req, if (!brcmf_fw_request_is_valid(req)) return -EINVAL; - fwctx = kzalloc(sizeof(*fwctx), GFP_KERNEL); + fwctx = kzalloc_obj(*fwctx); if (!fwctx) return -ENOMEM; @@ -825,7 +825,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chiprev, return NULL; } - fwreq = kzalloc(struct_size(fwreq, items, n_fwnames), GFP_KERNEL); + fwreq = kzalloc_flex(*fwreq, items, n_fwnames); if (!fwreq) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c index e1127d7e086d..df7e3bee19f2 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c @@ -145,7 +145,7 @@ u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN], if (i == flow->nrofrings) return -ENOMEM; - ring = kzalloc(sizeof(*ring), GFP_ATOMIC); + ring = kzalloc_obj(*ring, GFP_ATOMIC); if (!ring) return -ENOMEM; @@ -360,7 +360,7 @@ struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings) struct brcmf_flowring *flow; u32 i; - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (flow) { flow->dev = dev; flow->nrofrings = nrofrings; @@ -369,8 +369,7 @@ struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings) flow->addr_mode[i] = ADDR_INDIRECT; for (i = 0; i < ARRAY_SIZE(flow->hash); i++) flow->hash[i].ifidx = BRCMF_FLOWRING_INVALID_IFIDX; - flow->rings = kcalloc(nrofrings, sizeof(*flow->rings), - GFP_KERNEL); + flow->rings = kzalloc_objs(*flow->rings, nrofrings); if (!flow->rings) { kfree(flow); flow = NULL; @@ -480,7 +479,7 @@ void brcmf_flowring_add_tdls_peer(struct brcmf_flowring *flow, int ifidx, struct brcmf_flowring_tdls_entry *tdls_entry; struct brcmf_flowring_tdls_entry *search; - tdls_entry = kzalloc(sizeof(*tdls_entry), GFP_ATOMIC); + tdls_entry = kzalloc_obj(*tdls_entry, GFP_ATOMIC); if (tdls_entry == NULL) return; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c index c2d98ee6652f..984886481f4e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c @@ -497,7 +497,7 @@ void brcmf_fweh_process_event(struct brcmf_pub *drvr, datalen + sizeof(*event_packet) > packet_len) return; - event = kzalloc(struct_size(event, data, datalen), gfp); + event = kzalloc_flex(*event, data, datalen, gfp); if (!event) return; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index b70d20128f98..a43f1a38b0e3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -1712,8 +1712,7 @@ void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) /* allocate space for flow reorder info */ brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", flow_id, max_idx); - rfi = kzalloc(struct_size(rfi, pktslots, max_idx + 1), - GFP_ATOMIC); + rfi = kzalloc_flex(*rfi, pktslots, max_idx + 1, GFP_ATOMIC); if (rfi == NULL) { bphy_err(drvr, "failed to alloc buffer\n"); brcmf_netif_rx(ifp, pkt); @@ -2343,7 +2342,7 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr) int rc; u32 mode; - fws = kzalloc(sizeof(*fws), GFP_KERNEL); + fws = kzalloc_obj(*fws); if (!fws) { rc = -ENOMEM; goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c index 45fbcbdc7d9e..ba1ce1552e0f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c @@ -299,11 +299,11 @@ brcmf_msgbuf_init_pktids(u32 nr_array_entries, struct brcmf_msgbuf_pktid *array; struct brcmf_msgbuf_pktids *pktids; - array = kcalloc(nr_array_entries, sizeof(*array), GFP_KERNEL); + array = kzalloc_objs(*array, nr_array_entries); if (!array) return NULL; - pktids = kzalloc(sizeof(*pktids), GFP_KERNEL); + pktids = kzalloc_obj(*pktids); if (!pktids) { kfree(array); return NULL; @@ -670,7 +670,7 @@ static u32 brcmf_msgbuf_flowring_create(struct brcmf_msgbuf *msgbuf, int ifidx, u32 flowid; ulong flags; - create = kzalloc(sizeof(*create), GFP_ATOMIC); + create = kzalloc_obj(*create, GFP_ATOMIC); if (create == NULL) return BRCMF_FLOWRING_INVALID_ID; @@ -1539,7 +1539,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; } - msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL); + msgbuf = kzalloc_obj(*msgbuf); if (!msgbuf) goto fail; @@ -1588,8 +1588,8 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr) msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings; msgbuf->max_flowrings = if_msgbuf->max_flowrings; msgbuf->flowring_dma_handle = - kcalloc(msgbuf->max_flowrings, - sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL); + kzalloc_objs(*msgbuf->flowring_dma_handle, + msgbuf->max_flowrings); if (!msgbuf->flowring_dma_handle) goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 6327f4eca500..45b342ea0637 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -1155,7 +1155,7 @@ brcmf_pcie_alloc_dma_and_ring(struct brcmf_pciedev_info *devinfo, u32 ring_id, addr = tcm_ring_phys_addr + BRCMF_RING_LEN_ITEMS_OFFSET; brcmf_pcie_write_tcm16(devinfo, addr, ring_itemsize_array[ring_id]); - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) { dma_free_coherent(&devinfo->pdev->dev, size, dma_buf, dma_handle); @@ -1347,7 +1347,7 @@ static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo) devinfo->shared.max_flowrings = max_flowrings; devinfo->shared.max_submissionrings = max_submissionrings; devinfo->shared.max_completionrings = max_completionrings; - rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL); + rings = kzalloc_objs(*ring, max_flowrings); if (!rings) goto fail; @@ -2199,8 +2199,7 @@ static void brcmf_pcie_setup(struct device *dev, int ret, bus->msgbuf->commonrings[i] = &devinfo->shared.commonrings[i]->commonring; - flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings), - GFP_KERNEL); + flowrings = kzalloc_objs(*flowrings, devinfo->shared.max_flowrings); if (!flowrings) goto fail; @@ -2457,7 +2456,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) brcmf_dbg(PCIE, "Enter %x:%x\n", pdev->vendor, pdev->device); ret = -ENOMEM; - devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); + devinfo = kzalloc_obj(*devinfo); if (devinfo == NULL) return ret; @@ -2477,7 +2476,7 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) else devinfo->reginfo = &brcmf_reginfo_default; - pcie_bus_dev = kzalloc(sizeof(*pcie_bus_dev), GFP_KERNEL); + pcie_bus_dev = kzalloc_obj(*pcie_bus_dev); if (pcie_bus_dev == NULL) { ret = -ENOMEM; goto fail; @@ -2495,12 +2494,12 @@ brcmf_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (ret < 0) goto fail; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) { ret = -ENOMEM; goto fail; } - bus->msgbuf = kzalloc(sizeof(*bus->msgbuf), GFP_KERNEL); + bus->msgbuf = kzalloc_obj(*bus->msgbuf); if (!bus->msgbuf) { ret = -ENOMEM; kfree(bus); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c index 05f66ab13bed..d9fc94076791 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c @@ -321,7 +321,7 @@ static int brcmf_pno_prep_fwconfig(struct brcmf_pno_info *pi, } *buckets = NULL; - fw_buckets = kcalloc(pi->n_reqs, sizeof(*fw_buckets), GFP_KERNEL); + fw_buckets = kzalloc_objs(*fw_buckets, pi->n_reqs); if (!fw_buckets) return -ENOMEM; @@ -517,7 +517,7 @@ int brcmf_pno_attach(struct brcmf_cfg80211_info *cfg) struct brcmf_pno_info *pi; brcmf_dbg(TRACE, "enter\n"); - pi = kzalloc(sizeof(*pi), GFP_KERNEL); + pi = kzalloc_obj(*pi); if (!pi) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c index 2e911d4874af..7fc441859f52 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c @@ -23,7 +23,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) brcmf_dbg(TRACE, "Enter\n"); - proto = kzalloc(sizeof(*proto), GFP_ATOMIC); + proto = kzalloc_obj(*proto, GFP_ATOMIC); if (!proto) goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 8cf9d7e7c3f7..30f6fcb68632 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -4445,7 +4445,7 @@ brcmf_sdio_prepare_fw_request(struct brcmf_sdio *bus) return fwreq; } -struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) +int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_sdio *bus; @@ -4455,7 +4455,7 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) brcmf_dbg(TRACE, "Enter\n"); /* Allocate private bus interface state */ - bus = kzalloc(sizeof(*bus), GFP_ATOMIC); + bus = kzalloc_obj(*bus, GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; @@ -4551,11 +4551,12 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) goto fail; } - return bus; + return 0; fail: brcmf_sdio_remove(bus); - return ERR_PTR(ret); + sdiodev->bus = NULL; + return ret; } /* Detach and free everything */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h index 0d18ed15b403..80180d5c6c87 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h @@ -358,7 +358,7 @@ void brcmf_sdiod_freezer_uncount(struct brcmf_sdio_dev *sdiodev); int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev); int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev); -struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); +int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); void brcmf_sdio_remove(struct brcmf_sdio *bus); void brcmf_sdio_isr(struct brcmf_sdio *bus, bool in_isr); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index f0129d10d2b9..0b52f968b907 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -428,7 +428,7 @@ brcmf_usbdev_qinit(struct list_head *q, int qsize) int i; struct brcmf_usbreq *req, *reqs; - reqs = kcalloc(qsize, sizeof(struct brcmf_usbreq), GFP_ATOMIC); + reqs = kzalloc_objs(struct brcmf_usbreq, qsize, GFP_ATOMIC); if (reqs == NULL) return NULL; @@ -1255,7 +1255,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, if (!bus_pub) return -ENODEV; - bus = kzalloc(sizeof(*bus), GFP_ATOMIC); + bus = kzalloc_obj(*bus, GFP_ATOMIC); if (!bus) { ret = -ENOMEM; goto fail; @@ -1359,7 +1359,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) brcmf_dbg(USB, "Enter 0x%04x:0x%04x\n", id->idVendor, id->idProduct); - devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); + devinfo = kzalloc_obj(*devinfo, GFP_ATOMIC); if (devinfo == NULL) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c index 05d7c2a4fba5..e14b5530f720 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/wcc/core.c @@ -24,8 +24,7 @@ static int brcmf_wcc_alloc_fweh_info(struct brcmf_pub *drvr) { struct brcmf_fweh_info *fweh; - fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_WCC_E_LAST), - GFP_KERNEL); + fweh = kzalloc_flex(*fweh, evt_handler, BRCMF_WCC_E_LAST); if (!fweh) return -ENOMEM; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c index 0cb64fc56783..6a67db07833e 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/aiutils.c @@ -512,7 +512,7 @@ ai_attach(struct bcma_bus *pbus) struct si_info *sii; /* alloc struct si_info */ - sii = kzalloc(sizeof(*sii), GFP_ATOMIC); + sii = kzalloc_obj(*sii, GFP_ATOMIC); if (sii == NULL) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c index e1d707a7c964..fc7a5dd2e5d8 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c @@ -219,7 +219,7 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) struct ampdu_info *ampdu; int i; - ampdu = kzalloc(sizeof(*ampdu), GFP_ATOMIC); + ampdu = kzalloc_obj(*ampdu, GFP_ATOMIC); if (!ampdu) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c index f411bc6d795d..9a3e40528ff7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/antsel.c @@ -111,7 +111,7 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) struct antsel_info *asi; struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; - asi = kzalloc(sizeof(*asi), GFP_ATOMIC); + asi = kzalloc_obj(*asi, GFP_ATOMIC); if (!asi) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c index 3878c4124e25..cdfe8635c012 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c @@ -331,7 +331,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) const char *ccode = sprom->alpha2; int ccode_len = sizeof(sprom->alpha2); - wlc_cm = kzalloc(sizeof(*wlc_cm), GFP_ATOMIC); + wlc_cm = kzalloc_obj(*wlc_cm, GFP_ATOMIC); if (wlc_cm == NULL) return NULL; wlc_cm->pub = pub; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c index c739bf7463b3..9f6ef7ce1b58 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/dma.c @@ -558,7 +558,7 @@ struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, struct si_info *sii = container_of(sih, struct si_info, pub); /* allocate private info structure */ - di = kzalloc(sizeof(*di), GFP_ATOMIC); + di = kzalloc_obj(*di, GFP_ATOMIC); if (di == NULL) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c index aadcff1e2b5d..6255d673d2d3 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c @@ -1499,7 +1499,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, { struct brcms_timer *t; - t = kzalloc(sizeof(*t), GFP_ATOMIC); + t = kzalloc_obj(*t, GFP_ATOMIC); if (!t) return NULL; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c index c1a9c1e442ee..c7eaf160e1fa 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/main.c @@ -457,11 +457,11 @@ static struct brcms_bss_cfg *brcms_c_bsscfg_malloc(uint unit) { struct brcms_bss_cfg *cfg; - cfg = kzalloc(sizeof(*cfg), GFP_ATOMIC); + cfg = kzalloc_obj(*cfg, GFP_ATOMIC); if (cfg == NULL) goto fail; - cfg->current_bss = kzalloc(sizeof(*cfg->current_bss), GFP_ATOMIC); + cfg->current_bss = kzalloc_obj(*cfg->current_bss, GFP_ATOMIC); if (cfg->current_bss == NULL) goto fail; @@ -477,14 +477,14 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) { struct brcms_c_info *wlc; - wlc = kzalloc(sizeof(*wlc), GFP_ATOMIC); + wlc = kzalloc_obj(*wlc, GFP_ATOMIC); if (wlc == NULL) { *err = 1002; goto fail; } /* allocate struct brcms_c_pub state structure */ - wlc->pub = kzalloc(sizeof(*wlc->pub), GFP_ATOMIC); + wlc->pub = kzalloc_obj(*wlc->pub, GFP_ATOMIC); if (wlc->pub == NULL) { *err = 1003; goto fail; @@ -493,7 +493,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) /* allocate struct brcms_hardware state structure */ - wlc->hw = kzalloc(sizeof(*wlc->hw), GFP_ATOMIC); + wlc->hw = kzalloc_obj(*wlc->hw, GFP_ATOMIC); if (wlc->hw == NULL) { *err = 1005; goto fail; @@ -501,7 +501,7 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) wlc->hw->wlc = wlc; wlc->hw->bandstate[0] = - kcalloc(MAXBANDS, sizeof(struct brcms_hw_band), GFP_ATOMIC); + kzalloc_objs(struct brcms_hw_band, MAXBANDS, GFP_ATOMIC); if (wlc->hw->bandstate[0] == NULL) { *err = 1006; goto fail; @@ -515,14 +515,13 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) } wlc->modulecb = - kcalloc(BRCMS_MAXMODULES, sizeof(struct modulecb), - GFP_ATOMIC); + kzalloc_objs(struct modulecb, BRCMS_MAXMODULES, GFP_ATOMIC); if (wlc->modulecb == NULL) { *err = 1009; goto fail; } - wlc->default_bss = kzalloc(sizeof(*wlc->default_bss), GFP_ATOMIC); + wlc->default_bss = kzalloc_obj(*wlc->default_bss, GFP_ATOMIC); if (wlc->default_bss == NULL) { *err = 1010; goto fail; @@ -534,20 +533,20 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) goto fail; } - wlc->protection = kzalloc(sizeof(*wlc->protection), GFP_ATOMIC); + wlc->protection = kzalloc_obj(*wlc->protection, GFP_ATOMIC); if (wlc->protection == NULL) { *err = 1016; goto fail; } - wlc->stf = kzalloc(sizeof(*wlc->stf), GFP_ATOMIC); + wlc->stf = kzalloc_obj(*wlc->stf, GFP_ATOMIC); if (wlc->stf == NULL) { *err = 1017; goto fail; } wlc->bandstate[0] = - kcalloc(MAXBANDS, sizeof(*wlc->bandstate[0]), GFP_ATOMIC); + kzalloc_objs(*wlc->bandstate[0], MAXBANDS, GFP_ATOMIC); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; @@ -560,14 +559,14 @@ brcms_c_attach_malloc(uint unit, uint *err, uint devid) + (sizeof(struct brcms_band)*i)); } - wlc->corestate = kzalloc(sizeof(*wlc->corestate), GFP_ATOMIC); + wlc->corestate = kzalloc_obj(*wlc->corestate, GFP_ATOMIC); if (wlc->corestate == NULL) { *err = 1026; goto fail; } - wlc->corestate->macstat_snapshot = - kzalloc(sizeof(*wlc->corestate->macstat_snapshot), GFP_ATOMIC); + wlc->corestate->macstat_snapshot = kzalloc_obj(*wlc->corestate->macstat_snapshot, + GFP_ATOMIC); if (wlc->corestate->macstat_snapshot == NULL) { *err = 1027; goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c index ce6ce2dea39c..7eae73ef7e94 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c @@ -333,7 +333,7 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) { struct shared_phy *sh; - sh = kzalloc(sizeof(*sh), GFP_ATOMIC); + sh = kzalloc_obj(*sh, GFP_ATOMIC); if (sh == NULL) return NULL; @@ -420,7 +420,7 @@ wlc_phy_attach(struct shared_phy *sh, struct bcma_device *d11core, return &pi->pubpi_ro; } - pi = kzalloc(sizeof(*pi), GFP_ATOMIC); + pi = kzalloc_obj(*pi, GFP_ATOMIC); if (pi == NULL) return NULL; pi->wiphy = wiphy; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c index 5258681218ea..8cec5ad79fda 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c @@ -1319,7 +1319,7 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, s16 *ptr; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - ptr = kmalloc_array(131, sizeof(s16), GFP_ATOMIC); + ptr = kmalloc_objs(s16, 131, GFP_ATOMIC); if (NULL == ptr) return false; if (module == 2) { @@ -3605,7 +3605,7 @@ wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, u16 *phy_c32; phy_c21 = 0; phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; - ptr = kmalloc_array(131, sizeof(s16), GFP_ATOMIC); + ptr = kmalloc_objs(s16, 131, GFP_ATOMIC); if (NULL == ptr) return; @@ -4966,7 +4966,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) { struct brcms_phy_lcnphy *pi_lcn; - pi_lcn = kzalloc(sizeof(*pi_lcn), GFP_ATOMIC); + pi_lcn = kzalloc_obj(*pi_lcn, GFP_ATOMIC); if (!pi_lcn) return false; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c index b03d5a1f1a93..86cfa3e87a04 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c @@ -23049,8 +23049,7 @@ wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, tbl_len = (phy_bw << 1); } - tone_buf = kmalloc_array(tbl_len, sizeof(struct cordic_iq), - GFP_ATOMIC); + tone_buf = kmalloc_objs(struct cordic_iq, tbl_len, GFP_ATOMIC); if (tone_buf == NULL) return 0; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c index 8b852581c4e4..20cf6379e838 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy_shim.c @@ -40,7 +40,7 @@ struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, struct brcms_c_info *wlc) { struct phy_shim_info *physhim; - physhim = kzalloc(sizeof(*physhim), GFP_ATOMIC); + physhim = kzalloc_obj(*physhim, GFP_ATOMIC); if (!physhim) return NULL; diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index c7c5bc0f1650..248a051da52d 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -1885,9 +1885,8 @@ static int ipw2100_wdev_init(struct net_device *dev) bg_band->band = NL80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = kcalloc(geo->bg_channels, - sizeof(struct ieee80211_channel), - GFP_KERNEL); + bg_band->channels = kzalloc_objs(struct ieee80211_channel, + geo->bg_channels); if (!bg_band->channels) { ipw2100_down(priv); return -ENOMEM; @@ -3413,9 +3412,7 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) dma_addr_t p; priv->msg_buffers = - kmalloc_array(IPW_COMMAND_POOL_SIZE, - sizeof(struct ipw2100_tx_packet), - GFP_KERNEL); + kmalloc_objs(struct ipw2100_tx_packet, IPW_COMMAND_POOL_SIZE); if (!priv->msg_buffers) return -ENOMEM; @@ -4410,9 +4407,8 @@ static int ipw2100_tx_allocate(struct ipw2100_priv *priv) return err; } - priv->tx_buffers = kmalloc_array(TX_PENDED_QUEUE_LENGTH, - sizeof(struct ipw2100_tx_packet), - GFP_KERNEL); + priv->tx_buffers = kmalloc_objs(struct ipw2100_tx_packet, + TX_PENDED_QUEUE_LENGTH); if (!priv->tx_buffers) { bd_queue_free(priv, &priv->tx_queue); return -ENOMEM; @@ -4555,9 +4551,8 @@ static int ipw2100_rx_allocate(struct ipw2100_priv *priv) /* * allocate packets */ - priv->rx_buffers = kmalloc_array(RX_QUEUE_LENGTH, - sizeof(struct ipw2100_rx_packet), - GFP_KERNEL); + priv->rx_buffers = kmalloc_objs(struct ipw2100_rx_packet, + RX_QUEUE_LENGTH); if (!priv->rx_buffers) { IPW_DEBUG_INFO("can't allocate rx packet buffer table\n"); diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index 09035a77e775..dd64d21174e3 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -3153,8 +3153,7 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) if (!virts) return -ENOMEM; - phys = kmalloc_array(CB_NUMBER_OF_ELEMENTS_SMALL, sizeof(dma_addr_t), - GFP_KERNEL); + phys = kmalloc_objs(dma_addr_t, CB_NUMBER_OF_ELEMENTS_SMALL); if (!phys) { kfree(virts); return -ENOMEM; @@ -3723,7 +3722,7 @@ static int ipw_queue_tx_init(struct ipw_priv *priv, { struct pci_dev *dev = priv->pci_dev; - q->txb = kmalloc_array(count, sizeof(q->txb[0]), GFP_KERNEL); + q->txb = kmalloc_objs(q->txb[0], count); if (!q->txb) return -ENOMEM; @@ -5201,7 +5200,7 @@ static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv) struct ipw_rx_queue *rxq; int i; - rxq = kzalloc(sizeof(*rxq), GFP_KERNEL); + rxq = kzalloc_obj(*rxq); if (unlikely(!rxq)) { IPW_ERROR("memory allocation failed\n"); return NULL; @@ -8103,7 +8102,7 @@ static int is_duplicate_packet(struct ipw_priv *priv, break; } if (p == &priv->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) { IPW_ERROR ("Cannot malloc new mac entry\n"); @@ -11119,8 +11118,7 @@ static int ipw_up(struct ipw_priv *priv) return -EIO; if (cmdlog && !priv->cmdlog) { - priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog), - GFP_KERNEL); + priv->cmdlog = kzalloc_objs(*priv->cmdlog, cmdlog); if (priv->cmdlog == NULL) { IPW_ERROR("Error allocating %d command log entries.\n", cmdlog); @@ -11279,9 +11277,8 @@ static int ipw_wdev_init(struct net_device *dev) bg_band->band = NL80211_BAND_2GHZ; bg_band->n_channels = geo->bg_channels; - bg_band->channels = kcalloc(geo->bg_channels, - sizeof(struct ieee80211_channel), - GFP_KERNEL); + bg_band->channels = kzalloc_objs(struct ieee80211_channel, + geo->bg_channels); if (!bg_band->channels) { rc = -ENOMEM; goto out; @@ -11318,9 +11315,8 @@ static int ipw_wdev_init(struct net_device *dev) a_band->band = NL80211_BAND_5GHZ; a_band->n_channels = geo->a_channels; - a_band->channels = kcalloc(geo->a_channels, - sizeof(struct ieee80211_channel), - GFP_KERNEL); + a_band->channels = kzalloc_objs(struct ieee80211_channel, + geo->a_channels); if (!a_band->channels) { rc = -ENOMEM; goto out; @@ -11387,7 +11383,13 @@ static const struct pci_device_id card_ids[] = { {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0}, {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0}, {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0}, - {PCI_VDEVICE(INTEL, 0x104f), 0}, + /* + * This ID conflicts with i40e, but the devices can be differentiated + * because i40e devices use PCI_CLASS_NETWORK_ETHERNET and ipw2200 + * devices use PCI_CLASS_NETWORK_OTHER. + */ + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x104f), + PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0}, {PCI_VDEVICE(INTEL, 0x4220), 0}, /* BG */ {PCI_VDEVICE(INTEL, 0x4221), 0}, /* BG */ {PCI_VDEVICE(INTEL, 0x4223), 0}, /* ABG */ diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c index 243d0c5928a2..af03114fdf6c 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto.c @@ -159,7 +159,7 @@ int libipw_register_crypto_ops(const struct libipw_crypto_ops *ops) unsigned long flags; struct libipw_crypto_alg *alg; - alg = kzalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc_obj(*alg); if (alg == NULL) return -ENOMEM; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c index bf900d8c8ad3..631a4dd86cab 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_ccmp.c @@ -53,7 +53,7 @@ static void *libipw_ccmp_init(int key_idx) { struct libipw_ccmp_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc_obj(*priv, GFP_ATOMIC); if (priv == NULL) goto fail; priv->key_idx = key_idx; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c index 32288697da4f..c6b0de8d91ae 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_tkip.c @@ -87,7 +87,7 @@ static void *libipw_tkip_init(int key_idx) if (fips_enabled) return NULL; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc_obj(*priv, GFP_ATOMIC); if (priv == NULL) goto fail; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c index c3a4ccb9de17..96109e123a1a 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_crypto_wep.c @@ -37,7 +37,7 @@ static void *libipw_wep_init(int keyidx) if (fips_enabled) return NULL; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kzalloc_obj(*priv, GFP_ATOMIC); if (priv == NULL) return NULL; priv->key_idx = keyidx; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_module.c b/drivers/net/wireless/intel/ipw2x00/libipw_module.c index 2ad085b1f492..22358b2c2ecd 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_module.c @@ -57,8 +57,7 @@ static int libipw_networks_allocate(struct libipw_device *ieee) int i, j; for (i = 0; i < MAX_NETWORK_COUNT; i++) { - ieee->networks[i] = kzalloc(sizeof(struct libipw_network), - GFP_KERNEL); + ieee->networks[i] = kzalloc_obj(struct libipw_network); if (!ieee->networks[i]) { LIBIPW_ERROR("Out of memory allocating beacons\n"); for (j = 0; j < i; j++) diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c index 80edaa3dea9c..6e16060834b8 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_tx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_tx.c @@ -180,7 +180,7 @@ static struct libipw_txb *libipw_alloc_txb(int nr_frags, int txb_size, struct libipw_txb *txb; int i; - txb = kzalloc(struct_size(txb, fragments, nr_frags), gfp_mask); + txb = kzalloc_flex(*txb, fragments, nr_frags, gfp_mask); if (!txb) return NULL; diff --git a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c index db71d81b0d4f..122bcbae188f 100644 --- a/drivers/net/wireless/intel/ipw2x00/libipw_wx.c +++ b/drivers/net/wireless/intel/ipw2x00/libipw_wx.c @@ -365,8 +365,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee, struct libipw_crypt_data *new_crypt; /* take WEP into use */ - new_crypt = kzalloc(sizeof(struct libipw_crypt_data), - GFP_KERNEL); + new_crypt = kzalloc_obj(struct libipw_crypt_data); if (new_crypt == NULL) return -ENOMEM; new_crypt->ops = libipw_get_crypto_ops("WEP"); @@ -598,7 +597,7 @@ int libipw_wx_set_encodeext(struct libipw_device *ieee, libipw_crypt_delayed_deinit(&ieee->crypt_info, crypt); - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); + new_crypt = kzalloc_obj(*new_crypt); if (new_crypt == NULL) { ret = -ENOMEM; goto done; diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c b/drivers/net/wireless/intel/iwlegacy/3945-mac.c index 54991f31c52c..c148654aa953 100644 --- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c @@ -269,7 +269,7 @@ il3945_get_free_frame(struct il_priv *il) struct il3945_frame *frame; struct list_head *element; if (list_empty(&il->free_frames)) { - frame = kzalloc(sizeof(*frame), GFP_KERNEL); + frame = kzalloc_obj(*frame); if (!frame) { IL_ERR("Could not allocate frame!\n"); return NULL; diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index 57fa866efd9f..7921bc45e21d 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -3027,7 +3027,7 @@ il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id) u32 rate_flags = 0; __le32 rate_n_flags; - link_cmd = kzalloc(sizeof(struct il_link_quality_cmd), GFP_KERNEL); + link_cmd = kzalloc_obj(struct il_link_quality_cmd); if (!link_cmd) { IL_ERR("Unable to allocate memory for LQ cmd.\n"); return NULL; @@ -3709,7 +3709,7 @@ il4965_get_free_frame(struct il_priv *il) struct il_frame *frame; struct list_head *element; if (list_empty(&il->free_frames)) { - frame = kzalloc(sizeof(*frame), GFP_KERNEL); + frame = kzalloc_obj(*frame); if (!frame) { IL_ERR("Could not allocate frame!\n"); return NULL; diff --git a/drivers/net/wireless/intel/iwlegacy/common.c b/drivers/net/wireless/intel/iwlegacy/common.c index b7bd3ec4cc50..8d0ff339ad08 100644 --- a/drivers/net/wireless/intel/iwlegacy/common.c +++ b/drivers/net/wireless/intel/iwlegacy/common.c @@ -907,8 +907,7 @@ il_init_channel_map(struct il_priv *il) D_EEPROM("Parsing data for %d channels.\n", il->channel_count); il->channel_info = - kcalloc(il->channel_count, sizeof(struct il_channel_info), - GFP_KERNEL); + kzalloc_objs(struct il_channel_info, il->channel_count); if (!il->channel_info) { IL_ERR("Could not allocate channel_info\n"); il->channel_count = 0; @@ -2969,9 +2968,7 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id) /* Driver ilate data, only for Tx (not command) queues, * not shared with device. */ if (id != il->cmd_queue) { - txq->skbs = kcalloc(TFD_QUEUE_SIZE_MAX, - sizeof(struct sk_buff *), - GFP_KERNEL); + txq->skbs = kzalloc_objs(struct sk_buff *, TFD_QUEUE_SIZE_MAX); if (!txq->skbs) { IL_ERR("Fail to alloc skbs\n"); goto error; @@ -3024,9 +3021,9 @@ il_tx_queue_init(struct il_priv *il, u32 txq_id) } txq->meta = - kcalloc(actual_slots, sizeof(struct il_cmd_meta), GFP_KERNEL); + kzalloc_objs(struct il_cmd_meta, actual_slots); txq->cmd = - kcalloc(actual_slots, sizeof(struct il_device_cmd *), GFP_KERNEL); + kzalloc_objs(struct il_device_cmd *, actual_slots); if (!txq->meta || !txq->cmd) goto out_free_arrays; @@ -3444,12 +3441,11 @@ il_init_geos(struct il_priv *il) } channels = - kcalloc(il->channel_count, sizeof(struct ieee80211_channel), - GFP_KERNEL); + kzalloc_objs(struct ieee80211_channel, il->channel_count); if (!channels) return -ENOMEM; - rates = kcalloc(RATE_COUNT_LEGACY, sizeof(*rates), GFP_KERNEL); + rates = kzalloc_objs(*rates, RATE_COUNT_LEGACY); if (!rates) { kfree(channels); return -ENOMEM; @@ -4611,9 +4607,7 @@ il_alloc_txq_mem(struct il_priv *il) { if (!il->txq) il->txq = - kcalloc(il->cfg->num_of_queues, - sizeof(struct il_tx_queue), - GFP_KERNEL); + kzalloc_objs(struct il_tx_queue, il->cfg->num_of_queues); if (!il->txq) { IL_ERR("Not enough memory for txq\n"); return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/calib.c b/drivers/net/wireless/intel/iwlwifi/dvm/calib.c index f488620d2844..94c5d40cdf41 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/calib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/calib.c @@ -63,7 +63,7 @@ int iwl_calib_set(struct iwl_priv *priv, if (check_sub_overflow(len, sizeof(*cmd), &len)) return -ENOMEM; - res = kmalloc(struct_size(res, cmd.data, len), GFP_ATOMIC); + res = kmalloc_flex(*res, cmd.data, len, GFP_ATOMIC); if (!res) return -ENOMEM; res->cmd = *cmd; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c index be7e61e2b291..7f83f1bbdaad 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/devices.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/devices.c @@ -567,7 +567,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, }; int err; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c index d337ab543eb0..6de2517188f7 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/eeprom.c @@ -1067,8 +1067,7 @@ iwl_parse_eeprom_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, if (WARN_ON(!cfg || !cfg->eeprom_params)) return NULL; - data = kzalloc(struct_size(data, channels, IWL_NUM_CHANNELS), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NUM_CHANNELS); if (!data) return NULL; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c index 48711dbcfa5a..2e16799818e4 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/lib.c @@ -1056,7 +1056,7 @@ int iwlagn_suspend(struct iwl_priv *priv, struct cfg80211_wowlan *wowlan) int ret, i; u16 seq; - key_data.rsc_tsc = kzalloc(sizeof(*key_data.rsc_tsc), GFP_KERNEL); + key_data.rsc_tsc = kzalloc_obj(*key_data.rsc_tsc); if (!key_data.rsc_tsc) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/main.c b/drivers/net/wireless/intel/iwlwifi/dvm/main.c index 2b4dbebc71c2..ca5a8140908a 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/main.c @@ -205,7 +205,7 @@ int iwlagn_send_beacon_cmd(struct iwl_priv *priv) /* Allocate beacon command */ if (!priv->beacon_cmd) - priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL); + priv->beacon_cmd = kzalloc_obj(*tx_beacon_cmd); tx_beacon_cmd = priv->beacon_cmd; if (!tx_beacon_cmd) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c index b34ee68f3dce..088302a238de 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rx.c @@ -915,7 +915,7 @@ static void iwlagn_rx_noa_notification(struct iwl_priv *priv, len += 1 + 2; copylen += 1 + 2; - new_data = kmalloc(struct_size(new_data, data, len), GFP_ATOMIC); + new_data = kmalloc_flex(*new_data, data, len, GFP_ATOMIC); if (new_data) { new_data->length = len; new_data->data[0] = WLAN_EID_VENDOR_SPECIFIC; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c index 8b01ab986cb1..b6e3824fcda8 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/sta.c @@ -864,7 +864,7 @@ iwl_sta_alloc_lq(struct iwl_priv *priv, struct iwl_rxon_context *ctx, { struct iwl_link_quality_cmd *link_cmd; - link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL); + link_cmd = kzalloc_obj(struct iwl_link_quality_cmd); if (!link_cmd) { IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n"); return NULL; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c index 96831ce8da6f..fc9cf0531024 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/tt.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/tt.c @@ -595,13 +595,10 @@ void iwl_tt_initialize(struct iwl_priv *priv) if (priv->lib->adv_thermal_throttle) { IWL_DEBUG_TEMP(priv, "Advanced Thermal Throttling\n"); - tt->restriction = kcalloc(IWL_TI_STATE_MAX, - sizeof(struct iwl_tt_restriction), - GFP_KERNEL); - tt->transaction = kcalloc(IWL_TI_STATE_MAX * - (IWL_TI_STATE_MAX - 1), - sizeof(struct iwl_tt_trans), - GFP_KERNEL); + tt->restriction = kzalloc_objs(struct iwl_tt_restriction, + IWL_TI_STATE_MAX); + tt->transaction = kzalloc_objs(struct iwl_tt_trans, + IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1)); if (!tt->restriction || !tt->transaction) { IWL_ERR(priv, "Fallback to Legacy Throttling\n"); priv->thermal_throttle.advanced_tt = false; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c index 2ce55859641c..1f26d89fc908 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c @@ -595,7 +595,7 @@ static struct scatterlist *alloc_sgtable(ssize_t size) nents -= n_fill; } - new = kcalloc(n_alloc, sizeof(*new), GFP_KERNEL); + new = kzalloc_objs(*new, n_alloc); if (!new) { if (result) _devcd_free_sgtable(result); @@ -2958,8 +2958,7 @@ int iwl_fw_dbg_error_collect(struct iwl_fw_runtime *fwrt, struct iwl_fw_dump_desc *iwl_dump_error_desc; int ret; - iwl_dump_error_desc = - kmalloc(sizeof(*iwl_dump_error_desc), GFP_KERNEL); + iwl_dump_error_desc = kmalloc_obj(*iwl_dump_error_desc); if (!iwl_dump_error_desc) return -ENOMEM; @@ -3011,7 +3010,7 @@ int iwl_fw_dbg_collect(struct iwl_fw_runtime *fwrt, delay = le32_to_cpu(trigger->stop_delay) * USEC_PER_MSEC; } - desc = kzalloc(struct_size(desc, trig_desc.data, len), GFP_ATOMIC); + desc = kzalloc_flex(*desc, trig_desc.data, len, GFP_ATOMIC); if (!desc) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c index 3c4bee85b825..ddee7c2deb36 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/debugfs.c @@ -360,7 +360,7 @@ static void *iwl_dbgfs_fw_info_seq_start(struct seq_file *seq, loff_t *pos) if (*pos >= fw->ucode_capa.n_cmd_versions) return NULL; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return NULL; state->pos = *pos; diff --git a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c index f297e82d63d2..afff8d51ca95 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c +++ b/drivers/net/wireless/intel/iwlwifi/fw/pnvm.c @@ -379,7 +379,7 @@ iwl_pnvm_load_pnvm_to_trans(struct iwl_trans *trans, return; } - pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL); + pnvm_data = kzalloc_obj(*pnvm_data); if (!pnvm_data) goto free; @@ -425,7 +425,7 @@ iwl_pnvm_load_reduce_power_to_trans(struct iwl_trans *trans, return; } - pnvm_data = kzalloc(sizeof(*pnvm_data), GFP_KERNEL); + pnvm_data = kzalloc_obj(*pnvm_data); if (!pnvm_data) goto free; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 5240dacf1360..d021b24d04d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c @@ -71,7 +71,7 @@ static struct iwl_ucode_tlv *iwl_dbg_tlv_add(const struct iwl_ucode_tlv *tlv, u32 len = le32_to_cpu(tlv->length); struct iwl_dbg_tlv_node *node; - node = kzalloc(struct_size(node, tlv.data, len), GFP_KERNEL); + node = kzalloc_flex(*node, tlv.data, len); if (!node) return NULL; @@ -618,7 +618,7 @@ static int iwl_dbg_tlv_alloc_fragments(struct iwl_fw_runtime *fwrt, num_frags = min_t(u32, num_frags, remain_pages); frag_pages = DIV_ROUND_UP(remain_pages, num_frags); - fw_mon->frags = kcalloc(num_frags, sizeof(*fw_mon->frags), GFP_KERNEL); + fw_mon->frags = kzalloc_objs(*fw_mon->frags, num_frags); if (!fw_mon->frags) return -ENOMEM; @@ -1001,7 +1001,7 @@ static void iwl_dbg_tlv_set_periodic_trigs(struct iwl_fw_runtime *fwrt) collect_interval = le32_to_cpu(trig->data[0]); - timer_node = kzalloc(sizeof(*timer_node), GFP_KERNEL); + timer_node = kzalloc_obj(*timer_node); if (!timer_node) { IWL_ERR(fwrt, "WRT: Failed to allocate periodic trigger\n"); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index f8fc6f30fbe5..475b3e417efa 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1459,7 +1459,7 @@ static int iwl_alloc_ucode_mem(struct fw_img *out, struct fw_img_parsing *img) { struct fw_desc *sec; - sec = kcalloc(img->sec_counter, sizeof(*sec), GFP_KERNEL); + sec = kzalloc_objs(*sec, img->sec_counter); if (!sec) return -ENOMEM; @@ -1622,7 +1622,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) /* dump all fw memory areas by default */ fw->dbg.dump_mask = 0xffffffff; - pieces = kzalloc(sizeof(*pieces), GFP_KERNEL); + pieces = kzalloc_obj(*pieces); if (!pieces) goto out_free_fw; @@ -1915,7 +1915,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans) struct iwl_drv *drv; int ret; - drv = kzalloc(sizeof(*drv), GFP_KERNEL); + drv = kzalloc_obj(*drv); if (!drv) { ret = -ENOMEM; goto err; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c index e021fc57d85d..6d235c417fdd 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c @@ -1377,13 +1377,9 @@ iwl_parse_mei_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, u8 tx_chains = fw->valid_rx_ant; if (cfg->uhb_supported) - data = kzalloc(struct_size(data, channels, - IWL_NVM_NUM_CHANNELS_UHB), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UHB); else - data = kzalloc(struct_size(data, channels, - IWL_NVM_NUM_CHANNELS_EXT), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_EXT); if (!data) return NULL; @@ -1446,17 +1442,11 @@ iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_rf_cfg *cfg, const __le16 *ch_section; if (cfg->uhb_supported) - data = kzalloc(struct_size(data, channels, - IWL_NVM_NUM_CHANNELS_UHB), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_UHB); else if (cfg->nvm_type != IWL_NVM_EXT) - data = kzalloc(struct_size(data, channels, - IWL_NVM_NUM_CHANNELS), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS); else - data = kzalloc(struct_size(data, channels, - IWL_NVM_NUM_CHANNELS_EXT), - GFP_KERNEL); + data = kzalloc_flex(*data, channels, IWL_NVM_NUM_CHANNELS_EXT); if (!data) return NULL; @@ -1692,7 +1682,7 @@ iwl_parse_nvm_mcc_info(struct iwl_trans *trans, num_of_ch); /* build a regdomain rule for every valid channel */ - regd = kzalloc(struct_size(regd, reg_rules, num_of_ch), GFP_KERNEL); + regd = kzalloc_flex(*regd, reg_rules, num_of_ch); if (!regd) return ERR_PTR(-ENOMEM); @@ -2041,7 +2031,7 @@ struct iwl_nvm_data *iwl_get_nvm(struct iwl_trans *trans, if (empty_otp) IWL_INFO(trans, "OTP is empty\n"); - nvm = kzalloc(struct_size(nvm, channels, IWL_NUM_CHANNELS), GFP_KERNEL); + nvm = kzalloc_flex(*nvm, channels, IWL_NUM_CHANNELS); if (!nvm) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c index 0a93ac769f66..0a87deea3474 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-phy-db.c @@ -59,8 +59,7 @@ struct iwl_phy_db_chg_txp { struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) { - struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), - GFP_KERNEL); + struct iwl_phy_db *phy_db = kzalloc_obj(struct iwl_phy_db); if (!phy_db) return phy_db; @@ -172,9 +171,9 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, * Firmware sends the largest index first, so we can use * it to know how much we should allocate. */ - phy_db->calib_ch_group_papd = kcalloc(chg_id + 1, - sizeof(struct iwl_phy_db_entry), - GFP_ATOMIC); + phy_db->calib_ch_group_papd = kzalloc_objs(struct iwl_phy_db_entry, + chg_id + 1, + GFP_ATOMIC); if (!phy_db->calib_ch_group_papd) return -ENOMEM; phy_db->n_group_papd = chg_id + 1; @@ -186,9 +185,9 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, * Firmware sends the largest index first, so we can use * it to know how much we should allocate. */ - phy_db->calib_ch_group_txp = kcalloc(chg_id + 1, - sizeof(struct iwl_phy_db_entry), - GFP_ATOMIC); + phy_db->calib_ch_group_txp = kzalloc_objs(struct iwl_phy_db_entry, + chg_id + 1, + GFP_ATOMIC); if (!phy_db->calib_ch_group_txp) return -ENOMEM; phy_db->n_group_txp = chg_id + 1; diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c index fa1442246662..89901786fd68 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.c @@ -46,7 +46,7 @@ iwl_trans_get_restart_data(struct device *dev) if (data) return data; - data = kzalloc(struct_size(data, name, strlen(name) + 1), GFP_ATOMIC); + data = kzalloc_flex(*data, name, strlen(name) + 1, GFP_ATOMIC); if (!data) return NULL; @@ -113,7 +113,7 @@ static void iwl_trans_schedule_reprobe(struct iwl_trans *trans, return; } - reprobe = kzalloc(sizeof(*reprobe), GFP_KERNEL); + reprobe = kzalloc_obj(*reprobe); if (!reprobe) { module_put(THIS_MODULE); return; diff --git a/drivers/net/wireless/intel/iwlwifi/mei/main.c b/drivers/net/wireless/intel/iwlwifi/mei/main.c index dce0b7cf7b26..c5ff1b1b720f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mei/main.c +++ b/drivers/net/wireless/intel/iwlwifi/mei/main.c @@ -702,7 +702,7 @@ static void iwl_mei_handle_csme_filters(struct mei_cl_device *cldev, rcu_dereference_protected(mei->filters, lockdep_is_held(&iwl_mei_mutex)); - new_filters = kzalloc(sizeof(*new_filters), GFP_KERNEL); + new_filters = kzalloc_obj(*new_filters); if (!new_filters) return; @@ -886,7 +886,7 @@ static void iwl_mei_handle_nvm(struct mei_cl_device *cldev, int i; kfree(mei->nvm); - mei->nvm = kzalloc(sizeof(*mei_nvm), GFP_KERNEL); + mei->nvm = kzalloc_obj(*mei_nvm); if (!mei->nvm) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c index 6595542e95cf..ef98efc8fb1b 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c @@ -609,10 +609,9 @@ iwl_mld_handle_wowlan_info_notif(struct iwl_mld *mld, 5)) return true; - converted_notif = kzalloc(struct_size(converted_notif, - mlo_gtks, - notif_v5->num_mlo_link_keys), - GFP_ATOMIC); + converted_notif = kzalloc_flex(*converted_notif, mlo_gtks, + notif_v5->num_mlo_link_keys, + GFP_ATOMIC); if (!converted_notif) { IWL_ERR(mld, "Failed to allocate memory for converted wowlan_info_notif\n"); @@ -1173,8 +1172,7 @@ iwl_mld_set_netdetect_info(struct iwl_mld *mld, for (int k = 0; k < SCAN_OFFLOAD_MATCHING_CHANNELS_LEN; k++) n_channels += hweight8(matches[i].matching_channels[k]); - match = kzalloc(struct_size(match, channels, n_channels), - GFP_KERNEL); + match = kzalloc_flex(*match, channels, n_channels); if (!match) return; @@ -1251,8 +1249,7 @@ iwl_mld_process_netdetect_res(struct iwl_mld *mld, goto out; } n_matches = hweight_long(matched_profiles); - netdetect_info = kzalloc(struct_size(netdetect_info, matches, - n_matches), GFP_KERNEL); + netdetect_info = kzalloc_flex(*netdetect_info, matches, n_matches); if (netdetect_info) iwl_mld_set_netdetect_info(mld, netdetect_cfg, netdetect_info, resume_data->netdetect_res, @@ -1656,7 +1653,7 @@ iwl_mld_suspend_send_security_cmds(struct iwl_mld *mld, struct iwl_mld_suspend_key_iter_data data = {}; int ret; - data.rsc = kzalloc(sizeof(*data.rsc), GFP_KERNEL); + data.rsc = kzalloc_obj(*data.rsc); if (!data.rsc) return -ENOMEM; @@ -2002,8 +1999,7 @@ int iwl_mld_wowlan_resume(struct iwl_mld *mld) iwl_fw_dbg_read_d3_debug_data(&mld->fwrt); - resume_data.wowlan_status = kzalloc(sizeof(*resume_data.wowlan_status), - GFP_KERNEL); + resume_data.wowlan_status = kzalloc_obj(*resume_data.wowlan_status); if (!resume_data.wowlan_status) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/iface.c b/drivers/net/wireless/intel/iwlwifi/mld/iface.c index 743e44ff19cf..29df747c8938 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/iface.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/iface.c @@ -542,7 +542,7 @@ void iwl_mld_handle_probe_resp_data_notif(struct iwl_mld *mld, notif->noa_attr.len_low)) return; - new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + new_data = kzalloc_obj(*new_data); if (!new_data) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/link.c b/drivers/net/wireless/intel/iwlwifi/mld/link.c index d89840a1152b..b5430e8a73d6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/link.c @@ -468,7 +468,7 @@ int iwl_mld_add_link(struct iwl_mld *mld, if (is_deflink) { link = &mld_vif->deflink; } else { - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; } diff --git a/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c b/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c index 23362867b400..d39dd36b08e3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/low_latency.c @@ -131,8 +131,8 @@ int iwl_mld_low_latency_init(struct iwl_mld *mld) struct iwl_mld_low_latency *ll = &mld->low_latency; unsigned long ts = jiffies; - ll->pkts_counters = kcalloc(mld->trans->info.num_rxqs, - sizeof(*ll->pkts_counters), GFP_KERNEL); + ll->pkts_counters = kzalloc_objs(*ll->pkts_counters, + mld->trans->info.num_rxqs); if (!ll->pkts_counters) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c index 3414b04a6953..0c53d6bd9651 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/mac80211.c @@ -2092,8 +2092,7 @@ static int iwl_mld_alloc_ptk_pn(struct iwl_mld *mld, return -EINVAL; WARN_ON(rcu_access_pointer(mld_sta->ptk_pn[keyidx])); - *ptk_pn = kzalloc(struct_size(*ptk_pn, q, num_rx_queues), - GFP_KERNEL); + *ptk_pn = kzalloc_flex(**ptk_pn, q, num_rx_queues); if (!*ptk_pn) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/notif.c b/drivers/net/wireless/intel/iwlwifi/mld/notif.c index 35356b244c0a..240526d8b632 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/notif.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/notif.c @@ -557,7 +557,7 @@ static void iwl_mld_rx_notif(struct iwl_mld *mld, break; } - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); /* we can't do much... */ if (!entry) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/scan.c b/drivers/net/wireless/intel/iwlwifi/mld/scan.c index 16f48087a888..a1a4cf3ab3d3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/scan.c @@ -2083,9 +2083,8 @@ void iwl_mld_handle_channel_survey_notif(struct iwl_mld *mld, n_channels += mld->wiphy->bands[band]->n_channels; } - mld->channel_survey = kzalloc(struct_size(mld->channel_survey, - channels, n_channels), - GFP_KERNEL); + mld->channel_survey = kzalloc_flex(*mld->channel_survey, + channels, n_channels); if (!mld->channel_survey) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/sta.c b/drivers/net/wireless/intel/iwlwifi/mld/sta.c index 6056a306f7cb..6b7a89e050e6 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/sta.c @@ -539,7 +539,7 @@ iwl_mld_add_link_sta(struct iwl_mld *mld, struct ieee80211_link_sta *link_sta) if (link_sta == &link_sta->sta->deflink) { mld_link_sta = &mld_sta->deflink; } else { - mld_link_sta = kzalloc(sizeof(*mld_link_sta), GFP_KERNEL); + mld_link_sta = kzalloc_obj(*mld_link_sta); if (!mld_link_sta) return -ENOMEM; } @@ -660,8 +660,7 @@ iwl_mld_alloc_dup_data(struct iwl_mld *mld, struct iwl_mld_sta *mld_sta) if (mld->fw_status.in_hw_restart) return 0; - dup_data = kcalloc(mld->trans->info.num_rxqs, sizeof(*dup_data), - GFP_KERNEL); + dup_data = kzalloc_objs(*dup_data, mld->trans->info.num_rxqs); if (!dup_data) return -ENOMEM; @@ -695,9 +694,8 @@ static void iwl_mld_alloc_mpdu_counters(struct iwl_mld *mld, sta->tdls || !ieee80211_vif_is_mld(vif)) return; - mld_sta->mpdu_counters = kcalloc(mld->trans->info.num_rxqs, - sizeof(*mld_sta->mpdu_counters), - GFP_KERNEL); + mld_sta->mpdu_counters = kzalloc_objs(*mld_sta->mpdu_counters, + mld->trans->info.num_rxqs); if (!mld_sta->mpdu_counters) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c b/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c index 50799f9bfccb..897ab65b71aa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/time_sync.c @@ -12,8 +12,7 @@ static int iwl_mld_init_time_sync(struct iwl_mld *mld, u32 protocols, const u8 *addr) { - struct iwl_mld_time_sync_data *time_sync = kzalloc(sizeof(*time_sync), - GFP_KERNEL); + struct iwl_mld_time_sync_data *time_sync = kzalloc_obj(*time_sync); if (!time_sync) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index 6c225861db61..a19f9d2e9346 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -460,7 +460,7 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm, struct wowlan_key_rsc_v5_data data = {}; int i; - data.rsc = kzalloc(sizeof(*data.rsc), GFP_KERNEL); + data.rsc = kzalloc_obj(*data.rsc); if (!data.rsc) return -ENOMEM; @@ -483,7 +483,7 @@ static int iwl_mvm_wowlan_config_rsc_tsc(struct iwl_mvm *mvm, } else if (ver == 2 || ver == IWL_FW_CMD_VER_UNKNOWN) { struct wowlan_key_rsc_tsc_data data = {}; - data.rsc_tsc = kzalloc(sizeof(*data.rsc_tsc), GFP_KERNEL); + data.rsc_tsc = kzalloc_obj(*data.rsc_tsc); if (!data.rsc_tsc) return -ENOMEM; @@ -2605,8 +2605,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, n_matches = 0; } - net_detect = kzalloc(struct_size(net_detect, matches, n_matches), - GFP_KERNEL); + net_detect = kzalloc_flex(*net_detect, matches, n_matches); if (!net_detect || !n_matches) goto out_report_nd; net_detect->n_matches = n_matches; @@ -2620,8 +2619,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, d3_data->nd_results, i); - match = kzalloc(struct_size(match, channels, n_channels), - GFP_KERNEL); + match = kzalloc_flex(*match, channels, n_channels); if (!match) goto out_report_nd; match->n_channels = n_channels; @@ -3093,7 +3091,7 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm) } if (resume_notif_based) { - d3_data.status = kzalloc(sizeof(*d3_data.status), GFP_KERNEL); + d3_data.status = kzalloc_obj(*d3_data.status); if (!d3_data.status) { IWL_ERR(mvm, "Failed to allocate wowlan status\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c index a493ef6bedc3..ebc569e94f55 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c @@ -1124,7 +1124,7 @@ static void iwl_mvm_ftm_rtt_smoothing(struct iwl_mvm *mvm, } if (!resp) { - resp = kzalloc(sizeof(*resp), GFP_KERNEL); + resp = kzalloc_obj(*resp); if (!resp) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 0e5820c13523..c523c5e82d4a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1764,7 +1764,7 @@ void iwl_mvm_probe_resp_data_notif(struct iwl_mvm *mvm, notif->noa_attr.len_low)) return; - new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + new_data = kzalloc_obj(*new_data); if (!new_data) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 169c87588938..090791fe0638 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -4348,9 +4348,8 @@ static int __iwl_mvm_mac_set_key(struct ieee80211_hw *hw, int tid, q; WARN_ON(rcu_access_pointer(mvmsta->ptk_pn[keyidx])); - ptk_pn = kzalloc(struct_size(ptk_pn, q, - mvm->trans->info.num_rxqs), - GFP_KERNEL); + ptk_pn = kzalloc_flex(*ptk_pn, q, + mvm->trans->info.num_rxqs); if (!ptk_pn) { ret = -ENOMEM; break; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 075ff09e93cc..896ed9823021 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -905,7 +905,7 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw, if (!(added & BIT(i))) continue; - new_link[i] = kzalloc(sizeof(*new_link[i]), GFP_KERNEL); + new_link[i] = kzalloc_obj(*new_link[i]); if (!new_link[i]) { err = -ENOMEM; goto free; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c index 1100d763ceb6..3359e02e151f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c @@ -547,7 +547,7 @@ static int iwl_mvm_mld_alloc_sta_link(struct iwl_mvm *mvm, if (rcu_access_pointer(sta->link[link_id]) == &sta->deflink) { link = &mvm_sta->deflink; } else { - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index 5ebd046371f5..ae177477b201 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c @@ -1097,7 +1097,7 @@ static void iwl_mvm_me_conn_status(void *priv, const struct iwl_mei_conn_info *c */ prev_conn_info = rcu_dereference_protected(mvm->csme_conn_info, true); - curr_conn_info = kzalloc(sizeof(*curr_conn_info), GFP_KERNEL); + curr_conn_info = kzalloc_obj(*curr_conn_info); if (!curr_conn_info) return; @@ -1747,7 +1747,7 @@ static void iwl_mvm_rx_common(struct iwl_mvm *mvm, return; } - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); /* we can't do much... */ if (!entry) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c index 9c51953d255d..79829f775c89 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c @@ -547,7 +547,7 @@ iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm, else blocklist_len = IWL_SCAN_MAX_BLACKLIST_LEN; - blocklist = kcalloc(blocklist_len, sizeof(*blocklist), GFP_KERNEL); + blocklist = kzalloc_objs(*blocklist, blocklist_len); if (!blocklist) return -ENOMEM; @@ -3603,9 +3603,8 @@ void iwl_mvm_rx_channel_survey_notif(struct iwl_mvm *mvm, n_channels += mvm->hw->wiphy->bands[band]->n_channels; } - mvm->acs_survey = kzalloc(struct_size(mvm->acs_survey, - channels, n_channels), - GFP_KERNEL); + mvm->acs_survey = kzalloc_flex(*mvm->acs_survey, channels, + n_channels); if (!mvm->acs_survey) return; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 363232bb74fa..2d0811be7346 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -1798,8 +1798,7 @@ int iwl_mvm_sta_init(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (iwl_mvm_has_new_rx_api(mvm)) { int q; - dup_data = kcalloc(mvm->trans->info.num_rxqs, - sizeof(*dup_data), GFP_KERNEL); + dup_data = kzalloc_objs(*dup_data, mvm->trans->info.num_rxqs); if (!dup_data) return -ENOMEM; /* diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c index 0957223c776d..d5eb895144ef 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info.c @@ -99,10 +99,10 @@ int iwl_pcie_init_fw_sec(struct iwl_trans *trans, /* add 2 due to separators */ paging_cnt = iwl_pcie_get_num_sections(fw, lmac_cnt + umac_cnt + 2); - dram->fw = kcalloc(umac_cnt + lmac_cnt, sizeof(*dram->fw), GFP_KERNEL); + dram->fw = kzalloc_objs(*dram->fw, umac_cnt + lmac_cnt); if (!dram->fw) return -ENOMEM; - dram->paging = kcalloc(paging_cnt, sizeof(*dram->paging), GFP_KERNEL); + dram->paging = kzalloc_objs(*dram->paging, paging_cnt); if (!dram->paging) return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c index 619a9505e6d9..fe263cdc2e4f 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/rx.c @@ -773,15 +773,12 @@ static int iwl_pcie_rx_alloc(struct iwl_trans *trans) if (WARN_ON(trans_pcie->rxq)) return -EINVAL; - trans_pcie->rxq = kcalloc(trans->info.num_rxqs, sizeof(struct iwl_rxq), - GFP_KERNEL); - trans_pcie->rx_pool = kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), - sizeof(trans_pcie->rx_pool[0]), - GFP_KERNEL); + trans_pcie->rxq = kzalloc_objs(struct iwl_rxq, trans->info.num_rxqs); + trans_pcie->rx_pool = kzalloc_objs(trans_pcie->rx_pool[0], + RX_POOL_SIZE(trans_pcie->num_rx_bufs)); trans_pcie->global_table = - kcalloc(RX_POOL_SIZE(trans_pcie->num_rx_bufs), - sizeof(trans_pcie->global_table[0]), - GFP_KERNEL); + kzalloc_objs(trans_pcie->global_table[0], + RX_POOL_SIZE(trans_pcie->num_rx_bufs)); if (!trans_pcie->rxq || !trans_pcie->rx_pool || !trans_pcie->global_table) { ret = -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c index 415a19ea9f06..4560d92d76fe 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/trans.c @@ -2303,7 +2303,7 @@ void iwl_trans_pcie_reset(struct iwl_trans *trans, enum iwl_reset_mode mode) return; } - removal = kzalloc(sizeof(*removal), GFP_ATOMIC); + removal = kzalloc_obj(*removal, GFP_ATOMIC); if (!removal) { module_put(THIS_MODULE); return; @@ -2748,7 +2748,7 @@ static void *iwl_dbgfs_tx_queue_seq_start(struct seq_file *seq, loff_t *pos) if (*pos >= priv->trans->mac_cfg->base->num_of_queues) return NULL; - state = kmalloc(sizeof(*state), GFP_KERNEL); + state = kmalloc_obj(*state); if (!state) return NULL; state->pos = *pos; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c index df0545f09da9..bda9f807321e 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx-gen2.c @@ -928,7 +928,7 @@ iwl_txq_dyn_alloc_dma(struct iwl_trans *trans, int size, unsigned int timeout) if (WARN_ON(size > bc_tbl_entries)) return ERR_PTR(-EINVAL); - txq = kzalloc(sizeof(*txq), GFP_KERNEL); + txq = kzalloc_obj(*txq); if (!txq) return ERR_PTR(-ENOMEM); @@ -1152,7 +1152,7 @@ int iwl_txq_gen2_init(struct iwl_trans *trans, int txq_id, int queue_size) /* alloc and init the tx queue */ if (!trans_pcie->txqs.txq[txq_id]) { - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) { IWL_ERR(trans, "Not enough memory for tx queue\n"); return -ENOMEM; diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c index 6e85aa519e1b..fdb3ba4f63c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/gen1_2/tx.c @@ -741,9 +741,7 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, txq->n_window = slots_num; - txq->entries = kcalloc(slots_num, - sizeof(struct iwl_pcie_txq_entry), - GFP_KERNEL); + txq->entries = kzalloc_objs(struct iwl_pcie_txq_entry, slots_num); if (!txq->entries) goto error; @@ -751,8 +749,7 @@ int iwl_pcie_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, if (cmd_queue) for (i = 0; i < slots_num; i++) { txq->entries[i].cmd = - kmalloc(sizeof(struct iwl_device_cmd), - GFP_KERNEL); + kmalloc_obj(struct iwl_device_cmd); if (!txq->entries[i].cmd) goto error; } @@ -838,8 +835,8 @@ static int iwl_pcie_tx_alloc(struct iwl_trans *trans) } trans_pcie->txq_memory = - kcalloc(trans->mac_cfg->base->num_of_queues, - sizeof(struct iwl_txq), GFP_KERNEL); + kzalloc_objs(struct iwl_txq, + trans->mac_cfg->base->num_of_queues); if (!trans_pcie->txq_memory) { IWL_ERR(trans, "Not enough memory for txq\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/intersil/p54/eeprom.c b/drivers/net/wireless/intersil/p54/eeprom.c index 5bd35c147e19..95580921d933 100644 --- a/drivers/net/wireless/intersil/p54/eeprom.c +++ b/drivers/net/wireless/intersil/p54/eeprom.c @@ -154,13 +154,12 @@ static int p54_generate_band(struct ieee80211_hw *dev, if ((!list->entries) || (!list->band_channel_num[band])) return -EINVAL; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) goto err_out; - tmp->channels = kcalloc(list->band_channel_num[band], - sizeof(struct ieee80211_channel), - GFP_KERNEL); + tmp->channels = kzalloc_objs(struct ieee80211_channel, + list->band_channel_num[band]); if (!tmp->channels) goto err_out; @@ -336,23 +335,20 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev) max_channel_num = max_t(unsigned int, max_channel_num, priv->curve_data->entries); - list = kzalloc(sizeof(*list), GFP_KERNEL); + list = kzalloc_obj(*list); if (!list) { ret = -ENOMEM; goto free; } priv->chan_num = max_channel_num; - priv->survey = kcalloc(max_channel_num, sizeof(struct survey_info), - GFP_KERNEL); + priv->survey = kzalloc_objs(struct survey_info, max_channel_num); if (!priv->survey) { ret = -ENOMEM; goto free; } list->max_entries = max_channel_num; - list->channels = kcalloc(max_channel_num, - sizeof(struct p54_channel_entry), - GFP_KERNEL); + list->channels = kzalloc_objs(struct p54_channel_entry, max_channel_num); if (!list->channels) { ret = -ENOMEM; goto free; diff --git a/drivers/net/wireless/intersil/p54/p54usb.c b/drivers/net/wireless/intersil/p54/p54usb.c index cae47663b17b..c0d3b5329f4e 100644 --- a/drivers/net/wireless/intersil/p54/p54usb.c +++ b/drivers/net/wireless/intersil/p54/p54usb.c @@ -328,7 +328,7 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb) struct net2280_reg_write *reg = NULL; int err = -ENOMEM; - reg = kmalloc(sizeof(*reg), GFP_ATOMIC); + reg = kmalloc_obj(*reg, GFP_ATOMIC); if (!reg) goto out; diff --git a/drivers/net/wireless/marvell/libertas/cfg.c b/drivers/net/wireless/marvell/libertas/cfg.c index caba7491cd5a..98517888dba7 100644 --- a/drivers/net/wireless/marvell/libertas/cfg.c +++ b/drivers/net/wireless/marvell/libertas/cfg.c @@ -2094,7 +2094,7 @@ struct wireless_dev *lbs_cfg_alloc(struct device *dev) int ret = 0; struct wireless_dev *wdev; - wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + wdev = kzalloc_obj(struct wireless_dev); if (!wdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/marvell/libertas/debugfs.c b/drivers/net/wireless/marvell/libertas/debugfs.c index c604613ab506..9ebd69134940 100644 --- a/drivers/net/wireless/marvell/libertas/debugfs.c +++ b/drivers/net/wireless/marvell/libertas/debugfs.c @@ -232,7 +232,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask, if (!buf) return -ENOMEM; - subscribed = kzalloc(sizeof(*subscribed), GFP_KERNEL); + subscribed = kzalloc_obj(*subscribed); if (!subscribed) { ret = -ENOMEM; goto out_page; @@ -288,7 +288,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, ret = -EINVAL; goto out_page; } - events = kzalloc(sizeof(*events), GFP_KERNEL); + events = kzalloc_obj(*events); if (!events) { ret = -ENOMEM; goto out_page; diff --git a/drivers/net/wireless/marvell/libertas/if_sdio.c b/drivers/net/wireless/marvell/libertas/if_sdio.c index fc5318035822..dd6756c1242e 100644 --- a/drivers/net/wireless/marvell/libertas/if_sdio.c +++ b/drivers/net/wireless/marvell/libertas/if_sdio.c @@ -1158,7 +1158,7 @@ static int if_sdio_probe(struct sdio_func *func, return -ENODEV; } - card = kzalloc(sizeof(struct if_sdio_card), GFP_KERNEL); + card = kzalloc_obj(struct if_sdio_card); if (!card) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/libertas/if_spi.c b/drivers/net/wireless/marvell/libertas/if_spi.c index 8a2504a62840..b22d1e65f552 100644 --- a/drivers/net/wireless/marvell/libertas/if_spi.c +++ b/drivers/net/wireless/marvell/libertas/if_spi.c @@ -1113,7 +1113,7 @@ static int if_spi_probe(struct spi_device *spi) } /* Allocate card structure to represent this specific device */ - card = kzalloc(sizeof(struct if_spi_card), GFP_KERNEL); + card = kzalloc_obj(struct if_spi_card); if (!card) { err = -ENOMEM; goto teardown; diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c b/drivers/net/wireless/marvell/libertas/if_usb.c index 924ab93b7b67..8a6bf1365cfa 100644 --- a/drivers/net/wireless/marvell/libertas/if_usb.c +++ b/drivers/net/wireless/marvell/libertas/if_usb.c @@ -203,7 +203,7 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); - cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); + cardp = kzalloc_obj(struct if_usb_card); if (!cardp) goto error; diff --git a/drivers/net/wireless/marvell/libertas/main.c b/drivers/net/wireless/marvell/libertas/main.c index d44e02c6fe38..dd97f1b61f4d 100644 --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c @@ -799,8 +799,8 @@ static void lbs_free_adapter(struct lbs_private *priv) { lbs_free_cmd_buffer(priv); kfifo_free(&priv->event_fifo); - timer_delete(&priv->command_timer); - timer_delete(&priv->tx_lockup_timer); + timer_delete_sync(&priv->command_timer); + timer_delete_sync(&priv->tx_lockup_timer); } static const struct net_device_ops lbs_netdev_ops = { diff --git a/drivers/net/wireless/marvell/libertas/mesh.c b/drivers/net/wireless/marvell/libertas/mesh.c index 2dd635935448..fced7485d015 100644 --- a/drivers/net/wireless/marvell/libertas/mesh.c +++ b/drivers/net/wireless/marvell/libertas/mesh.c @@ -983,7 +983,7 @@ static int lbs_add_mesh(struct lbs_private *priv) int ret = 0; /* Allocate a virtual mesh device */ - mesh_wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); + mesh_wdev = kzalloc_obj(struct wireless_dev); if (!mesh_wdev) { lbs_deb_mesh("init mshX wireless device failed\n"); ret = -ENOMEM; diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c b/drivers/net/wireless/marvell/libertas_tf/if_usb.c index 5662a244f82a..f49151c18b79 100644 --- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c +++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c @@ -154,7 +154,7 @@ static int if_usb_probe(struct usb_interface *intf, lbtf_deb_enter(LBTF_DEB_USB); udev = interface_to_usbdev(intf); - cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); + cardp = kzalloc_obj(struct if_usb_card); if (!cardp) goto error; diff --git a/drivers/net/wireless/marvell/mwifiex/11n.c b/drivers/net/wireless/marvell/mwifiex/11n.c index 66f0f5377ac1..cef8a55427dd 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n.c +++ b/drivers/net/wireless/marvell/mwifiex/11n.c @@ -547,8 +547,8 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid, int tid_down; if (!mwifiex_get_ba_tbl(priv, tid, ra)) { - new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl), - GFP_ATOMIC); + new_node = kzalloc_obj(struct mwifiex_tx_ba_stream_tbl, + GFP_ATOMIC); if (!new_node) return; diff --git a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c index f3397dc6c422..610ec8302adf 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c @@ -344,7 +344,7 @@ mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta, return; } /* if !tbl then create one */ - new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL); + new_node = kzalloc_obj(struct mwifiex_rx_reorder_tbl); if (!new_node) return; diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c index a66d18e380fc..eb28fe718e71 100644 --- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c +++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c @@ -756,7 +756,7 @@ mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx, return -EINVAL; } - bss_cfg = kzalloc(sizeof(*bss_cfg), GFP_KERNEL); + bss_cfg = kzalloc_obj(*bss_cfg); if (!bss_cfg) return -ENOMEM; @@ -2073,7 +2073,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, if (GET_BSS_ROLE(priv) != MWIFIEX_BSS_ROLE_UAP) return -1; - bss_cfg = kzalloc(sizeof(struct mwifiex_uap_bss_param), GFP_KERNEL); + bss_cfg = kzalloc_obj(struct mwifiex_uap_bss_param); if (!bss_cfg) return -ENOMEM; @@ -2683,7 +2683,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, if (!mwifiex_stop_bg_scan(priv)) cfg80211_sched_scan_stopped_locked(priv->wdev.wiphy, 0); - user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL); + user_scan_cfg = kzalloc_obj(*user_scan_cfg); if (!user_scan_cfg) return -ENOMEM; @@ -2787,7 +2787,7 @@ mwifiex_cfg80211_sched_scan_start(struct wiphy *wiphy, request->n_channels, request->scan_plans->interval, (int)request->ie_len); - bgscan_cfg = kzalloc(sizeof(*bgscan_cfg), GFP_KERNEL); + bgscan_cfg = kzalloc_obj(*bgscan_cfg); if (!bgscan_cfg) return -ENOMEM; @@ -3148,7 +3148,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, SET_NETDEV_DEV(dev, adapter->dev); ret = dev_alloc_name(dev, name); - if (ret) + if (ret < 0) goto err_alloc_name; priv->dfs_cac_workqueue = alloc_workqueue("MWIFIEX_DFS_CAC-%s", @@ -3452,7 +3452,7 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv, if (wowlan->n_patterns || wowlan->magic_pkt) num_entries++; - mef_entry = kcalloc(num_entries, sizeof(*mef_entry), GFP_KERNEL); + mef_entry = kzalloc_objs(*mef_entry, num_entries); if (!mef_entry) return -ENOMEM; @@ -3989,7 +3989,7 @@ mwifiex_cfg80211_uap_add_station(struct mwifiex_private *priv, const u8 *mac, if (!ret) { struct station_info *sinfo; - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return -ENOMEM; @@ -4161,7 +4161,7 @@ static int mwifiex_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, if (!tb[MWIFIEX_TM_ATTR_DATA]) return -EINVAL; - hostcmd = kzalloc(sizeof(*hostcmd), GFP_KERNEL); + hostcmd = kzalloc_obj(*hostcmd); if (!hostcmd) return -ENOMEM; @@ -4677,9 +4677,8 @@ int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter) * additional active scan request for hidden SSIDs on passive channels. */ adapter->num_in_chan_stats = 2 * (n_channels_bg + n_channels_a); - adapter->chan_stats = kcalloc(adapter->num_in_chan_stats, - sizeof(*adapter->chan_stats), - GFP_KERNEL); + adapter->chan_stats = kzalloc_objs(*adapter->chan_stats, + adapter->num_in_chan_stats); if (!adapter->chan_stats) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/cmdevt.c b/drivers/net/wireless/marvell/mwifiex/cmdevt.c index 0f466c31337f..29e0f274575e 100644 --- a/drivers/net/wireless/marvell/mwifiex/cmdevt.c +++ b/drivers/net/wireless/marvell/mwifiex/cmdevt.c @@ -389,8 +389,8 @@ int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter) u32 i; /* Allocate and initialize struct cmd_ctrl_node */ - cmd_array = kcalloc(MWIFIEX_NUM_OF_CMD_BUFFER, - sizeof(struct cmd_ctrl_node), GFP_KERNEL); + cmd_array = kzalloc_objs(struct cmd_ctrl_node, + MWIFIEX_NUM_OF_CMD_BUFFER); if (!cmd_array) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c index 26694cee15d3..6e4074bfc0c8 100644 --- a/drivers/net/wireless/marvell/mwifiex/ie.c +++ b/drivers/net/wireless/marvell/mwifiex/ie.c @@ -149,7 +149,7 @@ mwifiex_update_uap_custom_ie(struct mwifiex_private *priv, u16 len; int ret; - ap_custom_ie = kzalloc(sizeof(*ap_custom_ie), GFP_KERNEL); + ap_custom_ie = kzalloc_obj(*ap_custom_ie); if (!ap_custom_ie) return -ENOMEM; @@ -221,8 +221,7 @@ static int mwifiex_update_vs_ie(const u8 *ies, int ies_len, vendor_ie = cfg80211_find_vendor_ie(oui, oui_type, ies, ies_len); if (vendor_ie) { if (!*ie_ptr) { - *ie_ptr = kzalloc(sizeof(struct mwifiex_ie), - GFP_KERNEL); + *ie_ptr = kzalloc_obj(struct mwifiex_ie); if (!*ie_ptr) return -ENOMEM; ie = *ie_ptr; @@ -326,7 +325,7 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, if (!info->tail || !info->tail_len) return 0; - gen_ie = kzalloc(sizeof(*gen_ie), GFP_KERNEL); + gen_ie = kzalloc_obj(*gen_ie); if (!gen_ie) return -ENOMEM; @@ -439,7 +438,7 @@ int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) int ret = 0; if (priv->gen_idx != MWIFIEX_AUTO_IDX_MASK) { - gen_ie = kmalloc(sizeof(*gen_ie), GFP_KERNEL); + gen_ie = kmalloc_obj(*gen_ie); if (!gen_ie) return -ENOMEM; @@ -457,7 +456,7 @@ int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) } if (priv->beacon_idx != MWIFIEX_AUTO_IDX_MASK) { - beacon_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); + beacon_ie = kmalloc_obj(struct mwifiex_ie); if (!beacon_ie) { ret = -ENOMEM; goto done; @@ -467,7 +466,7 @@ int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) beacon_ie->ie_length = 0; } if (priv->proberesp_idx != MWIFIEX_AUTO_IDX_MASK) { - pr_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); + pr_ie = kmalloc_obj(struct mwifiex_ie); if (!pr_ie) { ret = -ENOMEM; goto done; @@ -477,7 +476,7 @@ int mwifiex_del_mgmt_ies(struct mwifiex_private *priv) pr_ie->ie_length = 0; } if (priv->assocresp_idx != MWIFIEX_AUTO_IDX_MASK) { - ar_ie = kmalloc(sizeof(struct mwifiex_ie), GFP_KERNEL); + ar_ie = kmalloc_obj(struct mwifiex_ie); if (!ar_ie) { ret = -ENOMEM; goto done; diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index 4820010a86f6..5c9a46e64d23 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -25,7 +25,7 @@ static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv) struct mwifiex_bss_prio_node *bss_prio; struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl; - bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL); + bss_prio = kzalloc_obj(struct mwifiex_bss_prio_node); if (!bss_prio) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index ff177b06f42d..a8eab6b1e63b 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -60,7 +60,7 @@ static int mwifiex_register(void *card, struct device *dev, struct mwifiex_adapter *adapter; int i; - adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL); + adapter = kzalloc_obj(struct mwifiex_adapter); if (!adapter) return -ENOMEM; @@ -82,7 +82,7 @@ static int mwifiex_register(void *card, struct device *dev, for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) { /* Allocate memory for private structure */ adapter->priv[i] = - kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL); + kzalloc_obj(struct mwifiex_private); if (!adapter->priv[i]) goto error; @@ -1180,7 +1180,7 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) p += adapter->if_ops.reg_dump(adapter, p); } p += sprintf(p, "\n=== more debug information\n"); - debug_info = kzalloc(sizeof(*debug_info), GFP_KERNEL); + debug_info = kzalloc_obj(*debug_info); if (debug_info) { for (i = 0; i < adapter->priv_num; i++) { if (!adapter->priv[i]->netdev) @@ -1346,7 +1346,7 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA || GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) { - priv->hist_data = kmalloc(sizeof(*priv->hist_data), GFP_KERNEL); + priv->hist_data = kmalloc_obj(*priv->hist_data); if (priv->hist_data) mwifiex_hist_data_reset(priv); } diff --git a/drivers/net/wireless/marvell/mwifiex/scan.c b/drivers/net/wireless/marvell/mwifiex/scan.c index cab889af4c4a..97c0ec3b822e 100644 --- a/drivers/net/wireless/marvell/mwifiex/scan.c +++ b/drivers/net/wireless/marvell/mwifiex/scan.c @@ -1503,16 +1503,14 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, adapter->scan_processing = true; spin_unlock_bh(&adapter->mwifiex_cmd_lock); - scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), - GFP_KERNEL); + scan_cfg_out = kzalloc_obj(union mwifiex_scan_cmd_config_tlv); if (!scan_cfg_out) { ret = -ENOMEM; goto done; } - scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX, - sizeof(struct mwifiex_chan_scan_param_set), - GFP_KERNEL); + scan_chan_list = kzalloc_objs(struct mwifiex_chan_scan_param_set, + MWIFIEX_USER_SCAN_CHAN_MAX); if (!scan_chan_list) { kfree(scan_cfg_out); ret = -ENOMEM; @@ -1650,7 +1648,7 @@ static int mwifiex_save_hidden_ssid_channels(struct mwifiex_private *priv, int chid; /* Allocate and fill new bss descriptor */ - bss_desc = kzalloc(sizeof(*bss_desc), GFP_KERNEL); + bss_desc = kzalloc_obj(*bss_desc); if (!bss_desc) return -ENOMEM; @@ -1693,7 +1691,7 @@ static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv, int ret; /* Allocate and fill new bss descriptor */ - bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL); + bss_desc = kzalloc_obj(struct mwifiex_bssdescriptor); if (!bss_desc) return -ENOMEM; @@ -1932,7 +1930,7 @@ mwifiex_active_scan_req_for_passive_chan(struct mwifiex_private *priv) mwifiex_dbg(adapter, INFO, "No BSS with hidden SSID found on DFS channels\n"); return 0; } - user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL); + user_scan_cfg = kzalloc_obj(*user_scan_cfg); if (!user_scan_cfg) return -ENOMEM; @@ -2174,9 +2172,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, if (nd_config) { adapter->nd_info = - kzalloc(struct_size(adapter->nd_info, matches, - scan_rsp->number_of_sets), - GFP_ATOMIC); + kzalloc_flex(*adapter->nd_info, matches, + scan_rsp->number_of_sets, GFP_ATOMIC); if (adapter->nd_info) adapter->nd_info->n_matches = scan_rsp->number_of_sets; @@ -2452,7 +2449,7 @@ int mwifiex_stop_bg_scan(struct mwifiex_private *priv) return 0; } - bgscan_cfg = kzalloc(sizeof(*bgscan_cfg), GFP_KERNEL); + bgscan_cfg = kzalloc_obj(*bgscan_cfg); if (!bgscan_cfg) return -ENOMEM; @@ -2779,7 +2776,7 @@ static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv, return -EBUSY; } - scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL); + scan_cfg = kzalloc_obj(struct mwifiex_user_scan_cfg); if (!scan_cfg) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index dcca71158fc6..70ce31d7c76e 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -1516,7 +1516,7 @@ int mwifiex_send_rgpower_table(struct mwifiex_private *priv, const u8 *data, struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_ds_misc_cmd *hostcmd __free(kfree) = NULL; - hostcmd = kzalloc(sizeof(*hostcmd), GFP_KERNEL); + hostcmd = kzalloc_obj(*hostcmd); if (!hostcmd) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index 9c53825f222d..85512f526c5f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -1052,7 +1052,7 @@ mwifiex_create_custom_regdomain(struct mwifiex_private *priv, if (WARN_ON_ONCE(num_chan > NL80211_MAX_SUPP_REG_RULES)) return ERR_PTR(-EINVAL); - regd = kzalloc(struct_size(regd, reg_rules, num_chan), GFP_KERNEL); + regd = kzalloc_flex(*regd, reg_rules, num_chan); if (!regd) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index ef6722ffdc74..a6550548d3b4 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -330,8 +330,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, return -EINVAL; /* Allocate and fill new bss descriptor */ - bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), - GFP_KERNEL); + bss_desc = kzalloc_obj(struct mwifiex_bssdescriptor); if (!bss_desc) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/tdls.c b/drivers/net/wireless/marvell/mwifiex/tdls.c index 77a9a6de636d..a4cf323e704b 100644 --- a/drivers/net/wireless/marvell/mwifiex/tdls.c +++ b/drivers/net/wireless/marvell/mwifiex/tdls.c @@ -1356,7 +1356,7 @@ void mwifiex_add_auto_tdls_peer(struct mwifiex_private *priv, const u8 *mac) } /* create new TDLS peer */ - tdls_peer = kzalloc(sizeof(*tdls_peer), GFP_ATOMIC); + tdls_peer = kzalloc_obj(*tdls_peer, GFP_ATOMIC); if (tdls_peer) { ether_addr_copy(tdls_peer->mac_addr, mac); tdls_peer->tdls_status = TDLS_SETUP_INPROGRESS; diff --git a/drivers/net/wireless/marvell/mwifiex/uap_event.c b/drivers/net/wireless/marvell/mwifiex/uap_event.c index 245cb99a3daa..703104fd1fbe 100644 --- a/drivers/net/wireless/marvell/mwifiex/uap_event.c +++ b/drivers/net/wireless/marvell/mwifiex/uap_event.c @@ -105,7 +105,7 @@ int mwifiex_process_uap_event(struct mwifiex_private *priv) switch (eventcause) { case EVENT_UAP_STA_ASSOC: - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return -ENOMEM; diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c index 6882e90e90b2..7d3631d21223 100644 --- a/drivers/net/wireless/marvell/mwifiex/util.c +++ b/drivers/net/wireless/marvell/mwifiex/util.c @@ -694,7 +694,7 @@ mwifiex_add_sta_entry(struct mwifiex_private *priv, const u8 *mac) if (node) goto done; - node = kzalloc(sizeof(*node), GFP_ATOMIC); + node = kzalloc_obj(*node, GFP_ATOMIC); if (!node) goto done; diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c index 1b1222c73728..841505e83c7f 100644 --- a/drivers/net/wireless/marvell/mwifiex/wmm.c +++ b/drivers/net/wireless/marvell/mwifiex/wmm.c @@ -99,7 +99,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, const u8 *ra) { struct mwifiex_ra_list_tbl *ra_list; - ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC); + ra_list = kzalloc_obj(struct mwifiex_ra_list_tbl, GFP_ATOMIC); if (!ra_list) return NULL; diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c index 54d6d00ecdf1..99321d180f34 100644 --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c @@ -1182,7 +1182,7 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) return -ENOMEM; } - rxq->buf = kcalloc(MWL8K_RX_DESCS, sizeof(*rxq->buf), GFP_KERNEL); + rxq->buf = kzalloc_objs(*rxq->buf, MWL8K_RX_DESCS); if (rxq->buf == NULL) { dma_free_coherent(&priv->pdev->dev, size, rxq->rxd, rxq->rxd_dma); @@ -1478,7 +1478,7 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) return -ENOMEM; } - txq->skb = kcalloc(MWL8K_TX_DESCS, sizeof(*txq->skb), GFP_KERNEL); + txq->skb = kzalloc_objs(*txq->skb, MWL8K_TX_DESCS); if (txq->skb == NULL) { dma_free_coherent(&priv->pdev->dev, size, txq->txd, txq->txd_dma); @@ -2472,7 +2472,7 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) int rc; int i; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2537,7 +2537,7 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw) int rc, i; u32 api_version; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2639,7 +2639,7 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) int rc; int i; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2753,7 +2753,7 @@ static int mwl8k_cmd_get_stat(struct ieee80211_hw *hw, struct mwl8k_cmd_get_stat *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2796,7 +2796,7 @@ mwl8k_cmd_radio_control(struct ieee80211_hw *hw, bool enable, bool force) if (enable == priv->radio_on && !force) return 0; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2854,7 +2854,7 @@ static int mwl8k_cmd_rf_tx_power(struct ieee80211_hw *hw, int dBm) struct mwl8k_cmd_rf_tx_power *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2895,7 +2895,7 @@ static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw, int rc; int i; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -2948,7 +2948,7 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask) struct mwl8k_cmd_rf_antenna *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3066,7 +3066,7 @@ static int mwl8k_cmd_set_pre_scan(struct ieee80211_hw *hw) struct mwl8k_cmd_set_pre_scan *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3099,7 +3099,7 @@ mwl8k_cmd_bbp_reg_access(struct ieee80211_hw *hw, struct mwl8k_cmd_bbp_reg_access *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3135,7 +3135,7 @@ mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac) struct mwl8k_cmd_set_post_scan *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3228,7 +3228,7 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, struct mwl8k_priv *priv = hw->priv; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3314,7 +3314,7 @@ mwl8k_cmd_set_aid(struct ieee80211_hw *hw, u16 prot_mode; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3368,7 +3368,7 @@ mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct mwl8k_cmd_set_rate *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3402,7 +3402,7 @@ static int mwl8k_cmd_finalize_join(struct ieee80211_hw *hw, void *frame, int payload_len; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3440,7 +3440,7 @@ mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int radio_idx, struct mwl8k_cmd_set_rts_threshold *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3469,7 +3469,7 @@ static int mwl8k_cmd_set_slot(struct ieee80211_hw *hw, bool short_slot_time) struct mwl8k_cmd_set_slot *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3543,7 +3543,7 @@ mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum, struct mwl8k_cmd_set_edca_params *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3583,7 +3583,7 @@ static int mwl8k_cmd_set_wmm_mode(struct ieee80211_hw *hw, bool enable) struct mwl8k_cmd_set_wmm_mode *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3615,7 +3615,7 @@ static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx) struct mwl8k_cmd_mimo_config *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3658,7 +3658,7 @@ static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw) struct mwl8k_cmd_use_fixed_rate_sta *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3698,7 +3698,7 @@ mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt) struct mwl8k_cmd_use_fixed_rate_ap *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3727,7 +3727,7 @@ static int mwl8k_cmd_enable_sniffer(struct ieee80211_hw *hw, bool enable) struct mwl8k_cmd_enable_sniffer *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3782,7 +3782,7 @@ static int mwl8k_cmd_update_mac_addr(struct ieee80211_hw *hw, mac_type = MWL8K_MAC_TYPE_SECONDARY_AP; } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3837,7 +3837,7 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode) struct mwl8k_cmd_set_rate_adapt_mode *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3865,7 +3865,7 @@ static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap) struct mwl8k_cmd_get_watchdog_bitmap *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -3954,7 +3954,7 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, if (!enable && !(priv->running_bsses & (1 << mwl8k_vif->macid))) return 0; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4046,7 +4046,7 @@ mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, struct mwl8k_cmd_bastream *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4078,7 +4078,7 @@ mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream, struct mwl8k_cmd_bastream *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4121,7 +4121,7 @@ static void mwl8k_destroy_ba(struct ieee80211_hw *hw, { struct mwl8k_cmd_bastream *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return; @@ -4173,7 +4173,7 @@ static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw, u32 rates; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4211,7 +4211,7 @@ static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw, struct mwl8k_cmd_set_new_stn *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4254,7 +4254,7 @@ static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw, spin_unlock(&priv->stream_lock); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4341,7 +4341,7 @@ static int mwl8k_cmd_update_encryption_enable(struct ieee80211_hw *hw, struct mwl8k_cmd_update_encryption *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4410,7 +4410,7 @@ static int mwl8k_cmd_encryption_set_key(struct ieee80211_hw *hw, u8 idx; struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4467,7 +4467,7 @@ static int mwl8k_cmd_encryption_remove_key(struct ieee80211_hw *hw, int rc; struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4604,7 +4604,7 @@ static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw, u32 rates; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; @@ -4643,7 +4643,7 @@ static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw, struct mwl8k_cmd_update_stadb *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (cmd == NULL) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/agg-rx.c b/drivers/net/wireless/mediatek/mt76/agg-rx.c index 3d34caf7e4f7..bf1babac3895 100644 --- a/drivers/net/wireless/mediatek/mt76/agg-rx.c +++ b/drivers/net/wireless/mediatek/mt76/agg-rx.c @@ -248,7 +248,7 @@ int mt76_rx_aggr_start(struct mt76_dev *dev, struct mt76_wcid *wcid, u8 tidno, mt76_rx_aggr_stop(dev, wcid, tidno); - tid = kzalloc(struct_size(tid, reorder_buf, size), GFP_KERNEL); + tid = kzalloc_flex(*tid, reorder_buf, size); if (!tid) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c index bd56cdb022a2..45992fdcec60 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c @@ -1055,7 +1055,7 @@ mt7615_mac_queue_rate_update(struct mt7615_phy *phy, struct mt7615_sta *sta, if (work_pending(&dev->rate_work)) return -EBUSY; - wrd = kzalloc(sizeof(*wrd), GFP_ATOMIC); + wrd = kzalloc_obj(*wrd, GFP_ATOMIC); if (!wrd) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c index 3304b5971be0..b41ca1410da9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mac.c @@ -413,6 +413,7 @@ mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, u32 val; if (ieee80211_is_action(fc) && + skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 + 1 + 2 && mgmt->u.action.category == WLAN_CATEGORY_BACK && mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c index 871b67101976..0d9435900423 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c @@ -668,6 +668,7 @@ mt7925_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi, u32 val; if (ieee80211_is_action(fc) && + skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && mgmt->u.action.category == WLAN_CATEGORY_BACK && mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) tid = MT_TX_ADDBA; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c index 2560e2f46e89..d4f3ee943b47 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c @@ -800,6 +800,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, u32 val; if (ieee80211_is_action(fc) && + skb->len >= IEEE80211_MIN_ACTION_SIZE + 1 && mgmt->u.action.category == WLAN_CATEGORY_BACK && mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) { if (is_mt7990(&dev->mt76)) diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index beed795edb24..f16135f0b7f9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -966,7 +966,7 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev, mtxq->wcid = idx; } } else { - msta_link = kzalloc(sizeof(*msta_link), GFP_KERNEL); + msta_link = kzalloc_obj(*msta_link); if (!msta_link) return -ENOMEM; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index 14a88ef79b6c..c0c042de477b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -726,7 +726,7 @@ mt7996_mcu_wed_rro_event(struct mt7996_dev *dev, struct sk_buff *skb) struct mt7996_wed_rro_session_id *session; e = (void *)skb->data; - session = kzalloc(sizeof(*session), GFP_ATOMIC); + session = kzalloc_obj(*session, GFP_ATOMIC); if (!session) break; diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c index c39e7f313ea1..1561a601c7f2 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c @@ -484,15 +484,13 @@ static int disconnect(struct wiphy *wiphy, struct net_device *dev, static int wilc_wfi_cfg_allocate_wpa_entry(struct wilc_priv *priv, u8 idx) { if (!priv->wilc_gtk[idx]) { - priv->wilc_gtk[idx] = kzalloc(sizeof(*priv->wilc_gtk[idx]), - GFP_KERNEL); + priv->wilc_gtk[idx] = kzalloc_obj(*priv->wilc_gtk[idx]); if (!priv->wilc_gtk[idx]) return -ENOMEM; } if (!priv->wilc_ptk[idx]) { - priv->wilc_ptk[idx] = kzalloc(sizeof(*priv->wilc_ptk[idx]), - GFP_KERNEL); + priv->wilc_ptk[idx] = kzalloc_obj(*priv->wilc_ptk[idx]); if (!priv->wilc_ptk[idx]) return -ENOMEM; } @@ -504,8 +502,7 @@ static int wilc_wfi_cfg_allocate_wpa_igtk_entry(struct wilc_priv *priv, u8 idx) { idx -= 4; if (!priv->wilc_igtk[idx]) { - priv->wilc_igtk[idx] = kzalloc(sizeof(*priv->wilc_igtk[idx]), - GFP_KERNEL); + priv->wilc_igtk[idx] = kzalloc_obj(*priv->wilc_igtk[idx]); if (!priv->wilc_igtk[idx]) return -ENOMEM; } @@ -1178,7 +1175,7 @@ static int mgmt_tx(struct wiphy *wiphy, if (!ieee80211_is_mgmt(mgmt->frame_control)) goto out; - mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_KERNEL); + mgmt_tx = kmalloc_obj(*mgmt_tx); if (!mgmt_tx) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c index a229c6cab332..f354b11cb919 100644 --- a/drivers/net/wireless/microchip/wilc1000/hif.c +++ b/drivers/net/wireless/microchip/wilc1000/hif.c @@ -60,7 +60,7 @@ wilc_alloc_work(struct wilc_vif *vif, void (*work_fun)(struct work_struct *), if (!work_fun) return ERR_PTR(-EINVAL); - msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + msg = kzalloc_obj(*msg, GFP_ATOMIC); if (!msg) return ERR_PTR(-ENOMEM); msg->fn = work_fun; @@ -387,7 +387,7 @@ wilc_parse_join_bss_param(struct cfg80211_bss *bss, u64 ies_tsf; int ret; - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) return NULL; @@ -1039,7 +1039,7 @@ int wilc_set_external_auth_param(struct wilc_vif *vif, wid.id = WID_EXTERNAL_AUTH_PARAM; wid.type = WID_BIN_DATA; wid.size = sizeof(*param); - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) return -EINVAL; @@ -1516,7 +1516,7 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler) struct host_if_drv *hif_drv; struct wilc_vif *vif = netdev_priv(dev); - hif_drv = kzalloc(sizeof(*hif_drv), GFP_KERNEL); + hif_drv = kzalloc_obj(*hif_drv); if (!hif_drv) return -ENOMEM; diff --git a/drivers/net/wireless/microchip/wilc1000/mon.c b/drivers/net/wireless/microchip/wilc1000/mon.c index c3d27aaec297..b5cf6fa7a851 100644 --- a/drivers/net/wireless/microchip/wilc1000/mon.c +++ b/drivers/net/wireless/microchip/wilc1000/mon.c @@ -120,7 +120,7 @@ static int mon_mgmt_tx(struct net_device *dev, const u8 *buf, size_t len) return -EFAULT; netif_stop_queue(dev); - mgmt_tx = kmalloc(sizeof(*mgmt_tx), GFP_ATOMIC); + mgmt_tx = kmalloc_obj(*mgmt_tx, GFP_ATOMIC); if (!mgmt_tx) return -ENOMEM; diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c index af298021e050..956cb578bf37 100644 --- a/drivers/net/wireless/microchip/wilc1000/netdev.c +++ b/drivers/net/wireless/microchip/wilc1000/netdev.c @@ -752,7 +752,7 @@ netdev_tx_t wilc_mac_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } - tx_data = kmalloc(sizeof(*tx_data), GFP_ATOMIC); + tx_data = kmalloc_obj(*tx_data, GFP_ATOMIC); if (!tx_data) { dev_kfree_skb(skb); netif_wake_queue(ndev); diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index af970f999111..67dea1360f0a 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -145,7 +145,7 @@ static int wilc_sdio_probe(struct sdio_func *func, int ret; - sdio_priv = kzalloc(sizeof(*sdio_priv), GFP_KERNEL); + sdio_priv = kzalloc_obj(*sdio_priv); if (!sdio_priv) return -ENOMEM; diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index 5bcabb7decea..e40b829f719d 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -211,7 +211,7 @@ static int wilc_bus_probe(struct spi_device *spi) struct wilc *wilc; int ret; - spi_priv = kzalloc(sizeof(*spi_priv), GFP_KERNEL); + spi_priv = kzalloc_obj(*spi_priv); if (!spi_priv) return -ENOMEM; diff --git a/drivers/net/wireless/microchip/wilc1000/wlan.c b/drivers/net/wireless/microchip/wilc1000/wlan.c index fedc7d59216a..3fa8592eb250 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan.c @@ -244,7 +244,7 @@ static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer, return 0; } - tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); + tqe = kmalloc_obj(*tqe, GFP_ATOMIC); if (!tqe) { complete(&wilc->cfg_event); return 0; @@ -413,7 +413,7 @@ int wilc_wlan_txq_add_net_pkt(struct net_device *dev, return 0; } - tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); + tqe = kmalloc_obj(*tqe, GFP_ATOMIC); if (!tqe) { tx_complete_fn(tx_data, 0); @@ -466,7 +466,7 @@ int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer, tx_complete_fn(priv, 0); return 0; } - tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC); + tqe = kmalloc_obj(*tqe, GFP_ATOMIC); if (!tqe) { tx_complete_fn(priv, 0); @@ -1209,7 +1209,7 @@ static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status) offset += size; wilc->rx_buffer_offset = offset; - rqe = kmalloc(sizeof(*rqe), GFP_KERNEL); + rqe = kmalloc_obj(*rqe); if (!rqe) return; diff --git a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c index cfabd5aebb54..7664403c8d50 100644 --- a/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c +++ b/drivers/net/wireless/microchip/wilc1000/wlan_cfg.c @@ -390,7 +390,7 @@ int wilc_wlan_cfg_init(struct wilc *wl) if (!wl->cfg.s) goto out_w; - str_vals = kzalloc(sizeof(*str_vals), GFP_KERNEL); + str_vals = kzalloc_obj(*str_vals); if (!str_vals) goto out_s; diff --git a/drivers/net/wireless/purelifi/plfxlc/usb.c b/drivers/net/wireless/purelifi/plfxlc/usb.c index 711902a809db..5724ec173e64 100644 --- a/drivers/net/wireless/purelifi/plfxlc/usb.c +++ b/drivers/net/wireless/purelifi/plfxlc/usb.c @@ -204,7 +204,7 @@ static int __lf_x_usb_enable_rx(struct plfxlc_usb *usb) int i, r; r = -ENOMEM; - urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); + urbs = kzalloc_objs(struct urb *, RX_URBS_COUNT); if (!urbs) goto error; diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index 956c5763662f..d9c4dd6beaec 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -981,7 +981,7 @@ qtnf_parse_wowlan_info(struct qtnf_wmac *mac, const struct qlink_wowlan_support *data1; struct wiphy_wowlan_support *supp; - supp = kzalloc(sizeof(*supp), GFP_KERNEL); + supp = kzalloc_obj(*supp); if (!supp) return; @@ -1031,8 +1031,7 @@ qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) return -E2BIG; - mac->rd = kzalloc(struct_size(mac->rd, reg_rules, resp->n_reg_rules), - GFP_KERNEL); + mac->rd = kzalloc_flex(*mac->rd, reg_rules, resp->n_reg_rules); if (!mac->rd) return -ENOMEM; @@ -1084,8 +1083,7 @@ qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, return -EINVAL; } - limits = kcalloc(rec->n_limits, sizeof(*limits), - GFP_KERNEL); + limits = kzalloc_objs(*limits, rec->n_limits); if (!limits) return -ENOMEM; @@ -1254,9 +1252,8 @@ qtnf_cmd_resp_proc_mac_info(struct qtnf_wmac *mac, sizeof(mac_info->vht_cap_mod_mask)); mac_info->n_if_comb = resp_info->n_iface_combinations; - mac_info->if_comb = kcalloc(mac->macinfo.n_if_comb, - sizeof(*mac->macinfo.if_comb), - GFP_KERNEL); + mac_info->if_comb = kzalloc_objs(*mac->macinfo.if_comb, + mac->macinfo.n_if_comb); if (!mac->macinfo.if_comb) return -ENOMEM; @@ -1341,8 +1338,7 @@ static int qtnf_cmd_band_fill_iftype(const u8 *data, if (band->n_iftype_data == 0) return 0; - iftype_data = kcalloc(band->n_iftype_data, sizeof(*iftype_data), - GFP_KERNEL); + iftype_data = kzalloc_objs(*iftype_data, band->n_iftype_data); if (!iftype_data) { band->n_iftype_data = 0; return -ENOMEM; @@ -1389,8 +1385,7 @@ qtnf_cmd_resp_fill_band_info(struct ieee80211_supported_band *band, return 0; if (!band->channels) - band->channels = kcalloc(band->n_channels, sizeof(*chan), - GFP_KERNEL); + band->channels = kzalloc_objs(*chan, band->n_channels); if (!band->channels) { band->n_channels = 0; return -ENOMEM; diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index 38af6cdc2843..0c106709ae29 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -212,7 +212,7 @@ static int qtnf_mac_init_single_band(struct wiphy *wiphy, { int ret; - wiphy->bands[band] = kzalloc(sizeof(*wiphy->bands[band]), GFP_KERNEL); + wiphy->bands[band] = kzalloc_obj(*wiphy->bands[band]); if (!wiphy->bands[band]) return -ENOMEM; diff --git a/drivers/net/wireless/quantenna/qtnfmac/event.c b/drivers/net/wireless/quantenna/qtnfmac/event.c index 71840f41b73c..2551d74ed56e 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/event.c +++ b/drivers/net/wireless/quantenna/qtnfmac/event.c @@ -41,7 +41,7 @@ qtnf_event_handle_sta_assoc(struct qtnf_wmac *mac, struct qtnf_vif *vif, return -EPROTO; } - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (!sinfo) return -ENOMEM; diff --git a/drivers/net/wireless/quantenna/qtnfmac/util.c b/drivers/net/wireless/quantenna/qtnfmac/util.c index cda6f5f3f38a..4ad66cc1804d 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/util.c +++ b/drivers/net/wireless/quantenna/qtnfmac/util.c @@ -59,7 +59,7 @@ struct qtnf_sta_node *qtnf_sta_list_add(struct qtnf_vif *vif, if (node) goto done; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (unlikely(!node)) goto done; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c index 42e21e9f303b..cac191304bf5 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c @@ -1589,7 +1589,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c index 36ddc5a69fa4..fc35b60e422c 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c @@ -1907,7 +1907,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c index 09923765e2db..58728df6666c 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c @@ -1720,7 +1720,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 65d0f805459c..ca18a4c7e14a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -11907,13 +11907,12 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information and survey arrays */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; rt2x00dev->chan_survey = - kcalloc(spec->num_channels, sizeof(struct rt2x00_chan_survey), - GFP_KERNEL); + kzalloc_objs(struct rt2x00_chan_survey, spec->num_channels); if (!rt2x00dev->chan_survey) { kfree(info); return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c index b51a23300ba2..15de3db12429 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c @@ -179,7 +179,7 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev) u32 fw_mode; int ret; - reg = kmalloc(sizeof(*reg), GFP_KERNEL); + reg = kmalloc_obj(*reg); if (reg == NULL) return -ENOMEM; /* cannot use rt2x00usb_register_read here as it uses different diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c index f2395309ec00..e0bca06c7094 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c @@ -639,7 +639,7 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev) struct dentry *queue_folder; struct dentry *register_folder; - intf = kzalloc(sizeof(struct rt2x00debug_intf), GFP_KERNEL); + intf = kzalloc_obj(struct rt2x00debug_intf); if (!intf) { rt2x00_err(rt2x00dev, "Failed to allocate debug handler\n"); return; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c index 778a478ab53a..82fb230a73bb 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c @@ -1020,11 +1020,11 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev, if (spec->supported_rates & SUPPORT_RATE_OFDM) num_rates += 8; - channels = kcalloc(spec->num_channels, sizeof(*channels), GFP_KERNEL); + channels = kzalloc_objs(*channels, spec->num_channels); if (!channels) return -ENOMEM; - rates = kcalloc(num_rates, sizeof(*rates), GFP_KERNEL); + rates = kzalloc_objs(*rates, num_rates); if (!rates) goto exit_free_channels; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c index 13e48b1e7356..4b842497653c 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c @@ -564,7 +564,7 @@ static void rt2x00queue_bar_check(struct queue_entry *entry) if (likely(!ieee80211_is_back_req(bar->frame_control))) return; - bar_entry = kmalloc(sizeof(*bar_entry), GFP_ATOMIC); + bar_entry = kmalloc_obj(*bar_entry, GFP_ATOMIC); /* * If the alloc fails we still send the BAR out but just don't track @@ -1244,7 +1244,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) */ rt2x00dev->data_queues = 2 + rt2x00dev->ops->tx_queues + req_atim; - queue = kcalloc(rt2x00dev->data_queues, sizeof(*queue), GFP_KERNEL); + queue = kzalloc_objs(*queue, rt2x00dev->data_queues); if (!queue) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c index a6d50149e0c3..54599cad78f9 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c @@ -196,7 +196,7 @@ void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev, struct urb *urb; struct rt2x00_async_read_data *rd; - rd = kmalloc(sizeof(*rd), GFP_ATOMIC); + rd = kmalloc_obj(*rd, GFP_ATOMIC); if (!rd) return; diff --git a/drivers/net/wireless/ralink/rt2x00/rt61pci.c b/drivers/net/wireless/ralink/rt2x00/rt61pci.c index d1cd5694e3c7..79e1fd0a1fbd 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c +++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c @@ -2712,7 +2712,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/ralink/rt2x00/rt73usb.c b/drivers/net/wireless/ralink/rt2x00/rt73usb.c index b79dda952a33..d6b7174d087a 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c @@ -2136,7 +2136,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) /* * Create channel information array */ - info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, spec->num_channels); if (!info) return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c index 7aa2da0cd63c..f7e0f6573180 100644 --- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c @@ -129,7 +129,7 @@ static void rtl8187_iowrite_async(struct rtl8187_priv *priv, __le16 addr, } *buf; int rc; - buf = kmalloc(sizeof(*buf), GFP_ATOMIC); + buf = kmalloc_obj(*buf, GFP_ATOMIC); if (!buf) return; @@ -1463,7 +1463,7 @@ static int rtl8187_probe(struct usb_interface *intf, priv->is_rtl8187b = (id->driver_info == DEVICE_RTL8187B); /* allocate "DMA aware" buffer for register accesses */ - priv->io_dmabuf = kmalloc(sizeof(*priv->io_dmabuf), GFP_KERNEL); + priv->io_dmabuf = kmalloc_obj(*priv->io_dmabuf); if (!priv->io_dmabuf) { err = -ENOMEM; goto err_free_dev; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/core.c b/drivers/net/wireless/realtek/rtl8xxxu/core.c index f9a527f6a175..794187d28caa 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/core.c @@ -7323,7 +7323,7 @@ static void rtl8xxxu_collect_sta_iter(void *data, struct ieee80211_sta *sta) struct rtl8xxxu_iter_stas_data *iter_stas = data; struct rtl8xxxu_stas_entry *stas_entry; - stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC); + stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC); if (!stas_entry) return; @@ -7381,7 +7381,7 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw) } for (i = 0; i < RTL8XXXU_TX_URBS; i++) { - tx_urb = kmalloc(sizeof(struct rtl8xxxu_tx_urb), GFP_KERNEL); + tx_urb = kmalloc_obj(struct rtl8xxxu_tx_urb); if (!tx_urb) { if (!i) ret = -ENOMEM; @@ -7402,7 +7402,7 @@ static int rtl8xxxu_start(struct ieee80211_hw *hw) spin_unlock_irqrestore(&priv->rx_urb_lock, flags); for (i = 0; i < RTL8XXXU_RX_URBS; i++) { - rx_urb = kmalloc(sizeof(struct rtl8xxxu_rx_urb), GFP_KERNEL); + rx_urb = kmalloc_obj(struct rtl8xxxu_rx_urb); if (!rx_urb) { if (!i) ret = -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 09e5a16d7252..0ac9cf0937aa 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -2011,7 +2011,7 @@ void rtl_collect_scan_list(struct ieee80211_hw *hw, struct sk_buff *skb) } if (!entry) { - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) goto label_err; diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c index e88d92d3ae7a..bcd8bc270180 100644 --- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c +++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c @@ -132,10 +132,10 @@ static void rtl_btc_alloc_variable(struct rtl_priv *rtlpriv, bool wifi_only) { if (wifi_only) rtlpriv->btcoexist.wifi_only_context = - kzalloc(sizeof(struct wifi_only_cfg), GFP_KERNEL); + kzalloc_obj(struct wifi_only_cfg); else rtlpriv->btcoexist.btc_context = - kzalloc(sizeof(struct btc_coexist), GFP_KERNEL); + kzalloc_obj(struct btc_coexist); } static void rtl_btc_free_variable(struct rtl_priv *rtlpriv) diff --git a/drivers/net/wireless/realtek/rtlwifi/rc.c b/drivers/net/wireless/realtek/rtlwifi/rc.c index a164364109ba..dcfaa98198b6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rc.c +++ b/drivers/net/wireless/realtek/rtlwifi/rc.c @@ -278,7 +278,7 @@ static void *rtl_rate_alloc_sta(void *ppriv, struct rtl_priv *rtlpriv = ppriv; struct rtl_rate_priv *rate_priv; - rate_priv = kzalloc(sizeof(*rate_priv), gfp); + rate_priv = kzalloc_obj(*rate_priv, gfp); if (!rate_priv) return NULL; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c index cc699efa9c79..7bafb051d5ec 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192du/sw.c @@ -70,10 +70,8 @@ static int rtl92du_init_shared_data(struct ieee80211_hw *hw) rtlpriv->curveindex_5g = kcalloc(TARGET_CHNL_NUM_5G, sizeof(*rtlpriv->curveindex_5g), GFP_KERNEL); - rtlpriv->mutex_for_power_on_off = - kzalloc(sizeof(*rtlpriv->mutex_for_power_on_off), GFP_KERNEL); - rtlpriv->mutex_for_hw_init = - kzalloc(sizeof(*rtlpriv->mutex_for_hw_init), GFP_KERNEL); + rtlpriv->mutex_for_power_on_off = kzalloc_obj(*rtlpriv->mutex_for_power_on_off); + rtlpriv->mutex_for_hw_init = kzalloc_obj(*rtlpriv->mutex_for_hw_init); if (!rtlpriv->curveindex_2g || !rtlpriv->curveindex_5g || !rtlpriv->mutex_for_power_on_off || !rtlpriv->mutex_for_hw_init) { diff --git a/drivers/net/wireless/realtek/rtw88/fw.c b/drivers/net/wireless/realtek/rtw88/fw.c index c68a9fff6808..48207052e3f8 100644 --- a/drivers/net/wireless/realtek/rtw88/fw.c +++ b/drivers/net/wireless/realtek/rtw88/fw.c @@ -1331,7 +1331,7 @@ static struct rtw_rsvd_page *rtw_alloc_rsvd_page(struct rtw_dev *rtwdev, { struct rtw_rsvd_page *rsvd_pkt = NULL; - rsvd_pkt = kzalloc(sizeof(*rsvd_pkt), GFP_KERNEL); + rsvd_pkt = kzalloc_obj(*rsvd_pkt); if (!rsvd_pkt) return NULL; diff --git a/drivers/net/wireless/realtek/rtw88/sdio.c b/drivers/net/wireless/realtek/rtw88/sdio.c index 138e9e348c6c..1318e94f8524 100644 --- a/drivers/net/wireless/realtek/rtw88/sdio.c +++ b/drivers/net/wireless/realtek/rtw88/sdio.c @@ -1290,8 +1290,7 @@ static int rtw_sdio_init_tx(struct rtw_dev *rtwdev) for (i = 0; i < RTK_MAX_TX_QUEUE_NUM; i++) skb_queue_head_init(&rtwsdio->tx_queue[i]); - rtwsdio->tx_handler_data = kmalloc(sizeof(*rtwsdio->tx_handler_data), - GFP_KERNEL); + rtwsdio->tx_handler_data = kmalloc_obj(*rtwsdio->tx_handler_data); if (!rtwsdio->tx_handler_data) goto err_destroy_wq; diff --git a/drivers/net/wireless/realtek/rtw88/usb.c b/drivers/net/wireless/realtek/rtw88/usb.c index db60e142268d..433b06c8d8a6 100644 --- a/drivers/net/wireless/realtek/rtw88/usb.c +++ b/drivers/net/wireless/realtek/rtw88/usb.c @@ -403,7 +403,7 @@ static bool rtw_usb_tx_agg_skb(struct rtw_usb *rtwusb, struct sk_buff_head *list if (skb_queue_empty(list)) return false; - txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC); + txcb = kmalloc_obj(*txcb, GFP_ATOMIC); if (!txcb) return false; diff --git a/drivers/net/wireless/realtek/rtw88/util.c b/drivers/net/wireless/realtek/rtw88/util.c index 66819f694405..fcd6eb1ab32a 100644 --- a/drivers/net/wireless/realtek/rtw88/util.c +++ b/drivers/net/wireless/realtek/rtw88/util.c @@ -122,7 +122,7 @@ static void rtw_collect_sta_iter(void *data, struct ieee80211_sta *sta) struct rtw_iter_stas_data *iter_stas = data; struct rtw_stas_entry *stas_entry; - stas_entry = kmalloc(sizeof(*stas_entry), GFP_ATOMIC); + stas_entry = kmalloc_obj(*stas_entry, GFP_ATOMIC); if (!stas_entry) return; @@ -172,7 +172,7 @@ static void rtw_collect_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) struct rtw_iter_vifs_data *iter_stas = data; struct rtw_vifs_entry *vifs_entry; - vifs_entry = kmalloc(sizeof(*vifs_entry), GFP_ATOMIC); + vifs_entry = kmalloc_obj(*vifs_entry, GFP_ATOMIC); if (!vifs_entry) return; diff --git a/drivers/net/wireless/realtek/rtw89/acpi.c b/drivers/net/wireless/realtek/rtw89/acpi.c index f1e758a5f32b..ebb6cf555747 100644 --- a/drivers/net/wireless/realtek/rtw89/acpi.c +++ b/drivers/net/wireless/realtek/rtw89/acpi.c @@ -115,7 +115,7 @@ rtw89_acpi_evaluate_method(struct rtw89_dev *rtwdev, const char *method) goto out; } - data = kzalloc(struct_size(data, buf, len), GFP_KERNEL); + data = kzalloc_flex(*data, buf, len); if (!data) goto out; diff --git a/drivers/net/wireless/realtek/rtw89/cam.c b/drivers/net/wireless/realtek/rtw89/cam.c index 9f63d67777fa..7c62ece137d0 100644 --- a/drivers/net/wireless/realtek/rtw89/cam.c +++ b/drivers/net/wireless/realtek/rtw89/cam.c @@ -420,7 +420,7 @@ static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev, return ret; } - sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL); + sec_cam = kzalloc_obj(*sec_cam); if (!sec_cam) { ret = -ENOMEM; goto err_release_cam; diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index 6e77522bcd8f..36e988277b2b 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -4220,7 +4220,7 @@ int rtw89_core_send_nullfunc(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rt if (vif->type != NL80211_IFTYPE_STATION || !vif->cfg.assoc) return 0; - wait = kzalloc(sizeof(*wait), GFP_KERNEL); + wait = kzalloc_obj(*wait); if (!wait) return -ENOMEM; @@ -5657,7 +5657,7 @@ rtw89_wait_for_cond_prep(struct rtw89_wait_info *wait, unsigned int cond) if (cur != RTW89_WAIT_COND_IDLE) return ERR_PTR(-EPERM); - prep = kzalloc(sizeof(*prep), GFP_KERNEL); + prep = kzalloc_obj(*prep); if (!prep) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 06a9504d2bad..012ead92f5f2 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -3524,7 +3524,7 @@ rtw89_debug_priv_early_h2c_set(struct rtw89_dev *rtwdev, goto out; } - early_h2c = kmalloc(sizeof(*early_h2c), GFP_KERNEL); + early_h2c = kmalloc_obj(*early_h2c); if (!early_h2c) { kfree(h2c); return -EFAULT; diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index f84726f04669..c52f9e11a8b2 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1099,12 +1099,12 @@ int rtw89_build_phy_tbl_from_elm(struct rtw89_dev *rtwdev, else if (*pp) return 1; /* ignore if an element is existing */ - tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kzalloc_obj(*tbl); if (!tbl) return -ENOMEM; n_regs = le32_to_cpu(elm->size) / sizeof(tbl->regs[0]); - regs = kcalloc(n_regs, sizeof(*regs), GFP_KERNEL); + regs = kzalloc_objs(*regs, n_regs); if (!regs) goto out; @@ -1141,7 +1141,7 @@ int rtw89_fw_recognize_txpwr_from_elm(struct rtw89_dev *rtwdev, struct rtw89_txpwr_conf *conf; if (!rtwdev->rfe_data) { - rtwdev->rfe_data = kzalloc(sizeof(*rtwdev->rfe_data), GFP_KERNEL); + rtwdev->rfe_data = kzalloc_obj(*rtwdev->rfe_data); if (!rtwdev->rfe_data) return -ENOMEM; } @@ -1201,7 +1201,7 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, return -ENOENT; } - elm_info->txpwr_trk = kzalloc(sizeof(*elm_info->txpwr_trk), GFP_KERNEL); + elm_info->txpwr_trk = kzalloc_obj(*elm_info->txpwr_trk); if (!elm_info->txpwr_trk) return -ENOMEM; @@ -1250,7 +1250,7 @@ int rtw89_build_rfk_log_fmt_from_elm(struct rtw89_dev *rtwdev, if (elm_info->rfk_log_fmt) goto allocated; - elm_info->rfk_log_fmt = kzalloc(sizeof(*elm_info->rfk_log_fmt), GFP_KERNEL); + elm_info->rfk_log_fmt = kzalloc_obj(*elm_info->rfk_log_fmt); if (!elm_info->rfk_log_fmt) return 1; /* this is an optional element, so just ignore this */ @@ -2944,7 +2944,7 @@ static int rtw89_fw_h2c_add_general_pkt(struct rtw89_dev *rtwdev, struct sk_buff *skb; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -8138,7 +8138,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, skb_put_data(new, ies->ies[band], ies->len[band]); skb_put_data(new, ies->common_ies, ies->common_ie_len); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { ret = -ENOMEM; kfree_skb(new); @@ -8234,7 +8234,7 @@ static int rtw89_update_6ghz_rnr_chan_ax(struct rtw89_dev *rtwdev, hdr = (struct ieee80211_hdr *)skb->data; ether_addr_copy(hdr->addr3, params->bssid); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { ret = -ENOMEM; kfree_skb(skb); @@ -8527,7 +8527,7 @@ int rtw89_pno_scan_add_chan_list_ax(struct rtw89_dev *rtwdev, idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_AX; idx++, list_len++) { channel = nd_config->channels[idx]; - ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); + ch_info = kzalloc_obj(*ch_info); if (!ch_info) { ret = -ENOMEM; goto out; @@ -8567,7 +8567,7 @@ static int rtw89_hw_scan_add_op_types_ax(struct rtw89_dev *rtwdev, { struct rtw89_mac_chinfo_ax *tmp; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -8613,7 +8613,7 @@ int rtw89_hw_scan_prep_chan_list_ax(struct rtw89_dev *rtwdev, for (idx = 0; idx < req->n_channels; idx++) { channel = req->channels[idx]; - ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); + ch_info = kzalloc_obj(*ch_info); if (!ch_info) { ret = -ENOMEM; goto out; @@ -8745,7 +8745,7 @@ int rtw89_pno_scan_add_chan_list_be(struct rtw89_dev *rtwdev, idx < nd_config->n_channels && list_len < RTW89_SCAN_LIST_LIMIT_BE; idx++, list_len++) { channel = nd_config->channels[idx]; - ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); + ch_info = kzalloc_obj(*ch_info); if (!ch_info) { ret = -ENOMEM; goto out; @@ -8807,7 +8807,7 @@ int rtw89_hw_scan_prep_chan_list_be(struct rtw89_dev *rtwdev, !cfg80211_channel_is_psc(channel) && chan_by_rnr) continue; - ch_info = kzalloc(sizeof(*ch_info), GFP_KERNEL); + ch_info = kzalloc_obj(*ch_info); if (!ch_info) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 315bb0d0759f..0ea33743853e 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -1666,7 +1666,7 @@ int rtw89_ops_change_vif_links(struct ieee80211_hw *hw, return -EOPNOTSUPP; if (removing_links) { - snap = kzalloc(sizeof(*snap), GFP_KERNEL); + snap = kzalloc_obj(*snap); if (!snap) return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtw89/phy.c b/drivers/net/wireless/realtek/rtw89/phy.c index 6c6d5f1da867..ee6ab2136b9a 100644 --- a/drivers/net/wireless/realtek/rtw89/phy.c +++ b/drivers/net/wireless/realtek/rtw89/phy.c @@ -1975,7 +1975,7 @@ void rtw89_phy_init_rf_reg(struct rtw89_dev *rtwdev, bool noio) struct rtw89_fw_h2c_rf_reg_info *rf_reg_info; u8 path; - rf_reg_info = kzalloc(sizeof(*rf_reg_info), GFP_KERNEL); + rf_reg_info = kzalloc_obj(*rf_reg_info); if (!rf_reg_info) return; diff --git a/drivers/net/wireless/realtek/rtw89/sar.c b/drivers/net/wireless/realtek/rtw89/sar.c index ef7feccccd5e..7886ffaf5695 100644 --- a/drivers/net/wireless/realtek/rtw89/sar.c +++ b/drivers/net/wireless/realtek/rtw89/sar.c @@ -501,7 +501,7 @@ static void rtw89_set_sar_from_acpi(struct rtw89_dev *rtwdev) struct rtw89_sar_cfg_acpi *cfg; int ret; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return; diff --git a/drivers/net/wireless/realtek/rtw89/ser.c b/drivers/net/wireless/realtek/rtw89/ser.c index 7fdc69578da3..f91e66133b30 100644 --- a/drivers/net/wireless/realtek/rtw89/ser.c +++ b/drivers/net/wireless/realtek/rtw89/ser.c @@ -210,7 +210,7 @@ static int ser_send_msg(struct rtw89_ser *ser, u8 event) if (test_bit(RTW89_SER_DRV_STOP_RUN, ser->flags)) return -EIO; - msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + msg = kmalloc_obj(*msg, GFP_ATOMIC); if (!msg) return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c index e77561a4d971..da1b7ce8089e 100644 --- a/drivers/net/wireless/realtek/rtw89/usb.c +++ b/drivers/net/wireless/realtek/rtw89/usb.c @@ -294,7 +294,7 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) if (!skb) break; - txcb = kmalloc(sizeof(*txcb), GFP_ATOMIC); + txcb = kmalloc_obj(*txcb, GFP_ATOMIC); if (!txcb) { rtw89_usb_tx_free_skb(rtwdev, txch, skb); continue; @@ -931,8 +931,7 @@ static int rtw89_usb_intf_init(struct rtw89_dev *rtwdev, if (ret) return ret; - rtwusb->vendor_req_buf = kmalloc(sizeof(*rtwusb->vendor_req_buf), - GFP_KERNEL); + rtwusb->vendor_req_buf = kmalloc_obj(*rtwusb->vendor_req_buf); if (!rtwusb->vendor_req_buf) return -ENOMEM; diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index b67ceda59e92..368e08826f1e 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1490,7 +1490,7 @@ static int rtw89_pno_scan_update_probe_req(struct rtw89_dev *rtwdev, skb_put_data(skb, basic_rate_ie, sizeof(basic_rate_ie)); skb_put_data(skb, nd_config->ie, nd_config->ie_len); - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { kfree_skb(skb); rtw89_fw_release_pno_pkt_list(rtwdev, rtwvif_link); diff --git a/drivers/net/wireless/rsi/rsi_91x_coex.c b/drivers/net/wireless/rsi/rsi_91x_coex.c index 372eaaa2b9ef..ee603a5173fb 100644 --- a/drivers/net/wireless/rsi/rsi_91x_coex.c +++ b/drivers/net/wireless/rsi/rsi_91x_coex.c @@ -140,7 +140,7 @@ int rsi_coex_attach(struct rsi_common *common) struct rsi_coex_ctrl_block *coex_cb; int cnt; - coex_cb = kzalloc(sizeof(*coex_cb), GFP_KERNEL); + coex_cb = kzalloc_obj(*coex_cb); if (!coex_cb) return -ENOMEM; diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c index c528e6ca2c8d..34836a200620 100644 --- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c +++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c @@ -285,7 +285,7 @@ int rsi_init_dbgfs(struct rsi_hw *adapter) int ii; const struct rsi_dbg_files *files; - dev_dbgfs = kzalloc(sizeof(*dev_dbgfs), GFP_KERNEL); + dev_dbgfs = kzalloc_obj(*dev_dbgfs); if (!dev_dbgfs) return -ENOMEM; diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c b/drivers/net/wireless/rsi/rsi_91x_hal.c index 7d26314a3e76..a0c36144eb0b 100644 --- a/drivers/net/wireless/rsi/rsi_91x_hal.c +++ b/drivers/net/wireless/rsi/rsi_91x_hal.c @@ -647,7 +647,7 @@ static int bl_write_header(struct rsi_hw *adapter, u8 *flash_content, u32 write_addr, write_len; int status; - bl_hdr = kzalloc(sizeof(*bl_hdr), GFP_KERNEL); + bl_hdr = kzalloc_obj(*bl_hdr); if (!bl_hdr) return -ENOMEM; diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 8c8e074a3a70..c7ae8031436a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -668,7 +668,7 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; struct ieee80211_conf *conf = &hw->conf; - int status = -EOPNOTSUPP; + int status = 0; mutex_lock(&common->mutex); diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c index a9bb37d5d581..662e42d1e5e8 100644 --- a/drivers/net/wireless/rsi/rsi_91x_main.c +++ b/drivers/net/wireless/rsi/rsi_91x_main.c @@ -304,11 +304,11 @@ struct rsi_hw *rsi_91x_init(u16 oper_mode) struct rsi_common *common = NULL; u8 ii = 0; - adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); + adapter = kzalloc_obj(*adapter); if (!adapter) return NULL; - adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL); + adapter->priv = kzalloc_obj(*common); if (adapter->priv == NULL) { rsi_dbg(ERR_ZONE, "%s: Failed in allocation of memory\n", __func__); diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index ee7ad81c858d..bfa386b820d8 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -828,7 +828,7 @@ static int rsi_init_sdio_interface(struct rsi_hw *adapter, struct rsi_91x_sdiodev *rsi_91x_dev; int status; - rsi_91x_dev = kzalloc(sizeof(*rsi_91x_dev), GFP_KERNEL); + rsi_91x_dev = kzalloc_obj(*rsi_91x_dev); if (!rsi_91x_dev) return -ENOMEM; diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index dccc139cabb2..d83204701e27 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -620,7 +620,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, struct rsi_91x_usbdev *rsi_dev; int status; - rsi_dev = kzalloc(sizeof(*rsi_dev), GFP_KERNEL); + rsi_dev = kzalloc_obj(*rsi_dev); if (!rsi_dev) return -ENOMEM; diff --git a/drivers/net/wireless/silabs/wfx/debug.c b/drivers/net/wireless/silabs/wfx/debug.c index e8265208f9a5..454ec59fdc50 100644 --- a/drivers/net/wireless/silabs/wfx/debug.c +++ b/drivers/net/wireless/silabs/wfx/debug.c @@ -291,7 +291,7 @@ static ssize_t wfx_send_hif_msg_read(struct file *file, char __user *user_buf, static int wfx_send_hif_msg_open(struct inode *inode, struct file *file) { - struct dbgfs_hif_msg *context = kzalloc(sizeof(*context), GFP_KERNEL); + struct dbgfs_hif_msg *context = kzalloc_obj(*context); if (!context) return -ENOMEM; diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c index 00c4731d8f8e..2b6afe221268 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -287,7 +287,7 @@ static int cw1200_sdio_probe(struct sdio_func *func, if (func->num != 0x01) return -ENODEV; - self = kzalloc(sizeof(*self), GFP_KERNEL); + self = kzalloc_obj(*self); if (!self) { pr_err("Can't allocate SDIO hwbus_priv.\n"); return -ENOMEM; diff --git a/drivers/net/wireless/st/cw1200/debug.c b/drivers/net/wireless/st/cw1200/debug.c index 8686929c70df..7dad6d3ba239 100644 --- a/drivers/net/wireless/st/cw1200/debug.c +++ b/drivers/net/wireless/st/cw1200/debug.c @@ -360,8 +360,7 @@ static const struct file_operations fops_wsm_dumps = { int cw1200_debug_init(struct cw1200_common *priv) { int ret = -ENOMEM; - struct cw1200_debug_priv *d = kzalloc(sizeof(struct cw1200_debug_priv), - GFP_KERNEL); + struct cw1200_debug_priv *d = kzalloc_obj(struct cw1200_debug_priv); priv->debug = d; if (!d) return ret; diff --git a/drivers/net/wireless/st/cw1200/pm.c b/drivers/net/wireless/st/cw1200/pm.c index 2002e3f9fe45..84eb15d729c7 100644 --- a/drivers/net/wireless/st/cw1200/pm.c +++ b/drivers/net/wireless/st/cw1200/pm.c @@ -207,7 +207,7 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) wsm_set_ether_type_filter(priv, &cw1200_ether_type_filter_on.hdr); /* Allocate state */ - state = kzalloc(sizeof(struct cw1200_suspend_state), GFP_KERNEL); + state = kzalloc_obj(struct cw1200_suspend_state); if (!state) goto revert3; @@ -264,12 +264,14 @@ int cw1200_wow_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) wiphy_err(priv->hw->wiphy, "PM request failed: %d. WoW is disabled.\n", ret); cw1200_wow_resume(hw); + mutex_unlock(&priv->conf_mutex); return -EBUSY; } /* Force resume if event is coming from the device. */ if (atomic_read(&priv->bh_rx)) { cw1200_wow_resume(hw); + mutex_unlock(&priv->conf_mutex); return -EAGAIN; } diff --git a/drivers/net/wireless/st/cw1200/queue.c b/drivers/net/wireless/st/cw1200/queue.c index a933e2c7dc2c..c2f2c118224c 100644 --- a/drivers/net/wireless/st/cw1200/queue.c +++ b/drivers/net/wireless/st/cw1200/queue.c @@ -153,8 +153,7 @@ int cw1200_queue_stats_init(struct cw1200_queue_stats *stats, spin_lock_init(&stats->lock); init_waitqueue_head(&stats->wait_link_id_empty); - stats->link_map_cache = kcalloc(map_capacity, sizeof(int), - GFP_KERNEL); + stats->link_map_cache = kzalloc_objs(int, map_capacity); if (!stats->link_map_cache) return -ENOMEM; @@ -180,13 +179,11 @@ int cw1200_queue_init(struct cw1200_queue *queue, spin_lock_init(&queue->lock); timer_setup(&queue->gc, cw1200_queue_gc, 0); - queue->pool = kcalloc(capacity, sizeof(struct cw1200_queue_item), - GFP_KERNEL); + queue->pool = kzalloc_objs(struct cw1200_queue_item, capacity); if (!queue->pool) return -ENOMEM; - queue->link_map_cache = kcalloc(stats->map_capacity, sizeof(int), - GFP_KERNEL); + queue->link_map_cache = kzalloc_objs(int, stats->map_capacity); if (!queue->link_map_cache) { kfree(queue->pool); queue->pool = NULL; diff --git a/drivers/net/wireless/st/cw1200/scan.c b/drivers/net/wireless/st/cw1200/scan.c index 1f856fbbc0ea..dc7b617837ef 100644 --- a/drivers/net/wireless/st/cw1200/scan.c +++ b/drivers/net/wireless/st/cw1200/scan.c @@ -225,9 +225,7 @@ void cw1200_scan_work(struct work_struct *work) scan.type = WSM_SCAN_TYPE_BACKGROUND; scan.flags = WSM_SCAN_FLAG_FORCE_BACKGROUND; } - scan.ch = kcalloc(it - priv->scan.curr, - sizeof(struct wsm_scan_ch), - GFP_KERNEL); + scan.ch = kzalloc_objs(struct wsm_scan_ch, it - priv->scan.curr); if (!scan.ch) { priv->scan.status = -ENOMEM; goto fail; diff --git a/drivers/net/wireless/st/cw1200/wsm.c b/drivers/net/wireless/st/cw1200/wsm.c index 4a9e4b5d3547..d6529e5b73b2 100644 --- a/drivers/net/wireless/st/cw1200/wsm.c +++ b/drivers/net/wireless/st/cw1200/wsm.c @@ -922,7 +922,7 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf) return 0; } - event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL); + event = kzalloc_obj(struct cw1200_wsm_event); if (!event) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/acx.c b/drivers/net/wireless/ti/wl1251/acx.c index 166efac812fe..bff73be2e6e8 100644 --- a/drivers/net/wireless/ti/wl1251/acx.c +++ b/drivers/net/wireless/ti/wl1251/acx.c @@ -18,7 +18,7 @@ int wl1251_acx_frame_rates(struct wl1251 *wl, u8 ctrl_rate, u8 ctrl_mod, wl1251_debug(DEBUG_ACX, "acx frame rates"); - rates = kzalloc(sizeof(*rates), GFP_KERNEL); + rates = kzalloc_obj(*rates); if (!rates) return -ENOMEM; @@ -47,7 +47,7 @@ int wl1251_acx_station_id(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx dot11_station_id"); - mac = kzalloc(sizeof(*mac), GFP_KERNEL); + mac = kzalloc_obj(*mac); if (!mac) return -ENOMEM; @@ -67,7 +67,7 @@ int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id) wl1251_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); - default_key = kzalloc(sizeof(*default_key), GFP_KERNEL); + default_key = kzalloc_obj(*default_key); if (!default_key) return -ENOMEM; @@ -95,7 +95,7 @@ int wl1251_acx_wake_up_conditions(struct wl1251 *wl, u8 wake_up_event, wl1251_debug(DEBUG_ACX, "acx wake up conditions"); - wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); + wake_up = kzalloc_obj(*wake_up); if (!wake_up) return -ENOMEM; @@ -121,7 +121,7 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth) wl1251_debug(DEBUG_ACX, "acx sleep auth"); - auth = kzalloc(sizeof(*auth), GFP_KERNEL); + auth = kzalloc_obj(*auth); if (!auth) return -ENOMEM; @@ -140,7 +140,7 @@ int wl1251_acx_fw_version(struct wl1251 *wl, char *buf, size_t len) wl1251_debug(DEBUG_ACX, "acx fw rev"); - rev = kzalloc(sizeof(*rev), GFP_KERNEL); + rev = kzalloc_obj(*rev); if (!rev) return -ENOMEM; @@ -167,7 +167,7 @@ int wl1251_acx_tx_power(struct wl1251 *wl, int power) if (power < 0 || power > 25) return -EINVAL; - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -191,7 +191,7 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl, u32 data_flow_options) wl1251_debug(DEBUG_ACX, "acx feature cfg"); - feature = kzalloc(sizeof(*feature), GFP_KERNEL); + feature = kzalloc_obj(*feature); if (!feature) return -ENOMEM; @@ -233,7 +233,7 @@ int wl1251_acx_data_path_params(struct wl1251 *wl, wl1251_debug(DEBUG_ACX, "acx data path params"); - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -279,7 +279,7 @@ int wl1251_acx_rx_msdu_life_time(struct wl1251 *wl, u32 life_time) wl1251_debug(DEBUG_ACX, "acx rx msdu life time"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -303,7 +303,7 @@ int wl1251_acx_rx_config(struct wl1251 *wl, u32 config, u32 filter) wl1251_debug(DEBUG_ACX, "acx rx config"); - rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL); + rx_config = kzalloc_obj(*rx_config); if (!rx_config) return -ENOMEM; @@ -329,7 +329,7 @@ int wl1251_acx_pd_threshold(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx data pd threshold"); - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return -ENOMEM; @@ -353,7 +353,7 @@ int wl1251_acx_slot(struct wl1251 *wl, enum acx_slot_type slot_time) wl1251_debug(DEBUG_ACX, "acx slot"); - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) return -ENOMEM; @@ -379,7 +379,7 @@ int wl1251_acx_group_address_tbl(struct wl1251 *wl, bool enable, wl1251_debug(DEBUG_ACX, "acx group address tbl"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -405,7 +405,7 @@ int wl1251_acx_service_period_timeout(struct wl1251 *wl) struct acx_rx_timeout *rx_timeout; int ret; - rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); + rx_timeout = kzalloc_obj(*rx_timeout); if (!rx_timeout) return -ENOMEM; @@ -434,7 +434,7 @@ int wl1251_acx_rts_threshold(struct wl1251 *wl, u16 rts_threshold) wl1251_debug(DEBUG_ACX, "acx rts threshold"); - rts = kzalloc(sizeof(*rts), GFP_KERNEL); + rts = kzalloc_obj(*rts); if (!rts) return -ENOMEM; @@ -458,7 +458,7 @@ int wl1251_acx_beacon_filter_opt(struct wl1251 *wl, bool enable_filter) wl1251_debug(DEBUG_ACX, "acx beacon filter opt"); - beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); + beacon_filter = kzalloc_obj(*beacon_filter); if (!beacon_filter) return -ENOMEM; @@ -485,7 +485,7 @@ int wl1251_acx_beacon_filter_table(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx beacon filter table"); - ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); + ie_table = kzalloc_obj(*ie_table); if (!ie_table) return -ENOMEM; @@ -513,7 +513,7 @@ int wl1251_acx_conn_monit_params(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx connection monitor parameters"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -540,7 +540,7 @@ int wl1251_acx_sg_enable(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx sg enable"); - pta = kzalloc(sizeof(*pta), GFP_KERNEL); + pta = kzalloc_obj(*pta); if (!pta) return -ENOMEM; @@ -564,7 +564,7 @@ int wl1251_acx_sg_cfg(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx sg cfg"); - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) return -ENOMEM; @@ -616,7 +616,7 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx cca threshold"); - detection = kzalloc(sizeof(*detection), GFP_KERNEL); + detection = kzalloc_obj(*detection); if (!detection) return -ENOMEM; @@ -639,7 +639,7 @@ int wl1251_acx_bcn_dtim_options(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx bcn dtim options"); - bb = kzalloc(sizeof(*bb), GFP_KERNEL); + bb = kzalloc_obj(*bb); if (!bb) return -ENOMEM; @@ -666,7 +666,7 @@ int wl1251_acx_aid(struct wl1251 *wl, u16 aid) wl1251_debug(DEBUG_ACX, "acx aid"); - acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); + acx_aid = kzalloc_obj(*acx_aid); if (!acx_aid) return -ENOMEM; @@ -690,7 +690,7 @@ int wl1251_acx_event_mbox_mask(struct wl1251 *wl, u32 event_mask) wl1251_debug(DEBUG_ACX, "acx event mbox mask"); - mask = kzalloc(sizeof(*mask), GFP_KERNEL); + mask = kzalloc_obj(*mask); if (!mask) return -ENOMEM; @@ -719,7 +719,7 @@ int wl1251_acx_low_rssi(struct wl1251 *wl, s8 threshold, u8 weight, wl1251_debug(DEBUG_ACX, "acx low rssi"); - rssi = kzalloc(sizeof(*rssi), GFP_KERNEL); + rssi = kzalloc_obj(*rssi); if (!rssi) return -ENOMEM; @@ -743,7 +743,7 @@ int wl1251_acx_set_preamble(struct wl1251 *wl, enum acx_preamble_type preamble) wl1251_debug(DEBUG_ACX, "acx_set_preamble"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -768,7 +768,7 @@ int wl1251_acx_cts_protect(struct wl1251 *wl, wl1251_debug(DEBUG_ACX, "acx_set_ctsprotect"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -790,7 +790,7 @@ int wl1251_acx_tsf_info(struct wl1251 *wl, u64 *mactime) struct acx_tsf_info *tsf_info; int ret; - tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); + tsf_info = kzalloc_obj(*tsf_info); if (!tsf_info) return -ENOMEM; @@ -832,7 +832,7 @@ int wl1251_acx_mem_cfg(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx mem cfg"); - mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); + mem_conf = kzalloc_obj(*mem_conf); if (!mem_conf) return -ENOMEM; @@ -877,7 +877,7 @@ int wl1251_acx_wr_tbtt_and_dtim(struct wl1251 *wl, u16 tbtt, u8 dtim) wl1251_debug(DEBUG_ACX, "acx tbtt and dtim"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -904,7 +904,7 @@ int wl1251_acx_bet_enable(struct wl1251 *wl, enum wl1251_acx_bet_mode mode, wl1251_debug(DEBUG_ACX, "acx bet enable"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -929,7 +929,7 @@ int wl1251_acx_arp_ip_filter(struct wl1251 *wl, bool enable, __be32 address) wl1251_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -957,7 +957,7 @@ int wl1251_acx_ac_cfg(struct wl1251 *wl, u8 ac, u8 cw_min, u16 cw_max, wl1251_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " "aifs %d txop %d", ac, cw_min, cw_max, aifs, txop); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -990,7 +990,7 @@ int wl1251_acx_tid_cfg(struct wl1251 *wl, u8 queue, "ps_scheme %d ack_policy %d", queue, type, tsid, ps_scheme, ack_policy); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/cmd.c b/drivers/net/wireless/ti/wl1251/cmd.c index c33ee0d4d323..a726a809b54a 100644 --- a/drivers/net/wireless/ti/wl1251/cmd.c +++ b/drivers/net/wireless/ti/wl1251/cmd.c @@ -133,7 +133,7 @@ int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, wl1251_debug(DEBUG_CMD, "cmd vbm"); - vbm = kzalloc(sizeof(*vbm), GFP_KERNEL); + vbm = kzalloc_obj(*vbm); if (!vbm) return -ENOMEM; @@ -169,7 +169,7 @@ int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable) wl1251_debug(DEBUG_CMD, "cmd data path"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -203,7 +203,7 @@ int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable) wl1251_debug(DEBUG_CMD, "cmd data path"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -233,7 +233,7 @@ int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, int ret, i; u8 *bssid; - join = kzalloc(sizeof(*join), GFP_KERNEL); + join = kzalloc_obj(*join); if (!join) return -ENOMEM; @@ -276,7 +276,7 @@ int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode) wl1251_debug(DEBUG_CMD, "cmd set ps mode"); - ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); + ps_params = kzalloc_obj(*ps_params); if (!ps_params) return -ENOMEM; @@ -342,7 +342,7 @@ int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, WARN_ON(n_channels > SCAN_MAX_NUM_OF_CHANNELS); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -409,7 +409,7 @@ int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout) wl1251_debug(DEBUG_CMD, "cmd trigger scan to"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/debugfs.c b/drivers/net/wireless/ti/wl1251/debugfs.c index a1b778a0fda0..60ab923b75db 100644 --- a/drivers/net/wireless/ti/wl1251/debugfs.c +++ b/drivers/net/wireless/ti/wl1251/debugfs.c @@ -444,7 +444,7 @@ void wl1251_debugfs_reset(struct wl1251 *wl) int wl1251_debugfs_init(struct wl1251 *wl) { - wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), GFP_KERNEL); + wl->stats.fw_stats = kzalloc_obj(*wl->stats.fw_stats); if (!wl->stats.fw_stats) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c index e945aafd88ee..7575590446a3 100644 --- a/drivers/net/wireless/ti/wl1251/event.c +++ b/drivers/net/wireless/ti/wl1251/event.c @@ -208,7 +208,7 @@ int wl1251_event_handle(struct wl1251 *wl, u8 mbox_num) if (mbox_num > 1) return -EINVAL; - mbox = kmalloc(sizeof(*mbox), GFP_KERNEL); + mbox = kmalloc_obj(*mbox); if (!mbox) { wl1251_error("can not allocate mbox buffer"); return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/init.c b/drivers/net/wireless/ti/wl1251/init.c index 5663f197ea69..45c572460f46 100644 --- a/drivers/net/wireless/ti/wl1251/init.c +++ b/drivers/net/wireless/ti/wl1251/init.c @@ -194,8 +194,7 @@ int wl1251_hw_init_mem_config(struct wl1251 *wl) if (ret < 0) return ret; - wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map), - GFP_KERNEL); + wl->target_mem_map = kzalloc_obj(struct wl1251_acx_mem_map); if (!wl->target_mem_map) { wl1251_error("couldn't allocate target memory map"); return -ENOMEM; @@ -261,7 +260,7 @@ static int wl1251_hw_init_tx_queue_config(struct wl1251 *wl) wl1251_debug(DEBUG_ACX, "acx tx queue config"); - config = kzalloc(sizeof(*config), GFP_KERNEL); + config = kzalloc_obj(*config); if (!config) { ret = -ENOMEM; goto out; @@ -294,8 +293,7 @@ static int wl1251_hw_init_data_path_config(struct wl1251 *wl) int ret; /* asking for the data path parameters */ - wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp), - GFP_KERNEL); + wl->data_path = kzalloc_obj(struct acx_data_path_params_resp); if (!wl->data_path) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl1251/io.c b/drivers/net/wireless/ti/wl1251/io.c index e8d567af74b4..6660b77f4ebb 100644 --- a/drivers/net/wireless/ti/wl1251/io.c +++ b/drivers/net/wireless/ti/wl1251/io.c @@ -123,7 +123,7 @@ void wl1251_set_partition(struct wl1251 *wl, { struct wl1251_partition_set *partition; - partition = kmalloc(sizeof(*partition), GFP_KERNEL); + partition = kmalloc_obj(*partition); if (!partition) { wl1251_error("can not allocate partition buffer"); return; diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c index 69fc51f183ad..0f3f22e729ce 100644 --- a/drivers/net/wireless/ti/wl1251/main.c +++ b/drivers/net/wireless/ti/wl1251/main.c @@ -725,7 +725,7 @@ static u64 wl1251_op_prepare_multicast(struct ieee80211_hw *hw, if (unlikely(wl->state == WL1251_STATE_OFF)) return 0; - fp = kzalloc(sizeof(*fp), GFP_ATOMIC); + fp = kzalloc_obj(*fp, GFP_ATOMIC); if (!fp) { wl1251_error("Out of memory setting filters."); return 0; @@ -878,7 +878,7 @@ static int wl1251_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wl1251_debug(DEBUG_MAC80211, "mac80211 set key"); - wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL); + wl_cmd = kzalloc_obj(*wl_cmd); if (!wl_cmd) { ret = -ENOMEM; goto out; @@ -1640,7 +1640,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void) wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE; wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE; - wl->rx_descriptor = kmalloc(sizeof(*wl->rx_descriptor), GFP_KERNEL); + wl->rx_descriptor = kmalloc_obj(*wl->rx_descriptor); if (!wl->rx_descriptor) { wl1251_error("could not allocate memory for rx descriptor"); ieee80211_free_hw(hw); diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c index b45050243129..8fdc7430c008 100644 --- a/drivers/net/wireless/ti/wl1251/sdio.c +++ b/drivers/net/wireless/ti/wl1251/sdio.c @@ -204,7 +204,7 @@ static int wl1251_sdio_probe(struct sdio_func *func, wl = hw->priv; - wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); + wl_sdio = kzalloc_obj(*wl_sdio); if (wl_sdio == NULL) { ret = -ENOMEM; goto out_free_hw; diff --git a/drivers/net/wireless/ti/wl1251/tx.c b/drivers/net/wireless/ti/wl1251/tx.c index adb4840b0489..2da8c0d5105b 100644 --- a/drivers/net/wireless/ti/wl1251/tx.c +++ b/drivers/net/wireless/ti/wl1251/tx.c @@ -451,7 +451,7 @@ void wl1251_tx_complete(struct wl1251 *wl) if (unlikely(wl->state != WL1251_STATE_ON)) return; - result = kmalloc_array(FW_TX_CMPLT_BLOCK_SIZE, sizeof(*result), GFP_KERNEL); + result = kmalloc_objs(*result, FW_TX_CMPLT_BLOCK_SIZE); if (!result) { wl1251_error("can not allocate result buffer"); return; diff --git a/drivers/net/wireless/ti/wl12xx/acx.c b/drivers/net/wireless/ti/wl12xx/acx.c index fb830d01b8ff..c669d19b122f 100644 --- a/drivers/net/wireless/ti/wl12xx/acx.c +++ b/drivers/net/wireless/ti/wl12xx/acx.c @@ -17,7 +17,7 @@ int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap) struct wl1271_acx_host_config_bitmap *bitmap_conf; int ret; - bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); + bitmap_conf = kzalloc_obj(*bitmap_conf); if (!bitmap_conf) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 17434b3bb10b..1a0755f3f37e 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c @@ -22,7 +22,7 @@ int wl1271_cmd_ext_radio_parms(struct wl1271 *wl) if (!wl->nvs) return -ENODEV; - ext_radio_parms = kzalloc(sizeof(*ext_radio_parms), GFP_KERNEL); + ext_radio_parms = kzalloc_obj(*ext_radio_parms); if (!ext_radio_parms) return -ENOMEM; @@ -63,7 +63,7 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) return -EINVAL; } - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); + gen_parms = kzalloc_obj(*gen_parms); if (!gen_parms) return -ENOMEM; @@ -130,7 +130,7 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) return -EINVAL; } - gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL); + gen_parms = kzalloc_obj(*gen_parms); if (!gen_parms) return -ENOMEM; @@ -191,7 +191,7 @@ int wl1271_cmd_radio_parms(struct wl1271 *wl) if (!wl->nvs) return -ENODEV; - radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); + radio_parms = kzalloc_obj(*radio_parms); if (!radio_parms) return -ENOMEM; @@ -235,7 +235,7 @@ int wl128x_cmd_radio_parms(struct wl1271 *wl) if (!wl->nvs) return -ENODEV; - radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL); + radio_parms = kzalloc_obj(*radio_parms); if (!radio_parms) return -ENOMEM; @@ -280,7 +280,7 @@ int wl12xx_cmd_channel_switch(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "cmd channel switch"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index ffbf54776330..30a1da72eb08 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c @@ -1882,7 +1882,7 @@ static int wl12xx_setup(struct wl1271 *wl) wl1271_error("Invalid tcxo parameter %s", tcxo_param); } - priv->rx_mem_addr = kmalloc(sizeof(*priv->rx_mem_addr), GFP_KERNEL); + priv->rx_mem_addr = kmalloc_obj(*priv->rx_mem_addr); if (!priv->rx_mem_addr) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl12xx/scan.c b/drivers/net/wireless/ti/wl12xx/scan.c index 6c18e8552e4a..ec2fb6ff8860 100644 --- a/drivers/net/wireless/ti/wl12xx/scan.c +++ b/drivers/net/wireless/ti/wl12xx/scan.c @@ -91,8 +91,8 @@ static int wl1271_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (!passive && wl->scan.req->n_ssids == 0) return WL1271_NOTHING_TO_SCAN; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); - trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); + trigger = kzalloc_obj(*trigger); if (!cmd || !trigger) { ret = -ENOMEM; goto out; @@ -184,7 +184,7 @@ int wl12xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_CMD, "cmd scan stop"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -317,7 +317,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config"); - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; @@ -348,7 +348,7 @@ int wl1271_scan_sched_scan_config(struct wl1271 *wl, wl1271_debug(DEBUG_SCAN, "filter_type = %d", cfg->filter_type); - cfg_channels = kzalloc(sizeof(*cfg_channels), GFP_KERNEL); + cfg_channels = kzalloc_obj(*cfg_channels); if (!cfg_channels) { ret = -ENOMEM; goto out; @@ -425,7 +425,7 @@ int wl1271_scan_sched_scan_start(struct wl1271 *wl, struct wl12xx_vif *wlvif) test_bit(WLVIF_FLAG_IN_USE, &wlvif->flags)) return -EBUSY; - start = kzalloc(sizeof(*start), GFP_KERNEL); + start = kzalloc_obj(*start); if (!start) return -ENOMEM; @@ -465,7 +465,7 @@ void wl12xx_scan_sched_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_CMD, "cmd periodic scan stop"); /* FIXME: what to do if alloc'ing to stop fails? */ - stop = kzalloc(sizeof(*stop), GFP_KERNEL); + stop = kzalloc_obj(*stop); if (!stop) { wl1271_error("failed to alloc memory to send sched scan stop"); return; diff --git a/drivers/net/wireless/ti/wl18xx/acx.c b/drivers/net/wireless/ti/wl18xx/acx.c index d1deef02f43e..07f3008cf727 100644 --- a/drivers/net/wireless/ti/wl18xx/acx.c +++ b/drivers/net/wireless/ti/wl18xx/acx.c @@ -23,7 +23,7 @@ int wl18xx_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap, host_cfg_bitmap, sdio_blk_size, extra_mem_blks, len_field_size); - bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL); + bitmap_conf = kzalloc_obj(*bitmap_conf); if (!bitmap_conf) { ret = -ENOMEM; goto out; @@ -54,7 +54,7 @@ int wl18xx_acx_set_checksum_state(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx checksum state"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -80,7 +80,7 @@ int wl18xx_acx_clear_statistics(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx clear statistics"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -105,7 +105,7 @@ int wl18xx_acx_peer_ht_operation_mode(struct wl1271 *wl, u8 hlid, bool wide) wl1271_debug(DEBUG_ACX, "acx peer ht operation mode hlid %d bw %d", hlid, wide); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -146,7 +146,7 @@ int wl18xx_acx_set_peer_cap(struct wl1271 *wl, "acx set cap ht_supp: %d ht_cap: %d rates: 0x%x", ht_cap->ht_supported, ht_cap->cap, rate_set); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -192,7 +192,7 @@ int wl18xx_acx_interrupt_notify_config(struct wl1271 *wl, struct wl18xx_acx_interrupt_notify *acx; int ret = 0; - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -219,7 +219,7 @@ int wl18xx_acx_rx_ba_filter(struct wl1271 *wl, bool action) struct wl18xx_acx_rx_ba_filter *acx; int ret = 0; - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -247,7 +247,7 @@ int wl18xx_acx_ap_sleep(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx config ap sleep"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -277,7 +277,7 @@ int wl18xx_acx_dynamic_fw_traces(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx dynamic fw traces config %d", wl->dynamic_fw_traces); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -305,7 +305,7 @@ int wl18xx_acx_time_sync_cfg(struct wl1271 *wl) wl->conf.sg.params[WL18XX_CONF_SG_TIME_SYNC], wl->zone_master_mac_addr); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/ti/wl18xx/cmd.c b/drivers/net/wireless/ti/wl18xx/cmd.c index 5f8620d90052..20fe6b8601fb 100644 --- a/drivers/net/wireless/ti/wl18xx/cmd.c +++ b/drivers/net/wireless/ti/wl18xx/cmd.c @@ -22,7 +22,7 @@ int wl18xx_cmd_channel_switch(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "cmd channel switch (count=%d)", ch_switch->count); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -78,7 +78,7 @@ int wl18xx_cmd_smart_config_start(struct wl1271 *wl, u32 group_bitmap) wl1271_debug(DEBUG_CMD, "cmd smart config start group_bitmap=0x%x", group_bitmap); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -105,7 +105,7 @@ int wl18xx_cmd_smart_config_stop(struct wl1271 *wl) wl1271_debug(DEBUG_CMD, "cmd smart config stop"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -137,7 +137,7 @@ int wl18xx_cmd_smart_config_set_group_key(struct wl1271 *wl, u16 group_id, return -E2BIG; } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -167,7 +167,7 @@ int wl18xx_cmd_set_cac(struct wl1271 *wl, struct wl12xx_vif *wlvif, bool start) wl1271_debug(DEBUG_CMD, "cmd cac (channel %d) %s", wlvif->channel, start ? "start" : "stop"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -198,7 +198,7 @@ int wl18xx_cmd_radar_detection_debug(struct wl1271 *wl, u8 channel) wl1271_debug(DEBUG_CMD, "cmd radar detection debug (chan %d)", channel); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -224,7 +224,7 @@ int wl18xx_cmd_dfs_master_restart(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_CMD, "cmd dfs master restart (role %d)", wlvif->role_id); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wl18xx/scan.c b/drivers/net/wireless/ti/wl18xx/scan.c index d9f4b715abf6..1f4896eb0434 100644 --- a/drivers/net/wireless/ti/wl18xx/scan.c +++ b/drivers/net/wireless/ti/wl18xx/scan.c @@ -31,7 +31,7 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct wlcore_scan_channels *cmd_channels = NULL; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -67,7 +67,7 @@ static int wl18xx_scan_send(struct wl1271 *wl, struct wl12xx_vif *wlvif, /* configure channels */ WARN_ON(req->n_ssids > 1); - cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL); + cmd_channels = kzalloc_obj(*cmd_channels); if (!cmd_channels) { ret = -ENOMEM; goto out; @@ -169,7 +169,7 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl, if (filter_type < 0) return filter_type; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -201,7 +201,7 @@ int wl18xx_scan_sched_scan_config(struct wl1271 *wl, /* don't stop scanning automatically when something is found */ cmd->terminate_after = 0; - cmd_channels = kzalloc(sizeof(*cmd_channels), GFP_KERNEL); + cmd_channels = kzalloc_obj(*cmd_channels); if (!cmd_channels) { ret = -ENOMEM; goto out; @@ -301,7 +301,7 @@ static int __wl18xx_scan_stop(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_CMD, "cmd periodic scan stop"); - stop = kzalloc(sizeof(*stop), GFP_KERNEL); + stop = kzalloc_obj(*stop); if (!stop) { wl1271_error("failed to alloc memory to send sched scan stop"); return -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/acx.c b/drivers/net/wireless/ti/wlcore/acx.c index e820fe694121..9efa13638c45 100644 --- a/drivers/net/wireless/ti/wlcore/acx.c +++ b/drivers/net/wireless/ti/wlcore/acx.c @@ -28,7 +28,7 @@ int wl1271_acx_wake_up_conditions(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx wake up conditions (wake_up_event %d listen_interval %d)", wake_up_event, listen_interval); - wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL); + wake_up = kzalloc_obj(*wake_up); if (!wake_up) { ret = -ENOMEM; goto out; @@ -57,7 +57,7 @@ int wl1271_acx_sleep_auth(struct wl1271 *wl, u8 sleep_auth) wl1271_debug(DEBUG_ACX, "acx sleep auth %d", sleep_auth); - auth = kzalloc(sizeof(*auth), GFP_KERNEL); + auth = kzalloc_obj(*auth); if (!auth) { ret = -ENOMEM; goto out; @@ -90,7 +90,7 @@ int wl1271_acx_tx_power(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (power < 0 || power > 25) return -EINVAL; - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -117,7 +117,7 @@ int wl1271_acx_feature_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "acx feature cfg"); - feature = kzalloc(sizeof(*feature), GFP_KERNEL); + feature = kzalloc_obj(*feature); if (!feature) { ret = -ENOMEM; goto out; @@ -162,7 +162,7 @@ int wl1271_acx_rx_msdu_life_time(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx rx msdu life time"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -189,7 +189,7 @@ int wl1271_acx_slot(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx slot"); - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) { ret = -ENOMEM; goto out; @@ -218,7 +218,7 @@ int wl1271_acx_group_address_tbl(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx group address tbl"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -248,7 +248,7 @@ int wl1271_acx_service_period_timeout(struct wl1271 *wl, struct acx_rx_timeout *rx_timeout; int ret; - rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL); + rx_timeout = kzalloc_obj(*rx_timeout); if (!rx_timeout) { ret = -ENOMEM; goto out; @@ -288,7 +288,7 @@ int wl1271_acx_rts_threshold(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold); - rts = kzalloc(sizeof(*rts), GFP_KERNEL); + rts = kzalloc_obj(*rts); if (!rts) { ret = -ENOMEM; goto out; @@ -316,7 +316,7 @@ int wl1271_acx_dco_itrim_params(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx dco itrim parameters"); - dco = kzalloc(sizeof(*dco), GFP_KERNEL); + dco = kzalloc_obj(*dco); if (!dco) { ret = -ENOMEM; goto out; @@ -350,7 +350,7 @@ int wl1271_acx_beacon_filter_opt(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl->conf.conn.bcn_filt_mode == CONF_BCN_FILT_MODE_DISABLED) goto out; - beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL); + beacon_filter = kzalloc_obj(*beacon_filter); if (!beacon_filter) { ret = -ENOMEM; goto out; @@ -387,7 +387,7 @@ int wl1271_acx_beacon_filter_table(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "acx beacon filter table"); - ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL); + ie_table = kzalloc_obj(*ie_table); if (!ie_table) { ret = -ENOMEM; goto out; @@ -446,7 +446,7 @@ int wl1271_acx_conn_monit_params(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx connection monitor parameters: %s", enable ? "enabled" : "disabled"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -482,7 +482,7 @@ int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable) wl1271_debug(DEBUG_ACX, "acx sg enable"); - pta = kzalloc(sizeof(*pta), GFP_KERNEL); + pta = kzalloc_obj(*pta); if (!pta) { ret = -ENOMEM; goto out; @@ -512,7 +512,7 @@ int wl12xx_acx_sg_cfg(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx sg cfg"); - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) { ret = -ENOMEM; goto out; @@ -541,7 +541,7 @@ int wl1271_acx_cca_threshold(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx cca threshold"); - detection = kzalloc(sizeof(*detection), GFP_KERNEL); + detection = kzalloc_obj(*detection); if (!detection) { ret = -ENOMEM; goto out; @@ -567,7 +567,7 @@ int wl1271_acx_bcn_dtim_options(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "acx bcn dtim options"); - bb = kzalloc(sizeof(*bb), GFP_KERNEL); + bb = kzalloc_obj(*bb); if (!bb) { ret = -ENOMEM; goto out; @@ -597,7 +597,7 @@ int wl1271_acx_aid(struct wl1271 *wl, struct wl12xx_vif *wlvif, u16 aid) wl1271_debug(DEBUG_ACX, "acx aid"); - acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL); + acx_aid = kzalloc_obj(*acx_aid); if (!acx_aid) { ret = -ENOMEM; goto out; @@ -624,7 +624,7 @@ int wl1271_acx_event_mbox_mask(struct wl1271 *wl, u32 event_mask) wl1271_debug(DEBUG_ACX, "acx event mbox mask"); - mask = kzalloc(sizeof(*mask), GFP_KERNEL); + mask = kzalloc_obj(*mask); if (!mask) { ret = -ENOMEM; goto out; @@ -654,7 +654,7 @@ int wl1271_acx_set_preamble(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx_set_preamble"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -682,7 +682,7 @@ int wl1271_acx_cts_protect(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx_set_ctsprotect"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -727,7 +727,7 @@ int wl1271_acx_sta_rate_policies(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "acx rate policies"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; @@ -798,7 +798,7 @@ int wl1271_acx_ap_rate_policy(struct wl1271 *wl, struct conf_tx_rate_class *c, wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x", idx, c->enabled_rates); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -831,7 +831,7 @@ int wl1271_acx_ac_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx ac cfg %d cw_ming %d cw_max %d " "aifs %d txop %d", ac, cw_min, cw_max, aifsn, txop); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; @@ -866,7 +866,7 @@ int wl1271_acx_tid_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx tid config"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; @@ -907,7 +907,7 @@ int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold) wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; @@ -933,7 +933,7 @@ int wl1271_acx_tx_config_options(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx tx config options"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; @@ -961,7 +961,7 @@ int wl12xx_acx_mem_cfg(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "wl1271 mem cfg"); - mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL); + mem_conf = kzalloc_obj(*mem_conf); if (!mem_conf) { ret = -ENOMEM; goto out; @@ -998,8 +998,7 @@ int wl1271_acx_init_mem_config(struct wl1271 *wl) { int ret; - wl->target_mem_map = kzalloc(sizeof(struct wl1271_acx_mem_map), - GFP_KERNEL); + wl->target_mem_map = kzalloc_obj(struct wl1271_acx_mem_map); if (!wl->target_mem_map) { wl1271_error("couldn't allocate target memory map"); return -ENOMEM; @@ -1032,7 +1031,7 @@ int wl1271_acx_init_rx_interrupt(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "wl1271 rx interrupt config"); - rx_conf = kzalloc(sizeof(*rx_conf), GFP_KERNEL); + rx_conf = kzalloc_obj(*rx_conf); if (!rx_conf) { ret = -ENOMEM; goto out; @@ -1066,7 +1065,7 @@ int wl1271_acx_bet_enable(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (enable && wl->conf.conn.bet_enable == CONF_BET_MODE_DISABLE) goto out; - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1095,7 +1094,7 @@ int wl1271_acx_arp_ip_filter(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx arp ip filter, enable: %d", enable); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1128,7 +1127,7 @@ int wl1271_acx_pm_config(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx pm config"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1157,7 +1156,7 @@ int wl1271_acx_keep_alive_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx keep alive mode: %d", enable); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1185,7 +1184,7 @@ int wl1271_acx_keep_alive_config(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx keep alive config"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1217,7 +1216,7 @@ int wl1271_acx_rssi_snr_trigger(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx rssi snr trigger"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1259,7 +1258,7 @@ int wl1271_acx_rssi_snr_avg_weights(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "acx rssi snr avg weights"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1294,7 +1293,7 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl, "sta supp: %d sta cap: %d", ht_cap->ht_supported, ht_cap->cap); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1340,7 +1339,7 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "acx ht information setting"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1376,7 +1375,7 @@ int wl12xx_acx_set_ba_initiator_policy(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "acx ba initiator policy"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1412,7 +1411,7 @@ int wl12xx_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, wl1271_debug(DEBUG_ACX, "acx ba receiver session setting"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1451,7 +1450,7 @@ int wl12xx_acx_tsf_info(struct wl1271 *wl, struct wl12xx_vif *wlvif, struct wl12xx_acx_fw_tsf_information *tsf_info; int ret; - tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL); + tsf_info = kzalloc_obj(*tsf_info); if (!tsf_info) { ret = -ENOMEM; goto out; @@ -1483,7 +1482,7 @@ int wl1271_acx_ps_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx ps rx streaming"); - rx_streaming = kzalloc(sizeof(*rx_streaming), GFP_KERNEL); + rx_streaming = kzalloc_obj(*rx_streaming); if (!rx_streaming) { ret = -ENOMEM; goto out; @@ -1530,7 +1529,7 @@ int wl1271_acx_ap_max_tx_retry(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "acx ap max tx retry"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -1555,7 +1554,7 @@ int wl12xx_acx_config_ps(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "acx config ps"); - config_ps = kzalloc(sizeof(*config_ps), GFP_KERNEL); + config_ps = kzalloc_obj(*config_ps); if (!config_ps) { ret = -ENOMEM; goto out; @@ -1586,7 +1585,7 @@ int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, wl1271_debug(DEBUG_ACX, "acx set inconnaction sta %pM", addr); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -1612,7 +1611,7 @@ int wl1271_acx_fm_coex(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx fm coex setting"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1653,7 +1652,7 @@ int wl12xx_acx_set_rate_mgmt_params(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx set rate mgmt params"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; @@ -1695,7 +1694,7 @@ int wl12xx_acx_config_hangover(struct wl1271 *wl) wl1271_debug(DEBUG_ACX, "acx config hangover"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1735,7 +1734,7 @@ int wlcore_acx_average_rssi(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_ACX, "acx roaming statistics"); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) { ret = -ENOMEM; goto out; @@ -1767,7 +1766,7 @@ int wl1271_acx_default_rx_filter_enable(struct wl1271 *wl, bool enable, wl1271_debug(DEBUG_ACX, "acx default rx filter en: %d act: %d", enable, action); - acx = kzalloc(sizeof(*acx), GFP_KERNEL); + acx = kzalloc_obj(*acx); if (!acx) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 9d73ba933a16..04d0bb8460fe 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -172,7 +172,7 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, *timeout = false; - events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA); + events_vector = kmalloc_obj(*events_vector, GFP_KERNEL | GFP_DMA); if (!events_vector) return -ENOMEM; @@ -231,7 +231,7 @@ int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type, if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID)) return -EBUSY; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -273,7 +273,7 @@ int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id) if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID)) return -ENOENT; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -431,7 +431,7 @@ static int wl12xx_cmd_role_start_dev(struct wl1271 *wl, struct wl12xx_cmd_role_start *cmd; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -483,7 +483,7 @@ static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl, if (WARN_ON(wlvif->dev_hlid == WL12XX_INVALID_LINK_ID)) return -EINVAL; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -517,7 +517,7 @@ int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) u32 supported_rates; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -594,7 +594,7 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) return -EINVAL; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -641,7 +641,7 @@ int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) } } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -736,7 +736,7 @@ int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif) struct wl12xx_cmd_role_stop *cmd; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -769,7 +769,7 @@ int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif) struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; int ret; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -942,7 +942,7 @@ int wl1271_cmd_data_path(struct wl1271 *wl, bool enable) wl1271_debug(DEBUG_CMD, "cmd data path"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -993,7 +993,7 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_CMD, "cmd set ps mode"); - ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); + ps_params = kzalloc_obj(*ps_params); if (!ps_params) { ret = -ENOMEM; goto out; @@ -1028,7 +1028,7 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id, WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE); buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1340,7 +1340,7 @@ int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid) wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1376,7 +1376,7 @@ int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) return 0; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1442,7 +1442,7 @@ int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, int ret = 0; u8 lid_type; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -1505,7 +1505,7 @@ int wl12xx_cmd_set_peer_state(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", hlid); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1540,7 +1540,7 @@ int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1599,7 +1599,7 @@ int wl12xx_cmd_remove_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif, wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1733,7 +1733,7 @@ int wlcore_cmd_regdomain_config_locked(struct wl1271 *wl) if (!memcmp(tmp_ch_bitmap, wl->reg_ch_conf_last, sizeof(tmp_ch_bitmap))) goto out; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1778,7 +1778,7 @@ int wl12xx_cmd_config_fwlog(struct wl1271 *wl) wl1271_debug(DEBUG_CMD, "cmd config firmware logger"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1810,7 +1810,7 @@ int wl12xx_cmd_stop_fwlog(struct wl1271 *wl) wl1271_debug(DEBUG_CMD, "cmd stop firmware logger"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1840,7 +1840,7 @@ static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID)) return -EINVAL; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1882,7 +1882,7 @@ static int wl12xx_cmd_croc(struct wl1271 *wl, u8 role_id) wl1271_debug(DEBUG_CMD, "cmd croc (%d)", role_id); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -1951,7 +1951,7 @@ int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl, struct wl12xx_vif *wlvif) wl1271_debug(DEBUG_ACX, "cmd stop channel switch"); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; @@ -2055,7 +2055,7 @@ int wlcore_cmd_generic_cfg(struct wl1271 *wl, struct wl12xx_vif *wlvif, "cmd generic cfg (role %d feature %d enable %d value %d)", wlvif->role_id, feature, enable, value); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index 03b49baa9d89..aa59ddd520f9 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -148,7 +148,7 @@ static int wl1271_ap_init_deauth_template(struct wl1271 *wl, int ret; u32 rate; - tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + tmpl = kzalloc_obj(*tmpl); if (!tmpl) { ret = -ENOMEM; goto out; @@ -175,7 +175,7 @@ static int wl1271_ap_init_null_template(struct wl1271 *wl, int ret; u32 rate; - nullfunc = kzalloc(sizeof(*nullfunc), GFP_KERNEL); + nullfunc = kzalloc_obj(*nullfunc); if (!nullfunc) { ret = -ENOMEM; goto out; @@ -208,7 +208,7 @@ static int wl1271_ap_init_qos_null_template(struct wl1271 *wl, int ret; u32 rate; - qosnull = kzalloc(sizeof(*qosnull), GFP_KERNEL); + qosnull = kzalloc_obj(*qosnull); if (!qosnull) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index dce79bce2e3f..1c340a4a0930 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c @@ -1070,11 +1070,11 @@ static int wl1271_setup(struct wl1271 *wl) if (!wl->raw_fw_status) goto err; - wl->fw_status = kzalloc(sizeof(*wl->fw_status), GFP_KERNEL); + wl->fw_status = kzalloc_obj(*wl->fw_status); if (!wl->fw_status) goto err; - wl->tx_res_if = kzalloc(sizeof(*wl->tx_res_if), GFP_KERNEL); + wl->tx_res_if = kzalloc_obj(*wl->tx_res_if); if (!wl->tx_res_if) goto err; @@ -1477,7 +1477,7 @@ wl1271_validate_wowlan_pattern(struct cfg80211_pkt_pattern *p) struct wl12xx_rx_filter *wl1271_rx_filter_alloc(void) { - return kzalloc(sizeof(struct wl12xx_rx_filter), GFP_KERNEL); + return kzalloc_obj(struct wl12xx_rx_filter); } void wl1271_rx_filter_free(struct wl12xx_rx_filter *filter) @@ -1875,6 +1875,8 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) wl->wow_enabled); WARN_ON(!wl->wow_enabled); + mutex_lock(&wl->mutex); + ret = pm_runtime_force_resume(wl->dev); if (ret < 0) { wl1271_error("ELP wakeup failure!"); @@ -1891,8 +1893,6 @@ static int __maybe_unused wl1271_op_resume(struct ieee80211_hw *hw) run_irq_work = true; spin_unlock_irqrestore(&wl->wl_lock, flags); - mutex_lock(&wl->mutex); - /* test the recovery flag before calling any SDIO functions */ pending_recovery = test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags); @@ -3215,7 +3215,7 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw, struct wl1271_filter_params *fp; struct netdev_hw_addr *ha; - fp = kzalloc(sizeof(*fp), GFP_ATOMIC); + fp = kzalloc_obj(*fp, GFP_ATOMIC); if (!fp) { wl1271_error("Out of memory setting filters."); return 0; @@ -3346,7 +3346,7 @@ static int wl1271_record_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif, if (i == MAX_NUM_KEYS) return -EBUSY; - ap_key = kzalloc(sizeof(*ap_key), GFP_KERNEL); + ap_key = kzalloc_obj(*ap_key); if (!ap_key) return -ENOMEM; @@ -6459,7 +6459,7 @@ struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size, goto err_fwlog; } - wl->buffer_32 = kmalloc(sizeof(*wl->buffer_32), GFP_KERNEL); + wl->buffer_32 = kmalloc_obj(*wl->buffer_32); if (!wl->buffer_32) { ret = -ENOMEM; goto err_mbox; diff --git a/drivers/net/wireless/ti/wlcore/scan.c b/drivers/net/wireless/ti/wlcore/scan.c index f6dc54c1dbad..976d96495f28 100644 --- a/drivers/net/wireless/ti/wlcore/scan.c +++ b/drivers/net/wireless/ti/wlcore/scan.c @@ -389,7 +389,7 @@ wlcore_scan_sched_scan_ssid_list(struct wl1271 *wl, goto out; } - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out; diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index 7c0cb1b7fef0..8437038e4dd0 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c @@ -159,7 +159,7 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) if (ret < 0) goto out; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { ret = -ENOMEM; goto out_sleep; diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index 4d9f5f87e814..e89173f91637 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -6489,7 +6489,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) if (info->attrs[HWSIM_ATTR_PMSR_SUPPORT]) { struct cfg80211_pmsr_capabilities *pmsr_capa; - pmsr_capa = kmalloc(sizeof(*pmsr_capa), GFP_KERNEL); + pmsr_capa = kmalloc_obj(*pmsr_capa); if (!pmsr_capa) { ret = -ENOMEM; goto out_free; diff --git a/drivers/net/wireless/virtual/virt_wifi.c b/drivers/net/wireless/virtual/virt_wifi.c index 4eae89376feb..885dc7243e8d 100644 --- a/drivers/net/wireless/virtual/virt_wifi.c +++ b/drivers/net/wireless/virtual/virt_wifi.c @@ -558,7 +558,7 @@ static int virt_wifi_newlink(struct net_device *dev, netif_stacked_transfer_operstate(priv->lowerdev, dev); SET_NETDEV_DEV(dev, &priv->lowerdev->dev); - dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL); + dev->ieee80211_ptr = kzalloc_obj(*dev->ieee80211_ptr); if (!dev->ieee80211_ptr) { err = -ENOMEM; diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c index 0f6271d7259b..03948f0b4628 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c @@ -722,8 +722,7 @@ static int zd_mac_config_beacon(struct ieee80211_hw *hw, struct sk_buff *beacon, /* Alloc memory for full beacon write at once. */ num_cmds = 1 + zd_chip_is_zd1211b(&mac->chip) + full_len; - ioreqs = kmalloc_array(num_cmds, sizeof(struct zd_ioreq32), - GFP_KERNEL); + ioreqs = kmalloc_objs(struct zd_ioreq32, num_cmds); if (!ioreqs) { r = -ENOMEM; goto out_nofree; diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zydas/zd1211rw/zd_rf_uw2453.c index a4e7f187d82d..50aca6f681bf 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_rf_uw2453.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_rf_uw2453.c @@ -518,7 +518,7 @@ int zd_rf_init_uw2453(struct zd_rf *rf) /* we have our own TX integration code */ rf->update_channel_int = 0; - rf->priv = kmalloc(sizeof(struct uw2453_priv), GFP_KERNEL); + rf->priv = kmalloc_obj(struct uw2453_priv); if (rf->priv == NULL) return -ENOMEM; diff --git a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c index 8ee15a15f4ca..966d8ccb0dbc 100644 --- a/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zydas/zd1211rw/zd_usb.c @@ -752,7 +752,7 @@ static int __zd_usb_enable_rx(struct zd_usb *usb) dev_dbg_f(zd_usb_dev(usb), "\n"); r = -ENOMEM; - urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); + urbs = kzalloc_objs(struct urb *, RX_URBS_COUNT); if (!urbs) goto error; for (i = 0; i < RX_URBS_COUNT; i++) { diff --git a/drivers/net/wwan/iosm/iosm_ipc_imem.c b/drivers/net/wwan/iosm/iosm_ipc_imem.c index 530a3ea47a1a..1b7bc7d63a2e 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_imem.c +++ b/drivers/net/wwan/iosm/iosm_ipc_imem.c @@ -1334,7 +1334,7 @@ static int ipc_imem_config(struct iosm_imem *ipc_imem) struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, void __iomem *mmio, struct device *dev) { - struct iosm_imem *ipc_imem = kzalloc(sizeof(*pcie->imem), GFP_KERNEL); + struct iosm_imem *ipc_imem = kzalloc_obj(*pcie->imem); enum ipc_mem_exec_stage stage; if (!ipc_imem) @@ -1359,8 +1359,7 @@ struct iosm_imem *ipc_imem_init(struct iosm_pcie *pcie, unsigned int device_id, goto mmio_init_fail; } - ipc_imem->ipc_task = kzalloc(sizeof(*ipc_imem->ipc_task), - GFP_KERNEL); + ipc_imem->ipc_task = kzalloc_obj(*ipc_imem->ipc_task); /* Create tasklet for event handling*/ if (!ipc_imem->ipc_task) diff --git a/drivers/net/wwan/iosm/iosm_ipc_mmio.c b/drivers/net/wwan/iosm/iosm_ipc_mmio.c index 6764c13530b9..f8d32b0f95d9 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_mmio.c +++ b/drivers/net/wwan/iosm/iosm_ipc_mmio.c @@ -82,7 +82,7 @@ void ipc_mmio_update_cp_capability(struct iosm_mmio *ipc_mmio) struct iosm_mmio *ipc_mmio_init(void __iomem *mmio, struct device *dev) { - struct iosm_mmio *ipc_mmio = kzalloc(sizeof(*ipc_mmio), GFP_KERNEL); + struct iosm_mmio *ipc_mmio = kzalloc_obj(*ipc_mmio); int retries = IPC_MMIO_EXEC_STAGE_TIMEOUT; enum ipc_mem_exec_stage stage; diff --git a/drivers/net/wwan/iosm/iosm_ipc_mux.c b/drivers/net/wwan/iosm/iosm_ipc_mux.c index b846889fcb09..17c09221f0dd 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_mux.c +++ b/drivers/net/wwan/iosm/iosm_ipc_mux.c @@ -278,7 +278,7 @@ static int ipc_mux_schedule(struct iosm_mux *ipc_mux, union mux_msg *msg) struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg, struct iosm_imem *imem) { - struct iosm_mux *ipc_mux = kzalloc(sizeof(*ipc_mux), GFP_KERNEL); + struct iosm_mux *ipc_mux = kzalloc_obj(*ipc_mux); int i, j, ul_tds, ul_td_size; struct sk_buff_head *free_list; struct sk_buff *skb; diff --git a/drivers/net/wwan/iosm/iosm_ipc_pcie.c b/drivers/net/wwan/iosm/iosm_ipc_pcie.c index 08ff0d6ccfab..49052eb511ba 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_pcie.c +++ b/drivers/net/wwan/iosm/iosm_ipc_pcie.c @@ -260,7 +260,7 @@ static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev) static int ipc_pcie_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { - struct iosm_pcie *ipc_pcie = kzalloc(sizeof(*ipc_pcie), GFP_KERNEL); + struct iosm_pcie *ipc_pcie = kzalloc_obj(*ipc_pcie); int ret; pr_debug("Probing device 0x%X from the vendor 0x%X", pci_id->device, diff --git a/drivers/net/wwan/iosm/iosm_ipc_port.c b/drivers/net/wwan/iosm/iosm_ipc_port.c index 5d5b4183e14a..021349a78884 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_port.c +++ b/drivers/net/wwan/iosm/iosm_ipc_port.c @@ -48,7 +48,7 @@ static const struct wwan_port_ops ipc_wwan_ctrl_ops = { struct iosm_cdev *ipc_port_init(struct iosm_imem *ipc_imem, struct ipc_chnl_cfg ipc_port_cfg) { - struct iosm_cdev *ipc_port = kzalloc(sizeof(*ipc_port), GFP_KERNEL); + struct iosm_cdev *ipc_port = kzalloc_obj(*ipc_port); enum wwan_port_type port_type = ipc_port_cfg.wwan_port_type; enum ipc_channel_id chl_id = ipc_port_cfg.id; diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol.c b/drivers/net/wwan/iosm/iosm_ipc_protocol.c index 63fc7012f09f..527355a671b6 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_protocol.c +++ b/drivers/net/wwan/iosm/iosm_ipc_protocol.c @@ -222,8 +222,7 @@ bool ipc_protocol_resume(struct iosm_protocol *ipc_protocol) struct iosm_protocol *ipc_protocol_init(struct iosm_imem *ipc_imem) { - struct iosm_protocol *ipc_protocol = - kzalloc(sizeof(*ipc_protocol), GFP_KERNEL); + struct iosm_protocol *ipc_protocol = kzalloc_obj(*ipc_protocol); struct ipc_protocol_context_info *p_ci; u64 addr; diff --git a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c index 4627847c6daa..f2f86f41fd10 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c +++ b/drivers/net/wwan/iosm/iosm_ipc_protocol_ops.c @@ -69,7 +69,7 @@ static int ipc_protocol_msg_prepipe_open(struct iosm_protocol *ipc_protocol, * SKB ring is internal memory allocation for driver. No need to * re-calculate the start and end addresses. */ - skbr = kcalloc(pipe->nr_of_entries, sizeof(*skbr), GFP_ATOMIC); + skbr = kzalloc_objs(*skbr, pipe->nr_of_entries, GFP_ATOMIC); if (!skbr) return -ENOMEM; diff --git a/drivers/net/wwan/iosm/iosm_ipc_task_queue.c b/drivers/net/wwan/iosm/iosm_ipc_task_queue.c index 852a99166144..7cb2f6a506d9 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_task_queue.c +++ b/drivers/net/wwan/iosm/iosm_ipc_task_queue.c @@ -174,8 +174,7 @@ int ipc_task_init(struct ipc_task *ipc_task) { struct ipc_task_queue *ipc_queue = &ipc_task->ipc_queue; - ipc_task->ipc_tasklet = kzalloc(sizeof(*ipc_task->ipc_tasklet), - GFP_KERNEL); + ipc_task->ipc_tasklet = kzalloc_obj(*ipc_task->ipc_tasklet); if (!ipc_task->ipc_tasklet) return -ENOMEM; diff --git a/drivers/net/wwan/iosm/iosm_ipc_trace.c b/drivers/net/wwan/iosm/iosm_ipc_trace.c index 9656254c1c6c..7f3d305b3857 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_trace.c +++ b/drivers/net/wwan/iosm/iosm_ipc_trace.c @@ -140,7 +140,7 @@ struct iosm_trace *ipc_trace_init(struct iosm_imem *ipc_imem) ipc_imem_channel_init(ipc_imem, IPC_CTYPE_CTRL, chnl_cfg, IRQ_MOD_OFF); - ipc_trace = kzalloc(sizeof(*ipc_trace), GFP_KERNEL); + ipc_trace = kzalloc_obj(*ipc_trace); if (!ipc_trace) return NULL; diff --git a/drivers/net/wwan/iosm/iosm_ipc_uevent.c b/drivers/net/wwan/iosm/iosm_ipc_uevent.c index d12188ffed7e..4073b70e2457 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_uevent.c +++ b/drivers/net/wwan/iosm/iosm_ipc_uevent.c @@ -27,7 +27,7 @@ static void ipc_uevent_work(struct work_struct *data) void ipc_uevent_send(struct device *dev, char *uevent) { - struct ipc_uevent_info *info = kzalloc(sizeof(*info), GFP_ATOMIC); + struct ipc_uevent_info *info = kzalloc_obj(*info, GFP_ATOMIC); if (!info) return; diff --git a/drivers/net/wwan/iosm/iosm_ipc_wwan.c b/drivers/net/wwan/iosm/iosm_ipc_wwan.c index ff747fc79aaf..21266b599f62 100644 --- a/drivers/net/wwan/iosm/iosm_ipc_wwan.c +++ b/drivers/net/wwan/iosm/iosm_ipc_wwan.c @@ -290,7 +290,7 @@ struct iosm_wwan *ipc_wwan_init(struct iosm_imem *ipc_imem, struct device *dev) { struct iosm_wwan *ipc_wwan; - ipc_wwan = kzalloc(sizeof(*ipc_wwan), GFP_KERNEL); + ipc_wwan = kzalloc_obj(*ipc_wwan); if (!ipc_wwan) return NULL; diff --git a/drivers/net/wwan/mhi_wwan_ctrl.c b/drivers/net/wwan/mhi_wwan_ctrl.c index e13c0b078175..fa73861db6ad 100644 --- a/drivers/net/wwan/mhi_wwan_ctrl.c +++ b/drivers/net/wwan/mhi_wwan_ctrl.c @@ -218,7 +218,7 @@ static int mhi_wwan_ctrl_probe(struct mhi_device *mhi_dev, struct mhi_wwan_dev *mhiwwan; struct wwan_port *port; - mhiwwan = kzalloc(sizeof(*mhiwwan), GFP_KERNEL); + mhiwwan = kzalloc_obj(*mhiwwan); if (!mhiwwan) return -ENOMEM; diff --git a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c index 43ac1c3f1ad0..e10cb4f9104e 100644 --- a/drivers/net/wwan/t7xx/t7xx_hif_cldma.c +++ b/drivers/net/wwan/t7xx/t7xx_hif_cldma.c @@ -391,7 +391,7 @@ static struct cldma_request *t7xx_alloc_rx_request(struct cldma_ctrl *md_ctrl, s struct cldma_request *req; int val; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return NULL; @@ -451,7 +451,7 @@ static struct cldma_request *t7xx_alloc_tx_request(struct cldma_ctrl *md_ctrl) { struct cldma_request *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return NULL; @@ -1206,7 +1206,7 @@ static int t7xx_cldma_suspend(struct t7xx_pci_dev *t7xx_dev, void *entity_param) static int t7xx_cldma_pm_init(struct cldma_ctrl *md_ctrl) { - md_ctrl->pm_entity = kzalloc(sizeof(*md_ctrl->pm_entity), GFP_KERNEL); + md_ctrl->pm_entity = kzalloc_obj(*md_ctrl->pm_entity); if (!md_ctrl->pm_entity) return -ENOMEM; diff --git a/drivers/net/wwan/t7xx/t7xx_state_monitor.c b/drivers/net/wwan/t7xx/t7xx_state_monitor.c index cbdbb91e8381..091d7cabd630 100644 --- a/drivers/net/wwan/t7xx/t7xx_state_monitor.c +++ b/drivers/net/wwan/t7xx/t7xx_state_monitor.c @@ -486,7 +486,8 @@ int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id unsigned long flags; int ret; - cmd = kzalloc(sizeof(*cmd), flag & FSM_CMD_FLAG_IN_INTERRUPT ? GFP_ATOMIC : GFP_KERNEL); + cmd = kzalloc_obj(*cmd, + flag & FSM_CMD_FLAG_IN_INTERRUPT ? GFP_ATOMIC : GFP_KERNEL); if (!cmd) return -ENOMEM; @@ -532,8 +533,8 @@ int t7xx_fsm_append_event(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_event_state ev return -EINVAL; } - event = kmalloc(struct_size(event, data, length), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + event = kmalloc_flex(*event, data, length, + in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if (!event) return -ENOMEM; diff --git a/drivers/net/wwan/wwan_core.c b/drivers/net/wwan/wwan_core.c index 015213b3d687..ccce2ad74128 100644 --- a/drivers/net/wwan/wwan_core.c +++ b/drivers/net/wwan/wwan_core.c @@ -250,7 +250,7 @@ static struct wwan_device *wwan_create_dev(struct device *parent) goto done_unlock; } - wwandev = kzalloc(sizeof(*wwandev), GFP_KERNEL); + wwandev = kzalloc_obj(*wwandev); if (!wwandev) { wwandev = ERR_PTR(-ENOMEM); ida_free(&wwan_dev_ids, id); @@ -639,7 +639,7 @@ struct wwan_port *wwan_create_port(struct device *parent, if (IS_ERR(wwandev)) return ERR_CAST(wwandev); - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) { err = -ENOMEM; goto error_wwandev_remove; diff --git a/drivers/net/wwan/wwan_hwsim.c b/drivers/net/wwan/wwan_hwsim.c index 8541bd58e831..c3c2d2a68767 100644 --- a/drivers/net/wwan/wwan_hwsim.c +++ b/drivers/net/wwan/wwan_hwsim.c @@ -317,7 +317,7 @@ static struct wwan_hwsim_port *wwan_hwsim_port_new(struct wwan_hwsim_dev *dev, else return ERR_PTR(-EINVAL); - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); @@ -390,7 +390,7 @@ static struct wwan_hwsim_dev *wwan_hwsim_dev_new(void) struct wwan_hwsim_dev *dev; int err; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c index c6b2eba3511b..20c2c6c5bda1 100644 --- a/drivers/net/xen-netback/hash.c +++ b/drivers/net/xen-netback/hash.c @@ -39,7 +39,7 @@ static void xenvif_add_hash(struct xenvif *vif, const u8 *tag, unsigned long flags; bool found; - new = kmalloc(sizeof(*entry), GFP_ATOMIC); + new = kmalloc_obj(*entry, GFP_ATOMIC); if (!new) return; diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index c759ebc56457..3cdb7fd659db 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -855,7 +855,7 @@ static int xenvif_mcast_add(struct xenvif *vif, const u8 *addr) return -ENOSPC; } - mcast = kzalloc(sizeof(*mcast), GFP_ATOMIC); + mcast = kzalloc_obj(*mcast, GFP_ATOMIC); if (!mcast) return -ENOMEM; diff --git a/drivers/net/xen-netback/xenbus.c b/drivers/net/xen-netback/xenbus.c index a78a25b87240..e020f44ac2c7 100644 --- a/drivers/net/xen-netback/xenbus.c +++ b/drivers/net/xen-netback/xenbus.c @@ -735,10 +735,11 @@ static void connect(struct backend_info *be) */ requested_num_queues = xenbus_read_unsigned(dev->otherend, "multi-queue-num-queues", 1); - if (requested_num_queues > xenvif_max_queues) { + if (requested_num_queues > xenvif_max_queues || + requested_num_queues == 0) { /* buggy or malicious guest */ xenbus_dev_fatal(dev, -EINVAL, - "guest requested %u queues, exceeding the maximum of %u.", + "guest requested %u queues, but valid range is 1 - %u.", requested_num_queues, xenvif_max_queues); return; } @@ -1006,7 +1007,7 @@ static int netback_probe(struct xenbus_device *dev, int err; int sg; const char *script; - struct backend_info *be = kzalloc(sizeof(*be), GFP_KERNEL); + struct backend_info *be = kzalloc_obj(*be); if (!be) { xenbus_dev_fatal(dev, -ENOMEM, diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 0969d5c9f6b7..2ed673649c48 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1646,7 +1646,7 @@ static int xennet_xdp_set(struct net_device *dev, struct bpf_prog *prog, /* avoid the race with XDP headroom adjustment */ wait_event(module_wq, - xenbus_read_driver_state(np->xbdev->otherend) == + xenbus_read_driver_state(np->xbdev, np->xbdev->otherend) == XenbusStateReconfigured); np->netfront_xdp_enabled = true; @@ -1764,9 +1764,9 @@ static struct net_device *xennet_create_dev(struct xenbus_device *dev) do { xenbus_switch_state(dev, XenbusStateInitialising); err = wait_event_timeout(module_wq, - xenbus_read_driver_state(dev->otherend) != + xenbus_read_driver_state(dev, dev->otherend) != XenbusStateClosed && - xenbus_read_driver_state(dev->otherend) != + xenbus_read_driver_state(dev, dev->otherend) != XenbusStateUnknown, XENNET_TIMEOUT); } while (!err); @@ -2212,8 +2212,7 @@ static int xennet_create_queues(struct netfront_info *info, unsigned int i; int ret; - info->queues = kcalloc(*num_queues, sizeof(struct netfront_queue), - GFP_KERNEL); + info->queues = kzalloc_objs(struct netfront_queue, *num_queues); if (!info->queues) return -ENOMEM; @@ -2627,31 +2626,31 @@ static void xennet_bus_close(struct xenbus_device *dev) { int ret; - if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed) return; do { xenbus_switch_state(dev, XenbusStateClosing); ret = wait_event_timeout(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosing || - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosed || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown, - XENNET_TIMEOUT); + xenbus_read_driver_state(dev, dev->otherend) == + XenbusStateClosing || + xenbus_read_driver_state(dev, dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev, dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); } while (!ret); - if (xenbus_read_driver_state(dev->otherend) == XenbusStateClosed) + if (xenbus_read_driver_state(dev, dev->otherend) == XenbusStateClosed) return; do { xenbus_switch_state(dev, XenbusStateClosed); ret = wait_event_timeout(module_wq, - xenbus_read_driver_state(dev->otherend) == - XenbusStateClosed || - xenbus_read_driver_state(dev->otherend) == - XenbusStateUnknown, - XENNET_TIMEOUT); + xenbus_read_driver_state(dev, dev->otherend) == + XenbusStateClosed || + xenbus_read_driver_state(dev, dev->otherend) == + XenbusStateUnknown, + XENNET_TIMEOUT); } while (!ret); } diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c index f9cca885beec..0ea28597e6f5 100644 --- a/drivers/nfc/mei_phy.c +++ b/drivers/nfc/mei_phy.c @@ -373,7 +373,7 @@ struct nfc_mei_phy *nfc_mei_phy_alloc(struct mei_cl_device *cldev) { struct nfc_mei_phy *phy; - phy = kzalloc(sizeof(struct nfc_mei_phy), GFP_KERNEL); + phy = kzalloc_obj(struct nfc_mei_phy); if (!phy) return NULL; diff --git a/drivers/nfc/microread/microread.c b/drivers/nfc/microread/microread.c index bb4d029bb888..4149c5d735bd 100644 --- a/drivers/nfc/microread/microread.c +++ b/drivers/nfc/microread/microread.c @@ -473,7 +473,7 @@ static void microread_target_discovered(struct nfc_hci_dev *hdev, u8 gate, pr_info("target discovered to gate 0x%x\n", gate); - targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); + targets = kzalloc_obj(struct nfc_target); if (targets == NULL) { r = -ENOMEM; goto exit; @@ -650,7 +650,7 @@ int microread_probe(void *phy_id, const struct nfc_phy_ops *phy_ops, struct nfc_hci_init_data init_data; int r; - info = kzalloc(sizeof(struct microread_info), GFP_KERNEL); + info = kzalloc_obj(struct microread_info); if (!info) { r = -ENOMEM; goto err_info_alloc; diff --git a/drivers/nfc/nfcmrvl/main.c b/drivers/nfc/nfcmrvl/main.c index 141bc4b66dcb..c51d22e4579c 100644 --- a/drivers/nfc/nfcmrvl/main.c +++ b/drivers/nfc/nfcmrvl/main.c @@ -101,7 +101,7 @@ struct nfcmrvl_private *nfcmrvl_nci_register_dev(enum nfcmrvl_phy phy, int tailroom; u32 protocols; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/nfc/nfcsim.c b/drivers/nfc/nfcsim.c index a55381f80cd6..f8e5c4da3b13 100644 --- a/drivers/nfc/nfcsim.c +++ b/drivers/nfc/nfcsim.c @@ -66,7 +66,7 @@ static struct nfcsim_link *nfcsim_link_new(void) { struct nfcsim_link *link; - link = kzalloc(sizeof(struct nfcsim_link), GFP_KERNEL); + link = kzalloc_obj(struct nfcsim_link); if (!link) return NULL; @@ -373,7 +373,7 @@ static struct nfcsim *nfcsim_device_new(struct nfcsim_link *link_in, struct nfcsim *dev; int rc; - dev = kzalloc(sizeof(struct nfcsim), GFP_KERNEL); + dev = kzalloc_obj(struct nfcsim); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index 2b043a9f9533..d7bdbc82e2ba 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -444,7 +444,7 @@ static int __pn533_send_async(struct pn533 *dev, u8 cmd_code, dev_dbg(dev->dev, "Sending command 0x%x\n", cmd_code); - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -518,7 +518,7 @@ static int pn533_send_cmd_direct_async(struct pn533 *dev, u8 cmd_code, struct pn533_cmd *cmd; int rc; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -2019,7 +2019,7 @@ static int pn533_dep_link_up(struct nfc_dev *nfc_dev, struct nfc_target *target, *next = 0; } - arg = kmalloc(sizeof(*arg), GFP_KERNEL); + arg = kmalloc_obj(*arg); if (!arg) { dev_kfree_skb(skb); return -ENOMEM; @@ -2266,7 +2266,7 @@ static int pn533_transceive(struct nfc_dev *nfc_dev, goto error; } - arg = kmalloc(sizeof(*arg), GFP_KERNEL); + arg = kmalloc_obj(*arg); if (!arg) { rc = -ENOMEM; goto error; @@ -2744,7 +2744,7 @@ struct pn533 *pn53x_common_init(u32 device_type, { struct pn533 *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/nfc/pn533/uart.c b/drivers/nfc/pn533/uart.c index a081bce61c29..6d2f520a5bc8 100644 --- a/drivers/nfc/pn533/uart.c +++ b/drivers/nfc/pn533/uart.c @@ -242,7 +242,7 @@ static int pn532_uart_probe(struct serdev_device *serdev) int err; err = -ENOMEM; - pn532 = kzalloc(sizeof(*pn532), GFP_KERNEL); + pn532 = kzalloc_obj(*pn532); if (!pn532) goto err_exit; diff --git a/drivers/nfc/pn533/usb.c b/drivers/nfc/pn533/usb.c index 018a80674f06..0f12f86ebb02 100644 --- a/drivers/nfc/pn533/usb.c +++ b/drivers/nfc/pn533/usb.c @@ -628,6 +628,7 @@ static void pn533_usb_disconnect(struct usb_interface *interface) usb_free_urb(phy->out_urb); usb_free_urb(phy->ack_urb); kfree(phy->ack_buffer); + usb_put_dev(phy->udev); nfc_info(&interface->dev, "NXP PN533 NFC device disconnected\n"); } diff --git a/drivers/nfc/pn544/pn544.c b/drivers/nfc/pn544/pn544.c index 32a61a185142..9d0a16ac465e 100644 --- a/drivers/nfc/pn544/pn544.c +++ b/drivers/nfc/pn544/pn544.c @@ -910,7 +910,7 @@ int pn544_hci_probe(void *phy_id, const struct nfc_phy_ops *phy_ops, struct nfc_hci_init_data init_data; int r; - info = kzalloc(sizeof(struct pn544_hci_info), GFP_KERNEL); + info = kzalloc_obj(struct pn544_hci_info); if (!info) { r = -ENOMEM; goto err_info_alloc; diff --git a/drivers/nfc/port100.c b/drivers/nfc/port100.c index 00d8ea6dcb5d..a922569d7b48 100644 --- a/drivers/nfc/port100.c +++ b/drivers/nfc/port100.c @@ -859,7 +859,7 @@ static int port100_send_cmd_async(struct port100 *dev, u8 cmd_code, if (!resp) return -ENOMEM; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { dev_kfree_skb(resp); return -ENOMEM; @@ -1211,7 +1211,7 @@ static int port100_in_send_cmd(struct nfc_digital_dev *ddev, struct port100_cb_arg *cb_arg; __le16 timeout; - cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL); + cb_arg = kzalloc_obj(struct port100_cb_arg); if (!cb_arg) return -ENOMEM; @@ -1377,7 +1377,7 @@ static int port100_tg_send_cmd(struct nfc_digital_dev *ddev, struct port100_tg_comm_rf_cmd *hdr; struct port100_cb_arg *cb_arg; - cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL); + cb_arg = kzalloc_obj(struct port100_cb_arg); if (!cb_arg) return -ENOMEM; @@ -1418,7 +1418,7 @@ static int port100_listen_mdaa(struct nfc_digital_dev *ddev, if (rc) return rc; - cb_arg = kzalloc(sizeof(struct port100_cb_arg), GFP_KERNEL); + cb_arg = kzalloc_obj(struct port100_cb_arg); if (!cb_arg) return -ENOMEM; diff --git a/drivers/nfc/st21nfca/core.c b/drivers/nfc/st21nfca/core.c index bec6f607c32c..fd39a05c9622 100644 --- a/drivers/nfc/st21nfca/core.c +++ b/drivers/nfc/st21nfca/core.c @@ -946,7 +946,7 @@ int st21nfca_hci_probe(void *phy_id, const struct nfc_phy_ops *phy_ops, struct nfc_hci_init_data init_data; unsigned long quirks = 0; - info = kzalloc(sizeof(struct st21nfca_hci_info), GFP_KERNEL); + info = kzalloc_obj(struct st21nfca_hci_info); if (!info) return -ENOMEM; diff --git a/drivers/nfc/virtual_ncidev.c b/drivers/nfc/virtual_ncidev.c index b957fce83b7c..8eeb447ac96e 100644 --- a/drivers/nfc/virtual_ncidev.c +++ b/drivers/nfc/virtual_ncidev.c @@ -135,7 +135,7 @@ static int virtual_ncidev_open(struct inode *inode, struct file *file) int ret = 0; struct virtual_nci_dev *vdev; - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) return -ENOMEM; vdev->ndev = nci_allocate_device(&virtual_nci_ops, diff --git a/drivers/ntb/hw/epf/Kconfig b/drivers/ntb/hw/epf/Kconfig index 6197d1aab344..314485574bf8 100644 --- a/drivers/ntb/hw/epf/Kconfig +++ b/drivers/ntb/hw/epf/Kconfig @@ -1,6 +1,5 @@ config NTB_EPF tristate "Generic EPF Non-Transparent Bridge support" - depends on m help This driver supports EPF NTB on configurable endpoint. If unsure, say N. diff --git a/drivers/ntb/hw/intel/ntb_hw_gen1.c b/drivers/ntb/hw/intel/ntb_hw_gen1.c index 079b8cd79785..944d10b48ae4 100644 --- a/drivers/ntb/hw/intel/ntb_hw_gen1.c +++ b/drivers/ntb/hw/intel/ntb_hw_gen1.c @@ -763,7 +763,8 @@ static ssize_t ndev_debugfs_read(struct file *filp, char __user *ubuf, return ndev_ntb_debugfs_read(filp, ubuf, count, offp); else if (pdev_is_gen3(ndev->ntb.pdev)) return ndev_ntb3_debugfs_read(filp, ubuf, count, offp); - else if (pdev_is_gen4(ndev->ntb.pdev) || pdev_is_gen5(ndev->ntb.pdev)) + else if (pdev_is_gen4(ndev->ntb.pdev) || pdev_is_gen5(ndev->ntb.pdev) || + pdev_is_gen6(ndev->ntb.pdev)) return ndev_ntb4_debugfs_read(filp, ubuf, count, offp); return -ENXIO; @@ -1872,7 +1873,8 @@ static int intel_ntb_pci_probe(struct pci_dev *pdev, rc = gen3_init_dev(ndev); if (rc) goto err_init_dev; - } else if (pdev_is_gen4(pdev) || pdev_is_gen5(pdev)) { + } else if (pdev_is_gen4(pdev) || pdev_is_gen5(pdev) || + pdev_is_gen6(pdev)) { ndev->ntb.ops = &intel_ntb4_ops; rc = intel_ntb_init_pci(ndev, pdev); if (rc) @@ -1903,7 +1905,8 @@ static int intel_ntb_pci_probe(struct pci_dev *pdev, err_register: ndev_deinit_debugfs(ndev); if (pdev_is_gen1(pdev) || pdev_is_gen3(pdev) || - pdev_is_gen4(pdev) || pdev_is_gen5(pdev)) + pdev_is_gen4(pdev) || pdev_is_gen5(pdev) || + pdev_is_gen6(pdev)) xeon_deinit_dev(ndev); err_init_dev: intel_ntb_deinit_pci(ndev); @@ -1920,7 +1923,8 @@ static void intel_ntb_pci_remove(struct pci_dev *pdev) ntb_unregister_device(&ndev->ntb); ndev_deinit_debugfs(ndev); if (pdev_is_gen1(pdev) || pdev_is_gen3(pdev) || - pdev_is_gen4(pdev) || pdev_is_gen5(pdev)) + pdev_is_gen4(pdev) || pdev_is_gen5(pdev) || + pdev_is_gen6(pdev)) xeon_deinit_dev(ndev); intel_ntb_deinit_pci(ndev); kfree(ndev); @@ -2049,6 +2053,8 @@ static const struct pci_device_id intel_ntb_pci_tbl[] = { {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_ICX)}, /* GEN5 PCIe */ {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_GNR)}, + /* GEN6 PCIe */ + {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_DMR)}, {0} }; MODULE_DEVICE_TABLE(pci, intel_ntb_pci_tbl); diff --git a/drivers/ntb/hw/intel/ntb_hw_gen4.c b/drivers/ntb/hw/intel/ntb_hw_gen4.c index 22cac7975b3c..a221a978a9d5 100644 --- a/drivers/ntb/hw/intel/ntb_hw_gen4.c +++ b/drivers/ntb/hw/intel/ntb_hw_gen4.c @@ -46,6 +46,16 @@ static const struct intel_ntb_alt_reg gen4_b2b_reg = { .spad = GEN4_EM_SPAD_OFFSET, }; +static u64 get_ppd0(struct pci_dev *pdev) +{ + if (pdev_is_gen4(pdev) || pdev_is_gen5(pdev)) + return GEN4_PPD0_OFFSET; + else if (pdev_is_gen6(pdev)) + return GEN6_PPD0_OFFSET; + + return ULLONG_MAX; +} + static int gen4_poll_link(struct intel_ntb_dev *ndev) { u16 reg_val; @@ -183,7 +193,7 @@ static enum ntb_topo spr_ppd_topo(struct intel_ntb_dev *ndev, u32 ppd) int gen4_init_dev(struct intel_ntb_dev *ndev) { struct pci_dev *pdev = ndev->ntb.pdev; - u32 ppd1/*, ppd0*/; + u32 ppd1; u16 lnkctl; int rc; @@ -197,7 +207,7 @@ int gen4_init_dev(struct intel_ntb_dev *ndev) ppd1 = ioread32(ndev->self_mmio + GEN4_PPD1_OFFSET); if (pdev_is_ICX(pdev)) ndev->ntb.topo = gen4_ppd_topo(ndev, ppd1); - else if (pdev_is_SPR(pdev) || pdev_is_gen5(pdev)) + else if (pdev_is_SPR(pdev) || pdev_is_gen5(pdev) || pdev_is_gen6(pdev)) ndev->ntb.topo = spr_ppd_topo(ndev, ppd1); dev_dbg(&pdev->dev, "ppd %#x topo %s\n", ppd1, ntb_topo_string(ndev->ntb.topo)); @@ -432,10 +442,12 @@ static int intel_ntb4_link_enable(struct ntb_dev *ntb, enum ntb_speed max_speed, enum ntb_width max_width) { struct intel_ntb_dev *ndev; + struct pci_dev *pdev; u32 ntb_ctl, ppd0; u16 lnkctl; ndev = container_of(ntb, struct intel_ntb_dev, ntb); + pdev = ntb->pdev; dev_dbg(&ntb->pdev->dev, "Enabling link with max_speed %d max_width %d\n", @@ -476,12 +488,12 @@ static int intel_ntb4_link_enable(struct ntb_dev *ntb, iowrite16(lnkctl, ndev->self_mmio + GEN4_LINK_CTRL_OFFSET); /* start link training in PPD0 */ - ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET); + ppd0 = ioread32(ndev->self_mmio + get_ppd0(pdev)); ppd0 |= GEN4_PPD_LINKTRN; - iowrite32(ppd0, ndev->self_mmio + GEN4_PPD0_OFFSET); + iowrite32(ppd0, ndev->self_mmio + get_ppd0(pdev)); /* make sure link training has started */ - ppd0 = ioread32(ndev->self_mmio + GEN4_PPD0_OFFSET); + ppd0 = ioread32(ndev->self_mmio + get_ppd0(pdev)); if (!(ppd0 & GEN4_PPD_LINKTRN)) { dev_warn(&ntb->pdev->dev, "Link is not training\n"); return -ENXIO; diff --git a/drivers/ntb/hw/intel/ntb_hw_gen4.h b/drivers/ntb/hw/intel/ntb_hw_gen4.h index f91323eaf5ce..1ba8203d6352 100644 --- a/drivers/ntb/hw/intel/ntb_hw_gen4.h +++ b/drivers/ntb/hw/intel/ntb_hw_gen4.h @@ -103,6 +103,8 @@ #define NTB_LTR_IDLE_LATSCALE 0x0800 /* 1us scale */ #define NTB_LTR_IDLE_REQMNT 0x8000 /* snoop req enable */ +#define GEN6_PPD0_OFFSET 0xf0d4 + ssize_t ndev_ntb4_debugfs_read(struct file *filp, char __user *ubuf, size_t count, loff_t *offp); int gen4_init_dev(struct intel_ntb_dev *ndev); diff --git a/drivers/ntb/hw/intel/ntb_hw_intel.h b/drivers/ntb/hw/intel/ntb_hw_intel.h index da4d5fe55bab..0a3a3677f82a 100644 --- a/drivers/ntb/hw/intel/ntb_hw_intel.h +++ b/drivers/ntb/hw/intel/ntb_hw_intel.h @@ -71,6 +71,7 @@ #define PCI_DEVICE_ID_INTEL_NTB_B2B_SKX 0x201C #define PCI_DEVICE_ID_INTEL_NTB_B2B_ICX 0x347e #define PCI_DEVICE_ID_INTEL_NTB_B2B_GNR 0x0db4 +#define PCI_DEVICE_ID_INTEL_NTB_B2B_DMR 0x7868 /* Ntb control and link status */ #define NTB_CTL_CFG_LOCK BIT(0) @@ -235,4 +236,9 @@ static inline int pdev_is_gen5(struct pci_dev *pdev) return pdev->device == PCI_DEVICE_ID_INTEL_NTB_B2B_GNR; } +static inline int pdev_is_gen6(struct pci_dev *pdev) +{ + return pdev->device == PCI_DEVICE_ID_INTEL_NTB_B2B_DMR; +} + #endif diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c index f851397b65d6..e38540b92716 100644 --- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c +++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c @@ -29,7 +29,7 @@ MODULE_PARM_DESC(use_lut_mws, "Enable the use of the LUT based memory windows"); #define SWITCHTEC_NTB_MAGIC 0x45CC0001 -#define MAX_MWS 128 +#define MAX_MWS 256 struct shared_mw { u32 magic; @@ -1202,7 +1202,8 @@ static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev) sndev->mmio_self_ctrl); sndev->nr_lut_mw = ioread16(&sndev->mmio_self_ctrl->lut_table_entries); - sndev->nr_lut_mw = rounddown_pow_of_two(sndev->nr_lut_mw); + if (sndev->nr_lut_mw) + sndev->nr_lut_mw = rounddown_pow_of_two(sndev->nr_lut_mw); dev_dbg(&sndev->stdev->dev, "MWs: %d direct, %d lut\n", sndev->nr_direct_mw, sndev->nr_lut_mw); @@ -1212,7 +1213,8 @@ static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev) sndev->peer_nr_lut_mw = ioread16(&sndev->mmio_peer_ctrl->lut_table_entries); - sndev->peer_nr_lut_mw = rounddown_pow_of_two(sndev->peer_nr_lut_mw); + if (sndev->peer_nr_lut_mw) + sndev->peer_nr_lut_mw = rounddown_pow_of_two(sndev->peer_nr_lut_mw); dev_dbg(&sndev->stdev->dev, "Peer MWs: %d direct, %d lut\n", sndev->peer_nr_direct_mw, sndev->peer_nr_lut_mw); @@ -1314,6 +1316,12 @@ static void switchtec_ntb_init_shared(struct switchtec_ntb *sndev) for (i = 0; i < sndev->nr_lut_mw; i++) { int idx = sndev->nr_direct_mw + i; + if (idx >= MAX_MWS) { + dev_err(&sndev->stdev->dev, + "Total number of MW cannot be bigger than %d", MAX_MWS); + break; + } + sndev->self_shared->mw_sizes[idx] = LUT_SIZE; } } diff --git a/drivers/ntb/msi.c b/drivers/ntb/msi.c index 368f6d894bba..6817d504c12a 100644 --- a/drivers/ntb/msi.c +++ b/drivers/ntb/msi.c @@ -315,37 +315,6 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler, } EXPORT_SYMBOL(ntbm_msi_request_threaded_irq); -static int ntbm_msi_callback_match(struct device *dev, void *res, void *data) -{ - struct ntb_dev *ntb = dev_ntb(dev); - struct ntb_msi_devres *dr = res; - - return dr->ntb == ntb && dr->entry == data; -} - -/** - * ntbm_msi_free_irq() - free an interrupt - * @ntb: NTB device context - * @irq: Interrupt line to free - * @dev_id: Device identity to free - * - * This function should be used to manually free IRQs allocated with - * ntbm_request_[threaded_]irq(). - */ -void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, void *dev_id) -{ - struct msi_desc *entry = irq_get_msi_desc(irq); - - entry->write_msi_msg = NULL; - entry->write_msi_msg_data = NULL; - - WARN_ON(devres_destroy(&ntb->dev, ntbm_msi_callback_release, - ntbm_msi_callback_match, entry)); - - devm_free_irq(&ntb->dev, irq, dev_id); -} -EXPORT_SYMBOL(ntbm_msi_free_irq); - /** * ntb_msi_peer_trigger() - Trigger an interrupt handler on a peer * @ntb: NTB device context @@ -373,36 +342,3 @@ int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, return 0; } EXPORT_SYMBOL(ntb_msi_peer_trigger); - -/** - * ntb_msi_peer_addr() - Get the DMA address to trigger a peer's MSI interrupt - * @ntb: NTB device context - * @peer: Peer index - * @desc: MSI descriptor data which triggers the interrupt - * @msi_addr: Physical address to trigger the interrupt - * - * This function allows using DMA engines to trigger an interrupt - * (for example, trigger an interrupt to process the data after - * sending it). To trigger the interrupt, write @desc.data to the address - * returned in @msi_addr - * - * Return: Zero on success, otherwise a negative error number. - */ -int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, - struct ntb_msi_desc *desc, - phys_addr_t *msi_addr) -{ - int peer_widx = ntb_peer_mw_count(ntb) - 1 - peer; - phys_addr_t mw_phys_addr; - int ret; - - ret = ntb_peer_mw_get_addr(ntb, peer_widx, &mw_phys_addr, NULL); - if (ret) - return ret; - - if (msi_addr) - *msi_addr = mw_phys_addr + desc->addr_offset; - - return 0; -} -EXPORT_SYMBOL(ntb_msi_peer_addr); diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 71d4bb25f7fd..78e02fe6caba 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c @@ -54,12 +54,15 @@ #include #include #include +#include #include #include #include +#include #include #include #include +#include #include "linux/ntb.h" #include "linux/ntb_transport.h" @@ -100,6 +103,10 @@ module_param(use_msi, bool, 0644); MODULE_PARM_DESC(use_msi, "Use MSI interrupts instead of doorbells"); #endif +static bool tx_memcpy_offload; +module_param(tx_memcpy_offload, bool, 0644); +MODULE_PARM_DESC(tx_memcpy_offload, "Offload TX memcpy_toio() to a kernel thread"); + static struct dentry *nt_debugfs_dir; /* Only two-ports NTB devices are supported */ @@ -113,7 +120,6 @@ struct ntb_queue_entry { void *buf; unsigned int len; unsigned int flags; - int retries; int errors; unsigned int tx_index; unsigned int rx_index; @@ -149,7 +155,9 @@ struct ntb_transport_qp { void (*tx_handler)(struct ntb_transport_qp *qp, void *qp_data, void *data, int len); struct list_head tx_free_q; + struct list_head tx_offl_q; spinlock_t ntb_tx_free_q_lock; + spinlock_t ntb_tx_offl_q_lock; void __iomem *tx_mw; phys_addr_t tx_mw_phys; size_t tx_mw_size; @@ -200,6 +208,9 @@ struct ntb_transport_qp { int msi_irq; struct ntb_msi_desc msi_desc; struct ntb_msi_desc peer_msi_desc; + + struct task_struct *tx_offload_thread; + wait_queue_head_t tx_offload_wq; }; struct ntb_transport_mw { @@ -285,8 +296,14 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp, static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset); static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset); static void ntb_memcpy_rx(struct ntb_queue_entry *entry, void *offset); +static int ntb_tx_memcpy_kthread(void *data); +static inline bool ntb_tx_offload_enabled(struct ntb_transport_qp *qp) +{ + return tx_memcpy_offload && qp && qp->tx_offload_thread; +} + static int ntb_transport_bus_match(struct device *dev, const struct device_driver *drv) { @@ -466,104 +483,49 @@ void ntb_transport_unregister_client(struct ntb_transport_client *drv) } EXPORT_SYMBOL_GPL(ntb_transport_unregister_client); -static ssize_t debugfs_read(struct file *filp, char __user *ubuf, size_t count, - loff_t *offp) +static int ntb_qp_debugfs_stats_show(struct seq_file *s, void *v) { - struct ntb_transport_qp *qp; - char *buf; - ssize_t ret, out_offset, out_count; - - qp = filp->private_data; + struct ntb_transport_qp *qp = s->private; if (!qp || !qp->link_is_up) return 0; - out_count = 1000; + seq_puts(s, "\nNTB QP stats:\n\n"); - buf = kmalloc(out_count, GFP_KERNEL); - if (!buf) - return -ENOMEM; + seq_printf(s, "rx_bytes - \t%llu\n", qp->rx_bytes); + seq_printf(s, "rx_pkts - \t%llu\n", qp->rx_pkts); + seq_printf(s, "rx_memcpy - \t%llu\n", qp->rx_memcpy); + seq_printf(s, "rx_async - \t%llu\n", qp->rx_async); + seq_printf(s, "rx_ring_empty - %llu\n", qp->rx_ring_empty); + seq_printf(s, "rx_err_no_buf - %llu\n", qp->rx_err_no_buf); + seq_printf(s, "rx_err_oflow - \t%llu\n", qp->rx_err_oflow); + seq_printf(s, "rx_err_ver - \t%llu\n", qp->rx_err_ver); + seq_printf(s, "rx_buff - \t0x%p\n", qp->rx_buff); + seq_printf(s, "rx_index - \t%u\n", qp->rx_index); + seq_printf(s, "rx_max_entry - \t%u\n", qp->rx_max_entry); + seq_printf(s, "rx_alloc_entry - \t%u\n\n", qp->rx_alloc_entry); - out_offset = 0; - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "\nNTB QP stats:\n\n"); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_bytes - \t%llu\n", qp->rx_bytes); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_pkts - \t%llu\n", qp->rx_pkts); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_memcpy - \t%llu\n", qp->rx_memcpy); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_async - \t%llu\n", qp->rx_async); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_ring_empty - %llu\n", qp->rx_ring_empty); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_err_no_buf - %llu\n", qp->rx_err_no_buf); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_err_oflow - \t%llu\n", qp->rx_err_oflow); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_err_ver - \t%llu\n", qp->rx_err_ver); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_buff - \t0x%p\n", qp->rx_buff); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_index - \t%u\n", qp->rx_index); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_max_entry - \t%u\n", qp->rx_max_entry); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "rx_alloc_entry - \t%u\n\n", qp->rx_alloc_entry); + seq_printf(s, "tx_bytes - \t%llu\n", qp->tx_bytes); + seq_printf(s, "tx_pkts - \t%llu\n", qp->tx_pkts); + seq_printf(s, "tx_memcpy - \t%llu\n", qp->tx_memcpy); + seq_printf(s, "tx_async - \t%llu\n", qp->tx_async); + seq_printf(s, "tx_ring_full - \t%llu\n", qp->tx_ring_full); + seq_printf(s, "tx_err_no_buf - %llu\n", qp->tx_err_no_buf); + seq_printf(s, "tx_mw - \t0x%p\n", qp->tx_mw); + seq_printf(s, "tx_index (H) - \t%u\n", qp->tx_index); + seq_printf(s, "RRI (T) - \t%u\n", qp->remote_rx_info->entry); + seq_printf(s, "tx_max_entry - \t%u\n", qp->tx_max_entry); + seq_printf(s, "free tx - \t%u\n", ntb_transport_tx_free_entry(qp)); + seq_putc(s, '\n'); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_bytes - \t%llu\n", qp->tx_bytes); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_pkts - \t%llu\n", qp->tx_pkts); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_memcpy - \t%llu\n", qp->tx_memcpy); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_async - \t%llu\n", qp->tx_async); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_ring_full - \t%llu\n", qp->tx_ring_full); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_err_no_buf - %llu\n", qp->tx_err_no_buf); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_mw - \t0x%p\n", qp->tx_mw); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_index (H) - \t%u\n", qp->tx_index); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "RRI (T) - \t%u\n", - qp->remote_rx_info->entry); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "tx_max_entry - \t%u\n", qp->tx_max_entry); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "free tx - \t%u\n", - ntb_transport_tx_free_entry(qp)); + seq_printf(s, "Using TX DMA - \t%s\n", qp->tx_dma_chan ? "Yes" : "No"); + seq_printf(s, "Using RX DMA - \t%s\n", qp->rx_dma_chan ? "Yes" : "No"); + seq_printf(s, "QP Link - \t%s\n", qp->link_is_up ? "Up" : "Down"); + seq_putc(s, '\n'); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "\n"); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "Using TX DMA - \t%s\n", - qp->tx_dma_chan ? "Yes" : "No"); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "Using RX DMA - \t%s\n", - qp->rx_dma_chan ? "Yes" : "No"); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "QP Link - \t%s\n", - qp->link_is_up ? "Up" : "Down"); - out_offset += scnprintf(buf + out_offset, out_count - out_offset, - "\n"); - - if (out_offset > out_count) - out_offset = out_count; - - ret = simple_read_from_buffer(ubuf, count, offp, buf, out_offset); - kfree(buf); - return ret; + return 0; } - -static const struct file_operations ntb_qp_debugfs_stats = { - .owner = THIS_MODULE, - .open = simple_open, - .read = debugfs_read, -}; +DEFINE_SHOW_ATTRIBUTE(ntb_qp_debugfs_stats); static void ntb_list_add(spinlock_t *lock, struct list_head *entry, struct list_head *list) @@ -1236,15 +1198,15 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, qp->tx_max_entry = tx_size / qp->tx_max_frame; if (nt->debugfs_node_dir) { - char debugfs_name[4]; + char debugfs_name[8]; - snprintf(debugfs_name, 4, "qp%d", qp_num); + snprintf(debugfs_name, sizeof(debugfs_name), "qp%d", qp_num); qp->debugfs_dir = debugfs_create_dir(debugfs_name, nt->debugfs_node_dir); qp->debugfs_stats = debugfs_create_file("stats", S_IRUSR, qp->debugfs_dir, qp, - &ntb_qp_debugfs_stats); + &ntb_qp_debugfs_stats_fops); } else { qp->debugfs_dir = NULL; qp->debugfs_stats = NULL; @@ -1255,11 +1217,13 @@ static int ntb_transport_init_queue(struct ntb_transport_ctx *nt, spin_lock_init(&qp->ntb_rx_q_lock); spin_lock_init(&qp->ntb_tx_free_q_lock); + spin_lock_init(&qp->ntb_tx_offl_q_lock); INIT_LIST_HEAD(&qp->rx_post_q); INIT_LIST_HEAD(&qp->rx_pend_q); INIT_LIST_HEAD(&qp->rx_free_q); INIT_LIST_HEAD(&qp->tx_free_q); + INIT_LIST_HEAD(&qp->tx_offl_q); tasklet_init(&qp->rxc_db_work, ntb_transport_rxc_db, (unsigned long)qp); @@ -1571,15 +1535,15 @@ static int ntb_async_rx_submit(struct ntb_queue_entry *entry, void *offset) goto err; unmap->len = len; - unmap->addr[0] = dma_map_page(device->dev, virt_to_page(offset), - pay_off, len, DMA_TO_DEVICE); + unmap->addr[0] = dma_map_phys(device->dev, virt_to_phys(offset), + len, DMA_TO_DEVICE, 0); if (dma_mapping_error(device->dev, unmap->addr[0])) goto err_get_unmap; unmap->to_cnt = 1; - unmap->addr[1] = dma_map_page(device->dev, virt_to_page(buf), - buff_off, len, DMA_FROM_DEVICE); + unmap->addr[1] = dma_map_phys(device->dev, virt_to_phys(buf), + len, DMA_FROM_DEVICE, 0); if (dma_mapping_error(device->dev, unmap->addr[1])) goto err_get_unmap; @@ -1631,9 +1595,7 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset) if (res < 0) goto err; - if (!entry->retries) - qp->rx_async++; - + qp->rx_async++; return; err: @@ -1788,6 +1750,13 @@ static void ntb_tx_copy_callback(void *data, iowrite32(entry->flags | DESC_DONE_FLAG, &hdr->flags); + /* + * Make DONE flag visible before DB/MSI. WC + posted MWr may reorder + * across iATU/bridge (platform-dependent). Order and flush here. + */ + dma_mb(); + ioread32(&hdr->flags); + if (qp->use_msi) ntb_msi_peer_trigger(qp->ndev, PIDX, &qp->peer_msi_desc); else @@ -1808,7 +1777,7 @@ static void ntb_tx_copy_callback(void *data, ntb_list_add(&qp->ntb_tx_free_q_lock, &entry->entry, &qp->tx_free_q); } -static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) +static void ntb_memcpy_tx_on_stack(struct ntb_queue_entry *entry, void __iomem *offset) { #ifdef ARCH_HAS_NOCACHE_UACCESS /* @@ -1826,6 +1795,54 @@ static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) ntb_tx_copy_callback(entry, NULL); } +static int ntb_tx_memcpy_kthread(void *data) +{ + struct ntb_transport_qp *qp = data; + struct ntb_queue_entry *entry, *tmp; + const int resched_nr = 64; + LIST_HEAD(local_list); + void __iomem *offset; + int processed = 0; + + while (!kthread_should_stop()) { + spin_lock_irq(&qp->ntb_tx_offl_q_lock); + wait_event_interruptible_lock_irq_timeout(qp->tx_offload_wq, + kthread_should_stop() || + !list_empty(&qp->tx_offl_q), + qp->ntb_tx_offl_q_lock, 5*HZ); + list_splice_tail_init(&qp->tx_offl_q, &local_list); + spin_unlock_irq(&qp->ntb_tx_offl_q_lock); + + list_for_each_entry_safe(entry, tmp, &local_list, entry) { + list_del(&entry->entry); + offset = qp->tx_mw + qp->tx_max_frame * entry->tx_index; + ntb_memcpy_tx_on_stack(entry, offset); + if (++processed >= resched_nr) { + cond_resched(); + processed = 0; + } + } + cond_resched(); + } + + return 0; +} + +static void ntb_memcpy_tx(struct ntb_queue_entry *entry, void __iomem *offset) +{ + struct ntb_transport_qp *qp = entry->qp; + + if (WARN_ON_ONCE(!qp)) + return; + + if (ntb_tx_offload_enabled(qp)) { + ntb_list_add(&qp->ntb_tx_offl_q_lock, &entry->entry, + &qp->tx_offl_q); + wake_up(&qp->tx_offload_wq); + } else + ntb_memcpy_tx_on_stack(entry, offset); +} + static int ntb_async_tx_submit(struct ntb_transport_qp *qp, struct ntb_queue_entry *entry) { @@ -1852,8 +1869,8 @@ static int ntb_async_tx_submit(struct ntb_transport_qp *qp, goto err; unmap->len = len; - unmap->addr[0] = dma_map_page(device->dev, virt_to_page(buf), - buff_off, len, DMA_TO_DEVICE); + unmap->addr[0] = dma_map_phys(device->dev, virt_to_phys(buf), + len, DMA_TO_DEVICE, 0); if (dma_mapping_error(device->dev, unmap->addr[0])) goto err_get_unmap; @@ -1898,6 +1915,9 @@ static void ntb_async_tx(struct ntb_transport_qp *qp, hdr = offset + qp->tx_max_frame - sizeof(struct ntb_payload_header); entry->tx_hdr = hdr; + WARN_ON_ONCE(!ntb_transport_tx_free_entry(qp)); + WRITE_ONCE(qp->tx_index, (qp->tx_index + 1) % qp->tx_max_entry); + iowrite32(entry->len, &hdr->len); iowrite32((u32)qp->tx_pkts, &hdr->ver); @@ -1911,9 +1931,7 @@ static void ntb_async_tx(struct ntb_transport_qp *qp, if (res < 0) goto err; - if (!entry->retries) - qp->tx_async++; - + qp->tx_async++; return; err: @@ -1940,9 +1958,6 @@ static int ntb_process_tx(struct ntb_transport_qp *qp, ntb_async_tx(qp, entry); - qp->tx_index++; - qp->tx_index %= qp->tx_max_entry; - qp->tx_pkts++; return 0; @@ -2039,6 +2054,20 @@ ntb_transport_create_queue(void *data, struct device *client_dev, qp->tx_handler = handlers->tx_handler; qp->event_handler = handlers->event_handler; + init_waitqueue_head(&qp->tx_offload_wq); + if (tx_memcpy_offload) { + qp->tx_offload_thread = kthread_run(ntb_tx_memcpy_kthread, qp, + "ntb-txcpy/%s/%u", + pci_name(ndev->pdev), qp->qp_num); + if (IS_ERR(qp->tx_offload_thread)) { + dev_warn(&nt->ndev->dev, + "tx memcpy offload thread creation failed: %ld; falling back to inline copy\n", + PTR_ERR(qp->tx_offload_thread)); + qp->tx_offload_thread = NULL; + } + } else + qp->tx_offload_thread = NULL; + dma_cap_zero(dma_mask); dma_cap_set(DMA_MEMCPY, dma_mask); @@ -2146,6 +2175,11 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) qp->active = false; + if (qp->tx_offload_thread) { + kthread_stop(qp->tx_offload_thread); + qp->tx_offload_thread = NULL; + } + if (qp->tx_dma_chan) { struct dma_chan *chan = qp->tx_dma_chan; /* Putting the dma_chan to NULL will force any new traffic to be @@ -2209,6 +2243,9 @@ void ntb_transport_free_queue(struct ntb_transport_qp *qp) while ((entry = ntb_list_rm(&qp->ntb_tx_free_q_lock, &qp->tx_free_q))) kfree(entry); + while ((entry = ntb_list_rm(&qp->ntb_tx_offl_q_lock, &qp->tx_offl_q))) + kfree(entry); + qp->transport->qp_bitmap_free |= qp_bit; dev_info(&pdev->dev, "NTB Transport QP %d freed\n", qp->qp_num); @@ -2274,7 +2311,6 @@ int ntb_transport_rx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, entry->buf = data; entry->len = len; entry->flags = 0; - entry->retries = 0; entry->errors = 0; entry->rx_index = 0; @@ -2324,7 +2360,6 @@ int ntb_transport_tx_enqueue(struct ntb_transport_qp *qp, void *cb, void *data, entry->len = len; entry->flags = 0; entry->errors = 0; - entry->retries = 0; entry->tx_index = 0; rc = ntb_process_tx(qp, entry); diff --git a/drivers/ntb/test/ntb_msi_test.c b/drivers/ntb/test/ntb_msi_test.c index 4e18e08776c9..f52d409ba6d2 100644 --- a/drivers/ntb/test/ntb_msi_test.c +++ b/drivers/ntb/test/ntb_msi_test.c @@ -164,7 +164,7 @@ static void ntb_msit_db_event(void *ctx, int vec) if (irq_count == -1) continue; - desc = kcalloc(irq_count, sizeof(*desc), GFP_ATOMIC); + desc = kzalloc_objs(*desc, irq_count, GFP_ATOMIC); if (!desc) continue; diff --git a/drivers/ntb/test/ntb_tool.c b/drivers/ntb/test/ntb_tool.c index 641cb7e05a47..06881047f5bc 100644 --- a/drivers/ntb/test/ntb_tool.c +++ b/drivers/ntb/test/ntb_tool.c @@ -936,7 +936,7 @@ static ssize_t tool_peer_mw_trans_write(struct file *filep, buf[buf_size] = '\0'; - n = sscanf(buf, "%lli:%zi", &addr, &wsize); + n = sscanf(buf, "%llu:%zu", &addr, &wsize); if (n != 2) return -EINVAL; diff --git a/drivers/nubus/nubus.c b/drivers/nubus/nubus.c index 197c8c0de199..559dce302d06 100644 --- a/drivers/nubus/nubus.c +++ b/drivers/nubus/nubus.c @@ -510,7 +510,7 @@ nubus_get_functional_resource(struct nubus_board *board, int slot, dir.procdir = nubus_proc_add_rsrc_dir(board->procdir, parent, board); /* Actually we should probably panic if this fails */ - fres = kzalloc(sizeof(*fres), GFP_ATOMIC); + fres = kzalloc_obj(*fres, GFP_ATOMIC); if (!fres) return NULL; fres->resid = parent->type; @@ -739,7 +739,7 @@ static void __init nubus_add_board(int slot, int bytelanes) nubus_rewind(&rp, FORMAT_BLOCK_SIZE, bytelanes); /* Actually we should probably panic if this fails */ - if ((board = kzalloc(sizeof(*board), GFP_ATOMIC)) == NULL) + if ((board = kzalloc_obj(*board, GFP_ATOMIC)) == NULL) return; board->fblock = rp; diff --git a/drivers/nubus/proc.c b/drivers/nubus/proc.c index e7a347db708c..3ea3d1738eae 100644 --- a/drivers/nubus/proc.c +++ b/drivers/nubus/proc.c @@ -96,7 +96,7 @@ nubus_proc_alloc_pde_data(unsigned char *ptr, unsigned int size) { struct nubus_proc_pde_data *pded; - pded = kmalloc(sizeof(*pded), GFP_KERNEL); + pded = kmalloc_obj(*pded); if (!pded) return NULL; diff --git a/drivers/nvdimm/badrange.c b/drivers/nvdimm/badrange.c index 36c626db459a..551cb0691856 100644 --- a/drivers/nvdimm/badrange.c +++ b/drivers/nvdimm/badrange.c @@ -37,7 +37,7 @@ static int alloc_and_append_badrange_entry(struct badrange *badrange, { struct badrange_entry *bre; - bre = kzalloc(sizeof(*bre), flags); + bre = kzalloc_obj(*bre, flags); if (!bre) return -ENOMEM; @@ -50,7 +50,7 @@ static int add_badrange(struct badrange *badrange, u64 addr, u64 length) struct badrange_entry *bre, *bre_new; spin_unlock(&badrange->lock); - bre_new = kzalloc(sizeof(*bre_new), GFP_KERNEL); + bre_new = kzalloc_obj(*bre_new); spin_lock(&badrange->lock); if (list_empty(&badrange->list)) { diff --git a/drivers/nvdimm/btt.c b/drivers/nvdimm/btt.c index 237edfa1c624..b6bef092f8b8 100644 --- a/drivers/nvdimm/btt.c +++ b/drivers/nvdimm/btt.c @@ -539,8 +539,7 @@ static int btt_freelist_init(struct arena_info *arena) struct log_entry log_new; u32 i, map_entry, log_oldmap, log_newmap; - arena->freelist = kcalloc(arena->nfree, sizeof(struct free_entry), - GFP_KERNEL); + arena->freelist = kzalloc_objs(struct free_entry, arena->nfree); if (!arena->freelist) return -ENOMEM; @@ -733,8 +732,7 @@ static int btt_maplocks_init(struct arena_info *arena) { u32 i; - arena->map_locks = kcalloc(arena->nfree, sizeof(struct aligned_lock), - GFP_KERNEL); + arena->map_locks = kzalloc_objs(struct aligned_lock, arena->nfree); if (!arena->map_locks) return -ENOMEM; @@ -751,7 +749,7 @@ static struct arena_info *alloc_arena(struct btt *btt, size_t size, u64 logsize, mapsize, datasize; u64 available = size; - arena = kzalloc(sizeof(*arena), GFP_KERNEL); + arena = kzalloc_obj(*arena); if (!arena) return NULL; arena->nd_btt = btt->nd_btt; @@ -854,7 +852,7 @@ static int discover_arenas(struct btt *btt) size_t cur_off = 0; int num_arenas = 0; - struct btt_sb *super __free(kfree) = kzalloc(sizeof(*super), GFP_KERNEL); + struct btt_sb *super __free(kfree) = kzalloc_obj(*super); if (!super) return -ENOMEM; @@ -978,7 +976,7 @@ static int btt_arena_write_layout(struct arena_info *arena) if (ret) return ret; - super = kzalloc(sizeof(*super), GFP_NOIO); + super = kzalloc_obj(*super, GFP_NOIO); if (!super) return -ENOMEM; diff --git a/drivers/nvdimm/btt_devs.c b/drivers/nvdimm/btt_devs.c index b3279b86bbfd..d6b2f157368f 100644 --- a/drivers/nvdimm/btt_devs.c +++ b/drivers/nvdimm/btt_devs.c @@ -180,7 +180,7 @@ static struct device *__nd_btt_create(struct nd_region *nd_region, struct nd_btt *nd_btt; struct device *dev; - nd_btt = kzalloc(sizeof(*nd_btt), GFP_KERNEL); + nd_btt = kzalloc_obj(*nd_btt); if (!nd_btt) return NULL; diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c index 87178a53ff9c..bd9621d3f73c 100644 --- a/drivers/nvdimm/bus.c +++ b/drivers/nvdimm/bus.c @@ -336,7 +336,7 @@ struct nvdimm_bus *nvdimm_bus_register(struct device *parent, struct nvdimm_bus *nvdimm_bus; int rc; - nvdimm_bus = kzalloc(sizeof(*nvdimm_bus), GFP_KERNEL); + nvdimm_bus = kzalloc_obj(*nvdimm_bus); if (!nvdimm_bus) return NULL; INIT_LIST_HEAD(&nvdimm_bus->list); @@ -736,7 +736,7 @@ int nvdimm_bus_create_ndctl(struct nvdimm_bus *nvdimm_bus) struct device *dev; int rc; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; device_initialize(dev); diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c index 5ba204113fe1..34bd886c04a6 100644 --- a/drivers/nvdimm/core.c +++ b/drivers/nvdimm/core.c @@ -80,7 +80,7 @@ static struct nvdimm_map *alloc_nvdimm_map(struct device *dev, struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev); struct nvdimm_map *nvdimm_map; - nvdimm_map = kzalloc(sizeof(*nvdimm_map), GFP_KERNEL); + nvdimm_map = kzalloc_obj(*nvdimm_map); if (!nvdimm_map) return NULL; diff --git a/drivers/nvdimm/dax_devs.c b/drivers/nvdimm/dax_devs.c index ba4c409ede65..decc70f2fe3f 100644 --- a/drivers/nvdimm/dax_devs.c +++ b/drivers/nvdimm/dax_devs.c @@ -50,7 +50,7 @@ static struct nd_dax *nd_dax_alloc(struct nd_region *nd_region) struct nd_dax *nd_dax; struct device *dev; - nd_dax = kzalloc(sizeof(*nd_dax), GFP_KERNEL); + nd_dax = kzalloc_obj(*nd_dax); if (!nd_dax) return NULL; diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c index 2f6c26cc6a3e..addbd149a9c1 100644 --- a/drivers/nvdimm/dimm.c +++ b/drivers/nvdimm/dimm.c @@ -39,7 +39,7 @@ static int nvdimm_probe(struct device *dev) */ nvdimm_clear_locked(dev); - ndd = kzalloc(sizeof(*ndd), GFP_KERNEL); + ndd = kzalloc_obj(*ndd); if (!ndd) return -ENOMEM; diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c index e1349ef5f8fd..81daeb4d11a9 100644 --- a/drivers/nvdimm/dimm_devs.c +++ b/drivers/nvdimm/dimm_devs.c @@ -575,7 +575,7 @@ struct nvdimm *__nvdimm_create(struct nvdimm_bus *nvdimm_bus, const struct nvdimm_security_ops *sec_ops, const struct nvdimm_fw_ops *fw_ops) { - struct nvdimm *nvdimm = kzalloc(sizeof(*nvdimm), GFP_KERNEL); + struct nvdimm *nvdimm = kzalloc_obj(*nvdimm); struct device *dev; if (!nvdimm) diff --git a/drivers/nvdimm/label.c b/drivers/nvdimm/label.c index 04f4a049599a..4218e3ac4a2a 100644 --- a/drivers/nvdimm/label.c +++ b/drivers/nvdimm/label.c @@ -982,7 +982,7 @@ static int init_labels(struct nd_mapping *nd_mapping, int num_labels) * they can be garbage collected after writing the new labels. */ for (i = old_num_labels; i < num_labels; i++) { - label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL); + label_ent = kzalloc_obj(*label_ent); if (!label_ent) return -ENOMEM; mutex_lock(&nd_mapping->lock); diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index a5edcacfe46d..557fe0cb43e2 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -1530,11 +1530,11 @@ static struct device **create_namespace_io(struct nd_region *nd_region) struct device *dev, **devs; struct resource *res; - nsio = kzalloc(sizeof(*nsio), GFP_KERNEL); + nsio = kzalloc_obj(*nsio); if (!nsio) return NULL; - devs = kcalloc(2, sizeof(struct device *), GFP_KERNEL); + devs = kzalloc_objs(struct device *, 2); if (!devs) { kfree(nsio); return NULL; @@ -1693,7 +1693,7 @@ static struct device *create_namespace_pmem(struct nd_region *nd_region, nsl_uuid_raw(ndd, nd_label)); } - nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); + nspm = kzalloc_obj(*nspm); if (!nspm) return ERR_PTR(-ENOMEM); @@ -1797,7 +1797,7 @@ static struct device *nd_namespace_pmem_create(struct nd_region *nd_region) if (!is_memory(&nd_region->dev)) return NULL; - nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); + nspm = kzalloc_obj(*nspm); if (!nspm) return NULL; @@ -1931,7 +1931,7 @@ static struct device **scan_labels(struct nd_region *nd_region) struct nvdimm_drvdata *ndd = to_ndd(nd_mapping); resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1; - devs = kcalloc(2, sizeof(dev), GFP_KERNEL); + devs = kzalloc_objs(dev, 2); if (!devs) return NULL; @@ -1954,7 +1954,7 @@ static struct device **scan_labels(struct nd_region *nd_region) if (i < count) continue; if (count) { - __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL); + __devs = kzalloc_objs(dev, count + 2); if (!__devs) goto err; memcpy(__devs, devs, sizeof(dev) * count); @@ -1984,7 +1984,7 @@ static struct device **scan_labels(struct nd_region *nd_region) /* Publish a zero-sized namespace for userspace to configure. */ nd_mapping_free_labels(nd_mapping); - nspm = kzalloc(sizeof(*nspm), GFP_KERNEL); + nspm = kzalloc_obj(*nspm); if (!nspm) goto err; dev = &nspm->nsio.common.dev; @@ -2118,7 +2118,7 @@ static int init_active_labels(struct nd_region *nd_region) for (j = 0; j < count; j++) { struct nd_namespace_label *label; - label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL); + label_ent = kzalloc_obj(*label_ent); if (!label_ent) break; label = nd_label_active(ndd, j); diff --git a/drivers/nvdimm/nd_perf.c b/drivers/nvdimm/nd_perf.c index 2b6dc80d8fb5..e0b51438dc9b 100644 --- a/drivers/nvdimm/nd_perf.c +++ b/drivers/nvdimm/nd_perf.c @@ -184,7 +184,7 @@ static int create_cpumask_attr_group(struct nvdimm_pmu *nd_pmu) struct attribute **attrs_group; struct attribute_group *nvdimm_pmu_cpumask_group; - pmu_events_attr = kzalloc(sizeof(*pmu_events_attr), GFP_KERNEL); + pmu_events_attr = kzalloc_obj(*pmu_events_attr); if (!pmu_events_attr) return -ENOMEM; @@ -195,7 +195,7 @@ static int create_cpumask_attr_group(struct nvdimm_pmu *nd_pmu) } /* Allocate memory for cpumask attribute group */ - nvdimm_pmu_cpumask_group = kzalloc(sizeof(*nvdimm_pmu_cpumask_group), GFP_KERNEL); + nvdimm_pmu_cpumask_group = kzalloc_obj(*nvdimm_pmu_cpumask_group); if (!nvdimm_pmu_cpumask_group) { kfree(pmu_events_attr); kfree(attrs_group); diff --git a/drivers/nvdimm/nd_virtio.c b/drivers/nvdimm/nd_virtio.c index af82385be7c6..4176046627be 100644 --- a/drivers/nvdimm/nd_virtio.c +++ b/drivers/nvdimm/nd_virtio.c @@ -55,7 +55,7 @@ static int virtio_pmem_flush(struct nd_region *nd_region) return -EIO; } - req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); + req_data = kmalloc_obj(*req_data); if (!req_data) return -ENOMEM; diff --git a/drivers/nvdimm/of_pmem.c b/drivers/nvdimm/of_pmem.c index 68bddab3fb46..776b7778a12e 100644 --- a/drivers/nvdimm/of_pmem.c +++ b/drivers/nvdimm/of_pmem.c @@ -26,7 +26,7 @@ static int of_pmem_region_probe(struct platform_device *pdev) if (!np) return -ENXIO; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 42b172fc5576..8fa9c16aba7e 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -311,7 +311,7 @@ static struct nd_pfn *nd_pfn_alloc(struct nd_region *nd_region) struct nd_pfn *nd_pfn; struct device *dev; - nd_pfn = kzalloc(sizeof(*nd_pfn), GFP_KERNEL); + nd_pfn = kzalloc_obj(*nd_pfn); if (!nd_pfn) return NULL; diff --git a/drivers/nvdimm/ramdax.c b/drivers/nvdimm/ramdax.c index 954cb7919807..e76fca736d76 100644 --- a/drivers/nvdimm/ramdax.c +++ b/drivers/nvdimm/ramdax.c @@ -40,7 +40,7 @@ static int ramdax_register_region(struct resource *res, struct nd_interleave_set *nd_set; int nid = phys_to_target_node(res->start); - nd_set = kzalloc(sizeof(*nd_set), GFP_KERNEL); + nd_set = kzalloc_obj(*nd_set); if (!nd_set) return -ENOMEM; @@ -80,7 +80,7 @@ static int ramdax_register_dimm(struct resource *res, void *data) struct ramdax_dimm *dimm; int err; - dimm = kzalloc(sizeof(*dimm), GFP_KERNEL); + dimm = kzalloc_obj(*dimm); if (!dimm) return -ENOMEM; diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index 1220530a23b6..e35c2e18518f 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -1005,8 +1005,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, } nd_region = - kzalloc(struct_size(nd_region, mapping, ndr_desc->num_mappings), - GFP_KERNEL); + kzalloc_flex(*nd_region, mapping, ndr_desc->num_mappings); if (!nd_region) return NULL; diff --git a/drivers/nvme/host/auth.c b/drivers/nvme/host/auth.c index 8f3ccb317e4d..405e7c03b1cf 100644 --- a/drivers/nvme/host/auth.c +++ b/drivers/nvme/host/auth.c @@ -1083,8 +1083,7 @@ int nvme_auth_init_ctrl(struct nvme_ctrl *ctrl) if (!ctrl->opts->dhchap_secret && !ctrl->opts->dhchap_ctrl_secret) return 0; - ctrl->dhchap_ctxs = kvcalloc(ctrl_max_dhchaps(ctrl), - sizeof(*chap), GFP_KERNEL); + ctrl->dhchap_ctxs = kvzalloc_objs(*chap, ctrl_max_dhchaps(ctrl)); if (!ctrl->dhchap_ctxs) { ret = -ENOMEM; goto err_free_dhchap_ctrl_secret; diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 19b67cf5d550..766e9cc4ffca 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1469,7 +1469,7 @@ static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) c.identify.opcode = nvme_admin_identify; c.identify.cns = NVME_ID_CNS_CTRL; - *id = kmalloc(sizeof(struct nvme_id_ctrl), GFP_KERNEL); + *id = kmalloc_obj(struct nvme_id_ctrl); if (!*id) return -ENOMEM; @@ -1599,7 +1599,7 @@ int nvme_identify_ns(struct nvme_ctrl *ctrl, unsigned nsid, c.identify.nsid = cpu_to_le32(nsid); c.identify.cns = NVME_ID_CNS_NS; - *id = kmalloc(sizeof(**id), GFP_KERNEL); + *id = kmalloc_obj(**id); if (!*id) return -ENOMEM; @@ -1663,7 +1663,7 @@ static int nvme_ns_info_from_id_cs_indep(struct nvme_ctrl *ctrl, }; int ret; - id = kmalloc(sizeof(*id), GFP_KERNEL); + id = kmalloc_obj(*id); if (!id) return -ENOMEM; @@ -1923,7 +1923,7 @@ static int nvme_identify_ns_nvm(struct nvme_ctrl *ctrl, unsigned int nsid, struct nvme_id_ns_nvm *nvm; int ret; - nvm = kzalloc(sizeof(*nvm), GFP_KERNEL); + nvm = kzalloc_obj(*nvm); if (!nvm) return -ENOMEM; @@ -2046,14 +2046,10 @@ static u32 nvme_configure_atomic_write(struct nvme_ns *ns, if (id->nabspf) boundary = (le16_to_cpu(id->nabspf) + 1) * bs; } else { - /* - * Use the controller wide atomic write unit. This sucks - * because the limit is defined in terms of logical blocks while - * namespaces can have different formats, and because there is - * no clear language in the specification prohibiting different - * values for different controllers in the subsystem. - */ - atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs; + if (ns->ctrl->awupf) + dev_info_once(ns->ctrl->device, + "AWUPF ignored, only NAWUPF accepted\n"); + atomic_bs = bs; } lim->atomic_write_hw_max = atomic_bs; @@ -2784,7 +2780,7 @@ static int nvme_configure_host_options(struct nvme_ctrl *ctrl) if (!acre && !lbafee) return 0; - host = kzalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc_obj(*host); if (!host) return 0; @@ -2873,7 +2869,7 @@ static int nvme_configure_apst(struct nvme_ctrl *ctrl) return 0; } - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return 0; @@ -3208,7 +3204,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) struct nvme_subsystem *subsys, *found; int ret; - subsys = kzalloc(sizeof(*subsys), GFP_KERNEL); + subsys = kzalloc_obj(*subsys); if (!subsys) return -ENOMEM; @@ -3222,7 +3218,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) memcpy(subsys->model, id->mn, sizeof(subsys->model)); subsys->vendor_id = le16_to_cpu(id->vid); subsys->cmic = id->cmic; - subsys->awupf = le16_to_cpu(id->awupf); /* Versions prior to 1.4 don't necessarily report a valid type */ if (id->cntrltype == NVME_CTRL_DISC || @@ -3326,7 +3321,7 @@ static int nvme_get_effects_log(struct nvme_ctrl *ctrl, u8 csi, if (cel) goto out; - cel = kzalloc(sizeof(*cel), GFP_KERNEL); + cel = kzalloc_obj(*cel); if (!cel) return -ENOMEM; @@ -3379,7 +3374,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl) test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags)) return 0; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) return -ENOMEM; @@ -3408,7 +3403,7 @@ static int nvme_init_effects_log(struct nvme_ctrl *ctrl, { struct nvme_effects_log *effects, *old; - effects = kzalloc(sizeof(*effects), GFP_KERNEL); + effects = kzalloc_obj(*effects); if (!effects) return -ENOMEM; @@ -3655,6 +3650,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) dev_pm_qos_expose_latency_tolerance(ctrl->device); else if (!ctrl->apst_enabled && prev_apst_enabled) dev_pm_qos_hide_latency_tolerance(ctrl->device); + ctrl->awupf = le16_to_cpu(id->awupf); out_free: kfree(id); return ret; @@ -4186,13 +4182,6 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info) nvme_mpath_add_disk(ns, info->anagrpid); nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name); - /* - * Set ns->disk->device->driver_data to ns so we can access - * ns->head->passthru_err_log_enabled in - * nvme_io_passthru_err_log_enabled_[store | show](). - */ - dev_set_drvdata(disk_to_dev(ns->disk), ns); - return; out_cleanup_ns_from_list: @@ -4688,7 +4677,7 @@ static void nvme_get_fw_slot_info(struct nvme_ctrl *ctrl) struct nvme_fw_slot_info_log *log; u8 next_fw_slot, cur_fw_slot; - log = kmalloc(sizeof(*log), GFP_KERNEL); + log = kmalloc_obj(*log); if (!log) return; @@ -4845,7 +4834,6 @@ EXPORT_SYMBOL_GPL(nvme_complete_async_event); int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, const struct blk_mq_ops *ops, unsigned int cmd_size) { - struct queue_limits lim = {}; int ret; memset(set, 0, sizeof(*set)); @@ -4865,7 +4853,14 @@ int nvme_alloc_admin_tag_set(struct nvme_ctrl *ctrl, struct blk_mq_tag_set *set, if (ret) return ret; - ctrl->admin_q = blk_mq_alloc_queue(set, &lim, NULL); + /* + * If a previous admin queue exists (e.g., from before a reset), + * put it now before allocating a new one to avoid orphaning it. + */ + if (ctrl->admin_q) + blk_put_queue(ctrl->admin_q); + + ctrl->admin_q = blk_mq_alloc_queue(set, NULL, NULL); if (IS_ERR(ctrl->admin_q)) { ret = PTR_ERR(ctrl->admin_q); goto out_free_tagset; diff --git a/drivers/nvme/host/fabrics.c b/drivers/nvme/host/fabrics.c index 55a8afd2efd5..ac3d4f400601 100644 --- a/drivers/nvme/host/fabrics.c +++ b/drivers/nvme/host/fabrics.c @@ -26,7 +26,7 @@ static struct nvmf_host *nvmf_host_alloc(const char *hostnqn, uuid_t *id) { struct nvmf_host *host; - host = kmalloc(sizeof(*host), GFP_KERNEL); + host = kmalloc_obj(*host); if (!host) return NULL; @@ -396,7 +396,7 @@ static struct nvmf_connect_data *nvmf_connect_data_prep(struct nvme_ctrl *ctrl, { struct nvmf_connect_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; @@ -1290,8 +1290,8 @@ void nvmf_free_options(struct nvmf_ctrl_options *opts) kfree(opts->subsysnqn); kfree(opts->host_traddr); kfree(opts->host_iface); - kfree(opts->dhchap_secret); - kfree(opts->dhchap_ctrl_secret); + kfree_sensitive(opts->dhchap_secret); + kfree_sensitive(opts->dhchap_ctrl_secret); kfree(opts); } EXPORT_SYMBOL_GPL(nvmf_free_options); @@ -1312,7 +1312,7 @@ nvmf_create_ctrl(struct device *dev, const char *buf) struct nvme_ctrl *ctrl; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c index 6948de3f438a..e1bb4707183c 100644 --- a/drivers/nvme/host/fc.c +++ b/drivers/nvme/host/fc.c @@ -1724,15 +1724,15 @@ nvme_fc_rcv_ls_req(struct nvme_fc_remote_port *portptr, goto out_put; } - lsop = kzalloc(sizeof(*lsop), GFP_KERNEL); + lsop = kzalloc_obj(*lsop); if (!lsop) { nvme_fc_rcv_ls_req_err_msg(lport, w0); ret = -ENOMEM; goto out_put; } - lsop->rqstbuf = kzalloc(sizeof(*lsop->rqstbuf), GFP_KERNEL); - lsop->rspbuf = kzalloc(sizeof(*lsop->rspbuf), GFP_KERNEL); + lsop->rqstbuf = kzalloc_obj(*lsop->rqstbuf); + lsop->rspbuf = kzalloc_obj(*lsop->rspbuf); if (!lsop->rqstbuf || !lsop->rspbuf) { nvme_fc_rcv_ls_req_err_msg(lport, w0); ret = -ENOMEM; @@ -3443,7 +3443,7 @@ nvme_fc_alloc_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, goto out_fail; } - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) { ret = -ENOMEM; goto out_fail; @@ -3497,8 +3497,8 @@ nvme_fc_alloc_ctrl(struct device *dev, struct nvmf_ctrl_options *opts, ctrl->ctrl.cntlid = 0xffff; ret = -ENOMEM; - ctrl->queues = kcalloc(ctrl->ctrl.queue_count, - sizeof(struct nvme_fc_queue), GFP_KERNEL); + ctrl->queues = kzalloc_objs(struct nvme_fc_queue, + ctrl->ctrl.queue_count); if (!ctrl->queues) goto out_free_ida; diff --git a/drivers/nvme/host/hwmon.c b/drivers/nvme/host/hwmon.c index 89a1a1043d63..406203d8b9ad 100644 --- a/drivers/nvme/host/hwmon.c +++ b/drivers/nvme/host/hwmon.c @@ -230,11 +230,11 @@ int nvme_hwmon_init(struct nvme_ctrl *ctrl) struct device *hwmon; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; - data->log = kzalloc(sizeof(*data->log), GFP_KERNEL); + data->log = kzalloc_obj(*data->log); if (!data->log) { err = -ENOMEM; goto err_free_data; diff --git a/drivers/nvme/host/ioctl.c b/drivers/nvme/host/ioctl.c index fb62633ccbb0..8844bbd39515 100644 --- a/drivers/nvme/host/ioctl.c +++ b/drivers/nvme/host/ioctl.c @@ -447,7 +447,8 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns, struct io_uring_cmd *ioucmd, unsigned int issue_flags, bool vec) { struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); - const struct nvme_uring_cmd *cmd = io_uring_sqe_cmd(ioucmd->sqe); + const struct nvme_uring_cmd *cmd = io_uring_sqe128_cmd(ioucmd->sqe, + struct nvme_uring_cmd); struct request_queue *q = ns ? ns->queue : ctrl->admin_q; struct nvme_uring_data d; struct nvme_command c; diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 174027d1cc19..fc6800a9f7f9 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -1300,7 +1300,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) mutex_lock(&head->subsys->lock); /* * We are called when all paths have been removed, and at that point - * head->list is expected to be empty. However, nvme_remove_ns() and + * head->list is expected to be empty. However, nvme_ns_remove() and * nvme_init_ns_head() can run concurrently and so if head->delayed_ * removal_secs is configured, it is possible that by the time we reach * this point, head->list may no longer be empty. Therefore, we recheck @@ -1310,13 +1310,11 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) if (!list_empty(&head->list)) goto out; - if (head->delayed_removal_secs) { - /* - * Ensure that no one could remove this module while the head - * remove work is pending. - */ - if (!try_module_get(THIS_MODULE)) - goto out; + /* + * Ensure that no one could remove this module while the head + * remove work is pending. + */ + if (head->delayed_removal_secs && try_module_get(THIS_MODULE)) { mod_delayed_work(nvme_wq, &head->remove_work, head->delayed_removal_secs * HZ); } else { diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 9a5f28c5103c..9971045dbc05 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -180,6 +180,60 @@ enum nvme_quirks { NVME_QUIRK_DMAPOOL_ALIGN_512 = (1 << 22), }; +static inline char *nvme_quirk_name(enum nvme_quirks q) +{ + switch (q) { + case NVME_QUIRK_STRIPE_SIZE: + return "stripe_size"; + case NVME_QUIRK_IDENTIFY_CNS: + return "identify_cns"; + case NVME_QUIRK_DEALLOCATE_ZEROES: + return "deallocate_zeroes"; + case NVME_QUIRK_DELAY_BEFORE_CHK_RDY: + return "delay_before_chk_rdy"; + case NVME_QUIRK_NO_APST: + return "no_apst"; + case NVME_QUIRK_NO_DEEPEST_PS: + return "no_deepest_ps"; + case NVME_QUIRK_QDEPTH_ONE: + return "qdepth_one"; + case NVME_QUIRK_MEDIUM_PRIO_SQ: + return "medium_prio_sq"; + case NVME_QUIRK_IGNORE_DEV_SUBNQN: + return "ignore_dev_subnqn"; + case NVME_QUIRK_DISABLE_WRITE_ZEROES: + return "disable_write_zeroes"; + case NVME_QUIRK_SIMPLE_SUSPEND: + return "simple_suspend"; + case NVME_QUIRK_SINGLE_VECTOR: + return "single_vector"; + case NVME_QUIRK_128_BYTES_SQES: + return "128_bytes_sqes"; + case NVME_QUIRK_SHARED_TAGS: + return "shared_tags"; + case NVME_QUIRK_NO_TEMP_THRESH_CHANGE: + return "no_temp_thresh_change"; + case NVME_QUIRK_NO_NS_DESC_LIST: + return "no_ns_desc_list"; + case NVME_QUIRK_DMA_ADDRESS_BITS_48: + return "dma_address_bits_48"; + case NVME_QUIRK_SKIP_CID_GEN: + return "skip_cid_gen"; + case NVME_QUIRK_BOGUS_NID: + return "bogus_nid"; + case NVME_QUIRK_NO_SECONDARY_TEMP_THRESH: + return "no_secondary_temp_thresh"; + case NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND: + return "force_no_simple_suspend"; + case NVME_QUIRK_BROKEN_MSI: + return "broken_msi"; + case NVME_QUIRK_DMAPOOL_ALIGN_512: + return "dmapool_align_512"; + } + + return "unknown"; +} + /* * Common request structure for NVMe passthrough. All drivers must have * this structure as the first member of their request-private data. @@ -410,6 +464,8 @@ struct nvme_ctrl { enum nvme_ctrl_type cntrltype; enum nvme_dctype dctype; + + u16 awupf; /* 0's based value. */ }; static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) @@ -442,7 +498,6 @@ struct nvme_subsystem { u8 cmic; enum nvme_subsys_type subtype; u16 vendor_id; - u16 awupf; /* 0's based value. */ struct ida ns_ida; #ifdef CONFIG_NVME_MULTIPATH enum nvme_iopolicy iopolicy; diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 80df992d1ae8..b78ba239c8ea 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -72,6 +72,13 @@ static_assert(MAX_PRP_RANGE / NVME_CTRL_PAGE_SIZE <= (1 /* prp1 */ + NVME_MAX_NR_DESCRIPTORS * PRPS_PER_PAGE)); +struct quirk_entry { + u16 vendor_id; + u16 dev_id; + u32 enabled_quirks; + u32 disabled_quirks; +}; + static int use_threaded_interrupts; module_param(use_threaded_interrupts, int, 0444); @@ -102,6 +109,143 @@ static unsigned int io_queue_depth = 1024; module_param_cb(io_queue_depth, &io_queue_depth_ops, &io_queue_depth, 0644); MODULE_PARM_DESC(io_queue_depth, "set io queue depth, should >= 2 and < 4096"); +static struct quirk_entry *nvme_pci_quirk_list; +static unsigned int nvme_pci_quirk_count; + +/* Helper to parse individual quirk names */ +static int nvme_parse_quirk_names(char *quirk_str, struct quirk_entry *entry) +{ + int i; + size_t field_len; + bool disabled, found; + char *p = quirk_str, *field; + + while ((field = strsep(&p, ",")) && *field) { + disabled = false; + found = false; + + if (*field == '^') { + /* Skip the '^' character */ + disabled = true; + field++; + } + + field_len = strlen(field); + for (i = 0; i < 32; i++) { + unsigned int bit = 1U << i; + char *q_name = nvme_quirk_name(bit); + size_t q_len = strlen(q_name); + + if (!strcmp(q_name, "unknown")) + break; + + if (!strcmp(q_name, field) && + q_len == field_len) { + if (disabled) + entry->disabled_quirks |= bit; + else + entry->enabled_quirks |= bit; + found = true; + break; + } + } + + if (!found) { + pr_err("nvme: unrecognized quirk %s\n", field); + return -EINVAL; + } + } + return 0; +} + +/* Helper to parse a single VID:DID:quirk_names entry */ +static int nvme_parse_quirk_entry(char *s, struct quirk_entry *entry) +{ + char *field; + + field = strsep(&s, ":"); + if (!field || kstrtou16(field, 16, &entry->vendor_id)) + return -EINVAL; + + field = strsep(&s, ":"); + if (!field || kstrtou16(field, 16, &entry->dev_id)) + return -EINVAL; + + field = strsep(&s, ":"); + if (!field) + return -EINVAL; + + return nvme_parse_quirk_names(field, entry); +} + +static int quirks_param_set(const char *value, const struct kernel_param *kp) +{ + int count, err, i; + struct quirk_entry *qlist; + char *field, *val, *sep_ptr; + + err = param_set_copystring(value, kp); + if (err) + return err; + + val = kstrdup(value, GFP_KERNEL); + if (!val) + return -ENOMEM; + + if (!*val) + goto out_free_val; + + count = 1; + for (i = 0; val[i]; i++) { + if (val[i] == '-') + count++; + } + + qlist = kcalloc(count, sizeof(*qlist), GFP_KERNEL); + if (!qlist) { + err = -ENOMEM; + goto out_free_val; + } + + i = 0; + sep_ptr = val; + while ((field = strsep(&sep_ptr, "-"))) { + if (nvme_parse_quirk_entry(field, &qlist[i])) { + pr_err("nvme: failed to parse quirk string %s\n", + value); + goto out_free_qlist; + } + + i++; + } + + kfree(nvme_pci_quirk_list); + nvme_pci_quirk_count = count; + nvme_pci_quirk_list = qlist; + goto out_free_val; + +out_free_qlist: + kfree(qlist); +out_free_val: + kfree(val); + return err; +} + +static char quirks_param[128]; +static const struct kernel_param_ops quirks_param_ops = { + .set = quirks_param_set, + .get = param_get_string, +}; + +static struct kparam_string quirks_param_string = { + .maxlen = sizeof(quirks_param), + .string = quirks_param, +}; + +module_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0444); +MODULE_PARM_DESC(quirks, "Enable/disable NVMe quirks by specifying " + "quirks=VID:DID:quirk_names"); + static int io_queue_count_set(const char *val, const struct kernel_param *kp) { unsigned int n; @@ -400,7 +544,7 @@ static void nvme_dbbuf_set(struct nvme_dev *dev) /* Free memory and continue on */ nvme_dbbuf_dma_free(dev); - for (i = 1; i <= dev->online_queues; i++) + for (i = 1; i < dev->online_queues; i++) nvme_dbbuf_free(&dev->queues[i]); } } @@ -1481,14 +1625,16 @@ static irqreturn_t nvme_irq_check(int irq, void *data) static void nvme_poll_irqdisable(struct nvme_queue *nvmeq) { struct pci_dev *pdev = to_pci_dev(nvmeq->dev->dev); + int irq; WARN_ON_ONCE(test_bit(NVMEQ_POLLED, &nvmeq->flags)); - disable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)); + irq = pci_irq_vector(pdev, nvmeq->cq_vector); + disable_irq(irq); spin_lock(&nvmeq->cq_poll_lock); nvme_poll_cq(nvmeq, NULL); spin_unlock(&nvmeq->cq_poll_lock); - enable_irq(pci_irq_vector(pdev, nvmeq->cq_vector)); + enable_irq(irq); } static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) @@ -1496,7 +1642,8 @@ static int nvme_poll(struct blk_mq_hw_ctx *hctx, struct io_comp_batch *iob) struct nvme_queue *nvmeq = hctx->driver_data; bool found; - if (!nvme_cqe_pending(nvmeq)) + if (!test_bit(NVMEQ_POLLED, &nvmeq->flags) || + !nvme_cqe_pending(nvmeq)) return 0; spin_lock(&nvmeq->cq_poll_lock); @@ -2447,7 +2594,7 @@ static int nvme_alloc_host_mem_multi(struct nvme_dev *dev, u64 preferred, if (!descs) goto out; - bufs = kcalloc(max_entries, sizeof(*bufs), GFP_KERNEL); + bufs = kzalloc_objs(*bufs, max_entries); if (!bufs) goto out_free_descs; @@ -2774,7 +2921,25 @@ static int nvme_setup_io_queues(struct nvme_dev *dev) dev->nr_write_queues = write_queues; dev->nr_poll_queues = poll_queues; - nr_io_queues = dev->nr_allocated_queues - 1; + if (dev->ctrl.tagset) { + /* + * The set's maps are allocated only once at initialization + * time. We can't add special queues later if their mq_map + * wasn't preallocated. + */ + if (dev->ctrl.tagset->nr_maps < 3) + dev->nr_poll_queues = 0; + if (dev->ctrl.tagset->nr_maps < 2) + dev->nr_write_queues = 0; + } + + /* + * The initial number of allocated queue slots may be too large if the + * user reduced the special queue parameters. Cap the value to the + * number we need for this round. + */ + nr_io_queues = min(nvme_max_io_queues(dev), + dev->nr_allocated_queues - 1); result = nvme_set_queue_count(&dev->ctrl, &nr_io_queues); if (result < 0) return result; @@ -3458,12 +3623,25 @@ static unsigned long check_vendor_combination_bug(struct pci_dev *pdev) return 0; } +static struct quirk_entry *detect_dynamic_quirks(struct pci_dev *pdev) +{ + int i; + + for (i = 0; i < nvme_pci_quirk_count; i++) + if (pdev->vendor == nvme_pci_quirk_list[i].vendor_id && + pdev->device == nvme_pci_quirk_list[i].dev_id) + return &nvme_pci_quirk_list[i]; + + return NULL; +} + static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, const struct pci_device_id *id) { unsigned long quirks = id->driver_data; int node = dev_to_node(&pdev->dev); struct nvme_dev *dev; + struct quirk_entry *qentry; int ret = -ENOMEM; dev = kzalloc_node(struct_size(dev, descriptor_pools, nr_node_ids), @@ -3495,6 +3673,11 @@ static struct nvme_dev *nvme_pci_alloc_dev(struct pci_dev *pdev, "platform quirk: setting simple suspend\n"); quirks |= NVME_QUIRK_SIMPLE_SUSPEND; } + qentry = detect_dynamic_quirks(pdev); + if (qentry) { + quirks |= qentry->enabled_quirks; + quirks &= ~qentry->disabled_quirks; + } ret = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, quirks); if (ret) @@ -4095,6 +4278,7 @@ static int __init nvme_init(void) static void __exit nvme_exit(void) { + kfree(nvme_pci_quirk_list); pci_unregister_driver(&nvme_driver); flush_workqueue(nvme_wq); } diff --git a/drivers/nvme/host/pr.c b/drivers/nvme/host/pr.c index ad2ecc2f49a9..fe7dbe264815 100644 --- a/drivers/nvme/host/pr.c +++ b/drivers/nvme/host/pr.c @@ -242,7 +242,7 @@ static int nvme_pr_read_keys(struct block_device *bdev, if (rse_len > U32_MAX) return -EINVAL; - rse = kzalloc(rse_len, GFP_KERNEL); + rse = kvzalloc(rse_len, GFP_KERNEL); if (!rse) return -ENOMEM; @@ -267,7 +267,7 @@ static int nvme_pr_read_keys(struct block_device *bdev, } free_rse: - kfree(rse); + kvfree(rse); return ret; } diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index 35c0822edb2d..57111139e84f 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -215,7 +215,7 @@ static struct nvme_rdma_qe *nvme_rdma_alloc_ring(struct ib_device *ibdev, struct nvme_rdma_qe *ring; int i; - ring = kcalloc(ib_queue_size, sizeof(struct nvme_rdma_qe), GFP_KERNEL); + ring = kzalloc_objs(struct nvme_rdma_qe, ib_queue_size); if (!ring) return NULL; @@ -300,7 +300,7 @@ static int nvme_rdma_init_request(struct blk_mq_tag_set *set, struct nvme_rdma_queue *queue = &ctrl->queues[queue_idx]; nvme_req(rq)->ctrl = &ctrl->ctrl; - req->sqe.data = kzalloc(sizeof(struct nvme_command), GFP_KERNEL); + req->sqe.data = kzalloc_obj(struct nvme_command); if (!req->sqe.data) return -ENOMEM; @@ -375,7 +375,7 @@ nvme_rdma_find_get_device(struct rdma_cm_id *cm_id) goto out_unlock; } - ndev = kzalloc(sizeof(*ndev), GFP_KERNEL); + ndev = kzalloc_obj(*ndev); if (!ndev) goto out_err; @@ -2240,7 +2240,7 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev, struct nvme_rdma_ctrl *ctrl; int ret; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return ERR_PTR(-ENOMEM); ctrl->ctrl.opts = opts; @@ -2290,8 +2290,7 @@ static struct nvme_rdma_ctrl *nvme_rdma_alloc_ctrl(struct device *dev, ctrl->ctrl.kato = opts->kato; ret = -ENOMEM; - ctrl->queues = kcalloc(ctrl->ctrl.queue_count, sizeof(*ctrl->queues), - GFP_KERNEL); + ctrl->queues = kzalloc_objs(*ctrl->queues, ctrl->ctrl.queue_count); if (!ctrl->queues) goto out_free_ctrl; diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c index 29430949ce2f..16c6fea4b2db 100644 --- a/drivers/nvme/host/sysfs.c +++ b/drivers/nvme/host/sysfs.c @@ -601,6 +601,28 @@ static ssize_t dctype_show(struct device *dev, } static DEVICE_ATTR_RO(dctype); +static ssize_t quirks_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0, i; + struct nvme_ctrl *ctrl = dev_get_drvdata(dev); + unsigned long quirks = ctrl->quirks; + + if (!quirks) + return sysfs_emit(buf, "none\n"); + + for (i = 0; quirks; ++i) { + if (quirks & 1) { + count += sysfs_emit_at(buf, count, "%s\n", + nvme_quirk_name(BIT(i))); + } + quirks >>= 1; + } + + return count; +} +static DEVICE_ATTR_RO(quirks); + #ifdef CONFIG_NVME_HOST_AUTH static ssize_t nvme_ctrl_dhchap_secret_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -742,6 +764,7 @@ static struct attribute *nvme_dev_attrs[] = { &dev_attr_kato.attr, &dev_attr_cntrltype.attr, &dev_attr_dctype.attr, + &dev_attr_quirks.attr, #ifdef CONFIG_NVME_HOST_AUTH &dev_attr_dhchap_secret.attr, &dev_attr_dhchap_ctrl_secret.attr, diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 69cb04406b47..243dab830dc8 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -25,7 +25,8 @@ struct nvme_tcp_queue; -/* Define the socket priority to use for connections were it is desirable +/* + * Define the socket priority to use for connections where it is desirable * that the NIC consider performing optimized packet processing or filtering. * A non-zero value being sufficient to indicate general consideration of any * possible optimization. Making it a module param allows for alternative @@ -926,7 +927,7 @@ static int nvme_tcp_recv_data(struct nvme_tcp_queue *queue, struct sk_buff *skb, req->curr_bio = req->curr_bio->bi_next; /* - * If we don`t have any bios it means that controller + * If we don't have any bios it means the controller * sent more data than we requested, hence error */ if (!req->curr_bio) { @@ -1467,11 +1468,11 @@ static int nvme_tcp_init_connection(struct nvme_tcp_queue *queue) u32 maxh2cdata; int ret; - icreq = kzalloc(sizeof(*icreq), GFP_KERNEL); + icreq = kzalloc_obj(*icreq); if (!icreq) return -ENOMEM; - icresp = kzalloc(sizeof(*icresp), GFP_KERNEL); + icresp = kzalloc_obj(*icresp); if (!icresp) { ret = -ENOMEM; goto free_icreq; @@ -2891,7 +2892,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev, struct nvme_tcp_ctrl *ctrl; int ret; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return ERR_PTR(-ENOMEM); @@ -2949,8 +2950,7 @@ static struct nvme_tcp_ctrl *nvme_tcp_alloc_ctrl(struct device *dev, goto out_free_ctrl; } - ctrl->queues = kcalloc(ctrl->ctrl.queue_count, sizeof(*ctrl->queues), - GFP_KERNEL); + ctrl->queues = kzalloc_objs(*ctrl->queues, ctrl->ctrl.queue_count); if (!ctrl->queues) { ret = -ENOMEM; goto out_free_ctrl; diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c index deea2dbef5b8..8ed1b6a33454 100644 --- a/drivers/nvme/host/zns.c +++ b/drivers/nvme/host/zns.c @@ -13,7 +13,7 @@ static int nvme_set_max_append(struct nvme_ctrl *ctrl) struct nvme_id_ctrl_zns *id; int status; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) return -ENOMEM; @@ -64,7 +64,7 @@ int nvme_query_zone_info(struct nvme_ns *ns, unsigned lbaf, return status; } - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) return -ENOMEM; diff --git a/drivers/nvme/target/admin-cmd.c b/drivers/nvme/target/admin-cmd.c index 5e366502fb75..ca5b08ce1211 100644 --- a/drivers/nvme/target/admin-cmd.c +++ b/drivers/nvme/target/admin-cmd.c @@ -203,7 +203,7 @@ static void nvmet_execute_get_supported_log_pages(struct nvmet_req *req) struct nvme_supported_log *logs; u16 status; - logs = kzalloc(sizeof(*logs), GFP_KERNEL); + logs = kzalloc_obj(*logs); if (!logs) { status = NVME_SC_INTERNAL; goto out; @@ -308,7 +308,7 @@ static void nvmet_execute_get_log_page_rmi(struct nvmet_req *req) goto out; } - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) goto out; @@ -334,7 +334,7 @@ static void nvmet_execute_get_log_page_smart(struct nvmet_req *req) if (req->transfer_len != sizeof(*log)) goto out; - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) goto out; @@ -409,7 +409,7 @@ static void nvmet_execute_get_log_cmd_effects_ns(struct nvmet_req *req) struct nvme_effects_log *log; u16 status = NVME_SC_SUCCESS; - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) { status = NVME_SC_INTERNAL; goto out; @@ -504,7 +504,7 @@ static void nvmet_execute_get_log_page_endgrp(struct nvmet_req *req) if (status) goto out; - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) { status = NVME_SC_INTERNAL; goto out; @@ -542,8 +542,7 @@ static void nvmet_execute_get_log_page_ana(struct nvmet_req *req) u16 status; status = NVME_SC_INTERNAL; - desc = kmalloc(struct_size(desc, nsids, NVMET_MAX_NAMESPACES), - GFP_KERNEL); + desc = kmalloc_flex(*desc, nsids, NVMET_MAX_NAMESPACES); if (!desc) goto out; @@ -581,7 +580,7 @@ static void nvmet_execute_get_log_page_features(struct nvmet_req *req) struct nvme_supported_features_log *features; u16 status; - features = kzalloc(sizeof(*features), GFP_KERNEL); + features = kzalloc_obj(*features); if (!features) { status = NVME_SC_INTERNAL; goto out; @@ -660,7 +659,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) mutex_unlock(&subsys->lock); } - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; @@ -809,7 +808,7 @@ static void nvmet_execute_identify_ns(struct nvmet_req *req) goto out; } - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; @@ -1053,7 +1052,7 @@ static void nvme_execute_identify_ns_nvm(struct nvmet_req *req) if (status) goto out; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; @@ -1073,7 +1072,7 @@ static void nvmet_execute_id_cs_indep(struct nvmet_req *req) if (status) goto out; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; @@ -1586,7 +1585,7 @@ void nvmet_execute_async_event(struct nvmet_req *req) ctrl->async_event_cmds[ctrl->nr_async_event_cmds++] = req; mutex_unlock(&ctrl->lock); - queue_work(nvmet_wq, &ctrl->async_event_work); + queue_work(nvmet_aen_wq, &ctrl->async_event_work); } void nvmet_execute_keep_alive(struct nvmet_req *req) diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c index 127dae51fec1..3088e044dbcb 100644 --- a/drivers/nvme/target/configfs.c +++ b/drivers/nvme/target/configfs.c @@ -1040,7 +1040,7 @@ static int nvmet_port_subsys_allow_link(struct config_item *parent, return -EINVAL; } subsys = to_subsys(target); - link = kmalloc(sizeof(*link), GFP_KERNEL); + link = kmalloc_obj(*link); if (!link) return -ENOMEM; link->subsys = subsys; @@ -1120,7 +1120,7 @@ static int nvmet_allowed_hosts_allow_link(struct config_item *parent, } host = to_host(target); - link = kmalloc(sizeof(*link), GFP_KERNEL); + link = kmalloc_obj(*link); if (!link) return -ENOMEM; link->host = host; @@ -1825,7 +1825,7 @@ static struct config_group *nvmet_referral_make( { struct nvmet_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); @@ -1943,7 +1943,7 @@ static struct config_group *nvmet_ana_groups_make_group( goto out; ret = -ENOMEM; - grp = kzalloc(sizeof(*grp), GFP_KERNEL); + grp = kzalloc_obj(*grp); if (!grp) goto out; grp->port = port; @@ -2022,12 +2022,11 @@ static struct config_group *nvmet_ports_make(struct config_group *group, if (kstrtou16(name, 0, &portid)) return ERR_PTR(-EINVAL); - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); - port->ana_state = kcalloc(NVMET_MAX_ANAGRPS + 1, - sizeof(*port->ana_state), GFP_KERNEL); + port->ana_state = kzalloc_objs(*port->ana_state, NVMET_MAX_ANAGRPS + 1); if (!port->ana_state) { kfree(port); return ERR_PTR(-ENOMEM); @@ -2257,7 +2256,7 @@ static struct config_group *nvmet_hosts_make_group(struct config_group *group, { struct nvmet_host *host; - host = kzalloc(sizeof(*host), GFP_KERNEL); + host = kzalloc_obj(*host); if (!host) return ERR_PTR(-ENOMEM); diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index eab3e4fc0f74..9238e13bd480 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -27,6 +27,8 @@ static DEFINE_IDA(cntlid_ida); struct workqueue_struct *nvmet_wq; EXPORT_SYMBOL_GPL(nvmet_wq); +struct workqueue_struct *nvmet_aen_wq; +EXPORT_SYMBOL_GPL(nvmet_aen_wq); /* * This read/write semaphore is used to synchronize access to configuration @@ -194,7 +196,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, { struct nvmet_async_event *aen; - aen = kmalloc(sizeof(*aen), GFP_KERNEL); + aen = kmalloc_obj(*aen); if (!aen) return; @@ -206,7 +208,7 @@ void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type, list_add_tail(&aen->entry, &ctrl->async_events); mutex_unlock(&ctrl->lock); - queue_work(nvmet_wq, &ctrl->async_event_work); + queue_work(nvmet_aen_wq, &ctrl->async_event_work); } static void nvmet_add_to_changed_ns_log(struct nvmet_ctrl *ctrl, __le32 nsid) @@ -693,7 +695,7 @@ struct nvmet_ns *nvmet_ns_alloc(struct nvmet_subsys *subsys, u32 nsid) if (subsys->nr_namespaces == NVMET_MAX_NAMESPACES) goto out_unlock; - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_obj(*ns); if (!ns) goto out_unlock; @@ -1609,7 +1611,7 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) up_read(&nvmet_config_sem); args->status = NVME_SC_INTERNAL; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) goto out_put_subsystem; mutex_init(&ctrl->lock); @@ -1642,14 +1644,11 @@ struct nvmet_ctrl *nvmet_alloc_ctrl(struct nvmet_alloc_ctrl_args *args) if (!ctrl->changed_ns_list) goto out_free_ctrl; - ctrl->sqs = kcalloc(subsys->max_qid + 1, - sizeof(struct nvmet_sq *), - GFP_KERNEL); + ctrl->sqs = kzalloc_objs(struct nvmet_sq *, subsys->max_qid + 1); if (!ctrl->sqs) goto out_free_changed_ns_list; - ctrl->cqs = kcalloc(subsys->max_qid + 1, sizeof(struct nvmet_cq *), - GFP_KERNEL); + ctrl->cqs = kzalloc_objs(struct nvmet_cq *, subsys->max_qid + 1); if (!ctrl->cqs) goto out_free_sqs; @@ -1829,7 +1828,7 @@ struct nvmet_subsys *nvmet_subsys_alloc(const char *subsysnqn, char serial[NVMET_SN_MAX_SIZE / 2]; int ret; - subsys = kzalloc(sizeof(*subsys), GFP_KERNEL); + subsys = kzalloc_obj(*subsys); if (!subsys) return ERR_PTR(-ENOMEM); @@ -1959,9 +1958,14 @@ static int __init nvmet_init(void) if (!nvmet_wq) goto out_free_buffered_work_queue; + nvmet_aen_wq = alloc_workqueue("nvmet-aen-wq", + WQ_MEM_RECLAIM | WQ_UNBOUND, 0); + if (!nvmet_aen_wq) + goto out_free_nvmet_work_queue; + error = nvmet_init_debugfs(); if (error) - goto out_free_nvmet_work_queue; + goto out_free_nvmet_aen_work_queue; error = nvmet_init_discovery(); if (error) @@ -1977,6 +1981,8 @@ static int __init nvmet_init(void) nvmet_exit_discovery(); out_exit_debugfs: nvmet_exit_debugfs(); +out_free_nvmet_aen_work_queue: + destroy_workqueue(nvmet_aen_wq); out_free_nvmet_work_queue: destroy_workqueue(nvmet_wq); out_free_buffered_work_queue: @@ -1994,6 +2000,7 @@ static void __exit nvmet_exit(void) nvmet_exit_discovery(); nvmet_exit_debugfs(); ida_destroy(&cntlid_ida); + destroy_workqueue(nvmet_aen_wq); destroy_workqueue(nvmet_wq); destroy_workqueue(buffered_io_wq); destroy_workqueue(zbd_wq); diff --git a/drivers/nvme/target/discovery.c b/drivers/nvme/target/discovery.c index c06f3e04296c..e9b35549e254 100644 --- a/drivers/nvme/target/discovery.c +++ b/drivers/nvme/target/discovery.c @@ -263,7 +263,7 @@ static void nvmet_execute_disc_identify(struct nvmet_req *req) goto out; } - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; diff --git a/drivers/nvme/target/fabrics-cmd.c b/drivers/nvme/target/fabrics-cmd.c index 7b8d8b397802..7cadd1c9e44c 100644 --- a/drivers/nvme/target/fabrics-cmd.c +++ b/drivers/nvme/target/fabrics-cmd.c @@ -280,7 +280,7 @@ static void nvmet_execute_admin_connect(struct nvmet_req *req) if (!nvmet_check_transfer_len(req, sizeof(struct nvmf_connect_data))) return; - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { args.status = NVME_SC_INTERNAL; goto complete; @@ -344,7 +344,7 @@ static void nvmet_execute_io_connect(struct nvmet_req *req) if (!nvmet_check_transfer_len(req, sizeof(struct nvmf_connect_data))) return; - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { status = NVME_SC_INTERNAL; goto complete; diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 0d9784004c9b..4eaadc711c99 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -528,8 +528,7 @@ nvmet_fc_alloc_ls_iodlist(struct nvmet_fc_tgtport *tgtport) struct nvmet_fc_ls_iod *iod; int i; - iod = kcalloc(NVMET_LS_CTX_COUNT, sizeof(struct nvmet_fc_ls_iod), - GFP_KERNEL); + iod = kzalloc_objs(struct nvmet_fc_ls_iod, NVMET_LS_CTX_COUNT); if (!iod) return -ENOMEM; @@ -789,7 +788,7 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc, if (qid > NVMET_NR_QUEUES) return NULL; - queue = kzalloc(struct_size(queue, fod, sqsize), GFP_KERNEL); + queue = kzalloc_flex(*queue, fod, sqsize); if (!queue) return NULL; @@ -1034,7 +1033,7 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) if (match) return match; - newhost = kzalloc(sizeof(*newhost), GFP_KERNEL); + newhost = kzalloc_obj(*newhost); if (!newhost) return ERR_PTR(-ENOMEM); @@ -1116,7 +1115,7 @@ nvmet_fc_alloc_target_assoc(struct nvmet_fc_tgtport *tgtport, void *hosthandle) if (!tgtport->pe) return NULL; - assoc = kzalloc(sizeof(*assoc), GFP_KERNEL); + assoc = kzalloc_obj(*assoc); if (!assoc) return NULL; @@ -2717,7 +2716,7 @@ nvmet_fc_rcv_fcp_req(struct nvmet_fc_target_port *target_port, spin_unlock_irqrestore(&queue->qlock, flags); /* Now we need to dynamically allocate one */ - deferfcp = kmalloc(sizeof(*deferfcp), GFP_KERNEL); + deferfcp = kmalloc_obj(*deferfcp); if (!deferfcp) { /* release the queue lookup reference */ nvmet_fc_tgt_q_put(queue); @@ -2882,7 +2881,7 @@ nvmet_fc_add_port(struct nvmet_port *port) if (ret) return ret; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc_obj(*pe); if (!pe) return -ENOMEM; diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c index c30e9a3e014f..b63af3b643a6 100644 --- a/drivers/nvme/target/fcloop.c +++ b/drivers/nvme/target/fcloop.c @@ -491,6 +491,7 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport, struct fcloop_rport *rport = remoteport->private; struct nvmet_fc_target_port *targetport = rport->targetport; struct fcloop_tport *tport; + int ret = 0; if (!targetport) { /* @@ -500,12 +501,18 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport, * We end up here from delete association exchange: * nvmet_fc_xmt_disconnect_assoc sends an async request. * - * Return success because this is what LLDDs do; silently - * drop the response. + * Return success when remoteport is still online because this + * is what LLDDs do and silently drop the response. Otherwise, + * return with error to signal upper layer to perform the lsrsp + * resource cleanup. */ - lsrsp->done(lsrsp); + if (remoteport->port_state == FC_OBJSTATE_ONLINE) + lsrsp->done(lsrsp); + else + ret = -ENODEV; + kmem_cache_free(lsreq_cache, tls_req); - return 0; + return ret; } memcpy(lsreq->rspaddr, lsrsp->rspbuf, @@ -559,7 +566,7 @@ fcloop_tgt_discovery_evt(struct nvmet_fc_target_port *tgtport) { struct fcloop_rscn *tgt_rscn; - tgt_rscn = kzalloc(sizeof(*tgt_rscn), GFP_KERNEL); + tgt_rscn = kzalloc_obj(*tgt_rscn); if (!tgt_rscn) return; @@ -766,7 +773,7 @@ fcloop_fcp_req(struct nvme_fc_local_port *localport, if (!rport->targetport) return -ECONNREFUSED; - tfcp_req = kzalloc(sizeof(*tfcp_req), GFP_ATOMIC); + tfcp_req = kzalloc_obj(*tfcp_req, GFP_ATOMIC); if (!tfcp_req) return -ENOMEM; @@ -1194,11 +1201,11 @@ fcloop_create_local_port(struct device *dev, struct device_attribute *attr, unsigned long flags; int ret = -ENOMEM; - lport = kzalloc(sizeof(*lport), GFP_KERNEL); + lport = kzalloc_obj(*lport); if (!lport) return -ENOMEM; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) goto out_free_lport; @@ -1345,7 +1352,7 @@ fcloop_alloc_nport(const char *buf, size_t count, bool remoteport) u32 opts_mask = (remoteport) ? RPORT_OPTS : TGTPORT_OPTS; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return NULL; @@ -1357,7 +1364,7 @@ fcloop_alloc_nport(const char *buf, size_t count, bool remoteport) if ((opts->mask & opts_mask) != opts_mask) goto out_free_opts; - newnport = kzalloc(sizeof(*newnport), GFP_KERNEL); + newnport = kzalloc_obj(*newnport); if (!newnport) goto out_free_opts; diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 0103815542d4..f15d1c213bc6 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c @@ -363,29 +363,14 @@ u16 nvmet_bdev_flush(struct nvmet_req *req) return 0; } -static u16 nvmet_bdev_discard_range(struct nvmet_req *req, - struct nvme_dsm_range *range, struct bio **bio) -{ - struct nvmet_ns *ns = req->ns; - int ret; - - ret = __blkdev_issue_discard(ns->bdev, - nvmet_lba_to_sect(ns, range->slba), - le32_to_cpu(range->nlb) << (ns->blksize_shift - 9), - GFP_KERNEL, bio); - if (ret && ret != -EOPNOTSUPP) { - req->error_slba = le64_to_cpu(range->slba); - return errno_to_nvme_status(req, ret); - } - return NVME_SC_SUCCESS; -} - static void nvmet_bdev_execute_discard(struct nvmet_req *req) { + struct nvmet_ns *ns = req->ns; struct nvme_dsm_range range; struct bio *bio = NULL; + sector_t nr_sects; int i; - u16 status; + u16 status = NVME_SC_SUCCESS; for (i = 0; i <= le32_to_cpu(req->cmd->dsm.nr); i++) { status = nvmet_copy_from_sgl(req, i * sizeof(range), &range, @@ -393,9 +378,10 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req) if (status) break; - status = nvmet_bdev_discard_range(req, &range, &bio); - if (status) - break; + nr_sects = le32_to_cpu(range.nlb) << (ns->blksize_shift - 9); + __blkdev_issue_discard(ns->bdev, + nvmet_lba_to_sect(ns, range.slba), nr_sects, + GFP_KERNEL, &bio); } if (bio) { diff --git a/drivers/nvme/target/io-cmd-file.c b/drivers/nvme/target/io-cmd-file.c index 2d068439b129..0b22d183f927 100644 --- a/drivers/nvme/target/io-cmd-file.c +++ b/drivers/nvme/target/io-cmd-file.c @@ -228,8 +228,7 @@ static void nvmet_file_execute_rw(struct nvmet_req *req) } if (nr_bvec > NVMET_MAX_INLINE_BIOVEC) - req->f.bvec = kmalloc_array(nr_bvec, sizeof(struct bio_vec), - GFP_KERNEL); + req->f.bvec = kmalloc_objs(struct bio_vec, nr_bvec); else req->f.bvec = req->inline_bvec; diff --git a/drivers/nvme/target/loop.c b/drivers/nvme/target/loop.c index fc8e7c9ad858..4b3f4f11928d 100644 --- a/drivers/nvme/target/loop.c +++ b/drivers/nvme/target/loop.c @@ -565,7 +565,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, struct nvme_loop_ctrl *ctrl; int ret; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return ERR_PTR(-ENOMEM); ctrl->ctrl.opts = opts; @@ -592,8 +592,7 @@ static struct nvme_ctrl *nvme_loop_create_ctrl(struct device *dev, ctrl->ctrl.kato = opts->kato; ctrl->port = nvme_loop_find_port(&ctrl->ctrl); - ctrl->queues = kcalloc(opts->nr_io_queues + 1, sizeof(*ctrl->queues), - GFP_KERNEL); + ctrl->queues = kzalloc_objs(*ctrl->queues, opts->nr_io_queues + 1); if (!ctrl->queues) goto out_uninit_ctrl; diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h index b664b584fdc8..319d6a5e9cf0 100644 --- a/drivers/nvme/target/nvmet.h +++ b/drivers/nvme/target/nvmet.h @@ -501,6 +501,7 @@ extern struct kmem_cache *nvmet_bvec_cache; extern struct workqueue_struct *buffered_io_wq; extern struct workqueue_struct *zbd_wq; extern struct workqueue_struct *nvmet_wq; +extern struct workqueue_struct *nvmet_aen_wq; static inline void nvmet_set_result(struct nvmet_req *req, u32 result) { diff --git a/drivers/nvme/target/passthru.c b/drivers/nvme/target/passthru.c index 5d541c2a46a5..e27f84e3cf2b 100644 --- a/drivers/nvme/target/passthru.c +++ b/drivers/nvme/target/passthru.c @@ -86,7 +86,7 @@ static u16 nvmet_passthru_override_id_ctrl(struct nvmet_req *req) unsigned int max_hw_sectors; int page_shift; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) return NVME_SC_INTERNAL; @@ -178,7 +178,7 @@ static u16 nvmet_passthru_override_id_ns(struct nvmet_req *req) struct nvme_id_ns *id; int i; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) return NVME_SC_INTERNAL; diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c index f858a6c9d7cb..4e9db96ebfec 100644 --- a/drivers/nvme/target/pci-epf.c +++ b/drivers/nvme/target/pci-epf.c @@ -502,9 +502,8 @@ static inline int nvmet_pci_epf_transfer(struct nvmet_pci_epf_ctrl *ctrl, static int nvmet_pci_epf_alloc_irq_vectors(struct nvmet_pci_epf_ctrl *ctrl) { - ctrl->irq_vectors = kcalloc(ctrl->nr_queues, - sizeof(struct nvmet_pci_epf_irq_vector), - GFP_KERNEL); + ctrl->irq_vectors = kzalloc_objs(struct nvmet_pci_epf_irq_vector, + ctrl->nr_queues); if (!ctrl->irq_vectors) return -ENOMEM; @@ -1563,13 +1562,11 @@ static int nvmet_pci_epf_alloc_queues(struct nvmet_pci_epf_ctrl *ctrl) { unsigned int qid; - ctrl->sq = kcalloc(ctrl->nr_queues, - sizeof(struct nvmet_pci_epf_queue), GFP_KERNEL); + ctrl->sq = kzalloc_objs(struct nvmet_pci_epf_queue, ctrl->nr_queues); if (!ctrl->sq) return -ENOMEM; - ctrl->cq = kcalloc(ctrl->nr_queues, - sizeof(struct nvmet_pci_epf_queue), GFP_KERNEL); + ctrl->cq = kzalloc_objs(struct nvmet_pci_epf_queue, ctrl->nr_queues); if (!ctrl->cq) { kfree(ctrl->sq); ctrl->sq = NULL; diff --git a/drivers/nvme/target/pr.c b/drivers/nvme/target/pr.c index cd22d8333314..c71ae46244ff 100644 --- a/drivers/nvme/target/pr.c +++ b/drivers/nvme/target/pr.c @@ -230,7 +230,7 @@ static u16 nvmet_pr_register(struct nvmet_req *req, u16 status = NVME_SC_SUCCESS; u64 nrkey = le64_to_cpu(d->nrkey); - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) return NVME_SC_INTERNAL; @@ -331,7 +331,7 @@ static u16 nvmet_pr_update_reg_attr(struct nvmet_pr *pr, return NVME_SC_SUCCESS; } - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) return NVME_SC_INTERNAL; @@ -380,7 +380,7 @@ static void nvmet_execute_pr_register(struct nvmet_req *req) u8 reg_act = cdw10 & 0x07; /* Reservation Register Action, bit 02:00 */ u16 status; - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { status = NVME_SC_INTERNAL; goto out; @@ -662,7 +662,7 @@ static void nvmet_execute_pr_acquire(struct nvmet_req *req) goto out; } - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { status = NVME_SC_INTERNAL; goto out; @@ -773,7 +773,7 @@ static void nvmet_execute_pr_release(struct nvmet_req *req) goto out; } - d = kmalloc(sizeof(*d), GFP_KERNEL); + d = kmalloc_obj(*d); if (!d) { status = NVME_SC_INTERNAL; goto out; @@ -1013,7 +1013,7 @@ static int nvmet_pr_alloc_and_insert_pc_ref(struct nvmet_ns *ns, struct nvmet_pr_per_ctrl_ref *pc_ref; int ret; - pc_ref = kmalloc(sizeof(*pc_ref), GFP_ATOMIC); + pc_ref = kmalloc_obj(*pc_ref, GFP_ATOMIC); if (!pc_ref) return -ENOMEM; diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c index 9c12b2361a6d..e6e2c3f9afdf 100644 --- a/drivers/nvme/target/rdma.c +++ b/drivers/nvme/target/rdma.c @@ -222,7 +222,7 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) if (unlikely(!rsp)) { int ret; - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); if (unlikely(!rsp)) return NULL; ret = nvmet_rdma_alloc_rsp(queue->dev, rsp, @@ -317,7 +317,7 @@ static int nvmet_rdma_alloc_cmd(struct nvmet_rdma_device *ndev, struct nvmet_rdma_cmd *c, bool admin) { /* NVMe command / RDMA RECV */ - c->nvme_cmd = kmalloc(sizeof(*c->nvme_cmd), GFP_KERNEL); + c->nvme_cmd = kmalloc_obj(*c->nvme_cmd); if (!c->nvme_cmd) goto out; @@ -367,7 +367,7 @@ nvmet_rdma_alloc_cmds(struct nvmet_rdma_device *ndev, struct nvmet_rdma_cmd *cmds; int ret = -EINVAL, i; - cmds = kvcalloc(nr_cmds, sizeof(struct nvmet_rdma_cmd), GFP_KERNEL); + cmds = kvzalloc_objs(struct nvmet_rdma_cmd, nr_cmds); if (!cmds) goto out; @@ -401,7 +401,7 @@ static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, struct nvmet_rdma_rsp *r, int tag) { /* NVMe CQE / RDMA SEND */ - r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL); + r->req.cqe = kmalloc_obj(*r->req.cqe); if (!r->req.cqe) goto out; @@ -455,8 +455,7 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) NUMA_NO_NODE, false, true)) goto out; - queue->rsps = kvcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), - GFP_KERNEL); + queue->rsps = kvzalloc_objs(struct nvmet_rdma_rsp, nr_rsps); if (!queue->rsps) goto out_free_sbitmap; @@ -1096,7 +1095,7 @@ nvmet_rdma_init_srq(struct nvmet_rdma_device *ndev) struct ib_srq *srq; int ret, i; - nsrq = kzalloc(sizeof(*nsrq), GFP_KERNEL); + nsrq = kzalloc_obj(*nsrq); if (!nsrq) return ERR_PTR(-ENOMEM); @@ -1155,7 +1154,7 @@ static int nvmet_rdma_init_srqs(struct nvmet_rdma_device *ndev) ndev->srq_count = min(ndev->device->num_comp_vectors, ndev->device->attrs.max_srq); - ndev->srqs = kcalloc(ndev->srq_count, sizeof(*ndev->srqs), GFP_KERNEL); + ndev->srqs = kzalloc_objs(*ndev->srqs, ndev->srq_count); if (!ndev->srqs) return -ENOMEM; @@ -1208,7 +1207,7 @@ nvmet_rdma_find_get_device(struct rdma_cm_id *cm_id) goto out_unlock; } - ndev = kzalloc(sizeof(*ndev), GFP_KERNEL); + ndev = kzalloc_obj(*ndev); if (!ndev) goto out_err; @@ -1430,7 +1429,7 @@ nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev, struct nvmet_rdma_queue *queue; int ret; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) { ret = NVME_RDMA_CM_NO_RSC; goto out_reject; @@ -1924,7 +1923,7 @@ static int nvmet_rdma_add_port(struct nvmet_port *nport) __kernel_sa_family_t af; int ret; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -2088,6 +2087,7 @@ static void nvmet_rdma_remove_one(struct ib_device *ib_device, void *client_data mutex_unlock(&nvmet_rdma_queue_mutex); flush_workqueue(nvmet_wq); + flush_workqueue(nvmet_aen_wq); } static struct ib_client nvmet_rdma_ib_client = { diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c index bda816d66846..acc71a26733f 100644 --- a/drivers/nvme/target/tcp.c +++ b/drivers/nvme/target/tcp.c @@ -439,8 +439,7 @@ static int nvmet_tcp_map_data(struct nvmet_tcp_cmd *cmd) cmd->cur_sg = cmd->req.sg; if (nvmet_tcp_has_data_in(cmd)) { - cmd->iov = kmalloc_array(cmd->req.sg_cnt, - sizeof(*cmd->iov), GFP_KERNEL); + cmd->iov = kmalloc_objs(*cmd->iov, cmd->req.sg_cnt); if (!cmd->iov) goto err; } @@ -1513,7 +1512,7 @@ static int nvmet_tcp_alloc_cmds(struct nvmet_tcp_queue *queue) struct nvmet_tcp_cmd *cmds; int i, ret = -EINVAL, nr_cmds = queue->nr_cmds; - cmds = kvcalloc(nr_cmds, sizeof(struct nvmet_tcp_cmd), GFP_KERNEL); + cmds = kvzalloc_objs(struct nvmet_tcp_cmd, nr_cmds); if (!cmds) goto out; @@ -1901,7 +1900,7 @@ static void nvmet_tcp_alloc_queue(struct nvmet_tcp_port *port, struct file *sock_file = NULL; int ret; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) { ret = -ENOMEM; goto out_release; @@ -2037,7 +2036,7 @@ static int nvmet_tcp_add_port(struct nvmet_port *nport) __kernel_sa_family_t af; int ret; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/nvme/target/zns.c b/drivers/nvme/target/zns.c index 15a579cf528c..aeaf73b54c3a 100644 --- a/drivers/nvme/target/zns.c +++ b/drivers/nvme/target/zns.c @@ -73,7 +73,7 @@ void nvmet_execute_identify_ctrl_zns(struct nvmet_req *req) struct nvme_id_ctrl_zns *id; u16 status; - id = kzalloc(sizeof(*id), GFP_KERNEL); + id = kzalloc_obj(*id); if (!id) { status = NVME_SC_INTERNAL; goto out; @@ -104,7 +104,7 @@ void nvmet_execute_identify_ns_zns(struct nvmet_req *req) goto out; } - id_zns = kzalloc(sizeof(*id_zns), GFP_KERNEL); + id_zns = kzalloc_obj(*id_zns); if (!id_zns) { status = NVME_SC_INTERNAL; goto out; diff --git a/drivers/nvmem/Kconfig b/drivers/nvmem/Kconfig index bf47a982cf62..74ddbd0f79b0 100644 --- a/drivers/nvmem/Kconfig +++ b/drivers/nvmem/Kconfig @@ -30,7 +30,7 @@ source "drivers/nvmem/layouts/Kconfig" config NVMEM_AN8855_EFUSE tristate "Airoha AN8855 eFuse support" - depends on MFD_AIROHA_AN8855 || COMPILE_TEST + depends on COMPILE_TEST help Say y here to enable support for reading eFuses on Airoha AN8855 Switch. These are e.g. used to store factory programmed diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c index 387c88c55259..311cb2e5a5c0 100644 --- a/drivers/nvmem/core.c +++ b/drivers/nvmem/core.c @@ -650,7 +650,7 @@ int nvmem_add_one_cell(struct nvmem_device *nvmem, struct nvmem_cell_entry *cell; int rval; - cell = kzalloc(sizeof(*cell), GFP_KERNEL); + cell = kzalloc_obj(*cell); if (!cell) return -ENOMEM; @@ -789,11 +789,10 @@ static int nvmem_validate_keepouts(struct nvmem_device *nvmem) static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_node *np) { struct device *dev = &nvmem->dev; - struct device_node *child; const __be32 *addr; int len, ret; - for_each_child_of_node(np, child) { + for_each_child_of_node_scoped(np, child) { struct nvmem_cell_info info = {0}; addr = of_get_property(child, "reg", &len); @@ -801,7 +800,6 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod continue; if (len < 2 * sizeof(u32)) { dev_err(dev, "nvmem: invalid reg on %pOF\n", child); - of_node_put(child); return -EINVAL; } @@ -817,7 +815,6 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod info.nbits < 1 || info.bit_offset + info.nbits > BITS_PER_BYTE * info.bytes) { dev_err(dev, "nvmem: invalid bits on %pOF\n", child); - of_node_put(child); return -EINVAL; } } @@ -830,7 +827,7 @@ static int nvmem_add_cells_from_dt(struct nvmem_device *nvmem, struct device_nod ret = nvmem_add_one_cell(nvmem, &info); kfree(info.name); if (ret) { - of_node_put(child); + of_node_put(info.np); return ret; } } @@ -911,7 +908,7 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config) if (!config->reg_read && !config->reg_write) return ERR_PTR(-EINVAL); - nvmem = kzalloc(sizeof(*nvmem), GFP_KERNEL); + nvmem = kzalloc_obj(*nvmem); if (!nvmem) return ERR_PTR(-ENOMEM); @@ -1298,7 +1295,7 @@ static struct nvmem_cell *nvmem_create_cell(struct nvmem_cell_entry *entry, struct nvmem_cell *cell; const char *name = NULL; - cell = kzalloc(sizeof(*cell), GFP_KERNEL); + cell = kzalloc_obj(*cell); if (!cell) return ERR_PTR(-ENOMEM); diff --git a/drivers/nvmem/layouts.c b/drivers/nvmem/layouts.c index 7ebe53249035..b90584e1b99e 100644 --- a/drivers/nvmem/layouts.c +++ b/drivers/nvmem/layouts.c @@ -96,7 +96,7 @@ static int nvmem_layout_create_device(struct nvmem_device *nvmem, struct device *dev; int ret; - layout = kzalloc(sizeof(*layout), GFP_KERNEL); + layout = kzalloc_obj(*layout); if (!layout) return -ENOMEM; diff --git a/drivers/of/address.c b/drivers/of/address.c index 4034d798c55a..cf4aab11e9b1 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -929,7 +929,7 @@ int of_dma_get_range(struct device_node *np, const struct bus_dma_region **map) if (!num_ranges) return -EINVAL; - r = kcalloc(num_ranges + 1, sizeof(*r), GFP_KERNEL); + r = kzalloc_objs(*r, num_ranges + 1); if (!r) return -ENOMEM; diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 2eaaddcb0ec4..1a06175def37 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -411,7 +411,7 @@ struct property *__of_prop_dup(const struct property *prop, gfp_t allocflags) { struct property *new; - new = kzalloc(sizeof(*new), allocflags); + new = kzalloc_obj(*new, allocflags); if (!new) return NULL; @@ -454,7 +454,7 @@ struct device_node *__of_node_dup(const struct device_node *np, { struct device_node *node; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return NULL; node->full_name = kstrdup(full_name, GFP_KERNEL); @@ -908,7 +908,7 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, if (WARN_ON(action >= ARRAY_SIZE(action_names))) return -EINVAL; - ce = kzalloc(sizeof(*ce), GFP_KERNEL); + ce = kzalloc_obj(*ce); if (!ce) return -ENOMEM; diff --git a/drivers/of/irq.c b/drivers/of/irq.c index f374d8b212b8..6367c67732d2 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -669,7 +669,7 @@ void __init of_irq_init(const struct of_device_id *matches) * Here, we allocate and populate an of_intc_desc with the node * pointer, interrupt-parent device_node etc. */ - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) { of_node_put(np); goto err; diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index 31c5bc751d0d..1fd28f805610 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -646,7 +646,7 @@ int of_reserved_mem_device_init_by_idx(struct device *dev, if (!rmem || !rmem->ops || !rmem->ops->device_init) return -EINVAL; - rd = kmalloc(sizeof(struct rmem_assigned_device), GFP_KERNEL); + rd = kmalloc_obj(struct rmem_assigned_device); if (!rd) return -ENOMEM; diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 5b4f42230e6c..c1c5686fc7b1 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -248,7 +248,7 @@ static struct property *dup_and_fixup_symbol_prop( return NULL; target_path_len = strlen(target_path); - new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); + new_prop = kzalloc_obj(*new_prop); if (!new_prop) goto err_free_target_path; @@ -784,7 +784,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, of_node_put(node); } - fragments = kcalloc(cnt, sizeof(*fragments), GFP_KERNEL); + fragments = kzalloc_objs(*fragments, cnt); if (!fragments) { ret = -ENOMEM; goto err_out; @@ -1009,7 +1009,7 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, if (overlay_fdt_size < size) return -EINVAL; - ovcs = kzalloc(sizeof(*ovcs), GFP_KERNEL); + ovcs = kzalloc_obj(*ovcs); if (!ovcs) return -ENOMEM; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d90b1677d84e..ba591fbceb56 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -111,7 +111,7 @@ struct platform_device *of_device_alloc(struct device_node *np, /* Populate the resource table */ if (num_reg) { - res = kcalloc(num_reg, sizeof(*res), GFP_KERNEL); + res = kzalloc_objs(*res, num_reg); if (!res) { platform_device_put(dev); return NULL; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index a9cc2c990562..2940295843e6 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -197,7 +197,7 @@ static void __init of_unittest_dynamic(void) } /* Array of 4 properties for the purpose of testing */ - prop = kcalloc(4, sizeof(*prop), GFP_KERNEL); + prop = kzalloc_objs(*prop, 4); if (!prop) { unittest(0, "kzalloc() failed\n"); return; @@ -379,7 +379,7 @@ static void __init of_unittest_check_phandles(void) } } - nh = kzalloc(sizeof(*nh), GFP_KERNEL); + nh = kzalloc_obj(*nh); if (!nh) return; @@ -1136,7 +1136,7 @@ static void __init of_unittest_dma_ranges_one(const char *path, dma_addr_t dma_addr; struct device *dev_bogus; - dev_bogus = kzalloc(sizeof(struct device), GFP_KERNEL); + dev_bogus = kzalloc_obj(struct device); if (!dev_bogus) { unittest(0, "kzalloc() failed\n"); kfree(map); @@ -2275,7 +2275,7 @@ static int unittest_gpio_probe(struct platform_device *pdev) unittest_gpio_probe_count++; - devptr = kzalloc(sizeof(*devptr), GFP_KERNEL); + devptr = kzalloc_obj(*devptr); if (!devptr) return -ENOMEM; diff --git a/drivers/opp/core.c b/drivers/opp/core.c index ae43c656f108..866641666e41 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1532,7 +1532,7 @@ static struct opp_table *_allocate_opp_table(struct device *dev, int index) * Allocate a new OPP table. In the infrequent case where a new * device is needed to be added, we pay this penalty. */ - opp_table = kzalloc(sizeof(*opp_table), GFP_KERNEL); + opp_table = kzalloc_obj(*opp_table); if (!opp_table) return ERR_PTR(-ENOMEM); @@ -2260,9 +2260,7 @@ static int _opp_set_regulators(struct opp_table *opp_table, struct device *dev, if (opp_table->regulators) return 0; - opp_table->regulators = kmalloc_array(count, - sizeof(*opp_table->regulators), - GFP_KERNEL); + opp_table->regulators = kmalloc_objs(*opp_table->regulators, count); if (!opp_table->regulators) return -ENOMEM; @@ -2364,8 +2362,7 @@ static int _opp_set_clknames(struct opp_table *opp_table, struct device *dev, if (opp_table->clks) return 0; - opp_table->clks = kmalloc_array(count, sizeof(*opp_table->clks), - GFP_KERNEL); + opp_table->clks = kmalloc_objs(*opp_table->clks, count); if (!opp_table->clks) return -ENOMEM; @@ -2550,7 +2547,7 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) unsigned int id; int ret; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/opp/cpu.c b/drivers/opp/cpu.c index a6da7ee3ec76..0ea69c5c5001 100644 --- a/drivers/opp/cpu.c +++ b/drivers/opp/cpu.c @@ -51,7 +51,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev, if (max_opps <= 0) return max_opps ? max_opps : -ENODATA; - freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_KERNEL); + freq_table = kzalloc_objs(*freq_table, (max_opps + 1)); if (!freq_table) return -ENOMEM; diff --git a/drivers/opp/of.c b/drivers/opp/of.c index a268c2b250c0..f96adfd5b219 100644 --- a/drivers/opp/of.c +++ b/drivers/opp/of.c @@ -303,7 +303,7 @@ static int _of_opp_alloc_required_opps(struct opp_table *opp_table, if (!count) return 0; - opp->required_opps = kcalloc(count, sizeof(*opp->required_opps), GFP_KERNEL); + opp->required_opps = kzalloc_objs(*opp->required_opps, count); if (!opp->required_opps) return -ENOMEM; @@ -469,7 +469,7 @@ int dev_pm_opp_of_find_icc_paths(struct device *dev, } num_paths = count / 2; - paths = kcalloc(num_paths, sizeof(*paths), GFP_KERNEL); + paths = kzalloc_objs(*paths, num_paths); if (!paths) return -ENOMEM; diff --git a/drivers/opp/ti-opp-supply.c b/drivers/opp/ti-opp-supply.c index 5f0fb3ea385b..406ba47e0f0b 100644 --- a/drivers/opp/ti-opp-supply.c +++ b/drivers/opp/ti-opp-supply.c @@ -127,8 +127,7 @@ static int _store_optimized_voltages(struct device *dev, goto out; } - table = kcalloc(data->num_vdd_table, sizeof(*data->vdd_table), - GFP_KERNEL); + table = kzalloc_objs(*data->vdd_table, data->num_vdd_table); if (!table) { ret = -ENOMEM; goto out; diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 4e7071714356..d5b95e63c24e 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c @@ -1520,7 +1520,7 @@ static int __init ccio_probe(struct parisc_device *dev) struct ioc *ioc, **ioc_p = &ioc_list; struct pci_hba_data *hba; - ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); + ioc = kzalloc_obj(struct ioc); if (ioc == NULL) { printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); return -ENOMEM; @@ -1550,7 +1550,7 @@ static int __init ccio_probe(struct parisc_device *dev) } hppa_dma_ops = &ccio_ops; - hba = kzalloc(sizeof(*hba), GFP_KERNEL); + hba = kzalloc_obj(*hba); /* if this fails, no I/O cards will work, so may as well bug */ BUG_ON(hba == NULL); diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 01a50a051296..4b96d9fda49a 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -990,7 +990,7 @@ static int __init dino_probe(struct parisc_device *dev) */ } - dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); + dino_dev = kzalloc_obj(struct dino_device); if (!dino_dev) { printk("dino_init_chip - couldn't alloc dino_device\n"); return 1; diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c index f0cb31198a8f..e0a57086a8a8 100644 --- a/drivers/parisc/eisa_enumerator.c +++ b/drivers/parisc/eisa_enumerator.c @@ -86,7 +86,7 @@ static int configure_memory(const unsigned char *buf, for (i=0;iname = name; @@ -178,7 +178,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent, for (i=0;iname = board; res->start = get_16(buf+len+1); res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1; diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 0f9d80384e3d..33709eafe291 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -54,7 +54,7 @@ static int __init hppb_probe(struct parisc_device *dev) } if(card->hpa) { - card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL); + card->next = kzalloc_obj(struct hppb_card); if(!card->next) { printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); return 1; diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index a42552608fe4..035c996e3ca9 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c @@ -221,7 +221,7 @@ static size_t irt_num_entry; static struct irt_entry *iosapic_alloc_irt(int num_entries) { - return kcalloc(num_entries, sizeof(struct irt_entry), GFP_KERNEL); + return kzalloc_objs(struct irt_entry, num_entries); } /** @@ -915,7 +915,7 @@ void *iosapic_register(unsigned long hpa, void __iomem *vaddr) return NULL; } - isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); + isi = kzalloc_obj(struct iosapic_info); if (!isi) { BUG(); return NULL; @@ -927,8 +927,8 @@ void *iosapic_register(unsigned long hpa, void __iomem *vaddr) isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; DBG_IRT("iosapic_register: num vectors = %d\n", isi->isi_num_vectors); - vip = isi->isi_vector = kcalloc(isi->isi_num_vectors, - sizeof(struct vector_info), GFP_KERNEL); + vip = isi->isi_vector = kzalloc_objs(struct vector_info, + isi->isi_num_vectors); if (vip == NULL) { kfree(isi); return NULL; diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index 73c93e9cfa51..ef6125d83878 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c @@ -162,7 +162,7 @@ static int __init lasi_init_chip(struct parisc_device *dev) struct gsc_asic *lasi; int ret; - lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); + lasi = kzalloc_obj(*lasi); if (!lasi) return -ENOMEM; diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index 1d29fa13650b..5197a3c93c70 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1025,11 +1025,11 @@ lba_pat_resources(struct parisc_device *pa_dev, struct lba_device *lba_dev) pdc_pat_cell_mod_maddr_block_t *io_pdc_cell; /* IO_VIEW */ int i; - pa_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); + pa_pdc_cell = kzalloc_obj(pdc_pat_cell_mod_maddr_block_t); if (!pa_pdc_cell) return; - io_pdc_cell = kzalloc(sizeof(pdc_pat_cell_mod_maddr_block_t), GFP_KERNEL); + io_pdc_cell = kzalloc_obj(pdc_pat_cell_mod_maddr_block_t); if (!io_pdc_cell) { kfree(pa_pdc_cell); return; @@ -1546,7 +1546,7 @@ lba_driver_probe(struct parisc_device *dev) ** have an IRT entry will get NULL back from iosapic code. */ - lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL); + lba_dev = kzalloc_obj(struct lba_device); if (!lba_dev) { printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); return(1); diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index eefb2bac8443..d9339dd50826 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -1939,7 +1939,7 @@ static int __init sba_driver_callback(struct parisc_device *dev) printk(KERN_INFO "%s found %s at 0x%llx\n", MODULE_NAME, version, (unsigned long long)dev->hpa.start); - sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); + sba_dev = kzalloc_obj(struct sba_device); if (!sba_dev) { printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); return -ENOMEM; diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 834dbe9a767b..a82a5e88ed6d 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c @@ -70,7 +70,7 @@ static int __init wax_init_chip(struct parisc_device *dev) struct parisc_device *parent; int ret; - wax = kzalloc(sizeof(*wax), GFP_KERNEL); + wax = kzalloc_obj(*wax); if (!wax) return -ENOMEM; diff --git a/drivers/parport/daisy.c b/drivers/parport/daisy.c index 2231dbfd870d..0f15c5de8df8 100644 --- a/drivers/parport/daisy.c +++ b/drivers/parport/daisy.c @@ -51,7 +51,7 @@ static int assign_addrs(struct parport *port); static void add_dev(int devnum, struct parport *port, int daisy) { struct daisydev *newdev, **p; - newdev = kmalloc(sizeof(struct daisydev), GFP_KERNEL); + newdev = kmalloc_obj(struct daisydev); if (newdev) { newdev->port = port; newdev->daisy = daisy; diff --git a/drivers/parport/parport_cs.c b/drivers/parport/parport_cs.c index 8e7e3ac4bb87..2c1c8253a00b 100644 --- a/drivers/parport/parport_cs.c +++ b/drivers/parport/parport_cs.c @@ -87,7 +87,7 @@ static int parport_probe(struct pcmcia_device *link) dev_dbg(&link->dev, "parport_attach()\n"); /* Create new parport device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; link->priv = info; info->p_dev = link; diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index c7e18382dc01..e5e8054a1af8 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c @@ -234,7 +234,7 @@ static struct parport *parport_gsc_probe_port(unsigned long base, struct parport tmp; struct parport *p = &tmp; - priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); + priv = kzalloc_obj(struct parport_gsc_private); if (!priv) { printk(KERN_DEBUG "parport (0x%lx): no memory!\n", base); return NULL; diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c index 0919ed99ba94..14a4f4251d5c 100644 --- a/drivers/parport/parport_ip32.c +++ b/drivers/parport/parport_ip32.c @@ -2031,8 +2031,8 @@ static __init struct parport *parport_ip32_probe_port(void) parport_ip32_make_isa_registers(®s, &mace->isa.parallel, &mace->isa.ecp1284, 8 /* regshift */); - ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); - priv = kmalloc(sizeof(struct parport_ip32_private), GFP_KERNEL); + ops = kmalloc_obj(struct parport_operations); + priv = kmalloc_obj(struct parport_ip32_private); p = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, ops); if (ops == NULL || priv == NULL || p == NULL) { err = -ENOMEM; diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index f33b5d1ddfc1..c75abdd8ef25 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -2056,11 +2056,11 @@ static struct parport *__parport_pc_probe_port(unsigned long int base, } } - ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); + ops = kmalloc_obj(struct parport_operations); if (!ops) goto out1; - priv = kmalloc(sizeof(struct parport_pc_private), GFP_KERNEL); + priv = kmalloc_obj(struct parport_pc_private); if (!priv) goto out2; @@ -2880,7 +2880,7 @@ static int parport_pc_pci_probe(struct pci_dev *dev, if (err) return err; - data = kmalloc(sizeof(struct pci_parport_data), GFP_KERNEL); + data = kmalloc_obj(struct pci_parport_data); if (!data) return -ENOMEM; diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 427abdf3c4c4..ba5292828703 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -430,7 +430,7 @@ struct parport *parport_register_port(unsigned long base, int irq, int dma, int device; int ret; - tmp = kzalloc(sizeof(struct parport), GFP_KERNEL); + tmp = kzalloc_obj(struct parport); if (!tmp) return NULL; @@ -709,11 +709,11 @@ parport_register_dev_model(struct parport *port, const char *name, parport_get_port(port); - par_dev = kzalloc(sizeof(*par_dev), GFP_KERNEL); + par_dev = kzalloc_obj(*par_dev); if (!par_dev) goto err_put_port; - par_dev->state = kzalloc(sizeof(*par_dev->state), GFP_KERNEL); + par_dev->state = kzalloc_obj(*par_dev->state); if (!par_dev->state) goto err_put_par_dev; diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 51af9e6c541c..6c1ad1f542d9 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -65,7 +65,7 @@ void pci_bus_add_resource(struct pci_bus *bus, struct resource *res) { struct pci_bus_resource *bus_res; - bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); + bus_res = kzalloc_obj(struct pci_bus_resource); if (!bus_res) { dev_err(&bus->dev, "can't add %pR resource\n", res); return; diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 7e7844ff0f7e..c57ae4d6c5c0 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -165,6 +165,7 @@ static void dw_pcie_ep_clear_ib_maps(struct dw_pcie_ep *ep, u8 func_no, enum pci dw_pcie_disable_atu(pci, PCIE_ATU_REGION_DIR_IB, atu_index); clear_bit(atu_index, ep->ib_window_map); ep_func->bar_to_atu[bar] = 0; + return; } /* Tear down all Address Match Mode mappings, if any. */ @@ -518,6 +519,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, /* * We can only dynamically change a BAR if the new BAR size and * BAR flags do not differ from the existing configuration. + * + * Note: this safety check only works when the caller uses + * a new struct pci_epf_bar in the second set_bar() call. + * If the same instance is updated in place and passed in, + * we cannot reliably detect invalid barno/size/flags + * changes here. */ if (ep_func->epf_bar[bar]->barno != bar || ep_func->epf_bar[bar]->size != size || @@ -526,10 +533,12 @@ static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, u8 vfunc_no, /* * When dynamically changing a BAR, tear down any existing - * mappings before re-programming. + * mappings before re-programming. This is redundant when + * both the old and new mappings are BAR Match Mode, but + * required to handle in-place updates and match-mode + * changes reliably. */ - if (ep_func->epf_bar[bar]->num_submap || epf_bar->num_submap) - dw_pcie_ep_clear_ib_maps(ep, func_no, bar); + dw_pcie_ep_clear_ib_maps(ep, func_no, bar); /* * When dynamically changing a BAR, skip writing the BAR reg, as @@ -896,6 +905,19 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, * supported, so we avoid reprogramming the region on every MSI, * specifically unmapping immediately after writel(). */ + if (ep->msi_iatu_mapped && (ep->msi_msg_addr != msg_addr || + ep->msi_map_size != map_size)) { + /* + * The host changed the MSI target address or the required + * mapping size changed. Reprogramming the iATU when there are + * operations in flight is unsafe on this controller. However, + * there is no unified way to check if we have operations in + * flight, thus we don't know if we should WARN() or not. + */ + dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); + ep->msi_iatu_mapped = false; + } + if (!ep->msi_iatu_mapped) { ret = dw_pcie_ep_map_addr(epc, func_no, 0, ep->msi_mem_phys, msg_addr, @@ -906,15 +928,6 @@ int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, ep->msi_iatu_mapped = true; ep->msi_msg_addr = msg_addr; ep->msi_map_size = map_size; - } else if (WARN_ON_ONCE(ep->msi_msg_addr != msg_addr || - ep->msi_map_size != map_size)) { - /* - * The host changed the MSI target address or the required - * mapping size changed. Reprogramming the iATU at runtime is - * unsafe on this controller, so bail out instead of trying to - * update the existing region. - */ - return -EINVAL; } writel(msg_data | (interrupt_num - 1), ep->msi_mem + offset); @@ -1001,6 +1014,9 @@ int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, writel(msg_data, ep->msi_mem + offset); + /* flush posted write before unmap */ + readl(ep->msi_mem + offset); + dw_pcie_ep_unmap_addr(epc, func_no, 0, ep->msi_mem_phys); return 0; diff --git a/drivers/pci/controller/pci-hyperv-intf.c b/drivers/pci/controller/pci-hyperv-intf.c index 28b3e93d31c0..18acbda867f0 100644 --- a/drivers/pci/controller/pci-hyperv-intf.c +++ b/drivers/pci/controller/pci-hyperv-intf.c @@ -52,17 +52,5 @@ int hyperv_reg_block_invalidate(struct pci_dev *dev, void *context, } EXPORT_SYMBOL_GPL(hyperv_reg_block_invalidate); -static void __exit exit_hv_pci_intf(void) -{ -} - -static int __init init_hv_pci_intf(void) -{ - return 0; -} - -module_init(init_hv_pci_intf); -module_exit(exit_hv_pci_intf); - MODULE_DESCRIPTION("Hyper-V PCI Interface"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index 1e237d3538f9..2c7a406b4ba8 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -501,7 +501,6 @@ struct hv_pcibus_device { struct resource *low_mmio_res; struct resource *high_mmio_res; struct completion *survey_event; - struct pci_bus *pci_bus; spinlock_t config_lock; /* Avoid two threads writing index page */ spinlock_t device_list_lock; /* Protect lists below */ void __iomem *cfg_addr; @@ -946,7 +945,7 @@ static int hv_pci_irqchip_init(void) struct irq_domain *irq_domain_parent = NULL; int ret = -ENOMEM; - chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL); + chip_data = kzalloc_obj(*chip_data); if (!chip_data) return ret; @@ -1933,7 +1932,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) hv_int_desc_free(hpdev, int_desc); } - int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC); + int_desc = kzalloc_obj(*int_desc, GFP_ATOMIC); if (!int_desc) goto drop_reference; @@ -2593,7 +2592,7 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, unsigned long flags; int ret; - hpdev = kzalloc(sizeof(*hpdev), GFP_KERNEL); + hpdev = kzalloc_obj(*hpdev); if (!hpdev) return NULL; @@ -2832,7 +2831,7 @@ static int hv_pci_start_relations_work(struct hv_pcibus_device *hbus, return -ENOENT; } - dr_wrk = kzalloc(sizeof(*dr_wrk), GFP_NOWAIT); + dr_wrk = kzalloc_obj(*dr_wrk, GFP_NOWAIT); if (!dr_wrk) return -ENOMEM; @@ -2872,8 +2871,7 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus, struct hv_dr_state *dr; int i; - dr = kzalloc(struct_size(dr, func, relations->device_count), - GFP_NOWAIT); + dr = kzalloc_flex(*dr, func, relations->device_count, GFP_NOWAIT); if (!dr) return; @@ -2907,8 +2905,7 @@ static void hv_pci_devices_present2(struct hv_pcibus_device *hbus, struct hv_dr_state *dr; int i; - dr = kzalloc(struct_size(dr, func, relations->device_count), - GFP_NOWAIT); + dr = kzalloc_flex(*dr, func, relations->device_count, GFP_NOWAIT); if (!dr) return; @@ -3716,7 +3713,7 @@ static int hv_pci_probe(struct hv_device *hdev, if (!bridge) return -ENOMEM; - hbus = kzalloc(sizeof(*hbus), GFP_KERNEL); + hbus = kzalloc_obj(*hbus); if (!hbus) return -ENOMEM; diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c index ec6afc38e898..d4ae250d4bc6 100644 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@ -270,7 +270,7 @@ static int vmd_msi_alloc(struct irq_domain *domain, unsigned int virq, struct vmd_irq *vmdirq; for (int i = 0; i < nr_irqs; ++i) { - vmdirq = kzalloc(sizeof(*vmdirq), GFP_KERNEL); + vmdirq = kzalloc_obj(*vmdirq); if (!vmdirq) { vmd_msi_free(domain, virq, i); return -ENOMEM; diff --git a/drivers/pci/doe.c b/drivers/pci/doe.c index 62be9c8dbc52..7b41da4ec11a 100644 --- a/drivers/pci/doe.c +++ b/drivers/pci/doe.c @@ -167,7 +167,7 @@ static int pci_doe_sysfs_feature_populate(struct pci_dev *pdev, xa_for_each(&doe_mb->feats, i, entry) num_features++; - attrs = kcalloc(num_features, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, num_features); if (!attrs) { pci_warn(pdev, "Failed allocating the device_attribute array\n"); return -ENOMEM; @@ -641,7 +641,7 @@ static struct pci_doe_mb *pci_doe_create_mb(struct pci_dev *pdev, struct pci_doe_mb *doe_mb; int rc; - doe_mb = kzalloc(sizeof(*doe_mb), GFP_KERNEL); + doe_mb = kzalloc_obj(*doe_mb); if (!doe_mb) return ERR_PTR(-ENOMEM); diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index 260b7de2dbd5..119de32ff07b 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c @@ -37,7 +37,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, if (busr->start > busr->end) return ERR_PTR(-EINVAL); - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return ERR_PTR(-ENOMEM); @@ -75,7 +75,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, } if (per_bus_mapping) { - cfg->winp = kcalloc(bus_range, sizeof(*cfg->winp), GFP_KERNEL); + cfg->winp = kzalloc_objs(*cfg->winp, bus_range); if (!cfg->winp) goto err_exit_malloc; } else { diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig index 0c9cea0698d7..bb5a23994288 100644 --- a/drivers/pci/endpoint/functions/Kconfig +++ b/drivers/pci/endpoint/functions/Kconfig @@ -6,6 +6,7 @@ config PCI_EPF_TEST tristate "PCI Endpoint Test driver" depends on PCI_ENDPOINT + select CONFIGFS_FS select CRC32 help Enable this configuration option to enable the test driver diff --git a/drivers/pci/endpoint/functions/pci-epf-mhi.c b/drivers/pci/endpoint/functions/pci-epf-mhi.c index 27de533f0571..f9cf18aa5b34 100644 --- a/drivers/pci/endpoint/functions/pci-epf-mhi.c +++ b/drivers/pci/endpoint/functions/pci-epf-mhi.c @@ -525,7 +525,7 @@ static int pci_epf_mhi_edma_read_async(struct mhi_ep_cntrl *mhi_cntrl, goto err_unmap; } - transfer = kzalloc(sizeof(*transfer), GFP_KERNEL); + transfer = kzalloc_obj(*transfer); if (!transfer) { ret = -ENOMEM; goto err_unmap; @@ -604,7 +604,7 @@ static int pci_epf_mhi_edma_write_async(struct mhi_ep_cntrl *mhi_cntrl, goto err_unmap; } - transfer = kzalloc(sizeof(*transfer), GFP_KERNEL); + transfer = kzalloc_obj(*transfer); if (!transfer) { ret = -ENOMEM; goto err_unmap; diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index 0cb7af0919dc..582938b7b4f1 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -872,7 +872,7 @@ static void pci_epf_test_bar_subrange_setup(struct pci_epf_test *epf_test, sub_size = bar->size / nsub; - submap = kcalloc(nsub, sizeof(*submap), GFP_KERNEL); + submap = kzalloc_objs(*submap, nsub); if (!submap) goto err; diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 8b392a8363bb..0f3921f28f17 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -274,7 +274,7 @@ struct config_group *pci_ep_cfs_add_epc_group(const char *name) struct config_group *group; struct pci_epc_group *epc_group; - epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL); + epc_group = kzalloc_obj(*epc_group); if (!epc_group) { ret = -ENOMEM; goto err; @@ -599,7 +599,7 @@ static struct config_group *pci_epf_make(struct config_group *group, char *epf_name; int index, err; - epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL); + epf_group = kzalloc_obj(*epf_group); if (!epf_group) return ERR_PTR(-ENOMEM); diff --git a/drivers/pci/endpoint/pci-ep-msi.c b/drivers/pci/endpoint/pci-ep-msi.c index 1b58357b905f..51c19942a81e 100644 --- a/drivers/pci/endpoint/pci-ep-msi.c +++ b/drivers/pci/endpoint/pci-ep-msi.c @@ -67,7 +67,7 @@ int pci_epf_alloc_doorbell(struct pci_epf *epf, u16 num_db) dev_set_msi_domain(epc->dev.parent, domain); - msg = kcalloc(num_db, sizeof(struct pci_epf_doorbell_msg), GFP_KERNEL); + msg = kzalloc_objs(struct pci_epf_doorbell_msg, num_db); if (!msg) return -ENOMEM; diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c index 068155819c57..e546b3dbb240 100644 --- a/drivers/pci/endpoint/pci-epc-core.c +++ b/drivers/pci/endpoint/pci-epc-core.c @@ -982,7 +982,7 @@ __pci_epc_create(struct device *dev, const struct pci_epc_ops *ops, goto err_ret; } - epc = kzalloc(sizeof(*epc), GFP_KERNEL); + epc = kzalloc_obj(*epc); if (!epc) { ret = -ENOMEM; goto err_ret; diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c index 218a60e945db..6102a4af9d79 100644 --- a/drivers/pci/endpoint/pci-epc-mem.c +++ b/drivers/pci/endpoint/pci-epc-mem.c @@ -62,7 +62,7 @@ int pci_epc_multi_mem_init(struct pci_epc *epc, if (!windows || !num_windows) return -EINVAL; - epc->windows = kcalloc(num_windows, sizeof(*epc->windows), GFP_KERNEL); + epc->windows = kzalloc_objs(*epc->windows, num_windows); if (!epc->windows) return -ENOMEM; @@ -74,7 +74,7 @@ int pci_epc_multi_mem_init(struct pci_epc *epc, pages = windows[i].size >> page_shift; bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) { ret = -ENOMEM; i--; diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c index 9a505c796370..83fd20c11238 100644 --- a/drivers/pci/endpoint/pci-epf-core.c +++ b/drivers/pci/endpoint/pci-epf-core.c @@ -535,7 +535,7 @@ struct pci_epf *pci_epf_create(const char *name) struct device *dev; int len; - epf = kzalloc(sizeof(*epf), GFP_KERNEL); + epf = kzalloc_obj(*epf); if (!epf) return ERR_PTR(-ENOMEM); diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 9dad14e80bcf..70c95166e509 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -260,7 +260,7 @@ int acpiphp_register_hotplug_slot(struct acpiphp_slot *acpiphp_slot, int retval = -ENOMEM; char name[SLOT_NAME_SIZE]; - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) goto error; diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 5b1f271c6034..78e3effbb32d 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -60,7 +60,7 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) { struct acpiphp_context *context; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return NULL; @@ -279,7 +279,7 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, if (slot->device == device) goto slot_found; - slot = kzalloc(sizeof(struct acpiphp_slot), GFP_KERNEL); + slot = kzalloc_obj(struct acpiphp_slot); if (!slot) { acpi_lock_hp_context(); acpiphp_put_context(context); @@ -869,7 +869,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) return; handle = adev->handle; - bridge = kzalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); + bridge = kzalloc_obj(struct acpiphp_bridge); if (!bridge) return; @@ -889,7 +889,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) if (pci_is_root_bus(bridge->pci_bus)) { struct acpiphp_root_context *root_context; - root_context = kzalloc(sizeof(*root_context), GFP_KERNEL); + root_context = kzalloc_obj(*root_context); if (!root_context) goto err; diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 18e01cd55a8e..f8016ed24523 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -141,7 +141,7 @@ static union apci_descriptor *ibm_slot_from_id(int id) ibm_slot_done: if (ret) { - ret = kmalloc(sizeof(union apci_descriptor), GFP_KERNEL); + ret = kmalloc_obj(union apci_descriptor); if (ret) memcpy(ret, des, sizeof(union apci_descriptor)); } diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index dd93e53ea7c2..e7cd801a2655 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -189,7 +189,7 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) * with the pci_hotplug subsystem. */ for (i = first; i <= last; ++i) { - slot = kzalloc(sizeof(struct slot), GFP_KERNEL); + slot = kzalloc_obj(struct slot); if (!slot) { status = -ENOMEM; goto error; diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 47a3ed16159a..76e26b9a9f0d 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -593,7 +593,7 @@ static int ctrl_slot_setup(struct controller *ctrl, slot_number = ctrl->first_slot; while (number_of_slots) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) { result = -ENOMEM; goto error; @@ -822,7 +822,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto err_disable_device; } - ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL); + ctrl = kzalloc_obj(struct controller); if (!ctrl) { rc = -ENOMEM; goto err_disable_device; diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 760a5dec0431..040429028402 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -428,7 +428,7 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h /* this one isn't an aligned length, so we'll make a new entry * and split it up. */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -553,7 +553,7 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size if ((node->length - (temp_dword - node->base)) < size) continue; - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -573,7 +573,7 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size /* this one is longer than we need * so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -650,7 +650,7 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz if ((max->length - (temp_dword - max->base)) < size) continue; - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -668,7 +668,7 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz /* this one isn't end aligned properly at the top * so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -747,7 +747,7 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) if ((node->length - (temp_dword - node->base)) < size) continue; - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -767,7 +767,7 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) /* this one is longer than we need * so we'll make a new entry and split it up */ - split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); + split_node = kmalloc_obj(*split_node); if (!split_node) return NULL; @@ -955,7 +955,7 @@ struct pci_func *cpqhp_slot_create(u8 busnumber) struct pci_func *new_slot; struct pci_func *next; - new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); + new_slot = kzalloc_obj(*new_slot); if (new_slot == NULL) return new_slot; @@ -2435,10 +2435,10 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func /* Make copies of the nodes we are going to pass down so that * if there is a problem,we can just use these to free resources */ - hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); - hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); - hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); - hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL); + hold_bus_node = kmalloc_obj(*hold_bus_node); + hold_IO_node = kmalloc_obj(*hold_IO_node); + hold_mem_node = kmalloc_obj(*hold_mem_node); + hold_p_mem_node = kmalloc_obj(*hold_p_mem_node); if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) { kfree(hold_bus_node); diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index 7a65d427ac11..a197fb98be3e 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c @@ -504,7 +504,7 @@ int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) return 2; while (nummem--) { - mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); + mem_node = kmalloc_obj(struct pci_resource); if (!mem_node) break; @@ -532,7 +532,7 @@ int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) } while (numpmem--) { - p_mem_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); + p_mem_node = kmalloc_obj(struct pci_resource); if (!p_mem_node) break; @@ -560,7 +560,7 @@ int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) } while (numio--) { - io_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); + io_node = kmalloc_obj(struct pci_resource); if (!io_node) break; @@ -588,7 +588,7 @@ int compaq_nvram_load(void __iomem *rom_start, struct controller *ctrl) } while (numbus--) { - bus_node = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); + bus_node = kmalloc_obj(struct pci_resource); if (!bus_node) break; diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 88929360fe77..81c58b1ec200 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c @@ -151,8 +151,8 @@ int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) struct pci_bus *fakebus; u16 temp_word; - fakedev = kmalloc(sizeof(*fakedev), GFP_KERNEL); - fakebus = kmalloc(sizeof(*fakebus), GFP_KERNEL); + fakedev = kmalloc_obj(*fakedev); + fakebus = kmalloc_obj(*fakebus); if (!fakedev || !fakebus) { kfree(fakedev); kfree(fakebus); @@ -721,7 +721,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte(pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte); - bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); + bus_node = kmalloc_obj(*bus_node); if (!bus_node) return -ENOMEM; @@ -736,7 +736,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length); if ((b_base <= b_length) && (save_command & 0x01)) { - io_node = kmalloc(sizeof(*io_node), GFP_KERNEL); + io_node = kmalloc_obj(*io_node); if (!io_node) return -ENOMEM; @@ -752,7 +752,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); if ((w_base <= w_length) && (save_command & 0x02)) { - mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); + mem_node = kmalloc_obj(*mem_node); if (!mem_node) return -ENOMEM; @@ -768,7 +768,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); if ((w_base <= w_length) && (save_command & 0x02)) { - p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); + p_mem_node = kmalloc_obj(*p_mem_node); if (!p_mem_node) return -ENOMEM; @@ -799,8 +799,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFFE; temp_register = (~temp_register) + 1; - io_node = kmalloc(sizeof(*io_node), - GFP_KERNEL); + io_node = kmalloc_obj(*io_node); if (!io_node) return -ENOMEM; @@ -817,8 +816,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFF0; temp_register = (~temp_register) + 1; - p_mem_node = kmalloc(sizeof(*p_mem_node), - GFP_KERNEL); + p_mem_node = kmalloc_obj(*p_mem_node); if (!p_mem_node) return -ENOMEM; @@ -834,8 +832,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFF0; temp_register = (~temp_register) + 1; - mem_node = kmalloc(sizeof(*mem_node), - GFP_KERNEL); + mem_node = kmalloc_obj(*mem_node); if (!mem_node) return -ENOMEM; @@ -871,8 +868,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFFE; temp_register = (~temp_register) + 1; - io_node = kmalloc(sizeof(*io_node), - GFP_KERNEL); + io_node = kmalloc_obj(*io_node); if (!io_node) return -ENOMEM; @@ -888,8 +884,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFF0; temp_register = (~temp_register) + 1; - p_mem_node = kmalloc(sizeof(*p_mem_node), - GFP_KERNEL); + p_mem_node = kmalloc_obj(*p_mem_node); if (!p_mem_node) return -ENOMEM; @@ -905,8 +900,7 @@ int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func) temp_register = base & 0xFFFFFFF0; temp_register = (~temp_register) + 1; - mem_node = kmalloc(sizeof(*mem_node), - GFP_KERNEL); + mem_node = kmalloc_obj(*mem_node); if (!mem_node) return -ENOMEM; @@ -1293,7 +1287,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st temp_dword = io_base + io_length; if ((io_base) && (temp_dword < 0x10000)) { - io_node = kmalloc(sizeof(*io_node), GFP_KERNEL); + io_node = kmalloc_obj(*io_node); if (!io_node) return -ENOMEM; @@ -1315,7 +1309,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st /* If we've got a valid memory base, use it */ temp_dword = mem_base + mem_length; if ((mem_base) && (temp_dword < 0x10000)) { - mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); + mem_node = kmalloc_obj(*mem_node); if (!mem_node) return -ENOMEM; @@ -1340,7 +1334,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st */ temp_dword = pre_mem_base + pre_mem_length; if ((pre_mem_base) && (temp_dword < 0x10000)) { - p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); + p_mem_node = kmalloc_obj(*p_mem_node); if (!p_mem_node) return -ENOMEM; @@ -1365,7 +1359,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st * populated slots that don't have PCI-PCI bridges */ if (secondary_bus && (secondary_bus != primary_bus)) { - bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); + bus_node = kmalloc_obj(*bus_node); if (!bus_node) return -ENOMEM; diff --git a/drivers/pci/hotplug/cpqphp_sysfs.c b/drivers/pci/hotplug/cpqphp_sysfs.c index 6143ebf71f21..ca153c626942 100644 --- a/drivers/pci/hotplug/cpqphp_sysfs.c +++ b/drivers/pci/hotplug/cpqphp_sysfs.c @@ -134,7 +134,7 @@ static int open(struct inode *inode, struct file *file) int retval = -ENOMEM; mutex_lock(&cpqphp_mutex); - dbg = kmalloc(sizeof(*dbg), GFP_KERNEL); + dbg = kmalloc_obj(*dbg); if (!dbg) goto exit; dbg->data = kmalloc(MAX_OUTPUT, GFP_KERNEL); diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 197997e264a2..aca86c092d4a 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -624,11 +624,11 @@ static u8 bus_structure_fixup(u8 busno) if (pci_find_bus(0, busno) || !(ibmphp_find_same_bus_num(busno))) return 1; - bus = kmalloc(sizeof(*bus), GFP_KERNEL); + bus = kmalloc_obj(*bus); if (!bus) return 1; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc_obj(*dev); if (!dev) { kfree(bus); return 1; @@ -986,7 +986,7 @@ static int enable_slot(struct hotplug_slot *hs) goto error_power; } - slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); + slot_cur->func = kzalloc_obj(struct pci_func); if (!slot_cur->func) { /* do update_slot_info here? */ rc = -ENOMEM; @@ -1093,7 +1093,7 @@ int ibmphp_do_disable_slot(struct slot *slot_cur) if (slot_cur->func == NULL) { /* We need this for functions that were there on bootup */ - slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL); + slot_cur->func = kzalloc_obj(struct pci_func); if (!slot_cur->func) { rc = -ENOMEM; goto error; @@ -1187,7 +1187,7 @@ static int __init ibmphp_init(void) info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - ibmphp_pci_bus = kmalloc(sizeof(*ibmphp_pci_bus), GFP_KERNEL); + ibmphp_pci_bus = kmalloc_obj(*ibmphp_pci_bus); if (!ibmphp_pci_bus) { rc = -ENOMEM; goto exit; diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 7fb75401ad8a..c1939b88e75b 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c @@ -57,7 +57,7 @@ static int ebda_rio_table(void); static struct ebda_hpc_list * __init alloc_ebda_hpc_list(void) { - return kzalloc(sizeof(struct ebda_hpc_list), GFP_KERNEL); + return kzalloc_obj(struct ebda_hpc_list); } static struct controller *alloc_ebda_hpc(u32 slot_count, u32 bus_count) @@ -66,16 +66,16 @@ static struct controller *alloc_ebda_hpc(u32 slot_count, u32 bus_count) struct ebda_hpc_slot *slots; struct ebda_hpc_bus *buses; - controller = kzalloc(sizeof(struct controller), GFP_KERNEL); + controller = kzalloc_obj(struct controller); if (!controller) goto error; - slots = kcalloc(slot_count, sizeof(struct ebda_hpc_slot), GFP_KERNEL); + slots = kzalloc_objs(struct ebda_hpc_slot, slot_count); if (!slots) goto error_contr; controller->slots = slots; - buses = kcalloc(bus_count, sizeof(struct ebda_hpc_bus), GFP_KERNEL); + buses = kzalloc_objs(struct ebda_hpc_bus, bus_count); if (!buses) goto error_slots; controller->buses = buses; @@ -98,12 +98,12 @@ static void free_ebda_hpc(struct controller *controller) static struct ebda_rsrc_list * __init alloc_ebda_rsrc_list(void) { - return kzalloc(sizeof(struct ebda_rsrc_list), GFP_KERNEL); + return kzalloc_obj(struct ebda_rsrc_list); } static struct ebda_pci_rsrc *alloc_ebda_pci_rsrc(void) { - return kzalloc(sizeof(struct ebda_pci_rsrc), GFP_KERNEL); + return kzalloc_obj(struct ebda_pci_rsrc); } static void __init print_bus_info(void) @@ -352,7 +352,7 @@ int __init ibmphp_access_ebda(void) debug("now enter io table ---\n"); debug("rio blk id: %x\n", blk_id); - rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); + rio_table_ptr = kzalloc_obj(struct rio_table_hdr); if (!rio_table_ptr) { rc = -ENOMEM; goto out; @@ -408,7 +408,7 @@ static int __init ebda_rio_table(void) // we do concern about rio details for (i = 0; i < rio_table_ptr->riodev_count; i++) { - rio_detail_ptr = kzalloc(sizeof(struct rio_detail), GFP_KERNEL); + rio_detail_ptr = kzalloc_obj(struct rio_detail); if (!rio_detail_ptr) return -ENOMEM; rio_detail_ptr->rio_node_id = readb(io_mem + offset); @@ -461,7 +461,7 @@ static int __init combine_wpg_for_chassis(void) list_for_each_entry(rio_detail_ptr, &rio_vg_head, rio_detail_list) { opt_rio_ptr = search_opt_vg(rio_detail_ptr->chassis_num); if (!opt_rio_ptr) { - opt_rio_ptr = kzalloc(sizeof(struct opt_rio), GFP_KERNEL); + opt_rio_ptr = kzalloc_obj(struct opt_rio); if (!opt_rio_ptr) return -ENOMEM; opt_rio_ptr->rio_type = rio_detail_ptr->rio_type; @@ -499,7 +499,7 @@ static int combine_wpg_for_expansion(void) list_for_each_entry(rio_detail_ptr, &rio_lo_head, rio_detail_list) { opt_rio_lo_ptr = search_opt_lo(rio_detail_ptr->chassis_num); if (!opt_rio_lo_ptr) { - opt_rio_lo_ptr = kzalloc(sizeof(struct opt_rio_lo), GFP_KERNEL); + opt_rio_lo_ptr = kzalloc_obj(struct opt_rio_lo); if (!opt_rio_lo_ptr) return -ENOMEM; opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type; @@ -738,7 +738,7 @@ static int __init ebda_rsrc_controller(void) bus_info_ptr2 = ibmphp_find_same_bus_num(slot_ptr->slot_bus_num); if (!bus_info_ptr2) { - bus_info_ptr1 = kzalloc(sizeof(struct bus_info), GFP_KERNEL); + bus_info_ptr1 = kzalloc_obj(struct bus_info); if (!bus_info_ptr1) { rc = -ENOMEM; goto error_no_slot; @@ -840,7 +840,7 @@ static int __init ebda_rsrc_controller(void) // register slots with hpc core as well as create linked list of ibm slot for (index = 0; index < hpc_ptr->slot_count; index++) { - tmp_slot = kzalloc(sizeof(*tmp_slot), GFP_KERNEL); + tmp_slot = kzalloc_obj(*tmp_slot); if (!tmp_slot) { rc = -ENOMEM; goto error_no_slot; diff --git a/drivers/pci/hotplug/ibmphp_pci.c b/drivers/pci/hotplug/ibmphp_pci.c index eeb412cbd9fe..cffce14879a6 100644 --- a/drivers/pci/hotplug/ibmphp_pci.c +++ b/drivers/pci/hotplug/ibmphp_pci.c @@ -152,7 +152,7 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno) cleanup_count = 6; goto error; } - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kzalloc_obj(*newfunc); if (!newfunc) return -ENOMEM; @@ -189,7 +189,7 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno) flag = 0; for (i = 0; i < 32; i++) { if (func->devices[i]) { - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kzalloc_obj(*newfunc); if (!newfunc) return -ENOMEM; @@ -216,7 +216,7 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno) } } - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kzalloc_obj(*newfunc); if (!newfunc) return -ENOMEM; @@ -261,7 +261,7 @@ int ibmphp_configure_card(struct pci_func *func, u8 slotno) for (i = 0; i < 32; i++) { if (func->devices[i]) { debug("inside for loop, device is %x\n", i); - newfunc = kzalloc(sizeof(*newfunc), GFP_KERNEL); + newfunc = kzalloc_obj(*newfunc); if (!newfunc) return -ENOMEM; @@ -384,7 +384,7 @@ static int configure_device(struct pci_func *func) debug("len[count] in IO %x, count %d\n", len[count], count); - io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + io[count] = kzalloc_obj(struct resource_node); if (!io[count]) return -ENOMEM; @@ -421,7 +421,7 @@ static int configure_device(struct pci_func *func) debug("len[count] in PFMEM %x, count %d\n", len[count], count); - pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + pfmem[count] = kzalloc_obj(struct resource_node); if (!pfmem[count]) return -ENOMEM; @@ -435,7 +435,7 @@ static int configure_device(struct pci_func *func) ibmphp_add_resource(pfmem[count]); func->pfmem[count] = pfmem[count]; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kzalloc_obj(*mem_tmp); if (!mem_tmp) { kfree(pfmem[count]); return -ENOMEM; @@ -485,7 +485,7 @@ static int configure_device(struct pci_func *func) debug("len[count] in Mem %x, count %d\n", len[count], count); - mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem[count] = kzalloc_obj(struct resource_node); if (!mem[count]) return -ENOMEM; @@ -648,7 +648,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) debug("len[count] in IO = %x\n", len[count]); - bus_io[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_io[count] = kzalloc_obj(struct resource_node); if (!bus_io[count]) { retval = -ENOMEM; @@ -680,7 +680,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) debug("len[count] in PFMEM = %x\n", len[count]); - bus_pfmem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_pfmem[count] = kzalloc_obj(struct resource_node); if (!bus_pfmem[count]) { retval = -ENOMEM; goto error; @@ -695,7 +695,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) ibmphp_add_resource(bus_pfmem[count]); func->pfmem[count] = bus_pfmem[count]; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kzalloc_obj(*mem_tmp); if (!mem_tmp) { retval = -ENOMEM; goto error; @@ -735,7 +735,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) debug("len[count] in Memory is %x\n", len[count]); - bus_mem[count] = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + bus_mem[count] = kzalloc_obj(struct resource_node); if (!bus_mem[count]) { retval = -ENOMEM; goto error; @@ -804,7 +804,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) flag_io = 1; } else { debug("it wants %x IO behind the bridge\n", amount_needed->io); - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kzalloc_obj(*io); if (!io) { retval = -ENOMEM; @@ -826,7 +826,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) flag_mem = 1; } else { debug("it wants %x memory behind the bridge\n", amount_needed->mem); - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) { retval = -ENOMEM; goto error; @@ -847,7 +847,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) flag_pfmem = 1; } else { debug("it wants %x pfmemory behind the bridge\n", amount_needed->pfmem); - pfmem = kzalloc(sizeof(*pfmem), GFP_KERNEL); + pfmem = kzalloc_obj(*pfmem); if (!pfmem) { retval = -ENOMEM; goto error; @@ -861,7 +861,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) ibmphp_add_resource(pfmem); flag_pfmem = 1; } else { - mem_tmp = kzalloc(sizeof(*mem_tmp), GFP_KERNEL); + mem_tmp = kzalloc_obj(*mem_tmp); if (!mem_tmp) { retval = -ENOMEM; goto error; @@ -891,7 +891,7 @@ static int configure_bridge(struct pci_func **func_passed, u8 slotno) */ bus = ibmphp_find_res_bus(sec_number); if (!bus) { - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (!bus) { retval = -ENOMEM; goto error; @@ -1064,7 +1064,7 @@ static struct res_needed *scan_behind_bridge(struct pci_func *func, u8 busno) }; struct res_needed *amount; - amount = kzalloc(sizeof(*amount), GFP_KERNEL); + amount = kzalloc_obj(*amount); if (amount == NULL) return NULL; @@ -1618,7 +1618,7 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re list_add(&bus->bus_list, &cur_bus->bus_list); } if (io) { - io_range = kzalloc(sizeof(*io_range), GFP_KERNEL); + io_range = kzalloc_obj(*io_range); if (!io_range) return -ENOMEM; @@ -1629,7 +1629,7 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re bus->rangeIO = io_range; } if (mem) { - mem_range = kzalloc(sizeof(*mem_range), GFP_KERNEL); + mem_range = kzalloc_obj(*mem_range); if (!mem_range) return -ENOMEM; @@ -1640,7 +1640,7 @@ static int add_new_bus(struct bus_node *bus, struct resource_node *io, struct re bus->rangeMem = mem_range; } if (pfmem) { - pfmem_range = kzalloc(sizeof(*pfmem_range), GFP_KERNEL); + pfmem_range = kzalloc_obj(*pfmem_range); if (!pfmem_range) return -ENOMEM; diff --git a/drivers/pci/hotplug/ibmphp_res.c b/drivers/pci/hotplug/ibmphp_res.c index 4a72ade2cddb..0294fd97e6db 100644 --- a/drivers/pci/hotplug/ibmphp_res.c +++ b/drivers/pci/hotplug/ibmphp_res.c @@ -41,7 +41,7 @@ static struct bus_node * __init alloc_error_bus(struct ebda_pci_rsrc *curr, u8 b return NULL; } - newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); + newbus = kzalloc_obj(struct bus_node); if (!newbus) return NULL; @@ -62,7 +62,7 @@ static struct resource_node * __init alloc_resources(struct ebda_pci_rsrc *curr) return NULL; } - rs = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + rs = kzalloc_obj(struct resource_node); if (!rs) return NULL; @@ -81,7 +81,7 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node * u8 num_ranges = 0; if (first_bus) { - newbus = kzalloc(sizeof(struct bus_node), GFP_KERNEL); + newbus = kzalloc_obj(struct bus_node); if (!newbus) return -ENOMEM; @@ -101,7 +101,7 @@ static int __init alloc_bus_range(struct bus_node **new_bus, struct range_node * } } - newrange = kzalloc(sizeof(struct range_node), GFP_KERNEL); + newrange = kzalloc_obj(struct range_node); if (!newrange) { if (first_bus) kfree(newbus); @@ -1687,7 +1687,7 @@ static int __init once_over(void) bus_cur->firstPFMemFromMem = pfmem_cur; - mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem = kzalloc_obj(struct resource_node); if (!mem) return -ENOMEM; @@ -1969,7 +1969,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) end_address |= (upper_io_end << 16); if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kzalloc_obj(struct range_node); if (!range) return -ENOMEM; @@ -1993,7 +1993,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) fix_resources(bus_sec); if (ibmphp_find_resource(bus_cur, start_address, &io, IO)) { - io = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + io = kzalloc_obj(struct resource_node); if (!io) { kfree(range); return -ENOMEM; @@ -2016,7 +2016,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kzalloc_obj(struct range_node); if (!range) return -ENOMEM; @@ -2041,7 +2041,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) fix_resources(bus_sec); if (ibmphp_find_resource(bus_cur, start_address, &mem, MEM)) { - mem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + mem = kzalloc_obj(struct resource_node); if (!mem) { kfree(range); return -ENOMEM; @@ -2068,7 +2068,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) if ((start_address) && (start_address <= end_address)) { - range = kzalloc(sizeof(struct range_node), GFP_KERNEL); + range = kzalloc_obj(struct range_node); if (!range) return -ENOMEM; @@ -2092,7 +2092,7 @@ static int __init update_bridge_ranges(struct bus_node **bus) fix_resources(bus_sec); if (ibmphp_find_resource(bus_cur, start_address, &pfmem, PFMEM)) { - pfmem = kzalloc(sizeof(struct resource_node), GFP_KERNEL); + pfmem = kzalloc_obj(struct resource_node); if (!pfmem) { kfree(range); return -ENOMEM; diff --git a/drivers/pci/hotplug/octep_hp.c b/drivers/pci/hotplug/octep_hp.c index 2bce7296c050..a0a7f9ccb8fa 100644 --- a/drivers/pci/hotplug/octep_hp.c +++ b/drivers/pci/hotplug/octep_hp.c @@ -136,7 +136,7 @@ octep_hp_register_slot(struct octep_hp_controller *hp_ctrl, struct octep_hp_slot *hp_slot; int ret; - hp_slot = kzalloc(sizeof(*hp_slot), GFP_KERNEL); + hp_slot = kzalloc_obj(*hp_slot); if (!hp_slot) return ERR_PTR(-ENOMEM); @@ -271,7 +271,7 @@ static irqreturn_t octep_hp_intr_handler(int irq, void *data) intr_val = readq(hp_ctrl->base + OCTEP_HP_INTR_OFFSET(type)); writeq(intr_val, hp_ctrl->base + OCTEP_HP_INTR_OFFSET(type)); - hp_cmd = kzalloc(sizeof(*hp_cmd), GFP_ATOMIC); + hp_cmd = kzalloc_obj(*hp_cmd, GFP_ATOMIC); if (!hp_cmd) return IRQ_HANDLED; diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index f59baa912970..1e9158d7bac7 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -55,7 +55,7 @@ static int init_slot(struct controller *ctrl) int retval; /* Setup hotplug slot ops */ - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (!ops) return -ENOMEM; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index ad5f28f6a8b1..4c62140a3cb4 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -1011,7 +1011,7 @@ struct controller *pcie_init(struct pcie_device *dev) struct pci_dev *pdev = dev->port; struct pci_bus *subordinate = pdev->subordinate; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return NULL; diff --git a/drivers/pci/hotplug/pnv_php.c b/drivers/pci/hotplug/pnv_php.c index 35f1758126c6..5c020831e318 100644 --- a/drivers/pci/hotplug/pnv_php.c +++ b/drivers/pci/hotplug/pnv_php.c @@ -791,7 +791,7 @@ static struct pnv_php_slot *pnv_php_alloc_slot(struct device_node *dn) if (!bus) return NULL; - php_slot = kzalloc(sizeof(*php_slot), GFP_KERNEL); + php_slot = kzalloc_obj(*php_slot); if (!php_slot) return NULL; @@ -1028,7 +1028,7 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data) * The PE is left in frozen state if the event is missed. It's * fine as the PCI devices (PE) aren't functional any more. */ - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) { SLOT_WARN(php_slot, "PCI slot [%s] missed hotplug event 0x%04x\n", diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 779eab12e981..33ca19200c1b 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -32,7 +32,7 @@ struct slot *alloc_slot_struct(struct device_node *dn, { struct slot *slot; - slot = kzalloc(sizeof(struct slot), GFP_KERNEL); + slot = kzalloc_obj(struct slot); if (!slot) goto error_nomem; slot->name = kstrdup(drc_name, GFP_KERNEL); diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 56308515ecba..8d6f8eea599d 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -66,7 +66,7 @@ static int init_slots(struct controller *ctrl) int i; for (i = 0; i < ctrl->num_slots; i++) { - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) { retval = -ENOMEM; goto error; @@ -259,7 +259,7 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (acpi_get_hp_hw_control_from_firmware(pdev)) return -ENODEV; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) goto err_out_none; diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index e6c6f23bae27..a10cdcdcbbdc 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -29,7 +29,7 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type) { struct event_info *info; - info = kmalloc(sizeof(*info), GFP_ATOMIC); + info = kmalloc_obj(*info, GFP_ATOMIC); if (!info) return -ENOMEM; @@ -418,7 +418,7 @@ void shpchp_queue_pushbutton_work(struct work_struct *work) struct slot *p_slot = container_of(work, struct slot, work.work); struct pushbutton_work_info *info; - info = kmalloc(sizeof(*info), GFP_KERNEL); + info = kmalloc_obj(*info); if (!info) { ctrl_err(p_slot->ctrl, "%s: Cannot allocate memory\n", __func__); diff --git a/drivers/pci/ide.c b/drivers/pci/ide.c index 23f554490539..be74e8f0ae21 100644 --- a/drivers/pci/ide.c +++ b/drivers/pci/ide.c @@ -258,7 +258,7 @@ struct pci_ide *pci_ide_stream_alloc(struct pci_dev *pdev) if (!pdev->ide_cap) return NULL; - struct pci_ide *ide __free(kfree) = kzalloc(sizeof(*ide), GFP_KERNEL); + struct pci_ide *ide __free(kfree) = kzalloc_obj(*ide); if (!ide) return NULL; diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 4a659c34935e..91ac4e37ecb9 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -837,7 +837,7 @@ static int sriov_init(struct pci_dev *dev, int pos) pgsz &= ~(pgsz - 1); pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz); - iov = kzalloc(sizeof(*iov), GFP_KERNEL); + iov = kzalloc_obj(*iov); if (!iov) return -ENOMEM; diff --git a/drivers/pci/npem.c b/drivers/pci/npem.c index 97507e0df769..ffeeedf6e311 100644 --- a/drivers/pci/npem.c +++ b/drivers/pci/npem.c @@ -524,7 +524,7 @@ static int pci_npem_init(struct pci_dev *dev, const struct npem_ops *ops, int led_idx = 0; int ret; - npem = kzalloc(struct_size(npem, leds, supported_cnt), GFP_KERNEL); + npem = kzalloc_flex(*npem, leds, supported_cnt); if (!npem) return -ENOMEM; diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 9bb5f258759b..9f8eb5df279e 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -696,7 +696,7 @@ void of_pci_make_dev_node(struct pci_dev *pdev) if (!name) return; - cset = kmalloc(sizeof(*cset), GFP_KERNEL); + cset = kmalloc_obj(*cset); if (!cset) goto out_free_name; of_changeset_init(cset); @@ -784,7 +784,7 @@ void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge) if (!name) return; - cset = kmalloc(sizeof(*cset), GFP_KERNEL); + cset = kmalloc_obj(*cset); if (!cset) goto out_free_name; of_changeset_init(cset); diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 7aae46f333d9..75a358f73e69 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -119,7 +119,7 @@ static int of_pci_prop_ranges(struct pci_dev *pdev, struct of_changeset *ocs, res = &pdev->resource[PCI_STD_RESOURCES]; } - rp = kcalloc(num, sizeof(*rp), GFP_KERNEL); + rp = kzalloc_objs(*rp, num); if (!rp) return -ENOMEM; diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 79a414fd6623..e0f546166eb8 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -1006,7 +1006,7 @@ struct scatterlist *pci_p2pmem_alloc_sgl(struct pci_dev *pdev, struct scatterlist *sg; void *addr; - sg = kmalloc(sizeof(*sg), GFP_KERNEL); + sg = kmalloc_obj(*sg); if (!sg) return NULL; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 218e1fc1c1e2..4d0f2cb6c695 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -1663,11 +1663,11 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) struct acpi_pci_root_ops *root_ops; struct pci_host_bridge *host; - ri = kzalloc(sizeof(*ri), GFP_KERNEL); + ri = kzalloc_obj(*ri); if (!ri) return NULL; - root_ops = kzalloc(sizeof(*root_ops), GFP_KERNEL); + root_ops = kzalloc_obj(*root_ops); if (!root_ops) { kfree(ri); return NULL; diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 47887d55994a..dd9075403987 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -58,7 +58,7 @@ int pci_add_dynid(struct pci_driver *drv, { struct pci_dynid *dynid; - dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); + dynid = kzalloc_obj(*dynid); if (!dynid) return -ENOMEM; @@ -203,7 +203,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf, return -EINVAL; if (fields != 7) { - struct pci_dev *pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + struct pci_dev *pdev = kzalloc_obj(*pdev); if (!pdev) return -ENOMEM; diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 363187ba4f56..16eaaf749ba9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -1037,8 +1037,7 @@ void pci_create_legacy_files(struct pci_bus *b) if (!sysfs_initialized) return; - b->legacy_io = kcalloc(2, sizeof(struct bin_attribute), - GFP_ATOMIC); + b->legacy_io = kzalloc_objs(struct bin_attribute, 2, GFP_ATOMIC); if (!b->legacy_io) goto kzalloc_err; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f3244630bfd0..8479c2e1f74f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2462,8 +2462,7 @@ void pci_pme_active(struct pci_dev *dev, bool enable) if (dev->pme_poll) { struct pci_pme_device *pme_dev; if (enable) { - pme_dev = kmalloc(sizeof(struct pci_pme_device), - GFP_KERNEL); + pme_dev = kmalloc_obj(struct pci_pme_device); if (!pme_dev) { pci_warn(dev, "can't enable PME#\n"); return; @@ -3980,7 +3979,7 @@ int pci_register_io_range(const struct fwnode_handle *fwnode, phys_addr_t addr, if (!size || addr + size < addr) return -EINVAL; - range = kzalloc(sizeof(*range), GFP_ATOMIC); + range = kzalloc_obj(*range, GFP_ATOMIC); if (!range) return -ENOMEM; diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c index 8dfbb0fe6cf6..d916378bc707 100644 --- a/drivers/pci/pcie/aer.c +++ b/drivers/pci/pcie/aer.c @@ -390,7 +390,7 @@ void pci_aer_init(struct pci_dev *dev) if (!dev->aer_cap) return; - dev->aer_info = kzalloc(sizeof(*dev->aer_info), GFP_KERNEL); + dev->aer_info = kzalloc_obj(*dev->aer_info); if (!dev->aer_info) { dev->aer_cap = 0; return; diff --git a/drivers/pci/pcie/aer_inject.c b/drivers/pci/pcie/aer_inject.c index 91acc7b17f68..09bfc7194ef3 100644 --- a/drivers/pci/pcie/aer_inject.c +++ b/drivers/pci/pcie/aer_inject.c @@ -300,7 +300,7 @@ static int pci_bus_set_aer_ops(struct pci_bus *bus) struct pci_bus_ops *bus_ops; unsigned long flags; - bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL); + bus_ops = kmalloc_obj(*bus_ops); if (!bus_ops) return -ENOMEM; ops = pci_bus_set_ops(bus, &aer_inj_pci_ops); @@ -360,12 +360,12 @@ static int aer_inject(struct aer_error_inj *einj) goto out_put; } - err_alloc = kzalloc(sizeof(struct aer_error), GFP_KERNEL); + err_alloc = kzalloc_obj(struct aer_error); if (!err_alloc) { ret = -ENOMEM; goto out_put; } - rperr_alloc = kzalloc(sizeof(struct aer_error), GFP_KERNEL); + rperr_alloc = kzalloc_obj(struct aer_error); if (!rperr_alloc) { ret = -ENOMEM; goto out_put; diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index cedea47a3547..21f5d23e0b61 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -1063,7 +1063,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev) { struct pcie_link_state *link; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return NULL; diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index a2daebd9806c..4996cc4789f3 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -335,7 +335,7 @@ static int pcie_pme_probe(struct pcie_device *srv) type != PCI_EXP_TYPE_ROOT_PORT) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/pci/pcie/portdrv.c b/drivers/pci/pcie/portdrv.c index 88af0dacf351..2d6aa488fe7b 100644 --- a/drivers/pci/pcie/portdrv.c +++ b/drivers/pci/pcie/portdrv.c @@ -293,7 +293,7 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) struct pcie_device *pcie; struct device *device; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return -ENOMEM; pcie->port = pdev; diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index c7c61869bc9c..91a598ed534c 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -537,7 +537,7 @@ struct pci_ptm_debugfs *pcie_ptm_create_debugfs(struct device *dev, void *pdata, return NULL; } - ptm_debugfs = kzalloc(sizeof(*ptm_debugfs), GFP_KERNEL); + ptm_debugfs = kzalloc_obj(*ptm_debugfs); if (!ptm_debugfs) return NULL; diff --git a/drivers/pci/pcie/rcec.c b/drivers/pci/pcie/rcec.c index d0bcd141ac9c..2bf6d9d549ba 100644 --- a/drivers/pci/pcie/rcec.c +++ b/drivers/pci/pcie/rcec.c @@ -160,7 +160,7 @@ void pci_rcec_init(struct pci_dev *dev) if (!rcec) return; - rcec_ea = kzalloc(sizeof(*rcec_ea), GFP_KERNEL); + rcec_ea = kzalloc_obj(*rcec_ea); if (!rcec_ea) return; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2975974f35e8..bccc7a4bdd79 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -53,7 +53,7 @@ static struct resource *get_pci_domain_busn_res(int domain_nr) if (r->domain_nr == domain_nr) return &r->res; - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) return NULL; @@ -620,7 +620,7 @@ static struct pci_bus *pci_alloc_bus(struct pci_bus *parent) { struct pci_bus *b; - b = kzalloc(sizeof(*b), GFP_KERNEL); + b = kzalloc_obj(*b); if (!b) return NULL; @@ -2502,7 +2502,7 @@ struct pci_dev *pci_alloc_dev(struct pci_bus *bus) { struct pci_dev *dev; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = kzalloc_obj(struct pci_dev); if (!dev) return NULL; diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 9348a0fb8084..ce36e35681e8 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -297,7 +297,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) static int proc_bus_pci_open(struct inode *inode, struct file *file) { - struct pci_filp_private *fpriv = kmalloc(sizeof(*fpriv), GFP_KERNEL); + struct pci_filp_private *fpriv = kmalloc_obj(*fpriv); if (!fpriv) return -ENOMEM; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 32aa72456a44..61f769aaa2f6 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -73,7 +73,7 @@ int pci_dev_res_add_to_list(struct list_head *head, struct pci_dev *dev, { struct pci_dev_resource *tmp; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return -ENOMEM; @@ -224,14 +224,21 @@ static struct resource *pbus_select_window_for_type(struct pci_bus *bus, switch (iores_type) { case IORESOURCE_IO: - return pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); + win = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_IO_WINDOW); + if (win && (win->flags & IORESOURCE_IO)) + return win; + return NULL; case IORESOURCE_MEM: mmio = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_MEM_WINDOW); mmio_pref = pci_bus_resource_n(bus, PCI_BUS_BRIDGE_PREF_MEM_WINDOW); - if (!(type & IORESOURCE_PREFETCH) || - !(mmio_pref->flags & IORESOURCE_MEM)) + if (mmio && !(mmio->flags & IORESOURCE_MEM)) + mmio = NULL; + if (mmio_pref && !(mmio_pref->flags & IORESOURCE_MEM)) + mmio_pref = NULL; + + if (!(type & IORESOURCE_PREFETCH) || !mmio_pref) return mmio; if ((type & IORESOURCE_MEM_64) || @@ -343,7 +350,7 @@ static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) continue; } - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) panic("%s: kzalloc() failed!\n", __func__); tmp->res = r; @@ -1217,31 +1224,34 @@ static bool pbus_size_mem_optional(struct pci_dev *dev, int resno, struct resource *res = pci_resource_n(dev, resno); bool optional = pci_resource_is_optional(dev, resno); resource_size_t r_size = resource_size(res); - struct pci_dev_resource *dev_res; + struct pci_dev_resource *dev_res = NULL; if (!realloc_head) return false; - if (!optional) { - /* - * Only bridges have optional sizes in realloc_head at this - * point. As res_to_dev_res() walks the entire realloc_head - * list, skip calling it when known unnecessary. - */ - if (!pci_resource_is_bridge_win(resno)) - return false; - + /* + * Only bridges have optional sizes in realloc_head at this + * point. As res_to_dev_res() walks the entire realloc_head + * list, skip calling it when known unnecessary. + */ + if (pci_resource_is_bridge_win(resno)) { dev_res = res_to_dev_res(realloc_head, res); if (dev_res) { *children_add_size += dev_res->add_size; *add_align = max(*add_align, dev_res->min_align); } - - return false; } - /* Put SRIOV requested res to the optional list */ - pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); + if (!optional) + return false; + + /* + * Put requested res to the optional list if not there yet (SR-IOV, + * disabled ROM). Bridge windows with an optional part are already + * on the list. + */ + if (!dev_res) + pci_dev_res_add_to_list(realloc_head, dev, res, 0, align); *children_add_size += r_size; *add_align = max(align, *add_align); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 50fb3eb595fe..787311614e5b 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -256,7 +256,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, } placeholder: - slot = kzalloc(sizeof(*slot), GFP_KERNEL); + slot = kzalloc_obj(*slot); if (!slot) { err = -ENOMEM; goto err; diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c index 5ff84fb8fb0f..93ebec94b763 100644 --- a/drivers/pci/switch/switchtec.c +++ b/drivers/pci/switch/switchtec.c @@ -86,7 +86,7 @@ static struct switchtec_user *stuser_create(struct switchtec_dev *stdev) { struct switchtec_user *stuser; - stuser = kzalloc(sizeof(*stuser), GFP_KERNEL); + stuser = kzalloc_obj(*stuser); if (!stuser) return ERR_PTR(-ENOMEM); @@ -895,7 +895,7 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, u32 reg; int ret = 0; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; diff --git a/drivers/pci/vgaarb.c b/drivers/pci/vgaarb.c index 87143e235033..d9383bf541e7 100644 --- a/drivers/pci/vgaarb.c +++ b/drivers/pci/vgaarb.c @@ -735,7 +735,7 @@ static bool vga_arbiter_add_pci_device(struct pci_dev *pdev) u16 cmd; /* Allocate structure */ - vgadev = kzalloc(sizeof(struct vga_device), GFP_KERNEL); + vgadev = kzalloc_obj(struct vga_device); if (vgadev == NULL) { vgaarb_err(&pdev->dev, "failed to allocate VGA arbiter data\n"); /* @@ -1385,7 +1385,7 @@ static int vga_arb_open(struct inode *inode, struct file *file) pr_debug("%s\n", __func__); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return -ENOMEM; spin_lock_init(&priv->lock); diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 11636634ae51..cffc32d66032 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -462,8 +462,8 @@ static int pcifront_scan_root(struct pcifront_device *pdev, dev_info(&pdev->xdev->dev, "Creating PCI Frontend Bus %04x:%02x\n", domain, bus); - bus_entry = kzalloc(sizeof(*bus_entry), GFP_KERNEL); - sd = kzalloc(sizeof(*sd), GFP_KERNEL); + bus_entry = kzalloc_obj(*bus_entry); + sd = kzalloc_obj(*sd); if (!bus_entry || !sd) { err = -ENOMEM; goto err_out; @@ -687,7 +687,7 @@ static struct pcifront_device *alloc_pdev(struct xenbus_device *xdev) { struct pcifront_device *pdev; - pdev = kzalloc(sizeof(struct pcifront_device), GFP_KERNEL); + pdev = kzalloc_obj(struct pcifront_device); if (pdev == NULL) goto out; @@ -856,7 +856,7 @@ static void pcifront_try_connect(struct pcifront_device *pdev) int err; /* Only connect once */ - if (xenbus_read_driver_state(pdev->xdev->nodename) != + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != XenbusStateInitialised) return; @@ -876,7 +876,7 @@ static int pcifront_try_disconnect(struct pcifront_device *pdev) enum xenbus_state prev_state; - prev_state = xenbus_read_driver_state(pdev->xdev->nodename); + prev_state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename); if (prev_state >= XenbusStateClosing) goto out; @@ -895,7 +895,7 @@ static int pcifront_try_disconnect(struct pcifront_device *pdev) static void pcifront_attach_devices(struct pcifront_device *pdev) { - if (xenbus_read_driver_state(pdev->xdev->nodename) == + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) == XenbusStateReconfiguring) pcifront_connect(pdev); } @@ -909,7 +909,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) struct pci_dev *pci_dev; char str[64]; - state = xenbus_read_driver_state(pdev->xdev->nodename); + state = xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename); if (state == XenbusStateInitialised) { dev_dbg(&pdev->xdev->dev, "Handle skipped connect.\n"); /* We missed Connected and need to initialize. */ diff --git a/drivers/pcmcia/bcm63xx_pcmcia.c b/drivers/pcmcia/bcm63xx_pcmcia.c index d3baed444646..724fd6ee0fd0 100644 --- a/drivers/pcmcia/bcm63xx_pcmcia.c +++ b/drivers/pcmcia/bcm63xx_pcmcia.c @@ -333,7 +333,7 @@ static int bcm63xx_drv_pcmcia_probe(struct platform_device *pdev) int ret; int irq; - skt = kzalloc(sizeof(*skt), GFP_KERNEL); + skt = kzalloc_obj(*skt); if (!skt) return -ENOMEM; spin_lock_init(&skt->lock); diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 05b67fd93de6..d73ec3281b5e 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c @@ -1393,12 +1393,12 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info) destroy_cis_cache(s); mutex_unlock(&s->ops_mutex); - tuple = kmalloc(sizeof(*tuple), GFP_KERNEL); + tuple = kmalloc_obj(*tuple); if (tuple == NULL) { dev_warn(&s->dev, "no memory to validate CIS\n"); return -ENOMEM; } - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (p == NULL) { kfree(tuple); dev_warn(&s->dev, "no memory to validate CIS\n"); @@ -1480,11 +1480,11 @@ static ssize_t pccard_extract_cis(struct pcmcia_socket *s, char *buf, u_char *tuplebuffer; u_char *tempbuffer; - tuplebuffer = kmalloc_array(256, sizeof(u_char), GFP_KERNEL); + tuplebuffer = kmalloc_objs(u_char, 256); if (!tuplebuffer) return -ENOMEM; - tempbuffer = kmalloc_array(258, sizeof(u_char), GFP_KERNEL); + tempbuffer = kmalloc_objs(u_char, 258); if (!tempbuffer) { ret = -ENOMEM; goto free_tuple; diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 85d2616061dd..7b896d7dbc9f 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c @@ -427,7 +427,7 @@ static int db1x_pcmcia_socket_probe(struct platform_device *pdev) struct resource *r; int ret, bid; - sock = kzalloc(sizeof(struct db1x_pcmcia_sock), GFP_KERNEL); + sock = kzalloc_obj(struct db1x_pcmcia_sock); if (!sock) return -ENOMEM; diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 18f4eef28dbc..cc9f74391cf1 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -108,7 +108,7 @@ new_id_store(struct device_driver *driver, const char *buf, size_t count) if (fields < 6) return -EINVAL; - dynid = kzalloc(sizeof(struct pcmcia_dynid), GFP_KERNEL); + dynid = kzalloc_obj(struct pcmcia_dynid); if (!dynid) return -ENOMEM; @@ -402,7 +402,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) cistpl_vers_1_t *vers1; unsigned int i; - vers1 = kmalloc(sizeof(*vers1), GFP_KERNEL); + vers1 = kmalloc_obj(*vers1); if (!vers1) return -ENOMEM; @@ -428,7 +428,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) * probably memory cards (from pcmcia-cs) */ cistpl_device_geo_t *devgeo; - devgeo = kmalloc(sizeof(*devgeo), GFP_KERNEL); + devgeo = kmalloc_obj(*devgeo); if (!devgeo) { kfree(vers1); return -ENOMEM; @@ -488,7 +488,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, pr_debug("adding device to %d, function %d\n", s->sock, function); - p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); + p_dev = kzalloc_obj(struct pcmcia_device); if (!p_dev) goto err_put; @@ -542,7 +542,7 @@ static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, if (!p_dev->function_config) { config_t *c; dev_dbg(&p_dev->dev, "creating config_t\n"); - c = kzalloc(sizeof(struct config_t), GFP_KERNEL); + c = kzalloc_obj(struct config_t); if (!c) { mutex_unlock(&s->ops_mutex); goto err_unreg; diff --git a/drivers/pcmcia/electra_cf.c b/drivers/pcmcia/electra_cf.c index 2530079d38f4..e9179d0ae234 100644 --- a/drivers/pcmcia/electra_cf.c +++ b/drivers/pcmcia/electra_cf.c @@ -190,7 +190,7 @@ static int electra_cf_probe(struct platform_device *ofdev) if (err) return -EINVAL; - cf = kzalloc(sizeof(*cf), GFP_KERNEL); + cf = kzalloc_obj(*cf); if (!cf) return -ENOMEM; diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index d6f24c7d1562..49621074a47a 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c @@ -218,7 +218,7 @@ static int __init omap_cf_probe(struct platform_device *pdev) if (!res) return -EINVAL; - cf = kzalloc(sizeof *cf, GFP_KERNEL); + cf = kzalloc_obj(*cf); if (!cf) return -ENOMEM; timer_setup(&cf->timer, omap_cf_timer, 0); diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 6bc0bc24d357..0f474629229f 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c @@ -264,7 +264,7 @@ int pcmcia_loop_config(struct pcmcia_device *p_dev, struct pcmcia_cfg_mem *cfg_mem; int ret; - cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); + cfg_mem = kzalloc_obj(struct pcmcia_cfg_mem); if (cfg_mem == NULL) return -ENOMEM; diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 6868b60fd325..1b62ca30d08a 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c @@ -629,8 +629,7 @@ static int pd6729_pci_probe(struct pci_dev *dev, char configbyte; struct pd6729_socket *socket; - socket = kcalloc(MAX_SOCKETS, sizeof(struct pd6729_socket), - GFP_KERNEL); + socket = kzalloc_objs(struct pd6729_socket, MAX_SOCKETS); if (!socket) { dev_warn(&dev->dev, "failed to kzalloc socket.\n"); return -ENOMEM; diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 3a1d2baa466f..25b12c585ecb 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c @@ -31,7 +31,7 @@ struct resource *pcmcia_make_resource(resource_size_t start, resource_size_t end, unsigned long flags, const char *name) { - struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); + struct resource *res = kzalloc_obj(*res); if (res) { res->name = name; diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c index da494fe451ba..0679dd434719 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c @@ -117,7 +117,7 @@ static int add_interval(struct resource_map *map, u_long base, u_long num) if ((p->next == map) || (p->next->base > base+num-1)) break; } - q = kmalloc(sizeof(struct resource_map), GFP_KERNEL); + q = kmalloc_obj(struct resource_map); if (!q) { printk(KERN_WARNING "out of memory to update resources\n"); return -ENOMEM; @@ -155,8 +155,7 @@ static int sub_interval(struct resource_map *map, u_long base, u_long num) q->num = base - q->base; } else { /* Split the block into two pieces */ - p = kmalloc(sizeof(struct resource_map), - GFP_KERNEL); + p = kmalloc_obj(struct resource_map); if (!p) { printk(KERN_WARNING "out of memory to update resources\n"); return -ENOMEM; @@ -1023,7 +1022,7 @@ static int nonstatic_init(struct pcmcia_socket *s) { struct socket_data *data; - data = kzalloc(sizeof(struct socket_data), GFP_KERNEL); + data = kzalloc_obj(struct socket_data); if (!data) return -ENOMEM; diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 2a67e33fb5f0..55ea3ea6851b 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -153,7 +153,7 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, ops->socket_state = sa1111_pcmcia_socket_state; for (i = 0; i < ops->nr; i++) { - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index f84dd5914a6b..8a8aae1843b5 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c @@ -212,7 +212,7 @@ static int xxs1500_pcmcia_probe(struct platform_device *pdev) struct resource *r; int ret, irq; - sock = kzalloc(sizeof(struct xxs1500_pcmcia_sock), GFP_KERNEL); + sock = kzalloc_obj(struct xxs1500_pcmcia_sock); if (!sock) return -ENOMEM; diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 34c4eaee7dfc..54dc1fee57aa 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c @@ -1171,7 +1171,7 @@ static int yenta_probe(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; } - socket = kzalloc(sizeof(struct yenta_socket), GFP_KERNEL); + socket = kzalloc_obj(struct yenta_socket); if (!socket) return -ENOMEM; diff --git a/drivers/peci/core.c b/drivers/peci/core.c index 936c1fadefe5..e14995b1bf7f 100644 --- a/drivers/peci/core.c +++ b/drivers/peci/core.c @@ -52,7 +52,7 @@ static struct peci_controller *peci_controller_alloc(struct device *dev, if (!ops->xfer) return ERR_PTR(-EINVAL); - controller = kzalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc_obj(*controller); if (!controller) return ERR_PTR(-ENOMEM); diff --git a/drivers/peci/cpu.c b/drivers/peci/cpu.c index fbccc1d1b637..c9fc06c9ff53 100644 --- a/drivers/peci/cpu.c +++ b/drivers/peci/cpu.c @@ -199,7 +199,7 @@ static struct auxiliary_device *adev_alloc(struct peci_cpu *priv, int idx) const char *name; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return ERR_PTR(-ENOMEM); diff --git a/drivers/peci/device.c b/drivers/peci/device.c index 416635029f55..2b9610216c8b 100644 --- a/drivers/peci/device.c +++ b/drivers/peci/device.c @@ -170,7 +170,7 @@ int peci_device_create(struct peci_controller *controller, u8 addr) return ret; } - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return -ENOMEM; diff --git a/drivers/peci/request.c b/drivers/peci/request.c index e6327af45fc7..db2cc30a42a4 100644 --- a/drivers/peci/request.c +++ b/drivers/peci/request.c @@ -203,7 +203,7 @@ struct peci_request *peci_request_alloc(struct peci_device *device, u8 tx_len, u * should be converted to DMA API once support for controllers that do * allow it is added to avoid an extra copy. */ - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return NULL; diff --git a/drivers/perf/alibaba_uncore_drw_pmu.c b/drivers/perf/alibaba_uncore_drw_pmu.c index 99a0ef9817e0..ac49d3b2dad6 100644 --- a/drivers/perf/alibaba_uncore_drw_pmu.c +++ b/drivers/perf/alibaba_uncore_drw_pmu.c @@ -431,7 +431,7 @@ static struct ali_drw_pmu_irq *__ali_drw_pmu_init_irq(struct platform_device return irq; } - irq = kzalloc(sizeof(*irq), GFP_KERNEL); + irq = kzalloc_obj(*irq); if (!irq) return ERR_PTR(-ENOMEM); diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c index 4fbafc4b7984..40c05c519a1d 100644 --- a/drivers/perf/arm-cmn.c +++ b/drivers/perf/arm-cmn.c @@ -1700,7 +1700,7 @@ static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event) if (event->pmu != leader->pmu && !is_software_event(leader)) return -EINVAL; - val = kzalloc(sizeof(*val), GFP_KERNEL); + val = kzalloc_obj(*val); if (!val) return -ENOMEM; diff --git a/drivers/perf/arm_dmc620_pmu.c b/drivers/perf/arm_dmc620_pmu.c index 619cf937602f..4f6b196160f8 100644 --- a/drivers/perf/arm_dmc620_pmu.c +++ b/drivers/perf/arm_dmc620_pmu.c @@ -432,7 +432,7 @@ static struct dmc620_pmu_irq *__dmc620_pmu_get_irq(int irq_num) if (irq->irq_num == irq_num && refcount_inc_not_zero(&irq->refcount)) return irq; - irq = kzalloc(sizeof(*irq), GFP_KERNEL); + irq = kzalloc_obj(*irq); if (!irq) return ERR_PTR(-ENOMEM); diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c index 973a027d9063..939bcbd433aa 100644 --- a/drivers/perf/arm_pmu.c +++ b/drivers/perf/arm_pmu.c @@ -864,7 +864,7 @@ struct arm_pmu *armpmu_alloc(void) struct arm_pmu *pmu; int cpu; - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + pmu = kzalloc_obj(*pmu); if (!pmu) goto out; diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c index 5410fb7428d0..dbd0da111639 100644 --- a/drivers/perf/arm_spe_pmu.c +++ b/drivers/perf/arm_spe_pmu.c @@ -1020,7 +1020,7 @@ static void *arm_spe_pmu_setup_aux(struct perf_event *event, void **pages, if (!buf) return NULL; - pglist = kcalloc(nr_pages, sizeof(*pglist), GFP_KERNEL); + pglist = kzalloc_objs(*pglist, nr_pages); if (!pglist) goto out_free_buf; diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c index 22f73ac894e9..5385401fa9cf 100644 --- a/drivers/perf/dwc_pcie_pmu.c +++ b/drivers/perf/dwc_pcie_pmu.c @@ -649,7 +649,7 @@ static int dwc_pcie_register_dev(struct pci_dev *pdev) if (IS_ERR(plat_dev)) return PTR_ERR(plat_dev); - dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL); + dev_info = kzalloc_obj(*dev_info); if (!dev_info) { platform_device_unregister(plat_dev); return -ENOMEM; diff --git a/drivers/perf/riscv_pmu.c b/drivers/perf/riscv_pmu.c index 7644147d50b4..8e3cd0f35336 100644 --- a/drivers/perf/riscv_pmu.c +++ b/drivers/perf/riscv_pmu.c @@ -389,7 +389,7 @@ struct riscv_pmu *riscv_pmu_alloc(void) int cpuid, i; struct cpu_hw_events *cpuc; - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + pmu = kzalloc_obj(*pmu); if (!pmu) goto out; diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c index 9dcc22fd48ef..385af5e6e6d0 100644 --- a/drivers/perf/riscv_pmu_sbi.c +++ b/drivers/perf/riscv_pmu_sbi.c @@ -309,7 +309,7 @@ static int pmu_sbi_check_event_info(void) int i, j, k, result = 0, count = 0; struct sbiret ret; - event_info_shmem = kcalloc(num_events, sizeof(*event_info_shmem), GFP_KERNEL); + event_info_shmem = kzalloc_objs(*event_info_shmem, num_events); if (!event_info_shmem) return -ENOMEM; @@ -872,7 +872,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, unsigned long *mask) int i, num_hw_ctr = 0, num_fw_ctr = 0; union sbi_pmu_ctr_info cinfo; - pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL); + pmu_ctr_list = kzalloc_objs(*pmu_ctr_list, nctr); if (!pmu_ctr_list) return -ENOMEM; diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index 62153a3924b9..02467dfd4fb0 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -47,6 +47,17 @@ config GENERIC_PHY_MIPI_DPHY Provides a number of helpers a core functions for MIPI D-PHY drivers to us. +config PHY_GOOGLE_USB + tristate "Google Tensor SoC USB PHY driver" + select GENERIC_PHY + depends on TYPEC + help + Enable support for the USB PHY on Google Tensor SoCs, starting with + the G5 generation (Laguna). This driver provides the PHY interfaces + to interact with the SNPS eUSB2 and USB 3.2/DisplayPort Combo PHY, + both of which are integrated with the DWC3 USB DRD controller. + This driver currently supports USB high-speed. + config PHY_LPC18XX_USB_OTG tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver" depends on OF && (ARCH_LPC18XX || COMPILE_TEST) @@ -123,8 +134,21 @@ config PHY_NXP_PTN3222 schemes. It supports all three USB 2.0 data rates: Low Speed, Full Speed and High Speed. +config PHY_SPACEMIT_K1_PCIE + tristate "PCIe and combo PHY driver for the SpacemiT K1 SoC" + depends on ARCH_SPACEMIT || COMPILE_TEST + depends on COMMON_CLK + depends on HAS_IOMEM + depends on OF + select GENERIC_PHY + default ARCH_SPACEMIT + help + Enable support for the PCIe and USB 3 combo PHY and two + PCIe-only PHYs used in the SpacemiT K1 SoC. + source "drivers/phy/allwinner/Kconfig" source "drivers/phy/amlogic/Kconfig" +source "drivers/phy/apple/Kconfig" source "drivers/phy/broadcom/Kconfig" source "drivers/phy/cadence/Kconfig" source "drivers/phy/freescale/Kconfig" @@ -145,6 +169,7 @@ source "drivers/phy/rockchip/Kconfig" source "drivers/phy/samsung/Kconfig" source "drivers/phy/socionext/Kconfig" source "drivers/phy/sophgo/Kconfig" +source "drivers/phy/spacemit/Kconfig" source "drivers/phy/st/Kconfig" source "drivers/phy/starfive/Kconfig" source "drivers/phy/sunplus/Kconfig" diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index 30b150d68de7..a648c2e02a83 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_COMMON_PROPS_TEST) += phy-common-props-test.o obj-$(CONFIG_GENERIC_PHY) += phy-core.o obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY) += phy-core-mipi-dphy.o obj-$(CONFIG_PHY_CAN_TRANSCEIVER) += phy-can-transceiver.o +obj-$(CONFIG_PHY_GOOGLE_USB) += phy-google-usb.o obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o obj-$(CONFIG_PHY_XGENE) += phy-xgene.o obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o @@ -15,8 +16,10 @@ obj-$(CONFIG_PHY_SNPS_EUSB2) += phy-snps-eusb2.o obj-$(CONFIG_USB_LGM_PHY) += phy-lgm-usb.o obj-$(CONFIG_PHY_AIROHA_PCIE) += phy-airoha-pcie.o obj-$(CONFIG_PHY_NXP_PTN3222) += phy-nxp-ptn3222.o -obj-y += allwinner/ \ +obj-$(CONFIG_PHY_SPACEMIT_K1_PCIE) += phy-spacemit-k1-pcie.o +obj-$(CONFIG_GENERIC_PHY) += allwinner/ \ amlogic/ \ + apple/ \ broadcom/ \ cadence/ \ freescale/ \ @@ -38,6 +41,7 @@ obj-y += allwinner/ \ samsung/ \ socionext/ \ sophgo/ \ + spacemit/ \ st/ \ starfive/ \ sunplus/ \ diff --git a/drivers/phy/allwinner/phy-sun4i-usb.c b/drivers/phy/allwinner/phy-sun4i-usb.c index 59d38d88efb0..e2fbf8ccf99e 100644 --- a/drivers/phy/allwinner/phy-sun4i-usb.c +++ b/drivers/phy/allwinner/phy-sun4i-usb.c @@ -359,7 +359,7 @@ static int sun4i_usb_phy_init(struct phy *_phy) /* Force ISCR and cable state updates */ data->id_det = -1; data->vbus_det = -1; - queue_delayed_work(system_wq, &data->detect, 0); + queue_delayed_work(system_percpu_wq, &data->detect, 0); } return 0; @@ -482,7 +482,7 @@ static int sun4i_usb_phy_power_on(struct phy *_phy) /* We must report Vbus high within OTG_TIME_A_WAIT_VRISE msec. */ if (phy->index == 0 && sun4i_usb_phy0_poll(data)) - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); return 0; } @@ -503,7 +503,7 @@ static int sun4i_usb_phy_power_off(struct phy *_phy) * Vbus gpio to not trigger an edge irq on Vbus off, so force a rescan. */ if (phy->index == 0 && !sun4i_usb_phy0_poll(data)) - mod_delayed_work(system_wq, &data->detect, POLL_TIME); + mod_delayed_work(system_percpu_wq, &data->detect, POLL_TIME); return 0; } @@ -542,7 +542,7 @@ static int sun4i_usb_phy_set_mode(struct phy *_phy, data->id_det = -1; /* Force reprocessing of id */ data->force_session_end = true; - queue_delayed_work(system_wq, &data->detect, 0); + queue_delayed_work(system_percpu_wq, &data->detect, 0); return 0; } @@ -654,7 +654,7 @@ static void sun4i_usb_phy0_id_vbus_det_scan(struct work_struct *work) extcon_set_state_sync(data->extcon, EXTCON_USB, vbus_det); if (sun4i_usb_phy0_poll(data)) - queue_delayed_work(system_wq, &data->detect, POLL_TIME); + queue_delayed_work(system_percpu_wq, &data->detect, POLL_TIME); } static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id) @@ -662,7 +662,7 @@ static irqreturn_t sun4i_usb_phy0_id_vbus_det_irq(int irq, void *dev_id) struct sun4i_usb_phy_data *data = dev_id; /* vbus or id changed, let the pins settle and then scan them */ - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); return IRQ_HANDLED; } @@ -676,7 +676,7 @@ static int sun4i_usb_phy0_vbus_notify(struct notifier_block *nb, /* Properties on the vbus_power_supply changed, scan vbus_det */ if (val == PSY_EVENT_PROP_CHANGED && psy == data->vbus_power_supply) - mod_delayed_work(system_wq, &data->detect, DEBOUNCE_TIME); + mod_delayed_work(system_percpu_wq, &data->detect, DEBOUNCE_TIME); return NOTIFY_OK; } diff --git a/drivers/phy/apple/Kconfig b/drivers/phy/apple/Kconfig new file mode 100644 index 000000000000..d82d6f291a75 --- /dev/null +++ b/drivers/phy/apple/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +config PHY_APPLE_ATC + tristate "Apple Type-C PHY" + depends on (ARM64 && ARCH_APPLE) || (COMPILE_TEST && !GENERIC_ATOMIC64) + depends on TYPEC + select GENERIC_PHY + select APPLE_TUNABLE + help + Enable this to add support for the Apple Type-C PHY found in + Apple Silicon M-series SoCs. This PHY supports USB2, + USB3, USB4, Thunderbolt, and DisplayPort. + + If M is selected the module will be called 'phy-apple-atc'. diff --git a/drivers/phy/apple/Makefile b/drivers/phy/apple/Makefile new file mode 100644 index 000000000000..e02836a63df3 --- /dev/null +++ b/drivers/phy/apple/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause + +obj-$(CONFIG_PHY_APPLE_ATC) += phy-apple-atc.o +phy-apple-atc-y := atc.o diff --git a/drivers/phy/apple/atc.c b/drivers/phy/apple/atc.c new file mode 100644 index 000000000000..dc867f368b68 --- /dev/null +++ b/drivers/phy/apple/atc.c @@ -0,0 +1,2295 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-2-Clause +/* + * Apple Type-C PHY driver + * + * The Apple Type-C PHY (ATCPHY) is a combined PHY for USB 2.0, USB 3.x, + * USB4/Thunderbolt, and DisplayPort connectivity via Type-C ports found in + * Apple Silicon SoCs. + * + * The PHY handles muxing between these different protocols and also provides the + * reset controller for the attached DWC3 USB controller. + * + * No documentation for this PHY is available and its operation has been + * reverse engineered by observing the XNU's MMIO access using a thin hypervisor + * and correlating register access to XNU's very verbose debug output. Most + * register names comes from this debug output as well. + * + * In order to correctly setup the high speed lanes for the various modes + * calibration values copied from Apple's firmware by our bootloader m1n1 are + * required. Without these only USB2 operation is possible. + * + * Copyright (C) The Asahi Linux Contributors + * Author: Sven Peter + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define AUSPLL_FSM_CTRL 0x1014 + +#define AUSPLL_APB_CMD_OVERRIDE 0x2000 +#define AUSPLL_APB_CMD_OVERRIDE_REQ BIT(0) +#define AUSPLL_APB_CMD_OVERRIDE_ACK BIT(1) +#define AUSPLL_APB_CMD_OVERRIDE_UNK28 BIT(28) +#define AUSPLL_APB_CMD_OVERRIDE_CMD GENMASK(27, 3) + +#define AUSPLL_FREQ_DESC_A 0x2080 +#define AUSPLL_FD_FREQ_COUNT_TARGET GENMASK(9, 0) +#define AUSPLL_FD_FBDIVN_HALF BIT(10) +#define AUSPLL_FD_REV_DIVN GENMASK(13, 11) +#define AUSPLL_FD_KI_MAN GENMASK(17, 14) +#define AUSPLL_FD_KI_EXP GENMASK(21, 18) +#define AUSPLL_FD_KP_MAN GENMASK(25, 22) +#define AUSPLL_FD_KP_EXP GENMASK(29, 26) +#define AUSPLL_FD_KPKI_SCALE_HBW GENMASK(31, 30) + +#define AUSPLL_FREQ_DESC_B 0x2084 +#define AUSPLL_FD_FBDIVN_FRAC_DEN GENMASK(13, 0) +#define AUSPLL_FD_FBDIVN_FRAC_NUM GENMASK(27, 14) + +#define AUSPLL_FREQ_DESC_C 0x2088 +#define AUSPLL_FD_SDM_SSC_STEP GENMASK(7, 0) +#define AUSPLL_FD_SDM_SSC_EN BIT(8) +#define AUSPLL_FD_PCLK_DIV_SEL GENMASK(13, 9) +#define AUSPLL_FD_LFSDM_DIV GENMASK(15, 14) +#define AUSPLL_FD_LFCLK_CTRL GENMASK(19, 16) +#define AUSPLL_FD_VCLK_OP_DIVN GENMASK(21, 20) +#define AUSPLL_FD_VCLK_PRE_DIVN BIT(22) + +#define AUSPLL_DCO_EFUSE_SPARE 0x222c +#define AUSPLL_RODCO_ENCAP_EFUSE GENMASK(10, 9) +#define AUSPLL_RODCO_BIAS_ADJUST_EFUSE GENMASK(14, 12) + +#define AUSPLL_FRACN_CAN 0x22a4 +#define AUSPLL_DLL_START_CAPCODE GENMASK(18, 17) + +#define AUSPLL_CLKOUT_MASTER 0x2200 +#define AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN BIT(2) +#define AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN BIT(4) +#define AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN BIT(6) + +#define AUSPLL_CLKOUT_DIV 0x2208 +#define AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI GENMASK(20, 16) + +#define AUSPLL_BGR 0x2214 +#define AUSPLL_BGR_CTRL_AVAIL BIT(0) + +#define AUSPLL_CLKOUT_DTC_VREG 0x2220 +#define AUSPLL_DTC_VREG_ADJUST GENMASK(16, 14) +#define AUSPLL_DTC_VREG_BYPASS BIT(7) + +#define AUSPLL_FREQ_CFG 0x2224 +#define AUSPLL_FREQ_REFCLK GENMASK(1, 0) + +#define AUS_COMMON_SHIM_BLK_VREG 0x0a04 +#define AUS_VREG_TRIM GENMASK(6, 2) + +#define AUS_UNK_A20 0x0a20 +#define AUS_UNK_A20_TX_CAL_CODE GENMASK(23, 20) + +#define ACIOPHY_CMN_SHM_STS_REG0 0x0a74 +#define ACIOPHY_CMN_SHM_STS_REG0_CMD_READY BIT(0) + +#define CIO3PLL_CLK_CTRL 0x2a00 +#define CIO3PLL_CLK_PCLK_EN BIT(1) +#define CIO3PLL_CLK_REFCLK_EN BIT(5) + +#define CIO3PLL_DCO_NCTRL 0x2a38 +#define CIO3PLL_DCO_COARSEBIN_EFUSE0 GENMASK(6, 0) +#define CIO3PLL_DCO_COARSEBIN_EFUSE1 GENMASK(23, 17) + +#define CIO3PLL_FRACN_CAN 0x2aa4 +#define CIO3PLL_DLL_CAL_START_CAPCODE GENMASK(18, 17) + +#define CIO3PLL_DTC_VREG 0x2a20 +#define CIO3PLL_DTC_VREG_ADJUST GENMASK(16, 14) + +#define ACIOPHY_CFG0 0x08 +#define ACIOPHY_CFG0_COMMON_BIG_OV BIT(1) +#define ACIOPHY_CFG0_COMMON_SMALL_OV BIT(3) +#define ACIOPHY_CFG0_COMMON_CLAMP_OV BIT(5) +#define ACIOPHY_CFG0_RX_SMALL_OV GENMASK(9, 8) +#define ACIOPHY_CFG0_RX_BIG_OV GENMASK(13, 12) +#define ACIOPHY_CFG0_RX_CLAMP_OV GENMASK(17, 16) + +#define ACIOPHY_CROSSBAR 0x4c +#define ACIOPHY_CROSSBAR_PROTOCOL GENMASK(4, 0) +#define ACIOPHY_CROSSBAR_PROTOCOL_USB4 0x0 +#define ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED 0x1 +#define ACIOPHY_CROSSBAR_PROTOCOL_USB3 0xa +#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED 0xb +#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP 0x10 +#define ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED 0x11 +#define ACIOPHY_CROSSBAR_PROTOCOL_DP 0x14 +#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA GENMASK(16, 5) +#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE 0x0000 +#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100 0x100 +#define ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008 0x008 +#define ACIOPHY_CROSSBAR_DP_BOTH_PMA BIT(17) + +#define ACIOPHY_LANE_MODE 0x48 +#define ACIOPHY_LANE_MODE_RX0 GENMASK(2, 0) +#define ACIOPHY_LANE_MODE_TX0 GENMASK(5, 3) +#define ACIOPHY_LANE_MODE_RX1 GENMASK(8, 6) +#define ACIOPHY_LANE_MODE_TX1 GENMASK(11, 9) + +enum atcphy_lane_mode { + ACIOPHY_LANE_MODE_USB4 = 0, + ACIOPHY_LANE_MODE_USB3 = 1, + ACIOPHY_LANE_MODE_DP = 2, + ACIOPHY_LANE_MODE_OFF = 3, +}; + +#define ACIOPHY_TOP_BIST_CIOPHY_CFG1 0x84 +#define ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN BIT(27) +#define ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN BIT(28) + +#define ACIOPHY_TOP_BIST_OV_CFG 0x8c +#define ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV BIT(13) +#define ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV BIT(25) + +#define ACIOPHY_TOP_BIST_READ_CTRL 0x90 +#define ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE BIT(2) + +#define ACIOPHY_TOP_PHY_STAT 0x9c +#define ACIOPHY_TOP_PHY_STAT_LN0_UNK0 BIT(0) +#define ACIOPHY_TOP_PHY_STAT_LN0_UNK23 BIT(23) + +#define ACIOPHY_TOP_BIST_PHY_CFG0 0xa8 +#define ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N BIT(0) + +#define ACIOPHY_TOP_BIST_PHY_CFG1 0xac +#define ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN GENMASK(13, 10) + +#define ACIOPHY_SLEEP_CTRL 0x1b0 +#define ACIOPHY_SLEEP_CTRL_TX_BIG_OV GENMASK(3, 2) +#define ACIOPHY_SLEEP_CTRL_TX_SMALL_OV GENMASK(7, 6) +#define ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV GENMASK(11, 10) + +#define ACIOPHY_PLL_PCTL_FSM_CTRL1 0x1014 +#define ACIOPHY_PLL_APB_REQ_OV_SEL GENMASK(21, 13) +#define ACIOPHY_PLL_COMMON_CTRL 0x1028 +#define ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT BIT(24) + +#define ATCPHY_POWER_CTRL 0x20000 +#define ATCPHY_POWER_STAT 0x20004 +#define ATCPHY_POWER_SLEEP_SMALL BIT(0) +#define ATCPHY_POWER_SLEEP_BIG BIT(1) +#define ATCPHY_POWER_CLAMP_EN BIT(2) +#define ATCPHY_POWER_APB_RESET_N BIT(3) +#define ATCPHY_POWER_PHY_RESET_N BIT(4) + +#define ATCPHY_MISC 0x20008 +#define ATCPHY_MISC_RESET_N BIT(0) +#define ATCPHY_MISC_LANE_SWAP BIT(2) + +#define ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0 0x7000 +#define DP_PMA_BYTECLK_RESET BIT(0) +#define DP_MAC_DIV20_CLK_SEL BIT(1) +#define DPTXPHY_PMA_LANE_RESET_N BIT(2) +#define DPTXPHY_PMA_LANE_RESET_N_OV BIT(3) +#define DPTX_PCLK1_SELECT GENMASK(6, 4) +#define DPTX_PCLK2_SELECT GENMASK(9, 7) +#define DPRX_PCLK_SELECT GENMASK(12, 10) +#define DPTX_PCLK1_ENABLE BIT(13) +#define DPTX_PCLK2_ENABLE BIT(14) +#define DPRX_PCLK_ENABLE BIT(15) + +#define ACIOPHY_DP_PCLK_STAT 0x7044 +#define ACIOPHY_AUSPLL_LOCK BIT(3) + +#define LN0_AUSPMA_RX_TOP 0x9000 +#define LN0_AUSPMA_RX_EQ 0xA000 +#define LN0_AUSPMA_RX_SHM 0xB000 +#define LN0_AUSPMA_TX_TOP 0xC000 +#define LN0_AUSPMA_TX_SHM 0xD000 + +#define LN1_AUSPMA_RX_TOP 0x10000 +#define LN1_AUSPMA_RX_EQ 0x11000 +#define LN1_AUSPMA_RX_SHM 0x12000 +#define LN1_AUSPMA_TX_TOP 0x13000 +#define LN1_AUSPMA_TX_SHM 0x14000 + +#define LN_AUSPMA_RX_TOP_PMAFSM 0x0010 +#define LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV BIT(0) +#define LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ BIT(9) + +#define LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE 0x00F0 +#define LN_RX_TXMODE BIT(0) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0 0x00 +#define LN_TX_CLK_EN BIT(20) +#define LN_TX_CLK_EN_OV BIT(21) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1 0x04 +#define LN_RX_DIV20_RESET_N_OV BIT(29) +#define LN_RX_DIV20_RESET_N BIT(30) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL2 0x08 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL3 0x0C +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL4 0x10 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL5 0x14 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL6 0x18 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL7 0x1C +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL8 0x20 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL9 0x24 +#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10 0x28 +#define LN_DTVREG_ADJUST GENMASK(31, 27) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11 0x2C +#define LN_DTVREG_BIG_EN BIT(23) +#define LN_DTVREG_BIG_EN_OV BIT(24) +#define LN_DTVREG_SML_EN BIT(25) +#define LN_DTVREG_SML_EN_OV BIT(26) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12 0x30 +#define LN_TX_BYTECLK_RESET_SYNC_CLR BIT(22) +#define LN_TX_BYTECLK_RESET_SYNC_CLR_OV BIT(23) +#define LN_TX_BYTECLK_RESET_SYNC_EN BIT(24) +#define LN_TX_BYTECLK_RESET_SYNC_EN_OV BIT(25) +#define LN_TX_HRCLK_SEL BIT(28) +#define LN_TX_HRCLK_SEL_OV BIT(29) +#define LN_TX_PBIAS_EN BIT(30) +#define LN_TX_PBIAS_EN_OV BIT(31) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13 0x34 +#define LN_TX_PRE_EN BIT(0) +#define LN_TX_PRE_EN_OV BIT(1) +#define LN_TX_PST1_EN BIT(2) +#define LN_TX_PST1_EN_OV BIT(3) +#define LN_DTVREG_ADJUST_OV BIT(15) + +#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14A 0x38 +#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL14B 0x3C +#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15A 0x40 +#define LN_AUSPMA_RX_SHM_TJ_UNK_CTRL15B 0x44 +#define LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16 0x48 +#define LN_RXTERM_EN BIT(21) +#define LN_RXTERM_EN_OV BIT(22) +#define LN_RXTERM_PULLUP_LEAK_EN BIT(23) +#define LN_RXTERM_PULLUP_LEAK_EN_OV BIT(24) +#define LN_TX_CAL_CODE GENMASK(29, 25) +#define LN_TX_CAL_CODE_OV BIT(30) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17 0x4C +#define LN_TX_MARGIN GENMASK(19, 15) +#define LN_TX_MARGIN_OV BIT(20) +#define LN_TX_MARGIN_LSB BIT(21) +#define LN_TX_MARGIN_LSB_OV BIT(22) +#define LN_TX_MARGIN_P1 GENMASK(26, 23) +#define LN_TX_MARGIN_P1_OV BIT(27) +#define LN_TX_MARGIN_P1_LSB GENMASK(29, 28) +#define LN_TX_MARGIN_P1_LSB_OV BIT(30) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18 0x50 +#define LN_TX_P1_CODE GENMASK(3, 0) +#define LN_TX_P1_CODE_OV BIT(4) +#define LN_TX_P1_LSB_CODE GENMASK(6, 5) +#define LN_TX_P1_LSB_CODE_OV BIT(7) +#define LN_TX_MARGIN_PRE GENMASK(10, 8) +#define LN_TX_MARGIN_PRE_OV BIT(11) +#define LN_TX_MARGIN_PRE_LSB GENMASK(13, 12) +#define LN_TX_MARGIN_PRE_LSB_OV BIT(14) +#define LN_TX_PRE_LSB_CODE GENMASK(16, 15) +#define LN_TX_PRE_LSB_CODE_OV BIT(17) +#define LN_TX_PRE_CODE GENMASK(21, 18) +#define LN_TX_PRE_CODE_OV BIT(22) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19 0x54 +#define LN_TX_TEST_EN BIT(21) +#define LN_TX_TEST_EN_OV BIT(22) +#define LN_TX_EN BIT(23) +#define LN_TX_EN_OV BIT(24) +#define LN_TX_CLK_DLY_CTRL_TAPGEN GENMASK(27, 25) +#define LN_TX_CLK_DIV2_EN BIT(28) +#define LN_TX_CLK_DIV2_EN_OV BIT(29) +#define LN_TX_CLK_DIV2_RST BIT(30) +#define LN_TX_CLK_DIV2_RST_OV BIT(31) + +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL20 0x58 +#define LN_AUSPMA_RX_SHM_TJ_RXA_UNK_CTRL21 0x5C +#define LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22 0x60 +#define LN_VREF_ADJUST_GRAY GENMASK(11, 7) +#define LN_VREF_ADJUST_GRAY_OV BIT(12) +#define LN_VREF_BIAS_SEL GENMASK(14, 13) +#define LN_VREF_BIAS_SEL_OV BIT(15) +#define LN_VREF_BOOST_EN BIT(16) +#define LN_VREF_BOOST_EN_OV BIT(17) +#define LN_VREF_EN BIT(18) +#define LN_VREF_EN_OV BIT(19) +#define LN_VREF_LPBKIN_DATA GENMASK(29, 28) +#define LN_VREF_TEST_RXLPBKDT_EN BIT(30) +#define LN_VREF_TEST_RXLPBKDT_EN_OV BIT(31) + +#define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0 0x00 +#define LN_BYTECLK_RESET_SYNC_EN_OV BIT(2) +#define LN_BYTECLK_RESET_SYNC_EN BIT(3) +#define LN_BYTECLK_RESET_SYNC_CLR_OV BIT(4) +#define LN_BYTECLK_RESET_SYNC_CLR BIT(5) +#define LN_BYTECLK_RESET_SYNC_SEL_OV BIT(6) + +#define LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1 0x04 +#define LN_TXA_DIV2_EN_OV BIT(8) +#define LN_TXA_DIV2_EN BIT(9) +#define LN_TXA_DIV2_RESET_OV BIT(10) +#define LN_TXA_DIV2_RESET BIT(11) +#define LN_TXA_CLK_EN_OV BIT(22) +#define LN_TXA_CLK_EN BIT(23) + +#define LN_AUSPMA_TX_SHM_TXA_IMP_REG0 0x08 +#define LN_TXA_CAL_CTRL_OV BIT(0) +#define LN_TXA_CAL_CTRL GENMASK(18, 1) +#define LN_TXA_CAL_CTRL_BASE_OV BIT(19) +#define LN_TXA_CAL_CTRL_BASE GENMASK(23, 20) +#define LN_TXA_HIZ_OV BIT(29) +#define LN_TXA_HIZ BIT(30) + +#define LN_AUSPMA_TX_SHM_TXA_IMP_REG1 0x0C +#define LN_AUSPMA_TX_SHM_TXA_IMP_REG2 0x10 +#define LN_TXA_MARGIN_OV BIT(0) +#define LN_TXA_MARGIN GENMASK(18, 1) +#define LN_TXA_MARGIN_2R_OV BIT(19) +#define LN_TXA_MARGIN_2R BIT(20) + +#define LN_AUSPMA_TX_SHM_TXA_IMP_REG3 0x14 +#define LN_TXA_MARGIN_POST_OV BIT(0) +#define LN_TXA_MARGIN_POST GENMASK(10, 1) +#define LN_TXA_MARGIN_POST_2R_OV BIT(11) +#define LN_TXA_MARGIN_POST_2R BIT(12) +#define LN_TXA_MARGIN_POST_4R_OV BIT(13) +#define LN_TXA_MARGIN_POST_4R BIT(14) +#define LN_TXA_MARGIN_PRE_OV BIT(15) +#define LN_TXA_MARGIN_PRE GENMASK(21, 16) +#define LN_TXA_MARGIN_PRE_2R_OV BIT(22) +#define LN_TXA_MARGIN_PRE_2R BIT(23) +#define LN_TXA_MARGIN_PRE_4R_OV BIT(24) +#define LN_TXA_MARGIN_PRE_4R BIT(25) + +#define LN_AUSPMA_TX_SHM_TXA_UNK_REG0 0x18 +#define LN_AUSPMA_TX_SHM_TXA_UNK_REG1 0x1C +#define LN_AUSPMA_TX_SHM_TXA_UNK_REG2 0x20 + +#define LN_AUSPMA_TX_SHM_TXA_LDOCLK 0x24 +#define LN_LDOCLK_BYPASS_SML_OV BIT(8) +#define LN_LDOCLK_BYPASS_SML BIT(9) +#define LN_LDOCLK_BYPASS_BIG_OV BIT(10) +#define LN_LDOCLK_BYPASS_BIG BIT(11) +#define LN_LDOCLK_EN_SML_OV BIT(12) +#define LN_LDOCLK_EN_SML BIT(13) +#define LN_LDOCLK_EN_BIG_OV BIT(14) +#define LN_LDOCLK_EN_BIG BIT(15) + +/* LPDPTX registers */ +#define LPDPTX_AUX_CFG_BLK_AUX_CTRL 0x0000 +#define LPDPTX_BLK_AUX_CTRL_PWRDN BIT(4) +#define LPDPTX_BLK_AUX_RXOFFSET GENMASK(25, 22) + +#define LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL 0x0008 + +#define LPDPTX_AUX_CFG_BLK_AUX_MARGIN 0x000c +#define LPDPTX_MARGIN_RCAL_RXOFFSET_EN BIT(5) +#define LPDPTX_AUX_MARGIN_RCAL_TXSWING GENMASK(10, 6) + +#define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0 0x0204 +#define LPDPTX_CFG_PMA_AUX_SEL_LF_DATA BIT(15) + +#define LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1 0x0208 +#define LPDPTX_CFG_PMA_PHYS_ADJ GENMASK(22, 20) +#define LPDPTX_CFG_PMA_PHYS_ADJ_OV BIT(19) + +#define LPDPTX_AUX_CONTROL 0x4000 +#define LPDPTX_AUX_PWN_DOWN 0x10 +#define LPDPTX_AUX_CLAMP_EN 0x04 +#define LPDPTX_SLEEP_B_BIG_IN 0x02 +#define LPDPTX_SLEEP_B_SML_IN 0x01 +#define LPDPTX_TXTERM_CODEMSB 0x400 +#define LPDPTX_TXTERM_CODE GENMASK(9, 5) + +/* pipehandler registers */ +#define PIPEHANDLER_OVERRIDE 0x00 +#define PIPEHANDLER_OVERRIDE_RXVALID BIT(0) +#define PIPEHANDLER_OVERRIDE_RXDETECT BIT(2) + +#define PIPEHANDLER_OVERRIDE_VALUES 0x04 +#define PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 BIT(1) +#define PIPEHANDLER_OVERRIDE_VAL_RXDETECT1 BIT(2) +#define PIPEHANDLER_OVERRIDE_VAL_PHY_STATUS BIT(4) + +#define PIPEHANDLER_MUX_CTRL 0x0c +#define PIPEHANDLER_MUX_CTRL_CLK GENMASK(5, 3) +#define PIPEHANDLER_MUX_CTRL_DATA GENMASK(2, 0) +#define PIPEHANDLER_MUX_CTRL_CLK_OFF 0 +#define PIPEHANDLER_MUX_CTRL_CLK_USB3 1 +#define PIPEHANDLER_MUX_CTRL_CLK_USB4 2 +#define PIPEHANDLER_MUX_CTRL_CLK_DUMMY 4 + +#define PIPEHANDLER_MUX_CTRL_DATA_USB3 0 +#define PIPEHANDLER_MUX_CTRL_DATA_USB4 1 +#define PIPEHANDLER_MUX_CTRL_DATA_DUMMY 2 + +#define PIPEHANDLER_LOCK_REQ 0x10 +#define PIPEHANDLER_LOCK_ACK 0x14 +#define PIPEHANDLER_LOCK_EN BIT(0) + +#define PIPEHANDLER_AON_GEN 0x1C +#define PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN BIT(4) +#define PIPEHANDLER_AON_GEN_DWC3_RESET_N BIT(0) + +#define PIPEHANDLER_NONSELECTED_OVERRIDE 0x20 +#define PIPEHANDLER_NATIVE_RESET BIT(12) +#define PIPEHANDLER_DUMMY_PHY_EN BIT(15) +#define PIPEHANDLER_NATIVE_POWER_DOWN GENMASK(3, 0) + +#define PIPEHANDLER_LOCK_ACK_TIMEOUT_US 1000 + +/* USB2 PHY regs */ +#define USB2PHY_USBCTL 0x00 +#define USB2PHY_USBCTL_RUN 2 +#define USB2PHY_USBCTL_ISOLATION 4 + +#define USB2PHY_CTL 0x04 +#define USB2PHY_CTL_RESET BIT(0) +#define USB2PHY_CTL_PORT_RESET BIT(1) +#define USB2PHY_CTL_APB_RESET_N BIT(2) +#define USB2PHY_CTL_SIDDQ BIT(3) + +#define USB2PHY_SIG 0x08 +#define USB2PHY_SIG_VBUSDET_FORCE_VAL BIT(0) +#define USB2PHY_SIG_VBUSDET_FORCE_EN BIT(1) +#define USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL BIT(2) +#define USB2PHY_SIG_VBUSVLDEXT_FORCE_EN BIT(3) +#define USB2PHY_SIG_HOST (7 << 12) + +#define USB2PHY_MISCTUNE 0x1c +#define USB2PHY_MISCTUNE_APBCLK_GATE_OFF BIT(29) +#define USB2PHY_MISCTUNE_REFCLK_GATE_OFF BIT(30) + +enum atcphy_dp_link_rate { + ATCPHY_DP_LINK_RATE_RBR, + ATCPHY_DP_LINK_RATE_HBR, + ATCPHY_DP_LINK_RATE_HBR2, + ATCPHY_DP_LINK_RATE_HBR3, +}; + +/** + * enum atcphy_pipehandler_state - States of the PIPE mux interface ("pipehandler") + * @ATCPHY_PIPEHANDLER_STATE_DUMMY: "Dummy PHY" (disables USB3, USB2 only) + * @ATCPHY_PIPEHANDLER_STATE_USB3: USB3 directly connected to the Type-C port + * @ATCPHY_PIPEHANDLER_STATE_USB4: USB3 tunneled via USB4/Thunderbolt + * + * DWC3's USB3 PIPE interface is connected to a multiplexer inside this PHY + * which can switch between a dummy state (which effectively disables any USB3 + * support and falls back to USB2 only operation via the separate ULPI interface), + * a USB3 state (for regular USB3 or USB3+DisplayPort operation) and a USB4 state + * (for USB3 tunneled via USB4/Thunderbolt). + */ +enum atcphy_pipehandler_state { + ATCPHY_PIPEHANDLER_STATE_DUMMY, + ATCPHY_PIPEHANDLER_STATE_USB3, + ATCPHY_PIPEHANDLER_STATE_USB4, +}; + +/** + * enum atcphy_mode - Operating modes of the PHY + * @APPLE_ATCPHY_MODE_OFF: all PHYs powered off + * @APPLE_ATCPHY_MODE_USB2: Nothing on the four SS lanes (i.e. USB2 only on D-/+) + * @APPLE_ATCPHY_MODE_USB3: USB3 on two lanes, nothing on the other two + * @APPLE_ATCPHY_MODE_USB3_DP: USB3 on two lanes and DisplayPort on the other two + * @APPLE_ATCPHY_MODE_TBT: Thunderbolt on all lanes + * @APPLE_ATCPHY_MODE_USB4: USB4 on all lanes + * @APPLE_ATCPHY_MODE_DP: DisplayPort on all lanes + */ +enum atcphy_mode { + APPLE_ATCPHY_MODE_OFF, + APPLE_ATCPHY_MODE_USB2, + APPLE_ATCPHY_MODE_USB3, + APPLE_ATCPHY_MODE_USB3_DP, + APPLE_ATCPHY_MODE_TBT, + APPLE_ATCPHY_MODE_USB4, + APPLE_ATCPHY_MODE_DP, +}; + +enum atcphy_lane { + APPLE_ATCPHY_LANE_0, + APPLE_ATCPHY_LANE_1, +}; + +/* Link rate configuration, field names are taken from XNU debug output or register names */ +struct atcphy_dp_link_rate_configuration { + u16 freqinit_count_target; + u16 fbdivn_frac_den; + u16 fbdivn_frac_num; + u16 pclk_div_sel; + u8 lfclk_ctrl; + u8 vclk_op_divn; + bool plla_clkout_vreg_bypass; + bool txa_ldoclk_bypass; + bool txa_div2_en; +}; + +/* Crossbar and lane configuration */ +struct atcphy_mode_configuration { + u32 crossbar; + u32 crossbar_dp_single_pma; + bool crossbar_dp_both_pma; + enum atcphy_lane_mode lane_mode[2]; + bool dp_lane[2]; + bool set_swap; +}; + +/** + * struct apple_atcphy - Apple Type-C PHY device struct + * @np: Device node pointer + * @dev: Device pointer + * @tunables: Firmware-provided tunable parameters + * @tunables.axi2af: AXI to AF interface tunables + * @tunables.common: Common tunables for all lanes + * @tunables.lane_usb3: USB3 lane-specific tunables + * @tunables.lane_dp: DisplayPort lane-specific tunables + * @tunables.lane_usb4: USB4 lane-specific tunables + * @mode: Current PHY operating mode + * @swap_lanes: True if lanes must be swapped due to cable orientation + * @dp_link_rate: DisplayPort link rate + * @pipehandler_up: True if the PIPE mux ("pipehandler") is set to USB3 or USB4 mode + * @regs: Memory-mapped registers + * @regs.core: Core registers + * @regs.axi2af: AXI to Apple Fabric interface registers + * @regs.usb2phy: USB2 PHY registers + * @regs.pipehandler: USB3 PIPE interface ("pipehandler") registers + * @regs.lpdptx: DisplayPort registers + * @res: Resources for memory-mapped registers, used to verify that tunables aren't out of bounds + * @res.core: Core register resource + * @res.axi2af: AXI to Apple Fabric interface resource + * @phys: PHY instances + * @phys.usb2: USB2 PHY instance + * @phys.usb3: USB3 PHY instance + * @phys.dp: DisplayPort PHY instance + * @phy_provider: PHY provider instance + * @rcdev: Reset controller device + * @sw: Type-C switch instance + * @mux: Type-C mux instance + * @lock: Mutex for synchronizing register access across PHY, Type-C switch/mux and reset controller + */ +struct apple_atcphy { + struct device_node *np; + struct device *dev; + + struct { + struct apple_tunable *axi2af; + struct apple_tunable *common[2]; + struct apple_tunable *lane_usb3[2]; + struct apple_tunable *lane_dp[2]; + struct apple_tunable *lane_usb4[2]; + } tunables; + + enum atcphy_mode mode; + bool swap_lanes; + int dp_link_rate; + bool pipehandler_up; + + struct { + void __iomem *core; + void __iomem *axi2af; + void __iomem *usb2phy; + void __iomem *pipehandler; + void __iomem *lpdptx; + } regs; + + struct { + struct resource *core; + struct resource *axi2af; + } res; + + struct { + struct phy *usb2; + struct phy *usb3; + struct phy *dp; + } phys; + struct phy_provider *phy_provider; + + struct reset_controller_dev rcdev; + + struct typec_switch *sw; + struct typec_mux *mux; + + struct mutex lock; +}; + +static const struct { + const struct atcphy_mode_configuration normal; + const struct atcphy_mode_configuration swapped; + bool enable_dp_aux; + enum atcphy_pipehandler_state pipehandler_state; +} atcphy_modes[] = { + [APPLE_ATCPHY_MODE_OFF] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, + .dp_lane = {false, false}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, + .dp_lane = {false, false}, + .set_swap = false, /* doesn't matter since the SS lanes are off */ + }, + .enable_dp_aux = false, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, + }, + [APPLE_ATCPHY_MODE_USB2] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, + .dp_lane = {false, false}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_OFF, ACIOPHY_LANE_MODE_OFF}, + .dp_lane = {false, false}, + .set_swap = false, /* doesn't matter since the SS lanes are off */ + }, + .enable_dp_aux = false, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, + }, + [APPLE_ATCPHY_MODE_USB3] = { + /* + * Setting up the lanes as DP/USB3 is intentional here, USB3/USB3 does not work + * and isn't required since this PHY does not support 20GBps mode anyway. + * The only difference to APPLE_ATCPHY_MODE_USB3_DP is that DP Aux is not enabled. + */ + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_DP}, + .dp_lane = {false, true}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_USB3}, + .dp_lane = {true, false}, + .set_swap = true, + }, + .enable_dp_aux = false, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3, + }, + [APPLE_ATCPHY_MODE_USB3_DP] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB3, ACIOPHY_LANE_MODE_DP}, + .dp_lane = {false, true}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB3_DP_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_USB3}, + .dp_lane = {true, false}, + .set_swap = true, + }, + .enable_dp_aux = true, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB3, + }, + [APPLE_ATCPHY_MODE_TBT] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, + .dp_lane = {false, false}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, + .dp_lane = {false, false}, + .set_swap = false, /* intentionally false */ + }, + .enable_dp_aux = false, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, + }, + [APPLE_ATCPHY_MODE_USB4] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, + .dp_lane = {false, false}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_USB4_SWAPPED, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_NONE, + .crossbar_dp_both_pma = false, + .lane_mode = {ACIOPHY_LANE_MODE_USB4, ACIOPHY_LANE_MODE_USB4}, + .dp_lane = {false, false}, + .set_swap = false, /* intentionally false */ + }, + .enable_dp_aux = false, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_USB4, + }, + [APPLE_ATCPHY_MODE_DP] = { + .normal = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK100, + .crossbar_dp_both_pma = true, + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP}, + .dp_lane = {true, true}, + .set_swap = false, + }, + .swapped = { + .crossbar = ACIOPHY_CROSSBAR_PROTOCOL_DP, + .crossbar_dp_single_pma = ACIOPHY_CROSSBAR_DP_SINGLE_PMA_UNK008, + .crossbar_dp_both_pma = false, /* intentionally false */ + .lane_mode = {ACIOPHY_LANE_MODE_DP, ACIOPHY_LANE_MODE_DP}, + .dp_lane = {true, true}, + .set_swap = false, /* intentionally false */ + }, + .enable_dp_aux = true, + .pipehandler_state = ATCPHY_PIPEHANDLER_STATE_DUMMY, + }, +}; + +static const struct atcphy_dp_link_rate_configuration dp_lr_config[] = { + [ATCPHY_DP_LINK_RATE_RBR] = { + .freqinit_count_target = 0x21c, + .fbdivn_frac_den = 0x0, + .fbdivn_frac_num = 0x0, + .pclk_div_sel = 0x13, + .lfclk_ctrl = 0x5, + .vclk_op_divn = 0x2, + .plla_clkout_vreg_bypass = true, + .txa_ldoclk_bypass = true, + .txa_div2_en = true, + }, + [ATCPHY_DP_LINK_RATE_HBR] = { + .freqinit_count_target = 0x1c2, + .fbdivn_frac_den = 0x3ffe, + .fbdivn_frac_num = 0x1fff, + .pclk_div_sel = 0x9, + .lfclk_ctrl = 0x5, + .vclk_op_divn = 0x2, + .plla_clkout_vreg_bypass = true, + .txa_ldoclk_bypass = true, + .txa_div2_en = false, + }, + [ATCPHY_DP_LINK_RATE_HBR2] = { + .freqinit_count_target = 0x1c2, + .fbdivn_frac_den = 0x3ffe, + .fbdivn_frac_num = 0x1fff, + .pclk_div_sel = 0x4, + .lfclk_ctrl = 0x5, + .vclk_op_divn = 0x0, + .plla_clkout_vreg_bypass = true, + .txa_ldoclk_bypass = true, + .txa_div2_en = false, + }, + [ATCPHY_DP_LINK_RATE_HBR3] = { + .freqinit_count_target = 0x2a3, + .fbdivn_frac_den = 0x3ffc, + .fbdivn_frac_num = 0x2ffd, + .pclk_div_sel = 0x4, + .lfclk_ctrl = 0x6, + .vclk_op_divn = 0x0, + .plla_clkout_vreg_bypass = false, + .txa_ldoclk_bypass = false, + .txa_div2_en = false, + }, +}; + +static inline void mask32(void __iomem *reg, u32 mask, u32 set) +{ + u32 value = readl(reg); + + value &= ~mask; + value |= set; + writel(value, reg); +} + +static inline void core_mask32(struct apple_atcphy *atcphy, u32 reg, u32 mask, u32 set) +{ + mask32(atcphy->regs.core + reg, mask, set); +} + +static inline void set32(void __iomem *reg, u32 set) +{ + mask32(reg, 0, set); +} + +static inline void core_set32(struct apple_atcphy *atcphy, u32 reg, u32 set) +{ + core_mask32(atcphy, reg, 0, set); +} + +static inline void clear32(void __iomem *reg, u32 clear) +{ + mask32(reg, clear, 0); +} + +static inline void core_clear32(struct apple_atcphy *atcphy, u32 reg, u32 clear) +{ + core_mask32(atcphy, reg, clear, 0); +} + +static const struct atcphy_mode_configuration *atcphy_get_mode_config(struct apple_atcphy *atcphy, + enum atcphy_mode mode) +{ + if (atcphy->swap_lanes) + return &atcphy_modes[mode].swapped; + else + return &atcphy_modes[mode].normal; +} + +static void atcphy_apply_tunables(struct apple_atcphy *atcphy, enum atcphy_mode mode) +{ + const int lane0 = atcphy->swap_lanes ? 1 : 0; + const int lane1 = atcphy->swap_lanes ? 0 : 1; + + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.common[0]); + apple_tunable_apply(atcphy->regs.axi2af, atcphy->tunables.axi2af); + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.common[1]); + + switch (mode) { + /* + * USB 3.2 Gen 2x2 / SuperSpeed 20Gbps is not supported by this hardware and applying USB3 + * tunables to both lanes does not result in a working PHY configuration. Thus, both + * USB3-only and USB3/DP get the same tunable setup here. + */ + case APPLE_ATCPHY_MODE_USB3: + case APPLE_ATCPHY_MODE_USB3_DP: + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb3[lane0]); + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane1]); + break; + + case APPLE_ATCPHY_MODE_DP: + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane0]); + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_dp[lane1]); + break; + + /* + * Even though the various Thunderbolt versions and USB4 are different protocols they need + * the same tunables. The actual protocol-specific setup happens inside the Thunderbolt/USB4 + * native host interface. + */ + case APPLE_ATCPHY_MODE_TBT: + case APPLE_ATCPHY_MODE_USB4: + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb4[lane0]); + apple_tunable_apply(atcphy->regs.core, atcphy->tunables.lane_usb4[lane1]); + break; + + case APPLE_ATCPHY_MODE_OFF: + case APPLE_ATCPHY_MODE_USB2: + break; + } +} + +static int atcphy_pipehandler_lock(struct apple_atcphy *atcphy) +{ + int ret; + u32 reg; + + if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ) & PIPEHANDLER_LOCK_EN) { + dev_warn(atcphy->dev, "Pipehandler already locked\n"); + return 0; + } + + set32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, PIPEHANDLER_LOCK_EN); + + ret = readl_poll_timeout(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK, reg, + reg & PIPEHANDLER_LOCK_EN, 10, PIPEHANDLER_LOCK_ACK_TIMEOUT_US); + if (ret) { + clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, 1); + dev_warn(atcphy->dev, "Pipehandler lock not acked.\n"); + } + + return ret; +} + +static int atcphy_pipehandler_unlock(struct apple_atcphy *atcphy) +{ + int ret; + u32 reg; + + clear32(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_REQ, PIPEHANDLER_LOCK_EN); + ret = readl_poll_timeout(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK, reg, + !(reg & PIPEHANDLER_LOCK_EN), 10, PIPEHANDLER_LOCK_ACK_TIMEOUT_US); + if (ret) + dev_warn(atcphy->dev, "Pipehandler lock release not acked.\n"); + + return ret; +} + +static int atcphy_pipehandler_check(struct apple_atcphy *atcphy) +{ + int ret; + + lockdep_assert_held(&atcphy->lock); + + if (readl(atcphy->regs.pipehandler + PIPEHANDLER_LOCK_ACK) & PIPEHANDLER_LOCK_EN) { + dev_warn(atcphy->dev, "Pipehandler already locked\n"); + + ret = atcphy_pipehandler_unlock(atcphy); + if (ret) { + dev_err(atcphy->dev, "Failed to unlock pipehandler\n"); + return ret; + } + } + + return 0; +} + +static int atcphy_configure_pipehandler_usb3(struct apple_atcphy *atcphy, bool host) +{ + int ret; + u32 reg; + + ret = atcphy_pipehandler_check(atcphy); + if (ret) + return ret; + + /* + * Only host mode requires this unknown BIST sequence to work correctly, possibly due to + * some hardware quirk. Guest mode breaks if we try to apply this sequence. + */ + if (host) { + /* Force disable link detection */ + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES, + PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 | PIPEHANDLER_OVERRIDE_VAL_RXDETECT1); + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, + PIPEHANDLER_OVERRIDE_RXVALID); + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, + PIPEHANDLER_OVERRIDE_RXDETECT); + + ret = atcphy_pipehandler_lock(atcphy); + if (ret) { + dev_err(atcphy->dev, "Failed to lock pipehandler"); + return ret; + } + + /* BIST dance */ + core_set32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG0, + ACIOPHY_TOP_BIST_PHY_CFG0_LN0_RESET_N); + core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG, ACIOPHY_TOP_BIST_OV_CFG_LN0_RESET_N_OV); + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, + !(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 10, 10000); + if (ret) + dev_warn(atcphy->dev, + "Timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n"); + + core_set32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL, + ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE); + core_clear32(atcphy, ACIOPHY_TOP_BIST_READ_CTRL, + ACIOPHY_TOP_BIST_READ_CTRL_LN0_PHY_STATUS_RE); + + core_mask32(atcphy, ACIOPHY_TOP_BIST_PHY_CFG1, + ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN, + FIELD_PREP(ACIOPHY_TOP_BIST_PHY_CFG1_LN0_PWR_DOWN, 3)); + + core_set32(atcphy, ACIOPHY_TOP_BIST_OV_CFG, + ACIOPHY_TOP_BIST_OV_CFG_LN0_PWR_DOWN_OV); + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, + ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN); + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, + ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN); + writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_CIOPHY_CFG1); + + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, + (reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK0), 10, 10000); + if (ret) + dev_warn(atcphy->dev, + "timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK0\n"); + + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_TOP_PHY_STAT, reg, + !(reg & ACIOPHY_TOP_PHY_STAT_LN0_UNK23), 10, 10000); + if (ret) + dev_warn(atcphy->dev, + "timed out waiting for ACIOPHY_TOP_PHY_STAT_LN0_UNK23\n"); + + /* Clear reset for non-selected USB3 PHY (?) */ + mask32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, + PIPEHANDLER_NATIVE_POWER_DOWN, FIELD_PREP(PIPEHANDLER_NATIVE_POWER_DOWN, 3)); + clear32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, + PIPEHANDLER_NATIVE_RESET); + + /* More BIST stuff (?) */ + writel(0, atcphy->regs.core + ACIOPHY_TOP_BIST_OV_CFG); + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, + ACIOPHY_TOP_BIST_CIOPHY_CFG1_CLK_EN); + core_set32(atcphy, ACIOPHY_TOP_BIST_CIOPHY_CFG1, + ACIOPHY_TOP_BIST_CIOPHY_CFG1_BIST_EN); + } + + /* Configure PIPE mux to USB3 PHY */ + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_USB3)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_USB3)); + udelay(10); + + /* Remove link detection override */ + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXVALID); + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXDETECT); + + /* Pipehandler was only locked when the BIST sequence was applied for host mode */ + if (host) { + ret = atcphy_pipehandler_unlock(atcphy); + if (ret) + dev_warn(atcphy->dev, "Failed to unlock pipehandler"); + } + + return 0; +} + +static int atcphy_configure_pipehandler_dummy(struct apple_atcphy *atcphy) +{ + int ret; + + ret = atcphy_pipehandler_check(atcphy); + if (ret) + return ret; + + /* Force disable link detection */ + clear32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE_VALUES, + PIPEHANDLER_OVERRIDE_VAL_RXDETECT0 | PIPEHANDLER_OVERRIDE_VAL_RXDETECT1); + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXVALID); + set32(atcphy->regs.pipehandler + PIPEHANDLER_OVERRIDE, PIPEHANDLER_OVERRIDE_RXDETECT); + + ret = atcphy_pipehandler_lock(atcphy); + if (ret) + dev_warn(atcphy->dev, "Failed to lock pipehandler"); + + /* Switch to dummy PHY */ + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_DUMMY)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_DUMMY)); + udelay(10); + + ret = atcphy_pipehandler_unlock(atcphy); + if (ret) + dev_warn(atcphy->dev, "Failed to unlock pipehandler"); + + mask32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, + PIPEHANDLER_NATIVE_POWER_DOWN, FIELD_PREP(PIPEHANDLER_NATIVE_POWER_DOWN, 2)); + set32(atcphy->regs.pipehandler + PIPEHANDLER_NONSELECTED_OVERRIDE, + PIPEHANDLER_NATIVE_RESET); + + return 0; +} + +static int atcphy_configure_pipehandler(struct apple_atcphy *atcphy, bool host) +{ + int ret; + + lockdep_assert_held(&atcphy->lock); + + switch (atcphy_modes[atcphy->mode].pipehandler_state) { + case ATCPHY_PIPEHANDLER_STATE_USB3: + ret = atcphy_configure_pipehandler_usb3(atcphy, host); + atcphy->pipehandler_up = true; + break; + case ATCPHY_PIPEHANDLER_STATE_USB4: + dev_warn(atcphy->dev, + "ATCPHY_PIPEHANDLER_STATE_USB4 not implemented; falling back to USB2\n"); + ret = atcphy_configure_pipehandler_dummy(atcphy); + atcphy->pipehandler_up = false; + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static void atcphy_setup_pipehandler(struct apple_atcphy *atcphy) +{ + lockdep_assert_held(&atcphy->lock); + + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_OFF)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_DATA, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_DATA, PIPEHANDLER_MUX_CTRL_DATA_DUMMY)); + udelay(10); + mask32(atcphy->regs.pipehandler + PIPEHANDLER_MUX_CTRL, PIPEHANDLER_MUX_CTRL_CLK, + FIELD_PREP(PIPEHANDLER_MUX_CTRL_CLK, PIPEHANDLER_MUX_CTRL_CLK_DUMMY)); + udelay(10); +} + +static void atcphy_configure_lanes(struct apple_atcphy *atcphy, enum atcphy_mode mode) +{ + const struct atcphy_mode_configuration *mode_cfg = atcphy_get_mode_config(atcphy, mode); + + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX0, + FIELD_PREP(ACIOPHY_LANE_MODE_RX0, mode_cfg->lane_mode[0])); + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX0, + FIELD_PREP(ACIOPHY_LANE_MODE_TX0, mode_cfg->lane_mode[0])); + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_RX1, + FIELD_PREP(ACIOPHY_LANE_MODE_RX1, mode_cfg->lane_mode[1])); + core_mask32(atcphy, ACIOPHY_LANE_MODE, ACIOPHY_LANE_MODE_TX1, + FIELD_PREP(ACIOPHY_LANE_MODE_TX1, mode_cfg->lane_mode[1])); + core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_PROTOCOL, + FIELD_PREP(ACIOPHY_CROSSBAR_PROTOCOL, mode_cfg->crossbar)); + + if (mode_cfg->set_swap) + core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP); + else + core_clear32(atcphy, ATCPHY_MISC, ATCPHY_MISC_LANE_SWAP); + + core_mask32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_SINGLE_PMA, + FIELD_PREP(ACIOPHY_CROSSBAR_DP_SINGLE_PMA, mode_cfg->crossbar_dp_single_pma)); + if (mode_cfg->crossbar_dp_both_pma) + core_set32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_BOTH_PMA); + else + core_clear32(atcphy, ACIOPHY_CROSSBAR, ACIOPHY_CROSSBAR_DP_BOTH_PMA); + + if (mode_cfg->dp_lane[0]) { + core_set32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); + udelay(10); + core_clear32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ); + } else { + core_clear32(atcphy, LN0_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); + udelay(10); + } + + if (mode_cfg->dp_lane[1]) { + core_set32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); + udelay(10); + core_clear32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_REQ); + } else { + core_clear32(atcphy, LN1_AUSPMA_RX_TOP + LN_AUSPMA_RX_TOP_PMAFSM, + LN_AUSPMA_RX_TOP_PMAFSM_PCS_OV); + udelay(10); + } +} + +static void atcphy_enable_dp_aux(struct apple_atcphy *atcphy) +{ + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N); + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N_OV); + + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_SELECT, + FIELD_PREP(DPRX_PCLK_SELECT, 1)); + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_ENABLE); + + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_SELECT, + FIELD_PREP(DPTX_PCLK1_SELECT, 1)); + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_ENABLE); + + core_mask32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_SELECT, + FIELD_PREP(DPTX_PCLK2_SELECT, 1)); + core_set32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_ENABLE); + + core_set32(atcphy, ACIOPHY_PLL_COMMON_CTRL, + ACIOPHY_PLL_WAIT_FOR_CMN_READY_BEFORE_RESET_EXIT); + + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_SML_IN); + udelay(10); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_BIG_IN); + udelay(10); + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN); + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_TXTERM_CODEMSB); + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_TXTERM_CODE, + FIELD_PREP(LPDPTX_TXTERM_CODE, 0x16)); + + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_LDO_CTRL, 0x1c00); + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1, LPDPTX_CFG_PMA_PHYS_ADJ, + FIELD_PREP(LPDPTX_CFG_PMA_PHYS_ADJ, 5)); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG1, + LPDPTX_CFG_PMA_PHYS_ADJ_OV); + + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN, + LPDPTX_MARGIN_RCAL_RXOFFSET_EN); + + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_CTRL_PWRDN); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_SHM_CFG_BLK_AUX_CTRL_REG0, + LPDPTX_CFG_PMA_AUX_SEL_LF_DATA); + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_RXOFFSET, + FIELD_PREP(LPDPTX_BLK_AUX_RXOFFSET, 3)); + + mask32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_MARGIN, LPDPTX_AUX_MARGIN_RCAL_TXSWING, + FIELD_PREP(LPDPTX_AUX_MARGIN_RCAL_TXSWING, 12)); + + atcphy->dp_link_rate = -1; +} + +static void atcphy_disable_dp_aux(struct apple_atcphy *atcphy) +{ + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_PWN_DOWN); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CFG_BLK_AUX_CTRL, LPDPTX_BLK_AUX_CTRL_PWRDN); + set32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_AUX_CLAMP_EN); + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_SML_IN); + udelay(10); + clear32(atcphy->regs.lpdptx + LPDPTX_AUX_CONTROL, LPDPTX_SLEEP_B_BIG_IN); + udelay(10); + + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTXPHY_PMA_LANE_RESET_N); + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPRX_PCLK_ENABLE); + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK1_ENABLE); + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DPTX_PCLK2_ENABLE); +} + +static int atcphy_dp_configure_lane(struct apple_atcphy *atcphy, enum atcphy_lane lane, + const struct atcphy_dp_link_rate_configuration *cfg) +{ + void __iomem *tx_shm, *rx_shm, *rx_top; + unsigned int tx_cal_code; + + lockdep_assert_held(&atcphy->lock); + + switch (lane) { + case APPLE_ATCPHY_LANE_0: + tx_shm = atcphy->regs.core + LN0_AUSPMA_TX_SHM; + rx_shm = atcphy->regs.core + LN0_AUSPMA_RX_SHM; + rx_top = atcphy->regs.core + LN0_AUSPMA_RX_TOP; + break; + case APPLE_ATCPHY_LANE_1: + tx_shm = atcphy->regs.core + LN1_AUSPMA_TX_SHM; + rx_shm = atcphy->regs.core + LN1_AUSPMA_RX_SHM; + rx_top = atcphy->regs.core + LN1_AUSPMA_RX_TOP; + break; + default: + return -EINVAL; + } + + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_SML_OV); + udelay(10); + + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_EN_BIG_OV); + udelay(10); + + if (cfg->txa_ldoclk_bypass) { + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML_OV); + udelay(10); + + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG_OV); + udelay(10); + } else { + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_SML_OV); + udelay(10); + + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_LDOCLK, LN_LDOCLK_BYPASS_BIG_OV); + udelay(10); + } + + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_SEL_OV); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_EN); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_EN_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_CLR); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG0, LN_BYTECLK_RESET_SYNC_CLR_OV); + + if (cfg->txa_div2_en) + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN); + else + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_EN_OV); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_CLK_EN_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_RESET); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_CFG_MAIN_REG1, LN_TXA_DIV2_RESET_OV); + + mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE, + FIELD_PREP(LN_TXA_CAL_CTRL_BASE, 0xf)); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_BASE_OV); + + tx_cal_code = FIELD_GET(AUS_UNK_A20_TX_CAL_CODE, readl(atcphy->regs.core + AUS_UNK_A20)); + mask32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL, + FIELD_PREP(LN_TXA_CAL_CTRL, (1 << tx_cal_code) - 1)); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_CAL_CTRL_OV); + + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG2, LN_TXA_MARGIN_2R_OV); + + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_2R_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_POST_4R_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_2R_OV); + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG3, LN_TXA_MARGIN_PRE_4R_OV); + + clear32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ); + set32(tx_shm + LN_AUSPMA_TX_SHM_TXA_IMP_REG0, LN_TXA_HIZ_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N_OV); + udelay(10); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_AFE_CTRL1, LN_RX_DIV20_RESET_N); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_EN_OV); + + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE, + FIELD_PREP(LN_TX_CAL_CODE, tx_cal_code)); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_TX_CAL_CODE_OV); + + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DLY_CTRL_TAPGEN, + FIELD_PREP(LN_TX_CLK_DLY_CTRL_TAPGEN, 3)); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_EN_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_TEST_EN_OV); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_TEST_RXLPBKDT_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_TEST_RXLPBKDT_EN_OV); + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_LPBKIN_DATA, + FIELD_PREP(LN_VREF_LPBKIN_DATA, 3)); + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BIAS_SEL, + FIELD_PREP(LN_VREF_BIAS_SEL, 2)); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BIAS_SEL_OV); + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_ADJUST_GRAY, + FIELD_PREP(LN_VREF_ADJUST_GRAY, 0x18)); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_ADJUST_GRAY_OV); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_EN_OV); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN_OV); + udelay(10); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_VREF_CTRL22, LN_VREF_BOOST_EN_OV); + udelay(10); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PRE_EN_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_TX_PST1_EN_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_PBIAS_EN_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_PULLUP_LEAK_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_SAVOS_CTRL16, LN_RXTERM_PULLUP_LEAK_EN_OV); + + set32(rx_top + LN_AUSPMA_RX_TOP_TJ_CFG_RX_TXMODE, LN_RX_TXMODE); + + if (cfg->txa_div2_en) + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN); + else + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_EN_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_RST); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_CLK_DIV2_RST_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_HRCLK_SEL_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_LSB_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_LSB); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL17, LN_TX_MARGIN_P1_LSB_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_CODE_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_P1_LSB_CODE_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_LSB); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_MARGIN_PRE_LSB_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_LSB_CODE); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_LSB_CODE_OV); + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TX_CTRL18, LN_TX_PRE_CODE_OV); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_SML_EN_OV); + udelay(10); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL11, LN_DTVREG_BIG_EN_OV); + udelay(10); + + mask32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL10, LN_DTVREG_ADJUST, + FIELD_PREP(LN_DTVREG_ADJUST, 0xa)); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL13, LN_DTVREG_ADJUST_OV); + udelay(10); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_TERM_CTRL19, LN_TX_EN_OV); + udelay(10); + + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_CTLE_CTRL0, LN_TX_CLK_EN_OV); + + clear32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_CLR); + set32(rx_shm + LN_AUSPMA_RX_SHM_TJ_RXA_DFE_CTRL12, LN_TX_BYTECLK_RESET_SYNC_CLR_OV); + + return 0; +} + +static int atcphy_auspll_apb_command(struct apple_atcphy *atcphy, u32 command) +{ + int ret; + u32 reg; + + reg = readl(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE); + reg &= ~AUSPLL_APB_CMD_OVERRIDE_CMD; + reg |= FIELD_PREP(AUSPLL_APB_CMD_OVERRIDE_CMD, command); + reg |= AUSPLL_APB_CMD_OVERRIDE_REQ; + reg |= AUSPLL_APB_CMD_OVERRIDE_UNK28; + writel(reg, atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE); + + ret = readl_poll_timeout(atcphy->regs.core + AUSPLL_APB_CMD_OVERRIDE, reg, + (reg & AUSPLL_APB_CMD_OVERRIDE_ACK), 10, 10000); + if (ret) + dev_warn(atcphy->dev, "AUSPLL APB command was not acked\n"); + + core_clear32(atcphy, AUSPLL_APB_CMD_OVERRIDE, AUSPLL_APB_CMD_OVERRIDE_REQ); + + return 0; +} + +static int atcphy_dp_configure(struct apple_atcphy *atcphy, enum atcphy_dp_link_rate lr) +{ + const struct atcphy_dp_link_rate_configuration *cfg; + const struct atcphy_mode_configuration *mode_cfg; + int ret; + u32 reg; + + guard(mutex)(&atcphy->lock); + mode_cfg = atcphy_get_mode_config(atcphy, atcphy->mode); + cfg = &dp_lr_config[lr]; + + if (atcphy->dp_link_rate == lr) + return 0; + + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_CMN_SHM_STS_REG0, reg, + (reg & ACIOPHY_CMN_SHM_STS_REG0_CMD_READY), 10, 10000); + if (ret) { + dev_err(atcphy->dev, "ACIOPHY_CMN_SHM_STS_REG0_CMD_READY not set.\n"); + return ret; + } + + core_clear32(atcphy, AUSPLL_FREQ_CFG, AUSPLL_FREQ_REFCLK); + + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FREQ_COUNT_TARGET, + FIELD_PREP(AUSPLL_FD_FREQ_COUNT_TARGET, cfg->freqinit_count_target)); + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_FBDIVN_HALF); + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_REV_DIVN); + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_MAN, FIELD_PREP(AUSPLL_FD_KI_MAN, 8)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KI_EXP, FIELD_PREP(AUSPLL_FD_KI_EXP, 3)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_MAN, FIELD_PREP(AUSPLL_FD_KP_MAN, 8)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KP_EXP, FIELD_PREP(AUSPLL_FD_KP_EXP, 7)); + core_clear32(atcphy, AUSPLL_FREQ_DESC_A, AUSPLL_FD_KPKI_SCALE_HBW); + + core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_DEN, + FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_DEN, cfg->fbdivn_frac_den)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_B, AUSPLL_FD_FBDIVN_FRAC_NUM, + FIELD_PREP(AUSPLL_FD_FBDIVN_FRAC_NUM, cfg->fbdivn_frac_num)); + + core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_STEP); + core_clear32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_SDM_SSC_EN); + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_PCLK_DIV_SEL, + FIELD_PREP(AUSPLL_FD_PCLK_DIV_SEL, cfg->pclk_div_sel)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFSDM_DIV, + FIELD_PREP(AUSPLL_FD_LFSDM_DIV, 1)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_LFCLK_CTRL, + FIELD_PREP(AUSPLL_FD_LFCLK_CTRL, cfg->lfclk_ctrl)); + core_mask32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_OP_DIVN, + FIELD_PREP(AUSPLL_FD_VCLK_OP_DIVN, cfg->vclk_op_divn)); + core_set32(atcphy, AUSPLL_FREQ_DESC_C, AUSPLL_FD_VCLK_PRE_DIVN); + + core_mask32(atcphy, AUSPLL_CLKOUT_DIV, AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI, + FIELD_PREP(AUSPLL_CLKOUT_PLLA_REFBUFCLK_DI, 7)); + + if (cfg->plla_clkout_vreg_bypass) + core_set32(atcphy, AUSPLL_CLKOUT_DTC_VREG, AUSPLL_DTC_VREG_BYPASS); + else + core_clear32(atcphy, AUSPLL_CLKOUT_DTC_VREG, AUSPLL_DTC_VREG_BYPASS); + + core_set32(atcphy, AUSPLL_BGR, AUSPLL_BGR_CTRL_AVAIL); + + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_PCLK_DRVR_EN); + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_PCLK2_DRVR_EN); + core_set32(atcphy, AUSPLL_CLKOUT_MASTER, AUSPLL_CLKOUT_MASTER_REFBUFCLK_DRVR_EN); + + ret = atcphy_auspll_apb_command(atcphy, 0); + if (ret) + return ret; + + ret = readl_poll_timeout(atcphy->regs.core + ACIOPHY_DP_PCLK_STAT, reg, + (reg & ACIOPHY_AUSPLL_LOCK), 10, 10000); + if (ret) { + dev_err(atcphy->dev, "ACIOPHY_DP_PCLK did not lock.\n"); + return ret; + } + + ret = atcphy_auspll_apb_command(atcphy, 0x2800); + if (ret) + return ret; + + if (mode_cfg->dp_lane[0]) { + ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_0, cfg); + if (ret) + return ret; + } + + if (mode_cfg->dp_lane[1]) { + ret = atcphy_dp_configure_lane(atcphy, APPLE_ATCPHY_LANE_1, cfg); + if (ret) + return ret; + } + + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DP_PMA_BYTECLK_RESET); + core_clear32(atcphy, ACIOPHY_LANE_DP_CFG_BLK_TX_DP_CTRL0, DP_MAC_DIV20_CLK_SEL); + + atcphy->dp_link_rate = lr; + return 0; +} + +static void atcphy_usb2_power_off(struct apple_atcphy *atcphy) +{ + /* Disable the PHY, this clears USB2PHY_USBCTL_RUN */ + writel(USB2PHY_USBCTL_ISOLATION, atcphy->regs.usb2phy + USB2PHY_USBCTL); + udelay(10); + + /* Switch the PHY to low power mode */ + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ); + udelay(10); + + /* Enable all resets */ + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET); + udelay(10); + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET); + udelay(10); + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N); + udelay(10); + set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_APBCLK_GATE_OFF); + set32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_REFCLK_GATE_OFF); +} + +static int atcphy_power_off(struct apple_atcphy *atcphy) +{ + u32 reg; + int ret; + + atcphy_disable_dp_aux(atcphy); + + /* Enable all reset lines */ + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N); + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN); + core_clear32(atcphy, ATCPHY_MISC, ATCPHY_MISC_RESET_N | ATCPHY_MISC_LANE_SWAP); + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N); + + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG); + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, + !(reg & ATCPHY_POWER_SLEEP_BIG), 10, 1000); + if (ret) { + dev_err(atcphy->dev, "Failed to sleep atcphy \"big\"\n"); + return ret; + } + + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL); + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, + !(reg & ATCPHY_POWER_SLEEP_SMALL), 10, 1000); + if (ret) { + dev_err(atcphy->dev, "Failed to sleep atcphy \"small\"\n"); + return ret; + } + + return 0; +} + +static void atcphy_usb2_power_on(struct apple_atcphy *atcphy) +{ + set32(atcphy->regs.usb2phy + USB2PHY_SIG, + USB2PHY_SIG_VBUSDET_FORCE_VAL | USB2PHY_SIG_VBUSDET_FORCE_EN | + USB2PHY_SIG_VBUSVLDEXT_FORCE_VAL | USB2PHY_SIG_VBUSVLDEXT_FORCE_EN); + udelay(10); + + /* Take the PHY out of its low power state */ + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_SIDDQ); + udelay(10); + + /* Release reset */ + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_RESET); + udelay(10); + clear32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_PORT_RESET); + udelay(10); + set32(atcphy->regs.usb2phy + USB2PHY_CTL, USB2PHY_CTL_APB_RESET_N); + udelay(10); + clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_APBCLK_GATE_OFF); + clear32(atcphy->regs.usb2phy + USB2PHY_MISCTUNE, USB2PHY_MISCTUNE_REFCLK_GATE_OFF); + + /* Enable the PHY */ + writel(USB2PHY_USBCTL_RUN, atcphy->regs.usb2phy + USB2PHY_USBCTL); +} + +static int atcphy_power_on(struct apple_atcphy *atcphy) +{ + u32 reg; + int ret; + + atcphy_usb2_power_on(atcphy); + + core_set32(atcphy, ATCPHY_MISC, ATCPHY_MISC_RESET_N); + + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_SMALL); + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, + reg & ATCPHY_POWER_SLEEP_SMALL, 100, 100000); + if (ret) { + dev_err(atcphy->dev, "failed to wakeup atcphy \"small\"\n"); + return ret; + } + + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_SLEEP_BIG); + ret = readl_poll_timeout(atcphy->regs.core + ATCPHY_POWER_STAT, reg, + reg & ATCPHY_POWER_SLEEP_BIG, 100, 100000); + if (ret) { + dev_err(atcphy->dev, "failed to wakeup atcphy \"big\"\n"); + return ret; + } + + core_clear32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_CLAMP_EN); + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_APB_RESET_N); + + return 0; +} + +static int atcphy_configure(struct apple_atcphy *atcphy, enum atcphy_mode mode) +{ + int ret = 0; + + lockdep_assert_held(&atcphy->lock); + + if (mode == APPLE_ATCPHY_MODE_OFF) { + ret = atcphy_power_off(atcphy); + atcphy->mode = mode; + return ret; + } + + ret = atcphy_power_on(atcphy); + if (ret) + return ret; + + atcphy_apply_tunables(atcphy, mode); + + core_set32(atcphy, AUSPLL_FSM_CTRL, 0x1fe000); + core_set32(atcphy, AUSPLL_APB_CMD_OVERRIDE, AUSPLL_APB_CMD_OVERRIDE_UNK28); + + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_SMALL_OV); + udelay(10); + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_BIG_OV); + udelay(10); + set32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_COMMON_CLAMP_OV); + udelay(10); + + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_SMALL_OV, + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_SMALL_OV, 3)); + udelay(10); + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_BIG_OV, + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_BIG_OV, 3)); + udelay(10); + mask32(atcphy->regs.core + ACIOPHY_SLEEP_CTRL, ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV, + FIELD_PREP(ACIOPHY_SLEEP_CTRL_TX_CLAMP_OV, 3)); + udelay(10); + + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_BIG_OV, + FIELD_PREP(ACIOPHY_CFG0_RX_BIG_OV, 3)); + udelay(10); + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_SMALL_OV, + FIELD_PREP(ACIOPHY_CFG0_RX_SMALL_OV, 3)); + udelay(10); + mask32(atcphy->regs.core + ACIOPHY_CFG0, ACIOPHY_CFG0_RX_CLAMP_OV, + FIELD_PREP(ACIOPHY_CFG0_RX_CLAMP_OV, 3)); + udelay(10); + + /* Setup AUX channel if DP altmode is requested */ + if (atcphy_modes[mode].enable_dp_aux) + atcphy_enable_dp_aux(atcphy); + + /* Enable clocks and configure lanes */ + core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_PCLK_EN); + core_set32(atcphy, CIO3PLL_CLK_CTRL, CIO3PLL_CLK_REFCLK_EN); + atcphy_configure_lanes(atcphy, mode); + + /* Take the USB3 PHY out of reset */ + core_set32(atcphy, ATCPHY_POWER_CTRL, ATCPHY_POWER_PHY_RESET_N); + + atcphy->mode = mode; + + return 0; +} + +static int atcphy_usb2_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + struct apple_atcphy *atcphy = phy_get_drvdata(phy); + + guard(mutex)(&atcphy->lock); + + switch (mode) { + case PHY_MODE_USB_HOST: + set32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST); + break; + case PHY_MODE_USB_DEVICE: + clear32(atcphy->regs.usb2phy + USB2PHY_SIG, USB2PHY_SIG_HOST); + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct phy_ops apple_atc_usb2_phy_ops = { + .owner = THIS_MODULE, + .set_mode = atcphy_usb2_set_mode, +}; + +static int atcphy_usb3_power_off(struct phy *phy) +{ + struct apple_atcphy *atcphy = phy_get_drvdata(phy); + int ret; + + guard(mutex)(&atcphy->lock); + + ret = atcphy_configure_pipehandler_dummy(atcphy); + if (ret) + dev_warn(atcphy->dev, "Failed to switch pipe to dummy: %d", ret); + + atcphy->pipehandler_up = false; + + if (atcphy->mode != APPLE_ATCPHY_MODE_OFF) + atcphy_configure(atcphy, APPLE_ATCPHY_MODE_OFF); + + return 0; +} + +static int atcphy_usb3_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + struct apple_atcphy *atcphy = phy_get_drvdata(phy); + + guard(mutex)(&atcphy->lock); + + /* + * We may get multiple calls to set_mode (for host mode e.g. at least one from the dwc3 glue + * driver and then another one from the generic xhci code) but must only configure the + * PIPE handler once. + */ + if (atcphy->pipehandler_up) + return 0; + + switch (mode) { + case PHY_MODE_USB_HOST: + return atcphy_configure_pipehandler(atcphy, true); + case PHY_MODE_USB_DEVICE: + return atcphy_configure_pipehandler(atcphy, false); + default: + return -EINVAL; + } +} + +static const struct phy_ops apple_atc_usb3_phy_ops = { + .owner = THIS_MODULE, + .power_off = atcphy_usb3_power_off, + .set_mode = atcphy_usb3_set_mode, +}; + +static int atcphy_dpphy_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + /* Nothing to do here since the setup already happened in mux_set */ + if (mode == PHY_MODE_DP && submode == 0) + return 0; + return -EINVAL; +} + +static int atcphy_dpphy_validate(struct phy *phy, enum phy_mode mode, int submode, + union phy_configure_opts *opts_) +{ + struct phy_configure_opts_dp *opts = &opts_->dp; + struct apple_atcphy *atcphy = phy_get_drvdata(phy); + + if (mode != PHY_MODE_DP) + return -EINVAL; + if (submode != 0) + return -EINVAL; + + switch (atcphy->mode) { + case APPLE_ATCPHY_MODE_USB3_DP: + opts->lanes = 2; + break; + case APPLE_ATCPHY_MODE_DP: + opts->lanes = 4; + break; + default: + opts->lanes = 0; + } + + return 0; +} + +static int atcphy_dpphy_configure(struct phy *phy, union phy_configure_opts *opts_) +{ + struct phy_configure_opts_dp *opts = &opts_->dp; + struct apple_atcphy *atcphy = phy_get_drvdata(phy); + enum atcphy_dp_link_rate link_rate; + + if (opts->set_voltages) + return -EINVAL; + if (opts->set_lanes) + return -EINVAL; + + if (opts->set_rate) { + switch (opts->link_rate) { + case 1620: + link_rate = ATCPHY_DP_LINK_RATE_RBR; + break; + case 2700: + link_rate = ATCPHY_DP_LINK_RATE_HBR; + break; + case 5400: + link_rate = ATCPHY_DP_LINK_RATE_HBR2; + break; + case 8100: + link_rate = ATCPHY_DP_LINK_RATE_HBR3; + break; + case 0: + return 0; + default: + dev_err(atcphy->dev, "Unsupported link rate: %d\n", opts->link_rate); + return -EINVAL; + } + + return atcphy_dp_configure(atcphy, link_rate); + } + + return 0; +} + +static const struct phy_ops apple_atc_dp_phy_ops = { + .owner = THIS_MODULE, + .configure = atcphy_dpphy_configure, + .validate = atcphy_dpphy_validate, + .set_mode = atcphy_dpphy_set_mode, +}; + +static struct phy *atcphy_xlate(struct device *dev, const struct of_phandle_args *args) +{ + struct apple_atcphy *atcphy = dev_get_drvdata(dev); + + switch (args->args[0]) { + case PHY_TYPE_USB2: + return atcphy->phys.usb2; + case PHY_TYPE_USB3: + return atcphy->phys.usb3; + case PHY_TYPE_DP: + return atcphy->phys.dp; + } + return ERR_PTR(-ENODEV); +} + +static int atcphy_probe_phy(struct apple_atcphy *atcphy) +{ + struct { + struct phy **phy; + const struct phy_ops *ops; + } phys[] = { + { &atcphy->phys.usb2, &apple_atc_usb2_phy_ops }, + { &atcphy->phys.usb3, &apple_atc_usb3_phy_ops }, + { &atcphy->phys.dp, &apple_atc_dp_phy_ops }, + }; + + for (int i = 0; i < ARRAY_SIZE(phys); i++) { + *phys[i].phy = devm_phy_create(atcphy->dev, NULL, phys[i].ops); + if (IS_ERR(*phys[i].phy)) + return PTR_ERR(*phys[i].phy); + phy_set_drvdata(*phys[i].phy, atcphy); + } + + atcphy->phy_provider = devm_of_phy_provider_register(atcphy->dev, atcphy_xlate); + if (IS_ERR(atcphy->phy_provider)) + return PTR_ERR(atcphy->phy_provider); + return 0; +} + +static void _atcphy_dwc3_reset_assert(struct apple_atcphy *atcphy) +{ + lockdep_assert_held(&atcphy->lock); + + clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, PIPEHANDLER_AON_GEN_DWC3_RESET_N); + set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, + PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN); +} + +static int atcphy_dwc3_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct apple_atcphy *atcphy = container_of(rcdev, struct apple_atcphy, rcdev); + int ret; + + guard(mutex)(&atcphy->lock); + + _atcphy_dwc3_reset_assert(atcphy); + + if (atcphy->pipehandler_up) { + ret = atcphy_configure_pipehandler_dummy(atcphy); + if (ret) + dev_warn(atcphy->dev, "Failed to switch PIPE to dummy: %d\n", ret); + else + atcphy->pipehandler_up = false; + } + + atcphy_usb2_power_off(atcphy); + + return 0; +} + +static int atcphy_dwc3_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id) +{ + struct apple_atcphy *atcphy = container_of(rcdev, struct apple_atcphy, rcdev); + + guard(mutex)(&atcphy->lock); + + clear32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, + PIPEHANDLER_AON_GEN_DWC3_FORCE_CLAMP_EN); + set32(atcphy->regs.pipehandler + PIPEHANDLER_AON_GEN, PIPEHANDLER_AON_GEN_DWC3_RESET_N); + + return 0; +} + +const struct reset_control_ops atcphy_dwc3_reset_ops = { + .assert = atcphy_dwc3_reset_assert, + .deassert = atcphy_dwc3_reset_deassert, +}; + +static int atcphy_reset_xlate(struct reset_controller_dev *rcdev, + const struct of_phandle_args *reset_spec) +{ + return 0; +} + +static int atcphy_probe_rcdev(struct apple_atcphy *atcphy) +{ + atcphy->rcdev.owner = THIS_MODULE; + atcphy->rcdev.nr_resets = 1; + atcphy->rcdev.ops = &atcphy_dwc3_reset_ops; + atcphy->rcdev.of_node = atcphy->dev->of_node; + atcphy->rcdev.of_reset_n_cells = 0; + atcphy->rcdev.of_xlate = atcphy_reset_xlate; + + return devm_reset_controller_register(atcphy->dev, &atcphy->rcdev); +} + +static int atcphy_sw_set(struct typec_switch_dev *sw, enum typec_orientation orientation) +{ + struct apple_atcphy *atcphy = typec_switch_get_drvdata(sw); + + guard(mutex)(&atcphy->lock); + + switch (orientation) { + case TYPEC_ORIENTATION_NONE: + break; + case TYPEC_ORIENTATION_NORMAL: + atcphy->swap_lanes = false; + break; + case TYPEC_ORIENTATION_REVERSE: + atcphy->swap_lanes = true; + break; + } + + return 0; +} + +static int atcphy_probe_switch(struct apple_atcphy *atcphy) +{ + struct typec_switch_desc sw_desc = { + .drvdata = atcphy, + .fwnode = atcphy->dev->fwnode, + .set = atcphy_sw_set, + }; + + return PTR_ERR_OR_ZERO(typec_switch_register(atcphy->dev, &sw_desc)); +} + +static int atcphy_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) +{ + struct apple_atcphy *atcphy = typec_mux_get_drvdata(mux); + enum atcphy_mode target_mode; + + guard(mutex)(&atcphy->lock); + + if (state->mode == TYPEC_STATE_SAFE) { + target_mode = APPLE_ATCPHY_MODE_OFF; + } else if (state->mode == TYPEC_STATE_USB) { + target_mode = APPLE_ATCPHY_MODE_USB3; + } else if (!state->alt && state->mode == TYPEC_MODE_USB4) { + struct enter_usb_data *data = state->data; + u32 eudo_usb_mode = FIELD_GET(EUDO_USB_MODE_MASK, data->eudo); + + switch (eudo_usb_mode) { + case EUDO_USB_MODE_USB2: + target_mode = APPLE_ATCPHY_MODE_USB2; + break; + case EUDO_USB_MODE_USB3: + target_mode = APPLE_ATCPHY_MODE_USB3; + break; + case EUDO_USB_MODE_USB4: + target_mode = APPLE_ATCPHY_MODE_USB4; + break; + default: + dev_warn(atcphy->dev, "Unsupported EUDO USB mode: 0x%x.\n", eudo_usb_mode); + target_mode = APPLE_ATCPHY_MODE_OFF; + } + } else if (state->alt && state->alt->svid == USB_TYPEC_TBT_SID) { + target_mode = APPLE_ATCPHY_MODE_TBT; + } else if (state->alt && state->alt->svid == USB_TYPEC_DP_SID) { + switch (state->mode) { + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + target_mode = APPLE_ATCPHY_MODE_DP; + break; + case TYPEC_DP_STATE_D: + target_mode = APPLE_ATCPHY_MODE_USB3_DP; + break; + default: + dev_err(atcphy->dev, + "Unsupported DP pin assignment: 0x%lx, your connected device will not work.\n", + state->mode); + target_mode = APPLE_ATCPHY_MODE_OFF; + } + } else if (state->alt) { + dev_err(atcphy->dev, + "Unknown alternate mode SVID: 0x%x, your connected device will not work.\n", + state->alt->svid); + target_mode = APPLE_ATCPHY_MODE_OFF; + } else { + dev_err(atcphy->dev, "Unknown mode: 0x%lx, your connected device will not work.\n", + state->mode); + target_mode = APPLE_ATCPHY_MODE_OFF; + } + + if (atcphy->mode == target_mode) + return 0; + + /* + * If the pipehandler is still/already up here there's a bug somewhere so make sure to + * complain loudly. We can still try to switch modes and hope for the best though, + * in the worst case the hardware will fall back to USB2-only. + */ + WARN_ON_ONCE(atcphy->pipehandler_up); + return atcphy_configure(atcphy, target_mode); +} + +static int atcphy_probe_mux(struct apple_atcphy *atcphy) +{ + struct typec_mux_desc mux_desc = { + .drvdata = atcphy, + .fwnode = atcphy->dev->fwnode, + .set = atcphy_mux_set, + }; + + return PTR_ERR_OR_ZERO(typec_mux_register(atcphy->dev, &mux_desc)); +} + +static int atcphy_load_tunables(struct apple_atcphy *atcphy) +{ + struct { + const char *dt_name; + struct apple_tunable **tunable; + struct resource *res; + } tunables[] = { + { "apple,tunable-axi2af", &atcphy->tunables.axi2af, atcphy->res.axi2af }, + { "apple,tunable-common-a", &atcphy->tunables.common[0], atcphy->res.core }, + { "apple,tunable-common-b", &atcphy->tunables.common[1], atcphy->res.core }, + { "apple,tunable-lane0-usb", &atcphy->tunables.lane_usb3[0], atcphy->res.core }, + { "apple,tunable-lane1-usb", &atcphy->tunables.lane_usb3[1], atcphy->res.core }, + { "apple,tunable-lane0-cio", &atcphy->tunables.lane_usb4[0], atcphy->res.core }, + { "apple,tunable-lane1-cio", &atcphy->tunables.lane_usb4[1], atcphy->res.core }, + { "apple,tunable-lane0-dp", &atcphy->tunables.lane_dp[0], atcphy->res.core }, + { "apple,tunable-lane1-dp", &atcphy->tunables.lane_dp[1], atcphy->res.core }, + }; + + for (int i = 0; i < ARRAY_SIZE(tunables); i++) { + *tunables[i].tunable = devm_apple_tunable_parse( + atcphy->dev, atcphy->np, tunables[i].dt_name, tunables[i].res); + if (IS_ERR(*tunables[i].tunable)) { + dev_err(atcphy->dev, "Failed to read tunable %s: %ld\n", + tunables[i].dt_name, PTR_ERR(*tunables[i].tunable)); + return PTR_ERR(*tunables[i].tunable); + } + } + + return 0; +} + +static int atcphy_map_resources(struct platform_device *pdev, struct apple_atcphy *atcphy) +{ + struct { + const char *name; + void __iomem **addr; + struct resource **res; + } resources[] = { + { "core", &atcphy->regs.core, &atcphy->res.core }, + { "lpdptx", &atcphy->regs.lpdptx, NULL }, + { "axi2af", &atcphy->regs.axi2af, &atcphy->res.axi2af }, + { "usb2phy", &atcphy->regs.usb2phy, NULL }, + { "pipehandler", &atcphy->regs.pipehandler, NULL }, + }; + struct resource *res; + + for (int i = 0; i < ARRAY_SIZE(resources); i++) { + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resources[i].name); + *resources[i].addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(resources[i].addr)) + return dev_err_probe(atcphy->dev, PTR_ERR(resources[i].addr), + "Unable to map %s regs", resources[i].name); + + if (resources[i].res) + *resources[i].res = res; + } + + return 0; +} + +static int atcphy_probe_finalize(struct apple_atcphy *atcphy) +{ + int ret; + + guard(mutex)(&atcphy->lock); + + /* Reset dwc3 on probe, let dwc3 (consumer) deassert it */ + _atcphy_dwc3_reset_assert(atcphy); + + /* Reset atcphy to clear any state potentially left by the bootloader */ + atcphy_usb2_power_off(atcphy); + atcphy_power_off(atcphy); + atcphy_setup_pipehandler(atcphy); + + ret = atcphy_probe_rcdev(atcphy); + if (ret) + return dev_err_probe(atcphy->dev, ret, "Probing rcdev failed"); + ret = atcphy_probe_mux(atcphy); + if (ret) + return dev_err_probe(atcphy->dev, ret, "Probing mux failed"); + ret = atcphy_probe_switch(atcphy); + if (ret) + return dev_err_probe(atcphy->dev, ret, "Probing switch failed"); + ret = atcphy_probe_phy(atcphy); + if (ret) + return dev_err_probe(atcphy->dev, ret, "Probing phy failed"); + + return 0; +} + +static int atcphy_probe(struct platform_device *pdev) +{ + struct apple_atcphy *atcphy; + struct device *dev = &pdev->dev; + int ret; + + atcphy = devm_kzalloc(&pdev->dev, sizeof(*atcphy), GFP_KERNEL); + if (!atcphy) + return -ENOMEM; + + atcphy->dev = dev; + atcphy->np = dev->of_node; + mutex_init(&atcphy->lock); + platform_set_drvdata(pdev, atcphy); + + ret = atcphy_map_resources(pdev, atcphy); + if (ret) + return ret; + ret = atcphy_load_tunables(atcphy); + if (ret) + return ret; + + atcphy->mode = APPLE_ATCPHY_MODE_OFF; + atcphy->pipehandler_up = false; + + return atcphy_probe_finalize(atcphy); +} + +static const struct of_device_id atcphy_match[] = { + { .compatible = "apple,t8103-atcphy" }, + {}, +}; +MODULE_DEVICE_TABLE(of, atcphy_match); + +static struct platform_driver atcphy_driver = { + .driver = { + .name = "phy-apple-atc", + .of_match_table = atcphy_match, + }, + .probe = atcphy_probe, +}; +module_platform_driver(atcphy_driver); + +MODULE_AUTHOR("Sven Peter "); +MODULE_DESCRIPTION("Apple Type-C PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index 37fa4bad6bd7..d446a0f97688 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -300,6 +300,7 @@ enum cdns_torrent_phy_type { TYPE_USB, TYPE_USXGMII, TYPE_PCIE_ML, + TYPE_XAUI, }; enum cdns_torrent_ref_clk { @@ -320,14 +321,14 @@ enum cdns_torrent_ssc_mode { /* Unique key id for vals table entry * REFCLK0_RATE | REFCLK1_RATE | LINK0_TYPE | LINK1_TYPE | SSC_TYPE */ -#define REFCLK0_SHIFT 12 -#define REFCLK0_MASK GENMASK(14, 12) -#define REFCLK1_SHIFT 9 -#define REFCLK1_MASK GENMASK(11, 9) -#define LINK0_SHIFT 6 -#define LINK0_MASK GENMASK(8, 6) +#define REFCLK0_SHIFT 15 +#define REFCLK0_MASK GENMASK(18, 15) +#define REFCLK1_SHIFT 11 +#define REFCLK1_MASK GENMASK(14, 11) +#define LINK0_SHIFT 7 +#define LINK0_MASK GENMASK(10, 7) #define LINK1_SHIFT 3 -#define LINK1_MASK GENMASK(5, 3) +#define LINK1_MASK GENMASK(6, 3) #define SSC_SHIFT 0 #define SSC_MASK GENMASK(2, 0) @@ -397,6 +398,7 @@ struct cdns_torrent_refclk_driver { struct clk_hw hw; struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG]; struct clk_init_data clk_data; + u8 parent_index; }; #define to_cdns_torrent_refclk_driver(_hw) \ @@ -708,6 +710,8 @@ static const char *cdns_torrent_get_phy_type(enum cdns_torrent_phy_type phy_type return "USB"; case TYPE_USXGMII: return "USXGMII"; + case TYPE_XAUI: + return "XAUI"; default: return "None"; } @@ -3020,6 +3024,9 @@ static int cdns_torrent_phy_probe(struct platform_device *pdev) case PHY_TYPE_USXGMII: cdns_phy->phys[node].phy_type = TYPE_USXGMII; break; + case PHY_TYPE_XAUI: + cdns_phy->phys[node].phy_type = TYPE_XAUI; + break; default: dev_err(dev, "Unsupported protocol\n"); ret = -EINVAL; @@ -3326,11 +3333,29 @@ static const struct cdns_torrent_vals sgmii_qsgmii_xcvr_diag_ln_vals = { .num_regs = ARRAY_SIZE(sgmii_qsgmii_xcvr_diag_ln_regs), }; +static void cdns_torrent_refclk_driver_suspend(struct cdns_torrent_phy *cdns_phy) +{ + struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER]; + struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw); + + refclk_driver->parent_index = cdns_torrent_refclk_driver_get_parent(hw); +} + +static int cdns_torrent_refclk_driver_resume(struct cdns_torrent_phy *cdns_phy) +{ + struct clk_hw *hw = cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER]; + struct cdns_torrent_refclk_driver *refclk_driver = to_cdns_torrent_refclk_driver(hw); + + return cdns_torrent_refclk_driver_set_parent(hw, refclk_driver->parent_index); +} + static int cdns_torrent_phy_suspend_noirq(struct device *dev) { struct cdns_torrent_phy *cdns_phy = dev_get_drvdata(dev); int i; + cdns_torrent_refclk_driver_suspend(cdns_phy); + reset_control_assert(cdns_phy->phy_rst); reset_control_assert(cdns_phy->apb_rst); for (i = 0; i < cdns_phy->nsubnodes; i++) @@ -3352,6 +3377,10 @@ static int cdns_torrent_phy_resume_noirq(struct device *dev) int node = cdns_phy->nsubnodes; int ret, i; + ret = cdns_torrent_refclk_driver_resume(cdns_phy); + if (ret) + return ret; + ret = cdns_torrent_clk(cdns_phy); if (ret) return ret; @@ -3382,6 +3411,95 @@ static DEFINE_NOIRQ_DEV_PM_OPS(cdns_torrent_phy_pm_ops, cdns_torrent_phy_suspend_noirq, cdns_torrent_phy_resume_noirq); +/* PCIe and XAUI link configuration */ +static const struct cdns_reg_pairs pcie_xaui_link_cmn_regs[] = { + {0x0003, PHY_PLL_CFG}, + {0x0600, CMN_PDIAG_PLL1_CLK_SEL_M0} +}; + +static const struct cdns_reg_pairs xaui_pcie_xcvr_diag_ln_regs[] = { + {0x0011, XCVR_DIAG_HSCLK_SEL}, + {0x0089, XCVR_DIAG_PLLDRC_CTRL} +}; + +static const struct cdns_torrent_vals pcie_xaui_link_cmn_vals = { + .reg_pairs = pcie_xaui_link_cmn_regs, + .num_regs = ARRAY_SIZE(pcie_xaui_link_cmn_regs), +}; + +static const struct cdns_torrent_vals xaui_pcie_xcvr_diag_ln_vals = { + .reg_pairs = xaui_pcie_xcvr_diag_ln_regs, + .num_regs = ARRAY_SIZE(xaui_pcie_xcvr_diag_ln_regs), +}; + +/* XAUI 100 MHz Ref clk, no SSC */ +static const struct cdns_reg_pairs xaui_100_no_ssc_cmn_regs[] = { + {0x0004, CMN_PLL1_DSM_DIAG_M0}, + {0x0B17, CMN_PDIAG_PLL1_CP_PADJ_M0}, + {0x0E01, CMN_PDIAG_PLL1_CP_IADJ_M0}, + {0x0D05, CMN_PDIAG_PLL1_FILT_PADJ_M0}, + {0x003E, CMN_PLL1_INTDIV_M0}, + {0x8000, CMN_PLL1_FRACDIVL_M0}, + {0x0002, CMN_PLL1_FRACDIVH_M0}, + {0x002A, CMN_PLL1_HIGH_THR_M0}, + {0x3102, CMN_PDIAG_PLL1_CTRL_M0}, + {0x007F, CMN_TXPUCAL_TUNE}, + {0x007F, CMN_TXPDCAL_TUNE} +}; + +static const struct cdns_reg_pairs xaui_100_no_ssc_tx_ln_regs[] = { + {0x00F3, TX_PSC_A0}, + {0x04A2, TX_PSC_A2}, + {0x04A2, TX_PSC_A3 }, + {0x0000, TX_TXCC_CPOST_MULT_00} +}; + +static const struct cdns_reg_pairs ti_xaui_100_no_ssc_tx_ln_regs[] = { + {0x00F3, TX_PSC_A0}, + {0x04A2, TX_PSC_A2}, + {0x04A2, TX_PSC_A3 }, + {0x0000, TX_TXCC_CPOST_MULT_00}, + {0x4000, XCVR_DIAG_RXCLK_CTRL} +}; + +static const struct cdns_reg_pairs xaui_100_no_ssc_rx_ln_regs[] = { + {0x091D, RX_PSC_A0}, + {0x0900, RX_PSC_A2}, + {0x0100, RX_PSC_A3}, + {0x03C7, RX_REE_GCSM1_EQENM_PH1}, + {0x01C7, RX_REE_GCSM1_EQENM_PH2}, + {0x0000, RX_DIAG_DFE_CTRL}, + {0x0019, RX_REE_TAP1_CLIP}, + {0x0019, RX_REE_TAP2TON_CLIP}, + {0x0098, RX_DIAG_NQST_CTRL}, + {0x0C01, RX_DIAG_DFE_AMP_TUNE_2}, + {0x0000, RX_DIAG_DFE_AMP_TUNE_3}, + {0x0000, RX_DIAG_PI_CAP}, + {0x0031, RX_DIAG_PI_RATE}, + {0x0001, RX_DIAG_ACYA}, + {0x018C, RX_CDRLF_CNFG}, +}; + +static const struct cdns_torrent_vals xaui_100_no_ssc_cmn_vals = { + .reg_pairs = xaui_100_no_ssc_cmn_regs, + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_cmn_regs), +}; + +static const struct cdns_torrent_vals xaui_100_no_ssc_tx_ln_vals = { + .reg_pairs = xaui_100_no_ssc_tx_ln_regs, + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_tx_ln_regs), +}; + +static const struct cdns_torrent_vals ti_xaui_100_no_ssc_tx_ln_vals = { + .reg_pairs = ti_xaui_100_no_ssc_tx_ln_regs, + .num_regs = ARRAY_SIZE(ti_xaui_100_no_ssc_tx_ln_regs), +}; + +static const struct cdns_torrent_vals xaui_100_no_ssc_rx_ln_vals = { + .reg_pairs = xaui_100_no_ssc_rx_ln_regs, + .num_regs = ARRAY_SIZE(xaui_100_no_ssc_rx_ln_regs), +}; + /* USB and DP link configuration */ static const struct cdns_reg_pairs usb_dp_link_cmn_regs[] = { {0x0002, PHY_PLL_CFG}, @@ -4853,6 +4971,7 @@ static const struct cdns_torrent_vals_entry link_cmn_vals_entries[] = { {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_link_cmn_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_link_cmn_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_link_cmn_vals}, + {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), &pcie_xaui_link_cmn_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_link_cmn_vals}, @@ -4879,6 +4998,8 @@ static const struct cdns_torrent_vals_entry link_cmn_vals_entries[] = { {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &pcie_usxgmii_link_cmn_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_link_cmn_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_link_cmn_vals}, + + {CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &pcie_xaui_link_cmn_vals}, }; static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = { @@ -4893,6 +5014,7 @@ static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = { {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USB), &pcie_usb_xcvr_diag_ln_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_DP), &pcie_dp_xcvr_diag_ln_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_USXGMII), &pcie_usxgmii_xcvr_diag_ln_vals}, + {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE, TYPE_XAUI), NULL}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_PCIE_ML, TYPE_USB), &ml_pcie_usb_xcvr_diag_ln_vals}, @@ -4919,6 +5041,8 @@ static const struct cdns_torrent_vals_entry xcvr_diag_vals_entries[] = { {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_PCIE), &usxgmii_pcie_xcvr_diag_ln_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_SGMII), &usxgmii_sgmii_xcvr_diag_ln_vals}, {CDNS_TORRENT_KEY_ANYCLK(TYPE_USXGMII, TYPE_QSGMII), &usxgmii_sgmii_xcvr_diag_ln_vals}, + + {CDNS_TORRENT_KEY_ANYCLK(TYPE_XAUI, TYPE_PCIE), &xaui_pcie_xcvr_diag_ln_vals}, }; static const struct cdns_torrent_vals_entry pcs_cmn_vals_entries[] = { @@ -4960,6 +5084,8 @@ static const struct cdns_torrent_vals_entry cmn_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals}, @@ -5010,6 +5136,8 @@ static const struct cdns_torrent_vals_entry cmn_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, /* Dual refclk */ @@ -5054,6 +5182,8 @@ static const struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL}, @@ -5104,6 +5234,8 @@ static const struct cdns_torrent_vals_entry cdns_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, /* Dual refclk */ @@ -5148,6 +5280,8 @@ static const struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_no_ssc_rx_ln_vals}, @@ -5198,6 +5332,8 @@ static const struct cdns_torrent_vals_entry cdns_rx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, /* Dual refclk */ @@ -5278,6 +5414,8 @@ static const struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL}, @@ -5328,6 +5466,8 @@ static const struct cdns_torrent_vals_entry ti_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, /* Dual refclk */ @@ -5406,6 +5546,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &ml_pcie_100_no_ssc_cmn_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &ml_pcie_100_no_ssc_cmn_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &ml_pcie_100_int_ssc_cmn_vals}, @@ -5456,6 +5598,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_cmn_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_cmn_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_cmn_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &sl_usxgmii_156_25_no_ssc_cmn_vals}, /* Dual refclk */ @@ -5500,6 +5644,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), NULL}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), NULL}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), NULL}, @@ -5550,6 +5696,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_tx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &ti_xaui_100_no_ssc_tx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_tx_ln_vals}, /* Dual refclk */ @@ -5594,6 +5742,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_DP, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE, TYPE_XAUI, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, NO_SSC), &pcie_100_no_ssc_rx_ln_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, EXTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_PCIE_ML, TYPE_USB, INTERNAL_SSC), &pcie_100_no_ssc_rx_ln_vals}, @@ -5644,6 +5794,8 @@ static const struct cdns_torrent_vals_entry ti_j7200_rx_ln_vals_entries[] = { {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_USB, TYPE_DP, NO_SSC), &usb_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_100_MHZ, CLK_100_MHZ, TYPE_XAUI, TYPE_PCIE, NO_SSC), &xaui_100_no_ssc_rx_ln_vals}, + {CDNS_TORRENT_KEY(CLK_156_25_MHZ, CLK_156_25_MHZ, TYPE_USXGMII, TYPE_NONE, NO_SSC), &usxgmii_156_25_no_ssc_rx_ln_vals}, /* Dual refclk */ diff --git a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c index 91b3e62743d3..b05d80e849a1 100644 --- a/drivers/phy/freescale/phy-fsl-imx8mq-usb.c +++ b/drivers/phy/freescale/phy-fsl-imx8mq-usb.c @@ -17,6 +17,10 @@ #define PHY_CTRL0_FSEL_MASK GENMASK(10, 5) #define PHY_CTRL0_FSEL_24M 0x2a #define PHY_CTRL0_FSEL_100M 0x27 +#define PHY_CTRL0_SSC_RANGE_MASK GENMASK(23, 21) +#define PHY_CTRL0_SSC_RANGE_4003PPM 0x2 +#define PHY_CTRL0_SSC_RANGE_4492PPM 0x1 +#define PHY_CTRL0_SSC_RANGE_4980PPM 0x0 #define PHY_CTRL1 0x4 #define PHY_CTRL1_RESET BIT(0) @@ -47,6 +51,7 @@ #define PHY_CTRL5_PCS_TX_SWING_FULL_MASK GENMASK(6, 0) #define PHY_CTRL6 0x18 +#define PHY_CTRL6_RXTERM_OVERRIDE_SEL BIT(29) #define PHY_CTRL6_ALT_CLK_EN BIT(1) #define PHY_CTRL6_ALT_CLK_SEL BIT(0) @@ -587,6 +592,9 @@ static int imx8mp_usb_phy_init(struct phy *phy) value = readl(imx_phy->base + PHY_CTRL0); value |= PHY_CTRL0_REF_SSP_EN; + value &= ~PHY_CTRL0_SSC_RANGE_MASK; + value |= FIELD_PREP(PHY_CTRL0_SSC_RANGE_MASK, + PHY_CTRL0_SSC_RANGE_4003PPM); writel(value, imx_phy->base + PHY_CTRL0); value = readl(imx_phy->base + PHY_CTRL2); @@ -610,6 +618,7 @@ static int imx8mp_usb_phy_init(struct phy *phy) static int imx8mq_phy_power_on(struct phy *phy) { struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); + u32 value; int ret; ret = regulator_enable(imx_phy->vbus); @@ -626,12 +635,23 @@ static int imx8mq_phy_power_on(struct phy *phy) return ret; } - return ret; + /* Disable rx term override */ + value = readl(imx_phy->base + PHY_CTRL6); + value &= ~PHY_CTRL6_RXTERM_OVERRIDE_SEL; + writel(value, imx_phy->base + PHY_CTRL6); + + return 0; } static int imx8mq_phy_power_off(struct phy *phy) { struct imx8mq_usb_phy *imx_phy = phy_get_drvdata(phy); + u32 value; + + /* Override rx term to be 0 */ + value = readl(imx_phy->base + PHY_CTRL6); + value |= PHY_CTRL6_RXTERM_OVERRIDE_SEL; + writel(value, imx_phy->base + PHY_CTRL6); clk_disable_unprepare(imx_phy->alt_clk); clk_disable_unprepare(imx_phy->clk); @@ -676,6 +696,8 @@ static int imx8mq_usb_phy_probe(struct platform_device *pdev) if (!imx_phy) return -ENOMEM; + platform_set_drvdata(pdev, imx_phy); + imx_phy->clk = devm_clk_get(dev, "phy"); if (IS_ERR(imx_phy->clk)) { dev_err(dev, "failed to get imx8mq usb phy clock\n"); @@ -730,6 +752,7 @@ static struct platform_driver imx8mq_usb_phy_driver = { .driver = { .name = "imx8mq-usb-phy", .of_match_table = imx8mq_usb_phy_of_match, + .suppress_bind_attrs = true, } }; module_platform_driver(imx8mq_usb_phy_driver); diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c index 977d21d753a5..279b8ac7822d 100644 --- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c @@ -251,7 +251,7 @@ static void imx_hsio_configure_clk_pad(struct phy *phy) struct imx_hsio_lane *lane = phy_get_drvdata(phy); struct imx_hsio_priv *priv = lane->priv; - if (strncmp(priv->refclk_pad, "output", 6) == 0) { + if (priv->refclk_pad && strncmp(priv->refclk_pad, "output", 6) == 0) { pll = true; regmap_update_bits(priv->misc, HSIO_CTRL0, HSIO_IOB_A_0_TXOE | HSIO_IOB_A_0_M1M0_MASK, diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c index 7aef2f59e8eb..ece357443521 100644 --- a/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c +++ b/drivers/phy/freescale/phy-fsl-imx8qm-lvds-phy.c @@ -286,11 +286,9 @@ static int mixel_lvds_phy_reset(struct device *dev) regmap_write(priv->regmap, PHY_CTRL, CTRL_RESET_VAL); - ret = pm_runtime_put(dev); - if (ret < 0) - dev_err(dev, "failed to put PM runtime: %d\n", ret); + pm_runtime_put(dev); - return ret; + return 0; } static struct phy *mixel_lvds_phy_xlate(struct device *dev, diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c index c20d2636c5e9..2b0fd95ba62f 100644 --- a/drivers/phy/freescale/phy-fsl-lynx-28g.c +++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* Copyright (c) 2021-2022 NXP. */ +#include #include #include #include @@ -11,100 +12,408 @@ #define LYNX_28G_NUM_LANE 8 #define LYNX_28G_NUM_PLL 2 -/* General registers per SerDes block */ -#define LYNX_28G_PCC8 0x10a0 -#define LYNX_28G_PCC8_SGMII 0x1 -#define LYNX_28G_PCC8_SGMII_DIS 0x0 +/* SoC IP wrapper for protocol converters */ +#define PCC8 0x10a0 +#define PCC8_SGMIIa_KX BIT(3) +#define PCC8_SGMIIa_CFG BIT(0) -#define LYNX_28G_PCCC 0x10b0 -#define LYNX_28G_PCCC_10GBASER 0x9 -#define LYNX_28G_PCCC_USXGMII 0x1 -#define LYNX_28G_PCCC_SXGMII_DIS 0x0 +#define PCCC 0x10b0 +#define PCCC_SXGMIIn_XFI BIT(3) +#define PCCC_SXGMIIn_CFG BIT(0) -#define LYNX_28G_LNa_PCC_OFFSET(lane) (4 * (LYNX_28G_NUM_LANE - (lane->id) - 1)) +#define PCCD 0x10b4 +#define PCCD_E25Gn_CFG BIT(0) + +#define PCCE 0x10b8 +#define PCCE_E40Gn_LRV BIT(3) +#define PCCE_E40Gn_CFG BIT(0) +#define PCCE_E50Gn_LRV BIT(3) +#define PCCE_E50GnCFG BIT(0) +#define PCCE_E100Gn_LRV BIT(3) +#define PCCE_E100Gn_CFG BIT(0) + +#define SGMII_CFG(id) (28 - (id) * 4) /* Offset into PCC8 */ +#define SXGMII_CFG(id) (28 - (id) * 4) /* Offset into PCCC */ +#define E25G_CFG(id) (28 - (id) * 4) /* Offset into PCCD */ +#define E40G_CFG(id) (28 - (id) * 4) /* Offset into PCCE */ +#define E50G_CFG(id) (20 - (id) * 4) /* Offset into PCCE */ +#define E100G_CFG(id) (12 - (id) * 4) /* Offset into PCCE */ /* Per PLL registers */ -#define LYNX_28G_PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0) -#define LYNX_28G_PLLnRSTCTL_DIS(rstctl) (((rstctl) & BIT(24)) >> 24) -#define LYNX_28G_PLLnRSTCTL_LOCK(rstctl) (((rstctl) & BIT(23)) >> 23) +#define PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0) +#define PLLnRSTCTL_DIS(rstctl) (((rstctl) & BIT(24)) >> 24) +#define PLLnRSTCTL_LOCK(rstctl) (((rstctl) & BIT(23)) >> 23) -#define LYNX_28G_PLLnCR0(pll) (0x400 + (pll) * 0x100 + 0x4) -#define LYNX_28G_PLLnCR0_REFCLK_SEL(cr0) (((cr0) & GENMASK(20, 16))) -#define LYNX_28G_PLLnCR0_REFCLK_SEL_100MHZ 0x0 -#define LYNX_28G_PLLnCR0_REFCLK_SEL_125MHZ 0x10000 -#define LYNX_28G_PLLnCR0_REFCLK_SEL_156MHZ 0x20000 -#define LYNX_28G_PLLnCR0_REFCLK_SEL_150MHZ 0x30000 -#define LYNX_28G_PLLnCR0_REFCLK_SEL_161MHZ 0x40000 +#define PLLnCR0(pll) (0x400 + (pll) * 0x100 + 0x4) +#define PLLnCR0_REFCLK_SEL GENMASK(20, 16) +#define PLLnCR0_REFCLK_SEL_100MHZ 0x0 +#define PLLnCR0_REFCLK_SEL_125MHZ 0x1 +#define PLLnCR0_REFCLK_SEL_156MHZ 0x2 +#define PLLnCR0_REFCLK_SEL_150MHZ 0x3 +#define PLLnCR0_REFCLK_SEL_161MHZ 0x4 -#define LYNX_28G_PLLnCR1(pll) (0x400 + (pll) * 0x100 + 0x8) -#define LYNX_28G_PLLnCR1_FRATE_SEL(cr1) (((cr1) & GENMASK(28, 24))) -#define LYNX_28G_PLLnCR1_FRATE_5G_10GVCO 0x0 -#define LYNX_28G_PLLnCR1_FRATE_5G_25GVCO 0x10000000 -#define LYNX_28G_PLLnCR1_FRATE_10G_20GVCO 0x6000000 +#define PLLnCR1(pll) (0x400 + (pll) * 0x100 + 0x8) +#define PLLnCR1_FRATE_SEL GENMASK(28, 24) +#define PLLnCR1_FRATE_5G_10GVCO 0x0 +#define PLLnCR1_FRATE_5G_25GVCO 0x10 +#define PLLnCR1_FRATE_10G_20GVCO 0x6 /* Per SerDes lane registers */ /* Lane a General Control Register */ -#define LYNX_28G_LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0) -#define LYNX_28G_LNaGCR0_PROTO_SEL_MSK GENMASK(7, 3) -#define LYNX_28G_LNaGCR0_PROTO_SEL_SGMII 0x8 -#define LYNX_28G_LNaGCR0_PROTO_SEL_XFI 0x50 -#define LYNX_28G_LNaGCR0_IF_WIDTH_MSK GENMASK(2, 0) -#define LYNX_28G_LNaGCR0_IF_WIDTH_10_BIT 0x0 -#define LYNX_28G_LNaGCR0_IF_WIDTH_20_BIT 0x2 +#define LNaGCR0(lane) (0x800 + (lane) * 0x100 + 0x0) +#define LNaGCR0_PROTO_SEL GENMASK(7, 3) +#define LNaGCR0_PROTO_SEL_SGMII 0x1 +#define LNaGCR0_PROTO_SEL_XFI 0xa +#define LNaGCR0_IF_WIDTH GENMASK(2, 0) +#define LNaGCR0_IF_WIDTH_10_BIT 0x0 +#define LNaGCR0_IF_WIDTH_20_BIT 0x2 /* Lane a Tx Reset Control Register */ -#define LYNX_28G_LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20) -#define LYNX_28G_LNaTRSTCTL_HLT_REQ BIT(27) -#define LYNX_28G_LNaTRSTCTL_RST_DONE BIT(30) -#define LYNX_28G_LNaTRSTCTL_RST_REQ BIT(31) +#define LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20) +#define LNaTRSTCTL_HLT_REQ BIT(27) +#define LNaTRSTCTL_RST_DONE BIT(30) +#define LNaTRSTCTL_RST_REQ BIT(31) /* Lane a Tx General Control Register */ -#define LYNX_28G_LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24) -#define LYNX_28G_LNaTGCR0_USE_PLLF 0x0 -#define LYNX_28G_LNaTGCR0_USE_PLLS BIT(28) -#define LYNX_28G_LNaTGCR0_USE_PLL_MSK BIT(28) -#define LYNX_28G_LNaTGCR0_N_RATE_FULL 0x0 -#define LYNX_28G_LNaTGCR0_N_RATE_HALF 0x1000000 -#define LYNX_28G_LNaTGCR0_N_RATE_QUARTER 0x2000000 -#define LYNX_28G_LNaTGCR0_N_RATE_MSK GENMASK(26, 24) +#define LNaTGCR0(lane) (0x800 + (lane) * 0x100 + 0x24) +#define LNaTGCR0_USE_PLL BIT(28) +#define LNaTGCR0_USE_PLLF 0x0 +#define LNaTGCR0_USE_PLLS 0x1 +#define LNaTGCR0_N_RATE GENMASK(26, 24) +#define LNaTGCR0_N_RATE_FULL 0x0 +#define LNaTGCR0_N_RATE_HALF 0x1 +#define LNaTGCR0_N_RATE_QUARTER 0x2 -#define LYNX_28G_LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30) +#define LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30) +#define LNaTECR0_EQ_TYPE GENMASK(30, 28) +#define LNaTECR0_EQ_SGN_PREQ BIT(23) +#define LNaTECR0_EQ_PREQ GENMASK(19, 16) +#define LNaTECR0_EQ_SGN_POST1Q BIT(15) +#define LNaTECR0_EQ_POST1Q GENMASK(12, 8) +#define LNaTECR0_EQ_AMP_RED GENMASK(5, 0) + +#define LNaTECR1(lane) (0x800 + (lane) * 0x100 + 0x34) +#define LNaTECR1_EQ_ADPT_EQ_DRVR_DIS BIT(31) +#define LNaTECR1_EQ_ADPT_EQ GENMASK(29, 24) /* Lane a Rx Reset Control Register */ -#define LYNX_28G_LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40) -#define LYNX_28G_LNaRRSTCTL_HLT_REQ BIT(27) -#define LYNX_28G_LNaRRSTCTL_RST_DONE BIT(30) -#define LYNX_28G_LNaRRSTCTL_RST_REQ BIT(31) -#define LYNX_28G_LNaRRSTCTL_CDR_LOCK BIT(12) +#define LNaRRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x40) +#define LNaRRSTCTL_HLT_REQ BIT(27) +#define LNaRRSTCTL_RST_DONE BIT(30) +#define LNaRRSTCTL_RST_REQ BIT(31) +#define LNaRRSTCTL_CDR_LOCK BIT(12) /* Lane a Rx General Control Register */ -#define LYNX_28G_LNaRGCR0(lane) (0x800 + (lane) * 0x100 + 0x44) -#define LYNX_28G_LNaRGCR0_USE_PLLF 0x0 -#define LYNX_28G_LNaRGCR0_USE_PLLS BIT(28) -#define LYNX_28G_LNaRGCR0_USE_PLL_MSK BIT(28) -#define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) -#define LYNX_28G_LNaRGCR0_N_RATE_FULL 0x0 -#define LYNX_28G_LNaRGCR0_N_RATE_HALF 0x1000000 -#define LYNX_28G_LNaRGCR0_N_RATE_QUARTER 0x2000000 -#define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24) +#define LNaRGCR0(lane) (0x800 + (lane) * 0x100 + 0x44) +#define LNaRGCR0_USE_PLL BIT(28) +#define LNaRGCR0_USE_PLLF 0x0 +#define LNaRGCR0_USE_PLLS 0x1 +#define LNaRGCR0_N_RATE GENMASK(26, 24) +#define LNaRGCR0_N_RATE_FULL 0x0 +#define LNaRGCR0_N_RATE_HALF 0x1 +#define LNaRGCR0_N_RATE_QUARTER 0x2 -#define LYNX_28G_LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48) +#define LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48) +#define LNaRGCR1_RX_ORD_ELECIDLE BIT(31) +#define LNaRGCR1_DATA_LOST_FLT BIT(30) +#define LNaRGCR1_DATA_LOST BIT(29) +#define LNaRGCR1_IDLE_CONFIG BIT(28) +#define LNaRGCR1_ENTER_IDLE_FLT_SEL GENMASK(26, 24) +#define LNaRGCR1_EXIT_IDLE_FLT_SEL GENMASK(22, 20) +#define LNaRGCR1_DATA_LOST_TH_SEL GENMASK(18, 16) +#define LNaRGCR1_EXT_REC_CLK_SEL GENMASK(10, 8) +#define LNaRGCR1_WAKE_TX_DIS BIT(5) +#define LNaRGCR1_PHY_RDY BIT(4) +#define LNaRGCR1_CHANGE_RX_CLK BIT(3) +#define LNaRGCR1_PWR_MGT GENMASK(2, 0) -#define LYNX_28G_LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50) -#define LYNX_28G_LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54) -#define LYNX_28G_LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58) +#define LNaRECR0(lane) (0x800 + (lane) * 0x100 + 0x50) +#define LNaRECR0_EQ_GAINK2_HF_OV_EN BIT(31) +#define LNaRECR0_EQ_GAINK2_HF_OV GENMASK(28, 24) +#define LNaRECR0_EQ_GAINK3_MF_OV_EN BIT(23) +#define LNaRECR0_EQ_GAINK3_MF_OV GENMASK(20, 16) +#define LNaRECR0_EQ_GAINK4_LF_OV_EN BIT(7) +#define LNaRECR0_EQ_GAINK4_LF_DIS BIT(6) +#define LNaRECR0_EQ_GAINK4_LF_OV GENMASK(4, 0) -#define LYNX_28G_LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74) +#define LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54) +#define LNaRECR1_EQ_BLW_OV_EN BIT(31) +#define LNaRECR1_EQ_BLW_OV GENMASK(28, 24) +#define LNaRECR1_EQ_OFFSET_OV_EN BIT(23) +#define LNaRECR1_EQ_OFFSET_OV GENMASK(21, 16) -#define LYNX_28G_LNaPSS(lane) (0x1000 + (lane) * 0x4) -#define LYNX_28G_LNaPSS_TYPE(pss) (((pss) & GENMASK(30, 24)) >> 24) -#define LYNX_28G_LNaPSS_TYPE_SGMII 0x4 -#define LYNX_28G_LNaPSS_TYPE_XFI 0x28 +#define LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58) +#define LNaRECR2_EQ_OFFSET_RNG_DBL BIT(31) +#define LNaRECR2_EQ_BOOST GENMASK(29, 28) +#define LNaRECR2_EQ_BLW_SEL GENMASK(25, 24) +#define LNaRECR2_EQ_ZERO GENMASK(17, 16) +#define LNaRECR2_EQ_IND GENMASK(13, 12) +#define LNaRECR2_EQ_BIN_DATA_AVG_TC GENMASK(5, 4) +#define LNaRECR2_SPARE_IN GENMASK(1, 0) -#define LYNX_28G_SGMIIaCR1(lane) (0x1804 + (lane) * 0x10) -#define LYNX_28G_SGMIIaCR1_SGPCS_EN BIT(11) -#define LYNX_28G_SGMIIaCR1_SGPCS_DIS 0x0 -#define LYNX_28G_SGMIIaCR1_SGPCS_MSK BIT(11) +#define LNaRECR3(lane) (0x800 + (lane) * 0x100 + 0x5c) +#define LNaRECR3_EQ_SNAP_START BIT(31) +#define LNaRECR3_EQ_SNAP_DONE BIT(30) +#define LNaRECR3_EQ_GAINK2_HF_STAT GENMASK(28, 24) +#define LNaRECR3_EQ_GAINK3_MF_STAT GENMASK(20, 16) +#define LNaRECR3_SPARE_OUT GENMASK(13, 12) +#define LNaRECR3_EQ_GAINK4_LF_STAT GENMASK(4, 0) + +#define LNaRECR4(lane) (0x800 + (lane) * 0x100 + 0x60) +#define LNaRECR4_BLW_STAT GENMASK(28, 24) +#define LNaRECR4_EQ_OFFSET_STAT GENMASK(21, 16) +#define LNaRECR4_EQ_BIN_DATA_SEL GENMASK(15, 12) +#define LNaRECR4_EQ_BIN_DATA GENMASK(8, 0) /* bit 9 is reserved */ +#define LNaRECR4_EQ_BIN_DATA_SGN BIT(8) + +#define LNaRCCR0(lane) (0x800 + (lane) * 0x100 + 0x68) +#define LNaRCCR0_CAL_EN BIT(31) +#define LNaRCCR0_MEAS_EN BIT(30) +#define LNaRCCR0_CAL_BIN_SEL BIT(28) +#define LNaRCCR0_CAL_DC3_DIS BIT(27) +#define LNaRCCR0_CAL_DC2_DIS BIT(26) +#define LNaRCCR0_CAL_DC1_DIS BIT(25) +#define LNaRCCR0_CAL_DC0_DIS BIT(24) +#define LNaRCCR0_CAL_AC3_OV_EN BIT(15) +#define LNaRCCR0_CAL_AC3_OV GENMASK(11, 8) +#define LNaRCCR0_CAL_AC2_OV_EN BIT(7) + +#define LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74) +#define LNaRSCCR0_SMP_OFF_EN BIT(31) +#define LNaRSCCR0_SMP_OFF_OV_EN BIT(30) +#define LNaRSCCR0_SMP_MAN_OFF_EN BIT(29) +#define LNaRSCCR0_SMP_OFF_RNG_OV_EN BIT(27) +#define LNaRSCCR0_SMP_OFF_RNG_4X_OV BIT(25) +#define LNaRSCCR0_SMP_OFF_RNG_2X_OV BIT(24) +#define LNaRSCCR0_SMP_AUTOZ_PD BIT(23) +#define LNaRSCCR0_SMP_AUTOZ_CTRL GENMASK(19, 16) +#define LNaRSCCR0_SMP_AUTOZ_D1R GENMASK(13, 12) +#define LNaRSCCR0_SMP_AUTOZ_D1F GENMASK(9, 8) +#define LNaRSCCR0_SMP_AUTOZ_EG1R GENMASK(5, 4) +#define LNaRSCCR0_SMP_AUTOZ_EG1F GENMASK(1, 0) + +#define LNaTTLCR0(lane) (0x800 + (lane) * 0x100 + 0x80) +#define LNaTTLCR0_TTL_FLT_SEL GENMASK(29, 24) +#define LNaTTLCR0_TTL_SLO_PM_BYP BIT(22) +#define LNaTTLCR0_STALL_DET_DIS BIT(21) +#define LNaTTLCR0_INACT_MON_DIS BIT(20) +#define LNaTTLCR0_CDR_OV GENMASK(18, 16) +#define LNaTTLCR0_DATA_IN_SSC BIT(15) +#define LNaTTLCR0_CDR_MIN_SMP_ON GENMASK(1, 0) + +#define LNaTCSR0(lane) (0x800 + (lane) * 0x100 + 0xa0) +#define LNaTCSR0_SD_STAT_OBS_EN BIT(31) +#define LNaTCSR0_SD_LPBK_SEL GENMASK(29, 28) + +#define LNaPSS(lane) (0x1000 + (lane) * 0x4) +#define LNaPSS_TYPE GENMASK(30, 24) +#define LNaPSS_TYPE_SGMII (PROTO_SEL_SGMII_BASEX_KX << 2) +#define LNaPSS_TYPE_XFI (PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2) +#define LNaPSS_TYPE_40G ((PROTO_SEL_XFI_10GBASER_KR_SXGMII << 2) | 3) +#define LNaPSS_TYPE_25G (PROTO_SEL_25G_50G_100G << 2) +#define LNaPSS_TYPE_100G ((PROTO_SEL_25G_50G_100G << 2) | 2) + +/* MDEV_PORT is at the same bitfield address for all protocol converters */ +#define MDEV_PORT GENMASK(31, 27) + +#define SGMIIaCR0(lane) (0x1800 + (lane) * 0x10) +#define SGMIIaCR1(lane) (0x1804 + (lane) * 0x10) +#define SGMIIaCR1_SGPCS_EN BIT(11) + +#define ANLTaCR0(lane) (0x1a00 + (lane) * 0x10) +#define ANLTaCR1(lane) (0x1a04 + (lane) * 0x10) + +#define SXGMIIaCR0(lane) (0x1a80 + (lane) * 0x10) +#define SXGMIIaCR0_RST BIT(31) +#define SXGMIIaCR0_PD BIT(30) + +#define SXGMIIaCR1(lane) (0x1a84 + (lane) * 0x10) + +#define E25GaCR0(lane) (0x1b00 + (lane) * 0x10) +#define E25GaCR0_RST BIT(31) +#define E25GaCR0_PD BIT(30) + +#define E25GaCR1(lane) (0x1b04 + (lane) * 0x10) + +#define E25GaCR2(lane) (0x1b08 + (lane) * 0x10) +#define E25GaCR2_FEC_ENA BIT(23) +#define E25GaCR2_FEC_ERR_ENA BIT(22) +#define E25GaCR2_FEC91_ENA BIT(20) + +#define E40GaCR0(pcvt) (0x1b40 + (pcvt) * 0x20) +#define E40GaCR1(pcvt) (0x1b44 + (pcvt) * 0x20) + +#define E50GaCR1(pcvt) (0x1b84 + (pcvt) * 0x10) + +#define E100GaCR1(pcvt) (0x1c04 + (pcvt) * 0x20) + +#define CR(x) ((x) * 4) + +enum lynx_28g_eq_type { + EQ_TYPE_NO_EQ = 0, + EQ_TYPE_2TAP = 1, + EQ_TYPE_3TAP = 2, +}; + +enum lynx_28g_proto_sel { + PROTO_SEL_PCIE = 0, + PROTO_SEL_SGMII_BASEX_KX = 1, + PROTO_SEL_SATA = 2, + PROTO_SEL_XAUI = 4, + PROTO_SEL_XFI_10GBASER_KR_SXGMII = 0xa, + PROTO_SEL_25G_50G_100G = 0x1a, +}; + +enum lynx_lane_mode { + LANE_MODE_UNKNOWN, + LANE_MODE_1000BASEX_SGMII, + LANE_MODE_10GBASER, + LANE_MODE_USXGMII, + LANE_MODE_MAX, +}; + +struct lynx_28g_proto_conf { + /* LNaGCR0 */ + int proto_sel; + int if_width; + /* LNaTECR0 */ + int teq_type; + int sgn_preq; + int ratio_preq; + int sgn_post1q; + int ratio_post1q; + int amp_red; + /* LNaTECR1 */ + int adpt_eq; + /* LNaRGCR1 */ + int enter_idle_flt_sel; + int exit_idle_flt_sel; + int data_lost_th_sel; + /* LNaRECR0 */ + int gk2ovd; + int gk3ovd; + int gk4ovd; + int gk2ovd_en; + int gk3ovd_en; + int gk4ovd_en; + /* LNaRECR1 ? */ + int eq_offset_ovd; + int eq_offset_ovd_en; + /* LNaRECR2 */ + int eq_offset_rng_dbl; + int eq_blw_sel; + int eq_boost; + int spare_in; + /* LNaRSCCR0 */ + int smp_autoz_d1r; + int smp_autoz_eg1r; + /* LNaRCCR0 */ + int rccr0; + /* LNaTTLCR0 */ + int ttlcr0; +}; + +static const struct lynx_28g_proto_conf lynx_28g_proto_conf[LANE_MODE_MAX] = { + [LANE_MODE_1000BASEX_SGMII] = { + .proto_sel = LNaGCR0_PROTO_SEL_SGMII, + .if_width = LNaGCR0_IF_WIDTH_10_BIT, + .teq_type = EQ_TYPE_NO_EQ, + .sgn_preq = 1, + .ratio_preq = 0, + .sgn_post1q = 1, + .ratio_post1q = 0, + .amp_red = 6, + .adpt_eq = 48, + .enter_idle_flt_sel = 4, + .exit_idle_flt_sel = 3, + .data_lost_th_sel = 1, + .gk2ovd = 0x1f, + .gk3ovd = 0, + .gk4ovd = 0, + .gk2ovd_en = 1, + .gk3ovd_en = 1, + .gk4ovd_en = 0, + .eq_offset_ovd = 0x1f, + .eq_offset_ovd_en = 0, + .eq_offset_rng_dbl = 0, + .eq_blw_sel = 0, + .eq_boost = 0, + .spare_in = 0, + .smp_autoz_d1r = 0, + .smp_autoz_eg1r = 0, + .rccr0 = LNaRCCR0_CAL_EN, + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | + LNaTTLCR0_DATA_IN_SSC, + }, + [LANE_MODE_USXGMII] = { + .proto_sel = LNaGCR0_PROTO_SEL_XFI, + .if_width = LNaGCR0_IF_WIDTH_20_BIT, + .teq_type = EQ_TYPE_2TAP, + .sgn_preq = 1, + .ratio_preq = 0, + .sgn_post1q = 1, + .ratio_post1q = 3, + .amp_red = 7, + .adpt_eq = 48, + .enter_idle_flt_sel = 0, + .exit_idle_flt_sel = 0, + .data_lost_th_sel = 0, + .gk2ovd = 0, + .gk3ovd = 0, + .gk4ovd = 0, + .gk2ovd_en = 0, + .gk3ovd_en = 0, + .gk4ovd_en = 0, + .eq_offset_ovd = 0x1f, + .eq_offset_ovd_en = 0, + .eq_offset_rng_dbl = 1, + .eq_blw_sel = 1, + .eq_boost = 0, + .spare_in = 0, + .smp_autoz_d1r = 2, + .smp_autoz_eg1r = 0, + .rccr0 = LNaRCCR0_CAL_EN, + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | + LNaTTLCR0_DATA_IN_SSC, + }, + [LANE_MODE_10GBASER] = { + .proto_sel = LNaGCR0_PROTO_SEL_XFI, + .if_width = LNaGCR0_IF_WIDTH_20_BIT, + .teq_type = EQ_TYPE_2TAP, + .sgn_preq = 1, + .ratio_preq = 0, + .sgn_post1q = 1, + .ratio_post1q = 3, + .amp_red = 7, + .adpt_eq = 48, + .enter_idle_flt_sel = 0, + .exit_idle_flt_sel = 0, + .data_lost_th_sel = 0, + .gk2ovd = 0, + .gk3ovd = 0, + .gk4ovd = 0, + .gk2ovd_en = 0, + .gk3ovd_en = 0, + .gk4ovd_en = 0, + .eq_offset_ovd = 0x1f, + .eq_offset_ovd_en = 0, + .eq_offset_rng_dbl = 1, + .eq_blw_sel = 1, + .eq_boost = 0, + .spare_in = 0, + .smp_autoz_d1r = 2, + .smp_autoz_eg1r = 0, + .rccr0 = LNaRCCR0_CAL_EN, + .ttlcr0 = LNaTTLCR0_TTL_SLO_PM_BYP | + LNaTTLCR0_DATA_IN_SSC, + }, +}; + +struct lynx_pccr { + int offset; + int width; + int shift; +}; struct lynx_28g_priv; @@ -112,7 +421,7 @@ struct lynx_28g_pll { struct lynx_28g_priv *priv; u32 rstctl, cr0, cr1; int id; - DECLARE_PHY_INTERFACE_MASK(supported); + DECLARE_BITMAP(supported, LANE_MODE_MAX); }; struct lynx_28g_lane { @@ -121,7 +430,7 @@ struct lynx_28g_lane { bool powered_up; bool init; unsigned int id; - phy_interface_t interface; + enum lynx_lane_mode mode; }; struct lynx_28g_priv { @@ -149,23 +458,58 @@ static void lynx_28g_rmw(struct lynx_28g_priv *priv, unsigned long off, iowrite32(tmp, reg); } +#define lynx_28g_read(priv, off) \ + ioread32((priv)->base + (off)) +#define lynx_28g_write(priv, off, val) \ + iowrite32(val, (priv)->base + (off)) #define lynx_28g_lane_rmw(lane, reg, val, mask) \ - lynx_28g_rmw((lane)->priv, LYNX_28G_##reg(lane->id), \ - LYNX_28G_##reg##_##val, LYNX_28G_##reg##_##mask) + lynx_28g_rmw((lane)->priv, reg(lane->id), val, mask) #define lynx_28g_lane_read(lane, reg) \ - ioread32((lane)->priv->base + LYNX_28G_##reg((lane)->id)) + ioread32((lane)->priv->base + reg((lane)->id)) +#define lynx_28g_lane_write(lane, reg, val) \ + iowrite32(val, (lane)->priv->base + reg((lane)->id)) #define lynx_28g_pll_read(pll, reg) \ - ioread32((pll)->priv->base + LYNX_28G_##reg((pll)->id)) + ioread32((pll)->priv->base + reg((pll)->id)) -static bool lynx_28g_supports_interface(struct lynx_28g_priv *priv, int intf) +static const char *lynx_lane_mode_str(enum lynx_lane_mode lane_mode) +{ + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + return "1000Base-X/SGMII"; + case LANE_MODE_10GBASER: + return "10GBase-R"; + case LANE_MODE_USXGMII: + return "USXGMII"; + default: + return "unknown"; + } +} + +static enum lynx_lane_mode phy_interface_to_lane_mode(phy_interface_t intf) +{ + switch (intf) { + case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_1000BASEX: + return LANE_MODE_1000BASEX_SGMII; + case PHY_INTERFACE_MODE_10GBASER: + return LANE_MODE_10GBASER; + case PHY_INTERFACE_MODE_USXGMII: + return LANE_MODE_USXGMII; + default: + return LANE_MODE_UNKNOWN; + } +} + +static bool lynx_28g_supports_lane_mode(struct lynx_28g_priv *priv, + enum lynx_lane_mode mode) { int i; for (i = 0; i < LYNX_28G_NUM_PLL; i++) { - if (LYNX_28G_PLLnRSTCTL_DIS(priv->pll[i].rstctl)) + if (PLLnRSTCTL_DIS(priv->pll[i].rstctl)) continue; - if (test_bit(intf, priv->pll[i].supported)) + if (test_bit(mode, priv->pll[i].supported)) return true; } @@ -173,7 +517,7 @@ static bool lynx_28g_supports_interface(struct lynx_28g_priv *priv, int intf) } static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, - phy_interface_t intf) + enum lynx_lane_mode mode) { struct lynx_28g_pll *pll; int i; @@ -181,43 +525,51 @@ static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv, for (i = 0; i < LYNX_28G_NUM_PLL; i++) { pll = &priv->pll[i]; - if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) + if (PLLnRSTCTL_DIS(pll->rstctl)) continue; - if (test_bit(intf, pll->supported)) + if (test_bit(mode, pll->supported)) return pll; } /* no pll supports requested mode, either caller forgot to check * lynx_28g_supports_lane_mode, or this is a bug. */ - dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf)); + dev_WARN_ONCE(priv->dev, 1, "no pll for lane mode %s\n", + lynx_lane_mode_str(mode)); return NULL; } static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane, struct lynx_28g_pll *pll, - phy_interface_t intf) + enum lynx_lane_mode lane_mode) { - switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { - case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: - case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: - switch (intf) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_QUARTER, N_RATE_MSK); - lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_QUARTER, N_RATE_MSK); + switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) { + case PLLnCR1_FRATE_5G_10GVCO: + case PLLnCR1_FRATE_5G_25GVCO: + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + lynx_28g_lane_rmw(lane, LNaTGCR0, + FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_QUARTER), + LNaTGCR0_N_RATE); + lynx_28g_lane_rmw(lane, LNaRGCR0, + FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_QUARTER), + LNaRGCR0_N_RATE); break; default: break; } break; - case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: - switch (intf) { - case PHY_INTERFACE_MODE_10GBASER: - case PHY_INTERFACE_MODE_USXGMII: - lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_FULL, N_RATE_MSK); - lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_FULL, N_RATE_MSK); + case PLLnCR1_FRATE_10G_20GVCO: + switch (lane_mode) { + case LANE_MODE_10GBASER: + case LANE_MODE_USXGMII: + lynx_28g_lane_rmw(lane, LNaTGCR0, + FIELD_PREP(LNaTGCR0_N_RATE, LNaTGCR0_N_RATE_FULL), + LNaTGCR0_N_RATE); + lynx_28g_lane_rmw(lane, LNaRGCR0, + FIELD_PREP(LNaRGCR0_N_RATE, LNaRGCR0_N_RATE_FULL), + LNaRGCR0_N_RATE); break; default: break; @@ -232,117 +584,22 @@ static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane, struct lynx_28g_pll *pll) { if (pll->id == 0) { - lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLF, USE_PLL_MSK); - lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLF, USE_PLL_MSK); + lynx_28g_lane_rmw(lane, LNaTGCR0, + FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLF), + LNaTGCR0_USE_PLL); + lynx_28g_lane_rmw(lane, LNaRGCR0, + FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLF), + LNaRGCR0_USE_PLL); } else { - lynx_28g_lane_rmw(lane, LNaTGCR0, USE_PLLS, USE_PLL_MSK); - lynx_28g_lane_rmw(lane, LNaRGCR0, USE_PLLS, USE_PLL_MSK); + lynx_28g_lane_rmw(lane, LNaTGCR0, + FIELD_PREP(LNaTGCR0_USE_PLL, LNaTGCR0_USE_PLLS), + LNaTGCR0_USE_PLL); + lynx_28g_lane_rmw(lane, LNaRGCR0, + FIELD_PREP(LNaRGCR0_USE_PLL, LNaRGCR0_USE_PLLS), + LNaRGCR0_USE_PLL); } } -static void lynx_28g_cleanup_lane(struct lynx_28g_lane *lane) -{ - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); - struct lynx_28g_priv *priv = lane->priv; - - /* Cleanup the protocol configuration registers of the current protocol */ - switch (lane->interface) { - case PHY_INTERFACE_MODE_10GBASER: - lynx_28g_rmw(priv, LYNX_28G_PCCC, - LYNX_28G_PCCC_SXGMII_DIS << lane_offset, - GENMASK(3, 0) << lane_offset); - break; - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - lynx_28g_rmw(priv, LYNX_28G_PCC8, - LYNX_28G_PCC8_SGMII_DIS << lane_offset, - GENMASK(3, 0) << lane_offset); - break; - default: - break; - } -} - -static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane) -{ - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); - struct lynx_28g_priv *priv = lane->priv; - struct lynx_28g_pll *pll; - - lynx_28g_cleanup_lane(lane); - - /* Setup the lane to run in SGMII */ - lynx_28g_rmw(priv, LYNX_28G_PCC8, - LYNX_28G_PCC8_SGMII << lane_offset, - GENMASK(3, 0) << lane_offset); - - /* Setup the protocol select and SerDes parallel interface width */ - lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK); - lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK); - - /* Find the PLL that works with this interface type */ - pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII); - if (unlikely(pll == NULL)) - return; - - /* Switch to the PLL that works with this interface type */ - lynx_28g_lane_set_pll(lane, pll); - - /* Choose the portion of clock net to be used on this lane */ - lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_SGMII); - - /* Enable the SGMII PCS */ - lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_EN, SGPCS_MSK); - - /* Configure the appropriate equalization parameters for the protocol */ - iowrite32(0x00808006, priv->base + LYNX_28G_LNaTECR0(lane->id)); - iowrite32(0x04310000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); - iowrite32(0x9f800000, priv->base + LYNX_28G_LNaRECR0(lane->id)); - iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR2(lane->id)); - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); -} - -static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane) -{ - u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane); - struct lynx_28g_priv *priv = lane->priv; - struct lynx_28g_pll *pll; - - lynx_28g_cleanup_lane(lane); - - /* Enable the SXGMII lane */ - lynx_28g_rmw(priv, LYNX_28G_PCCC, - LYNX_28G_PCCC_10GBASER << lane_offset, - GENMASK(3, 0) << lane_offset); - - /* Setup the protocol select and SerDes parallel interface width */ - lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK); - lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK); - - /* Find the PLL that works with this interface type */ - pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER); - if (unlikely(pll == NULL)) - return; - - /* Switch to the PLL that works with this interface type */ - lynx_28g_lane_set_pll(lane, pll); - - /* Choose the portion of clock net to be used on this lane */ - lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER); - - /* Disable the SGMII PCS */ - lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK); - - /* Configure the appropriate equalization parameters for the protocol */ - iowrite32(0x10808307, priv->base + LYNX_28G_LNaTECR0(lane->id)); - iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id)); - iowrite32(0x00000000, priv->base + LYNX_28G_LNaRECR0(lane->id)); - iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id)); - iowrite32(0x81000020, priv->base + LYNX_28G_LNaRECR2(lane->id)); - iowrite32(0x00002000, priv->base + LYNX_28G_LNaRSCCR0(lane->id)); -} - static int lynx_28g_power_off(struct phy *phy) { struct lynx_28g_lane *lane = phy_get_drvdata(phy); @@ -352,15 +609,17 @@ static int lynx_28g_power_off(struct phy *phy) return 0; /* Issue a halt request */ - lynx_28g_lane_rmw(lane, LNaTRSTCTL, HLT_REQ, HLT_REQ); - lynx_28g_lane_rmw(lane, LNaRRSTCTL, HLT_REQ, HLT_REQ); + lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_HLT_REQ, + LNaTRSTCTL_HLT_REQ); + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_HLT_REQ, + LNaRRSTCTL_HLT_REQ); /* Wait until the halting process is complete */ do { trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - } while ((trstctl & LYNX_28G_LNaTRSTCTL_HLT_REQ) || - (rrstctl & LYNX_28G_LNaRRSTCTL_HLT_REQ)); + } while ((trstctl & LNaTRSTCTL_HLT_REQ) || + (rrstctl & LNaRRSTCTL_HLT_REQ)); lane->powered_up = false; @@ -376,64 +635,345 @@ static int lynx_28g_power_on(struct phy *phy) return 0; /* Issue a reset request on the lane */ - lynx_28g_lane_rmw(lane, LNaTRSTCTL, RST_REQ, RST_REQ); - lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); + lynx_28g_lane_rmw(lane, LNaTRSTCTL, LNaTRSTCTL_RST_REQ, + LNaTRSTCTL_RST_REQ); + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ, + LNaRRSTCTL_RST_REQ); /* Wait until the reset sequence is completed */ do { trstctl = lynx_28g_lane_read(lane, LNaTRSTCTL); rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - } while (!(trstctl & LYNX_28G_LNaTRSTCTL_RST_DONE) || - !(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); + } while (!(trstctl & LNaTRSTCTL_RST_DONE) || + !(rrstctl & LNaRRSTCTL_RST_DONE)); lane->powered_up = true; return 0; } +static int lynx_28g_get_pccr(enum lynx_lane_mode lane_mode, int lane, + struct lynx_pccr *pccr) +{ + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + pccr->offset = PCC8; + pccr->width = 4; + pccr->shift = SGMII_CFG(lane); + break; + case LANE_MODE_USXGMII: + case LANE_MODE_10GBASER: + pccr->offset = PCCC; + pccr->width = 4; + pccr->shift = SXGMII_CFG(lane); + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int lynx_28g_get_pcvt_offset(int lane, enum lynx_lane_mode lane_mode) +{ + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + return SGMIIaCR0(lane); + case LANE_MODE_USXGMII: + case LANE_MODE_10GBASER: + return SXGMIIaCR0(lane); + default: + return -EOPNOTSUPP; + } +} + +static int lynx_pccr_read(struct lynx_28g_lane *lane, enum lynx_lane_mode mode, + u32 *val) +{ + struct lynx_28g_priv *priv = lane->priv; + struct lynx_pccr pccr; + u32 tmp; + int err; + + err = lynx_28g_get_pccr(mode, lane->id, &pccr); + if (err) + return err; + + tmp = lynx_28g_read(priv, pccr.offset); + *val = (tmp >> pccr.shift) & GENMASK(pccr.width - 1, 0); + + return 0; +} + +static int lynx_pccr_write(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode, u32 val) +{ + struct lynx_28g_priv *priv = lane->priv; + struct lynx_pccr pccr; + u32 old, tmp, mask; + int err; + + err = lynx_28g_get_pccr(lane_mode, lane->id, &pccr); + if (err) + return err; + + old = lynx_28g_read(priv, pccr.offset); + mask = GENMASK(pccr.width - 1, 0) << pccr.shift; + tmp = (old & ~mask) | (val << pccr.shift); + lynx_28g_write(priv, pccr.offset, tmp); + + dev_dbg(&lane->phy->dev, "PCCR@0x%x: 0x%x -> 0x%x\n", + pccr.offset, old, tmp); + + return 0; +} + +static int lynx_pcvt_read(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode, int cr, u32 *val) +{ + struct lynx_28g_priv *priv = lane->priv; + int offset; + + offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); + if (offset < 0) + return offset; + + *val = lynx_28g_read(priv, offset + cr); + + return 0; +} + +static int lynx_pcvt_write(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode, int cr, u32 val) +{ + struct lynx_28g_priv *priv = lane->priv; + int offset; + + offset = lynx_28g_get_pcvt_offset(lane->id, lane_mode); + if (offset < 0) + return offset; + + lynx_28g_write(priv, offset + cr, val); + + return 0; +} + +static int lynx_pcvt_rmw(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode, + int cr, u32 val, u32 mask) +{ + int err; + u32 tmp; + + err = lynx_pcvt_read(lane, lane_mode, cr, &tmp); + if (err) + return err; + + tmp &= ~mask; + tmp |= val; + + return lynx_pcvt_write(lane, lane_mode, cr, tmp); +} + +static void lynx_28g_lane_remap_pll(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode) +{ + struct lynx_28g_priv *priv = lane->priv; + struct lynx_28g_pll *pll; + + /* Switch to the PLL that works with this interface type */ + pll = lynx_28g_pll_get(priv, lane_mode); + if (unlikely(pll == NULL)) + return; + + lynx_28g_lane_set_pll(lane, pll); + + /* Choose the portion of clock net to be used on this lane */ + lynx_28g_lane_set_nrate(lane, pll, lane_mode); +} + +static void lynx_28g_lane_change_proto_conf(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode) +{ + const struct lynx_28g_proto_conf *conf = &lynx_28g_proto_conf[lane_mode]; + + lynx_28g_lane_rmw(lane, LNaGCR0, + FIELD_PREP(LNaGCR0_PROTO_SEL, conf->proto_sel) | + FIELD_PREP(LNaGCR0_IF_WIDTH, conf->if_width), + LNaGCR0_PROTO_SEL | LNaGCR0_IF_WIDTH); + + lynx_28g_lane_rmw(lane, LNaTECR0, + FIELD_PREP(LNaTECR0_EQ_TYPE, conf->teq_type) | + FIELD_PREP(LNaTECR0_EQ_SGN_PREQ, conf->sgn_preq) | + FIELD_PREP(LNaTECR0_EQ_PREQ, conf->ratio_preq) | + FIELD_PREP(LNaTECR0_EQ_SGN_POST1Q, conf->sgn_post1q) | + FIELD_PREP(LNaTECR0_EQ_POST1Q, conf->ratio_post1q) | + FIELD_PREP(LNaTECR0_EQ_AMP_RED, conf->amp_red), + LNaTECR0_EQ_TYPE | + LNaTECR0_EQ_SGN_PREQ | + LNaTECR0_EQ_PREQ | + LNaTECR0_EQ_SGN_POST1Q | + LNaTECR0_EQ_POST1Q | + LNaTECR0_EQ_AMP_RED); + + lynx_28g_lane_rmw(lane, LNaTECR1, + FIELD_PREP(LNaTECR1_EQ_ADPT_EQ, conf->adpt_eq), + LNaTECR1_EQ_ADPT_EQ); + + lynx_28g_lane_rmw(lane, LNaRGCR1, + FIELD_PREP(LNaRGCR1_ENTER_IDLE_FLT_SEL, conf->enter_idle_flt_sel) | + FIELD_PREP(LNaRGCR1_EXIT_IDLE_FLT_SEL, conf->exit_idle_flt_sel) | + FIELD_PREP(LNaRGCR1_DATA_LOST_TH_SEL, conf->data_lost_th_sel), + LNaRGCR1_ENTER_IDLE_FLT_SEL | + LNaRGCR1_EXIT_IDLE_FLT_SEL | + LNaRGCR1_DATA_LOST_TH_SEL); + + lynx_28g_lane_rmw(lane, LNaRECR0, + FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV_EN, conf->gk2ovd_en) | + FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV_EN, conf->gk3ovd_en) | + FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV_EN, conf->gk4ovd_en) | + FIELD_PREP(LNaRECR0_EQ_GAINK2_HF_OV, conf->gk2ovd) | + FIELD_PREP(LNaRECR0_EQ_GAINK3_MF_OV, conf->gk3ovd) | + FIELD_PREP(LNaRECR0_EQ_GAINK4_LF_OV, conf->gk4ovd), + LNaRECR0_EQ_GAINK2_HF_OV | + LNaRECR0_EQ_GAINK3_MF_OV | + LNaRECR0_EQ_GAINK4_LF_OV | + LNaRECR0_EQ_GAINK2_HF_OV_EN | + LNaRECR0_EQ_GAINK3_MF_OV_EN | + LNaRECR0_EQ_GAINK4_LF_OV_EN); + + lynx_28g_lane_rmw(lane, LNaRECR1, + FIELD_PREP(LNaRECR1_EQ_OFFSET_OV, conf->eq_offset_ovd) | + FIELD_PREP(LNaRECR1_EQ_OFFSET_OV_EN, conf->eq_offset_ovd_en), + LNaRECR1_EQ_OFFSET_OV | + LNaRECR1_EQ_OFFSET_OV_EN); + + lynx_28g_lane_rmw(lane, LNaRECR2, + FIELD_PREP(LNaRECR2_EQ_OFFSET_RNG_DBL, conf->eq_offset_rng_dbl) | + FIELD_PREP(LNaRECR2_EQ_BLW_SEL, conf->eq_blw_sel) | + FIELD_PREP(LNaRECR2_EQ_BOOST, conf->eq_boost) | + FIELD_PREP(LNaRECR2_SPARE_IN, conf->spare_in), + LNaRECR2_EQ_OFFSET_RNG_DBL | + LNaRECR2_EQ_BLW_SEL | + LNaRECR2_EQ_BOOST | + LNaRECR2_SPARE_IN); + + lynx_28g_lane_rmw(lane, LNaRSCCR0, + FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_D1R, conf->smp_autoz_d1r) | + FIELD_PREP(LNaRSCCR0_SMP_AUTOZ_EG1R, conf->smp_autoz_eg1r), + LNaRSCCR0_SMP_AUTOZ_D1R | + LNaRSCCR0_SMP_AUTOZ_EG1R); + + lynx_28g_lane_write(lane, LNaRCCR0, conf->rccr0); + lynx_28g_lane_write(lane, LNaTTLCR0, conf->ttlcr0); +} + +static int lynx_28g_lane_disable_pcvt(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode) +{ + struct lynx_28g_priv *priv = lane->priv; + int err; + + spin_lock(&priv->pcc_lock); + + err = lynx_pccr_write(lane, lane_mode, 0); + if (err) + goto out; + + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + err = lynx_pcvt_rmw(lane, lane_mode, CR(1), 0, + SGMIIaCR1_SGPCS_EN); + break; + default: + err = 0; + } + +out: + spin_unlock(&priv->pcc_lock); + + return err; +} + +static int lynx_28g_lane_enable_pcvt(struct lynx_28g_lane *lane, + enum lynx_lane_mode lane_mode) +{ + struct lynx_28g_priv *priv = lane->priv; + u32 val; + int err; + + spin_lock(&priv->pcc_lock); + + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + err = lynx_pcvt_rmw(lane, lane_mode, CR(1), SGMIIaCR1_SGPCS_EN, + SGMIIaCR1_SGPCS_EN); + break; + default: + err = 0; + } + + val = 0; + + switch (lane_mode) { + case LANE_MODE_1000BASEX_SGMII: + val |= PCC8_SGMIIa_CFG; + break; + case LANE_MODE_10GBASER: + val |= PCCC_SXGMIIn_XFI; + fallthrough; + case LANE_MODE_USXGMII: + val |= PCCC_SXGMIIn_CFG; + break; + default: + break; + } + + err = lynx_pccr_write(lane, lane_mode, val); + + spin_unlock(&priv->pcc_lock); + + return err; +} + static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode) { struct lynx_28g_lane *lane = phy_get_drvdata(phy); struct lynx_28g_priv *priv = lane->priv; int powered_up = lane->powered_up; + enum lynx_lane_mode lane_mode; int err = 0; if (mode != PHY_MODE_ETHERNET) return -EOPNOTSUPP; - if (lane->interface == PHY_INTERFACE_MODE_NA) + if (lane->mode == LANE_MODE_UNKNOWN) return -EOPNOTSUPP; - if (!lynx_28g_supports_interface(priv, submode)) + lane_mode = phy_interface_to_lane_mode(submode); + if (!lynx_28g_supports_lane_mode(priv, lane_mode)) return -EOPNOTSUPP; + if (lane_mode == lane->mode) + return 0; + /* If the lane is powered up, put the lane into the halt state while * the reconfiguration is being done. */ if (powered_up) lynx_28g_power_off(phy); - spin_lock(&priv->pcc_lock); - - switch (submode) { - case PHY_INTERFACE_MODE_SGMII: - case PHY_INTERFACE_MODE_1000BASEX: - lynx_28g_lane_set_sgmii(lane); - break; - case PHY_INTERFACE_MODE_10GBASER: - lynx_28g_lane_set_10gbaser(lane); - break; - default: - err = -EOPNOTSUPP; + err = lynx_28g_lane_disable_pcvt(lane, lane->mode); + if (err) goto out; - } - lane->interface = submode; + lynx_28g_lane_change_proto_conf(lane, lane_mode); + lynx_28g_lane_remap_pll(lane, lane_mode); + WARN_ON(lynx_28g_lane_enable_pcvt(lane, lane_mode)); + + lane->mode = lane_mode; out: - spin_unlock(&priv->pcc_lock); - - /* Power up the lane if necessary */ if (powered_up) lynx_28g_power_on(phy); @@ -445,11 +985,13 @@ static int lynx_28g_validate(struct phy *phy, enum phy_mode mode, int submode, { struct lynx_28g_lane *lane = phy_get_drvdata(phy); struct lynx_28g_priv *priv = lane->priv; + enum lynx_lane_mode lane_mode; if (mode != PHY_MODE_ETHERNET) return -EOPNOTSUPP; - if (!lynx_28g_supports_interface(priv, submode)) + lane_mode = phy_interface_to_lane_mode(submode); + if (!lynx_28g_supports_lane_mode(priv, lane_mode)) return -EOPNOTSUPP; return 0; @@ -495,19 +1037,19 @@ static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv) pll->cr0 = lynx_28g_pll_read(pll, PLLnCR0); pll->cr1 = lynx_28g_pll_read(pll, PLLnCR1); - if (LYNX_28G_PLLnRSTCTL_DIS(pll->rstctl)) + if (PLLnRSTCTL_DIS(pll->rstctl)) continue; - switch (LYNX_28G_PLLnCR1_FRATE_SEL(pll->cr1)) { - case LYNX_28G_PLLnCR1_FRATE_5G_10GVCO: - case LYNX_28G_PLLnCR1_FRATE_5G_25GVCO: + switch (FIELD_GET(PLLnCR1_FRATE_SEL, pll->cr1)) { + case PLLnCR1_FRATE_5G_10GVCO: + case PLLnCR1_FRATE_5G_25GVCO: /* 5GHz clock net */ - __set_bit(PHY_INTERFACE_MODE_1000BASEX, pll->supported); - __set_bit(PHY_INTERFACE_MODE_SGMII, pll->supported); + __set_bit(LANE_MODE_1000BASEX_SGMII, pll->supported); break; - case LYNX_28G_PLLnCR1_FRATE_10G_20GVCO: + case PLLnCR1_FRATE_10G_20GVCO: /* 10.3125GHz clock net */ - __set_bit(PHY_INTERFACE_MODE_10GBASER, pll->supported); + __set_bit(LANE_MODE_10GBASER, pll->supported); + __set_bit(LANE_MODE_USXGMII, pll->supported); break; default: /* 6GHz, 12.890625GHz, 8GHz */ @@ -536,11 +1078,12 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work) } rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - if (!(rrstctl & LYNX_28G_LNaRRSTCTL_CDR_LOCK)) { - lynx_28g_lane_rmw(lane, LNaRRSTCTL, RST_REQ, RST_REQ); + if (!(rrstctl & LNaRRSTCTL_CDR_LOCK)) { + lynx_28g_lane_rmw(lane, LNaRRSTCTL, LNaRRSTCTL_RST_REQ, + LNaRRSTCTL_RST_REQ); do { rrstctl = lynx_28g_lane_read(lane, LNaRRSTCTL); - } while (!(rrstctl & LYNX_28G_LNaRRSTCTL_RST_DONE)); + } while (!(rrstctl & LNaRRSTCTL_RST_DONE)); } mutex_unlock(&lane->phy->mutex); @@ -551,19 +1094,23 @@ static void lynx_28g_cdr_lock_check(struct work_struct *work) static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane) { - u32 pss, protocol; + u32 pccr, pss, protocol; pss = lynx_28g_lane_read(lane, LNaPSS); - protocol = LYNX_28G_LNaPSS_TYPE(pss); + protocol = FIELD_GET(LNaPSS_TYPE, pss); switch (protocol) { - case LYNX_28G_LNaPSS_TYPE_SGMII: - lane->interface = PHY_INTERFACE_MODE_SGMII; + case LNaPSS_TYPE_SGMII: + lane->mode = LANE_MODE_1000BASEX_SGMII; break; - case LYNX_28G_LNaPSS_TYPE_XFI: - lane->interface = PHY_INTERFACE_MODE_10GBASER; + case LNaPSS_TYPE_XFI: + lynx_pccr_read(lane, LANE_MODE_10GBASER, &pccr); + if (pccr & PCCC_SXGMIIn_XFI) + lane->mode = LANE_MODE_10GBASER; + else + lane->mode = LANE_MODE_USXGMII; break; default: - lane->interface = PHY_INTERFACE_MODE_NA; + lane->mode = LANE_MODE_UNKNOWN; } } @@ -571,7 +1118,14 @@ static struct phy *lynx_28g_xlate(struct device *dev, const struct of_phandle_args *args) { struct lynx_28g_priv *priv = dev_get_drvdata(dev); - int idx = args->args[0]; + int idx; + + if (args->args_count == 0) + return of_phy_simple_xlate(dev, args); + else if (args->args_count != 1) + return ERR_PTR(-ENODEV); + + idx = args->args[0]; if (WARN_ON(idx >= LYNX_28G_NUM_LANE)) return ERR_PTR(-EINVAL); @@ -579,17 +1133,41 @@ static struct phy *lynx_28g_xlate(struct device *dev, return priv->lane[idx].phy; } +static int lynx_28g_probe_lane(struct lynx_28g_priv *priv, int id, + struct device_node *dn) +{ + struct lynx_28g_lane *lane = &priv->lane[id]; + struct phy *phy; + + phy = devm_phy_create(priv->dev, dn, &lynx_28g_ops); + if (IS_ERR(phy)) + return PTR_ERR(phy); + + lane->priv = priv; + lane->phy = phy; + lane->id = id; + phy_set_drvdata(phy, lane); + lynx_28g_lane_read_configuration(lane); + + return 0; +} + static int lynx_28g_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct phy_provider *provider; struct lynx_28g_priv *priv; - int i; + struct device_node *dn; + int err; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->dev = &pdev->dev; + + priv->dev = dev; + dev_set_drvdata(dev, priv); + spin_lock_init(&priv->pcc_lock); + INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); priv->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(priv->base)) @@ -597,35 +1175,51 @@ static int lynx_28g_probe(struct platform_device *pdev) lynx_28g_pll_read_configuration(priv); - for (i = 0; i < LYNX_28G_NUM_LANE; i++) { - struct lynx_28g_lane *lane = &priv->lane[i]; - struct phy *phy; + dn = dev_of_node(dev); + if (of_get_child_count(dn)) { + struct device_node *child; - memset(lane, 0, sizeof(*lane)); + for_each_available_child_of_node(dn, child) { + u32 reg; - phy = devm_phy_create(&pdev->dev, NULL, &lynx_28g_ops); - if (IS_ERR(phy)) - return PTR_ERR(phy); + /* PHY subnode name must be 'phy'. */ + if (!(of_node_name_eq(child, "phy"))) + continue; - lane->priv = priv; - lane->phy = phy; - lane->id = i; - phy_set_drvdata(phy, lane); - lynx_28g_lane_read_configuration(lane); + if (of_property_read_u32(child, "reg", ®)) { + dev_err(dev, "No \"reg\" property for %pOF\n", child); + of_node_put(child); + return -EINVAL; + } + + if (reg >= LYNX_28G_NUM_LANE) { + dev_err(dev, "\"reg\" property out of range for %pOF\n", child); + of_node_put(child); + return -EINVAL; + } + + err = lynx_28g_probe_lane(priv, reg, child); + if (err) { + of_node_put(child); + return err; + } + } + } else { + for (int i = 0; i < LYNX_28G_NUM_LANE; i++) { + err = lynx_28g_probe_lane(priv, i, NULL); + if (err) + return err; + } } - dev_set_drvdata(dev, priv); - - spin_lock_init(&priv->pcc_lock); - INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check); + provider = devm_of_phy_provider_register(dev, lynx_28g_xlate); + if (IS_ERR(provider)) + return PTR_ERR(provider); queue_delayed_work(system_power_efficient_wq, &priv->cdr_check, msecs_to_jiffies(1000)); - dev_set_drvdata(&pdev->dev, priv); - provider = devm_of_phy_provider_register(&pdev->dev, lynx_28g_xlate); - - return PTR_ERR_OR_ZERO(provider); + return 0; } static void lynx_28g_remove(struct platform_device *pdev) diff --git a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c index 191c282246d9..d010fec15671 100644 --- a/drivers/phy/freescale/phy-fsl-samsung-hdmi.c +++ b/drivers/phy/freescale/phy-fsl-samsung-hdmi.c @@ -570,17 +570,20 @@ const struct phy_config *fsl_samsung_hdmi_phy_find_settings(struct fsl_samsung_h return fract_div_phy; } -static long fsl_samsung_hdmi_phy_clk_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *parent_rate) +static int fsl_samsung_hdmi_phy_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct fsl_samsung_hdmi_phy *phy = to_fsl_samsung_hdmi_phy(hw); - const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, rate); + const struct phy_config *target_settings = fsl_samsung_hdmi_phy_find_settings(phy, + req->rate); if (target_settings == NULL) return -EINVAL; dev_dbg(phy->dev, "round_rate, closest rate = %u\n", target_settings->pixclk); - return target_settings->pixclk; + req->rate = target_settings->pixclk; + + return 0; } static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw, @@ -599,7 +602,7 @@ static int fsl_samsung_hdmi_phy_clk_set_rate(struct clk_hw *hw, static const struct clk_ops phy_clk_ops = { .recalc_rate = phy_clk_recalc_rate, - .round_rate = fsl_samsung_hdmi_phy_clk_round_rate, + .determine_rate = fsl_samsung_hdmi_phy_clk_determine_rate, .set_rate = fsl_samsung_hdmi_phy_clk_set_rate, }; diff --git a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c index 59903f86b13f..dd3e515a8e86 100644 --- a/drivers/phy/marvell/phy-mvebu-cp110-utmi.c +++ b/drivers/phy/marvell/phy-mvebu-cp110-utmi.c @@ -338,7 +338,7 @@ static int mvebu_cp110_utmi_phy_probe(struct platform_device *pdev) return -ENOMEM; } - port->dr_mode = of_usb_get_dr_mode_by_phy(child, -1); + port->dr_mode = of_usb_get_dr_mode_by_phy(child, 0); if ((port->dr_mode != USB_DR_MODE_HOST) && (port->dr_mode != USB_DR_MODE_PERIPHERAL)) { dev_err(&pdev->dev, diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c index e51b2d13eab4..b0b6497e7eed 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt2701.c @@ -90,10 +90,10 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) usleep_range(80, 100); } -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return rate; + return 0; } static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -170,7 +170,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, .set_rate = mtk_hdmi_pll_set_rate, - .round_rate = mtk_hdmi_pll_round_rate, + .determine_rate = mtk_hdmi_pll_determine_rate, .recalc_rate = mtk_hdmi_pll_recalc_rate, }; diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c index d04758396046..58c6596c8c20 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8173.c @@ -118,18 +118,18 @@ static void mtk_hdmi_pll_unprepare(struct clk_hw *hw) usleep_range(100, 150); } -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); - hdmi_phy->pll_rate = rate; - if (rate <= 74250000) - *parent_rate = rate; + hdmi_phy->pll_rate = req->rate; + if (req->rate <= 74250000) + req->best_parent_rate = req->rate; else - *parent_rate = rate / 2; + req->best_parent_rate = req->rate / 2; - return rate; + return 0; } static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, @@ -223,7 +223,7 @@ static const struct clk_ops mtk_hdmi_phy_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, .set_rate = mtk_hdmi_pll_set_rate, - .round_rate = mtk_hdmi_pll_round_rate, + .determine_rate = mtk_hdmi_pll_determine_rate, .recalc_rate = mtk_hdmi_pll_recalc_rate, }; diff --git a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c index b38f3ae26b3f..1426a2db984d 100644 --- a/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c +++ b/drivers/phy/mediatek/phy-mtk-hdmi-mt8195.c @@ -418,13 +418,13 @@ static int mtk_hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, return mtk_hdmi_pll_calc(hdmi_phy, hw, rate, parent_rate); } -static long mtk_hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int mtk_hdmi_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct mtk_hdmi_phy *hdmi_phy = to_mtk_hdmi_phy(hw); - hdmi_phy->pll_rate = rate; - return rate; + hdmi_phy->pll_rate = req->rate; + return 0; } static unsigned long mtk_hdmi_pll_recalc_rate(struct clk_hw *hw, @@ -439,7 +439,7 @@ static const struct clk_ops mtk_hdmi_pll_ops = { .prepare = mtk_hdmi_pll_prepare, .unprepare = mtk_hdmi_pll_unprepare, .set_rate = mtk_hdmi_pll_set_rate, - .round_rate = mtk_hdmi_pll_round_rate, + .determine_rate = mtk_hdmi_pll_determine_rate, .recalc_rate = mtk_hdmi_pll_recalc_rate, }; diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c index 673cb0f08959..438ff3605d90 100644 --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8173.c @@ -237,16 +237,18 @@ static void mtk_mipi_tx_pll_unprepare(struct clk_hw *hw) mtk_phy_clear_bits(base + MIPITX_DSI_PLL_CON0, RG_DSI_MPPLL_DIV_MSK); } -static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clamp_val(rate, 50000000, 1250000000); + req->rate = clamp_val(req->rate, 50000000, 1250000000); + + return 0; } static const struct clk_ops mtk_mipi_tx_pll_ops = { .prepare = mtk_mipi_tx_pll_prepare, .unprepare = mtk_mipi_tx_pll_unprepare, - .round_rate = mtk_mipi_tx_pll_round_rate, + .determine_rate = mtk_mipi_tx_pll_determine_rate, .set_rate = mtk_mipi_tx_pll_set_rate, .recalc_rate = mtk_mipi_tx_pll_recalc_rate, }; diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c index 553725e1269c..a54d44ef70ab 100644 --- a/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c +++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi-mt8183.c @@ -97,16 +97,18 @@ static void mtk_mipi_tx_pll_disable(struct clk_hw *hw) mtk_phy_clear_bits(base + MIPITX_PLL_PWR, AD_DSI_PLL_SDM_PWR_ON); } -static long mtk_mipi_tx_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int mtk_mipi_tx_pll_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { - return clamp_val(rate, 125000000, 1600000000); + req->rate = clamp_val(req->rate, 125000000, 1600000000); + + return 0; } static const struct clk_ops mtk_mipi_tx_pll_ops = { .enable = mtk_mipi_tx_pll_enable, .disable = mtk_mipi_tx_pll_disable, - .round_rate = mtk_mipi_tx_pll_round_rate, + .determine_rate = mtk_mipi_tx_pll_determine_rate, .set_rate = mtk_mipi_tx_pll_set_rate, .recalc_rate = mtk_mipi_tx_pll_recalc_rate, }; diff --git a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c index 1a0b7484f525..100a50d0e861 100644 --- a/drivers/phy/mediatek/phy-mtk-xfi-tphy.c +++ b/drivers/phy/mediatek/phy-mtk-xfi-tphy.c @@ -353,7 +353,7 @@ static int mtk_xfi_tphy_power_on(struct phy *phy) * Disable and unprepare all clocks previously enabled. * * Return: - * See clk_bulk_prepare_disable(). + * See clk_bulk_disable_unprepare(). */ static int mtk_xfi_tphy_power_off(struct phy *phy) { diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c index 8d227890a345..21aaf2f76e53 100644 --- a/drivers/phy/phy-core.c +++ b/drivers/phy/phy-core.c @@ -75,7 +75,7 @@ int phy_create_lookup(struct phy *phy, const char *con_id, const char *dev_id) if (!phy || !dev_id || !con_id) return -EINVAL; - pl = kzalloc(sizeof(*pl), GFP_KERNEL); + pl = kzalloc_obj(*pl); if (!pl) return -ENOMEM; @@ -138,17 +138,14 @@ static struct phy *phy_find(struct device *dev, const char *con_id) static struct phy_provider *of_phy_provider_lookup(struct device_node *node) { struct phy_provider *phy_provider; - struct device_node *child; list_for_each_entry(phy_provider, &phy_provider_list, list) { if (phy_provider->dev->of_node == node) return phy_provider; - for_each_child_of_node(phy_provider->children, child) - if (child == node) { - of_node_put(child); + for_each_child_of_node_scoped(phy_provider->children, child) + if (child == node) return phy_provider; - } } return ERR_PTR(-EPROBE_DEFER); @@ -190,15 +187,15 @@ int phy_pm_runtime_get_sync(struct phy *phy) } EXPORT_SYMBOL_GPL(phy_pm_runtime_get_sync); -int phy_pm_runtime_put(struct phy *phy) +void phy_pm_runtime_put(struct phy *phy) { if (!phy) - return 0; + return; if (!pm_runtime_enabled(&phy->dev)) - return -ENOTSUPP; + return; - return pm_runtime_put(&phy->dev); + pm_runtime_put(&phy->dev); } EXPORT_SYMBOL_GPL(phy_pm_runtime_put); @@ -1007,7 +1004,7 @@ struct phy *phy_create(struct device *dev, struct device_node *node, if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - phy = kzalloc(sizeof(*phy), GFP_KERNEL); + phy = kzalloc_obj(*phy); if (!phy) return ERR_PTR(-ENOMEM); @@ -1177,7 +1174,7 @@ struct phy_provider *__of_phy_provider_register(struct device *dev, children = dev->of_node; } - phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL); + phy_provider = kzalloc_obj(*phy_provider); if (!phy_provider) return ERR_PTR(-ENOMEM); diff --git a/drivers/phy/phy-google-usb.c b/drivers/phy/phy-google-usb.c new file mode 100644 index 000000000000..ab20bc20f19e --- /dev/null +++ b/drivers/phy/phy-google-usb.c @@ -0,0 +1,296 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * phy-google-usb.c - Google USB PHY driver + * + * Copyright (C) 2025, Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USBCS_USB2PHY_CFG19_OFFSET 0x0 +#define USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV GENMASK(19, 8) + +#define USBCS_USB2PHY_CFG21_OFFSET 0x8 +#define USBCS_USB2PHY_CFG21_PHY_ENABLE BIT(12) +#define USBCS_USB2PHY_CFG21_REF_FREQ_SEL GENMASK(15, 13) +#define USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL BIT(19) + +#define USBCS_PHY_CFG1_OFFSET 0x28 +#define USBCS_PHY_CFG1_SYS_VBUSVALID BIT(17) + +enum google_usb_phy_id { + GOOGLE_USB2_PHY, + GOOGLE_USB_PHY_NUM, +}; + +struct google_usb_phy_instance { + struct google_usb_phy *parent; + unsigned int index; + struct phy *phy; + unsigned int num_clks; + struct clk_bulk_data *clks; + unsigned int num_rsts; + struct reset_control_bulk_data *rsts; +}; + +struct google_usb_phy { + struct device *dev; + struct regmap *usb_cfg_regmap; + unsigned int usb2_cfg_offset; + void __iomem *usbdp_top_base; + struct google_usb_phy_instance *insts; + /* + * Protect phy registers from concurrent access, specifically via + * google_usb_set_orientation callback. + */ + struct mutex phy_mutex; + struct typec_switch_dev *sw; + enum typec_orientation orientation; +}; + +static void set_vbus_valid(struct google_usb_phy *gphy) +{ + u32 reg; + + if (gphy->orientation == TYPEC_ORIENTATION_NONE) { + reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); + reg &= ~USBCS_PHY_CFG1_SYS_VBUSVALID; + writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); + } else { + reg = readl(gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); + reg |= USBCS_PHY_CFG1_SYS_VBUSVALID; + writel(reg, gphy->usbdp_top_base + USBCS_PHY_CFG1_OFFSET); + } +} + +static int google_usb_set_orientation(struct typec_switch_dev *sw, + enum typec_orientation orientation) +{ + struct google_usb_phy *gphy = typec_switch_get_drvdata(sw); + + dev_dbg(gphy->dev, "set orientation %d\n", orientation); + + gphy->orientation = orientation; + + if (pm_runtime_suspended(gphy->dev)) + return 0; + + guard(mutex)(&gphy->phy_mutex); + + set_vbus_valid(gphy); + + return 0; +} + +static int google_usb2_phy_init(struct phy *_phy) +{ + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy); + struct google_usb_phy *gphy = inst->parent; + u32 reg; + int ret; + + dev_dbg(gphy->dev, "initializing usb2 phy\n"); + + guard(mutex)(&gphy->phy_mutex); + + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®); + reg &= ~USBCS_USB2PHY_CFG21_PHY_TX_DIG_BYPASS_SEL; + reg &= ~USBCS_USB2PHY_CFG21_REF_FREQ_SEL; + reg |= FIELD_PREP(USBCS_USB2PHY_CFG21_REF_FREQ_SEL, 0); + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); + + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, ®); + reg &= ~USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV; + reg |= FIELD_PREP(USBCS_USB2PHY_CFG19_PHY_CFG_PLL_FB_DIV, 368); + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG19_OFFSET, reg); + + set_vbus_valid(gphy); + + ret = clk_bulk_prepare_enable(inst->num_clks, inst->clks); + if (ret) + return ret; + + ret = reset_control_bulk_deassert(inst->num_rsts, inst->rsts); + if (ret) { + clk_bulk_disable_unprepare(inst->num_clks, inst->clks); + return ret; + } + + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®); + reg |= USBCS_USB2PHY_CFG21_PHY_ENABLE; + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); + + return 0; +} + +static int google_usb2_phy_exit(struct phy *_phy) +{ + struct google_usb_phy_instance *inst = phy_get_drvdata(_phy); + struct google_usb_phy *gphy = inst->parent; + u32 reg; + + dev_dbg(gphy->dev, "exiting usb2 phy\n"); + + guard(mutex)(&gphy->phy_mutex); + + regmap_read(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, ®); + reg &= ~USBCS_USB2PHY_CFG21_PHY_ENABLE; + regmap_write(gphy->usb_cfg_regmap, gphy->usb2_cfg_offset + USBCS_USB2PHY_CFG21_OFFSET, reg); + + reset_control_bulk_assert(inst->num_rsts, inst->rsts); + clk_bulk_disable_unprepare(inst->num_clks, inst->clks); + + return 0; +} + +static const struct phy_ops google_usb2_phy_ops = { + .init = google_usb2_phy_init, + .exit = google_usb2_phy_exit, +}; + +static struct phy *google_usb_phy_xlate(struct device *dev, + const struct of_phandle_args *args) +{ + struct google_usb_phy *gphy = dev_get_drvdata(dev); + + if (args->args[0] >= GOOGLE_USB_PHY_NUM) { + dev_err(dev, "invalid PHY index requested from DT\n"); + return ERR_PTR(-ENODEV); + } + return gphy->insts[args->args[0]].phy; +} + +static int google_usb_phy_probe(struct platform_device *pdev) +{ + struct typec_switch_desc sw_desc = { }; + struct google_usb_phy_instance *inst; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct google_usb_phy *gphy; + struct phy *phy; + u32 args[1]; + int ret; + + gphy = devm_kzalloc(dev, sizeof(*gphy), GFP_KERNEL); + if (!gphy) + return -ENOMEM; + + dev_set_drvdata(dev, gphy); + gphy->dev = dev; + + ret = devm_mutex_init(dev, &gphy->phy_mutex); + if (ret) + return ret; + + gphy->usb_cfg_regmap = + syscon_regmap_lookup_by_phandle_args(dev->of_node, + "google,usb-cfg-csr", + ARRAY_SIZE(args), args); + if (IS_ERR(gphy->usb_cfg_regmap)) { + return dev_err_probe(dev, PTR_ERR(gphy->usb_cfg_regmap), + "invalid usb cfg csr\n"); + } + + gphy->usb2_cfg_offset = args[0]; + + gphy->usbdp_top_base = devm_platform_ioremap_resource_byname(pdev, + "usbdp_top"); + if (IS_ERR(gphy->usbdp_top_base)) + return dev_err_probe(dev, PTR_ERR(gphy->usbdp_top_base), + "invalid usbdp top\n"); + + gphy->insts = devm_kcalloc(dev, GOOGLE_USB_PHY_NUM, sizeof(*gphy->insts), GFP_KERNEL); + if (!gphy->insts) + return -ENOMEM; + + inst = &gphy->insts[GOOGLE_USB2_PHY]; + inst->parent = gphy; + inst->index = GOOGLE_USB2_PHY; + phy = devm_phy_create(dev, NULL, &google_usb2_phy_ops); + if (IS_ERR(phy)) + return dev_err_probe(dev, PTR_ERR(phy), + "failed to create usb2 phy instance\n"); + inst->phy = phy; + phy_set_drvdata(phy, inst); + + inst->num_clks = 2; + inst->clks = devm_kcalloc(dev, inst->num_clks, sizeof(*inst->clks), GFP_KERNEL); + if (!inst->clks) + return -ENOMEM; + inst->clks[0].id = "usb2"; + inst->clks[1].id = "usb2_apb"; + ret = devm_clk_bulk_get(dev, inst->num_clks, inst->clks); + if (ret) + return dev_err_probe(dev, ret, "failed to get u2 phy clks\n"); + + inst->num_rsts = 2; + inst->rsts = devm_kcalloc(dev, inst->num_rsts, sizeof(*inst->rsts), GFP_KERNEL); + if (!inst->rsts) + return -ENOMEM; + inst->rsts[0].id = "usb2"; + inst->rsts[1].id = "usb2_apb"; + ret = devm_reset_control_bulk_get_exclusive(dev, inst->num_rsts, inst->rsts); + if (ret) + return dev_err_probe(dev, ret, "failed to get u2 phy resets\n"); + + phy_provider = devm_of_phy_provider_register(dev, google_usb_phy_xlate); + if (IS_ERR(phy_provider)) + return dev_err_probe(dev, PTR_ERR(phy_provider), + "failed to register phy provider\n"); + + pm_runtime_enable(dev); + + sw_desc.fwnode = dev_fwnode(dev); + sw_desc.drvdata = gphy; + sw_desc.name = fwnode_get_name(dev_fwnode(dev)); + sw_desc.set = google_usb_set_orientation; + + gphy->sw = typec_switch_register(dev, &sw_desc); + if (IS_ERR(gphy->sw)) + return dev_err_probe(dev, PTR_ERR(gphy->sw), + "failed to register typec switch\n"); + + return 0; +} + +static void google_usb_phy_remove(struct platform_device *pdev) +{ + struct google_usb_phy *gphy = dev_get_drvdata(&pdev->dev); + + typec_switch_unregister(gphy->sw); + pm_runtime_disable(&pdev->dev); +} + +static const struct of_device_id google_usb_phy_of_match[] = { + { + .compatible = "google,lga-usb-phy", + }, + { } +}; +MODULE_DEVICE_TABLE(of, google_usb_phy_of_match); + +static struct platform_driver google_usb_phy = { + .probe = google_usb_phy_probe, + .remove = google_usb_phy_remove, + .driver = { + .name = "google-usb-phy", + .of_match_table = google_usb_phy_of_match, + } +}; + +module_platform_driver(google_usb_phy); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Google USB phy driver"); diff --git a/drivers/phy/phy-spacemit-k1-pcie.c b/drivers/phy/phy-spacemit-k1-pcie.c new file mode 100644 index 000000000000..75477bea7f70 --- /dev/null +++ b/drivers/phy/phy-spacemit-k1-pcie.c @@ -0,0 +1,670 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SpacemiT K1 PCIe and PCIe/USB 3 combo PHY driver + * + * Copyright (C) 2025 by RISCstar Solutions Corporation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Three PCIe ports are supported in the SpacemiT K1 SoC, and this driver + * supports their PHYs. + * + * The PHY for PCIe port A is different from the PHYs for ports B and C: + * - It has one lane, while ports B and C have two + * - It is a combo PHY can be used for PCIe or USB 3 + * - It can automatically calibrate PCIe TX and RX termination settings + * + * The PHY functionality for PCIe ports B and C is identical: + * - They have two PCIe lanes (but can be restricted to 1 via device tree) + * - They are used for PCIe only + * - They are configured using TX and RX values computed for port A + * + * A given board is designed to use the combo PHY for either PCIe or USB 3. + * Whether the combo PHY is configured for PCIe or USB 3 is specified in + * device tree using a phandle plus an argument. The argument indicates + * the type (either PHY_TYPE_PCIE or PHY_TYPE_USB3). + * + * Each PHY has a reset that it gets and deasserts during initialization. + * Each depends also on other clocks and resets provided by the controller + * hardware (PCIe or USB) it is associated with. The controller drivers + * are required to enable any clocks and de-assert any resets that affect + * PHY operation. In addition each PHY implements an internal PLL, driven + * by an external (24 MHz) oscillator. + * + * PCIe PHYs must be programmed with RX and TX calibration values. The + * combo PHY is the only one that can determine these values. They are + * determined by temporarily enabling the combo PHY in PCIe mode at probe + * time (if necessary). This calibration only needs to be done once, and + * when it has completed the TX and RX values are saved. + * + * To allow the combo PHY to be enabled for calibration, the resets and + * clocks it uses in PCIe mode must be supplied. + */ + +struct k1_pcie_phy { + struct device *dev; /* PHY provider device */ + struct phy *phy; + void __iomem *regs; + u32 pcie_lanes; /* Max (1 or 2) unless limited by DT */ + struct clk *pll; + struct clk_hw pll_hw; /* Private PLL clock */ + + /* The remaining fields are only used for the combo PHY */ + u32 type; /* PHY_TYPE_PCIE or PHY_TYPE_USB3 */ + struct regmap *pmu; /* MMIO regmap (no errors) */ +}; + +#define CALIBRATION_TIMEOUT 500000 /* For combo PHY (usec) */ +#define PLL_TIMEOUT 500000 /* For PHY PLL lock (usec) */ +#define POLL_DELAY 500 /* Time between polls (usec) */ + +/* Selecting the combo PHY operating mode requires APMU regmap access */ +#define SYSCON_APMU "spacemit,apmu" + +/* PMU space, for selecting between PCIe and USB 3 mode (combo PHY only) */ + +#define PMUA_USB_PHY_CTRL0 0x0110 +#define COMBO_PHY_SEL BIT(3) /* 0: PCIe; 1: USB 3 */ + +#define PCIE_CLK_RES_CTRL 0x03cc +#define PCIE_APP_HOLD_PHY_RST BIT(30) + +/* PHY register space */ + +/* Offset between lane 0 and lane 1 registers when there are two */ +#define PHY_LANE_OFFSET 0x0400 + +/* PHY PLL configuration */ +#define PCIE_PU_ADDR_CLK_CFG 0x0008 +#define PLL_READY BIT(0) /* read-only */ +#define CFG_INTERNAL_TIMER_ADJ GENMASK(10, 7) +#define TIMER_ADJ_USB 0x2 +#define TIMER_ADJ_PCIE 0x6 +#define CFG_SW_PHY_INIT_DONE BIT(11) /* We set after PLL config */ + +#define PCIE_RC_DONE_STATUS 0x0018 +#define CFG_FORCE_RCV_RETRY BIT(10) /* Used for PCIe */ + +/* PCIe PHY lane calibration; assumes 24MHz input clock */ +#define PCIE_RC_CAL_REG2 0x0020 +#define RC_CAL_TOGGLE BIT(22) +#define CLKSEL GENMASK(31, 29) +#define CLKSEL_24M 0x3 + +/* Additional PHY PLL configuration (USB 3 and PCIe) */ +#define PCIE_PU_PLL_1 0x0048 +#define REF_100_WSSC BIT(12) /* 1: input is 100MHz, SSC */ +#define FREF_SEL GENMASK(15, 13) +#define FREF_24M 0x1 +#define SSC_DEP_SEL GENMASK(19, 16) +#define SSC_DEP_NONE 0x0 +#define SSC_DEP_5000PPM 0xa + +/* PCIe PHY configuration */ +#define PCIE_PU_PLL_2 0x004c +#define GEN_REF100 BIT(4) /* 1: generate 100MHz clk */ + +#define PCIE_RX_REG1 0x0050 +#define EN_RTERM BIT(3) +#define AFE_RTERM_REG GENMASK(11, 8) + +#define PCIE_RX_REG2 0x0054 +#define RX_RTERM_SEL BIT(5) /* 0: use AFE_RTERM_REG value */ + +#define PCIE_LTSSM_DIS_ENTRY 0x005c +#define CFG_REFCLK_MODE GENMASK(9, 8) +#define RFCLK_MODE_DRIVER 0x1 +#define OVRD_REFCLK_MODE BIT(10) /* 1: use CFG_RFCLK_MODE */ + +#define PCIE_TX_REG1 0x0064 +#define TX_RTERM_REG GENMASK(15, 12) +#define TX_RTERM_SEL BIT(25) /* 1: use TX_RTERM_REG */ + +/* Zeroed for the combo PHY operating in USB mode */ +#define USB3_TEST_CTRL 0x0068 + +/* PHY calibration values, determined by the combo PHY at probe time */ +#define PCIE_RCAL_RESULT 0x0084 /* Port A PHY only */ +#define RTERM_VALUE_RX GENMASK(3, 0) +#define RTERM_VALUE_TX GENMASK(7, 4) +#define R_TUNE_DONE BIT(10) + +static u32 k1_phy_rterm = ~0; /* Invalid initial value */ + +/* Save the RX and TX receiver termination values */ +static void k1_phy_rterm_set(u32 val) +{ + k1_phy_rterm = val & (RTERM_VALUE_RX | RTERM_VALUE_TX); +} + +static bool k1_phy_rterm_valid(void) +{ + /* Valid if no bits outside those we care about are set */ + return !(k1_phy_rterm & ~(RTERM_VALUE_RX | RTERM_VALUE_TX)); +} + +static u32 k1_phy_rterm_rx(void) +{ + return FIELD_GET(RTERM_VALUE_RX, k1_phy_rterm); +} + +static u32 k1_phy_rterm_tx(void) +{ + return FIELD_GET(RTERM_VALUE_TX, k1_phy_rterm); +} + +/* Only the combo PHY has a PMU pointer defined */ +static bool k1_phy_port_a(struct k1_pcie_phy *k1_phy) +{ + return !!k1_phy->pmu; +} + +/* The PLL clocks are driven by the external oscillator */ +static const struct clk_parent_data k1_pcie_phy_data[] = { + { .fw_name = "refclk", }, +}; + +static struct k1_pcie_phy *clk_hw_to_k1_phy(struct clk_hw *clk_hw) +{ + return container_of(clk_hw, struct k1_pcie_phy, pll_hw); +} + +/* USB mode only works on the combo PHY, which has only one lane */ +static void k1_pcie_phy_pll_prepare_usb(struct k1_pcie_phy *k1_phy) +{ + void __iomem *regs = k1_phy->regs; + u32 val; + + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); + val &= ~CFG_INTERNAL_TIMER_ADJ; + val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_USB); + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); + + val = readl(regs + PCIE_PU_PLL_1); + val &= ~SSC_DEP_SEL; + val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_5000PPM); + writel(val, regs + PCIE_PU_PLL_1); +} + +/* Perform PCIe-specific register updates before starting the PLL clock */ +static void k1_pcie_phy_pll_prepare_pcie(struct k1_pcie_phy *k1_phy) +{ + void __iomem *regs = k1_phy->regs; + u32 val; + u32 i; + + for (i = 0; i < k1_phy->pcie_lanes; i++) { + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); + val &= ~CFG_INTERNAL_TIMER_ADJ; + val |= FIELD_PREP(CFG_INTERNAL_TIMER_ADJ, TIMER_ADJ_PCIE); + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); + + regs += PHY_LANE_OFFSET; /* Next lane */ + } + + regs = k1_phy->regs; + val = readl(regs + PCIE_RC_DONE_STATUS); + val |= CFG_FORCE_RCV_RETRY; + writel(val, regs + PCIE_RC_DONE_STATUS); + + val = readl(regs + PCIE_PU_PLL_1); + val &= ~SSC_DEP_SEL; + val |= FIELD_PREP(SSC_DEP_SEL, SSC_DEP_NONE); + writel(val, regs + PCIE_PU_PLL_1); + + val = readl(regs + PCIE_PU_PLL_2); + val |= GEN_REF100; /* Enable 100 MHz PLL output clock */ + writel(val, regs + PCIE_PU_PLL_2); +} + +static int k1_pcie_phy_pll_prepare(struct clk_hw *clk_hw) +{ + struct k1_pcie_phy *k1_phy = clk_hw_to_k1_phy(clk_hw); + void __iomem *regs = k1_phy->regs; + u32 val; + u32 i; + + if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) + k1_pcie_phy_pll_prepare_usb(k1_phy); + else + k1_pcie_phy_pll_prepare_pcie(k1_phy); + + /* + * Disable 100 MHz input reference with spread-spectrum + * clocking and select the 24 MHz clock input frequency + */ + val = readl(regs + PCIE_PU_PLL_1); + val &= ~REF_100_WSSC; + val &= ~FREF_SEL; + val |= FIELD_PREP(FREF_SEL, FREF_24M); + writel(val, regs + PCIE_PU_PLL_1); + + /* Mark PLL configuration done on all lanes */ + for (i = 0; i < k1_phy->pcie_lanes; i++) { + val = readl(regs + PCIE_PU_ADDR_CLK_CFG); + val |= CFG_SW_PHY_INIT_DONE; + writel(val, regs + PCIE_PU_ADDR_CLK_CFG); + + regs += PHY_LANE_OFFSET; /* Next lane */ + } + + /* + * Wait for indication the PHY PLL is locked. Lanes for ports + * B and C share a PLL, so it's enough to sample just lane 0. + */ + return readl_poll_timeout(k1_phy->regs + PCIE_PU_ADDR_CLK_CFG, + val, val & PLL_READY, + POLL_DELAY, PLL_TIMEOUT); +} + +/* Prepare implies enable, and once enabled, it's always on */ +static const struct clk_ops k1_pcie_phy_pll_ops = { + .prepare = k1_pcie_phy_pll_prepare, +}; + +/* We represent the PHY PLL as a private clock */ +static int k1_pcie_phy_pll_setup(struct k1_pcie_phy *k1_phy) +{ + struct clk_hw *hw = &k1_phy->pll_hw; + struct device *dev = k1_phy->dev; + struct clk_init_data init = { }; + char *name; + int ret; + + name = kasprintf(GFP_KERNEL, "pcie%u_phy_pll", k1_phy->phy->id); + if (!name) + return -ENOMEM; + + init.name = name; + init.ops = &k1_pcie_phy_pll_ops; + init.parent_data = k1_pcie_phy_data; + init.num_parents = ARRAY_SIZE(k1_pcie_phy_data); + + hw->init = &init; + + ret = devm_clk_hw_register(dev, hw); + + kfree(name); /* __clk_register() duplicates the name we provide */ + + if (ret) + return ret; + + k1_phy->pll = devm_clk_hw_get_clk(dev, hw, "pll"); + if (IS_ERR(k1_phy->pll)) + return PTR_ERR(k1_phy->pll); + + return 0; +} + +/* Select PCIe or USB 3 mode for the combo PHY. */ +static void k1_combo_phy_sel(struct k1_pcie_phy *k1_phy, bool usb) +{ + struct regmap *pmu = k1_phy->pmu; + + /* Only change it if it's not already in the desired state */ + if (!regmap_test_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL) == usb) + regmap_assign_bits(pmu, PMUA_USB_PHY_CTRL0, COMBO_PHY_SEL, usb); +} + +static void k1_pcie_phy_init_pcie(struct k1_pcie_phy *k1_phy) +{ + u32 rx_rterm = k1_phy_rterm_rx(); + u32 tx_rterm = k1_phy_rterm_tx(); + void __iomem *regs; + u32 val; + int i; + + /* For the combo PHY, set PHY to PCIe mode */ + if (k1_phy_port_a(k1_phy)) + k1_combo_phy_sel(k1_phy, false); + + regs = k1_phy->regs; + for (i = 0; i < k1_phy->pcie_lanes; i++) { + val = readl(regs + PCIE_RX_REG1); + + /* Set RX analog front-end receiver termination value */ + val &= ~AFE_RTERM_REG; + val |= FIELD_PREP(AFE_RTERM_REG, rx_rterm); + + /* And enable refclock receiver termination */ + val |= EN_RTERM; + writel(val, regs + PCIE_RX_REG1); + + val = readl(regs + PCIE_RX_REG2); + /* Use PCIE_RX_REG1 AFE_RTERM_REG value */ + val &= ~RX_RTERM_SEL; + writel(val, regs + PCIE_RX_REG2); + + val = readl(regs + PCIE_TX_REG1); + + /* Set TX driver termination value */ + val &= ~TX_RTERM_REG; + val |= FIELD_PREP(TX_RTERM_REG, tx_rterm); + + /* Use PCIE_TX_REG1 TX_RTERM_REG value */ + val |= TX_RTERM_SEL; + writel(val, regs + PCIE_TX_REG1); + + /* Set the input clock to 24 MHz, and clear RC_CAL_TOGGLE */ + val = readl(regs + PCIE_RC_CAL_REG2); + val &= CLKSEL; + val |= FIELD_PREP(CLKSEL, CLKSEL_24M); + val &= ~RC_CAL_TOGGLE; + writel(val, regs + PCIE_RC_CAL_REG2); + + /* Now trigger recalibration by setting RC_CAL_TOGGLE again */ + val |= RC_CAL_TOGGLE; + writel(val, regs + PCIE_RC_CAL_REG2); + + val = readl(regs + PCIE_LTSSM_DIS_ENTRY); + /* Override the reference clock; set to refclk driver mode */ + val |= OVRD_REFCLK_MODE; + val &= ~CFG_REFCLK_MODE; + val |= FIELD_PREP(CFG_REFCLK_MODE, RFCLK_MODE_DRIVER); + writel(val, regs + PCIE_LTSSM_DIS_ENTRY); + + regs += PHY_LANE_OFFSET; /* Next lane */ + } +} + +/* Only called for combo PHY */ +static void k1_pcie_phy_init_usb(struct k1_pcie_phy *k1_phy) +{ + k1_combo_phy_sel(k1_phy, true); + + /* We're not doing any testing */ + writel(0, k1_phy->regs + USB3_TEST_CTRL); +} + +static int k1_pcie_phy_init(struct phy *phy) +{ + struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); + + /* Note: port type is only valid for port A (both checks needed) */ + if (k1_phy_port_a(k1_phy) && k1_phy->type == PHY_TYPE_USB3) + k1_pcie_phy_init_usb(k1_phy); + else + k1_pcie_phy_init_pcie(k1_phy); + + + return clk_prepare_enable(k1_phy->pll); +} + +static int k1_pcie_phy_exit(struct phy *phy) +{ + struct k1_pcie_phy *k1_phy = phy_get_drvdata(phy); + + clk_disable_unprepare(k1_phy->pll); + + return 0; +} + +static const struct phy_ops k1_pcie_phy_ops = { + .init = k1_pcie_phy_init, + .exit = k1_pcie_phy_exit, + .owner = THIS_MODULE, +}; + +/* + * Get values needed for calibrating PHYs operating in PCIe mode. Only + * the combo PHY is able to do this, and its calibration values are used + * for configuring all PCIe PHYs. + * + * We always need to de-assert the "global" reset on the combo PHY, + * because the USB driver depends on it. If used for PCIe, that driver + * will (also) de-assert this, but by leaving it de-asserted for the + * combo PHY, the USB driver doesn't have to do this. Note: although + * SpacemiT refers to this as the global reset, we name the "phy" reset. + * + * In addition, we guarantee the APP_HOLD_PHY_RESET bit is clear for the + * combo PHY, so the USB driver doesn't have to manage that either. The + * PCIe driver is free to change this bit for normal operation. + * + * Calibration only needs to be done once. It's possible calibration has + * already completed (e.g., it might have happened in the boot loader, or + * -EPROBE_DEFER might result in this function being called again). So we + * check that early too, to avoid doing it more than once. + * + * Otherwise we temporarily power up the PHY using the PCIe app clocks + * and resets, wait for the hardware to indicate calibration is done, + * grab the value, then shut the PHY down again. + */ +static int k1_pcie_combo_phy_calibrate(struct k1_pcie_phy *k1_phy) +{ + struct reset_control_bulk_data resets[] = { + { .id = "dbi", }, + { .id = "mstr", }, + { .id = "slv", }, + }; + struct clk_bulk_data clocks[] = { + { .id = "dbi", }, + { .id = "mstr", }, + { .id = "slv", }, + }; + struct device *dev = k1_phy->dev; + int ret = 0; + int val; + + /* Nothing to do if we already set the receiver termination value */ + if (k1_phy_rterm_valid()) + return 0; + + /* + * We also guarantee the APP_HOLD_PHY_RESET bit is clear. We can + * leave this bit clear even if an error happens below. + */ + regmap_assign_bits(k1_phy->pmu, PCIE_CLK_RES_CTRL, + PCIE_APP_HOLD_PHY_RST, false); + + /* If the calibration already completed (e.g. by U-Boot), we're done */ + val = readl(k1_phy->regs + PCIE_RCAL_RESULT); + if (val & R_TUNE_DONE) + goto out_tune_done; + + /* Put the PHY into PCIe mode */ + k1_combo_phy_sel(k1_phy, false); + + /* Get and enable the PCIe app clocks */ + ret = clk_bulk_get(dev, ARRAY_SIZE(clocks), clocks); + if (ret < 0) + goto out_tune_done; + ret = clk_bulk_prepare_enable(ARRAY_SIZE(clocks), clocks); + if (ret) + goto out_put_clocks; + + /* Get the PCIe application resets (not the PHY reset) */ + ret = reset_control_bulk_get_shared(dev, ARRAY_SIZE(resets), resets); + if (ret) + goto out_disable_clocks; + + /* De-assert the PCIe application resets */ + ret = reset_control_bulk_deassert(ARRAY_SIZE(resets), resets); + if (ret) + goto out_put_resets; + + /* + * This is the core activity here. Wait for the hardware to + * signal that it has completed calibration/tuning. Once it + * has, the register value will contain the values we'll + * use to configure PCIe PHYs. + */ + ret = readl_poll_timeout(k1_phy->regs + PCIE_RCAL_RESULT, + val, val & R_TUNE_DONE, + POLL_DELAY, CALIBRATION_TIMEOUT); + + /* Clean up. We're done with the resets and clocks */ + reset_control_bulk_assert(ARRAY_SIZE(resets), resets); +out_put_resets: + reset_control_bulk_put(ARRAY_SIZE(resets), resets); +out_disable_clocks: + clk_bulk_disable_unprepare(ARRAY_SIZE(clocks), clocks); +out_put_clocks: + clk_bulk_put(ARRAY_SIZE(clocks), clocks); +out_tune_done: + /* If we got the value without timing out, set k1_phy_rterm */ + if (!ret) + k1_phy_rterm_set(val); + + return ret; +} + +static struct phy * +k1_pcie_combo_phy_xlate(struct device *dev, const struct of_phandle_args *args) +{ + struct k1_pcie_phy *k1_phy = dev_get_drvdata(dev); + u32 type; + + /* The argument specifying the PHY mode is required */ + if (args->args_count != 1) + return ERR_PTR(-EINVAL); + + /* We only support PCIe and USB 3 mode */ + type = args->args[0]; + if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3) + return ERR_PTR(-EINVAL); + + /* This PHY can only be used once */ + if (k1_phy->type != PHY_NONE) + return ERR_PTR(-EBUSY); + + k1_phy->type = type; + + return k1_phy->phy; +} + +/* Use the maximum number of PCIe lanes unless limited by device tree */ +static u32 k1_pcie_num_lanes(struct k1_pcie_phy *k1_phy, bool port_a) +{ + struct device *dev = k1_phy->dev; + u32 count = 0; + u32 max; + int ret; + + ret = of_property_read_u32(dev_of_node(dev), "num-lanes", &count); + if (count == 1) + return 1; + + if (count == 2 && !port_a) + return 2; + + max = port_a ? 1 : 2; + if (ret != -EINVAL) + dev_warn(dev, "bad lane count %u for port; using %u\n", + count, max); + + return max; +} + +static int k1_pcie_combo_phy_probe(struct k1_pcie_phy *k1_phy) +{ + struct device *dev = k1_phy->dev; + struct regmap *regmap; + int ret; + + /* Setting the PHY mode requires access to the PMU regmap */ + regmap = syscon_regmap_lookup_by_phandle(dev_of_node(dev), SYSCON_APMU); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "failed to get PMU\n"); + k1_phy->pmu = regmap; + + ret = k1_pcie_combo_phy_calibrate(k1_phy); + if (ret) + return dev_err_probe(dev, ret, "calibration failed\n"); + + /* Needed by k1_pcie_combo_phy_xlate(), which also sets k1_phy->type */ + dev_set_drvdata(dev, k1_phy); + + return 0; +} + +static int k1_pcie_phy_probe(struct platform_device *pdev) +{ + struct phy *(*xlate)(struct device *dev, + const struct of_phandle_args *args); + struct device *dev = &pdev->dev; + struct reset_control *phy_reset; + struct phy_provider *provider; + struct k1_pcie_phy *k1_phy; + bool probing_port_a; + int ret; + + xlate = of_device_get_match_data(dev); + probing_port_a = xlate == k1_pcie_combo_phy_xlate; + + /* Only the combo PHY can calibrate, so it must probe first */ + if (!k1_phy_rterm_valid() && !probing_port_a) + return -EPROBE_DEFER; + + k1_phy = devm_kzalloc(dev, sizeof(*k1_phy), GFP_KERNEL); + if (!k1_phy) + return -ENOMEM; + k1_phy->dev = dev; + + k1_phy->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(k1_phy->regs)) + return dev_err_probe(dev, PTR_ERR(k1_phy->regs), + "error mapping registers\n"); + + /* De-assert the PHY (global) reset and leave it that way */ + phy_reset = devm_reset_control_get_exclusive_deasserted(dev, "phy"); + if (IS_ERR(phy_reset)) + return PTR_ERR(phy_reset); + + if (probing_port_a) { + ret = k1_pcie_combo_phy_probe(k1_phy); + if (ret) + return dev_err_probe(dev, ret, + "error probing combo phy\n"); + } + + k1_phy->pcie_lanes = k1_pcie_num_lanes(k1_phy, probing_port_a); + + k1_phy->phy = devm_phy_create(dev, NULL, &k1_pcie_phy_ops); + if (IS_ERR(k1_phy->phy)) + return dev_err_probe(dev, PTR_ERR(k1_phy->phy), + "error creating phy\n"); + phy_set_drvdata(k1_phy->phy, k1_phy); + + ret = k1_pcie_phy_pll_setup(k1_phy); + if (ret) + return dev_err_probe(dev, ret, "error initializing clock\n"); + + provider = devm_of_phy_provider_register(dev, xlate); + if (IS_ERR(provider)) + return dev_err_probe(dev, PTR_ERR(provider), + "error registering provider\n"); + return 0; +} + +static const struct of_device_id k1_pcie_phy_of_match[] = { + { .compatible = "spacemit,k1-combo-phy", k1_pcie_combo_phy_xlate, }, + { .compatible = "spacemit,k1-pcie-phy", of_phy_simple_xlate, }, + { }, +}; +MODULE_DEVICE_TABLE(of, k1_pcie_phy_of_match); + +static struct platform_driver k1_pcie_phy_driver = { + .probe = k1_pcie_phy_probe, + .driver = { + .of_match_table = k1_pcie_phy_of_match, + .name = "spacemit-k1-pcie-phy", + } +}; +module_platform_driver(k1_pcie_phy_driver); + +MODULE_DESCRIPTION("SpacemiT K1 PCIe and USB 3 PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-edp.c b/drivers/phy/qualcomm/phy-qcom-edp.c index f1b51018683d..7372de05a0b8 100644 --- a/drivers/phy/qualcomm/phy-qcom-edp.c +++ b/drivers/phy/qualcomm/phy-qcom-edp.c @@ -26,13 +26,15 @@ #include "phy-qcom-qmp-qserdes-com-v4.h" #include "phy-qcom-qmp-qserdes-com-v6.h" +#include "phy-qcom-qmp-qserdes-dp-com-v8.h" + /* EDP_PHY registers */ #define DP_PHY_CFG 0x0010 #define DP_PHY_CFG_1 0x0014 #define DP_PHY_PD_CTL 0x001c #define DP_PHY_MODE 0x0020 -#define DP_AUX_CFG_SIZE 10 +#define DP_AUX_CFG_SIZE 13 #define DP_PHY_AUX_CFG(n) (0x24 + (0x04 * (n))) #define DP_PHY_AUX_INTERRUPT_MASK 0x0058 @@ -76,6 +78,7 @@ struct phy_ver_ops { int (*com_power_on)(const struct qcom_edp *edp); int (*com_resetsm_cntrl)(const struct qcom_edp *edp); int (*com_bias_en_clkbuflr)(const struct qcom_edp *edp); + int (*com_clk_fwd_cfg)(const struct qcom_edp *edp); int (*com_configure_pll)(const struct qcom_edp *edp); int (*com_configure_ssc)(const struct qcom_edp *edp); }; @@ -83,6 +86,7 @@ struct phy_ver_ops { struct qcom_edp_phy_cfg { bool is_edp; const u8 *aux_cfg; + const u8 *vco_div_cfg; const struct qcom_edp_swing_pre_emph_cfg *swing_pre_emph_cfg; const struct phy_ver_ops *ver_ops; }; @@ -103,7 +107,9 @@ struct qcom_edp { struct phy_configure_opts_dp dp_opts; - struct clk_bulk_data clks[2]; + struct clk_bulk_data *clks; + int num_clks; + struct regulator_bulk_data supplies[2]; bool is_edp; @@ -179,8 +185,12 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg = { .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3, }; -static const u8 edp_phy_aux_cfg_v4[10] = { - 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 +static const u8 edp_phy_aux_cfg_v4[DP_AUX_CFG_SIZE] = { + 0x00, 0x13, 0x24, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, +}; + +static const u8 edp_phy_vco_div_cfg_v4[4] = { + 0x01, 0x01, 0x02, 0x00, }; static const u8 edp_pre_emp_hbr_rbr_v5[4][4] = { @@ -204,8 +214,16 @@ static const struct qcom_edp_swing_pre_emph_cfg edp_phy_swing_pre_emph_cfg_v5 = .pre_emphasis_hbr3_hbr2 = &edp_pre_emp_hbr2_hbr3_v5, }; -static const u8 edp_phy_aux_cfg_v5[10] = { - 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03 +static const u8 edp_phy_aux_cfg_v5[DP_AUX_CFG_SIZE] = { + 0x00, 0x13, 0xa4, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x00, +}; + +static const u8 edp_phy_aux_cfg_v8[DP_AUX_CFG_SIZE] = { + 0x00, 0x00, 0xa0, 0x00, 0x0a, 0x26, 0x0a, 0x03, 0x37, 0x03, 0x02, 0x02, 0x04, +}; + +static const u8 edp_phy_vco_div_cfg_v8[4] = { + 0x00, 0x00, 0x02, 0x01, }; static int qcom_edp_phy_init(struct phy *phy) @@ -218,12 +236,16 @@ static int qcom_edp_phy_init(struct phy *phy) if (ret) return ret; - ret = clk_bulk_prepare_enable(ARRAY_SIZE(edp->clks), edp->clks); + ret = clk_bulk_prepare_enable(edp->num_clks, edp->clks); if (ret) goto out_disable_supplies; memcpy(aux_cfg, edp->cfg->aux_cfg, sizeof(aux_cfg)); + ret = edp->cfg->ver_ops->com_clk_fwd_cfg(edp); + if (ret) + return ret; + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, edp->edp + DP_PHY_PD_CTL); @@ -343,22 +365,22 @@ static int qcom_edp_set_vco_div(const struct qcom_edp *edp, unsigned long *pixel switch (dp_opts->link_rate) { case 1620: - vco_div = 0x1; + vco_div = edp->cfg->vco_div_cfg[0]; *pixel_freq = 1620000000UL / 2; break; case 2700: - vco_div = 0x1; + vco_div = edp->cfg->vco_div_cfg[1]; *pixel_freq = 2700000000UL / 2; break; case 5400: - vco_div = 0x2; + vco_div = edp->cfg->vco_div_cfg[2]; *pixel_freq = 5400000000UL / 4; break; case 8100: - vco_div = 0x0; + vco_div = edp->cfg->vco_div_cfg[3]; *pixel_freq = 8100000000UL / 6; break; @@ -396,6 +418,11 @@ static int qcom_edp_phy_com_resetsm_cntrl_v4(const struct qcom_edp *edp) val, val & BIT(0), 500, 10000); } +static int qcom_edp_com_clk_fwd_cfg_v4(const struct qcom_edp *edp) +{ + return 0; +} + static int qcom_edp_com_bias_en_clkbuflr_v4(const struct qcom_edp *edp) { /* Turn on BIAS current for PHY/PLL */ @@ -528,6 +555,7 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = { .com_power_on = qcom_edp_phy_power_on_v4, .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v4, .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v4, + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, .com_configure_pll = qcom_edp_com_configure_pll_v4, .com_configure_ssc = qcom_edp_com_configure_ssc_v4, }; @@ -535,17 +563,20 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v4 = { static const struct qcom_edp_phy_cfg sa8775p_dp_phy_cfg = { .is_edp = false, .aux_cfg = edp_phy_aux_cfg_v5, + .vco_div_cfg = edp_phy_vco_div_cfg_v4, .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5, .ver_ops = &qcom_edp_phy_ops_v4, }; static const struct qcom_edp_phy_cfg sc7280_dp_phy_cfg = { .aux_cfg = edp_phy_aux_cfg_v4, + .vco_div_cfg = edp_phy_vco_div_cfg_v4, .ver_ops = &qcom_edp_phy_ops_v4, }; static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { .aux_cfg = edp_phy_aux_cfg_v4, + .vco_div_cfg = edp_phy_vco_div_cfg_v4, .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, .ver_ops = &qcom_edp_phy_ops_v4, }; @@ -553,6 +584,7 @@ static const struct qcom_edp_phy_cfg sc8280xp_dp_phy_cfg = { static const struct qcom_edp_phy_cfg sc8280xp_edp_phy_cfg = { .is_edp = true, .aux_cfg = edp_phy_aux_cfg_v4, + .vco_div_cfg = edp_phy_vco_div_cfg_v4, .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg, .ver_ops = &qcom_edp_phy_ops_v4, }; @@ -726,16 +758,197 @@ static const struct phy_ver_ops qcom_edp_phy_ops_v6 = { .com_power_on = qcom_edp_phy_power_on_v6, .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v6, .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v6, + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v4, .com_configure_pll = qcom_edp_com_configure_pll_v6, .com_configure_ssc = qcom_edp_com_configure_ssc_v6, }; static struct qcom_edp_phy_cfg x1e80100_phy_cfg = { .aux_cfg = edp_phy_aux_cfg_v4, + .vco_div_cfg = edp_phy_vco_div_cfg_v4, .swing_pre_emph_cfg = &dp_phy_swing_pre_emph_cfg, .ver_ops = &qcom_edp_phy_ops_v6, }; +static int qcom_edp_com_configure_ssc_v8(const struct qcom_edp *edp) +{ + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; + u32 step1; + u32 step2; + + switch (dp_opts->link_rate) { + case 1620: + case 2700: + case 8100: + step1 = 0x5b; + step2 = 0x02; + break; + + case 5400: + step1 = 0x5b; + step2 = 0x02; + break; + + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + + writel(0x01, edp->pll + DP_QSERDES_V8_COM_SSC_EN_CENTER); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_SSC_ADJ_PER1); + writel(0x6b, edp->pll + DP_QSERDES_V8_COM_SSC_PER1); + writel(0x02, edp->pll + DP_QSERDES_V8_COM_SSC_PER2); + writel(step1, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0); + writel(step2, edp->pll + DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0); + + return 0; +} + +static int qcom_edp_com_configure_pll_v8(const struct qcom_edp *edp) +{ + const struct phy_configure_opts_dp *dp_opts = &edp->dp_opts; + u32 div_frac_start2_mode0; + u32 div_frac_start3_mode0; + u32 dec_start_mode0; + u32 lock_cmp1_mode0; + u32 lock_cmp2_mode0; + u32 code1_mode0; + u32 code2_mode0; + u32 hsclk_sel; + + switch (dp_opts->link_rate) { + case 1620: + hsclk_sel = 0x5; + dec_start_mode0 = 0x34; + div_frac_start2_mode0 = 0xc0; + div_frac_start3_mode0 = 0x0b; + lock_cmp1_mode0 = 0x37; + lock_cmp2_mode0 = 0x04; + code1_mode0 = 0x71; + code2_mode0 = 0x0c; + break; + + case 2700: + hsclk_sel = 0x3; + dec_start_mode0 = 0x34; + div_frac_start2_mode0 = 0xc0; + div_frac_start3_mode0 = 0x0b; + lock_cmp1_mode0 = 0x07; + lock_cmp2_mode0 = 0x07; + code1_mode0 = 0x71; + code2_mode0 = 0x0c; + break; + + case 5400: + case 8100: + hsclk_sel = 0x2; + dec_start_mode0 = 0x4f; + div_frac_start2_mode0 = 0xa0; + div_frac_start3_mode0 = 0x01; + lock_cmp1_mode0 = 0x18; + lock_cmp2_mode0 = 0x15; + code1_mode0 = 0x14; + code2_mode0 = 0x25; + break; + + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + + writel(0x01, edp->pll + DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL); + writel(0x3b, edp->pll + DP_QSERDES_V8_COM_SYSCLK_EN_SEL); + writel(0x02, edp->pll + DP_QSERDES_V8_COM_SYS_CLK_CTRL); + writel(0x0c, edp->pll + DP_QSERDES_V8_COM_CLK_ENABLE1); + writel(0x06, edp->pll + DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE); + writel(0x30, edp->pll + DP_QSERDES_V8_COM_CLK_SELECT); + writel(hsclk_sel, edp->pll + DP_QSERDES_V8_COM_HSCLK_SEL_1); + writel(0x07, edp->pll + DP_QSERDES_V8_COM_PLL_IVCO); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP_EN); + writel(0x36, edp->pll + DP_QSERDES_V8_COM_PLL_CCTRL_MODE0); + writel(0x16, edp->pll + DP_QSERDES_V8_COM_PLL_RCTRL_MODE0); + writel(0x06, edp->pll + DP_QSERDES_V8_COM_CP_CTRL_MODE0); + writel(dec_start_mode0, edp->pll + DP_QSERDES_V8_COM_DEC_START_MODE0); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0); + writel(div_frac_start2_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0); + writel(div_frac_start3_mode0, edp->pll + DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0); + writel(0x96, edp->pll + DP_QSERDES_V8_COM_CMN_CONFIG_1); + writel(0x3f, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_MAP); + writel(lock_cmp1_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP1_MODE0); + writel(lock_cmp2_mode0, edp->pll + DP_QSERDES_V8_COM_LOCK_CMP2_MODE0); + + writel(0x0a, edp->pll + DP_QSERDES_V8_COM_BG_TIMER); + writel(0x0a, edp->pll + DP_QSERDES_V8_COM_CORECLK_DIV_MODE0); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE_CTRL); + writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); + writel(0x00, edp->pll + DP_QSERDES_V8_COM_CORE_CLK_EN); + writel(0xa0, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE1_MODE0); + writel(0x01, edp->pll + DP_QSERDES_V8_COM_VCO_TUNE2_MODE0); + + writel(code1_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0); + writel(code2_mode0, edp->pll + DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0); + + return 0; +} + + +static int qcom_edp_phy_com_resetsm_cntrl_v8(const struct qcom_edp *edp) +{ + u32 val; + + writel(0x20, edp->pll + DP_QSERDES_V8_COM_RESETSM_CNTRL); + + return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_C_READY_STATUS, + val, val & BIT(0), 500, 10000); +} + +static int qcom_edp_com_clk_fwd_cfg_v8(const struct qcom_edp *edp) +{ + writel(0x3f, edp->pll + DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1); + + return 0; +} + +static int qcom_edp_com_bias_en_clkbuflr_v8(const struct qcom_edp *edp) +{ + /* Turn on BIAS current for PHY/PLL */ + writel(0x1f, edp->pll + DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN); + + return 0; +} + +static int qcom_edp_phy_power_on_v8(const struct qcom_edp *edp) +{ + u32 val; + + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, + edp->edp + DP_PHY_PD_CTL); + writel(0xfc, edp->edp + DP_PHY_MODE); + + return readl_poll_timeout(edp->pll + DP_QSERDES_V8_COM_CMN_STATUS, + val, val & BIT(7), 5, 200); +} + +static const struct phy_ver_ops qcom_edp_phy_ops_v8 = { + .com_power_on = qcom_edp_phy_power_on_v8, + .com_resetsm_cntrl = qcom_edp_phy_com_resetsm_cntrl_v8, + .com_bias_en_clkbuflr = qcom_edp_com_bias_en_clkbuflr_v8, + .com_clk_fwd_cfg = qcom_edp_com_clk_fwd_cfg_v8, + .com_configure_pll = qcom_edp_com_configure_pll_v8, + .com_configure_ssc = qcom_edp_com_configure_ssc_v8, +}; + +static struct qcom_edp_phy_cfg glymur_phy_cfg = { + .aux_cfg = edp_phy_aux_cfg_v8, + .vco_div_cfg = edp_phy_vco_div_cfg_v8, + .swing_pre_emph_cfg = &edp_phy_swing_pre_emph_cfg_v5, + .ver_ops = &qcom_edp_phy_ops_v8, +}; + static int qcom_edp_phy_power_on(struct phy *phy) { const struct qcom_edp *edp = phy_get_drvdata(phy); @@ -885,7 +1098,7 @@ static int qcom_edp_phy_exit(struct phy *phy) { struct qcom_edp *edp = phy_get_drvdata(phy); - clk_bulk_disable_unprepare(ARRAY_SIZE(edp->clks), edp->clks); + clk_bulk_disable_unprepare(edp->num_clks, edp->clks); regulator_bulk_disable(ARRAY_SIZE(edp->supplies), edp->supplies); return 0; @@ -1092,11 +1305,9 @@ static int qcom_edp_phy_probe(struct platform_device *pdev) if (IS_ERR(edp->pll)) return PTR_ERR(edp->pll); - edp->clks[0].id = "aux"; - edp->clks[1].id = "cfg_ahb"; - ret = devm_clk_bulk_get(dev, ARRAY_SIZE(edp->clks), edp->clks); - if (ret) - return ret; + edp->num_clks = devm_clk_bulk_get_all(dev, &edp->clks); + if (edp->num_clks < 0) + return dev_err_probe(dev, edp->num_clks, "failed to get clocks\n"); edp->supplies[0].supply = "vdda-phy"; edp->supplies[1].supply = "vdda-pll"; @@ -1133,6 +1344,7 @@ static int qcom_edp_phy_probe(struct platform_device *pdev) } static const struct of_device_id qcom_edp_phy_match_table[] = { + { .compatible = "qcom,glymur-dp-phy", .data = &glymur_phy_cfg, }, { .compatible = "qcom,sa8775p-edp-phy", .data = &sa8775p_dp_phy_cfg, }, { .compatible = "qcom,sc7280-edp-phy", .data = &sc7280_dp_phy_cfg, }, { .compatible = "qcom,sc8180x-edp-phy", .data = &sc7280_dp_phy_cfg, }, diff --git a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c index 651a12b59bc8..efeec4709a15 100644 --- a/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c +++ b/drivers/phy/qualcomm/phy-qcom-eusb2-repeater.c @@ -37,6 +37,17 @@ #define EUSB2_TUNE_EUSB_EQU 0x5A #define EUSB2_TUNE_EUSB_HS_COMP_CUR 0x5B +static const int squelch_detector[] = { + [0] = -6000, + [1] = -5000, + [2] = -4000, + [3] = -3000, + [4] = -2000, + [5] = -1000, + [6] = 0, + [7] = 1000, +}; + struct eusb2_repeater_init_tbl_reg { unsigned int reg; unsigned int value; @@ -75,6 +86,13 @@ static const struct eusb2_repeater_init_tbl_reg smb2360_init_tbl[] = { { EUSB2_TUNE_USB2_PREEM, 0x2 }, }; +static const struct eusb2_repeater_init_tbl_reg smb2370_init_tbl[] = { + { EUSB2_TUNE_IUSB2, 0x4 }, + { EUSB2_TUNE_SQUELCH_U, 0x3 }, + { EUSB2_TUNE_USB2_SLEW, 0x7 }, + { EUSB2_TUNE_USB2_PREEM, 0x0 }, +}; + static const struct eusb2_repeater_cfg pm8550b_eusb2_cfg = { .init_tbl = pm8550b_init_tbl, .init_tbl_num = ARRAY_SIZE(pm8550b_init_tbl), @@ -97,6 +115,13 @@ static const struct eusb2_repeater_cfg smb2360_eusb2_cfg = { .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), }; +static const struct eusb2_repeater_cfg smb2370_eusb2_cfg = { + .init_tbl = smb2370_init_tbl, + .init_tbl_num = ARRAY_SIZE(smb2370_init_tbl), + .vreg_list = pm8550b_vreg_l, + .num_vregs = ARRAY_SIZE(pm8550b_vreg_l), +}; + static int eusb2_repeater_init_vregs(struct eusb2_repeater *rptr) { int num = rptr->cfg->num_vregs; @@ -120,7 +145,9 @@ static int eusb2_repeater_init(struct phy *phy) struct regmap *regmap = rptr->regmap; u32 base = rptr->base; u32 poll_val; + s32 dt_val; int ret; + int i; u8 val; ret = regulator_bulk_enable(rptr->cfg->num_vregs, rptr->vregs); @@ -147,6 +174,15 @@ static int eusb2_repeater_init(struct phy *phy) if (!of_property_read_u8(np, "qcom,tune-res-fsdif", &val)) regmap_write(regmap, base + EUSB2_TUNE_RES_FSDIF, val); + if (!of_property_read_s32(np, "qcom,squelch-detector-bp", &dt_val)) { + for (i = 0; i < ARRAY_SIZE(squelch_detector); i++) { + if (squelch_detector[i] == dt_val) { + regmap_write(regmap, base + EUSB2_TUNE_SQUELCH_U, i); + break; + } + } + } + /* Wait for status OK */ ret = regmap_read_poll_timeout(regmap, base + EUSB2_RPTR_STATUS, poll_val, poll_val & RPTR_OK, 10, 5); @@ -278,6 +314,10 @@ static const struct of_device_id eusb2_repeater_of_match_table[] = { .compatible = "qcom,smb2360-eusb2-repeater", .data = &smb2360_eusb2_cfg, }, + { + .compatible = "qcom,smb2370-eusb2-repeater", + .data = &smb2370_eusb2_cfg, + }, { }, }; MODULE_DEVICE_TABLE(of, eusb2_repeater_of_match_table); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c index 9e2a6c5d0f58..93f1aa10d400 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-combo.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-combo.c @@ -30,7 +30,12 @@ #include "phy-qcom-qmp-common.h" #include "phy-qcom-qmp.h" +#include "phy-qcom-qmp-pcs-aon-v6.h" +#include "phy-qcom-qmp-pcs-aon-v8.h" #include "phy-qcom-qmp-pcs-misc-v3.h" +#include "phy-qcom-qmp-pcs-misc-v4.h" +#include "phy-qcom-qmp-pcs-misc-v5.h" +#include "phy-qcom-qmp-pcs-misc-v8.h" #include "phy-qcom-qmp-pcs-usb-v4.h" #include "phy-qcom-qmp-pcs-usb-v5.h" #include "phy-qcom-qmp-pcs-usb-v6.h" @@ -43,6 +48,9 @@ #include "phy-qcom-qmp-dp-phy-v4.h" #include "phy-qcom-qmp-dp-phy-v5.h" #include "phy-qcom-qmp-dp-phy-v6.h" +#include "phy-qcom-qmp-dp-phy-v8.h" + +#include "phy-qcom-qmp-usb43-pcs-v8.h" /* QPHY_V3_DP_COM_RESET_OVRD_CTRL register bits */ /* DP PHY soft reset */ @@ -61,6 +69,7 @@ /* QPHY_V3_DP_COM_TYPEC_CTRL register bits */ #define SW_PORTSELECT_VAL BIT(0) #define SW_PORTSELECT_MUX BIT(1) +#define INVERT_CC_POLARITY BIT(2) #define PHY_INIT_COMPLETE_TIMEOUT 10000 @@ -79,6 +88,7 @@ enum qphy_reg_layout { QPHY_PCS_AUTONOMOUS_MODE_CTRL, QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR, QPHY_PCS_POWER_DOWN_CONTROL, + QPHY_PCS_CLAMP_ENABLE, QPHY_COM_RESETSM_CNTRL, QPHY_COM_C_READY_STATUS, @@ -94,6 +104,8 @@ enum qphy_reg_layout { QPHY_TX_HIGHZ_DRVR_EN, QPHY_TX_TRANSCEIVER_BIAS_EN, + QPHY_AON_TOGGLE_ENABLE, + QPHY_DP_AON_TOGGLE_ENABLE, /* Keep last to ensure regs_layout arrays are properly initialized */ QPHY_LAYOUT_SIZE }; @@ -106,6 +118,8 @@ static const unsigned int qmp_v3_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V3_PCS_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V3_PCS_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V3_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V3_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V3_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V3_COM_CMN_STATUS, @@ -131,6 +145,8 @@ static const unsigned int qmp_v45_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V4_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V4_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V4_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V4_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V4_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V4_COM_CMN_STATUS, @@ -156,6 +172,8 @@ static const unsigned int qmp_v5_5nm_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V5_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V5_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V5_PCS_MISC_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V5_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V5_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V5_COM_CMN_STATUS, @@ -181,6 +199,8 @@ static const unsigned int qmp_v6_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, @@ -206,6 +226,8 @@ static const unsigned int qmp_v6_n4_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V6_PCS_USB3_AUTONOMOUS_MODE_CTRL, [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V6_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V6_PCS_AON_CLAMP_ENABLE, + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V6_COM_RESETSM_CNTRL, [QPHY_COM_C_READY_STATUS] = QSERDES_V6_COM_C_READY_STATUS, [QPHY_COM_CMN_STATUS] = QSERDES_V6_COM_CMN_STATUS, @@ -246,6 +268,237 @@ static const unsigned int qmp_v8_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_TX_TRANSCEIVER_BIAS_EN, }; +static const unsigned int qmp_v8_n3_usb43dpphy_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V8_USB43_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V8_USB43_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V8_USB43_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL, + + /* In PCS_USB */ + [QPHY_PCS_AUTONOMOUS_MODE_CTRL] = QPHY_V8_PCS_USB_AUTONOMOUS_MODE_CTRL, + [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V8_PCS_USB_LFPS_RXTERM_IRQ_CLEAR, + + [QPHY_PCS_CLAMP_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE, + [QPHY_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE, + [QPHY_DP_AON_TOGGLE_ENABLE] = QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE, + + [QPHY_COM_RESETSM_CNTRL] = QSERDES_V8_COM_RESETSM_CNTRL, + [QPHY_COM_C_READY_STATUS] = QSERDES_V8_COM_C_READY_STATUS, + [QPHY_COM_CMN_STATUS] = QSERDES_V8_COM_CMN_STATUS, + [QPHY_COM_BIAS_EN_CLKBUFLR_EN] = QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, + + [QPHY_DP_PHY_STATUS] = QSERDES_V8_DP_PHY_STATUS, + [QPHY_DP_PHY_VCO_DIV] = QSERDES_V8_DP_PHY_VCO_DIV, + + [QPHY_TX_TX_DRV_LVL] = QSERDES_V8_LALB_TX0_DRV_LVL, + [QPHY_TX_TX_EMP_POST1_LVL] = QSERDES_V8_LALB_TX0_EMP_POST1_LVL, + [QPHY_TX_HIGHZ_DRVR_EN] = QSERDES_V8_LALB_HIGHZ_DRVR_EN, + [QPHY_TX_TRANSCEIVER_BIAS_EN] = QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1, 0xe1), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1, 0x4d), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x95), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x1e), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0xe1), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0x4d), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO_MODE1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_2, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x33), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xaf), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1, 0x01), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1, 0xc4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2, 0x89), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3, 0x20), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6, 0x13), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1, 0x21), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_SIGDET_LVL, 0x55), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME, 0xa4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_RX_CONFIG, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_TSYNC_DLY_TIME, 0x04), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1, 0xd4), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2, 0x30), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG, 0x0c), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_V8_USB43_PCS_EQ_CONFIG5, 0x10), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_pcs_usb_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), +}; + +static const struct qmp_phy_init_tbl glymur_usb43dp_lalb_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x81), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3, 0x80), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4, 0x8D), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x13), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_4, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1, 0xa2), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2, 0x6e), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7, 0x2a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B0, 0x4c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B1, 0xc4), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B2, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B3, 0x64), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B4, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B5, 0x4b), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B6, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_MODE_RATE2_B7, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2, 0x26), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_0_1, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_INIT_RATE_2_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3, 0x22), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2, 0x85), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3, 0x45), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_ENABLES, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CNTRL, 0xa3), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_LVL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_SIGDET_CAL_TRIM, 0x66), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2, 0x32), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01, 0x76), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23, 0x67), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1, 0x33), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3, 0x43), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123, 0xe5), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123, 0xf5), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL, 0xd0), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_EN, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE0_1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_GM_CAL_RES_RATE2_3, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_AUX_CLK_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_EOM_CTRL1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2, 0x77), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1, 0xdd), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123, 0x1C), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_DIG_BKUP_CTRL16, 0x37), +}; + static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V3_COM_PLL_IVCO, 0x07), QMP_PHY_INIT_CFG(QSERDES_V3_COM_SYSCLK_EN_SEL, 0x14), @@ -1132,6 +1385,38 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_CORE_CLK_EN, 0x0f), }; +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_EN_CENTER, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x3b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x56), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DCC_CAL_3, 0x60), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PSM_CAL_EN, 0x01), +}; + static const struct qmp_phy_init_tbl qmp_v6_dp_tx_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_TX_VMODE_CTRL1, 0x40), QMP_PHY_INIT_CFG(QSERDES_V6_TX_PRE_STALL_LDO_BOOST_EN, 0x30), @@ -1159,6 +1444,33 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_tx_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V6_N4_TX_TX_BAND, 0x1), }; +static const struct qmp_phy_init_tbl qmp_v8_n3p_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRANSMITTER_EN_CTRL, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_VMODE_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT1, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_ANA_INTERFACE_SELECT2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_PCS_INTERFACE_SELECT1, 0x50), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_1, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_CLKBUF_ENABLE, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TRAN_DRVR_EMP_EN, 0x5f), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_EMP_POST1_LVL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_EMP_POST1_LVL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_PRE1_EMPH, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_PRE1_EMPH, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_DRV_LVL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_DRV_LVL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_HIGHZ_DRVR_EN, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_2, 0x50), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_LANE_MODE_3, 0x51), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX_DCC_ANA_CTRL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET, 0x10), +}; + static const struct qmp_phy_init_tbl qmp_v6_dp_serdes_tbl_rbr[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x05), QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x34), @@ -1275,6 +1587,109 @@ static const struct qmp_phy_init_tbl qmp_v6_n4_dp_serdes_tbl_hbr3[] = { QMP_PHY_INIT_CFG(QSERDES_V6_COM_SSC_STEP_SIZE2_MODE0, 0x01), }; +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_rbr[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x7a), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x83), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x37), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xfe), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa4), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x21), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xa3), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr2[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0xf6), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xae), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_RESETSM_CNTRL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x3f), +}; + +static const struct qmp_phy_init_tbl qmp_v8_dp_serdes_tbl_hbr3[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_HSCLK_SEL_1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x63), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0, 0x5b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0, 0x0a), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DEC_START_MODE0, 0x4f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_ADJ_PER1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER1, 0x6b), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_ENABLE1, 0x0c), + + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYS_CLK_CTRL, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_PLL_IVCO, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SYSCLK_EN_SEL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CORE_CLK_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD3, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_CMN_MODE_CONTD1, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL, 0x84), +}; + static const struct qmp_phy_init_tbl sc8280xp_usb43dp_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_EN_CENTER, 0x01), QMP_PHY_INIT_CFG(QSERDES_V5_COM_SSC_PER1, 0x31), @@ -1649,6 +2064,12 @@ static struct regulator_bulk_data qmp_phy_vreg_l[] = { { .supply = "vdda-pll", .init_load_uA = 36000, }, }; +static struct regulator_bulk_data qmp_phy_vreg_refgen[] = { + { .supply = "vdda-phy", .init_load_uA = 21800 }, + { .supply = "vdda-pll", .init_load_uA = 36000 }, + { .supply = "refgen", .init_load_uA = 3270 }, +}; + static const u8 qmp_dp_v3_pre_emphasis_hbr3_hbr2[4][4] = { { 0x00, 0x0c, 0x15, 0x1a }, { 0x02, 0x0e, 0x16, 0xff }, @@ -1771,6 +2192,7 @@ struct qmp_combo_offsets { u16 usb3_serdes; u16 usb3_pcs_misc; u16 usb3_pcs; + u16 usb3_pcs_aon; u16 usb3_pcs_usb; u16 dp_serdes; u16 dp_txa; @@ -1792,6 +2214,8 @@ struct qmp_phy_cfg { int pcs_tbl_num; const struct qmp_phy_init_tbl *pcs_usb_tbl; int pcs_usb_tbl_num; + const struct qmp_phy_init_tbl *pcs_misc_tbl; + int pcs_misc_tbl_num; const struct qmp_phy_init_tbl *dp_serdes_tbl; int dp_serdes_tbl_num; @@ -1815,6 +2239,7 @@ struct qmp_phy_cfg { const u8 (*pre_emphasis_hbr3_hbr2)[4][4]; /* DP PHY callbacks */ + int (*configure_dp_clocks)(struct qmp_combo *qmp); int (*configure_dp_phy)(struct qmp_combo *qmp); void (*configure_dp_tx)(struct qmp_combo *qmp); int (*calibrate_dp_phy)(struct qmp_combo *qmp); @@ -1836,6 +2261,7 @@ struct qmp_phy_cfg { /* Offset from PCS to PCS_USB region */ unsigned int pcs_usb_offset; + bool invert_cc_polarity; }; struct qmp_combo { @@ -1852,6 +2278,7 @@ struct qmp_combo { void __iomem *tx2; void __iomem *rx2; void __iomem *pcs_misc; + void __iomem *pcs_aon; void __iomem *pcs_usb; void __iomem *dp_serdes; @@ -1891,6 +2318,7 @@ struct qmp_combo { static void qmp_v3_dp_aux_init(struct qmp_combo *qmp); static void qmp_v3_configure_dp_tx(struct qmp_combo *qmp); +static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp); static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp); static int qmp_v3_calibrate_dp_phy(struct qmp_combo *qmp); @@ -1899,6 +2327,10 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp); static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp); static int qmp_v4_calibrate_dp_phy(struct qmp_combo *qmp); +static void qmp_v8_dp_aux_init(struct qmp_combo *qmp); +static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp); +static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp); + static inline void qphy_setbits(void __iomem *base, u32 offset, u32 val) { u32 reg; @@ -1976,6 +2408,7 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = { .usb3_serdes = 0x1000, .usb3_pcs_misc = 0x1c00, .usb3_pcs = 0x1e00, + .usb3_pcs_aon = 0x2000, .usb3_pcs_usb = 0x2100, .dp_serdes = 0x3000, .dp_txa = 0x3400, @@ -1983,6 +2416,19 @@ static const struct qmp_combo_offsets qmp_combo_offsets_v8 = { .dp_dp_phy = 0x3c00, }; +static const struct qmp_combo_offsets qmp_combo_usb43dp_offsets_v8 = { + .com = 0x0000, + .usb3_pcs_aon = 0x0100, + .usb3_serdes = 0x1000, + .usb3_pcs_misc = 0x1400, + .usb3_pcs = 0x1600, + .usb3_pcs_usb = 0x1900, + .dp_serdes = 0x2000, + .dp_dp_phy = 0x2400, + .txa = 0x4000, + .txb = 0x5000, +}; + static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { .offsets = &qmp_combo_offsets_v3, @@ -2018,6 +2464,7 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2026,6 +2473,7 @@ static const struct qmp_phy_cfg sar2130p_usb3dpphy_cfg = { .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), .vreg_list = qmp_phy_vreg_l, .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .invert_cc_polarity = true, }; static const struct qmp_phy_cfg sc7180_usb3dpphy_cfg = { @@ -2153,6 +2601,7 @@ static const struct qmp_phy_cfg sc8180x_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2199,6 +2648,7 @@ static const struct qmp_phy_cfg sc8280xp_usb43dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2244,6 +2694,7 @@ static const struct qmp_phy_cfg x1e80100_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2332,6 +2783,7 @@ static const struct qmp_phy_cfg sm8250_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2380,6 +2832,7 @@ static const struct qmp_phy_cfg sm8350_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2427,6 +2880,7 @@ static const struct qmp_phy_cfg sm8550_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2472,6 +2926,7 @@ static const struct qmp_phy_cfg sm8650_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2517,6 +2972,7 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = { .dp_aux_init = qmp_v4_dp_aux_init, .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v3_configure_dp_clocks, .configure_dp_phy = qmp_v4_configure_dp_phy, .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, @@ -2527,6 +2983,52 @@ static const struct qmp_phy_cfg sm8750_usb3dpphy_cfg = { .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), }; +static const struct qmp_phy_cfg glymur_usb3dpphy_cfg = { + .offsets = &qmp_combo_usb43dp_offsets_v8, + + .serdes_tbl = glymur_usb43dp_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(glymur_usb43dp_serdes_tbl), + .tx_tbl = glymur_usb43dp_lalb_tbl, + .tx_tbl_num = ARRAY_SIZE(glymur_usb43dp_lalb_tbl), + .pcs_tbl = glymur_usb43dp_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_tbl), + .pcs_usb_tbl = glymur_usb43dp_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_usb_tbl), + .pcs_misc_tbl = glymur_usb43dp_pcs_misc_tbl, + .pcs_misc_tbl_num = ARRAY_SIZE(glymur_usb43dp_pcs_misc_tbl), + + .dp_serdes_tbl = qmp_v8_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl), + .dp_tx_tbl = qmp_v8_n3p_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v8_n3p_dp_tx_tbl), + + .serdes_tbl_rbr = qmp_v8_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qmp_v8_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qmp_v8_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr2), + .serdes_tbl_hbr3 = qmp_v8_dp_serdes_tbl_hbr3, + .serdes_tbl_hbr3_num = ARRAY_SIZE(qmp_v8_dp_serdes_tbl_hbr3), + + .swing_hbr_rbr = &qmp_dp_v6_voltage_swing_hbr_rbr, + .pre_emphasis_hbr_rbr = &qmp_dp_v6_pre_emphasis_hbr_rbr, + .swing_hbr3_hbr2 = &qmp_dp_v5_voltage_swing_hbr3_hbr2, + .pre_emphasis_hbr3_hbr2 = &qmp_dp_v5_pre_emphasis_hbr3_hbr2, + + .dp_aux_init = qmp_v8_dp_aux_init, + .configure_dp_tx = qmp_v4_configure_dp_tx, + .configure_dp_clocks = qmp_v8_configure_dp_clocks, + .configure_dp_phy = qmp_v8_configure_dp_phy, + .calibrate_dp_phy = qmp_v4_calibrate_dp_phy, + + .regs = qmp_v8_n3_usb43dpphy_regs_layout, + .reset_list = msm8996_usb3phy_reset_l, + .num_resets = ARRAY_SIZE(msm8996_usb3phy_reset_l), + .vreg_list = qmp_phy_vreg_refgen, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_refgen), +}; + static int qmp_combo_dp_serdes_init(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -2689,7 +3191,7 @@ static bool qmp_combo_configure_dp_mode(struct qmp_combo *qmp) return reverse; } -static int qmp_combo_configure_dp_clocks(struct qmp_combo *qmp) +static int qmp_v3_configure_dp_clocks(struct qmp_combo *qmp) { const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; u32 phy_vco_div; @@ -2736,7 +3238,7 @@ static int qmp_v3_configure_dp_phy(struct qmp_combo *qmp) writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX0_TX1_LANE_CTL); writel(0x05, qmp->dp_dp_phy + QSERDES_V3_DP_PHY_TX2_TX3_LANE_CTL); - ret = qmp_combo_configure_dp_clocks(qmp); + ret = qmp_v3_configure_dp_clocks(qmp); if (ret) return ret; @@ -2822,6 +3324,35 @@ static void qmp_v4_dp_aux_init(struct qmp_combo *qmp) qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); } +static void qmp_v8_dp_aux_init(struct qmp_combo *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_PSR_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_DP_CLAMP_EN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + /* Turn on BIAS current for PHY/PLL */ + writel(0x1c, qmp->dp_serdes + cfg->regs[QPHY_COM_BIAS_EN_CLKBUFLR_EN]); + + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + writel(0x06, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); + writel(0xb7, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); + qmp->dp_aux_cfg = 0; + + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | + PHY_AUX_REQ_ERR_MASK, + qmp->dp_dp_phy + QSERDES_V4_DP_PHY_AUX_INTERRUPT_MASK); +} + static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -2836,6 +3367,58 @@ static void qmp_v4_configure_dp_tx(struct qmp_combo *qmp) qmp_combo_configure_dp_swing(qmp); } +static int qmp_v8_configure_dp_clocks(struct qmp_combo *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 phy_vco_div; + unsigned long pixel_freq; + const struct qmp_phy_cfg *cfg = qmp->cfg; + + switch (dp_opts->link_rate) { + case 1620: + phy_vco_div = 0x4; + pixel_freq = 1620000000UL / 2; + break; + case 2700: + phy_vco_div = 0x2; + pixel_freq = 2700000000UL / 2; + break; + case 5400: + phy_vco_div = 0x4; + pixel_freq = 5400000000UL / 4; + break; + case 8100: + phy_vco_div = 0x3; + pixel_freq = 8100000000UL / 6; + break; + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + writel(phy_vco_div, qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_VCO_DIV]); + + /* disable core reset tsync */ + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + writel(0x04, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC); + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC); + writel(0x08, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_CYC); + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); + + writel(0x3e, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TSYNC_OVRD); + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL); + writel(0x05, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL); + writel(0x01, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_AUXLESS_CFG1); + writel(0x11, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LFPS_PERIOD); + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN0_DRV_LVL); + writel(0x1f, qmp->dp_dp_phy + QSERDES_V8_DP_PHY_LN1_DRV_LVL); + + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); + + return 0; +} + static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -2852,7 +3435,7 @@ static int qmp_v456_configure_dp_phy(struct qmp_combo *qmp) writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX0_TX1_LANE_CTL); writel(0x05, qmp->dp_dp_phy + QSERDES_V4_DP_PHY_TX2_TX3_LANE_CTL); - ret = qmp_combo_configure_dp_clocks(qmp); + ret = qmp->cfg->configure_dp_clocks(qmp); if (ret) return ret; @@ -2966,6 +3549,62 @@ static int qmp_v4_configure_dp_phy(struct qmp_combo *qmp) return 0; } +static int qmp_v8_configure_dp_phy(struct qmp_combo *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 bias0_en, drvr0_en, bias1_en, drvr1_en; + u32 status; + int ret; + + ret = qmp_v456_configure_dp_phy(qmp); + if (ret < 0) + return ret; + + if (dp_opts->lanes == 1) { + bias0_en = reverse ? 0x3e : 0x15; + bias1_en = reverse ? 0x15 : 0x3e; + drvr0_en = reverse ? 0x13 : 0x10; + drvr1_en = reverse ? 0x10 : 0x13; + } else if (dp_opts->lanes == 2) { + bias0_en = reverse ? 0x3f : 0x15; + bias1_en = reverse ? 0x15 : 0x3f; + drvr0_en = 0x10; + drvr1_en = 0x10; + } else { + bias0_en = 0x3f; + bias1_en = 0x3f; + drvr0_en = 0x34; + drvr1_en = 0x34; + } + + writel(drvr0_en, qmp->dp_tx + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); + writel(bias0_en, qmp->dp_tx + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); + writel(drvr1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_HIGHZ_DRVR_EN]); + writel(bias1_en, qmp->dp_tx2 + cfg->regs[QPHY_TX_TRANSCEIVER_BIAS_EN]); + + writel(0x08, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + udelay(100); + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + udelay(500); + + if (readl_poll_timeout(qmp->dp_dp_phy + cfg->regs[QPHY_DP_PHY_STATUS], + status, + ((status & BIT(1)) > 0), + 500, + 10000)) + return -ETIMEDOUT; + + writel(0x00, qmp->dp_tx + cfg->regs[QPHY_TX_TX_DRV_LVL]); + writel(0x00, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_DRV_LVL]); + + writel(0x2b, qmp->dp_tx + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); + writel(0x2b, qmp->dp_tx2 + cfg->regs[QPHY_TX_TX_EMP_POST1_LVL]); + + return 0; +} + /* * We need to calibrate the aux setting here as many times * as the caller tries @@ -3023,6 +3662,7 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) { const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *com = qmp->com; + void __iomem *pcs_aon = qmp->pcs_aon; int ret; u32 val; @@ -3058,10 +3698,20 @@ static int qmp_combo_com_init(struct qmp_combo *qmp, bool force) SW_DPPHY_RESET_MUX | SW_DPPHY_RESET | SW_USB3PHY_RESET_MUX | SW_USB3PHY_RESET); + /* override hardware control for reset of qmp phy */ + if (pcs_aon && cfg->regs[QPHY_AON_TOGGLE_ENABLE]) { + qphy_clrbits(pcs_aon, cfg->regs[QPHY_AON_TOGGLE_ENABLE], 0x1); + qphy_clrbits(pcs_aon, cfg->regs[QPHY_DP_AON_TOGGLE_ENABLE], 0x1); + } + /* Use software based port select and switch on typec orientation */ val = SW_PORTSELECT_MUX; if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) val |= SW_PORTSELECT_VAL; + + if (cfg->invert_cc_polarity) + val |= INVERT_CC_POLARITY; + writel(val, com + QPHY_V3_DP_COM_TYPEC_CTRL); switch (qmp->qmpphy_mode) { @@ -3235,6 +3885,8 @@ static int qmp_combo_usb_power_on(struct phy *phy) qmp_configure_lane(qmp->dev, rx2, cfg->rx_tbl, cfg->rx_tbl_num, 2); qmp_configure(qmp->dev, pcs, cfg->pcs_tbl, cfg->pcs_tbl_num); + qmp_configure(qmp->dev, qmp->pcs_misc, cfg->pcs_misc_tbl, cfg->pcs_misc_tbl_num); + if (pcs_usb) qmp_configure(qmp->dev, pcs_usb, cfg->pcs_usb_tbl, @@ -3361,6 +4013,7 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp) const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; void __iomem *pcs_misc = qmp->pcs_misc; + void __iomem *pcs_aon = qmp->pcs_aon; u32 intr_mask; if (qmp->phy_mode == PHY_MODE_USB_HOST_SS || @@ -3380,9 +4033,14 @@ static void qmp_combo_enable_autonomous_mode(struct qmp_combo *qmp) /* Enable required PHY autonomous mode interrupts */ qphy_setbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], intr_mask); - /* Enable i/o clamp_n for autonomous mode */ - if (pcs_misc) - qphy_clrbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + /* + * Enable i/o clamp_n for autonomous mode + * V6 and later versions use pcs aon clamp register + */ + if (pcs_aon) + qphy_clrbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + else if (pcs_misc) + qphy_clrbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); } static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp) @@ -3390,10 +4048,13 @@ static void qmp_combo_disable_autonomous_mode(struct qmp_combo *qmp) const struct qmp_phy_cfg *cfg = qmp->cfg; void __iomem *pcs_usb = qmp->pcs_usb ?: qmp->pcs; void __iomem *pcs_misc = qmp->pcs_misc; + void __iomem *pcs_aon = qmp->pcs_aon; /* Disable i/o clamp_n on resume for normal mode */ - if (pcs_misc) - qphy_setbits(pcs_misc, QPHY_V3_PCS_MISC_CLAMP_ENABLE, CLAMP_EN); + if (pcs_aon) + qphy_setbits(pcs_aon, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); + else if (pcs_misc) + qphy_setbits(pcs_misc, cfg->regs[QPHY_PCS_CLAMP_ENABLE], CLAMP_EN); qphy_clrbits(pcs_usb, cfg->regs[QPHY_PCS_AUTONOMOUS_MODE_CTRL], ARCVR_DTCT_EN | ARCVR_DTCT_EVENT_SEL | ALFPS_DTCT_EN); @@ -4058,6 +4719,8 @@ static int qmp_combo_parse_dt(struct qmp_combo *qmp) qmp->serdes = base + offs->usb3_serdes; qmp->pcs_misc = base + offs->usb3_pcs_misc; qmp->pcs = base + offs->usb3_pcs; + if (offs->usb3_pcs_aon) + qmp->pcs_aon = base + offs->usb3_pcs_aon; qmp->pcs_usb = base + offs->usb3_pcs_usb; qmp->dp_serdes = base + offs->dp_serdes; @@ -4319,6 +4982,10 @@ static int qmp_combo_probe(struct platform_device *pdev) } static const struct of_device_id qmp_combo_of_match_table[] = { + { + .compatible = "qcom,glymur-qmp-usb3-dp-phy", + .data = &glymur_usb3dpphy_cfg, + }, { .compatible = "qcom,sar2130p-qmp-usb3-dp-phy", .data = &sar2130p_usb3dpphy_cfg, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h new file mode 100644 index 000000000000..8b9572d3cdeb --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v2.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V2_H_ +#define QCOM_PHY_QMP_DP_PHY_V2_H_ + +// /* Only for QMP V2 PHY - DP PHY registers */ +#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK 0x048 +#define QSERDES_V2_DP_PHY_AUX_INTERRUPT_CLEAR 0x04c +#define QSERDES_V2_DP_PHY_AUX_BIST_CFG 0x050 + +#define QSERDES_V2_DP_PHY_VCO_DIV 0x068 +#define QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL 0x06c +#define QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL 0x088 + +#define QSERDES_V2_DP_PHY_SPARE0 0x0ac +#define QSERDES_V2_DP_PHY_STATUS 0x0c0 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h new file mode 100644 index 000000000000..b6a8ab59c2ff --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-phy-v8.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_DP_PHY_V8_H_ +#define QCOM_PHY_QMP_DP_PHY_V8_H_ + +/* Only for QMP V8 PHY - DP PHY registers */ +#define QSERDES_V8_DP_PHY_VCO_DIV 0x070 +#define QSERDES_V8_DP_PHY_AUX_INTERRUPT_STATUS 0x0e0 +#define QSERDES_V8_DP_PHY_TSYNC_OVRD 0x074 +#define QSERDES_V8_DP_PHY_TX0_TX1_LANE_CTL 0x078 +#define QSERDES_V8_DP_PHY_TX2_TX3_LANE_CTL 0x0bc +#define QSERDES_V8_DP_PHY_AUXLESS_CFG1 0x0c8 +#define QSERDES_V8_DP_PHY_LFPS_PERIOD 0x0d0 +#define QSERDES_V8_DP_PHY_LFPS_CYC 0x0d4 +#define QSERDES_V8_DP_PHY_AUXLESS_SETUP_CYC 0x0d8 +#define QSERDES_V8_DP_PHY_AUXLESS_SILENCE_CYC 0x0d8 +#define QSERDES_V8_DP_PHY_LN0_DRV_LVL 0x0e0 +#define QSERDES_V8_DP_PHY_LN1_DRV_LVL 0x0e4 +#define QSERDES_V8_DP_PHY_STATUS 0x114 + + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h new file mode 100644 index 000000000000..2bef1eecdc56 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-dp-qserdes-com-v8.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025 Linaro Ltd. + */ + +#ifndef QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ +#define QCOM_PHY_QMP_DP_QSERDES_COM_V8_H_ + +/* Only for DP QMP V8 PHY - QSERDES COM registers */ +#define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070 +#define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 +#define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 +#define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c +#define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 +#define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 +#define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088 +#define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 +#define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 +#define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 +#define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 +#define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac +#define DP_QSERDES_V8_COM_BG_TIMER 0x0bc +#define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0 +#define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4 +#define DP_QSERDES_V8_COM_SSC_PER1 0x0cc +#define DP_QSERDES_V8_COM_SSC_PER2 0x0d0 +#define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0 +#define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 +#define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 +#define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4 +#define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 +#define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118 +#define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120 +#define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c +#define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140 +#define DP_QSERDES_V8_COM_CLK_SELECT 0x164 +#define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170 +#define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174 +#define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180 +#define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4 +#define DP_QSERDES_V8_COM_CMN_STATUS 0x314 +#define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c index 86b1b7e2da86..fed2fc9bb311 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c @@ -37,6 +37,9 @@ #include "phy-qcom-qmp-pcs-pcie-v6_30.h" #include "phy-qcom-qmp-pcs-v6_30.h" #include "phy-qcom-qmp-pcie-qhp.h" +#include "phy-qcom-qmp-qserdes-com-v8.h" +#include "phy-qcom-qmp-pcs-pcie-v8.h" +#include "phy-qcom-qmp-qserdes-txrx-pcie-v8.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 @@ -100,6 +103,13 @@ static const unsigned int pciephy_v7_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V7_PCS_POWER_DOWN_CONTROL, }; +static const unsigned int pciephy_v8_regs_layout[QPHY_LAYOUT_SIZE] = { + [QPHY_SW_RESET] = QPHY_V8_PCS_SW_RESET, + [QPHY_START_CTRL] = QPHY_V8_PCS_START_CONTROL, + [QPHY_PCS_STATUS] = QPHY_V8_PCS_PCS_STATUS1, + [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V8_PCS_POWER_DOWN_CONTROL, +}; + static const unsigned int pciephy_v8_50_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_START_CTRL] = QPHY_V8_50_PCS_START_CONTROL, [QPHY_PCS_STATUS] = QPHY_V8_50_PCS_STATUS1, @@ -3067,6 +3077,149 @@ static const struct qmp_phy_init_tbl sar2130p_qmp_gen3x2_pcie_ep_pcs_misc_tbl[] QMP_PHY_INIT_CFG(QPHY_PCIE_V6_PCS_PCIE_POWER_STATE_CONFIG4, 0x07), }; +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0x93), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), + + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xf8), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x06), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0xab), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_ENABLE1, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYS_CLK_CTRL, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_EN, 0x46), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CLK_SELECT, 0x34), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0xa0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MISC_1, 0x88), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_MODE, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_DC_LEVEL_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_SPARE_FOR_ECO, 0x02), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_2, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_LANE_MODE_3, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_BAND1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_10B_8B, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_SEL_20B_10B, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN, 0x90), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2, 0x0d), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3, 0x53), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_TX_PHPRE_CTRL, 0x20), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS, 0x15), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL, 0x89), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4, 0x2d), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_ENABLES, 0x1c), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SIGDET_LVL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_BAND_CTRL0, 0x05), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_SVS_MODE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2, 0x42), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1, 0xc2), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0, 0xe4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1, 0x63), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2, 0xd8), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3, 0x99), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4, 0x67), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1, 0xa4), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2, 0x28), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3, 0x9f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4, 0x48), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5, 0x24), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_PCIE_RX_GM_CAL, 0x0d), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB, 0x17), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_SIGDET_LVL, 0xcc), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL, 0x40), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1, 0x04), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2, 0x02), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG4, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG5, 0x22), +}; + +static const struct qmp_phy_init_tbl kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_TX_RX_CONFIG, 0xc0), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2, 0x1d), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE, 0xc1), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS, 0x00), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_EQ_CONFIG1, 0x16), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME, 0x27), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5, 0x02), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_PRE_GAIN, 0x2e), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1, 0x03), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3, 0x28), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5, 0x0f), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5, 0xf2), + QMP_PHY_INIT_CFG(QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6, 0x1f), +}; + struct qmp_pcie_offsets { u16 serdes; u16 pcs; @@ -3363,6 +3516,16 @@ static const struct qmp_pcie_offsets qmp_pcie_offsets_v6_30 = { .ln_shrd = 0x8000, }; +static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_0 = { + .serdes = 0x1000, + .pcs = 0x1400, + .pcs_misc = 0x1800, + .tx = 0x0000, + .rx = 0x0200, + .tx2 = 0x0800, + .rx2 = 0x0a00, +}; + static const struct qmp_pcie_offsets qmp_pcie_offsets_v8_50 = { .serdes = 0x8000, .pcs = 0x9000, @@ -4425,6 +4588,34 @@ static const struct qmp_phy_cfg qmp_v6_gen4x4_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg qmp_v8_gen3x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v8_0, + + .tbls = { + .serdes = kaanapali_qmp_gen3x2_pcie_serdes_tbl, + .serdes_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_serdes_tbl), + .tx = kaanapali_qmp_gen3x2_pcie_tx_tbl, + .tx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_tx_tbl), + .rx = kaanapali_qmp_gen3x2_pcie_rx_tbl, + .rx_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_rx_tbl), + .pcs = kaanapali_qmp_gen3x2_pcie_pcs_tbl, + .pcs_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_tbl), + .pcs_misc = kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl, + .pcs_misc_num = ARRAY_SIZE(kaanapali_qmp_gen3x2_pcie_pcs_misc_tbl), + }, + + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = pciephy_v8_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS_4_20, +}; + static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { .lanes = 4, @@ -4441,6 +4632,22 @@ static const struct qmp_phy_cfg glymur_qmp_gen5x4_pciephy_cfg = { .phy_status = PHYSTATUS_4_20, }; +static const struct qmp_phy_cfg glymur_qmp_gen4x2_pciephy_cfg = { + .lanes = 2, + + .offsets = &qmp_pcie_offsets_v8_0, + + .reset_list = sdm845_pciephy_reset_l, + .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + + .regs = pciephy_v8_regs_layout, + + .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, + .phy_status = PHYSTATUS_4_20, +}; + static void qmp_pcie_init_port_b(struct qmp_pcie *qmp, const struct qmp_phy_cfg_tbls *tbls) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -5192,6 +5399,9 @@ static int qmp_pcie_probe(struct platform_device *pdev) static const struct of_device_id qmp_pcie_of_match_table[] = { { + .compatible = "qcom,glymur-qmp-gen4x2-pcie-phy", + .data = &glymur_qmp_gen4x2_pciephy_cfg, + }, { .compatible = "qcom,glymur-qmp-gen5x4-pcie-phy", .data = &glymur_qmp_gen5x4_pciephy_cfg, }, { @@ -5209,6 +5419,9 @@ static const struct of_device_id qmp_pcie_of_match_table[] = { }, { .compatible = "qcom,ipq9574-qmp-gen3x2-pcie-phy", .data = &ipq9574_gen3x2_pciephy_cfg, + }, { + .compatible = "qcom,kaanapali-qmp-gen3x2-pcie-phy", + .data = &qmp_v8_gen3x2_pciephy_cfg, }, { .compatible = "qcom,msm8998-qmp-pcie-phy", .data = &msm8998_pciephy_cfg, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h new file mode 100644 index 000000000000..52db31a7cf22 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v6.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_AON_V6_H_ +#define QCOM_PHY_QMP_PCS_AON_V6_H_ + +/* Only for QMP V6 PHY - PCS_AON registers */ +#define QPHY_V6_PCS_AON_CLAMP_ENABLE 0x00 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h new file mode 100644 index 000000000000..f6a275c0938f --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-aon-v8.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_AON_V8_H_ +#define QCOM_PHY_QMP_PCS_AON_V8_H_ + +/* Only for QMP V8 PHY - PCS_AON registers */ +#define QPHY_V8_PCS_AON_USB3_AON_CLAMP_ENABLE 0x00 +#define QPHY_V8_PCS_AON_USB4_AON_CLAMP_ENABLE 0x04 +#define QPHY_V8_PCS_AON_USB3_AON_TOGGLE_ENABLE 0x08 +#define QPHY_V8_PCS_AON_USB4_AON_TOGGLE_ENABLE 0x0c +#define QPHY_V8_PCS_AON_DP_AON_TOGGLE_ENABLE 0x10 +#define QPHY_V8_PCS_AON_DUMMY_STATUS 0x14 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h new file mode 100644 index 000000000000..77d04c6a1644 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v5.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_MISC_V5_H_ +#define QCOM_PHY_QMP_PCS_MISC_V5_H_ + +/* Only for QMP V5 PHY - PCS_MISC registers */ +#define QPHY_V5_PCS_MISC_CLAMP_ENABLE 0x0c + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h new file mode 100644 index 000000000000..a93ef2faa894 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-misc-v8.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_MISC_V8_H_ +#define QCOM_PHY_QMP_PCS_MISC_V8_H_ + +/* Only for QMP V8 PHY - PCS_MISC registers */ +#define QPHY_V8_PCS_MISC_PCS_MISC_CONFIG1 0x08 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h new file mode 100644 index 000000000000..1e06aa9d73d5 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcs-pcie-v8.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_PCS_PCIE_V8_H_ +#define QCOM_PHY_QMP_PCS_PCIE_V8_H_ + +/* Only for QMP V8 PHY - PCIE PCS registers */ + +#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG2 0x00c +#define QPHY_PCIE_V8_PCS_TX_RX_CONFIG 0x018 +#define QPHY_PCIE_V8_PCS_ENDPOINT_REFCLK_DRIVE 0x01c +#define QPHY_PCIE_V8_PCS_OSC_DTCT_ACTIONS 0x090 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG1 0x0a0 +#define QPHY_PCIE_V8_PCS_G3_RXEQEVAL_TIME 0x0f0 +#define QPHY_PCIE_V8_PCS_G4_RXEQEVAL_TIME 0x0f4 +#define QPHY_PCIE_V8_PCS_G4_EQ_CONFIG5 0x108 +#define QPHY_PCIE_V8_PCS_G4_PRE_GAIN 0x15c +#define QPHY_PCIE_V8_PCS_G12S1_TXDEEMPH_M6DB 0x170 +#define QPHY_PCIE_V8_PCS_G3S2_PRE_GAIN 0x178 +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG1 0x17c +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG3 0x184 +#define QPHY_PCIE_V8_PCS_RX_MARGINING_CONFIG5 0x18c +#define QPHY_PCIE_V8_PCS_RX_SIGDET_LVL 0x190 +#define QPHY_PCIE_V8_PCS_G3_FOM_EQ_CONFIG5 0x1ac +#define QPHY_PCIE_V8_PCS_ELECIDLE_DLY_SEL 0x1b8 +#define QPHY_PCIE_V8_PCS_G4_FOM_EQ_CONFIG5 0x1c0 +#define QPHY_PCIE_V8_PCS_POWER_STATE_CONFIG6 0x1d0 +#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG1 0x1dc +#define QPHY_PCIE_V8_PCS_PCS_TX_RX_CONFIG2 0x1e0 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG4 0x1f8 +#define QPHY_PCIE_V8_PCS_EQ_CONFIG5 0x1fc +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h new file mode 100644 index 000000000000..3ea1884f35dd --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v2.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_COM_V2_H_ +#define QCOM_PHY_QMP_QSERDES_COM_V2_H_ + +/* Only for QMP V2 PHY - QSERDES COM registers */ +#define QSERDES_V2_COM_ATB_SEL1 0x000 +#define QSERDES_V2_COM_ATB_SEL2 0x004 +#define QSERDES_V2_COM_FREQ_UPDATE 0x008 +#define QSERDES_V2_COM_BG_TIMER 0x00c +#define QSERDES_V2_COM_SSC_EN_CENTER 0x010 +#define QSERDES_V2_COM_SSC_ADJ_PER1 0x014 +#define QSERDES_V2_COM_SSC_ADJ_PER2 0x018 +#define QSERDES_V2_COM_SSC_PER1 0x01c +#define QSERDES_V2_COM_SSC_PER2 0x020 +#define QSERDES_V2_COM_SSC_STEP_SIZE1 0x024 +#define QSERDES_V2_COM_SSC_STEP_SIZE2 0x028 +#define QSERDES_V2_COM_POST_DIV 0x02c +#define QSERDES_V2_COM_POST_DIV_MUX 0x030 +#define QSERDES_V2_COM_BIAS_EN_CLKBUFLR_EN 0x034 +#define QSERDES_V2_COM_CLK_ENABLE1 0x038 +#define QSERDES_V2_COM_SYS_CLK_CTRL 0x03c +#define QSERDES_V2_COM_SYSCLK_BUF_ENABLE 0x040 +#define QSERDES_V2_COM_PLL_EN 0x044 +#define QSERDES_V2_COM_PLL_IVCO 0x048 +#define QSERDES_V2_COM_LOCK_CMP1_MODE0 0x04c +#define QSERDES_V2_COM_LOCK_CMP2_MODE0 0x050 +#define QSERDES_V2_COM_LOCK_CMP3_MODE0 0x054 +#define QSERDES_V2_COM_LOCK_CMP1_MODE1 0x058 +#define QSERDES_V2_COM_LOCK_CMP2_MODE1 0x05c +#define QSERDES_V2_COM_LOCK_CMP3_MODE1 0x060 +#define QSERDES_V2_COM_EP_CLOCK_DETECT_CTR 0x068 +#define QSERDES_V2_COM_SYSCLK_DET_COMP_STATUS 0x06c +#define QSERDES_V2_COM_CLK_EP_DIV 0x074 +#define QSERDES_V2_COM_CP_CTRL_MODE0 0x078 +#define QSERDES_V2_COM_CP_CTRL_MODE1 0x07c +#define QSERDES_V2_COM_PLL_RCTRL_MODE0 0x084 +#define QSERDES_V2_COM_PLL_RCTRL_MODE1 0x088 +#define QSERDES_V2_COM_PLL_CCTRL_MODE0 0x090 +#define QSERDES_V2_COM_PLL_CCTRL_MODE1 0x094 +#define QSERDES_V2_COM_PLL_CNTRL 0x09c +#define QSERDES_V2_COM_BIAS_EN_CTRL_BY_PSM 0x0a8 +#define QSERDES_V2_COM_SYSCLK_EN_SEL 0x0ac +#define QSERDES_V2_COM_CML_SYSCLK_SEL 0x0b0 +#define QSERDES_V2_COM_RESETSM_CNTRL 0x0b4 +#define QSERDES_V2_COM_RESETSM_CNTRL2 0x0b8 +#define QSERDES_V2_COM_LOCK_CMP_EN 0x0c8 +#define QSERDES_V2_COM_LOCK_CMP_CFG 0x0cc +#define QSERDES_V2_COM_DEC_START_MODE0 0x0d0 +#define QSERDES_V2_COM_DEC_START_MODE1 0x0d4 +#define QSERDES_V2_COM_VCOCAL_DEADMAN_CTRL 0x0d8 +#define QSERDES_V2_COM_DIV_FRAC_START1_MODE0 0x0dc +#define QSERDES_V2_COM_DIV_FRAC_START2_MODE0 0x0e0 +#define QSERDES_V2_COM_DIV_FRAC_START3_MODE0 0x0e4 +#define QSERDES_V2_COM_DIV_FRAC_START1_MODE1 0x0e8 +#define QSERDES_V2_COM_DIV_FRAC_START2_MODE1 0x0ec +#define QSERDES_V2_COM_DIV_FRAC_START3_MODE1 0x0f0 +#define QSERDES_V2_COM_VCO_TUNE_MINVAL1 0x0f4 +#define QSERDES_V2_COM_VCO_TUNE_MINVAL2 0x0f8 +#define QSERDES_V2_COM_INTEGLOOP_INITVAL 0x100 +#define QSERDES_V2_COM_INTEGLOOP_EN 0x104 +#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE0 0x108 +#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE0 0x10c +#define QSERDES_V2_COM_INTEGLOOP_GAIN0_MODE1 0x110 +#define QSERDES_V2_COM_INTEGLOOP_GAIN1_MODE1 0x114 +#define QSERDES_V2_COM_VCO_TUNE_MAXVAL1 0x118 +#define QSERDES_V2_COM_VCO_TUNE_MAXVAL2 0x11c +#define QSERDES_V2_COM_VCO_TUNE_CTRL 0x124 +#define QSERDES_V2_COM_VCO_TUNE_MAP 0x128 +#define QSERDES_V2_COM_VCO_TUNE1_MODE0 0x12c +#define QSERDES_V2_COM_VCO_TUNE2_MODE0 0x130 +#define QSERDES_V2_COM_VCO_TUNE1_MODE1 0x134 +#define QSERDES_V2_COM_VCO_TUNE2_MODE1 0x138 +#define QSERDES_V2_COM_VCO_TUNE_INITVAL1 0x13c +#define QSERDES_V2_COM_VCO_TUNE_INITVAL2 0x140 +#define QSERDES_V2_COM_VCO_TUNE_TIMER1 0x144 +#define QSERDES_V2_COM_VCO_TUNE_TIMER2 0x148 +#define QSERDES_V2_COM_CMN_STATUS 0x15c +#define QSERDES_V2_COM_RESET_SM_STATUS 0x160 +#define QSERDES_V2_COM_RESTRIM_CODE_STATUS 0x164 +#define QSERDES_V2_COM_PLLCAL_CODE1_STATUS 0x168 +#define QSERDES_V2_COM_PLLCAL_CODE2_STATUS 0x16c +#define QSERDES_V2_COM_CLK_SELECT 0x174 +#define QSERDES_V2_COM_HSCLK_SEL 0x178 +#define QSERDES_V2_COM_INTEGLOOP_BINCODE_STATUS 0x17c +#define QSERDES_V2_COM_PLL_ANALOG 0x180 +#define QSERDES_V2_COM_CORECLK_DIV 0x184 +#define QSERDES_V2_COM_SW_RESET 0x188 +#define QSERDES_V2_COM_CORE_CLK_EN 0x18c +#define QSERDES_V2_COM_C_READY_STATUS 0x190 +#define QSERDES_V2_COM_CMN_CONFIG 0x194 +#define QSERDES_V2_COM_CMN_RATE_OVERRIDE 0x198 +#define QSERDES_V2_COM_SVS_MODE_CLK_SEL 0x19c +#define QSERDES_V2_COM_DEBUG_BUS0 0x1a0 +#define QSERDES_V2_COM_DEBUG_BUS1 0x1a4 +#define QSERDES_V2_COM_DEBUG_BUS2 0x1a8 +#define QSERDES_V2_COM_DEBUG_BUS3 0x1ac +#define QSERDES_V2_COM_DEBUG_BUS_SEL 0x1b0 +#define QSERDES_V2_COM_CMN_MISC1 0x1b4 +#define QSERDES_V2_COM_CMN_MISC2 0x1b8 +#define QSERDES_V2_COM_CORECLK_DIV_MODE1 0x1bc + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h index d3b2292257bc..d8ac4c4a2c31 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-com-v8.h @@ -33,6 +33,7 @@ #define QSERDES_V8_COM_CP_CTRL_MODE0 0x070 #define QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 #define QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 +#define QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c #define QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 #define QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 #define QSERDES_V8_COM_DEC_START_MODE0 0x088 @@ -40,6 +41,7 @@ #define QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 #define QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 #define QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 +#define QSERDES_V8_COM_HSCLK_HS_SWITCH_SEL_1 0x09c #define QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 #define QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac #define QSERDES_V8_COM_BG_TIMER 0x0bc @@ -47,13 +49,22 @@ #define QSERDES_V8_COM_SSC_PER1 0x0cc #define QSERDES_V8_COM_SSC_PER2 0x0d0 #define QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define QSERDES_V8_COM_CLK_ENABLE1 0x0e0 +#define QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 +#define QSERDES_V8_COM_PLL_IVCO 0x0f4 #define QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 #define QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 #define QSERDES_V8_COM_RESETSM_CNTRL 0x118 +#define QSERDES_V8_COM_LOCK_CMP_EN 0x120 #define QSERDES_V8_COM_LOCK_CMP_CFG 0x124 #define QSERDES_V8_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V8_COM_CLK_SELECT 0x164 #define QSERDES_V8_COM_CORE_CLK_EN 0x170 #define QSERDES_V8_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V8_COM_CMN_MISC_1 0x184 +#define QSERDES_V8_COM_CMN_MODE 0x188 +#define QSERDES_V8_COM_VCO_DC_LEVEL_CTRL 0x198 +#define QSERDES_V8_COM_PLL_SPARE_FOR_ECO 0x2b4 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a4 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2 0x1a8 #define QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3 0x1ac diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h new file mode 100644 index 000000000000..93edabb830af --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-dp-com-v8.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2025 Linaro Ltd. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_DP_COM_V8_H_ +#define QCOM_PHY_QMP_QSERDES_DP_COM_V8_H_ + +/* Only for DP QMP V8 PHY - QSERDES COM registers */ +#define DP_QSERDES_V8_COM_HSCLK_SEL_1 0x03c +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define DP_QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define DP_QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define DP_QSERDES_V8_COM_CP_CTRL_MODE0 0x070 +#define DP_QSERDES_V8_COM_PLL_RCTRL_MODE0 0x074 +#define DP_QSERDES_V8_COM_PLL_CCTRL_MODE0 0x078 +#define DP_QSERDES_V8_COM_CORECLK_DIV_MODE0 0x07c +#define DP_QSERDES_V8_COM_LOCK_CMP1_MODE0 0x080 +#define DP_QSERDES_V8_COM_LOCK_CMP2_MODE0 0x084 +#define DP_QSERDES_V8_COM_DEC_START_MODE0 0x088 +#define DP_QSERDES_V8_COM_DIV_FRAC_START1_MODE0 0x090 +#define DP_QSERDES_V8_COM_DIV_FRAC_START2_MODE0 0x094 +#define DP_QSERDES_V8_COM_DIV_FRAC_START3_MODE0 0x098 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 +#define DP_QSERDES_V8_COM_VCO_TUNE1_MODE0 0x0a8 +#define DP_QSERDES_V8_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 +#define DP_QSERDES_V8_COM_VCO_TUNE2_MODE0 0x0ac +#define DP_QSERDES_V8_COM_BG_TIMER 0x0bc +#define DP_QSERDES_V8_COM_SSC_EN_CENTER 0x0c0 +#define DP_QSERDES_V8_COM_SSC_ADJ_PER1 0x0c4 +#define DP_QSERDES_V8_COM_SSC_PER1 0x0cc +#define DP_QSERDES_V8_COM_SSC_PER2 0x0d0 +#define DP_QSERDES_V8_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define DP_QSERDES_V8_COM_CLK_ENABLE1 0x0e0 +#define DP_QSERDES_V8_COM_SYS_CLK_CTRL 0x0e4 +#define DP_QSERDES_V8_COM_SYSCLK_BUF_ENABLE 0x0e8 +#define DP_QSERDES_V8_COM_PLL_IVCO 0x0f4 +#define DP_QSERDES_V8_COM_SYSCLK_EN_SEL 0x110 +#define DP_QSERDES_V8_COM_RESETSM_CNTRL 0x118 +#define DP_QSERDES_V8_COM_LOCK_CMP_EN 0x120 +#define DP_QSERDES_V8_COM_VCO_TUNE_CTRL 0x13c +#define DP_QSERDES_V8_COM_VCO_TUNE_MAP 0x140 +#define DP_QSERDES_V8_COM_CLK_SELECT 0x164 +#define DP_QSERDES_V8_COM_CORE_CLK_EN 0x170 +#define DP_QSERDES_V8_COM_CMN_CONFIG_1 0x174 +#define DP_QSERDES_V8_COM_SVS_MODE_CLK_SEL 0x180 +#define DP_QSERDES_V8_COM_CLK_FWD_CONFIG_1 0x2f4 +#define DP_QSERDES_V8_COM_CMN_STATUS 0x314 +#define DP_QSERDES_V8_COM_C_READY_STATUS 0x33c + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h new file mode 100644 index 000000000000..60ba730620f8 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-lalb-v8.h @@ -0,0 +1,639 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_V8_LALBH_ +#define QCOM_PHY_QMP_QSERDES_V8_LALBH_ + +#define QSERDES_V8_LALB_BIST_MODE_LANENO 0x0 +#define QSERDES_V8_LALB_BIST_INVERT 0x4 +#define QSERDES_V8_LALB_PERL_LENGTH1 0x8 +#define QSERDES_V8_LALB_PERL_LENGTH2 0xc +#define QSERDES_V8_LALB_BIST_PATTERN1 0x10 +#define QSERDES_V8_LALB_BIST_PATTERN2 0x14 +#define QSERDES_V8_LALB_BIST_PATTERN3 0x18 +#define QSERDES_V8_LALB_BIST_PATTERN4 0x1c +#define QSERDES_V8_LALB_BIST_PATTERN5 0x20 +#define QSERDES_V8_LALB_BIST_PATTERN6 0x24 +#define QSERDES_V8_LALB_BIST_PATTERN7 0x28 +#define QSERDES_V8_LALB_BIST_PATTERN8 0x2c +#define QSERDES_V8_LALB_PRBS_SEED1 0x30 +#define QSERDES_V8_LALB_PRBS_SEED2 0x34 +#define QSERDES_V8_LALB_PRBS_SEED3 0x38 +#define QSERDES_V8_LALB_PRBS_SEED4 0x3c +#define QSERDES_V8_LALB_PRBS_SEED5 0x40 +#define QSERDES_V8_LALB_PRBS_SEED6 0x44 +#define QSERDES_V8_LALB_PRBS_SEED7 0x48 +#define QSERDES_V8_LALB_SW_RESET_PWRDNB 0x4c +#define QSERDES_V8_LALB_RESET_GEN 0x50 +#define QSERDES_V8_LALB_RESET_TSYNC_EN_CTRL 0x54 +#define QSERDES_V8_LALB_CDR_EN_RXEQ_RESET 0x58 +#define QSERDES_V8_LALB_CLKBUF_ENABLE 0x5c +#define QSERDES_V8_LALB_TX0_EMP_POST1_LVL 0x60 +#define QSERDES_V8_LALB_TX1_EMP_POST1_LVL 0x64 +#define QSERDES_V8_LALB_TX0_IDLE_CTRL 0x68 +#define QSERDES_V8_LALB_TX1_IDLE_CTRL 0x6c +#define QSERDES_V8_LALB_TX0_DRV_LVL 0x70 +#define QSERDES_V8_LALB_TX0_DRV_LVL_OFFSET 0x74 +#define QSERDES_V8_LALB_TX1_DRV_LVL 0x78 +#define QSERDES_V8_LALB_TX1_DRV_LVL_OFFSET 0x7c +#define QSERDES_V8_LALB_TRAN_DRVR_EMP_EN 0x80 +#define QSERDES_V8_LALB_TX_LVL_UPDATE_CTRL 0x84 +#define QSERDES_V8_LALB_TX0_PRE1_EMPH 0x88 +#define QSERDES_V8_LALB_TX1_PRE1_EMPH 0x8c +#define QSERDES_V8_LALB_TX0_PRE2_EMPH 0x90 +#define QSERDES_V8_LALB_TX1_PRE2_EMPH 0x94 +#define QSERDES_V8_LALB_STALL_LDO_BOOST_EN 0x98 +#define QSERDES_V8_LALB_PRE_EMPH_EN_CTRL 0x9c +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL1 0xa0 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL2 0xa4 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL3 0xa8 +#define QSERDES_V8_LALB_PCIE5_TOP_LDO_CODE_CTRL4 0xac +#define QSERDES_V8_LALB_TRANSMITTER_EN_CTRL 0xb0 +#define QSERDES_V8_LALB_HIGHZ_DRVR_EN 0xb4 +#define QSERDES_V8_LALB_TX_MISC_CTRL1 0xb8 +#define QSERDES_V8_LALB_LPB_EN_CTRL1 0xbc +#define QSERDES_V8_LALB_LBP_EN_CTRL2 0xc0 +#define QSERDES_V8_LALB_TX0_SERDES_BYP_CTRL 0xc4 +#define QSERDES_V8_LALB_TX1_SERDES_BYP_CTRL 0xc8 +#define QSERDES_V8_LALB_LANE_MODE_1 0xcc +#define QSERDES_V8_LALB_LANE_MODE_2 0xd0 +#define QSERDES_V8_LALB_LANE_MODE_3 0xd4 +#define QSERDES_V8_LALB_LANE_MODE_4 0xd8 +#define QSERDES_V8_LALB_ATB_SEL1 0xdc +#define QSERDES_V8_LALB_ATB_SEL2 0xe0 +#define QSERDES_V8_LALB_TX0_RES_CODE_LANE 0xe4 +#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_OVRD 0xe8 +#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_CTRL 0xec +#define QSERDES_V8_LALB_TX0_RESTRIM_INIT_CODE 0xf0 +#define QSERDES_V8_LALB_TX0_RESTRIM_POST_CAL_OFFSET 0xf4 +#define QSERDES_V8_LALB_TX1_RES_CODE_LANE 0xf8 +#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_OVRD 0xfc +#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_CTRL 0x100 +#define QSERDES_V8_LALB_TX1_RESTRIM_INIT_CODE 0x104 +#define QSERDES_V8_LALB_TX1_RESTRIM_POST_CAL_OFFSET 0x108 +#define QSERDES_V8_LALB_TX0_RESTRIM_VREF_SEL 0x10c +#define QSERDES_V8_LALB_TX1_RESTRIM_VREF_SEL 0x110 +#define QSERDES_V8_LALB_VMODE_CTRL1 0x114 +#define QSERDES_V8_LALB_SLEW_CNTL_RATE01 0x118 +#define QSERDES_V8_LALB_SLEW_CNTL_RATE23 0x11c +#define QSERDES_V8_LALB_SLEW_CNTL_RATE4 0x120 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT1 0x124 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT2 0x128 +#define QSERDES_V8_LALB_ANA_INTERFACE_SELECT3 0x12c +#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT1 0x130 +#define QSERDES_V8_LALB_PCS_INTERFACE_SELECT2 0x134 +#define QSERDES_V8_LALB_LDO_TIMER_CTRL 0x138 +#define QSERDES_V8_LALB_AC_JTAG_ENABLE 0x13c +#define QSERDES_V8_LALB_AC_JTAG_INITP 0x140 +#define QSERDES_V8_LALB_AC_JTAG_INITN 0x144 +#define QSERDES_V8_LALB_AC_JTAG_LVL 0x148 +#define QSERDES_V8_LALB_AC_JTAG_MODE 0x14c +#define QSERDES_V8_LALB_AC_JTAG_RESET 0x150 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B0 0x154 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B1 0x158 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B2 0x15c +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B3 0x160 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B4 0x164 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B5 0x168 +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B6 0x16c +#define QSERDES_V8_LALB_RX_MODE_RATE_0_1_B7 0x170 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B0 0x174 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B1 0x178 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B2 0x17c +#define QSERDES_V8_LALB_RX_MODE_RATE2_B3 0x180 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B4 0x184 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B5 0x188 +#define QSERDES_V8_LALB_RX_MODE_RATE2_B6 0x18c +#define QSERDES_V8_LALB_RX_MODE_RATE2_B7 0x190 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B0 0x194 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B1 0x198 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B2 0x19c +#define QSERDES_V8_LALB_RX_MODE_RATE3_B3 0x1a0 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B4 0x1a4 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B5 0x1a8 +#define QSERDES_V8_LALB_RX_MODE_RATE3_B6 0x1ac +#define QSERDES_V8_LALB_RX_MODE_RATE3_B7 0x1b0 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B0 0x1b4 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B1 0x1b8 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B2 0x1bc +#define QSERDES_V8_LALB_RX_MODE_RATE4_B3 0x1c0 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B4 0x1c4 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B5 0x1c8 +#define QSERDES_V8_LALB_RX_MODE_RATE4_B6 0x1cc +#define QSERDES_V8_LALB_RX_MODE_RATE4_B7 0x1d0 +#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL1 0x1d4 +#define QSERDES_V8_LALB_TX_DCC_ANA_CTRL2 0x1d8 +#define QSERDES_V8_LALB_CMUX_DCC_CTRL1 0x1dc +#define QSERDES_V8_LALB_CMUX_DCC_POSTCAL_OFFSET 0x1e0 +#define QSERDES_V8_LALB_CMUX_DCC_OVRD 0x1e4 +#define QSERDES_V8_LALB_TX_DCC_CTRL 0x1e8 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_CONFIG 0x1ec +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_POSTCAL_OFFSET 0x1f0 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_OVRD 0x1f4 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_CONFIG 0x1f8 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x1fc +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_CONFIG 0x200 +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x204 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_CONFIG 0x208 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_POSTCAL_OFFSET 0x20c +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_OVRD 0x210 +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_CONFIG 0x214 +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_OFFSET_AND_OVRD 0x218 +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_CONFIG 0x21c +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_OFFSET_AND_OVRD 0x220 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CTRL 0x224 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE0 0x228 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE1 0x22c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE2 0x230 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE3 0x234 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_CODE_OVRD_RATE4 0x238 +#define QSERDES_V8_LALB_CDR_VCO_CAL_CTRL 0x23c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE0 0x240 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE0 0x244 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE1 0x248 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE1 0x24c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE2 0x250 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE2 0x254 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE3 0x258 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE3 0x25c +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT1_RATE4 0x260 +#define QSERDES_V8_LALB_CDR_VCO_CTUNE_MEAS_CNT2_RATE4 0x264 +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_0_1 0x268 +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_2_3 0x26c +#define QSERDES_V8_LALB_CDR_VCTRL_RATE_4 0x270 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_0_1 0x274 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_2_3 0x278 +#define QSERDES_V8_LALB_KVCO_INIT_RATE_4 0x27c +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE0 0x280 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE1 0x284 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE2 0x288 +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE3 0x28c +#define QSERDES_V8_LALB_KVCO_CODE_OVRD_RATE4 0x290 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_0_1 0x294 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_2_3 0x298 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_HIGH_RATE_4 0x29c +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_0_1 0x2a0 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_2_3 0x2a4 +#define QSERDES_V8_LALB_KVCO_CAL_VCTRL_LOW_RATE_4 0x2a8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE0 0x2ac +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE0 0x2b0 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE1 0x2b4 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE1 0x2b8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE2 0x2bc +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE2 0x2c0 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE3 0x2c4 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE3 0x2c8 +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF1_RATE4 0x2cc +#define QSERDES_V8_LALB_KVCO_IDEAL_FREQ_DIFF2_RATE4 0x2d0 +#define QSERDES_V8_LALB_KP_CDR_UP_DN 0x2d4 +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_0_1 0x2d8 +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE_2_3 0x2dc +#define QSERDES_V8_LALB_KP_CODE_OVRD_RATE4 0x2e0 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE0 0x2e4 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE0 0x2e8 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE1 0x2ec +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE1 0x2f0 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE2 0x2f4 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE2 0x2f8 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE3 0x2fc +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE3 0x300 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND1_RATE4 0x304 +#define QSERDES_V8_LALB_KP_CAL_UPPER_FREQ_DIFF_BND2_RATE4 0x308 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE0 0x30c +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE1 0x310 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE2 0x314 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE3 0x318 +#define QSERDES_V8_LALB_KP_CAL_LOWER_FREQ_DIFF_BND_RATE4 0x31c +#define QSERDES_V8_LALB_CDR_KVCO_KP_CAL_FREQ_MEAS_CTRL 0x320 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CTRL 0x324 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT1 0x328 +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT2 0x32c +#define QSERDES_V8_LALB_PLLLOCK_CMP_DEBUG_CNT3 0x330 +#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_0123 0x334 +#define QSERDES_V8_LALB_RX_SUMMER_CAL_SPD_MODE_RATE_4 0x338 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE0 0x33c +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE1 0x340 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE2 0x344 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE3 0x348 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CODE_OVERRIDE_RATE4 0x34c +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL1 0x350 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL2 0x354 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL3 0x358 +#define QSERDES_V8_LALB_RX_IVCM_CAL_CTRL4 0x35c +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE0 0x360 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE1 0x364 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE2 0x368 +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE3 0x36c +#define QSERDES_V8_LALB_RX_IVCM_POSTCAL_OFFSET_RATE4 0x370 +#define QSERDES_V8_LALB_RX_IDAC_I0_DC_OFFSETS 0x374 +#define QSERDES_V8_LALB_RX_IDAC_I0BAR_DC_OFFSETS 0x378 +#define QSERDES_V8_LALB_RX_IDAC_I1_DC_OFFSETS 0x37c +#define QSERDES_V8_LALB_RX_IDAC_I1BAR_DC_OFFSETS 0x380 +#define QSERDES_V8_LALB_RX_IDAC_Q_DC_OFFSETS 0x384 +#define QSERDES_V8_LALB_RX_IDAC_QBAR_DC_OFFSETS 0x388 +#define QSERDES_V8_LALB_RX_IDAC_A_DC_OFFSETS 0x38c +#define QSERDES_V8_LALB_RX_IDAC_ABAR_DC_OFFSETS 0x390 +#define QSERDES_V8_LALB_RX_IDAC_EN 0x394 +#define QSERDES_V8_LALB_DATA_SLICER_INIT_TIMER_CTRL 0x398 +#define QSERDES_V8_LALB_RX_IDAC_ENABLES 0x39c +#define QSERDES_V8_LALB_RX_IDAC_SIGN 0x3a0 +#define QSERDES_V8_LALB_RX_IDAC_TSETTLE 0x3a4 +#define QSERDES_V8_LALB_SIGDET_ENABLES 0x3a8 +#define QSERDES_V8_LALB_SIGDET_CNTRL 0x3ac +#define QSERDES_V8_LALB_SIGDET_LVL 0x3b0 +#define QSERDES_V8_LALB_SIGDET_DEGLITCH_CNTRL 0x3b4 +#define QSERDES_V8_LALB_SIGDET_CAL_CTRL1 0x3b8 +#define QSERDES_V8_LALB_SIGDET_CAL_CTRL2_AND_CDR_LOCK_EDGE 0x3bc +#define QSERDES_V8_LALB_SIGDET_CAL_TRIM 0x3c0 +#define QSERDES_V8_LALB_IA_OFFSET_CENTER_CAL_CTRL 0x3c4 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE0 0x3c8 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE1 0x3cc +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE2 0x3d0 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE3 0x3d4 +#define QSERDES_V8_LALB_FREQ_LOCK_DET_DLY_RATE4 0x3d8 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE0 0x3dc +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE1 0x3e0 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE2 0x3e4 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE3 0x3e8 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_RATE4 0x3ec +#define QSERDES_V8_LALB_CDR_LOCK_CTRL 0x3f0 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE0 0x3f4 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE1 0x3f8 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE2 0x3fc +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE3 0x400 +#define QSERDES_V8_LALB_CDR_CP_CUR_FLL_RATE4 0x404 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE0 0x408 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE1 0x40c +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE2 0x410 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE3 0x414 +#define QSERDES_V8_LALB_CDR_CP_CUR_PLL_RATE4 0x418 +#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE_0123 0x41c +#define QSERDES_V8_LALB_CDR_FLL_DIV_RATIO_RATE4 0x420 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_01 0x424 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE_23 0x428 +#define QSERDES_V8_LALB_CDR_LOOP_CCODE_RATE4 0x42c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_0_1 0x430 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE_2_3 0x434 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FAST_RATE4 0x438 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_0_1 0x43c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE_2_3 0x440 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_FLL_RATE4 0x444 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_0_1 0x448 +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE_2_3 0x44c +#define QSERDES_V8_LALB_CDR_LOOP_RCODE_PLL_RATE4 0x450 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE_0123 0x454 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_RATE4 0x458 +#define QSERDES_V8_LALB_CDR_VCO_TYPE_CONFIG 0x45c +#define QSERDES_V8_LALB_CDR_VCO_EN_LOWFREQ 0x460 +#define QSERDES_V8_LALB_CDR_FAST_SLOW_VCO_OVRD 0x464 +#define QSERDES_V8_LALB_CDR_LOOP_FUNC_CTRL 0x468 +#define QSERDES_V8_LALB_CDR_FAST_LOCK_EN_CTRL 0x46c +#define QSERDES_V8_LALB_RX_RCVR_EN 0x470 +#define QSERDES_V8_LALB_LANE_RATE_CTRL 0x474 +#define QSERDES_V8_LALB_RX_TERM_RCVR_CTRL 0x478 +#define QSERDES_V8_LALB_REC_DETECT_CTRL 0x47c +#define QSERDES_V8_LALB_RCV_DETECT_LVL 0x480 +#define QSERDES_V8_LALB_GM_CAL_EN 0x484 +#define QSERDES_V8_LALB_GM_CAL_RES_RATE0_1 0x488 +#define QSERDES_V8_LALB_GM_CAL_RES_RATE2_3 0x48c +#define QSERDES_V8_LALB_GM_CAL_RES_RATE4 0x490 +#define QSERDES_V8_LALB_RX_TERM_BW_RATE_0123 0x494 +#define QSERDES_V8_LALB_RX_TERM_BW_RATE4 0x498 +#define QSERDES_V8_LALB_AUX_CLK_CTRL 0x49c +#define QSERDES_V8_LALB_AUX_OFFSET_CONTROL 0x4a0 +#define QSERDES_V8_LALB_AUXDATA_TB 0x4a4 +#define QSERDES_V8_LALB_EOM_CTRL1 0x4a8 +#define QSERDES_V8_LALB_EOM_CTRL2 0x4ac +#define QSERDES_V8_LALB_EOM_CTRL3 0x4b0 +#define QSERDES_V8_LALB_EOM_CTRL4 0x4b4 +#define QSERDES_V8_LALB_DFE_EN_TIMER 0x4b8 +#define QSERDES_V8_LALB_RX_EQ_OFFSET_LSB 0x4bc +#define QSERDES_V8_LALB_RX_EQ_OFFSET_MSB 0x4c0 +#define QSERDES_V8_LALB_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x4c4 +#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL2 0x4c8 +#define QSERDES_V8_LALB_RX_OFFSET_ADAPTOR_CNTRL3 0x4cc +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL1 0x4d0 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL2 0x4d4 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL3 0x4d8 +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL4 0x4dc +#define QSERDES_V8_LALB_RX_EQU_ADAPTOR_CNTRL5 0x4e0 +#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_LSB 0x4e4 +#define QSERDES_V8_LALB_RX_EQU_KEQ_UP_MSB 0x4e8 +#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_LSB 0x4ec +#define QSERDES_V8_LALB_RX_EQU_KEQ_DN_MSB 0x4f0 +#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_0_1_2 0x4f4 +#define QSERDES_V8_LALB_CTLE_ADP_RESET_INIT_CODE_RATE_3_4 0x4f8 +#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_0_1_2 0x4fc +#define QSERDES_V8_LALB_CTLE_POST_CAL_OFFSET_RATE_3_4 0x500 +#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK1 0x504 +#define QSERDES_V8_LALB_RX_VGA_GAIN2_BLK2 0x508 +#define QSERDES_V8_LALB_VGA_CAL_CNTRL1 0x50c +#define QSERDES_V8_LALB_VGA_CAL_CNTRL2 0x510 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE0_1 0x514 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE2_3 0x518 +#define QSERDES_V8_LALB_VGA_CAL_MAN_VAL_RATE4 0x51c +#define QSERDES_V8_LALB_KVGA_CTRL1 0x520 +#define QSERDES_V8_LALB_KVGA_CTRL2 0x524 +#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL1 0x528 +#define QSERDES_V8_LALB_VTHRESH_CAL_CNTRL2 0x52c +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE0 0x530 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE1 0x534 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE2 0x538 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE3 0x53c +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_VAL_RATE4 0x540 +#define QSERDES_V8_LALB_VTHRESH_CAL_MAN_CAL_PAM3 0x544 +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_0_1 0x548 +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE_2_3 0x54c +#define QSERDES_V8_LALB_VTH_POST_CAL_OFFSET_RATE4 0x550 +#define QSERDES_V8_LALB_DFE_TAP1_CTRL 0x554 +#define QSERDES_V8_LALB_DFE_TAP1_MANVAL_KTAP 0x558 +#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_0_1_2 0x55c +#define QSERDES_V8_LALB_DFE_TAP1_POST_CAL_OFFSET_RATE_3_4 0x560 +#define QSERDES_V8_LALB_DFE_TAP2_CTRL 0x564 +#define QSERDES_V8_LALB_DFE_TAP2_MANVAL_KTAP 0x568 +#define QSERDES_V8_LALB_DFE_TAP3_CTRL 0x56c +#define QSERDES_V8_LALB_DFE_TAP3_MANVAL_KTAP 0x570 +#define QSERDES_V8_LALB_DFE_TAP4_CTRL 0x574 +#define QSERDES_V8_LALB_DFE_TAP4_MANVAL_KTAP 0x578 +#define QSERDES_V8_LALB_DFE_TAP5_CTRL 0x57c +#define QSERDES_V8_LALB_DFE_TAP5_MANVAL_KTAP 0x580 +#define QSERDES_V8_LALB_DFE_TAP6_CTRL 0x584 +#define QSERDES_V8_LALB_DFE_TAP6_MANVAL_KTAP 0x588 +#define QSERDES_V8_LALB_DFE_TAP7_CTRL 0x58c +#define QSERDES_V8_LALB_DFE_TAP7_MANVAL_KTAP 0x590 +#define QSERDES_V8_LALB_DFE_TAP1_DAC_ENABLE 0x594 +#define QSERDES_V8_LALB_DFE_TAP2_DAC_ENABLE 0x598 +#define QSERDES_V8_LALB_DFE_TAP345_DAC_ENABLE 0x59c +#define QSERDES_V8_LALB_DFE_TAP67_DAC_ENABLE 0x5a0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CTRL 0x5a4 +#define QSERDES_V8_LALB_CDR_IQTUNE_GAIN 0x5a8 +#define QSERDES_V8_LALB_CDR_IQTUNE_MAN_INDEX 0x5ac +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL1 0x5b0 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CAL_CTRL2 0x5b4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE0 0x5b8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE1 0x5bc +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE2 0x5c0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE3 0x5c4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK0_CAL_CODE_RATE4 0x5c8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE0 0x5cc +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE1 0x5d0 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE2 0x5d4 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE3 0x5d8 +#define QSERDES_V8_LALB_CDR_IQTUNE_CLK90_CAL_CODE_RATE4 0x5dc +#define QSERDES_V8_LALB_CDR_IQTUNE_ANA_CTRL 0x5e0 +#define QSERDES_V8_LALB_CDR_IQTUNE_VDCC_CTRL 0x5e4 +#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE0123 0x5e8 +#define QSERDES_V8_LALB_CDR_IQTUNE_DIV2_CTRL_RATE4 0x5ec +#define QSERDES_V8_LALB_BLW_CTRL 0x5f0 +#define QSERDES_V8_LALB_BLW_ANA_VER_CTRL 0x5f4 +#define QSERDES_V8_LALB_BLW_GAIN_CAL_CTRL 0x5f8 +#define QSERDES_V8_LALB_BLW_GAIN_FORCE_CODE 0x5fc +#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE3 0x600 +#define QSERDES_V8_LALB_BLW_MAN_VAL_RATE4 0x604 +#define QSERDES_V8_LALB_IVTH_CAL_CTRL1 0x608 +#define QSERDES_V8_LALB_IVTH_CAL_CTRL2 0x60c +#define QSERDES_V8_LALB_IVTH_CAL_CTRL3 0x610 +#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_VAL 0x614 +#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_VAL 0x618 +#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_VAL 0x61c +#define QSERDES_V8_LALB_IVTH_CAL_VAL_OVRD_MUX 0x620 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_OVRD_MUXES 0x624 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE0 0x628 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE1 0x62c +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE2 0x630 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE3 0x634 +#define QSERDES_V8_LALB_VCO_CTUNE_LOWER_BND_RATE4 0x638 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE0 0x63c +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE1 0x640 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE2 0x644 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE3 0x648 +#define QSERDES_V8_LALB_VCO_CTUNE_UPPER_BND_RATE4 0x64c +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE0 0x650 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE1 0x654 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE2 0x658 +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE3 0x65c +#define QSERDES_V8_LALB_CDR_LOCK_KVCO_OFFSET_RATE4 0x660 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE0 0x664 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE1 0x668 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE2 0x66c +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE3 0x670 +#define QSERDES_V8_LALB_CDR_LOCK_KP_OFFSET_RATE4 0x674 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE0 0x678 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE1 0x67c +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE2 0x680 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE3 0x684 +#define QSERDES_V8_LALB_CDR_FASTLOCK_CP_CUR_PLL_RATE4 0x688 +#define QSERDES_V8_LALB_DEBUG_BUS_SEL 0x68c +#define QSERDES_V8_LALB_BIST_STATUS 0x690 +#define QSERDES_V8_LALB_BIST_ERROR_COUNT1 0x694 +#define QSERDES_V8_LALB_BIST_ERROR_COUNT2 0x698 +#define QSERDES_V8_LALB_AC_JTAG_OUTP 0x69c +#define QSERDES_V8_LALB_AC_JTAG_OUTN 0x6a0 +#define QSERDES_V8_LALB_DATA_SLICER_DEBUG_STATUS 0x6a4 +#define QSERDES_V8_LALB_DATA_SLICER_TIMER1_STATUS 0x6a8 +#define QSERDES_V8_LALB_DATA_SLICER_TIMER2_STATUS 0x6ac +#define QSERDES_V8_LALB_TX0_RESTRIM_CODE_STATUS 0x6b0 +#define QSERDES_V8_LALB_TX0_RESTRIM_ICAL_CODE_STATUS 0x6b4 +#define QSERDES_V8_LALB_TX0_RESTRIM_CAL_STATUS 0x6b8 +#define QSERDES_V8_LALB_TX1_RESTRIM_CODE_STATUS 0x6bc +#define QSERDES_V8_LALB_TX1_RESTRIM_ICAL_CODE_STATUS 0x6c0 +#define QSERDES_V8_LALB_TX1_RESTRIM_CAL_STATUS 0x6c4 +#define QSERDES_V8_LALB_CMUX_DCC_CAL_FSM_STATUS 0x6c8 +#define QSERDES_V8_LALB_CMUX_DCC_READCODE_STATUS 0x6cc +#define QSERDES_V8_LALB_TX_DCC_CAL_ANA_STATUS 0x6d0 +#define QSERDES_V8_LALB_TX0_CTUNE_DCC_FSM_DEBUG_STATUS 0x6d4 +#define QSERDES_V8_LALB_TX0_COARSE_DCC_READCODE_STATUS 0x6d8 +#define QSERDES_V8_LALB_TX0_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6dc +#define QSERDES_V8_LALB_TX0_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6e0 +#define QSERDES_V8_LALB_TX0_FINE_DCC_READCODE_STATUS 0x6e4 +#define QSERDES_V8_LALB_TX1_CTUNE_DCC_FSM_DEBUG_STATUS 0x6e8 +#define QSERDES_V8_LALB_TX1_COARSE_DCC_READCODE_STATUS 0x6ec +#define QSERDES_V8_LALB_TX1_FTUNE_MSB_DCC_FSM_DEBUG_STATUS 0x6f0 +#define QSERDES_V8_LALB_TX1_FTUNE_LSB_DCC_FSM_DEBUG_STATUS 0x6f4 +#define QSERDES_V8_LALB_TX1_FINE_DCC_READCODE_STATUS 0x6f8 +#define QSERDES_V8_LALB_CDR_VCO_CAL_STATUS 0x6fc +#define QSERDES_V8_LALB_CDR_VCTRL_STATUS 0x700 +#define QSERDES_V8_LALB_CDR_VCO_CAP_CODE_STATUS 0x704 +#define QSERDES_V8_LALB_KVCO_CAL_DEBUG1_STATUS 0x708 +#define QSERDES_V8_LALB_KVCO_CAL_DEBUG2_STATUS 0x70c +#define QSERDES_V8_LALB_KP_CAL_DEBUG1_STATUS 0x710 +#define QSERDES_V8_LALB_KP_CAL_DEBUG2_STATUS 0x714 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG1_STATUS 0x718 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG2_STATUS 0x71c +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG3_STATUS 0x720 +#define QSERDES_V8_LALB_CDR_VCO_FREQ_DEBUG4_STATUS 0x724 +#define QSERDES_V8_LALB_IVCM_CAL_STATUS 0x728 +#define QSERDES_V8_LALB_IVCM_CAL_DEBUG_STATUS 0x72c +#define QSERDES_V8_LALB_IDAC_STATUS_I0 0x730 +#define QSERDES_V8_LALB_IDAC_STATUS_I0BAR 0x734 +#define QSERDES_V8_LALB_IDAC_STATUS_I1 0x738 +#define QSERDES_V8_LALB_IDAC_STATUS_I1BAR 0x73c +#define QSERDES_V8_LALB_IDAC_STATUS_Q 0x740 +#define QSERDES_V8_LALB_IDAC_STATUS_QBAR 0x744 +#define QSERDES_V8_LALB_IDAC_STATUS_A 0x748 +#define QSERDES_V8_LALB_IDAC_STATUS_ABAR 0x74c +#define QSERDES_V8_LALB_IDAC_STATUS_SM_ON 0x750 +#define QSERDES_V8_LALB_IDAC_STATUS_SIGNERROR 0x754 +#define QSERDES_V8_LALB_RX_SIGDET_STATUS 0x758 +#define QSERDES_V8_LALB_SIGDET_CAL_CODE_STATUS 0x75c +#define QSERDES_V8_LALB_SIGDET_CAL_FSM_DEBUG_STATUS 0x760 +#define QSERDES_V8_LALB_CDR_FREQ_LOCK_CNT_STATUS 0x764 +#define QSERDES_V8_LALB_CDR_PHASE_LOCK_CNT_STATUS 0x768 +#define QSERDES_V8_LALB_CDR_LOCK_DEBUG_STATUS 0x76c +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS1 0x770 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS2 0x774 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS3 0x778 +#define QSERDES_V8_LALB_IDATA_HIGH_STATUS4 0x77c +#define QSERDES_V8_LALB_IDATA_LOW_STATUS1 0x780 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS2 0x784 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS3 0x788 +#define QSERDES_V8_LALB_IDATA_LOW_STATUS4 0x78c +#define QSERDES_V8_LALB_QDATA_STATUS1 0x790 +#define QSERDES_V8_LALB_QDATA_STATUS2 0x794 +#define QSERDES_V8_LALB_QDATA_STATUS3 0x798 +#define QSERDES_V8_LALB_QDATA_STATUS4 0x79c +#define QSERDES_V8_LALB_IA_ERROR_COUNTER_LOW 0x7a0 +#define QSERDES_V8_LALB_IA_ERROR_COUNTER_HIGH 0x7a4 +#define QSERDES_V8_LALB_EOM_ERR_CNT_LSB_STATUS 0x7a8 +#define QSERDES_V8_LALB_EOM_ERR_CNT_MSB_STATUS 0x7ac +#define QSERDES_V8_LALB_EOM_OP_STATUS 0x7b0 +#define QSERDES_V8_LALB_AUX_MIXER_INDEX_STATUS 0x7b4 +#define QSERDES_V8_LALB_AUX_OFFSET_STATUS 0x7b8 +#define QSERDES_V8_LALB_AUXDATA_TB_STATUS 0x7bc +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_0_STATUS 0x7c0 +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_90_STATUS 0x7c4 +#define QSERDES_V8_LALB_AUX_MIXER_CTRL_180_STATUS 0x7c8 +#define QSERDES_V8_LALB_IQ_MIXER_INDEX_STATUS 0x7cc +#define QSERDES_V8_LALB_IQTUNE_FLTR_INDEX_STATUS 0x7d0 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_0_STATUS 0x7d4 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_90_STATUS 0x7d8 +#define QSERDES_V8_LALB_IQ_MIXER_CTRL_180_STATUS 0x7dc +#define QSERDES_V8_LALB_READ_EQCODE 0x7e0 +#define QSERDES_V8_LALB_READ_OFFSETCODE 0x7e4 +#define QSERDES_V8_LALB_VGA_READ_CODE 0x7e8 +#define QSERDES_V8_LALB_VTHRESH_READ_CODE 0x7ec +#define QSERDES_V8_LALB_DFE_TAP1_READ_CODE 0x7f0 +#define QSERDES_V8_LALB_DFE_TAP2_READ_CODE 0x7f4 +#define QSERDES_V8_LALB_DFE_TAP3_READ_CODE 0x7f8 +#define QSERDES_V8_LALB_DFE_TAP4_READ_CODE 0x7fc +#define QSERDES_V8_LALB_DFE_TAP5_READ_CODE 0x800 +#define QSERDES_V8_LALB_DFE_TAP6_READ_CODE 0x804 +#define QSERDES_V8_LALB_DFE_TAP7_READ_CODE 0x808 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_BIN_CODE 0x80c +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK0_CODE 0x810 +#define QSERDES_V8_LALB_CDR_IQTUNE_FILTER_CLK90_CODE 0x814 +#define QSERDES_V8_LALB_BLW_READ_CODE 0x818 +#define QSERDES_V8_LALB_IA_OFFSET_CAL_DEBUG_STATUS 0x81c +#define QSERDES_V8_LALB_IA_OFFSET_CAL_STATUS 0x820 +#define QSERDES_V8_LALB_IVTH_CAL_STATUS 0x824 +#define QSERDES_V8_LALB_IVTH_NRZ_EYE_HEIGHT_STATUS 0x828 +#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MAX_STATUS 0x82c +#define QSERDES_V8_LALB_IVTH_UPPER_EYE_MIN_STATUS 0x830 +#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MAX_STATUS 0x834 +#define QSERDES_V8_LALB_IVTH_LOWER_EYE_MIN_STATUS 0x838 +#define QSERDES_V8_LALB_IVTH_UP_INIT_CTR_STATUS 0x83c +#define QSERDES_V8_LALB_VTH_I_UP_CNTRL_STATUS 0x840 +#define QSERDES_V8_LALB_VTH_I_DN_CNTRL_STATUS 0x844 +#define QSERDES_V8_LALB_NRZ_EYE_HEIGHT_SEL_STATUS 0x848 +#define QSERDES_V8_LALB_DEBUG_BUS0 0x84c +#define QSERDES_V8_LALB_DEBUG_BUS1 0x850 +#define QSERDES_V8_LALB_DEBUG_BUS2 0x854 +#define QSERDES_V8_LALB_DEBUG_BUS3 0x858 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL1 0x85c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL2 0x860 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL3 0x864 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL4 0x868 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL5 0x86c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL6 0x870 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL7 0x874 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL8 0x878 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL9 0x87c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL10 0x880 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL11 0x884 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL12 0x888 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL13 0x88c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL14 0x890 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL15 0x894 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL16 0x898 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL17 0x89c +#define QSERDES_V8_LALB_DIG_BKUP_CTRL18 0x8a0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL19 0x8a4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL20 0x8a8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL21 0x8ac +#define QSERDES_V8_LALB_DIG_BKUP_CTRL22 0x8b0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL23 0x8b4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL24 0x8b8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL25 0x8bc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL26 0x8c0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL27 0x8c4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL28 0x8c8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL29 0x8cc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL30 0x8d0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL31 0x8d4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL32 0x8d8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_1 0x8dc +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_2 0x8e0 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_3 0x8e4 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_4 0x8e8 +#define QSERDES_V8_LALB_DIG_BKUP_CTRL_V2_5 0x8ec +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS1 0x8f0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS2 0x8f4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS3 0x8f8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS4 0x8fc +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS5 0x900 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS6 0x904 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS7 0x908 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS8 0x90c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS9 0x910 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS10 0x914 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS11 0x918 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS12 0x91c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS13 0x920 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS14 0x924 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS15 0x928 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS16 0x92c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS17 0x930 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS18 0x934 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS19 0x938 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS20 0x93c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS21 0x940 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS22 0x944 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS23 0x948 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS24 0x94c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS25 0x950 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS26 0x954 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS27 0x958 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS28 0x95c +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS29 0x960 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS30 0x964 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS31 0x968 +#define QSERDES_V8_LALB_DIG_BKUP_RO_BUS32 0x96c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS1 0x970 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS2 0x974 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS3 0x978 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS4 0x97c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS5 0x980 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS6 0x984 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS7 0x988 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS8 0x98c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS9 0x990 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS10 0x994 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS11 0x998 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS12 0x99c +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS13 0x9a0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS14 0x9a4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS15 0x9a8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS16 0x9ac +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS17 0x9b0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS18 0x9b4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS19 0x9b8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS20 0x9bc +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS21 0x9c0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS22 0x9c4 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS23 0x9c8 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS24 0x9cc +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS25 0x9d0 +#define QSERDES_V8_LALB_DIG_BKUP_RO_V2_BUS26 0x9d4 +#endif /* QCOM_PHY_QMP_QSERDES_V8_LALBH_ */ diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h new file mode 100644 index 000000000000..181846e08c0f --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-pcie-v8.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_PCIE_V8_H_ + +#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_TX 0x030 +#define QSERDES_V8_PCIE_TX_RES_CODE_LANE_OFFSET_RX 0x034 +#define QSERDES_V8_PCIE_TX_LANE_MODE_1 0x07c +#define QSERDES_V8_PCIE_TX_LANE_MODE_2 0x080 +#define QSERDES_V8_PCIE_TX_LANE_MODE_3 0x084 +#define QSERDES_V8_PCIE_TX_TRAN_DRVR_EMP_EN 0x0b4 +#define QSERDES_V8_PCIE_TX_TX_BAND0 0x0e0 +#define QSERDES_V8_PCIE_TX_TX_BAND1 0x0e4 +#define QSERDES_V8_PCIE_TX_SEL_10B_8B 0x0f4 +#define QSERDES_V8_PCIE_TX_SEL_20B_10B 0x0f8 +#define QSERDES_V8_PCIE_TX_PARRATE_REC_DETECT_IDLE_EN 0x058 +#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH1 0x118 +#define QSERDES_V8_PCIE_TX_TX_ADAPT_POST_THRESH2 0x11c +#define QSERDES_V8_PCIE_TX_PHPRE_CTRL 0x128 +#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE3 0x148 +#define QSERDES_V8_PCIE_TX_EQ_RCF_CTRL_RATE4 0x14c + +#define QSERDES_V8_PCIE_RX_UCDR_FO_GAIN_RATE4 0x0dc +#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE3 0x0ec +#define QSERDES_V8_PCIE_RX_UCDR_SO_GAIN_RATE4 0x0f0 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CONTROLS 0x0f4 +#define QSERDES_V8_PCIE_RX_VGA_CAL_CNTRL1 0x170 +#define QSERDES_V8_PCIE_RX_VGA_CAL_MAN_VAL 0x178 +#define QSERDES_V8_PCIE_RX_RX_EQU_ADAPTOR_CNTRL4 0x1b4 +#define QSERDES_V8_PCIE_RX_SIGDET_ENABLES 0x1d8 +#define QSERDES_V8_PCIE_RX_SIGDET_LVL 0x1e0 +#define QSERDES_V8_PCIE_RX_RXCLK_DIV2_CTRL 0x0b8 +#define QSERDES_V8_PCIE_RX_RX_BAND_CTRL0 0x0bc +#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL0 0x0c4 +#define QSERDES_V8_PCIE_RX_RX_TERM_BW_CTRL1 0x0c8 +#define QSERDES_V8_PCIE_RX_SVS_MODE_CTRL 0x0b4 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL1 0x058 +#define QSERDES_V8_PCIE_RX_UCDR_PI_CTRL2 0x05c +#define QSERDES_V8_PCIE_RX_UCDR_SB2_THRESH2_RATE3 0x084 +#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN1_RATE3 0x098 +#define QSERDES_V8_PCIE_RX_UCDR_SB2_GAIN2_RATE3 0x0ac +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B0 0x218 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B1 0x21c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B2 0x220 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B4 0x228 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE_0_1_B7 0x234 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B0 0x260 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B1 0x264 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B2 0x268 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B3 0x26c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE3_B4 0x270 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B0 0x284 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B1 0x288 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B2 0x28c +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B3 0x290 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B4 0x294 +#define QSERDES_V8_PCIE_RX_RX_MODE_RATE4_SA_B5 0x298 +#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE32 0x31c +#define QSERDES_V8_PCIE_RX_Q_PI_INTRINSIC_BIAS_RATE4 0x320 +#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_LSB 0x11c +#define QSERDES_V8_PCIE_RX_EOM_MAX_ERR_LIMIT_MSB 0x120 +#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE23 0x108 +#define QSERDES_V8_PCIE_RX_AUXDATA_BIN_RATE4 0x10c +#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE3 0x198 +#define QSERDES_V8_PCIE_RX_VTHRESH_CAL_MAN_VAL_RATE4 0x19c +#define QSERDES_V8_PCIE_RX_GM_CAL 0x1a0 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h new file mode 100644 index 000000000000..34919720b7bc --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-qserdes-txrx-v2.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2017, The Linux Foundation. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ +#define QCOM_PHY_QMP_QSERDES_TXRX_V2_H_ + +/* Only for QMP V2 PHY - TX registers */ +#define QSERDES_V2_TX_BIST_MODE_LANENO 0x000 +#define QSERDES_V2_TX_CLKBUF_ENABLE 0x008 +#define QSERDES_V2_TX_TX_EMP_POST1_LVL 0x00c +#define QSERDES_V2_TX_TX_DRV_LVL 0x01c +#define QSERDES_V2_TX_RESET_TSYNC_EN 0x024 +#define QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN 0x028 +#define QSERDES_V2_TX_TX_BAND 0x02c +#define QSERDES_V2_TX_SLEW_CNTL 0x030 +#define QSERDES_V2_TX_INTERFACE_SELECT 0x034 +#define QSERDES_V2_TX_RES_CODE_LANE_TX 0x03c +#define QSERDES_V2_TX_RES_CODE_LANE_RX 0x040 +#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX 0x044 +#define QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX 0x048 +#define QSERDES_V2_TX_DEBUG_BUS_SEL 0x058 +#define QSERDES_V2_TX_TRANSCEIVER_BIAS_EN 0x05c +#define QSERDES_V2_TX_HIGHZ_DRVR_EN 0x060 +#define QSERDES_V2_TX_TX_POL_INV 0x064 +#define QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN 0x068 +#define QSERDES_V2_TX_LANE_MODE_1 0x08c +#define QSERDES_V2_TX_LANE_MODE_2 0x090 +#define QSERDES_V2_TX_LANE_MODE_3 0x094 +#define QSERDES_V2_TX_RCV_DETECT_LVL_2 0x0a4 +#define QSERDES_V2_TX_TRAN_DRVR_EMP_EN 0x0c0 +#define QSERDES_V2_TX_TX_INTERFACE_MODE 0x0c4 +#define QSERDES_V2_TX_VMODE_CTRL1 0x0f0 + +/* Only for QMP V2 PHY - RX registers */ +#define QSERDES_V2_RX_UCDR_FO_GAIN 0x008 +#define QSERDES_V2_RX_UCDR_SO_GAIN_HALF 0x00c +#define QSERDES_V2_RX_UCDR_SO_GAIN 0x014 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_HALF 0x024 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN_QUARTER 0x028 +#define QSERDES_V2_RX_UCDR_SVS_SO_GAIN 0x02c +#define QSERDES_V2_RX_UCDR_FASTLOCK_FO_GAIN 0x030 +#define QSERDES_V2_RX_UCDR_SO_SATURATION_AND_ENABLE 0x034 +#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_LOW 0x03c +#define QSERDES_V2_RX_UCDR_FASTLOCK_COUNT_HIGH 0x040 +#define QSERDES_V2_RX_UCDR_PI_CONTROLS 0x044 +#define QSERDES_V2_RX_RX_TERM_BW 0x07c +#define QSERDES_V2_RX_VGA_CAL_CNTRL1 0x0bc +#define QSERDES_V2_RX_VGA_CAL_CNTRL2 0x0c0 +#define QSERDES_V2_RX_RX_EQ_GAIN2_LSB 0x0c8 +#define QSERDES_V2_RX_RX_EQ_GAIN2_MSB 0x0cc +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL1 0x0d0 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL2 0x0d4 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL3 0x0d8 +#define QSERDES_V2_RX_RX_EQU_ADAPTOR_CNTRL4 0x0dc +#define QSERDES_V2_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 0x0f8 +#define QSERDES_V2_RX_RX_OFFSET_ADAPTOR_CNTRL2 0x0fc +#define QSERDES_V2_RX_SIGDET_ENABLES 0x100 +#define QSERDES_V2_RX_SIGDET_CNTRL 0x104 +#define QSERDES_V2_RX_SIGDET_LVL 0x108 +#define QSERDES_V2_RX_SIGDET_DEGLITCH_CNTRL 0x10c +#define QSERDES_V2_RX_RX_BAND 0x110 +#define QSERDES_V2_RX_RX_INTERFACE_MODE 0x11c +#define QSERDES_V2_RX_RX_MODE_00 0x164 +#define QSERDES_V2_RX_RX_MODE_01 0x168 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c index 8a280433a42b..df138a5442eb 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-ufs.c @@ -84,6 +84,68 @@ static const unsigned int ufsphy_v6_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_POWER_DOWN_CONTROL] = QPHY_V6_PCS_UFS_POWER_DOWN_CONTROL, }; +static const struct qmp_phy_init_tbl milos_ufsphy_serdes[] = { + QMP_PHY_INIT_CFG(QSERDES_V6_COM_SYSCLK_EN_SEL, 0xd9), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_SEL_1, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_HSCLK_HS_SWITCH_SEL_1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP_EN, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IETRIM, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CMN_IPTRIM, 0x17), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_BG_TIMER, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_VCO_TUNE_INITVAL2, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE0, 0x82), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE0, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE0, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE0, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE0, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_DEC_START_MODE1, 0x98), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_CP_CTRL_MODE1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_RCTRL_MODE1, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_PLL_CCTRL_MODE1, 0x18), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP1_MODE1, 0x32), + QMP_PHY_INIT_CFG(QSERDES_V6_COM_LOCK_CMP2_MODE1, 0x0f), +}; + +static const struct qmp_phy_init_tbl milos_ufsphy_tx[] = { + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_LANE_MODE_1, 0x05), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_TX, 0x07), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_RES_CODE_LANE_OFFSET_RX, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_TX_FR_DCC_CTRL, 0xcc), +}; + +static const struct qmp_phy_init_tbl milos_ufsphy_rx[] = { + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_FO_GAIN_RATE2, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_VGA_CAL_MAN_VAL, 0x3e), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B0, 0xce), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B1, 0xce), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B2, 0x18), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B3, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B4, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE_0_1_B6, 0x60), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B3, 0x9e), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE2_B6, 0x60), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B3, 0x9e), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B4, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B5, 0x36), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_MODE_RATE3_B8, 0x02), + QMP_PHY_INIT_CFG(QSERDES_UFS_V6_RX_UCDR_PI_CTRL1, 0x94), +}; + +static const struct qmp_phy_init_tbl milos_ufsphy_pcs[] = { + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_MULTI_LANE_CTRL1, 0x02), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_MID_TERM_CTRL1, 0x43), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_PLL_CNTL, 0x0b), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_LARGE_AMP_DRV_LVL, 0x0f), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_SIGDET_CTRL2, 0x68), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_TX_HSGEAR_CAPABILITY, 0x04), + QMP_PHY_INIT_CFG(QPHY_V6_PCS_UFS_RX_HSGEAR_CAPABILITY, 0x04), +}; + static const struct qmp_phy_init_tbl msm8996_ufsphy_serdes[] = { QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x0e), QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0xd7), @@ -1165,6 +1227,11 @@ static inline void qphy_clrbits(void __iomem *base, u32 offset, u32 val) } /* Regulator bulk data with load values for specific configurations */ +static const struct regulator_bulk_data milos_ufsphy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 140120 }, + { .supply = "vdda-pll", .init_load_uA = 18340 }, +}; + static const struct regulator_bulk_data msm8996_ufsphy_vreg_l[] = { { .supply = "vdda-phy", .init_load_uA = 51400 }, { .supply = "vdda-pll", .init_load_uA = 14600 }, @@ -1258,6 +1325,32 @@ static const struct qmp_ufs_offsets qmp_ufs_offsets_v6 = { .rx2 = 0x1a00, }; +static const struct qmp_phy_cfg milos_ufsphy_cfg = { + .lanes = 2, + + .offsets = &qmp_ufs_offsets_v6, + .max_supported_gear = UFS_HS_G4, + + .tbls = { + .serdes = milos_ufsphy_serdes, + .serdes_num = ARRAY_SIZE(milos_ufsphy_serdes), + .tx = milos_ufsphy_tx, + .tx_num = ARRAY_SIZE(milos_ufsphy_tx), + .rx = milos_ufsphy_rx, + .rx_num = ARRAY_SIZE(milos_ufsphy_rx), + .pcs = milos_ufsphy_pcs, + .pcs_num = ARRAY_SIZE(milos_ufsphy_pcs), + }, + .tbls_hs_b = { + .serdes = sm8550_ufsphy_hs_b_serdes, + .serdes_num = ARRAY_SIZE(sm8550_ufsphy_hs_b_serdes), + }, + + .vreg_list = milos_ufsphy_vreg_l, + .num_vregs = ARRAY_SIZE(milos_ufsphy_vreg_l), + .regs = ufsphy_v6_regs_layout, +}; + static const struct qmp_phy_cfg msm8996_ufsphy_cfg = { .lanes = 1, @@ -2166,6 +2259,9 @@ static int qmp_ufs_probe(struct platform_device *pdev) static const struct of_device_id qmp_ufs_of_match_table[] = { { + .compatible = "qcom,milos-qmp-ufs-phy", + .data = &milos_ufsphy_cfg, + }, { .compatible = "qcom,msm8996-qmp-ufs-phy", .data = &msm8996_ufsphy_cfg, }, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c index ed646a7e705b..b0ecd5ba2464 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usb.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb.c @@ -28,6 +28,7 @@ #include "phy-qcom-qmp-pcs-usb-v5.h" #include "phy-qcom-qmp-pcs-usb-v6.h" #include "phy-qcom-qmp-pcs-usb-v7.h" +#include "phy-qcom-qmp-pcs-usb-v8.h" #define PHY_INIT_COMPLETE_TIMEOUT 10000 @@ -109,6 +110,139 @@ static const unsigned int qmp_v7_usb3phy_regs_layout[QPHY_LAYOUT_SIZE] = { [QPHY_PCS_LFPS_RXTERM_IRQ_CLEAR] = QPHY_V7_PCS_USB3_LFPS_RXTERM_IRQ_CLEAR, }; +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE1, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE1, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORECLK_DIV_MODE1, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE1, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE1, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE1, 0x75), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_HSCLK_SEL_1, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE1, 0x25), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE1, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE1, 0x5c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE1, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE1_MODE0, 0x5c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BIN_VCOCAL_CMP_CODE2_MODE0, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE1_MODE0, 0xc0), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_STEP_SIZE2_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CP_CTRL_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_PLL_CCTRL_MODE0, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP1_MODE0, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP2_MODE0, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MODE0, 0x41), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DEC_START_MSB_MODE0, 0x00), + + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START1_MODE0, 0x55), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START2_MODE0, 0x75), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_DIV_FRAC_START3_MODE0, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE1_MODE0, 0x25), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE2_MODE0, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_BG_TIMER, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_EN_CENTER, 0x01), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER1, 0x62), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SSC_PER2, 0x02), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_BUF_ENABLE, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_SYSCLK_EN_SEL, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_LOCK_CMP_CFG, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_VCO_TUNE_MAP, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CORE_CLK_EN, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_CMN_CONFIG_1, 0x16), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_1, 0xb6), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_2, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_AUTO_GAIN_ADJ_CTRL_3, 0x36), + QMP_PHY_INIT_CFG(QSERDES_V8_COM_ADDITIONAL_MISC, 0x0c), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG1, 0xc4), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG2, 0x89), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG3, 0x20), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_LOCK_DETECT_CONFIG6, 0x13), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_REFGEN_REQ_CONFIG1, 0x21), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RX_SIGDET_LVL, 0x55), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_L, 0xe7), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_RCVR_DTCT_DLY_P1U2_H, 0x03), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_CDR_RESET_TIME, 0x0a), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG1, 0xd4), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_ALIGN_DETECT_CONFIG2, 0x30), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_PCS_TX_RX_CONFIG, 0x0c), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG1, 0x4b), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_EQ_CONFIG5, 0x10), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_TX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_RX, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_TX, 0x1f), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RES_CODE_LANE_OFFSET_RX, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_1, 0xf5), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_3, 0x11), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_4, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_LANE_MODE_5, 0x5f), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_RCV_DETECT_LVL_2, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V8_TX_PI_QEC_CTRL, 0x21), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_rx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FO_GAIN, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_GAIN, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_FO_GAIN, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SO_SATURATION_AND_ENABLE, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_LOW, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_FASTLOCK_COUNT_HIGH, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_PI_CONTROLS, 0x99), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH1, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_THRESH2, 0x08), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN1, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_UCDR_SB2_GAIN2, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_AUX_DATA_TCOARSE_TFINE, 0x20), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL1, 0x54), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VGA_CAL_CNTRL2, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_GM_CAL, 0x1b), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL2, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL3, 0x4a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQU_ADAPTOR_CNTRL4, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_LOW, 0x07), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_IDAC_TSETTLE_HIGH, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1, 0x27), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_ENABLES, 0x0c), + + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CNTRL, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_DEGLITCH_CNTRL, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_LOW, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH2, 0xff), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH3, 0xdf), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_00_HIGH4, 0xed), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_LOW, 0x19), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH, 0x09), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH2, 0x91), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH3, 0xb7), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_RX_MODE_01_HIGH4, 0xaa), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_EN_TIMER, 0x04), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DFE_CTLE_POST_CAL_OFFSET, 0x38), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_DCC_CTRL1, 0x0c), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_VTH_CODE, 0x10), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_CTRL1, 0x14), + QMP_PHY_INIT_CFG(QSERDES_V8_RX_SIGDET_CAL_TRIM, 0x08), +}; + +static const struct qmp_phy_init_tbl glymur_usb3_uniphy_pcs_usb_tbl[] = { + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_LFPS_DET_HIGH_COUNT_VAL, 0xf8), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_DFE_TIME_S2, 0x07), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RXEQTRAINING_WAIT_TIME, 0x75), + QMP_PHY_INIT_CFG(QPHY_V8_PCS_USB_RCVR_DTCT_DLY_U3_L, 0x40), +}; + static const struct qmp_phy_init_tbl ipq9574_usb3_serdes_tbl[] = { QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x1a), QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x08), @@ -1266,7 +1400,7 @@ struct qmp_phy_cfg { int pcs_usb_tbl_num; /* regulators to be requested */ - const char * const *vreg_list; + const struct regulator_bulk_data *vreg_list; int num_vregs; /* array of registers with different offsets */ @@ -1344,8 +1478,9 @@ static const char * const usb3phy_reset_l[] = { }; /* list of regulators */ -static const char * const qmp_phy_vreg_l[] = { - "vdda-phy", "vdda-pll", +static const struct regulator_bulk_data qmp_phy_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 21800, }, + { .supply = "vdda-pll", .init_load_uA = 36000, }, }; static const struct qmp_usb_offsets qmp_usb_offsets_v3 = { @@ -1403,6 +1538,14 @@ static const struct qmp_usb_offsets qmp_usb_offsets_v7 = { .rx = 0x1000, }; +static const struct qmp_usb_offsets qmp_usb_offsets_v8 = { + .serdes = 0, + .pcs = 0x0400, + .pcs_usb = 0x1200, + .tx = 0x0e00, + .rx = 0x1000, +}; + static const struct qmp_phy_cfg ipq6018_usb3phy_cfg = { .offsets = &qmp_usb_offsets_v3, @@ -1704,6 +1847,24 @@ static const struct qmp_phy_cfg x1e80100_usb3_uniphy_cfg = { .regs = qmp_v7_usb3phy_regs_layout, }; +static const struct qmp_phy_cfg glymur_usb3_uniphy_cfg = { + .offsets = &qmp_usb_offsets_v8, + + .serdes_tbl = glymur_usb3_uniphy_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_serdes_tbl), + .tx_tbl = glymur_usb3_uniphy_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_tx_tbl), + .rx_tbl = glymur_usb3_uniphy_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_rx_tbl), + .pcs_tbl = glymur_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_tbl), + .pcs_usb_tbl = glymur_usb3_uniphy_pcs_usb_tbl, + .pcs_usb_tbl_num = ARRAY_SIZE(glymur_usb3_uniphy_pcs_usb_tbl), + .vreg_list = qmp_phy_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .regs = qmp_v7_usb3phy_regs_layout, +}; + static int qmp_usb_serdes_init(struct qmp_usb *qmp) { const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -1986,23 +2147,6 @@ static const struct dev_pm_ops qmp_usb_pm_ops = { qmp_usb_runtime_resume, NULL) }; -static int qmp_usb_vreg_init(struct qmp_usb *qmp) -{ - const struct qmp_phy_cfg *cfg = qmp->cfg; - struct device *dev = qmp->dev; - int num = cfg->num_vregs; - int i; - - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); - if (!qmp->vregs) - return -ENOMEM; - - for (i = 0; i < num; i++) - qmp->vregs[i].supply = cfg->vreg_list[i]; - - return devm_regulator_bulk_get(dev, num, qmp->vregs); -} - static int qmp_usb_reset_init(struct qmp_usb *qmp, const char *const *reset_list, int num_resets) @@ -2251,7 +2395,8 @@ static int qmp_usb_probe(struct platform_device *pdev) if (!qmp->cfg) return -EINVAL; - ret = qmp_usb_vreg_init(qmp); + ret = devm_regulator_bulk_get_const(dev, qmp->cfg->num_vregs, + qmp->cfg->vreg_list, &qmp->vregs); if (ret) return ret; @@ -2302,6 +2447,9 @@ static int qmp_usb_probe(struct platform_device *pdev) static const struct of_device_id qmp_usb_of_match_table[] = { { + .compatible = "qcom,glymur-qmp-usb3-uni-phy", + .data = &glymur_usb3_uniphy_cfg, + }, { .compatible = "qcom,ipq5424-qmp-usb3-phy", .data = &ipq9574_usb3phy_cfg, }, { diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h new file mode 100644 index 000000000000..4f387c8ed9e5 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-pcs-v8.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_USB43_PCS_V8_H_ +#define QCOM_PHY_QMP_USB43_PCS_V8_H_ + +#define QPHY_V8_USB43_PCS_SW_RESET 0x000 +#define QPHY_V8_USB43_PCS_PCS_STATUS1 0x014 +#define QPHY_V8_USB43_PCS_POWER_DOWN_CONTROL 0x040 +#define QPHY_V8_USB43_PCS_START_CONTROL 0x044 +#define QPHY_V8_USB43_PCS_POWER_STATE_CONFIG1 0x090 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG1 0x0c4 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG2 0x0c8 +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG3 0x0cc +#define QPHY_V8_USB43_PCS_LOCK_DETECT_CONFIG6 0x0d8 +#define QPHY_V8_USB43_PCS_REFGEN_REQ_CONFIG1 0x0dc +#define QPHY_V8_USB43_PCS_RX_SIGDET_LVL 0x188 +#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_L 0x190 +#define QPHY_V8_USB43_PCS_RCVR_DTCT_DLY_P1U2_H 0x194 +#define QPHY_V8_USB43_PCS_RATE_SLEW_CNTRL1 0x198 +#define QPHY_V8_USB43_PCS_TSYNC_RSYNC_TIME 0x1ac +#define QPHY_V8_USB43_PCS_RX_CONFIG 0x1b0 +#define QPHY_V8_USB43_PCS_TSYNC_DLY_TIME 0x1b4 +#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG1 0x1c0 +#define QPHY_V8_USB43_PCS_ALIGN_DETECT_CONFIG2 0x1c4 +#define QPHY_V8_USB43_PCS_PCS_TX_RX_CONFIG 0x1d0 +#define QPHY_V8_USB43_PCS_EQ_CONFIG1 0x1dc +#define QPHY_V8_USB43_PCS_EQ_CONFIG2 0x1e0 +#define QPHY_V8_USB43_PCS_EQ_CONFIG5 0x1ec + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h new file mode 100644 index 000000000000..e9c743fce9d1 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usb43-qserdes-com-v8.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ +#define QCOM_PHY_QMP_USB43_QSERDES_COM_V8_H_ + +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE1 0x000 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE1 0x004 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE1 0x008 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE1 0x00c +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE1 0x010 +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE1 0x014 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE1 0x018 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE1 0x01c +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE1 0x020 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE1 0x024 +#define QSERDES_V8_USB43_COM_DEC_START_MODE1 0x028 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE1 0x02c +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE1 0x030 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE1 0x034 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE1 0x038 +#define QSERDES_V8_USB43_COM_HSCLK_SEL_1 0x03c +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE1 0x040 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE1 0x044 +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE1 0x048 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE1 0x04c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE1 0x050 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE1 0x054 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE0 0x058 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE0 0x05c +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE0 0x060 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE0 0x064 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE0 0x068 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE0 0x06c +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE0 0x070 +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE0 0x074 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE0 0x078 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE0 0x07c +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE0 0x080 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE0 0x084 +#define QSERDES_V8_USB43_COM_DEC_START_MODE0 0x088 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE0 0x08c +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE0 0x090 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE0 0x094 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE0 0x098 +#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_1 0x09c +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE0 0x0a0 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE0 0x0a4 +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE0 0x0a8 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE0 0x0ac +#define QSERDES_V8_USB43_COM_ATB_SEL1 0x0b0 +#define QSERDES_V8_USB43_COM_ATB_SEL2 0x0b4 +#define QSERDES_V8_USB43_COM_FREQ_UPDATE 0x0b8 +#define QSERDES_V8_USB43_COM_BG_TIMER 0x0bc +#define QSERDES_V8_USB43_COM_SSC_EN_CENTER 0x0c0 +#define QSERDES_V8_USB43_COM_SSC_ADJ_PER1 0x0c4 +#define QSERDES_V8_USB43_COM_SSC_ADJ_PER2 0x0c8 +#define QSERDES_V8_USB43_COM_SSC_PER1 0x0cc +#define QSERDES_V8_USB43_COM_SSC_PER2 0x0d0 +#define QSERDES_V8_USB43_COM_POST_DIV 0x0d4 +#define QSERDES_V8_USB43_COM_POST_DIV_MUX 0x0d8 +#define QSERDES_V8_USB43_COM_BIAS_EN_CLKBUFLR_EN 0x0dc +#define QSERDES_V8_USB43_COM_CLK_ENABLE1 0x0e0 +#define QSERDES_V8_USB43_COM_SYS_CLK_CTRL 0x0e4 +#define QSERDES_V8_USB43_COM_SYSCLK_BUF_ENABLE 0x0e8 +#define QSERDES_V8_USB43_COM_PLL_EN 0x0ec +#define QSERDES_V8_USB43_COM_DEBUG_BUS_OVRD 0x0f0 +#define QSERDES_V8_USB43_COM_PLL_IVCO 0x0f4 +#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE1 0x0f8 +#define QSERDES_V8_USB43_COM_CMN_IETRIM 0x0fc +#define QSERDES_V8_USB43_COM_CMN_IPTRIM 0x100 +#define QSERDES_V8_USB43_COM_EP_CLOCK_DETECT_CTRL 0x104 +#define QSERDES_V8_USB43_COM_PLL_CNTRL 0x108 +#define QSERDES_V8_USB43_COM_BIAS_EN_CTRL_BY_PSM 0x10c +#define QSERDES_V8_USB43_COM_SYSCLK_EN_SEL 0x110 +#define QSERDES_V8_USB43_COM_CML_SYSCLK_SEL 0x114 +#define QSERDES_V8_USB43_COM_RESETSM_CNTRL 0x118 +#define QSERDES_V8_USB43_COM_RESETSM_CNTRL2 0x11c +#define QSERDES_V8_USB43_COM_LOCK_CMP_EN 0x120 +#define QSERDES_V8_USB43_COM_LOCK_CMP_CFG 0x124 +#define QSERDES_V8_USB43_COM_INTEGLOOP_INITVAL 0x128 +#define QSERDES_V8_USB43_COM_INTEGLOOP_EN 0x12c +#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN0 0x130 +#define QSERDES_V8_USB43_COM_INTEGLOOP_P_PATH_GAIN1 0x134 +#define QSERDES_V8_USB43_COM_VCOCAL_DEADMAN_CTRL 0x138 +#define QSERDES_V8_USB43_COM_VCO_TUNE_CTRL 0x13c +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAP 0x140 +#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL1 0x144 +#define QSERDES_V8_USB43_COM_VCO_TUNE_INITVAL2 0x148 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL1 0x14c +#define QSERDES_V8_USB43_COM_VCO_TUNE_MINVAL2 0x150 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL1 0x154 +#define QSERDES_V8_USB43_COM_VCO_TUNE_MAXVAL2 0x158 +#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER1 0x15c +#define QSERDES_V8_USB43_COM_VCO_TUNE_TIMER2 0x160 +#define QSERDES_V8_USB43_COM_CLK_SELECT 0x164 +#define QSERDES_V8_USB43_COM_PLL_ANALOG 0x168 +#define QSERDES_V8_USB43_COM_SW_RESET 0x16c +#define QSERDES_V8_USB43_COM_CORE_CLK_EN 0x170 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_1 0x174 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_3 0x178 +#define QSERDES_V8_USB43_COM_CMN_RATE_OVERRIDE 0x17c +#define QSERDES_V8_USB43_COM_SVS_MODE_CLK_SEL 0x180 +#define QSERDES_V8_USB43_COM_DEBUG_BUS_SEL 0x184 +#define QSERDES_V8_USB43_COM_CMN_MISC1 0x188 +#define QSERDES_V8_USB43_COM_CMN_MODE 0x18c +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD 0x190 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD1 0x194 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD2 0x198 +#define QSERDES_V8_USB43_COM_VCO_DC_LEVEL_CTRL 0x19c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_1 0x1a0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_CTRL_1 0x1a4 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_1 0x1a8 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_2 0x1ac +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_3 0x1b0 +#define QSERDES_V8_USB43_COM_AUTO_GAIN_ADJ_CTRL_4 0x1b4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC 0x1b8 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_2 0x1bc +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_3 0x1c0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_4 0x1c4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_5 0x1c8 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE1_MODE2 0x1cc +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE2_MODE2 0x1d0 +#define QSERDES_V8_USB43_COM_SSC_STEP_SIZE3_MODE2 0x1d4 +#define QSERDES_V8_USB43_COM_CLK_EP_DIV_MODE2 0x1d8 +#define QSERDES_V8_USB43_COM_CP_CTRL_MODE2 0x1dc +#define QSERDES_V8_USB43_COM_PLL_RCTRL_MODE2 0x1e0 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_MODE2 0x1e4 +#define QSERDES_V8_USB43_COM_CORECLK_DIV_MODE2 0x1e8 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_MODE2 0x1ec +#define QSERDES_V8_USB43_COM_LOCK_CMP2_MODE2 0x1f0 +#define QSERDES_V8_USB43_COM_DEC_START_MODE2 0x1f4 +#define QSERDES_V8_USB43_COM_DEC_START_MSB_MODE2 0x1f8 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START1_MODE2 0x1fc +#define QSERDES_V8_USB43_COM_DIV_FRAC_START2_MODE2 0x200 +#define QSERDES_V8_USB43_COM_DIV_FRAC_START3_MODE2 0x204 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN0_MODE2 0x208 +#define QSERDES_V8_USB43_COM_INTEGLOOP_GAIN1_MODE2 0x20c +#define QSERDES_V8_USB43_COM_VCO_TUNE1_MODE2 0x210 +#define QSERDES_V8_USB43_COM_VCO_TUNE2_MODE2 0x214 +#define QSERDES_V8_USB43_COM_PLL_IVCO_MODE2 0x218 +#define QSERDES_V8_USB43_COM_HSCLK_SEL_2 0x21c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE1_MODE2 0x220 +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_CMP_CODE2_MODE2 0x224 +#define QSERDES_V8_USB43_COM_HSCLK_HS_SWITCH_SEL_2 0x228 +#define QSERDES_V8_USB43_COM_CMN_CONFIG_2 0x22c +#define QSERDES_V8_USB43_COM_BIN_VCOCAL_HSCLK_SEL_2 0x230 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_0 0x234 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_1 0x238 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_2 0x23c +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_3 0x240 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_4 0x244 +#define QSERDES_V8_USB43_COM_IVCOCAL_CONFIG_5 0x248 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE0 0x24c +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE0 0x250 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE1 0x254 +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE1 0x258 +#define QSERDES_V8_USB43_COM_LOCK_CMP1_EARLY_MODE2 0x25c +#define QSERDES_V8_USB43_COM_LOCK_CMP2_EARLY_MODE2 0x260 +#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_0 0x264 +#define QSERDES_V8_USB43_COM_EARLY_LOCK_CONFIG_1 0x268 +#define QSERDES_V8_USB43_COM_ADAPTIVE_ANALOG_CONFIG 0x26c +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE0 0x270 +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE0 0x274 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE0 0x278 +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE1 0x27c +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE1 0x280 +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE1 0x284 +#define QSERDES_V8_USB43_COM_CP_CTRL_ADAPTIVE_MODE2 0x288 +#define QSERDES_V8_USB43_COM_PLL_RCCTRL_ADAPTIVE_MODE2 0x28c +#define QSERDES_V8_USB43_COM_PLL_CCTRL_ADAPTIVE_MODE2 0x290 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD3 0x294 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD4 0x298 +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD5 0x29c +#define QSERDES_V8_USB43_COM_CMN_MODE_CONTD6 0x2a0 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_6 0x2a4 +#define QSERDES_V8_USB43_COM_ADDITIONAL_MISC_7 0x2a8 +#define QSERDES_V8_USB43_COM_VCO_WAIT_CYCLES 0x2ac +#define QSERDES_V8_USB43_COM_BIAS_WAIT_CYCLES 0x2b0 +#define QSERDES_V8_USB43_COM_AUX_CLK_PSM_ENABLE 0x2b4 +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO 0x2b8 +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_1 0x2bc +#define QSERDES_V8_USB43_COM_PLL_SPARE_FOR_ECO_2 0x2c0 +#define QSERDES_V8_USB43_COM_LDO_CAL_1 0x2c4 +#define QSERDES_V8_USB43_COM_LDO_CAL_2 0x2c8 +#define QSERDES_V8_USB43_COM_LDO_CAL_3 0x2cc +#define QSERDES_V8_USB43_COM_LDO_CAL_4 0x2d0 +#define QSERDES_V8_USB43_COM_LDO_CAL_5 0x2d4 +#define QSERDES_V8_USB43_COM_DCC_CAL_1 0x2d8 +#define QSERDES_V8_USB43_COM_DCC_CAL_2 0x2dc +#define QSERDES_V8_USB43_COM_DCC_CAL_3 0x2e0 +#define QSERDES_V8_USB43_COM_DCC_CAL_4 0x2e4 +#define QSERDES_V8_USB43_COM_DCC_CAL_5 0x2e8 +#define QSERDES_V8_USB43_COM_DCC_CAL_6 0x2ec +#define QSERDES_V8_USB43_COM_PSM_CAL_EN 0x2f0 +#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_1 0x2f4 +#define QSERDES_V8_USB43_COM_CLK_FWD_CONFIG_2 0x2f8 +#define QSERDES_V8_USB43_COM_IP_CTRL_AND_DP_SEL 0x2fc +#define QSERDES_V8_USB43_COM_DCC_CAL_7 0x300 +#define QSERDES_V8_USB43_COM_DCC_CAL_8 0x304 +#define QSERDES_V8_USB43_COM_DCC_CAL_9 0x308 +#define QSERDES_V8_USB43_COM_MODE_OPERATION_STATUS 0x30c +#define QSERDES_V8_USB43_COM_SYSCLK_DET_COMP_STATUS 0x310 +#define QSERDES_V8_USB43_COM_CMN_STATUS 0x314 +#define QSERDES_V8_USB43_COM_RESET_SM_STATUS 0x318 +#define QSERDES_V8_USB43_COM_RESTRIM_CODE_STATUS 0x31c +#define QSERDES_V8_USB43_COM_PLLCAL_CODE1_STATUS 0x320 +#define QSERDES_V8_USB43_COM_PLLCAL_CODE2_STATUS 0x324 +#define QSERDES_V8_USB43_COM_INTEGLOOP_BINCODE_STATUS 0x328 +#define QSERDES_V8_USB43_COM_DEBUG_BUS0 0x32c +#define QSERDES_V8_USB43_COM_DEBUG_BUS1 0x330 +#define QSERDES_V8_USB43_COM_DEBUG_BUS2 0x334 +#define QSERDES_V8_USB43_COM_DEBUG_BUS3 0x338 +#define QSERDES_V8_USB43_COM_C_READY_STATUS 0x33c +#define QSERDES_V8_USB43_COM_READ_DUMMY_1 0x340 +#define QSERDES_V8_USB43_COM_READ_DUMMY_2 0x344 +#define QSERDES_V8_USB43_COM_READ_DUMMY_3 0x348 +#define QSERDES_V8_USB43_COM_IVCO_CAL_CODE_STATUS 0x34c +#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_2 0x350 +#define QSERDES_V8_USB43_COM_PLL_LDO_CAL_STATUS_3 0x354 + +#endif diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c index 5e7fcb26744a..14feb77789b3 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c +++ b/drivers/phy/qualcomm/phy-qcom-qmp-usbc.c @@ -22,13 +22,19 @@ #include #include #include +#include #include "phy-qcom-qmp-common.h" #include "phy-qcom-qmp.h" #include "phy-qcom-qmp-pcs-misc-v3.h" +#include "phy-qcom-qmp-dp-phy.h" +#include "phy-qcom-qmp-dp-phy-v2.h" + #define PHY_INIT_COMPLETE_TIMEOUT 10000 +#define SW_PORTSELECT_VAL BIT(0) +#define SW_PORTSELECT_MUX BIT(1) /* set of registers with offsets different per-PHY */ enum qphy_reg_layout { @@ -284,6 +290,83 @@ static const struct qmp_phy_init_tbl qcm2290_usb3_pcs_tbl[] = { QMP_PHY_INIT_CFG(QPHY_V3_PCS_RX_SIGDET_LVL, 0x88), }; +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_SVS_MODE_CLK_SEL, 0x01), + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_EN_SEL, 0x37), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_SYS_CLK_CTRL, 0x06), + QMP_PHY_INIT_CFG(QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_ENABLE1, 0x0e), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_CTRL, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_SYSCLK_BUF_ENABLE, 0x06), + QMP_PHY_INIT_CFG(QSERDES_COM_CLK_SELECT, 0x30), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_IVCO, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_CCTRL_MODE0, 0x28), + QMP_PHY_INIT_CFG(QSERDES_COM_PLL_RCTRL_MODE0, 0x16), + QMP_PHY_INIT_CFG(QSERDES_COM_CP_CTRL_MODE0, 0x0b), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN0_MODE0, 0x40), + QMP_PHY_INIT_CFG(QSERDES_COM_INTEGLOOP_GAIN1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_MAP, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_BG_TIMER, 0x08), + QMP_PHY_INIT_CFG(QSERDES_COM_CORECLK_DIV, 0x05), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_VCO_TUNE_CTRL, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_CORE_CLK_EN, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_COM_CMN_CONFIG, 0x02), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_rbr[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x2c), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0xbf), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x21), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x24), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x69), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x80), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x07), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x3f), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x38), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_serdes_tbl_hbr2[] = { + QMP_PHY_INIT_CFG(QSERDES_COM_HSCLK_SEL, 0x20), + QMP_PHY_INIT_CFG(QSERDES_COM_DEC_START_MODE0, 0x8c), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START1_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START2_MODE0, 0x00), + QMP_PHY_INIT_CFG(QSERDES_COM_DIV_FRAC_START3_MODE0, 0x0a), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP1_MODE0, 0x7f), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP2_MODE0, 0x70), + QMP_PHY_INIT_CFG(QSERDES_COM_LOCK_CMP3_MODE0, 0x00), +}; + +static const struct qmp_phy_init_tbl qmp_v2_dp_tx_tbl[] = { + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRANSCEIVER_BIAS_EN, 0x1a), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_VMODE_CTRL1, 0x40), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PRE_STALL_LDO_BOOST_EN, 0x30), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_INTERFACE_SELECT, 0x3d), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_CLKBUF_ENABLE, 0x0f), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RESET_TSYNC_EN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TRAN_DRVR_EMP_EN, 0x03), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_PARRATE_REC_DETECT_IDLE_EN, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_INTERFACE_MODE, 0x00), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_EMP_POST1_LVL, 0x2b), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_DRV_LVL, 0x2f), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_TX_BAND, 0x4), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_TX, 0x12), + QMP_PHY_INIT_CFG(QSERDES_V2_TX_RES_CODE_LANE_OFFSET_RX, 0x12), +}; + struct qmp_usbc_offsets { u16 serdes; u16 pcs; @@ -293,13 +376,18 @@ struct qmp_usbc_offsets { /* for PHYs with >= 2 lanes */ u16 tx2; u16 rx2; + + u16 dp_serdes; + u16 dp_txa; + u16 dp_txb; + u16 dp_dp_phy; }; -/* struct qmp_phy_cfg - per-PHY initialization config */ +struct qmp_usbc; struct qmp_phy_cfg { const struct qmp_usbc_offsets *offsets; - /* Init sequence for PHY blocks - serdes, tx, rx, pcs */ + /* Init sequence for USB PHY blocks - serdes, tx, rx, pcs */ const struct qmp_phy_init_tbl *serdes_tbl; int serdes_tbl_num; const struct qmp_phy_init_tbl *tx_tbl; @@ -309,8 +397,30 @@ struct qmp_phy_cfg { const struct qmp_phy_init_tbl *pcs_tbl; int pcs_tbl_num; - /* regulators to be requested */ - const char * const *vreg_list; + /* Init sequence for DP PHY blocks - serdes, tx, rbr, hbr, hbr2 */ + const struct qmp_phy_init_tbl *dp_serdes_tbl; + int dp_serdes_tbl_num; + const struct qmp_phy_init_tbl *dp_tx_tbl; + int dp_tx_tbl_num; + const struct qmp_phy_init_tbl *serdes_tbl_rbr; + int serdes_tbl_rbr_num; + const struct qmp_phy_init_tbl *serdes_tbl_hbr; + int serdes_tbl_hbr_num; + const struct qmp_phy_init_tbl *serdes_tbl_hbr2; + int serdes_tbl_hbr2_num; + + const u8 (*swing_tbl)[4][4]; + const u8 (*pre_emphasis_tbl)[4][4]; + + /* DP PHY callbacks */ + void (*dp_aux_init)(struct qmp_usbc *qmp); + void (*configure_dp_tx)(struct qmp_usbc *qmp); + int (*configure_dp_phy)(struct qmp_usbc *qmp); + int (*calibrate_dp_phy)(struct qmp_usbc *qmp); + + const char * const *reset_list; + int num_resets; + const struct regulator_bulk_data *vreg_list; int num_vregs; /* array of registers with different offsets */ @@ -329,25 +439,36 @@ struct qmp_usbc { void __iomem *rx; void __iomem *tx2; void __iomem *rx2; - - struct regmap *tcsr_map; - u32 vls_clamp_reg; + void __iomem *dp_dp_phy; + void __iomem *dp_tx; + void __iomem *dp_tx2; + void __iomem *dp_serdes; struct clk *pipe_clk; + struct clk_fixed_rate pipe_clk_fixed; + + struct clk_hw dp_link_hw; + struct clk_hw dp_pixel_hw; struct clk_bulk_data *clks; int num_clks; int num_resets; struct reset_control_bulk_data *resets; struct regulator_bulk_data *vregs; + struct regmap *tcsr_map; + u32 vls_clamp_reg; + u32 dp_phy_mode_reg; + struct mutex phy_mutex; + struct phy *usb_phy; enum phy_mode mode; unsigned int usb_init_count; - struct phy *phy; - - struct clk_fixed_rate pipe_clk_fixed; + struct phy *dp_phy; + unsigned int dp_aux_cfg; + struct phy_configure_opts_dp dp_opts; + unsigned int dp_init_count; struct typec_switch_dev *sw; enum typec_orientation orientation; @@ -391,9 +512,23 @@ static const char * const usb3phy_reset_l[] = { "phy_phy", "phy", }; -/* list of regulators */ -static const char * const qmp_phy_vreg_l[] = { - "vdda-phy", "vdda-pll", +static const char * const usb3dpphy_reset_l[] = { + "phy_phy", "dp_phy", +}; + +static const struct regulator_bulk_data qmp_phy_msm8998_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 68600 }, + { .supply = "vdda-pll", .init_load_uA = 14200 }, +}; + +static const struct regulator_bulk_data qmp_phy_sm2290_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 66100 }, + { .supply = "vdda-pll", .init_load_uA = 13300 }, +}; + +static const struct regulator_bulk_data qmp_phy_qcs615_vreg_l[] = { + { .supply = "vdda-phy", .init_load_uA = 50000 }, + { .supply = "vdda-pll", .init_load_uA = 20000 }, }; static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { @@ -406,6 +541,34 @@ static const struct qmp_usbc_offsets qmp_usbc_offsets_v3_qcm2290 = { .rx2 = 0x800, }; +static const struct qmp_usbc_offsets qmp_usbc_usb3dp_offsets_qcs615 = { + .serdes = 0x0, + .pcs = 0xc00, + .pcs_misc = 0xa00, + .tx = 0x200, + .rx = 0x400, + .tx2 = 0x600, + .rx2 = 0x800, + .dp_serdes = 0x1c00, + .dp_txa = 0x1400, + .dp_txb = 0x1800, + .dp_dp_phy = 0x1000, +}; + +static const u8 qmp_v2_dp_pre_emphasis_hbr2_rbr[4][4] = { + {0x00, 0x0b, 0x12, 0xff}, + {0x00, 0x0a, 0x12, 0xff}, + {0x00, 0x0c, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff} +}; + +static const u8 qmp_v2_dp_voltage_swing_hbr2_rbr[4][4] = { + {0x07, 0x0f, 0x14, 0xff}, + {0x11, 0x1d, 0x1f, 0xff}, + {0x18, 0x1f, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff} +}; + static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .offsets = &qmp_usbc_offsets_v3_qcm2290, @@ -417,8 +580,10 @@ static const struct qmp_phy_cfg msm8998_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(msm8998_usb3_rx_tbl), .pcs_tbl = msm8998_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(msm8998_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), + .vreg_list = qmp_phy_msm8998_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), .regs = qmp_v3_usb3phy_regs_layout, }; @@ -433,8 +598,10 @@ static const struct qmp_phy_cfg qcm2290_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), + .vreg_list = qmp_phy_sm2290_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_sm2290_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; @@ -449,17 +616,86 @@ static const struct qmp_phy_cfg sdm660_usb3phy_cfg = { .rx_tbl_num = ARRAY_SIZE(sdm660_usb3_rx_tbl), .pcs_tbl = qcm2290_usb3_pcs_tbl, .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), - .vreg_list = qmp_phy_vreg_l, - .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), + .vreg_list = qmp_phy_msm8998_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_msm8998_vreg_l), .regs = qmp_v3_usb3phy_regs_layout_qcm2290, }; -static int qmp_usbc_init(struct phy *phy) +static const struct qmp_phy_cfg qcs615_usb3phy_cfg = { + .offsets = &qmp_usbc_offsets_v3_qcm2290, + + .serdes_tbl = qcm2290_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), + .tx_tbl = qcm2290_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), + .rx_tbl = qcm2290_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), + .pcs_tbl = qcm2290_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + .reset_list = usb3phy_reset_l, + .num_resets = ARRAY_SIZE(usb3phy_reset_l), + .vreg_list = qmp_phy_qcs615_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, +}; + +static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp); +static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp); +static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp); +static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp); + +static const struct qmp_phy_cfg qcs615_usb3dp_phy_cfg = { + .offsets = &qmp_usbc_usb3dp_offsets_qcs615, + + .serdes_tbl = qcm2290_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qcm2290_usb3_serdes_tbl), + .tx_tbl = qcm2290_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qcm2290_usb3_tx_tbl), + .rx_tbl = qcm2290_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qcm2290_usb3_rx_tbl), + .pcs_tbl = qcm2290_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qcm2290_usb3_pcs_tbl), + + .regs = qmp_v3_usb3phy_regs_layout_qcm2290, + + .dp_serdes_tbl = qmp_v2_dp_serdes_tbl, + .dp_serdes_tbl_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl), + .dp_tx_tbl = qmp_v2_dp_tx_tbl, + .dp_tx_tbl_num = ARRAY_SIZE(qmp_v2_dp_tx_tbl), + + .serdes_tbl_rbr = qmp_v2_dp_serdes_tbl_rbr, + .serdes_tbl_rbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_rbr), + .serdes_tbl_hbr = qmp_v2_dp_serdes_tbl_hbr, + .serdes_tbl_hbr_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr), + .serdes_tbl_hbr2 = qmp_v2_dp_serdes_tbl_hbr2, + .serdes_tbl_hbr2_num = ARRAY_SIZE(qmp_v2_dp_serdes_tbl_hbr2), + + .swing_tbl = &qmp_v2_dp_voltage_swing_hbr2_rbr, + .pre_emphasis_tbl = &qmp_v2_dp_pre_emphasis_hbr2_rbr, + + .dp_aux_init = qmp_v2_dp_aux_init, + .configure_dp_tx = qmp_v2_configure_dp_tx, + .configure_dp_phy = qmp_v2_configure_dp_phy, + .calibrate_dp_phy = qmp_v2_calibrate_dp_phy, + + .reset_list = usb3dpphy_reset_l, + .num_resets = ARRAY_SIZE(usb3dpphy_reset_l), + .vreg_list = qmp_phy_qcs615_vreg_l, + .num_vregs = ARRAY_SIZE(qmp_phy_qcs615_vreg_l), +}; + +static void qmp_usbc_set_phy_mode(struct qmp_usbc *qmp, bool is_dp) +{ + if (qmp->tcsr_map && qmp->dp_phy_mode_reg) + regmap_write(qmp->tcsr_map, qmp->dp_phy_mode_reg, is_dp); +} + +static int qmp_usbc_com_init(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; - void __iomem *pcs = qmp->pcs; - u32 val = 0; int ret; ret = regulator_bulk_enable(cfg->num_vregs, qmp->vregs); @@ -484,16 +720,6 @@ static int qmp_usbc_init(struct phy *phy) if (ret) goto err_assert_reset; - qphy_setbits(pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); - -#define SW_PORTSELECT_VAL BIT(0) -#define SW_PORTSELECT_MUX BIT(1) - /* Use software based port select and switch on typec orientation */ - val = SW_PORTSELECT_MUX; - if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) - val |= SW_PORTSELECT_VAL; - writel(val, qmp->pcs_misc); - return 0; err_assert_reset: @@ -504,7 +730,7 @@ static int qmp_usbc_init(struct phy *phy) return ret; } -static int qmp_usbc_exit(struct phy *phy) +static int qmp_usbc_com_exit(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -518,7 +744,254 @@ static int qmp_usbc_exit(struct phy *phy) return 0; } -static int qmp_usbc_power_on(struct phy *phy) +static void qmp_v2_dp_aux_init(struct qmp_usbc *qmp) +{ + writel(DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + writel(DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN, + qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG0); + writel(0x13, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG2); + writel(0x00, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG3); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG4); + writel(0x26, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG5); + writel(0x0a, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG6); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG7); + writel(0xbb, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG8); + writel(0x03, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG9); + qmp->dp_aux_cfg = 0; + + writel(PHY_AUX_STOP_ERR_MASK | PHY_AUX_DEC_ERR_MASK | + PHY_AUX_SYNC_ERR_MASK | PHY_AUX_ALIGN_ERR_MASK | + PHY_AUX_REQ_ERR_MASK, + qmp->dp_dp_phy + QSERDES_V2_DP_PHY_AUX_INTERRUPT_MASK); +} + +static int qmp_v2_configure_dp_swing(struct qmp_usbc *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + unsigned int v_level = 0, p_level = 0; + u8 voltage_swing_cfg, pre_emphasis_cfg; + int i; + + if (dp_opts->lanes > 4) { + dev_err(qmp->dev, "Invalid lane_num(%d)\n", dp_opts->lanes); + return -EINVAL; + } + + for (i = 0; i < dp_opts->lanes; i++) { + v_level = max(v_level, dp_opts->voltage[i]); + p_level = max(p_level, dp_opts->pre[i]); + } + + if (v_level > 4 || p_level > 4) { + dev_err(qmp->dev, "Invalid v(%d) | p(%d) level)\n", + v_level, p_level); + return -EINVAL; + } + + voltage_swing_cfg = (*cfg->swing_tbl)[v_level][p_level]; + pre_emphasis_cfg = (*cfg->pre_emphasis_tbl)[v_level][p_level]; + + voltage_swing_cfg |= DP_PHY_TXn_TX_DRV_LVL_MUX_EN; + pre_emphasis_cfg |= DP_PHY_TXn_TX_EMP_POST1_LVL_MUX_EN; + + if (voltage_swing_cfg == 0xff && pre_emphasis_cfg == 0xff) + return -EINVAL; + + writel(voltage_swing_cfg, tx + QSERDES_V2_TX_TX_DRV_LVL); + writel(pre_emphasis_cfg, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); + writel(voltage_swing_cfg, tx2 + QSERDES_V2_TX_TX_DRV_LVL); + writel(pre_emphasis_cfg, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); + + return 0; +} + +static void qmp_usbc_configure_dp_mode(struct qmp_usbc *qmp) +{ + bool reverse = (qmp->orientation == TYPEC_ORIENTATION_REVERSE); + u32 val; + + val = DP_PHY_PD_CTL_PWRDN | DP_PHY_PD_CTL_AUX_PWRDN | + DP_PHY_PD_CTL_PLL_PWRDN | DP_PHY_PD_CTL_LANE_0_1_PWRDN | DP_PHY_PD_CTL_LANE_2_3_PWRDN; + + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + if (reverse) + writel(0xc9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); + else + writel(0xd9, qmp->dp_dp_phy + QSERDES_DP_PHY_MODE); +} + +static int qmp_usbc_configure_dp_clocks(struct qmp_usbc *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + u32 phy_vco_div; + unsigned long pixel_freq; + + switch (dp_opts->link_rate) { + case 1620: + phy_vco_div = 0x1; + pixel_freq = 1620000000UL / 2; + break; + case 2700: + phy_vco_div = 0x1; + pixel_freq = 2700000000UL / 2; + break; + case 5400: + phy_vco_div = 0x2; + pixel_freq = 5400000000UL / 4; + break; + default: + dev_err(qmp->dev, "link rate:%d not supported\n", dp_opts->link_rate); + return -EINVAL; + } + writel(phy_vco_div, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_VCO_DIV); + + clk_set_rate(qmp->dp_link_hw.clk, dp_opts->link_rate * 100000); + clk_set_rate(qmp->dp_pixel_hw.clk, pixel_freq); + + return 0; +} + +static void qmp_v2_configure_dp_tx(struct qmp_usbc *qmp) +{ + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + + /* program default setting first */ + writel(0x2a, tx + QSERDES_V2_TX_TX_DRV_LVL); + writel(0x20, tx + QSERDES_V2_TX_TX_EMP_POST1_LVL); + writel(0x2a, tx2 + QSERDES_V2_TX_TX_DRV_LVL); + writel(0x20, tx2 + QSERDES_V2_TX_TX_EMP_POST1_LVL); + + if (dp_opts->link_rate >= 2700) { + writel(0xc4, tx + QSERDES_V2_TX_LANE_MODE_1); + writel(0xc4, tx2 + QSERDES_V2_TX_LANE_MODE_1); + } else { + writel(0xc6, tx + QSERDES_V2_TX_LANE_MODE_1); + writel(0xc6, tx2 + QSERDES_V2_TX_LANE_MODE_1); + } + + qmp_v2_configure_dp_swing(qmp); +} + +static int qmp_v2_configure_dp_phy(struct qmp_usbc *qmp) +{ + u32 status; + int ret; + + qmp_usbc_configure_dp_mode(qmp); + + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX0_TX1_LANE_CTL); + writel(0x05, qmp->dp_dp_phy + QSERDES_V2_DP_PHY_TX2_TX3_LANE_CTL); + + ret = qmp_usbc_configure_dp_clocks(qmp); + if (ret) + return ret; + + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x05, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x01, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x09, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + writel(0x20, qmp->dp_serdes + QSERDES_COM_RESETSM_CNTRL); + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_C_READY_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)) { + dev_err(qmp->dev, "C_READY not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "FREQ_DONE not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_serdes + QSERDES_COM_CMN_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PLL_LOCKED not ready\n"); + return -ETIMEDOUT; + } + + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(0)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "TSYNC_DONE not ready\n"); + return -ETIMEDOUT; + } + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PHY_READY not ready\n"); + return -ETIMEDOUT; + } + + writel(0x3f, qmp->dp_tx + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); + writel(0x10, qmp->dp_tx + QSERDES_V2_TX_HIGHZ_DRVR_EN); + writel(0x0a, qmp->dp_tx + QSERDES_V2_TX_TX_POL_INV); + writel(0x3f, qmp->dp_tx2 + QSERDES_V2_TX_TRANSCEIVER_BIAS_EN); + writel(0x10, qmp->dp_tx2 + QSERDES_V2_TX_HIGHZ_DRVR_EN); + writel(0x0a, qmp->dp_tx2 + QSERDES_V2_TX_TX_POL_INV); + + writel(0x18, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + writel(0x19, qmp->dp_dp_phy + QSERDES_DP_PHY_CFG); + + if (readl_poll_timeout(qmp->dp_dp_phy + QSERDES_V2_DP_PHY_STATUS, + status, + ((status & BIT(1)) > 0), + 500, + 10000)){ + dev_err(qmp->dev, "PHY_READY not ready\n"); + return -ETIMEDOUT; + } + + return 0; +} + +static int qmp_v2_calibrate_dp_phy(struct qmp_usbc *qmp) +{ + static const u8 cfg1_settings[] = {0x13, 0x23, 0x1d}; + u8 val; + + qmp->dp_aux_cfg++; + qmp->dp_aux_cfg %= ARRAY_SIZE(cfg1_settings); + val = cfg1_settings[qmp->dp_aux_cfg]; + + writel(val, qmp->dp_dp_phy + QSERDES_DP_PHY_AUX_CFG1); + + return 0; +} + +static int qmp_usbc_usb_power_on(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -526,6 +999,14 @@ static int qmp_usbc_power_on(struct phy *phy) unsigned int val; int ret; + qphy_setbits(qmp->pcs, cfg->regs[QPHY_PCS_POWER_DOWN_CONTROL], SW_PWRDN); + + /* Use software based port select and switch on typec orientation */ + val = SW_PORTSELECT_MUX; + if (qmp->orientation == TYPEC_ORIENTATION_REVERSE) + val |= SW_PORTSELECT_VAL; + writel(val, qmp->pcs_misc); + qmp_configure(qmp->dev, qmp->serdes, cfg->serdes_tbl, cfg->serdes_tbl_num); @@ -566,7 +1047,7 @@ static int qmp_usbc_power_on(struct phy *phy) return ret; } -static int qmp_usbc_power_off(struct phy *phy) +static int qmp_usbc_usb_power_off(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); const struct qmp_phy_cfg *cfg = qmp->cfg; @@ -587,20 +1068,39 @@ static int qmp_usbc_power_off(struct phy *phy) return 0; } -static int qmp_usbc_enable(struct phy *phy) +static int qmp_usbc_check_phy_status(struct qmp_usbc *qmp, bool is_dp) +{ + if ((is_dp && qmp->usb_init_count) || + (!is_dp && qmp->dp_init_count)) { + dev_err(qmp->dev, + "PHY is configured for %s, can not enable %s\n", + is_dp ? "USB" : "DP", is_dp ? "DP" : "USB"); + return -EBUSY; + } + + return 0; +} + +static int qmp_usbc_usb_enable(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); int ret; mutex_lock(&qmp->phy_mutex); - ret = qmp_usbc_init(phy); + ret = qmp_usbc_check_phy_status(qmp, false); if (ret) goto out_unlock; - ret = qmp_usbc_power_on(phy); + ret = qmp_usbc_com_init(phy); + if (ret) + goto out_unlock; + + qmp_usbc_set_phy_mode(qmp, false); + + ret = qmp_usbc_usb_power_on(phy); if (ret) { - qmp_usbc_exit(phy); + qmp_usbc_com_exit(phy); goto out_unlock; } @@ -611,19 +1111,19 @@ static int qmp_usbc_enable(struct phy *phy) return ret; } -static int qmp_usbc_disable(struct phy *phy) +static int qmp_usbc_usb_disable(struct phy *phy) { struct qmp_usbc *qmp = phy_get_drvdata(phy); int ret; qmp->usb_init_count--; - ret = qmp_usbc_power_off(phy); + ret = qmp_usbc_usb_power_off(phy); if (ret) return ret; - return qmp_usbc_exit(phy); + return qmp_usbc_com_exit(phy); } -static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) +static int qmp_usbc_usb_set_mode(struct phy *phy, enum phy_mode mode, int submode) { struct qmp_usbc *qmp = phy_get_drvdata(phy); @@ -632,10 +1132,185 @@ static int qmp_usbc_set_mode(struct phy *phy, enum phy_mode mode, int submode) return 0; } -static const struct phy_ops qmp_usbc_phy_ops = { - .init = qmp_usbc_enable, - .exit = qmp_usbc_disable, - .set_mode = qmp_usbc_set_mode, +static int qmp_usbc_dp_enable(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + int ret; + + if (qmp->dp_init_count) { + dev_err(qmp->dev, "DP already inited\n"); + return 0; + } + + mutex_lock(&qmp->phy_mutex); + + ret = qmp_usbc_check_phy_status(qmp, true); + if (ret) + goto dp_init_unlock; + + ret = qmp_usbc_com_init(phy); + if (ret) + goto dp_init_unlock; + + qmp_usbc_set_phy_mode(qmp, true); + + cfg->dp_aux_init(qmp); + + qmp->dp_init_count++; + +dp_init_unlock: + mutex_unlock(&qmp->phy_mutex); + return ret; +} + +static int qmp_usbc_dp_disable(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + + mutex_lock(&qmp->phy_mutex); + + qmp_usbc_com_exit(phy); + + qmp->dp_init_count--; + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_dp *dp_opts = &opts->dp; + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + + mutex_lock(&qmp->phy_mutex); + + memcpy(&qmp->dp_opts, dp_opts, sizeof(*dp_opts)); + if (qmp->dp_opts.set_voltages) { + cfg->configure_dp_tx(qmp); + qmp->dp_opts.set_voltages = 0; + } + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_calibrate(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + int ret = 0; + + mutex_lock(&qmp->phy_mutex); + + if (cfg->calibrate_dp_phy) { + ret = cfg->calibrate_dp_phy(qmp); + if (ret) { + dev_err(qmp->dev, "dp calibrate err(%d)\n", ret); + mutex_unlock(&qmp->phy_mutex); + return ret; + } + } + + mutex_unlock(&qmp->phy_mutex); + return 0; +} + +static int qmp_usbc_dp_serdes_init(struct qmp_usbc *qmp) +{ + const struct qmp_phy_cfg *cfg = qmp->cfg; + void __iomem *serdes = qmp->dp_serdes; + const struct phy_configure_opts_dp *dp_opts = &qmp->dp_opts; + + qmp_configure(qmp->dev, serdes, cfg->dp_serdes_tbl, + cfg->dp_serdes_tbl_num); + + switch (dp_opts->link_rate) { + case 1620: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_rbr, + cfg->serdes_tbl_rbr_num); + break; + case 2700: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr, + cfg->serdes_tbl_hbr_num); + break; + case 5400: + qmp_configure(qmp->dev, serdes, cfg->serdes_tbl_hbr2, + cfg->serdes_tbl_hbr2_num); + break; + default: + /* Other link rates aren't supported */ + return -EINVAL; + } + + return 0; +} + +static int qmp_usbc_dp_power_on(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + const struct qmp_phy_cfg *cfg = qmp->cfg; + + void __iomem *tx = qmp->dp_tx; + void __iomem *tx2 = qmp->dp_tx2; + + /* + * FIXME: SW_PORTSELECT handling for DP orientation flip is not implemented. + * Expected: + * - For standard lane mapping: configure SW_PORTSELECT in QSERDES_DP_PHY_CFG_1. + * - For non-standard mapping: pass orientation to dp_ctrl and handle flip + * via logical2physical lane remapping. + */ + + mutex_lock(&qmp->phy_mutex); + + qmp_usbc_dp_serdes_init(qmp); + + qmp_configure_lane(qmp->dev, tx, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 1); + qmp_configure_lane(qmp->dev, tx2, cfg->dp_tx_tbl, cfg->dp_tx_tbl_num, 2); + + /* Configure special DP tx tunings */ + cfg->configure_dp_tx(qmp); + + /* Configure link rate, swing, etc. */ + cfg->configure_dp_phy(qmp); + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static int qmp_usbc_dp_power_off(struct phy *phy) +{ + struct qmp_usbc *qmp = phy_get_drvdata(phy); + + mutex_lock(&qmp->phy_mutex); + + /* Assert DP PHY power down */ + writel(DP_PHY_PD_CTL_PSR_PWRDN, qmp->dp_dp_phy + QSERDES_DP_PHY_PD_CTL); + + mutex_unlock(&qmp->phy_mutex); + + return 0; +} + +static const struct phy_ops qmp_usbc_usb_phy_ops = { + .init = qmp_usbc_usb_enable, + .exit = qmp_usbc_usb_disable, + .set_mode = qmp_usbc_usb_set_mode, + .owner = THIS_MODULE, +}; + +static const struct phy_ops qmp_usbc_dp_phy_ops = { + .init = qmp_usbc_dp_enable, + .exit = qmp_usbc_dp_disable, + .configure = qmp_usbc_dp_configure, + .calibrate = qmp_usbc_dp_calibrate, + .power_on = qmp_usbc_dp_power_on, + .power_off = qmp_usbc_dp_power_off, .owner = THIS_MODULE, }; @@ -690,7 +1365,7 @@ static int __maybe_unused qmp_usbc_runtime_suspend(struct device *dev) dev_vdbg(dev, "Suspending QMP phy, mode:%d\n", qmp->mode); - if (!qmp->phy->init_count) { + if (!qmp->usb_init_count && !qmp->dp_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } @@ -710,7 +1385,7 @@ static int __maybe_unused qmp_usbc_runtime_resume(struct device *dev) dev_vdbg(dev, "Resuming QMP phy, mode:%d\n", qmp->mode); - if (!qmp->phy->init_count) { + if (!qmp->usb_init_count && !qmp->dp_init_count) { dev_vdbg(dev, "PHY not initialized, bailing out\n"); return 0; } @@ -736,23 +1411,6 @@ static const struct dev_pm_ops qmp_usbc_pm_ops = { qmp_usbc_runtime_resume, NULL) }; -static int qmp_usbc_vreg_init(struct qmp_usbc *qmp) -{ - const struct qmp_phy_cfg *cfg = qmp->cfg; - struct device *dev = qmp->dev; - int num = cfg->num_vregs; - int i; - - qmp->vregs = devm_kcalloc(dev, num, sizeof(*qmp->vregs), GFP_KERNEL); - if (!qmp->vregs) - return -ENOMEM; - - for (i = 0; i < num; i++) - qmp->vregs[i].supply = cfg->vreg_list[i]; - - return devm_regulator_bulk_get(dev, num, qmp->vregs); -} - static int qmp_usbc_reset_init(struct qmp_usbc *qmp, const char *const *reset_list, int num_resets) @@ -796,9 +1454,23 @@ static int qmp_usbc_clk_init(struct qmp_usbc *qmp) return devm_clk_bulk_get_optional(dev, num, qmp->clks); } -static void phy_clk_release_provider(void *res) +static struct clk_hw *qmp_usbc_clks_hw_get(struct of_phandle_args *clkspec, void *data) { - of_clk_del_provider(res); + struct qmp_usbc *qmp = data; + + if (clkspec->args_count == 0) + return &qmp->pipe_clk_fixed.hw; + + switch (clkspec->args[0]) { + case QMP_USB43DP_USB3_PIPE_CLK: + return &qmp->pipe_clk_fixed.hw; + case QMP_USB43DP_DP_LINK_CLK: + return &qmp->dp_link_hw; + case QMP_USB43DP_DP_VCO_DIV_CLK: + return &qmp->dp_pixel_hw; + } + + return ERR_PTR(-EINVAL); } /* @@ -823,12 +1495,14 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) { struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; struct clk_init_data init = { }; + char name[64]; int ret; ret = of_property_read_string(np, "clock-output-names", &init.name); if (ret) { - dev_err(qmp->dev, "%pOFn: No clock-output-names\n", np); - return ret; + /* Clock name is not mandatory. */ + snprintf(name, sizeof(name), "%s::pipe_clk", dev_name(qmp->dev)); + init.name = name; } init.ops = &clk_fixed_rate_ops; @@ -837,10 +1511,183 @@ static int phy_pipe_clk_register(struct qmp_usbc *qmp, struct device_node *np) fixed->fixed_rate = 125000000; fixed->hw.init = &init; - ret = devm_clk_hw_register(qmp->dev, &fixed->hw); + return devm_clk_hw_register(qmp->dev, &fixed->hw); +} + +/* + * Display Port PLL driver block diagram for branch clocks + * + * +------------------------------+ + * | DP_VCO_CLK | + * | | + * | +-------------------+ | + * | | (DP PLL/VCO) | | + * | +---------+---------+ | + * | v | + * | +----------+-----------+ | + * | | hsclk_divsel_clk_src | | + * | +----------+-----------+ | + * +------------------------------+ + * | + * +---------<---------v------------>----------+ + * | | + * +--------v----------------+ | + * | dp_phy_pll_link_clk | | + * | link_clk | | + * +--------+----------------+ | + * | | + * | | + * v v + * Input to DISPCC block | + * for link clk, crypto clk | + * and interface clock | + * | + * | + * +--------<------------+-----------------+---<---+ + * | | | + * +----v---------+ +--------v-----+ +--------v------+ + * | vco_divided | | vco_divided | | vco_divided | + * | _clk_src | | _clk_src | | _clk_src | + * | | | | | | + * |divsel_six | | divsel_two | | divsel_four | + * +-------+------+ +-----+--------+ +--------+------+ + * | | | + * v---->----------v-------------<------v + * | + * +----------+-----------------+ + * | dp_phy_pll_vco_div_clk | + * +---------+------------------+ + * | + * v + * Input to DISPCC block + * for DP pixel clock + * + */ +static int qmp_dp_pixel_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + switch (req->rate) { + case 1620000000UL / 2: + case 2700000000UL / 2: + /* 5.4 is same link rate as 2.7GHz, i.e. div 4 */ + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_pixel_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp = container_of(hw, struct qmp_usbc, dp_pixel_hw); + + dp_opts = &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + return 1620000000UL / 2; + case 2700: + return 2700000000UL / 2; + case 5400: + return 5400000000UL / 4; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_pixel_clk_ops = { + .determine_rate = qmp_dp_pixel_clk_determine_rate, + .recalc_rate = qmp_dp_pixel_clk_recalc_rate, +}; + +static int qmp_dp_link_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) +{ + switch (req->rate) { + case 162000000: + case 270000000: + case 540000000: + return 0; + default: + return -EINVAL; + } +} + +static unsigned long qmp_dp_link_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) +{ + const struct qmp_usbc *qmp; + const struct phy_configure_opts_dp *dp_opts; + + qmp = container_of(hw, struct qmp_usbc, dp_link_hw); + dp_opts = &qmp->dp_opts; + + switch (dp_opts->link_rate) { + case 1620: + case 2700: + case 5400: + return dp_opts->link_rate * 100000; + default: + return 0; + } +} + +static const struct clk_ops qmp_dp_link_clk_ops = { + .determine_rate = qmp_dp_link_clk_determine_rate, + .recalc_rate = qmp_dp_link_clk_recalc_rate, +}; + +static int phy_dp_clks_register(struct qmp_usbc *qmp, struct device_node *np) +{ + struct clk_init_data init = { }; + char name[64]; + int ret; + + snprintf(name, sizeof(name), "%s::link_clk", dev_name(qmp->dev)); + init.ops = &qmp_dp_link_clk_ops; + init.name = name; + qmp->dp_link_hw.init = &init; + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_link_hw); + if (ret < 0) { + dev_err(qmp->dev, "link clk reg fail ret=%d\n", ret); + return ret; + } + + snprintf(name, sizeof(name), "%s::vco_div_clk", dev_name(qmp->dev)); + init.ops = &qmp_dp_pixel_clk_ops; + init.name = name; + qmp->dp_pixel_hw.init = &init; + ret = devm_clk_hw_register(qmp->dev, &qmp->dp_pixel_hw); + if (ret) { + dev_err(qmp->dev, "pxl clk reg fail ret=%d\n", ret); + return ret; + } + + return 0; +} + +static void phy_clk_release_provider(void *res) +{ + of_clk_del_provider(res); +} + +static int qmp_usbc_register_clocks(struct qmp_usbc *qmp, struct device_node *np) +{ + struct clk_fixed_rate *fixed = &qmp->pipe_clk_fixed; + int ret; + + ret = phy_pipe_clk_register(qmp, np); if (ret) return ret; + if (qmp->dp_serdes != 0) { + ret = phy_dp_clks_register(qmp, np); + if (ret) + return ret; + } + + if (np == qmp->dev->of_node) + return devm_of_clk_add_hw_provider(qmp->dev, qmp_usbc_clks_hw_get, qmp); + ret = of_clk_add_hw_provider(np, of_clk_hw_simple_get, &fixed->hw); if (ret) return ret; @@ -865,11 +1712,12 @@ static int qmp_usbc_typec_switch_set(struct typec_switch_dev *sw, qmp->orientation = orientation; if (qmp->usb_init_count) { - qmp_usbc_power_off(qmp->phy); - qmp_usbc_exit(qmp->phy); + qmp_usbc_usb_power_off(qmp->usb_phy); + qmp_usbc_com_exit(qmp->usb_phy); - qmp_usbc_init(qmp->phy); - qmp_usbc_power_on(qmp->phy); + qmp_usbc_com_init(qmp->usb_phy); + qmp_usbc_set_phy_mode(qmp, false); + qmp_usbc_usb_power_on(qmp->usb_phy); } mutex_unlock(&qmp->phy_mutex); @@ -985,6 +1833,13 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) if (IS_ERR(base)) return PTR_ERR(base); + if (offs->dp_serdes != 0) { + qmp->dp_serdes = base + offs->dp_serdes; + qmp->dp_tx = base + offs->dp_txa; + qmp->dp_tx2 = base + offs->dp_txb; + qmp->dp_dp_phy = base + offs->dp_dp_phy; + } + qmp->serdes = base + offs->serdes; qmp->pcs = base + offs->pcs; if (offs->pcs_misc) @@ -1005,23 +1860,23 @@ static int qmp_usbc_parse_dt(struct qmp_usbc *qmp) "failed to get pipe clock\n"); } - ret = qmp_usbc_reset_init(qmp, usb3phy_reset_l, - ARRAY_SIZE(usb3phy_reset_l)); + ret = qmp_usbc_reset_init(qmp, cfg->reset_list, cfg->num_resets); if (ret) return ret; return 0; } -static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) +static int qmp_usbc_parse_tcsr(struct qmp_usbc *qmp) { struct of_phandle_args tcsr_args; struct device *dev = qmp->dev; - int ret; + int ret, args_count; - /* for backwards compatibility ignore if there is no property */ - ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", 1, 0, - &tcsr_args); + args_count = of_property_count_u32_elems(dev->of_node, "qcom,tcsr-reg"); + args_count = args_count - 1; + ret = of_parse_phandle_with_fixed_args(dev->of_node, "qcom,tcsr-reg", + args_count, 0, &tcsr_args); if (ret == -ENOENT) return 0; else if (ret < 0) @@ -1034,9 +1889,29 @@ static int qmp_usbc_parse_vls_clamp(struct qmp_usbc *qmp) qmp->vls_clamp_reg = tcsr_args.args[0]; + if (args_count > 1) + qmp->dp_phy_mode_reg = tcsr_args.args[1]; + return 0; } +static struct phy *qmp_usbc_phy_xlate(struct device *dev, const struct of_phandle_args *args) +{ + struct qmp_usbc *qmp = dev_get_drvdata(dev); + + if (args->args_count == 0) + return qmp->usb_phy; + + switch (args->args[0]) { + case QMP_USB43DP_USB3_PHY: + return qmp->usb_phy; + case QMP_USB43DP_DP_PHY: + return qmp->dp_phy ?: ERR_PTR(-ENODEV); + } + + return ERR_PTR(-EINVAL); +} + static int qmp_usbc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -1060,7 +1935,8 @@ static int qmp_usbc_probe(struct platform_device *pdev) mutex_init(&qmp->phy_mutex); - ret = qmp_usbc_vreg_init(qmp); + ret = devm_regulator_bulk_get_const(qmp->dev, qmp->cfg->num_vregs, + qmp->cfg->vreg_list, &qmp->vregs); if (ret) return ret; @@ -1068,7 +1944,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) if (ret) return ret; - ret = qmp_usbc_parse_vls_clamp(qmp); + ret = qmp_usbc_parse_tcsr(qmp); if (ret) return ret; @@ -1093,22 +1969,32 @@ static int qmp_usbc_probe(struct platform_device *pdev) */ pm_runtime_forbid(dev); - ret = phy_pipe_clk_register(qmp, np); + ret = qmp_usbc_register_clocks(qmp, np); if (ret) goto err_node_put; - qmp->phy = devm_phy_create(dev, np, &qmp_usbc_phy_ops); - if (IS_ERR(qmp->phy)) { - ret = PTR_ERR(qmp->phy); + qmp->usb_phy = devm_phy_create(dev, np, &qmp_usbc_usb_phy_ops); + if (IS_ERR(qmp->usb_phy)) { + ret = PTR_ERR(qmp->usb_phy); dev_err(dev, "failed to create PHY: %d\n", ret); goto err_node_put; } - phy_set_drvdata(qmp->phy, qmp); + phy_set_drvdata(qmp->usb_phy, qmp); + + if (qmp->dp_serdes != 0) { + qmp->dp_phy = devm_phy_create(dev, np, &qmp_usbc_dp_phy_ops); + if (IS_ERR(qmp->dp_phy)) { + ret = PTR_ERR(qmp->dp_phy); + dev_err(dev, "failed to create PHY: %d\n", ret); + goto err_node_put; + } + phy_set_drvdata(qmp->dp_phy, qmp); + } of_node_put(np); - phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + phy_provider = devm_of_phy_provider_register(dev, qmp_usbc_phy_xlate); return PTR_ERR_OR_ZERO(phy_provider); @@ -1124,9 +2010,12 @@ static const struct of_device_id qmp_usbc_of_match_table[] = { }, { .compatible = "qcom,qcm2290-qmp-usb3-phy", .data = &qcm2290_usb3phy_cfg, + }, { + .compatible = "qcom,qcs615-qmp-usb3-dp-phy", + .data = &qcs615_usb3dp_phy_cfg, }, { .compatible = "qcom,qcs615-qmp-usb3-phy", - .data = &qcm2290_usb3phy_cfg, + .data = &qcs615_usb3phy_cfg, }, { .compatible = "qcom,sdm660-qmp-usb3-phy", .data = &sdm660_usb3phy_cfg, diff --git a/drivers/phy/qualcomm/phy-qcom-qmp.h b/drivers/phy/qualcomm/phy-qcom-qmp.h index da2a7ad2cdcc..a873bdd7bffe 100644 --- a/drivers/phy/qualcomm/phy-qcom-qmp.h +++ b/drivers/phy/qualcomm/phy-qcom-qmp.h @@ -9,6 +9,9 @@ #include "phy-qcom-qmp-qserdes-com.h" #include "phy-qcom-qmp-qserdes-txrx.h" +#include "phy-qcom-qmp-qserdes-com-v2.h" +#include "phy-qcom-qmp-qserdes-txrx-v2.h" + #include "phy-qcom-qmp-qserdes-com-v3.h" #include "phy-qcom-qmp-qserdes-txrx-v3.h" @@ -32,7 +35,9 @@ #include "phy-qcom-qmp-qserdes-txrx-v7.h" #include "phy-qcom-qmp-qserdes-com-v8.h" +#include "phy-qcom-qmp-usb43-qserdes-com-v8.h" #include "phy-qcom-qmp-qserdes-txrx-v8.h" +#include "phy-qcom-qmp-qserdes-lalb-v8.h" #include "phy-qcom-qmp-qserdes-pll.h" diff --git a/drivers/phy/renesas/Kconfig b/drivers/phy/renesas/Kconfig index 16211072098e..90a9ca2db7fc 100644 --- a/drivers/phy/renesas/Kconfig +++ b/drivers/phy/renesas/Kconfig @@ -29,7 +29,9 @@ config PHY_RCAR_GEN3_USB2 depends on ARCH_RENESAS depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in depends on USB_SUPPORT + depends on REGULATOR select GENERIC_PHY + select MULTIPLEXER select USB_COMMON help Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs. diff --git a/drivers/phy/renesas/phy-rcar-gen2.c b/drivers/phy/renesas/phy-rcar-gen2.c index c0221e7258c0..6c671254c625 100644 --- a/drivers/phy/renesas/phy-rcar-gen2.c +++ b/drivers/phy/renesas/phy-rcar-gen2.c @@ -85,7 +85,7 @@ static int rcar_gen2_phy_init(struct phy *p) * Try to acquire exclusive access to PHY. The first driver calling * phy_init() on a given channel wins, and all attempts to use another * PHY on this channel will fail until phy_exit() is called by the first - * driver. Achieving this with cmpxcgh() should be SMP-safe. + * driver. Achieving this with cmpxchg() should be SMP-safe. */ if (cmpxchg(&channel->selected_phy, -1, phy->number) != -1) return -EBUSY; @@ -337,7 +337,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rcar_gen2_phy_driver *drv; struct phy_provider *provider; - struct device_node *np; void __iomem *base; struct clk *clk; const struct rcar_gen2_phy_data *data; @@ -379,7 +378,7 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) if (!drv->channels) return -ENOMEM; - for_each_child_of_node(dev->of_node, np) { + for_each_child_of_node_scoped(dev->of_node, np) { struct rcar_gen2_channel *channel = drv->channels + i; u32 channel_num; int error, n; @@ -391,7 +390,6 @@ static int rcar_gen2_phy_probe(struct platform_device *pdev) error = of_property_read_u32(np, "reg", &channel_num); if (error || channel_num >= data->num_channels) { dev_err(dev, "Invalid \"reg\" property\n"); - of_node_put(np); return error; } channel->select_mask = select_mask[channel_num]; diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c index 582de10d5beb..cfc2a8d9028d 100644 --- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c +++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c @@ -17,11 +17,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -141,6 +143,7 @@ struct rcar_gen3_chan { bool extcon_host; bool is_otg_channel; bool uses_otg_pins; + bool otg_internal_reg; }; struct rcar_gen3_phy_drv_data { @@ -204,28 +207,43 @@ static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm) writel(val, usb2_base + USB2_LINECTRL1); } -static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) +static void rcar_gen3_phy_usb2_set_vbus(struct rcar_gen3_chan *ch, + u32 vbus_ctrl_reg, + u32 vbus_ctrl_val, + bool enable) { void __iomem *usb2_base = ch->base; - u32 vbus_ctrl_reg = USB2_ADPCTRL; - u32 vbus_ctrl_val = USB2_ADPCTRL_DRVVBUS; u32 val; + val = readl(usb2_base + vbus_ctrl_reg); + if (enable) + val |= vbus_ctrl_val; + else + val &= ~vbus_ctrl_val; + writel(val, usb2_base + vbus_ctrl_reg); + + dev_vdbg(ch->dev, "%s: reg=0x%08x, val=%08x, enable=%d\n", + __func__, vbus_ctrl_reg, val, enable); +} + +static void rcar_gen3_enable_vbus_ctrl(struct rcar_gen3_chan *ch, int vbus) +{ + if (ch->otg_internal_reg) { + regulator_hardware_enable(ch->vbus, vbus); + return; + } + if (ch->phy_data->no_adp_ctrl || ch->phy_data->vblvl_ctrl) { if (ch->vbus) regulator_hardware_enable(ch->vbus, vbus); - vbus_ctrl_reg = USB2_VBCTRL; - vbus_ctrl_val = USB2_VBCTRL_VBOUT; + rcar_gen3_phy_usb2_set_vbus(ch, USB2_VBCTRL, + USB2_VBCTRL_VBOUT, vbus); + return; } - val = readl(usb2_base + vbus_ctrl_reg); - if (vbus) - val |= vbus_ctrl_val; - else - val &= ~vbus_ctrl_val; - dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, vbus); - writel(val, usb2_base + vbus_ctrl_reg); + rcar_gen3_phy_usb2_set_vbus(ch, USB2_ADPCTRL, + USB2_ADPCTRL_DRVVBUS, vbus); } static void rcar_gen3_control_otg_irq(struct rcar_gen3_chan *ch, int enable) @@ -583,7 +601,7 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p) u32 val; int ret = 0; - if (channel->vbus) { + if (channel->vbus && !channel->otg_internal_reg) { ret = regulator_enable(channel->vbus); if (ret) return ret; @@ -624,7 +642,7 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p) } } - if (channel->vbus) + if (channel->vbus && !channel->otg_internal_reg) ret = regulator_disable(channel->vbus); return ret; @@ -799,11 +817,149 @@ static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) return 0; } +static int rcar_gen3_phy_usb2_regulator_endisable(struct regulator_dev *rdev, + bool enable) +{ + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); + struct device *dev = channel->dev; + int ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); + return ret; + } + + rcar_gen3_phy_usb2_set_vbus(channel, USB2_VBCTRL, + USB2_VBCTRL_VBOUT, enable); + pm_runtime_put_noidle(dev); + + return ret; +} + +static int rcar_gen3_phy_usb2_regulator_enable(struct regulator_dev *rdev) +{ + return rcar_gen3_phy_usb2_regulator_endisable(rdev, true); +} + +static int rcar_gen3_phy_usb2_regulator_disable(struct regulator_dev *rdev) +{ + return rcar_gen3_phy_usb2_regulator_endisable(rdev, false); +} + +static int rcar_gen3_phy_usb2_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct rcar_gen3_chan *channel = rdev_get_drvdata(rdev); + void __iomem *usb2_base = channel->base; + struct device *dev = channel->dev; + u32 vbus_ctrl_reg = USB2_VBCTRL; + u32 val; + int ret; + + ret = pm_runtime_resume_and_get(dev); + if (ret < 0) { + dev_warn(dev, "pm_runtime_get failed: %i\n", ret); + return ret; + } + + val = readl(usb2_base + vbus_ctrl_reg); + + pm_runtime_put_noidle(dev); + dev_dbg(channel->dev, "%s: %08x\n", __func__, val); + + return (val & USB2_VBCTRL_VBOUT) ? 1 : 0; +} + +static const struct regulator_ops rcar_gen3_phy_usb2_regulator_ops = { + .enable = rcar_gen3_phy_usb2_regulator_enable, + .disable = rcar_gen3_phy_usb2_regulator_disable, + .is_enabled = rcar_gen3_phy_usb2_regulator_is_enabled, +}; + +static const struct regulator_desc rcar_gen3_phy_usb2_regulator = { + .name = "otg-vbus-regulator", + .of_match = of_match_ptr("vbus-regulator"), + .ops = &rcar_gen3_phy_usb2_regulator_ops, + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .fixed_uV = 5000000, + .n_voltages = 1, +}; + +static void rcar_gen3_phy_usb2_vbus_disable_action(void *data) +{ + struct regulator *vbus = data; + + regulator_disable(vbus); +} + +static int rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(struct rcar_gen3_chan *channel, + bool enable) +{ + struct device *dev = channel->dev; + int ret; + + channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); + if (IS_ERR(channel->vbus)) + return PTR_ERR(channel->vbus); + + if (!enable) + return 0; + + ret = regulator_enable(channel->vbus); + if (ret) + return ret; + + return devm_add_action_or_reset(dev, rcar_gen3_phy_usb2_vbus_disable_action, + channel->vbus); +} + +static int rcar_gen3_phy_usb2_vbus_regulator_register(struct rcar_gen3_chan *channel) +{ + struct device *dev = channel->dev; + struct regulator_config rcfg = { .dev = dev, }; + struct regulator_dev *rdev; + bool enable = false; + + rcfg.of_node = of_get_available_child_by_name(dev->of_node, + "vbus-regulator"); + if (rcfg.of_node) { + rcfg.driver_data = channel; + rdev = devm_regulator_register(dev, &rcar_gen3_phy_usb2_regulator, + &rcfg); + of_node_put(rcfg.of_node); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Failed to create vbus-regulator\n"); + + channel->otg_internal_reg = true; + enable = true; + } + + return rcar_gen3_phy_usb2_vbus_regulator_get_exclusive_enable(channel, enable); +} + +/* Temporary wrapper until the multiplexer subsystem supports optional muxes */ +static inline struct mux_state * +devm_mux_state_get_optional(struct device *dev, const char *mux_name) +{ + if (!of_property_present(dev->of_node, "mux-states")) + return NULL; + + return devm_mux_state_get(dev, mux_name); +} + +static void rcar_gen3_phy_mux_state_deselect(void *data) +{ + mux_state_deselect(data); +} + static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct rcar_gen3_chan *channel; struct phy_provider *provider; + struct mux_state *mux_state; int ret = 0, i, irq; if (!dev->of_node) { @@ -852,78 +1008,87 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev) * devm_phy_create() will call pm_runtime_enable(&phy->dev); * And then, phy-core will manage runtime pm for this device. */ - pm_runtime_enable(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n"); channel->phy_data = of_device_get_match_data(dev); - if (!channel->phy_data) { - ret = -EINVAL; - goto error; - } + if (!channel->phy_data) + return -EINVAL; platform_set_drvdata(pdev, channel); channel->dev = dev; ret = rcar_gen3_phy_usb2_init_bus(channel); if (ret) - goto error; + return ret; spin_lock_init(&channel->lock); for (i = 0; i < NUM_OF_PHYS; i++) { channel->rphys[i].phy = devm_phy_create(dev, NULL, channel->phy_data->phy_usb2_ops); - if (IS_ERR(channel->rphys[i].phy)) { - dev_err(dev, "Failed to create USB2 PHY\n"); - ret = PTR_ERR(channel->rphys[i].phy); - goto error; - } + if (IS_ERR(channel->rphys[i].phy)) + return dev_err_probe(dev, PTR_ERR(channel->rphys[i].phy), + "Failed to create USB2 PHY\n"); + channel->rphys[i].ch = channel; channel->rphys[i].int_enable_bits = rcar_gen3_int_enable[i]; phy_set_drvdata(channel->rphys[i].phy, &channel->rphys[i]); } - if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) - channel->vbus = devm_regulator_get_exclusive(dev, "vbus"); - else + mux_state = devm_mux_state_get_optional(dev, NULL); + if (IS_ERR(mux_state)) + return PTR_ERR(mux_state); + if (mux_state) { + ret = mux_state_select(mux_state); + if (ret) + return dev_err_probe(dev, ret, "Failed to select USB mux\n"); + + ret = devm_add_action_or_reset(dev, rcar_gen3_phy_mux_state_deselect, + mux_state); + if (ret) + return dev_err_probe(dev, ret, + "Failed to register USB mux state deselect\n"); + } + + if (channel->phy_data->no_adp_ctrl && channel->is_otg_channel) { + ret = rcar_gen3_phy_usb2_vbus_regulator_register(channel); + if (ret) + return ret; + } else { channel->vbus = devm_regulator_get_optional(dev, "vbus"); + } if (IS_ERR(channel->vbus)) { - if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) { - ret = PTR_ERR(channel->vbus); - goto error; - } + if (PTR_ERR(channel->vbus) == -EPROBE_DEFER) + return PTR_ERR(channel->vbus); + channel->vbus = NULL; } irq = platform_get_irq_optional(pdev, 0); if (irq < 0 && irq != -ENXIO) { - ret = irq; - goto error; + return irq; } else if (irq > 0) { INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work); ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq, IRQF_SHARED, dev_name(dev), channel); - if (ret < 0) { - dev_err(dev, "Failed to request irq (%d)\n", irq); - goto error; - } + if (ret < 0) + return dev_err_probe(dev, ret, + "Failed to request irq (%d)\n", + irq); } provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate); if (IS_ERR(provider)) { - dev_err(dev, "Failed to register PHY provider\n"); - ret = PTR_ERR(provider); - goto error; + return dev_err_probe(dev, PTR_ERR(provider), + "Failed to register PHY provider\n"); } else if (channel->is_otg_channel) { ret = device_create_file(dev, &dev_attr_role); if (ret < 0) - goto error; + return ret; } return 0; - -error: - pm_runtime_disable(dev); - - return ret; } static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) @@ -932,8 +1097,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) if (channel->is_otg_channel) device_remove_file(&pdev->dev, &dev_attr_role); - - pm_runtime_disable(&pdev->dev); } static int rcar_gen3_phy_usb2_suspend(struct device *dev) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c index 8dcc2bb777b5..1483907413fa 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-hdmi.c @@ -749,22 +749,23 @@ unsigned long inno_hdmi_phy_rk3228_clk_recalc_rate(struct clk_hw *hw, return vco; } -static long inno_hdmi_phy_rk3228_clk_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +static int inno_hdmi_phy_rk3228_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { const struct pre_pll_config *cfg = pre_pll_cfg_table; - rate = (rate / 1000) * 1000; + req->rate = (req->rate / 1000) * 1000; for (; cfg->pixclock != 0; cfg++) - if (cfg->pixclock == rate && !cfg->fracdiv) + if (cfg->pixclock == req->rate && !cfg->fracdiv) break; if (cfg->pixclock == 0) return -EINVAL; - return cfg->pixclock; + req->rate = cfg->pixclock; + + return 0; } static int inno_hdmi_phy_rk3228_clk_set_rate(struct clk_hw *hw, @@ -835,7 +836,7 @@ static const struct clk_ops inno_hdmi_phy_rk3228_clk_ops = { .unprepare = inno_hdmi_phy_rk3228_clk_unprepare, .is_prepared = inno_hdmi_phy_rk3228_clk_is_prepared, .recalc_rate = inno_hdmi_phy_rk3228_clk_recalc_rate, - .round_rate = inno_hdmi_phy_rk3228_clk_round_rate, + .determine_rate = inno_hdmi_phy_rk3228_clk_determine_rate, .set_rate = inno_hdmi_phy_rk3228_clk_set_rate, }; @@ -906,22 +907,23 @@ unsigned long inno_hdmi_phy_rk3328_clk_recalc_rate(struct clk_hw *hw, return inno->pixclock; } -static long inno_hdmi_phy_rk3328_clk_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) +static int inno_hdmi_phy_rk3328_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { const struct pre_pll_config *cfg = pre_pll_cfg_table; - rate = (rate / 1000) * 1000; + req->rate = (req->rate / 1000) * 1000; for (; cfg->pixclock != 0; cfg++) - if (cfg->pixclock == rate) + if (cfg->pixclock == req->rate) break; if (cfg->pixclock == 0) return -EINVAL; - return cfg->pixclock; + req->rate = cfg->pixclock; + + return 0; } static int inno_hdmi_phy_rk3328_clk_set_rate(struct clk_hw *hw, @@ -989,7 +991,7 @@ static const struct clk_ops inno_hdmi_phy_rk3328_clk_ops = { .unprepare = inno_hdmi_phy_rk3328_clk_unprepare, .is_prepared = inno_hdmi_phy_rk3328_clk_is_prepared, .recalc_rate = inno_hdmi_phy_rk3328_clk_recalc_rate, - .round_rate = inno_hdmi_phy_rk3328_clk_round_rate, + .determine_rate = inno_hdmi_phy_rk3328_clk_determine_rate, .set_rate = inno_hdmi_phy_rk3328_clk_set_rate, }; diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c index 7f8fc8e6d489..b60d6bf3f33c 100644 --- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c @@ -529,7 +529,7 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) return -EINVAL; } - if (device_property_read_bool(priv->dev, "rockchip,ext-refclk")) { + if (priv->ext_refclk) { rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { @@ -554,11 +554,9 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) } } - if (priv->type == PHY_TYPE_PCIE) { - if (device_property_read_bool(priv->dev, "rockchip,enable-ssc")) - rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, - RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); - } + if (priv->type == PHY_TYPE_PCIE && priv->enable_ssc) + rockchip_combphy_updatel(priv, RK3528_PHYREG40_SSC_EN, + RK3528_PHYREG40_SSC_EN, RK3528_PHYREG40); return 0; } @@ -582,7 +580,7 @@ static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x101 }, .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, /* pipe-grf */ - .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, + .u3otg0_port_en = { 0x0044, 15, 0, 0x0181, 0x1100 }, }; static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = { diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c index 4508a3147272..0f69060aa5d5 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-dcphy.c @@ -1508,7 +1508,9 @@ static int samsung_mipi_dcphy_exit(struct phy *phy) { struct samsung_mipi_dcphy *samsung = phy_get_drvdata(phy); - return pm_runtime_put(samsung->dev); + pm_runtime_put(samsung->dev); + + return 0; } static const struct phy_ops samsung_mipi_dcphy_ops = { diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c index 29de2f7bdae8..2d973bc37f07 100644 --- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c @@ -22,6 +22,7 @@ #include #define GRF_HDPTX_CON0 0x00 +#define LC_REF_CLK_SEL BIT(11) #define HDPTX_I_PLL_EN BIT(7) #define HDPTX_I_BIAS_EN BIT(6) #define HDPTX_I_BGR_EN BIT(5) @@ -32,17 +33,17 @@ #define HDPTX_O_PHY_RDY BIT(1) #define HDPTX_O_SB_RDY BIT(0) -#define HDTPX_REG(_n, _min, _max) \ +#define HDPTX_REG(_n, _min, _max) \ ( \ BUILD_BUG_ON_ZERO((0x##_n) < (0x##_min)) + \ BUILD_BUG_ON_ZERO((0x##_n) > (0x##_max)) + \ ((0x##_n) * 4) \ ) -#define CMN_REG(n) HDTPX_REG(n, 0000, 00a7) -#define SB_REG(n) HDTPX_REG(n, 0100, 0129) -#define LNTOP_REG(n) HDTPX_REG(n, 0200, 0229) -#define LANE_REG(n) HDTPX_REG(n, 0300, 062d) +#define CMN_REG(n) HDPTX_REG(n, 0000, 00a7) +#define SB_REG(n) HDPTX_REG(n, 0100, 0129) +#define LNTOP_REG(n) HDPTX_REG(n, 0200, 0229) +#define LANE_REG(n) HDPTX_REG(n, 0300, 062d) /* CMN_REG(0008) */ #define OVRD_LCPLL_EN_MASK BIT(7) @@ -322,6 +323,9 @@ #define HDMI14_MAX_RATE 340000000 #define HDMI20_MAX_RATE 600000000 +#define FRL_3G3L_RATE 900000000 +#define FRL_6G3L_RATE 1800000000 +#define FRL_8G4L_RATE 3200000000 enum dp_link_rate { DP_BW_RBR, @@ -329,6 +333,22 @@ enum dp_link_rate { DP_BW_HBR2, }; +struct lcpll_config { + unsigned long long rate; + u8 lcvco_mode_en; + u8 pi_en; + u8 clk_en_100m; + u8 pms_mdiv; + u8 pms_mdiv_afc; + u8 pms_pdiv; + u8 pms_refdiv; + u8 pms_sdiv; + u8 sdm_deno; + u8 sdm_num_sign; + u8 sdm_num; + u8 sdc_n; +}; + struct ropll_config { unsigned long long rate; u8 pms_mdiv; @@ -336,27 +356,13 @@ struct ropll_config { u8 pms_pdiv; u8 pms_refdiv; u8 pms_sdiv; - u8 pms_iqdiv_rstn; - u8 ref_clk_sel; u8 sdm_en; - u8 sdm_rstn; - u8 sdc_frac_en; - u8 sdc_rstn; - u8 sdm_clk_div; u8 sdm_deno; u8 sdm_num_sign; u8 sdm_num; u8 sdc_n; u8 sdc_num; u8 sdc_deno; - u8 sdc_ndiv_rstn; - u8 ssc_en; - u8 ssc_fm_dev; - u8 ssc_fm_freq; - u8 ssc_clk_div_sel; - u8 ana_cpp_ctrl; - u8 ana_lpf_c_sel; - u8 cd_tx_ser_rate_sel; }; struct tx_drv_ctrl { @@ -387,6 +393,12 @@ struct rk_hdptx_phy_cfg { unsigned int phy_ids[MAX_HDPTX_PHY_NUM]; }; +struct rk_hdptx_hdmi_cfg { + enum phy_hdmi_mode mode; + unsigned long long rate; + unsigned int bpc; +}; + struct rk_hdptx_phy { struct device *dev; struct regmap *regmap; @@ -394,14 +406,13 @@ struct rk_hdptx_phy { int phy_id; struct phy *phy; - struct phy_configure_opts_hdmi hdmi_cfg; + struct rk_hdptx_hdmi_cfg hdmi_cfg; struct clk_bulk_data *clks; int nr_clks; struct reset_control_bulk_data rsts[RST_MAX]; /* clk provider */ struct clk_hw hw; - unsigned long hw_rate; bool restrict_rate_change; atomic_t usage_count; @@ -411,52 +422,44 @@ struct rk_hdptx_phy { unsigned int lanes; }; -static const struct ropll_config ropll_tmds_cfg[] = { - { 594000000ULL, 124, 124, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 371250000ULL, 155, 155, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 297000000ULL, 124, 124, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 162000000ULL, 135, 135, 1, 1, 3, 1, 1, 0, 1, 1, 1, 1, 4, 0, 3, 5, 5, 0x10, - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 185625000ULL, 155, 155, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 154000000ULL, 193, 193, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 193, 1, 32, 2, 1, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 148500000ULL, 0x7b, 0x7b, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 4, 0, 3, 5, 5, - 0x10, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 146250000ULL, 122, 122, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 244, 1, 16, 2, 1, 1, - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 119000000ULL, 149, 149, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 149, 1, 16, 2, 1, 1, - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 106500000ULL, 89, 89, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 89, 1, 16, 1, 0, 1, - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 108000000ULL, 135, 135, 1, 1, 5, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 85500000ULL, 214, 214, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 214, 1, 16, 2, 1, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 83500000ULL, 105, 105, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 42, 1, 16, 1, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 92812500ULL, 155, 155, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 74250000ULL, 124, 124, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 62, 1, 16, 5, 0, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 65000000ULL, 162, 162, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 54, 0, 16, 4, 1, - 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 50250000ULL, 84, 84, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 11, 1, 4, 5, - 4, 11, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 33750000ULL, 0x70, 0x70, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 0x2, 0, 0x01, 5, - 1, 1, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 40000000ULL, 100, 100, 1, 1, 11, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 27000000ULL, 0x5a, 0x5a, 1, 1, 0xf, 1, 1, 0, 1, 0, 1, 1, 0x9, 0, 0x05, 0, - 0x14, 0x18, 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, - { 25175000ULL, 84, 84, 1, 1, 0xf, 1, 1, 1, 1, 1, 1, 1, 168, 1, 16, 4, 1, 1, - 1, 0, 0x20, 0x0c, 1, 0x0e, 0, 0, }, +static const struct lcpll_config rk_hdptx_frl_lcpll_cfg[] = { + /* | pms | sdm | */ + /* rate, lcen, pien, cken, mdiv, mdafc, pdiv, rdiv, sdiv, deno, nsig, num, sdcn, */ + { 4800000000ULL, 1, 0, 0, 125, 125, 1, 1, 0, 1, 0, 0, 2, }, + { 4000000000ULL, 1, 1, 0, 104, 104, 1, 1, 0, 9, 0, 1, 1, }, + { 2400000000ULL, 1, 0, 0, 125, 125, 1, 1, 1, 1, 0, 0, 2, }, + { 1800000000ULL, 1, 0, 0, 125, 125, 1, 1, 1, 1, 0, 0, 2, }, + { 900000000ULL, 1, 0, 0, 125, 125, 1, 1, 3, 1, 0, 0, 2, }, }; -static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { +static const struct ropll_config rk_hdptx_tmds_ropll_cfg[] = { + /* | pms | sdm | sdc | */ + /* rate, mdiv, mdafc, pdiv, rdiv, sdiv, en, deno, nsig, num, n, num, deno, */ + { 594000000ULL, 124, 124, 1, 1, 0, 1, 62, 1, 16, 5, 0, 1, }, + { 461101250ULL, 97, 97, 1, 1, 0, 1, 71, 1, 53, 2, 6, 35, }, + { 371250000ULL, 155, 155, 1, 1, 1, 1, 62, 1, 16, 5, 0, 1, }, + { 297000000ULL, 124, 124, 1, 1, 1, 1, 62, 1, 16, 5, 0, 1, }, + { 185625000ULL, 155, 155, 1, 1, 3, 1, 62, 1, 16, 5, 0, 1, }, + { 162000000ULL, 135, 135, 1, 1, 3, 0, 4, 0, 3, 5, 5, 16, }, + { 154000000ULL, 193, 193, 1, 1, 5, 1, 193, 1, 32, 2, 1, 1, }, + { 148500000ULL, 123, 123, 1, 1, 3, 1, 4, 0, 3, 5, 5, 16, }, + { 146250000ULL, 122, 122, 1, 1, 3, 1, 244, 1, 16, 2, 1, 1, }, + { 119000000ULL, 149, 149, 1, 1, 5, 1, 149, 1, 16, 2, 1, 1, }, + { 108000000ULL, 135, 135, 1, 1, 5, 0, 9, 0, 5, 0, 20, 24, }, + { 106500000ULL, 89, 89, 1, 1, 3, 1, 89, 1, 16, 1, 0, 1, }, + { 92812500ULL, 155, 155, 1, 1, 7, 1, 62, 1, 16, 5, 0, 1, }, + { 85500000ULL, 214, 214, 1, 1, 11, 1, 214, 1, 16, 2, 1, 1, }, + { 83500000ULL, 105, 105, 1, 1, 5, 1, 42, 1, 16, 1, 0, 1, }, + { 74250000ULL, 124, 124, 1, 1, 7, 1, 62, 1, 16, 5, 0, 1, }, + { 65000000ULL, 162, 162, 1, 1, 11, 1, 54, 0, 16, 4, 1, 1, }, + { 50250000ULL, 84, 84, 1, 1, 7, 1, 11, 1, 4, 5, 4, 11, }, + { 40000000ULL, 100, 100, 1, 1, 11, 0, 9, 0, 5, 0, 20, 24, }, + { 33750000ULL, 112, 112, 1, 1, 15, 1, 2, 0, 1, 5, 1, 1, }, + { 27000000ULL, 90, 90, 1, 1, 15, 0, 9, 0, 5, 0, 20, 24, }, + { 25175000ULL, 84, 84, 1, 1, 15, 1, 168, 1, 16, 4, 1, 1, }, +}; + +static const struct reg_sequence rk_hdptx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(0009), 0x0c), REG_SEQ0(CMN_REG(000a), 0x83), REG_SEQ0(CMN_REG(000b), 0x06), @@ -465,13 +468,11 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(000e), 0x0f), REG_SEQ0(CMN_REG(000f), 0x0f), REG_SEQ0(CMN_REG(0010), 0x04), - REG_SEQ0(CMN_REG(0011), 0x00), REG_SEQ0(CMN_REG(0012), 0x26), REG_SEQ0(CMN_REG(0013), 0x22), REG_SEQ0(CMN_REG(0014), 0x24), REG_SEQ0(CMN_REG(0015), 0x77), REG_SEQ0(CMN_REG(0016), 0x08), - REG_SEQ0(CMN_REG(0017), 0x00), REG_SEQ0(CMN_REG(0018), 0x04), REG_SEQ0(CMN_REG(0019), 0x48), REG_SEQ0(CMN_REG(001a), 0x01), @@ -479,13 +480,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(001c), 0x01), REG_SEQ0(CMN_REG(001d), 0x64), REG_SEQ0(CMN_REG(001f), 0x00), - REG_SEQ0(CMN_REG(0026), 0x53), REG_SEQ0(CMN_REG(0029), 0x01), - REG_SEQ0(CMN_REG(0030), 0x00), - REG_SEQ0(CMN_REG(0031), 0x20), - REG_SEQ0(CMN_REG(0032), 0x30), - REG_SEQ0(CMN_REG(0033), 0x0b), - REG_SEQ0(CMN_REG(0034), 0x23), REG_SEQ0(CMN_REG(0035), 0x00), REG_SEQ0(CMN_REG(0038), 0x00), REG_SEQ0(CMN_REG(0039), 0x00), @@ -496,7 +491,6 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(003f), 0x83), REG_SEQ0(CMN_REG(0040), 0x06), REG_SEQ0(CMN_REG(0041), 0x20), - REG_SEQ0(CMN_REG(0042), 0xb8), REG_SEQ0(CMN_REG(0043), 0x00), REG_SEQ0(CMN_REG(0044), 0x46), REG_SEQ0(CMN_REG(0045), 0x24), @@ -506,14 +500,9 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(004b), 0x00), REG_SEQ0(CMN_REG(004c), 0x01), REG_SEQ0(CMN_REG(004d), 0x64), - REG_SEQ0(CMN_REG(004e), 0x14), REG_SEQ0(CMN_REG(004f), 0x00), REG_SEQ0(CMN_REG(0050), 0x00), - REG_SEQ0(CMN_REG(005d), 0x0c), REG_SEQ0(CMN_REG(005f), 0x01), - REG_SEQ0(CMN_REG(006b), 0x04), - REG_SEQ0(CMN_REG(0073), 0x30), - REG_SEQ0(CMN_REG(0074), 0x00), REG_SEQ0(CMN_REG(0075), 0x20), REG_SEQ0(CMN_REG(0076), 0x30), REG_SEQ0(CMN_REG(0077), 0x08), @@ -525,13 +514,10 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(007e), 0x00), REG_SEQ0(CMN_REG(007f), 0x00), REG_SEQ0(CMN_REG(0080), 0x00), - REG_SEQ0(CMN_REG(0081), 0x09), REG_SEQ0(CMN_REG(0082), 0x04), REG_SEQ0(CMN_REG(0083), 0x24), REG_SEQ0(CMN_REG(0084), 0x20), REG_SEQ0(CMN_REG(0085), 0x03), - REG_SEQ0(CMN_REG(0086), 0x01), - REG_SEQ0(CMN_REG(0087), 0x0c), REG_SEQ0(CMN_REG(008a), 0x55), REG_SEQ0(CMN_REG(008b), 0x25), REG_SEQ0(CMN_REG(008c), 0x2c), @@ -543,10 +529,113 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { REG_SEQ0(CMN_REG(0092), 0x00), REG_SEQ0(CMN_REG(0093), 0x00), REG_SEQ0(CMN_REG(009a), 0x11), +}; + +static const struct reg_sequence rk_hdptx_frl_lcpll_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0011), 0x00), + REG_SEQ0(CMN_REG(0017), 0x00), + REG_SEQ0(CMN_REG(0025), 0x10), + REG_SEQ0(CMN_REG(0026), 0x53), + REG_SEQ0(CMN_REG(0027), 0x01), + REG_SEQ0(CMN_REG(0028), 0x0d), + REG_SEQ0(CMN_REG(002e), 0x02), + REG_SEQ0(CMN_REG(002f), 0x0d), + REG_SEQ0(CMN_REG(0030), 0x00), + REG_SEQ0(CMN_REG(0031), 0x20), + REG_SEQ0(CMN_REG(0032), 0x30), + REG_SEQ0(CMN_REG(0033), 0x0b), + REG_SEQ0(CMN_REG(0034), 0x23), + REG_SEQ0(CMN_REG(003d), 0x00), + REG_SEQ0(CMN_REG(0042), 0xb8), + REG_SEQ0(CMN_REG(0046), 0xff), + REG_SEQ0(CMN_REG(0048), 0x44), + REG_SEQ0(CMN_REG(004e), 0x14), + REG_SEQ0(CMN_REG(0051), 0x00), + REG_SEQ0(CMN_REG(0055), 0x00), + REG_SEQ0(CMN_REG(0059), 0x11), + REG_SEQ0(CMN_REG(005a), 0x03), + REG_SEQ0(CMN_REG(005c), 0x05), + REG_SEQ0(CMN_REG(005d), 0x0c), + REG_SEQ0(CMN_REG(005e), 0x07), + REG_SEQ0(CMN_REG(0060), 0x01), + REG_SEQ0(CMN_REG(0064), 0x07), + REG_SEQ0(CMN_REG(0065), 0x00), + REG_SEQ0(CMN_REG(0069), 0x00), + REG_SEQ0(CMN_REG(006b), 0x04), + REG_SEQ0(CMN_REG(006c), 0x00), + REG_SEQ0(CMN_REG(0070), 0x01), + REG_SEQ0(CMN_REG(0073), 0x30), + REG_SEQ0(CMN_REG(0074), 0x00), + REG_SEQ0(CMN_REG(0081), 0x09), + REG_SEQ0(CMN_REG(0086), 0x01), + REG_SEQ0(CMN_REG(0087), 0x0c), + REG_SEQ0(CMN_REG(0089), 0x02), + REG_SEQ0(CMN_REG(0095), 0x00), + REG_SEQ0(CMN_REG(0097), 0x00), + REG_SEQ0(CMN_REG(0099), 0x00), REG_SEQ0(CMN_REG(009b), 0x10), }; -static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { +static const struct reg_sequence rk_hdptx_frl_lcpll_ropll_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0008), 0xd0), + REG_SEQ0(CMN_REG(0011), 0x00), + REG_SEQ0(CMN_REG(0017), 0x00), + REG_SEQ0(CMN_REG(001e), 0x35), + REG_SEQ0(CMN_REG(0020), 0x6b), + REG_SEQ0(CMN_REG(0021), 0x6b), + REG_SEQ0(CMN_REG(0022), 0x11), + REG_SEQ0(CMN_REG(0024), 0x00), + REG_SEQ0(CMN_REG(0025), 0x10), + REG_SEQ0(CMN_REG(0026), 0x53), + REG_SEQ0(CMN_REG(0027), 0x15), + REG_SEQ0(CMN_REG(0028), 0x0d), + REG_SEQ0(CMN_REG(002a), 0x09), + REG_SEQ0(CMN_REG(002b), 0x01), + REG_SEQ0(CMN_REG(002c), 0x02), + REG_SEQ0(CMN_REG(002d), 0x02), + REG_SEQ0(CMN_REG(002e), 0x0d), + REG_SEQ0(CMN_REG(002f), 0x61), + REG_SEQ0(CMN_REG(0030), 0x00), + REG_SEQ0(CMN_REG(0031), 0x20), + REG_SEQ0(CMN_REG(0032), 0x30), + REG_SEQ0(CMN_REG(0033), 0x0b), + REG_SEQ0(CMN_REG(0034), 0x23), + REG_SEQ0(CMN_REG(0037), 0x00), + REG_SEQ0(CMN_REG(003d), 0xc0), + REG_SEQ0(CMN_REG(0042), 0xb8), + REG_SEQ0(CMN_REG(0046), 0xff), + REG_SEQ0(CMN_REG(0048), 0x44), + REG_SEQ0(CMN_REG(004e), 0x14), + REG_SEQ0(CMN_REG(0054), 0x19), + REG_SEQ0(CMN_REG(0058), 0x19), + REG_SEQ0(CMN_REG(0059), 0x11), + REG_SEQ0(CMN_REG(005b), 0x30), + REG_SEQ0(CMN_REG(005c), 0x25), + REG_SEQ0(CMN_REG(005d), 0x14), + REG_SEQ0(CMN_REG(005e), 0x0e), + REG_SEQ0(CMN_REG(0063), 0x01), + REG_SEQ0(CMN_REG(0064), 0x0e), + REG_SEQ0(CMN_REG(0068), 0x00), + REG_SEQ0(CMN_REG(0069), 0x02), + REG_SEQ0(CMN_REG(006b), 0x00), + REG_SEQ0(CMN_REG(006f), 0x00), + REG_SEQ0(CMN_REG(0073), 0x02), + REG_SEQ0(CMN_REG(0074), 0x00), + REG_SEQ0(CMN_REG(007a), 0x00), + REG_SEQ0(CMN_REG(0081), 0x09), + REG_SEQ0(CMN_REG(0086), 0x11), + REG_SEQ0(CMN_REG(0087), 0x0c), + REG_SEQ0(CMN_REG(0089), 0x00), + REG_SEQ0(CMN_REG(0095), 0x03), + REG_SEQ0(CMN_REG(0097), 0x00), + REG_SEQ0(CMN_REG(0099), 0x00), + REG_SEQ0(CMN_REG(009b), 0x10), + REG_SEQ0(CMN_REG(009e), 0x03), + REG_SEQ0(CMN_REG(009f), 0xff), + REG_SEQ0(CMN_REG(00a0), 0x60), +}; + +static const struct reg_sequence rk_hdptx_tmds_cmn_init_seq[] = { REG_SEQ0(CMN_REG(0008), 0x00), REG_SEQ0(CMN_REG(0011), 0x01), REG_SEQ0(CMN_REG(0017), 0x20), @@ -577,9 +666,13 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { REG_SEQ0(CMN_REG(0048), 0x11), REG_SEQ0(CMN_REG(004e), 0x34), REG_SEQ0(CMN_REG(005c), 0x25), + REG_SEQ0(CMN_REG(005d), 0x0c), REG_SEQ0(CMN_REG(005e), 0x4f), + REG_SEQ0(CMN_REG(006b), 0x04), + REG_SEQ0(CMN_REG(0073), 0x30), REG_SEQ0(CMN_REG(0074), 0x04), REG_SEQ0(CMN_REG(0081), 0x01), + REG_SEQ0(CMN_REG(0086), 0x01), REG_SEQ0(CMN_REG(0087), 0x04), REG_SEQ0(CMN_REG(0089), 0x00), REG_SEQ0(CMN_REG(0095), 0x00), @@ -588,14 +681,24 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { REG_SEQ0(CMN_REG(009b), 0x00), }; -static const struct reg_sequence rk_hdtpx_common_sb_init_seq[] = { +static const struct reg_sequence rk_hdptx_common_sb_init_seq[] = { REG_SEQ0(SB_REG(0114), 0x00), REG_SEQ0(SB_REG(0115), 0x00), REG_SEQ0(SB_REG(0116), 0x00), REG_SEQ0(SB_REG(0117), 0x00), }; -static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = { +static const struct reg_sequence rk_hdptx_frl_lntop_init_seq[] = { + REG_SEQ0(LNTOP_REG(0200), 0x04), + REG_SEQ0(LNTOP_REG(0201), 0x00), + REG_SEQ0(LNTOP_REG(0202), 0x00), + REG_SEQ0(LNTOP_REG(0203), 0xf0), + REG_SEQ0(LNTOP_REG(0204), 0xff), + REG_SEQ0(LNTOP_REG(0205), 0xff), + REG_SEQ0(LNTOP_REG(0206), 0x05), +}; + +static const struct reg_sequence rk_hdptx_tmds_lntop_highbr_seq[] = { REG_SEQ0(LNTOP_REG(0201), 0x00), REG_SEQ0(LNTOP_REG(0202), 0x00), REG_SEQ0(LNTOP_REG(0203), 0x0f), @@ -603,7 +706,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_highbr_seq[] = { REG_SEQ0(LNTOP_REG(0205), 0xff), }; -static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = { +static const struct reg_sequence rk_hdptx_tmds_lntop_lowbr_seq[] = { REG_SEQ0(LNTOP_REG(0201), 0x07), REG_SEQ0(LNTOP_REG(0202), 0xc1), REG_SEQ0(LNTOP_REG(0203), 0xf0), @@ -611,7 +714,7 @@ static const struct reg_sequence rk_hdtpx_tmds_lntop_lowbr_seq[] = { REG_SEQ0(LNTOP_REG(0205), 0x1f), }; -static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { +static const struct reg_sequence rk_hdptx_common_lane_init_seq[] = { REG_SEQ0(LANE_REG(0303), 0x0c), REG_SEQ0(LANE_REG(0307), 0x20), REG_SEQ0(LANE_REG(030a), 0x17), @@ -666,7 +769,39 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { REG_SEQ0(LANE_REG(0620), 0xa0), }; -static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { +static const struct reg_sequence rk_hdptx_frl_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0312), 0x3c), + REG_SEQ0(LANE_REG(0412), 0x3c), + REG_SEQ0(LANE_REG(0512), 0x3c), + REG_SEQ0(LANE_REG(0612), 0x3c), + REG_SEQ0(LANE_REG(0303), 0x2f), + REG_SEQ0(LANE_REG(0403), 0x2f), + REG_SEQ0(LANE_REG(0503), 0x2f), + REG_SEQ0(LANE_REG(0603), 0x2f), + REG_SEQ0(LANE_REG(0305), 0x03), + REG_SEQ0(LANE_REG(0405), 0x03), + REG_SEQ0(LANE_REG(0505), 0x03), + REG_SEQ0(LANE_REG(0605), 0x03), + REG_SEQ0(LANE_REG(0306), 0xfc), + REG_SEQ0(LANE_REG(0406), 0xfc), + REG_SEQ0(LANE_REG(0506), 0xfc), + REG_SEQ0(LANE_REG(0606), 0xfc), + REG_SEQ0(LANE_REG(0305), 0x4f), + REG_SEQ0(LANE_REG(0405), 0x4f), + REG_SEQ0(LANE_REG(0505), 0x4f), + REG_SEQ0(LANE_REG(0605), 0x4f), + REG_SEQ0(LANE_REG(0304), 0x14), + REG_SEQ0(LANE_REG(0404), 0x14), + REG_SEQ0(LANE_REG(0504), 0x14), + REG_SEQ0(LANE_REG(0604), 0x14), + /* Keep Inter-Pair Skew in the limits */ + REG_SEQ0(LANE_REG(031e), 0x02), + REG_SEQ0(LANE_REG(041e), 0x02), + REG_SEQ0(LANE_REG(051e), 0x02), + REG_SEQ0(LANE_REG(061e), 0x02), +}; + +static const struct reg_sequence rk_hdptx_tmds_lane_init_seq[] = { REG_SEQ0(LANE_REG(0312), 0x00), REG_SEQ0(LANE_REG(0412), 0x00), REG_SEQ0(LANE_REG(0512), 0x00), @@ -829,6 +964,13 @@ static int rk_hdptx_post_enable_lane(struct rk_hdptx_phy *hdptx) HDPTX_I_BIAS_EN | HDPTX_I_BGR_EN; regmap_write(hdptx->grf, GRF_HDPTX_CON0, val); + /* 3 lanes FRL mode */ + if (hdptx->hdmi_cfg.rate == FRL_6G3L_RATE || + hdptx->hdmi_cfg.rate == FRL_3G3L_RATE) + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x07); + else + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f); + ret = regmap_read_poll_timeout(hdptx->grf, GRF_HDPTX_STATUS, val, (val & HDPTX_O_PHY_RDY) && (val & HDPTX_O_PLL_LOCK_DONE), @@ -882,6 +1024,7 @@ static void rk_hdptx_phy_disable(struct rk_hdptx_phy *hdptx) usleep_range(20, 30); reset_control_deassert(hdptx->rsts[RST_APB].rstc); + regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0); regmap_write(hdptx->regmap, LANE_REG(0300), 0x82); regmap_write(hdptx->regmap, SB_REG(010f), 0xc1); regmap_write(hdptx->regmap, SB_REG(0110), 0x1); @@ -970,25 +1113,99 @@ static bool rk_hdptx_phy_clk_pll_calc(unsigned long long rate, return true; } -static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) +static int rk_hdptx_frl_lcpll_cmn_config(struct rk_hdptx_phy *hdptx) +{ + const struct lcpll_config *cfg = NULL; + int i; + + dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate); + + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) { + if (hdptx->hdmi_cfg.rate == rk_hdptx_frl_lcpll_cfg[i].rate) { + cfg = &rk_hdptx_frl_lcpll_cfg[i]; + break; + } + } + + if (!cfg) { + dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n", + __func__, hdptx->hdmi_cfg.rate); + return -EINVAL; + } + + rk_hdptx_pre_power_up(hdptx); + + regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16); + + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_cmn_init_seq); + + regmap_update_bits(hdptx->regmap, CMN_REG(0008), + LCPLL_EN_MASK | LCPLL_LCVCO_MODE_EN_MASK, + FIELD_PREP(LCPLL_EN_MASK, 1) | + FIELD_PREP(LCPLL_LCVCO_MODE_EN_MASK, cfg->lcvco_mode_en)); + + regmap_update_bits(hdptx->regmap, CMN_REG(001e), + LCPLL_PI_EN_MASK | LCPLL_100M_CLK_EN_MASK, + FIELD_PREP(LCPLL_PI_EN_MASK, cfg->pi_en) | + FIELD_PREP(LCPLL_100M_CLK_EN_MASK, cfg->clk_en_100m)); + + regmap_write(hdptx->regmap, CMN_REG(0020), cfg->pms_mdiv); + regmap_write(hdptx->regmap, CMN_REG(0021), cfg->pms_mdiv_afc); + regmap_write(hdptx->regmap, CMN_REG(0022), + (cfg->pms_pdiv << 4) | cfg->pms_refdiv); + regmap_write(hdptx->regmap, CMN_REG(0023), + (cfg->pms_sdiv << 4) | cfg->pms_sdiv); + regmap_write(hdptx->regmap, CMN_REG(002a), cfg->sdm_deno); + regmap_write(hdptx->regmap, CMN_REG(002b), cfg->sdm_num_sign); + regmap_write(hdptx->regmap, CMN_REG(002c), cfg->sdm_num); + + regmap_update_bits(hdptx->regmap, CMN_REG(002d), LCPLL_SDC_N_MASK, + FIELD_PREP(LCPLL_SDC_N_MASK, cfg->sdc_n)); + + regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_POSTDIV_SEL_MASK, + FIELD_PREP(PLL_PCG_POSTDIV_SEL_MASK, cfg->pms_sdiv)); + regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_SEL_MASK, + FIELD_PREP(PLL_PCG_CLK_SEL_MASK, (hdptx->hdmi_cfg.bpc - 8) >> 1)); + + return rk_hdptx_post_enable_pll(hdptx); +} + +static int rk_hdptx_frl_lcpll_ropll_cmn_config(struct rk_hdptx_phy *hdptx) +{ + dev_dbg(hdptx->dev, "%s rate=%llu\n", __func__, hdptx->hdmi_cfg.rate); + + rk_hdptx_pre_power_up(hdptx); + + /* ROPLL input reference clock from LCPLL (cascade mode) */ + regmap_write(hdptx->grf, GRF_HDPTX_CON0, + (LC_REF_CLK_SEL << 16) | LC_REF_CLK_SEL); + + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lcpll_ropll_cmn_init_seq); + + return rk_hdptx_post_enable_pll(hdptx); +} + +static int rk_hdptx_tmds_ropll_cmn_config(struct rk_hdptx_phy *hdptx) { const struct ropll_config *cfg = NULL; struct ropll_config rc = {0}; - int ret, i; + int i; - if (!hdptx->hdmi_cfg.tmds_char_rate) + if (!hdptx->hdmi_cfg.rate) return 0; - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) - if (hdptx->hdmi_cfg.tmds_char_rate == ropll_tmds_cfg[i].rate) { - cfg = &ropll_tmds_cfg[i]; + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++) + if (hdptx->hdmi_cfg.rate == rk_hdptx_tmds_ropll_cfg[i].rate) { + cfg = &rk_hdptx_tmds_ropll_cfg[i]; break; } if (!cfg) { - if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.tmds_char_rate, &rc)) { + if (!rk_hdptx_phy_clk_pll_calc(hdptx->hdmi_cfg.rate, &rc)) { dev_err(hdptx->dev, "%s cannot find pll cfg for rate=%llu\n", - __func__, hdptx->hdmi_cfg.tmds_char_rate); + __func__, hdptx->hdmi_cfg.rate); return -EINVAL; } @@ -996,13 +1213,15 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) } dev_dbg(hdptx->dev, "%s rate=%llu mdiv=%u sdiv=%u sdm_en=%u k_sign=%u k=%u lc=%u\n", - __func__, hdptx->hdmi_cfg.tmds_char_rate, cfg->pms_mdiv, cfg->pms_sdiv + 1, + __func__, hdptx->hdmi_cfg.rate, cfg->pms_mdiv, cfg->pms_sdiv + 1, cfg->sdm_en, cfg->sdm_num_sign, cfg->sdm_num, cfg->sdm_deno); rk_hdptx_pre_power_up(hdptx); - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_cmn_init_seq); - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_cmn_init_seq); + regmap_write(hdptx->grf, GRF_HDPTX_CON0, LC_REF_CLK_SEL << 16); + + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_cmn_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_cmn_init_seq); regmap_write(hdptx->regmap, CMN_REG(0051), cfg->pms_mdiv); regmap_write(hdptx->regmap, CMN_REG(0055), cfg->pms_mdiv_afc); @@ -1036,33 +1255,49 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) regmap_update_bits(hdptx->regmap, CMN_REG(0086), PLL_PCG_CLK_EN_MASK, FIELD_PREP(PLL_PCG_CLK_EN_MASK, 0x1)); - ret = rk_hdptx_post_enable_pll(hdptx); - if (!ret) - hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, - hdptx->hdmi_cfg.bpc); - - return ret; + return rk_hdptx_post_enable_pll(hdptx); } -static int rk_hdptx_ropll_tmds_mode_config(struct rk_hdptx_phy *hdptx) +static int rk_hdptx_pll_cmn_config(struct rk_hdptx_phy *hdptx) { - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_sb_init_seq); + if (hdptx->hdmi_cfg.rate <= HDMI20_MAX_RATE) + return rk_hdptx_tmds_ropll_cmn_config(hdptx); + + if (hdptx->hdmi_cfg.rate == FRL_8G4L_RATE) + return rk_hdptx_frl_lcpll_ropll_cmn_config(hdptx); + + return rk_hdptx_frl_lcpll_cmn_config(hdptx); +} + +static int rk_hdptx_frl_lcpll_mode_config(struct rk_hdptx_phy *hdptx) +{ + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lntop_init_seq); + + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_frl_lane_init_seq); + + return rk_hdptx_post_enable_lane(hdptx); +} + +static int rk_hdptx_tmds_ropll_mode_config(struct rk_hdptx_phy *hdptx) +{ + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_sb_init_seq); regmap_write(hdptx->regmap, LNTOP_REG(0200), 0x06); - if (hdptx->hdmi_cfg.tmds_char_rate > HDMI14_MAX_RATE) { + if (hdptx->hdmi_cfg.rate > HDMI14_MAX_RATE) { /* For 1/40 bitrate clk */ - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_highbr_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_highbr_seq); } else { /* For 1/10 bitrate clk */ - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lntop_lowbr_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lntop_lowbr_seq); } regmap_write(hdptx->regmap, LNTOP_REG(0206), 0x07); - regmap_write(hdptx->regmap, LNTOP_REG(0207), 0x0f); - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_common_lane_init_seq); - rk_hdptx_multi_reg_write(hdptx, rk_hdtpx_tmds_lane_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_common_lane_init_seq); + rk_hdptx_multi_reg_write(hdptx, rk_hdptx_tmds_lane_init_seq); return rk_hdptx_post_enable_lane(hdptx); } @@ -1074,7 +1309,7 @@ static void rk_hdptx_dp_reset(struct rk_hdptx_phy *hdptx) reset_control_assert(hdptx->rsts[RST_INIT].rstc); reset_control_assert(hdptx->rsts[RST_APB].rstc); - udelay(10); + usleep_range(10, 15); reset_control_deassert(hdptx->rsts[RST_APB].rstc); regmap_update_bits(hdptx->regmap, LANE_REG(0301), @@ -1121,7 +1356,7 @@ static int rk_hdptx_phy_consumer_get(struct rk_hdptx_phy *hdptx) if (mode == PHY_MODE_DP) { rk_hdptx_dp_reset(hdptx); } else { - ret = rk_hdptx_ropll_tmds_cmn_config(hdptx); + ret = rk_hdptx_pll_cmn_config(hdptx); if (ret) goto dec_usage; } @@ -1422,19 +1657,19 @@ static int rk_hdptx_phy_power_on(struct phy *phy) int ret, lane; if (mode != PHY_MODE_DP) { - if (!hdptx->hdmi_cfg.tmds_char_rate) { + if (!hdptx->hdmi_cfg.rate && hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) { /* * FIXME: Temporary workaround to setup TMDS char rate * from the RK DW HDMI QP bridge driver. * Will be removed as soon the switch to the HDMI PHY * configuration API has been completed on both ends. */ - hdptx->hdmi_cfg.tmds_char_rate = phy_get_bus_width(hdptx->phy) & 0xfffffff; - hdptx->hdmi_cfg.tmds_char_rate *= 100; + hdptx->hdmi_cfg.rate = phy_get_bus_width(hdptx->phy) & 0xfffffff; + hdptx->hdmi_cfg.rate *= 100; } dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, - hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); + hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc); } ret = rk_hdptx_phy_consumer_get(hdptx); @@ -1468,7 +1703,11 @@ static int rk_hdptx_phy_power_on(struct phy *phy) regmap_write(hdptx->grf, GRF_HDPTX_CON0, HDPTX_MODE_SEL << 16 | FIELD_PREP(HDPTX_MODE_SEL, 0x0)); - ret = rk_hdptx_ropll_tmds_mode_config(hdptx); + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) + ret = rk_hdptx_frl_lcpll_mode_config(hdptx); + else + ret = rk_hdptx_tmds_ropll_mode_config(hdptx); + if (ret) rk_hdptx_phy_consumer_put(hdptx, true); } @@ -1484,25 +1723,57 @@ static int rk_hdptx_phy_power_off(struct phy *phy) } static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx, - struct phy_configure_opts_hdmi *hdmi) + struct phy_configure_opts_hdmi *hdmi_in, + struct rk_hdptx_hdmi_cfg *hdmi_out) { int i; - if (!hdmi->tmds_char_rate || hdmi->tmds_char_rate > HDMI20_MAX_RATE) - return -EINVAL; + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) { + unsigned long long frl_rate = 100000000ULL * hdmi_in->frl.lanes * + hdmi_in->frl.rate_per_lane; - for (i = 0; i < ARRAY_SIZE(ropll_tmds_cfg); i++) - if (hdmi->tmds_char_rate == ropll_tmds_cfg[i].rate) + switch (hdmi_in->frl.rate_per_lane) { + case 3: + case 6: + case 8: + case 10: + case 12: break; + default: + return -EINVAL; + } - if (i == ARRAY_SIZE(ropll_tmds_cfg) && - !rk_hdptx_phy_clk_pll_calc(hdmi->tmds_char_rate, NULL)) - return -EINVAL; + if (!hdmi_in->frl.lanes || hdmi_in->frl.lanes > 4) + return -EINVAL; - if (!hdmi->bpc) - hdmi->bpc = 8; + if (frl_rate != FRL_8G4L_RATE) { + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) + if (frl_rate == rk_hdptx_frl_lcpll_cfg[i].rate) + break; + if (i == ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg)) + return -EINVAL; + } - switch (hdmi->bpc) { + if (hdmi_out) + hdmi_out->rate = frl_rate; + } else { + if (!hdmi_in->tmds_char_rate || hdmi_in->tmds_char_rate > HDMI20_MAX_RATE) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg); i++) + if (hdmi_in->tmds_char_rate == rk_hdptx_tmds_ropll_cfg[i].rate) + break; + + if (i == ARRAY_SIZE(rk_hdptx_tmds_ropll_cfg) && + !rk_hdptx_phy_clk_pll_calc(hdmi_in->tmds_char_rate, NULL)) + return -EINVAL; + + if (hdmi_out) + hdmi_out->rate = hdmi_in->tmds_char_rate; + } + + switch (hdmi_in->bpc) { + case 0: case 8: case 10: case 12: @@ -1512,6 +1783,9 @@ static int rk_hdptx_phy_verify_hdmi_config(struct rk_hdptx_phy *hdptx, return -EINVAL; } + if (hdmi_out) + hdmi_out->bpc = hdmi_in->bpc ?: 8; + return 0; } @@ -1656,11 +1930,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx, regmap_update_bits(hdptx->regmap, LANE_REG(030a) + offset, LN_TX_JEQ_EVEN_CTRL_RBR_MASK, FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_RBR_MASK, - ctrl->tx_jeq_even_ctrl)); + ctrl->tx_jeq_even_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(030c) + offset, LN_TX_JEQ_ODD_CTRL_RBR_MASK, FIELD_PREP(LN_TX_JEQ_ODD_CTRL_RBR_MASK, - ctrl->tx_jeq_odd_ctrl)); + ctrl->tx_jeq_odd_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, LN_TX_SER_40BIT_EN_RBR_MASK, FIELD_PREP(LN_TX_SER_40BIT_EN_RBR_MASK, 0x1)); @@ -1670,11 +1944,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx, regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset, LN_TX_JEQ_EVEN_CTRL_HBR_MASK, FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR_MASK, - ctrl->tx_jeq_even_ctrl)); + ctrl->tx_jeq_even_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset, LN_TX_JEQ_ODD_CTRL_HBR_MASK, FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR_MASK, - ctrl->tx_jeq_odd_ctrl)); + ctrl->tx_jeq_odd_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, LN_TX_SER_40BIT_EN_HBR_MASK, FIELD_PREP(LN_TX_SER_40BIT_EN_HBR_MASK, 0x1)); @@ -1685,11 +1959,11 @@ static void rk_hdptx_phy_set_voltage(struct rk_hdptx_phy *hdptx, regmap_update_bits(hdptx->regmap, LANE_REG(030b) + offset, LN_TX_JEQ_EVEN_CTRL_HBR2_MASK, FIELD_PREP(LN_TX_JEQ_EVEN_CTRL_HBR2_MASK, - ctrl->tx_jeq_even_ctrl)); + ctrl->tx_jeq_even_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(030d) + offset, LN_TX_JEQ_ODD_CTRL_HBR2_MASK, FIELD_PREP(LN_TX_JEQ_ODD_CTRL_HBR2_MASK, - ctrl->tx_jeq_odd_ctrl)); + ctrl->tx_jeq_odd_ctrl)); regmap_update_bits(hdptx->regmap, LANE_REG(0311) + offset, LN_TX_SER_40BIT_EN_HBR2_MASK, FIELD_PREP(LN_TX_SER_40BIT_EN_HBR2_MASK, 0x1)); @@ -1770,6 +2044,31 @@ static int rk_hdptx_phy_set_voltages(struct rk_hdptx_phy *hdptx, return 0; } +static int rk_hdptx_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) +{ + struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); + + if (mode == PHY_MODE_DP) + return 0; + + if (mode != PHY_MODE_HDMI) { + dev_err(&phy->dev, "invalid PHY mode: %d\n", mode); + return -EINVAL; + } + + switch (submode) { + case PHY_HDMI_MODE_TMDS: + case PHY_HDMI_MODE_FRL: + hdptx->hdmi_cfg.mode = submode; + break; + default: + dev_err(&phy->dev, "invalid HDMI mode: %d\n", submode); + return -EINVAL; + } + + return 0; +} + static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opts) { struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); @@ -1777,16 +2076,15 @@ static int rk_hdptx_phy_configure(struct phy *phy, union phy_configure_opts *opt int ret; if (mode != PHY_MODE_DP) { - ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); + ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, &hdptx->hdmi_cfg); if (ret) { dev_err(hdptx->dev, "invalid hdmi params for phy configure\n"); } else { - hdptx->hdmi_cfg = opts->hdmi; hdptx->restrict_rate_change = true; + dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, + hdptx->hdmi_cfg.rate, hdptx->hdmi_cfg.bpc); } - dev_dbg(hdptx->dev, "%s rate=%llu bpc=%u\n", __func__, - hdptx->hdmi_cfg.tmds_char_rate, hdptx->hdmi_cfg.bpc); return ret; } @@ -1830,7 +2128,7 @@ static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode, struct rk_hdptx_phy *hdptx = phy_get_drvdata(phy); if (mode != PHY_MODE_DP) - return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi); + return rk_hdptx_phy_verify_hdmi_config(hdptx, &opts->hdmi, NULL); return rk_hdptx_phy_verify_dp_config(hdptx, &opts->dp); } @@ -1838,6 +2136,7 @@ static int rk_hdptx_phy_validate(struct phy *phy, enum phy_mode mode, static const struct phy_ops rk_hdptx_phy_ops = { .power_on = rk_hdptx_phy_power_on, .power_off = rk_hdptx_phy_power_off, + .set_mode = rk_hdptx_phy_set_mode, .configure = rk_hdptx_phy_configure, .validate = rk_hdptx_phy_validate, .owner = THIS_MODULE, @@ -1862,34 +2161,170 @@ static void rk_hdptx_phy_clk_unprepare(struct clk_hw *hw) rk_hdptx_phy_consumer_put(hdptx, true); } +#define PLL_REF_CLK 24000000ULL + +static u64 rk_hdptx_phy_clk_calc_rate_from_pll_cfg(struct rk_hdptx_phy *hdptx) +{ + struct lcpll_config lcpll_hw; + struct ropll_config ropll_hw; + u64 fout, sdm; + u32 mode, val; + int ret, i; + + ret = regmap_read(hdptx->regmap, CMN_REG(0008), &mode); + if (ret) + return 0; + + if (mode & LCPLL_LCVCO_MODE_EN_MASK) { + ret = regmap_read(hdptx->regmap, CMN_REG(0020), &val); + if (ret) + return 0; + lcpll_hw.pms_mdiv = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(0023), &val); + if (ret) + return 0; + lcpll_hw.pms_sdiv = val & 0xf; + + ret = regmap_read(hdptx->regmap, CMN_REG(002B), &val); + if (ret) + return 0; + lcpll_hw.sdm_num_sign = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(002C), &val); + if (ret) + return 0; + lcpll_hw.sdm_num = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(002A), &val); + if (ret) + return 0; + lcpll_hw.sdm_deno = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(002D), &val); + if (ret) + return 0; + lcpll_hw.sdc_n = (val & LCPLL_SDC_N_MASK) >> 1; + + for (i = 0; i < ARRAY_SIZE(rk_hdptx_frl_lcpll_cfg); i++) { + const struct lcpll_config *cfg = &rk_hdptx_frl_lcpll_cfg[i]; + + if (cfg->pms_mdiv == lcpll_hw.pms_mdiv && + cfg->pms_sdiv == lcpll_hw.pms_sdiv && + cfg->sdm_num_sign == lcpll_hw.sdm_num_sign && + cfg->sdm_num == lcpll_hw.sdm_num && + cfg->sdm_deno == lcpll_hw.sdm_deno && + cfg->sdc_n == lcpll_hw.sdc_n) + return cfg->rate; + } + + dev_dbg(hdptx->dev, "%s no FRL match found\n", __func__); + return 0; + } + + ret = regmap_read(hdptx->regmap, CMN_REG(0051), &val); + if (ret) + return 0; + ropll_hw.pms_mdiv = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(005E), &val); + if (ret) + return 0; + ropll_hw.sdm_en = val & ROPLL_SDM_EN_MASK; + + ret = regmap_read(hdptx->regmap, CMN_REG(0064), &val); + if (ret) + return 0; + ropll_hw.sdm_num_sign = val & ROPLL_SDM_NUM_SIGN_RBR_MASK; + + ret = regmap_read(hdptx->regmap, CMN_REG(0065), &val); + if (ret) + return 0; + ropll_hw.sdm_num = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(0060), &val); + if (ret) + return 0; + ropll_hw.sdm_deno = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(0069), &val); + if (ret) + return 0; + ropll_hw.sdc_n = (val & ROPLL_SDC_N_RBR_MASK) + 3; + + ret = regmap_read(hdptx->regmap, CMN_REG(006c), &val); + if (ret) + return 0; + ropll_hw.sdc_num = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(0070), &val); + if (ret) + return 0; + ropll_hw.sdc_deno = val; + + ret = regmap_read(hdptx->regmap, CMN_REG(0086), &val); + if (ret) + return 0; + ropll_hw.pms_sdiv = ((val & PLL_PCG_POSTDIV_SEL_MASK) >> 4) + 1; + + fout = PLL_REF_CLK * ropll_hw.pms_mdiv; + if (ropll_hw.sdm_en) { + sdm = div_u64(PLL_REF_CLK * ropll_hw.sdc_deno * + ropll_hw.pms_mdiv * ropll_hw.sdm_num, + 16 * ropll_hw.sdm_deno * + (ropll_hw.sdc_deno * ropll_hw.sdc_n - ropll_hw.sdc_num)); + + if (ropll_hw.sdm_num_sign) + fout = fout - sdm; + else + fout = fout + sdm; + } + + return div_u64(fout * 2, ropll_hw.pms_sdiv * 10); +} + static unsigned long rk_hdptx_phy_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); + u32 status; + u64 rate; + int ret; - return hdptx->hw_rate; + ret = regmap_read(hdptx->grf, GRF_HDPTX_CON0, &status); + if (ret || !(status & HDPTX_I_PLL_EN)) + return 0; + + rate = rk_hdptx_phy_clk_calc_rate_from_pll_cfg(hdptx); + + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) + return rate; + + return DIV_ROUND_CLOSEST_ULL(rate * 8, hdptx->hdmi_cfg.bpc); } -static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int rk_hdptx_phy_clk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); + if (hdptx->hdmi_cfg.mode == PHY_HDMI_MODE_FRL) + return hdptx->hdmi_cfg.rate; + /* * FIXME: Temporarily allow altering TMDS char rate via CCF. * To be dropped as soon as the RK DW HDMI QP bridge driver * switches to make use of phy_configure(). */ - if (!hdptx->restrict_rate_change && rate != hdptx->hdmi_cfg.tmds_char_rate) { + if (!hdptx->restrict_rate_change && req->rate != hdptx->hdmi_cfg.rate) { struct phy_configure_opts_hdmi hdmi = { - .tmds_char_rate = rate, + .tmds_char_rate = req->rate, }; - int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi); + + int ret = rk_hdptx_phy_verify_hdmi_config(hdptx, &hdmi, &hdptx->hdmi_cfg); if (ret) return ret; - - hdptx->hdmi_cfg = hdmi; } /* @@ -1897,37 +2332,42 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with * a different rate argument. */ - return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc); + req->rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.rate * 8, hdptx->hdmi_cfg.bpc); + + return 0; } static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); - unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); + unsigned long long link_rate = rate; - /* Revert any unlikely TMDS char rate change since round_rate() */ - if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { + if (hdptx->hdmi_cfg.mode != PHY_HDMI_MODE_FRL) + link_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); + + /* Revert any unlikely link rate change since determine_rate() */ + if (hdptx->hdmi_cfg.rate != link_rate) { dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n", - tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); - hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; + link_rate, hdptx->hdmi_cfg.rate); + hdptx->hdmi_cfg.rate = link_rate; } /* - * The TMDS char rate would be normally programmed in HW during + * The link rate would be normally programmed in HW during * phy_ops.power_on() or clk_ops.prepare() callbacks, but it might * happen that the former gets fired too late, i.e. after this call, * while the latter being executed only once, i.e. when clock remains * in the prepared state during rate changes. */ - return rk_hdptx_ropll_tmds_cmn_config(hdptx); + return rk_hdptx_pll_cmn_config(hdptx); } static const struct clk_ops hdptx_phy_clk_ops = { .prepare = rk_hdptx_phy_clk_prepare, .unprepare = rk_hdptx_phy_clk_unprepare, .recalc_rate = rk_hdptx_phy_clk_recalc_rate, - .round_rate = rk_hdptx_phy_clk_round_rate, + .determine_rate = rk_hdptx_phy_clk_determine_rate, .set_rate = rk_hdptx_phy_clk_set_rate, }; diff --git a/drivers/phy/rockchip/phy-rockchip-usb.c b/drivers/phy/rockchip/phy-rockchip-usb.c index c3c30df29c3e..cef96739cf3f 100644 --- a/drivers/phy/rockchip/phy-rockchip-usb.c +++ b/drivers/phy/rockchip/phy-rockchip-usb.c @@ -446,7 +446,6 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct rockchip_usb_phy_base *phy_base; struct phy_provider *phy_provider; - struct device_node *child; int err; phy_base = devm_kzalloc(dev, sizeof(*phy_base), GFP_KERNEL); @@ -472,12 +471,10 @@ static int rockchip_usb_phy_probe(struct platform_device *pdev) return PTR_ERR(phy_base->reg_base); } - for_each_available_child_of_node(dev->of_node, child) { + for_each_available_child_of_node_scoped(dev->of_node, child) { err = rockchip_usb_phy_init(phy_base, child); - if (err) { - of_node_put(child); + if (err) return err; - } } phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); diff --git a/drivers/phy/samsung/phy-exynos5-usbdrd.c b/drivers/phy/samsung/phy-exynos5-usbdrd.c index 1c8bf80119f1..5a181cb4597e 100644 --- a/drivers/phy/samsung/phy-exynos5-usbdrd.c +++ b/drivers/phy/samsung/phy-exynos5-usbdrd.c @@ -41,6 +41,13 @@ #define EXYNOS2200_CLKRST_LINK_PCLK_SEL BIT(1) #define EXYNOS2200_DRD_UTMI 0x10 + +/* ExynosAutov920 bits */ +#define UTMICTL_FORCE_UTMI_SUSPEND BIT(13) +#define UTMICTL_FORCE_UTMI_SLEEP BIT(12) +#define UTMICTL_FORCE_DPPULLDOWN BIT(9) +#define UTMICTL_FORCE_DMPULLDOWN BIT(8) + #define EXYNOS2200_UTMI_FORCE_VBUSVALID BIT(1) #define EXYNOS2200_UTMI_FORCE_BVALID BIT(0) @@ -250,6 +257,52 @@ #define EXYNOS850_DRD_HSP_TEST 0x5c #define HSP_TEST_SIDDQ BIT(24) +#define EXYNOSAUTOV920_DRD_HSP_CLKRST 0x100 +#define HSPCLKRST_PHY20_SW_PORTRESET BIT(3) +#define HSPCLKRST_PHY20_SW_POR BIT(1) +#define HSPCLKRST_PHY20_SW_POR_SEL BIT(0) + +#define EXYNOSAUTOV920_DRD_HSPCTL 0x104 +#define HSPCTRL_VBUSVLDEXTSEL BIT(13) +#define HSPCTRL_VBUSVLDEXT BIT(12) +#define HSPCTRL_EN_UTMISUSPEND BIT(9) +#define HSPCTRL_COMMONONN BIT(8) + +#define EXYNOSAUTOV920_DRD_HSP_TEST 0x10c + +#define EXYNOSAUTOV920_DRD_HSPPLLTUNE 0x110 +#define HSPPLLTUNE_FSEL GENMASK(18, 16) + +/* ExynosAutov920 phy usb31drd port reg */ +#define EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL 0x000 +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN BIT(5) +#define PHY_RST_CTRL_PIPE_LANE0_RESET_N BIT(4) +#define PHY_RST_CTRL_PHY_RESET_OVRD_EN BIT(1) +#define PHY_RST_CTRL_PHY_RESET BIT(0) + +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0 0x0004 +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR GENMASK(31, 16) +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK BIT(8) +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK BIT(4) +#define PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL BIT(0) + +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1 0x0008 + +#define EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2 0x000c +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN BIT(0) +#define PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA GENMASK(31, 16) + +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0 0x100 +#define PHY_CONFIG0_PHY0_PMA_PWR_STABLE BIT(14) +#define PHY_CONFIG0_PHY0_PCS_PWR_STABLE BIT(13) +#define PHY_CONFIG0_PHY0_ANA_PWR_EN BIT(1) + +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7 0x11c +#define PHY_CONFIG7_PHY_TEST_POWERDOWN BIT(24) + +#define EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4 0x110 +#define PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN BIT(2) + /* Exynos9 - GS101 */ #define EXYNOS850_DRD_SECPMACTL 0x48 #define SECPMACTL_PMA_ROPLL_REF_CLK_SEL GENMASK(13, 12) @@ -2054,6 +2107,595 @@ static const struct exynos5_usbdrd_phy_drvdata exynos990_usbdrd_phy = { .n_regulators = ARRAY_SIZE(exynos5_regulator_names), }; +static void +exynosautov920_usb31drd_cr_clk(struct exynos5_usbdrd_phy *phy_drd, bool high) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + if (high) + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; + else + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; + + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + fsleep(1); +} + +static void +exynosautov920_usb31drd_port_phy_ready(struct exynos5_usbdrd_phy *phy_drd) +{ + struct device *dev = phy_drd->dev; + void __iomem *reg_phy = phy_drd->reg_phy; + static const unsigned int timeout_us = 20000; + static const unsigned int sleep_us = 40; + u32 reg; + int err; + + /* Clear cr_para_con */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + reg &= ~(PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK | + PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR); + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON1); + writel(0x0, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); + + exynosautov920_usb31drd_cr_clk(phy_drd, true); + exynosautov920_usb31drd_cr_clk(phy_drd, false); + + /* + * The maximum time from phy reset de-assertion to de-assertion of + * tx/rx_ack can be as high as 5ms in fast simulation mode. + * Time to phy ready is < 20ms + */ + err = readl_poll_timeout(reg_phy + + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0, + reg, !(reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK), + sleep_us, timeout_us); + if (err) + dev_err(dev, "timed out waiting for rx/tx_ack: %#.8x\n", reg); + + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); +} + +static void +exynosautov920_usb31drd_cr_write(struct exynos5_usbdrd_phy *phy_drd, + u16 addr, u16 data) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 cnt = 0; + u32 reg; + + /* Pre Clocking */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + reg |= PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + + /* + * tx clks must be available prior to assertion of tx req. + * tx pstate p2 to p0 transition directly is not permitted. + * tx clk ready must be asserted synchronously on tx clk prior + * to internal transmit clk alignment sequence in the phy + * when entering from p2 to p1 to p0. + */ + do { + exynosautov920_usb31drd_cr_clk(phy_drd, true); + exynosautov920_usb31drd_cr_clk(phy_drd, false); + cnt++; + } while (cnt < 15); + + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + + /* + * tx data path is active when tx lane is in p0 state + * and tx data en asserted. enable cr_para_wr_en. + */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); + reg &= ~PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA; + reg |= FIELD_PREP(PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_DATA, data) | + PHY_CR_PARA_CON2_PHY0_CR_PARA_WR_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON2); + + /* write addr */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + reg &= ~PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR; + reg |= FIELD_PREP(PHY_CR_PARA_CON0_PHY0_CR_PARA_ADDR, addr) | + PHY_CR_PARA_CON0_PHY0_CR_PARA_CLK | + PHY_CR_PARA_CON0_PHY0_CR_PARA_SEL; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + + /* check cr_para_ack*/ + cnt = 0; + do { + /* + * data symbols are captured by phy on rising edge of the + * tx_clk when tx data enabled. + * completion of the write cycle is acknowledged by assertion + * of the cr_para_ack. + */ + exynosautov920_usb31drd_cr_clk(phy_drd, true); + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CR_PARA_CON0); + if ((reg & PHY_CR_PARA_CON0_PHY0_CR_PARA_ACK)) + break; + + exynosautov920_usb31drd_cr_clk(phy_drd, false); + + /* + * wait for minimum of 10 cr_para_clk cycles after phy reset + * is negated, before accessing control regs to allow for + * internal resets. + */ + cnt++; + } while (cnt < 10); + + if (cnt < 10) + exynosautov920_usb31drd_cr_clk(phy_drd, false); +} + +static void +exynosautov920_usb31drd_phy_reset(struct exynos5_usbdrd_phy *phy_drd, int val) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + reg &= ~PHY_RST_CTRL_PHY_RESET_OVRD_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + if (val) + reg |= PHY_RST_CTRL_PHY_RESET; + else + reg &= ~PHY_RST_CTRL_PHY_RESET; + + reg |= PHY_RST_CTRL_PHY_RESET_OVRD_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); +} + +static void +exynosautov920_usb31drd_lane0_reset(struct exynos5_usbdrd_phy *phy_drd, int val) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); + if (val) + reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N; + else + reg |= PHY_RST_CTRL_PIPE_LANE0_RESET_N; + + reg &= ~PHY_RST_CTRL_PIPE_LANE0_RESET_N_OVRD_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_RST_CTRL); +} + +static void +exynosautov920_usb31drd_pipe3_init(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + /* + * Phy and Pipe Lane reset assert. + * assert reset (phy_reset = 1). + * The lane-ack outputs are asserted during reset (tx_ack = rx_ack = 1) + */ + exynosautov920_usb31drd_phy_reset(phy_drd, 1); + exynosautov920_usb31drd_lane0_reset(phy_drd, 1); + + /* + * ANA Power En, PCS & PMA PWR Stable Set + * ramp-up power suppiles + */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0); + reg |= PHY_CONFIG0_PHY0_ANA_PWR_EN | PHY_CONFIG0_PHY0_PCS_PWR_STABLE | + PHY_CONFIG0_PHY0_PMA_PWR_STABLE; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG0); + + fsleep(10); + + /* + * phy is not functional in test_powerdown mode, test_powerdown to be + * de-asserted for normal operation + */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); + reg &= ~PHY_CONFIG7_PHY_TEST_POWERDOWN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); + + /* + * phy reset signal be asserted for minimum 10us after power + * supplies are ramped-up + */ + fsleep(10); + + /* + * Phy and Pipe Lane reset assert de-assert + */ + exynosautov920_usb31drd_phy_reset(phy_drd, 0); + exynosautov920_usb31drd_lane0_reset(phy_drd, 0); + + /* Pipe_rx0_sris_mode_en = 1 */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4); + reg |= PHY_CONFIG4_PIPE_RX0_SRIS_MODE_EN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG4); + + /* + * wait for lane ack outputs to de-assert (tx_ack = rx_ack = 0) + * Exit from the reset state is indicated by de-assertion of *_ack + */ + exynosautov920_usb31drd_port_phy_ready(phy_drd); + + /* override values for level settings */ + exynosautov920_usb31drd_cr_write(phy_drd, 0x22, 0x00F5); +} + +static void +exynosautov920_usb31drd_ssphy_disable(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + /* 1. Assert reset (phy_reset = 1) */ + exynosautov920_usb31drd_lane0_reset(phy_drd, 1); + exynosautov920_usb31drd_phy_reset(phy_drd, 1); + + /* phy test power down */ + reg = readl(reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); + reg |= PHY_CONFIG7_PHY_TEST_POWERDOWN; + writel(reg, reg_phy + EXYNOSAUTOV920_USB31DRD_PHY_CONFIG7); +} + +static void +exynosautov920_usbdrd_utmi_init(struct exynos5_usbdrd_phy *phy_drd) +{ + void __iomem *reg_phy = phy_drd->reg_phy; + u32 reg; + + /* + * Disable HWACG (hardware auto clock gating control). This + * forces QACTIVE signal in Q-Channel interface to HIGH level, + * to make sure the PHY clock is not gated by the hardware. + */ + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); + reg |= LINKCTRL_FORCE_QACT; + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); + + /* De-assert link reset */ + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); + reg &= ~CLKRST_LINK_SW_RST; + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); + + /* Set PHY POR High */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); + reg |= HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_POR_SEL; + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); + + /* Enable UTMI+ */ + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); + reg &= ~(UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP | + UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN); + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); + + /* set phy clock & control HS phy */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); + reg |= HSPCTRL_EN_UTMISUSPEND | HSPCTRL_COMMONONN; + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); + + fsleep(100); + + /* Set VBUS Valid and DP-Pull up control by VBUS pad usage */ + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); + reg |= FIELD_PREP_CONST(LINKCTRL_BUS_FILTER_BYPASS, 0xf); + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); + + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); + reg |= EXYNOS2200_UTMI_FORCE_VBUSVALID | EXYNOS2200_UTMI_FORCE_BVALID; + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); + + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); + reg |= HSPCTRL_VBUSVLDEXTSEL | HSPCTRL_VBUSVLDEXT; + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPCTL); + + /* Setting FSEL for refference clock */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE); + reg &= ~HSPPLLTUNE_FSEL; + + switch (phy_drd->extrefclk) { + case EXYNOS5_FSEL_50MHZ: + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 7); + break; + case EXYNOS5_FSEL_26MHZ: + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 6); + break; + case EXYNOS5_FSEL_24MHZ: + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 2); + break; + case EXYNOS5_FSEL_20MHZ: + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 1); + break; + case EXYNOS5_FSEL_19MHZ2: + reg |= FIELD_PREP(HSPPLLTUNE_FSEL, 0); + break; + default: + dev_warn(phy_drd->dev, "unsupported ref clk: %#.2x\n", + phy_drd->extrefclk); + break; + } + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSPPLLTUNE); + + /* Enable PHY Power Mode */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); + reg &= ~HSP_TEST_SIDDQ; + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); + + /* before POR low, 10us delay is needed to Finish PHY reset */ + fsleep(10); + + /* Set PHY POR Low */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); + reg |= HSPCLKRST_PHY20_SW_POR_SEL; + reg &= ~(HSPCLKRST_PHY20_SW_POR | HSPCLKRST_PHY20_SW_PORTRESET); + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_CLKRST); + + /* after POR low and delay 75us, PHYCLOCK is guaranteed. */ + fsleep(75); + + /* Disable forcing pipe interface */ + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); + reg &= ~LINKCTRL_FORCE_PIPE_EN; + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); + + /* Pclk to pipe_clk */ + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); + reg |= EXYNOS2200_CLKRST_LINK_PCLK_SEL; + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); +} + +static void +exynosautov920_usbdrd_hsphy_disable(struct exynos5_usbdrd_phy *phy_drd) +{ + u32 reg; + void __iomem *reg_phy = phy_drd->reg_phy; + + /* set phy clock & control HS phy */ + reg = readl(reg_phy + EXYNOS2200_DRD_UTMI); + reg |= UTMICTL_FORCE_UTMI_SUSPEND | UTMICTL_FORCE_UTMI_SLEEP; + reg &= ~(UTMICTL_FORCE_DPPULLDOWN | UTMICTL_FORCE_DMPULLDOWN); + writel(reg, reg_phy + EXYNOS2200_DRD_UTMI); + + /* Disable PHY Power Mode */ + reg = readl(reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); + reg |= HSP_TEST_SIDDQ; + writel(reg, reg_phy + EXYNOSAUTOV920_DRD_HSP_TEST); + + /* clear force q-channel */ + reg = readl(reg_phy + EXYNOS850_DRD_LINKCTRL); + reg &= ~LINKCTRL_FORCE_QACT; + writel(reg, reg_phy + EXYNOS850_DRD_LINKCTRL); + + /* link sw reset is need for USB_DP/DM high-z in host mode */ + reg = readl(reg_phy + EXYNOS2200_DRD_CLKRST); + reg |= CLKRST_LINK_SW_RST; + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); + fsleep(10); + reg &= ~CLKRST_LINK_SW_RST; + writel(reg, reg_phy + EXYNOS2200_DRD_CLKRST); +} + +static int exynosautov920_usbdrd_phy_init(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); + if (ret) + return ret; + + /* Bypass PHY isol */ + inst->phy_cfg->phy_isol(inst, false); + + /* UTMI or PIPE3 specific init */ + inst->phy_cfg->phy_init(phy_drd); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); + + return 0; +} + +static int exynosautov920_usbdrd_phy_exit(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); + if (ret) + return ret; + + exynos850_usbdrd_phy_exit(phy); + + /* enable PHY isol */ + inst->phy_cfg->phy_isol(inst, true); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); + + return 0; +} + +static int exynosautov920_usbdrd_combo_phy_exit(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret = 0; + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_clks, phy_drd->clks); + if (ret) + return ret; + + if (inst->phy_cfg->id == EXYNOS5_DRDPHY_UTMI) + exynosautov920_usbdrd_hsphy_disable(phy_drd); + else if (inst->phy_cfg->id == EXYNOS5_DRDPHY_PIPE3) + exynosautov920_usb31drd_ssphy_disable(phy_drd); + + /* enable PHY isol */ + inst->phy_cfg->phy_isol(inst, true); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_clks, phy_drd->clks); + + return 0; +} + +static int exynosautov920_usbdrd_phy_power_on(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + int ret; + + dev_dbg(phy_drd->dev, "Request to power_on usbdrd_phy phy\n"); + + ret = clk_bulk_prepare_enable(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + if (ret) + return ret; + + /* Enable supply */ + ret = regulator_bulk_enable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); + if (ret) { + dev_err(phy_drd->dev, "Failed to enable PHY regulator(s)\n"); + goto fail_supply; + } + + return 0; + +fail_supply: + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + + return ret; +} + +static int exynosautov920_usbdrd_phy_power_off(struct phy *phy) +{ + struct phy_usb_instance *inst = phy_get_drvdata(phy); + struct exynos5_usbdrd_phy *phy_drd = to_usbdrd_phy(inst); + + dev_dbg(phy_drd->dev, "Request to power_off usbdrd_phy phy\n"); + + /* Disable supply */ + regulator_bulk_disable(phy_drd->drv_data->n_regulators, + phy_drd->regulators); + + clk_bulk_disable_unprepare(phy_drd->drv_data->n_core_clks, + phy_drd->core_clks); + + return 0; +} + +static const char * const exynosautov920_usb30_regulators[] = { + "dvdd", "vdd18", +}; + +static const char * const exynosautov920_usb20_regulators[] = { + "dvdd", "vdd18", "vdd33", +}; + +static const struct +exynos5_usbdrd_phy_config usb31drd_phy_cfg_exynosautov920[] = { + { + .id = EXYNOS5_DRDPHY_PIPE3, + .phy_isol = exynos5_usbdrd_phy_isol, + .phy_init = exynosautov920_usb31drd_pipe3_init, + }, +}; + +static const struct phy_ops exynosautov920_usb31drd_combo_ssphy_ops = { + .init = exynosautov920_usbdrd_phy_init, + .exit = exynosautov920_usbdrd_combo_phy_exit, + .power_on = exynosautov920_usbdrd_phy_power_on, + .power_off = exynosautov920_usbdrd_phy_power_off, + .owner = THIS_MODULE, +}; + +static const +struct exynos5_usbdrd_phy_drvdata exynosautov920_usb31drd_combo_ssphy = { + .phy_cfg = usb31drd_phy_cfg_exynosautov920, + .phy_ops = &exynosautov920_usb31drd_combo_ssphy_ops, + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB31, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynosautov920_usb30_regulators, + .n_regulators = ARRAY_SIZE(exynosautov920_usb30_regulators), +}; + +static const struct phy_ops exynosautov920_usbdrd_combo_hsphy_ops = { + .init = exynosautov920_usbdrd_phy_init, + .exit = exynosautov920_usbdrd_combo_phy_exit, + .power_on = exynosautov920_usbdrd_phy_power_on, + .power_off = exynosautov920_usbdrd_phy_power_off, + .owner = THIS_MODULE, +}; + +static const struct +exynos5_usbdrd_phy_config usbdrd_hsphy_cfg_exynosautov920[] = { + { + .id = EXYNOS5_DRDPHY_UTMI, + .phy_isol = exynos5_usbdrd_phy_isol, + .phy_init = exynosautov920_usbdrd_utmi_init, + }, +}; + +static const +struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_combo_hsphy = { + .phy_cfg = usbdrd_hsphy_cfg_exynosautov920, + .phy_ops = &exynosautov920_usbdrd_combo_hsphy_ops, + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynosautov920_usb20_regulators, + .n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators), +}; + +static const struct phy_ops exynosautov920_usbdrd_phy_ops = { + .init = exynosautov920_usbdrd_phy_init, + .exit = exynosautov920_usbdrd_phy_exit, + .power_on = exynosautov920_usbdrd_phy_power_on, + .power_off = exynosautov920_usbdrd_phy_power_off, + .owner = THIS_MODULE, +}; + +static const struct exynos5_usbdrd_phy_config phy_cfg_exynosautov920[] = { + { + .id = EXYNOS5_DRDPHY_UTMI, + .phy_isol = exynos5_usbdrd_phy_isol, + .phy_init = exynos850_usbdrd_utmi_init, + }, +}; + +static const struct exynos5_usbdrd_phy_drvdata exynosautov920_usbdrd_phy = { + .phy_cfg = phy_cfg_exynosautov920, + .phy_ops = &exynosautov920_usbdrd_phy_ops, + .pmu_offset_usbdrd0_phy = EXYNOSAUTOV920_PHY_CTRL_USB20, + .clk_names = exynos5_clk_names, + .n_clks = ARRAY_SIZE(exynos5_clk_names), + .core_clk_names = exynos5_core_clk_names, + .n_core_clks = ARRAY_SIZE(exynos5_core_clk_names), + .regulator_names = exynosautov920_usb20_regulators, + .n_regulators = ARRAY_SIZE(exynosautov920_usb20_regulators), +}; + static const struct exynos5_usbdrd_phy_config phy_cfg_gs101[] = { { .id = EXYNOS5_DRDPHY_UTMI, @@ -2260,6 +2902,15 @@ static const struct of_device_id exynos5_usbdrd_phy_of_match[] = { }, { .compatible = "samsung,exynos990-usbdrd-phy", .data = &exynos990_usbdrd_phy + }, { + .compatible = "samsung,exynosautov920-usb31drd-combo-ssphy", + .data = &exynosautov920_usb31drd_combo_ssphy + }, { + .compatible = "samsung,exynosautov920-usbdrd-combo-hsphy", + .data = &exynosautov920_usbdrd_combo_hsphy + }, { + .compatible = "samsung,exynosautov920-usbdrd-phy", + .data = &exynosautov920_usbdrd_phy }, { }, }; diff --git a/drivers/phy/socionext/phy-uniphier-usb2.c b/drivers/phy/socionext/phy-uniphier-usb2.c index 21c201717d95..c49d432e526b 100644 --- a/drivers/phy/socionext/phy-uniphier-usb2.c +++ b/drivers/phy/socionext/phy-uniphier-usb2.c @@ -106,7 +106,7 @@ static const struct phy_ops uniphier_u2phy_ops = { static int uniphier_u2phy_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *parent, *child; + struct device_node *parent; struct uniphier_u2phy_priv *priv = NULL, *next = NULL; struct phy_provider *phy_provider; struct regmap *regmap; @@ -129,34 +129,31 @@ static int uniphier_u2phy_probe(struct platform_device *pdev) return PTR_ERR(regmap); } - for_each_child_of_node(dev->of_node, child) { + for_each_child_of_node_scoped(dev->of_node, child) { priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto out_put_child; - } + if (!priv) + return -ENOMEM; + priv->regmap = regmap; priv->vbus = devm_regulator_get_optional(dev, "vbus"); if (IS_ERR(priv->vbus)) { - if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) { - ret = PTR_ERR(priv->vbus); - goto out_put_child; - } + if (PTR_ERR(priv->vbus) == -EPROBE_DEFER) + return PTR_ERR(priv->vbus); + priv->vbus = NULL; } priv->phy = devm_phy_create(dev, child, &uniphier_u2phy_ops); if (IS_ERR(priv->phy)) { dev_err(dev, "Failed to create phy\n"); - ret = PTR_ERR(priv->phy); - goto out_put_child; + return PTR_ERR(priv->phy); } ret = of_property_read_u32(child, "reg", &data_idx); if (ret) { dev_err(dev, "Failed to get reg property\n"); - goto out_put_child; + return ret; } if (data_idx < ndatas) @@ -174,11 +171,6 @@ static int uniphier_u2phy_probe(struct platform_device *pdev) phy_provider = devm_of_phy_provider_register(dev, uniphier_u2phy_xlate); return PTR_ERR_OR_ZERO(phy_provider); - -out_put_child: - of_node_put(child); - - return ret; } static const struct uniphier_u2phy_soc_data uniphier_pro4_data[] = { diff --git a/drivers/phy/spacemit/Kconfig b/drivers/phy/spacemit/Kconfig new file mode 100644 index 000000000000..0136aee2e8a2 --- /dev/null +++ b/drivers/phy/spacemit/Kconfig @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Phy drivers for SpacemiT platforms +# +config PHY_SPACEMIT_K1_USB2 + tristate "SpacemiT K1 USB 2.0 PHY support" + depends on (ARCH_SPACEMIT || COMPILE_TEST) && OF + depends on COMMON_CLK + depends on USB_COMMON + select GENERIC_PHY + help + Enable this to support K1 USB 2.0 PHY driver. This driver takes care of + enabling and clock setup and will be used by K1 udc/ehci/otg/xhci driver. diff --git a/drivers/phy/spacemit/Makefile b/drivers/phy/spacemit/Makefile new file mode 100644 index 000000000000..fec0b425a948 --- /dev/null +++ b/drivers/phy/spacemit/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_PHY_SPACEMIT_K1_USB2) += phy-k1-usb2.o diff --git a/drivers/phy/spacemit/phy-k1-usb2.c b/drivers/phy/spacemit/phy-k1-usb2.c new file mode 100644 index 000000000000..342061380012 --- /dev/null +++ b/drivers/phy/spacemit/phy-k1-usb2.c @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * SpacemiT K1 USB 2.0 PHY driver + * + * Copyright (C) 2025 SpacemiT (Hangzhou) Technology Co. Ltd + * Copyright (C) 2025 Ze Huang + */ + +#include +#include +#include +#include +#include +#include + +#define PHY_RST_MODE_CTRL 0x04 +#define PHY_PLL_RDY BIT(0) +#define PHY_CLK_CDR_EN BIT(1) +#define PHY_CLK_PLL_EN BIT(2) +#define PHY_CLK_MAC_EN BIT(3) +#define PHY_MAC_RSTN BIT(5) +#define PHY_CDR_RSTN BIT(6) +#define PHY_PLL_RSTN BIT(7) +/* + * hs line state sel (Bit 13): + * - 1 (Default): Internal HS line state is set to 01 when usb_hs_tx_en is valid. + * - 0: Internal HS line state is always driven by usb_hs_lstate. + * + * fs line state sel (Bit 14): + * - 1 (Default): FS line state is determined by the output data + * (usb_fs_datain/b). + * - 0: FS line state is always determined by the input data (dmo/dpo). + */ +#define PHY_HS_LINE_TX_MODE BIT(13) +#define PHY_FS_LINE_TX_MODE BIT(14) + +#define PHY_INIT_MODE_BITS (PHY_FS_LINE_TX_MODE | PHY_HS_LINE_TX_MODE) +#define PHY_CLK_ENABLE_BITS (PHY_CLK_PLL_EN | PHY_CLK_CDR_EN | \ + PHY_CLK_MAC_EN) +#define PHY_DEASSERT_RST_BITS (PHY_PLL_RSTN | PHY_CDR_RSTN | \ + PHY_MAC_RSTN) + +#define PHY_TX_HOST_CTRL 0x10 +#define PHY_HST_DISC_AUTO_CLR BIT(2) /* autoclear hs host disc when re-connect */ + +#define PHY_HSTXP_HW_CTRL 0x34 +#define PHY_HSTXP_RSTN BIT(2) /* generate reset for clock hstxp */ +#define PHY_CLK_HSTXP_EN BIT(3) /* clock hstxp enable */ +#define PHY_HSTXP_MODE BIT(4) /* 0: force en_txp to be 1; 1: no force */ + +#define PHY_PLL_DIV_CFG 0x98 +#define PHY_FDIV_FRACT_8_15 GENMASK(7, 0) +#define PHY_FDIV_FRACT_16_19 GENMASK(11, 8) +#define PHY_FDIV_FRACT_20_21 BIT(12) /* fdiv_reg<21>, <20>, bit21 == bit20 */ +/* + * freq_sel<1:0> + * if ref clk freq=24.0MHz-->freq_sel<2:0> == 3b'001, then internal divider value == 80 + */ +#define PHY_FDIV_FRACT_0_1 GENMASK(14, 13) +/* + * pll divider value selection + * 1: divider value will choose internal default value ,dependent on freq_sel<1:0> + * 0: divider value will be over ride by fdiv_reg<21:0> + */ +#define PHY_DIV_LOCAL_EN BIT(15) + +#define PHY_SEL_FREQ_24MHZ 0x01 +#define FDIV_REG_MASK (PHY_FDIV_FRACT_20_21 | PHY_FDIV_FRACT_16_19 | \ + PHY_FDIV_FRACT_8_15) +#define FDIV_REG_VAL 0x1ec4 /* 0x100 selects 24MHz, rest are default */ + +#define K1_USB2PHY_RESET_TIME_MS 50 + +struct spacemit_usb2phy { + struct phy *phy; + struct clk *clk; + struct regmap *regmap_base; +}; + +static const struct regmap_config phy_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x200, +}; + +static int spacemit_usb2phy_init(struct phy *phy) +{ + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); + struct regmap *map = sphy->regmap_base; + u32 val; + int ret; + + ret = clk_enable(sphy->clk); + if (ret) { + dev_err(&phy->dev, "failed to enable clock\n"); + clk_disable(sphy->clk); + return ret; + } + + /* + * make sure the usb controller is not under reset process before + * any configuration + */ + usleep_range(150, 200); + + /* 24M ref clk */ + val = FIELD_PREP(FDIV_REG_MASK, FDIV_REG_VAL) | + FIELD_PREP(PHY_FDIV_FRACT_0_1, PHY_SEL_FREQ_24MHZ) | + PHY_DIV_LOCAL_EN; + regmap_write(map, PHY_PLL_DIV_CFG, val); + + ret = regmap_read_poll_timeout(map, PHY_RST_MODE_CTRL, val, + (val & PHY_PLL_RDY), + 500, K1_USB2PHY_RESET_TIME_MS * 1000); + if (ret) { + dev_err(&phy->dev, "wait PLLREADY timeout\n"); + clk_disable(sphy->clk); + return ret; + } + + /* release usb2 phy internal reset and enable clock gating */ + val = (PHY_INIT_MODE_BITS | PHY_CLK_ENABLE_BITS | PHY_DEASSERT_RST_BITS); + regmap_write(map, PHY_RST_MODE_CTRL, val); + + val = (PHY_HSTXP_RSTN | PHY_CLK_HSTXP_EN | PHY_HSTXP_MODE); + regmap_write(map, PHY_HSTXP_HW_CTRL, val); + + /* auto clear host disc */ + regmap_update_bits(map, PHY_TX_HOST_CTRL, PHY_HST_DISC_AUTO_CLR, + PHY_HST_DISC_AUTO_CLR); + + return 0; +} + +static int spacemit_usb2phy_exit(struct phy *phy) +{ + struct spacemit_usb2phy *sphy = phy_get_drvdata(phy); + + clk_disable(sphy->clk); + + return 0; +} + +static const struct phy_ops spacemit_usb2phy_ops = { + .init = spacemit_usb2phy_init, + .exit = spacemit_usb2phy_exit, + .owner = THIS_MODULE, +}; + +static int spacemit_usb2phy_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct spacemit_usb2phy *sphy; + void __iomem *base; + + sphy = devm_kzalloc(dev, sizeof(*sphy), GFP_KERNEL); + if (!sphy) + return -ENOMEM; + + sphy->clk = devm_clk_get_prepared(&pdev->dev, NULL); + if (IS_ERR(sphy->clk)) + return dev_err_probe(dev, PTR_ERR(sphy->clk), "Failed to get clock\n"); + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + sphy->regmap_base = devm_regmap_init_mmio(dev, base, &phy_regmap_config); + if (IS_ERR(sphy->regmap_base)) + return dev_err_probe(dev, PTR_ERR(sphy->regmap_base), "Failed to init regmap\n"); + + sphy->phy = devm_phy_create(dev, NULL, &spacemit_usb2phy_ops); + if (IS_ERR(sphy->phy)) + return dev_err_probe(dev, PTR_ERR(sphy->phy), "Failed to create phy\n"); + + phy_set_drvdata(sphy->phy, sphy); + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static const struct of_device_id spacemit_usb2phy_dt_match[] = { + { .compatible = "spacemit,k1-usb2-phy", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spacemit_usb2phy_dt_match); + +static struct platform_driver spacemit_usb2_phy_driver = { + .probe = spacemit_usb2phy_probe, + .driver = { + .name = "spacemit-usb2-phy", + .of_match_table = spacemit_usb2phy_dt_match, + }, +}; +module_platform_driver(spacemit_usb2_phy_driver); + +MODULE_DESCRIPTION("Spacemit USB 2.0 PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/tegra/xusb-tegra124.c b/drivers/phy/tegra/xusb-tegra124.c index f4f75ea033b8..70b6213370a8 100644 --- a/drivers/phy/tegra/xusb-tegra124.c +++ b/drivers/phy/tegra/xusb-tegra124.c @@ -430,7 +430,7 @@ tegra124_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_usb2_lane *usb2; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -614,7 +614,7 @@ tegra124_usb2_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -679,7 +679,7 @@ tegra124_ulpi_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_ulpi_lane *ulpi; int err; - ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); + ulpi = kzalloc_obj(*ulpi); if (!ulpi) return ERR_PTR(-ENOMEM); @@ -751,7 +751,7 @@ tegra124_ulpi_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); + ulpi = kzalloc_obj(*ulpi); if (!ulpi) return ERR_PTR(-ENOMEM); @@ -815,7 +815,7 @@ tegra124_hsic_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_hsic_lane *hsic; int err; - hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); + hsic = kzalloc_obj(*hsic); if (!hsic) return ERR_PTR(-ENOMEM); @@ -967,7 +967,7 @@ tegra124_hsic_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); + hsic = kzalloc_obj(*hsic); if (!hsic) return ERR_PTR(-ENOMEM); @@ -1035,7 +1035,7 @@ tegra124_pcie_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_pcie_lane *pcie; int err; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return ERR_PTR(-ENOMEM); @@ -1155,7 +1155,7 @@ tegra124_pcie_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return ERR_PTR(-ENOMEM); @@ -1213,7 +1213,7 @@ tegra124_sata_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_sata_lane *sata; int err; - sata = kzalloc(sizeof(*sata), GFP_KERNEL); + sata = kzalloc_obj(*sata); if (!sata) return ERR_PTR(-ENOMEM); @@ -1351,7 +1351,7 @@ tegra124_sata_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - sata = kzalloc(sizeof(*sata), GFP_KERNEL); + sata = kzalloc_obj(*sata); if (!sata) return ERR_PTR(-ENOMEM); diff --git a/drivers/phy/tegra/xusb-tegra186.c b/drivers/phy/tegra/xusb-tegra186.c index bec9616c4a2e..1ddf11265974 100644 --- a/drivers/phy/tegra/xusb-tegra186.c +++ b/drivers/phy/tegra/xusb-tegra186.c @@ -302,7 +302,7 @@ tegra186_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_usb2_lane *usb2; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -1031,7 +1031,7 @@ tegra186_usb2_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -1113,7 +1113,7 @@ tegra186_usb3_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_usb3_lane *usb3; int err; - usb3 = kzalloc(sizeof(*usb3), GFP_KERNEL); + usb3 = kzalloc_obj(*usb3); if (!usb3) return ERR_PTR(-ENOMEM); @@ -1417,7 +1417,7 @@ tegra186_usb3_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - usb3 = kzalloc(sizeof(*usb3), GFP_KERNEL); + usb3 = kzalloc_obj(*usb3); if (!usb3) return ERR_PTR(-ENOMEM); diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c index 3409924498e9..1abc5913ec49 100644 --- a/drivers/phy/tegra/xusb-tegra210.c +++ b/drivers/phy/tegra/xusb-tegra210.c @@ -1759,7 +1759,7 @@ tegra210_usb2_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_usb2_lane *usb2; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -2185,7 +2185,7 @@ tegra210_usb2_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) return ERR_PTR(-ENOMEM); @@ -2255,7 +2255,7 @@ tegra210_hsic_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_hsic_lane *hsic; int err; - hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); + hsic = kzalloc_obj(*hsic); if (!hsic) return ERR_PTR(-ENOMEM); @@ -2439,7 +2439,7 @@ tegra210_hsic_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); + hsic = kzalloc_obj(*hsic); if (!hsic) return ERR_PTR(-ENOMEM); @@ -2688,7 +2688,7 @@ tegra210_pcie_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_pcie_lane *pcie; int err; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return ERR_PTR(-ENOMEM); @@ -2786,7 +2786,7 @@ tegra210_pcie_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - pcie = kzalloc(sizeof(*pcie), GFP_KERNEL); + pcie = kzalloc_obj(*pcie); if (!pcie) return ERR_PTR(-ENOMEM); @@ -2858,7 +2858,7 @@ tegra210_sata_lane_probe(struct tegra_xusb_pad *pad, struct device_node *np, struct tegra_xusb_sata_lane *sata; int err; - sata = kzalloc(sizeof(*sata), GFP_KERNEL); + sata = kzalloc_obj(*sata); if (!sata) return ERR_PTR(-ENOMEM); @@ -2955,7 +2955,7 @@ tegra210_sata_pad_probe(struct tegra_xusb_padctl *padctl, struct tegra_xusb_pad *pad; int err; - sata = kzalloc(sizeof(*sata), GFP_KERNEL); + sata = kzalloc_obj(*sata); if (!sata) return ERR_PTR(-ENOMEM); diff --git a/drivers/phy/tegra/xusb.c b/drivers/phy/tegra/xusb.c index c89df95aa6ca..9d74c0ecc31b 100644 --- a/drivers/phy/tegra/xusb.c +++ b/drivers/phy/tegra/xusb.c @@ -796,7 +796,7 @@ static int tegra_xusb_add_usb2_port(struct tegra_xusb_padctl *padctl, if (!np || !of_device_is_available(np)) goto out; - usb2 = kzalloc(sizeof(*usb2), GFP_KERNEL); + usb2 = kzalloc_obj(*usb2); if (!usb2) { err = -ENOMEM; goto out; @@ -863,7 +863,7 @@ static int tegra_xusb_add_ulpi_port(struct tegra_xusb_padctl *padctl, if (!np || !of_device_is_available(np)) goto out; - ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); + ulpi = kzalloc_obj(*ulpi); if (!ulpi) { err = -ENOMEM; goto out; @@ -919,7 +919,7 @@ static int tegra_xusb_add_hsic_port(struct tegra_xusb_padctl *padctl, if (!np || !of_device_is_available(np)) goto out; - hsic = kzalloc(sizeof(*hsic), GFP_KERNEL); + hsic = kzalloc_obj(*hsic); if (!hsic) { err = -ENOMEM; goto out; @@ -1004,7 +1004,7 @@ static int tegra_xusb_add_usb3_port(struct tegra_xusb_padctl *padctl, if (!np || !of_device_is_available(np)) goto out; - usb3 = kzalloc(sizeof(*usb3), GFP_KERNEL); + usb3 = kzalloc_obj(*usb3); if (!usb3) { err = -ENOMEM; goto out; diff --git a/drivers/phy/tegra/xusb.h b/drivers/phy/tegra/xusb.h index d2b5f9565132..cd277d0ed9e1 100644 --- a/drivers/phy/tegra/xusb.h +++ b/drivers/phy/tegra/xusb.h @@ -69,7 +69,6 @@ struct tegra_xusb_usb2_lane { struct tegra_xusb_lane base; u32 hs_curr_level_offset; - bool powered_on; }; static inline struct tegra_xusb_usb2_lane * diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index a8b440c6c46b..6e9ecb88dc8b 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -393,6 +393,7 @@ struct wiz { struct clk *output_clks[WIZ_MAX_OUTPUT_CLOCKS]; struct clk_onecell_data clk_data; const struct wiz_data *data; + int mux_sel_status[WIZ_MUX_NUM_CLOCKS]; }; static int wiz_reset(struct wiz *wiz) @@ -934,12 +935,12 @@ static unsigned long wiz_clk_div_recalc_rate(struct clk_hw *hw, return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2); } -static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) +static int wiz_clk_div_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct wiz_clk_divider *div = to_wiz_clk_div(hw); - return divider_round_rate(hw, rate, prate, div->table, 2, 0x0); + return divider_determine_rate(hw, req, div->table, 2, 0x0); } static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, @@ -958,7 +959,7 @@ static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate, static const struct clk_ops wiz_clk_div_ops = { .recalc_rate = wiz_clk_div_recalc_rate, - .round_rate = wiz_clk_div_round_rate, + .determine_rate = wiz_clk_div_determine_rate, .set_rate = wiz_clk_div_set_rate, }; @@ -1654,11 +1655,25 @@ static void wiz_remove(struct platform_device *pdev) pm_runtime_disable(dev); } +static int wiz_suspend_noirq(struct device *dev) +{ + struct wiz *wiz = dev_get_drvdata(dev); + int i; + + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) + regmap_field_read(wiz->mux_sel_field[i], &wiz->mux_sel_status[i]); + + return 0; +} + static int wiz_resume_noirq(struct device *dev) { struct device_node *node = dev->of_node; struct wiz *wiz = dev_get_drvdata(dev); - int ret; + int ret, i; + + for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) + regmap_field_write(wiz->mux_sel_field[i], wiz->mux_sel_status[i]); /* Enable supplemental Control override if available */ if (wiz->sup_legacy_clk_override) @@ -1680,7 +1695,7 @@ static int wiz_resume_noirq(struct device *dev) return ret; } -static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, NULL, wiz_resume_noirq); +static DEFINE_NOIRQ_DEV_PM_OPS(wiz_pm_ops, wiz_suspend_noirq, wiz_resume_noirq); static struct platform_driver wiz_driver = { .probe = wiz_probe, diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 7b9f792acb0e..afecd9407f53 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -25,6 +25,12 @@ config GENERIC_PINCONF bool select PINCONF +config GENERIC_PINCTRL + bool + select GENERIC_PINCONF + select GENERIC_PINCTRL_GROUPS + select GENERIC_PINMUX_FUNCTIONS + config DEBUG_PINCTRL bool "Debug PINCTRL calls" depends on DEBUG_KERNEL @@ -486,16 +492,6 @@ config PINCTRL_PIC32MZDA def_bool y if PIC32MZDA select PINCTRL_PIC32 -config PINCTRL_PIC64GX - bool "pic64gx gpio2 pinctrl driver" - depends on ARCH_MICROCHIP || COMPILE_TEST - depends on OF - select GENERIC_PINCONF - select REGMAP_MMIO - default y - help - This selects the pinctrl driver for gpio2 on pic64gx. - config PINCTRL_PISTACHIO bool "IMG Pistachio SoC pinctrl driver" depends on OF && (MIPS || COMPILE_TEST) @@ -507,15 +503,6 @@ config PINCTRL_PISTACHIO help This support pinctrl and GPIO driver for IMG Pistachio SoC. -config PINCTRL_POLARFIRE_SOC - bool "Polarfire SoC pinctrl driver" - depends on ARCH_MICROCHIP || COMPILE_TEST - depends on OF - select GENERIC_PINCONF - default y - help - This selects the pinctrl driver for Microchip Polarfire SoC. - config PINCTRL_RK805 tristate "Pinctrl and GPIO driver for RK805 PMIC" depends on MFD_RK8XX @@ -710,6 +697,7 @@ source "drivers/pinctrl/freescale/Kconfig" source "drivers/pinctrl/intel/Kconfig" source "drivers/pinctrl/mediatek/Kconfig" source "drivers/pinctrl/meson/Kconfig" +source "drivers/pinctrl/microchip/Kconfig" source "drivers/pinctrl/mvebu/Kconfig" source "drivers/pinctrl/nomadik/Kconfig" source "drivers/pinctrl/nuvoton/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index be5200c23e60..f7d5d5f76d0c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -7,6 +7,7 @@ obj-y += core.o pinctrl-utils.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.o +obj-$(CONFIG_GENERIC_PINCTRL) += pinctrl-generic.o obj-$(CONFIG_OF) += devicetree.o obj-$(CONFIG_PINCTRL_AMD) += pinctrl-amd.o @@ -48,9 +49,7 @@ obj-$(CONFIG_PINCTRL_OCELOT) += pinctrl-ocelot.o obj-$(CONFIG_PINCTRL_PALMAS) += pinctrl-palmas.o obj-$(CONFIG_PINCTRL_PEF2256) += pinctrl-pef2256.o obj-$(CONFIG_PINCTRL_PIC32) += pinctrl-pic32.o -obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o obj-$(CONFIG_PINCTRL_PISTACHIO) += pinctrl-pistachio.o -obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_RP1) += pinctrl-rp1.o @@ -76,6 +75,7 @@ obj-y += freescale/ obj-$(CONFIG_X86) += intel/ obj-y += mediatek/ obj-$(CONFIG_PINCTRL_MESON) += meson/ +obj-y += microchip/ obj-y += mvebu/ obj-y += nomadik/ obj-y += nuvoton/ diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c index cb295856dda1..f9d8fb1ab1ec 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c @@ -6,14 +6,12 @@ #include #include #include -#include -#include +#include #include #include #include #include #include -#include #include #include "../core.h" diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c index 792089628362..50979787db5c 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c @@ -7,14 +7,13 @@ #include #include #include -#include +#include #include #include #include #include #include #include -#include #include #include "../core.h" @@ -2654,9 +2653,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx, np = of_parse_phandle(ctx->dev->of_node, "aspeed,external-nodes", 1); if (np) { - if (!of_device_is_compatible(np->parent, "aspeed,ast2400-lpc-v2") && - !of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2") && - !of_device_is_compatible(np->parent, "aspeed,ast2600-lpc-v2")) + if (!of_device_is_compatible(np->parent, "aspeed,ast2500-lpc-v2")) return ERR_PTR(-ENODEV); map = syscon_node_to_regmap(np->parent); diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c index b0c7e4f6df9c..8cf61aab81b1 100644 --- a/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed-g6.c @@ -4,13 +4,10 @@ #include #include #include -#include -#include -#include +#include #include #include #include -#include #include #include "../core.h" diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index c165674c5b4d..e7b35019a5a7 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -803,7 +803,7 @@ static int bcm2835_pctl_dt_node_to_map_pull(struct bcm2835_pinctrl *pc, return -EINVAL; } - configs = kzalloc(sizeof(*configs), GFP_KERNEL); + configs = kzalloc_obj(*configs); if (!configs) return -ENOMEM; configs[0] = pinconf_to_config_packed(BCM2835_PINCONF_PARAM_PULL, pull); @@ -873,8 +873,7 @@ static int bcm2835_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, maps_per_pin++; if (num_pulls) maps_per_pin++; - cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps), - GFP_KERNEL); + cur_map = maps = kzalloc_objs(*maps, num_pins * maps_per_pin); if (!maps) return -ENOMEM; diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c index 8afcfa4e5694..7971339e269f 100644 --- a/drivers/pinctrl/berlin/berlin.c +++ b/drivers/pinctrl/berlin/berlin.c @@ -215,7 +215,7 @@ static int berlin_pinctrl_build_state(struct platform_device *pdev) } /* we will reallocate later */ - pctrl->functions = kcalloc(max_functions, sizeof(*pctrl->functions), GFP_KERNEL); + pctrl->functions = kzalloc_objs(*pctrl->functions, max_functions); if (!pctrl->functions) return -ENOMEM; diff --git a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c index a8f82104a384..227c37c360e1 100644 --- a/drivers/pinctrl/cirrus/pinctrl-cs42l43.c +++ b/drivers/pinctrl/cirrus/pinctrl-cs42l43.c @@ -574,10 +574,9 @@ static int cs42l43_pin_probe(struct platform_device *pdev) if (child) { ret = devm_add_action_or_reset(&pdev->dev, cs42l43_fwnode_put, child); - if (ret) { - fwnode_handle_put(child); + if (ret) return ret; - } + if (!child->dev) child->dev = priv->dev; fwnode = child; diff --git a/drivers/pinctrl/cix/pinctrl-sky1.c b/drivers/pinctrl/cix/pinctrl-sky1.c index 5d0d8be815b2..938894058d86 100644 --- a/drivers/pinctrl/cix/pinctrl-sky1.c +++ b/drivers/pinctrl/cix/pinctrl-sky1.c @@ -522,11 +522,10 @@ static int __maybe_unused sky1_pinctrl_resume(struct device *dev) return pinctrl_force_default(spctl->pctl); } -const struct dev_pm_ops sky1_pinctrl_pm_ops = { +static const struct dev_pm_ops sky1_pinctrl_pm_ops = { SET_LATE_SYSTEM_SLEEP_PM_OPS(sky1_pinctrl_suspend, sky1_pinctrl_resume) }; -EXPORT_SYMBOL_GPL(sky1_pinctrl_pm_ops); static int sky1_pinctrl_probe(struct platform_device *pdev) { diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 83254a95ef17..b5e97689589f 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -215,7 +215,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, return -EINVAL; } - pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); + pindesc = kzalloc_obj(*pindesc); if (!pindesc) return -ENOMEM; @@ -955,7 +955,7 @@ static struct pinctrl_state *create_state(struct pinctrl *p, { struct pinctrl_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); @@ -983,7 +983,7 @@ static int add_setting(struct pinctrl *p, struct pinctrl_dev *pctldev, if (map->type == PIN_MAP_TYPE_DUMMY_STATE) return 0; - setting = kzalloc(sizeof(*setting), GFP_KERNEL); + setting = kzalloc_obj(*setting); if (!setting) return -ENOMEM; @@ -1063,7 +1063,7 @@ static struct pinctrl *create_pinctrl(struct device *dev, * mapping, this is what consumers will get when requesting * a pin control handle with pinctrl_get() */ - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return ERR_PTR(-ENOMEM); p->dev = dev; @@ -1383,9 +1383,9 @@ int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) } EXPORT_SYMBOL_GPL(pinctrl_select_state); -static void devm_pinctrl_release(struct device *dev, void *res) +static void devm_pinctrl_release(void *p) { - pinctrl_put(*(struct pinctrl **)res); + pinctrl_put(p); } /** @@ -1397,31 +1397,21 @@ static void devm_pinctrl_release(struct device *dev, void *res) */ struct pinctrl *devm_pinctrl_get(struct device *dev) { - struct pinctrl **ptr, *p; - - ptr = devres_alloc(devm_pinctrl_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); + struct pinctrl *p; + int ret; p = pinctrl_get(dev); - if (!IS_ERR(p)) { - *ptr = p; - devres_add(dev, ptr); - } else { - devres_free(ptr); - } + if (IS_ERR(p)) + return p; + + ret = devm_add_action_or_reset(dev, devm_pinctrl_release, p); + if (ret) + return ERR_PTR(ret); return p; } EXPORT_SYMBOL_GPL(devm_pinctrl_get); -static int devm_pinctrl_match(struct device *dev, void *res, void *data) -{ - struct pinctrl **p = res; - - return *p == data; -} - /** * devm_pinctrl_put() - Resource managed pinctrl_put() * @p: the pinctrl handle to release @@ -1432,8 +1422,7 @@ static int devm_pinctrl_match(struct device *dev, void *res, void *data) */ void devm_pinctrl_put(struct pinctrl *p) { - WARN_ON(devres_release(p->dev, devm_pinctrl_release, - devm_pinctrl_match, p)); + devm_release_action(p->dev, devm_pinctrl_release, p); } EXPORT_SYMBOL_GPL(devm_pinctrl_put); @@ -1494,7 +1483,7 @@ int pinctrl_register_mappings(const struct pinctrl_map *maps, } } - maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL); + maps_node = kzalloc_obj(*maps_node); if (!maps_node) return -ENOMEM; @@ -2087,7 +2076,7 @@ pinctrl_init_controller(const struct pinctrl_desc *pctldesc, struct device *dev, if (!pctldesc->name) return ERR_PTR(-EINVAL); - pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL); + pctldev = kzalloc_obj(*pctldev); if (!pctldev) return ERR_PTR(-ENOMEM); @@ -2198,10 +2187,8 @@ int pinctrl_enable(struct pinctrl_dev *pctldev) int error; error = pinctrl_claim_hogs(pctldev); - if (error) { - dev_err(pctldev->dev, "could not claim hogs: %i\n", error); + if (error) return error; - } mutex_lock(&pinctrldev_list_mutex); list_add_tail(&pctldev->node, &pinctrldev_list); @@ -2316,23 +2303,11 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) } EXPORT_SYMBOL_GPL(pinctrl_unregister); -static void devm_pinctrl_dev_release(struct device *dev, void *res) +static void devm_pinctrl_dev_release(void *pctldev) { - struct pinctrl_dev *pctldev = *(struct pinctrl_dev **)res; - pinctrl_unregister(pctldev); } -static int devm_pinctrl_dev_match(struct device *dev, void *res, void *data) -{ - struct pctldev **r = res; - - if (WARN_ON(!r || !*r)) - return 0; - - return *r == data; -} - /** * devm_pinctrl_register() - Resource managed version of pinctrl_register(). * @dev: parent device for this pin controller @@ -2348,20 +2323,16 @@ struct pinctrl_dev *devm_pinctrl_register(struct device *dev, const struct pinctrl_desc *pctldesc, void *driver_data) { - struct pinctrl_dev **ptr, *pctldev; - - ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return ERR_PTR(-ENOMEM); + struct pinctrl_dev *pctldev; + int ret; pctldev = pinctrl_register(pctldesc, dev, driver_data); - if (IS_ERR(pctldev)) { - devres_free(ptr); + if (IS_ERR(pctldev)) return pctldev; - } - *ptr = pctldev; - devres_add(dev, ptr); + ret = devm_add_action_or_reset(dev, devm_pinctrl_dev_release, pctldev); + if (ret) + return ERR_PTR(ret); return pctldev; } @@ -2383,38 +2354,16 @@ int devm_pinctrl_register_and_init(struct device *dev, void *driver_data, struct pinctrl_dev **pctldev) { - struct pinctrl_dev **ptr; int error; - ptr = devres_alloc(devm_pinctrl_dev_release, sizeof(*ptr), GFP_KERNEL); - if (!ptr) - return -ENOMEM; - error = pinctrl_register_and_init(pctldesc, dev, driver_data, pctldev); - if (error) { - devres_free(ptr); + if (error) return error; - } - *ptr = *pctldev; - devres_add(dev, ptr); - - return 0; + return devm_add_action_or_reset(dev, devm_pinctrl_dev_release, *pctldev); } EXPORT_SYMBOL_GPL(devm_pinctrl_register_and_init); -/** - * devm_pinctrl_unregister() - Resource managed version of pinctrl_unregister(). - * @dev: device for which resource was allocated - * @pctldev: the pinctrl device to unregister. - */ -void devm_pinctrl_unregister(struct device *dev, struct pinctrl_dev *pctldev) -{ - WARN_ON(devres_release(dev, devm_pinctrl_dev_release, - devm_pinctrl_dev_match, pctldev)); -} -EXPORT_SYMBOL_GPL(devm_pinctrl_unregister); - static int __init pinctrl_init(void) { pr_debug("initialized pinctrl subsystem\n"); diff --git a/drivers/pinctrl/devicetree.c b/drivers/pinctrl/devicetree.c index 0b7f74beb6a6..d0c3e26409a8 100644 --- a/drivers/pinctrl/devicetree.c +++ b/drivers/pinctrl/devicetree.c @@ -84,7 +84,7 @@ static int dt_remember_or_free_map(struct pinctrl *p, const char *statename, } /* Remember the converted mapping table entries */ - dt_map = kzalloc(sizeof(*dt_map), GFP_KERNEL); + dt_map = kzalloc_obj(*dt_map); if (!dt_map) goto err_free_map; @@ -187,7 +187,7 @@ static int dt_remember_dummy_state(struct pinctrl *p, const char *statename) { struct pinctrl_map *map; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return -ENOMEM; diff --git a/drivers/pinctrl/freescale/pinctrl-imx-scmi.c b/drivers/pinctrl/freescale/pinctrl-imx-scmi.c index 4e8ab919b334..e14bdbc7bea7 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx-scmi.c +++ b/drivers/pinctrl/freescale/pinctrl-imx-scmi.c @@ -38,11 +38,12 @@ struct scmi_pinctrl_imx { }; /* SCMI pin control types, aligned with SCMI firmware */ -#define IMX_SCMI_NUM_CFG 4 +#define IMX_SCMI_NUM_CFG 5 #define IMX_SCMI_PIN_MUX 192 #define IMX_SCMI_PIN_CONFIG 193 #define IMX_SCMI_PIN_DAISY_ID 194 #define IMX_SCMI_PIN_DAISY_CFG 195 +#define IMX_SCMI_PIN_EXT 196 #define IMX_SCMI_NO_PAD_CTL BIT(31) #define IMX_SCMI_PAD_SION BIT(30) @@ -50,8 +51,9 @@ struct scmi_pinctrl_imx { #define IMX_SCMI_PIN_SIZE 24 -#define IMX95_DAISY_OFF 0x408 #define IMX94_DAISY_OFF 0x608 +#define IMX95_DAISY_OFF 0x408 +#define IMX952_DAISY_OFF 0x460 static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np, @@ -73,6 +75,8 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev, daisy_off = IMX95_DAISY_OFF; } else if (of_machine_is_compatible("fsl,imx94")) { daisy_off = IMX94_DAISY_OFF; + } else if (of_machine_is_compatible("fsl,imx952")) { + daisy_off = IMX952_DAISY_OFF; } else { dev_err(pctldev->dev, "platform not support scmi pinctrl\n"); return -EINVAL; @@ -95,8 +99,7 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev, num_pins = size / pin_size; map_num = num_pins; - new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), - GFP_KERNEL); + new_map = kmalloc_objs(struct pinctrl_map, map_num); if (!new_map) return -ENOMEM; @@ -118,7 +121,14 @@ static int pinctrl_scmi_imx_dt_node_to_map(struct pinctrl_dev *pctldev, pin_id = mux_reg / 4; - cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, mux_val); + cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_MUX, (mux_val & 0xFF)); + + if (mux_val & 0xFF00) { + int ext_val = (mux_val & 0xFF00) >> 8; + + cfg[j++] = pinconf_to_config_packed(IMX_SCMI_PIN_EXT, ext_val); + } else + ncfg--; if (!conf_reg || (conf_val & IMX_SCMI_NO_PAD_CTL)) ncfg--; @@ -291,8 +301,9 @@ scmi_pinctrl_imx_get_pins(struct scmi_pinctrl_imx *pmx, struct pinctrl_desc *des } static const char * const scmi_pinctrl_imx_allowlist[] = { - "fsl,imx95", "fsl,imx94", + "fsl,imx95", + "fsl,imx952", NULL }; diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index 731c58ad43ee..9a45b376d36f 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c @@ -88,8 +88,7 @@ static int imx_dt_node_to_map(struct pinctrl_dev *pctldev, } } - new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), - GFP_KERNEL); + new_map = kmalloc_objs(struct pinctrl_map, map_num); if (!new_map) return -ENOMEM; diff --git a/drivers/pinctrl/freescale/pinctrl-imx1-core.c b/drivers/pinctrl/freescale/pinctrl-imx1-core.c index af1ccfc90bff..b36c8a1461b7 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx1-core.c +++ b/drivers/pinctrl/freescale/pinctrl-imx1-core.c @@ -244,8 +244,7 @@ static int imx1_dt_node_to_map(struct pinctrl_dev *pctldev, for (i = 0; i < grp->npins; i++) map_num++; - new_map = kmalloc_array(map_num, sizeof(struct pinctrl_map), - GFP_KERNEL); + new_map = kmalloc_objs(struct pinctrl_map, map_num); if (!new_map) return -ENOMEM; diff --git a/drivers/pinctrl/freescale/pinctrl-mxs.c b/drivers/pinctrl/freescale/pinctrl-mxs.c index edb242d30609..6280009be3fa 100644 --- a/drivers/pinctrl/freescale/pinctrl-mxs.c +++ b/drivers/pinctrl/freescale/pinctrl-mxs.c @@ -92,7 +92,7 @@ static int mxs_dt_node_to_map(struct pinctrl_dev *pctldev, if (!purecfg && config) new_num = 2; - new_map = kcalloc(new_num, sizeof(*new_map), GFP_KERNEL); + new_map = kzalloc_objs(*new_map, new_num); if (!new_map) return -ENOMEM; diff --git a/drivers/pinctrl/intel/Kconfig b/drivers/pinctrl/intel/Kconfig index 248c2e558ff3..04c3a5b581f3 100644 --- a/drivers/pinctrl/intel/Kconfig +++ b/drivers/pinctrl/intel/Kconfig @@ -45,6 +45,7 @@ config PINCTRL_INTEL_PLATFORM of Intel PCH pins and using them as GPIOs. Currently the following Intel SoCs / platforms require this to be functional: - Lunar Lake + - Nova Lake - Panther Lake config PINCTRL_ALDERLAKE @@ -52,7 +53,10 @@ config PINCTRL_ALDERLAKE select PINCTRL_INTEL help This pinctrl driver provides an interface that allows configuring - of Intel Alder Lake PCH pins and using them as GPIOs. + PCH pins of the following platforms and using them as GPIOs: + - Alder Lake HX, N, and S + - Raptor Lake HX, E, and S + - Twin Lake config PINCTRL_BROXTON tristate "Intel Broxton pinctrl and GPIO driver" @@ -136,15 +140,17 @@ config PINCTRL_METEORLAKE select PINCTRL_INTEL help This pinctrl driver provides an interface that allows configuring - of Intel Meteor Lake pins and using them as GPIOs. + SoC pins of the following platforms and using them as GPIOs: + - Arrow Lake (all variants) + - Meteor Lake (all variants) config PINCTRL_METEORPOINT tristate "Intel Meteor Point pinctrl and GPIO driver" select PINCTRL_INTEL help - Meteor Point is the PCH of Intel Meteor Lake. This pinctrl driver - provides an interface that allows configuring of PCH pins and - using them as GPIOs. + This pinctrl driver provides an interface that allows configuring + PCH pins of the following platforms and using them as GPIOs: + - Arrow Lake HX and S config PINCTRL_SUNRISEPOINT tristate "Intel Sunrisepoint pinctrl and GPIO driver" @@ -159,7 +165,11 @@ config PINCTRL_TIGERLAKE select PINCTRL_INTEL help This pinctrl driver provides an interface that allows configuring - of Intel Tiger Lake PCH pins and using them as GPIOs. + PCH pins of the following platforms and using them as GPIOs: + - Alder Lake H, P, PS, and U + - Raptor Lake H, P, PS, PX, and U + - Rocket Lake S + - Tiger Lake (all variants) source "drivers/pinctrl/intel/Kconfig.tng" endmenu diff --git a/drivers/pinctrl/intel/pinctrl-alderlake.c b/drivers/pinctrl/intel/pinctrl-alderlake.c index 7bf1d5c285a0..dcb541976f2f 100644 --- a/drivers/pinctrl/intel/pinctrl-alderlake.c +++ b/drivers/pinctrl/intel/pinctrl-alderlake.c @@ -2,7 +2,7 @@ /* * Intel Alder Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2020, 2022 Intel Corporation + * Copyright (C) 2020-2022 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index b3a5222a175f..b733ec31ad9d 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -2,7 +2,7 @@ /* * Pinctrl GPIO driver for Intel Baytrail * - * Copyright (c) 2012-2013, Intel Corporation + * Copyright (C) 2012-2013 Intel Corporation * Author: Mathias Nyman */ @@ -101,10 +101,12 @@ struct intel_pad_context { u32 val; }; -#define COMMUNITY(p, n, map) \ +#define BYT_COMMUNITY(p, n, g, map) \ { \ .pin_base = (p), \ .npins = (n), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ .pad_map = (map),\ } @@ -360,8 +362,15 @@ static const struct intel_function byt_score_functions[] = { FUNCTION("gpio", byt_score_gpio_groups), }; +static const struct intel_padgroup byt_score_gpps[] = { + INTEL_GPP(0, 0, 31, 0), + INTEL_GPP(1, 32, 63, 32), + INTEL_GPP(2, 64, 95, 64), + INTEL_GPP(3, 96, 101, 96), +}; + static const struct intel_community byt_score_communities[] = { - COMMUNITY(0, BYT_NGPIO_SCORE, byt_score_pins_map), + BYT_COMMUNITY(0, 102, byt_score_gpps, byt_score_pins_map), }; static const struct intel_pinctrl_soc_data byt_score_soc_data = { @@ -483,8 +492,13 @@ static const struct intel_function byt_sus_functions[] = { FUNCTION("pmu_clk", byt_sus_pmu_clk_groups), }; +static const struct intel_padgroup byt_sus_gpps[] = { + INTEL_GPP(0, 0, 31, 0), + INTEL_GPP(1, 32, 43, 32), +}; + static const struct intel_community byt_sus_communities[] = { - COMMUNITY(0, BYT_NGPIO_SUS, byt_sus_pins_map), + BYT_COMMUNITY(0, 44, byt_sus_gpps, byt_sus_pins_map), }; static const struct intel_pinctrl_soc_data byt_sus_soc_data = { @@ -536,8 +550,12 @@ static const unsigned int byt_ncore_pins_map[BYT_NGPIO_NCORE] = { 3, 6, 10, 13, 2, 5, 9, 7, }; +static const struct intel_padgroup byt_ncore_gpps[] = { + INTEL_GPP(0, 0, 27, 0), +}; + static const struct intel_community byt_ncore_communities[] = { - COMMUNITY(0, BYT_NGPIO_NCORE, byt_ncore_pins_map), + BYT_COMMUNITY(0, 28, byt_ncore_gpps, byt_ncore_pins_map), }; static const struct intel_pinctrl_soc_data byt_ncore_soc_data = { @@ -1490,19 +1508,6 @@ static int byt_gpio_irq_init_hw(struct gpio_chip *chip) return 0; } -static int byt_gpio_add_pin_ranges(struct gpio_chip *chip) -{ - struct intel_pinctrl *vg = gpiochip_get_data(chip); - struct device *dev = vg->dev; - int ret; - - ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, vg->soc->npins); - if (ret) - return dev_err_probe(dev, ret, "failed to add GPIO pin range\n"); - - return 0; -} - static int byt_gpio_probe(struct intel_pinctrl *vg) { struct platform_device *pdev = to_platform_device(vg->dev); @@ -1515,7 +1520,7 @@ static int byt_gpio_probe(struct intel_pinctrl *vg) gc->label = dev_name(vg->dev); gc->base = -1; gc->can_sleep = false; - gc->add_pin_ranges = byt_gpio_add_pin_ranges; + gc->add_pin_ranges = intel_gpio_add_pin_ranges; gc->parent = vg->dev; gc->ngpio = vg->soc->npins; @@ -1611,7 +1616,7 @@ static int byt_pinctrl_probe(struct platform_device *pdev) vg->pctldev = devm_pinctrl_register(dev, &vg->pctldesc, vg); if (IS_ERR(vg->pctldev)) - return dev_err_probe(dev, PTR_ERR(vg->pctldev), "failed to register pinctrl\n"); + return PTR_ERR(vg->pctldev); ret = byt_gpio_probe(vg); if (ret) diff --git a/drivers/pinctrl/intel/pinctrl-broxton.c b/drivers/pinctrl/intel/pinctrl-broxton.c index 140b29956340..3d3c1706928a 100644 --- a/drivers/pinctrl/intel/pinctrl-broxton.c +++ b/drivers/pinctrl/intel/pinctrl-broxton.c @@ -2,7 +2,7 @@ /* * Intel Broxton SoC pinctrl/GPIO driver * - * Copyright (C) 2015, 2016 Intel Corporation + * Copyright (C) 2015-2016 Intel Corporation * Author: Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-cannonlake.c b/drivers/pinctrl/intel/pinctrl-cannonlake.c index a3ffd19fd5be..baa7c9a62ff9 100644 --- a/drivers/pinctrl/intel/pinctrl-cannonlake.c +++ b/drivers/pinctrl/intel/pinctrl-cannonlake.c @@ -2,7 +2,7 @@ /* * Intel Cannon Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2017, Intel Corporation + * Copyright (C) 2017 Intel Corporation * Authors: Andy Shevchenko * Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-cedarfork.c b/drivers/pinctrl/intel/pinctrl-cedarfork.c index 2916f7d90090..578e1ee57acf 100644 --- a/drivers/pinctrl/intel/pinctrl-cedarfork.c +++ b/drivers/pinctrl/intel/pinctrl-cedarfork.c @@ -2,7 +2,7 @@ /* * Intel Cedar Fork PCH pinctrl/GPIO driver * - * Copyright (C) 2017, Intel Corporation + * Copyright (C) 2017 Intel Corporation * Author: Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 8bd0c8512f78..a33eca5eafc4 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -2,7 +2,7 @@ /* * Cherryview/Braswell pinctrl driver * - * Copyright (C) 2014, 2020 Intel Corporation + * Copyright (C) 2014-2020 Intel Corporation * Author: Mika Westerberg * * This driver is based on the original Cherryview GPIO driver by @@ -1644,7 +1644,7 @@ static int chv_pinctrl_probe(struct platform_device *pdev) pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); if (IS_ERR(pctrl->pctldev)) - return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n"); + return PTR_ERR(pctrl->pctldev); ret = chv_gpio_probe(pctrl, irq); if (ret) diff --git a/drivers/pinctrl/intel/pinctrl-denverton.c b/drivers/pinctrl/intel/pinctrl-denverton.c index f492f73ba246..4a1d346fb30c 100644 --- a/drivers/pinctrl/intel/pinctrl-denverton.c +++ b/drivers/pinctrl/intel/pinctrl-denverton.c @@ -2,7 +2,7 @@ /* * Intel Denverton SoC pinctrl/GPIO driver * - * Copyright (C) 2017, Intel Corporation + * Copyright (C) 2017 Intel Corporation * Author: Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-elkhartlake.c b/drivers/pinctrl/intel/pinctrl-elkhartlake.c index 0e8742f31cd4..8a24ef12141d 100644 --- a/drivers/pinctrl/intel/pinctrl-elkhartlake.c +++ b/drivers/pinctrl/intel/pinctrl-elkhartlake.c @@ -2,7 +2,7 @@ /* * Intel Elkhart Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2019, Intel Corporation + * Copyright (C) 2019 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-emmitsburg.c b/drivers/pinctrl/intel/pinctrl-emmitsburg.c index ba06a9ec239a..3b63b6dd2560 100644 --- a/drivers/pinctrl/intel/pinctrl-emmitsburg.c +++ b/drivers/pinctrl/intel/pinctrl-emmitsburg.c @@ -2,7 +2,7 @@ /* * Intel Emmitsburg PCH pinctrl/GPIO driver * - * Copyright (C) 2020, Intel Corporation + * Copyright (C) 2020 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-icelake.c b/drivers/pinctrl/intel/pinctrl-icelake.c index 1516fe7b4e4a..daabc5288cbb 100644 --- a/drivers/pinctrl/intel/pinctrl-icelake.c +++ b/drivers/pinctrl/intel/pinctrl-icelake.c @@ -2,7 +2,7 @@ /* * Intel Ice Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2018, 2022 Intel Corporation + * Copyright (C) 2018-2022 Intel Corporation * Authors: Andy Shevchenko * Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-intel-platform.c b/drivers/pinctrl/intel/pinctrl-intel-platform.c index dd5dbede0f59..61dd579e3f97 100644 --- a/drivers/pinctrl/intel/pinctrl-intel-platform.c +++ b/drivers/pinctrl/intel/pinctrl-intel-platform.c @@ -2,7 +2,7 @@ /* * Intel PCH pinctrl/GPIO driver * - * Copyright (C) 2021-2023, Intel Corporation + * Copyright (C) 2021-2023 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index cf9db8ac0f42..9d32bb8bc13a 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -2,7 +2,7 @@ /* * Intel pinctrl/GPIO core driver. * - * Copyright (C) 2015, Intel Corporation + * Copyright (C) 2015 Intel Corporation * Authors: Mathias Nyman * Mika Westerberg */ @@ -1673,7 +1673,7 @@ int intel_pinctrl_probe(struct platform_device *pdev, pctrl->pctldev = devm_pinctrl_register(dev, &pctrl->pctldesc, pctrl); if (IS_ERR(pctrl->pctldev)) - return dev_err_probe(dev, PTR_ERR(pctrl->pctldev), "failed to register pinctrl\n"); + return PTR_ERR(pctrl->pctldev); ret = intel_gpio_probe(pctrl, irq); if (ret) diff --git a/drivers/pinctrl/intel/pinctrl-intel.h b/drivers/pinctrl/intel/pinctrl-intel.h index c1520797f895..2f37109d5860 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.h +++ b/drivers/pinctrl/intel/pinctrl-intel.h @@ -2,7 +2,7 @@ /* * Core pinctrl/GPIO driver for Intel GPIO controllers * - * Copyright (C) 2015, Intel Corporation + * Copyright (C) 2015 Intel Corporation * Authors: Mathias Nyman * Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-jasperlake.c b/drivers/pinctrl/intel/pinctrl-jasperlake.c index c6e1836c69a7..a8f65c3dbb1c 100644 --- a/drivers/pinctrl/intel/pinctrl-jasperlake.c +++ b/drivers/pinctrl/intel/pinctrl-jasperlake.c @@ -2,7 +2,7 @@ /* * Intel Jasper Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2020, Intel Corporation + * Copyright (C) 2020 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-lakefield.c b/drivers/pinctrl/intel/pinctrl-lakefield.c index bfb8b565d15c..39872c352ac2 100644 --- a/drivers/pinctrl/intel/pinctrl-lakefield.c +++ b/drivers/pinctrl/intel/pinctrl-lakefield.c @@ -2,7 +2,7 @@ /* * Intel Lakefield PCH pinctrl/GPIO driver * - * Copyright (C) 2020, Intel Corporation + * Copyright (C) 2020 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-lewisburg.c b/drivers/pinctrl/intel/pinctrl-lewisburg.c index 9fe651370f32..ebbc94047b6f 100644 --- a/drivers/pinctrl/intel/pinctrl-lewisburg.c +++ b/drivers/pinctrl/intel/pinctrl-lewisburg.c @@ -2,7 +2,7 @@ /* * Intel Lewisburg pinctrl/GPIO driver * - * Copyright (C) 2017, Intel Corporation + * Copyright (C) 2017 Intel Corporation * Author: Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-lynxpoint.c b/drivers/pinctrl/intel/pinctrl-lynxpoint.c index 1565eefdd4bf..299ee4f22bdc 100644 --- a/drivers/pinctrl/intel/pinctrl-lynxpoint.c +++ b/drivers/pinctrl/intel/pinctrl-lynxpoint.c @@ -2,7 +2,7 @@ /* * Intel Lynxpoint PCH pinctrl/GPIO driver * - * Copyright (c) 2012, 2019, Intel Corporation + * Copyright (C) 2012-2019 Intel Corporation * Authors: Mathias Nyman * Andy Shevchenko */ @@ -29,10 +29,12 @@ #include "pinctrl-intel.h" -#define COMMUNITY(p, n) \ +#define LPTLP_COMMUNITY(p, n, g) \ { \ .pin_base = (p), \ .npins = (n), \ + .gpps = (g), \ + .ngpps = ARRAY_SIZE(g), \ } static const struct pinctrl_pin_desc lptlp_pins[] = { @@ -133,8 +135,14 @@ static const struct pinctrl_pin_desc lptlp_pins[] = { PINCTRL_PIN(94, "GP94_UART0_CTSB"), }; +static const struct intel_padgroup lptlp_gpps[] = { + INTEL_GPP(0, 0, 31, 0), + INTEL_GPP(1, 32, 63, 32), + INTEL_GPP(2, 64, 94, 64), +}; + static const struct intel_community lptlp_communities[] = { - COMMUNITY(0, 95), + LPTLP_COMMUNITY(0, 95, lptlp_gpps), }; static const struct intel_pinctrl_soc_data lptlp_soc_data = { @@ -692,19 +700,6 @@ static int lp_gpio_irq_init_hw(struct gpio_chip *chip) return 0; } -static int lp_gpio_add_pin_ranges(struct gpio_chip *chip) -{ - struct intel_pinctrl *lg = gpiochip_get_data(chip); - struct device *dev = lg->dev; - int ret; - - ret = gpiochip_add_pin_range(chip, dev_name(dev), 0, 0, lg->soc->npins); - if (ret) - return dev_err_probe(dev, ret, "failed to add GPIO pin range\n"); - - return 0; -} - static int lp_gpio_probe(struct platform_device *pdev) { const struct intel_pinctrl_soc_data *soc; @@ -740,7 +735,7 @@ static int lp_gpio_probe(struct platform_device *pdev) lg->pctldev = devm_pinctrl_register(dev, &lg->pctldesc, lg); if (IS_ERR(lg->pctldev)) - return dev_err_probe(dev, PTR_ERR(lg->pctldev), "failed to register pinctrl\n"); + return PTR_ERR(lg->pctldev); platform_set_drvdata(pdev, lg); @@ -777,7 +772,7 @@ static int lp_gpio_probe(struct platform_device *pdev) gc->base = -1; gc->ngpio = LP_NUM_GPIO; gc->can_sleep = false; - gc->add_pin_ranges = lp_gpio_add_pin_ranges; + gc->add_pin_ranges = intel_gpio_add_pin_ranges; gc->parent = dev; /* set up interrupts */ diff --git a/drivers/pinctrl/intel/pinctrl-merrifield.c b/drivers/pinctrl/intel/pinctrl-merrifield.c index 2f4d73dda41d..83b4d1862545 100644 --- a/drivers/pinctrl/intel/pinctrl-merrifield.c +++ b/drivers/pinctrl/intel/pinctrl-merrifield.c @@ -2,7 +2,7 @@ /* * Intel Merrifield SoC pinctrl driver * - * Copyright (C) 2016, Intel Corporation + * Copyright (C) 2016 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-meteorlake.c b/drivers/pinctrl/intel/pinctrl-meteorlake.c index b7395947569a..3f5070a339bf 100644 --- a/drivers/pinctrl/intel/pinctrl-meteorlake.c +++ b/drivers/pinctrl/intel/pinctrl-meteorlake.c @@ -2,7 +2,7 @@ /* * Intel Meteor Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2022, Intel Corporation + * Copyright (C) 2022 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-meteorpoint.c b/drivers/pinctrl/intel/pinctrl-meteorpoint.c index b7858c2b2c5c..bff7be1f137d 100644 --- a/drivers/pinctrl/intel/pinctrl-meteorpoint.c +++ b/drivers/pinctrl/intel/pinctrl-meteorpoint.c @@ -2,7 +2,7 @@ /* * Intel Meteor Point PCH pinctrl/GPIO driver * - * Copyright (C) 2022-2023, Intel Corporation + * Copyright (C) 2022-2023 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-moorefield.c b/drivers/pinctrl/intel/pinctrl-moorefield.c index 6a79207e6b2a..30f9a4481827 100644 --- a/drivers/pinctrl/intel/pinctrl-moorefield.c +++ b/drivers/pinctrl/intel/pinctrl-moorefield.c @@ -2,7 +2,7 @@ /* * Intel Moorefield SoC pinctrl driver * - * Copyright (C) 2022, Intel Corporation + * Copyright (C) 2022 Intel Corporation * Author: Andy Shevchenko */ diff --git a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c index b51befde9e8b..308651091d9c 100644 --- a/drivers/pinctrl/intel/pinctrl-sunrisepoint.c +++ b/drivers/pinctrl/intel/pinctrl-sunrisepoint.c @@ -2,7 +2,7 @@ /* * Intel Sunrisepoint PCH pinctrl/GPIO driver * - * Copyright (C) 2015, Intel Corporation + * Copyright (C) 2015 Intel Corporation * Authors: Mathias Nyman * Mika Westerberg */ diff --git a/drivers/pinctrl/intel/pinctrl-tangier.c b/drivers/pinctrl/intel/pinctrl-tangier.c index 5f0b7334a489..5fc13d369dd8 100644 --- a/drivers/pinctrl/intel/pinctrl-tangier.c +++ b/drivers/pinctrl/intel/pinctrl-tangier.c @@ -2,7 +2,7 @@ /* * Intel Tangier pinctrl driver * - * Copyright (C) 2016, 2023 Intel Corporation + * Copyright (C) 2016-2023 Intel Corporation * * Authors: Andy Shevchenko * Raag Jadav @@ -518,15 +518,19 @@ static const struct pinctrl_desc tng_pinctrl_desc = { .owner = THIS_MODULE, }; -static int tng_pinctrl_probe(struct platform_device *pdev, - const struct tng_pinctrl *data) +int devm_tng_pinctrl_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; + const struct tng_pinctrl *data; struct tng_family *families; struct tng_pinctrl *tp; void __iomem *regs; unsigned int i; + data = device_get_match_data(dev); + if (!data) + return -ENODATA; + tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL); if (!tp) return -ENOMEM; @@ -562,21 +566,10 @@ static int tng_pinctrl_probe(struct platform_device *pdev, tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp); if (IS_ERR(tp->pctldev)) - return dev_err_probe(dev, PTR_ERR(tp->pctldev), "failed to register pinctrl\n"); + return PTR_ERR(tp->pctldev); return 0; } - -int devm_tng_pinctrl_probe(struct platform_device *pdev) -{ - const struct tng_pinctrl *data; - - data = device_get_match_data(&pdev->dev); - if (!data) - return -ENODATA; - - return tng_pinctrl_probe(pdev, data); -} EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, "PINCTRL_TANGIER"); MODULE_AUTHOR("Andy Shevchenko "); diff --git a/drivers/pinctrl/intel/pinctrl-tangier.h b/drivers/pinctrl/intel/pinctrl-tangier.h index 955cc967c0bc..6af8eeeae943 100644 --- a/drivers/pinctrl/intel/pinctrl-tangier.h +++ b/drivers/pinctrl/intel/pinctrl-tangier.h @@ -2,7 +2,7 @@ /* * Intel Tangier pinctrl functions * - * Copyright (C) 2016, 2023 Intel Corporation + * Copyright (C) 2016-2023 Intel Corporation * * Authors: Andy Shevchenko * Raag Jadav diff --git a/drivers/pinctrl/intel/pinctrl-tigerlake.c b/drivers/pinctrl/intel/pinctrl-tigerlake.c index c0887596d113..ae231f7fba49 100644 --- a/drivers/pinctrl/intel/pinctrl-tigerlake.c +++ b/drivers/pinctrl/intel/pinctrl-tigerlake.c @@ -2,7 +2,7 @@ /* * Intel Tiger Lake PCH pinctrl/GPIO driver * - * Copyright (C) 2019 - 2020, Intel Corporation + * Copyright (C) 2019-2020 Intel Corporation * Authors: Andy Shevchenko * Mika Westerberg */ diff --git a/drivers/pinctrl/mediatek/mtk-eint.c b/drivers/pinctrl/mediatek/mtk-eint.c index c8c5097c11c4..2a3c04eedc5f 100644 --- a/drivers/pinctrl/mediatek/mtk-eint.c +++ b/drivers/pinctrl/mediatek/mtk-eint.c @@ -544,24 +544,32 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin) } } - eint->pin_list = devm_kmalloc(eint->dev, eint->nbase * sizeof(u16 *), GFP_KERNEL); + eint->pin_list = devm_kcalloc(eint->dev, eint->nbase, + sizeof(*eint->pin_list), GFP_KERNEL); if (!eint->pin_list) goto err_pin_list; - eint->wake_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL); + eint->wake_mask = devm_kcalloc(eint->dev, eint->nbase, + sizeof(*eint->wake_mask), GFP_KERNEL); if (!eint->wake_mask) goto err_wake_mask; - eint->cur_mask = devm_kmalloc(eint->dev, eint->nbase * sizeof(u32 *), GFP_KERNEL); + eint->cur_mask = devm_kcalloc(eint->dev, eint->nbase, + sizeof(*eint->cur_mask), GFP_KERNEL); if (!eint->cur_mask) goto err_cur_mask; for (i = 0; i < eint->nbase; i++) { - eint->pin_list[i] = devm_kzalloc(eint->dev, eint->base_pin_num[i] * sizeof(u16), + eint->pin_list[i] = devm_kzalloc(eint->dev, + eint->base_pin_num[i] * sizeof(**eint->pin_list), GFP_KERNEL); port = DIV_ROUND_UP(eint->base_pin_num[i], 32); - eint->wake_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL); - eint->cur_mask[i] = devm_kzalloc(eint->dev, port * sizeof(u32), GFP_KERNEL); + eint->wake_mask[i] = devm_kzalloc(eint->dev, + port * sizeof(**eint->wake_mask), + GFP_KERNEL); + eint->cur_mask[i] = devm_kzalloc(eint->dev, + port * sizeof(**eint->cur_mask), + GFP_KERNEL); if (!eint->pin_list[i] || !eint->wake_mask[i] || !eint->cur_mask[i]) goto err_eint; } @@ -597,12 +605,9 @@ int mtk_eint_do_init(struct mtk_eint *eint, struct mtk_eint_pin *eint_pin) err_eint: for (i = 0; i < eint->nbase; i++) { - if (eint->cur_mask[i]) - devm_kfree(eint->dev, eint->cur_mask[i]); - if (eint->wake_mask[i]) - devm_kfree(eint->dev, eint->wake_mask[i]); - if (eint->pin_list[i]) - devm_kfree(eint->dev, eint->pin_list[i]); + devm_kfree(eint->dev, eint->cur_mask[i]); + devm_kfree(eint->dev, eint->wake_mask[i]); + devm_kfree(eint->dev, eint->pin_list[i]); } devm_kfree(eint->dev, eint->cur_mask); err_cur_mask: diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7981.c b/drivers/pinctrl/mediatek/pinctrl-mt7981.c index 6216c2e057f6..22c8f2480346 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7981.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7981.c @@ -1019,7 +1019,7 @@ static struct mtk_pin_soc mt7981_data = { .nfuncs = ARRAY_SIZE(mt7981_functions), .eint_hw = &mt7981_eint_hw, .gpio_m = 0, - .ies_present = false, + .ies_present = true, .base_names = mt7981_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7981_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7986.c b/drivers/pinctrl/mediatek/pinctrl-mt7986.c index 2a762ade9c35..5dda4b7467fd 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7986.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7986.c @@ -919,7 +919,7 @@ static struct mtk_pin_soc mt7986a_data = { .nfuncs = ARRAY_SIZE(mt7986_functions), .eint_hw = &mt7986a_eint_hw, .gpio_m = 0, - .ies_present = false, + .ies_present = true, .base_names = mt7986_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, @@ -945,7 +945,7 @@ static struct mtk_pin_soc mt7986b_data = { .nfuncs = ARRAY_SIZE(mt7986_functions), .eint_hw = &mt7986b_eint_hw, .gpio_m = 0, - .ies_present = false, + .ies_present = true, .base_names = mt7986_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7986_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7988.c b/drivers/pinctrl/mediatek/pinctrl-mt7988.c index 9569e8c0cec1..fd3a7ff0a04d 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt7988.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt7988.c @@ -1505,7 +1505,7 @@ static const struct mtk_pin_soc mt7988_data = { .nfuncs = ARRAY_SIZE(mt7988_functions), .eint_hw = &mt7988_eint_hw, .gpio_m = 0, - .ies_present = false, + .ies_present = true, .base_names = mt7988_pinctrl_register_base_names, .nbase_names = ARRAY_SIZE(mt7988_pinctrl_register_base_names), .bias_disable_set = mtk_pinconf_bias_disable_set, diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8365.c b/drivers/pinctrl/mediatek/pinctrl-mt8365.c index e3e0d66cfbbf..c20b9e2e02dd 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mt8365.c +++ b/drivers/pinctrl/mediatek/pinctrl-mt8365.c @@ -456,7 +456,6 @@ static const struct mtk_pinctrl_devdata mt8365_pinctrl_data = { .smt_offset = 0x0470, .pullen_offset = 0x0860, .pullsel_offset = 0x0900, - .drv_offset = 0x0710, .type1_start = 145, .type1_end = 145, .port_shf = 4, diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h index 11afa12a96cb..3b96f3dd338d 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h @@ -263,7 +263,6 @@ struct mtk_pinctrl_devdata { unsigned int smt_offset; unsigned int pullen_offset; unsigned int pullsel_offset; - unsigned int drv_offset; unsigned int dout_offset; unsigned int din_offset; unsigned int pinmux_offset; diff --git a/drivers/pinctrl/meson/Kconfig b/drivers/pinctrl/meson/Kconfig index 0315e224bce6..ce6aeec2fc79 100644 --- a/drivers/pinctrl/meson/Kconfig +++ b/drivers/pinctrl/meson/Kconfig @@ -15,25 +15,25 @@ if PINCTRL_MESON config PINCTRL_MESON8 bool "Meson 8 SoC pinctrl driver" - depends on ARM + depends on ARM || COMPILE_TEST select PINCTRL_MESON8_PMX default ARCH_MESON config PINCTRL_MESON8B bool "Meson 8b SoC pinctrl driver" - depends on ARM + depends on ARM || COMPILE_TEST select PINCTRL_MESON8_PMX default ARCH_MESON config PINCTRL_MESON_GXBB tristate "Meson gxbb SoC pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON8_PMX default ARCH_MESON config PINCTRL_MESON_GXL tristate "Meson gxl SoC pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON8_PMX default ARCH_MESON @@ -42,7 +42,7 @@ config PINCTRL_MESON8_PMX config PINCTRL_MESON_AXG tristate "Meson axg Soc pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON @@ -51,25 +51,25 @@ config PINCTRL_MESON_AXG_PMX config PINCTRL_MESON_G12A tristate "Meson g12a Soc pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON config PINCTRL_MESON_A1 tristate "Meson a1 Soc pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON config PINCTRL_MESON_S4 tristate "Meson s4 Soc pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON config PINCTRL_AMLOGIC_A4 bool "AMLOGIC pincontrol" - depends on ARM64 + depends on ARM64 || COMPILE_TEST default ARCH_MESON help This is the driver for the pin controller found on Amlogic SoCs. @@ -80,13 +80,13 @@ config PINCTRL_AMLOGIC_A4 config PINCTRL_AMLOGIC_C3 tristate "Amlogic C3 SoC pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON config PINCTRL_AMLOGIC_T7 tristate "Amlogic T7 SoC pinctrl driver" - depends on ARM64 + depends on ARM64 || COMPILE_TEST select PINCTRL_MESON_AXG_PMX default ARCH_MESON diff --git a/drivers/pinctrl/meson/pinctrl-amlogic-a4.c b/drivers/pinctrl/meson/pinctrl-amlogic-a4.c index d9e3a8d5932a..e2293a872dcb 100644 --- a/drivers/pinctrl/meson/pinctrl-amlogic-a4.c +++ b/drivers/pinctrl/meson/pinctrl-amlogic-a4.c @@ -24,6 +24,7 @@ #include #include "../core.h" +#include "../pinctrl-utils.h" #include "../pinconf.h" #define gpio_chip_to_bank(chip) \ @@ -672,11 +673,78 @@ static void aml_pin_dbg_show(struct pinctrl_dev *pcdev, struct seq_file *s, seq_printf(s, " %s", dev_name(pcdev->dev)); } +static int aml_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, + unsigned int *num_maps) +{ + struct device *dev = pctldev->dev; + unsigned long *configs = NULL; + unsigned int num_configs = 0; + struct property *prop; + unsigned int reserved_maps; + int reserve; + int ret; + + prop = of_find_property(np, "pinmux", NULL); + if (!prop) { + dev_info(dev, "Missing pinmux property\n"); + return -ENOENT; + } + + struct device_node *pnode __free(device_node) = of_get_parent(np); + if (!pnode) { + dev_info(dev, "Missing function node\n"); + return -EINVAL; + } + + reserved_maps = 0; + *map = NULL; + *num_maps = 0; + + ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, + &num_configs); + if (ret < 0) { + dev_err(dev, "%pOF: could not parse node property\n", np); + return ret; + } + + reserve = 1; + if (num_configs) + reserve++; + + ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, + num_maps, reserve); + if (ret < 0) + goto exit; + + ret = pinctrl_utils_add_map_mux(pctldev, map, + &reserved_maps, num_maps, np->name, + pnode->name); + if (ret < 0) + goto exit; + + if (num_configs) { + ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps, + num_maps, np->name, configs, + num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); + if (ret < 0) + goto exit; + } + +exit: + kfree(configs); + if (ret) + pinctrl_utils_free_map(pctldev, *map, *num_maps); + + return ret; +} + static const struct pinctrl_ops aml_pctrl_ops = { .get_groups_count = aml_get_groups_count, .get_group_name = aml_get_group_name, .get_group_pins = aml_get_group_pins, - .dt_node_to_map = pinconf_generic_dt_node_to_map_pinmux, + .dt_node_to_map = aml_dt_node_to_map_pinmux, .dt_free_map = pinconf_generic_dt_free_map, .pin_dbg_show = aml_pin_dbg_show, }; @@ -725,8 +793,9 @@ static u32 aml_bank_pins(struct device_node *np) if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &of_args)) return 0; - else - return of_args.args[2]; + + of_node_put(of_args.np); + return of_args.args[2]; } static int aml_bank_number(struct device_node *np) @@ -736,8 +805,9 @@ static int aml_bank_number(struct device_node *np) if (of_parse_phandle_with_fixed_args(np, "gpio-ranges", 3, 0, &of_args)) return -EINVAL; - else - return of_args.args[1] >> 8; + + of_node_put(of_args.np); + return of_args.args[1] >> 8; } static unsigned int aml_count_pins(struct device_node *np) @@ -893,7 +963,7 @@ static const struct gpio_chip aml_gpio_template = { .direction_input = aml_gpio_direction_input, .direction_output = aml_gpio_direction_output, .get_direction = aml_gpio_get_direction, - .can_sleep = false, + .can_sleep = true, }; static void init_bank_register_bit(struct aml_pinctrl *info, diff --git a/drivers/pinctrl/microchip/Kconfig b/drivers/pinctrl/microchip/Kconfig new file mode 100644 index 000000000000..aba55f686f45 --- /dev/null +++ b/drivers/pinctrl/microchip/Kconfig @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config PINCTRL_PIC64GX + bool "pic64gx gpio2 pinctrl driver" + depends on ARCH_MICROCHIP || COMPILE_TEST + depends on OF + select GENERIC_PINCONF + select REGMAP_MMIO + help + This selects the pinctrl driver for gpio2 on pic64gx. + +config PINCTRL_POLARFIRE_SOC + bool "Polarfire SoC pinctrl drivers" + depends on ARCH_MICROCHIP || COMPILE_TEST + depends on OF + select GENERIC_PINCTRL + help + This selects the pinctrl drivers for Microchip Polarfire SoC. diff --git a/drivers/pinctrl/microchip/Makefile b/drivers/pinctrl/microchip/Makefile new file mode 100644 index 000000000000..ab0575cd2ed1 --- /dev/null +++ b/drivers/pinctrl/microchip/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_PINCTRL_PIC64GX) += pinctrl-pic64gx-gpio2.o +obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-iomux0.o +obj-$(CONFIG_PINCTRL_POLARFIRE_SOC) += pinctrl-mpfs-mssio.o diff --git a/drivers/pinctrl/pinctrl-mpfs-iomux0.c b/drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c similarity index 98% rename from drivers/pinctrl/pinctrl-mpfs-iomux0.c rename to drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c index cf5b2e4e8f5b..1b060a038920 100644 --- a/drivers/pinctrl/pinctrl-mpfs-iomux0.c +++ b/drivers/pinctrl/microchip/pinctrl-mpfs-iomux0.c @@ -15,10 +15,10 @@ #include #include -#include "core.h" -#include "pinctrl-utils.h" -#include "pinconf.h" -#include "pinmux.h" +#include "../core.h" +#include "../pinctrl-utils.h" +#include "../pinconf.h" +#include "../pinmux.h" #define MPFS_IOMUX0_REG 0x200 diff --git a/drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c b/drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c new file mode 100644 index 000000000000..3d5ffd6cb14b --- /dev/null +++ b/drivers/pinctrl/microchip/pinctrl-mpfs-mssio.c @@ -0,0 +1,737 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "../core.h" +#include "../pinctrl-utils.h" +#include "../pinconf.h" +#include "../pinmux.h" + +#define MPFS_PINCTRL_PAD_MUX_MASK GENMASK(3, 0) + +#define MPFS_PINCTRL_IOCFG_MASK GENMASK(14, 0) +#define MPFS_PINCTRL_IBUFMD_MASK GENMASK(2, 0) +#define MPFS_PINCTRL_DRV_MASK GENMASK(6, 3) +#define MPFS_PINCTRL_CLAMP BIT(7) +#define MPFS_PINCTRL_ENHYST BIT(8) +#define MPFS_PINCTRL_LOCKDN BIT(9) +#define MPFS_PINCTRL_WPD BIT(10) +#define MPFS_PINCTRL_WPU BIT(11) +#define MPFS_PINCTRL_PULL_MASK GENMASK(11, 10) +#define MPFS_PINCTRL_LP_PERSIST_EN BIT(12) +#define MPFS_PINCTRL_LP_BYPASS_EN BIT(13) + +#define MPFS_PINCTRL_MSSIO_BANK2_CFG_CR 0x1c4 +#define MPFS_PINCTRL_MSSIO_BANK4_CFG_CR 0x1c8 +#define MPFS_PINCTRL_BANK_VOLTAGE_MASK GENMASK(19, 16) + +#define MPFS_PINCTRL_IOCFG01_REG 0x234 + +#define MPFS_PINCTRL_INTER_BANK_GAP 0x4 + +#define MPFS_PINCTRL_BANK2_START 14 + +#define MPFS_PINCTRL_LOCKDOWN (PIN_CONFIG_END + 1) +#define MPFS_PINCTRL_CLAMP_DIODE (PIN_CONFIG_END + 2) +#define MPFS_PINCTRL_IBUFMD (PIN_CONFIG_END + 3) + +struct mpfs_pinctrl_mux_config { + u8 pin; + u8 function; +}; + +struct mpfs_pinctrl { + struct pinctrl_dev *pctrl; + struct device *dev; + struct regmap *regmap; + struct regmap *sysreg_regmap; + struct mutex mutex; + struct pinctrl_desc desc; +}; + +struct mpfs_pinctrl_drive_strength { + u8 ma; + u8 val; +}; + +struct mpfs_pinctrl_bank_voltage { + u32 uv; + u8 val; +}; + +static struct mpfs_pinctrl_drive_strength mpfs_pinctrl_drive_strengths[8] = { + { .ma = 2, .val = 2 }, + { .ma = 4, .val = 3 }, + { .ma = 6, .val = 4 }, + { .ma = 8, .val = 5 }, + { .ma = 10, .val = 6 }, + { .ma = 12, .val = 7 }, + { .ma = 16, .val = 10 }, + { .ma = 20, .val = 12 }, +}; +static struct mpfs_pinctrl_bank_voltage mpfs_pinctrl_bank_voltages[8] = { + { .uv = 1200000, .val = 0 }, + { .uv = 1500000, .val = 2 }, + { .uv = 1800000, .val = 4 }, + { .uv = 2500000, .val = 6 }, + { .uv = 3300000, .val = 8 }, + { .uv = 0, .val = 0x3f }, // pin unused +}; + +static int mpfs_pinctrl_get_drive_strength_ma(u32 drive_strength) +{ + size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths); + + for (int i = 0; i < num; i++) + if (drive_strength == mpfs_pinctrl_drive_strengths[i].val) + return mpfs_pinctrl_drive_strengths[i].ma; + + return -EINVAL; +} + +static int mpfs_pinctrl_get_drive_strength_val(u32 drive_strength_ma) +{ + size_t num = ARRAY_SIZE(mpfs_pinctrl_drive_strengths); + + if (!drive_strength_ma) + return -EINVAL; + + for (int i = 0; i < num; i++) + if (drive_strength_ma <= mpfs_pinctrl_drive_strengths[i].ma) + return mpfs_pinctrl_drive_strengths[i].val; + + return mpfs_pinctrl_drive_strengths[num - 1].val; +} + +static int mpfs_pinctrl_get_bank_voltage_uv(u32 bank_voltage) +{ + size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages); + + for (int i = 0; i < num; i++) + if (bank_voltage == mpfs_pinctrl_bank_voltages[i].val) + return mpfs_pinctrl_bank_voltages[i].uv; + + return -EINVAL; +} + +static int mpfs_pinctrl_get_bank_voltage_val(u32 bank_voltage_uv) +{ + size_t num = ARRAY_SIZE(mpfs_pinctrl_bank_voltages); + + for (int i = 0; i < num; i++) + if (bank_voltage_uv <= mpfs_pinctrl_bank_voltages[i].uv) + return mpfs_pinctrl_bank_voltages[i].val; + + return -EINVAL; +} + +static u32 mpfs_pinctrl_pin_to_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin) +{ + u32 bank_voltage, val; + + if (pin < MPFS_PINCTRL_BANK2_START) + regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR, &val); + else + regmap_read(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR, &val); + + bank_voltage = FIELD_GET(MPFS_PINCTRL_BANK_VOLTAGE_MASK, val); + + return mpfs_pinctrl_get_bank_voltage_uv(bank_voltage); +} + +static void mpfs_pinctrl_set_bank_voltage(struct mpfs_pinctrl *pctrl, unsigned int pin, + u32 bank_voltage) +{ + u32 val = FIELD_PREP(MPFS_PINCTRL_BANK_VOLTAGE_MASK, bank_voltage); + + if (pin < MPFS_PINCTRL_BANK2_START) + regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK4_CFG_CR, + MPFS_PINCTRL_BANK_VOLTAGE_MASK, val); + else + regmap_assign_bits(pctrl->sysreg_regmap, MPFS_PINCTRL_MSSIO_BANK2_CFG_CR, + MPFS_PINCTRL_BANK_VOLTAGE_MASK, val); +} + +static char *mpfs_pinctrl_function_names[] = { + "sd", + "emmc", + "qspi", + "spi", + "usb", + "uart", + "i2c", + "can", + "mdio", + "misc", + "reserved", + "gpio", + "fabric test", + "tied-low", + "tied-high", + "tristate" +}; + +static int mpfs_pinctrl_function_map(const char *function) +{ + size_t num = ARRAY_SIZE(mpfs_pinctrl_function_names); + + for (int i = 0; i < num; i++) + if (!strcmp(function, mpfs_pinctrl_function_names[i])) + return i; + + return -EINVAL; +} + +static const struct pinconf_generic_params mpfs_pinctrl_custom_bindings[] = { + { "microchip,clamp-diode", MPFS_PINCTRL_CLAMP_DIODE, 1 }, + { "microchip,ibufmd", MPFS_PINCTRL_IBUFMD, 0x0 }, +}; + +static int mpfs_pinctrl_pin_to_iomux_offset(unsigned int pin) +{ + int offset; + + switch (pin) { + case 0 ... 7: + offset = pin * 4; + break; + case 8 ... 13: + offset = (pin - 8) * 4; + break; + case 14 ... 21: + offset = (pin - 14) * 4; + break; + case 22 ... 29: + offset = (pin - 22) * 4; + break; + case 30 ... 37: + offset = (pin - 30) * 4; + break; + default: + offset = -EINVAL; + } + + return offset; +} + +static int mpfs_pinctrl_pin_to_iomux_reg(unsigned int pin) +{ + int reg; + + switch (pin) { + case 0 ... 7: + reg = 0x204; + break; + case 8 ... 13: + reg = 0x208; + break; + case 14 ... 21: + reg = 0x20c; + break; + case 22 ... 29: + reg = 0x210; + break; + case 30 ... 37: + reg = 0x214; + break; + default: + reg = -EINVAL; + } + + return reg; +} + +static int mpfs_pinctrl_pin_to_iocfg_reg(unsigned int pin) +{ + u32 reg = MPFS_PINCTRL_IOCFG01_REG; + + if (pin >= MPFS_PINCTRL_BANK2_START) + reg += MPFS_PINCTRL_INTER_BANK_GAP; + + // 2 pins per 32-bit register + reg += (pin / 2) * 0x4; + + return reg; +} + +static int mpfs_pinctrl_pin_to_iocfg_offset(unsigned int pin) +{ + return 16 * (pin % 2); +} + +static void mpfs_pinctrl_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq, + unsigned int pin) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 func; + int reg, offset; + + reg = mpfs_pinctrl_pin_to_iomux_reg(pin); + offset = mpfs_pinctrl_pin_to_iomux_offset(pin); + + seq_printf(seq, "reg: %x, offset: %u ", reg, offset); + seq_printf(seq, "pin: %u ", pin); + + if (reg < 0 || offset < 0) + return; + + regmap_read(pctrl->regmap, reg, &func); + func = (func >> offset) & MPFS_PINCTRL_PAD_MUX_MASK; + seq_printf(seq, "func: %s (%x)\n", mpfs_pinctrl_function_names[func], func); +} + +static const struct pinctrl_ops mpfs_pinctrl_ops = { + .get_groups_count = pinctrl_generic_get_group_count, + .get_group_name = pinctrl_generic_get_group_name, + .get_group_pins = pinctrl_generic_get_group_pins, + .pin_dbg_show = mpfs_pinctrl_dbg_show, + .dt_node_to_map = pinctrl_generic_pins_function_dt_node_to_map, + .dt_free_map = pinctrl_utils_free_map, +}; + +static int mpfs_pinctrl_set_pin_func(struct mpfs_pinctrl *pctrl, u8 pin, u8 function) +{ + struct device *dev = pctrl->dev; + int reg, offset; + u32 func, mask; + + reg = mpfs_pinctrl_pin_to_iomux_reg(pin); + offset = mpfs_pinctrl_pin_to_iomux_offset(pin); + + func = function << offset; + mask = MPFS_PINCTRL_PAD_MUX_MASK << offset; + + dev_dbg(dev, "Setting pin %u. reg: %x offset %u func %x\n", pin, reg, offset, func); + + if (reg < 0 || offset < 0) + return -EINVAL; + + regmap_update_bits(pctrl->regmap, reg, mask, func); + + return 0; +} + +static int mpfs_pinctrl_set_mux(struct pinctrl_dev *pctrl_dev, unsigned int fsel, + unsigned int gsel) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + const struct group_desc *group; + const char **functions; + + group = pinctrl_generic_get_group(pctrl_dev, gsel); + if (!group) + return -EINVAL; + + functions = group->data; + + for (int i = 0; i < group->grp.npins; i++) { + int function; + + function = mpfs_pinctrl_function_map(functions[i]); + if (function < 0) { + dev_err(pctrl->dev, "invalid function %s\n", functions[i]); + return function; + } + + mpfs_pinctrl_set_pin_func(pctrl, group->grp.pins[i], function); + } + + return 0; +} + +static const struct pinmux_ops mpfs_pinctrl_pinmux_ops = { + .get_functions_count = pinmux_generic_get_function_count, + .get_function_name = pinmux_generic_get_function_name, + .get_function_groups = pinmux_generic_get_function_groups, + .set_mux = mpfs_pinctrl_set_mux, +}; + +static int mpfs_pinctrl_pinconf_get(struct pinctrl_dev *pctrl_dev, unsigned int pin, + unsigned long *config) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + int param = pinconf_to_config_param(*config); + int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin); + int val; + u32 arg; + u8 str; + + regmap_read(pctrl->regmap, reg, &val); + + val = val >> mpfs_pinctrl_pin_to_iocfg_offset(pin); + val = val & MPFS_PINCTRL_IOCFG_MASK; + + switch (param) { + case PIN_CONFIG_BIAS_BUS_HOLD: + if (!(val & MPFS_PINCTRL_WPD)) + return -EINVAL; + + if (!(val & MPFS_PINCTRL_WPU)) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + if (!(val & MPFS_PINCTRL_WPD)) + return -EINVAL; + + if (val & MPFS_PINCTRL_WPU) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_PULL_UP: + if (!(val & MPFS_PINCTRL_WPU)) + return -EINVAL; + + if (val & MPFS_PINCTRL_WPD) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_BIAS_DISABLE: + if (val & MPFS_PINCTRL_PULL_MASK) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + str = FIELD_GET(MPFS_PINCTRL_DRV_MASK, val); + if (!str) + return -EINVAL; + + arg = mpfs_pinctrl_get_drive_strength_ma(str); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (!FIELD_GET(MPFS_PINCTRL_ENHYST, val)) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_PERSIST_STATE: + if (!FIELD_GET(MPFS_PINCTRL_LP_PERSIST_EN, val)) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_MODE_LOW_POWER: + if (!FIELD_GET(MPFS_PINCTRL_LP_BYPASS_EN, val)) + return -EINVAL; + + arg = 1; + break; + case PIN_CONFIG_POWER_SOURCE: + arg = mpfs_pinctrl_pin_to_bank_voltage(pctrl, pin); + break; + case MPFS_PINCTRL_CLAMP_DIODE: + if (!FIELD_GET(MPFS_PINCTRL_CLAMP, val)) + return -EINVAL; + + arg = 1; + break; + case MPFS_PINCTRL_LOCKDOWN: + /* + * Lockdown is a read-only configuration, it'll get set if the + * tamper unit triggers global lockdown and lockdown has been + * set in the MSS Configurator for the bank a pin belongs to. + */ + if (!FIELD_GET(MPFS_PINCTRL_LOCKDN, val)) + return -EINVAL; + + arg = 1; + break; + case MPFS_PINCTRL_IBUFMD: + arg = FIELD_GET(MPFS_PINCTRL_IBUFMD_MASK, val); + break; + default: + return -ENOTSUPP; + } + + *config = pinconf_to_config_packed(param, arg); + + return 0; +} + +static int mpfs_pinctrl_pinconf_generate_config(struct mpfs_pinctrl *pctrl, unsigned int pin, + unsigned long *configs, unsigned int num_configs, + u32 *value, u32 *bank_voltage) +{ + u32 val = 0; + + for (int i = 0; i < num_configs; i++) { + int param, tmp; + u32 arg; + + param = pinconf_to_config_param(configs[i]); + arg = pinconf_to_config_argument(configs[i]); + + switch (param) { + case PIN_CONFIG_BIAS_BUS_HOLD: + val |= MPFS_PINCTRL_PULL_MASK; + break; + case PIN_CONFIG_BIAS_PULL_DOWN: + val &= ~MPFS_PINCTRL_PULL_MASK; + val |= MPFS_PINCTRL_WPD; + break; + case PIN_CONFIG_BIAS_PULL_UP: + val &= ~MPFS_PINCTRL_PULL_MASK; + val |= MPFS_PINCTRL_WPU; + break; + case PIN_CONFIG_BIAS_DISABLE: + val &= ~MPFS_PINCTRL_PULL_MASK; + break; + case PIN_CONFIG_DRIVE_STRENGTH: + tmp = mpfs_pinctrl_get_drive_strength_val(arg); + if (tmp < 0) + return tmp; + + val |= FIELD_PREP(MPFS_PINCTRL_DRV_MASK, tmp); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (!arg) + break; + val |= MPFS_PINCTRL_ENHYST; + break; + case PIN_CONFIG_PERSIST_STATE: + val |= MPFS_PINCTRL_LP_PERSIST_EN; + break; + case PIN_CONFIG_MODE_LOW_POWER: + if (arg) + val |= MPFS_PINCTRL_LP_BYPASS_EN; + break; + case PIN_CONFIG_POWER_SOURCE: + tmp = mpfs_pinctrl_get_bank_voltage_val(arg); + if (tmp < 0) + return tmp; + + *bank_voltage = tmp; + break; + case MPFS_PINCTRL_CLAMP_DIODE: + val |= MPFS_PINCTRL_CLAMP; + break; + case MPFS_PINCTRL_IBUFMD: + val |= FIELD_PREP(MPFS_PINCTRL_IBUFMD_MASK, arg); + break; + default: + dev_err(pctrl->dev, "config %u not supported\n", param); + return -ENOTSUPP; + } + } + + *value = val; + return 0; +} + +static int mpfs_pinctrl_pin_set_config(struct mpfs_pinctrl *pctrl, unsigned int pin, u32 config) +{ + int reg = mpfs_pinctrl_pin_to_iocfg_reg(pin); + int offset = mpfs_pinctrl_pin_to_iocfg_offset(pin); + u32 val, mask; + + mask = MPFS_PINCTRL_IOCFG_MASK << offset; + val = config << offset; + + regmap_update_bits(pctrl->regmap, reg, mask, val); + + return 0; +} + +static int mpfs_pinctrl_pinconf_set(struct pinctrl_dev *pctrl_dev, unsigned int pin, + unsigned long *configs, unsigned int num_configs) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 val, bank_voltage = 0; + int ret; + + ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val, + &bank_voltage); + if (ret) + return ret; + + ret = mpfs_pinctrl_pin_set_config(pctrl, pin, val); + if (ret) + return ret; + + if (bank_voltage) + mpfs_pinctrl_set_bank_voltage(pctrl, pin, bank_voltage); + + return 0; +} + +static int mpfs_pinctrl_pinconf_group_set(struct pinctrl_dev *pctrl_dev, unsigned int gsel, + unsigned long *configs, unsigned int num_configs) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + const struct group_desc *group; + unsigned int pin; + u32 val, bank_voltage = 0; + int ret; + + group = pinctrl_generic_get_group(pctrl_dev, gsel); + if (!group) + return -EINVAL; + + /* + * Assume that the first pin in a group is representative, as the mss + * configurator doesn't allow splitting a function between two banks. + */ + pin = group->grp.pins[0]; + + ret = mpfs_pinctrl_pinconf_generate_config(pctrl, pin, configs, num_configs, &val, + &bank_voltage); + if (ret) + return ret; + + for (int i = 0; i < group->grp.npins; i++) + mpfs_pinctrl_pin_set_config(pctrl, group->grp.pins[i], val); + + if (bank_voltage) + mpfs_pinctrl_set_bank_voltage(pctrl, group->grp.pins[0], bank_voltage); + + return 0; +} + +static void mpfs_pinctrl_pinconf_dbg_show(struct pinctrl_dev *pctrl_dev, struct seq_file *seq, + unsigned int pin) +{ + struct mpfs_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev); + u32 val; + int reg, offset; + + reg = mpfs_pinctrl_pin_to_iocfg_reg(pin); + offset = mpfs_pinctrl_pin_to_iocfg_offset(pin); + + seq_printf(seq, "pin: %u ", pin); + seq_printf(seq, "reg: %x offset: %u ", reg, offset); + + if (reg < 0 || offset < 0) + return; + + regmap_read(pctrl->regmap, reg, &val); + val = (val & (MPFS_PINCTRL_IOCFG_MASK << offset)) >> offset; + seq_printf(seq, "val: %x\n", val); +} + +static const struct pinconf_ops mpfs_pinctrl_pinconf_ops = { + .pin_config_get = mpfs_pinctrl_pinconf_get, + .pin_config_set = mpfs_pinctrl_pinconf_set, + .pin_config_group_set = mpfs_pinctrl_pinconf_group_set, + .pin_config_dbg_show = mpfs_pinctrl_pinconf_dbg_show, + .is_generic = true, +}; + +static const struct pinctrl_pin_desc mpfs_pinctrl_pins[] = { + PINCTRL_PIN(0, "bank 4 0"), + PINCTRL_PIN(1, "bank 4 1"), + PINCTRL_PIN(2, "bank 4 2"), + PINCTRL_PIN(3, "bank 4 3"), + PINCTRL_PIN(4, "bank 4 4"), + PINCTRL_PIN(5, "bank 4 5"), + PINCTRL_PIN(6, "bank 4 6"), + PINCTRL_PIN(7, "bank 4 7"), + PINCTRL_PIN(8, "bank 4 8"), + PINCTRL_PIN(9, "bank 4 9"), + PINCTRL_PIN(10, "bank 4 10"), + PINCTRL_PIN(11, "bank 4 11"), + PINCTRL_PIN(12, "bank 4 12"), + PINCTRL_PIN(13, "bank 4 13"), + + PINCTRL_PIN(14, "bank 2 0"), + PINCTRL_PIN(15, "bank 2 1"), + PINCTRL_PIN(16, "bank 2 2"), + PINCTRL_PIN(17, "bank 2 3"), + PINCTRL_PIN(18, "bank 2 4"), + PINCTRL_PIN(19, "bank 2 5"), + PINCTRL_PIN(20, "bank 2 6"), + PINCTRL_PIN(21, "bank 2 7"), + PINCTRL_PIN(22, "bank 2 8"), + PINCTRL_PIN(23, "bank 2 9"), + PINCTRL_PIN(24, "bank 2 10"), + PINCTRL_PIN(25, "bank 2 11"), + PINCTRL_PIN(26, "bank 2 12"), + PINCTRL_PIN(27, "bank 2 13"), + PINCTRL_PIN(28, "bank 2 14"), + PINCTRL_PIN(29, "bank 2 15"), + PINCTRL_PIN(30, "bank 2 16"), + PINCTRL_PIN(31, "bank 2 17"), + PINCTRL_PIN(32, "bank 2 18"), + PINCTRL_PIN(33, "bank 2 19"), + PINCTRL_PIN(34, "bank 2 20"), + PINCTRL_PIN(35, "bank 2 21"), + PINCTRL_PIN(36, "bank 2 22"), + PINCTRL_PIN(37, "bank 2 23"), +}; + +static int mpfs_pinctrl_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct mpfs_pinctrl *pctrl; + int ret; + + pctrl = devm_kzalloc(dev, sizeof(*pctrl), GFP_KERNEL); + if (!pctrl) + return -ENOMEM; + + pctrl->regmap = device_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(pctrl->regmap)) + dev_err_probe(dev, PTR_ERR(pctrl->regmap), "Failed to find syscon regmap\n"); + + pctrl->sysreg_regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-sysreg-scb"); + if (IS_ERR(pctrl->sysreg_regmap)) + return PTR_ERR(pctrl->sysreg_regmap); + + pctrl->desc.name = dev_name(dev); + pctrl->desc.pins = mpfs_pinctrl_pins; + pctrl->desc.npins = ARRAY_SIZE(mpfs_pinctrl_pins); + pctrl->desc.pctlops = &mpfs_pinctrl_ops; + pctrl->desc.pmxops = &mpfs_pinctrl_pinmux_ops; + pctrl->desc.confops = &mpfs_pinctrl_pinconf_ops; + pctrl->desc.owner = THIS_MODULE; + pctrl->desc.num_custom_params = ARRAY_SIZE(mpfs_pinctrl_custom_bindings); + pctrl->desc.custom_params = mpfs_pinctrl_custom_bindings; + + pctrl->dev = dev; + + ret = devm_mutex_init(dev, &pctrl->mutex); + if (ret) + return ret; + + platform_set_drvdata(pdev, pctrl); + + pctrl->pctrl = devm_pinctrl_register(&pdev->dev, &pctrl->desc, pctrl); + if (IS_ERR(pctrl->pctrl)) + return PTR_ERR(pctrl->pctrl); + + return 0; +} + +static const struct of_device_id mpfs_pinctrl_of_match[] = { + { .compatible = "microchip,mpfs-pinctrl-mssio" }, + { } +}; +MODULE_DEVICE_TABLE(of, mpfs_pinctrl_of_match); + +static struct platform_driver mpfs_pinctrl_driver = { + .driver = { + .name = "mpfs-pinctrl", + .of_match_table = mpfs_pinctrl_of_match, + }, + .probe = mpfs_pinctrl_probe, +}; +module_platform_driver(mpfs_pinctrl_driver); + +MODULE_AUTHOR("Conor Dooley "); +MODULE_DESCRIPTION("Polarfire SoC mssio pinctrl driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-pic64gx-gpio2.c b/drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c similarity index 99% rename from drivers/pinctrl/pinctrl-pic64gx-gpio2.c rename to drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c index f322bb5e6181..a0b3e839cf3b 100644 --- a/drivers/pinctrl/pinctrl-pic64gx-gpio2.c +++ b/drivers/pinctrl/microchip/pinctrl-pic64gx-gpio2.c @@ -14,7 +14,7 @@ #include #include -#include "pinctrl-utils.h" +#include "../pinctrl-utils.h" #define PIC64GX_PINMUX_REG 0x0 diff --git a/drivers/pinctrl/mvebu/pinctrl-mvebu.c b/drivers/pinctrl/mvebu/pinctrl-mvebu.c index 84a119718f86..5ce3d7fcdd34 100644 --- a/drivers/pinctrl/mvebu/pinctrl-mvebu.c +++ b/drivers/pinctrl/mvebu/pinctrl-mvebu.c @@ -430,7 +430,7 @@ static int mvebu_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return 0; } - *map = kmalloc_array(nmaps, sizeof(**map), GFP_KERNEL); + *map = kmalloc_objs(**map, nmaps); if (!*map) return -ENOMEM; diff --git a/drivers/pinctrl/nuvoton/pinctrl-ma35.c b/drivers/pinctrl/nuvoton/pinctrl-ma35.c index 8d71dc53cc1d..f01344201628 100644 --- a/drivers/pinctrl/nuvoton/pinctrl-ma35.c +++ b/drivers/pinctrl/nuvoton/pinctrl-ma35.c @@ -202,7 +202,7 @@ static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev, } map_num += grp->grp.npins; - new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); + new_map = kzalloc_objs(*new_map, map_num); if (!new_map) return -ENOMEM; diff --git a/drivers/pinctrl/nxp/pinctrl-s32cc.c b/drivers/pinctrl/nxp/pinctrl-s32cc.c index 35511f83d056..fe7cd641fddd 100644 --- a/drivers/pinctrl/nxp/pinctrl-s32cc.c +++ b/drivers/pinctrl/nxp/pinctrl-s32cc.c @@ -386,7 +386,7 @@ static int s32_pmx_gpio_request_enable(struct pinctrl_dev *pctldev, return ret; /* Save current configuration */ - gpio_pin = kmalloc(sizeof(*gpio_pin), GFP_KERNEL); + gpio_pin = kmalloc_obj(*gpio_pin); if (!gpio_pin) return -ENOMEM; diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c index 366775841c63..2b030bd0e6ad 100644 --- a/drivers/pinctrl/pinconf-generic.c +++ b/drivers/pinctrl/pinconf-generic.c @@ -351,13 +351,13 @@ int pinconf_generic_parse_dt_config(struct device_node *np, ret = parse_dt_cfg(np, dt_params, ARRAY_SIZE(dt_params), cfg, &ncfg); if (ret) - return ret; + goto out; if (pctldev && pctldev->desc->num_custom_params && pctldev->desc->custom_params) { ret = parse_dt_cfg(np, pctldev->desc->custom_params, pctldev->desc->num_custom_params, cfg, &ncfg); if (ret) - return ret; + goto out; } /* no configs found at all */ @@ -385,75 +385,6 @@ int pinconf_generic_parse_dt_config(struct device_node *np, } EXPORT_SYMBOL_GPL(pinconf_generic_parse_dt_config); -int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, - unsigned int *num_maps) -{ - struct device *dev = pctldev->dev; - struct device_node *pnode; - unsigned long *configs = NULL; - unsigned int num_configs = 0; - struct property *prop; - unsigned int reserved_maps; - int reserve; - int ret; - - prop = of_find_property(np, "pinmux", NULL); - if (!prop) { - dev_info(dev, "Missing pinmux property\n"); - return -ENOENT; - } - - pnode = of_get_parent(np); - if (!pnode) { - dev_info(dev, "Missing function node\n"); - return -EINVAL; - } - - reserved_maps = 0; - *map = NULL; - *num_maps = 0; - - ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, - &num_configs); - if (ret < 0) { - dev_err(dev, "%pOF: could not parse node property\n", np); - return ret; - } - - reserve = 1; - if (num_configs) - reserve++; - - ret = pinctrl_utils_reserve_map(pctldev, map, &reserved_maps, - num_maps, reserve); - if (ret < 0) - goto exit; - - ret = pinctrl_utils_add_map_mux(pctldev, map, - &reserved_maps, num_maps, np->name, - pnode->name); - if (ret < 0) - goto exit; - - if (num_configs) { - ret = pinctrl_utils_add_map_configs(pctldev, map, &reserved_maps, - num_maps, np->name, configs, - num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); - if (ret < 0) - goto exit; - } - -exit: - kfree(configs); - if (ret) - pinctrl_utils_free_map(pctldev, *map, *num_maps); - - return ret; -} -EXPORT_SYMBOL_GPL(pinconf_generic_dt_node_to_map_pinmux); - int pinconf_generic_dt_subnode_to_map(struct pinctrl_dev *pctldev, struct device_node *np, struct pinctrl_map **map, unsigned int *reserved_maps, unsigned int *num_maps, diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index e1ae71610526..2880adef476e 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -160,3 +160,19 @@ pinconf_generic_parse_dt_pinmux(struct device_node *np, struct device *dev, return -ENOTSUPP; } #endif + +#if defined(CONFIG_GENERIC_PINCTRL) && defined (CONFIG_OF) +int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **maps, + unsigned int *num_maps); +#else +static inline int +pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **maps, + unsigned int *num_maps) +{ + return -ENOTSUPP; +} +#endif diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 2dac5c71eb00..2af94ef56434 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -21,11 +21,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include diff --git a/drivers/pinctrl/pinctrl-amdisp.c b/drivers/pinctrl/pinctrl-amdisp.c index efbf40c776ea..e0874cc086a7 100644 --- a/drivers/pinctrl/pinctrl-amdisp.c +++ b/drivers/pinctrl/pinctrl-amdisp.c @@ -80,7 +80,7 @@ static int amdisp_get_group_pins(struct pinctrl_dev *pctldev, return 0; } -const struct pinctrl_ops amdisp_pinctrl_ops = { +static const struct pinctrl_ops amdisp_pinctrl_ops = { .get_groups_count = amdisp_get_groups_count, .get_group_name = amdisp_get_group_name, .get_group_pins = amdisp_get_group_pins, diff --git a/drivers/pinctrl/pinctrl-apple-gpio.c b/drivers/pinctrl/pinctrl-apple-gpio.c index e1a7bc8cf765..6305b96aaa73 100644 --- a/drivers/pinctrl/pinctrl-apple-gpio.c +++ b/drivers/pinctrl/pinctrl-apple-gpio.c @@ -102,9 +102,9 @@ static u32 apple_gpio_get_reg(struct apple_gpio_pinctrl *pctl, static int apple_gpio_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *node, struct pinctrl_map **map, - unsigned *num_maps) + unsigned int *num_maps) { - unsigned reserved_maps; + unsigned int reserved_maps; struct apple_gpio_pinctrl *pctl; u32 pinfunc, pin, func; int num_pins, i, ret; @@ -170,8 +170,15 @@ static const struct pinctrl_ops apple_gpio_pinctrl_ops = { /* Pin multiplexer functions */ -static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned func, - unsigned group) +static bool apple_gpio_pinmux_func_is_gpio(struct pinctrl_dev *pctldev, + unsigned int selector) +{ + /* Function selector 0 is always the GPIO mode */ + return (selector == 0); +} + +static int apple_gpio_pinmux_set(struct pinctrl_dev *pctldev, unsigned int func, + unsigned int group) { struct apple_gpio_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); @@ -186,6 +193,7 @@ static const struct pinmux_ops apple_gpio_pinmux_ops = { .get_functions_count = pinmux_generic_get_function_count, .get_function_name = pinmux_generic_get_function_name, .get_function_groups = pinmux_generic_get_function_groups, + .function_is_gpio = apple_gpio_pinmux_func_is_gpio, .set_mux = apple_gpio_pinmux_set, .strict = true, }; @@ -202,7 +210,7 @@ static int apple_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) return GPIO_LINE_DIRECTION_IN; } -static int apple_gpio_get(struct gpio_chip *chip, unsigned offset) +static int apple_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct apple_gpio_pinctrl *pctl = gpiochip_get_data(chip); unsigned int reg = apple_gpio_get_reg(pctl, offset); @@ -392,8 +400,7 @@ static int apple_gpio_register(struct apple_gpio_pinctrl *pctl) girq->parents = kmalloc_array(girq->num_parents, sizeof(*girq->parents), GFP_KERNEL); - irq_data = kmalloc_array(girq->num_parents, sizeof(*irq_data), - GFP_KERNEL); + irq_data = kmalloc_objs(*irq_data, girq->num_parents); if (!girq->parents || !irq_data) { ret = -ENOMEM; goto out_free_irq_data; diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c index ec5351fc282e..41cbb46ac589 100644 --- a/drivers/pinctrl/pinctrl-at91-pio4.c +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -1053,6 +1053,12 @@ static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = { .last_bank_count = ATMEL_PIO_NPINS_PER_BANK, }; +static const struct atmel_pioctrl_data microchip_sama7d65_pioctrl_data = { + .nbanks = 5, + .last_bank_count = 14, /* sama7d65 has only PE0 to PE13 */ + .slew_rate_support = 1, +}; + static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { .nbanks = 5, .last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */ @@ -1063,6 +1069,9 @@ static const struct of_device_id atmel_pctrl_of_match[] = { { .compatible = "atmel,sama5d2-pinctrl", .data = &atmel_sama5d2_pioctrl_data, + }, { + .compatible = "microchip,sama7d65-pinctrl", + .data = µchip_sama7d65_pioctrl_data, }, { .compatible = "microchip,sama7g5-pinctrl", .data = µchip_sama7g5_pioctrl_data, diff --git a/drivers/pinctrl/pinctrl-aw9523.c b/drivers/pinctrl/pinctrl-aw9523.c index 479553a79216..02a24ac87ea4 100644 --- a/drivers/pinctrl/pinctrl-aw9523.c +++ b/drivers/pinctrl/pinctrl-aw9523.c @@ -291,14 +291,14 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, unsigned int mask, val; int i, rc; - mutex_lock(&awi->i2c_lock); + guard(mutex)(&awi->i2c_lock); for (i = 0; i < num_configs; i++) { param = pinconf_to_config_param(configs[i]); arg = pinconf_to_config_argument(configs[i]); rc = aw9523_pcfg_param_to_reg(param, pin, ®); if (rc) - goto end; + return rc; switch (param) { case PIN_CONFIG_LEVEL: @@ -307,7 +307,7 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, AW9523_REG_CONF_STATE(pin), BIT(regbit), 0); if (rc) - goto end; + return rc; /* Then, fall through to config output level */ fallthrough; @@ -323,10 +323,9 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, break; case PIN_CONFIG_DRIVE_OPEN_DRAIN: /* Open-Drain is supported only on port 0 */ - if (pin >= AW9523_PINS_PER_PORT) { - rc = -ENOTSUPP; - goto end; - } + if (pin >= AW9523_PINS_PER_PORT) + return -ENOTSUPP; + mask = AW9523_GCR_GPOMD_MASK; val = 0; break; @@ -341,17 +340,15 @@ static int aw9523_pconf_set(struct pinctrl_dev *pctldev, unsigned int pin, val = AW9523_GCR_GPOMD_MASK; break; default: - rc = -ENOTSUPP; - goto end; + return -ENOTSUPP; } rc = regmap_update_bits(awi->regmap, reg, mask, val); if (rc) - goto end; + return rc; } -end: - mutex_unlock(&awi->i2c_lock); - return rc; + + return 0; } static const struct pinconf_ops aw9523_pinconf_ops = { @@ -599,14 +596,14 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, u8 m, state = 0; int ret; - mutex_lock(&awi->i2c_lock); + guard(mutex)(&awi->i2c_lock); /* Port 0 (gpio 0-7) */ m = *mask; if (m) { ret = _aw9523_gpio_get_multiple(awi, 0, &state, m); if (ret) - goto out; + return ret; } *bits = state; @@ -616,13 +613,12 @@ static int aw9523_gpio_get_multiple(struct gpio_chip *chip, ret = _aw9523_gpio_get_multiple(awi, AW9523_PINS_PER_PORT, &state, m); if (ret) - goto out; + return ret; *bits |= (state << 8); } -out: - mutex_unlock(&awi->i2c_lock); - return ret; + + return 0; } static int aw9523_gpio_set_multiple(struct gpio_chip *chip, @@ -632,30 +628,28 @@ static int aw9523_gpio_set_multiple(struct gpio_chip *chip, struct aw9523 *awi = gpiochip_get_data(chip); u8 mask_lo, mask_hi, bits_lo, bits_hi; unsigned int reg; - int ret = 0; + int ret; mask_lo = *mask; mask_hi = *mask >> 8; bits_lo = *bits; bits_hi = *bits >> 8; - mutex_lock(&awi->i2c_lock); + guard(mutex)(&awi->i2c_lock); if (mask_hi) { reg = AW9523_REG_OUT_STATE(AW9523_PINS_PER_PORT); ret = regmap_write_bits(awi->regmap, reg, mask_hi, bits_hi); if (ret) - goto out; + return ret; } if (mask_lo) { reg = AW9523_REG_OUT_STATE(0); ret = regmap_write_bits(awi->regmap, reg, mask_lo, bits_lo); if (ret) - goto out; + return ret; } -out: - mutex_unlock(&awi->i2c_lock); - return ret; + return 0; } static int aw9523_gpio_set(struct gpio_chip *chip, unsigned int offset, @@ -695,16 +689,15 @@ static int aw9523_direction_output(struct gpio_chip *chip, u8 regbit = offset % AW9523_PINS_PER_PORT; int ret; - mutex_lock(&awi->i2c_lock); + guard(mutex)(&awi->i2c_lock); ret = regmap_update_bits(awi->regmap, AW9523_REG_OUT_STATE(offset), BIT(regbit), value ? BIT(regbit) : 0); if (ret) - goto end; + return ret; ret = regmap_update_bits(awi->regmap, AW9523_REG_CONF_STATE(offset), BIT(regbit), 0); -end: - mutex_unlock(&awi->i2c_lock); + return ret; } diff --git a/drivers/pinctrl/pinctrl-cy8c95x0.c b/drivers/pinctrl/pinctrl-cy8c95x0.c index a4b04bf6d081..5c055d344ac9 100644 --- a/drivers/pinctrl/pinctrl-cy8c95x0.c +++ b/drivers/pinctrl/pinctrl-cy8c95x0.c @@ -627,7 +627,7 @@ static int cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, bitmap_scatter(tmask, mask, chip->map, MAX_LINE); bitmap_scatter(tval, val, chip->map, MAX_LINE); - for_each_set_clump8(offset, bits, tmask, chip->tpin) { + for_each_set_clump8(offset, bits, tmask, chip->nport * BANK_SZ) { unsigned int i = offset / 8; write_val = bitmap_get_value8(tval, offset); @@ -655,7 +655,7 @@ static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg, bitmap_scatter(tmask, mask, chip->map, MAX_LINE); bitmap_scatter(tval, val, chip->map, MAX_LINE); - for_each_set_clump8(offset, bits, tmask, chip->tpin) { + for_each_set_clump8(offset, bits, tmask, chip->nport * BANK_SZ) { unsigned int i = offset / 8; ret = cy8c95x0_regmap_read_bits(chip, reg, i, bits, &read_val); diff --git a/drivers/pinctrl/pinctrl-equilibrium.c b/drivers/pinctrl/pinctrl-equilibrium.c index 2d04829b29c9..ba1c867b7b89 100644 --- a/drivers/pinctrl/pinctrl-equilibrium.c +++ b/drivers/pinctrl/pinctrl-equilibrium.c @@ -23,7 +23,7 @@ #define PIN_NAME_LEN 10 #define PAD_REG_OFF 0x100 -static void eqbr_gpio_disable_irq(struct irq_data *d) +static void eqbr_irq_mask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc); @@ -36,7 +36,7 @@ static void eqbr_gpio_disable_irq(struct irq_data *d) gpiochip_disable_irq(gc, offset); } -static void eqbr_gpio_enable_irq(struct irq_data *d) +static void eqbr_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc); @@ -50,7 +50,7 @@ static void eqbr_gpio_enable_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&gctrl->lock, flags); } -static void eqbr_gpio_ack_irq(struct irq_data *d) +static void eqbr_irq_ack(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc); @@ -62,10 +62,17 @@ static void eqbr_gpio_ack_irq(struct irq_data *d) raw_spin_unlock_irqrestore(&gctrl->lock, flags); } -static void eqbr_gpio_mask_ack_irq(struct irq_data *d) +static void eqbr_irq_mask_ack(struct irq_data *d) { - eqbr_gpio_disable_irq(d); - eqbr_gpio_ack_irq(d); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc); + unsigned int offset = irqd_to_hwirq(d); + unsigned long flags; + + raw_spin_lock_irqsave(&gctrl->lock, flags); + writel(BIT(offset), gctrl->membase + GPIO_IRNENCLR); + writel(BIT(offset), gctrl->membase + GPIO_IRNCR); + raw_spin_unlock_irqrestore(&gctrl->lock, flags); } static inline void eqbr_cfg_bit(void __iomem *addr, @@ -92,7 +99,7 @@ static int eqbr_irq_type_cfg(struct gpio_irq_type *type, return 0; } -static int eqbr_gpio_set_irq_type(struct irq_data *d, unsigned int type) +static int eqbr_irq_set_type(struct irq_data *d, unsigned int type) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct eqbr_gpio_ctrl *gctrl = gpiochip_get_data(gc); @@ -166,11 +173,11 @@ static void eqbr_irq_handler(struct irq_desc *desc) static const struct irq_chip eqbr_irq_chip = { .name = "gpio_irq", - .irq_mask = eqbr_gpio_disable_irq, - .irq_unmask = eqbr_gpio_enable_irq, - .irq_ack = eqbr_gpio_ack_irq, - .irq_mask_ack = eqbr_gpio_mask_ack_irq, - .irq_set_type = eqbr_gpio_set_irq_type, + .irq_ack = eqbr_irq_ack, + .irq_mask = eqbr_irq_mask, + .irq_mask_ack = eqbr_irq_mask_ack, + .irq_unmask = eqbr_irq_unmask, + .irq_set_type = eqbr_irq_set_type, .flags = IRQCHIP_IMMUTABLE, GPIOCHIP_IRQ_RESOURCE_HELPERS, }; @@ -846,6 +853,7 @@ static int pinbank_init(struct device_node *np, bank->pin_base = spec.args[1]; bank->nr_pins = spec.args[2]; + of_node_put(spec.np); bank->aval_pinmap = readl(bank->membase + REG_AVAIL); bank->id = id; diff --git a/drivers/pinctrl/pinctrl-generic.c b/drivers/pinctrl/pinctrl-generic.c new file mode 100644 index 000000000000..efb39c6a6703 --- /dev/null +++ b/drivers/pinctrl/pinctrl-generic.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define pr_fmt(fmt) "generic pinconfig core: " fmt + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "core.h" +#include "pinconf.h" +#include "pinctrl-utils.h" +#include "pinmux.h" + +static int pinctrl_generic_pins_function_dt_subnode_to_map(struct pinctrl_dev *pctldev, + struct device_node *parent, + struct device_node *np, + struct pinctrl_map **maps, + unsigned int *num_maps, + unsigned int *num_reserved_maps, + const char **group_names, + unsigned int ngroups) +{ + struct device *dev = pctldev->dev; + const char **functions; + const char *group_name; + unsigned long *configs; + unsigned int num_configs, pin, *pins; + int npins, ret, reserve = 1; + + npins = of_property_count_u32_elems(np, "pins"); + + if (npins < 1) { + dev_err(dev, "invalid pinctrl group %pOFn.%pOFn %d\n", + parent, np, npins); + return npins; + } + + group_name = devm_kasprintf(dev, GFP_KERNEL, "%pOFn.%pOFn", parent, np); + if (!group_name) + return -ENOMEM; + + group_names[ngroups] = group_name; + + pins = devm_kcalloc(dev, npins, sizeof(*pins), GFP_KERNEL); + if (!pins) + return -ENOMEM; + + functions = devm_kcalloc(dev, npins, sizeof(*functions), GFP_KERNEL); + if (!functions) + return -ENOMEM; + + for (int i = 0; i < npins; i++) { + ret = of_property_read_u32_index(np, "pins", i, &pin); + if (ret) + return ret; + + pins[i] = pin; + + ret = of_property_read_string(np, "function", &functions[i]); + if (ret) + return ret; + } + + ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve); + if (ret) + return ret; + + ret = pinctrl_utils_add_map_mux(pctldev, maps, num_reserved_maps, num_maps, group_name, + parent->name); + if (ret < 0) + return ret; + + ret = pinctrl_generic_add_group(pctldev, group_name, pins, npins, functions); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to add group %s: %d\n", + group_name, ret); + + ret = pinconf_generic_parse_dt_config(np, pctldev, &configs, &num_configs); + if (ret) + return dev_err_probe(dev, ret, "failed to parse pin config of group %s\n", + group_name); + + if (num_configs == 0) + return 0; + + ret = pinctrl_utils_reserve_map(pctldev, maps, num_reserved_maps, num_maps, reserve); + if (ret) + return ret; + + ret = pinctrl_utils_add_map_configs(pctldev, maps, num_reserved_maps, num_maps, group_name, + configs, + num_configs, PIN_MAP_TYPE_CONFIGS_GROUP); + kfree(configs); + if (ret) + return ret; + + return 0; +}; + +/* + * For platforms that do not define groups or functions in the driver, but + * instead use the devicetree to describe them. This function will, unlike + * pinconf_generic_dt_node_to_map() etc which rely on driver defined groups + * and functions, create them in addition to parsing pinconf properties and + * adding mappings. + */ +int pinctrl_generic_pins_function_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **maps, + unsigned int *num_maps) +{ + struct device *dev = pctldev->dev; + struct device_node *child_np; + const char **group_names; + unsigned int num_reserved_maps = 0; + int ngroups = 0; + int ret; + + *maps = NULL; + *num_maps = 0; + + /* + * Check if this is actually the pins node, or a parent containing + * multiple pins nodes. + */ + if (!of_property_present(np, "pins")) + goto parent; + + group_names = devm_kcalloc(dev, 1, sizeof(*group_names), GFP_KERNEL); + if (!group_names) + return -ENOMEM; + + ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, np, + maps, num_maps, + &num_reserved_maps, + group_names, + ngroups); + if (ret) { + pinctrl_utils_free_map(pctldev, *maps, *num_maps); + return dev_err_probe(dev, ret, "error figuring out mappings for %s\n", np->name); + } + + ret = pinmux_generic_add_function(pctldev, np->name, group_names, 1, NULL); + if (ret < 0) { + pinctrl_utils_free_map(pctldev, *maps, *num_maps); + return dev_err_probe(dev, ret, "error adding function %s\n", np->name); + } + + return 0; + +parent: + for_each_available_child_of_node(np, child_np) + ngroups += 1; + + group_names = devm_kcalloc(dev, ngroups, sizeof(*group_names), GFP_KERNEL); + if (!group_names) + return -ENOMEM; + + ngroups = 0; + for_each_available_child_of_node_scoped(np, child_np) { + ret = pinctrl_generic_pins_function_dt_subnode_to_map(pctldev, np, child_np, + maps, num_maps, + &num_reserved_maps, + group_names, + ngroups); + if (ret) { + pinctrl_utils_free_map(pctldev, *maps, *num_maps); + return dev_err_probe(dev, ret, "error figuring out mappings for %s\n", + np->name); + } + + ngroups++; + } + + ret = pinmux_generic_add_function(pctldev, np->name, group_names, ngroups, NULL); + if (ret < 0) { + pinctrl_utils_free_map(pctldev, *maps, *num_maps); + return dev_err_probe(dev, ret, "error adding function %s\n", np->name); + } + + return 0; +} +EXPORT_SYMBOL_GPL(pinctrl_generic_pins_function_dt_node_to_map); diff --git a/drivers/pinctrl/pinctrl-k230.c b/drivers/pinctrl/pinctrl-k230.c index d716f23d837f..886577abf0d0 100644 --- a/drivers/pinctrl/pinctrl-k230.c +++ b/drivers/pinctrl/pinctrl-k230.c @@ -65,6 +65,7 @@ struct k230_pmx_func { }; struct k230_pinctrl { + struct device *dev; struct pinctrl_desc pctl; struct pinctrl_dev *pctl_dev; struct regmap *regmap_base; @@ -210,7 +211,7 @@ static int k230_dt_node_to_map(struct pinctrl_dev *pctldev, map_num += info->groups[grp_id].num_pins + 1; } - new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); + new_map = kzalloc_objs(*new_map, map_num); if (!new_map) return -ENOMEM; *map = new_map; @@ -470,7 +471,7 @@ static int k230_pinctrl_parse_groups(struct device_node *np, struct k230_pinctrl *info, unsigned int index) { - struct device *dev = info->pctl_dev->dev; + struct device *dev = info->dev; const __be32 *list; int size, i, ret; @@ -511,7 +512,7 @@ static int k230_pinctrl_parse_functions(struct device_node *np, struct k230_pinctrl *info, unsigned int index) { - struct device *dev = info->pctl_dev->dev; + struct device *dev = info->dev; struct k230_pmx_func *func; struct k230_pin_group *grp; static unsigned int idx, i; @@ -596,6 +597,8 @@ static int k230_pinctrl_probe(struct platform_device *pdev) if (!info) return -ENOMEM; + info->dev = dev; + pctl = &info->pctl; pctl->name = "k230-pinctrl"; diff --git a/drivers/pinctrl/pinctrl-microchip-sgpio.c b/drivers/pinctrl/pinctrl-microchip-sgpio.c index b6363f3cdce9..7a6cb5f502b0 100644 --- a/drivers/pinctrl/pinctrl-microchip-sgpio.c +++ b/drivers/pinctrl/pinctrl-microchip-sgpio.c @@ -264,19 +264,17 @@ static int sgpio_single_shot(struct sgpio_priv *priv) * setting. * After the manual burst, reenable the auto repeat mode again. */ - mutex_lock(&priv->poll_lock); + guard(mutex)(&priv->poll_lock); ret = regmap_update_bits(priv->regs, addr, single_shot | auto_repeat, single_shot); if (ret) - goto out; + return ret; ret = regmap_read_poll_timeout(priv->regs, addr, ctrl, !(ctrl & single_shot), 100, 60000); /* reenable auto repeat mode even if there was an error */ ret2 = regmap_update_bits(priv->regs, addr, auto_repeat, auto_repeat); -out: - mutex_unlock(&priv->poll_lock); return ret ?: ret2; } diff --git a/drivers/pinctrl/pinctrl-ocelot.c b/drivers/pinctrl/pinctrl-ocelot.c index 70da3f37567a..0fe0527863b8 100644 --- a/drivers/pinctrl/pinctrl-ocelot.c +++ b/drivers/pinctrl/pinctrl-ocelot.c @@ -97,6 +97,8 @@ enum { FUNC_FC_SHRD20, FUNC_FUSA, FUNC_GPIO, + FUNC_I2C, + FUNC_I2C_Sa, FUNC_IB_TRG_a, FUNC_IB_TRG_b, FUNC_IB_TRG_c, @@ -112,9 +114,11 @@ enum { FUNC_IRQ1, FUNC_IRQ1_IN, FUNC_IRQ1_OUT, + FUNC_IRQ2, FUNC_IRQ3, FUNC_IRQ4, FUNC_EXT_IRQ, + FUNC_MACLED, FUNC_MIIM, FUNC_MIIM_a, FUNC_MIIM_b, @@ -126,6 +130,7 @@ enum { FUNC_OB_TRG_a, FUNC_OB_TRG_b, FUNC_PHY_LED, + FUNC_PHY_DBG, FUNC_PCI_WAKE, FUNC_MD, FUNC_PCIE_PERST, @@ -156,10 +161,12 @@ enum { FUNC_SG0, FUNC_SG1, FUNC_SG2, + FUNC_SPI, FUNC_SGPIO_a, FUNC_SGPIO_b, FUNC_SI, FUNC_SI2, + FUNC_SI_Sa, FUNC_SYNCE, FUNC_TACHO, FUNC_TACHO_a, @@ -188,6 +195,7 @@ enum { FUNC_EMMC_SD, FUNC_REF_CLK, FUNC_RCVRD_CLK, + FUNC_RGMII, FUNC_MAX }; @@ -237,6 +245,8 @@ static const char *const ocelot_function_names[] = { [FUNC_FC_SHRD20] = "fc_shrd20", [FUNC_FUSA] = "fusa", [FUNC_GPIO] = "gpio", + [FUNC_I2C] = "i2c", + [FUNC_I2C_Sa] = "i2c_slave_a", [FUNC_IB_TRG_a] = "ib_trig_a", [FUNC_IB_TRG_b] = "ib_trig_b", [FUNC_IB_TRG_c] = "ib_trig_c", @@ -252,9 +262,11 @@ static const char *const ocelot_function_names[] = { [FUNC_IRQ1] = "irq1", [FUNC_IRQ1_IN] = "irq1_in", [FUNC_IRQ1_OUT] = "irq1_out", + [FUNC_IRQ2] = "irq2", [FUNC_IRQ3] = "irq3", [FUNC_IRQ4] = "irq4", [FUNC_EXT_IRQ] = "ext_irq", + [FUNC_MACLED] = "mac_led", [FUNC_MIIM] = "miim", [FUNC_MIIM_a] = "miim_a", [FUNC_MIIM_b] = "miim_b", @@ -263,6 +275,7 @@ static const char *const ocelot_function_names[] = { [FUNC_MIIM_Sb] = "miim_slave_b", [FUNC_MIIM_IRQ] = "miim_irq", [FUNC_PHY_LED] = "phy_led", + [FUNC_PHY_DBG] = "phy_dbg", [FUNC_PCI_WAKE] = "pci_wake", [FUNC_PCIE_PERST] = "pcie_perst", [FUNC_MD] = "md", @@ -300,6 +313,8 @@ static const char *const ocelot_function_names[] = { [FUNC_SGPIO_b] = "sgpio_b", [FUNC_SI] = "si", [FUNC_SI2] = "si2", + [FUNC_SI_Sa] = "si_slave_a", + [FUNC_SPI] = "spi", [FUNC_SYNCE] = "synce", [FUNC_TACHO] = "tacho", [FUNC_TACHO_a] = "tacho_a", @@ -328,6 +343,7 @@ static const char *const ocelot_function_names[] = { [FUNC_EMMC_SD] = "emmc_sd", [FUNC_REF_CLK] = "ref_clk", [FUNC_RCVRD_CLK] = "rcvrd_clk", + [FUNC_RGMII] = "rgmii", }; struct ocelot_pmx_func { @@ -358,12 +374,14 @@ struct ocelot_pinctrl { const struct ocelot_pincfg_data *pincfg_data; struct ocelot_pmx_func func[FUNC_MAX]; u8 stride; + u8 altm_stride; struct workqueue_struct *wq; }; struct ocelot_match_data { struct pinctrl_desc desc; struct ocelot_pincfg_data pincfg_data; + unsigned int n_alt_modes; }; struct ocelot_irq_work { @@ -1321,6 +1339,132 @@ static const struct pinctrl_pin_desc lan969x_pins[] = { LAN969X_PIN(66), }; +#define LAN9645X_P(p, f0, f1, f2, f3, f4, f5, f6, f7) \ +static struct ocelot_pin_caps lan9645x_pin_##p = { \ + .pin = p, \ + .functions = { \ + FUNC_##f0, FUNC_##f1, FUNC_##f2, \ + FUNC_##f3 \ + }, \ + .a_functions = { \ + FUNC_##f4, FUNC_##f5, FUNC_##f6, \ + FUNC_##f7 \ + }, \ +} + +/* Pin FUNC0 FUNC1 FUNC2 FUNC3 FUNC4 FUNC5 FUNC6 FUNC7 */ +LAN9645X_P(0, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG); +LAN9645X_P(1, GPIO, SPI, SI_Sa, I2C_Sa, MIIM_Sa, UART, MIIM, PHY_DBG); +LAN9645X_P(2, GPIO, SPI, SI_Sa, I2C, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(3, GPIO, SPI, SI_Sa, I2C, MIIM_Sa, NONE, NONE, PHY_DBG); +LAN9645X_P(4, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG); +LAN9645X_P(5, GPIO, RGMII, TWI_SCL_M, I2C, NONE, NONE, SI_Sa, PHY_DBG); +LAN9645X_P(6, GPIO, RGMII, TWI_SCL_M, NONE, NONE, NONE, SI_Sa, PHY_DBG); +LAN9645X_P(7, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, SI_Sa, PHY_DBG); +LAN9645X_P(8, GPIO, RGMII, TWI_SCL_M, SFP, SGPIO_a, MIIM, NONE, PHY_DBG); +LAN9645X_P(9, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ1, UART, PHY_DBG); +LAN9645X_P(10, GPIO, RGMII, TWI_SCL_M, RECO_CLK, SGPIO_a, IRQ2, UART, PHY_DBG); +LAN9645X_P(11, GPIO, RGMII, TWI_SCL_M, MIIM, NONE, IRQ3, NONE, PHY_DBG); +LAN9645X_P(12, GPIO, RGMII, TWI_SCL_M, MIIM, PTP0, NONE, NONE, PHY_DBG); +LAN9645X_P(13, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP1, MACLED, NONE, PHY_DBG); +LAN9645X_P(14, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP2, MACLED, NONE, PHY_DBG); +LAN9645X_P(15, GPIO, RGMII, TWI_SCL_M, CLKMON, PTP3, NONE, NONE, PHY_DBG); +LAN9645X_P(16, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(17, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(18, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(19, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(20, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(21, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(22, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(23, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(24, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(25, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(26, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(27, GPIO, RGMII, NONE, NONE, NONE, NONE, NONE, PHY_DBG); +LAN9645X_P(28, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R); +LAN9645X_P(29, GPIO, RECO_CLK, MIIM, NONE, NONE, NONE, NONE, R); +LAN9645X_P(30, GPIO, PTP0, I2C, UART, NONE, NONE, NONE, R); +LAN9645X_P(31, GPIO, PTP1, TWI_SCL_M, UART, NONE, NONE, NONE, R); +LAN9645X_P(32, GPIO, PTP2, TWI_SCL_M, NONE, NONE, NONE, NONE, R); +LAN9645X_P(33, GPIO, PTP3, IRQ0, NONE, NONE, NONE, NONE, R); +LAN9645X_P(34, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, NONE, NONE, R); +LAN9645X_P(35, GPIO, RECO_CLK, PHY_LED, PHY_LED, NONE, MACLED, NONE, R); +LAN9645X_P(36, GPIO, PTP0, PHY_LED, PHY_LED, NONE, MACLED, NONE, R); +LAN9645X_P(37, GPIO, PTP1, PHY_LED, PHY_LED, NONE, MACLED, NONE, R); +LAN9645X_P(38, GPIO, NONE, PHY_LED, PHY_LED, NONE, MACLED, NONE, R); +LAN9645X_P(39, GPIO, UART, PHY_LED, NONE, NONE, MACLED, NONE, R); +LAN9645X_P(40, GPIO, SPI, PHY_LED, SGPIO_a, NONE, MACLED, NONE, R); +LAN9645X_P(41, GPIO, SPI, PHY_LED, SGPIO_a, IRQ1, MACLED, NONE, R); +LAN9645X_P(42, GPIO, SPI, PHY_LED, SGPIO_a, IRQ2, MACLED, SFP, R); +LAN9645X_P(43, GPIO, SPI, PHY_LED, SGPIO_a, IRQ3, MACLED, SFP, R); +LAN9645X_P(44, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R); +LAN9645X_P(45, GPIO, MIIM, I2C, NONE, NONE, NONE, NONE, R); +LAN9645X_P(46, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R); +LAN9645X_P(47, GPIO, NONE, PHY_LED, NONE, NONE, NONE, NONE, R); +LAN9645X_P(48, GPIO, MIIM_Sa, PHY_LED, NONE, NONE, NONE, NONE, R); +LAN9645X_P(49, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R); +LAN9645X_P(50, GPIO, MIIM_Sa, PHY_LED, I2C_Sa, NONE, NONE, NONE, R); + +#define LAN9645X_PIN(n) { \ + .number = n, \ + .name = "GPIO_"#n, \ + .drv_data = &lan9645x_pin_##n \ +} + +static const struct pinctrl_pin_desc lan9645x_pins[] = { + LAN9645X_PIN(0), + LAN9645X_PIN(1), + LAN9645X_PIN(2), + LAN9645X_PIN(3), + LAN9645X_PIN(4), + LAN9645X_PIN(5), + LAN9645X_PIN(6), + LAN9645X_PIN(7), + LAN9645X_PIN(8), + LAN9645X_PIN(9), + LAN9645X_PIN(10), + LAN9645X_PIN(11), + LAN9645X_PIN(12), + LAN9645X_PIN(13), + LAN9645X_PIN(14), + LAN9645X_PIN(15), + LAN9645X_PIN(16), + LAN9645X_PIN(17), + LAN9645X_PIN(18), + LAN9645X_PIN(19), + LAN9645X_PIN(20), + LAN9645X_PIN(21), + LAN9645X_PIN(22), + LAN9645X_PIN(23), + LAN9645X_PIN(24), + LAN9645X_PIN(25), + LAN9645X_PIN(26), + LAN9645X_PIN(27), + LAN9645X_PIN(28), + LAN9645X_PIN(29), + LAN9645X_PIN(30), + LAN9645X_PIN(31), + LAN9645X_PIN(32), + LAN9645X_PIN(33), + LAN9645X_PIN(34), + LAN9645X_PIN(35), + LAN9645X_PIN(36), + LAN9645X_PIN(37), + LAN9645X_PIN(38), + LAN9645X_PIN(39), + LAN9645X_PIN(40), + LAN9645X_PIN(41), + LAN9645X_PIN(42), + LAN9645X_PIN(43), + LAN9645X_PIN(44), + LAN9645X_PIN(45), + LAN9645X_PIN(46), + LAN9645X_PIN(47), + LAN9645X_PIN(48), + LAN9645X_PIN(49), + LAN9645X_PIN(50), +}; + static int ocelot_get_functions_count(struct pinctrl_dev *pctldev) { return ARRAY_SIZE(ocelot_function_names); @@ -1362,7 +1506,7 @@ static int ocelot_pin_function_idx(struct ocelot_pinctrl *info, return -1; } -#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->stride * ((p) / 32)))) +#define REG_ALT(msb, info, p) (OCELOT_GPIO_ALT0 * (info)->stride + 4 * ((msb) + ((info)->altm_stride * ((p) / 32)))) static int ocelot_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int selector, unsigned int group) @@ -1469,6 +1613,13 @@ static int lan966x_gpio_request_enable(struct pinctrl_dev *pctldev, return 0; } +static int lan9645x_gpio_request_enable(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned int offset) +{ + return 0; +} + static const struct pinmux_ops ocelot_pmx_ops = { .get_functions_count = ocelot_get_functions_count, .get_function_name = ocelot_get_function_name, @@ -1487,6 +1638,15 @@ static const struct pinmux_ops lan966x_pmx_ops = { .gpio_request_enable = lan966x_gpio_request_enable, }; +static const struct pinmux_ops lan9645x_pmx_ops = { + .get_functions_count = ocelot_get_functions_count, + .get_function_name = ocelot_get_function_name, + .get_function_groups = ocelot_get_function_groups, + .set_mux = lan966x_pinmux_set_mux, + .gpio_set_direction = ocelot_gpio_set_direction, + .gpio_request_enable = lan9645x_gpio_request_enable, +}; + static int ocelot_pctl_get_groups_count(struct pinctrl_dev *pctldev) { struct ocelot_pinctrl *info = pinctrl_dev_get_drvdata(pctldev); @@ -1884,6 +2044,24 @@ static const struct ocelot_match_data lan969x_desc = { }, }; +static struct ocelot_match_data lan9645xf_desc = { + .desc = { + .name = "lan9645xf-pinctrl", + .pins = lan9645x_pins, + .npins = ARRAY_SIZE(lan9645x_pins), + .pctlops = &ocelot_pctl_ops, + .pmxops = &lan9645x_pmx_ops, + .confops = &ocelot_confops, + .owner = THIS_MODULE, + }, + .pincfg_data = { + .pd_bit = BIT(3), + .pu_bit = BIT(2), + .drive_bits = GENMASK(1, 0), + }, + .n_alt_modes = 7, +}; + static int ocelot_create_group_func_map(struct device *dev, struct ocelot_pinctrl *info) { @@ -2084,7 +2262,7 @@ static void ocelot_irq_unmask_level(struct irq_data *data) if (active) { struct ocelot_irq_work *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return; @@ -2218,6 +2396,7 @@ static const struct of_device_id ocelot_pinctrl_of_match[] = { { .compatible = "microchip,sparx5-pinctrl", .data = &sparx5_desc }, { .compatible = "microchip,lan966x-pinctrl", .data = &lan966x_desc }, { .compatible = "microchip,lan9691-pinctrl", .data = &lan969x_desc }, + { .compatible = "microchip,lan96455f-pinctrl", .data = &lan9645xf_desc }, {}, }; MODULE_DEVICE_TABLE(of, ocelot_pinctrl_of_match); @@ -2294,6 +2473,9 @@ static int ocelot_pinctrl_probe(struct platform_device *pdev) reset_control_reset(reset); info->stride = 1 + (info->desc->npins - 1) / 32; + info->altm_stride = info->stride; + if (data->n_alt_modes) + info->altm_stride = fls(data->n_alt_modes); regmap_config.max_register = OCELOT_GPIO_SD_MAP * info->stride + 15 * 4; diff --git a/drivers/pinctrl/pinctrl-pic32.c b/drivers/pinctrl/pinctrl-pic32.c index e8b481e87c77..16bbbcf72062 100644 --- a/drivers/pinctrl/pinctrl-pic32.c +++ b/drivers/pinctrl/pinctrl-pic32.c @@ -15,13 +15,12 @@ #include #include #include +#include #include #include #include #include -#include - #include "pinctrl-utils.h" #include "pinctrl-pic32.h" diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c index 2fc67aeafdb3..f15b18f334ee 100644 --- a/drivers/pinctrl/pinctrl-rockchip.c +++ b/drivers/pinctrl/pinctrl-rockchip.c @@ -415,7 +415,7 @@ static int rockchip_dt_node_to_map(struct pinctrl_dev *pctldev, map_num += grp->npins; - new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); + new_map = kzalloc_objs(*new_map, map_num); if (!new_map) return -ENOMEM; @@ -3604,7 +3604,7 @@ static int rockchip_pinconf_defer_pin(struct rockchip_pin_bank *bank, { struct rockchip_pin_deferred *cfg; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; @@ -3639,17 +3639,12 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin, * The lock makes sure that either gpio-probe has completed * or the gpio driver hasn't probed yet. */ - mutex_lock(&bank->deferred_lock); - if (!gpio || !gpio->direction_output) { - rc = rockchip_pinconf_defer_pin(bank, pin - bank->pin_base, param, - arg); - mutex_unlock(&bank->deferred_lock); - if (rc) - return rc; - - break; + scoped_guard(mutex, &bank->deferred_lock) { + if (!gpio || !gpio->direction_output) + return rockchip_pinconf_defer_pin(bank, + pin - bank->pin_base, + param, arg); } - mutex_unlock(&bank->deferred_lock); } switch (param) { diff --git a/drivers/pinctrl/pinctrl-rp1.c b/drivers/pinctrl/pinctrl-rp1.c index ffc2f0b460a6..fc4ed68ea5ac 100644 --- a/drivers/pinctrl/pinctrl-rp1.c +++ b/drivers/pinctrl/pinctrl-rp1.c @@ -1158,7 +1158,7 @@ static int rp1_pctl_legacy_map_pull(struct rp1_pinctrl *pc, return -EINVAL; } - configs = kzalloc(sizeof(*configs), GFP_KERNEL); + configs = kzalloc_obj(*configs); if (!configs) return -ENOMEM; @@ -1233,7 +1233,7 @@ static int rp1_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, if (num_configs || num_pulls) maps_per_pin++; reserved_maps = num_pins * maps_per_pin; - maps = kcalloc(reserved_maps, sizeof(*maps), GFP_KERNEL); + maps = kzalloc_objs(*maps, reserved_maps); if (!maps) return -ENOMEM; diff --git a/drivers/pinctrl/pinctrl-scmi.c b/drivers/pinctrl/pinctrl-scmi.c index af3ac031e362..f4f296e07be5 100644 --- a/drivers/pinctrl/pinctrl-scmi.c +++ b/drivers/pinctrl/pinctrl-scmi.c @@ -319,7 +319,7 @@ pinctrl_scmi_alloc_configs(struct pinctrl_dev *pctldev, u32 num_configs, if (!*p_config_value) return -ENOMEM; - *p_config_type = kcalloc(num_configs, sizeof(**p_config_type), GFP_KERNEL); + *p_config_type = kzalloc_objs(**p_config_type, num_configs); if (!*p_config_type) { kfree(*p_config_value); return -ENOMEM; @@ -504,8 +504,9 @@ static int pinctrl_scmi_get_pins(struct scmi_pinctrl *pmx, } static const char * const scmi_pinctrl_blocklist[] = { - "fsl,imx95", "fsl,imx94", + "fsl,imx95", + "fsl,imx952", NULL }; diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c index 998f23d6c317..d85e6c1f6321 100644 --- a/drivers/pinctrl/pinctrl-single.c +++ b/drivers/pinctrl/pinctrl-single.c @@ -1359,6 +1359,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) } range = devm_kzalloc(pcs->dev, sizeof(*range), GFP_KERNEL); if (!range) { + of_node_put(gpiospec.np); ret = -ENOMEM; break; } @@ -1368,6 +1369,7 @@ static int pcs_add_gpio_func(struct device_node *node, struct pcs_device *pcs) mutex_lock(&pcs->mutex); list_add_tail(&range->node, &pcs->gpiofuncs); mutex_unlock(&pcs->mutex); + of_node_put(gpiospec.np); } return ret; } diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index d3cea3437d7f..8ce88e591f47 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -987,6 +987,7 @@ static int st_pinconf_get(struct pinctrl_dev *pctldev, static void st_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin_id) + __must_hold(&pctldev->mutex) { struct st_pio_control *pc; unsigned long config; diff --git a/drivers/pinctrl/pinctrl-tb10x.c b/drivers/pinctrl/pinctrl-tb10x.c index 129fa51d13b1..3f581404a9b9 100644 --- a/drivers/pinctrl/pinctrl-tb10x.c +++ b/drivers/pinctrl/pinctrl-tb10x.c @@ -607,7 +607,7 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl, int muxmode = -1; int i; - mutex_lock(&state->mutex); + guard(mutex)(&state->mutex); /* * Figure out to which port the requested GPIO belongs and how to @@ -642,7 +642,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl, * Error: The requested pin is already * used for something else. */ - mutex_unlock(&state->mutex); return -EBUSY; } break; @@ -667,8 +666,6 @@ static int tb10x_gpio_request_enable(struct pinctrl_dev *pctl, if (muxport >= 0) tb10x_pinctrl_set_config(state, muxport, muxmode); - mutex_unlock(&state->mutex); - return 0; } @@ -695,34 +692,28 @@ static int tb10x_pctl_set_mux(struct pinctrl_dev *pctl, if (grp->port < 0) return 0; - mutex_lock(&state->mutex); + guard(mutex)(&state->mutex); /* * Check if the requested function is compatible with previously * requested functions. */ if (state->ports[grp->port].count - && (state->ports[grp->port].mode != grp->mode)) { - mutex_unlock(&state->mutex); + && (state->ports[grp->port].mode != grp->mode)) return -EBUSY; - } /* * Check if the requested function is compatible with previously * requested GPIOs. */ for (i = 0; i < grp->pincnt; i++) - if (test_bit(grp->pins[i], state->gpios)) { - mutex_unlock(&state->mutex); + if (test_bit(grp->pins[i], state->gpios)) return -EBUSY; - } tb10x_pinctrl_set_config(state, grp->port, grp->mode); state->ports[grp->port].count++; - mutex_unlock(&state->mutex); - return 0; } diff --git a/drivers/pinctrl/pinctrl-th1520.c b/drivers/pinctrl/pinctrl-th1520.c index 83e9c9f77370..4d5a99483dee 100644 --- a/drivers/pinctrl/pinctrl-th1520.c +++ b/drivers/pinctrl/pinctrl-th1520.c @@ -447,7 +447,7 @@ static int th1520_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, nmaps += npins; } - map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, nmaps); if (!map) return -ENOMEM; diff --git a/drivers/pinctrl/qcom/pinctrl-glymur.c b/drivers/pinctrl/qcom/pinctrl-glymur.c index 335005084b6b..44f9745325b7 100644 --- a/drivers/pinctrl/qcom/pinctrl-glymur.c +++ b/drivers/pinctrl/qcom/pinctrl-glymur.c @@ -1729,6 +1729,26 @@ static const struct msm_gpio_wakeirq_map glymur_pdc_map[] = { { 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 }, }; +static const struct msm_gpio_wakeirq_map mahua_pdc_map[] = { + { 0, 116 }, { 2, 114 }, { 3, 115 }, { 4, 175 }, { 5, 176 }, + { 7, 111 }, { 11, 129 }, { 13, 130 }, { 15, 112 }, { 19, 113 }, + { 23, 187 }, { 27, 188 }, { 28, 121 }, { 29, 122 }, { 30, 136 }, + { 31, 203 }, { 32, 189 }, { 34, 174 }, { 35, 190 }, { 36, 191 }, + { 39, 124 }, { 43, 192 }, { 47, 193 }, { 51, 123 }, { 53, 133 }, + { 55, 125 }, { 59, 131 }, { 64, 134 }, { 65, 150 }, { 66, 186 }, + { 67, 132 }, { 68, 195 }, { 71, 135 }, { 75, 196 }, { 79, 197 }, + { 83, 198 }, { 84, 181 }, { 85, 199 }, { 87, 200 }, { 91, 201 }, + { 92, 182 }, { 93, 183 }, { 94, 184 }, { 95, 185 }, { 98, 202 }, + { 105, 157 }, { 113, 128 }, { 121, 117 }, { 123, 118 }, { 125, 119 }, + { 129, 120 }, { 131, 126 }, { 132, 160 }, { 133, 194 }, { 134, 127 }, + { 141, 137 }, { 144, 138 }, { 145, 139 }, { 147, 140 }, { 148, 141 }, + { 150, 146 }, { 151, 147 }, { 153, 148 }, { 154, 144 }, { 155, 159 }, + { 156, 149 }, { 157, 151 }, { 163, 142 }, { 172, 143 }, { 181, 145 }, + { 193, 161 }, { 196, 152 }, { 203, 177 }, { 208, 178 }, { 215, 162 }, + { 217, 153 }, { 220, 154 }, { 221, 155 }, { 228, 179 }, { 230, 180 }, + { 232, 206 }, { 234, 172 }, { 235, 173 }, { 242, 158 }, { 244, 156 }, +}; + static const struct msm_pinctrl_soc_data glymur_tlmm = { .pins = glymur_pins, .npins = ARRAY_SIZE(glymur_pins), @@ -1742,14 +1762,34 @@ static const struct msm_pinctrl_soc_data glymur_tlmm = { .egpio_func = 11, }; +static const struct msm_pinctrl_soc_data mahua_tlmm = { + .pins = glymur_pins, + .npins = ARRAY_SIZE(glymur_pins), + .functions = glymur_functions, + .nfunctions = ARRAY_SIZE(glymur_functions), + .groups = glymur_groups, + .ngroups = ARRAY_SIZE(glymur_groups), + .ngpios = 251, + .wakeirq_map = mahua_pdc_map, + .nwakeirq_map = ARRAY_SIZE(mahua_pdc_map), + .egpio_func = 11, +}; + static const struct of_device_id glymur_tlmm_of_match[] = { - { .compatible = "qcom,glymur-tlmm", }, - { } + { .compatible = "qcom,glymur-tlmm", .data = &glymur_tlmm }, + { .compatible = "qcom,mahua-tlmm", .data = &mahua_tlmm }, + { }, }; static int glymur_tlmm_probe(struct platform_device *pdev) { - return msm_pinctrl_probe(pdev, &glymur_tlmm); + const struct msm_pinctrl_soc_data *data; + + data = of_device_get_match_data(&pdev->dev); + if (!data) + return -ENODEV; + + return msm_pinctrl_probe(pdev, data); } static struct platform_driver glymur_tlmm_driver = { diff --git a/drivers/pinctrl/qcom/pinctrl-qcs615.c b/drivers/pinctrl/qcom/pinctrl-qcs615.c index 4dfa820d4e77..f1c827ddbfbf 100644 --- a/drivers/pinctrl/qcom/pinctrl-qcs615.c +++ b/drivers/pinctrl/qcom/pinctrl-qcs615.c @@ -1067,6 +1067,7 @@ static const struct msm_pinctrl_soc_data qcs615_tlmm = { .ntiles = ARRAY_SIZE(qcs615_tiles), .wakeirq_map = qcs615_pdc_map, .nwakeirq_map = ARRAY_SIZE(qcs615_pdc_map), + .wakeirq_dual_edge_errata = true, }; static const struct of_device_id qcs615_tlmm_of_match[] = { diff --git a/drivers/pinctrl/qcom/pinctrl-sdm660-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sdm660-lpass-lpi.c index d93af5f0e8d3..65411abfbfac 100644 --- a/drivers/pinctrl/qcom/pinctrl-sdm660-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-sdm660-lpass-lpi.c @@ -76,7 +76,7 @@ static const char * const pdm_clk_groups[] = { "gpio18" }; static const char * const pdm_rx_groups[] = { "gpio21", "gpio23", "gpio25" }; static const char * const pdm_sync_groups[] = { "gpio19" }; -const struct lpi_pingroup sdm660_lpi_pinctrl_groups[] = { +static const struct lpi_pingroup sdm660_lpi_pinctrl_groups[] = { LPI_PINGROUP_OFFSET(0, LPI_NO_SLEW, _, _, _, _, 0x0000), LPI_PINGROUP_OFFSET(1, LPI_NO_SLEW, _, _, _, _, 0x1000), LPI_PINGROUP_OFFSET(2, LPI_NO_SLEW, _, _, _, _, 0x2000), @@ -113,7 +113,7 @@ const struct lpi_pingroup sdm660_lpi_pinctrl_groups[] = { LPI_PINGROUP_OFFSET(31, LPI_NO_SLEW, _, _, _, _, 0xb010), }; -const struct lpi_function sdm660_lpi_pinctrl_functions[] = { +static const struct lpi_function sdm660_lpi_pinctrl_functions[] = { LPI_FUNCTION(comp_rx), LPI_FUNCTION(dmic1_clk), LPI_FUNCTION(dmic1_data), diff --git a/drivers/pinctrl/qcom/pinctrl-sm8250-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sm8250-lpass-lpi.c index 64494a86490e..c27452eece3e 100644 --- a/drivers/pinctrl/qcom/pinctrl-sm8250-lpass-lpi.c +++ b/drivers/pinctrl/qcom/pinctrl-sm8250-lpass-lpi.c @@ -73,7 +73,7 @@ static const char * const i2s1_ws_groups[] = { "gpio7" }; static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" }; static const char * const wsa_swr_clk_groups[] = { "gpio10" }; static const char * const wsa_swr_data_groups[] = { "gpio11" }; -static const char * const i2s2_data_groups[] = { "gpio12", "gpio12" }; +static const char * const i2s2_data_groups[] = { "gpio12", "gpio13" }; static const struct lpi_pingroup sm8250_groups[] = { LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _), diff --git a/drivers/pinctrl/renesas/Kconfig b/drivers/pinctrl/renesas/Kconfig index 8cbd79a13414..d979e25e5088 100644 --- a/drivers/pinctrl/renesas/Kconfig +++ b/drivers/pinctrl/renesas/Kconfig @@ -308,9 +308,11 @@ config PINCTRL_RZT2H bool "pin control support for RZ/N2H and RZ/T2H" if COMPILE_TEST depends on 64BIT && OF select GPIOLIB + select GPIOLIB_IRQCHIP select GENERIC_PINCTRL_GROUPS select GENERIC_PINMUX_FUNCTIONS select GENERIC_PINCONF + select IRQ_DOMAIN_HIERARCHY help This selects GPIO and pinctrl driver for Renesas RZ/T2H platforms. diff --git a/drivers/pinctrl/renesas/core.c b/drivers/pinctrl/renesas/core.c index 96d6040a8871..0840668638d9 100644 --- a/drivers/pinctrl/renesas/core.c +++ b/drivers/pinctrl/renesas/core.c @@ -1273,8 +1273,7 @@ static void __init sh_pfc_check_driver(const struct platform_driver *pdrv) !of_find_matching_node(NULL, pdrv->driver.of_match_table)) return; - sh_pfc_regs = kcalloc(SH_PFC_MAX_REGS, sizeof(*sh_pfc_regs), - GFP_KERNEL); + sh_pfc_regs = kzalloc_objs(*sh_pfc_regs, SH_PFC_MAX_REGS); if (!sh_pfc_regs) return; diff --git a/drivers/pinctrl/renesas/pinctrl-rza1.c b/drivers/pinctrl/renesas/pinctrl-rza1.c index 3cfa4c8be80e..bc8b9b9ad05b 100644 --- a/drivers/pinctrl/renesas/pinctrl-rza1.c +++ b/drivers/pinctrl/renesas/pinctrl-rza1.c @@ -1062,7 +1062,7 @@ static int rza1_dt_node_to_map(struct pinctrl_dev *pctldev, /* Create map where to retrieve function and mux settings from */ *num_maps = 0; - *map = kzalloc(sizeof(**map), GFP_KERNEL); + *map = kzalloc_obj(**map); if (!*map) { ret = -ENOMEM; goto remove_function; diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c index 29a9db197599..8618f32ed26a 100644 --- a/drivers/pinctrl/renesas/pinctrl-rza2.c +++ b/drivers/pinctrl/renesas/pinctrl-rza2.c @@ -395,7 +395,7 @@ static int rza2_dt_node_to_map(struct pinctrl_dev *pctldev, /* Create map where to retrieve function and mux settings from */ *num_maps = 0; - *map = kzalloc(sizeof(**map), GFP_KERNEL); + *map = kzalloc_obj(**map); if (!*map) { ret = -ENOMEM; goto remove_function; diff --git a/drivers/pinctrl/renesas/pinctrl-rzt2h.c b/drivers/pinctrl/renesas/pinctrl-rzt2h.c index 4826ff91cd90..9949108a35bb 100644 --- a/drivers/pinctrl/renesas/pinctrl-rzt2h.c +++ b/drivers/pinctrl/renesas/pinctrl-rzt2h.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ #define PFC_MASK GENMASK_ULL(5, 0) #define PFC_PIN_MASK(pin) (PFC_MASK << ((pin) * 8)) +#define PFC_FUNC_INTERRUPT 0 /* * Use 16 lower bits [15:0] for pin identifier @@ -64,6 +66,9 @@ #define RZT2H_MAX_SAFETY_PORTS 12 +#define RZT2H_INTERRUPTS_START 16 +#define RZT2H_INTERRUPTS_NUM 17 + struct rzt2h_pinctrl_data { unsigned int n_port_pins; const u8 *port_pin_configs; @@ -79,9 +84,11 @@ struct rzt2h_pinctrl { struct device *dev; struct gpio_chip gpio_chip; struct pinctrl_gpio_range gpio_range; + DECLARE_BITMAP(used_irqs, RZT2H_INTERRUPTS_NUM); spinlock_t lock; /* lock read/write registers */ struct mutex mutex; /* serialize adding groups and functions */ bool safety_port_enabled; + atomic_t wakeup_path; }; #define RZT2H_GET_BASE(pctrl, port) \ @@ -119,6 +126,19 @@ static int rzt2h_validate_pin(struct rzt2h_pinctrl *pctrl, unsigned int offset) return (pincfg & BIT(pin)) ? 0 : -EINVAL; } +static void rzt2h_pinctrl_set_gpio_en(struct rzt2h_pinctrl *pctrl, + u8 port, u8 pin, bool en) +{ + u8 reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); + + if (en) + reg &= ~BIT(pin); + else + reg |= BIT(pin); + + rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port)); +} + static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, u8 port, u8 pin, u8 func) { @@ -133,8 +153,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, rzt2h_pinctrl_writew(pctrl, port, reg16, PM(port)); /* Temporarily switch to GPIO mode with PMC register */ - reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - rzt2h_pinctrl_writeb(pctrl, port, reg16 & ~BIT(pin), PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, true); /* Select Pin function mode with PFC register */ reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port)); @@ -142,8 +161,7 @@ static void rzt2h_pinctrl_set_pfc_mode(struct rzt2h_pinctrl *pctrl, rzt2h_pinctrl_writeq(pctrl, port, reg64 | ((u64)func << (pin * 8)), PFC(port)); /* Switch to Peripheral pin function with PMC register */ - reg16 = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - rzt2h_pinctrl_writeb(pctrl, port, reg16 | BIT(pin), PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false); } static int rzt2h_pinctrl_set_mux(struct pinctrl_dev *pctldev, @@ -447,7 +465,6 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset) u8 port = RZT2H_PIN_ID_TO_PORT(offset); u8 bit = RZT2H_PIN_ID_TO_PIN(offset); int ret; - u8 reg; ret = rzt2h_validate_pin(pctrl, offset); if (ret) @@ -460,9 +477,7 @@ static int rzt2h_gpio_request(struct gpio_chip *chip, unsigned int offset) guard(spinlock_irqsave)(&pctrl->lock); /* Select GPIO mode in PMC Register */ - reg = rzt2h_pinctrl_readb(pctrl, port, PMC(port)); - reg &= ~BIT(bit); - rzt2h_pinctrl_writeb(pctrl, port, reg, PMC(port)); + rzt2h_pinctrl_set_gpio_en(pctrl, port, bit, true); return 0; } @@ -486,6 +501,7 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) struct rzt2h_pinctrl *pctrl = gpiochip_get_data(chip); u8 port = RZT2H_PIN_ID_TO_PORT(offset); u8 bit = RZT2H_PIN_ID_TO_PIN(offset); + u64 reg64; u16 reg; int ret; @@ -493,8 +509,25 @@ static int rzt2h_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) if (ret) return ret; - if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) + guard(spinlock_irqsave)(&pctrl->lock); + + if (rzt2h_pinctrl_readb(pctrl, port, PMC(port)) & BIT(bit)) { + /* + * When a GPIO is being requested as an IRQ, the pinctrl + * framework expects to be able to read the GPIO's direction. + * IRQ function is separate from GPIO, and enabling it takes the + * pin out of GPIO mode. + * At this point, .child_to_parent_hwirq() has already been + * called to enable the IRQ function. + * Default to input direction for IRQ function. + */ + reg64 = rzt2h_pinctrl_readq(pctrl, port, PFC(port)); + reg64 = (reg64 >> (bit * 8)) & PFC_MASK; + if (reg64 == PFC_FUNC_INTERRUPT) + return GPIO_LINE_DIRECTION_IN; + return -EINVAL; + } reg = rzt2h_pinctrl_readw(pctrl, port, PM(port)); reg = (reg >> (bit * 2)) & PM_MASK; @@ -617,14 +650,185 @@ static const char * const rzt2h_gpio_names[] = { "P35_0", "P35_1", "P35_2", "P35_3", "P35_4", "P35_5", "P35_6", "P35_7", }; +/* + * Interrupts 0-15 are for INTCPUn, which are not exposed externally. + * Interrupts 16-31 are for IRQn. SEI is 32. + * This table matches the information found in User Manual's Section + * 17.5, Multiplexed Pin Configurations, Tables 17.5 to 17.40, on the + * Interrupt rows. + * RZ/N2H has the same GPIO to IRQ mapping, except for the pins which + * are not present. + */ +static const u8 rzt2h_gpio_irq_map[] = { + 32, 16, 17, 18, 19, 0, 20, 21, + 22, 0, 0, 0, 0, 0, 0, 0, + 23, 24, 25, 26, 27, 0, 0, 0, + 0, 0, 28, 29, 30, 31, 0, 0, + 0, 0, 0, 0, 0, 32, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, + 0, 0, 24, 25, 26, 27, 0, 28, + 29, 30, 31, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 24, 32, 16, + 0, 0, 0, 0, 0, 0, 0, 0, + 20, 23, 17, 18, 19, 0, 16, 25, + 29, 20, 21, 22, 23, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 0, 18, + 0, 0, 19, 0, 0, 20, 0, 30, + 21, 0, 0, 22, 0, 0, 24, 25, + 0, 0, 0, 0, 0, 16, 17, 0, + 18, 0, 0, 26, 27, 0, 0, 0, + 28, 29, 30, 31, 0, 0, 0, 0, + 23, 31, 32, 16, 17, 18, 19, 20, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 27, 0, 0, 21, 22, 23, 24, 25, + 26, 0, 0, 0, 0, 0, 0, 0, + 27, 28, 29, 30, 31, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 28, 32, 16, + 17, 18, 19, 0, 0, 0, 0, 20, + 21, 22, 23, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 24, 25, 0, 0, + 0, 0, 26, 27, 0, 0, 0, 30, + 0, 29, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 28, 29, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 30, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static void rzt2h_gpio_irq_disable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + irq_chip_disable_parent(d); + gpiochip_disable_irq(gc, hwirq); +} + +static void rzt2h_gpio_irq_enable(struct irq_data *d) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + unsigned int hwirq = irqd_to_hwirq(d); + + gpiochip_enable_irq(gc, hwirq); + irq_chip_enable_parent(d); +} + +static int rzt2h_gpio_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip); + int ret; + + ret = irq_chip_set_wake_parent(d, on); + if (ret) + return ret; + + /* + * If any of the IRQs are in use, put the entire pin controller on the + * device wakeup path. + */ + if (on) + atomic_inc(&pctrl->wakeup_path); + else + atomic_dec(&pctrl->wakeup_path); + + return 0; +} + +static const struct irq_chip rzt2h_gpio_irqchip = { + .name = "rzt2h-gpio", + .irq_disable = rzt2h_gpio_irq_disable, + .irq_enable = rzt2h_gpio_irq_enable, + .irq_mask = irq_chip_mask_parent, + .irq_unmask = irq_chip_unmask_parent, + .irq_set_type = irq_chip_set_type_parent, + .irq_set_wake = rzt2h_gpio_irq_set_wake, + .irq_eoi = irq_chip_eoi_parent, + .irq_set_affinity = irq_chip_set_affinity_parent, + .flags = IRQCHIP_IMMUTABLE, + GPIOCHIP_IRQ_RESOURCE_HELPERS, +}; + +static int rzt2h_gpio_child_to_parent_hwirq(struct gpio_chip *gc, + unsigned int child, + unsigned int child_type, + unsigned int *parent, + unsigned int *parent_type) +{ + struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc); + u8 port = RZT2H_PIN_ID_TO_PORT(child); + u8 pin = RZT2H_PIN_ID_TO_PIN(child); + u8 parent_irq; + + parent_irq = rzt2h_gpio_irq_map[child]; + if (parent_irq < RZT2H_INTERRUPTS_START) + return -EINVAL; + + if (test_and_set_bit(parent_irq - RZT2H_INTERRUPTS_START, + pctrl->used_irqs)) + return -EBUSY; + + rzt2h_pinctrl_set_pfc_mode(pctrl, port, pin, PFC_FUNC_INTERRUPT); + + *parent = parent_irq; + *parent_type = child_type; + + return 0; +} + +static void rzt2h_gpio_irq_domain_free(struct irq_domain *domain, unsigned int virq, + unsigned int nr_irqs) +{ + struct irq_data *d = irq_domain_get_irq_data(domain, virq); + struct gpio_chip *gc = irq_data_get_irq_chip_data(d); + struct rzt2h_pinctrl *pctrl = container_of(gc, struct rzt2h_pinctrl, gpio_chip); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + u8 port = RZT2H_PIN_ID_TO_PORT(hwirq); + u8 pin = RZT2H_PIN_ID_TO_PIN(hwirq); + + if (test_and_clear_bit(hwirq - RZT2H_INTERRUPTS_START, pctrl->used_irqs)) + rzt2h_pinctrl_set_gpio_en(pctrl, port, pin, false); + + irq_domain_free_irqs_common(domain, virq, nr_irqs); +} + +static void rzt2h_gpio_init_irq_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct rzt2h_pinctrl *pctrl = gpiochip_get_data(gc); + unsigned int offset; + + for (offset = 0; offset < ngpios; offset++) { + if (!rzt2h_gpio_irq_map[offset] || rzt2h_validate_pin(pctrl, offset)) + clear_bit(offset, valid_mask); + } +} + static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl) { struct pinctrl_gpio_range *range = &pctrl->gpio_range; struct gpio_chip *chip = &pctrl->gpio_chip; + struct device_node *np = pctrl->dev->of_node; + struct irq_domain *parent_domain; struct device *dev = pctrl->dev; struct of_phandle_args of_args; + struct device_node *parent_np; + struct gpio_irq_chip *girq; int ret; + parent_np = of_irq_find_parent(np); + if (!parent_np) + return -ENXIO; + + parent_domain = irq_find_host(parent_np); + of_node_put(parent_np); + if (!parent_domain) + return -EPROBE_DEFER; + ret = of_parse_phandle_with_fixed_args(dev->of_node, "gpio-ranges", 3, 0, &of_args); if (ret) return dev_err_probe(dev, ret, "Unable to parse gpio-ranges\n"); @@ -648,6 +852,17 @@ static int rzt2h_gpio_register(struct rzt2h_pinctrl *pctrl) chip->set = rzt2h_gpio_set; chip->label = dev_name(dev); + if (of_property_present(np, "interrupt-controller")) { + girq = &chip->irq; + gpio_irq_chip_set_chip(girq, &rzt2h_gpio_irqchip); + girq->fwnode = dev_fwnode(pctrl->dev); + girq->parent_domain = parent_domain; + girq->child_to_parent_hwirq = rzt2h_gpio_child_to_parent_hwirq; + girq->populate_parent_alloc_arg = gpiochip_populate_parent_fwspec_twocell; + girq->child_irq_domain_ops.free = rzt2h_gpio_irq_domain_free; + girq->init_valid_mask = rzt2h_gpio_init_irq_valid_mask; + } + range->id = 0; range->pin_base = 0; range->base = 0; @@ -792,10 +1007,25 @@ static const struct of_device_id rzt2h_pinctrl_of_table[] = { { /* sentinel */ } }; +static int rzt2h_pinctrl_suspend_noirq(struct device *dev) +{ + struct rzt2h_pinctrl *pctrl = dev_get_drvdata(dev); + + if (atomic_read(&pctrl->wakeup_path)) + device_set_wakeup_path(dev); + + return 0; +} + +static const struct dev_pm_ops rzt2h_pinctrl_pm_ops = { + NOIRQ_SYSTEM_SLEEP_PM_OPS(rzt2h_pinctrl_suspend_noirq, NULL) +}; + static struct platform_driver rzt2h_pinctrl_driver = { .driver = { .name = DRV_NAME, .of_match_table = of_match_ptr(rzt2h_pinctrl_of_table), + .pm = pm_sleep_ptr(&rzt2h_pinctrl_pm_ops), .suppress_bind_attrs = true, }, .probe = rzt2h_pinctrl_probe, diff --git a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c index 627dca504d7a..fe9f92cb037e 100644 --- a/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c +++ b/drivers/pinctrl/samsung/pinctrl-exynos-arm64.c @@ -1770,6 +1770,123 @@ const struct samsung_pinctrl_of_match_data exynos8895_of_data __initconst = { .num_ctrl = ARRAY_SIZE(exynos8895_pin_ctrl), }; +/* pin banks of exynos9610 pin-controller 0 (ALIVE) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks0[] __initconst = { + EXYNOS850_PIN_BANK_EINTN(6, 0x000, "etc0"), + GS101_PIN_BANK_EINTW(8, 0x020, "gpa0", 0x00, 0x00), + GS101_PIN_BANK_EINTW(8, 0x040, "gpa1", 0x04, 0x08), + GS101_PIN_BANK_EINTW(8, 0x060, "gpa2", 0x08, 0x0c), + EXYNOS850_PIN_BANK_EINTN(5, 0x080, "gpq0"), +}; + +/* pin banks of exynos9610 pin-controller 1 (CMGP) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks1[] __initconst = { + EXYNOS850_PIN_BANK_EINTW(1, 0x000, "gpm0", 0x00), + EXYNOS850_PIN_BANK_EINTW(1, 0x020, "gpm1", 0x04), + EXYNOS850_PIN_BANK_EINTW(1, 0x040, "gpm2", 0x08), + EXYNOS850_PIN_BANK_EINTW(1, 0x060, "gpm3", 0x0C), + EXYNOS850_PIN_BANK_EINTW(1, 0x080, "gpm4", 0x10), + EXYNOS850_PIN_BANK_EINTW(1, 0x0A0, "gpm5", 0x14), + EXYNOS850_PIN_BANK_EINTW(1, 0x0C0, "gpm6", 0x18), + EXYNOS850_PIN_BANK_EINTW(1, 0x0E0, "gpm7", 0x1C), + EXYNOS850_PIN_BANK_EINTW(1, 0x100, "gpm8", 0x20), + EXYNOS850_PIN_BANK_EINTW(1, 0x120, "gpm9", 0x24), + EXYNOS850_PIN_BANK_EINTW(1, 0x140, "gpm10", 0x28), + EXYNOS850_PIN_BANK_EINTW(1, 0x160, "gpm11", 0x2C), + EXYNOS850_PIN_BANK_EINTW(1, 0x180, "gpm12", 0x30), + EXYNOS850_PIN_BANK_EINTW(1, 0x1A0, "gpm13", 0x34), + EXYNOS850_PIN_BANK_EINTW(1, 0x1C0, "gpm14", 0x38), + EXYNOS850_PIN_BANK_EINTW(1, 0x1E0, "gpm15", 0x3C), + EXYNOS850_PIN_BANK_EINTW(1, 0x200, "gpm16", 0x40), + EXYNOS850_PIN_BANK_EINTW(1, 0x220, "gpm17", 0x44), + EXYNOS850_PIN_BANK_EINTW(1, 0x240, "gpm18", 0x48), + EXYNOS850_PIN_BANK_EINTW(1, 0x260, "gpm19", 0x4C), + EXYNOS850_PIN_BANK_EINTW(1, 0x280, "gpm20", 0x50), + EXYNOS850_PIN_BANK_EINTW(1, 0x2A0, "gpm21", 0x54), + EXYNOS850_PIN_BANK_EINTW(1, 0x2C0, "gpm22", 0x58), + EXYNOS850_PIN_BANK_EINTW(1, 0x2E0, "gpm23", 0x5C), + EXYNOS850_PIN_BANK_EINTW(1, 0x300, "gpm24", 0x60), + EXYNOS850_PIN_BANK_EINTW(1, 0x320, "gpm25", 0x64), +}; + +/* pin banks of exynos9610 pin-controller 2 (DISPAUD) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks2[] __initconst = { + GS101_PIN_BANK_EINTG(5, 0x000, "gpb0", 0x00, 0x00), + GS101_PIN_BANK_EINTG(4, 0x020, "gpb1", 0x04, 0x08), + GS101_PIN_BANK_EINTG(5, 0x040, "gpb2", 0x08, 0x0c), +}; + +/* pin banks of exynos9610 pin-controller 3 (FSYS) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks3[] __initconst = { + GS101_PIN_BANK_EINTG(4, 0x000, "gpf0", 0x00, 0x00), + GS101_PIN_BANK_EINTG(8, 0x020, "gpf1", 0x04, 0x04), + GS101_PIN_BANK_EINTG(6, 0x040, "gpf2", 0x08, 0x0c), +}; + +/* pin banks of exynos9610 pin-controller 4 (TOP) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks4[] __initconst = { + GS101_PIN_BANK_EINTG(8, 0x000, "gpp0", 0x00, 0x00), + GS101_PIN_BANK_EINTG(6, 0x020, "gpp1", 0x04, 0x08), + GS101_PIN_BANK_EINTG(8, 0x040, "gpp2", 0x08, 0x10), + GS101_PIN_BANK_EINTG(8, 0x060, "gpc0", 0x0C, 0x18), + GS101_PIN_BANK_EINTG(8, 0x080, "gpc1", 0x10, 0x20), + GS101_PIN_BANK_EINTG(5, 0x0A0, "gpc2", 0x14, 0x28), + GS101_PIN_BANK_EINTG(8, 0x0C0, "gpg0", 0x18, 0x30), + GS101_PIN_BANK_EINTG(8, 0x0E0, "gpg1", 0x1C, 0x38), + GS101_PIN_BANK_EINTG(8, 0x100, "gpg2", 0x20, 0x40), + GS101_PIN_BANK_EINTG(6, 0x120, "gpg3", 0x24, 0x48), + GS101_PIN_BANK_EINTG(3, 0x140, "gpg4", 0x28, 0x50), +}; + +/* pin banks of exynos9610 pin-controller 5 (SHUB) */ +static const struct samsung_pin_bank_data exynos9610_pin_banks5[] __initconst = { + EXYNOS850_PIN_BANK_EINTG(4, 0x000, "gph0", 0x00), + EXYNOS850_PIN_BANK_EINTG(3, 0x020, "gph1", 0x04), +}; + +static const struct samsung_pin_ctrl exynos9610_pin_ctrl[] __initconst = { + { + /* pin-controller instance 0 ALIVE data */ + .pin_banks = exynos9610_pin_banks0, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks0), + .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 1 CMGP data */ + .pin_banks = exynos9610_pin_banks1, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks1), + .eint_wkup_init = exynos_eint_wkup_init, + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 2 DISPAUD data */ + .pin_banks = exynos9610_pin_banks2, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks2), + }, { + /* pin-controller instance 3 FSYS data */ + .pin_banks = exynos9610_pin_banks3, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks3), + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 4 TOP data */ + .pin_banks = exynos9610_pin_banks4, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks4), + .suspend = exynos_pinctrl_suspend, + .resume = exynos_pinctrl_resume, + }, { + /* pin-controller instance 5 SHUB data */ + .pin_banks = exynos9610_pin_banks5, + .nr_banks = ARRAY_SIZE(exynos9610_pin_banks5), + }, +}; + +const struct samsung_pinctrl_of_match_data exynos9610_of_data __initconst = { + .ctrl = exynos9610_pin_ctrl, + .num_ctrl = ARRAY_SIZE(exynos9610_pin_ctrl), +}; + /* * Pinctrl driver data for Tesla FSD SoC. FSD SoC includes three * gpio/pin-mux/pinconfig controllers. diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.c b/drivers/pinctrl/samsung/pinctrl-samsung.c index e374effba25a..5ac6f6b02327 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.c +++ b/drivers/pinctrl/samsung/pinctrl-samsung.c @@ -1504,6 +1504,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = { .data = &exynos8890_of_data }, { .compatible = "samsung,exynos8895-pinctrl", .data = &exynos8895_of_data }, + { .compatible = "samsung,exynos9610-pinctrl", + .data = &exynos9610_of_data }, { .compatible = "samsung,exynos9810-pinctrl", .data = &exynos9810_of_data }, { .compatible = "samsung,exynos990-pinctrl", diff --git a/drivers/pinctrl/samsung/pinctrl-samsung.h b/drivers/pinctrl/samsung/pinctrl-samsung.h index 0f7b2ea98158..937600430a6e 100644 --- a/drivers/pinctrl/samsung/pinctrl-samsung.h +++ b/drivers/pinctrl/samsung/pinctrl-samsung.h @@ -398,6 +398,7 @@ extern const struct samsung_pinctrl_of_match_data exynos7885_of_data; extern const struct samsung_pinctrl_of_match_data exynos850_of_data; extern const struct samsung_pinctrl_of_match_data exynos8890_of_data; extern const struct samsung_pinctrl_of_match_data exynos8895_of_data; +extern const struct samsung_pinctrl_of_match_data exynos9610_of_data; extern const struct samsung_pinctrl_of_match_data exynos9810_of_data; extern const struct samsung_pinctrl_of_match_data exynos990_of_data; extern const struct samsung_pinctrl_of_match_data exynosautov9_of_data; diff --git a/drivers/pinctrl/sophgo/pinctrl-cv18xx.h b/drivers/pinctrl/sophgo/pinctrl-cv18xx.h index 759c0e604acf..973ab9a38fcf 100644 --- a/drivers/pinctrl/sophgo/pinctrl-cv18xx.h +++ b/drivers/pinctrl/sophgo/pinctrl-cv18xx.h @@ -6,11 +6,7 @@ #ifndef _PINCTRL_SOPHGO_CV18XX_H #define _PINCTRL_SOPHGO_CV18XX_H -#include #include -#include -#include -#include #include #include diff --git a/drivers/pinctrl/sophgo/pinctrl-sg2042.h b/drivers/pinctrl/sophgo/pinctrl-sg2042.h index d481973fcf97..1a2b00dde1fa 100644 --- a/drivers/pinctrl/sophgo/pinctrl-sg2042.h +++ b/drivers/pinctrl/sophgo/pinctrl-sg2042.h @@ -6,12 +6,6 @@ #ifndef _PINCTRL_SOPHGO_SG2042_H #define _PINCTRL_SOPHGO_SG2042_H -#include -#include -#include -#include -#include -#include #include #include diff --git a/drivers/pinctrl/sophgo/pinctrl-sophgo-common.c b/drivers/pinctrl/sophgo/pinctrl-sophgo-common.c index 7f1fd68db19e..4dfe16b66188 100644 --- a/drivers/pinctrl/sophgo/pinctrl-sophgo-common.c +++ b/drivers/pinctrl/sophgo/pinctrl-sophgo-common.c @@ -94,7 +94,7 @@ int sophgo_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node if (!grpnames) return -ENOMEM; - map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, ngroups * 2); if (!map) return -ENOMEM; diff --git a/drivers/pinctrl/spacemit/Kconfig b/drivers/pinctrl/spacemit/Kconfig index d6f6017fd097..c021d51033d1 100644 --- a/drivers/pinctrl/spacemit/Kconfig +++ b/drivers/pinctrl/spacemit/Kconfig @@ -4,7 +4,7 @@ # config PINCTRL_SPACEMIT_K1 - bool "SpacemiT K1 SoC Pinctrl driver" + bool "SpacemiT K1/K3 SoC Pinctrl driver" depends on ARCH_SPACEMIT || COMPILE_TEST depends on OF default ARCH_SPACEMIT @@ -12,7 +12,7 @@ config PINCTRL_SPACEMIT_K1 select GENERIC_PINMUX_FUNCTIONS select GENERIC_PINCONF help - Say Y to select the pinctrl driver for K1 SoC. + Say Y to select the pinctrl driver for K1/K3 SoC. This pin controller allows selecting the mux function for each pin. This driver can also be built as a module called pinctrl-k1. diff --git a/drivers/pinctrl/spacemit/pinctrl-k1.c b/drivers/pinctrl/spacemit/pinctrl-k1.c index 33af9b5791c1..62cab6f6cd0a 100644 --- a/drivers/pinctrl/spacemit/pinctrl-k1.c +++ b/drivers/pinctrl/spacemit/pinctrl-k1.c @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -24,11 +26,12 @@ #include "pinctrl-k1.h" /* - * +---------+----------+-----------+--------+--------+----------+--------+ - * | pull | drive | schmitter | slew | edge | strong | mux | - * | up/down | strength | trigger | rate | detect | pull | mode | - * +---------+----------+-----------+--------+--------+----------+--------+ - * 3 bits 3 bits 2 bits 1 bit 3 bits 1 bit 3 bits + * | pull | drive | schmitter | slew | edge | strong | mux | + * SoC | up/down | strength | trigger | rate | detect | pull | mode | + *-----+---------+----------+-----------+-------+--------+--------+--------+ + * K1 | 3 bits | 3 bits | 2 bits | 1 bit | 3 bits | 1 bit | 3 bits | + *-----+---------+----------+-----------+-------+--------+--------+--------+ + * K3 | 3 bits | 4 bits | 1 bits | 1 bit | 3 bits | 1 bit | 3 bits | */ #define PAD_MUX GENMASK(2, 0) @@ -38,12 +41,50 @@ #define PAD_EDGE_CLEAR BIT(6) #define PAD_SLEW_RATE GENMASK(12, 11) #define PAD_SLEW_RATE_EN BIT(7) -#define PAD_SCHMITT GENMASK(9, 8) -#define PAD_DRIVE GENMASK(12, 10) +#define PAD_SCHMITT_K1 GENMASK(9, 8) +#define PAD_DRIVE_K1 GENMASK(12, 10) +#define PAD_SCHMITT_K3 BIT(8) +#define PAD_DRIVE_K3 GENMASK(12, 9) #define PAD_PULLDOWN BIT(13) #define PAD_PULLUP BIT(14) #define PAD_PULL_EN BIT(15) +#define IO_PWR_DOMAIN_OFFSET 0x800 + +#define IO_PWR_DOMAIN_GPIO2_Kx 0x0c +#define IO_PWR_DOMAIN_MMC_Kx 0x1c + +#define IO_PWR_DOMAIN_GPIO3_K1 0x10 +#define IO_PWR_DOMAIN_QSPI_K1 0x20 + +#define IO_PWR_DOMAIN_GPIO1_K3 0x04 +#define IO_PWR_DOMAIN_GPIO5_K3 0x10 +#define IO_PWR_DOMAIN_GPIO4_K3 0x20 +#define IO_PWR_DOMAIN_QSPI_K3 0x2c + +#define IO_PWR_DOMAIN_V18EN BIT(2) + +#define APBC_ASFAR 0x50 +#define APBC_ASSAR 0x54 + +#define APBC_ASFAR_AKEY 0xbaba +#define APBC_ASSAR_AKEY 0xeb10 + +struct spacemit_pin_drv_strength { + u8 val; + u32 mA; +}; + +struct spacemit_pinctrl_dconf { + u64 schmitt_mask; + u64 drive_mask; + + struct spacemit_pin_drv_strength *ds_1v8_tbl; + size_t ds_1v8_tbl_num; + struct spacemit_pin_drv_strength *ds_3v3_tbl; + size_t ds_3v3_tbl_num; +}; + struct spacemit_pin { u16 pin; u16 flags; @@ -60,12 +101,17 @@ struct spacemit_pinctrl { raw_spinlock_t lock; void __iomem *regs; + + struct regmap *regmap_apbc; }; struct spacemit_pinctrl_data { const struct pinctrl_pin_desc *pins; const struct spacemit_pin *data; u16 npins; + unsigned int (*pin_to_offset)(unsigned int pin); + unsigned int (*pin_to_io_pd_offset)(unsigned int pin); + const struct spacemit_pinctrl_dconf *dconf; }; struct spacemit_pin_mux_config { @@ -73,13 +119,8 @@ struct spacemit_pin_mux_config { u32 config; }; -struct spacemit_pin_drv_strength { - u8 val; - u32 mA; -}; - /* map pin id to pinctrl register offset, refer MFPR definition */ -static unsigned int spacemit_pin_to_offset(unsigned int pin) +static unsigned int spacemit_k1_pin_to_offset(unsigned int pin) { unsigned int offset = 0; @@ -124,10 +165,67 @@ static unsigned int spacemit_pin_to_offset(unsigned int pin) return offset << 2; } +static unsigned int spacemit_k3_pin_to_offset(unsigned int pin) +{ + unsigned int offset = pin > 130 ? (pin + 2) : pin; + + return offset << 2; +} + +static unsigned int spacemit_k1_pin_to_io_pd_offset(unsigned int pin) +{ + unsigned int offset = 0; + + switch (pin) { + case 47 ... 52: + offset = IO_PWR_DOMAIN_GPIO3_K1; + break; + case 75 ... 80: + offset = IO_PWR_DOMAIN_GPIO2_Kx; + break; + case 98 ... 103: + offset = IO_PWR_DOMAIN_QSPI_K1; + break; + case 104 ... 109: + offset = IO_PWR_DOMAIN_MMC_Kx; + break; + } + + return offset; +} + +static unsigned int spacemit_k3_pin_to_io_pd_offset(unsigned int pin) +{ + unsigned int offset = 0; + + switch (pin) { + case 0 ... 20: + offset = IO_PWR_DOMAIN_GPIO1_K3; + break; + case 21 ... 41: + offset = IO_PWR_DOMAIN_GPIO2_Kx; + break; + case 76 ... 98: + offset = IO_PWR_DOMAIN_GPIO4_K3; + break; + case 99 ... 127: + offset = IO_PWR_DOMAIN_GPIO5_K3; + break; + case 132 ... 137: + offset = IO_PWR_DOMAIN_MMC_Kx; + break; + case 138 ... 144: + offset = IO_PWR_DOMAIN_QSPI_K3; + break; + } + + return offset; +} + static inline void __iomem *spacemit_pin_to_reg(struct spacemit_pinctrl *pctrl, unsigned int pin) { - return pctrl->regs + spacemit_pin_to_offset(pin); + return pctrl->regs + pctrl->data->pin_to_offset(pin); } static u16 spacemit_dt_get_pin(u32 value) @@ -177,7 +275,7 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev, void __iomem *reg; u32 value; - seq_printf(seq, "offset: 0x%04x ", spacemit_pin_to_offset(pin)); + seq_printf(seq, "offset: 0x%04x ", pctrl->data->pin_to_offset(pin)); seq_printf(seq, "type: %s ", io_type_desc[type]); reg = spacemit_pin_to_reg(pctrl, pin); @@ -185,23 +283,70 @@ static void spacemit_pctrl_dbg_show(struct pinctrl_dev *pctldev, seq_printf(seq, "mux: %ld reg: 0x%04x", (value & PAD_MUX), value); } -/* use IO high level output current as the table */ -static struct spacemit_pin_drv_strength spacemit_ds_1v8_tbl[4] = { - { 0, 11 }, - { 2, 21 }, - { 4, 32 }, - { 6, 42 }, +static const struct spacemit_pinctrl_dconf k1_drive_conf = { + .drive_mask = PAD_DRIVE_K1, + .schmitt_mask = PAD_SCHMITT_K1, + .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { + { 0, 11 }, + { 2, 21 }, + { 4, 32 }, + { 6, 42 }, + }, + .ds_1v8_tbl_num = 4, + .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { + { 0, 7 }, + { 2, 10 }, + { 4, 13 }, + { 6, 16 }, + { 1, 19 }, + { 3, 23 }, + { 5, 26 }, + { 7, 29 }, + }, + .ds_3v3_tbl_num = 8, }; -static struct spacemit_pin_drv_strength spacemit_ds_3v3_tbl[8] = { - { 0, 7 }, - { 2, 10 }, - { 4, 13 }, - { 6, 16 }, - { 1, 19 }, - { 3, 23 }, - { 5, 26 }, - { 7, 29 }, +static const struct spacemit_pinctrl_dconf k3_drive_conf = { + .drive_mask = PAD_DRIVE_K3, + .schmitt_mask = PAD_SCHMITT_K3, + .ds_1v8_tbl = (struct spacemit_pin_drv_strength[]) { + { 0, 2 }, + { 1, 4 }, + { 2, 6 }, + { 3, 7 }, + { 4, 9 }, + { 5, 11 }, + { 6, 13 }, + { 7, 14 }, + { 8, 21 }, + { 9, 23 }, + { 10, 25 }, + { 11, 26 }, + { 12, 28 }, + { 13, 30 }, + { 14, 31 }, + { 15, 33 }, + }, + .ds_1v8_tbl_num = 16, + .ds_3v3_tbl = (struct spacemit_pin_drv_strength[]) { + { 0, 3 }, + { 1, 5 }, + { 2, 7 }, + { 3, 9 }, + { 4, 11 }, + { 5, 13 }, + { 6, 15 }, + { 7, 17 }, + { 8, 25 }, + { 9, 27 }, + { 10, 29 }, + { 11, 31 }, + { 12, 33 }, + { 13, 35 }, + { 14, 37 }, + { 15, 38 }, + }, + .ds_3v3_tbl_num = 16, }; static inline u8 spacemit_get_ds_value(struct spacemit_pin_drv_strength *tbl, @@ -229,16 +374,17 @@ static inline u32 spacemit_get_ds_mA(struct spacemit_pin_drv_strength *tbl, } static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type, + const struct spacemit_pinctrl_dconf *dconf, u32 mA) { switch (type) { case IO_TYPE_1V8: - return spacemit_get_ds_value(spacemit_ds_1v8_tbl, - ARRAY_SIZE(spacemit_ds_1v8_tbl), + return spacemit_get_ds_value(dconf->ds_1v8_tbl, + dconf->ds_1v8_tbl_num, mA); case IO_TYPE_3V3: - return spacemit_get_ds_value(spacemit_ds_3v3_tbl, - ARRAY_SIZE(spacemit_ds_3v3_tbl), + return spacemit_get_ds_value(dconf->ds_3v3_tbl, + dconf->ds_3v3_tbl_num, mA); default: return 0; @@ -246,16 +392,17 @@ static inline u8 spacemit_get_driver_strength(enum spacemit_pin_io_type type, } static inline u32 spacemit_get_drive_strength_mA(enum spacemit_pin_io_type type, + const struct spacemit_pinctrl_dconf *dconf, u32 value) { switch (type) { case IO_TYPE_1V8: - return spacemit_get_ds_mA(spacemit_ds_1v8_tbl, - ARRAY_SIZE(spacemit_ds_1v8_tbl), - value & 0x6); + return spacemit_get_ds_mA(dconf->ds_1v8_tbl, + dconf->ds_1v8_tbl_num, + value); case IO_TYPE_3V3: - return spacemit_get_ds_mA(spacemit_ds_3v3_tbl, - ARRAY_SIZE(spacemit_ds_3v3_tbl), + return spacemit_get_ds_mA(dconf->ds_3v3_tbl, + dconf->ds_3v3_tbl_num, value); default: return 0; @@ -294,6 +441,42 @@ static int spacemit_pctrl_check_power(struct pinctrl_dev *pctldev, return 0; } +static void spacemit_set_io_pwr_domain(struct spacemit_pinctrl *pctrl, + const struct spacemit_pin *spin, + const enum spacemit_pin_io_type type) +{ + u32 offset, val = 0; + + if (!pctrl->regmap_apbc) + return; + + offset = pctrl->data->pin_to_io_pd_offset(spin->pin); + + /* Other bits are reserved so don't need to save them */ + if (type == IO_TYPE_1V8) + val = IO_PWR_DOMAIN_V18EN; + + /* + * IO power domain registers are protected and cannot be accessed + * directly. Before performing any read or write to the IO power + * domain registers, an explicit unlock sequence must be issued + * via the AIB Secure Access Register (ASAR). + * + * The unlock sequence allows exactly one subsequent access to the + * IO power domain registers. After that access completes, the ASAR + * keys are automatically cleared, and the registers become locked + * again. + * + * This mechanism ensures that IO power domain configuration is + * performed intentionally, as incorrect voltage settings may + * result in functional failures or hardware damage. + */ + regmap_write(pctrl->regmap_apbc, APBC_ASFAR, APBC_ASFAR_AKEY); + regmap_write(pctrl->regmap_apbc, APBC_ASSAR, APBC_ASSAR_AKEY); + + writel_relaxed(val, pctrl->regs + IO_PWR_DOMAIN_OFFSET + offset); +} + static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node *np, struct pinctrl_map **maps, @@ -316,7 +499,7 @@ static int spacemit_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, if (!grpnames) return -ENOMEM; - map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, ngroups * 2); if (!map) return -ENOMEM; @@ -501,7 +684,9 @@ static int spacemit_pinconf_get(struct pinctrl_dev *pctldev, #define ENABLE_DRV_STRENGTH BIT(1) #define ENABLE_SLEW_RATE BIT(2) -static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, +static int spacemit_pinconf_generate_config(struct spacemit_pinctrl *pctrl, + const struct spacemit_pin *spin, + const struct spacemit_pinctrl_dconf *dconf, unsigned long *configs, unsigned int num_configs, u32 *value) @@ -539,8 +724,8 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, drv_strength = arg; break; case PIN_CONFIG_INPUT_SCHMITT: - v &= ~PAD_SCHMITT; - v |= FIELD_PREP(PAD_SCHMITT, arg); + v &= ~dconf->schmitt_mask; + v |= (arg << __ffs(dconf->schmitt_mask)) & dconf->schmitt_mask; break; case PIN_CONFIG_POWER_SOURCE: voltage = arg; @@ -574,12 +759,13 @@ static int spacemit_pinconf_generate_config(const struct spacemit_pin *spin, default: return -EINVAL; } + spacemit_set_io_pwr_domain(pctrl, spin, type); } - val = spacemit_get_driver_strength(type, drv_strength); + val = spacemit_get_driver_strength(type, dconf, drv_strength); - v &= ~PAD_DRIVE; - v |= FIELD_PREP(PAD_DRIVE, val); + v &= ~dconf->drive_mask; + v |= (val << __ffs(dconf->drive_mask)) & dconf->drive_mask; } if (flag & ENABLE_SLEW_RATE) { @@ -629,7 +815,8 @@ static int spacemit_pinconf_set(struct pinctrl_dev *pctldev, const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); u32 value; - if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) + if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, + configs, num_configs, &value)) return -EINVAL; return spacemit_pin_set_config(pctrl, pin, value); @@ -651,7 +838,8 @@ static int spacemit_pinconf_group_set(struct pinctrl_dev *pctldev, return -EINVAL; spin = spacemit_get_pin(pctrl, group->grp.pins[0]); - if (spacemit_pinconf_generate_config(spin, configs, num_configs, &value)) + if (spacemit_pinconf_generate_config(pctrl, spin, pctrl->data->dconf, + configs, num_configs, &value)) return -EINVAL; for (i = 0; i < group->grp.npins; i++) @@ -685,6 +873,7 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *seq, unsigned int pin) { struct spacemit_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctldev); + const struct spacemit_pinctrl_dconf *dconf = pctrl->data->dconf; const struct spacemit_pin *spin = spacemit_get_pin(pctrl, pin); enum spacemit_pin_io_type type = spacemit_to_pin_io_type(spin); void __iomem *reg = spacemit_pin_to_reg(pctrl, pin); @@ -695,17 +884,17 @@ static void spacemit_pinconf_dbg_show(struct pinctrl_dev *pctldev, seq_printf(seq, ", io type (%s)", io_type_desc[type]); - tmp = FIELD_GET(PAD_DRIVE, value); + tmp = (value & dconf->drive_mask) >> __ffs(dconf->drive_mask); if (type == IO_TYPE_1V8 || type == IO_TYPE_3V3) { - mA = spacemit_get_drive_strength_mA(type, tmp); + mA = spacemit_get_drive_strength_mA(type, dconf, tmp); seq_printf(seq, ", drive strength (%d mA)", mA); } /* drive strength depend on power source, so show all values */ if (type == IO_TYPE_EXTERNAL) seq_printf(seq, ", drive strength (%d or %d mA)", - spacemit_get_drive_strength_mA(IO_TYPE_1V8, tmp), - spacemit_get_drive_strength_mA(IO_TYPE_3V3, tmp)); + spacemit_get_drive_strength_mA(IO_TYPE_1V8, dconf, tmp), + spacemit_get_drive_strength_mA(IO_TYPE_3V3, dconf, tmp)); seq_printf(seq, ", register (0x%04x)", value); } @@ -720,6 +909,7 @@ static const struct pinconf_ops spacemit_pinconf_ops = { static int spacemit_pinctrl_probe(struct platform_device *pdev) { + struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; struct spacemit_pinctrl *pctrl; struct clk *func_clk, *bus_clk; @@ -741,6 +931,12 @@ static int spacemit_pinctrl_probe(struct platform_device *pdev) if (IS_ERR(pctrl->regs)) return PTR_ERR(pctrl->regs); + pctrl->regmap_apbc = syscon_regmap_lookup_by_phandle(np, "spacemit,apbc"); + if (IS_ERR(pctrl->regmap_apbc)) { + dev_warn(dev, "no syscon found, disable power voltage switch functionality\n"); + pctrl->regmap_apbc = NULL; + } + func_clk = devm_clk_get_enabled(dev, "func"); if (IS_ERR(func_clk)) return dev_err_probe(dev, PTR_ERR(func_clk), "failed to get func clock\n"); @@ -1042,10 +1238,352 @@ static const struct spacemit_pinctrl_data k1_pinctrl_data = { .pins = k1_pin_desc, .data = k1_pin_data, .npins = ARRAY_SIZE(k1_pin_desc), + .pin_to_offset = spacemit_k1_pin_to_offset, + .pin_to_io_pd_offset = spacemit_k1_pin_to_io_pd_offset, + .dconf = &k1_drive_conf, +}; + +static const struct pinctrl_pin_desc k3_pin_desc[] = { + PINCTRL_PIN(0, "GPIO_00"), + PINCTRL_PIN(1, "GPIO_01"), + PINCTRL_PIN(2, "GPIO_02"), + PINCTRL_PIN(3, "GPIO_03"), + PINCTRL_PIN(4, "GPIO_04"), + PINCTRL_PIN(5, "GPIO_05"), + PINCTRL_PIN(6, "GPIO_06"), + PINCTRL_PIN(7, "GPIO_07"), + PINCTRL_PIN(8, "GPIO_08"), + PINCTRL_PIN(9, "GPIO_09"), + PINCTRL_PIN(10, "GPIO_10"), + PINCTRL_PIN(11, "GPIO_11"), + PINCTRL_PIN(12, "GPIO_12"), + PINCTRL_PIN(13, "GPIO_13"), + PINCTRL_PIN(14, "GPIO_14"), + PINCTRL_PIN(15, "GPIO_15"), + PINCTRL_PIN(16, "GPIO_16"), + PINCTRL_PIN(17, "GPIO_17"), + PINCTRL_PIN(18, "GPIO_18"), + PINCTRL_PIN(19, "GPIO_19"), + PINCTRL_PIN(20, "GPIO_20"), + PINCTRL_PIN(21, "GPIO_21"), + PINCTRL_PIN(22, "GPIO_22"), + PINCTRL_PIN(23, "GPIO_23"), + PINCTRL_PIN(24, "GPIO_24"), + PINCTRL_PIN(25, "GPIO_25"), + PINCTRL_PIN(26, "GPIO_26"), + PINCTRL_PIN(27, "GPIO_27"), + PINCTRL_PIN(28, "GPIO_28"), + PINCTRL_PIN(29, "GPIO_29"), + PINCTRL_PIN(30, "GPIO_30"), + PINCTRL_PIN(31, "GPIO_31"), + PINCTRL_PIN(32, "GPIO_32"), + PINCTRL_PIN(33, "GPIO_33"), + PINCTRL_PIN(34, "GPIO_34"), + PINCTRL_PIN(35, "GPIO_35"), + PINCTRL_PIN(36, "GPIO_36"), + PINCTRL_PIN(37, "GPIO_37"), + PINCTRL_PIN(38, "GPIO_38"), + PINCTRL_PIN(39, "GPIO_39"), + PINCTRL_PIN(40, "GPIO_40"), + PINCTRL_PIN(41, "GPIO_41"), + PINCTRL_PIN(42, "GPIO_42"), + PINCTRL_PIN(43, "GPIO_43"), + PINCTRL_PIN(44, "GPIO_44"), + PINCTRL_PIN(45, "GPIO_45"), + PINCTRL_PIN(46, "GPIO_46"), + PINCTRL_PIN(47, "GPIO_47"), + PINCTRL_PIN(48, "GPIO_48"), + PINCTRL_PIN(49, "GPIO_49"), + PINCTRL_PIN(50, "GPIO_50"), + PINCTRL_PIN(51, "GPIO_51"), + PINCTRL_PIN(52, "GPIO_52"), + PINCTRL_PIN(53, "GPIO_53"), + PINCTRL_PIN(54, "GPIO_54"), + PINCTRL_PIN(55, "GPIO_55"), + PINCTRL_PIN(56, "GPIO_56"), + PINCTRL_PIN(57, "GPIO_57"), + PINCTRL_PIN(58, "GPIO_58"), + PINCTRL_PIN(59, "GPIO_59"), + PINCTRL_PIN(60, "GPIO_60"), + PINCTRL_PIN(61, "GPIO_61"), + PINCTRL_PIN(62, "GPIO_62"), + PINCTRL_PIN(63, "GPIO_63"), + PINCTRL_PIN(64, "GPIO_64"), + PINCTRL_PIN(65, "GPIO_65"), + PINCTRL_PIN(66, "GPIO_66"), + PINCTRL_PIN(67, "GPIO_67"), + PINCTRL_PIN(68, "GPIO_68"), + PINCTRL_PIN(69, "GPIO_69"), + PINCTRL_PIN(70, "GPIO_70"), + PINCTRL_PIN(71, "GPIO_71"), + PINCTRL_PIN(72, "GPIO_72"), + PINCTRL_PIN(73, "GPIO_73"), + PINCTRL_PIN(74, "GPIO_74"), + PINCTRL_PIN(75, "GPIO_75"), + PINCTRL_PIN(76, "GPIO_76"), + PINCTRL_PIN(77, "GPIO_77"), + PINCTRL_PIN(78, "GPIO_78"), + PINCTRL_PIN(79, "GPIO_79"), + PINCTRL_PIN(80, "GPIO_80"), + PINCTRL_PIN(81, "GPIO_81"), + PINCTRL_PIN(82, "GPIO_82"), + PINCTRL_PIN(83, "GPIO_83"), + PINCTRL_PIN(84, "GPIO_84"), + PINCTRL_PIN(85, "GPIO_85"), + PINCTRL_PIN(86, "GPIO_86"), + PINCTRL_PIN(87, "GPIO_87"), + PINCTRL_PIN(88, "GPIO_88"), + PINCTRL_PIN(89, "GPIO_89"), + PINCTRL_PIN(90, "GPIO_90"), + PINCTRL_PIN(91, "GPIO_91"), + PINCTRL_PIN(92, "GPIO_92"), + PINCTRL_PIN(93, "GPIO_93"), + PINCTRL_PIN(94, "GPIO_94"), + PINCTRL_PIN(95, "GPIO_95"), + PINCTRL_PIN(96, "GPIO_96"), + PINCTRL_PIN(97, "GPIO_97"), + PINCTRL_PIN(98, "GPIO_98"), + PINCTRL_PIN(99, "GPIO_99"), + PINCTRL_PIN(100, "GPIO_100"), + PINCTRL_PIN(101, "GPIO_101"), + PINCTRL_PIN(102, "GPIO_102"), + PINCTRL_PIN(103, "GPIO_103"), + PINCTRL_PIN(104, "GPIO_104"), + PINCTRL_PIN(105, "GPIO_105"), + PINCTRL_PIN(106, "GPIO_106"), + PINCTRL_PIN(107, "GPIO_107"), + PINCTRL_PIN(108, "GPIO_108"), + PINCTRL_PIN(109, "GPIO_109"), + PINCTRL_PIN(110, "GPIO_110"), + PINCTRL_PIN(111, "GPIO_111"), + PINCTRL_PIN(112, "GPIO_112"), + PINCTRL_PIN(113, "GPIO_113"), + PINCTRL_PIN(114, "GPIO_114"), + PINCTRL_PIN(115, "GPIO_115"), + PINCTRL_PIN(116, "GPIO_116"), + PINCTRL_PIN(117, "GPIO_117"), + PINCTRL_PIN(118, "GPIO_118"), + PINCTRL_PIN(119, "GPIO_119"), + PINCTRL_PIN(120, "GPIO_120"), + PINCTRL_PIN(121, "GPIO_121"), + PINCTRL_PIN(122, "GPIO_122"), + PINCTRL_PIN(123, "GPIO_123"), + PINCTRL_PIN(124, "GPIO_124"), + PINCTRL_PIN(125, "GPIO_125"), + PINCTRL_PIN(126, "GPIO_126"), + PINCTRL_PIN(127, "GPIO_127"), + PINCTRL_PIN(128, "PWR_SCL"), + PINCTRL_PIN(129, "PWR_SDA"), + PINCTRL_PIN(130, "VCXO_EN"), + PINCTRL_PIN(131, "PMIC_INT_N"), + PINCTRL_PIN(132, "MMC1_DAT3"), + PINCTRL_PIN(133, "MMC1_DAT2"), + PINCTRL_PIN(134, "MMC1_DAT1"), + PINCTRL_PIN(135, "MMC1_DAT0"), + PINCTRL_PIN(136, "MMC1_CMD"), + PINCTRL_PIN(137, "MMC1_CLK"), + PINCTRL_PIN(138, "QSPI_DAT0"), + PINCTRL_PIN(139, "QSPI_DAT1"), + PINCTRL_PIN(140, "QSPI_DAT2"), + PINCTRL_PIN(141, "QSPI_DAT3"), + PINCTRL_PIN(142, "QSPI_CS0"), + PINCTRL_PIN(143, "QSPI_CS1"), + PINCTRL_PIN(144, "QSPI_CLK"), + PINCTRL_PIN(145, "PRI_TDI"), + PINCTRL_PIN(146, "PRI_TMS"), + PINCTRL_PIN(147, "PRI_TCK"), + PINCTRL_PIN(148, "PRI_TDO"), + PINCTRL_PIN(149, "PWR_SSP_SCLK"), + PINCTRL_PIN(150, "PWR_SSP_FRM"), + PINCTRL_PIN(151, "PWR_SSP_TXD"), + PINCTRL_PIN(152, "PWR_SSP_RXD"), +}; + +static const struct spacemit_pin k3_pin_data[ARRAY_SIZE(k3_pin_desc)] = { + /* GPIO1 bank */ + K1_FUNC_PIN(0, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(1, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(2, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(3, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(4, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(5, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(6, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(7, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(8, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(9, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(10, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(11, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(12, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(13, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(14, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(15, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(16, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(17, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(18, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(19, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(20, 0, IO_TYPE_EXTERNAL), + + /* GPIO2 bank */ + K1_FUNC_PIN(21, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(22, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(23, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(24, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(25, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(26, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(27, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(28, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(29, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(30, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(31, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(32, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(33, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(34, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(35, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(36, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(37, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(38, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(39, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(40, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(41, 0, IO_TYPE_EXTERNAL), + + /* GPIO3 bank */ + K1_FUNC_PIN(42, 0, IO_TYPE_1V8), + K1_FUNC_PIN(43, 0, IO_TYPE_1V8), + K1_FUNC_PIN(44, 0, IO_TYPE_1V8), + K1_FUNC_PIN(45, 0, IO_TYPE_1V8), + K1_FUNC_PIN(46, 0, IO_TYPE_1V8), + K1_FUNC_PIN(47, 0, IO_TYPE_1V8), + K1_FUNC_PIN(48, 0, IO_TYPE_1V8), + K1_FUNC_PIN(49, 0, IO_TYPE_1V8), + K1_FUNC_PIN(50, 0, IO_TYPE_1V8), + K1_FUNC_PIN(51, 0, IO_TYPE_1V8), + K1_FUNC_PIN(52, 0, IO_TYPE_1V8), + K1_FUNC_PIN(53, 0, IO_TYPE_1V8), + K1_FUNC_PIN(54, 0, IO_TYPE_1V8), + K1_FUNC_PIN(55, 0, IO_TYPE_1V8), + K1_FUNC_PIN(56, 0, IO_TYPE_1V8), + K1_FUNC_PIN(57, 0, IO_TYPE_1V8), + K1_FUNC_PIN(58, 0, IO_TYPE_1V8), + K1_FUNC_PIN(59, 0, IO_TYPE_1V8), + K1_FUNC_PIN(60, 0, IO_TYPE_1V8), + K1_FUNC_PIN(61, 0, IO_TYPE_1V8), + K1_FUNC_PIN(62, 0, IO_TYPE_1V8), + K1_FUNC_PIN(63, 0, IO_TYPE_1V8), + K1_FUNC_PIN(64, 0, IO_TYPE_1V8), + K1_FUNC_PIN(65, 0, IO_TYPE_1V8), + K1_FUNC_PIN(66, 0, IO_TYPE_1V8), + K1_FUNC_PIN(67, 0, IO_TYPE_1V8), + K1_FUNC_PIN(68, 0, IO_TYPE_1V8), + K1_FUNC_PIN(69, 0, IO_TYPE_1V8), + K1_FUNC_PIN(70, 0, IO_TYPE_1V8), + K1_FUNC_PIN(71, 0, IO_TYPE_1V8), + K1_FUNC_PIN(72, 0, IO_TYPE_1V8), + K1_FUNC_PIN(73, 0, IO_TYPE_1V8), + K1_FUNC_PIN(74, 0, IO_TYPE_1V8), + K1_FUNC_PIN(75, 0, IO_TYPE_1V8), + + /* GPIO4 bank */ + K1_FUNC_PIN(76, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(77, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(78, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(79, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(80, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(81, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(82, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(83, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(84, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(85, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(86, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(87, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(88, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(89, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(90, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(91, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(92, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(93, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(94, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(95, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(96, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(97, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(98, 0, IO_TYPE_EXTERNAL), + + /* GPIO5 bank */ + K1_FUNC_PIN(99, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(100, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(101, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(102, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(103, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(104, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(105, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(106, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(107, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(108, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(109, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(110, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(111, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(112, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(113, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(114, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(115, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(116, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(117, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(118, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(119, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(120, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(121, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(122, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(123, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(124, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(125, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(126, 0, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(127, 0, IO_TYPE_EXTERNAL), + + /* PMIC */ + K1_FUNC_PIN(128, 0, IO_TYPE_1V8), + K1_FUNC_PIN(129, 0, IO_TYPE_1V8), + K1_FUNC_PIN(130, 0, IO_TYPE_1V8), + K1_FUNC_PIN(131, 0, IO_TYPE_1V8), + + /* SD/MMC1 */ + K1_FUNC_PIN(132, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(133, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(134, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(135, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(136, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(137, 1, IO_TYPE_EXTERNAL), + + /* QSPI */ + K1_FUNC_PIN(138, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(139, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(140, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(141, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(142, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(143, 1, IO_TYPE_EXTERNAL), + K1_FUNC_PIN(144, 1, IO_TYPE_EXTERNAL), + + /* PMIC */ + K1_FUNC_PIN(145, 1, IO_TYPE_1V8), + K1_FUNC_PIN(146, 1, IO_TYPE_1V8), + K1_FUNC_PIN(147, 1, IO_TYPE_1V8), + K1_FUNC_PIN(148, 1, IO_TYPE_1V8), + K1_FUNC_PIN(149, 1, IO_TYPE_1V8), + K1_FUNC_PIN(150, 1, IO_TYPE_1V8), + K1_FUNC_PIN(151, 1, IO_TYPE_1V8), + K1_FUNC_PIN(152, 1, IO_TYPE_1V8), +}; + +static const struct spacemit_pinctrl_data k3_pinctrl_data = { + .pins = k3_pin_desc, + .data = k3_pin_data, + .npins = ARRAY_SIZE(k3_pin_desc), + .pin_to_offset = spacemit_k3_pin_to_offset, + .pin_to_io_pd_offset = spacemit_k3_pin_to_io_pd_offset, + .dconf = &k3_drive_conf, }; static const struct of_device_id k1_pinctrl_ids[] = { { .compatible = "spacemit,k1-pinctrl", .data = &k1_pinctrl_data }, + { .compatible = "spacemit,k3-pinctrl", .data = &k3_pinctrl_data }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, k1_pinctrl_ids); @@ -1061,5 +1599,5 @@ static struct platform_driver k1_pinctrl_driver = { builtin_platform_driver(k1_pinctrl_driver); MODULE_AUTHOR("Yixun Lan "); -MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1 SoC"); +MODULE_DESCRIPTION("Pinctrl driver for the SpacemiT K1/K3 SoC"); MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c index a8c5fe973cd4..f92f6efde1dc 100644 --- a/drivers/pinctrl/spear/pinctrl-spear.c +++ b/drivers/pinctrl/spear/pinctrl-spear.c @@ -173,7 +173,7 @@ static int spear_pinctrl_dt_node_to_map(struct pinctrl_dev *pctldev, return -ENODEV; } - *map = kcalloc(count, sizeof(**map), GFP_KERNEL); + *map = kzalloc_objs(**map, count); if (!*map) return -ENOMEM; diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c index 7fa13f282b85..25cb98d9c54e 100644 --- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7100.c @@ -517,7 +517,7 @@ static int starfive_dt_node_to_map(struct pinctrl_dev *pctldev, if (!pgnames) return -ENOMEM; - map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, nmaps); if (!map) return -ENOMEM; diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c index 9b67063a0b0b..44f84e4c29bf 100644 --- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110-sys.c @@ -7,14 +7,11 @@ */ #include -#include #include #include #include #include -#include #include -#include #include #include diff --git a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c index eb5cf8c067d1..e44480e71ea8 100644 --- a/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c +++ b/drivers/pinctrl/starfive/pinctrl-starfive-jh7110.c @@ -143,7 +143,7 @@ static int jh7110_dt_node_to_map(struct pinctrl_dev *pctldev, if (!pgnames) return -ENOMEM; - map = kcalloc(nmaps, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, nmaps); if (!map) return -ENOMEM; diff --git a/drivers/pinctrl/sunplus/sppctl.c b/drivers/pinctrl/sunplus/sppctl.c index fabe7efaa837..67e036d66245 100644 --- a/drivers/pinctrl/sunplus/sppctl.c +++ b/drivers/pinctrl/sunplus/sppctl.c @@ -865,7 +865,7 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node if (nmG <= 0) nmG = 0; - *map = kcalloc(*num_maps + nmG, sizeof(**map), GFP_KERNEL); + *map = kzalloc_objs(**map, *num_maps + nmG); if (!(*map)) return -ENOMEM; @@ -882,7 +882,7 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; (*map)[i].data.configs.num_configs = 1; (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); - configs = kmalloc(sizeof(*configs), GFP_KERNEL); + configs = kmalloc_obj(*configs); if (!configs) goto sppctl_map_err; *configs = FIELD_GET(GENMASK(7, 0), dt_pin); @@ -897,7 +897,7 @@ static int sppctl_dt_node_to_map(struct pinctrl_dev *pctldev, struct device_node (*map)[i].type = PIN_MAP_TYPE_CONFIGS_PIN; (*map)[i].data.configs.num_configs = 1; (*map)[i].data.configs.group_or_pin = pin_get_name(pctldev, pin_num); - configs = kmalloc(sizeof(*configs), GFP_KERNEL); + configs = kmalloc_obj(*configs); if (!configs) goto sppctl_map_err; *configs = SPPCTL_IOP_CONFIGS; diff --git a/drivers/pinctrl/sunxi/pinctrl-sunxi.c b/drivers/pinctrl/sunxi/pinctrl-sunxi.c index 0fb057a07dcc..c990b6118172 100644 --- a/drivers/pinctrl/sunxi/pinctrl-sunxi.c +++ b/drivers/pinctrl/sunxi/pinctrl-sunxi.c @@ -204,6 +204,32 @@ sunxi_pinctrl_desc_find_function_by_pin(struct sunxi_pinctrl *pctl, return NULL; } +static struct sunxi_desc_function * +sunxi_pinctrl_desc_find_function_by_pin_and_mux(struct sunxi_pinctrl *pctl, + const u16 pin_num, + const u8 muxval) +{ + for (unsigned int i = 0; i < pctl->desc->npins; i++) { + const struct sunxi_desc_pin *pin = pctl->desc->pins + i; + struct sunxi_desc_function *func = pin->functions; + + if (pin->pin.number != pin_num) + continue; + + if (pin->variant && !(pctl->variant & pin->variant)) + continue; + + while (func->name) { + if (func->muxval == muxval) + return func; + + func++; + } + } + + return NULL; +} + static int sunxi_pctrl_get_groups_count(struct pinctrl_dev *pctldev) { struct sunxi_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); @@ -435,7 +461,7 @@ static int sunxi_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, * any configuration. */ nmaps = npins * 2; - *map = kmalloc_array(nmaps, sizeof(struct pinctrl_map), GFP_KERNEL); + *map = kmalloc_objs(struct pinctrl_map, nmaps); if (!*map) return -ENOMEM; @@ -930,6 +956,30 @@ static const struct pinmux_ops sunxi_pmx_ops = { .strict = true, }; +static int sunxi_pinctrl_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct sunxi_pinctrl *pctl = gpiochip_get_data(chip); + const struct sunxi_desc_function *func; + u32 pin = offset + chip->base; + u32 reg, shift, mask; + u8 muxval; + + sunxi_mux_reg(pctl, offset, ®, &shift, &mask); + + muxval = (readl(pctl->membase + reg) & mask) >> shift; + + func = sunxi_pinctrl_desc_find_function_by_pin_and_mux(pctl, pin, muxval); + if (!func) + return -ENODEV; + + if (!strcmp(func->name, "gpio_out")) + return GPIO_LINE_DIRECTION_OUT; + if (!strcmp(func->name, "gpio_in") || !strcmp(func->name, "irq")) + return GPIO_LINE_DIRECTION_IN; + return -EINVAL; +} + static int sunxi_pinctrl_gpio_direction_input(struct gpio_chip *chip, unsigned offset) { @@ -1328,9 +1378,7 @@ static int sunxi_pinctrl_build_state(struct platform_device *pdev) * special functions per pin, plus one entry for the sentinel. * We'll reallocate that later anyway. */ - pctl->functions = kcalloc(7 * pctl->ngroups + 4, - sizeof(*pctl->functions), - GFP_KERNEL); + pctl->functions = kzalloc_objs(*pctl->functions, 7 * pctl->ngroups + 4); if (!pctl->functions) return -ENOMEM; @@ -1601,6 +1649,7 @@ int sunxi_pinctrl_init_with_flags(struct platform_device *pdev, pctl->chip->request = gpiochip_generic_request; pctl->chip->free = gpiochip_generic_free; pctl->chip->set_config = gpiochip_generic_config; + pctl->chip->get_direction = sunxi_pinctrl_gpio_get_direction; pctl->chip->direction_input = sunxi_pinctrl_gpio_direction_input; pctl->chip->direction_output = sunxi_pinctrl_gpio_direction_output; pctl->chip->get = sunxi_pinctrl_gpio_get; diff --git a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c index 49c5edeba87f..c6a51bb21215 100644 --- a/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c +++ b/drivers/pinctrl/tegra/pinctrl-tegra-xusb.c @@ -474,14 +474,14 @@ static const struct pinconf_ops tegra_xusb_padctl_pinconf_ops = { #endif }; -static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) +static void tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) { u32 value; - mutex_lock(&padctl->lock); + guard(mutex)(&padctl->lock); if (padctl->enable++ > 0) - goto out; + return; value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; @@ -498,23 +498,19 @@ static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl) value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - -out: - mutex_unlock(&padctl->lock); - return 0; } -static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) +static void tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) { u32 value; - mutex_lock(&padctl->lock); + guard(mutex)(&padctl->lock); if (WARN_ON(padctl->enable == 0)) - goto out; + return; if (--padctl->enable > 0) - goto out; + return; value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN; @@ -531,24 +527,24 @@ static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl) value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM); value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN; padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM); - -out: - mutex_unlock(&padctl->lock); - return 0; } static int tegra_xusb_phy_init(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); - return tegra_xusb_padctl_enable(padctl); + tegra_xusb_padctl_enable(padctl); + + return 0; } static int tegra_xusb_phy_exit(struct phy *phy) { struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy); - return tegra_xusb_padctl_disable(padctl); + tegra_xusb_padctl_disable(padctl); + + return 0; } static int pcie_phy_power_on(struct phy *phy) diff --git a/drivers/pinctrl/vt8500/pinctrl-wmt.c b/drivers/pinctrl/vt8500/pinctrl-wmt.c index 7213a8d4bf09..1c7624a6cb97 100644 --- a/drivers/pinctrl/vt8500/pinctrl-wmt.c +++ b/drivers/pinctrl/vt8500/pinctrl-wmt.c @@ -251,7 +251,7 @@ static int wmt_pctl_dt_node_to_map_pull(struct wmt_pinctrl_data *data, return group; } - configs = kzalloc(sizeof(*configs), GFP_KERNEL); + configs = kzalloc_obj(*configs); if (!configs) return -ENOMEM; @@ -344,8 +344,7 @@ static int wmt_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, if (num_pulls) maps_per_pin++; - cur_map = maps = kcalloc(num_pins * maps_per_pin, sizeof(*maps), - GFP_KERNEL); + cur_map = maps = kzalloc_objs(*maps, num_pins * maps_per_pin); if (!maps) return -ENOMEM; diff --git a/drivers/platform/arm64/huawei-gaokun-ec.c b/drivers/platform/arm64/huawei-gaokun-ec.c index 7170f8eb76f7..a83ddc20b5a3 100644 --- a/drivers/platform/arm64/huawei-gaokun-ec.c +++ b/drivers/platform/arm64/huawei-gaokun-ec.c @@ -680,7 +680,7 @@ static int gaokun_aux_init(struct device *parent, const char *name, struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c index 0b92047265de..c3c4cb6704d1 100644 --- a/drivers/platform/chrome/chromeos_laptop.c +++ b/drivers/platform/chrome/chromeos_laptop.c @@ -807,9 +807,7 @@ chromeos_laptop_prepare_acpi_peripherals(struct chromeos_laptop *cros_laptop, if (!n_peripherals) return 0; - acpi_peripherals = kcalloc(n_peripherals, - sizeof(*src->acpi_peripherals), - GFP_KERNEL); + acpi_peripherals = kzalloc_objs(*src->acpi_peripherals, n_peripherals); if (!acpi_peripherals) return -ENOMEM; @@ -881,7 +879,7 @@ chromeos_laptop_prepare(const struct chromeos_laptop *src) struct chromeos_laptop *cros_laptop; int error; - cros_laptop = kzalloc(sizeof(*cros_laptop), GFP_KERNEL); + cros_laptop = kzalloc_obj(*cros_laptop); if (!cros_laptop) return ERR_PTR(-ENOMEM); diff --git a/drivers/platform/chrome/cros_ec_chardev.c b/drivers/platform/chrome/cros_ec_chardev.c index c9d80ad5b57e..002be3352100 100644 --- a/drivers/platform/chrome/cros_ec_chardev.c +++ b/drivers/platform/chrome/cros_ec_chardev.c @@ -162,7 +162,7 @@ static int cros_ec_chardev_open(struct inode *inode, struct file *filp) struct chardev_priv *priv; int ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c index b712bcff6fb2..c0806c562bb9 100644 --- a/drivers/platform/chrome/cros_ec_typec.c +++ b/drivers/platform/chrome/cros_ec_typec.c @@ -491,6 +491,7 @@ static int cros_typec_init_ports(struct cros_typec_data *typec) cap->driver_data = cros_port; cap->ops = &cros_typec_usb_mode_ops; + cap->no_mode_control = !typec->ap_driven_altmode; cros_port->port = typec_register_port(dev, cap); if (IS_ERR(cros_port->port)) { diff --git a/drivers/platform/chrome/wilco_ec/event.c b/drivers/platform/chrome/wilco_ec/event.c index 196e46a1d489..743cd4839bff 100644 --- a/drivers/platform/chrome/wilco_ec/event.c +++ b/drivers/platform/chrome/wilco_ec/event.c @@ -106,7 +106,7 @@ static struct ec_event_queue *event_queue_new(int capacity) { struct ec_event_queue *q; - q = kzalloc(struct_size(q, entries, capacity), GFP_KERNEL); + q = kzalloc_flex(*q, entries, capacity); if (!q) return NULL; @@ -457,7 +457,7 @@ static int event_device_add(struct acpi_device *adev) return error; } - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kzalloc_obj(*dev_data); if (!dev_data) { error = -ENOMEM; goto free_minor; diff --git a/drivers/platform/chrome/wilco_ec/telemetry.c b/drivers/platform/chrome/wilco_ec/telemetry.c index b18043e31ae4..cadb68fa0a40 100644 --- a/drivers/platform/chrome/wilco_ec/telemetry.c +++ b/drivers/platform/chrome/wilco_ec/telemetry.c @@ -248,7 +248,7 @@ static int telem_open(struct inode *inode, struct file *filp) get_device(&dev_data->dev); - sess_data = kzalloc(sizeof(*sess_data), GFP_KERNEL); + sess_data = kzalloc_obj(*sess_data); if (!sess_data) { atomic_set(&dev_data->available, 1); return -ENOMEM; @@ -370,7 +370,7 @@ static int telem_device_probe(struct platform_device *pdev) return error; } - dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kzalloc_obj(*dev_data); if (!dev_data) { ida_free(&telem_ida, minor); return -ENOMEM; diff --git a/drivers/platform/goldfish/goldfish_pipe.c b/drivers/platform/goldfish/goldfish_pipe.c index abc31971fe6a..75c86f5688c9 100644 --- a/drivers/platform/goldfish/goldfish_pipe.c +++ b/drivers/platform/goldfish/goldfish_pipe.c @@ -660,7 +660,7 @@ static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev) */ u32 new_capacity = 2 * dev->pipes_capacity; struct goldfish_pipe **pipes = - kcalloc(new_capacity, sizeof(*pipes), GFP_ATOMIC); + kzalloc_objs(*pipes, new_capacity, GFP_ATOMIC); if (!pipes) return -ENOMEM; memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); @@ -699,7 +699,7 @@ static int goldfish_pipe_open(struct inode *inode, struct file *file) int status; /* Allocate new pipe kernel object */ - struct goldfish_pipe *pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); + struct goldfish_pipe *pipe = kzalloc_obj(*pipe); if (!pipe) return -ENOMEM; @@ -826,8 +826,7 @@ static int goldfish_pipe_device_init(struct platform_device *pdev, dev->pdev_dev = &pdev->dev; dev->first_signalled_pipe = NULL; dev->pipes_capacity = INITIAL_PIPES_CAPACITY; - dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes), - GFP_KERNEL); + dev->pipes = kzalloc_objs(*dev->pipes, dev->pipes_capacity); if (!dev->pipes) { misc_deregister(&dev->miscdev); return -ENOMEM; diff --git a/drivers/platform/mellanox/mlxbf-tmfifo.c b/drivers/platform/mellanox/mlxbf-tmfifo.c index 14aa87b39be5..3c6408581373 100644 --- a/drivers/platform/mellanox/mlxbf-tmfifo.c +++ b/drivers/platform/mellanox/mlxbf-tmfifo.c @@ -1203,7 +1203,7 @@ static int mlxbf_tmfifo_create_vdev(struct device *dev, goto fail; } - tm_vdev = kzalloc(sizeof(*tm_vdev), GFP_KERNEL); + tm_vdev = kzalloc_obj(*tm_vdev); if (!tm_vdev) { ret = -ENOMEM; goto fail; diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c index 48e9861bb571..4a2d36f7331e 100644 --- a/drivers/platform/olpc/olpc-ec.c +++ b/drivers/platform/olpc/olpc-ec.c @@ -408,7 +408,7 @@ static int olpc_ec_probe(struct platform_device *pdev) if (!ec_driver) return -ENODEV; - ec = kzalloc(sizeof(*ec), GFP_KERNEL); + ec = kzalloc_obj(*ec); if (!ec) return -ENOMEM; diff --git a/drivers/platform/raspberrypi/vchiq-interface/vchiq_arm.c b/drivers/platform/raspberrypi/vchiq-interface/vchiq_arm.c index 6a7b96d3dae6..e78641703252 100644 --- a/drivers/platform/raspberrypi/vchiq-interface/vchiq_arm.c +++ b/drivers/platform/raspberrypi/vchiq-interface/vchiq_arm.c @@ -358,7 +358,7 @@ int vchiq_initialise(struct vchiq_state *state, struct vchiq_instance **instance __func__, i); } - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) { ret = -ENOMEM; goto failed; @@ -618,7 +618,7 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl } } } else { - waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); + waiter = kzalloc_obj(*waiter); if (!waiter) return -ENOMEM; } @@ -1249,8 +1249,7 @@ vchiq_dump_service_use_state(struct vchiq_state *state) if (!arm_state) return; - service_data = kmalloc_array(MAX_SERVICES, sizeof(*service_data), - GFP_KERNEL); + service_data = kmalloc_objs(*service_data, MAX_SERVICES); if (!service_data) return; diff --git a/drivers/platform/raspberrypi/vchiq-interface/vchiq_bus.c b/drivers/platform/raspberrypi/vchiq-interface/vchiq_bus.c index f50e637d505c..011105f1318d 100644 --- a/drivers/platform/raspberrypi/vchiq-interface/vchiq_bus.c +++ b/drivers/platform/raspberrypi/vchiq-interface/vchiq_bus.c @@ -68,7 +68,7 @@ vchiq_device_register(struct device *parent, const char *name) struct vchiq_device *device; int ret; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) return NULL; diff --git a/drivers/platform/raspberrypi/vchiq-interface/vchiq_core.c b/drivers/platform/raspberrypi/vchiq-interface/vchiq_core.c index 83de27cfd469..48d6b1d74329 100644 --- a/drivers/platform/raspberrypi/vchiq-interface/vchiq_core.c +++ b/drivers/platform/raspberrypi/vchiq-interface/vchiq_core.c @@ -2723,7 +2723,7 @@ vchiq_add_service_internal(struct vchiq_state *state, if (ret) return NULL; - service = kzalloc(sizeof(*service), GFP_KERNEL); + service = kzalloc_obj(*service); if (!service) return service; diff --git a/drivers/platform/raspberrypi/vchiq-interface/vchiq_dev.c b/drivers/platform/raspberrypi/vchiq-interface/vchiq_dev.c index 0f3dde2657d6..f1c9c0d4b96a 100644 --- a/drivers/platform/raspberrypi/vchiq-interface/vchiq_dev.c +++ b/drivers/platform/raspberrypi/vchiq-interface/vchiq_dev.c @@ -149,7 +149,7 @@ static int vchiq_ioc_create_service(struct vchiq_instance *instance, if (args->is_open && !instance->connected) return -ENOTCONN; - user_service = kmalloc(sizeof(*user_service), GFP_KERNEL); + user_service = kmalloc_obj(*user_service); if (!user_service) return -ENOMEM; @@ -298,7 +298,7 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, return -EINVAL; if (args->mode == VCHIQ_BULK_MODE_BLOCKING) { - waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); + waiter = kzalloc_obj(*waiter); if (!waiter) { ret = -ENOMEM; goto out; @@ -1185,7 +1185,7 @@ static int vchiq_open(struct inode *inode, struct file *file) return -ENOTCONN; } - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) return -ENOMEM; diff --git a/drivers/platform/raspberrypi/vchiq-mmal/mmal-vchiq.c b/drivers/platform/raspberrypi/vchiq-mmal/mmal-vchiq.c index cd073ed3ea2d..c89c16fb8b33 100644 --- a/drivers/platform/raspberrypi/vchiq-mmal/mmal-vchiq.c +++ b/drivers/platform/raspberrypi/vchiq-mmal/mmal-vchiq.c @@ -190,7 +190,7 @@ get_msg_context(struct vchiq_mmal_instance *instance) int handle; /* todo: should this be allocated from a pool to avoid kzalloc */ - msg_context = kzalloc(sizeof(*msg_context), GFP_KERNEL); + msg_context = kzalloc_obj(*msg_context); if (!msg_context) return ERR_PTR(-ENOMEM); @@ -1898,7 +1898,7 @@ int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instanc goto err_shutdown_vchiq; } - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) { err = -ENOMEM; diff --git a/drivers/platform/surface/aggregator/bus.c b/drivers/platform/surface/aggregator/bus.c index d68d231e716e..4395331be659 100644 --- a/drivers/platform/surface/aggregator/bus.c +++ b/drivers/platform/surface/aggregator/bus.c @@ -83,7 +83,7 @@ struct ssam_device *ssam_device_alloc(struct ssam_controller *ctrl, { struct ssam_device *sdev; - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + sdev = kzalloc_obj(*sdev); if (!sdev) return NULL; diff --git a/drivers/platform/surface/aggregator/controller.c b/drivers/platform/surface/aggregator/controller.c index a265e667538c..6a8430cb9cbf 100644 --- a/drivers/platform/surface/aggregator/controller.c +++ b/drivers/platform/surface/aggregator/controller.c @@ -344,7 +344,7 @@ ssam_nf_refcount_inc(struct ssam_nf *nf, struct ssam_event_registry reg, } } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return ERR_PTR(-ENOMEM); @@ -623,7 +623,7 @@ static struct ssam_event_item *ssam_event_item_alloc(size_t len, gfp_t flags) item->ops.free = __ssam_event_item_free_cached; } else { - item = kzalloc(struct_size(item, event.data, len), flags); + item = kzalloc_flex(*item, event.data, len, flags); if (!item) return NULL; diff --git a/drivers/platform/surface/aggregator/core.c b/drivers/platform/surface/aggregator/core.c index c7e05f7bc199..43d5988fb964 100644 --- a/drivers/platform/surface/aggregator/core.c +++ b/drivers/platform/surface/aggregator/core.c @@ -380,9 +380,9 @@ static int ssam_serdev_setup(struct acpi_device *ssh, struct serdev_device *serd /* -- Power management. ----------------------------------------------------- */ -static void ssam_serial_hub_shutdown(struct device *dev) +static void ssam_serial_hub_shutdown(struct serdev_device *serdev) { - struct ssam_controller *c = dev_get_drvdata(dev); + struct ssam_controller *c = dev_get_drvdata(&serdev->dev); int status; /* @@ -652,7 +652,7 @@ static int ssam_serial_hub_probe(struct serdev_device *serdev) } /* Allocate controller. */ - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return -ENOMEM; @@ -834,12 +834,12 @@ MODULE_DEVICE_TABLE(of, ssam_serial_hub_of_match); static struct serdev_device_driver ssam_serial_hub = { .probe = ssam_serial_hub_probe, .remove = ssam_serial_hub_remove, + .shutdown = ssam_serial_hub_shutdown, .driver = { .name = "surface_serial_hub", .acpi_match_table = ACPI_PTR(ssam_serial_hub_acpi_match), .of_match_table = of_match_ptr(ssam_serial_hub_of_match), .pm = &ssam_serial_hub_pm_ops, - .shutdown = ssam_serial_hub_shutdown, .probe_type = PROBE_PREFER_ASYNCHRONOUS, }, }; diff --git a/drivers/platform/surface/surface3_power.c b/drivers/platform/surface/surface3_power.c index 1ee5239269ae..94fdddc7f207 100644 --- a/drivers/platform/surface/surface3_power.c +++ b/drivers/platform/surface/surface3_power.c @@ -454,8 +454,7 @@ static int mshw0011_install_space_handler(struct i2c_client *client) if (!adev) return -ENODEV; - data = kzalloc(sizeof(struct mshw0011_handler_data), - GFP_KERNEL); + data = kzalloc_obj(struct mshw0011_handler_data); if (!data) return -ENOMEM; diff --git a/drivers/platform/surface/surface_aggregator_cdev.c b/drivers/platform/surface/surface_aggregator_cdev.c index bfaa09d1648b..8929937ba9dc 100644 --- a/drivers/platform/surface/surface_aggregator_cdev.c +++ b/drivers/platform/surface/surface_aggregator_cdev.c @@ -154,7 +154,7 @@ static int ssam_cdev_notifier_register(struct ssam_cdev_client *client, u8 tc, i } /* Allocate new notifier. */ - nf = kzalloc(sizeof(*nf), GFP_KERNEL); + nf = kzalloc_obj(*nf); if (!nf) { mutex_unlock(&client->notifier_lock); return -ENOMEM; @@ -685,7 +685,7 @@ static int ssam_dbg_device_probe(struct platform_device *pdev) if (IS_ERR(ctrl)) return PTR_ERR(ctrl) == -ENODEV ? -EPROBE_DEFER : PTR_ERR(ctrl); - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return -ENOMEM; diff --git a/drivers/platform/surface/surface_dtx.c b/drivers/platform/surface/surface_dtx.c index 97ae010069e4..d6cd56970479 100644 --- a/drivers/platform/surface/surface_dtx.c +++ b/drivers/platform/surface/surface_dtx.c @@ -403,7 +403,7 @@ static int surface_dtx_open(struct inode *inode, struct file *file) struct sdtx_client *client; /* Initialize client. */ - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; @@ -1044,7 +1044,7 @@ static struct sdtx_device *sdtx_device_create(struct device *dev, struct ssam_co struct sdtx_device *ddev; int status; - ddev = kzalloc(sizeof(*ddev), GFP_KERNEL); + ddev = kzalloc_obj(*ddev); if (!ddev) return ERR_PTR(-ENOMEM); diff --git a/drivers/platform/surface/surfacepro3_button.c b/drivers/platform/surface/surfacepro3_button.c index e652c85c9161..9bd39f09c7db 100644 --- a/drivers/platform/surface/surfacepro3_button.c +++ b/drivers/platform/surface/surfacepro3_button.c @@ -199,7 +199,7 @@ static int surface_button_add(struct acpi_device *device) if (!surface_button_check_MSHW0040(device)) return -ENODEV; - button = kzalloc(sizeof(struct surface_button), GFP_KERNEL); + button = kzalloc_obj(struct surface_button); if (!button) return -ENOMEM; diff --git a/drivers/platform/wmi/core.c b/drivers/platform/wmi/core.c index 1601bf9fe135..b8e6b9a421c6 100644 --- a/drivers/platform/wmi/core.c +++ b/drivers/platform/wmi/core.c @@ -1296,7 +1296,7 @@ static int parse_wdg(struct device *wmi_bus_dev, struct platform_device *pdev) continue; } - wblock = kzalloc(sizeof(*wblock), GFP_KERNEL); + wblock = kzalloc_obj(*wblock); if (!wblock) continue; diff --git a/drivers/platform/x86/amd/pmc/mp1_stb.c b/drivers/platform/x86/amd/pmc/mp1_stb.c index 3b9b9f30faa3..753d630f3283 100644 --- a/drivers/platform/x86/amd/pmc/mp1_stb.c +++ b/drivers/platform/x86/amd/pmc/mp1_stb.c @@ -141,7 +141,7 @@ static int amd_stb_handle_efr(struct file *filp) u32 fsize; fsize = dev->dram_size - S2D_RSVD_RAM_SPACE; - stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL); + stb_data_arr = kmalloc_flex(*stb_data_arr, data, fsize); if (!stb_data_arr) return -ENOMEM; @@ -189,7 +189,7 @@ static int amd_stb_debugfs_open_v2(struct inode *inode, struct file *filp) } fsize = min(num_samples, S2D_TELEMETRY_BYTES_MAX); - stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL); + stb_data_arr = kmalloc_flex(*stb_data_arr, data, fsize); if (!stb_data_arr) return -ENOMEM; diff --git a/drivers/platform/x86/amd/wbrf.c b/drivers/platform/x86/amd/wbrf.c index dc10d12bc80d..3281357185d1 100644 --- a/drivers/platform/x86/amd/wbrf.c +++ b/drivers/platform/x86/amd/wbrf.c @@ -72,7 +72,8 @@ static int wbrf_record(struct acpi_device *adev, uint8_t action, struct wbrf_ran */ num_of_elements = 2 * num_of_ranges + 2; - union acpi_object *tmp __free(kfree) = kcalloc(num_of_elements, sizeof(*tmp), GFP_KERNEL); + union acpi_object *tmp __free(kfree) = kzalloc_objs(*tmp, + num_of_elements); if (!tmp) return -ENOMEM; diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 1417e230edbd..fbc30f1f8abd 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c @@ -799,7 +799,7 @@ static int gmux_probe(struct pnp_dev *pnp, const struct pnp_device_id *id) return -ENODEV; } - gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); + gmux_data = kzalloc_obj(*gmux_data); if (!gmux_data) return -ENOMEM; pnp_set_drvdata(pnp, gmux_data); diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c index 9c1a9ad42bc4..5b0987ccc270 100644 --- a/drivers/platform/x86/asus-armoury.c +++ b/drivers/platform/x86/asus-armoury.c @@ -1005,8 +1005,7 @@ static void init_rog_tunables(void) /* Initialize AC power tunables */ ac_limits = power_data->ac_data; if (ac_limits) { - ac_rog_tunables = kzalloc(sizeof(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]), - GFP_KERNEL); + ac_rog_tunables = kzalloc_obj(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]); if (!ac_rog_tunables) goto err_nomem; @@ -1053,8 +1052,7 @@ static void init_rog_tunables(void) /* Initialize DC power tunables */ dc_limits = power_data->dc_data; if (dc_limits) { - dc_rog_tunables = kzalloc(sizeof(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]), - GFP_KERNEL); + dc_rog_tunables = kzalloc_obj(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]); if (!dc_rog_tunables) { kfree(ac_rog_tunables); goto err_nomem; diff --git a/drivers/platform/x86/asus-armoury.h b/drivers/platform/x86/asus-armoury.h index 6e9703bd5017..208f6fe16168 100644 --- a/drivers/platform/x86/asus-armoury.h +++ b/drivers/platform/x86/asus-armoury.h @@ -346,6 +346,35 @@ struct power_data { * _def is not required and will be assumed to be default == max if missing. */ static const struct dmi_system_id power_limits[] = { + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "FA401UM"), + }, + .driver_data = &(struct power_data) { + .ac_data = &(struct power_limits) { + .ppt_pl1_spl_min = 15, + .ppt_pl1_spl_max = 80, + .ppt_pl2_sppt_min = 35, + .ppt_pl2_sppt_max = 80, + .ppt_pl3_fppt_min = 35, + .ppt_pl3_fppt_max = 80, + .nv_dynamic_boost_min = 5, + .nv_dynamic_boost_max = 15, + .nv_temp_target_min = 75, + .nv_temp_target_max = 87, + }, + .dc_data = &(struct power_limits) { + .ppt_pl1_spl_min = 25, + .ppt_pl1_spl_max = 35, + .ppt_pl2_sppt_min = 31, + .ppt_pl2_sppt_max = 44, + .ppt_pl3_fppt_min = 45, + .ppt_pl3_fppt_max = 65, + .nv_temp_target_min = 75, + .nv_temp_target_max = 87, + }, + }, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "FA401UV"), @@ -1457,6 +1486,38 @@ static const struct dmi_system_id power_limits[] = { }, }, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "GX650RX"), + }, + .driver_data = &(struct power_data) { + .ac_data = &(struct power_limits) { + .ppt_pl1_spl_min = 28, + .ppt_pl1_spl_def = 70, + .ppt_pl1_spl_max = 90, + .ppt_pl2_sppt_min = 28, + .ppt_pl2_sppt_def = 70, + .ppt_pl2_sppt_max = 100, + .ppt_pl3_fppt_min = 28, + .ppt_pl3_fppt_def = 110, + .ppt_pl3_fppt_max = 125, + .nv_dynamic_boost_min = 5, + .nv_dynamic_boost_max = 25, + .nv_temp_target_min = 76, + .nv_temp_target_max = 87, + }, + .dc_data = &(struct power_limits) { + .ppt_pl1_spl_min = 28, + .ppt_pl1_spl_max = 50, + .ppt_pl2_sppt_min = 28, + .ppt_pl2_sppt_max = 50, + .ppt_pl3_fppt_min = 28, + .ppt_pl3_fppt_max = 65, + .nv_temp_target_min = 76, + .nv_temp_target_max = 87, + }, + }, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "G513I"), @@ -1708,6 +1769,20 @@ static const struct dmi_system_id power_limits[] = { .requires_fan_curve = true, }, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_NAME, "G733QS"), + }, + .driver_data = &(struct power_data) { + .ac_data = &(struct power_limits) { + .ppt_pl1_spl_min = 15, + .ppt_pl1_spl_max = 80, + .ppt_pl2_sppt_min = 15, + .ppt_pl2_sppt_max = 80, + }, + .requires_fan_curve = false, + }, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "G814J"), diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index a0a411b4f2d6..d96f6af26ff7 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -1831,7 +1831,7 @@ static int asus_acpi_add(struct acpi_device *device) pr_notice("Asus Laptop Support version %s\n", ASUS_LAPTOP_VERSION); - asus = kzalloc(sizeof(struct asus_laptop), GFP_KERNEL); + asus = kzalloc_obj(struct asus_laptop); if (!asus) return -ENOMEM; asus->handle = device->handle; diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 275b56d6a09f..7c0915e097ba 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c @@ -5014,7 +5014,7 @@ static int asus_wmi_add(struct platform_device *pdev) int err; u32 result; - asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); + asus = kzalloc_obj(struct asus_wmi); if (!asus) return -ENOMEM; diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 74d3eb83f56a..e6eed3d65580 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c @@ -400,7 +400,7 @@ static int cmpc_accel_add_v4(struct acpi_device *acpi) struct input_dev *inputdev; struct cmpc_accel *accel; - accel = kmalloc(sizeof(*accel), GFP_KERNEL); + accel = kmalloc_obj(*accel); if (!accel) return -ENOMEM; @@ -650,7 +650,7 @@ static int cmpc_accel_add(struct acpi_device *acpi) struct input_dev *inputdev; struct cmpc_accel *accel; - accel = kmalloc(sizeof(*accel), GFP_KERNEL); + accel = kmalloc_obj(*accel); if (!accel) return -ENOMEM; @@ -964,7 +964,7 @@ static int cmpc_ipml_add(struct acpi_device *acpi) struct ipml200_dev *ipml; struct backlight_properties props; - ipml = kmalloc(sizeof(*ipml), GFP_KERNEL); + ipml = kmalloc_obj(*ipml); if (ipml == NULL) return -ENOMEM; diff --git a/drivers/platform/x86/dell/alienware-wmi-wmax.c b/drivers/platform/x86/dell/alienware-wmi-wmax.c index e69b50162bb1..d1b4df91401b 100644 --- a/drivers/platform/x86/dell/alienware-wmi-wmax.c +++ b/drivers/platform/x86/dell/alienware-wmi-wmax.c @@ -175,7 +175,7 @@ static const struct dmi_system_id awcc_dmi_table[] __initconst = { DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m18"), }, - .driver_data = &generic_quirks, + .driver_data = &g_series_quirks, }, { .ident = "Alienware x15", diff --git a/drivers/platform/x86/dell/dell-smbios-base.c b/drivers/platform/x86/dell/dell-smbios-base.c index 444786102f02..4b7c54b76228 100644 --- a/drivers/platform/x86/dell/dell-smbios-base.c +++ b/drivers/platform/x86/dell/dell-smbios-base.c @@ -495,12 +495,12 @@ static int build_tokens_sysfs(struct platform_device *dev) int ret; int i, j; - token_entries = kcalloc(da_num_tokens, sizeof(*token_entries), GFP_KERNEL); + token_entries = kzalloc_objs(*token_entries, da_num_tokens); if (!token_entries) return -ENOMEM; /* need to store both location and value + terminator*/ - token_attrs = kcalloc((2 * da_num_tokens) + 1, sizeof(*token_attrs), GFP_KERNEL); + token_attrs = kzalloc_objs(*token_attrs, (2 * da_num_tokens) + 1); if (!token_attrs) goto out_allocate_attrs; diff --git a/drivers/platform/x86/dell/dell-wmi-base.c b/drivers/platform/x86/dell/dell-wmi-base.c index 28076929d6af..e7a411ae9ca1 100644 --- a/drivers/platform/x86/dell/dell-wmi-base.c +++ b/drivers/platform/x86/dell/dell-wmi-base.c @@ -80,6 +80,12 @@ static const struct dmi_system_id dell_wmi_smbios_list[] __initconst = { static const struct key_entry dell_wmi_keymap_type_0000[] = { { KE_IGNORE, 0x003a, { KEY_CAPSLOCK } }, + /* Audio mute toggle */ + { KE_KEY, 0x0109, { KEY_MUTE } }, + + /* Mic mute toggle */ + { KE_KEY, 0x0150, { KEY_MICMUTE } }, + /* Meta key lock */ { KE_IGNORE, 0xe000, { KEY_RIGHTMETA } }, @@ -586,7 +592,7 @@ static void handle_dmi_entry(const struct dmi_header *dm, void *opaque) return; } - keymap = kcalloc(hotkey_num, sizeof(struct key_entry), GFP_KERNEL); + keymap = kzalloc_objs(struct key_entry, hotkey_num); if (!keymap) { results->err = -ENOMEM; return; @@ -656,13 +662,8 @@ static int dell_wmi_input_setup(struct wmi_device *wdev) goto err_free_dev; } - keymap = kcalloc(dmi_results.keymap_size + - ARRAY_SIZE(dell_wmi_keymap_type_0000) + - ARRAY_SIZE(dell_wmi_keymap_type_0010) + - ARRAY_SIZE(dell_wmi_keymap_type_0011) + - ARRAY_SIZE(dell_wmi_keymap_type_0012) + - 1, - sizeof(struct key_entry), GFP_KERNEL); + keymap = kzalloc_objs(struct key_entry, + dmi_results.keymap_size + ARRAY_SIZE(dell_wmi_keymap_type_0000) + ARRAY_SIZE(dell_wmi_keymap_type_0010) + ARRAY_SIZE(dell_wmi_keymap_type_0011) + ARRAY_SIZE(dell_wmi_keymap_type_0012) + 1); if (!keymap) { kfree(dmi_results.keymap); err = -ENOMEM; @@ -773,7 +774,7 @@ static int dell_wmi_events_set_enabled(bool enable) struct calling_interface_buffer *buffer; int ret; - buffer = kzalloc(sizeof(struct calling_interface_buffer), GFP_KERNEL); + buffer = kzalloc_obj(struct calling_interface_buffer); if (!buffer) return -ENOMEM; buffer->cmd_class = CLASS_INFO; diff --git a/drivers/platform/x86/dell/dell-wmi-privacy.c b/drivers/platform/x86/dell/dell-wmi-privacy.c index 4b65e1655d42..ed099a431ea4 100644 --- a/drivers/platform/x86/dell/dell-wmi-privacy.c +++ b/drivers/platform/x86/dell/dell-wmi-privacy.c @@ -314,8 +314,8 @@ static int dell_privacy_wmi_probe(struct wmi_device *wdev, const void *context) return -ENOMEM; /* remap the wmi keymap event to new keymap */ - keymap = kcalloc(ARRAY_SIZE(dell_wmi_keymap_type_0012), - sizeof(struct key_entry), GFP_KERNEL); + keymap = kzalloc_objs(struct key_entry, + ARRAY_SIZE(dell_wmi_keymap_type_0012)); if (!keymap) return -ENOMEM; diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c index fc2f58b4cbc6..09996fbdc707 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/enum-attributes.c @@ -119,8 +119,8 @@ int alloc_enum_data(void) wmi_priv.enumeration_instances_count = get_instance_count(DELL_WMI_BIOS_ENUMERATION_ATTRIBUTE_GUID); - wmi_priv.enumeration_data = kcalloc(wmi_priv.enumeration_instances_count, - sizeof(struct enumeration_data), GFP_KERNEL); + wmi_priv.enumeration_data = kzalloc_objs(struct enumeration_data, + wmi_priv.enumeration_instances_count); if (!wmi_priv.enumeration_data) { wmi_priv.enumeration_instances_count = 0; ret = -ENOMEM; diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c index 735248064239..ab5c24722475 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/int-attributes.c @@ -123,8 +123,8 @@ int alloc_int_data(void) int ret = 0; wmi_priv.integer_instances_count = get_instance_count(DELL_WMI_BIOS_INTEGER_ATTRIBUTE_GUID); - wmi_priv.integer_data = kcalloc(wmi_priv.integer_instances_count, - sizeof(struct integer_data), GFP_KERNEL); + wmi_priv.integer_data = kzalloc_objs(struct integer_data, + wmi_priv.integer_instances_count); if (!wmi_priv.integer_data) { wmi_priv.integer_instances_count = 0; ret = -ENOMEM; diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c index 3167e06d416e..be939b731063 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/passobj-attributes.c @@ -143,7 +143,8 @@ int alloc_po_data(void) int ret = 0; wmi_priv.po_instances_count = get_instance_count(DELL_WMI_BIOS_PASSOBJ_ATTRIBUTE_GUID); - wmi_priv.po_data = kcalloc(wmi_priv.po_instances_count, sizeof(struct po_data), GFP_KERNEL); + wmi_priv.po_data = kzalloc_objs(struct po_data, + wmi_priv.po_instances_count); if (!wmi_priv.po_data) { wmi_priv.po_instances_count = 0; ret = -ENOMEM; diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c b/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c index 86ec962aace9..e586f7957946 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/passwordattr-interface.c @@ -93,7 +93,6 @@ int set_new_password(const char *password_type, const char *new) if (ret < 0) goto out; - print_hex_dump_bytes("set new password data: ", DUMP_PREFIX_NONE, buffer, buffer_size); ret = call_password_interface(wmi_priv.password_attr_wdev, buffer, buffer_size); /* on success copy the new password to current password */ if (!ret) diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c b/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c index 0d2c74f8d1aa..41e19f0391b2 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/string-attributes.c @@ -108,8 +108,8 @@ int alloc_str_data(void) int ret = 0; wmi_priv.str_instances_count = get_instance_count(DELL_WMI_BIOS_STRING_ATTRIBUTE_GUID); - wmi_priv.str_data = kcalloc(wmi_priv.str_instances_count, - sizeof(struct str_data), GFP_KERNEL); + wmi_priv.str_data = kzalloc_objs(struct str_data, + wmi_priv.str_instances_count); if (!wmi_priv.str_data) { wmi_priv.str_instances_count = 0; ret = -ENOMEM; diff --git a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c index f5402b714657..9dddab6c9397 100644 --- a/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c +++ b/drivers/platform/x86/dell/dell-wmi-sysman/sysman.c @@ -460,7 +460,7 @@ static int init_bios_attributes(int attr_type, const char *guid) } /* build attribute */ - attr_name_kobj = kzalloc(sizeof(*attr_name_kobj), GFP_KERNEL); + attr_name_kobj = kzalloc_obj(*attr_name_kobj); if (!attr_name_kobj) { retval = -ENOMEM; goto err_attr_init; diff --git a/drivers/platform/x86/dell/dell_rbu.c b/drivers/platform/x86/dell/dell_rbu.c index 403df9bd9522..eb50f1d75d0c 100644 --- a/drivers/platform/x86/dell/dell_rbu.c +++ b/drivers/platform/x86/dell/dell_rbu.c @@ -111,7 +111,7 @@ static int create_packet(void *data, size_t length) __must_hold(&rbu_data.lock) spin_unlock(&rbu_data.lock); - newpacket = kzalloc(sizeof (struct packet_data), GFP_KERNEL); + newpacket = kzalloc_obj(struct packet_data); if (!newpacket) { pr_warn("failed to allocate new packet\n"); diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index d1908815f5a2..974f55e0b36f 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1366,7 +1366,7 @@ static int eeepc_acpi_add(struct acpi_device *device) int result; pr_notice(EEEPC_LAPTOP_NAME "\n"); - eeepc = kzalloc(sizeof(struct eeepc_laptop), GFP_KERNEL); + eeepc = kzalloc_obj(struct eeepc_laptop); if (!eeepc) return -ENOMEM; eeepc->handle = device->handle; diff --git a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c index 51e8977d3eb4..27fd6cd21529 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +++ b/drivers/platform/x86/hp/hp-bioscfg/bioscfg.c @@ -588,7 +588,7 @@ static int hp_add_other_attributes(int attr_type) int ret; char *attr_name; - attr_name_kobj = kzalloc(sizeof(*attr_name_kobj), GFP_KERNEL); + attr_name_kobj = kzalloc_obj(*attr_name_kobj); if (!attr_name_kobj) return -ENOMEM; @@ -711,7 +711,7 @@ static int hp_init_bios_package_attribute(enum hp_wmi_data_type attr_type, } /* build attribute */ - attr_name_kobj = kzalloc(sizeof(*attr_name_kobj), GFP_KERNEL); + attr_name_kobj = kzalloc_obj(*attr_name_kobj); if (!attr_name_kobj) { ret = -ENOMEM; goto pack_attr_exit; @@ -810,7 +810,7 @@ static int hp_init_bios_buffer_attribute(enum hp_wmi_data_type attr_type, } /* build attribute */ - attr_name_kobj = kzalloc(sizeof(*attr_name_kobj), GFP_KERNEL); + attr_name_kobj = kzalloc_obj(*attr_name_kobj); if (!attr_name_kobj) { ret = -ENOMEM; goto buff_attr_exit; diff --git a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c index f346aad8e9d8..af4d1920d488 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c @@ -94,8 +94,11 @@ int hp_alloc_enumeration_data(void) bioscfg_drv.enumeration_instances_count = hp_get_instance_count(HP_WMI_BIOS_ENUMERATION_GUID); - bioscfg_drv.enumeration_data = kcalloc(bioscfg_drv.enumeration_instances_count, - sizeof(*bioscfg_drv.enumeration_data), GFP_KERNEL); + if (!bioscfg_drv.enumeration_instances_count) + return -EINVAL; + bioscfg_drv.enumeration_data = kvcalloc(bioscfg_drv.enumeration_instances_count, + sizeof(*bioscfg_drv.enumeration_data), GFP_KERNEL); + if (!bioscfg_drv.enumeration_data) { bioscfg_drv.enumeration_instances_count = 0; return -ENOMEM; @@ -444,6 +447,6 @@ void hp_exit_enumeration_attributes(void) } bioscfg_drv.enumeration_instances_count = 0; - kfree(bioscfg_drv.enumeration_data); + kvfree(bioscfg_drv.enumeration_data); bioscfg_drv.enumeration_data = NULL; } diff --git a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c index 63b1fda2be4e..d96e160953e3 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/int-attributes.c @@ -109,8 +109,8 @@ static const struct attribute_group integer_attr_group = { int hp_alloc_integer_data(void) { bioscfg_drv.integer_instances_count = hp_get_instance_count(HP_WMI_BIOS_INTEGER_GUID); - bioscfg_drv.integer_data = kcalloc(bioscfg_drv.integer_instances_count, - sizeof(*bioscfg_drv.integer_data), GFP_KERNEL); + bioscfg_drv.integer_data = kzalloc_objs(*bioscfg_drv.integer_data, + bioscfg_drv.integer_instances_count); if (!bioscfg_drv.integer_data) { bioscfg_drv.integer_instances_count = 0; diff --git a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c index 6a31f47ce3f5..f09489a085c8 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/order-list-attributes.c @@ -98,9 +98,8 @@ int hp_alloc_ordered_list_data(void) { bioscfg_drv.ordered_list_instances_count = hp_get_instance_count(HP_WMI_BIOS_ORDERED_LIST_GUID); - bioscfg_drv.ordered_list_data = kcalloc(bioscfg_drv.ordered_list_instances_count, - sizeof(*bioscfg_drv.ordered_list_data), - GFP_KERNEL); + bioscfg_drv.ordered_list_data = kzalloc_objs(*bioscfg_drv.ordered_list_data, + bioscfg_drv.ordered_list_instances_count); if (!bioscfg_drv.ordered_list_data) { bioscfg_drv.ordered_list_instances_count = 0; return -ENOMEM; diff --git a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c index ec79d9d50377..4d79eb8056a5 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c @@ -185,8 +185,8 @@ static const struct attribute_group password_attr_group = { int hp_alloc_password_data(void) { bioscfg_drv.password_instances_count = hp_get_instance_count(HP_WMI_BIOS_PASSWORD_GUID); - bioscfg_drv.password_data = kcalloc(bioscfg_drv.password_instances_count, - sizeof(*bioscfg_drv.password_data), GFP_KERNEL); + bioscfg_drv.password_data = kzalloc_objs(*bioscfg_drv.password_data, + bioscfg_drv.password_instances_count); if (!bioscfg_drv.password_data) { bioscfg_drv.password_instances_count = 0; return -ENOMEM; diff --git a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c index 7b885d25650c..fe5a9a3a4ef1 100644 --- a/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c +++ b/drivers/platform/x86/hp/hp-bioscfg/string-attributes.c @@ -101,8 +101,8 @@ static const struct attribute_group string_attr_group = { int hp_alloc_string_data(void) { bioscfg_drv.string_instances_count = hp_get_instance_count(HP_WMI_BIOS_STRING_GUID); - bioscfg_drv.string_data = kcalloc(bioscfg_drv.string_instances_count, - sizeof(*bioscfg_drv.string_data), GFP_KERNEL); + bioscfg_drv.string_data = kzalloc_objs(*bioscfg_drv.string_data, + bioscfg_drv.string_instances_count); if (!bioscfg_drv.string_data) { bioscfg_drv.string_instances_count = 0; return -ENOMEM; diff --git a/drivers/platform/x86/hp/hp-wmi.c b/drivers/platform/x86/hp/hp-wmi.c index 304d9ac63c8a..68ede7e5757a 100644 --- a/drivers/platform/x86/hp/hp-wmi.c +++ b/drivers/platform/x86/hp/hp-wmi.c @@ -146,6 +146,7 @@ static const char * const omen_thermal_profile_boards[] = { "8900", "8901", "8902", "8912", "8917", "8918", "8949", "894A", "89EB", "8A15", "8A42", "8BAD", + "8E41", }; /* DMI Board names of Omen laptops that are specifically set to be thermal @@ -166,17 +167,26 @@ static const char * const omen_timed_thermal_profile_boards[] = { "8BAD", }; -/* DMI Board names of Victus 16-d1xxx laptops */ +/* DMI Board names of Victus 16-d laptops */ static const char * const victus_thermal_profile_boards[] = { + "88F8", "8A25", }; /* DMI Board names of Victus 16-r and Victus 16-s laptops */ static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = { + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") }, + .driver_data = (void *)&omen_v1_thermal_params, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") }, .driver_data = (void *)&victus_s_thermal_params, }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") }, + .driver_data = (void *)&omen_v1_thermal_params, + }, { .matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") }, .driver_data = (void *)&victus_s_thermal_params, diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 8a4c54089ace..93cca17fdf58 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -854,7 +854,7 @@ static __init int huawei_wmi_init(void) struct platform_device *pdev; int err; - huawei_wmi = kzalloc(sizeof(struct huawei_wmi), GFP_KERNEL); + huawei_wmi = kzalloc_obj(struct huawei_wmi); if (!huawei_wmi) return -ENOMEM; diff --git a/drivers/platform/x86/intel/hid.c b/drivers/platform/x86/intel/hid.c index 0f8684f4464b..95c405c8bac0 100644 --- a/drivers/platform/x86/intel/hid.c +++ b/drivers/platform/x86/intel/hid.c @@ -135,6 +135,13 @@ static const struct dmi_system_id button_array_table[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Tablet Gen 2"), }, }, + { + .ident = "Lenovo ThinkPad X1 Fold 16 Gen 1", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "ThinkPad X1 Fold 16 Gen 1"), + }, + }, { .ident = "Microsoft Surface Go 3", .matches = { @@ -189,6 +196,18 @@ static const struct dmi_system_id dmi_vgbs_allow_list[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Dell Pro Rugged 12 Tablet RA02260"), }, }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14 Plus 2-in-1 DB04250"), + }, + }, + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell 16 Plus 2-in-1 DB06250"), + }, + }, { } }; diff --git a/drivers/platform/x86/intel/ifs/core.c b/drivers/platform/x86/intel/ifs/core.c index b73e582128c9..3dafa28a1010 100644 --- a/drivers/platform/x86/intel/ifs/core.c +++ b/drivers/platform/x86/intel/ifs/core.c @@ -125,7 +125,7 @@ static int __init ifs_init(void) if (rdmsrq_safe(MSR_INTEGRITY_CAPS, &msrval)) return -ENODEV; - ifs_pkg_auth = kmalloc_array(topology_max_packages(), sizeof(bool), GFP_KERNEL); + ifs_pkg_auth = kmalloc_objs(bool, topology_max_packages()); if (!ifs_pkg_auth) return -ENOMEM; diff --git a/drivers/platform/x86/intel/int1092/intel_sar.c b/drivers/platform/x86/intel/int1092/intel_sar.c index e526841aff60..88822023a149 100644 --- a/drivers/platform/x86/intel/int1092/intel_sar.c +++ b/drivers/platform/x86/intel/int1092/intel_sar.c @@ -91,8 +91,8 @@ static acpi_status parse_package(struct wwan_sar_context *context, union acpi_ob item->package.count <= data->total_dev_mode) return AE_ERROR; - data->device_mode_info = kmalloc_array(data->total_dev_mode, - sizeof(struct wwan_device_mode_info), GFP_KERNEL); + data->device_mode_info = kmalloc_objs(struct wwan_device_mode_info, + data->total_dev_mode); if (!data->device_mode_info) return AE_ERROR; @@ -248,7 +248,7 @@ static int sar_probe(struct platform_device *device) int reg; int result; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return -ENOMEM; diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c index 1505fc3ef7a8..1c65ce87cde0 100644 --- a/drivers/platform/x86/intel/int3472/discrete.c +++ b/drivers/platform/x86/intel/int3472/discrete.c @@ -107,7 +107,7 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472, int ret; struct gpiod_lookup_table *lookup __free(kfree) = - kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + kzalloc_flex(*lookup, table, 2); if (!lookup) return ERR_PTR(-ENOMEM); @@ -223,6 +223,10 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3 *con_id = "avdd"; *gpio_flags = GPIO_ACTIVE_HIGH; break; + case INT3472_GPIO_TYPE_DOVDD: + *con_id = "dovdd"; + *gpio_flags = GPIO_ACTIVE_HIGH; + break; case INT3472_GPIO_TYPE_HANDSHAKE: *con_id = "dvdd"; *gpio_flags = GPIO_ACTIVE_HIGH; @@ -251,6 +255,7 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3 * 0x0b Power enable * 0x0c Clock enable * 0x0d Privacy LED + * 0x10 DOVDD (digital I/O voltage) * 0x13 Hotplug detect * * There are some known platform specific quirks where that does not quite @@ -332,6 +337,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, case INT3472_GPIO_TYPE_CLK_ENABLE: case INT3472_GPIO_TYPE_PRIVACY_LED: case INT3472_GPIO_TYPE_POWER_ENABLE: + case INT3472_GPIO_TYPE_DOVDD: case INT3472_GPIO_TYPE_HANDSHAKE: gpio = skl_int3472_gpiod_get_from_temp_lookup(int3472, agpio, con_id, gpio_flags); if (IS_ERR(gpio)) { @@ -356,6 +362,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, case INT3472_GPIO_TYPE_POWER_ENABLE: second_sensor = int3472->quirks.avdd_second_sensor; fallthrough; + case INT3472_GPIO_TYPE_DOVDD: case INT3472_GPIO_TYPE_HANDSHAKE: ret = skl_int3472_register_regulator(int3472, gpio, enable_time_us, con_id, second_sensor); diff --git a/drivers/platform/x86/intel/int3472/tps68470.c b/drivers/platform/x86/intel/int3472/tps68470.c index 0133405697dc..a496075c0d2a 100644 --- a/drivers/platform/x86/intel/int3472/tps68470.c +++ b/drivers/platform/x86/intel/int3472/tps68470.c @@ -180,7 +180,7 @@ static int skl_int3472_tps68470_probe(struct i2c_client *client) if (!board_data) return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n"); - cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL); + cells = kzalloc_objs(*cells, TPS68470_WIN_MFD_CELL_COUNT); if (!cells) return -ENOMEM; diff --git a/drivers/platform/x86/intel/pmc/pltdrv.c b/drivers/platform/x86/intel/pmc/pltdrv.c index 3141d6cbc41b..71ebb9ea1be2 100644 --- a/drivers/platform/x86/intel/pmc/pltdrv.c +++ b/drivers/platform/x86/intel/pmc/pltdrv.c @@ -65,7 +65,7 @@ static int __init pmc_core_platform_init(void) if (!x86_match_cpu(intel_pmc_core_platform_ids)) return -ENODEV; - pmc_core_device = kzalloc(sizeof(*pmc_core_device), GFP_KERNEL); + pmc_core_device = kzalloc_obj(*pmc_core_device); if (!pmc_core_device) return -ENOMEM; diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c index a4dfca6cac19..a52803bfe124 100644 --- a/drivers/platform/x86/intel/pmt/telemetry.c +++ b/drivers/platform/x86/intel/pmt/telemetry.c @@ -107,7 +107,7 @@ static int pmt_telem_add_endpoint(struct intel_vsec_device *ivdev, struct telem_endpoint *ep; /* Endpoint lifetimes are managed by kref, not devres */ - entry->ep = kzalloc(sizeof(*(entry->ep)), GFP_KERNEL); + entry->ep = kzalloc_obj(*(entry->ep)); if (!entry->ep) return -ENOMEM; diff --git a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c index 7449873c3d40..1c48bf6d5457 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_if_common.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_if_common.c @@ -89,7 +89,7 @@ static int isst_store_new_cmd(int cmd, u32 cpu, int mbox_cmd_type, u32 param, { struct isst_cmd *sst_cmd; - sst_cmd = kmalloc(sizeof(*sst_cmd), GFP_KERNEL); + sst_cmd = kmalloc_obj(*sst_cmd); if (!sst_cmd) return -ENOMEM; @@ -425,15 +425,11 @@ static int isst_if_cpu_info_init(void) { int ret; - isst_cpu_info = kcalloc(num_possible_cpus(), - sizeof(*isst_cpu_info), - GFP_KERNEL); + isst_cpu_info = kzalloc_objs(*isst_cpu_info, num_possible_cpus()); if (!isst_cpu_info) return -ENOMEM; - isst_pkg_info = kcalloc(topology_max_packages(), - sizeof(*isst_pkg_info), - GFP_KERNEL); + isst_pkg_info = kzalloc_objs(*isst_pkg_info, topology_max_packages()); if (!isst_pkg_info) { kfree(isst_cpu_info); return -ENOMEM; diff --git a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c index 9c078c8acb50..b8cdaa233ea9 100644 --- a/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c +++ b/drivers/platform/x86/intel/speed_select_if/isst_tpmi_core.c @@ -1603,7 +1603,7 @@ int tpmi_sst_dev_add(struct auxiliary_device *auxdev) * devm_* allocation here as each partition is a * different device, which can be unbound. */ - tpmi_sst = kzalloc(sizeof(*tpmi_sst), GFP_KERNEL); + tpmi_sst = kzalloc_obj(*tpmi_sst); if (!tpmi_sst) { ret = -ENOMEM; goto unlock_exit; @@ -1819,9 +1819,8 @@ int tpmi_sst_init(void) goto init_done; } - isst_common.sst_inst = kcalloc(topology_max_packages(), - sizeof(*isst_common.sst_inst), - GFP_KERNEL); + isst_common.sst_inst = kzalloc_objs(*isst_common.sst_inst, + topology_max_packages()); if (!isst_common.sst_inst) { ret = -ENOMEM; goto init_done; diff --git a/drivers/platform/x86/intel/tpmi_power_domains.c b/drivers/platform/x86/intel/tpmi_power_domains.c index 7d93119a4c30..833052dc34d2 100644 --- a/drivers/platform/x86/intel/tpmi_power_domains.c +++ b/drivers/platform/x86/intel/tpmi_power_domains.c @@ -221,8 +221,8 @@ static int __init tpmi_init(void) if (ret) return ret; - tpmi_power_domain_mask = kcalloc(size_mul(topology_max_packages(), MAX_POWER_DOMAINS), - sizeof(*tpmi_power_domain_mask), GFP_KERNEL); + tpmi_power_domain_mask = kzalloc_objs(*tpmi_power_domain_mask, + size_mul(topology_max_packages(), MAX_POWER_DOMAINS)); if (!tpmi_power_domain_mask) return -ENOMEM; diff --git a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c index 0dfc552b2802..667f2c8b9594 100644 --- a/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c +++ b/drivers/platform/x86/intel/uncore-frequency/uncore-frequency.c @@ -278,8 +278,7 @@ static int __init intel_uncore_init(void) uncore_max_entries = topology_max_packages() * topology_max_dies_per_package(); - uncore_instances = kcalloc(uncore_max_entries, - sizeof(*uncore_instances), GFP_KERNEL); + uncore_instances = kzalloc_objs(*uncore_instances, uncore_max_entries); if (!uncore_instances) return -ENOMEM; diff --git a/drivers/platform/x86/intel/vsec.c b/drivers/platform/x86/intel/vsec.c index 012d87878afd..5059d320edf8 100644 --- a/drivers/platform/x86/intel/vsec.c +++ b/drivers/platform/x86/intel/vsec.c @@ -299,11 +299,11 @@ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *he return -EINVAL; } - intel_vsec_dev = kzalloc(sizeof(*intel_vsec_dev), GFP_KERNEL); + intel_vsec_dev = kzalloc_obj(*intel_vsec_dev); if (!intel_vsec_dev) return -ENOMEM; - res = kcalloc(header->num_entries, sizeof(*res), GFP_KERNEL); + res = kzalloc_objs(*res, header->num_entries); if (!res) return -ENOMEM; diff --git a/drivers/platform/x86/intel/vsec_tpmi.c b/drivers/platform/x86/intel/vsec_tpmi.c index 7748b5557a18..98846e88d3d0 100644 --- a/drivers/platform/x86/intel/vsec_tpmi.c +++ b/drivers/platform/x86/intel/vsec_tpmi.c @@ -622,11 +622,11 @@ static int tpmi_create_device(struct intel_tpmi_info *tpmi_info, if (!name) return -EOPNOTSUPP; - res = kcalloc(pfs->pfs_header.num_entries, sizeof(*res), GFP_KERNEL); + res = kzalloc_objs(*res, pfs->pfs_header.num_entries); if (!res) return -ENOMEM; - feature_vsec_dev = kzalloc(sizeof(*feature_vsec_dev), GFP_KERNEL); + feature_vsec_dev = kzalloc_obj(*feature_vsec_dev); if (!feature_vsec_dev) { kfree(res); return -ENOMEM; diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 3acf6149a9ec..a2472ad10f37 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c @@ -573,7 +573,7 @@ __intel_scu_ipc_register(struct device *parent, if (ipcdev) return ERR_PTR(-EBUSY); - scu = kzalloc(sizeof(*scu), GFP_KERNEL); + scu = kzalloc_obj(*scu); if (!scu) return ERR_PTR(-ENOMEM); diff --git a/drivers/platform/x86/lenovo/ideapad-laptop.c b/drivers/platform/x86/lenovo/ideapad-laptop.c index 06ac002a1ebc..ae1ebb071fab 100644 --- a/drivers/platform/x86/lenovo/ideapad-laptop.c +++ b/drivers/platform/x86/lenovo/ideapad-laptop.c @@ -1172,7 +1172,7 @@ static int ideapad_dytc_profile_init(struct ideapad_private *priv) return -ENODEV; } - priv->dytc = kzalloc(sizeof(*priv->dytc), GFP_KERNEL); + priv->dytc = kzalloc_obj(*priv->dytc); if (!priv->dytc) return -ENOMEM; diff --git a/drivers/platform/x86/lenovo/think-lmi.c b/drivers/platform/x86/lenovo/think-lmi.c index c45f0206b4ab..e215e86e3db7 100644 --- a/drivers/platform/x86/lenovo/think-lmi.c +++ b/drivers/platform/x86/lenovo/think-lmi.c @@ -1593,7 +1593,7 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type, { struct tlmi_pwd_setting *new_pwd; - new_pwd = kzalloc(sizeof(struct tlmi_pwd_setting), GFP_KERNEL); + new_pwd = kzalloc_obj(struct tlmi_pwd_setting); if (!new_pwd) return NULL; @@ -1668,7 +1668,7 @@ static int tlmi_analyze(struct wmi_device *wdev) strreplace(item, ',', '\0'); /* Create a setting entry */ - setting = kzalloc(sizeof(*setting), GFP_KERNEL); + setting = kzalloc_obj(*setting); if (!setting) { ret = -ENOMEM; kfree(item); diff --git a/drivers/platform/x86/lenovo/thinkpad_acpi.c b/drivers/platform/x86/lenovo/thinkpad_acpi.c index 6b0e4b4c485e..8982d92dfd97 100644 --- a/drivers/platform/x86/lenovo/thinkpad_acpi.c +++ b/drivers/platform/x86/lenovo/thinkpad_acpi.c @@ -873,7 +873,7 @@ static int __init register_tpacpi_subdriver(struct ibm_struct *ibm) BUG_ON(!ibm->acpi); - ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL); + ibm->acpi->driver = kzalloc_obj(struct acpi_driver); if (!ibm->acpi->driver) { pr_err("failed to allocate memory for ibm->acpi->driver\n"); return -ENOMEM; @@ -1197,7 +1197,7 @@ static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id, BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]); - atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL); + atp_rfk = kzalloc_obj(struct tpacpi_rfk); if (atp_rfk) atp_rfk->rfkill = rfkill_alloc(name, &tpacpi_pdev->dev, @@ -5817,8 +5817,7 @@ static int __init led_init(struct ibm_init_struct *iibm) if (led_supported == TPACPI_LED_NONE) return -ENODEV; - tpacpi_leds = kcalloc(TPACPI_LED_NUMLEDS, sizeof(*tpacpi_leds), - GFP_KERNEL); + tpacpi_leds = kzalloc_objs(*tpacpi_leds, TPACPI_LED_NUMLEDS); if (!tpacpi_leds) { pr_err("Out of memory for LED data\n"); return -ENOMEM; @@ -9526,14 +9525,16 @@ static int tpacpi_battery_get(int what, int battery, int *ret) { switch (what) { case THRESHOLD_START: - if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_START, ret, battery)) + if (!battery_info.batteries[battery].start_support || + ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_START, ret, battery))) return -ENODEV; /* The value is in the low 8 bits of the response */ *ret = *ret & 0xFF; return 0; case THRESHOLD_STOP: - if ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_STOP, ret, battery)) + if (!battery_info.batteries[battery].stop_support || + ACPI_FAILURE(tpacpi_battery_acpi_eval(GET_STOP, ret, battery))) return -ENODEV; /* Value is in lower 8 bits */ *ret = *ret & 0xFF; diff --git a/drivers/platform/x86/oxpec.c b/drivers/platform/x86/oxpec.c index 144a454103b9..6d4a53a2ed60 100644 --- a/drivers/platform/x86/oxpec.c +++ b/drivers/platform/x86/oxpec.c @@ -11,7 +11,7 @@ * * Copyright (C) 2022 Joaquín I. Aramendía * Copyright (C) 2024 Derek J. Clark - * Copyright (C) 2025 Antheas Kapenekakis + * Copyright (C) 2025-2026 Antheas Kapenekakis */ #include @@ -114,6 +114,13 @@ static const struct dmi_system_id dmi_table[] = { }, .driver_data = (void *)aok_zoe_a1, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "AOKZOE A2 Pro"), + }, + .driver_data = (void *)aok_zoe_a1, + }, { .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "AOKZOE"), @@ -142,6 +149,13 @@ static const struct dmi_system_id dmi_table[] = { }, .driver_data = (void *)oxp_2, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER APEX"), + }, + .driver_data = (void *)oxp_fly, + }, { .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), @@ -212,6 +226,13 @@ static const struct dmi_system_id dmi_table[] = { }, .driver_data = (void *)oxp_mini_amd_pro, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1z"), + }, + .driver_data = (void *)oxp_x1, + }, { .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), @@ -226,6 +247,13 @@ static const struct dmi_system_id dmi_table[] = { }, .driver_data = (void *)oxp_x1, }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), + DMI_EXACT_MATCH(DMI_BOARD_NAME, "ONEXPLAYER X1Air"), + }, + .driver_data = (void *)oxp_x1, + }, { .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ONE-NETBOOK"), diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 937f1a5b78ed..d923ddaa4849 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c @@ -1017,7 +1017,7 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) */ num_sifr++; - pcc = kzalloc(sizeof(struct pcc_acpi), GFP_KERNEL); + pcc = kzalloc_obj(struct pcc_acpi); if (!pcc) { pr_err("Couldn't allocate mem for pcc"); return -ENOMEM; diff --git a/drivers/platform/x86/pmc_atom.c b/drivers/platform/x86/pmc_atom.c index 0aa7076bc9cc..48c2a0e59d18 100644 --- a/drivers/platform/x86/pmc_atom.c +++ b/drivers/platform/x86/pmc_atom.c @@ -428,7 +428,7 @@ static int pmc_setup_clks(struct pci_dev *pdev, void __iomem *pmc_regmap, struct platform_device *clkdev; struct pmc_clk_data *clk_data; - clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + clk_data = kzalloc_obj(*clk_data); if (!clk_data) return -ENOMEM; diff --git a/drivers/platform/x86/redmi-wmi.c b/drivers/platform/x86/redmi-wmi.c index 949236b93a32..e5cb348e3a39 100644 --- a/drivers/platform/x86/redmi-wmi.c +++ b/drivers/platform/x86/redmi-wmi.c @@ -20,7 +20,10 @@ static const struct key_entry redmi_wmi_keymap[] = { {KE_KEY, 0x00000201, {KEY_SELECTIVE_SCREENSHOT}}, {KE_KEY, 0x00000301, {KEY_ALL_APPLICATIONS}}, - {KE_KEY, 0x00001b01, {KEY_SETUP}}, + {KE_KEY, 0x00001b01, {KEY_CONFIG}}, + {KE_KEY, 0x00011b01, {KEY_CONFIG}}, + {KE_KEY, 0x00010101, {KEY_SWITCHVIDEOMODE}}, + {KE_KEY, 0x00001a01, {KEY_REFRESH_RATE_TOGGLE}}, /* AI button has code for each position */ {KE_KEY, 0x00011801, {KEY_ASSISTANT}}, @@ -32,6 +35,26 @@ static const struct key_entry redmi_wmi_keymap[] = { {KE_IGNORE, 0x00050501, {}}, {KE_IGNORE, 0x000a0501, {}}, + /* Xiaomi G Command Center */ + {KE_KEY, 0x00010a01, {KEY_VENDOR}}, + + /* OEM preset power mode */ + {KE_IGNORE, 0x00011601, {}}, + {KE_IGNORE, 0x00021601, {}}, + {KE_IGNORE, 0x00031601, {}}, + {KE_IGNORE, 0x00041601, {}}, + + /* Fn Lock state */ + {KE_IGNORE, 0x00000701, {}}, + {KE_IGNORE, 0x00010701, {}}, + + /* Fn+`/1/2/3/4 */ + {KE_KEY, 0x00011101, {KEY_F13}}, + {KE_KEY, 0x00011201, {KEY_F14}}, + {KE_KEY, 0x00011301, {KEY_F15}}, + {KE_KEY, 0x00011401, {KEY_F16}}, + {KE_KEY, 0x00011501, {KEY_F17}}, + {KE_END} }; diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index 9d43a12db73c..710f3d5bf84c 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c @@ -1671,7 +1671,7 @@ static int __init samsung_init(void) if (!force && !dmi_check_system(samsung_dmi_table)) return -ENODEV; - samsung = kzalloc(sizeof(*samsung), GFP_KERNEL); + samsung = kzalloc_obj(*samsung); if (!samsung) return -ENOMEM; diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 56beebc38850..d3e7a52c22a7 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -829,7 +829,7 @@ static int sony_nc_handles_setup(struct platform_device *pd) { int i, r, result, arg; - handles = kzalloc(sizeof(*handles), GFP_KERNEL); + handles = kzalloc_obj(*handles); if (!handles) return -ENOMEM; @@ -1902,7 +1902,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd, } } - kbdbl_ctl = kzalloc(sizeof(*kbdbl_ctl), GFP_KERNEL); + kbdbl_ctl = kzalloc_obj(*kbdbl_ctl); if (!kbdbl_ctl) return -ENOMEM; @@ -2070,7 +2070,7 @@ static int sony_nc_battery_care_setup(struct platform_device *pd, { int ret = 0; - bcare_ctl = kzalloc(sizeof(struct battery_care_control), GFP_KERNEL); + bcare_ctl = kzalloc_obj(struct battery_care_control); if (!bcare_ctl) return -ENOMEM; @@ -2222,7 +2222,7 @@ static ssize_t sony_nc_thermal_mode_show(struct device *dev, static int sony_nc_thermal_setup(struct platform_device *pd) { int ret = 0; - th_handle = kzalloc(sizeof(struct snc_thermal_ctrl), GFP_KERNEL); + th_handle = kzalloc_obj(struct snc_thermal_ctrl); if (!th_handle) return -ENOMEM; @@ -2370,7 +2370,7 @@ static int sony_nc_lid_resume_setup(struct platform_device *pd, if (sony_call_snc_handle(handle, 0x0000, &result)) return -EIO; - lid_ctl = kzalloc(sizeof(struct snc_lid_resume_control), GFP_KERNEL); + lid_ctl = kzalloc_obj(struct snc_lid_resume_control); if (!lid_ctl) return -ENOMEM; @@ -2497,7 +2497,7 @@ static int sony_nc_gfx_switch_setup(struct platform_device *pd, { unsigned int result; - gfxs_ctl = kzalloc(sizeof(struct snc_gfx_switch_control), GFP_KERNEL); + gfxs_ctl = kzalloc_obj(struct snc_gfx_switch_control); if (!gfxs_ctl) return -ENOMEM; @@ -2576,7 +2576,7 @@ static int sony_nc_highspeed_charging_setup(struct platform_device *pd) return 0; } - hsc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + hsc_handle = kzalloc_obj(struct device_attribute); if (!hsc_handle) return -ENOMEM; @@ -2642,7 +2642,7 @@ static int sony_nc_lowbatt_setup(struct platform_device *pd) { unsigned int result; - lowbatt_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + lowbatt_handle = kzalloc_obj(struct device_attribute); if (!lowbatt_handle) return -ENOMEM; @@ -2719,11 +2719,11 @@ static int sony_nc_fanspeed_setup(struct platform_device *pd) { unsigned int result; - fan_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + fan_handle = kzalloc_obj(struct device_attribute); if (!fan_handle) return -ENOMEM; - hsf_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + hsf_handle = kzalloc_obj(struct device_attribute); if (!hsf_handle) { result = -ENOMEM; goto out_hsf_handle_alloc; @@ -2823,7 +2823,7 @@ static int sony_nc_usb_charge_setup(struct platform_device *pd) return 0; } - uc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + uc_handle = kzalloc_obj(struct device_attribute); if (!uc_handle) return -ENOMEM; @@ -2870,7 +2870,7 @@ static int sony_nc_panelid_setup(struct platform_device *pd) { unsigned int result; - panel_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + panel_handle = kzalloc_obj(struct device_attribute); if (!panel_handle) return -ENOMEM; @@ -2925,7 +2925,7 @@ static int sony_nc_smart_conn_setup(struct platform_device *pd) { unsigned int result; - sc_handle = kzalloc(sizeof(struct device_attribute), GFP_KERNEL); + sc_handle = kzalloc_obj(struct device_attribute); if (!sc_handle) return -ENOMEM; @@ -2999,7 +2999,7 @@ static int sony_nc_touchpad_setup(struct platform_device *pd, { int ret = 0; - tp_ctl = kzalloc(sizeof(struct touchpad_control), GFP_KERNEL); + tp_ctl = kzalloc_obj(struct touchpad_control); if (!tp_ctl) return -ENOMEM; @@ -4161,7 +4161,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) case ACPI_RESOURCE_TYPE_START_DEPENDENT: { /* start IO enumeration */ - struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); + struct sony_pic_ioport *ioport = kzalloc_obj(*ioport); if (!ioport) return AE_ERROR; @@ -4191,8 +4191,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) p->interrupts[i]); continue; } - interrupt = kzalloc(sizeof(*interrupt), - GFP_KERNEL); + interrupt = kzalloc_obj(*interrupt); if (!interrupt) return AE_ERROR; diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index 53fc2b364552..a7b4b6c8e549 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c @@ -292,7 +292,7 @@ static int topstar_acpi_add(struct acpi_device *device) dmi_check_system(topstar_dmi_ids); - topstar = kzalloc(sizeof(struct topstar_laptop), GFP_KERNEL); + topstar = kzalloc_obj(struct topstar_laptop); if (!topstar) return -ENOMEM; diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 5ad3a7183d33..18fb558115aa 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -3321,7 +3321,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) return -ENODEV; } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; dev->acpi_dev = acpi_dev; diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index dad2c3e55904..e587beef05b9 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c @@ -242,7 +242,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) pr_info("Toshiba ACPI Bluetooth device driver\n"); - bt_dev = kzalloc(sizeof(*bt_dev), GFP_KERNEL); + bt_dev = kzalloc_obj(*bt_dev); if (!bt_dev) return -ENOMEM; bt_dev->acpi_dev = device; diff --git a/drivers/platform/x86/touchscreen_dmi.c b/drivers/platform/x86/touchscreen_dmi.c index bdc19cd8d3ed..d83c387821ea 100644 --- a/drivers/platform/x86/touchscreen_dmi.c +++ b/drivers/platform/x86/touchscreen_dmi.c @@ -410,6 +410,16 @@ static const struct ts_dmi_data gdix1002_upside_down_data = { .properties = gdix1001_upside_down_props, }; +static const struct property_entry gdix1001_y_inverted_props[] = { + PROPERTY_ENTRY_BOOL("touchscreen-inverted-y"), + { } +}; + +static const struct ts_dmi_data gdix1001_y_inverted_data = { + .acpi_name = "GDIX1001", + .properties = gdix1001_y_inverted_props, +}; + static const struct property_entry gp_electronic_t701_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 960), PROPERTY_ENTRY_U32("touchscreen-size-y", 640), @@ -1658,6 +1668,14 @@ const struct dmi_system_id touchscreen_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), }, }, + { + /* SUPI S10 */ + .driver_data = (void *)&gdix1001_y_inverted_data, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "SUPI"), + DMI_MATCH(DMI_PRODUCT_NAME, "S10"), + }, + }, { /* Techbite Arc 11.6 */ .driver_data = (void *)&techbite_arc_11_6_data, diff --git a/drivers/platform/x86/uniwill/uniwill-acpi.c b/drivers/platform/x86/uniwill/uniwill-acpi.c index 3c9af441d133..6341dca20b76 100644 --- a/drivers/platform/x86/uniwill/uniwill-acpi.c +++ b/drivers/platform/x86/uniwill/uniwill-acpi.c @@ -314,8 +314,8 @@ #define LED_CHANNELS 3 #define LED_MAX_BRIGHTNESS 200 -#define UNIWILL_FEATURE_FN_LOCK_TOGGLE BIT(0) -#define UNIWILL_FEATURE_SUPER_KEY_TOGGLE BIT(1) +#define UNIWILL_FEATURE_FN_LOCK BIT(0) +#define UNIWILL_FEATURE_SUPER_KEY BIT(1) #define UNIWILL_FEATURE_TOUCHPAD_TOGGLE BIT(2) #define UNIWILL_FEATURE_LIGHTBAR BIT(3) #define UNIWILL_FEATURE_BATTERY BIT(4) @@ -330,6 +330,7 @@ struct uniwill_data { struct acpi_battery_hook hook; unsigned int last_charge_ctrl; struct mutex battery_lock; /* Protects the list of currently registered batteries */ + unsigned int last_status; unsigned int last_switch_status; struct mutex super_key_lock; /* Protects the toggling of the super key lock state */ struct list_head batteries; @@ -377,11 +378,15 @@ static const struct key_entry uniwill_keymap[] = { { KE_IGNORE, UNIWILL_OSD_CAPSLOCK, { KEY_CAPSLOCK }}, { KE_IGNORE, UNIWILL_OSD_NUMLOCK, { KEY_NUMLOCK }}, - /* Reported when the user locks/unlocks the super key */ - { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_LOCK_ENABLE, { KEY_UNKNOWN }}, - { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_LOCK_DISABLE, { KEY_UNKNOWN }}, + /* + * Reported when the user enables/disables the super key. + * Those events might even be reported when the change was done + * using the sysfs attribute! + */ + { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_DISABLE, { KEY_UNKNOWN }}, + { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_ENABLE, { KEY_UNKNOWN }}, /* Optional, might not be reported by all devices */ - { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_LOCK_CHANGED, { KEY_UNKNOWN }}, + { KE_IGNORE, UNIWILL_OSD_SUPER_KEY_STATE_CHANGED, { KEY_UNKNOWN }}, /* Reported in manual mode when toggling the airplane mode status */ { KE_KEY, UNIWILL_OSD_RFKILL, { KEY_RFKILL }}, @@ -401,9 +406,6 @@ static const struct key_entry uniwill_keymap[] = { /* Reported when the user wants to toggle the mute status */ { KE_IGNORE, UNIWILL_OSD_MUTE, { KEY_MUTE }}, - /* Reported when the user locks/unlocks the Fn key */ - { KE_IGNORE, UNIWILL_OSD_FN_LOCK, { KEY_FN_ESC }}, - /* Reported when the user wants to toggle the brightness of the keyboard */ { KE_KEY, UNIWILL_OSD_KBDILLUMTOGGLE, { KEY_KBDILLUMTOGGLE }}, { KE_KEY, UNIWILL_OSD_KB_LED_LEVEL0, { KEY_KBDILLUMTOGGLE }}, @@ -576,6 +578,7 @@ static bool uniwill_volatile_reg(struct device *dev, unsigned int reg) case EC_ADDR_SECOND_FAN_RPM_1: case EC_ADDR_SECOND_FAN_RPM_2: case EC_ADDR_BAT_ALERT: + case EC_ADDR_BIOS_OEM: case EC_ADDR_PWM_1: case EC_ADDR_PWM_2: case EC_ADDR_TRIGGER: @@ -600,8 +603,8 @@ static const struct regmap_config uniwill_ec_config = { .use_single_write = true, }; -static ssize_t fn_lock_toggle_enable_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t fn_lock_store(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count) { struct uniwill_data *data = dev_get_drvdata(dev); unsigned int value; @@ -624,8 +627,7 @@ static ssize_t fn_lock_toggle_enable_store(struct device *dev, struct device_att return count; } -static ssize_t fn_lock_toggle_enable_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t fn_lock_show(struct device *dev, struct device_attribute *attr, char *buf) { struct uniwill_data *data = dev_get_drvdata(dev); unsigned int value; @@ -638,10 +640,10 @@ static ssize_t fn_lock_toggle_enable_show(struct device *dev, struct device_attr return sysfs_emit(buf, "%d\n", !!(value & FN_LOCK_STATUS)); } -static DEVICE_ATTR_RW(fn_lock_toggle_enable); +static DEVICE_ATTR_RW(fn_lock); -static ssize_t super_key_toggle_enable_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) +static ssize_t super_key_enable_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct uniwill_data *data = dev_get_drvdata(dev); unsigned int value; @@ -673,8 +675,7 @@ static ssize_t super_key_toggle_enable_store(struct device *dev, struct device_a return count; } -static ssize_t super_key_toggle_enable_show(struct device *dev, struct device_attribute *attr, - char *buf) +static ssize_t super_key_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct uniwill_data *data = dev_get_drvdata(dev); unsigned int value; @@ -687,7 +688,7 @@ static ssize_t super_key_toggle_enable_show(struct device *dev, struct device_at return sysfs_emit(buf, "%d\n", !(value & SUPER_KEY_LOCK_STATUS)); } -static DEVICE_ATTR_RW(super_key_toggle_enable); +static DEVICE_ATTR_RW(super_key_enable); static ssize_t touchpad_toggle_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -881,8 +882,8 @@ static int uniwill_nvidia_ctgp_init(struct uniwill_data *data) static struct attribute *uniwill_attrs[] = { /* Keyboard-related */ - &dev_attr_fn_lock_toggle_enable.attr, - &dev_attr_super_key_toggle_enable.attr, + &dev_attr_fn_lock.attr, + &dev_attr_super_key_enable.attr, &dev_attr_touchpad_toggle_enable.attr, /* Lightbar-related */ &dev_attr_rainbow_animation.attr, @@ -897,13 +898,13 @@ static umode_t uniwill_attr_is_visible(struct kobject *kobj, struct attribute *a struct device *dev = kobj_to_dev(kobj); struct uniwill_data *data = dev_get_drvdata(dev); - if (attr == &dev_attr_fn_lock_toggle_enable.attr) { - if (uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK_TOGGLE)) + if (attr == &dev_attr_fn_lock.attr) { + if (uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) return attr->mode; } - if (attr == &dev_attr_super_key_toggle_enable.attr) { - if (uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) + if (attr == &dev_attr_super_key_enable.attr) { + if (uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) return attr->mode; } @@ -1293,7 +1294,7 @@ static int uniwill_add_battery(struct power_supply *battery, struct acpi_battery struct uniwill_battery_entry *entry; int ret; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -1357,6 +1358,9 @@ static int uniwill_notifier_call(struct notifier_block *nb, unsigned long action switch (action) { case UNIWILL_OSD_BATTERY_ALERT: + if (!uniwill_device_supports(data, UNIWILL_FEATURE_BATTERY)) + return NOTIFY_DONE; + mutex_lock(&data->battery_lock); list_for_each_entry(entry, &data->batteries, head) { power_supply_changed(entry->battery); @@ -1369,6 +1373,13 @@ static int uniwill_notifier_call(struct notifier_block *nb, unsigned long action * gets implemented. */ + return NOTIFY_OK; + case UNIWILL_OSD_FN_LOCK: + if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) + return NOTIFY_DONE; + + sysfs_notify(&data->dev->kobj, NULL, "fn_lock"); + return NOTIFY_OK; default: mutex_lock(&data->input_lock); @@ -1503,9 +1514,21 @@ static void uniwill_shutdown(struct platform_device *pdev) regmap_clear_bits(data->regmap, EC_ADDR_AP_OEM, ENABLE_MANUAL_CTRL); } -static int uniwill_suspend_keyboard(struct uniwill_data *data) +static int uniwill_suspend_fn_lock(struct uniwill_data *data) { - if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) + if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) + return 0; + + /* + * The EC_ADDR_BIOS_OEM is marked as volatile, so we have to restore it + * ourselves. + */ + return regmap_read(data->regmap, EC_ADDR_BIOS_OEM, &data->last_status); +} + +static int uniwill_suspend_super_key(struct uniwill_data *data) +{ + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) return 0; /* @@ -1542,7 +1565,11 @@ static int uniwill_suspend(struct device *dev) struct uniwill_data *data = dev_get_drvdata(dev); int ret; - ret = uniwill_suspend_keyboard(data); + ret = uniwill_suspend_fn_lock(data); + if (ret < 0) + return ret; + + ret = uniwill_suspend_super_key(data); if (ret < 0) return ret; @@ -1560,12 +1587,21 @@ static int uniwill_suspend(struct device *dev) return 0; } -static int uniwill_resume_keyboard(struct uniwill_data *data) +static int uniwill_resume_fn_lock(struct uniwill_data *data) +{ + if (!uniwill_device_supports(data, UNIWILL_FEATURE_FN_LOCK)) + return 0; + + return regmap_update_bits(data->regmap, EC_ADDR_BIOS_OEM, FN_LOCK_STATUS, + data->last_status); +} + +static int uniwill_resume_super_key(struct uniwill_data *data) { unsigned int value; int ret; - if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY_TOGGLE)) + if (!uniwill_device_supports(data, UNIWILL_FEATURE_SUPER_KEY)) return 0; ret = regmap_read(data->regmap, EC_ADDR_SWITCH_STATUS, &value); @@ -1608,7 +1644,11 @@ static int uniwill_resume(struct device *dev) if (ret < 0) return ret; - ret = uniwill_resume_keyboard(data); + ret = uniwill_resume_fn_lock(data); + if (ret < 0) + return ret; + + ret = uniwill_resume_super_key(data); if (ret < 0) return ret; @@ -1643,16 +1683,16 @@ static struct platform_driver uniwill_driver = { }; static struct uniwill_device_descriptor lapac71h_descriptor __initdata = { - .features = UNIWILL_FEATURE_FN_LOCK_TOGGLE | - UNIWILL_FEATURE_SUPER_KEY_TOGGLE | + .features = UNIWILL_FEATURE_FN_LOCK | + UNIWILL_FEATURE_SUPER_KEY | UNIWILL_FEATURE_TOUCHPAD_TOGGLE | UNIWILL_FEATURE_BATTERY | UNIWILL_FEATURE_HWMON, }; static struct uniwill_device_descriptor lapkc71f_descriptor __initdata = { - .features = UNIWILL_FEATURE_FN_LOCK_TOGGLE | - UNIWILL_FEATURE_SUPER_KEY_TOGGLE | + .features = UNIWILL_FEATURE_FN_LOCK | + UNIWILL_FEATURE_SUPER_KEY | UNIWILL_FEATURE_TOUCHPAD_TOGGLE | UNIWILL_FEATURE_LIGHTBAR | UNIWILL_FEATURE_BATTERY | diff --git a/drivers/platform/x86/uniwill/uniwill-wmi.h b/drivers/platform/x86/uniwill/uniwill-wmi.h index 48783b2e9ffb..fb1910c0f741 100644 --- a/drivers/platform/x86/uniwill/uniwill-wmi.h +++ b/drivers/platform/x86/uniwill/uniwill-wmi.h @@ -64,8 +64,8 @@ #define UNIWILL_OSD_KB_LED_LEVEL3 0x3E #define UNIWILL_OSD_KB_LED_LEVEL4 0x3F -#define UNIWILL_OSD_SUPER_KEY_LOCK_ENABLE 0x40 -#define UNIWILL_OSD_SUPER_KEY_LOCK_DISABLE 0x41 +#define UNIWILL_OSD_SUPER_KEY_DISABLE 0x40 +#define UNIWILL_OSD_SUPER_KEY_ENABLE 0x41 #define UNIWILL_OSD_MENU_JP 0x42 @@ -74,7 +74,7 @@ #define UNIWILL_OSD_RFKILL 0xA4 -#define UNIWILL_OSD_SUPER_KEY_LOCK_CHANGED 0xA5 +#define UNIWILL_OSD_SUPER_KEY_STATE_CHANGED 0xA5 #define UNIWILL_OSD_LIGHTBAR_STATE_CHANGED 0xA6 diff --git a/drivers/platform/x86/uv_sysfs.c b/drivers/platform/x86/uv_sysfs.c index f6a0627f36db..a8c50b323a9e 100644 --- a/drivers/platform/x86/uv_sysfs.c +++ b/drivers/platform/x86/uv_sysfs.c @@ -216,8 +216,7 @@ static int uv_hubs_init(void) u64 sz; int i, ret; - prev_obj_to_cnode = kmalloc_array(uv_bios_obj_cnt, sizeof(*prev_obj_to_cnode), - GFP_KERNEL); + prev_obj_to_cnode = kmalloc_objs(*prev_obj_to_cnode, uv_bios_obj_cnt); if (!prev_obj_to_cnode) return -ENOMEM; @@ -242,14 +241,14 @@ static int uv_hubs_init(void) goto err_enum_objs; } - uv_hubs = kcalloc(uv_bios_obj_cnt, sizeof(*uv_hubs), GFP_KERNEL); + uv_hubs = kzalloc_objs(*uv_hubs, uv_bios_obj_cnt); if (!uv_hubs) { ret = -ENOMEM; goto err_enum_objs; } for (i = 0; i < uv_bios_obj_cnt; i++) { - uv_hubs[i] = kzalloc(sizeof(*uv_hubs[i]), GFP_KERNEL); + uv_hubs[i] = kzalloc_obj(*uv_hubs[i]); if (!uv_hubs[i]) { i--; ret = -ENOMEM; @@ -368,7 +367,7 @@ static int uv_ports_init(void) s64 biosr; int j = 0, k = 0, ret, sz; - port_buf = kcalloc(uv_bios_obj_cnt, sizeof(*port_buf), GFP_KERNEL); + port_buf = kzalloc_objs(*port_buf, uv_bios_obj_cnt); if (!port_buf) return -ENOMEM; @@ -388,8 +387,8 @@ static int uv_ports_init(void) } } for (j = 0; j < uv_bios_obj_cnt; j++) { - uv_hubs[j]->ports = kcalloc(hub_buf[j].ports, - sizeof(*uv_hubs[j]->ports), GFP_KERNEL); + uv_hubs[j]->ports = kzalloc_objs(*uv_hubs[j]->ports, + hub_buf[j].ports); if (!uv_hubs[j]->ports) { ret = -ENOMEM; j--; @@ -398,7 +397,7 @@ static int uv_ports_init(void) } for (j = 0; j < uv_bios_obj_cnt; j++) { for (k = 0; k < hub_buf[j].ports; k++) { - uv_hubs[j]->ports[k] = kzalloc(sizeof(*uv_hubs[j]->ports[k]), GFP_KERNEL); + uv_hubs[j]->ports[k] = kzalloc_obj(*uv_hubs[j]->ports[k]); if (!uv_hubs[j]->ports[k]) { ret = -ENOMEM; k--; @@ -674,8 +673,7 @@ static int pci_topology_init(void) } num_pci_lines = l; - uv_pci_objs = kcalloc(num_pci_lines, - sizeof(*uv_pci_objs), GFP_KERNEL); + uv_pci_objs = kzalloc_objs(*uv_pci_objs, num_pci_lines); if (!uv_pci_objs) { kfree(pci_top_str); ret = -ENOMEM; @@ -683,7 +681,7 @@ static int pci_topology_init(void) } start = pci_top_str; while ((found = strsep(&start, "\n")) != NULL) { - uv_pci_objs[k] = kzalloc(sizeof(*uv_pci_objs[k]), GFP_KERNEL); + uv_pci_objs[k] = kzalloc_obj(*uv_pci_objs[k]); if (!uv_pci_objs[k]) { ret = -ENOMEM; goto err_pci_obj; diff --git a/drivers/platform/x86/wireless-hotkey.c b/drivers/platform/x86/wireless-hotkey.c index a220fe4f9ef8..e5083c0e1515 100644 --- a/drivers/platform/x86/wireless-hotkey.c +++ b/drivers/platform/x86/wireless-hotkey.c @@ -91,7 +91,7 @@ static int wl_add(struct acpi_device *device) struct wl_button *button; int err; - button = kzalloc(sizeof(struct wl_button), GFP_KERNEL); + button = kzalloc_obj(struct wl_button); if (!button) return -ENOMEM; diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 6588fae30356..021009e9085b 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -49,7 +49,7 @@ int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id, struct gpiod_lookup_table *lookup; struct gpio_desc *gpiod; - lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + lookup = kzalloc_flex(*lookup, table, 2); if (!lookup) return -ENOMEM; @@ -447,7 +447,7 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) exit_handler = dev_info->exit; } - i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); + i2c_clients = kzalloc_objs(*i2c_clients, dev_info->i2c_client_count); if (!i2c_clients) { x86_android_tablet_remove(pdev); return -ENOMEM; @@ -462,7 +462,7 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) } } - spi_devs = kcalloc(dev_info->spi_dev_count, sizeof(*spi_devs), GFP_KERNEL); + spi_devs = kzalloc_objs(*spi_devs, dev_info->spi_dev_count); if (!spi_devs) { x86_android_tablet_remove(pdev); return -ENOMEM; @@ -478,7 +478,7 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) } /* + 1 to make space for the (optional) gpio_keys_button platform device */ - pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL); + pdevs = kzalloc_objs(*pdevs, dev_info->pdev_count + 1); if (!pdevs) { x86_android_tablet_remove(pdev); return -ENOMEM; @@ -494,7 +494,7 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) } } - serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); + serdevs = kzalloc_objs(*serdevs, dev_info->serdev_count); if (!serdevs) { x86_android_tablet_remove(pdev); return -ENOMEM; diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index cb02222c978c..4d1b1b310cc5 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c @@ -86,7 +86,7 @@ static int ebook_switch_add(struct acpi_device *device) struct input_dev *input; int error; - button = kzalloc(sizeof(struct ebook_switch), GFP_KERNEL); + button = kzalloc_obj(struct ebook_switch); if (!button) return -ENOMEM; diff --git a/drivers/pmdomain/bcm/bcm2835-power.c b/drivers/pmdomain/bcm/bcm2835-power.c index 1d29addfe036..0450202bbee2 100644 --- a/drivers/pmdomain/bcm/bcm2835-power.c +++ b/drivers/pmdomain/bcm/bcm2835-power.c @@ -580,11 +580,11 @@ static int bcm2835_reset_status(struct reset_controller_dev *rcdev, switch (id) { case BCM2835_RESET_V3D: - return !PM_READ(PM_GRAFX & PM_V3DRSTN); + return !(PM_READ(PM_GRAFX) & PM_V3DRSTN); case BCM2835_RESET_H264: - return !PM_READ(PM_IMAGE & PM_H264RSTN); + return !(PM_READ(PM_IMAGE) & PM_H264RSTN); case BCM2835_RESET_ISP: - return !PM_READ(PM_IMAGE & PM_ISPRSTN); + return !(PM_READ(PM_IMAGE) & PM_ISPRSTN); default: return -EINVAL; } diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index bf82775f6a67..52ea84e548ff 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c @@ -1811,7 +1811,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, if (ret) return ERR_PTR(ret); - gpd_data = kzalloc(sizeof(*gpd_data), GFP_KERNEL); + gpd_data = kzalloc_obj(*gpd_data); if (!gpd_data) { ret = -ENOMEM; goto err_put; @@ -1822,7 +1822,7 @@ static struct generic_pm_domain_data *genpd_alloc_dev_data(struct device *dev, /* Allocate data used by a governor. */ if (has_governor) { - td = kzalloc(sizeof(*td), GFP_KERNEL); + td = kzalloc_obj(*td); if (!td) { ret = -ENOMEM; goto err_free; @@ -2161,7 +2161,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd, return -EINVAL; } - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; @@ -2269,7 +2269,7 @@ static int genpd_set_default_power_state(struct generic_pm_domain *genpd) { struct genpd_power_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; @@ -2295,7 +2295,7 @@ static int genpd_alloc_data(struct generic_pm_domain *genpd) return -ENOMEM; if (genpd->gov) { - gd = kzalloc(sizeof(*gd), GFP_KERNEL); + gd = kzalloc_obj(*gd); if (!gd) { ret = -ENOMEM; goto free; @@ -2623,7 +2623,7 @@ static int genpd_add_provider(struct device_node *np, genpd_xlate_t xlate, { struct of_genpd_provider *cp; - cp = kzalloc(sizeof(*cp), GFP_KERNEL); + cp = kzalloc_obj(*cp); if (!cp) return -ENOMEM; @@ -3316,7 +3316,7 @@ struct device *genpd_dev_pm_attach_by_id(struct device *dev, return ERR_PTR(-ENODEV); /* Allocate and register device on the genpd bus. */ - virt_dev = kzalloc(sizeof(*virt_dev), GFP_KERNEL); + virt_dev = kzalloc_obj(*virt_dev); if (!virt_dev) return ERR_PTR(-ENOMEM); @@ -3474,7 +3474,7 @@ int of_genpd_parse_idle_states(struct device_node *dn, return 0; } - st = kcalloc(ret, sizeof(*st), GFP_KERNEL); + st = kzalloc_objs(*st, ret); if (!st) return -ENOMEM; diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c index cff738e4d546..a829f8da5be7 100644 --- a/drivers/pmdomain/imx/gpcv2.c +++ b/drivers/pmdomain/imx/gpcv2.c @@ -1416,7 +1416,9 @@ static int imx_pgc_domain_suspend(struct device *dev) static int imx_pgc_domain_resume(struct device *dev) { - return pm_runtime_put(dev); + pm_runtime_put(dev); + + return 0; } #endif diff --git a/drivers/pmdomain/renesas/rcar-gen4-sysc.c b/drivers/pmdomain/renesas/rcar-gen4-sysc.c index 7434bf42d215..0c6c639a91d0 100644 --- a/drivers/pmdomain/renesas/rcar-gen4-sysc.c +++ b/drivers/pmdomain/renesas/rcar-gen4-sysc.c @@ -324,7 +324,7 @@ static int __init rcar_gen4_sysc_pd_init(void) rcar_gen4_sysc_base = base; - domains = kzalloc(sizeof(*domains), GFP_KERNEL); + domains = kzalloc_obj(*domains); if (!domains) { error = -ENOMEM; goto out_put; diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c index d8a8ffcde38d..bd7bb9cbd9da 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.c +++ b/drivers/pmdomain/renesas/rcar-sysc.c @@ -383,7 +383,7 @@ static int __init rcar_sysc_pd_init(void) rcar_sysc_extmask_offs = info->extmask_offs; rcar_sysc_extmask_val = info->extmask_val; - domains = kzalloc(sizeof(*domains), GFP_KERNEL); + domains = kzalloc_obj(*domains); if (!domains) { error = -ENOMEM; goto out_put; diff --git a/drivers/pmdomain/renesas/rmobile-sysc.c b/drivers/pmdomain/renesas/rmobile-sysc.c index a6bf7295e909..93103ff33d6e 100644 --- a/drivers/pmdomain/renesas/rmobile-sysc.c +++ b/drivers/pmdomain/renesas/rmobile-sysc.c @@ -277,7 +277,7 @@ static int __init rmobile_add_pm_domains(void __iomem *base, /* always-on domain */ } - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return -ENOMEM; diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c index 997e93c12951..44d34840ede7 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c @@ -1311,7 +1311,7 @@ static const struct rockchip_domain_info rk3576_pm_domains[] = { static const struct rockchip_domain_info rk3588_pm_domains[] = { [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, BIT(0), 0, 0x0, 0, BIT(1), 0x0, BIT(0), BIT(0), false, true), [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, BIT(1), BIT(1), 0x0, 0, 0, 0x0, 0, 0, false, true), - [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false, false), + [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, BIT(2), BIT(2), 0x0, 0, 0, 0x0, 0, 0, false, true), [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, BIT(3), 0, 0x0, BIT(11), BIT(2), 0x0, BIT(1), BIT(1), false, false), [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, BIT(4), 0, 0x0, BIT(12), BIT(3), 0x0, BIT(2), BIT(2), false, false), [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, BIT(5), 0, 0x0, BIT(13), BIT(4), 0x0, BIT(3), BIT(3), false, false), diff --git a/drivers/pmdomain/st/ste-ux500-pm-domain.c b/drivers/pmdomain/st/ste-ux500-pm-domain.c index 3d4f111ed156..6896cb4a7b71 100644 --- a/drivers/pmdomain/st/ste-ux500-pm-domain.c +++ b/drivers/pmdomain/st/ste-ux500-pm-domain.c @@ -65,7 +65,7 @@ static int ux500_pm_domains_probe(struct platform_device *pdev) if (!np) return -ENODEV; - genpd_data = kzalloc(sizeof(*genpd_data), GFP_KERNEL); + genpd_data = kzalloc_obj(*genpd_data); if (!genpd_data) return -ENOMEM; diff --git a/drivers/pmdomain/tegra/powergate-bpmp.c b/drivers/pmdomain/tegra/powergate-bpmp.c index 9f4366250bfd..8cde4f384846 100644 --- a/drivers/pmdomain/tegra/powergate-bpmp.c +++ b/drivers/pmdomain/tegra/powergate-bpmp.c @@ -226,7 +226,7 @@ tegra_bpmp_probe_powergates(struct tegra_bpmp *bpmp, dev_dbg(bpmp->dev, "maximum powergate ID: %u\n", max_id); - powergates = kcalloc(max_id + 1, sizeof(*powergates), GFP_KERNEL); + powergates = kzalloc_objs(*powergates, max_id + 1); if (!powergates) return -ENOMEM; @@ -260,7 +260,7 @@ static int tegra_bpmp_add_powergates(struct tegra_bpmp *bpmp, unsigned int i; int err; - domains = kcalloc(count, sizeof(*domains), GFP_KERNEL); + domains = kzalloc_objs(*domains, count); if (!domains) return -ENOMEM; diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index c7596dc24fbd..87f5af454751 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -80,7 +80,7 @@ static int card_probe(struct pnp_card *card, struct pnp_card_driver *drv) if (!id) return 0; - clink = kzalloc(sizeof(*clink), GFP_KERNEL); + clink = kzalloc_obj(*clink); if (!clink) return 0; clink->card = card; @@ -108,7 +108,7 @@ static struct pnp_id *pnp_add_card_id(struct pnp_card *card, char *id) { struct pnp_id *dev_id, *ptr; - dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); + dev_id = kzalloc_obj(struct pnp_id); if (!dev_id) return NULL; @@ -159,7 +159,7 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *protocol, int id, char *pnp struct pnp_card *card; struct pnp_id *dev_id; - card = kzalloc(sizeof(struct pnp_card), GFP_KERNEL); + card = kzalloc_obj(struct pnp_card); if (!card) return NULL; diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index ac48db6dcfe3..81603327079c 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -122,7 +122,7 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, struct pnp_dev *dev; struct pnp_id *dev_id; - dev = kzalloc(sizeof(struct pnp_dev), GFP_KERNEL); + dev = kzalloc_obj(struct pnp_dev); if (!dev) return NULL; diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 05e9840bc3d4..6d58b1465081 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -315,7 +315,7 @@ struct pnp_id *pnp_add_id(struct pnp_dev *dev, const char *id) { struct pnp_id *dev_id, *ptr; - dev_id = kzalloc(sizeof(struct pnp_id), GFP_KERNEL); + dev_id = kzalloc_obj(struct pnp_id); if (!dev_id) return NULL; diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 44efcdb87e6f..9303fef72df0 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -214,7 +214,7 @@ static ssize_t options_show(struct device *dmdev, struct device_attribute *attr, int ret, dep = 0, set = 0; char *indent; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return -ENOMEM; @@ -257,7 +257,7 @@ static ssize_t resources_show(struct device *dmdev, if (!dev) return -EINVAL; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return -ENOMEM; diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index 6e1d4bfd28ac..7aaecd137d31 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c @@ -29,7 +29,7 @@ static void quirk_awe32_add_ports(struct pnp_dev *dev, { struct pnp_option *new_option; - new_option = kmalloc(sizeof(struct pnp_option), GFP_KERNEL); + new_option = kmalloc_obj(struct pnp_option); if (!new_option) { dev_err(&dev->dev, "couldn't add ioport region to option set " "%d\n", pnp_option_set(option)); @@ -155,8 +155,7 @@ static struct pnp_option *pnp_clone_dependent_set(struct pnp_dev *dev, list_for_each_entry(option, &dev->options, list) { if (pnp_option_is_dependent(option) && pnp_option_set(option) == set) { - new_option = kmalloc(sizeof(struct pnp_option), - GFP_KERNEL); + new_option = kmalloc_obj(struct pnp_option); if (!new_option) { dev_err(&dev->dev, "couldn't clone dependent " "set %d\n", set); diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index 8f7695624c8c..6792bd023123 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -38,7 +38,7 @@ static struct pnp_option *pnp_build_option(struct pnp_dev *dev, unsigned long ty { struct pnp_option *option; - option = kzalloc(sizeof(struct pnp_option), GFP_KERNEL); + option = kzalloc_obj(struct pnp_option); if (!option) return NULL; @@ -499,7 +499,7 @@ static struct pnp_resource *pnp_new_resource(struct pnp_dev *dev) { struct pnp_resource *pnp_res; - pnp_res = kzalloc(sizeof(struct pnp_resource), GFP_KERNEL); + pnp_res = kzalloc_obj(struct pnp_resource); if (!pnp_res) return NULL; diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c index 1fcf0af7cc0b..4dff71be11b6 100644 --- a/drivers/power/sequencing/core.c +++ b/drivers/power/sequencing/core.c @@ -90,7 +90,7 @@ static struct pwrseq_unit *pwrseq_unit_new(const struct pwrseq_unit_data *data) { struct pwrseq_unit *unit; - unit = kzalloc(sizeof(*unit), GFP_KERNEL); + unit = kzalloc_obj(*unit); if (!unit) return NULL; @@ -138,7 +138,7 @@ static struct pwrseq_unit_dep *pwrseq_unit_dep_new(struct pwrseq_unit *unit) { struct pwrseq_unit_dep *dep; - dep = kzalloc(sizeof(*dep), GFP_KERNEL); + dep = kzalloc_obj(*dep); if (!dep) return NULL; @@ -195,7 +195,7 @@ pwrseq_target_new(const struct pwrseq_target_data *data) { struct pwrseq_target *target; - target = kzalloc(sizeof(*target), GFP_KERNEL); + target = kzalloc_obj(*target); if (!target) return NULL; @@ -669,8 +669,7 @@ struct pwrseq_desc *pwrseq_get(struct device *dev, const char *target) struct pwrseq_match_data match_data; int ret; - struct pwrseq_desc *desc __free(kfree) = kzalloc(sizeof(*desc), - GFP_KERNEL); + struct pwrseq_desc *desc __free(kfree) = kzalloc_obj(*desc); if (!desc) return ERR_PTR(-ENOMEM); diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c index d31a7dd8b35c..dadb4aad9d5d 100644 --- a/drivers/power/sequencing/pwrseq-pcie-m2.c +++ b/drivers/power/sequencing/pwrseq-pcie-m2.c @@ -109,7 +109,7 @@ static int pwrseq_pcie_m2_probe(struct platform_device *pdev) if (!ctx) return -ENOMEM; - ctx->of_node = of_node_get(dev->of_node); + ctx->of_node = dev_of_node(dev); ctx->pdata = device_get_match_data(dev); if (!ctx->pdata) return dev_err_probe(dev, -ENODEV, diff --git a/drivers/power/sequencing/pwrseq-thead-gpu.c b/drivers/power/sequencing/pwrseq-thead-gpu.c index 7c82a10ca9f6..a45318b4b2c1 100644 --- a/drivers/power/sequencing/pwrseq-thead-gpu.c +++ b/drivers/power/sequencing/pwrseq-thead-gpu.c @@ -145,7 +145,7 @@ static int pwrseq_thead_gpu_match(struct pwrseq_device *pwrseq, PWRSEQ_MATCH_OK : PWRSEQ_NO_MATCH; ctx->num_clks = ARRAY_SIZE(clk_names); - ctx->clks = kcalloc(ctx->num_clks, sizeof(*ctx->clks), GFP_KERNEL); + ctx->clks = kzalloc_objs(*ctx->clks, ctx->num_clks); if (!ctx->clks) return -ENOMEM; diff --git a/drivers/power/supply/cros_peripheral_charger.c b/drivers/power/supply/cros_peripheral_charger.c index 962a6fd29832..f132fad288cb 100644 --- a/drivers/power/supply/cros_peripheral_charger.c +++ b/drivers/power/supply/cros_peripheral_charger.c @@ -64,7 +64,7 @@ static int cros_pchg_ec_command(const struct charger_data *charger, struct cros_ec_command *msg; int ret; - msg = kzalloc(struct_size(msg, data, max(outsize, insize)), GFP_KERNEL); + msg = kzalloc_flex(*msg, data, max(outsize, insize)); if (!msg) return -ENOMEM; diff --git a/drivers/power/supply/cros_usbpd-charger.c b/drivers/power/supply/cros_usbpd-charger.c index 47d3f58aa15c..7d3e676a951c 100644 --- a/drivers/power/supply/cros_usbpd-charger.c +++ b/drivers/power/supply/cros_usbpd-charger.c @@ -94,7 +94,7 @@ static int cros_usbpd_charger_ec_command(struct charger_data *charger, struct cros_ec_command *msg; int ret; - msg = kzalloc(struct_size(msg, data, max(outsize, insize)), GFP_KERNEL); + msg = kzalloc_flex(*msg, data, max(outsize, insize)); if (!msg) return -ENOMEM; diff --git a/drivers/power/supply/pmu_battery.c b/drivers/power/supply/pmu_battery.c index ed83c5e05ca3..b5ffe2da14dc 100644 --- a/drivers/power/supply/pmu_battery.c +++ b/drivers/power/supply/pmu_battery.c @@ -160,8 +160,7 @@ static int __init pmu_bat_init(void) for (i = 0; i < pmu_battery_count; i++) { struct power_supply_config psy_cfg = {}; - struct pmu_battery_dev *pbat = kzalloc(sizeof(*pbat), - GFP_KERNEL); + struct pmu_battery_dev *pbat = kzalloc_obj(*pbat); if (!pbat) break; diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 9a28381e2607..a446d3d086fc 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1426,7 +1426,7 @@ int power_supply_register_extension(struct power_supply *psy, const struct power if (power_supply_has_property(psy, ext->properties[i])) return -EEXIST; - reg = kmalloc(sizeof(*reg), GFP_KERNEL); + reg = kmalloc_obj(*reg); if (!reg) return -ENOMEM; diff --git a/drivers/power/supply/power_supply_leds.c b/drivers/power/supply/power_supply_leds.c index f4a7e566bea1..1548aaba3362 100644 --- a/drivers/power/supply/power_supply_leds.c +++ b/drivers/power/supply/power_supply_leds.c @@ -48,7 +48,7 @@ static int power_supply_register_led_trigger(struct power_supply *psy, if (err && *err) return *err; - psy_trig = kzalloc(sizeof(*psy_trig), GFP_KERNEL); + psy_trig = kzalloc_obj(*psy_trig); if (!psy_trig) goto err_free_trigger; diff --git a/drivers/powercap/arm_scmi_powercap.c b/drivers/powercap/arm_scmi_powercap.c index a081f177e702..ab66e9a3b1e2 100644 --- a/drivers/powercap/arm_scmi_powercap.c +++ b/drivers/powercap/arm_scmi_powercap.c @@ -370,7 +370,7 @@ static int scmi_zones_register(struct device *dev, unsigned int sp = 0, reg_zones = 0; struct scmi_powercap_zone *spz, **zones_stack; - zones_stack = kcalloc(pr->num_zones, sizeof(spz), GFP_KERNEL); + zones_stack = kzalloc_objs(spz, pr->num_zones); if (!zones_stack) return -ENOMEM; diff --git a/drivers/powercap/dtpm.c b/drivers/powercap/dtpm.c index 129d55bc705c..b7a65e543f19 100644 --- a/drivers/powercap/dtpm.c +++ b/drivers/powercap/dtpm.c @@ -418,7 +418,7 @@ static struct dtpm *dtpm_setup_virtual(const struct dtpm_node *hierarchy, struct dtpm *dtpm; int ret; - dtpm = kzalloc(sizeof(*dtpm), GFP_KERNEL); + dtpm = kzalloc_obj(*dtpm); if (!dtpm) return ERR_PTR(-ENOMEM); dtpm_init(dtpm, NULL); diff --git a/drivers/powercap/dtpm_cpu.c b/drivers/powercap/dtpm_cpu.c index 99390ec1481f..21355db6419d 100644 --- a/drivers/powercap/dtpm_cpu.c +++ b/drivers/powercap/dtpm_cpu.c @@ -212,7 +212,7 @@ static int __dtpm_cpu_setup(int cpu, struct dtpm *parent) goto release_policy; } - dtpm_cpu = kzalloc(sizeof(*dtpm_cpu), GFP_KERNEL); + dtpm_cpu = kzalloc_obj(*dtpm_cpu); if (!dtpm_cpu) { ret = -ENOMEM; goto release_policy; diff --git a/drivers/powercap/dtpm_devfreq.c b/drivers/powercap/dtpm_devfreq.c index d1dff6ccab12..fa71285dee60 100644 --- a/drivers/powercap/dtpm_devfreq.c +++ b/drivers/powercap/dtpm_devfreq.c @@ -160,7 +160,7 @@ static int __dtpm_devfreq_setup(struct devfreq *devfreq, struct dtpm *parent) } } - dtpm_devfreq = kzalloc(sizeof(*dtpm_devfreq), GFP_KERNEL); + dtpm_devfreq = kzalloc_obj(*dtpm_devfreq); if (!dtpm_devfreq) return -ENOMEM; diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index 3ff6da3bf4e6..019a65a5283a 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -254,7 +254,7 @@ static void rapl_init_domains(struct rapl_package *rp); static int rapl_read_data_raw(struct rapl_domain *rd, enum rapl_primitives prim, bool xlate, u64 *data, - bool atomic); + bool pmu_ctx); static int rapl_write_data_raw(struct rapl_domain *rd, enum rapl_primitives prim, unsigned long long value); @@ -832,7 +832,7 @@ prim_fixups(struct rapl_domain *rd, enum rapl_primitives prim) */ static int rapl_read_data_raw(struct rapl_domain *rd, enum rapl_primitives prim, bool xlate, u64 *data, - bool atomic) + bool pmu_ctx) { u64 value; enum rapl_primitives prim_fixed = prim_fixups(rd, prim); @@ -854,7 +854,7 @@ static int rapl_read_data_raw(struct rapl_domain *rd, ra.mask = rpi->mask; - if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, atomic)) { + if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, pmu_ctx)) { pr_debug("failed to read reg 0x%llx for %s:%s\n", ra.reg.val, rd->rp->name, rd->name); return -EIO; } @@ -1520,8 +1520,7 @@ static int rapl_detect_domains(struct rapl_package *rp) } pr_debug("found %d domains on %s\n", rp->nr_domains, rp->name); - rp->domains = kcalloc(rp->nr_domains, sizeof(struct rapl_domain), - GFP_KERNEL); + rp->domains = kzalloc_objs(struct rapl_domain, rp->nr_domains); if (!rp->domains) return -ENOMEM; @@ -1590,23 +1589,21 @@ static struct rapl_pmu rapl_pmu; /* PMU helpers */ -static int get_pmu_cpu(struct rapl_package *rp) +static void set_pmu_cpumask(struct rapl_package *rp, cpumask_var_t mask) { int cpu; if (!rp->has_pmu) - return nr_cpu_ids; + return; /* Only TPMI & MSR RAPL are supported for now */ if (rp->priv->type != RAPL_IF_TPMI && rp->priv->type != RAPL_IF_MSR) - return nr_cpu_ids; + return; /* TPMI/MSR RAPL uses any CPU in the package for PMU */ for_each_online_cpu(cpu) if (topology_physical_package_id(cpu) == rp->id) - return cpu; - - return nr_cpu_ids; + cpumask_set_cpu(cpu, mask); } static bool is_rp_pmu_cpu(struct rapl_package *rp, int cpu) @@ -1883,7 +1880,6 @@ static ssize_t cpumask_show(struct device *dev, { struct rapl_package *rp; cpumask_var_t cpu_mask; - int cpu; int ret; if (!alloc_cpumask_var(&cpu_mask, GFP_KERNEL)) @@ -1895,9 +1891,7 @@ static ssize_t cpumask_show(struct device *dev, /* Choose a cpu for each RAPL Package */ list_for_each_entry(rp, &rapl_packages, plist) { - cpu = get_pmu_cpu(rp); - if (cpu < nr_cpu_ids) - cpumask_set_cpu(cpu, cpu_mask); + set_pmu_cpumask(rp, cpu_mask); } cpus_read_unlock(); @@ -2221,7 +2215,7 @@ struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *pr struct rapl_package *rp; int ret; - rp = kzalloc(sizeof(struct rapl_package), GFP_KERNEL); + rp = kzalloc_obj(struct rapl_package); if (!rp) return ERR_PTR(-ENOMEM); diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index a2bc0a9c1e10..3d5e7f56d68a 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -110,16 +110,14 @@ static int rapl_cpu_down_prep(unsigned int cpu) return 0; } -static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool atomic) +static int rapl_msr_read_raw(int cpu, struct reg_action *ra, bool pmu_ctx) { /* - * When called from atomic-context (eg PMU event handler) - * perform MSR read directly using rdmsrq(). + * When called from PMU context, perform MSR read directly using + * rdmsrq() without IPI overhead. Package-scoped MSRs are readable + * from any CPU in the package. */ - if (atomic) { - if (unlikely(smp_processor_id() != cpu)) - return -EIO; - + if (pmu_ctx) { rdmsrq(ra->reg.msr, ra->value); goto out; } diff --git a/drivers/powercap/intel_rapl_tpmi.c b/drivers/powercap/intel_rapl_tpmi.c index 0a0b85f4528b..ba956a2571d1 100644 --- a/drivers/powercap/intel_rapl_tpmi.c +++ b/drivers/powercap/intel_rapl_tpmi.c @@ -102,7 +102,7 @@ static struct tpmi_rapl_package *trp_alloc(int pkg_id) } } - trp = kzalloc(sizeof(*trp), GFP_KERNEL); + trp = kzalloc_obj(*trp); if (!trp) { ret = -ENOMEM; goto err_del_powercap; @@ -157,7 +157,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; if (tpmi_domain_version == TPMI_VERSION_INVALID) { - pr_warn(FW_BUG "Invalid version\n"); + pr_debug("Invalid version, other instances may be valid\n"); return -ENODEV; } diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c index f3b2ae635305..9197fa20d93f 100644 --- a/drivers/powercap/powercap_sys.c +++ b/drivers/powercap/powercap_sys.c @@ -501,7 +501,7 @@ struct powercap_zone *powercap_register_zone( return ERR_PTR(-EINVAL); memset(power_zone, 0, sizeof(*power_zone)); } else { - power_zone = kzalloc(sizeof(*power_zone), GFP_KERNEL); + power_zone = kzalloc_obj(*power_zone); if (!power_zone) return ERR_PTR(-ENOMEM); power_zone->allocated = true; @@ -529,9 +529,8 @@ struct powercap_zone *powercap_register_zone( power_zone->name = kstrdup(name, GFP_KERNEL); if (!power_zone->name) goto err_name_alloc; - power_zone->constraints = kcalloc(nr_constraints, - sizeof(*power_zone->constraints), - GFP_KERNEL); + power_zone->constraints = kzalloc_objs(*power_zone->constraints, + nr_constraints); if (!power_zone->constraints) goto err_const_alloc; @@ -614,7 +613,7 @@ struct powercap_control_type *powercap_register_control_type( return ERR_PTR(-EINVAL); memset(control_type, 0, sizeof(*control_type)); } else { - control_type = kzalloc(sizeof(*control_type), GFP_KERNEL); + control_type = kzalloc_obj(*control_type); if (!control_type) return ERR_PTR(-ENOMEM); control_type->allocated = true; diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c index 24db06750297..f5af18bc2971 100644 --- a/drivers/pps/clients/pps_parport.c +++ b/drivers/pps/clients/pps_parport.c @@ -142,7 +142,7 @@ static void parport_attach(struct parport *port) return; } - device = kzalloc(sizeof(struct pps_client_pp), GFP_KERNEL); + device = kzalloc_obj(struct pps_client_pp); if (!device) { pr_err("memory allocation failed, not attaching\n"); return; diff --git a/drivers/pps/generators/Kconfig b/drivers/pps/generators/Kconfig index b3f340ed3163..4ef02b3f2576 100644 --- a/drivers/pps/generators/Kconfig +++ b/drivers/pps/generators/Kconfig @@ -23,14 +23,6 @@ config PPS_GENERATOR_DUMMY This driver can also be built as a module. If so, the module will be called pps_gen-dummy. -config PPS_GENERATOR_PARPORT - tristate "Parallel port PPS signal generator" - depends on PARPORT && BROKEN - help - If you say yes here you get support for a PPS signal generator which - utilizes STROBE pin of a parallel port to send PPS signals. It uses - parport abstraction layer and hrtimers to precisely control the signal. - config PPS_GENERATOR_TIO tristate "TIO PPS signal generator" depends on X86 && CPU_SUP_INTEL diff --git a/drivers/pps/generators/Makefile b/drivers/pps/generators/Makefile index e109920e8a2d..5d38774b4a56 100644 --- a/drivers/pps/generators/Makefile +++ b/drivers/pps/generators/Makefile @@ -7,7 +7,6 @@ pps_gen_core-y := pps_gen.o sysfs.o obj-$(CONFIG_PPS_GENERATOR) := pps_gen_core.o obj-$(CONFIG_PPS_GENERATOR_DUMMY) += pps_gen-dummy.o -obj-$(CONFIG_PPS_GENERATOR_PARPORT) += pps_gen_parport.o obj-$(CONFIG_PPS_GENERATOR_TIO) += pps_gen_tio.o ccflags-$(CONFIG_PPS_DEBUG) := -DDEBUG diff --git a/drivers/pps/generators/pps_gen.c b/drivers/pps/generators/pps_gen.c index 5b8bb454913c..7143c003366c 100644 --- a/drivers/pps/generators/pps_gen.c +++ b/drivers/pps/generators/pps_gen.c @@ -230,7 +230,7 @@ struct pps_gen_device *pps_gen_register_source(const struct pps_gen_source_info struct pps_gen_device *pps_gen; int err; - pps_gen = kzalloc(sizeof(struct pps_gen_device), GFP_KERNEL); + pps_gen = kzalloc_obj(struct pps_gen_device); if (pps_gen == NULL) { err = -ENOMEM; goto pps_gen_register_source_exit; diff --git a/drivers/pps/generators/pps_gen_parport.c b/drivers/pps/generators/pps_gen_parport.c deleted file mode 100644 index 05bbf8d30ef1..000000000000 --- a/drivers/pps/generators/pps_gen_parport.c +++ /dev/null @@ -1,238 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * pps_gen_parport.c -- kernel parallel port PPS signal generator - * - * Copyright (C) 2009 Alexander Gordeev - */ - - -/* - * TODO: - * fix issues when realtime clock is adjusted in a leap - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include - -#define SIGNAL 0 -#define NO_SIGNAL PARPORT_CONTROL_STROBE - -/* module parameters */ - -#define SEND_DELAY_MAX 100000 - -static unsigned int send_delay = 30000; -MODULE_PARM_DESC(delay, - "Delay between setting and dropping the signal (ns)"); -module_param_named(delay, send_delay, uint, 0); - - -#define SAFETY_INTERVAL 3000 /* set the hrtimer earlier for safety (ns) */ - -/* internal per port structure */ -struct pps_generator_pp { - struct pardevice *pardev; /* parport device */ - struct hrtimer timer; - long port_write_time; /* calibrated port write time (ns) */ -}; - -static struct pps_generator_pp device = { - .pardev = NULL, -}; - -static int attached; - -/* calibrated time between a hrtimer event and the reaction */ -static long hrtimer_error = SAFETY_INTERVAL; - -/* the kernel hrtimer event */ -static enum hrtimer_restart hrtimer_event(struct hrtimer *timer) -{ - struct timespec64 expire_time, ts1, ts2, ts3, dts; - struct pps_generator_pp *dev; - struct parport *port; - long lim, delta; - unsigned long flags; - - /* We have to disable interrupts here. The idea is to prevent - * other interrupts on the same processor to introduce random - * lags while polling the clock. ktime_get_real_ts64() takes <1us on - * most machines while other interrupt handlers can take much - * more potentially. - * - * NB: approx time with blocked interrupts = - * send_delay + 3 * SAFETY_INTERVAL - */ - local_irq_save(flags); - - /* first of all we get the time stamp... */ - ktime_get_real_ts64(&ts1); - expire_time = ktime_to_timespec64(hrtimer_get_softexpires(timer)); - dev = container_of(timer, struct pps_generator_pp, timer); - lim = NSEC_PER_SEC - send_delay - dev->port_write_time; - - /* check if we are late */ - if (expire_time.tv_sec != ts1.tv_sec || ts1.tv_nsec > lim) { - local_irq_restore(flags); - pr_err("we are late this time %ptSp\n", &ts1); - goto done; - } - - /* busy loop until the time is right for an assert edge */ - do { - ktime_get_real_ts64(&ts2); - } while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim); - - /* set the signal */ - port = dev->pardev->port; - port->ops->write_control(port, SIGNAL); - - /* busy loop until the time is right for a clear edge */ - lim = NSEC_PER_SEC - dev->port_write_time; - do { - ktime_get_real_ts64(&ts2); - } while (expire_time.tv_sec == ts2.tv_sec && ts2.tv_nsec < lim); - - /* unset the signal */ - port->ops->write_control(port, NO_SIGNAL); - - ktime_get_real_ts64(&ts3); - - local_irq_restore(flags); - - /* update calibrated port write time */ - dts = timespec64_sub(ts3, ts2); - dev->port_write_time = - (dev->port_write_time + timespec64_to_ns(&dts)) >> 1; - -done: - /* update calibrated hrtimer error */ - dts = timespec64_sub(ts1, expire_time); - delta = timespec64_to_ns(&dts); - /* If the new error value is bigger then the old, use the new - * value, if not then slowly move towards the new value. This - * way it should be safe in bad conditions and efficient in - * good conditions. - */ - if (delta >= hrtimer_error) - hrtimer_error = delta; - else - hrtimer_error = (3 * hrtimer_error + delta) >> 2; - - /* update the hrtimer expire time */ - hrtimer_set_expires(timer, - ktime_set(expire_time.tv_sec + 1, - NSEC_PER_SEC - (send_delay + - dev->port_write_time + SAFETY_INTERVAL + - 2 * hrtimer_error))); - - return HRTIMER_RESTART; -} - -/* calibrate port write time */ -#define PORT_NTESTS_SHIFT 5 -static void calibrate_port(struct pps_generator_pp *dev) -{ - struct parport *port = dev->pardev->port; - int i; - long acc = 0; - - for (i = 0; i < (1 << PORT_NTESTS_SHIFT); i++) { - struct timespec64 a, b; - unsigned long irq_flags; - - local_irq_save(irq_flags); - ktime_get_real_ts64(&a); - port->ops->write_control(port, NO_SIGNAL); - ktime_get_real_ts64(&b); - local_irq_restore(irq_flags); - - b = timespec64_sub(b, a); - acc += timespec64_to_ns(&b); - } - - dev->port_write_time = acc >> PORT_NTESTS_SHIFT; - pr_info("port write takes %ldns\n", dev->port_write_time); -} - -static inline ktime_t next_intr_time(struct pps_generator_pp *dev) -{ - struct timespec64 ts; - - ktime_get_real_ts64(&ts); - - return ktime_set(ts.tv_sec + - ((ts.tv_nsec > 990 * NSEC_PER_MSEC) ? 1 : 0), - NSEC_PER_SEC - (send_delay + - dev->port_write_time + 3 * SAFETY_INTERVAL)); -} - -static void parport_attach(struct parport *port) -{ - struct pardev_cb pps_cb; - - if (send_delay > SEND_DELAY_MAX) { - pr_err("delay value should be not greater then %d\n", SEND_DELAY_MAX); - return; - } - - if (attached) { - /* we already have a port */ - return; - } - - memset(&pps_cb, 0, sizeof(pps_cb)); - pps_cb.private = &device; - pps_cb.flags = PARPORT_FLAG_EXCL; - device.pardev = parport_register_dev_model(port, KBUILD_MODNAME, - &pps_cb, 0); - if (!device.pardev) { - pr_err("couldn't register with %s\n", port->name); - return; - } - - if (parport_claim_or_block(device.pardev) < 0) { - pr_err("couldn't claim %s\n", port->name); - goto err_unregister_dev; - } - - pr_info("attached to %s\n", port->name); - attached = 1; - - calibrate_port(&device); - - hrtimer_setup(&device.timer, hrtimer_event, CLOCK_REALTIME, HRTIMER_MODE_ABS); - hrtimer_start(&device.timer, next_intr_time(&device), HRTIMER_MODE_ABS); - - return; - -err_unregister_dev: - parport_unregister_device(device.pardev); -} - -static void parport_detach(struct parport *port) -{ - if (port->cad != device.pardev) - return; /* not our port */ - - hrtimer_cancel(&device.timer); - parport_release(device.pardev); - parport_unregister_device(device.pardev); -} - -static struct parport_driver pps_gen_parport_driver = { - .name = KBUILD_MODNAME, - .match_port = parport_attach, - .detach = parport_detach, -}; -module_parport_driver(pps_gen_parport_driver); - -MODULE_AUTHOR("Alexander Gordeev "); -MODULE_DESCRIPTION("parallel port PPS signal generator"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c index 6985c34de2ce..1bf0335a1b41 100644 --- a/drivers/pps/kapi.c +++ b/drivers/pps/kapi.c @@ -83,7 +83,7 @@ struct pps_device *pps_register_source(struct pps_source_info *info, } /* Allocate memory for the new PPS source struct */ - pps = kzalloc(sizeof(struct pps_device), GFP_KERNEL); + pps = kzalloc_obj(struct pps_device); if (pps == NULL) { err = -ENOMEM; goto pps_register_source_exit; diff --git a/drivers/ps3/ps3-lpm.c b/drivers/ps3/ps3-lpm.c index 188ae2572674..f8d8f607134a 100644 --- a/drivers/ps3/ps3-lpm.c +++ b/drivers/ps3/ps3-lpm.c @@ -1181,7 +1181,7 @@ static int ps3_lpm_probe(struct ps3_system_bus_device *dev) return -EBUSY; } - lpm_priv = kzalloc(sizeof(*lpm_priv), GFP_KERNEL); + lpm_priv = kzalloc_obj(*lpm_priv); if (!lpm_priv) return -ENOMEM; diff --git a/drivers/ps3/ps3-vuart.c b/drivers/ps3/ps3-vuart.c index 5cb92535a4a1..39ffa2366132 100644 --- a/drivers/ps3/ps3-vuart.c +++ b/drivers/ps3/ps3-vuart.c @@ -914,7 +914,7 @@ static int ps3_vuart_bus_interrupt_get(void) BUG_ON(vuart_bus_priv.bmp); - vuart_bus_priv.bmp = kzalloc(sizeof(struct ports_bmp), GFP_KERNEL); + vuart_bus_priv.bmp = kzalloc_obj(struct ports_bmp); if (!vuart_bus_priv.bmp) { result = -ENOMEM; @@ -1015,8 +1015,7 @@ static int ps3_vuart_probe(struct ps3_system_bus_device *dev) /* Setup dev->driver_priv. */ - dev->driver_priv = kzalloc(sizeof(struct ps3_vuart_port_priv), - GFP_KERNEL); + dev->driver_priv = kzalloc_obj(struct ps3_vuart_port_priv); if (!dev->driver_priv) { result = -ENOMEM; diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index f6c9e56bdba7..d4b91c480f98 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c @@ -934,7 +934,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) return -EBUSY; } - ps3av = kzalloc(sizeof(*ps3av), GFP_KERNEL); + ps3av = kzalloc_obj(*ps3av); if (!ps3av) return -ENOMEM; diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index b0e167c0b3eb..d6f54ccaf93b 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c @@ -328,7 +328,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, return ERR_PTR(-EINVAL); /* Initialize a clock structure. */ - ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL); + ptp = kzalloc_obj(struct ptp_clock); if (!ptp) { err = -ENOMEM; goto no_memory; @@ -344,7 +344,7 @@ struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info, ptp->devid = MKDEV(major, index); ptp->index = index; INIT_LIST_HEAD(&ptp->tsevqs); - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) { err = -ENOMEM; goto no_memory_queue; diff --git a/drivers/ptp/ptp_ines.c b/drivers/ptp/ptp_ines.c index 790eb42b78db..9e7af6a10261 100644 --- a/drivers/ptp/ptp_ines.c +++ b/drivers/ptp/ptp_ines.c @@ -760,7 +760,7 @@ static int ines_ptp_ctrl_probe(struct platform_device *pld) err = PTR_ERR(addr); goto out; } - clock = kzalloc(sizeof(*clock), GFP_KERNEL); + clock = kzalloc_obj(*clock); if (!clock) { err = -ENOMEM; goto out; diff --git a/drivers/ptp/ptp_mock.c b/drivers/ptp/ptp_mock.c index bbd14ce24b34..4d66b6147121 100644 --- a/drivers/ptp/ptp_mock.c +++ b/drivers/ptp/ptp_mock.c @@ -120,7 +120,7 @@ struct mock_phc *mock_phc_create(struct device *dev) struct mock_phc *phc; int err; - phc = kzalloc(sizeof(*phc), GFP_KERNEL); + phc = kzalloc_obj(*phc); if (!phc) { err = -ENOMEM; goto out; diff --git a/drivers/ptp/ptp_ocp.c b/drivers/ptp/ptp_ocp.c index 1b16a9c3d7fd..d88ab2f86b1b 100644 --- a/drivers/ptp/ptp_ocp.c +++ b/drivers/ptp/ptp_ocp.c @@ -2241,7 +2241,7 @@ ptp_ocp_register_ext(struct ptp_ocp *bp, struct ocp_resource *r) struct ptp_ocp_ext_src *ext; int err; - ext = kzalloc(sizeof(*ext), GFP_KERNEL); + ext = kzalloc_obj(*ext); if (!ext) return -ENOMEM; @@ -2378,8 +2378,7 @@ ptp_ocp_attr_group_add(struct ptp_ocp *bp, if (attr_tbl[i].cap & bp->fw_cap) count++; - bp->attr_group = kcalloc(count + 1, sizeof(*bp->attr_group), - GFP_KERNEL); + bp->attr_group = kzalloc_objs(*bp->attr_group, count + 1); if (!bp->attr_group) return -ENOMEM; @@ -2646,7 +2645,7 @@ ptp_ocp_set_pins(struct ptp_ocp *bp) struct ptp_pin_desc *config; int i; - config = kcalloc(4, sizeof(*config), GFP_KERNEL); + config = kzalloc_objs(*config, 4); if (!config) return -ENOMEM; diff --git a/drivers/ptp/ptp_qoriq.c b/drivers/ptp/ptp_qoriq.c index 8da995e36aeb..76272e5ac5b8 100644 --- a/drivers/ptp/ptp_qoriq.c +++ b/drivers/ptp/ptp_qoriq.c @@ -613,7 +613,7 @@ static int ptp_qoriq_probe(struct platform_device *dev) int err = -ENOMEM; void __iomem *base; - ptp_qoriq = kzalloc(sizeof(*ptp_qoriq), GFP_KERNEL); + ptp_qoriq = kzalloc_obj(*ptp_qoriq); if (!ptp_qoriq) goto no_memory; diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 200eaf500696..dc398c6b7528 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c @@ -443,12 +443,11 @@ int ptp_populate_pin_groups(struct ptp_clock *ptp) if (!n_pins) return 0; - ptp->pin_dev_attr = kcalloc(n_pins, sizeof(*ptp->pin_dev_attr), - GFP_KERNEL); + ptp->pin_dev_attr = kzalloc_objs(*ptp->pin_dev_attr, n_pins); if (!ptp->pin_dev_attr) goto no_dev_attr; - ptp->pin_attr = kcalloc(1 + n_pins, sizeof(*ptp->pin_attr), GFP_KERNEL); + ptp->pin_attr = kzalloc_objs(*ptp->pin_attr, 1 + n_pins); if (!ptp->pin_attr) goto no_pin_attr; diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c index 64c950456517..915a4f6defc9 100644 --- a/drivers/ptp/ptp_vclock.c +++ b/drivers/ptp/ptp_vclock.c @@ -191,7 +191,7 @@ struct ptp_vclock *ptp_vclock_register(struct ptp_clock *pclock) { struct ptp_vclock *vclock; - vclock = kzalloc(sizeof(*vclock), GFP_KERNEL); + vclock = kzalloc_obj(*vclock); if (!vclock) return NULL; diff --git a/drivers/ptp/ptp_vmclock.c b/drivers/ptp/ptp_vmclock.c index c7c75e19f4dd..8b630eb916b5 100644 --- a/drivers/ptp/ptp_vmclock.c +++ b/drivers/ptp/ptp_vmclock.c @@ -460,7 +460,7 @@ static int vmclock_miscdev_open(struct inode *inode, struct file *fp) { struct vmclock_state *st = container_of(fp->private_data, struct vmclock_state, miscdev); - struct vmclock_file_state *fst = kzalloc(sizeof(*fst), GFP_KERNEL); + struct vmclock_file_state *fst = kzalloc_obj(*fst); if (!fst) return -ENOMEM; diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 8da78b4b21b9..be4885da85b6 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -1333,7 +1333,7 @@ static int pwm_export_child(struct device *pwmchip_dev, struct pwm_device *pwm) if (test_and_set_bit(PWMF_EXPORTED, &pwm->flags)) return -EBUSY; - export = kzalloc(sizeof(*export), GFP_KERNEL); + export = kzalloc_obj(*export); if (!export) { clear_bit(PWMF_EXPORTED, &pwm->flags); return -ENOMEM; @@ -2138,7 +2138,7 @@ static int pwm_cdev_open(struct inode *inode, struct file *file) if (!chip->operational) return -ENXIO; - cdata = kzalloc(struct_size(cdata, pwm, chip->npwm), GFP_KERNEL); + cdata = kzalloc_flex(*cdata, pwm, chip->npwm); if (!cdata) return -ENOMEM; diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 995cfeca972b..009b3b595bbf 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -348,7 +348,7 @@ rio_mport_create_outbound_mapping(struct mport_dev *md, struct file *filp, rmcd_debug(OBW, "did=%d ra=0x%llx sz=0x%x", rioid, raddr, size); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) return -ENOMEM; @@ -800,7 +800,7 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, if (xfer->length == 0) return -EINVAL; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -835,8 +835,7 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, offset = lower_32_bits(offset_in_page(xfer->loc_addr)); nr_pages = PAGE_ALIGN(xfer->length + offset) >> PAGE_SHIFT; - page_list = kmalloc_array(nr_pages, - sizeof(*page_list), GFP_KERNEL); + page_list = kmalloc_objs(*page_list, nr_pages); if (page_list == NULL) { ret = -ENOMEM; goto err_req; @@ -1070,7 +1069,7 @@ static int rio_mport_create_dma_mapping(struct mport_dev *md, struct file *filp, { struct rio_mport_mapping *map; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) return -ENOMEM; @@ -1190,7 +1189,7 @@ rio_mport_create_inbound_mapping(struct mport_dev *md, struct file *filp, if (size > 0xffffffff) return -EINVAL; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) return -ENOMEM; @@ -1432,7 +1431,7 @@ static int rio_mport_add_db_filter(struct mport_cdev_priv *priv, return ret; } - db_filter = kzalloc(sizeof(*db_filter), GFP_KERNEL); + db_filter = kzalloc_obj(*db_filter); if (db_filter == NULL) { rio_release_inb_dbell(md->mport, filter.low, filter.high); return -ENOMEM; @@ -1540,7 +1539,7 @@ static int rio_mport_add_pw_filter(struct mport_cdev_priv *priv, if (copy_from_user(&filter, arg, sizeof(filter))) return -EFAULT; - pw_filter = kzalloc(sizeof(*pw_filter), GFP_KERNEL); + pw_filter = kzalloc_obj(*pw_filter); if (pw_filter == NULL) return -ENOMEM; @@ -1879,7 +1878,7 @@ static int mport_cdev_open(struct inode *inode, struct file *filp) get_device(&chdev->dev); - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { put_device(&chdev->dev); return -ENOMEM; @@ -2349,7 +2348,7 @@ static struct mport_dev *mport_cdev_add(struct rio_mport *mport) struct mport_dev *md; struct rio_mport_attr attr; - md = kzalloc(sizeof(*md), GFP_KERNEL); + md = kzalloc_obj(*md); if (!md) { rmcd_error("Unable allocate a device object"); return NULL; diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 4b84270a8906..66331e67cf4e 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c @@ -1145,7 +1145,7 @@ static int tsi721_rio_map_inb_mem(struct rio_mport *mport, dma_addr_t lstart, loc_start = ibw_start; - map = kzalloc(sizeof(struct tsi721_ib_win_mapping), GFP_ATOMIC); + map = kzalloc_obj(struct tsi721_ib_win_mapping, GFP_ATOMIC); if (map == NULL) return -ENOMEM; @@ -2774,7 +2774,7 @@ static int tsi721_probe(struct pci_dev *pdev, struct tsi721_device *priv; int err; - priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL); + priv = kzalloc_obj(struct tsi721_device); if (!priv) { err = -ENOMEM; goto err_exit; diff --git a/drivers/rapidio/devices/tsi721_dma.c b/drivers/rapidio/devices/tsi721_dma.c index f77f75172bdc..52749f1d2a11 100644 --- a/drivers/rapidio/devices/tsi721_dma.c +++ b/drivers/rapidio/devices/tsi721_dma.c @@ -739,8 +739,7 @@ static int tsi721_alloc_chan_resources(struct dma_chan *dchan) } /* Allocate queue of transaction descriptors */ - desc = kcalloc(dma_txqueue_sz, sizeof(struct tsi721_tx_desc), - GFP_ATOMIC); + desc = kzalloc_objs(struct tsi721_tx_desc, dma_txqueue_sz, GFP_ATOMIC); if (!desc) { tsi721_bdma_ch_free(bdma_chan); return -ENOMEM; diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 46daf32ea13b..0c175e6d424f 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c @@ -107,7 +107,7 @@ EXPORT_SYMBOL(rio_query_mport); */ struct rio_net *rio_alloc_net(struct rio_mport *mport) { - struct rio_net *net = kzalloc(sizeof(*net), GFP_KERNEL); + struct rio_net *net = kzalloc_obj(*net); if (net) { INIT_LIST_HEAD(&net->node); @@ -242,7 +242,7 @@ int rio_request_inb_mbox(struct rio_mport *mport, if (!mport->ops->open_inb_mbox) goto out; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (res) { rio_init_mbox_res(res, mbox, mbox); @@ -326,7 +326,7 @@ int rio_request_outb_mbox(struct rio_mport *mport, if (!mport->ops->open_outb_mbox) goto out; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (res) { rio_init_mbox_res(res, mbox, mbox); @@ -403,7 +403,7 @@ rio_setup_inb_dbell(struct rio_mport *mport, void *dev_id, struct resource *res, void (*dinb) (struct rio_mport * mport, void *dev_id, u16 src, u16 dst, u16 info)) { - struct rio_dbell *dbell = kmalloc(sizeof(*dbell), GFP_KERNEL); + struct rio_dbell *dbell = kmalloc_obj(*dbell); if (!dbell) return -ENOMEM; @@ -438,7 +438,7 @@ int rio_request_inb_dbell(struct rio_mport *mport, u16 dst, u16 info)) { int rc; - struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); + struct resource *res = kzalloc_obj(*res); if (res) { rio_init_dbell_res(res, start, end); @@ -515,7 +515,7 @@ EXPORT_SYMBOL_GPL(rio_release_inb_dbell); struct resource *rio_request_outb_dbell(struct rio_dev *rdev, u16 start, u16 end) { - struct resource *res = kzalloc(sizeof(struct resource), GFP_KERNEL); + struct resource *res = kzalloc_obj(struct resource); if (res) { rio_init_dbell_res(res, start, end); @@ -563,7 +563,7 @@ int rio_add_mport_pw_handler(struct rio_mport *mport, void *context, int (*pwcback)(struct rio_mport *mport, void *context, union rio_pw_msg *msg, int step)) { - struct rio_pwrite *pwrite = kzalloc(sizeof(*pwrite), GFP_KERNEL); + struct rio_pwrite *pwrite = kzalloc_obj(*pwrite); if (!pwrite) return -ENOMEM; @@ -1865,7 +1865,7 @@ int rio_register_scan(int mport_id, struct rio_scan *scan_ops) /* * Allocate and initialize new scan registration node. */ - scan = kzalloc(sizeof(*scan), GFP_KERNEL); + scan = kzalloc_obj(*scan); if (!scan) { rc = -ENOMEM; goto err_out; @@ -2000,7 +2000,7 @@ int rio_init_mports(void) goto no_disc; } - work = kcalloc(n, sizeof *work, GFP_KERNEL); + work = kzalloc_objs(*work, n); if (!work) { destroy_workqueue(rio_wq); goto no_disc; diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c index 66464674223f..c55af5924da2 100644 --- a/drivers/rapidio/rio_cm.c +++ b/drivers/rapidio/rio_cm.c @@ -389,7 +389,7 @@ static int riocm_req_handler(struct cm_dev *cm, void *req_data) return -EINVAL; } - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) { riocm_put_channel(ch); return -ENOMEM; @@ -702,7 +702,7 @@ static int riocm_queue_req(struct cm_dev *cm, struct rio_dev *rdev, unsigned long flags; struct tx_req *treq; - treq = kzalloc(sizeof(*treq), GFP_KERNEL); + treq = kzalloc_obj(*treq); if (treq == NULL) return -ENOMEM; @@ -965,7 +965,7 @@ static int riocm_ch_connect(u16 loc_ch, struct cm_dev *cm, * Send connect request to the remote RapidIO device */ - hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + hdr = kzalloc_obj(*hdr); if (hdr == NULL) { ret = -ENOMEM; goto conn_done; @@ -1022,7 +1022,7 @@ static int riocm_send_ack(struct rio_channel *ch) struct rio_ch_chan_hdr *hdr; int ret; - hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + hdr = kzalloc_obj(*hdr); if (hdr == NULL) return -ENOMEM; @@ -1283,7 +1283,7 @@ static struct rio_channel *riocm_ch_alloc(u16 ch_num) int start, end; struct rio_channel *ch; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (!ch) return ERR_PTR(-ENOMEM); @@ -1396,7 +1396,7 @@ static int riocm_send_close(struct rio_channel *ch) * Send CH_CLOSE notification to the remote RapidIO device */ - hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + hdr = kzalloc_obj(*hdr); if (hdr == NULL) return -ENOMEM; @@ -1952,7 +1952,7 @@ static int riocm_add_dev(struct device *dev, struct subsys_interface *sif) riocm_debug(RDEV, "(%s)", rio_name(rdev)); - peer = kmalloc(sizeof(*peer), GFP_KERNEL); + peer = kmalloc_obj(*peer); if (!peer) return -ENOMEM; @@ -2099,7 +2099,7 @@ static int riocm_add_mport(struct device *dev) riocm_debug(MPORT, "add mport %s", mport->name); - cm = kzalloc(sizeof(*cm), GFP_KERNEL); + cm = kzalloc_obj(*cm); if (!cm) return -ENOMEM; diff --git a/drivers/ras/amd/fmpm.c b/drivers/ras/amd/fmpm.c index 8877c6ff64c4..34ef75af31cb 100644 --- a/drivers/ras/amd/fmpm.c +++ b/drivers/ras/amd/fmpm.c @@ -819,7 +819,7 @@ static int allocate_records(void) { int i, ret = 0; - fru_records = kcalloc(max_nr_fru, sizeof(struct fru_rec *), GFP_KERNEL); + fru_records = kzalloc_objs(struct fru_rec *, max_nr_fru); if (!fru_records) { ret = -ENOMEM; goto out; diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index a708fc63f581..d10b6f9243d5 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -508,7 +508,7 @@ config REGULATOR_FP9931 This driver supports the FP9931/JD9930 voltage regulator chip which is used to provide power to Electronic Paper Displays so it is found in E-Book readers. - If HWWON is enabled, it also provides temperature measurement. + If HWMON is enabled, it also provides temperature measurement. config REGULATOR_LM363X tristate "TI LM363X voltage regulators" diff --git a/drivers/regulator/bq257xx-regulator.c b/drivers/regulator/bq257xx-regulator.c index fc1ccede4468..dab8f1ab4450 100644 --- a/drivers/regulator/bq257xx-regulator.c +++ b/drivers/regulator/bq257xx-regulator.c @@ -115,11 +115,10 @@ static void bq257xx_reg_dt_parse_gpio(struct platform_device *pdev) return; subchild = of_get_child_by_name(child, pdata->desc.of_match); + of_node_put(child); if (!subchild) return; - of_node_put(child); - pdata->otg_en_gpio = devm_fwnode_gpiod_get_index(&pdev->dev, of_fwnode_handle(subchild), "enable", 0, diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 8c2fd20edd50..2286bdf6edcb 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1740,7 +1740,7 @@ static int regulator_event_forward_notifier(struct notifier_block *nb, return NOTIFY_DONE; } - rew = kmalloc(sizeof(*rew), GFP_ATOMIC); + rew = kmalloc_obj(*rew, GFP_ATOMIC); if (!rew) return NOTIFY_DONE; @@ -1855,7 +1855,7 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, else has_dev = 0; - new_node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); + new_node = kzalloc_obj(struct regulator_map); if (new_node == NULL) return -ENOMEM; @@ -1965,8 +1965,6 @@ static const struct file_operations constraint_flags_fops = { #endif }; -#define REG_STR_SIZE 64 - static void link_and_create_debugfs(struct regulator *regulator, struct regulator_dev *rdev, struct device *dev) { @@ -2014,15 +2012,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, lockdep_assert_held_once(&rdev->mutex.base); if (dev) { - char buf[REG_STR_SIZE]; - int size; - - size = snprintf(buf, REG_STR_SIZE, "%s-%s", - dev->kobj.name, supply_name); - if (size >= REG_STR_SIZE) - return NULL; - - supply_name = kstrdup(buf, GFP_KERNEL); + supply_name = kasprintf(GFP_KERNEL, "%s-%s", dev->kobj.name, supply_name); if (supply_name == NULL) return NULL; } else { @@ -2031,7 +2021,7 @@ static struct regulator *create_regulator(struct regulator_dev *rdev, return NULL; } - regulator = kzalloc(sizeof(*regulator), GFP_KERNEL); + regulator = kzalloc_obj(*regulator); if (regulator == NULL) { kfree_const(supply_name); return NULL; @@ -2711,7 +2701,7 @@ int regulator_register_supply_alias(struct device *dev, const char *id, struct regulator_supply_alias *map; struct regulator_supply_alias *new_map; - new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); + new_map = kzalloc_obj(struct regulator_supply_alias); if (!new_map) return -ENOMEM; @@ -2835,7 +2825,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, struct gpio_desc *gpiod; gpiod = config->ena_gpiod; - new_pin = kzalloc(sizeof(*new_pin), GFP_KERNEL); + new_pin = kzalloc_obj(*new_pin); mutex_lock(®ulator_list_mutex); @@ -5923,7 +5913,7 @@ static int regulator_init_coupling(struct regulator_dev *rdev) else n_phandles = of_get_n_coupled(rdev); - coupled = kcalloc(n_phandles + 1, sizeof(*coupled), GFP_KERNEL); + coupled = kzalloc_objs(*coupled, n_phandles + 1); if (!coupled) return -ENOMEM; @@ -6044,7 +6034,7 @@ regulator_register(struct device *dev, goto rinse; } - rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); + rdev = kzalloc_obj(struct regulator_dev); if (rdev == NULL) { ret = -ENOMEM; goto rinse; @@ -6127,8 +6117,7 @@ regulator_register(struct device *dev, sizeof(*rdev->constraints), GFP_KERNEL); else - rdev->constraints = kzalloc(sizeof(*rdev->constraints), - GFP_KERNEL); + rdev->constraints = kzalloc_obj(*rdev->constraints); if (!rdev->constraints) { ret = -ENOMEM; goto wash; diff --git a/drivers/regulator/fixed-helper.c b/drivers/regulator/fixed-helper.c index b6cb0aaac3b1..ba5551ac034d 100644 --- a/drivers/regulator/fixed-helper.c +++ b/drivers/regulator/fixed-helper.c @@ -34,7 +34,7 @@ struct platform_device *regulator_register_always_on(int id, const char *name, { struct fixed_regulator_data *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; diff --git a/drivers/regulator/fp9931.c b/drivers/regulator/fp9931.c index 7fbcc6327cc6..abea3b69d8a0 100644 --- a/drivers/regulator/fp9931.c +++ b/drivers/regulator/fp9931.c @@ -144,13 +144,12 @@ static int fp9931_hwmon_read(struct device *dev, enum hwmon_sensor_types type, return ret; ret = regmap_read(data->regmap, FP9931_REG_TMST_VALUE, &val); - if (ret) - return ret; + if (!ret) + *temp = (s8)val * 1000; pm_runtime_put_autosuspend(data->dev); - *temp = (s8)val * 1000; - return 0; + return ret; } static umode_t fp9931_hwmon_is_visible(const void *data, diff --git a/drivers/regulator/mt6363-regulator.c b/drivers/regulator/mt6363-regulator.c index e0fbf92e7685..0aebcbda0a19 100644 --- a/drivers/regulator/mt6363-regulator.c +++ b/drivers/regulator/mt6363-regulator.c @@ -861,7 +861,7 @@ static int mt6363_regulator_probe(struct platform_device *pdev) struct irq_domain *domain; struct irq_fwspec fwspec; struct spmi_device *sdev; - int i, ret; + int i, ret, val; config.regmap = mt6363_spmi_register_regmap(dev); if (IS_ERR(config.regmap)) @@ -870,6 +870,13 @@ static int mt6363_regulator_probe(struct platform_device *pdev) config.dev = dev; sdev = to_spmi_device(dev->parent); + /* + * The first read may fail if the bootloader sets sleep mode: wake up + * this PMIC with W/R on the SPMI bus and ignore the first result. + * This matches the MT6373 driver behavior. + */ + regmap_read(config.regmap, MT6363_TOP_TRAP, &val); + interrupt_parent = of_irq_find_parent(dev->of_node); if (!interrupt_parent) return dev_err_probe(dev, -EINVAL, "Cannot find IRQ parent\n"); @@ -892,10 +899,8 @@ static int mt6363_regulator_probe(struct platform_device *pdev) "Failed to map IRQ%d\n", info->hwirq); ret = devm_add_action_or_reset(dev, mt6363_irq_remove, &info->virq); - if (ret) { - irq_dispose_mapping(info->hwirq); + if (ret) return ret; - } config.driver_data = info; INIT_DELAYED_WORK(&info->oc_work, mt6363_oc_irq_enable_work); diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index 33463926a2a6..c0cc6cc0afd8 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -973,9 +973,7 @@ int of_regulator_bulk_get_all(struct device *dev, struct device_node *np, } if (num_consumers == 0) return 0; - _consumers = kmalloc_array(num_consumers, - sizeof(struct regulator_bulk_data), - GFP_KERNEL); + _consumers = kmalloc_objs(struct regulator_bulk_data, num_consumers); if (!_consumers) return -ENOMEM; goto restart; diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index 5fa868264250..45d7dc44c2cd 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c @@ -1293,6 +1293,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) struct regulator_dev *ldo5; struct pca9450 *pca9450; unsigned int device_id, i; + const char *type_name; int ret; pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL); @@ -1303,15 +1304,22 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) case PCA9450_TYPE_PCA9450A: regulator_desc = pca9450a_regulators; pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators); + type_name = "pca9450a"; break; case PCA9450_TYPE_PCA9450BC: regulator_desc = pca9450bc_regulators; pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators); + type_name = "pca9450bc"; break; case PCA9450_TYPE_PCA9451A: + regulator_desc = pca9451a_regulators; + pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators); + type_name = "pca9451a"; + break; case PCA9450_TYPE_PCA9452: regulator_desc = pca9451a_regulators; pca9450->rcnt = ARRAY_SIZE(pca9451a_regulators); + type_name = "pca9452"; break; default: dev_err(&i2c->dev, "Unknown device type"); @@ -1369,7 +1377,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) if (pca9450->irq) { ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL, pca9450_irq_handler, - (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), + (IRQF_TRIGGER_LOW | IRQF_ONESHOT), "pca9450-irq", pca9450); if (ret != 0) return dev_err_probe(pca9450->dev, ret, "Failed to request IRQ: %d\n", @@ -1413,9 +1421,7 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) pca9450_i2c_restart_handler, pca9450)) dev_warn(&i2c->dev, "Failed to register restart handler\n"); - dev_info(&i2c->dev, "%s probed.\n", - type == PCA9450_TYPE_PCA9450A ? "pca9450a" : - (type == PCA9450_TYPE_PCA9451A ? "pca9451a" : "pca9450bc")); + dev_info(&i2c->dev, "%s probed.\n", type_name); return 0; } diff --git a/drivers/regulator/pf9453-regulator.c b/drivers/regulator/pf9453-regulator.c index 779a6fdb0574..eed3055d1c1c 100644 --- a/drivers/regulator/pf9453-regulator.c +++ b/drivers/regulator/pf9453-regulator.c @@ -809,7 +809,7 @@ static int pf9453_i2c_probe(struct i2c_client *i2c) } ret = devm_request_threaded_irq(pf9453->dev, pf9453->irq, NULL, pf9453_irq_handler, - (IRQF_TRIGGER_FALLING | IRQF_ONESHOT), + IRQF_ONESHOT, "pf9453-irq", pf9453); if (ret) return dev_err_probe(pf9453->dev, ret, "Failed to request IRQ: %d\n", pf9453->irq); diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 1e8142479656..e66408f23bb6 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -24,6 +24,9 @@ #include /* Field definitions */ +#define RK801_BUCK_VSEL_MASK 0x7f +#define RK801_LDO_VSEL_MASK 0x3f + #define RK808_BUCK_VSEL_MASK 0x3f #define RK808_BUCK4_VSEL_MASK 0xf #define RK808_LDO_VSEL_MASK 0x1f @@ -158,6 +161,11 @@ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, 0, 0, _etime, &rk808_reg_ops) +#define RK801_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _disval, _etime) \ + RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ + _vmask, _ereg, _emask, _emask, _disval, _etime, &rk801_reg_ops) + #define RK816_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \ _vmask, _ereg, _emask, _disval, _etime) \ RK8XX_DESC_COM(_id, _match, _supply, _min, _max, _step, _vreg, \ @@ -185,6 +193,11 @@ .ops = _ops \ } +#define RK801_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \ + _disval) \ + RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ + _emask, _disval, &rk801_switch_ops) + #define RK817_DESC_SWITCH(_id, _match, _supply, _ereg, _emask, \ _disval) \ RKXX_DESC_SWITCH_COM(_id, _match, _supply, _ereg, _emask, \ @@ -802,6 +815,115 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode) } } +static unsigned int rk801_get_mode(struct regulator_dev *rdev) +{ + unsigned int val; + int err; + + err = regmap_read(rdev->regmap, RK801_POWER_FPWM_EN_REG, &val); + if (err) + return err; + + if (val & BIT(rdev->desc->id)) + return REGULATOR_MODE_FAST; + else + return REGULATOR_MODE_NORMAL; +} + +static int rk801_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + unsigned int offset = rdev->desc->id; + + switch (mode) { + case REGULATOR_MODE_FAST: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_FPWM_MODE << offset); + case REGULATOR_MODE_NORMAL: + return regmap_update_bits(rdev->regmap, RK801_POWER_FPWM_EN_REG, + BIT(offset), RK801_AUTO_PWM_MODE << offset); + default: + dev_err(&rdev->dev, "do not support this mode\n"); + return -EINVAL; + } + + return 0; +} + +static int rk801_set_suspend_voltage(struct regulator_dev *rdev, int uv) +{ + unsigned int reg; + int sel; + + if (rdev->desc->id < RK801_ID_LDO1) + sel = regulator_map_voltage_linear_range(rdev, uv, uv); + else + sel = regulator_map_voltage_linear(rdev, uv, uv); + if (sel < 0) + return -EINVAL; + + reg = rdev->desc->vsel_reg + RK801_SLP_REG_OFFSET; + + return regmap_update_bits(rdev->regmap, reg, + rdev->desc->vsel_mask, sel); +} + +static int rk801_set_suspend_enable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + BIT(rdev->desc->id), BIT(rdev->desc->id)); +} + +static int rk801_set_suspend_disable(struct regulator_dev *rdev) +{ + return regmap_update_bits(rdev->regmap, RK801_POWER_SLP_EN_REG, + BIT(rdev->desc->id), 0); +} + +static int rk801_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_selector, + unsigned int new_selector) +{ + return regulator_set_voltage_time_sel(rdev, old_selector, + new_selector) + RK801_HW_SYNC_US; +} + +static const struct regulator_ops rk801_buck_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .set_voltage_time_sel = rk801_set_voltage_time_sel, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_mode = rk801_set_mode, + .get_mode = rk801_get_mode, + .set_suspend_voltage = rk801_set_suspend_voltage, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_reg_ops = { + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_suspend_voltage = rk801_set_suspend_voltage, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + +static const struct regulator_ops rk801_switch_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_suspend_enable = rk801_set_suspend_enable, + .set_suspend_disable = rk801_set_suspend_disable, +}; + static const struct regulator_ops rk805_reg_ops = { .list_voltage = regulator_list_voltage_linear, .map_voltage = regulator_map_voltage_linear, @@ -1049,6 +1171,123 @@ static const struct regulator_ops rk817_switch_ops = { .set_suspend_disable = rk817_set_suspend_disable, }; +static const struct linear_range rk801_buck1_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 83, 83, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 84, 84, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 85, 85, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck2_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0, 2, 50000), /* 0.8v - 0.9v */ + REGULATOR_LINEAR_RANGE(1800000, 3, 4, 400000), /* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(3300000, 5, 5, 0), /* 3.3v */ + REGULATOR_LINEAR_RANGE(5000000, 6, 6, 0), /* 5.0v */ + REGULATOR_LINEAR_RANGE(5250000, 7, 7, 0), /* 5.25v */ +}; + +static const struct linear_range rk801_buck4_voltage_ranges[] = { + REGULATOR_LINEAR_RANGE(500000, 0, 80, 12500), /* 0.5v - 1.5v */ + REGULATOR_LINEAR_RANGE(1800000, 81, 82, 400000),/* 1.8v - 2.2v */ + REGULATOR_LINEAR_RANGE(2500000, 83, 83, 0), /* 2.5v */ + REGULATOR_LINEAR_RANGE(2800000, 84, 84, 0), /* 2.8v */ + REGULATOR_LINEAR_RANGE(3000000, 85, 85, 0), /* 3.0v */ + REGULATOR_LINEAR_RANGE(3300000, 86, 86, 0), /* 3.3v */ +}; + +static const struct regulator_desc rk801_reg[] = { + { + .name = "dcdc1", + .supply_name = "vcc1", + .of_match = of_match_ptr("dcdc1"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC1, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 86, + .linear_ranges = rk801_buck1_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck1_voltage_ranges), + .vsel_reg = RK801_BUCK1_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC1), + .enable_val = ENABLE_MASK(RK801_ID_DCDC1), + .disable_val = DISABLE_VAL(RK801_ID_DCDC1), + .ramp_delay = 1000, + .of_map_mode = rk8xx_regulator_of_map_mode, + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "dcdc2", + .supply_name = "vcc2", + .of_match = of_match_ptr("dcdc2"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC2, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 8, + .linear_ranges = rk801_buck2_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck2_voltage_ranges), + .vsel_reg = RK801_BUCK2_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC2), + .enable_val = ENABLE_MASK(RK801_ID_DCDC2), + .disable_val = DISABLE_VAL(RK801_ID_DCDC2), + .ramp_delay = 1000, + .of_map_mode = rk8xx_regulator_of_map_mode, + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "dcdc3", + .supply_name = "vcc3", + .of_match = of_match_ptr("dcdc3"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC3, + .ops = &rk801_switch_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 1, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC3), + .enable_val = ENABLE_MASK(RK801_ID_DCDC3), + .disable_val = DISABLE_VAL(RK801_ID_DCDC3), + .of_map_mode = rk8xx_regulator_of_map_mode, + .enable_time = 400, + .owner = THIS_MODULE, + }, { + .name = "dcdc4", + .supply_name = "vcc4", + .of_match = of_match_ptr("dcdc4"), + .regulators_node = of_match_ptr("regulators"), + .id = RK801_ID_DCDC4, + .ops = &rk801_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 87, + .linear_ranges = rk801_buck4_voltage_ranges, + .n_linear_ranges = ARRAY_SIZE(rk801_buck4_voltage_ranges), + .vsel_reg = RK801_BUCK4_ON_VSEL_REG, + .vsel_mask = RK801_BUCK_VSEL_MASK, + .enable_reg = RK801_POWER_EN0_REG, + .enable_mask = ENABLE_MASK(RK801_ID_DCDC4), + .enable_val = ENABLE_MASK(RK801_ID_DCDC4), + .disable_val = DISABLE_VAL(RK801_ID_DCDC4), + .ramp_delay = 1000, + .of_map_mode = rk8xx_regulator_of_map_mode, + .enable_time = 400, + .owner = THIS_MODULE, + }, + + RK801_DESC(RK801_ID_LDO1, "ldo1", "vcc5", 500, 3400, 50, + RK801_LDO1_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(0), DISABLE_VAL(0), 400), + RK801_DESC(RK801_ID_LDO2, "ldo2", "vcc6", 500, 3400, 50, + RK801_LDO2_ON_VSEL_REG, RK801_LDO_VSEL_MASK, RK801_POWER_EN1_REG, + ENABLE_MASK(1), DISABLE_VAL(1), 400), + RK801_DESC_SWITCH(RK801_ID_SWITCH, "switch", "vcc7", RK801_POWER_EN1_REG, + ENABLE_MASK(2), DISABLE_VAL(2)), +}; + static const struct regulator_desc rk805_reg[] = { { .name = "DCDC_REG1", @@ -1887,6 +2126,10 @@ static int rk808_regulator_probe(struct platform_device *pdev) return -ENOMEM; switch (rk808->variant) { + case RK801_ID: + regulators = rk801_reg; + nregulators = RK801_NUM_REGULATORS; + break; case RK805_ID: regulators = rk805_reg; nregulators = RK805_NUM_REGULATORS; diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 2d5510acd078..81cfd60460f8 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -440,15 +440,15 @@ static int s2mpg10_of_parse_cb(struct device_node *np, [S2MPG10_EXTCTRL_LDO20M_EN] = S2MPG10_PCTRLSEL_LDO20M_EN, }; static const u32 ext_control_s2mpg11[] = { - [S2MPG11_EXTCTRL_PWREN] = S2MPG10_PCTRLSEL_PWREN, - [S2MPG11_EXTCTRL_PWREN_MIF] = S2MPG10_PCTRLSEL_PWREN_MIF, - [S2MPG11_EXTCTRL_AP_ACTIVE_N] = S2MPG10_PCTRLSEL_AP_ACTIVE_N, - [S2MPG11_EXTCTRL_G3D_EN] = S2MPG10_PCTRLSEL_CPUCL1_EN, - [S2MPG11_EXTCTRL_G3D_EN2] = S2MPG10_PCTRLSEL_CPUCL1_EN2, - [S2MPG11_EXTCTRL_AOC_VDD] = S2MPG10_PCTRLSEL_CPUCL2_EN, - [S2MPG11_EXTCTRL_AOC_RET] = S2MPG10_PCTRLSEL_CPUCL2_EN2, - [S2MPG11_EXTCTRL_UFS_EN] = S2MPG10_PCTRLSEL_TPU_EN, - [S2MPG11_EXTCTRL_LDO13S_EN] = S2MPG10_PCTRLSEL_TPU_EN2, + [S2MPG11_EXTCTRL_PWREN] = S2MPG11_PCTRLSEL_PWREN, + [S2MPG11_EXTCTRL_PWREN_MIF] = S2MPG11_PCTRLSEL_PWREN_MIF, + [S2MPG11_EXTCTRL_AP_ACTIVE_N] = S2MPG11_PCTRLSEL_AP_ACTIVE_N, + [S2MPG11_EXTCTRL_G3D_EN] = S2MPG11_PCTRLSEL_G3D_EN, + [S2MPG11_EXTCTRL_G3D_EN2] = S2MPG11_PCTRLSEL_G3D_EN2, + [S2MPG11_EXTCTRL_AOC_VDD] = S2MPG11_PCTRLSEL_AOC_VDD, + [S2MPG11_EXTCTRL_AOC_RET] = S2MPG11_PCTRLSEL_AOC_RET, + [S2MPG11_EXTCTRL_UFS_EN] = S2MPG11_PCTRLSEL_UFS_EN, + [S2MPG11_EXTCTRL_LDO13S_EN] = S2MPG11_PCTRLSEL_LDO13S_EN, }; u32 ext_control; @@ -478,8 +478,6 @@ static int s2mpg10_of_parse_cb(struct device_node *np, return -EINVAL; } - if (ext_control > ARRAY_SIZE(ext_control_s2mpg10)) - return -EINVAL; ext_control = ext_control_s2mpg10[ext_control]; break; @@ -503,8 +501,6 @@ static int s2mpg10_of_parse_cb(struct device_node *np, return -EINVAL; } - if (ext_control > ARRAY_SIZE(ext_control_s2mpg11)) - return -EINVAL; ext_control = ext_control_s2mpg11[ext_control]; break; diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c index 3286c9ab33d0..786622d8d598 100644 --- a/drivers/regulator/tps65185.c +++ b/drivers/regulator/tps65185.c @@ -332,6 +332,9 @@ static int tps65185_probe(struct i2c_client *client) int i; data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + data->regmap = devm_regmap_init_i2c(client, ®map_config); if (IS_ERR(data->regmap)) return dev_err_probe(&client->dev, PTR_ERR(data->regmap), diff --git a/drivers/remoteproc/Kconfig b/drivers/remoteproc/Kconfig index 48a0d3a69ed0..ee54436fea5a 100644 --- a/drivers/remoteproc/Kconfig +++ b/drivers/remoteproc/Kconfig @@ -27,6 +27,8 @@ config IMX_REMOTEPROC tristate "i.MX remoteproc support" depends on ARCH_MXC depends on HAVE_ARM_SMCCC + depends on IMX_SCMI_CPU_DRV || !IMX_SCMI_CPU_DRV + depends on IMX_SCMI_LMM_DRV || !IMX_SCMI_LMM_DRV select MAILBOX help Say y here to support iMX's remote processors via the remote diff --git a/drivers/remoteproc/imx_dsp_rproc.c b/drivers/remoteproc/imx_dsp_rproc.c index 5130a35214c9..008741af9f11 100644 --- a/drivers/remoteproc/imx_dsp_rproc.c +++ b/drivers/remoteproc/imx_dsp_rproc.c @@ -38,15 +38,15 @@ MODULE_PARM_DESC(no_mailboxes, /* Flag indicating that the remote is up and running */ #define REMOTE_IS_READY BIT(0) -/* Flag indicating that the host should wait for a firmware-ready response */ -#define WAIT_FW_READY BIT(1) +/* Flag indicating that the host should wait for a firmware-confirmation response */ +#define WAIT_FW_CONFIRMATION BIT(1) #define REMOTE_READY_WAIT_MAX_RETRIES 500 /* * This flag is set in the DSP resource table's features field to indicate - * that the firmware requires the host NOT to wait for a FW_READY response. + * that the firmware requires the host NOT to wait for a FW_CONFIRMATION response. */ -#define FEATURE_DONT_WAIT_FW_READY BIT(0) +#define FEATURE_SKIP_FW_CONFIRMATION BIT(0) /* att flags */ /* DSP own area */ @@ -287,7 +287,7 @@ static int imx_dsp_rproc_ready(struct rproc *rproc) * @avail: available space in the resource table * * Parse the DSP-specific resource entry and update flags accordingly. - * If the WAIT_FW_READY feature is set, the host must wait for the firmware + * If the WAIT_FW_CONFIRMATION feature is set, the host must wait for the firmware * to signal readiness before proceeding with execution. * * Return: RSC_HANDLED if processed successfully, RSC_IGNORED otherwise. @@ -322,7 +322,7 @@ static int imx_dsp_rproc_handle_rsc(struct rproc *rproc, u32 rsc_type, /* * For now, in struct fw_rsc_imx_dsp, version 0, - * only FEATURE_DONT_WAIT_FW_READY is valid. + * only FEATURE_SKIP_FW_CONFIRMATION is valid. * * When adding new features, please upgrade version. */ @@ -332,8 +332,8 @@ static int imx_dsp_rproc_handle_rsc(struct rproc *rproc, u32 rsc_type, return RSC_IGNORED; } - if (imx_dsp_rsc->features & FEATURE_DONT_WAIT_FW_READY) - priv->flags &= ~WAIT_FW_READY; + if (imx_dsp_rsc->features & FEATURE_SKIP_FW_CONFIRMATION) + priv->flags &= ~WAIT_FW_CONFIRMATION; return RSC_HANDLED; } @@ -385,7 +385,7 @@ static int imx_dsp_rproc_start(struct rproc *rproc) return ret; } - if (priv->flags & WAIT_FW_READY) + if (priv->flags & WAIT_FW_CONFIRMATION) return imx_dsp_rproc_ready(rproc); return 0; @@ -644,6 +644,32 @@ static void imx_dsp_rproc_free_mbox(struct imx_dsp_rproc *priv) mbox_free_channel(priv->rxdb_ch); } +static int imx_dsp_rproc_mem_alloc(struct rproc *rproc, + struct rproc_mem_entry *mem) +{ + struct device *dev = rproc->dev.parent; + void *va; + + va = ioremap_wc(mem->dma, mem->len); + if (!va) { + dev_err(dev, "Unable to map memory region: %pa+%zx\n", + &mem->dma, mem->len); + return -ENOMEM; + } + + mem->va = va; + + return 0; +} + +static int imx_dsp_rproc_mem_release(struct rproc *rproc, + struct rproc_mem_entry *mem) +{ + iounmap(mem->va); + + return 0; +} + /** * imx_dsp_rproc_add_carveout() - request mailbox channels * @priv: private data pointer @@ -659,7 +685,6 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv) struct device *dev = rproc->dev.parent; struct device_node *np = dev->of_node; struct rproc_mem_entry *mem; - void __iomem *cpu_addr; int a, i = 0; u64 da; @@ -673,15 +698,10 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv) if (imx_dsp_rproc_sys_to_da(priv, att->sa, att->size, &da)) return -EINVAL; - cpu_addr = devm_ioremap_wc(dev, att->sa, att->size); - if (!cpu_addr) { - dev_err(dev, "failed to map memory %p\n", &att->sa); - return -ENOMEM; - } - /* Register memory region */ - mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)att->sa, - att->size, da, NULL, NULL, "dsp_mem"); + mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)att->sa, + att->size, da, imx_dsp_rproc_mem_alloc, + imx_dsp_rproc_mem_release, "dsp_mem"); if (mem) rproc_coredump_add_segment(rproc, da, att->size); @@ -709,15 +729,11 @@ static int imx_dsp_rproc_add_carveout(struct imx_dsp_rproc *priv) if (imx_dsp_rproc_sys_to_da(priv, res.start, resource_size(&res), &da)) return -EINVAL; - cpu_addr = devm_ioremap_resource_wc(dev, &res); - if (IS_ERR(cpu_addr)) { - dev_err(dev, "failed to map memory %pR\n", &res); - return PTR_ERR(cpu_addr); - } - /* Register memory region */ - mem = rproc_mem_entry_init(dev, (void __force *)cpu_addr, (dma_addr_t)res.start, - resource_size(&res), da, NULL, NULL, + mem = rproc_mem_entry_init(dev, NULL, (dma_addr_t)res.start, + resource_size(&res), da, + imx_dsp_rproc_mem_alloc, + imx_dsp_rproc_mem_release, "%.*s", strchrnul(res.name, '@') - res.name, res.name); if (!mem) return -ENOMEM; @@ -984,9 +1000,11 @@ static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw) * Clear buffers after pm rumtime for internal ocram is not * accessible if power and clock are not enabled. */ - list_for_each_entry(carveout, &rproc->carveouts, node) { - if (carveout->va) - memset(carveout->va, 0, carveout->len); + if (rproc->state == RPROC_OFFLINE) { + list_for_each_entry(carveout, &rproc->carveouts, node) { + if (carveout->va) + memset(carveout->va, 0, carveout->len); + } } ret = imx_dsp_rproc_elf_load_segments(rproc, fw); @@ -1131,8 +1149,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev) priv = rproc->priv; priv->rproc = rproc; priv->dsp_dcfg = dsp_dcfg; - /* By default, host waits for fw_ready reply */ - priv->flags |= WAIT_FW_READY; + /* By default, host waits for fw_confirmation reply */ + priv->flags |= WAIT_FW_CONFIRMATION; if (no_mailboxes) imx_dsp_rproc_mbox_init = imx_dsp_rproc_mbox_no_alloc; @@ -1242,6 +1260,21 @@ static int imx_dsp_suspend(struct device *dev) if (rproc->state != RPROC_RUNNING) goto out; + /* + * No channel available for sending messages; + * indicates no mailboxes present, so trigger PM runtime suspend + */ + if (!priv->tx_ch) { + dev_dbg(dev, "No initialized mbox tx channel, suspend directly.\n"); + goto out; + } + + /* No fw confirmation expected, so trigger PM runtime suspend */ + if (!(priv->flags & WAIT_FW_CONFIRMATION)) { + dev_dbg(dev, "No FW_CONFIRMATION needed, suspend directly.\n"); + goto out; + } + reinit_completion(&priv->pm_comp); /* Tell DSP that suspend is happening */ diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c index 3be8790c14a2..8c8ddbf995a4 100644 --- a/drivers/remoteproc/imx_rproc.c +++ b/drivers/remoteproc/imx_rproc.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include "imx_rproc.h" @@ -92,9 +94,16 @@ struct imx_rproc_mem { #define ATT_CORE_MASK 0xffff #define ATT_CORE(I) BIT((I)) +/* Linux has permission to handle the Logical Machine of remote cores */ +#define IMX_RPROC_FLAGS_SM_LMM_CTRL BIT(0) + static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block); static void imx_rproc_free_mbox(void *data); +/* Forward declarations for platform operations */ +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm; +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu; + struct imx_rproc { struct device *dev; struct regmap *regmap; @@ -116,6 +125,24 @@ struct imx_rproc { u32 entry; /* cpu start address */ u32 core_index; struct dev_pm_domain_list *pd_list; + const struct imx_rproc_plat_ops *ops; + /* + * For i.MX System Manager based systems + * BIT 0: IMX_RPROC_FLAGS_SM_LMM_CTRL(RPROC LM is under Linux control ) + */ + u32 flags; +}; + +static const struct imx_rproc_att imx_rproc_att_imx95_m7[] = { + /* dev addr , sys addr , size , flags */ + /* TCM CODE NON-SECURE */ + { 0x00000000, 0x203C0000, 0x00040000, ATT_OWN | ATT_IOMEM }, + + /* TCM SYS NON-SECURE*/ + { 0x20000000, 0x20400000, 0x00040000, ATT_OWN | ATT_IOMEM }, + + /* DDR */ + { 0x80000000, 0x80000000, 0x50000000, 0 }, }; static const struct imx_rproc_att imx_rproc_att_imx93[] = { @@ -312,10 +339,51 @@ static int imx_rproc_scu_api_start(struct rproc *rproc) return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry); } -static int imx_rproc_start(struct rproc *rproc) +static int imx_rproc_sm_cpu_start(struct rproc *rproc) { struct imx_rproc *priv = rproc->priv; const struct imx_rproc_dcfg *dcfg = priv->dcfg; + int ret; + + ret = scmi_imx_cpu_reset_vector_set(dcfg->cpuid, 0, true, false, false); + if (ret) { + dev_err(priv->dev, "Failed to set reset vector cpuid(%u): %d\n", dcfg->cpuid, ret); + return ret; + } + + return scmi_imx_cpu_start(dcfg->cpuid, true); +} + +static int imx_rproc_sm_lmm_start(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; + const struct imx_rproc_dcfg *dcfg = priv->dcfg; + struct device *dev = priv->dev; + int ret; + + /* + * If the remoteproc core can't start the M7, it will already be + * handled in imx_rproc_sm_lmm_prepare(). + */ + ret = scmi_imx_lmm_reset_vector_set(dcfg->lmid, dcfg->cpuid, 0, 0); + if (ret) { + dev_err(dev, "Failed to set reset vector lmid(%u), cpuid(%u): %d\n", + dcfg->lmid, dcfg->cpuid, ret); + return ret; + } + + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_BOOT, 0); + if (ret) { + dev_err(dev, "Failed to boot lmm(%d): %d\n", dcfg->lmid, ret); + return ret; + } + + return 0; +} + +static int imx_rproc_start(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; struct device *dev = priv->dev; int ret; @@ -323,10 +391,10 @@ static int imx_rproc_start(struct rproc *rproc) if (ret) return ret; - if (!dcfg->ops || !dcfg->ops->start) + if (!priv->ops || !priv->ops->start) return -EOPNOTSUPP; - ret = dcfg->ops->start(rproc); + ret = priv->ops->start(rproc); if (ret) dev_err(dev, "Failed to enable remote core!\n"); @@ -369,17 +437,35 @@ static int imx_rproc_scu_api_stop(struct rproc *rproc) return imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry); } -static int imx_rproc_stop(struct rproc *rproc) +static int imx_rproc_sm_cpu_stop(struct rproc *rproc) { struct imx_rproc *priv = rproc->priv; const struct imx_rproc_dcfg *dcfg = priv->dcfg; + + return scmi_imx_cpu_start(dcfg->cpuid, false); +} + +static int imx_rproc_sm_lmm_stop(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; + const struct imx_rproc_dcfg *dcfg = priv->dcfg; + + if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_CTRL)) + return -EACCES; + + return scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0); +} + +static int imx_rproc_stop(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; struct device *dev = priv->dev; int ret; - if (!dcfg->ops || !dcfg->ops->stop) + if (!priv->ops || !priv->ops->stop) return -EOPNOTSUPP; - ret = dcfg->ops->stop(rproc); + ret = priv->ops->stop(rproc); if (ret) dev_err(dev, "Failed to stop remote core\n"); else @@ -486,6 +572,36 @@ static int imx_rproc_mem_release(struct rproc *rproc, return 0; } +static int imx_rproc_sm_lmm_prepare(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; + const struct imx_rproc_dcfg *dcfg = priv->dcfg; + int ret; + + /* + * IMX_RPROC_FLAGS_SM_LMM_CTRL not set indicates Linux is not able + * to start/stop M7, then if rproc is not in detached state, + * prepare should fail. If in detached state, this is in rproc_attach() + * path. + */ + if (rproc->state == RPROC_DETACHED) + return 0; + + if (!(priv->flags & IMX_RPROC_FLAGS_SM_LMM_CTRL)) + return -EACCES; + + /* Power on the Logical Machine to make sure TCM is available. */ + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0); + if (ret) { + dev_err(priv->dev, "Failed to power on lmm(%d): %d\n", dcfg->lmid, ret); + return ret; + } + + dev_info(priv->dev, "lmm(%d) powered on by Linux\n", dcfg->lmid); + + return 0; +} + static int imx_rproc_prepare(struct rproc *rproc) { struct imx_rproc *priv = rproc->priv; @@ -501,7 +617,7 @@ static int imx_rproc_prepare(struct rproc *rproc) err = of_reserved_mem_region_to_resource(np, i++, &res); if (err) - return 0; + break; /* * Ignore the first memory region which will be used vdev buffer. @@ -528,6 +644,11 @@ static int imx_rproc_prepare(struct rproc *rproc) rproc_coredump_add_segment(rproc, da, resource_size(&res)); rproc_add_carveout(rproc, mem); } + + if (priv->ops && priv->ops->prepare) + return priv->ops->prepare(rproc); + + return 0; } static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw) @@ -584,12 +705,11 @@ static int imx_rproc_scu_api_detach(struct rproc *rproc) static int imx_rproc_detach(struct rproc *rproc) { struct imx_rproc *priv = rproc->priv; - const struct imx_rproc_dcfg *dcfg = priv->dcfg; - if (!dcfg->ops || !dcfg->ops->detach) + if (!priv->ops || !priv->ops->detach) return -EOPNOTSUPP; - return dcfg->ops->detach(rproc); + return priv->ops->detach(rproc); } static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz) @@ -609,6 +729,10 @@ imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware * { struct imx_rproc *priv = rproc->priv; + /* No resource table in the firmware */ + if (!rproc->table_ptr) + return NULL; + if (priv->rsc_table) return (struct resource_table *)priv->rsc_table; @@ -694,7 +818,7 @@ static int imx_rproc_addr_init(struct imx_rproc *priv, } priv->mem[b].sys_addr = res.start; priv->mem[b].size = resource_size(&res); - if (!strcmp(res.name, "rsc-table")) + if (strstarts(res.name, "rsc-table")) priv->rsc_table = priv->mem[b].cpu_addr; b++; } @@ -977,20 +1101,97 @@ static int imx_rproc_scu_api_detect_mode(struct rproc *rproc) return 0; } -static int imx_rproc_detect_mode(struct imx_rproc *priv) +/* Check whether remoteproc core is responsible for M7 lifecycle */ +static int imx_rproc_sm_lmm_check(struct rproc *rproc, bool started) { + struct imx_rproc *priv = rproc->priv; const struct imx_rproc_dcfg *dcfg = priv->dcfg; + struct device *dev = priv->dev; + int ret; + + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_POWER_ON, 0); + if (ret) { + if (ret == -EACCES) { + /* + * M7 is booted before Linux and not under Linux Control, so only + * do IPC between RPROC and Linux, not return failure + */ + dev_info(dev, "lmm(%d) not under Linux Control\n", dcfg->lmid); + return 0; + } + + dev_err(dev, "power on lmm(%d) failed: %d\n", dcfg->lmid, ret); + return ret; + } + + /* Shutdown remote processor if not started */ + if (!started) { + ret = scmi_imx_lmm_operation(dcfg->lmid, SCMI_IMX_LMM_SHUTDOWN, 0); + if (ret) { + dev_err(dev, "shutdown lmm(%d) failed: %d\n", dcfg->lmid, ret); + return ret; + } + } + + priv->flags |= IMX_RPROC_FLAGS_SM_LMM_CTRL; + + return 0; +} + +static int imx_rproc_sm_detect_mode(struct rproc *rproc) +{ + struct imx_rproc *priv = rproc->priv; + const struct imx_rproc_dcfg *dcfg = priv->dcfg; + struct device *dev = priv->dev; + struct scmi_imx_lmm_info info; + bool started = false; + int ret; + + ret = scmi_imx_cpu_started(dcfg->cpuid, &started); + if (ret) { + dev_err(dev, "Failed to detect cpu(%d) status: %d\n", dcfg->cpuid, ret); + return ret; + } + + if (started) + priv->rproc->state = RPROC_DETACHED; + + /* Get current Linux Logical Machine ID */ + ret = scmi_imx_lmm_info(LMM_ID_DISCOVER, &info); + if (ret) { + dev_err(dev, "Failed to get current LMM ID err: %d\n", ret); + return ret; + } /* - * To i.MX{7,8} ULP, Linux is under control of RTOS, no need - * dcfg->ops or dcfg->ops->detect_mode, it is state RPROC_DETACHED. + * Check whether M7 is in the same LM as host core(running Linux) + * If yes, use CPU protocol API to manage M7. + * If no, use Logical Machine API to manage M7. */ - if (!dcfg->ops || !dcfg->ops->detect_mode) { + if (dcfg->lmid == info.lmid) { + priv->ops = &imx_rproc_ops_sm_cpu; + dev_info(dev, "Using CPU Protocol OPS\n"); + return 0; + } + + priv->ops = &imx_rproc_ops_sm_lmm; + dev_info(dev, "Using LMM Protocol OPS\n"); + + return imx_rproc_sm_lmm_check(rproc, started); +} + +static int imx_rproc_detect_mode(struct imx_rproc *priv) +{ + /* + * To i.MX{7,8} ULP, Linux is under control of RTOS, no need + * priv->ops or priv->ops->detect_mode, it is state RPROC_DETACHED. + */ + if (!priv->ops || !priv->ops->detect_mode) { priv->rproc->state = RPROC_DETACHED; return 0; } - return dcfg->ops->detect_mode(priv->rproc); + return priv->ops->detect_mode(priv->rproc); } static int imx_rproc_sys_off_handler(struct sys_off_data *data) @@ -1040,6 +1241,9 @@ static int imx_rproc_probe(struct platform_device *pdev) priv->dcfg = dcfg; priv->dev = dev; + if (dcfg->ops) + priv->ops = dcfg->ops; + dev_set_drvdata(dev, rproc); priv->workqueue = create_workqueue(dev_name(dev)); if (!priv->workqueue) { @@ -1151,6 +1355,19 @@ static const struct imx_rproc_plat_ops imx_rproc_ops_scu_api = { .detect_mode = imx_rproc_scu_api_detect_mode, }; +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_lmm = { + .detect_mode = imx_rproc_sm_detect_mode, + .prepare = imx_rproc_sm_lmm_prepare, + .start = imx_rproc_sm_lmm_start, + .stop = imx_rproc_sm_lmm_stop, +}; + +static const struct imx_rproc_plat_ops imx_rproc_ops_sm_cpu = { + .detect_mode = imx_rproc_sm_detect_mode, + .start = imx_rproc_sm_cpu_start, + .stop = imx_rproc_sm_cpu_stop, +}; + static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = { .src_reg = IMX7D_SRC_SCR, .src_mask = IMX7D_M4_RST_MASK, @@ -1234,6 +1451,15 @@ static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = { .flags = IMX_RPROC_NEED_CLKS, }; +static const struct imx_rproc_dcfg imx_rproc_cfg_imx95_m7 = { + .att = imx_rproc_att_imx95_m7, + .att_size = ARRAY_SIZE(imx_rproc_att_imx95_m7), + .ops = &imx_rproc_ops_sm_lmm, + /* Must align with System Manager Firmware */ + .cpuid = 1, /* Use 1 as cpu id for M7 core */ + .lmid = 1, /* Use 1 as Logical Machine ID where M7 resides */ +}; + static const struct of_device_id imx_rproc_of_match[] = { { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp }, { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d }, @@ -1248,6 +1474,7 @@ static const struct of_device_id imx_rproc_of_match[] = { { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm }, { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp }, { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 }, + { .compatible = "fsl,imx95-cm7", .data = &imx_rproc_cfg_imx95_m7 }, {}, }; MODULE_DEVICE_TABLE(of, imx_rproc_of_match); diff --git a/drivers/remoteproc/imx_rproc.h b/drivers/remoteproc/imx_rproc.h index 1b2d9f4d6d19..d37e6f90548c 100644 --- a/drivers/remoteproc/imx_rproc.h +++ b/drivers/remoteproc/imx_rproc.h @@ -24,6 +24,7 @@ struct imx_rproc_plat_ops { int (*stop)(struct rproc *rproc); int (*detach)(struct rproc *rproc); int (*detect_mode)(struct rproc *rproc); + int (*prepare)(struct rproc *rproc); }; struct imx_rproc_dcfg { @@ -37,6 +38,9 @@ struct imx_rproc_dcfg { size_t att_size; u32 flags; const struct imx_rproc_plat_ops *ops; + /* For System Manager(SM) based SoCs */ + u32 cpuid; /* ID of the remote core */ + u32 lmid; /* ID of the Logcial Machine */ }; #endif /* _IMX_RPROC_H */ diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c index db8fd045468d..bb6f6a16d895 100644 --- a/drivers/remoteproc/mtk_scp.c +++ b/drivers/remoteproc/mtk_scp.c @@ -283,7 +283,7 @@ static irqreturn_t scp_irq_handler(int irq, void *priv) struct mtk_scp *scp = priv; int ret; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(scp->dev, "failed to enable clocks\n"); return IRQ_NONE; @@ -291,7 +291,7 @@ static irqreturn_t scp_irq_handler(int irq, void *priv) scp->data->scp_irq_handler(scp); - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return IRQ_HANDLED; } @@ -665,7 +665,7 @@ static int scp_load(struct rproc *rproc, const struct firmware *fw) struct device *dev = scp->dev; int ret; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(dev, "failed to enable clocks\n"); return ret; @@ -680,7 +680,7 @@ static int scp_load(struct rproc *rproc, const struct firmware *fw) ret = scp_elf_load_segments(rproc, fw); leave: - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return ret; } @@ -691,14 +691,14 @@ static int scp_parse_fw(struct rproc *rproc, const struct firmware *fw) struct device *dev = scp->dev; int ret; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(dev, "failed to enable clocks\n"); return ret; } ret = scp_ipi_init(scp, fw); - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return ret; } @@ -709,7 +709,7 @@ static int scp_start(struct rproc *rproc) struct scp_run *run = &scp->run; int ret; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(dev, "failed to enable clocks\n"); return ret; @@ -734,14 +734,14 @@ static int scp_start(struct rproc *rproc) goto stop; } - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); dev_info(dev, "SCP is ready. FW version %s\n", run->fw_ver); return 0; stop: scp->data->scp_reset_assert(scp); - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return ret; } @@ -909,7 +909,7 @@ static int scp_stop(struct rproc *rproc) struct mtk_scp *scp = rproc->priv; int ret; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(scp->dev, "failed to enable clocks\n"); return ret; @@ -917,12 +917,29 @@ static int scp_stop(struct rproc *rproc) scp->data->scp_reset_assert(scp); scp->data->scp_stop(scp); - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return 0; } +static int scp_prepare(struct rproc *rproc) +{ + struct mtk_scp *scp = rproc->priv; + + return clk_prepare(scp->clk); +} + +static int scp_unprepare(struct rproc *rproc) +{ + struct mtk_scp *scp = rproc->priv; + + clk_unprepare(scp->clk); + return 0; +} + static const struct rproc_ops scp_ops = { + .prepare = scp_prepare, + .unprepare = scp_unprepare, .start = scp_start, .stop = scp_stop, .load = scp_load, @@ -1287,7 +1304,6 @@ static int scp_add_multi_core(struct platform_device *pdev, struct device *dev = &pdev->dev; struct device_node *np = dev_of_node(dev); struct platform_device *cpdev; - struct device_node *child; struct list_head *scp_list = &scp_cluster->mtk_scp_list; const struct mtk_scp_of_data **cluster_of_data; struct mtk_scp *scp, *temp; @@ -1296,11 +1312,10 @@ static int scp_add_multi_core(struct platform_device *pdev, cluster_of_data = (const struct mtk_scp_of_data **)of_device_get_match_data(dev); - for_each_available_child_of_node(np, child) { + for_each_available_child_of_node_scoped(np, child) { if (!cluster_of_data[core_id]) { ret = -EINVAL; dev_err(dev, "Not support core %d\n", core_id); - of_node_put(child); goto init_fail; } @@ -1308,7 +1323,6 @@ static int scp_add_multi_core(struct platform_device *pdev, if (!cpdev) { ret = -ENODEV; dev_err(dev, "Not found platform device for core %d\n", core_id); - of_node_put(child); goto init_fail; } @@ -1317,14 +1331,12 @@ static int scp_add_multi_core(struct platform_device *pdev, if (IS_ERR(scp)) { ret = PTR_ERR(scp); dev_err(dev, "Failed to initialize core %d rproc\n", core_id); - of_node_put(child); goto init_fail; } ret = rproc_add(scp->rproc); if (ret) { dev_err(dev, "Failed to add rproc of core %d\n", core_id); - of_node_put(child); scp_free(scp); goto init_fail; } @@ -1580,12 +1592,51 @@ static const struct of_device_id mtk_scp_of_match[] = { }; MODULE_DEVICE_TABLE(of, mtk_scp_of_match); +static int __maybe_unused scp_suspend(struct device *dev) +{ + struct mtk_scp *scp = dev_get_drvdata(dev); + struct rproc *rproc = scp->rproc; + + /* + * Only unprepare if the SCP is running and holding the clock. + * + * Note: `scp_ops` doesn't implement .attach() callback, hence + * `rproc->state` can never be RPROC_ATTACHED. Otherwise, it + * should also be checked here. + */ + if (rproc->state == RPROC_RUNNING) + clk_unprepare(scp->clk); + return 0; +} + +static int __maybe_unused scp_resume(struct device *dev) +{ + struct mtk_scp *scp = dev_get_drvdata(dev); + struct rproc *rproc = scp->rproc; + + /* + * Only prepare if the SCP was running and holding the clock. + * + * Note: `scp_ops` doesn't implement .attach() callback, hence + * `rproc->state` can never be RPROC_ATTACHED. Otherwise, it + * should also be checked here. + */ + if (rproc->state == RPROC_RUNNING) + return clk_prepare(scp->clk); + return 0; +} + +static const struct dev_pm_ops scp_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(scp_suspend, scp_resume) +}; + static struct platform_driver mtk_scp_driver = { .probe = scp_probe, .remove = scp_remove, .driver = { .name = "mtk-scp", .of_match_table = mtk_scp_of_match, + .pm = &scp_pm_ops, }, }; diff --git a/drivers/remoteproc/mtk_scp_ipi.c b/drivers/remoteproc/mtk_scp_ipi.c index c068227e251e..7a37e273b3af 100644 --- a/drivers/remoteproc/mtk_scp_ipi.c +++ b/drivers/remoteproc/mtk_scp_ipi.c @@ -171,7 +171,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, WARN_ON(len > scp_sizes->ipi_share_buffer_size) || WARN_ON(!buf)) return -EINVAL; - ret = clk_prepare_enable(scp->clk); + ret = clk_enable(scp->clk); if (ret) { dev_err(scp->dev, "failed to enable clock\n"); return ret; @@ -211,7 +211,7 @@ int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len, unlock_mutex: mutex_unlock(&scp->send_lock); - clk_disable_unprepare(scp->clk); + clk_disable(scp->clk); return ret; } diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 8c8688f99f0a..6c31140268ac 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c @@ -370,7 +370,7 @@ static struct qcom_ssr_subsystem *qcom_ssr_get_subsys(const char *name) if (!strcmp(info->name, name)) goto out; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { info = ERR_PTR(-ENOMEM); goto out; @@ -534,7 +534,7 @@ static int pdm_notify_prepare(struct rproc_subdev *subdev) struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; diff --git a/drivers/remoteproc/qcom_sysmon.c b/drivers/remoteproc/qcom_sysmon.c index 660ac6fc4082..3ceec1fd6d99 100644 --- a/drivers/remoteproc/qcom_sysmon.c +++ b/drivers/remoteproc/qcom_sysmon.c @@ -203,7 +203,7 @@ static const struct qmi_elem_info ssctl_shutdown_resp_ei[] = { }; struct ssctl_subsys_event_req { - u8 subsys_name_len; + u32 subsys_name_len; char subsys_name[SSCTL_SUBSYS_NAME_LENGTH]; u32 event; u8 evt_driven_valid; @@ -628,7 +628,7 @@ struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc, struct qcom_sysmon *sysmon; int ret; - sysmon = kzalloc(sizeof(*sysmon), GFP_KERNEL); + sysmon = kzalloc_obj(*sysmon); if (!sysmon) return ERR_PTR(-ENOMEM); diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index ee18bf2e8054..4add9037dbd5 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c @@ -537,7 +537,7 @@ static int wcnss_alloc_memory_region(struct qcom_wcnss *wcnss) wcnss->mem_phys = wcnss->mem_reloc = res.start; wcnss->mem_size = resource_size(&res); - wcnss->mem_region = devm_ioremap_resource_wc(wcnss->dev, &res); + wcnss->mem_region = devm_ioremap_wc(wcnss->dev, wcnss->mem_phys, wcnss->mem_size); if (IS_ERR(wcnss->mem_region)) { dev_err(wcnss->dev, "unable to map memory region: %pR\n", &res); return PTR_ERR(wcnss->mem_region); diff --git a/drivers/remoteproc/qcom_wcnss_iris.c b/drivers/remoteproc/qcom_wcnss_iris.c index 2b52b403eb3f..2b89b4db6c94 100644 --- a/drivers/remoteproc/qcom_wcnss_iris.c +++ b/drivers/remoteproc/qcom_wcnss_iris.c @@ -125,7 +125,7 @@ struct qcom_iris *qcom_iris_probe(struct device *parent, bool *use_48mhz_xo) return ERR_PTR(-EINVAL); } - iris = kzalloc(sizeof(*iris), GFP_KERNEL); + iris = kzalloc_obj(*iris); if (!iris) { of_node_put(of_node); return ERR_PTR(-ENOMEM); diff --git a/drivers/remoteproc/remoteproc_core.c b/drivers/remoteproc/remoteproc_core.c index aada2780b343..b087ed21858a 100644 --- a/drivers/remoteproc/remoteproc_core.c +++ b/drivers/remoteproc/remoteproc_core.c @@ -557,7 +557,7 @@ static int rproc_handle_trace(struct rproc *rproc, void *ptr, return -EINVAL; } - trace = kzalloc(sizeof(*trace), GFP_KERNEL); + trace = kzalloc_obj(*trace); if (!trace) return -ENOMEM; @@ -635,7 +635,7 @@ static int rproc_handle_devmem(struct rproc *rproc, void *ptr, return -EINVAL; } - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) return -ENOMEM; @@ -727,7 +727,7 @@ static int rproc_alloc_carveout(struct rproc *rproc, * physical address in this case. */ if (mem->da != FW_RSC_ADDR_ANY && rproc->domain) { - mapping = kzalloc(sizeof(*mapping), GFP_KERNEL); + mapping = kzalloc_obj(*mapping); if (!mapping) { ret = -ENOMEM; goto dma_free; @@ -917,7 +917,7 @@ rproc_mem_entry_init(struct device *dev, struct rproc_mem_entry *mem; va_list args; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return mem; @@ -960,7 +960,7 @@ rproc_of_resm_mem_entry_init(struct device *dev, u32 of_resm_idx, size_t len, struct rproc_mem_entry *mem; va_list args; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return mem; diff --git a/drivers/remoteproc/remoteproc_coredump.c b/drivers/remoteproc/remoteproc_coredump.c index 6ede8c0c93ad..ceff380228c7 100644 --- a/drivers/remoteproc/remoteproc_coredump.c +++ b/drivers/remoteproc/remoteproc_coredump.c @@ -49,7 +49,7 @@ int rproc_coredump_add_segment(struct rproc *rproc, dma_addr_t da, size_t size) { struct rproc_dump_segment *segment; - segment = kzalloc(sizeof(*segment), GFP_KERNEL); + segment = kzalloc_obj(*segment); if (!segment) return -ENOMEM; @@ -86,7 +86,7 @@ int rproc_coredump_add_custom_segment(struct rproc *rproc, { struct rproc_dump_segment *segment; - segment = kzalloc(sizeof(*segment), GFP_KERNEL); + segment = kzalloc_obj(*segment); if (!segment) return -ENOMEM; diff --git a/drivers/remoteproc/remoteproc_virtio.c b/drivers/remoteproc/remoteproc_virtio.c index c5d46a878149..d5e9ff045a28 100644 --- a/drivers/remoteproc/remoteproc_virtio.c +++ b/drivers/remoteproc/remoteproc_virtio.c @@ -430,7 +430,7 @@ static int rproc_add_virtio_dev(struct rproc_vdev *rvdev, int id) } /* Allocate virtio device */ - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) { ret = -ENOMEM; goto out; diff --git a/drivers/remoteproc/stm32_rproc.c b/drivers/remoteproc/stm32_rproc.c index c28679d3b43c..632614013dc6 100644 --- a/drivers/remoteproc/stm32_rproc.c +++ b/drivers/remoteproc/stm32_rproc.c @@ -164,7 +164,7 @@ static int stm32_rproc_of_memory_translations(struct platform_device *pdev, p_mems = devm_kcalloc(dev, cnt, sizeof(*p_mems), GFP_KERNEL); if (!p_mems) return -ENOMEM; - mem_range = kcalloc(cnt, sizeof(*mem_range), GFP_KERNEL); + mem_range = kzalloc_objs(*mem_range, cnt); if (!mem_range) return -ENOMEM; diff --git a/drivers/remoteproc/xlnx_r5_remoteproc.c b/drivers/remoteproc/xlnx_r5_remoteproc.c index a7b75235f53e..b71ce69afe9f 100644 --- a/drivers/remoteproc/xlnx_r5_remoteproc.c +++ b/drivers/remoteproc/xlnx_r5_remoteproc.c @@ -265,7 +265,7 @@ static struct mbox_info *zynqmp_r5_setup_mbox(struct device *cdev) struct mbox_client *mbox_cl; struct mbox_info *ipi; - ipi = kzalloc(sizeof(*ipi), GFP_KERNEL); + ipi = kzalloc_obj(*ipi); if (!ipi) return NULL; @@ -1271,7 +1271,6 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) struct zynqmp_r5_core **r5_cores; enum rpu_oper_mode fw_reg_val; struct device **child_devs; - struct device_node *child; enum rpu_tcm_comb tcm_mode; int core_count, ret, i; struct mbox_info *ipi; @@ -1338,22 +1337,20 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) core_count = 1; } - child_devs = kcalloc(core_count, sizeof(struct device *), GFP_KERNEL); + child_devs = kzalloc_objs(struct device *, core_count); if (!child_devs) return -ENOMEM; - r5_cores = kcalloc(core_count, - sizeof(struct zynqmp_r5_core *), GFP_KERNEL); + r5_cores = kzalloc_objs(struct zynqmp_r5_core *, core_count); if (!r5_cores) { kfree(child_devs); return -ENOMEM; } i = 0; - for_each_available_child_of_node(dev_node, child) { + for_each_available_child_of_node_scoped(dev_node, child) { child_pdev = of_find_device_by_node(child); if (!child_pdev) { - of_node_put(child); ret = -ENODEV; goto release_r5_cores; } @@ -1363,7 +1360,6 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) /* create and add remoteproc instance of type struct rproc */ r5_cores[i] = zynqmp_r5_add_rproc_core(&child_pdev->dev); if (IS_ERR(r5_cores[i])) { - of_node_put(child); ret = PTR_ERR(r5_cores[i]); r5_cores[i] = NULL; goto release_r5_cores; @@ -1383,10 +1379,8 @@ static int zynqmp_r5_cluster_init(struct zynqmp_r5_cluster *cluster) * If two child nodes are available in dts in lockstep mode, * then ignore second child node. */ - if (cluster_mode == LOCKSTEP_MODE) { - of_node_put(child); + if (cluster_mode == LOCKSTEP_MODE) break; - } i++; } @@ -1508,7 +1502,7 @@ static int zynqmp_r5_remoteproc_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; int ret; - cluster = kzalloc(sizeof(*cluster), GFP_KERNEL); + cluster = kzalloc_obj(*cluster); if (!cluster) return -ENOMEM; diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c index b495d5291868..1eebc2602187 100644 --- a/drivers/resctrl/mpam_devices.c +++ b/drivers/resctrl/mpam_devices.c @@ -295,7 +295,7 @@ mpam_class_alloc(u8 level_idx, enum mpam_class_types type) lockdep_assert_held(&mpam_list_lock); - class = kzalloc(sizeof(*class), GFP_KERNEL); + class = kzalloc_obj(*class); if (!class) return ERR_PTR(-ENOMEM); init_garbage(&class->garbage); @@ -343,7 +343,7 @@ mpam_component_alloc(struct mpam_class *class, int id) lockdep_assert_held(&mpam_list_lock); - comp = kzalloc(sizeof(*comp), GFP_KERNEL); + comp = kzalloc_obj(*comp); if (!comp) return ERR_PTR(-ENOMEM); init_garbage(&comp->garbage); @@ -398,7 +398,7 @@ mpam_vmsc_alloc(struct mpam_component *comp, struct mpam_msc *msc) lockdep_assert_held(&mpam_list_lock); - vmsc = kzalloc(sizeof(*vmsc), GFP_KERNEL); + vmsc = kzalloc_obj(*vmsc); if (!vmsc) return ERR_PTR(-ENOMEM); init_garbage(&vmsc->garbage); @@ -2419,7 +2419,7 @@ static int __allocate_component_cfg(struct mpam_component *comp) if (comp->cfg) return 0; - comp->cfg = kcalloc(mpam_partid_max + 1, sizeof(*comp->cfg), GFP_KERNEL); + comp->cfg = kzalloc_objs(*comp->cfg, mpam_partid_max + 1); if (!comp->cfg) return -ENOMEM; @@ -2444,9 +2444,8 @@ static int __allocate_component_cfg(struct mpam_component *comp) if (!ris->props.num_mbwu_mon) continue; - mbwu_state = kcalloc(ris->props.num_mbwu_mon, - sizeof(*ris->mbwu_state), - GFP_KERNEL); + mbwu_state = kzalloc_objs(*ris->mbwu_state, + ris->props.num_mbwu_mon); if (!mbwu_state) { __destroy_component_cfg(comp); return -ENOMEM; diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 0666dfc41ca9..fceec45c8afc 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -778,7 +778,7 @@ __reset_control_get_internal(struct reset_controller_dev *rcdev, } } - rstc = kzalloc(sizeof(*rstc), GFP_KERNEL); + rstc = kzalloc_obj(*rstc); if (!rstc) return ERR_PTR(-ENOMEM); @@ -836,7 +836,7 @@ static int reset_add_gpio_aux_device(struct device *parent, struct auxiliary_device *adev; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; @@ -931,7 +931,7 @@ static int __reset_add_reset_gpio_device(const struct of_phandle_args *args) return id; /* Not freed on success, because it is persisent subsystem data. */ - rgpio_dev = kzalloc(sizeof(*rgpio_dev), GFP_KERNEL); + rgpio_dev = kzalloc_obj(*rgpio_dev); if (!rgpio_dev) { ret = -ENOMEM; goto err_ida_free; @@ -1360,7 +1360,7 @@ of_reset_control_array_get(struct device_node *np, enum reset_control_flags flag if (num < 0) return optional ? NULL : ERR_PTR(num); - resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); + resets = kzalloc_flex(*resets, rstc, num); if (!resets) return ERR_PTR(-ENOMEM); resets->num_rstcs = num; diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c index e5b6127783a7..4070a4b6663f 100644 --- a/drivers/reset/reset-npcm.c +++ b/drivers/reset/reset-npcm.c @@ -399,7 +399,7 @@ static struct auxiliary_device *npcm_clock_adev_alloc(struct npcm_rc_data *rst_d struct auxiliary_device *adev; int ret; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index 8c6492e5693c..da208270b787 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -27,7 +27,7 @@ static int a10_reset_init(struct device_node *np) int ret; u32 reg_offset = 0x10; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c index e752594b6971..2544de6576e4 100644 --- a/drivers/reset/reset-sunxi.c +++ b/drivers/reset/reset-sunxi.c @@ -27,7 +27,7 @@ static int sunxi_reset_init(struct device_node *np) resource_size_t size; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c index d1213c33da20..0e03c5336609 100644 --- a/drivers/rpmsg/mtk_rpmsg.c +++ b/drivers/rpmsg/mtk_rpmsg.c @@ -91,7 +91,7 @@ __mtk_create_ept(struct mtk_rpmsg_rproc_subdev *mtk_subdev, struct platform_device *pdev = mtk_subdev->pdev; int ret; - mept = kzalloc(sizeof(*mept), GFP_KERNEL); + mept = kzalloc_obj(*mept); if (!mept) return NULL; mept->mtk_subdev = mtk_subdev; @@ -201,7 +201,7 @@ static int mtk_rpmsg_register_device(struct mtk_rpmsg_rproc_subdev *mtk_subdev, struct mtk_rpmsg_device *mdev; struct platform_device *pdev = mtk_subdev->pdev; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; @@ -252,7 +252,7 @@ static int mtk_rpmsg_create_device(struct mtk_rpmsg_rproc_subdev *mtk_subdev, { struct mtk_rpmsg_channel_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -380,7 +380,7 @@ mtk_rpmsg_create_rproc_subdev(struct platform_device *pdev, { struct mtk_rpmsg_rproc_subdev *mtk_subdev; - mtk_subdev = kzalloc(sizeof(*mtk_subdev), GFP_KERNEL); + mtk_subdev = kzalloc_obj(*mtk_subdev); if (!mtk_subdev) return NULL; diff --git a/drivers/rpmsg/qcom_glink_native.c b/drivers/rpmsg/qcom_glink_native.c index 5ea096acc858..9ef17c2e45b0 100644 --- a/drivers/rpmsg/qcom_glink_native.c +++ b/drivers/rpmsg/qcom_glink_native.c @@ -227,7 +227,7 @@ static struct glink_channel *qcom_glink_alloc_channel(struct qcom_glink *glink, { struct glink_channel *channel; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return ERR_PTR(-ENOMEM); @@ -754,7 +754,7 @@ qcom_glink_alloc_intent(struct qcom_glink *glink, int ret; unsigned long flags; - intent = kzalloc(sizeof(*intent), GFP_KERNEL); + intent = kzalloc_obj(*intent); if (!intent) return NULL; @@ -875,7 +875,7 @@ static int qcom_glink_rx_defer(struct qcom_glink *glink, size_t extra) return -ENXIO; } - dcmd = kzalloc(struct_size(dcmd, data, extra), GFP_ATOMIC); + dcmd = kzalloc_flex(*dcmd, data, extra, GFP_ATOMIC); if (!dcmd) return -ENOMEM; @@ -945,7 +945,7 @@ static int qcom_glink_rx_data(struct qcom_glink *glink, size_t avail) if (glink->intentless) { /* Might have an ongoing, fragmented, message to append */ if (!channel->buf) { - intent = kzalloc(sizeof(*intent), GFP_ATOMIC); + intent = kzalloc_obj(*intent, GFP_ATOMIC); if (!intent) return -ENOMEM; @@ -1070,7 +1070,7 @@ static void qcom_glink_handle_intent(struct qcom_glink *glink, count > 0 ? msg->intents[0].iid : 0); for (i = 0; i < count; ++i) { - intent = kzalloc(sizeof(*intent), GFP_ATOMIC); + intent = kzalloc_obj(*intent, GFP_ATOMIC); if (!intent) break; @@ -1669,7 +1669,7 @@ static int qcom_glink_rx_open(struct qcom_glink *glink, unsigned int rcid, complete_all(&channel->open_req); if (create_device) { - rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); + rpdev = kzalloc_obj(*rpdev); if (!rpdev) { ret = -ENOMEM; goto rcid_remove; @@ -1868,7 +1868,7 @@ static int qcom_glink_create_chrdev(struct qcom_glink *glink) struct rpmsg_device *rpdev; struct glink_channel *channel; - rpdev = kzalloc(sizeof(*rpdev), GFP_KERNEL); + rpdev = kzalloc_obj(*rpdev); if (!rpdev) return -ENOMEM; diff --git a/drivers/rpmsg/qcom_glink_smem.c b/drivers/rpmsg/qcom_glink_smem.c index 7a982c60a8dd..62adc4db2317 100644 --- a/drivers/rpmsg/qcom_glink_smem.c +++ b/drivers/rpmsg/qcom_glink_smem.c @@ -230,7 +230,7 @@ struct qcom_glink_smem *qcom_glink_smem_register(struct device *parent, size_t size; int ret; - smem = kzalloc(sizeof(*smem), GFP_KERNEL); + smem = kzalloc_obj(*smem); if (!smem) return ERR_PTR(-ENOMEM); diff --git a/drivers/rpmsg/qcom_smd.c b/drivers/rpmsg/qcom_smd.c index 42594f5ee438..e1eb450f4fea 100644 --- a/drivers/rpmsg/qcom_smd.c +++ b/drivers/rpmsg/qcom_smd.c @@ -922,7 +922,7 @@ static struct rpmsg_endpoint *qcom_smd_create_ept(struct rpmsg_device *rpdev, return NULL; } - qsept = kzalloc(sizeof(*qsept), GFP_KERNEL); + qsept = kzalloc_obj(*qsept); if (!qsept) return NULL; @@ -1077,7 +1077,7 @@ static int qcom_smd_create_device(struct qcom_smd_channel *channel) dev_dbg(&edge->dev, "registering '%s'\n", channel->name); - qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL); + qsdev = kzalloc_obj(*qsdev); if (!qsdev) return -ENOMEM; @@ -1104,7 +1104,7 @@ static int qcom_smd_create_chrdev(struct qcom_smd_edge *edge) { struct qcom_smd_device *qsdev; - qsdev = kzalloc(sizeof(*qsdev), GFP_KERNEL); + qsdev = kzalloc_obj(*qsdev); if (!qsdev) return -ENOMEM; @@ -1132,7 +1132,7 @@ static struct qcom_smd_channel *qcom_smd_create_channel(struct qcom_smd_edge *ed void *info; int ret; - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) return ERR_PTR(-ENOMEM); @@ -1484,7 +1484,7 @@ struct qcom_smd_edge *qcom_smd_register_edge(struct device *parent, if (!qcom_smem_is_available()) return ERR_PTR(-EPROBE_DEFER); - edge = kzalloc(sizeof(*edge), GFP_KERNEL); + edge = kzalloc_obj(*edge); if (!edge) return ERR_PTR(-ENOMEM); diff --git a/drivers/rpmsg/rpmsg_char.c b/drivers/rpmsg/rpmsg_char.c index 96fcdd2d7093..ca9cf8858a5e 100644 --- a/drivers/rpmsg/rpmsg_char.c +++ b/drivers/rpmsg/rpmsg_char.c @@ -410,7 +410,7 @@ static struct rpmsg_eptdev *rpmsg_chrdev_eptdev_alloc(struct rpmsg_device *rpdev struct rpmsg_eptdev *eptdev; struct device *dev; - eptdev = kzalloc(sizeof(*eptdev), GFP_KERNEL); + eptdev = kzalloc_obj(*eptdev); if (!eptdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c index 5d661681a9b6..96964745065b 100644 --- a/drivers/rpmsg/rpmsg_core.c +++ b/drivers/rpmsg/rpmsg_core.c @@ -352,50 +352,38 @@ field##_show(struct device *dev, \ } \ static DEVICE_ATTR_RO(field); -#define rpmsg_string_attr(field, member) \ -static ssize_t \ -field##_store(struct device *dev, struct device_attribute *attr, \ - const char *buf, size_t sz) \ -{ \ - struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ - const char *old; \ - char *new; \ - \ - new = kstrndup(buf, sz, GFP_KERNEL); \ - if (!new) \ - return -ENOMEM; \ - new[strcspn(new, "\n")] = '\0'; \ - \ - device_lock(dev); \ - old = rpdev->member; \ - if (strlen(new)) { \ - rpdev->member = new; \ - } else { \ - kfree(new); \ - rpdev->member = NULL; \ - } \ - device_unlock(dev); \ - \ - kfree(old); \ - \ - return sz; \ -} \ -static ssize_t \ -field##_show(struct device *dev, \ - struct device_attribute *attr, char *buf) \ -{ \ - struct rpmsg_device *rpdev = to_rpmsg_device(dev); \ - \ - return sprintf(buf, "%s\n", rpdev->member); \ -} \ -static DEVICE_ATTR_RW(field) - /* for more info, see Documentation/ABI/testing/sysfs-bus-rpmsg */ rpmsg_show_attr(name, id.name, "%s\n"); rpmsg_show_attr(src, src, "0x%x\n"); rpmsg_show_attr(dst, dst, "0x%x\n"); rpmsg_show_attr(announce, announce ? "true" : "false", "%s\n"); -rpmsg_string_attr(driver_override, driver_override); + +static ssize_t driver_override_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + int ret; + + ret = driver_set_override(dev, &rpdev->driver_override, buf, count); + if (ret) + return ret; + + return count; +} + +static ssize_t driver_override_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct rpmsg_device *rpdev = to_rpmsg_device(dev); + ssize_t len; + + device_lock(dev); + len = sysfs_emit(buf, "%s\n", rpdev->driver_override); + device_unlock(dev); + return len; +} +static DEVICE_ATTR_RW(driver_override); static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/rpmsg/rpmsg_ctrl.c b/drivers/rpmsg/rpmsg_ctrl.c index 28f57945ccd9..5c19188d0294 100644 --- a/drivers/rpmsg/rpmsg_ctrl.c +++ b/drivers/rpmsg/rpmsg_ctrl.c @@ -141,7 +141,7 @@ static int rpmsg_ctrldev_probe(struct rpmsg_device *rpdev) struct device *dev; int ret; - ctrldev = kzalloc(sizeof(*ctrldev), GFP_KERNEL); + ctrldev = kzalloc_obj(*ctrldev); if (!ctrldev) return -ENOMEM; diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index 484890b4a6a7..8d9e2b4dc7c1 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c @@ -41,13 +41,12 @@ * @buf_size: size of one rx or tx buffer * @last_sbuf: index of last tx buffer used * @bufs_dma: dma base addr of the buffers - * @tx_lock: protects svq, sbufs and sleepers, to allow concurrent senders. + * @tx_lock: protects svq and sbufs, to allow concurrent senders. * sending a message might require waking up a dozing remote * processor, which involves sleeping, hence the mutex. * @endpoints: idr of local endpoints, allows fast retrieval * @endpoints_lock: lock of the endpoints set * @sendq: wait queue of sending contexts waiting for a tx buffers - * @sleepers: number of senders that are waiting for a tx buffer * * This structure stores the rpmsg state of a given virtio remote processor * device (there might be several virtio proc devices for each physical @@ -65,7 +64,6 @@ struct virtproc_info { struct idr endpoints; struct mutex endpoints_lock; wait_queue_head_t sendq; - atomic_t sleepers; }; /* The feature bitmap for virtio rpmsg */ @@ -144,6 +142,8 @@ static int virtio_rpmsg_sendto(struct rpmsg_endpoint *ept, void *data, int len, static int virtio_rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len); static int virtio_rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, int len, u32 dst); +static __poll_t virtio_rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, + poll_table *wait); static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept); static struct rpmsg_device *__rpmsg_create_channel(struct virtproc_info *vrp, struct rpmsg_channel_info *chinfo); @@ -154,6 +154,7 @@ static const struct rpmsg_endpoint_ops virtio_endpoint_ops = { .sendto = virtio_rpmsg_sendto, .trysend = virtio_rpmsg_trysend, .trysendto = virtio_rpmsg_trysendto, + .poll = virtio_rpmsg_poll, .get_mtu = virtio_rpmsg_get_mtu, }; @@ -209,7 +210,7 @@ static struct rpmsg_endpoint *__rpmsg_create_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept; struct device *dev = rpdev ? &rpdev->dev : &vrp->vdev->dev; - ept = kzalloc(sizeof(*ept), GFP_KERNEL); + ept = kzalloc_obj(*ept); if (!ept) return NULL; @@ -399,7 +400,7 @@ static struct rpmsg_device *__rpmsg_create_channel(struct virtproc_info *vrp, return NULL; } - vch = kzalloc(sizeof(*vch), GFP_KERNEL); + vch = kzalloc_obj(*vch); if (!vch) return NULL; @@ -436,7 +437,6 @@ static void *get_a_tx_buf(struct virtproc_info *vrp) unsigned int len; void *ret; - /* support multiple concurrent senders */ mutex_lock(&vrp->tx_lock); /* @@ -454,62 +454,6 @@ static void *get_a_tx_buf(struct virtproc_info *vrp) return ret; } -/** - * rpmsg_upref_sleepers() - enable "tx-complete" interrupts, if needed - * @vrp: virtual remote processor state - * - * This function is called before a sender is blocked, waiting for - * a tx buffer to become available. - * - * If we already have blocking senders, this function merely increases - * the "sleepers" reference count, and exits. - * - * Otherwise, if this is the first sender to block, we also enable - * virtio's tx callbacks, so we'd be immediately notified when a tx - * buffer is consumed (we rely on virtio's tx callback in order - * to wake up sleeping senders as soon as a tx buffer is used by the - * remote processor). - */ -static void rpmsg_upref_sleepers(struct virtproc_info *vrp) -{ - /* support multiple concurrent senders */ - mutex_lock(&vrp->tx_lock); - - /* are we the first sleeping context waiting for tx buffers ? */ - if (atomic_inc_return(&vrp->sleepers) == 1) - /* enable "tx-complete" interrupts before dozing off */ - virtqueue_enable_cb(vrp->svq); - - mutex_unlock(&vrp->tx_lock); -} - -/** - * rpmsg_downref_sleepers() - disable "tx-complete" interrupts, if needed - * @vrp: virtual remote processor state - * - * This function is called after a sender, that waited for a tx buffer - * to become available, is unblocked. - * - * If we still have blocking senders, this function merely decreases - * the "sleepers" reference count, and exits. - * - * Otherwise, if there are no more blocking senders, we also disable - * virtio's tx callbacks, to avoid the overhead incurred with handling - * those (now redundant) interrupts. - */ -static void rpmsg_downref_sleepers(struct virtproc_info *vrp) -{ - /* support multiple concurrent senders */ - mutex_lock(&vrp->tx_lock); - - /* are we the last sleeping context waiting for tx buffers ? */ - if (atomic_dec_and_test(&vrp->sleepers)) - /* disable "tx-complete" interrupts */ - virtqueue_disable_cb(vrp->svq); - - mutex_unlock(&vrp->tx_lock); -} - /** * rpmsg_send_offchannel_raw() - send a message across to the remote processor * @rpdev: the rpmsg channel @@ -582,9 +526,6 @@ static int rpmsg_send_offchannel_raw(struct rpmsg_device *rpdev, /* no free buffer ? wait for one (but bail after 15 seconds) */ while (!msg) { - /* enable "tx-complete" interrupts, if not already enabled */ - rpmsg_upref_sleepers(vrp); - /* * sleep until a free buffer is available or 15 secs elapse. * the timeout period is not configurable because there's @@ -595,9 +536,6 @@ static int rpmsg_send_offchannel_raw(struct rpmsg_device *rpdev, (msg = get_a_tx_buf(vrp)), msecs_to_jiffies(15000)); - /* disable "tx-complete" interrupts if we're the last sleeper */ - rpmsg_downref_sleepers(vrp); - /* timeout ? */ if (!err) { dev_err(dev, "timeout waiting for a tx buffer\n"); @@ -676,6 +614,34 @@ static int virtio_rpmsg_trysendto(struct rpmsg_endpoint *ept, void *data, return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); } +static __poll_t virtio_rpmsg_poll(struct rpmsg_endpoint *ept, struct file *filp, + poll_table *wait) +{ + struct rpmsg_device *rpdev = ept->rpdev; + struct virtio_rpmsg_channel *vch = to_virtio_rpmsg_channel(rpdev); + struct virtproc_info *vrp = vch->vrp; + __poll_t mask = 0; + + poll_wait(filp, &vrp->sendq, wait); + + /* support multiple concurrent senders */ + mutex_lock(&vrp->tx_lock); + + /* + * check for a free buffer, either: + * - we haven't used all of the available transmit buffers (half of the + * allocated buffers are used for transmit, hence num_bufs / 2), or, + * - we ask the virtqueue if there's a buffer available + */ + if (vrp->last_sbuf < vrp->num_bufs / 2 || + !virtqueue_enable_cb(vrp->svq)) + mask |= EPOLLOUT; + + mutex_unlock(&vrp->tx_lock); + + return mask; +} + static ssize_t virtio_rpmsg_get_mtu(struct rpmsg_endpoint *ept) { struct rpmsg_device *rpdev = ept->rpdev; @@ -813,7 +779,7 @@ static struct rpmsg_device *rpmsg_virtio_add_ctrl_dev(struct virtio_device *vdev struct rpmsg_device *rpdev_ctrl; int err = 0; - vch = kzalloc(sizeof(*vch), GFP_KERNEL); + vch = kzalloc_obj(*vch); if (!vch) return ERR_PTR(-ENOMEM); @@ -859,7 +825,7 @@ static int rpmsg_probe(struct virtio_device *vdev) size_t total_buf_space; bool notify; - vrp = kzalloc(sizeof(*vrp), GFP_KERNEL); + vrp = kzalloc_obj(*vrp); if (!vrp) return -ENOMEM; @@ -922,9 +888,6 @@ static int rpmsg_probe(struct virtio_device *vdev) WARN_ON(err); /* sanity check; this can't really happen */ } - /* suppress "tx-complete" interrupts */ - virtqueue_disable_cb(vrp->svq); - vdev->priv = vrp; rpdev_ctrl = rpmsg_virtio_add_ctrl_dev(vdev); @@ -935,7 +898,7 @@ static int rpmsg_probe(struct virtio_device *vdev) /* if supported by the remote processor, enable the name service */ if (virtio_has_feature(vdev, VIRTIO_RPMSG_F_NS)) { - vch = kzalloc(sizeof(*vch), GFP_KERNEL); + vch = kzalloc_obj(*vch); if (!vch) { err = -ENOMEM; goto free_ctrldev; diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 7ac18985e438..b46ac73a2124 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -418,6 +418,7 @@ config RTC_DRV_SPACEMIT_P1 config RTC_DRV_NVIDIA_VRS10 tristate "NVIDIA VRS10 RTC device" + depends on ARCH_TEGRA || COMPILE_TEST help If you say yes here you will get support for the battery backed RTC device of NVIDIA VRS (Voltage Regulator Specification). The RTC is connected via diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index b1a2be1f9e3b..01ba04028f1f 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -208,7 +208,7 @@ static struct rtc_device *rtc_allocate_device(void) { struct rtc_device *rtc; - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + rtc = kzalloc_obj(*rtc); if (!rtc) return NULL; @@ -410,7 +410,7 @@ int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc) /* Check to see if there is an ALARM already set in hw */ err = __rtc_read_alarm(rtc, &alrm); - if (!err && !rtc_valid_tm(&alrm.time)) + if (!err) rtc_initialize_alarm(rtc, &alrm); rtc_dev_prepare(rtc); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index b8b298efd9a9..1906f4884a83 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -457,7 +457,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) * are in, we can return -ETIME to signal that the timer has already * expired, which is true in both cases. */ - if ((scheduled - now) <= 1) { + if (!err && (scheduled - now) <= 1) { err = __rtc_read_time(rtc, &tm); if (err) return err; diff --git a/drivers/rtc/rtc-ac100.c b/drivers/rtc/rtc-ac100.c index 33626311fa78..bba7115ff3ad 100644 --- a/drivers/rtc/rtc-ac100.c +++ b/drivers/rtc/rtc-ac100.c @@ -140,42 +140,16 @@ static unsigned long ac100_clkout_recalc_rate(struct clk_hw *hw, AC100_CLKOUT_DIV_WIDTH); } -static long ac100_clkout_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long prate) -{ - unsigned long best_rate = 0, tmp_rate, tmp_prate; - int i; - - if (prate == AC100_RTC_32K_RATE) - return divider_round_rate(hw, rate, &prate, NULL, - AC100_CLKOUT_DIV_WIDTH, - CLK_DIVIDER_POWER_OF_TWO); - - for (i = 0; ac100_clkout_prediv[i].div; i++) { - tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[i].val); - tmp_rate = divider_round_rate(hw, rate, &tmp_prate, NULL, - AC100_CLKOUT_DIV_WIDTH, - CLK_DIVIDER_POWER_OF_TWO); - - if (tmp_rate > rate) - continue; - if (rate - tmp_rate < best_rate - tmp_rate) - best_rate = tmp_rate; - } - - return best_rate; -} - static int ac100_clkout_determine_rate(struct clk_hw *hw, struct clk_rate_request *req) { - struct clk_hw *best_parent; + int i, ret, num_parents = clk_hw_get_num_parents(hw); + struct clk_hw *best_parent = NULL; unsigned long best = 0; - int i, num_parents = clk_hw_get_num_parents(hw); for (i = 0; i < num_parents; i++) { struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i); - unsigned long tmp, prate; + unsigned long prate; /* * The clock has two parents, one is a fixed clock which is @@ -199,13 +173,40 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw, prate = clk_hw_get_rate(parent); - tmp = ac100_clkout_round_rate(hw, req->rate, prate); + if (prate == AC100_RTC_32K_RATE) { + struct clk_rate_request div_req = *req; - if (tmp > req->rate) - continue; - if (req->rate - tmp < req->rate - best) { - best = tmp; - best_parent = parent; + div_req.best_parent_rate = prate; + + ret = divider_determine_rate(hw, &div_req, NULL, + AC100_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_POWER_OF_TWO); + if (ret != 0 || div_req.rate > req->rate) { + continue; + } else if (req->rate - div_req.rate < req->rate - best) { + best = div_req.rate; + best_parent = parent; + } + } else { + int j; + + for (j = 0; ac100_clkout_prediv[j].div; j++) { + struct clk_rate_request div_req = *req; + unsigned long tmp_prate; + + tmp_prate = DIV_ROUND_UP(prate, ac100_clkout_prediv[j].div); + div_req.best_parent_rate = tmp_prate; + + ret = divider_determine_rate(hw, &div_req, NULL, + AC100_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_POWER_OF_TWO); + if (ret != 0 || div_req.rate > req->rate) { + continue; + } else if (req->rate - div_req.rate < req->rate - best) { + best = div_req.rate; + best_parent = parent; + } + } } } @@ -213,7 +214,7 @@ static int ac100_clkout_determine_rate(struct clk_hw *hw, return -EINVAL; req->best_parent_hw = best_parent; - req->best_parent_rate = best; + req->best_parent_rate = clk_hw_get_rate(best_parent); req->rate = best; return 0; diff --git a/drivers/rtc/rtc-ds1390.c b/drivers/rtc/rtc-ds1390.c index f46428ca77cc..f7afd6bdeb4a 100644 --- a/drivers/rtc/rtc-ds1390.c +++ b/drivers/rtc/rtc-ds1390.c @@ -134,7 +134,7 @@ static int ds1390_read_time(struct device *dev, struct rtc_time *dt) chip->txrx_buf[0] = DS1390_REG_SECONDS; /* do the i/o */ - status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 8); + status = spi_write_then_read(spi, chip->txrx_buf, 1, chip->txrx_buf, 7); if (status != 0) return status; diff --git a/drivers/rtc/rtc-loongson.c b/drivers/rtc/rtc-loongson.c index 2ca7ffd5d7a9..066f0644d1c3 100644 --- a/drivers/rtc/rtc-loongson.c +++ b/drivers/rtc/rtc-loongson.c @@ -66,7 +66,8 @@ * According to the LS1C manual, RTC_CTRL and alarm-related registers are not defined. * Accessing the relevant registers will cause the system to hang. */ -#define LS1C_RTC_CTRL_WORKAROUND BIT(0) +#define LOONGSON_RTC_CTRL_WORKAROUND BIT(0) +#define LOONGSON_RTC_ALARM_WORKAROUND BIT(1) struct loongson_rtc_config { u32 pm_offset; /* Offset of PM domain, for RTC alarm wakeup */ @@ -89,7 +90,7 @@ static const struct loongson_rtc_config ls1b_rtc_config = { static const struct loongson_rtc_config ls1c_rtc_config = { .pm_offset = 0, - .flags = LS1C_RTC_CTRL_WORKAROUND, + .flags = LOONGSON_RTC_CTRL_WORKAROUND | LOONGSON_RTC_ALARM_WORKAROUND, }; static const struct loongson_rtc_config generic_rtc_config = { @@ -97,6 +98,11 @@ static const struct loongson_rtc_config generic_rtc_config = { .flags = 0, }; +static const struct loongson_rtc_config ls2k0300_rtc_config = { + .pm_offset = 0x0, + .flags = LOONGSON_RTC_ALARM_WORKAROUND, +}; + static const struct loongson_rtc_config ls2k1000_rtc_config = { .pm_offset = 0x800, .flags = 0, @@ -153,7 +159,7 @@ static int loongson_rtc_set_enabled(struct device *dev) { struct loongson_rtc_priv *priv = dev_get_drvdata(dev); - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) return 0; /* Enable RTC TOY counters and crystal */ @@ -167,7 +173,7 @@ static bool loongson_rtc_get_enabled(struct device *dev) u32 ctrl_data; struct loongson_rtc_priv *priv = dev_get_drvdata(dev); - if (priv->config->flags & LS1C_RTC_CTRL_WORKAROUND) + if (priv->config->flags & LOONGSON_RTC_CTRL_WORKAROUND) return true; ret = regmap_read(priv->regmap, RTC_CTRL_REG, &ctrl_data); @@ -299,9 +305,41 @@ static const struct rtc_class_ops loongson_rtc_ops = { .alarm_irq_enable = loongson_rtc_alarm_irq_enable, }; +static int loongson_rtc_alarm_setting(struct platform_device *pdev, void __iomem *regs) +{ + int ret = 0, alarm_irq; + struct device *dev = &pdev->dev; + struct loongson_rtc_priv *priv = dev_get_drvdata(dev); + + if (priv->config->flags & LOONGSON_RTC_ALARM_WORKAROUND) { + /* Loongson-1C/Loongson-2K0300 RTC does not support alarm */ + clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); + return 0; + } + + /* Get RTC alarm irq */ + alarm_irq = platform_get_irq(pdev, 0); + if (alarm_irq < 0) + return alarm_irq; + + ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, 0, "loongson-alarm", + priv); + if (ret < 0) + return ret; + + priv->pm_base = regs - priv->config->pm_offset; + device_init_wakeup(dev, true); + + if (has_acpi_companion(dev)) + acpi_install_fixed_event_handler(ACPI_EVENT_RTC, + loongson_rtc_handler, priv); + + return ret; +} + static int loongson_rtc_probe(struct platform_device *pdev) { - int ret, alarm_irq; + int ret; void __iomem *regs; struct loongson_rtc_priv *priv; struct device *dev = &pdev->dev; @@ -330,25 +368,9 @@ static int loongson_rtc_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(priv->rtcdev), "devm_rtc_allocate_device failed\n"); - /* Get RTC alarm irq */ - alarm_irq = platform_get_irq(pdev, 0); - if (alarm_irq > 0) { - ret = devm_request_irq(dev, alarm_irq, loongson_rtc_isr, - 0, "loongson-alarm", priv); - if (ret < 0) - return dev_err_probe(dev, ret, "Unable to request irq %d\n", - alarm_irq); - - priv->pm_base = regs - priv->config->pm_offset; - device_init_wakeup(dev, true); - - if (has_acpi_companion(dev)) - acpi_install_fixed_event_handler(ACPI_EVENT_RTC, - loongson_rtc_handler, priv); - } else { - /* Loongson-1C RTC does not support alarm */ - clear_bit(RTC_FEATURE_ALARM, priv->rtcdev->features); - } + ret = loongson_rtc_alarm_setting(pdev, regs); + if (ret) + return ret; /* Loongson RTC does not support UIE */ clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, priv->rtcdev->features); @@ -379,6 +401,7 @@ static const struct of_device_id loongson_rtc_of_match[] = { { .compatible = "loongson,ls1b-rtc", .data = &ls1b_rtc_config }, { .compatible = "loongson,ls1c-rtc", .data = &ls1c_rtc_config }, { .compatible = "loongson,ls7a-rtc", .data = &generic_rtc_config }, + { .compatible = "loongson,ls2k0300-rtc", .data = &ls2k0300_rtc_config }, { .compatible = "loongson,ls2k1000-rtc", .data = &ls2k1000_rtc_config }, { /* sentinel */ } }; diff --git a/drivers/rtc/rtc-max31335.c b/drivers/rtc/rtc-max31335.c index 23b7bf16b4cd..952b455071d6 100644 --- a/drivers/rtc/rtc-max31335.c +++ b/drivers/rtc/rtc-max31335.c @@ -591,7 +591,7 @@ static struct nvmem_config max31335_nvmem_cfg = { .size = MAX31335_RAM_SIZE, }; -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) static int max31335_read_temp(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { @@ -672,7 +672,7 @@ static int max31335_clkout_register(struct device *dev) static int max31335_probe(struct i2c_client *client) { struct max31335_data *max31335; -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) struct device *hwmon; #endif const struct chip_desc *match; @@ -727,7 +727,7 @@ static int max31335_probe(struct i2c_client *client) return dev_err_probe(&client->dev, ret, "cannot register rtc nvmem\n"); -#if IS_REACHABLE(HWMON) +#if IS_REACHABLE(CONFIG_HWMON) if (max31335->chip->temp_reg) { hwmon = devm_hwmon_device_register_with_info(&client->dev, client->name, max31335, &max31335_chip_info, NULL); diff --git a/drivers/rtc/rtc-optee.c b/drivers/rtc/rtc-optee.c index eefde789d194..6c908c0d861a 100644 --- a/drivers/rtc/rtc-optee.c +++ b/drivers/rtc/rtc-optee.c @@ -541,10 +541,7 @@ static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data) { - if (ver->impl_id == TEE_IMPL_ID_OPTEE) - return 1; - else - return 0; + return (ver->impl_id == TEE_IMPL_ID_OPTEE); } static int optee_rtc_probe(struct tee_client_device *rtc_device) diff --git a/drivers/rtc/rtc-pcf8563.c b/drivers/rtc/rtc-pcf8563.c index 4e61011fb7a9..b281e9489df1 100644 --- a/drivers/rtc/rtc-pcf8563.c +++ b/drivers/rtc/rtc-pcf8563.c @@ -424,7 +424,7 @@ static const struct clk_ops pcf8563_clkout_ops = { static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563) { - struct device_node *node = pcf8563->rtc->dev.of_node; + struct device_node *node = pcf8563->rtc->dev.parent->of_node; struct clk_init_data init; struct clk *clk; int ret; diff --git a/drivers/rtc/rtc-pic32.c b/drivers/rtc/rtc-pic32.c index 52c11532bc3a..3c7a38a4ac08 100644 --- a/drivers/rtc/rtc-pic32.c +++ b/drivers/rtc/rtc-pic32.c @@ -15,8 +15,7 @@ #include #include #include - -#include +#include #define PIC32_RTCCON 0x00 #define PIC32_RTCCON_ON BIT(15) diff --git a/drivers/rtc/rtc-s35390a.c b/drivers/rtc/rtc-s35390a.c index 07bd983b5692..a4678d7c6cf6 100644 --- a/drivers/rtc/rtc-s35390a.c +++ b/drivers/rtc/rtc-s35390a.c @@ -18,6 +18,7 @@ #define S35390A_CMD_TIME1 2 #define S35390A_CMD_TIME2 3 #define S35390A_CMD_INT2_REG1 5 +#define S35390A_CMD_FREE_REG 7 #define S35390A_BYTE_YEAR 0 #define S35390A_BYTE_MONTH 1 @@ -416,6 +417,23 @@ static const struct rtc_class_ops s35390a_rtc_ops = { .ioctl = s35390a_rtc_ioctl, }; +static int s35390a_nvmem_read(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct s35390a *s35390a = priv; + + /* The offset is ignored because the NVMEM region is only 1 byte */ + return s35390a_get_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes); +} + +static int s35390a_nvmem_write(void *priv, unsigned int offset, void *val, + size_t bytes) +{ + struct s35390a *s35390a = priv; + + return s35390a_set_reg(s35390a, S35390A_CMD_FREE_REG, val, bytes); +} + static int s35390a_probe(struct i2c_client *client) { int err, err_read; @@ -424,6 +442,15 @@ static int s35390a_probe(struct i2c_client *client) struct rtc_device *rtc; u8 buf, status1; struct device *dev = &client->dev; + struct nvmem_config nvmem_cfg = { + .name = "s35390a_nvram", + .type = NVMEM_TYPE_BATTERY_BACKED, + .word_size = 1, + .stride = 1, + .size = 1, + .reg_read = s35390a_nvmem_read, + .reg_write = s35390a_nvmem_write, + }; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) return -ENODEV; @@ -490,6 +517,11 @@ static int s35390a_probe(struct i2c_client *client) if (status1 & S35390A_FLAG_INT2) rtc_update_irq(rtc, 1, RTC_AF); + nvmem_cfg.priv = s35390a; + err = devm_rtc_nvmem_register(rtc, &nvmem_cfg); + if (err) + return err; + return devm_rtc_register_device(rtc); } diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index e5e6013d080e..7fc60880e409 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -233,12 +233,12 @@ static void __init sun6i_rtc_clk_init(struct device_node *node, const char *parents[2]; u32 reg; - rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + rtc = kzalloc_obj(*rtc); if (!rtc) return; rtc->data = data; - clk_data = kzalloc(struct_size(clk_data, hws, 3), GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, 3); if (!clk_data) { kfree(rtc); return; diff --git a/drivers/rtc/rtc-zynqmp.c b/drivers/rtc/rtc-zynqmp.c index 3baa2b481d9f..2ae54804b87a 100644 --- a/drivers/rtc/rtc-zynqmp.c +++ b/drivers/rtc/rtc-zynqmp.c @@ -43,9 +43,7 @@ #define RTC_MSEC 1000 #define RTC_FR_MASK 0xF0000 #define RTC_FR_MAX_TICKS 16 -#define RTC_PPB 1000000000LL -#define RTC_MIN_OFFSET -32768000 -#define RTC_MAX_OFFSET 32767000 +#define RTC_PPB 1000000000 struct xlnx_rtc_dev { struct rtc_device *rtc; @@ -178,21 +176,28 @@ static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev) static int xlnx_rtc_read_offset(struct device *dev, long *offset) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); - unsigned long long rtc_ppb = RTC_PPB; - unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); - unsigned int calibval; + unsigned int calibval, fract_data, fract_part; + int freq = xrtcdev->freq; + int max_tick, tick_mult; long offset_val; + /* Tick to offset multiplier */ + tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq); + calibval = readl(xrtcdev->reg_base + RTC_CALIB_RD); /* Offset with seconds ticks */ - offset_val = calibval & RTC_TICK_MASK; - offset_val = offset_val - RTC_CALIB_DEF; - offset_val = offset_val * tick_mult; + max_tick = calibval & RTC_TICK_MASK; + offset_val = max_tick - freq; + /* Convert to ppb */ + offset_val *= tick_mult; /* Offset with fractional ticks */ - if (calibval & RTC_FR_EN) - offset_val += ((calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT) - * (tick_mult / RTC_FR_MAX_TICKS); + if (calibval & RTC_FR_EN) { + fract_data = (calibval & RTC_FR_MASK) >> RTC_FR_DATSHIFT; + fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS); + offset_val += (fract_part * fract_data); + } + *offset = offset_val; return 0; @@ -201,44 +206,38 @@ static int xlnx_rtc_read_offset(struct device *dev, long *offset) static int xlnx_rtc_set_offset(struct device *dev, long offset) { struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev); - unsigned long long rtc_ppb = RTC_PPB; - unsigned int tick_mult = do_div(rtc_ppb, xrtcdev->freq); - unsigned char fract_tick = 0; + int max_tick, tick_mult, fract_offset, fract_part; + int freq = xrtcdev->freq; unsigned int calibval; - short int max_tick; - int fract_offset; + int fract_data = 0; - if (offset < RTC_MIN_OFFSET || offset > RTC_MAX_OFFSET) - return -ERANGE; + /* Tick to offset multiplier */ + tick_mult = DIV_ROUND_CLOSEST(RTC_PPB, freq); /* Number ticks for given offset */ max_tick = div_s64_rem(offset, tick_mult, &fract_offset); + if (freq + max_tick > RTC_TICK_MASK || (freq + max_tick < 1)) + return -ERANGE; + /* Number fractional ticks for given offset */ if (fract_offset) { - if (fract_offset < 0) { - fract_offset = fract_offset + tick_mult; + fract_part = DIV_ROUND_UP(tick_mult, RTC_FR_MAX_TICKS); + fract_data = fract_offset / fract_part; + /* Subtract one from max_tick while adding fract_offset */ + if (fract_offset < 0 && fract_data) { max_tick--; - } - if (fract_offset > (tick_mult / RTC_FR_MAX_TICKS)) { - for (fract_tick = 1; fract_tick < 16; fract_tick++) { - if (fract_offset <= - (fract_tick * - (tick_mult / RTC_FR_MAX_TICKS))) - break; - } + fract_data += RTC_FR_MAX_TICKS; } } /* Zynqmp RTC uses second and fractional tick * counters for compensation */ - calibval = max_tick + RTC_CALIB_DEF; + calibval = max_tick + freq; - if (fract_tick) - calibval |= RTC_FR_EN; - - calibval |= (fract_tick << RTC_FR_DATSHIFT); + if (fract_data) + calibval |= (RTC_FR_EN | (fract_data << RTC_FR_DATSHIFT)); writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR)); @@ -345,7 +344,15 @@ static int xlnx_rtc_probe(struct platform_device *pdev) &xrtcdev->freq); if (ret) xrtcdev->freq = RTC_CALIB_DEF; + } else { + xrtcdev->freq--; } + + if (xrtcdev->freq > RTC_TICK_MASK) { + dev_err(&pdev->dev, "Invalid RTC calibration value\n"); + return -EINVAL; + } + ret = readl(xrtcdev->reg_base + RTC_CALIB_RD); if (!ret) writel(xrtcdev->freq, (xrtcdev->reg_base + RTC_CALIB_WR)); diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 35031357ac4d..3181c06d91ce 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -86,7 +86,7 @@ struct dasd_device *dasd_alloc_device(void) { struct dasd_device *device; - device = kzalloc(sizeof(struct dasd_device), GFP_ATOMIC); + device = kzalloc_obj(struct dasd_device, GFP_ATOMIC); if (!device) return ERR_PTR(-ENOMEM); @@ -150,7 +150,7 @@ struct dasd_block *dasd_alloc_block(void) { struct dasd_block *block; - block = kzalloc(sizeof(*block), GFP_ATOMIC); + block = kzalloc_obj(*block, GFP_ATOMIC); if (!block) return ERR_PTR(-ENOMEM); /* open_count = 0 means device online but not in use */ @@ -868,7 +868,7 @@ int dasd_profile_on(struct dasd_profile *profile) { struct dasd_profile_info *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; spin_lock_bh(&profile->lock); @@ -3180,7 +3180,7 @@ enum blk_eh_timer_return dasd_times_out(struct request *req) static int dasd_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, unsigned int idx) { - struct dasd_queue *dq = kzalloc(sizeof(*dq), GFP_KERNEL); + struct dasd_queue *dq = kzalloc_obj(*dq); if (!dq) return -ENOMEM; diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index f7e768d8ca76..8d6c16d35c22 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c @@ -98,7 +98,7 @@ static struct alias_server *_allocate_server(struct dasd_uid *uid) { struct alias_server *server; - server = kzalloc(sizeof(*server), GFP_KERNEL); + server = kzalloc_obj(*server); if (!server) return ERR_PTR(-ENOMEM); memcpy(server->uid.vendor, uid->vendor, sizeof(uid->vendor)); @@ -117,17 +117,16 @@ static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid) { struct alias_lcu *lcu; - lcu = kzalloc(sizeof(*lcu), GFP_KERNEL); + lcu = kzalloc_obj(*lcu); if (!lcu) return ERR_PTR(-ENOMEM); - lcu->uac = kzalloc(sizeof(*(lcu->uac)), GFP_KERNEL | GFP_DMA); + lcu->uac = kzalloc_obj(*(lcu->uac), GFP_KERNEL | GFP_DMA); if (!lcu->uac) goto out_err1; - lcu->rsu_cqr = kzalloc(sizeof(*lcu->rsu_cqr), GFP_KERNEL | GFP_DMA); + lcu->rsu_cqr = kzalloc_obj(*lcu->rsu_cqr, GFP_KERNEL | GFP_DMA); if (!lcu->rsu_cqr) goto out_err2; - lcu->rsu_cqr->cpaddr = kzalloc(sizeof(struct ccw1), - GFP_KERNEL | GFP_DMA); + lcu->rsu_cqr->cpaddr = kzalloc_obj(struct ccw1, GFP_KERNEL | GFP_DMA); if (!lcu->rsu_cqr->cpaddr) goto out_err3; lcu->rsu_cqr->data = kzalloc(16, GFP_KERNEL | GFP_DMA); @@ -323,7 +322,7 @@ static int _add_device_to_lcu(struct alias_lcu *lcu, } group = _find_group(lcu, &uid); if (!group) { - group = kzalloc(sizeof(*group), GFP_ATOMIC); + group = kzalloc_obj(*group, GFP_ATOMIC); if (!group) return -ENOMEM; memcpy(group->uid.vendor, uid.vendor, sizeof(uid.vendor)); diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 73972900fc55..381d616ad433 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c @@ -412,7 +412,7 @@ dasd_add_busid(const char *bus_id, int features) struct dasd_devmap *devmap, *new, *tmp; int hash; - new = kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); + new = kzalloc_obj(struct dasd_devmap); if (!new) return ERR_PTR(-ENOMEM); spin_lock(&dasd_devmap_lock); @@ -605,7 +605,7 @@ static int dasd_devmap_get_pprc_status(struct dasd_device *device, dev_warn(&device->cdev->dev, "Unable to query copy relation status\n"); return -EOPNOTSUPP; } - temp = kzalloc(sizeof(*temp), GFP_KERNEL); + temp = kzalloc_obj(*temp); if (!temp) return -ENOMEM; @@ -2274,7 +2274,7 @@ static ssize_t dasd_copy_pair_store(struct device *dev, } else if (sec_devmap->copy) { copy = sec_devmap->copy; } else { - copy = kzalloc(sizeof(*copy), GFP_KERNEL); + copy = kzalloc_obj(*copy); if (!copy) return -ENOMEM; } diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 56f1af8a7ddd..af68c2ee659d 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -325,7 +325,7 @@ dasd_diag_check_device(struct dasd_device *device) int rc; if (private == NULL) { - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (private == NULL) { DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Allocating memory for private DASD data " @@ -395,7 +395,7 @@ dasd_diag_check_device(struct dasd_device *device) rc = -ENOMEM; goto out; } - bio = kzalloc(sizeof(*bio), GFP_KERNEL); + bio = kzalloc_obj(*bio); if (bio == NULL) { DBF_DEV_EVENT(DBF_WARNING, device, "%s", "No memory to allocate initialization bio"); diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index b08e900687f3..14e58c336baa 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -1468,7 +1468,7 @@ static int dasd_eckd_pe_handler(struct dasd_device *device, { struct pe_handler_work_data *data; - data = kzalloc(sizeof(*data), GFP_ATOMIC | GFP_DMA); + data = kzalloc_obj(*data, GFP_ATOMIC | GFP_DMA); if (!data) { if (mutex_trylock(&dasd_pe_handler_mutex)) { data = pe_handler_worker; @@ -1720,7 +1720,7 @@ static int dasd_eckd_ext_pool_exhaust(struct dasd_device *device, { struct ext_pool_exhaust_work_data *data; - data = kzalloc(sizeof(*data), GFP_ATOMIC); + data = kzalloc_obj(*data, GFP_ATOMIC); if (!data) return -ENOMEM; INIT_WORK(&data->worker, dasd_eckd_ext_pool_exhaust_work); @@ -2070,7 +2070,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) "The DASD is not operating in multipath mode\n"); } if (!private) { - private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); + private = kzalloc_obj(*private, GFP_KERNEL | GFP_DMA); if (!private) { dev_warn(&device->cdev->dev, "Allocating memory for private DASD data " @@ -3729,7 +3729,7 @@ static int dasd_in_copy_relation(struct dasd_device *device) if (!dasd_eckd_pprc_enabled(device)) return 0; - temp = kzalloc(sizeof(*temp), GFP_KERNEL); + temp = kzalloc_obj(*temp); if (!temp) return -ENOMEM; @@ -5951,7 +5951,7 @@ static int dasd_eckd_query_host_access(struct dasd_device *device, "Could not allocate read message buffer request"); return PTR_ERR(cqr); } - host_access = kzalloc(sizeof(*host_access), GFP_KERNEL | GFP_DMA); + host_access = kzalloc_obj(*host_access, GFP_KERNEL | GFP_DMA); if (!host_access) { dasd_sfree_request(cqr, device); DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", @@ -6017,7 +6017,7 @@ static int dasd_eckd_host_access_count(struct dasd_device *device) int count = 0; int rc, i; - access = kzalloc(sizeof(*access), GFP_NOIO); + access = kzalloc_obj(*access, GFP_NOIO); if (!access) { DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not allocate access buffer"); @@ -6053,7 +6053,7 @@ static int dasd_hosts_print(struct dasd_device *device, struct seq_file *m) char sysplex[9] = ""; int rc, i; - access = kzalloc(sizeof(*access), GFP_NOIO); + access = kzalloc_obj(*access, GFP_NOIO); if (!access) { DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not allocate access buffer"); @@ -6135,6 +6135,7 @@ static void copy_pair_set_active(struct dasd_copy_relation *copy, char *new_busi static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid, char *sec_busid) { + struct dasd_eckd_private *prim_priv, *sec_priv; struct dasd_device *primary, *secondary; struct dasd_copy_relation *copy; struct dasd_block *block; @@ -6155,6 +6156,9 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid if (!secondary) return DASD_COPYPAIRSWAP_SECONDARY; + prim_priv = primary->private; + sec_priv = secondary->private; + /* * usually the device should be quiesced for swap * for paranoia stop device and requeue requests again @@ -6182,6 +6186,18 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid dev_name(&secondary->cdev->dev), rc); } + if (primary->stopped & DASD_STOPPED_QUIESCE) { + dasd_device_set_stop_bits(secondary, DASD_STOPPED_QUIESCE); + dasd_device_remove_stop_bits(primary, DASD_STOPPED_QUIESCE); + } + + /* + * The secondary device never got through format detection, but since it + * is a copy of the primary device, the format is exactly the same; + * therefore, the detected layout can simply be copied. + */ + sec_priv->uses_cdl = prim_priv->uses_cdl; + /* re-enable device */ dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC); dasd_device_remove_stop_bits(secondary, DASD_STOPPED_PPRC); @@ -6721,7 +6737,7 @@ static void dasd_eckd_check_attention_work(struct work_struct *work) data = container_of(work, struct check_attention_work_data, worker); device = data->device; - messages = kzalloc(sizeof(*messages), GFP_KERNEL); + messages = kzalloc_obj(*messages); if (!messages) { DBF_DEV_EVENT(DBF_WARNING, device, "%s", "Could not allocate attention message buffer"); @@ -6748,7 +6764,7 @@ static int dasd_eckd_check_attention(struct dasd_device *device, __u8 lpum) { struct check_attention_work_data *data; - data = kzalloc(sizeof(*data), GFP_ATOMIC); + data = kzalloc_obj(*data, GFP_ATOMIC); if (!data) return -ENOMEM; INIT_WORK(&data->worker, dasd_eckd_check_attention_work); @@ -6912,18 +6928,17 @@ dasd_eckd_init(void) int ret; ASCEBC(dasd_eckd_discipline.ebcname, 4); - dasd_reserve_req = kmalloc(sizeof(*dasd_reserve_req), - GFP_KERNEL | GFP_DMA); + dasd_reserve_req = kmalloc_obj(*dasd_reserve_req, GFP_KERNEL | GFP_DMA); if (!dasd_reserve_req) return -ENOMEM; - dasd_vol_info_req = kmalloc(sizeof(*dasd_vol_info_req), - GFP_KERNEL | GFP_DMA); + dasd_vol_info_req = kmalloc_obj(*dasd_vol_info_req, + GFP_KERNEL | GFP_DMA); if (!dasd_vol_info_req) { kfree(dasd_reserve_req); return -ENOMEM; } - pe_handler_worker = kmalloc(sizeof(*pe_handler_worker), - GFP_KERNEL | GFP_DMA); + pe_handler_worker = kmalloc_obj(*pe_handler_worker, + GFP_KERNEL | GFP_DMA); if (!pe_handler_worker) { kfree(dasd_reserve_req); kfree(dasd_vol_info_req); diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c index b177b7952f2e..78d66e2711cd 100644 --- a/drivers/s390/block/dasd_eer.c +++ b/drivers/s390/block/dasd_eer.c @@ -544,7 +544,7 @@ static int dasd_eer_open(struct inode *inp, struct file *filp) struct eerbuffer *eerb; unsigned long flags; - eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); + eerb = kzalloc_obj(struct eerbuffer); if (!eerb) return -ENOMEM; eerb->buffer_page_count = eer_pages; @@ -689,7 +689,7 @@ int __init dasd_eer_init(void) { int rc; - dasd_eer_dev = kzalloc(sizeof(*dasd_eer_dev), GFP_KERNEL); + dasd_eer_dev = kzalloc_obj(*dasd_eer_dev); if (!dasd_eer_dev) return -ENOMEM; diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c index c2a87201c153..029acb83ecab 100644 --- a/drivers/s390/block/dasd_fba.c +++ b/drivers/s390/block/dasd_fba.c @@ -119,7 +119,7 @@ dasd_fba_check_characteristics(struct dasd_device *device) int readonly, rc; if (!private) { - private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); + private = kzalloc_obj(*private, GFP_KERNEL | GFP_DMA); if (!private) { dev_warn(&device->cdev->dev, "Allocating memory for private DASD " diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index f883990be626..c85ee42732a3 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c @@ -442,7 +442,7 @@ static int dasd_ioctl_read_profile(struct dasd_block *block, void __user *argp) struct dasd_profile_info_t *data; int rc = 0; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; @@ -560,7 +560,7 @@ static int dasd_ioctl_information(struct dasd_block *block, void __user *argp, struct dasd_information2_t *dasd_info; int error; - dasd_info = kzalloc(sizeof(*dasd_info), GFP_KERNEL); + dasd_info = kzalloc_obj(*dasd_info); if (!dasd_info) return -ENOMEM; diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 38e1df8f8a82..e5a02c2990d0 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -240,9 +240,7 @@ dcssblk_is_continuous(struct dcssblk_dev_info *dev_info) if (dev_info->num_of_segments <= 1) return 0; - sort_list = kcalloc(dev_info->num_of_segments, - sizeof(struct segment_info), - GFP_KERNEL); + sort_list = kzalloc_objs(struct segment_info, dev_info->num_of_segments); if (sort_list == NULL) return -ENOMEM; i = 0; @@ -310,7 +308,7 @@ dcssblk_load_segment(char *name, struct segment_info **seg_info) return -EEXIST; /* get a struct segment_info */ - *seg_info = kzalloc(sizeof(struct segment_info), GFP_KERNEL); + *seg_info = kzalloc_obj(struct segment_info); if (*seg_info == NULL) return -ENOMEM; @@ -606,8 +604,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char * get a struct dcssblk_dev_info */ if (num_of_segments == 0) { - dev_info = kzalloc(sizeof(struct dcssblk_dev_info), - GFP_KERNEL); + dev_info = kzalloc_obj(struct dcssblk_dev_info); if (dev_info == NULL) { rc = -ENOMEM; goto out; diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 04e84f45dcc9..fa223949eac0 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -77,8 +77,7 @@ static int __scm_alloc_rq(void) if (!scmrq->aob) goto free; - scmrq->request = kcalloc(nr_requests_per_io, sizeof(scmrq->request[0]), - GFP_KERNEL); + scmrq->request = kzalloc_objs(scmrq->request[0], nr_requests_per_io); if (!scmrq->request) goto free; @@ -331,7 +330,7 @@ static blk_status_t scm_blk_request(struct blk_mq_hw_ctx *hctx, static int scm_blk_init_hctx(struct blk_mq_hw_ctx *hctx, void *data, unsigned int idx) { - struct scm_queue *qd = kzalloc(sizeof(*qd), GFP_KERNEL); + struct scm_queue *qd = kzalloc_obj(*qd); if (!qd) return -ENOMEM; diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index 6cffbbe83f89..095d06eeae7c 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -43,7 +43,7 @@ static int scm_probe(struct scm_device *scmdev) if (scmdev->attrs.oper_state != OP_STATE_GOOD) return -EINVAL; - bdev = kzalloc(sizeof(*bdev), GFP_KERNEL); + bdev = kzalloc_obj(*bdev); if (!bdev) return -ENOMEM; diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 56e43d43c713..46265f4fbfd8 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -670,7 +670,7 @@ static struct raw3215_info *raw3215_alloc_info(void) { struct raw3215_info *info; - info = kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA); + info = kzalloc_obj(struct raw3215_info, GFP_KERNEL | GFP_DMA); if (!info) return NULL; @@ -916,7 +916,7 @@ static int __init con3215_init(void) /* allocate 3215 request structures */ raw3215_freelist = NULL; for (i = 0; i < NR_3215_REQ; i++) { - req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); + req = kzalloc_obj(struct raw3215_req, GFP_KERNEL | GFP_DMA); if (!req) return -ENOMEM; req->next = raw3215_freelist; diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 4a7c084e68a6..644d3679748d 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c @@ -829,7 +829,7 @@ static struct tty3270 *tty3270_alloc_view(void) { struct tty3270 *tp; - tp = kzalloc(sizeof(*tp), GFP_KERNEL); + tp = kzalloc_obj(*tp); if (!tp) goto out_err; @@ -895,11 +895,11 @@ static struct tty3270_line *tty3270_alloc_screen(struct tty3270 *tp, unsigned in int allocated, lines; allocated = __roundup_pow_of_two(rows) * TTY3270_SCREEN_PAGES; - screen = kcalloc(allocated, sizeof(struct tty3270_line), GFP_KERNEL); + screen = kzalloc_objs(struct tty3270_line, allocated); if (!screen) goto out_err; for (lines = 0; lines < allocated; lines++) { - screen[lines].cells = kcalloc(cols, sizeof(struct tty3270_cell), GFP_KERNEL); + screen[lines].cells = kzalloc_objs(struct tty3270_cell, cols); if (!screen[lines].cells) goto out_screen; } diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 73555dbe30d0..f8e2cc17ac53 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c @@ -367,7 +367,7 @@ static struct fs3270 *fs3270_alloc_view(void) { struct fs3270 *fp; - fp = kzalloc(sizeof(*fp), GFP_KERNEL); + fp = kzalloc_obj(*fp); if (!fp) return ERR_PTR(-ENOMEM); fp->init = raw3270_request_alloc(0); diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index a45f07a2cc8f..ecd9ace2b3aa 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c @@ -78,7 +78,7 @@ kbd_alloc(void) { struct kbd_data *kbd; int i; - kbd = kzalloc(sizeof(struct kbd_data), GFP_KERNEL); + kbd = kzalloc_obj(struct kbd_data); if (!kbd) goto out; kbd->key_maps = kzalloc(sizeof(ebc_key_maps), GFP_KERNEL); @@ -105,7 +105,7 @@ kbd_alloc(void) { } } kbd->fn_handler = - kcalloc(NR_FN_HANDLER, sizeof(fn_handler_fn *), GFP_KERNEL); + kzalloc_objs(fn_handler_fn *, NR_FN_HANDLER); if (!kbd->fn_handler) goto out_func; kbd->accent_table = kmemdup(ebc_accent_table, diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 3d84f84b4cbd..52bc0c95bfbf 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c @@ -181,12 +181,11 @@ static struct mon_private *mon_alloc_mem(void) int i; struct mon_private *monpriv; - monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); + monpriv = kzalloc_obj(struct mon_private); if (!monpriv) return NULL; for (i = 0; i < MON_MSGLIM; i++) { - monpriv->msg_array[i] = kzalloc(sizeof(struct mon_msg), - GFP_KERNEL); + monpriv->msg_array[i] = kzalloc_obj(struct mon_msg); if (!monpriv->msg_array[i]) { mon_free_mem(monpriv); return NULL; diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index cf2e51061422..eaeb4a6384d1 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c @@ -58,8 +58,8 @@ static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn) struct appldata_product_id *id; int rc; - id = kmalloc(sizeof(*id), GFP_KERNEL); - parm_list = kmalloc(sizeof(*parm_list), GFP_KERNEL); + id = kmalloc_obj(*id); + parm_list = kmalloc_obj(*parm_list); rc = -ENOMEM; if (!id || !parm_list) goto out; @@ -126,7 +126,7 @@ static int monwrite_new_hdr(struct mon_private *monpriv) } else if (monhdr->mon_function != MONWRITE_STOP_INTERVAL) { if (mon_buf_count >= mon_max_bufs) return -ENOSPC; - monbuf = kzalloc(sizeof(struct mon_buf), GFP_KERNEL); + monbuf = kzalloc_obj(struct mon_buf); if (!monbuf) return -ENOMEM; monbuf->data = kzalloc(monhdr->datalen, @@ -188,7 +188,7 @@ static int monwrite_open(struct inode *inode, struct file *filp) { struct mon_private *monpriv; - monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); + monpriv = kzalloc_obj(struct mon_private); if (!monpriv) return -ENOMEM; INIT_LIST_HEAD(&monpriv->list); diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 55850b5a7f51..aa9c4d81225c 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -146,7 +146,7 @@ struct raw3270_request *raw3270_request_alloc(size_t size) struct raw3270_request *rq; /* Allocate request structure */ - rq = kzalloc(sizeof(*rq), GFP_KERNEL | GFP_DMA); + rq = kzalloc_obj(*rq, GFP_KERNEL | GFP_DMA); if (!rq) return ERR_PTR(-ENOMEM); @@ -813,7 +813,7 @@ struct raw3270 __init *raw3270_setup_console(void) if (IS_ERR(cdev)) return ERR_CAST(cdev); - rp = kzalloc(sizeof(*rp), GFP_KERNEL | GFP_DMA); + rp = kzalloc_obj(*rp, GFP_KERNEL | GFP_DMA); ascebc = kzalloc(256, GFP_KERNEL); rc = raw3270_setup_device(cdev, rp, ascebc); if (rc) @@ -858,7 +858,7 @@ static struct raw3270 *raw3270_create_device(struct ccw_device *cdev) char *ascebc; int rc; - rp = kzalloc(sizeof(*rp), GFP_KERNEL | GFP_DMA); + rp = kzalloc_obj(*rp, GFP_KERNEL | GFP_DMA); if (!rp) return ERR_PTR(-ENOMEM); ascebc = kmalloc(256, GFP_KERNEL); diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index be4730936f5c..1dc93d945be6 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -66,7 +66,7 @@ int sclp_sync_request_timeout(sclp_cmdw_t cmd, void *sccb, int timeout) struct sclp_req *request; int rc; - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) return -ENOMEM; if (timeout) @@ -134,7 +134,7 @@ static int do_core_configure(sclp_cmdw_t cmd) * Use kmalloc to have a minimum alignment of 8 bytes and ensure sccb * is not going to cross a page boundary. */ - sccb = kzalloc(sizeof(*sccb), GFP_KERNEL | GFP_DMA); + sccb = kzalloc_obj(*sccb, GFP_KERNEL | GFP_DMA); if (!sccb) return -ENOMEM; sccb->header.length = sizeof(*sccb); diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index 8e1636bcf8b5..b80f73fa1e01 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -81,7 +81,7 @@ static struct sclp_req *cpi_prepare_req(void) struct cpi_sccb *sccb; struct cpi_evbuf *evb; - req = kzalloc(sizeof(struct sclp_req), GFP_KERNEL); + req = kzalloc_obj(struct sclp_req); if (!req) return ERR_PTR(-ENOMEM); sccb = (struct cpi_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); diff --git a/drivers/s390/char/sclp_ftp.c b/drivers/s390/char/sclp_ftp.c index 2a1c4b2cafc8..853492d53953 100644 --- a/drivers/s390/char/sclp_ftp.c +++ b/drivers/s390/char/sclp_ftp.c @@ -92,7 +92,7 @@ static int sclp_ftp_et7(const struct hmcdrv_ftp_cmdspec *ftp) ssize_t len; int rc; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); sccb = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (!req || !sccb) { rc = -ENOMEM; diff --git a/drivers/s390/char/sclp_mem.c b/drivers/s390/char/sclp_mem.c index 27f0d2f12a8b..78c054e26d17 100644 --- a/drivers/s390/char/sclp_mem.c +++ b/drivers/s390/char/sclp_mem.c @@ -431,7 +431,7 @@ static int __init sclp_init_mem(void) max_sclp_mems = roundup(sclp.rnmax * sclp.rzm, block_size) / block_size; /* Allocate memory for all blocks ahead of time. */ - sclp_mems = kcalloc(max_sclp_mems, sizeof(struct sclp_mem), GFP_KERNEL); + sclp_mems = kzalloc_objs(struct sclp_mem, max_sclp_mems); if (!sclp_mems) return -ENOMEM; kset = kset_create_and_add("memory", NULL, firmware_kobj); @@ -453,7 +453,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) struct list_head *prev; u16 last_rn; - new_incr = kzalloc(sizeof(*new_incr), GFP_KERNEL); + new_incr = kzalloc_obj(*new_incr); if (!new_incr) return; new_incr->rn = rn; diff --git a/drivers/s390/char/sclp_sd.c b/drivers/s390/char/sclp_sd.c index e4a90a14028a..c62b2eacdc13 100644 --- a/drivers/s390/char/sclp_sd.c +++ b/drivers/s390/char/sclp_sd.c @@ -518,7 +518,7 @@ static __init struct sclp_sd_file *sclp_sd_file_create(const char *name, u8 di) struct sclp_sd_file *sd_file; int rc; - sd_file = kzalloc(sizeof(*sd_file), GFP_KERNEL); + sd_file = kzalloc_obj(*sd_file); if (!sd_file) return NULL; sd_file->di = di; diff --git a/drivers/s390/char/tape_3490.c b/drivers/s390/char/tape_3490.c index c4ea32af1b65..ac70055fd8ba 100644 --- a/drivers/s390/char/tape_3490.c +++ b/drivers/s390/char/tape_3490.c @@ -140,7 +140,7 @@ tape_3490_schedule_work(struct tape_device *device, enum tape_op op) { struct tape_3490_work *p; - if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL) + if ((p = kzalloc_obj(*p, GFP_ATOMIC)) == NULL) return -ENOMEM; INIT_WORK(&p->work, tape_3490_work_handler); @@ -784,7 +784,7 @@ tape_3490_online(struct ccw_device *cdev) static struct ccw_driver tape_3490_driver = { .driver = { - .name = "tape_3490", + .name = "tape_34xx", .owner = THIS_MODULE, }, .ids = tape_3490_ids, diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index 1ae9ad219c08..b69430220a81 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c @@ -45,7 +45,7 @@ struct tape_class_device *register_tape_dev( int rc; char * s; - tcd = kzalloc(sizeof(struct tape_class_device), GFP_KERNEL); + tcd = kzalloc_obj(struct tape_class_device); if (!tcd) return ERR_PTR(-ENOMEM); diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index a62b650ea3c2..bd8e3deb1199 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c @@ -249,7 +249,7 @@ tape_med_state_work(struct tape_device *device, enum tape_medium_state state) { struct tape_med_state_work_data *p; - p = kzalloc(sizeof(*p), GFP_ATOMIC); + p = kzalloc_obj(*p, GFP_ATOMIC); if (p) { INIT_WORK(&p->work, tape_med_state_work_handler); p->device = tape_get_device(device); @@ -477,7 +477,7 @@ tape_alloc_device(void) { struct tape_device *device; - device = kzalloc(sizeof(struct tape_device), GFP_KERNEL); + device = kzalloc_obj(struct tape_device); if (device == NULL) { DBF_EXCEPTION(2, "ti:no mem\n"); return ERR_PTR(-ENOMEM); @@ -678,15 +678,15 @@ tape_alloc_request(int cplength, int datasize) DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize); - request = kzalloc(sizeof(struct tape_request), GFP_KERNEL); + request = kzalloc_obj(struct tape_request); if (request == NULL) { DBF_EXCEPTION(1, "cqra nomem\n"); return ERR_PTR(-ENOMEM); } /* allocate channel program */ if (cplength > 0) { - request->cpaddr = kcalloc(cplength, sizeof(struct ccw1), - GFP_ATOMIC | GFP_DMA); + request->cpaddr = kzalloc_objs(struct ccw1, cplength, + GFP_ATOMIC | GFP_DMA); if (request->cpaddr == NULL) { DBF_EXCEPTION(1, "cqra nomem\n"); kfree(request); diff --git a/drivers/s390/char/uvdevice.c b/drivers/s390/char/uvdevice.c index 2b83fb6dc1d7..e6a264c996ce 100644 --- a/drivers/s390/char/uvdevice.c +++ b/drivers/s390/char/uvdevice.c @@ -196,7 +196,7 @@ static int uvio_attestation(struct uvio_ioctl_cb *uv_ioctl) goto out; ret = -ENOMEM; - uvio_attest = kzalloc(sizeof(*uvio_attest), GFP_KERNEL); + uvio_attest = kzalloc_obj(*uvio_attest); if (!uvio_attest) goto out; @@ -216,7 +216,7 @@ static int uvio_attestation(struct uvio_ioctl_cb *uv_ioctl) goto out; } - uvcb_attest = kzalloc(sizeof(*uvcb_attest), GFP_KERNEL); + uvcb_attest = kzalloc_obj(*uvcb_attest); if (!uvcb_attest) goto out; diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index bde6c9e59166..b277f9d0c321 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c @@ -104,7 +104,7 @@ static int vmcp_open(struct inode *inode, struct file *file) if (!capable(CAP_SYS_ADMIN)) return -EPERM; - session = kmalloc(sizeof(*session), GFP_KERNEL); + session = kmalloc_obj(*session); if (!session) return -ENOMEM; diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index a226ff208eda..a47a40fac848 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -107,7 +107,7 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) { struct urdev *urd; - urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); + urd = kzalloc_obj(struct urdev); if (!urd) return NULL; urd->reclen = cdev->id.driver_info; @@ -225,8 +225,7 @@ static struct ccw1 *alloc_chan_prog(const char __user *ubuf, int rec_count, * That means we allocate room for CCWs to cover count/reclen * records plus a NOP. */ - cpa = kcalloc(rec_count + 1, sizeof(struct ccw1), - GFP_KERNEL | GFP_DMA); + cpa = kzalloc_objs(struct ccw1, rec_count + 1, GFP_KERNEL | GFP_DMA); if (!cpa) return ERR_PTR(-ENOMEM); @@ -397,7 +396,7 @@ static struct urfile *urfile_alloc(struct urdev *urd) { struct urfile *urf; - urf = kzalloc(sizeof(struct urfile), GFP_KERNEL); + urf = kzalloc_obj(struct urfile); if (!urf) return NULL; urf->urd = urd; @@ -606,7 +605,7 @@ static int verify_uri_device(struct urdev *urd) char *buf; int rc; - fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA); + fcb = kmalloc_obj(*fcb, GFP_KERNEL | GFP_DMA); if (!fcb) return -ENOMEM; @@ -665,7 +664,7 @@ static int get_uri_file_reclen(struct urdev *urd) struct file_control_block *fcb; int rc; - fcb = kmalloc(sizeof(*fcb), GFP_KERNEL | GFP_DMA); + fcb = kmalloc_obj(*fcb, GFP_KERNEL | GFP_DMA); if (!fcb) return -ENOMEM; rc = diag_read_next_file_info(fcb, 0); diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index f5c59abba221..061ee91e490e 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c @@ -130,7 +130,7 @@ struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags, struct airq_iv *iv; unsigned long size; - iv = kzalloc(sizeof(*iv), GFP_KERNEL); + iv = kzalloc_obj(*iv); if (!iv) goto out; iv->bits = bits; diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 185c99c5d4cc..e2766963b69e 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -322,7 +322,7 @@ int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, if (num_devices < 1) return -EINVAL; - gdev = kzalloc(struct_size(gdev, cdev, num_devices), GFP_KERNEL); + gdev = kzalloc_flex(*gdev, cdev, num_devices); if (!gdev) return -ENOMEM; diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index c10e2444507e..c890f21a82ce 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -530,7 +530,7 @@ int chp_new(struct chp_id chpid) if (chp_is_registered(chpid)) goto out; - chp = kzalloc(sizeof(struct channel_path), GFP_KERNEL); + chp = kzalloc_obj(struct channel_path); if (!chp) { ret = -ENOMEM; goto out; @@ -593,7 +593,7 @@ struct channel_path_desc_fmt0 *chp_get_chp_desc(struct chp_id chpid) chp = chpid_to_chp(chpid); if (!chp) return NULL; - desc = kmalloc(sizeof(*desc), GFP_KERNEL); + desc = kmalloc_obj(*desc); if (!desc) return NULL; diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index ce992b2107cb..73413417a2ce 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c @@ -81,7 +81,7 @@ static int chsc_subchannel_probe(struct subchannel *sch) CHSC_MSG(6, "Detected chsc subchannel 0.%x.%04x\n", sch->schid.ssid, sch->schid.sch_no); sch->isc = CHSC_SCH_ISC; - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (!private) return -ENOMEM; dev_set_drvdata(&sch->dev, private); @@ -295,7 +295,7 @@ static int chsc_ioctl_start(void __user *user_area) chsc_area = (void *)get_zeroed_page(GFP_KERNEL); if (!chsc_area) return -ENOMEM; - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) { ret = -ENOMEM; goto out_free; @@ -335,7 +335,7 @@ static int chsc_ioctl_on_close_set(void __user *user_area) ret = -EBUSY; goto out_unlock; } - on_close_request = kzalloc(sizeof(*on_close_request), GFP_KERNEL); + on_close_request = kzalloc_obj(*on_close_request); if (!on_close_request) { ret = -ENOMEM; goto out_unlock; @@ -441,7 +441,7 @@ static int chsc_ioctl_info_channel_path(void __user *user_cd) scpcd_area = (void *)get_zeroed_page(GFP_KERNEL); if (!scpcd_area) return -ENOMEM; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) { ret = -ENOMEM; goto out_free; @@ -503,7 +503,7 @@ static int chsc_ioctl_info_cu(void __user *user_cd) scucd_area = (void *)get_zeroed_page(GFP_KERNEL); if (!scucd_area) return -ENOMEM; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) { ret = -ENOMEM; goto out_free; @@ -566,7 +566,7 @@ static int chsc_ioctl_info_sch_cu(void __user *user_cud) sscud_area = (void *)get_zeroed_page(GFP_KERNEL); if (!sscud_area) return -ENOMEM; - cud = kzalloc(sizeof(*cud), GFP_KERNEL); + cud = kzalloc_obj(*cud); if (!cud) { ret = -ENOMEM; goto out_free; @@ -628,7 +628,7 @@ static int chsc_ioctl_conf_info(void __user *user_ci) sci_area = (void *)get_zeroed_page(GFP_KERNEL); if (!sci_area) return -ENOMEM; - ci = kzalloc(sizeof(*ci), GFP_KERNEL); + ci = kzalloc_obj(*ci); if (!ci) { ret = -ENOMEM; goto out_free; @@ -699,7 +699,7 @@ static int chsc_ioctl_conf_comp_list(void __user *user_ccl) sccl_area = (void *)get_zeroed_page(GFP_KERNEL); if (!sccl_area) return -ENOMEM; - ccl = kzalloc(sizeof(*ccl), GFP_KERNEL); + ccl = kzalloc_obj(*ccl); if (!ccl) { ret = -ENOMEM; goto out_free; @@ -755,7 +755,7 @@ static int chsc_ioctl_chpd(void __user *user_chpd) struct chsc_cpd_info *chpd; int ret; - chpd = kzalloc(sizeof(*chpd), GFP_KERNEL); + chpd = kzalloc_obj(*chpd); scpd_area = (void *)get_zeroed_page(GFP_KERNEL); if (!scpd_area || !chpd) { ret = -ENOMEM; @@ -799,7 +799,7 @@ static int chsc_ioctl_dcal(void __user *user_dcal) sdcal_area = (void *)get_zeroed_page(GFP_KERNEL); if (!sdcal_area) return -ENOMEM; - dcal = kzalloc(sizeof(*dcal), GFP_KERNEL); + dcal = kzalloc_obj(*dcal); if (!dcal) { ret = -ENOMEM; goto out_free; diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 7d035e4937ce..92ab3d546fe4 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -483,11 +483,11 @@ static int alloc_cmb(struct ccw_device *cdev) struct cmb_data *cmb_data; /* Allocate private cmb_data. */ - cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); + cmb_data = kzalloc_obj(struct cmb_data); if (!cmb_data) return -ENOMEM; - cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL); + cmb_data->last_block = kzalloc_obj(struct cmb); if (!cmb_data->last_block) { kfree(cmb_data); return -ENOMEM; @@ -766,11 +766,11 @@ static int alloc_cmbe(struct ccw_device *cdev) if (!cmbe) return ret; - cmb_data = kzalloc(sizeof(*cmb_data), GFP_KERNEL); + cmb_data = kzalloc_obj(*cmb_data); if (!cmb_data) goto out_free; - cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL); + cmb_data->last_block = kzalloc_obj(struct cmbe); if (!cmb_data->last_block) goto out_free; diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index ac24e019020e..5ab239f38588 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -203,7 +203,7 @@ struct subchannel *css_alloc_subchannel(struct subchannel_id schid, if (ret < 0) return ERR_PTR(ret); - sch = kzalloc(sizeof(*sch), GFP_KERNEL | GFP_DMA); + sch = kzalloc_obj(*sch, GFP_KERNEL | GFP_DMA); if (!sch) return ERR_PTR(-ENOMEM); @@ -971,7 +971,7 @@ static int __init setup_css(int nr) struct channel_subsystem *css; int ret; - css = kzalloc(sizeof(*css), GFP_KERNEL); + css = kzalloc_obj(*css); if (!css) return -ENOMEM; @@ -1005,8 +1005,7 @@ static int __init setup_css(int nr) goto out_err; } - css->pseudo_subchannel = kzalloc(sizeof(*css->pseudo_subchannel), - GFP_KERNEL); + css->pseudo_subchannel = kzalloc_obj(*css->pseudo_subchannel); if (!css->pseudo_subchannel) { device_unregister(&css->device); ret = -ENOMEM; diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 602f36102c7c..5bbb112b1619 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -686,13 +686,13 @@ static struct ccw_device * io_subchannel_allocate_dev(struct subchannel *sch) struct gen_pool *dma_pool; int ret; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) { ret = -ENOMEM; goto err_cdev; } - cdev->private = kzalloc(sizeof(struct ccw_device_private), - GFP_KERNEL | GFP_DMA); + cdev->private = kzalloc_obj(struct ccw_device_private, + GFP_KERNEL | GFP_DMA); if (!cdev->private) { ret = -ENOMEM; goto err_priv; @@ -1060,7 +1060,7 @@ static int io_subchannel_probe(struct subchannel *sch) if (rc) goto out_schedule; /* Allocate I/O subchannel private data. */ - io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); + io_priv = kzalloc_obj(*io_priv, GFP_KERNEL | GFP_DMA); if (!io_priv) goto out_schedule; @@ -1644,7 +1644,7 @@ struct ccw_device * __init ccw_device_create_console(struct ccw_driver *drv) if (IS_ERR(sch)) return ERR_CAST(sch); - io_priv = kzalloc(sizeof(*io_priv), GFP_KERNEL | GFP_DMA); + io_priv = kzalloc_obj(*io_priv, GFP_KERNEL | GFP_DMA); if (!io_priv) goto err_priv; io_priv->dma_area = dma_alloc_coherent(&sch->dev, diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c index d60f7d80863a..7ce374313730 100644 --- a/drivers/s390/cio/eadm_sch.c +++ b/drivers/s390/cio/eadm_sch.c @@ -215,7 +215,7 @@ static int eadm_subchannel_probe(struct subchannel *sch) struct eadm_private *private; int ret; - private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); + private = kzalloc_obj(*private, GFP_KERNEL | GFP_DMA); if (!private) return -ENOMEM; diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 4fb900f2d3d9..b35195e7c68a 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c @@ -81,7 +81,7 @@ int qdio_allocate_dbf(struct qdio_irq *irq_ptr) } debug_set_level(irq_ptr->debug_area, DBF_WARN); DBF_DEV_EVENT(DBF_ERR, irq_ptr, "dbf created"); - new_entry = kzalloc(sizeof(struct qdio_dbf_entry), GFP_KERNEL); + new_entry = kzalloc_obj(struct qdio_dbf_entry); if (!new_entry) { debug_unregister(irq_ptr->debug_area); return -ENOMEM; diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 7dd967165025..7e594a800525 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -965,7 +965,7 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs, if (!irq_ptr) return -ENOMEM; - irq_ptr->ccw = kmalloc(sizeof(*irq_ptr->ccw), GFP_KERNEL | GFP_DMA); + irq_ptr->ccw = kmalloc_obj(*irq_ptr->ccw, GFP_KERNEL | GFP_DMA); if (!irq_ptr->ccw) goto err_ccw; diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index f931954910c5..85ca8650adeb 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c @@ -204,8 +204,7 @@ int __init qdio_thinint_init(void) { int rc; - q_indicators = kcalloc(TIQDIO_NR_INDICATORS, sizeof(struct indicator_t), - GFP_KERNEL); + q_indicators = kzalloc_objs(struct indicator_t, TIQDIO_NR_INDICATORS); if (!q_indicators) return -ENOMEM; diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 9b4da237a0ed..d13ed1011c03 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -207,7 +207,7 @@ static int scm_add(struct chsc_scm_info *scm_info, size_t num) put_device(&scmdev->dev); continue; } - scmdev = kzalloc(sizeof(*scmdev), GFP_KERNEL); + scmdev = kzalloc_obj(*scmdev); if (!scmdev) return -ENODEV; scmdev_setup(scmdev, sale, scm_info->is, scm_info->mbc); diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c index 5f6e10225627..7561aa7d3e01 100644 --- a/drivers/s390/cio/vfio_ccw_cp.c +++ b/drivers/s390/cio/vfio_ccw_cp.c @@ -65,11 +65,11 @@ static int page_array_alloc(struct page_array *pa, unsigned int len) pa->pa_nr = len; - pa->pa_iova = kcalloc(len, sizeof(*pa->pa_iova), GFP_KERNEL); + pa->pa_iova = kzalloc_objs(*pa->pa_iova, len); if (!pa->pa_iova) return -ENOMEM; - pa->pa_page = kcalloc(len, sizeof(*pa->pa_page), GFP_KERNEL); + pa->pa_page = kzalloc_objs(*pa->pa_page, len); if (!pa->pa_page) { kfree(pa->pa_iova); return -ENOMEM; @@ -319,15 +319,15 @@ static struct ccwchain *ccwchain_alloc(struct channel_program *cp, int len) { struct ccwchain *chain; - chain = kzalloc(sizeof(*chain), GFP_KERNEL); + chain = kzalloc_obj(*chain); if (!chain) return NULL; - chain->ch_ccw = kcalloc(len, sizeof(*chain->ch_ccw), GFP_DMA | GFP_KERNEL); + chain->ch_ccw = kzalloc_objs(*chain->ch_ccw, len, GFP_DMA | GFP_KERNEL); if (!chain->ch_ccw) goto out_err; - chain->ch_pa = kcalloc(len, sizeof(*chain->ch_pa), GFP_KERNEL); + chain->ch_pa = kzalloc_objs(*chain->ch_pa, len); if (!chain->ch_pa) goto out_err; @@ -516,7 +516,7 @@ static dma64_t *get_guest_idal(struct ccw1 *ccw, struct channel_program *cp, int int idaw_mask = ~(idaw_size - 1); int i, ret; - idaws = kcalloc(idaw_nr, sizeof(*idaws), GFP_DMA | GFP_KERNEL); + idaws = kzalloc_objs(*idaws, idaw_nr, GFP_DMA | GFP_KERNEL); if (!idaws) return ERR_PTR(-ENOMEM); diff --git a/drivers/s390/cio/vfio_ccw_drv.c b/drivers/s390/cio/vfio_ccw_drv.c index 6ff5c9cfb7ed..1a095085bc72 100644 --- a/drivers/s390/cio/vfio_ccw_drv.c +++ b/drivers/s390/cio/vfio_ccw_drv.c @@ -171,7 +171,7 @@ static int vfio_ccw_sch_probe(struct subchannel *sch) return -ENODEV; } - parent = kzalloc(sizeof(*parent), GFP_KERNEL); + parent = kzalloc_obj(*parent); if (!parent) return -ENOMEM; @@ -281,7 +281,7 @@ static void vfio_ccw_queue_crw(struct vfio_ccw_private *private, * carry on. The guest will either see a later one or * learn when it issues its own store subchannel. */ - crw = kzalloc(sizeof(*crw), GFP_ATOMIC); + crw = kzalloc_obj(*crw, GFP_ATOMIC); if (!crw) return; diff --git a/drivers/s390/cio/vfio_ccw_ops.c b/drivers/s390/cio/vfio_ccw_ops.c index a596f6013019..45ec722d25ea 100644 --- a/drivers/s390/cio/vfio_ccw_ops.c +++ b/drivers/s390/cio/vfio_ccw_ops.c @@ -55,8 +55,7 @@ static int vfio_ccw_mdev_init_dev(struct vfio_device *vdev) INIT_WORK(&private->io_work, vfio_ccw_sch_io_todo); INIT_WORK(&private->crw_work, vfio_ccw_crw_todo); - private->cp.guest_cp = kcalloc(CCWCHAIN_LEN_MAX, sizeof(struct ccw1), - GFP_KERNEL); + private->cp.guest_cp = kzalloc_objs(struct ccw1, CCWCHAIN_LEN_MAX); if (!private->cp.guest_cp) goto out_free_private; diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index 8b0ad6f582ec..e827fbeb76fb 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -233,7 +233,7 @@ struct ap_card *ap_card_create(int id, struct ap_tapq_hwinfo hwinfo, { struct ap_card *ac; - ac = kzalloc(sizeof(*ac), GFP_KERNEL); + ac = kzalloc_obj(*ac); if (!ac) return NULL; ac->ap_dev.device.release = ap_card_device_release; diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index a80ab87cad62..3fe2e41c5c6b 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -1183,7 +1183,7 @@ struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac) { struct ap_queue *aq; - aq = kzalloc(sizeof(*aq), GFP_KERNEL); + aq = kzalloc_obj(*aq); if (!aq) return NULL; aq->card = ac; diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index ad1cd699f53b..d6b595eb3370 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -223,7 +223,7 @@ static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc) return -EFAULT; nr_apqns = MAXAPQNSINLIST; - apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn), GFP_KERNEL); + apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); if (!apqns) return -ENOMEM; @@ -569,9 +569,7 @@ static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak) return -EFAULT; nr_apqns = kak.apqn_entries; if (nr_apqns) { - apqns = kmalloc_array(nr_apqns, - sizeof(struct pkey_apqn), - GFP_KERNEL); + apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); if (!apqns) return -ENOMEM; } @@ -620,9 +618,7 @@ static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat) return -EFAULT; nr_apqns = kat.apqn_entries; if (nr_apqns) { - apqns = kmalloc_array(nr_apqns, - sizeof(struct pkey_apqn), - GFP_KERNEL); + apqns = kmalloc_objs(struct pkey_apqn, nr_apqns); if (!apqns) return -ENOMEM; } diff --git a/drivers/s390/crypto/pkey_uv.c b/drivers/s390/crypto/pkey_uv.c index 6cd3c49384b5..17a914d111ac 100644 --- a/drivers/s390/crypto/pkey_uv.c +++ b/drivers/s390/crypto/pkey_uv.c @@ -291,7 +291,7 @@ static int __init pkey_uv_init(void) if (!test_bit_inv(BIT_UVC_CMD_RETR_SECRET, uv_info.inst_calls_list)) return -ENODEV; - uv_list = kmalloc(sizeof(*uv_list), GFP_KERNEL); + uv_list = kmalloc_obj(*uv_list); if (!uv_list) return -ENOMEM; diff --git a/drivers/s390/crypto/vfio_ap_drv.c b/drivers/s390/crypto/vfio_ap_drv.c index 67a807e2e75b..fd7394d81880 100644 --- a/drivers/s390/crypto/vfio_ap_drv.c +++ b/drivers/s390/crypto/vfio_ap_drv.c @@ -96,7 +96,7 @@ static int vfio_ap_matrix_dev_create(void) if (ret) goto bus_register_err; - matrix_dev = kzalloc(sizeof(*matrix_dev), GFP_KERNEL); + matrix_dev = kzalloc_obj(*matrix_dev); if (!matrix_dev) { ret = -ENOMEM; goto matrix_alloc_err; diff --git a/drivers/s390/crypto/vfio_ap_ops.c b/drivers/s390/crypto/vfio_ap_ops.c index 48da32ad0493..44b3a1dcc1b3 100644 --- a/drivers/s390/crypto/vfio_ap_ops.c +++ b/drivers/s390/crypto/vfio_ap_ops.c @@ -2424,7 +2424,7 @@ int vfio_ap_mdev_probe_queue(struct ap_device *apdev) if (ret) return ret; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) { ret = -ENOMEM; goto err_remove_group; diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index c796773fbce8..023ea279361f 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -397,7 +397,7 @@ static int zcdn_create(const char *name) } /* alloc and prepare a new zcdn device */ - zcdndev = kzalloc(sizeof(*zcdndev), GFP_KERNEL); + zcdndev = kzalloc_obj(*zcdndev); if (!zcdndev) { rc = -ENOMEM; goto unlockout; @@ -1065,7 +1065,7 @@ static long _zcrypt_send_ep11_cprb(u32 xflags, struct ap_perms *perms, rc = -ENOMEM; if (target_num != 0) { if (userspace) { - targets = kcalloc(target_num, sizeof(*targets), GFP_KERNEL); + targets = kzalloc_objs(*targets, target_num); if (!targets) goto out; if (copy_from_user(targets, xcrb->targets, @@ -1627,9 +1627,8 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, size_t total_size = MAX_ZDEV_ENTRIES_EXT * sizeof(struct zcrypt_device_status_ext); - device_status = kvcalloc(MAX_ZDEV_ENTRIES_EXT, - sizeof(struct zcrypt_device_status_ext), - GFP_KERNEL); + device_status = kvzalloc_objs(struct zcrypt_device_status_ext, + MAX_ZDEV_ENTRIES_EXT); if (!device_status) return -ENOMEM; zcrypt_device_status_mask_ext(device_status, diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c index 6dea702a5cac..16f04e65046b 100644 --- a/drivers/s390/crypto/zcrypt_card.c +++ b/drivers/s390/crypto/zcrypt_card.c @@ -90,7 +90,7 @@ static ssize_t online_store(struct device *dev, list_for_each_entry(zq, &zc->zqueues, list) maxzqs++; if (maxzqs > 0) - zq_uelist = kcalloc(maxzqs + 1, sizeof(*zq_uelist), GFP_ATOMIC); + zq_uelist = kzalloc_objs(*zq_uelist, maxzqs + 1, GFP_ATOMIC); list_for_each_entry(zq, &zc->zqueues, list) if (zcrypt_queue_force_online(zq, online)) if (zq_uelist) { @@ -138,7 +138,7 @@ struct zcrypt_card *zcrypt_card_alloc(void) { struct zcrypt_card *zc; - zc = kzalloc(sizeof(*zc), GFP_KERNEL); + zc = kzalloc_obj(*zc); if (!zc) return NULL; INIT_LIST_HEAD(&zc->list); diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c index 573bad1d6d86..37a157a1d969 100644 --- a/drivers/s390/crypto/zcrypt_ccamisc.c +++ b/drivers/s390/crypto/zcrypt_ccamisc.c @@ -1639,11 +1639,13 @@ int cca_get_info(u16 cardnr, u16 domain, struct cca_info *ci, u32 xflags) memset(ci, 0, sizeof(*ci)); - /* get first info from zcrypt device driver about this apqn */ - rc = zcrypt_device_status_ext(cardnr, domain, &devstat); - if (rc) - return rc; - ci->hwtype = devstat.hwtype; + /* if specific domain given, fetch status and hw info for this apqn */ + if (domain != AUTOSEL_DOM) { + rc = zcrypt_device_status_ext(cardnr, domain, &devstat); + if (rc) + return rc; + ci->hwtype = devstat.hwtype; + } /* * Prep memory for rule array and var array use. diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index e9a984903bff..e7b0ed26a9ec 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c @@ -85,8 +85,7 @@ static ssize_t cca_serialnr_show(struct device *dev, memset(&ci, 0, sizeof(ci)); - if (ap_domain_index >= 0) - cca_get_info(ac->id, ap_domain_index, &ci, 0); + cca_get_info(ac->id, AUTOSEL_DOM, &ci, 0); return sysfs_emit(buf, "%s\n", ci.serial); } diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c index a173d32eb6e8..87457cde2c7c 100644 --- a/drivers/s390/crypto/zcrypt_queue.c +++ b/drivers/s390/crypto/zcrypt_queue.c @@ -115,7 +115,7 @@ struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size) { struct zcrypt_queue *zq; - zq = kzalloc(sizeof(*zq), GFP_KERNEL); + zq = kzalloc_obj(*zq); if (!zq) return NULL; zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL); diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c index 3d7ccf2366a0..8b0d76a47d9f 100644 --- a/drivers/s390/net/ctcm_main.c +++ b/drivers/s390/net/ctcm_main.c @@ -1268,7 +1268,7 @@ static int ctcm_probe_device(struct ccwgroup_device *cgdev) if (!get_device(&cgdev->dev)) return -ENODEV; - priv = kzalloc(sizeof(struct ctcm_priv), GFP_KERNEL); + priv = kzalloc_obj(struct ctcm_priv); if (!priv) { CTCM_DBF_TEXT_(ERROR, CTC_DBF_ERROR, "%s: memory allocation failure", @@ -1307,7 +1307,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, "%s(%s), type %d, proto %d", __func__, dev_name(&cdev->dev), type, priv->protocol); - ch = kzalloc(sizeof(struct channel), GFP_KERNEL); + ch = kzalloc_obj(struct channel); if (ch == NULL) return -ENOMEM; @@ -1327,7 +1327,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, } else ccw_num = 8; - ch->ccw = kcalloc(ccw_num, sizeof(struct ccw1), GFP_KERNEL | GFP_DMA); + ch->ccw = kzalloc_objs(struct ccw1, ccw_num, GFP_KERNEL | GFP_DMA); if (ch->ccw == NULL) goto nomem_return; @@ -1408,7 +1408,7 @@ static int add_channel(struct ccw_device *cdev, enum ctcm_channel_types type, fsm_newstate(ch->fsm, CTC_STATE_IDLE); - ch->irb = kzalloc(sizeof(struct irb), GFP_KERNEL); + ch->irb = kzalloc_obj(struct irb); if (ch->irb == NULL) goto nomem_return; diff --git a/drivers/s390/net/ctcm_mpc.c b/drivers/s390/net/ctcm_mpc.c index 0f329fb514ee..aeb102537e7f 100644 --- a/drivers/s390/net/ctcm_mpc.c +++ b/drivers/s390/net/ctcm_mpc.c @@ -1163,7 +1163,7 @@ static void ctcmpc_unpack_skb(struct channel *ch, struct sk_buff *pskb) skb_pull(pskb, new_len); /* point to next PDU */ } } else { - mpcginfo = kmalloc(sizeof(struct mpcg_info), GFP_ATOMIC); + mpcginfo = kmalloc_obj(struct mpcg_info, GFP_ATOMIC); if (mpcginfo == NULL) goto done; @@ -1259,7 +1259,7 @@ struct mpc_group *ctcmpc_init_mpc_group(struct ctcm_priv *priv) CTCM_DBF_TEXT_(MPC_SETUP, CTC_DBF_INFO, "Enter %s(%p)", CTCM_FUNTAIL, priv); - grp = kzalloc(sizeof(struct mpc_group), GFP_KERNEL); + grp = kzalloc_obj(struct mpc_group); if (grp == NULL) return NULL; diff --git a/drivers/s390/net/fsm.c b/drivers/s390/net/fsm.c index 58f8e2fb6d54..9b8622aef807 100644 --- a/drivers/s390/net/fsm.c +++ b/drivers/s390/net/fsm.c @@ -23,7 +23,7 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_ fsm_function_t *m; fsm *f; - this = kzalloc(sizeof(fsm_instance), order); + this = kzalloc_obj(fsm_instance, order); if (this == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc instance\n", name); @@ -32,7 +32,7 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_ strscpy(this->name, name, sizeof(this->name)); init_waitqueue_head(&this->wait_q); - f = kzalloc(sizeof(fsm), order); + f = kzalloc_obj(fsm, order); if (f == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc fsm\n", name); @@ -45,7 +45,7 @@ init_fsm(char *name, const char **state_names, const char **event_names, int nr_ f->state_names = state_names; this->f = f; - m = kcalloc(nr_states*nr_events, sizeof(fsm_function_t), order); + m = kzalloc_objs(fsm_function_t, nr_states * nr_events, order); if (m == NULL) { printk(KERN_WARNING "fsm(%s): init_fsm: Couldn't alloc jumptable\n", name); diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 8b8e4f06be0f..7d0479e4e095 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -598,7 +598,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct ism_dev *ism; int ret; - ism = kzalloc(sizeof(*ism), GFP_KERNEL); + ism = kzalloc_obj(*ism); if (!ism) return -ENOMEM; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 1c80e8ca67b5..cf5f760d0e02 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -225,7 +225,7 @@ static struct qeth_buffer_pool_entry *qeth_alloc_pool_entry(unsigned int pages) struct qeth_buffer_pool_entry *entry; unsigned int i; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -324,7 +324,7 @@ static void qeth_free_qdio_queue(struct qeth_qdio_q *q) static struct qeth_qdio_q *qeth_alloc_qdio_queue(void) { - struct qeth_qdio_q *q = kzalloc(sizeof(*q), GFP_KERNEL); + struct qeth_qdio_q *q = kzalloc_obj(*q); int i; if (!q) @@ -559,7 +559,7 @@ static void qeth_add_local_addrs4(struct qeth_card *card, if (duplicate) continue; - addr = kmalloc(sizeof(*addr), GFP_ATOMIC); + addr = kmalloc_obj(*addr, GFP_ATOMIC); if (!addr) { dev_err(&card->gdev->dev, "Failed to allocate local addr object. Traffic to %pI4 might suffer.\n", @@ -602,7 +602,7 @@ static void qeth_add_local_addrs6(struct qeth_card *card, if (duplicate) continue; - addr = kmalloc(sizeof(*addr), GFP_ATOMIC); + addr = kmalloc_obj(*addr, GFP_ATOMIC); if (!addr) { dev_err(&card->gdev->dev, "Failed to allocate local addr object. Traffic to %pI6c might suffer.\n", @@ -930,7 +930,7 @@ static struct qeth_cmd_buffer *qeth_alloc_cmd(struct qeth_channel *channel, if (length > QETH_BUFSIZE) return NULL; - iob = kzalloc(sizeof(*iob), GFP_KERNEL); + iob = kzalloc_obj(*iob); if (!iob) return NULL; @@ -1626,7 +1626,7 @@ static struct qeth_card *qeth_alloc_card(struct ccwgroup_device *gdev) struct qeth_card *card; QETH_DBF_TEXT(SETUP, 2, "alloccrd"); - card = kzalloc(sizeof(*card), GFP_KERNEL); + card = kzalloc_obj(*card); if (!card) goto out; QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); @@ -1837,8 +1837,8 @@ static enum qeth_discipline_id qeth_vm_detect_layer(struct qeth_card *card) if (rc) goto out; - request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA); - response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA); + request = kzalloc_obj(*request, GFP_KERNEL | GFP_DMA); + response = kzalloc_obj(*response, GFP_KERNEL | GFP_DMA); if (!request || !response) { rc = -ENOMEM; goto out; @@ -2591,7 +2591,7 @@ static void qeth_free_output_queue(struct qeth_qdio_out_q *q) static struct qeth_qdio_out_q *qeth_alloc_output_queue(void) { - struct qeth_qdio_out_q *q = kzalloc(sizeof(*q), GFP_KERNEL); + struct qeth_qdio_out_q *q = kzalloc_obj(*q); unsigned int i; if (!q) @@ -4953,8 +4953,8 @@ int qeth_vm_request_mac(struct qeth_card *card) QETH_CARD_TEXT(card, 2, "vmreqmac"); - request = kzalloc(sizeof(*request), GFP_KERNEL | GFP_DMA); - response = kzalloc(sizeof(*response), GFP_KERNEL | GFP_DMA); + request = kzalloc_obj(*request, GFP_KERNEL | GFP_DMA); + response = kzalloc_obj(*response, GFP_KERNEL | GFP_DMA); if (!request || !response) { rc = -ENOMEM; goto out; @@ -6249,7 +6249,7 @@ static int qeth_add_dbf_entry(struct qeth_card *card, char *name) } if (debug_register_view(card->debug, &debug_hex_ascii_view)) goto err_dbg; - new_entry = kzalloc(sizeof(struct qeth_dbf_entry), GFP_KERNEL); + new_entry = kzalloc_obj(struct qeth_dbf_entry); if (!new_entry) goto err_dbg; strscpy(new_entry->dbf_name, name, sizeof(new_entry->dbf_name)); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 7498a83b1f06..a9e7d1d637a2 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -442,7 +442,7 @@ static void qeth_l2_add_mac(struct qeth_card *card, struct netdev_hw_addr *ha) } } - mac = kzalloc(sizeof(struct qeth_mac), GFP_ATOMIC); + mac = kzalloc_obj(struct qeth_mac, GFP_ATOMIC); if (!mac) return; @@ -827,7 +827,7 @@ static int qeth_l2_br2dev_queue_work(struct net_device *brdev, struct qeth_l2_br2dev_event_work *worker_data; struct qeth_card *card; - worker_data = kzalloc(sizeof(*worker_data), GFP_ATOMIC); + worker_data = kzalloc_obj(*worker_data, GFP_ATOMIC); if (!worker_data) return -ENOMEM; INIT_WORK(&worker_data->work, qeth_l2_br2dev_worker); @@ -1348,7 +1348,7 @@ static void qeth_bridge_state_change(struct qeth_card *card, return; } - data = kzalloc(sizeof(*data), GFP_ATOMIC); + data = kzalloc_obj(*data, GFP_ATOMIC); if (!data) { QETH_CARD_TEXT(card, 2, "BPSalloc"); return; diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 027bc346232f..1542bfc9f561 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2163,7 +2163,7 @@ static int qeth_l3_ip6_event(struct notifier_block *this, if (!qeth_is_supported(card, IPA_IPV6)) return NOTIFY_DONE; - ip_work = kmalloc(sizeof(*ip_work), GFP_ATOMIC); + ip_work = kmalloc_obj(*ip_work, GFP_ATOMIC); if (!ip_work) return NOTIFY_DONE; diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index a6b64228ead2..aa2603122e2c 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -431,7 +431,7 @@ static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count, if (rc) return rc; - ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); + ipatoe = kzalloc_obj(struct qeth_ipato_entry); if (!ipatoe) return -ENOMEM; diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 3dadaacc42a6..852bb2d5eba2 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c @@ -92,7 +92,7 @@ int smsg_register_callback(const char *prefix, { struct smsg_callback *cb; - cb = kmalloc(sizeof(struct smsg_callback), GFP_KERNEL); + cb = kmalloc_obj(struct smsg_callback); if (!cb) return -ENOMEM; cb->prefix = prefix; diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 1bd0370460cd..c53305b4cb25 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -69,7 +69,7 @@ static struct smsg_app_event *smsg_app_event_alloc(const char *from, { struct smsg_app_event *ev; - ev = kzalloc(sizeof(*ev), GFP_ATOMIC); + ev = kzalloc_obj(*ev, GFP_ATOMIC); if (!ev) return NULL; diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 01f927ae61b5..8ff7db7921b5 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c @@ -344,7 +344,7 @@ struct zfcp_adapter *zfcp_adapter_enqueue(struct ccw_device *ccw_device) if (!get_device(&ccw_device->dev)) return ERR_PTR(-ENODEV); - adapter = kzalloc(sizeof(struct zfcp_adapter), GFP_KERNEL); + adapter = kzalloc_obj(struct zfcp_adapter); if (!adapter) { put_device(&ccw_device->dev); return ERR_PTR(-ENOMEM); @@ -518,7 +518,7 @@ struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn, goto err_put; } - port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL); + port = kzalloc_obj(struct zfcp_port); if (!port) goto err_put; diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 6b5561c54e2f..71f625926ae1 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -816,7 +816,7 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) char name[DEBUG_MAX_NAME_LEN]; struct zfcp_dbf *dbf; - dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL); + dbf = kzalloc_obj(struct zfcp_dbf); if (!dbf) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_diag.c b/drivers/s390/scsi/zfcp_diag.c index 4d2d89d9c15a..7be5a1d56263 100644 --- a/drivers/s390/scsi/zfcp_diag.c +++ b/drivers/s390/scsi/zfcp_diag.c @@ -36,7 +36,7 @@ int zfcp_diag_adapter_setup(struct zfcp_adapter *const adapter) struct zfcp_diag_adapter *diag; struct zfcp_diag_header *hdr; - diag = kzalloc(sizeof(*diag), GFP_KERNEL); + diag = kzalloc_obj(*diag); if (diag == NULL) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index 78ca394e1195..05d081297879 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -128,7 +128,7 @@ void zfcp_fc_enqueue_event(struct zfcp_adapter *adapter, { struct zfcp_fc_event *event; - event = kmalloc(sizeof(struct zfcp_fc_event), GFP_ATOMIC); + event = kmalloc_obj(struct zfcp_fc_event, GFP_ATOMIC); if (!event) return; @@ -1116,7 +1116,7 @@ int zfcp_fc_gs_setup(struct zfcp_adapter *adapter) { struct zfcp_fc_wka_ports *wka_ports; - wka_ports = kzalloc(sizeof(struct zfcp_fc_wka_ports), GFP_KERNEL); + wka_ports = kzalloc_obj(struct zfcp_fc_wka_ports); if (!wka_ports) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 9418086368c3..d407f16e77ef 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -806,7 +806,7 @@ static struct zfcp_fsf_req *zfcp_fsf_alloc(mempool_t *pool) if (likely(pool)) req = mempool_alloc(pool, GFP_ATOMIC); else - req = kmalloc(sizeof(*req), GFP_ATOMIC); + req = kmalloc_obj(*req, GFP_ATOMIC); if (unlikely(!req)) return NULL; diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index e15a1eabe42d..ce1af72d9b61 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -549,7 +549,7 @@ int zfcp_qdio_setup(struct zfcp_adapter *adapter) { struct zfcp_qdio *qdio; - qdio = kzalloc(sizeof(struct zfcp_qdio), GFP_KERNEL); + qdio = kzalloc_obj(struct zfcp_qdio); if (!qdio) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_reqlist.h b/drivers/s390/scsi/zfcp_reqlist.h index 59fbb1b128cb..a0fd4739ff4a 100644 --- a/drivers/s390/scsi/zfcp_reqlist.h +++ b/drivers/s390/scsi/zfcp_reqlist.h @@ -42,7 +42,7 @@ static inline struct zfcp_reqlist *zfcp_reqlist_alloc(void) size_t i; struct zfcp_reqlist *rl; - rl = kzalloc(sizeof(struct zfcp_reqlist), GFP_KERNEL); + rl = kzalloc_obj(struct zfcp_reqlist); if (!rl) return NULL; diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 634bd8dceedd..3590113c2b74 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -542,7 +542,7 @@ zfcp_scsi_init_fc_host_stats(struct zfcp_adapter *adapter) struct fc_host_statistics *fc_stats; if (!adapter->fc_stats) { - fc_stats = kmalloc(sizeof(*fc_stats), GFP_KERNEL); + fc_stats = kmalloc_obj(*fc_stats); if (!fc_stats) return NULL; adapter->fc_stats = fc_stats; /* freed in adapter_release */ @@ -622,7 +622,7 @@ zfcp_scsi_get_fc_host_stats(struct Scsi_Host *host) if (!fc_stats) return NULL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; @@ -651,7 +651,7 @@ static void zfcp_scsi_reset_fc_host_stats(struct Scsi_Host *shost) int ret; adapter = (struct zfcp_adapter *)shost->hostdata[0]; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return; diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 10a3840b2b6b..42423549e511 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -708,7 +708,7 @@ static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev, if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) return -EOPNOTSUPP; - qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL); + qtcb_port = kzalloc_obj(struct fsf_qtcb_bottom_port); if (!qtcb_port) return -ENOMEM; @@ -733,8 +733,7 @@ static int zfcp_sysfs_adapter_ex_config(struct device *dev, if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)) return -EOPNOTSUPP; - qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config), - GFP_KERNEL); + qtcb_config = kzalloc_obj(struct fsf_qtcb_bottom_config); if (!qtcb_config) return -ENOMEM; diff --git a/drivers/s390/scsi/zfcp_unit.c b/drivers/s390/scsi/zfcp_unit.c index 4ef2a635d34f..510cb248cf83 100644 --- a/drivers/s390/scsi/zfcp_unit.c +++ b/drivers/s390/scsi/zfcp_unit.c @@ -137,7 +137,7 @@ int zfcp_unit_add(struct zfcp_port *port, u64 fcp_lun) goto out; } - unit = kzalloc(sizeof(struct zfcp_unit), GFP_KERNEL); + unit = kzalloc_obj(struct zfcp_unit); if (!unit) { retval = -ENOMEM; goto out; diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 1653cc668dcf..bab6cad3fd5c 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -277,7 +277,7 @@ static struct airq_info *new_airq_info(int index) struct airq_info *info; int rc; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return NULL; rwlock_init(&info->lock); @@ -566,7 +566,7 @@ static struct virtqueue *virtio_ccw_setup_vq(struct virtio_device *vdev, notify = virtio_ccw_kvm_notify; /* Allocate queue. */ - info = kzalloc(sizeof(struct virtio_ccw_vq_info), GFP_KERNEL); + info = kzalloc_obj(struct virtio_ccw_vq_info); if (!info) { dev_warn(&vcdev->cdev->dev, "no info\n"); err = -ENOMEM; @@ -1370,7 +1370,7 @@ static int virtio_ccw_online(struct ccw_device *cdev) struct virtio_ccw_device *vcdev; unsigned long flags; - vcdev = kzalloc(sizeof(*vcdev), GFP_KERNEL); + vcdev = kzalloc_obj(*vcdev); if (!vcdev) { dev_warn(&cdev->dev, "Could not get memory for virtio\n"); ret = -ENOMEM; diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index 23af4edd295b..d3083a547aa5 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c @@ -448,7 +448,7 @@ static void attach_one_temp(struct bbc_i2c_bus *bp, struct platform_device *op, { struct bbc_cpu_temperature *tp; - tp = kzalloc(sizeof(*tp), GFP_KERNEL); + tp = kzalloc_obj(*tp); if (!tp) return; @@ -496,7 +496,7 @@ static void attach_one_fan(struct bbc_i2c_bus *bp, struct platform_device *op, { struct bbc_fan_control *fp; - fp = kzalloc(sizeof(*fp), GFP_KERNEL); + fp = kzalloc_obj(*fp); if (!fp) return; diff --git a/drivers/sbus/char/bbc_i2c.c b/drivers/sbus/char/bbc_i2c.c index 90e71ce4bab8..1801ba56389c 100644 --- a/drivers/sbus/char/bbc_i2c.c +++ b/drivers/sbus/char/bbc_i2c.c @@ -92,7 +92,7 @@ struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct platform_de struct bbc_i2c_client *client; const u32 *reg; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return NULL; client->bp = bp; @@ -298,7 +298,7 @@ static struct bbc_i2c_bus * attach_one_i2c(struct platform_device *op, int index struct device_node *dp; int entry; - bp = kzalloc(sizeof(*bp), GFP_KERNEL); + bp = kzalloc_obj(*bp); if (!bp) return NULL; diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c index 8643947fee8e..0b90a2450429 100644 --- a/drivers/sbus/char/openprom.c +++ b/drivers/sbus/char/openprom.c @@ -666,7 +666,7 @@ static int openprom_open(struct inode * inode, struct file * file) { DATA *data; - data = kmalloc(sizeof(DATA), GFP_KERNEL); + data = kmalloc_obj(DATA); if (!data) return -ENOMEM; diff --git a/drivers/sbus/char/oradax.c b/drivers/sbus/char/oradax.c index a536dd6f4f7c..45df0b274491 100644 --- a/drivers/sbus/char/oradax.c +++ b/drivers/sbus/char/oradax.c @@ -643,12 +643,11 @@ static int dax_open(struct inode *inode, struct file *f) struct dax_ctx *ctx = NULL; int i; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (ctx == NULL) goto done; - ctx->ccb_buf = kcalloc(DAX_MAX_CCBS, sizeof(struct dax_ccb), - GFP_KERNEL); + ctx->ccb_buf = kzalloc_objs(struct dax_ccb, DAX_MAX_CCBS); if (ctx->ccb_buf == NULL) goto done; diff --git a/drivers/sbus/char/uctrl.c b/drivers/sbus/char/uctrl.c index e3dec78f51e9..85aaec5876a7 100644 --- a/drivers/sbus/char/uctrl.c +++ b/drivers/sbus/char/uctrl.c @@ -348,7 +348,7 @@ static int uctrl_probe(struct platform_device *op) struct uctrl_driver *p; int err = -ENOMEM; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { printk(KERN_ERR "uctrl: Unable to allocate device struct.\n"); goto out; diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index e64a9a18ec6e..9b93a2440af8 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1184,7 +1184,7 @@ static int twa_initialize_device_extension(TW_Device_Extension *tw_dev) } /* Allocate event info space */ - tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL); + tw_dev->event_queue[0] = kzalloc_objs(TW_Event, TW_Q_LENGTH); if (!tw_dev->event_queue[0]) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0x18, "Event info memory allocation failed"); goto out; diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index fde12475b712..52dc1aa639f7 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -1052,7 +1052,7 @@ static int twl_initialize_device_extension(TW_Device_Extension *tw_dev) } /* Allocate event info space */ - tw_dev->event_queue[0] = kcalloc(TW_Q_LENGTH, sizeof(TW_Event), GFP_KERNEL); + tw_dev->event_queue[0] = kzalloc_objs(TW_Event, TW_Q_LENGTH); if (!tw_dev->event_queue[0]) { TW_PRINTK(tw_dev->host, TW_DRIVER, 0xc, "Event info memory allocation failed"); goto out; diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 860538c6f8cb..c78f74b8f45c 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -2020,8 +2020,7 @@ NCR_700_set_offset(struct scsi_target *STp, int offset) STATIC int NCR_700_sdev_init(struct scsi_device *SDp) { - SDp->hostdata = kzalloc(sizeof(struct NCR_700_Device_Parameters), - GFP_KERNEL); + SDp->hostdata = kzalloc_obj(struct NCR_700_Device_Parameters); if (!SDp->hostdata) return -ENOMEM; diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 49929d0339fa..da6599ae3d0d 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2214,15 +2214,14 @@ static int __init blogic_init(void) if (blogic_probe_options.noprobe) return -ENODEV; blogic_probeinfo_list = - kcalloc(BLOGIC_MAX_ADAPTERS, sizeof(struct blogic_probeinfo), - GFP_KERNEL); + kzalloc_objs(struct blogic_probeinfo, BLOGIC_MAX_ADAPTERS); if (blogic_probeinfo_list == NULL) { blogic_err("BusLogic: Unable to allocate Probe Info List\n", NULL); return -ENOMEM; } - adapter = kzalloc(sizeof(struct blogic_adapter), GFP_KERNEL); + adapter = kzalloc_obj(struct blogic_adapter); if (adapter == NULL) { kfree(blogic_probeinfo_list); blogic_err("BusLogic: Unable to allocate Prototype Host Adapter\n", NULL); diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 75b43047a155..a02638b477de 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c @@ -47,8 +47,7 @@ static int __init amiga_a4000t_scsi_probe(struct platform_device *pdev) "A4000T builtin SCSI")) return -EBUSY; - hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), - GFP_KERNEL); + hostdata = kzalloc_obj(struct NCR_700_Host_Parameters); if (!hostdata) { dev_err(&pdev->dev, "Failed to allocate host data\n"); goto out_release; diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 0be719f38377..df9492247631 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -492,8 +492,8 @@ int aac_get_containers(struct aac_dev *dev) fsa_dev_ptr = dev->fsa_dev; - dev->fsa_dev = kcalloc(maximum_num_containers, - sizeof(*fsa_dev_ptr), GFP_KERNEL); + dev->fsa_dev = kzalloc_objs(*fsa_dev_ptr, + maximum_num_containers); kfree(fsa_dev_ptr); fsa_dev_ptr = NULL; @@ -820,7 +820,7 @@ int aac_probe_container(struct aac_dev *dev, int cid) { struct aac_cmd_priv *cmd_priv; struct scsi_cmnd *scsicmd = kzalloc(sizeof(*scsicmd) + sizeof(*cmd_priv), GFP_KERNEL); - struct scsi_device *scsidev = kzalloc(sizeof(*scsidev), GFP_KERNEL); + struct scsi_device *scsidev = kzalloc_obj(*scsidev); int status; if (!scsicmd || !scsidev) { @@ -4010,7 +4010,7 @@ static int aac_convert_sgraw2(struct aac_raw_io2 *rio2, int pages, int nseg, int if (aac_convert_sgl == 0) return 0; - sge = kmalloc_array(nseg_new, sizeof(*sge), GFP_ATOMIC); + sge = kmalloc_objs(*sge, nseg_new, GFP_ATOMIC); if (sge == NULL) return -ENOMEM; diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index 68240d6f27ab..bd82aeb679ae 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -169,7 +169,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg) struct aac_fib_context * fibctx; int status; - fibctx = kmalloc(sizeof(struct aac_fib_context), GFP_KERNEL); + fibctx = kmalloc_obj(struct aac_fib_context); if (fibctx == NULL) { status = -ENOMEM; } else { diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 726c8531b7d3..9bd3f5b868bc 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -632,7 +632,7 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev) * Ok now init the communication subsystem */ - dev->queues = kzalloc(sizeof(struct aac_queue_block), GFP_KERNEL); + dev->queues = kzalloc_obj(struct aac_queue_block); if (dev->queues == NULL) { printk(KERN_ERR "Error could not allocate comm region.\n"); return NULL; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 7d9a4dce236b..c4485629f792 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -1907,13 +1907,13 @@ static int fillup_pools(struct aac_dev *dev, struct hw_fib **hw_fib_pool, hw_fib_p = hw_fib_pool; fib_p = fib_pool; while (hw_fib_p < &hw_fib_pool[num]) { - *(hw_fib_p) = kmalloc(sizeof(struct hw_fib), GFP_KERNEL); + *(hw_fib_p) = kmalloc_obj(struct hw_fib); if (!(*(hw_fib_p++))) { --hw_fib_p; break; } - *(fib_p) = kmalloc(sizeof(struct fib), GFP_KERNEL); + *(fib_p) = kmalloc_obj(struct fib); if (!(*(fib_p++))) { kfree(*(--hw_fib_p)); break; @@ -2101,12 +2101,11 @@ static void aac_process_events(struct aac_dev *dev) if (!num) goto free_fib; - hw_fib_pool = kmalloc_array(num, sizeof(struct hw_fib *), - GFP_KERNEL); + hw_fib_pool = kmalloc_objs(struct hw_fib *, num); if (!hw_fib_pool) goto free_fib; - fib_pool = kmalloc_array(num, sizeof(struct fib *), GFP_KERNEL); + fib_pool = kmalloc_objs(struct fib *, num); if (!fib_pool) goto free_hw_fib_pool; diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index fbe334c59f37..169c41d080a1 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -184,7 +184,7 @@ unsigned int aac_command_normal(struct aac_queue *q) * a fib object in order to manage the linked lists */ if (dev->aif_thread) - if((fib = kmalloc(sizeof(struct fib), GFP_ATOMIC)) == NULL) + if((fib = kmalloc_obj(struct fib, GFP_ATOMIC)) == NULL) fib = &fibctx; memset(fib, 0, sizeof(struct fib)); @@ -284,9 +284,9 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif, * manage the linked lists. */ if ((!dev->aif_thread) - || (!(fib = kzalloc(sizeof(struct fib),GFP_ATOMIC)))) + || (!(fib = kzalloc_obj(struct fib, GFP_ATOMIC)))) return 1; - if (!(hw_fib = kzalloc(sizeof(struct hw_fib),GFP_ATOMIC))) { + if (!(hw_fib = kzalloc_obj(struct hw_fib, GFP_ATOMIC))) { kfree (fib); return 1; } diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index ea468666159a..2fa8f7ddb703 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1661,9 +1661,7 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (aac_reset_devices || reset_devices) aac->init_reset = true; - aac->fibs = kcalloc(shost->can_queue + AAC_NUM_MGT_FIB, - sizeof(struct fib), - GFP_KERNEL); + aac->fibs = kzalloc_objs(struct fib, shost->can_queue + AAC_NUM_MGT_FIB); if (!aac->fibs) { error = -ENOMEM; goto out_free_host; diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 08bddac49757..fcf059bf41e8 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7486,8 +7486,8 @@ static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, return ASC_ERROR; } - asc_sg_head = kzalloc(struct_size(asc_sg_head, sg_list, use_sg), - GFP_ATOMIC); + asc_sg_head = kzalloc_flex(*asc_sg_head, sg_list, use_sg, + GFP_ATOMIC); if (!asc_sg_head) { scsi_dma_unmap(scp); set_host_byte(scp, DID_SOFT_ERROR); @@ -11314,7 +11314,7 @@ static int advansys_eisa_probe(struct device *dev) struct eisa_scsi_data *data; err = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto fail; ioport = edev->base_addr + 0xc30; diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 6b87ea004e53..3602a1fc40e4 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c @@ -3604,7 +3604,7 @@ ahd_alloc_tstate(struct ahd_softc *ahd, u_int scsi_id, char channel) && ahd->enabled_targets[scsi_id] != master_tstate) panic("%s: ahd_alloc_tstate - Target already allocated", ahd_name(ahd)); - tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC); + tstate = kmalloc_obj(*tstate, GFP_ATOMIC); if (tstate == NULL) return (NULL); @@ -6037,14 +6037,14 @@ ahd_alloc(void *platform_arg, char *name) { struct ahd_softc *ahd; - ahd = kzalloc(sizeof(*ahd), GFP_ATOMIC); + ahd = kzalloc_obj(*ahd, GFP_ATOMIC); if (!ahd) { printk("aic7xxx: cannot malloc softc!\n"); kfree(name); return NULL; } - ahd->seep_config = kmalloc(sizeof(*ahd->seep_config), GFP_ATOMIC); + ahd->seep_config = kmalloc_obj(*ahd->seep_config, GFP_ATOMIC); if (ahd->seep_config == NULL) { kfree(ahd); kfree(name); @@ -6777,7 +6777,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd) hscb = &((struct hardware_scb *)hscb_map->vaddr)[offset]; hscb_busaddr = hscb_map->physaddr + (offset * sizeof(*hscb)); } else { - hscb_map = kmalloc(sizeof(*hscb_map), GFP_ATOMIC); + hscb_map = kmalloc_obj(*hscb_map, GFP_ATOMIC); if (hscb_map == NULL) return; @@ -6810,7 +6810,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd) segs = sg_map->vaddr + offset; sg_busaddr = sg_map->physaddr + offset; } else { - sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC); + sg_map = kmalloc_obj(*sg_map, GFP_ATOMIC); if (sg_map == NULL) return; @@ -6847,7 +6847,7 @@ ahd_alloc_scbs(struct ahd_softc *ahd) sense_data = sense_map->vaddr + offset; sense_busaddr = sense_map->physaddr + offset; } else { - sense_map = kmalloc(sizeof(*sense_map), GFP_ATOMIC); + sense_map = kmalloc_obj(*sense_map, GFP_ATOMIC); if (sense_map == NULL) return; @@ -6882,11 +6882,11 @@ ahd_alloc_scbs(struct ahd_softc *ahd) struct scb_platform_data *pdata; u_int col_tag; - next_scb = kmalloc(sizeof(*next_scb), GFP_ATOMIC); + next_scb = kmalloc_obj(*next_scb, GFP_ATOMIC); if (next_scb == NULL) break; - pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC); + pdata = kmalloc_obj(*pdata, GFP_ATOMIC); if (pdata == NULL) { kfree(next_scb); break; @@ -10339,7 +10339,7 @@ ahd_handle_en_lun(struct ahd_softc *ahd, struct cam_sim *sim, union ccb *ccb) return; } } - lstate = kzalloc(sizeof(*lstate), GFP_ATOMIC); + lstate = kzalloc_obj(*lstate, GFP_ATOMIC); if (lstate == NULL) { xpt_print_path(ccb->ccb_h.path); printk("Couldn't allocate lstate\n"); diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index c8b6dc48300a..feb1707feb7e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -923,7 +923,7 @@ ahd_dma_tag_create(struct ahd_softc *ahd, bus_dma_tag_t parent, { bus_dma_tag_t dmat; - dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC); + dmat = kmalloc_obj(*dmat, GFP_ATOMIC); if (dmat == NULL) return (ENOMEM); @@ -1309,7 +1309,7 @@ int ahd_platform_alloc(struct ahd_softc *ahd, void *platform_arg) { ahd->platform_data = - kzalloc(sizeof(struct ahd_platform_data), GFP_ATOMIC); + kzalloc_obj(struct ahd_platform_data, GFP_ATOMIC); if (ahd->platform_data == NULL) return (ENOMEM); ahd->platform_data->irq = AHD_LINUX_NOIRQ; diff --git a/drivers/scsi/aic7xxx/aic79xx_proc.c b/drivers/scsi/aic7xxx/aic79xx_proc.c index 746d0ca2a657..aa37838b78a6 100644 --- a/drivers/scsi/aic7xxx/aic79xx_proc.c +++ b/drivers/scsi/aic7xxx/aic79xx_proc.c @@ -242,8 +242,8 @@ ahd_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length) u_int start_addr; if (ahd->seep_config == NULL) { - ahd->seep_config = kmalloc(sizeof(*ahd->seep_config), - GFP_ATOMIC); + ahd->seep_config = kmalloc_obj(*ahd->seep_config, + GFP_ATOMIC); if (ahd->seep_config == NULL) { printk("aic79xx: Unable to allocate serial " "eeprom buffer. Write failing\n"); diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index a396f048a031..b9761f9f0bbc 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c @@ -2128,7 +2128,7 @@ ahc_alloc_tstate(struct ahc_softc *ahc, u_int scsi_id, char channel) && ahc->enabled_targets[scsi_id] != master_tstate) panic("%s: ahc_alloc_tstate - Target already allocated", ahc_name(ahc)); - tstate = kmalloc(sizeof(*tstate), GFP_ATOMIC); + tstate = kmalloc_obj(*tstate, GFP_ATOMIC); if (tstate == NULL) return (NULL); @@ -4381,14 +4381,14 @@ ahc_alloc(void *platform_arg, char *name) struct ahc_softc *ahc; int i; - ahc = kzalloc(sizeof(*ahc), GFP_ATOMIC); + ahc = kzalloc_obj(*ahc, GFP_ATOMIC); if (!ahc) { printk("aic7xxx: cannot malloc softc!\n"); kfree(name); return NULL; } - ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), GFP_ATOMIC); + ahc->seep_config = kmalloc_obj(*ahc->seep_config, GFP_ATOMIC); if (ahc->seep_config == NULL) { kfree(ahc); kfree(name); @@ -4433,7 +4433,7 @@ ahc_softc_init(struct ahc_softc *ahc) ahc->pause = ahc->unpause | PAUSE; /* XXX The shared scb data stuff should be deprecated */ if (ahc->scb_data == NULL) { - ahc->scb_data = kzalloc(sizeof(*ahc->scb_data), GFP_ATOMIC); + ahc->scb_data = kzalloc_obj(*ahc->scb_data, GFP_ATOMIC); if (ahc->scb_data == NULL) return (ENOMEM); } @@ -4738,8 +4738,8 @@ ahc_init_scbdata(struct ahc_softc *ahc) SLIST_INIT(&scb_data->sg_maps); /* Allocate SCB resources */ - scb_data->scbarray = kcalloc(AHC_SCB_MAX_ALLOC, sizeof(struct scb), - GFP_ATOMIC); + scb_data->scbarray = kzalloc_objs(struct scb, AHC_SCB_MAX_ALLOC, + GFP_ATOMIC); if (scb_data->scbarray == NULL) return (ENOMEM); @@ -4943,7 +4943,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc) next_scb = &scb_data->scbarray[scb_data->numscbs]; - sg_map = kmalloc(sizeof(*sg_map), GFP_ATOMIC); + sg_map = kmalloc_obj(*sg_map, GFP_ATOMIC); if (sg_map == NULL) return; @@ -4970,7 +4970,7 @@ ahc_alloc_scbs(struct ahc_softc *ahc) for (i = 0; i < newcount; i++) { struct scb_platform_data *pdata; - pdata = kmalloc(sizeof(*pdata), GFP_ATOMIC); + pdata = kmalloc_obj(*pdata, GFP_ATOMIC); if (pdata == NULL) break; next_scb->platform_data = pdata; @@ -7488,7 +7488,7 @@ ahc_handle_en_lun(struct ahc_softc *ahc, struct cam_sim *sim, union ccb *ccb) return; } } - lstate = kzalloc(sizeof(*lstate), GFP_ATOMIC); + lstate = kzalloc_obj(*lstate, GFP_ATOMIC); if (lstate == NULL) { xpt_print_path(ccb->ccb_h.path); printk("Couldn't allocate lstate\n"); diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index c71f80f8fa34..d93b522695eb 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -823,7 +823,7 @@ ahc_dma_tag_create(struct ahc_softc *ahc, bus_dma_tag_t parent, { bus_dma_tag_t dmat; - dmat = kmalloc(sizeof(*dmat), GFP_ATOMIC); + dmat = kmalloc_obj(*dmat, GFP_ATOMIC); if (dmat == NULL) return (ENOMEM); @@ -1201,7 +1201,7 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) { ahc->platform_data = - kzalloc(sizeof(struct ahc_platform_data), GFP_ATOMIC); + kzalloc_obj(struct ahc_platform_data, GFP_ATOMIC); if (ahc->platform_data == NULL) return (ENOMEM); ahc->platform_data->irq = AHC_LINUX_NOIRQ; diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 4bc9e2dfccf6..3b2ba7b4d61b 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c @@ -255,8 +255,8 @@ ahc_proc_write_seeprom(struct Scsi_Host *shost, char *buffer, int length) u_int start_addr; if (ahc->seep_config == NULL) { - ahc->seep_config = kmalloc(sizeof(*ahc->seep_config), - GFP_ATOMIC); + ahc->seep_config = kmalloc_obj(*ahc->seep_config, + GFP_ATOMIC); if (ahc->seep_config == NULL) { printk("aic7xxx: Unable to allocate serial " "eeprom buffer. Write failing\n"); diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c index e74393357025..caa9d7143894 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.c +++ b/drivers/scsi/aic94xx/aic94xx_hwi.c @@ -272,8 +272,7 @@ static int asd_alloc_edbs(struct asd_ha_struct *asd_ha, gfp_t gfp_flags) struct asd_seq_data *seq = &asd_ha->seq; int i; - seq->edb_arr = kmalloc_array(seq->num_edbs, sizeof(*seq->edb_arr), - gfp_flags); + seq->edb_arr = kmalloc_objs(*seq->edb_arr, seq->num_edbs, gfp_flags); if (!seq->edb_arr) return -ENOMEM; @@ -305,8 +304,7 @@ static int asd_alloc_escbs(struct asd_ha_struct *asd_ha, struct asd_ascb *escb; int i, escbs; - seq->escb_arr = kmalloc_array(seq->num_escbs, sizeof(*seq->escb_arr), - gfp_flags); + seq->escb_arr = kmalloc_objs(*seq->escb_arr, seq->num_escbs, gfp_flags); if (!seq->escb_arr) return -ENOMEM; diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 95f3620059f7..4400a3661d90 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c @@ -642,9 +642,9 @@ static int asd_register_sas_ha(struct asd_ha_struct *asd_ha) { int i; struct asd_sas_phy **sas_phys = - kcalloc(ASD_MAX_PHYS, sizeof(*sas_phys), GFP_KERNEL); + kzalloc_objs(*sas_phys, ASD_MAX_PHYS); struct asd_sas_port **sas_ports = - kcalloc(ASD_MAX_PHYS, sizeof(*sas_ports), GFP_KERNEL); + kzalloc_objs(*sas_ports, ASD_MAX_PHYS); if (!sas_phys || !sas_ports) { kfree(sas_phys); @@ -710,7 +710,7 @@ static int asd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) asd_dev = &asd_pcidev_data[asd_id]; - asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); + asd_ha = kzalloc_obj(*asd_ha); if (!asd_ha) { asd_printk("out of memory\n"); goto Err_put; diff --git a/drivers/scsi/aic94xx/aic94xx_sds.c b/drivers/scsi/aic94xx/aic94xx_sds.c index 5def83c88f13..57818393f9f0 100644 --- a/drivers/scsi/aic94xx/aic94xx_sds.c +++ b/drivers/scsi/aic94xx/aic94xx_sds.c @@ -207,7 +207,7 @@ static int asd_get_bios_chim(struct asd_ha_struct *asd_ha, goto out; } err = -ENOMEM; - bc_struct = kmalloc(sizeof(*bc_struct), GFP_KERNEL); + bc_struct = kmalloc_obj(*bc_struct); if (!bc_struct) { asd_printk("no memory for bios_chim struct\n"); goto out; @@ -341,7 +341,7 @@ int asd_read_ocm(struct asd_ha_struct *asd_ha) if (asd_hwi_check_ocm_access(asd_ha)) return -1; - dir = kmalloc(sizeof(*dir), GFP_KERNEL); + dir = kmalloc_obj(*dir); if (!dir) { asd_printk("no memory for ocm dir\n"); return -ENOMEM; @@ -1040,7 +1040,7 @@ int asd_read_flash(struct asd_ha_struct *asd_ha) if (err) return err; - flash_dir = kmalloc(sizeof(*flash_dir), GFP_KERNEL); + flash_dir = kmalloc_obj(*flash_dir); if (!flash_dir) return -ENOMEM; diff --git a/drivers/scsi/am53c974.c b/drivers/scsi/am53c974.c index 003e61831e33..f972a3c90a2f 100644 --- a/drivers/scsi/am53c974.c +++ b/drivers/scsi/am53c974.c @@ -396,7 +396,7 @@ static int pci_esp_probe_one(struct pci_dev *pdev, goto fail_disable_device; } - pep = kzalloc(sizeof(struct pci_esp_priv), GFP_KERNEL); + pep = kzalloc_obj(struct pci_esp_priv); if (!pep) { dev_printk(KERN_INFO, &pdev->dev, "failed to allocate esp_priv\n"); diff --git a/drivers/scsi/arm/queue.c b/drivers/scsi/arm/queue.c index 978df23ce188..797cf4971f5d 100644 --- a/drivers/scsi/arm/queue.c +++ b/drivers/scsi/arm/queue.c @@ -71,7 +71,7 @@ int queue_initialise (Queue_t *queue) * need to keep free lists or allocate this * memory. */ - queue->alloc = q = kmalloc_array(nqueues, sizeof(QE_t), GFP_KERNEL); + queue->alloc = q = kmalloc_objs(QE_t, nqueues); if (q) { for (; nqueues; q++, nqueues--) { SET_MAGIC(q, QUEUE_MAGIC_FREE); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index a0e794ffc980..fd18d4d3d219 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -303,7 +303,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc) beiscsi_conn = conn->dd_data; phba = beiscsi_conn->phba; - inv_tbl = kzalloc(sizeof(*inv_tbl), GFP_ATOMIC); + inv_tbl = kzalloc_obj(*inv_tbl, GFP_ATOMIC); if (!inv_tbl) { spin_unlock_bh(&session->frwd_lock); beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_EH, @@ -2476,25 +2476,21 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) /* Allocate memory for wrb_context */ phwi_ctrlr = phba->phwi_ctrlr; - phwi_ctrlr->wrb_context = kcalloc(phba->params.cxns_per_ctrl, - sizeof(struct hwi_wrb_context), - GFP_KERNEL); + phwi_ctrlr->wrb_context = kzalloc_objs(struct hwi_wrb_context, + phba->params.cxns_per_ctrl); if (!phwi_ctrlr->wrb_context) { kfree(phba->phwi_ctrlr); return -ENOMEM; } - phba->init_mem = kcalloc(SE_MEM_MAX, sizeof(*mem_descr), - GFP_KERNEL); + phba->init_mem = kzalloc_objs(*mem_descr, SE_MEM_MAX); if (!phba->init_mem) { kfree(phwi_ctrlr->wrb_context); kfree(phba->phwi_ctrlr); return -ENOMEM; } - mem_arr_orig = kmalloc_array(BEISCSI_MAX_FRAGS_INIT, - sizeof(*mem_arr_orig), - GFP_KERNEL); + mem_arr_orig = kmalloc_objs(*mem_arr_orig, BEISCSI_MAX_FRAGS_INIT); if (!mem_arr_orig) { kfree(phba->init_mem); kfree(phwi_ctrlr->wrb_context); @@ -2542,8 +2538,7 @@ static int beiscsi_alloc_mem(struct beiscsi_hba *phba) } while (alloc_size); mem_descr->num_elements = j; mem_descr->size_in_bytes = phba->mem_req[i]; - mem_descr->mem_array = kmalloc_array(j, sizeof(*mem_arr), - GFP_KERNEL); + mem_descr->mem_array = kmalloc_objs(*mem_arr, j); if (!mem_descr->mem_array) goto free_mem; @@ -2629,9 +2624,8 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) /* Allocate memory for WRBQ */ phwi_ctxt = phwi_ctrlr->phwi_ctxt; - phwi_ctxt->be_wrbq = kcalloc(phba->params.cxns_per_ctrl, - sizeof(struct be_queue_info), - GFP_KERNEL); + phwi_ctxt->be_wrbq = kzalloc_objs(struct be_queue_info, + phba->params.cxns_per_ctrl); if (!phwi_ctxt->be_wrbq) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : WRBQ Mem Alloc Failed\n"); @@ -2641,18 +2635,16 @@ static int beiscsi_init_wrb_handle(struct beiscsi_hba *phba) for (index = 0; index < phba->params.cxns_per_ctrl; index++) { pwrb_context = &phwi_ctrlr->wrb_context[index]; pwrb_context->pwrb_handle_base = - kcalloc(phba->params.wrbs_per_cxn, - sizeof(struct wrb_handle *), - GFP_KERNEL); + kzalloc_objs(struct wrb_handle *, + phba->params.wrbs_per_cxn); if (!pwrb_context->pwrb_handle_base) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); goto init_wrb_hndl_failed; } pwrb_context->pwrb_handle_basestd = - kcalloc(phba->params.wrbs_per_cxn, - sizeof(struct wrb_handle *), - GFP_KERNEL); + kzalloc_objs(struct wrb_handle *, + phba->params.wrbs_per_cxn); if (!pwrb_context->pwrb_handle_basestd) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); @@ -3363,9 +3355,7 @@ beiscsi_create_wrb_rings(struct beiscsi_hba *phba, idx = 0; mem_descr = phba->init_mem; mem_descr += HWI_MEM_WRB; - pwrb_arr = kmalloc_array(phba->params.cxns_per_ctrl, - sizeof(*pwrb_arr), - GFP_KERNEL); + pwrb_arr = kmalloc_objs(*pwrb_arr, phba->params.cxns_per_ctrl); if (!pwrb_arr) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Memory alloc failed in create wrb ring.\n"); @@ -3902,18 +3892,16 @@ static int beiscsi_init_sgl_handle(struct beiscsi_hba *phba) mem_descr_sglh = phba->init_mem; mem_descr_sglh += HWI_MEM_SGLH; if (1 == mem_descr_sglh->num_elements) { - phba->io_sgl_hndl_base = kcalloc(phba->params.ios_per_ctrl, - sizeof(struct sgl_handle *), - GFP_KERNEL); + phba->io_sgl_hndl_base = kzalloc_objs(struct sgl_handle *, + phba->params.ios_per_ctrl); if (!phba->io_sgl_hndl_base) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, "BM_%d : Mem Alloc Failed. Failing to load\n"); return -ENOMEM; } phba->eh_sgl_hndl_base = - kcalloc(phba->params.icds_per_ctrl - - phba->params.ios_per_ctrl, - sizeof(struct sgl_handle *), GFP_KERNEL); + kzalloc_objs(struct sgl_handle *, + phba->params.icds_per_ctrl - phba->params.ios_per_ctrl); if (!phba->eh_sgl_hndl_base) { kfree(phba->io_sgl_hndl_base); beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT, @@ -4004,8 +3992,7 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) for (ulp_num = 0; ulp_num < BEISCSI_ULP_COUNT; ulp_num++) { if (test_bit(ulp_num, (void *)&phba->fw_config.ulp_supported)) { - ptr_cid_info = kzalloc(sizeof(struct ulp_cid_info), - GFP_KERNEL); + ptr_cid_info = kzalloc_obj(struct ulp_cid_info); if (!ptr_cid_info) { ret = -ENOMEM; @@ -4031,18 +4018,16 @@ static int hba_setup_cid_tbls(struct beiscsi_hba *phba) phba->cid_array_info[ulp_num] = ptr_cid_info; } } - phba->ep_array = kcalloc(phba->params.cxns_per_ctrl, - sizeof(struct iscsi_endpoint *), - GFP_KERNEL); + phba->ep_array = kzalloc_objs(struct iscsi_endpoint *, + phba->params.cxns_per_ctrl); if (!phba->ep_array) { ret = -ENOMEM; goto free_memory; } - phba->conn_table = kcalloc(phba->params.cxns_per_ctrl, - sizeof(struct beiscsi_conn *), - GFP_KERNEL); + phba->conn_table = kzalloc_objs(struct beiscsi_conn *, + phba->params.cxns_per_ctrl); if (!phba->conn_table) { kfree(phba->ep_array); phba->ep_array = NULL; diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 9a85f417018f..2df399c537c1 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -1863,7 +1863,7 @@ bfa_fcs_lport_fdmi_build_rhba_pyld(struct bfa_fcs_lport_fdmi_s *fdmi, u8 *pyld) u8 *curr_ptr; u16 templen, count; - fcs_hba_attr = kzalloc(sizeof(*fcs_hba_attr), GFP_KERNEL); + fcs_hba_attr = kzalloc_obj(*fcs_hba_attr); if (!fcs_hba_attr) return -ENOMEM; diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index bdfd06516671..448f736457f0 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -473,7 +473,7 @@ bfa_fcb_rport_alloc(struct bfad_s *bfad, struct bfa_fcs_rport_s **rport, { bfa_status_t rc = BFA_STATUS_OK; - *rport_drv = kzalloc(sizeof(struct bfad_rport_s), GFP_ATOMIC); + *rport_drv = kzalloc_obj(struct bfad_rport_s, GFP_ATOMIC); if (*rport_drv == NULL) { rc = BFA_STATUS_ENOMEM; goto ext; @@ -496,7 +496,7 @@ bfa_fcb_pbc_vport_create(struct bfad_s *bfad, struct bfi_pbc_vport_s pbc_vport) struct bfad_vport_s *vport; int rc; - vport = kzalloc(sizeof(struct bfad_vport_s), GFP_ATOMIC); + vport = kzalloc_obj(struct bfad_vport_s, GFP_ATOMIC); if (!vport) { bfa_trc(bfad, 0); return; @@ -640,7 +640,7 @@ bfad_vport_create(struct bfad_s *bfad, u16 vf_id, unsigned long flags; struct completion fcomp; - vport = kzalloc(sizeof(struct bfad_vport_s), GFP_KERNEL); + vport = kzalloc_obj(struct bfad_vport_s); if (!vport) { rc = BFA_STATUS_ENOMEM; goto ext; @@ -1271,13 +1271,13 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) (PCI_FUNC(pdev->devfn) != 0)) return -ENODEV; - bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL); + bfad = kzalloc_obj(struct bfad_s); if (!bfad) { error = -ENOMEM; goto out; } - bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL); + bfad->trcmod = kzalloc_obj(struct bfa_trc_mod_s); if (!bfad->trcmod) { printk(KERN_WARNING "Error alloc trace buffer!\n"); error = -ENOMEM; diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 54bc1539e1e9..9751beff817d 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -264,7 +264,7 @@ bfad_im_get_stats(struct Scsi_Host *shost) bfa_status_t rc; unsigned long flags; - fcstats = kzalloc(sizeof(union bfa_port_stats_u), GFP_KERNEL); + fcstats = kzalloc_obj(union bfa_port_stats_u); if (fcstats == NULL) return NULL; @@ -907,8 +907,7 @@ bfad_im_num_of_discovered_ports_show(struct device *dev, struct bfa_rport_qualifier_s *rports = NULL; unsigned long flags; - rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s), - GFP_ATOMIC); + rports = kzalloc_objs(struct bfa_rport_qualifier_s, nrports, GFP_ATOMIC); if (rports == NULL) return sysfs_emit(buf, "Failed\n"); diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 54bd11e6d593..292bc9aa43f1 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -3410,7 +3410,7 @@ bfad_im_bsg_els_ct_request(struct bsg_job *job) goto out; } - drv_fcxp = kzalloc(sizeof(struct bfad_fcxp), GFP_KERNEL); + drv_fcxp = kzalloc_obj(struct bfad_fcxp); if (drv_fcxp == NULL) { kfree(bsg_fcpt); rc = -ENOMEM; diff --git a/drivers/scsi/bfa/bfad_debugfs.c b/drivers/scsi/bfa/bfad_debugfs.c index f6dd077d47c9..2f9bb8fa7fa7 100644 --- a/drivers/scsi/bfa/bfad_debugfs.c +++ b/drivers/scsi/bfa/bfad_debugfs.c @@ -46,7 +46,7 @@ bfad_debugfs_open_drvtrc(struct inode *inode, struct file *file) struct bfad_s *bfad = port->bfad; struct bfad_debug_info *debug; - debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL); + debug = kzalloc_obj(struct bfad_debug_info); if (!debug) return -ENOMEM; @@ -67,7 +67,7 @@ bfad_debugfs_open_fwtrc(struct inode *inode, struct file *file) unsigned long flags; int rc; - fw_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL); + fw_debug = kzalloc_obj(struct bfad_debug_info); if (!fw_debug) return -ENOMEM; @@ -109,7 +109,7 @@ bfad_debugfs_open_fwsave(struct inode *inode, struct file *file) unsigned long flags; int rc; - fw_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL); + fw_debug = kzalloc_obj(struct bfad_debug_info); if (!fw_debug) return -ENOMEM; @@ -147,7 +147,7 @@ bfad_debugfs_open_reg(struct inode *inode, struct file *file) { struct bfad_debug_info *reg_debug; - reg_debug = kzalloc(sizeof(struct bfad_debug_info), GFP_KERNEL); + reg_debug = kzalloc_obj(struct bfad_debug_info); if (!reg_debug) return -ENOMEM; diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 6c84982c4726..97990b285e17 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c @@ -426,7 +426,7 @@ int bfa_fcb_itnim_alloc(struct bfad_s *bfad, struct bfa_fcs_itnim_s **itnim, struct bfad_itnim_s **itnim_drv) { - *itnim_drv = kzalloc(sizeof(struct bfad_itnim_s), GFP_ATOMIC); + *itnim_drv = kzalloc_obj(struct bfad_itnim_s, GFP_ATOMIC); if (*itnim_drv == NULL) return -ENOMEM; @@ -622,7 +622,7 @@ bfad_im_port_new(struct bfad_s *bfad, struct bfad_port_s *port) int rc = BFA_STATUS_OK; struct bfad_im_port_s *im_port; - im_port = kzalloc(sizeof(struct bfad_im_port_s), GFP_ATOMIC); + im_port = kzalloc_obj(struct bfad_im_port_s, GFP_ATOMIC); if (im_port == NULL) { rc = BFA_STATUS_ENOMEM; goto ext; @@ -698,7 +698,7 @@ bfad_im_probe(struct bfad_s *bfad) { struct bfad_im_s *im; - im = kzalloc(sizeof(struct bfad_im_s), GFP_KERNEL); + im = kzalloc_obj(struct bfad_im_s); if (im == NULL) return BFA_STATUS_ENOMEM; @@ -994,7 +994,7 @@ bfad_im_supported_speeds(struct bfa_s *bfa) struct bfa_ioc_attr_s *ioc_attr; u32 supported_speed = 0; - ioc_attr = kzalloc(sizeof(struct bfa_ioc_attr_s), GFP_KERNEL); + ioc_attr = kzalloc_obj(struct bfa_ioc_attr_s); if (!ioc_attr) return 0; diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index 754f2e82d955..749e30aaf926 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -80,7 +80,7 @@ int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req) aborted_io_req->xid); memset(&rrq, 0, sizeof(rrq)); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_NOIO); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for RRQ\n"); rc = -ENOMEM; @@ -189,7 +189,7 @@ int bnx2fc_send_adisc(struct bnx2fc_rport *tgt, struct fc_frame *fp) int rc; fh = fc_frame_header_get(fp); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for ADISC\n"); return -ENOMEM; @@ -217,7 +217,7 @@ int bnx2fc_send_logo(struct bnx2fc_rport *tgt, struct fc_frame *fp) int rc; fh = fc_frame_header_get(fp); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n"); return -ENOMEM; @@ -245,7 +245,7 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp) int rc; fh = fc_frame_header_get(fp); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for LOGO\n"); return -ENOMEM; @@ -592,7 +592,7 @@ int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req) BNX2FC_IO_DBG(orig_io_req, "Sending REC\n"); memset(&rec, 0, sizeof(rec)); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for REC\n"); rc = -ENOMEM; @@ -633,7 +633,7 @@ int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl) BNX2FC_IO_DBG(orig_io_req, "Sending SRR\n"); memset(&srr, 0, sizeof(srr)); - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to allocate cb_arg for SRR\n"); rc = -ENOMEM; diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c index 0f68739d380a..26e0ff380860 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c @@ -1356,7 +1356,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) struct fcoe_capabilities *fcoe_cap; int rc; - hba = kzalloc(sizeof(*hba), GFP_KERNEL); + hba = kzalloc_obj(*hba); if (!hba) { printk(KERN_ERR PFX "Unable to allocate hba structure\n"); return NULL; @@ -1381,8 +1381,7 @@ static struct bnx2fc_hba *bnx2fc_hba_create(struct cnic_dev *cnic) hba->next_conn_id = 0; hba->tgt_ofld_list = - kcalloc(BNX2FC_NUM_MAX_SESS, sizeof(struct bnx2fc_rport *), - GFP_KERNEL); + kzalloc_objs(struct bnx2fc_rport *, BNX2FC_NUM_MAX_SESS); if (!hba->tgt_ofld_list) { printk(KERN_ERR PFX "Unable to allocate tgt offload list\n"); goto tgtofld_err; @@ -1492,7 +1491,7 @@ static struct fc_lport *bnx2fc_if_create(struct bnx2fc_interface *interface, struct bnx2fc_hba *hba = interface->hba; int rc = 0; - blport = kzalloc(sizeof(struct bnx2fc_lport), GFP_KERNEL); + blport = kzalloc_obj(struct bnx2fc_lport); if (!blport) { BNX2FC_HBA_DBG(ctlr->lp, "Unable to alloc blport\n"); return NULL; @@ -2200,7 +2199,7 @@ static int __bnx2fc_enable(struct fcoe_ctlr *ctlr) if (!hba->cnic->get_fc_npiv_tbl) goto done; - npiv_tbl = kzalloc(sizeof(struct cnic_fc_npiv_tbl), GFP_KERNEL); + npiv_tbl = kzalloc_obj(struct cnic_fc_npiv_tbl); if (!npiv_tbl) goto done; diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index 090d436bcef8..a5ecb87d5b2d 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -561,7 +561,7 @@ void bnx2fc_process_l2_frame_compl(struct bnx2fc_rport *tgt, u8 op; - unsol_els = kzalloc(sizeof(*unsol_els), GFP_ATOMIC); + unsol_els = kzalloc_obj(*unsol_els, GFP_ATOMIC); if (!unsol_els) { BNX2FC_TGT_DBG(tgt, "Unable to allocate unsol_work\n"); return; @@ -972,7 +972,7 @@ static struct bnx2fc_work *bnx2fc_alloc_work(struct bnx2fc_rport *tgt, u16 wqe, struct fcoe_task_ctx_entry *task) { struct bnx2fc_work *work; - work = kzalloc(sizeof(struct bnx2fc_work), GFP_ATOMIC); + work = kzalloc_obj(struct bnx2fc_work, GFP_ATOMIC); if (!work) return NULL; diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 90b2b54c549a..9c7a541a4523 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -241,15 +241,13 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) } cmgr->hba = hba; - cmgr->free_list = kcalloc(arr_sz, sizeof(*cmgr->free_list), - GFP_KERNEL); + cmgr->free_list = kzalloc_objs(*cmgr->free_list, arr_sz); if (!cmgr->free_list) { printk(KERN_ERR PFX "failed to alloc free_list\n"); goto mem_err; } - cmgr->free_list_lock = kcalloc(arr_sz, sizeof(*cmgr->free_list_lock), - GFP_KERNEL); + cmgr->free_list_lock = kzalloc_objs(*cmgr->free_list_lock, arr_sz); if (!cmgr->free_list_lock) { printk(KERN_ERR PFX "failed to alloc free_list_lock\n"); kfree(cmgr->free_list); @@ -272,7 +270,7 @@ struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba) xid = BNX2FC_MIN_XID; num_pri_ios = num_ios - hba->elstm_xids; for (i = 0; i < num_ios; i++) { - io_req = kzalloc(sizeof(*io_req), GFP_KERNEL); + io_req = kzalloc_obj(*io_req); if (!io_req) { printk(KERN_ERR PFX "failed to alloc io_req\n"); @@ -942,7 +940,7 @@ int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset, port = orig_io_req->port; interface = port->priv; - cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(struct bnx2fc_els_cb_arg, GFP_ATOMIC); if (!cb_arg) { printk(KERN_ERR PFX "Unable to alloc cb_arg for seq clnup\n"); rc = -ENOMEM; diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index 40db5190a222..d24cc2c795d6 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -1925,7 +1925,7 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session, goto err; } /* Alloc and copy to the cqe */ - bnx2i_work = kzalloc(sizeof(struct bnx2i_work), GFP_ATOMIC); + bnx2i_work = kzalloc_obj(struct bnx2i_work, GFP_ATOMIC); if (bnx2i_work) { INIT_LIST_HEAD(&bnx2i_work->list); bnx2i_work->session = session; diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index baf5f4e47937..23301edf100d 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c @@ -44,7 +44,7 @@ bvme6000_probe(struct platform_device *dev) if (!MACH_IS_BVME6000) goto out; - hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + hostdata = kzalloc_obj(struct NCR_700_Host_Parameters); if (!hostdata) { printk(KERN_ERR "bvme6000-scsi: " "Failed to allocate host data\n"); diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index b6ca23a29ef5..4010fdbf813c 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -364,8 +364,7 @@ ch_readconfig(scsi_changer *ch) } /* look up the devices of the data transfer elements */ - ch->dt = kcalloc(ch->counts[CHET_DT], sizeof(*ch->dt), - GFP_KERNEL); + ch->dt = kzalloc_objs(*ch->dt, ch->counts[CHET_DT]); if (!ch->dt) { kfree(buffer); @@ -904,7 +903,7 @@ static int ch_probe(struct scsi_device *sd) if (sd->type != TYPE_MEDIUM_CHANGER) return -ENODEV; - ch = kzalloc(sizeof(*ch), GFP_KERNEL); + ch = kzalloc_obj(*ch); if (NULL == ch) return -ENOMEM; diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 7aa418ebfe01..df9f81f29950 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -2429,7 +2429,7 @@ csio_hw_flash_fw(struct csio_hw *hw, int *reset) /* allocate memory to read the header of the firmware on the * card */ - card_fw = kmalloc(sizeof(*card_fw), GFP_KERNEL); + card_fw = kmalloc_obj(*card_fw); if (!card_fw) return -ENOMEM; @@ -4389,7 +4389,7 @@ csio_hw_init(struct csio_hw *hw) INIT_LIST_HEAD(&hw->evt_free_q); for (i = 0; i < csio_evtq_sz; i++) { - evt_entry = kzalloc(sizeof(struct csio_evt_msg), GFP_KERNEL); + evt_entry = kzalloc_obj(struct csio_evt_msg); if (!evt_entry) { rv = -ENOMEM; csio_err(hw, "Failed to initialize eventq"); diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c index db0c2174430a..238431524801 100644 --- a/drivers/scsi/csiostor/csio_init.c +++ b/drivers/scsi/csiostor/csio_init.c @@ -516,7 +516,7 @@ static struct csio_hw *csio_hw_alloc(struct pci_dev *pdev) { struct csio_hw *hw; - hw = kzalloc(sizeof(struct csio_hw), GFP_KERNEL); + hw = kzalloc_obj(struct csio_hw); if (!hw) goto err; diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 6cc1d53165a0..78d5ecd14f65 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -1837,7 +1837,7 @@ csio_ln_fdmi_init(struct csio_lnode *ln) struct csio_dma_buf *dma_buf; /* Allocate MGMT request required for FDMI */ - ln->mgmt_req = kzalloc(sizeof(struct csio_ioreq), GFP_KERNEL); + ln->mgmt_req = kzalloc_obj(struct csio_ioreq); if (!ln->mgmt_req) { csio_ln_err(ln, "Failed to alloc ioreq for FDMI\n"); CSIO_INC_STATS(hw, n_err_nomem); @@ -2002,7 +2002,7 @@ csio_ln_init(struct csio_lnode *ln) /* This is the lnode used during initialization */ - ln->fcfinfo = kzalloc(sizeof(struct csio_fcf_info), GFP_KERNEL); + ln->fcfinfo = kzalloc_obj(struct csio_fcf_info); if (!ln->fcfinfo) { csio_ln_err(ln, "Failed to alloc FCF record\n"); CSIO_INC_STATS(hw, n_err_nomem); @@ -2029,8 +2029,7 @@ csio_ln_init(struct csio_lnode *ln) ln->fcfinfo = pln->fcfinfo; } else { /* Another non-root physical lnode (FCF) */ - ln->fcfinfo = kzalloc(sizeof(struct csio_fcf_info), - GFP_KERNEL); + ln->fcfinfo = kzalloc_obj(struct csio_fcf_info); if (!ln->fcfinfo) { csio_ln_err(ln, "Failed to alloc FCF info\n"); CSIO_INC_STATS(hw, n_err_nomem); diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index 05137784f369..b1de615cf316 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -2341,7 +2341,7 @@ csio_scsi_alloc_ddp_bufs(struct csio_scsim *scm, struct csio_hw *hw, for (n = 0; n < num_buf; n++) { /* Set unit size to request size */ unit_size = buf_size; - ddp_desc = kzalloc(sizeof(struct csio_dma_buf), GFP_KERNEL); + ddp_desc = kzalloc_obj(struct csio_dma_buf); if (!ddp_desc) { csio_err(hw, "Failed to allocate ddp descriptors," @@ -2435,7 +2435,7 @@ csio_scsim_init(struct csio_scsim *scm, struct csio_hw *hw) INIT_LIST_HEAD(&scm->ioreq_freelist); for (i = 0; i < csio_scsi_ioreqs; i++) { - ioreq = kzalloc(sizeof(struct csio_ioreq), GFP_KERNEL); + ioreq = kzalloc_obj(struct csio_ioreq); if (!ioreq) { csio_err(hw, "I/O request element allocation failed, " diff --git a/drivers/scsi/csiostor/csio_wr.c b/drivers/scsi/csiostor/csio_wr.c index 010a1df37f15..aa6007a21868 100644 --- a/drivers/scsi/csiostor/csio_wr.c +++ b/drivers/scsi/csiostor/csio_wr.c @@ -278,9 +278,8 @@ csio_wr_alloc_q(struct csio_hw *hw, uint32_t qsize, uint32_t wrsize, q->un.iq.flq_idx = flq_idx; flq = wrm->q_arr[q->un.iq.flq_idx]; - flq->un.fl.bufs = kcalloc(flq->credits, - sizeof(struct csio_dma_buf), - GFP_KERNEL); + flq->un.fl.bufs = kzalloc_objs(struct csio_dma_buf, + flq->credits); if (!flq->un.fl.bufs) { csio_err(hw, "Failed to allocate FL queue bufs" @@ -1651,12 +1650,12 @@ csio_wrm_init(struct csio_wrm *wrm, struct csio_hw *hw) return -EINVAL; } - wrm->q_arr = kcalloc(wrm->num_q, sizeof(struct csio_q *), GFP_KERNEL); + wrm->q_arr = kzalloc_objs(struct csio_q *, wrm->num_q); if (!wrm->q_arr) goto err; for (i = 0; i < wrm->num_q; i++) { - wrm->q_arr[i] = kzalloc(sizeof(struct csio_q), GFP_KERNEL); + wrm->q_arr[i] = kzalloc_obj(struct csio_q); if (!wrm->q_arr[i]) { while (--i >= 0) kfree(wrm->q_arr[i]); diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index bf75940f2be1..ea9631bfe2e2 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -556,7 +556,7 @@ EXPORT_SYMBOL_GPL(cxgbi_sock_free_cpl_skbs); static struct cxgbi_sock *cxgbi_sock_create(struct cxgbi_device *cdev) { - struct cxgbi_sock *csk = kzalloc(sizeof(*csk), GFP_NOIO); + struct cxgbi_sock *csk = kzalloc_obj(*csk, GFP_NOIO); if (!csk) { pr_info("alloc csk %zu failed.\n", sizeof(*csk)); diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 9dc499c89d3e..6183ce05d8cf 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -2990,7 +2990,7 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, u8 period_index = eeprom->target[target].period & 0x07; struct DeviceCtlBlk *dcb; - dcb = kmalloc(sizeof(struct DeviceCtlBlk), GFP_ATOMIC); + dcb = kmalloc_obj(struct DeviceCtlBlk, GFP_ATOMIC); if (!dcb) return NULL; dcb->acb = NULL; diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 6fd89ae33059..efb08b9b145a 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -219,7 +219,7 @@ static struct alua_port_group *alua_alloc_pg(struct scsi_device *sdev, { struct alua_port_group *pg, *tmp_pg; - pg = kzalloc(sizeof(struct alua_port_group), GFP_KERNEL); + pg = kzalloc_obj(struct alua_port_group); if (!pg) return ERR_PTR(-ENOMEM); @@ -1137,7 +1137,7 @@ static int alua_activate(struct scsi_device *sdev, struct alua_queue_data *qdata; struct alua_port_group *pg; - qdata = kzalloc(sizeof(*qdata), GFP_KERNEL); + qdata = kzalloc_obj(*qdata); if (!qdata) { err = SCSI_DH_RES_TEMP_UNAVAIL; goto out; @@ -1239,7 +1239,7 @@ static int alua_bus_attach(struct scsi_device *sdev) struct alua_dh_data *h; int err; - h = kzalloc(sizeof(*h) , GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return SCSI_DH_NOMEM; spin_lock_init(&h->pg_lock); diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 3cf88db2d5b2..ff41b51ef462 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -478,7 +478,7 @@ static int clariion_bus_attach(struct scsi_device *sdev) struct clariion_dh_data *h; int err; - h = kzalloc(sizeof(*h) , GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return SCSI_DH_NOMEM; h->lun_state = CLARIION_LUN_UNINITIALIZED; diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index b6eaf49dfb00..6e8849d7f0a3 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -226,7 +226,7 @@ static int hp_sw_bus_attach(struct scsi_device *sdev) struct hp_sw_dh_data *h; int ret; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return SCSI_DH_NOMEM; h->path_state = HP_SW_PATH_UNINITIALIZED; diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 6e1b252cea0e..88c8e36b221e 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -336,7 +336,7 @@ static struct rdac_controller *get_controller(int index, char *array_name, return tmp; } } - ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC); + ctlr = kmalloc_obj(*ctlr, GFP_ATOMIC); if (!ctlr) return NULL; @@ -601,7 +601,7 @@ static int queue_mode_select(struct scsi_device *sdev, struct rdac_queue_data *qdata; struct rdac_controller *ctlr; - qdata = kzalloc(sizeof(*qdata), GFP_KERNEL); + qdata = kzalloc_obj(*qdata); if (!qdata) return SCSI_DH_RETRY; @@ -741,7 +741,7 @@ static int rdac_bus_attach(struct scsi_device *sdev) char array_name[ARRAY_LABEL_LEN]; char array_id[UNIQUE_ID_LEN]; - h = kzalloc(sizeof(*h) , GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return SCSI_DH_NOMEM; h->lun = UNINITIALIZED_LUN; diff --git a/drivers/scsi/elx/efct/efct_driver.c b/drivers/scsi/elx/efct/efct_driver.c index 528399f725d4..07c2f453459e 100644 --- a/drivers/scsi/elx/efct/efct_driver.c +++ b/drivers/scsi/elx/efct/efct_driver.c @@ -93,7 +93,7 @@ efct_efclib_config(struct efct *efct, struct libefc_function_template *tt) struct sli4 *sli; int rc = 0; - efc = kzalloc(sizeof(*efc), GFP_KERNEL); + efc = kzalloc_obj(*efc); if (!efc) return -ENOMEM; diff --git a/drivers/scsi/elx/efct/efct_hw.c b/drivers/scsi/elx/efct/efct_hw.c index 5b079b8b7a08..1838032f6486 100644 --- a/drivers/scsi/elx/efct/efct_hw.c +++ b/drivers/scsi/elx/efct/efct_hw.c @@ -487,14 +487,14 @@ efct_hw_setup_io(struct efct_hw *hw) struct efct *efct = hw->os; if (!hw->io) { - hw->io = kmalloc_array(hw->config.n_io, sizeof(io), GFP_KERNEL); + hw->io = kmalloc_objs(io, hw->config.n_io); if (!hw->io) return -ENOMEM; memset(hw->io, 0, hw->config.n_io * sizeof(io)); for (i = 0; i < hw->config.n_io; i++) { - hw->io[i] = kzalloc(sizeof(*io), GFP_KERNEL); + hw->io[i] = kzalloc_obj(*io); if (!hw->io[i]) goto error; } @@ -611,7 +611,7 @@ efct_hw_init_prereg_io(struct efct_hw *hw) struct efc_dma req; struct efct *efct = hw->os; - sgls = kmalloc_array(sgls_per_request, sizeof(*sgls), GFP_KERNEL); + sgls = kmalloc_objs(*sgls, sgls_per_request); if (!sgls) return -ENOMEM; @@ -1182,7 +1182,7 @@ efct_hw_rx_buffer_alloc(struct efct_hw *hw, u32 rqindex, u32 count, if (!count) return NULL; - rq_buf = kmalloc_array(count, sizeof(*rq_buf), GFP_KERNEL); + rq_buf = kmalloc_objs(*rq_buf, count); if (!rq_buf) return NULL; memset(rq_buf, 0, sizeof(*rq_buf) * count); @@ -1287,8 +1287,7 @@ efct_hw_rx_post(struct efct_hw *hw) for (i = 0; i < hw->hw_rq_count; i++) count += hw->hw_rq[i]->entry_count; - hw->seq_pool = kmalloc_array(count, - sizeof(struct efc_hw_sequence), GFP_KERNEL); + hw->seq_pool = kmalloc_objs(struct efc_hw_sequence, count); if (!hw->seq_pool) return -ENOMEM; } @@ -2064,7 +2063,7 @@ efct_hw_reqtag_pool_alloc(struct efct_hw *hw) struct reqtag_pool *reqtag_pool; struct hw_wq_callback *wqcb; - reqtag_pool = kzalloc(sizeof(*reqtag_pool), GFP_KERNEL); + reqtag_pool = kzalloc_obj(*reqtag_pool); if (!reqtag_pool) return NULL; @@ -2072,7 +2071,7 @@ efct_hw_reqtag_pool_alloc(struct efct_hw *hw) /* initialize reqtag pool lock */ spin_lock_init(&reqtag_pool->lock); for (i = 0; i < U16_MAX; i++) { - wqcb = kmalloc(sizeof(*wqcb), GFP_KERNEL); + wqcb = kmalloc_obj(*wqcb); if (!wqcb) break; @@ -3105,7 +3104,7 @@ efct_hw_get_link_stats(struct efct_hw *hw, u8 req_ext_counters, struct efct_hw_link_stat_cb_arg *cb_arg; u8 mbxdata[SLI4_BMBX_SIZE]; - cb_arg = kzalloc(sizeof(*cb_arg), GFP_ATOMIC); + cb_arg = kzalloc_obj(*cb_arg, GFP_ATOMIC); if (!cb_arg) return -ENOMEM; @@ -3189,7 +3188,7 @@ efct_hw_get_host_stats(struct efct_hw *hw, u8 cc, struct efct_hw_host_stat_cb_arg *cb_arg; u8 mbxdata[SLI4_BMBX_SIZE]; - cb_arg = kmalloc(sizeof(*cb_arg), GFP_ATOMIC); + cb_arg = kmalloc_obj(*cb_arg, GFP_ATOMIC); if (!cb_arg) return -ENOMEM; @@ -3239,7 +3238,7 @@ efct_hw_async_call(struct efct_hw *hw, efct_hw_async_cb_t callback, void *arg) * we need this to be persistent as the mbox cmd submission may be * queued and executed later execution. */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -3307,7 +3306,7 @@ efct_hw_firmware_write(struct efct_hw *hw, struct efc_dma *dma, u32 size, struct efct_hw_fw_wr_cb_arg *cb_arg; int noc = 0; - cb_arg = kzalloc(sizeof(*cb_arg), GFP_KERNEL); + cb_arg = kzalloc_obj(*cb_arg); if (!cb_arg) return -ENOMEM; diff --git a/drivers/scsi/elx/efct/efct_hw_queues.c b/drivers/scsi/elx/efct/efct_hw_queues.c index 3a1d1a5864a3..3c27f927f96c 100644 --- a/drivers/scsi/elx/efct/efct_hw_queues.c +++ b/drivers/scsi/elx/efct/efct_hw_queues.c @@ -127,7 +127,7 @@ efct_hw_map_wq_cpu(struct efct_hw *hw) struct hw_eq * efct_hw_new_eq(struct efct_hw *hw, u32 entry_count) { - struct hw_eq *eq = kzalloc(sizeof(*eq), GFP_KERNEL); + struct hw_eq *eq = kzalloc_obj(*eq); if (!eq) return NULL; @@ -159,7 +159,7 @@ struct hw_cq * efct_hw_new_cq(struct hw_eq *eq, u32 entry_count) { struct efct_hw *hw = eq->hw; - struct hw_cq *cq = kzalloc(sizeof(*cq), GFP_KERNEL); + struct hw_cq *cq = kzalloc_obj(*cq); if (!cq) return NULL; @@ -204,7 +204,7 @@ efct_hw_new_cq_set(struct hw_eq *eqs[], struct hw_cq *cqs[], cqs[i] = NULL; for (i = 0; i < num_cqs; i++) { - cq = kzalloc(sizeof(*cq), GFP_KERNEL); + cq = kzalloc_obj(*cq); if (!cq) goto error; @@ -244,7 +244,7 @@ struct hw_mq * efct_hw_new_mq(struct hw_cq *cq, u32 entry_count) { struct efct_hw *hw = cq->eq->hw; - struct hw_mq *mq = kzalloc(sizeof(*mq), GFP_KERNEL); + struct hw_mq *mq = kzalloc_obj(*mq); if (!mq) return NULL; @@ -275,7 +275,7 @@ struct hw_wq * efct_hw_new_wq(struct hw_cq *cq, u32 entry_count) { struct efct_hw *hw = cq->eq->hw; - struct hw_wq *wq = kzalloc(sizeof(*wq), GFP_KERNEL); + struct hw_wq *wq = kzalloc_obj(*wq); if (!wq) return NULL; @@ -324,7 +324,7 @@ efct_hw_new_rq_set(struct hw_cq *cqs[], struct hw_rq *rqs[], * encapsulates 2 SLI queues (for rq pair) */ for (i = 0, q_count = 0; i < num_rq_pairs; i++, q_count += 2) { - rq = kzalloc(sizeof(*rq), GFP_KERNEL); + rq = kzalloc_obj(*rq); if (!rq) goto error; diff --git a/drivers/scsi/elx/efct/efct_io.c b/drivers/scsi/elx/efct/efct_io.c index c612f0a48839..91ab64ce9f97 100644 --- a/drivers/scsi/elx/efct/efct_io.c +++ b/drivers/scsi/elx/efct/efct_io.c @@ -25,7 +25,7 @@ efct_io_pool_create(struct efct *efct, u32 num_sgl) struct efct_io *io; /* Allocate the IO pool */ - io_pool = kzalloc(sizeof(*io_pool), GFP_KERNEL); + io_pool = kzalloc_obj(*io_pool); if (!io_pool) return NULL; @@ -35,7 +35,7 @@ efct_io_pool_create(struct efct *efct, u32 num_sgl) spin_lock_init(&io_pool->lock); for (i = 0; i < EFCT_NUM_SCSI_IOS; i++) { - io = kzalloc(sizeof(*io), GFP_KERNEL); + io = kzalloc_obj(*io); if (!io) break; diff --git a/drivers/scsi/elx/efct/efct_lio.c b/drivers/scsi/elx/efct/efct_lio.c index bd3d489e56ae..d6e35ee8fee0 100644 --- a/drivers/scsi/elx/efct/efct_lio.c +++ b/drivers/scsi/elx/efct/efct_lio.c @@ -744,7 +744,7 @@ efct_lio_make_nport(struct target_fabric_configfs *tf, return ERR_PTR(-ENXIO); } - lio_nport = kzalloc(sizeof(*lio_nport), GFP_KERNEL); + lio_nport = kzalloc_obj(*lio_nport); if (!lio_nport) return ERR_PTR(-ENOMEM); @@ -796,7 +796,7 @@ efct_lio_npiv_make_nport(struct target_fabric_configfs *tf, return ERR_PTR(-ENXIO); } - lio_vport = kzalloc(sizeof(*lio_vport), GFP_KERNEL); + lio_vport = kzalloc_obj(*lio_vport); if (!lio_vport) return ERR_PTR(-ENOMEM); @@ -808,7 +808,7 @@ efct_lio_npiv_make_nport(struct target_fabric_configfs *tf, efct_format_wwn(lio_vport->wwpn_str, sizeof(lio_vport->wwpn_str), "naa.", npiv_wwpn); - vport_list = kzalloc(sizeof(*vport_list), GFP_KERNEL); + vport_list = kzalloc_obj(*vport_list); if (!vport_list) { kfree(lio_vport); return ERR_PTR(-ENOMEM); @@ -895,7 +895,7 @@ efct_lio_make_tpg(struct se_wwn *wwn, const char *name) if (kstrtoul(name + 5, 10, &n) || n > USHRT_MAX) return ERR_PTR(-EINVAL); - tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); + tpg = kzalloc_obj(*tpg); if (!tpg) return ERR_PTR(-ENOMEM); @@ -958,7 +958,7 @@ efct_lio_npiv_make_tpg(struct se_wwn *wwn, const char *name) return ERR_PTR(-EINVAL); } - tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); + tpg = kzalloc_obj(*tpg); if (!tpg) return ERR_PTR(-ENOMEM); @@ -1069,7 +1069,7 @@ static int efct_session_cb(struct se_portal_group *se_tpg, struct efct_node *tgt_node; struct efct *efct = node->efc->base; - tgt_node = kzalloc(sizeof(*tgt_node), GFP_KERNEL); + tgt_node = kzalloc_obj(*tgt_node); if (!tgt_node) return -ENOMEM; @@ -1227,7 +1227,7 @@ int efct_scsi_new_initiator(struct efc *efc, struct efc_node *node) * Since LIO only supports initiator validation at thread level, * we are open minded and accept all callers. */ - wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC); + wq_data = kzalloc_obj(*wq_data, GFP_ATOMIC); if (!wq_data) return -ENOMEM; @@ -1292,7 +1292,7 @@ int efct_scsi_del_initiator(struct efc *efc, struct efc_node *node, int reason) return -EIO; } - wq_data = kzalloc(sizeof(*wq_data), GFP_ATOMIC); + wq_data = kzalloc_obj(*wq_data, GFP_ATOMIC); if (!wq_data) return -ENOMEM; diff --git a/drivers/scsi/elx/efct/efct_xport.c b/drivers/scsi/elx/efct/efct_xport.c index dfe05fab7b42..9dcaef6fc188 100644 --- a/drivers/scsi/elx/efct/efct_xport.c +++ b/drivers/scsi/elx/efct/efct_xport.c @@ -28,7 +28,7 @@ efct_xport_alloc(struct efct *efct) { struct efct_xport *xport; - xport = kzalloc(sizeof(*xport), GFP_KERNEL); + xport = kzalloc_obj(*xport); if (!xport) return xport; diff --git a/drivers/scsi/elx/libefc/efc_domain.c b/drivers/scsi/elx/libefc/efc_domain.c index ca9d7ff2c0d2..554a538ffd33 100644 --- a/drivers/scsi/elx/libefc/efc_domain.c +++ b/drivers/scsi/elx/libefc/efc_domain.c @@ -134,7 +134,7 @@ efc_domain_alloc(struct efc *efc, uint64_t fcf_wwn) { struct efc_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_ATOMIC); + domain = kzalloc_obj(*domain, GFP_ATOMIC); if (!domain) return NULL; diff --git a/drivers/scsi/elx/libefc/efc_fabric.c b/drivers/scsi/elx/libefc/efc_fabric.c index 4ed9f46ded65..12e82deb2a35 100644 --- a/drivers/scsi/elx/libefc/efc_fabric.c +++ b/drivers/scsi/elx/libefc/efc_fabric.c @@ -685,7 +685,7 @@ efc_process_gidpt_payload(struct efc_node *node, } /* Allocate a buffer for all nodes */ - active_nodes = kcalloc(port_count, sizeof(*active_nodes), GFP_ATOMIC); + active_nodes = kzalloc_objs(*active_nodes, port_count, GFP_ATOMIC); if (!active_nodes) { node_printf(node, "efc_malloc failed\n"); return -EIO; diff --git a/drivers/scsi/elx/libefc/efc_nport.c b/drivers/scsi/elx/libefc/efc_nport.c index 1a7437f4328e..1ea26c7337eb 100644 --- a/drivers/scsi/elx/libefc/efc_nport.c +++ b/drivers/scsi/elx/libefc/efc_nport.c @@ -82,7 +82,7 @@ efc_nport_alloc(struct efc_domain *domain, uint64_t wwpn, uint64_t wwnn, } } - nport = kzalloc(sizeof(*nport), GFP_ATOMIC); + nport = kzalloc_obj(*nport, GFP_ATOMIC); if (!nport) return nport; @@ -756,7 +756,7 @@ efc_vport_create_spec(struct efc *efc, uint64_t wwnn, uint64_t wwpn, } } - vport = kzalloc(sizeof(*vport), GFP_ATOMIC); + vport = kzalloc_obj(*vport, GFP_ATOMIC); if (!vport) { spin_unlock_irqrestore(&efc->vport_lock, flags); return NULL; diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c index 04a07fe57be2..0a35f1953768 100644 --- a/drivers/scsi/esas2r/esas2r_init.c +++ b/drivers/scsi/esas2r/esas2r_init.c @@ -103,8 +103,7 @@ static void esas2r_initmem_free(struct esas2r_adapter *a, static bool alloc_vda_req(struct esas2r_adapter *a, struct esas2r_request *rq) { - struct esas2r_mem_desc *memdesc = kzalloc( - sizeof(struct esas2r_mem_desc), GFP_KERNEL); + struct esas2r_mem_desc *memdesc = kzalloc_obj(struct esas2r_mem_desc); if (memdesc == NULL) { esas2r_hdebug("could not alloc mem for vda request memdesc\n"); @@ -783,8 +782,7 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, /* allocate requests for asynchronous events */ a->first_ae_req = - kcalloc(num_ae_requests, sizeof(struct esas2r_request), - GFP_KERNEL); + kzalloc_objs(struct esas2r_request, num_ae_requests); if (a->first_ae_req == NULL) { esas2r_log(ESAS2R_LOG_CRIT, @@ -793,8 +791,7 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, } /* allocate the S/G list memory descriptors */ - a->sg_list_mds = kcalloc(num_sg_lists, sizeof(struct esas2r_mem_desc), - GFP_KERNEL); + a->sg_list_mds = kzalloc_objs(struct esas2r_mem_desc, num_sg_lists); if (a->sg_list_mds == NULL) { esas2r_log(ESAS2R_LOG_CRIT, @@ -804,9 +801,8 @@ bool esas2r_init_adapter_struct(struct esas2r_adapter *a, /* allocate the request table */ a->req_table = - kcalloc(num_requests + num_ae_requests + 1, - sizeof(struct esas2r_request *), - GFP_KERNEL); + kzalloc_objs(struct esas2r_request *, + num_requests + num_ae_requests + 1); if (a->req_table == NULL) { esas2r_log(ESAS2R_LOG_CRIT, diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index fdcffc871d19..ada278c24c51 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c @@ -194,8 +194,7 @@ static ssize_t write_hw(struct file *file, struct kobject *kobj, int length = min(sizeof(struct atto_ioctl), count); if (!a->local_atto_ioctl) { - a->local_atto_ioctl = kmalloc(sizeof(struct atto_ioctl), - GFP_KERNEL); + a->local_atto_ioctl = kmalloc_obj(struct atto_ioctl); if (a->local_atto_ioctl == NULL) { esas2r_log(ESAS2R_LOG_WARN, "write_hw kzalloc failed for %zu bytes", @@ -1831,7 +1830,7 @@ void esas2r_queue_fw_event(struct esas2r_adapter *a, struct esas2r_fw_event_work *fw_event; unsigned long flags; - fw_event = kzalloc(sizeof(struct esas2r_fw_event_work), GFP_ATOMIC); + fw_event = kzalloc_obj(struct esas2r_fw_event_work, GFP_ATOMIC); if (!fw_event) { esas2r_log(ESAS2R_LOG_WARN, "esas2r_queue_fw_event failed to alloc"); diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 05647ccc3c8a..897a01d3e303 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -881,7 +881,7 @@ static struct esp_cmd_entry *esp_get_ent(struct esp *esp) struct esp_cmd_entry *ret; if (list_empty(head)) { - ret = kzalloc(sizeof(struct esp_cmd_entry), GFP_ATOMIC); + ret = kzalloc_obj(struct esp_cmd_entry, GFP_ATOMIC); } else { ret = list_entry(head->next, struct esp_cmd_entry, list); list_del(&ret->list); @@ -2447,7 +2447,7 @@ static int esp_sdev_init(struct scsi_device *dev) struct esp_target_data *tp = &esp->target[dev->id]; struct esp_lun_data *lp; - lp = kzalloc(sizeof(*lp), GFP_KERNEL); + lp = kzalloc_obj(*lp); if (!lp) return -ENOMEM; dev->hostdata = lp; diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index c8c5dfb3ba9a..534596c6d76c 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -820,7 +820,7 @@ static void fcoe_fdmi_info(struct fc_lport *lport, struct net_device *netdev) if (realdev->netdev_ops->ndo_fcoe_get_hbainfo) { struct netdev_fcoe_hbainfo *fdmi; - fdmi = kzalloc(sizeof(*fdmi), GFP_KERNEL); + fdmi = kzalloc_obj(*fdmi); if (!fdmi) return; diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 8e4241c295e3..02cd4410efca 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -168,7 +168,7 @@ static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) LIBFCOE_FIP_DBG(fip, "New FCF fab %16.16llx mac %pM\n", new->fabric_name, new->fcf_mac); - temp = kzalloc(sizeof(*temp), GFP_KERNEL); + temp = kzalloc_obj(*temp); if (!temp) goto out; @@ -1043,7 +1043,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT) goto out; - fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC); + fcf = kmalloc_obj(*fcf, GFP_ATOMIC); if (!fcf) goto out; @@ -1378,8 +1378,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, */ num_vlink_desc = rlen / sizeof(*vp); if (num_vlink_desc) - vlink_desc_arr = kmalloc_array(num_vlink_desc, sizeof(vp), - GFP_ATOMIC); + vlink_desc_arr = kmalloc_objs(vp, num_vlink_desc, GFP_ATOMIC); if (!vlink_desc_arr) return; num_vlink_desc = 0; diff --git a/drivers/scsi/fcoe/fcoe_sysfs.c b/drivers/scsi/fcoe/fcoe_sysfs.c index 0609ca6b9353..afea5763a3c0 100644 --- a/drivers/scsi/fcoe/fcoe_sysfs.c +++ b/drivers/scsi/fcoe/fcoe_sysfs.c @@ -986,7 +986,7 @@ struct fcoe_fcf_device *fcoe_fcf_device_add(struct fcoe_ctlr_device *ctlr, } } - fcf = kzalloc(sizeof(struct fcoe_fcf_device), GFP_ATOMIC); + fcf = kzalloc_obj(struct fcoe_fcf_device, GFP_ATOMIC); if (unlikely(!fcf)) goto out; diff --git a/drivers/scsi/fcoe/fcoe_transport.c b/drivers/scsi/fcoe/fcoe_transport.c index 2f478426f16e..88d85fc9a52a 100644 --- a/drivers/scsi/fcoe/fcoe_transport.c +++ b/drivers/scsi/fcoe/fcoe_transport.c @@ -638,7 +638,7 @@ static int fcoe_add_netdev_mapping(struct net_device *netdev, { struct fcoe_netdev_mapping *nm; - nm = kmalloc(sizeof(*nm), GFP_KERNEL); + nm = kmalloc_obj(*nm); if (!nm) { printk(KERN_ERR "Unable to allocate netdev_mapping"); return -ENOMEM; diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c index ae37f85f618b..455426564ca0 100644 --- a/drivers/scsi/fnic/fdls_disc.c +++ b/drivers/scsi/fnic/fdls_disc.c @@ -272,7 +272,7 @@ void fdls_schedule_oxid_free(struct fnic_iport_s *iport, uint16_t *active_oxid) *active_oxid = FNIC_UNASSIGNED_OXID; reclaim_entry = (struct reclaim_entry_s *) - kzalloc(sizeof(struct reclaim_entry_s), GFP_ATOMIC); + kzalloc_obj(struct reclaim_entry_s, GFP_ATOMIC); if (!reclaim_entry) { FNIC_FCS_DBG(KERN_WARNING, fnic->host, fnic->fnic_num, @@ -316,7 +316,7 @@ void fdls_schedule_oxid_free_retry_work(struct work_struct *work) FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "Schedule oxid free. oxid idx: %d\n", idx); - reclaim_entry = kzalloc(sizeof(*reclaim_entry), GFP_KERNEL); + reclaim_entry = kzalloc_obj(*reclaim_entry); if (!reclaim_entry) { schedule_delayed_work(&oxid_pool->schedule_oxid_free_retry, msecs_to_jiffies(SCHEDULE_OXID_FREE_RETRY_TIME)); @@ -1270,7 +1270,7 @@ bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport) if (tport->flags & FNIC_FDLS_SCSI_REGISTERED) { tport_del_evt = - kzalloc(sizeof(struct fnic_tport_event_s), GFP_ATOMIC); + kzalloc_obj(struct fnic_tport_event_s, GFP_ATOMIC); if (!tport_del_evt) { FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "Failed to allocate memory for tport fcid: 0x%0x\n", @@ -1776,7 +1776,7 @@ static struct fnic_tport_s *fdls_create_tport(struct fnic_iport_s *iport, FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "FDLS create tport: fcid: 0x%x wwpn: 0x%llx", fcid, wwpn); - tport = kzalloc(sizeof(struct fnic_tport_s), GFP_ATOMIC); + tport = kzalloc_obj(struct fnic_tport_s, GFP_ATOMIC); if (!tport) { FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "Memory allocation failure while creating tport: 0x%x\n", @@ -2365,7 +2365,7 @@ static void fdls_send_delete_tport_msg(struct fnic_tport_s *tport) struct fnic *fnic = iport->fnic; struct fnic_tport_event_s *tport_del_evt; - tport_del_evt = kzalloc(sizeof(struct fnic_tport_event_s), GFP_ATOMIC); + tport_del_evt = kzalloc_obj(struct fnic_tport_event_s, GFP_ATOMIC); if (!tport_del_evt) { FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "Failed to allocate memory for tport event fcid: 0x%x", @@ -2852,7 +2852,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, fdls_set_tport_state(tport, FDLS_TGT_STATE_READY); /* Inform the driver about new target added */ - tport_add_evt = kzalloc(sizeof(struct fnic_tport_event_s), GFP_ATOMIC); + tport_add_evt = kzalloc_obj(struct fnic_tport_event_s, GFP_ATOMIC); if (!tport_add_evt) { FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "tport event memory allocation failure: 0x%0x\n", diff --git a/drivers/scsi/fnic/fip.c b/drivers/scsi/fnic/fip.c index ce62ab1180bd..ccd0da7d490f 100644 --- a/drivers/scsi/fnic/fip.c +++ b/drivers/scsi/fnic/fip.c @@ -139,7 +139,7 @@ void fnic_fcoe_process_vlan_resp(struct fnic *fnic, struct fip_header *fiph) FNIC_FIP_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "process_vlan_resp: FIP VLAN %d\n", vid); - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) { /* retry from timer */ diff --git a/drivers/scsi/fnic/fnic_debugfs.c b/drivers/scsi/fnic/fnic_debugfs.c index 5767862ae42f..ba86964fb45e 100644 --- a/drivers/scsi/fnic/fnic_debugfs.c +++ b/drivers/scsi/fnic/fnic_debugfs.c @@ -200,7 +200,7 @@ static int fnic_trace_debugfs_open(struct inode *inode, fnic_dbgfs_t *fnic_dbg_prt; u8 *rdata_ptr; rdata_ptr = (u8 *)inode->i_private; - fnic_dbg_prt = kzalloc(sizeof(fnic_dbgfs_t), GFP_KERNEL); + fnic_dbg_prt = kzalloc_obj(fnic_dbgfs_t); if (!fnic_dbg_prt) return -ENOMEM; @@ -436,7 +436,7 @@ static int fnic_reset_stats_open(struct inode *inode, struct file *file) { struct stats_debug_info *debug; - debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); + debug = kzalloc_obj(struct stats_debug_info); if (!debug) return -ENOMEM; @@ -583,7 +583,7 @@ static int fnic_stats_debugfs_open(struct inode *inode, struct stats_debug_info *debug; int buf_size = 2 * PAGE_SIZE; - debug = kzalloc(sizeof(struct stats_debug_info), GFP_KERNEL); + debug = kzalloc_obj(struct stats_debug_info); if (!debug) return -ENOMEM; diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 103ab6f1f7cd..405b341b73d7 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -376,7 +376,7 @@ static inline int fnic_import_rq_eth_pkt(struct fnic *fnic, void *fp) eh = (struct ethhdr *) fp; if ((eh->h_proto == cpu_to_be16(ETH_P_FIP)) && (fnic->iport.usefip)) { fip_fr_elem = (struct fnic_frame_list *) - kzalloc(sizeof(struct fnic_frame_list), GFP_ATOMIC); + kzalloc_obj(struct fnic_frame_list, GFP_ATOMIC); if (!fip_fr_elem) return 0; fip_fr_elem->fp = fp; diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 4cc4077ea53c..8b551b79e087 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -715,7 +715,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* * Allocate fnic */ - fnic = kzalloc(sizeof(struct fnic), GFP_KERNEL); + fnic = kzalloc_obj(struct fnic); if (!fnic) { err = -ENOMEM; goto err_out_fnic_alloc; diff --git a/drivers/scsi/fnic/vnic_dev.c b/drivers/scsi/fnic/vnic_dev.c index e0b173cc9d5f..991c86eb5aff 100644 --- a/drivers/scsi/fnic/vnic_dev.c +++ b/drivers/scsi/fnic/vnic_dev.c @@ -422,7 +422,7 @@ static int vnic_dev_init_devcmd2(struct vnic_dev *vdev) if (vdev->devcmd2) return 0; - vdev->devcmd2 = kzalloc(sizeof(*vdev->devcmd2), GFP_ATOMIC); + vdev->devcmd2 = kzalloc_obj(*vdev->devcmd2, GFP_ATOMIC); if (!vdev->devcmd2) return -ENOMEM; @@ -911,7 +911,7 @@ struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev, void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar) { if (!vdev) { - vdev = kzalloc(sizeof(struct vnic_dev), GFP_KERNEL); + vdev = kzalloc_obj(struct vnic_dev); if (!vdev) return NULL; } diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 30a9c6612651..c2b082f1252c 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -2578,7 +2578,7 @@ int hisi_sas_probe(struct platform_device *pdev, shost->transportt = hisi_sas_stt; shost->max_id = HISI_SAS_MAX_DEVICES; shost->max_lun = ~0; - shost->max_channel = 1; + shost->max_channel = 0; shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; if (hisi_hba->hw->slot_index_alloc) { shost->can_queue = HISI_SAS_MAX_COMMANDS; diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 2f9e01717ef3..f69efc6494b8 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -4993,7 +4993,7 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id) shost->transportt = hisi_sas_stt; shost->max_id = HISI_SAS_MAX_DEVICES; shost->max_lun = ~0; - shost->max_channel = 1; + shost->max_channel = 0; shost->max_cmd_len = HISI_SAS_MAX_CDB_LEN; shost->can_queue = HISI_SAS_UNRESERVED_IPTT; shost->cmd_per_lun = HISI_SAS_UNRESERVED_IPTT; diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 3e235dbfb67a..a1b116cd4723 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -1597,7 +1597,7 @@ static void hpsa_monitor_offline_device(struct ctlr_info *h, spin_unlock_irqrestore(&h->offline_device_lock, flags); /* Device is not on the list, add it. */ - device = kmalloc(sizeof(*device), GFP_KERNEL); + device = kmalloc_obj(*device); if (!device) return; @@ -1936,8 +1936,8 @@ static void adjust_hpsa_scsi_table(struct ctlr_info *h, } spin_unlock_irqrestore(&h->reset_lock, flags); - added = kcalloc(HPSA_MAX_DEVICES, sizeof(*added), GFP_KERNEL); - removed = kcalloc(HPSA_MAX_DEVICES, sizeof(*removed), GFP_KERNEL); + added = kzalloc_objs(*added, HPSA_MAX_DEVICES); + removed = kzalloc_objs(*removed, HPSA_MAX_DEVICES); if (!added || !removed) { dev_warn(&h->pdev->dev, "out of memory in " @@ -2200,15 +2200,13 @@ static int hpsa_allocate_ioaccel2_sg_chain_blocks(struct ctlr_info *h) return 0; h->ioaccel2_cmd_sg_list = - kcalloc(h->nr_cmds, sizeof(*h->ioaccel2_cmd_sg_list), - GFP_KERNEL); + kzalloc_objs(*h->ioaccel2_cmd_sg_list, h->nr_cmds); if (!h->ioaccel2_cmd_sg_list) return -ENOMEM; for (i = 0; i < h->nr_cmds; i++) { h->ioaccel2_cmd_sg_list[i] = - kmalloc_array(h->maxsgentries, - sizeof(*h->ioaccel2_cmd_sg_list[i]), - GFP_KERNEL); + kmalloc_objs(*h->ioaccel2_cmd_sg_list[i], + h->maxsgentries); if (!h->ioaccel2_cmd_sg_list[i]) goto clean; } @@ -2240,15 +2238,13 @@ static int hpsa_alloc_sg_chain_blocks(struct ctlr_info *h) if (h->chainsize <= 0) return 0; - h->cmd_sg_list = kcalloc(h->nr_cmds, sizeof(*h->cmd_sg_list), - GFP_KERNEL); + h->cmd_sg_list = kzalloc_objs(*h->cmd_sg_list, h->nr_cmds); if (!h->cmd_sg_list) return -ENOMEM; for (i = 0; i < h->nr_cmds; i++) { - h->cmd_sg_list[i] = kmalloc_array(h->chainsize, - sizeof(*h->cmd_sg_list[i]), - GFP_KERNEL); + h->cmd_sg_list[i] = kmalloc_objs(*h->cmd_sg_list[i], + h->chainsize); if (!h->cmd_sg_list[i]) goto clean; @@ -3469,11 +3465,11 @@ static void hpsa_get_enclosure_info(struct ctlr_info *h, goto out; } - bssbp = kzalloc(sizeof(*bssbp), GFP_KERNEL); + bssbp = kzalloc_obj(*bssbp); if (!bssbp) goto out; - id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL); + id_phys = kzalloc_obj(*id_phys); if (!id_phys) goto out; @@ -3534,7 +3530,7 @@ static u64 hpsa_get_sas_address_from_report_physical(struct ctlr_info *h, u64 sa = 0; int i; - physdev = kzalloc(sizeof(*physdev), GFP_KERNEL); + physdev = kzalloc_obj(*physdev); if (!physdev) return 0; @@ -3565,7 +3561,7 @@ static void hpsa_get_sas_address(struct ctlr_info *h, unsigned char *scsi3addr, if (is_hba_lunid(scsi3addr)) { struct bmic_sense_subsystem_info *ssi; - ssi = kzalloc(sizeof(*ssi), GFP_KERNEL); + ssi = kzalloc_obj(*ssi); if (!ssi) return; @@ -3789,7 +3785,7 @@ static inline int hpsa_scsi_do_report_phys_luns(struct ctlr_info *h, return rc; /* REPORT PHYS EXTENDED is not supported */ - lbuf = kzalloc(sizeof(*lbuf), GFP_KERNEL); + lbuf = kzalloc_obj(*lbuf); if (!lbuf) return -ENOMEM; @@ -4260,7 +4256,7 @@ static bool hpsa_is_disk_spare(struct ctlr_info *h, u8 *lunaddrbytes) bool is_spare = false; int rc; - id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL); + id_phys = kzalloc_obj(*id_phys); if (!id_phys) return false; @@ -4345,12 +4341,12 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) int raid_ctlr_position; bool physical_device; - currentsd = kcalloc(HPSA_MAX_DEVICES, sizeof(*currentsd), GFP_KERNEL); - physdev_list = kzalloc(sizeof(*physdev_list), GFP_KERNEL); - logdev_list = kzalloc(sizeof(*logdev_list), GFP_KERNEL); - tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL); - id_phys = kzalloc(sizeof(*id_phys), GFP_KERNEL); - id_ctlr = kzalloc(sizeof(*id_ctlr), GFP_KERNEL); + currentsd = kzalloc_objs(*currentsd, HPSA_MAX_DEVICES); + physdev_list = kzalloc_obj(*physdev_list); + logdev_list = kzalloc_obj(*logdev_list); + tmpdevice = kzalloc_obj(*tmpdevice); + id_phys = kzalloc_obj(*id_phys); + id_ctlr = kzalloc_obj(*id_ctlr); if (!currentsd || !physdev_list || !logdev_list || !tmpdevice || !id_phys || !id_ctlr) { @@ -4390,7 +4386,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h) break; } - currentsd[i] = kzalloc(sizeof(*currentsd[i]), GFP_KERNEL); + currentsd[i] = kzalloc_obj(*currentsd[i]); if (!currentsd[i]) { h->drv_req_rescan = 1; goto out; @@ -6504,7 +6500,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, status = -ENOMEM; goto cleanup1; } - buff_size = kmalloc_array(SG_ENTRIES_IN_CMD, sizeof(int), GFP_KERNEL); + buff_size = kmalloc_objs(int, SG_ENTRIES_IN_CMD); if (!buff_size) { status = -ENOMEM; goto cleanup1; @@ -8494,7 +8490,7 @@ static int hpsa_luns_changed(struct ctlr_info *h) if (!h->lastlogicals) return rc; - logdev = kzalloc(sizeof(*logdev), GFP_KERNEL); + logdev = kzalloc_obj(*logdev); if (!logdev) return rc; @@ -8635,7 +8631,7 @@ static struct ctlr_info *hpda_alloc_ctlr_info(void) { struct ctlr_info *h; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return NULL; @@ -8856,7 +8852,7 @@ static int hpsa_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) hpsa_hba_inquiry(h); - h->lastlogicals = kzalloc(sizeof(*(h->lastlogicals)), GFP_KERNEL); + h->lastlogicals = kzalloc_obj(*(h->lastlogicals)); if (!h->lastlogicals) dev_info(&h->pdev->dev, "Can't track change to report lun data\n"); @@ -8960,7 +8956,7 @@ static void hpsa_disable_rld_caching(struct ctlr_info *h) if (unlikely(h->lockup_detected)) return; - options = kzalloc(sizeof(*options), GFP_KERNEL); + options = kzalloc_obj(*options); if (!options) return; @@ -9557,7 +9553,7 @@ static struct hpsa_sas_phy *hpsa_alloc_sas_phy( struct hpsa_sas_phy *hpsa_sas_phy; struct sas_phy *phy; - hpsa_sas_phy = kzalloc(sizeof(*hpsa_sas_phy), GFP_KERNEL); + hpsa_sas_phy = kzalloc_obj(*hpsa_sas_phy); if (!hpsa_sas_phy) return NULL; @@ -9642,7 +9638,7 @@ static struct hpsa_sas_port struct hpsa_sas_port *hpsa_sas_port; struct sas_port *port; - hpsa_sas_port = kzalloc(sizeof(*hpsa_sas_port), GFP_KERNEL); + hpsa_sas_port = kzalloc_obj(*hpsa_sas_port); if (!hpsa_sas_port) return NULL; @@ -9690,7 +9686,7 @@ static struct hpsa_sas_node *hpsa_alloc_sas_node(struct device *parent_dev) { struct hpsa_sas_node *hpsa_sas_node; - hpsa_sas_node = kzalloc(sizeof(*hpsa_sas_node), GFP_KERNEL); + hpsa_sas_node = kzalloc_obj(*hpsa_sas_node); if (hpsa_sas_node) { hpsa_sas_node->parent_dev = parent_dev; INIT_LIST_HEAD(&hpsa_sas_node->port_list_head); diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c index 1c370d11b6dd..a20fce04fe79 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc.c +++ b/drivers/scsi/ibmvscsi/ibmvfc.c @@ -797,7 +797,7 @@ static int ibmvfc_init_event_pool(struct ibmvfc_host *vhost, return 0; pool->size = queue->total_depth; - pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL); + pool->events = kzalloc_objs(*pool->events, pool->size); if (!pool->events) return -ENOMEM; @@ -6057,9 +6057,7 @@ static int ibmvfc_alloc_channels(struct ibmvfc_host *vhost, int i, j; int rc = 0; - channels->scrqs = kcalloc(channels->max_queues, - sizeof(*channels->scrqs), - GFP_KERNEL); + channels->scrqs = kzalloc_objs(*channels->scrqs, channels->max_queues); if (!channels->scrqs) return -ENOMEM; @@ -6211,8 +6209,8 @@ static int ibmvfc_alloc_mem(struct ibmvfc_host *vhost) if (ibmvfc_alloc_disc_buf(dev, &vhost->scsi_scrqs)) goto free_login_buffer; - vhost->trace = kcalloc(IBMVFC_NUM_TRACE_ENTRIES, - sizeof(struct ibmvfc_trace_entry), GFP_KERNEL); + vhost->trace = kzalloc_objs(struct ibmvfc_trace_entry, + IBMVFC_NUM_TRACE_ENTRIES); atomic_set(&vhost->trace_index, -1); if (!vhost->trace) diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 200debd6f7e8..609bda730b3a 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -447,7 +447,7 @@ static int initialize_event_pool(struct event_pool *pool, pool->size = size; pool->next = 0; - pool->events = kcalloc(pool->size, sizeof(*pool->events), GFP_KERNEL); + pool->events = kzalloc_objs(*pool->events, pool->size); if (!pool->events) return -ENOMEM; diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index f259746bc804..b395a9d7c640 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -2214,7 +2214,7 @@ static int ibmvscsis_make_nexus(struct ibmvscsis_tport *tport) return 0; } - nexus = kzalloc(sizeof(*nexus), GFP_KERNEL); + nexus = kzalloc_obj(*nexus); if (!nexus) { dev_err(&vscsi->dev, "Unable to allocate struct ibmvscsis_nexus\n"); return -ENOMEM; @@ -3424,7 +3424,7 @@ static int ibmvscsis_probe(struct vio_dev *vdev, int rc = 0; long hrc = 0; - vscsi = kzalloc(sizeof(*vscsi), GFP_KERNEL); + vscsi = kzalloc_obj(*vscsi); if (!vscsi) { rc = -ENOMEM; dev_err(&vdev->dev, "probe: allocation of adapter failed\n"); diff --git a/drivers/scsi/ibmvscsi_tgt/libsrp.c b/drivers/scsi/ibmvscsi_tgt/libsrp.c index 0ecad398ed3d..eef9e452ece5 100644 --- a/drivers/scsi/ibmvscsi_tgt/libsrp.c +++ b/drivers/scsi/ibmvscsi_tgt/libsrp.c @@ -27,10 +27,10 @@ static int srp_iu_pool_alloc(struct srp_queue *q, size_t max, struct iu_entry *iue; int i; - q->pool = kcalloc(max, sizeof(struct iu_entry *), GFP_KERNEL); + q->pool = kzalloc_objs(struct iu_entry *, max); if (!q->pool) return -ENOMEM; - q->items = kcalloc(max, sizeof(struct iu_entry), GFP_KERNEL); + q->items = kzalloc_objs(struct iu_entry, max); if (!q->items) goto free_pool; @@ -61,12 +61,12 @@ static struct srp_buf **srp_ring_alloc(struct device *dev, struct srp_buf **ring; int i; - ring = kcalloc(max, sizeof(struct srp_buf *), GFP_KERNEL); + ring = kzalloc_objs(struct srp_buf *, max); if (!ring) return NULL; for (i = 0; i < max; i++) { - ring[i] = kzalloc(sizeof(*ring[i]), GFP_KERNEL); + ring[i] = kzalloc_obj(*ring[i]); if (!ring[i]) goto out; ring[i]->buf = dma_alloc_coherent(dev, size, &ring[i]->dma, diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index da7aaac10a73..0535252e77e3 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -1158,7 +1158,7 @@ static int __imm_attach(struct parport *pb) init_waitqueue_head(&waiting); - dev = kzalloc(sizeof(imm_struct), GFP_KERNEL); + dev = kzalloc_obj(imm_struct); if (!dev) return -ENOMEM; diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index c0487ce38d8d..d207e5e81afe 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -3776,7 +3776,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) order = get_order(sg_size); /* Allocate a scatter/gather list for the DMA */ - sglist = kzalloc(sizeof(struct ipr_sglist), GFP_KERNEL); + sglist = kzalloc_obj(struct ipr_sglist); if (sglist == NULL) { ipr_trace; return NULL; @@ -4273,7 +4273,7 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) __be32 **ioa_data; unsigned long lock_flags = 0; - dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL); + dump = kzalloc_obj(struct ipr_dump); if (!dump) { ipr_err("Dump memory allocation failed\n"); @@ -8859,8 +8859,9 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) if (!ioa_cfg->ipr_cmd_pool) return -ENOMEM; - ioa_cfg->ipr_cmnd_list = kcalloc(IPR_NUM_CMD_BLKS, sizeof(struct ipr_cmnd *), GFP_KERNEL); - ioa_cfg->ipr_cmnd_list_dma = kcalloc(IPR_NUM_CMD_BLKS, sizeof(dma_addr_t), GFP_KERNEL); + ioa_cfg->ipr_cmnd_list = kzalloc_objs(struct ipr_cmnd *, + IPR_NUM_CMD_BLKS); + ioa_cfg->ipr_cmnd_list_dma = kzalloc_objs(dma_addr_t, IPR_NUM_CMD_BLKS); if (!ioa_cfg->ipr_cmnd_list || !ioa_cfg->ipr_cmnd_list_dma) { ipr_free_cmd_blks(ioa_cfg); @@ -8963,9 +8964,8 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) int i, rc = -ENOMEM; ENTER; - ioa_cfg->res_entries = kcalloc(ioa_cfg->max_devs_supported, - sizeof(struct ipr_resource_entry), - GFP_KERNEL); + ioa_cfg->res_entries = kzalloc_objs(struct ipr_resource_entry, + ioa_cfg->max_devs_supported); if (!ioa_cfg->res_entries) goto out; @@ -9026,9 +9026,8 @@ static int ipr_alloc_mem(struct ipr_ioa_cfg *ioa_cfg) list_add_tail(&ioa_cfg->hostrcb[i]->queue, &ioa_cfg->hostrcb_free_q); } - ioa_cfg->trace = kcalloc(IPR_NUM_TRACE_ENTRIES, - sizeof(struct ipr_trace_entry), - GFP_KERNEL); + ioa_cfg->trace = kzalloc_objs(struct ipr_trace_entry, + IPR_NUM_TRACE_ENTRIES); if (!ioa_cfg->trace) goto out_free_hostrcb_dma; diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 0089b17ed288..41ed73966a48 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -1086,7 +1086,7 @@ static enum scsi_qc_status ips_queue_lck(struct scsi_cmnd *SC) } /* allocate space for the scribble */ - scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC); + scratch = kmalloc_obj(ips_copp_wait_item_t, GFP_ATOMIC); if (!scratch) { SC->result = DID_ERROR << 16; @@ -6874,7 +6874,7 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) } /* found a controller */ - ha = kzalloc(sizeof (ips_ha_t), GFP_KERNEL); + ha = kzalloc_obj(ips_ha_t); if (ha == NULL) { IPS_PRINTK(KERN_WARNING, pci_dev, "Unable to allocate temporary ha struct\n"); @@ -6947,7 +6947,7 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) ha->logical_drive_info_dma_addr = dma_address; - ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL); + ha->conf = kmalloc_obj(IPS_CONF); if (!ha->conf) { IPS_PRINTK(KERN_WARNING, pci_dev, @@ -6955,7 +6955,7 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) return ips_abort_init(ha, index); } - ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL); + ha->nvram = kmalloc_obj(IPS_NVRAM_P5); if (!ha->nvram) { IPS_PRINTK(KERN_WARNING, pci_dev, @@ -6963,7 +6963,7 @@ ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr) return ips_abort_init(ha, index); } - ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL); + ha->subsys = kmalloc_obj(IPS_SUBSYS); if (!ha->subsys) { IPS_PRINTK(KERN_WARNING, pci_dev, diff --git a/drivers/scsi/iscsi_boot_sysfs.c b/drivers/scsi/iscsi_boot_sysfs.c index a64abe38db2d..0b22197bf8f5 100644 --- a/drivers/scsi/iscsi_boot_sysfs.c +++ b/drivers/scsi/iscsi_boot_sysfs.c @@ -344,7 +344,7 @@ iscsi_boot_create_kobj(struct iscsi_boot_kset *boot_kset, { struct iscsi_boot_kobj *boot_kobj; - boot_kobj = kzalloc(sizeof(*boot_kobj), GFP_KERNEL); + boot_kobj = kzalloc_obj(*boot_kobj); if (!boot_kobj) return NULL; INIT_LIST_HEAD(&boot_kobj->list); @@ -497,7 +497,7 @@ struct iscsi_boot_kset *iscsi_boot_create_kset(const char *set_name) { struct iscsi_boot_kset *boot_kset; - boot_kset = kzalloc(sizeof(*boot_kset), GFP_KERNEL); + boot_kset = kzalloc_obj(*boot_kset); if (!boot_kset) return NULL; diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c index 86fe19e0468d..6d1fb55cc3ad 100644 --- a/drivers/scsi/lasi700.c +++ b/drivers/scsi/lasi700.c @@ -88,7 +88,7 @@ lasi700_probe(struct parisc_device *dev) struct NCR_700_Host_Parameters *hostdata; struct Scsi_Host *host; - hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); + hostdata = kzalloc_obj(*hostdata); if (!hostdata) { dev_printk(KERN_ERR, &dev->dev, "Failed to allocate host data\n"); return -ENOMEM; diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 60d621ad0024..7792724d5b97 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -116,7 +116,7 @@ static void fc_disc_recv_rscn_req(struct fc_disc *disc, struct fc_frame *fp) case ELS_ADDR_FMT_PORT: FC_DISC_DBG(disc, "Port address format for port " "(%6.6x)\n", ntoh24(pp->rscn_fid)); - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); if (!dp) { redisc = 1; break; diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index f84a7e6ae379..9183a0e9568a 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -2391,7 +2391,7 @@ struct fc_exch_mgr_anchor *fc_exch_mgr_add(struct fc_lport *lport, { struct fc_exch_mgr_anchor *ema; - ema = kmalloc(sizeof(*ema), GFP_ATOMIC); + ema = kmalloc_obj(*ema, GFP_ATOMIC); if (!ema) return ema; @@ -2480,7 +2480,7 @@ struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lport, /* * allocate memory for EM */ - mp = kzalloc(sizeof(struct fc_exch_mgr), GFP_ATOMIC); + mp = kzalloc_obj(struct fc_exch_mgr, GFP_ATOMIC); if (!mp) return NULL; diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index 2f93f6c65a86..a5139e43ca4c 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -2298,7 +2298,7 @@ int fc_fcp_init(struct fc_lport *lport) if (!lport->tt.fcp_abort_io) lport->tt.fcp_abort_io = fc_fcp_abort_io; - si = kzalloc(sizeof(struct fc_fcp_internal), GFP_KERNEL); + si = kzalloc_obj(struct fc_fcp_internal); if (!si) return -ENOMEM; lport->scsi_priv = si; diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c index 310fa5add5f0..32683ea6953c 100644 --- a/drivers/scsi/libfc/fc_lport.c +++ b/drivers/scsi/libfc/fc_lport.c @@ -2049,7 +2049,7 @@ static int fc_lport_els_request(struct bsg_job *job, fh->fh_df_ctl = 0; fh->fh_parm_offset = 0; - info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); + info = kzalloc_obj(struct fc_bsg_info); if (!info) { fc_frame_free(fp); return -ENOMEM; @@ -2109,7 +2109,7 @@ static int fc_lport_ct_request(struct bsg_job *job, fh->fh_df_ctl = 0; fh->fh_parm_offset = 0; - info = kzalloc(sizeof(struct fc_bsg_info), GFP_KERNEL); + info = kzalloc_obj(struct fc_bsg_info); if (!info) { fc_frame_free(fp); return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index bcecb4911da9..61368e55bf86 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -579,7 +579,7 @@ int sas_ata_init(struct domain_device *found_dev) struct ata_port *ap; int rc; - ata_host = kzalloc(sizeof(*ata_host), GFP_KERNEL); + ata_host = kzalloc_obj(*ata_host); if (!ata_host) { pr_err("ata host alloc failed.\n"); return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index d953225f6cc2..f471ab464a78 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -433,7 +433,7 @@ static int sas_expander_discover(struct domain_device *dev) struct expander_device *ex = &dev->ex_dev; int res; - ex->ex_phy = kcalloc(ex->num_phys, sizeof(*ex->ex_phy), GFP_KERNEL); + ex->ex_phy = kzalloc_objs(*ex->ex_phy, ex->num_phys); if (!ex->ex_phy) return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index 6b15ad1bcada..0bec236f0fb5 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c @@ -39,7 +39,7 @@ struct sas_task *sas_alloc_task(gfp_t flags) struct sas_task *sas_alloc_slow_task(gfp_t flags) { struct sas_task *task = sas_alloc_task(flags); - struct sas_task_slow *slow = kmalloc(sizeof(*slow), flags); + struct sas_task_slow *slow = kmalloc_obj(*slow, flags); if (!task || !slow) { if (task) @@ -505,7 +505,7 @@ static void phy_enable_work(struct work_struct *work) static int sas_phy_setup(struct sas_phy *phy) { - struct sas_phy_data *d = kzalloc(sizeof(*d), GFP_KERNEL); + struct sas_phy_data *d = kzalloc_obj(*d); if (!d) return -ENOMEM; diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h index d104c87f04f5..7dce0f587149 100644 --- a/drivers/scsi/libsas/sas_internal.h +++ b/drivers/scsi/libsas/sas_internal.h @@ -192,7 +192,7 @@ static inline void sas_phy_set_target(struct asd_sas_phy *p, struct domain_devic static inline struct domain_device *sas_alloc_device(void) { - struct domain_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct domain_device *dev = kzalloc_obj(*dev); if (dev) { INIT_LIST_HEAD(&dev->siblings); diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 4af5c069635a..53f41d68e0d8 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2041,7 +2041,7 @@ lpfc_xcvr_data_show(struct device *dev, struct device_attribute *attr, struct sff_trasnceiver_codes_byte7 *trasn_code_byte7; /* Get transceiver information */ - rdp_context = kmalloc(sizeof(*rdp_context), GFP_KERNEL); + rdp_context = kmalloc_obj(*rdp_context); if (!rdp_context) { len = scnprintf(buf, PAGE_SIZE - len, "SPF info NA: alloc failure\n"); diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index d61d979f9b77..7406dfa60016 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -174,7 +174,7 @@ lpfc_alloc_bsg_buffers(struct lpfc_hba *phba, unsigned int size, /* Allocate dma buffer and place in BPL passed */ while (bytes_left) { /* Allocate dma buffer */ - mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc_obj(struct lpfc_dmabuf); if (!mp) { if (mlist) lpfc_free_bsg_buffers(phba, mlist); @@ -416,7 +416,7 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job) return -ENODEV; /* allocate our bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, "2733 Failed allocation of dd_data\n"); @@ -430,7 +430,7 @@ lpfc_bsg_send_mgmt_cmd(struct bsg_job *job) goto free_dd; } - bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc_obj(struct lpfc_dmabuf); if (!bmp) { rc = -ENOMEM; goto free_cmdiocbq; @@ -683,7 +683,7 @@ lpfc_bsg_rport_els(struct bsg_job *job) } /* allocate our bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, "2735 Failed allocation of dd_data\n"); @@ -843,7 +843,7 @@ lpfc_bsg_event_unref(struct lpfc_bsg_event *evt) static struct lpfc_bsg_event * lpfc_bsg_event_new(uint32_t ev_mask, int ev_reg_id, uint32_t ev_req_id) { - struct lpfc_bsg_event *evt = kzalloc(sizeof(*evt), GFP_KERNEL); + struct lpfc_bsg_event *evt = kzalloc_obj(*evt); if (!evt) return NULL; @@ -939,7 +939,7 @@ lpfc_bsg_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, lpfc_bsg_event_ref(evt); spin_unlock_irqrestore(&phba->ct_ev_lock, flags); - evt_dat = kzalloc(sizeof(*evt_dat), GFP_KERNEL); + evt_dat = kzalloc_obj(*evt_dat); if (evt_dat == NULL) { spin_lock_irqsave(&phba->ct_ev_lock, flags); lpfc_bsg_event_unref(evt); @@ -1215,7 +1215,7 @@ lpfc_bsg_hba_set_event(struct bsg_job *job) if (&evt->node == &phba->ct_ev_waiters) { /* no event waiting struct yet - first call */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (dd_data == NULL) { lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, "2734 Failed allocation of dd_data\n"); @@ -1477,7 +1477,7 @@ lpfc_issue_ct_rsp(struct lpfc_hba *phba, struct bsg_job *job, uint32_t tag, } /* allocate our bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, "2736 Failed allocation of dd_data\n"); @@ -1605,7 +1605,7 @@ lpfc_bsg_send_mgmt_rsp(struct bsg_job *job) goto send_mgmt_rsp_exit; } - bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc_obj(struct lpfc_dmabuf); if (!bmp) { rc = -ENOMEM; goto send_mgmt_rsp_exit; @@ -2628,7 +2628,7 @@ static int lpfcdiag_loop_get_xri(struct lpfc_hba *phba, uint16_t rpi, cmdiocbq = lpfc_sli_get_iocbq(phba); rspiocbq = lpfc_sli_get_iocbq(phba); - dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + dmabuf = kmalloc_obj(struct lpfc_dmabuf); if (dmabuf) { dmabuf->virt = lpfc_mbuf_alloc(phba, 0, &dmabuf->phys); if (dmabuf->virt) { @@ -2733,7 +2733,7 @@ lpfc_bsg_dma_page_alloc(struct lpfc_hba *phba) struct pci_dev *pcidev = phba->pcidev; /* allocate dma buffer struct */ - dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + dmabuf = kmalloc_obj(struct lpfc_dmabuf); if (!dmabuf) return NULL; @@ -2829,7 +2829,7 @@ diag_cmd_data_alloc(struct lpfc_hba *phba, cnt = size; /* allocate struct lpfc_dmabufext buffer header */ - dmp = kmalloc(sizeof(struct lpfc_dmabufext), GFP_KERNEL); + dmp = kmalloc_obj(struct lpfc_dmabufext); if (!dmp) goto out; @@ -2909,7 +2909,7 @@ static int lpfcdiag_sli3_loop_post_rxbufs(struct lpfc_hba *phba, uint16_t rxxri, pring = lpfc_phba_elsring(phba); cmdiocbq = lpfc_sli_get_iocbq(phba); - rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + rxbmp = kmalloc_obj(struct lpfc_dmabuf); if (rxbmp != NULL) { rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys); if (rxbmp->virt) { @@ -3160,7 +3160,7 @@ lpfc_bsg_diag_loopback_run(struct bsg_job *job) cmdiocbq = lpfc_sli_get_iocbq(phba); if (phba->sli_rev < LPFC_SLI_REV4) rspiocbq = lpfc_sli_get_iocbq(phba); - txbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + txbmp = kmalloc_obj(struct lpfc_dmabuf); if (txbmp) { txbmp->virt = lpfc_mbuf_alloc(phba, 0, &txbmp->phys); @@ -4074,7 +4074,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, } /* bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { rc = -ENOMEM; goto job_error; @@ -4275,7 +4275,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, if (ext_buf_cnt == 1) { /* bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { rc = -ENOMEM; goto job_error; @@ -4624,7 +4624,7 @@ lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct bsg_job *job, "ebuffers received\n", phba->mbox_ext_buf_ctx.numBuf); - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { rc = -ENOMEM; goto job_error; @@ -4896,7 +4896,7 @@ lpfc_bsg_issue_mbox(struct lpfc_hba *phba, struct bsg_job *job, goto job_done; /* must be negative */ /* allocate our bsg tracking structure */ - dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL); + dd_data = kmalloc_obj(struct bsg_job_data); if (!dd_data) { lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC, "2727 Failed allocation of dd_data\n"); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index d3caac394291..d64f4acfcdae 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -165,7 +165,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, u32 tmo; /* fill in BDEs for command */ - mp = kmalloc(sizeof(*mp), GFP_KERNEL); + mp = kmalloc_obj(*mp); if (!mp) { rc = 1; goto ct_exit; @@ -178,7 +178,7 @@ lpfc_ct_reject_event(struct lpfc_nodelist *ndlp, } /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof(*bmp), GFP_KERNEL); + bmp = kmalloc_obj(*bmp); if (!bmp) { rc = 3; goto ct_free_mpvirt; @@ -498,7 +498,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, __be16 cmdcode, struct ulp_bde64 *bpl, while (size) { /* Allocate buffer for rsp payload */ - mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc_obj(struct lpfc_dmabuf); if (!mp) { if (mlist) lpfc_free_ct_rsp(phba, mlist); @@ -1924,7 +1924,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + mp = kmalloc_obj(struct lpfc_dmabuf); if (!mp) { rc=2; goto ns_cmd_exit; @@ -1938,7 +1938,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, } /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + bmp = kmalloc_obj(struct lpfc_dmabuf); if (!bmp) { rc=4; goto ns_cmd_free_mpvirt; @@ -3220,7 +3220,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - rq = kmalloc(sizeof(*rq), GFP_KERNEL); + rq = kmalloc_obj(*rq); if (!rq) goto fdmi_cmd_exit; @@ -3229,7 +3229,7 @@ lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, goto fdmi_cmd_free_rq; /* Allocate buffer for Buffer ptr list */ - rsp = kmalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kmalloc_obj(*rsp); if (!rsp) goto fdmi_cmd_free_rqvirt; @@ -3716,7 +3716,7 @@ lpfc_vmid_cmd(struct lpfc_vport *vport, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - mp = kmalloc(sizeof(*mp), GFP_KERNEL); + mp = kmalloc_obj(*mp); if (!mp) goto vmid_free_mp_exit; @@ -3725,7 +3725,7 @@ lpfc_vmid_cmd(struct lpfc_vport *vport, goto vmid_free_mp_virt_exit; /* Allocate buffer for Buffer ptr list */ - bmp = kmalloc(sizeof(*bmp), GFP_KERNEL); + bmp = kmalloc_obj(*bmp); if (!bmp) goto vmid_free_bmp_exit; diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 646f88c776f5..052023fc1733 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -1951,7 +1951,7 @@ lpfc_debugfs_disc_trc_open(struct inode *inode, struct file *file) goto out; } - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2001,7 +2001,7 @@ lpfc_debugfs_slow_ring_trc_open(struct inode *inode, struct file *file) goto out; } - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2045,7 +2045,7 @@ lpfc_debugfs_hbqinfo_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2087,7 +2087,7 @@ lpfc_debugfs_multixripools_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2132,7 +2132,7 @@ lpfc_debugfs_lockstat_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2269,7 +2269,7 @@ lpfc_debugfs_ras_log_open(struct inode *inode, struct file *file) phba->cfg_ras_fwlog_buffsize, &size)) goto out; - debug = kzalloc(sizeof(*debug), GFP_KERNEL); + debug = kzalloc_obj(*debug); if (!debug) goto out; @@ -2316,7 +2316,7 @@ lpfc_debugfs_dumpHBASlim_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2358,7 +2358,7 @@ lpfc_debugfs_dumpHostSlim_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2522,7 +2522,7 @@ lpfc_debugfs_nodelist_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2688,7 +2688,7 @@ lpfc_debugfs_nvmestat_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2776,7 +2776,7 @@ lpfc_debugfs_scsistat_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2830,7 +2830,7 @@ lpfc_debugfs_ioktime_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -2957,7 +2957,7 @@ lpfc_debugfs_nvmeio_trc_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -3062,7 +3062,7 @@ lpfc_debugfs_hdwqstat_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -3226,7 +3226,7 @@ lpfc_idiag_open(struct inode *inode, struct file *file) { struct lpfc_debug *debug; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) return -ENOMEM; @@ -5471,7 +5471,7 @@ lpfc_cgn_buffer_open(struct inode *inode, struct file *file) struct lpfc_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -5563,7 +5563,7 @@ lpfc_rx_monitor_open(struct inode *inode, struct file *file) struct lpfc_rx_monitor_debug *debug; int rc = -ENOMEM; - debug = kmalloc(sizeof(*debug), GFP_KERNEL); + debug = kmalloc_obj(*debug); if (!debug) goto out; @@ -6210,10 +6210,8 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) phba->hba_debugfs_root, phba, &lpfc_debugfs_op_slow_ring_trc); if (!phba->slow_ring_trc) { - phba->slow_ring_trc = kcalloc( - lpfc_debugfs_max_slow_ring_trc, - sizeof(struct lpfc_debugfs_trc), - GFP_KERNEL); + phba->slow_ring_trc = kzalloc_objs(struct lpfc_debugfs_trc, + lpfc_debugfs_max_slow_ring_trc); if (!phba->slow_ring_trc) { lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT, "0416 Cannot create debugfs " diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 32da3c23c7f4..cee709617a31 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -216,7 +216,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, u8 expect_rsp, /* fill in BDEs for command */ /* Allocate buffer for command payload */ - pcmd = kmalloc(sizeof(*pcmd), GFP_KERNEL); + pcmd = kmalloc_obj(*pcmd); if (pcmd) pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); if (!pcmd || !pcmd->virt) @@ -226,7 +226,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, u8 expect_rsp, /* Allocate buffer for response payload */ if (expect_rsp) { - prsp = kmalloc(sizeof(*prsp), GFP_KERNEL); + prsp = kmalloc_obj(*prsp); if (prsp) prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &prsp->phys); @@ -238,7 +238,7 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, u8 expect_rsp, } /* Allocate buffer for Buffer ptr list */ - pbuflist = kmalloc(sizeof(*pbuflist), GFP_KERNEL); + pbuflist = kmalloc_obj(*pbuflist); if (pbuflist) pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pbuflist->phys); @@ -7537,7 +7537,7 @@ lpfc_els_rcv_rdp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, if (RDP_NPORT_ID_SIZE != be32_to_cpu(rdp_req->nport_id_desc.length)) goto rjt_logerr; - rdp_context = kzalloc(sizeof(struct lpfc_rdp_context), GFP_KERNEL); + rdp_context = kzalloc_obj(struct lpfc_rdp_context); if (!rdp_context) { rjt_err = LSRJT_UNABLE_TPC; goto error; @@ -7842,7 +7842,7 @@ lpfc_els_rcv_lcb(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, goto rjt; } - lcb_context = kmalloc(sizeof(*lcb_context), GFP_KERNEL); + lcb_context = kmalloc_obj(*lcb_context); if (!lcb_context) { rjt_err = LSRJT_UNABLE_TPC; goto rjt; @@ -9965,7 +9965,7 @@ lpfc_send_els_event(struct lpfc_vport *vport, struct Scsi_Host *shost = lpfc_shost_from_vport(vport); if (*payload == ELS_CMD_LOGO) { - logo_data = kmalloc(sizeof(struct lpfc_logo_event), GFP_KERNEL); + logo_data = kmalloc_obj(struct lpfc_logo_event); if (!logo_data) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0148 Failed to allocate memory " @@ -9974,8 +9974,7 @@ lpfc_send_els_event(struct lpfc_vport *vport, } els_data = &logo_data->header; } else { - els_data = kmalloc(sizeof(struct lpfc_els_event_header), - GFP_KERNEL); + els_data = kmalloc_obj(struct lpfc_els_event_header); if (!els_data) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "0149 Failed to allocate memory " @@ -12325,8 +12324,7 @@ lpfc_cmpl_els_qfpa(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (!vport->qfpa_res) { max_desc = FCELSSIZE / sizeof(*vport->qfpa_res); - vport->qfpa_res = kcalloc(max_desc, sizeof(*vport->qfpa_res), - GFP_KERNEL); + vport->qfpa_res = kzalloc_objs(*vport->qfpa_res, max_desc); if (!vport->qfpa_res) goto out; } @@ -12339,8 +12337,7 @@ lpfc_cmpl_els_qfpa(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, desc = (struct priority_range_desc *)(pcmd + 8); vmid_range = vport->vmid_priority.vmid_range; if (!vmid_range) { - vmid_range = kcalloc(MAX_PRIORITY_DESC, sizeof(*vmid_range), - GFP_KERNEL); + vmid_range = kzalloc_objs(*vmid_range, MAX_PRIORITY_DESC); if (!vmid_range) { kfree(vport->qfpa_res); goto out; @@ -12438,7 +12435,7 @@ lpfc_vmid_uvem(struct lpfc_vport *vport, if (!ndlp || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) return -ENXIO; - vmid_context = kmalloc(sizeof(*vmid_context), GFP_KERNEL); + vmid_context = kmalloc_obj(*vmid_context); if (!vmid_context) return -ENOMEM; elsiocb = lpfc_prep_els_iocb(vport, 1, LPFC_UVEM_SIZE, 2, diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1aeebdc08073..8aaf05d7bb0a 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -726,8 +726,7 @@ lpfc_alloc_fast_evt(struct lpfc_hba *phba) { if (atomic_read(&phba->fast_event_count) > LPFC_MAX_EVT_COUNT) return NULL; - ret = kzalloc(sizeof(struct lpfc_fast_path_event), - GFP_ATOMIC); + ret = kzalloc_obj(struct lpfc_fast_path_event, GFP_ATOMIC); if (ret) { atomic_inc(&phba->fast_event_count); INIT_LIST_HEAD(&ret->work_evt.evt_listp); @@ -1141,7 +1140,7 @@ lpfc_workq_post_event(struct lpfc_hba *phba, void *arg1, void *arg2, * All Mailbox completions and LPFC_ELS_RING rcv ring IOCB events will * be queued to worker thread for processing */ - evtp = kmalloc(sizeof(struct lpfc_work_evt), GFP_ATOMIC); + evtp = kmalloc_obj(struct lpfc_work_evt, GFP_ATOMIC); if (!evtp) return 0; @@ -3644,8 +3643,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) * defaults. */ if (!test_bit(HBA_FIP_SUPPORT, &phba->hba_flag)) { - fcf_record = kzalloc(sizeof(struct fcf_record), - GFP_KERNEL); + fcf_record = kzalloc_obj(struct fcf_record); if (unlikely(!fcf_record)) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -4056,7 +4054,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba) memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); mb = &pmb->u.mb; - vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL); + vport_info = kzalloc_obj(struct static_vport_info); if (!vport_info) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "0543 lpfc_create_static_vport failed to" @@ -7012,8 +7010,7 @@ lpfc_read_fcf_conn_tbl(struct lpfc_hba *phba, for (i = 0; i < record_count; i++) { if (!(conn_rec[i].flags & FCFCNCT_VALID)) continue; - conn_entry = kzalloc(sizeof(struct lpfc_fcf_conn_entry), - GFP_KERNEL); + conn_entry = kzalloc_obj(struct lpfc_fcf_conn_entry); if (!conn_entry) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2566 Failed to allocate connection" diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index a116a16c4a6f..e9d9ac7da485 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -2820,7 +2820,7 @@ lpfc_sli3_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cn /* 2 buffers can be posted per command */ /* Allocate buffer to post */ - mp1 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + mp1 = kmalloc_obj(struct lpfc_dmabuf); if (mp1) mp1->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp1->phys); if (!mp1 || !mp1->virt) { @@ -2833,7 +2833,7 @@ lpfc_sli3_post_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, int cn INIT_LIST_HEAD(&mp1->list); /* Allocate buffer to post */ if (cnt > 1) { - mp2 = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); + mp2 = kmalloc_obj(struct lpfc_dmabuf); if (mp2) mp2->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &mp2->phys); @@ -3539,7 +3539,7 @@ void lpfc_create_multixri_pools(struct lpfc_hba *phba) count_per_hwq = phba->sli4_hba.io_xri_cnt / hwq_count; for (i = 0; i < hwq_count; i++) { - multixri_pool = kzalloc(sizeof(*multixri_pool), GFP_KERNEL); + multixri_pool = kzalloc_obj(*multixri_pool); if (!multixri_pool) { lpfc_printf_log(phba, KERN_INFO, LOG_INIT, @@ -4064,8 +4064,7 @@ lpfc_sli4_els_sgl_update(struct lpfc_hba *phba) els_xri_cnt); /* allocate the additional els sgls */ for (i = 0; i < xri_cnt; i++) { - sglq_entry = kzalloc(sizeof(struct lpfc_sglq), - GFP_KERNEL); + sglq_entry = kzalloc_obj(struct lpfc_sglq); if (sglq_entry == NULL) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -4184,8 +4183,7 @@ lpfc_sli4_nvmet_sgl_update(struct lpfc_hba *phba) phba->sli4_hba.nvmet_xri_cnt, nvmet_xri_cnt); /* allocate the additional nvmet sgls */ for (i = 0; i < xri_cnt; i++) { - sglq_entry = kzalloc(sizeof(struct lpfc_sglq), - GFP_KERNEL); + sglq_entry = kzalloc_obj(struct lpfc_sglq); if (sglq_entry == NULL) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, @@ -4478,7 +4476,7 @@ lpfc_new_io_buf(struct lpfc_hba *phba, int num_to_alloc) phba->sli4_hba.io_xri_cnt = 0; for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { - lpfc_ncmd = kzalloc(sizeof(*lpfc_ncmd), GFP_KERNEL); + lpfc_ncmd = kzalloc_obj(*lpfc_ncmd); if (!lpfc_ncmd) break; /* @@ -4637,8 +4635,7 @@ lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport) if (lpfc_is_vmid_enabled(phba)) { vport->vmid = - kcalloc(phba->cfg_max_vmid, sizeof(struct lpfc_vmid), - GFP_KERNEL); + kzalloc_objs(struct lpfc_vmid, phba->cfg_max_vmid); if (!vport->vmid) return -ENOMEM; @@ -7773,9 +7770,8 @@ lpfc_sli_driver_resource_setup(struct lpfc_hba *phba) return -ENODEV; if (!phba->sli.sli3_ring) - phba->sli.sli3_ring = kcalloc(LPFC_SLI3_MAX_RING, - sizeof(struct lpfc_sli_ring), - GFP_KERNEL); + phba->sli.sli3_ring = kzalloc_objs(struct lpfc_sli_ring, + LPFC_SLI3_MAX_RING); if (!phba->sli.sli3_ring) return -ENOMEM; @@ -8357,9 +8353,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) goto out_remove_rpi_hdrs; } - phba->sli4_hba.hba_eq_hdl = kcalloc(phba->cfg_irq_chann, - sizeof(struct lpfc_hba_eq_hdl), - GFP_KERNEL); + phba->sli4_hba.hba_eq_hdl = kzalloc_objs(struct lpfc_hba_eq_hdl, + phba->cfg_irq_chann); if (!phba->sli4_hba.hba_eq_hdl) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "2572 Failed allocate memory for " @@ -8368,9 +8363,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) goto out_free_fcf_rr_bmask; } - phba->sli4_hba.cpu_map = kcalloc(phba->sli4_hba.num_possible_cpu, - sizeof(struct lpfc_vector_map_info), - GFP_KERNEL); + phba->sli4_hba.cpu_map = kzalloc_objs(struct lpfc_vector_map_info, + phba->sli4_hba.num_possible_cpu); if (!phba->sli4_hba.cpu_map) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3327 Failed allocate memory for msi-x " @@ -8387,9 +8381,8 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) goto out_free_hba_cpu_map; } - phba->sli4_hba.idle_stat = kcalloc(phba->sli4_hba.num_possible_cpu, - sizeof(*phba->sli4_hba.idle_stat), - GFP_KERNEL); + phba->sli4_hba.idle_stat = kzalloc_objs(*phba->sli4_hba.idle_stat, + phba->sli4_hba.num_possible_cpu); if (!phba->sli4_hba.idle_stat) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3390 Failed allocation for idle_stat\n"); @@ -8663,7 +8656,7 @@ lpfc_init_iocb_list(struct lpfc_hba *phba, int iocb_count) /* Initialize and populate the iocb list per host. */ INIT_LIST_HEAD(&phba->lpfc_iocb_list); for (i = 0; i < iocb_count; i++) { - iocbq_entry = kzalloc(sizeof(struct lpfc_iocbq), GFP_KERNEL); + iocbq_entry = kzalloc_obj(struct lpfc_iocbq); if (iocbq_entry == NULL) { printk(KERN_ERR "%s: only allocated %d iocbs of " "expected %d count. Unloading driver.\n", @@ -8913,7 +8906,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) * First allocate the protocol header region for the port. The * port expects a 4KB DMA-mapped memory region that is 4K aligned. */ - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + dmabuf = kzalloc_obj(struct lpfc_dmabuf); if (!dmabuf) return NULL; @@ -8931,7 +8924,7 @@ lpfc_sli4_create_rpi_hdr(struct lpfc_hba *phba) } /* Save the rpi header data for cleanup later. */ - rpi_hdr = kzalloc(sizeof(struct lpfc_rpi_hdr), GFP_KERNEL); + rpi_hdr = kzalloc_obj(struct lpfc_rpi_hdr); if (!rpi_hdr) goto err_free_coherent; @@ -9004,7 +8997,7 @@ lpfc_hba_alloc(struct pci_dev *pdev) struct lpfc_hba *phba; /* Allocate memory for HBA structure */ - phba = kzalloc(sizeof(struct lpfc_hba), GFP_KERNEL); + phba = kzalloc_obj(struct lpfc_hba); if (!phba) { dev_err(&pdev->dev, "failed to allocate hba struct\n"); return NULL; @@ -9722,7 +9715,7 @@ lpfc_create_bootstrap_mbox(struct lpfc_hba *phba) uint32_t pa_addr; uint64_t phys_addr; - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + dmabuf = kzalloc_obj(struct lpfc_dmabuf); if (!dmabuf) return -ENOMEM; @@ -10442,9 +10435,8 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) phba->sli4_hba.cq_ecount = LPFC_CQE_DEF_COUNT; if (!phba->sli4_hba.hdwq) { - phba->sli4_hba.hdwq = kcalloc( - phba->cfg_hdw_queue, sizeof(struct lpfc_sli4_hdw_queue), - GFP_KERNEL); + phba->sli4_hba.hdwq = kzalloc_objs(struct lpfc_sli4_hdw_queue, + phba->cfg_hdw_queue); if (!phba->sli4_hba.hdwq) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "6427 Failed allocate memory for " @@ -10473,30 +10465,24 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME) { if (phba->nvmet_support) { - phba->sli4_hba.nvmet_cqset = kcalloc( - phba->cfg_nvmet_mrq, - sizeof(struct lpfc_queue *), - GFP_KERNEL); + phba->sli4_hba.nvmet_cqset = kzalloc_objs(struct lpfc_queue *, + phba->cfg_nvmet_mrq); if (!phba->sli4_hba.nvmet_cqset) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3121 Fail allocate memory for " "fast-path CQ set array\n"); goto out_error; } - phba->sli4_hba.nvmet_mrq_hdr = kcalloc( - phba->cfg_nvmet_mrq, - sizeof(struct lpfc_queue *), - GFP_KERNEL); + phba->sli4_hba.nvmet_mrq_hdr = kzalloc_objs(struct lpfc_queue *, + phba->cfg_nvmet_mrq); if (!phba->sli4_hba.nvmet_mrq_hdr) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3122 Fail allocate memory for " "fast-path RQ set hdr array\n"); goto out_error; } - phba->sli4_hba.nvmet_mrq_data = kcalloc( - phba->cfg_nvmet_mrq, - sizeof(struct lpfc_queue *), - GFP_KERNEL); + phba->sli4_hba.nvmet_mrq_data = kzalloc_objs(struct lpfc_queue *, + phba->cfg_nvmet_mrq); if (!phba->sli4_hba.nvmet_mrq_data) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "3124 Fail allocate memory for " @@ -11381,8 +11367,8 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) if (phba->sli4_hba.cq_max) { kfree(phba->sli4_hba.cq_lookup); - phba->sli4_hba.cq_lookup = kcalloc((phba->sli4_hba.cq_max + 1), - sizeof(struct lpfc_queue *), GFP_KERNEL); + phba->sli4_hba.cq_lookup = kzalloc_objs(struct lpfc_queue *, + (phba->sli4_hba.cq_max + 1)); if (!phba->sli4_hba.cq_lookup) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "0549 Failed setup of CQ Lookup table: " @@ -11511,7 +11497,7 @@ lpfc_sli4_cq_event_pool_create(struct lpfc_hba *phba) int i; for (i = 0; i < (4 * phba->sli4_hba.cq_ecount); i++) { - cq_event = kmalloc(sizeof(struct lpfc_cq_event), GFP_KERNEL); + cq_event = kmalloc_obj(struct lpfc_cq_event); if (!cq_event) goto out_pool_create_fail; list_add_tail(&cq_event->list, @@ -12039,6 +12025,8 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba) iounmap(phba->sli4_hba.conf_regs_memmap_p); if (phba->sli4_hba.dpp_regs_memmap_p) iounmap(phba->sli4_hba.dpp_regs_memmap_p); + if (phba->sli4_hba.dpp_regs_memmap_wc_p) + iounmap(phba->sli4_hba.dpp_regs_memmap_wc_p); break; case LPFC_SLI_INTF_IF_TYPE_1: break; @@ -14616,8 +14604,7 @@ lpfc_write_firmware(const struct firmware *fw, void *context) "New Version:%s\n", fwrev, image->revision); for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) { - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), - GFP_KERNEL); + dmabuf = kzalloc_obj(struct lpfc_dmabuf); if (!dmabuf) { rc = -ENOMEM; goto release_out; diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index fb6dbcb86c09..d07c2786cb12 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c @@ -64,7 +64,7 @@ lpfc_mbox_rsrc_prep(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) { struct lpfc_dmabuf *mp; - mp = kmalloc(sizeof(*mp), GFP_KERNEL); + mp = kmalloc_obj(*mp); if (!mp) return -ENOMEM; @@ -1869,8 +1869,7 @@ lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox, pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ? LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount; /* Allocate record for keeping SGE virtual addresses */ - mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt), - GFP_KERNEL); + mbox->sge_array = kzalloc_obj(struct lpfc_mbx_nembed_sge_virt); if (!mbox->sge_array) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX, "2527 Failed to allocate non-embedded SGE " diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 2697da3248b3..057a7910c570 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c @@ -118,9 +118,7 @@ lpfc_mem_alloc(struct lpfc_hba *phba, int align) if (!phba->lpfc_mbuf_pool) goto fail; - pool->elements = kmalloc_array(LPFC_MBUF_POOL_SIZE, - sizeof(struct lpfc_dmabuf), - GFP_KERNEL); + pool->elements = kmalloc_objs(struct lpfc_dmabuf, LPFC_MBUF_POOL_SIZE); if (!pool->elements) goto fail_free_lpfc_mbuf_pool; @@ -511,7 +509,7 @@ lpfc_els_hbq_alloc(struct lpfc_hba *phba) { struct hbq_dmabuf *hbqbp; - hbqbp = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); + hbqbp = kzalloc_obj(struct hbq_dmabuf); if (!hbqbp) return NULL; @@ -563,7 +561,7 @@ lpfc_sli4_rb_alloc(struct lpfc_hba *phba) { struct hbq_dmabuf *dma_buf; - dma_buf = kzalloc(sizeof(struct hbq_dmabuf), GFP_KERNEL); + dma_buf = kzalloc_obj(struct hbq_dmabuf); if (!dma_buf) return NULL; @@ -621,7 +619,7 @@ lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba) { struct rqb_dmabuf *dma_buf; - dma_buf = kzalloc(sizeof(*dma_buf), GFP_KERNEL); + dma_buf = kzalloc_obj(*dma_buf); if (!dma_buf) return NULL; diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 8240d59f4120..5e431928de0b 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -564,7 +564,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if (!login_mbox) goto out; - save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL); + save_iocb = kzalloc_obj(*save_iocb); if (!save_iocb) goto out; @@ -764,7 +764,7 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * registered. */ if (test_bit(NLP_RPI_REGISTERED, &ndlp->nlp_flag)) { - elsiocb = kmalloc(sizeof(*elsiocb), GFP_KERNEL); + elsiocb = kmalloc_obj(*elsiocb); if (elsiocb) { /* Save info from cmd IOCB used in * rsp diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index e6f632521cff..a6b3b16f870d 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -98,7 +98,7 @@ lpfc_nvme_create_queue(struct nvme_fc_local_port *pnvme_lport, test_bit(HBA_IOQ_FLUSH, &vport->phba->hba_flag)) return -ENODEV; - qhandle = kzalloc(sizeof(struct lpfc_nvme_qhandle), GFP_KERNEL); + qhandle = kzalloc_obj(struct lpfc_nvme_qhandle); if (qhandle == NULL) return -ENOMEM; @@ -587,7 +587,7 @@ __lpfc_nvme_ls_req(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * in the nvme-fc layer. */ - bmp = kmalloc(sizeof(*bmp), GFP_KERNEL); + bmp = kmalloc_obj(*bmp); if (!bmp) { lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT, "6044 NVMEx LS REQ: Could not alloc LS buf " diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 4cfc928bcf2d..debd9317103a 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -1507,9 +1507,8 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba) "6403 Allocate NVMET resources for %d XRIs\n", phba->sli4_hba.nvmet_xri_cnt); - phba->sli4_hba.nvmet_ctx_info = kcalloc( - phba->sli4_hba.num_possible_cpu * phba->cfg_nvmet_mrq, - sizeof(struct lpfc_nvmet_ctx_info), GFP_KERNEL); + phba->sli4_hba.nvmet_ctx_info = kzalloc_objs(struct lpfc_nvmet_ctx_info, + phba->sli4_hba.num_possible_cpu * phba->cfg_nvmet_mrq); if (!phba->sli4_hba.nvmet_ctx_info) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "6419 Failed allocate memory for " @@ -1567,15 +1566,14 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba) idx = 0; cpu = cpumask_first(cpu_present_mask); for (i = 0; i < phba->sli4_hba.nvmet_xri_cnt; i++) { - ctx_buf = kzalloc(sizeof(*ctx_buf), GFP_KERNEL); + ctx_buf = kzalloc_obj(*ctx_buf); if (!ctx_buf) { lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, "6404 Ran out of memory for NVMET\n"); return -ENOMEM; } - ctx_buf->context = kzalloc(sizeof(*ctx_buf->context), - GFP_KERNEL); + ctx_buf->context = kzalloc_obj(*ctx_buf->context); if (!ctx_buf->context) { kfree(ctx_buf); lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT, diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index df64948e55ee..69bf1ac6f846 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -265,7 +265,7 @@ lpfc_new_scsi_buf_s3(struct lpfc_vport *vport, int num_to_alloc) (int)sizeof(struct fcp_rsp), bpl_size); for (bcnt = 0; bcnt < num_to_alloc; bcnt++) { - psb = kzalloc(sizeof(struct lpfc_io_buf), GFP_KERNEL); + psb = kzalloc_obj(struct lpfc_io_buf); if (!psb) break; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 734af3d039f8..303523f754b8 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2135,8 +2135,7 @@ lpfc_sli_next_iotag(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq) - LPFC_IOCBQ_LOOKUP_INCREMENT)) { new_len = psli->iocbq_lookup_len + LPFC_IOCBQ_LOOKUP_INCREMENT; spin_unlock_irq(&phba->hbalock); - new_arr = kcalloc(new_len, sizeof(struct lpfc_iocbq *), - GFP_KERNEL); + new_arr = kzalloc_objs(struct lpfc_iocbq *, new_len); if (new_arr) { spin_lock_irq(&phba->hbalock); old_arr = psli->iocbq_lookup; @@ -3240,7 +3239,7 @@ lpfc_nvme_unsol_ls_handler(struct lpfc_hba *phba, struct lpfc_iocbq *piocb) (FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT))) { failwhy = "Bad NVME LS F_CTL"; } else { - axchg = kzalloc(sizeof(*axchg), GFP_ATOMIC); + axchg = kzalloc_obj(*axchg, GFP_ATOMIC); if (!axchg) failwhy = "No CTX memory"; } @@ -5894,7 +5893,7 @@ lpfc_sli4_read_rev(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, struct lpfc_dmabuf *dmabuf; struct lpfc_mqe *mqe; - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + dmabuf = kzalloc_obj(struct lpfc_dmabuf); if (!dmabuf) return -ENOMEM; @@ -6944,8 +6943,7 @@ lpfc_sli4_ras_dma_alloc(struct lpfc_hba *phba, ras_fwlog->fw_buffcount = fwlog_buff_count; for (i = 0; i < ras_fwlog->fw_buffcount; i++) { - dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), - GFP_KERNEL); + dmabuf = kzalloc_obj(struct lpfc_dmabuf); if (!dmabuf) { rc = -ENOMEM; lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, @@ -8048,8 +8046,7 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba) int lpfc_rx_monitor_create_ring(struct lpfc_rx_info_monitor *rx_monitor, u32 entries) { - rx_monitor->ring = kmalloc_array(entries, sizeof(struct rx_info_entry), - GFP_KERNEL); + rx_monitor->ring = kmalloc_objs(struct rx_info_entry, entries); if (!rx_monitor->ring) return -ENOMEM; @@ -8296,7 +8293,7 @@ lpfc_cmf_setup(struct lpfc_hba *phba) /* Allocate Congestion Information Buffer */ if (!phba->cgn_i) { - mp = kmalloc(sizeof(*mp), GFP_KERNEL); + mp = kmalloc_obj(*mp); if (mp) mp->virt = dma_alloc_coherent (&phba->pcidev->dev, @@ -8378,8 +8375,7 @@ lpfc_cmf_setup(struct lpfc_hba *phba) /* Allocate RX Monitor Buffer */ if (!phba->rx_monitor) { - phba->rx_monitor = kzalloc(sizeof(*phba->rx_monitor), - GFP_KERNEL); + phba->rx_monitor = kzalloc_obj(*phba->rx_monitor); if (!phba->rx_monitor) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -15981,6 +15977,32 @@ lpfc_dual_chute_pci_bar_map(struct lpfc_hba *phba, uint16_t pci_barset) return NULL; } +static __maybe_unused void __iomem * +lpfc_dpp_wc_map(struct lpfc_hba *phba, uint8_t dpp_barset) +{ + + /* DPP region is supposed to cover 64-bit BAR2 */ + if (dpp_barset != WQ_PCI_BAR_4_AND_5) { + lpfc_log_msg(phba, KERN_WARNING, LOG_INIT, + "3273 dpp_barset x%x != WQ_PCI_BAR_4_AND_5\n", + dpp_barset); + return NULL; + } + + if (!phba->sli4_hba.dpp_regs_memmap_wc_p) { + void __iomem *dpp_map; + + dpp_map = ioremap_wc(phba->pci_bar2_map, + pci_resource_len(phba->pcidev, + PCI_64BIT_BAR4)); + + if (dpp_map) + phba->sli4_hba.dpp_regs_memmap_wc_p = dpp_map; + } + + return phba->sli4_hba.dpp_regs_memmap_wc_p; +} + /** * lpfc_modify_hba_eq_delay - Modify Delay Multiplier on EQs * @phba: HBA structure that EQs are on. @@ -16944,9 +16966,6 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, uint8_t dpp_barset; uint32_t dpp_offset; uint8_t wq_create_version; -#ifdef CONFIG_X86 - unsigned long pg_addr; -#endif /* sanity check on queue memory */ if (!wq || !cq) @@ -17132,14 +17151,15 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, #ifdef CONFIG_X86 /* Enable combined writes for DPP aperture */ - pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK; - rc = set_memory_wc(pg_addr, 1); - if (rc) { + bar_memmap_p = lpfc_dpp_wc_map(phba, dpp_barset); + if (!bar_memmap_p) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "3272 Cannot setup Combined " "Write on WQ[%d] - disable DPP\n", wq->queue_id); phba->cfg_enable_dpp = 0; + } else { + wq->dpp_regaddr = bar_memmap_p + dpp_offset; } #else phba->cfg_enable_dpp = 0; @@ -17147,7 +17167,7 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, } else wq->db_regaddr = phba->sli4_hba.WQDBregaddr; } - wq->pring = kzalloc(sizeof(struct lpfc_sli_ring), GFP_KERNEL); + wq->pring = kzalloc_obj(struct lpfc_sli_ring); if (wq->pring == NULL) { status = -ENOMEM; goto out; @@ -19466,7 +19486,7 @@ lpfc_sli4_handle_mds_loopback(struct lpfc_vport *vport, } /* Allocate buffer for command payload */ - pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); + pcmd = kmalloc_obj(struct lpfc_dmabuf); if (pcmd) pcmd->virt = dma_pool_alloc(phba->lpfc_drb_pool, GFP_KERNEL, &pcmd->phys); @@ -22297,7 +22317,7 @@ lpfc_read_object(struct lpfc_hba *phba, char *rdobject, uint32_t *datap, read_object->u.request.rd_object_name[j] = cpu_to_le32(rd_object_name[j]); - pcmd = kmalloc(sizeof(*pcmd), GFP_KERNEL); + pcmd = kmalloc_obj(*pcmd); if (pcmd) pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys); if (!pcmd || !pcmd->virt) { diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index ee58383492b2..b6d90604bb61 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h @@ -785,6 +785,9 @@ struct lpfc_sli4_hba { void __iomem *dpp_regs_memmap_p; /* Kernel memory mapped address for * dpp registers */ + void __iomem *dpp_regs_memmap_wc_p;/* Kernel memory mapped address for + * dpp registers with write combining + */ union { struct { /* IF Type 0, BAR 0 PCI cfg space reg mem map */ diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index aff6c9d5e7c2..f4eadc1028a9 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -787,8 +787,7 @@ lpfc_create_vport_work_array(struct lpfc_hba *phba) struct lpfc_vport *port_iterator; struct lpfc_vport **vports; int index = 0; - vports = kcalloc(phba->max_vports + 1, sizeof(struct lpfc_vport *), - GFP_KERNEL); + vports = kzalloc_objs(struct lpfc_vport *, phba->max_vports + 1); if (vports == NULL) return NULL; spin_lock_irq(&phba->port_list_lock); diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 49f856be2e51..de2bd860b9d7 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -462,9 +462,8 @@ static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *mat * +1 to allow for aligning. * XXX FIXME: Use DMA consistent routines */ - dma_cmd_space = kmalloc_array(host->sg_tablesize + 2, - sizeof(struct dbdma_cmd), - GFP_KERNEL); + dma_cmd_space = kmalloc_objs(struct dbdma_cmd, + host->sg_tablesize + 2); if (!dma_cmd_space) { printk(KERN_ERR "mac53c94: couldn't allocate dma " "command space for %pOF\n", node); diff --git a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c index ff0253d47a0e..a0ceaa2428c2 100644 --- a/drivers/scsi/mac_esp.c +++ b/drivers/scsi/mac_esp.c @@ -323,7 +323,7 @@ static int esp_mac_probe(struct platform_device *dev) host->this_id = esp->scsi_id; esp->scsi_id_mask = 1 << esp->scsi_id; - mep = kzalloc(sizeof(struct mac_esp_priv), GFP_KERNEL); + mep = kzalloc_obj(struct mac_esp_priv); if (!mep) goto fail_free_command_block; mep->esp = esp; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 6b088bb049cc..9476a0d2c72d 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -4254,8 +4254,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_host_put; } - adapter->scb_list = kmalloc_array(MAX_COMMANDS, sizeof(scb_t), - GFP_KERNEL); + adapter->scb_list = kmalloc_objs(scb_t, MAX_COMMANDS); if (!adapter->scb_list) { dev_warn(&pdev->dev, "out of RAM\n"); goto out_free_cmd_buffer; diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index b6a32bb0bd19..06cf94ee4e36 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -429,7 +429,7 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_master(pdev); // Allocate the per driver initialization structure - adapter = kzalloc(sizeof(adapter_t), GFP_KERNEL); + adapter = kzalloc_obj(adapter_t); if (adapter == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -713,7 +713,7 @@ megaraid_init_mbox(adapter_t *adapter) * Allocate and initialize the init data structure for mailbox * controllers */ - raid_dev = kzalloc(sizeof(mraid_device_t), GFP_KERNEL); + raid_dev = kzalloc_obj(mraid_device_t); if (raid_dev == NULL) return -1; @@ -1017,7 +1017,7 @@ megaraid_alloc_cmd_packets(adapter_t *adapter) * since the calling routine does not yet know the number of available * commands. */ - adapter->kscb_list = kcalloc(MBOX_MAX_SCSI_CMDS, sizeof(scb_t), GFP_KERNEL); + adapter->kscb_list = kzalloc_objs(scb_t, MBOX_MAX_SCSI_CMDS); if (adapter->kscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -3403,7 +3403,7 @@ megaraid_cmm_register(adapter_t *adapter) int i; // Allocate memory for the base list of scb for management module. - adapter->uscb_list = kcalloc(MBOX_MAX_USER_CMDS, sizeof(scb_t), GFP_KERNEL); + adapter->uscb_list = kzalloc_objs(scb_t, MBOX_MAX_USER_CMDS); if (adapter->uscb_list == NULL) { con_log(CL_ANN, (KERN_WARNING @@ -3763,9 +3763,9 @@ megaraid_sysfs_alloc_resources(adapter_t *adapter) mraid_device_t *raid_dev = ADAP2RAIDDEV(adapter); int rval = 0; - raid_dev->sysfs_uioc = kmalloc(sizeof(uioc_t), GFP_KERNEL); + raid_dev->sysfs_uioc = kmalloc_obj(uioc_t); - raid_dev->sysfs_mbox64 = kmalloc(sizeof(mbox64_t), GFP_KERNEL); + raid_dev->sysfs_mbox64 = kmalloc_obj(mbox64_t); raid_dev->sysfs_buffer = dma_alloc_coherent(&adapter->pdev->dev, PAGE_SIZE, &raid_dev->sysfs_buffer_dma, GFP_KERNEL); diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index 87184e2538b0..538da0e98131 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -913,7 +913,7 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) if (lld_adp->drvr_type != DRVRTYPE_MBOX) return (-EINVAL); - adapter = kzalloc(sizeof(mraid_mmadp_t), GFP_KERNEL); + adapter = kzalloc_obj(mraid_mmadp_t); if (!adapter) return -ENOMEM; @@ -932,12 +932,8 @@ mraid_mm_register_adp(mraid_mmadp_t *lld_adp) * Allocate single blocks of memory for all required kiocs, * mailboxes and passthru structures. */ - adapter->kioc_list = kmalloc_array(lld_adp->max_kioc, - sizeof(uioc_t), - GFP_KERNEL); - adapter->mbox_list = kmalloc_array(lld_adp->max_kioc, - sizeof(mbox64_t), - GFP_KERNEL); + adapter->kioc_list = kmalloc_objs(uioc_t, lld_adp->max_kioc); + adapter->mbox_list = kmalloc_objs(mbox64_t, lld_adp->max_kioc); adapter->pthru_dma_pool = dma_pool_create("megaraid mm pthru pool", &adapter->pdev->dev, sizeof(mraid_passthru_t), diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 52894e892a92..ac71ea4898b2 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2137,8 +2137,7 @@ static int megasas_sdev_init(struct scsi_device *sdev) } scan_target: - mr_device_priv_data = kzalloc(sizeof(*mr_device_priv_data), - GFP_KERNEL); + mr_device_priv_data = kzalloc_obj(*mr_device_priv_data); if (!mr_device_priv_data) return -ENOMEM; @@ -3255,7 +3254,7 @@ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd) ((instance->issuepend_done == 1))) { struct megasas_aen_event *ev; - ev = kzalloc(sizeof(*ev), GFP_ATOMIC); + ev = kzalloc_obj(*ev, GFP_ATOMIC); if (!ev) { dev_err(&instance->pdev->dev, "megasas_service_aen: out of memory\n"); } else { @@ -4468,7 +4467,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) * Allocate the dynamic array first and then allocate individual * commands. */ - instance->cmd_list = kcalloc(max_cmd, sizeof(struct megasas_cmd*), GFP_KERNEL); + instance->cmd_list = kzalloc_objs(struct megasas_cmd *, max_cmd); if (!instance->cmd_list) { dev_printk(KERN_DEBUG, &instance->pdev->dev, "out of memory\n"); @@ -4476,8 +4475,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) } for (i = 0; i < max_cmd; i++) { - instance->cmd_list[i] = kmalloc(sizeof(struct megasas_cmd), - GFP_KERNEL); + instance->cmd_list[i] = kmalloc_obj(struct megasas_cmd); if (!instance->cmd_list[i]) { @@ -6377,9 +6375,8 @@ static int megasas_init_fw(struct megasas_instance *instance) /* stream detection initialization */ if (instance->adapter_type >= VENTURA_SERIES) { fusion->stream_detect_by_ld = - kcalloc(MAX_LOGICAL_DRIVES_EXT, - sizeof(struct LD_STREAM_DETECT *), - GFP_KERNEL); + kzalloc_objs(struct LD_STREAM_DETECT *, + MAX_LOGICAL_DRIVES_EXT); if (!fusion->stream_detect_by_ld) { dev_err(&instance->pdev->dev, "unable to allocate stream detection for pool of LDs\n"); @@ -6387,8 +6384,7 @@ static int megasas_init_fw(struct megasas_instance *instance) } for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { fusion->stream_detect_by_ld[i] = - kzalloc(sizeof(struct LD_STREAM_DETECT), - GFP_KERNEL); + kzalloc_obj(struct LD_STREAM_DETECT); if (!fusion->stream_detect_by_ld[i]) { dev_err(&instance->pdev->dev, "unable to allocate stream detect by LD\n"); @@ -8496,7 +8492,7 @@ megasas_compat_iocpacket_get_user(void __user *arg) int err = -EFAULT; int i; - ioc = kzalloc(sizeof(*ioc), GFP_KERNEL); + ioc = kzalloc_obj(*ioc); if (!ioc) return ERR_PTR(-ENOMEM); size = offsetof(struct megasas_iocpacket, frame) + sizeof(ioc->frame); diff --git a/drivers/scsi/megaraid/megaraid_sas_debugfs.c b/drivers/scsi/megaraid/megaraid_sas_debugfs.c index c69760775efa..81698cd83f5a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_debugfs.c +++ b/drivers/scsi/megaraid/megaraid_sas_debugfs.c @@ -65,7 +65,7 @@ megasas_debugfs_raidmap_open(struct inode *inode, struct file *file) fusion = instance->ctrl_context; - debug = kzalloc(sizeof(struct megasas_debugfs_buffer), GFP_KERNEL); + debug = kzalloc_obj(struct megasas_debugfs_buffer); if (!debug) return -ENOMEM; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index a6794f49e9fa..2699e4e09b5b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -598,8 +598,7 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance *instance) * commands. */ fusion->cmd_list = - kcalloc(max_mpt_cmd, sizeof(struct megasas_cmd_fusion *), - GFP_KERNEL); + kzalloc_objs(struct megasas_cmd_fusion *, max_mpt_cmd); if (!fusion->cmd_list) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); @@ -607,8 +606,7 @@ megasas_alloc_cmdlist_fusion(struct megasas_instance *instance) } for (i = 0; i < max_mpt_cmd; i++) { - fusion->cmd_list[i] = kzalloc(sizeof(struct megasas_cmd_fusion), - GFP_KERNEL); + fusion->cmd_list[i] = kzalloc_obj(struct megasas_cmd_fusion); if (!fusion->cmd_list[i]) { for (j = 0; j < i; j++) kfree(fusion->cmd_list[j]); @@ -1744,7 +1742,7 @@ static int megasas_alloc_ioc_init_frame(struct megasas_instance *instance) fusion = instance->ctrl_context; - cmd = kzalloc(sizeof(struct megasas_cmd), GFP_KERNEL); + cmd = kzalloc_obj(struct megasas_cmd); if (!cmd) { dev_err(&instance->pdev->dev, "Failed from func: %s line: %d\n", @@ -5298,8 +5296,7 @@ megasas_alloc_fusion_context(struct megasas_instance *instance) { struct fusion_context *fusion; - instance->ctrl_context = kzalloc(sizeof(struct fusion_context), - GFP_KERNEL); + instance->ctrl_context = kzalloc_obj(struct fusion_context); if (!instance->ctrl_context) { dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index df984e9b5197..c744210cc901 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -1288,7 +1288,7 @@ static void mpi3mr_fault_uevent_emit(struct mpi3mr_ioc *mrioc) struct kobj_uevent_env *env; int ret; - env = kzalloc(sizeof(*env), GFP_KERNEL); + env = kzalloc_obj(*env); if (!env) return; @@ -1618,6 +1618,7 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) ioc_info(mrioc, "successfully transitioned to %s state\n", mpi3mr_iocstate_name(ioc_state)); + mpi3mr_clear_reset_history(mrioc); return 0; } ioc_status = readl(&mrioc->sysif_regs->ioc_status); @@ -1637,6 +1638,15 @@ static int mpi3mr_bring_ioc_ready(struct mpi3mr_ioc *mrioc) elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; } while (elapsed_time_sec < mrioc->ready_timeout); + ioc_state = mpi3mr_get_iocstate(mrioc); + if (ioc_state == MRIOC_STATE_READY) { + ioc_info(mrioc, + "successfully transitioned to %s state after %llu seconds\n", + mpi3mr_iocstate_name(ioc_state), elapsed_time_sec); + mpi3mr_clear_reset_history(mrioc); + return 0; + } + out_failed: elapsed_time_sec = jiffies_to_msecs(jiffies - start_time)/1000; if ((retry < 2) && (elapsed_time_sec < (mrioc->ready_timeout - 60))) { @@ -2110,8 +2120,8 @@ static int mpi3mr_alloc_op_reply_q_segments(struct mpi3mr_ioc *mrioc, u16 qidx) op_reply_q->num_segments = DIV_ROUND_UP(op_reply_q->num_replies, op_reply_q->segment_qd); - op_reply_q->q_segments = kcalloc(op_reply_q->num_segments, - sizeof(struct segments), GFP_KERNEL); + op_reply_q->q_segments = kzalloc_objs(struct segments, + op_reply_q->num_segments); if (!op_reply_q->q_segments) return -ENOMEM; @@ -2168,8 +2178,8 @@ static int mpi3mr_alloc_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 qidx) op_req_q->num_segments = DIV_ROUND_UP(op_req_q->num_requests, op_req_q->segment_qd); - op_req_q->q_segments = kcalloc(op_req_q->num_segments, - sizeof(struct segments), GFP_KERNEL); + op_req_q->q_segments = kzalloc_objs(struct segments, + op_req_q->num_segments); if (!op_req_q->q_segments) return -ENOMEM; @@ -2463,8 +2473,7 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) num_queues); if (!mrioc->req_qinfo) { - mrioc->req_qinfo = kcalloc(num_queues, - sizeof(struct op_req_qinfo), GFP_KERNEL); + mrioc->req_qinfo = kzalloc_objs(struct op_req_qinfo, num_queues); if (!mrioc->req_qinfo) { retval = -1; goto out_failed; @@ -4808,21 +4817,25 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc) } for (i = 0; i < mrioc->num_queues; i++) { - mrioc->op_reply_qinfo[i].qid = 0; - mrioc->op_reply_qinfo[i].ci = 0; - mrioc->op_reply_qinfo[i].num_replies = 0; - mrioc->op_reply_qinfo[i].ephase = 0; - atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0); - atomic_set(&mrioc->op_reply_qinfo[i].in_use, 0); - mpi3mr_memset_op_reply_q_buffers(mrioc, i); + if (mrioc->op_reply_qinfo) { + mrioc->op_reply_qinfo[i].qid = 0; + mrioc->op_reply_qinfo[i].ci = 0; + mrioc->op_reply_qinfo[i].num_replies = 0; + mrioc->op_reply_qinfo[i].ephase = 0; + atomic_set(&mrioc->op_reply_qinfo[i].pend_ios, 0); + atomic_set(&mrioc->op_reply_qinfo[i].in_use, 0); + mpi3mr_memset_op_reply_q_buffers(mrioc, i); + } - mrioc->req_qinfo[i].ci = 0; - mrioc->req_qinfo[i].pi = 0; - mrioc->req_qinfo[i].num_requests = 0; - mrioc->req_qinfo[i].qid = 0; - mrioc->req_qinfo[i].reply_qid = 0; - spin_lock_init(&mrioc->req_qinfo[i].q_lock); - mpi3mr_memset_op_req_q_buffers(mrioc, i); + if (mrioc->req_qinfo) { + mrioc->req_qinfo[i].ci = 0; + mrioc->req_qinfo[i].pi = 0; + mrioc->req_qinfo[i].num_requests = 0; + mrioc->req_qinfo[i].qid = 0; + mrioc->req_qinfo[i].reply_qid = 0; + spin_lock_init(&mrioc->req_qinfo[i].q_lock); + mpi3mr_memset_op_req_q_buffers(mrioc, i); + } } atomic_set(&mrioc->pend_large_data_sz, 0); diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 8e5abf620718..90f8b9d1c2ac 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -676,7 +676,7 @@ static struct mpi3mr_tgt_dev *mpi3mr_alloc_tgtdev(void) { struct mpi3mr_tgt_dev *tgtdev; - tgtdev = kzalloc(sizeof(*tgtdev), GFP_ATOMIC); + tgtdev = kzalloc_obj(*tgtdev, GFP_ATOMIC); if (!tgtdev) return NULL; kref_init(&tgtdev->ref_count); @@ -1710,8 +1710,7 @@ static void mpi3mr_encldev_add_chg_evt_bh(struct mpi3mr_ioc *mrioc, encl_handle); if (!enclosure_dev && present) { enclosure_dev = - kzalloc(sizeof(struct mpi3mr_enclosure_node), - GFP_KERNEL); + kzalloc_obj(struct mpi3mr_enclosure_node); if (!enclosure_dev) return; list_add_tail(&enclosure_dev->list, @@ -2535,8 +2534,7 @@ static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle, } while (retrycount--); if (cmd_idx >= MPI3MR_NUM_DEVRMCMD) { - delayed_dev_rmhs = kzalloc(sizeof(*delayed_dev_rmhs), - GFP_ATOMIC); + delayed_dev_rmhs = kzalloc_obj(*delayed_dev_rmhs, GFP_ATOMIC); if (!delayed_dev_rmhs) return; INIT_LIST_HEAD(&delayed_dev_rmhs->list); @@ -2677,8 +2675,7 @@ static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event, } while (retrycount--); if (cmd_idx >= MPI3MR_NUM_EVTACKCMD) { - delayed_evtack = kzalloc(sizeof(*delayed_evtack), - GFP_ATOMIC); + delayed_evtack = kzalloc_obj(*delayed_evtack, GFP_ATOMIC); if (!delayed_evtack) return; INIT_LIST_HEAD(&delayed_evtack->list); @@ -4900,7 +4897,7 @@ static int mpi3mr_sdev_init(struct scsi_device *sdev) spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); - scsi_dev_priv_data = kzalloc(sizeof(*scsi_dev_priv_data), GFP_KERNEL); + scsi_dev_priv_data = kzalloc_obj(*scsi_dev_priv_data); if (!scsi_dev_priv_data) return -ENOMEM; @@ -4931,7 +4928,7 @@ static int mpi3mr_target_alloc(struct scsi_target *starget) int retval = 0; struct sas_rphy *rphy = NULL; - scsi_tgt_priv_data = kzalloc(sizeof(*scsi_tgt_priv_data), GFP_KERNEL); + scsi_tgt_priv_data = kzalloc_obj(*scsi_tgt_priv_data); if (!scsi_tgt_priv_data) return -ENOMEM; diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 101161554ef1..240f67a8e2e3 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -1022,8 +1022,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id) { struct mpi3mr_hba_port *hba_port; - hba_port = kzalloc(sizeof(struct mpi3mr_hba_port), - GFP_KERNEL); + hba_port = kzalloc_obj(struct mpi3mr_hba_port); if (!hba_port) return NULL; hba_port->port_id = port_id; @@ -1221,8 +1220,7 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) mrioc->sas_hba.host_node = 1; INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; - mrioc->sas_hba.phy = kcalloc(num_phys, - sizeof(struct mpi3mr_sas_phy), GFP_KERNEL); + mrioc->sas_hba.phy = kzalloc_objs(struct mpi3mr_sas_phy, num_phys); if (!mrioc->sas_hba.phy) return; @@ -1344,7 +1342,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, return NULL; } - mr_sas_port = kzalloc(sizeof(struct mpi3mr_sas_port), GFP_KERNEL); + mr_sas_port = kzalloc_obj(struct mpi3mr_sas_port); if (!mr_sas_port) return NULL; @@ -1721,7 +1719,7 @@ mpi3mr_refresh_sas_ports(struct mpi3mr_ioc *mrioc) sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); if (!sas_io_unit_pg0) return; - h_port = kcalloc(64, sizeof(struct host_port), GFP_KERNEL); + h_port = kzalloc_objs(struct host_port, 64); if (!h_port) goto out; @@ -2098,8 +2096,7 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle) if (sas_expander) return 0; - sas_expander = kzalloc(sizeof(struct mpi3mr_sas_node), - GFP_KERNEL); + sas_expander = kzalloc_obj(struct mpi3mr_sas_node); if (!sas_expander) return -ENOMEM; @@ -2118,8 +2115,8 @@ int mpi3mr_expander_add(struct mpi3mr_ioc *mrioc, u16 handle) rc = -1; goto out_fail; } - sas_expander->phy = kcalloc(sas_expander->num_phys, - sizeof(struct mpi3mr_sas_phy), GFP_KERNEL); + sas_expander->phy = kzalloc_objs(struct mpi3mr_sas_phy, + sas_expander->num_phys); if (!sas_expander->phy) { rc = -1; goto out_fail; diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 2f2183f405c9..79052f2accbd 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c @@ -1497,8 +1497,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) goto out; smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx); if (!smid) { - delayed_event_ack = kzalloc(sizeof(*delayed_event_ack), - GFP_ATOMIC); + delayed_event_ack = kzalloc_obj(*delayed_event_ack, GFP_ATOMIC); if (!delayed_event_ack) goto out; INIT_LIST_HEAD(&delayed_event_ack->list); @@ -3162,7 +3161,7 @@ _base_request_irq(struct MPT3SAS_ADAPTER *ioc, u8 index) struct adapter_reply_queue *reply_q; int r, qid; - reply_q = kzalloc(sizeof(struct adapter_reply_queue), GFP_KERNEL); + reply_q = kzalloc_obj(struct adapter_reply_queue); if (!reply_q) { ioc_err(ioc, "unable to allocate memory %zu!\n", sizeof(struct adapter_reply_queue)); @@ -3462,8 +3461,8 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc) iopoll_q_count = poll_queues; if (iopoll_q_count) { - ioc->io_uring_poll_queues = kcalloc(iopoll_q_count, - sizeof(struct io_uring_poll_queue), GFP_KERNEL); + ioc->io_uring_poll_queues = kzalloc_objs(struct io_uring_poll_queue, + iopoll_q_count); if (!ioc->io_uring_poll_queues) iopoll_q_count = 0; } @@ -3727,9 +3726,8 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) * each register is at offset bytes of * MPT3_SUP_REPLY_POST_HOST_INDEX_REG_OFFSET from previous one. */ - ioc->replyPostRegisterIndex = kcalloc( - ioc->combined_reply_index_count, - sizeof(resource_size_t *), GFP_KERNEL); + ioc->replyPostRegisterIndex = kzalloc_objs(resource_size_t *, + ioc->combined_reply_index_count); if (!ioc->replyPostRegisterIndex) { ioc_err(ioc, "allocation for replyPostRegisterIndex failed!\n"); @@ -6218,8 +6216,7 @@ base_alloc_rdpq_dma_pool(struct MPT3SAS_ADAPTER *ioc, int sz) sizeof(Mpi2DefaultReplyDescriptor_t); int count = ioc->rdpq_array_enable ? ioc->reply_queue_count : 1; - ioc->reply_post = kcalloc(count, sizeof(struct reply_post_struct), - GFP_KERNEL); + ioc->reply_post = kzalloc_objs(struct reply_post_struct, count); if (!ioc->reply_post) return -ENOMEM; /* @@ -6562,8 +6559,8 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) } /* initialize hi-priority queue smid's */ - ioc->hpr_lookup = kcalloc(ioc->hi_priority_depth, - sizeof(struct request_tracker), GFP_KERNEL); + ioc->hpr_lookup = kzalloc_objs(struct request_tracker, + ioc->hi_priority_depth); if (!ioc->hpr_lookup) { ioc_err(ioc, "hpr_lookup: kcalloc failed\n"); goto out; @@ -6575,8 +6572,8 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) ioc->hi_priority_depth, ioc->hi_priority_smid)); /* initialize internal queue smid's */ - ioc->internal_lookup = kcalloc(ioc->internal_depth, - sizeof(struct request_tracker), GFP_KERNEL); + ioc->internal_lookup = kzalloc_objs(struct request_tracker, + ioc->internal_depth); if (!ioc->internal_lookup) { ioc_err(ioc, "internal_lookup: kcalloc failed\n"); goto out; @@ -8430,8 +8427,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) } if (ioc->is_warpdrive) { - ioc->reply_post_host_index = kcalloc(ioc->cpu_msix_table_sz, - sizeof(resource_size_t *), GFP_KERNEL); + ioc->reply_post_host_index = kzalloc_objs(resource_size_t *, + ioc->cpu_msix_table_sz); if (!ioc->reply_post_host_index) { ioc_info(ioc, "Allocation for reply_post_host_index failed!!!\n"); r = -ENOMEM; @@ -8520,8 +8517,8 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) if (r) goto out_free_resources; - ioc->pfacts = kcalloc(ioc->facts.NumberOfPorts, - sizeof(struct mpt3sas_port_facts), GFP_KERNEL); + ioc->pfacts = kzalloc_objs(struct mpt3sas_port_facts, + ioc->facts.NumberOfPorts); if (!ioc->pfacts) { r = -ENOMEM; goto out_free_resources; diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 3b951589feeb..8bb947004885 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -1331,8 +1331,8 @@ _ctl_eventenable(struct MPT3SAS_ADAPTER *ioc, void __user *arg) /* initialize event_log */ ioc->event_context = 0; ioc->aen_event_read_flag = 0; - ioc->event_log = kcalloc(MPT3SAS_CTL_EVENT_LOG_SIZE, - sizeof(struct MPT3_IOCTL_EVENTS), GFP_KERNEL); + ioc->event_log = kzalloc_objs(struct MPT3_IOCTL_EVENTS, + MPT3SAS_CTL_EVENT_LOG_SIZE); if (!ioc->event_log) { pr_err("failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -3881,8 +3881,7 @@ diag_trigger_master_store(struct device *cdev, rc = min(sizeof(struct SL_WH_MASTER_TRIGGER_T), count); if (ioc->supports_trigger_pages) { - master_tg = kzalloc(sizeof(struct SL_WH_MASTER_TRIGGER_T), - GFP_KERNEL); + master_tg = kzalloc_obj(struct SL_WH_MASTER_TRIGGER_T); if (!master_tg) return -ENOMEM; @@ -3956,8 +3955,7 @@ diag_trigger_event_store(struct device *cdev, sz = min(sizeof(struct SL_WH_EVENT_TRIGGERS_T), count); if (ioc->supports_trigger_pages) { - event_tg = kzalloc(sizeof(struct SL_WH_EVENT_TRIGGERS_T), - GFP_KERNEL); + event_tg = kzalloc_obj(struct SL_WH_EVENT_TRIGGERS_T); if (!event_tg) return -ENOMEM; @@ -4031,8 +4029,7 @@ diag_trigger_scsi_store(struct device *cdev, sz = min(sizeof(struct SL_WH_SCSI_TRIGGERS_T), count); if (ioc->supports_trigger_pages) { - scsi_tg = kzalloc(sizeof(struct SL_WH_SCSI_TRIGGERS_T), - GFP_KERNEL); + scsi_tg = kzalloc_obj(struct SL_WH_SCSI_TRIGGERS_T); if (!scsi_tg) return -ENOMEM; @@ -4105,8 +4102,7 @@ diag_trigger_mpi_store(struct device *cdev, sz = min(sizeof(struct SL_WH_MPI_TRIGGERS_T), count); if (ioc->supports_trigger_pages) { - mpi_tg = kzalloc(sizeof(struct SL_WH_MPI_TRIGGERS_T), - GFP_KERNEL); + mpi_tg = kzalloc_obj(struct SL_WH_MPI_TRIGGERS_T); if (!mpi_tg) return -ENOMEM; diff --git a/drivers/scsi/mpt3sas/mpt3sas_debugfs.c b/drivers/scsi/mpt3sas/mpt3sas_debugfs.c index a6ab1db81167..183391f6b8d1 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_debugfs.c +++ b/drivers/scsi/mpt3sas/mpt3sas_debugfs.c @@ -58,7 +58,7 @@ _debugfs_iocdump_open(struct inode *inode, struct file *file) struct MPT3SAS_ADAPTER *ioc = inode->i_private; struct mpt3sas_debugfs_buffer *debug; - debug = kzalloc(sizeof(struct mpt3sas_debugfs_buffer), GFP_KERNEL); + debug = kzalloc_obj(struct mpt3sas_debugfs_buffer); if (!debug) return -ENOMEM; diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 26a13b622c95..6ff788557294 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -476,7 +476,7 @@ mpt3sas_get_port_by_id(struct MPT3SAS_ADAPTER *ioc, * And add this object to port_table_list. */ if (!ioc->multipath_on_hba) { - port = kzalloc(sizeof(struct hba_port), GFP_ATOMIC); + port = kzalloc_obj(struct hba_port, GFP_ATOMIC); if (!port) return NULL; @@ -1940,8 +1940,7 @@ scsih_target_alloc(struct scsi_target *starget) unsigned long flags; struct sas_rphy *rphy; - sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data), - GFP_KERNEL); + sas_target_priv_data = kzalloc_obj(*sas_target_priv_data); if (!sas_target_priv_data) return -ENOMEM; @@ -2109,8 +2108,7 @@ scsih_sdev_init(struct scsi_device *sdev) struct _pcie_device *pcie_device; unsigned long flags; - sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), - GFP_KERNEL); + sas_device_priv_data = kzalloc_obj(*sas_device_priv_data); if (!sas_device_priv_data) return -ENOMEM; @@ -4470,7 +4468,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_tr_cb_idx); if (!smid) { - delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); + delayed_tr = kzalloc_obj(*delayed_tr, GFP_ATOMIC); if (!delayed_tr) goto out; INIT_LIST_HEAD(&delayed_tr->list); @@ -4568,7 +4566,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, smid_sas_ctrl = mpt3sas_base_get_smid(ioc, ioc->tm_sas_control_cb_idx); if (!smid_sas_ctrl) { - delayed_sc = kzalloc(sizeof(*delayed_sc), GFP_ATOMIC); + delayed_sc = kzalloc_obj(*delayed_sc, GFP_ATOMIC); if (!delayed_sc) return _scsih_check_for_pending_tm(ioc, smid); INIT_LIST_HEAD(&delayed_sc->list); @@ -4694,7 +4692,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) smid = mpt3sas_base_get_smid_hpr(ioc, ioc->tm_tr_volume_cb_idx); if (!smid) { - delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); + delayed_tr = kzalloc_obj(*delayed_tr, GFP_ATOMIC); if (!delayed_tr) return; INIT_LIST_HEAD(&delayed_tr->list); @@ -5215,7 +5213,7 @@ _scsih_check_ir_config_unhide_events(struct MPT3SAS_ADAPTER *ioc, if (!volume_handle) _scsih_tm_tr_send(ioc, handle); else if (volume_handle == a || volume_handle == b) { - delayed_tr = kzalloc(sizeof(*delayed_tr), GFP_ATOMIC); + delayed_tr = kzalloc_obj(*delayed_tr, GFP_ATOMIC); BUG_ON(!delayed_tr); INIT_LIST_HEAD(&delayed_tr->list); delayed_tr->handle = handle; @@ -6378,8 +6376,7 @@ _scsih_update_vphys_after_reset(struct MPT3SAS_ADAPTER *ioc) port_id = sas_iounit_pg0->PhyData[i].Port; mport = mpt3sas_get_port_by_id(ioc, port_id, 1); if (!mport) { - mport = kzalloc( - sizeof(struct hba_port), GFP_KERNEL); + mport = kzalloc_obj(struct hba_port); if (!mport) break; mport->port_id = port_id; @@ -6749,8 +6746,7 @@ _scsih_sas_port_refresh(struct MPT3SAS_ADAPTER *ioc) } ioc->sas_hba.num_phys = num_phys; - port_table = kcalloc(ioc->sas_hba.num_phys, - sizeof(struct hba_port), GFP_KERNEL); + port_table = kzalloc_objs(struct hba_port, ioc->sas_hba.num_phys); if (!port_table) return; @@ -6841,7 +6837,7 @@ _scsih_alloc_vphy(struct MPT3SAS_ADAPTER *ioc, u8 port_id, u8 phy_num) vphy = mpt3sas_get_vphy_by_phy(ioc, port, phy_num); if (!vphy) { - vphy = kzalloc(sizeof(struct virtual_phy), GFP_KERNEL); + vphy = kzalloc_obj(struct virtual_phy); if (!vphy) return NULL; @@ -6911,7 +6907,7 @@ _scsih_sas_host_refresh(struct MPT3SAS_ADAPTER *ioc) sas_iounit_pg0->PhyData[0].ControllerDevHandle); port_id = sas_iounit_pg0->PhyData[i].Port; if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { - port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + port = kzalloc_obj(struct hba_port); if (!port) goto out; @@ -7031,8 +7027,8 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) ioc->sas_hba.nr_phys_allocated = max_t(u8, MPT_MAX_HBA_NUM_PHYS, num_phys); - ioc->sas_hba.phy = kcalloc(ioc->sas_hba.nr_phys_allocated, - sizeof(struct _sas_phy), GFP_KERNEL); + ioc->sas_hba.phy = kzalloc_objs(struct _sas_phy, + ioc->sas_hba.nr_phys_allocated); if (!ioc->sas_hba.phy) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -7117,7 +7113,7 @@ _scsih_sas_host_add(struct MPT3SAS_ADAPTER *ioc) port_id = sas_iounit_pg0->PhyData[i].Port; if (!(mpt3sas_get_port_by_id(ioc, port_id, 0))) { - port = kzalloc(sizeof(struct hba_port), GFP_KERNEL); + port = kzalloc_obj(struct hba_port); if (!port) goto out; @@ -7258,8 +7254,7 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) if (sas_expander) return 0; - sas_expander = kzalloc(sizeof(struct _sas_node), - GFP_KERNEL); + sas_expander = kzalloc_obj(struct _sas_node); if (!sas_expander) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -7286,8 +7281,8 @@ _scsih_expander_add(struct MPT3SAS_ADAPTER *ioc, u16 handle) rc = -1; goto out_fail; } - sas_expander->phy = kcalloc(sas_expander->num_phys, - sizeof(struct _sas_phy), GFP_KERNEL); + sas_expander->phy = kzalloc_objs(struct _sas_phy, + sas_expander->num_phys); if (!sas_expander->phy) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -7782,7 +7777,7 @@ _scsih_report_luns(struct MPT3SAS_ADAPTER *ioc, u16 handle, void *data, int retries; lun_data = NULL; - transfer_packet = kzalloc(sizeof(struct _scsi_io_transfer), GFP_KERNEL); + transfer_packet = kzalloc_obj(struct _scsi_io_transfer); if (!transfer_packet) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -7869,7 +7864,7 @@ _scsih_start_unit(struct MPT3SAS_ADAPTER *ioc, u16 handle, u32 lun, u8 is_pd, enum device_responsive_state rc; int return_code; - transfer_packet = kzalloc(sizeof(struct _scsi_io_transfer), GFP_KERNEL); + transfer_packet = kzalloc_obj(struct _scsi_io_transfer); if (!transfer_packet) { pr_info("failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -7930,7 +7925,7 @@ _scsih_test_unit_ready(struct MPT3SAS_ADAPTER *ioc, u16 handle, u32 lun, int return_code; int sata_init_failure = 0; - transfer_packet = kzalloc(sizeof(struct _scsi_io_transfer), GFP_KERNEL); + transfer_packet = kzalloc_obj(struct _scsi_io_transfer); if (!transfer_packet) { pr_info("failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -8002,7 +7997,7 @@ _scsih_ata_pass_thru_idd(struct MPT3SAS_ADAPTER *ioc, u16 handle, u32 data_length; idd_data = NULL; - transfer_packet = kzalloc(sizeof(struct _scsi_io_transfer), GFP_KERNEL); + transfer_packet = kzalloc_obj(struct _scsi_io_transfer); if (!transfer_packet) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -8133,7 +8128,7 @@ _scsih_wait_for_target_to_become_ready(struct MPT3SAS_ADAPTER *ioc, u16 handle, int lun; struct scsi_lun *lunp; - lun_data = kcalloc(MPT3_MAX_LUNS, sizeof(struct scsi_lun), GFP_KERNEL); + lun_data = kzalloc_objs(struct scsi_lun, MPT3_MAX_LUNS); if (!lun_data) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -8482,8 +8477,7 @@ _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 retry_count, } } - sas_device = kzalloc(sizeof(struct _sas_device), - GFP_KERNEL); + sas_device = kzalloc_obj(struct _sas_device); if (!sas_device) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -9386,7 +9380,7 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 retry_count) } } - pcie_device = kzalloc(sizeof(struct _pcie_device), GFP_KERNEL); + pcie_device = kzalloc_obj(struct _pcie_device); if (!pcie_device) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -9838,8 +9832,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT3SAS_ADAPTER *ioc, case MPI2_EVENT_SAS_ENCL_RC_ADDED: if (!enclosure_dev) { enclosure_dev = - kzalloc(sizeof(struct _enclosure_node), - GFP_KERNEL); + kzalloc_obj(struct _enclosure_node); if (!enclosure_dev) { ioc_info(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -10264,7 +10257,7 @@ _scsih_sas_volume_add(struct MPT3SAS_ADAPTER *ioc, if (raid_device) return; - raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); + raid_device = kzalloc_obj(struct _raid_device); if (!raid_device) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -10682,7 +10675,7 @@ _scsih_sas_ir_volume_event(struct MPT3SAS_ADAPTER *ioc, break; } - raid_device = kzalloc(sizeof(struct _raid_device), GFP_KERNEL); + raid_device = kzalloc_obj(struct _raid_device); if (!raid_device) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); @@ -11043,7 +11036,7 @@ _scsih_create_enclosure_list_after_reset(struct MPT3SAS_ADAPTER *ioc) enclosure_handle = 0xFFFF; do { enclosure_dev = - kzalloc(sizeof(struct _enclosure_node), GFP_KERNEL); + kzalloc_obj(struct _enclosure_node); if (!enclosure_dev) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index f3400d01cc2a..e74a526efa8d 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c @@ -698,8 +698,7 @@ mpt3sas_transport_port_add(struct MPT3SAS_ADAPTER *ioc, u16 handle, return NULL; } - mpt3sas_port = kzalloc(sizeof(struct _sas_port), - GFP_KERNEL); + mpt3sas_port = kzalloc_obj(struct _sas_port); if (!mpt3sas_port) { ioc_err(ioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index 9b19d5205e50..f4db93c13986 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c @@ -49,7 +49,7 @@ static int mvme16x_probe(struct platform_device *dev) goto out; } - hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + hostdata = kzalloc_obj(struct NCR_700_Host_Parameters); if (hostdata == NULL) { printk(KERN_ERR "mvme16x-scsi: " "Failed to allocate host data\n"); diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 7f1ad305eee6..5abc17a2e261 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -401,7 +401,7 @@ static int mvs_prep_sas_ha_init(struct Scsi_Host *shost, sha->sas_port = arr_port; sha->shost = shost; - sha->lldd_ha = kzalloc(sizeof(struct mvs_prv_info), GFP_KERNEL); + sha->lldd_ha = kzalloc_obj(struct mvs_prv_info); if (!sha->lldd_ha) goto exit_free; @@ -502,7 +502,7 @@ static int mvs_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) chip = &mvs_chips[ent->driver_data]; SHOST_TO_SAS_HA(shost) = - kcalloc(1, sizeof(struct sas_ha_struct), GFP_KERNEL); + kzalloc_objs(struct sas_ha_struct, 1); if (!SHOST_TO_SAS_HA(shost)) { scsi_host_put(shost); rc = -ENOMEM; diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index f2e7997d5b9d..359226e80eae 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -1739,7 +1739,7 @@ static int mvs_handle_event(struct mvs_info *mvi, void *data, int handler) struct mvs_wq *mwq; int ret = 0; - mwq = kmalloc(sizeof(struct mvs_wq), GFP_ATOMIC); + mwq = kmalloc_obj(struct mvs_wq, GFP_ATOMIC); if (mwq) { mwq->mvi = mvi; mwq->data = data; diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index cda8bd083a38..e70d336b4ab3 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -106,7 +106,7 @@ static int mvumi_map_pci_addr(struct pci_dev *dev, void **addr_array) static struct mvumi_res *mvumi_alloc_mem_resource(struct mvumi_hba *mhba, enum resource_type type, unsigned int size) { - struct mvumi_res *res = kzalloc(sizeof(*res), GFP_ATOMIC); + struct mvumi_res *res = kzalloc_obj(*res, GFP_ATOMIC); if (!res) { dev_err(&mhba->pdev->dev, @@ -252,7 +252,7 @@ static struct mvumi_cmd *mvumi_create_internal_cmd(struct mvumi_hba *mhba, { struct mvumi_cmd *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) { dev_err(&mhba->pdev->dev, "failed to create a internal cmd\n"); return NULL; @@ -368,7 +368,7 @@ static int mvumi_alloc_cmds(struct mvumi_hba *mhba) struct mvumi_cmd *cmd; for (i = 0; i < mhba->max_io; i++) { - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) goto err_exit; @@ -1572,8 +1572,7 @@ static int mvumi_probe_devices(struct mvumi_hba *mhba) found = mvumi_match_devices(mhba, id, wwid); if (!found) { mvumi_remove_devices(mhba, id); - mv_dev = kzalloc(sizeof(struct mvumi_device), - GFP_KERNEL); + mv_dev = kzalloc_obj(struct mvumi_device); if (!mv_dev) { dev_err(&mhba->pdev->dev, "%s alloc mv_dev failed\n", @@ -1749,7 +1748,7 @@ static void mvumi_launch_events(struct mvumi_hba *mhba, u32 isr_status) continue; } - mu_ev = kzalloc(sizeof(*mu_ev), GFP_ATOMIC); + mu_ev = kzalloc_obj(*mu_ev, GFP_ATOMIC); if (mu_ev) { INIT_WORK(&mu_ev->work_q, mvumi_scan_events); mu_ev->mhba = mhba; @@ -2193,7 +2192,7 @@ static int mvumi_cfg_hw_reg(struct mvumi_hba *mhba) mhba->mmio = mhba->base_addr[0]; base = mhba->mmio; if (!mhba->regs) { - mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL); + mhba->regs = kzalloc_obj(*regs); if (mhba->regs == NULL) return -ENOMEM; } @@ -2245,7 +2244,7 @@ static int mvumi_cfg_hw_reg(struct mvumi_hba *mhba) mhba->mmio = mhba->base_addr[2]; base = mhba->mmio; if (!mhba->regs) { - mhba->regs = kzalloc(sizeof(*regs), GFP_KERNEL); + mhba->regs = kzalloc_obj(*regs); if (mhba->regs == NULL) return -ENOMEM; } diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index efeacb9ffd7c..3678b66310ed 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -1628,7 +1628,7 @@ static int myrb_ldev_sdev_init(struct scsi_device *sdev) ldev_info = cb->ldev_info_buf + ldev_num; - sdev->hostdata = kzalloc(sizeof(*ldev_info), GFP_KERNEL); + sdev->hostdata = kzalloc_obj(*ldev_info); if (!sdev->hostdata) return -ENOMEM; dev_dbg(&sdev->sdev_gendev, @@ -1672,7 +1672,7 @@ static int myrb_pdev_sdev_init(struct scsi_device *sdev) if (sdev->id > MYRB_MAX_TARGETS) return -ENXIO; - pdev_info = kzalloc(sizeof(*pdev_info), GFP_KERNEL); + pdev_info = kzalloc_obj(*pdev_info); if (!pdev_info) return -ENOMEM; diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index 7e8bb533c669..afd68225221a 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -538,11 +538,11 @@ static bool myrs_enable_mmio_mbox(struct myrs_hba *cs, cs->fwstat_buf = NULL; goto out_free; } - cs->ctlr_info = kzalloc(sizeof(struct myrs_ctlr_info), GFP_KERNEL); + cs->ctlr_info = kzalloc_obj(struct myrs_ctlr_info); if (!cs->ctlr_info) goto out_free; - cs->event_buf = kzalloc(sizeof(struct myrs_event), GFP_KERNEL); + cs->event_buf = kzalloc_obj(struct myrs_event); if (!cs->event_buf) goto out_free; @@ -1803,7 +1803,7 @@ static int myrs_sdev_init(struct scsi_device *sdev) ldev_num = myrs_translate_ldev(cs, sdev); - ldev_info = kzalloc(sizeof(*ldev_info), GFP_KERNEL); + ldev_info = kzalloc_obj(*ldev_info); if (!ldev_info) return -ENOMEM; @@ -1865,7 +1865,7 @@ static int myrs_sdev_init(struct scsi_device *sdev) } else { struct myrs_pdev_info *pdev_info; - pdev_info = kzalloc(sizeof(*pdev_info), GFP_KERNEL); + pdev_info = kzalloc_obj(*pdev_info); if (!pdev_info) return -ENOMEM; diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 1b54ba51a485..014ae8d42331 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c @@ -96,7 +96,7 @@ static int aha152x_probe(struct pcmcia_device *link) dev_dbg(&link->dev, "aha152x_attach()\n"); /* Create new SCSI device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->p_dev = link; link->priv = info; diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index fb3a1b43d8bd..ae70fda96ae9 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c @@ -1520,7 +1520,7 @@ static int nsp_cs_probe(struct pcmcia_device *link) nsp_dbg(NSP_DEBUG_INIT, "in"); /* Create new SCSI device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info == NULL) { return -ENOMEM; } info->p_dev = link; link->priv = info; diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c index 310d0b6586a6..5d8a434d3f66 100644 --- a/drivers/scsi/pcmcia/qlogic_stub.c +++ b/drivers/scsi/pcmcia/qlogic_stub.c @@ -152,7 +152,7 @@ static int qlogic_probe(struct pcmcia_device *link) dev_dbg(&link->dev, "qlogic_attach()\n"); /* Create new SCSI device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->p_dev = link; diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 8f56f7277dee..1530c1ad5d36 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -849,7 +849,7 @@ SYM53C500_probe(struct pcmcia_device *link) dev_dbg(&link->dev, "SYM53C500_attach()\n"); /* Create new SCSI device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->p_dev = link; diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 8005995a317c..fff8d877abb9 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1686,7 +1686,7 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data, struct pm8001_work *pw; int ret = 0; - pw = kmalloc(sizeof(struct pm8001_work), GFP_ATOMIC); + pw = kmalloc_obj(struct pm8001_work, GFP_ATOMIC); if (pw) { pw->pm8001_ha = pm8001_ha; pw->data = data; @@ -4371,7 +4371,7 @@ int pm8001_chip_get_nvmd_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_ioctl_payload *ioctl_payload = payload; nvmd_type = ioctl_payload->minor_function; - fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL); + fw_control_context = kzalloc_obj(struct fw_control_ex); if (!fw_control_context) return -ENOMEM; fw_control_context->usrAddr = (u8 *)ioctl_payload->func_specific; @@ -4464,7 +4464,7 @@ int pm8001_chip_set_nvmd_req(struct pm8001_hba_info *pm8001_ha, struct pm8001_ioctl_payload *ioctl_payload = payload; nvmd_type = ioctl_payload->minor_function; - fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL); + fw_control_context = kzalloc_obj(struct fw_control_ex); if (!fw_control_context) return -ENOMEM; @@ -4579,7 +4579,7 @@ pm8001_chip_fw_flash_update_req(struct pm8001_hba_info *pm8001_ha, dma_addr_t phys_addr = pm8001_ha->memoryMap.region[FW_FLASH].phys_addr; struct pm8001_ioctl_payload *ioctl_payload = payload; - fw_control_context = kzalloc(sizeof(struct fw_control_ex), GFP_KERNEL); + fw_control_context = kzalloc_obj(struct fw_control_ex); if (!fw_control_context) return -ENOMEM; fw_control = (struct fw_control_info *)&ioctl_payload->func_specific; diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 9acca83d6958..e93ea76b565e 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -622,7 +622,7 @@ static int pm8001_prep_sas_ha_init(struct Scsi_Host *shost, sha->sas_phy = arr_phy; sha->sas_port = arr_port; - sha->lldd_ha = kzalloc(sizeof(struct pm8001_hba_info), GFP_KERNEL); + sha->lldd_ha = kzalloc_obj(struct pm8001_hba_info); if (!sha->lldd_ha) goto exit_free1; @@ -1148,7 +1148,7 @@ static int pm8001_pci_probe(struct pci_dev *pdev, goto err_out_regions; } chip = &pm8001_chips[ent->driver_data]; - sha = kzalloc(sizeof(struct sas_ha_struct), GFP_KERNEL); + sha = kzalloc_obj(struct sas_ha_struct); if (!sha) { rc = -ENOMEM; goto err_out_free_host; @@ -1264,7 +1264,7 @@ static int pm8001_init_ccb_tag(struct pm8001_hba_info *pm8001_ha) /* Memory region for ccb_info*/ pm8001_ha->ccb_count = ccb_count; pm8001_ha->ccb_info = - kcalloc(ccb_count, sizeof(struct pm8001_ccb_info), GFP_KERNEL); + kzalloc_objs(struct pm8001_ccb_info, ccb_count); if (!pm8001_ha->ccb_info) { pm8001_dbg(pm8001_ha, FAIL, "Unable to allocate memory for ccb\n"); diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 6a8d35aea93a..645524f3fe2d 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -525,8 +525,9 @@ int pm8001_queue_command(struct sas_task *task, gfp_t gfp_flags) } else { task->task_done(task); } - rc = -ENODEV; - goto err_out; + spin_unlock_irqrestore(&pm8001_ha->lock, flags); + pm8001_dbg(pm8001_ha, IO, "pm8001_task_exec device gone\n"); + return 0; } ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, task); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 31960b72c1e9..954f307352e6 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1563,7 +1563,7 @@ void pm80xx_fatal_error_uevent_emit(struct pm8001_hba_info *pm8001_ha, pm8001_dbg(pm8001_ha, FAIL, "emitting fatal error uevent"); - env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); + env = kzalloc_obj(struct kobj_uevent_env); if (!env) return; diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index cf163e63054b..942a99393204 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -3468,7 +3468,7 @@ static long pmcraid_chr_ioctl( void __user *argp = (void __user *)arg; int retval = -ENOTTY; - hdr = kmalloc(sizeof(struct pmcraid_ioctl_header), GFP_KERNEL); + hdr = kmalloc_obj(struct pmcraid_ioctl_header); if (!hdr) { pmcraid_err("failed to allocate memory for ioctl header\n"); @@ -4385,9 +4385,8 @@ static int pmcraid_allocate_config_buffers(struct pmcraid_instance *pinstance) int i; pinstance->res_entries = - kcalloc(PMCRAID_MAX_RESOURCES, - sizeof(struct pmcraid_resource_entry), - GFP_KERNEL); + kzalloc_objs(struct pmcraid_resource_entry, + PMCRAID_MAX_RESOURCES); if (NULL == pinstance->res_entries) { pmcraid_err("failed to allocate memory for resource table\n"); diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c index ddcef40789e5..8a4e910d5758 100644 --- a/drivers/scsi/ppa.c +++ b/drivers/scsi/ppa.c @@ -1042,7 +1042,7 @@ static int __ppa_attach(struct parport *pb) int err = -ENOMEM; struct pardev_cb ppa_cb; - dev = kzalloc(sizeof(ppa_struct), GFP_KERNEL); + dev = kzalloc_obj(ppa_struct); if (!dev) return -ENOMEM; dev->base = -1; diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c index 96174353e389..a9d109c2cb4d 100644 --- a/drivers/scsi/qedf/qedf_debugfs.c +++ b/drivers/scsi/qedf/qedf_debugfs.c @@ -422,7 +422,7 @@ qedf_offload_stats_show(struct seq_file *s, void *unused) struct qedf_ctx *qedf = s->private; struct qed_fcoe_stats *fw_fcoe_stats; - fw_fcoe_stats = kmalloc(sizeof(struct qed_fcoe_stats), GFP_KERNEL); + fw_fcoe_stats = kmalloc_obj(struct qed_fcoe_stats); if (!fw_fcoe_stats) { QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate memory for " "fw_fcoe_stats.\n"); diff --git a/drivers/scsi/qedf/qedf_els.c b/drivers/scsi/qedf/qedf_els.c index 1ff5bc314fc0..12841516653d 100644 --- a/drivers/scsi/qedf/qedf_els.c +++ b/drivers/scsi/qedf/qedf_els.c @@ -297,7 +297,7 @@ int qedf_send_rrq(struct qedf_ioreq *aborted_io_req) aborted_io_req->xid); memset(&rrq, 0, sizeof(rrq)); - cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct qedf_els_cb_arg, GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "RRQ\n"); @@ -510,7 +510,7 @@ int qedf_send_adisc(struct qedf_rport *fcport, struct fc_frame *fp) qedf = fcport->qedf; fh = fc_frame_header_get(fp); - cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct qedf_els_cb_arg, GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "ADISC\n"); @@ -659,7 +659,7 @@ static int qedf_send_srr(struct qedf_ioreq *orig_io_req, u32 offset, u8 r_ctl) "orig_xid=0x%x\n", orig_io_req, orig_io_req->xid); memset(&srr, 0, sizeof(srr)); - cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct qedf_els_cb_arg, GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "SRR\n"); @@ -708,7 +708,7 @@ static void qedf_initiate_seq_cleanup(struct qedf_ioreq *orig_io_req, "Doing sequence cleanup for xid=0x%x offset=%u.\n", orig_io_req->xid, offset); - cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct qedf_els_cb_arg, GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(fcport->qedf->dbg_ctx), "Unable to allocate cb_arg " "for sequence cleanup\n"); @@ -1033,7 +1033,7 @@ int qedf_send_rec(struct qedf_ioreq *orig_io_req) memset(&rec, 0, sizeof(rec)); - cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO); + cb_arg = kzalloc_obj(struct qedf_els_cb_arg, GFP_NOIO); if (!cb_arg) { QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for " "REC\n"); diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index d12c47be016e..a120f0e37a64 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c @@ -230,8 +230,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) } /* Allocate task parameters to pass to f/w init funcions */ - io_req->task_params = kzalloc(sizeof(*io_req->task_params), - GFP_KERNEL); + io_req->task_params = kzalloc_obj(*io_req->task_params); if (!io_req->task_params) { QEDF_ERR(&(qedf->dbg_ctx), "Failed to allocate task_params for xid=0x%x\n", @@ -243,8 +242,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) * Allocate scatter/gather list info to pass to f/w init * functions. */ - io_req->sgl_task_params = kzalloc( - sizeof(struct scsi_sgl_task_params), GFP_KERNEL); + io_req->sgl_task_params = kzalloc_obj(struct scsi_sgl_task_params); if (!io_req->sgl_task_params) { QEDF_ERR(&(qedf->dbg_ctx), "Failed to allocate sgl_task_params for xid=0x%x\n", @@ -254,8 +252,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) } /* Allocate pool of io_bdts - one for each qedf_ioreq */ - cmgr->io_bdt_pool = kmalloc_array(num_ios, sizeof(struct io_bdt *), - GFP_KERNEL); + cmgr->io_bdt_pool = kmalloc_objs(struct io_bdt *, num_ios); if (!cmgr->io_bdt_pool) { QEDF_WARN(&(qedf->dbg_ctx), "Failed to alloc io_bdt_pool.\n"); @@ -263,8 +260,7 @@ struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf) } for (i = 0; i < num_ios; i++) { - cmgr->io_bdt_pool[i] = kmalloc(sizeof(struct io_bdt), - GFP_KERNEL); + cmgr->io_bdt_pool[i] = kmalloc_obj(struct io_bdt); if (!cmgr->io_bdt_pool[i]) { QEDF_WARN(&(qedf->dbg_ctx), "Failed to alloc io_bdt_pool[%d].\n", i); diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 7792e00800ae..da429b3a4283 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -2082,7 +2082,7 @@ static struct fc_host_statistics *qedf_fc_get_host_stats(struct Scsi_Host if (lport->vport) goto out; - fw_fcoe_stats = kmalloc(sizeof(struct qed_fcoe_stats), GFP_KERNEL); + fw_fcoe_stats = kmalloc_obj(struct qed_fcoe_stats); if (!fw_fcoe_stats) { QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate memory for " "fw_fcoe_stats.\n"); @@ -2674,7 +2674,7 @@ static int qedf_ll2_rx(void *cookie, struct sk_buff *skb, return 0; } - skb_work = kzalloc(sizeof(struct qedf_skb_work), GFP_ATOMIC); + skb_work = kzalloc_obj(struct qedf_skb_work, GFP_ATOMIC); if (!skb_work) { QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate skb_work so " "dropping frame.\n"); @@ -2778,8 +2778,7 @@ static int qedf_prepare_sb(struct qedf_ctx *qedf) int ret; qedf->fp_array = - kcalloc(qedf->num_queues, sizeof(struct qedf_fastpath), - GFP_KERNEL); + kzalloc_objs(struct qedf_fastpath, qedf->num_queues); if (!qedf->fp_array) { QEDF_ERR(&(qedf->dbg_ctx), "fastpath array allocation " @@ -2790,7 +2789,7 @@ static int qedf_prepare_sb(struct qedf_ctx *qedf) for (id = 0; id < qedf->num_queues; id++) { fp = &(qedf->fp_array[id]); fp->sb_id = QEDF_SB_ID_NULL; - fp->sb_info = kcalloc(1, sizeof(*fp->sb_info), GFP_KERNEL); + fp->sb_info = kzalloc_objs(*fp->sb_info, 1); if (!fp->sb_info) { QEDF_ERR(&(qedf->dbg_ctx), "SB info struct " "allocation failed.\n"); @@ -3083,8 +3082,7 @@ static int qedf_alloc_global_queues(struct qedf_ctx *qedf) /* Allocate a CQ and an associated PBL for each MSI-X vector */ for (i = 0; i < qedf->num_queues; i++) { - qedf->global_queues[i] = kzalloc(sizeof(struct global_queue), - GFP_KERNEL); + qedf->global_queues[i] = kzalloc_obj(struct global_queue); if (!qedf->global_queues[i]) { QEDF_WARN(&(qedf->dbg_ctx), "Unable to allocate " "global queue %d.\n", i); diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 6901738324da..854efa4f61d8 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -190,7 +190,7 @@ static void qedi_process_tmf_resp(struct qedi_ctx *qedi, cqe_tmp_response = &cqe->cqe_common.iscsi_hdr.tmf_response; qedi_cmd = task->dd_data; - qedi_cmd->tmf_resp_buf = kzalloc(sizeof(*resp_hdr_ptr), GFP_ATOMIC); + qedi_cmd->tmf_resp_buf = kzalloc_obj(*resp_hdr_ptr, GFP_ATOMIC); if (!qedi_cmd->tmf_resp_buf) { QEDI_ERR(&qedi->dbg_ctx, "Failed to allocate resp buf, cid=0x%x\n", @@ -1358,7 +1358,7 @@ static void qedi_abort_work(struct work_struct *work) goto clear_cleanup; } - list_work = kzalloc(sizeof(*list_work), GFP_NOIO); + list_work = kzalloc_obj(*list_work, GFP_NOIO); if (!list_work) { QEDI_ERR(&qedi->dbg_ctx, "Memory allocation failed\n"); goto clear_cleanup; diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 6ed8ef97642c..6ab3a989d281 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -440,7 +440,7 @@ static int qedi_iscsi_update_conn(struct qedi_ctx *qedi, qedi_ep = qedi_conn->ep; - conn_info = kzalloc(sizeof(*conn_info), GFP_KERNEL); + conn_info = kzalloc_obj(*conn_info); if (!conn_info) { QEDI_ERR(&qedi->dbg_ctx, "memory alloc failed\n"); return -ENOMEM; @@ -505,7 +505,7 @@ static int qedi_iscsi_offload_conn(struct qedi_endpoint *qedi_ep) int rval; int i; - conn_info = kzalloc(sizeof(*conn_info), GFP_KERNEL); + conn_info = kzalloc_obj(*conn_info); if (!conn_info) { QEDI_ERR(&qedi->dbg_ctx, "Failed to allocate memory ep=%p\n", qedi_ep); diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 56685ee22fdf..227ff7bd1bdc 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -276,7 +276,7 @@ static int qedi_alloc_uio_rings(struct qedi_ctx *qedi) } } - udev = kzalloc(sizeof(*udev), GFP_KERNEL); + udev = kzalloc_obj(*udev); if (!udev) goto err_udev; @@ -410,16 +410,16 @@ static int qedi_alloc_fp(struct qedi_ctx *qedi) { int ret = 0; - qedi->fp_array = kcalloc(MIN_NUM_CPUS_MSIX(qedi), - sizeof(struct qedi_fastpath), GFP_KERNEL); + qedi->fp_array = kzalloc_objs(struct qedi_fastpath, + MIN_NUM_CPUS_MSIX(qedi)); if (!qedi->fp_array) { QEDI_ERR(&qedi->dbg_ctx, "fastpath fp array allocation failed.\n"); return -ENOMEM; } - qedi->sb_array = kcalloc(MIN_NUM_CPUS_MSIX(qedi), - sizeof(struct qed_sb_info), GFP_KERNEL); + qedi->sb_array = kzalloc_objs(struct qed_sb_info, + MIN_NUM_CPUS_MSIX(qedi)); if (!qedi->sb_array) { QEDI_ERR(&qedi->dbg_ctx, "fastpath sb array allocation failed.\n"); @@ -498,9 +498,8 @@ static int qedi_setup_cid_que(struct qedi_ctx *qedi) if (!qedi->cid_que.cid_que_base) return -ENOMEM; - qedi->cid_que.conn_cid_tbl = kmalloc_array(qedi->max_active_conns, - sizeof(struct qedi_conn *), - GFP_KERNEL); + qedi->cid_que.conn_cid_tbl = kmalloc_objs(struct qedi_conn *, + qedi->max_active_conns); if (!qedi->cid_que.conn_cid_tbl) { kfree(qedi->cid_que.cid_que_base); qedi->cid_que.cid_que_base = NULL; @@ -706,7 +705,7 @@ static int qedi_ll2_rx(void *cookie, struct sk_buff *skb, u32 arg1, u32 arg2) "Allowed frame ethertype [0x%x] len [0x%x].\n", eh->h_proto, skb->len); - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) { QEDI_WARN(&qedi->dbg_ctx, "Could not allocate work so dropping frame.\n"); @@ -956,7 +955,7 @@ static int qedi_find_boot_info(struct qedi_ctx *qedi, pri_ctrl_flags = !!(block->target[0].ctrl_flags & NVM_ISCSI_CFG_TARGET_ENABLED); if (pri_ctrl_flags) { - pri_tgt = kzalloc(sizeof(*pri_tgt), GFP_KERNEL); + pri_tgt = kzalloc_obj(*pri_tgt); if (!pri_tgt) return -1; qedi_get_boot_tgt_info(block, pri_tgt, 0); @@ -965,7 +964,7 @@ static int qedi_find_boot_info(struct qedi_ctx *qedi, sec_ctrl_flags = !!(block->target[1].ctrl_flags & NVM_ISCSI_CFG_TARGET_ENABLED); if (sec_ctrl_flags) { - sec_tgt = kzalloc(sizeof(*sec_tgt), GFP_KERNEL); + sec_tgt = kzalloc_obj(*sec_tgt); if (!sec_tgt) { ret = -1; goto free_tgt; @@ -1066,7 +1065,7 @@ static void qedi_get_protocol_tlv_data(void *dev, void *data) struct qedi_ctx *qedi = dev; int rval = 0; - fw_iscsi_stats = kmalloc(sizeof(*fw_iscsi_stats), GFP_KERNEL); + fw_iscsi_stats = kmalloc_obj(*fw_iscsi_stats); if (!fw_iscsi_stats) { QEDI_ERR(&qedi->dbg_ctx, "Could not allocate memory for fw_iscsi_stats.\n"); @@ -1239,7 +1238,7 @@ static int qedi_queue_cqe(struct qedi_ctx *qedi, union iscsi_cqe *cqe, case ISCSI_CQE_TYPE_UNSOLICITED: case ISCSI_CQE_TYPE_DUMMY: case ISCSI_CQE_TYPE_TASK_CLEANUP: - qedi_work = kzalloc(sizeof(*qedi_work), GFP_ATOMIC); + qedi_work = kzalloc_obj(*qedi_work, GFP_ATOMIC); if (!qedi_work) { rc = -1; break; @@ -1668,8 +1667,7 @@ static int qedi_alloc_global_queues(struct qedi_ctx *qedi) */ for (i = 0; i < qedi->num_queues; i++) { qedi->global_queues[i] = - kzalloc(sizeof(*qedi->global_queues[0]), - GFP_KERNEL); + kzalloc_obj(*qedi->global_queues[0]); if (!qedi->global_queues[i]) { QEDI_ERR(&qedi->dbg_ctx, "Unable to allocation global queue %d.\n", i); @@ -1895,8 +1893,8 @@ struct qedi_cmd *qedi_get_cmd_from_tid(struct qedi_ctx *qedi, u32 tid) static int qedi_alloc_itt(struct qedi_ctx *qedi) { - qedi->itt_map = kcalloc(MAX_ISCSI_TASK_ENTRIES, - sizeof(struct qedi_itt_map), GFP_KERNEL); + qedi->itt_map = kzalloc_objs(struct qedi_itt_map, + MAX_ISCSI_TASK_ENTRIES); if (!qedi->itt_map) { QEDI_ERR(&qedi->dbg_ctx, "Unable to allocate itt map array memory\n"); diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 2c44a379cb23..5e910b5ca670 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -2395,7 +2395,7 @@ qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job) !IS_QLA28XX(vha->hw)) return -EPERM; - dd = kmalloc(sizeof(*dd), GFP_KERNEL); + dd = kmalloc_obj(*dd); if (!dd) { ql_log(ql_log_warn, vha, 0x70db, "Failed to allocate memory for dport.\n"); @@ -2441,7 +2441,7 @@ qla2x00_do_dport_diagnostics_v2(struct bsg_job *bsg_job) if (!IS_DPORT_CAPABLE(vha->hw)) return -EPERM; - dd = kzalloc(sizeof(*dd), GFP_KERNEL); + dd = kzalloc_obj(*dd); if (!dd) return -ENOMEM; @@ -2598,7 +2598,7 @@ qla2x00_manage_host_stats(struct bsg_job *bsg_job) return -EIO; } - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); + req_data = kzalloc_obj(*req_data); if (!req_data) { ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n"); return -ENOMEM; @@ -2669,7 +2669,7 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) return -EIO; } - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); + req_data = kzalloc_obj(*req_data); if (!req_data) { ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n"); return -ENOMEM; @@ -2776,7 +2776,7 @@ qla2x00_get_tgt_stats(struct bsg_job *bsg_job) return -EIO; } - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); + req_data = kzalloc_obj(*req_data); if (!req_data) { ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n"); return -ENOMEM; @@ -2859,7 +2859,7 @@ qla2x00_manage_host_port(struct bsg_job *bsg_job) return -EIO; } - req_data = kzalloc(sizeof(*req_data), GFP_KERNEL); + req_data = kzalloc_obj(*req_data); if (!req_data) { ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n"); return -ENOMEM; diff --git a/drivers/scsi/qla2xxx/qla_edif.c b/drivers/scsi/qla2xxx/qla_edif.c index ccd4485087a1..eccedb38a515 100644 --- a/drivers/scsi/qla2xxx/qla_edif.c +++ b/drivers/scsi/qla2xxx/qla_edif.c @@ -174,7 +174,7 @@ static int qla_edif_list_add_sa_update_index(fc_port_t *fcport, * when update is called for the first two sa_indexes * followed by a delete of the first sa_index */ - entry = kzalloc((sizeof(struct edif_list_entry)), GFP_ATOMIC); + entry = kzalloc_obj(struct edif_list_entry, GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -1393,7 +1393,7 @@ qla_edif_add_sa_ctl(fc_port_t *fcport, struct qla_sa_update_frame *sa_frame, int index = sa_frame->fast_sa_index; unsigned long flags = 0; - sa_ctl = kzalloc(sizeof(*sa_ctl), GFP_KERNEL); + sa_ctl = kzalloc_obj(*sa_ctl); if (!sa_ctl) { /* couldn't get space */ ql_dbg(ql_dbg_edif, fcport->vha, 0x9100, @@ -2187,7 +2187,7 @@ qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype) { struct edb_node *node; - node = kzalloc(sizeof(*node), GFP_ATOMIC); + node = kzalloc_obj(*node, GFP_ATOMIC); if (!node) { /* couldn't get space */ ql_dbg(ql_dbg_edif, vha, 0x9100, @@ -3279,7 +3279,7 @@ static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport, } /* if there is no entry for this nport, add one */ - entry = kzalloc((sizeof(struct edif_sa_index_entry)), GFP_ATOMIC); + entry = kzalloc_obj(struct edif_sa_index_entry, GFP_ATOMIC); if (!entry) return INVALID_EDIF_SA_INDEX; @@ -3381,7 +3381,7 @@ void qla_edif_sadb_release(struct qla_hw_data *ha) int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha) { ha->edif_tx_sa_id_map = - kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL); + kzalloc_objs(long, BITS_TO_LONGS(EDIF_NUM_SA_INDEX)); if (!ha->edif_tx_sa_id_map) { ql_log_pci(ql_log_fatal, ha->pdev, 0x0009, @@ -3390,7 +3390,7 @@ int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha) } ha->edif_rx_sa_id_map = - kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL); + kzalloc_objs(long, BITS_TO_LONGS(EDIF_NUM_SA_INDEX)); if (!ha->edif_rx_sa_id_map) { kfree(ha->edif_tx_sa_id_map); ha->edif_tx_sa_id_map = NULL; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 689f909943b4..730c42b1a7b9 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -4033,9 +4033,7 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req) req->num_outstanding_cmds = ha->cur_fw_iocb_count; } - req->outstanding_cmds = kcalloc(req->num_outstanding_cmds, - sizeof(srb_t *), - GFP_KERNEL); + req->outstanding_cmds = kzalloc_objs(srb_t *, req->num_outstanding_cmds); if (!req->outstanding_cmds) { /* @@ -4043,9 +4041,8 @@ qla2x00_alloc_outstanding_cmds(struct qla_hw_data *ha, struct req_que *req) * initialization. */ req->num_outstanding_cmds = MIN_OUTSTANDING_COMMANDS; - req->outstanding_cmds = kcalloc(req->num_outstanding_cmds, - sizeof(srb_t *), - GFP_KERNEL); + req->outstanding_cmds = kzalloc_objs(srb_t *, + req->num_outstanding_cmds); if (!req->outstanding_cmds) { ql_log(ql_log_fatal, NULL, 0x0126, @@ -5574,7 +5571,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) { fc_port_t *fcport; - fcport = kzalloc(sizeof(fc_port_t), flags); + fcport = kzalloc_obj(fc_port_t, flags); if (!fcport) return NULL; @@ -6494,8 +6491,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) /* Try GID_PT to get device list, else GAN. */ if (!ha->swl) - ha->swl = kcalloc(ha->max_fibre_devices, sizeof(sw_info_t), - GFP_KERNEL); + ha->swl = kzalloc_objs(sw_info_t, ha->max_fibre_devices); swl = ha->swl; if (!swl) { /*EMPTY*/ @@ -9231,7 +9227,7 @@ qla84xx_get_chip(struct scsi_qla_host *vha) } } - cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL); + cs84xx = kzalloc_obj(*cs84xx); if (!cs84xx) goto done; @@ -9885,7 +9881,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, } if (ql2xmqsupport || ql2xnvmeenable) { - qpair = kzalloc(sizeof(struct qla_qpair), GFP_KERNEL); + qpair = kzalloc_obj(struct qla_qpair); if (qpair == NULL) { ql_log(ql_log_warn, vha, 0x0182, "Failed to allocate memory for queue pair.\n"); diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index ef4b3cc1cd77..53eaff1e0f65 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h @@ -621,8 +621,7 @@ static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha) scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); if (!ha->qp_cpu_map) { - ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *), - GFP_KERNEL); + ha->qp_cpu_map = kzalloc_objs(struct qla_qpair *, NR_CPUS); if (!ha->qp_cpu_map) { ql_log(ql_log_fatal, vha, 0x0180, "Unable to allocate memory for qp_cpu_map ptrs.\n"); diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 3224044f1775..dbe3cd4e274c 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c @@ -882,7 +882,7 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, used_dsds -= avail_dsds; /* allocate tracking DS */ - dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(struct dsd_dma, GFP_ATOMIC); if (!dsd_ptr) return 1; @@ -979,7 +979,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, used_dsds -= avail_dsds; /* allocate tracking DS */ - dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(struct dsd_dma, GFP_ATOMIC); if (!dsd_ptr) return 1; @@ -1123,8 +1123,8 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, * Allocate list item to store * the DMA buffers */ - dsd_ptr = kzalloc(sizeof(*dsd_ptr), - GFP_ATOMIC); + dsd_ptr = kzalloc_obj(*dsd_ptr, + GFP_ATOMIC); if (!dsd_ptr) { ql_dbg(ql_dbg_tgt, vha, 0xe024, "%s: failed alloc dsd_ptr\n", @@ -1209,7 +1209,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, used_dsds -= avail_dsds; /* allocate tracking DS */ - dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(*dsd_ptr, GFP_ATOMIC); if (!dsd_ptr) { ql_dbg(ql_dbg_tgt, vha, 0xe026, "%s: failed alloc dsd_ptr\n", @@ -1275,7 +1275,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, used_dsds -= avail_dsds; /* allocate tracking DS */ - dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(*dsd_ptr, GFP_ATOMIC); if (!dsd_ptr) { ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe027, @@ -2751,7 +2751,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, if (!elsio->u.els_logo.els_logo_pyld) { /* ref: INIT */ kref_put(&sp->cmd_kref, qla2x00_sp_release); - qla2x00_free_fcport(fcport); return QLA_FUNCTION_FAILED; } @@ -2776,7 +2775,6 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, if (rval != QLA_SUCCESS) { /* ref: INIT */ kref_put(&sp->cmd_kref, qla2x00_sp_release); - qla2x00_free_fcport(fcport); return QLA_FUNCTION_FAILED; } @@ -3450,7 +3448,7 @@ qla82xx_start_scsi(srb_t *sp) more_dsd_lists -= qpair->dsd_avail; for (i = 0; i < more_dsd_lists; i++) { - dsd_ptr = kzalloc(sizeof(struct dsd_dma), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(struct dsd_dma, GFP_ATOMIC); if (!dsd_ptr) { ql_log(ql_log_fatal, vha, 0x300e, "Failed to allocate memory for dsd_dma " @@ -4315,7 +4313,7 @@ qla_start_scsi_type6(srb_t *sp) more_dsd_lists -= qpair->dsd_avail; for (i = 0; i < more_dsd_lists; i++) { - dsd_ptr = kzalloc(sizeof(*dsd_ptr), GFP_ATOMIC); + dsd_ptr = kzalloc_obj(*dsd_ptr, GFP_ATOMIC); if (!dsd_ptr) { ql_log(ql_log_fatal, vha, 0x3029, "Failed to allocate memory for dsd_dma for cmd=%p.\n", cmd); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 608d2f36e7b4..33776330956c 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -4562,9 +4562,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) } } vha->irq_offset = desc.pre_vectors; - ha->msix_entries = kcalloc(ha->msix_count, - sizeof(struct qla_msix_entry), - GFP_KERNEL); + ha->msix_entries = kzalloc_objs(struct qla_msix_entry, ha->msix_count); if (!ha->msix_entries) { ql_log(ql_log_fatal, vha, 0x00c8, "Failed to allocate memory for ha->msix_entries.\n"); diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 0abc47e72e0b..c563133f751e 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c @@ -707,7 +707,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options, device_reg_t *reg; uint32_t cnt; - req = kzalloc(sizeof(struct req_que), GFP_KERNEL); + req = kzalloc_obj(struct req_que); if (req == NULL) { ql_log(ql_log_fatal, base_vha, 0x00d9, "Failed to allocate memory for request queue.\n"); @@ -834,7 +834,7 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options, uint16_t que_id = 0; device_reg_t *reg; - rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL); + rsp = kzalloc_obj(struct rsp_que); if (rsp == NULL) { ql_log(ql_log_warn, base_vha, 0x0066, "Failed to allocate memory for response queue.\n"); @@ -1102,7 +1102,7 @@ int qla_create_buf_pool(struct scsi_qla_host *vha, struct qla_qpair *qp) return -ENOMEM; } sz = qp->req->length * sizeof(dma_addr_t); - qp->buf_pool.dma_array = kcalloc(qp->req->length, sizeof(dma_addr_t), GFP_KERNEL); + qp->buf_pool.dma_array = kzalloc_objs(dma_addr_t, qp->req->length); if (!qp->buf_pool.dma_array) { ql_log(ql_log_warn, vha, 0x0186, "Failed to allocate dma_array(%d).\n", sz); diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 42eb65a62f1f..2531e71c39dc 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c @@ -1286,7 +1286,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) goto out; } - uctx = kzalloc(sizeof(*uctx), GFP_ATOMIC); + uctx = kzalloc_obj(*uctx, GFP_ATOMIC); if (!uctx) { ql_log(ql_log_info, vha, 0x2126, "Failed allocate memory\n"); a.reason = FCNVME_RJT_RC_LOGIC; diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 0cd3db8ed4ef..298c060c1292 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -1183,7 +1183,7 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha) ql_log(ql_log_info, vha, 0x0072, "%d CRB init values found in ROM.\n", n); - buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kmalloc_objs(struct crb_addr_pair, n); if (buf == NULL) { ql_log(ql_log_fatal, vha, 0x010c, "Unable to allocate memory.\n"); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index a88b460641f2..72b1c28e4dae 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -438,23 +438,21 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, { scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - ha->req_q_map = kcalloc(ha->max_req_queues, sizeof(struct req_que *), - GFP_KERNEL); + ha->req_q_map = kzalloc_objs(struct req_que *, ha->max_req_queues); if (!ha->req_q_map) { ql_log(ql_log_fatal, vha, 0x003b, "Unable to allocate memory for request queue ptrs.\n"); goto fail_req_map; } - ha->rsp_q_map = kcalloc(ha->max_rsp_queues, sizeof(struct rsp_que *), - GFP_KERNEL); + ha->rsp_q_map = kzalloc_objs(struct rsp_que *, ha->max_rsp_queues); if (!ha->rsp_q_map) { ql_log(ql_log_fatal, vha, 0x003c, "Unable to allocate memory for response queue ptrs.\n"); goto fail_rsp_map; } - ha->base_qpair = kzalloc(sizeof(struct qla_qpair), GFP_KERNEL); + ha->base_qpair = kzalloc_obj(struct qla_qpair); if (ha->base_qpair == NULL) { ql_log(ql_log_warn, vha, 0x00e0, "Failed to allocate base queue pair memory.\n"); @@ -464,8 +462,8 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req, qla_init_base_qpair(vha, req, rsp); if ((ql2xmqsupport || ql2xnvmeenable) && ha->max_qpairs) { - ha->queue_pair_map = kcalloc(ha->max_qpairs, sizeof(struct qla_qpair *), - GFP_KERNEL); + ha->queue_pair_map = kzalloc_objs(struct qla_qpair *, + ha->max_qpairs); if (!ha->queue_pair_map) { ql_log(ql_log_fatal, vha, 0x0180, "Unable to allocate memory for queue pair ptrs.\n"); @@ -2960,7 +2958,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) ql2xallocfwdump = 0; } - ha = kzalloc(sizeof(struct qla_hw_data), GFP_KERNEL); + ha = kzalloc_obj(struct qla_hw_data); if (!ha) { ql_log_pci(ql_log_fatal, pdev, 0x0009, "Unable to allocate memory for ha.\n"); @@ -4151,7 +4149,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, int rc; if (QLA_TGT_MODE_ENABLED() || EDIF_CAP(ha)) { - ha->vp_map = kcalloc(MAX_MULTI_ID_FABRIC, sizeof(struct qla_vp_map), GFP_KERNEL); + ha->vp_map = kzalloc_objs(struct qla_vp_map, + MAX_MULTI_ID_FABRIC); if (!ha->vp_map) goto fail; } @@ -4247,7 +4246,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ha->pool.good.count = 0; ha->pool.unusable.count = 0; for (i = 0; i < 128; i++) { - dsd = kzalloc(sizeof(*dsd), GFP_ATOMIC); + dsd = kzalloc_obj(*dsd, GFP_ATOMIC); if (!dsd) { ql_dbg_pci(ql_dbg_init, ha->pdev, 0xe0ee, "%s: failed alloc dsd\n", @@ -4335,7 +4334,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, } /* Allocate memory for request ring */ - *req = kzalloc(sizeof(struct req_que), GFP_KERNEL); + *req = kzalloc_obj(struct req_que); if (!*req) { ql_log_pci(ql_log_fatal, ha->pdev, 0x0028, "Failed to allocate memory for req.\n"); @@ -4351,7 +4350,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, goto fail_req_ring; } /* Allocate memory for response ring */ - *rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL); + *rsp = kzalloc_obj(struct rsp_que); if (!*rsp) { ql_log_pci(ql_log_fatal, ha->pdev, 0x002a, "Failed to allocate memory for rsp.\n"); @@ -4376,9 +4375,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, (*rsp)->ring); /* Allocate memory for NVRAM data for vports */ if (ha->nvram_npiv_size) { - ha->npiv_info = kcalloc(ha->nvram_npiv_size, - sizeof(struct qla_npiv_entry), - GFP_KERNEL); + ha->npiv_info = kzalloc_objs(struct qla_npiv_entry, + ha->nvram_npiv_size); if (!ha->npiv_info) { ql_log_pci(ql_log_fatal, ha->pdev, 0x002d, "Failed to allocate memory for npiv_info.\n"); @@ -4422,9 +4420,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, INIT_LIST_HEAD(&ha->vp_list); /* Allocate memory for our loop_id bitmap */ - ha->loop_id_map = kcalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE), - sizeof(long), - GFP_KERNEL); + ha->loop_id_map = kzalloc_objs(long, BITS_TO_LONGS(LOOPID_MAP_SIZE)); if (!ha->loop_id_map) goto fail_loop_id_map; else { @@ -5136,7 +5132,7 @@ qla2x00_alloc_work(struct scsi_qla_host *vha, enum qla_work_type type) if (qla_vha_mark_busy(vha)) return NULL; - e = kzalloc(sizeof(struct qla_work_evt), GFP_ATOMIC); + e = kzalloc_obj(struct qla_work_evt, GFP_ATOMIC); if (!e) { QLA_VHA_MARK_NOT_BUSY(vha); return NULL; @@ -6018,7 +6014,7 @@ qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha, ql_dbg(ql_dbg_init, vha, 0x0181, "%s: s_id=%#x\n", __func__, sid); - pdb = kzalloc(sizeof(*pdb), GFP_KERNEL); + pdb = kzalloc_obj(*pdb); if (!pdb) { ql_dbg(ql_dbg_init, vha, 0x0181, "%s: Failed allocate pdb\n", __func__); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index ef3a5fac2b48..e47da45e93a0 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -1621,7 +1621,7 @@ static int qlt_sched_sess_work(struct qla_tgt *tgt, int type, struct qla_tgt_sess_work_param *prm; unsigned long flags; - prm = kzalloc(sizeof(*prm), GFP_ATOMIC); + prm = kzalloc_obj(*prm, GFP_ATOMIC); if (!prm) { ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf050, "qla_target(%d): Unable to create session " @@ -3988,7 +3988,7 @@ static int qlt_prepare_srr_ctio(struct qla_qpair *qpair, return 0; } - srr = kzalloc(sizeof(*srr), GFP_ATOMIC); + srr = kzalloc_obj(*srr, GFP_ATOMIC); if (!srr) return -ENOMEM; @@ -5561,7 +5561,7 @@ static void qlt_prepare_srr_imm(struct scsi_qla_host *vha, * safely. */ - srr = kzalloc(sizeof(*srr), GFP_ATOMIC); + srr = kzalloc_obj(*srr, GFP_ATOMIC); if (!srr) goto out_reject; @@ -5707,7 +5707,7 @@ static int qlt_set_data_offset(struct qla_tgt_cmd *cmd, uint32_t offset) */ int n_alloc_sg = min(sg_srr_cnt, 2); struct scatterlist *sg_srr = - kmalloc_array(n_alloc_sg, sizeof(*sg_srr), GFP_ATOMIC); + kmalloc_objs(*sg_srr, n_alloc_sg, GFP_ATOMIC); if (!sg_srr) { ql_dbg(ql_dbg_tgt_mgt, vha, 0x11027, "qla_target(%d): tag %lld: Unable to allocate SRR scatterlist\n", @@ -7458,16 +7458,14 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) BUG_ON(base_vha->vha_tgt.qla_tgt != NULL); - tgt = kzalloc(sizeof(struct qla_tgt), GFP_KERNEL); + tgt = kzalloc_obj(struct qla_tgt); if (!tgt) { ql_dbg(ql_dbg_tgt, base_vha, 0xe066, "Unable to allocate struct qla_tgt\n"); return -ENOMEM; } - tgt->qphints = kcalloc(ha->max_qpairs + 1, - sizeof(struct qla_qpair_hint), - GFP_KERNEL); + tgt->qphints = kzalloc_objs(struct qla_qpair_hint, ha->max_qpairs + 1); if (!tgt->qphints) { kfree(tgt); ql_log(ql_log_warn, base_vha, 0x0197, @@ -8280,7 +8278,7 @@ qlt_handle_abts_recv(struct scsi_qla_host *vha, struct rsp_que *rsp, { struct qla_tgt_sess_op *op; - op = kzalloc(sizeof(*op), GFP_ATOMIC); + op = kzalloc_obj(*op, GFP_ATOMIC); if (!op) { /* do not reach for ATIO queue here. This is best effort err diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 3177cb7864a7..28df9025def0 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c @@ -1015,7 +1015,7 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg(struct se_wwn *wwn, return ERR_PTR(-ENOSYS); } - tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); + tpg = kzalloc_obj(struct tcm_qla2xxx_tpg); if (!tpg) { pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); return ERR_PTR(-ENOMEM); @@ -1106,7 +1106,7 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg(struct se_wwn *wwn, if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) return ERR_PTR(-EINVAL); - tpg = kzalloc(sizeof(struct tcm_qla2xxx_tpg), GFP_KERNEL); + tpg = kzalloc_obj(struct tcm_qla2xxx_tpg); if (!tpg) { pr_err("Unable to allocate struct tcm_qla2xxx_tpg\n"); return ERR_PTR(-ENOMEM); @@ -1609,7 +1609,7 @@ static struct se_wwn *tcm_qla2xxx_make_lport( if (tcm_qla2xxx_parse_wwn(name, &wwpn, 1) < 0) return ERR_PTR(-EINVAL); - lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); + lport = kzalloc_obj(struct tcm_qla2xxx_lport); if (!lport) { pr_err("Unable to allocate struct tcm_qla2xxx_lport\n"); return ERR_PTR(-ENOMEM); @@ -1735,7 +1735,7 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( &npiv_wwpn, &npiv_wwnn) < 0) return ERR_PTR(-EINVAL); - lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); + lport = kzalloc_obj(struct tcm_qla2xxx_lport); if (!lport) { pr_err("Unable to allocate struct tcm_qla2xxx_lport for NPIV\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/scsi/qla4xxx/ql4_iocb.c b/drivers/scsi/qla4xxx/ql4_iocb.c index 28eab07935ba..c40441b12db9 100644 --- a/drivers/scsi/qla4xxx/ql4_iocb.c +++ b/drivers/scsi/qla4xxx/ql4_iocb.c @@ -451,7 +451,7 @@ static struct mrb *qla4xxx_get_new_mrb(struct scsi_qla_host *ha) { struct mrb *mrb; - mrb = kzalloc(sizeof(*mrb), GFP_KERNEL); + mrb = kzalloc_obj(*mrb); if (!mrb) return mrb; diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index b0a62aaa1cca..f7340cfc990a 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -1058,7 +1058,7 @@ qla4_82xx_pinit_from_rom(struct scsi_qla_host *ha, int verbose) ql4_printk(KERN_INFO, ha, "%s: %d CRB init values found in ROM.\n", DRIVER_NAME, n); - buf = kmalloc_array(n, sizeof(struct crb_addr_pair), GFP_KERNEL); + buf = kmalloc_objs(struct crb_addr_pair, n); if (buf == NULL) { ql4_printk(KERN_WARNING, ha, "%s: [ERROR] Unable to malloc memory.\n", DRIVER_NAME); diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index 95a86e0dfd77..94f76e358634 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c @@ -81,7 +81,7 @@ static int raid_setup(struct transport_container *tc, struct device *dev, BUG_ON(dev_get_drvdata(cdev)); - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; @@ -212,8 +212,7 @@ raid_attr_ro_state_fn(state); struct raid_template * raid_class_attach(struct raid_function_template *ft) { - struct raid_internal *i = kzalloc(sizeof(struct raid_internal), - GFP_KERNEL); + struct raid_internal *i = kzalloc_obj(struct raid_internal); int count = 0; if (unlikely(!i)) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index c947655db518..1515495fd9ea 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1169,7 +1169,7 @@ static ssize_t sdebug_error_write(struct file *file, const char __user *ubuf, return -EINVAL; } - inject = kzalloc(sizeof(struct sdebug_err_inject), GFP_KERNEL); + inject = kzalloc_obj(struct sdebug_err_inject); if (!inject) { kfree(buf); return -ENOMEM; @@ -1266,7 +1266,7 @@ static int sdebug_target_alloc(struct scsi_target *starget) { struct sdebug_target_info *targetip; - targetip = kzalloc(sizeof(struct sdebug_target_info), GFP_KERNEL); + targetip = kzalloc_obj(struct sdebug_target_info); if (!targetip) return -ENOMEM; @@ -6504,8 +6504,7 @@ static int sdebug_device_create_zones(struct sdebug_dev_info *devip) devip->max_open = sdeb_zbc_max_open; } - devip->zstate = kcalloc(devip->nr_zones, - sizeof(struct sdeb_zone_state), GFP_KERNEL); + devip->zstate = kzalloc_objs(struct sdeb_zone_state, devip->nr_zones); if (!devip->zstate) return -ENOMEM; @@ -6549,7 +6548,7 @@ static struct sdebug_dev_info *sdebug_device_create( { struct sdebug_dev_info *devip; - devip = kzalloc(sizeof(*devip), flags); + devip = kzalloc_obj(*devip, flags); if (devip) { if (sdebug_uuid_ctl == 1) uuid_gen(&devip->lu_name); @@ -6649,8 +6648,7 @@ static int scsi_debug_sdev_configure(struct scsi_device *sdp, if (sdebug_ptype == TYPE_TAPE) { if (!devip->tape_blocks[0]) { devip->tape_blocks[0] = - kcalloc(TAPE_UNITS, sizeof(struct tape_block), - GFP_KERNEL); + kzalloc_objs(struct tape_block, TAPE_UNITS); if (!devip->tape_blocks[0]) return 1; } @@ -8791,7 +8789,7 @@ static int sdebug_add_store(void) struct sdeb_store_info *sip = NULL; struct xa_limit xal = { .max = 1 << 16, .min = 0 }; - sip = kzalloc(sizeof(*sip), GFP_KERNEL); + sip = kzalloc_obj(*sip); if (!sip) return -ENOMEM; @@ -8868,7 +8866,7 @@ static int sdebug_add_host_helper(int per_host_idx) struct sdebug_host_info *sdbg_host; struct sdebug_dev_info *sdbg_devinfo, *tmp; - sdbg_host = kzalloc(sizeof(*sdbg_host), GFP_KERNEL); + sdbg_host = kzalloc_obj(*sdbg_host); if (!sdbg_host) return -ENOMEM; idx = (per_host_idx < 0) ? sdeb_first_idx : per_host_idx; diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 78346b2b69c9..68a992494b12 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -190,7 +190,7 @@ static struct { {"IBM", "2076", NULL, BLIST_NO_VPD_SIZE}, {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, {"iomega", "jaz 1GB", "J.86", BLIST_NOTQ | BLIST_NOLUN}, - {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN}, + {"IOMEGA", "ZIP", NULL, BLIST_NOTQ | BLIST_NOLUN | BLIST_SKIP_IO_HINTS}, {"IOMEGA", "Io20S *F", NULL, BLIST_KEY}, {"INSITE", "Floptical F*8I", NULL, BLIST_KEY}, {"INSITE", "I325VM", NULL, BLIST_KEY}, @@ -355,7 +355,7 @@ int scsi_dev_info_list_add_keyed(int compatible, char *vendor, char *model, if (IS_ERR(devinfo_table)) return PTR_ERR(devinfo_table); - devinfo = kmalloc(sizeof(*devinfo), GFP_KERNEL); + devinfo = kmalloc_obj(*devinfo); if (!devinfo) { printk(KERN_ERR "%s: no memory\n", __func__); return -ENOMEM; @@ -615,7 +615,7 @@ static int devinfo_seq_show(struct seq_file *m, void *v) static void *devinfo_seq_start(struct seq_file *m, loff_t *ppos) { - struct double_list *dl = kmalloc(sizeof(*dl), GFP_KERNEL); + struct double_list *dl = kmalloc_obj(*dl); loff_t pos = *ppos; if (!dl) @@ -759,7 +759,7 @@ int scsi_dev_info_add_list(enum scsi_devinfo_key key, const char *name) /* list already exists */ return -EEXIST; - devinfo_table = kmalloc(sizeof(*devinfo_table), GFP_KERNEL); + devinfo_table = kmalloc_obj(*devinfo_table); if (!devinfo_table) return -ENOMEM; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 68c411aa5665..d3a8cd4166f9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2751,7 +2751,7 @@ EXPORT_SYMBOL_GPL(sdev_evt_send); struct scsi_event *sdev_evt_alloc(enum scsi_device_event evt_type, gfp_t gfpflags) { - struct scsi_event *evt = kzalloc(sizeof(struct scsi_event), gfpflags); + struct scsi_event *evt = kzalloc_obj(struct scsi_event, gfpflags); if (!evt) return NULL; diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 41f23cd0bfb4..1799dcae775c 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -162,7 +162,7 @@ int scsi_proc_hostdir_add(const struct scsi_host_template *sht) mutex_lock(&global_host_template_mutex); e = __scsi_lookup_proc_entry(sht); if (!e) { - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) { ret = -ENOMEM; goto unlock; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 7acbfcfc2172..7b11bc7de0e3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -360,11 +360,8 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, * default device queue depth to figure out sbitmap shift * since we use this queue depth most of times. */ - if (scsi_realloc_sdev_budget_map(sdev, depth)) { - put_device(&starget->dev); - kfree(sdev); - goto out; - } + if (scsi_realloc_sdev_budget_map(sdev, depth)) + goto out_device_destroy; scsi_change_queue_depth(sdev, depth); @@ -1954,7 +1951,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) goto err; } - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) goto err; data->shost = scsi_host_get(shost); diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 9532138105c1..dce95e361daf 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -2651,8 +2651,7 @@ struct scsi_transport_template * fc_attach_transport(struct fc_function_template *ft) { int count; - struct fc_internal *i = kzalloc(sizeof(struct fc_internal), - GFP_KERNEL); + struct fc_internal *i = kzalloc_obj(struct fc_internal); if (unlikely(!i)) return NULL; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index ed21c032bbc4..8aa76f813bcd 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -4848,7 +4848,7 @@ iscsi_register_transport(struct iscsi_transport *tt) if (priv) return NULL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; INIT_LIST_HEAD(&priv->list); diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index d69c7c444a31..12124f9d5ccd 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -712,7 +712,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number) struct Scsi_Host *shost = dev_to_shost(parent); struct sas_phy *phy; - phy = kzalloc(sizeof(*phy), GFP_KERNEL); + phy = kzalloc_obj(*phy); if (!phy) return NULL; @@ -907,7 +907,7 @@ struct sas_port *sas_port_alloc(struct device *parent, int port_id) struct Scsi_Host *shost = dev_to_shost(parent); struct sas_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return NULL; @@ -1467,7 +1467,7 @@ struct sas_rphy *sas_end_device_alloc(struct sas_port *parent) struct Scsi_Host *shost = dev_to_shost(&parent->dev); struct sas_end_device *rdev; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) { return NULL; } @@ -1511,7 +1511,7 @@ struct sas_rphy *sas_expander_alloc(struct sas_port *parent, BUG_ON(type != SAS_EDGE_EXPANDER_DEVICE && type != SAS_FANOUT_EXPANDER_DEVICE); - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) { return NULL; } @@ -1815,7 +1815,7 @@ sas_attach_transport(struct sas_function_template *ft) struct sas_internal *i; int count; - i = kzalloc(sizeof(struct sas_internal), GFP_KERNEL); + i = kzalloc_obj(struct sas_internal); if (!i) return NULL; diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 17a4a0918fc4..3e3da8c2ff26 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -1096,7 +1096,7 @@ void spi_schedule_dv_device(struct scsi_device *sdev) { struct work_queue_wrapper *wqw = - kmalloc(sizeof(struct work_queue_wrapper), GFP_ATOMIC); + kmalloc_obj(struct work_queue_wrapper, GFP_ATOMIC); if (unlikely(!wqw)) return; @@ -1570,8 +1570,7 @@ static int spi_target_configure(struct transport_container *tc, struct scsi_transport_template * spi_attach_transport(struct spi_function_template *ft) { - struct spi_internal *i = kzalloc(sizeof(struct spi_internal), - GFP_KERNEL); + struct spi_internal *i = kzalloc_obj(struct spi_internal); if (unlikely(!i)) return NULL; diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index aeb58a9e6b7f..d71ab5fdb758 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -700,7 +700,7 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, struct srp_internal *i = to_srp_internal(shost->transportt); int id, ret; - rport = kzalloc(sizeof(*rport), GFP_KERNEL); + rport = kzalloc_obj(*rport); if (!rport) return ERR_PTR(-ENOMEM); @@ -814,7 +814,7 @@ srp_attach_transport(struct srp_function_template *ft) int count; struct srp_internal *i; - i = kzalloc(sizeof(*i), GFP_KERNEL); + i = kzalloc_obj(*i); if (!i) return NULL; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index d76996d6cbc9..628a1d0a74ba 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3735,7 +3735,7 @@ static void sd_revalidate_disk(struct gendisk *disk) if (!scsi_device_online(sdp)) return; - lim = kmalloc(sizeof(*lim), GFP_KERNEL); + lim = kmalloc_obj(*lim); if (!lim) return; @@ -3974,7 +3974,7 @@ static int sd_probe(struct scsi_device *sdp) "sd_probe\n")); error = -ENOMEM; - sdkp = kzalloc(sizeof(*sdkp), GFP_KERNEL); + sdkp = kzalloc_obj(*sdkp); if (!sdkp) goto out; diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 789b170da652..8e1686358e25 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -528,9 +528,8 @@ struct efd { }; static int ses_enclosure_find_by_addr(struct enclosure_device *edev, - void *data) + struct efd *efd) { - struct efd *efd = data; int i; struct ses_component *scomp; @@ -683,7 +682,7 @@ static void ses_match_to_enclosure(struct enclosure_device *edev, if (efd.addr) { efd.dev = &sdev->sdev_gendev; - enclosure_for_each_device(ses_enclosure_find_by_addr, &efd); + ses_enclosure_find_by_addr(edev, &efd); } } @@ -715,7 +714,7 @@ static int ses_intf_add(struct device *cdev) if (sdev->type != TYPE_ENCLOSURE) sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n"); - ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL); + ses_dev = kzalloc_obj(*ses_dev); hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL); if (!hdr_buf || !ses_dev) goto err_init_free; @@ -799,7 +798,7 @@ static int ses_intf_add(struct device *cdev) } page2_not_supported: if (components > 0) { - scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); + scomp = kzalloc_objs(struct ses_component, components); if (!scomp) goto err_free; } diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 1a521f9d821a..37bac49f30f0 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1436,7 +1436,7 @@ sg_alloc(struct scsi_device *scsidp) int error; u32 k; - sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); + sdp = kzalloc_obj(Sg_device); if (!sdp) { sdev_printk(KERN_WARNING, scsidp, "%s: kmalloc Sg_device " "failure\n", __func__); @@ -2157,7 +2157,7 @@ sg_add_sfp(Sg_device * sdp) unsigned long iflags; int bufflen; - sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN); + sfp = kzalloc_obj(*sfp, GFP_ATOMIC | __GFP_NOWARN); if (!sfp) return ERR_PTR(-ENOMEM); @@ -2456,7 +2456,7 @@ struct sg_proc_deviter { static void * dev_seq_start(struct seq_file *s, loff_t *pos) { - struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); + struct sg_proc_deviter * it = kmalloc_obj(*it); s->private = it; if (! it) diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c index 70c75ab1453a..408f37003748 100644 --- a/drivers/scsi/sim710.c +++ b/drivers/scsi/sim710.c @@ -87,7 +87,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, { struct Scsi_Host * host = NULL; struct NCR_700_Host_Parameters *hostdata = - kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + kzalloc_obj(struct NCR_700_Host_Parameters); printk(KERN_NOTICE "sim710: %s\n", dev_name(dev)); printk(KERN_NOTICE "sim710: irq = %d, clock = %d, base = 0x%lx, scsi_id = %d\n", diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 6f859f0d2046..b4ed991976d0 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -888,7 +888,7 @@ static int pqi_get_advanced_raid_bypass_config(struct pqi_ctrl_info *ctrl_info) struct pqi_raid_path_request request; struct bmic_sense_feature_buffer *buffer; - buffer = kmalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kmalloc_obj(*buffer); if (!buffer) return -ENOMEM; @@ -953,7 +953,7 @@ static int pqi_flush_cache(struct pqi_ctrl_info *ctrl_info, int rc; struct bmic_flush_cache *flush_cache; - flush_cache = kzalloc(sizeof(*flush_cache), GFP_KERNEL); + flush_cache = kzalloc_obj(*flush_cache); if (!flush_cache) return -ENOMEM; @@ -982,7 +982,7 @@ static int pqi_set_diag_rescan(struct pqi_ctrl_info *ctrl_info) int rc; struct bmic_diag_options *diag; - diag = kzalloc(sizeof(*diag), GFP_KERNEL); + diag = kzalloc_obj(*diag); if (!diag) return -ENOMEM; @@ -1164,7 +1164,7 @@ static int pqi_report_phys_logical_luns(struct pqi_ctrl_info *ctrl_info, u8 cmd, void *lun_data = NULL; struct report_lun_header *report_lun_header; - report_lun_header = kmalloc(sizeof(*report_lun_header), GFP_KERNEL); + report_lun_header = kmalloc_obj(*report_lun_header); if (!report_lun_header) { rc = -ENOMEM; goto out; @@ -1252,8 +1252,8 @@ static inline int pqi_report_phys_luns(struct pqi_ctrl_info *ctrl_info, void **b rpl_8byte_wwid_list = rpl_list; num_physicals = get_unaligned_be32(&rpl_8byte_wwid_list->header.list_length) / sizeof(rpl_8byte_wwid_list->lun_entries[0]); - rpl_16byte_wwid_list = kmalloc(struct_size(rpl_16byte_wwid_list, lun_entries, - num_physicals), GFP_KERNEL); + rpl_16byte_wwid_list = kmalloc_flex(*rpl_16byte_wwid_list, lun_entries, + num_physicals); if (!rpl_16byte_wwid_list) { rc = -ENOMEM; goto out_free_rpl_list; @@ -1478,7 +1478,7 @@ static int pqi_get_raid_map(struct pqi_ctrl_info *ctrl_info, u32 raid_map_size; struct raid_map *raid_map; - raid_map = kmalloc(sizeof(*raid_map), GFP_KERNEL); + raid_map = kmalloc_obj(*raid_map); if (!raid_map) return -ENOMEM; @@ -1616,7 +1616,7 @@ static void pqi_get_volume_status(struct pqi_ctrl_info *ctrl_info, u32 volume_flags; struct ciss_vpd_logical_volume_status *vpd; - vpd = kmalloc(sizeof(*vpd), GFP_KERNEL); + vpd = kmalloc_obj(*vpd); if (!vpd) goto no_buffer; @@ -2447,7 +2447,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) * pqi_get_physical_disk_info() because it's a fairly large * buffer. */ - id_phys = kmalloc(sizeof(*id_phys), GFP_KERNEL); + id_phys = kmalloc_obj(*id_phys); if (!id_phys) { dev_warn(&ctrl_info->pci_dev->dev, "%s\n", out_of_memory_msg); @@ -2472,9 +2472,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) num_new_devices = num_physicals + num_logicals; - new_device_list = kmalloc_array(num_new_devices, - sizeof(*new_device_list), - GFP_KERNEL); + new_device_list = kmalloc_objs(*new_device_list, num_new_devices); if (!new_device_list) { dev_warn(&ctrl_info->pci_dev->dev, "%s\n", out_of_memory_msg); rc = -ENOMEM; @@ -2482,7 +2480,7 @@ static int pqi_update_scsi_devices(struct pqi_ctrl_info *ctrl_info) } for (i = 0; i < num_new_devices; i++) { - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (!device) { dev_warn(&ctrl_info->pci_dev->dev, "%s\n", out_of_memory_msg); @@ -4751,7 +4749,7 @@ static int pqi_report_device_capability(struct pqi_ctrl_info *ctrl_info) struct pqi_device_capability *capability; struct pqi_iu_layer_descriptor *sop_iu_layer_descriptor; - capability = kmalloc(sizeof(*capability), GFP_KERNEL); + capability = kmalloc_obj(*capability); if (!capability) return -ENOMEM; @@ -5207,8 +5205,8 @@ static int pqi_alloc_io_resources(struct pqi_ctrl_info *ctrl_info) struct device *dev; struct pqi_io_request *io_request; - ctrl_info->io_request_pool = kcalloc(ctrl_info->max_io_slots, - sizeof(ctrl_info->io_request_pool[0]), GFP_KERNEL); + ctrl_info->io_request_pool = kzalloc_objs(ctrl_info->io_request_pool[0], + ctrl_info->max_io_slots); if (!ctrl_info->io_request_pool) { dev_err(&ctrl_info->pci_dev->dev, @@ -7746,7 +7744,7 @@ static int pqi_get_ctrl_serial_number(struct pqi_ctrl_info *ctrl_info) int rc; struct bmic_sense_subsystem_info *sense_info; - sense_info = kzalloc(sizeof(*sense_info), GFP_KERNEL); + sense_info = kzalloc_obj(*sense_info); if (!sense_info) return -ENOMEM; @@ -7769,7 +7767,7 @@ static int pqi_get_ctrl_product_details(struct pqi_ctrl_info *ctrl_info) int rc; struct bmic_identify_controller *identify; - identify = kmalloc(sizeof(*identify), GFP_KERNEL); + identify = kmalloc_obj(*identify); if (!identify) return -ENOMEM; diff --git a/drivers/scsi/smartpqi/smartpqi_sas_transport.c b/drivers/scsi/smartpqi/smartpqi_sas_transport.c index 93e96705754e..b9c56a3816e0 100644 --- a/drivers/scsi/smartpqi/smartpqi_sas_transport.c +++ b/drivers/scsi/smartpqi/smartpqi_sas_transport.c @@ -22,7 +22,7 @@ static struct pqi_sas_phy *pqi_alloc_sas_phy(struct pqi_sas_port *pqi_sas_port) struct pqi_sas_phy *pqi_sas_phy; struct sas_phy *phy; - pqi_sas_phy = kzalloc(sizeof(*pqi_sas_phy), GFP_KERNEL); + pqi_sas_phy = kzalloc_obj(*pqi_sas_phy); if (!pqi_sas_phy) return NULL; @@ -131,7 +131,7 @@ static struct pqi_sas_port *pqi_alloc_sas_port( struct pqi_sas_port *pqi_sas_port; struct sas_port *port; - pqi_sas_port = kzalloc(sizeof(*pqi_sas_port), GFP_KERNEL); + pqi_sas_port = kzalloc_obj(*pqi_sas_port); if (!pqi_sas_port) return NULL; @@ -180,7 +180,7 @@ static struct pqi_sas_node *pqi_alloc_sas_node(struct device *parent_dev) { struct pqi_sas_node *pqi_sas_node; - pqi_sas_node = kzalloc(sizeof(*pqi_sas_node), GFP_KERNEL); + pqi_sas_node = kzalloc_obj(*pqi_sas_node); if (pqi_sas_node) { pqi_sas_node->parent_dev = parent_dev; INIT_LIST_HEAD(&pqi_sas_node->port_list_head); @@ -463,7 +463,7 @@ pqi_build_csmi_smp_passthru_buffer(struct sas_rphy *rphy, u32 req_size; u32 resp_size; - smp_buf = kzalloc(sizeof(*smp_buf), GFP_KERNEL); + smp_buf = kzalloc_obj(*smp_buf); if (!smp_buf) return NULL; diff --git a/drivers/scsi/sni_53c710.c b/drivers/scsi/sni_53c710.c index d1d2556c8fc4..b504a2cc5041 100644 --- a/drivers/scsi/sni_53c710.c +++ b/drivers/scsi/sni_53c710.c @@ -64,7 +64,7 @@ static int snirm710_probe(struct platform_device *dev) return -ENODEV; base = res->start; - hostdata = kzalloc(sizeof(*hostdata), GFP_KERNEL); + hostdata = kzalloc_obj(*hostdata); if (!hostdata) return -ENOMEM; diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c index 4db3ba62fcd3..71d34a702f2a 100644 --- a/drivers/scsi/snic/snic_disc.c +++ b/drivers/scsi/snic/snic_disc.c @@ -244,7 +244,7 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) return tgt; } - tgt = kzalloc(sizeof(*tgt), GFP_KERNEL); + tgt = kzalloc_obj(*tgt); if (!tgt) { SNIC_HOST_ERR(snic->shost, "Failure to allocate snic_tgt.\n"); ret = -ENOMEM; diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c index 1c24517e4e65..82953e6a0915 100644 --- a/drivers/scsi/snic/snic_main.c +++ b/drivers/scsi/snic/snic_main.c @@ -818,7 +818,7 @@ snic_global_data_init(void) struct kmem_cache *cachep; ssize_t len = 0; - snic_glob = kzalloc(sizeof(*snic_glob), GFP_KERNEL); + snic_glob = kzalloc_obj(*snic_glob); if (!snic_glob) { SNIC_ERR("Failed to allocate Global Context.\n"); diff --git a/drivers/scsi/snic/vnic_dev.c b/drivers/scsi/snic/vnic_dev.c index 760f3f22095c..ed7771e62854 100644 --- a/drivers/scsi/snic/vnic_dev.c +++ b/drivers/scsi/snic/vnic_dev.c @@ -42,8 +42,6 @@ struct vnic_dev { struct vnic_devcmd_notify *notify; struct vnic_devcmd_notify notify_copy; dma_addr_t notify_pa; - u32 *linkstatus; - dma_addr_t linkstatus_pa; struct vnic_stats *stats; dma_addr_t stats_pa; struct vnic_devcmd_fw_info *fw_info; @@ -352,7 +350,7 @@ static int svnic_dev_init_devcmd2(struct vnic_dev *vdev) if (!p) return -ENODEV; - dc2c = kzalloc(sizeof(*dc2c), GFP_ATOMIC); + dc2c = kzalloc_obj(*dc2c, GFP_ATOMIC); if (!dc2c) return -ENOMEM; @@ -650,8 +648,6 @@ int svnic_dev_init(struct vnic_dev *vdev, int arg) int svnic_dev_link_status(struct vnic_dev *vdev) { - if (vdev->linkstatus) - return *vdev->linkstatus; if (!vnic_dev_notify_ready(vdev)) return 0; @@ -686,11 +682,6 @@ void svnic_dev_unregister(struct vnic_dev *vdev) sizeof(struct vnic_devcmd_notify), vdev->notify, vdev->notify_pa); - if (vdev->linkstatus) - dma_free_coherent(&vdev->pdev->dev, - sizeof(u32), - vdev->linkstatus, - vdev->linkstatus_pa); if (vdev->stats) dma_free_coherent(&vdev->pdev->dev, sizeof(struct vnic_stats), @@ -712,7 +703,7 @@ struct vnic_dev *svnic_dev_alloc_discover(struct vnic_dev *vdev, unsigned int num_bars) { if (!vdev) { - vdev = kzalloc(sizeof(struct vnic_dev), GFP_ATOMIC); + vdev = kzalloc_obj(struct vnic_dev, GFP_ATOMIC); if (!vdev) return NULL; } diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 1fb85f548955..7adb2573f50d 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -629,7 +629,7 @@ static int sr_probe(struct scsi_device *sdev) goto fail; error = -ENOMEM; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) goto fail; diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index 413e844fa276..f1c3c4946637 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -462,7 +462,7 @@ static struct st_request *st_allocate_request(struct scsi_tape *stp) { struct st_request *streq; - streq = kzalloc(sizeof(*streq), GFP_KERNEL); + streq = kzalloc_obj(*streq); if (streq) streq->stp = stp; else { @@ -3973,7 +3973,7 @@ static struct st_buffer *new_tape_buffer(int max_sg) { struct st_buffer *tb; - tb = kzalloc(sizeof(struct st_buffer), GFP_KERNEL); + tb = kzalloc_obj(struct st_buffer); if (!tb) { printk(KERN_NOTICE "st: Can't allocate new tape buffer.\n"); return NULL; @@ -3982,8 +3982,7 @@ static struct st_buffer *new_tape_buffer(int max_sg) tb->use_sg = max_sg; tb->buffer_size = 0; - tb->reserved_pages = kcalloc(max_sg, sizeof(struct page *), - GFP_KERNEL); + tb->reserved_pages = kzalloc_objs(struct page *, max_sg); if (!tb->reserved_pages) { kfree(tb); return NULL; @@ -4374,7 +4373,7 @@ static int st_probe(struct scsi_device *SDp) goto out; } - tpnt = kzalloc(sizeof(struct scsi_tape), GFP_KERNEL); + tpnt = kzalloc_obj(struct scsi_tape); if (tpnt == NULL) { sdev_printk(KERN_ERR, SDp, "st: Can't allocate device descriptor.\n"); @@ -4457,7 +4456,7 @@ static int st_probe(struct scsi_device *SDp) } tpnt->index = error; sprintf(tpnt->name, "st%d", tpnt->index); - tpnt->stats = kzalloc(sizeof(struct scsi_tape_stats), GFP_KERNEL); + tpnt->stats = kzalloc_obj(struct scsi_tape_stats); if (tpnt->stats == NULL) { sdev_printk(KERN_ERR, SDp, "st: Can't allocate statistics.\n"); @@ -5007,7 +5006,7 @@ static int sgl_map_user_pages(struct st_buffer *STbp, if (count == 0) return 0; - pages = kmalloc_array(max_pages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, max_pages); if (pages == NULL) return -ENOMEM; diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 5a3f6fe22ae9..6aeeb338633d 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -1757,7 +1757,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) } } - hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL); + hba->ccb = kzalloc_objs(struct st_ccb, ci->rq_count); if (!hba->ccb) { err = -ENOMEM; printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n", diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index b3f83c0dcced..ae1abab97835 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1063,7 +1063,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, /* * We need to schedule work to process this error; schedule it. */ - wrk = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); + wrk = kmalloc_obj(struct storvsc_scan_work, GFP_ATOMIC); if (!wrk) { set_host_byte(scmnd, DID_BAD_TARGET); return; @@ -1856,8 +1856,9 @@ static enum scsi_qc_status storvsc_queuecommand(struct Scsi_Host *host, cmd_request->payload_sz = payload_sz; /* Invokes the vsc to start an IO */ - ret = storvsc_do_io(dev, cmd_request, get_cpu()); - put_cpu(); + migrate_disable(); + ret = storvsc_do_io(dev, cmd_request, smp_processor_id()); + migrate_enable(); if (ret) scsi_dma_unmap(scmnd); @@ -1970,7 +1971,7 @@ static int storvsc_probe(struct hv_device *device, host_dev->host = host; - stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); + stor_device = kzalloc_obj(struct storvsc_device); if (!stor_device) { ret = -ENOMEM; goto err_out0; diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c index f0db17e34ea0..c554e4158094 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.c +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c @@ -4990,8 +4990,8 @@ struct sym_lcb *sym_alloc_lcb (struct sym_hcb *np, u_char tn, u_char ln) * Allocate the table of pointers for LUN(s) > 0, if needed. */ if (ln && !tp->lunmp) { - tp->lunmp = kcalloc(SYM_CONF_MAX_LUN, sizeof(struct sym_lcb *), - GFP_ATOMIC); + tp->lunmp = kzalloc_objs(struct sym_lcb *, SYM_CONF_MAX_LUN, + GFP_ATOMIC); if (!tp->lunmp) goto fail; } @@ -5655,7 +5655,7 @@ int sym_hcb_attach(struct Scsi_Host *shost, struct sym_fw *fw, struct sym_nvram /* * Allocate the array of lists of CCBs hashed by DSA. */ - np->ccbh = kcalloc(CCB_HASH_SIZE, sizeof(*np->ccbh), GFP_KERNEL); + np->ccbh = kzalloc_objs(*np->ccbh, CCB_HASH_SIZE); if (!np->ccbh) goto attach_failed; diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c index 89322717b181..0ed8558dad72 100644 --- a/drivers/scsi/virtio_scsi.c +++ b/drivers/scsi/virtio_scsi.c @@ -853,8 +853,8 @@ static int virtscsi_init(struct virtio_device *vdev, num_req_vqs = vscsi->num_queues; num_vqs = num_req_vqs + VIRTIO_SCSI_VQ_BASE; - vqs = kmalloc_array(num_vqs, sizeof(struct virtqueue *), GFP_KERNEL); - vqs_info = kcalloc(num_vqs, sizeof(*vqs_info), GFP_KERNEL); + vqs = kmalloc_objs(struct virtqueue *, num_vqs); + vqs_info = kzalloc_objs(*vqs_info, num_vqs); if (!vqs || !vqs_info) { err = -ENOMEM; diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c index 11f86c76f391..151cac9f9c2a 100644 --- a/drivers/scsi/vmw_pvscsi.c +++ b/drivers/scsi/vmw_pvscsi.c @@ -1478,8 +1478,7 @@ static int pvscsi_probe(struct pci_dev *pdev, const struct pci_device_id *id) */ pvscsi_setup_all_rings(adapter); - adapter->cmd_map = kcalloc(adapter->req_depth, - sizeof(struct pvscsi_ctx), GFP_KERNEL); + adapter->cmd_map = kzalloc_objs(struct pvscsi_ctx, adapter->req_depth); if (!adapter->cmd_map) { printk(KERN_ERR "vmw_pvscsi: failed to allocate memory.\n"); error = -ENOMEM; diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index bf36c07c2b47..989bcaee42ca 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -494,8 +494,8 @@ static int map_data_for_request(struct vscsifrnt_info *info, return -E2BIG; } seg_grants = vscsiif_grants_sg(data_grants); - shadow->sg = kcalloc(data_grants, - sizeof(struct scsiif_request_segment), GFP_ATOMIC); + shadow->sg = kzalloc_objs(struct scsiif_request_segment, + data_grants, GFP_ATOMIC); if (!shadow->sg) return -ENOMEM; } @@ -669,7 +669,7 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act) if (info->host_active == STATE_ERROR) return FAILED; - shadow = kzalloc(sizeof(*shadow), GFP_NOIO); + shadow = kzalloc_obj(*shadow, GFP_NOIO); if (!shadow) return FAILED; @@ -1175,7 +1175,7 @@ static void scsifront_backend_changed(struct xenbus_device *dev, return; } - if (xenbus_read_driver_state(dev->nodename) == + if (xenbus_read_driver_state(dev, dev->nodename) == XenbusStateInitialised) scsifront_do_lun_hotplug(info, VSCSIFRONT_OP_ADD_LUN); diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index 7acf9193a9e8..6aca9897b231 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c @@ -95,7 +95,7 @@ static int zorro7xx_init_one(struct zorro_dev *z, return -EBUSY; } - hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); + hostdata = kzalloc_obj(struct NCR_700_Host_Parameters); if (!hostdata) { printk(KERN_ERR "zorro7xx: Failed to allocate host data\n"); goto out_release; diff --git a/drivers/scsi/zorro_esp.c b/drivers/scsi/zorro_esp.c index 56cae22a4242..1622285c9aec 100644 --- a/drivers/scsi/zorro_esp.c +++ b/drivers/scsi/zorro_esp.c @@ -726,7 +726,7 @@ static int zorro_esp_probe(struct zorro_dev *z, pr_info("%s found at address 0x%lx.\n", zdd->name, board); - zep = kzalloc(sizeof(*zep), GFP_KERNEL); + zep = kzalloc_obj(*zep); if (!zep) { pr_err("Can't allocate device private data!\n"); return -ENOMEM; diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c index 64ed7d64458a..f93b8d9d9ca8 100644 --- a/drivers/sh/clk/cpg.c +++ b/drivers/sh/clk/cpg.c @@ -459,7 +459,7 @@ int __init sh_clk_fsidiv_register(struct clk *clks, int nr) for (i = 0; i < nr; i++) { - map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL); + map = kzalloc_obj(struct clk_mapping); if (!map) { pr_err("%s: unable to alloc memory\n", __func__); return -ENOMEM; diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 3dde703b7766..aa68fe190865 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -204,7 +204,7 @@ int __init register_intc_controller(struct intc_desc *desc) pr_info("Registered controller '%s' with %u IRQs\n", desc->name, hw->nr_vectors); - d = kzalloc(sizeof(*d), GFP_NOWAIT); + d = kzalloc_obj(*d, GFP_NOWAIT); if (!d) goto err0; @@ -217,8 +217,7 @@ int __init register_intc_controller(struct intc_desc *desc) if (desc->num_resources) { d->nr_windows = desc->num_resources; - d->window = kcalloc(d->nr_windows, sizeof(*d->window), - GFP_NOWAIT); + d->window = kzalloc_objs(*d->window, d->nr_windows, GFP_NOWAIT); if (!d->window) goto err1; @@ -267,8 +266,7 @@ int __init register_intc_controller(struct intc_desc *desc) } if (hw->prio_regs) { - d->prio = kcalloc(hw->nr_vectors, sizeof(*d->prio), - GFP_NOWAIT); + d->prio = kzalloc_objs(*d->prio, hw->nr_vectors, GFP_NOWAIT); if (!d->prio) goto err4; @@ -283,8 +281,7 @@ int __init register_intc_controller(struct intc_desc *desc) } if (hw->sense_regs) { - d->sense = kcalloc(hw->nr_vectors, sizeof(*d->sense), - GFP_NOWAIT); + d->sense = kzalloc_objs(*d->sense, hw->nr_vectors, GFP_NOWAIT); if (!d->sense) goto err5; diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index a638c3048207..291798526519 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -93,7 +93,7 @@ static int add_virq_to_pirq(unsigned int irq, unsigned int virq) last = &entry->next; } - entry = kzalloc(sizeof(struct intc_virq_list), GFP_ATOMIC); + entry = kzalloc_obj(struct intc_virq_list, GFP_ATOMIC); if (!entry) return -ENOMEM; @@ -168,7 +168,7 @@ static void __init intc_subgroup_init_one(struct intc_desc *desc, if (!subgroup->enum_ids[i]) continue; - entry = kmalloc(sizeof(*entry), GFP_NOWAIT); + entry = kmalloc_obj(*entry, GFP_NOWAIT); if (!entry) break; diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c index 6dc0549f7900..5585f220e495 100644 --- a/drivers/sh/maple/maple.c +++ b/drivers/sh/maple/maple.c @@ -187,7 +187,7 @@ static struct mapleq *maple_allocq(struct maple_device *mdev) { struct mapleq *mq; - mq = kzalloc(sizeof(*mq), GFP_KERNEL); + mq = kzalloc_obj(*mq); if (!mq) goto failed_nomem; @@ -215,7 +215,7 @@ static struct maple_device *maple_alloc_dev(int port, int unit) /* zero this out to avoid kobj subsystem * thinking it has already been registered */ - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return NULL; diff --git a/drivers/siox/siox-core.c b/drivers/siox/siox-core.c index f98f5a27e659..3e8f3b6a4555 100644 --- a/drivers/siox/siox-core.c +++ b/drivers/siox/siox-core.c @@ -822,7 +822,7 @@ static struct siox_device *siox_device_add(struct siox_master *smaster, int ret; size_t buf_len; - sdevice = kzalloc(sizeof(*sdevice), GFP_KERNEL); + sdevice = kzalloc_obj(*sdevice); if (!sdevice) return ERR_PTR(-ENOMEM); diff --git a/drivers/slimbus/core.c b/drivers/slimbus/core.c index 5079d3271ee8..ee6318e247d3 100644 --- a/drivers/slimbus/core.c +++ b/drivers/slimbus/core.c @@ -180,7 +180,7 @@ static struct slim_device *slim_alloc_device(struct slim_controller *ctrl, struct slim_device *sbdev; int ret; - sbdev = kzalloc(sizeof(*sbdev), GFP_KERNEL); + sbdev = kzalloc_obj(*sbdev); if (!sbdev) return NULL; diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c index ba3d80d12605..9aa7218b4e8d 100644 --- a/drivers/slimbus/qcom-ngd-ctrl.c +++ b/drivers/slimbus/qcom-ngd-ctrl.c @@ -1514,26 +1514,22 @@ static int of_qcom_slim_ngd_register(struct device *parent, const struct ngd_reg_offset_data *data; struct qcom_slim_ngd *ngd; const struct of_device_id *match; - struct device_node *node; u32 id; int ret; match = of_match_node(qcom_slim_ngd_dt_match, parent->of_node); data = match->data; - for_each_available_child_of_node(parent->of_node, node) { + for_each_available_child_of_node_scoped(parent->of_node, node) { if (of_property_read_u32(node, "reg", &id)) continue; - ngd = kzalloc(sizeof(*ngd), GFP_KERNEL); - if (!ngd) { - of_node_put(node); + ngd = kzalloc_obj(*ngd); + if (!ngd) return -ENOMEM; - } ngd->pdev = platform_device_alloc(QCOM_SLIM_NGD_DRV_NAME, id); if (!ngd->pdev) { kfree(ngd); - of_node_put(node); return -ENOMEM; } ngd->id = id; @@ -1546,7 +1542,6 @@ static int of_qcom_slim_ngd_register(struct device *parent, if (ret) { platform_device_put(ngd->pdev); kfree(ngd); - of_node_put(node); return ret; } ngd->pdev->dev.of_node = node; @@ -1556,7 +1551,6 @@ static int of_qcom_slim_ngd_register(struct device *parent, if (ret) { platform_device_put(ngd->pdev); kfree(ngd); - of_node_put(node); return ret; } ngd->base = ctrl->base + ngd->id * data->offset + diff --git a/drivers/slimbus/stream.c b/drivers/slimbus/stream.c index 863ab3075d7e..b4e70a7edd1c 100644 --- a/drivers/slimbus/stream.c +++ b/drivers/slimbus/stream.c @@ -103,7 +103,7 @@ struct slim_stream_runtime *slim_stream_allocate(struct slim_device *dev, { struct slim_stream_runtime *rt; - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) return ERR_PTR(-ENOMEM); @@ -214,7 +214,7 @@ int slim_stream_prepare(struct slim_stream_runtime *rt, } num_ports = hweight32(cfg->port_mask); - rt->ports = kcalloc(num_ports, sizeof(*port), GFP_KERNEL); + rt->ports = kzalloc_objs(*port, num_ports); if (!rt->ports) return -ENOMEM; diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c index dcb75baaff24..c20f685e56f9 100644 --- a/drivers/soc/amlogic/meson-gx-socinfo.c +++ b/drivers/soc/amlogic/meson-gx-socinfo.c @@ -188,7 +188,7 @@ static int __init meson_gx_socinfo_init(void) return -EINVAL; } - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENODEV; diff --git a/drivers/soc/amlogic/meson-mx-socinfo.c b/drivers/soc/amlogic/meson-mx-socinfo.c index 92125dd65f33..e1a7795a2733 100644 --- a/drivers/soc/amlogic/meson-mx-socinfo.c +++ b/drivers/soc/amlogic/meson-mx-socinfo.c @@ -146,7 +146,7 @@ static int __init meson_mx_socinfo_init(void) if (ret < 0) return ret; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENODEV; diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig index ad6736889231..d0ff32182a2b 100644 --- a/drivers/soc/apple/Kconfig +++ b/drivers/soc/apple/Kconfig @@ -38,6 +38,10 @@ config APPLE_SART Say 'y' here if you have an Apple SoC. +config APPLE_TUNABLE + tristate + depends on ARCH_APPLE || COMPILE_TEST + endmenu endif diff --git a/drivers/soc/apple/Makefile b/drivers/soc/apple/Makefile index 4d9ab8f3037b..0b85ab61aefe 100644 --- a/drivers/soc/apple/Makefile +++ b/drivers/soc/apple/Makefile @@ -8,3 +8,6 @@ apple-rtkit-y = rtkit.o rtkit-crashlog.o obj-$(CONFIG_APPLE_SART) += apple-sart.o apple-sart-y = sart.o + +obj-$(CONFIG_APPLE_TUNABLE) += apple-tunable.o +apple-tunable-y = tunable.o diff --git a/drivers/soc/apple/rtkit.c b/drivers/soc/apple/rtkit.c index 4ad4f964fde7..a3fdac8f6f06 100644 --- a/drivers/soc/apple/rtkit.c +++ b/drivers/soc/apple/rtkit.c @@ -590,7 +590,7 @@ static void apple_rtkit_rx(struct apple_mbox *mbox, struct apple_mbox_msg msg, rtk->ops->recv_message_early(rtk->cookie, ep, msg.msg0)) return; - work = kzalloc(sizeof(*work), GFP_ATOMIC); + work = kzalloc_obj(*work, GFP_ATOMIC); if (!work) return; @@ -667,7 +667,7 @@ struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie, if (!ops) return ERR_PTR(-EINVAL); - rtk = kzalloc(sizeof(*rtk), GFP_KERNEL); + rtk = kzalloc_obj(*rtk); if (!rtk) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/apple/tunable.c b/drivers/soc/apple/tunable.c new file mode 100644 index 000000000000..659323839171 --- /dev/null +++ b/drivers/soc/apple/tunable.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Apple Silicon hardware tunable support + * + * Each tunable is a list with each entry containing a offset into the MMIO + * region, a mask of bits to be cleared and a set of bits to be set. These + * tunables are passed along by the previous boot stages and vary from device + * to device such that they cannot be hardcoded in the individual drivers. + * + * Copyright (C) The Asahi Linux Contributors + */ + +#include +#include +#include +#include +#include + +struct apple_tunable *devm_apple_tunable_parse(struct device *dev, + struct device_node *np, + const char *name, + struct resource *res) +{ + struct apple_tunable *tunable; + struct property *prop; + const __be32 *p; + size_t sz; + int i; + + if (resource_size(res) < 4) + return ERR_PTR(-EINVAL); + + prop = of_find_property(np, name, NULL); + if (!prop) + return ERR_PTR(-ENOENT); + + if (prop->length % (3 * sizeof(u32))) + return ERR_PTR(-EINVAL); + sz = prop->length / (3 * sizeof(u32)); + + tunable = devm_kzalloc(dev, struct_size(tunable, values, sz), GFP_KERNEL); + if (!tunable) + return ERR_PTR(-ENOMEM); + tunable->sz = sz; + + for (i = 0, p = NULL; i < tunable->sz; ++i) { + p = of_prop_next_u32(prop, p, &tunable->values[i].offset); + p = of_prop_next_u32(prop, p, &tunable->values[i].mask); + p = of_prop_next_u32(prop, p, &tunable->values[i].value); + + /* Sanity checks to catch bugs in our bootloader */ + if (tunable->values[i].offset % 4) + return ERR_PTR(-EINVAL); + if (tunable->values[i].offset > (resource_size(res) - 4)) + return ERR_PTR(-EINVAL); + } + + return tunable; +} +EXPORT_SYMBOL(devm_apple_tunable_parse); + +void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable) +{ + size_t i; + + for (i = 0; i < tunable->sz; ++i) { + u32 val, old_val; + + old_val = readl(regs + tunable->values[i].offset); + val = old_val & ~tunable->values[i].mask; + val |= tunable->values[i].value; + if (val != old_val) + writel(val, regs + tunable->values[i].offset); + } +} +EXPORT_SYMBOL(apple_tunable_apply); + +MODULE_LICENSE("Dual MIT/GPL"); +MODULE_AUTHOR("Sven Peter "); +MODULE_DESCRIPTION("Apple Silicon hardware tunable support"); diff --git a/drivers/soc/aspeed/aspeed-p2a-ctrl.c b/drivers/soc/aspeed/aspeed-p2a-ctrl.c index 3be2e1b1085b..d88abc5f195b 100644 --- a/drivers/soc/aspeed/aspeed-p2a-ctrl.c +++ b/drivers/soc/aspeed/aspeed-p2a-ctrl.c @@ -238,7 +238,7 @@ static int aspeed_p2a_open(struct inode *inode, struct file *file) { struct aspeed_p2a_user *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/soc/aspeed/aspeed-socinfo.c b/drivers/soc/aspeed/aspeed-socinfo.c index 67e9ac3d08ec..5e34e01ad26d 100644 --- a/drivers/soc/aspeed/aspeed-socinfo.c +++ b/drivers/soc/aspeed/aspeed-socinfo.c @@ -113,7 +113,7 @@ static int __init aspeed_socinfo_init(void) } of_node_put(np); - attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_obj(*attrs); if (!attrs) return -ENODEV; diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 09347bccdb1d..d89f9dcade7d 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -368,7 +368,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) return NULL; } - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return NULL; diff --git a/drivers/soc/bcm/brcmstb/common.c b/drivers/soc/bcm/brcmstb/common.c index 2a010881f4b6..2da79bd42930 100644 --- a/drivers/soc/bcm/brcmstb/common.c +++ b/drivers/soc/bcm/brcmstb/common.c @@ -82,7 +82,7 @@ static int __init brcmstb_soc_device_init(void) if (!sun_top_ctrl) return ret; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) { ret = -ENOMEM; goto out; diff --git a/drivers/soc/cirrus/soc-ep93xx.c b/drivers/soc/cirrus/soc-ep93xx.c index 3e79b3b13aef..d55cf28ed726 100644 --- a/drivers/soc/cirrus/soc-ep93xx.c +++ b/drivers/soc/cirrus/soc-ep93xx.c @@ -92,7 +92,7 @@ static struct auxiliary_device __init *ep93xx_adev_alloc(struct device *parent, struct auxiliary_device *adev; int ret; - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (!rdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/dove/pmu.c b/drivers/soc/dove/pmu.c index dd8ade8e9ee8..611caaeed8fc 100644 --- a/drivers/soc/dove/pmu.c +++ b/drivers/soc/dove/pmu.c @@ -311,7 +311,7 @@ int __init dove_init_pmu_legacy(const struct dove_pmu_initdata *initdata) struct pmu_data *pmu; int ret; - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + pmu = kzalloc_obj(*pmu); if (!pmu) return -ENOMEM; @@ -324,7 +324,7 @@ int __init dove_init_pmu_legacy(const struct dove_pmu_initdata *initdata) domain_initdata++) { struct pmu_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (domain) { domain->pmu = pmu; domain->pwr_mask = domain_initdata->pwr_mask; @@ -386,7 +386,7 @@ int __init dove_init_pmu(void) return 0; } - pmu = kzalloc(sizeof(*pmu), GFP_KERNEL); + pmu = kzalloc_obj(*pmu); if (!pmu) return -ENOMEM; @@ -408,7 +408,7 @@ int __init dove_init_pmu(void) struct of_phandle_args args; struct pmu_domain *domain; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) break; diff --git a/drivers/soc/fsl/dpaa2-console.c b/drivers/soc/fsl/dpaa2-console.c index 6310f54e68a2..7f2ffe38dc07 100644 --- a/drivers/soc/fsl/dpaa2-console.c +++ b/drivers/soc/fsl/dpaa2-console.c @@ -111,7 +111,7 @@ static int dpaa2_generic_console_open(struct inode *node, struct file *fp, u64 base_addr; int err; - cd = kmalloc(sizeof(*cd), GFP_KERNEL); + cd = kmalloc_obj(*cd); if (!cd) return -ENOMEM; diff --git a/drivers/soc/fsl/dpio/dpio-service.c b/drivers/soc/fsl/dpio/dpio-service.c index 0b60ed16297c..317ca50b0c2b 100644 --- a/drivers/soc/fsl/dpio/dpio-service.c +++ b/drivers/soc/fsl/dpio/dpio-service.c @@ -133,7 +133,7 @@ static void dpaa2_io_dim_work(struct work_struct *w) struct dpaa2_io *dpaa2_io_create(const struct dpaa2_io_desc *desc, struct device *dev) { - struct dpaa2_io *obj = kmalloc(sizeof(*obj), GFP_KERNEL); + struct dpaa2_io *obj = kmalloc_obj(*obj); u32 qman_256_cycles_per_ns; if (!obj) @@ -523,7 +523,7 @@ int dpaa2_io_service_enqueue_multiple_desc_fq(struct dpaa2_io *d, struct qbman_eq_desc *ed; int i, ret; - ed = kcalloc(32, sizeof(struct qbman_eq_desc), GFP_KERNEL); + ed = kzalloc_objs(struct qbman_eq_desc, 32); if (!ed) return -ENOMEM; @@ -658,7 +658,7 @@ struct dpaa2_io_store *dpaa2_io_store_create(unsigned int max_frames, if (!max_frames || (max_frames > 32)) return NULL; - ret = kmalloc(sizeof(*ret), GFP_KERNEL); + ret = kmalloc_obj(*ret); if (!ret) return NULL; diff --git a/drivers/soc/fsl/dpio/qbman-portal.c b/drivers/soc/fsl/dpio/qbman-portal.c index 0a3fb6c115f4..278e25d09be2 100644 --- a/drivers/soc/fsl/dpio/qbman-portal.c +++ b/drivers/soc/fsl/dpio/qbman-portal.c @@ -246,7 +246,7 @@ static inline u8 qm_cyc_diff(u8 ringsize, u8 first, u8 last) */ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d) { - struct qbman_swp *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct qbman_swp *p = kzalloc_obj(*p); u32 reg; u32 mask_size; u32 eqcr_pi; diff --git a/drivers/soc/fsl/guts.c b/drivers/soc/fsl/guts.c index 6bf3e6a980ff..40afb27b582b 100644 --- a/drivers/soc/fsl/guts.c +++ b/drivers/soc/fsl/guts.c @@ -213,7 +213,7 @@ static int __init fsl_guts_init(void) of_node_put(np); /* Register soc device */ - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/soc/fsl/qbman/bman.c b/drivers/soc/fsl/qbman/bman.c index 6cc1847e534a..f22eff294122 100644 --- a/drivers/soc/fsl/qbman/bman.c +++ b/drivers/soc/fsl/qbman/bman.c @@ -700,7 +700,7 @@ struct bman_pool *bman_new_pool(void) if (bm_alloc_bpid_range(&bpid, 1)) return NULL; - pool = kmalloc(sizeof(*pool), GFP_KERNEL); + pool = kmalloc_obj(*pool); if (!pool) goto err; diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 6b392b3ad4b1..411381f1a1c4 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1270,7 +1270,7 @@ static int qman_create_portal(struct qman_portal *portal, qm_dqrr_set_ithresh(p, QMAN_PIRQ_DQRR_ITHRESH); qm_mr_set_ithresh(p, QMAN_PIRQ_MR_ITHRESH); qm_out(p, QM_REG_ITPR, QMAN_PIRQ_IPERIOD); - portal->cgrs = kmalloc_array(2, sizeof(*portal->cgrs), GFP_KERNEL); + portal->cgrs = kmalloc_objs(*portal->cgrs, 2); if (!portal->cgrs) goto fail_cgrs; /* initial snapshot is no-depletion */ diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index c54154b404df..66828f2a3577 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c @@ -161,7 +161,7 @@ struct qe_pin *qe_pin_request(struct device *dev, int index) int gpio_num; int err; - qe_pin = kzalloc(sizeof(*qe_pin), GFP_KERNEL); + qe_pin = kzalloc_obj(*qe_pin); if (!qe_pin) { dev_dbg(dev, "%s: can't allocate memory\n", __func__); return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c index 02c29f5f86d3..c77a068f64ff 100644 --- a/drivers/soc/fsl/qe/qe_common.c +++ b/drivers/soc/fsl/qe/qe_common.c @@ -118,7 +118,7 @@ static s32 cpm_muram_alloc_common(unsigned long size, struct muram_block *entry; s32 start; - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; start = gen_pool_alloc_algo(muram_pool, size, algo, data); diff --git a/drivers/soc/fsl/qe/ucc_fast.c b/drivers/soc/fsl/qe/ucc_fast.c index 53d8aafc9317..fa474dfcca13 100644 --- a/drivers/soc/fsl/qe/ucc_fast.c +++ b/drivers/soc/fsl/qe/ucc_fast.c @@ -191,7 +191,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc return -EINVAL; } - uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); + uccf = kzalloc_obj(struct ucc_fast_private); if (!uccf) { printk(KERN_ERR "%s: Cannot allocate private data\n", __func__); diff --git a/drivers/soc/fsl/qe/ucc_slow.c b/drivers/soc/fsl/qe/ucc_slow.c index d5ac1ac0ed3c..7c5dc7de54d5 100644 --- a/drivers/soc/fsl/qe/ucc_slow.c +++ b/drivers/soc/fsl/qe/ucc_slow.c @@ -148,7 +148,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc return -EINVAL; } - uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); + uccs = kzalloc_obj(struct ucc_slow_private); if (!uccs) { printk(KERN_ERR "%s: Cannot allocate private data\n", __func__); diff --git a/drivers/soc/hisilicon/kunpeng_hccs.c b/drivers/soc/hisilicon/kunpeng_hccs.c index 006fec47ea10..2af3bfda313e 100644 --- a/drivers/soc/hisilicon/kunpeng_hccs.c +++ b/drivers/soc/hisilicon/kunpeng_hccs.c @@ -616,8 +616,7 @@ static int hccs_get_all_port_info_on_die(struct hccs_dev *hdev, int ret; u8 i; - attrs = kcalloc(die->port_num, sizeof(struct hccs_port_attr), - GFP_KERNEL); + attrs = kzalloc_objs(struct hccs_port_attr, die->port_num); if (!attrs) return -ENOMEM; diff --git a/drivers/soc/imx/soc-imx.c b/drivers/soc/imx/soc-imx.c index fab668c83f98..504ebce18793 100644 --- a/drivers/soc/imx/soc-imx.c +++ b/drivers/soc/imx/soc-imx.c @@ -40,7 +40,7 @@ static int __init imx_soc_device_init(void) if (!__mxc_cpu_type) return 0; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/soc/mediatek/mtk-cmdq-helper.c b/drivers/soc/mediatek/mtk-cmdq-helper.c index 67e5879374ac..f8ee6c9ade89 100644 --- a/drivers/soc/mediatek/mtk-cmdq-helper.c +++ b/drivers/soc/mediatek/mtk-cmdq-helper.c @@ -114,7 +114,7 @@ struct cmdq_client *cmdq_mbox_create(struct device *dev, int index) { struct cmdq_client *client; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return (struct cmdq_client *)-ENOMEM; diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c index 30bc45d17d34..8e7ae3cb92ff 100644 --- a/drivers/soc/microchip/mpfs-sys-controller.c +++ b/drivers/soc/microchip/mpfs-sys-controller.c @@ -132,7 +132,7 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) struct device_node *np; int i, ret; - sys_controller = kzalloc(sizeof(*sys_controller), GFP_KERNEL); + sys_controller = kzalloc_obj(*sys_controller); if (!sys_controller) return -ENOMEM; diff --git a/drivers/soc/nuvoton/wpcm450-soc.c b/drivers/soc/nuvoton/wpcm450-soc.c index c5e0d11c383b..5511bd284773 100644 --- a/drivers/soc/nuvoton/wpcm450-soc.c +++ b/drivers/soc/nuvoton/wpcm450-soc.c @@ -74,7 +74,7 @@ static int __init wpcm450_soc_init(void) return -ENODEV; } - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return -ENOMEM; diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index a956c407ce03..78e72379a6e0 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -95,7 +95,7 @@ gpr_port_t *gpr_alloc_port(struct apr_device *gdev, struct device *dev, struct pkt_router_svc *svc; int id; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); @@ -171,7 +171,7 @@ static int apr_callback(struct rpmsg_device *rpdev, void *buf, return -EINVAL; } - abuf = kzalloc(struct_size(abuf, buf, len), GFP_ATOMIC); + abuf = kzalloc_flex(*abuf, buf, len, GFP_ATOMIC); if (!abuf) return -ENOMEM; @@ -416,7 +416,7 @@ static int apr_add_device(struct device *dev, struct device_node *np, struct pkt_router_svc *svc; int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return -ENOMEM; diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 1abfda7a58f2..ad5899d083f3 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -4447,7 +4447,7 @@ struct llcc_slice_desc *llcc_slice_getd(u32 uid) if (count == sz || !cfg) return ERR_PTR(-ENODEV); - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c index 71130a2f62e9..6a23f18b0281 100644 --- a/drivers/soc/qcom/ocmem.c +++ b/drivers/soc/qcom/ocmem.c @@ -226,7 +226,7 @@ struct ocmem_buf *ocmem_allocate(struct ocmem *ocmem, enum ocmem_client client, if (test_and_set_bit_lock(BIT(client), &ocmem->active_allocations)) return ERR_PTR(-EBUSY); - struct ocmem_buf *buf __free(kfree) = kzalloc(sizeof(*buf), GFP_KERNEL); + struct ocmem_buf *buf __free(kfree) = kzalloc_obj(*buf); if (!buf) { ret = -ENOMEM; goto err_unlock; diff --git a/drivers/soc/qcom/pdr_interface.c b/drivers/soc/qcom/pdr_interface.c index 71be378d2e43..72259f489075 100644 --- a/drivers/soc/qcom/pdr_interface.c +++ b/drivers/soc/qcom/pdr_interface.c @@ -322,7 +322,7 @@ static void pdr_indication_cb(struct qmi_handle *qmi, ind_msg->service_path, ind_msg->curr_state, ind_msg->transaction_id); - ind = kzalloc(sizeof(*ind), GFP_KERNEL); + ind = kzalloc_obj(*ind); if (!ind) return; @@ -396,8 +396,7 @@ static int pdr_locate_service(struct pdr_handle *pdr, struct pdr_service *pds) int domains_read = 0; int ret, i; - struct servreg_get_domain_list_resp *resp __free(kfree) = kzalloc(sizeof(*resp), - GFP_KERNEL); + struct servreg_get_domain_list_resp *resp __free(kfree) = kzalloc_obj(*resp); if (!resp) return -ENOMEM; @@ -520,7 +519,7 @@ struct pdr_service *pdr_add_lookup(struct pdr_handle *pdr, !service_path || strlen(service_path) > SERVREG_NAME_LENGTH) return ERR_PTR(-EINVAL); - struct pdr_service *pds __free(kfree) = kzalloc(sizeof(*pds), GFP_KERNEL); + struct pdr_service *pds __free(kfree) = kzalloc_obj(*pds); if (!pds) return ERR_PTR(-ENOMEM); @@ -645,7 +644,7 @@ struct pdr_handle *pdr_handle_alloc(void (*status)(int state, if (!status) return ERR_PTR(-EINVAL); - struct pdr_handle *pdr __free(kfree) = kzalloc(sizeof(*pdr), GFP_KERNEL); + struct pdr_handle *pdr __free(kfree) = kzalloc_obj(*pdr); if (!pdr) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/qcom_pd_mapper.c b/drivers/soc/qcom/qcom_pd_mapper.c index 1bcbe69688d2..dc10bc859ff4 100644 --- a/drivers/soc/qcom/qcom_pd_mapper.c +++ b/drivers/soc/qcom/qcom_pd_mapper.c @@ -77,7 +77,7 @@ static int qcom_pdm_add_service_domain(struct qcom_pdm_data *data, return -EBUSY; } } else { - service = kzalloc(sizeof(*service), GFP_KERNEL); + service = kzalloc_obj(*service); if (!service) return -ENOMEM; @@ -87,7 +87,7 @@ static int qcom_pdm_add_service_domain(struct qcom_pdm_data *data, list_add_tail(&service->list, &data->services); } - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) { if (list_empty(&service->domains)) { list_del(&service->list); @@ -158,7 +158,7 @@ static void qcom_pdm_get_domain_list(struct qmi_handle *qmi, u32 offset; int ret; - rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); + rsp = kzalloc_obj(*rsp); if (!rsp) return; @@ -635,7 +635,7 @@ static struct qcom_pdm_data *qcom_pdm_start(void) return ERR_PTR(-ENODEV); } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/qcom/qmi_interface.c b/drivers/soc/qcom/qmi_interface.c index 6500f863aae5..16e2e24b6096 100644 --- a/drivers/soc/qcom/qmi_interface.c +++ b/drivers/soc/qcom/qmi_interface.c @@ -44,7 +44,7 @@ static void qmi_recv_new_server(struct qmi_handle *qmi, if (!node && !port) return; - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) return; @@ -209,7 +209,7 @@ int qmi_add_lookup(struct qmi_handle *qmi, unsigned int service, { struct qmi_service *svc; - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) return -ENOMEM; @@ -273,7 +273,7 @@ int qmi_add_server(struct qmi_handle *qmi, unsigned int service, { struct qmi_service *svc; - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) return -ENOMEM; diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 1b32469f2789..342c0845134e 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -192,7 +192,7 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev) } - rmtfs_mem = kzalloc(sizeof(*rmtfs_mem), GFP_KERNEL); + rmtfs_mem = kzalloc_obj(*rmtfs_mem); if (!rmtfs_mem) return -ENOMEM; diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index 8903ed956312..ca37da3dc2b1 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -121,7 +121,7 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, if (req) goto existing; - req = kzalloc(sizeof(*req), GFP_ATOMIC); + req = kzalloc_obj(*req, GFP_ATOMIC); if (!req) { req = ERR_PTR(-ENOMEM); goto unlock; @@ -225,7 +225,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, struct rpmh_request *rpm_msg; int ret; - rpm_msg = kzalloc(sizeof(*rpm_msg), GFP_ATOMIC); + rpm_msg = kzalloc_obj(*rpm_msg, GFP_ATOMIC); if (!rpm_msg) return -ENOMEM; rpm_msg->needs_free = true; diff --git a/drivers/soc/qcom/smem_state.c b/drivers/soc/qcom/smem_state.c index cc5be8019b6a..be52ec4396d1 100644 --- a/drivers/soc/qcom/smem_state.c +++ b/drivers/soc/qcom/smem_state.c @@ -197,7 +197,7 @@ struct qcom_smem_state *qcom_smem_state_register(struct device_node *of_node, { struct qcom_smem_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index ee4f17bb4db4..38ff0b823bda 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c @@ -487,7 +487,7 @@ static int __init renesas_soc_init(void) chipid = ioremap(family->reg, 4); } - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) { if (chipid) iounmap(chipid); diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c index ae727d9c8cc5..7471dc8736e6 100644 --- a/drivers/soc/renesas/rz-sysc.c +++ b/drivers/soc/renesas/rz-sysc.c @@ -110,7 +110,7 @@ static int rz_sysc_probe(struct platform_device *pdev) struct rz_sysc *sysc; int ret; - struct regmap_config *regmap_cfg __free(kfree) = kzalloc(sizeof(*regmap_cfg), GFP_KERNEL); + struct regmap_config *regmap_cfg __free(kfree) = kzalloc_obj(*regmap_cfg); if (!regmap_cfg) return -ENOMEM; diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 74d2fedea71c..291484595dcf 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c @@ -441,7 +441,7 @@ struct device *tegra_soc_device_register(void) struct soc_device_attribute *attr; struct soc_device *dev; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return NULL; diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index 9cdbd8ba94be..a1a2966512d1 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c @@ -1131,11 +1131,11 @@ int tegra_pmc_powergate_sequence_power_up(struct tegra_pmc *pmc, if (!tegra_powergate_is_available(pmc, id)) return -EINVAL; - pg = kzalloc(sizeof(*pg), GFP_KERNEL); + pg = kzalloc_obj(*pg); if (!pg) return -ENOMEM; - pg->clk_rates = kzalloc(sizeof(*pg->clk_rates), GFP_KERNEL); + pg->clk_rates = kzalloc_obj(*pg->clk_rates); if (!pg->clk_rates) { kfree(pg->clks); return -ENOMEM; @@ -1341,7 +1341,7 @@ static int tegra_powergate_of_get_clks(struct tegra_powergate *pg, if (count == 0) return -ENODEV; - pg->clks = kcalloc(count, sizeof(clk), GFP_KERNEL); + pg->clks = kzalloc_objs(clk, count); if (!pg->clks) return -ENOMEM; @@ -1402,7 +1402,7 @@ static int tegra_powergate_add(struct tegra_pmc *pmc, struct device_node *np) int id, err = 0; bool off; - pg = kzalloc(sizeof(*pg), GFP_KERNEL); + pg = kzalloc_obj(*pg); if (!pg) return -ENOMEM; diff --git a/drivers/soc/ti/k3-socinfo.c b/drivers/soc/ti/k3-socinfo.c index 42275cb5ba1c..676041879eca 100644 --- a/drivers/soc/ti/k3-socinfo.c +++ b/drivers/soc/ti/k3-socinfo.c @@ -163,7 +163,7 @@ static int k3_chipinfo_probe(struct platform_device *pdev) partno_id = (jtag_id & CTRLMMR_WKUP_JTAGID_PARTNO_MASK) >> CTRLMMR_WKUP_JTAGID_PARTNO_SHIFT; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/soc/ux500/ux500-soc-id.c b/drivers/soc/ux500/ux500-soc-id.c index 27d6e25a0115..f49539d79824 100644 --- a/drivers/soc/ux500/ux500-soc-id.c +++ b/drivers/soc/ux500/ux500-soc-id.c @@ -205,7 +205,7 @@ static int __init ux500_soc_device_init(void) ux500_setup_id(); - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) { of_node_put(backupram); return -ENOMEM; diff --git a/drivers/soc/versatile/soc-integrator.c b/drivers/soc/versatile/soc-integrator.c index d5099a3386b4..b67a7fd4af25 100644 --- a/drivers/soc/versatile/soc-integrator.c +++ b/drivers/soc/versatile/soc-integrator.c @@ -123,7 +123,7 @@ static int __init integrator_soc_init(void) return -ENODEV; integrator_coreid = val; - soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); + soc_dev_attr = kzalloc_obj(*soc_dev_attr); if (!soc_dev_attr) return -ENOMEM; diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c index 6fdf4d14b7e7..f733dc42b3b1 100644 --- a/drivers/soc/xilinx/xlnx_event_manager.c +++ b/drivers/soc/xilinx/xlnx_event_manager.c @@ -122,7 +122,7 @@ static int xlnx_add_cb_for_notify_event(const u32 node_id, const u32 event, cons if (!present_in_hash) { /* Add new entry if not present in HASH table */ - eve_data = kmalloc(sizeof(*eve_data), GFP_KERNEL); + eve_data = kmalloc_obj(*eve_data); if (!eve_data) return -ENOMEM; eve_data->key = key; @@ -130,7 +130,7 @@ static int xlnx_add_cb_for_notify_event(const u32 node_id, const u32 event, cons eve_data->wake = wake; INIT_LIST_HEAD(&eve_data->cb_list_head); - cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL); + cb_data = kmalloc_obj(*cb_data); if (!cb_data) { kfree(eve_data); return -ENOMEM; @@ -153,7 +153,7 @@ static int xlnx_add_cb_for_notify_event(const u32 node_id, const u32 event, cons } /* Add multiple handler and private data in list */ - cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL); + cb_data = kmalloc_obj(*cb_data); if (!cb_data) return -ENOMEM; cb_data->eve_cb = cb_fun; @@ -179,7 +179,7 @@ static int xlnx_add_cb_for_suspend(event_cb_func_t cb_fun, void *data) } /* Add new entry if not present */ - eve_data = kmalloc(sizeof(*eve_data), GFP_KERNEL); + eve_data = kmalloc_obj(*eve_data); if (!eve_data) return -ENOMEM; @@ -187,7 +187,7 @@ static int xlnx_add_cb_for_suspend(event_cb_func_t cb_fun, void *data) eve_data->cb_type = PM_INIT_SUSPEND_CB; INIT_LIST_HEAD(&eve_data->cb_list_head); - cb_data = kmalloc(sizeof(*cb_data), GFP_KERNEL); + cb_data = kmalloc_obj(*cb_data); if (!cb_data) { kfree(eve_data); return -ENOMEM; diff --git a/drivers/soundwire/Kconfig b/drivers/soundwire/Kconfig index ad56393e4c93..196a7daaabdb 100644 --- a/drivers/soundwire/Kconfig +++ b/drivers/soundwire/Kconfig @@ -40,6 +40,7 @@ config SOUNDWIRE_INTEL select AUXILIARY_BUS depends on ACPI && SND_SOC depends on SND_SOC_SOF_HDA_MLINK || !SND_SOC_SOF_HDA_MLINK + depends on SND_HDA_CORE || !SND_HDA_ALIGNED_MMIO help SoundWire Intel Master driver. If you have an Intel platform which has a SoundWire Master then diff --git a/drivers/soundwire/amd_init.c b/drivers/soundwire/amd_init.c index 643e94524fe6..8e419ddfa516 100644 --- a/drivers/soundwire/amd_init.c +++ b/drivers/soundwire/amd_init.c @@ -98,14 +98,13 @@ static struct sdw_amd_ctx *sdw_amd_probe_controller(struct sdw_amd_res *res) * the parent .probe. * If devm_ was used, the memory might never be freed on errors. */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; ctx->count = count; ctx->link_mask = res->link_mask; - struct resource *sdw_res __free(kfree) = kzalloc(sizeof(*sdw_res), - GFP_KERNEL); + struct resource *sdw_res __free(kfree) = kzalloc_obj(*sdw_res); if (!sdw_res) { kfree(ctx); return NULL; @@ -205,8 +204,7 @@ int sdw_amd_get_slave_info(struct sdw_amd_ctx *ctx) num_slaves++; } - ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves), - GFP_KERNEL); + ctx->peripherals = kmalloc_flex(*ctx->peripherals, array, num_slaves); if (!ctx->peripherals) return -ENOMEM; ctx->peripherals->num_peripherals = num_slaves; diff --git a/drivers/soundwire/amd_manager.c b/drivers/soundwire/amd_manager.c index 5fd311ee4107..b9ccb3343896 100644 --- a/drivers/soundwire/amd_manager.c +++ b/drivers/soundwire/amd_manager.c @@ -718,8 +718,7 @@ static int amd_sdw_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), - GFP_KERNEL); + struct sdw_port_config *pconfig __free(kfree) = kzalloc_obj(*pconfig); if (!pconfig) return -ENOMEM; @@ -764,7 +763,7 @@ static int amd_set_sdw_stream(struct snd_soc_dai *dai, void *stream, int directi } /* allocate and set dai_runtime info */ - dai_runtime = kzalloc(sizeof(*dai_runtime), GFP_KERNEL); + dai_runtime = kzalloc_obj(*dai_runtime); if (!dai_runtime) return -ENOMEM; diff --git a/drivers/soundwire/bus_type.c b/drivers/soundwire/bus_type.c index 5c67c13e5735..a05aa36828cb 100644 --- a/drivers/soundwire/bus_type.c +++ b/drivers/soundwire/bus_type.c @@ -72,13 +72,7 @@ int sdw_slave_uevent(const struct device *dev, struct kobj_uevent_env *env) return 0; } -const struct bus_type sdw_bus_type = { - .name = "soundwire", - .match = sdw_bus_match, -}; -EXPORT_SYMBOL_GPL(sdw_bus_type); - -static int sdw_drv_probe(struct device *dev) +static int sdw_bus_probe(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); @@ -164,11 +158,10 @@ static int sdw_drv_probe(struct device *dev) return 0; } -static int sdw_drv_remove(struct device *dev) +static void sdw_bus_remove(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); - int ret = 0; mutex_lock(&slave->sdw_dev_lock); @@ -177,22 +170,29 @@ static int sdw_drv_remove(struct device *dev) mutex_unlock(&slave->sdw_dev_lock); if (drv->remove) - ret = drv->remove(slave); + drv->remove(slave); ida_free(&slave->bus->slave_ida, slave->index); - - return ret; } -static void sdw_drv_shutdown(struct device *dev) +static void sdw_bus_shutdown(struct device *dev) { struct sdw_slave *slave = dev_to_sdw_dev(dev); struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); - if (drv->shutdown) + if (dev->driver && drv->shutdown) drv->shutdown(slave); } +const struct bus_type sdw_bus_type = { + .name = "soundwire", + .match = sdw_bus_match, + .probe = sdw_bus_probe, + .remove = sdw_bus_remove, + .shutdown = sdw_bus_shutdown, +}; +EXPORT_SYMBOL_GPL(sdw_bus_type); + /** * __sdw_register_driver() - register a SoundWire Slave driver * @drv: driver to register @@ -211,9 +211,6 @@ int __sdw_register_driver(struct sdw_driver *drv, struct module *owner) } drv->driver.owner = owner; - drv->driver.probe = sdw_drv_probe; - drv->driver.remove = sdw_drv_remove; - drv->driver.shutdown = sdw_drv_shutdown; drv->driver.dev_groups = sdw_attr_groups; return driver_register(&drv->driver); diff --git a/drivers/soundwire/cadence_master.c b/drivers/soundwire/cadence_master.c index a106e5e482c8..f245c3ffb9e9 100644 --- a/drivers/soundwire/cadence_master.c +++ b/drivers/soundwire/cadence_master.c @@ -1846,7 +1846,7 @@ int cdns_set_sdw_stream(struct snd_soc_dai *dai, } /* allocate and set dai_runtime info */ - dai_runtime = kzalloc(sizeof(*dai_runtime), GFP_KERNEL); + dai_runtime = kzalloc_obj(*dai_runtime); if (!dai_runtime) return -ENOMEM; diff --git a/drivers/soundwire/debugfs.c b/drivers/soundwire/debugfs.c index 6068011dd0d9..ccc9670ef77c 100644 --- a/drivers/soundwire/debugfs.c +++ b/drivers/soundwire/debugfs.c @@ -224,7 +224,7 @@ static int do_bpt_sequence(struct sdw_slave *slave, bool write, u8 *buffer) struct sdw_bpt_msg msg = {0}; struct sdw_bpt_section *sec; - sec = kcalloc(1, sizeof(*sec), GFP_KERNEL); + sec = kzalloc_objs(*sec, 1); if (!sec) return -ENOMEM; msg.sections = 1; diff --git a/drivers/soundwire/dmi-quirks.c b/drivers/soundwire/dmi-quirks.c index 91ab97a456fa..5854218e1a27 100644 --- a/drivers/soundwire/dmi-quirks.c +++ b/drivers/soundwire/dmi-quirks.c @@ -122,6 +122,17 @@ static const struct dmi_system_id adr_remap_quirk_table[] = { }, .driver_data = (void *)intel_tgl_bios, }, + { + /* + * quirk used for Avell B.ON (OEM rebrand of NUC15 'Bishop County' + * LAPBC510 and LAPBC710) + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Avell High Performance"), + DMI_MATCH(DMI_PRODUCT_NAME, "B.ON"), + }, + .driver_data = (void *)intel_tgl_bios, + }, { /* quirk used for NUC15 'Rooks County' LAPRC510 and LAPRC710 skews */ .matches = { diff --git a/drivers/soundwire/generic_bandwidth_allocation.c b/drivers/soundwire/generic_bandwidth_allocation.c index 530ac66ac6fa..fb3970e12dac 100644 --- a/drivers/soundwire/generic_bandwidth_allocation.c +++ b/drivers/soundwire/generic_bandwidth_allocation.c @@ -402,7 +402,7 @@ static int sdw_compute_port_params(struct sdw_bus *bus, struct sdw_stream_runtim if (group.count == 0) goto out; - params = kcalloc(group.count, sizeof(*params), GFP_KERNEL); + params = kzalloc_objs(*params, group.count); if (!params) { ret = -ENOMEM; goto out; diff --git a/drivers/soundwire/intel.c b/drivers/soundwire/intel.c index 9db78f3d7615..dcd7440e78fa 100644 --- a/drivers/soundwire/intel.c +++ b/drivers/soundwire/intel.c @@ -769,8 +769,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), - GFP_KERNEL); + struct sdw_port_config *pconfig __free(kfree) = kzalloc_obj(*pconfig); if (!pconfig) return -ENOMEM; diff --git a/drivers/soundwire/intel_ace2x.c b/drivers/soundwire/intel_ace2x.c index 1ed0251d2592..7f01e43ae978 100644 --- a/drivers/soundwire/intel_ace2x.c +++ b/drivers/soundwire/intel_ace2x.c @@ -127,7 +127,7 @@ static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave * sconfig.bps = 32; /* this is required for BPT/BRA */ /* Port configuration */ - pconfig = kcalloc(2, sizeof(*pconfig), GFP_KERNEL); + pconfig = kzalloc_objs(*pconfig, 2); if (!pconfig) { ret = -ENOMEM; goto remove_slave; @@ -747,8 +747,7 @@ static int intel_hw_params(struct snd_pcm_substream *substream, sconfig.bps = snd_pcm_format_width(params_format(params)); /* Port configuration */ - struct sdw_port_config *pconfig __free(kfree) = kzalloc(sizeof(*pconfig), - GFP_KERNEL); + struct sdw_port_config *pconfig __free(kfree) = kzalloc_obj(*pconfig); if (!pconfig) return -ENOMEM; diff --git a/drivers/soundwire/intel_auxdevice.c b/drivers/soundwire/intel_auxdevice.c index 6df2601fff90..8752b0e3ce74 100644 --- a/drivers/soundwire/intel_auxdevice.c +++ b/drivers/soundwire/intel_auxdevice.c @@ -52,6 +52,7 @@ struct wake_capable_part { static struct wake_capable_part wake_capable_list[] = { {0x01fa, 0x4243}, + {0x01fa, 0x4245}, {0x025d, 0x5682}, {0x025d, 0x700}, {0x025d, 0x711}, diff --git a/drivers/soundwire/intel_init.c b/drivers/soundwire/intel_init.c index 4ffdabaf9693..ad48d67fa935 100644 --- a/drivers/soundwire/intel_init.c +++ b/drivers/soundwire/intel_init.c @@ -40,7 +40,7 @@ static struct sdw_intel_link_dev *intel_link_dev_register(struct sdw_intel_res * struct auxiliary_device *auxdev; int ret; - ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); + ldev = kzalloc_obj(*ldev); if (!ldev) return ERR_PTR(-ENOMEM); @@ -186,7 +186,7 @@ static struct sdw_intel_ctx * the parent .probe. * If devm_ was used, the memory might never be freed on errors. */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -198,7 +198,7 @@ static struct sdw_intel_ctx * If some links are disabled, the link pointer will remain NULL. Given that the * number of links is small, this is simpler than using a list to keep track of links. */ - ctx->ldev = kcalloc(ctx->count, sizeof(*ctx->ldev), GFP_KERNEL); + ctx->ldev = kzalloc_objs(*ctx->ldev, ctx->count); if (!ctx->ldev) { kfree(ctx); return NULL; @@ -253,8 +253,7 @@ static struct sdw_intel_ctx num_slaves++; } - ctx->peripherals = kmalloc(struct_size(ctx->peripherals, array, num_slaves), - GFP_KERNEL); + ctx->peripherals = kmalloc_flex(*ctx->peripherals, array, num_slaves); if (!ctx->peripherals) goto err; ctx->peripherals->num_peripherals = num_slaves; diff --git a/drivers/soundwire/master.c b/drivers/soundwire/master.c index b2c64512739d..440bfc52ccba 100644 --- a/drivers/soundwire/master.c +++ b/drivers/soundwire/master.c @@ -133,7 +133,7 @@ int sdw_master_device_add(struct sdw_bus *bus, struct device *parent, if (!parent) return -EINVAL; - md = kzalloc(sizeof(*md), GFP_KERNEL); + md = kzalloc_obj(*md); if (!md) return -ENOMEM; diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c index 17afc5aa8b44..3d8f5a81eff1 100644 --- a/drivers/soundwire/qcom.c +++ b/drivers/soundwire/qcom.c @@ -1228,10 +1228,10 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, struct sdw_port_runtime *p_rt; struct sdw_slave *slave; unsigned long *port_mask; - int maxport, pn, nports = 0, ret = 0; + int maxport, pn, nports = 0; unsigned int m_port; - struct sdw_port_config *pconfig __free(kfree) = kcalloc(ctrl->nports, - sizeof(*pconfig), GFP_KERNEL); + struct sdw_port_config *pconfig __free(kfree) = kzalloc_objs(*pconfig, + ctrl->nports); if (!pconfig) return -ENOMEM; @@ -1246,7 +1246,8 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, sconfig.type = stream->type; sconfig.bps = 1; - mutex_lock(&ctrl->port_lock); + guard(mutex)(&ctrl->port_lock); + list_for_each_entry(m_rt, &stream->master_list, stream_node) { /* * For streams with multiple masters: @@ -1272,8 +1273,7 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, if (pn > maxport) { dev_err(ctrl->dev, "All ports busy\n"); - ret = -EBUSY; - goto out; + return -EBUSY; } set_bit(pn, port_mask); pconfig[nports].num = pn; @@ -1285,10 +1285,8 @@ static int qcom_swrm_stream_alloc_ports(struct qcom_swrm_ctrl *ctrl, sdw_stream_add_master(&ctrl->bus, &sconfig, pconfig, nports, stream); -out: - mutex_unlock(&ctrl->port_lock); - return ret; + return 0; } static int qcom_swrm_hw_params(struct snd_pcm_substream *substream, diff --git a/drivers/soundwire/slave.c b/drivers/soundwire/slave.c index d933cebad52b..f5a3ca3b9dda 100644 --- a/drivers/soundwire/slave.c +++ b/drivers/soundwire/slave.c @@ -32,7 +32,7 @@ int sdw_slave_add(struct sdw_bus *bus, int ret; int i; - slave = kzalloc(sizeof(*slave), GFP_KERNEL); + slave = kzalloc_obj(*slave); if (!slave) return -ENOMEM; diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c index 38c9dbd35606..b6982f8dcf17 100644 --- a/drivers/soundwire/stream.c +++ b/drivers/soundwire/stream.c @@ -748,11 +748,11 @@ static int sdw_bank_switch(struct sdw_bus *bus, int m_rt_count) int ret; u16 addr; - wr_msg = kzalloc(sizeof(*wr_msg), GFP_KERNEL); + wr_msg = kzalloc_obj(*wr_msg); if (!wr_msg) return -ENOMEM; - wbuf = kzalloc(sizeof(*wbuf), GFP_KERNEL); + wbuf = kzalloc_obj(*wbuf); if (!wbuf) { ret = -ENOMEM; goto error_1; @@ -956,7 +956,7 @@ static struct sdw_port_runtime *sdw_port_alloc(struct list_head *port_list) { struct sdw_port_runtime *p_rt; - p_rt = kzalloc(sizeof(*p_rt), GFP_KERNEL); + p_rt = kzalloc_obj(*p_rt); if (!p_rt) return NULL; @@ -1131,7 +1131,7 @@ static struct sdw_slave_runtime { struct sdw_slave_runtime *s_rt; - s_rt = kzalloc(sizeof(*s_rt), GFP_KERNEL); + s_rt = kzalloc_obj(*s_rt); if (!s_rt) return NULL; @@ -1241,7 +1241,7 @@ static struct sdw_master_runtime } } - m_rt = kzalloc(sizeof(*m_rt), GFP_KERNEL); + m_rt = kzalloc_obj(*m_rt); if (!m_rt) return NULL; @@ -1875,7 +1875,7 @@ struct sdw_stream_runtime *sdw_alloc_stream(const char *stream_name, enum sdw_st { struct sdw_stream_runtime *stream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return NULL; diff --git a/drivers/spi/spi-amlogic-spifc-a4.c b/drivers/spi/spi-amlogic-spifc-a4.c index 35a7c4965e11..3956869cfec1 100644 --- a/drivers/spi/spi-amlogic-spifc-a4.c +++ b/drivers/spi/spi-amlogic-spifc-a4.c @@ -411,7 +411,7 @@ static int aml_sfc_dma_buffer_setup(struct aml_sfc *sfc, void *databuf, ret = dma_mapping_error(sfc->dev, sfc->daddr); if (ret) { dev_err(sfc->dev, "DMA mapping error\n"); - goto out_map_data; + return ret; } cmd = CMD_DATA_ADDRL(sfc->daddr); @@ -429,7 +429,6 @@ static int aml_sfc_dma_buffer_setup(struct aml_sfc *sfc, void *databuf, ret = dma_mapping_error(sfc->dev, sfc->iaddr); if (ret) { dev_err(sfc->dev, "DMA mapping error\n"); - dma_unmap_single(sfc->dev, sfc->daddr, datalen, dir); goto out_map_data; } @@ -448,7 +447,7 @@ static int aml_sfc_dma_buffer_setup(struct aml_sfc *sfc, void *databuf, return 0; out_map_info: - dma_unmap_single(sfc->dev, sfc->iaddr, datalen, dir); + dma_unmap_single(sfc->dev, sfc->iaddr, infolen, dir); out_map_data: dma_unmap_single(sfc->dev, sfc->daddr, datalen, dir); @@ -986,7 +985,7 @@ static int aml_sfc_ecc_init_ctx(struct nand_device *nand) nand->ecc.ctx.conf.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; - ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); + ecc_cfg = kzalloc_obj(*ecc_cfg); if (!ecc_cfg) return -ENOMEM; diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c index bbe97ce89a2f..76eb3ba75ab1 100644 --- a/drivers/spi/spi-at91-usart.c +++ b/drivers/spi/spi-at91-usart.c @@ -364,7 +364,7 @@ static int at91_usart_spi_setup(struct spi_device *spi) mr &= ~US_MR_LOOP; if (!ausd) { - ausd = kzalloc(sizeof(*ausd), GFP_KERNEL); + ausd = kzalloc_obj(*ausd); if (!ausd) return -ENOMEM; diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c index 60a37ff5c6f5..2665f31a49ce 100644 --- a/drivers/spi/spi-atcspi200.c +++ b/drivers/spi/spi-atcspi200.c @@ -195,7 +195,15 @@ static void atcspi_set_trans_ctl(struct atcspi_dev *spi, if (op->addr.buswidth > 1) tc |= TRANS_ADDR_FMT; if (op->data.nbytes) { - tc |= TRANS_DUAL_QUAD(ffs(op->data.buswidth) - 1); + unsigned int width_code; + + width_code = ffs(op->data.buswidth) - 1; + if (unlikely(width_code > 3)) { + WARN_ON_ONCE(1); + width_code = 0; + } + tc |= TRANS_DUAL_QUAD(width_code); + if (op->data.dir == SPI_MEM_DATA_IN) { if (op->dummy.nbytes) tc |= TRANS_MODE_DMY_READ | @@ -497,31 +505,17 @@ static int atcspi_init_resources(struct platform_device *pdev, static int atcspi_configure_dma(struct atcspi_dev *spi) { - struct dma_chan *dma_chan; - int ret = 0; + spi->host->dma_rx = devm_dma_request_chan(spi->dev, "rx"); + if (IS_ERR(spi->host->dma_rx)) + return PTR_ERR(spi->host->dma_rx); - dma_chan = devm_dma_request_chan(spi->dev, "rx"); - if (IS_ERR(dma_chan)) { - ret = PTR_ERR(dma_chan); - goto err_exit; - } - spi->host->dma_rx = dma_chan; + spi->host->dma_tx = devm_dma_request_chan(spi->dev, "tx"); + if (IS_ERR(spi->host->dma_tx)) + return PTR_ERR(spi->host->dma_tx); - dma_chan = devm_dma_request_chan(spi->dev, "tx"); - if (IS_ERR(dma_chan)) { - ret = PTR_ERR(dma_chan); - goto free_rx; - } - spi->host->dma_tx = dma_chan; init_completion(&spi->dma_completion); - return ret; - -free_rx: - dma_release_channel(spi->host->dma_rx); - spi->host->dma_rx = NULL; -err_exit: - return ret; + return 0; } static int atcspi_enable_clk(struct atcspi_dev *spi) diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index d71c0dbf1f38..445d645585bf 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -1300,7 +1300,7 @@ static int atmel_spi_setup(struct spi_device *spi) asd = spi->controller_state; if (!asd) { - asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL); + asd = kzalloc_obj(struct atmel_spi_device); if (!asd) return -ENOMEM; diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index c75e8da049f7..48ee5bf48173 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c @@ -815,7 +815,7 @@ static int spi_engine_optimize_message(struct spi_message *msg) p_dry.length = 0; spi_engine_compile_message(msg, true, &p_dry); - p = kzalloc(struct_size(p, instructions, p_dry.length + 1), GFP_KERNEL); + p = kzalloc_flex(*p, instructions, p_dry.length + 1); if (!p) return -ENOMEM; diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 9c06ac562f3e..dcade7b99cef 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c @@ -712,7 +712,7 @@ static int bcm_qspi_setup(struct spi_device *spi) xp = spi_get_ctldata(spi); if (!xp) { - xp = kzalloc(sizeof(*xp), GFP_KERNEL); + xp = kzalloc_obj(*xp); if (!xp) return -ENOMEM; spi_set_ctldata(spi, xp); @@ -1565,8 +1565,7 @@ int bcm_qspi_probe(struct platform_device *pdev, return PTR_ERR(qspi->base[CHIP_SELECT]); } - qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), - GFP_KERNEL); + qspi->dev_ids = kzalloc_objs(struct bcm_qspi_dev_id, num_irqs); if (!qspi->dev_ids) return -ENOMEM; diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 35ae50ca37ac..ff94482fefcc 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -1313,7 +1313,7 @@ static int bcm2835_spi_setup(struct spi_device *spi) * More on the problem that it addresses: * https://www.spinics.net/lists/linux-gpio/msg36218.html */ - lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + lookup = kzalloc_flex(*lookup, table, 2); if (!lookup) { ret = -ENOMEM; goto err_cleanup; diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index ebe18f0b5d23..9f03ac217319 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -193,7 +193,7 @@ int spi_bitbang_setup(struct spi_device *spi) bitbang = spi_controller_get_devdata(spi->controller); if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; spi->controller_state = cs; diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 649ff55333f0..5fb0cb07c110 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -76,6 +76,11 @@ struct cqspi_flash_pdata { u8 cs; }; +static const struct clk_bulk_data cqspi_clks[CLK_QSPI_NUM] = { + [CLK_QSPI_APB] = { .id = "apb" }, + [CLK_QSPI_AHB] = { .id = "ahb" }, +}; + struct cqspi_st { struct platform_device *pdev; struct spi_controller *host; @@ -1823,6 +1828,7 @@ static int cqspi_probe(struct platform_device *pdev) } /* Obtain QSPI clocks. */ + memcpy(&cqspi->clks, &cqspi_clks, sizeof(cqspi->clks)); ret = devm_clk_bulk_get_optional(dev, CLK_QSPI_NUM, cqspi->clks); if (ret) return dev_err_probe(dev, ret, "Failed to get clocks\n"); diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index d680142a059f..da7f2ae3a570 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c @@ -443,7 +443,7 @@ static int davinci_spi_of_setup(struct spi_device *spi) u32 prop; if (spicfg == NULL && np) { - spicfg = kzalloc(sizeof(*spicfg), GFP_KERNEL); + spicfg = kzalloc_obj(*spicfg); if (!spicfg) return -ENOMEM; *spicfg = davinci_spi_default_cfg; diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 0d59c141beb0..b47637888c5c 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c @@ -797,7 +797,7 @@ static int dw_spi_setup(struct spi_device *spi) struct dw_spi *dws = spi_controller_get_devdata(spi->controller); u32 rx_sample_dly_ns; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; spi_set_ctldata(spi, chip); diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index 65adec7c7524..fe726b9b1780 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c @@ -271,7 +271,7 @@ static int dw_spi_dma_wait(struct dw_spi *dws, unsigned int len, u32 speed) msecs_to_jiffies(ms)); if (ms == 0) { - dev_err(&dws->ctlr->cur_msg->spi->dev, + dev_err(&dws->ctlr->dev, "DMA transaction timed out\n"); return -ETIMEDOUT; } diff --git a/drivers/spi/spi-fsi.c b/drivers/spi/spi-fsi.c index 68276d195917..f6a75f0184c4 100644 --- a/drivers/spi/spi-fsi.c +++ b/drivers/spi/spi-fsi.c @@ -528,12 +528,12 @@ static size_t fsi_spi_max_transfer_size(struct spi_device *spi) return SPI_FSI_MAX_RX_SIZE; } -static int fsi_spi_probe(struct device *dev) +static int fsi_spi_probe(struct fsi_device *fsi) { int rc; int num_controllers_registered = 0; struct fsi2spi *bridge; - struct fsi_device *fsi = to_fsi_dev(dev); + struct device *dev = &fsi->dev; rc = fsi_spi_check_mux(fsi, dev); if (rc) @@ -590,10 +590,9 @@ MODULE_DEVICE_TABLE(fsi, fsi_spi_ids); static struct fsi_driver fsi_spi_driver = { .id_table = fsi_spi_ids, + .probe = fsi_spi_probe, .drv = { .name = "spi-fsi", - .bus = &fsi_bus_type, - .probe = fsi_spi_probe, }, }; module_fsi_driver(fsi_spi_driver); diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 76f142a54254..9f2a7b8163b1 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c @@ -1290,7 +1290,7 @@ static int dspi_setup(struct spi_device *spi) /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (chip == NULL) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + chip = kzalloc_obj(struct chip_data); if (!chip) return -ENOMEM; } diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index b06555a457f8..56270f8fdc17 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -482,7 +482,7 @@ static int fsl_espi_setup(struct spi_device *spi) struct fsl_espi_cs *cs = spi_get_ctldata(spi); if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; spi_set_ctldata(spi, cs); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 481a7b28aacd..bf3fc3ce0cc2 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -378,7 +378,7 @@ static int fsl_spi_setup(struct spi_device *spi) return -EINVAL; if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; spi_set_ctldata(spi, cs); diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index f123cdab9007..216a0a91fc47 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -426,7 +426,7 @@ static int hisi_spi_setup(struct spi_device *spi) /* Only alloc on first setup */ chip = spi_get_ctldata(spi); if (!chip) { - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; spi_set_ctldata(spi, chip); diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index f65c0bf11a73..64c6c09e1e7b 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1666,9 +1666,9 @@ static int spi_imx_dma_data_prepare(struct spi_imx_data *spi_imx, tail_bl = (transfer->len % MX51_ECSPI_CTRL_MAX_BURST) * BITS_PER_BYTE - 1; } - spi_imx->dma_data = kmalloc_array(spi_imx->dma_package_num, - sizeof(struct dma_data_package), - GFP_KERNEL | __GFP_ZERO); + spi_imx->dma_data = kmalloc_objs(struct dma_data_package, + spi_imx->dma_package_num, + GFP_KERNEL | __GFP_ZERO); if (!spi_imx->dma_data) { dev_err(spi_imx->dev, "Failed to allocate DMA package buffer!\n"); return -ENOMEM; diff --git a/drivers/spi/spi-intel-pci.c b/drivers/spi/spi-intel-pci.c index bce3d149bea1..d8ef8f89330a 100644 --- a/drivers/spi/spi-intel-pci.c +++ b/drivers/spi/spi-intel-pci.c @@ -96,6 +96,7 @@ static const struct pci_device_id intel_spi_pci_ids[] = { { PCI_VDEVICE(INTEL, 0xa324), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa3a4), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xa823), (unsigned long)&cnl_info }, + { PCI_VDEVICE(INTEL, 0xd323), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xe323), (unsigned long)&cnl_info }, { PCI_VDEVICE(INTEL, 0xe423), (unsigned long)&cnl_info }, { }, diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 965673bac98b..a09371a075d2 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -713,7 +713,7 @@ spi_mem_dirmap_create(struct spi_mem *mem, if (info->op_tmpl.data.dir == SPI_MEM_NO_DATA) return ERR_PTR(-EINVAL); - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return ERR_PTR(-ENOMEM); diff --git a/drivers/spi/spi-mpc512x-psc.c b/drivers/spi/spi-mpc512x-psc.c index a1aeb5403a74..75d560f6b5cc 100644 --- a/drivers/spi/spi-mpc512x-psc.c +++ b/drivers/spi/spi-mpc512x-psc.c @@ -362,7 +362,7 @@ static int mpc512x_psc_spi_setup(struct spi_device *spi) return -EINVAL; if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c index 73d2383461ca..954f6caceb31 100644 --- a/drivers/spi/spi-mpc52xx-psc.c +++ b/drivers/spi/spi-mpc52xx-psc.c @@ -222,7 +222,7 @@ static int mpc52xx_psc_spi_setup(struct spi_device *spi) return -EINVAL; if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; spi->controller_state = cs; diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c index 14188a6ba5a1..05bbd3795e7d 100644 --- a/drivers/spi/spi-mpc52xx.c +++ b/drivers/spi/spi-mpc52xx.c @@ -443,9 +443,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) ms->gpio_cs_count = gpiod_count(&op->dev, NULL); if (ms->gpio_cs_count > 0) { host->num_chipselect = ms->gpio_cs_count; - ms->gpio_cs = kmalloc_array(ms->gpio_cs_count, - sizeof(*ms->gpio_cs), - GFP_KERNEL); + ms->gpio_cs = kmalloc_objs(*ms->gpio_cs, ms->gpio_cs_count); if (!ms->gpio_cs) { rc = -ENOMEM; goto err_alloc_gpio; diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c index 7f7d0dfec743..437edbd658aa 100644 --- a/drivers/spi/spi-mtk-snfi.c +++ b/drivers/spi/spi-mtk-snfi.c @@ -675,7 +675,7 @@ static int mtk_snand_ecc_init_ctx(struct nand_device *nand) if (ret) return ret; - ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); + ecc_cfg = kzalloc_obj(*ecc_cfg); if (!ecc_cfg) return -ENOMEM; diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c index 0ebcbdb1b1f7..b3301c69e2de 100644 --- a/drivers/spi/spi-mxs.c +++ b/drivers/spi/spi-mxs.c @@ -182,7 +182,7 @@ static int mxs_spi_txrx_dma(struct mxs_spi *spi, if (!len) return -EINVAL; - dma_xfer = kcalloc(sgs, sizeof(*dma_xfer), GFP_KERNEL); + dma_xfer = kzalloc_objs(*dma_xfer, sgs); if (!dma_xfer) return -ENOMEM; diff --git a/drivers/spi/spi-offload.c b/drivers/spi/spi-offload.c index d336f4d228d5..a579ef33b2d2 100644 --- a/drivers/spi/spi-offload.c +++ b/drivers/spi/spi-offload.c @@ -117,7 +117,7 @@ struct spi_offload *devm_spi_offload_get(struct device *dev, if (!spi->controller->get_offload) return ERR_PTR(-ENODEV); - resource = kzalloc(sizeof(*resource), GFP_KERNEL); + resource = kzalloc_obj(*resource); if (!resource) return ERR_PTR(-ENOMEM); diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index b9a91dbfeaef..83e263eb6069 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c @@ -425,7 +425,7 @@ static int uwire_setup(struct spi_device *spi) int status; if (ust == NULL) { - ust = kzalloc(sizeof(*ust), GFP_KERNEL); + ust = kzalloc_obj(*ust); if (ust == NULL) return -ENOMEM; spi->controller_state = ust; diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 69c2e9d9be3c..2207e05c9d06 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -1076,7 +1076,7 @@ static int omap2_mcspi_setup(struct spi_device *spi) struct omap2_mcspi_cs *cs = spi->controller_state; if (!cs) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; cs->base = mcspi->base + spi_get_chipselect(spi, 0) * 0x14; diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c index fa0c1ee84532..051590038895 100644 --- a/drivers/spi/spi-pic32-sqi.c +++ b/drivers/spi/spi-pic32-sqi.c @@ -467,7 +467,7 @@ static int ring_desc_ring_alloc(struct pic32_sqi *sqi) } /* allocate software ring descriptors */ - sqi->ring = kcalloc(PESQI_BD_COUNT, sizeof(*rdesc), GFP_KERNEL); + sqi->ring = kzalloc_objs(*rdesc, PESQI_BD_COUNT); if (!sqi->ring) { dma_free_coherent(&sqi->host->dev, sizeof(*bd) * PESQI_BD_COUNT, diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index c32a1fba31ef..c82cc522776d 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -1606,7 +1606,7 @@ static int pl022_setup(struct spi_device *spi) chip = spi_get_ctldata(spi); if (chip == NULL) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + chip = kzalloc_obj(struct chip_data); if (!chip) return -ENOMEM; dev_dbg(&spi->dev, diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c index 688cabcfbc52..46ac58dfb3fc 100644 --- a/drivers/spi/spi-ppc4xx.c +++ b/drivers/spi/spi-ppc4xx.c @@ -218,7 +218,7 @@ static int spi_ppc4xx_setup(struct spi_device *spi) } if (cs == NULL) { - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return -ENOMEM; spi->controller_state = cs; diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 78c399e95ef2..f7881a31e4cc 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -1184,7 +1184,7 @@ static int setup(struct spi_device *spi) /* Only allocate on the first setup */ chip = spi_get_ctldata(spi); if (!chip) { - chip = kzalloc(sizeof(struct chip_data), GFP_KERNEL); + chip = kzalloc_obj(struct chip_data); if (!chip) return -ENOMEM; } diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index d7fef48f20ef..66f2d1b78ade 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c @@ -258,7 +258,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) cwperpage = mtd->writesize / NANDC_STEP_SIZE; snandc->qspi->num_cw = cwperpage; - ecc_cfg = kzalloc(sizeof(*ecc_cfg), GFP_KERNEL); + ecc_cfg = kzalloc_obj(*ecc_cfg); if (!ecc_cfg) return -ENOMEM; diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c index 2990bf85ee47..174995042f53 100644 --- a/drivers/spi/spi-rockchip-sfc.c +++ b/drivers/spi/spi-rockchip-sfc.c @@ -711,7 +711,7 @@ static int rockchip_sfc_probe(struct platform_device *pdev) } } - ret = devm_spi_register_controller(dev, host); + ret = spi_register_controller(host); if (ret) goto err_register; diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 4fbefd85d2e2..ba85243d6d89 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -961,7 +961,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_target_ctrldata( return ERR_PTR(-EINVAL); } - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return ERR_PTR(-ENOMEM); diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index b99de8c4cc99..33f211e159ef 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c @@ -1625,6 +1625,9 @@ static int stm32_spi_prepare_rx_dma_mdma_chaining(struct stm32_spi *spi, return -EINVAL; } + *rx_mdma_desc = _mdma_desc; + *rx_dma_desc = _dma_desc; + return 0; } diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index d805da250a10..848cb6836bd5 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -920,7 +920,7 @@ static struct tegra_spi_client_data return NULL; } - cdata = kzalloc(sizeof(*cdata), GFP_KERNEL); + cdata = kzalloc_obj(*cdata); if (!cdata) return NULL; diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index 663c0136d119..dd8bfb3f3544 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c @@ -249,7 +249,7 @@ static int tle62x0_probe(struct spi_device *spi) return -EINVAL; } - st = kzalloc(sizeof(struct tle62x0_state), GFP_KERNEL); + st = kzalloc_obj(struct tle62x0_state); if (st == NULL) return -ENOMEM; diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 60fce5c73031..cae2dcefabea 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c @@ -982,7 +982,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) spin_unlock_irqrestore(&data->lock, flags); /* RX */ - dma->sg_rx_p = kmalloc_array(num, sizeof(*dma->sg_rx_p), GFP_ATOMIC); + dma->sg_rx_p = kmalloc_objs(*dma->sg_rx_p, num, GFP_ATOMIC); if (!dma->sg_rx_p) return; @@ -1045,7 +1045,7 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) head = 0; } - dma->sg_tx_p = kmalloc_array(num, sizeof(*dma->sg_tx_p), GFP_ATOMIC); + dma->sg_tx_p = kmalloc_objs(*dma->sg_tx_p, num, GFP_ATOMIC); if (!dma->sg_tx_p) return; @@ -1527,11 +1527,11 @@ static int pch_spi_probe(struct pci_dev *pdev, const struct pci_device_id *id) int i; struct pch_pd_dev_save *pd_dev_save; - pd_dev_save = kzalloc(sizeof(*pd_dev_save), GFP_KERNEL); + pd_dev_save = kzalloc_obj(*pd_dev_save); if (!pd_dev_save) return -ENOMEM; - board_dat = kzalloc(sizeof(*board_dat), GFP_KERNEL); + board_dat = kzalloc_obj(*board_dat); if (!board_dat) { retval = -ENOMEM; goto err_no_mem; diff --git a/drivers/spi/spi-virtio.c b/drivers/spi/spi-virtio.c index 9e66c917fb75..fa4c68049eca 100644 --- a/drivers/spi/spi-virtio.c +++ b/drivers/spi/spi-virtio.c @@ -158,8 +158,7 @@ static int virtio_spi_transfer_one(struct spi_controller *ctrl, unsigned int incnt = 0; int ret; - struct virtio_spi_req *spi_req __free(kfree) = kzalloc(sizeof(*spi_req), - GFP_KERNEL); + struct virtio_spi_req *spi_req __free(kfree) = kzalloc_obj(*spi_req); if (!spi_req) return -ENOMEM; diff --git a/drivers/spi/spi-wpcm-fiu.c b/drivers/spi/spi-wpcm-fiu.c index 0e3ee5516587..0e26ff178505 100644 --- a/drivers/spi/spi-wpcm-fiu.c +++ b/drivers/spi/spi-wpcm-fiu.c @@ -459,11 +459,11 @@ static int wpcm_fiu_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory"); fiu->memory = devm_ioremap_resource(dev, res); - fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); if (IS_ERR(fiu->memory)) return dev_err_probe(dev, PTR_ERR(fiu->memory), "Failed to map flash memory window\n"); + fiu->memory_size = min_t(size_t, resource_size(res), MAX_MEMORY_SIZE_TOTAL); fiu->shm_regmap = syscon_regmap_lookup_by_phandle_optional(dev->of_node, "nuvoton,shm"); wpcm_fiu_hw_init(fiu); diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 3887fcf8ec86..61f7bde8c7fb 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -568,7 +568,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr) if (!spi_controller_get(ctlr)) return NULL; - spi = kzalloc(sizeof(*spi), GFP_KERNEL); + spi = kzalloc_obj(*spi); if (!spi) { spi_controller_put(ctlr); return NULL; @@ -921,7 +921,7 @@ int spi_register_board_info(struct spi_board_info const *info, unsigned n) if (!n) return 0; - bi = kcalloc(n, sizeof(*bi), GFP_KERNEL); + bi = kzalloc_objs(*bi, n); if (!bi) return -ENOMEM; diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 9a0160f6dc3d..638221178384 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -74,7 +74,6 @@ struct spidev_data { struct list_head device_entry; /* TX/RX buffers are NULL unless this device is open (users > 0) */ - struct mutex buf_lock; unsigned users; u8 *tx_buffer; u8 *rx_buffer; @@ -102,24 +101,6 @@ spidev_sync_unlocked(struct spi_device *spi, struct spi_message *message) return status; } -static ssize_t -spidev_sync(struct spidev_data *spidev, struct spi_message *message) -{ - ssize_t status; - struct spi_device *spi; - - mutex_lock(&spidev->spi_lock); - spi = spidev->spi; - - if (spi == NULL) - status = -ESHUTDOWN; - else - status = spidev_sync_unlocked(spi, message); - - mutex_unlock(&spidev->spi_lock); - return status; -} - static inline ssize_t spidev_sync_write(struct spidev_data *spidev, size_t len) { @@ -132,7 +113,8 @@ spidev_sync_write(struct spidev_data *spidev, size_t len) spi_message_init(&m); spi_message_add_tail(&t, &m); - return spidev_sync(spidev, &m); + + return spidev_sync_unlocked(spidev->spi, &m); } static inline ssize_t @@ -147,7 +129,8 @@ spidev_sync_read(struct spidev_data *spidev, size_t len) spi_message_init(&m); spi_message_add_tail(&t, &m); - return spidev_sync(spidev, &m); + + return spidev_sync_unlocked(spidev->spi, &m); } /*-------------------------------------------------------------------------*/ @@ -157,7 +140,7 @@ static ssize_t spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct spidev_data *spidev; - ssize_t status; + ssize_t status = -ESHUTDOWN; /* chipselect only toggles at start or end of operation */ if (count > bufsiz) @@ -165,7 +148,11 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) spidev = filp->private_data; - mutex_lock(&spidev->buf_lock); + mutex_lock(&spidev->spi_lock); + + if (spidev->spi == NULL) + goto err_spi_removed; + status = spidev_sync_read(spidev, count); if (status > 0) { unsigned long missing; @@ -176,7 +163,9 @@ spidev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) else status = status - missing; } - mutex_unlock(&spidev->buf_lock); + +err_spi_removed: + mutex_unlock(&spidev->spi_lock); return status; } @@ -187,7 +176,7 @@ spidev_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { struct spidev_data *spidev; - ssize_t status; + ssize_t status = -ESHUTDOWN; unsigned long missing; /* chipselect only toggles at start or end of operation */ @@ -196,13 +185,19 @@ spidev_write(struct file *filp, const char __user *buf, spidev = filp->private_data; - mutex_lock(&spidev->buf_lock); + mutex_lock(&spidev->spi_lock); + + if (spidev->spi == NULL) + goto err_spi_removed; + missing = copy_from_user(spidev->tx_buffer, buf, count); if (missing == 0) status = spidev_sync_write(spidev, count); else status = -EFAULT; - mutex_unlock(&spidev->buf_lock); + +err_spi_removed: + mutex_unlock(&spidev->spi_lock); return status; } @@ -219,7 +214,7 @@ static int spidev_message(struct spidev_data *spidev, int status = -EFAULT; spi_message_init(&msg); - k_xfers = kcalloc(n_xfers, sizeof(*k_tmp), GFP_KERNEL); + k_xfers = kzalloc_objs(*k_tmp, n_xfers); if (k_xfers == NULL) return -ENOMEM; @@ -379,14 +374,6 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) ctlr = spi->controller; - /* use the buffer lock here for triple duty: - * - prevent I/O (from us) so calling spi_setup() is safe; - * - prevent concurrent SPI_IOC_WR_* from morphing - * data fields while SPI_IOC_RD_* reads them; - * - SPI_IOC_MESSAGE needs the buffer locked "normally". - */ - mutex_lock(&spidev->buf_lock); - switch (cmd) { /* read requests */ case SPI_IOC_RD_MODE: @@ -510,7 +497,6 @@ spidev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; } - mutex_unlock(&spidev->buf_lock); spi_dev_put(spi); mutex_unlock(&spidev->spi_lock); return retval; @@ -541,9 +527,6 @@ spidev_compat_ioc_message(struct file *filp, unsigned int cmd, return -ESHUTDOWN; } - /* SPI_IOC_MESSAGE needs the buffer locked "normally" */ - mutex_lock(&spidev->buf_lock); - /* Check message and copy into scratch area */ ioc = spidev_get_ioc_message(cmd, u_ioc, &n_ioc); if (IS_ERR(ioc)) { @@ -564,7 +547,6 @@ spidev_compat_ioc_message(struct file *filp, unsigned int cmd, kfree(ioc); done: - mutex_unlock(&spidev->buf_lock); spi_dev_put(spi); mutex_unlock(&spidev->spi_lock); return retval; @@ -795,14 +777,13 @@ static int spidev_probe(struct spi_device *spi) } /* Allocate driver data */ - spidev = kzalloc(sizeof(*spidev), GFP_KERNEL); + spidev = kzalloc_obj(*spidev); if (!spidev) return -ENOMEM; /* Initialize the driver data */ spidev->spi = spi; mutex_init(&spidev->spi_lock); - mutex_init(&spidev->buf_lock); INIT_LIST_HEAD(&spidev->device_entry); diff --git a/drivers/spmi/spmi-apple-controller.c b/drivers/spmi/spmi-apple-controller.c index 697b3e8bb023..87e3ee9d4f2a 100644 --- a/drivers/spmi/spmi-apple-controller.c +++ b/drivers/spmi/spmi-apple-controller.c @@ -149,6 +149,7 @@ static int apple_spmi_probe(struct platform_device *pdev) } static const struct of_device_id apple_spmi_match_table[] = { + { .compatible = "apple,t8103-spmi", }, { .compatible = "apple,spmi", }, {} }; diff --git a/drivers/spmi/spmi-mtk-pmif.c b/drivers/spmi/spmi-mtk-pmif.c index 160d36f7d238..1048420b5afb 100644 --- a/drivers/spmi/spmi-mtk-pmif.c +++ b/drivers/spmi/spmi-mtk-pmif.c @@ -1,14 +1,21 @@ // SPDX-License-Identifier: GPL-2.0 // // Copyright (c) 2021 MediaTek Inc. +// Copyright (c) 2025 Collabora Ltd +// AngeloGioacchino Del Regno #include +#include #include +#include +#include #include #include +#include #include #include #include +#include #define SWINF_IDLE 0x00 #define SWINF_WFVLDCLR 0x06 @@ -20,11 +27,13 @@ #define PMIF_CMD_EXT_REG 2 #define PMIF_CMD_EXT_REG_LONG 3 -#define PMIF_DELAY_US 10 +#define PMIF_DELAY_US 2 #define PMIF_TIMEOUT_US (10 * 1000) #define PMIF_CHAN_OFFSET 0x5 +#define PMIF_RCS_IRQ_MASK GENMASK(7, 0) +#define PMIF_MAX_BUSES 2 #define PMIF_MAX_CLKS 3 #define SPMI_OP_ST_BUSY 1 @@ -41,16 +50,28 @@ struct pmif_data { const u32 *regs; const u32 *spmimst_regs; u32 soc_chan; + u8 spmi_ver; + u32 num_spmi_buses; +}; + +struct pmif_bus { + void __iomem *base; + void __iomem *spmimst_base; + struct spmi_controller *ctrl; + struct irq_domain *dom; + int irq; + struct clk_bulk_data clks[PMIF_MAX_CLKS]; + size_t nclks; + u8 irq_min_sid; + u8 irq_max_sid; + u16 irq_en; + raw_spinlock_t lock; }; struct pmif { - void __iomem *base; - void __iomem *spmimst_base; + struct pmif_bus bus[PMIF_MAX_BUSES]; struct ch_reg chan; - struct clk_bulk_data clks[PMIF_MAX_CLKS]; - size_t nclks; const struct pmif_data *data; - raw_spinlock_t lock; }; static const char * const pmif_clock_names[] = { @@ -262,33 +283,46 @@ static const u32 mt8195_spmi_regs[] = { [SPMI_MST_DBG] = 0x00FC, }; -static u32 pmif_readl(struct pmif *arb, enum pmif_regs reg) +static inline struct pmif *to_mtk_pmif(struct spmi_controller *ctrl) { - return readl(arb->base + arb->data->regs[reg]); + return dev_get_drvdata(ctrl->dev.parent); } -static void pmif_writel(struct pmif *arb, u32 val, enum pmif_regs reg) +static u32 pmif_readl(struct pmif *arb, struct pmif_bus *pbus, enum pmif_regs reg) { - writel(val, arb->base + arb->data->regs[reg]); + return readl(pbus->base + arb->data->regs[reg]); } -static void mtk_spmi_writel(struct pmif *arb, u32 val, enum spmi_regs reg) +static void pmif_writel(struct pmif *arb, struct pmif_bus *pbus, + u32 val, enum pmif_regs reg) { - writel(val, arb->spmimst_base + arb->data->spmimst_regs[reg]); + writel(val, pbus->base + arb->data->regs[reg]); } -static bool pmif_is_fsm_vldclr(struct pmif *arb) +static u32 mtk_spmi_readl(struct pmif *arb, struct pmif_bus *pbus, enum spmi_regs reg) +{ + return readl(pbus->spmimst_base + arb->data->spmimst_regs[reg]); +} + +static void mtk_spmi_writel(struct pmif *arb, struct pmif_bus *pbus, + u32 val, enum spmi_regs reg) +{ + writel(val, pbus->spmimst_base + arb->data->spmimst_regs[reg]); +} + +static bool pmif_is_fsm_vldclr(struct pmif *arb, struct pmif_bus *pbus) { u32 reg_rdata; - reg_rdata = pmif_readl(arb, arb->chan.ch_sta); + reg_rdata = pmif_readl(arb, pbus, arb->chan.ch_sta); return GET_SWINF(reg_rdata) == SWINF_WFVLDCLR; } static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) { - struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); + struct pmif *arb = to_mtk_pmif(ctrl); u32 rdata, cmd; int ret; @@ -298,8 +332,8 @@ static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) cmd = opc - SPMI_CMD_RESET; - mtk_spmi_writel(arb, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL); - ret = readl_poll_timeout_atomic(arb->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA], + mtk_spmi_writel(arb, pbus, (cmd << 0x4) | sid, SPMI_OP_ST_CTRL); + ret = readl_poll_timeout_atomic(pbus->spmimst_base + arb->data->spmimst_regs[SPMI_OP_ST_STA], rdata, (rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY, PMIF_DELAY_US, PMIF_TIMEOUT_US); if (ret < 0) @@ -311,7 +345,8 @@ static int pmif_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid) static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u16 addr, u8 *buf, size_t len) { - struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); + struct pmif *arb = to_mtk_pmif(ctrl); struct ch_reg *inf_reg; int ret; u32 data, cmd; @@ -325,7 +360,6 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, if (len > 4) { dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); - return -EINVAL; } @@ -336,41 +370,43 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, else return -EINVAL; - raw_spin_lock_irqsave(&arb->lock, flags); + raw_spin_lock_irqsave(&pbus->lock, flags); /* Wait for Software Interface FSM state to be IDLE. */ inf_reg = &arb->chan; - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], data, GET_SWINF(data) == SWINF_IDLE, PMIF_DELAY_US, PMIF_TIMEOUT_US); if (ret < 0) { /* set channel ready if the data has transferred */ - if (pmif_is_fsm_vldclr(arb)) - pmif_writel(arb, 1, inf_reg->ch_rdy); - raw_spin_unlock_irqrestore(&arb->lock, flags); + if (pmif_is_fsm_vldclr(arb, pbus)) + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); + raw_spin_unlock_irqrestore(&pbus->lock, flags); dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); return ret; } /* Send the command. */ cmd = (opc << 30) | (sid << 24) | ((len - 1) << 16) | addr; - pmif_writel(arb, cmd, inf_reg->ch_send); - raw_spin_unlock_irqrestore(&arb->lock, flags); + pmif_writel(arb, pbus, cmd, inf_reg->ch_send); /* * Wait for Software Interface FSM state to be WFVLDCLR, * read the data and clear the valid flag. */ - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], data, GET_SWINF(data) == SWINF_WFVLDCLR, PMIF_DELAY_US, PMIF_TIMEOUT_US); if (ret < 0) { + raw_spin_unlock_irqrestore(&pbus->lock, flags); dev_err(&ctrl->dev, "failed to wait for SWINF_WFVLDCLR\n"); return ret; } - data = pmif_readl(arb, inf_reg->rdata); + data = pmif_readl(arb, pbus, inf_reg->rdata); + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); + raw_spin_unlock_irqrestore(&pbus->lock, flags); + memcpy(buf, &data, len); - pmif_writel(arb, 1, inf_reg->ch_rdy); return 0; } @@ -378,7 +414,8 @@ static int pmif_spmi_read_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, u16 addr, const u8 *buf, size_t len) { - struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct pmif_bus *pbus = spmi_controller_get_drvdata(ctrl); + struct pmif *arb = to_mtk_pmif(ctrl); struct ch_reg *inf_reg; int ret; u32 data, wdata, cmd; @@ -409,31 +446,184 @@ static int pmif_spmi_write_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid, /* Set the write data. */ memcpy(&wdata, buf, len); - raw_spin_lock_irqsave(&arb->lock, flags); + raw_spin_lock_irqsave(&pbus->lock, flags); /* Wait for Software Interface FSM state to be IDLE. */ inf_reg = &arb->chan; - ret = readl_poll_timeout_atomic(arb->base + arb->data->regs[inf_reg->ch_sta], + ret = readl_poll_timeout_atomic(pbus->base + arb->data->regs[inf_reg->ch_sta], data, GET_SWINF(data) == SWINF_IDLE, PMIF_DELAY_US, PMIF_TIMEOUT_US); if (ret < 0) { /* set channel ready if the data has transferred */ - if (pmif_is_fsm_vldclr(arb)) - pmif_writel(arb, 1, inf_reg->ch_rdy); - raw_spin_unlock_irqrestore(&arb->lock, flags); + if (pmif_is_fsm_vldclr(arb, pbus)) + pmif_writel(arb, pbus, 1, inf_reg->ch_rdy); + raw_spin_unlock_irqrestore(&pbus->lock, flags); dev_err(&ctrl->dev, "failed to wait for SWINF_IDLE\n"); return ret; } - pmif_writel(arb, wdata, inf_reg->wdata); + pmif_writel(arb, pbus, wdata, inf_reg->wdata); /* Send the command. */ cmd = (opc << 30) | BIT(29) | (sid << 24) | ((len - 1) << 16) | addr; - pmif_writel(arb, cmd, inf_reg->ch_send); - raw_spin_unlock_irqrestore(&arb->lock, flags); + pmif_writel(arb, pbus, cmd, inf_reg->ch_send); + raw_spin_unlock_irqrestore(&pbus->lock, flags); return 0; } +static void mtk_spmi_handle_chained_irq(struct irq_desc *desc) +{ + struct pmif_bus *pbus = irq_desc_get_handler_data(desc); + struct irq_chip *chip = irq_desc_get_chip(desc); + struct pmif *arb = to_mtk_pmif(pbus->ctrl); + u8 regidx_min, regidx_max; + bool irq_handled = false; + unsigned int i; + + regidx_min = pbus->irq_min_sid / 4; + regidx_min += SPMI_SLV_3_0_EINT; + + regidx_max = pbus->irq_max_sid / 4; + regidx_max += SPMI_SLV_3_0_EINT; + + chained_irq_enter(chip, desc); + + for (i = regidx_min; i <= regidx_max; i++) { + u32 val = mtk_spmi_readl(arb, pbus, i); + + while (val) { + u8 bit = __ffs(val); + u8 bank = bit / 7; + u8 sid = ((i - SPMI_SLV_3_0_EINT) * 4) + bank; + + val &= ~(PMIF_RCS_IRQ_MASK << (8 * bank)); + + /* Check if IRQs for this SID are enabled */ + if (!(pbus->irq_en & BIT(sid))) + continue; + + generic_handle_domain_irq_safe(pbus->dom, sid); + irq_handled = true; + } + } + + if (!irq_handled) + handle_bad_irq(desc); + + chained_irq_exit(chip, desc); +} + +static void mtk_spmi_rcs_irq_eoi(struct irq_data *d) +{ + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); + struct pmif *arb = to_mtk_pmif(pbus->ctrl); + irq_hw_number_t irq = irqd_to_hwirq(d); + unsigned int reg, shift; + + /* There are four interrupts (8 bits each) per register */ + reg = SPMI_SLV_3_0_EINT + d->hwirq / 4; + shift = (irq % 4) * 8; + + mtk_spmi_writel(arb, pbus, PMIF_RCS_IRQ_MASK << shift, reg); +} + +static void mtk_spmi_rcs_irq_enable(struct irq_data *d) +{ + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); + irq_hw_number_t irq = irqd_to_hwirq(d); + + pbus->irq_en |= BIT(irq); +} + +static void mtk_spmi_rcs_irq_disable(struct irq_data *d) +{ + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); + irq_hw_number_t irq = irqd_to_hwirq(d); + + pbus->irq_en &= ~BIT(irq); +} + +static int mtk_spmi_rcs_irq_set_wake(struct irq_data *d, unsigned int on) +{ + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); + + return irq_set_irq_wake(pbus->irq, on); +} + +static const struct irq_chip mtk_spmi_rcs_irq_chip = { + .name = "spmi_rcs", + .irq_eoi = mtk_spmi_rcs_irq_eoi, + .irq_enable = mtk_spmi_rcs_irq_enable, + .irq_disable = mtk_spmi_rcs_irq_disable, + .irq_set_wake = mtk_spmi_rcs_irq_set_wake, +}; + +static int mtk_spmi_rcs_irq_translate(struct irq_domain *d, struct irq_fwspec *fwspec, + unsigned long *out_hwirq, unsigned int *out_type) +{ + struct pmif_bus *pbus = d->host_data; + struct device *dev = &pbus->ctrl->dev; + u32 *intspec = fwspec->param; + + if (intspec[0] > SPMI_MAX_SLAVE_ID) + return -EINVAL; + + /* + * The IRQ number in intspec[1] is ignored on purpose here! + * + * The controller only has knowledge of which SID raised an interrupt + * and the type of irq, but doesn't know about any device irq number, + * hence that must be read from the SPMI device's registers. + */ + *out_hwirq = intspec[0]; + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; + + if (pbus->irq_min_sid > intspec[0]) + pbus->irq_min_sid = intspec[0]; + + if (pbus->irq_max_sid < intspec[0]) + pbus->irq_max_sid = intspec[0]; + + dev_dbg(dev, "Found SPMI IRQ %u (map: 0x%lx)\n", intspec[0], *out_hwirq); + + return 0; +} + +static struct lock_class_key mtk_spmi_rcs_irqlock_class, mtk_spmi_rcs_irqreq_class; + +static int mtk_spmi_rcs_irq_alloc(struct irq_domain *d, unsigned int virq, + unsigned int nr_irqs, void *data) +{ + struct pmif_bus *pbus = d->host_data; + struct device *dev = &pbus->ctrl->dev; + struct irq_fwspec *fwspec = data; + irq_hw_number_t hwirq; + unsigned int irqtype; + int i, ret; + + ret = mtk_spmi_rcs_irq_translate(d, fwspec, &hwirq, &irqtype); + if (ret) + return ret; + + for (i = 0; i < nr_irqs; i++) { + dev_dbg(dev, "Mapping IRQ%u (hwirq %lu) with type %u\n", + virq, hwirq, irqtype); + + irq_set_lockdep_class(virq, &mtk_spmi_rcs_irqlock_class, + &mtk_spmi_rcs_irqreq_class); + irq_domain_set_info(d, virq, hwirq, &mtk_spmi_rcs_irq_chip, + pbus, handle_level_irq, NULL, NULL); + } + + return 0; +} + +static const struct irq_domain_ops mtk_spmi_rcs_irq_domain_ops = { + .alloc = mtk_spmi_rcs_irq_alloc, + .free = irq_domain_free_irqs_common, + .translate = mtk_spmi_rcs_irq_translate, +}; + static const struct pmif_data mt6873_pmif_arb = { .regs = mt6873_regs, .spmimst_regs = mt6873_spmi_regs, @@ -446,52 +636,176 @@ static const struct pmif_data mt8195_pmif_arb = { .soc_chan = 2, }; -static int mtk_spmi_probe(struct platform_device *pdev) -{ - struct pmif *arb; - struct spmi_controller *ctrl; - int err, i; - u32 chan_offset; +static const struct pmif_data mt8196_pmif_arb = { + .regs = mt8195_regs, + .spmimst_regs = mt8195_spmi_regs, + .soc_chan = 2, + .spmi_ver = 2, + .num_spmi_buses = 2, +}; - ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*arb)); +static int mtk_spmi_irq_init(struct device_node *node, + const struct pmif_data *pdata, + struct pmif_bus *pbus) +{ + struct pmif *arb = to_mtk_pmif(pbus->ctrl); + unsigned int i; + + /* No interrupts required for SPMI 1.x controller */ + if (pdata->spmi_ver < 2) { + pbus->dom = NULL; + return 0; + } + + pbus->irq = of_irq_get_byname(node, "rcs"); + if (pbus->irq <= 0) + return pbus->irq ? : -ENXIO; + + pbus->dom = irq_domain_create_tree(of_fwnode_handle(node), + &mtk_spmi_rcs_irq_domain_ops, pbus); + if (!pbus->dom) + return -ENOMEM; + + /* Clear possible unhandled interrupts coming from bootloader SPMI init */ + for (i = SPMI_SLV_3_0_EINT; i <= SPMI_SLV_F_C_EINT; i++) + mtk_spmi_writel(arb, pbus, GENMASK(31, 0), i); + + return 0; +} + +static void mtk_spmi_irq_remove(struct pmif_bus *pbus) +{ + if (!pbus->dom) + return; + + irq_set_chained_handler_and_data(pbus->irq, NULL, NULL); + irq_domain_remove(pbus->dom); +} + +static int mtk_spmi_bus_probe(struct platform_device *pdev, + struct device_node *node, + const struct pmif_data *pdata, + struct pmif_bus *pbus) +{ + struct spmi_controller *ctrl; + int err, idx, bus_id, i; + + if (pdata->num_spmi_buses > 1) + bus_id = of_alias_get_id(node, "spmi"); + else + bus_id = 0; + + if (bus_id < 0) + return dev_err_probe(&pdev->dev, bus_id, + "Cannot find SPMI Bus alias ID\n"); + + ctrl = devm_spmi_controller_alloc(&pdev->dev, sizeof(*pbus)); if (IS_ERR(ctrl)) return PTR_ERR(ctrl); - arb = spmi_controller_get_drvdata(ctrl); + pbus = spmi_controller_get_drvdata(ctrl); + pbus->ctrl = ctrl; + + idx = of_property_match_string(node, "reg-names", "pmif"); + if (idx < 0) + return -EINVAL; + + pbus->base = devm_of_iomap(&pdev->dev, node, idx, NULL); + if (IS_ERR(pbus->base)) + return PTR_ERR(pbus->base); + + idx = of_property_match_string(node, "reg-names", "spmimst"); + if (idx < 0) + return -EINVAL; + + pbus->spmimst_base = devm_of_iomap(&pdev->dev, node, idx, NULL); + if (IS_ERR(pbus->spmimst_base)) + return PTR_ERR(pbus->spmimst_base); + + pbus->nclks = ARRAY_SIZE(pmif_clock_names); + for (i = 0; i < pbus->nclks; i++) { + pbus->clks[i].id = pmif_clock_names[i]; + pbus->clks[i].clk = of_clk_get_by_name(node, pbus->clks[i].id); + if (IS_ERR(pbus->clks[i].clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(pbus->clks[i].clk), + "Failed to get clocks\n"); + } + + err = clk_bulk_prepare_enable(pbus->nclks, pbus->clks); + if (err) { + dev_err_probe(&pdev->dev, err, "Failed to enable clocks\n"); + goto err_put_clks; + } + + err = mtk_spmi_irq_init(node, pdata, pbus); + if (err) { + dev_err_probe(&pdev->dev, err, "Cannot initialize SPMI IRQs\n"); + goto err_disable_clks; + } + + ctrl->cmd = pmif_arb_cmd; + ctrl->read_cmd = pmif_spmi_read_cmd; + ctrl->write_cmd = pmif_spmi_write_cmd; + ctrl->dev.of_node = node; + dev_set_name(&ctrl->dev, "spmi-%d", bus_id); + + raw_spin_lock_init(&pbus->lock); + + err = spmi_controller_add(ctrl); + if (err) + goto err_remove_irq; + + if (pbus->dom) + irq_set_chained_handler_and_data(pbus->irq, mtk_spmi_handle_chained_irq, pbus); + + return 0; + +err_remove_irq: + mtk_spmi_irq_remove(pbus); +err_disable_clks: + clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); +err_put_clks: + clk_bulk_put(pbus->nclks, pbus->clks); + return err; +} + +static int mtk_spmi_probe(struct platform_device *pdev) +{ + struct device_node *node = pdev->dev.of_node; + struct pmif *arb; + u32 chan_offset; + u8 cur_bus = 0; + int ret; + + arb = devm_kzalloc(&pdev->dev, sizeof(*arb), GFP_KERNEL); + if (!arb) + return -ENOMEM; + arb->data = device_get_match_data(&pdev->dev); if (!arb->data) { dev_err(&pdev->dev, "Cannot get drv_data\n"); return -EINVAL; } - arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif"); - if (IS_ERR(arb->base)) - return PTR_ERR(arb->base); + platform_set_drvdata(pdev, arb); - arb->spmimst_base = devm_platform_ioremap_resource_byname(pdev, "spmimst"); - if (IS_ERR(arb->spmimst_base)) - return PTR_ERR(arb->spmimst_base); + if (!arb->data->num_spmi_buses) { + ret = mtk_spmi_bus_probe(pdev, node, arb->data, &arb->bus[cur_bus]); + if (ret) + return ret; + } else { + for_each_available_child_of_node_scoped(node, child) { + if (!of_node_name_eq(child, "spmi")) + continue; - arb->nclks = ARRAY_SIZE(pmif_clock_names); - for (i = 0; i < arb->nclks; i++) - arb->clks[i].id = pmif_clock_names[i]; - - err = clk_bulk_get(&pdev->dev, arb->nclks, arb->clks); - if (err) { - dev_err(&pdev->dev, "Failed to get clocks: %d\n", err); - return err; + ret = mtk_spmi_bus_probe(pdev, child, arb->data, + &arb->bus[cur_bus]); + if (ret) + return ret; + cur_bus++; + } } - err = clk_bulk_prepare_enable(arb->nclks, arb->clks); - if (err) { - dev_err(&pdev->dev, "Failed to enable clocks: %d\n", err); - goto err_put_clks; - } - - ctrl->cmd = pmif_arb_cmd; - ctrl->read_cmd = pmif_spmi_read_cmd; - ctrl->write_cmd = pmif_spmi_write_cmd; - chan_offset = PMIF_CHAN_OFFSET * arb->data->soc_chan; arb->chan.ch_sta = PMIF_SWINF_0_STA + chan_offset; arb->chan.wdata = PMIF_SWINF_0_WDATA_31_0 + chan_offset; @@ -499,31 +813,25 @@ static int mtk_spmi_probe(struct platform_device *pdev) arb->chan.ch_send = PMIF_SWINF_0_ACC + chan_offset; arb->chan.ch_rdy = PMIF_SWINF_0_VLD_CLR + chan_offset; - raw_spin_lock_init(&arb->lock); - - platform_set_drvdata(pdev, ctrl); - - err = spmi_controller_add(ctrl); - if (err) - goto err_domain_remove; - return 0; - -err_domain_remove: - clk_bulk_disable_unprepare(arb->nclks, arb->clks); -err_put_clks: - clk_bulk_put(arb->nclks, arb->clks); - return err; } static void mtk_spmi_remove(struct platform_device *pdev) { - struct spmi_controller *ctrl = platform_get_drvdata(pdev); - struct pmif *arb = spmi_controller_get_drvdata(ctrl); + struct pmif *arb = platform_get_drvdata(pdev); + int i; - spmi_controller_remove(ctrl); - clk_bulk_disable_unprepare(arb->nclks, arb->clks); - clk_bulk_put(arb->nclks, arb->clks); + for (i = 0; i < PMIF_MAX_BUSES; i++) { + struct pmif_bus *pbus = &arb->bus[i]; + + if (!pbus->ctrl) + continue; + + mtk_spmi_irq_remove(pbus); + spmi_controller_remove(pbus->ctrl); + clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); + clk_bulk_put(pbus->nclks, pbus->clks); + } } static const struct of_device_id mtk_spmi_match_table[] = { @@ -533,6 +841,9 @@ static const struct of_device_id mtk_spmi_match_table[] = { }, { .compatible = "mediatek,mt8195-spmi", .data = &mt8195_pmif_arb, + }, { + .compatible = "mediatek,mt8196-spmi", + .data = &mt8196_pmif_arb, }, { /* sentinel */ }, @@ -549,6 +860,7 @@ static struct platform_driver mtk_spmi_driver = { }; module_platform_driver(mtk_spmi_driver); +MODULE_AUTHOR("AngeloGioacchino Del Regno "); MODULE_AUTHOR("Hsin-Hsiung Wang "); MODULE_DESCRIPTION("MediaTek SPMI Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c index 91581974ef84..69f8d456324a 100644 --- a/drivers/spmi/spmi-pmic-arb.c +++ b/drivers/spmi/spmi-pmic-arb.c @@ -2,6 +2,8 @@ /* * Copyright (c) 2012-2015, 2017, 2021, The Linux Foundation. All rights reserved. */ + +#include #include #include #include @@ -25,12 +27,12 @@ #define PMIC_ARB_VERSION_V3_MIN 0x30000000 #define PMIC_ARB_VERSION_V5_MIN 0x50000000 #define PMIC_ARB_VERSION_V7_MIN 0x70000000 +#define PMIC_ARB_VERSION_V8_MIN 0x80000000 #define PMIC_ARB_INT_EN 0x0004 #define PMIC_ARB_FEATURES 0x0004 #define PMIC_ARB_FEATURES_PERIPH_MASK GENMASK(10, 0) - -#define PMIC_ARB_FEATURES1 0x0008 +#define PMIC_ARB_FEATURES_V8_PERIPH_MASK GENMASK(12, 0) /* PMIC Arbiter channel registers offsets */ #define PMIC_ARB_CMD 0x00 @@ -50,9 +52,11 @@ #define SPMI_MAPPING_BIT_IS_1_RESULT(X) (((X) >> 0) & 0xFF) #define SPMI_MAPPING_TABLE_TREE_DEPTH 16 /* Maximum of 16-bits */ -#define PMIC_ARB_MAX_PPID BIT(12) /* PPID is 12bit */ +#define PMIC_ARB_MAX_PPID BIT(13) #define PMIC_ARB_APID_VALID BIT(15) -#define PMIC_ARB_CHAN_IS_IRQ_OWNER(reg) ((reg) & BIT(24)) +#define PMIC_ARB_CHAN_IS_IRQ_OWNER_MASK BIT(24) +#define PMIC_ARB_V8_CHAN_IS_IRQ_OWNER_MASK BIT(31) + #define INVALID_EE 0xFF /* Ownership Table */ @@ -96,30 +100,37 @@ enum pmic_arb_channel { PMIC_ARB_CHANNEL_OBS, }; -#define PMIC_ARB_MAX_BUSES 2 +#define PMIC_ARB_MAX_BUSES 4 /* Maximum number of support PMIC peripherals */ #define PMIC_ARB_MAX_PERIPHS 512 #define PMIC_ARB_MAX_PERIPHS_V7 1024 +#define PMIC_ARB_MAX_PERIPHS_V8 8192 #define PMIC_ARB_TIMEOUT_US 1000 #define PMIC_ARB_MAX_TRANS_BYTES (8) #define PMIC_ARB_APID_MASK 0xFF -#define PMIC_ARB_PPID_MASK 0xFFF +#define PMIC_ARB_PPID_MASK GENMASK(11, 0) +#define PMIC_ARB_V8_PPID_MASK GENMASK(12, 0) /* interrupt enable bit */ #define SPMI_PIC_ACC_ENABLE_BIT BIT(0) -#define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ - ((((slave_id) & 0xF) << 28) | \ - (((periph_id) & 0xFF) << 20) | \ - (((irq_id) & 0x7) << 16) | \ - (((apid) & 0x3FF) << 0)) +#define HWIRQ_SID_MASK GENMASK(28, 24) +#define HWIRQ_PID_MASK GENMASK(23, 16) +#define HWIRQ_IRQID_MASK GENMASK(15, 13) +#define HWIRQ_APID_MASK GENMASK(12, 0) -#define hwirq_to_sid(hwirq) (((hwirq) >> 28) & 0xF) -#define hwirq_to_per(hwirq) (((hwirq) >> 20) & 0xFF) -#define hwirq_to_irq(hwirq) (((hwirq) >> 16) & 0x7) -#define hwirq_to_apid(hwirq) (((hwirq) >> 0) & 0x3FF) +#define spec_to_hwirq(slave_id, periph_id, irq_id, apid) \ + (FIELD_PREP(HWIRQ_SID_MASK, (slave_id)) | \ + FIELD_PREP(HWIRQ_PID_MASK, (periph_id)) | \ + FIELD_PREP(HWIRQ_IRQID_MASK, (irq_id)) | \ + FIELD_PREP(HWIRQ_APID_MASK, (apid))) + +#define hwirq_to_sid(hwirq) FIELD_GET(HWIRQ_SID_MASK, (hwirq)) +#define hwirq_to_per(hwirq) FIELD_GET(HWIRQ_PID_MASK, (hwirq)) +#define hwirq_to_irq(hwirq) FIELD_GET(HWIRQ_IRQID_MASK, (hwirq)) +#define hwirq_to_apid(hwirq) FIELD_GET(HWIRQ_APID_MASK, (hwirq)) struct pmic_arb_ver_ops; @@ -138,11 +149,12 @@ struct spmi_pmic_arb; * @domain: irq domain object for PMIC IRQ domain * @intr: address of the SPMI interrupt control registers. * @cnfg: address of the PMIC Arbiter configuration registers. + * @apid_owner: on v8: address of APID owner mapping table registers * @spmic: spmi controller registered for this bus * @lock: lock to synchronize accesses. - * @base_apid: on v7: minimum APID associated with the particular SPMI - * bus instance - * @apid_count: on v5 and v7: number of APIDs associated with the + * @base_apid: on v7 and v8: minimum APID associated with the + * particular SPMI bus instance + * @apid_count: on v5, v7 and v8: number of APIDs associated with the * particular SPMI bus instance * @mapping_table: in-memory copy of PPID -> APID mapping table. * @mapping_table_valid:bitmap containing valid-only periphs @@ -159,6 +171,7 @@ struct spmi_pmic_arb_bus { struct irq_domain *domain; void __iomem *intr; void __iomem *cnfg; + void __iomem *apid_owner; struct spmi_controller *spmic; raw_spinlock_t lock; u16 base_apid; @@ -181,6 +194,7 @@ struct spmi_pmic_arb_bus { * @wr_base: on v1 "core", on v2 "chnls" register base off DT. * @core: core register base for v2 and above only (see above) * @core_size: core register base size + * @apid_map: on v8, APID mapping table register base * @channel: execution environment channel to use for accesses. * @ee: the current Execution Environment * @ver_ops: version dependent operations. @@ -193,6 +207,7 @@ struct spmi_pmic_arb { void __iomem *wr_base; void __iomem *core; resource_size_t core_size; + void __iomem *apid_map; u8 channel; u8 ee; const struct pmic_arb_ver_ops *ver_ops; @@ -206,6 +221,7 @@ struct spmi_pmic_arb { * * @ver_str: version string. * @get_core_resources: initializes the core, observer and channels + * @get_bus_resources: requests per-SPMI bus register resources * @init_apid: finds the apid base and count * @ppid_to_apid: finds the apid for a given ppid. * @non_data_cmd: on v1 issues an spmi non-data command. @@ -227,6 +243,9 @@ struct spmi_pmic_arb { struct pmic_arb_ver_ops { const char *ver_str; int (*get_core_resources)(struct platform_device *pdev, void __iomem *core); + int (*get_bus_resources)(struct platform_device *pdev, + struct device_node *node, + struct spmi_pmic_arb_bus *bus); int (*init_apid)(struct spmi_pmic_arb_bus *bus, int index); int (*ppid_to_apid)(struct spmi_pmic_arb_bus *bus, u16 ppid); /* spmi commands (read_cmd, write_cmd, cmd) functionality */ @@ -656,7 +675,7 @@ static int periph_interrupt(struct spmi_pmic_arb_bus *bus, u16 apid) unsigned int irq; u32 status, id; int handled = 0; - u8 sid = (bus->apid_data[apid].ppid >> 8) & 0xF; + u8 sid = (bus->apid_data[apid].ppid >> 8) & 0x1F; u8 per = bus->apid_data[apid].ppid & 0xFF; status = readl_relaxed(pmic_arb->ver_ops->irq_status(bus, apid)); @@ -686,7 +705,7 @@ static void pmic_arb_chained_irq(struct irq_desc *desc) int last = bus->max_apid; /* * acc_offset will be non-zero for the secondary SPMI bus instance on - * v7 controllers. + * v7 and v8 controllers. */ int acc_offset = bus->base_apid >> 5; u8 ee = pmic_arb->ee; @@ -913,7 +932,8 @@ static int qpnpint_irq_domain_translate(struct irq_domain *d, return -EINVAL; if (fwspec->param_count != 4) return -EINVAL; - if (intspec[0] > 0xF || intspec[1] > 0xFF || intspec[2] > 0x7) + if (intspec[0] > FIELD_MAX(HWIRQ_SID_MASK) || intspec[1] > FIELD_MAX(HWIRQ_PID_MASK) || + intspec[2] > FIELD_MAX(HWIRQ_IRQID_MASK)) return -EINVAL; ppid = intspec[0] << 8 | intspec[1]; @@ -1160,7 +1180,9 @@ static int pmic_arb_ppid_to_apid_v2(struct spmi_pmic_arb_bus *bus, u16 ppid) return apid_valid & ~PMIC_ARB_APID_VALID; } -static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) +static int _pmic_arb_read_apid_map(struct spmi_pmic_arb_bus *bus, + void __iomem *ppid_base, unsigned long ppid_mask, + u8 ppid_shift, unsigned long irq_owner_mask) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; struct apid_data *apidd; @@ -1171,7 +1193,7 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) /* * In order to allow multiple EEs to write to a single PPID in arbiter - * version 5 and 7, there is more than one APID mapped to each PPID. + * version 5,7 and 8, there can be more than one APID mapped to each PPID. * The owner field for each of these mappings specifies the EE which is * allowed to write to the APID. The owner of the last (highest) APID * which has the IRQ owner bit set for a given PPID will receive @@ -1183,19 +1205,30 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) * APID = N to N+M-1 are assigned to the secondary bus * where N = number of APIDs supported by the primary bus and * M = number of APIDs supported by the secondary bus + * + * In arbiter version 8, the APID numbering space is divided between + * the SPMI buses according to this mapping: + * APID = 0 to N-1 --> bus 0 + * APID = N to N+M-1 --> bus 1 + * APID = N+M to N+M+P-1 --> bus 2 + * APID = N+M+P to N+M+P+Q-1 --> bus 3 + * where N = number of APIDs supported by bus 0 + * M = number of APIDs supported by bus 1 + * P = number of APIDs supported by bus 2 + * Q = number of APIDs supported by bus 3 */ + apidd = &bus->apid_data[bus->base_apid]; apid_max = bus->base_apid + bus->apid_count; for (i = bus->base_apid; i < apid_max; i++, apidd++) { offset = pmic_arb->ver_ops->apid_map_offset(i); if (offset >= pmic_arb->core_size) break; - - regval = readl_relaxed(pmic_arb->core + offset); + regval = readl_relaxed(ppid_base + offset); if (!regval) continue; - ppid = (regval >> 8) & PMIC_ARB_PPID_MASK; - is_irq_ee = PMIC_ARB_CHAN_IS_IRQ_OWNER(regval); + ppid = (regval >> ppid_shift) & ppid_mask; + is_irq_ee = regval & irq_owner_mask; regval = readl_relaxed(pmic_arb->ver_ops->apid_owner(bus, i)); apidd->write_ee = SPMI_OWNERSHIP_PERIPH2OWNER(regval); @@ -1237,6 +1270,12 @@ static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) return 0; } +static int pmic_arb_read_apid_map_v5(struct spmi_pmic_arb_bus *bus) +{ + return _pmic_arb_read_apid_map(bus, bus->pmic_arb->core, PMIC_ARB_PPID_MASK, + 8, PMIC_ARB_CHAN_IS_IRQ_OWNER_MASK); +} + static int pmic_arb_ppid_to_apid_v5(struct spmi_pmic_arb_bus *bus, u16 ppid) { if (!(bus->ppid_to_apid[ppid] & PMIC_ARB_APID_VALID)) @@ -1345,37 +1384,46 @@ static int pmic_arb_get_core_resources_v7(struct platform_device *pdev, return pmic_arb_get_obsrvr_chnls_v2(pdev); } -/* - * Only v7 supports 2 buses. Each bus will get a different apid count, read - * from different registers. - */ -static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) +static int _pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index, + int max_buses, unsigned long periph_mask) { struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; - int ret; + int i; - if (index == 0) { - bus->base_apid = 0; - bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } else if (index == 1) { - bus->base_apid = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES) & - PMIC_ARB_FEATURES_PERIPH_MASK; - bus->apid_count = readl_relaxed(pmic_arb->core + PMIC_ARB_FEATURES1) & - PMIC_ARB_FEATURES_PERIPH_MASK; - } else { - dev_err(&bus->spmic->dev, "Unsupported buses count %d detected\n", - bus->id); + if (index < 0 || index >= max_buses) { + dev_err(&bus->spmic->dev, "Unsupported bus index %d detected\n", + index); return -EINVAL; } - if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { - dev_err(&bus->spmic->dev, "Unsupported APID count %d detected\n", + bus->base_apid = 0; + bus->apid_count = 0; + for (i = 0; i <= index; i++) { + bus->base_apid += bus->apid_count; + bus->apid_count = readl_relaxed(pmic_arb->core + + PMIC_ARB_FEATURES + i * 4) & + periph_mask; + } + + if (bus->apid_count == 0) { + dev_err(&bus->spmic->dev, "Bus %d not implemented\n", index); + return -EINVAL; + } else if (bus->base_apid + bus->apid_count > pmic_arb->max_periphs) { + dev_err(&bus->spmic->dev, "Unsupported max APID %d detected\n", bus->base_apid + bus->apid_count); return -EINVAL; } - ret = pmic_arb_init_apid_min_max(bus); + return pmic_arb_init_apid_min_max(bus); +} + +/* + * Arbiter v7 supports 2 buses. Each bus will get a different apid count, read + * from different registers. + */ +static int pmic_arb_init_apid_v7(struct spmi_pmic_arb_bus *bus, int index) +{ + int ret = _pmic_arb_init_apid_v7(bus, index, 2, PMIC_ARB_FEATURES_PERIPH_MASK); if (ret) return ret; @@ -1424,6 +1472,102 @@ static int pmic_arb_offset_v7(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, return offset; } +static int pmic_arb_get_core_resources_v8(struct platform_device *pdev, + void __iomem *core) +{ + struct spmi_pmic_arb *pmic_arb = platform_get_drvdata(pdev); + + pmic_arb->apid_map = devm_platform_ioremap_resource_byname(pdev, "chnl_map"); + if (IS_ERR(pmic_arb->apid_map)) + return PTR_ERR(pmic_arb->apid_map); + + pmic_arb->core = core; + + pmic_arb->max_periphs = PMIC_ARB_MAX_PERIPHS_V8; + + return pmic_arb_get_obsrvr_chnls_v2(pdev); +} + +static int pmic_arb_get_bus_resources_v8(struct platform_device *pdev, + struct device_node *node, + struct spmi_pmic_arb_bus *bus) +{ + int index; + + index = of_property_match_string(node, "reg-names", "chnl_owner"); + if (index < 0) { + dev_err(&pdev->dev, "chnl_owner reg region missing\n"); + return -EINVAL; + } + + bus->apid_owner = devm_of_iomap(&pdev->dev, node, index, NULL); + + return PTR_ERR_OR_ZERO(bus->apid_owner); +} + +static int pmic_arb_read_apid_map_v8(struct spmi_pmic_arb_bus *bus) +{ + return _pmic_arb_read_apid_map(bus, bus->pmic_arb->apid_map, + PMIC_ARB_V8_PPID_MASK, 0, + PMIC_ARB_V8_CHAN_IS_IRQ_OWNER_MASK); +} + +/* + * Arbiter v8 supports up to 4 buses. Each bus will get a different apid count, read + * from different registers. + */ +static int pmic_arb_init_apid_v8(struct spmi_pmic_arb_bus *bus, int index) +{ + int ret = _pmic_arb_init_apid_v7(bus, index, 4, + PMIC_ARB_FEATURES_V8_PERIPH_MASK); + if (ret) + return ret; + + ret = pmic_arb_read_apid_map_v8(bus); + if (ret) { + dev_err(&bus->spmic->dev, "could not read APID->PPID mapping table, rc= %d\n", + ret); + return ret; + } + + return 0; +} + +/* + * v8 offset per ee and per apid for observer channels and per apid for + * read/write channels. + */ +static int pmic_arb_offset_v8(struct spmi_pmic_arb_bus *bus, u8 sid, u16 addr, + enum pmic_arb_channel ch_type) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + u16 apid; + int rc; + u32 offset = 0; + u16 ppid = (sid << 8) | (addr >> 8); + + rc = pmic_arb->ver_ops->ppid_to_apid(bus, ppid); + if (rc < 0) + return rc; + + apid = rc; + switch (ch_type) { + case PMIC_ARB_CHANNEL_OBS: + offset = 0x40000 * pmic_arb->ee + 0x20 * apid; + break; + case PMIC_ARB_CHANNEL_RW: + if (bus->apid_data[apid].write_ee != pmic_arb->ee) { + dev_err(&bus->spmic->dev, "disallowed SPMI write to sid=%u, addr=0x%04X\n", + sid, addr); + return -EPERM; + } + offset = 0x200 * apid; + break; + } + + return offset; +} + static u32 pmic_arb_fmt_cmd_v1(u8 opc, u8 sid, u16 addr, u8 bc) { return (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7); @@ -1490,6 +1634,14 @@ pmic_arb_acc_enable_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x100 + 0x1000 * n; } +static void __iomem * +pmic_arb_acc_enable_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x100 + 0x200 * n; +} + static void __iomem * pmic_arb_irq_status_v1(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1516,6 +1668,14 @@ pmic_arb_irq_status_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x104 + 0x1000 * n; } +static void __iomem * +pmic_arb_irq_status_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x104 + 0x200 * n; +} + static void __iomem * pmic_arb_irq_clear_v1(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1542,6 +1702,14 @@ pmic_arb_irq_clear_v7(struct spmi_pmic_arb_bus *bus, u16 n) return pmic_arb->wr_base + 0x108 + 0x1000 * n; } +static void __iomem * +pmic_arb_irq_clear_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + struct spmi_pmic_arb *pmic_arb = bus->pmic_arb; + + return pmic_arb->wr_base + 0x108 + 0x200 * n; +} + static u32 pmic_arb_apid_map_offset_v2(u16 n) { return 0x800 + 0x4 * n; @@ -1557,6 +1725,12 @@ static u32 pmic_arb_apid_map_offset_v7(u16 n) return 0x2000 + 0x4 * n; } +static u32 pmic_arb_apid_map_offset_v8(u16 n) +{ + /* For v8, offset is from "chnl_map" base register, not "core". */ + return 0x4 * n; +} + static void __iomem * pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) { @@ -1564,7 +1738,7 @@ pmic_arb_apid_owner_v2(struct spmi_pmic_arb_bus *bus, u16 n) } /* - * For arbiter version 7, APID ownership table registers have independent + * For arbiter version 7 and 8, APID ownership table registers have independent * numbering space for each SPMI bus instance, so each is indexed starting from * 0. */ @@ -1574,6 +1748,12 @@ pmic_arb_apid_owner_v7(struct spmi_pmic_arb_bus *bus, u16 n) return bus->cnfg + 0x4 * (n - bus->base_apid); } +static void __iomem * +pmic_arb_apid_owner_v8(struct spmi_pmic_arb_bus *bus, u16 n) +{ + return bus->apid_owner + 0x4 * (n - bus->base_apid); +} + static const struct pmic_arb_ver_ops pmic_arb_v1 = { .ver_str = "v1", .get_core_resources = pmic_arb_get_core_resources_v1, @@ -1654,6 +1834,23 @@ static const struct pmic_arb_ver_ops pmic_arb_v7 = { .apid_owner = pmic_arb_apid_owner_v7, }; +static const struct pmic_arb_ver_ops pmic_arb_v8 = { + .ver_str = "v8", + .get_core_resources = pmic_arb_get_core_resources_v8, + .get_bus_resources = pmic_arb_get_bus_resources_v8, + .init_apid = pmic_arb_init_apid_v8, + .ppid_to_apid = pmic_arb_ppid_to_apid_v5, + .non_data_cmd = pmic_arb_non_data_cmd_v2, + .offset = pmic_arb_offset_v8, + .fmt_cmd = pmic_arb_fmt_cmd_v2, + .owner_acc_status = pmic_arb_owner_acc_status_v7, + .acc_enable = pmic_arb_acc_enable_v8, + .irq_status = pmic_arb_irq_status_v8, + .irq_clear = pmic_arb_irq_clear_v8, + .apid_map_offset = pmic_arb_apid_map_offset_v8, + .apid_owner = pmic_arb_apid_owner_v8, +}; + static const struct irq_domain_ops pmic_arb_irq_domain_ops = { .activate = qpnpint_irq_domain_activate, .alloc = qpnpint_irq_domain_alloc, @@ -1731,6 +1928,12 @@ static int spmi_pmic_arb_bus_init(struct platform_device *pdev, bus->spmic = ctrl; bus->id = bus_index; + if (pmic_arb->ver_ops->get_bus_resources) { + ret = pmic_arb->ver_ops->get_bus_resources(pdev, node, bus); + if (ret) + return ret; + } + ret = pmic_arb->ver_ops->init_apid(bus, bus_index); if (ret) return ret; @@ -1825,8 +2028,10 @@ static int spmi_pmic_arb_probe(struct platform_device *pdev) pmic_arb->ver_ops = &pmic_arb_v3; else if (hw_ver < PMIC_ARB_VERSION_V7_MIN) pmic_arb->ver_ops = &pmic_arb_v5; - else + else if (hw_ver < PMIC_ARB_VERSION_V8_MIN) pmic_arb->ver_ops = &pmic_arb_v7; + else + pmic_arb->ver_ops = &pmic_arb_v8; err = pmic_arb->ver_ops->get_core_resources(pdev, core); if (err) @@ -1875,6 +2080,7 @@ static void spmi_pmic_arb_remove(struct platform_device *pdev) static const struct of_device_id spmi_pmic_arb_match_table[] = { { .compatible = "qcom,spmi-pmic-arb", }, { .compatible = "qcom,x1e80100-spmi-pmic-arb", }, + { .compatible = "qcom,glymur-spmi-pmic-arb", }, {}, }; MODULE_DEVICE_TABLE(of, spmi_pmic_arb_match_table); diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c index 3cf8d9bd4566..e889b129f3ac 100644 --- a/drivers/spmi/spmi.c +++ b/drivers/spmi/spmi.c @@ -418,7 +418,7 @@ struct spmi_device *spmi_device_alloc(struct spmi_controller *ctrl) { struct spmi_device *sdev; - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + sdev = kzalloc_obj(*sdev); if (!sdev) return NULL; diff --git a/drivers/ssb/bridge_pcmcia_80211.c b/drivers/ssb/bridge_pcmcia_80211.c index ffa379efff83..689ff069ff37 100644 --- a/drivers/ssb/bridge_pcmcia_80211.c +++ b/drivers/ssb/bridge_pcmcia_80211.c @@ -31,7 +31,7 @@ static int ssb_host_pcmcia_probe(struct pcmcia_device *dev) int err = -ENOMEM; int res = 0; - ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); + ssb = kzalloc_obj(*ssb); if (!ssb) goto out_error; diff --git a/drivers/ssb/driver_gige.c b/drivers/ssb/driver_gige.c index ebee6b0e3c34..0aca0711807b 100644 --- a/drivers/ssb/driver_gige.c +++ b/drivers/ssb/driver_gige.c @@ -173,7 +173,7 @@ static int ssb_gige_probe(struct ssb_device *sdev, struct ssb_gige *dev; u32 base, tmslow, tmshigh; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; dev->dev = sdev; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index aa6165e3db4a..b2d339eb57d5 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -481,7 +481,7 @@ static int ssb_devices_register(struct ssb_bus *bus) continue; } - devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL); + devwrap = kzalloc_obj(*devwrap); if (!devwrap) { err = -ENOMEM; goto error; diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c index dd70fd41c77d..5b6b5e0e4433 100644 --- a/drivers/ssb/pcihost_wrapper.c +++ b/drivers/ssb/pcihost_wrapper.c @@ -71,7 +71,7 @@ static int ssb_pcihost_probe(struct pci_dev *dev, int err = -ENOMEM; u32 val; - ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); + ssb = kzalloc_obj(*ssb); if (!ssb) goto out; err = pci_enable_device(dev); diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index 509d620d6ce7..aa90b27197cf 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -9,11 +9,6 @@ * See Xilinx PG080 document for IP details */ -/* ---------------------------- - * includes - * ---------------------------- - */ - #include #include #include @@ -25,20 +20,14 @@ #include #include #include -#include #include -#include #include #include #include #include #include #include - -/* ---------------------------- - * driver parameters - * ---------------------------- - */ +#include #define DRIVER_NAME "axis_fifo" @@ -46,90 +35,51 @@ #define AXIS_FIFO_DEBUG_REG_NAME_MAX_LEN 4 -/* ---------------------------- - * IP register offsets - * ---------------------------- - */ +#define XLLF_ISR_OFFSET 0x00 /* Interrupt Status */ +#define XLLF_IER_OFFSET 0x04 /* Interrupt Enable */ +#define XLLF_TDFR_OFFSET 0x08 /* Transmit Reset */ +#define XLLF_TDFV_OFFSET 0x0c /* Transmit Vacancy */ +#define XLLF_TDFD_OFFSET 0x10 /* Transmit Data */ +#define XLLF_TLR_OFFSET 0x14 /* Transmit Length */ +#define XLLF_RDFR_OFFSET 0x18 /* Receive Reset */ +#define XLLF_RDFO_OFFSET 0x1c /* Receive Occupancy */ +#define XLLF_RDFD_OFFSET 0x20 /* Receive Data */ +#define XLLF_RLR_OFFSET 0x24 /* Receive Length */ +#define XLLF_SRR_OFFSET 0x28 /* Local Link Reset */ +#define XLLF_TDR_OFFSET 0x2C /* Transmit Destination */ +#define XLLF_RDR_OFFSET 0x30 /* Receive Destination */ -#define XLLF_ISR_OFFSET 0x00000000 /* Interrupt Status */ -#define XLLF_IER_OFFSET 0x00000004 /* Interrupt Enable */ +#define XLLF_RDFR_RESET_MASK 0xa5 /* Receive reset value */ +#define XLLF_TDFR_RESET_MASK 0xa5 /* Transmit reset value */ +#define XLLF_SRR_RESET_MASK 0xa5 /* Local Link reset value */ -#define XLLF_TDFR_OFFSET 0x00000008 /* Transmit Reset */ -#define XLLF_TDFV_OFFSET 0x0000000c /* Transmit Vacancy */ -#define XLLF_TDFD_OFFSET 0x00000010 /* Transmit Data */ -#define XLLF_TLR_OFFSET 0x00000014 /* Transmit Length */ - -#define XLLF_RDFR_OFFSET 0x00000018 /* Receive Reset */ -#define XLLF_RDFO_OFFSET 0x0000001c /* Receive Occupancy */ -#define XLLF_RDFD_OFFSET 0x00000020 /* Receive Data */ -#define XLLF_RLR_OFFSET 0x00000024 /* Receive Length */ -#define XLLF_SRR_OFFSET 0x00000028 /* Local Link Reset */ -#define XLLF_TDR_OFFSET 0x0000002C /* Transmit Destination */ -#define XLLF_RDR_OFFSET 0x00000030 /* Receive Destination */ - -/* ---------------------------- - * reset register masks - * ---------------------------- - */ - -#define XLLF_RDFR_RESET_MASK 0x000000a5 /* receive reset value */ -#define XLLF_TDFR_RESET_MASK 0x000000a5 /* Transmit reset value */ -#define XLLF_SRR_RESET_MASK 0x000000a5 /* Local Link reset value */ - -/* ---------------------------- - * interrupt masks - * ---------------------------- - */ - -#define XLLF_INT_RPURE_MASK 0x80000000 /* Receive under-read */ -#define XLLF_INT_RPORE_MASK 0x40000000 /* Receive over-read */ -#define XLLF_INT_RPUE_MASK 0x20000000 /* Receive underrun (empty) */ -#define XLLF_INT_TPOE_MASK 0x10000000 /* Transmit overrun */ -#define XLLF_INT_TC_MASK 0x08000000 /* Transmit complete */ -#define XLLF_INT_RC_MASK 0x04000000 /* Receive complete */ -#define XLLF_INT_TSE_MASK 0x02000000 /* Transmit length mismatch */ +#define XLLF_INT_RPURE_MASK BIT(31) /* Receive under-read */ +#define XLLF_INT_RPORE_MASK BIT(30) /* Receive over-read */ +#define XLLF_INT_RPUE_MASK BIT(29) /* Receive underrun (empty) */ +#define XLLF_INT_TPOE_MASK BIT(28) /* Transmit overrun */ +#define XLLF_INT_TC_MASK BIT(27) /* Transmit complete */ +#define XLLF_INT_RC_MASK BIT(26) /* Receive complete */ +#define XLLF_INT_TSE_MASK BIT(25) /* Transmit length mismatch */ #define XLLF_INT_CLEAR_ALL GENMASK(31, 0) -/* ---------------------------- - * globals - * ---------------------------- - */ -static long read_timeout = 1000; /* ms to wait before read() times out */ -static long write_timeout = 1000; /* ms to wait before write() times out */ - static DEFINE_IDA(axis_fifo_ida); -/* ---------------------------- - * module command-line arguments - * ---------------------------- - */ - -module_param(read_timeout, long, 0444); -MODULE_PARM_DESC(read_timeout, "ms to wait before blocking read() timing out; set to -1 for no timeout"); -module_param(write_timeout, long, 0444); -MODULE_PARM_DESC(write_timeout, "ms to wait before blocking write() timing out; set to -1 for no timeout"); - -/* ---------------------------- - * types - * ---------------------------- - */ - struct axis_fifo { int id; - void __iomem *base_addr; /* kernel space memory */ + void __iomem *base_addr; - unsigned int rx_fifo_depth; /* max words in the receive fifo */ - unsigned int tx_fifo_depth; /* max words in the transmit fifo */ - int has_rx_fifo; /* whether the IP has the rx fifo enabled */ - int has_tx_fifo; /* whether the IP has the tx fifo enabled */ + unsigned int rx_fifo_depth; + unsigned int tx_fifo_depth; + int has_rx_fifo; + int has_tx_fifo; - wait_queue_head_t read_queue; /* wait queue for asynchronos read */ + wait_queue_head_t read_queue; struct mutex read_lock; /* lock for reading */ - wait_queue_head_t write_queue; /* wait queue for asynchronos write */ + wait_queue_head_t write_queue; struct mutex write_lock; /* lock for writing */ - struct device *dt_device; /* device created from the device tree */ + struct device *dt_device; struct miscdevice miscdev; struct dentry *debugfs_dir; @@ -140,11 +90,6 @@ struct axis_fifo_debug_reg { unsigned int offset; }; -/* ---------------------------- - * implementation - * ---------------------------- - */ - static void reset_ip_core(struct axis_fifo *fifo) { iowrite32(XLLF_SRR_RESET_MASK, fifo->base_addr + XLLF_SRR_OFFSET); @@ -175,7 +120,7 @@ static void reset_ip_core(struct axis_fifo *fifo) static ssize_t axis_fifo_read(struct file *f, char __user *buf, size_t len, loff_t *off) { - struct axis_fifo *fifo = (struct axis_fifo *)f->private_data; + struct axis_fifo *fifo = f->private_data; size_t bytes_available; unsigned int words_available; unsigned int copied; @@ -185,10 +130,6 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, u32 tmp_buf[READ_BUF_SIZE]; if (f->f_flags & O_NONBLOCK) { - /* - * Device opened in non-blocking mode. Try to lock it and then - * check if any packet is available. - */ if (!mutex_trylock(&fifo->read_lock)) return -EAGAIN; @@ -197,38 +138,18 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, goto end_unlock; } } else { - /* opened in blocking mode - * wait for a packet available interrupt (or timeout) - * if nothing is currently available - */ mutex_lock(&fifo->read_lock); - ret = wait_event_interruptible_timeout(fifo->read_queue, - ioread32(fifo->base_addr + XLLF_RDFO_OFFSET), - read_timeout); - - if (ret <= 0) { - if (ret == 0) { - ret = -EAGAIN; - } else if (ret != -ERESTARTSYS) { - dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in read (ret=%i)\n", - ret); - } + ret = wait_event_interruptible(fifo->read_queue, + ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)); + if (ret) goto end_unlock; - } } bytes_available = ioread32(fifo->base_addr + XLLF_RLR_OFFSET); words_available = bytes_available / sizeof(u32); - if (!bytes_available) { - dev_err(fifo->dt_device, "received a packet of length 0\n"); - ret = -EIO; - goto end_unlock; - } if (bytes_available > len) { - dev_err(fifo->dt_device, "user read buffer too small (available bytes=%zu user buffer bytes=%zu)\n", - bytes_available, len); ret = -EINVAL; goto err_flush_rx; } @@ -242,9 +163,6 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, goto err_flush_rx; } - /* read data into an intermediate buffer, copying the contents - * to userspace when the buffer is full - */ copied = 0; while (words_available > 0) { copy = min(words_available, READ_BUF_SIZE); @@ -295,25 +213,13 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, static ssize_t axis_fifo_write(struct file *f, const char __user *buf, size_t len, loff_t *off) { - struct axis_fifo *fifo = (struct axis_fifo *)f->private_data; + struct axis_fifo *fifo = f->private_data; unsigned int words_to_write; u32 *txbuf; int ret; - if (len % sizeof(u32)) { - dev_err(fifo->dt_device, - "tried to send a packet that isn't word-aligned\n"); - return -EINVAL; - } - words_to_write = len / sizeof(u32); - if (!words_to_write) { - dev_err(fifo->dt_device, - "tried to send a packet of length 0\n"); - return -EINVAL; - } - /* * In 'Store-and-Forward' mode, the maximum packet that can be * transmitted is limited by the size of the FIFO, which is @@ -323,14 +229,11 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, * otherwise a 'Transmit Packet Overrun Error' interrupt will be * raised, which requires a reset of the TX circuit to recover. */ - if (words_to_write > (fifo->tx_fifo_depth - 4)) + if (!words_to_write || (len % sizeof(u32)) || + (words_to_write > (fifo->tx_fifo_depth - 4))) return -EINVAL; if (f->f_flags & O_NONBLOCK) { - /* - * Device opened in non-blocking mode. Try to lock it and then - * check if there is any room to write the given buffer. - */ if (!mutex_trylock(&fifo->write_lock)) return -EAGAIN; @@ -340,27 +243,12 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, goto end_unlock; } } else { - /* opened in blocking mode */ - - /* wait for an interrupt (or timeout) if there isn't - * currently enough room in the fifo - */ mutex_lock(&fifo->write_lock); - ret = wait_event_interruptible_timeout(fifo->write_queue, - ioread32(fifo->base_addr + XLLF_TDFV_OFFSET) - >= words_to_write, - write_timeout); - - if (ret <= 0) { - if (ret == 0) { - ret = -EAGAIN; - } else if (ret != -ERESTARTSYS) { - dev_err(fifo->dt_device, "wait_event_interruptible_timeout() error in write (ret=%i)\n", - ret); - } + ret = wait_event_interruptible(fifo->write_queue, + ioread32(fifo->base_addr + XLLF_TDFV_OFFSET) >= words_to_write); + if (ret) goto end_unlock; - } } txbuf = vmemdup_user(buf, len); @@ -372,7 +260,6 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, for (int i = 0; i < words_to_write; ++i) iowrite32(txbuf[i], fifo->base_addr + XLLF_TDFD_OFFSET); - /* write packet size to fifo */ iowrite32(len, fifo->base_addr + XLLF_TLR_OFFSET); ret = len; @@ -383,6 +270,28 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, return ret; } +static __poll_t axis_fifo_poll(struct file *f, poll_table *wait) +{ + struct axis_fifo *fifo = f->private_data; + __poll_t mask = 0; + + if (fifo->has_rx_fifo) { + poll_wait(f, &fifo->read_queue, wait); + + if (ioread32(fifo->base_addr + XLLF_RDFO_OFFSET)) + mask |= EPOLLIN | EPOLLRDNORM; + } + + if (fifo->has_tx_fifo) { + poll_wait(f, &fifo->write_queue, wait); + + if (ioread32(fifo->base_addr + XLLF_TDFV_OFFSET)) + mask |= EPOLLOUT | EPOLLWRNORM; + } + + return mask; +} + static irqreturn_t axis_fifo_irq(int irq, void *dw) { struct axis_fifo *fifo = dw; @@ -436,19 +345,12 @@ static int axis_fifo_open(struct inode *inod, struct file *f) return 0; } -static int axis_fifo_close(struct inode *inod, struct file *f) -{ - f->private_data = NULL; - - return 0; -} - static const struct file_operations fops = { .owner = THIS_MODULE, .open = axis_fifo_open, - .release = axis_fifo_close, .read = axis_fifo_read, - .write = axis_fifo_write + .write = axis_fifo_write, + .poll = axis_fifo_poll, }; static int axis_fifo_debugfs_regs_show(struct seq_file *m, void *p) @@ -548,23 +450,12 @@ static int axis_fifo_parse_dt(struct axis_fifo *fifo) static int axis_fifo_probe(struct platform_device *pdev) { - struct resource *r_mem; /* IO mem resources */ - struct device *dev = &pdev->dev; /* OS device (from device tree) */ + struct resource *r_mem; + struct device *dev = &pdev->dev; struct axis_fifo *fifo = NULL; - char *device_name; int rc = 0; /* error return value */ int irq; - /* ---------------------------- - * init wrapper device - * ---------------------------- - */ - - device_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!device_name) - return -ENOMEM; - - /* allocate device wrapper memory */ fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL); if (!fifo) return -ENOMEM; @@ -578,38 +469,20 @@ static int axis_fifo_probe(struct platform_device *pdev) mutex_init(&fifo->read_lock); mutex_init(&fifo->write_lock); - /* ---------------------------- - * init device memory space - * ---------------------------- - */ - - /* get iospace for the device and request physical memory */ fifo->base_addr = devm_platform_get_and_ioremap_resource(pdev, 0, &r_mem); if (IS_ERR(fifo->base_addr)) return PTR_ERR(fifo->base_addr); - /* ---------------------------- - * init IP - * ---------------------------- - */ - rc = axis_fifo_parse_dt(fifo); if (rc) return rc; reset_ip_core(fifo); - /* ---------------------------- - * init device interrupts - * ---------------------------- - */ - - /* get IRQ resource */ irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; - /* request IRQ */ rc = devm_request_irq(fifo->dt_device, irq, &axis_fifo_irq, 0, DRIVER_NAME, fifo); if (rc) { @@ -618,21 +491,20 @@ static int axis_fifo_probe(struct platform_device *pdev) return rc; } - /* ---------------------------- - * init char device - * ---------------------------- - */ fifo->id = ida_alloc(&axis_fifo_ida, GFP_KERNEL); if (fifo->id < 0) return fifo->id; - snprintf(device_name, 32, "%s%d", DRIVER_NAME, fifo->id); - - /* create character device */ fifo->miscdev.fops = &fops; fifo->miscdev.minor = MISC_DYNAMIC_MINOR; - fifo->miscdev.name = device_name; fifo->miscdev.parent = dev; + fifo->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "%s%d", + DRIVER_NAME, fifo->id); + if (!fifo->miscdev.name) { + ida_free(&axis_fifo_ida, fifo->id); + return -ENOMEM; + } + rc = misc_register(&fifo->miscdev); if (rc < 0) { ida_free(&axis_fifo_ida, fifo->id); @@ -673,18 +545,6 @@ static struct platform_driver axis_fifo_driver = { static int __init axis_fifo_init(void) { - if (read_timeout >= 0) - read_timeout = msecs_to_jiffies(read_timeout); - else - read_timeout = MAX_SCHEDULE_TIMEOUT; - - if (write_timeout >= 0) - write_timeout = msecs_to_jiffies(write_timeout); - else - write_timeout = MAX_SCHEDULE_TIMEOUT; - - pr_info("axis-fifo driver loaded with parameters read_timeout = %li, write_timeout = %li\n", - read_timeout, write_timeout); return platform_driver_register(&axis_fifo_driver); } diff --git a/drivers/staging/fbtft/Kconfig b/drivers/staging/fbtft/Kconfig index c2655768209a..578412a2f379 100644 --- a/drivers/staging/fbtft/Kconfig +++ b/drivers/staging/fbtft/Kconfig @@ -2,11 +2,14 @@ menuconfig FB_TFT tristate "Support for small TFT LCD display modules" depends on FB && SPI - depends on FB_DEVICE depends on BACKLIGHT_CLASS_DEVICE depends on GPIOLIB || COMPILE_TEST select FB_BACKLIGHT select FB_SYSMEM_HELPERS_DEFERRED + help + Support for small TFT LCD display modules over SPI bus. FB_DEVICE + is not required, but if enabled, provides sysfs interface for debugging + and gamma curve configuration. if FB_TFT diff --git a/drivers/staging/fbtft/fb_agm1264k-fl.c b/drivers/staging/fbtft/fb_agm1264k-fl.c index 207d578547cd..af2dbebefc72 100644 --- a/drivers/staging/fbtft/fb_agm1264k-fl.c +++ b/drivers/staging/fbtft/fb_agm1264k-fl.c @@ -283,8 +283,9 @@ static int write_vmem(struct fbtft_par *par, size_t offset, size_t len) int ret = 0; /* buffer to convert RGB565 -> grayscale16 -> Dithered image 1bpp */ - signed short *convert_buf = kmalloc_array(par->info->var.xres * - par->info->var.yres, sizeof(signed short), GFP_NOIO); + signed short *convert_buf = kmalloc_objs(signed short, + par->info->var.xres * par->info->var.yres, + GFP_NOIO); if (!convert_buf) return -ENOMEM; diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c index 8a5ccc8ae0a1..f427c0914907 100644 --- a/drivers/staging/fbtft/fbtft-core.c +++ b/drivers/staging/fbtft/fbtft-core.c @@ -365,9 +365,9 @@ static int fbtft_fb_setcolreg(unsigned int regno, unsigned int red, unsigned int val; int ret = 1; - dev_dbg(info->dev, - "%s(regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X)\n", - __func__, regno, red, green, blue, transp); + fb_dbg(info, + "regno=%u, red=0x%X, green=0x%X, blue=0x%X, trans=0x%X\n", + regno, red, green, blue, transp); switch (info->fix.visual) { case FB_VISUAL_TRUECOLOR: @@ -391,8 +391,7 @@ static int fbtft_fb_blank(int blank, struct fb_info *info) struct fbtft_par *par = info->par; int ret = -EINVAL; - dev_dbg(info->dev, "%s(blank=%d)\n", - __func__, blank); + fb_dbg(info, "blank=%d\n", blank); if (!par->fbtftops.blank) return ret; @@ -793,11 +792,11 @@ int fbtft_register_framebuffer(struct fb_info *fb_info) if (spi) sprintf(text2, ", spi%d.%d at %d MHz", spi->controller->bus_num, spi_get_chipselect(spi, 0), spi->max_speed_hz / 1000000); - dev_info(fb_info->dev, - "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n", - fb_info->fix.id, fb_info->var.xres, fb_info->var.yres, - fb_info->fix.smem_len >> 10, text1, - HZ / fb_info->fbdefio->delay, text2); + fb_dbg(fb_info, + "%s frame buffer, %dx%d, %d KiB video memory%s, fps=%lu%s\n", + fb_info->fix.id, fb_info->var.xres, fb_info->var.yres, + fb_info->fix.smem_len >> 10, text1, + HZ / fb_info->fbdefio->delay, text2); /* Turn on backlight if available */ if (fb_info->bl_dev) { diff --git a/drivers/staging/fbtft/fbtft-sysfs.c b/drivers/staging/fbtft/fbtft-sysfs.c index e45c90a03a90..d05599d80011 100644 --- a/drivers/staging/fbtft/fbtft-sysfs.c +++ b/drivers/staging/fbtft/fbtft-sysfs.c @@ -203,14 +203,26 @@ static struct device_attribute debug_device_attr = void fbtft_sysfs_init(struct fbtft_par *par) { - device_create_file(par->info->dev, &debug_device_attr); + struct device *dev; + + dev = dev_of_fbinfo(par->info); + if (!dev) + return; + + device_create_file(dev, &debug_device_attr); if (par->gamma.curves && par->fbtftops.set_gamma) - device_create_file(par->info->dev, &gamma_device_attrs[0]); + device_create_file(dev, &gamma_device_attrs[0]); } void fbtft_sysfs_exit(struct fbtft_par *par) { - device_remove_file(par->info->dev, &debug_device_attr); + struct device *dev; + + dev = dev_of_fbinfo(par->info); + if (!dev) + return; + + device_remove_file(dev, &debug_device_attr); if (par->gamma.curves && par->fbtftops.set_gamma) - device_remove_file(par->info->dev, &gamma_device_attrs[0]); + device_remove_file(dev, &gamma_device_attrs[0]); } diff --git a/drivers/staging/greybus/TODO b/drivers/staging/greybus/TODO index 6461e0132fe3..e69de29bb2d1 100644 --- a/drivers/staging/greybus/TODO +++ b/drivers/staging/greybus/TODO @@ -1,5 +0,0 @@ -* Convert all uses of the old GPIO API from to the - GPIO descriptor API in and look up GPIO - lines from device tree or ACPI. -* Make pwm.c use the struct pwm_ops::apply instead of ::config, ::set_polarity, - ::enable and ::disable. diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index 90ab32638d3f..33f26a65f0cc 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -10,13 +10,14 @@ #include #include #include -#include #include #include #include #include +#include #include #include +#include #include "arche_platform.h" static void apb_bootret_deassert(struct device *dev); @@ -314,8 +315,8 @@ static ssize_t state_show(struct device *dev, static DEVICE_ATTR_RW(state); -static int apb_ctrl_get_devtree_data(struct platform_device *pdev, - struct arche_apb_ctrl_drvdata *apb) +static int apb_ctrl_get_fw_data(struct platform_device *pdev, + struct arche_apb_ctrl_drvdata *apb) { struct device *dev = &pdev->dev; int ret; @@ -378,7 +379,7 @@ static int apb_ctrl_get_devtree_data(struct platform_device *pdev, } /* Only applicable for platform >= V2 */ - if (of_property_read_bool(pdev->dev.of_node, "gb,spi-en-active-high")) + if (device_property_read_bool(&pdev->dev, "gb,spi-en-active-high")) apb->spi_en_polarity_high = true; return 0; @@ -394,7 +395,7 @@ static int arche_apb_ctrl_probe(struct platform_device *pdev) if (!apb) return -ENOMEM; - ret = apb_ctrl_get_devtree_data(pdev, apb); + ret = apb_ctrl_get_fw_data(pdev, apb); if (ret) { dev_err(dev, "failed to get apb devicetree data %d\n", ret); return ret; @@ -403,7 +404,7 @@ static int arche_apb_ctrl_probe(struct platform_device *pdev) /* Initially set APB to OFF state */ apb->state = ARCHE_PLATFORM_STATE_OFF; /* Check whether device needs to be enabled on boot */ - if (of_property_read_bool(pdev->dev.of_node, "arche,init-disable")) + if (device_property_read_bool(&pdev->dev, "arche,init-disable")) apb->init_disabled = true; platform_set_drvdata(pdev, apb); diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index d48464390f58..f669a7e2eb11 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -523,10 +523,9 @@ static int arche_platform_probe(struct platform_device *pdev) arche_pdata->pm_notifier.notifier_call = arche_platform_pm_notifier; ret = register_pm_notifier(&arche_pdata->pm_notifier); - if (ret) { dev_err(dev, "failed to register pm notifier %d\n", ret); - goto err_device_remove; + goto err_depopulate; } /* Explicitly power off if requested */ @@ -534,8 +533,9 @@ static int arche_platform_probe(struct platform_device *pdev) mutex_lock(&arche_pdata->platform_state_mutex); ret = arche_platform_coldboot_seq(arche_pdata); if (ret) { + mutex_unlock(&arche_pdata->platform_state_mutex); dev_err(dev, "Failed to cold boot svc %d\n", ret); - goto err_coldboot; + goto err_unregister_pm_notifier; } arche_platform_wd_irq_en(arche_pdata); mutex_unlock(&arche_pdata->platform_state_mutex); @@ -544,29 +544,22 @@ static int arche_platform_probe(struct platform_device *pdev) dev_info(dev, "Device registered successfully\n"); return 0; -err_coldboot: - mutex_unlock(&arche_pdata->platform_state_mutex); +err_unregister_pm_notifier: + unregister_pm_notifier(&arche_pdata->pm_notifier); +err_depopulate: + of_platform_depopulate(dev); err_device_remove: device_remove_file(&pdev->dev, &dev_attr_state); return ret; } -static int arche_remove_child(struct device *dev, void *unused) -{ - struct platform_device *pdev = to_platform_device(dev); - - platform_device_unregister(pdev); - - return 0; -} - static void arche_platform_remove(struct platform_device *pdev) { struct arche_platform_drvdata *arche_pdata = platform_get_drvdata(pdev); unregister_pm_notifier(&arche_pdata->pm_notifier); device_remove_file(&pdev->dev, &dev_attr_state); - device_for_each_child(&pdev->dev, NULL, arche_remove_child); + of_platform_depopulate(&pdev->dev); arche_platform_poweroff_seq(arche_pdata); if (usb3613_hub_mode_ctrl(false)) @@ -576,10 +569,10 @@ static void arche_platform_remove(struct platform_device *pdev) static __maybe_unused int arche_platform_suspend(struct device *dev) { /* - * If timing profile premits, we may shutdown bridge + * If timing profile permits, we may shutdown bridge * completely * - * TODO: sequence ?? + * TODO: define shutdown sequence * * Also, need to make sure we meet precondition for unipro suspend * Precondition: Definition ??? diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index 4a4dfb42f50f..e87b82ca6d8a 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -188,7 +188,7 @@ int gb_audio_manager_module_create(struct gb_audio_manager_module **module, int err; struct gb_audio_manager_module *m; - m = kzalloc(sizeof(*m), GFP_ATOMIC); + m = kzalloc_obj(*m, GFP_ATOMIC); if (!m) return -ENOMEM; diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c index d53e58f92e81..97b9937bbdc1 100644 --- a/drivers/staging/greybus/authentication.c +++ b/drivers/staging/greybus/authentication.c @@ -306,7 +306,7 @@ int gb_cap_connection_init(struct gb_connection *connection) if (!connection) return 0; - cap = kzalloc(sizeof(*cap), GFP_KERNEL); + cap = kzalloc_obj(*cap); if (!cap) return -ENOMEM; diff --git a/drivers/staging/greybus/bootrom.c b/drivers/staging/greybus/bootrom.c index d4d86b3898de..83921d90c322 100644 --- a/drivers/staging/greybus/bootrom.c +++ b/drivers/staging/greybus/bootrom.c @@ -424,7 +424,7 @@ static int gb_bootrom_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_BOOTROM) return -ENODEV; - bootrom = kzalloc(sizeof(*bootrom), GFP_KERNEL); + bootrom = kzalloc_obj(*bootrom); if (!bootrom) return -ENOMEM; diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index 5ac19c0055d9..62b55bb28408 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -791,7 +791,7 @@ static int gb_camera_op_configure_streams(void *priv, unsigned int *nstreams, if (gb_nstreams > GB_CAMERA_MAX_STREAMS) return -EINVAL; - gb_streams = kcalloc(gb_nstreams, sizeof(*gb_streams), GFP_KERNEL); + gb_streams = kzalloc_objs(*gb_streams, gb_nstreams); if (!gb_streams) return -ENOMEM; @@ -932,7 +932,7 @@ static ssize_t gb_camera_debugfs_configure_streams(struct gb_camera *gcam, return ret; /* For each stream to configure parse width, height and format */ - streams = kcalloc(nstreams, sizeof(*streams), GFP_KERNEL); + streams = kzalloc_objs(*streams, nstreams); if (!streams) return -ENOMEM; @@ -1244,7 +1244,7 @@ static int gb_camera_probe(struct gb_bundle *bundle, if (!mgmt_cport_id || !data_cport_id) return -ENODEV; - gcam = kzalloc(sizeof(*gcam), GFP_KERNEL); + gcam = kzalloc_obj(*gcam); if (!gcam) return -ENOMEM; diff --git a/drivers/staging/greybus/fw-core.c b/drivers/staging/greybus/fw-core.c index 0fb15a60412f..2016a74f137f 100644 --- a/drivers/staging/greybus/fw-core.c +++ b/drivers/staging/greybus/fw-core.c @@ -68,7 +68,7 @@ static int gb_fw_core_probe(struct gb_bundle *bundle, u16 cport_id; u8 protocol_id; - fw_core = kzalloc(sizeof(*fw_core), GFP_KERNEL); + fw_core = kzalloc_obj(*fw_core); if (!fw_core) return -ENOMEM; diff --git a/drivers/staging/greybus/fw-download.c b/drivers/staging/greybus/fw-download.c index 9a09bd3af79b..a0a683447b3d 100644 --- a/drivers/staging/greybus/fw-download.c +++ b/drivers/staging/greybus/fw-download.c @@ -165,7 +165,7 @@ static struct fw_request *find_firmware(struct fw_download *fw_download, struct fw_request *fw_req; int ret, req_count; - fw_req = kzalloc(sizeof(*fw_req), GFP_KERNEL); + fw_req = kzalloc_obj(*fw_req); if (!fw_req) return ERR_PTR(-ENOMEM); @@ -409,7 +409,7 @@ int gb_fw_download_connection_init(struct gb_connection *connection) if (!connection) return 0; - fw_download = kzalloc(sizeof(*fw_download), GFP_KERNEL); + fw_download = kzalloc_obj(*fw_download); if (!fw_download) return -ENOMEM; diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index 152949c23d65..5d01da6b6eb9 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -577,7 +577,7 @@ int gb_fw_mgmt_connection_init(struct gb_connection *connection) if (!connection) return 0; - fw_mgmt = kzalloc(sizeof(*fw_mgmt), GFP_KERNEL); + fw_mgmt = kzalloc_obj(*fw_mgmt); if (!fw_mgmt) return -ENOMEM; diff --git a/drivers/staging/greybus/gb-camera.h b/drivers/staging/greybus/gb-camera.h index 3e09147435a5..d5a33a13f2a4 100644 --- a/drivers/staging/greybus/gb-camera.h +++ b/drivers/staging/greybus/gb-camera.h @@ -10,9 +10,9 @@ #include /* Input flags need to be set from the caller */ -#define GB_CAMERA_IN_FLAG_TEST (1 << 0) +#define GB_CAMERA_IN_FLAG_TEST BIT(0) /* Output flags returned */ -#define GB_CAMERA_OUT_FLAG_ADJUSTED (1 << 0) +#define GB_CAMERA_OUT_FLAG_ADJUSTED BIT(0) /** * struct gb_camera_stream - Represents greybus camera stream. @@ -89,8 +89,9 @@ struct gb_camera_csi_params { struct gb_camera_ops { ssize_t (*capabilities)(void *priv, char *buf, size_t len); int (*configure_streams)(void *priv, unsigned int *nstreams, - unsigned int *flags, struct gb_camera_stream *streams, - struct gb_camera_csi_params *csi_params); + unsigned int *flags, + struct gb_camera_stream *streams, + struct gb_camera_csi_params *csi_params); int (*capture)(void *priv, u32 request_id, unsigned int streams, unsigned int num_frames, size_t settings_size, const void *settings); diff --git a/drivers/staging/greybus/gbphy.c b/drivers/staging/greybus/gbphy.c index 60cf09a302a7..bdb0f5164a6f 100644 --- a/drivers/staging/greybus/gbphy.c +++ b/drivers/staging/greybus/gbphy.c @@ -229,7 +229,7 @@ static struct gbphy_device *gb_gbphy_create_dev(struct gb_bundle *bundle, if (id < 0) return ERR_PTR(id); - gbphy_dev = kzalloc(sizeof(*gbphy_dev), GFP_KERNEL); + gbphy_dev = kzalloc_obj(*gbphy_dev); if (!gbphy_dev) { ida_free(&gbphy_id, id); return ERR_PTR(-ENOMEM); @@ -282,7 +282,7 @@ static int gb_gbphy_probe(struct gb_bundle *bundle, if (bundle->num_cports == 0) return -ENODEV; - gbphy_host = kzalloc(sizeof(*gbphy_host), GFP_KERNEL); + gbphy_host = kzalloc_obj(*gbphy_host); if (!gbphy_host) return -ENOMEM; diff --git a/drivers/staging/greybus/gpio.c b/drivers/staging/greybus/gpio.c index ac62b932e6a4..12185f7a982c 100644 --- a/drivers/staging/greybus/gpio.c +++ b/drivers/staging/greybus/gpio.c @@ -485,8 +485,7 @@ static int gb_gpio_controller_setup(struct gb_gpio_controller *ggc) if (ret) return ret; - ggc->lines = kcalloc(ggc->line_max + 1, sizeof(*ggc->lines), - GFP_KERNEL); + ggc->lines = kzalloc_objs(*ggc->lines, ggc->line_max + 1); if (!ggc->lines) return -ENOMEM; @@ -503,7 +502,7 @@ static int gb_gpio_probe(struct gbphy_device *gbphy_dev, struct irq_chip *irqc; int ret; - ggc = kzalloc(sizeof(*ggc), GFP_KERNEL); + ggc = kzalloc_obj(*ggc); if (!ggc) return -ENOMEM; diff --git a/drivers/staging/greybus/hid.c b/drivers/staging/greybus/hid.c index 63c77a3df591..1f58c907c036 100644 --- a/drivers/staging/greybus/hid.c +++ b/drivers/staging/greybus/hid.c @@ -434,7 +434,7 @@ static int gb_hid_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_HID) return -ENODEV; - ghid = kzalloc(sizeof(*ghid), GFP_KERNEL); + ghid = kzalloc_obj(*ghid); if (!ghid) return -ENOMEM; diff --git a/drivers/staging/greybus/i2c.c b/drivers/staging/greybus/i2c.c index 14f1ff6d448c..7b6f42113065 100644 --- a/drivers/staging/greybus/i2c.c +++ b/drivers/staging/greybus/i2c.c @@ -235,7 +235,7 @@ static int gb_i2c_probe(struct gbphy_device *gbphy_dev, struct i2c_adapter *adapter; int ret; - gb_i2c_dev = kzalloc(sizeof(*gb_i2c_dev), GFP_KERNEL); + gb_i2c_dev = kzalloc_obj(*gb_i2c_dev); if (!gb_i2c_dev) return -ENOMEM; diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index e509fdc715db..cab02b5da867 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -269,14 +269,13 @@ static int channel_attr_groups_set(struct gb_channel *channel, return 0; /* Set attributes based in the channel flags */ - channel->attrs = kcalloc(size + 1, sizeof(*channel->attrs), GFP_KERNEL); + channel->attrs = kzalloc_objs(*channel->attrs, size + 1); if (!channel->attrs) return -ENOMEM; - channel->attr_group = kzalloc(sizeof(*channel->attr_group), GFP_KERNEL); + channel->attr_group = kzalloc_obj(*channel->attr_group); if (!channel->attr_group) return -ENOMEM; - channel->attr_groups = kcalloc(2, sizeof(*channel->attr_groups), - GFP_KERNEL); + channel->attr_groups = kzalloc_objs(*channel->attr_groups, 2); if (!channel->attr_groups) return -ENOMEM; @@ -1008,14 +1007,17 @@ static int gb_lights_light_config(struct gb_lights *glights, u8 id) if (!strlen(conf.name)) return -EINVAL; - light->channels_count = conf.channel_count; light->name = kstrndup(conf.name, NAMES_MAX, GFP_KERNEL); if (!light->name) return -ENOMEM; - light->channels = kcalloc(light->channels_count, - sizeof(struct gb_channel), GFP_KERNEL); + light->channels = kzalloc_objs(struct gb_channel, conf.channel_count); if (!light->channels) return -ENOMEM; + /* + * Publish channels_count only after channels allocation so cleanup + * doesn't walk a NULL channels pointer on allocation failure. + */ + light->channels_count = conf.channel_count; /* First we collect all the configurations for all channels */ for (i = 0; i < light->channels_count; i++) { @@ -1149,8 +1151,7 @@ static int gb_lights_create_all(struct gb_lights *glights) if (ret < 0) goto out; - glights->lights = kcalloc(glights->lights_count, - sizeof(struct gb_light), GFP_KERNEL); + glights->lights = kzalloc_objs(struct gb_light, glights->lights_count); if (!glights->lights) { ret = -ENOMEM; goto out; @@ -1258,7 +1259,7 @@ static int gb_lights_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LIGHTS) return -ENODEV; - glights = kzalloc(sizeof(*glights), GFP_KERNEL); + glights = kzalloc_obj(*glights); if (!glights) return -ENOMEM; diff --git a/drivers/staging/greybus/log.c b/drivers/staging/greybus/log.c index 57dcf9453bf1..815d20ba9b6b 100644 --- a/drivers/staging/greybus/log.c +++ b/drivers/staging/greybus/log.c @@ -77,7 +77,7 @@ static int gb_log_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LOG) return -ENODEV; - log = kzalloc(sizeof(*log), GFP_KERNEL); + log = kzalloc_obj(*log); if (!log) return -ENOMEM; diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 1f19323b0e1a..aa9c73cb0ae5 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -471,7 +471,7 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type, struct gb_operation *operation; int ret; - op_async = kzalloc(sizeof(*op_async), GFP_KERNEL); + op_async = kzalloc_obj(*op_async); if (!op_async) return -ENOMEM; @@ -989,7 +989,7 @@ static int gb_loopback_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_LOOPBACK) return -ENODEV; - gb = kzalloc(sizeof(*gb), GFP_KERNEL); + gb = kzalloc_obj(*gb); if (!gb) return -ENOMEM; diff --git a/drivers/staging/greybus/power_supply.c b/drivers/staging/greybus/power_supply.c index a484c0ca058d..33b7a63979d6 100644 --- a/drivers/staging/greybus/power_supply.c +++ b/drivers/staging/greybus/power_supply.c @@ -545,15 +545,14 @@ static int gb_power_supply_prop_descriptors_get(struct gb_power_supply *gbpsy) } } - gbpsy->props = kcalloc(gbpsy->properties_count, sizeof(*gbpsy->props), - GFP_KERNEL); + gbpsy->props = kzalloc_objs(*gbpsy->props, gbpsy->properties_count); if (!gbpsy->props) { ret = -ENOMEM; goto out_put_operation; } - gbpsy->props_raw = kcalloc(gbpsy->properties_count, - sizeof(*gbpsy->props_raw), GFP_KERNEL); + gbpsy->props_raw = kzalloc_objs(*gbpsy->props_raw, + gbpsy->properties_count); if (!gbpsy->props_raw) { ret = -ENOMEM; goto out_put_operation; @@ -942,9 +941,8 @@ static int gb_power_supplies_setup(struct gb_power_supplies *supplies) if (ret < 0) goto out; - supplies->supply = kcalloc(supplies->supplies_count, - sizeof(struct gb_power_supply), - GFP_KERNEL); + supplies->supply = kzalloc_objs(struct gb_power_supply, + supplies->supplies_count); if (!supplies->supply) { ret = -ENOMEM; @@ -1064,7 +1062,7 @@ static int gb_power_supply_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_POWER_SUPPLY) return -ENODEV; - supplies = kzalloc(sizeof(*supplies), GFP_KERNEL); + supplies = kzalloc_obj(*supplies); if (!supplies) return -ENOMEM; diff --git a/drivers/staging/greybus/raw.c b/drivers/staging/greybus/raw.c index 71de6776739c..3027a2c25bcd 100644 --- a/drivers/staging/greybus/raw.c +++ b/drivers/staging/greybus/raw.c @@ -73,7 +73,7 @@ static int receive_data(struct gb_raw *raw, u32 len, u8 *data) goto exit; } - raw_data = kmalloc(struct_size(raw_data, data, len), GFP_KERNEL); + raw_data = kmalloc_flex(*raw_data, data, len); if (!raw_data) { retval = -ENOMEM; goto exit; @@ -164,7 +164,7 @@ static int gb_raw_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_RAW) return -ENODEV; - raw = kzalloc(sizeof(*raw), GFP_KERNEL); + raw = kzalloc_obj(*raw); if (!raw) return -ENOMEM; diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index 5326ea372b24..12c36a5e1d8c 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c @@ -806,7 +806,7 @@ static int gb_sdio_probe(struct gbphy_device *gbphy_dev, mutex_init(&host->lock); spin_lock_init(&host->xfer); - host->mrq_workqueue = alloc_workqueue("mmc-%s", 0, 1, + host->mrq_workqueue = alloc_workqueue("mmc-%s", WQ_PERCPU, 1, dev_name(&gbphy_dev->dev)); if (!host->mrq_workqueue) { ret = -ENOMEM; diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 5cece0a6606f..7d060b4cd33d 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -823,7 +823,7 @@ static int gb_uart_probe(struct gbphy_device *gbphy_dev, goto exit_connection_destroy; } - gb_tty = kzalloc(sizeof(*gb_tty), GFP_KERNEL); + gb_tty = kzalloc_obj(*gb_tty); if (!gb_tty) { retval = -ENOMEM; goto exit_connection_destroy; diff --git a/drivers/staging/greybus/vibrator.c b/drivers/staging/greybus/vibrator.c index ee112aa13ff1..0ec4d317c9db 100644 --- a/drivers/staging/greybus/vibrator.c +++ b/drivers/staging/greybus/vibrator.c @@ -128,7 +128,7 @@ static int gb_vibrator_probe(struct gb_bundle *bundle, if (cport_desc->protocol_id != GREYBUS_PROTOCOL_VIBRATOR) return -ENODEV; - vib = kzalloc(sizeof(*vib), GFP_KERNEL); + vib = kzalloc_obj(*vib); if (!vib) return -ENOMEM; diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index f45968ef94ea..3bdaee925dee 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -136,7 +136,7 @@ static struct i2c_driver adt7316_driver = { .driver = { .name = "adt7316", .of_match_table = adt7316_of_match, - .pm = ADT7316_PM_OPS, + .pm = pm_sleep_ptr(&adt7316_pm_ops), }, .probe = adt7316_i2c_probe, .id_table = adt7316_i2c_id, diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c index af513e003da7..f91325d11394 100644 --- a/drivers/staging/iio/addac/adt7316-spi.c +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -142,7 +142,7 @@ static struct spi_driver adt7316_driver = { .driver = { .name = "adt7316", .of_match_table = adt7316_of_spi_match, - .pm = ADT7316_PM_OPS, + .pm = pm_sleep_ptr(&adt7316_pm_ops), }, .probe = adt7316_spi_probe, .id_table = adt7316_spi_id, diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 8a9a8262c2be..59fb3bd26bc1 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -2082,7 +2082,6 @@ static const struct attribute_group adt7516_event_attribute_group = { .name = "events", }; -#ifdef CONFIG_PM_SLEEP static int adt7316_disable(struct device *dev) { struct iio_dev *dev_info = dev_get_drvdata(dev); @@ -2098,9 +2097,8 @@ static int adt7316_enable(struct device *dev) return _adt7316_store_enabled(chip, 1); } -EXPORT_SYMBOL_GPL(adt7316_pm_ops); -SIMPLE_DEV_PM_OPS(adt7316_pm_ops, adt7316_disable, adt7316_enable); -#endif + +EXPORT_GPL_SIMPLE_DEV_PM_OPS(adt7316_pm_ops, adt7316_disable, adt7316_enable); static const struct iio_info adt7316_info = { .attrs = &adt7316_attribute_group, diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h index 8c2a92ae7157..f208f0d3583a 100644 --- a/drivers/staging/iio/addac/adt7316.h +++ b/drivers/staging/iio/addac/adt7316.h @@ -22,12 +22,8 @@ struct adt7316_bus { int (*multi_write)(void *client, u8 first_reg, u8 count, u8 *data); }; -#ifdef CONFIG_PM_SLEEP extern const struct dev_pm_ops adt7316_pm_ops; -#define ADT7316_PM_OPS (&adt7316_pm_ops) -#else -#define ADT7316_PM_OPS NULL -#endif + int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); diff --git a/drivers/staging/iio/frequency/ad9832.c b/drivers/staging/iio/frequency/ad9832.c index 49388da5a684..b87ea1781b27 100644 --- a/drivers/staging/iio/frequency/ad9832.c +++ b/drivers/staging/iio/frequency/ad9832.c @@ -23,12 +23,9 @@ #include #include -#include "ad9832.h" - #include "dds.h" /* Registers */ - #define AD9832_FREQ0LL 0x0 #define AD9832_FREQ0HL 0x1 #define AD9832_FREQ0LM 0x2 @@ -45,14 +42,12 @@ #define AD9832_PHASE2H 0xD #define AD9832_PHASE3L 0xE #define AD9832_PHASE3H 0xF - #define AD9832_PHASE_SYM 0x10 #define AD9832_FREQ_SYM 0x11 #define AD9832_PINCTRL_EN 0x12 #define AD9832_OUTPUT_EN 0x13 /* Command Control Bits */ - #define AD9832_CMD_PHA8BITSW 0x1 #define AD9832_CMD_PHA16BITSW 0x0 #define AD9832_CMD_FRE8BITSW 0x3 @@ -92,7 +87,6 @@ * @phase_data: tuning word spi transmit buffer * @freq_data: tuning word spi transmit buffer */ - struct ad9832_state { struct spi_device *spi; struct clk *mclk; @@ -299,16 +293,10 @@ static const struct iio_info ad9832_info = { static int ad9832_probe(struct spi_device *spi) { - struct ad9832_platform_data *pdata = dev_get_platdata(&spi->dev); struct iio_dev *indio_dev; struct ad9832_state *st; int ret; - if (!pdata) { - dev_dbg(&spi->dev, "no platform data?\n"); - return -ENODEV; - } - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); if (!indio_dev) return -ENOMEM; @@ -335,7 +323,6 @@ static int ad9832_probe(struct spi_device *spi) indio_dev->modes = INDIO_DIRECT_MODE; /* Setup default messages */ - st->xfer.tx_buf = &st->data; st->xfer.len = 2; @@ -379,30 +366,6 @@ static int ad9832_probe(struct spi_device *spi) return ret; } - ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0); - if (ret) - return ret; - - ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1); - if (ret) - return ret; - - ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0); - if (ret) - return ret; - - ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1); - if (ret) - return ret; - - ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2); - if (ret) - return ret; - - ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3); - if (ret) - return ret; - return devm_iio_device_register(&spi->dev, indio_dev); } diff --git a/drivers/staging/iio/frequency/ad9832.h b/drivers/staging/iio/frequency/ad9832.h deleted file mode 100644 index d0d840edb8d2..000000000000 --- a/drivers/staging/iio/frequency/ad9832.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * AD9832 SPI DDS driver - * - * Copyright 2011 Analog Devices Inc. - */ -#ifndef IIO_DDS_AD9832_H_ -#define IIO_DDS_AD9832_H_ - -/* - * TODO: struct ad9832_platform_data needs to go into include/linux/iio - */ - -/** - * struct ad9832_platform_data - platform specific information - * @freq0: power up freq0 tuning word in Hz - * @freq1: power up freq1 tuning word in Hz - * @phase0: power up phase0 value [0..4095] correlates with 0..2PI - * @phase1: power up phase1 value [0..4095] correlates with 0..2PI - * @phase2: power up phase2 value [0..4095] correlates with 0..2PI - * @phase3: power up phase3 value [0..4095] correlates with 0..2PI - */ - -struct ad9832_platform_data { - unsigned long freq0; - unsigned long freq1; - unsigned short phase0; - unsigned short phase1; - unsigned short phase2; - unsigned short phase3; -}; - -#endif /* IIO_DDS_AD9832_H_ */ diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c index 6050637a0def..d3414312e1de 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c @@ -794,7 +794,7 @@ static int gc2235_probe(struct i2c_client *client) int ret; unsigned int i; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c index a4519babf37d..2c41c496daa6 100644 --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2722.c @@ -952,7 +952,7 @@ static int ov2722_probe(struct i2c_client *client) void *ovpdev; int ret; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c index a3cd9d3e9ce7..fec369575d88 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c +++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c @@ -2960,7 +2960,7 @@ int atomisp_set_parameters(struct video_device *vdev, * are ready, the parameters will be set to CSS. * per-frame setting only works for the main output frame. */ - param = kvzalloc(sizeof(*param), GFP_KERNEL); + param = kvzalloc_obj(*param); if (!param) return -ENOMEM; css_param = ¶m->params; diff --git a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c index 2a90f86e515f..ba61cc28fac1 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c +++ b/drivers/staging/media/atomisp/pci/atomisp_csi2_bridge.c @@ -305,8 +305,8 @@ static int atomisp_csi2_add_gpio_mappings(struct acpi_device *adev) int ret; /* Max num GPIOs we've seen plus a terminator */ - int3472 = kzalloc(struct_size(int3472, gpios.table, INT3472_MAX_SENSOR_GPIOS + 1), - GFP_KERNEL); + int3472 = kzalloc_flex(*int3472, gpios.table, + INT3472_MAX_SENSOR_GPIOS + 1); if (!int3472) return -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c index 964cc3bcc0ac..4026e98c5845 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c +++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c @@ -969,7 +969,7 @@ static int camera_sensor_csi_alloc(struct v4l2_subdev *sd, u32 port, u32 lanes, struct i2c_client *client = v4l2_get_subdevdata(sd); struct camera_mipi_info *csi; - csi = kzalloc(sizeof(*csi), GFP_KERNEL); + csi = kzalloc_obj(*csi); if (!csi) return -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c index bb8b2f2213b0..a7f22de1c889 100644 --- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c +++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c @@ -696,7 +696,7 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL; dev_dbg(isp->dev, "allocating %d 3a buffers\n", count); while (count--) { - s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL); + s3a_buf = kzalloc_obj(struct atomisp_s3a_buf); if (!s3a_buf) goto error; @@ -715,7 +715,7 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, count = ATOMISP_CSS_Q_DEPTH + 1; dev_dbg(isp->dev, "allocating %d dis buffers\n", count); while (count--) { - dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL); + dis_buf = kzalloc_obj(struct atomisp_dis_buf); if (!dis_buf) goto error; if (atomisp_css_allocate_stat_buffers( @@ -737,8 +737,7 @@ int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n", count, i); while (count--) { - md_buf = kzalloc(sizeof(struct atomisp_metadata_buf), - GFP_KERNEL); + md_buf = kzalloc_obj(struct atomisp_metadata_buf); if (!md_buf) goto error; diff --git a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c index 5d0cd5260d3a..856561e951a5 100644 --- a/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c +++ b/drivers/staging/media/atomisp/pci/hmm/hmm_bo.c @@ -676,7 +676,7 @@ int hmm_bo_alloc_pages(struct hmm_buffer_object *bo, mutex_lock(&bo->mutex); check_bo_status_no_goto(bo, HMM_BO_PAGE_ALLOCED, status_err); - bo->pages = kcalloc(bo->pgnr, sizeof(struct page *), GFP_KERNEL); + bo->pages = kzalloc_objs(struct page *, bo->pgnr); if (unlikely(!bo->pages)) { ret = -ENOMEM; goto alloc_err; diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c index a1bea8bd1a39..bd2def6c341a 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.c @@ -309,7 +309,7 @@ ia_css_isp_dvs_statistics_allocate( if (!grid->enable) return NULL; - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -350,7 +350,7 @@ ia_css_isp_dvs_statistics_map_allocate( * so we use a local char * instead. */ char *base_ptr; - me = kvmalloc(sizeof(*me), GFP_KERNEL); + me = kvmalloc_obj(*me); if (!me) { IA_CSS_LOG("cannot allocate memory"); goto err; diff --git a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c index 027eae0ca69e..4a38d678f334 100644 --- a/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c +++ b/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c @@ -274,7 +274,7 @@ ia_css_isp_dvs2_statistics_allocate( if (!grid->enable) return NULL; - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; diff --git a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c index 2cb96f9a6030..8614efc28b19 100644 --- a/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c +++ b/drivers/staging/media/atomisp/pci/runtime/frame/src/frame.c @@ -650,7 +650,7 @@ static struct ia_css_frame *frame_create(unsigned int width, unsigned int raw_bit_depth, bool valid) { - struct ia_css_frame *me = kvmalloc(sizeof(*me), GFP_KERNEL); + struct ia_css_frame *me = kvmalloc_obj(*me); if (!me) return NULL; diff --git a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c index cb8d652227a7..0470871f8fff 100644 --- a/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c +++ b/drivers/staging/media/atomisp/pci/runtime/pipeline/src/pipeline.c @@ -579,7 +579,7 @@ static int pipeline_stage_create( out_frame[i] = stage_desc->out_frame[i]; } - stage = kvzalloc(sizeof(*stage), GFP_KERNEL); + stage = kvzalloc_obj(*stage); if (!stage) { err = -ENOMEM; goto ERR; diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c index 73bd87f43a8c..6cda5925fa45 100644 --- a/drivers/staging/media/atomisp/pci/sh_css.c +++ b/drivers/staging/media/atomisp/pci/sh_css.c @@ -1880,7 +1880,7 @@ create_pipe(enum ia_css_pipe_mode mode, return -EINVAL; } - me = kmalloc(sizeof(*me), GFP_KERNEL); + me = kmalloc_obj(*me); if (!me) return -ENOMEM; @@ -4530,16 +4530,15 @@ static int load_video_binaries(struct ia_css_pipe *pipe) if (err) return err; mycs->num_yuv_scaler = cas_scaler_descr.num_stage; - mycs->yuv_scaler_binary = kcalloc(cas_scaler_descr.num_stage, - sizeof(struct ia_css_binary), - GFP_KERNEL); + mycs->yuv_scaler_binary = kzalloc_objs(struct ia_css_binary, + cas_scaler_descr.num_stage); if (!mycs->yuv_scaler_binary) { mycs->num_yuv_scaler = 0; err = -ENOMEM; return err; } - mycs->is_output_stage = kcalloc(cas_scaler_descr.num_stage, - sizeof(bool), GFP_KERNEL); + mycs->is_output_stage = kzalloc_objs(bool, + cas_scaler_descr.num_stage); if (!mycs->is_output_stage) { err = -ENOMEM; return err; @@ -5110,16 +5109,15 @@ static int load_primary_binaries( return err; } mycs->num_yuv_scaler = cas_scaler_descr.num_stage; - mycs->yuv_scaler_binary = kcalloc(cas_scaler_descr.num_stage, - sizeof(struct ia_css_binary), - GFP_KERNEL); + mycs->yuv_scaler_binary = kzalloc_objs(struct ia_css_binary, + cas_scaler_descr.num_stage); if (!mycs->yuv_scaler_binary) { err = -ENOMEM; IA_CSS_LEAVE_ERR_PRIVATE(err); return err; } - mycs->is_output_stage = kcalloc(cas_scaler_descr.num_stage, - sizeof(bool), GFP_KERNEL); + mycs->is_output_stage = kzalloc_objs(bool, + cas_scaler_descr.num_stage); if (!mycs->is_output_stage) { err = -ENOMEM; IA_CSS_LEAVE_ERR_PRIVATE(err); @@ -5970,9 +5968,8 @@ ia_css_pipe_create_cas_scaler_desc(struct ia_css_pipe *pipe, descr->num_stage = num_stages; - descr->in_info = kmalloc_array(descr->num_stage, - sizeof(struct ia_css_frame_info), - GFP_KERNEL); + descr->in_info = kmalloc_objs(struct ia_css_frame_info, + descr->num_stage); if (!descr->in_info) { err = -ENOMEM; goto ERR; @@ -6143,15 +6140,14 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) goto ERR; mycs->num_output = cas_scaler_descr.num_output_stage; mycs->num_yuv_scaler = cas_scaler_descr.num_stage; - mycs->yuv_scaler_binary = kcalloc(cas_scaler_descr.num_stage, - sizeof(struct ia_css_binary), - GFP_KERNEL); + mycs->yuv_scaler_binary = kzalloc_objs(struct ia_css_binary, + cas_scaler_descr.num_stage); if (!mycs->yuv_scaler_binary) { err = -ENOMEM; goto ERR; } - mycs->is_output_stage = kcalloc(cas_scaler_descr.num_stage, - sizeof(bool), GFP_KERNEL); + mycs->is_output_stage = kzalloc_objs(bool, + cas_scaler_descr.num_stage); if (!mycs->is_output_stage) { err = -ENOMEM; goto ERR; @@ -6250,9 +6246,7 @@ load_yuvpp_binaries(struct ia_css_pipe *pipe) mycs->num_vf_pp = 1; } - mycs->vf_pp_binary = kcalloc(mycs->num_vf_pp, - sizeof(struct ia_css_binary), - GFP_KERNEL); + mycs->vf_pp_binary = kzalloc_objs(struct ia_css_binary, mycs->num_vf_pp); if (!mycs->vf_pp_binary) { err = -ENOMEM; goto ERR; @@ -7909,7 +7903,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, } /* allocate the stream instance */ - curr_stream = kzalloc(sizeof(struct ia_css_stream), GFP_KERNEL); + curr_stream = kzalloc_obj(struct ia_css_stream); if (!curr_stream) { err = -ENOMEM; IA_CSS_LEAVE_ERR(err); @@ -7920,7 +7914,7 @@ ia_css_stream_create(const struct ia_css_stream_config *stream_config, /* allocate pipes */ curr_stream->num_pipes = num_pipes; - curr_stream->pipes = kcalloc(num_pipes, sizeof(struct ia_css_pipe *), GFP_KERNEL); + curr_stream->pipes = kzalloc_objs(struct ia_css_pipe *, num_pipes); if (!curr_stream->pipes) { curr_stream->num_pipes = 0; kfree(curr_stream); diff --git a/drivers/staging/media/atomisp/pci/sh_css_firmware.c b/drivers/staging/media/atomisp/pci/sh_css_firmware.c index bed599223717..57ecf5549c23 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_firmware.c +++ b/drivers/staging/media/atomisp/pci/sh_css_firmware.c @@ -262,8 +262,7 @@ sh_css_load_firmware(struct device *dev, const char *fw_data, sh_css_blob_info = NULL; } - fw_minibuffer = kcalloc(sh_css_num_binaries, sizeof(struct fw_param), - GFP_KERNEL); + fw_minibuffer = kzalloc_objs(struct fw_param, sh_css_num_binaries); if (!fw_minibuffer) return -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/sh_css_host_data.c b/drivers/staging/media/atomisp/pci/sh_css_host_data.c index 39efd8933034..d8f8e5e4482c 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_host_data.c +++ b/drivers/staging/media/atomisp/pci/sh_css_host_data.c @@ -12,7 +12,7 @@ struct ia_css_host_data *ia_css_host_data_allocate(size_t size) { struct ia_css_host_data *me; - me = kmalloc(sizeof(struct ia_css_host_data), GFP_KERNEL); + me = kmalloc_obj(struct ia_css_host_data); if (!me) return NULL; me->size = (uint32_t)size; diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c index 7fa4aab35b06..9ccdb66de2df 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c +++ b/drivers/staging/media/atomisp/pci/sh_css_param_dvs.c @@ -22,8 +22,7 @@ alloc_dvs_6axis_table(const struct ia_css_resolution *frame_res, int err = 0; struct ia_css_dvs_6axis_config *dvs_config = NULL; - dvs_config = kvmalloc(sizeof(struct ia_css_dvs_6axis_config), - GFP_KERNEL); + dvs_config = kvmalloc_obj(struct ia_css_dvs_6axis_config); if (!dvs_config) { IA_CSS_ERROR("out of memory"); err = -ENOMEM; diff --git a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c index 513e272f2fdc..9105334c71b1 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_param_shading.c +++ b/drivers/staging/media/atomisp/pci/sh_css_param_shading.c @@ -328,7 +328,7 @@ ia_css_shading_table_alloc( IA_CSS_ENTER(""); - me = kmalloc(sizeof(*me), GFP_KERNEL); + me = kmalloc_obj(*me); if (!me) return me; diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c index 11d62313c908..fcebace11daf 100644 --- a/drivers/staging/media/atomisp/pci/sh_css_params.c +++ b/drivers/staging/media/atomisp/pci/sh_css_params.c @@ -1369,7 +1369,7 @@ struct ia_css_morph_table *ia_css_morph_table_allocate( IA_CSS_ENTER(""); - me = kvmalloc(sizeof(*me), GFP_KERNEL); + me = kvmalloc_obj(*me); if (!me) { IA_CSS_ERROR("out of memory"); return me; @@ -1516,7 +1516,7 @@ ia_css_isp_3a_statistics_map_allocate( * so we use a local char * instead. */ char *base_ptr; - me = kvmalloc(sizeof(*me), GFP_KERNEL); + me = kvmalloc_obj(*me); if (!me) { IA_CSS_LEAVE("cannot allocate memory"); goto err; @@ -2136,7 +2136,7 @@ ia_css_isp_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) if (!grid->enable) return NULL; - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -2200,7 +2200,7 @@ ia_css_metadata_allocate(const struct ia_css_metadata_info *metadata_info) if (metadata_info->size == 0) return NULL; - md = kvmalloc(sizeof(*md), GFP_KERNEL); + md = kvmalloc_obj(*md); if (!md) goto error; @@ -2330,7 +2330,7 @@ sh_css_create_isp_params(struct ia_css_stream *stream, int err; size_t params_size; struct ia_css_isp_parameters *params = - kvmalloc(sizeof(struct ia_css_isp_parameters), GFP_KERNEL); + kvmalloc_obj(struct ia_css_isp_parameters); if (!params) { *isp_params_out = NULL; @@ -4161,7 +4161,7 @@ ia_css_3a_statistics_allocate(const struct ia_css_3a_grid_info *grid) assert(grid); - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -4201,7 +4201,7 @@ ia_css_dvs_statistics_allocate(const struct ia_css_dvs_grid_info *grid) assert(grid); - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -4239,7 +4239,7 @@ ia_css_dvs_coefficients_allocate(const struct ia_css_dvs_grid_info *grid) assert(grid); - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -4280,7 +4280,7 @@ ia_css_dvs2_statistics_allocate(const struct ia_css_dvs_grid_info *grid) assert(grid); - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -4371,7 +4371,7 @@ ia_css_dvs2_coefficients_allocate(const struct ia_css_dvs_grid_info *grid) assert(grid); - me = kvcalloc(1, sizeof(*me), GFP_KERNEL); + me = kvzalloc_objs(*me, 1); if (!me) goto err; @@ -4464,8 +4464,7 @@ ia_css_dvs2_6axis_config_allocate(const struct ia_css_stream *stream) if (!params || !params->pipe_dvs_6axis_config[IA_CSS_PIPE_ID_VIDEO]) goto err; - dvs_config = kvcalloc(1, sizeof(struct ia_css_dvs_6axis_config), - GFP_KERNEL); + dvs_config = kvzalloc_objs(struct ia_css_dvs_6axis_config, 1); if (!dvs_config) goto err; diff --git a/drivers/staging/media/av7110/av7110.c b/drivers/staging/media/av7110/av7110.c index 602342d1174f..607992100baf 100644 --- a/drivers/staging/media/av7110/av7110.c +++ b/drivers/staging/media/av7110/av7110.c @@ -2424,7 +2424,7 @@ static int av7110_attach(struct saa7146_dev *dev, } /* prepare the av7110 device struct */ - av7110 = kzalloc(sizeof(*av7110), GFP_KERNEL); + av7110 = kzalloc_obj(*av7110); if (!av7110) { dprintk(1, "out of memory\n"); return -ENOMEM; diff --git a/drivers/staging/media/av7110/sp8870.c b/drivers/staging/media/av7110/sp8870.c index 93bf47a62e38..29fb4934c039 100644 --- a/drivers/staging/media/av7110/sp8870.c +++ b/drivers/staging/media/av7110/sp8870.c @@ -563,7 +563,7 @@ struct dvb_frontend *sp8870_attach(const struct sp8870_config *config, struct sp8870_state *state = NULL; /* allocate memory for the internal state */ - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) goto error; diff --git a/drivers/staging/media/imx/imx-media-csc-scaler.c b/drivers/staging/media/imx/imx-media-csc-scaler.c index 0a27330f9790..00fcdd4d0487 100644 --- a/drivers/staging/media/imx/imx-media-csc-scaler.c +++ b/drivers/staging/media/imx/imx-media-csc-scaler.c @@ -124,7 +124,7 @@ static void device_run(void *_ctx) src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); - run = kzalloc(sizeof(*run), GFP_KERNEL); + run = kzalloc_obj(*run); if (!run) goto err; @@ -756,7 +756,7 @@ static int ipu_csc_scaler_open(struct file *file) struct ipu_csc_scaler_ctx *ctx = NULL; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -880,7 +880,7 @@ imx_media_csc_scaler_device_init(struct imx_media_dev *md) struct video_device *vfd; int ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/staging/media/ipu3/ipu3-css-fw.c b/drivers/staging/media/ipu3/ipu3-css-fw.c index 37482b626c3c..146e92ce6e4c 100644 --- a/drivers/staging/media/ipu3/ipu3-css-fw.c +++ b/drivers/staging/media/ipu3/ipu3-css-fw.c @@ -236,7 +236,7 @@ int imgu_css_fw_init(struct imgu_css *css) /* Allocate and map fw binaries into IMGU */ - css->binary = kcalloc(binary_nr, sizeof(*css->binary), GFP_KERNEL); + css->binary = kzalloc_objs(*css->binary, binary_nr); if (!css->binary) { r = -ENOMEM; goto error_out; diff --git a/drivers/staging/media/ipu3/ipu3-css.c b/drivers/staging/media/ipu3/ipu3-css.c index 777cac1c27bf..8063401246fb 100644 --- a/drivers/staging/media/ipu3/ipu3-css.c +++ b/drivers/staging/media/ipu3/ipu3-css.c @@ -1702,7 +1702,7 @@ int imgu_css_fmt_try(struct imgu_css *css, struct v4l2_pix_format_mplane *in, *out, *vf; int i, s, ret; - q = kcalloc(IPU3_CSS_QUEUES, sizeof(struct imgu_css_queue), GFP_KERNEL); + q = kzalloc_objs(struct imgu_css_queue, IPU3_CSS_QUEUES); if (!q) return -ENOMEM; diff --git a/drivers/staging/media/ipu3/ipu3-dmamap.c b/drivers/staging/media/ipu3/ipu3-dmamap.c index 8a19b0024152..ef208a059ef6 100644 --- a/drivers/staging/media/ipu3/ipu3-dmamap.c +++ b/drivers/staging/media/ipu3/ipu3-dmamap.c @@ -39,7 +39,7 @@ static struct page **imgu_dmamap_alloc_buffer(size_t size, gfp_t gfp) const gfp_t high_order_gfp = __GFP_NOWARN | __GFP_NORETRY; /* Allocate mem for array of page ptrs */ - pages = kvmalloc_array(count, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, count); if (!pages) return NULL; diff --git a/drivers/staging/media/ipu3/ipu3-mmu.c b/drivers/staging/media/ipu3/ipu3-mmu.c index cb9bf5fb29a5..b196a5815903 100644 --- a/drivers/staging/media/ipu3/ipu3-mmu.c +++ b/drivers/staging/media/ipu3/ipu3-mmu.c @@ -429,7 +429,7 @@ struct imgu_mmu_info *imgu_mmu_init(struct device *parent, void __iomem *base) struct imgu_mmu *mmu; u32 pteval; - mmu = kzalloc(sizeof(*mmu), GFP_KERNEL); + mmu = kzalloc_obj(*mmu); if (!mmu) return ERR_PTR(-ENOMEM); diff --git a/drivers/staging/media/ipu7/ipu7-bus.c b/drivers/staging/media/ipu7/ipu7-bus.c index 7da44fde002a..7a1b0744b236 100644 --- a/drivers/staging/media/ipu7/ipu7-bus.c +++ b/drivers/staging/media/ipu7/ipu7-bus.c @@ -89,7 +89,7 @@ ipu7_bus_initialize_device(struct pci_dev *pdev, struct device *parent, struct ipu7_device *isp = pci_get_drvdata(pdev); int ret; - adev = kzalloc(sizeof(*adev), GFP_KERNEL); + adev = kzalloc_obj(*adev); if (!adev) return ERR_PTR(-ENOMEM); diff --git a/drivers/staging/media/ipu7/ipu7-dma.c b/drivers/staging/media/ipu7/ipu7-dma.c index a118b41b2f34..9a356ae3b95a 100644 --- a/drivers/staging/media/ipu7/ipu7-dma.c +++ b/drivers/staging/media/ipu7/ipu7-dma.c @@ -164,7 +164,7 @@ void *ipu7_dma_alloc(struct ipu7_bus_device *sys, size_t size, unsigned int i; int ret; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return NULL; diff --git a/drivers/staging/media/ipu7/ipu7-mmu.c b/drivers/staging/media/ipu7/ipu7-mmu.c index ea35cce4830a..6ded07ccd780 100644 --- a/drivers/staging/media/ipu7/ipu7-mmu.c +++ b/drivers/staging/media/ipu7/ipu7-mmu.c @@ -584,7 +584,7 @@ static struct ipu7_mmu_info *ipu7_mmu_alloc(struct ipu7_device *isp) struct ipu7_mmu_info *mmu_info; int ret; - mmu_info = kzalloc(sizeof(*mmu_info), GFP_KERNEL); + mmu_info = kzalloc_obj(*mmu_info); if (!mmu_info) return NULL; @@ -654,7 +654,7 @@ static struct ipu7_dma_mapping *alloc_dma_mapping(struct ipu7_device *isp) struct ipu7_dma_mapping *dmap; unsigned long base_pfn; - dmap = kzalloc(sizeof(*dmap), GFP_KERNEL); + dmap = kzalloc_obj(*dmap); if (!dmap) return NULL; diff --git a/drivers/staging/media/ipu7/ipu7.c b/drivers/staging/media/ipu7/ipu7.c index fa5a1867626f..c771e763f8c5 100644 --- a/drivers/staging/media/ipu7/ipu7.c +++ b/drivers/staging/media/ipu7/ipu7.c @@ -2150,7 +2150,7 @@ ipu7_isys_init(struct pci_dev *pdev, struct device *parent, } } - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return ERR_PTR(-ENOMEM); @@ -2197,7 +2197,7 @@ ipu7_psys_init(struct pci_dev *pdev, struct device *parent, struct ipu7_psys_pdata *pdata; int ret; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + pdata = kzalloc_obj(*pdata); if (!pdata) return ERR_PTR(-ENOMEM); @@ -2271,7 +2271,7 @@ static int ipu7_map_fw_code_region(struct ipu7_bus_device *sys, n_pages = PFN_UP(size); - pages = kmalloc_array(n_pages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, n_pages); if (!pages) return -ENOMEM; diff --git a/drivers/staging/media/meson/vdec/codec_h264.c b/drivers/staging/media/meson/vdec/codec_h264.c index c61128fc4bb9..89e0f8624e5b 100644 --- a/drivers/staging/media/meson/vdec/codec_h264.c +++ b/drivers/staging/media/meson/vdec/codec_h264.c @@ -233,7 +233,7 @@ static int codec_h264_load_extended_firmware(struct amvdec_session *sess, if (len < SIZE_EXT_FW) return -EINVAL; - h264 = kzalloc(sizeof(*h264), GFP_KERNEL); + h264 = kzalloc_obj(*h264); if (!h264) return -ENOMEM; diff --git a/drivers/staging/media/meson/vdec/codec_mpeg12.c b/drivers/staging/media/meson/vdec/codec_mpeg12.c index 48869cc3d973..76e9ca7191ab 100644 --- a/drivers/staging/media/meson/vdec/codec_mpeg12.c +++ b/drivers/staging/media/meson/vdec/codec_mpeg12.c @@ -66,7 +66,7 @@ static int codec_mpeg12_start(struct amvdec_session *sess) struct codec_mpeg12 *mpeg12; int ret; - mpeg12 = kzalloc(sizeof(*mpeg12), GFP_KERNEL); + mpeg12 = kzalloc_obj(*mpeg12); if (!mpeg12) return -ENOMEM; diff --git a/drivers/staging/media/meson/vdec/codec_vp9.c b/drivers/staging/media/meson/vdec/codec_vp9.c index 394df5761556..8e80ecf84193 100644 --- a/drivers/staging/media/meson/vdec/codec_vp9.c +++ b/drivers/staging/media/meson/vdec/codec_vp9.c @@ -762,7 +762,7 @@ static int codec_vp9_start(struct amvdec_session *sess) int i; int ret; - vp9 = kzalloc(sizeof(*vp9), GFP_KERNEL); + vp9 = kzalloc_obj(*vp9); if (!vp9) return -ENOMEM; @@ -1192,7 +1192,7 @@ static struct vp9_frame *codec_vp9_get_new_frame(struct amvdec_session *sess) struct vb2_v4l2_buffer *vbuf; struct vp9_frame *new_frame; - new_frame = kzalloc(sizeof(*new_frame), GFP_KERNEL); + new_frame = kzalloc_obj(*new_frame); if (!new_frame) return NULL; diff --git a/drivers/staging/media/meson/vdec/vdec.c b/drivers/staging/media/meson/vdec/vdec.c index 49e497a32973..4b77ec1af5a7 100644 --- a/drivers/staging/media/meson/vdec/vdec.c +++ b/drivers/staging/media/meson/vdec/vdec.c @@ -132,7 +132,7 @@ vdec_queue_recycle(struct amvdec_session *sess, struct vb2_buffer *vb) { struct amvdec_buffer *new_buf; - new_buf = kmalloc(sizeof(*new_buf), GFP_KERNEL); + new_buf = kmalloc_obj(*new_buf); if (!new_buf) return; new_buf->vb = vb; @@ -867,7 +867,7 @@ static int vdec_open(struct file *file) struct amvdec_session *sess; int ret; - sess = kzalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc_obj(*sess); if (!sess) return -ENOMEM; diff --git a/drivers/staging/media/meson/vdec/vdec_helpers.c b/drivers/staging/media/meson/vdec/vdec_helpers.c index 7d2a75653250..f02c21d5a9c1 100644 --- a/drivers/staging/media/meson/vdec/vdec_helpers.c +++ b/drivers/staging/media/meson/vdec/vdec_helpers.c @@ -233,7 +233,7 @@ int amvdec_add_ts(struct amvdec_session *sess, u64 ts, struct amvdec_timestamp *new_ts; unsigned long flags; - new_ts = kzalloc(sizeof(*new_ts), GFP_KERNEL); + new_ts = kzalloc_obj(*new_ts); if (!new_ts) return -ENOMEM; diff --git a/drivers/staging/media/sunxi/cedrus/cedrus.c b/drivers/staging/media/sunxi/cedrus/cedrus.c index bff42ea1871f..6600245dff0e 100644 --- a/drivers/staging/media/sunxi/cedrus/cedrus.c +++ b/drivers/staging/media/sunxi/cedrus/cedrus.c @@ -359,7 +359,7 @@ static int cedrus_open(struct file *file) if (mutex_lock_interruptible(&dev->dev_mutex)) return -ERESTARTSYS; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { mutex_unlock(&dev->dev_mutex); return -ENOMEM; diff --git a/drivers/staging/media/tegra-video/csi.c b/drivers/staging/media/tegra-video/csi.c index 3c3f6e3fd1ec..7842104ca933 100644 --- a/drivers/staging/media/tegra-video/csi.c +++ b/drivers/staging/media/tegra-video/csi.c @@ -463,7 +463,7 @@ static int tegra_csi_channel_alloc(struct tegra_csi *csi, struct tegra_csi_channel *chan; int ret = 0, i; - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return -ENOMEM; diff --git a/drivers/staging/media/tegra-video/vi.c b/drivers/staging/media/tegra-video/vi.c index 14b327afe045..9c0b38585d63 100644 --- a/drivers/staging/media/tegra-video/vi.c +++ b/drivers/staging/media/tegra-video/vi.c @@ -1209,7 +1209,7 @@ static int tegra_vi_channel_alloc(struct tegra_vi *vi, unsigned int port_num, * be holding the device node open. Channel memory allocated * with kzalloc is freed during video device release callback. */ - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return -ENOMEM; diff --git a/drivers/staging/media/tegra-video/video.c b/drivers/staging/media/tegra-video/video.c index 68783d5ffeb1..ae1ae03fa9de 100644 --- a/drivers/staging/media/tegra-video/video.c +++ b/drivers/staging/media/tegra-video/video.c @@ -46,7 +46,7 @@ static int host1x_video_probe(struct host1x_device *dev) struct tegra_video_device *vid; int ret; - vid = kzalloc(sizeof(*vid), GFP_KERNEL); + vid = kzalloc_obj(*vid); if (!vid) return -ENOMEM; diff --git a/drivers/staging/most/dim2/dim2.c b/drivers/staging/most/dim2/dim2.c index dad2abe6c0c9..8d649d920433 100644 --- a/drivers/staging/most/dim2/dim2.c +++ b/drivers/staging/most/dim2/dim2.c @@ -113,10 +113,12 @@ static inline struct dim2_hdm *iface_to_hdm(struct most_interface *iface) return container_of(iface, struct dim2_hdm, most_iface); } -/* Macro to identify a network status message */ -#define PACKET_IS_NET_INFO(p) \ - (((p)[1] == 0x18) && ((p)[2] == 0x05) && ((p)[3] == 0x0C) && \ - ((p)[13] == 0x3C) && ((p)[14] == 0x00) && ((p)[15] == 0x0A)) +/* Identify a network status message */ +static bool packet_is_net_info(const u8 *p) +{ + return p[1] == 0x18 && p[2] == 0x05 && p[3] == 0x0C && + p[13] == 0x3C && p[14] == 0x00 && p[15] == 0x0A; +} static ssize_t state_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -304,7 +306,7 @@ static void service_done_flag(struct dim2_hdm *dev, int ch_idx) if (hdm_ch->data_type == MOST_CH_ASYNC && hdm_ch->direction == MOST_CH_RX && - PACKET_IS_NET_INFO(data)) { + packet_is_net_info(data)) { retrieve_netinfo(dev, mbo); spin_lock_irqsave(&dim_lock, flags); @@ -757,7 +759,7 @@ static int dim2_probe(struct platform_device *pdev) enum { MLB_INT_IDX, AHB0_INT_IDX }; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/staging/most/video/video.c b/drivers/staging/most/video/video.c index 32f71d9a9cf7..04351f8ccccf 100644 --- a/drivers/staging/most/video/video.c +++ b/drivers/staging/most/video/video.c @@ -84,7 +84,7 @@ static int comp_vdev_open(struct file *filp) return -EINVAL; } - fh = kzalloc(sizeof(*fh), GFP_KERNEL); + fh = kzalloc_obj(*fh); if (!fh) return -ENOMEM; @@ -121,6 +121,7 @@ static int comp_vdev_close(struct file *filp) struct comp_fh *fh = to_comp_fh(filp); struct most_video_dev *mdev = fh->mdev; struct mbo *mbo, *tmp; + LIST_HEAD(free_list); /* * We need to put MBOs back before we call most_stop_channel() @@ -133,13 +134,14 @@ static int comp_vdev_close(struct file *filp) spin_lock_irq(&mdev->list_lock); mdev->mute = true; - list_for_each_entry_safe(mbo, tmp, &mdev->pending_mbos, list) { - list_del(&mbo->list); - spin_unlock_irq(&mdev->list_lock); - most_put_mbo(mbo); - spin_lock_irq(&mdev->list_lock); - } + list_replace_init(&mdev->pending_mbos, &free_list); spin_unlock_irq(&mdev->list_lock); + + list_for_each_entry_safe(mbo, tmp, &free_list, list) { + list_del_init(&mbo->list); + most_put_mbo(mbo); + } + most_stop_channel(mdev->iface, mdev->ch_idx, &comp); mdev->mute = false; @@ -472,7 +474,7 @@ static int comp_probe_channel(struct most_interface *iface, int channel_idx, return -EINVAL; } - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; @@ -554,6 +556,7 @@ static int __init comp_init(void) static void __exit comp_exit(void) { struct most_video_dev *mdev, *tmp; + LIST_HEAD(free_list); /* * As the mostcore currently doesn't call disconnect_channel() @@ -562,16 +565,15 @@ static void __exit comp_exit(void) * This must be fixed in core. */ spin_lock_irq(&list_lock); - list_for_each_entry_safe(mdev, tmp, &video_devices, list) { - list_del(&mdev->list); - spin_unlock_irq(&list_lock); + list_replace_init(&video_devices, &free_list); + spin_unlock_irq(&list_lock); + list_for_each_entry_safe(mdev, tmp, &free_list, list) { + list_del_init(&mdev->list); comp_unregister_videodev(mdev); v4l2_device_disconnect(&mdev->v4l2_dev); v4l2_device_put(&mdev->v4l2_dev); - spin_lock_irq(&list_lock); } - spin_unlock_irq(&list_lock); most_deregister_configfs_subsys(&comp); most_deregister_component(&comp); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 263774e6a78c..e9af66a08448 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -648,7 +648,6 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) break; case 2: /* first byte after command */ if (status == (I2C_SL_IRQ | RNW | RCVD)) { - udelay(33); if (nvec->rx->data[0] != 0x01) { dev_err(nvec->dev, "Read without prior read command\n"); @@ -660,6 +659,9 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) nvec_tx_set(nvec); to_send = nvec->tx->data[0]; nvec->tx->pos = 1; + /* delay ACK due to AP20 HW Bug + do not replace by usleep_range */ + udelay(33); } else if (status == (I2C_SL_IRQ)) { nvec->rx->data[1] = received; nvec->rx->pos = 2; diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 2db57795ea2f..e6234d29e264 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -102,7 +102,7 @@ static int nvec_mouse_probe(struct platform_device *pdev) struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev; - ser_dev = kzalloc(sizeof(*ser_dev), GFP_KERNEL); + ser_dev = kzalloc_obj(*ser_dev); if (!ser_dev) return -ENOMEM; diff --git a/drivers/staging/rtl8723bs/Kconfig b/drivers/staging/rtl8723bs/Kconfig index 353e6ee2c145..414982893b6b 100644 --- a/drivers/staging/rtl8723bs/Kconfig +++ b/drivers/staging/rtl8723bs/Kconfig @@ -3,9 +3,9 @@ config RTL8723BS tristate "Realtek RTL8723BS SDIO Wireless LAN NIC driver" depends on WLAN && MMC && CFG80211 depends on m - select CRYPTO select CRYPTO_LIB_AES select CRYPTO_LIB_ARC4 + select CRYPTO_LIB_UTILS help This option enables support for RTL8723BS SDIO drivers, such as the wifi found on the 1st gen Intel Compute Stick, the CHIP diff --git a/drivers/staging/rtl8723bs/TODO b/drivers/staging/rtl8723bs/TODO index 050dcd0bffab..34c216e6da32 100644 --- a/drivers/staging/rtl8723bs/TODO +++ b/drivers/staging/rtl8723bs/TODO @@ -1,7 +1,6 @@ TODO: - find and remove any code for other chips that is left over - convert any remaining unusual variable types -- find codes that can use %pM and %Nph formatting - checkpatch.pl fixes - most of the remaining ones are lines too long. Many of them will require refactoring - merge Realtek's bugfixes and new features into the driver diff --git a/drivers/staging/rtl8723bs/core/rtw_ap.c b/drivers/staging/rtl8723bs/core/rtw_ap.c index 67197c7d4a4d..864cd8b6d1f1 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ap.c +++ b/drivers/staging/rtl8723bs/core/rtw_ap.c @@ -114,11 +114,8 @@ static void update_BCNTIM(struct adapter *padapter) dst_ie = pie + offset; } - if (remainder_ielen > 0) { - pbackup_remainder_ie = rtw_malloc(remainder_ielen); - if (pbackup_remainder_ie && premainder_ie) - memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); - } + if (premainder_ie && remainder_ielen) + pbackup_remainder_ie = kmemdup(premainder_ie, remainder_ielen, GFP_ATOMIC); *dst_ie++ = WLAN_EID_TIM; @@ -178,6 +175,8 @@ void expire_timeout_chk(struct adapter *padapter) struct sta_priv *pstapriv = &padapter->stapriv; u8 chk_alive_num = 0; char chk_alive_list[NUM_STA]; + struct sta_info *psta_tmp; + LIST_HEAD(free_list); int i; spin_lock_bh(&pstapriv->auth_list_lock); @@ -190,19 +189,19 @@ void expire_timeout_chk(struct adapter *padapter) if (psta->expire_to > 0) { psta->expire_to--; if (psta->expire_to == 0) { - list_del_init(&psta->auth_list); + list_move(&psta->auth_list, &free_list); pstapriv->auth_list_cnt--; - - spin_unlock_bh(&pstapriv->auth_list_lock); - - rtw_free_stainfo(padapter, psta); - - spin_lock_bh(&pstapriv->auth_list_lock); } } } spin_unlock_bh(&pstapriv->auth_list_lock); + + list_for_each_entry_safe(psta, psta_tmp, &free_list, auth_list) { + list_del_init(&psta->auth_list); + rtw_free_stainfo(padapter, psta); + } + psta = NULL; spin_lock_bh(&pstapriv->asoc_list_lock); @@ -318,9 +317,9 @@ void expire_timeout_chk(struct adapter *padapter) associated_clients_update(padapter, updated); } -void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) +void add_ratid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) { - unsigned char sta_band = 0, shortGIrate = false; + unsigned char sta_band = 0, short_gi_rate = false; unsigned int tx_ra_bitmap = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct wlan_bssid_ex @@ -335,7 +334,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) rtw_hal_update_sta_rate_mask(padapter, psta); tx_ra_bitmap = psta->ra_mask; - shortGIrate = query_ra_short_GI(psta); + short_gi_rate = query_ra_short_GI(psta); if (pcur_network->configuration.ds_config > 14) { sta_band |= WIRELESS_INVALID; @@ -358,7 +357,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) arg[0] = psta->mac_id; arg[1] = psta->raid; - arg[2] = shortGIrate; + arg[2] = short_gi_rate; arg[3] = psta->init_rate; rtw_hal_add_ra_tid(padapter, tx_ra_bitmap, arg, rssi_level); @@ -368,7 +367,7 @@ void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level) void update_bmc_sta(struct adapter *padapter) { unsigned char network_type; - int supportRateNum = 0; + int support_rate_num = 0; unsigned int tx_ra_bitmap = 0; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; @@ -391,10 +390,10 @@ void update_bmc_sta(struct adapter *padapter) memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); - /* prepare for add_RATid */ - supportRateNum = rtw_get_rateset_len((u8 *)&pcur_network->supported_rates); + /* prepare for add_ratid */ + support_rate_num = rtw_get_rateset_len((u8 *)&pcur_network->supported_rates); network_type = rtw_check_network_type((u8 *)&pcur_network->supported_rates, - supportRateNum, + support_rate_num, pcur_network->configuration.ds_config ); if (is_supported_tx_cck(network_type)) { @@ -549,7 +548,7 @@ void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta) memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats)); /* add ratid */ - /* add_RATid(padapter, psta);//move to ap_sta_info_defer_update() */ + /* add_ratid(padapter, psta); move to ap_sta_info_defer_update() */ spin_lock_bh(&psta->lock); psta->state |= _FW_LINKED; @@ -688,7 +687,7 @@ void start_bss_network(struct adapter *padapter) } /* set MSR to AP_Mode */ - Set_MSR(padapter, _HW_STATE_AP_); + set_msr(padapter, _HW_STATE_AP_); /* Set BSSID REG */ rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pnetwork->mac_address); @@ -807,8 +806,8 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) u16 cap, ht_cap = false; uint ie_len = 0; int group_cipher, pairwise_cipher; - u8 channel, network_type, supportRate[NDIS_802_11_LENGTH_RATES_EX]; - int supportRateNum = 0; + u8 channel, network_type, support_rate[NDIS_802_11_LENGTH_RATES_EX]; + int support_rate_num = 0; u8 OUI1[] = {0x00, 0x50, 0xf2, 0x01}; u8 WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; struct registry_priv *pregistrypriv = &padapter->registrypriv; @@ -870,15 +869,15 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) pbss_network->configuration.ds_config = channel; - memset(supportRate, 0, NDIS_802_11_LENGTH_RATES_EX); + memset(support_rate, 0, NDIS_802_11_LENGTH_RATES_EX); /* get supported rates */ p = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_SUPP_RATES, &ie_len, (pbss_network->ie_length - _BEACON_IE_OFFSET_)); if (p) { - memcpy(supportRate, p + 2, ie_len); - supportRateNum = ie_len; + memcpy(support_rate, p + 2, ie_len); + support_rate_num = ie_len; } /* get ext_supported rates */ @@ -887,11 +886,11 @@ int rtw_check_beacon_data(struct adapter *padapter, u8 *pbuf, int len) &ie_len, pbss_network->ie_length - _BEACON_IE_OFFSET_); if (p) { - memcpy(supportRate + supportRateNum, p + 2, ie_len); - supportRateNum += ie_len; + memcpy(support_rate + support_rate_num, p + 2, ie_len); + support_rate_num += ie_len; } - network_type = rtw_check_network_type(supportRate, supportRateNum, channel); + network_type = rtw_check_network_type(support_rate, support_rate_num, channel); rtw_set_supported_rate(pbss_network->supported_rates, network_type); @@ -1230,13 +1229,13 @@ u8 rtw_ap_set_pairwise_key(struct adapter *padapter, struct sta_info *psta) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c); if (!ph2c) { res = _FAIL; goto exit; } - psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); + psetstakey_para = kzalloc_obj(*psetstakey_para); if (!psetstakey_para) { kfree(ph2c); res = _FAIL; @@ -1270,12 +1269,12 @@ static int rtw_ap_set_key(struct adapter *padapter, struct cmd_priv *pcmdpriv = &padapter->cmdpriv; int res = _SUCCESS; - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd); if (!pcmd) { res = _FAIL; goto exit; } - psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm)); + psetkeyparm = kzalloc_obj(*psetkeyparm); if (!psetkeyparm) { kfree(pcmd); res = _FAIL; @@ -1440,11 +1439,8 @@ static void update_bcn_wps_ie(struct adapter *padapter) remainder_ielen = ielen - wps_offset - wps_ielen; - if (remainder_ielen > 0) { - pbackup_remainder_ie = rtw_malloc(remainder_ielen); - if (pbackup_remainder_ie) - memcpy(pbackup_remainder_ie, premainder_ie, remainder_ielen); - } + if (premainder_ie && remainder_ielen) + pbackup_remainder_ie = kmemdup(premainder_ie, remainder_ielen, GFP_ATOMIC); wps_ielen = (uint)pwps_ie_src[1];/* to get ie data len */ if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) { @@ -1947,7 +1943,7 @@ void ap_sta_info_defer_update(struct adapter *padapter, struct sta_info *psta) pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; /* add ratid */ - add_RATid(padapter, psta, 0);/* DM_RATR_STA_INIT */ + add_ratid(padapter, psta, 0);/* DM_RATR_STA_INIT */ } } diff --git a/drivers/staging/rtl8723bs/core/rtw_cmd.c b/drivers/staging/rtl8723bs/core/rtw_cmd.c index ef2d92b5588a..abb84f8aecbe 100644 --- a/drivers/staging/rtl8723bs/core/rtw_cmd.c +++ b/drivers/staging/rtl8723bs/core/rtw_cmd.c @@ -7,6 +7,7 @@ #include #include #include +#include static struct _cmd_callback rtw_cmd_callback[] = { {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ @@ -170,21 +171,19 @@ int rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) pcmdpriv->cmd_seq = 1; - pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); - + pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, GFP_ATOMIC); if (!pcmdpriv->cmd_allocated_buf) return -ENOMEM; - pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); - - pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); + pcmdpriv->cmd_buf = PTR_ALIGN(pcmdpriv->cmd_allocated_buf, CMDBUFF_ALIGN_SZ); + pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_ATOMIC); if (!pcmdpriv->rsp_allocated_buf) { kfree(pcmdpriv->cmd_allocated_buf); return -ENOMEM; } - pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); + pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); pcmdpriv->cmd_issued_cnt = 0; pcmdpriv->cmd_done_cnt = 0; @@ -204,7 +203,7 @@ int rtw_init_evt_priv(struct evt_priv *pevtpriv) _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); pevtpriv->c2h_wk_alive = false; - pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1); + pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN + 1); if (!pevtpriv->c2h_queue) return -ENOMEM; @@ -305,7 +304,7 @@ int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) bAllow = true; if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) || - !atomic_read(&pcmdpriv->cmdthd_running)) /* com_thread not running */ + !atomic_read(&pcmdpriv->cmdthd_running)) /* com_thread not running */ return _FAIL; return _SUCCESS; @@ -363,7 +362,7 @@ void rtw_free_cmd_obj(struct cmd_obj *pcmd) void rtw_stop_cmd_thread(struct adapter *adapter) { if (adapter->cmdThread && - atomic_read(&adapter->cmdpriv.cmdthd_running) && + atomic_read(&adapter->cmdpriv.cmdthd_running) && adapter->cmdpriv.stop_req == 0) { adapter->cmdpriv.stop_req = 1; complete(&adapter->cmdpriv.cmd_queue_comp); @@ -523,7 +522,7 @@ int rtw_cmd_thread(void *context) */ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, - struct rtw_ieee80211_channel *ch, int ch_num) + struct rtw_ieee80211_channel *ch, int ch_num) { u8 res = _FAIL; struct cmd_obj *ph2c; @@ -534,11 +533,11 @@ u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, if (check_fwstate(pmlmepriv, _FW_LINKED)) rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) return _FAIL; - psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); + psurveyPara = kzalloc_obj(*psurveyPara, GFP_ATOMIC); if (!psurveyPara) { kfree(ph2c); return _FAIL; @@ -602,7 +601,7 @@ u8 rtw_createbss_cmd(struct adapter *padapter) struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; u8 res = _SUCCESS; - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd, GFP_ATOMIC); if (!pcmd) { res = _FAIL; goto exit; @@ -635,7 +634,7 @@ int rtw_startbss_cmd(struct adapter *padapter, int flags) start_bss_network(padapter); } else { /* need enqueue, prepare cmd_obj and enqueue */ - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd); if (!pcmd) { res = _FAIL; goto exit; @@ -687,7 +686,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) u32 tmp_len; u8 *ptmp = NULL; - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd); if (!pcmd) { res = _FAIL; goto exit; @@ -696,7 +695,7 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) t_len = sizeof(struct wlan_bssid_ex); /* for hidden ap to set fw_state here */ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != true) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) != true) { switch (ndis_network_mode) { case Ndis802_11IBSS: set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); @@ -721,10 +720,10 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->ie_length; - if ((psecnetwork->ie_length-12) < (256-1)) - memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], psecnetwork->ie_length-12); + if ((psecnetwork->ie_length - 12) < (256 - 1)) + memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], psecnetwork->ie_length - 12); else - memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], (256-1)); + memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->ies[12], (256 - 1)); psecnetwork->ie_length = 0; /* Added by Albert 2009/02/18 */ @@ -751,22 +750,22 @@ u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) } phtpriv->ht_option = false; - ptmp = rtw_get_ie(&pnetwork->network.ies[12], WLAN_EID_HT_CAPABILITY, &tmp_len, pnetwork->network.ie_length-12); + ptmp = rtw_get_ie(&pnetwork->network.ies[12], WLAN_EID_HT_CAPABILITY, &tmp_len, pnetwork->network.ie_length - 12); if (pregistrypriv->ht_enable && ptmp && tmp_len > 0) { /* Added by Albert 2010/06/23 */ /* For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */ /* Especially for Realtek 8192u SoftAP. */ if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && - (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && - (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { + (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && + (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { rtw_ht_use_default_setting(padapter); rtw_build_wmm_ie_ht(padapter, &psecnetwork->ies[12], &psecnetwork->ie_length); /* rtw_restructure_ht_ie */ rtw_restructure_ht_ie(padapter, &pnetwork->network.ies[12], &psecnetwork->ies[0], - pnetwork->network.ie_length-12, &psecnetwork->ie_length, - pnetwork->network.configuration.ds_config); + pnetwork->network.ie_length - 12, &psecnetwork->ie_length, + pnetwork->network.configuration.ds_config); } } @@ -796,7 +795,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu u8 res = _SUCCESS; /* prepare cmd parameter */ - param = rtw_zmalloc(sizeof(*param)); + param = kzalloc_obj(*param); if (!param) { res = _FAIL; goto exit; @@ -805,7 +804,7 @@ u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueu if (enqueue) { /* need enqueue, prepare cmd_obj and enqueue */ - cmdobj = rtw_zmalloc(sizeof(*cmdobj)); + cmdobj = kzalloc_obj(*cmdobj); if (!cmdobj) { res = _FAIL; kfree(param); @@ -832,8 +831,7 @@ u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infrast struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - psetop = rtw_zmalloc(sizeof(struct setopmode_parm)); - + psetop = kzalloc_obj(*psetop); if (!psetop) { res = _FAIL; goto exit; @@ -841,7 +839,7 @@ u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infrast psetop->mode = (u8)networktype; if (enqueue) { - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c); if (!ph2c) { kfree(psetop); res = _FAIL; @@ -868,7 +866,7 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_ struct security_priv *psecuritypriv = &padapter->securitypriv; u8 res = _SUCCESS; - psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); + psetstakey_para = kzalloc_obj(*psetstakey_para); if (!psetstakey_para) { res = _FAIL; goto exit; @@ -890,14 +888,14 @@ u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_ padapter->securitypriv.busetkipkey = true; if (enqueue) { - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c); if (!ph2c) { kfree(psetstakey_para); res = _FAIL; goto exit; } - psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); + psetstakey_rsp = kzalloc_obj(*psetstakey_rsp); if (!psetstakey_rsp) { kfree(ph2c); kfree(psetstakey_para); @@ -930,25 +928,25 @@ u8 rtw_clearstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 enqueu while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1)) >= 0) { netdev_dbg(padapter->pnetdev, "clear key for addr:%pM, camid:%d\n", - MAC_ARG(sta->hwaddr), cam_id); + sta->hwaddr, cam_id); clear_cam_entry(padapter, cam_id); rtw_camid_free(padapter, cam_id); } } else { - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c); if (!ph2c) { res = _FAIL; goto exit; } - psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); + psetstakey_para = kzalloc_obj(*psetstakey_para); if (!psetstakey_para) { kfree(ph2c); res = _FAIL; goto exit; } - psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); + psetstakey_rsp = kzalloc_obj(*psetstakey_rsp); if (!psetstakey_rsp) { kfree(ph2c); kfree(psetstakey_para); @@ -978,13 +976,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm)); + paddbareq_parm = kzalloc_obj(*paddbareq_parm, GFP_ATOMIC); if (!paddbareq_parm) { kfree(ph2c); res = _FAIL; @@ -1002,6 +1000,7 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) exit: return res; } + /* add for CONFIG_IEEE80211W, none 11w can use it */ u8 rtw_reset_securitypriv_cmd(struct adapter *padapter) { @@ -1010,13 +1009,13 @@ u8 rtw_reset_securitypriv_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1043,13 +1042,13 @@ u8 rtw_free_assoc_resources_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1077,13 +1076,13 @@ u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) u8 res = _SUCCESS; /* only primary padapter does this cmd */ - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1122,8 +1121,8 @@ static void collect_traffic_statistics(struct adapter *padapter) pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes; pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes; - pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8/2/1024/1024); - pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8/2/1024/1024); + pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8 / 2 / 1024 / 1024); + pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8 / 2 / 1024 / 1024); } u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) @@ -1148,7 +1147,7 @@ u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) BusyThreshold = BusyThresholdLow; if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) { + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) { bBusyTraffic = true; if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) @@ -1159,7 +1158,7 @@ u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) /* Higher Tx/Rx data. */ if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || - pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { bHigherBusyTraffic = true; if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) @@ -1170,7 +1169,7 @@ u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) /* check traffic for powersaving. */ if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || - (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { + (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { bEnterPS = false; if (bBusyTraffic) { @@ -1224,7 +1223,6 @@ u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; return bEnterPS; - } static void dynamic_chk_wk_hdl(struct adapter *padapter) @@ -1264,7 +1262,7 @@ void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) u8 mstatus; if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || - check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { + check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { return; } @@ -1318,13 +1316,14 @@ u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) u8 res = _SUCCESS; if (enqueue) { - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, + GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1359,13 +1358,13 @@ u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1421,13 +1420,13 @@ u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1446,7 +1445,6 @@ u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta) exit: return res; - } u8 rtw_ps_cmd(struct adapter *padapter) @@ -1456,13 +1454,13 @@ u8 rtw_ps_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ppscmd = rtw_zmalloc(sizeof(struct cmd_obj)); + ppscmd = kzalloc_obj(*ppscmd, GFP_ATOMIC); if (!ppscmd) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ppscmd); res = _FAIL; @@ -1516,9 +1514,7 @@ static void rtw_chk_hi_queue_hdl(struct adapter *padapter) } else {/* re check again */ rtw_chk_hi_queue_cmd(padapter); } - } - } u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) @@ -1528,13 +1524,13 @@ u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1598,9 +1594,9 @@ static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len) cmd_idx = info->cid; - if (info->len > buf_len-2) { + if (info->len > buf_len - 2) { rtw_warn_on(1); - len = buf_len-2; + len = buf_len - 2; } else { len = info->len; } @@ -1610,7 +1606,7 @@ static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len) buf[1] = 0; else if (cmd_idx == BTINFO_BT_AUTO_RPT) buf[1] = 2; - hal_btcoex_BtInfoNotify(adapter, len+1, &buf[1]); + hal_btcoex_BtInfoNotify(adapter, len + 1, &buf[1]); } u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length) @@ -1620,13 +1616,13 @@ u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm, GFP_ATOMIC); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1655,13 +1651,13 @@ u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c); if (!ph2c) { res = _FAIL; goto exit; } - pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); + pdrvextra_cmd_parm = kzalloc_obj(*pdrvextra_cmd_parm); if (!pdrvextra_cmd_parm) { kfree(ph2c); res = _FAIL; @@ -1670,7 +1666,7 @@ u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) pdrvextra_cmd_parm->ec_id = C2H_WK_CID; pdrvextra_cmd_parm->type = 0; - pdrvextra_cmd_parm->size = c2h_evt?16:0; + pdrvextra_cmd_parm->size = c2h_evt ? 16 : 0; pdrvextra_cmd_parm->pbuf = c2h_evt; init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); @@ -1697,7 +1693,7 @@ static void c2h_wk_callback(struct work_struct *work) /* This C2H event is read, clear it */ c2h_evt_clear(adapter); } else { - c2h_evt = rtw_malloc(16); + c2h_evt = kmalloc(16, GFP_ATOMIC); if (c2h_evt) { /* This C2H event is not read, read & clear now */ if (c2h_evt_read_88xx(adapter, c2h_evt) != _SUCCESS) { @@ -1877,7 +1873,6 @@ void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) spin_unlock_bh(&pmlmepriv->scanned_queue.lock); /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ - } createbss_cmd_fail: diff --git a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c index e89b24fa5e05..3e2b5e6b07f9 100644 --- a/drivers/staging/rtl8723bs/core/rtw_ieee80211.c +++ b/drivers/staging/rtl8723bs/core/rtw_ieee80211.c @@ -186,20 +186,25 @@ u8 *rtw_get_ie_ex(u8 *in_ie, uint in_len, u8 eid, u8 *oui, u8 oui_len, u8 *ie, u cnt = 0; - while (cnt < in_len) { + while (cnt + 2 <= in_len) { + u8 ie_len = in_ie[cnt + 1]; + + if (cnt + 2 + ie_len > in_len) + break; + if (eid == in_ie[cnt] - && (!oui || !memcmp(&in_ie[cnt+2], oui, oui_len))) { + && (!oui || (ie_len >= oui_len && !memcmp(&in_ie[cnt + 2], oui, oui_len)))) { target_ie = &in_ie[cnt]; if (ie) - memcpy(ie, &in_ie[cnt], in_ie[cnt+1]+2); + memcpy(ie, &in_ie[cnt], ie_len + 2); if (ielen) - *ielen = in_ie[cnt+1]+2; + *ielen = ie_len + 2; break; } - cnt += in_ie[cnt+1]+2; /* goto next */ + cnt += ie_len + 2; /* goto next */ } return target_ie; @@ -1010,7 +1015,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) pbuf = rtw_get_wpa_ie(&pnetwork->network.ies[12], &wpa_ielen, pnetwork->network.ie_length-12); if (pbuf && (wpa_ielen > 0)) { - if (_SUCCESS == rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x; @@ -1020,7 +1025,7 @@ static int rtw_get_cipher_info(struct wlan_network *pnetwork) pbuf = rtw_get_wpa2_ie(&pnetwork->network.ies[12], &wpa_ielen, pnetwork->network.ie_length-12); if (pbuf && (wpa_ielen > 0)) { - if (_SUCCESS == rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x)) { + if (rtw_parse_wpa2_ie(pbuf, wpa_ielen+2, &group_cipher, &pairwise_cipher, &is8021x) == _SUCCESS) { pnetwork->bcn_info.pairwise_cipher = pairwise_cipher; pnetwork->bcn_info.group_cipher = group_cipher; pnetwork->bcn_info.is_8021x = is8021x; @@ -1140,7 +1145,7 @@ int rtw_action_frame_parse(const u8 *frame, u32 frame_len, u8 *category, u8 *act return true; } -static const char *_action_public_str[] = { +static const char * const _action_public_str[] = { "ACT_PUB_BSSCOEXIST", "ACT_PUB_DSE_ENABLE", "ACT_PUB_DSE_DEENABLE", diff --git a/drivers/staging/rtl8723bs/core/rtw_io.c b/drivers/staging/rtl8723bs/core/rtw_io.c index fe9f94001eed..965c3cfea103 100644 --- a/drivers/staging/rtl8723bs/core/rtw_io.c +++ b/drivers/staging/rtl8723bs/core/rtw_io.c @@ -29,7 +29,7 @@ u8 rtw_read8(struct adapter *adapter, u32 addr) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); _read8 = pintfhdl->io_ops._read8; @@ -41,7 +41,7 @@ u16 rtw_read16(struct adapter *adapter, u32 addr) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); _read16 = pintfhdl->io_ops._read16; @@ -53,20 +53,19 @@ u32 rtw_read32(struct adapter *adapter, u32 addr) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); _read32 = pintfhdl->io_ops._read32; return _read32(pintfhdl, addr); - } int rtw_write8(struct adapter *adapter, u32 addr, u8 val) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); int ret; @@ -80,7 +79,7 @@ int rtw_write16(struct adapter *adapter, u32 addr, u16 val) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); int ret; @@ -93,7 +92,7 @@ int rtw_write32(struct adapter *adapter, u32 addr, u32 val) { /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); int ret; @@ -108,7 +107,7 @@ u32 rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) { u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); struct io_priv *pio_priv = &adapter->iopriv; - struct intf_hdl *pintfhdl = &(pio_priv->intf); + struct intf_hdl *pintfhdl = &pio_priv->intf; _write_port = pintfhdl->io_ops._write_port; diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index 98704179ad35..1ef48bf6581c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -179,8 +179,8 @@ void _rtw_free_network(struct mlme_priv *pmlmepriv, struct wlan_network *pnetwor if (pnetwork->fixed) return; - if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) || - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || + check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) lifetime = 1; if (!isfreeall) { @@ -267,7 +267,7 @@ signed int rtw_if_up(struct adapter *padapter) signed int res; if (padapter->bDriverStopped || padapter->bSurpriseRemoved || - (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == false)) + !check_fwstate(&padapter->mlmepriv, _FW_LINKED)) res = false; else res = true; @@ -283,8 +283,8 @@ void rtw_generate_random_ibss(u8 *pibss) pibss[1] = 0x11; pibss[2] = 0x87; pibss[3] = (u8)(curtime & 0xff) ;/* p[0]; */ - pibss[4] = (u8)((curtime>>8) & 0xff) ;/* p[1]; */ - pibss[5] = (u8)((curtime>>16) & 0xff) ;/* p[2]; */ + pibss[4] = (u8)((curtime >> 8) & 0xff) ;/* p[1]; */ + pibss[5] = (u8)((curtime >> 16) & 0xff) ;/* p[2]; */ } u8 *rtw_get_capability_from_ie(u8 *ie) @@ -433,14 +433,14 @@ void update_network(struct wlan_bssid_ex *dst, struct wlan_bssid_ex *src, sq_final = padapter->recvpriv.signal_qual; /* the rssi value here is undecorated, and will be used for antenna diversity */ if (sq_smp != 101) /* from the right channel */ - rssi_final = (src->rssi+dst->rssi*4)/5; + rssi_final = (src->rssi + dst->rssi * 4) / 5; else rssi_final = rssi_ori; } else { if (sq_smp != 101) { /* from the right channel */ - ss_final = ((u32)(src->phy_info.signal_strength)+(u32)(dst->phy_info.signal_strength)*4)/5; - sq_final = ((u32)(src->phy_info.signal_quality)+(u32)(dst->phy_info.signal_quality)*4)/5; - rssi_final = (src->rssi+dst->rssi*4)/5; + ss_final = ((u32)(src->phy_info.signal_strength) + (u32)(dst->phy_info.signal_strength) * 4) / 5; + sq_final = ((u32)(src->phy_info.signal_quality) + (u32)(dst->phy_info.signal_quality) * 4) / 5; + rssi_final = (src->rssi + dst->rssi * 4) / 5; } else { /* bss info not receiving from the right channel, use the original RX signal infos */ ss_final = dst->phy_info.signal_strength; @@ -469,7 +469,7 @@ static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex &pmlmepriv->cur_network.network, &pmlmepriv->cur_network.network); - if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&pmlmepriv->cur_network.network, pnetwork, 0))) { + if (check_fwstate(pmlmepriv, _FW_LINKED) && (is_same_network(&pmlmepriv->cur_network.network, pnetwork, 0))) { update_network(&pmlmepriv->cur_network.network, pnetwork, adapter, true); rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie), pmlmepriv->cur_network.network.ie_length); @@ -609,7 +609,7 @@ int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwor privacy = pnetwork->network.privacy; if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { - if (rtw_get_wps_ie(pnetwork->network.ies+_FIXED_IE_LENGTH_, pnetwork->network.ie_length-_FIXED_IE_LENGTH_, NULL, &wps_ielen)) + if (rtw_get_wps_ie(pnetwork->network.ies + _FIXED_IE_LENGTH_, pnetwork->network.ie_length - _FIXED_IE_LENGTH_, NULL, &wps_ielen)) return true; else return false; @@ -633,7 +633,7 @@ int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwor if ((desired_encmode != Ndis802_11EncryptionDisabled) && (privacy == 0)) bselected = false; - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { if (pnetwork->network.infrastructure_mode != pmlmepriv->cur_network.network.infrastructure_mode) bselected = false; } @@ -661,7 +661,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) spin_lock_bh(&pmlmepriv->lock); /* update IBSS_network 's timestamp */ - if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == true) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { if (!memcmp(&pmlmepriv->cur_network.network.mac_address, pnetwork->mac_address, ETH_ALEN)) { struct wlan_network *ibss_wlan = NULL; @@ -678,7 +678,7 @@ void rtw_survey_event_callback(struct adapter *adapter, u8 *pbuf) } /* lock pmlmepriv->lock when you accessing network_q */ - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == false) { + if (!check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) { if (pnetwork->ssid.ssid[0] == 0) pnetwork->ssid.ssid_length = 0; rtw_add_network(adapter, pnetwork); @@ -710,8 +710,8 @@ void rtw_surveydone_event_callback(struct adapter *adapter, u8 *pbuf) rtw_set_signal_stat_timer(&adapter->recvpriv); if (pmlmepriv->to_join) { - if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { - if (check_fwstate(pmlmepriv, _FW_LINKED) == false) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { + if (!check_fwstate(pmlmepriv, _FW_LINKED)) { set_fwstate(pmlmepriv, _FW_UNDER_LINKING); if (rtw_select_and_join_from_scanned_queue(pmlmepriv) == _SUCCESS) { @@ -819,15 +819,6 @@ static void free_scanqueue(struct mlme_priv *pmlmepriv) spin_unlock_bh(&scan_queue->lock); } -static void rtw_reset_rx_info(struct debug_priv *pdbgpriv) -{ - pdbgpriv->dbg_rx_ampdu_drop_count = 0; - pdbgpriv->dbg_rx_ampdu_forced_indicate_count = 0; - pdbgpriv->dbg_rx_ampdu_loss_count = 0; - pdbgpriv->dbg_rx_dup_mgt_frame_drop_count = 0; - pdbgpriv->dbg_rx_ampdu_window_shift_cnt = 0; -} - static void find_network(struct adapter *adapter) { struct wlan_network *pwlan = NULL; @@ -835,8 +826,10 @@ static void find_network(struct adapter *adapter) struct wlan_network *tgt_network = &pmlmepriv->cur_network; pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); - if (pwlan) - pwlan->fixed = false; + if (!pwlan) + return; + + pwlan->fixed = false; if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) && (adapter->stapriv.asoc_sta_count == 1)) @@ -848,17 +841,15 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) { struct mlme_priv *pmlmepriv = &adapter->mlmepriv; struct wlan_network *tgt_network = &pmlmepriv->cur_network; - struct dvobj_priv *psdpriv = adapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_AP_STATE)) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_AP_STATE)) { struct sta_info *psta; psta = rtw_get_stainfo(&adapter->stapriv, tgt_network->network.mac_address); rtw_free_stainfo(adapter, psta); } - if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE)) { struct sta_info *psta; rtw_free_all_stainfo(adapter); @@ -873,8 +864,6 @@ void rtw_free_assoc_resources(struct adapter *adapter, int lock_scanned_queue) if (lock_scanned_queue) adapter->securitypriv.key_mask = 0; - - rtw_reset_rx_info(pdbgpriv); } /* rtw_indicate_connect: the caller has to lock pmlmepriv->lock */ @@ -909,7 +898,7 @@ void rtw_indicate_disconnect(struct adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; - _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING|WIFI_UNDER_WPS); + _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING | WIFI_UNDER_WPS); if (rtw_to_roam(padapter) > 0) _clr_fwstate_(pmlmepriv, _FW_LINKED); @@ -940,7 +929,7 @@ inline void rtw_indicate_scan_done(struct adapter *padapter, bool aborted) if ((!adapter_to_pwrctl(padapter)->bInSuspend) && (!check_fwstate(&padapter->mlmepriv, - WIFI_ASOC_STATE|WIFI_UNDER_LINKING))) { + WIFI_ASOC_STATE | WIFI_UNDER_LINKING))) { rtw_set_ips_deny(padapter, 0); _set_timer(&padapter->mlmepriv.dynamic_chk_timer, 1); } @@ -1078,8 +1067,8 @@ static void rtw_joinbss_update_network(struct adapter *padapter, struct wlan_net switch (pnetwork->network.infrastructure_mode) { case Ndis802_11Infrastructure: - if (pmlmepriv->fw_state&WIFI_UNDER_WPS) - pmlmepriv->fw_state = WIFI_STATION_STATE|WIFI_UNDER_WPS; + if (pmlmepriv->fw_state & WIFI_UNDER_WPS) + pmlmepriv->fw_state = WIFI_STATION_STATE | WIFI_UNDER_WPS; else pmlmepriv->fw_state = WIFI_STATION_STATE; @@ -1206,7 +1195,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_free_stainfo(adapter, pcur_sta); ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, pnetwork->network.mac_address); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { if (ptarget_wlan) ptarget_wlan->fixed = true; } @@ -1214,7 +1203,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) } else { ptarget_wlan = _rtw_find_same_network(&pmlmepriv->scanned_queue, pnetwork); - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { if (ptarget_wlan) ptarget_wlan->fixed = true; } @@ -1231,7 +1220,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) } /* s3. find ptarget_sta & update ptarget_sta after update cur_network only for station mode */ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { ptarget_sta = rtw_joinbss_update_stainfo(adapter, pnetwork); if (!ptarget_sta) { spin_unlock_bh(&pmlmepriv->scanned_queue.lock); @@ -1240,7 +1229,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) } /* s4. indicate connect */ - if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { + if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { pmlmepriv->cur_network_scanned = ptarget_wlan; rtw_indicate_connect(adapter); } @@ -1258,7 +1247,7 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_reset_securitypriv(adapter); _set_timer(&pmlmepriv->assoc_timer, 1); - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == true) + if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); } else {/* if join_res < 0 (join fails), then try again */ @@ -1309,7 +1298,7 @@ void rtw_sta_media_status_rpt(struct adapter *adapter, struct sta_info *psta, u3 if (!psta) return; - media_status_rpt = (u16)((psta->mac_id<<8)|mstatus); /* MACID|OPMODE:1 connect */ + media_status_rpt = (u16)((psta->mac_id << 8) | mstatus); /* MACID|OPMODE:1 connect */ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status_rpt); } @@ -1337,10 +1326,9 @@ void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) /* report to upper layer */ spin_lock_bh(&psta->lock); if (psta->passoc_req && psta->assoc_req_len > 0) { - passoc_req = rtw_zmalloc(psta->assoc_req_len); + passoc_req = kmemdup(psta->passoc_req, psta->assoc_req_len, GFP_ATOMIC); if (passoc_req) { assoc_req_len = psta->assoc_req_len; - memcpy(passoc_req, psta->passoc_req, assoc_req_len); kfree(psta->passoc_req); psta->passoc_req = NULL; @@ -1386,8 +1374,8 @@ void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) spin_lock_bh(&pmlmepriv->lock); - if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) || - (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { + if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) || + check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { if (adapter->stapriv.asoc_sta_count == 2) { spin_lock_bh(&pmlmepriv->scanned_queue.lock); ptarget_wlan = rtw_find_network(&pmlmepriv->scanned_queue, cur_network->network.mac_address); @@ -1427,13 +1415,13 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) if (mac_id >= 0) { u16 media_status; - media_status = (mac_id<<8)|0; /* MACID|OPMODE:0 means disconnect */ + media_status = (mac_id << 8) | 0; /* MACID|OPMODE:0 means disconnect */ /* for STA, AP, ADHOC mode, report disconnect stauts to FW */ rtw_hal_set_hwreg(adapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status); } /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */ - if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) + if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) return; mlmeext_sta_del_event_callback(adapter); @@ -1562,10 +1550,10 @@ void _rtw_join_timeout_handler(struct timer_list *t) continue; break; - } else { - rtw_indicate_disconnect(adapter); - break; } + + rtw_indicate_disconnect(adapter); + break; } } else { @@ -1607,7 +1595,7 @@ void rtw_mlme_reset_auto_scan_int(struct adapter *adapter) if (pmlmeinfo->VHT_enable) /* disable auto scan when connect to 11AC AP */ mlme->auto_scan_int_ms = 0; else if (adapter->registrypriv.wifi_spec && is_client_associated_to_ap(adapter) == true) - mlme->auto_scan_int_ms = 60*1000; + mlme->auto_scan_int_ms = 60 * 1000; else if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) { if (check_fwstate(mlme, WIFI_STATION_STATE) && check_fwstate(mlme, _FW_LINKED)) mlme->auto_scan_int_ms = mlme->roam_scan_int_ms; @@ -1624,7 +1612,7 @@ static void rtw_auto_scan_handler(struct adapter *padapter) if (pmlmepriv->auto_scan_int_ms != 0 && jiffies_to_msecs(jiffies - pmlmepriv->scan_start_time) > pmlmepriv->auto_scan_int_ms) { if (!padapter->registrypriv.wifi_spec) { - if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == true) + if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) goto exit; if (pmlmepriv->LinkDetectInfo.bBusyTraffic) @@ -1866,7 +1854,7 @@ int rtw_select_and_join_from_scanned_queue(struct mlme_priv *pmlmepriv) candidate_exist: /* check for situation of _FW_LINKED */ - if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { + if (check_fwstate(pmlmepriv, _FW_LINKED)) { rtw_disassoc_cmd(adapter, 0, true); rtw_indicate_disconnect(adapter); rtw_free_assoc_resources(adapter, 0); @@ -1887,13 +1875,13 @@ signed int rtw_set_auth(struct adapter *adapter, struct security_priv *psecurity struct cmd_priv *pcmdpriv = &adapter->cmdpriv; signed int res = _SUCCESS; - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd); if (!pcmd) { res = _FAIL; /* try again */ goto exit; } - psetauthparm = rtw_zmalloc(sizeof(struct setauth_parm)); + psetauthparm = kzalloc_obj(*psetauthparm); if (!psetauthparm) { kfree(pcmd); res = _FAIL; @@ -1924,7 +1912,7 @@ signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecurityp struct cmd_priv *pcmdpriv = &adapter->cmdpriv; signed int res = _SUCCESS; - psetkeyparm = rtw_zmalloc(sizeof(struct setkey_parm)); + psetkeyparm = kzalloc_obj(*psetkeyparm); if (!psetkeyparm) { res = _FAIL; goto exit; @@ -1966,7 +1954,7 @@ signed int rtw_set_key(struct adapter *adapter, struct security_priv *psecurityp } if (enqueue) { - pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd = kzalloc_obj(*pcmd); if (!pcmd) { kfree(psetkeyparm); res = _FAIL; /* try again */ @@ -2000,7 +1988,10 @@ int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_ while (i < in_len) { ielength = initial_out_len; - if (in_ie[i] == 0xDD && in_ie[i+2] == 0x00 && in_ie[i+3] == 0x50 && in_ie[i+4] == 0xF2 && in_ie[i+5] == 0x02 && i+5 < in_len) { /* WMM element ID and OUI */ + if (i + 5 < in_len && + in_ie[i] == 0xDD && in_ie[i + 2] == 0x00 && + in_ie[i + 3] == 0x50 && in_ie[i + 4] == 0xF2 && + in_ie[i + 5] == 0x02) { for (j = i; j < i + 9; j++) { out_ie[ielength] = in_ie[j]; ielength++; @@ -2012,13 +2003,13 @@ int rtw_restruct_wmm_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, uint in_ break; } - i += (in_ie[i+1]+2); /* to the next IE element */ + i += (in_ie[i + 1] + 2); /* to the next IE element */ } return ielength; } -/* Ported from 8185: IsInPreAuthKeyList(). +/* Ported from 8185: IsInPreAuthKeyList(). * (Renamed from SecIsInPreAuthKeyList(), 2006-10-13.) * Added by Annie, 2006-05-07. * @@ -2068,12 +2059,12 @@ static int rtw_append_pmkid(struct adapter *Adapter, int iEntry, u8 *ie, uint ie static void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) { uint len; - u8 *buff, *p, i; + u8 *buff, *p; union iwreq_data wrqu; buff = NULL; if (authmode == WLAN_EID_VENDOR_SPECIFIC) { - buff = rtw_zmalloc(IW_CUSTOM_MAX); + buff = kzalloc(IW_CUSTOM_MAX, GFP_ATOMIC); if (!buff) return; @@ -2084,8 +2075,7 @@ static void rtw_report_sec_ie(struct adapter *adapter, u8 authmode, u8 *sec_ie) len = sec_ie[1] + 2; len = (len < IW_CUSTOM_MAX) ? len : IW_CUSTOM_MAX; - for (i = 0; i < len; i++) - p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), "%02x", sec_ie[i]); + p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), " %*ph", len, sec_ie); p += scnprintf(p, IW_CUSTOM_MAX - (p - buff), ")"); @@ -2118,13 +2108,13 @@ signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, u authmode = WLAN_EID_RSN; if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) { - memcpy(out_ie+ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); + memcpy(out_ie + ielength, psecuritypriv->wps_ie, psecuritypriv->wps_ie_len); ielength += psecuritypriv->wps_ie_len; } else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) { /* copy RSN or SSN */ - memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2); - ielength += psecuritypriv->supplicant_ie[1]+2; + memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1] + 2); + ielength += psecuritypriv->supplicant_ie[1] + 2; rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); } @@ -2292,7 +2282,7 @@ void rtw_build_wmm_ie_ht(struct adapter *padapter, u8 *out_ie, uint *pout_len) if (padapter->mlmepriv.qospriv.qos_option == 0) { out_len = *pout_len; - rtw_set_ie(out_ie+out_len, WLAN_EID_VENDOR_SPECIFIC, + rtw_set_ie(out_ie + out_len, WLAN_EID_VENDOR_SPECIFIC, _WMM_IE_Length_, WMM_IE, pout_len); padapter->mlmepriv.qospriv.qos_option = 1; @@ -2336,7 +2326,7 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ } else { p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len); if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { - struct HT_info_element *pht_info = (struct HT_info_element *)(p+2); + struct HT_info_element *pht_info = (struct HT_info_element *)(p + 2); if (pht_info->infos[0] & BIT(2)) { switch (pht_info->infos[0] & 0x3) { @@ -2399,14 +2389,14 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); - ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03); + ht_capie.ampdu_params_info = (max_rx_ampdu_factor & 0x03); if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) - ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&(0x07<<2)); + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & (0x07 << 2)); else - ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY&0x00); + ht_capie.ampdu_params_info |= (IEEE80211_HT_CAP_AMPDU_DENSITY & 0x00); - rtw_set_ie(out_ie+out_len, WLAN_EID_HT_CAPABILITY, + rtw_set_ie(out_ie + out_len, WLAN_EID_HT_CAPABILITY, sizeof(struct ieee80211_ht_cap), (unsigned char *)&ht_capie, pout_len); phtpriv->ht_option = true; @@ -2415,7 +2405,7 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ p = rtw_get_ie(in_ie, WLAN_EID_HT_OPERATION, &ielen, in_len); if (p && (ielen == sizeof(struct ieee80211_ht_addt_info))) { out_len = *pout_len; - rtw_set_ie(out_ie+out_len, WLAN_EID_HT_OPERATION, ielen, p+2, pout_len); + rtw_set_ie(out_ie + out_len, WLAN_EID_HT_OPERATION, ielen, p + 2, pout_len); } } @@ -2447,17 +2437,17 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channe /* check Max Rx A-MPDU Size */ len = 0; - p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_CAPABILITY, &len, ie_len-sizeof(struct ndis_802_11_fix_ie)); + p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_CAPABILITY, &len, ie_len - sizeof(struct ndis_802_11_fix_ie)); if (p && len > 0) { - pht_capie = (struct ieee80211_ht_cap *)(p+2); + pht_capie = (struct ieee80211_ht_cap *)(p + 2); max_ampdu_sz = (pht_capie->ampdu_params_info & IEEE80211_HT_CAP_AMPDU_FACTOR); - max_ampdu_sz = 1 << (max_ampdu_sz+3); /* max_ampdu_sz (kbytes); */ + max_ampdu_sz = 1 << (max_ampdu_sz + 3); /* max_ampdu_sz (kbytes); */ phtpriv->rx_ampdu_maxlen = max_ampdu_sz; } len = 0; - p = rtw_get_ie(pie+sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_OPERATION, &len, ie_len-sizeof(struct ndis_802_11_fix_ie)); + p = rtw_get_ie(pie + sizeof(struct ndis_802_11_fix_ie), WLAN_EID_HT_OPERATION, &len, ie_len - sizeof(struct ndis_802_11_fix_ie)); if (p && len > 0) { /* todo: */ } @@ -2536,8 +2526,8 @@ void rtw_issue_addbareq_cmd(struct adapter *padapter, struct xmit_frame *pxmitfr phtpriv = &psta->htpriv; if (phtpriv->ht_option && phtpriv->ampdu_enable) { - issued = (phtpriv->agg_enable_bitmap>>priority)&0x1; - issued |= (phtpriv->candidate_tid_bitmap>>priority)&0x1; + issued = (phtpriv->agg_enable_bitmap >> priority) & 0x1; + issued |= (phtpriv->candidate_tid_bitmap >> priority) & 0x1; if (issued == 0) { psta->htpriv.candidate_tid_bitmap |= BIT((u8)priority); @@ -2607,12 +2597,12 @@ void _rtw_roaming(struct adapter *padapter, struct wlan_network *tgt_network) signed int rtw_linked_check(struct adapter *padapter) { - if ((check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == true) || - (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == true)) { + if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) || + check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { if (padapter->stapriv.asoc_sta_count > 2) return true; } else { /* Station mode */ - if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == true) + if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) return true; } return false; diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c index ac49bfbaa5bb..b1f20aa81efb 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme_ext.c @@ -438,8 +438,6 @@ void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; u8 *pframe = precv_frame->u.hdr.rx_data; struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; if (GetFrameType(pframe) != WIFI_MGT_TYPE) return; @@ -463,7 +461,6 @@ void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame) if (GetRetry(pframe)) { if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) { /* drop the duplicate management frame */ - pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++; return; } } @@ -562,7 +559,7 @@ unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) int cam_idx; struct sta_info *psta; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct sta_priv *pstapriv = &padapter->stapriv; u8 *pframe = precv_frame->u.hdr.rx_data; @@ -589,7 +586,7 @@ unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { /* we should update current network before auth, or some IE is wrong */ - pbss = rtw_malloc(sizeof(struct wlan_bssid_ex)); + pbss = kmalloc_obj(*pbss, GFP_ATOMIC); if (pbss) { if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true); @@ -681,7 +678,7 @@ unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame) struct sta_priv *pstapriv = &padapter->stapriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->u.hdr.rx_data; uint len = precv_frame->u.hdr.len; u8 offset = 0; @@ -858,7 +855,7 @@ unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_fram unsigned char *p; unsigned int go2asoc = 0; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->u.hdr.rx_data; uint pkt_len = precv_frame->u.hdr.len; @@ -944,7 +941,7 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct security_priv *psecuritypriv = &padapter->securitypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur = &(pmlmeinfo->network); struct sta_priv *pstapriv = &padapter->stapriv; u8 *pframe = precv_frame->u.hdr.rx_data; @@ -1120,11 +1117,10 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); if (!wpa_ie) { - if (elems.wps_ie) { + if (elems.wps_ie) pstat->flags |= WLAN_STA_WPS; - } else { + else pstat->flags |= WLAN_STA_MAYBE_WPS; - } /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */ @@ -1181,50 +1177,50 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; for (;;) { p = rtw_get_ie(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); - if (p) { - if (!memcmp(p+2, WMM_IE, 6)) { - - pstat->flags |= WLAN_STA_WME; - - pstat->qos_option = 1; - pstat->qos_info = *(p+8); - - pstat->max_sp_len = (pstat->qos_info>>5)&0x3; - - if ((pstat->qos_info&0xf) != 0xf) - pstat->has_legacy_ac = true; - else - pstat->has_legacy_ac = false; - - if (pstat->qos_info&0xf) { - if (pstat->qos_info&BIT(0)) - pstat->uapsd_vo = BIT(0)|BIT(1); - else - pstat->uapsd_vo = 0; - - if (pstat->qos_info&BIT(1)) - pstat->uapsd_vi = BIT(0)|BIT(1); - else - pstat->uapsd_vi = 0; - - if (pstat->qos_info&BIT(2)) - pstat->uapsd_bk = BIT(0)|BIT(1); - else - pstat->uapsd_bk = 0; - - if (pstat->qos_info&BIT(3)) - pstat->uapsd_be = BIT(0)|BIT(1); - else - pstat->uapsd_be = 0; - - } - - break; - } - } else { + if (!p) break; + + if (memcmp(p+2, WMM_IE, 6)) { + p = p + ie_len + 2; + continue; } - p = p + ie_len + 2; + + pstat->flags |= WLAN_STA_WME; + + pstat->qos_option = 1; + pstat->qos_info = *(p+8); + + pstat->max_sp_len = (pstat->qos_info>>5)&0x3; + + if ((pstat->qos_info&0xf) != 0xf) + pstat->has_legacy_ac = true; + else + pstat->has_legacy_ac = false; + + if (pstat->qos_info&0xf) { + if (pstat->qos_info&BIT(0)) + pstat->uapsd_vo = BIT(0)|BIT(1); + else + pstat->uapsd_vo = 0; + + if (pstat->qos_info&BIT(1)) + pstat->uapsd_vi = BIT(0)|BIT(1); + else + pstat->uapsd_vi = 0; + + if (pstat->qos_info&BIT(2)) + pstat->uapsd_bk = BIT(0)|BIT(1); + else + pstat->uapsd_bk = 0; + + if (pstat->qos_info&BIT(3)) + pstat->uapsd_be = BIT(0)|BIT(1); + else + pstat->uapsd_be = 0; + + } + + break; } } @@ -1266,19 +1262,12 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) else pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; - - - if (status != WLAN_STATUS_SUCCESS) - goto OnAssocReqFail; - /* TODO: identify_proprietary_vendor_ie(); */ /* Realtek proprietary IE */ /* identify if this is Broadcom sta */ /* identify if this is ralink sta */ /* Customer proprietary IE */ - - /* get a unique AID */ if (pstat->aid == 0) { for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) @@ -1334,11 +1323,10 @@ unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) spin_lock_bh(&pstat->lock); kfree(pstat->passoc_req); pstat->assoc_req_len = 0; - pstat->passoc_req = rtw_zmalloc(pkt_len); - if (pstat->passoc_req) { - memcpy(pstat->passoc_req, pframe, pkt_len); + pstat->passoc_req = kmemdup(pframe, pkt_len, GFP_ATOMIC); + if (pstat->passoc_req) pstat->assoc_req_len = pkt_len; - } + spin_unlock_bh(&pstat->lock); /* 3-(1) report sta add event */ @@ -1372,7 +1360,7 @@ unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame) struct ndis_80211_var_ie *pIE; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ u8 *pframe = precv_frame->u.hdr.rx_data; uint pkt_len = precv_frame->u.hdr.len; @@ -1459,7 +1447,7 @@ unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame) unsigned short reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->u.hdr.rx_data; int ignore_received_deauth = 0; @@ -1532,7 +1520,7 @@ unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame) unsigned short reason; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->u.hdr.rx_data; /* check A3 */ @@ -1628,7 +1616,7 @@ unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_fra unsigned char category, action; unsigned short tid, status; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 *pframe = precv_frame->u.hdr.rx_data; struct sta_priv *pstapriv = &padapter->stapriv; @@ -1849,7 +1837,6 @@ unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame) { u8 *pframe = precv_frame->u.hdr.rx_data; - struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); unsigned short tid; @@ -1865,14 +1852,6 @@ unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv default: break; } - if (0) { - int pp; - - netdev_dbg(padapter->pnetdev, "pattrib->pktlen = %d =>", pattrib->pkt_len); - for (pp = 0; pp < pattrib->pkt_len; pp++) - pr_cont(" %02x ", pframe[pp]); - pr_cont("\n"); - } return _SUCCESS; } @@ -2115,7 +2094,7 @@ void issue_beacon(struct adapter *padapter, int timeout_ms) struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); pmgntframe = alloc_mgtxmitframe(pxmitpriv); @@ -2263,7 +2242,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p uint wps_ielen; struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); unsigned int rate_len; @@ -2348,7 +2327,7 @@ void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p u8 *buf; u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr); - buf = rtw_zmalloc(MAX_IE_SZ); + buf = kzalloc(MAX_IE_SZ, GFP_ATOMIC); if (!buf) return; @@ -2586,7 +2565,7 @@ void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short int use_shared_key = 0; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; __le16 le_tmp; pmgntframe = alloc_mgtxmitframe(pxmitpriv); @@ -2714,7 +2693,7 @@ void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_i struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); u8 *ie = pnetwork->ies; __le16 lestatus, le_tmp; @@ -2845,7 +2824,7 @@ void issue_assocreq(struct adapter *padapter) struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; int bssrate_len = 0, sta_bssrate_len = 0; u8 vs_ie_length = 0; @@ -3024,7 +3003,7 @@ static int _issue_nulldata(struct adapter *padapter, unsigned char *da, pxmitpriv = &(padapter->xmitpriv); pmlmeext = &(padapter->mlmeextpriv); - pmlmeinfo = &(pmlmeext->mlmext_info); + pmlmeinfo = &pmlmeext->mlmext_info; pmgntframe = alloc_mgtxmitframe(pxmitpriv); if (!pmgntframe) @@ -3086,7 +3065,7 @@ int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int pow int ret; int i = 0; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct sta_info *psta; @@ -3163,7 +3142,7 @@ static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 *qc; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; pmgntframe = alloc_mgtxmitframe(pxmitpriv); if (!pmgntframe) @@ -3231,7 +3210,7 @@ int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int int ret; int i = 0; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; /* da == NULL, assume it's null data for sta to ap*/ if (!da) @@ -3271,7 +3250,7 @@ static int _issue_deauth(struct adapter *padapter, unsigned char *da, __le16 *fctrl; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; int ret = _FAIL; __le16 le_tmp; @@ -3365,7 +3344,7 @@ void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsig __le16 *fctrl; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; __le16 le_tmp; pmgntframe = alloc_mgtxmitframe(pxmitpriv); @@ -3438,7 +3417,7 @@ void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned ch __le16 *fctrl; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct sta_info *psta; struct sta_priv *pstapriv = &padapter->stapriv; struct registry_priv *pregpriv = &padapter->registrypriv; @@ -3586,7 +3565,7 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter) struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct __queue *queue = &(pmlmepriv->scanned_queue); u8 InfoContent[16] = {0}; u8 ICS[8][15]; @@ -3684,29 +3663,29 @@ static void issue_action_BSSCoexistPacket(struct adapter *padapter) for (i = 0; i < 8; i++) { - if (ICS[i][0] == 1) { - int j, k = 0; + int j, k = 0; - InfoContent[k] = i; - /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ - k++; + if (ICS[i][0] != 1) + continue; - for (j = 1; j <= 14; j++) { - if (ICS[i][j] == 1) { - if (k < 16) { - InfoContent[k] = j; /* channel number */ - /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ - k++; - } - } + InfoContent[k] = i; + /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ + k++; + + for (j = 1; j <= 14; j++) { + if (ICS[i][j] != 1) + continue; + + if (k < 16) { + InfoContent[k] = j; /* channel number */ + /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ + k++; } - - pframe = rtw_set_ie(pframe, WLAN_EID_BSS_INTOLERANT_CHL_REPORT, k, InfoContent, &(pattrib->pktlen)); - } - } + pframe = rtw_set_ie(pframe, WLAN_EID_BSS_INTOLERANT_CHL_REPORT, k, InfoContent, &(pattrib->pktlen)); + } } @@ -3722,7 +3701,7 @@ unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) struct sta_info *psta = NULL; /* struct recv_reorder_ctrl *preorder_ctrl; */ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u16 tid; if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) @@ -3791,7 +3770,7 @@ void site_survey(struct adapter *padapter) unsigned char survey_channel = 0, val8; enum rt_scan_type ScanType = SCAN_PASSIVE; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u32 initialgain = 0; u32 channel_scan_time_ms = 0; @@ -3831,14 +3810,16 @@ void site_survey(struct adapter *padapter) int i; for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { - if (pmlmeext->sitesurvey_res.ssid[i].ssid_length) { - /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ - if (padapter->registrypriv.wifi_spec) - issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); - else - issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0); + if (!pmlmeext->sitesurvey_res.ssid[i].ssid_length) + continue; + + /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ + if (padapter->registrypriv.wifi_spec) issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); - } + else + issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0); + + issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); } if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { @@ -3872,7 +3853,7 @@ void site_survey(struct adapter *padapter) /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ /* config MSR */ - Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + set_msr(padapter, (pmlmeinfo->state & 0x3)); initialgain = 0xff; /* restore RX GAIN */ rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); @@ -3913,7 +3894,7 @@ u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, str u8 ie_offset; struct registry_priv *pregistrypriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; __le32 le32_tmp; len = packet_len - sizeof(struct ieee80211_hdr_3addr); @@ -4063,7 +4044,7 @@ void start_create_ibss(struct adapter *padapter) u8 val8; u8 join_type; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); pmlmeext->cur_channel = (u8)pnetwork->configuration.ds_config; @@ -4089,7 +4070,7 @@ void start_create_ibss(struct adapter *padapter) /* set msr to WIFI_FW_ADHOC_STATE */ pmlmeinfo->state = WIFI_FW_ADHOC_STATE; - Set_MSR(padapter, (pmlmeinfo->state & 0x3)); + set_msr(padapter, (pmlmeinfo->state & 0x3)); /* issue beacon */ if (send_beacon(padapter) == _FAIL) { @@ -4117,7 +4098,7 @@ void start_clnt_join(struct adapter *padapter) unsigned short caps; u8 val8; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); int beacon_timeout; @@ -4128,7 +4109,7 @@ void start_clnt_join(struct adapter *padapter) caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); update_capinfo(padapter, caps); if (caps&WLAN_CAPABILITY_ESS) { - Set_MSR(padapter, WIFI_FW_STATION_STATE); + set_msr(padapter, WIFI_FW_STATION_STATE); val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; @@ -4155,7 +4136,7 @@ void start_clnt_join(struct adapter *padapter) pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; } else if (caps&WLAN_CAPABILITY_IBSS) { /* adhoc client */ - Set_MSR(padapter, WIFI_FW_ADHOC_STATE); + set_msr(padapter, WIFI_FW_ADHOC_STATE); val8 = 0xcf; rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); @@ -4174,7 +4155,7 @@ void start_clnt_join(struct adapter *padapter) void start_clnt_auth(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; timer_delete_sync(&pmlmeext->link_timer); @@ -4199,7 +4180,7 @@ void start_clnt_auth(struct adapter *padapter) void start_clnt_assoc(struct adapter *padapter) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; timer_delete_sync(&pmlmeext->link_timer); @@ -4214,7 +4195,7 @@ void start_clnt_assoc(struct adapter *padapter) unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; /* check A3 */ if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) @@ -4395,12 +4376,12 @@ void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame pmlmeext = &padapter->mlmeextpriv; pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4448,12 +4429,12 @@ void report_surveydone_event(struct adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4490,15 +4471,15 @@ void report_join_res(struct adapter *padapter, int res) struct joinbss_event *pjoinbss_evt; struct C2HEvent_Header *pc2h_evt_hdr; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4542,12 +4523,12 @@ void report_wmm_edca_update(struct adapter *padapter) struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4588,12 +4569,12 @@ void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsi struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4639,12 +4620,12 @@ void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; - pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); + pcmd_obj = kzalloc_obj(*pcmd_obj, GFP_ATOMIC); if (!pcmd_obj) return; cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); - pevtcmd = rtw_zmalloc(cmdsz); + pevtcmd = kzalloc(cmdsz, GFP_ATOMIC); if (!pevtcmd) { kfree(pcmd_obj); return; @@ -4678,7 +4659,7 @@ void update_sta_info(struct adapter *padapter, struct sta_info *psta) { struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; /* ERP */ VCS_update(padapter, psta); @@ -4738,7 +4719,7 @@ static void rtw_mlmeext_disconnect(struct adapter *padapter) { struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); /* set_opmode_cmd(padapter, infra_client_with_mlme); */ @@ -4761,7 +4742,7 @@ static void rtw_mlmeext_disconnect(struct adapter *padapter) rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); /* set MSR to no link state -> infra. mode */ - Set_MSR(padapter, _HW_STATE_STATION_); + set_msr(padapter, _HW_STATE_STATION_); pmlmeinfo->state = WIFI_FW_NULL_STATE; @@ -4784,7 +4765,7 @@ static void rtw_mlmeext_disconnect(struct adapter *padapter) void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); struct sta_priv *pstapriv = &padapter->stapriv; u8 join_type; @@ -4862,7 +4843,7 @@ void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta) { struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 join_type; if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { @@ -4923,14 +4904,16 @@ void _linked_info_dump(struct adapter *padapter) { int i; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; int UndecoratedSmoothedPWDB; struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); if (padapter->bLinkInfoDump) { if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) - rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); + rtw_hal_get_def_var(padapter, + HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, + &UndecoratedSmoothedPWDB); for (i = 0; i < NUM_STA; i++) { if (pdvobj->macid[i]) { @@ -4966,10 +4949,9 @@ void linked_status_chk(struct adapter *padapter) struct sta_info *psta; struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct sta_priv *pstapriv = &padapter->stapriv; - if (is_client_associated_to_ap(padapter)) { /* linked infrastructure client mode */ @@ -4985,7 +4967,8 @@ void linked_status_chk(struct adapter *padapter) link_count_limit = 7; /* 16 sec */ /* Marked by Kurt 20130715 */ - /* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */ + /* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, */ + /* so we could not check rx limit that strictly. */ /* todo: To check why we under miracast session, rx_chk would be false */ psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.mac_address); if (psta) { @@ -4998,9 +4981,18 @@ void linked_status_chk(struct adapter *padapter) { if (rx_chk != _SUCCESS) { if (pmlmeext->retry == 0) { - issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0); - issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0); - issue_probereq_ex(padapter, &pmlmeinfo->network.ssid, pmlmeinfo->network.mac_address, 0, 0, 0, 0); + issue_probereq_ex(padapter, + &pmlmeinfo->network.ssid, + pmlmeinfo->network.mac_address, + 0, 0, 0, 0); + issue_probereq_ex(padapter, + &pmlmeinfo->network.ssid, + pmlmeinfo->network.mac_address, + 0, 0, 0, 0); + issue_probereq_ex(padapter, + &pmlmeinfo->network.ssid, + pmlmeinfo->network.mac_address, + 0, 0, 0, 0); } } @@ -5024,7 +5016,7 @@ void linked_status_chk(struct adapter *padapter) } if (tx_chk == _FAIL) { - pmlmeinfo->link_count %= (link_count_limit+1); + pmlmeinfo->link_count %= (link_count_limit + 1); } else { pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; pmlmeinfo->link_count = 0; @@ -5042,7 +5034,6 @@ void linked_status_chk(struct adapter *padapter) continue; if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) { - if (pmlmeinfo->FW_sta_info[i].retry < 3) { pmlmeinfo->FW_sta_info[i].retry++; } else { @@ -5060,9 +5051,7 @@ void linked_status_chk(struct adapter *padapter) } /* set_link_timer(pmlmeext, DISCONNECT_TO); */ - } - } void survey_timer_hdl(struct timer_list *t) @@ -5085,11 +5074,11 @@ void survey_timer_hdl(struct timer_list *t) pmlmeext->scan_abort = false;/* reset */ } - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) return; - psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); + psurveyPara = kzalloc_obj(*psurveyPara, GFP_ATOMIC); if (!psurveyPara) { kfree(ph2c); return; @@ -5105,7 +5094,7 @@ void link_timer_hdl(struct timer_list *t) struct adapter *padapter = timer_container_of(padapter, t, mlmeextpriv.link_timer); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { @@ -5178,7 +5167,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) { u8 type; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; if (psetop->mode == Ndis802_11APMode) { @@ -5186,7 +5175,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) type = _HW_STATE_AP_; /* start_ap_mode(padapter); */ } else if (psetop->mode == Ndis802_11Infrastructure) { - pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */ + pmlmeinfo->state &= ~(BIT(0) | BIT(1));/* clear state */ pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */ type = _HW_STATE_STATION_; } else if (psetop->mode == Ndis802_11IBSS) { @@ -5196,7 +5185,7 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) } rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); - /* Set_MSR(padapter, type); */ + /* set_msr(padapter, type); */ if (psetop->mode == Ndis802_11APMode) { /* Do this after port switch to */ @@ -5205,13 +5194,12 @@ u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) } return H2C_SUCCESS; - } u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) { struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; /* u32 initialgain; */ @@ -5271,7 +5259,7 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) struct ndis_80211_var_ie *pIE; struct registry_priv *pregpriv = &padapter->registrypriv; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); u32 i; u8 cbw40_enable = 0; @@ -5291,8 +5279,8 @@ u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) timer_delete_sync(&pmlmeext->link_timer); /* set MSR to nolink -> infra. mode */ - /* Set_MSR(padapter, _HW_STATE_NOLINK_); */ - Set_MSR(padapter, _HW_STATE_STATION_); + /* set_msr(padapter, _HW_STATE_NOLINK_); */ + set_msr(padapter, _HW_STATE_STATION_); rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); @@ -5413,7 +5401,7 @@ u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) { struct disconnect_parm *param = (struct disconnect_parm *)pbuf; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); u8 val8; @@ -5509,8 +5497,11 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { if (pparm->ssid[i].ssid_length) { - memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid, pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE); - pmlmeext->sitesurvey_res.ssid[i].ssid_length = pparm->ssid[i].ssid_length; + memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid, + pparm->ssid[i].ssid, + IW_ESSID_MAX_SIZE); + pmlmeext->sitesurvey_res.ssid[i].ssid_length = + pparm->ssid[i].ssid_length; } else { pmlmeext->sitesurvey_res.ssid[i].ssid_length = 0; } @@ -5538,7 +5529,8 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) } } - if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { + if ((pmlmeext->sitesurvey_res.state == SCAN_START) || + (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { /* disable dynamic functions, such as high power, DIG */ Save_DM_Func_Flag(padapter); Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); @@ -5551,7 +5543,7 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); /* set MSR to no link state */ - Set_MSR(padapter, _HW_STATE_NOLINK_); + set_msr(padapter, _HW_STATE_NOLINK_); val8 = 1; /* under site survey */ rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); @@ -5562,14 +5554,13 @@ u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) site_survey(padapter); return H2C_SUCCESS; - } u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf) { struct setauth_parm *pparm = (struct setauth_parm *)pbuf; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; if (pparm->mode < 4) pmlmeinfo->auth_algo = pparm->mode; @@ -5583,7 +5574,7 @@ u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) s16 cam_id = 0; struct setkey_parm *pparm = (struct setkey_parm *)pbuf; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; u8 *addr; @@ -5604,7 +5595,7 @@ u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) write_cam(padapter, cam_id, ctrl, addr, pparm->key); netdev_dbg(padapter->pnetdev, "set group key camid:%d, addr:%pM, kid:%d, type:%s\n", - cam_id, MAC_ARG(addr), pparm->keyid, + cam_id, addr, pparm->keyid, security_type_str(pparm->algorithm)); } @@ -5623,7 +5614,7 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) s16 cam_id = 0; u8 ret = H2C_SUCCESS; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; struct sta_priv *pstapriv = &padapter->stapriv; struct sta_info *psta; @@ -5634,7 +5625,7 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) psta = rtw_get_stainfo(pstapriv, pparm->addr); if (!psta) { netdev_dbg(padapter->pnetdev, "%s sta:%pM not found\n", - __func__, MAC_ARG(pparm->addr)); + __func__, pparm->addr); ret = H2C_REJECTED; goto exit; } @@ -5649,14 +5640,14 @@ u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) { netdev_dbg(padapter->pnetdev, "clear key for addr:%pM, camid:%d\n", - MAC_ARG(pparm->addr), cam_id); + pparm->addr, cam_id); clear_cam_entry(padapter, cam_id); rtw_camid_free(padapter, cam_id); } } else { netdev_dbg(padapter->pnetdev, "set pairwise key camid:%d, addr:%pM, kid:%d, type:%s\n", - cam_id, MAC_ARG(pparm->addr), pparm->keyid, + cam_id, pparm->addr, pparm->keyid, security_type_str(pparm->algorithm)); ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); @@ -5671,7 +5662,7 @@ u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) { struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); @@ -5692,14 +5683,13 @@ u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) return H2C_SUCCESS; } - u8 chk_bmc_sleepq_cmd(struct adapter *padapter) { struct cmd_obj *ph2c; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); u8 res = _SUCCESS; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; @@ -5719,17 +5709,17 @@ u8 set_tx_beacon_cmd(struct adapter *padapter) struct Tx_Beacon_param *ptxBeacon_parm; struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; - struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); + struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; u8 res = _SUCCESS; int len_diff = 0; - ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); + ph2c = kzalloc_obj(*ph2c, GFP_ATOMIC); if (!ph2c) { res = _FAIL; goto exit; } - ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param)); + ptxBeacon_parm = kzalloc_obj(*ptxBeacon_parm, GFP_ATOMIC); if (!ptxBeacon_parm) { kfree(ph2c); res = _FAIL; @@ -5738,8 +5728,8 @@ u8 set_tx_beacon_cmd(struct adapter *padapter) memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex)); - len_diff = update_hidden_ssid(ptxBeacon_parm->network.ies+_BEACON_IE_OFFSET_, - ptxBeacon_parm->network.ie_length-_BEACON_IE_OFFSET_, + len_diff = update_hidden_ssid(ptxBeacon_parm->network.ies + _BEACON_IE_OFFSET_, + ptxBeacon_parm->network.ie_length - _BEACON_IE_OFFSET_, pmlmeinfo->hidden_ssid_mode); ptxBeacon_parm->network.ie_length += len_diff; @@ -5794,8 +5784,8 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) goto _abort_event_; peventbuf = (uint *)pbuf; - evt_sz = (u16)(*peventbuf&0xffff); - evt_code = (u8)((*peventbuf>>16)&0xff); + evt_sz = (u16)(*peventbuf & 0xffff); + evt_code = (u8)((*peventbuf >> 16) & 0xff); /* checking if event code is valid */ if (evt_code >= MAX_C2HEVT) @@ -5803,7 +5793,7 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) /* checking if event size match the event parm size */ if ((wlanevents[evt_code].parmsize != 0) && - (wlanevents[evt_code].parmsize != evt_sz)) + (wlanevents[evt_code].parmsize != evt_sz)) goto _abort_event_; atomic_inc(&pevt_priv->event_seq); @@ -5817,12 +5807,8 @@ u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) pevt_priv->evt_done_cnt++; } - _abort_event_: - - return H2C_SUCCESS; - } u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf) @@ -5846,7 +5832,7 @@ u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) if (!psta_bmc) return H2C_SUCCESS; - if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) { + if ((pstapriv->tim_bitmap & BIT(0)) && (psta_bmc->sleepq_len > 0)) { msleep(10);/* 10ms, ATIM(HIQ) Windows */ /* spin_lock_bh(&psta_bmc->sleep_q.lock); */ @@ -5945,8 +5931,13 @@ u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf) setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; - pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); - init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); + pmlmeext->max_chan_nums = init_channel_set(padapter, + setChannelPlan_param->channel_plan, + pmlmeext->channel_set); + init_channel_list(padapter, + pmlmeext->channel_set, + pmlmeext->max_chan_nums, + &pmlmeext->channel_list); if (padapter->rtw_wdev && padapter->rtw_wdev->wiphy) { struct regulatory_request request; @@ -5966,9 +5957,10 @@ u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf) /* TDLS_ESTABLISHED : write RCR DATA BIT */ /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */ /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */ -/* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */ +/* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */ /* TDLS_OFF_CH : first time set channel to off channel */ -/* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */ +/* TDLS_BASE_CH : go back tp the channel linked with AP when set */ +/* base channel as target channel */ /* TDLS_P_OFF_CH : periodically go to off channel */ /* TDLS_P_BASE_CH : periodically go back to base channel */ /* TDLS_RS_RCR : restore RCR */ @@ -5982,8 +5974,7 @@ u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf) { struct RunInThread_param *p; - - if (pbuf == NULL) + if (!pbuf) return H2C_PARAMETERS_ERROR; p = (struct RunInThread_param *)pbuf; diff --git a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c index 0ef788abf403..1c9e02732687 100644 --- a/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c +++ b/drivers/staging/rtl8723bs/core/rtw_pwrctrl.c @@ -139,8 +139,6 @@ static bool rtw_pwr_unassociated_idle(struct adapter *adapter) void rtw_ps_processor(struct adapter *padapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; u32 ps_deny = 0; mutex_lock(&adapter_to_pwrctl(padapter)->lock); @@ -149,10 +147,8 @@ void rtw_ps_processor(struct adapter *padapter) if (ps_deny != 0) goto exit; - if (pwrpriv->bInSuspend) {/* system suspend or autosuspend */ - pdbgpriv->dbg_ps_insuspend_cnt++; + if (pwrpriv->bInSuspend) /* system suspend or autosuspend */ return; - } pwrpriv->ps_processing = true; diff --git a/drivers/staging/rtl8723bs/core/rtw_recv.c b/drivers/staging/rtl8723bs/core/rtw_recv.c index e893cb6fa273..337671b1211f 100644 --- a/drivers/staging/rtl8723bs/core/rtw_recv.c +++ b/drivers/staging/rtl8723bs/core/rtw_recv.c @@ -501,7 +501,7 @@ static union recv_frame *portctrl(struct adapter *adapter, union recv_frame *pre { u8 *psta_addr = NULL; u8 *ptr; - uint auth_alg; + unsigned int auth_alg; struct recv_frame_hdr *pfhdr; struct sta_info *psta; struct sta_priv *pstapriv; @@ -1425,7 +1425,7 @@ static signed int validate_80211w_mgmt(struct adapter *adapter, union recv_frame memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); /* actual management data frame body */ data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; - mgmt_DATA = rtw_zmalloc(data_len); + mgmt_DATA = kzalloc(data_len, GFP_ATOMIC); if (!mgmt_DATA) goto validate_80211w_fail; precv_frame = decryptor(adapter, precv_frame); @@ -1630,7 +1630,7 @@ static struct sk_buff *rtw_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubfra pattrib = &prframe->u.hdr.attrib; - sub_skb = rtw_skb_alloc(nSubframe_Length + 12); + sub_skb = __dev_alloc_skb(nSubframe_Length + 12, GFP_ATOMIC); if (!sub_skb) return NULL; @@ -1782,9 +1782,6 @@ static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe) static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) { - struct adapter *padapter = preorder_ctrl->padapter; - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; u8 wsize = preorder_ctrl->wsize_b; u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) % 4096u; @@ -1810,7 +1807,6 @@ static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_n preorder_ctrl->indicate_seq = seq_num + 1 - wsize; else preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; - pdbgpriv->dbg_rx_ampdu_window_shift_cnt++; } return true; @@ -1861,15 +1857,6 @@ static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, un } -static void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq) -{ - if (current_seq < prev_seq) - pdbgpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq); - else - pdbgpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq); - -} - static int rtw_recv_indicatepkt(struct adapter *padapter, union recv_frame *precv_frame) { struct recv_priv *precvpriv; @@ -1916,8 +1903,6 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor int bPktInBuf = false; struct recv_priv *precvpriv = &padapter->recvpriv; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */ /* spin_lock(&ppending_recvframe_queue->lock); */ @@ -1927,7 +1912,6 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor /* Handling some condition for forced indicate case. */ if (bforced == true) { - pdbgpriv->dbg_rx_ampdu_forced_indicate_count++; if (list_empty(phead)) { /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ /* spin_unlock(&ppending_recvframe_queue->lock); */ @@ -1937,7 +1921,6 @@ static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reor prframe = (union recv_frame *)plist; pattrib = &prframe->u.hdr.attrib; - recv_indicatepkts_pkt_loss_cnt(pdbgpriv, preorder_ctrl->indicate_seq, pattrib->seq_num); preorder_ctrl->indicate_seq = pattrib->seq_num; } @@ -1998,8 +1981,6 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame * struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; if (!pattrib->amsdu) { /* s1. */ @@ -2035,9 +2016,6 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame * preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; - if (retval != _SUCCESS) { - } - return retval; } } @@ -2045,11 +2023,8 @@ static int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame * spin_lock_bh(&ppending_recvframe_queue->lock); /* s2. check if winstart_b(indicate_seq) needs to been updated */ - if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) { - pdbgpriv->dbg_rx_ampdu_drop_count++; + if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) goto _err_exit; - } - /* s3. Insert all packet into Reorder Queue to maintain its ordering. */ if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) { diff --git a/drivers/staging/rtl8723bs/core/rtw_security.c b/drivers/staging/rtl8723bs/core/rtw_security.c index 8ee5bed252bf..b489babe7432 100644 --- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -5,6 +5,7 @@ * ******************************************************************************/ #include +#include #include #include #include @@ -128,29 +129,6 @@ void rtw_wep_decrypt(struct adapter *padapter, u8 *precvframe) /* 3 =====TKIP related ===== */ -static u32 secmicgetuint32(u8 *p) -/* Convert from Byte[] to Us3232 in a portable way */ -{ - s32 i; - u32 res = 0; - - for (i = 0; i < 4; i++) - res |= ((u32)(*p++)) << (8 * i); - - return res; -} - -static void secmicputuint32(u8 *p, u32 val) -/* Convert from Us3232 to Byte[] in a portable way */ -{ - long i; - - for (i = 0; i < 4; i++) { - *p++ = (u8) (val & 0xff); - val >>= 8; - } -} - static void secmicclear(struct mic_data *pmicdata) { /* Reset the state to the empty message. */ @@ -163,8 +141,8 @@ static void secmicclear(struct mic_data *pmicdata) void rtw_secmicsetkey(struct mic_data *pmicdata, u8 *key) { /* Set the key */ - pmicdata->K0 = secmicgetuint32(key); - pmicdata->K1 = secmicgetuint32(key + 4); + pmicdata->K0 = get_unaligned_le32(key); + pmicdata->K1 = get_unaligned_le32(key + 4); /* and reset the message */ secmicclear(pmicdata); } @@ -212,8 +190,8 @@ void rtw_secgetmic(struct mic_data *pmicdata, u8 *dst) while (pmicdata->nBytesInM != 0) rtw_secmicappendbyte(pmicdata, 0); /* The appendByte function has already computed the result. */ - secmicputuint32(dst, pmicdata->L); - secmicputuint32(dst + 4, pmicdata->R); + put_unaligned_le32(pmicdata->L, dst); + put_unaligned_le32(pmicdata->R, dst + 4); /* Reset to the empty message. */ secmicclear(pmicdata); } @@ -1316,8 +1294,7 @@ u32 rtw_BIP_verify(struct adapter *padapter, u8 *precvframe) __le64 le_tmp64; ori_len = pattrib->pkt_len - WLAN_HDR_A3_LEN + BIP_AAD_SIZE; - BIP_AAD = rtw_zmalloc(ori_len); - + BIP_AAD = kzalloc(ori_len, GFP_KERNEL); if (!BIP_AAD) return _FAIL; @@ -1488,7 +1465,7 @@ void rtw_sec_restore_wep_key(struct adapter *adapter) struct security_priv *securitypriv = &(adapter->securitypriv); signed int keyid; - if ((_WEP40_ == securitypriv->dot11PrivacyAlgrthm) || (_WEP104_ == securitypriv->dot11PrivacyAlgrthm)) { + if ((securitypriv->dot11PrivacyAlgrthm == _WEP40_) || (securitypriv->dot11PrivacyAlgrthm == _WEP104_)) { for (keyid = 0; keyid < 4; keyid++) { if (securitypriv->key_mask & BIT(keyid)) { if (keyid == securitypriv->dot11PrivacyKeyIndex) diff --git a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c index 3e80d03c4ec9..bdd4b6d8fd2e 100644 --- a/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c +++ b/drivers/staging/rtl8723bs/core/rtw_sta_mgt.c @@ -54,7 +54,7 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) struct sta_info *psta; s32 i; - pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA+4); + pstapriv->pallocated_stainfo_buf = vzalloc(sizeof(struct sta_info) * NUM_STA + 4); if (!pstapriv->pallocated_stainfo_buf) return _FAIL; @@ -105,7 +105,7 @@ u32 _rtw_init_sta_priv(struct sta_priv *pstapriv) inline int rtw_stainfo_offset(struct sta_priv *stapriv, struct sta_info *sta) { - int offset = (((u8 *)sta) - stapriv->pstainfo_buf)/sizeof(struct sta_info); + int offset = (((u8 *)sta) - stapriv->pstainfo_buf) / sizeof(struct sta_info); return offset; } @@ -191,77 +191,76 @@ struct sta_info *rtw_alloc_stainfo(struct sta_priv *pstapriv, u8 *hwaddr) /* spin_unlock_bh(&(pfree_sta_queue->lock)); */ spin_unlock_bh(&(pstapriv->sta_hash_lock)); return NULL; - } else { - psta = container_of(get_next(&pfree_sta_queue->queue), struct sta_info, list); - - list_del_init(&(psta->list)); - - /* spin_unlock_bh(&(pfree_sta_queue->lock)); */ - - _rtw_init_stainfo(psta); - - psta->padapter = pstapriv->padapter; - - memcpy(psta->hwaddr, hwaddr, ETH_ALEN); - - index = wifi_mac_hash(hwaddr); - - if (index >= NUM_STA) { - spin_unlock_bh(&(pstapriv->sta_hash_lock)); - psta = NULL; - goto exit; - } - phash_list = &(pstapriv->sta_hash[index]); - - /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ - - list_add_tail(&psta->hash_list, phash_list); - - pstapriv->asoc_sta_count++; - - /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ - -/* Commented by Albert 2009/08/13 */ -/* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */ -/* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */ -/* So, we initialize the tid_rxseq variable as the 0xffff. */ - - for (i = 0; i < 16; i++) - memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2); - - timer_setup(&psta->addba_retry_timer, addba_timer_hdl, 0); - - /* for A-MPDU Rx reordering buffer control */ - for (i = 0; i < 16 ; i++) { - preorder_ctrl = &psta->recvreorder_ctrl[i]; - - preorder_ctrl->padapter = pstapriv->padapter; - - preorder_ctrl->enable = false; - - preorder_ctrl->indicate_seq = 0xffff; - preorder_ctrl->wend_b = 0xffff; - /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */ - preorder_ctrl->wsize_b = 64;/* 64; */ - - INIT_LIST_HEAD(&preorder_ctrl->pending_recvframe_queue.queue); - spin_lock_init(&preorder_ctrl->pending_recvframe_queue.lock); - - /* init recv timer */ - timer_setup(&preorder_ctrl->reordering_ctrl_timer, - rtw_reordering_ctrl_timeout_handler, 0); - } - - /* init for DM */ - psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); - psta->rssi_stat.UndecoratedSmoothedCCK = (-1); - - /* init for the sequence number of received management frame */ - psta->RxMgmtFrameSeqNum = 0xffff; - spin_unlock_bh(&(pstapriv->sta_hash_lock)); - /* alloc mac id for non-bc/mc station, */ - rtw_alloc_macid(pstapriv->padapter, psta); } + psta = container_of(get_next(&pfree_sta_queue->queue), struct sta_info, list); + + list_del_init(&(psta->list)); + + /* spin_unlock_bh(&(pfree_sta_queue->lock)); */ + + _rtw_init_stainfo(psta); + + psta->padapter = pstapriv->padapter; + + memcpy(psta->hwaddr, hwaddr, ETH_ALEN); + + index = wifi_mac_hash(hwaddr); + + if (index >= NUM_STA) { + spin_unlock_bh(&(pstapriv->sta_hash_lock)); + psta = NULL; + goto exit; + } + phash_list = &(pstapriv->sta_hash[index]); + + /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ + + list_add_tail(&psta->hash_list, phash_list); + + pstapriv->asoc_sta_count++; + + /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ + + /* Commented by Albert 2009/08/13 */ + /* For the SMC router, the sequence number of first packet of WPS handshake will be 0. */ + /* In this case, this packet will be dropped by recv_decache function if we use the 0x00 as the default value for tid_rxseq variable. */ + /* So, we initialize the tid_rxseq variable as the 0xffff. */ + + for (i = 0; i < 16; i++) + memcpy(&psta->sta_recvpriv.rxcache.tid_rxseq[i], &wRxSeqInitialValue, 2); + + timer_setup(&psta->addba_retry_timer, addba_timer_hdl, 0); + + /* for A-MPDU Rx reordering buffer control */ + for (i = 0; i < 16 ; i++) { + preorder_ctrl = &psta->recvreorder_ctrl[i]; + + preorder_ctrl->padapter = pstapriv->padapter; + + preorder_ctrl->enable = false; + + preorder_ctrl->indicate_seq = 0xffff; + preorder_ctrl->wend_b = 0xffff; + /* preorder_ctrl->wsize_b = (NR_RECVBUFF-2); */ + preorder_ctrl->wsize_b = 64;/* 64; */ + + INIT_LIST_HEAD(&preorder_ctrl->pending_recvframe_queue.queue); + spin_lock_init(&preorder_ctrl->pending_recvframe_queue.lock); + + /* init recv timer */ + timer_setup(&preorder_ctrl->reordering_ctrl_timer, + rtw_reordering_ctrl_timeout_handler, 0); + } + + /* init for DM */ + psta->rssi_stat.UndecoratedSmoothedPWDB = (-1); + psta->rssi_stat.UndecoratedSmoothedCCK = (-1); + + /* init for the sequence number of received management frame */ + psta->RxMgmtFrameSeqNum = 0xffff; + spin_unlock_bh(&(pstapriv->sta_hash_lock)); + /* alloc mac id for non-bc/mc station, */ + rtw_alloc_macid(pstapriv->padapter, psta); exit: @@ -311,7 +310,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) /* spin_lock_bh(&(pxmitpriv->vi_pending.lock)); */ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->vi_q.sta_pending); list_del_init(&(pstaxmitpriv->vi_q.tx_pending)); - phwxmit = pxmitpriv->hwxmits+1; + phwxmit = pxmitpriv->hwxmits + 1; phwxmit->accnt -= pstaxmitpriv->vi_q.qcnt; pstaxmitpriv->vi_q.qcnt = 0; /* spin_unlock_bh(&(pxmitpriv->vi_pending.lock)); */ @@ -320,7 +319,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) /* spin_lock_bh(&(pxmitpriv->be_pending.lock)); */ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->be_q.sta_pending); list_del_init(&(pstaxmitpriv->be_q.tx_pending)); - phwxmit = pxmitpriv->hwxmits+2; + phwxmit = pxmitpriv->hwxmits + 2; phwxmit->accnt -= pstaxmitpriv->be_q.qcnt; pstaxmitpriv->be_q.qcnt = 0; /* spin_unlock_bh(&(pxmitpriv->be_pending.lock)); */ @@ -329,7 +328,7 @@ u32 rtw_free_stainfo(struct adapter *padapter, struct sta_info *psta) /* spin_lock_bh(&(pxmitpriv->bk_pending.lock)); */ rtw_free_xmitframe_queue(pxmitpriv, &pstaxmitpriv->bk_q.sta_pending); list_del_init(&(pstaxmitpriv->bk_q.tx_pending)); - phwxmit = pxmitpriv->hwxmits+3; + phwxmit = pxmitpriv->hwxmits + 3; phwxmit->accnt -= pstaxmitpriv->bk_q.qcnt; pstaxmitpriv->bk_q.qcnt = 0; /* spin_unlock_bh(&(pxmitpriv->bk_pending.lock)); */ diff --git a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c index 5ffefa50699e..3242978da36c 100644 --- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c +++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c @@ -63,11 +63,10 @@ u8 networktype_to_raid_ex(struct adapter *adapter, struct sta_info *psta) break; case WIRELESS_11B_24N: case WIRELESS_11BG_24N: - if (psta->bw_mode == CHANNEL_WIDTH_20) { + if (psta->bw_mode == CHANNEL_WIDTH_20) raid = RATEID_IDX_BGN_20M_1SS_BN; - } else { + else raid = RATEID_IDX_BGN_40M_1SS; - } break; default: raid = RATEID_IDX_BGN_40M_2SS; @@ -243,7 +242,7 @@ void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable) rtw_hal_set_hwreg(padapter, HW_VAR_DM_FUNC_CLR, (u8 *)(&mode)); } -void Set_MSR(struct adapter *padapter, u8 type) +void set_msr(struct adapter *padapter, u8 type) { rtw_hal_set_hwreg(padapter, HW_VAR_MEDIA_STATUS, (u8 *)(&type)); } @@ -617,7 +616,7 @@ s16 rtw_camid_alloc(struct adapter *adapter, struct sta_info *sta, u8 kid) netdev_dbg(adapter->pnetdev, FUNC_ADPT_FMT " pairwise key with %pM id:%u no room\n", FUNC_ADPT_ARG(adapter), - MAC_ARG(sta->hwaddr), kid); + sta->hwaddr, kid); else netdev_dbg(adapter->pnetdev, FUNC_ADPT_FMT " group key id:%u no room\n", @@ -694,8 +693,8 @@ int WMM_param_handler(struct adapter *padapter, struct ndis_80211_var_ie *pIE) if (!memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element))) return false; - else - memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); + + memcpy(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)); pmlmeinfo->WMM_enable = 1; return true; @@ -1132,7 +1131,7 @@ int rtw_check_bcn_info(struct adapter *Adapter, u8 *pframe, u32 packet_len) if (memcmp(cur_network->network.mac_address, pbssid, 6)) return true; - bssid = rtw_zmalloc(sizeof(struct wlan_bssid_ex)); + bssid = kzalloc_obj(*bssid); if (!bssid) return true; @@ -1450,9 +1449,7 @@ unsigned char check_assoc_AP(u8 *pframe, uint len) return get_realtek_assoc_AP_vender(pIE); else if (!memcmp(pIE->data, AIRGOCAP_OUI, 3)) return HT_IOT_PEER_AIRGO; - else - break; - + break; default: break; } diff --git a/drivers/staging/rtl8723bs/core/rtw_xmit.c b/drivers/staging/rtl8723bs/core/rtw_xmit.c index 21690857fd62..7b18be8912e6 100644 --- a/drivers/staging/rtl8723bs/core/rtw_xmit.c +++ b/drivers/staging/rtl8723bs/core/rtw_xmit.c @@ -78,7 +78,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) } pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4); - pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf; + pxframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; for (i = 0; i < NR_XMITFRAME; i++) { INIT_LIST_HEAD(&pxframe->list); @@ -238,7 +238,9 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitbuf->padapter = padapter; pxmitbuf->buf_tag = XMITBUF_CMD; - res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true); + res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, + MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, + true); if (res == _FAIL) { res = _FAIL; goto exit; @@ -248,7 +250,7 @@ s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter) pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ; pxmitbuf->len = 0; pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead; - pxmitbuf->alloc_sz = MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ; + pxmitbuf->alloc_sz = MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ; } } @@ -274,7 +276,7 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) { int i; struct adapter *padapter = pxmitpriv->adapter; - struct xmit_frame *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf; + struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitpriv->pxmit_frame_buf; struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf; rtw_hal_free_xmit_priv(padapter); @@ -321,7 +323,9 @@ void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv) for (i = 0; i < CMDBUF_MAX; i++) { pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i]; if (pxmitbuf) - rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true); + rtw_os_xmit_resource_free(padapter, pxmitbuf, + MAX_CMDBUF_SZ + XMITBUF_ALIGN_SZ, + true); } rtw_free_hwxmits(padapter); @@ -596,23 +600,31 @@ u8 qos_acm(u8 acm_mask, u8 priority) return priority; } -static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) +static int set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib) { struct ethhdr etherhdr; struct iphdr ip_hdr; s32 UserPriority = 0; + int ret; _rtw_open_pktfile(ppktfile->pkt, ppktfile); - _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); + ret = _rtw_pktfile_read(ppktfile, (unsigned char *)ðerhdr, ETH_HLEN); + if (ret < 0) + return ret; /* get UserPriority from IP hdr */ if (pattrib->ether_type == 0x0800) { - _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); + ret = _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr)); + if (ret < 0) + return ret; + UserPriority = ip_hdr.tos >> 5; } pattrib->priority = UserPriority; pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN; pattrib->subtype = WIFI_QOS_DATA_TYPE; + + return 0; } static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib) @@ -626,9 +638,12 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct qos_priv *pqospriv = &pmlmepriv->qospriv; signed int res = _SUCCESS; + int ret; _rtw_open_pktfile(pkt, &pktfile); - _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN); + ret = _rtw_pktfile_read(&pktfile, (u8 *)ðerhdr, ETH_HLEN); + if (ret < 0) + return ret; pattrib->ether_type = ntohs(etherhdr.h_proto); @@ -655,7 +670,9 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p u8 tmp[24]; - _rtw_pktfile_read(&pktfile, &tmp[0], 24); + ret = _rtw_pktfile_read(&pktfile, &tmp[0], 24); + if (ret < 0) + return ret; pattrib->dhcp_pkt = 0; if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */ @@ -715,8 +732,9 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p if (!(psta->state & _FW_LINKED)) return _FAIL; - /* TODO:_lock */ + spin_lock_bh(&psta->lock); if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) { + spin_unlock_bh(&psta->lock); res = _FAIL; goto exit; } @@ -724,7 +742,7 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p update_attrib_phy_info(padapter, pattrib, psta); pattrib->psta = psta; - /* TODO:_unlock */ + spin_unlock_bh(&psta->lock); pattrib->pctrl = 0; @@ -736,12 +754,17 @@ static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct p pattrib->subtype = WIFI_DATA_TYPE; pattrib->priority = 0; - if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) { - if (pattrib->qos_en) - set_qos(&pktfile, pattrib); + if (check_fwstate(pmlmepriv, WIFI_AP_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) { + if (pattrib->qos_en) { + ret = set_qos(&pktfile, pattrib); + if (ret < 0) + return ret; + } } else { if (pqospriv->qos_option) { - set_qos(&pktfile, pattrib); + ret = set_qos(&pktfile, pattrib); + if (ret < 0) + return ret; if (pmlmepriv->acm_mask != 0) pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority); @@ -787,15 +810,15 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]); } - if (pframe[1]&1) { /* ToDS == 1 */ + if (pframe[1] & 1) { /* ToDS == 1 */ rtw_secmicappend(&micdata, &pframe[16], 6); /* DA */ - if (pframe[1]&2) /* From Ds == 1 */ + if (pframe[1] & 2) /* From Ds == 1 */ rtw_secmicappend(&micdata, &pframe[24], 6); else rtw_secmicappend(&micdata, &pframe[10], 6); } else { /* ToDS == 0 */ rtw_secmicappend(&micdata, &pframe[4], 6); /* DA */ - if (pframe[1]&2) /* From Ds == 1 */ + if (pframe[1] & 2) /* From Ds == 1 */ rtw_secmicappend(&micdata, &pframe[16], 6); else rtw_secmicappend(&micdata, &pframe[10], 6); @@ -810,16 +833,20 @@ static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitfr for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) { payload = (u8 *)round_up((SIZE_PTR)(payload), 4); - payload = payload+pattrib->hdrlen+pattrib->iv_len; + payload = payload + pattrib->hdrlen + pattrib->iv_len; - if ((curfragnum+1) == pattrib->nr_frags) { - length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0); + if ((curfragnum + 1) == pattrib->nr_frags) { + length = pattrib->last_txcmdsz - pattrib->hdrlen - + pattrib->iv_len - + ((pattrib->bswenc) ? pattrib->icv_len : 0); rtw_secmicappend(&micdata, payload, length); - payload = payload+length; + payload = payload + length; } else { - length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0); + length = pxmitpriv->frag_len - pattrib->hdrlen - + pattrib->iv_len - + ((pattrib->bswenc) ? pattrib->icv_len : 0); rtw_secmicappend(&micdata, payload, length); - payload = payload+length+pattrib->icv_len; + payload = payload + length + pattrib->icv_len; } } rtw_secgetmic(&micdata, &mic[0]); @@ -1039,6 +1066,7 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct s32 bmcst = is_multicast_ether_addr(pattrib->ra); s32 res = _SUCCESS; + int ret; if (!pxmitframe->buf_addr) return _FAIL; @@ -1054,7 +1082,9 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct } _rtw_open_pktfile(pkt, &pktfile); - _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); + ret = _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen); + if (ret < 0) + return ret; frg_inx = 0; frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */ @@ -1096,6 +1126,9 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len); } + if (mem_sz < 0) + return mem_sz; + pframe += mem_sz; if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { @@ -1108,8 +1141,10 @@ s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct if (bmcst || (rtw_endofpktfile(&pktfile) == true)) { pattrib->nr_frags = frg_inx; - pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz:0) + - ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz; + pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + + ((pattrib->nr_frags == 1) ? llc_sz : 0) + + ((pattrib->bswenc) ? pattrib->icv_len : 0) + + mem_sz; ClearMFrag(mem_start); @@ -1158,8 +1193,8 @@ s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, s mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET; pwlanhdr = (struct ieee80211_hdr *)pframe; - ori_len = BIP_AAD_SIZE+pattrib->pktlen; - tmp_buf = BIP_AAD = rtw_zmalloc(ori_len); + ori_len = BIP_AAD_SIZE + pattrib->pktlen; + tmp_buf = BIP_AAD = kzalloc(ori_len, GFP_ATOMIC); subtype = GetFrameSubType(pframe); /* bit(7)~bit(2) */ if (!BIP_AAD) @@ -1211,14 +1246,14 @@ s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, s /* conscruct AAD, copy address 1 to address 3 */ memcpy(BIP_AAD + 2, &pwlanhdr->addrs, sizeof(pwlanhdr->addrs)); /* copy management fram body */ - memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len); + memcpy(BIP_AAD + BIP_AAD_SIZE, MGMT_body, frame_body_len); /* calculate mic */ if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey - , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic)) + , BIP_AAD, BIP_AAD_SIZE + frame_body_len, mic)) goto xmitframe_coalesce_fail; /* copy right BIP mic value, total is 128bits, we use the 0~63 bits */ - memcpy(pframe-8, mic, 8); + memcpy(pframe - 8, mic, 8); } else { /* unicast mgmt frame TX */ /* start to encrypt mgmt frame */ if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || @@ -1267,9 +1302,10 @@ s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, s memcpy(pframe, pattrib->iv, pattrib->iv_len); pframe += pattrib->iv_len; /* copy mgmt data portion after CCMP header */ - memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen); + memcpy(pframe, tmp_buf + pattrib->hdrlen, + pattrib->pktlen - pattrib->hdrlen); /* move pframe to end of mgmt pkt */ - pframe += pattrib->pktlen-pattrib->hdrlen; + pframe += pattrib->pktlen - pattrib->hdrlen; /* add 8 bytes CCMP IV header to length */ pattrib->pktlen += pattrib->iv_len; if ((pattrib->icv_len > 0) && (pattrib->bswenc)) { @@ -1375,7 +1411,7 @@ void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; u8 pkt_num = 1; - if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) { + if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) { pkt_num = pxmitframe->agg_num; pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num; @@ -1662,8 +1698,7 @@ struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv) struct xmit_frame *pxframe = NULL; u8 *alloc_addr; - alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4); - + alloc_addr = kzalloc(sizeof(*pxframe) + 4, GFP_ATOMIC); if (!alloc_addr) goto exit; @@ -1707,8 +1742,6 @@ s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitfram queue = &pxmitpriv->free_xmit_queue; else if (pxmitframe->ext_tag == 1) queue = &pxmitpriv->free_xframe_ext_queue; - else { - } spin_lock_bh(&queue->lock); @@ -1836,8 +1869,8 @@ s32 rtw_alloc_hwxmits(struct adapter *padapter) pxmitpriv->hwxmits = NULL; - pxmitpriv->hwxmits = rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry); - + pxmitpriv->hwxmits = kzalloc_objs(*hwxmits, pxmitpriv->hwxmit_entry, + GFP_ATOMIC); if (!pxmitpriv->hwxmits) return _FAIL; @@ -1958,7 +1991,7 @@ s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt) res = update_attrib(padapter, *ppkt, &pxmitframe->attrib); - if (res == _FAIL) { + if (res != _SUCCESS) { rtw_free_xmitframe(pxmitpriv, pxmitframe); return -1; } @@ -2070,7 +2103,7 @@ signed int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct x spin_lock_bh(&psta->sleep_q.lock); - if (psta->state&WIFI_SLEEP_STATE) { + if (psta->state & WIFI_SLEEP_STATE) { u8 wmmps_ac = 0; if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) { @@ -2083,20 +2116,20 @@ signed int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct x switch (pattrib->priority) { case 1: case 2: - wmmps_ac = psta->uapsd_bk&BIT(0); + wmmps_ac = psta->uapsd_bk & BIT(0); break; case 4: case 5: - wmmps_ac = psta->uapsd_vi&BIT(0); + wmmps_ac = psta->uapsd_vi & BIT(0); break; case 6: case 7: - wmmps_ac = psta->uapsd_vo&BIT(0); + wmmps_ac = psta->uapsd_vo & BIT(0); break; case 0: case 3: default: - wmmps_ac = psta->uapsd_be&BIT(0); + wmmps_ac = psta->uapsd_be & BIT(0); break; } @@ -2214,20 +2247,20 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) switch (pxmitframe->attrib.priority) { case 1: case 2: - wmmps_ac = psta->uapsd_bk&BIT(1); + wmmps_ac = psta->uapsd_bk & BIT(1); break; case 4: case 5: - wmmps_ac = psta->uapsd_vi&BIT(1); + wmmps_ac = psta->uapsd_vi & BIT(1); break; case 6: case 7: - wmmps_ac = psta->uapsd_vo&BIT(1); + wmmps_ac = psta->uapsd_vo & BIT(1); break; case 0: case 3: default: - wmmps_ac = psta->uapsd_be&BIT(1); + wmmps_ac = psta->uapsd_be & BIT(1); break; } @@ -2259,7 +2292,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) pstapriv->tim_bitmap &= ~BIT(psta->aid); - if (psta->state&WIFI_SLEEP_STATE) + if (psta->state & WIFI_SLEEP_STATE) psta->state ^= WIFI_SLEEP_STATE; if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { @@ -2274,7 +2307,7 @@ void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta) if (!psta_bmc) goto _exit; - if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) { /* no any sta in ps mode */ + if ((pstapriv->sta_dz_bitmap & 0xfffe) == 0x0) { /* no any sta in ps mode */ xmitframe_phead = get_list_head(&psta_bmc->sleep_q); list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) { pxmitframe = list_entry(xmitframe_plist, @@ -2327,20 +2360,20 @@ void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *pst switch (pxmitframe->attrib.priority) { case 1: case 2: - wmmps_ac = psta->uapsd_bk&BIT(1); + wmmps_ac = psta->uapsd_bk & BIT(1); break; case 4: case 5: - wmmps_ac = psta->uapsd_vi&BIT(1); + wmmps_ac = psta->uapsd_vi & BIT(1); break; case 6: case 7: - wmmps_ac = psta->uapsd_vo&BIT(1); + wmmps_ac = psta->uapsd_vo & BIT(1); break; case 0: case 3: default: - wmmps_ac = psta->uapsd_be&BIT(1); + wmmps_ac = psta->uapsd_be & BIT(1); break; } diff --git a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c index 4da2487f6750..4666b2ff3157 100644 --- a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c +++ b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.c @@ -1,23 +1,21 @@ // SPDX-License-Identifier: GPL-2.0 /****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -******************************************************************************/ + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + ******************************************************************************/ #include #include "odm_precomp.h" -static bool CheckPositive( - struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2 -) +static bool CheckPositive(struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2) { u8 _BoardType = - ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA */ - ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA */ - ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA */ - ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ - ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT */ + ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA */ + ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA */ + ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA */ + ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ + ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT */ u32 cond1 = Condition1, cond2 = Condition2; u32 driver1 = @@ -33,8 +31,7 @@ static bool CheckPositive( pDM_Odm->TypeALNA << 16 | pDM_Odm->TypeAPA << 24; - - /* Value Defined Check =============== */ + /* Value Defined Check =============== */ /* QFN Type [15:12] and Cut Version [27:24] need to do value check */ if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) @@ -42,16 +39,16 @@ static bool CheckPositive( if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) return false; - /* Bit Defined Check ================ */ - /* We don't care [31:28] and [23:20] */ - /* */ + /* Bit Defined Check ================ */ + /* We don't care [31:28] and [23:20] */ + /* */ cond1 &= 0x000F0FFF; driver1 &= 0x000F0FFF; if ((cond1 & driver1) == cond1) { u32 bitMask = 0; - if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE */ + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE */ return true; if ((cond1 & BIT0) != 0) /* GLNA */ @@ -63,7 +60,7 @@ static bool CheckPositive( if ((cond1 & BIT3) != 0) /* APA */ bitMask |= 0xFF000000; - /* BoardType of each RF path is matched */ + /* BoardType of each RF path is matched */ if ((cond2 & bitMask) == (driver2 & bitMask)) return true; } @@ -71,8 +68,8 @@ static bool CheckPositive( } /****************************************************************************** -* AGC_TAB.TXT -******************************************************************************/ + * AGC_TAB.TXT + ******************************************************************************/ static u32 Array_MP_8723B_AGC_TAB[] = { 0xC78, 0xFD000001, @@ -217,18 +214,18 @@ void ODM_ReadAndConfig_MP_8723B_AGC_TAB(struct dm_odm_t *pDM_Odm) for (i = 0; i < ArrayLen; i += 2) { u32 v1 = Array[i]; - u32 v2 = Array[i+1]; + u32 v2 = Array[i + 1]; - /* This (offset, data) pair doesn't care the condition. */ + /* This (offset, data) pair doesn't care the condition. */ if (v1 < 0x40000000) { odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2); continue; } else { - /* This line is the beginning of branch. */ + /* This line is the beginning of branch. */ bool bMatched = true; - u8 cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + u8 cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); - if (cCond == COND_ELSE) { /* ELSE, ENDIF */ + if (cCond == COND_ELSE) { /* ELSE, ENDIF */ bMatched = true; READ_NEXT_PAIR(v1, v2, i); } else if (!CheckPositive(pDM_Odm, v1, v2)) { @@ -242,25 +239,26 @@ void ODM_ReadAndConfig_MP_8723B_AGC_TAB(struct dm_odm_t *pDM_Odm) } if (!bMatched) { - /* Condition isn't matched. - * Discard the following (offset, data) pairs. - */ - while (v1 < 0x40000000 && i < ArrayLen-2) + /* + * Condition isn't matched. + * Discard the following (offset, data) pairs. + */ + while (v1 < 0x40000000 && i < ArrayLen - 2) READ_NEXT_PAIR(v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ + i -= 2; /* prevent from for-loop += 2 */ } else { - /* Configure matched pairs and skip to end of if-else. */ - while (v1 < 0x40000000 && i < ArrayLen-2) { + /* Configure matched pairs and skip to end of if-else. */ + while (v1 < 0x40000000 && i < ArrayLen - 2) { odm_ConfigBB_AGC_8723B(pDM_Odm, v1, bMaskDWord, v2); READ_NEXT_PAIR(v1, v2, i); } - /* Keeps reading until ENDIF. */ - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { + /* Keeps reading until ENDIF. */ + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); + while (cCond != COND_ENDIF && i < ArrayLen - 2) { READ_NEXT_PAIR(v1, v2, i); - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); } } } @@ -268,8 +266,8 @@ void ODM_ReadAndConfig_MP_8723B_AGC_TAB(struct dm_odm_t *pDM_Odm) } /****************************************************************************** -* PHY_REG.TXT -******************************************************************************/ + * PHY_REG.TXT + ******************************************************************************/ static u32 Array_MP_8723B_PHY_REG[] = { 0x800, 0x80040000, @@ -476,18 +474,18 @@ void ODM_ReadAndConfig_MP_8723B_PHY_REG(struct dm_odm_t *pDM_Odm) for (i = 0; i < ArrayLen; i += 2) { u32 v1 = Array[i]; - u32 v2 = Array[i+1]; + u32 v2 = Array[i + 1]; - /* This (offset, data) pair doesn't care the condition. */ + /* This (offset, data) pair doesn't care the condition. */ if (v1 < 0x40000000) { odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); continue; } else { - /* This line is the beginning of branch. */ + /* This line is the beginning of branch. */ bool bMatched = true; - u8 cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + u8 cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); - if (cCond == COND_ELSE) { /* ELSE, ENDIF */ + if (cCond == COND_ELSE) { /* ELSE, ENDIF */ bMatched = true; READ_NEXT_PAIR(v1, v2, i); } else if (!CheckPositive(pDM_Odm, v1, v2)) { @@ -501,24 +499,25 @@ void ODM_ReadAndConfig_MP_8723B_PHY_REG(struct dm_odm_t *pDM_Odm) } if (!bMatched) { - /* Condition isn't matched. - * Discard the following (offset, data) pairs. - */ - while (v1 < 0x40000000 && i < ArrayLen-2) + /* + * Condition isn't matched. + * Discard the following (offset, data) pairs. + */ + while (v1 < 0x40000000 && i < ArrayLen - 2) READ_NEXT_PAIR(v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - while (v1 < 0x40000000 && i < ArrayLen-2) { + i -= 2; /* prevent from for-loop += 2 */ + } else { /* Configure matched pairs and skip to end of if-else. */ + while (v1 < 0x40000000 && i < ArrayLen - 2) { odm_ConfigBB_PHY_8723B(pDM_Odm, v1, bMaskDWord, v2); READ_NEXT_PAIR(v1, v2, i); } - /* Keeps reading until ENDIF. */ - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { + /* Keeps reading until ENDIF. */ + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); + while (cCond != COND_ENDIF && i < ArrayLen - 2) { READ_NEXT_PAIR(v1, v2, i); - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); } } } @@ -526,8 +525,8 @@ void ODM_ReadAndConfig_MP_8723B_PHY_REG(struct dm_odm_t *pDM_Odm) } /****************************************************************************** -* PHY_REG_PG.TXT -******************************************************************************/ + * PHY_REG_PG.TXT + ******************************************************************************/ static u32 Array_MP_8723B_PHY_REG_PG[] = { 0, 0x00000e08, 0x0000ff00, 0x00003800, @@ -548,9 +547,9 @@ void ODM_ReadAndConfig_MP_8723B_PHY_REG_PG(struct dm_odm_t *pDM_Odm) for (i = 0; i < ARRAY_SIZE(Array_MP_8723B_PHY_REG_PG); i += 4) { u32 v1 = Array[i]; - u32 v2 = Array[i+1]; - u32 v3 = Array[i+2]; - u32 v4 = Array[i+3]; + u32 v2 = Array[i + 1]; + u32 v3 = Array[i + 2]; + u32 v4 = Array[i + 3]; odm_ConfigBB_PHY_REG_PG_8723B(pDM_Odm, v1, v2, v3, v4); } diff --git a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.h b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.h index 186007ce57d5..054acfe231b4 100644 --- a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.h +++ b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_BB.h @@ -1,17 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0 */ /****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -******************************************************************************/ + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + ******************************************************************************/ #ifndef __INC_MP_BB_HW_IMG_8723B_H #define __INC_MP_BB_HW_IMG_8723B_H - /****************************************************************************** -* AGC_TAB.TXT -******************************************************************************/ + * AGC_TAB.TXT + ******************************************************************************/ void ODM_ReadAndConfig_MP_8723B_AGC_TAB(/* TC: Test Chip, MP: MP Chip */ @@ -19,8 +18,8 @@ ODM_ReadAndConfig_MP_8723B_AGC_TAB(/* TC: Test Chip, MP: MP Chip */ ); /****************************************************************************** -* PHY_REG.TXT -******************************************************************************/ + * PHY_REG.TXT + ******************************************************************************/ void ODM_ReadAndConfig_MP_8723B_PHY_REG(/* TC: Test Chip, MP: MP Chip */ @@ -28,8 +27,8 @@ ODM_ReadAndConfig_MP_8723B_PHY_REG(/* TC: Test Chip, MP: MP Chip */ ); /****************************************************************************** -* PHY_REG_PG.TXT -******************************************************************************/ + * PHY_REG_PG.TXT + ******************************************************************************/ void ODM_ReadAndConfig_MP_8723B_PHY_REG_PG(/* TC: Test Chip, MP: MP Chip */ diff --git a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_MAC.c b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_MAC.c index 1f0cc8d58df3..9a3393f5122b 100644 --- a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_MAC.c +++ b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_MAC.c @@ -1,23 +1,21 @@ // SPDX-License-Identifier: GPL-2.0 /****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -******************************************************************************/ + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + ******************************************************************************/ #include #include "odm_precomp.h" -static bool CheckPositive( - struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2 -) +static bool CheckPositive(struct dm_odm_t *pDM_Odm, const u32 Condition1, const u32 Condition2) { u8 _BoardType = - ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA */ - ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA */ - ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA */ - ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ - ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT */ + ((pDM_Odm->BoardType & BIT4) >> 4) << 0 | /* _GLNA */ + ((pDM_Odm->BoardType & BIT3) >> 3) << 1 | /* _GPA */ + ((pDM_Odm->BoardType & BIT7) >> 7) << 2 | /* _ALNA */ + ((pDM_Odm->BoardType & BIT6) >> 6) << 3 | /* _APA */ + ((pDM_Odm->BoardType & BIT2) >> 2) << 4; /* _BT */ u32 cond1 = Condition1, cond2 = Condition2; u32 driver1 = @@ -33,8 +31,7 @@ static bool CheckPositive( pDM_Odm->TypeALNA << 16 | pDM_Odm->TypeAPA << 24; - - /* Value Defined Check =============== */ + /* Value Defined Check =============== */ /* QFN Type [15:12] and Cut Version [27:24] need to do value check */ if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != (driver1 & 0x0000F000))) @@ -42,15 +39,16 @@ static bool CheckPositive( if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != (driver1 & 0x0F000000))) return false; - /* Bit Defined Check ================ */ - /* We don't care [31:28] and [23:20] */ - /* */ + /* Bit Defined Check ================ */ + /* We don't care [31:28] and [23:20] */ + /* */ cond1 &= 0x000F0FFF; driver1 &= 0x000F0FFF; if ((cond1 & driver1) == cond1) { u32 bitMask = 0; - if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE */ + + if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE */ return true; if ((cond1 & BIT0) != 0) /* GLNA */ @@ -62,15 +60,16 @@ static bool CheckPositive( if ((cond1 & BIT3) != 0) /* APA */ bitMask |= 0xFF000000; - if ((cond2 & bitMask) == (driver2 & bitMask)) /* BoardType of each RF path is matched */ + /* BoardType of each RF path is matched */ + if ((cond2 & bitMask) == (driver2 & bitMask)) return true; } return false; } /****************************************************************************** -* MAC_REG.TXT -******************************************************************************/ + * MAC_REG.TXT + ******************************************************************************/ static u32 Array_MP_8723B_MAC_REG[] = { 0x02F, 0x00000030, @@ -187,18 +186,18 @@ void ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t *pDM_Odm) for (i = 0; i < ArrayLen; i += 2) { u32 v1 = Array[i]; - u32 v2 = Array[i+1]; + u32 v2 = Array[i + 1]; - /* This (offset, data) pair doesn't care the condition. */ + /* This (offset, data) pair doesn't care the condition. */ if (v1 < 0x40000000) { odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2); continue; } else { - /* This line is the beginning of branch. */ + /* This line is the beginning of branch. */ bool bMatched = true; - u8 cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + u8 cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); - if (cCond == COND_ELSE) { /* ELSE, ENDIF */ + if (cCond == COND_ELSE) { /* ELSE, ENDIF */ bMatched = true; READ_NEXT_PAIR(v1, v2, i); } else if (!CheckPositive(pDM_Odm, v1, v2)) { @@ -212,22 +211,25 @@ void ODM_ReadAndConfig_MP_8723B_MAC_REG(struct dm_odm_t *pDM_Odm) } if (!bMatched) { - /* Condition isn't matched. Discard the following (offset, data) pairs. */ - while (v1 < 0x40000000 && i < ArrayLen-2) + /* + * Condition isn't matched. + * Discard the following (offset, data) pairs. + */ + while (v1 < 0x40000000 && i < ArrayLen - 2) READ_NEXT_PAIR(v1, v2, i); - i -= 2; /* prevent from for-loop += 2 */ - } else { /* Configure matched pairs and skip to end of if-else. */ - while (v1 < 0x40000000 && i < ArrayLen-2) { + i -= 2; /* prevent from for-loop += 2 */ + } else { /* Configure matched pairs and skip to end of if-else. */ + while (v1 < 0x40000000 && i < ArrayLen - 2) { odm_ConfigMAC_8723B(pDM_Odm, v1, (u8)v2); READ_NEXT_PAIR(v1, v2, i); } - /* Keeps reading until ENDIF. */ - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); - while (cCond != COND_ENDIF && i < ArrayLen-2) { + /* Keeps reading until ENDIF. */ + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); + while (cCond != COND_ENDIF && i < ArrayLen - 2) { READ_NEXT_PAIR(v1, v2, i); - cCond = (u8)((v1 & (BIT29|BIT28)) >> 28); + cCond = (u8)((v1 & (BIT29 | BIT28)) >> 28); } } } diff --git a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_RF.c b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_RF.c index 155ec311a52e..0c7d0307b822 100644 --- a/drivers/staging/rtl8723bs/hal/HalHWImg8723B_RF.c +++ b/drivers/staging/rtl8723bs/hal/HalHWImg8723B_RF.c @@ -1,9 +1,9 @@ // SPDX-License-Identifier: GPL-2.0 /****************************************************************************** -* -* Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. -* -******************************************************************************/ + * + * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. + * + ******************************************************************************/ #include #include "odm_precomp.h" @@ -79,8 +79,8 @@ static bool CheckPositive( } /****************************************************************************** -* RadioA.TXT -******************************************************************************/ + * RadioA.TXT + ******************************************************************************/ static u32 Array_MP_8723B_RadioA[] = { 0x000, 0x00010000, @@ -243,9 +243,10 @@ void ODM_ReadAndConfig_MP_8723B_RadioA(struct dm_odm_t *pDM_Odm) } if (!bMatched) { - /* Condition isn't matched. - * Discard the following (offset, data) pairs. - */ + /* + * Condition isn't matched. + * Discard the following (offset, data) pairs. + */ while (v1 < 0x40000000 && i < ArrayLen-2) READ_NEXT_PAIR(v1, v2, i); @@ -269,8 +270,8 @@ void ODM_ReadAndConfig_MP_8723B_RadioA(struct dm_odm_t *pDM_Odm) } /****************************************************************************** -* TxPowerTrack_SDIO.TXT -******************************************************************************/ + * TxPowerTrack_SDIO.TXT + ******************************************************************************/ static u8 gDeltaSwingTableIdx_MP_2GB_N_TxPowerTrack_SDIO_8723B[] = { 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5, 5, 6, 6, 6, 6, @@ -354,8 +355,8 @@ void ODM_ReadAndConfig_MP_8723B_TxPowerTrack_SDIO(struct dm_odm_t *pDM_Odm) } /****************************************************************************** -* TXPWR_LMT.TXT -******************************************************************************/ + * TXPWR_LMT.TXT + ******************************************************************************/ static u8 *Array_MP_8723B_TXPWR_LMT[] = { "FCC", "20M", "CCK", "1T", "01", "32", diff --git a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c index 34692cca33f5..9df3274c1048 100644 --- a/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c +++ b/drivers/staging/rtl8723bs/hal/HalPhyRf_8723B.c @@ -1078,6 +1078,7 @@ void ODM_SetIQCbyRFpath(struct dm_odm_t *pDM_Odm, u32 RFpath) { struct odm_rf_cal_t *pRFCalibrateInfo = &pDM_Odm->RFCalibrateInfo; + u8 path; if ( (pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL] != 0x0) && @@ -1085,23 +1086,18 @@ void ODM_SetIQCbyRFpath(struct dm_odm_t *pDM_Odm, u32 RFpath) (pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL] != 0x0) && (pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL] != 0x0) ) { - if (RFpath) { /* S1: RFpath = 0, S0:RFpath = 1 */ - /* S0 TX IQC */ - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC94][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC80][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S0][IDX_0xC4C][VAL]); - /* S0 RX IQC */ - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xC14][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S0][IDX_0xCA0][VAL]); - } else { - /* S1 TX IQC */ - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC94][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC80][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[PATH_S1][IDX_0xC4C][VAL]); - /* S1 RX IQC */ - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xC14][VAL]); - PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[PATH_S1][IDX_0xCA0][VAL]); - } + if (RFpath) + path = PATH_S0; + else + path = PATH_S1; + + /* TX IQC */ + PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC94][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC94][VAL]); + PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC80][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC80][VAL]); + PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC4C][KEY], bMaskDWord, pRFCalibrateInfo->TxIQC_8723B[path][IDX_0xC4C][VAL]); + /* RX IQC */ + PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[path][IDX_0xC14][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[path][IDX_0xC14][VAL]); + PHY_SetBBReg(pDM_Odm->Adapter, pRFCalibrateInfo->RxIQC_8723B[path][IDX_0xCA0][KEY], bMaskDWord, pRFCalibrateInfo->RxIQC_8723B[path][IDX_0xCA0][VAL]); } } diff --git a/drivers/staging/rtl8723bs/hal/hal_com.c b/drivers/staging/rtl8723bs/hal/hal_com.c index 70b5b289f9cb..31b3e880ae6a 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com.c +++ b/drivers/staging/rtl8723bs/hal/hal_com.c @@ -782,21 +782,8 @@ bool GetU1ByteIntegerFromStringInDecimal(char *Str, u8 *pInt) void rtw_hal_check_rxfifo_full(struct adapter *adapter) { - struct dvobj_priv *psdpriv = adapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - int save_cnt = false; - /* switch counter to RX fifo */ rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xf0); - save_cnt = true; - /* todo: other chips */ - - if (save_cnt) { - /* rtw_write8(adapter, REG_RXERR_RPT+3, rtw_read8(adapter, REG_RXERR_RPT+3)|0xa0); */ - pdbgpriv->dbg_rx_fifo_last_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow; - pdbgpriv->dbg_rx_fifo_curr_overflow = rtw_read16(adapter, REG_RXERR_RPT); - pdbgpriv->dbg_rx_fifo_diff_overflow = pdbgpriv->dbg_rx_fifo_curr_overflow-pdbgpriv->dbg_rx_fifo_last_overflow; - } } static u32 Array_kfreemap[] = { diff --git a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c index cd76e26e868f..dc2da49e6738 100644 --- a/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/hal_com_phycfg.c @@ -573,8 +573,9 @@ s8 PHY_GetTxPowerByRate(struct adapter *padapter, u8 RFPath, u8 Rate) s8 value = 0; u8 rateIndex = PHY_GetRateIndexOfTxPowerByRate(Rate); - if ((padapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory == 2) || - padapter->registrypriv.RegEnableTxPowerByRate == 0) + if ((padapter->registrypriv.reg_enable_tx_power_by_rate == 2 && + pHalData->EEPROMRegulatory == 2) || + padapter->registrypriv.reg_enable_tx_power_by_rate == 0) return 0; if (RFPath >= RF_PATH_MAX) @@ -690,12 +691,12 @@ s8 phy_get_tx_pwr_lmt(struct adapter *adapter, u32 reg_pwr_tbl_sel, struct hal_com_data *hal_data = GET_HAL_DATA(adapter); s8 limits[10] = {0}; u8 i = 0; - if (((adapter->registrypriv.RegEnableTxPowerLimit == 2) && + if (((adapter->registrypriv.reg_enable_tx_power_limit == 2) && (hal_data->EEPROMRegulatory != 1)) || - (adapter->registrypriv.RegEnableTxPowerLimit == 0)) + (adapter->registrypriv.reg_enable_tx_power_limit == 0)) return MAX_POWER_INDEX; - switch (adapter->registrypriv.RegPwrTblSel) { + switch (adapter->registrypriv.reg_pwr_tbl_sel) { case 1: idx_regulation = TXPWR_LMT_ETSI; break; @@ -751,6 +752,7 @@ s8 phy_get_tx_pwr_lmt(struct adapter *adapter, u32 reg_pwr_tbl_sel, void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter) { struct hal_com_data *pHalData = GET_HAL_DATA(Adapter); + struct registry_priv *r = &Adapter->registrypriv; u8 BW40PwrBasedBm2_4G = 0x2E; u8 regulation, bw, channel, rateSection; s8 tempValue = 0, tempPwrLmt = 0; @@ -771,7 +773,7 @@ void PHY_ConvertTxPowerLimitToPowerIndex(struct adapter *Adapter) else if (rateSection == 0) /* CCK */ BW40PwrBasedBm2_4G = PHY_GetTxPowerByRateBase(Adapter, rfPath, CCK); } else - BW40PwrBasedBm2_4G = Adapter->registrypriv.RegPowerBase * 2; + BW40PwrBasedBm2_4G = r->reg_power_base * 2; if (tempPwrLmt != MAX_POWER_INDEX) { tempValue = tempPwrLmt - BW40PwrBasedBm2_4G; diff --git a/drivers/staging/rtl8723bs/hal/hal_intf.c b/drivers/staging/rtl8723bs/hal/hal_intf.c index 462553d296ff..27c0c0198714 100644 --- a/drivers/staging/rtl8723bs/hal/hal_intf.c +++ b/drivers/staging/rtl8723bs/hal/hal_intf.c @@ -207,7 +207,7 @@ void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level) pmlmepriv = &(padapter->mlmepriv); if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) - add_RATid(padapter, psta, rssi_level); + add_ratid(padapter, psta, rssi_level); else { UpdateHalRAMask8723B(padapter, psta->mac_id, rssi_level); } @@ -218,17 +218,6 @@ void rtw_hal_add_ra_tid(struct adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_l rtl8723b_Add_RateATid(padapter, bitmap, arg, rssi_level); } -/*Start specifical interface thread */ -void rtw_hal_start_thread(struct adapter *padapter) -{ - rtl8723b_start_thread(padapter); -} -/*Start specifical interface thread */ -void rtw_hal_stop_thread(struct adapter *padapter) -{ - rtl8723b_stop_thread(padapter); -} - u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask) { return PHY_QueryBBReg_8723B(padapter, RegAddr, BitMask); diff --git a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c index 666a9f44012d..166af5f6c9e0 100644 --- a/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c +++ b/drivers/staging/rtl8723bs/hal/odm_CfoTracking.c @@ -100,9 +100,8 @@ void ODM_CfoTracking(void *pDM_VOID) u8 Adjust_Xtal = 1; /* 4 Support ability */ - if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) { + if (!(pDM_Odm->SupportAbility & ODM_BB_CFO_TRACKING)) return; - } if (!pDM_Odm->bLinked || !pDM_Odm->bOneEntryOnly) { /* 4 No link or more than one entry */ @@ -110,9 +109,9 @@ void ODM_CfoTracking(void *pDM_VOID) } else { /* 3 1. CFO Tracking */ /* 4 1.1 No new packet */ - if (pCfoTrack->packetCount == pCfoTrack->packetCount_pre) { + if (pCfoTrack->packetCount == pCfoTrack->packetCount_pre) return; - } + pCfoTrack->packetCount_pre = pCfoTrack->packetCount; /* 4 1.2 Calculate CFO */ @@ -133,8 +132,9 @@ void ODM_CfoTracking(void *pDM_VOID) ) { pCfoTrack->largeCFOHit = 1; return; - } else - pCfoTrack->largeCFOHit = 0; + } + + pCfoTrack->largeCFOHit = 0; pCfoTrack->CFO_ave_pre = CFO_ave; /* 4 1.4 Dynamic Xtal threshold */ @@ -176,11 +176,10 @@ void ODM_CfoTracking(void *pDM_VOID) } /* 3 2. Dynamic ATC switch */ - if (CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) { + if (CFO_ave < CFO_TH_ATC && CFO_ave > -CFO_TH_ATC) odm_SetATCStatus(pDM_Odm, false); - } else { + else odm_SetATCStatus(pDM_Odm, true); - } } } diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c index 57c83f332e74..8d259820f103 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_hal_init.c @@ -17,8 +17,8 @@ static void _FWDownloadEnable(struct adapter *padapter, bool enable) if (enable) { /* 8051 enable */ - tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1); - rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04); + tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04); tmp = rtw_read8(padapter, REG_MCUFWDL); rtw_write8(padapter, REG_MCUFWDL, tmp|0x01); @@ -158,23 +158,23 @@ void _8051Reset8723(struct adapter *padapter) /* Reset 8051(WLMCU) IO wrapper */ /* 0x1c[8] = 0 */ /* Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 */ - io_rst = rtw_read8(padapter, REG_RSV_CTRL+1); + io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1); io_rst &= ~BIT(0); - rtw_write8(padapter, REG_RSV_CTRL+1, io_rst); + rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst); - cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1); + cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); cpu_rst &= ~BIT(2); - rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst); /* Enable 8051 IO wrapper */ /* 0x1c[8] = 1 */ - io_rst = rtw_read8(padapter, REG_RSV_CTRL+1); + io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1); io_rst |= BIT(0); - rtw_write8(padapter, REG_RSV_CTRL+1, io_rst); + rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst); - cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1); + cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); cpu_rst |= BIT(2); - rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst); } u8 g_fwdl_chksum_fail; @@ -259,7 +259,7 @@ static s32 _FWFreeToGo(struct adapter *adapter, u32 min_cnt, u32 timeout_ms) void rtl8723b_FirmwareSelfReset(struct adapter *padapter) { struct hal_com_data *pHalData = GET_HAL_DATA(padapter); - u8 u1bTmp; + u8 val; u8 Delay = 100; if ( @@ -268,19 +268,19 @@ void rtl8723b_FirmwareSelfReset(struct adapter *padapter) /* 0x1cf = 0x20. Inform 8051 to reset. 2009.12.25. tynli_test */ rtw_write8(padapter, REG_HMETFR+3, 0x20); - u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1); - while (u1bTmp & BIT2) { + val = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + while (val & BIT2) { Delay--; if (Delay == 0) break; udelay(50); - u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1); + val = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); } if (Delay == 0) { /* force firmware reset */ - u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1); - rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2)); + val = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val & (~BIT2)); } } } @@ -304,14 +304,12 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) const struct firmware *fw; struct device *device = dvobj_to_dev(padapter->dvobj); u8 *fwfilepath; - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; u8 tmp_ps; - pFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL); + pFirmware = kzalloc_obj(struct rt_firmware); if (!pFirmware) return _FAIL; - pBTFirmware = kzalloc(sizeof(struct rt_firmware), GFP_KERNEL); + pBTFirmware = kzalloc_obj(struct rt_firmware); if (!pBTFirmware) { kfree(pFirmware); return _FAIL; @@ -324,8 +322,6 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) /* 2. read power_state = 0xA0[1:0] */ tmp_ps = rtw_read8(padapter, 0xa0); tmp_ps &= 0x03; - if (tmp_ps != 0x01) - pdbgpriv->dbg_downloadfw_pwr_state_cnt++; fwfilepath = "rtlwifi/rtl8723bs_nic.bin"; @@ -346,12 +342,14 @@ s32 rtl8723b_FirmwareDownload(struct adapter *padapter, bool bUsedWoWLANFw) if (fw->size > FW_8723B_SIZE) { rtStatus = _FAIL; + release_firmware(fw); goto exit; } pFirmware->fw_buffer_sz = kmemdup(fw->data, fw->size, GFP_KERNEL); if (!pFirmware->fw_buffer_sz) { rtStatus = _FAIL; + release_firmware(fw); goto exit; } @@ -642,7 +640,7 @@ static void hal_ReadEFuse_WiFi( if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN) return; - efuseTbl = rtw_malloc(EFUSE_MAX_MAP_LEN); + efuseTbl = kmalloc(EFUSE_MAX_MAP_LEN, GFP_ATOMIC); if (!efuseTbl) return; @@ -730,7 +728,7 @@ static void hal_ReadEFuse_BT( if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) return; - efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN); + efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_ATOMIC); if (!efuseTbl) return; @@ -1024,7 +1022,7 @@ void hal_notch_filter_8723b(struct adapter *adapter, bool enable) void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) { u32 mask, rate_bitmap; - u8 shortGIrate = false; + u8 short_gi_rate = false; struct sta_info *psta; struct hal_com_data *pHalData = GET_HAL_DATA(padapter); struct dm_priv *pdmpriv = &pHalData->dmpriv; @@ -1038,7 +1036,7 @@ void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) if (!psta) return; - shortGIrate = query_ra_short_GI(psta); + short_gi_rate = query_ra_short_GI(psta); mask = psta->ra_mask; @@ -1051,7 +1049,7 @@ void UpdateHalRAMask8723B(struct adapter *padapter, u32 mac_id, u8 rssi_level) mask &= ~rate_bitmap; if (pHalData->fw_ractrl) { - rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask); + rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, short_gi_rate, mask); } /* set correct initial date rate for each mac_id */ @@ -1946,7 +1944,7 @@ static void hw_var_set_opmode(struct adapter *padapter, u8 variable, u8 *val) rtw_write8(padapter, REG_BCN_CTRL, val8); /* set net_type */ - Set_MSR(padapter, mode); + set_msr(padapter, mode); if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) { { @@ -2914,22 +2912,3 @@ u8 GetHalDefVar8723B(struct adapter *padapter, enum hal_def_variable variable, v return bResult; } - -void rtl8723b_start_thread(struct adapter *padapter) -{ - struct xmit_priv *xmitpriv = &padapter->xmitpriv; - - xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT"); -} - -void rtl8723b_stop_thread(struct adapter *padapter) -{ - struct xmit_priv *xmitpriv = &padapter->xmitpriv; - - /* stop xmit_buf_thread */ - if (xmitpriv->SdioXmitThread) { - complete(&xmitpriv->SdioXmitStart); - wait_for_completion(&xmitpriv->SdioXmitTerminate); - xmitpriv->SdioXmitThread = NULL; - } -} diff --git a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c index d8709d40cb33..6d5e531505f9 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723b_phycfg.c @@ -338,13 +338,10 @@ static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter) /* Read Tx Power Limit File */ PHY_InitTxPowerLimit(Adapter); - if ( - Adapter->registrypriv.RegEnableTxPowerLimit == 1 || - (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1) - ) { - ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, - CONFIG_RF_TXPWR_LMT, 0); - } + if (Adapter->registrypriv.reg_enable_tx_power_limit == 1 || + (Adapter->registrypriv.reg_enable_tx_power_limit == 2 && + pHalData->EEPROMRegulatory == 1)) + ODM_ConfigRFWithHeaderFile(&pHalData->odmpriv, CONFIG_RF_TXPWR_LMT, 0); /* */ /* 1. Read PHY_REG.TXT BB INIT!! */ @@ -353,20 +350,18 @@ static int phy_BB8723b_Config_ParaFile(struct adapter *Adapter) /* If EEPROM or EFUSE autoload OK, We must config by PHY_REG_PG.txt */ PHY_InitTxPowerByRate(Adapter); - if ( - Adapter->registrypriv.RegEnableTxPowerByRate == 1 || - (Adapter->registrypriv.RegEnableTxPowerByRate == 2 && pHalData->EEPROMRegulatory != 2) - ) { - ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, - CONFIG_BB_PHY_REG_PG); + + if (Adapter->registrypriv.reg_enable_tx_power_by_rate == 1 || + (Adapter->registrypriv.reg_enable_tx_power_by_rate == 2 && + pHalData->EEPROMRegulatory != 2)) { + ODM_ConfigBBWithHeaderFile(&pHalData->odmpriv, CONFIG_BB_PHY_REG_PG); if (pHalData->odmpriv.PhyRegPgValueType == PHY_REG_PG_EXACT_VALUE) PHY_TxPowerByRateConfiguration(Adapter); - if ( - Adapter->registrypriv.RegEnableTxPowerLimit == 1 || - (Adapter->registrypriv.RegEnableTxPowerLimit == 2 && pHalData->EEPROMRegulatory == 1) - ) + if (Adapter->registrypriv.reg_enable_tx_power_limit == 1 || + (Adapter->registrypriv.reg_enable_tx_power_limit == 2 && + pHalData->EEPROMRegulatory == 1)) PHY_ConvertTxPowerLimitToPowerIndex(Adapter); } @@ -541,7 +536,7 @@ u8 PHY_GetTxPowerIndex( limit = phy_get_tx_pwr_lmt( padapter, - padapter->registrypriv.RegPwrTblSel, + padapter->registrypriv.reg_pwr_tbl_sel, pHalData->CurrentChannelBW, RFPath, Rate, diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c index 399edfbf8ec6..5faac9f28b02 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_recv.c @@ -159,12 +159,10 @@ static void rtl8723bs_c2h_packet_handler(struct adapter *padapter, if (length == 0) return; - tmp = rtw_zmalloc(length); + tmp = kmemdup(pbuf, length, GFP_ATOMIC); if (!tmp) return; - memcpy(tmp, pbuf, length); - res = rtw_c2h_packet_wk_cmd(padapter, tmp, length); if (!res) @@ -292,7 +290,7 @@ static void rtl8723bs_recv_tasklet(struct tasklet_struct *t) alloc_sz += 14; } - pkt_copy = rtw_skb_alloc(alloc_sz); + pkt_copy = __dev_alloc_skb(alloc_sz, GFP_ATOMIC); if (!pkt_copy) { rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue); break; @@ -382,7 +380,7 @@ s32 rtl8723bs_init_recv_priv(struct adapter *padapter) spin_lock_init(&precvpriv->recv_buf_pending_queue.lock); n = NR_RECVBUFF * sizeof(struct recv_buf) + 4; - precvpriv->pallocated_recv_buf = rtw_zmalloc(n); + precvpriv->pallocated_recv_buf = kzalloc(n, GFP_KERNEL); if (!precvpriv->pallocated_recv_buf) { res = _FAIL; goto exit; @@ -399,8 +397,7 @@ s32 rtl8723bs_init_recv_priv(struct adapter *padapter) SIZE_PTR tmpaddr = 0; SIZE_PTR alignment = 0; - precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); - + precvbuf->pskb = __dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_ATOMIC); if (precvbuf->pskb) { precvbuf->pskb->dev = padapter->pnetdev; diff --git a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c index abb6fdfe7e1f..a1f2cbf2cf55 100644 --- a/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c +++ b/drivers/staging/rtl8723bs/hal/rtl8723bs_xmit.c @@ -146,7 +146,7 @@ s32 rtl8723bs_xmit_buf_handler(struct adapter *padapter) do { queue_empty = rtl8723_dequeue_writeport(padapter); -/* dump secondary adapter xmitbuf */ +/* dump secondary adapter xmitbuf */ } while (!queue_empty); rtw_unregister_tx_alive(padapter); @@ -289,10 +289,10 @@ static s32 xmit_xmitframes(struct adapter *padapter, struct xmit_priv *pxmitpriv pxmitframe->buf_addr = pxmitbuf->ptail; ret = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe); - if (ret == _FAIL) { + if (ret != _SUCCESS) { netdev_err(padapter->pnetdev, - "%s: coalesce FAIL!", - __func__); + "%s: coalesce failed with error %d\n", + __func__, ret); /* Todo: error handler */ } else { k++; diff --git a/drivers/staging/rtl8723bs/hal/sdio_halinit.c b/drivers/staging/rtl8723bs/hal/sdio_halinit.c index 4e81ef53dc47..0fa1b22fdf9a 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_halinit.c +++ b/drivers/staging/rtl8723bs/hal/sdio_halinit.c @@ -589,7 +589,7 @@ u32 rtl8723bs_hal_init(struct adapter *padapter) struct hal_com_data *pHalData; struct pwrctrl_priv *pwrctrlpriv; u32 NavUpper = WiFiNavUpperUs; - u8 u1bTmp; + u8 val; pHalData = GET_HAL_DATA(padapter); pwrctrlpriv = adapter_to_pwrctl(padapter); @@ -780,9 +780,9 @@ u32 rtl8723bs_hal_init(struct adapter *padapter) pHalData->SdioTxOQTMaxFreeSpace = pHalData->SdioTxOQTFreeSpace; /* Enable MACTXEN/MACRXEN block */ - u1bTmp = rtw_read8(padapter, REG_CR); - u1bTmp |= (MACTXEN | MACRXEN); - rtw_write8(padapter, REG_CR, u1bTmp); + val = rtw_read8(padapter, REG_CR); + val |= (MACTXEN | MACRXEN); + rtw_write8(padapter, REG_CR, val); rtw_hal_set_hwreg(padapter, HW_VAR_NAV_UPPER, (u8 *)&NavUpper); @@ -848,7 +848,7 @@ u32 rtl8723bs_hal_init(struct adapter *padapter) /* */ static void CardDisableRTL8723BSdio(struct adapter *padapter) { - u8 u1bTmp; + u8 val; u8 bMacPwrCtrlOn; /* Run LPS WL RFOFF flow */ @@ -856,26 +856,26 @@ static void CardDisableRTL8723BSdio(struct adapter *padapter) /* ==== Reset digital sequence ====== */ - u1bTmp = rtw_read8(padapter, REG_MCUFWDL); - if ((u1bTmp & RAM_DL_SEL) && padapter->bFWReady) /* 8051 RAM code */ + val = rtw_read8(padapter, REG_MCUFWDL); + if ((val & RAM_DL_SEL) && padapter->bFWReady) /* 8051 RAM code */ rtl8723b_FirmwareSelfReset(padapter); /* Reset MCU 0x2[10]= 0. Suggested by Filen. 2011.01.26. by tynli. */ - u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); - u1bTmp &= ~BIT(2); /* 0x2[10], FEN_CPUEN */ - rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp); + val = rtw_read8(padapter, REG_SYS_FUNC_EN + 1); + val &= ~BIT(2); /* 0x2[10], FEN_CPUEN */ + rtw_write8(padapter, REG_SYS_FUNC_EN + 1, val); /* MCUFWDL 0x80[1:0]= 0 */ /* reset MCU ready status */ rtw_write8(padapter, REG_MCUFWDL, 0); /* Reset MCU IO Wrapper, added by Roger, 2011.08.30 */ - u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1); - u1bTmp &= ~BIT(0); - rtw_write8(padapter, REG_RSV_CTRL + 1, u1bTmp); - u1bTmp = rtw_read8(padapter, REG_RSV_CTRL + 1); - u1bTmp |= BIT(0); - rtw_write8(padapter, REG_RSV_CTRL+1, u1bTmp); + val = rtw_read8(padapter, REG_RSV_CTRL + 1); + val &= ~BIT(0); + rtw_write8(padapter, REG_RSV_CTRL + 1, val); + val = rtw_read8(padapter, REG_RSV_CTRL + 1); + val |= BIT(0); + rtw_write8(padapter, REG_RSV_CTRL + 1, val); /* ==== Reset digital sequence end ====== */ @@ -886,9 +886,6 @@ static void CardDisableRTL8723BSdio(struct adapter *padapter) u32 rtl8723bs_hal_deinit(struct adapter *padapter) { - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - if (padapter->hw_init_completed) { if (adapter_to_pwrctl(padapter)->bips_processing) { if (padapter->netif_up) { @@ -921,18 +918,15 @@ u32 rtl8723bs_hal_deinit(struct adapter *padapter) adapter_to_pwrctl(padapter)->pre_ips_type = 0; } else { - pdbgpriv->dbg_carddisable_cnt++; CardDisableRTL8723BSdio(padapter); adapter_to_pwrctl(padapter)->pre_ips_type = 1; } } else { - pdbgpriv->dbg_carddisable_cnt++; CardDisableRTL8723BSdio(padapter); } - } else - pdbgpriv->dbg_deinit_fail_cnt++; + } return _SUCCESS; } diff --git a/drivers/staging/rtl8723bs/hal/sdio_ops.c b/drivers/staging/rtl8723bs/hal/sdio_ops.c index 0ee50b4a1149..c9cb20c61a2b 100644 --- a/drivers/staging/rtl8723bs/hal/sdio_ops.c +++ b/drivers/staging/rtl8723bs/hal/sdio_ops.c @@ -132,6 +132,7 @@ static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset) static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr) { u32 ftaddr; + ftaddr = _cvrt2ftaddr(addr, NULL, NULL); return sd_read8(intfhdl, ftaddr, NULL); @@ -180,7 +181,7 @@ static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr) } else { u8 *tmpbuf; - tmpbuf = rtw_malloc(8); + tmpbuf = kmalloc(8, GFP_ATOMIC); if (!tmpbuf) return SDIO_ERR_VAL32; @@ -227,9 +228,9 @@ static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf) ftaddr &= ~(u16)0x3; n = cnt + shift; - tmpbuf = rtw_malloc(n); + tmpbuf = kmalloc(n, GFP_ATOMIC); if (!tmpbuf) - return -1; + return -ENOMEM; err = sd_read(intfhdl, ftaddr, n, tmpbuf); if (!err) @@ -330,9 +331,9 @@ static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf) ftaddr &= ~(u16)0x3; n = cnt + shift; - tmpbuf = rtw_malloc(n); + tmpbuf = kmalloc(n, GFP_ATOMIC); if (!tmpbuf) - return -1; + return -ENOMEM; err = sd_read(intfhdl, ftaddr, 4, tmpbuf); if (err) { kfree(tmpbuf); @@ -502,9 +503,9 @@ static s32 _sdio_local_read( return _sd_cmd52_read(intfhdl, addr, cnt, buf); n = round_up(cnt, 4); - tmpbuf = rtw_malloc(n); + tmpbuf = kmalloc(n, GFP_ATOMIC); if (!tmpbuf) - return -1; + return -ENOMEM; err = _sd_read(intfhdl, addr, n, tmpbuf); if (!err) @@ -543,9 +544,9 @@ s32 sdio_local_read( return sd_cmd52_read(intfhdl, addr, cnt, buf); n = round_up(cnt, 4); - tmpbuf = rtw_malloc(n); + tmpbuf = kmalloc(n, GFP_ATOMIC); if (!tmpbuf) - return -1; + return -ENOMEM; err = sd_read(intfhdl, addr, n, tmpbuf); if (!err) @@ -582,9 +583,9 @@ s32 sdio_local_write( ) return sd_cmd52_write(intfhdl, addr, cnt, buf); - tmpbuf = rtw_malloc(cnt); + tmpbuf = kmalloc(cnt, GFP_ATOMIC); if (!tmpbuf) - return -1; + return -ENOMEM; memcpy(tmpbuf, buf, cnt); @@ -809,7 +810,7 @@ static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size) SIZE_PTR tmpaddr = 0; SIZE_PTR alignment = 0; - recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ); + recvbuf->pskb = __dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_ATOMIC); if (!recvbuf->pskb) return NULL; @@ -882,7 +883,7 @@ void sd_int_dpc(struct adapter *adapter) u8 *status; u32 addr; - status = rtw_malloc(4); + status = kmalloc(4, GFP_ATOMIC); if (status) { addr = REG_TXDMA_STATUS; hal_sdio_get_cmd_addr_8723b(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr); @@ -895,7 +896,7 @@ void sd_int_dpc(struct adapter *adapter) if (hal->sdio_hisr & SDIO_HISR_C2HCMD) { struct c2h_evt_hdr_88xx *c2h_evt; - c2h_evt = rtw_zmalloc(16); + c2h_evt = kzalloc(16, GFP_ATOMIC); if (c2h_evt) { if (c2h_evt_read_88xx(adapter, (u8 *)c2h_evt) == _SUCCESS) { if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) { diff --git a/drivers/staging/rtl8723bs/include/drv_types.h b/drivers/staging/rtl8723bs/include/drv_types.h index f86180dc350c..7ed375ba18d8 100644 --- a/drivers/staging/rtl8723bs/include/drv_types.h +++ b/drivers/staging/rtl8723bs/include/drv_types.h @@ -156,14 +156,10 @@ struct registry_priv { u8 notch_filter; /* define for tx power adjust */ - u8 RegEnableTxPowerLimit; - u8 RegEnableTxPowerByRate; - u8 RegPowerBase; - u8 RegPwrTblSel; - s8 TxBBSwing_2G; - u8 AmplifierType_2G; - u8 bEn_RFE; - u8 RFE_Type; + u8 reg_enable_tx_power_limit; + u8 reg_enable_tx_power_by_rate; + u8 reg_power_base; + u8 reg_pwr_tbl_sel; u8 check_fw_ps; u8 qos_opt_enable; @@ -177,45 +173,6 @@ struct registry_priv { #define GET_IFACE_NUMS(padapter) (((struct adapter *)padapter)->dvobj->iface_nums) #define GET_ADAPTER(padapter, iface_id) (((struct adapter *)padapter)->dvobj->padapters[iface_id]) -struct debug_priv { - u32 dbg_sdio_free_irq_error_cnt; - u32 dbg_sdio_alloc_irq_error_cnt; - u32 dbg_sdio_free_irq_cnt; - u32 dbg_sdio_alloc_irq_cnt; - u32 dbg_sdio_deinit_error_cnt; - u32 dbg_sdio_init_error_cnt; - u32 dbg_suspend_error_cnt; - u32 dbg_suspend_cnt; - u32 dbg_resume_cnt; - u32 dbg_resume_error_cnt; - u32 dbg_deinit_fail_cnt; - u32 dbg_carddisable_cnt; - u32 dbg_carddisable_error_cnt; - u32 dbg_ps_insuspend_cnt; - u32 dbg_dev_unload_inIPS_cnt; - u32 dbg_wow_leave_ps_fail_cnt; - u32 dbg_scan_pwr_state_cnt; - u32 dbg_downloadfw_pwr_state_cnt; - u32 dbg_fw_read_ps_state_fail_cnt; - u32 dbg_leave_ips_fail_cnt; - u32 dbg_leave_lps_fail_cnt; - u32 dbg_h2c_leave32k_fail_cnt; - u32 dbg_diswow_dload_fw_fail_cnt; - u32 dbg_enwow_dload_fw_fail_cnt; - u32 dbg_ips_drvopen_fail_cnt; - u32 dbg_poll_fail_cnt; - u32 dbg_rpwm_toggle_cnt; - u32 dbg_rpwm_timeout_fail_cnt; - u64 dbg_rx_fifo_last_overflow; - u64 dbg_rx_fifo_curr_overflow; - u64 dbg_rx_fifo_diff_overflow; - u64 dbg_rx_ampdu_drop_count; - u64 dbg_rx_ampdu_forced_indicate_count; - u64 dbg_rx_ampdu_loss_count; - u64 dbg_rx_dup_mgt_frame_drop_count; - u64 dbg_rx_ampdu_window_shift_cnt; -}; - struct rtw_traffic_statistics { /* tx statistics */ u64 tx_bytes; @@ -251,8 +208,6 @@ struct dvobj_priv { s32 processing_dev_remove; - struct debug_priv drv_dbg; - /* for local/global synchronization */ /* */ spinlock_t lock; diff --git a/drivers/staging/rtl8723bs/include/hal_intf.h b/drivers/staging/rtl8723bs/include/hal_intf.h index 82b60899129d..b193854bfe6e 100644 --- a/drivers/staging/rtl8723bs/include/hal_intf.h +++ b/drivers/staging/rtl8723bs/include/hal_intf.h @@ -221,9 +221,6 @@ void rtw_hal_free_recv_priv(struct adapter *padapter); void rtw_hal_update_ra_mask(struct sta_info *psta, u8 rssi_level); void rtw_hal_add_ra_tid(struct adapter *padapter, u32 bitmap, u8 *arg, u8 rssi_level); -void rtw_hal_start_thread(struct adapter *padapter); -void rtw_hal_stop_thread(struct adapter *padapter); - void beacon_timing_control(struct adapter *padapter); u32 rtw_hal_read_bbreg(struct adapter *padapter, u32 RegAddr, u32 BitMask); diff --git a/drivers/staging/rtl8723bs/include/ieee80211.h b/drivers/staging/rtl8723bs/include/ieee80211.h index 1098b0209200..0f28c904a714 100644 --- a/drivers/staging/rtl8723bs/include/ieee80211.h +++ b/drivers/staging/rtl8723bs/include/ieee80211.h @@ -506,7 +506,6 @@ Total: 28-2340 bytes #define DEFAULT_MAX_SCAN_AGE (15 * HZ) #define DEFAULT_FTS 2346 -#define MAC_ARG(x) (x) #define IP_ARG(x) (x) static inline int is_multicast_mac_addr(const u8 *addr) diff --git a/drivers/staging/rtl8723bs/include/osdep_service.h b/drivers/staging/rtl8723bs/include/osdep_service.h index 8b1634f4091e..955e8678dc26 100644 --- a/drivers/staging/rtl8723bs/include/osdep_service.h +++ b/drivers/staging/rtl8723bs/include/osdep_service.h @@ -54,21 +54,10 @@ extern int RTW_STATUS_CODE(int error_code); -void *_rtw_zmalloc(u32 sz); -void *_rtw_malloc(u32 sz); void _kfree(u8 *pbuf, u32 sz); -struct sk_buff *_rtw_skb_alloc(u32 sz); -struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb); int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb); -#define rtw_malloc(sz) _rtw_malloc((sz)) -#define rtw_zmalloc(sz) _rtw_zmalloc((sz)) - -#define rtw_skb_alloc(size) _rtw_skb_alloc((size)) -#define rtw_skb_alloc_f(size, mstat_f) _rtw_skb_alloc((size)) -#define rtw_skb_copy(skb) _rtw_skb_copy((skb)) -#define rtw_skb_copy_f(skb, mstat_f) _rtw_skb_copy((skb)) #define rtw_netif_rx(ndev, skb) _rtw_netif_rx(ndev, skb) extern void _rtw_init_queue(struct __queue *pqueue); @@ -91,10 +80,6 @@ static inline int rtw_bug_check(void *parg1, void *parg2, void *parg3, void *par #define _RND(sz, r) ((((sz)+((r)-1))/(r))*(r)) -#ifndef MAC_ARG -#define MAC_ARG(x) (x) -#endif - extern void rtw_free_netdev(struct net_device *netdev); /* Macros for handling unaligned memory accesses */ diff --git a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h index 06e0a549fa9d..7ec84304a19e 100644 --- a/drivers/staging/rtl8723bs/include/rtl8723b_hal.h +++ b/drivers/staging/rtl8723bs/include/rtl8723b_hal.h @@ -231,9 +231,6 @@ void rtl8723b_InitBeaconParameters(struct adapter *padapter); void _InitBurstPktLen_8723BS(struct adapter *adapter); void _8051Reset8723(struct adapter *padapter); -void rtl8723b_start_thread(struct adapter *padapter); -void rtl8723b_stop_thread(struct adapter *padapter); - int FirmwareDownloadBT(struct adapter *adapter, struct rt_firmware *firmware); void CCX_FwC2HTxRpt_8723b(struct adapter *padapter, u8 *pdata, u8 len); diff --git a/drivers/staging/rtl8723bs/include/rtw_ap.h b/drivers/staging/rtl8723bs/include/rtw_ap.h index 7a735e691399..83e835eb6513 100644 --- a/drivers/staging/rtl8723bs/include/rtw_ap.h +++ b/drivers/staging/rtl8723bs/include/rtw_ap.h @@ -11,7 +11,7 @@ void init_mlme_ap_info(struct adapter *padapter); void free_mlme_ap_info(struct adapter *padapter); /* void update_BCNTIM(struct adapter *padapter); */ void update_beacon(struct adapter *padapter, u8 ie_id, u8 *oui, u8 tx); -void add_RATid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level); +void add_ratid(struct adapter *padapter, struct sta_info *psta, u8 rssi_level); void expire_timeout_chk(struct adapter *padapter); void update_sta_info_apmode(struct adapter *padapter, struct sta_info *psta); void start_bss_network(struct adapter *padapter); diff --git a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h index dd5080056e58..afa5631a441a 100644 --- a/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h +++ b/drivers/staging/rtl8723bs/include/rtw_mlme_ext.h @@ -441,7 +441,7 @@ void Save_DM_Func_Flag(struct adapter *padapter); void Restore_DM_Func_Flag(struct adapter *padapter); void Switch_DM_Func(struct adapter *padapter, u32 mode, u8 enable); -void Set_MSR(struct adapter *padapter, u8 type); +void set_msr(struct adapter *padapter, u8 type); u8 rtw_get_oper_ch(struct adapter *adapter); void rtw_set_oper_ch(struct adapter *adapter, u8 ch); diff --git a/drivers/staging/rtl8723bs/include/xmit_osdep.h b/drivers/staging/rtl8723bs/include/xmit_osdep.h index 8704dced593a..880344bffe2f 100644 --- a/drivers/staging/rtl8723bs/include/xmit_osdep.h +++ b/drivers/staging/rtl8723bs/include/xmit_osdep.h @@ -35,7 +35,7 @@ void rtw_os_xmit_resource_free(struct adapter *padapter, struct xmit_buf *pxmitb extern uint rtw_remainder_len(struct pkt_file *pfile); extern void _rtw_open_pktfile(struct sk_buff *pkt, struct pkt_file *pfile); -extern uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen); +int _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, unsigned int rlen); extern signed int rtw_endofpktfile(struct pkt_file *pfile); extern void rtw_os_pkt_complete(struct adapter *padapter, struct sk_buff *pkt); diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 60edeae1cffe..7cb0c6f22bf3 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -111,6 +111,7 @@ static struct ieee80211_supported_band *rtw_spt_band_alloc( { struct ieee80211_supported_band *spt_band = NULL; int n_channels, n_bitrates; + size_t alloc_sz; if (band == NL80211_BAND_2GHZ) { n_channels = RTW_2G_CHANNELS_NUM; @@ -119,9 +120,10 @@ static struct ieee80211_supported_band *rtw_spt_band_alloc( goto exit; } - spt_band = rtw_zmalloc(sizeof(struct ieee80211_supported_band) + - sizeof(struct ieee80211_channel) * n_channels + - sizeof(struct ieee80211_rate) * n_bitrates); + alloc_sz = sizeof(*spt_band); + alloc_sz = size_add(alloc_sz, array_size(n_channels, sizeof(struct ieee80211_channel))); + alloc_sz = size_add(alloc_sz, array_size(n_bitrates, sizeof(struct ieee80211_rate))); + spt_band = kzalloc(alloc_sz, GFP_KERNEL); if (!spt_band) goto exit; @@ -315,9 +317,10 @@ struct cfg80211_bss *rtw_cfg80211_inform_bss(struct adapter *padapter, struct wl len, notify_signal, GFP_ATOMIC); if (unlikely(!bss)) - goto exit; + goto free_buf; cfg80211_put_bss(wiphy, bss); +free_buf: kfree(buf); exit: @@ -840,11 +843,9 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, struct mlme_priv *pmlmepriv = &padapter->mlmepriv; param_len = sizeof(struct ieee_param) + params->key_len; - param = rtw_malloc(param_len); + param = kzalloc(param_len, GFP_KERNEL); if (!param) - return -1; - - memset(param, 0, param_len); + return -ENOMEM; param->cmd = IEEE_CMD_SET_ENCRYPTION; eth_broadcast_addr(param->sta_addr); @@ -1162,11 +1163,10 @@ static int rtw_cfg80211_set_probe_req_wpsp2pie(struct adapter *padapter, char *b pmlmepriv->wps_probe_req_ie = NULL; } - pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen); + pmlmepriv->wps_probe_req_ie = kmemdup(wps_ie, wps_ielen, GFP_KERNEL); if (!pmlmepriv->wps_probe_req_ie) return -EINVAL; - memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen); pmlmepriv->wps_probe_req_ie_len = wps_ielen; } } @@ -1248,7 +1248,7 @@ static int cfg80211_rtw_scan(struct wiphy *wiphy goto check_need_indicate_scan_done; } - ssid = kcalloc(RTW_SSID_SCAN_AMOUNT, sizeof(*ssid), GFP_KERNEL); + ssid = kzalloc_objs(*ssid, RTW_SSID_SCAN_AMOUNT); if (!ssid) { ret = -ENOMEM; goto check_need_indicate_scan_done; @@ -1430,7 +1430,7 @@ static int rtw_cfg80211_set_wpa_ie(struct adapter *padapter, u8 *pie, size_t iel goto exit; } - buf = rtw_zmalloc(ielen); + buf = kzalloc(ielen, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto exit; @@ -1714,14 +1714,12 @@ static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev, wep_key_len = wep_key_len <= 5 ? 5 : 13; wep_total_len = wep_key_len + offsetof(struct ndis_802_11_wep, key_material); - pwep = rtw_malloc(wep_total_len); + pwep = kzalloc(wep_total_len, GFP_KERNEL); if (!pwep) { ret = -ENOMEM; goto exit; } - memset(pwep, 0, wep_total_len); - pwep->key_length = wep_key_len; pwep->length = wep_total_len; @@ -2147,7 +2145,7 @@ static int rtw_cfg80211_add_monitor_if(struct adapter *padapter, char *name, str pnpi->sizeof_priv = sizeof(struct adapter); /* wdev */ - mon_wdev = rtw_zmalloc(sizeof(struct wireless_dev)); + mon_wdev = kzalloc_obj(*mon_wdev); if (!mon_wdev) { ret = -ENOMEM; goto out; @@ -2257,7 +2255,7 @@ static int rtw_add_beacon(struct adapter *adapter, const u8 *head, size_t head_l if (head_len < 24) return -EINVAL; - pbuf = rtw_zmalloc(head_len + tail_len); + pbuf = kzalloc(head_len + tail_len, GFP_KERNEL); if (!pbuf) return -ENOMEM; @@ -2728,7 +2726,7 @@ int rtw_wdev_alloc(struct adapter *padapter, struct device *dev) goto free_wiphy; /* wdev */ - wdev = rtw_zmalloc(sizeof(struct wireless_dev)); + wdev = kzalloc_obj(*wdev); if (!wdev) { ret = -ENOMEM; goto unregister_wiphy; diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index 6ca6dc548805..29939bf5a156 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -6,6 +6,7 @@ ******************************************************************************/ #include #include +#include MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Realtek Wireless Lan Driver"); @@ -259,13 +260,10 @@ static void loadparam(struct adapter *padapter, struct net_device *pnetdev) registry_par->notch_filter = (u8)rtw_notch_filter; - registry_par->RegEnableTxPowerLimit = (u8)rtw_tx_pwr_lmt_enable; - registry_par->RegEnableTxPowerByRate = (u8)rtw_tx_pwr_by_rate; + registry_par->reg_enable_tx_power_limit = (u8)rtw_tx_pwr_lmt_enable; + registry_par->reg_enable_tx_power_by_rate = (u8)rtw_tx_pwr_by_rate; - registry_par->RegPowerBase = 14; - registry_par->TxBBSwing_2G = 0xFF; - registry_par->bEn_RFE = 1; - registry_par->RFE_Type = 64; + registry_par->reg_power_base = 14; registry_par->qos_opt_enable = (u8)rtw_qos_opt_enable; @@ -480,7 +478,13 @@ u32 rtw_start_drv_threads(struct adapter *padapter) else wait_for_completion(&padapter->cmdpriv.terminate_cmdthread_comp); /* wait for cmd_thread to run */ - rtw_hal_start_thread(padapter); + padapter->xmitpriv.SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, + padapter, "RTWHALXT"); + if (IS_ERR(padapter->xmitpriv.SdioXmitThread)) { + padapter->xmitpriv.SdioXmitThread = NULL; + _status = _FAIL; + } + return _status; } @@ -492,7 +496,12 @@ void rtw_stop_drv_threads(struct adapter *padapter) complete(&padapter->xmitpriv.xmit_comp); wait_for_completion(&padapter->xmitpriv.terminate_xmitthread_comp); - rtw_hal_stop_thread(padapter); + /* stop SdioXmitThread */ + if (padapter->xmitpriv.SdioXmitThread) { + complete(&padapter->xmitpriv.SdioXmitStart); + wait_for_completion(&padapter->xmitpriv.SdioXmitTerminate); + padapter->xmitpriv.SdioXmitThread = NULL; + } } static void rtw_init_default_value(struct adapter *padapter) @@ -553,14 +562,13 @@ static void rtw_init_default_value(struct adapter *padapter) padapter->fix_rate = 0xFF; padapter->driver_ampdu_spacing = 0xFF; padapter->driver_rx_ampdu_factor = 0xFF; - } struct dvobj_priv *devobj_init(void) { struct dvobj_priv *pdvobj = NULL; - pdvobj = rtw_zmalloc(sizeof(*pdvobj)); + pdvobj = kzalloc_obj(*pdvobj); if (!pdvobj) return NULL; @@ -898,7 +906,6 @@ void rtw_ips_pwr_down(struct adapter *padapter) void rtw_ips_dev_unload(struct adapter *padapter) { - if (!padapter->bSurpriseRemoved) rtw_hal_deinit(padapter); } @@ -934,14 +941,6 @@ static int netdev_close(struct net_device *pnetdev) padapter->net_closed = true; padapter->netif_up = false; -/*if (!padapter->hw_init_completed) - { - - padapter->bDriverStopped = true; - - rtw_dev_unload(padapter); - } - else*/ if (pwrctl->rf_pwrstate == rf_on) { /* s1. */ if (pnetdev) { @@ -974,13 +973,10 @@ void rtw_ndev_destructor(struct net_device *ndev) void rtw_dev_unload(struct adapter *padapter) { struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter); - struct dvobj_priv *pobjpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &pobjpriv->drv_dbg; struct cmd_priv *pcmdpriv = &padapter->cmdpriv; u8 cnt = 0; if (padapter->bup) { - padapter->bDriverStopped = true; if (padapter->xmitpriv.ack_tx) rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_DRV_STOP); @@ -1005,7 +1001,6 @@ void rtw_dev_unload(struct adapter *padapter) /* check HW status and SW state */ netdev_dbg(padapter->pnetdev, "%s: driver in IPS-FWLPS\n", __func__); - pdbgpriv->dbg_dev_unload_inIPS_cnt++; LeaveAllPowerSaveMode(padapter); } else { netdev_dbg(padapter->pnetdev, @@ -1022,7 +1017,6 @@ void rtw_dev_unload(struct adapter *padapter) } padapter->bup = false; - } } @@ -1089,24 +1083,21 @@ static void rtw_suspend_normal(struct adapter *padapter) void rtw_suspend_common(struct adapter *padapter) { struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; unsigned long start_time = jiffies; netdev_dbg(padapter->pnetdev, " suspend start\n"); - pdbgpriv->dbg_suspend_cnt++; pwrpriv->bInSuspend = true; while (pwrpriv->bips_processing) msleep(1); - if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) { - pdbgpriv->dbg_suspend_error_cnt++; + if ((!padapter->bup) || (padapter->bDriverStopped) || (padapter->bSurpriseRemoved)) return; - } + rtw_ps_deny(padapter, PS_DENY_SUSPEND); rtw_cancel_all_timer(padapter); @@ -1134,8 +1125,6 @@ static int rtw_resume_process_normal(struct adapter *padapter) struct net_device *pnetdev; struct pwrctrl_priv *pwrpriv; struct mlme_priv *pmlmepriv; - struct dvobj_priv *psdpriv; - struct debug_priv *pdbgpriv; int ret = _SUCCESS; @@ -1147,8 +1136,6 @@ static int rtw_resume_process_normal(struct adapter *padapter) pnetdev = padapter->pnetdev; pwrpriv = adapter_to_pwrctl(padapter); pmlmepriv = &padapter->mlmepriv; - psdpriv = padapter->dvobj; - pdbgpriv = &psdpriv->drv_dbg; /* interface init */ /* if (sdio_init(adapter_to_dvobj(padapter)) != _SUCCESS) */ if ((padapter->intf_init) && (padapter->intf_init(adapter_to_dvobj(padapter)) != _SUCCESS)) { @@ -1167,7 +1154,6 @@ static int rtw_resume_process_normal(struct adapter *padapter) if (pm_netdev_open(pnetdev, true) != 0) { ret = -1; - pdbgpriv->dbg_resume_error_cnt++; goto exit; } diff --git a/drivers/staging/rtl8723bs/os_dep/osdep_service.c b/drivers/staging/rtl8723bs/os_dep/osdep_service.c index a00f9f0c85c5..7959daeabc6f 100644 --- a/drivers/staging/rtl8723bs/os_dep/osdep_service.c +++ b/drivers/staging/rtl8723bs/os_dep/osdep_service.c @@ -6,10 +6,7 @@ ******************************************************************************/ #include -/* -* Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE -* @return: one of RTW_STATUS_CODE -*/ +/* Translate the OS dependent error_code to RTW_STATUS_CODE */ inline int RTW_STATUS_CODE(int error_code) { if (error_code >= 0) @@ -17,31 +14,6 @@ inline int RTW_STATUS_CODE(int error_code) return _FAIL; } -void *_rtw_malloc(u32 sz) -{ - return kmalloc(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -} - -void *_rtw_zmalloc(u32 sz) -{ - void *pbuf = _rtw_malloc(sz); - - if (pbuf) - memset(pbuf, 0, sz); - - return pbuf; -} - -inline struct sk_buff *_rtw_skb_alloc(u32 sz) -{ - return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -} - -inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb) -{ - return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); -} - inline int _rtw_netif_rx(struct net_device *ndev, struct sk_buff *skb) { skb->dev = ndev; @@ -132,11 +104,9 @@ void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) goto keep_ori; /* duplicate src */ - dup = rtw_malloc(src_len); - if (dup) { + dup = kmemdup(src, src_len, GFP_ATOMIC); + if (dup) dup_len = src_len; - memcpy(dup, src, dup_len); - } keep_ori: ori = *buf; @@ -152,7 +122,6 @@ void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len) kfree(ori); } - /** * rtw_cbuf_full - test if cbuf is full * @cbuf: pointer of struct rtw_cbuf @@ -204,6 +173,7 @@ bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf) void *rtw_cbuf_pop(struct rtw_cbuf *cbuf) { void *buf; + if (rtw_cbuf_empty(cbuf)) return NULL; @@ -223,12 +193,8 @@ struct rtw_cbuf *rtw_cbuf_alloc(u32 size) { struct rtw_cbuf *cbuf; - cbuf = rtw_malloc(struct_size(cbuf, bufs, size)); - - if (cbuf) { - cbuf->write = cbuf->read = 0; - cbuf->size = size; - } + cbuf = kzalloc_flex(*cbuf, bufs, size); + cbuf->size = size; return cbuf; } diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c index 1d0239eef114..d664e254912c 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_intf.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_intf.c @@ -70,13 +70,10 @@ static int sdio_alloc_irq(struct dvobj_priv *dvobj) sdio_claim_host(func); err = sdio_claim_irq(func, &sd_sync_int_hdl); - if (err) { - dvobj->drv_dbg.dbg_sdio_alloc_irq_error_cnt++; + if (err) netdev_crit(dvobj->if1->pnetdev, "%s: sdio_claim_irq FAIL(%d)!\n", __func__, err); - } else { - dvobj->drv_dbg.dbg_sdio_alloc_irq_cnt++; + else dvobj->irq_alloc = 1; - } sdio_release_host(func); @@ -97,12 +94,10 @@ static void sdio_free_irq(struct dvobj_priv *dvobj) sdio_claim_host(func); err = sdio_release_irq(func); if (err) { - dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; netdev_err(dvobj->if1->pnetdev, "%s: sdio_release_irq FAIL(%d)!\n", __func__, err); - } else - dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; + } sdio_release_host(func); } dvobj->irq_alloc = 0; @@ -122,16 +117,13 @@ static u32 sdio_init(struct dvobj_priv *dvobj) sdio_claim_host(func); err = sdio_enable_func(func); - if (err) { - dvobj->drv_dbg.dbg_sdio_init_error_cnt++; + if (err) goto release; - } err = sdio_set_block_size(func, 512); - if (err) { - dvobj->drv_dbg.dbg_sdio_init_error_cnt++; + if (err) goto release; - } + psdio_data->block_transfer_len = 512; psdio_data->tx_block_mode = 1; psdio_data->rx_block_mode = 1; @@ -147,22 +139,15 @@ static u32 sdio_init(struct dvobj_priv *dvobj) static void sdio_deinit(struct dvobj_priv *dvobj) { struct sdio_func *func; - int err; func = dvobj->intf_data.func; if (func) { sdio_claim_host(func); - err = sdio_disable_func(func); - if (err) - dvobj->drv_dbg.dbg_sdio_deinit_error_cnt++; + sdio_disable_func(func); if (dvobj->irq_alloc) { - err = sdio_release_irq(func); - if (err) - dvobj->drv_dbg.dbg_sdio_free_irq_error_cnt++; - else - dvobj->drv_dbg.dbg_sdio_free_irq_cnt++; + sdio_release_irq(func); } sdio_release_host(func); @@ -377,7 +362,8 @@ static int rtw_drv_init( if (status != _SUCCESS) goto free_if1; - if (sdio_alloc_irq(dvobj) != _SUCCESS) + status = sdio_alloc_irq(dvobj); + if (status != _SUCCESS) goto free_if1; status = _SUCCESS; @@ -433,15 +419,12 @@ static int rtw_sdio_suspend(struct device *dev) struct dvobj_priv *psdpriv = sdio_get_drvdata(func); struct pwrctrl_priv *pwrpriv = dvobj_to_pwrctl(psdpriv); struct adapter *padapter = psdpriv->if1; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; if (padapter->bDriverStopped) return 0; - if (pwrpriv->bInSuspend) { - pdbgpriv->dbg_suspend_error_cnt++; + if (pwrpriv->bInSuspend) return 0; - } rtw_suspend_common(padapter); @@ -451,13 +434,9 @@ static int rtw_sdio_suspend(struct device *dev) static int rtw_resume_process(struct adapter *padapter) { struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); - struct dvobj_priv *psdpriv = padapter->dvobj; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - if (!pwrpriv->bInSuspend) { - pdbgpriv->dbg_resume_error_cnt++; + if (!pwrpriv->bInSuspend) return -1; - } return rtw_resume_common(padapter); } @@ -469,9 +448,6 @@ static int rtw_sdio_resume(struct device *dev) struct adapter *padapter = psdpriv->if1; struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; int ret = 0; - struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; - - pdbgpriv->dbg_resume_cnt++; ret = rtw_resume_process(padapter); diff --git a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c index 5dc00e9117ae..3ea9fdfa14f8 100644 --- a/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/sdio_ops_linux.c @@ -219,14 +219,14 @@ u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err) if (*err == 0) { rtw_reset_continual_io_error(psdiodev); break; - } else { - if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) - padapter->bSurpriseRemoved = true; + } - if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { - padapter->bSurpriseRemoved = true; - break; - } + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) + padapter->bSurpriseRemoved = true; + + if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { + padapter->bSurpriseRemoved = true; + break; } } } @@ -295,14 +295,14 @@ void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err) if (*err == 0) { rtw_reset_continual_io_error(psdiodev); break; - } else { - if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) - padapter->bSurpriseRemoved = true; + } - if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { - padapter->bSurpriseRemoved = true; - break; - } + if ((-ESHUTDOWN == *err) || (-ENODEV == *err)) + padapter->bSurpriseRemoved = true; + + if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) { + padapter->bSurpriseRemoved = true; + break; } } } diff --git a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c index 944b9c724b32..0be3143fffe5 100644 --- a/drivers/staging/rtl8723bs/os_dep/xmit_linux.c +++ b/drivers/staging/rtl8723bs/os_dep/xmit_linux.c @@ -21,19 +21,22 @@ void _rtw_open_pktfile(struct sk_buff *pktptr, struct pkt_file *pfile) pfile->cur_buffer = pfile->buf_start; } -uint _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, uint rlen) +int _rtw_pktfile_read(struct pkt_file *pfile, u8 *rmem, unsigned int rlen) { - uint len = 0; + int ret; - len = rtw_remainder_len(pfile); - len = (rlen > len) ? len : rlen; + if (rtw_remainder_len(pfile) < rlen) + return -EINVAL; - if (rmem) - skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, len); + if (rmem) { + ret = skb_copy_bits(pfile->pkt, pfile->buf_len - pfile->pkt_len, rmem, rlen); + if (ret < 0) + return ret; + } - pfile->cur_addr += len; - pfile->pkt_len -= len; - return len; + pfile->cur_addr += rlen; + pfile->pkt_len -= rlen; + return rlen; } signed int rtw_endofpktfile(struct pkt_file *pfile) @@ -46,7 +49,7 @@ signed int rtw_endofpktfile(struct pkt_file *pfile) int rtw_os_xmit_resource_alloc(struct adapter *padapter, struct xmit_buf *pxmitbuf, u32 alloc_sz, u8 flag) { if (alloc_sz > 0) { - pxmitbuf->pallocated_buf = rtw_zmalloc(alloc_sz); + pxmitbuf->pallocated_buf = kzalloc(alloc_sz, GFP_KERNEL); if (!pxmitbuf->pallocated_buf) return _FAIL; @@ -159,8 +162,7 @@ static int rtw_mlcst2unicst(struct adapter *padapter, struct sk_buff *skb) !memcmp(psta->hwaddr, bc_addr, 6)) continue; - newskb = rtw_skb_copy(skb); - + newskb = skb_copy(skb, GFP_ATOMIC); if (newskb) { memcpy(newskb->data, psta->hwaddr, 6); res = rtw_xmit(padapter, &newskb); diff --git a/drivers/staging/sm750fb/TODO b/drivers/staging/sm750fb/TODO index 7ce632d040b3..037984801654 100644 --- a/drivers/staging/sm750fb/TODO +++ b/drivers/staging/sm750fb/TODO @@ -1,6 +1,4 @@ TODO: -- lots of checkpatch cleanup -- use kernel coding style - refine the code and remove unused code - Implement hardware acceleration for imageblit if image->depth > 1 - must be ported to the atomic kms framework in the drm subsystem (which will diff --git a/drivers/staging/sm750fb/ddk750_chip.c b/drivers/staging/sm750fb/ddk750_chip.c index 025dae3756aa..136692b00804 100644 --- a/drivers/staging/sm750fb/ddk750_chip.c +++ b/drivers/staging/sm750fb/ddk750_chip.c @@ -249,7 +249,7 @@ int ddk750_init_hw(struct initchip_param *p_init_param) * Reset the memory controller. * If the memory controller is not reset in SM750, * the system might hang when sw accesses the memory. - * The memory should be resetted after changing the MXCLK. + * The memory should be reset after changing the MXCLK. */ if (p_init_param->reset_memory == 1) { reg = peek32(MISC_CTRL); diff --git a/drivers/staging/sm750fb/sm750.c b/drivers/staging/sm750fb/sm750.c index fecd7457e615..62f6e0cdff4d 100644 --- a/drivers/staging/sm750fb/sm750.c +++ b/drivers/staging/sm750fb/sm750.c @@ -740,7 +740,7 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index) "kernel HELPERS prepared vesa_modes", }; - static const char *fixId[2] = { + static const char *fix_id[2] = { "sm750_fb1", "sm750_fb2", }; @@ -862,7 +862,7 @@ static int lynxfb_set_fbinfo(struct fb_info *info, int index) fix->ywrapstep = crtc->ywrapstep; fix->accel = FB_ACCEL_SMI; - strscpy(fix->id, fixId[index], sizeof(fix->id)); + strscpy(fix->id, fix_id[index], sizeof(fix->id)); fix->smem_start = crtc->o_screen + sm750_dev->vidmem_start; pr_info("fix->smem_start = %lx\n", fix->smem_start); @@ -918,12 +918,12 @@ static void sm750fb_setup(struct sm750_dev *sm750_dev, char *src) swap = 0; - sm750_dev->initParm.chip_clk = 0; - sm750_dev->initParm.mem_clk = 0; - sm750_dev->initParm.master_clk = 0; - sm750_dev->initParm.powerMode = 0; - sm750_dev->initParm.setAllEngOff = 0; - sm750_dev->initParm.resetMemory = 1; + sm750_dev->init_parm.chip_clk = 0; + sm750_dev->init_parm.mem_clk = 0; + sm750_dev->init_parm.master_clk = 0; + sm750_dev->init_parm.powerMode = 0; + sm750_dev->init_parm.setAllEngOff = 0; + sm750_dev->init_parm.resetMemory = 1; /* defaultly turn g_hwcursor on for both view */ g_hwcursor = 3; @@ -1123,6 +1123,7 @@ static void lynxfb_pci_remove(struct pci_dev *pdev) iounmap(sm750_dev->pvReg); iounmap(sm750_dev->pvMem); + pci_release_region(pdev, 1); kfree(g_settings); } diff --git a/drivers/staging/sm750fb/sm750.h b/drivers/staging/sm750fb/sm750.h index fcb7d586ebf0..67b9bfa23f41 100644 --- a/drivers/staging/sm750fb/sm750.h +++ b/drivers/staging/sm750fb/sm750.h @@ -102,7 +102,7 @@ struct sm750_dev { /* locks*/ spinlock_t slock; - struct init_status initParm; + struct init_status init_parm; enum sm750_pnltype pnltype; enum sm750_dataflow dataflow; int nocrt; diff --git a/drivers/staging/sm750fb/sm750_accel.c b/drivers/staging/sm750fb/sm750_accel.c index 046b9282b24a..0f94d859e91c 100644 --- a/drivers/staging/sm750fb/sm750_accel.c +++ b/drivers/staging/sm750fb/sm750_accel.c @@ -27,7 +27,7 @@ static inline u32 read_dpr(struct lynx_accel *accel, int offset) return readl(accel->dpr_base + offset); } -static inline void write_dpPort(struct lynx_accel *accel, u32 data) +static inline void write_dp_port(struct lynx_accel *accel, u32 data) { writel(data, accel->dp_port_base); } @@ -132,12 +132,12 @@ int sm750_hw_fillrect(struct lynx_accel *accel, /** * sm750_hw_copyarea * @accel: Acceleration device data - * @sBase: Address of source: offset in frame buffer - * @sPitch: Pitch value of source surface in BYTE + * @source_base: Address of source: offset in frame buffer + * @source_pitch: Pitch value of source surface in BYTE * @sx: Starting x coordinate of source surface * @sy: Starting y coordinate of source surface - * @dBase: Address of destination: offset in frame buffer - * @dPitch: Pitch value of destination surface in BYTE + * @dest_base: Address of destination: offset in frame buffer + * @dest_pitch: Pitch value of destination surface in BYTE * @Bpp: Color depth of destination surface * @dx: Starting x coordinate of destination surface * @dy: Starting y coordinate of destination surface @@ -146,21 +146,21 @@ int sm750_hw_fillrect(struct lynx_accel *accel, * @rop2: ROP value */ int sm750_hw_copyarea(struct lynx_accel *accel, - unsigned int sBase, unsigned int sPitch, + unsigned int source_base, unsigned int source_pitch, unsigned int sx, unsigned int sy, - unsigned int dBase, unsigned int dPitch, + unsigned int dest_base, unsigned int dest_pitch, unsigned int Bpp, unsigned int dx, unsigned int dy, unsigned int width, unsigned int height, unsigned int rop2) { - unsigned int nDirection, de_ctrl; + unsigned int direction, de_ctrl; - nDirection = LEFT_TO_RIGHT; + direction = LEFT_TO_RIGHT; /* Direction of ROP2 operation: 1 = Left to Right, (-1) = Right to Left */ de_ctrl = 0; /* If source and destination are the same surface, need to check for overlay cases */ - if (sBase == dBase && sPitch == dPitch) { + if (source_base == dest_base && source_pitch == dest_pitch) { /* Determine direction of operation */ if (sy < dy) { /* +----------+ @@ -173,7 +173,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * +----------+ */ - nDirection = BOTTOM_TO_TOP; + direction = BOTTOM_TO_TOP; } else if (sy > dy) { /* +----------+ * |D | @@ -185,7 +185,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * +----------+ */ - nDirection = TOP_TO_BOTTOM; + direction = TOP_TO_BOTTOM; } else { /* sy == dy */ @@ -198,7 +198,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * +------+---+------+ */ - nDirection = RIGHT_TO_LEFT; + direction = RIGHT_TO_LEFT; } else { /* sx > dx */ @@ -210,12 +210,12 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * +------+---+------+ */ - nDirection = LEFT_TO_RIGHT; + direction = LEFT_TO_RIGHT; } } } - if ((nDirection == BOTTOM_TO_TOP) || (nDirection == RIGHT_TO_LEFT)) { + if ((direction == BOTTOM_TO_TOP) || (direction == RIGHT_TO_LEFT)) { sx += width - 1; sy += height - 1; dx += width - 1; @@ -234,14 +234,14 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * It is an address offset (128 bit aligned) * from the beginning of frame buffer. */ - write_dpr(accel, DE_WINDOW_SOURCE_BASE, sBase); /* dpr40 */ + write_dpr(accel, DE_WINDOW_SOURCE_BASE, source_base); /* dpr40 */ /* * 2D Destination Base. * It is an address offset (128 bit aligned) * from the beginning of frame buffer. */ - write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); /* dpr44 */ + write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dest_base); /* dpr44 */ /* * Program pitch (distance between the 1st points of two adjacent lines). @@ -249,9 +249,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * pixel values. Need Byte to pixel conversion. */ write_dpr(accel, DE_PITCH, - ((dPitch / Bpp << DE_PITCH_DESTINATION_SHIFT) & + ((dest_pitch / Bpp << DE_PITCH_DESTINATION_SHIFT) & DE_PITCH_DESTINATION_MASK) | - (sPitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */ + (source_pitch / Bpp & DE_PITCH_SOURCE_MASK)); /* dpr10 */ /* * Screen Window width in Pixels. @@ -259,9 +259,9 @@ int sm750_hw_copyarea(struct lynx_accel *accel, * for a given point. */ write_dpr(accel, DE_WINDOW_WIDTH, - ((dPitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) & + ((dest_pitch / Bpp << DE_WINDOW_WIDTH_DST_SHIFT) & DE_WINDOW_WIDTH_DST_MASK) | - (sPitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */ + (source_pitch / Bpp & DE_WINDOW_WIDTH_SRC_MASK)); /* dpr3c */ if (accel->de_wait() != 0) return -1; @@ -277,7 +277,7 @@ int sm750_hw_copyarea(struct lynx_accel *accel, (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */ de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT | - ((nDirection == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) | + ((direction == RIGHT_TO_LEFT) ? DE_CONTROL_DIRECTION : 0) | DE_CONTROL_COMMAND_BITBLT | DE_CONTROL_STATUS; write_dpr(accel, DE_CONTROL, de_ctrl); /* dpr0c */ @@ -299,38 +299,38 @@ static unsigned int de_get_transparency(struct lynx_accel *accel) /** * sm750_hw_imageblit * @accel: Acceleration device data - * @pSrcbuf: pointer to start of source buffer in system memory - * @srcDelta: Pitch value (in bytes) of the source buffer, +ive means top down + * @src_buf: pointer to start of source buffer in system memory + * @src_delta: Pitch value (in bytes) of the source buffer, +ive means top down * and -ive mean button up - * @startBit: Mono data can start at any bit in a byte, this value should be + * @start_bit: Mono data can start at any bit in a byte, this value should be * 0 to 7 - * @dBase: Address of destination: offset in frame buffer - * @dPitch: Pitch value of destination surface in BYTE - * @bytePerPixel: Color depth of destination surface + * @dest_base: Address of destination: offset in frame buffer + * @dest_pitch: Pitch value of destination surface in BYTE + * @byte_per_pixel: Color depth of destination surface * @dx: Starting x coordinate of destination surface * @dy: Starting y coordinate of destination surface * @width: width of rectangle in pixel value * @height: height of rectangle in pixel value - * @fColor: Foreground color (corresponding to a 1 in the monochrome data - * @bColor: Background color (corresponding to a 0 in the monochrome data + * @fg_color: Foreground color (corresponding to a 1 in the monochrome data + * @bg_color: Background color (corresponding to a 0 in the monochrome data * @rop2: ROP value */ -int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, - u32 srcDelta, u32 startBit, u32 dBase, u32 dPitch, - u32 bytePerPixel, u32 dx, u32 dy, u32 width, - u32 height, u32 fColor, u32 bColor, u32 rop2) +int sm750_hw_imageblit(struct lynx_accel *accel, const char *src_buf, + u32 src_delta, u32 start_bit, u32 dest_base, u32 dest_pitch, + u32 byte_per_pixel, u32 dx, u32 dy, u32 width, + u32 height, u32 fg_color, u32 bg_color, u32 rop2) { - unsigned int ulBytesPerScan; - unsigned int ul4BytesPerScan; - unsigned int ulBytesRemain; + unsigned int bytes_per_scan; + unsigned int words_per_scan; + unsigned int bytes_remain; unsigned int de_ctrl = 0; - unsigned char ajRemain[4]; + unsigned char remain[4]; int i, j; - startBit &= 7; /* Just make sure the start bit is within legal range */ - ulBytesPerScan = (width + startBit + 7) / 8; - ul4BytesPerScan = ulBytesPerScan & ~3; - ulBytesRemain = ulBytesPerScan & 3; + start_bit &= 7; /* Just make sure the start bit is within legal range */ + bytes_per_scan = (width + start_bit + 7) / 8; + words_per_scan = bytes_per_scan & ~3; + bytes_remain = bytes_per_scan & 3; if (accel->de_wait() != 0) return -1; @@ -345,7 +345,7 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, * It is an address offset (128 bit aligned) * from the beginning of frame buffer. */ - write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dBase); + write_dpr(accel, DE_WINDOW_DESTINATION_BASE, dest_base); /* * Program pitch (distance between the 1st points of two adjacent @@ -353,9 +353,9 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, * register uses pixel values. Need Byte to pixel conversion. */ write_dpr(accel, DE_PITCH, - ((dPitch / bytePerPixel << DE_PITCH_DESTINATION_SHIFT) & + ((dest_pitch / byte_per_pixel << DE_PITCH_DESTINATION_SHIFT) & DE_PITCH_DESTINATION_MASK) | - (dPitch / bytePerPixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */ + (dest_pitch / byte_per_pixel & DE_PITCH_SOURCE_MASK)); /* dpr10 */ /* * Screen Window width in Pixels. @@ -363,17 +363,17 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, * in frame buffer for a given point. */ write_dpr(accel, DE_WINDOW_WIDTH, - ((dPitch / bytePerPixel << DE_WINDOW_WIDTH_DST_SHIFT) & + ((dest_pitch / byte_per_pixel << DE_WINDOW_WIDTH_DST_SHIFT) & DE_WINDOW_WIDTH_DST_MASK) | - (dPitch / bytePerPixel & DE_WINDOW_WIDTH_SRC_MASK)); + (dest_pitch / byte_per_pixel & DE_WINDOW_WIDTH_SRC_MASK)); /* * Note: For 2D Source in Host Write, only X_K1_MONO field is needed, * and Y_K2 field is not used. - * For mono bitmap, use startBit for X_K1. + * For mono bitmap, use start_bit for X_K1. */ write_dpr(accel, DE_SOURCE, - (startBit << DE_SOURCE_X_K1_SHIFT) & + (start_bit << DE_SOURCE_X_K1_SHIFT) & DE_SOURCE_X_K1_MONO_MASK); /* dpr00 */ write_dpr(accel, DE_DESTINATION, @@ -384,8 +384,8 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, ((width << DE_DIMENSION_X_SHIFT) & DE_DIMENSION_X_MASK) | (height & DE_DIMENSION_Y_ET_MASK)); /* dpr08 */ - write_dpr(accel, DE_FOREGROUND, fColor); - write_dpr(accel, DE_BACKGROUND, bColor); + write_dpr(accel, DE_FOREGROUND, fg_color); + write_dpr(accel, DE_BACKGROUND, bg_color); de_ctrl = (rop2 & DE_CONTROL_ROP_MASK) | DE_CONTROL_ROP_SELECT | DE_CONTROL_COMMAND_HOST_WRITE | @@ -396,16 +396,16 @@ int sm750_hw_imageblit(struct lynx_accel *accel, const char *pSrcbuf, /* Write MONO data (line by line) to 2D Engine data port */ for (i = 0; i < height; i++) { /* For each line, send the data in chunks of 4 bytes */ - for (j = 0; j < (ul4BytesPerScan / 4); j++) - write_dpPort(accel, *(unsigned int *)(pSrcbuf + (j * 4))); + for (j = 0; j < (words_per_scan / 4); j++) + write_dp_port(accel, *(unsigned int *)(src_buf + (j * 4))); - if (ulBytesRemain) { - memcpy(ajRemain, pSrcbuf + ul4BytesPerScan, - ulBytesRemain); - write_dpPort(accel, *(unsigned int *)ajRemain); + if (bytes_remain) { + memcpy(remain, src_buf + words_per_scan, + bytes_remain); + write_dp_port(accel, *(unsigned int *)remain); } - pSrcbuf += srcDelta; + src_buf += src_delta; } return 0; diff --git a/drivers/staging/sm750fb/sm750_hw.c b/drivers/staging/sm750fb/sm750_hw.c index ce46f240cbaf..f60b152a647d 100644 --- a/drivers/staging/sm750fb/sm750_hw.c +++ b/drivers/staging/sm750fb/sm750_hw.c @@ -36,16 +36,11 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) pr_info("mmio phyAddr = %lx\n", sm750_dev->vidreg_start); - /* - * reserve the vidreg space of smi adaptor - * if you do this, you need to add release region code - * in lynxfb_remove, or memory will not be mapped again - * successfully - */ + /* reserve the vidreg space of smi adaptor */ ret = pci_request_region(pdev, 1, "sm750fb"); if (ret) { pr_err("Can not request PCI regions.\n"); - goto exit; + return ret; } /* now map mmio and vidmem */ @@ -54,7 +49,7 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) if (!sm750_dev->pvReg) { pr_err("mmio failed\n"); ret = -EFAULT; - goto exit; + goto err_release_region; } pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg); @@ -79,13 +74,18 @@ int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev) sm750_dev->pvMem = ioremap_wc(sm750_dev->vidmem_start, sm750_dev->vidmem_size); if (!sm750_dev->pvMem) { - iounmap(sm750_dev->pvReg); pr_err("Map video memory failed\n"); ret = -EFAULT; - goto exit; + goto err_unmap_reg; } pr_info("video memory vaddr = %p\n", sm750_dev->pvMem); -exit: + + return 0; + +err_unmap_reg: + iounmap(sm750_dev->pvReg); +err_release_region: + pci_release_region(pdev, 1); return ret; } @@ -93,7 +93,7 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) { struct init_status *parm; - parm = &sm750_dev->initParm; + parm = &sm750_dev->init_parm; if (parm->chip_clk == 0) parm->chip_clk = (sm750_get_chip_type() == SM750LE) ? DEFAULT_SM750LE_CHIP_CLOCK : @@ -104,7 +104,7 @@ int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev) if (parm->master_clk == 0) parm->master_clk = parm->chip_clk / 3; - ddk750_init_hw((struct initchip_param *)&sm750_dev->initParm); + ddk750_init_hw((struct initchip_param *)&sm750_dev->init_parm); /* for sm718, open pci burst */ if (sm750_dev->devid == 0x718) { poke32(SYSTEM_CTRL, diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c index 68e8d491a7ec..bce42bff307f 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c @@ -108,7 +108,7 @@ static int snd_bcm2835_playback_open_generic(struct snd_pcm_substream *substream goto out; } - alsa_stream = kzalloc(sizeof(*alsa_stream), GFP_KERNEL); + alsa_stream = kzalloc_obj(*alsa_stream); if (!alsa_stream) { err = -ENOMEM; goto out; diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 7368b384497f..3156cb8392f4 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -219,7 +219,7 @@ int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) int err; /* Allocate memory for this instance */ - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) return -ENOMEM; mutex_init(&instance->vchi_mutex); diff --git a/drivers/staging/vme_user/vme.c b/drivers/staging/vme_user/vme.c index 2095de72596a..f10a00c05f12 100644 --- a/drivers/staging/vme_user/vme.c +++ b/drivers/staging/vme_user/vme.c @@ -287,7 +287,7 @@ struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, if (!allocated_image) goto err_image; - resource = kmalloc(sizeof(*resource), GFP_KERNEL); + resource = kmalloc_obj(*resource); if (!resource) goto err_alloc; @@ -484,7 +484,7 @@ struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, goto err_image; } - resource = kmalloc(sizeof(*resource), GFP_KERNEL); + resource = kmalloc_obj(*resource); if (!resource) goto err_alloc; @@ -854,7 +854,7 @@ struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route) if (!allocated_ctrlr) goto err_ctrlr; - resource = kmalloc(sizeof(*resource), GFP_KERNEL); + resource = kmalloc_obj(*resource); if (!resource) goto err_alloc; @@ -894,7 +894,7 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) return NULL; } - dma_list = kmalloc(sizeof(*dma_list), GFP_KERNEL); + dma_list = kmalloc_obj(*dma_list); if (!dma_list) return NULL; @@ -924,11 +924,11 @@ struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type) struct vme_dma_attr *attributes; struct vme_dma_pattern *pattern_attr; - attributes = kmalloc(sizeof(*attributes), GFP_KERNEL); + attributes = kmalloc_obj(*attributes); if (!attributes) goto err_attr; - pattern_attr = kmalloc(sizeof(*pattern_attr), GFP_KERNEL); + pattern_attr = kmalloc_obj(*pattern_attr); if (!pattern_attr) goto err_pat; @@ -964,11 +964,11 @@ struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address) /* XXX Run some sanity checks here */ - attributes = kmalloc(sizeof(*attributes), GFP_KERNEL); + attributes = kmalloc_obj(*attributes); if (!attributes) goto err_attr; - pci_attr = kmalloc(sizeof(*pci_attr), GFP_KERNEL); + pci_attr = kmalloc_obj(*pci_attr); if (!pci_attr) goto err_pci; @@ -1005,11 +1005,11 @@ struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, struct vme_dma_attr *attributes; struct vme_dma_vme *vme_attr; - attributes = kmalloc(sizeof(*attributes), GFP_KERNEL); + attributes = kmalloc_obj(*attributes); if (!attributes) goto err_attr; - vme_attr = kmalloc(sizeof(*vme_attr), GFP_KERNEL); + vme_attr = kmalloc_obj(*vme_attr); if (!vme_attr) goto err_vme; @@ -1233,7 +1233,7 @@ struct vme_error_handler *vme_register_error_handler(struct vme_bridge *bridge, { struct vme_error_handler *handler; - handler = kmalloc(sizeof(*handler), GFP_ATOMIC); + handler = kmalloc_obj(*handler, GFP_ATOMIC); if (!handler) return NULL; @@ -1288,7 +1288,7 @@ EXPORT_SYMBOL(vme_irq_handler); * already in use. Hardware specific errors also possible. */ int vme_irq_request(struct vme_dev *vdev, int level, int statid, - void (*callback)(int, int, void *), + void (*callback)(int level, int statid, void *priv_data), void *priv_data) { struct vme_bridge *bridge; @@ -1458,7 +1458,7 @@ struct vme_resource *vme_lm_request(struct vme_dev *vdev) if (!allocated_lm) goto err_lm; - resource = kmalloc(sizeof(*resource), GFP_KERNEL); + resource = kmalloc_obj(*resource); if (!resource) goto err_alloc; @@ -1810,7 +1810,7 @@ static int __vme_register_driver_bus(struct vme_driver *drv, struct vme_dev *tmp; for (i = 0; i < ndevs; i++) { - vdev = kzalloc(sizeof(*vdev), GFP_KERNEL); + vdev = kzalloc_obj(*vdev); if (!vdev) { err = -ENOMEM; goto err_devalloc; diff --git a/drivers/staging/vme_user/vme.h b/drivers/staging/vme_user/vme.h index 7753e736f9fd..797e9940fdd1 100644 --- a/drivers/staging/vme_user/vme.h +++ b/drivers/staging/vme_user/vme.h @@ -121,69 +121,70 @@ struct vme_dev { */ struct vme_driver { const char *name; - int (*match)(struct vme_dev *); - int (*probe)(struct vme_dev *); - void (*remove)(struct vme_dev *); + int (*match)(struct vme_dev *vdev); + int (*probe)(struct vme_dev *vdev); + void (*remove)(struct vme_dev *vdev); struct device_driver driver; struct list_head devices; }; -void *vme_alloc_consistent(struct vme_resource *, size_t, dma_addr_t *); -void vme_free_consistent(struct vme_resource *, size_t, void *, dma_addr_t); +void *vme_alloc_consistent(struct vme_resource *resource, size_t size, dma_addr_t *dma); +void vme_free_consistent(struct vme_resource *resource, size_t size, void *vaddr, dma_addr_t dma); -size_t vme_get_size(struct vme_resource *); +size_t vme_get_size(struct vme_resource *resource); int vme_check_window(struct vme_bridge *bridge, u32 aspace, unsigned long long vme_base, unsigned long long size); -struct vme_resource *vme_slave_request(struct vme_dev *, u32, u32); -int vme_slave_set(struct vme_resource *, int, unsigned long long, - unsigned long long, dma_addr_t, u32, u32); -int vme_slave_get(struct vme_resource *, int *, unsigned long long *, - unsigned long long *, dma_addr_t *, u32 *, u32 *); -void vme_slave_free(struct vme_resource *); +struct vme_resource *vme_slave_request(struct vme_dev *vdev, u32 address, u32 cycle); +int vme_slave_set(struct vme_resource *resource, int enabled, unsigned long long vme_base, + unsigned long long size, dma_addr_t buf_base, u32 aspace, u32 cycle); +int vme_slave_get(struct vme_resource *resource, int *enabled, unsigned long long *vme_base, + unsigned long long *size, dma_addr_t *buf_base, u32 *aspace, u32 *cycle); +void vme_slave_free(struct vme_resource *resource); -struct vme_resource *vme_master_request(struct vme_dev *, u32, u32, u32); -int vme_master_set(struct vme_resource *, int, unsigned long long, - unsigned long long, u32, u32, u32); -int vme_master_get(struct vme_resource *, int *, unsigned long long *, - unsigned long long *, u32 *, u32 *, u32 *); -ssize_t vme_master_read(struct vme_resource *, void *, size_t, loff_t); -ssize_t vme_master_write(struct vme_resource *, void *, size_t, loff_t); -unsigned int vme_master_rmw(struct vme_resource *, unsigned int, unsigned int, - unsigned int, loff_t); +struct vme_resource *vme_master_request(struct vme_dev *vdev, u32 address, u32 cycle, u32 dwidth); +int vme_master_set(struct vme_resource *resource, int enabled, unsigned long long vme_base, + unsigned long long size, u32 aspace, u32 cycle, u32 dwidth); +int vme_master_get(struct vme_resource *resource, int *enabled, unsigned long long *vme_base, + unsigned long long *size, u32 *aspace, u32 *cycle, u32 *dwidth); +ssize_t vme_master_read(struct vme_resource *resource, void *buf, size_t count, loff_t offset); +ssize_t vme_master_write(struct vme_resource *resource, void *buf, size_t count, loff_t offset); +unsigned int vme_master_rmw(struct vme_resource *resource, unsigned int mask, unsigned int compare, + unsigned int swap, loff_t offset); int vme_master_mmap(struct vme_resource *resource, struct vm_area_struct *vma); -void vme_master_free(struct vme_resource *); +void vme_master_free(struct vme_resource *resource); -struct vme_resource *vme_dma_request(struct vme_dev *, u32); -struct vme_dma_list *vme_new_dma_list(struct vme_resource *); -struct vme_dma_attr *vme_dma_pattern_attribute(u32, u32); -struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t); -struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long, u32, u32, u32); -void vme_dma_free_attribute(struct vme_dma_attr *); -int vme_dma_list_add(struct vme_dma_list *, struct vme_dma_attr *, - struct vme_dma_attr *, size_t); -int vme_dma_list_exec(struct vme_dma_list *); -int vme_dma_list_free(struct vme_dma_list *); -int vme_dma_free(struct vme_resource *); +struct vme_resource *vme_dma_request(struct vme_dev *vdev, u32 route); +struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource); +struct vme_dma_attr *vme_dma_pattern_attribute(u32 pattern, u32 type); +struct vme_dma_attr *vme_dma_pci_attribute(dma_addr_t address); +struct vme_dma_attr *vme_dma_vme_attribute(unsigned long long address, + u32 aspace, u32 cycle, u32 dwidth); +void vme_dma_free_attribute(struct vme_dma_attr *attributes); +int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, + struct vme_dma_attr *dest, size_t count); +int vme_dma_list_exec(struct vme_dma_list *list); +int vme_dma_list_free(struct vme_dma_list *list); +int vme_dma_free(struct vme_resource *resource); -int vme_irq_request(struct vme_dev *, int, int, - void (*callback)(int, int, void *), void *); -void vme_irq_free(struct vme_dev *, int, int); -int vme_irq_generate(struct vme_dev *, int, int); +int vme_irq_request(struct vme_dev *vdev, int level, int statid, + void (*callback)(int level, int statid, void *priv_data), void *priv_data); +void vme_irq_free(struct vme_dev *vdev, int level, int statid); +int vme_irq_generate(struct vme_dev *vdev, int level, int statid); -struct vme_resource *vme_lm_request(struct vme_dev *); -int vme_lm_count(struct vme_resource *); -int vme_lm_set(struct vme_resource *, unsigned long long, u32, u32); -int vme_lm_get(struct vme_resource *, unsigned long long *, u32 *, u32 *); -int vme_lm_attach(struct vme_resource *, int, void (*callback)(void *), void *); -int vme_lm_detach(struct vme_resource *, int); -void vme_lm_free(struct vme_resource *); +struct vme_resource *vme_lm_request(struct vme_dev *vdev); +int vme_lm_count(struct vme_resource *resource); +int vme_lm_set(struct vme_resource *resource, unsigned long long lm_base, u32 aspace, u32 cycle); +int vme_lm_get(struct vme_resource *resource, unsigned long long *lm_base, u32 *aspace, u32 *cycle); +int vme_lm_attach(struct vme_resource *resource, int monitor, void (*callback)(void *), void *data); +int vme_lm_detach(struct vme_resource *resource, int monitor); +void vme_lm_free(struct vme_resource *resource); -int vme_slot_num(struct vme_dev *); -int vme_bus_num(struct vme_dev *); +int vme_slot_num(struct vme_dev *vdev); +int vme_bus_num(struct vme_dev *vdev); -int vme_register_driver(struct vme_driver *, unsigned int); -void vme_unregister_driver(struct vme_driver *); +int vme_register_driver(struct vme_driver *drv, unsigned int ndevs); +void vme_unregister_driver(struct vme_driver *drv); #endif /* _VME_H_ */ diff --git a/drivers/staging/vme_user/vme_bridge.h b/drivers/staging/vme_user/vme_bridge.h index abf880d68b12..92b0baa793d7 100644 --- a/drivers/staging/vme_user/vme_bridge.h +++ b/drivers/staging/vme_user/vme_bridge.h @@ -88,7 +88,7 @@ struct vme_error_handler { }; struct vme_callback { - void (*func)(int, int, void*); + void (*func)(int level, int statid, void *priv_data); void *priv_data; }; @@ -178,11 +178,11 @@ struct vme_bridge { }; void vme_bus_error_handler(struct vme_bridge *bridge, unsigned long long address, int am); -void vme_irq_handler(struct vme_bridge *, int, int); +void vme_irq_handler(struct vme_bridge *bridge, int level, int statid); -struct vme_bridge *vme_init_bridge(struct vme_bridge *); -int vme_register_bridge(struct vme_bridge *); -void vme_unregister_bridge(struct vme_bridge *); +struct vme_bridge *vme_init_bridge(struct vme_bridge *bridge); +int vme_register_bridge(struct vme_bridge *bridge); +void vme_unregister_bridge(struct vme_bridge *bridge); struct vme_error_handler *vme_register_error_handler(struct vme_bridge *bridge, u32 aspace, unsigned long long address, size_t len); void vme_unregister_error_handler(struct vme_error_handler *handler); diff --git a/drivers/staging/vme_user/vme_fake.c b/drivers/staging/vme_user/vme_fake.c index 731fbba17dfd..be4ad47ed526 100644 --- a/drivers/staging/vme_user/vme_fake.c +++ b/drivers/staging/vme_user/vme_fake.c @@ -1073,13 +1073,13 @@ static int __init fake_init(void) /* If we want to support more than one bridge at some point, we need to * dynamically allocate this so we get one per device. */ - fake_bridge = kzalloc(sizeof(*fake_bridge), GFP_KERNEL); + fake_bridge = kzalloc_obj(*fake_bridge); if (!fake_bridge) { retval = -ENOMEM; goto err_struct; } - fake_device = kzalloc(sizeof(*fake_device), GFP_KERNEL); + fake_device = kzalloc_obj(*fake_device); if (!fake_device) { retval = -ENOMEM; goto err_driver; @@ -1102,7 +1102,7 @@ static int __init fake_init(void) /* Add master windows to list */ INIT_LIST_HEAD(&fake_bridge->master_resources); for (i = 0; i < FAKE_MAX_MASTER; i++) { - master_image = kmalloc(sizeof(*master_image), GFP_KERNEL); + master_image = kmalloc_obj(*master_image); if (!master_image) { retval = -ENOMEM; goto err_master; @@ -1128,7 +1128,7 @@ static int __init fake_init(void) /* Add slave windows to list */ INIT_LIST_HEAD(&fake_bridge->slave_resources); for (i = 0; i < FAKE_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(*slave_image), GFP_KERNEL); + slave_image = kmalloc_obj(*slave_image); if (!slave_image) { retval = -ENOMEM; goto err_slave; @@ -1150,7 +1150,7 @@ static int __init fake_init(void) /* Add location monitor to list */ INIT_LIST_HEAD(&fake_bridge->lm_resources); - lm = kmalloc(sizeof(*lm), GFP_KERNEL); + lm = kmalloc_obj(*lm); if (!lm) { retval = -ENOMEM; goto err_lm; diff --git a/drivers/staging/vme_user/vme_tsi148.c b/drivers/staging/vme_user/vme_tsi148.c index 733594dde9ae..4cf3486646ce 100644 --- a/drivers/staging/vme_user/vme_tsi148.c +++ b/drivers/staging/vme_user/vme_tsi148.c @@ -1611,7 +1611,7 @@ static int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *s tsi148_bridge = list->parent->parent; /* Descriptor must be aligned on 64-bit boundaries */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { retval = -ENOMEM; goto err_mem; @@ -2260,14 +2260,14 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* If we want to support more than one of each bridge, we need to * dynamically generate this so we get one per device */ - tsi148_bridge = kzalloc(sizeof(*tsi148_bridge), GFP_KERNEL); + tsi148_bridge = kzalloc_obj(*tsi148_bridge); if (!tsi148_bridge) { retval = -ENOMEM; goto err_struct; } vme_init_bridge(tsi148_bridge); - tsi148_device = kzalloc(sizeof(*tsi148_device), GFP_KERNEL); + tsi148_device = kzalloc_obj(*tsi148_device); if (!tsi148_device) { retval = -ENOMEM; goto err_driver; @@ -2332,9 +2332,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) if (err_chk) { master_num--; - tsi148_device->flush_image = - kmalloc(sizeof(*tsi148_device->flush_image), - GFP_KERNEL); + tsi148_device->flush_image = kmalloc_obj(*tsi148_device->flush_image); if (!tsi148_device->flush_image) { retval = -ENOMEM; goto err_master; @@ -2350,7 +2348,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add master windows to list */ for (i = 0; i < master_num; i++) { - master_image = kmalloc(sizeof(*master_image), GFP_KERNEL); + master_image = kmalloc_obj(*master_image); if (!master_image) { retval = -ENOMEM; goto err_master; @@ -2376,7 +2374,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add slave windows to list */ for (i = 0; i < TSI148_MAX_SLAVE; i++) { - slave_image = kmalloc(sizeof(*slave_image), GFP_KERNEL); + slave_image = kmalloc_obj(*slave_image); if (!slave_image) { retval = -ENOMEM; goto err_slave; @@ -2397,7 +2395,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) /* Add dma engines to list */ for (i = 0; i < TSI148_MAX_DMA; i++) { - dma_ctrlr = kmalloc(sizeof(*dma_ctrlr), GFP_KERNEL); + dma_ctrlr = kmalloc_obj(*dma_ctrlr); if (!dma_ctrlr) { retval = -ENOMEM; goto err_dma; @@ -2417,7 +2415,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Add location monitor to list */ - lm = kmalloc(sizeof(*lm), GFP_KERNEL); + lm = kmalloc_obj(*lm); if (!lm) { retval = -ENOMEM; goto err_lm; diff --git a/drivers/staging/vme_user/vme_user.c b/drivers/staging/vme_user/vme_user.c index 5829a4141561..d95dd7d9190a 100644 --- a/drivers/staging/vme_user/vme_user.c +++ b/drivers/staging/vme_user/vme_user.c @@ -464,7 +464,7 @@ static int vme_user_master_mmap(unsigned int minor, struct vm_area_struct *vma) return err; } - vma_priv = kmalloc(sizeof(*vma_priv), GFP_KERNEL); + vma_priv = kmalloc_obj(*vma_priv); if (!vma_priv) { mutex_unlock(&image[minor].mutex); return -ENOMEM; @@ -690,7 +690,7 @@ static int vme_user_probe(struct vme_dev *vdev) return err; } -static void vme_user_remove(struct vme_dev *dev) +static void vme_user_remove(struct vme_dev *vdev) { int i; diff --git a/drivers/target/iscsi/cxgbit/cxgbit_cm.c b/drivers/target/iscsi/cxgbit/cxgbit_cm.c index d9204c590d9a..146705845fa3 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_cm.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_cm.c @@ -79,7 +79,7 @@ static struct np_info * cxgbit_np_hash_add(struct cxgbit_device *cdev, struct cxgbit_np *cnp, unsigned int stid) { - struct np_info *p = kzalloc(sizeof(*p), GFP_KERNEL); + struct np_info *p = kzalloc_obj(*p); if (p) { int bucket = cxgbit_np_hashfn(cnp); @@ -431,7 +431,7 @@ int cxgbit_setup_np(struct iscsi_np *np, struct sockaddr_storage *ksockaddr) (ksockaddr->ss_family != AF_INET6)) return -EINVAL; - cnp = kzalloc(sizeof(*cnp), GFP_KERNEL); + cnp = kzalloc_obj(*cnp); if (!cnp) return -ENOMEM; @@ -1288,7 +1288,7 @@ cxgbit_pass_accept_req(struct cxgbit_device *cdev, struct sk_buff *skb) goto reject; } - csk = kzalloc(sizeof(*csk), GFP_ATOMIC); + csk = kzalloc_obj(*csk, GFP_ATOMIC); if (!csk) { dst_release(dst); goto rel_skb; diff --git a/drivers/target/iscsi/cxgbit/cxgbit_main.c b/drivers/target/iscsi/cxgbit/cxgbit_main.c index 2c1950df3b3e..b6036820fc95 100644 --- a/drivers/target/iscsi/cxgbit/cxgbit_main.c +++ b/drivers/target/iscsi/cxgbit/cxgbit_main.c @@ -57,7 +57,7 @@ static void *cxgbit_uld_add(const struct cxgb4_lld_info *lldi) if (is_t4(lldi->adapter_type)) return ERR_PTR(-ENODEV); - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return ERR_PTR(-ENOMEM); @@ -646,7 +646,7 @@ cxgbit_dcbevent_notify(struct notifier_block *nb, unsigned long action, struct cxgbit_dcb_work *dcb_work; struct dcb_app_type *dcb_app = data; - dcb_work = kzalloc(sizeof(*dcb_work), GFP_ATOMIC); + dcb_work = kzalloc_obj(*dcb_work, GFP_ATOMIC); if (!dcb_work) return NOTIFY_DONE; diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index a2dde08c8a62..e80449f6ce15 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -121,7 +121,7 @@ struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf) return ERR_PTR(-EINVAL); } - tiqn = kzalloc(sizeof(*tiqn), GFP_KERNEL); + tiqn = kzalloc_obj(*tiqn); if (!tiqn) return ERR_PTR(-ENOMEM); @@ -352,7 +352,7 @@ struct iscsi_np *iscsit_add_np( return np; } - np = kzalloc(sizeof(*np), GFP_KERNEL); + np = kzalloc_obj(*np); if (!np) { mutex_unlock(&np_lock); return ERR_PTR(-ENOMEM); @@ -674,7 +674,7 @@ static int __init iscsi_target_init_module(void) int ret = 0, size; pr_debug("iSCSI-Target "ISCSIT_VERSION"\n"); - iscsit_global = kzalloc(sizeof(*iscsit_global), GFP_KERNEL); + iscsit_global = kzalloc_obj(*iscsit_global); if (!iscsit_global) return -1; @@ -981,7 +981,7 @@ static int iscsit_allocate_iovecs(struct iscsit_cmd *cmd) u32 iov_count = max(1UL, DIV_ROUND_UP(cmd->se_cmd.data_length, PAGE_SIZE)); iov_count += ISCSI_IOV_DATA_BUFFER; - cmd->iov_data = kcalloc(iov_count, sizeof(*cmd->iov_data), GFP_KERNEL); + cmd->iov_data = kzalloc_objs(*cmd->iov_data, iov_count); if (!cmd->iov_data) return -ENOMEM; @@ -1992,7 +1992,7 @@ iscsit_handle_task_mgt_cmd(struct iscsit_conn *conn, struct iscsit_cmd *cmd, hdr->refcmdsn = cpu_to_be32(ISCSI_RESERVED_TAG); cmd->data_direction = DMA_NONE; - cmd->tmr_req = kzalloc(sizeof(*cmd->tmr_req), GFP_KERNEL); + cmd->tmr_req = kzalloc_obj(*cmd->tmr_req); if (!cmd->tmr_req) { return iscsit_add_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES, diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index 2c4d583fe3e6..c46c69a28e97 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -152,7 +152,7 @@ static struct iscsi_chap *chap_server_open( return NULL; } - conn->auth_protocol = kzalloc(sizeof(struct iscsi_chap), GFP_KERNEL); + conn->auth_protocol = kzalloc_obj(struct iscsi_chap); if (!conn->auth_protocol) return NULL; diff --git a/drivers/target/iscsi/iscsi_target_erl2.c b/drivers/target/iscsi/iscsi_target_erl2.c index 56d78af7cec7..bda254a0d4ed 100644 --- a/drivers/target/iscsi/iscsi_target_erl2.c +++ b/drivers/target/iscsi/iscsi_target_erl2.c @@ -268,7 +268,7 @@ int iscsit_prepare_cmds_for_reallegiance(struct iscsit_conn *conn) * (struct iscsit_cmd->cr) so we need to allocate this before preparing the * connection's command list for connection recovery. */ - cr = kzalloc(sizeof(struct iscsi_conn_recovery), GFP_KERNEL); + cr = kzalloc_obj(struct iscsi_conn_recovery); if (!cr) { pr_err("Unable to allocate memory for" " struct iscsi_conn_recovery.\n"); diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 53aca059dc16..aafc94bcb635 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -38,7 +38,7 @@ static struct iscsi_login *iscsi_login_init_conn(struct iscsit_conn *conn) { struct iscsi_login *login; - login = kzalloc(sizeof(struct iscsi_login), GFP_KERNEL); + login = kzalloc_obj(struct iscsi_login); if (!login) { pr_err("Unable to allocate memory for struct iscsi_login.\n"); return NULL; @@ -219,7 +219,7 @@ static int iscsi_login_zero_tsih_s1( struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; int ret; - sess = kzalloc(sizeof(struct iscsit_session), GFP_KERNEL); + sess = kzalloc_obj(struct iscsit_session); if (!sess) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); @@ -267,7 +267,7 @@ static int iscsi_login_zero_tsih_s1( */ atomic_set(&sess->max_cmd_sn, be32_to_cpu(pdu->cmdsn)); - sess->sess_ops = kzalloc(sizeof(struct iscsi_sess_ops), GFP_KERNEL); + sess->sess_ops = kzalloc_obj(struct iscsi_sess_ops); if (!sess->sess_ops) { iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); @@ -1002,7 +1002,7 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np) { struct iscsit_conn *conn; - conn = kzalloc(sizeof(struct iscsit_conn), GFP_KERNEL); + conn = kzalloc_obj(struct iscsit_conn); if (!conn) { pr_err("Could not allocate memory for new connection\n"); return NULL; @@ -1040,7 +1040,7 @@ static struct iscsit_conn *iscsit_alloc_conn(struct iscsi_np *np) if (iscsit_conn_set_transport(conn, np->np_transport) < 0) goto free_conn; - conn->conn_ops = kzalloc(sizeof(struct iscsi_conn_ops), GFP_KERNEL); + conn->conn_ops = kzalloc_obj(struct iscsi_conn_ops); if (!conn->conn_ops) { pr_err("Unable to allocate memory for struct iscsi_conn_ops.\n"); goto put_transport; diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c index 1d4e1788e073..4ed578c7b98d 100644 --- a/drivers/target/iscsi/iscsi_target_parameters.c +++ b/drivers/target/iscsi/iscsi_target_parameters.c @@ -73,7 +73,7 @@ static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *para { struct iscsi_param *param = NULL; - param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL); + param = kzalloc_obj(struct iscsi_param); if (!param) { pr_err("Unable to allocate memory for parameter.\n"); goto out; @@ -148,7 +148,7 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) struct iscsi_param *param = NULL; struct iscsi_param_list *pl; - pl = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); + pl = kzalloc_obj(struct iscsi_param_list); if (!pl) { pr_err("Unable to allocate memory for" " struct iscsi_param_list.\n"); @@ -519,7 +519,7 @@ int iscsi_copy_param_list( struct iscsi_param *new_param = NULL; struct iscsi_param_list *param_list = NULL; - param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); + param_list = kzalloc_obj(struct iscsi_param_list); if (!param_list) { pr_err("Unable to allocate memory for struct iscsi_param_list.\n"); return -ENOMEM; @@ -535,7 +535,7 @@ int iscsi_copy_param_list( continue; } - new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL); + new_param = kzalloc_obj(struct iscsi_param); if (!new_param) { pr_err("Unable to allocate memory for struct iscsi_param.\n"); goto err_out; @@ -670,7 +670,7 @@ static int iscsi_add_notunderstood_response( return -1; } - extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL); + extra_response = kzalloc_obj(struct iscsi_extra_response); if (!extra_response) { pr_err("Unable to allocate memory for" " struct iscsi_extra_response.\n"); diff --git a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c index 66de2b8de463..75c37c8866c8 100644 --- a/drivers/target/iscsi/iscsi_target_seq_pdu_list.c +++ b/drivers/target/iscsi/iscsi_target_seq_pdu_list.c @@ -535,7 +535,7 @@ int iscsit_build_pdu_and_seq_lists( iscsit_determine_counts_for_list(cmd, &bl, &seq_count, &pdu_count); if (!conn->sess->sess_ops->DataSequenceInOrder) { - seq = kcalloc(seq_count, sizeof(struct iscsi_seq), GFP_ATOMIC); + seq = kzalloc_objs(struct iscsi_seq, seq_count, GFP_ATOMIC); if (!seq) { pr_err("Unable to allocate struct iscsi_seq list\n"); return -ENOMEM; @@ -545,7 +545,7 @@ int iscsit_build_pdu_and_seq_lists( } if (!conn->sess->sess_ops->DataPDUInOrder) { - pdu = kcalloc(pdu_count, sizeof(struct iscsi_pdu), GFP_ATOMIC); + pdu = kzalloc_objs(struct iscsi_pdu, pdu_count, GFP_ATOMIC); if (!pdu) { pr_err("Unable to allocate struct iscsi_pdu list.\n"); kfree(seq); diff --git a/drivers/target/iscsi/iscsi_target_tpg.c b/drivers/target/iscsi/iscsi_target_tpg.c index bf06cfdfb012..99772364c88e 100644 --- a/drivers/target/iscsi/iscsi_target_tpg.c +++ b/drivers/target/iscsi/iscsi_target_tpg.c @@ -26,7 +26,7 @@ struct iscsi_portal_group *iscsit_alloc_portal_group(struct iscsi_tiqn *tiqn, u1 { struct iscsi_portal_group *tpg; - tpg = kzalloc(sizeof(struct iscsi_portal_group), GFP_KERNEL); + tpg = kzalloc_obj(struct iscsi_portal_group); if (!tpg) { pr_err("Unable to allocate struct iscsi_portal_group\n"); return NULL; @@ -464,7 +464,7 @@ struct iscsi_tpg_np *iscsit_tpg_add_network_portal( } } - tpg_np = kzalloc(sizeof(struct iscsi_tpg_np), GFP_KERNEL); + tpg_np = kzalloc_obj(struct iscsi_tpg_np); if (!tpg_np) { pr_err("Unable to allocate memory for" " struct iscsi_tpg_np.\n"); diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c index 0821a149573e..d668bd19fd4a 100644 --- a/drivers/target/loopback/tcm_loop.c +++ b/drivers/target/loopback/tcm_loop.c @@ -693,7 +693,7 @@ static int tcm_loop_make_nexus( return -EEXIST; } - tl_nexus = kzalloc(sizeof(*tl_nexus), GFP_KERNEL); + tl_nexus = kzalloc_obj(*tl_nexus); if (!tl_nexus) return -ENOMEM; @@ -994,7 +994,7 @@ static struct se_wwn *tcm_loop_make_scsi_hba( char *ptr; int ret, off = 0; - tl_hba = kzalloc(sizeof(*tl_hba), GFP_KERNEL); + tl_hba = kzalloc_obj(*tl_hba); if (!tl_hba) return ERR_PTR(-ENOMEM); diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c index 09120a538a40..ad1da7edbb08 100644 --- a/drivers/target/sbp/sbp_target.c +++ b/drivers/target/sbp/sbp_target.c @@ -186,7 +186,7 @@ static struct sbp_session *sbp_session_create( snprintf(guid_str, sizeof(guid_str), "%016llx", guid); - sess = kmalloc(sizeof(*sess), GFP_KERNEL); + sess = kmalloc_obj(*sess); if (!sess) return ERR_PTR(-ENOMEM); @@ -391,7 +391,7 @@ static void sbp_management_request_login( 1 << LOGIN_ORB_RECONNECT(be32_to_cpu(req->orb.misc)), tport->max_reconnect_timeout) - 1; - login = kmalloc(sizeof(*login), GFP_KERNEL); + login = kmalloc_obj(*login); if (!login) { pr_err("failed to allocate login descriptor\n"); @@ -428,7 +428,7 @@ static void sbp_management_request_login( spin_unlock_bh(&sess->lock); already_logged_in: - response = kzalloc(sizeof(*response), GFP_KERNEL); + response = kzalloc_obj(*response); if (!response) { pr_err("failed to allocate login response block\n"); @@ -1014,7 +1014,7 @@ static struct sbp_target_agent *sbp_target_agent_register( struct sbp_target_agent *agent; int ret; - agent = kmalloc(sizeof(*agent), GFP_KERNEL); + agent = kmalloc_obj(*agent); if (!agent) return ERR_PTR(-ENOMEM); @@ -1603,7 +1603,7 @@ static void sbp_mgt_agent_rw(struct fw_card *card, rcode = RCODE_CONFLICT_ERROR; goto out; } - req = kzalloc(sizeof(*req), GFP_ATOMIC); + req = kzalloc_obj(*req, GFP_ATOMIC); if (!req) { rcode = RCODE_CONFLICT_ERROR; goto out; @@ -1636,7 +1636,7 @@ static struct sbp_management_agent *sbp_management_agent_register( int ret; struct sbp_management_agent *agent; - agent = kmalloc(sizeof(*agent), GFP_KERNEL); + agent = kmalloc_obj(*agent); if (!agent) return ERR_PTR(-ENOMEM); @@ -1973,7 +1973,7 @@ static struct se_portal_group *sbp_make_tpg(struct se_wwn *wwn, return ERR_PTR(-EBUSY); } - tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); + tpg = kzalloc_obj(*tpg); if (!tpg) return ERR_PTR(-ENOMEM); @@ -2030,7 +2030,7 @@ static struct se_wwn *sbp_make_tport( if (sbp_parse_wwn(name, &guid) < 0) return ERR_PTR(-EINVAL); - tport = kzalloc(sizeof(*tport), GFP_KERNEL); + tport = kzalloc_obj(*tport); if (!tport) return ERR_PTR(-ENOMEM); diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c index b27a3b8dd767..a1c91d4515bc 100644 --- a/drivers/target/target_core_configfs.c +++ b/drivers/target/target_core_configfs.c @@ -108,8 +108,8 @@ static ssize_t target_core_item_dbroot_store(struct config_item *item, const char *page, size_t count) { ssize_t read_bytes; - struct file *fp; ssize_t r = -EINVAL; + struct path path = {}; mutex_lock(&target_devices_lock); if (target_devices) { @@ -131,17 +131,14 @@ static ssize_t target_core_item_dbroot_store(struct config_item *item, db_root_stage[read_bytes - 1] = '\0'; /* validate new db root before accepting it */ - fp = filp_open(db_root_stage, O_RDONLY, 0); - if (IS_ERR(fp)) { + r = kern_path(db_root_stage, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path); + if (r) { pr_err("db_root: cannot open: %s\n", db_root_stage); + if (r == -ENOTDIR) + pr_err("db_root: not a directory: %s\n", db_root_stage); goto unlock; } - if (!S_ISDIR(file_inode(fp)->i_mode)) { - filp_close(fp, NULL); - pr_err("db_root: not a directory: %s\n", db_root_stage); - goto unlock; - } - filp_close(fp, NULL); + path_put(&path); strscpy(db_root, db_root_stage); pr_debug("Target_Core_ConfigFS: db_root set to %s\n", db_root); @@ -475,12 +472,12 @@ int target_register_template(const struct target_core_fabric_ops *fo) if (ret) return ret; - tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL); + tf = kzalloc_obj(struct target_fabric_configfs); if (!tf) { pr_err("%s: could not allocate memory!\n", __func__); return -ENOMEM; } - tfo = kzalloc(sizeof(struct target_core_fabric_ops), GFP_KERNEL); + tfo = kzalloc_obj(struct target_core_fabric_ops); if (!tfo) { kfree(tf); pr_err("%s: could not allocate memory!\n", __func__); diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index 8ccb8541db1c..74c6383f9eed 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c @@ -324,7 +324,7 @@ int core_enable_device_list_for_node( struct se_dev_entry *orig, *new; int ret = 0; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) { pr_err("Unable to allocate se_dev_entry memory\n"); return -ENOMEM; @@ -591,7 +591,7 @@ struct se_lun_acl *core_dev_init_initiator_node_lun_acl( *ret = -EOVERFLOW; return NULL; } - lacl = kzalloc(sizeof(struct se_lun_acl), GFP_KERNEL); + lacl = kzalloc_obj(struct se_lun_acl); if (!lacl) { pr_err("Unable to allocate memory for struct se_lun_acl.\n"); *ret = -ENOMEM; @@ -726,7 +726,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) if (!dev->stats) goto free_device; - dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); + dev->queues = kzalloc_objs(*dev->queues, nr_cpu_ids); if (!dev->queues) goto free_stats; diff --git a/drivers/target/target_core_fabric_configfs.c b/drivers/target/target_core_fabric_configfs.c index 59713e9be10a..331689b30f85 100644 --- a/drivers/target/target_core_fabric_configfs.c +++ b/drivers/target/target_core_fabric_configfs.c @@ -899,7 +899,7 @@ target_fabric_setup_tpg_base_cit(struct target_fabric_configfs *tf) nr_attrs++; /* + 1 for final NULL in the array */ - attrs = kcalloc(nr_attrs + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, nr_attrs + 1); if (!attrs) return -ENOMEM; diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index b2610073e8cc..3ae1f7137d9d 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -38,7 +38,7 @@ static int fd_attach_hba(struct se_hba *hba, u32 host_id) { struct fd_host *fd_host; - fd_host = kzalloc(sizeof(struct fd_host), GFP_KERNEL); + fd_host = kzalloc_obj(struct fd_host); if (!fd_host) { pr_err("Unable to allocate memory for struct fd_host\n"); return -ENOMEM; @@ -73,7 +73,7 @@ static struct se_device *fd_alloc_device(struct se_hba *hba, const char *name) struct fd_dev *fd_dev; struct fd_host *fd_host = hba->hba_ptr; - fd_dev = kzalloc(sizeof(struct fd_dev), GFP_KERNEL); + fd_dev = kzalloc_obj(struct fd_dev); if (!fd_dev) { pr_err("Unable to allocate memory for struct fd_dev\n"); return NULL; @@ -276,7 +276,7 @@ fd_execute_rw_aio(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, ssize_t len = 0; int ret = 0, i; - aio_cmd = kmalloc(struct_size(aio_cmd, bvecs, sgl_nents), GFP_KERNEL); + aio_cmd = kmalloc_flex(*aio_cmd, bvecs, sgl_nents); if (!aio_cmd) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; @@ -320,7 +320,7 @@ static int fd_do_rw(struct se_cmd *cmd, struct file *fd, loff_t pos = (cmd->t_task_lba * block_size); int ret = 0, i; - bvec = kcalloc(sgl_nents, sizeof(struct bio_vec), GFP_KERNEL); + bvec = kzalloc_objs(struct bio_vec, sgl_nents); if (!bvec) { pr_err("Unable to allocate fd_do_readv iov[]\n"); return -ENOMEM; @@ -455,7 +455,7 @@ fd_execute_write_same(struct se_cmd *cmd) return TCM_INVALID_CDB_FIELD; } - bvec = kcalloc(nolb, sizeof(struct bio_vec), GFP_KERNEL); + bvec = kzalloc_objs(struct bio_vec, nolb); if (!bvec) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; diff --git a/drivers/target/target_core_hba.c b/drivers/target/target_core_hba.c index d508b343ba7b..61c54b489b7f 100644 --- a/drivers/target/target_core_hba.c +++ b/drivers/target/target_core_hba.c @@ -39,7 +39,7 @@ int transport_backend_register(const struct target_backend_ops *ops) { struct target_backend *tb, *old; - tb = kzalloc(sizeof(*tb), GFP_KERNEL); + tb = kzalloc_obj(*tb); if (!tb) return -ENOMEM; tb->ops = ops; @@ -111,7 +111,7 @@ core_alloc_hba(const char *plugin_name, u32 plugin_dep_id, u32 hba_flags) struct se_hba *hba; int ret = 0; - hba = kzalloc(sizeof(*hba), GFP_KERNEL); + hba = kzalloc_obj(*hba); if (!hba) { pr_err("Unable to allocate struct se_hba\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 8ec7b534ad76..3c92f94497b4 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c @@ -59,15 +59,14 @@ static struct se_device *iblock_alloc_device(struct se_hba *hba, const char *nam { struct iblock_dev *ib_dev = NULL; - ib_dev = kzalloc(sizeof(struct iblock_dev), GFP_KERNEL); + ib_dev = kzalloc_obj(struct iblock_dev); if (!ib_dev) { pr_err("Unable to allocate struct iblock_dev\n"); return NULL; } ib_dev->ibd_exclusive = true; - ib_dev->ibd_plug = kcalloc(nr_cpu_ids, sizeof(*ib_dev->ibd_plug), - GFP_KERNEL); + ib_dev->ibd_plug = kzalloc_objs(*ib_dev->ibd_plug, nr_cpu_ids); if (!ib_dev->ibd_plug) goto free_dev; @@ -523,7 +522,7 @@ iblock_execute_write_same(struct se_cmd *cmd) return 0; } - ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); + ibr = kzalloc_obj(struct iblock_req); if (!ibr) goto fail; cmd->priv = ibr; @@ -783,7 +782,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, miter_dir = SG_MITER_FROM_SG; } - ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL); + ibr = kzalloc_obj(struct iblock_req); if (!ibr) goto fail; cmd->priv = ibr; diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 83e172c92238..f88e63aefcd8 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c @@ -1490,7 +1490,7 @@ core_scsi3_decode_spec_i_port( * local_node_acl pointer and add to struct list_head tid_dest_list * for add registration processing in the loop of tid_dest_list below. */ - tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), GFP_KERNEL); + tidh_new = kzalloc_obj(struct pr_transport_id_holder); if (!tidh_new) { pr_err("Unable to allocate tidh_new\n"); return TCM_INSUFFICIENT_REGISTRATION_RESOURCES; @@ -1712,8 +1712,7 @@ core_scsi3_decode_spec_i_port( * the dest_node_acl and dest_se_deve pointers for the * loop below. */ - tidh_new = kzalloc(sizeof(struct pr_transport_id_holder), - GFP_KERNEL); + tidh_new = kzalloc_obj(struct pr_transport_id_holder); if (!tidh_new) { pr_err("Unable to allocate tidh_new\n"); core_scsi3_lunacl_undepend_item(dest_se_deve); diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 823b2665f95b..9ed2818c3028 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -51,7 +51,7 @@ static int pscsi_attach_hba(struct se_hba *hba, u32 host_id) { struct pscsi_hba_virt *phv; - phv = kzalloc(sizeof(struct pscsi_hba_virt), GFP_KERNEL); + phv = kzalloc_obj(struct pscsi_hba_virt); if (!phv) { pr_err("Unable to allocate struct pscsi_hba_virt\n"); return -ENOMEM; @@ -247,7 +247,7 @@ pscsi_get_inquiry_vpd_device_ident(struct scsi_device *sdev, } pr_debug("T10 VPD Identifier Length: %d\n", ident_len); - vpd = kzalloc(sizeof(struct t10_vpd), GFP_KERNEL); + vpd = kzalloc_obj(struct t10_vpd); if (!vpd) { pr_err("Unable to allocate memory for" " struct t10_vpd\n"); @@ -334,7 +334,7 @@ static struct se_device *pscsi_alloc_device(struct se_hba *hba, { struct pscsi_dev_virt *pdv; - pdv = kzalloc(sizeof(struct pscsi_dev_virt), GFP_KERNEL); + pdv = kzalloc_obj(struct pscsi_dev_virt); if (!pdv) { pr_err("Unable to allocate memory for struct pscsi_dev_virt\n"); return NULL; diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c index 6f67cc09c2b5..092d9fe0d4e3 100644 --- a/drivers/target/target_core_rd.c +++ b/drivers/target/target_core_rd.c @@ -34,7 +34,7 @@ static int rd_attach_hba(struct se_hba *hba, u32 host_id) { struct rd_host *rd_host; - rd_host = kzalloc(sizeof(*rd_host), GFP_KERNEL); + rd_host = kzalloc_obj(*rd_host); if (!rd_host) return -ENOMEM; @@ -131,8 +131,7 @@ static int rd_allocate_sgl_table(struct rd_dev *rd_dev, struct rd_dev_sg_table * if (sg_per_table < total_sg_needed) chain_entry = 1; - sg = kmalloc_array(sg_per_table + chain_entry, sizeof(*sg), - GFP_KERNEL); + sg = kmalloc_objs(*sg, sg_per_table + chain_entry); if (!sg) return -ENOMEM; @@ -192,7 +191,7 @@ static int rd_build_device_space(struct rd_dev *rd_dev) total_sg_needed = rd_dev->rd_page_count; sg_tables = (total_sg_needed / max_sg_per_table) + 1; - sg_table = kcalloc(sg_tables, sizeof(*sg_table), GFP_KERNEL); + sg_table = kzalloc_objs(*sg_table, sg_tables); if (!sg_table) return -ENOMEM; @@ -249,7 +248,7 @@ static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length, int block total_sg_needed = (rd_dev->rd_page_count * prot_length / block_size) + 1; sg_tables = (total_sg_needed / max_sg_per_table) + 1; - sg_table = kcalloc(sg_tables, sizeof(*sg_table), GFP_KERNEL); + sg_table = kzalloc_objs(*sg_table, sg_tables); if (!sg_table) return -ENOMEM; @@ -272,7 +271,7 @@ static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name) struct rd_dev *rd_dev; struct rd_host *rd_host = hba->hba_ptr; - rd_dev = kzalloc(sizeof(*rd_dev), GFP_KERNEL); + rd_dev = kzalloc_obj(*rd_dev); if (!rd_dev) return NULL; diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c index 4718db628222..db7388e207b2 100644 --- a/drivers/target/target_core_tmr.c +++ b/drivers/target/target_core_tmr.c @@ -31,7 +31,7 @@ int core_tmr_alloc_req( { struct se_tmr_req *tmr; - tmr = kzalloc(sizeof(struct se_tmr_req), gfp_flags); + tmr = kzalloc_obj(struct se_tmr_req, gfp_flags); if (!tmr) { pr_err("Unable to allocate struct se_tmr_req\n"); return -ENOMEM; diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 8b5ad50baa43..ccff9f6e4826 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -610,7 +610,7 @@ struct se_lun *core_tpg_alloc_lun( { struct se_lun *lun; - lun = kzalloc(sizeof(*lun), GFP_KERNEL); + lun = kzalloc_obj(*lun); if (!lun) { pr_err("Unable to allocate se_lun memory\n"); return ERR_PTR(-ENOMEM); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 50d21888a0c9..a7330c4fedde 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -233,7 +233,7 @@ struct target_cmd_counter *target_alloc_cmd_counter(void) struct target_cmd_counter *cmd_cnt; int rc; - cmd_cnt = kzalloc(sizeof(*cmd_cnt), GFP_KERNEL); + cmd_cnt = kzalloc_obj(*cmd_cnt); if (!cmd_cnt) return NULL; @@ -2740,7 +2740,7 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) return kmap(sg_page(sg)) + sg->offset; /* >1 page. use vmap */ - pages = kmalloc_array(cmd->t_data_nents, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, cmd->t_data_nents); if (!pages) return NULL; diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 3fd963612775..af95531ddd35 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -1293,7 +1293,7 @@ tcmu_tmr_notify(struct se_device *se_dev, enum tcm_tmreq_table tmf, pr_debug("TMR event %d on dev %s, aborted cmds %d, afflicted cmd_ids %d\n", tcmu_tmr_type(tmf), udev->name, i, cmd_cnt); - tmr = kmalloc(struct_size(tmr, tmr_cmd_ids, cmd_cnt), GFP_NOIO); + tmr = kmalloc_flex(*tmr, tmr_cmd_ids, cmd_cnt, GFP_NOIO); if (!tmr) goto unlock; @@ -1582,7 +1582,7 @@ static int tcmu_attach_hba(struct se_hba *hba, u32 host_id) { struct tcmu_hba *tcmu_hba; - tcmu_hba = kzalloc(sizeof(struct tcmu_hba), GFP_KERNEL); + tcmu_hba = kzalloc_obj(struct tcmu_hba); if (!tcmu_hba) return -ENOMEM; @@ -1602,7 +1602,7 @@ static struct se_device *tcmu_alloc_device(struct se_hba *hba, const char *name) { struct tcmu_dev *udev; - udev = kzalloc(sizeof(struct tcmu_dev), GFP_KERNEL); + udev = kzalloc_obj(struct tcmu_dev); if (!udev) return NULL; kref_init(&udev->kref); diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c index 93534a6e14b7..9e5e94f3aa5d 100644 --- a/drivers/target/target_core_xcopy.c +++ b/drivers/target/target_core_xcopy.c @@ -898,7 +898,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd) return TCM_PARAMETER_LIST_LENGTH_ERROR; } - xop = kzalloc(sizeof(struct xcopy_op), GFP_KERNEL); + xop = kzalloc_obj(struct xcopy_op); if (!xop) goto err; xop->xop_se_cmd = se_cmd; diff --git a/drivers/target/tcm_fc/tfc_conf.c b/drivers/target/tcm_fc/tfc_conf.c index a29b20b5f78e..88cf1e5a5810 100644 --- a/drivers/target/tcm_fc/tfc_conf.c +++ b/drivers/target/tcm_fc/tfc_conf.c @@ -244,7 +244,7 @@ static struct se_portal_group *ft_add_tpg(struct se_wwn *wwn, const char *name) } ft_wwn = container_of(wwn, struct ft_lport_wwn, se_wwn); - tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); + tpg = kzalloc_obj(*tpg); if (!tpg) return NULL; tpg->index = index; @@ -334,7 +334,7 @@ static struct se_wwn *ft_add_wwn( pr_debug("add wwn %s\n", name); if (ft_parse_wwn(name, &wwpn, 1) < 0) return NULL; - ft_wwn = kzalloc(sizeof(*ft_wwn), GFP_KERNEL); + ft_wwn = kzalloc_obj(*ft_wwn); if (!ft_wwn) return NULL; ft_wwn->wwpn = wwpn; diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c index d6afaba52ea5..797be06ab71b 100644 --- a/drivers/target/tcm_fc/tfc_sess.c +++ b/drivers/target/tcm_fc/tfc_sess.c @@ -59,7 +59,7 @@ static struct ft_tport *ft_tport_get(struct fc_lport *lport) return tport; } - tport = kzalloc(sizeof(*tport), GFP_KERNEL); + tport = kzalloc_obj(*tport); if (!tport) return NULL; @@ -219,7 +219,7 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id, if (sess->port_id == port_id) return sess; - sess = kzalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc_obj(*sess); if (!sess) return ERR_PTR(-ENOMEM); diff --git a/drivers/target/tcm_remote/tcm_remote.c b/drivers/target/tcm_remote/tcm_remote.c index cb8db2558056..03b00f6eca58 100644 --- a/drivers/target/tcm_remote/tcm_remote.c +++ b/drivers/target/tcm_remote/tcm_remote.c @@ -156,7 +156,7 @@ static struct se_wwn *tcm_remote_make_wwn( char *ptr; int ret, off = 0; - remote_hba = kzalloc(sizeof(*remote_hba), GFP_KERNEL); + remote_hba = kzalloc_obj(*remote_hba); if (!remote_hba) return ERR_PTR(-ENOMEM); diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index 0629f277f7b4..ebc835cf1b2b 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c @@ -82,7 +82,7 @@ static void __init tc_bus_add_devices(struct tc_bus *tbus) goto out_err; /* Found a board, allocate it an entry in the list */ - tdev = kzalloc(sizeof(*tdev), GFP_KERNEL); + tdev = kzalloc_obj(*tdev); if (!tdev) { pr_err("tc%x: unable to allocate tc_dev\n", slot); goto out_err; diff --git a/drivers/tee/amdtee/call.c b/drivers/tee/amdtee/call.c index 460b0c9e511f..441b2ceaafc3 100644 --- a/drivers/tee/amdtee/call.c +++ b/drivers/tee/amdtee/call.c @@ -134,7 +134,7 @@ static u32 get_ta_refcount(u32 ta_handle) if (ta_data->ta_handle == ta_handle) return ++ta_data->refcount; - ta_data = kzalloc(sizeof(*ta_data), GFP_KERNEL); + ta_data = kzalloc_obj(*ta_data); if (ta_data) { ta_data->ta_handle = ta_handle; ta_data->refcount = 1; @@ -293,7 +293,7 @@ int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id) if (!count || !start || !buf_id) return -EINVAL; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; diff --git a/drivers/tee/amdtee/core.c b/drivers/tee/amdtee/core.c index fb39d9a19c69..a1347d04b3ac 100644 --- a/drivers/tee/amdtee/core.c +++ b/drivers/tee/amdtee/core.c @@ -38,7 +38,7 @@ static int amdtee_open(struct tee_context *ctx) { struct amdtee_context_data *ctxdata; - ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); + ctxdata = kzalloc_obj(*ctxdata); if (!ctxdata) return -ENOMEM; @@ -122,7 +122,7 @@ static struct amdtee_session *alloc_session(struct amdtee_context_data *ctxdata, } /* Allocate a new session and add to list */ - sess = kzalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc_obj(*sess); if (sess) { sess->ta_handle = ta_handle; kref_init(&sess->refcount); @@ -351,7 +351,7 @@ int amdtee_map_shmem(struct tee_shm *shm) if (!shm) return -EINVAL; - shmnode = kmalloc(sizeof(*shmnode), GFP_KERNEL); + shmnode = kmalloc_obj(*shmnode); if (!shmnode) return -ENOMEM; @@ -465,11 +465,11 @@ static int __init amdtee_driver_init(void) return rc; } - drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); + drv_data = kzalloc_obj(*drv_data); if (!drv_data) return -ENOMEM; - amdtee = kzalloc(sizeof(*amdtee), GFP_KERNEL); + amdtee = kzalloc_obj(*amdtee); if (!amdtee) { rc = -ENOMEM; goto err_kfree_drv_data; diff --git a/drivers/tee/amdtee/shm_pool.c b/drivers/tee/amdtee/shm_pool.c index 6346e0bc8a64..c330e8e9168a 100644 --- a/drivers/tee/amdtee/shm_pool.c +++ b/drivers/tee/amdtee/shm_pool.c @@ -59,7 +59,7 @@ static const struct tee_shm_pool_ops pool_ops = { struct tee_shm_pool *amdtee_config_shm(void) { - struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); + struct tee_shm_pool *pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/tee/optee/call.c b/drivers/tee/optee/call.c index 16eb953e14bb..9effe88049e9 100644 --- a/drivers/tee/optee/call.c +++ b/drivers/tee/optee/call.c @@ -293,7 +293,7 @@ struct optee_msg_arg *optee_get_msg_arg(struct tee_context *ctx, /* * No entry was found, let's allocate a new. */ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { res = ERR_PTR(-ENOMEM); goto out; @@ -404,7 +404,7 @@ int optee_open_session(struct tee_context *ctx, if (rc) goto out; - sess = kzalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc_obj(*sess); if (!sess) { rc = -ENOMEM; goto out; diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c index 2d807bc748bc..a52c1f498b99 100644 --- a/drivers/tee/optee/core.c +++ b/drivers/tee/optee/core.c @@ -125,7 +125,7 @@ int optee_open(struct tee_context *ctx, bool cap_memref_null) struct tee_device *teedev = ctx->teedev; struct optee *optee = tee_get_drvdata(teedev); - ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); + ctxdata = kzalloc_obj(*ctxdata); if (!ctxdata) return -ENOMEM; diff --git a/drivers/tee/optee/device.c b/drivers/tee/optee/device.c index 950b4661d5df..bae954e79fdc 100644 --- a/drivers/tee/optee/device.c +++ b/drivers/tee/optee/device.c @@ -81,7 +81,7 @@ static int optee_register_device(const uuid_t *device_uuid, u32 func) struct tee_client_device *optee_device = NULL; int rc; - optee_device = kzalloc(sizeof(*optee_device), GFP_KERNEL); + optee_device = kzalloc_obj(*optee_device); if (!optee_device) return -ENOMEM; diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index 8fc72aa95722..b4372fa268d0 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -78,7 +78,7 @@ static int optee_shm_add_ffa_handle(struct optee *optee, struct tee_shm *shm, struct shm_rhash *r; int rc; - r = kmalloc(sizeof(*r), GFP_KERNEL); + r = kmalloc_obj(*r); if (!r) return -ENOMEM; r->shm = shm; @@ -404,7 +404,7 @@ static const struct tee_shm_pool_ops pool_ffa_ops = { */ static struct tee_shm_pool *optee_ffa_shm_pool_alloc_pages(void) { - struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); + struct tee_shm_pool *pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); @@ -697,7 +697,7 @@ static int optee_ffa_lend_protmem(struct optee *optee, struct tee_shm *protmem, unsigned int n; int rc; - mem_attr = kcalloc(ma_count, sizeof(*mem_attr), GFP_KERNEL); + mem_attr = kzalloc_objs(*mem_attr, ma_count); for (n = 0; n < ma_count; n++) { mem_attr[n].receiver = mem_attrs[n] & U16_MAX; mem_attr[n].attrs = mem_attrs[n] >> 16; @@ -1077,7 +1077,7 @@ static int optee_ffa_probe(struct ffa_device *ffa_dev) if (sec_caps & OPTEE_FFA_SEC_CAP_ARG_OFFSET) arg_cache_flags |= OPTEE_SHM_ARG_SHARED; - optee = kzalloc(sizeof(*optee), GFP_KERNEL); + optee = kzalloc_obj(*optee); if (!optee) return -ENOMEM; diff --git a/drivers/tee/optee/notif.c b/drivers/tee/optee/notif.c index 1970880c796f..6e85f2f5c516 100644 --- a/drivers/tee/optee/notif.c +++ b/drivers/tee/optee/notif.c @@ -38,7 +38,7 @@ int optee_notif_wait(struct optee *optee, u_int key, u32 timeout) if (key > optee->notif.max_key) return -EINVAL; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; init_completion(&entry->c); diff --git a/drivers/tee/optee/protmem.c b/drivers/tee/optee/protmem.c index 2eba48d5ac73..be3abf6e8aa6 100644 --- a/drivers/tee/optee/protmem.c +++ b/drivers/tee/optee/protmem.c @@ -294,7 +294,7 @@ struct tee_protmem_pool *optee_protmem_alloc_dyn_pool(struct optee *optee, u_int pa_width; int rc; - rp = kzalloc(sizeof(*rp), GFP_KERNEL); + rp = kzalloc_obj(*rp); if (!rp) return ERR_PTR(-ENOMEM); rp->use_case = id; diff --git a/drivers/tee/optee/rpc.c b/drivers/tee/optee/rpc.c index 1758eb7e6e8b..b0ed4cb49452 100644 --- a/drivers/tee/optee/rpc.c +++ b/drivers/tee/optee/rpc.c @@ -55,8 +55,7 @@ static void handle_rpc_func_cmd_i2c_transfer(struct tee_context *ctx, return; } - params = kmalloc_array(arg->num_params, sizeof(struct tee_param), - GFP_KERNEL); + params = kmalloc_objs(struct tee_param, arg->num_params); if (!params) { arg->ret = TEEC_ERROR_OUT_OF_MEMORY; return; @@ -192,8 +191,7 @@ static void handle_rpc_supp_cmd(struct tee_context *ctx, struct optee *optee, arg->ret_origin = TEEC_ORIGIN_COMMS; - params = kmalloc_array(arg->num_params, sizeof(struct tee_param), - GFP_KERNEL); + params = kmalloc_objs(struct tee_param, arg->num_params); if (!params) { arg->ret = TEEC_ERROR_OUT_OF_MEMORY; return; diff --git a/drivers/tee/optee/smc_abi.c b/drivers/tee/optee/smc_abi.c index 51fae1ab8ef8..b8a2bdac3208 100644 --- a/drivers/tee/optee/smc_abi.c +++ b/drivers/tee/optee/smc_abi.c @@ -626,7 +626,7 @@ static const struct tee_shm_pool_ops pool_ops = { */ static struct tee_shm_pool *optee_shm_pool_alloc_pages(void) { - struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); + struct tee_shm_pool *pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); @@ -1816,7 +1816,7 @@ static int optee_probe(struct platform_device *pdev) if (IS_ERR(pool)) return PTR_ERR(pool); - optee = kzalloc(sizeof(*optee), GFP_KERNEL); + optee = kzalloc_obj(*optee); if (!optee) { rc = -ENOMEM; goto err_free_shm_pool; diff --git a/drivers/tee/optee/supp.c b/drivers/tee/optee/supp.c index d0f397c90242..a3d11b1f90fa 100644 --- a/drivers/tee/optee/supp.c +++ b/drivers/tee/optee/supp.c @@ -89,7 +89,7 @@ u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, if (!supp->ctx && ctx->supp_nowait) return TEEC_ERROR_COMMUNICATION; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return TEEC_ERROR_OUT_OF_MEMORY; diff --git a/drivers/tee/qcomtee/call.c b/drivers/tee/qcomtee/call.c index 8f8830f0df26..0efc5646242a 100644 --- a/drivers/tee/qcomtee/call.c +++ b/drivers/tee/qcomtee/call.c @@ -416,8 +416,8 @@ static int qcomtee_object_invoke(struct tee_context *ctx, return -ENOMEM; /* +1 for ending QCOMTEE_ARG_TYPE_INV. */ - struct qcomtee_arg *u __free(kfree) = kcalloc(arg->num_params + 1, sizeof(*u), - GFP_KERNEL); + struct qcomtee_arg *u __free(kfree) = kzalloc_objs(*u, + arg->num_params + 1); if (!u) return -ENOMEM; @@ -562,8 +562,7 @@ static int qcomtee_supp_send(struct tee_context *ctx, u32 errno, u32 num_params, static int qcomtee_open(struct tee_context *ctx) { - struct qcomtee_context_data *ctxdata __free(kfree) = kzalloc(sizeof(*ctxdata), - GFP_KERNEL); + struct qcomtee_context_data *ctxdata __free(kfree) = kzalloc_obj(*ctxdata); if (!ctxdata) return -ENOMEM; @@ -706,7 +705,7 @@ static int qcomtee_probe(struct platform_device *pdev) struct qcomtee *qcomtee; int err; - qcomtee = kzalloc(sizeof(*qcomtee), GFP_KERNEL); + qcomtee = kzalloc_obj(*qcomtee); if (!qcomtee) return -ENOMEM; diff --git a/drivers/tee/qcomtee/core.c b/drivers/tee/qcomtee/core.c index ecd04403591c..b1cb50e434f0 100644 --- a/drivers/tee/qcomtee/core.c +++ b/drivers/tee/qcomtee/core.c @@ -54,7 +54,7 @@ qcomtee_qtee_object_alloc(struct qcomtee_object_invoke_ctx *oic, struct qcomtee *qcomtee = tee_get_drvdata(oic->ctx->teedev); struct qcomtee_object *object; - object = kzalloc(sizeof(*object), GFP_KERNEL); + object = kzalloc_obj(*object); if (!object) return NULL_QCOMTEE_OBJECT; diff --git a/drivers/tee/qcomtee/mem_obj.c b/drivers/tee/qcomtee/mem_obj.c index a16f8fc39b8d..ebba200ddf44 100644 --- a/drivers/tee/qcomtee/mem_obj.c +++ b/drivers/tee/qcomtee/mem_obj.c @@ -91,8 +91,7 @@ int qcomtee_memobj_param_to_object(struct qcomtee_object **object, struct tee_shm *shm; int err; - struct qcomtee_mem_object *mem_object __free(kfree) = kzalloc(sizeof(*mem_object), - GFP_KERNEL); + struct qcomtee_mem_object *mem_object __free(kfree) = kzalloc_obj(*mem_object); if (!mem_object) return -ENOMEM; diff --git a/drivers/tee/qcomtee/qcomtee_object.h b/drivers/tee/qcomtee/qcomtee_object.h index 5221449be7db..8b4401ecad48 100644 --- a/drivers/tee/qcomtee/qcomtee_object.h +++ b/drivers/tee/qcomtee/qcomtee_object.h @@ -176,7 +176,7 @@ qcomtee_object_invoke_ctx_alloc(struct tee_context *ctx) { struct qcomtee_object_invoke_ctx *oic; - oic = kzalloc(sizeof(*oic), GFP_KERNEL); + oic = kzalloc_obj(*oic); if (oic) oic->ctx = ctx; return oic; diff --git a/drivers/tee/qcomtee/shm.c b/drivers/tee/qcomtee/shm.c index 580bd25f98ed..b67909ef3f46 100644 --- a/drivers/tee/qcomtee/shm.c +++ b/drivers/tee/qcomtee/shm.c @@ -140,7 +140,7 @@ struct tee_shm_pool *qcomtee_shm_pool_alloc(void) { struct tee_shm_pool *pool; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/tee/qcomtee/user_obj.c b/drivers/tee/qcomtee/user_obj.c index 6aa3aefd67f0..10452fcc7ccb 100644 --- a/drivers/tee/qcomtee/user_obj.c +++ b/drivers/tee/qcomtee/user_obj.c @@ -326,7 +326,7 @@ static void qcomtee_user_object_release(struct qcomtee_object *object) if (!uo->notify) goto out_no_notify; - ureq = kzalloc(sizeof(*ureq), GFP_KERNEL); + ureq = kzalloc_obj(*ureq); if (!ureq) goto out_no_notify; @@ -370,7 +370,7 @@ int qcomtee_user_param_to_object(struct qcomtee_object **object, int err; struct qcomtee_user_object *user_object __free(kfree) = - kzalloc(sizeof(*user_object), GFP_KERNEL); + kzalloc_obj(*user_object); if (!user_object) return -ENOMEM; diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c index 6c49e2e383c6..ef9642d72672 100644 --- a/drivers/tee/tee_core.c +++ b/drivers/tee/tee_core.c @@ -51,7 +51,7 @@ struct tee_context *teedev_open(struct tee_device *teedev) if (!tee_device_get(teedev)) return ERR_PTR(-EINVAL); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto err; @@ -560,8 +560,7 @@ static int tee_ioctl_open_session(struct tee_context *ctx, return -EINVAL; if (arg.num_params) { - params = kcalloc(arg.num_params, sizeof(struct tee_param), - GFP_KERNEL); + params = kzalloc_objs(struct tee_param, arg.num_params); if (!params) return -ENOMEM; uparams = uarg->params; @@ -638,8 +637,7 @@ static int tee_ioctl_invoke(struct tee_context *ctx, return -EINVAL; if (arg.num_params) { - params = kcalloc(arg.num_params, sizeof(struct tee_param), - GFP_KERNEL); + params = kzalloc_objs(struct tee_param, arg.num_params); if (!params) return -ENOMEM; uparams = uarg->params; @@ -699,8 +697,7 @@ static int tee_ioctl_object_invoke(struct tee_context *ctx, return -EINVAL; if (arg.num_params) { - params = kcalloc(arg.num_params, sizeof(struct tee_param), - GFP_KERNEL); + params = kzalloc_objs(struct tee_param, arg.num_params); if (!params) return -ENOMEM; uparams = uarg->params; @@ -844,7 +841,7 @@ static int tee_ioctl_supp_recv(struct tee_context *ctx, if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) != buf.buf_len) return -EINVAL; - params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL); + params = kzalloc_objs(struct tee_param, num_params); if (!params) return -ENOMEM; @@ -958,7 +955,7 @@ static int tee_ioctl_supp_send(struct tee_context *ctx, if (size_add(sizeof(*uarg), TEE_IOCTL_PARAM_SIZE(num_params)) > buf.buf_len) return -EINVAL; - params = kcalloc(num_params, sizeof(struct tee_param), GFP_KERNEL); + params = kzalloc_objs(struct tee_param, num_params); if (!params) return -ENOMEM; @@ -1052,7 +1049,7 @@ struct tee_device *tee_device_alloc(const struct tee_desc *teedesc, !teedesc->ops->release) return ERR_PTR(-EINVAL); - teedev = kzalloc(sizeof(*teedev), GFP_KERNEL); + teedev = kzalloc_obj(*teedev); if (!teedev) { ret = ERR_PTR(-ENOMEM); goto err; diff --git a/drivers/tee/tee_heap.c b/drivers/tee/tee_heap.c index d8d7735cdffb..007c00156520 100644 --- a/drivers/tee/tee_heap.c +++ b/drivers/tee/tee_heap.c @@ -94,7 +94,7 @@ static int tee_heap_attach(struct dma_buf *dmabuf, struct tee_heap_attachment *a; int ret; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return -ENOMEM; @@ -188,7 +188,7 @@ static struct dma_buf *tee_dma_heap_alloc(struct dma_heap *heap, if (!teedev) return ERR_PTR(-EINVAL); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) { dmabuf = ERR_PTR(-ENOMEM); goto err; @@ -260,7 +260,7 @@ static int alloc_dma_heap(struct tee_device *teedev, enum tee_dma_heap_id id, return -ENOMEM; } - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return -ENOMEM; h->id = id; @@ -472,7 +472,7 @@ struct tee_protmem_pool *tee_protmem_static_pool_alloc(phys_addr_t paddr, if (!pfn_valid(PHYS_PFN(paddr))) return ERR_PTR(-EINVAL); - stp = kzalloc(sizeof(*stp), GFP_KERNEL); + stp = kzalloc_obj(*stp); if (!stp) return ERR_PTR(-ENOMEM); diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 4a47de4bb2e5..6c5b9e352e5e 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -106,7 +106,7 @@ static struct tee_shm *shm_alloc_helper(struct tee_context *ctx, size_t size, goto err_dev_put; } - shm = kzalloc(sizeof(*shm), GFP_KERNEL); + shm = kzalloc_obj(*shm); if (!shm) { ret = ERR_PTR(-ENOMEM); goto err_dev_put; @@ -214,7 +214,7 @@ struct tee_shm *tee_shm_register_fd(struct tee_context *ctx, int fd) teedev_ctx_get(ctx); - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) { rc = -ENOMEM; goto err_put_tee; @@ -315,7 +315,7 @@ struct tee_shm *tee_shm_alloc_dma_mem(struct tee_context *ctx, if (!page) goto err_put_teedev; - dma_mem = kzalloc(sizeof(*dma_mem), GFP_KERNEL); + dma_mem = kzalloc_obj(*dma_mem); if (!dma_mem) goto err_free_pages; @@ -373,7 +373,7 @@ int tee_dyn_shm_alloc_helper(struct tee_shm *shm, size_t size, size_t align, shm->paddr = virt_to_phys(shm->kaddr); shm->size = nr_pages * PAGE_SIZE; - pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, nr_pages); if (!pages) { rc = -ENOMEM; goto err_pages; @@ -438,7 +438,7 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags, teedev_ctx_get(ctx); - shm = kzalloc(sizeof(*shm), GFP_KERNEL); + shm = kzalloc_obj(*shm); if (!shm) { ret = ERR_PTR(-ENOMEM); goto err_ctx_put; @@ -456,7 +456,7 @@ register_shm_helper(struct tee_context *ctx, struct iov_iter *iter, u32 flags, goto err_ctx_put; } - shm->pages = kcalloc(num_pages, sizeof(*shm->pages), GFP_KERNEL); + shm->pages = kzalloc_objs(*shm->pages, num_pages); if (!shm->pages) { ret = ERR_PTR(-ENOMEM); goto err_free_shm; diff --git a/drivers/tee/tee_shm_pool.c b/drivers/tee/tee_shm_pool.c index 80004b55628d..1a2a7f47e30f 100644 --- a/drivers/tee/tee_shm_pool.c +++ b/drivers/tee/tee_shm_pool.c @@ -65,7 +65,7 @@ struct tee_shm_pool *tee_shm_pool_alloc_res_mem(unsigned long vaddr, if (vaddr & page_mask || paddr & page_mask || size & page_mask) return ERR_PTR(-EINVAL); - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/drivers/tee/tstee/core.c b/drivers/tee/tstee/core.c index 533425e9e9e7..79ae5d161638 100644 --- a/drivers/tee/tstee/core.c +++ b/drivers/tee/tstee/core.c @@ -59,7 +59,7 @@ static int tstee_open(struct tee_context *ctx) { struct ts_context_data *ctxdata; - ctxdata = kzalloc(sizeof(*ctxdata), GFP_KERNEL); + ctxdata = kzalloc_obj(*ctxdata); if (!ctxdata) return -ENOMEM; @@ -122,7 +122,7 @@ static int tstee_open_session(struct tee_context *ctx, if (ffa_args[TS_RPC_SERVICE_INFO_IFACE] > U8_MAX) return -EINVAL; - sess = kzalloc(sizeof(*sess), GFP_KERNEL); + sess = kzalloc_obj(*sess); if (!sess) return -ENOMEM; @@ -376,7 +376,7 @@ static const struct tee_shm_pool_ops pool_ops = { static struct tee_shm_pool *tstee_create_shm_pool(void) { - struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL); + struct tee_shm_pool *pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); @@ -414,7 +414,7 @@ static int tstee_probe(struct ffa_device *ffa_dev) if (!tstee_check_rpc_compatible(ffa_dev)) return -EINVAL; - tstee = kzalloc(sizeof(*tstee), GFP_KERNEL); + tstee = kzalloc_obj(*tstee); if (!tstee) return -ENOMEM; diff --git a/drivers/thermal/cpufreq_cooling.c b/drivers/thermal/cpufreq_cooling.c index 6b7ab1814c12..32bf5ab44f4a 100644 --- a/drivers/thermal/cpufreq_cooling.c +++ b/drivers/thermal/cpufreq_cooling.c @@ -371,9 +371,8 @@ static int allocate_idle_time(struct cpufreq_cooling_device *cpufreq_cdev) { unsigned int num_cpus = cpumask_weight(cpufreq_cdev->policy->related_cpus); - cpufreq_cdev->idle_time = kcalloc(num_cpus, - sizeof(*cpufreq_cdev->idle_time), - GFP_KERNEL); + cpufreq_cdev->idle_time = kzalloc_objs(*cpufreq_cdev->idle_time, + num_cpus); if (!cpufreq_cdev->idle_time) return -ENOMEM; @@ -543,7 +542,7 @@ __cpufreq_cooling_register(struct device_node *np, return ERR_PTR(-ENODEV); } - cpufreq_cdev = kzalloc(sizeof(*cpufreq_cdev), GFP_KERNEL); + cpufreq_cdev = kzalloc_obj(*cpufreq_cdev); if (!cpufreq_cdev) return ERR_PTR(-ENOMEM); diff --git a/drivers/thermal/cpuidle_cooling.c b/drivers/thermal/cpuidle_cooling.c index f678c1281862..425f596614e8 100644 --- a/drivers/thermal/cpuidle_cooling.c +++ b/drivers/thermal/cpuidle_cooling.c @@ -179,7 +179,7 @@ static int __cpuidle_cooling_register(struct device_node *np, char *name; int ret; - idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); + idle_cdev = kzalloc_obj(*idle_cdev); if (!idle_cdev) { ret = -ENOMEM; goto out; diff --git a/drivers/thermal/devfreq_cooling.c b/drivers/thermal/devfreq_cooling.c index 8fd7cf1932cd..597e86d16a4e 100644 --- a/drivers/thermal/devfreq_cooling.c +++ b/drivers/thermal/devfreq_cooling.c @@ -402,7 +402,7 @@ of_devfreq_cooling_register_power(struct device_node *np, struct devfreq *df, int err, num_opps; - dfc = kzalloc(sizeof(*dfc), GFP_KERNEL); + dfc = kzalloc_obj(*dfc); if (!dfc) return ERR_PTR(-ENOMEM); diff --git a/drivers/thermal/gov_power_allocator.c b/drivers/thermal/gov_power_allocator.c index 0d9f636c80f4..37f2e22a999e 100644 --- a/drivers/thermal/gov_power_allocator.c +++ b/drivers/thermal/gov_power_allocator.c @@ -622,8 +622,7 @@ static int allocate_actors_buffer(struct power_allocator_params *params, goto clean_state; } - params->power = kcalloc(num_actors, sizeof(struct power_actor), - GFP_KERNEL); + params->power = kzalloc_objs(struct power_actor, num_actors); if (!params->power) { ret = -ENOMEM; goto clean_state; @@ -699,7 +698,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz) struct power_allocator_params *params; int ret; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -720,7 +719,7 @@ static int power_allocator_bind(struct thermal_zone_device *tz) } if (!tz->tzp) { - tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL); + tz->tzp = kzalloc_obj(*tz->tzp); if (!tz->tzp) { ret = -ENOMEM; goto free_params; diff --git a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c index ce5d53be108b..0a548fdc4a7e 100644 --- a/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c +++ b/drivers/thermal/intel/int340x_thermal/acpi_thermal_rel.c @@ -89,7 +89,7 @@ int acpi_parse_trt(acpi_handle handle, int *trt_count, struct trt **trtp, } *trt_count = p->package.count; - trts = kcalloc(*trt_count, sizeof(struct trt), GFP_KERNEL); + trts = kzalloc_objs(struct trt, *trt_count); if (!trts) { result = -ENOMEM; goto end; @@ -165,7 +165,7 @@ int acpi_parse_art(acpi_handle handle, int *art_count, struct art **artp, /* ignore p->package.elements[0], as this is _ART Revision field */ *art_count = p->package.count - 1; - arts = kcalloc(*art_count, sizeof(struct art), GFP_KERNEL); + arts = kzalloc_objs(struct art, *art_count); if (!arts) { result = -ENOMEM; goto end; @@ -253,7 +253,7 @@ static int acpi_parse_psvt(acpi_handle handle, int *psvt_count, struct psvt **ps goto end; } - psvts = kcalloc(*psvt_count, sizeof(*psvts), GFP_KERNEL); + psvts = kzalloc_objs(*psvts, *psvt_count); if (!psvts) { result = -ENOMEM; goto end; diff --git a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c index 41d3bc3ed8a2..d200734625ee 100644 --- a/drivers/thermal/intel/int340x_thermal/int3400_thermal.c +++ b/drivers/thermal/intel/int340x_thermal/int3400_thermal.c @@ -382,8 +382,7 @@ static int evaluate_odvp(struct int3400_thermal_priv *priv) if (priv->odvp == NULL) { priv->odvp_count = obj->package.count; - priv->odvp = kmalloc_array(priv->odvp_count, sizeof(int), - GFP_KERNEL); + priv->odvp = kmalloc_objs(int, priv->odvp_count); if (!priv->odvp) { ret = -ENOMEM; goto out_err; @@ -391,9 +390,8 @@ static int evaluate_odvp(struct int3400_thermal_priv *priv) } if (priv->odvp_attrs == NULL) { - priv->odvp_attrs = kcalloc(priv->odvp_count, - sizeof(struct odvp_attr), - GFP_KERNEL); + priv->odvp_attrs = kzalloc_objs(struct odvp_attr, + priv->odvp_count); if (!priv->odvp_attrs) { ret = -ENOMEM; goto out_err; @@ -563,7 +561,7 @@ static int int3400_thermal_probe(struct platform_device *pdev) if (!adev) return -ENODEV; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c index 3d9efe69d562..965700ee6962 100644 --- a/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c +++ b/drivers/thermal/intel/int340x_thermal/int340x_thermal_zone.c @@ -123,7 +123,7 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, acpi_status status; int i, ret; - int34x_zone = kzalloc(sizeof(*int34x_zone), GFP_KERNEL); + int34x_zone = kzalloc_obj(*int34x_zone); if (!int34x_zone) return ERR_PTR(-ENOMEM); @@ -133,8 +133,8 @@ struct int34x_thermal_zone *int340x_thermal_zone_add(struct acpi_device *adev, if (ACPI_SUCCESS(status)) int34x_zone->aux_trip_nr = trip_cnt; - zone_trips = kcalloc(trip_cnt + INT340X_THERMAL_MAX_TRIP_COUNT, - sizeof(*zone_trips), GFP_KERNEL); + zone_trips = kzalloc_objs(*zone_trips, + trip_cnt + INT340X_THERMAL_MAX_TRIP_COUNT); if (!zone_trips) { ret = -ENOMEM; goto err_trips_alloc; diff --git a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c index bb9398dfa3c1..314fbc1f490f 100644 --- a/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c +++ b/drivers/thermal/intel/int340x_thermal/processor_thermal_rfim.c @@ -467,8 +467,11 @@ int proc_thermal_rfim_add(struct pci_dev *pdev, struct proc_thermal_device *proc break; } ret = sysfs_create_group(&pdev->dev.kobj, &dlvr_attribute_group); - if (ret) + if (ret) { + if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_FIVR) + sysfs_remove_group(&pdev->dev.kobj, &fivr_attribute_group); return ret; + } } if (proc_priv->mmio_feature_mask & PROC_THERMAL_FEATURE_DVFS) { diff --git a/drivers/thermal/intel/intel_hfi.c b/drivers/thermal/intel/intel_hfi.c index 8a2f441cd2ec..1a1a95b39405 100644 --- a/drivers/thermal/intel/intel_hfi.c +++ b/drivers/thermal/intel/intel_hfi.c @@ -212,7 +212,7 @@ static void update_capabilities(struct hfi_instance *hfi_instance) if (!cpu_count) goto out; - cpu_caps = kcalloc(cpu_count, sizeof(*cpu_caps), GFP_KERNEL); + cpu_caps = kzalloc_objs(*cpu_caps, cpu_count); if (!cpu_caps) goto out; @@ -690,8 +690,7 @@ void __init intel_hfi_init(void) * This allocation may fail. CPU hotplug callbacks must check * for a null pointer. */ - hfi_instances = kcalloc(max_hfi_instances, sizeof(*hfi_instances), - GFP_KERNEL); + hfi_instances = kzalloc_objs(*hfi_instances, max_hfi_instances); if (!hfi_instances) return; diff --git a/drivers/thermal/intel/intel_quark_dts_thermal.c b/drivers/thermal/intel/intel_quark_dts_thermal.c index 89498eb29a89..15476699bdda 100644 --- a/drivers/thermal/intel/intel_quark_dts_thermal.c +++ b/drivers/thermal/intel/intel_quark_dts_thermal.c @@ -336,7 +336,7 @@ static struct soc_sensor_entry *alloc_soc_dts(void) int err; u32 out; - aux_entry = kzalloc(sizeof(*aux_entry), GFP_KERNEL); + aux_entry = kzalloc_obj(*aux_entry); if (!aux_entry) { err = -ENOMEM; return ERR_PTR(-ENOMEM); diff --git a/drivers/thermal/intel/intel_soc_dts_iosf.c b/drivers/thermal/intel/intel_soc_dts_iosf.c index ea87439fe7a9..93773878398e 100644 --- a/drivers/thermal/intel/intel_soc_dts_iosf.c +++ b/drivers/thermal/intel/intel_soc_dts_iosf.c @@ -320,7 +320,7 @@ intel_soc_dts_iosf_init(enum intel_soc_dts_interrupt_type intr_type, if (tj_max < 0) return ERR_PTR(tj_max); - sensors = kzalloc(sizeof(*sensors), GFP_KERNEL); + sensors = kzalloc_obj(*sensors); if (!sensors) return ERR_PTR(-ENOMEM); diff --git a/drivers/thermal/intel/x86_pkg_temp_thermal.c b/drivers/thermal/intel/x86_pkg_temp_thermal.c index aab5f9fca9c3..540109761f0a 100644 --- a/drivers/thermal/intel/x86_pkg_temp_thermal.c +++ b/drivers/thermal/intel/x86_pkg_temp_thermal.c @@ -335,7 +335,7 @@ static int pkg_temp_thermal_device_add(unsigned int cpu) return tj_max; tj_max *= 1000; - zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL); + zonedev = kzalloc_obj(*zonedev); if (!zonedev) return -ENOMEM; @@ -492,8 +492,7 @@ static int __init pkg_temp_thermal_init(void) return -ENODEV; max_id = topology_max_packages() * topology_max_dies_per_package(); - zones = kcalloc(max_id, sizeof(struct zone_device *), - GFP_KERNEL); + zones = kzalloc_objs(struct zone_device *, max_id); if (!zones) return -ENOMEM; diff --git a/drivers/thermal/k3_j72xx_bandgap.c b/drivers/thermal/k3_j72xx_bandgap.c index d9ec3bf19496..6aba00d8b8fd 100644 --- a/drivers/thermal/k3_j72xx_bandgap.c +++ b/drivers/thermal/k3_j72xx_bandgap.c @@ -462,7 +462,7 @@ static int k3_j72xx_bandgap_probe(struct platform_device *pdev) goto err_alloc; } - ref_table = kcalloc(TABLE_SIZE, sizeof(*ref_table), GFP_KERNEL); + ref_table = kzalloc_objs(*ref_table, TABLE_SIZE); if (!ref_table) { ret = -ENOMEM; goto err_alloc; diff --git a/drivers/thermal/testing/zone.c b/drivers/thermal/testing/zone.c index c12c405225bb..3c339242f52d 100644 --- a/drivers/thermal/testing/zone.c +++ b/drivers/thermal/testing/zone.c @@ -186,12 +186,11 @@ int tt_add_tz(void) { int ret; - struct tt_thermal_zone *tt_zone __free(kfree) = kzalloc(sizeof(*tt_zone), - GFP_KERNEL); + struct tt_thermal_zone *tt_zone __free(kfree) = kzalloc_obj(*tt_zone); if (!tt_zone) return -ENOMEM; - struct tt_work *tt_work __free(kfree) = kzalloc(sizeof(*tt_work), GFP_KERNEL); + struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work); if (!tt_work) return -ENOMEM; @@ -244,7 +243,7 @@ int tt_del_tz(const char *arg) if (ret != 1) return -EINVAL; - struct tt_work *tt_work __free(kfree) = kzalloc(sizeof(*tt_work), GFP_KERNEL); + struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work); if (!tt_work) return -ENOMEM; @@ -330,11 +329,11 @@ int tt_zone_add_trip(const char *arg) { int id; - struct tt_work *tt_work __free(kfree) = kzalloc(sizeof(*tt_work), GFP_KERNEL); + struct tt_work *tt_work __free(kfree) = kzalloc_obj(*tt_work); if (!tt_work) return -ENOMEM; - struct tt_trip *tt_trip __free(kfree) = kzalloc(sizeof(*tt_trip), GFP_KERNEL); + struct tt_trip *tt_trip __free(kfree) = kzalloc_obj(*tt_trip); if (!tt_trip) return -ENOMEM; @@ -391,8 +390,8 @@ static int tt_zone_register_tz(struct tt_thermal_zone *tt_zone) if (tt_zone->tz) return -EINVAL; - struct thermal_trip *trips __free(kfree) = kcalloc(tt_zone->num_trips, - sizeof(*trips), GFP_KERNEL); + struct thermal_trip *trips __free(kfree) = kzalloc_objs(*trips, + tt_zone->num_trips); if (!trips) return -ENOMEM; diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c index dc9f7416f7ff..b7d706ed7ed9 100644 --- a/drivers/thermal/thermal_core.c +++ b/drivers/thermal/thermal_core.c @@ -844,7 +844,7 @@ static int thermal_bind_cdev_to_trip(struct thermal_zone_device *tz, if (cool_spec->lower > cool_spec->upper || cool_spec->upper > cdev->max_state) return -EINVAL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; @@ -1070,7 +1070,7 @@ __thermal_cooling_device_register(struct device_node *np, if (!thermal_class) return ERR_PTR(-ENODEV); - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return ERR_PTR(-ENOMEM); @@ -1542,7 +1542,7 @@ thermal_zone_device_register_with_trips(const char *type, if (!thermal_class) return ERR_PTR(-ENODEV); - tz = kzalloc(struct_size(tz, trips, num_trips), GFP_KERNEL); + tz = kzalloc_flex(*tz, trips, num_trips); if (!tz) return ERR_PTR(-ENOMEM); @@ -1899,7 +1899,7 @@ static int __init thermal_init(void) if (result) goto unregister_netlink; - thermal_class = kzalloc(sizeof(*thermal_class), GFP_KERNEL); + thermal_class = kzalloc_obj(*thermal_class); if (!thermal_class) { result = -ENOMEM; goto unregister_governors; diff --git a/drivers/thermal/thermal_debugfs.c b/drivers/thermal/thermal_debugfs.c index 11668f5b3c28..da02d8f179b0 100644 --- a/drivers/thermal/thermal_debugfs.c +++ b/drivers/thermal/thermal_debugfs.c @@ -193,7 +193,7 @@ static struct thermal_debugfs *thermal_debugfs_add_id(struct dentry *d, int id) struct thermal_debugfs *thermal_dbg; char ids[IDSLENGTH]; - thermal_dbg = kzalloc(sizeof(*thermal_dbg), GFP_KERNEL); + thermal_dbg = kzalloc_obj(*thermal_dbg); if (!thermal_dbg) return NULL; @@ -226,7 +226,7 @@ thermal_debugfs_cdev_record_alloc(struct thermal_debugfs *thermal_dbg, { struct cdev_record *cdev_record; - cdev_record = kzalloc(sizeof(*cdev_record), GFP_KERNEL); + cdev_record = kzalloc_obj(*cdev_record); if (!cdev_record) return NULL; @@ -559,7 +559,7 @@ static struct tz_episode *thermal_debugfs_tz_event_alloc(struct thermal_zone_dev struct tz_episode *tze; int i; - tze = kzalloc(struct_size(tze, trip_stats, tz->num_trips), GFP_KERNEL); + tze = kzalloc_flex(*tze, trip_stats, tz->num_trips); if (!tze) return NULL; @@ -876,7 +876,7 @@ void thermal_debug_tz_add(struct thermal_zone_device *tz) tz_dbg->tz = tz; - tz_dbg->trips_crossed = kcalloc(tz->num_trips, sizeof(int), GFP_KERNEL); + tz_dbg->trips_crossed = kzalloc_objs(int, tz->num_trips); if (!tz_dbg->trips_crossed) { thermal_debugfs_remove_id(thermal_dbg); return; diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c index faf1d0083890..b624892bc6d6 100644 --- a/drivers/thermal/thermal_hwmon.c +++ b/drivers/thermal/thermal_hwmon.c @@ -145,7 +145,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) goto register_sys_interface; } - hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); + hwmon = kzalloc_obj(*hwmon); if (!hwmon) return -ENOMEM; @@ -160,7 +160,7 @@ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) } register_sys_interface: - temp = kzalloc(sizeof(*temp), GFP_KERNEL); + temp = kzalloc_obj(*temp); if (!temp) { result = -ENOMEM; goto unregister_name; diff --git a/drivers/thermal/thermal_of.c b/drivers/thermal/thermal_of.c index b6d0c92f5522..6ebb83cb70b2 100644 --- a/drivers/thermal/thermal_of.c +++ b/drivers/thermal/thermal_of.c @@ -107,7 +107,7 @@ static struct thermal_trip *thermal_of_trips_init(struct device_node *np, int *n if (!count) return NULL; - struct thermal_trip *tt __free(kfree) = kcalloc(count, sizeof(*tt), GFP_KERNEL); + struct thermal_trip *tt __free(kfree) = kzalloc_objs(*tt, count); if (!tt) return ERR_PTR(-ENOMEM); diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c index 2538c2dcf6a9..46b3b2df935c 100644 --- a/drivers/thermal/thermal_sysfs.c +++ b/drivers/thermal/thermal_sysfs.c @@ -392,7 +392,7 @@ static int create_trip_attrs(struct thermal_zone_device *tz) struct attribute **attrs; int i; - attrs = kcalloc(tz->num_trips * 3 + 1, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, tz->num_trips * 3 + 1); if (!attrs) return -ENOMEM; @@ -465,7 +465,7 @@ int thermal_zone_create_device_groups(struct thermal_zone_device *tz) /* we need one extra for trips and the NULL to terminate the array */ size = ARRAY_SIZE(thermal_zone_attribute_groups) + 2; /* This also takes care of API requirement to be NULL terminated */ - groups = kcalloc(size, sizeof(*groups), GFP_KERNEL); + groups = kzalloc_objs(*groups, size); if (!groups) return -ENOMEM; diff --git a/drivers/thermal/thermal_thresholds.c b/drivers/thermal/thermal_thresholds.c index 38f5fd0e8930..970b8fd33847 100644 --- a/drivers/thermal/thermal_thresholds.c +++ b/drivers/thermal/thermal_thresholds.c @@ -181,7 +181,7 @@ int thermal_thresholds_add(struct thermal_zone_device *tz, t->direction |= direction; } else { - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) return -ENOMEM; diff --git a/drivers/thunderbolt/ctl.c b/drivers/thunderbolt/ctl.c index d7a535671404..b2fd60fc7bcc 100644 --- a/drivers/thunderbolt/ctl.c +++ b/drivers/thunderbolt/ctl.c @@ -89,7 +89,7 @@ struct tb_cfg_request *tb_cfg_request_alloc(void) { struct tb_cfg_request *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return NULL; @@ -333,7 +333,7 @@ static void tb_ctl_pkg_free(struct ctl_pkg *pkg) static struct ctl_pkg *tb_ctl_pkg_alloc(struct tb_ctl *ctl) { - struct ctl_pkg *pkg = kzalloc(sizeof(*pkg), GFP_KERNEL); + struct ctl_pkg *pkg = kzalloc_obj(*pkg); if (!pkg) return NULL; pkg->ctl = ctl; @@ -654,7 +654,7 @@ struct tb_ctl *tb_ctl_alloc(struct tb_nhi *nhi, int index, int timeout_msec, event_cb cb, void *cb_data) { int i; - struct tb_ctl *ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + struct tb_ctl *ctl = kzalloc_obj(*ctl); if (!ctl) return NULL; diff --git a/drivers/thunderbolt/debugfs.c b/drivers/thunderbolt/debugfs.c index 45266ec72f88..042f6a0d0f7f 100644 --- a/drivers/thunderbolt/debugfs.c +++ b/drivers/thunderbolt/debugfs.c @@ -1657,7 +1657,7 @@ static struct tb_margining *margining_alloc(struct tb_port *port, return NULL; } - margining = kzalloc(sizeof(*margining), GFP_KERNEL); + margining = kzalloc_obj(*margining); if (!margining) return NULL; diff --git a/drivers/thunderbolt/dma_port.c b/drivers/thunderbolt/dma_port.c index dc8ea188a114..334fefe21255 100644 --- a/drivers/thunderbolt/dma_port.c +++ b/drivers/thunderbolt/dma_port.c @@ -209,7 +209,7 @@ struct tb_dma_port *dma_port_alloc(struct tb_switch *sw) if (port < 0) return NULL; - dma = kzalloc(sizeof(*dma), GFP_KERNEL); + dma = kzalloc_obj(*dma); if (!dma) return NULL; diff --git a/drivers/thunderbolt/dma_test.c b/drivers/thunderbolt/dma_test.c index 9e47a63f28e7..b4aa79d482a0 100644 --- a/drivers/thunderbolt/dma_test.c +++ b/drivers/thunderbolt/dma_test.c @@ -267,7 +267,7 @@ static int dma_test_submit_rx(struct dma_test *dt, size_t npackets) struct dma_test_frame *tf; dma_addr_t dma_addr; - tf = kzalloc(sizeof(*tf), GFP_KERNEL); + tf = kzalloc_obj(*tf); if (!tf) return -ENOMEM; @@ -318,7 +318,7 @@ static int dma_test_submit_tx(struct dma_test *dt, size_t npackets) struct dma_test_frame *tf; dma_addr_t dma_addr; - tf = kzalloc(sizeof(*tf), GFP_KERNEL); + tf = kzalloc_obj(*tf); if (!tf) return -ENOMEM; diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c index 3ced37b4a869..317780b99992 100644 --- a/drivers/thunderbolt/domain.c +++ b/drivers/thunderbolt/domain.c @@ -126,7 +126,7 @@ static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr, ssize_t ret; int i; - uuids = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL); + uuids = kzalloc_objs(uuid_t, tb->nboot_acl); if (!uuids) return -ENOMEM; @@ -181,7 +181,7 @@ static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr, if (!str) return -ENOMEM; - acl = kcalloc(tb->nboot_acl, sizeof(uuid_t), GFP_KERNEL); + acl = kzalloc_objs(uuid_t, tb->nboot_acl); if (!acl) { ret = -ENOMEM; goto err_free_str; diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c index d339ba835376..9d95bf3ab44c 100644 --- a/drivers/thunderbolt/icm.c +++ b/drivers/thunderbolt/icm.c @@ -427,7 +427,7 @@ static int icm_fr_get_route(struct tb *tb, u8 link, u8 depth, u64 *route) int ret, index; u8 i; - switches = kcalloc(npackets, sizeof(*switches), GFP_KERNEL); + switches = kzalloc_objs(*switches, npackets); if (!switches) return -ENOMEM; @@ -1769,7 +1769,7 @@ static void icm_handle_event(struct tb *tb, enum tb_cfg_pkg_type type, { struct icm_notification *n; - n = kmalloc(sizeof(*n), GFP_KERNEL); + n = kmalloc_obj(*n); if (!n) return; @@ -2246,7 +2246,7 @@ static int icm_usb4_switch_nvm_authenticate(struct tb *tb, u64 route) struct tb_cfg_request *req; int ret; - auth = kzalloc(sizeof(*auth), GFP_KERNEL); + auth = kzalloc_obj(*auth); if (!auth) return -ENOMEM; diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index 6d0c9d37c55d..ccce020a2432 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -587,7 +587,7 @@ static struct tb_ring *tb_ring_alloc(struct tb_nhi *nhi, u32 hop, int size, dev_dbg(&nhi->pdev->dev, "allocating %s ring %d of size %d\n", transmit ? "TX" : "RX", hop, size); - ring = kzalloc(sizeof(*ring), GFP_KERNEL); + ring = kzalloc_obj(*ring); if (!ring) return NULL; diff --git a/drivers/thunderbolt/nvm.c b/drivers/thunderbolt/nvm.c index 6901058b7ac0..3dfa70ea6570 100644 --- a/drivers/thunderbolt/nvm.c +++ b/drivers/thunderbolt/nvm.c @@ -330,7 +330,7 @@ struct tb_nvm *tb_nvm_alloc(struct device *dev) return ERR_PTR(-EOPNOTSUPP); } - nvm = kzalloc(sizeof(*nvm), GFP_KERNEL); + nvm = kzalloc_obj(*nvm); if (!nvm) return ERR_PTR(-ENOMEM); diff --git a/drivers/thunderbolt/path.c b/drivers/thunderbolt/path.c index f9b11dadfbdd..22fb4a1e1acd 100644 --- a/drivers/thunderbolt/path.c +++ b/drivers/thunderbolt/path.c @@ -150,7 +150,7 @@ struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid, num_hops++; } - path = kzalloc(sizeof(*path), GFP_KERNEL); + path = kzalloc_obj(*path); if (!path) return NULL; @@ -160,7 +160,7 @@ struct tb_path *tb_path_discover(struct tb_port *src, int src_hopid, path->activated = true; path->alloc_hopid = alloc_hopid; - path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL); + path->hops = kzalloc_objs(*path->hops, num_hops); if (!path->hops) { kfree(path); return NULL; @@ -245,7 +245,7 @@ struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid, size_t num_hops; int i, ret; - path = kzalloc(sizeof(*path), GFP_KERNEL); + path = kzalloc_obj(*path); if (!path) return NULL; @@ -267,7 +267,7 @@ struct tb_path *tb_path_alloc(struct tb *tb, struct tb_port *src, int src_hopid, /* Each hop takes two ports */ num_hops = i / 2; - path->hops = kcalloc(num_hops, sizeof(*path->hops), GFP_KERNEL); + path->hops = kzalloc_objs(*path->hops, num_hops); if (!path->hops) { kfree(path); return NULL; @@ -586,7 +586,7 @@ int tb_path_activate(struct tb_path *path) tb_dbg(path->tb, "%s path activation complete\n", path->name); return 0; err: - tb_WARN(path->tb, "%s path activation failed\n", path->name); + tb_warn(path->tb, "%s path activation failed: %d\n", path->name, res); return res; } diff --git a/drivers/thunderbolt/property.c b/drivers/thunderbolt/property.c index 31aa0516932a..50cbfc92fe65 100644 --- a/drivers/thunderbolt/property.c +++ b/drivers/thunderbolt/property.c @@ -81,7 +81,7 @@ tb_property_alloc(const char *key, enum tb_property_type type) { struct tb_property *property; - property = kzalloc(sizeof(*property), GFP_KERNEL); + property = kzalloc_obj(*property); if (!property) return NULL; @@ -166,7 +166,7 @@ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block, unsigned int content_offset; struct tb_property_dir *dir; - dir = kzalloc(sizeof(*dir), GFP_KERNEL); + dir = kzalloc_obj(*dir); if (!dir) return NULL; @@ -247,7 +247,7 @@ struct tb_property_dir *tb_property_create_dir(const uuid_t *uuid) { struct tb_property_dir *dir; - dir = kzalloc(sizeof(*dir), GFP_KERNEL); + dir = kzalloc_obj(*dir); if (!dir) return NULL; diff --git a/drivers/thunderbolt/retimer.c b/drivers/thunderbolt/retimer.c index 13d64dbd2bc5..b1e8d9d6454d 100644 --- a/drivers/thunderbolt/retimer.c +++ b/drivers/thunderbolt/retimer.c @@ -410,7 +410,7 @@ static int tb_retimer_add(struct tb_port *port, u8 index, u32 auth_status, } - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) return -ENOMEM; diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index e2732c575bad..e5b48a331c58 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -69,7 +69,7 @@ static void nvm_set_auth_status(const struct tb_switch *sw, u32 status) st = __nvm_get_auth_status(sw); if (!st) { - st = kzalloc(sizeof(*st), GFP_KERNEL); + st = kzalloc_obj(*st); if (!st) goto unlock; @@ -2475,7 +2475,7 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, if (upstream_port < 0) return ERR_PTR(upstream_port); - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = kzalloc_obj(*sw); if (!sw) return ERR_PTR(-ENOMEM); @@ -2503,8 +2503,7 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent, } /* initialize ports */ - sw->ports = kcalloc(sw->config.max_port_number + 1, sizeof(*sw->ports), - GFP_KERNEL); + sw->ports = kzalloc_objs(*sw->ports, sw->config.max_port_number + 1); if (!sw->ports) { ret = -ENOMEM; goto err_free_sw_ports; @@ -2577,7 +2576,7 @@ tb_switch_alloc_safe_mode(struct tb *tb, struct device *parent, u64 route) { struct tb_switch *sw; - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = kzalloc_obj(*sw); if (!sw) return ERR_PTR(-ENOMEM); diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 4f5f1dfc0fbf..c69c323e6952 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -94,7 +94,7 @@ static void tb_queue_hotplug(struct tb *tb, u64 route, u8 port, bool unplug) { struct tb_hotplug_event *ev; - ev = kmalloc(sizeof(*ev), GFP_KERNEL); + ev = kmalloc_obj(*ev); if (!ev) return; @@ -2862,7 +2862,7 @@ static void tb_queue_dp_bandwidth_request(struct tb *tb, u64 route, u8 port, { struct tb_hotplug_event *ev; - ev = kmalloc(sizeof(*ev), GFP_KERNEL); + ev = kmalloc_obj(*ev); if (!ev) return; diff --git a/drivers/thunderbolt/tunnel.c b/drivers/thunderbolt/tunnel.c index 9fa95c595ecc..89676acf1290 100644 --- a/drivers/thunderbolt/tunnel.c +++ b/drivers/thunderbolt/tunnel.c @@ -180,11 +180,11 @@ static struct tb_tunnel *tb_tunnel_alloc(struct tb *tb, size_t npaths, { struct tb_tunnel *tunnel; - tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL); + tunnel = kzalloc_obj(*tunnel); if (!tunnel) return NULL; - tunnel->paths = kcalloc(npaths, sizeof(tunnel->paths[0]), GFP_KERNEL); + tunnel->paths = kzalloc_objs(tunnel->paths[0], npaths); if (!tunnel->paths) { kfree(tunnel); return NULL; diff --git a/drivers/thunderbolt/usb4_port.c b/drivers/thunderbolt/usb4_port.c index b5e06237261b..c32d3516e780 100644 --- a/drivers/thunderbolt/usb4_port.c +++ b/drivers/thunderbolt/usb4_port.c @@ -305,7 +305,7 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port) struct usb4_port *usb4; int ret; - usb4 = kzalloc(sizeof(*usb4), GFP_KERNEL); + usb4 = kzalloc_obj(*usb4); if (!usb4) return ERR_PTR(-ENOMEM); diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c index 63c7be818b2c..754808c43f00 100644 --- a/drivers/thunderbolt/xdomain.c +++ b/drivers/thunderbolt/xdomain.c @@ -858,7 +858,7 @@ tb_xdp_schedule_request(struct tb *tb, const struct tb_xdp_header *hdr, { struct xdomain_request_work *xw; - xw = kmalloc(sizeof(*xw), GFP_KERNEL); + xw = kmalloc_obj(*xw); if (!xw) return false; @@ -1094,7 +1094,7 @@ static void enumerate_services(struct tb_xdomain *xd) continue; } - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) break; @@ -1974,7 +1974,7 @@ struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent, down = tb_port_at(route, parent_sw); tb_port_unlock(down); - xd = kzalloc(sizeof(*xd), GFP_KERNEL); + xd = kzalloc_obj(*xd); if (!xd) return NULL; diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 69508d7a4135..2b3ca9f6bf07 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c @@ -772,7 +772,7 @@ static int __init ehv_bc_init(void) * array, then you can use pointer math (e.g. "bc - bcs") to get its * tty index. */ - bcs = kcalloc(count, sizeof(struct ehv_bc_data), GFP_KERNEL); + bcs = kzalloc_objs(struct ehv_bc_data, count); if (!bcs) return -ENOMEM; diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index 3a9582029005..12d08de59095 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -238,9 +238,7 @@ static int goldfish_tty_create_driver(void) int ret; struct tty_driver *tty; - goldfish_ttys = kcalloc(goldfish_tty_line_count, - sizeof(*goldfish_ttys), - GFP_KERNEL); + goldfish_ttys = kzalloc_objs(*goldfish_ttys, goldfish_tty_line_count); if (goldfish_ttys == NULL) { ret = -ENOMEM; goto err_alloc_goldfish_ttys_failed; diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 6b58f340f210..45d090bf090e 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -922,7 +922,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, return ERR_PTR(err); } - hp = kzalloc(struct_size(hp, outbuf, outbuf_size), GFP_KERNEL); + hp = kzalloc_flex(*hp, outbuf, outbuf_size); if (!hp) return ERR_PTR(-ENOMEM); diff --git a/drivers/tty/hvc/hvc_iucv.c b/drivers/tty/hvc/hvc_iucv.c index 4ca7472c38e0..1dcdb9e99bd8 100644 --- a/drivers/tty/hvc/hvc_iucv.c +++ b/drivers/tty/hvc/hvc_iucv.c @@ -9,8 +9,7 @@ * * Author(s): Hendrik Brueckner */ -#define KMSG_COMPONENT "hvc_iucv" -#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#define pr_fmt(fmt) "hvc_iucv: " fmt #include #include @@ -1051,7 +1050,7 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console) char name[9]; int rc; - priv = kzalloc(sizeof(struct hvc_iucv_private), GFP_KERNEL); + priv = kzalloc_obj(struct hvc_iucv_private); if (!priv) return -ENOMEM; @@ -1344,7 +1343,7 @@ static int __init hvc_iucv_init(void) } } - hvc_iucv_buffer_cache = kmem_cache_create(KMSG_COMPONENT, + hvc_iucv_buffer_cache = kmem_cache_create("hvc_iucv", sizeof(struct iucv_tty_buffer), 0, 0, NULL); if (!hvc_iucv_buffer_cache) { diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c index b2ec1f6efa0a..402da9e7c534 100644 --- a/drivers/tty/hvc/hvc_opal.c +++ b/drivers/tty/hvc/hvc_opal.c @@ -181,7 +181,7 @@ static int hvc_opal_probe(struct platform_device *dev) pv = hvc_opal_privs[termno]; boot = 1; } else if (hvc_opal_privs[termno] == NULL) { - pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL); + pv = kzalloc_obj(struct hvc_opal_priv); if (!pv) return -ENOMEM; pv->proto = proto; diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 47930601a26a..14c6a5564617 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -338,7 +338,7 @@ static int hvc_vio_probe(struct vio_dev *vdev, pr_devel("->non-boot console, using termno %d\n", termno); if (termno < 0) return -ENODEV; - pv = kzalloc(sizeof(struct hvterm_priv), GFP_KERNEL); + pv = kzalloc_obj(struct hvterm_priv); if (!pv) return -ENOMEM; pv->termno = vdev->unit_address; diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 95ec01b1aacf..7f0b6262488c 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -264,7 +264,7 @@ static int xen_hvm_console_init(void) info = vtermno_to_xencons(HVC_COOKIE); if (!info) { - info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); + info = kzalloc_obj(struct xencons_info); if (!info) return -ENOMEM; spin_lock_init(&info->ring_lock); @@ -328,7 +328,7 @@ static int xen_pv_console_init(void) info = vtermno_to_xencons(HVC_COOKIE); if (!info) { - info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); + info = kzalloc_obj(struct xencons_info); if (!info) return -ENOMEM; } else if (info->intf != NULL) { @@ -352,7 +352,7 @@ static int xen_initial_domain_console_init(void) info = vtermno_to_xencons(HVC_COOKIE); if (!info) { - info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); + info = kzalloc_obj(struct xencons_info); if (!info) return -ENOMEM; spin_lock_init(&info->ring_lock); @@ -513,7 +513,7 @@ static int xencons_probe(struct xenbus_device *dev, if (devid == 0) return -ENODEV; - info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL); + info = kzalloc_obj(struct xencons_info); if (!info) return -ENOMEM; spin_lock_init(&info->ring_lock); diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index f57fd9095f75..d32b1e3c50bf 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -748,7 +748,7 @@ static int hvcs_probe( return -EFAULT; } - hvcsd = kzalloc(sizeof(*hvcsd), GFP_KERNEL); + hvcsd = kzalloc_obj(*hvcsd); if (!hvcsd) return -ENODEV; @@ -1394,8 +1394,7 @@ static int hvcs_alloc_index_list(int n) { int i; - hvcs_index_list = kmalloc_array(n, sizeof(hvcs_index_count), - GFP_KERNEL); + hvcs_index_list = kmalloc_objs(hvcs_index_count, n); if (!hvcs_index_list) return -ENOMEM; hvcs_index_count = n; diff --git a/drivers/tty/ipwireless/hardware.c b/drivers/tty/ipwireless/hardware.c index e18848267be4..0bfcbca6e2df 100644 --- a/drivers/tty/ipwireless/hardware.c +++ b/drivers/tty/ipwireless/hardware.c @@ -1618,7 +1618,7 @@ struct ipw_hardware *ipwireless_hardware_create(void) { int i; struct ipw_hardware *hw = - kzalloc(sizeof(struct ipw_hardware), GFP_KERNEL); + kzalloc_obj(struct ipw_hardware); if (!hw) return NULL; diff --git a/drivers/tty/ipwireless/main.c b/drivers/tty/ipwireless/main.c index 4c18bbfe1a92..a2875823290e 100644 --- a/drivers/tty/ipwireless/main.c +++ b/drivers/tty/ipwireless/main.c @@ -267,7 +267,7 @@ static int ipwireless_attach(struct pcmcia_device *link) struct ipw_dev *ipw; int ret; - ipw = kzalloc(sizeof(struct ipw_dev), GFP_KERNEL); + ipw = kzalloc_obj(struct ipw_dev); if (!ipw) return -ENOMEM; diff --git a/drivers/tty/ipwireless/network.c b/drivers/tty/ipwireless/network.c index fe569f6294a2..ad2c5157a018 100644 --- a/drivers/tty/ipwireless/network.c +++ b/drivers/tty/ipwireless/network.c @@ -257,7 +257,7 @@ static void do_go_online(struct work_struct *work_go_online) struct ppp_channel *channel; spin_unlock_irqrestore(&network->lock, flags); - channel = kzalloc(sizeof(struct ppp_channel), GFP_KERNEL); + channel = kzalloc_obj(struct ppp_channel); if (!channel) { printk(KERN_ERR IPWIRELESS_PCCARD_NAME ": unable to allocate PPP channel\n"); @@ -416,7 +416,7 @@ void ipwireless_network_packet_received(struct ipw_network *network, struct ipw_network *ipwireless_network_create(struct ipw_hardware *hw) { struct ipw_network *network = - kzalloc(sizeof(struct ipw_network), GFP_KERNEL); + kzalloc_obj(struct ipw_network); if (!network) return NULL; diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index b6de40815fb9..ffdbcdd041a3 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c @@ -437,7 +437,7 @@ static int add_tty(int j, struct ipw_network *network, int channel_idx, int secondary_channel_idx, int tty_type) { - ttys[j] = kzalloc(sizeof(struct ipw_tty), GFP_KERNEL); + ttys[j] = kzalloc_obj(struct ipw_tty); if (!ttys[j]) return -ENOMEM; ttys[j]->index = j; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 214abeb89aaa..c13e050de83b 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -2065,8 +2065,7 @@ static void gsm_control_retransmit(struct timer_list *t) static struct gsm_control *gsm_control_send(struct gsm_mux *gsm, unsigned int command, u8 *data, int clen) { - struct gsm_control *ctrl = kzalloc(sizeof(struct gsm_control), - GFP_ATOMIC); + struct gsm_control *ctrl = kzalloc_obj(struct gsm_control, GFP_ATOMIC); unsigned long flags; if (ctrl == NULL) return NULL; @@ -2646,7 +2645,7 @@ static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, in static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) { - struct gsm_dlci *dlci = kzalloc(sizeof(struct gsm_dlci), GFP_ATOMIC); + struct gsm_dlci *dlci = kzalloc_obj(struct gsm_dlci, GFP_ATOMIC); if (dlci == NULL) return NULL; spin_lock_init(&dlci->lock); @@ -3276,7 +3275,7 @@ static inline unsigned int mux_line_to_num(unsigned int line) static struct gsm_mux *gsm_alloc_mux(void) { int i; - struct gsm_mux *gsm = kzalloc(sizeof(struct gsm_mux), GFP_KERNEL); + struct gsm_mux *gsm = kzalloc_obj(struct gsm_mux); if (gsm == NULL) return NULL; gsm->buf = kmalloc(MAX_MRU + 1, GFP_KERNEL); diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 3c9dcb0928c6..98eefa2cede4 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -127,6 +127,8 @@ struct n_hdlc_buf_list { * @rx_buf_list: list of received frame buffers * @tx_free_buf_list: list unused transmit frame buffers * @rx_free_buf_list: list unused received frame buffers + * @write_work: work struct for deferred frame transmission + * @tty_for_write_work: pointer to tty instance used by the @write_work */ struct n_hdlc { bool tbusy; @@ -386,8 +388,7 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const u8 *data, * buffer unless the maximum count has been reached */ if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT) - buf = kmalloc(struct_size(buf, buf, maxframe), - GFP_ATOMIC); + buf = kmalloc_flex(*buf, buf, maxframe, GFP_ATOMIC); } if (!buf) { @@ -668,7 +669,7 @@ static void n_hdlc_alloc_buf(struct n_hdlc_buf_list *list, unsigned int count, unsigned int i; for (i = 0; i < count; i++) { - buf = kmalloc(struct_size(buf, buf, maxframe), GFP_KERNEL); + buf = kmalloc_flex(*buf, buf, maxframe); if (!buf) { pr_debug("%s(), kmalloc() failed for %s buffer %u\n", __func__, name, i); @@ -685,7 +686,7 @@ static void n_hdlc_alloc_buf(struct n_hdlc_buf_list *list, unsigned int count, */ static struct n_hdlc *n_hdlc_alloc(void) { - struct n_hdlc *n_hdlc = kzalloc(sizeof(*n_hdlc), GFP_KERNEL); + struct n_hdlc *n_hdlc = kzalloc_obj(*n_hdlc); if (!n_hdlc) return NULL; diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index e28a921c1637..ed99dbc9f990 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1298,7 +1298,7 @@ static int nozomi_card_init(struct pci_dev *pdev, goto err; } - dc = kzalloc(sizeof(struct nozomi), GFP_KERNEL); + dc = kzalloc_obj(struct nozomi); if (unlikely(!dc)) { dev_err(&pdev->dev, "Could not allocate memory\n"); ret = -ENOMEM; diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 6120d827a797..cb427e93372d 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -364,8 +364,8 @@ static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, if (driver->subtype != PTY_TYPE_MASTER) return -EIO; - ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); - ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); + ports[0] = kmalloc_obj(**ports); + ports[1] = kmalloc_obj(**ports); if (!ports[0] || !ports[1]) goto err; if (!try_module_get(driver->other->owner)) { diff --git a/drivers/tty/rpmsg_tty.c b/drivers/tty/rpmsg_tty.c index 60a2915f5cfe..c5fd6d9b380f 100644 --- a/drivers/tty/rpmsg_tty.c +++ b/drivers/tty/rpmsg_tty.c @@ -134,7 +134,7 @@ static struct rpmsg_tty_port *rpmsg_tty_alloc_cport(void) struct rpmsg_tty_port *cport; int ret; - cport = kzalloc(sizeof(*cport), GFP_KERNEL); + cport = kzalloc_obj(*cport); if (!cport) return ERR_PTR(-ENOMEM); diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c index b33e708cb245..8f25510f89b6 100644 --- a/drivers/tty/serdev/core.c +++ b/drivers/tty/serdev/core.c @@ -414,11 +414,21 @@ static void serdev_drv_remove(struct device *dev) sdrv->remove(to_serdev_device(dev)); } +static void serdev_drv_shutdown(struct device *dev) +{ + const struct serdev_device_driver *sdrv = + to_serdev_device_driver(dev->driver); + + if (dev->driver && sdrv->shutdown) + sdrv->shutdown(to_serdev_device(dev)); +} + static const struct bus_type serdev_bus_type = { .name = "serial", .match = serdev_device_match, .probe = serdev_drv_probe, .remove = serdev_drv_remove, + .shutdown = serdev_drv_shutdown, }; /** @@ -432,7 +442,7 @@ struct serdev_device *serdev_device_alloc(struct serdev_controller *ctrl) { struct serdev_device *serdev; - serdev = kzalloc(sizeof(*serdev), GFP_KERNEL); + serdev = kzalloc_obj(*serdev); if (!serdev) return NULL; @@ -814,6 +824,14 @@ void serdev_controller_remove(struct serdev_controller *ctrl) } EXPORT_SYMBOL_GPL(serdev_controller_remove); +static void serdev_legacy_shutdown(struct serdev_device *serdev) +{ + struct device *dev = &serdev->dev; + struct device_driver *driver = dev->driver; + + driver->shutdown(dev); +} + /** * __serdev_device_driver_register() - Register client driver with serdev core * @sdrv: client driver to be associated with client-device. @@ -830,6 +848,9 @@ int __serdev_device_driver_register(struct serdev_device_driver *sdrv, struct mo /* force drivers to async probe so I/O is possible in probe */ sdrv->driver.probe_type = PROBE_PREFER_ASYNCHRONOUS; + if (!sdrv->shutdown && sdrv->driver.shutdown) + sdrv->shutdown = serdev_legacy_shutdown; + return driver_register(&sdrv->driver); } EXPORT_SYMBOL_GPL(__serdev_device_driver_register); diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c index 758c4aa203ab..fb596262b9c7 100644 --- a/drivers/tty/serial/8250/8250_acorn.c +++ b/drivers/tty/serial/8250/8250_acorn.c @@ -44,7 +44,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) unsigned long bus_addr; unsigned int i; - info = kzalloc(sizeof(struct serial_card_info), GFP_KERNEL); + info = kzalloc_obj(struct serial_card_info); if (!info) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 0e81f78c6063..d2e2c5dfef99 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c @@ -140,7 +140,7 @@ static struct irq_info *serial_get_or_create_irq_info(const struct uart_8250_por if (i->irq == up->port.irq) return i; - i = kzalloc(sizeof(*i), GFP_KERNEL); + i = kzalloc_obj(*i); if (i == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 27af83f0ff46..db73b2ae17fa 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -643,6 +643,10 @@ static int dw8250_probe(struct platform_device *pdev) if (err) return err; + err = pm_runtime_set_active(dev); + if (err) + return dev_err_probe(dev, err, "Failed to set the runtime suspend as active\n"); + data->uart_16550_compatible = device_property_read_bool(dev, "snps,uart-16550-compatible"); data->pdata = device_get_match_data(p->dev); @@ -685,7 +689,6 @@ static int dw8250_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - pm_runtime_set_active(dev); pm_runtime_enable(dev); return 0; @@ -741,19 +744,25 @@ static int dw8250_runtime_suspend(struct device *dev) static int dw8250_runtime_resume(struct device *dev) { + int ret; struct dw8250_data *data = dev_get_drvdata(dev); - clk_prepare_enable(data->pclk); + ret = clk_prepare_enable(data->pclk); + if (ret) + return ret; - clk_prepare_enable(data->clk); + ret = clk_prepare_enable(data->clk); + if (ret) { + clk_disable_unprepare(data->pclk); + return ret; + } return 0; } -static const struct dev_pm_ops dw8250_pm_ops = { - SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume) - RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL) -}; +static _DEFINE_DEV_PM_OPS(dw8250_pm_ops, dw8250_suspend, dw8250_resume, + dw8250_runtime_suspend, dw8250_runtime_resume, + NULL); static const struct dw8250_platform_data dw8250_dw_apb = { .usr_reg = DW_UART_USR, diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index 3012ea03d22c..59ec0c7377a1 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c @@ -240,7 +240,7 @@ static int __init hp300_8250_init(void) #endif /* Create new serial device */ - port = kmalloc(sizeof(struct hp300_port), GFP_KERNEL); + port = kmalloc_obj(struct hp300_port); if (!port) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_keba.c b/drivers/tty/serial/8250/8250_keba.c index c05b89551b12..f94d97e69dc5 100644 --- a/drivers/tty/serial/8250/8250_keba.c +++ b/drivers/tty/serial/8250/8250_keba.c @@ -6,10 +6,18 @@ */ #include -#include +#include +#include +#include +#include +#include #include #include +#include #include +#include +#include +#include #include "8250.h" @@ -43,6 +51,10 @@ enum kuart_mode { #define KUART_CAPABILITY_RS232 BIT(KUART_MODE_RS232) #define KUART_CAPABILITY_MASK GENMASK(3, 0) +/* registers for Indexed Control Register access in enhanced mode */ +#define KUART_EMODE_ICR_OFFSET UART_SCR +#define KUART_EMODE_ICR_VALUE UART_LSR + /* Additional Control Register DTR line configuration */ #define UART_ACR_DTRLC_MASK 0x18 #define UART_ACR_DTRLC_COMPAT 0x00 @@ -90,13 +102,13 @@ static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc) u8 acr; /* set index register to 0 to access ACR register */ - serial_out(up, UART_SCR, UART_ACR); + serial_out(up, KUART_EMODE_ICR_OFFSET, UART_ACR); /* set value register to 0x10 writing DTR mode (1,0) */ - acr = serial_in(up, UART_LSR); + acr = serial_in(up, KUART_EMODE_ICR_VALUE); acr &= ~UART_ACR_DTRLC_MASK; acr |= dtrlc; - serial_out(up, UART_LSR, acr); + serial_out(up, KUART_EMODE_ICR_VALUE, acr); } static int kuart_rs485_config(struct uart_port *port, struct ktermios *termios, @@ -240,10 +252,9 @@ static int kuart_probe(struct auxiliary_device *auxdev, } retval = serial8250_register_8250_port(&uart); - if (retval < 0) { - dev_err(&auxdev->dev, "UART registration failed!\n"); - return retval; - } + if (retval < 0) + return dev_err_probe(&auxdev->dev, retval, + "UART registration failed!\n"); kuart->line = retval; return 0; diff --git a/drivers/tty/serial/8250/8250_men_mcb.c b/drivers/tty/serial/8250/8250_men_mcb.c index a78ef35c8187..6373234da03d 100644 --- a/drivers/tty/serial/8250/8250_men_mcb.c +++ b/drivers/tty/serial/8250/8250_men_mcb.c @@ -28,8 +28,6 @@ #define MEN_UART3_MASK 0x04 #define MEN_UART4_MASK 0x08 -#define MEN_Z125_UARTS_AVAILABLE 0x01 - #define MEN_Z025_MAX_UARTS 4 #define MEN_UART_MEM_SIZE 0x10 #define MEM_UART_REGISTER_SIZE 0x01 @@ -42,12 +40,10 @@ #define MEN_READ_REGISTER(addr) readb(addr) -#define MAX_PORTS 4 - struct serial_8250_men_mcb_data { int num_ports; - int line[MAX_PORTS]; - unsigned int offset[MAX_PORTS]; + int line[MEN_Z025_MAX_UARTS]; + unsigned int offset[MEN_Z025_MAX_UARTS]; }; /* @@ -126,7 +122,7 @@ static int read_serial_data(struct mcb_device *mdev, if (res < 0) return res; - for (i = 0; i < MAX_PORTS; i++) { + for (i = 0; i < MEN_Z025_MAX_UARTS; i++) { mask = 0x1 << i; switch (uarts_available & mask) { case MEN_UART1_MASK: @@ -150,7 +146,7 @@ static int read_serial_data(struct mcb_device *mdev, } } - if (count <= 0 || count > MAX_PORTS) { + if (count <= 0 || count > MEN_Z025_MAX_UARTS) { dev_err(&mdev->dev, "unexpected number of ports: %u\n", count); return -ENODEV; @@ -268,7 +264,4 @@ module_mcb_driver(mcb_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MEN 8250 UART driver"); MODULE_AUTHOR("Michael Moese dev.of_node, "used-by-rtas")) return -EBUSY; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info == NULL) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index 9e49ef48b851..c552c6b9a037 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -100,6 +100,9 @@ #define OMAP_UART_REV_52 0x0502 #define OMAP_UART_REV_63 0x0603 +/* Resume register */ +#define UART_OMAP_RESUME 0x0B + /* Interrupt Enable Register 2 */ #define UART_OMAP_IER2 0x1B #define UART_OMAP_IER2_RHR_IT_DIS BIT(2) @@ -119,7 +122,6 @@ /* Timeout low and High */ #define UART_OMAP_TO_L 0x26 #define UART_OMAP_TO_H 0x27 - struct omap8250_priv { void __iomem *membase; int line; @@ -241,22 +243,6 @@ static void omap_8250_get_divisor(struct uart_port *port, unsigned int baud, unsigned int div_13, div_16; unsigned int abs_d13, abs_d16; - /* - * Old custom speed handling. - */ - if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) { - priv->quot = port->custom_divisor & UART_DIV_MAX; - /* - * I assume that nobody is using this. But hey, if somebody - * would like to specify the divisor _and_ the mode then the - * driver is ready and waiting for it. - */ - if (port->custom_divisor & (1 << 16)) - priv->mdr1 = UART_OMAP_MDR1_13X_MODE; - else - priv->mdr1 = UART_OMAP_MDR1_16X_MODE; - return; - } div_13 = DIV_ROUND_CLOSEST(uartclk, 13 * baud); div_16 = DIV_ROUND_CLOSEST(uartclk, 16 * baud); @@ -929,7 +915,6 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) goto out; cookie = dma->rx_cookie; - dma->rx_running = 0; /* Re-enable RX FIFO interrupt now that transfer is complete */ if (priv->habit & UART_HAS_RHR_IT_DIS) { @@ -963,6 +948,7 @@ static void __dma_rx_do_complete(struct uart_8250_port *p) goto out; ret = tty_insert_flip_string(tty_port, dma->rx_buf, count); + dma->rx_running = 0; p->port.icount.rx += ret; p->port.icount.buf_overrun += count - ret; out: @@ -1256,6 +1242,20 @@ static u16 omap_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, u16 status return status; } +static void am654_8250_handle_uart_errors(struct uart_8250_port *up, u8 iir, u16 status) +{ + if (status & UART_LSR_OE) { + serial8250_clear_and_reinit_fifos(up); + serial_in(up, UART_LSR); + serial_in(up, UART_OMAP_RESUME); + } else { + if (status & (UART_LSR_FE | UART_LSR_PE | UART_LSR_BI)) + serial_in(up, UART_RX); + if (iir & UART_IIR_XOFF) + serial_in(up, UART_IIR); + } +} + static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, u16 status) { @@ -1266,7 +1266,8 @@ static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, * Queue a new transfer if FIFO has data. */ if ((status & (UART_LSR_DR | UART_LSR_BI)) && - (up->ier & UART_IER_RDI)) { + (up->ier & UART_IER_RDI) && !(status & UART_LSR_OE)) { + am654_8250_handle_uart_errors(up, iir, status); omap_8250_rx_dma(up); serial_out(up, UART_OMAP_EFR2, UART_OMAP_EFR2_TIMEOUT_BEHAVE); } else if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT) { @@ -1282,6 +1283,8 @@ static void am654_8250_handle_rx_dma(struct uart_8250_port *up, u8 iir, serial_out(up, UART_OMAP_EFR2, 0x0); up->ier |= UART_IER_RLSI | UART_IER_RDI; serial_out(up, UART_IER, up->ier); + } else { + am654_8250_handle_uart_errors(up, iir, status); } } @@ -1363,6 +1366,8 @@ static int omap8250_select_wakeup_pinctrl(struct device *dev, if (!device_may_wakeup(dev)) return 0; + device_set_out_band_wakeup(dev); + return pinctrl_select_state(priv->pinctrl, priv->pinctrl_wakeup); } diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 3efe075ef7b2..aa1ab4da9ff1 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1205,60 +1205,49 @@ static unsigned int pci_oxsemi_tornado_get_divisor(struct uart_port *port, u8 tcr; int i; - /* Old custom speed handling. */ - if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) { - unsigned int cust_div = port->custom_divisor; + best_squot = quot_scale; + for (i = 0; i < ARRAY_SIZE(p); i++) { + unsigned int spre; + unsigned int srem; + u8 cp; + u8 tc; - quot = cust_div & UART_DIV_MAX; - tcr = (cust_div >> 16) & OXSEMI_TORNADO_TCR_MASK; - cpr = (cust_div >> 20) & OXSEMI_TORNADO_CPR_MASK; - if (cpr < OXSEMI_TORNADO_CPR_MIN) - cpr = OXSEMI_TORNADO_CPR_DEF; - } else { - best_squot = quot_scale; - for (i = 0; i < ARRAY_SIZE(p); i++) { - unsigned int spre; - unsigned int srem; - u8 cp; - u8 tc; + tc = p[i][0]; + cp = p[i][1]; + spre = tc * cp; - tc = p[i][0]; - cp = p[i][1]; - spre = tc * cp; + srem = sdiv % spre; + if (srem > spre / 2) + srem = spre - srem; + squot = DIV_ROUND_CLOSEST(srem * quot_scale, spre); - srem = sdiv % spre; - if (srem > spre / 2) - srem = spre - srem; - squot = DIV_ROUND_CLOSEST(srem * quot_scale, spre); - - if (srem == 0) { - tcr = tc; - cpr = cp; - quot = sdiv / spre; - break; - } else if (squot < best_squot) { - best_squot = squot; - tcr = tc; - cpr = cp; - quot = DIV_ROUND_CLOSEST(sdiv, spre); - } + if (srem == 0) { + tcr = tc; + cpr = cp; + quot = sdiv / spre; + break; + } else if (squot < best_squot) { + best_squot = squot; + tcr = tc; + cpr = cp; + quot = DIV_ROUND_CLOSEST(sdiv, spre); } - while (tcr <= (OXSEMI_TORNADO_TCR_MASK + 1) >> 1 && - quot % 2 == 0) { + } + while (tcr <= (OXSEMI_TORNADO_TCR_MASK + 1) >> 1 && + quot % 2 == 0) { + quot >>= 1; + tcr <<= 1; + } + while (quot > UART_DIV_MAX) { + if (tcr <= (OXSEMI_TORNADO_TCR_MASK + 1) >> 1) { quot >>= 1; tcr <<= 1; - } - while (quot > UART_DIV_MAX) { - if (tcr <= (OXSEMI_TORNADO_TCR_MASK + 1) >> 1) { - quot >>= 1; - tcr <<= 1; - } else if (cpr <= OXSEMI_TORNADO_CPR_MASK >> 1) { - quot >>= 1; - cpr <<= 1; - } else { - quot = quot * cpr / OXSEMI_TORNADO_CPR_MASK; - cpr = OXSEMI_TORNADO_CPR_MASK; - } + } else if (cpr <= OXSEMI_TORNADO_CPR_MASK >> 1) { + quot >>= 1; + cpr <<= 1; + } else { + quot = quot * cpr / OXSEMI_TORNADO_CPR_MASK; + cpr = OXSEMI_TORNADO_CPR_MASK; } } @@ -4159,7 +4148,7 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) nr_ports = rc; } - priv = kzalloc(struct_size(priv, line, nr_ports), GFP_KERNEL); + priv = kzalloc_flex(*priv, line, nr_ports); if (!priv) { priv = ERR_PTR(-ENOMEM); goto err_deinit; diff --git a/drivers/tty/serial/8250/8250_platform.c b/drivers/tty/serial/8250/8250_platform.c index 86d12d2b5907..ad3a7bc31d6f 100644 --- a/drivers/tty/serial/8250/8250_platform.c +++ b/drivers/tty/serial/8250/8250_platform.c @@ -111,7 +111,7 @@ static int serial8250_probe_acpi(struct platform_device *pdev) struct resource *regs; int ret, line; - struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); + struct uart_8250_port *uart __free(kfree) = kzalloc_obj(*uart); if (!uart) return -ENOMEM; @@ -156,7 +156,7 @@ static int serial8250_probe_platform(struct platform_device *dev, struct plat_se { int ret, i; - struct uart_8250_port *uart __free(kfree) = kzalloc(sizeof(*uart), GFP_KERNEL); + struct uart_8250_port *uart __free(kfree) = kzalloc_obj(*uart); if (!uart) return -ENOMEM; diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 719faf92aa8a..cc94af2d578a 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -553,7 +553,7 @@ static int serial8250_em485_init(struct uart_8250_port *p) if (p->em485) goto deassert_rts; - p->em485 = kmalloc(sizeof(struct uart_8250_em485), GFP_ATOMIC); + p->em485 = kmalloc_obj(struct uart_8250_em485, GFP_ATOMIC); if (!p->em485) return -ENOMEM; diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index c488ff6f2865..fd4e8b6ab60d 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -116,6 +116,7 @@ config SERIAL_8250_DMA config SERIAL_8250_PCILIB bool + depends on SERIAL_8250 && PCI config SERIAL_8250_PCI tristate "8250/16550 PCI device support" @@ -205,6 +206,37 @@ config SERIAL_8250_EXTENDED kernel: saying N will just cause the configurator to skip all the questions about serial driver options. If unsure, say N. +config SERIAL_8250_SHARE_IRQ + bool "Support for sharing serial interrupts" + depends on SERIAL_8250_EXTENDED + help + Some serial boards have hardware support which allows multiple dumb + serial ports on the same board to share a single IRQ. To enable + support for this in the serial driver, say Y here. + +config SERIAL_8250_DETECT_IRQ + bool "Autodetect IRQ on standard ports (unsafe)" + depends on SERIAL_8250_EXTENDED + help + Say Y here if you want the kernel to try to guess which IRQ + to use for your serial port. + + This is considered unsafe; it is far better to configure the IRQ in + a boot script using the setserial command. + + If unsure, say N. + +config SERIAL_8250_RSA + bool "Support RSA serial ports" + depends on SERIAL_8250_EXTENDED + help + Say Y here if you have a IODATA RSA-DV II/S ISA card and + would like to use its >115kbps speeds. + You will need to provide module parameter "probe_rsa", or boot-time + parameter 8250.probe_rsa with I/O addresses of this card then. + + If you don't have such card, or if unsure, say N. + config SERIAL_8250_MANY_PORTS bool "Support more than 4 legacy serial ports" depends on SERIAL_8250_EXTENDED @@ -240,19 +272,6 @@ config SERIAL_8250_ACCENT To compile this driver as a module, choose M here: the module will be called 8250_accent. -config SERIAL_8250_ASPEED_VUART - tristate "Aspeed Virtual UART" - depends on SERIAL_8250 - depends on OF - depends on MFD_SYSCON - depends on ARCH_ASPEED || COMPILE_TEST - select REGMAP - help - If you want to use the virtual UART (VUART) device on Aspeed - BMC platforms, enable this option. This enables the 16550A- - compatible device on the local LPC bus, giving a UART device - with no physical RS232 connections. - config SERIAL_8250_BOCA tristate "Support Boca cards" depends on SERIAL_8250 != n && ISA && SERIAL_8250_MANY_PORTS @@ -293,44 +312,23 @@ config SERIAL_8250_PCI1XXXX serial driver for the serial interface. This driver support will ensure to support baud rates upto 1.5Mpbs. +config SERIAL_8250_ASPEED_VUART + tristate "Aspeed Virtual UART" + depends on SERIAL_8250 + depends on OF + depends on MFD_SYSCON + depends on ARCH_ASPEED || COMPILE_TEST + select REGMAP + help + If you want to use the virtual UART (VUART) device on Aspeed + BMC platforms, enable this option. This enables the 16550A- + compatible device on the local LPC bus, giving a UART device + with no physical RS232 connections. + # # Misc. options/drivers. # -config SERIAL_8250_SHARE_IRQ - bool "Support for sharing serial interrupts" - depends on SERIAL_8250_EXTENDED - help - Some serial boards have hardware support which allows multiple dumb - serial ports on the same board to share a single IRQ. To enable - support for this in the serial driver, say Y here. - -config SERIAL_8250_DETECT_IRQ - bool "Autodetect IRQ on standard ports (unsafe)" - depends on SERIAL_8250_EXTENDED - help - Say Y here if you want the kernel to try to guess which IRQ - to use for your serial port. - - This is considered unsafe; it is far better to configure the IRQ in - a boot script using the setserial command. - - If unsure, say N. - -config SERIAL_8250_RSA - bool "Support RSA serial ports" - depends on SERIAL_8250_EXTENDED - help - Say Y here if you have a IODATA RSA-DV II/S ISA card and - would like to use its >115kbps speeds. - You will need to provide module parameter "probe_rsa", or boot-time - parameter 8250.probe_rsa with I/O addresses of this card then. - - If you don't have such card, or if unsure, say N. - -config SERIAL_8250_DWLIB - bool - config SERIAL_8250_ACORN tristate "Acorn expansion card serial port support" depends on ARCH_ACORN && SERIAL_8250 @@ -596,3 +594,6 @@ config SERIAL_OF_PLATFORM are probed through devicetree, including Open Firmware based PowerPC systems and embedded systems on architectures using the flattened device tree format. + +config SERIAL_8250_DWLIB + bool diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 58e279ea7ee0..80483fc7388d 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c @@ -305,7 +305,7 @@ static int serial_probe(struct pcmcia_device *link) dev_dbg(&link->dev, "serial_attach()\n"); /* Create new serial device */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->p_dev = link; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 59221cce0028..f86775cfdcc9 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -413,6 +413,10 @@ config SERIAL_21285_CONSOLE your boot loader (lilo or loadlin) about how to pass options to the kernel at boot time.) +config SERIAL_PXA_NON8250 + bool + depends on !SERIAL_8250 || COMPILE_TEST + config SERIAL_PXA bool "PXA serial port support (DEPRECATED)" depends on ARCH_PXA || ARCH_MMP @@ -426,10 +430,6 @@ config SERIAL_PXA Unless you have a specific need, you should use SERIAL_8250_PXA instead of this. -config SERIAL_PXA_NON8250 - bool - depends on !SERIAL_8250 || COMPILE_TEST - config SERIAL_PXA_CONSOLE bool "Console on PXA serial port (DEPRECATED)" depends on SERIAL_PXA @@ -486,14 +486,14 @@ config SERIAL_IMX can enable its onboard serial port by enabling this option. config SERIAL_IMX_CONSOLE - tristate "Console on IMX serial port" + bool "Console on IMX serial port" depends on SERIAL_IMX select SERIAL_CORE_CONSOLE help If you have enabled the serial port on the Freescale IMX - CPU you can make it the console by answering Y/M to this option. + CPU you can make it the console by answering Y to this option. - Even if you say Y/M here, the currently visible virtual console + Even if you say Y here, the currently visible virtual console (/dev/tty0) will still be used as the system console by default, but you can alter that using a kernel command line option such as "console=ttymxc0". (Try "man bootparam" or see the documentation of @@ -671,7 +671,7 @@ config SERIAL_SH_SCI_EARLYCON default ARCH_RENESAS config SERIAL_SH_SCI_DMA - bool "DMA support" if EXPERT + bool "Support for DMA on SuperH SCI(F)" if EXPERT depends on SERIAL_SH_SCI && DMA_ENGINE default ARCH_RENESAS @@ -863,15 +863,15 @@ config SERIAL_ICOM This driver can also be built as a module. If so, the module will be called icom. +config HAS_TXX9_SERIAL + bool + config SERIAL_TXX9 bool "TMPTX39XX/49XX SIO support" depends on HAS_TXX9_SERIAL select SERIAL_CORE default y -config HAS_TXX9_SERIAL - bool - config SERIAL_TXX9_NR_UARTS int "Maximum number of TMPTX39XX/49XX SIO ports" depends on SERIAL_TXX9 @@ -1251,12 +1251,6 @@ config SERIAL_AR933X_NR_UARTS Set this to the number of serial ports you want the driver to support. -config SERIAL_MPS2_UART_CONSOLE - bool "MPS2 UART console support" - depends on SERIAL_MPS2_UART - select SERIAL_CORE_CONSOLE - select SERIAL_EARLYCON - config SERIAL_MPS2_UART bool "MPS2 UART port" depends on ARCH_MPS2 || COMPILE_TEST @@ -1264,6 +1258,12 @@ config SERIAL_MPS2_UART help This driver support the UART ports on ARM MPS2. +config SERIAL_MPS2_UART_CONSOLE + bool "MPS2 UART console support" + depends on SERIAL_MPS2_UART + select SERIAL_CORE_CONSOLE + select SERIAL_EARLYCON + config SERIAL_ARC tristate "ARC UART driver support" select SERIAL_CORE diff --git a/drivers/tty/serial/icom.c b/drivers/tty/serial/icom.c index b7e33a896589..bcdc07208486 100644 --- a/drivers/tty/serial/icom.c +++ b/drivers/tty/serial/icom.c @@ -1632,7 +1632,7 @@ static int icom_alloc_adapter(struct icom_adapter struct icom_adapter *icom_adapter; struct icom_adapter *cur_adapter_entry; - icom_adapter = kzalloc(sizeof(struct icom_adapter), GFP_KERNEL); + icom_adapter = kzalloc_obj(struct icom_adapter); if (!icom_adapter) { return -ENOMEM; diff --git a/drivers/tty/serial/jsm/jsm_driver.c b/drivers/tty/serial/jsm/jsm_driver.c index 8d21373cae57..4b73e51f83fb 100644 --- a/drivers/tty/serial/jsm/jsm_driver.c +++ b/drivers/tty/serial/jsm/jsm_driver.c @@ -66,7 +66,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto out_disable_device; } - brd = kzalloc(sizeof(*brd), GFP_KERNEL); + brd = kzalloc_obj(*brd); if (!brd) { rc = -ENOMEM; goto out_release_regions; diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index be2f130696b3..286871610c39 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c @@ -391,7 +391,7 @@ int jsm_tty_init(struct jsm_board *brd) * Okay to malloc with GFP_KERNEL, we are not at * interrupt context, and there are no locks held. */ - brd->channels[i] = kzalloc(sizeof(struct jsm_channel), GFP_KERNEL); + brd->channels[i] = kzalloc_obj(struct jsm_channel); if (!brd->channels[i]) { jsm_dbg(CORE, &brd->pci_dev, "%s:%d Unable to allocate memory for channel struct\n", diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index 3faa1b6aa3ee..475b0a6efce4 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c @@ -708,7 +708,7 @@ static int max3100_probe(struct spi_device *spi) return dev_err_probe(dev, -ENOSPC, "too many MAX3100 chips\n"); } - max3100s[i] = kzalloc(sizeof(struct max3100_port), GFP_KERNEL); + max3100s[i] = kzalloc_obj(struct max3100_port); if (!max3100s[i]) { mutex_unlock(&max3100s_lock); return -ENOMEM; diff --git a/drivers/tty/serial/men_z135_uart.c b/drivers/tty/serial/men_z135_uart.c index 9cc15449b673..6fad57fee912 100644 --- a/drivers/tty/serial/men_z135_uart.c +++ b/drivers/tty/serial/men_z135_uart.c @@ -919,5 +919,4 @@ module_exit(men_z135_exit); MODULE_AUTHOR("Johannes Thumshirn "); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("MEN 16z135 High Speed UART"); -MODULE_ALIAS("mcb:16z135"); MODULE_IMPORT_NS("MCB"); diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 884fefbfd5a1..6729d8e83c3c 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c @@ -909,7 +909,7 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) priv->tx_dma_use = 1; - priv->sg_tx_p = kmalloc_array(num, sizeof(struct scatterlist), GFP_ATOMIC); + priv->sg_tx_p = kmalloc_objs(struct scatterlist, num, GFP_ATOMIC); if (!priv->sg_tx_p) { dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); return 0; @@ -1651,7 +1651,7 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev, board = &drv_dat[id->driver_data]; port_type = board->port_type; - priv = kzalloc(sizeof(struct eg20t_port), GFP_KERNEL); + priv = kzalloc_obj(struct eg20t_port); if (priv == NULL) goto init_port_alloc_err; diff --git a/drivers/tty/serial/pic32_uart.c b/drivers/tty/serial/pic32_uart.c index 14d50bd7f1bd..8407f85776c0 100644 --- a/drivers/tty/serial/pic32_uart.c +++ b/drivers/tty/serial/pic32_uart.c @@ -22,8 +22,7 @@ #include #include #include - -#include +#include /* UART name and device definitions */ #define PIC32_DEV_NAME "pic32-uart" diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index e395ff29c1a2..fea0255067cc 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c @@ -811,7 +811,7 @@ static int serial_pxa_probe(struct platform_device *dev) if (irq < 0) return irq; - sport = kzalloc(sizeof(struct uart_pxa_port), GFP_KERNEL); + sport = kzalloc_obj(struct uart_pxa_port); if (!sport) return -ENOMEM; diff --git a/drivers/tty/serial/rsci.c b/drivers/tty/serial/rsci.c index b3c48dc1e07d..c3f12df693ad 100644 --- a/drivers/tty/serial/rsci.c +++ b/drivers/tty/serial/rsci.c @@ -11,6 +11,8 @@ #include #include #include + +#include "serial_mctrl_gpio.h" #include "rsci.h" MODULE_IMPORT_NS("SH_SCI"); @@ -24,7 +26,6 @@ MODULE_IMPORT_NS("SH_SCI"); #define CCR3 0x14 #define CCR4 0x18 #define FCR 0x24 -#define DCR 0x30 #define CSR 0x48 #define FRSR 0x50 #define FTSR 0x54 @@ -36,12 +37,6 @@ MODULE_IMPORT_NS("SH_SCI"); #define RDR_FPER BIT(11) /* FIFO Parity Error */ #define RDR_RDAT_MSK GENMASK(8, 0) -/* TDR (Transmit Data Register) */ -#define TDR_MPBT BIT(9) /* Multiprocessor Transfer */ -#define TDR_TDAT_9BIT_LSHIFT 0 -#define TDR_TDAT_9BIT_VAL 0x1FF -#define TDR_TDAT_9BIT_MSK (TDR_TDAT_9BIT_VAL << TDR_TDAT_9BIT_LSHIFT) - /* CCR0 (Common Control Register 0) */ #define CCR0_SSE BIT(24) /* SSn# Pin Function Enable */ #define CCR0_TEIE BIT(21) /* Transmit End Interrupt Enable */ @@ -66,6 +61,41 @@ MODULE_IMPORT_NS("SH_SCI"); #define CCR1_CTSPEN BIT(1) /* CTS External Pin Enable */ #define CCR1_CTSE BIT(0) /* CTS Enable */ +/* CCR2 (Common Control Register 2) */ +#define CCR2_INIT 0xFF000004 +#define CCR2_CKS_TCLK (0) /* TCLK clock */ +#define CCR2_CKS_TCLK_DIV4 BIT(20) /* TCLK/4 clock */ +#define CCR2_CKS_TCLK_DIV16 BIT(21) /* TCLK16 clock */ +#define CCR2_CKS_TCLK_DIV64 (BIT(21) | BIT(20)) /* TCLK/64 clock */ +#define CCR2_BRME BIT(16) /* Bitrate Modulation Enable */ +#define CCR2_ABCSE BIT(6) /* Asynchronous Mode Extended Base Clock Select */ +#define CCR2_ABCS BIT(5) /* Asynchronous Mode Base Clock Select */ +#define CCR2_BGDM BIT(4) /* Baud Rate Generator Double-Speed Mode Select */ + +/* CCR3 (Common Control Register 3) */ +#define CCR3_INIT 0x1203 +#define CCR3_BLK BIT(29) /* Block Transfer Mode */ +#define CCR3_GM BIT(28) /* GSM Mode */ +#define CCR3_CKE1 BIT(25) /* Clock Enable 1 */ +#define CCR3_CKE0 BIT(24) /* Clock Enable 0 */ +#define CCR3_DEN BIT(21) /* Driver Enabled */ +#define CCR3_FM BIT(20) /* FIFO Mode Select */ +#define CCR3_MP BIT(19) /* Multi-Processor Mode */ +#define CCR3_MOD_ASYNC 0 /* Asynchronous mode (Multi-processor mode) */ +#define CCR3_MOD_IRDA BIT(16) /* Smart card interface mode */ +#define CCR3_MOD_CLK_SYNC BIT(17) /* Clock synchronous mode */ +#define CCR3_MOD_SPI (BIT(17) | BIT(16)) /* Simple SPI mode */ +#define CCR3_MOD_I2C BIT(18) /* Simple I2C mode */ +#define CCR3_RXDESEL BIT(15) /* Asynchronous Start Bit Edge Detection Select */ +#define CCR3_STP BIT(14) /* Stop bit Length */ +#define CCR3_SINV BIT(13) /* Transmitted/Received Data Invert */ +#define CCR3_LSBF BIT(12) /* LSB First select */ +#define CCR3_CHR1 BIT(9) /* Character Length */ +#define CCR3_CHR0 BIT(8) /* Character Length */ +#define CCR3_BPEN BIT(7) /* Synchronizer Bypass Enable */ +#define CCR3_CPOL BIT(1) /* Clock Polarity Select */ +#define CCR3_CPHA BIT(0) /* Clock Phase Select */ + /* FCR (FIFO Control Register) */ #define FCR_RFRST BIT(23) /* Receive FIFO Data Register Reset */ #define FCR_TFRST BIT(15) /* Transmit FIFO Data Register Reset */ @@ -119,8 +149,6 @@ MODULE_IMPORT_NS("SH_SCI"); /* FFCLR (FIFO Flag CLear Register) */ #define FFCLR_DRC BIT(0) /* DR Clear */ -#define DCR_DEPOL BIT(0) - static u32 rsci_serial_in(struct uart_port *p, int offset) { return readl(p->membase + offset); @@ -137,10 +165,6 @@ static void rsci_clear_DRxC(struct uart_port *port) rsci_serial_out(port, FFCLR, FFCLR_DRC); } -static void rsci_clear_SCxSR(struct uart_port *port, unsigned int mask) -{ - rsci_serial_out(port, CFCLR, mask); -} static void rsci_start_rx(struct uart_port *port) { @@ -151,21 +175,160 @@ static void rsci_start_rx(struct uart_port *port) rsci_serial_out(port, CCR0, ctrl); } +static void rsci_enable_ms(struct uart_port *port) +{ + mctrl_gpio_enable_ms(to_sci_port(port)->gpios); +} + +static void rsci_init_pins(struct uart_port *port, unsigned int cflag) +{ + struct sci_port *s = to_sci_port(port); + + /* Use port-specific handler if provided */ + if (s->cfg->ops && s->cfg->ops->init_pins) { + s->cfg->ops->init_pins(port, cflag); + return; + } + + if (!s->has_rtscts) + return; + + if (s->autorts) + rsci_serial_out(port, CCR1, rsci_serial_in(port, CCR1) | + CCR1_CTSE | CCR1_CTSPEN); +} + +static int rsci_scif_set_rtrg(struct uart_port *port, int rx_trig) +{ + u32 fcr = rsci_serial_in(port, FCR); + + if (rx_trig >= port->fifosize) + rx_trig = port->fifosize - 1; + else if (rx_trig < 1) + rx_trig = 0; + + FIELD_MODIFY(FCR_RTRG4_0, &fcr, rx_trig); + rsci_serial_out(port, FCR, fcr); + + return rx_trig; +} + static void rsci_set_termios(struct uart_port *port, struct ktermios *termios, const struct ktermios *old) { + unsigned int ccr2_val = CCR2_INIT, ccr3_val = CCR3_INIT; + unsigned int ccr0_val = 0, ccr1_val = 0, ccr4_val = 0; + unsigned int brr1 = 255, cks1 = 0, srr1 = 15; struct sci_port *s = to_sci_port(port); + unsigned int brr = 255, cks = 0; + int min_err = INT_MAX, err; + unsigned long max_freq = 0; + unsigned int baud, i; unsigned long flags; + unsigned int ctrl; + int best_clk = -1; + + if ((termios->c_cflag & CSIZE) == CS7) { + ccr3_val |= CCR3_CHR0; + } else { + termios->c_cflag &= ~CSIZE; + termios->c_cflag |= CS8; + } + + if (termios->c_cflag & PARENB) + ccr1_val |= CCR1_PE; + + if (termios->c_cflag & PARODD) + ccr1_val |= (CCR1_PE | CCR1_PM); + + if (termios->c_cflag & CSTOPB) + ccr3_val |= CCR3_STP; + + /* Enable noise filter function */ + ccr1_val |= CCR1_NFEN; + + /* + * earlyprintk comes here early on with port->uartclk set to zero. + * the clock framework is not up and running at this point so here + * we assume that 115200 is the maximum baud rate. please note that + * the baud rate is not programmed during earlyprintk - it is assumed + * that the previous boot loader has enabled required clocks and + * setup the baud rate generator hardware for us already. + */ + if (!port->uartclk) { + max_freq = 115200; + } else { + for (i = 0; i < SCI_NUM_CLKS; i++) + max_freq = max(max_freq, s->clk_rates[i]); + + max_freq /= min_sr(s); + } + + baud = uart_get_baud_rate(port, termios, old, 0, max_freq); + if (!baud) + goto done; + + /* Divided Functional Clock using standard Bit Rate Register */ + err = sci_scbrr_calc(s, baud, &brr1, &srr1, &cks1); + if (abs(err) < abs(min_err)) { + best_clk = SCI_FCK; + ccr0_val = 0; + min_err = err; + brr = brr1; + cks = cks1; + } + +done: + if (best_clk >= 0) + dev_dbg(port->dev, "Using clk %pC for %u%+d bps\n", + s->clks[best_clk], baud, min_err); sci_port_enable(s); uart_port_lock_irqsave(port, &flags); - /* For now, only RX enabling is supported */ - if (termios->c_cflag & CREAD) + uart_update_timeout(port, termios->c_cflag, baud); + + rsci_serial_out(port, CCR0, ccr0_val); + + ccr3_val |= CCR3_FM; + rsci_serial_out(port, CCR3, ccr3_val); + + ccr2_val |= (cks << 20) | (brr << 8); + rsci_serial_out(port, CCR2, ccr2_val); + + rsci_serial_out(port, CCR1, ccr1_val); + rsci_serial_out(port, CCR4, ccr4_val); + + ctrl = rsci_serial_in(port, FCR); + ctrl |= (FCR_RFRST | FCR_TFRST); + rsci_serial_out(port, FCR, ctrl); + + if (s->rx_trigger > 1) + rsci_scif_set_rtrg(port, s->rx_trigger); + + port->status &= ~UPSTAT_AUTOCTS; + s->autorts = false; + + if ((port->flags & UPF_HARD_FLOW) && (termios->c_cflag & CRTSCTS)) { + port->status |= UPSTAT_AUTOCTS; + s->autorts = true; + } + + rsci_init_pins(port, termios->c_cflag); + rsci_serial_out(port, CFCLR, CFCLR_CLRFLAG); + rsci_serial_out(port, FFCLR, FFCLR_DRC); + + ccr0_val |= CCR0_RE; + rsci_serial_out(port, CCR0, ccr0_val); + + if ((termios->c_cflag & CREAD) != 0) rsci_start_rx(port); uart_port_unlock_irqrestore(port, flags); sci_port_disable(s); + + if (UART_ENABLE_MS(port, termios->c_cflag)) + rsci_enable_ms(port); } static int rsci_txfill(struct uart_port *port) @@ -190,13 +353,34 @@ static unsigned int rsci_tx_empty(struct uart_port *port) static void rsci_set_mctrl(struct uart_port *port, unsigned int mctrl) { - /* Not supported yet */ + if (mctrl & TIOCM_LOOP) { + /* Standard loopback mode */ + rsci_serial_out(port, CCR1, rsci_serial_in(port, CCR1) | CCR1_SPLP); + } } static unsigned int rsci_get_mctrl(struct uart_port *port) { - /* Not supported yet */ - return 0; + struct sci_port *s = to_sci_port(port); + struct mctrl_gpios *gpios = s->gpios; + unsigned int mctrl = 0; + + mctrl_gpio_get(gpios, &mctrl); + + /* + * CTS/RTS is handled in hardware when supported, while nothing + * else is wired up. + */ + if (!mctrl_gpio_to_gpiod(gpios, UART_GPIO_CTS)) + mctrl |= TIOCM_CTS; + + if (!mctrl_gpio_to_gpiod(gpios, UART_GPIO_DSR)) + mctrl |= TIOCM_DSR; + + if (!mctrl_gpio_to_gpiod(gpios, UART_GPIO_DCD)) + mctrl |= TIOCM_CAR; + + return mctrl; } static void rsci_clear_CFC(struct uart_port *port, unsigned int mask) @@ -326,7 +510,8 @@ static void rsci_receive_chars(struct uart_port *port) continue; } - /* Store data and status. + /* + * Store data and status. * Non FIFO mode is not supported */ if (rdat & RDR_FFER) { @@ -360,6 +545,28 @@ static void rsci_receive_chars(struct uart_port *port) } } +static void rsci_break_ctl(struct uart_port *port, int break_state) +{ + unsigned short ccr0_val, ccr1_val; + unsigned long flags; + + uart_port_lock_irqsave(port, &flags); + ccr1_val = rsci_serial_in(port, CCR1); + ccr0_val = rsci_serial_in(port, CCR0); + + if (break_state == -1) { + ccr1_val = (ccr1_val | CCR1_SPB2IO) & ~CCR1_SPB2DT; + ccr0_val &= ~CCR0_TE; + } else { + ccr1_val = (ccr1_val | CCR1_SPB2DT) & ~CCR1_SPB2IO; + ccr0_val |= CCR0_TE; + } + + rsci_serial_out(port, CCR1, ccr1_val); + rsci_serial_out(port, CCR0, ccr0_val); + uart_port_unlock_irqrestore(port, flags); +} + static void rsci_poll_put_char(struct uart_port *port, unsigned char c) { u32 status; @@ -375,18 +582,27 @@ static void rsci_poll_put_char(struct uart_port *port, unsigned char c) } rsci_serial_out(port, TDR, c); done: - rsci_clear_SCxSR(port, CFCLR_TDREC); + rsci_clear_CFC(port, CFCLR_TDREC); } static void rsci_prepare_console_write(struct uart_port *port, u32 ctrl) { struct sci_port *s = to_sci_port(port); - u32 ctrl_temp = - s->params->param_bits->rxtx_enable | CCR0_TIE | - s->hscif_tot; + u32 ctrl_temp = s->params->param_bits->rxtx_enable; + + if (s->type == RSCI_PORT_SCIF16) + ctrl_temp |= CCR0_TIE | s->hscif_tot; + rsci_serial_out(port, CCR0, ctrl_temp); } +static void rsci_finish_console_write(struct uart_port *port, u32 ctrl) +{ + /* First set TE = 0 and then restore the CCR0 value */ + rsci_serial_out(port, CCR0, ctrl & ~CCR0_TE); + rsci_serial_out(port, CCR0, ctrl); +} + static const char *rsci_type(struct uart_port *port) { return "rsci"; @@ -416,7 +632,18 @@ static const struct sci_port_params_bits rsci_port_param_bits = { .poll_sent_bits = CSR_TDRE | CSR_TEND, }; -static const struct sci_port_params rsci_port_params = { +static const struct sci_port_params rsci_rzg3e_port_params = { + .fifosize = 32, + .overrun_reg = CSR, + .overrun_mask = CSR_ORER, + .sampling_rate_mask = SCI_SR(32), + .error_mask = RSCI_DEFAULT_ERROR_MASK, + .error_clear = RSCI_ERROR_CLEAR, + .param_bits = &rsci_port_param_bits, + .common_regs = &rsci_common_regs, +}; + +static const struct sci_port_params rsci_rzt2h_port_params = { .fifosize = 16, .overrun_reg = CSR, .overrun_mask = CSR_ORER, @@ -434,6 +661,8 @@ static const struct uart_ops rsci_uart_ops = { .start_tx = rsci_start_tx, .stop_tx = rsci_stop_tx, .stop_rx = rsci_stop_rx, + .enable_ms = rsci_enable_ms, + .break_ctl = rsci_break_ctl, .startup = sci_startup, .shutdown = sci_shutdown, .set_termios = rsci_set_termios, @@ -448,31 +677,47 @@ static const struct uart_ops rsci_uart_ops = { static const struct sci_port_ops rsci_port_ops = { .read_reg = rsci_serial_in, .write_reg = rsci_serial_out, - .clear_SCxSR = rsci_clear_SCxSR, + .clear_SCxSR = rsci_clear_CFC, .transmit_chars = rsci_transmit_chars, .receive_chars = rsci_receive_chars, .poll_put_char = rsci_poll_put_char, .prepare_console_write = rsci_prepare_console_write, + .finish_console_write = rsci_finish_console_write, .suspend_regs_size = rsci_suspend_regs_size, + .set_rtrg = rsci_scif_set_rtrg, .shutdown_complete = rsci_shutdown_complete, }; -struct sci_of_data of_sci_rsci_data = { - .type = SCI_PORT_RSCI, +struct sci_of_data of_rsci_rzg3e_data = { + .type = RSCI_PORT_SCIF32, .ops = &rsci_port_ops, .uart_ops = &rsci_uart_ops, - .params = &rsci_port_params, + .params = &rsci_rzg3e_port_params, +}; + +struct sci_of_data of_rsci_rzt2h_data = { + .type = RSCI_PORT_SCIF16, + .ops = &rsci_port_ops, + .uart_ops = &rsci_uart_ops, + .params = &rsci_rzt2h_port_params, }; #ifdef CONFIG_SERIAL_SH_SCI_EARLYCON -static int __init rsci_early_console_setup(struct earlycon_device *device, - const char *opt) +static int __init rsci_rzg3e_early_console_setup(struct earlycon_device *device, + const char *opt) { - return scix_early_console_setup(device, &of_sci_rsci_data); + return scix_early_console_setup(device, &of_rsci_rzg3e_data); } -OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rsci_early_console_setup); +static int __init rsci_rzt2h_early_console_setup(struct earlycon_device *device, + const char *opt) +{ + return scix_early_console_setup(device, &of_rsci_rzt2h_data); +} + +OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g047-rsci", rsci_rzg3e_early_console_setup); +OF_EARLYCON_DECLARE(rsci, "renesas,r9a09g077-rsci", rsci_rzt2h_early_console_setup); #endif /* CONFIG_SERIAL_SH_SCI_EARLYCON */ diff --git a/drivers/tty/serial/rsci.h b/drivers/tty/serial/rsci.h index 2af3f28b465a..2aa2ba3973ee 100644 --- a/drivers/tty/serial/rsci.h +++ b/drivers/tty/serial/rsci.h @@ -5,6 +5,7 @@ #include "sh-sci-common.h" -extern struct sci_of_data of_sci_rsci_data; +extern struct sci_of_data of_rsci_rzg3e_data; +extern struct sci_of_data of_rsci_rzt2h_data; #endif /* __RSCI_H__ */ diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/serial_base_bus.c index 1e1ad28d83fc..a12935f6b992 100644 --- a/drivers/tty/serial/serial_base_bus.c +++ b/drivers/tty/serial/serial_base_bus.c @@ -116,7 +116,7 @@ struct serial_ctrl_device *serial_base_ctrl_add(struct uart_port *port, struct serial_ctrl_device *ctrl_dev; int err; - ctrl_dev = kzalloc(sizeof(*ctrl_dev), GFP_KERNEL); + ctrl_dev = kzalloc_obj(*ctrl_dev); if (!ctrl_dev) return ERR_PTR(-ENOMEM); @@ -156,7 +156,7 @@ struct serial_port_device *serial_base_port_add(struct uart_port *port, int min = 0, max = -1; /* Use -1 for max to apply IDA defaults */ int err; - port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); + port_dev = kzalloc_obj(*port_dev); if (!port_dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 2805cad10511..487756947a96 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -2716,7 +2716,7 @@ int uart_register_driver(struct uart_driver *drv) * Maybe we should be using a slab cache for this, especially if * we have a large number of ports to handle. */ - drv->state = kcalloc(drv->nr, sizeof(struct uart_state), GFP_KERNEL); + drv->state = kzalloc_objs(struct uart_state, drv->nr); if (!drv->state) goto out; @@ -3088,8 +3088,7 @@ static int serial_core_add_one_port(struct uart_driver *drv, struct uart_port *u if (uport->attr_group) num_groups++; - uport->tty_groups = kcalloc(num_groups, sizeof(*uport->tty_groups), - GFP_KERNEL); + uport->tty_groups = kzalloc_objs(*uport->tty_groups, num_groups); if (!uport->tty_groups) return -ENOMEM; diff --git a/drivers/tty/serial/sh-sci-common.h b/drivers/tty/serial/sh-sci-common.h index e3c028df14f1..f363a659c46a 100644 --- a/drivers/tty/serial/sh-sci-common.h +++ b/drivers/tty/serial/sh-sci-common.h @@ -7,7 +7,8 @@ /* Private port IDs */ enum SCI_PORT_TYPE { - SCI_PORT_RSCI = BIT(7) | 0, + RSCI_PORT_SCIF16 = BIT(7) | 0, + RSCI_PORT_SCIF32 = BIT(7) | 1, }; enum SCI_CLKS { @@ -15,6 +16,9 @@ enum SCI_CLKS { SCI_SCK, /* Optional External Clock */ SCI_BRG_INT, /* Optional BRG Internal Clock Source */ SCI_SCIF_CLK, /* Optional BRG External Clock Source */ + SCI_FCK_DIV4, /* Optional Functional Clock frequency-divided by 4 */ + SCI_FCK_DIV16, /* Optional Functional Clock frequency-divided by 16 */ + SCI_FCK_DIV64, /* Optional Functional Clock frequency-divided by 64 */ SCI_NUM_CLKS }; @@ -89,6 +93,7 @@ struct sci_port_ops { void (*shutdown_complete)(struct uart_port *port); void (*prepare_console_write)(struct uart_port *port, u32 ctrl); + void (*finish_console_write)(struct uart_port *port, u32 ctrl); void (*console_save)(struct uart_port *port); void (*console_restore)(struct uart_port *port); size_t (*suspend_regs_size)(void); @@ -165,6 +170,9 @@ void sci_port_enable(struct sci_port *sci_port); int sci_startup(struct uart_port *port); void sci_shutdown(struct uart_port *port); +int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr, + unsigned int *srr, unsigned int *cks); + #define min_sr(_port) ffs((_port)->sampling_rate_mask) #define max_sr(_port) fls((_port)->sampling_rate_mask) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fbfe5575bd3c..bd7486315338 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1182,6 +1182,11 @@ static int sci_handle_errors(struct uart_port *port) return copied; } +static bool sci_is_rsci_type(u8 type) +{ + return (type == RSCI_PORT_SCIF16 || type == RSCI_PORT_SCIF32); +} + static int sci_handle_fifo_overrun(struct uart_port *port) { struct tty_port *tport = &port->state->port; @@ -1190,7 +1195,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) int copied = 0; u32 status; - if (s->type != SCI_PORT_RSCI) { + if (!sci_is_rsci_type(s->type)) { reg = sci_getreg(port, s->params->overrun_reg); if (!reg->size) return 0; @@ -1198,7 +1203,7 @@ static int sci_handle_fifo_overrun(struct uart_port *port) status = s->ops->read_reg(port, s->params->overrun_reg); if (status & s->params->overrun_mask) { - if (s->type == SCI_PORT_RSCI) { + if (sci_is_rsci_type(s->type)) { /* * All of the CFCLR_*C clearing bits match the corresponding * CSR_*status bits. So, reuse the overrun mask for clearing. @@ -2015,7 +2020,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr) unsigned long flags; u32 ctrl; - if (s->type != PORT_SCI && s->type != SCI_PORT_RSCI) + if (s->type != PORT_SCI && !sci_is_rsci_type(s->type)) return sci_tx_interrupt(irq, ptr); uart_port_lock_irqsave(port, &flags); @@ -2568,9 +2573,8 @@ static int sci_brg_calc(struct sci_port *s, unsigned int bps, } /* calculate sample rate, BRR, and clock select */ -static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, - unsigned int *brr, unsigned int *srr, - unsigned int *cks) +int sci_scbrr_calc(struct sci_port *s, unsigned int bps, unsigned int *brr, + unsigned int *srr, unsigned int *cks) { unsigned long freq = s->clk_rates[SCI_FCK]; unsigned int sr, br, prediv, scrate, c; @@ -2634,6 +2638,7 @@ static int sci_scbrr_calc(struct sci_port *s, unsigned int bps, min_err, *brr, *srr + 1, *cks); return min_err; } +EXPORT_SYMBOL_NS_GPL(sci_scbrr_calc, "SH_SCI"); static void sci_reset(struct uart_port *port) { @@ -3167,15 +3172,21 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) [SCI_SCK] = "sck", [SCI_BRG_INT] = "brg_int", [SCI_SCIF_CLK] = "scif_clk", + [SCI_FCK_DIV4] = "tclk_div4", + [SCI_FCK_DIV16] = "tclk_div16", + [SCI_FCK_DIV64] = "tclk_div64", }; struct clk *clk; unsigned int i; if (sci_port->type == PORT_HSCIF) { clk_names[SCI_SCK] = "hsck"; - } else if (sci_port->type == SCI_PORT_RSCI) { + } else if (sci_port->type == RSCI_PORT_SCIF16) { clk_names[SCI_FCK] = "operation"; clk_names[SCI_BRG_INT] = "bus"; + } else if (sci_port->type == RSCI_PORT_SCIF32) { + clk_names[SCI_FCK] = "tclk"; + clk_names[SCI_BRG_INT] = "pclk"; } for (i = 0; i < SCI_NUM_CLKS; i++) { @@ -3185,12 +3196,13 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) if (IS_ERR(clk)) return PTR_ERR(clk); - if (!clk && sci_port->type == SCI_PORT_RSCI && - (i == SCI_FCK || i == SCI_BRG_INT)) { - return dev_err_probe(dev, -ENODEV, - "failed to get %s\n", - name); - } + if (!clk && sci_port->type == RSCI_PORT_SCIF16 && + (i == SCI_FCK || i == SCI_BRG_INT)) + return dev_err_probe(dev, -ENODEV, "failed to get %s\n", name); + + if (!clk && sci_port->type == RSCI_PORT_SCIF32 && + (i != SCI_SCK && i != SCI_SCIF_CLK)) + return dev_err_probe(dev, -ENODEV, "failed to get %s\n", name); if (!clk && i == SCI_FCK) { /* @@ -3200,16 +3212,13 @@ static int sci_init_clocks(struct sci_port *sci_port, struct device *dev) */ clk = devm_clk_get(dev, "peripheral_clk"); if (IS_ERR(clk)) - return dev_err_probe(dev, PTR_ERR(clk), - "failed to get %s\n", - name); + return dev_err_probe(dev, PTR_ERR(clk), "failed to get %s\n", name); } if (!clk) dev_dbg(dev, "failed to get %s\n", name); else - dev_dbg(dev, "clk %s is %pC rate %lu\n", name, - clk, clk_get_rate(clk)); + dev_dbg(dev, "clk %s is %pC rate %lu\n", name, clk, clk_get_rate(clk)); sci_port->clks[i] = clk; } return 0; @@ -3295,7 +3304,7 @@ static int sci_init_single(struct platform_device *dev, * The fourth interrupt on SCI and RSCI port is transmit end interrupt, so * shuffle the interrupts. */ - if (p->type == PORT_SCI || p->type == SCI_PORT_RSCI) + if (p->type == PORT_SCI || sci_is_rsci_type(p->type)) swap(sci_port->irqs[SCIx_BRI_IRQ], sci_port->irqs[SCIx_TEI_IRQ]); /* The SCI generates several interrupts. They can be muxed together or @@ -3320,6 +3329,7 @@ static int sci_init_single(struct platform_device *dev, sci_port->rx_trigger = 64; break; case PORT_SCIFA: + case RSCI_PORT_SCIF32: sci_port->rx_trigger = 32; break; case PORT_SCIF: @@ -3329,8 +3339,8 @@ static int sci_init_single(struct platform_device *dev, else sci_port->rx_trigger = 8; break; - case SCI_PORT_RSCI: - sci_port->rx_trigger = 15; + case RSCI_PORT_SCIF16: + sci_port->rx_trigger = 16; break; default: sci_port->rx_trigger = 1; @@ -3422,7 +3432,10 @@ static void serial_console_write(struct console *co, const char *s, cpu_relax(); /* restore the SCSCR */ - sci_port->ops->write_reg(port, regs->control, ctrl); + if (sci_port->ops->finish_console_write) + sci_port->ops->finish_console_write(port, ctrl); + else + sci_port->ops->write_reg(port, regs->control, ctrl); if (locked) uart_port_unlock_irqrestore(port, flags); @@ -3549,16 +3562,14 @@ static struct uart_driver sci_uart_driver = { static void sci_remove(struct platform_device *dev) { struct sci_port *s = platform_get_drvdata(dev); - unsigned int type = s->type; /* uart_remove_... clears it */ sci_ports_in_use &= ~BIT(s->port.line); uart_remove_one_port(&sci_uart_driver, &s->port); - if (s->port.fifosize > 1) + if (s->port.fifosize > 1) { device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger); - if (type == PORT_SCIFA || type == PORT_SCIFB || type == PORT_HSCIF || - type == SCI_PORT_RSCI) device_remove_file(&dev->dev, &dev_attr_rx_fifo_timeout); + } } static const struct sci_of_data of_sci_scif_sh2 = { @@ -3652,9 +3663,13 @@ static const struct of_device_id of_sci_match[] __maybe_unused = { .data = &of_sci_scif_rzv2h, }, #ifdef CONFIG_SERIAL_RSCI + { + .compatible = "renesas,r9a09g047-rsci", + .data = &of_rsci_rzg3e_data, + }, { .compatible = "renesas,r9a09g077-rsci", - .data = &of_sci_rsci_data, + .data = &of_rsci_rzt2h_data, }, #endif /* CONFIG_SERIAL_RSCI */ /* Family-specific types */ @@ -3716,7 +3731,7 @@ static struct plat_sci_port *sci_parse_dt(struct platform_device *pdev, data = of_device_get_match_data(&pdev->dev); - rstc = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); + rstc = devm_reset_control_array_get_optional_exclusive(&pdev->dev); if (IS_ERR(rstc)) return ERR_PTR(dev_err_probe(&pdev->dev, PTR_ERR(rstc), "failed to get reset ctrl\n")); @@ -3917,15 +3932,10 @@ static int sci_probe(struct platform_device *dev) ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_trigger); if (ret) return ret; - } - if (sp->type == PORT_SCIFA || sp->type == PORT_SCIFB || - sp->type == PORT_HSCIF || sp->type == SCI_PORT_RSCI) { + ret = device_create_file(&dev->dev, &dev_attr_rx_fifo_timeout); if (ret) { - if (sp->port.fifosize > 1) { - device_remove_file(&dev->dev, - &dev_attr_rx_fifo_trigger); - } + device_remove_file(&dev->dev, &dev_attr_rx_fifo_trigger); return ret; } } diff --git a/drivers/tty/serial/sunhv.c b/drivers/tty/serial/sunhv.c index 2b3ec65d595d..35301d6d5bc6 100644 --- a/drivers/tty/serial/sunhv.c +++ b/drivers/tty/serial/sunhv.c @@ -529,7 +529,7 @@ static int hv_probe(struct platform_device *op) if (op->archdata.irqs[0] == 0xffffffff) return -ENODEV; - port = kzalloc(sizeof(struct uart_port), GFP_KERNEL); + port = kzalloc_obj(struct uart_port); if (unlikely(!port)) return -ENOMEM; diff --git a/drivers/tty/serial/sunsab.c b/drivers/tty/serial/sunsab.c index df906ccf2e8a..d0a070c23704 100644 --- a/drivers/tty/serial/sunsab.c +++ b/drivers/tty/serial/sunsab.c @@ -1117,9 +1117,8 @@ static int __init sunsab_init(void) } if (num_channels) { - sunsab_ports = kcalloc(num_channels, - sizeof(struct uart_sunsab_port), - GFP_KERNEL); + sunsab_ports = kzalloc_objs(struct uart_sunsab_port, + num_channels); if (!sunsab_ports) return -ENOMEM; diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 383141fe7ba0..6505a1930da9 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -1398,7 +1398,7 @@ static int su_probe(struct platform_device *op) return -EINVAL; up = &sunsu_ports[nr_inst]; } else { - up = kzalloc(sizeof(*up), GFP_KERNEL); + up = kzalloc_obj(*up); if (!up) return -ENOMEM; } diff --git a/drivers/tty/serial/timbuart.c b/drivers/tty/serial/timbuart.c index 6fa93c3872a7..7a0326e7102a 100644 --- a/drivers/tty/serial/timbuart.c +++ b/drivers/tty/serial/timbuart.c @@ -412,7 +412,7 @@ static int timbuart_probe(struct platform_device *dev) dev_dbg(&dev->dev, "%s\n", __func__); - uart = kzalloc(sizeof(*uart), GFP_KERNEL); + uart = kzalloc_obj(*uart); if (!uart) { err = -EINVAL; goto err_mem; diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 0613f8c11ab1..6b7dcbbacd13 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1247,7 +1247,7 @@ static int ucc_uart_probe(struct platform_device *ofdev) if (ret) return ret; - qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL); + qe_port = kzalloc_obj(struct uart_qe_port); if (!qe_port) { dev_err(&ofdev->dev, "can't allocate QE port structure\n"); return -ENOMEM; diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index 9d591fb291fd..bf4f50e0ce94 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c @@ -3477,7 +3477,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev { struct slgt_info *info; - info = kzalloc(sizeof(struct slgt_info), GFP_KERNEL); + info = kzalloc_obj(struct slgt_info); if (!info) { DBGERR(("%s device alloc failed adapter=%d port=%d\n", diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 1f78b0db3b25..c2e4b31b699a 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -971,7 +971,7 @@ static int sysrq_connect(struct input_handler *handler, struct sysrq_state *sysrq; int error; - sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL); + sysrq = kzalloc_obj(struct sysrq_state); if (!sysrq) return -ENOMEM; diff --git a/drivers/tty/tty_audit.c b/drivers/tty/tty_audit.c index 75542333c54a..d014af6ab060 100644 --- a/drivers/tty/tty_audit.c +++ b/drivers/tty/tty_audit.c @@ -35,7 +35,7 @@ static struct tty_audit_buf *tty_audit_buf_alloc(void) { struct tty_audit_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) goto err; diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index 1a5673acd9b1..79ec953824d5 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -177,7 +177,7 @@ static struct tty_buffer *tty_buffer_alloc(struct tty_port *port, size_t size) */ if (atomic_read(&port->buf.mem_used) > port->buf.mem_limit) return NULL; - p = kmalloc(struct_size(p, data, 2 * size), GFP_ATOMIC | __GFP_NOWARN); + p = kmalloc_flex(*p, data, 2 * size, GFP_ATOMIC | __GFP_NOWARN); if (p == NULL) return NULL; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e2d92cf70eb7..a5d0457e0e28 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -183,7 +183,7 @@ int tty_alloc_file(struct file *file) { struct tty_file_private *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -1471,7 +1471,7 @@ void tty_save_termios(struct tty_struct *tty) /* Stash the termios data */ tp = tty->driver->termios[idx]; if (tp == NULL) { - tp = kmalloc(sizeof(*tp), GFP_KERNEL); + tp = kmalloc_obj(*tp); if (tp == NULL) return; tty->driver->termios[idx] = tp; @@ -3099,7 +3099,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) { struct tty_struct *tty; - tty = kzalloc(sizeof(*tty), GFP_KERNEL_ACCOUNT); + tty = kzalloc_obj(*tty, GFP_KERNEL_ACCOUNT); if (!tty) return NULL; @@ -3244,7 +3244,7 @@ struct device *tty_register_device_attr(struct tty_driver *driver, else tty_line_name(driver, index, name); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -3333,7 +3333,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) return ERR_PTR(-EINVAL); - driver = kzalloc(sizeof(*driver), GFP_KERNEL); + driver = kzalloc_obj(*driver); if (!driver) return ERR_PTR(-ENOMEM); @@ -3343,10 +3343,8 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, driver->flags = flags; if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { - driver->ttys = kcalloc(lines, sizeof(*driver->ttys), - GFP_KERNEL); - driver->termios = kcalloc(lines, sizeof(*driver->termios), - GFP_KERNEL); + driver->ttys = kzalloc_objs(*driver->ttys, lines); + driver->termios = kzalloc_objs(*driver->termios, lines); if (!driver->ttys || !driver->termios) { err = -ENOMEM; goto err_free_all; @@ -3354,8 +3352,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, } if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { - driver->ports = kcalloc(lines, sizeof(*driver->ports), - GFP_KERNEL); + driver->ports = kzalloc_objs(*driver->ports, lines); if (!driver->ports) { err = -ENOMEM; goto err_free_all; @@ -3363,7 +3360,7 @@ struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, cdevs = lines; } - driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); + driver->cdevs = kzalloc_objs(*driver->cdevs, cdevs); if (!driver->cdevs) { err = -ENOMEM; goto err_free_all; diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index d80e9d4c974b..888f2f8f9481 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -162,7 +162,7 @@ static struct tty_ldisc *tty_ldisc_get(struct tty_struct *tty, int disc) * There is no way to handle allocation failure of only 16 bytes. * Let's simplify error handling and save more memory. */ - ld = kmalloc(sizeof(struct tty_ldisc), GFP_KERNEL | __GFP_NOFAIL); + ld = kmalloc_obj(struct tty_ldisc, GFP_KERNEL | __GFP_NOFAIL); ld->ops = ldops; ld->tty = tty; diff --git a/drivers/tty/vcc.c b/drivers/tty/vcc.c index 2960031ace72..27a55465bf5e 100644 --- a/drivers/tty/vcc.c +++ b/drivers/tty/vcc.c @@ -574,7 +574,7 @@ static int vcc_probe(struct vio_dev *vdev, const struct vio_device_id *id) return -ENODEV; } - port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL); + port = kzalloc_obj(struct vcc_port); if (!port) return -ENOMEM; @@ -957,7 +957,7 @@ static int vcc_install(struct tty_driver *driver, struct tty_struct *tty) if (ret) return ret; - port_tty = kzalloc(sizeof(struct tty_port), GFP_KERNEL); + port_tty = kzalloc_obj(struct tty_port); if (!port_tty) return -ENOMEM; diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 7a11c3f2e875..3fa89a2dbeba 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -539,7 +539,7 @@ static int con_allocate_new(struct vc_data *vc) { struct uni_pagedict *new, *old = *vc->uni_pagedict_loc; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return -ENOMEM; diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index d65fc60dd7be..13bc048f45e8 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -1548,7 +1548,7 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev, { int error; - struct input_handle __free(kfree) *handle = kzalloc(sizeof(*handle), GFP_KERNEL); + struct input_handle __free(kfree) *handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; @@ -1649,6 +1649,123 @@ int __init kbd_init(void) /* Ioctl support code */ +static int vt_do_kdgkbdiacr(void __user *udp) +{ + struct kbdiacrs __user *a = udp; + int i, asize; + + struct kbdiacr __free(kfree) *dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr), + GFP_KERNEL); + if (!dia) + return -ENOMEM; + + /* Lock the diacriticals table, make a copy and then + copy it after we unlock */ + scoped_guard(spinlock_irqsave, &kbd_event_lock) { + asize = accent_table_size; + for (i = 0; i < asize; i++) { + dia[i].diacr = conv_uni_to_8bit(accent_table[i].diacr); + dia[i].base = conv_uni_to_8bit(accent_table[i].base); + dia[i].result = conv_uni_to_8bit(accent_table[i].result); + } + } + + if (put_user(asize, &a->kb_cnt)) + return -EFAULT; + if (copy_to_user(a->kbdiacr, dia, asize * sizeof(struct kbdiacr))) + return -EFAULT; + return 0; +} + +static int vt_do_kdgkbdiacruc(void __user *udp) +{ + struct kbdiacrsuc __user *a = udp; + int asize; + + void __free(kfree) *buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc), + GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + /* Lock the diacriticals table, make a copy and then + copy it after we unlock */ + scoped_guard(spinlock_irqsave, &kbd_event_lock) { + asize = accent_table_size; + memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc)); + } + + if (put_user(asize, &a->kb_cnt)) + return -EFAULT; + if (copy_to_user(a->kbdiacruc, buf, asize * sizeof(struct kbdiacruc))) + return -EFAULT; + + return 0; +} + +static int vt_do_kdskbdiacr(void __user *udp, int perm) +{ + struct kbdiacrs __user *a = udp; + struct kbdiacr __free(kfree) *dia = NULL; + unsigned int ct; + int i; + + if (!perm) + return -EPERM; + if (get_user(ct, &a->kb_cnt)) + return -EFAULT; + if (ct >= MAX_DIACR) + return -EINVAL; + + if (ct) { + dia = memdup_array_user(a->kbdiacr, + ct, sizeof(struct kbdiacr)); + if (IS_ERR(dia)) + return PTR_ERR(dia); + } + + guard(spinlock_irqsave)(&kbd_event_lock); + accent_table_size = ct; + for (i = 0; i < ct; i++) { + accent_table[i].diacr = + conv_8bit_to_uni(dia[i].diacr); + accent_table[i].base = + conv_8bit_to_uni(dia[i].base); + accent_table[i].result = + conv_8bit_to_uni(dia[i].result); + } + + return 0; +} + +static int vt_do_kdskbdiacruc(void __user *udp, int perm) +{ + struct kbdiacrsuc __user *a = udp; + unsigned int ct; + void __free(kfree) *buf = NULL; + + if (!perm) + return -EPERM; + + if (get_user(ct, &a->kb_cnt)) + return -EFAULT; + + if (ct >= MAX_DIACR) + return -EINVAL; + + if (ct) { + buf = memdup_array_user(a->kbdiacruc, + ct, sizeof(struct kbdiacruc)); + if (IS_ERR(buf)) + return PTR_ERR(buf); + } + guard(spinlock_irqsave)(&kbd_event_lock); + if (ct) + memcpy(accent_table, buf, + ct * sizeof(struct kbdiacruc)); + accent_table_size = ct; + return 0; +} + /** * vt_do_diacrit - diacritical table updates * @cmd: ioctl request @@ -1660,123 +1777,15 @@ int __init kbd_init(void) */ int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm) { - int asize; - switch (cmd) { case KDGKBDIACR: - { - struct kbdiacrs __user *a = udp; - int i; - - struct kbdiacr __free(kfree) *dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr), - GFP_KERNEL); - if (!dia) - return -ENOMEM; - - /* Lock the diacriticals table, make a copy and then - copy it after we unlock */ - scoped_guard(spinlock_irqsave, &kbd_event_lock) { - asize = accent_table_size; - for (i = 0; i < asize; i++) { - dia[i].diacr = conv_uni_to_8bit(accent_table[i].diacr); - dia[i].base = conv_uni_to_8bit(accent_table[i].base); - dia[i].result = conv_uni_to_8bit(accent_table[i].result); - } - } - - if (put_user(asize, &a->kb_cnt)) - return -EFAULT; - if (copy_to_user(a->kbdiacr, dia, asize * sizeof(struct kbdiacr))) - return -EFAULT; - return 0; - } + return vt_do_kdgkbdiacr(udp); case KDGKBDIACRUC: - { - struct kbdiacrsuc __user *a = udp; - - void __free(kfree) *buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc), - GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - /* Lock the diacriticals table, make a copy and then - copy it after we unlock */ - scoped_guard(spinlock_irqsave, &kbd_event_lock) { - asize = accent_table_size; - memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc)); - } - - if (put_user(asize, &a->kb_cnt)) - return -EFAULT; - if (copy_to_user(a->kbdiacruc, buf, asize * sizeof(struct kbdiacruc))) - return -EFAULT; - - return 0; - } - + return vt_do_kdgkbdiacruc(udp); case KDSKBDIACR: - { - struct kbdiacrs __user *a = udp; - struct kbdiacr __free(kfree) *dia = NULL; - unsigned int ct; - int i; - - if (!perm) - return -EPERM; - if (get_user(ct, &a->kb_cnt)) - return -EFAULT; - if (ct >= MAX_DIACR) - return -EINVAL; - - if (ct) { - dia = memdup_array_user(a->kbdiacr, - ct, sizeof(struct kbdiacr)); - if (IS_ERR(dia)) - return PTR_ERR(dia); - } - - guard(spinlock_irqsave)(&kbd_event_lock); - accent_table_size = ct; - for (i = 0; i < ct; i++) { - accent_table[i].diacr = - conv_8bit_to_uni(dia[i].diacr); - accent_table[i].base = - conv_8bit_to_uni(dia[i].base); - accent_table[i].result = - conv_8bit_to_uni(dia[i].result); - } - - return 0; - } - + return vt_do_kdskbdiacr(udp, perm); case KDSKBDIACRUC: - { - struct kbdiacrsuc __user *a = udp; - unsigned int ct; - void __free(kfree) *buf = NULL; - - if (!perm) - return -EPERM; - - if (get_user(ct, &a->kb_cnt)) - return -EFAULT; - - if (ct >= MAX_DIACR) - return -EINVAL; - - if (ct) { - buf = memdup_array_user(a->kbdiacruc, - ct, sizeof(struct kbdiacruc)); - if (IS_ERR(buf)) - return PTR_ERR(buf); - } - guard(spinlock_irqsave)(&kbd_event_lock); - if (ct) - memcpy(accent_table, buf, - ct * sizeof(struct kbdiacruc)); - accent_table_size = ct; - return 0; - } + return vt_do_kdskbdiacruc(udp, perm); } return 0; } diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c index c814644ef4ee..4d2d46c95fef 100644 --- a/drivers/tty/vt/vc_screen.c +++ b/drivers/tty/vt/vc_screen.c @@ -131,7 +131,7 @@ vcs_poll_data_get(struct file *file) if (poll) return poll; - poll = kzalloc(sizeof(*poll), GFP_KERNEL); + poll = kzalloc_obj(*poll); if (!poll) return NULL; poll->cons_num = console(file_inode(file)); diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 84de274d24ca..c1f152d8b03b 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -1065,7 +1065,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ /* although the numbers above are not valid since long ago, the point is still up-to-date and the comment still has its value even if only as a historical artifact. --mj, July 1998 */ - param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL); + param.vc = vc = kzalloc_obj(struct vc_data); if (!vc) return -ENOMEM; @@ -3230,7 +3230,6 @@ static int do_con_write(struct tty_struct *tty, const u8 *buf, int count) goto rescan_last_byte; } con_flush(vc, &draw); - console_conditional_schedule(); notify_update(vc); return n; @@ -3778,7 +3777,8 @@ static int __init con_init(void) } for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { - vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); + vc_cons[currcons].d = vc = kzalloc_obj(struct vc_data, + GFP_NOWAIT); INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); tty_port_init(&vc->port); visual_init(vc, currcons, true); diff --git a/drivers/ufs/core/ufs-hwmon.c b/drivers/ufs/core/ufs-hwmon.c index 34194064367f..aa0b60a0ee8a 100644 --- a/drivers/ufs/core/ufs-hwmon.c +++ b/drivers/ufs/core/ufs-hwmon.c @@ -169,7 +169,7 @@ void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) struct ufs_hwmon_data *data; struct device *hwmon; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return; diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 847b55789bb8..9ceb6d6d479d 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -517,8 +518,8 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, struct scsi_cmnd *cmd, if (hba->mcq_enabled) { struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq); - - hwq_id = hwq->id; + if (hwq) + hwq_id = hwq->id; } else { doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL); } @@ -4389,14 +4390,6 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) spin_unlock_irqrestore(hba->host->host_lock, flags); mutex_unlock(&hba->uic_cmd_mutex); - /* - * If the h8 exit fails during the runtime resume process, it becomes - * stuck and cannot be recovered through the error handler. To fix - * this, use link recovery instead of the error handler. - */ - if (ret && hba->pm_op_in_progress) - ret = ufshcd_link_recovery(hba); - return ret; } @@ -5249,6 +5242,25 @@ static void ufshcd_lu_init(struct ufs_hba *hba, struct scsi_device *sdev) hba->dev_info.rpmb_region_size[1] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION1_SIZE]; hba->dev_info.rpmb_region_size[2] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION2_SIZE]; hba->dev_info.rpmb_region_size[3] = desc_buf[RPMB_UNIT_DESC_PARAM_REGION3_SIZE]; + + if (hba->dev_info.wspecversion <= 0x0220) { + /* + * These older spec chips have only one RPMB region, + * sized between 128 kB minimum and 16 MB maximum. + * No per region size fields are provided (respective + * REGIONX_SIZE fields always contain zeros), so get + * it from the logical block count and size fields for + * compatibility + * + * (See JESD220C-2_2 Section 14.1.4.6 + * RPMB Unit Descriptor,* offset 13h, 4 bytes) + */ + hba->dev_info.rpmb_region_size[0] = + (get_unaligned_be64(desc_buf + + RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_COUNT) + << desc_buf[RPMB_UNIT_DESC_PARAM_LOGICAL_BLK_SIZE]) + / SZ_128K; + } } @@ -5963,6 +5975,7 @@ static int ufshcd_disable_auto_bkops(struct ufs_hba *hba) hba->auto_bkops_enabled = false; trace_ufshcd_auto_bkops_state(hba, "Disabled"); + hba->urgent_bkops_lvl = BKOPS_STATUS_PERF_IMPACT; hba->is_urgent_bkops_lvl_checked = false; out: return err; @@ -6066,7 +6079,7 @@ static void ufshcd_bkops_exception_event_handler(struct ufs_hba *hba) * impacted or critical. Handle these device by determining their urgent * bkops status at runtime. */ - if (curr_status < BKOPS_STATUS_PERF_IMPACT) { + if ((curr_status > BKOPS_STATUS_NO_OP) && (curr_status < BKOPS_STATUS_PERF_IMPACT)) { dev_err(hba->dev, "%s: device raised urgent BKOPS exception for bkops status %d\n", __func__, curr_status); /* update the current status as the urgent bkops level */ @@ -7097,7 +7110,7 @@ static irqreturn_t ufshcd_handle_mcq_cq_events(struct ufs_hba *hba) ret = ufshcd_vops_get_outstanding_cqs(hba, &outstanding_cqs); if (ret) - outstanding_cqs = (1U << hba->nr_hw_queues) - 1; + outstanding_cqs = (1ULL << hba->nr_hw_queues) - 1; /* Exclude the poll queues */ nr_queues = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL]; @@ -10053,6 +10066,7 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) } flush_work(&hba->eeh_work); + cancel_delayed_work_sync(&hba->ufs_rtc_update_work); ret = ufshcd_vops_suspend(hba, pm_op, PRE_CHANGE); if (ret) @@ -10107,7 +10121,6 @@ static int __ufshcd_wl_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op) if (ret) goto set_link_active; - cancel_delayed_work_sync(&hba->ufs_rtc_update_work); goto out; set_link_active: @@ -10179,7 +10192,15 @@ static int __ufshcd_wl_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) } else { dev_err(hba->dev, "%s: hibern8 exit failed %d\n", __func__, ret); - goto vendor_suspend; + /* + * If the h8 exit fails during the runtime resume + * process, it becomes stuck and cannot be recovered + * through the error handler. To fix this, use link + * recovery instead of the error handler. + */ + ret = ufshcd_link_recovery(hba); + if (ret) + goto vendor_suspend; } } else if (ufshcd_is_link_off(hba)) { /* diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index fa0d4e6aee16..5a4998e2caf8 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c @@ -306,7 +306,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) goto err_map; } } - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) { ret = -ENOMEM; goto err_map; @@ -335,7 +335,7 @@ static int uio_dev_add_attributes(struct uio_device *idev) goto err_portio; } } - portio = kzalloc(sizeof(*portio), GFP_KERNEL); + portio = kzalloc_obj(*portio); if (!portio) { ret = -ENOMEM; goto err_portio; @@ -494,7 +494,7 @@ static int uio_open(struct inode *inode, struct file *filep) goto err_module_get; } - listener = kmalloc(sizeof(*listener), GFP_KERNEL); + listener = kmalloc_obj(*listener); if (!listener) { ret = -ENOMEM; goto err_alloc_listener; @@ -991,7 +991,7 @@ int __uio_register_device(struct module *owner, info->uio_dev = NULL; - idev = kzalloc(sizeof(*idev), GFP_KERNEL); + idev = kzalloc_obj(*idev); if (!idev) { return -ENOMEM; } diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 949eca0adebe..6f3c86149887 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_USB_UHCI_HCD) += host/ obj-$(CONFIG_USB_FHCI_HCD) += host/ obj-$(CONFIG_USB_XHCI_HCD) += host/ obj-$(CONFIG_USB_SL811_HCD) += host/ -obj-$(CONFIG_USB_ISP1362_HCD) += host/ obj-$(CONFIG_USB_R8A66597_HCD) += host/ obj-$(CONFIG_USB_FSL_USB2) += host/ obj-$(CONFIG_USB_FOTG210_HCD) += host/ diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 68a8e9de8b4f..f1900c567ba4 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -1130,7 +1130,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance, int ret; /* instance init */ - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) return -ENOMEM; diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index e6b610a87482..9d28c652bcd8 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c @@ -804,7 +804,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, } } - instance = kzalloc(sizeof(*instance), GFP_KERNEL); + instance = kzalloc_obj(*instance); if (!instance) { ret = -ENOMEM; diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 78a2585f33ec..f3ae72feb5bf 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -2516,7 +2516,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, return ret; } - sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL); + sc = kzalloc_obj(struct uea_softc); if (!sc) return -ENOMEM; diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 5f3ad9a99d9e..9600e1ec0993 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -804,7 +804,7 @@ static int usbatm_atm_open(struct atm_vcc *vcc) goto fail; } - new = kzalloc(sizeof(struct usbatm_vcc_data), GFP_KERNEL); + new = kzalloc_obj(struct usbatm_vcc_data); if (!new) { ret = -ENOMEM; goto fail; diff --git a/drivers/usb/c67x00/c67x00-drv.c b/drivers/usb/c67x00/c67x00-drv.c index 8f38e2c5369a..7ca6682c96c4 100644 --- a/drivers/usb/c67x00/c67x00-drv.c +++ b/drivers/usb/c67x00/c67x00-drv.c @@ -121,7 +121,7 @@ static int c67x00_drv_probe(struct platform_device *pdev) if (!pdata) return -ENODEV; - c67x00 = kzalloc(sizeof(*c67x00), GFP_KERNEL); + c67x00 = kzalloc_obj(*c67x00); if (!c67x00) return -ENOMEM; diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index a09fa68a6ce7..a832f5696f2a 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -246,7 +246,7 @@ c67x00_ep_data_alloc(struct c67x00_hcd *c67x00, struct urb *urb) } /* Allocate and initialize a new c67x00 endpoint data structure */ - ep_data = kzalloc(sizeof(*ep_data), GFP_ATOMIC); + ep_data = kzalloc_obj(*ep_data, GFP_ATOMIC); if (!ep_data) return NULL; @@ -349,7 +349,7 @@ int c67x00_urb_enqueue(struct usb_hcd *hcd, int port = get_root_port(urb->dev)-1; /* Allocate and initialize urb private data */ - urbp = kzalloc(sizeof(*urbp), mem_flags); + urbp = kzalloc_obj(*urbp, mem_flags); if (!urbp) { ret = -ENOMEM; goto err_urbp; @@ -574,7 +574,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, || usb_pipeint(urb->pipe))) return -EMSGSIZE; /* Not really an error, but expected */ - td = kzalloc(sizeof(*td), GFP_ATOMIC); + td = kzalloc_obj(*td, GFP_ATOMIC); if (!td) return -ENOMEM; diff --git a/drivers/usb/cdns3/cdns3-gadget.c b/drivers/usb/cdns3/cdns3-gadget.c index 168707213ed9..d59a60a16ec7 100644 --- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -903,7 +903,7 @@ static int cdns3_prepare_aligned_request_buf(struct cdns3_request *priv_req) buf = priv_req->aligned_buf; if (!buf || priv_req->request.length > buf->size) { - buf = kzalloc(sizeof(*buf), GFP_ATOMIC); + buf = kzalloc_obj(*buf, GFP_ATOMIC); if (!buf) return -ENOMEM; @@ -2315,7 +2315,7 @@ struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); struct cdns3_request *priv_req; - priv_req = kzalloc(sizeof(*priv_req), gfp_flags); + priv_req = kzalloc_obj(*priv_req, gfp_flags); if (!priv_req) return NULL; @@ -3287,7 +3287,7 @@ static int cdns3_gadget_start(struct cdns *cdns) u32 max_speed; int ret; - priv_dev = kzalloc(sizeof(*priv_dev), GFP_KERNEL); + priv_dev = kzalloc_obj(*priv_dev); if (!priv_dev) return -ENOMEM; diff --git a/drivers/usb/cdns3/cdns3-pci-wrap.c b/drivers/usb/cdns3/cdns3-pci-wrap.c index 57f57c24c663..eb5760f75b9d 100644 --- a/drivers/usb/cdns3/cdns3-pci-wrap.c +++ b/drivers/usb/cdns3/cdns3-pci-wrap.c @@ -97,7 +97,7 @@ static int cdns3_pci_probe(struct pci_dev *pdev, if (pci_is_enabled(func)) { wrap = pci_get_drvdata(func); } else { - wrap = kzalloc(sizeof(*wrap), GFP_KERNEL); + wrap = kzalloc_obj(*wrap); if (!wrap) return -ENOMEM; } diff --git a/drivers/usb/cdns3/cdnsp-gadget.c b/drivers/usb/cdns3/cdnsp-gadget.c index d37c29a253dd..6b3815f8a6e5 100644 --- a/drivers/usb/cdns3/cdnsp-gadget.c +++ b/drivers/usb/cdns3/cdnsp-gadget.c @@ -1102,7 +1102,7 @@ static struct usb_request *cdnsp_gadget_ep_alloc_request(struct usb_ep *ep, struct cdnsp_ep *pep = to_cdnsp_ep(ep); struct cdnsp_request *preq; - preq = kzalloc(sizeof(*preq), gfp_flags); + preq = kzalloc_obj(*preq, gfp_flags); if (!preq) return NULL; @@ -1905,7 +1905,7 @@ static int __cdnsp_gadget_init(struct cdns *cdns) cdns_drd_gadget_on(cdns); - pdev = kzalloc(sizeof(*pdev), GFP_KERNEL); + pdev = kzalloc_obj(*pdev); if (!pdev) return -ENOMEM; diff --git a/drivers/usb/cdns3/cdnsp-mem.c b/drivers/usb/cdns3/cdnsp-mem.c index 97866bfb2da9..a2a1b21f2ef8 100644 --- a/drivers/usb/cdns3/cdnsp-mem.c +++ b/drivers/usb/cdns3/cdnsp-mem.c @@ -35,7 +35,7 @@ static struct cdnsp_segment *cdnsp_segment_alloc(struct cdnsp_device *pdev, dma_addr_t dma; int i; - seg = kzalloc(sizeof(*seg), flags); + seg = kzalloc_obj(*seg, flags); if (!seg) return NULL; @@ -376,7 +376,7 @@ static struct cdnsp_ring *cdnsp_ring_alloc(struct cdnsp_device *pdev, struct cdnsp_ring *ring; int ret; - ring = kzalloc(sizeof *(ring), flags); + ring = kzalloc_obj(*(ring), flags); if (!ring) return NULL; @@ -575,9 +575,8 @@ int cdnsp_alloc_stream_info(struct cdnsp_device *pdev, stream_info->num_stream_ctxs = num_stream_ctxs; /* Initialize the array of virtual pointers to stream rings. */ - stream_info->stream_rings = kcalloc(num_streams, - sizeof(struct cdnsp_ring *), - GFP_ATOMIC); + stream_info->stream_rings = kzalloc_objs(struct cdnsp_ring *, + num_streams, GFP_ATOMIC); if (!stream_info->stream_rings) return -ENOMEM; diff --git a/drivers/usb/cdns3/cdnsp-pci.c b/drivers/usb/cdns3/cdnsp-pci.c index 5e7b88ca8b96..566d94e49102 100644 --- a/drivers/usb/cdns3/cdnsp-pci.c +++ b/drivers/usb/cdns3/cdnsp-pci.c @@ -82,7 +82,7 @@ static int cdnsp_pci_probe(struct pci_dev *pdev, if (pci_is_enabled(func)) { cdnsp = pci_get_drvdata(func); } else { - cdnsp = kzalloc(sizeof(*cdnsp), GFP_KERNEL); + cdnsp = kzalloc_obj(*cdnsp); if (!cdnsp) { ret = -ENOMEM; goto put_pci; diff --git a/drivers/usb/cdns3/core.c b/drivers/usb/cdns3/core.c index 1243a5cea91b..f0e32227c0b7 100644 --- a/drivers/usb/cdns3/core.c +++ b/drivers/usb/cdns3/core.c @@ -551,7 +551,7 @@ int cdns_resume(struct cdns *cdns) } } - if (cdns->roles[cdns->role]->resume) + if (!role_changed && cdns->roles[cdns->role]->resume) cdns->roles[cdns->role]->resume(cdns, power_lost); return 0; diff --git a/drivers/usb/chipidea/ci_hdrc_imx.c b/drivers/usb/chipidea/ci_hdrc_imx.c index d4ee9e16332f..56d2ba824a0b 100644 --- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -385,6 +385,7 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) const struct ci_hdrc_imx_platform_flag *imx_platform_flag; struct device_node *np = pdev->dev.of_node; struct device *dev = &pdev->dev; + const char *irq_name; imx_platform_flag = of_device_get_match_data(&pdev->dev); @@ -525,10 +526,16 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev) data->wakeup_irq = platform_get_irq_optional(pdev, 1); if (data->wakeup_irq > 0) { + irq_name = devm_kasprintf(dev, GFP_KERNEL, "%s:wakeup", pdata.name); + if (!irq_name) { + dev_err_probe(dev, -ENOMEM, "failed to create irq_name\n"); + goto err_clk; + } + ret = devm_request_threaded_irq(dev, data->wakeup_irq, NULL, ci_wakeup_irq_handler, IRQF_ONESHOT | IRQF_NO_AUTOEN, - pdata.name, data); + irq_name, data); if (ret) goto err_clk; } diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 64a421ae0f05..f2de86d0ce40 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -360,8 +360,8 @@ static int add_td_to_list(struct ci_hw_ep *hwep, struct ci_hw_req *hwreq, { int i; u32 temp; - struct td_node *lastnode, *node = kzalloc(sizeof(struct td_node), - GFP_ATOMIC); + struct td_node *lastnode, *node = kzalloc_obj(struct td_node, + GFP_ATOMIC); if (node == NULL) return -ENOMEM; @@ -931,6 +931,13 @@ __acquires(hwep->lock) list_del_init(&hwreq->queue); hwreq->req.status = -ESHUTDOWN; + /* Unmap DMA and clean up bounce buffers before giving back */ + usb_gadget_unmap_request_by_dev(hwep->ci->dev->parent, + &hwreq->req, hwep->dir); + + if (hwreq->sgt.sgl) + sglist_do_debounce(hwreq, false); + if (hwreq->req.complete != NULL) { spin_unlock(hwep->lock); usb_gadget_giveback_request(&hwep->ep, &hwreq->req); @@ -1638,7 +1645,7 @@ static struct usb_request *ep_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) if (ep == NULL) return NULL; - hwreq = kzalloc(sizeof(struct ci_hw_req), gfp_flags); + hwreq = kzalloc_obj(struct ci_hw_req, gfp_flags); if (hwreq != NULL) { INIT_LIST_HEAD(&hwreq->queue); INIT_LIST_HEAD(&hwreq->tds); diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 54be4aa1dcb2..7ede29d4c7c1 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -1350,7 +1350,7 @@ static int acm_probe(struct usb_interface *intf, made_compressed_probe: dev_dbg(&intf->dev, "interfaces are valid\n"); - acm = kzalloc(sizeof(struct acm), GFP_KERNEL); + acm = kzalloc_obj(struct acm); if (!acm) return -ENOMEM; @@ -1379,6 +1379,8 @@ static int acm_probe(struct usb_interface *intf, acm->ctrl_caps = h.usb_cdc_acm_descriptor->bmCapabilities; if (quirks & NO_CAP_LINE) acm->ctrl_caps &= ~USB_CDC_CAP_LINE; + if (quirks & MISSING_CAP_BRK) + acm->ctrl_caps |= USB_CDC_CAP_BRK; acm->ctrlsize = ctrlsize; acm->readsize = readsize; acm->rx_buflimit = num_rx_buf; @@ -2002,6 +2004,9 @@ static const struct usb_device_id acm_ids[] = { .driver_info = IGNORE_DEVICE, }, + /* CH343 supports CAP_BRK, but doesn't advertise it */ + { USB_DEVICE(0x1a86, 0x55d3), .driver_info = MISSING_CAP_BRK, }, + /* control interfaces without any protocol set */ { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, USB_CDC_PROTO_NONE) }, diff --git a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h index 759ac15631d3..76f73853a60b 100644 --- a/drivers/usb/class/cdc-acm.h +++ b/drivers/usb/class/cdc-acm.h @@ -113,3 +113,4 @@ struct acm { #define CLEAR_HALT_CONDITIONS BIT(5) #define SEND_ZERO_PACKET BIT(6) #define DISABLE_ECHO BIT(7) +#define MISSING_CAP_BRK BIT(8) diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index ecd6d1f39e49..7556c0dac908 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -225,7 +225,8 @@ static void wdm_in_callback(struct urb *urb) /* we may already be in overflow */ if (!test_bit(WDM_OVERFLOW, &desc->flags)) { memmove(desc->ubuf + desc->length, desc->inbuf, length); - desc->length += length; + smp_wmb(); /* against wdm_read() */ + WRITE_ONCE(desc->length, desc->length + length); } } skip_error: @@ -533,6 +534,7 @@ static ssize_t wdm_read return -ERESTARTSYS; cntr = READ_ONCE(desc->length); + smp_rmb(); /* against wdm_in_callback() */ if (cntr == 0) { desc->read = 0; retry: @@ -1027,7 +1029,7 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor int rv = -ENOMEM; struct wdm_device *desc; - desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL); + desc = kzalloc_obj(struct wdm_device); if (!desc) goto out; INIT_LIST_HEAD(&desc->device_list); @@ -1050,10 +1052,10 @@ static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor desc->wMaxPacketSize = usb_endpoint_maxp(ep); - desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + desc->orq = kmalloc_obj(struct usb_ctrlrequest); if (!desc->orq) goto err; - desc->irq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + desc->irq = kmalloc_obj(struct usb_ctrlrequest); if (!desc->irq) goto err; diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index a7a1d38b6bef..669b9e6879bf 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -1142,7 +1142,7 @@ static int usblp_probe(struct usb_interface *intf, /* Malloc and start initializing usblp structure so we can use it * directly. */ - usblp = kzalloc(sizeof(struct usblp), GFP_KERNEL); + usblp = kzalloc_obj(struct usblp); if (!usblp) { retval = -ENOMEM; goto abort_ret; diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 206f1b738ed3..d39bbfd7fd18 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -172,7 +172,7 @@ static int usbtmc_open(struct inode *inode, struct file *filp) return -ENODEV; } - file_data = kzalloc(sizeof(*file_data), GFP_KERNEL); + file_data = kzalloc_obj(*file_data); if (!file_data) return -ENOMEM; @@ -727,7 +727,7 @@ static int usbtmc488_ioctl_trigger(struct usbtmc_file_data *file_data) buffer[1] = data->bTag; buffer[2] = ~data->bTag; - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out), buffer, USBTMC_HEADER_SIZE, @@ -1347,7 +1347,7 @@ static int send_request_dev_dep_msg_in(struct usbtmc_file_data *file_data, buffer[11] = 0; /* Reserved */ /* Send bulk URB */ - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_sndbulkpipe(data->usb_dev, data->bulk_out), buffer, USBTMC_HEADER_SIZE, @@ -1419,7 +1419,7 @@ static ssize_t usbtmc_read(struct file *filp, char __user *buf, actual = 0; /* Send bulk URB */ - retval = usb_bulk_msg(data->usb_dev, + retval = usb_bulk_msg_killable(data->usb_dev, usb_rcvbulkpipe(data->usb_dev, data->bulk_in), buffer, bufsize, &actual, @@ -2378,7 +2378,7 @@ static int usbtmc_probe(struct usb_interface *intf, dev_dbg(&intf->dev, "%s called\n", __func__); - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/usb/common/ulpi.c b/drivers/usb/common/ulpi.c index 4a2ee447b213..56c9bfaf2ea3 100644 --- a/drivers/usb/common/ulpi.c +++ b/drivers/usb/common/ulpi.c @@ -324,7 +324,7 @@ struct ulpi *ulpi_register_interface(struct device *dev, struct ulpi *ulpi; int ret; - ulpi = kzalloc(sizeof(*ulpi), GFP_KERNEL); + ulpi = kzalloc_obj(*ulpi); if (!ulpi) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 2bb1ceb9d621..6a1fd967e0a6 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -823,7 +823,7 @@ static int usb_parse_configuration(struct usb_device *dev, int cfgidx, nalts[i] = j = USB_MAXALTSETTING; } - intfc = kzalloc(struct_size(intfc, altsetting, j), GFP_KERNEL); + intfc = kzalloc_flex(*intfc, altsetting, j); config->intf_cache[i] = intfc; if (!intfc) return -ENOMEM; @@ -927,7 +927,11 @@ int usb_get_configuration(struct usb_device *dev) dev->descriptor.bNumConfigurations = ncfg = USB_MAXCONFIG; } - if (ncfg < 1) { + if (ncfg < 1 && dev->quirks & USB_QUIRK_FORCE_ONE_CONFIG) { + dev_info(ddev, "Device claims zero configurations, forcing to 1\n"); + dev->descriptor.bNumConfigurations = 1; + ncfg = 1; + } else if (ncfg < 1) { dev_err(ddev, "no configurations\n"); return -EINVAL; } @@ -1045,7 +1049,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) return -ENOMSG; } - bos = kzalloc(sizeof(*bos), GFP_KERNEL); + bos = kzalloc_obj(*bos); if (!bos) return -ENOMEM; @@ -1066,7 +1070,7 @@ int usb_get_bos_descriptor(struct usb_device *dev) if (total_len < length) return -EINVAL; - dev->bos = kzalloc(sizeof(*dev->bos), GFP_KERNEL); + dev->bos = kzalloc_obj(*dev->bos); if (!dev->bos) return -ENOMEM; diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index f6ce6e26e0d4..e191934623c7 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -245,7 +245,7 @@ static int usbdev_mmap(struct file *file, struct vm_area_struct *vma) if (ret) goto error; - usbm = kzalloc(sizeof(struct usb_memory), GFP_KERNEL); + usbm = kzalloc_obj(struct usb_memory); if (!usbm) { ret = -ENOMEM; goto error_decrease_mem; @@ -402,7 +402,7 @@ static struct async *alloc_async(unsigned int numisoframes) { struct async *as; - as = kzalloc(sizeof(struct async), GFP_KERNEL); + as = kzalloc_obj(struct async); if (!as) return NULL; as->urb = usb_alloc_urb(numisoframes, GFP_KERNEL); @@ -970,7 +970,7 @@ static int parse_usbdevfs_streams(struct usb_dev_state *ps, if (num_streams_ret && (num_streams < 2 || num_streams > 65536)) return -EINVAL; - eps = kmalloc_array(num_eps, sizeof(*eps), GFP_KERNEL); + eps = kmalloc_objs(*eps, num_eps); if (!eps) return -ENOMEM; @@ -1039,7 +1039,7 @@ static int usbdev_open(struct inode *inode, struct file *file) int ret; ret = -ENOMEM; - ps = kzalloc(sizeof(struct usb_dev_state), GFP_KERNEL); + ps = kzalloc_obj(struct usb_dev_state); if (!ps) goto out_free_ps; @@ -1196,7 +1196,7 @@ static int do_proc_control(struct usb_dev_state *ps, urb = usb_alloc_urb(0, GFP_NOIO); if (!urb) goto done; - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); + dr = kmalloc_obj(struct usb_ctrlrequest, GFP_NOIO); if (!dr) goto done; @@ -1670,7 +1670,7 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb /* min 8 byte setup packet */ if (uurb->buffer_length < 8) return -EINVAL; - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + dr = kmalloc_obj(struct usb_ctrlrequest); if (!dr) return -ENOMEM; if (copy_from_user(dr, uurb->buffer, 8)) { @@ -1805,9 +1805,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb as->mem_usage = u; if (num_sgs) { - as->urb->sg = kmalloc_array(num_sgs, - sizeof(struct scatterlist), - GFP_KERNEL | __GFP_NOWARN); + as->urb->sg = kmalloc_objs(struct scatterlist, num_sgs, + GFP_KERNEL | __GFP_NOWARN); if (!as->urb->sg) { ret = -ENOMEM; goto error; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 2f5958bc4f7f..2574e65bc640 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -57,7 +57,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, if (fields < 2) return -EINVAL; - dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); + dynid = kzalloc_obj(*dynid); if (!dynid) return -ENOMEM; diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e48399401608..4137ab47f1cd 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c @@ -154,7 +154,7 @@ int usb_create_ep_devs(struct device *parent, struct ep_device *ep_dev; int retval; - ep_dev = kzalloc(sizeof(*ep_dev), GFP_KERNEL); + ep_dev = kzalloc_obj(*ep_dev); if (!ep_dev) { retval = -ENOMEM; goto exit; diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 24feb0de1c00..dee842ea6931 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -77,10 +77,6 @@ /*-------------------------------------------------------------------------*/ -/* Keep track of which host controller drivers are loaded */ -unsigned long usb_hcds_loaded; -EXPORT_SYMBOL_GPL(usb_hcds_loaded); - /* host controllers we manage */ DEFINE_IDR (usb_bus_idr); EXPORT_SYMBOL_GPL (usb_bus_idr); @@ -2197,7 +2193,7 @@ int ehset_single_step_set_feature(struct usb_hcd *hcd, int port) if (!buf) return -ENOMEM; - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + dr = kmalloc_obj(struct usb_ctrlrequest); if (!dr) { kfree(buf); return -ENOMEM; @@ -2571,16 +2567,14 @@ struct usb_hcd *__usb_create_hcd(const struct hc_driver *driver, if (!hcd) return NULL; if (primary_hcd == NULL) { - hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex), - GFP_KERNEL); + hcd->address0_mutex = kmalloc_obj(*hcd->address0_mutex); if (!hcd->address0_mutex) { kfree(hcd); dev_dbg(dev, "hcd address0 mutex alloc failed\n"); return NULL; } mutex_init(hcd->address0_mutex); - hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex), - GFP_KERNEL); + hcd->bandwidth_mutex = kmalloc_obj(*hcd->bandwidth_mutex); if (!hcd->bandwidth_mutex) { kfree(hcd->address0_mutex); kfree(hcd); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index be50d03034a9..24960ba9caa9 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -929,7 +929,7 @@ int usb_hub_clear_tt_buffer(struct urb *urb) * since each TT has "at least two" buffers that can need it (and * there can be many TTs per hub). even if they're uncommon. */ - clear = kmalloc(sizeof *clear, GFP_ATOMIC); + clear = kmalloc_obj(*clear, GFP_ATOMIC); if (clear == NULL) { dev_err(&udev->dev, "can't save CLEAR_TT_BUFFER state\n"); /* FIXME recover somehow ... RESET_TT? */ @@ -1461,20 +1461,20 @@ static int hub_configure(struct usb_hub *hub, unsigned full_load; unsigned maxchild; - hub->buffer = kmalloc(sizeof(*hub->buffer), GFP_KERNEL); + hub->buffer = kmalloc_obj(*hub->buffer); if (!hub->buffer) { ret = -ENOMEM; goto fail; } - hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL); + hub->status = kmalloc_obj(*hub->status); if (!hub->status) { ret = -ENOMEM; goto fail; } mutex_init(&hub->status_mutex); - hub->descriptor = kzalloc(sizeof(*hub->descriptor), GFP_KERNEL); + hub->descriptor = kzalloc_obj(*hub->descriptor); if (!hub->descriptor) { ret = -ENOMEM; goto fail; @@ -1522,7 +1522,7 @@ static int hub_configure(struct usb_hub *hub, dev_info(hub_dev, "%d port%s detected\n", maxchild, str_plural(maxchild)); - hub->ports = kcalloc(maxchild, sizeof(struct usb_port *), GFP_KERNEL); + hub->ports = kzalloc_objs(struct usb_port *, maxchild); if (!hub->ports) { ret = -ENOMEM; goto fail; @@ -1958,7 +1958,7 @@ static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id) /* We found a hub */ dev_info(&intf->dev, "USB hub found\n"); - hub = kzalloc(sizeof(*hub), GFP_KERNEL); + hub = kzalloc_obj(*hub); if (!hub) return -ENOMEM; @@ -4142,7 +4142,7 @@ static int usb_req_set_sel(struct usb_device *udev) * which may be initiated by an error path of a mass storage driver. * Therefore, use GFP_NOIO. */ - sel_values = kmalloc(sizeof *(sel_values), GFP_NOIO); + sel_values = kmalloc_obj(*(sel_values), GFP_NOIO); if (!sel_values) return -ENOMEM; @@ -5236,7 +5236,7 @@ check_highspeed(struct usb_hub *hub, struct usb_device *udev, int port1) if (udev->quirks & USB_QUIRK_DEVICE_QUALIFIER) return; - qual = kmalloc(sizeof *qual, GFP_KERNEL); + qual = kmalloc_obj(*qual); if (qual == NULL) return; diff --git a/drivers/usb/core/ledtrig-usbport.c b/drivers/usb/core/ledtrig-usbport.c index 5e3c515991f3..8881644777a7 100644 --- a/drivers/usb/core/ledtrig-usbport.c +++ b/drivers/usb/core/ledtrig-usbport.c @@ -190,7 +190,7 @@ static int usbport_trig_add_port(struct usbport_trig_data *usbport_data, size_t len; int err; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) { err = -ENOMEM; goto err_out; @@ -305,7 +305,7 @@ static int usbport_trig_activate(struct led_classdev *led_cdev) struct usbport_trig_data *usbport_data; int err; - usbport_data = kzalloc(sizeof(*usbport_data), GFP_KERNEL); + usbport_data = kzalloc_obj(*usbport_data); if (!usbport_data) return -ENOMEM; usbport_data->led_cdev = led_cdev; diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 6138468c67c4..2ab120ce2fa8 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -42,16 +42,19 @@ static void usb_api_blocking_completion(struct urb *urb) /* - * Starts urb and waits for completion or timeout. Note that this call - * is NOT interruptible. Many device driver i/o requests should be - * interruptible and therefore these drivers should implement their - * own interruptible routines. + * Starts urb and waits for completion or timeout. + * Whether or not the wait is killable depends on the flag passed in. + * For example, compare usb_bulk_msg() and usb_bulk_msg_killable(). + * + * For non-killable waits, we enforce a maximum limit on the timeout value. */ -static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) +static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length, + bool killable) { struct api_context ctx; unsigned long expire; int retval; + long rc; init_completion(&ctx.done); urb->context = &ctx; @@ -60,13 +63,24 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) if (unlikely(retval)) goto out; - expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; - if (!wait_for_completion_timeout(&ctx.done, expire)) { + if (!killable && (timeout <= 0 || timeout > USB_MAX_SYNCHRONOUS_TIMEOUT)) + timeout = USB_MAX_SYNCHRONOUS_TIMEOUT; + expire = (timeout > 0) ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; + if (killable) + rc = wait_for_completion_killable_timeout(&ctx.done, expire); + else + rc = wait_for_completion_timeout(&ctx.done, expire); + if (rc <= 0) { usb_kill_urb(urb); - retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); + if (ctx.status != -ENOENT) + retval = ctx.status; + else if (rc == 0) + retval = -ETIMEDOUT; + else + retval = rc; dev_dbg(&urb->dev->dev, - "%s timed out on ep%d%s len=%u/%u\n", + "%s timed out or killed on ep%d%s len=%u/%u\n", current->comm, usb_endpoint_num(&urb->ep->desc), usb_urb_dir_in(urb) ? "in" : "out", @@ -100,7 +114,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev, usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data, len, usb_api_blocking_completion, NULL); - retv = usb_start_wait_urb(urb, timeout, &length); + retv = usb_start_wait_urb(urb, timeout, &length, false); if (retv < 0) return retv; else @@ -117,8 +131,7 @@ static int usb_internal_control_msg(struct usb_device *usb_dev, * @index: USB message index value * @data: pointer to the data to send * @size: length in bytes of the data to send - * @timeout: time in msecs to wait for the message to complete before timing - * out (if 0 the wait is forever) + * @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. * @@ -141,7 +154,7 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, struct usb_ctrlrequest *dr; int ret; - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_NOIO); + dr = kmalloc_obj(struct usb_ctrlrequest, GFP_NOIO); if (!dr) return -ENOMEM; @@ -173,8 +186,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg); * @index: USB message index value * @driver_data: pointer to the data to send * @size: length in bytes of the data to send - * @timeout: time in msecs to wait for the message to complete before timing - * out (if 0 the wait is forever) + * @timeout: time in msecs to wait for the message to complete before timing out * @memflags: the flags for memory allocation for buffers * * Context: !in_interrupt () @@ -232,8 +244,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_send); * @index: USB message index value * @driver_data: pointer to the data to be filled in by the message * @size: length in bytes of the data to be received - * @timeout: time in msecs to wait for the message to complete before timing - * out (if 0 the wait is forever) + * @timeout: time in msecs to wait for the message to complete before timing out * @memflags: the flags for memory allocation for buffers * * Context: !in_interrupt () @@ -304,8 +315,7 @@ EXPORT_SYMBOL_GPL(usb_control_msg_recv); * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred * in bytes - * @timeout: time in msecs to wait for the message to complete before - * timing out (if 0 the wait is forever) + * @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. * @@ -337,8 +347,7 @@ EXPORT_SYMBOL_GPL(usb_interrupt_msg); * @len: length in bytes of the data to send * @actual_length: pointer to a location to put the actual length transferred * in bytes - * @timeout: time in msecs to wait for the message to complete before - * timing out (if 0 the wait is forever) + * @timeout: time in msecs to wait for the message to complete before timing out * * Context: task context, might sleep. * @@ -385,10 +394,59 @@ int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, usb_api_blocking_completion, NULL); - return usb_start_wait_urb(urb, timeout, actual_length); + return usb_start_wait_urb(urb, timeout, actual_length, false); } EXPORT_SYMBOL_GPL(usb_bulk_msg); +/** + * usb_bulk_msg_killable - Builds a bulk urb, sends it off and waits for completion in a killable state + * @usb_dev: pointer to the usb device to send the message to + * @pipe: endpoint "pipe" to send the message to + * @data: pointer to the data to send + * @len: length in bytes of the data to send + * @actual_length: pointer to a location to put the actual length transferred + * in bytes + * @timeout: time in msecs to wait for the message to complete before + * timing out (if <= 0, the wait is as long as possible) + * + * Context: task context, might sleep. + * + * This function is just like usb_blk_msg(), except that it waits in a + * killable state and there is no limit on the timeout length. + * + * Return: + * If successful, 0. Otherwise a negative error number. The number of actual + * bytes transferred will be stored in the @actual_length parameter. + * + */ +int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, int timeout) +{ + struct urb *urb; + struct usb_host_endpoint *ep; + + ep = usb_pipe_endpoint(usb_dev, pipe); + if (!ep || len < 0) + return -EINVAL; + + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) + return -ENOMEM; + + if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + pipe = (pipe & ~(3 << 30)) | (PIPE_INTERRUPT << 30); + usb_fill_int_urb(urb, usb_dev, pipe, data, len, + usb_api_blocking_completion, NULL, + ep->desc.bInterval); + } else + usb_fill_bulk_urb(urb, usb_dev, pipe, data, len, + usb_api_blocking_completion, NULL); + + return usb_start_wait_urb(urb, timeout, actual_length, true); +} +EXPORT_SYMBOL_GPL(usb_bulk_msg_killable); + /*-------------------------------------------------------------------*/ static void sg_clean(struct usb_sg_request *io) @@ -526,7 +584,7 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev, } /* initialize all the urbs we'll use */ - io->urbs = kmalloc_array(io->entries, sizeof(*io->urbs), mem_flags); + io->urbs = kmalloc_objs(*io->urbs, io->entries, mem_flags); if (!io->urbs) goto nomem; @@ -1058,7 +1116,7 @@ struct usb_device_descriptor *usb_get_device_descriptor(struct usb_device *udev) struct usb_device_descriptor *desc; int ret; - desc = kmalloc(sizeof(*desc), GFP_NOIO); + desc = kmalloc_obj(*desc, GFP_NOIO); if (!desc) return ERR_PTR(-ENOMEM); @@ -2028,15 +2086,13 @@ int usb_set_configuration(struct usb_device *dev, int configuration) n = nintf = 0; if (cp) { nintf = cp->desc.bNumInterfaces; - new_interfaces = kmalloc_array(nintf, sizeof(*new_interfaces), - GFP_NOIO); + new_interfaces = kmalloc_objs(*new_interfaces, nintf, GFP_NOIO); if (!new_interfaces) return -ENOMEM; for (; n < nintf; ++n) { - new_interfaces[n] = kzalloc( - sizeof(struct usb_interface), - GFP_NOIO); + new_interfaces[n] = kzalloc_obj(struct usb_interface, + GFP_NOIO); if (!new_interfaces[n]) { ret = -ENOMEM; free_interfaces: @@ -2289,7 +2345,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) { struct set_config_request *req; - req = kmalloc(sizeof(*req), GFP_KERNEL); + req = kmalloc_obj(*req); if (!req) return -ENOMEM; req->udev = udev; diff --git a/drivers/usb/core/phy.c b/drivers/usb/core/phy.c index faa20054ad5a..4bba1c275740 100644 --- a/drivers/usb/core/phy.c +++ b/drivers/usb/core/phy.c @@ -200,16 +200,10 @@ int usb_phy_roothub_set_mode(struct usb_phy_roothub *phy_roothub, list_for_each_entry(roothub_entry, head, list) { err = phy_set_mode(roothub_entry->phy, mode); if (err) - goto err_out; + return err; } return 0; - -err_out: - list_for_each_entry_continue_reverse(roothub_entry, head, list) - phy_power_off(roothub_entry->phy); - - return err; } EXPORT_SYMBOL_GPL(usb_phy_roothub_set_mode); diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c index f54198171b6a..44e38f922bc5 100644 --- a/drivers/usb/core/port.c +++ b/drivers/usb/core/port.c @@ -739,11 +739,11 @@ int usb_hub_create_port_device(struct usb_hub *hub, int port1) struct usb_device *hdev = hub->hdev; int retval; - port_dev = kzalloc(sizeof(*port_dev), GFP_KERNEL); + port_dev = kzalloc_obj(*port_dev); if (!port_dev) return -ENOMEM; - port_dev->req = kzalloc(sizeof(*(port_dev->req)), GFP_KERNEL); + port_dev->req = kzalloc_obj(*(port_dev->req)); if (!port_dev->req) { kfree(port_dev); return -ENOMEM; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c4d85089d19b..5523a8e29021 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -61,8 +61,7 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) quirk_list = NULL; } - quirk_list = kcalloc(quirk_count, sizeof(struct quirk_entry), - GFP_KERNEL); + quirk_list = kzalloc_objs(struct quirk_entry, quirk_count); if (!quirk_list) { quirk_count = 0; mutex_unlock(&quirk_mutex); @@ -141,6 +140,8 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp) case 'p': flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT; break; + case 'q': + flags |= USB_QUIRK_FORCE_ONE_CONFIG; /* Ignore unrecognized flag characters */ } } @@ -208,6 +209,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP v222w 16GB Mini USB Drive */ { USB_DEVICE(0x03f0, 0x3f40), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Huawei 4G LTE module ME906S */ + { USB_DEVICE(0x03f0, 0xa31d), .driver_info = + USB_QUIRK_DISCONNECT_SUSPEND }, + /* Creative SB Audigy 2 NX */ { USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME }, @@ -377,6 +382,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* SanDisk Extreme 55AE */ { USB_DEVICE(0x0781, 0x55ae), .driver_info = USB_QUIRK_NO_LPM }, + /* Avermedia Live Gamer Ultra 2.1 (GC553G2) - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x07ca, 0x2553), .driver_info = USB_QUIRK_NO_BOS }, + /* Realforce 87U Keyboard */ { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM }, @@ -437,6 +445,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x0b05, 0x17e0), .driver_info = USB_QUIRK_IGNORE_REMOTE_WAKEUP }, + /* ASUS TUF 4K PRO - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x0b05, 0x1ab9), .driver_info = USB_QUIRK_NO_BOS }, + /* Realtek Semiconductor Corp. Mass Storage Device (Multicard Reader)*/ { USB_DEVICE(0x0bda, 0x0151), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, @@ -565,6 +576,9 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM }, + /* UGREEN 35871 - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x2b89, 0x5871), .driver_info = USB_QUIRK_NO_BOS }, + /* APTIV AUTOMOTIVE HUB */ { USB_DEVICE(0x2c48, 0x0132), .driver_info = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT }, @@ -575,12 +589,18 @@ static const struct usb_device_id usb_quirk_list[] = { /* Alcor Link AK9563 SC Reader used in 2022 Lenovo ThinkPads */ { USB_DEVICE(0x2ce3, 0x9563), .driver_info = USB_QUIRK_NO_LPM }, + /* ezcap401 - BOS descriptor fetch hangs at SuperSpeed Plus */ + { USB_DEVICE(0x32ed, 0x0401), .driver_info = USB_QUIRK_NO_BOS }, + /* DELL USB GEN2 */ { USB_DEVICE(0x413c, 0xb062), .driver_info = USB_QUIRK_NO_LPM | USB_QUIRK_RESET_RESUME }, /* VCOM device */ { USB_DEVICE(0x4296, 0x7570), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS }, + /* Noji-MCS SmartCard Reader */ + { USB_DEVICE(0x5131, 0x2007), .driver_info = USB_QUIRK_FORCE_ONE_CONFIG }, + /* INTEL VALUE SSD */ { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index ff8df16cca35..c06b44ca507b 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -72,8 +72,7 @@ struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) { struct urb *urb; - urb = kmalloc(struct_size(urb, iso_frame_desc, iso_packets), - mem_flags); + urb = kmalloc_flex(*urb, iso_frame_desc, iso_packets, mem_flags); if (!urb) return NULL; usb_init_urb(urb); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index e740f7852bcd..e9a10a33534c 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -648,7 +648,7 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_hcd *usb_hcd = bus_to_hcd(bus); unsigned raw_port = port1; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index c3d24312db0f..f375c5185bfe 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -578,6 +578,7 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg) { switch (hsotg->dr_mode) { case USB_DR_MODE_HOST: + dwc2_force_mode(hsotg, true); /* * NOTE: This is required for some rockchip soc based * platforms on their host-only dwc2. diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 0637bfbc054e..d216e26c787b 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -397,7 +397,7 @@ static struct usb_request *dwc2_hsotg_ep_alloc_request(struct usb_ep *ep, { struct dwc2_hsotg_req *req; - req = kzalloc(sizeof(*req), flags); + req = kzalloc_obj(*req, flags); if (!req) return NULL; diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c index 30eb8506617c..1a763ad4f721 100644 --- a/drivers/usb/dwc2/hcd.c +++ b/drivers/usb/dwc2/hcd.c @@ -3823,7 +3823,7 @@ static struct dwc2_hcd_urb *dwc2_hcd_urb_alloc(struct dwc2_hsotg *hsotg, { struct dwc2_hcd_urb *urb; - urb = kzalloc(struct_size(urb, iso_descs, iso_desc_count), mem_flags); + urb = kzalloc_flex(*urb, iso_descs, iso_desc_count, mem_flags); if (urb) urb->packet_count = iso_desc_count; return urb; @@ -4743,7 +4743,7 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, qh_allocated = true; } - qtd = kzalloc(sizeof(*qtd), mem_flags); + qtd = kzalloc_obj(*qtd, mem_flags); if (!qtd) { retval = -ENOMEM; goto fail1; @@ -5218,7 +5218,7 @@ int dwc2_hcd_init(struct dwc2_hsotg *hsotg) memset(&hsotg->hc_ptr_array[0], 0, sizeof(hsotg->hc_ptr_array)); for (i = 0; i < num_channels; i++) { - channel = kzalloc(sizeof(*channel), GFP_KERNEL); + channel = kzalloc_obj(*channel); if (!channel) goto error3; channel->hc_num = i; diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c index 904fe0632b34..4f00ff1dc3e1 100644 --- a/drivers/usb/dwc2/hcd_queue.c +++ b/drivers/usb/dwc2/hcd_queue.c @@ -1585,7 +1585,7 @@ struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, return NULL; /* Allocate memory */ - qh = kzalloc(sizeof(*qh), mem_flags); + qh = kzalloc_obj(*qh, mem_flags); if (!qh) return NULL; diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index bf3e04635131..240b15bc52cb 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -211,4 +211,15 @@ config USB_DWC3_APPLE mode on these machines. Say 'Y' or 'M' if you have such device. +config USB_DWC3_GOOGLE + tristate "Google Platform" + help + Support the DesignWare Core USB3 IP found on Google Tensor SoCs, + starting with the G5 generation (Laguna). This driver includes + support for hibernation in host mode. + Say 'Y' or 'M' if you have one such device. + + To compile this driver as a module, choose M here: the + module will be called dwc3-google.ko. + endif diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 89d46ab50068..073bef5309b5 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -59,3 +59,4 @@ obj-$(CONFIG_USB_DWC3_XILINX) += dwc3-xilinx.o obj-$(CONFIG_USB_DWC3_OCTEON) += dwc3-octeon.o obj-$(CONFIG_USB_DWC3_RTK) += dwc3-rtk.o obj-$(CONFIG_USB_DWC3_GENERIC_PLAT) += dwc3-generic-plat.o +obj-$(CONFIG_USB_DWC3_GOOGLE) += dwc3-google.o diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 93fd5fdf95cb..161a4d58b2ce 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -114,23 +114,23 @@ void dwc3_enable_susphy(struct dwc3 *dwc, bool enable) int i; for (i = 0; i < dwc->num_usb3_ports; i++) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(i)); + reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(i)); if (enable && !dwc->dis_u3_susphy_quirk) reg |= DWC3_GUSB3PIPECTL_SUSPHY; else reg &= ~DWC3_GUSB3PIPECTL_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(i), reg); + dwc3_writel(dwc, DWC3_GUSB3PIPECTL(i), reg); } for (i = 0; i < dwc->num_usb2_ports; i++) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i)); if (enable && !dwc->dis_u2_susphy_quirk) reg |= DWC3_GUSB2PHYCFG_SUSPHY; else reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg); } } EXPORT_SYMBOL_GPL(dwc3_enable_susphy); @@ -140,7 +140,7 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy) unsigned int hw_mode; u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); /* * For DRD controllers, GUSB3PIPECTL.SUSPENDENABLE and @@ -155,10 +155,10 @@ void dwc3_set_prtcap(struct dwc3 *dwc, u32 mode, bool ignore_susphy) reg &= ~(DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)); reg |= DWC3_GCTL_PRTCAPDIR(mode); - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); dwc->current_dr_role = mode; - trace_dwc3_set_prtcap(mode); + trace_dwc3_set_prtcap(dwc, mode); } EXPORT_SYMBOL_GPL(dwc3_set_prtcap); @@ -216,9 +216,9 @@ static void __dwc3_set_mode(struct work_struct *work) if (dwc->current_dr_role && ((DWC3_IP_IS(DWC3) || DWC3_VER_IS_PRIOR(DWC31, 190A)) && desired_dr_role != DWC3_GCTL_PRTCAP_OTG)) { - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); reg |= DWC3_GCTL_CORESOFTRESET; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); /* * Wait for internal clocks to synchronized. DWC_usb31 and @@ -228,9 +228,9 @@ static void __dwc3_set_mode(struct work_struct *work) */ msleep(100); - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); reg &= ~DWC3_GCTL_CORESOFTRESET; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); } spin_lock_irqsave(&dwc->lock, flags); @@ -254,9 +254,9 @@ static void __dwc3_set_mode(struct work_struct *work) phy_set_mode(dwc->usb3_generic_phy[i], PHY_MODE_USB_HOST); if (dwc->dis_split_quirk) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); + reg = dwc3_readl(dwc, DWC3_GUCTL3); reg |= DWC3_GUCTL3_SPLITDISABLE; - dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); + dwc3_writel(dwc, DWC3_GUCTL3, reg); } } break; @@ -306,11 +306,11 @@ u32 dwc3_core_fifo_space(struct dwc3_ep *dep, u8 type) struct dwc3 *dwc = dep->dwc; u32 reg; - dwc3_writel(dwc->regs, DWC3_GDBGFIFOSPACE, - DWC3_GDBGFIFOSPACE_NUM(dep->number) | - DWC3_GDBGFIFOSPACE_TYPE(type)); + dwc3_writel(dwc, DWC3_GDBGFIFOSPACE, + DWC3_GDBGFIFOSPACE_NUM(dep->number) | + DWC3_GDBGFIFOSPACE_TYPE(type)); - reg = dwc3_readl(dwc->regs, DWC3_GDBGFIFOSPACE); + reg = dwc3_readl(dwc, DWC3_GDBGFIFOSPACE); return DWC3_GDBGFIFOSPACE_SPACE_AVAILABLE(reg); } @@ -332,7 +332,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST) return 0; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg |= DWC3_DCTL_CSFTRST; reg &= ~DWC3_DCTL_RUN_STOP; dwc3_gadget_dctl_write_safe(dwc, reg); @@ -347,7 +347,7 @@ int dwc3_core_soft_reset(struct dwc3 *dwc) retries = 10; do { - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (!(reg & DWC3_DCTL_CSFTRST)) goto done; @@ -387,12 +387,12 @@ static void dwc3_frame_length_adjustment(struct dwc3 *dwc) if (dwc->fladj == 0) return; - reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg = dwc3_readl(dwc, DWC3_GFLADJ); dft = reg & DWC3_GFLADJ_30MHZ_MASK; if (dft != dwc->fladj) { reg &= ~DWC3_GFLADJ_30MHZ_MASK; reg |= DWC3_GFLADJ_30MHZ_SDBND_SEL | dwc->fladj; - dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + dwc3_writel(dwc, DWC3_GFLADJ, reg); } } @@ -424,10 +424,10 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc) return; } - reg = dwc3_readl(dwc->regs, DWC3_GUCTL); + reg = dwc3_readl(dwc, DWC3_GUCTL); reg &= ~DWC3_GUCTL_REFCLKPER_MASK; reg |= FIELD_PREP(DWC3_GUCTL_REFCLKPER_MASK, period); - dwc3_writel(dwc->regs, DWC3_GUCTL, reg); + dwc3_writel(dwc, DWC3_GUCTL, reg); if (DWC3_VER_IS_PRIOR(DWC3, 250A)) return; @@ -455,7 +455,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc) */ decr = 480000000 / rate; - reg = dwc3_readl(dwc->regs, DWC3_GFLADJ); + reg = dwc3_readl(dwc, DWC3_GFLADJ); reg &= ~DWC3_GFLADJ_REFCLK_FLADJ_MASK & ~DWC3_GFLADJ_240MHZDECR & ~DWC3_GFLADJ_240MHZDECR_PLS1; @@ -466,7 +466,7 @@ static void dwc3_ref_clk_period(struct dwc3 *dwc) if (dwc->gfladj_refclk_lpm_sel) reg |= DWC3_GFLADJ_REFCLK_LPM_SEL; - dwc3_writel(dwc->regs, DWC3_GFLADJ, reg); + dwc3_writel(dwc, DWC3_GFLADJ, reg); } /** @@ -569,16 +569,16 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) evt = dwc->ev_buf; evt->lpos = 0; - dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), - lower_32_bits(evt->dma)); - dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), - upper_32_bits(evt->dma)); - dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), - DWC3_GEVNTSIZ_SIZE(evt->length)); + dwc3_writel(dwc, DWC3_GEVNTADRLO(0), + lower_32_bits(evt->dma)); + dwc3_writel(dwc, DWC3_GEVNTADRHI(0), + upper_32_bits(evt->dma)); + dwc3_writel(dwc, DWC3_GEVNTSIZ(0), + DWC3_GEVNTSIZ_SIZE(evt->length)); /* Clear any stale event */ - reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); + reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0)); + dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg); return 0; } @@ -593,7 +593,7 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) * Exynos platforms may not be able to access event buffer if the * controller failed to halt on dwc3_core_exit(). */ - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); if (!(reg & DWC3_DSTS_DEVCTRLHLT)) return; @@ -601,14 +601,14 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) evt->lpos = 0; - dwc3_writel(dwc->regs, DWC3_GEVNTADRLO(0), 0); - dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); - dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK + dwc3_writel(dwc, DWC3_GEVNTADRLO(0), 0); + dwc3_writel(dwc, DWC3_GEVNTADRHI(0), 0); + dwc3_writel(dwc, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(0)); /* Clear any stale event */ - reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); + reg = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0)); + dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), reg); } static void dwc3_core_num_eps(struct dwc3 *dwc) @@ -622,18 +622,18 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc) { struct dwc3_hwparams *parms = &dwc->hwparams; - parms->hwparams0 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS0); - parms->hwparams1 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS1); - parms->hwparams2 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS2); - parms->hwparams3 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS3); - parms->hwparams4 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS4); - parms->hwparams5 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS5); - parms->hwparams6 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS6); - parms->hwparams7 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS7); - parms->hwparams8 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS8); + parms->hwparams0 = dwc3_readl(dwc, DWC3_GHWPARAMS0); + parms->hwparams1 = dwc3_readl(dwc, DWC3_GHWPARAMS1); + parms->hwparams2 = dwc3_readl(dwc, DWC3_GHWPARAMS2); + parms->hwparams3 = dwc3_readl(dwc, DWC3_GHWPARAMS3); + parms->hwparams4 = dwc3_readl(dwc, DWC3_GHWPARAMS4); + parms->hwparams5 = dwc3_readl(dwc, DWC3_GHWPARAMS5); + parms->hwparams6 = dwc3_readl(dwc, DWC3_GHWPARAMS6); + parms->hwparams7 = dwc3_readl(dwc, DWC3_GHWPARAMS7); + parms->hwparams8 = dwc3_readl(dwc, DWC3_GHWPARAMS8); if (DWC3_IP_IS(DWC32)) - parms->hwparams9 = dwc3_readl(dwc->regs, DWC3_GHWPARAMS9); + parms->hwparams9 = dwc3_readl(dwc, DWC3_GHWPARAMS9); } static void dwc3_config_soc_bus(struct dwc3 *dwc) @@ -641,10 +641,10 @@ static void dwc3_config_soc_bus(struct dwc3 *dwc) if (dwc->gsbuscfg0_reqinfo != DWC3_GSBUSCFG0_REQINFO_UNSPECIFIED) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + reg = dwc3_readl(dwc, DWC3_GSBUSCFG0); reg &= ~DWC3_GSBUSCFG0_REQINFO(~0); reg |= DWC3_GSBUSCFG0_REQINFO(dwc->gsbuscfg0_reqinfo); - dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, reg); + dwc3_writel(dwc, DWC3_GSBUSCFG0, reg); } } @@ -668,7 +668,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(index)); + reg = dwc3_readl(dwc, DWC3_GUSB3PIPECTL(index)); /* * Make sure UX_EXIT_PX is cleared as that causes issues with some @@ -706,7 +706,7 @@ static int dwc3_ss_phy_setup(struct dwc3 *dwc, int index) if (dwc->dis_del_phy_power_chg_quirk) reg &= ~DWC3_GUSB3PIPECTL_DEPOCHANGE; - dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(index), reg); + dwc3_writel(dwc, DWC3_GUSB3PIPECTL(index), reg); return 0; } @@ -715,7 +715,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(index)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(index)); /* Select the HS PHY interface */ switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { @@ -727,7 +727,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index) } else if (dwc->hsphy_interface && !strncmp(dwc->hsphy_interface, "ulpi", 4)) { reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg); } else { /* Relying on default value. */ if (!(reg & DWC3_GUSB2PHYCFG_ULPI_UTMI)) @@ -777,7 +777,7 @@ static int dwc3_hs_phy_setup(struct dwc3 *dwc, int index) if (dwc->ulpi_ext_vbus_drv) reg |= DWC3_GUSB2PHYCFG_ULPIEXTVBUSDRV; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(index), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(index), reg); return 0; } @@ -991,7 +991,7 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GSNPSID); + reg = dwc3_readl(dwc, DWC3_GSNPSID); dwc->ip = DWC3_GSNPS_ID(reg); if (dwc->ip == DWC4_IP) dwc->ip = DWC32_IP; @@ -1000,8 +1000,8 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc) if (DWC3_IP_IS(DWC3)) { dwc->revision = reg; } else if (DWC3_IP_IS(DWC31) || DWC3_IP_IS(DWC32)) { - dwc->revision = dwc3_readl(dwc->regs, DWC3_VER_NUMBER); - dwc->version_type = dwc3_readl(dwc->regs, DWC3_VER_TYPE); + dwc->revision = dwc3_readl(dwc, DWC3_VER_NUMBER); + dwc->version_type = dwc3_readl(dwc, DWC3_VER_TYPE); } else { return false; } @@ -1015,7 +1015,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) unsigned int hw_mode; u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); reg &= ~DWC3_GCTL_SCALEDOWN_MASK; hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0); power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1); @@ -1093,7 +1093,7 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc) if (DWC3_VER_IS_PRIOR(DWC3, 190A)) reg |= DWC3_GCTL_U2RSTECN; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); } static int dwc3_core_get_phy(struct dwc3 *dwc); @@ -1113,7 +1113,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) int ret; int i; - cfg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG0); + cfg = dwc3_readl(dwc, DWC3_GSBUSCFG0); /* * Handle property "snps,incr-burst-type-adjustment". @@ -1188,7 +1188,7 @@ static void dwc3_set_incr_burst_type(struct dwc3 *dwc) break; } - dwc3_writel(dwc->regs, DWC3_GSBUSCFG0, cfg); + dwc3_writel(dwc, DWC3_GSBUSCFG0, cfg); } static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) @@ -1213,12 +1213,12 @@ static void dwc3_set_power_down_clk_scale(struct dwc3 *dwc) * (3x or more) to be within the requirement. */ scale = DIV_ROUND_UP(clk_get_rate(dwc->susp_clk), 16000); - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); if ((reg & DWC3_GCTL_PWRDNSCALE_MASK) < DWC3_GCTL_PWRDNSCALE(scale) || (reg & DWC3_GCTL_PWRDNSCALE_MASK) > DWC3_GCTL_PWRDNSCALE(scale*3)) { reg &= ~(DWC3_GCTL_PWRDNSCALE_MASK); reg |= DWC3_GCTL_PWRDNSCALE(scale); - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); } } @@ -1241,7 +1241,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc) tx_maxburst = dwc->tx_max_burst_prd; if (rx_thr_num && rx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GRXTHRCFG); reg |= DWC31_RXTHRNUMPKTSEL_PRD; reg &= ~DWC31_RXTHRNUMPKT_PRD(~0); @@ -1250,11 +1250,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC31_MAXRXBURSTSIZE_PRD(~0); reg |= DWC31_MAXRXBURSTSIZE_PRD(rx_maxburst); - dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GRXTHRCFG, reg); } if (tx_thr_num && tx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GTXTHRCFG); reg |= DWC31_TXTHRNUMPKTSEL_PRD; reg &= ~DWC31_TXTHRNUMPKT_PRD(~0); @@ -1263,7 +1263,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC31_MAXTXBURSTSIZE_PRD(~0); reg |= DWC31_MAXTXBURSTSIZE_PRD(tx_maxburst); - dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GTXTHRCFG, reg); } } @@ -1274,7 +1274,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc) if (DWC3_IP_IS(DWC3)) { if (rx_thr_num && rx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GRXTHRCFG); reg |= DWC3_GRXTHRCFG_PKTCNTSEL; reg &= ~DWC3_GRXTHRCFG_RXPKTCNT(~0); @@ -1283,11 +1283,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC3_GRXTHRCFG_MAXRXBURSTSIZE(~0); reg |= DWC3_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); - dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GRXTHRCFG, reg); } if (tx_thr_num && tx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GTXTHRCFG); reg |= DWC3_GTXTHRCFG_PKTCNTSEL; reg &= ~DWC3_GTXTHRCFG_TXPKTCNT(~0); @@ -1296,11 +1296,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC3_GTXTHRCFG_MAXTXBURSTSIZE(~0); reg |= DWC3_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); - dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GTXTHRCFG, reg); } } else { if (rx_thr_num && rx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GRXTHRCFG); reg |= DWC31_GRXTHRCFG_PKTCNTSEL; reg &= ~DWC31_GRXTHRCFG_RXPKTCNT(~0); @@ -1309,11 +1309,11 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC31_GRXTHRCFG_MAXRXBURSTSIZE(~0); reg |= DWC31_GRXTHRCFG_MAXRXBURSTSIZE(rx_maxburst); - dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GRXTHRCFG, reg); } if (tx_thr_num && tx_maxburst) { - reg = dwc3_readl(dwc->regs, DWC3_GTXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GTXTHRCFG); reg |= DWC31_GTXTHRCFG_PKTCNTSEL; reg &= ~DWC31_GTXTHRCFG_TXPKTCNT(~0); @@ -1322,7 +1322,7 @@ static void dwc3_config_threshold(struct dwc3 *dwc) reg &= ~DWC31_GTXTHRCFG_MAXTXBURSTSIZE(~0); reg |= DWC31_GTXTHRCFG_MAXTXBURSTSIZE(tx_maxburst); - dwc3_writel(dwc->regs, DWC3_GTXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GTXTHRCFG, reg); } } } @@ -1345,7 +1345,7 @@ int dwc3_core_init(struct dwc3 *dwc) * Write Linux Version Code to our GUID register so it's easy to figure * out which kernel version a bug was found. */ - dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE); + dwc3_writel(dwc, DWC3_GUID, LINUX_VERSION_CODE); ret = dwc3_phy_setup(dwc); if (ret) @@ -1410,9 +1410,9 @@ int dwc3_core_init(struct dwc3 *dwc) * DWC_usb31 controller. */ if (DWC3_VER_IS_WITHIN(DWC3, 310A, ANY)) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); + reg = dwc3_readl(dwc, DWC3_GUCTL2); reg |= DWC3_GUCTL2_RST_ACTBITLATER; - dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); + dwc3_writel(dwc, DWC3_GUCTL2, reg); } /* @@ -1425,9 +1425,9 @@ int dwc3_core_init(struct dwc3 *dwc) * setting GUCTL2[19] by default; instead, use GUCTL2[19] = 0. */ if (DWC3_VER_IS(DWC3, 320A)) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL2); + reg = dwc3_readl(dwc, DWC3_GUCTL2); reg &= ~DWC3_GUCTL2_LC_TIMER; - dwc3_writel(dwc->regs, DWC3_GUCTL2, reg); + dwc3_writel(dwc, DWC3_GUCTL2, reg); } /* @@ -1440,13 +1440,13 @@ int dwc3_core_init(struct dwc3 *dwc) * legacy ULPI PHYs. */ if (dwc->resume_hs_terminations) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); + reg = dwc3_readl(dwc, DWC3_GUCTL1); reg |= DWC3_GUCTL1_RESUME_OPMODE_HS_HOST; - dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + dwc3_writel(dwc, DWC3_GUCTL1, reg); } if (!DWC3_VER_IS_PRIOR(DWC3, 250A)) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL1); + reg = dwc3_readl(dwc, DWC3_GUCTL1); /* * Enable hardware control of sending remote wakeup @@ -1481,7 +1481,7 @@ int dwc3_core_init(struct dwc3 *dwc) reg &= ~DWC3_GUCTL1_DEV_FORCE_20_CLK_FOR_30_CLK; } - dwc3_writel(dwc->regs, DWC3_GUCTL1, reg); + dwc3_writel(dwc, DWC3_GUCTL1, reg); } dwc3_config_threshold(dwc); @@ -1492,9 +1492,9 @@ int dwc3_core_init(struct dwc3 *dwc) int i; for (i = 0; i < dwc->num_usb3_ports; i++) { - reg = dwc3_readl(dwc->regs, DWC3_LLUCTL(i)); + reg = dwc3_readl(dwc, DWC3_LLUCTL(i)); reg |= DWC3_LLUCTL_FORCE_GEN1; - dwc3_writel(dwc->regs, DWC3_LLUCTL(i), reg); + dwc3_writel(dwc, DWC3_LLUCTL(i), reg); } } @@ -1513,9 +1513,9 @@ int dwc3_core_init(struct dwc3 *dwc) * function is available only from version 1.70a. */ if (DWC3_VER_IS_WITHIN(DWC31, 170A, 180A)) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); + reg = dwc3_readl(dwc, DWC3_GUCTL3); reg |= DWC3_GUCTL3_USB20_RETRY_DISABLE; - dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); + dwc3_writel(dwc, DWC3_GUCTL3, reg); } return 0; @@ -2155,6 +2155,20 @@ static int dwc3_get_num_ports(struct dwc3 *dwc) return 0; } +static void dwc3_vbus_draw_work(struct work_struct *work) +{ + struct dwc3 *dwc = container_of(work, struct dwc3, vbus_draw_work); + union power_supply_propval val = {0}; + int ret; + + val.intval = 1000 * (dwc->current_limit); + ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); + + if (ret < 0) + dev_dbg(dwc->dev, "Error (%d) setting vbus draw (%d mA)\n", + ret, dwc->current_limit); +} + static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) { struct power_supply *usb_psy; @@ -2169,6 +2183,7 @@ static struct power_supply *dwc3_get_usb_power_supply(struct dwc3 *dwc) if (!usb_psy) return ERR_PTR(-EPROBE_DEFER); + INIT_WORK(&dwc->vbus_draw_work, dwc3_vbus_draw_work); return usb_psy; } @@ -2395,8 +2410,10 @@ void dwc3_core_remove(struct dwc3 *dwc) dwc3_free_event_buffers(dwc); - if (dwc->usb_psy) + if (dwc->usb_psy) { + cancel_work_sync(&dwc->vbus_draw_work); power_supply_put(dwc->usb_psy); + } } EXPORT_SYMBOL_GPL(dwc3_core_remove); @@ -2439,9 +2456,9 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) int ret; if (!pm_runtime_suspended(dwc->dev) && !PMSG_IS_AUTO(msg)) { - dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & + dwc->susphy_state = (dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)) & DWC3_GUSB2PHYCFG_SUSPHY) || - (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & + (dwc3_readl(dwc, DWC3_GUSB3PIPECTL(0)) & DWC3_GUSB3PIPECTL_SUSPHY); /* * TI AM62 platform requires SUSPHY to be @@ -2471,10 +2488,10 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) if (dwc->dis_u2_susphy_quirk || dwc->dis_enblslpm_quirk) { for (i = 0; i < dwc->num_usb2_ports; i++) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i)); reg |= DWC3_GUSB2PHYCFG_ENBLSLPM | DWC3_GUSB2PHYCFG_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg); } /* Give some time for USB2 PHY to suspend */ @@ -2534,14 +2551,14 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) } /* Restore GUSB2PHYCFG bits that were modified in suspend */ for (i = 0; i < dwc->num_usb2_ports; i++) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(i)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(i)); if (dwc->dis_u2_susphy_quirk) reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; if (dwc->dis_enblslpm_quirk) reg &= ~DWC3_GUSB2PHYCFG_ENBLSLPM; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(i), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(i), reg); } for (i = 0; i < dwc->num_usb2_ports; i++) @@ -2723,9 +2740,9 @@ void dwc3_pm_complete(struct dwc3 *dwc) if (dwc->current_dr_role == DWC3_GCTL_PRTCAP_HOST && dwc->dis_split_quirk) { - reg = dwc3_readl(dwc->regs, DWC3_GUCTL3); + reg = dwc3_readl(dwc, DWC3_GUCTL3); reg |= DWC3_GUCTL3_SPLITDISABLE; - dwc3_writel(dwc->regs, DWC3_GUCTL3, reg); + dwc3_writel(dwc, DWC3_GUCTL3, reg); } } EXPORT_SYMBOL_GPL(dwc3_pm_complete); diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index 45757169b672..a35b3db1f9f3 100644 --- a/drivers/usb/dwc3/core.h +++ b/drivers/usb/dwc3/core.h @@ -165,10 +165,10 @@ #define DWC3_DCFG1 0xc740 /* DWC_usb32 only */ #define DWC3_DEP_BASE(n) (0xc800 + ((n) * 0x10)) -#define DWC3_DEPCMDPAR2 0x00 -#define DWC3_DEPCMDPAR1 0x04 -#define DWC3_DEPCMDPAR0 0x08 -#define DWC3_DEPCMD 0x0c +#define DWC3_DEPCMDPAR2(n) (DWC3_DEP_BASE(n) + 0x00) +#define DWC3_DEPCMDPAR1(n) (DWC3_DEP_BASE(n) + 0x04) +#define DWC3_DEPCMDPAR0(n) (DWC3_DEP_BASE(n) + 0x08) +#define DWC3_DEPCMD(n) (DWC3_DEP_BASE(n) + 0x0c) #define DWC3_DEV_IMOD(n) (0xca00 + ((n) * 0x4)) @@ -749,8 +749,6 @@ struct dwc3_ep { struct list_head pending_list; struct list_head started_list; - void __iomem *regs; - struct dwc3_trb *trb_pool; dma_addr_t trb_pool_dma; struct dwc3 *dwc; @@ -1060,6 +1058,8 @@ struct dwc3_glue_ops { * @role_switch_default_mode: default operation mode of controller while * usb role is USB_ROLE_NONE. * @usb_psy: pointer to power supply interface. + * @vbus_draw_work: Work to set the vbus drawing limit + * @current_limit: How much current to draw from vbus, in milliAmperes. * @usb2_phy: pointer to USB2 PHY * @usb3_phy: pointer to USB3 PHY * @usb2_generic_phy: pointer to array of USB2 PHYs @@ -1246,6 +1246,8 @@ struct dwc3 { enum usb_dr_mode role_switch_default_mode; struct power_supply *usb_psy; + struct work_struct vbus_draw_work; + unsigned int current_limit; u32 fladj; u32 ref_clk_per; diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index d18bf5e32cc8..65d909e4b785 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -36,23 +36,19 @@ #define dump_ep_register_set(n) \ { \ .name = "DEPCMDPAR2("__stringify(n)")", \ - .offset = DWC3_DEP_BASE(n) + \ - DWC3_DEPCMDPAR2, \ + .offset = DWC3_DEPCMDPAR2(n), \ }, \ { \ .name = "DEPCMDPAR1("__stringify(n)")", \ - .offset = DWC3_DEP_BASE(n) + \ - DWC3_DEPCMDPAR1, \ + .offset = DWC3_DEPCMDPAR1(n), \ }, \ { \ .name = "DEPCMDPAR0("__stringify(n)")", \ - .offset = DWC3_DEP_BASE(n) + \ - DWC3_DEPCMDPAR0, \ + .offset = DWC3_DEPCMDPAR0(n), \ }, \ { \ .name = "DEPCMD("__stringify(n)")", \ - .offset = DWC3_DEP_BASE(n) + \ - DWC3_DEPCMD, \ + .offset = DWC3_DEPCMD(n), \ } @@ -300,14 +296,14 @@ static void dwc3_host_lsp(struct seq_file *s) reg = DWC3_GDBGLSPMUX_HOSTSELECT(sel); - dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); - val = dwc3_readl(dwc->regs, DWC3_GDBGLSP); + dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg); + val = dwc3_readl(dwc, DWC3_GDBGLSP); seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", sel, val); if (dbc_enabled && sel < 256) { reg |= DWC3_GDBGLSPMUX_ENDBC; - dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); - val = dwc3_readl(dwc->regs, DWC3_GDBGLSP); + dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg); + val = dwc3_readl(dwc, DWC3_GDBGLSP); seq_printf(s, "GDBGLSP_DBC[%d] = 0x%08x\n", sel, val); } } @@ -320,8 +316,8 @@ static void dwc3_gadget_lsp(struct seq_file *s) for (i = 0; i < 16; i++) { reg = DWC3_GDBGLSPMUX_DEVSELECT(i); - dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); - reg = dwc3_readl(dwc->regs, DWC3_GDBGLSP); + dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg); + reg = dwc3_readl(dwc, DWC3_GDBGLSP); seq_printf(s, "GDBGLSP[%d] = 0x%08x\n", i, reg); } } @@ -339,7 +335,7 @@ static int dwc3_lsp_show(struct seq_file *s, void *unused) return ret; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_GSTS); + reg = dwc3_readl(dwc, DWC3_GSTS); current_mode = DWC3_GSTS_CURMOD(reg); switch (current_mode) { @@ -410,7 +406,7 @@ static int dwc3_mode_show(struct seq_file *s, void *unused) return ret; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); spin_unlock_irqrestore(&dwc->lock, flags); mode = DWC3_GCTL_PRTCAP(reg); @@ -482,7 +478,7 @@ static int dwc3_testmode_show(struct seq_file *s, void *unused) return ret; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= DWC3_DCTL_TSTCTRL_MASK; reg >>= 1; spin_unlock_irqrestore(&dwc->lock, flags); @@ -581,7 +577,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) return ret; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_GSTS); + reg = dwc3_readl(dwc, DWC3_GSTS); if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { seq_puts(s, "Not available\n"); spin_unlock_irqrestore(&dwc->lock, flags); @@ -589,7 +585,7 @@ static int dwc3_link_state_show(struct seq_file *s, void *unused) return 0; } - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); state = DWC3_DSTS_USBLNKST(reg); speed = reg & DWC3_DSTS_CONNECTSPD; @@ -643,14 +639,14 @@ static ssize_t dwc3_link_state_write(struct file *file, return ret; spin_lock_irqsave(&dwc->lock, flags); - reg = dwc3_readl(dwc->regs, DWC3_GSTS); + reg = dwc3_readl(dwc, DWC3_GSTS); if (DWC3_GSTS_CURMOD(reg) != DWC3_GSTS_CURMOD_DEVICE) { spin_unlock_irqrestore(&dwc->lock, flags); pm_runtime_put_sync(dwc->dev); return -EINVAL; } - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); speed = reg & DWC3_DSTS_CONNECTSPD; if (speed < DWC3_DSTS_SUPERSPEED && @@ -946,10 +942,10 @@ static int dwc3_ep_info_register_show(struct seq_file *s, void *unused) spin_lock_irqsave(&dwc->lock, flags); reg = DWC3_GDBGLSPMUX_EPSELECT(dep->number); - dwc3_writel(dwc->regs, DWC3_GDBGLSPMUX, reg); + dwc3_writel(dwc, DWC3_GDBGLSPMUX, reg); - lower_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO0); - upper_32_bits = dwc3_readl(dwc->regs, DWC3_GDBGEPINFO1); + lower_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO0); + upper_32_bits = dwc3_readl(dwc, DWC3_GDBGEPINFO1); ep_info = ((u64)upper_32_bits << 32) | lower_32_bits; seq_printf(s, "0x%016llx\n", ep_info); @@ -1007,7 +1003,7 @@ void dwc3_debugfs_init(struct dwc3 *dwc) { struct dentry *root; - dwc->regset = kzalloc(sizeof(*dwc->regset), GFP_KERNEL); + dwc->regset = kzalloc_obj(*dwc->regset); if (!dwc->regset) return; diff --git a/drivers/usb/dwc3/drd.c b/drivers/usb/dwc3/drd.c index 589bbeb27454..f3e37d383627 100644 --- a/drivers/usb/dwc3/drd.c +++ b/drivers/usb/dwc3/drd.c @@ -18,25 +18,25 @@ static void dwc3_otg_disable_events(struct dwc3 *dwc, u32 disable_mask) { - u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN); + u32 reg = dwc3_readl(dwc, DWC3_OEVTEN); reg &= ~(disable_mask); - dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); + dwc3_writel(dwc, DWC3_OEVTEN, reg); } static void dwc3_otg_enable_events(struct dwc3 *dwc, u32 enable_mask) { - u32 reg = dwc3_readl(dwc->regs, DWC3_OEVTEN); + u32 reg = dwc3_readl(dwc, DWC3_OEVTEN); reg |= (enable_mask); - dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); + dwc3_writel(dwc, DWC3_OEVTEN, reg); } static void dwc3_otg_clear_events(struct dwc3 *dwc) { - u32 reg = dwc3_readl(dwc->regs, DWC3_OEVT); + u32 reg = dwc3_readl(dwc, DWC3_OEVT); - dwc3_writel(dwc->regs, DWC3_OEVTEN, reg); + dwc3_writel(dwc, DWC3_OEVTEN, reg); } #define DWC3_OTG_ALL_EVENTS (DWC3_OEVTEN_XHCIRUNSTPSETEN | \ @@ -72,18 +72,18 @@ static irqreturn_t dwc3_otg_irq(int irq, void *_dwc) struct dwc3 *dwc = _dwc; irqreturn_t ret = IRQ_NONE; - reg = dwc3_readl(dwc->regs, DWC3_OEVT); + reg = dwc3_readl(dwc, DWC3_OEVT); if (reg) { /* ignore non OTG events, we can't disable them in OEVTEN */ if (!(reg & DWC3_OTG_ALL_EVENTS)) { - dwc3_writel(dwc->regs, DWC3_OEVT, reg); + dwc3_writel(dwc, DWC3_OEVT, reg); return IRQ_NONE; } if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST && !(reg & DWC3_OEVT_DEVICEMODE)) dwc->otg_restart_host = true; - dwc3_writel(dwc->regs, DWC3_OEVT, reg); + dwc3_writel(dwc, DWC3_OEVT, reg); ret = IRQ_WAKE_THREAD; } @@ -100,23 +100,23 @@ static void dwc3_otgregs_init(struct dwc3 *dwc) * the signal outputs sent to the PHY, the OTG FSM logic of the * core and also the resets to the VBUS filters inside the core. */ - reg = dwc3_readl(dwc->regs, DWC3_OCFG); + reg = dwc3_readl(dwc, DWC3_OCFG); reg |= DWC3_OCFG_SFTRSTMASK; - dwc3_writel(dwc->regs, DWC3_OCFG, reg); + dwc3_writel(dwc, DWC3_OCFG, reg); /* Disable hibernation for simplicity */ - reg = dwc3_readl(dwc->regs, DWC3_GCTL); + reg = dwc3_readl(dwc, DWC3_GCTL); reg &= ~DWC3_GCTL_GBLHIBERNATIONEN; - dwc3_writel(dwc->regs, DWC3_GCTL, reg); + dwc3_writel(dwc, DWC3_GCTL, reg); /* * Initialize OTG registers as per * Figure 11-4 OTG Driver Overall Programming Flow */ /* OCFG.SRPCap = 0, OCFG.HNPCap = 0 */ - reg = dwc3_readl(dwc->regs, DWC3_OCFG); + reg = dwc3_readl(dwc, DWC3_OCFG); reg &= ~(DWC3_OCFG_SRPCAP | DWC3_OCFG_HNPCAP); - dwc3_writel(dwc->regs, DWC3_OCFG, reg); + dwc3_writel(dwc, DWC3_OCFG, reg); /* OEVT = FFFF */ dwc3_otg_clear_events(dwc); /* OEVTEN = 0 */ @@ -127,11 +127,11 @@ static void dwc3_otgregs_init(struct dwc3 *dwc) * OCTL.PeriMode = 1, OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0, * OCTL.HNPReq = 0 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg |= DWC3_OCTL_PERIMODE; reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_HNPREQ); - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); } static int dwc3_otg_get_irq(struct dwc3 *dwc) @@ -175,9 +175,9 @@ void dwc3_otg_init(struct dwc3 *dwc) /* GCTL.PrtCapDir=2'b11 */ dwc3_set_prtcap(dwc, DWC3_GCTL_PRTCAP_OTG, true); /* GUSB2PHYCFG0.SusPHY=0 */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); /* Initialize OTG registers */ dwc3_otgregs_init(dwc); @@ -203,17 +203,17 @@ void dwc3_otg_host_init(struct dwc3 *dwc) * OCTL.PeriMode=0, OCTL.TermSelDLPulse = 0, * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg &= ~(DWC3_OCTL_PERIMODE | DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN); - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); /* * OCFG.DisPrtPwrCutoff = 0/1 */ - reg = dwc3_readl(dwc->regs, DWC3_OCFG); + reg = dwc3_readl(dwc, DWC3_OCFG); reg &= ~DWC3_OCFG_DISPWRCUTTOFF; - dwc3_writel(dwc->regs, DWC3_OCFG, reg); + dwc3_writel(dwc, DWC3_OCFG, reg); /* * OCFG.SRPCap = 1, OCFG.HNPCap = GHWPARAMS6.HNP_CAP @@ -229,15 +229,15 @@ void dwc3_otg_host_init(struct dwc3 *dwc) /* GUSB2PHYCFG.ULPIAutoRes = 1/0, GUSB2PHYCFG.SusPHY = 1 */ if (!dwc->dis_u2_susphy_quirk) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); } /* Set Port Power to enable VBUS: OCTL.PrtPwrCtl = 1 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg |= DWC3_OCTL_PRTPWRCTL; - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); } /* should be called after Host controller driver is stopped */ @@ -258,9 +258,9 @@ static void dwc3_otg_host_exit(struct dwc3 *dwc) */ /* OCTL.HstSetHNPEn = 0, OCTL.PrtPwrCtl=0 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg &= ~(DWC3_OCTL_HSTSETHNPEN | DWC3_OCTL_PRTPWRCTL); - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); } /* should be called before the gadget controller driver is started */ @@ -274,27 +274,27 @@ static void dwc3_otg_device_init(struct dwc3 *dwc) * OCFG.HNPCap = GHWPARAMS6.HNP_CAP, OCFG.SRPCap = 1 * but we keep them 0 for simple dual-role operation. */ - reg = dwc3_readl(dwc->regs, DWC3_OCFG); + reg = dwc3_readl(dwc, DWC3_OCFG); /* OCFG.OTGSftRstMsk = 0/1 */ reg |= DWC3_OCFG_SFTRSTMASK; - dwc3_writel(dwc->regs, DWC3_OCFG, reg); + dwc3_writel(dwc, DWC3_OCFG, reg); /* * OCTL.PeriMode = 1 * OCTL.TermSelDLPulse = 0/1, OCTL.HNPReq = 0 * OCTL.DevSetHNPEn = 0, OCTL.HstSetHNPEn = 0 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg |= DWC3_OCTL_PERIMODE; reg &= ~(DWC3_OCTL_TERMSELIDPULSE | DWC3_OCTL_HNPREQ | DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HSTSETHNPEN); - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); /* OEVTEN.OTGBDevSesVldDetEvntEn = 1 */ dwc3_otg_enable_events(dwc, DWC3_OEVTEN_BDEVSESSVLDDETEN); /* GUSB2PHYCFG.ULPIAutoRes = 0, GUSB2PHYCFG0.SusPHY = 1 */ if (!dwc->dis_u2_susphy_quirk) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); reg |= DWC3_GUSB2PHYCFG_SUSPHY; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); } /* GCTL.GblHibernationEn = 0. Already 0. */ } @@ -319,10 +319,10 @@ static void dwc3_otg_device_exit(struct dwc3 *dwc) DWC3_OEVTEN_BDEVBHOSTENDEN); /* OCTL.DevSetHNPEn = 0, OCTL.HNPReq = 0, OCTL.PeriMode=1 */ - reg = dwc3_readl(dwc->regs, DWC3_OCTL); + reg = dwc3_readl(dwc, DWC3_OCTL); reg &= ~(DWC3_OCTL_DEVSETHNPEN | DWC3_OCTL_HNPREQ); reg |= DWC3_OCTL_PERIMODE; - dwc3_writel(dwc->regs, DWC3_OCTL, reg); + dwc3_writel(dwc, DWC3_OCTL, reg); } void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) @@ -341,7 +341,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) return; if (!ignore_idstatus) { - reg = dwc3_readl(dwc->regs, DWC3_OSTS); + reg = dwc3_readl(dwc, DWC3_OSTS); id = !!(reg & DWC3_OSTS_CONIDSTS); dwc->desired_otg_role = id ? DWC3_OTG_ROLE_DEVICE : @@ -381,6 +381,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) dwc3_otgregs_init(dwc); dwc3_otg_host_init(dwc); spin_unlock_irqrestore(&dwc->lock, flags); + dwc3_pre_set_role(dwc, USB_ROLE_HOST); ret = dwc3_host_init(dwc); if (ret) { dev_err(dwc->dev, "failed to initialize host\n"); @@ -406,6 +407,7 @@ void dwc3_otg_update(struct dwc3 *dwc, bool ignore_idstatus) otg_set_vbus(dwc->usb2_phy->otg, false); if (dwc->usb2_generic_phy[0]) phy_set_mode(dwc->usb2_generic_phy[0], PHY_MODE_USB_DEVICE); + dwc3_pre_set_role(dwc, USB_ROLE_DEVICE); ret = dwc3_gadget_init(dwc); if (ret) dev_err(dwc->dev, "failed to initialize peripheral\n"); @@ -433,10 +435,12 @@ static int dwc3_drd_notifier(struct notifier_block *nb, unsigned long event, void *ptr) { struct dwc3 *dwc = container_of(nb, struct dwc3, edev_nb); + u32 mode = event ? DWC3_GCTL_PRTCAP_HOST : DWC3_GCTL_PRTCAP_DEVICE; + enum usb_role role = mode == DWC3_GCTL_PRTCAP_HOST ? + USB_ROLE_HOST : USB_ROLE_DEVICE; - dwc3_set_mode(dwc, event ? - DWC3_GCTL_PRTCAP_HOST : - DWC3_GCTL_PRTCAP_DEVICE); + dwc3_pre_set_role(dwc, role); + dwc3_set_mode(dwc, mode); return NOTIFY_DONE; } diff --git a/drivers/usb/dwc3/dwc3-google.c b/drivers/usb/dwc3/dwc3-google.c new file mode 100644 index 000000000000..2105c72af753 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-google.c @@ -0,0 +1,626 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * dwc3-google.c - Google DWC3 Specific Glue Layer + * + * Copyright (c) 2025, Google LLC + * Author: Roy Luo + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "glue.h" + +/* HOST CFG registers */ +#define HC_STATUS_OFFSET 0x0 +#define HC_STATUS_CURRENT_POWER_STATE_U2PMU GENMASK(1, 0) +#define HC_STATUS_CURRENT_POWER_STATE_U3PMU GENMASK(4, 3) + +#define HOST_CFG1_OFFSET 0x4 +#define HOST_CFG1_PME_EN BIT(3) +#define HOST_CFG1_PM_POWER_STATE_REQUEST GENMASK(5, 4) +#define HOST_CFG1_PM_POWER_STATE_D0 0x0 +#define HOST_CFG1_PM_POWER_STATE_D3 0x3 + +/* USBINT registers */ +#define USBINT_CFG1_OFFSET 0x0 +#define USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK BIT(2) +#define USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK BIT(3) +#define USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN BIT(8) +#define USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN BIT(9) +#define USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR BIT(14) +#define USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR BIT(15) + +#define USBINT_STATUS_OFFSET 0x4 +#define USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW BIT(2) +#define USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW BIT(3) + +#define USBCS_TOP_CTRL_CFG1_OFFSET 0xc +#define USBCS_TOP_CTRL_CFG1_USB2ONLY_MODE BIT(5) + +#define DWC3_GOOGLE_MAX_RESETS 4 + +struct dwc3_google { + struct device *dev; + struct dwc3 dwc; + struct clk_bulk_data *clks; + int num_clks; + struct reset_control_bulk_data rsts[DWC3_GOOGLE_MAX_RESETS]; + int num_rsts; + struct reset_control *non_sticky_rst; + struct device *usb_psw_pd; + struct device_link *usb_psw_pd_dl; + struct notifier_block usb_psw_pd_nb; + struct device *usb_top_pd; + struct device_link *usb_top_pd_dl; + struct regmap *usb_cfg_regmap; + unsigned int host_cfg_offset; + unsigned int usbint_cfg_offset; + int hs_pme_irq; + int ss_pme_irq; + bool is_usb2only; + bool is_hibernation; +}; + +#define to_dwc3_google(d) container_of_const((d), struct dwc3_google, dwc) + +static int dwc3_google_rst_init(struct dwc3_google *google) +{ + int ret; + + google->num_rsts = 4; + google->rsts[0].id = "non_sticky"; + google->rsts[1].id = "sticky"; + google->rsts[2].id = "drd_bus"; + google->rsts[3].id = "top"; + + ret = devm_reset_control_bulk_get_exclusive(google->dev, + google->num_rsts, + google->rsts); + + if (ret < 0) + return ret; + + google->non_sticky_rst = google->rsts[0].rstc; + + return 0; +} + +static int dwc3_google_set_pmu_state(struct dwc3_google *google, int state) +{ + u32 reg; + int ret; + + regmap_read(google->usb_cfg_regmap, + google->host_cfg_offset + HOST_CFG1_OFFSET, ®); + + reg &= ~HOST_CFG1_PM_POWER_STATE_REQUEST; + reg |= (FIELD_PREP(HOST_CFG1_PM_POWER_STATE_REQUEST, state) | + HOST_CFG1_PME_EN); + regmap_write(google->usb_cfg_regmap, + google->host_cfg_offset + HOST_CFG1_OFFSET, reg); + + ret = regmap_read_poll_timeout(google->usb_cfg_regmap, + google->host_cfg_offset + HC_STATUS_OFFSET, reg, + (FIELD_GET(HC_STATUS_CURRENT_POWER_STATE_U2PMU, + reg) == state && + FIELD_GET(HC_STATUS_CURRENT_POWER_STATE_U3PMU, + reg) == state), + 10, 10000); + + if (ret) + dev_err(google->dev, "failed to set PMU state %d\n", state); + + return ret; +} + +/* + * Clear pme interrupts and report their status. + * The hardware requires write-1 then write-0 sequence to clear the interrupt bits. + */ +static u32 dwc3_google_clear_pme_irqs(struct dwc3_google *google) +{ + u32 irq_status, reg_set, reg_clear; + + regmap_read(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_STATUS_OFFSET, &irq_status); + + irq_status &= (USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW | + USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW); + if (!irq_status) + return irq_status; + + regmap_read(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, ®_set); + + reg_clear = reg_set; + if (irq_status & USBINT_STATUS_USBDRD_PME_GEN_U2P_INTR_STS_RAW) { + reg_set |= USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR; + reg_clear &= ~USBINT_CFG1_USBDRD_PME_GEN_U2_INTR_CLR; + } + if (irq_status & USBINT_STATUS_USBDRD_PME_GEN_U3P_INTR_STS_RAW) { + reg_set |= USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR; + reg_clear &= ~USBINT_CFG1_USBDRD_PME_GEN_U3_INTR_CLR; + } + + regmap_write(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg_set); + regmap_write(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg_clear); + + return irq_status; +} + +static void dwc3_google_enable_pme_irq(struct dwc3_google *google) +{ + u32 reg; + + regmap_read(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, ®); + reg &= ~(USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK | + USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK); + reg |= (USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN | + USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN); + regmap_write(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg); + + enable_irq(google->hs_pme_irq); + enable_irq(google->ss_pme_irq); + enable_irq_wake(google->hs_pme_irq); + enable_irq_wake(google->ss_pme_irq); +} + +static void dwc3_google_disable_pme_irq(struct dwc3_google *google) +{ + u32 reg; + + regmap_read(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, ®); + reg &= ~(USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_INT_EN | + USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_INT_EN); + reg |= (USBINT_CFG1_USBDRD_PME_GEN_U2P_INTR_MSK | + USBINT_CFG1_USBDRD_PME_GEN_U3P_INTR_MSK); + regmap_write(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBINT_CFG1_OFFSET, reg); + + disable_irq_wake(google->hs_pme_irq); + disable_irq_wake(google->ss_pme_irq); + disable_irq_nosync(google->hs_pme_irq); + disable_irq_nosync(google->ss_pme_irq); +} + +static irqreturn_t dwc3_google_resume_irq(int irq, void *data) +{ + struct dwc3_google *google = data; + struct dwc3 *dwc = &google->dwc; + u32 irq_status, dr_role; + + irq_status = dwc3_google_clear_pme_irqs(google); + dr_role = dwc->current_dr_role; + + if (!irq_status || !google->is_hibernation || + dr_role != DWC3_GCTL_PRTCAP_HOST) { + dev_dbg(google->dev, "spurious pme irq %d, hibernation %d, dr_role %u\n", + irq, google->is_hibernation, dr_role); + return IRQ_HANDLED; + } + + if (dwc->xhci) + pm_runtime_resume(&dwc->xhci->dev); + + return IRQ_HANDLED; +} + +static int dwc3_google_request_irq(struct dwc3_google *google, struct platform_device *pdev, + const char *irq_name, const char *req_name) +{ + int ret; + int irq; + + irq = platform_get_irq_byname(pdev, irq_name); + if (irq < 0) + return irq; + + irq_set_status_flags(irq, IRQ_NOAUTOEN); + ret = devm_request_threaded_irq(google->dev, irq, NULL, + dwc3_google_resume_irq, + IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + req_name, google); + if (ret < 0) { + dev_err(google->dev, "failed to request irq %s\n", req_name); + return ret; + } + + return irq; +} + +static int dwc3_google_usb_psw_pd_notifier(struct notifier_block *nb, unsigned long action, void *d) +{ + struct dwc3_google *google = container_of(nb, struct dwc3_google, usb_psw_pd_nb); + int ret; + + if (!google->is_hibernation) + return NOTIFY_OK; + + if (action == GENPD_NOTIFY_OFF) { + dev_dbg(google->dev, "enter D3 power state\n"); + dwc3_google_set_pmu_state(google, HOST_CFG1_PM_POWER_STATE_D3); + ret = reset_control_assert(google->non_sticky_rst); + if (ret) + dev_err(google->dev, "non sticky reset assert failed: %d\n", ret); + } else if (action == GENPD_NOTIFY_ON) { + dev_dbg(google->dev, "enter D0 power state\n"); + dwc3_google_clear_pme_irqs(google); + ret = reset_control_deassert(google->non_sticky_rst); + if (ret) + dev_err(google->dev, "non sticky reset deassert failed: %d\n", ret); + dwc3_google_set_pmu_state(google, HOST_CFG1_PM_POWER_STATE_D0); + } + + return NOTIFY_OK; +} + +static void dwc3_google_pm_domain_deinit(struct dwc3_google *google) +{ + if (google->usb_top_pd_dl) + device_link_del(google->usb_top_pd_dl); + + if (!IS_ERR_OR_NULL(google->usb_top_pd)) { + device_set_wakeup_capable(google->usb_top_pd, false); + dev_pm_domain_detach(google->usb_top_pd, true); + } + + if (google->usb_psw_pd_dl) + device_link_del(google->usb_psw_pd_dl); + + if (!IS_ERR_OR_NULL(google->usb_psw_pd)) { + dev_pm_genpd_remove_notifier(google->usb_psw_pd); + dev_pm_domain_detach(google->usb_psw_pd, true); + } +} + +static int dwc3_google_pm_domain_init(struct dwc3_google *google) +{ + int ret; + + /* + * Establish PM RUNTIME link between dwc dev and its power domain usb_psw_pd, + * register notifier block to handle hibernation. + */ + google->usb_psw_pd = dev_pm_domain_attach_by_name(google->dev, "psw"); + if (IS_ERR_OR_NULL(google->usb_psw_pd)) { + dev_err(google->dev, "failed to get psw pd"); + ret = google->usb_psw_pd ? PTR_ERR(google->usb_psw_pd) : -ENODATA; + return ret; + } + + google->usb_psw_pd_nb.notifier_call = dwc3_google_usb_psw_pd_notifier; + ret = dev_pm_genpd_add_notifier(google->usb_psw_pd, &google->usb_psw_pd_nb); + if (ret) { + dev_err(google->dev, "failed to add psw pd notifier"); + goto err; + } + + google->usb_psw_pd_dl = device_link_add(google->dev, google->usb_psw_pd, + DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (!google->usb_psw_pd_dl) { + dev_err(google->usb_psw_pd, "failed to add device link"); + ret = -ENODEV; + goto err; + } + + /* + * usb_top_pd is the parent power domain of usb_psw_pd. Keeping usb_top_pd on + * while usb_psw_pd is off places the controller in a power-gated state, + * essential for hibernation. Acquire a handle to usb_top_pd and sets it as + * wakeup-capable to allow the domain to be left on during system suspend. + */ + google->usb_top_pd = dev_pm_domain_attach_by_name(google->dev, "top"); + if (IS_ERR_OR_NULL(google->usb_top_pd)) { + dev_err(google->dev, "failed to get top pd"); + ret = google->usb_top_pd ? PTR_ERR(google->usb_top_pd) : -ENODATA; + goto err; + } + device_set_wakeup_capable(google->usb_top_pd, true); + + google->usb_top_pd_dl = device_link_add(google->dev, google->usb_top_pd, + DL_FLAG_STATELESS); + if (!google->usb_top_pd_dl) { + dev_err(google->usb_top_pd, "failed to add device link"); + ret = -ENODEV; + goto err; + } + + return 0; + +err: + dwc3_google_pm_domain_deinit(google); + + return ret; +} + +static void dwc3_google_program_usb2only(struct dwc3_google *google) +{ + u32 reg; + + regmap_read(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBCS_TOP_CTRL_CFG1_OFFSET, ®); + reg |= USBCS_TOP_CTRL_CFG1_USB2ONLY_MODE; + regmap_write(google->usb_cfg_regmap, + google->usbint_cfg_offset + USBCS_TOP_CTRL_CFG1_OFFSET, reg); +} + +static int dwc3_google_probe(struct platform_device *pdev) +{ + struct dwc3_probe_data probe_data = {}; + struct device *dev = &pdev->dev; + struct dwc3_google *google; + struct resource *res; + int ret; + u32 args[2]; + + google = devm_kzalloc(&pdev->dev, sizeof(*google), GFP_KERNEL); + if (!google) + return -ENOMEM; + + google->dev = &pdev->dev; + + ret = dwc3_google_pm_domain_init(google); + if (ret < 0) + return dev_err_probe(dev, ret, "failed to init pdom\n"); + + google->usb_cfg_regmap = + syscon_regmap_lookup_by_phandle_args(dev->of_node, + "google,usb-cfg-csr", + ARRAY_SIZE(args), args); + if (IS_ERR(google->usb_cfg_regmap)) { + return dev_err_probe(dev, PTR_ERR(google->usb_cfg_regmap), + "invalid usb cfg csr\n"); + } + + google->host_cfg_offset = args[0]; + google->usbint_cfg_offset = args[1]; + + if (device_property_match_string(dev, "phy-names", "usb3-phy") < 0) { + google->is_usb2only = true; + dwc3_google_program_usb2only(google); + } + + ret = devm_clk_bulk_get_all_enabled(dev, &google->clks); + if (ret < 0) { + ret = dev_err_probe(dev, ret, "failed to get and enable clks\n"); + goto err_deinit_pdom; + } + google->num_clks = ret; + + ret = dwc3_google_rst_init(google); + if (ret) { + ret = dev_err_probe(dev, ret, "failed to get resets\n"); + goto err_deinit_pdom; + } + + ret = reset_control_bulk_deassert(google->num_rsts, google->rsts); + if (ret) { + ret = dev_err_probe(dev, ret, "failed to deassert rsts\n"); + goto err_deinit_pdom; + } + + ret = dwc3_google_request_irq(google, pdev, "hs_pme", "USB HS wakeup"); + if (ret < 0) { + ret = dev_err_probe(dev, ret, "failed to request hs pme irq"); + goto err_reset_assert; + } + google->hs_pme_irq = ret; + + ret = dwc3_google_request_irq(google, pdev, "ss_pme", "USB SS wakeup"); + if (ret < 0) { + ret = dev_err_probe(dev, ret, "failed to request ss pme irq"); + goto err_reset_assert; + } + google->ss_pme_irq = ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = dev_err_probe(dev, -ENODEV, "invalid memory\n"); + goto err_reset_assert; + } + + device_init_wakeup(dev, true); + + google->dwc.dev = dev; + probe_data.dwc = &google->dwc; + probe_data.res = res; + probe_data.ignore_clocks_and_resets = true; + ret = dwc3_core_probe(&probe_data); + if (ret) { + ret = dev_err_probe(dev, ret, "failed to register DWC3 Core\n"); + goto err_reset_assert; + } + + return 0; + +err_reset_assert: + reset_control_bulk_assert(google->num_rsts, google->rsts); + +err_deinit_pdom: + dwc3_google_pm_domain_deinit(google); + + return ret; +} + +static void dwc3_google_remove(struct platform_device *pdev) +{ + struct dwc3 *dwc = platform_get_drvdata(pdev); + struct dwc3_google *google = to_dwc3_google(dwc); + + dwc3_core_remove(&google->dwc); + + reset_control_bulk_assert(google->num_rsts, google->rsts); + + dwc3_google_pm_domain_deinit(google); +} + +static int dwc3_google_suspend(struct dwc3_google *google, pm_message_t msg) +{ + if (pm_runtime_suspended(google->dev)) + return 0; + + if (google->dwc.current_dr_role == DWC3_GCTL_PRTCAP_HOST) { + /* + * Follow dwc3_suspend_common() guidelines for deciding between + * a full teardown and hibernation. + */ + if (PMSG_IS_AUTO(msg) || device_may_wakeup(google->dev)) { + dev_dbg(google->dev, "enter hibernation"); + pm_runtime_get_sync(google->usb_top_pd); + device_wakeup_enable(google->usb_top_pd); + dwc3_google_enable_pme_irq(google); + google->is_hibernation = true; + return 0; + } + } + + reset_control_bulk_assert(google->num_rsts, google->rsts); + clk_bulk_disable_unprepare(google->num_clks, google->clks); + + return 0; +} + +static int dwc3_google_resume(struct dwc3_google *google, pm_message_t msg) +{ + int ret; + + if (google->is_hibernation) { + dev_dbg(google->dev, "exit hibernation"); + dwc3_google_disable_pme_irq(google); + device_wakeup_disable(google->usb_top_pd); + pm_runtime_put_sync(google->usb_top_pd); + google->is_hibernation = false; + return 0; + } + + if (google->is_usb2only) + dwc3_google_program_usb2only(google); + + ret = clk_bulk_prepare_enable(google->num_clks, google->clks); + if (ret) + return ret; + + ret = reset_control_bulk_deassert(google->num_rsts, google->rsts); + if (ret) { + clk_bulk_disable_unprepare(google->num_clks, google->clks); + return ret; + } + + return 0; +} + +static int dwc3_google_pm_suspend(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + struct dwc3_google *google = to_dwc3_google(dwc); + int ret; + + ret = dwc3_pm_suspend(&google->dwc); + if (ret) + return ret; + + return dwc3_google_suspend(google, PMSG_SUSPEND); +} + +static int dwc3_google_pm_resume(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + struct dwc3_google *google = to_dwc3_google(dwc); + int ret; + + ret = dwc3_google_resume(google, PMSG_RESUME); + if (ret) + return ret; + + return dwc3_pm_resume(&google->dwc); +} + +static void dwc3_google_complete(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + + dwc3_pm_complete(dwc); +} + +static int dwc3_google_prepare(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + + return dwc3_pm_prepare(dwc); +} + +static int dwc3_google_runtime_suspend(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + struct dwc3_google *google = to_dwc3_google(dwc); + int ret; + + ret = dwc3_runtime_suspend(&google->dwc); + if (ret) + return ret; + + return dwc3_google_suspend(google, PMSG_AUTO_SUSPEND); +} + +static int dwc3_google_runtime_resume(struct device *dev) +{ + struct dwc3 *dwc = dev_get_drvdata(dev); + struct dwc3_google *google = to_dwc3_google(dwc); + int ret; + + ret = dwc3_google_resume(google, PMSG_AUTO_RESUME); + if (ret) + return ret; + + return dwc3_runtime_resume(&google->dwc); +} + +static int dwc3_google_runtime_idle(struct device *dev) +{ + return dwc3_runtime_idle(dev_get_drvdata(dev)); +} + +static const struct dev_pm_ops dwc3_google_dev_pm_ops = { + SYSTEM_SLEEP_PM_OPS(dwc3_google_pm_suspend, dwc3_google_pm_resume) + RUNTIME_PM_OPS(dwc3_google_runtime_suspend, dwc3_google_runtime_resume, + dwc3_google_runtime_idle) + .complete = pm_sleep_ptr(dwc3_google_complete), + .prepare = pm_sleep_ptr(dwc3_google_prepare), +}; + +static const struct of_device_id dwc3_google_of_match[] = { + { .compatible = "google,lga-dwc3" }, + { } +}; +MODULE_DEVICE_TABLE(of, dwc3_google_of_match); + +static struct platform_driver dwc3_google_driver = { + .probe = dwc3_google_probe, + .remove = dwc3_google_remove, + .driver = { + .name = "dwc3-google", + .pm = pm_ptr(&dwc3_google_dev_pm_ops), + .of_match_table = dwc3_google_of_match, + }, +}; + +module_platform_driver(dwc3_google_driver); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("DesignWare DWC3 Google Glue Driver"); diff --git a/drivers/usb/dwc3/dwc3-imx8mp.c b/drivers/usb/dwc3/dwc3-imx8mp.c index 45c276a31d84..b3d7252bd910 100644 --- a/drivers/usb/dwc3/dwc3-imx8mp.c +++ b/drivers/usb/dwc3/dwc3-imx8mp.c @@ -51,7 +51,7 @@ struct dwc3_imx8mp { struct device *dev; - struct platform_device *dwc3; + struct platform_device *dwc3_pdev; void __iomem *hsio_blk_base; void __iomem *glue_base; struct clk *hsio_clk; @@ -100,7 +100,7 @@ static void imx8mp_configure_glue(struct dwc3_imx8mp *dwc3_imx) static void dwc3_imx8mp_wakeup_enable(struct dwc3_imx8mp *dwc3_imx, pm_message_t msg) { - struct dwc3 *dwc3 = platform_get_drvdata(dwc3_imx->dwc3); + struct dwc3 *dwc3 = platform_get_drvdata(dwc3_imx->dwc3_pdev); u32 val; if (!dwc3) @@ -142,7 +142,7 @@ static const struct software_node dwc3_imx8mp_swnode = { static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx) { struct dwc3_imx8mp *dwc3_imx = _dwc3_imx; - struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3); + struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3_pdev); if (!dwc3_imx->pm_suspended) return IRQ_HANDLED; @@ -158,11 +158,31 @@ static irqreturn_t dwc3_imx8mp_interrupt(int irq, void *_dwc3_imx) return IRQ_HANDLED; } +static void dwc3_imx_pre_set_role(struct dwc3 *dwc, enum usb_role role) +{ + if (role == USB_ROLE_HOST) + /* + * For xhci host, we need disable dwc core auto + * suspend, because during this auto suspend delay(5s), + * xhci host RUN_STOP is cleared and wakeup is not + * enabled, if device is inserted, xhci host can't + * response the connection. + */ + pm_runtime_dont_use_autosuspend(dwc->dev); + else + pm_runtime_use_autosuspend(dwc->dev); +} + +struct dwc3_glue_ops dwc3_imx_glue_ops = { + .pre_set_role = dwc3_imx_pre_set_role, +}; + static int dwc3_imx8mp_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *node = dev->of_node; struct dwc3_imx8mp *dwc3_imx; + struct dwc3 *dwc3; struct resource *res; int err, irq; @@ -233,13 +253,24 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev) goto remove_swnode; } - dwc3_imx->dwc3 = of_find_device_by_node(dwc3_np); - if (!dwc3_imx->dwc3) { + dwc3_imx->dwc3_pdev = of_find_device_by_node(dwc3_np); + if (!dwc3_imx->dwc3_pdev) { dev_err(dev, "failed to get dwc3 platform device\n"); err = -ENODEV; goto depopulate; } + dwc3 = platform_get_drvdata(dwc3_imx->dwc3_pdev); + if (!dwc3) { + err = dev_err_probe(dev, -EPROBE_DEFER, "failed to get dwc3 platform data\n"); + goto depopulate; + } + + dwc3->glue_ops = &dwc3_imx_glue_ops; + + if (dwc3->dr_mode == USB_DR_MODE_HOST) + pm_runtime_dont_use_autosuspend(dwc3->dev); + err = devm_request_threaded_irq(dev, irq, NULL, dwc3_imx8mp_interrupt, IRQF_ONESHOT, dev_name(dev), dwc3_imx); if (err) { @@ -253,7 +284,7 @@ static int dwc3_imx8mp_probe(struct platform_device *pdev) return 0; put_dwc3: - put_device(&dwc3_imx->dwc3->dev); + put_device(&dwc3_imx->dwc3_pdev->dev); depopulate: of_platform_depopulate(dev); remove_swnode: @@ -270,7 +301,7 @@ static void dwc3_imx8mp_remove(struct platform_device *pdev) struct dwc3_imx8mp *dwc3_imx = platform_get_drvdata(pdev); struct device *dev = &pdev->dev; - put_device(&dwc3_imx->dwc3->dev); + put_device(&dwc3_imx->dwc3_pdev->dev); pm_runtime_get_sync(dev); of_platform_depopulate(dev); @@ -296,7 +327,7 @@ static int dwc3_imx8mp_suspend(struct dwc3_imx8mp *dwc3_imx, pm_message_t msg) static int dwc3_imx8mp_resume(struct dwc3_imx8mp *dwc3_imx, pm_message_t msg) { - struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3); + struct dwc3 *dwc = platform_get_drvdata(dwc3_imx->dwc3_pdev); int ret = 0; if (!dwc3_imx->pm_suspended) diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 6ecadc81bd6b..6c1cbb722ca8 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -56,6 +56,7 @@ #define PCI_DEVICE_ID_INTEL_CNPH 0xa36e #define PCI_DEVICE_ID_INTEL_CNPV 0xa3b0 #define PCI_DEVICE_ID_INTEL_RPL 0xa70e +#define PCI_DEVICE_ID_INTEL_NVLH 0xd37f #define PCI_DEVICE_ID_INTEL_PTLH 0xe332 #define PCI_DEVICE_ID_INTEL_PTLH_PCH 0xe37e #define PCI_DEVICE_ID_INTEL_PTLU 0xe432 @@ -447,6 +448,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = { { PCI_DEVICE_DATA(INTEL, CNPH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, CNPV, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, RPL, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, NVLH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLH_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, PTLU, &dwc3_pci_intel_swnode) }, diff --git a/drivers/usb/dwc3/dwc3-xilinx.c b/drivers/usb/dwc3/dwc3-xilinx.c index 0a8c47876ff9..f41b0da5e89d 100644 --- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -132,21 +132,6 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) goto err; } - /* - * The following core resets are not required unless a USB3 PHY - * is used, and the subsequent register settings are not required - * unless a core reset is performed (they should be set properly - * by the first-stage boot loader, but may be reverted by a core - * reset). They may also break the configuration if USB3 is actually - * in use but the usb3-phy entry is missing from the device tree. - * Therefore, skip these operations in this case. - */ - if (!priv_data->usb3_phy) { - /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */ - writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK); - goto skip_usb3_phy; - } - crst = devm_reset_control_get_exclusive(dev, "usb_crst"); if (IS_ERR(crst)) { ret = PTR_ERR(crst); @@ -171,22 +156,31 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) goto err; } - ret = reset_control_assert(crst); - if (ret < 0) { - dev_err(dev, "Failed to assert core reset\n"); - goto err; - } + /* + * Asserting the core resets is not required unless a USB3 PHY is used. + * They may also break the configuration if USB3 is actually in use but + * the usb3-phy entry is missing from the device tree. Therefore, skip + * a full reset cycle and just deassert the resets if the phy is + * absent. + */ + if (priv_data->usb3_phy) { + ret = reset_control_assert(crst); + if (ret < 0) { + dev_err(dev, "Failed to assert core reset\n"); + goto err; + } - ret = reset_control_assert(hibrst); - if (ret < 0) { - dev_err(dev, "Failed to assert hibernation reset\n"); - goto err; - } + ret = reset_control_assert(hibrst); + if (ret < 0) { + dev_err(dev, "Failed to assert hibernation reset\n"); + goto err; + } - ret = reset_control_assert(apbrst); - if (ret < 0) { - dev_err(dev, "Failed to assert APB reset\n"); - goto err; + ret = reset_control_assert(apbrst); + if (ret < 0) { + dev_err(dev, "Failed to assert APB reset\n"); + goto err; + } } ret = phy_init(priv_data->usb3_phy); @@ -201,11 +195,15 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) goto err; } - /* Set PIPE Power Present signal in FPD Power Present Register*/ - writel(FPD_POWER_PRSNT_OPTION, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); - - /* Set the PIPE Clock Select bit in FPD PIPE Clock register */ - writel(PIPE_CLK_SELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK); + if (priv_data->usb3_phy) { + /* Set PIPE Power Present signal in FPD Power Present Register*/ + writel(FPD_POWER_PRSNT_OPTION, priv_data->regs + XLNX_USB_FPD_POWER_PRSNT); + /* Set the PIPE Clock Select bit in FPD PIPE Clock register */ + writel(PIPE_CLK_SELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK); + } else { + /* Deselect the PIPE Clock Select bit in FPD PIPE Clock register */ + writel(PIPE_CLK_DESELECT, priv_data->regs + XLNX_USB_FPD_PIPE_CLK); + } ret = reset_control_deassert(crst); if (ret < 0) { @@ -225,7 +223,6 @@ static int dwc3_xlnx_init_zynqmp(struct dwc3_xlnx *priv_data) goto err; } -skip_usb3_phy: /* ulpi reset via gpio-modepin or gpio-framework driver */ reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset_gpio)) { diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index e0bad5708664..bfe616194dfa 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -361,7 +361,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, if ((dwc->speed == DWC3_DSTS_SUPERSPEED) || (dwc->speed == DWC3_DSTS_SUPERSPEED_PLUS)) { - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (reg & DWC3_DCTL_INITU1ENA) usb_status |= 1 << USB_DEV_STAT_U1_ENABLED; if (reg & DWC3_DCTL_INITU2ENA) @@ -417,12 +417,12 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state, if (set && dwc->dis_u1_entry_quirk) return -EINVAL; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (set) reg |= DWC3_DCTL_INITU1ENA; else reg &= ~DWC3_DCTL_INITU1ENA; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); return 0; } @@ -441,12 +441,12 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state, if (set && dwc->dis_u2_entry_quirk) return -EINVAL; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (set) reg |= DWC3_DCTL_INITU2ENA; else reg &= ~DWC3_DCTL_INITU2ENA; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); return 0; } @@ -612,10 +612,10 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) return -EINVAL; } - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~(DWC3_DCFG_DEVADDR_MASK); reg |= DWC3_DCFG_DEVADDR(addr); - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); if (addr) usb_gadget_set_state(dwc->gadget, USB_STATE_ADDRESS); @@ -672,12 +672,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl) * Enable transition to U1/U2 state when * nothing is pending from application. */ - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (!dwc->dis_u1_entry_quirk) reg |= DWC3_DCTL_ACCEPTU1ENA; if (!dwc->dis_u2_entry_quirk) reg |= DWC3_DCTL_ACCEPTU2ENA; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); } break; @@ -717,7 +717,7 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req) dwc->u2sel = le16_to_cpu(timing.u2sel); dwc->u2pel = le16_to_cpu(timing.u2pel); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (reg & DWC3_DCTL_INITU2ENA) param = dwc->u2pel; if (reg & DWC3_DCTL_INITU1ENA) @@ -833,7 +833,7 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc, if (!dwc->gadget_driver || !dwc->softconnect || !dwc->connected) goto out; - trace_dwc3_ctrl_req(ctrl); + trace_dwc3_ctrl_req(dwc, ctrl); len = le16_to_cpu(ctrl->wLength); if (!len) { diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 8a35a6901db7..0a688904ce8c 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -42,7 +42,7 @@ int dwc3_gadget_set_test_mode(struct dwc3 *dwc, int mode) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; switch (mode) { @@ -73,7 +73,7 @@ int dwc3_gadget_get_link_state(struct dwc3 *dwc) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); return DWC3_DSTS_USBLNKST(reg); } @@ -97,7 +97,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) */ if (!DWC3_VER_IS_PRIOR(DWC3, 194A)) { while (--retries) { - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); if (reg & DWC3_DSTS_DCNRD) udelay(5); else @@ -108,15 +108,15 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) return -ETIMEDOUT; } - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; /* set no action before sending new link state change */ - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); /* set requested state */ reg |= DWC3_DCTL_ULSTCHNGREQ(state); - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); /* * The following code is racy when called from dwc3_gadget_wakeup, @@ -128,7 +128,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state) /* wait for a change in DSTS */ retries = 10000; while (--retries) { - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); if (DWC3_DSTS_USBLNKST(reg) == state) return 0; @@ -260,11 +260,11 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd, int ret = 0; u32 reg; - dwc3_writel(dwc->regs, DWC3_DGCMDPAR, param); - dwc3_writel(dwc->regs, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); + dwc3_writel(dwc, DWC3_DGCMDPAR, param); + dwc3_writel(dwc, DWC3_DGCMD, cmd | DWC3_DGCMD_CMDACT); do { - reg = dwc3_readl(dwc->regs, DWC3_DGCMD); + reg = dwc3_readl(dwc, DWC3_DGCMD); if (!(reg & DWC3_DGCMD_CMDACT)) { status = DWC3_DGCMD_STATUS(reg); if (status) @@ -278,7 +278,7 @@ int dwc3_send_gadget_generic_command(struct dwc3 *dwc, unsigned int cmd, status = -ETIMEDOUT; } - trace_dwc3_gadget_generic_cmd(cmd, param, status); + trace_dwc3_gadget_generic_cmd(dwc, cmd, param, status); return ret; } @@ -320,6 +320,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, int cmd_status = 0; int ret = -EINVAL; + u8 epnum = dep->number; /* * When operating in USB 2.0 speeds (HS/FS), if GUSB2PHYCFG.ENBLSLPM or @@ -333,7 +334,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, */ if (dwc->gadget->speed <= USB_SPEED_HIGH || DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); if (unlikely(reg & DWC3_GUSB2PHYCFG_SUSPHY)) { saved_config |= DWC3_GUSB2PHYCFG_SUSPHY; reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; @@ -345,7 +346,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, } if (saved_config) - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); } /* @@ -355,9 +356,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, * improve performance. */ if (DWC3_DEPCMD_CMD(cmd) != DWC3_DEPCMD_UPDATETRANSFER) { - dwc3_writel(dep->regs, DWC3_DEPCMDPAR0, params->param0); - dwc3_writel(dep->regs, DWC3_DEPCMDPAR1, params->param1); - dwc3_writel(dep->regs, DWC3_DEPCMDPAR2, params->param2); + dwc3_writel(dwc, DWC3_DEPCMDPAR0(epnum), params->param0); + dwc3_writel(dwc, DWC3_DEPCMDPAR1(epnum), params->param1); + dwc3_writel(dwc, DWC3_DEPCMDPAR2(epnum), params->param2); } /* @@ -381,7 +382,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, else cmd |= DWC3_DEPCMD_CMDACT; - dwc3_writel(dep->regs, DWC3_DEPCMD, cmd); + dwc3_writel(dwc, DWC3_DEPCMD(epnum), cmd); if (!(cmd & DWC3_DEPCMD_CMDACT) || (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && @@ -391,7 +392,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, } do { - reg = dwc3_readl(dep->regs, DWC3_DEPCMD); + reg = dwc3_readl(dwc, DWC3_DEPCMD(epnum)); if (!(reg & DWC3_DEPCMD_CMDACT)) { cmd_status = DWC3_DEPCMD_STATUS(reg); @@ -447,9 +448,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, mdelay(1); if (saved_config) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); reg |= saved_config; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); } return ret; @@ -726,7 +727,7 @@ static int dwc3_gadget_calc_ram_depth(struct dwc3 *dwc) u32 reg; /* Check if TXFIFOs start at non-zero addr */ - reg = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + reg = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0)); fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(reg); ram_depth -= (fifo_0_start >> 16); @@ -754,7 +755,7 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) /* Read ep0IN related TXFIFO size */ dep = dwc->eps[1]; - size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0)); if (DWC3_IP_IS(DWC3)) fifo_depth = DWC3_GTXFIFOSIZ_TXFDEP(size); else @@ -769,10 +770,10 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc) /* Don't change TXFRAMNUM on usb31 version */ size = DWC3_IP_IS(DWC3) ? 0 : - dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) & + dwc3_readl(dwc, DWC3_GTXFIFOSIZ(num >> 1)) & DWC31_GTXFIFOSIZ_TXFRAMNUM; - dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1), size); + dwc3_writel(dwc, DWC3_GTXFIFOSIZ(num >> 1), size); dep->flags &= ~DWC3_EP_TXFIFO_RESIZED; } dwc->num_ep_resized = 0; @@ -875,7 +876,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) fifo_size++; /* Check if TXFIFOs start at non-zero addr */ - tmp = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(0)); + tmp = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(0)); fifo_0_start = DWC3_GTXFIFOSIZ_TXFSTADDR(tmp); fifo_size |= (fifo_0_start + (dwc->last_fifo_depth << 16)); @@ -898,7 +899,7 @@ static int dwc3_gadget_resize_tx_fifos(struct dwc3_ep *dep) return -ENOMEM; } - dwc3_writel(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size); + dwc3_writel(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1), fifo_size); dep->flags |= DWC3_EP_TXFIFO_RESIZED; dwc->num_ep_resized++; @@ -942,9 +943,9 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action) dep->type = usb_endpoint_type(desc); dep->flags |= DWC3_EP_ENABLED; - reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); + reg = dwc3_readl(dwc, DWC3_DALEPENA); reg |= DWC3_DALEPENA_EP(dep->number); - dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + dwc3_writel(dwc, DWC3_DALEPENA, reg); dep->trb_dequeue = 0; dep->trb_enqueue = 0; @@ -1079,9 +1080,9 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep) if (dep->flags & DWC3_EP_STALL) __dwc3_gadget_ep_set_halt(dep, 0, false); - reg = dwc3_readl(dwc->regs, DWC3_DALEPENA); + reg = dwc3_readl(dwc, DWC3_DALEPENA); reg &= ~DWC3_DALEPENA_EP(dep->number); - dwc3_writel(dwc->regs, DWC3_DALEPENA, reg); + dwc3_writel(dwc, DWC3_DALEPENA, reg); dwc3_remove_requests(dwc, dep, -ESHUTDOWN); @@ -1187,7 +1188,7 @@ static struct usb_request *dwc3_gadget_ep_alloc_request(struct usb_ep *ep, struct dwc3_request *req; struct dwc3_ep *dep = to_dwc3_ep(ep); - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -1742,7 +1743,7 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc) { u32 reg; - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); return DWC3_DSTS_SOFFN(reg); } @@ -2350,13 +2351,13 @@ static void dwc3_gadget_enable_linksts_evts(struct dwc3 *dwc, bool set) if (DWC3_VER_IS_PRIOR(DWC3, 250A)) return; - reg = dwc3_readl(dwc->regs, DWC3_DEVTEN); + reg = dwc3_readl(dwc, DWC3_DEVTEN); if (set) reg |= DWC3_DEVTEN_ULSTCNGEN; else reg &= ~DWC3_DEVTEN_ULSTCNGEN; - dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); + dwc3_writel(dwc, DWC3_DEVTEN, reg); } static int dwc3_gadget_get_frame(struct usb_gadget *g) @@ -2379,7 +2380,7 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) * * We can check that via USB Link State bits in DSTS register. */ - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); link_state = DWC3_DSTS_USBLNKST(reg); @@ -2407,9 +2408,9 @@ static int __dwc3_gadget_wakeup(struct dwc3 *dwc) /* Recent versions do this automatically */ if (DWC3_VER_IS_PRIOR(DWC3, 194A)) { /* write zeroes to Link Change Request */ - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); } /* @@ -2529,7 +2530,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc) if (ssp_rate == USB_SSP_GEN_UNKNOWN) ssp_rate = dwc->max_ssp_rate; - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~DWC3_DCFG_SPEED_MASK; reg &= ~DWC3_DCFG_NUMLANES(~0); @@ -2542,7 +2543,7 @@ static void __dwc3_gadget_set_ssp_rate(struct dwc3 *dwc) dwc->max_ssp_rate != USB_SSP_GEN_2x1) reg |= DWC3_DCFG_NUMLANES(1); - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); } static void __dwc3_gadget_set_speed(struct dwc3 *dwc) @@ -2560,7 +2561,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) return; } - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~(DWC3_DCFG_SPEED_MASK); /* @@ -2611,7 +2612,7 @@ static void __dwc3_gadget_set_speed(struct dwc3 *dwc) speed < USB_SPEED_SUPER_PLUS) reg &= ~DWC3_DCFG_NUMLANES(~0); - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); } static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) @@ -2636,7 +2637,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) * mentioned in the dwc3 programming guide. It has been tested on an * Exynos platforms. */ - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); if (reg & DWC3_GUSB2PHYCFG_SUSPHY) { saved_config |= DWC3_GUSB2PHYCFG_SUSPHY; reg &= ~DWC3_GUSB2PHYCFG_SUSPHY; @@ -2648,9 +2649,9 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) } if (saved_config) - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); if (is_on) { if (DWC3_VER_IS_WITHIN(DWC3, ANY, 187A)) { reg &= ~DWC3_DCTL_TRGTULST_MASK; @@ -2674,14 +2675,14 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on) do { usleep_range(1000, 2000); - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); reg &= DWC3_DSTS_DEVCTRLHLT; } while (--timeout && !(!is_on ^ !reg)); if (saved_config) { - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); reg |= saved_config; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYCFG(0), reg); } if (!timeout) @@ -2857,13 +2858,13 @@ static void dwc3_gadget_enable_irq(struct dwc3 *dwc) if (!DWC3_VER_IS_PRIOR(DWC3, 230A)) reg |= DWC3_DEVTEN_U3L2L1SUSPEN; - dwc3_writel(dwc->regs, DWC3_DEVTEN, reg); + dwc3_writel(dwc, DWC3_DEVTEN, reg); } static void dwc3_gadget_disable_irq(struct dwc3 *dwc) { /* mask all interrupts */ - dwc3_writel(dwc->regs, DWC3_DEVTEN, 0x00); + dwc3_writel(dwc, DWC3_DEVTEN, 0x00); } static irqreturn_t dwc3_interrupt(int irq, void *_dwc); @@ -2904,10 +2905,10 @@ static void dwc3_gadget_setup_nump(struct dwc3 *dwc) nump = min_t(u32, nump, 16); /* update NumP */ - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~DWC3_DCFG_NUMP_MASK; reg |= nump << DWC3_DCFG_NUMP_SHIFT; - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); } static int __dwc3_gadget_start(struct dwc3 *dwc) @@ -2921,10 +2922,10 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) * the core supports IMOD, disable it. */ if (dwc->imod_interval) { - dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB); + dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval); + dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB); } else if (dwc3_has_imod(dwc)) { - dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), 0); + dwc3_writel(dwc, DWC3_DEV_IMOD(0), 0); } /* @@ -2934,13 +2935,13 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) * This way, we maximize the chances that we'll be able to get several * bursts of data without going through any sort of endpoint throttling. */ - reg = dwc3_readl(dwc->regs, DWC3_GRXTHRCFG); + reg = dwc3_readl(dwc, DWC3_GRXTHRCFG); if (DWC3_IP_IS(DWC3)) reg &= ~DWC3_GRXTHRCFG_PKTCNTSEL; else reg &= ~DWC31_GRXTHRCFG_PKTCNTSEL; - dwc3_writel(dwc->regs, DWC3_GRXTHRCFG, reg); + dwc3_writel(dwc, DWC3_GRXTHRCFG, reg); dwc3_gadget_setup_nump(dwc); @@ -2951,15 +2952,15 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) * ACK with NumP=0 and PP=0 (for IN direction). This slightly improves * the stream performance. */ - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg |= DWC3_DCFG_IGNSTRMPP; - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); /* Enable MST by default if the device is capable of MST */ if (DWC3_MST_CAPABLE(&dwc->hwparams)) { - reg = dwc3_readl(dwc->regs, DWC3_DCFG1); + reg = dwc3_readl(dwc, DWC3_DCFG1); reg &= ~DWC3_DCFG1_DIS_MST_ENH; - dwc3_writel(dwc->regs, DWC3_DCFG1, reg); + dwc3_writel(dwc, DWC3_DCFG1, reg); } /* Start with SuperSpeed Default */ @@ -3123,8 +3124,6 @@ static void dwc3_gadget_set_ssp_rate(struct usb_gadget *g, static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) { struct dwc3 *dwc = gadget_to_dwc(g); - union power_supply_propval val = {0}; - int ret; if (dwc->usb2_phy) return usb_phy_set_power(dwc->usb2_phy, mA); @@ -3132,10 +3131,10 @@ static int dwc3_gadget_vbus_draw(struct usb_gadget *g, unsigned int mA) if (!dwc->usb_psy) return -EOPNOTSUPP; - val.intval = 1000 * mA; - ret = power_supply_set_property(dwc->usb_psy, POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, &val); + dwc->current_limit = mA; + schedule_work(&dwc->vbus_draw_work); - return ret; + return 0; } /** @@ -3239,7 +3238,7 @@ static int dwc3_gadget_init_in_endpoint(struct dwc3_ep *dep) /* MDWIDTH is represented in bits, we need it in bytes */ mdwidth /= 8; - size = dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(dep->number >> 1)); + size = dwc3_readl(dwc, DWC3_GTXFIFOSIZ(dep->number >> 1)); if (DWC3_IP_IS(DWC3)) size = DWC3_GTXFIFOSIZ_TXFDEP(size); else @@ -3288,7 +3287,7 @@ static int dwc3_gadget_init_out_endpoint(struct dwc3_ep *dep) mdwidth /= 8; /* All OUT endpoints share a single RxFIFO space */ - size = dwc3_readl(dwc->regs, DWC3_GRXFIFOSIZ(0)); + size = dwc3_readl(dwc, DWC3_GRXFIFOSIZ(0)); if (DWC3_IP_IS(DWC3)) size = DWC3_GRXFIFOSIZ_RXFDEP(size); else @@ -3374,14 +3373,13 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum) int ret; u8 num = epnum >> 1; - dep = kzalloc(sizeof(*dep), GFP_KERNEL); + dep = kzalloc_obj(*dep); if (!dep) return -ENOMEM; dep->dwc = dwc; dep->number = epnum; dep->direction = direction; - dep->regs = dwc->regs + DWC3_DEP_BASE(epnum); dwc->eps[epnum] = dep; dep->combo_num = 0; dep->start_cmd_status = 0; @@ -3742,9 +3740,9 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep, return no_started_trb; } - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg |= dwc->u1u2; - dwc3_writel(dwc->regs, DWC3_DCTL, reg); + dwc3_writel(dwc, DWC3_DCTL, reg); dwc->u1u2 = 0; } @@ -4074,7 +4072,7 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) dwc3_gadget_set_link_state(dwc, DWC3_LINK_STATE_RX_DET); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_INITU1ENA; reg &= ~DWC3_DCTL_INITU2ENA; dwc3_gadget_dctl_write_safe(dwc, reg); @@ -4163,7 +4161,7 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_stop_active_transfers(dwc); dwc->connected = true; - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_TSTCTRL_MASK; dwc3_gadget_dctl_write_safe(dwc, reg); dwc->test_mode = false; @@ -4172,9 +4170,9 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) dwc3_clear_stall_all_ep(dwc); /* Reset device address to zero */ - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~(DWC3_DCFG_DEVADDR_MASK); - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); } static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) @@ -4188,7 +4186,7 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) if (!dwc->softconnect) return; - reg = dwc3_readl(dwc->regs, DWC3_DSTS); + reg = dwc3_readl(dwc, DWC3_DSTS); speed = reg & DWC3_DSTS_CONNECTSPD; dwc->speed = speed; @@ -4263,11 +4261,11 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) !dwc->usb2_gadget_lpm_disable && (speed != DWC3_DSTS_SUPERSPEED) && (speed != DWC3_DSTS_SUPERSPEED_PLUS)) { - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg |= DWC3_DCFG_LPM_CAP; - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~(DWC3_DCTL_HIRD_THRES_MASK | DWC3_DCTL_L1_HIBER_EN); reg |= DWC3_DCTL_HIRD_THRES(dwc->hird_threshold | @@ -4290,12 +4288,12 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) dwc3_gadget_dctl_write_safe(dwc, reg); } else { if (dwc->usb2_gadget_lpm_disable) { - reg = dwc3_readl(dwc->regs, DWC3_DCFG); + reg = dwc3_readl(dwc, DWC3_DCFG); reg &= ~DWC3_DCFG_LPM_CAP; - dwc3_writel(dwc->regs, DWC3_DCFG, reg); + dwc3_writel(dwc, DWC3_DCFG, reg); } - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); reg &= ~DWC3_DCTL_HIRD_THRES_MASK; dwc3_gadget_dctl_write_safe(dwc, reg); } @@ -4401,7 +4399,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc, switch (dwc->link_state) { case DWC3_LINK_STATE_U1: case DWC3_LINK_STATE_U2: - reg = dwc3_readl(dwc->regs, DWC3_DCTL); + reg = dwc3_readl(dwc, DWC3_DCTL); u1u2 = reg & (DWC3_DCTL_INITU2ENA | DWC3_DCTL_ACCEPTU2ENA | DWC3_DCTL_INITU1ENA @@ -4558,7 +4556,7 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt) ret = IRQ_HANDLED; /* Unmask interrupt */ - dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), + dwc3_writel(dwc, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_SIZE(evt->length)); evt->flags &= ~DWC3_EVENT_PENDING; @@ -4569,8 +4567,8 @@ static irqreturn_t dwc3_process_event_buf(struct dwc3_event_buffer *evt) wmb(); if (dwc->imod_interval) { - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB); - dwc3_writel(dwc->regs, DWC3_DEV_IMOD(0), dwc->imod_interval); + dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), DWC3_GEVNTCOUNT_EHB); + dwc3_writel(dwc, DWC3_DEV_IMOD(0), dwc->imod_interval); } return ret; @@ -4619,7 +4617,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) if (evt->flags & DWC3_EVENT_PENDING) return IRQ_HANDLED; - count = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); + count = dwc3_readl(dwc, DWC3_GEVNTCOUNT(0)); count &= DWC3_GEVNTCOUNT_MASK; if (!count) return IRQ_NONE; @@ -4634,7 +4632,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) evt->flags |= DWC3_EVENT_PENDING; /* Mask interrupt */ - dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), + dwc3_writel(dwc, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK | DWC3_GEVNTSIZ_SIZE(evt->length)); amount = min(count, evt->length - evt->lpos); @@ -4643,7 +4641,7 @@ static irqreturn_t dwc3_check_event_buf(struct dwc3_event_buffer *evt) if (amount < count) memcpy(evt->cache, evt->buf, count - amount); - dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), count); + dwc3_writel(dwc, DWC3_GEVNTCOUNT(0), count); return IRQ_WAKE_THREAD; } @@ -4730,7 +4728,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) } init_completion(&dwc->ep0_in_setup); - dwc->gadget = kzalloc(sizeof(struct usb_gadget), GFP_KERNEL); + dwc->gadget = kzalloc_obj(struct usb_gadget); if (!dwc->gadget) { ret = -ENOMEM; goto err3; diff --git a/drivers/usb/dwc3/gadget.h b/drivers/usb/dwc3/gadget.h index d73e735e4081..45f113b3c146 100644 --- a/drivers/usb/dwc3/gadget.h +++ b/drivers/usb/dwc3/gadget.h @@ -132,7 +132,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep) { u32 res_id; - res_id = dwc3_readl(dep->regs, DWC3_DEPCMD); + res_id = dwc3_readl(dep->dwc, DWC3_DEPCMD(dep->number)); dep->resource_index = DWC3_DEPCMD_GET_RSC_IDX(res_id); } @@ -147,7 +147,7 @@ static inline void dwc3_gadget_ep_get_transfer_index(struct dwc3_ep *dep) static inline void dwc3_gadget_dctl_write_safe(struct dwc3 *dwc, u32 value) { value &= ~DWC3_DCTL_ULSTCHNGREQ_MASK; - dwc3_writel(dwc->regs, DWC3_DCTL, value); + dwc3_writel(dwc, DWC3_DCTL, value); } #endif /* __DRIVERS_USB_DWC3_GADGET_H */ diff --git a/drivers/usb/dwc3/io.h b/drivers/usb/dwc3/io.h index 1e96ea339d48..cad9a2ae1547 100644 --- a/drivers/usb/dwc3/io.h +++ b/drivers/usb/dwc3/io.h @@ -16,9 +16,10 @@ #include "debug.h" #include "core.h" -static inline u32 dwc3_readl(void __iomem *base, u32 offset) +static inline u32 dwc3_readl(struct dwc3 *dwc, u32 offset) { u32 value; + void __iomem *base = dwc->regs; /* * We requested the mem region starting from the Globals address @@ -32,13 +33,15 @@ static inline u32 dwc3_readl(void __iomem *base, u32 offset) * documentation, so we revert it back to the proper addresses, the * same way they are described on SNPS documentation */ - trace_dwc3_readl(base - DWC3_GLOBALS_REGS_START, offset, value); + trace_dwc3_readl(dwc, base - DWC3_GLOBALS_REGS_START, offset, value); return value; } -static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) +static inline void dwc3_writel(struct dwc3 *dwc, u32 offset, u32 value) { + void __iomem *base = dwc->regs; + /* * We requested the mem region starting from the Globals address * space, see dwc3_probe in core.c. @@ -51,7 +54,7 @@ static inline void dwc3_writel(void __iomem *base, u32 offset, u32 value) * documentation, so we revert it back to the proper addresses, the * same way they are described on SNPS documentation */ - trace_dwc3_writel(base - DWC3_GLOBALS_REGS_START, offset, value); + trace_dwc3_writel(dwc, base - DWC3_GLOBALS_REGS_START, offset, value); } #endif /* __DRIVERS_USB_DWC3_IO_H */ diff --git a/drivers/usb/dwc3/trace.h b/drivers/usb/dwc3/trace.h index b6ba984bafcd..5253da23d8b0 100644 --- a/drivers/usb/dwc3/trace.h +++ b/drivers/usb/dwc3/trace.h @@ -20,63 +20,70 @@ #include "debug.h" DECLARE_EVENT_CLASS(dwc3_log_set_prtcap, - TP_PROTO(u32 mode), - TP_ARGS(mode), + TP_PROTO(struct dwc3 *dwc, u32 mode), + TP_ARGS(dwc, mode), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __field(u32, mode) ), TP_fast_assign( + __entry->base_address = dwc->xhci_resources[0].start; __entry->mode = mode; ), - TP_printk("mode %s", dwc3_mode_string(__entry->mode)) + TP_printk("%pa: mode %s", &__entry->base_address, dwc3_mode_string(__entry->mode)) ); DEFINE_EVENT(dwc3_log_set_prtcap, dwc3_set_prtcap, - TP_PROTO(u32 mode), - TP_ARGS(mode) + TP_PROTO(struct dwc3 *dwc, u32 mode), + TP_ARGS(dwc, mode) ); DECLARE_EVENT_CLASS(dwc3_log_io, - TP_PROTO(void *base, u32 offset, u32 value), - TP_ARGS(base, offset, value), + TP_PROTO(struct dwc3 *dwc, void *base, u32 offset, u32 value), + TP_ARGS(dwc, base, offset, value), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __field(void *, base) __field(u32, offset) __field(u32, value) ), TP_fast_assign( + __entry->base_address = dwc->xhci_resources[0].start; __entry->base = base; __entry->offset = offset; __entry->value = value; ), - TP_printk("addr %p offset %04x value %08x", + TP_printk("%pa: addr %p offset %04x value %08x", + &__entry->base_address, __entry->base + __entry->offset, __entry->offset, __entry->value) ); DEFINE_EVENT(dwc3_log_io, dwc3_readl, - TP_PROTO(void __iomem *base, u32 offset, u32 value), - TP_ARGS(base, offset, value) + TP_PROTO(struct dwc3 *dwc, void __iomem *base, u32 offset, u32 value), + TP_ARGS(dwc, base, offset, value) ); DEFINE_EVENT(dwc3_log_io, dwc3_writel, - TP_PROTO(void __iomem *base, u32 offset, u32 value), - TP_ARGS(base, offset, value) + TP_PROTO(struct dwc3 *dwc, void __iomem *base, u32 offset, u32 value), + TP_ARGS(dwc, base, offset, value) ); DECLARE_EVENT_CLASS(dwc3_log_event, TP_PROTO(u32 event, struct dwc3 *dwc), TP_ARGS(event, dwc), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __field(u32, event) __field(u32, ep0state) ), TP_fast_assign( + __entry->base_address = dwc->xhci_resources[0].start; __entry->event = event; __entry->ep0state = dwc->ep0state; ), - TP_printk("event (%08x): %s", __entry->event, + TP_printk("%pa: event (%08x): %s", &__entry->base_address, __entry->event, dwc3_decode_event(__get_buf(DWC3_MSG_MAX), DWC3_MSG_MAX, __entry->event, __entry->ep0state)) ); @@ -87,9 +94,10 @@ DEFINE_EVENT(dwc3_log_event, dwc3_event, ); DECLARE_EVENT_CLASS(dwc3_log_ctrl, - TP_PROTO(struct usb_ctrlrequest *ctrl), - TP_ARGS(ctrl), + TP_PROTO(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl), + TP_ARGS(dwc, ctrl), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __field(__u8, bRequestType) __field(__u8, bRequest) __field(__u16, wValue) @@ -97,13 +105,15 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl, __field(__u16, wLength) ), TP_fast_assign( + __entry->base_address = dwc->xhci_resources[0].start; __entry->bRequestType = ctrl->bRequestType; __entry->bRequest = ctrl->bRequest; __entry->wValue = le16_to_cpu(ctrl->wValue); __entry->wIndex = le16_to_cpu(ctrl->wIndex); __entry->wLength = le16_to_cpu(ctrl->wLength); ), - TP_printk("%s", usb_decode_ctrl(__get_buf(DWC3_MSG_MAX), DWC3_MSG_MAX, + TP_printk("%pa: %s", &__entry->base_address, usb_decode_ctrl(__get_buf(DWC3_MSG_MAX), + DWC3_MSG_MAX, __entry->bRequestType, __entry->bRequest, __entry->wValue, __entry->wIndex, __entry->wLength) @@ -111,14 +121,15 @@ DECLARE_EVENT_CLASS(dwc3_log_ctrl, ); DEFINE_EVENT(dwc3_log_ctrl, dwc3_ctrl_req, - TP_PROTO(struct usb_ctrlrequest *ctrl), - TP_ARGS(ctrl) + TP_PROTO(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl), + TP_ARGS(dwc, ctrl) ); DECLARE_EVENT_CLASS(dwc3_log_request, TP_PROTO(struct dwc3_request *req), TP_ARGS(req), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __string(name, req->dep->name) __field(struct dwc3_request *, req) __field(unsigned int, actual) @@ -129,7 +140,7 @@ DECLARE_EVENT_CLASS(dwc3_log_request, __field(int, no_interrupt) ), TP_fast_assign( - __assign_str(name); + __entry->base_address = req->dep->dwc->xhci_resources[0].start; __entry->req = req; __entry->actual = req->request.actual; __entry->length = req->request.length; @@ -138,8 +149,10 @@ DECLARE_EVENT_CLASS(dwc3_log_request, __entry->short_not_ok = req->request.short_not_ok; __entry->no_interrupt = req->request.no_interrupt; ), - TP_printk("%s: req %p length %u/%u %s%s%s ==> %d", - __get_str(name), __entry->req, __entry->actual, __entry->length, + TP_printk("%pa: %s: req %p length %u/%u %s%s%s ==> %d", + &__entry->base_address, + __get_str(name), __entry->req, + __entry->actual, __entry->length, __entry->zero ? "Z" : "z", __entry->short_not_ok ? "S" : "s", __entry->no_interrupt ? "i" : "I", @@ -173,28 +186,30 @@ DEFINE_EVENT(dwc3_log_request, dwc3_gadget_giveback, ); DECLARE_EVENT_CLASS(dwc3_log_generic_cmd, - TP_PROTO(unsigned int cmd, u32 param, int status), - TP_ARGS(cmd, param, status), + TP_PROTO(struct dwc3 *dwc, unsigned int cmd, u32 param, int status), + TP_ARGS(dwc, cmd, param, status), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __field(unsigned int, cmd) __field(u32, param) __field(int, status) ), TP_fast_assign( + __entry->base_address = dwc->xhci_resources[0].start; __entry->cmd = cmd; __entry->param = param; __entry->status = status; ), - TP_printk("cmd '%s' [%x] param %08x --> status: %s", - dwc3_gadget_generic_cmd_string(__entry->cmd), + TP_printk("%pa: cmd '%s' [%x] param %08x --> status: %s", + &__entry->base_address, dwc3_gadget_generic_cmd_string(__entry->cmd), __entry->cmd, __entry->param, dwc3_gadget_generic_cmd_status_string(__entry->status) ) ); DEFINE_EVENT(dwc3_log_generic_cmd, dwc3_gadget_generic_cmd, - TP_PROTO(unsigned int cmd, u32 param, int status), - TP_ARGS(cmd, param, status) + TP_PROTO(struct dwc3 *dwc, unsigned int cmd, u32 param, int status), + TP_ARGS(dwc, cmd, param, status) ); DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, @@ -202,6 +217,7 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, struct dwc3_gadget_ep_cmd_params *params, int cmd_status), TP_ARGS(dep, cmd, params, cmd_status), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __string(name, dep->name) __field(unsigned int, cmd) __field(u32, param0) @@ -210,6 +226,7 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, __field(int, cmd_status) ), TP_fast_assign( + __entry->base_address = dep->dwc->xhci_resources[0].start; __assign_str(name); __entry->cmd = cmd; __entry->param0 = params->param0; @@ -217,8 +234,9 @@ DECLARE_EVENT_CLASS(dwc3_log_gadget_ep_cmd, __entry->param2 = params->param2; __entry->cmd_status = cmd_status; ), - TP_printk("%s: cmd '%s' [%x] params %08x %08x %08x --> status: %s", - __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), + TP_printk("%pa: %s: cmd '%s' [%x] params %08x %08x %08x --> status: %s", + &__entry->base_address, __get_str(name), + dwc3_gadget_ep_cmd_string(__entry->cmd), __entry->cmd, __entry->param0, __entry->param1, __entry->param2, dwc3_ep_cmd_status_string(__entry->cmd_status) @@ -235,6 +253,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, TP_PROTO(struct dwc3_ep *dep, struct dwc3_trb *trb), TP_ARGS(dep, trb), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __string(name, dep->name) __field(struct dwc3_trb *, trb) __field(u32, bpl) @@ -246,6 +265,7 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __field(u32, dequeue) ), TP_fast_assign( + __entry->base_address = dep->dwc->xhci_resources[0].start; __assign_str(name); __entry->trb = trb; __entry->bpl = trb->bpl; @@ -256,8 +276,8 @@ DECLARE_EVENT_CLASS(dwc3_log_trb, __entry->enqueue = dep->trb_enqueue; __entry->dequeue = dep->trb_dequeue; ), - TP_printk("%s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x sofn %08x (%c%c%c%c:%c%c:%s)", - __get_str(name), __entry->trb, __entry->enqueue, + TP_printk("%pa: %s: trb %p (E%d:D%d) buf %08x%08x size %s%d ctrl %08x sofn %08x (%c%c%c%c:%c%c:%s)", + &__entry->base_address, __get_str(name), __entry->trb, __entry->enqueue, __entry->dequeue, __entry->bph, __entry->bpl, ({char *s; int pcm = ((__entry->size >> 24) & 3) + 1; @@ -307,6 +327,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep, TP_PROTO(struct dwc3_ep *dep), TP_ARGS(dep), TP_STRUCT__entry( + __field(phys_addr_t, base_address) __string(name, dep->name) __field(unsigned int, maxpacket) __field(unsigned int, maxpacket_limit) @@ -318,6 +339,7 @@ DECLARE_EVENT_CLASS(dwc3_log_ep, __field(u8, trb_dequeue) ), TP_fast_assign( + __entry->base_address = dep->dwc->xhci_resources[0].start; __assign_str(name); __entry->maxpacket = dep->endpoint.maxpacket; __entry->maxpacket_limit = dep->endpoint.maxpacket_limit; @@ -328,8 +350,8 @@ DECLARE_EVENT_CLASS(dwc3_log_ep, __entry->trb_enqueue = dep->trb_enqueue; __entry->trb_dequeue = dep->trb_dequeue; ), - TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c", - __get_str(name), __entry->maxpacket, + TP_printk("%pa: %s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c:%c", + &__entry->base_address, __get_str(name), __entry->maxpacket, __entry->maxpacket_limit, __entry->max_streams, __entry->maxburst, __entry->trb_enqueue, __entry->trb_dequeue, diff --git a/drivers/usb/dwc3/ulpi.c b/drivers/usb/dwc3/ulpi.c index f23f4c9a557e..57daad15f502 100644 --- a/drivers/usb/dwc3/ulpi.c +++ b/drivers/usb/dwc3/ulpi.c @@ -33,13 +33,13 @@ static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read) if (read) ns += DWC3_ULPI_BASE_DELAY; - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYCFG(0)); if (reg & DWC3_GUSB2PHYCFG_SUSPHY) usleep_range(1000, 1200); while (count--) { ndelay(ns); - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0)); if (reg & DWC3_GUSB2PHYACC_DONE) return 0; cpu_relax(); @@ -55,13 +55,13 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr) int ret; reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); - dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg); ret = dwc3_ulpi_busyloop(dwc, addr, true); if (ret) return ret; - reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); + reg = dwc3_readl(dwc, DWC3_GUSB2PHYACC(0)); return DWC3_GUSB2PHYACC_DATA(reg); } @@ -73,7 +73,7 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val) reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); reg |= DWC3_GUSB2PHYACC_WRITE | val; - dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); + dwc3_writel(dwc, DWC3_GUSB2PHYACC(0), reg); return dwc3_ulpi_busyloop(dwc, addr, false); } diff --git a/drivers/usb/fotg210/fotg210-hcd.c b/drivers/usb/fotg210/fotg210-hcd.c index 64c4965a160f..1a48329a4e08 100644 --- a/drivers/usb/fotg210/fotg210-hcd.c +++ b/drivers/usb/fotg210/fotg210-hcd.c @@ -515,7 +515,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) unsigned i; __hc32 tag; - seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC); + seen = kmalloc_objs(*seen, DBG_SCHED_LIMIT, GFP_ATOMIC); if (!seen) return 0; @@ -738,7 +738,7 @@ static struct debug_buffer { struct debug_buffer *buf; - buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); + buf = kzalloc_obj(struct debug_buffer); if (buf) { buf->bus = bus; @@ -1847,7 +1847,7 @@ static struct fotg210_qh *fotg210_qh_alloc(struct fotg210_hcd *fotg210, struct fotg210_qh *qh; dma_addr_t dma; - qh = kzalloc(sizeof(*qh), GFP_ATOMIC); + qh = kzalloc_obj(*qh, GFP_ATOMIC); if (!qh) goto done; qh->hw = (struct fotg210_qh_hw *) @@ -3899,7 +3899,7 @@ static struct fotg210_iso_stream *iso_stream_alloc(gfp_t mem_flags) { struct fotg210_iso_stream *stream; - stream = kzalloc(sizeof(*stream), mem_flags); + stream = kzalloc_obj(*stream, mem_flags); if (likely(stream != NULL)) { INIT_LIST_HEAD(&stream->td_list); INIT_LIST_HEAD(&stream->free_list); @@ -4007,7 +4007,7 @@ static struct fotg210_iso_sched *iso_sched_alloc(unsigned packets, { struct fotg210_iso_sched *iso_sched; - iso_sched = kzalloc(struct_size(iso_sched, packet, packets), mem_flags); + iso_sched = kzalloc_flex(*iso_sched, packet, packets, mem_flags); if (likely(iso_sched != NULL)) INIT_LIST_HEAD(&iso_sched->td_list); @@ -5625,11 +5625,6 @@ int __init fotg210_hcd_init(void) if (usb_disabled()) return -ENODEV; - set_bit(USB_EHCI_LOADED, &usb_hcds_loaded); - if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) || - test_bit(USB_OHCI_LOADED, &usb_hcds_loaded)) - pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n"); - pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd\n", hcd_name, sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd), @@ -5643,5 +5638,4 @@ int __init fotg210_hcd_init(void) void __exit fotg210_hcd_cleanup(void) { debugfs_remove(fotg210_debug_root); - clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); } diff --git a/drivers/usb/fotg210/fotg210-udc.c b/drivers/usb/fotg210/fotg210-udc.c index 0bae12e34f9a..d9e024873a42 100644 --- a/drivers/usb/fotg210/fotg210-udc.c +++ b/drivers/usb/fotg210/fotg210-udc.c @@ -244,7 +244,7 @@ static struct usb_request *fotg210_ep_alloc_request(struct usb_ep *_ep, { struct fotg210_request *req; - req = kzalloc(sizeof(struct fotg210_request), gfp_flags); + req = kzalloc_obj(struct fotg210_request, gfp_flags); if (!req) return NULL; @@ -1183,7 +1183,7 @@ int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg) return irq; /* initialize udc */ - fotg210 = kzalloc(sizeof(struct fotg210_udc), GFP_KERNEL); + fotg210 = kzalloc_obj(struct fotg210_udc); if (fotg210 == NULL) return -ENOMEM; @@ -1207,7 +1207,7 @@ int fotg210_udc_probe(struct platform_device *pdev, struct fotg210 *fotg) ret = -ENOMEM; for (i = 0; i < FOTG210_MAX_NUM_EP; i++) { - fotg210->ep[i] = kzalloc(sizeof(struct fotg210_ep), GFP_KERNEL); + fotg210->ep[i] = kzalloc_obj(struct fotg210_ep); if (!fotg210->ep[i]) goto err_alloc; } diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5b3866909b75..a902184bdf82 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2531,7 +2531,7 @@ static int composite_bind(struct usb_gadget *gadget, struct usb_composite_driver *composite = to_cdriver(gdriver); int status = -ENOMEM; - cdev = kzalloc(sizeof *cdev, GFP_KERNEL); + cdev = kzalloc_obj(*cdev); if (!cdev) return status; diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 6bcac85c5550..183a25f65ac8 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -409,7 +409,7 @@ static void gadget_info_attr_release(struct config_item *item) kfree(gi); } -static struct configfs_item_operations gadget_root_item_ops = { +static const struct configfs_item_operations gadget_root_item_ops = { .release = gadget_info_attr_release, }; @@ -514,7 +514,7 @@ static void config_usb_cfg_unlink( WARN(1, "Unable to locate function to unbind\n"); } -static struct configfs_item_operations gadget_config_item_ops = { +static const struct configfs_item_operations gadget_config_item_ops = { .release = gadget_config_attr_release, .allow_link = config_usb_cfg_link, .drop_link = config_usb_cfg_unlink, @@ -663,7 +663,7 @@ static void function_drop( config_item_put(item); } -static struct configfs_group_operations functions_ops = { +static const struct configfs_group_operations functions_ops = { .make_group = &function_make, .drop_item = &function_drop, }; @@ -727,7 +727,7 @@ static struct config_group *config_desc_make( if (ret) return ERR_PTR(ret); - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return ERR_PTR(-ENOMEM); cfg->c.label = kstrdup(buf, GFP_KERNEL); @@ -766,7 +766,7 @@ static void config_desc_drop( config_item_put(item); } -static struct configfs_group_operations config_desc_ops = { +static const struct configfs_group_operations config_desc_ops = { .make_group = &config_desc_make, .drop_item = &config_desc_drop, }; @@ -799,7 +799,7 @@ static void gadget_language_attr_release(struct config_item *item) kfree(gs); } -static struct configfs_item_operations gadget_language_langid_item_ops = { +static const struct configfs_item_operations gadget_language_langid_item_ops = { .release = gadget_language_attr_release, }; @@ -852,7 +852,7 @@ static void gadget_string_release(struct config_item *item) kfree(string); } -static struct configfs_item_operations gadget_string_item_ops = { +static const struct configfs_item_operations gadget_string_item_ops = { .release = gadget_string_release, }; @@ -870,7 +870,7 @@ static struct config_item *gadget_language_string_make(struct config_group *grou language = to_gadget_language(&group->cg_item); - string = kzalloc(sizeof(*string), GFP_KERNEL); + string = kzalloc_obj(*string); if (!string) return ERR_PTR(-ENOMEM); @@ -901,7 +901,7 @@ static void gadget_language_string_drop(struct config_group *group, string->usb_string.id = i++; } -static struct configfs_group_operations gadget_language_langid_group_ops = { +static const struct configfs_group_operations gadget_language_langid_group_ops = { .make_item = gadget_language_string_make, .drop_item = gadget_language_string_drop, }; @@ -922,7 +922,7 @@ static struct config_group *gadget_language_make(struct config_group *group, int langs = 0; int ret; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return ERR_PTR(-ENOMEM); @@ -960,7 +960,7 @@ static void gadget_language_drop(struct config_group *group, config_item_put(item); } -static struct configfs_group_operations gadget_language_group_ops = { +static const struct configfs_group_operations gadget_language_group_ops = { .make_group = &gadget_language_make, .drop_item = &gadget_language_drop, }; @@ -1266,7 +1266,7 @@ static void os_desc_unlink(struct config_item *os_desc_ci, mutex_unlock(&gi->lock); } -static struct configfs_item_operations os_desc_ops = { +static const struct configfs_item_operations os_desc_ops = { .allow_link = os_desc_link, .drop_link = os_desc_unlink, }; @@ -1391,7 +1391,7 @@ static void usb_os_desc_ext_prop_release(struct config_item *item) kfree(ext_prop); /* frees a whole chunk */ } -static struct configfs_item_operations ext_prop_ops = { +static const struct configfs_item_operations ext_prop_ops = { .release = usb_os_desc_ext_prop_release, }; @@ -1456,7 +1456,7 @@ static void ext_prop_drop(struct config_group *group, struct config_item *item) config_item_put(item); } -static struct configfs_group_operations interf_grp_ops = { +static const struct configfs_group_operations interf_grp_ops = { .make_item = &ext_prop_make, .drop_item = &ext_prop_drop, }; @@ -1629,8 +1629,7 @@ configfs_attach_gadget_strings(struct gadget_info *gi) if (!nlangs) return NULL; - gadget_strings = kcalloc(nlangs + 1, /* including NULL terminator */ - sizeof(struct usb_gadget_strings *), GFP_KERNEL); + gadget_strings = kzalloc_objs(struct usb_gadget_strings *, nlangs + 1)/* including NULL terminator */; if (!gadget_strings) return ERR_PTR(-ENOMEM); @@ -1645,8 +1644,8 @@ configfs_attach_gadget_strings(struct gadget_info *gi) goto cleanup; } - stringtab = kcalloc(language->nstrings + 1, sizeof(struct usb_string), - GFP_KERNEL); + stringtab = kzalloc_objs(struct usb_string, + language->nstrings + 1); if (!stringtab) { us = ERR_PTR(-ENOMEM); goto cleanup; @@ -1992,7 +1991,7 @@ static struct config_group *gadgets_make( { struct gadget_info *gi; - gi = kzalloc(sizeof(*gi), GFP_KERNEL); + gi = kzalloc_obj(*gi); if (!gi) return ERR_PTR(-ENOMEM); @@ -2061,7 +2060,7 @@ static void gadgets_drop(struct config_group *group, struct config_item *item) config_item_put(item); } -static struct configfs_group_operations gadgets_ops = { +static const struct configfs_group_operations gadgets_ops = { .make_group = &gadgets_make, .drop_item = &gadgets_drop, }; diff --git a/drivers/usb/gadget/function/f_acm.c b/drivers/usb/gadget/function/f_acm.c index 106046e17c4e..c628d02bfb1d 100644 --- a/drivers/usb/gadget/function/f_acm.c +++ b/drivers/usb/gadget/function/f_acm.c @@ -748,7 +748,7 @@ static struct usb_function *acm_alloc_func(struct usb_function_instance *fi) struct f_serial_opts *opts; struct f_acm *acm; - acm = kzalloc(sizeof(*acm), GFP_KERNEL); + acm = kzalloc_obj(*acm); if (!acm) return ERR_PTR(-ENOMEM); @@ -793,7 +793,7 @@ static void acm_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations acm_item_ops = { +static const struct configfs_item_operations acm_item_ops = { .release = acm_attr_release, }; @@ -882,7 +882,7 @@ static struct usb_function_instance *acm_alloc_instance(void) struct f_serial_opts *opts; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); opts->protocol = USB_CDC_ACM_PROTO_AT_V25TER; diff --git a/drivers/usb/gadget/function/f_ecm.c b/drivers/usb/gadget/function/f_ecm.c index 675d2bc538a4..e0c02121374e 100644 --- a/drivers/usb/gadget/function/f_ecm.c +++ b/drivers/usb/gadget/function/f_ecm.c @@ -847,7 +847,7 @@ static struct usb_function_instance *ecm_alloc_inst(void) { struct f_ecm_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); @@ -927,7 +927,7 @@ static struct usb_function *ecm_alloc(struct usb_function_instance *fi) int status; /* allocate and initialize one new instance */ - ecm = kzalloc(sizeof(*ecm), GFP_KERNEL); + ecm = kzalloc_obj(*ecm); if (!ecm) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_eem.c b/drivers/usb/gadget/function/f_eem.c index edbbadad6138..0142a0e487ee 100644 --- a/drivers/usb/gadget/function/f_eem.c +++ b/drivers/usb/gadget/function/f_eem.c @@ -462,7 +462,7 @@ static int eem_unwrap(struct gether *port, goto next; } - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) { kfree(req->buf); usb_ep_free_request(ep, req); @@ -608,7 +608,7 @@ static struct usb_function_instance *eem_alloc_inst(void) { struct f_eem_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); @@ -651,7 +651,7 @@ static struct usb_function *eem_alloc(struct usb_function_instance *fi) struct f_eem_opts *opts; /* allocate and initialize one new instance */ - eem = kzalloc(sizeof(*eem), GFP_KERNEL); + eem = kzalloc_obj(*eem); if (!eem) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index fa467a40949d..002c3441bea3 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -814,7 +814,7 @@ static void *ffs_build_sg_list(struct sg_table *sgt, size_t sz) return NULL; n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT; - pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL); + pages = kvmalloc_objs(struct page *, n_pages); if (!pages) { vfree(vaddr); @@ -957,7 +957,7 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile, data_len, ret); data_len -= ret; - buf = kmalloc(struct_size(buf, storage, data_len), GFP_KERNEL); + buf = kmalloc_flex(*buf, storage, data_len); if (!buf) return -ENOMEM; buf->length = data_len; @@ -1245,7 +1245,7 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) ssize_t res; if (!is_sync_kiocb(kiocb)) { - p = kzalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc_obj(io_data); if (!p) return -ENOMEM; p->aio = true; @@ -1280,7 +1280,7 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) ssize_t res; if (!is_sync_kiocb(kiocb)) { - p = kzalloc(sizeof(io_data), GFP_KERNEL); + p = kzalloc_obj(io_data); if (!p) return -ENOMEM; p->aio = true; @@ -1503,13 +1503,13 @@ static int ffs_dmabuf_attach(struct file *file, int fd) goto err_dmabuf_put; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { err = -ENOMEM; goto err_dmabuf_detach; } - dir = epfile->in ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + dir = epfile->in ? DMA_TO_DEVICE : DMA_FROM_DEVICE; err = ffs_dma_resv_lock(dmabuf, nonblock); if (err) @@ -1639,7 +1639,7 @@ static int ffs_dmabuf_transfer(struct file *file, /* Make sure we don't have writers */ timeout = nonblock ? 0 : msecs_to_jiffies(DMABUF_ENQUEUE_TIMEOUT_MS); retl = dma_resv_wait_timeout(dmabuf->resv, - dma_resv_usage_rw(epfile->in), + dma_resv_usage_rw(!epfile->in), true, timeout); if (retl == 0) retl = -EBUSY; @@ -1652,7 +1652,7 @@ static int ffs_dmabuf_transfer(struct file *file, if (ret) goto err_resv_unlock; - fence = kmalloc(sizeof(*fence), GFP_KERNEL); + fence = kmalloc_obj(*fence); if (!fence) { ret = -ENOMEM; goto err_resv_unlock; @@ -1684,7 +1684,7 @@ static int ffs_dmabuf_transfer(struct file *file, dma_fence_init(&fence->base, &ffs_dmabuf_fence_ops, &priv->lock, priv->context, seqno); - resv_dir = epfile->in ? DMA_RESV_USAGE_WRITE : DMA_RESV_USAGE_READ; + resv_dir = epfile->in ? DMA_RESV_USAGE_READ : DMA_RESV_USAGE_WRITE; dma_resv_add_fence(dmabuf->resv, &fence->base, resv_dir); dma_resv_unlock(dmabuf->resv); @@ -1744,10 +1744,8 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, { int fd; - if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) + return -EFAULT; return ffs_dmabuf_attach(file, fd); } @@ -1755,10 +1753,8 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, { int fd; - if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&fd, (void __user *)value, sizeof(fd))) + return -EFAULT; return ffs_dmabuf_detach(file, fd); } @@ -1766,10 +1762,8 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code, { struct usb_ffs_dmabuf_transfer_req req; - if (copy_from_user(&req, (void __user *)value, sizeof(req))) { - ret = -EFAULT; - break; - } + if (copy_from_user(&req, (void __user *)value, sizeof(req))) + return -EFAULT; return ffs_dmabuf_transfer(file, &req); } @@ -2073,7 +2067,7 @@ static int ffs_fs_init_fs_context(struct fs_context *fc) { struct ffs_sb_fill_data *ctx; - ctx = kzalloc(sizeof(struct ffs_sb_fill_data), GFP_KERNEL); + ctx = kzalloc_obj(struct ffs_sb_fill_data); if (!ctx) return -ENOMEM; @@ -2189,7 +2183,7 @@ static void ffs_data_closed(struct ffs_data *ffs) static struct ffs_data *ffs_data_new(const char *dev_name) { - struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); + struct ffs_data *ffs = kzalloc_obj(*ffs); if (!ffs) return NULL; @@ -2336,7 +2330,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs) int err; count = ffs->eps_count; - epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL); + epfiles = kzalloc_objs(*epfiles, count); if (!epfiles) return -ENOMEM; @@ -4000,7 +3994,7 @@ static void ffs_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations ffs_item_ops = { +static const struct configfs_item_operations ffs_item_ops = { .release = ffs_attr_release, }; @@ -4037,7 +4031,7 @@ static struct usb_function_instance *ffs_alloc_inst(void) struct f_fs_opts *opts; struct ffs_dev *dev; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -4113,7 +4107,7 @@ static struct usb_function *ffs_alloc(struct usb_function_instance *fi) { struct ffs_function *func; - func = kzalloc(sizeof(*func), GFP_KERNEL); + func = kzalloc_obj(*func); if (!func) return ERR_PTR(-ENOMEM); @@ -4144,7 +4138,7 @@ static struct ffs_dev *_ffs_alloc_dev(void) if (_ffs_get_single_dev()) return ERR_PTR(-EBUSY); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index 3ddfd4f66f0b..8812ebf33d14 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -650,7 +650,7 @@ static int f_hidg_get_report(struct file *file, struct usb_hidg_report __user *b struct report_entry *ptr; __u8 report_id; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -775,7 +775,7 @@ static void hidg_intout_complete(struct usb_ep *ep, struct usb_request *req) switch (req->status) { case 0: - req_list = kzalloc(sizeof(*req_list), GFP_ATOMIC); + req_list = kzalloc_obj(*req_list, GFP_ATOMIC); if (!req_list) { ERROR(cdev, "Unable to allocate mem for req_list\n"); goto free_req; @@ -1207,9 +1207,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) if (!hidg->interval_user_set) { hidg_fs_in_ep_desc.bInterval = 10; hidg_hs_in_ep_desc.bInterval = 4; + hidg_ss_in_ep_desc.bInterval = 4; } else { hidg_fs_in_ep_desc.bInterval = hidg->interval; hidg_hs_in_ep_desc.bInterval = hidg->interval; + hidg_ss_in_ep_desc.bInterval = hidg->interval; } hidg_ss_out_comp_desc.wBytesPerInterval = @@ -1239,9 +1241,11 @@ static int hidg_bind(struct usb_configuration *c, struct usb_function *f) if (!hidg->interval_user_set) { hidg_fs_out_ep_desc.bInterval = 10; hidg_hs_out_ep_desc.bInterval = 4; + hidg_ss_out_ep_desc.bInterval = 4; } else { hidg_fs_out_ep_desc.bInterval = hidg->interval; hidg_hs_out_ep_desc.bInterval = hidg->interval; + hidg_ss_out_ep_desc.bInterval = hidg->interval; } status = usb_assign_descriptors(f, hidg_fs_descriptors_intout, @@ -1328,7 +1332,7 @@ static void hid_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations hidg_item_ops = { +static const struct configfs_item_operations hidg_item_ops = { .release = hid_attr_release, }; @@ -1530,7 +1534,7 @@ static struct usb_function_instance *hidg_alloc_inst(void) struct usb_function_instance *ret; int status = 0; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); @@ -1596,7 +1600,7 @@ static struct usb_function *hidg_alloc(struct usb_function_instance *fi) int ret; /* allocate and initialize one new instance */ - hidg = kzalloc(sizeof(*hidg), GFP_KERNEL); + hidg = kzalloc_obj(*hidg); if (!hidg) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_loopback.c b/drivers/usb/gadget/function/f_loopback.c index 49b009a7d5d7..d2d07fb49e70 100644 --- a/drivers/usb/gadget/function/f_loopback.c +++ b/drivers/usb/gadget/function/f_loopback.c @@ -425,7 +425,7 @@ static struct usb_function *loopback_alloc(struct usb_function_instance *fi) struct f_loopback *loop; struct f_lb_opts *lb_opts; - loop = kzalloc(sizeof *loop, GFP_KERNEL); + loop = kzalloc_obj(*loop); if (!loop) return ERR_PTR(-ENOMEM); @@ -464,7 +464,7 @@ static void lb_attr_release(struct config_item *item) usb_put_function_instance(&lb_opts->func_inst); } -static struct configfs_item_operations lb_item_ops = { +static const struct configfs_item_operations lb_item_ops = { .release = lb_attr_release, }; @@ -568,7 +568,7 @@ static struct usb_function_instance *loopback_alloc_instance(void) { struct f_lb_opts *lb_opts; - lb_opts = kzalloc(sizeof(*lb_opts), GFP_KERNEL); + lb_opts = kzalloc_obj(*lb_opts); if (!lb_opts) return ERR_PTR(-ENOMEM); mutex_init(&lb_opts->lock); diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 94d478b6bcd3..b7b06cb79ff5 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -180,6 +180,7 @@ #include #include #include +#include #include #include #include @@ -1853,8 +1854,15 @@ static int check_command_size_in_blocks(struct fsg_common *common, int cmnd_size, enum data_direction data_dir, unsigned int mask, int needs_medium, const char *name) { - if (common->curlun) - common->data_size_from_cmnd <<= common->curlun->blkbits; + if (common->curlun) { + if (check_shl_overflow(common->data_size_from_cmnd, + common->curlun->blkbits, + &common->data_size_from_cmnd)) { + common->phase_error = 1; + return -EINVAL; + } + } + return check_command(common, cmnd_size, data_dir, mask, needs_medium, name); } @@ -2699,7 +2707,7 @@ static void fsg_lun_release(struct device *dev) static struct fsg_common *fsg_common_setup(struct fsg_common *common) { if (!common) { - common = kzalloc(sizeof(*common), GFP_KERNEL); + common = kzalloc_obj(*common); if (!common) return ERR_PTR(-ENOMEM); common->free_storage_on_release = 1; @@ -2740,7 +2748,7 @@ int fsg_common_set_num_buffers(struct fsg_common *common, unsigned int n) struct fsg_buffhd *bh, *buffhds; int i; - buffhds = kcalloc(n, sizeof(*buffhds), GFP_KERNEL); + buffhds = kzalloc_objs(*buffhds, n); if (!buffhds) return -ENOMEM; @@ -2887,7 +2895,7 @@ int fsg_common_create_lun(struct fsg_common *common, struct fsg_lun_config *cfg, return -EINVAL; } - lun = kzalloc(sizeof(*lun), GFP_KERNEL); + lun = kzalloc_obj(*lun); if (!lun) return -ENOMEM; @@ -3153,7 +3161,7 @@ static void fsg_lun_attr_release(struct config_item *item) kfree(lun_opts); } -static struct configfs_item_operations fsg_lun_item_ops = { +static const struct configfs_item_operations fsg_lun_item_ops = { .release = fsg_lun_attr_release, }; @@ -3311,7 +3319,7 @@ static struct config_group *fsg_lun_make(struct config_group *group, goto out; } - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) { ret = -ENOMEM; goto out; @@ -3369,7 +3377,7 @@ static void fsg_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations fsg_item_ops = { +static const struct configfs_item_operations fsg_item_ops = { .release = fsg_attr_release, }; @@ -3462,7 +3470,7 @@ static struct configfs_attribute *fsg_attrs[] = { NULL, }; -static struct configfs_group_operations fsg_group_ops = { +static const struct configfs_group_operations fsg_group_ops = { .make_group = fsg_lun_make, .drop_item = fsg_lun_drop, }; @@ -3489,7 +3497,7 @@ static struct usb_function_instance *fsg_alloc_inst(void) struct fsg_lun_config config; int rc; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); @@ -3554,7 +3562,7 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi) struct fsg_common *common = opts->common; struct fsg_dev *fsg; - fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); + fsg = kzalloc_obj(*fsg); if (unlikely(!fsg)) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c index da82598fcef8..4d9e4bd700d8 100644 --- a/drivers/usb/gadget/function/f_midi.c +++ b/drivers/usb/gadget/function/f_midi.c @@ -875,6 +875,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) struct usb_composite_dev *cdev = c->cdev; struct f_midi *midi = func_to_midi(f); struct usb_string *us; + struct f_midi_opts *opts; int status, n, jack = 1, i = 0, endpoint_descriptor_index = 0; midi->gadget = cdev->gadget; @@ -883,6 +884,10 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) if (status < 0) goto fail_register; + opts = container_of(f->fi, struct f_midi_opts, func_inst); + if (opts->interface_string) + midi_string_defs[STRING_FUNC_IDX].s = opts->interface_string; + /* maybe allocate device-global string ID */ us = usb_gstrings_attach(c->cdev, midi_strings, ARRAY_SIZE(midi_string_defs)); @@ -926,8 +931,7 @@ static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) goto fail; /* allocate temporary function list */ - midi_function = kcalloc((MAX_PORTS * 4) + 11, sizeof(*midi_function), - GFP_KERNEL); + midi_function = kzalloc_objs(*midi_function, (MAX_PORTS * 4) + 11); if (!midi_function) { status = -ENOMEM; goto fail; @@ -1086,7 +1090,7 @@ static void midi_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations midi_item_ops = { +static const struct configfs_item_operations midi_item_ops = { .release = midi_attr_release, }; @@ -1178,59 +1182,60 @@ end: \ \ CONFIGFS_ATTR(f_midi_opts_, name); +#define F_MIDI_OPT_STRING(name) \ +static ssize_t f_midi_opts_##name##_show(struct config_item *item, char *page) \ +{ \ + struct f_midi_opts *opts = to_f_midi_opts(item); \ + ssize_t result; \ + \ + mutex_lock(&opts->lock); \ + if (opts->name) { \ + result = strscpy(page, opts->name, PAGE_SIZE); \ + } else { \ + page[0] = 0; \ + result = 0; \ + } \ + \ + mutex_unlock(&opts->lock); \ + \ + return result; \ +} \ + \ +static ssize_t f_midi_opts_##name##_store(struct config_item *item, \ + const char *page, size_t len) \ +{ \ + struct f_midi_opts *opts = to_f_midi_opts(item); \ + int ret; \ + char *c; \ + \ + mutex_lock(&opts->lock); \ + if (opts->refcnt > 1) { \ + ret = -EBUSY; \ + goto end; \ + } \ + \ + c = kstrndup(page, len, GFP_KERNEL); \ + if (!c) { \ + ret = -ENOMEM; \ + goto end; \ + } \ + kfree(opts->name); \ + opts->name = c; \ + ret = len; \ +end: \ + mutex_unlock(&opts->lock); \ + return ret; \ +} \ + \ +CONFIGFS_ATTR(f_midi_opts_, name) + F_MIDI_OPT_SIGNED(index, true, SNDRV_CARDS); F_MIDI_OPT(buflen, false, 0); F_MIDI_OPT(qlen, false, 0); F_MIDI_OPT(in_ports, true, MAX_PORTS); F_MIDI_OPT(out_ports, true, MAX_PORTS); - -static ssize_t f_midi_opts_id_show(struct config_item *item, char *page) -{ - struct f_midi_opts *opts = to_f_midi_opts(item); - ssize_t result; - - mutex_lock(&opts->lock); - if (opts->id) { - result = strscpy(page, opts->id, PAGE_SIZE); - } else { - page[0] = 0; - result = 0; - } - - mutex_unlock(&opts->lock); - - return result; -} - -static ssize_t f_midi_opts_id_store(struct config_item *item, - const char *page, size_t len) -{ - struct f_midi_opts *opts = to_f_midi_opts(item); - int ret; - char *c; - - mutex_lock(&opts->lock); - if (opts->refcnt > 1) { - ret = -EBUSY; - goto end; - } - - c = kstrndup(page, len, GFP_KERNEL); - if (!c) { - ret = -ENOMEM; - goto end; - } - if (opts->id_allocated) - kfree(opts->id); - opts->id = c; - opts->id_allocated = true; - ret = len; -end: - mutex_unlock(&opts->lock); - return ret; -} - -CONFIGFS_ATTR(f_midi_opts_, id); +F_MIDI_OPT_STRING(id); +F_MIDI_OPT_STRING(interface_string); static struct configfs_attribute *midi_attrs[] = { &f_midi_opts_attr_index, @@ -1239,6 +1244,7 @@ static struct configfs_attribute *midi_attrs[] = { &f_midi_opts_attr_in_ports, &f_midi_opts_attr_out_ports, &f_midi_opts_attr_id, + &f_midi_opts_attr_interface_string, NULL, }; @@ -1262,8 +1268,8 @@ static void f_midi_free_inst(struct usb_function_instance *f) mutex_unlock(&opts->lock); if (free) { - if (opts->id_allocated) - kfree(opts->id); + kfree(opts->id); + kfree(opts->interface_string); kfree(opts); } } @@ -1272,14 +1278,15 @@ static struct usb_function_instance *f_midi_alloc_inst(void) { struct f_midi_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); opts->func_inst.free_func_inst = f_midi_free_inst; opts->index = SNDRV_DEFAULT_IDX1; - opts->id = SNDRV_DEFAULT_STR1; + opts->id = NULL; + opts->interface_string = NULL; opts->buflen = 512; opts->qlen = 32; opts->in_ports = 1; @@ -1353,8 +1360,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) } /* allocate and initialize one new instance */ - midi = kzalloc(struct_size(midi, in_ports_array, opts->in_ports), - GFP_KERNEL); + midi = kzalloc_flex(*midi, in_ports_array, opts->in_ports); if (!midi) { status = -ENOMEM; goto setup_fail; diff --git a/drivers/usb/gadget/function/f_midi2.c b/drivers/usb/gadget/function/f_midi2.c index de16b02d857e..b5f0defde95d 100644 --- a/drivers/usb/gadget/function/f_midi2.c +++ b/drivers/usb/gadget/function/f_midi2.c @@ -1187,8 +1187,7 @@ static int f_midi2_init_ep(struct f_midi2 *midi2, struct f_midi2_ep *ep, return -ENODEV; usb_ep->complete = complete; - usb_ep->reqs = kcalloc(midi2->info.num_reqs, sizeof(*usb_ep->reqs), - GFP_KERNEL); + usb_ep->reqs = kzalloc_objs(*usb_ep->reqs, midi2->info.num_reqs); if (!usb_ep->reqs) return -ENOMEM; for (i = 0; i < midi2->info.num_reqs; i++) { @@ -2316,7 +2315,7 @@ static void f_midi2_block_opts_release(struct config_item *item) kfree(opts); } -static struct configfs_item_operations f_midi2_block_item_ops = { +static const struct configfs_item_operations f_midi2_block_item_ops = { .release = f_midi2_block_opts_release, }; @@ -2340,7 +2339,7 @@ static int f_midi2_block_opts_create(struct f_midi2_ep_opts *ep_opts, goto out; } - block_opts = kzalloc(sizeof(*block_opts), GFP_KERNEL); + block_opts = kzalloc_obj(*block_opts); if (!block_opts) { ret = -ENOMEM; goto out; @@ -2479,11 +2478,11 @@ static void f_midi2_ep_opts_release(struct config_item *item) kfree(opts); } -static struct configfs_item_operations f_midi2_ep_item_ops = { +static const struct configfs_item_operations f_midi2_ep_item_ops = { .release = f_midi2_ep_opts_release, }; -static struct configfs_group_operations f_midi2_ep_group_ops = { +static const struct configfs_group_operations f_midi2_ep_group_ops = { .make_group = f_midi2_opts_block_make, .drop_item = f_midi2_opts_block_drop, }; @@ -2502,7 +2501,7 @@ static int f_midi2_ep_opts_create(struct f_midi2_opts *opts, { struct f_midi2_ep_opts *ep_opts; - ep_opts = kzalloc(sizeof(*ep_opts), GFP_KERNEL); + ep_opts = kzalloc_obj(*ep_opts); if (!ep_opts) return -ENOMEM; @@ -2618,11 +2617,11 @@ static void f_midi2_opts_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations f_midi2_item_ops = { +static const struct configfs_item_operations f_midi2_item_ops = { .release = f_midi2_opts_release, }; -static struct configfs_group_operations f_midi2_group_ops = { +static const struct configfs_group_operations f_midi2_group_ops = { .make_group = f_midi2_opts_ep_make, .drop_item = f_midi2_opts_ep_drop, }; @@ -2652,7 +2651,7 @@ static struct usb_function_instance *f_midi2_alloc_inst(void) struct f_midi2_block_opts *block_opts; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -2813,7 +2812,7 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi) struct f_midi2_block *bp; int i, num_eps, blk; - midi2 = kzalloc(sizeof(*midi2), GFP_KERNEL); + midi2 = kzalloc_obj(*midi2); if (!midi2) return ERR_PTR(-ENOMEM); @@ -2855,8 +2854,8 @@ static struct usb_function *f_midi2_alloc(struct usb_function_instance *fi) } } - midi2->string_defs = kcalloc(midi2->total_blocks + 1, - sizeof(*midi2->string_defs), GFP_KERNEL); + midi2->string_defs = kzalloc_objs(*midi2->string_defs, + midi2->total_blocks + 1); if (!midi2->string_defs) { do_f_midi2_free(midi2, opts); return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_ncm.c b/drivers/usb/gadget/function/f_ncm.c index 0e38330271d5..a6fa5ed3d6cb 100644 --- a/drivers/usb/gadget/function/f_ncm.c +++ b/drivers/usb/gadget/function/f_ncm.c @@ -1439,6 +1439,7 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) struct f_ncm_opts *ncm_opts; struct usb_os_desc_table *os_desc_table __free(kfree) = NULL; + struct net_device *net __free(detach_gadget) = NULL; struct usb_request *request __free(free_usb_request) = NULL; if (!can_support_ecm(cdev->gadget)) @@ -1452,18 +1453,19 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) return -ENOMEM; } - mutex_lock(&ncm_opts->lock); - gether_set_gadget(ncm_opts->net, cdev->gadget); - if (!ncm_opts->bound) { - ncm_opts->net->mtu = (ncm_opts->max_segment_size - ETH_HLEN); - status = gether_register_netdev(ncm_opts->net); - } - mutex_unlock(&ncm_opts->lock); + scoped_guard(mutex, &ncm_opts->lock) + if (ncm_opts->bind_count == 0) { + if (!device_is_registered(&ncm_opts->net->dev)) { + ncm_opts->net->mtu = (ncm_opts->max_segment_size - ETH_HLEN); + gether_set_gadget(ncm_opts->net, cdev->gadget); + status = gether_register_netdev(ncm_opts->net); + } else + status = gether_attach_gadget(ncm_opts->net, cdev->gadget); - if (status) - return status; - - ncm_opts->bound = true; + if (status) + return status; + net = ncm_opts->net; + } ncm_string_defs[1].s = ncm->ethaddr; @@ -1564,6 +1566,9 @@ static int ncm_bind(struct usb_configuration *c, struct usb_function *f) } ncm->notify_req = no_free_ptr(request); + ncm_opts->bind_count++; + retain_and_null_ptr(net); + DBG(cdev, "CDC Network: IN/%s OUT/%s NOTIFY/%s\n", ncm->port.in_ep->name, ncm->port.out_ep->name, ncm->notify->name); @@ -1655,7 +1660,7 @@ static void ncm_free_inst(struct usb_function_instance *f) struct f_ncm_opts *opts; opts = container_of(f, struct f_ncm_opts, func_inst); - if (opts->bound) + if (device_is_registered(&opts->net->dev)) gether_cleanup(netdev_priv(opts->net)); else free_netdev(opts->net); @@ -1670,7 +1675,7 @@ static struct usb_function_instance *ncm_alloc_inst(void) char *names[1]; struct config_group *ncm_interf_group; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); opts->ncm_os_desc.ext_compat_id = opts->ncm_ext_compat_id; @@ -1718,9 +1723,12 @@ static void ncm_free(struct usb_function *f) static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) { struct f_ncm *ncm = func_to_ncm(f); + struct f_ncm_opts *ncm_opts; DBG(c->cdev, "ncm unbind\n"); + ncm_opts = container_of(f->fi, struct f_ncm_opts, func_inst); + hrtimer_cancel(&ncm->task_timer); kfree(f->os_desc_table); @@ -1736,6 +1744,10 @@ static void ncm_unbind(struct usb_configuration *c, struct usb_function *f) kfree(ncm->notify_req->buf); usb_ep_free_request(ncm->notify, ncm->notify_req); + + ncm_opts->bind_count--; + if (ncm_opts->bind_count == 0) + gether_detach_gadget(ncm_opts->net); } static struct usb_function *ncm_alloc(struct usb_function_instance *fi) diff --git a/drivers/usb/gadget/function/f_obex.c b/drivers/usb/gadget/function/f_obex.c index 1305e2326cdf..715bb0decd3b 100644 --- a/drivers/usb/gadget/function/f_obex.c +++ b/drivers/usb/gadget/function/f_obex.c @@ -390,7 +390,7 @@ static void obex_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations obex_item_ops = { +static const struct configfs_item_operations obex_item_ops = { .release = obex_attr_release, }; @@ -426,7 +426,7 @@ static struct usb_function_instance *obex_alloc_inst(void) struct f_serial_opts *opts; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -461,7 +461,7 @@ static struct usb_function *obex_alloc(struct usb_function_instance *fi) struct f_serial_opts *opts; /* allocate and initialize one new instance */ - obex = kzalloc(sizeof(*obex), GFP_KERNEL); + obex = kzalloc_obj(*obex); if (!obex) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_phonet.c b/drivers/usb/gadget/function/f_phonet.c index 0aa9e8224cae..2c007790ead2 100644 --- a/drivers/usb/gadget/function/f_phonet.c +++ b/drivers/usb/gadget/function/f_phonet.c @@ -585,7 +585,7 @@ static void phonet_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations phonet_item_ops = { +static const struct configfs_item_operations phonet_item_ops = { .release = phonet_attr_release, }; @@ -623,7 +623,7 @@ static struct usb_function_instance *phonet_alloc_inst(void) { struct f_phonet_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -669,7 +669,7 @@ static struct usb_function *phonet_alloc(struct usb_function_instance *fi) struct f_phonet *fp; struct f_phonet_opts *opts; - fp = kzalloc(struct_size(fp, out_reqv, phonet_rxq_size), GFP_KERNEL); + fp = kzalloc_flex(*fp, out_reqv, phonet_rxq_size); if (!fp) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_printer.c b/drivers/usb/gadget/function/f_printer.c index d295ade8fa67..e4f7828ae75d 100644 --- a/drivers/usb/gadget/function/f_printer.c +++ b/drivers/usb/gadget/function/f_printer.c @@ -1220,7 +1220,7 @@ static void printer_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations printer_item_ops = { +static const struct configfs_item_operations printer_item_ops = { .release = printer_attr_release, }; @@ -1374,7 +1374,7 @@ static struct usb_function_instance *gprinter_alloc_inst(void) struct usb_function_instance *ret; int status = 0; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -1482,7 +1482,7 @@ static struct usb_function *gprinter_alloc(struct usb_function_instance *fi) return ERR_PTR(-ENOENT); } - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { mutex_unlock(&opts->lock); return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_rndis.c b/drivers/usb/gadget/function/f_rndis.c index 7451e7cb7a85..8b11d8d6d89c 100644 --- a/drivers/usb/gadget/function/f_rndis.c +++ b/drivers/usb/gadget/function/f_rndis.c @@ -673,7 +673,7 @@ rndis_bind(struct usb_configuration *c, struct usb_function *f) rndis_opts = container_of(f->fi, struct f_rndis_opts, func_inst); if (cdev->use_os_string) { - os_desc_table = kzalloc(sizeof(*os_desc_table), GFP_KERNEL); + os_desc_table = kzalloc_obj(*os_desc_table); if (!os_desc_table) return -ENOMEM; } @@ -888,7 +888,7 @@ static struct usb_function_instance *rndis_alloc_inst(void) char *names[1]; struct config_group *rndis_interf_group; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); opts->rndis_os_desc.ext_compat_id = opts->rndis_ext_compat_id; @@ -956,7 +956,7 @@ static struct usb_function *rndis_alloc(struct usb_function_instance *fi) struct rndis_params *params; /* allocate and initialize one new instance */ - rndis = kzalloc(sizeof(*rndis), GFP_KERNEL); + rndis = kzalloc_obj(*rndis); if (!rndis) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_serial.c b/drivers/usb/gadget/function/f_serial.c index 0f266bc067f5..ae8813c67bc7 100644 --- a/drivers/usb/gadget/function/f_serial.c +++ b/drivers/usb/gadget/function/f_serial.c @@ -260,7 +260,7 @@ static void serial_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations serial_item_ops = { +static const struct configfs_item_operations serial_item_ops = { .release = serial_attr_release, }; @@ -317,7 +317,7 @@ static struct usb_function_instance *gser_alloc_inst(void) struct f_serial_opts *opts; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -376,7 +376,7 @@ static struct usb_function *gser_alloc(struct usb_function_instance *fi) struct f_serial_opts *opts; /* allocate and initialize one new instance */ - gser = kzalloc(sizeof(*gser), GFP_KERNEL); + gser = kzalloc_obj(*gser); if (!gser) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_sourcesink.c b/drivers/usb/gadget/function/f_sourcesink.c index ec5fd25020fd..d2b707e41669 100644 --- a/drivers/usb/gadget/function/f_sourcesink.c +++ b/drivers/usb/gadget/function/f_sourcesink.c @@ -46,6 +46,7 @@ struct f_sourcesink { unsigned isoc_mult; unsigned isoc_maxburst; unsigned buflen; + unsigned bulk_maxburst; unsigned bulk_qlen; unsigned iso_qlen; }; @@ -328,6 +329,12 @@ sourcesink_bind(struct usb_configuration *c, struct usb_function *f) source_sink_intf_alt0.bInterfaceNumber = id; source_sink_intf_alt1.bInterfaceNumber = id; + if (ss->bulk_maxburst > 15) + ss->bulk_maxburst = 15; + + ss_source_comp_desc.bMaxBurst = ss->bulk_maxburst; + ss_sink_comp_desc.bMaxBurst = ss->bulk_maxburst; + /* allocate bulk endpoints */ ss->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc); if (!ss->in_ep) { @@ -837,7 +844,7 @@ static struct usb_function *source_sink_alloc_func( struct f_sourcesink *ss; struct f_ss_opts *ss_opts; - ss = kzalloc(sizeof(*ss), GFP_KERNEL); + ss = kzalloc_obj(*ss); if (!ss) return ERR_PTR(-ENOMEM); @@ -853,6 +860,7 @@ static struct usb_function *source_sink_alloc_func( ss->isoc_mult = ss_opts->isoc_mult; ss->isoc_maxburst = ss_opts->isoc_maxburst; ss->buflen = ss_opts->bulk_buflen; + ss->bulk_maxburst = ss_opts->bulk_maxburst; ss->bulk_qlen = ss_opts->bulk_qlen; ss->iso_qlen = ss_opts->iso_qlen; @@ -882,7 +890,7 @@ static void ss_attr_release(struct config_item *item) usb_put_function_instance(&ss_opts->func_inst); } -static struct configfs_item_operations ss_item_ops = { +static const struct configfs_item_operations ss_item_ops = { .release = ss_attr_release, }; @@ -1101,6 +1109,49 @@ static ssize_t f_ss_opts_isoc_maxburst_store(struct config_item *item, CONFIGFS_ATTR(f_ss_opts_, isoc_maxburst); +static ssize_t f_ss_opts_bulk_maxburst_show(struct config_item *item, char *page) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int result; + + mutex_lock(&opts->lock); + result = sysfs_emit(page, "%u\n", opts->bulk_maxburst); + mutex_unlock(&opts->lock); + + return result; +} + +static ssize_t f_ss_opts_bulk_maxburst_store(struct config_item *item, + const char *page, size_t len) +{ + struct f_ss_opts *opts = to_f_ss_opts(item); + int ret; + u8 num; + + mutex_lock(&opts->lock); + if (opts->refcnt) { + ret = -EBUSY; + goto end; + } + + ret = kstrtou8(page, 0, &num); + if (ret) + goto end; + + if (num > 15) { + ret = -EINVAL; + goto end; + } + + opts->bulk_maxburst = num; + ret = len; +end: + mutex_unlock(&opts->lock); + return ret; +} + +CONFIGFS_ATTR(f_ss_opts_, bulk_maxburst); + static ssize_t f_ss_opts_bulk_buflen_show(struct config_item *item, char *page) { struct f_ss_opts *opts = to_f_ss_opts(item); @@ -1222,6 +1273,7 @@ static struct configfs_attribute *ss_attrs[] = { &f_ss_opts_attr_isoc_mult, &f_ss_opts_attr_isoc_maxburst, &f_ss_opts_attr_bulk_buflen, + &f_ss_opts_attr_bulk_maxburst, &f_ss_opts_attr_bulk_qlen, &f_ss_opts_attr_iso_qlen, NULL, @@ -1245,7 +1297,7 @@ static struct usb_function_instance *source_sink_alloc_inst(void) { struct f_ss_opts *ss_opts; - ss_opts = kzalloc(sizeof(*ss_opts), GFP_KERNEL); + ss_opts = kzalloc_obj(*ss_opts); if (!ss_opts) return ERR_PTR(-ENOMEM); mutex_init(&ss_opts->lock); diff --git a/drivers/usb/gadget/function/f_subset.c b/drivers/usb/gadget/function/f_subset.c index ea3fdd842462..076072386e5e 100644 --- a/drivers/usb/gadget/function/f_subset.c +++ b/drivers/usb/gadget/function/f_subset.c @@ -428,7 +428,7 @@ static struct usb_function_instance *geth_alloc_inst(void) { struct f_gether_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); mutex_init(&opts->lock); @@ -467,7 +467,7 @@ static struct usb_function *geth_alloc(struct usb_function_instance *fi) int status; /* allocate and initialize one new instance */ - geth = kzalloc(sizeof(*geth), GFP_KERNEL); + geth = kzalloc_obj(*geth); if (!geth) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 6e8804f04baa..a7853dcbb14c 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1222,12 +1222,19 @@ static void usbg_submit_cmd(struct usbg_cmd *cmd) se_cmd = &cmd->se_cmd; tpg = cmd->fu->tpg; tv_nexus = tpg->tpg_nexus; + if (!tv_nexus) { + struct usb_gadget *gadget = fuas_to_gadget(cmd->fu); + + dev_err(&gadget->dev, "Missing nexus, ignoring command\n"); + return; + } + dir = get_cmd_dir(cmd->cmd_buf); if (dir < 0) goto out; target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf, - cmd->sense_iu.sense, cmd->unpacked_lun, 0, + cmd->sense_iu.sense, cmd->unpacked_lun, cmd->data_len, cmd->prio_attr, dir, flags); return; @@ -1389,6 +1396,7 @@ static int usbg_submit_command(struct f_uas *fu, struct usb_request *req) cmd->tmr_func = 0; cmd->tmr_rsp = RC_RESPONSE_UNKNOWN; cmd->flags = 0; + cmd->data_len = 0; cmd_iu = (struct command_iu *)iu; @@ -1482,6 +1490,13 @@ static void bot_cmd_work(struct work_struct *work) se_cmd = &cmd->se_cmd; tpg = cmd->fu->tpg; tv_nexus = tpg->tpg_nexus; + if (!tv_nexus) { + struct usb_gadget *gadget = fuas_to_gadget(cmd->fu); + + dev_err(&gadget->dev, "Missing nexus, ignoring command\n"); + return; + } + dir = get_cmd_dir(cmd->cmd_buf); if (dir < 0) goto out; @@ -1675,7 +1690,7 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn, goto unlock_dep; } - tpg = kzalloc(sizeof(struct usbg_tpg), GFP_KERNEL); + tpg = kzalloc_obj(struct usbg_tpg); ret = -ENOMEM; if (!tpg) goto unref_dep; @@ -1767,7 +1782,7 @@ static struct se_wwn *usbg_make_tport( if (!wnn_name) return ERR_PTR(-EINVAL); - tport = kzalloc(sizeof(struct usbg_tport), GFP_KERNEL); + tport = kzalloc_obj(struct usbg_tport); if (!(tport)) return ERR_PTR(-ENOMEM); @@ -1860,7 +1875,7 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name) goto out_unlock; } - tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); + tv_nexus = kzalloc_obj(*tv_nexus); if (!tv_nexus) { ret = -ENOMEM; goto out_unlock; @@ -2399,7 +2414,7 @@ static int tcm_set_alt(struct usb_function *f, unsigned intf, unsigned alt) if ((alt == USB_G_ALT_INT_BBB) || (alt == USB_G_ALT_INT_UAS)) { struct guas_setup_wq *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (!work) return -ENOMEM; INIT_WORK(&work->work, tcm_delayed_set_alt); @@ -2446,7 +2461,7 @@ static void tcm_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations tcm_item_ops = { +static const struct configfs_item_operations tcm_item_ops = { .release = tcm_attr_release, }; @@ -2534,7 +2549,7 @@ static struct usb_function_instance *tcm_alloc_inst(void) int i; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -2589,7 +2604,7 @@ static struct usb_function *tcm_alloc(struct usb_function_instance *fi) return ERR_PTR(-ENODEV); } - fu = kzalloc(sizeof(*fu), GFP_KERNEL); + fu = kzalloc_obj(*fu); if (!fu) { mutex_unlock(&tpg_instances_lock); return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 9da9fb4e1239..85c502e98f57 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -451,7 +451,7 @@ static int audio_notify(struct g_audio *audio, int unit_id, int cs) goto err_dec_int_count; } - msg = kmalloc(sizeof(*msg), GFP_ATOMIC); + msg = kmalloc_obj(*msg, GFP_ATOMIC); if (msg == NULL) { ret = -ENOMEM; goto err_free_request; @@ -1512,7 +1512,7 @@ static void f_uac1_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations f_uac1_item_ops = { +static const struct configfs_item_operations f_uac1_item_ops = { .release = f_uac1_attr_release, }; @@ -1748,7 +1748,7 @@ static struct usb_function_instance *f_audio_alloc_inst(void) { struct f_uac1_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -1831,7 +1831,7 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) struct f_uac1_opts *opts; /* allocate and initialize one new instance */ - uac1 = kzalloc(sizeof(*uac1), GFP_KERNEL); + uac1 = kzalloc_obj(*uac1); if (!uac1) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_uac1_legacy.c b/drivers/usb/gadget/function/f_uac1_legacy.c index 49cf5aae90ca..a0c953a99727 100644 --- a/drivers/usb/gadget/function/f_uac1_legacy.c +++ b/drivers/usb/gadget/function/f_uac1_legacy.c @@ -251,7 +251,7 @@ static struct f_audio_buf *f_audio_buffer_alloc(int buf_size) { struct f_audio_buf *copy_buf; - copy_buf = kzalloc(sizeof *copy_buf, GFP_ATOMIC); + copy_buf = kzalloc_obj(*copy_buf, GFP_ATOMIC); if (!copy_buf) return ERR_PTR(-ENOMEM); @@ -812,7 +812,7 @@ static void f_uac1_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations f_uac1_item_ops = { +static const struct configfs_item_operations f_uac1_item_ops = { .release = f_uac1_attr_release, }; @@ -942,7 +942,7 @@ static struct usb_function_instance *f_audio_alloc_inst(void) { struct f_uac1_legacy_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -985,7 +985,7 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) struct f_uac1_legacy_opts *opts; /* allocate and initialize one new instance */ - audio = kzalloc(sizeof(*audio), GFP_KERNEL); + audio = kzalloc_obj(*audio); if (!audio) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index dd252ff2fb4e..897787d0803c 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -1388,7 +1388,7 @@ afunc_notify(struct g_audio *agdev, int unit_id, int cs) goto err_dec_int_count; } - msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + msg = kzalloc_obj(*msg, GFP_ATOMIC); if (msg == NULL) { ret = -ENOMEM; goto err_free_request; @@ -1874,7 +1874,7 @@ static void f_uac2_attr_release(struct config_item *item) usb_put_function_instance(&opts->func_inst); } -static struct configfs_item_operations f_uac2_item_ops = { +static const struct configfs_item_operations f_uac2_item_ops = { .release = f_uac2_attr_release, }; @@ -2189,7 +2189,7 @@ static struct usb_function_instance *afunc_alloc_inst(void) { struct f_uac2_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); @@ -2278,7 +2278,7 @@ static struct usb_function *afunc_alloc(struct usb_function_instance *fi) struct f_uac2 *uac2; struct f_uac2_opts *opts; - uac2 = kzalloc(sizeof(*uac2), GFP_KERNEL); + uac2 = kzalloc_obj(*uac2); if (uac2 == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c index a96476507d2f..494fdbc4e85b 100644 --- a/drivers/usb/gadget/function/f_uvc.c +++ b/drivers/usb/gadget/function/f_uvc.c @@ -887,7 +887,7 @@ static struct usb_function_instance *uvc_alloc_inst(void) struct uvc_descriptor_header **ctl_cls; int ret; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return ERR_PTR(-ENOMEM); opts->func_inst.free_func_inst = uvc_free_inst; @@ -1042,7 +1042,7 @@ static struct usb_function *uvc_alloc(struct usb_function_instance *fi) struct uvc_descriptor_header **strm_cls; struct config_item *streaming, *header, *h; - uvc = kzalloc(sizeof(*uvc), GFP_KERNEL); + uvc = kzalloc_obj(*uvc); if (uvc == NULL) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/gadget/function/g_zero.h b/drivers/usb/gadget/function/g_zero.h index 98b8462ad538..7bd66004821f 100644 --- a/drivers/usb/gadget/function/g_zero.h +++ b/drivers/usb/gadget/function/g_zero.h @@ -34,6 +34,7 @@ struct f_ss_opts { unsigned isoc_mult; unsigned isoc_maxburst; unsigned bulk_buflen; + unsigned bulk_maxburst; unsigned bulk_qlen; unsigned iso_qlen; diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index afd75d72412c..3da54a7d7aba 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -892,7 +892,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v) return ERR_PTR(-ENODEV); } - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) { rndis_put_nr(i); diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c index ca8dbec65f73..e53f2927b539 100644 --- a/drivers/usb/gadget/function/u_audio.c +++ b/drivers/usb/gadget/function/u_audio.c @@ -1191,7 +1191,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, if (!g_audio) return -EINVAL; - uac = kzalloc(sizeof(*uac), GFP_KERNEL); + uac = kzalloc_obj(*uac); if (!uac) return -ENOMEM; g_audio->uac = uac; @@ -1209,9 +1209,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, prm->max_psize = g_audio->out_ep_maxpsize; prm->srate = params->c_srates[0]; - prm->reqs = kcalloc(params->req_number, - sizeof(struct usb_request *), - GFP_KERNEL); + prm->reqs = kzalloc_objs(struct usb_request *, + params->req_number); if (!prm->reqs) { err = -ENOMEM; goto fail; @@ -1234,9 +1233,8 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, prm->max_psize = g_audio->in_ep_maxpsize; prm->srate = params->p_srates[0]; - prm->reqs = kcalloc(params->req_number, - sizeof(struct usb_request *), - GFP_KERNEL); + prm->reqs = kzalloc_objs(struct usb_request *, + params->req_number); if (!prm->reqs) { err = -ENOMEM; goto fail; diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c index c47965d850d4..1a9e7c495e2e 100644 --- a/drivers/usb/gadget/function/u_ether.c +++ b/drivers/usb/gadget/function/u_ether.c @@ -897,6 +897,28 @@ void gether_set_gadget(struct net_device *net, struct usb_gadget *g) } EXPORT_SYMBOL_GPL(gether_set_gadget); +int gether_attach_gadget(struct net_device *net, struct usb_gadget *g) +{ + int ret; + + ret = device_move(&net->dev, &g->dev, DPM_ORDER_DEV_AFTER_PARENT); + if (ret) + return ret; + + gether_set_gadget(net, g); + return 0; +} +EXPORT_SYMBOL_GPL(gether_attach_gadget); + +void gether_detach_gadget(struct net_device *net) +{ + struct eth_dev *dev = netdev_priv(net); + + device_move(&net->dev, NULL, DPM_ORDER_NONE); + dev->gadget = NULL; +} +EXPORT_SYMBOL_GPL(gether_detach_gadget); + int gether_set_dev_addr(struct net_device *net, const char *dev_addr) { struct eth_dev *dev; diff --git a/drivers/usb/gadget/function/u_ether.h b/drivers/usb/gadget/function/u_ether.h index 34be220cef77..c85a1cf3c115 100644 --- a/drivers/usb/gadget/function/u_ether.h +++ b/drivers/usb/gadget/function/u_ether.h @@ -150,6 +150,32 @@ static inline struct net_device *gether_setup_default(void) */ void gether_set_gadget(struct net_device *net, struct usb_gadget *g); +/** + * gether_attach_gadget - Reparent net_device to the gadget device. + * @net: The network device to reparent. + * @g: The target USB gadget device to parent to. + * + * This function moves the network device to be a child of the USB gadget + * device in the device hierarchy. This is typically done when the function + * is bound to a configuration. + * + * Returns 0 on success, or a negative error code on failure. + */ +int gether_attach_gadget(struct net_device *net, struct usb_gadget *g); + +/** + * gether_detach_gadget - Detach net_device from its gadget parent. + * @net: The network device to detach. + * + * This function moves the network device to be a child of the virtual + * devices parent, effectively detaching it from the USB gadget device + * hierarchy. This is typically done when the function is unbound + * from a configuration but the instance is not yet freed. + */ +void gether_detach_gadget(struct net_device *net); + +DEFINE_FREE(detach_gadget, struct net_device *, if (_T) gether_detach_gadget(_T)) + /** * gether_set_dev_addr - initialize an ethernet-over-usb link with eth address * @net: device representing this link diff --git a/drivers/usb/gadget/function/u_ether_configfs.h b/drivers/usb/gadget/function/u_ether_configfs.h index f558c3139ebe..51f0d79e5eca 100644 --- a/drivers/usb/gadget/function/u_ether_configfs.h +++ b/drivers/usb/gadget/function/u_ether_configfs.h @@ -21,7 +21,7 @@ usb_put_function_instance(&opts->func_inst); \ } \ \ - static struct configfs_item_operations _f_##_item_ops = { \ + static const struct configfs_item_operations _f_##_item_ops = { \ .release = _f_##_attr_release, \ } diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h index 2e400b495cb8..41cb8aa73f09 100644 --- a/drivers/usb/gadget/function/u_midi.h +++ b/drivers/usb/gadget/function/u_midi.h @@ -19,7 +19,7 @@ struct f_midi_opts { struct usb_function_instance func_inst; int index; char *id; - bool id_allocated; + char *interface_string; unsigned int in_ports; unsigned int out_ports; unsigned int buflen; diff --git a/drivers/usb/gadget/function/u_ncm.h b/drivers/usb/gadget/function/u_ncm.h index 49ec095cdb4b..b1f3db8b68c1 100644 --- a/drivers/usb/gadget/function/u_ncm.h +++ b/drivers/usb/gadget/function/u_ncm.h @@ -18,7 +18,7 @@ struct f_ncm_opts { struct usb_function_instance func_inst; struct net_device *net; - bool bound; + int bind_count; struct config_group *ncm_interf_group; struct usb_os_desc ncm_os_desc; diff --git a/drivers/usb/gadget/function/u_serial.c b/drivers/usb/gadget/function/u_serial.c index 1cce5317181a..e43ad6373846 100644 --- a/drivers/usb/gadget/function/u_serial.c +++ b/drivers/usb/gadget/function/u_serial.c @@ -1082,7 +1082,7 @@ static int gs_console_init(struct gs_port *port) if (port->console) return 0; - cons = kzalloc(sizeof(*port->console), GFP_KERNEL); + cons = kzalloc_obj(*port->console); if (!cons) return -ENOMEM; @@ -1215,7 +1215,7 @@ gs_port_alloc(unsigned port_num, struct usb_cdc_line_coding *coding) goto out; } - port = kzalloc(sizeof(struct gs_port), GFP_KERNEL); + port = kzalloc_obj(struct gs_port); if (port == NULL) { ret = -ENOMEM; goto out; diff --git a/drivers/usb/gadget/function/u_uac1_legacy.c b/drivers/usb/gadget/function/u_uac1_legacy.c index dd21c251542c..01016102fa17 100644 --- a/drivers/usb/gadget/function/u_uac1_legacy.c +++ b/drivers/usb/gadget/function/u_uac1_legacy.c @@ -106,7 +106,7 @@ static int playback_default_hw_params(struct gaudio_snd_dev *snd) snd->channels = 2; snd->rate = 48000; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c index 5a87516ddb31..70a1415ea401 100644 --- a/drivers/usb/gadget/function/uvc_configfs.c +++ b/drivers/usb/gadget/function/uvc_configfs.c @@ -128,7 +128,7 @@ static void uvcg_config_item_release(struct config_item *item) kfree(group); } -static struct configfs_item_operations uvcg_config_item_ops = { +static const struct configfs_item_operations uvcg_config_item_ops = { .release = uvcg_config_item_release, }; @@ -158,7 +158,7 @@ static int uvcg_config_create_group(struct config_group *parent, { struct config_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; @@ -270,7 +270,7 @@ static struct config_item *uvcg_control_header_make(struct config_group *group, { struct uvcg_control_header *h; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -285,7 +285,7 @@ static struct config_item *uvcg_control_header_make(struct config_group *group, return &h->item; } -static struct configfs_group_operations uvcg_control_header_grp_ops = { +static const struct configfs_group_operations uvcg_control_header_grp_ops = { .make_item = uvcg_control_header_make, }; @@ -1233,7 +1233,7 @@ static void uvcg_extension_drop_link(struct config_item *src, struct config_item mutex_unlock(su_mutex); } -static struct configfs_item_operations uvcg_extension_item_ops = { +static const struct configfs_item_operations uvcg_extension_item_ops = { .release = uvcg_extension_release, .allow_link = uvcg_extension_allow_link, .drop_link = uvcg_extension_drop_link, @@ -1273,7 +1273,7 @@ static struct config_item *uvcg_extension_make(struct config_group *group, const opts_item = group->cg_item.ci_parent->ci_parent; opts = to_f_uvc_opts(opts_item); - xu = kzalloc(sizeof(*xu), GFP_KERNEL); + xu = kzalloc_obj(*xu); if (!xu) return ERR_PTR(-ENOMEM); @@ -1298,7 +1298,7 @@ static struct config_item *uvcg_extension_make(struct config_group *group, const return &xu->item; } -static struct configfs_group_operations uvcg_extensions_grp_ops = { +static const struct configfs_group_operations uvcg_extensions_grp_ops = { .make_item = uvcg_extension_make, .drop_item = uvcg_extension_drop, }; @@ -1414,7 +1414,7 @@ static void uvcg_control_class_drop_link(struct config_item *src, mutex_unlock(su_mutex); } -static struct configfs_item_operations uvcg_control_class_item_ops = { +static const struct configfs_item_operations uvcg_control_class_item_ops = { .release = uvcg_config_item_release, .allow_link = uvcg_control_class_allow_link, .drop_link = uvcg_control_class_drop_link, @@ -1437,7 +1437,7 @@ static int uvcg_control_class_create_children(struct config_group *parent) for (i = 0; i < ARRAY_SIZE(names); ++i) { struct uvcg_control_class_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; @@ -1664,7 +1664,7 @@ static void uvcg_format_drop_link(struct config_item *src, struct config_item *t mutex_unlock(su_mutex); } -static struct configfs_item_operations uvcg_format_item_operations = { +static const struct configfs_item_operations uvcg_format_item_operations = { .release = uvcg_config_item_release, .allow_link = uvcg_format_allow_link, .drop_link = uvcg_format_drop_link, @@ -1785,7 +1785,7 @@ static int uvcg_streaming_header_allow_link(struct config_item *src, uvcg_format_set_indices(to_config_group(target)); - format_ptr = kzalloc(sizeof(*format_ptr), GFP_KERNEL); + format_ptr = kzalloc_obj(*format_ptr); if (!format_ptr) { ret = -ENOMEM; goto out; @@ -1840,7 +1840,7 @@ static void uvcg_streaming_header_drop_link(struct config_item *src, mutex_unlock(su_mutex); } -static struct configfs_item_operations uvcg_streaming_header_item_ops = { +static const struct configfs_item_operations uvcg_streaming_header_item_ops = { .release = uvcg_config_item_release, .allow_link = uvcg_streaming_header_allow_link, .drop_link = uvcg_streaming_header_drop_link, @@ -1899,7 +1899,7 @@ static struct config_item { struct uvcg_streaming_header *h; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -1914,7 +1914,7 @@ static struct config_item return &h->item; } -static struct configfs_group_operations uvcg_streaming_header_grp_ops = { +static const struct configfs_group_operations uvcg_streaming_header_grp_ops = { .make_item = uvcg_streaming_header_make, }; @@ -2163,7 +2163,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group, struct config_item *opts_item; struct uvcg_frame_ptr *frame_ptr; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -2197,7 +2197,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group, return ERR_PTR(-EINVAL); } - frame_ptr = kzalloc(sizeof(*frame_ptr), GFP_KERNEL); + frame_ptr = kzalloc_obj(*frame_ptr); if (!frame_ptr) { mutex_unlock(&opts->lock); kfree(h); @@ -2261,7 +2261,7 @@ static void uvcg_format_set_indices(struct config_group *fmt) * streaming/uncompressed/ */ -static struct configfs_group_operations uvcg_uncompressed_group_ops = { +static const struct configfs_group_operations uvcg_uncompressed_group_ops = { .make_item = uvcg_frame_make, .drop_item = uvcg_frame_drop, }; @@ -2483,7 +2483,7 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group, if (!color_match) return ERR_PTR(-EINVAL); - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -2508,7 +2508,7 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group, return &h->fmt.group; } -static struct configfs_group_operations uvcg_uncompressed_grp_ops = { +static const struct configfs_group_operations uvcg_uncompressed_grp_ops = { .make_group = uvcg_uncompressed_make, }; @@ -2525,7 +2525,7 @@ static const struct uvcg_config_group_type uvcg_uncompressed_grp_type = { * streaming/mjpeg/ */ -static struct configfs_group_operations uvcg_mjpeg_group_ops = { +static const struct configfs_group_operations uvcg_mjpeg_group_ops = { .make_item = uvcg_frame_make, .drop_item = uvcg_frame_drop, }; @@ -2675,7 +2675,7 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group, if (!color_match) return ERR_PTR(-EINVAL); - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -2698,7 +2698,7 @@ static struct config_group *uvcg_mjpeg_make(struct config_group *group, return &h->fmt.group; } -static struct configfs_group_operations uvcg_mjpeg_grp_ops = { +static const struct configfs_group_operations uvcg_mjpeg_grp_ops = { .make_group = uvcg_mjpeg_make, }; @@ -2715,7 +2715,7 @@ static const struct uvcg_config_group_type uvcg_mjpeg_grp_type = { * streaming/framebased/ */ -static struct configfs_group_operations uvcg_framebased_group_ops = { +static const struct configfs_group_operations uvcg_framebased_group_ops = { .make_item = uvcg_frame_make, .drop_item = uvcg_frame_drop, }; @@ -2926,7 +2926,7 @@ static struct config_group *uvcg_framebased_make(struct config_group *group, if (!color_match) return ERR_PTR(-EINVAL); - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (!h) return ERR_PTR(-ENOMEM); @@ -2953,7 +2953,7 @@ static struct config_group *uvcg_framebased_make(struct config_group *group, return &h->fmt.group; } -static struct configfs_group_operations uvcg_framebased_grp_ops = { +static const struct configfs_group_operations uvcg_framebased_grp_ops = { .make_group = uvcg_framebased_make, }; @@ -3056,7 +3056,7 @@ static void uvcg_color_matching_release(struct config_item *item) kfree(color_match); } -static struct configfs_item_operations uvcg_color_matching_item_ops = { +static const struct configfs_item_operations uvcg_color_matching_item_ops = { .release = uvcg_color_matching_release, }; @@ -3075,7 +3075,7 @@ static struct config_group *uvcg_color_matching_make(struct config_group *group, { struct uvcg_color_matching *color_match; - color_match = kzalloc(sizeof(*color_match), GFP_KERNEL); + color_match = kzalloc_obj(*color_match); if (!color_match) return ERR_PTR(-ENOMEM); @@ -3089,7 +3089,7 @@ static struct config_group *uvcg_color_matching_make(struct config_group *group, return &color_match->group; } -static struct configfs_group_operations uvcg_color_matching_grp_group_ops = { +static const struct configfs_group_operations uvcg_color_matching_grp_group_ops = { .make_group = uvcg_color_matching_make, }; @@ -3097,7 +3097,7 @@ static int uvcg_color_matching_create_children(struct config_group *parent) { struct uvcg_color_matching *color_match; - color_match = kzalloc(sizeof(*color_match), GFP_KERNEL); + color_match = kzalloc_obj(*color_match); if (!color_match) return -ENOMEM; @@ -3530,7 +3530,7 @@ static void uvcg_streaming_class_drop_link(struct config_item *src, mutex_unlock(su_mutex); } -static struct configfs_item_operations uvcg_streaming_class_item_ops = { +static const struct configfs_item_operations uvcg_streaming_class_item_ops = { .release = uvcg_config_item_release, .allow_link = uvcg_streaming_class_allow_link, .drop_link = uvcg_streaming_class_drop_link, @@ -3553,7 +3553,7 @@ static int uvcg_streaming_class_create_children(struct config_group *parent) for (i = 0; i < ARRAY_SIZE(names); ++i) { struct uvcg_streaming_class_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return -ENOMEM; @@ -3698,7 +3698,7 @@ static void uvc_func_drop_link(struct config_item *src, struct config_item *tgt) mutex_unlock(&opts->lock); } -static struct configfs_item_operations uvc_func_item_ops = { +static const struct configfs_item_operations uvc_func_item_ops = { .release = uvc_func_item_release, .allow_link = uvc_func_allow_link, .drop_link = uvc_func_drop_link, diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c index fd4b998ccd16..ed48d38498fb 100644 --- a/drivers/usb/gadget/function/uvc_v4l2.c +++ b/drivers/usb/gadget/function/uvc_v4l2.c @@ -667,7 +667,7 @@ uvc_v4l2_open(struct file *file) struct uvc_device *uvc = video_get_drvdata(vdev); struct uvc_file_handle *handle; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (handle == NULL) return -ENOMEM; diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c index f568dee08b3b..2f9700b3f1b6 100644 --- a/drivers/usb/gadget/function/uvc_video.c +++ b/drivers/usb/gadget/function/uvc_video.c @@ -513,7 +513,7 @@ uvc_video_prep_requests(struct uvc_video *video) return; } - interval_duration = 2 << (video->ep->desc->bInterval - 1); + interval_duration = 1 << (video->ep->desc->bInterval - 1); if (cdev->gadget->speed < USB_SPEED_HIGH) interval_duration *= 10000; else @@ -559,7 +559,7 @@ uvc_video_alloc_requests(struct uvc_video *video) uvc_video_prep_requests(video); for (i = 0; i < video->uvc_num_requests; i++) { - ureq = kzalloc(sizeof(struct uvc_request), GFP_KERNEL); + ureq = kzalloc_obj(struct uvc_request); if (ureq == NULL) goto error; diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index d70fb5bc2357..03032ea6f701 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -298,7 +298,7 @@ static int dbgp_bind(struct usb_gadget *gadget, dbgp.req->length = DBGP_REQ_EP0_LEN; #ifdef CONFIG_USB_G_DBGP_SERIAL - dbgp.serial = kzalloc(sizeof(struct gserial), GFP_KERNEL); + dbgp.serial = kzalloc_obj(struct gserial); if (!dbgp.serial) { stp = 3; err = -ENOMEM; diff --git a/drivers/usb/gadget/legacy/g_ffs.c b/drivers/usb/gadget/legacy/g_ffs.c index 578556422ea3..dc59e625aca8 100644 --- a/drivers/usb/gadget/legacy/g_ffs.c +++ b/drivers/usb/gadget/legacy/g_ffs.c @@ -188,7 +188,7 @@ static int __init gfs_init(void) /* * Allocate in one chunk for easier maintenance */ - f_ffs[0] = kcalloc(func_num * N_CONF, sizeof(*f_ffs[0]), GFP_KERNEL); + f_ffs[0] = kzalloc_objs(*f_ffs[0], func_num * N_CONF); if (!f_ffs[0]) { ret = -ENOMEM; goto no_func; @@ -196,7 +196,7 @@ static int __init gfs_init(void) for (i = 1; i < N_CONF; ++i) f_ffs[i] = f_ffs[0] + i * func_num; - fi_ffs = kcalloc(func_num, sizeof(*fi_ffs), GFP_KERNEL); + fi_ffs = kzalloc_objs(*fi_ffs, func_num); if (!fi_ffs) { ret = -ENOMEM; goto no_func; diff --git a/drivers/usb/gadget/legacy/hid.c b/drivers/usb/gadget/legacy/hid.c index 3684546e8801..89722413e5fd 100644 --- a/drivers/usb/gadget/legacy/hid.c +++ b/drivers/usb/gadget/legacy/hid.c @@ -227,7 +227,7 @@ static int hidg_plat_driver_probe(struct platform_device *pdev) return -ENODEV; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 62566a8e7451..d87a8ab51510 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -173,7 +173,7 @@ static struct dev_data *dev_new (void) { struct dev_data *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; dev->state = STATE_DEV_DISABLED; @@ -614,7 +614,7 @@ ep_read_iter(struct kiocb *iocb, struct iov_iter *to) if (value >= 0 && (copy_to_iter(buf, value, to) != value)) value = -EFAULT; } else { - struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); + struct kiocb_priv *priv = kzalloc_obj(*priv); value = -ENOMEM; if (!priv) goto fail; @@ -682,7 +682,7 @@ ep_write_iter(struct kiocb *iocb, struct iov_iter *from) } else if (is_sync_kiocb(iocb)) { value = ep_io(epdata, buf, len); } else { - struct kiocb_priv *priv = kzalloc(sizeof *priv, GFP_KERNEL); + struct kiocb_priv *priv = kzalloc_obj(*priv); value = -ENOMEM; if (priv) { value = ep_aio(iocb, priv, epdata, buf, len); @@ -1598,7 +1598,7 @@ static int activate_ep_files (struct dev_data *dev) gadget_for_each_ep (ep, dev->gadget) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto enomem0; data->state = STATE_EP_DISABLED; diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c index 46f343ba48b3..4febf8dac7ca 100644 --- a/drivers/usb/gadget/legacy/raw_gadget.c +++ b/drivers/usb/gadget/legacy/raw_gadget.c @@ -190,7 +190,7 @@ static struct raw_dev *dev_new(void) { struct raw_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; /* Matches kref_put() in raw_release(). */ @@ -1251,7 +1251,7 @@ static int raw_ioctl_eps_info(struct raw_dev *dev, unsigned long value) struct usb_raw_eps_info *info; struct raw_ep *ep; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { ret = -ENOMEM; goto out; diff --git a/drivers/usb/gadget/udc/amd5536udc_pci.c b/drivers/usb/gadget/udc/amd5536udc_pci.c index a36913ae31f9..cd767b1e3fe7 100644 --- a/drivers/usb/gadget/udc/amd5536udc_pci.c +++ b/drivers/usb/gadget/udc/amd5536udc_pci.c @@ -95,7 +95,7 @@ static int udc_pci_probe( } /* init */ - dev = kzalloc(sizeof(struct udc), GFP_KERNEL); + dev = kzalloc_obj(struct udc); if (!dev) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/aspeed-vhub/core.c b/drivers/usb/gadget/udc/aspeed-vhub/core.c index f2685f89b3e5..4a8b9ff8368f 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/core.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/core.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "vhub.h" @@ -77,7 +78,7 @@ struct usb_request *ast_vhub_alloc_request(struct usb_ep *u_ep, { struct ast_vhub_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; return &req->req; @@ -280,6 +281,8 @@ static void ast_vhub_remove(struct platform_device *pdev) if (vhub->clk) clk_disable_unprepare(vhub->clk); + reset_control_assert(vhub->rst); + spin_unlock_irqrestore(&vhub->lock, flags); if (vhub->ep0_bufs) @@ -294,6 +297,7 @@ static void ast_vhub_remove(struct platform_device *pdev) static int ast_vhub_probe(struct platform_device *pdev) { enum usb_device_speed max_speed; + const u64 *dma_mask_ptr; struct ast_vhub *vhub; struct resource *res; int i, rc = 0; @@ -348,6 +352,16 @@ static int ast_vhub_probe(struct platform_device *pdev) goto err; } + vhub->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL); + if (IS_ERR(vhub->rst)) { + rc = PTR_ERR(vhub->rst); + goto err; + } + + rc = reset_control_deassert(vhub->rst); + if (rc) + goto err; + /* Check if we need to limit the HW to USB1 */ max_speed = usb_get_maximum_speed(&pdev->dev); if (max_speed != USB_SPEED_UNKNOWN && max_speed < USB_SPEED_HIGH) @@ -370,6 +384,12 @@ static int ast_vhub_probe(struct platform_device *pdev) goto err; } + dma_mask_ptr = (u64 *)of_device_get_match_data(&pdev->dev); + if (dma_mask_ptr) { + rc = dma_coerce_mask_and_coherent(&pdev->dev, *dma_mask_ptr); + if (rc) + goto err; + } /* * Allocate DMA buffers for all EP0s in one chunk, * one per port and one for the vHub itself @@ -412,15 +432,25 @@ static int ast_vhub_probe(struct platform_device *pdev) return rc; } +static const u64 dma_mask_32 = DMA_BIT_MASK(32); +static const u64 dma_mask_64 = DMA_BIT_MASK(64); + static const struct of_device_id ast_vhub_dt_ids[] = { { .compatible = "aspeed,ast2400-usb-vhub", + .data = &dma_mask_32, }, { .compatible = "aspeed,ast2500-usb-vhub", + .data = &dma_mask_32, }, { .compatible = "aspeed,ast2600-usb-vhub", + .data = &dma_mask_32, + }, + { + .compatible = "aspeed,ast2700-usb-vhub", + .data = &dma_mask_64, }, { } }; diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c index a09f72772e6e..2ecd049dacc2 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c @@ -560,7 +560,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx) * endpoint 0. */ d->max_epns = min_t(u32, vhub->max_epns, 30); - d->epns = kcalloc(d->max_epns, sizeof(*d->epns), GFP_KERNEL); + d->epns = kzalloc_objs(*d->epns, d->max_epns); if (!d->epns) return -ENOMEM; @@ -569,7 +569,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx) * named "parent" devices for each port so we create a sub device * here for that purpose */ - d->port_dev = kzalloc(sizeof(struct device), GFP_KERNEL); + d->port_dev = kzalloc_obj(struct device); if (!d->port_dev) { rc = -ENOMEM; goto fail_alloc; diff --git a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h index 6b9dfa6e10eb..aca2050e2db0 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/vhub.h +++ b/drivers/usb/gadget/udc/aspeed-vhub/vhub.h @@ -388,6 +388,7 @@ struct ast_vhub { spinlock_t lock; struct work_struct wake_work; struct clk *clk; + struct reset_control *rst; /* EP0 DMA buffers allocated in one chunk */ void *ep0_bufs; diff --git a/drivers/usb/gadget/udc/aspeed_udc.c b/drivers/usb/gadget/udc/aspeed_udc.c index 353bfb1ff0a1..7fc6696b7694 100644 --- a/drivers/usb/gadget/udc/aspeed_udc.c +++ b/drivers/usb/gadget/udc/aspeed_udc.c @@ -452,7 +452,7 @@ static struct usb_request *ast_udc_ep_alloc_request(struct usb_ep *_ep, struct ast_udc_ep *ep = to_ast_ep(_ep); struct ast_udc_request *req; - req = kzalloc(sizeof(struct ast_udc_request), gfp_flags); + req = kzalloc_obj(struct ast_udc_request, gfp_flags); if (!req) { EP_DBG(ep, "request allocation failed\n"); return NULL; diff --git a/drivers/usb/gadget/udc/at91_udc.c b/drivers/usb/gadget/udc/at91_udc.c index 42b94d858e37..5aa360ba4f03 100644 --- a/drivers/usb/gadget/udc/at91_udc.c +++ b/drivers/usb/gadget/udc/at91_udc.c @@ -585,7 +585,7 @@ at91_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct at91_request *req; - req = kzalloc(sizeof (struct at91_request), gfp_flags); + req = kzalloc_obj(struct at91_request, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c index 0c6f2ad81d37..72a2f95ff018 100644 --- a/drivers/usb/gadget/udc/atmel_usba_udc.c +++ b/drivers/usb/gadget/udc/atmel_usba_udc.c @@ -40,7 +40,7 @@ static int queue_dbg_open(struct inode *inode, struct file *file) struct usba_request *req, *req_copy; struct list_head *queue_data; - queue_data = kmalloc(sizeof(*queue_data), GFP_KERNEL); + queue_data = kmalloc_obj(*queue_data); if (!queue_data) return -ENOMEM; INIT_LIST_HEAD(queue_data); @@ -702,7 +702,7 @@ usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags); - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/bcm63xx_udc.c b/drivers/usb/gadget/udc/bcm63xx_udc.c index 502612a5650e..c4f9ea45bdbb 100644 --- a/drivers/usb/gadget/udc/bcm63xx_udc.c +++ b/drivers/usb/gadget/udc/bcm63xx_udc.c @@ -1115,7 +1115,7 @@ static struct usb_request *bcm63xx_udc_alloc_request(struct usb_ep *ep, { struct bcm63xx_req *breq; - breq = kzalloc(sizeof(*breq), mem_flags); + breq = kzalloc_obj(*breq, mem_flags); if (!breq) return NULL; return &breq->req; diff --git a/drivers/usb/gadget/udc/bdc/bdc_core.c b/drivers/usb/gadget/udc/bdc/bdc_core.c index 5c3d8b64c0e7..438201dc96ca 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_core.c +++ b/drivers/usb/gadget/udc/bdc/bdc_core.c @@ -35,8 +35,8 @@ static int poll_oip(struct bdc *bdc, u32 usec) u32 status; int ret; - ret = readl_poll_timeout(bdc->regs + BDC_BDCSC, status, - (BDC_CSTS(status) != BDC_OIP), 10, usec); + ret = readl_poll_timeout_atomic(bdc->regs + BDC_BDCSC, status, + (BDC_CSTS(status) != BDC_OIP), 10, usec); if (ret) dev_err(bdc->dev, "operation timedout BDCSC: 0x%08x\n", status); else @@ -397,8 +397,7 @@ static int bdc_mem_alloc(struct bdc *bdc) "ieps:%d eops:%d num_eps:%d\n", num_ieps, num_oeps, bdc->num_eps); /* allocate array of ep pointers */ - bdc->bdc_ep_array = kcalloc(bdc->num_eps, sizeof(struct bdc_ep *), - GFP_KERNEL); + bdc->bdc_ep_array = kzalloc_objs(struct bdc_ep *, bdc->num_eps); if (!bdc->bdc_ep_array) goto fail; diff --git a/drivers/usb/gadget/udc/bdc/bdc_ep.c b/drivers/usb/gadget/udc/bdc/bdc_ep.c index f995cfa9b99e..c0ab3347059a 100644 --- a/drivers/usb/gadget/udc/bdc/bdc_ep.c +++ b/drivers/usb/gadget/udc/bdc/bdc_ep.c @@ -138,16 +138,15 @@ static int ep_bd_list_alloc(struct bdc_ep *ep) __func__, ep, num_tabs); /* Allocate memory for table array */ - ep->bd_list.bd_table_array = kcalloc(num_tabs, - sizeof(struct bd_table *), - GFP_ATOMIC); + ep->bd_list.bd_table_array = kzalloc_objs(struct bd_table *, num_tabs, + GFP_ATOMIC); if (!ep->bd_list.bd_table_array) return -ENOMEM; /* Allocate memory for each table */ for (index = 0; index < num_tabs; index++) { /* Allocate memory for bd_table structure */ - bd_table = kzalloc(sizeof(*bd_table), GFP_ATOMIC); + bd_table = kzalloc_obj(*bd_table, GFP_ATOMIC); if (!bd_table) goto fail; @@ -1829,7 +1828,7 @@ static struct usb_request *bdc_gadget_alloc_request(struct usb_ep *_ep, struct bdc_req *req; struct bdc_ep *ep; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -1946,7 +1945,7 @@ static int init_ep(struct bdc *bdc, u32 epnum, u32 dir) struct bdc_ep *ep; dev_dbg(bdc->dev, "%s epnum=%d dir=%d\n", __func__, epnum, dir); - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c index 9b53daf76583..308d3c468ab1 100644 --- a/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c +++ b/drivers/usb/gadget/udc/cdns2/cdns2-gadget.c @@ -1505,7 +1505,7 @@ struct usb_request *cdns2_gadget_ep_alloc_request(struct usb_ep *ep, struct cdns2_endpoint *pep = ep_to_cdns2_ep(ep); struct cdns2_request *preq; - preq = kzalloc(sizeof(*preq), gfp_flags); + preq = kzalloc_obj(*preq, gfp_flags); if (!preq) return NULL; diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 8dbe79bdc0f9..08d2a93b3bba 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -1393,7 +1393,7 @@ int usb_add_gadget(struct usb_gadget *gadget) struct usb_udc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); + udc = kzalloc_obj(*udc); if (!udc) goto error; diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index 1cefca660773..c9eca90376e2 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -666,7 +666,7 @@ static struct usb_request *dummy_alloc_request(struct usb_ep *_ep, if (!_ep) return NULL; - req = kzalloc(sizeof(*req), mem_flags); + req = kzalloc_obj(*req, mem_flags); if (!req) return NULL; INIT_LIST_HEAD(&req->queue); @@ -1270,7 +1270,7 @@ static int dummy_urb_enqueue( unsigned long flags; int rc; - urbp = kmalloc(sizeof *urbp, mem_flags); + urbp = kmalloc_obj(*urbp, mem_flags); if (!urbp) return -ENOMEM; urbp->urb = urb; @@ -2819,7 +2819,7 @@ static int __init dummy_hcd_init(void) } } for (i = 0; i < mod_data.num; i++) { - dum[i] = kzalloc(sizeof(struct dummy), GFP_KERNEL); + dum[i] = kzalloc_obj(struct dummy); if (!dum[i]) { retval = -ENOMEM; goto err_add_pdata; diff --git a/drivers/usb/gadget/udc/fsl_qe_udc.c b/drivers/usb/gadget/udc/fsl_qe_udc.c index aacfde06387c..bf87285ad13c 100644 --- a/drivers/usb/gadget/udc/fsl_qe_udc.c +++ b/drivers/usb/gadget/udc/fsl_qe_udc.c @@ -417,7 +417,7 @@ static int qe_ep_rxbd_update(struct qe_ep *ep) bd = ep->rxbase; - ep->rxframe = kmalloc(sizeof(*ep->rxframe), GFP_ATOMIC); + ep->rxframe = kmalloc_obj(*ep->rxframe, GFP_ATOMIC); if (!ep->rxframe) return -ENOMEM; @@ -666,7 +666,7 @@ static int qe_ep_init(struct qe_udc *udc, } if ((ep->tm == USBP_TM_CTL) || (ep->dir == USB_DIR_IN)) { - ep->txframe = kmalloc(sizeof(*ep->txframe), GFP_ATOMIC); + ep->txframe = kmalloc_obj(*ep->txframe, GFP_ATOMIC); if (!ep->txframe) goto en_done2; qe_frame_init(ep->txframe); @@ -1670,7 +1670,7 @@ static struct usb_request *qe_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct qe_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -2344,7 +2344,7 @@ static struct qe_udc *qe_udc_config(struct platform_device *ofdev) u64 size; u32 offset; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); + udc = kzalloc_obj(*udc); if (!udc) goto cleanup; diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 4dea8bc30cf6..600ce8cc0fef 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -678,7 +678,7 @@ fsl_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct fsl_req *req; - req = kzalloc(sizeof *req, gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -2250,7 +2250,7 @@ static int struct_udc_setup(struct fsl_udc *udc, pdata = dev_get_platdata(&pdev->dev); udc->phy_mode = pdata->phy_mode; - udc->eps = kcalloc(udc->max_ep, sizeof(struct fsl_ep), GFP_KERNEL); + udc->eps = kzalloc_objs(struct fsl_ep, udc->max_ep); if (!udc->eps) { dev_err(&udc->gadget.dev, "kmalloc udc endpoint status failed\n"); goto eps_alloc_failed; @@ -2369,7 +2369,7 @@ static int fsl_udc_probe(struct platform_device *pdev) unsigned int i; u32 dccparams; - udc_controller = kzalloc(sizeof(struct fsl_udc), GFP_KERNEL); + udc_controller = kzalloc_obj(struct fsl_udc); if (udc_controller == NULL) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/goku_udc.c b/drivers/usb/gadget/udc/goku_udc.c index b860c2e76449..db42a5e3e805 100644 --- a/drivers/usb/gadget/udc/goku_udc.c +++ b/drivers/usb/gadget/udc/goku_udc.c @@ -273,7 +273,7 @@ goku_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) if (!_ep) return NULL; - req = kzalloc(sizeof *req, gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -1755,7 +1755,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* alloc, and start init */ - dev = kzalloc (sizeof *dev, GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { retval = -ENOMEM; goto err; diff --git a/drivers/usb/gadget/udc/gr_udc.c b/drivers/usb/gadget/udc/gr_udc.c index bf5b3c964c18..cdcbfae140e9 100644 --- a/drivers/usb/gadget/udc/gr_udc.c +++ b/drivers/usb/gadget/udc/gr_udc.c @@ -347,7 +347,7 @@ static struct usb_request *gr_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct gr_request *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/lpc32xx_udc.c b/drivers/usb/gadget/udc/lpc32xx_udc.c index 83c7e243dcf9..044c31869cfb 100644 --- a/drivers/usb/gadget/udc/lpc32xx_udc.c +++ b/drivers/usb/gadget/udc/lpc32xx_udc.c @@ -1705,7 +1705,7 @@ static struct usb_request *lpc32xx_ep_alloc_request(struct usb_ep *_ep, { struct lpc32xx_request *req; - req = kzalloc(sizeof(struct lpc32xx_request), gfp_flags); + req = kzalloc_obj(struct lpc32xx_request, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/m66592-udc.c b/drivers/usb/gadget/udc/m66592-udc.c index 54885175b8a4..d77c11c4eb38 100644 --- a/drivers/usb/gadget/udc/m66592-udc.c +++ b/drivers/usb/gadget/udc/m66592-udc.c @@ -1330,7 +1330,7 @@ static struct usb_request *m66592_alloc_request(struct usb_ep *_ep, { struct m66592_request *req; - req = kzalloc(sizeof(struct m66592_request), gfp_flags); + req = kzalloc_obj(struct m66592_request, gfp_flags); if (!req) return NULL; @@ -1571,7 +1571,7 @@ static int m66592_probe(struct platform_device *pdev) } /* initialize ucd */ - m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); + m66592 = kzalloc_obj(struct m66592); if (m66592 == NULL) { ret = -ENOMEM; goto clean_up; diff --git a/drivers/usb/gadget/udc/max3420_udc.c b/drivers/usb/gadget/udc/max3420_udc.c index 7349ea774adf..11fd61cba5af 100644 --- a/drivers/usb/gadget/udc/max3420_udc.c +++ b/drivers/usb/gadget/udc/max3420_udc.c @@ -1007,7 +1007,7 @@ static struct usb_request *max3420_alloc_request(struct usb_ep *_ep, struct max3420_ep *ep = to_max3420_ep(_ep); struct max3420_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/net2280.c b/drivers/usb/gadget/udc/net2280.c index 8ea1adc7461d..d02765bd49ce 100644 --- a/drivers/usb/gadget/udc/net2280.c +++ b/drivers/usb/gadget/udc/net2280.c @@ -554,7 +554,7 @@ static struct usb_request } ep = container_of(_ep, struct net2280_ep, ep); - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -3625,7 +3625,7 @@ static int net2280_probe(struct pci_dev *pdev, const struct pci_device_id *id) int retval, i; /* alloc, and start init */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { retval = -ENOMEM; goto done; diff --git a/drivers/usb/gadget/udc/omap_udc.c b/drivers/usb/gadget/udc/omap_udc.c index 062bf2b57d2e..91139ae668f4 100644 --- a/drivers/usb/gadget/udc/omap_udc.c +++ b/drivers/usb/gadget/udc/omap_udc.c @@ -267,7 +267,7 @@ omap_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) { struct omap_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; @@ -2627,7 +2627,7 @@ omap_udc_setup(struct platform_device *odev, struct usb_phy *xceiv) /* UDC_PULLUP_EN gates the chip clock */ /* OTG_SYSCON_1 |= DEV_IDLE_EN; */ - udc = kzalloc(sizeof(*udc), GFP_KERNEL); + udc = kzalloc_obj(*udc); if (!udc) return -ENOMEM; diff --git a/drivers/usb/gadget/udc/pch_udc.c b/drivers/usb/gadget/udc/pch_udc.c index 0b20ecbe64f9..0a6886428739 100644 --- a/drivers/usb/gadget/udc/pch_udc.c +++ b/drivers/usb/gadget/udc/pch_udc.c @@ -1717,7 +1717,7 @@ static struct usb_request *pch_udc_alloc_request(struct usb_ep *usbep, if (!usbep) return NULL; ep = container_of(usbep, struct pch_udc_ep, ep); - req = kzalloc(sizeof *req, gfp); + req = kzalloc_obj(*req, gfp); if (!req) return NULL; req->req.dma = DMA_ADDR_INVALID; diff --git a/drivers/usb/gadget/udc/pxa25x_udc.c b/drivers/usb/gadget/udc/pxa25x_udc.c index b97fb7b0cb2c..b3d58d7c3a77 100644 --- a/drivers/usb/gadget/udc/pxa25x_udc.c +++ b/drivers/usb/gadget/udc/pxa25x_udc.c @@ -508,7 +508,7 @@ pxa25x_ep_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) { struct pxa25x_request *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c b/drivers/usb/gadget/udc/pxa27x_udc.c index 897f53601b5b..4fac477d24c0 100644 --- a/drivers/usb/gadget/udc/pxa27x_udc.c +++ b/drivers/usb/gadget/udc/pxa27x_udc.c @@ -573,7 +573,7 @@ pxa_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) { struct pxa27x_request *req; - req = kzalloc(sizeof *req, gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/r8a66597-udc.c b/drivers/usb/gadget/udc/r8a66597-udc.c index e5c2630e3711..e7a5d8553c0e 100644 --- a/drivers/usb/gadget/udc/r8a66597-udc.c +++ b/drivers/usb/gadget/udc/r8a66597-udc.c @@ -1580,7 +1580,7 @@ static struct usb_request *r8a66597_alloc_request(struct usb_ep *_ep, { struct r8a66597_request *req; - req = kzalloc(sizeof(struct r8a66597_request), gfp_flags); + req = kzalloc_obj(struct r8a66597_request, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index 7cdcc9d16b8b..b0b264d34919 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -2265,7 +2265,7 @@ static struct usb_request *__renesas_usb3_ep_alloc_request(gfp_t gfp_flags) { struct renesas_usb3_request *usb3_req; - usb3_req = kzalloc(sizeof(struct renesas_usb3_request), gfp_flags); + usb3_req = kzalloc_obj(struct renesas_usb3_request, gfp_flags); if (!usb3_req) return NULL; diff --git a/drivers/usb/gadget/udc/renesas_usbf.c b/drivers/usb/gadget/udc/renesas_usbf.c index 4c201574a0af..5d510665da1f 100644 --- a/drivers/usb/gadget/udc/renesas_usbf.c +++ b/drivers/usb/gadget/udc/renesas_usbf.c @@ -2081,7 +2081,7 @@ static struct usb_request *usbf_ep_alloc_request(struct usb_ep *_ep, if (!_ep) return NULL; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/snps_udc_core.c b/drivers/usb/gadget/udc/snps_udc_core.c index 373942ceb076..5f9514623956 100644 --- a/drivers/usb/gadget/udc/snps_udc_core.c +++ b/drivers/usb/gadget/udc/snps_udc_core.c @@ -523,7 +523,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) ep = container_of(usbep, struct udc_ep, ep); VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num); - req = kzalloc(sizeof(struct udc_request), gfp); + req = kzalloc_obj(struct udc_request, gfp); if (!req) return NULL; diff --git a/drivers/usb/gadget/udc/tegra-xudc.c b/drivers/usb/gadget/udc/tegra-xudc.c index 9d2007f448c0..e9d33be02866 100644 --- a/drivers/usb/gadget/udc/tegra-xudc.c +++ b/drivers/usb/gadget/udc/tegra-xudc.c @@ -1906,7 +1906,7 @@ tegra_xudc_ep_alloc_request(struct usb_ep *usb_ep, gfp_t gfp) { struct tegra_xudc_request *req; - req = kzalloc(sizeof(*req), gfp); + req = kzalloc_obj(*req, gfp); if (!req) return NULL; @@ -3392,17 +3392,18 @@ static void tegra_xudc_device_params_init(struct tegra_xudc *xudc) { u32 val, imod; + val = xudc_readl(xudc, BLCG); if (xudc->soc->has_ipfs) { - val = xudc_readl(xudc, BLCG); val |= BLCG_ALL; val &= ~(BLCG_DFPCI | BLCG_UFPCI | BLCG_FE | BLCG_COREPLL_PWRDN); val |= BLCG_IOPLL_0_PWRDN; val |= BLCG_IOPLL_1_PWRDN; val |= BLCG_IOPLL_2_PWRDN; - - xudc_writel(xudc, val, BLCG); + } else { + val &= ~BLCG_COREPLL_PWRDN; } + xudc_writel(xudc, val, BLCG); if (xudc->soc->port_speed_quirk) tegra_xudc_limit_port_speed(xudc); @@ -3953,6 +3954,7 @@ static void tegra_xudc_remove(struct platform_device *pdev) static int __maybe_unused tegra_xudc_powergate(struct tegra_xudc *xudc) { unsigned long flags; + u32 val; dev_dbg(xudc->dev, "entering ELPG\n"); @@ -3965,6 +3967,10 @@ static int __maybe_unused tegra_xudc_powergate(struct tegra_xudc *xudc) spin_unlock_irqrestore(&xudc->lock, flags); + val = xudc_readl(xudc, BLCG); + val |= BLCG_COREPLL_PWRDN; + xudc_writel(xudc, val, BLCG); + clk_bulk_disable_unprepare(xudc->soc->num_clks, xudc->clks); regulator_bulk_disable(xudc->soc->num_supplies, xudc->supplies); diff --git a/drivers/usb/gadget/udc/udc-xilinx.c b/drivers/usb/gadget/udc/udc-xilinx.c index 8d803a612bb1..bef06fe7543b 100644 --- a/drivers/usb/gadget/udc/udc-xilinx.c +++ b/drivers/usb/gadget/udc/udc-xilinx.c @@ -970,7 +970,7 @@ static struct usb_request *xudc_ep_alloc_request(struct usb_ep *_ep, struct xusb_ep *ep = to_xusb_ep(_ep); struct xusb_req *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index c4f17ce5c77b..0a277a07cf70 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -383,18 +383,6 @@ config USB_ISP116X_HCD To compile this driver as a module, choose M here: the module will be called isp116x-hcd. -config USB_ISP1362_HCD - tristate "ISP1362 HCD support" - depends on HAS_IOPORT - depends on COMPILE_TEST # nothing uses this - help - Supports the Philips ISP1362 chip as a host controller - - This driver does not support isochronous transfers. - - To compile this driver as a module, choose M here: the - module will be called isp1362-hcd. - config USB_MAX3421_HCD tristate "MAX3421 HCD (USB-over-SPI) support" depends on USB && SPI @@ -616,7 +604,7 @@ config USB_UHCI_ASPEED config USB_FHCI_HCD tristate "Freescale QE USB Host Controller support" - depends on OF_GPIO && QE_GPIO && QUICC_ENGINE + depends on QE_GPIO && QUICC_ENGINE select FSL_GTM select QE_USB help diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 4df946c05ba0..a07e7ba9cd53 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_USB_EHCI_BRCMSTB) += ehci-brcm.o obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o -obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_OHCI_HCD_PCI) += ohci-pci.o diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 435001128221..3cf743c81eb4 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -629,7 +629,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) unsigned i; __hc32 tag; - seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC); + seen = kmalloc_objs(*seen, DBG_SCHED_LIMIT, GFP_ATOMIC); if (!seen) return 0; seen_count = 0; @@ -917,7 +917,7 @@ static struct debug_buffer *alloc_buffer(struct usb_bus *bus, { struct debug_buffer *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (buf) { buf->bus = bus; diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 6d1d190c914d..3c46bb18c7f3 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1354,12 +1354,6 @@ static int __init ehci_hcd_init(void) if (usb_disabled()) return -ENODEV; - set_bit(USB_EHCI_LOADED, &usb_hcds_loaded); - if (test_bit(USB_UHCI_LOADED, &usb_hcds_loaded) || - test_bit(USB_OHCI_LOADED, &usb_hcds_loaded)) - printk(KERN_WARNING "Warning! ehci_hcd should always be loaded" - " before uhci_hcd and ohci_hcd, not after\n"); - pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd sitd %zd\n", hcd_name, sizeof(struct ehci_qh), sizeof(struct ehci_qtd), @@ -1390,7 +1384,6 @@ static int __init ehci_hcd_init(void) debugfs_remove(ehci_debug_root); ehci_debug_root = NULL; #endif - clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); return retval; } module_init(ehci_hcd_init); @@ -1404,6 +1397,5 @@ static void __exit ehci_hcd_cleanup(void) #ifdef CONFIG_DYNAMIC_DEBUG debugfs_remove(ehci_debug_root); #endif - clear_bit(USB_EHCI_LOADED, &usb_hcds_loaded); } module_exit(ehci_hcd_cleanup); diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 4c6c08b675b5..a2d4499e67e0 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -69,7 +69,7 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) struct ehci_qh *qh; dma_addr_t dma; - qh = kzalloc(sizeof *qh, GFP_ATOMIC); + qh = kzalloc_obj(*qh, GFP_ATOMIC); if (!qh) goto done; qh->hw = (struct ehci_qh_hw *) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 7e834587e7de..a241337c9af8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -117,9 +117,8 @@ static struct ehci_tt *find_tt(struct usb_device *udev) if (utt->multi) { tt_index = utt->hcpriv; if (!tt_index) { /* Create the index array */ - tt_index = kcalloc(utt->hub->maxchild, - sizeof(*tt_index), - GFP_ATOMIC); + tt_index = kzalloc_objs(*tt_index, utt->hub->maxchild, + GFP_ATOMIC); if (!tt_index) return ERR_PTR(-ENOMEM); utt->hcpriv = tt_index; @@ -137,7 +136,7 @@ static struct ehci_tt *find_tt(struct usb_device *udev) struct ehci_hcd *ehci = hcd_to_ehci(bus_to_hcd(udev->bus)); - tt = kzalloc(sizeof(*tt), GFP_ATOMIC); + tt = kzalloc_obj(*tt, GFP_ATOMIC); if (!tt) { if (allocated_index) { utt->hcpriv = NULL; @@ -1003,7 +1002,7 @@ iso_stream_alloc(gfp_t mem_flags) { struct ehci_iso_stream *stream; - stream = kzalloc(sizeof(*stream), mem_flags); + stream = kzalloc_obj(*stream, mem_flags); if (likely(stream != NULL)) { INIT_LIST_HEAD(&stream->td_list); INIT_LIST_HEAD(&stream->free_list); @@ -1167,7 +1166,7 @@ iso_sched_alloc(unsigned packets, gfp_t mem_flags) { struct ehci_iso_sched *iso_sched; - iso_sched = kzalloc(struct_size(iso_sched, packet, packets), mem_flags); + iso_sched = kzalloc_flex(*iso_sched, packet, packets, mem_flags); if (likely(iso_sched != NULL)) INIT_LIST_HEAD(&iso_sched->td_list); diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 22a0942f0bce..271bcbe9b326 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c @@ -193,7 +193,7 @@ static int fhci_mem_init(struct fhci_hcd *fhci) { int i; - fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL); + fhci->hc_list = kzalloc_obj(*fhci->hc_list); if (!fhci->hc_list) goto err; @@ -203,7 +203,7 @@ static int fhci_mem_init(struct fhci_hcd *fhci) INIT_LIST_HEAD(&fhci->hc_list->intr_list); INIT_LIST_HEAD(&fhci->hc_list->done_list); - fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL); + fhci->vroot_hub = kzalloc_obj(*fhci->vroot_hub); if (!fhci->vroot_hub) goto err; @@ -217,7 +217,7 @@ static int fhci_mem_init(struct fhci_hcd *fhci) for (i = 0; i < MAX_TDS; i++) { struct td *td; - td = kmalloc(sizeof(*td), GFP_KERNEL); + td = kmalloc_obj(*td); if (!td) goto err; fhci_recycle_empty_td(fhci, td); @@ -225,7 +225,7 @@ static int fhci_mem_init(struct fhci_hcd *fhci) for (i = 0; i < MAX_EDS; i++) { struct ed *ed; - ed = kmalloc(sizeof(*ed), GFP_KERNEL); + ed = kmalloc_obj(*ed); if (!ed) goto err; fhci_recycle_empty_ed(fhci, ed); @@ -264,7 +264,7 @@ static int fhci_usb_init(struct fhci_hcd *fhci) usb->max_frame_usage = FRAME_TIME_USAGE; usb->sw_transaction_time = SW_FIX_TIME_BETWEEN_TRANSACTION; - usb->actual_frame = kzalloc(sizeof(*usb->actual_frame), GFP_KERNEL); + usb->actual_frame = kzalloc_obj(*usb->actual_frame); if (!usb->actual_frame) { fhci_usb_free(usb); return -ENOMEM; @@ -306,7 +306,7 @@ static struct fhci_usb *fhci_create_lld(struct fhci_hcd *fhci) struct fhci_usb *usb; /* allocate memory for SCC data structure */ - usb = kzalloc(sizeof(*usb), GFP_KERNEL); + usb = kzalloc_obj(*usb); if (!usb) return NULL; @@ -426,12 +426,12 @@ static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, } /* allocate the private part of the URB */ - urb_priv = kzalloc(sizeof(*urb_priv), mem_flags); + urb_priv = kzalloc_obj(*urb_priv, mem_flags); if (!urb_priv) return -ENOMEM; /* allocate the private part of the URB */ - urb_priv->tds = kcalloc(size, sizeof(*urb_priv->tds), mem_flags); + urb_priv->tds = kzalloc_objs(*urb_priv->tds, size, mem_flags); if (!urb_priv->tds) { kfree(urb_priv); return -ENOMEM; diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c index 658aedc6adc1..d5951fc1964a 100644 --- a/drivers/usb/host/fhci-mem.c +++ b/drivers/usb/host/fhci-mem.c @@ -42,7 +42,7 @@ static struct td *get_empty_td(struct fhci_hcd *fhci) td = list_entry(fhci->empty_tds.next, struct td, node); list_del(fhci->empty_tds.next); } else { - td = kmalloc(sizeof(*td), GFP_ATOMIC); + td = kmalloc_obj(*td, GFP_ATOMIC); if (!td) fhci_err(fhci, "No memory to allocate to TD\n"); else @@ -66,7 +66,7 @@ struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci) ed = list_entry(fhci->empty_eds.next, struct ed, node); list_del(fhci->empty_eds.next); } else { - ed = kmalloc(sizeof(*ed), GFP_ATOMIC); + ed = kmalloc_obj(*ed, GFP_ATOMIC); if (!ed) fhci_err(fhci, "No memory to allocate to ED\n"); else diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c index d98fd9e1af0b..d7482dc0604e 100644 --- a/drivers/usb/host/fhci-tds.c +++ b/drivers/usb/host/fhci-tds.c @@ -161,7 +161,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, return -EINVAL; } - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -183,7 +183,7 @@ u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, struct packet *pkt; u8 *buff; - pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + pkt = kmalloc_obj(*pkt); if (!pkt) { err_for = "frame"; goto err; diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 71c22c4bd163..b5e9056895e4 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -703,7 +703,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, } /* avoid all allocations within spinlocks: request or endpoint */ if (!hep->hcpriv) { - ep = kzalloc(sizeof *ep, mem_flags); + ep = kzalloc_obj(*ep, mem_flags); if (!ep) return -ENOMEM; } diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c deleted file mode 100644 index 954fc5ad565b..000000000000 --- a/drivers/usb/host/isp1362-hcd.c +++ /dev/null @@ -1,2769 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * ISP1362 HCD (Host Controller Driver) for USB. - * - * Copyright (C) 2005 Lothar Wassmann - * - * Derived from the SL811 HCD, rewritten for ISP116x. - * Copyright (C) 2005 Olav Kongas - * - * Portions: - * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) - * Copyright (C) 2004 David Brownell - */ - -/* - * The ISP1362 chip requires a large delay (300ns and 462ns) between - * accesses to the address and data register. - * The following timing options exist: - * - * 1. Configure your memory controller to add such delays if it can (the best) - * 2. Implement platform-specific delay function possibly - * combined with configuring the memory controller; see - * include/linux/usb_isp1362.h for more info. - * 3. Use ndelay (easiest, poorest). - * - * Use the corresponding macros USE_PLATFORM_DELAY and USE_NDELAY in the - * platform specific section of isp1362.h to select the appropriate variant. - * - * Also note that according to the Philips "ISP1362 Errata" document - * Rev 1.00 from 27 May data corruption may occur when the #WR signal - * is reasserted (even with #CS deasserted) within 132ns after a - * write cycle to any controller register. If the hardware doesn't - * implement the recommended fix (gating the #WR with #CS) software - * must ensure that no further write cycle (not necessarily to the chip!) - * is issued by the CPU within this interval. - - * For PXA25x this can be ensured by using VLIO with the maximum - * recovery time (MSCx = 0x7f8c) with a memory clock of 99.53 MHz. - */ - -#undef ISP1362_DEBUG - -/* - * The PXA255 UDC apparently doesn't handle GET_STATUS, GET_CONFIG and - * GET_INTERFACE requests correctly when the SETUP and DATA stages of the - * requests are carried out in separate frames. This will delay any SETUP - * packets until the start of the next frame so that this situation is - * unlikely to occur (and makes usbtest happy running with a PXA255 target - * device). - */ -#undef BUGGY_PXA2XX_UDC_USBTEST - -#undef PTD_TRACE -#undef URB_TRACE -#undef VERBOSE -#undef REGISTERS - -/* This enables a memory test on the ISP1362 chip memory to make sure the - * chip access timing is correct. - */ -#undef CHIP_BUFFER_TEST - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -static int dbg_level; -#ifdef ISP1362_DEBUG -module_param(dbg_level, int, 0644); -#else -module_param(dbg_level, int, 0); -#endif - -#include "../core/usb.h" -#include "isp1362.h" - - -#define DRIVER_VERSION "2005-04-04" -#define DRIVER_DESC "ISP1362 USB Host Controller Driver" - -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); - -static const char hcd_name[] = "isp1362-hcd"; - -static void isp1362_hc_stop(struct usb_hcd *hcd); -static int isp1362_hc_start(struct usb_hcd *hcd); - -/*-------------------------------------------------------------------------*/ - -/* - * When called from the interrupthandler only isp1362_hcd->irqenb is modified, - * since the interrupt handler will write isp1362_hcd->irqenb to HCuPINT upon - * completion. - * We don't need a 'disable' counterpart, since interrupts will be disabled - * only by the interrupt handler. - */ -static inline void isp1362_enable_int(struct isp1362_hcd *isp1362_hcd, u16 mask) -{ - if ((isp1362_hcd->irqenb | mask) == isp1362_hcd->irqenb) - return; - if (mask & ~isp1362_hcd->irqenb) - isp1362_write_reg16(isp1362_hcd, HCuPINT, mask & ~isp1362_hcd->irqenb); - isp1362_hcd->irqenb |= mask; - if (isp1362_hcd->irq_active) - return; - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb); -} - -/*-------------------------------------------------------------------------*/ - -static inline struct isp1362_ep_queue *get_ptd_queue(struct isp1362_hcd *isp1362_hcd, - u16 offset) -{ - struct isp1362_ep_queue *epq = NULL; - - if (offset < isp1362_hcd->istl_queue[1].buf_start) - epq = &isp1362_hcd->istl_queue[0]; - else if (offset < isp1362_hcd->intl_queue.buf_start) - epq = &isp1362_hcd->istl_queue[1]; - else if (offset < isp1362_hcd->atl_queue.buf_start) - epq = &isp1362_hcd->intl_queue; - else if (offset < isp1362_hcd->atl_queue.buf_start + - isp1362_hcd->atl_queue.buf_size) - epq = &isp1362_hcd->atl_queue; - - if (epq) - DBG(1, "%s: PTD $%04x is on %s queue\n", __func__, offset, epq->name); - else - pr_warn("%s: invalid PTD $%04x\n", __func__, offset); - - return epq; -} - -static inline int get_ptd_offset(struct isp1362_ep_queue *epq, u8 index) -{ - int offset; - - if (index * epq->blk_size > epq->buf_size) { - pr_warn("%s: Bad %s index %d(%d)\n", - __func__, epq->name, index, - epq->buf_size / epq->blk_size); - return -EINVAL; - } - offset = epq->buf_start + index * epq->blk_size; - DBG(3, "%s: %s PTD[%02x] # %04x\n", __func__, epq->name, index, offset); - - return offset; -} - -/*-------------------------------------------------------------------------*/ - -static inline u16 max_transfer_size(struct isp1362_ep_queue *epq, size_t size, - int mps) -{ - u16 xfer_size = min_t(size_t, MAX_XFER_SIZE, size); - - xfer_size = min_t(size_t, xfer_size, epq->buf_avail * epq->blk_size - PTD_HEADER_SIZE); - if (xfer_size < size && xfer_size % mps) - xfer_size -= xfer_size % mps; - - return xfer_size; -} - -static int claim_ptd_buffers(struct isp1362_ep_queue *epq, - struct isp1362_ep *ep, u16 len) -{ - int ptd_offset = -EINVAL; - int num_ptds = ((len + PTD_HEADER_SIZE - 1) / epq->blk_size) + 1; - int found; - - BUG_ON(len > epq->buf_size); - - if (!epq->buf_avail) - return -ENOMEM; - - if (ep->num_ptds) - pr_err("%s: %s len %d/%d num_ptds %d buf_map %08lx skip_map %08lx\n", __func__, - epq->name, len, epq->blk_size, num_ptds, epq->buf_map, epq->skip_map); - BUG_ON(ep->num_ptds != 0); - - found = bitmap_find_next_zero_area(&epq->buf_map, epq->buf_count, 0, - num_ptds, 0); - if (found >= epq->buf_count) - return -EOVERFLOW; - - DBG(1, "%s: Found %d PTDs[%d] for %d/%d byte\n", __func__, - num_ptds, found, len, (int)(epq->blk_size - PTD_HEADER_SIZE)); - ptd_offset = get_ptd_offset(epq, found); - WARN_ON(ptd_offset < 0); - ep->ptd_offset = ptd_offset; - ep->num_ptds += num_ptds; - epq->buf_avail -= num_ptds; - BUG_ON(epq->buf_avail > epq->buf_count); - ep->ptd_index = found; - bitmap_set(&epq->buf_map, found, num_ptds); - DBG(1, "%s: Done %s PTD[%d] $%04x, avail %d count %d claimed %d %08lx:%08lx\n", - __func__, epq->name, ep->ptd_index, ep->ptd_offset, - epq->buf_avail, epq->buf_count, num_ptds, epq->buf_map, epq->skip_map); - - return found; -} - -static inline void release_ptd_buffers(struct isp1362_ep_queue *epq, struct isp1362_ep *ep) -{ - int last = ep->ptd_index + ep->num_ptds; - - if (last > epq->buf_count) - pr_err("%s: ep %p req %d len %d %s PTD[%d] $%04x num_ptds %d buf_count %d buf_avail %d buf_map %08lx skip_map %08lx\n", - __func__, ep, ep->num_req, ep->length, epq->name, ep->ptd_index, - ep->ptd_offset, ep->num_ptds, epq->buf_count, epq->buf_avail, - epq->buf_map, epq->skip_map); - BUG_ON(last > epq->buf_count); - - bitmap_clear(&epq->buf_map, ep->ptd_index, ep->num_ptds); - bitmap_set(&epq->skip_map, ep->ptd_index, ep->num_ptds); - epq->buf_avail += ep->num_ptds; - epq->ptd_count--; - - BUG_ON(epq->buf_avail > epq->buf_count); - BUG_ON(epq->ptd_count > epq->buf_count); - - DBG(1, "%s: Done %s PTDs $%04x released %d avail %d count %d\n", - __func__, epq->name, - ep->ptd_offset, ep->num_ptds, epq->buf_avail, epq->buf_count); - DBG(1, "%s: buf_map %08lx skip_map %08lx\n", __func__, - epq->buf_map, epq->skip_map); - - ep->num_ptds = 0; - ep->ptd_offset = -EINVAL; - ep->ptd_index = -EINVAL; -} - -/*-------------------------------------------------------------------------*/ - -/* - Set up PTD's. -*/ -static void prepare_ptd(struct isp1362_hcd *isp1362_hcd, struct urb *urb, - struct isp1362_ep *ep, struct isp1362_ep_queue *epq, - u16 fno) -{ - struct ptd *ptd; - int toggle; - int dir; - u16 len; - size_t buf_len = urb->transfer_buffer_length - urb->actual_length; - - DBG(3, "%s: %s ep %p\n", __func__, epq->name, ep); - - ptd = &ep->ptd; - - ep->data = (unsigned char *)urb->transfer_buffer + urb->actual_length; - - switch (ep->nextpid) { - case USB_PID_IN: - toggle = usb_gettoggle(urb->dev, ep->epnum, 0); - dir = PTD_DIR_IN; - if (usb_pipecontrol(urb->pipe)) { - len = min_t(size_t, ep->maxpacket, buf_len); - } else if (usb_pipeisoc(urb->pipe)) { - len = min_t(size_t, urb->iso_frame_desc[fno].length, MAX_XFER_SIZE); - ep->data = urb->transfer_buffer + urb->iso_frame_desc[fno].offset; - } else - len = max_transfer_size(epq, buf_len, ep->maxpacket); - DBG(1, "%s: IN len %d/%d/%d from URB\n", __func__, len, ep->maxpacket, - (int)buf_len); - break; - case USB_PID_OUT: - toggle = usb_gettoggle(urb->dev, ep->epnum, 1); - dir = PTD_DIR_OUT; - if (usb_pipecontrol(urb->pipe)) - len = min_t(size_t, ep->maxpacket, buf_len); - else if (usb_pipeisoc(urb->pipe)) - len = min_t(size_t, urb->iso_frame_desc[0].length, MAX_XFER_SIZE); - else - len = max_transfer_size(epq, buf_len, ep->maxpacket); - if (len == 0) - pr_info("%s: Sending ZERO packet: %d\n", __func__, - urb->transfer_flags & URB_ZERO_PACKET); - DBG(1, "%s: OUT len %d/%d/%d from URB\n", __func__, len, ep->maxpacket, - (int)buf_len); - break; - case USB_PID_SETUP: - toggle = 0; - dir = PTD_DIR_SETUP; - len = sizeof(struct usb_ctrlrequest); - DBG(1, "%s: SETUP len %d\n", __func__, len); - ep->data = urb->setup_packet; - break; - case USB_PID_ACK: - toggle = 1; - len = 0; - dir = (urb->transfer_buffer_length && usb_pipein(urb->pipe)) ? - PTD_DIR_OUT : PTD_DIR_IN; - DBG(1, "%s: ACK len %d\n", __func__, len); - break; - default: - toggle = dir = len = 0; - pr_err("%s@%d: ep->nextpid %02x\n", __func__, __LINE__, ep->nextpid); - BUG_ON(1); - } - - ep->length = len; - if (!len) - ep->data = NULL; - - ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle); - ptd->mps = PTD_MPS(ep->maxpacket) | PTD_SPD(urb->dev->speed == USB_SPEED_LOW) | - PTD_EP(ep->epnum); - ptd->len = PTD_LEN(len) | PTD_DIR(dir); - ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); - - if (usb_pipeint(urb->pipe)) { - ptd->faddr |= PTD_SF_INT(ep->branch); - ptd->faddr |= PTD_PR(ep->interval ? __ffs(ep->interval) : 0); - } - if (usb_pipeisoc(urb->pipe)) - ptd->faddr |= PTD_SF_ISO(fno); - - DBG(1, "%s: Finished\n", __func__); -} - -static void isp1362_write_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep, - struct isp1362_ep_queue *epq) -{ - struct ptd *ptd = &ep->ptd; - int len = PTD_GET_DIR(ptd) == PTD_DIR_IN ? 0 : ep->length; - - prefetch(ptd); - isp1362_write_buffer(isp1362_hcd, ptd, ep->ptd_offset, PTD_HEADER_SIZE); - if (len) - isp1362_write_buffer(isp1362_hcd, ep->data, - ep->ptd_offset + PTD_HEADER_SIZE, len); - - dump_ptd(ptd); - dump_ptd_out_data(ptd, ep->data); -} - -static void isp1362_read_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep, - struct isp1362_ep_queue *epq) -{ - struct ptd *ptd = &ep->ptd; - int act_len; - - WARN_ON(list_empty(&ep->active)); - BUG_ON(ep->ptd_offset < 0); - - list_del_init(&ep->active); - DBG(1, "%s: ep %p removed from active list %p\n", __func__, ep, &epq->active); - - prefetchw(ptd); - isp1362_read_buffer(isp1362_hcd, ptd, ep->ptd_offset, PTD_HEADER_SIZE); - dump_ptd(ptd); - act_len = PTD_GET_COUNT(ptd); - if (PTD_GET_DIR(ptd) != PTD_DIR_IN || act_len == 0) - return; - if (act_len > ep->length) - pr_err("%s: ep %p PTD $%04x act_len %d ep->length %d\n", __func__, ep, - ep->ptd_offset, act_len, ep->length); - BUG_ON(act_len > ep->length); - /* Only transfer the amount of data that has actually been overwritten - * in the chip buffer. We don't want any data that doesn't belong to the - * transfer to leak out of the chip to the callers transfer buffer! - */ - prefetchw(ep->data); - isp1362_read_buffer(isp1362_hcd, ep->data, - ep->ptd_offset + PTD_HEADER_SIZE, act_len); - dump_ptd_in_data(ptd, ep->data); -} - -/* - * INT PTDs will stay in the chip until data is available. - * This function will remove a PTD from the chip when the URB is dequeued. - * Must be called with the spinlock held and IRQs disabled - */ -static void remove_ptd(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) - -{ - int index; - struct isp1362_ep_queue *epq; - - DBG(1, "%s: ep %p PTD[%d] $%04x\n", __func__, ep, ep->ptd_index, ep->ptd_offset); - BUG_ON(ep->ptd_offset < 0); - - epq = get_ptd_queue(isp1362_hcd, ep->ptd_offset); - BUG_ON(!epq); - - /* put ep in remove_list for cleanup */ - WARN_ON(!list_empty(&ep->remove_list)); - list_add_tail(&ep->remove_list, &isp1362_hcd->remove_list); - /* let SOF interrupt handle the cleanup */ - isp1362_enable_int(isp1362_hcd, HCuPINT_SOF); - - index = ep->ptd_index; - if (index < 0) - /* ISO queues don't have SKIP registers */ - return; - - DBG(1, "%s: Disabling PTD[%02x] $%04x %08lx|%08x\n", __func__, - index, ep->ptd_offset, epq->skip_map, 1 << index); - - /* prevent further processing of PTD (will be effective after next SOF) */ - epq->skip_map |= 1 << index; - if (epq == &isp1362_hcd->atl_queue) { - DBG(2, "%s: ATLSKIP = %08x -> %08lx\n", __func__, - isp1362_read_reg32(isp1362_hcd, HCATLSKIP), epq->skip_map); - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, epq->skip_map); - if (~epq->skip_map == 0) - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE); - } else if (epq == &isp1362_hcd->intl_queue) { - DBG(2, "%s: INTLSKIP = %08x -> %08lx\n", __func__, - isp1362_read_reg32(isp1362_hcd, HCINTLSKIP), epq->skip_map); - isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, epq->skip_map); - if (~epq->skip_map == 0) - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE); - } -} - -/* - Take done or failed requests out of schedule. Give back - processed urbs. -*/ -static void finish_request(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep, - struct urb *urb, int status) - __releases(isp1362_hcd->lock) - __acquires(isp1362_hcd->lock) -{ - urb->hcpriv = NULL; - ep->error_count = 0; - - if (usb_pipecontrol(urb->pipe)) - ep->nextpid = USB_PID_SETUP; - - URB_DBG("%s: req %d FA %d ep%d%s %s: len %d/%d %s stat %d\n", __func__, - ep->num_req, usb_pipedevice(urb->pipe), - usb_pipeendpoint(urb->pipe), - !usb_pipein(urb->pipe) ? "out" : "in", - usb_pipecontrol(urb->pipe) ? "ctrl" : - usb_pipeint(urb->pipe) ? "int" : - usb_pipebulk(urb->pipe) ? "bulk" : - "iso", - urb->actual_length, urb->transfer_buffer_length, - !(urb->transfer_flags & URB_SHORT_NOT_OK) ? - "short_ok" : "", urb->status); - - - usb_hcd_unlink_urb_from_ep(isp1362_hcd_to_hcd(isp1362_hcd), urb); - spin_unlock(&isp1362_hcd->lock); - usb_hcd_giveback_urb(isp1362_hcd_to_hcd(isp1362_hcd), urb, status); - spin_lock(&isp1362_hcd->lock); - - /* take idle endpoints out of the schedule right away */ - if (!list_empty(&ep->hep->urb_list)) - return; - - /* async deschedule */ - if (!list_empty(&ep->schedule)) { - list_del_init(&ep->schedule); - return; - } - - - if (ep->interval) { - /* periodic deschedule */ - DBG(1, "deschedule qh%d/%p branch %d load %d bandwidth %d -> %d\n", ep->interval, - ep, ep->branch, ep->load, - isp1362_hcd->load[ep->branch], - isp1362_hcd->load[ep->branch] - ep->load); - isp1362_hcd->load[ep->branch] -= ep->load; - ep->branch = PERIODIC_SIZE; - } -} - -/* - * Analyze transfer results, handle partial transfers and errors -*/ -static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) -{ - struct urb *urb = get_urb(ep); - struct usb_device *udev; - struct ptd *ptd; - int short_ok; - u16 len; - int urbstat = -EINPROGRESS; - u8 cc; - - DBG(2, "%s: ep %p req %d\n", __func__, ep, ep->num_req); - - udev = urb->dev; - ptd = &ep->ptd; - cc = PTD_GET_CC(ptd); - if (cc == PTD_NOTACCESSED) { - pr_err("%s: req %d PTD %p Untouched by ISP1362\n", __func__, - ep->num_req, ptd); - cc = PTD_DEVNOTRESP; - } - - short_ok = !(urb->transfer_flags & URB_SHORT_NOT_OK); - len = urb->transfer_buffer_length - urb->actual_length; - - /* Data underrun is special. For allowed underrun - we clear the error and continue as normal. For - forbidden underrun we finish the DATA stage - immediately while for control transfer, - we do a STATUS stage. - */ - if (cc == PTD_DATAUNDERRUN) { - if (short_ok) { - DBG(1, "%s: req %d Allowed data underrun short_%sok %d/%d/%d byte\n", - __func__, ep->num_req, short_ok ? "" : "not_", - PTD_GET_COUNT(ptd), ep->maxpacket, len); - cc = PTD_CC_NOERROR; - urbstat = 0; - } else { - DBG(1, "%s: req %d Data Underrun %s nextpid %02x short_%sok %d/%d/%d byte\n", - __func__, ep->num_req, - usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, - short_ok ? "" : "not_", - PTD_GET_COUNT(ptd), ep->maxpacket, len); - /* save the data underrun error code for later and - * proceed with the status stage - */ - urb->actual_length += PTD_GET_COUNT(ptd); - if (usb_pipecontrol(urb->pipe)) { - ep->nextpid = USB_PID_ACK; - BUG_ON(urb->actual_length > urb->transfer_buffer_length); - - if (urb->status == -EINPROGRESS) - urb->status = cc_to_error[PTD_DATAUNDERRUN]; - } else { - usb_settoggle(udev, ep->epnum, ep->nextpid == USB_PID_OUT, - PTD_GET_TOGGLE(ptd)); - urbstat = cc_to_error[PTD_DATAUNDERRUN]; - } - goto out; - } - } - - if (cc != PTD_CC_NOERROR) { - if (++ep->error_count >= 3 || cc == PTD_CC_STALL || cc == PTD_DATAOVERRUN) { - urbstat = cc_to_error[cc]; - DBG(1, "%s: req %d nextpid %02x, status %d, error %d, error_count %d\n", - __func__, ep->num_req, ep->nextpid, urbstat, cc, - ep->error_count); - } - goto out; - } - - switch (ep->nextpid) { - case USB_PID_OUT: - if (PTD_GET_COUNT(ptd) != ep->length) - pr_err("%s: count=%d len=%d\n", __func__, - PTD_GET_COUNT(ptd), ep->length); - BUG_ON(PTD_GET_COUNT(ptd) != ep->length); - urb->actual_length += ep->length; - BUG_ON(urb->actual_length > urb->transfer_buffer_length); - usb_settoggle(udev, ep->epnum, 1, PTD_GET_TOGGLE(ptd)); - if (urb->actual_length == urb->transfer_buffer_length) { - DBG(3, "%s: req %d xfer complete %d/%d status %d -> 0\n", __func__, - ep->num_req, len, ep->maxpacket, urbstat); - if (usb_pipecontrol(urb->pipe)) { - DBG(3, "%s: req %d %s Wait for ACK\n", __func__, - ep->num_req, - usb_pipein(urb->pipe) ? "IN" : "OUT"); - ep->nextpid = USB_PID_ACK; - } else { - if (len % ep->maxpacket || - !(urb->transfer_flags & URB_ZERO_PACKET)) { - urbstat = 0; - DBG(3, "%s: req %d URB %s status %d count %d/%d/%d\n", - __func__, ep->num_req, usb_pipein(urb->pipe) ? "IN" : "OUT", - urbstat, len, ep->maxpacket, urb->actual_length); - } - } - } - break; - case USB_PID_IN: - len = PTD_GET_COUNT(ptd); - BUG_ON(len > ep->length); - urb->actual_length += len; - BUG_ON(urb->actual_length > urb->transfer_buffer_length); - usb_settoggle(udev, ep->epnum, 0, PTD_GET_TOGGLE(ptd)); - /* if transfer completed or (allowed) data underrun */ - if ((urb->transfer_buffer_length == urb->actual_length) || - len % ep->maxpacket) { - DBG(3, "%s: req %d xfer complete %d/%d status %d -> 0\n", __func__, - ep->num_req, len, ep->maxpacket, urbstat); - if (usb_pipecontrol(urb->pipe)) { - DBG(3, "%s: req %d %s Wait for ACK\n", __func__, - ep->num_req, - usb_pipein(urb->pipe) ? "IN" : "OUT"); - ep->nextpid = USB_PID_ACK; - } else { - urbstat = 0; - DBG(3, "%s: req %d URB %s status %d count %d/%d/%d\n", - __func__, ep->num_req, usb_pipein(urb->pipe) ? "IN" : "OUT", - urbstat, len, ep->maxpacket, urb->actual_length); - } - } - break; - case USB_PID_SETUP: - if (urb->transfer_buffer_length == urb->actual_length) { - ep->nextpid = USB_PID_ACK; - } else if (usb_pipeout(urb->pipe)) { - usb_settoggle(udev, 0, 1, 1); - ep->nextpid = USB_PID_OUT; - } else { - usb_settoggle(udev, 0, 0, 1); - ep->nextpid = USB_PID_IN; - } - break; - case USB_PID_ACK: - DBG(3, "%s: req %d got ACK %d -> 0\n", __func__, ep->num_req, - urbstat); - WARN_ON(urbstat != -EINPROGRESS); - urbstat = 0; - ep->nextpid = 0; - break; - default: - BUG_ON(1); - } - - out: - if (urbstat != -EINPROGRESS) { - DBG(2, "%s: Finishing ep %p req %d urb %p status %d\n", __func__, - ep, ep->num_req, urb, urbstat); - finish_request(isp1362_hcd, ep, urb, urbstat); - } -} - -static void finish_unlinks(struct isp1362_hcd *isp1362_hcd) -{ - struct isp1362_ep *ep; - struct isp1362_ep *tmp; - - list_for_each_entry_safe(ep, tmp, &isp1362_hcd->remove_list, remove_list) { - struct isp1362_ep_queue *epq = - get_ptd_queue(isp1362_hcd, ep->ptd_offset); - int index = ep->ptd_index; - - BUG_ON(epq == NULL); - if (index >= 0) { - DBG(1, "%s: remove PTD[%d] $%04x\n", __func__, index, ep->ptd_offset); - BUG_ON(ep->num_ptds == 0); - release_ptd_buffers(epq, ep); - } - if (!list_empty(&ep->hep->urb_list)) { - struct urb *urb = get_urb(ep); - - DBG(1, "%s: Finishing req %d ep %p from remove_list\n", __func__, - ep->num_req, ep); - finish_request(isp1362_hcd, ep, urb, -ESHUTDOWN); - } - WARN_ON(list_empty(&ep->active)); - if (!list_empty(&ep->active)) { - list_del_init(&ep->active); - DBG(1, "%s: ep %p removed from active list\n", __func__, ep); - } - list_del_init(&ep->remove_list); - DBG(1, "%s: ep %p removed from remove_list\n", __func__, ep); - } - DBG(1, "%s: Done\n", __func__); -} - -static inline void enable_atl_transfers(struct isp1362_hcd *isp1362_hcd, int count) -{ - if (count > 0) { - if (count < isp1362_hcd->atl_queue.ptd_count) - isp1362_write_reg16(isp1362_hcd, HCATLDTC, count); - isp1362_enable_int(isp1362_hcd, HCuPINT_ATL); - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, isp1362_hcd->atl_queue.skip_map); - isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE); - } else - isp1362_enable_int(isp1362_hcd, HCuPINT_SOF); -} - -static inline void enable_intl_transfers(struct isp1362_hcd *isp1362_hcd) -{ - isp1362_enable_int(isp1362_hcd, HCuPINT_INTL); - isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE); - isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, isp1362_hcd->intl_queue.skip_map); -} - -static inline void enable_istl_transfers(struct isp1362_hcd *isp1362_hcd, int flip) -{ - isp1362_enable_int(isp1362_hcd, flip ? HCuPINT_ISTL1 : HCuPINT_ISTL0); - isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, flip ? - HCBUFSTAT_ISTL1_FULL : HCBUFSTAT_ISTL0_FULL); -} - -static int submit_req(struct isp1362_hcd *isp1362_hcd, struct urb *urb, - struct isp1362_ep *ep, struct isp1362_ep_queue *epq) -{ - int index; - - prepare_ptd(isp1362_hcd, urb, ep, epq, 0); - index = claim_ptd_buffers(epq, ep, ep->length); - if (index == -ENOMEM) { - DBG(1, "%s: req %d No free %s PTD available: %d, %08lx:%08lx\n", __func__, - ep->num_req, epq->name, ep->num_ptds, epq->buf_map, epq->skip_map); - return index; - } else if (index == -EOVERFLOW) { - DBG(1, "%s: req %d Not enough space for %d byte %s PTD %d %08lx:%08lx\n", - __func__, ep->num_req, ep->length, epq->name, ep->num_ptds, - epq->buf_map, epq->skip_map); - return index; - } else - BUG_ON(index < 0); - list_add_tail(&ep->active, &epq->active); - DBG(1, "%s: ep %p req %d len %d added to active list %p\n", __func__, - ep, ep->num_req, ep->length, &epq->active); - DBG(1, "%s: Submitting %s PTD $%04x for ep %p req %d\n", __func__, epq->name, - ep->ptd_offset, ep, ep->num_req); - isp1362_write_ptd(isp1362_hcd, ep, epq); - __clear_bit(ep->ptd_index, &epq->skip_map); - - return 0; -} - -static void start_atl_transfers(struct isp1362_hcd *isp1362_hcd) -{ - int ptd_count = 0; - struct isp1362_ep_queue *epq = &isp1362_hcd->atl_queue; - struct isp1362_ep *ep; - int defer = 0; - - if (atomic_read(&epq->finishing)) { - DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name); - return; - } - - list_for_each_entry(ep, &isp1362_hcd->async, schedule) { - struct urb *urb = get_urb(ep); - int ret; - - if (!list_empty(&ep->active)) { - DBG(2, "%s: Skipping active %s ep %p\n", __func__, epq->name, ep); - continue; - } - - DBG(1, "%s: Processing %s ep %p req %d\n", __func__, epq->name, - ep, ep->num_req); - - ret = submit_req(isp1362_hcd, urb, ep, epq); - if (ret == -ENOMEM) { - defer = 1; - break; - } else if (ret == -EOVERFLOW) { - defer = 1; - continue; - } -#ifdef BUGGY_PXA2XX_UDC_USBTEST - defer = ep->nextpid == USB_PID_SETUP; -#endif - ptd_count++; - } - - /* Avoid starving of endpoints */ - if (isp1362_hcd->async.next != isp1362_hcd->async.prev) { - DBG(2, "%s: Cycling ASYNC schedule %d\n", __func__, ptd_count); - list_move(&isp1362_hcd->async, isp1362_hcd->async.next); - } - if (ptd_count || defer) - enable_atl_transfers(isp1362_hcd, defer ? 0 : ptd_count); - - epq->ptd_count += ptd_count; - if (epq->ptd_count > epq->stat_maxptds) { - epq->stat_maxptds = epq->ptd_count; - DBG(0, "%s: max_ptds: %d\n", __func__, epq->stat_maxptds); - } -} - -static void start_intl_transfers(struct isp1362_hcd *isp1362_hcd) -{ - int ptd_count = 0; - struct isp1362_ep_queue *epq = &isp1362_hcd->intl_queue; - struct isp1362_ep *ep; - - if (atomic_read(&epq->finishing)) { - DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name); - return; - } - - list_for_each_entry(ep, &isp1362_hcd->periodic, schedule) { - struct urb *urb = get_urb(ep); - int ret; - - if (!list_empty(&ep->active)) { - DBG(1, "%s: Skipping active %s ep %p\n", __func__, - epq->name, ep); - continue; - } - - DBG(1, "%s: Processing %s ep %p req %d\n", __func__, - epq->name, ep, ep->num_req); - ret = submit_req(isp1362_hcd, urb, ep, epq); - if (ret == -ENOMEM) - break; - else if (ret == -EOVERFLOW) - continue; - ptd_count++; - } - - if (ptd_count) { - static int last_count; - - if (ptd_count != last_count) { - DBG(0, "%s: ptd_count: %d\n", __func__, ptd_count); - last_count = ptd_count; - } - enable_intl_transfers(isp1362_hcd); - } - - epq->ptd_count += ptd_count; - if (epq->ptd_count > epq->stat_maxptds) - epq->stat_maxptds = epq->ptd_count; -} - -static inline int next_ptd(struct isp1362_ep_queue *epq, struct isp1362_ep *ep) -{ - u16 ptd_offset = ep->ptd_offset; - int num_ptds = (ep->length + PTD_HEADER_SIZE + (epq->blk_size - 1)) / epq->blk_size; - - DBG(2, "%s: PTD offset $%04x + %04x => %d * %04x -> $%04x\n", __func__, ptd_offset, - ep->length, num_ptds, epq->blk_size, ptd_offset + num_ptds * epq->blk_size); - - ptd_offset += num_ptds * epq->blk_size; - if (ptd_offset < epq->buf_start + epq->buf_size) - return ptd_offset; - else - return -ENOMEM; -} - -static void start_iso_transfers(struct isp1362_hcd *isp1362_hcd) -{ - int ptd_count = 0; - int flip = isp1362_hcd->istl_flip; - struct isp1362_ep_queue *epq; - int ptd_offset; - struct isp1362_ep *ep; - struct isp1362_ep *tmp; - u16 fno = isp1362_read_reg32(isp1362_hcd, HCFMNUM); - - fill2: - epq = &isp1362_hcd->istl_queue[flip]; - if (atomic_read(&epq->finishing)) { - DBG(1, "%s: finish_transfers is active for %s\n", __func__, epq->name); - return; - } - - if (!list_empty(&epq->active)) - return; - - ptd_offset = epq->buf_start; - list_for_each_entry_safe(ep, tmp, &isp1362_hcd->isoc, schedule) { - struct urb *urb = get_urb(ep); - s16 diff = fno - (u16)urb->start_frame; - - DBG(1, "%s: Processing %s ep %p\n", __func__, epq->name, ep); - - if (diff > urb->number_of_packets) { - /* time frame for this URB has elapsed */ - finish_request(isp1362_hcd, ep, urb, -EOVERFLOW); - continue; - } else if (diff < -1) { - /* URB is not due in this frame or the next one. - * Comparing with '-1' instead of '0' accounts for double - * buffering in the ISP1362 which enables us to queue the PTD - * one frame ahead of time - */ - } else if (diff == -1) { - /* submit PTD's that are due in the next frame */ - prepare_ptd(isp1362_hcd, urb, ep, epq, fno); - if (ptd_offset + PTD_HEADER_SIZE + ep->length > - epq->buf_start + epq->buf_size) { - pr_err("%s: Not enough ISO buffer space for %d byte PTD\n", - __func__, ep->length); - continue; - } - ep->ptd_offset = ptd_offset; - list_add_tail(&ep->active, &epq->active); - - ptd_offset = next_ptd(epq, ep); - if (ptd_offset < 0) { - pr_warn("%s: req %d No more %s PTD buffers available\n", - __func__, ep->num_req, epq->name); - break; - } - } - } - list_for_each_entry(ep, &epq->active, active) { - if (epq->active.next == &ep->active) - ep->ptd.mps |= PTD_LAST_MSK; - isp1362_write_ptd(isp1362_hcd, ep, epq); - ptd_count++; - } - - if (ptd_count) - enable_istl_transfers(isp1362_hcd, flip); - - epq->ptd_count += ptd_count; - if (epq->ptd_count > epq->stat_maxptds) - epq->stat_maxptds = epq->ptd_count; - - /* check, whether the second ISTL buffer may also be filled */ - if (!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) & - (flip ? HCBUFSTAT_ISTL0_FULL : HCBUFSTAT_ISTL1_FULL))) { - fno++; - ptd_count = 0; - flip = 1 - flip; - goto fill2; - } -} - -static void finish_transfers(struct isp1362_hcd *isp1362_hcd, unsigned long done_map, - struct isp1362_ep_queue *epq) -{ - struct isp1362_ep *ep; - struct isp1362_ep *tmp; - - if (list_empty(&epq->active)) { - DBG(1, "%s: Nothing to do for %s queue\n", __func__, epq->name); - return; - } - - DBG(1, "%s: Finishing %s transfers %08lx\n", __func__, epq->name, done_map); - - atomic_inc(&epq->finishing); - list_for_each_entry_safe(ep, tmp, &epq->active, active) { - int index = ep->ptd_index; - - DBG(1, "%s: Checking %s PTD[%02x] $%04x\n", __func__, epq->name, - index, ep->ptd_offset); - - BUG_ON(index < 0); - if (__test_and_clear_bit(index, &done_map)) { - isp1362_read_ptd(isp1362_hcd, ep, epq); - epq->free_ptd = index; - BUG_ON(ep->num_ptds == 0); - release_ptd_buffers(epq, ep); - - DBG(1, "%s: ep %p req %d removed from active list\n", __func__, - ep, ep->num_req); - if (!list_empty(&ep->remove_list)) { - list_del_init(&ep->remove_list); - DBG(1, "%s: ep %p removed from remove list\n", __func__, ep); - } - DBG(1, "%s: Postprocessing %s ep %p req %d\n", __func__, epq->name, - ep, ep->num_req); - postproc_ep(isp1362_hcd, ep); - } - if (!done_map) - break; - } - if (done_map) - pr_warn("%s: done_map not clear: %08lx:%08lx\n", - __func__, done_map, epq->skip_map); - atomic_dec(&epq->finishing); -} - -static void finish_iso_transfers(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep_queue *epq) -{ - struct isp1362_ep *ep; - struct isp1362_ep *tmp; - - if (list_empty(&epq->active)) { - DBG(1, "%s: Nothing to do for %s queue\n", __func__, epq->name); - return; - } - - DBG(1, "%s: Finishing %s transfers\n", __func__, epq->name); - - atomic_inc(&epq->finishing); - list_for_each_entry_safe(ep, tmp, &epq->active, active) { - DBG(1, "%s: Checking PTD $%04x\n", __func__, ep->ptd_offset); - - isp1362_read_ptd(isp1362_hcd, ep, epq); - DBG(1, "%s: Postprocessing %s ep %p\n", __func__, epq->name, ep); - postproc_ep(isp1362_hcd, ep); - } - WARN_ON(epq->blk_size != 0); - atomic_dec(&epq->finishing); -} - -static irqreturn_t isp1362_irq(struct usb_hcd *hcd) -{ - int handled = 0; - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - u16 irqstat; - u16 svc_mask; - - spin_lock(&isp1362_hcd->lock); - - BUG_ON(isp1362_hcd->irq_active++); - - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0); - - irqstat = isp1362_read_reg16(isp1362_hcd, HCuPINT); - DBG(3, "%s: got IRQ %04x:%04x\n", __func__, irqstat, isp1362_hcd->irqenb); - - /* only handle interrupts that are currently enabled */ - irqstat &= isp1362_hcd->irqenb; - isp1362_write_reg16(isp1362_hcd, HCuPINT, irqstat); - svc_mask = irqstat; - - if (irqstat & HCuPINT_SOF) { - isp1362_hcd->irqenb &= ~HCuPINT_SOF; - isp1362_hcd->irq_stat[ISP1362_INT_SOF]++; - handled = 1; - svc_mask &= ~HCuPINT_SOF; - DBG(3, "%s: SOF\n", __func__); - isp1362_hcd->fmindex = isp1362_read_reg32(isp1362_hcd, HCFMNUM); - if (!list_empty(&isp1362_hcd->remove_list)) - finish_unlinks(isp1362_hcd); - if (!list_empty(&isp1362_hcd->async) && !(irqstat & HCuPINT_ATL)) { - if (list_empty(&isp1362_hcd->atl_queue.active)) { - start_atl_transfers(isp1362_hcd); - } else { - isp1362_enable_int(isp1362_hcd, HCuPINT_ATL); - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, - isp1362_hcd->atl_queue.skip_map); - isp1362_set_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE); - } - } - } - - if (irqstat & HCuPINT_ISTL0) { - isp1362_hcd->irq_stat[ISP1362_INT_ISTL0]++; - handled = 1; - svc_mask &= ~HCuPINT_ISTL0; - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ISTL0_FULL); - DBG(1, "%s: ISTL0\n", __func__); - WARN_ON((int)!!isp1362_hcd->istl_flip); - WARN_ON(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) & - HCBUFSTAT_ISTL0_ACTIVE); - WARN_ON(!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) & - HCBUFSTAT_ISTL0_DONE)); - isp1362_hcd->irqenb &= ~HCuPINT_ISTL0; - } - - if (irqstat & HCuPINT_ISTL1) { - isp1362_hcd->irq_stat[ISP1362_INT_ISTL1]++; - handled = 1; - svc_mask &= ~HCuPINT_ISTL1; - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ISTL1_FULL); - DBG(1, "%s: ISTL1\n", __func__); - WARN_ON(!(int)isp1362_hcd->istl_flip); - WARN_ON(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) & - HCBUFSTAT_ISTL1_ACTIVE); - WARN_ON(!(isp1362_read_reg16(isp1362_hcd, HCBUFSTAT) & - HCBUFSTAT_ISTL1_DONE)); - isp1362_hcd->irqenb &= ~HCuPINT_ISTL1; - } - - if (irqstat & (HCuPINT_ISTL0 | HCuPINT_ISTL1)) { - WARN_ON((irqstat & (HCuPINT_ISTL0 | HCuPINT_ISTL1)) == - (HCuPINT_ISTL0 | HCuPINT_ISTL1)); - finish_iso_transfers(isp1362_hcd, - &isp1362_hcd->istl_queue[isp1362_hcd->istl_flip]); - start_iso_transfers(isp1362_hcd); - isp1362_hcd->istl_flip = 1 - isp1362_hcd->istl_flip; - } - - if (irqstat & HCuPINT_INTL) { - u32 done_map = isp1362_read_reg32(isp1362_hcd, HCINTLDONE); - u32 skip_map = isp1362_read_reg32(isp1362_hcd, HCINTLSKIP); - isp1362_hcd->irq_stat[ISP1362_INT_INTL]++; - - DBG(2, "%s: INTL\n", __func__); - - svc_mask &= ~HCuPINT_INTL; - - isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, skip_map | done_map); - if (~(done_map | skip_map) == 0) - /* All PTDs are finished, disable INTL processing entirely */ - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_INTL_ACTIVE); - - handled = 1; - WARN_ON(!done_map); - if (done_map) { - DBG(3, "%s: INTL done_map %08x\n", __func__, done_map); - finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->intl_queue); - start_intl_transfers(isp1362_hcd); - } - } - - if (irqstat & HCuPINT_ATL) { - u32 done_map = isp1362_read_reg32(isp1362_hcd, HCATLDONE); - u32 skip_map = isp1362_read_reg32(isp1362_hcd, HCATLSKIP); - isp1362_hcd->irq_stat[ISP1362_INT_ATL]++; - - DBG(2, "%s: ATL\n", __func__); - - svc_mask &= ~HCuPINT_ATL; - - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, skip_map | done_map); - if (~(done_map | skip_map) == 0) - isp1362_clr_mask16(isp1362_hcd, HCBUFSTAT, HCBUFSTAT_ATL_ACTIVE); - if (done_map) { - DBG(3, "%s: ATL done_map %08x\n", __func__, done_map); - finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->atl_queue); - start_atl_transfers(isp1362_hcd); - } - handled = 1; - } - - if (irqstat & HCuPINT_OPR) { - u32 intstat = isp1362_read_reg32(isp1362_hcd, HCINTSTAT); - isp1362_hcd->irq_stat[ISP1362_INT_OPR]++; - - svc_mask &= ~HCuPINT_OPR; - DBG(2, "%s: OPR %08x:%08x\n", __func__, intstat, isp1362_hcd->intenb); - intstat &= isp1362_hcd->intenb; - if (intstat & OHCI_INTR_UE) { - pr_err("Unrecoverable error\n"); - /* FIXME: do here reset or cleanup or whatever */ - } - if (intstat & OHCI_INTR_RHSC) { - isp1362_hcd->rhstatus = isp1362_read_reg32(isp1362_hcd, HCRHSTATUS); - isp1362_hcd->rhport[0] = isp1362_read_reg32(isp1362_hcd, HCRHPORT1); - isp1362_hcd->rhport[1] = isp1362_read_reg32(isp1362_hcd, HCRHPORT2); - } - if (intstat & OHCI_INTR_RD) { - pr_info("%s: RESUME DETECTED\n", __func__); - isp1362_show_reg(isp1362_hcd, HCCONTROL); - usb_hcd_resume_root_hub(hcd); - } - isp1362_write_reg32(isp1362_hcd, HCINTSTAT, intstat); - irqstat &= ~HCuPINT_OPR; - handled = 1; - } - - if (irqstat & HCuPINT_SUSP) { - isp1362_hcd->irq_stat[ISP1362_INT_SUSP]++; - handled = 1; - svc_mask &= ~HCuPINT_SUSP; - - pr_info("%s: SUSPEND IRQ\n", __func__); - } - - if (irqstat & HCuPINT_CLKRDY) { - isp1362_hcd->irq_stat[ISP1362_INT_CLKRDY]++; - handled = 1; - isp1362_hcd->irqenb &= ~HCuPINT_CLKRDY; - svc_mask &= ~HCuPINT_CLKRDY; - pr_info("%s: CLKRDY IRQ\n", __func__); - } - - if (svc_mask) - pr_err("%s: Unserviced interrupt(s) %04x\n", __func__, svc_mask); - - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb); - isp1362_hcd->irq_active--; - spin_unlock(&isp1362_hcd->lock); - - return IRQ_RETVAL(handled); -} - -/*-------------------------------------------------------------------------*/ - -#define MAX_PERIODIC_LOAD 900 /* out of 1000 usec */ -static int balance(struct isp1362_hcd *isp1362_hcd, u16 interval, u16 load) -{ - int i, branch = -ENOSPC; - - /* search for the least loaded schedule branch of that interval - * which has enough bandwidth left unreserved. - */ - for (i = 0; i < interval; i++) { - if (branch < 0 || isp1362_hcd->load[branch] > isp1362_hcd->load[i]) { - int j; - - for (j = i; j < PERIODIC_SIZE; j += interval) { - if ((isp1362_hcd->load[j] + load) > MAX_PERIODIC_LOAD) { - pr_err("%s: new load %d load[%02x] %d max %d\n", __func__, - load, j, isp1362_hcd->load[j], MAX_PERIODIC_LOAD); - break; - } - } - if (j < PERIODIC_SIZE) - continue; - branch = i; - } - } - return branch; -} - -/* NB! ALL the code above this point runs with isp1362_hcd->lock - held, irqs off -*/ - -/*-------------------------------------------------------------------------*/ - -static int isp1362_urb_enqueue(struct usb_hcd *hcd, - struct urb *urb, - gfp_t mem_flags) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - struct usb_device *udev = urb->dev; - unsigned int pipe = urb->pipe; - int is_out = !usb_pipein(pipe); - int type = usb_pipetype(pipe); - int epnum = usb_pipeendpoint(pipe); - struct usb_host_endpoint *hep = urb->ep; - struct isp1362_ep *ep = NULL; - unsigned long flags; - int retval = 0; - - DBG(3, "%s: urb %p\n", __func__, urb); - - if (type == PIPE_ISOCHRONOUS) { - pr_err("Isochronous transfers not supported\n"); - return -ENOSPC; - } - - URB_DBG("%s: FA %d ep%d%s %s: len %d %s%s\n", __func__, - usb_pipedevice(pipe), epnum, - is_out ? "out" : "in", - usb_pipecontrol(pipe) ? "ctrl" : - usb_pipeint(pipe) ? "int" : - usb_pipebulk(pipe) ? "bulk" : - "iso", - urb->transfer_buffer_length, - (urb->transfer_flags & URB_ZERO_PACKET) ? "ZERO_PACKET " : "", - !(urb->transfer_flags & URB_SHORT_NOT_OK) ? - "short_ok" : ""); - - /* avoid all allocations within spinlocks: request or endpoint */ - if (!hep->hcpriv) { - ep = kzalloc(sizeof *ep, mem_flags); - if (!ep) - return -ENOMEM; - } - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - /* don't submit to a dead or disabled port */ - if (!((isp1362_hcd->rhport[0] | isp1362_hcd->rhport[1]) & - USB_PORT_STAT_ENABLE) || - !HC_IS_RUNNING(hcd->state)) { - kfree(ep); - retval = -ENODEV; - goto fail_not_linked; - } - - retval = usb_hcd_link_urb_to_ep(hcd, urb); - if (retval) { - kfree(ep); - goto fail_not_linked; - } - - if (hep->hcpriv) { - ep = hep->hcpriv; - } else { - INIT_LIST_HEAD(&ep->schedule); - INIT_LIST_HEAD(&ep->active); - INIT_LIST_HEAD(&ep->remove_list); - ep->udev = usb_get_dev(udev); - ep->hep = hep; - ep->epnum = epnum; - ep->maxpacket = usb_maxpacket(udev, urb->pipe); - ep->ptd_offset = -EINVAL; - ep->ptd_index = -EINVAL; - usb_settoggle(udev, epnum, is_out, 0); - - if (type == PIPE_CONTROL) - ep->nextpid = USB_PID_SETUP; - else if (is_out) - ep->nextpid = USB_PID_OUT; - else - ep->nextpid = USB_PID_IN; - - switch (type) { - case PIPE_ISOCHRONOUS: - case PIPE_INTERRUPT: - if (urb->interval > PERIODIC_SIZE) - urb->interval = PERIODIC_SIZE; - ep->interval = urb->interval; - ep->branch = PERIODIC_SIZE; - ep->load = usb_calc_bus_time(udev->speed, !is_out, - type == PIPE_ISOCHRONOUS, - usb_maxpacket(udev, pipe)) / 1000; - break; - } - hep->hcpriv = ep; - } - ep->num_req = isp1362_hcd->req_serial++; - - /* maybe put endpoint into schedule */ - switch (type) { - case PIPE_CONTROL: - case PIPE_BULK: - if (list_empty(&ep->schedule)) { - DBG(1, "%s: Adding ep %p req %d to async schedule\n", - __func__, ep, ep->num_req); - list_add_tail(&ep->schedule, &isp1362_hcd->async); - } - break; - case PIPE_ISOCHRONOUS: - case PIPE_INTERRUPT: - urb->interval = ep->interval; - - /* urb submitted for already existing EP */ - if (ep->branch < PERIODIC_SIZE) - break; - - retval = balance(isp1362_hcd, ep->interval, ep->load); - if (retval < 0) { - pr_err("%s: balance returned %d\n", __func__, retval); - goto fail; - } - ep->branch = retval; - retval = 0; - isp1362_hcd->fmindex = isp1362_read_reg32(isp1362_hcd, HCFMNUM); - DBG(1, "%s: Current frame %04x branch %02x start_frame %04x(%04x)\n", - __func__, isp1362_hcd->fmindex, ep->branch, - ((isp1362_hcd->fmindex + PERIODIC_SIZE - 1) & - ~(PERIODIC_SIZE - 1)) + ep->branch, - (isp1362_hcd->fmindex & (PERIODIC_SIZE - 1)) + ep->branch); - - if (list_empty(&ep->schedule)) { - if (type == PIPE_ISOCHRONOUS) { - u16 frame = isp1362_hcd->fmindex; - - frame += max_t(u16, 8, ep->interval); - frame &= ~(ep->interval - 1); - frame |= ep->branch; - if (frame_before(frame, isp1362_hcd->fmindex)) - frame += ep->interval; - urb->start_frame = frame; - - DBG(1, "%s: Adding ep %p to isoc schedule\n", __func__, ep); - list_add_tail(&ep->schedule, &isp1362_hcd->isoc); - } else { - DBG(1, "%s: Adding ep %p to periodic schedule\n", __func__, ep); - list_add_tail(&ep->schedule, &isp1362_hcd->periodic); - } - } else - DBG(1, "%s: ep %p already scheduled\n", __func__, ep); - - DBG(2, "%s: load %d bandwidth %d -> %d\n", __func__, - ep->load / ep->interval, isp1362_hcd->load[ep->branch], - isp1362_hcd->load[ep->branch] + ep->load); - isp1362_hcd->load[ep->branch] += ep->load; - } - - urb->hcpriv = hep; - ALIGNSTAT(isp1362_hcd, urb->transfer_buffer); - - switch (type) { - case PIPE_CONTROL: - case PIPE_BULK: - start_atl_transfers(isp1362_hcd); - break; - case PIPE_INTERRUPT: - start_intl_transfers(isp1362_hcd); - break; - case PIPE_ISOCHRONOUS: - start_iso_transfers(isp1362_hcd); - break; - default: - BUG(); - } - fail: - if (retval) - usb_hcd_unlink_urb_from_ep(hcd, urb); - - - fail_not_linked: - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (retval) - DBG(0, "%s: urb %p failed with %d\n", __func__, urb, retval); - return retval; -} - -static int isp1362_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - struct usb_host_endpoint *hep; - unsigned long flags; - struct isp1362_ep *ep; - int retval = 0; - - DBG(3, "%s: urb %p\n", __func__, urb); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - retval = usb_hcd_check_unlink_urb(hcd, urb, status); - if (retval) - goto done; - - hep = urb->hcpriv; - - if (!hep) { - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - return -EIDRM; - } - - ep = hep->hcpriv; - if (ep) { - /* In front of queue? */ - if (ep->hep->urb_list.next == &urb->urb_list) { - if (!list_empty(&ep->active)) { - DBG(1, "%s: urb %p ep %p req %d active PTD[%d] $%04x\n", __func__, - urb, ep, ep->num_req, ep->ptd_index, ep->ptd_offset); - /* disable processing and queue PTD for removal */ - remove_ptd(isp1362_hcd, ep); - urb = NULL; - } - } - if (urb) { - DBG(1, "%s: Finishing ep %p req %d\n", __func__, ep, - ep->num_req); - finish_request(isp1362_hcd, ep, urb, status); - } else - DBG(1, "%s: urb %p active; wait4irq\n", __func__, urb); - } else { - pr_warn("%s: No EP in URB %p\n", __func__, urb); - retval = -EINVAL; - } -done: - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - DBG(3, "%s: exit\n", __func__); - - return retval; -} - -static void isp1362_endpoint_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) -{ - struct isp1362_ep *ep = hep->hcpriv; - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - - DBG(1, "%s: ep %p\n", __func__, ep); - if (!ep) - return; - spin_lock_irqsave(&isp1362_hcd->lock, flags); - if (!list_empty(&hep->urb_list)) { - if (!list_empty(&ep->active) && list_empty(&ep->remove_list)) { - DBG(1, "%s: Removing ep %p req %d PTD[%d] $%04x\n", __func__, - ep, ep->num_req, ep->ptd_index, ep->ptd_offset); - remove_ptd(isp1362_hcd, ep); - pr_info("%s: Waiting for Interrupt to clean up\n", __func__); - } - } - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - /* Wait for interrupt to clear out active list */ - while (!list_empty(&ep->active)) - msleep(1); - - DBG(1, "%s: Freeing EP %p\n", __func__, ep); - - usb_put_dev(ep->udev); - kfree(ep); - hep->hcpriv = NULL; -} - -static int isp1362_get_frame(struct usb_hcd *hcd) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - u32 fmnum; - unsigned long flags; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - fmnum = isp1362_read_reg32(isp1362_hcd, HCFMNUM); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - return (int)fmnum; -} - -/*-------------------------------------------------------------------------*/ - -/* Adapted from ohci-hub.c */ -static int isp1362_hub_status_data(struct usb_hcd *hcd, char *buf) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - int ports, i, changed = 0; - unsigned long flags; - - if (!HC_IS_RUNNING(hcd->state)) - return -ESHUTDOWN; - - /* Report no status change now, if we are scheduled to be - called later */ - if (timer_pending(&hcd->rh_timer)) - return 0; - - ports = isp1362_hcd->rhdesca & RH_A_NDP; - BUG_ON(ports > 2); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - /* init status */ - if (isp1362_hcd->rhstatus & (RH_HS_LPSC | RH_HS_OCIC)) - buf[0] = changed = 1; - else - buf[0] = 0; - - for (i = 0; i < ports; i++) { - u32 status = isp1362_hcd->rhport[i]; - - if (status & (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | - RH_PS_OCIC | RH_PS_PRSC)) { - changed = 1; - buf[0] |= 1 << (i + 1); - continue; - } - - if (!(status & RH_PS_CCS)) - continue; - } - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - return changed; -} - -static void isp1362_hub_descriptor(struct isp1362_hcd *isp1362_hcd, - struct usb_hub_descriptor *desc) -{ - u32 reg = isp1362_hcd->rhdesca; - - DBG(3, "%s: enter\n", __func__); - - desc->bDescriptorType = USB_DT_HUB; - desc->bDescLength = 9; - desc->bHubContrCurrent = 0; - desc->bNbrPorts = reg & 0x3; - /* Power switching, device type, overcurrent. */ - desc->wHubCharacteristics = cpu_to_le16((reg >> 8) & - (HUB_CHAR_LPSM | - HUB_CHAR_COMPOUND | - HUB_CHAR_OCPM)); - DBG(0, "%s: hubcharacteristics = %02x\n", __func__, - desc->wHubCharacteristics); - desc->bPwrOn2PwrGood = (reg >> 24) & 0xff; - /* ports removable, and legacy PortPwrCtrlMask */ - desc->u.hs.DeviceRemovable[0] = desc->bNbrPorts == 1 ? 1 << 1 : 3 << 1; - desc->u.hs.DeviceRemovable[1] = ~0; - - DBG(3, "%s: exit\n", __func__); -} - -/* Adapted from ohci-hub.c */ -static int isp1362_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, - u16 wIndex, char *buf, u16 wLength) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - int retval = 0; - unsigned long flags; - unsigned long t1; - int ports = isp1362_hcd->rhdesca & RH_A_NDP; - u32 tmp = 0; - - switch (typeReq) { - case ClearHubFeature: - DBG(0, "ClearHubFeature: "); - switch (wValue) { - case C_HUB_OVER_CURRENT: - DBG(0, "C_HUB_OVER_CURRENT\n"); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_OCIC); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - break; - case C_HUB_LOCAL_POWER: - DBG(0, "C_HUB_LOCAL_POWER\n"); - break; - default: - goto error; - } - break; - case SetHubFeature: - DBG(0, "SetHubFeature: "); - switch (wValue) { - case C_HUB_OVER_CURRENT: - case C_HUB_LOCAL_POWER: - DBG(0, "C_HUB_OVER_CURRENT or C_HUB_LOCAL_POWER\n"); - break; - default: - goto error; - } - break; - case GetHubDescriptor: - DBG(0, "GetHubDescriptor\n"); - isp1362_hub_descriptor(isp1362_hcd, (struct usb_hub_descriptor *)buf); - break; - case GetHubStatus: - DBG(0, "GetHubStatus\n"); - put_unaligned(cpu_to_le32(0), (__le32 *) buf); - break; - case GetPortStatus: -#ifndef VERBOSE - DBG(0, "GetPortStatus\n"); -#endif - if (!wIndex || wIndex > ports) - goto error; - tmp = isp1362_hcd->rhport[--wIndex]; - put_unaligned(cpu_to_le32(tmp), (__le32 *) buf); - break; - case ClearPortFeature: - DBG(0, "ClearPortFeature: "); - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - - switch (wValue) { - case USB_PORT_FEAT_ENABLE: - DBG(0, "USB_PORT_FEAT_ENABLE\n"); - tmp = RH_PS_CCS; - break; - case USB_PORT_FEAT_C_ENABLE: - DBG(0, "USB_PORT_FEAT_C_ENABLE\n"); - tmp = RH_PS_PESC; - break; - case USB_PORT_FEAT_SUSPEND: - DBG(0, "USB_PORT_FEAT_SUSPEND\n"); - tmp = RH_PS_POCI; - break; - case USB_PORT_FEAT_C_SUSPEND: - DBG(0, "USB_PORT_FEAT_C_SUSPEND\n"); - tmp = RH_PS_PSSC; - break; - case USB_PORT_FEAT_POWER: - DBG(0, "USB_PORT_FEAT_POWER\n"); - tmp = RH_PS_LSDA; - - break; - case USB_PORT_FEAT_C_CONNECTION: - DBG(0, "USB_PORT_FEAT_C_CONNECTION\n"); - tmp = RH_PS_CSC; - break; - case USB_PORT_FEAT_C_OVER_CURRENT: - DBG(0, "USB_PORT_FEAT_C_OVER_CURRENT\n"); - tmp = RH_PS_OCIC; - break; - case USB_PORT_FEAT_C_RESET: - DBG(0, "USB_PORT_FEAT_C_RESET\n"); - tmp = RH_PS_PRSC; - break; - default: - goto error; - } - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, tmp); - isp1362_hcd->rhport[wIndex] = - isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - break; - case SetPortFeature: - DBG(0, "SetPortFeature: "); - if (!wIndex || wIndex > ports) - goto error; - wIndex--; - switch (wValue) { - case USB_PORT_FEAT_SUSPEND: - DBG(0, "USB_PORT_FEAT_SUSPEND\n"); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PSS); - isp1362_hcd->rhport[wIndex] = - isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - break; - case USB_PORT_FEAT_POWER: - DBG(0, "USB_PORT_FEAT_POWER\n"); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, RH_PS_PPS); - isp1362_hcd->rhport[wIndex] = - isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - break; - case USB_PORT_FEAT_RESET: - DBG(0, "USB_PORT_FEAT_RESET\n"); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - t1 = jiffies + msecs_to_jiffies(USB_RESET_WIDTH); - while (time_before(jiffies, t1)) { - /* spin until any current reset finishes */ - for (;;) { - tmp = isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + wIndex); - if (!(tmp & RH_PS_PRS)) - break; - udelay(500); - } - if (!(tmp & RH_PS_CCS)) - break; - /* Reset lasts 10ms (claims datasheet) */ - isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + wIndex, (RH_PS_PRS)); - - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - msleep(10); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - } - - isp1362_hcd->rhport[wIndex] = isp1362_read_reg32(isp1362_hcd, - HCRHPORT1 + wIndex); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - break; - default: - goto error; - } - break; - - default: - error: - /* "protocol stall" on error */ - DBG(0, "PROTOCOL STALL\n"); - retval = -EPIPE; - } - - return retval; -} - -#ifdef CONFIG_PM -static int isp1362_bus_suspend(struct usb_hcd *hcd) -{ - int status = 0; - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - - if (time_before(jiffies, isp1362_hcd->next_statechange)) - msleep(5); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL); - switch (isp1362_hcd->hc_control & OHCI_CTRL_HCFS) { - case OHCI_USB_RESUME: - DBG(0, "%s: resume/suspend?\n", __func__); - isp1362_hcd->hc_control &= ~OHCI_CTRL_HCFS; - isp1362_hcd->hc_control |= OHCI_USB_RESET; - isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control); - fallthrough; - case OHCI_USB_RESET: - status = -EBUSY; - pr_warn("%s: needs reinit!\n", __func__); - goto done; - case OHCI_USB_SUSPEND: - pr_warn("%s: already suspended?\n", __func__); - goto done; - } - DBG(0, "%s: suspend root hub\n", __func__); - - /* First stop any processing */ - hcd->state = HC_STATE_QUIESCING; - if (!list_empty(&isp1362_hcd->atl_queue.active) || - !list_empty(&isp1362_hcd->intl_queue.active) || - !list_empty(&isp1362_hcd->istl_queue[0] .active) || - !list_empty(&isp1362_hcd->istl_queue[1] .active)) { - int limit; - - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, ~0); - isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, ~0); - isp1362_write_reg16(isp1362_hcd, HCBUFSTAT, 0); - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0); - isp1362_write_reg32(isp1362_hcd, HCINTSTAT, OHCI_INTR_SF); - - DBG(0, "%s: stopping schedules ...\n", __func__); - limit = 2000; - while (limit > 0) { - udelay(250); - limit -= 250; - if (isp1362_read_reg32(isp1362_hcd, HCINTSTAT) & OHCI_INTR_SF) - break; - } - mdelay(7); - if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ATL) { - u32 done_map = isp1362_read_reg32(isp1362_hcd, HCATLDONE); - finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->atl_queue); - } - if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_INTL) { - u32 done_map = isp1362_read_reg32(isp1362_hcd, HCINTLDONE); - finish_transfers(isp1362_hcd, done_map, &isp1362_hcd->intl_queue); - } - if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ISTL0) - finish_iso_transfers(isp1362_hcd, &isp1362_hcd->istl_queue[0]); - if (isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_ISTL1) - finish_iso_transfers(isp1362_hcd, &isp1362_hcd->istl_queue[1]); - } - DBG(0, "%s: HCINTSTAT: %08x\n", __func__, - isp1362_read_reg32(isp1362_hcd, HCINTSTAT)); - isp1362_write_reg32(isp1362_hcd, HCINTSTAT, - isp1362_read_reg32(isp1362_hcd, HCINTSTAT)); - - /* Suspend hub */ - isp1362_hcd->hc_control = OHCI_USB_SUSPEND; - isp1362_show_reg(isp1362_hcd, HCCONTROL); - isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control); - isp1362_show_reg(isp1362_hcd, HCCONTROL); - -#if 1 - isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL); - if ((isp1362_hcd->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_SUSPEND) { - pr_err("%s: controller won't suspend %08x\n", __func__, - isp1362_hcd->hc_control); - status = -EBUSY; - } else -#endif - { - /* no resumes until devices finish suspending */ - isp1362_hcd->next_statechange = jiffies + msecs_to_jiffies(5); - } -done: - if (status == 0) { - hcd->state = HC_STATE_SUSPENDED; - DBG(0, "%s: HCD suspended: %08x\n", __func__, - isp1362_read_reg32(isp1362_hcd, HCCONTROL)); - } - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - return status; -} - -static int isp1362_bus_resume(struct usb_hcd *hcd) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - u32 port; - unsigned long flags; - int status = -EINPROGRESS; - - if (time_before(jiffies, isp1362_hcd->next_statechange)) - msleep(5); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_hcd->hc_control = isp1362_read_reg32(isp1362_hcd, HCCONTROL); - pr_info("%s: HCCONTROL: %08x\n", __func__, isp1362_hcd->hc_control); - if (hcd->state == HC_STATE_RESUMING) { - pr_warn("%s: duplicate resume\n", __func__); - status = 0; - } else - switch (isp1362_hcd->hc_control & OHCI_CTRL_HCFS) { - case OHCI_USB_SUSPEND: - DBG(0, "%s: resume root hub\n", __func__); - isp1362_hcd->hc_control &= ~OHCI_CTRL_HCFS; - isp1362_hcd->hc_control |= OHCI_USB_RESUME; - isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control); - break; - case OHCI_USB_RESUME: - /* HCFS changes sometime after INTR_RD */ - DBG(0, "%s: remote wakeup\n", __func__); - break; - case OHCI_USB_OPER: - DBG(0, "%s: odd resume\n", __func__); - status = 0; - hcd->self.root_hub->dev.power.power_state = PMSG_ON; - break; - default: /* RESET, we lost power */ - DBG(0, "%s: root hub hardware reset\n", __func__); - status = -EBUSY; - } - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (status == -EBUSY) { - DBG(0, "%s: Restarting HC\n", __func__); - isp1362_hc_stop(hcd); - return isp1362_hc_start(hcd); - } - if (status != -EINPROGRESS) - return status; - spin_lock_irqsave(&isp1362_hcd->lock, flags); - port = isp1362_read_reg32(isp1362_hcd, HCRHDESCA) & RH_A_NDP; - while (port--) { - u32 stat = isp1362_read_reg32(isp1362_hcd, HCRHPORT1 + port); - - /* force global, not selective, resume */ - if (!(stat & RH_PS_PSS)) { - DBG(0, "%s: Not Resuming RH port %d\n", __func__, port); - continue; - } - DBG(0, "%s: Resuming RH port %d\n", __func__, port); - isp1362_write_reg32(isp1362_hcd, HCRHPORT1 + port, RH_PS_POCI); - } - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - /* Some controllers (lucent) need extra-long delays */ - hcd->state = HC_STATE_RESUMING; - mdelay(20 /* usb 11.5.1.10 */ + 15); - - isp1362_hcd->hc_control = OHCI_USB_OPER; - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_show_reg(isp1362_hcd, HCCONTROL); - isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - /* TRSMRCY */ - msleep(10); - - /* keep it alive for ~5x suspend + resume costs */ - isp1362_hcd->next_statechange = jiffies + msecs_to_jiffies(250); - - hcd->self.root_hub->dev.power.power_state = PMSG_ON; - hcd->state = HC_STATE_RUNNING; - return 0; -} -#else -#define isp1362_bus_suspend NULL -#define isp1362_bus_resume NULL -#endif - -/*-------------------------------------------------------------------------*/ - -static void dump_irq(struct seq_file *s, char *label, u16 mask) -{ - seq_printf(s, "%-15s %04x%s%s%s%s%s%s\n", label, mask, - mask & HCuPINT_CLKRDY ? " clkrdy" : "", - mask & HCuPINT_SUSP ? " susp" : "", - mask & HCuPINT_OPR ? " opr" : "", - mask & HCuPINT_EOT ? " eot" : "", - mask & HCuPINT_ATL ? " atl" : "", - mask & HCuPINT_SOF ? " sof" : ""); -} - -static void dump_int(struct seq_file *s, char *label, u32 mask) -{ - seq_printf(s, "%-15s %08x%s%s%s%s%s%s%s\n", label, mask, - mask & OHCI_INTR_MIE ? " MIE" : "", - mask & OHCI_INTR_RHSC ? " rhsc" : "", - mask & OHCI_INTR_FNO ? " fno" : "", - mask & OHCI_INTR_UE ? " ue" : "", - mask & OHCI_INTR_RD ? " rd" : "", - mask & OHCI_INTR_SF ? " sof" : "", - mask & OHCI_INTR_SO ? " so" : ""); -} - -static void dump_ctrl(struct seq_file *s, char *label, u32 mask) -{ - seq_printf(s, "%-15s %08x%s%s%s\n", label, mask, - mask & OHCI_CTRL_RWC ? " rwc" : "", - mask & OHCI_CTRL_RWE ? " rwe" : "", - ({ - char *hcfs; - switch (mask & OHCI_CTRL_HCFS) { - case OHCI_USB_OPER: - hcfs = " oper"; - break; - case OHCI_USB_RESET: - hcfs = " reset"; - break; - case OHCI_USB_RESUME: - hcfs = " resume"; - break; - case OHCI_USB_SUSPEND: - hcfs = " suspend"; - break; - default: - hcfs = " ?"; - } - hcfs; - })); -} - -static void dump_regs(struct seq_file *s, struct isp1362_hcd *isp1362_hcd) -{ - seq_printf(s, "HCREVISION [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCREVISION), - isp1362_read_reg32(isp1362_hcd, HCREVISION)); - seq_printf(s, "HCCONTROL [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCCONTROL), - isp1362_read_reg32(isp1362_hcd, HCCONTROL)); - seq_printf(s, "HCCMDSTAT [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCCMDSTAT), - isp1362_read_reg32(isp1362_hcd, HCCMDSTAT)); - seq_printf(s, "HCINTSTAT [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTSTAT), - isp1362_read_reg32(isp1362_hcd, HCINTSTAT)); - seq_printf(s, "HCINTENB [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTENB), - isp1362_read_reg32(isp1362_hcd, HCINTENB)); - seq_printf(s, "HCFMINTVL [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMINTVL), - isp1362_read_reg32(isp1362_hcd, HCFMINTVL)); - seq_printf(s, "HCFMREM [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMREM), - isp1362_read_reg32(isp1362_hcd, HCFMREM)); - seq_printf(s, "HCFMNUM [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCFMNUM), - isp1362_read_reg32(isp1362_hcd, HCFMNUM)); - seq_printf(s, "HCLSTHRESH [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCLSTHRESH), - isp1362_read_reg32(isp1362_hcd, HCLSTHRESH)); - seq_printf(s, "HCRHDESCA [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHDESCA), - isp1362_read_reg32(isp1362_hcd, HCRHDESCA)); - seq_printf(s, "HCRHDESCB [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHDESCB), - isp1362_read_reg32(isp1362_hcd, HCRHDESCB)); - seq_printf(s, "HCRHSTATUS [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHSTATUS), - isp1362_read_reg32(isp1362_hcd, HCRHSTATUS)); - seq_printf(s, "HCRHPORT1 [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHPORT1), - isp1362_read_reg32(isp1362_hcd, HCRHPORT1)); - seq_printf(s, "HCRHPORT2 [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCRHPORT2), - isp1362_read_reg32(isp1362_hcd, HCRHPORT2)); - seq_printf(s, "\n"); - seq_printf(s, "HCHWCFG [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCHWCFG), - isp1362_read_reg16(isp1362_hcd, HCHWCFG)); - seq_printf(s, "HCDMACFG [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCDMACFG), - isp1362_read_reg16(isp1362_hcd, HCDMACFG)); - seq_printf(s, "HCXFERCTR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCXFERCTR), - isp1362_read_reg16(isp1362_hcd, HCXFERCTR)); - seq_printf(s, "HCuPINT [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCuPINT), - isp1362_read_reg16(isp1362_hcd, HCuPINT)); - seq_printf(s, "HCuPINTENB [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCuPINTENB), - isp1362_read_reg16(isp1362_hcd, HCuPINTENB)); - seq_printf(s, "HCCHIPID [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCCHIPID), - isp1362_read_reg16(isp1362_hcd, HCCHIPID)); - seq_printf(s, "HCSCRATCH [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCSCRATCH), - isp1362_read_reg16(isp1362_hcd, HCSCRATCH)); - seq_printf(s, "HCBUFSTAT [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCBUFSTAT), - isp1362_read_reg16(isp1362_hcd, HCBUFSTAT)); - seq_printf(s, "HCDIRADDR [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCDIRADDR), - isp1362_read_reg32(isp1362_hcd, HCDIRADDR)); -#if 0 - seq_printf(s, "HCDIRDATA [%02x] %04x\n", ISP1362_REG_NO(HCDIRDATA), - isp1362_read_reg16(isp1362_hcd, HCDIRDATA)); -#endif - seq_printf(s, "HCISTLBUFSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCISTLBUFSZ), - isp1362_read_reg16(isp1362_hcd, HCISTLBUFSZ)); - seq_printf(s, "HCISTLRATE [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCISTLRATE), - isp1362_read_reg16(isp1362_hcd, HCISTLRATE)); - seq_printf(s, "\n"); - seq_printf(s, "HCINTLBUFSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLBUFSZ), - isp1362_read_reg16(isp1362_hcd, HCINTLBUFSZ)); - seq_printf(s, "HCINTLBLKSZ[%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLBLKSZ), - isp1362_read_reg16(isp1362_hcd, HCINTLBLKSZ)); - seq_printf(s, "HCINTLDONE [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLDONE), - isp1362_read_reg32(isp1362_hcd, HCINTLDONE)); - seq_printf(s, "HCINTLSKIP [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLSKIP), - isp1362_read_reg32(isp1362_hcd, HCINTLSKIP)); - seq_printf(s, "HCINTLLAST [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLLAST), - isp1362_read_reg32(isp1362_hcd, HCINTLLAST)); - seq_printf(s, "HCINTLCURR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCINTLCURR), - isp1362_read_reg16(isp1362_hcd, HCINTLCURR)); - seq_printf(s, "\n"); - seq_printf(s, "HCATLBUFSZ [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLBUFSZ), - isp1362_read_reg16(isp1362_hcd, HCATLBUFSZ)); - seq_printf(s, "HCATLBLKSZ [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLBLKSZ), - isp1362_read_reg16(isp1362_hcd, HCATLBLKSZ)); -#if 0 - seq_printf(s, "HCATLDONE [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDONE), - isp1362_read_reg32(isp1362_hcd, HCATLDONE)); -#endif - seq_printf(s, "HCATLSKIP [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLSKIP), - isp1362_read_reg32(isp1362_hcd, HCATLSKIP)); - seq_printf(s, "HCATLLAST [%02x] %08x\n", ISP1362_REG_NO(ISP1362_REG_HCATLLAST), - isp1362_read_reg32(isp1362_hcd, HCATLLAST)); - seq_printf(s, "HCATLCURR [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLCURR), - isp1362_read_reg16(isp1362_hcd, HCATLCURR)); - seq_printf(s, "\n"); - seq_printf(s, "HCATLDTC [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDTC), - isp1362_read_reg16(isp1362_hcd, HCATLDTC)); - seq_printf(s, "HCATLDTCTO [%02x] %04x\n", ISP1362_REG_NO(ISP1362_REG_HCATLDTCTO), - isp1362_read_reg16(isp1362_hcd, HCATLDTCTO)); -} - -static int isp1362_show(struct seq_file *s, void *unused) -{ - struct isp1362_hcd *isp1362_hcd = s->private; - struct isp1362_ep *ep; - int i; - - seq_printf(s, "%s\n%s version %s\n", - isp1362_hcd_to_hcd(isp1362_hcd)->product_desc, hcd_name, DRIVER_VERSION); - - /* collect statistics to help estimate potential win for - * DMA engines that care about alignment (PXA) - */ - seq_printf(s, "alignment: 16b/%ld 8b/%ld 4b/%ld 2b/%ld 1b/%ld\n", - isp1362_hcd->stat16, isp1362_hcd->stat8, isp1362_hcd->stat4, - isp1362_hcd->stat2, isp1362_hcd->stat1); - seq_printf(s, "max # ptds in ATL fifo: %d\n", isp1362_hcd->atl_queue.stat_maxptds); - seq_printf(s, "max # ptds in INTL fifo: %d\n", isp1362_hcd->intl_queue.stat_maxptds); - seq_printf(s, "max # ptds in ISTL fifo: %d\n", - max(isp1362_hcd->istl_queue[0] .stat_maxptds, - isp1362_hcd->istl_queue[1] .stat_maxptds)); - - /* FIXME: don't show the following in suspended state */ - spin_lock_irq(&isp1362_hcd->lock); - - dump_irq(s, "hc_irq_enable", isp1362_read_reg16(isp1362_hcd, HCuPINTENB)); - dump_irq(s, "hc_irq_status", isp1362_read_reg16(isp1362_hcd, HCuPINT)); - dump_int(s, "ohci_int_enable", isp1362_read_reg32(isp1362_hcd, HCINTENB)); - dump_int(s, "ohci_int_status", isp1362_read_reg32(isp1362_hcd, HCINTSTAT)); - dump_ctrl(s, "ohci_control", isp1362_read_reg32(isp1362_hcd, HCCONTROL)); - - for (i = 0; i < NUM_ISP1362_IRQS; i++) - if (isp1362_hcd->irq_stat[i]) - seq_printf(s, "%-15s: %d\n", - ISP1362_INT_NAME(i), isp1362_hcd->irq_stat[i]); - - dump_regs(s, isp1362_hcd); - list_for_each_entry(ep, &isp1362_hcd->async, schedule) { - struct urb *urb; - - seq_printf(s, "%p, ep%d%s, maxpacket %d:\n", ep, ep->epnum, - ({ - char *s; - switch (ep->nextpid) { - case USB_PID_IN: - s = "in"; - break; - case USB_PID_OUT: - s = "out"; - break; - case USB_PID_SETUP: - s = "setup"; - break; - case USB_PID_ACK: - s = "status"; - break; - default: - s = "?"; - break; - } - s;}), ep->maxpacket) ; - list_for_each_entry(urb, &ep->hep->urb_list, urb_list) { - seq_printf(s, " urb%p, %d/%d\n", urb, - urb->actual_length, - urb->transfer_buffer_length); - } - } - if (!list_empty(&isp1362_hcd->async)) - seq_printf(s, "\n"); - dump_ptd_queue(&isp1362_hcd->atl_queue); - - seq_printf(s, "periodic size= %d\n", PERIODIC_SIZE); - - list_for_each_entry(ep, &isp1362_hcd->periodic, schedule) { - seq_printf(s, "branch:%2d load:%3d PTD[%d] $%04x:\n", ep->branch, - isp1362_hcd->load[ep->branch], ep->ptd_index, ep->ptd_offset); - - seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", - ep->interval, ep, - (ep->udev->speed == USB_SPEED_FULL) ? "" : "ls ", - ep->udev->devnum, ep->epnum, - (ep->epnum == 0) ? "" : - ((ep->nextpid == USB_PID_IN) ? - "in" : "out"), ep->maxpacket); - } - dump_ptd_queue(&isp1362_hcd->intl_queue); - - seq_printf(s, "ISO:\n"); - - list_for_each_entry(ep, &isp1362_hcd->isoc, schedule) { - seq_printf(s, " %d/%p (%sdev%d ep%d%s max %d)\n", - ep->interval, ep, - (ep->udev->speed == USB_SPEED_FULL) ? "" : "ls ", - ep->udev->devnum, ep->epnum, - (ep->epnum == 0) ? "" : - ((ep->nextpid == USB_PID_IN) ? - "in" : "out"), ep->maxpacket); - } - - spin_unlock_irq(&isp1362_hcd->lock); - seq_printf(s, "\n"); - - return 0; -} -DEFINE_SHOW_ATTRIBUTE(isp1362); - -/* expect just one isp1362_hcd per system */ -static void create_debug_file(struct isp1362_hcd *isp1362_hcd) -{ - debugfs_create_file("isp1362", S_IRUGO, usb_debug_root, isp1362_hcd, - &isp1362_fops); -} - -static void remove_debug_file(struct isp1362_hcd *isp1362_hcd) -{ - debugfs_lookup_and_remove("isp1362", usb_debug_root); -} - -/*-------------------------------------------------------------------------*/ - -static void __isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) -{ - int tmp = 20; - - isp1362_write_reg16(isp1362_hcd, HCSWRES, HCSWRES_MAGIC); - isp1362_write_reg32(isp1362_hcd, HCCMDSTAT, OHCI_HCR); - while (--tmp) { - mdelay(1); - if (!(isp1362_read_reg32(isp1362_hcd, HCCMDSTAT) & OHCI_HCR)) - break; - } - if (!tmp) - pr_err("Software reset timeout\n"); -} - -static void isp1362_sw_reset(struct isp1362_hcd *isp1362_hcd) -{ - unsigned long flags; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - __isp1362_sw_reset(isp1362_hcd); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); -} - -static int isp1362_mem_config(struct usb_hcd *hcd) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - u32 total; - u16 istl_size = ISP1362_ISTL_BUFSIZE; - u16 intl_blksize = ISP1362_INTL_BLKSIZE + PTD_HEADER_SIZE; - u16 intl_size = ISP1362_INTL_BUFFERS * intl_blksize; - u16 atl_blksize = ISP1362_ATL_BLKSIZE + PTD_HEADER_SIZE; - u16 atl_buffers = (ISP1362_BUF_SIZE - (istl_size + intl_size)) / atl_blksize; - u16 atl_size; - int i; - - WARN_ON(istl_size & 3); - WARN_ON(atl_blksize & 3); - WARN_ON(intl_blksize & 3); - WARN_ON(atl_blksize < PTD_HEADER_SIZE); - WARN_ON(intl_blksize < PTD_HEADER_SIZE); - - BUG_ON((unsigned)ISP1362_INTL_BUFFERS > 32); - if (atl_buffers > 32) - atl_buffers = 32; - atl_size = atl_buffers * atl_blksize; - total = atl_size + intl_size + istl_size; - dev_info(hcd->self.controller, "ISP1362 Memory usage:\n"); - dev_info(hcd->self.controller, " ISTL: 2 * %4d: %4d @ $%04x:$%04x\n", - istl_size / 2, istl_size, 0, istl_size / 2); - dev_info(hcd->self.controller, " INTL: %4d * (%3zu+8): %4d @ $%04x\n", - ISP1362_INTL_BUFFERS, intl_blksize - PTD_HEADER_SIZE, - intl_size, istl_size); - dev_info(hcd->self.controller, " ATL : %4d * (%3zu+8): %4d @ $%04x\n", - atl_buffers, atl_blksize - PTD_HEADER_SIZE, - atl_size, istl_size + intl_size); - dev_info(hcd->self.controller, " USED/FREE: %4d %4d\n", total, - ISP1362_BUF_SIZE - total); - - if (total > ISP1362_BUF_SIZE) { - dev_err(hcd->self.controller, "%s: Memory requested: %d, available %d\n", - __func__, total, ISP1362_BUF_SIZE); - return -ENOMEM; - } - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - for (i = 0; i < 2; i++) { - isp1362_hcd->istl_queue[i].buf_start = i * istl_size / 2, - isp1362_hcd->istl_queue[i].buf_size = istl_size / 2; - isp1362_hcd->istl_queue[i].blk_size = 4; - INIT_LIST_HEAD(&isp1362_hcd->istl_queue[i].active); - snprintf(isp1362_hcd->istl_queue[i].name, - sizeof(isp1362_hcd->istl_queue[i].name), "ISTL%d", i); - DBG(3, "%s: %5s buf $%04x %d\n", __func__, - isp1362_hcd->istl_queue[i].name, - isp1362_hcd->istl_queue[i].buf_start, - isp1362_hcd->istl_queue[i].buf_size); - } - isp1362_write_reg16(isp1362_hcd, HCISTLBUFSZ, istl_size / 2); - - isp1362_hcd->intl_queue.buf_start = istl_size; - isp1362_hcd->intl_queue.buf_size = intl_size; - isp1362_hcd->intl_queue.buf_count = ISP1362_INTL_BUFFERS; - isp1362_hcd->intl_queue.blk_size = intl_blksize; - isp1362_hcd->intl_queue.buf_avail = isp1362_hcd->intl_queue.buf_count; - isp1362_hcd->intl_queue.skip_map = ~0; - INIT_LIST_HEAD(&isp1362_hcd->intl_queue.active); - - isp1362_write_reg16(isp1362_hcd, HCINTLBUFSZ, - isp1362_hcd->intl_queue.buf_size); - isp1362_write_reg16(isp1362_hcd, HCINTLBLKSZ, - isp1362_hcd->intl_queue.blk_size - PTD_HEADER_SIZE); - isp1362_write_reg32(isp1362_hcd, HCINTLSKIP, ~0); - isp1362_write_reg32(isp1362_hcd, HCINTLLAST, - 1 << (ISP1362_INTL_BUFFERS - 1)); - - isp1362_hcd->atl_queue.buf_start = istl_size + intl_size; - isp1362_hcd->atl_queue.buf_size = atl_size; - isp1362_hcd->atl_queue.buf_count = atl_buffers; - isp1362_hcd->atl_queue.blk_size = atl_blksize; - isp1362_hcd->atl_queue.buf_avail = isp1362_hcd->atl_queue.buf_count; - isp1362_hcd->atl_queue.skip_map = ~0; - INIT_LIST_HEAD(&isp1362_hcd->atl_queue.active); - - isp1362_write_reg16(isp1362_hcd, HCATLBUFSZ, - isp1362_hcd->atl_queue.buf_size); - isp1362_write_reg16(isp1362_hcd, HCATLBLKSZ, - isp1362_hcd->atl_queue.blk_size - PTD_HEADER_SIZE); - isp1362_write_reg32(isp1362_hcd, HCATLSKIP, ~0); - isp1362_write_reg32(isp1362_hcd, HCATLLAST, - 1 << (atl_buffers - 1)); - - snprintf(isp1362_hcd->atl_queue.name, - sizeof(isp1362_hcd->atl_queue.name), "ATL"); - snprintf(isp1362_hcd->intl_queue.name, - sizeof(isp1362_hcd->intl_queue.name), "INTL"); - DBG(3, "%s: %5s buf $%04x %2d * %4d = %4d\n", __func__, - isp1362_hcd->intl_queue.name, - isp1362_hcd->intl_queue.buf_start, - ISP1362_INTL_BUFFERS, isp1362_hcd->intl_queue.blk_size, - isp1362_hcd->intl_queue.buf_size); - DBG(3, "%s: %5s buf $%04x %2d * %4d = %4d\n", __func__, - isp1362_hcd->atl_queue.name, - isp1362_hcd->atl_queue.buf_start, - atl_buffers, isp1362_hcd->atl_queue.blk_size, - isp1362_hcd->atl_queue.buf_size); - - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - return 0; -} - -static int isp1362_hc_reset(struct usb_hcd *hcd) -{ - int ret = 0; - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long t; - unsigned long timeout = 100; - unsigned long flags; - int clkrdy = 0; - - pr_debug("%s:\n", __func__); - - if (isp1362_hcd->board && isp1362_hcd->board->reset) { - isp1362_hcd->board->reset(hcd->self.controller, 1); - msleep(20); - if (isp1362_hcd->board->clock) - isp1362_hcd->board->clock(hcd->self.controller, 1); - isp1362_hcd->board->reset(hcd->self.controller, 0); - } else - isp1362_sw_reset(isp1362_hcd); - - /* chip has been reset. First we need to see a clock */ - t = jiffies + msecs_to_jiffies(timeout); - while (!clkrdy && time_before_eq(jiffies, t)) { - spin_lock_irqsave(&isp1362_hcd->lock, flags); - clkrdy = isp1362_read_reg16(isp1362_hcd, HCuPINT) & HCuPINT_CLKRDY; - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (!clkrdy) - msleep(4); - } - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_CLKRDY); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (!clkrdy) { - pr_err("Clock not ready after %lums\n", timeout); - ret = -ENODEV; - } - return ret; -} - -static void isp1362_hc_stop(struct usb_hcd *hcd) -{ - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - u32 tmp; - - pr_debug("%s:\n", __func__); - - timer_delete_sync(&hcd->rh_timer); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0); - - /* Switch off power for all ports */ - tmp = isp1362_read_reg32(isp1362_hcd, HCRHDESCA); - tmp &= ~(RH_A_NPS | RH_A_PSM); - isp1362_write_reg32(isp1362_hcd, HCRHDESCA, tmp); - isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPS); - - /* Reset the chip */ - if (isp1362_hcd->board && isp1362_hcd->board->reset) - isp1362_hcd->board->reset(hcd->self.controller, 1); - else - __isp1362_sw_reset(isp1362_hcd); - - if (isp1362_hcd->board && isp1362_hcd->board->clock) - isp1362_hcd->board->clock(hcd->self.controller, 0); - - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); -} - -#ifdef CHIP_BUFFER_TEST -static int isp1362_chip_test(struct isp1362_hcd *isp1362_hcd) -{ - int ret = 0; - u16 *ref; - unsigned long flags; - - ref = kmalloc(2 * ISP1362_BUF_SIZE, GFP_KERNEL); - if (ref) { - int offset; - u16 *tst = &ref[ISP1362_BUF_SIZE / 2]; - - for (offset = 0; offset < ISP1362_BUF_SIZE / 2; offset++) { - ref[offset] = ~offset; - tst[offset] = offset; - } - - for (offset = 0; offset < 4; offset++) { - int j; - - for (j = 0; j < 8; j++) { - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_buffer(isp1362_hcd, (u8 *)ref + offset, 0, j); - isp1362_read_buffer(isp1362_hcd, (u8 *)tst + offset, 0, j); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - if (memcmp(ref, tst, j)) { - ret = -ENODEV; - pr_err("%s: memory check with %d byte offset %d failed\n", - __func__, j, offset); - dump_data((u8 *)ref + offset, j); - dump_data((u8 *)tst + offset, j); - } - } - } - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_buffer(isp1362_hcd, ref, 0, ISP1362_BUF_SIZE); - isp1362_read_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - if (memcmp(ref, tst, ISP1362_BUF_SIZE)) { - ret = -ENODEV; - pr_err("%s: memory check failed\n", __func__); - dump_data((u8 *)tst, ISP1362_BUF_SIZE / 2); - } - - for (offset = 0; offset < 256; offset++) { - int test_size = 0; - - yield(); - - memset(tst, 0, ISP1362_BUF_SIZE); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE); - isp1362_read_buffer(isp1362_hcd, tst, 0, ISP1362_BUF_SIZE); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (memcmp(tst, tst + (ISP1362_BUF_SIZE / (2 * sizeof(*tst))), - ISP1362_BUF_SIZE / 2)) { - pr_err("%s: Failed to clear buffer\n", __func__); - dump_data((u8 *)tst, ISP1362_BUF_SIZE); - break; - } - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_buffer(isp1362_hcd, ref, offset * 2, PTD_HEADER_SIZE); - isp1362_write_buffer(isp1362_hcd, ref + PTD_HEADER_SIZE / sizeof(*ref), - offset * 2 + PTD_HEADER_SIZE, test_size); - isp1362_read_buffer(isp1362_hcd, tst, offset * 2, - PTD_HEADER_SIZE + test_size); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (memcmp(ref, tst, PTD_HEADER_SIZE + test_size)) { - dump_data(((u8 *)ref) + offset, PTD_HEADER_SIZE + test_size); - dump_data((u8 *)tst, PTD_HEADER_SIZE + test_size); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_read_buffer(isp1362_hcd, tst, offset * 2, - PTD_HEADER_SIZE + test_size); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - if (memcmp(ref, tst, PTD_HEADER_SIZE + test_size)) { - ret = -ENODEV; - pr_err("%s: memory check with offset %02x failed\n", - __func__, offset); - break; - } - pr_warn("%s: memory check with offset %02x ok after second read\n", - __func__, offset); - } - } - kfree(ref); - } - return ret; -} -#endif - -static int isp1362_hc_start(struct usb_hcd *hcd) -{ - int ret; - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - struct isp1362_platform_data *board = isp1362_hcd->board; - u16 hwcfg; - u16 chipid; - unsigned long flags; - - pr_debug("%s:\n", __func__); - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - chipid = isp1362_read_reg16(isp1362_hcd, HCCHIPID); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - if ((chipid & HCCHIPID_MASK) != HCCHIPID_MAGIC) { - pr_err("%s: Invalid chip ID %04x\n", __func__, chipid); - return -ENODEV; - } - -#ifdef CHIP_BUFFER_TEST - ret = isp1362_chip_test(isp1362_hcd); - if (ret) - return -ENODEV; -#endif - spin_lock_irqsave(&isp1362_hcd->lock, flags); - /* clear interrupt status and disable all interrupt sources */ - isp1362_write_reg16(isp1362_hcd, HCuPINT, 0xff); - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, 0); - - /* HW conf */ - hwcfg = HCHWCFG_INT_ENABLE | HCHWCFG_DBWIDTH(1); - if (board->sel15Kres) - hwcfg |= HCHWCFG_PULLDOWN_DS2 | - ((MAX_ROOT_PORTS > 1) ? HCHWCFG_PULLDOWN_DS1 : 0); - if (board->clknotstop) - hwcfg |= HCHWCFG_CLKNOTSTOP; - if (board->oc_enable) - hwcfg |= HCHWCFG_ANALOG_OC; - if (board->int_act_high) - hwcfg |= HCHWCFG_INT_POL; - if (board->int_edge_triggered) - hwcfg |= HCHWCFG_INT_TRIGGER; - if (board->dreq_act_high) - hwcfg |= HCHWCFG_DREQ_POL; - if (board->dack_act_high) - hwcfg |= HCHWCFG_DACK_POL; - isp1362_write_reg16(isp1362_hcd, HCHWCFG, hwcfg); - isp1362_show_reg(isp1362_hcd, HCHWCFG); - isp1362_write_reg16(isp1362_hcd, HCDMACFG, 0); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - ret = isp1362_mem_config(hcd); - if (ret) - return ret; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - - /* Root hub conf */ - isp1362_hcd->rhdesca = 0; - if (board->no_power_switching) - isp1362_hcd->rhdesca |= RH_A_NPS; - if (board->power_switching_mode) - isp1362_hcd->rhdesca |= RH_A_PSM; - if (board->potpg) - isp1362_hcd->rhdesca |= (board->potpg << 24) & RH_A_POTPGT; - else - isp1362_hcd->rhdesca |= (25 << 24) & RH_A_POTPGT; - - isp1362_write_reg32(isp1362_hcd, HCRHDESCA, isp1362_hcd->rhdesca & ~RH_A_OCPM); - isp1362_write_reg32(isp1362_hcd, HCRHDESCA, isp1362_hcd->rhdesca | RH_A_OCPM); - isp1362_hcd->rhdesca = isp1362_read_reg32(isp1362_hcd, HCRHDESCA); - - isp1362_hcd->rhdescb = RH_B_PPCM; - isp1362_write_reg32(isp1362_hcd, HCRHDESCB, isp1362_hcd->rhdescb); - isp1362_hcd->rhdescb = isp1362_read_reg32(isp1362_hcd, HCRHDESCB); - - isp1362_read_reg32(isp1362_hcd, HCFMINTVL); - isp1362_write_reg32(isp1362_hcd, HCFMINTVL, (FSMP(FI) << 16) | FI); - isp1362_write_reg32(isp1362_hcd, HCLSTHRESH, LSTHRESH); - - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - isp1362_hcd->hc_control = OHCI_USB_OPER; - hcd->state = HC_STATE_RUNNING; - - spin_lock_irqsave(&isp1362_hcd->lock, flags); - /* Set up interrupts */ - isp1362_hcd->intenb = OHCI_INTR_MIE | OHCI_INTR_RHSC | OHCI_INTR_UE; - isp1362_hcd->intenb |= OHCI_INTR_RD; - isp1362_hcd->irqenb = HCuPINT_OPR | HCuPINT_SUSP; - isp1362_write_reg32(isp1362_hcd, HCINTENB, isp1362_hcd->intenb); - isp1362_write_reg16(isp1362_hcd, HCuPINTENB, isp1362_hcd->irqenb); - - /* Go operational */ - isp1362_write_reg32(isp1362_hcd, HCCONTROL, isp1362_hcd->hc_control); - /* enable global power */ - isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPSC | RH_HS_DRWE); - - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static const struct hc_driver isp1362_hc_driver = { - .description = hcd_name, - .product_desc = "ISP1362 Host Controller", - .hcd_priv_size = sizeof(struct isp1362_hcd), - - .irq = isp1362_irq, - .flags = HCD_USB11 | HCD_MEMORY, - - .reset = isp1362_hc_reset, - .start = isp1362_hc_start, - .stop = isp1362_hc_stop, - - .urb_enqueue = isp1362_urb_enqueue, - .urb_dequeue = isp1362_urb_dequeue, - .endpoint_disable = isp1362_endpoint_disable, - - .get_frame_number = isp1362_get_frame, - - .hub_status_data = isp1362_hub_status_data, - .hub_control = isp1362_hub_control, - .bus_suspend = isp1362_bus_suspend, - .bus_resume = isp1362_bus_resume, -}; - -/*-------------------------------------------------------------------------*/ - -static void isp1362_remove(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - - remove_debug_file(isp1362_hcd); - DBG(0, "%s: Removing HCD\n", __func__); - usb_remove_hcd(hcd); - DBG(0, "%s: put_hcd\n", __func__); - usb_put_hcd(hcd); - DBG(0, "%s: Done\n", __func__); -} - -static int isp1362_probe(struct platform_device *pdev) -{ - struct usb_hcd *hcd; - struct isp1362_hcd *isp1362_hcd; - struct resource *data, *irq_res; - void __iomem *addr_reg; - void __iomem *data_reg; - int irq; - int retval = 0; - unsigned int irq_flags = 0; - - if (usb_disabled()) - return -ENODEV; - - /* basic sanity checks first. board-specific init logic should - * have initialized this the three resources and probably board - * specific platform_data. we don't probe for IRQs, and do only - * minimal sanity checking. - */ - if (pdev->num_resources < 3) - return -ENODEV; - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) - return -ENODEV; - - irq = irq_res->start; - - addr_reg = devm_platform_ioremap_resource(pdev, 1); - if (IS_ERR(addr_reg)) - return PTR_ERR(addr_reg); - - data_reg = devm_platform_get_and_ioremap_resource(pdev, 0, &data); - if (IS_ERR(data_reg)) - return PTR_ERR(data_reg); - - /* allocate and initialize hcd */ - hcd = usb_create_hcd(&isp1362_hc_driver, &pdev->dev, dev_name(&pdev->dev)); - if (!hcd) - return -ENOMEM; - - hcd->rsrc_start = data->start; - isp1362_hcd = hcd_to_isp1362_hcd(hcd); - isp1362_hcd->data_reg = data_reg; - isp1362_hcd->addr_reg = addr_reg; - - isp1362_hcd->next_statechange = jiffies; - spin_lock_init(&isp1362_hcd->lock); - INIT_LIST_HEAD(&isp1362_hcd->async); - INIT_LIST_HEAD(&isp1362_hcd->periodic); - INIT_LIST_HEAD(&isp1362_hcd->isoc); - INIT_LIST_HEAD(&isp1362_hcd->remove_list); - isp1362_hcd->board = dev_get_platdata(&pdev->dev); -#if USE_PLATFORM_DELAY - if (!isp1362_hcd->board->delay) { - dev_err(hcd->self.controller, "No platform delay function given\n"); - retval = -ENODEV; - goto err; - } -#endif - - if (irq_res->flags & IORESOURCE_IRQ_HIGHEDGE) - irq_flags |= IRQF_TRIGGER_RISING; - if (irq_res->flags & IORESOURCE_IRQ_LOWEDGE) - irq_flags |= IRQF_TRIGGER_FALLING; - if (irq_res->flags & IORESOURCE_IRQ_HIGHLEVEL) - irq_flags |= IRQF_TRIGGER_HIGH; - if (irq_res->flags & IORESOURCE_IRQ_LOWLEVEL) - irq_flags |= IRQF_TRIGGER_LOW; - - retval = usb_add_hcd(hcd, irq, irq_flags | IRQF_SHARED); - if (retval != 0) - goto err; - device_wakeup_enable(hcd->self.controller); - - dev_info(&pdev->dev, "%s, irq %d\n", hcd->product_desc, irq); - - create_debug_file(isp1362_hcd); - - return 0; - - err: - usb_put_hcd(hcd); - - return retval; -} - -#ifdef CONFIG_PM -static int isp1362_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - int retval = 0; - - DBG(0, "%s: Suspending device\n", __func__); - - if (state.event == PM_EVENT_FREEZE) { - DBG(0, "%s: Suspending root hub\n", __func__); - retval = isp1362_bus_suspend(hcd); - } else { - DBG(0, "%s: Suspending RH ports\n", __func__); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPS); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - } - if (retval == 0) - pdev->dev.power.power_state = state; - return retval; -} - -static int isp1362_resume(struct platform_device *pdev) -{ - struct usb_hcd *hcd = platform_get_drvdata(pdev); - struct isp1362_hcd *isp1362_hcd = hcd_to_isp1362_hcd(hcd); - unsigned long flags; - - DBG(0, "%s: Resuming\n", __func__); - - if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) { - DBG(0, "%s: Resume RH ports\n", __func__); - spin_lock_irqsave(&isp1362_hcd->lock, flags); - isp1362_write_reg32(isp1362_hcd, HCRHSTATUS, RH_HS_LPSC); - spin_unlock_irqrestore(&isp1362_hcd->lock, flags); - return 0; - } - - pdev->dev.power.power_state = PMSG_ON; - - return isp1362_bus_resume(isp1362_hcd_to_hcd(isp1362_hcd)); -} -#else -#define isp1362_suspend NULL -#define isp1362_resume NULL -#endif - -static struct platform_driver isp1362_driver = { - .probe = isp1362_probe, - .remove = isp1362_remove, - - .suspend = isp1362_suspend, - .resume = isp1362_resume, - .driver = { - .name = hcd_name, - }, -}; - -module_platform_driver(isp1362_driver); diff --git a/drivers/usb/host/isp1362.h b/drivers/usb/host/isp1362.h deleted file mode 100644 index 74ca4be24723..000000000000 --- a/drivers/usb/host/isp1362.h +++ /dev/null @@ -1,914 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * ISP1362 HCD (Host Controller Driver) for USB. - * - * COPYRIGHT (C) by L. Wassmann - */ - -/* ------------------------------------------------------------------------- */ - -#define MAX_ROOT_PORTS 2 - -#define USE_32BIT 0 - -/* These options are mutually exclusive */ -#define USE_PLATFORM_DELAY 0 -#define USE_NDELAY 0 - -#define DUMMY_DELAY_ACCESS do {} while (0) - -/* ------------------------------------------------------------------------- */ - -#define USB_RESET_WIDTH 50 -#define MAX_XFER_SIZE 1023 - -/* Buffer sizes */ -#define ISP1362_BUF_SIZE 4096 -#define ISP1362_ISTL_BUFSIZE 512 -#define ISP1362_INTL_BLKSIZE 64 -#define ISP1362_INTL_BUFFERS 16 -#define ISP1362_ATL_BLKSIZE 64 - -#define ISP1362_REG_WRITE_OFFSET 0x80 - -#define REG_WIDTH_16 0x000 -#define REG_WIDTH_32 0x100 -#define REG_WIDTH_MASK 0x100 -#define REG_NO_MASK 0x0ff - -#ifdef ISP1362_DEBUG -typedef const unsigned int isp1362_reg_t; - -#define REG_ACCESS_R 0x200 -#define REG_ACCESS_W 0x400 -#define REG_ACCESS_RW 0x600 -#define REG_ACCESS_MASK 0x600 - -#define ISP1362_REG_NO(r) ((r) & REG_NO_MASK) - -#define ISP1362_REG(name, addr, width, rw) \ -static isp1362_reg_t ISP1362_REG_##name = ((addr) | (width) | (rw)) - -#define REG_ACCESS_TEST(r) BUG_ON(((r) & ISP1362_REG_WRITE_OFFSET) && !((r) & REG_ACCESS_W)) -#define REG_WIDTH_TEST(r, w) BUG_ON(((r) & REG_WIDTH_MASK) != (w)) -#else -typedef const unsigned char isp1362_reg_t; -#define ISP1362_REG_NO(r) (r) - -#define ISP1362_REG(name, addr, width, rw) \ -static isp1362_reg_t __maybe_unused ISP1362_REG_##name = addr - -#define REG_ACCESS_TEST(r) do {} while (0) -#define REG_WIDTH_TEST(r, w) do {} while (0) -#endif - -/* OHCI compatible registers */ -/* - * Note: Some of the ISP1362 'OHCI' registers implement only - * a subset of the bits defined in the OHCI spec. - * - * Bitmasks for the individual bits of these registers are defined in "ohci.h" - */ -ISP1362_REG(HCREVISION, 0x00, REG_WIDTH_32, REG_ACCESS_R); -ISP1362_REG(HCCONTROL, 0x01, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCCMDSTAT, 0x02, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCINTSTAT, 0x03, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCINTENB, 0x04, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCINTDIS, 0x05, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCFMINTVL, 0x0d, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCFMREM, 0x0e, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCFMNUM, 0x0f, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCLSTHRESH, 0x11, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCRHDESCA, 0x12, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCRHDESCB, 0x13, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCRHSTATUS, 0x14, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCRHPORT1, 0x15, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCRHPORT2, 0x16, REG_WIDTH_32, REG_ACCESS_RW); - -/* Philips ISP1362 specific registers */ -ISP1362_REG(HCHWCFG, 0x20, REG_WIDTH_16, REG_ACCESS_RW); -#define HCHWCFG_DISABLE_SUSPEND (1 << 15) -#define HCHWCFG_GLOBAL_PWRDOWN (1 << 14) -#define HCHWCFG_PULLDOWN_DS2 (1 << 13) -#define HCHWCFG_PULLDOWN_DS1 (1 << 12) -#define HCHWCFG_CLKNOTSTOP (1 << 11) -#define HCHWCFG_ANALOG_OC (1 << 10) -#define HCHWCFG_ONEINT (1 << 9) -#define HCHWCFG_DACK_MODE (1 << 8) -#define HCHWCFG_ONEDMA (1 << 7) -#define HCHWCFG_DACK_POL (1 << 6) -#define HCHWCFG_DREQ_POL (1 << 5) -#define HCHWCFG_DBWIDTH_MASK (0x03 << 3) -#define HCHWCFG_DBWIDTH(n) (((n) << 3) & HCHWCFG_DBWIDTH_MASK) -#define HCHWCFG_INT_POL (1 << 2) -#define HCHWCFG_INT_TRIGGER (1 << 1) -#define HCHWCFG_INT_ENABLE (1 << 0) - -ISP1362_REG(HCDMACFG, 0x21, REG_WIDTH_16, REG_ACCESS_RW); -#define HCDMACFG_CTR_ENABLE (1 << 7) -#define HCDMACFG_BURST_LEN_MASK (0x03 << 5) -#define HCDMACFG_BURST_LEN(n) (((n) << 5) & HCDMACFG_BURST_LEN_MASK) -#define HCDMACFG_BURST_LEN_1 HCDMACFG_BURST_LEN(0) -#define HCDMACFG_BURST_LEN_4 HCDMACFG_BURST_LEN(1) -#define HCDMACFG_BURST_LEN_8 HCDMACFG_BURST_LEN(2) -#define HCDMACFG_DMA_ENABLE (1 << 4) -#define HCDMACFG_BUF_TYPE_MASK (0x07 << 1) -#define HCDMACFG_BUF_TYPE(n) (((n) << 1) & HCDMACFG_BUF_TYPE_MASK) -#define HCDMACFG_BUF_ISTL0 HCDMACFG_BUF_TYPE(0) -#define HCDMACFG_BUF_ISTL1 HCDMACFG_BUF_TYPE(1) -#define HCDMACFG_BUF_INTL HCDMACFG_BUF_TYPE(2) -#define HCDMACFG_BUF_ATL HCDMACFG_BUF_TYPE(3) -#define HCDMACFG_BUF_DIRECT HCDMACFG_BUF_TYPE(4) -#define HCDMACFG_DMA_RW_SELECT (1 << 0) - -ISP1362_REG(HCXFERCTR, 0x22, REG_WIDTH_16, REG_ACCESS_RW); - -ISP1362_REG(HCuPINT, 0x24, REG_WIDTH_16, REG_ACCESS_RW); -#define HCuPINT_SOF (1 << 0) -#define HCuPINT_ISTL0 (1 << 1) -#define HCuPINT_ISTL1 (1 << 2) -#define HCuPINT_EOT (1 << 3) -#define HCuPINT_OPR (1 << 4) -#define HCuPINT_SUSP (1 << 5) -#define HCuPINT_CLKRDY (1 << 6) -#define HCuPINT_INTL (1 << 7) -#define HCuPINT_ATL (1 << 8) -#define HCuPINT_OTG (1 << 9) - -ISP1362_REG(HCuPINTENB, 0x25, REG_WIDTH_16, REG_ACCESS_RW); -/* same bit definitions apply as for HCuPINT */ - -ISP1362_REG(HCCHIPID, 0x27, REG_WIDTH_16, REG_ACCESS_R); -#define HCCHIPID_MASK 0xff00 -#define HCCHIPID_MAGIC 0x3600 - -ISP1362_REG(HCSCRATCH, 0x28, REG_WIDTH_16, REG_ACCESS_RW); - -ISP1362_REG(HCSWRES, 0x29, REG_WIDTH_16, REG_ACCESS_W); -#define HCSWRES_MAGIC 0x00f6 - -ISP1362_REG(HCBUFSTAT, 0x2c, REG_WIDTH_16, REG_ACCESS_RW); -#define HCBUFSTAT_ISTL0_FULL (1 << 0) -#define HCBUFSTAT_ISTL1_FULL (1 << 1) -#define HCBUFSTAT_INTL_ACTIVE (1 << 2) -#define HCBUFSTAT_ATL_ACTIVE (1 << 3) -#define HCBUFSTAT_RESET_HWPP (1 << 4) -#define HCBUFSTAT_ISTL0_ACTIVE (1 << 5) -#define HCBUFSTAT_ISTL1_ACTIVE (1 << 6) -#define HCBUFSTAT_ISTL0_DONE (1 << 8) -#define HCBUFSTAT_ISTL1_DONE (1 << 9) -#define HCBUFSTAT_PAIRED_PTDPP (1 << 10) - -ISP1362_REG(HCDIRADDR, 0x32, REG_WIDTH_32, REG_ACCESS_RW); -#define HCDIRADDR_ADDR_MASK 0x0000ffff -#define HCDIRADDR_ADDR(n) (((n) << 0) & HCDIRADDR_ADDR_MASK) -#define HCDIRADDR_COUNT_MASK 0xffff0000 -#define HCDIRADDR_COUNT(n) (((n) << 16) & HCDIRADDR_COUNT_MASK) -ISP1362_REG(HCDIRDATA, 0x45, REG_WIDTH_16, REG_ACCESS_RW); - -ISP1362_REG(HCISTLBUFSZ, 0x30, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCISTL0PORT, 0x40, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCISTL1PORT, 0x42, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCISTLRATE, 0x47, REG_WIDTH_16, REG_ACCESS_RW); - -ISP1362_REG(HCINTLBUFSZ, 0x33, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCINTLPORT, 0x43, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCINTLBLKSZ, 0x53, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCINTLDONE, 0x17, REG_WIDTH_32, REG_ACCESS_R); -ISP1362_REG(HCINTLSKIP, 0x18, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCINTLLAST, 0x19, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCINTLCURR, 0x1a, REG_WIDTH_16, REG_ACCESS_R); - -ISP1362_REG(HCATLBUFSZ, 0x34, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCATLPORT, 0x44, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCATLBLKSZ, 0x54, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCATLDONE, 0x1b, REG_WIDTH_32, REG_ACCESS_R); -ISP1362_REG(HCATLSKIP, 0x1c, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCATLLAST, 0x1d, REG_WIDTH_32, REG_ACCESS_RW); -ISP1362_REG(HCATLCURR, 0x1e, REG_WIDTH_16, REG_ACCESS_R); - -ISP1362_REG(HCATLDTC, 0x51, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(HCATLDTCTO, 0x52, REG_WIDTH_16, REG_ACCESS_RW); - - -ISP1362_REG(OTGCONTROL, 0x62, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(OTGSTATUS, 0x67, REG_WIDTH_16, REG_ACCESS_R); -ISP1362_REG(OTGINT, 0x68, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(OTGINTENB, 0x69, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(OTGTIMER, 0x6A, REG_WIDTH_16, REG_ACCESS_RW); -ISP1362_REG(OTGALTTMR, 0x6C, REG_WIDTH_16, REG_ACCESS_RW); - -/* Philips transfer descriptor, cpu-endian */ -struct ptd { - u16 count; -#define PTD_COUNT_MSK (0x3ff << 0) -#define PTD_TOGGLE_MSK (1 << 10) -#define PTD_ACTIVE_MSK (1 << 11) -#define PTD_CC_MSK (0xf << 12) - u16 mps; -#define PTD_MPS_MSK (0x3ff << 0) -#define PTD_SPD_MSK (1 << 10) -#define PTD_LAST_MSK (1 << 11) -#define PTD_EP_MSK (0xf << 12) - u16 len; -#define PTD_LEN_MSK (0x3ff << 0) -#define PTD_DIR_MSK (3 << 10) -#define PTD_DIR_SETUP (0) -#define PTD_DIR_OUT (1) -#define PTD_DIR_IN (2) - u16 faddr; -#define PTD_FA_MSK (0x7f << 0) -/* PTD Byte 7: [StartingFrame (if ISO PTD) | StartingFrame[0..4], PollingRate[0..2] (if INT PTD)] */ -#define PTD_SF_ISO_MSK (0xff << 8) -#define PTD_SF_INT_MSK (0x1f << 8) -#define PTD_PR_MSK (0x07 << 13) -} __attribute__ ((packed, aligned(2))); -#define PTD_HEADER_SIZE sizeof(struct ptd) - -/* ------------------------------------------------------------------------- */ -/* Copied from ohci.h: */ -/* - * Hardware transfer status codes -- CC from PTD - */ -#define PTD_CC_NOERROR 0x00 -#define PTD_CC_CRC 0x01 -#define PTD_CC_BITSTUFFING 0x02 -#define PTD_CC_DATATOGGLEM 0x03 -#define PTD_CC_STALL 0x04 -#define PTD_DEVNOTRESP 0x05 -#define PTD_PIDCHECKFAIL 0x06 -#define PTD_UNEXPECTEDPID 0x07 -#define PTD_DATAOVERRUN 0x08 -#define PTD_DATAUNDERRUN 0x09 - /* 0x0A, 0x0B reserved for hardware */ -#define PTD_BUFFEROVERRUN 0x0C -#define PTD_BUFFERUNDERRUN 0x0D - /* 0x0E, 0x0F reserved for HCD */ -#define PTD_NOTACCESSED 0x0F - - -/* map OHCI TD status codes (CC) to errno values */ -static const int cc_to_error[16] = { - /* No Error */ 0, - /* CRC Error */ -EILSEQ, - /* Bit Stuff */ -EPROTO, - /* Data Togg */ -EILSEQ, - /* Stall */ -EPIPE, - /* DevNotResp */ -ETIMEDOUT, - /* PIDCheck */ -EPROTO, - /* UnExpPID */ -EPROTO, - /* DataOver */ -EOVERFLOW, - /* DataUnder */ -EREMOTEIO, - /* (for hw) */ -EIO, - /* (for hw) */ -EIO, - /* BufferOver */ -ECOMM, - /* BuffUnder */ -ENOSR, - /* (for HCD) */ -EALREADY, - /* (for HCD) */ -EALREADY -}; - - -/* - * HcControl (control) register masks - */ -#define OHCI_CTRL_HCFS (3 << 6) /* host controller functional state */ -#define OHCI_CTRL_RWC (1 << 9) /* remote wakeup connected */ -#define OHCI_CTRL_RWE (1 << 10) /* remote wakeup enable */ - -/* pre-shifted values for HCFS */ -# define OHCI_USB_RESET (0 << 6) -# define OHCI_USB_RESUME (1 << 6) -# define OHCI_USB_OPER (2 << 6) -# define OHCI_USB_SUSPEND (3 << 6) - -/* - * HcCommandStatus (cmdstatus) register masks - */ -#define OHCI_HCR (1 << 0) /* host controller reset */ -#define OHCI_SOC (3 << 16) /* scheduling overrun count */ - -/* - * masks used with interrupt registers: - * HcInterruptStatus (intrstatus) - * HcInterruptEnable (intrenable) - * HcInterruptDisable (intrdisable) - */ -#define OHCI_INTR_SO (1 << 0) /* scheduling overrun */ -#define OHCI_INTR_WDH (1 << 1) /* writeback of done_head */ -#define OHCI_INTR_SF (1 << 2) /* start frame */ -#define OHCI_INTR_RD (1 << 3) /* resume detect */ -#define OHCI_INTR_UE (1 << 4) /* unrecoverable error */ -#define OHCI_INTR_FNO (1 << 5) /* frame number overflow */ -#define OHCI_INTR_RHSC (1 << 6) /* root hub status change */ -#define OHCI_INTR_OC (1 << 30) /* ownership change */ -#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ - -/* roothub.portstatus [i] bits */ -#define RH_PS_CCS 0x00000001 /* current connect status */ -#define RH_PS_PES 0x00000002 /* port enable status*/ -#define RH_PS_PSS 0x00000004 /* port suspend status */ -#define RH_PS_POCI 0x00000008 /* port over current indicator */ -#define RH_PS_PRS 0x00000010 /* port reset status */ -#define RH_PS_PPS 0x00000100 /* port power status */ -#define RH_PS_LSDA 0x00000200 /* low speed device attached */ -#define RH_PS_CSC 0x00010000 /* connect status change */ -#define RH_PS_PESC 0x00020000 /* port enable status change */ -#define RH_PS_PSSC 0x00040000 /* port suspend status change */ -#define RH_PS_OCIC 0x00080000 /* over current indicator change */ -#define RH_PS_PRSC 0x00100000 /* port reset status change */ - -/* roothub.status bits */ -#define RH_HS_LPS 0x00000001 /* local power status */ -#define RH_HS_OCI 0x00000002 /* over current indicator */ -#define RH_HS_DRWE 0x00008000 /* device remote wakeup enable */ -#define RH_HS_LPSC 0x00010000 /* local power status change */ -#define RH_HS_OCIC 0x00020000 /* over current indicator change */ -#define RH_HS_CRWE 0x80000000 /* clear remote wakeup enable */ - -/* roothub.b masks */ -#define RH_B_DR 0x0000ffff /* device removable flags */ -#define RH_B_PPCM 0xffff0000 /* port power control mask */ - -/* roothub.a masks */ -#define RH_A_NDP (0xff << 0) /* number of downstream ports */ -#define RH_A_PSM (1 << 8) /* power switching mode */ -#define RH_A_NPS (1 << 9) /* no power switching */ -#define RH_A_DT (1 << 10) /* device type (mbz) */ -#define RH_A_OCPM (1 << 11) /* over current protection mode */ -#define RH_A_NOCP (1 << 12) /* no over current protection */ -#define RH_A_POTPGT (0xff << 24) /* power on to power good time */ - -#define FI 0x2edf /* 12000 bits per frame (-1) */ -#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) -#define LSTHRESH 0x628 /* lowspeed bit threshold */ - -/* ------------------------------------------------------------------------- */ - -/* PTD accessor macros. */ -#define PTD_GET_COUNT(p) (((p)->count & PTD_COUNT_MSK) >> 0) -#define PTD_COUNT(v) (((v) << 0) & PTD_COUNT_MSK) -#define PTD_GET_TOGGLE(p) (((p)->count & PTD_TOGGLE_MSK) >> 10) -#define PTD_TOGGLE(v) (((v) << 10) & PTD_TOGGLE_MSK) -#define PTD_GET_ACTIVE(p) (((p)->count & PTD_ACTIVE_MSK) >> 11) -#define PTD_ACTIVE(v) (((v) << 11) & PTD_ACTIVE_MSK) -#define PTD_GET_CC(p) (((p)->count & PTD_CC_MSK) >> 12) -#define PTD_CC(v) (((v) << 12) & PTD_CC_MSK) -#define PTD_GET_MPS(p) (((p)->mps & PTD_MPS_MSK) >> 0) -#define PTD_MPS(v) (((v) << 0) & PTD_MPS_MSK) -#define PTD_GET_SPD(p) (((p)->mps & PTD_SPD_MSK) >> 10) -#define PTD_SPD(v) (((v) << 10) & PTD_SPD_MSK) -#define PTD_GET_LAST(p) (((p)->mps & PTD_LAST_MSK) >> 11) -#define PTD_LAST(v) (((v) << 11) & PTD_LAST_MSK) -#define PTD_GET_EP(p) (((p)->mps & PTD_EP_MSK) >> 12) -#define PTD_EP(v) (((v) << 12) & PTD_EP_MSK) -#define PTD_GET_LEN(p) (((p)->len & PTD_LEN_MSK) >> 0) -#define PTD_LEN(v) (((v) << 0) & PTD_LEN_MSK) -#define PTD_GET_DIR(p) (((p)->len & PTD_DIR_MSK) >> 10) -#define PTD_DIR(v) (((v) << 10) & PTD_DIR_MSK) -#define PTD_GET_FA(p) (((p)->faddr & PTD_FA_MSK) >> 0) -#define PTD_FA(v) (((v) << 0) & PTD_FA_MSK) -#define PTD_GET_SF_INT(p) (((p)->faddr & PTD_SF_INT_MSK) >> 8) -#define PTD_SF_INT(v) (((v) << 8) & PTD_SF_INT_MSK) -#define PTD_GET_SF_ISO(p) (((p)->faddr & PTD_SF_ISO_MSK) >> 8) -#define PTD_SF_ISO(v) (((v) << 8) & PTD_SF_ISO_MSK) -#define PTD_GET_PR(p) (((p)->faddr & PTD_PR_MSK) >> 13) -#define PTD_PR(v) (((v) << 13) & PTD_PR_MSK) - -#define LOG2_PERIODIC_SIZE 5 /* arbitrary; this matches OHCI */ -#define PERIODIC_SIZE (1 << LOG2_PERIODIC_SIZE) - -struct isp1362_ep { - struct usb_host_endpoint *hep; - struct usb_device *udev; - - /* philips transfer descriptor */ - struct ptd ptd; - - u8 maxpacket; - u8 epnum; - u8 nextpid; - u16 error_count; - u16 length; /* of current packet */ - s16 ptd_offset; /* buffer offset in ISP1362 where - PTD has been stored - (for access thru HCDIRDATA) */ - int ptd_index; - int num_ptds; - void *data; /* to databuf */ - /* queue of active EPs (the ones transmitted to the chip) */ - struct list_head active; - - /* periodic schedule */ - u8 branch; - u16 interval; - u16 load; - u16 last_iso; - - /* async schedule */ - struct list_head schedule; /* list of all EPs that need processing */ - struct list_head remove_list; - int num_req; -}; - -struct isp1362_ep_queue { - struct list_head active; /* list of PTDs currently processed by HC */ - atomic_t finishing; - unsigned long buf_map; - unsigned long skip_map; - int free_ptd; - u16 buf_start; - u16 buf_size; - u16 blk_size; /* PTD buffer block size for ATL and INTL */ - u8 buf_count; - u8 buf_avail; - char name[16]; - - /* for statistical tracking */ - u8 stat_maxptds; /* Max # of ptds seen simultaneously in fifo */ - u8 ptd_count; /* number of ptds submitted to this queue */ -}; - -struct isp1362_hcd { - spinlock_t lock; - void __iomem *addr_reg; - void __iomem *data_reg; - - struct isp1362_platform_data *board; - - unsigned long stat1, stat2, stat4, stat8, stat16; - - /* HC registers */ - u32 intenb; /* "OHCI" interrupts */ - u16 irqenb; /* uP interrupts */ - - /* Root hub registers */ - u32 rhdesca; - u32 rhdescb; - u32 rhstatus; - u32 rhport[MAX_ROOT_PORTS]; - unsigned long next_statechange; - - /* HC control reg shadow copy */ - u32 hc_control; - - /* async schedule: control, bulk */ - struct list_head async; - - /* periodic schedule: int */ - u16 load[PERIODIC_SIZE]; - struct list_head periodic; - u16 fmindex; - - /* periodic schedule: isochronous */ - struct list_head isoc; - unsigned int istl_flip:1; - unsigned int irq_active:1; - - /* Schedules for the current frame */ - struct isp1362_ep_queue atl_queue; - struct isp1362_ep_queue intl_queue; - struct isp1362_ep_queue istl_queue[2]; - - /* list of PTDs retrieved from HC */ - struct list_head remove_list; - enum { - ISP1362_INT_SOF, - ISP1362_INT_ISTL0, - ISP1362_INT_ISTL1, - ISP1362_INT_EOT, - ISP1362_INT_OPR, - ISP1362_INT_SUSP, - ISP1362_INT_CLKRDY, - ISP1362_INT_INTL, - ISP1362_INT_ATL, - ISP1362_INT_OTG, - NUM_ISP1362_IRQS - } IRQ_NAMES; - unsigned int irq_stat[NUM_ISP1362_IRQS]; - int req_serial; -}; - -static inline const char *ISP1362_INT_NAME(int n) -{ - switch (n) { - case ISP1362_INT_SOF: return "SOF"; - case ISP1362_INT_ISTL0: return "ISTL0"; - case ISP1362_INT_ISTL1: return "ISTL1"; - case ISP1362_INT_EOT: return "EOT"; - case ISP1362_INT_OPR: return "OPR"; - case ISP1362_INT_SUSP: return "SUSP"; - case ISP1362_INT_CLKRDY: return "CLKRDY"; - case ISP1362_INT_INTL: return "INTL"; - case ISP1362_INT_ATL: return "ATL"; - case ISP1362_INT_OTG: return "OTG"; - default: return "unknown"; - } -} - -static inline void ALIGNSTAT(struct isp1362_hcd *isp1362_hcd, void *ptr) -{ - unsigned long p = (unsigned long)ptr; - if (!(p & 0xf)) - isp1362_hcd->stat16++; - else if (!(p & 0x7)) - isp1362_hcd->stat8++; - else if (!(p & 0x3)) - isp1362_hcd->stat4++; - else if (!(p & 0x1)) - isp1362_hcd->stat2++; - else - isp1362_hcd->stat1++; -} - -static inline struct isp1362_hcd *hcd_to_isp1362_hcd(struct usb_hcd *hcd) -{ - return (struct isp1362_hcd *) (hcd->hcd_priv); -} - -static inline struct usb_hcd *isp1362_hcd_to_hcd(struct isp1362_hcd *isp1362_hcd) -{ - return container_of((void *)isp1362_hcd, struct usb_hcd, hcd_priv); -} - -#define frame_before(f1, f2) ((s16)((u16)f1 - (u16)f2) < 0) - -/* - * ISP1362 HW Interface - */ - -#define DBG(level, fmt...) \ - do { \ - if (dbg_level > level) \ - pr_debug(fmt); \ - } while (0) - -#ifdef VERBOSE -# define VDBG(fmt...) DBG(3, fmt) -#else -# define VDBG(fmt...) do {} while (0) -#endif - -#ifdef REGISTERS -# define RDBG(fmt...) DBG(1, fmt) -#else -# define RDBG(fmt...) do {} while (0) -#endif - -#ifdef URB_TRACE -#define URB_DBG(fmt...) DBG(0, fmt) -#else -#define URB_DBG(fmt...) do {} while (0) -#endif - - -#if USE_PLATFORM_DELAY -#if USE_NDELAY -#error USE_PLATFORM_DELAY and USE_NDELAY defined simultaneously. -#endif -#define isp1362_delay(h, d) (h)->board->delay(isp1362_hcd_to_hcd(h)->self.controller, d) -#elif USE_NDELAY -#define isp1362_delay(h, d) ndelay(d) -#else -#define isp1362_delay(h, d) do {} while (0) -#endif - -#define get_urb(ep) ({ \ - BUG_ON(list_empty(&ep->hep->urb_list)); \ - container_of(ep->hep->urb_list.next, struct urb, urb_list); \ -}) - -/* basic access functions for ISP1362 chip registers */ -/* NOTE: The contents of the address pointer register cannot be read back! The driver must ensure, - * that all register accesses are performed with interrupts disabled, since the interrupt - * handler has no way of restoring the previous state. - */ -static void isp1362_write_addr(struct isp1362_hcd *isp1362_hcd, isp1362_reg_t reg) -{ - REG_ACCESS_TEST(reg); - DUMMY_DELAY_ACCESS; - writew(ISP1362_REG_NO(reg), isp1362_hcd->addr_reg); - DUMMY_DELAY_ACCESS; - isp1362_delay(isp1362_hcd, 1); -} - -static void isp1362_write_data16(struct isp1362_hcd *isp1362_hcd, u16 val) -{ - DUMMY_DELAY_ACCESS; - writew(val, isp1362_hcd->data_reg); -} - -static u16 isp1362_read_data16(struct isp1362_hcd *isp1362_hcd) -{ - u16 val; - - DUMMY_DELAY_ACCESS; - val = readw(isp1362_hcd->data_reg); - - return val; -} - -static void isp1362_write_data32(struct isp1362_hcd *isp1362_hcd, u32 val) -{ -#if USE_32BIT - DUMMY_DELAY_ACCESS; - writel(val, isp1362_hcd->data_reg); -#else - DUMMY_DELAY_ACCESS; - writew((u16)val, isp1362_hcd->data_reg); - DUMMY_DELAY_ACCESS; - writew(val >> 16, isp1362_hcd->data_reg); -#endif -} - -static u32 isp1362_read_data32(struct isp1362_hcd *isp1362_hcd) -{ - u32 val; - -#if USE_32BIT - DUMMY_DELAY_ACCESS; - val = readl(isp1362_hcd->data_reg); -#else - DUMMY_DELAY_ACCESS; - val = (u32)readw(isp1362_hcd->data_reg); - DUMMY_DELAY_ACCESS; - val |= (u32)readw(isp1362_hcd->data_reg) << 16; -#endif - return val; -} - -/* use readsw/writesw to access the fifo whenever possible */ -/* assume HCDIRDATA or XFERCTR & addr_reg have been set up */ -static void isp1362_read_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len) -{ - u8 *dp = buf; - u16 data; - - if (!len) - return; - - RDBG("%s: Reading %d byte from fifo to mem @ %p\n", __func__, len, buf); -#if USE_32BIT - if (len >= 4) { - RDBG("%s: Using readsl for %d dwords\n", __func__, len >> 2); - readsl(isp1362_hcd->data_reg, dp, len >> 2); - dp += len & ~3; - len &= 3; - } -#endif - if (len >= 2) { - RDBG("%s: Using readsw for %d words\n", __func__, len >> 1); - insw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1); - dp += len & ~1; - len &= 1; - } - - BUG_ON(len & ~1); - if (len > 0) { - data = isp1362_read_data16(isp1362_hcd); - RDBG("%s: Reading trailing byte %02x to mem @ %08x\n", __func__, - (u8)data, (u32)dp); - *dp = (u8)data; - } -} - -static void isp1362_write_fifo(struct isp1362_hcd *isp1362_hcd, void *buf, u16 len) -{ - u8 *dp = buf; - u16 data; - - if (!len) - return; - - if ((unsigned long)dp & 0x1) { - /* not aligned */ - for (; len > 1; len -= 2) { - data = *dp++; - data |= *dp++ << 8; - isp1362_write_data16(isp1362_hcd, data); - } - if (len) - isp1362_write_data16(isp1362_hcd, *dp); - return; - } - - RDBG("%s: Writing %d byte to fifo from memory @%p\n", __func__, len, buf); -#if USE_32BIT - if (len >= 4) { - RDBG("%s: Using writesl for %d dwords\n", __func__, len >> 2); - writesl(isp1362_hcd->data_reg, dp, len >> 2); - dp += len & ~3; - len &= 3; - } -#endif - if (len >= 2) { - RDBG("%s: Using writesw for %d words\n", __func__, len >> 1); - outsw((unsigned long)isp1362_hcd->data_reg, dp, len >> 1); - dp += len & ~1; - len &= 1; - } - - BUG_ON(len & ~1); - if (len > 0) { - /* finally write any trailing byte; we don't need to care - * about the high byte of the last word written - */ - data = (u16)*dp; - RDBG("%s: Sending trailing byte %02x from mem @ %08x\n", __func__, - data, (u32)dp); - isp1362_write_data16(isp1362_hcd, data); - } -} - -#define isp1362_read_reg16(d, r) ({ \ - u16 __v; \ - REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16); \ - isp1362_write_addr(d, ISP1362_REG_##r); \ - __v = isp1362_read_data16(d); \ - RDBG("%s: Read %04x from %s[%02x]\n", __func__, __v, #r, \ - ISP1362_REG_NO(ISP1362_REG_##r)); \ - __v; \ -}) - -#define isp1362_read_reg32(d, r) ({ \ - u32 __v; \ - REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32); \ - isp1362_write_addr(d, ISP1362_REG_##r); \ - __v = isp1362_read_data32(d); \ - RDBG("%s: Read %08x from %s[%02x]\n", __func__, __v, #r, \ - ISP1362_REG_NO(ISP1362_REG_##r)); \ - __v; \ -}) - -#define isp1362_write_reg16(d, r, v) { \ - REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_16); \ - isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET); \ - isp1362_write_data16(d, (u16)(v)); \ - RDBG("%s: Wrote %04x to %s[%02x]\n", __func__, (u16)(v), #r, \ - ISP1362_REG_NO(ISP1362_REG_##r)); \ -} - -#define isp1362_write_reg32(d, r, v) { \ - REG_WIDTH_TEST(ISP1362_REG_##r, REG_WIDTH_32); \ - isp1362_write_addr(d, (ISP1362_REG_##r) | ISP1362_REG_WRITE_OFFSET); \ - isp1362_write_data32(d, (u32)(v)); \ - RDBG("%s: Wrote %08x to %s[%02x]\n", __func__, (u32)(v), #r, \ - ISP1362_REG_NO(ISP1362_REG_##r)); \ -} - -#define isp1362_set_mask16(d, r, m) { \ - u16 __v; \ - __v = isp1362_read_reg16(d, r); \ - if ((__v | m) != __v) \ - isp1362_write_reg16(d, r, __v | m); \ -} - -#define isp1362_clr_mask16(d, r, m) { \ - u16 __v; \ - __v = isp1362_read_reg16(d, r); \ - if ((__v & ~m) != __v) \ - isp1362_write_reg16(d, r, __v & ~m); \ -} - -#define isp1362_set_mask32(d, r, m) { \ - u32 __v; \ - __v = isp1362_read_reg32(d, r); \ - if ((__v | m) != __v) \ - isp1362_write_reg32(d, r, __v | m); \ -} - -#define isp1362_clr_mask32(d, r, m) { \ - u32 __v; \ - __v = isp1362_read_reg32(d, r); \ - if ((__v & ~m) != __v) \ - isp1362_write_reg32(d, r, __v & ~m); \ -} - -#define isp1362_show_reg(d, r) { \ - if ((ISP1362_REG_##r & REG_WIDTH_MASK) == REG_WIDTH_32) \ - DBG(0, "%-12s[%02x]: %08x\n", #r, \ - ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg32(d, r)); \ - else \ - DBG(0, "%-12s[%02x]: %04x\n", #r, \ - ISP1362_REG_NO(ISP1362_REG_##r), isp1362_read_reg16(d, r)); \ -} - -static void isp1362_write_diraddr(struct isp1362_hcd *isp1362_hcd, u16 offset, u16 len) -{ - len = (len + 1) & ~1; - - isp1362_clr_mask16(isp1362_hcd, HCDMACFG, HCDMACFG_CTR_ENABLE); - isp1362_write_reg32(isp1362_hcd, HCDIRADDR, - HCDIRADDR_ADDR(offset) | HCDIRADDR_COUNT(len)); -} - -static void isp1362_read_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len) -{ - isp1362_write_diraddr(isp1362_hcd, offset, len); - - DBG(3, "%s: Reading %d byte from buffer @%04x to memory @ %p\n", - __func__, len, offset, buf); - - isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); - - isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA); - - isp1362_read_fifo(isp1362_hcd, buf, len); - isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); -} - -static void isp1362_write_buffer(struct isp1362_hcd *isp1362_hcd, void *buf, u16 offset, int len) -{ - isp1362_write_diraddr(isp1362_hcd, offset, len); - - DBG(3, "%s: Writing %d byte to buffer @%04x from memory @ %p\n", - __func__, len, offset, buf); - - isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); - - isp1362_write_addr(isp1362_hcd, ISP1362_REG_HCDIRDATA | ISP1362_REG_WRITE_OFFSET); - isp1362_write_fifo(isp1362_hcd, buf, len); - - isp1362_write_reg16(isp1362_hcd, HCuPINT, HCuPINT_EOT); -} - -static void __attribute__((unused)) dump_data(char *buf, int len) -{ - if (dbg_level > 0) { - int k; - int lf = 0; - - for (k = 0; k < len; ++k) { - if (!lf) - DBG(0, "%04x:", k); - printk(" %02x", ((u8 *) buf)[k]); - lf = 1; - if (!k) - continue; - if (k % 16 == 15) { - printk("\n"); - lf = 0; - continue; - } - if (k % 8 == 7) - printk(" "); - if (k % 4 == 3) - printk(" "); - } - if (lf) - printk("\n"); - } -} - -#if defined(PTD_TRACE) - -static void dump_ptd(struct ptd *ptd) -{ - DBG(0, "EP %p: CC=%x EP=%d DIR=%x CNT=%d LEN=%d MPS=%d TGL=%x ACT=%x FA=%d SPD=%x SF=%x PR=%x LST=%x\n", - container_of(ptd, struct isp1362_ep, ptd), - PTD_GET_CC(ptd), PTD_GET_EP(ptd), PTD_GET_DIR(ptd), - PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), - PTD_GET_TOGGLE(ptd), PTD_GET_ACTIVE(ptd), PTD_GET_FA(ptd), - PTD_GET_SPD(ptd), PTD_GET_SF_INT(ptd), PTD_GET_PR(ptd), PTD_GET_LAST(ptd)); - DBG(0, " %04x %04x %04x %04x\n", ptd->count, ptd->mps, ptd->len, ptd->faddr); -} - -static void dump_ptd_out_data(struct ptd *ptd, u8 *buf) -{ - if (dbg_level > 0) { - if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { - DBG(0, "--out->\n"); - dump_data(buf, PTD_GET_LEN(ptd)); - } - } -} - -static void dump_ptd_in_data(struct ptd *ptd, u8 *buf) -{ - if (dbg_level > 0) { - if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { - DBG(0, "<--in--\n"); - dump_data(buf, PTD_GET_COUNT(ptd)); - } - DBG(0, "-----\n"); - } -} - -static void dump_ptd_queue(struct isp1362_ep_queue *epq) -{ - struct isp1362_ep *ep; - int dbg = dbg_level; - - dbg_level = 1; - list_for_each_entry(ep, &epq->active, active) { - dump_ptd(&ep->ptd); - dump_data(ep->data, ep->length); - } - dbg_level = dbg; -} -#else -#define dump_ptd(ptd) do {} while (0) -#define dump_ptd_in_data(ptd, buf) do {} while (0) -#define dump_ptd_out_data(ptd, buf) do {} while (0) -#define dump_ptd_data(ptd, buf) do {} while (0) -#define dump_ptd_queue(epq) do {} while (0) -#endif diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 4b5f03f683f7..0e17c988d36a 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1523,7 +1523,7 @@ max3421_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) max3421_ep = urb->ep->hcpriv; if (!max3421_ep) { /* gets freed in max3421_endpoint_disable: */ - max3421_ep = kzalloc(sizeof(struct max3421_ep), GFP_ATOMIC); + max3421_ep = kzalloc_obj(struct max3421_ep, GFP_ATOMIC); if (!max3421_ep) { retval = -ENOMEM; goto out; @@ -1878,10 +1878,10 @@ max3421_probe(struct spi_device *spi) INIT_LIST_HEAD(&max3421_hcd->ep_list); spi_set_drvdata(spi, max3421_hcd); - max3421_hcd->tx = kmalloc(sizeof(*max3421_hcd->tx), GFP_KERNEL); + max3421_hcd->tx = kmalloc_obj(*max3421_hcd->tx); if (!max3421_hcd->tx) goto error; - max3421_hcd->rx = kmalloc(sizeof(*max3421_hcd->rx), GFP_KERNEL); + max3421_hcd->rx = kmalloc_obj(*max3421_hcd->rx); if (!max3421_hcd->rx) goto error; diff --git a/drivers/usb/host/octeon-hcd.c b/drivers/usb/host/octeon-hcd.c index 361d33b0c4d2..34ce771fa0f5 100644 --- a/drivers/usb/host/octeon-hcd.c +++ b/drivers/usb/host/octeon-hcd.c @@ -1098,7 +1098,7 @@ static struct cvmx_usb_pipe *cvmx_usb_open_pipe(struct octeon_hcd *usb, { struct cvmx_usb_pipe *pipe; - pipe = kzalloc(sizeof(*pipe), GFP_ATOMIC); + pipe = kzalloc_obj(*pipe, GFP_ATOMIC); if (!pipe) return NULL; if ((device_speed == CVMX_USB_SPEED_HIGH) && @@ -2138,7 +2138,7 @@ static struct cvmx_usb_transaction *cvmx_usb_submit_transaction( if (unlikely(pipe->transfer_type != type)) return NULL; - transaction = kzalloc(sizeof(*transaction), GFP_ATOMIC); + transaction = kzalloc_obj(*transaction, GFP_ATOMIC); if (unlikely(!transaction)) return NULL; @@ -3180,9 +3180,8 @@ static int octeon_usb_urb_enqueue(struct usb_hcd *hcd, * Allocate a structure to use for our private list of * isochronous packets. */ - iso_packet = kmalloc_array(urb->number_of_packets, - sizeof(struct cvmx_usb_iso_packet), - GFP_ATOMIC); + iso_packet = kmalloc_objs(struct cvmx_usb_iso_packet, + urb->number_of_packets, GFP_ATOMIC); if (iso_packet) { int i; /* Fill the list with the data from the URB */ diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 76bc8d56325d..9e0e06bbc570 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -492,7 +492,7 @@ static ssize_t fill_periodic_buffer(struct debug_buffer *buf) char *next; unsigned i; - seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC); + seen = kmalloc_objs(*seen, DBG_SCHED_LIMIT, GFP_ATOMIC); if (!seen) return 0; seen_count = 0; @@ -667,7 +667,7 @@ static struct debug_buffer *alloc_buffer(struct ohci_hcd *ohci, { struct debug_buffer *buf; - buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); + buf = kzalloc_obj(struct debug_buffer); if (buf) { buf->ohci = ohci; diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 9c7f3008646e..129468b1efc2 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -190,7 +190,7 @@ static int ohci_urb_enqueue ( } /* allocate the private part of the URB */ - urb_priv = kzalloc(struct_size(urb_priv, td, size), mem_flags); + urb_priv = kzalloc_flex(*urb_priv, td, size, mem_flags); if (!urb_priv) return -ENOMEM; INIT_LIST_HEAD (&urb_priv->pending); @@ -1282,7 +1282,6 @@ static int __init ohci_hcd_mod_init(void) pr_debug ("%s: block sizes: ed %zd td %zd\n", hcd_name, sizeof (struct ed), sizeof (struct td)); - set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); ohci_debug_root = debugfs_create_dir("ohci", usb_debug_root); @@ -1332,7 +1331,6 @@ static int __init ohci_hcd_mod_init(void) debugfs_remove(ohci_debug_root); ohci_debug_root = NULL; - clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); return retval; } module_init(ohci_hcd_mod_init); @@ -1352,7 +1350,6 @@ static void __exit ohci_hcd_mod_exit(void) ps3_ohci_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); #endif debugfs_remove(ohci_debug_root); - clear_bit(USB_OHCI_LOADED, &usb_hcds_loaded); } module_exit(ohci_hcd_mod_exit); diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 6b7c73eff081..ca96067e6d6d 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -1149,7 +1149,7 @@ static int ehci_mem_init(struct oxu_hcd *oxu, gfp_t flags) for (i = 0; i < QTD_NUM; i++) oxu->qtd_used[i] = 0; - oxu->murb_pool = kcalloc(MURB_NUM, sizeof(struct oxu_murb), flags); + oxu->murb_pool = kzalloc_objs(struct oxu_murb, MURB_NUM, flags); if (!oxu->murb_pool) goto fail; diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index d21a03cf5c17..0a26489a40d0 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -337,7 +337,7 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, struct r8a66597_device *dev; int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ - dev = kzalloc(sizeof(struct r8a66597_device), GFP_ATOMIC); + dev = kzalloc_obj(struct r8a66597_device, GFP_ATOMIC); if (dev == NULL) return -ENOMEM; @@ -1859,7 +1859,7 @@ static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, struct r8a66597_td *td; u16 pipenum; - td = kzalloc(sizeof(struct r8a66597_td), GFP_ATOMIC); + td = kzalloc_obj(struct r8a66597_td, GFP_ATOMIC); if (td == NULL) return NULL; @@ -1901,8 +1901,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, goto error_not_linked; if (!hep->hcpriv) { - hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), - GFP_ATOMIC); + hep->hcpriv = kzalloc_obj(struct r8a66597_pipe, GFP_ATOMIC); if (!hep->hcpriv) { ret = -ENOMEM; goto error; diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 5d6dba681e50..4ae47edd4b8b 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -814,7 +814,7 @@ static int sl811h_urb_enqueue( /* avoid all allocations within spinlocks */ if (!hep->hcpriv) { - ep = kzalloc(sizeof *ep, mem_flags); + ep = kzalloc_obj(*ep, mem_flags); if (ep == NULL) return -ENOMEM; } diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 16d157013018..ada91ca33f65 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c @@ -178,7 +178,7 @@ static int sl811_cs_probe(struct pcmcia_device *link) { local_info_t *local; - local = kzalloc(sizeof(local_info_t), GFP_KERNEL); + local = kzalloc_obj(local_info_t); if (!local) return -ENOMEM; local->p_dev = link; diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index c4e67c4b51f6..e91ec6a4fa74 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c @@ -561,7 +561,7 @@ static int uhci_debug_open(struct inode *inode, struct file *file) struct uhci_debug *up; unsigned long flags; - up = kmalloc(sizeof(*up), GFP_KERNEL); + up = kmalloc_obj(*up); if (!up) return -ENOMEM; diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 14e6dfef16c6..433d64a5fab5 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -603,8 +603,7 @@ static int uhci_start(struct usb_hcd *hcd) goto err_alloc_frame; } - uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), - GFP_KERNEL); + uhci->frame_cpu = kzalloc_objs(*uhci->frame_cpu, UHCI_NUMFRAMES); if (!uhci->frame_cpu) goto err_alloc_frame_cpu; @@ -867,8 +866,6 @@ static int __init uhci_hcd_init(void) if (usb_disabled()) return -ENODEV; - set_bit(USB_UHCI_LOADED, &usb_hcds_loaded); - #ifdef CONFIG_DYNAMIC_DEBUG errbuf = kmalloc(ERRBUF_LEN, GFP_KERNEL); if (!errbuf) @@ -912,8 +909,6 @@ static int __init uhci_hcd_init(void) errbuf_failed: #endif - - clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded); return retval; } @@ -930,7 +925,6 @@ static void __exit uhci_hcd_cleanup(void) #ifdef CONFIG_DYNAMIC_DEBUG kfree(errbuf); #endif - clear_bit(USB_UHCI_LOADED, &usb_hcds_loaded); } module_init(uhci_hcd_init); diff --git a/drivers/usb/host/xhci-dbgcap.c b/drivers/usb/host/xhci-dbgcap.c index 9da4f3b452cb..7e6f7d72f03e 100644 --- a/drivers/usb/host/xhci-dbgcap.c +++ b/drivers/usb/host/xhci-dbgcap.c @@ -29,6 +29,12 @@ #include "xhci-trace.h" #include "xhci-dbgcap.h" +static const struct dbc_str dbc_str_default = { + .manufacturer = "Linux Foundation", + .product = "Linux USB Debug Target", + .serial = "0001", +}; + static void dbc_free_ctx(struct device *dev, struct xhci_container_ctx *ctx) { if (!ctx) @@ -52,55 +58,6 @@ static void dbc_ring_free(struct device *dev, struct xhci_ring *ring) kfree(ring); } -static u32 xhci_dbc_populate_strings(struct dbc_str_descs *strings) -{ - struct usb_string_descriptor *s_desc; - u32 string_length; - - /* Serial string: */ - s_desc = (struct usb_string_descriptor *)strings->serial; - utf8s_to_utf16s(DBC_STRING_SERIAL, strlen(DBC_STRING_SERIAL), - UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, - DBC_MAX_STRING_LENGTH); - - s_desc->bLength = (strlen(DBC_STRING_SERIAL) + 1) * 2; - s_desc->bDescriptorType = USB_DT_STRING; - string_length = s_desc->bLength; - string_length <<= 8; - - /* Product string: */ - s_desc = (struct usb_string_descriptor *)strings->product; - utf8s_to_utf16s(DBC_STRING_PRODUCT, strlen(DBC_STRING_PRODUCT), - UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, - DBC_MAX_STRING_LENGTH); - - s_desc->bLength = (strlen(DBC_STRING_PRODUCT) + 1) * 2; - s_desc->bDescriptorType = USB_DT_STRING; - string_length += s_desc->bLength; - string_length <<= 8; - - /* Manufacture string: */ - s_desc = (struct usb_string_descriptor *)strings->manufacturer; - utf8s_to_utf16s(DBC_STRING_MANUFACTURER, - strlen(DBC_STRING_MANUFACTURER), - UTF16_LITTLE_ENDIAN, (wchar_t *)s_desc->wData, - DBC_MAX_STRING_LENGTH); - - s_desc->bLength = (strlen(DBC_STRING_MANUFACTURER) + 1) * 2; - s_desc->bDescriptorType = USB_DT_STRING; - string_length += s_desc->bLength; - string_length <<= 8; - - /* String0: */ - strings->string0[0] = 4; - strings->string0[1] = USB_DT_STRING; - strings->string0[2] = 0x09; - strings->string0[3] = 0x04; - string_length += 4; - - return string_length; -} - static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc) { struct xhci_ep_ctx *ep_ctx; @@ -124,7 +81,65 @@ static void xhci_dbc_init_ep_contexts(struct xhci_dbc *dbc) ep_ctx->deq = cpu_to_le64(deq | dbc->ring_in->cycle_state); } -static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length) +static u8 get_str_desc_len(const char *desc) +{ + return ((struct usb_string_descriptor *)desc)->bLength; +} + +static u32 dbc_prepare_info_context_str_len(struct dbc_str_descs *descs) +{ + u32 len; + + len = get_str_desc_len(descs->serial); + len <<= 8; + len += get_str_desc_len(descs->product); + len <<= 8; + len += get_str_desc_len(descs->manufacturer); + len <<= 8; + len += get_str_desc_len(descs->string0); + + return len; +} + +static int xhci_dbc_populate_str_desc(char *desc, const char *src) +{ + struct usb_string_descriptor *s_desc; + int len; + + s_desc = (struct usb_string_descriptor *)desc; + + /* len holds number of 2 byte UTF-16 characters */ + len = utf8s_to_utf16s(src, strlen(src), UTF16_LITTLE_ENDIAN, + (wchar_t *)s_desc->wData, USB_MAX_STRING_LEN * 2); + if (len < 0) + return len; + + s_desc->bLength = len * 2 + 2; + s_desc->bDescriptorType = USB_DT_STRING; + + return s_desc->bLength; +} + +static void xhci_dbc_populate_str_descs(struct dbc_str_descs *str_descs, + struct dbc_str *str) +{ + /* Serial string: */ + xhci_dbc_populate_str_desc(str_descs->serial, str->serial); + + /* Product string: */ + xhci_dbc_populate_str_desc(str_descs->product, str->product); + + /* Manufacturer string: */ + xhci_dbc_populate_str_desc(str_descs->manufacturer, str->manufacturer); + + /* String0: */ + str_descs->string0[0] = 4; + str_descs->string0[1] = USB_DT_STRING; + str_descs->string0[2] = 0x09; + str_descs->string0[3] = 0x04; +} + +static void xhci_dbc_init_contexts(struct xhci_dbc *dbc) { struct dbc_info_context *info; u32 dev_info; @@ -135,12 +150,12 @@ static void xhci_dbc_init_contexts(struct xhci_dbc *dbc, u32 string_length) /* Populate info Context: */ info = (struct dbc_info_context *)dbc->ctx->bytes; - dma = dbc->string_dma; + dma = dbc->str_descs_dma; info->string0 = cpu_to_le64(dma); - info->manufacturer = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH); - info->product = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 2); - info->serial = cpu_to_le64(dma + DBC_MAX_STRING_LENGTH * 3); - info->length = cpu_to_le32(string_length); + info->manufacturer = cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN); + info->product = cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN * 2); + info->serial = cpu_to_le64(dma + USB_MAX_STRING_DESC_LEN * 3); + info->length = cpu_to_le32(dbc_prepare_info_context_str_len(dbc->str_descs)); /* Populate bulk in and out endpoint contexts: */ xhci_dbc_init_ep_contexts(dbc); @@ -223,7 +238,7 @@ dbc_alloc_request(struct xhci_dbc *dbc, unsigned int direction, gfp_t flags) if (!dbc) return NULL; - req = kzalloc(sizeof(*req), flags); + req = kzalloc_obj(*req, flags); if (!req) return NULL; @@ -431,7 +446,7 @@ dbc_alloc_ctx(struct device *dev, gfp_t flags) { struct xhci_container_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), flags); + ctx = kzalloc_obj(*ctx, flags); if (!ctx) return NULL; @@ -488,14 +503,14 @@ xhci_dbc_ring_alloc(struct device *dev, enum xhci_ring_type type, gfp_t flags) struct xhci_segment *seg; dma_addr_t dma; - ring = kzalloc(sizeof(*ring), flags); + ring = kzalloc_obj(*ring, flags); if (!ring) return NULL; ring->num_segs = 1; ring->type = type; - seg = kzalloc(sizeof(*seg), flags); + seg = kzalloc_obj(*seg, flags); if (!seg) goto seg_fail; @@ -525,7 +540,6 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags) { int ret; dma_addr_t deq; - u32 string_length; struct device *dev = dbc->dev; /* Allocate various rings for events and transfers: */ @@ -552,11 +566,11 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags) goto ctx_fail; /* Allocate the string table: */ - dbc->string_size = sizeof(*dbc->string); - dbc->string = dma_alloc_coherent(dev, dbc->string_size, - &dbc->string_dma, flags); - if (!dbc->string) - goto string_fail; + dbc->str_descs_size = sizeof(*dbc->str_descs); + dbc->str_descs = dma_alloc_coherent(dev, dbc->str_descs_size, + &dbc->str_descs_dma, flags); + if (!dbc->str_descs) + goto str_descs_fail; /* Setup ERST register: */ writel(dbc->erst.num_entries, &dbc->regs->ersts); @@ -566,16 +580,16 @@ static int xhci_dbc_mem_init(struct xhci_dbc *dbc, gfp_t flags) dbc->ring_evt->dequeue); lo_hi_writeq(deq, &dbc->regs->erdp); - /* Setup strings and contexts: */ - string_length = xhci_dbc_populate_strings(dbc->string); - xhci_dbc_init_contexts(dbc, string_length); + /* Setup string descriptors and contexts: */ + xhci_dbc_populate_str_descs(dbc->str_descs, &dbc->str); + xhci_dbc_init_contexts(dbc); xhci_dbc_eps_init(dbc); dbc->state = DS_INITIALIZED; return 0; -string_fail: +str_descs_fail: dbc_free_ctx(dev, dbc->ctx); dbc->ctx = NULL; ctx_fail: @@ -600,8 +614,8 @@ static void xhci_dbc_mem_cleanup(struct xhci_dbc *dbc) xhci_dbc_eps_exit(dbc); - dma_free_coherent(dbc->dev, dbc->string_size, dbc->string, dbc->string_dma); - dbc->string = NULL; + dma_free_coherent(dbc->dev, dbc->str_descs_size, dbc->str_descs, dbc->str_descs_dma); + dbc->str_descs = NULL; dbc_free_ctx(dbc->dev, dbc->ctx); dbc->ctx = NULL; @@ -1196,6 +1210,108 @@ static ssize_t dbc_bcdDevice_store(struct device *dev, return size; } +static ssize_t dbc_manufacturer_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + + return sysfs_emit(buf, "%s\n", dbc->str.manufacturer); +} + +static ssize_t dbc_manufacturer_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + size_t len; + + if (dbc->state != DS_DISABLED) + return -EBUSY; + + len = strcspn(buf, "\n"); + if (!len) + return -EINVAL; + + if (len > USB_MAX_STRING_LEN) + return -E2BIG; + + memcpy(dbc->str.manufacturer, buf, len); + dbc->str.manufacturer[len] = '\0'; + + return size; +} + +static ssize_t dbc_product_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + + return sysfs_emit(buf, "%s\n", dbc->str.product); +} + +static ssize_t dbc_product_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + size_t len; + + if (dbc->state != DS_DISABLED) + return -EBUSY; + + len = strcspn(buf, "\n"); + if (!len) + return -EINVAL; + + if (len > USB_MAX_STRING_LEN) + return -E2BIG; + + memcpy(dbc->str.product, buf, len); + dbc->str.product[len] = '\0'; + + return size; +} + +static ssize_t dbc_serial_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + + return sysfs_emit(buf, "%s\n", dbc->str.serial); +} + +static ssize_t dbc_serial_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + struct xhci_dbc *dbc = xhci->dbc; + size_t len; + + if (dbc->state != DS_DISABLED) + return -EBUSY; + + len = strcspn(buf, "\n"); + if (!len) + return -EINVAL; + + if (len > USB_MAX_STRING_LEN) + return -E2BIG; + + memcpy(dbc->str.serial, buf, len); + dbc->str.serial[len] = '\0'; + + return size; +} + static ssize_t dbc_bInterfaceProtocol_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -1283,6 +1399,9 @@ static DEVICE_ATTR_RW(dbc); static DEVICE_ATTR_RW(dbc_idVendor); static DEVICE_ATTR_RW(dbc_idProduct); static DEVICE_ATTR_RW(dbc_bcdDevice); +static DEVICE_ATTR_RW(dbc_serial); +static DEVICE_ATTR_RW(dbc_product); +static DEVICE_ATTR_RW(dbc_manufacturer); static DEVICE_ATTR_RW(dbc_bInterfaceProtocol); static DEVICE_ATTR_RW(dbc_poll_interval_ms); @@ -1291,6 +1410,9 @@ static struct attribute *dbc_dev_attrs[] = { &dev_attr_dbc_idVendor.attr, &dev_attr_dbc_idProduct.attr, &dev_attr_dbc_bcdDevice.attr, + &dev_attr_dbc_serial.attr, + &dev_attr_dbc_product.attr, + &dev_attr_dbc_manufacturer.attr, &dev_attr_dbc_bInterfaceProtocol.attr, &dev_attr_dbc_poll_interval_ms.attr, NULL @@ -1303,7 +1425,7 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver * struct xhci_dbc *dbc; int ret; - dbc = kzalloc(sizeof(*dbc), GFP_KERNEL); + dbc = kzalloc_obj(*dbc); if (!dbc) return NULL; @@ -1316,6 +1438,9 @@ xhci_alloc_dbc(struct device *dev, void __iomem *base, const struct dbc_driver * dbc->bInterfaceProtocol = DBC_PROTOCOL; dbc->poll_interval = DBC_POLL_INTERVAL_DEFAULT; + /* initialize serial, product and manufacturer with default values */ + dbc->str = dbc_str_default; + if (readl(&dbc->regs->control) & DBC_CTRL_DBC_ENABLE) goto err; diff --git a/drivers/usb/host/xhci-dbgcap.h b/drivers/usb/host/xhci-dbgcap.h index 5426c971d2d3..20ae4e7617f2 100644 --- a/drivers/usb/host/xhci-dbgcap.h +++ b/drivers/usb/host/xhci-dbgcap.h @@ -47,10 +47,6 @@ struct dbc_info_context { #define DBC_DOOR_BELL_TARGET(p) (((p) & 0xff) << 8) #define DBC_MAX_PACKET 1024 -#define DBC_MAX_STRING_LENGTH 64 -#define DBC_STRING_MANUFACTURER "Linux Foundation" -#define DBC_STRING_PRODUCT "Linux USB Debug Target" -#define DBC_STRING_SERIAL "0001" #define DBC_CONTEXT_SIZE 64 /* @@ -63,11 +59,31 @@ struct dbc_info_context { #define DBC_PORTSC_LINK_CHANGE BIT(22) #define DBC_PORTSC_CONFIG_CHANGE BIT(23) +/* + * The maximum length of a string descriptor is 255, because the bLength + * field in the usb_string_descriptor struct is __u8. In practice the + * maximum length is 254, because a string descriptor consists of a 2 byte + * header followed by UTF-16 characters (2 bytes each). This allows for + * only 126 characters (code points) in the string, which is where + * USB_MAX_STRING_LEN comes from. + */ +#define USB_MAX_STRING_DESC_LEN 254 + struct dbc_str_descs { - char string0[DBC_MAX_STRING_LENGTH]; - char manufacturer[DBC_MAX_STRING_LENGTH]; - char product[DBC_MAX_STRING_LENGTH]; - char serial[DBC_MAX_STRING_LENGTH]; + char string0[USB_MAX_STRING_DESC_LEN]; + char manufacturer[USB_MAX_STRING_DESC_LEN]; + char product[USB_MAX_STRING_DESC_LEN]; + char serial[USB_MAX_STRING_DESC_LEN]; +}; + +/* + * NULL terminated UTF-8 strings used to create UTF-16 strings + * (with maxiumum USB_MAX_STRING_LEN 2 byte characters). + */ +struct dbc_str { + char manufacturer[USB_MAX_STRING_LEN+1]; + char product[USB_MAX_STRING_LEN+1]; + char serial[USB_MAX_STRING_LEN+1]; }; #define DBC_PROTOCOL 1 /* GNU Remote Debug Command */ @@ -133,9 +149,10 @@ struct xhci_dbc { struct xhci_erst erst; struct xhci_container_ctx *ctx; - struct dbc_str_descs *string; - dma_addr_t string_dma; - size_t string_size; + struct dbc_str_descs *str_descs; + dma_addr_t str_descs_dma; + size_t str_descs_size; + struct dbc_str str; u16 idVendor; u16 idProduct; u16 bcdDevice; diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c index 90282e51e23e..2e7384c6b6ec 100644 --- a/drivers/usb/host/xhci-dbgtty.c +++ b/drivers/usb/host/xhci-dbgtty.c @@ -584,7 +584,7 @@ int xhci_dbc_tty_probe(struct device *dev, void __iomem *base, struct xhci_hcd * if (!dbc_tty_driver) return -ENODEV; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/drivers/usb/host/xhci-debugfs.c b/drivers/usb/host/xhci-debugfs.c index c1eb1036ede9..ade178ab34a7 100644 --- a/drivers/usb/host/xhci-debugfs.c +++ b/drivers/usb/host/xhci-debugfs.c @@ -87,7 +87,7 @@ static struct xhci_regset *xhci_debugfs_alloc_regset(struct xhci_hcd *xhci) { struct xhci_regset *regset; - regset = kzalloc(sizeof(*regset), GFP_KERNEL); + regset = kzalloc_obj(*regset); if (!regset) return NULL; @@ -386,11 +386,19 @@ static const struct file_operations port_fops = { static int xhci_portli_show(struct seq_file *s, void *unused) { struct xhci_port *port = s->private; - struct xhci_hcd *xhci = hcd_to_xhci(port->rhub->hcd); + struct xhci_hcd *xhci; u32 portli; portli = readl(&port->port_reg->portli); + /* port without protocol capability isn't added to a roothub */ + if (!port->rhub) { + seq_printf(s, "0x%08x\n", portli); + return 0; + } + + xhci = hcd_to_xhci(port->rhub->hcd); + /* PORTLI fields are valid if port is a USB3 or eUSB2V2 port */ if (port->rhub == &xhci->usb3_rhub) seq_printf(s, "0x%08x LEC=%u RLC=%u TLC=%u\n", portli, @@ -468,7 +476,7 @@ void xhci_debugfs_create_endpoint(struct xhci_hcd *xhci, if (spriv->eps[ep_index]) return; - epriv = kzalloc(sizeof(*epriv), GFP_KERNEL); + epriv = kzalloc_obj(*epriv); if (!epriv) return; @@ -608,7 +616,7 @@ void xhci_debugfs_create_slot(struct xhci_hcd *xhci, int slot_id) struct xhci_slot_priv *priv; struct xhci_virt_device *dev = xhci->devs[slot_id]; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return; diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index c708bdd69f16..75bc1eb98b76 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -977,7 +977,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, return 0; } - dev = kzalloc(sizeof(*dev), flags); + dev = kzalloc_obj(*dev, flags); if (!dev) return 0; diff --git a/drivers/usb/host/xhci-mtk-sch.c b/drivers/usb/host/xhci-mtk-sch.c index 27eb384a3963..583623cd4d8f 100644 --- a/drivers/usb/host/xhci-mtk-sch.c +++ b/drivers/usb/host/xhci-mtk-sch.c @@ -179,8 +179,7 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev) if (utt->multi) { tt_index = utt->hcpriv; if (!tt_index) { /* Create the index array */ - tt_index = kcalloc(utt->hub->maxchild, - sizeof(*tt_index), GFP_KERNEL); + tt_index = kzalloc_objs(*tt_index, utt->hub->maxchild); if (!tt_index) return ERR_PTR(-ENOMEM); utt->hcpriv = tt_index; @@ -193,7 +192,7 @@ static struct mu3h_sch_tt *find_tt(struct usb_device *udev) tt = *ptt; if (!tt) { /* Create the mu3h_sch_tt */ - tt = kzalloc(sizeof(*tt), GFP_KERNEL); + tt = kzalloc_obj(*tt); if (!tt) { if (allocated_index) { utt->hcpriv = NULL; @@ -264,7 +263,7 @@ create_sch_ep(struct xhci_hcd_mtk *mtk, struct usb_device *udev, else len = 1; - sch_ep = kzalloc(struct_size(sch_ep, bw_budget_table, len), GFP_KERNEL); + sch_ep = kzalloc_flex(*sch_ep, bw_budget_table, len); if (!sch_ep) return ERR_PTR(-ENOMEM); @@ -891,7 +890,7 @@ int xhci_mtk_sch_init(struct xhci_hcd_mtk *mtk) /* ss IN and OUT are separated */ num_usb_bus = xhci->usb3_rhub.num_ports * 2 + xhci->usb2_rhub.num_ports; - sch_array = kcalloc(num_usb_bus, sizeof(*sch_array), GFP_KERNEL); + sch_array = kzalloc_objs(*sch_array, num_usb_bus); if (sch_array == NULL) return -ENOMEM; diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 9315ba18310d..1cbefee3c4ca 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3195,6 +3195,7 @@ irqreturn_t xhci_irq(struct usb_hcd *hcd) if (status & STS_HCE) { xhci_warn(xhci, "WARNING: Host Controller Error\n"); + xhci_halt(xhci); goto out; } diff --git a/drivers/usb/host/xhci-sideband.c b/drivers/usb/host/xhci-sideband.c index 2bd77255032b..abbcc0e44f1b 100644 --- a/drivers/usb/host/xhci-sideband.c +++ b/drivers/usb/host/xhci-sideband.c @@ -28,11 +28,11 @@ xhci_ring_to_sgtable(struct xhci_sideband *sb, struct xhci_ring *ring) dev = xhci_to_hcd(sb->xhci)->self.sysdev; sz = ring->num_segs * TRB_SEGMENT_SIZE; n_pages = PAGE_ALIGN(sz) >> PAGE_SHIFT; - pages = kvmalloc_array(n_pages, sizeof(struct page *), GFP_KERNEL); + pages = kvmalloc_objs(struct page *, n_pages); if (!pages) return NULL; - sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kzalloc_obj(*sgt); if (!sgt) { kvfree(pages); return NULL; diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c index 8b492871d21d..3f6aa2440b05 100644 --- a/drivers/usb/host/xhci-tegra.c +++ b/drivers/usb/host/xhci-tegra.c @@ -1570,7 +1570,6 @@ static int tegra_xusb_setup_wakeup(struct platform_device *pdev, struct tegra_xu data = irq_get_irq_data(tegra->wake_irqs[i]); if (!data) { dev_warn(tegra->dev, "get wake event %d irq data fail\n", i); - irq_dispose_mapping(tegra->wake_irqs[i]); break; } @@ -1583,16 +1582,6 @@ static int tegra_xusb_setup_wakeup(struct platform_device *pdev, struct tegra_xu return 0; } -static void tegra_xusb_dispose_wake(struct tegra_xusb *tegra) -{ - unsigned int i; - - for (i = 0; i < tegra->num_wakes; i++) - irq_dispose_mapping(tegra->wake_irqs[i]); - - tegra->num_wakes = 0; -} - static int tegra_xusb_probe(struct platform_device *pdev) { struct tegra_xusb *tegra; @@ -1648,10 +1637,8 @@ static int tegra_xusb_probe(struct platform_device *pdev) return err; tegra->padctl = tegra_xusb_padctl_get(&pdev->dev); - if (IS_ERR(tegra->padctl)) { - err = PTR_ERR(tegra->padctl); - goto dispose_wake; - } + if (IS_ERR(tegra->padctl)) + return PTR_ERR(tegra->padctl); np = of_parse_phandle(pdev->dev.of_node, "nvidia,xusb-padctl", 0); if (!np) { @@ -1975,8 +1962,6 @@ static int tegra_xusb_probe(struct platform_device *pdev) put_padctl: of_node_put(np); tegra_xusb_padctl_put(tegra->padctl); -dispose_wake: - tegra_xusb_dispose_wake(tegra); return err; } @@ -2009,8 +1994,6 @@ static void tegra_xusb_remove(struct platform_device *pdev) if (tegra->padctl_irq) pm_runtime_disable(&pdev->dev); - tegra_xusb_dispose_wake(tegra); - pm_runtime_put(&pdev->dev); tegra_xusb_disable(tegra); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b3ba16b9718c..ef6d8662adec 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1641,7 +1641,7 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag else num_tds = 1; - urb_priv = kzalloc(struct_size(urb_priv, td, num_tds), mem_flags); + urb_priv = kzalloc_flex(*urb_priv, td, num_tds, mem_flags); if (!urb_priv) return -ENOMEM; @@ -4146,7 +4146,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || (xhci->xhc_state & XHCI_STATE_HALTED)) { spin_unlock_irqrestore(&xhci->lock, flags); - kfree(command); + xhci_free_command(xhci, command); return -ENODEV; } @@ -4154,7 +4154,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id) slot_id); if (ret) { spin_unlock_irqrestore(&xhci->lock, flags); - kfree(command); + xhci_free_command(xhci, command); return ret; } xhci_ring_cmd_db(xhci); diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 7b7e1554ea20..ca287b770e8c 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -707,7 +707,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l if (signal_pending (current)) { mutex_unlock(&mdc800->io_lock); - return -EINTR; + return len == left ? -EINTR : len-left; } sts=left > (mdc800->out_count-mdc800->out_ptr)?mdc800->out_count-mdc800->out_ptr:left; @@ -730,9 +730,11 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l mutex_unlock(&mdc800->io_lock); return len-left; } - wait_event_timeout(mdc800->download_wait, + retval = wait_event_timeout(mdc800->download_wait, mdc800->downloaded, msecs_to_jiffies(TO_DOWNLOAD_GET_READY)); + if (!retval) + usb_kill_urb(mdc800->download_urb); mdc800->downloaded = 0; if (mdc800->download_urb->status != 0) { @@ -982,7 +984,7 @@ static int __init usb_mdc800_init (void) { int retval = -ENODEV; /* Allocate Memory */ - mdc800=kzalloc (sizeof (struct mdc800_data), GFP_KERNEL); + mdc800=kzalloc_obj(struct mdc800_data); if (!mdc800) goto cleanup_on_fail; diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 82859374f302..45dc209f5fe5 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c @@ -723,7 +723,7 @@ static int mts_usb_probe(struct usb_interface *intf, } - new_desc = kzalloc(sizeof(struct mts_desc), GFP_KERNEL); + new_desc = kzalloc_obj(struct mts_desc); if (!new_desc) goto out; diff --git a/drivers/usb/isp1760/isp1760-hcd.c b/drivers/usb/isp1760/isp1760-hcd.c index 8dcd9cc22413..6c52c6f59d69 100644 --- a/drivers/usb/isp1760/isp1760-hcd.c +++ b/drivers/usb/isp1760/isp1760-hcd.c @@ -2572,15 +2572,15 @@ int isp1760_hcd_register(struct isp1760_hcd *priv, struct resource *mem, priv->hcd = hcd; - priv->atl_slots = kcalloc(mem_layout->slot_num, - sizeof(struct isp1760_slotinfo), GFP_KERNEL); + priv->atl_slots = kzalloc_objs(struct isp1760_slotinfo, + mem_layout->slot_num); if (!priv->atl_slots) { ret = -ENOMEM; goto put_hcd; } - priv->int_slots = kcalloc(mem_layout->slot_num, - sizeof(struct isp1760_slotinfo), GFP_KERNEL); + priv->int_slots = kzalloc_objs(struct isp1760_slotinfo, + mem_layout->slot_num); if (!priv->int_slots) { ret = -ENOMEM; goto free_atl_slots; diff --git a/drivers/usb/isp1760/isp1760-udc.c b/drivers/usb/isp1760/isp1760-udc.c index 65ac91d0595a..e45a54c4a560 100644 --- a/drivers/usb/isp1760/isp1760-udc.c +++ b/drivers/usb/isp1760/isp1760-udc.c @@ -878,7 +878,7 @@ static struct usb_request *isp1760_ep_alloc_request(struct usb_ep *ep, { struct isp1760_request *req; - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (!req) return NULL; diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index ed6a19254d2f..369d0d2ee2be 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -657,7 +657,7 @@ static int adu_probe(struct usb_interface *interface, int res; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); + dev = kzalloc_obj(struct adu_device); if (!dev) return -ENOMEM; diff --git a/drivers/usb/misc/apple-mfi-fastcharge.c b/drivers/usb/misc/apple-mfi-fastcharge.c index 47b38dcc2992..339f6cd2e9b2 100644 --- a/drivers/usb/misc/apple-mfi-fastcharge.c +++ b/drivers/usb/misc/apple-mfi-fastcharge.c @@ -184,7 +184,7 @@ static int mfi_fc_probe(struct usb_device *udev) if (!mfi_fc_match(udev)) return -ENODEV; - mfi = kzalloc(sizeof(struct mfi_device), GFP_KERNEL); + mfi = kzalloc_obj(struct mfi_device); if (!mfi) return -ENOMEM; diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 62b5a30edc42..4beebde59842 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -226,7 +226,7 @@ static int appledisplay_probe(struct usb_interface *iface, int_in_endpointAddr = endpoint->bEndpointAddress; /* allocate memory for our device state and initialize it */ - pdata = kzalloc(sizeof(struct appledisplay), GFP_KERNEL); + pdata = kzalloc_obj(struct appledisplay); if (!pdata) { retval = -ENOMEM; goto error; diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c index 45cff32656c6..d8016540953f 100644 --- a/drivers/usb/misc/chaoskey.c +++ b/drivers/usb/misc/chaoskey.c @@ -143,7 +143,7 @@ static int chaoskey_probe(struct usb_interface *interface, /* Looks good, allocate and initialize */ - dev = kzalloc(sizeof(struct chaoskey), GFP_KERNEL); + dev = kzalloc_obj(struct chaoskey); if (dev == NULL) goto out; diff --git a/drivers/usb/misc/cypress_cy7c63.c b/drivers/usb/misc/cypress_cy7c63.c index 75f5a740cba3..99185fc3e9df 100644 --- a/drivers/usb/misc/cypress_cy7c63.c +++ b/drivers/usb/misc/cypress_cy7c63.c @@ -211,7 +211,7 @@ static int cypress_probe(struct usb_interface *interface, int retval = -ENOMEM; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto error_mem; diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 875016dd073c..2bf082474e9d 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c @@ -307,7 +307,7 @@ static int cytherm_probe(struct usb_interface *interface, struct usb_cytherm *dev; int retval = -ENOMEM; - dev = kzalloc(sizeof(struct usb_cytherm), GFP_KERNEL); + dev = kzalloc_obj(struct usb_cytherm); if (!dev) goto error_mem; diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index ea39243efee3..0f6b3464c2d6 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c @@ -330,7 +330,7 @@ static int idmouse_probe(struct usb_interface *interface, return -ENODEV; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) return -ENOMEM; diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 365c10069345..18670dfed2e7 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -777,7 +777,7 @@ static int iowarrior_probe(struct usb_interface *interface, int res; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); + dev = kzalloc_obj(struct iowarrior); if (!dev) return retval; diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index f392d6f84df9..c74f142f6637 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -656,7 +656,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto exit; mutex_init(&dev->mutex); diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 379cf01a6e96..052ffc2e71ee 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -748,7 +748,7 @@ static int tower_probe(struct usb_interface *interface, const struct usb_device_ int result; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto exit; diff --git a/drivers/usb/misc/lvstest.c b/drivers/usb/misc/lvstest.c index 25ec5666a75e..9b6e10177f80 100644 --- a/drivers/usb/misc/lvstest.c +++ b/drivers/usb/misc/lvstest.c @@ -260,7 +260,7 @@ static ssize_t get_dev_desc_store(struct device *dev, struct usb_device_descriptor *descriptor; int ret; - descriptor = kmalloc(sizeof(*descriptor), GFP_KERNEL); + descriptor = kmalloc_obj(*descriptor); if (!descriptor) return -ENOMEM; diff --git a/drivers/usb/misc/onboard_usb_dev.c b/drivers/usb/misc/onboard_usb_dev.c index 41360a7591e5..ba37eb99efba 100644 --- a/drivers/usb/misc/onboard_usb_dev.c +++ b/drivers/usb/misc/onboard_usb_dev.c @@ -202,7 +202,7 @@ static int onboard_dev_add_usbdev(struct onboard_dev *onboard_dev, goto error; } - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) { err = -ENOMEM; goto error; diff --git a/drivers/usb/misc/onboard_usb_dev.h b/drivers/usb/misc/onboard_usb_dev.h index c1462be5526d..1a1e86e60e04 100644 --- a/drivers/usb/misc/onboard_usb_dev.h +++ b/drivers/usb/misc/onboard_usb_dev.h @@ -115,6 +115,13 @@ static const struct onboard_dev_pdata vialab_vl817_data = { .is_hub = true, }; +static const struct onboard_dev_pdata wch_ch334_data = { + .reset_us = 14000, + .num_supplies = 2, + .supply_names = { "vdd33", "v5" }, + .is_hub = true, +}; + static const struct onboard_dev_pdata xmos_xvf3500_data = { .reset_us = 1, .num_supplies = 2, @@ -146,6 +153,7 @@ static const struct of_device_id onboard_dev_match[] = { { .compatible = "usbbda,5411", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,414", .data = &realtek_rts5411_data, }, { .compatible = "usbbda,5414", .data = &realtek_rts5411_data, }, + { .compatible = "usb1a86,8091", .data = &wch_ch334_data, }, { .compatible = "usb1da0,5511", .data = ¶de_ps5511_data, }, { .compatible = "usb1da0,55a1", .data = ¶de_ps5511_data, }, { .compatible = "usb2109,817", .data = &vialab_vl817_data, }, diff --git a/drivers/usb/misc/onboard_usb_dev_pdevs.c b/drivers/usb/misc/onboard_usb_dev_pdevs.c index 722504752ce3..cdb6949e18ec 100644 --- a/drivers/usb/misc/onboard_usb_dev_pdevs.c +++ b/drivers/usb/misc/onboard_usb_dev_pdevs.c @@ -109,7 +109,7 @@ void onboard_dev_create_pdevs(struct usb_device *parent_hub, struct list_head *p goto node_put; } - pdle = kzalloc(sizeof(*pdle), GFP_KERNEL); + pdle = kzalloc_obj(*pdle); if (!pdle) { of_platform_device_destroy(&pdev->dev, NULL); goto node_put; diff --git a/drivers/usb/misc/sisusbvga/sisusbvga.c b/drivers/usb/misc/sisusbvga/sisusbvga.c index febf34f9f049..3e75a7c24828 100644 --- a/drivers/usb/misc/sisusbvga/sisusbvga.c +++ b/drivers/usb/misc/sisusbvga/sisusbvga.c @@ -2797,7 +2797,7 @@ static int sisusb_probe(struct usb_interface *intf, dev->devnum); /* Allocate memory for our private */ - sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL); + sisusb = kzalloc_obj(*sisusb); if (!sisusb) return -ENOMEM; diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 26baba3ab7d7..6aaec2db360b 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c @@ -86,7 +86,7 @@ static int tv_probe(struct usb_interface *interface, struct trancevibrator *dev; int retval; - dev = kzalloc(sizeof(struct trancevibrator), GFP_KERNEL); + dev = kzalloc_obj(struct trancevibrator); if (!dev) { retval = -ENOMEM; goto error; diff --git a/drivers/usb/misc/usb-ljca.c b/drivers/usb/misc/usb-ljca.c index 9e65bb9577ea..7e85fd12da56 100644 --- a/drivers/usb/misc/usb-ljca.c +++ b/drivers/usb/misc/usb-ljca.c @@ -529,7 +529,7 @@ static int ljca_new_client_device(struct ljca_adapter *adap, u8 type, u8 id, struct ljca_client *client; int ret; - client = kzalloc(sizeof *client, GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) { kfree(data); return -ENOMEM; @@ -597,7 +597,7 @@ static int ljca_enumerate_gpio(struct ljca_adapter *adap) return -EINVAL; /* construct platform data */ - gpio_info = kzalloc(sizeof *gpio_info, GFP_KERNEL); + gpio_info = kzalloc_obj(*gpio_info); if (!gpio_info) return -ENOMEM; gpio_info->num = gpio_num; @@ -630,7 +630,7 @@ static int ljca_enumerate_i2c(struct ljca_adapter *adap) for (i = 0; i < desc->num; i++) { /* construct platform data */ - i2c_info = kzalloc(sizeof *i2c_info, GFP_KERNEL); + i2c_info = kzalloc_obj(*i2c_info); if (!i2c_info) return -ENOMEM; @@ -669,7 +669,7 @@ static int ljca_enumerate_spi(struct ljca_adapter *adap) for (i = 0; i < desc->num; i++) { /* construct platform data */ - spi_info = kzalloc(sizeof *spi_info, GFP_KERNEL); + spi_info = kzalloc_obj(*spi_info); if (!spi_info) return -ENOMEM; diff --git a/drivers/usb/misc/usbio.c b/drivers/usb/misc/usbio.c index 37644dddf157..2e68d48a2cc0 100644 --- a/drivers/usb/misc/usbio.c +++ b/drivers/usb/misc/usbio.c @@ -439,7 +439,7 @@ static int usbio_add_client(struct usbio_device *usbio, char *name, u8 id, void struct auxiliary_device *adev; int ret; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index bb546f624a45..f794695dea9d 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -323,7 +323,7 @@ static int lcd_probe(struct usb_interface *interface, int retval; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/usb/misc/usbsevseg.c b/drivers/usb/misc/usbsevseg.c index 546deff754ba..b37bf53dd54f 100644 --- a/drivers/usb/misc/usbsevseg.c +++ b/drivers/usb/misc/usbsevseg.c @@ -308,7 +308,7 @@ static int sevseg_probe(struct usb_interface *interface, struct usb_sevsegdev *mydev; int rc = -ENOMEM; - mydev = kzalloc(sizeof(struct usb_sevsegdev), GFP_KERNEL); + mydev = kzalloc_obj(struct usb_sevsegdev); if (!mydev) goto error_mem; diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 5c92c8d8e283..98071b25ac07 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -545,7 +545,7 @@ alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe) if (max == 0) return NULL; - sg = kmalloc_array(nents, sizeof(*sg), GFP_KERNEL); + sg = kmalloc_objs(*sg, nents); if (!sg) return NULL; sg_init_table(sg, nents); @@ -1221,7 +1221,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param) * as with bulk/intr sglists, sglen is the queue depth; it also * controls which subtests run (more tests than sglen) or rerun. */ - urb = kcalloc(param->sglen, sizeof(struct urb *), GFP_KERNEL); + urb = kzalloc_objs(struct urb *, param->sglen); if (!urb) return -ENOMEM; for (i = 0; i < param->sglen; i++) { @@ -1370,7 +1370,7 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param) if (!u) goto cleanup; - reqp = kmalloc(sizeof(*reqp), GFP_KERNEL); + reqp = kmalloc_obj(*reqp); if (!reqp) goto cleanup; reqp->setup = req; @@ -1572,7 +1572,7 @@ static int unlink_queued(struct usbtest_dev *dev, int pipe, unsigned num, memset(buf, 0, size); /* Allocate and init the urbs we'll queue */ - ctx.urbs = kcalloc(num, sizeof(struct urb *), GFP_KERNEL); + ctx.urbs = kzalloc_objs(struct urb *, num); if (!ctx.urbs) goto free_buf; for (i = 0; i < num; i++) { @@ -2052,7 +2052,7 @@ test_queue(struct usbtest_dev *dev, struct usbtest_param_32 *param, if (param->sglen > MAX_SGLEN) return -EINVAL; - urbs = kcalloc(param->sglen, sizeof(*urbs), GFP_KERNEL); + urbs = kzalloc_objs(*urbs, param->sglen); if (!urbs) return -ENOMEM; @@ -2786,7 +2786,7 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id) } #endif - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; info = (struct usbtest_info *) id->driver_info; diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index b26c1d382d59..a8af7615b1bf 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -134,7 +134,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p usbdev = priv->usbdev; if (!usbdev) return NULL; - rq = kzalloc(sizeof(struct uss720_async_request), mem_flags); + rq = kzalloc_obj(struct uss720_async_request, mem_flags); if (!rq) return NULL; kref_init(&rq->ref_count); @@ -147,7 +147,7 @@ static struct uss720_async_request *submit_async_request(struct parport_uss720_p kref_put(&rq->ref_count, destroy_async); return NULL; } - rq->dr = kmalloc(sizeof(*rq->dr), mem_flags); + rq->dr = kmalloc_obj(*rq->dr, mem_flags); if (!rq->dr) { kref_put(&rq->ref_count, destroy_async); return NULL; @@ -701,7 +701,7 @@ static int uss720_probe(struct usb_interface *intf, /* * Allocate parport interface */ - priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL); + priv = kzalloc_obj(struct parport_uss720_private); if (!priv) { usb_put_dev(usbdev); return -ENOMEM; @@ -736,7 +736,7 @@ static int uss720_probe(struct usb_interface *intf, ret = get_1284_register(pp, 0, ®, GFP_KERNEL); dev_dbg(&intf->dev, "reg: %7ph\n", priv->reg); if (ret < 0) - return ret; + goto probe_abort; ret = usb_find_last_int_in_endpoint(interface, &epd); if (!ret) { diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c index 70dff0db5354..7a482cdee1e9 100644 --- a/drivers/usb/misc/yurex.c +++ b/drivers/usb/misc/yurex.c @@ -197,7 +197,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ int res; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto error; kref_init(&dev->kref); @@ -272,6 +272,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt, dev, 1); dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + dev->bbu = -1; if (usb_submit_urb(dev->urb, GFP_KERNEL)) { retval = -EIO; dev_err(&interface->dev, "Could not submitting URB\n"); @@ -280,7 +281,6 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_ /* save our data pointer in this interface device */ usb_set_intfdata(interface, dev); - dev->bbu = -1; /* we can register the device now, as it is ready */ retval = usb_register_dev(interface, &yurex_class); diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index e713fc5964b1..687f6a8981f3 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c @@ -694,7 +694,7 @@ static int mon_bin_open(struct inode *inode, struct file *file) return -ENODEV; } - rp = kzalloc(sizeof(struct mon_reader_bin), GFP_KERNEL); + rp = kzalloc_obj(struct mon_reader_bin); if (rp == NULL) { rc = -ENOMEM; goto err_alloc; @@ -1029,8 +1029,7 @@ static long mon_bin_ioctl(struct file *file, unsigned int cmd, unsigned long arg return -EINVAL; size = CHUNK_ALIGN(arg); - vec = kcalloc(size / CHUNK_SIZE, sizeof(struct mon_pgmap), - GFP_KERNEL); + vec = kzalloc_objs(struct mon_pgmap, size / CHUNK_SIZE); if (vec == NULL) { ret = -ENOMEM; break; diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index af852d53aac6..e4fff194fea0 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c @@ -273,7 +273,7 @@ static void mon_bus_init(struct usb_bus *ubus) { struct mon_bus *mbus; - mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL); + mbus = kzalloc_obj(struct mon_bus); if (mbus == NULL) goto err_alloc; kref_init(&mbus->ref); diff --git a/drivers/usb/mon/mon_stat.c b/drivers/usb/mon/mon_stat.c index 398e02af6a2b..3ee2e483da57 100644 --- a/drivers/usb/mon/mon_stat.c +++ b/drivers/usb/mon/mon_stat.c @@ -29,7 +29,7 @@ static int mon_stat_open(struct inode *inode, struct file *file) struct mon_bus *mbus; struct snap *sp; - sp = kmalloc(sizeof(struct snap), GFP_KERNEL); + sp = kmalloc_obj(struct snap); if (sp == NULL) return -ENOMEM; diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 68b9b2b41189..4c8e2518e407 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c @@ -330,7 +330,7 @@ static int mon_text_open(struct inode *inode, struct file *file) mutex_lock(&mon_lock); mbus = inode->i_private; - rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); + rp = kzalloc_obj(struct mon_reader_text); if (rp == NULL) { rc = -ENOMEM; goto err_alloc; diff --git a/drivers/usb/mtu3/mtu3_core.c b/drivers/usb/mtu3/mtu3_core.c index 3a25ee18f144..66dbfe1705d5 100644 --- a/drivers/usb/mtu3/mtu3_core.c +++ b/drivers/usb/mtu3/mtu3_core.c @@ -613,7 +613,7 @@ static int mtu3_mem_alloc(struct mtu3 *mtu) /* one for ep0, another is reserved */ mtu->num_eps = min(in_ep_num, out_ep_num) + 1; - ep_array = kcalloc(mtu->num_eps * 2, sizeof(*ep_array), GFP_KERNEL); + ep_array = kzalloc_objs(*ep_array, mtu->num_eps * 2); if (ep_array == NULL) return -ENOMEM; diff --git a/drivers/usb/mtu3/mtu3_gadget.c b/drivers/usb/mtu3/mtu3_gadget.c index bf73fbc29976..da29f467943f 100644 --- a/drivers/usb/mtu3/mtu3_gadget.c +++ b/drivers/usb/mtu3/mtu3_gadget.c @@ -235,7 +235,7 @@ struct usb_request *mtu3_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) struct mtu3_ep *mep = to_mtu3_ep(ep); struct mtu3_request *mreq; - mreq = kzalloc(sizeof(*mreq), gfp_flags); + mreq = kzalloc_obj(*mreq, gfp_flags); if (!mreq) return NULL; diff --git a/drivers/usb/musb/musb_cppi41.c b/drivers/usb/musb/musb_cppi41.c index 4cde3abb7006..28e958fcc862 100644 --- a/drivers/usb/musb/musb_cppi41.c +++ b/drivers/usb/musb/musb_cppi41.c @@ -756,7 +756,7 @@ cppi41_dma_controller_create(struct musb *musb, void __iomem *base) return NULL; } - controller = kzalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc_obj(*controller); if (!controller) goto kzalloc_fail; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index d666c4292753..016d3f3fc1e0 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1133,7 +1133,7 @@ struct usb_request *musb_alloc_request(struct usb_ep *ep, gfp_t gfp_flags) struct musb_ep *musb_ep = to_musb_ep(ep); struct musb_request *request; - request = kzalloc(sizeof *request, gfp_flags); + request = kzalloc_obj(*request, gfp_flags); if (!request) return NULL; diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 6b4481a867c5..8efd2fa472f9 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -2154,7 +2154,7 @@ static int musb_urb_enqueue( * REVISIT consider a dedicated qh kmem_cache, so it's harder * for bugs in other kernel code to break this driver... */ - qh = kzalloc(sizeof *qh, mem_flags); + qh = kzalloc_obj(*qh, mem_flags); if (!qh) { spin_lock_irqsave(&musb->lock, flags); usb_hcd_unlink_urb_from_ep(hcd, urb); diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 7acd1635850d..8c6c643fcb2c 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c @@ -395,7 +395,7 @@ dma_controller_alloc(struct musb *musb, void __iomem *base) { struct musb_dma_controller *controller; - controller = kzalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc_obj(*controller); if (!controller) return NULL; diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 60a93b8bbe3c..36ee61a52e7e 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c @@ -596,7 +596,7 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base) | TUSB_DMA_REQ_CONF_DMA_REQ_EN(0x3f) | TUSB_DMA_REQ_CONF_DMA_REQ_ASSER(2)); - tusb_dma = kzalloc(sizeof(struct tusb_omap_dma), GFP_KERNEL); + tusb_dma = kzalloc_obj(struct tusb_omap_dma); if (!tusb_dma) goto out; @@ -615,13 +615,13 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base) struct dma_channel *ch; struct tusb_omap_dma_ch *chdat; - ch = kzalloc(sizeof(struct dma_channel), GFP_KERNEL); + ch = kzalloc_obj(struct dma_channel); if (!ch) goto cleanup; dma_channel_pool[i] = ch; - chdat = kzalloc(sizeof(struct tusb_omap_dma_ch), GFP_KERNEL); + chdat = kzalloc_obj(struct tusb_omap_dma_ch); if (!chdat) goto cleanup; diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index d5cf5e8bb1ca..bbb4978c0cd5 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c @@ -362,7 +362,7 @@ ux500_dma_controller_create(struct musb *musb, void __iomem *base) struct resource *iomem; int ret; - controller = kzalloc(sizeof(*controller), GFP_KERNEL); + controller = kzalloc_obj(*controller); if (!controller) goto kzalloc_fail; diff --git a/drivers/usb/phy/phy-fsl-usb.c b/drivers/usb/phy/phy-fsl-usb.c index e266a47c4d48..35d79f11b03d 100644 --- a/drivers/usb/phy/phy-fsl-usb.c +++ b/drivers/usb/phy/phy-fsl-usb.c @@ -779,11 +779,11 @@ static int fsl_otg_conf(struct platform_device *pdev) return 0; /* allocate space to fsl otg device */ - fsl_otg_tc = kzalloc(sizeof(struct fsl_otg), GFP_KERNEL); + fsl_otg_tc = kzalloc_obj(struct fsl_otg); if (!fsl_otg_tc) return -ENOMEM; - fsl_otg_tc->phy.otg = kzalloc(sizeof(struct usb_otg), GFP_KERNEL); + fsl_otg_tc->phy.otg = kzalloc_obj(struct usb_otg); if (!fsl_otg_tc->phy.otg) { kfree(fsl_otg_tc); return -ENOMEM; diff --git a/drivers/usb/phy/phy-fsl-usb.h b/drivers/usb/phy/phy-fsl-usb.h index d70341ae5a92..95bfe7f1b83a 100644 --- a/drivers/usb/phy/phy-fsl-usb.h +++ b/drivers/usb/phy/phy-fsl-usb.h @@ -345,7 +345,7 @@ inline struct fsl_otg_timer *otg_timer_initializer { struct fsl_otg_timer *timer; - timer = kmalloc(sizeof(struct fsl_otg_timer), GFP_KERNEL); + timer = kmalloc_obj(struct fsl_otg_timer); if (!timer) return NULL; timer->function = function; diff --git a/drivers/usb/phy/phy-generic.c b/drivers/usb/phy/phy-generic.c index 8423be59ec0f..de26b302334d 100644 --- a/drivers/usb/phy/phy-generic.c +++ b/drivers/usb/phy/phy-generic.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include @@ -49,15 +49,13 @@ static int nop_set_suspend(struct usb_phy *x, int suspend) int ret = 0; if (suspend) { - if (!IS_ERR(nop->clk)) - clk_disable_unprepare(nop->clk); + clk_disable_unprepare(nop->clk); if (!IS_ERR(nop->vcc) && !device_may_wakeup(x->dev)) ret = regulator_disable(nop->vcc); } else { if (!IS_ERR(nop->vcc) && !device_may_wakeup(x->dev)) ret = regulator_enable(nop->vcc); - if (!IS_ERR(nop->clk)) - clk_prepare_enable(nop->clk); + clk_prepare_enable(nop->clk); } return ret; @@ -137,11 +135,9 @@ int usb_gen_phy_init(struct usb_phy *phy) dev_err(phy->dev, "Failed to enable power\n"); } - if (!IS_ERR(nop->clk)) { - ret = clk_prepare_enable(nop->clk); - if (ret) - return ret; - } + ret = clk_prepare_enable(nop->clk); + if (ret) + return ret; nop_reset(nop); @@ -155,8 +151,7 @@ void usb_gen_phy_shutdown(struct usb_phy *phy) gpiod_set_value_cansleep(nop->gpiod_reset, 1); - if (!IS_ERR(nop->clk)) - clk_disable_unprepare(nop->clk); + clk_disable_unprepare(nop->clk); if (!IS_ERR(nop->vcc)) { if (regulator_disable(nop->vcc)) @@ -202,18 +197,9 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) { enum usb_phy_type type = USB_PHY_TYPE_USB2; int err = 0; - u32 clk_rate = 0; - bool needs_clk = false; - if (dev->of_node) { - struct device_node *node = dev->of_node; - - if (of_property_read_u32(node, "clock-frequency", &clk_rate)) - clk_rate = 0; - - needs_clk = of_property_present(node, "clocks"); - } + device_property_read_u32(dev, "clock-frequency", &clk_rate); nop->gpiod_reset = devm_gpiod_get_optional(dev, "reset", GPIOD_ASIS); err = PTR_ERR_OR_ZERO(nop->gpiod_reset); @@ -235,20 +221,16 @@ int usb_phy_gen_create_phy(struct device *dev, struct usb_phy_generic *nop) if (!nop->phy.otg) return -ENOMEM; - nop->clk = devm_clk_get(dev, "main_clk"); - if (IS_ERR(nop->clk)) { - dev_dbg(dev, "Can't get phy clock: %ld\n", - PTR_ERR(nop->clk)); - if (needs_clk) - return PTR_ERR(nop->clk); - } + nop->clk = devm_clk_get_optional(dev, "main_clk"); + if (IS_ERR(nop->clk)) + return dev_err_probe(dev, PTR_ERR(nop->clk), + "Can't get phy clock\n"); - if (!IS_ERR(nop->clk) && clk_rate) { + if (clk_rate) { err = clk_set_rate(nop->clk, clk_rate); - if (err) { - dev_err(dev, "Error setting clock rate\n"); - return err; - } + if (err) + return dev_err_probe(dev, err, + "Error setting clock rate\n"); } nop->vcc = devm_regulator_get_optional(dev, "vcc"); @@ -282,7 +264,6 @@ EXPORT_SYMBOL_GPL(usb_phy_gen_create_phy); static int usb_phy_generic_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct device_node *dn = dev->of_node; struct usb_phy_generic *nop; int err; @@ -293,17 +274,17 @@ static int usb_phy_generic_probe(struct platform_device *pdev) err = usb_phy_gen_create_phy(dev, nop); if (err) return err; + if (nop->gpiod_vbus) { - err = devm_request_threaded_irq(&pdev->dev, + err = devm_request_threaded_irq(dev, gpiod_to_irq(nop->gpiod_vbus), NULL, nop_gpio_vbus_thread, VBUS_IRQ_FLAGS, "vbus_detect", nop); - if (err) { - dev_err(&pdev->dev, "can't request irq %i, err: %d\n", - gpiod_to_irq(nop->gpiod_vbus), err); - return err; - } + if (err) + return dev_err_probe(dev, err, "can't request irq %i\n", + gpiod_to_irq(nop->gpiod_vbus)); + nop->phy.otg->state = gpiod_get_value(nop->gpiod_vbus) ? OTG_STATE_B_PERIPHERAL : OTG_STATE_B_IDLE; } @@ -312,16 +293,13 @@ static int usb_phy_generic_probe(struct platform_device *pdev) nop->phy.shutdown = usb_gen_phy_shutdown; err = usb_add_phy_dev(&nop->phy); - if (err) { - dev_err(&pdev->dev, "can't register transceiver, err: %d\n", - err); - return err; - } + if (err) + return dev_err_probe(dev, err, "can't register transceiver\n"); platform_set_drvdata(pdev, nop); - device_set_wakeup_capable(&pdev->dev, - of_property_read_bool(dn, "wakeup-source")); + device_set_wakeup_capable(dev, + device_property_read_bool(dev, "wakeup-source")); return 0; } diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c index fb9031628d39..00443a7beaeb 100644 --- a/drivers/usb/phy/phy-tegra-usb.c +++ b/drivers/usb/phy/phy-tegra-usb.c @@ -29,17 +29,26 @@ #include #include +#define USB_TXFILLTUNING 0x154 +#define USB_FIFO_TXFILL_THRES(x) (((x) & 0x1f) << 16) +#define USB_FIFO_TXFILL_MASK 0x1f0000 + #define ULPI_VIEWPORT 0x170 /* PORTSC PTS/PHCD bits, Tegra20 only */ #define TEGRA_USB_PORTSC1 0x184 -#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) -#define TEGRA_USB_PORTSC1_PHCD BIT(23) +#define TEGRA_USB_PORTSC1_PTS(x) (((x) & 0x3) << 30) +#define TEGRA_USB_PORTSC1_PHCD BIT(23) +#define TEGRA_USB_PORTSC1_WKOC BIT(22) +#define TEGRA_USB_PORTSC1_WKDS BIT(21) +#define TEGRA_USB_PORTSC1_WKCN BIT(20) /* HOSTPC1 PTS/PHCD bits, Tegra30 and above */ +#define TEGRA30_USB_PORTSC1 0x174 #define TEGRA_USB_HOSTPC1_DEVLC 0x1b4 -#define TEGRA_USB_HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29) -#define TEGRA_USB_HOSTPC1_DEVLC_PHCD BIT(22) +#define TEGRA_USB_HOSTPC1_DEVLC_PTS(x) (((x) & 0x7) << 29) +#define TEGRA_USB_HOSTPC1_DEVLC_PHCD BIT(22) +#define TEGRA_USB_HOSTPC1_DEVLC_PTS_HSIC 4 /* Bits of PORTSC1, which will get cleared by writing 1 into them */ #define TEGRA_PORTSC1_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) @@ -51,11 +60,12 @@ #define USB_SUSP_CLR BIT(5) #define USB_PHY_CLK_VALID BIT(7) #define UTMIP_RESET BIT(11) -#define UHSIC_RESET BIT(11) #define UTMIP_PHY_ENABLE BIT(12) #define ULPI_PHY_ENABLE BIT(13) #define USB_SUSP_SET BIT(14) +#define UHSIC_RESET BIT(14) #define USB_WAKEUP_DEBOUNCE_COUNT(x) (((x) & 0x7) << 16) +#define UHSIC_PHY_ENABLE BIT(19) #define USB_PHY_VBUS_SENSORS 0x404 #define B_SESS_VLD_WAKEUP_EN BIT(14) @@ -156,6 +166,58 @@ #define UTMIP_BIAS_CFG1 0x83c #define UTMIP_BIAS_PDTRK_COUNT(x) (((x) & 0x1f) << 3) +/* + * Tegra20 has no UTMIP registers on PHY2 and UHSIC registers start from 0x800 + * just where UTMIP registers should have been. This is the case only with Tegra20 + * Tegra30+ have UTMIP registers at 0x800 and UHSIC registers are shifted by 0x400 + * to 0xc00, but register layout is preserved. + */ +#define UHSIC_PLL_CFG1 0x804 +#define UHSIC_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0) +#define UHSIC_PLLU_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 14) + +#define UHSIC_HSRX_CFG0 0x808 +#define UHSIC_ELASTIC_UNDERRUN_LIMIT(x) (((x) & 0x1f) << 2) +#define UHSIC_ELASTIC_OVERRUN_LIMIT(x) (((x) & 0x1f) << 8) +#define UHSIC_IDLE_WAIT(x) (((x) & 0x1f) << 13) + +#define UHSIC_HSRX_CFG1 0x80c +#define UHSIC_HS_SYNC_START_DLY(x) (((x) & 0x1f) << 1) + +#define UHSIC_TX_CFG0 0x810 +#define UHSIC_HS_READY_WAIT_FOR_VALID BIT(9) + +#define UHSIC_MISC_CFG0 0x814 +#define UHSIC_SUSPEND_EXIT_ON_EDGE BIT(7) +#define UHSIC_DETECT_SHORT_CONNECT BIT(8) +#define UHSIC_FORCE_XCVR_MODE BIT(15) +#define UHSIC_DISABLE_BUSRESET BIT(20) + +#define UHSIC_MISC_CFG1 0x818 +#define UHSIC_PLLU_STABLE_COUNT(x) (((x) & 0xfff) << 2) + +#define UHSIC_PADS_CFG0 0x81c +#define UHSIC_TX_RTUNEN 0xf000 +#define UHSIC_TX_RTUNE(x) (((x) & 0xf) << 12) + +#define UHSIC_PADS_CFG1 0x820 +#define UHSIC_PD_BG BIT(2) +#define UHSIC_PD_TX BIT(3) +#define UHSIC_PD_TRK BIT(4) +#define UHSIC_PD_RX BIT(5) +#define UHSIC_PD_ZI BIT(6) +#define UHSIC_RX_SEL BIT(7) +#define UHSIC_RPD_DATA BIT(9) +#define UHSIC_RPD_STROBE BIT(10) +#define UHSIC_RPU_DATA BIT(11) +#define UHSIC_RPU_STROBE BIT(12) + +#define UHSIC_CMD_CFG0 0x824 +#define UHSIC_PRETEND_CONNECT_DETECT BIT(5) + +#define UHSIC_STAT_CFG0 0x828 +#define UHSIC_CONNECT_DETECT BIT(0) + /* For Tegra30 and above only, the address is different in Tegra20 */ #define USB_USBMODE 0x1f8 #define USB_USBMODE_MASK (3 << 0) @@ -174,7 +236,8 @@ struct tegra_xtal_freq { u8 enable_delay; u8 stable_count; u8 active_delay; - u8 xtal_freq_count; + u8 utmi_xtal_freq_count; + u16 hsic_xtal_freq_count; u16 debounce; }; @@ -184,7 +247,8 @@ static const struct tegra_xtal_freq tegra_freq_table[] = { .enable_delay = 0x02, .stable_count = 0x2F, .active_delay = 0x04, - .xtal_freq_count = 0x76, + .utmi_xtal_freq_count = 0x76, + .hsic_xtal_freq_count = 0x1CA, .debounce = 0x7530, }, { @@ -192,7 +256,8 @@ static const struct tegra_xtal_freq tegra_freq_table[] = { .enable_delay = 0x02, .stable_count = 0x33, .active_delay = 0x05, - .xtal_freq_count = 0x7F, + .utmi_xtal_freq_count = 0x7F, + .hsic_xtal_freq_count = 0x1F0, .debounce = 0x7EF4, }, { @@ -200,7 +265,8 @@ static const struct tegra_xtal_freq tegra_freq_table[] = { .enable_delay = 0x03, .stable_count = 0x4B, .active_delay = 0x06, - .xtal_freq_count = 0xBB, + .utmi_xtal_freq_count = 0xBB, + .hsic_xtal_freq_count = 0x2DD, .debounce = 0xBB80, }, { @@ -208,7 +274,8 @@ static const struct tegra_xtal_freq tegra_freq_table[] = { .enable_delay = 0x04, .stable_count = 0x66, .active_delay = 0x09, - .xtal_freq_count = 0xFE, + .utmi_xtal_freq_count = 0xFE, + .hsic_xtal_freq_count = 0x3E0, .debounce = 0xFDE8, }, }; @@ -532,7 +599,7 @@ static int utmi_phy_power_on(struct tegra_usb_phy *phy) val = readl_relaxed(base + UTMIP_PLL_CFG1); val &= ~(UTMIP_XTAL_FREQ_COUNT(~0) | UTMIP_PLLU_ENABLE_DLY_COUNT(~0)); - val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->xtal_freq_count) | + val |= UTMIP_XTAL_FREQ_COUNT(phy->freq->utmi_xtal_freq_count) | UTMIP_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); writel_relaxed(val, base + UTMIP_PLL_CFG1); } @@ -803,17 +870,170 @@ static int ulpi_phy_power_off(struct tegra_usb_phy *phy) return 0; } +static u32 tegra_hsic_readl(struct tegra_usb_phy *phy, u32 reg) +{ + void __iomem *base = phy->regs; + u32 shift = phy->soc_config->uhsic_registers_offset; + + return readl_relaxed(base + shift + reg); +} + +static void tegra_hsic_writel(struct tegra_usb_phy *phy, u32 reg, u32 value) +{ + void __iomem *base = phy->regs; + u32 shift = phy->soc_config->uhsic_registers_offset; + + writel_relaxed(value, base + shift + reg); +} + +static int uhsic_phy_power_on(struct tegra_usb_phy *phy) +{ + struct tegra_utmip_config *config = phy->config; + void __iomem *base = phy->regs; + u32 val; + int err = 0; + + val = tegra_hsic_readl(phy, UHSIC_PADS_CFG1); + val &= ~(UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX | + UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE); + val |= UHSIC_RX_SEL; + tegra_hsic_writel(phy, UHSIC_PADS_CFG1, val); + + udelay(2); + + val = readl_relaxed(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel_relaxed(val, base + USB_SUSP_CTRL); + + udelay(30); + + val = readl_relaxed(base + USB_SUSP_CTRL); + val |= UHSIC_PHY_ENABLE; + writel_relaxed(val, base + USB_SUSP_CTRL); + + val = tegra_hsic_readl(phy, UHSIC_HSRX_CFG0); + val &= ~(UHSIC_IDLE_WAIT(~0) | + UHSIC_ELASTIC_UNDERRUN_LIMIT(~0) | + UHSIC_ELASTIC_OVERRUN_LIMIT(~0)); + val |= UHSIC_IDLE_WAIT(config->idle_wait_delay) | + UHSIC_ELASTIC_UNDERRUN_LIMIT(config->elastic_limit) | + UHSIC_ELASTIC_OVERRUN_LIMIT(config->elastic_limit); + tegra_hsic_writel(phy, UHSIC_HSRX_CFG0, val); + + val = tegra_hsic_readl(phy, UHSIC_HSRX_CFG1); + val &= ~UHSIC_HS_SYNC_START_DLY(~0); + val |= UHSIC_HS_SYNC_START_DLY(config->hssync_start_delay); + tegra_hsic_writel(phy, UHSIC_HSRX_CFG1, val); + + val = tegra_hsic_readl(phy, UHSIC_MISC_CFG0); + val |= UHSIC_SUSPEND_EXIT_ON_EDGE; + tegra_hsic_writel(phy, UHSIC_MISC_CFG0, val); + + val = tegra_hsic_readl(phy, UHSIC_MISC_CFG1); + val &= ~UHSIC_PLLU_STABLE_COUNT(~0); + val |= UHSIC_PLLU_STABLE_COUNT(phy->freq->stable_count); + tegra_hsic_writel(phy, UHSIC_MISC_CFG1, val); + + val = tegra_hsic_readl(phy, UHSIC_PLL_CFG1); + val &= ~(UHSIC_XTAL_FREQ_COUNT(~0) | + UHSIC_PLLU_ENABLE_DLY_COUNT(~0)); + val |= UHSIC_XTAL_FREQ_COUNT(phy->freq->hsic_xtal_freq_count) | + UHSIC_PLLU_ENABLE_DLY_COUNT(phy->freq->enable_delay); + tegra_hsic_writel(phy, UHSIC_PLL_CFG1, val); + + val = readl_relaxed(base + USB_SUSP_CTRL); + val &= ~UHSIC_RESET; + writel_relaxed(val, base + USB_SUSP_CTRL); + + udelay(2); + + if (phy->soc_config->requires_usbmode_setup) { + val = readl_relaxed(base + USB_USBMODE); + val &= ~USB_USBMODE_MASK; + if (phy->mode == USB_DR_MODE_HOST) + val |= USB_USBMODE_HOST; + else + val |= USB_USBMODE_DEVICE; + writel_relaxed(val, base + USB_USBMODE); + } + + set_pts(phy, phy->soc_config->uhsic_pts_value); + + val = readl_relaxed(base + USB_TXFILLTUNING); + if ((val & USB_FIFO_TXFILL_MASK) != USB_FIFO_TXFILL_THRES(0x10)) { + val = USB_FIFO_TXFILL_THRES(0x10); + writel_relaxed(val, base + USB_TXFILLTUNING); + } + + val = readl_relaxed(base + phy->soc_config->portsc1_offset); + val &= ~(TEGRA_USB_PORTSC1_WKOC | TEGRA_USB_PORTSC1_WKDS | + TEGRA_USB_PORTSC1_WKCN); + writel_relaxed(val, base + phy->soc_config->portsc1_offset); + + val = tegra_hsic_readl(phy, UHSIC_PADS_CFG0); + val &= ~UHSIC_TX_RTUNEN; + val |= UHSIC_TX_RTUNE(phy->soc_config->uhsic_tx_rtune); + tegra_hsic_writel(phy, UHSIC_PADS_CFG0, val); + + err = utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID); + + if (err) + dev_err(phy->u_phy.dev, + "Timeout waiting for PHY to stabilize on enable (HSIC)\n"); + + return err; +} + +static int uhsic_phy_power_off(struct tegra_usb_phy *phy) +{ + void __iomem *base = phy->regs; + u32 val; + + set_phcd(phy, true); + + val = tegra_hsic_readl(phy, UHSIC_PADS_CFG1); + val |= (UHSIC_PD_BG | UHSIC_PD_TX | UHSIC_PD_TRK | UHSIC_PD_RX | + UHSIC_PD_ZI | UHSIC_RPD_DATA | UHSIC_RPD_STROBE); + tegra_hsic_writel(phy, UHSIC_PADS_CFG1, val); + + val = readl_relaxed(base + USB_SUSP_CTRL); + val |= UHSIC_RESET; + writel_relaxed(val, base + USB_SUSP_CTRL); + + udelay(30); + + val = readl_relaxed(base + USB_SUSP_CTRL); + val &= ~UHSIC_PHY_ENABLE; + writel_relaxed(val, base + USB_SUSP_CTRL); + + return 0; +} + static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) { - int err; + int err = 0; if (phy->powered_on) return 0; - if (phy->is_ulpi_phy) - err = ulpi_phy_power_on(phy); - else + switch (phy->phy_type) { + case USBPHY_INTERFACE_MODE_UTMI: err = utmi_phy_power_on(phy); + break; + + case USBPHY_INTERFACE_MODE_ULPI: + err = ulpi_phy_power_on(phy); + break; + + case USBPHY_INTERFACE_MODE_HSIC: + err = uhsic_phy_power_on(phy); + break; + + default: + break; + } + if (err) return err; @@ -827,15 +1047,28 @@ static int tegra_usb_phy_power_on(struct tegra_usb_phy *phy) static int tegra_usb_phy_power_off(struct tegra_usb_phy *phy) { - int err; + int err = 0; if (!phy->powered_on) return 0; - if (phy->is_ulpi_phy) - err = ulpi_phy_power_off(phy); - else + switch (phy->phy_type) { + case USBPHY_INTERFACE_MODE_UTMI: err = utmi_phy_power_off(phy); + break; + + case USBPHY_INTERFACE_MODE_ULPI: + err = ulpi_phy_power_off(phy); + break; + + case USBPHY_INTERFACE_MODE_HSIC: + err = uhsic_phy_power_off(phy); + break; + + default: + break; + } + if (err) return err; @@ -854,7 +1087,7 @@ static void tegra_usb_phy_shutdown(struct usb_phy *u_phy) usb_phy_set_wakeup(u_phy, false); tegra_usb_phy_power_off(phy); - if (!phy->is_ulpi_phy) + if (phy->phy_type == USBPHY_INTERFACE_MODE_UTMI) utmip_pad_close(phy); regulator_disable(phy->vbus); @@ -1040,7 +1273,7 @@ static int tegra_usb_phy_init(struct usb_phy *u_phy) goto disable_clk; } - if (!phy->is_ulpi_phy) { + if (phy->phy_type == USBPHY_INTERFACE_MODE_UTMI) { err = utmip_pad_open(phy); if (err) goto disable_vbus; @@ -1057,7 +1290,7 @@ static int tegra_usb_phy_init(struct usb_phy *u_phy) return 0; close_phy: - if (!phy->is_ulpi_phy) + if (phy->phy_type == USBPHY_INTERFACE_MODE_UTMI) utmip_pad_close(phy); disable_vbus: @@ -1095,8 +1328,6 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, struct resource *res; int err; - tegra_phy->is_ulpi_phy = false; - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, "Failed to get UTMI pad regs\n"); @@ -1231,6 +1462,10 @@ static const struct tegra_phy_soc_config tegra20_soc_config = { .requires_usbmode_setup = false, .requires_extra_tuning_parameters = false, .requires_pmc_ao_power_up = false, + .uhsic_registers_offset = 0, + .uhsic_tx_rtune = 0, /* 40 ohm */ + .uhsic_pts_value = 0, /* UTMI */ + .portsc1_offset = TEGRA_USB_PORTSC1, }; static const struct tegra_phy_soc_config tegra30_soc_config = { @@ -1239,6 +1474,10 @@ static const struct tegra_phy_soc_config tegra30_soc_config = { .requires_usbmode_setup = true, .requires_extra_tuning_parameters = true, .requires_pmc_ao_power_up = true, + .uhsic_registers_offset = 0x400, + .uhsic_tx_rtune = 8, /* 50 ohm */ + .uhsic_pts_value = TEGRA_USB_HOSTPC1_DEVLC_PTS_HSIC, + .portsc1_offset = TEGRA30_USB_PORTSC1, }; static const struct of_device_id tegra_usb_phy_id_table[] = { @@ -1252,7 +1491,6 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct tegra_usb_phy *tegra_phy; - enum usb_phy_interface phy_type; struct reset_control *reset; struct gpio_desc *gpiod; struct resource *res; @@ -1314,9 +1552,10 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) return err; } - phy_type = of_usb_get_phy_mode(np); - switch (phy_type) { + tegra_phy->phy_type = of_usb_get_phy_mode(np); + switch (tegra_phy->phy_type) { case USBPHY_INTERFACE_MODE_UTMI: + case USBPHY_INTERFACE_MODE_HSIC: err = utmi_phy_probe(tegra_phy, pdev); if (err) return err; @@ -1341,8 +1580,6 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) break; case USBPHY_INTERFACE_MODE_ULPI: - tegra_phy->is_ulpi_phy = true; - tegra_phy->clk = devm_clk_get(&pdev->dev, "ulpi-link"); err = PTR_ERR_OR_ZERO(tegra_phy->clk); if (err) { @@ -1382,7 +1619,7 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) default: dev_err(&pdev->dev, "phy_type %u is invalid or unsupported\n", - phy_type); + tegra_phy->phy_type); return -EINVAL; } diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index cf4a0367d6d6..8c93bde4b816 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -815,6 +815,15 @@ static void usbhs_remove(struct platform_device *pdev) usbhs_platform_call(priv, hardware_exit, pdev); reset_control_assert(priv->rsts); + + /* + * Explicitly free the IRQ to ensure the interrupt handler is + * disabled and synchronized before freeing resources. + * devm_free_irq() calls free_irq() which waits for any running + * ISR to complete, preventing UAF. + */ + devm_free_irq(&pdev->dev, priv->irq, priv); + usbhs_mod_remove(priv); usbhs_fifo_remove(priv); usbhs_pipe_remove(priv); diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index e8e5723f5412..1539e8e6901d 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c @@ -325,7 +325,7 @@ static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, } /* alloc recip data buffer */ - buf = kmalloc(sizeof(*buf), GFP_ATOMIC); + buf = kmalloc_obj(*buf, GFP_ATOMIC); if (!buf) { usb_ep_free_request(&dcp->ep, req); return; @@ -661,7 +661,7 @@ static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, { struct usbhsg_request *ureq; - ureq = kzalloc(sizeof *ureq, gfp_flags); + ureq = kzalloc_obj(*ureq, gfp_flags); if (!ureq) return NULL; @@ -1084,11 +1084,11 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) int i; int ret; - gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); + gpriv = kzalloc_obj(struct usbhsg_gpriv); if (!gpriv) return -ENOMEM; - uep = kcalloc(pipe_size, sizeof(struct usbhsg_uep), GFP_KERNEL); + uep = kzalloc_objs(struct usbhsg_uep, pipe_size); if (!uep) { ret = -ENOMEM; goto usbhs_mod_gadget_probe_err_gpriv; diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index ae54221011c3..f7ef3a9f82a4 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c @@ -158,7 +158,7 @@ static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, { struct usbhsh_request *ureq; - ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); + ureq = kzalloc_obj(struct usbhsh_request, mem_flags); if (!ureq) return NULL; @@ -374,7 +374,7 @@ static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, struct usb_endpoint_descriptor *desc = &ep->desc; unsigned long flags; - uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); + uep = kzalloc_obj(struct usbhsh_ep, mem_flags); if (!uep) return -ENOMEM; diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index 56fc3ff5016f..e4e897e8256f 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c @@ -822,8 +822,7 @@ int usbhs_pipe_probe(struct usbhs_priv *priv) return -EINVAL; } - info->pipe = kcalloc(pipe_size, sizeof(struct usbhs_pipe), - GFP_KERNEL); + info->pipe = kzalloc_objs(struct usbhs_pipe, pipe_size); if (!info->pipe) return -ENOMEM; diff --git a/drivers/usb/roles/class.c b/drivers/usb/roles/class.c index 30482d4cf826..edec139b68b5 100644 --- a/drivers/usb/roles/class.c +++ b/drivers/usb/roles/class.c @@ -139,9 +139,14 @@ static void *usb_role_switch_match(const struct fwnode_handle *fwnode, const cha static struct usb_role_switch * usb_role_switch_is_parent(struct fwnode_handle *fwnode) { - struct fwnode_handle *parent = fwnode_get_parent(fwnode); + struct fwnode_handle *parent; struct device *dev; + if (!fwnode_device_is_compatible(fwnode, "usb-b-connector")) + return NULL; + + parent = fwnode_get_parent(fwnode); + if (!fwnode_property_present(parent, "usb-role-switch")) { fwnode_handle_put(parent); return NULL; @@ -364,7 +369,7 @@ usb_role_switch_register(struct device *parent, if (!desc || !desc->set) return ERR_PTR(-EINVAL); - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = kzalloc_obj(*sw); if (!sw) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 800b04fe37fa..d974da43fba3 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -126,7 +126,7 @@ static int ark3116_port_probe(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct ark3116_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 5c41c1c82c3f..38ac910b1082 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -114,7 +114,7 @@ static int belkin_sa_port_probe(struct usb_serial_port *port) struct usb_device *dev = port->serial->dev; struct belkin_sa_private *priv; - priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); + priv = kmalloc_obj(struct belkin_sa_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index 7cc36f84821f..569f4aede215 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c @@ -381,7 +381,7 @@ static int ch341_port_probe(struct usb_serial_port *port) struct ch341_private *priv; int r; - priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); + priv = kzalloc_obj(struct ch341_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index c3ea3a46ed76..29f09190846e 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c @@ -133,7 +133,7 @@ static int usb_console_setup(struct console *co, char *options) * the termios structure, then later call set_termios to * configure according to command line arguments */ - tty = kzalloc(sizeof(*tty), GFP_KERNEL); + tty = kzalloc_obj(*tty); if (!tty) { retval = -ENOMEM; goto reset_open_count; diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 36b25418b214..333b8b463704 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -2006,7 +2006,7 @@ static int cp210x_port_probe(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct cp210x_port_private *port_priv; - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); + port_priv = kzalloc_obj(*port_priv); if (!port_priv) return -ENOMEM; @@ -2163,7 +2163,7 @@ static int cp210x_attach(struct usb_serial *serial) int result; struct cp210x_serial_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 76dd8e7453b5..4e8ceb23c27d 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -101,7 +101,7 @@ static int cyberjack_port_probe(struct usb_serial_port *port) struct cyberjack_private *priv; int result; - priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); + priv = kmalloc_obj(struct cyberjack_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index e29569d65991..afff1a0f4298 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -445,7 +445,7 @@ static int cypress_generic_port_probe(struct usb_serial_port *port) return -ENODEV; } - priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); + priv = kzalloc_obj(struct cypress_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index a06485965412..d515df045c4c 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c @@ -1209,7 +1209,7 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num) { struct digi_port *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -1231,7 +1231,7 @@ static int digi_startup(struct usb_serial *serial) struct digi_serial *serial_priv; int ret; - serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); + serial_priv = kzalloc_obj(*serial_priv); if (!serial_priv) return -ENOMEM; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index acb48b1c83f7..af14548fa03d 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -2188,7 +2188,7 @@ static int ftdi_port_probe(struct usb_serial_port *port) struct ftdi_private *priv; int result; - priv = kzalloc(sizeof(struct ftdi_private), GFP_KERNEL); + priv = kzalloc_obj(struct ftdi_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 614de0c2f5f2..7205483a0115 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -267,7 +267,7 @@ static int pkt_add(struct garmin_data *garmin_data_p, /* process only packets containing data ... */ if (data_length) { - pkt = kmalloc(struct_size(pkt, data, data_length), GFP_ATOMIC); + pkt = kmalloc_flex(*pkt, data, data_length, GFP_ATOMIC); if (!pkt) return 0; @@ -1373,7 +1373,7 @@ static int garmin_port_probe(struct usb_serial_port *port) int status; struct garmin_data *garmin_data_p; - garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); + garmin_data_p = kzalloc_obj(struct garmin_data); if (!garmin_data_p) return -ENOMEM; diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 1fffda7647f9..58694b8943d1 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -498,7 +498,7 @@ static int get_epic_descriptor(struct edgeport_serial *ep) ep->is_epic = 0; - epic = kmalloc(sizeof(*epic), GFP_KERNEL); + epic = kmalloc_obj(*epic); if (!epic) return -ENOMEM; @@ -2714,7 +2714,7 @@ static int edge_startup(struct usb_serial *serial) dev = serial->dev; /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + edge_serial = kzalloc_obj(struct edgeport_serial); if (!edge_serial) return -ENOMEM; @@ -2956,7 +2956,7 @@ static int edge_port_probe(struct usb_serial_port *port) { struct edgeport_port *edge_port; - edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + edge_port = kzalloc_obj(*edge_port); if (!edge_port) return -ENOMEM; diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 7d0584b2a234..cb55370e036f 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -528,7 +528,7 @@ static int tx_active(struct edgeport_port *port) u8 *lsr; int bytes_left = 0; - oedb = kmalloc(sizeof(*oedb), GFP_KERNEL); + oedb = kmalloc_obj(*oedb); if (!oedb) return -ENOMEM; @@ -680,7 +680,7 @@ static int check_i2c_image(struct edgeport_serial *serial) u8 *buffer; u16 ttype; - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); + rom_desc = kmalloc_obj(*rom_desc); if (!rom_desc) return -ENOMEM; @@ -759,7 +759,7 @@ static int get_manuf_info(struct edgeport_serial *serial, u8 *buffer) struct edge_ti_manuf_descriptor *desc; struct device *dev = &serial->serial->dev->dev; - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); + rom_desc = kmalloc_obj(*rom_desc); if (!rom_desc) return -ENOMEM; @@ -1089,7 +1089,7 @@ static int do_download_mode(struct edgeport_serial *serial, * Validate Hardware version number * Read Manufacturing Descriptor from TI Based Edgeport */ - ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL); + ti_manuf_desc = kmalloc_obj(*ti_manuf_desc); if (!ti_manuf_desc) return -ENOMEM; @@ -1107,7 +1107,7 @@ static int do_download_mode(struct edgeport_serial *serial, return -EINVAL; } - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); + rom_desc = kmalloc_obj(*rom_desc); if (!rom_desc) { kfree(ti_manuf_desc); return -ENOMEM; @@ -1123,8 +1123,7 @@ static int do_download_mode(struct edgeport_serial *serial, dev_dbg(dev, "%s - Found Type FIRMWARE (Type 2) record\n", __func__); - firmware_version = kmalloc(sizeof(*firmware_version), - GFP_KERNEL); + firmware_version = kmalloc_obj(*firmware_version); if (!firmware_version) { kfree(rom_desc); kfree(ti_manuf_desc); @@ -1419,7 +1418,7 @@ static int do_boot_mode(struct edgeport_serial *serial, * Validate Hardware version number * Read Manufacturing Descriptor from TI Based Edgeport */ - ti_manuf_desc = kmalloc(sizeof(*ti_manuf_desc), GFP_KERNEL); + ti_manuf_desc = kmalloc_obj(*ti_manuf_desc); if (!ti_manuf_desc) return -ENOMEM; @@ -2219,7 +2218,7 @@ static void change_port_settings(struct tty_struct *tty, unsigned cflag; int status; - config = kmalloc (sizeof (*config), GFP_KERNEL); + config = kmalloc_obj(*config); if (!config) { tty->termios = *old_termios; return; @@ -2458,7 +2457,7 @@ static void edge_heartbeat_work(struct work_struct *work) serial = container_of(work, struct edgeport_serial, heartbeat_work.work); - rom_desc = kmalloc(sizeof(*rom_desc), GFP_KERNEL); + rom_desc = kmalloc_obj(*rom_desc); /* Descriptor address request is enough to reset the firmware timer */ if (!rom_desc || !get_descriptor_addr(serial, I2C_DESC_TYPE_ION, @@ -2497,7 +2496,7 @@ static int edge_startup(struct usb_serial *serial) u16 product_id; /* create our private serial structure */ - edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); + edge_serial = kzalloc_obj(struct edgeport_serial); if (!edge_serial) return -ENOMEM; @@ -2551,7 +2550,7 @@ static int edge_port_probe(struct usb_serial_port *port) struct edgeport_port *edge_port; int ret; - edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + edge_port = kzalloc_obj(*edge_port); if (!edge_port) return -ENOMEM; diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index b1e672c2f423..83709d678b3a 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c @@ -198,7 +198,7 @@ static int ipw_attach(struct usb_serial *serial) { struct usb_wwan_intf_private *data; - data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + data = kzalloc_obj(struct usb_wwan_intf_private); if (!data) return -ENOMEM; diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index a106b71e698f..12e928d25ba1 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c @@ -126,7 +126,7 @@ irda_usb_find_class_desc(struct usb_serial *serial, unsigned int ifnum) struct usb_irda_cs_descriptor *desc; int ret; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return NULL; diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index c21dcc9b6f05..f8d6aa30a3e1 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -67,7 +67,7 @@ static int iuu_port_probe(struct usb_serial_port *port) struct iuu_private *priv; int ret; - priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); + priv = kzalloc_obj(struct iuu_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9129e0282c24..46448843541a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -2789,7 +2789,7 @@ static int keyspan_startup(struct usb_serial *serial) } /* Setup private data for serial driver */ - s_priv = kzalloc(sizeof(struct keyspan_serial_private), GFP_KERNEL); + s_priv = kzalloc_obj(struct keyspan_serial_private); if (!s_priv) return -ENOMEM; @@ -2886,7 +2886,7 @@ static int keyspan_port_probe(struct usb_serial_port *port) s_priv = usb_get_serial_data(serial); d_details = s_priv->device_details; - p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); + p_priv = kzalloc_obj(*p_priv); if (!p_priv) return -ENOMEM; diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index e98b479593d3..5036600dd334 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -654,7 +654,7 @@ static int keyspan_pda_port_probe(struct usb_serial_port *port) struct keyspan_pda_private *priv; - priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); + priv = kmalloc_obj(struct keyspan_pda_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index d36155b6d2bf..ed8531a64768 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -189,7 +189,7 @@ static int klsi_105_port_probe(struct usb_serial_port *port) { struct klsi_105_private *priv; - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -378,7 +378,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, unsigned long flags; speed_t baud; - cfg = kmalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kmalloc_obj(*cfg); if (!cfg) return; diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 3a1343d88386..6126afd67a7b 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -130,7 +130,7 @@ static int kobil_port_probe(struct usb_serial_port *port) struct usb_serial *serial = port->serial; struct kobil_private *priv; - priv = kmalloc(sizeof(struct kobil_private), GFP_KERNEL); + priv = kmalloc_obj(struct kobil_private); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2bce8cc03aca..18844b92bd08 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c @@ -385,7 +385,7 @@ static int mct_u232_port_probe(struct usb_serial_port *port) return -ENODEV; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 028878292901..bc834cc48550 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c @@ -245,7 +245,7 @@ static int metrousb_port_probe(struct usb_serial_port *port) { struct metrousb_private *metro_priv; - metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); + metro_priv = kzalloc_obj(*metro_priv); if (!metro_priv) return -ENOMEM; diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index e59bfa7c8030..94459408e7fb 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -555,7 +555,7 @@ static int mos7715_parport_init(struct usb_serial *serial) struct mos7715_parport *mos_parport; /* allocate and initialize parallel port control struct */ - mos_parport = kzalloc(sizeof(struct mos7715_parport), GFP_KERNEL); + mos_parport = kzalloc_obj(struct mos7715_parport); if (!mos_parport) return -ENOMEM; @@ -1703,7 +1703,7 @@ static int mos7720_port_probe(struct usb_serial_port *port) { struct moschip_port *mos7720_port; - mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); + mos7720_port = kzalloc_obj(*mos7720_port); if (!mos7720_port) return -ENOMEM; diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 9e9aca271c0a..c0d0c24b074b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -1532,7 +1532,7 @@ static int mos7840_port_probe(struct usb_serial_port *port) pnum = port->port_number; dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum); - mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); + mos7840_port = kzalloc_obj(struct moschip_port); if (!mos7840_port) return -ENOMEM; @@ -1677,8 +1677,7 @@ static int mos7840_port_probe(struct usb_serial_port *port) /* Initialize LED timers */ if (mos7840_port->has_led) { mos7840_port->led_urb = usb_alloc_urb(0, GFP_KERNEL); - mos7840_port->led_dr = kmalloc(sizeof(*mos7840_port->led_dr), - GFP_KERNEL); + mos7840_port->led_dr = kmalloc_obj(*mos7840_port->led_dr); if (!mos7840_port->led_urb || !mos7840_port->led_dr) { status = -ENOMEM; goto error; diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 397ebd5a3e74..aa1e9745f967 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -113,7 +113,7 @@ static int omninet_port_probe(struct usb_serial_port *port) { struct omninet_data *od; - od = kzalloc(sizeof(*od), GFP_KERNEL); + od = kzalloc_obj(*od); if (!od) return -ENOMEM; diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 1ee84ccc4bbd..e2bed477ad57 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c @@ -220,7 +220,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, /* The connected devices do not have a bulk write endpoint, * to transmit data to de barcode device the control endpoint is used */ - dr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC); + dr = kmalloc_obj(struct usb_ctrlrequest, GFP_ATOMIC); if (!dr) goto error_no_dr; @@ -354,7 +354,7 @@ static int opticon_port_probe(struct usb_serial_port *port) { struct opticon_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9f2cc5fb9f45..e349ed66d2ac 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -1401,12 +1401,16 @@ static const struct usb_device_id option_ids[] = { .driver_info = NCTRL(0) | RSVD(1) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a0, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a1, 0xff), /* Telit FN20C04 (RNDIS) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a2, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a3, 0xff), /* Telit FN920C04 (ECM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a4, 0xff), /* Telit FN20C04 (rmnet) */ .driver_info = RSVD(0) | NCTRL(3) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a6, 0xff), /* Telit FN920C04 (RNDIS) */ + .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a7, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10a8, 0xff), /* Telit FN920C04 (ECM) */ @@ -1415,6 +1419,8 @@ static const struct usb_device_id option_ids[] = { .driver_info = RSVD(0) | NCTRL(2) | RSVD(3) | RSVD(4) }, { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10aa, 0xff), /* Telit FN920C04 (MBIM) */ .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, 0x10ab, 0xff), /* Telit FN920C04 (RNDIS) */ + .driver_info = NCTRL(3) | RSVD(4) | RSVD(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x30), /* Telit FE990B (rmnet) */ .driver_info = NCTRL(5) }, { USB_DEVICE_AND_INTERFACE_INFO(TELIT_VENDOR_ID, 0x10b0, 0xff, 0xff, 0x40) }, @@ -2600,7 +2606,7 @@ static int option_attach(struct usb_serial *serial) struct usb_wwan_intf_private *data; unsigned long device_flags; - data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); + data = kzalloc_obj(struct usb_wwan_intf_private); if (!data) return -ENOMEM; diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index bd206cb9cc08..3ef5b5d8ce1a 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -328,7 +328,7 @@ static int oti6858_port_probe(struct usb_serial_port *port) { struct oti6858_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 22579d0d8ab8..50dc838e8115 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -503,7 +503,7 @@ static int pl2303_startup(struct usb_serial *serial) type = ret; dev_dbg(&serial->interface->dev, "device type: %s\n", pl2303_type_data[type].name); - spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); + spriv = kzalloc_obj(*spriv); if (!spriv) return -ENOMEM; @@ -555,7 +555,7 @@ static int pl2303_port_probe(struct usb_serial_port *port) { struct pl2303_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 13c664317a05..1a930dc668e4 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -431,7 +431,7 @@ static int qc_attach(struct usb_serial *serial) struct usb_wwan_intf_private *data; bool sendsetup; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 72fe83a6c978..b05c655b3cc4 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -626,7 +626,7 @@ static int qt2_attach(struct usb_serial *serial) return status; } - serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); + serial_priv = kzalloc_obj(*serial_priv); if (!serial_priv) return -ENOMEM; @@ -657,7 +657,7 @@ static int qt2_port_probe(struct usb_serial_port *port) struct qt2_port_private *port_priv; u8 bEndpointAddress; - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); + port_priv = kzalloc_obj(*port_priv); if (!port_priv) return -ENOMEM; diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 741e68e46139..6e443aacae07 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -828,7 +828,7 @@ static int sierra_startup(struct usb_serial *serial) { struct sierra_intf_private *intfdata; - intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); + intfdata = kzalloc_obj(*intfdata); if (!intfdata) return -ENOMEM; @@ -861,7 +861,7 @@ static int sierra_port_probe(struct usb_serial_port *port) const struct sierra_iface_list *himemory_list; u8 ifnum; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + portdata = kzalloc_obj(*portdata); if (!portdata) return -ENOMEM; diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 11077beb7232..2fbb48f19efd 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -145,7 +145,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port) const struct usb_device_id *id = usb_get_serial_data(port->serial); struct spcp8x5_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index df21009bdf42..da6316410b77 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -326,7 +326,7 @@ static int ssu100_port_probe(struct usb_serial_port *port) { struct ssu100_port_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c index 58962bcbf9ba..7a5aa39172a8 100644 --- a/drivers/usb/serial/symbolserial.c +++ b/drivers/usb/serial/symbolserial.c @@ -149,7 +149,7 @@ static int symbol_port_probe(struct usb_serial_port *port) { struct symbol_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index d671189ecee2..658b54d8fcef 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -519,7 +519,7 @@ static int ti_startup(struct usb_serial *serial) dev->descriptor.bNumConfigurations, dev->actconfig->desc.bConfigurationValue); - tdev = kzalloc(sizeof(struct ti_device), GFP_KERNEL); + tdev = kzalloc_obj(struct ti_device); if (!tdev) return -ENOMEM; @@ -598,7 +598,7 @@ static int ti_port_probe(struct usb_serial_port *port) { struct ti_port *tport; - tport = kzalloc(sizeof(*tport), GFP_KERNEL); + tport = kzalloc_obj(*tport); if (!tport) return -ENOMEM; @@ -897,7 +897,7 @@ static void ti_set_termios(struct tty_struct *tty, u16 wbaudrate; u16 wflags = 0; - config = kmalloc(sizeof(*config), GFP_KERNEL); + config = kmalloc_obj(*config); if (!config) return; diff --git a/drivers/usb/serial/upd78f0730.c b/drivers/usb/serial/upd78f0730.c index 15a17bf111f1..78c4d3c19a8e 100644 --- a/drivers/usb/serial/upd78f0730.c +++ b/drivers/usb/serial/upd78f0730.c @@ -161,7 +161,7 @@ static int upd78f0730_port_probe(struct usb_serial_port *port) { struct upd78f0730_port_private *private; - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (!private) return -ENOMEM; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index c78ff40b1e5f..0e072fd87c3d 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -688,7 +688,7 @@ static struct usb_serial *create_serial(struct usb_device *dev, { struct usb_serial *serial; - serial = kzalloc(sizeof(*serial), GFP_KERNEL); + serial = kzalloc_obj(*serial); if (!serial) return NULL; serial->dev = usb_get_dev(dev); @@ -1005,7 +1005,7 @@ static int usb_serial_probe(struct usb_interface *interface, } /* descriptor matches, let's find the endpoints needed */ - epds = kzalloc(sizeof(*epds), GFP_KERNEL); + epds = kzalloc_obj(*epds); if (!epds) { retval = -ENOMEM; goto err_release_sibling; @@ -1059,7 +1059,7 @@ static int usb_serial_probe(struct usb_interface *interface, dev_dbg(ddev, "setting up %d port structure(s)\n", max_endpoints); for (i = 0; i < max_endpoints; ++i) { - port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); + port = kzalloc_obj(struct usb_serial_port); if (!port) { retval = -ENOMEM; goto err_free_epds; @@ -1482,7 +1482,7 @@ int __usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers * Suspend/resume support is implemented in the usb-serial core, * so fill in the PM-related fields in udriver. */ - udriver = kzalloc(sizeof(*udriver), GFP_KERNEL); + udriver = kzalloc_obj(*udriver); if (!udriver) return -ENOMEM; diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 0017f6e969e1..e752ffa4dc62 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c @@ -449,7 +449,7 @@ int usb_wwan_port_probe(struct usb_serial_port *port) if (!port->bulk_in_size || !port->bulk_out_size) return -ENODEV; - portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); + portdata = kzalloc_obj(*portdata); if (!portdata) return -ENOMEM; diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 009faeb2ef55..6e2b52b2b5f8 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c @@ -278,8 +278,7 @@ static int whiteheat_attach(struct usb_serial *serial) serial->type->description, hw_info->sw_major_rev, hw_info->sw_minor_rev); - command_info = kmalloc(sizeof(struct whiteheat_command_private), - GFP_KERNEL); + command_info = kmalloc_obj(struct whiteheat_command_private); if (!command_info) goto no_command_private; @@ -330,7 +329,7 @@ static int whiteheat_port_probe(struct usb_serial_port *port) { struct whiteheat_private *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/drivers/usb/serial/xr_serial.c b/drivers/usb/serial/xr_serial.c index 4186e791b384..9fc4082de770 100644 --- a/drivers/usb/serial/xr_serial.c +++ b/drivers/usb/serial/xr_serial.c @@ -756,7 +756,7 @@ static void xr_cdc_set_line_coding(struct tty_struct *tty, struct usb_cdc_line_coding *lc; int ret; - lc = kzalloc(sizeof(*lc), GFP_KERNEL); + lc = kzalloc_obj(*lc); if (!lc) return; @@ -1020,7 +1020,7 @@ static int xr_port_probe(struct usb_serial_port *port) type_id = (int)(unsigned long)usb_get_serial_data(port->serial); type = &xr_types[type_id]; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index e01f3a42bde4..691fe47009cf 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -1113,7 +1113,7 @@ static int init_alauda(struct us_data *us) struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; nand_init_ecc(); - us->extra = kzalloc(sizeof(struct alauda_info), GFP_NOIO); + us->extra = kzalloc_obj(struct alauda_info, GFP_NOIO); if (!us->extra) return -ENOMEM; diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 9ba369483c9b..0ded8ef72efa 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -555,7 +555,7 @@ static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) }; if (!us->extra) { - us->extra = kzalloc(sizeof(struct datafab_info), GFP_NOIO); + us->extra = kzalloc_obj(struct datafab_info, GFP_NOIO); if (!us->extra) return USB_STOR_TRANSPORT_ERROR; diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index ce91fb105975..8770de01a384 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -1119,9 +1119,8 @@ static int ms_lib_alloc_writebuf(struct us_data *us) info->MS_Lib.blkpag = kmalloc_array(info->MS_Lib.PagesPerBlock, info->MS_Lib.BytesPerSector, GFP_KERNEL); - info->MS_Lib.blkext = kmalloc_array(info->MS_Lib.PagesPerBlock, - sizeof(struct ms_lib_type_extdat), - GFP_KERNEL); + info->MS_Lib.blkext = kmalloc_objs(struct ms_lib_type_extdat, + info->MS_Lib.PagesPerBlock); if ((info->MS_Lib.blkpag == NULL) || (info->MS_Lib.blkext == NULL)) { ms_lib_free_writebuf(us); @@ -2336,7 +2335,7 @@ static int ene_ub6250_probe(struct usb_interface *intf, return result; /* FIXME: where should the code alloc extra buf ? */ - us->extra = kzalloc(sizeof(struct ene_ub6250_info), GFP_KERNEL); + us->extra = kzalloc_obj(struct ene_ub6250_info); if (!us->extra) return -ENOMEM; us->extra_destructor = ene_ub6250_info_destructor; diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index a1669c35bad5..a4fd5dda3396 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1463,7 +1463,7 @@ static int isd200_init_info(struct us_data *us) { struct isd200_info *info; - info = kzalloc(sizeof(struct isd200_info), GFP_KERNEL); + info = kzalloc_obj(struct isd200_info); if (!info) return -ENOMEM; diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 089c6f8ac85f..a9c48091491e 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -482,7 +482,7 @@ static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us) }; if (!us->extra) { - us->extra = kzalloc(sizeof(struct jumpshot_info), GFP_NOIO); + us->extra = kzalloc_obj(struct jumpshot_info, GFP_NOIO); if (!us->extra) return USB_STOR_TRANSPORT_ERROR; diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 341d6839548a..5f199c21bb0c 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -174,7 +174,7 @@ static void rio_karma_destructor(void *extra) static int rio_karma_init(struct us_data *us) { - struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); + struct karma_data *data = kzalloc_obj(struct karma_data, GFP_NOIO); if (!data) return -ENOMEM; diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 5a8a1ffda0ec..49d281f7bef6 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -183,7 +183,7 @@ static int onetouch_connect_input(struct us_data *ss) maxp = usb_maxpacket(udev, pipe); maxp = min(maxp, ONETOUCH_PKT_LEN); - onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); + onetouch = kzalloc_obj(struct usb_onetouch); input_dev = input_allocate_device(); if (!onetouch || !input_dev) goto fail1; diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 3cc243956fd4..af038b897c6b 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -976,7 +976,7 @@ static int init_realtek_cr(struct us_data *us) struct rts51x_chip *chip; int size, i, retval; - chip = kzalloc(sizeof(struct rts51x_chip), GFP_KERNEL); + chip = kzalloc_obj(struct rts51x_chip); if (!chip) return -ENOMEM; diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index e66b920e99e2..3d45e1b54c66 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1232,8 +1232,8 @@ sddr09_read_map(struct us_data *us) { kfree(info->lba_to_pba); kfree(info->pba_to_lba); - info->lba_to_pba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); - info->pba_to_lba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); + info->lba_to_pba = kmalloc_objs(int, numblocks, GFP_NOIO); + info->pba_to_lba = kmalloc_objs(int, numblocks, GFP_NOIO); if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { printk(KERN_WARNING "sddr09_read_map: out of memory\n"); @@ -1428,7 +1428,7 @@ sddr09_common_init(struct us_data *us) { return -EINVAL; } - us->extra = kzalloc(sizeof(struct sddr09_card_info), GFP_NOIO); + us->extra = kzalloc_obj(struct sddr09_card_info, GFP_NOIO); if (!us->extra) return -ENOMEM; us->extra_destructor = sddr09_card_info_destructor; diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 9d813727e65f..e05e824cd4d1 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -691,8 +691,8 @@ static int sddr55_read_map(struct us_data *us) { kfree(info->lba_to_pba); kfree(info->pba_to_lba); - info->lba_to_pba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); - info->pba_to_lba = kmalloc_array(numblocks, sizeof(int), GFP_NOIO); + info->lba_to_pba = kmalloc_objs(int, numblocks, GFP_NOIO); + info->pba_to_lba = kmalloc_objs(int, numblocks, GFP_NOIO); if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { kfree(info->lba_to_pba); @@ -799,8 +799,7 @@ static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) struct sddr55_card_info *info; if (!us->extra) { - us->extra = kzalloc( - sizeof(struct sddr55_card_info), GFP_NOIO); + us->extra = kzalloc_obj(struct sddr55_card_info, GFP_NOIO); if (!us->extra) return USB_STOR_TRANSPORT_ERROR; us->extra_destructor = sddr55_card_info_destructor; diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 27faa0ead11d..7e5424268c73 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1454,7 +1454,7 @@ static int init_usbat(struct us_data *us, int devicetype) unsigned char subcountL = USBAT_ATA_LBA_ME; unsigned char *status = us->iobuf; - us->extra = kzalloc(sizeof(struct usbat_info), GFP_NOIO); + us->extra = kzalloc_obj(struct usbat_info, GFP_NOIO); if (!us->extra) return -ENOMEM; diff --git a/drivers/usb/storage/sierra_ms.c b/drivers/usb/storage/sierra_ms.c index 177fa6cd143a..c5e3eeeb2144 100644 --- a/drivers/usb/storage/sierra_ms.c +++ b/drivers/usb/storage/sierra_ms.c @@ -100,7 +100,7 @@ static ssize_t truinst_show(struct device *dev, struct device_attribute *attr, if (swi_tru_install == TRU_FORCE_MS) { result = sysfs_emit(buf, "Forced Mass Storage\n"); } else { - swocInfo = kmalloc(sizeof(struct swoc_info), GFP_KERNEL); + swocInfo = kmalloc_obj(struct swoc_info); if (!swocInfo) { sysfs_emit(buf, "Error\n"); return -ENOMEM; @@ -149,8 +149,7 @@ int sierra_ms_init(struct us_data *us) else { usb_stor_dbg(us, "SWIMS: Normal SWoC Logic\n"); - swocInfo = kmalloc(sizeof(struct swoc_info), - GFP_KERNEL); + swocInfo = kmalloc_obj(struct swoc_info); if (!swocInfo) return -ENOMEM; diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index ac3c0b919fdd..0a9902d2b118 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -480,7 +480,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, if (!urb) goto out; - iu = kzalloc(sizeof(*iu), gfp); + iu = kzalloc_obj(*iu, gfp); if (!iu) goto free; diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 152ee3376550..fa83fe0defe2 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -537,7 +537,7 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) usb_set_intfdata(intf, us); /* Allocate the control/setup and DMA-mapped buffers */ - us->cr = kmalloc(sizeof(*us->cr), GFP_KERNEL); + us->cr = kmalloc_obj(*us->cr); if (!us->cr) return -ENOMEM; diff --git a/drivers/usb/typec/Makefile b/drivers/usb/typec/Makefile index 7a368fea61bc..8a6a1c663eb6 100644 --- a/drivers/usb/typec/Makefile +++ b/drivers/usb/typec/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_TYPEC) += typec.o -typec-y := class.o mux.o bus.o pd.o retimer.o +typec-y := class.o mux.o bus.o pd.o retimer.o mode_selection.o typec-$(CONFIG_ACPI) += port-mapper.o obj-$(CONFIG_TYPEC) += altmodes/ obj-$(CONFIG_TYPEC_TCPM) += tcpm/ diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index d96ab106a980..35d9c3086990 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -100,9 +100,14 @@ static int dp_altmode_configure(struct dp_altmode *dp, u8 con) { u8 pin_assign = 0; u32 conf; + u32 signal; /* DP Signalling */ - conf = (dp->data.conf & DP_CONF_SIGNALLING_MASK) >> DP_CONF_SIGNALLING_SHIFT; + signal = DP_CAP_DP_SIGNALLING(dp->port->vdo) & DP_CAP_DP_SIGNALLING(dp->alt->vdo); + if (dp->plug_prime) + signal &= DP_CAP_DP_SIGNALLING(dp->plug_prime->vdo); + + conf = signal << DP_CONF_SIGNALLING_SHIFT; switch (con) { case DP_STATUS_CON_DISABLED: @@ -804,8 +809,10 @@ int dp_altmode_probe(struct typec_altmode *alt) if (plug) typec_altmode_set_drvdata(plug, dp); - dp->state = plug ? DP_STATE_ENTER_PRIME : DP_STATE_ENTER; - schedule_work(&dp->work); + if (!alt->mode_selection) { + dp->state = plug ? DP_STATE_ENTER_PRIME : DP_STATE_ENTER; + schedule_work(&dp->work); + } return 0; } diff --git a/drivers/usb/typec/altmodes/thunderbolt.c b/drivers/usb/typec/altmodes/thunderbolt.c index 6eadf7835f8f..c4c5da6154da 100644 --- a/drivers/usb/typec/altmodes/thunderbolt.c +++ b/drivers/usb/typec/altmodes/thunderbolt.c @@ -307,7 +307,7 @@ static int tbt_altmode_probe(struct typec_altmode *alt) typec_altmode_set_drvdata(alt, tbt); typec_altmode_set_ops(alt, &tbt_altmode_ops); - if (tbt_ready(alt)) { + if (!alt->mode_selection && tbt_ready(alt)) { if (tbt->plug[TYPEC_PLUG_SOP_P]) tbt->state = TBT_STATE_SOP_P_ENTER; else if (tbt->plug[TYPEC_PLUG_SOP_PP]) diff --git a/drivers/usb/typec/bus.c b/drivers/usb/typec/bus.c index a884cec9ab7e..e84b134a3381 100644 --- a/drivers/usb/typec/bus.c +++ b/drivers/usb/typec/bus.c @@ -445,7 +445,23 @@ static struct attribute *typec_attrs[] = { &dev_attr_description.attr, NULL }; -ATTRIBUTE_GROUPS(typec); + +static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n) +{ + if (is_typec_partner_altmode(kobj_to_dev(kobj))) + return attr->mode; + return 0; +} + +static const struct attribute_group typec_group = { + .is_visible = typec_is_visible, + .attrs = typec_attrs, +}; + +static const struct attribute_group *typec_groups[] = { + &typec_group, + NULL +}; static int typec_match(struct device *dev, const struct device_driver *driver) { @@ -453,6 +469,9 @@ static int typec_match(struct device *dev, const struct device_driver *driver) struct typec_altmode *altmode = to_typec_altmode(dev); const struct typec_device_id *id; + if (!is_typec_partner_altmode(dev)) + return 0; + for (id = drv->id_table; id->svid; id++) if (id->svid == altmode->svid) return 1; @@ -463,6 +482,9 @@ static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env) { const struct typec_altmode *altmode = to_typec_altmode(dev); + if (!is_typec_partner_altmode(dev)) + return 0; + if (add_uevent_var(env, "SVID=%04X", altmode->svid)) return -ENOMEM; @@ -547,3 +569,4 @@ const struct bus_type typec_bus = { .probe = typec_probe, .remove = typec_remove, }; +EXPORT_SYMBOL_GPL(typec_bus); diff --git a/drivers/usb/typec/bus.h b/drivers/usb/typec/bus.h index 643b8c81786d..7df5deb1dd3a 100644 --- a/drivers/usb/typec/bus.h +++ b/drivers/usb/typec/bus.h @@ -5,7 +5,6 @@ #include -struct bus_type; struct typec_mux; struct typec_retimer; @@ -28,9 +27,4 @@ struct altmode { #define to_altmode(d) container_of(d, struct altmode, adev) -extern const struct bus_type typec_bus; -extern const struct device_type typec_altmode_dev_type; - -#define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type) - #endif /* __USB_TYPEC_ALTMODE_H__ */ diff --git a/drivers/usb/typec/class.c b/drivers/usb/typec/class.c index 9b2647cb199b..831430909471 100644 --- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -235,7 +235,7 @@ static int altmode_match(struct device *dev, const void *data) struct typec_altmode *adev = to_typec_altmode(dev); const struct typec_device_id *id = data; - if (!is_typec_altmode(dev)) + if (!is_typec_port_altmode(dev)) return 0; return (adev->svid == id->svid); @@ -445,11 +445,88 @@ svid_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(svid); +static int increment_duplicated_priority(struct device *dev, void *data) +{ + if (is_typec_port_altmode(dev)) { + struct typec_altmode **alt_target = (struct typec_altmode **)data; + struct typec_altmode *alt = to_typec_altmode(dev); + + if (alt != *alt_target && alt->priority == (*alt_target)->priority) { + alt->priority++; + *alt_target = alt; + return 1; + } + } + return 0; +} + +static int find_duplicated_priority(struct device *dev, void *data) +{ + if (is_typec_port_altmode(dev)) { + struct typec_altmode **alt_target = (struct typec_altmode **)data; + struct typec_altmode *alt = to_typec_altmode(dev); + + if (alt != *alt_target && alt->priority == (*alt_target)->priority) + return 1; + } + return 0; +} + +static int typec_mode_set_priority(struct typec_altmode *alt, const u8 priority) +{ + struct typec_port *port = to_typec_port(alt->dev.parent); + const u8 old_priority = alt->priority; + int res = 1; + + alt->priority = priority; + while (res) { + res = device_for_each_child(&port->dev, &alt, find_duplicated_priority); + if (res) { + alt->priority++; + if (alt->priority == 0) { + alt->priority = old_priority; + return -EOVERFLOW; + } + } + } + + res = 1; + alt->priority = priority; + while (res) + res = device_for_each_child(&port->dev, &alt, + increment_duplicated_priority); + + return 0; +} + +static ssize_t priority_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + u8 val; + int err = kstrtou8(buf, 10, &val); + + if (!err) + err = typec_mode_set_priority(to_typec_altmode(dev), val); + + if (!err) + return size; + return err; +} + +static ssize_t priority_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sysfs_emit(buf, "%u\n", to_typec_altmode(dev)->priority); +} +static DEVICE_ATTR_RW(priority); + static struct attribute *typec_altmode_attrs[] = { &dev_attr_active.attr, &dev_attr_mode.attr, &dev_attr_svid.attr, &dev_attr_vdo.attr, + &dev_attr_priority.attr, NULL }; @@ -457,11 +534,17 @@ static umode_t typec_altmode_attr_is_visible(struct kobject *kobj, struct attribute *attr, int n) { struct typec_altmode *adev = to_typec_altmode(kobj_to_dev(kobj)); + struct typec_port *port = typec_altmode2port(adev); - if (attr == &dev_attr_active.attr) - if (!is_typec_port(adev->dev.parent) && - (!adev->ops || !adev->ops->activate)) - return 0444; + if (attr == &dev_attr_active.attr) { + if (!is_typec_port(adev->dev.parent)) { + if (!port->mode_control || !adev->ops || !adev->ops->activate) + return 0444; + } + } else if (attr == &dev_attr_priority.attr) { + if (!is_typec_port(adev->dev.parent) || !port->mode_control) + return 0; + } return attr->mode; } @@ -532,22 +615,38 @@ static void typec_altmode_release(struct device *dev) kfree(alt); } -const struct device_type typec_altmode_dev_type = { - .name = "typec_alternate_mode", +const struct device_type typec_port_altmode_dev_type = { + .name = "typec_port_alternate_mode", .groups = typec_altmode_groups, .release = typec_altmode_release, }; +EXPORT_SYMBOL_GPL(typec_port_altmode_dev_type); + +const struct device_type typec_plug_altmode_dev_type = { + .name = "typec_plug_alternate_mode", + .groups = typec_altmode_groups, + .release = typec_altmode_release, +}; +EXPORT_SYMBOL_GPL(typec_plug_altmode_dev_type); + +const struct device_type typec_partner_altmode_dev_type = { + .name = "typec_partner_alternate_mode", + .groups = typec_altmode_groups, + .release = typec_altmode_release, +}; +EXPORT_SYMBOL_GPL(typec_partner_altmode_dev_type); static struct typec_altmode * typec_register_altmode(struct device *parent, - const struct typec_altmode_desc *desc) + const struct typec_altmode_desc *desc, + const struct device_type *type) { unsigned int id = altmode_id_get(parent); bool is_port = is_typec_port(parent); struct altmode *alt; int ret; - alt = kzalloc(sizeof(*alt), GFP_KERNEL); + alt = kzalloc_obj(*alt); if (!alt) { altmode_id_remove(parent, id); return ERR_PTR(-ENOMEM); @@ -556,6 +655,7 @@ typec_register_altmode(struct device *parent, alt->adev.svid = desc->svid; alt->adev.mode = desc->mode; alt->adev.vdo = desc->vdo; + alt->adev.mode_selection = desc->mode_selection; alt->roles = desc->roles; alt->id = id; @@ -575,7 +675,7 @@ typec_register_altmode(struct device *parent, alt->adev.dev.parent = parent; alt->adev.dev.groups = alt->groups; - alt->adev.dev.type = &typec_altmode_dev_type; + alt->adev.dev.type = type; dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); get_device(alt->adev.dev.parent); @@ -584,9 +684,7 @@ typec_register_altmode(struct device *parent, if (!is_port) typec_altmode_set_partner(alt); - /* The partners are bind to drivers */ - if (is_typec_partner(parent)) - alt->adev.dev.bus = &typec_bus; + alt->adev.dev.bus = &typec_bus; /* Plug alt modes need a class to generate udev events. */ if (is_typec_plug(parent)) @@ -963,7 +1061,7 @@ struct typec_altmode * typec_partner_register_altmode(struct typec_partner *partner, const struct typec_altmode_desc *desc) { - return typec_register_altmode(&partner->dev, desc); + return typec_register_altmode(&partner->dev, desc, &typec_partner_altmode_dev_type); } EXPORT_SYMBOL_GPL(typec_partner_register_altmode); @@ -1015,7 +1113,7 @@ struct typec_partner *typec_register_partner(struct typec_port *port, struct typec_partner *partner; int ret; - partner = kzalloc(sizeof(*partner), GFP_KERNEL); + partner = kzalloc_obj(*partner); if (!partner) return ERR_PTR(-ENOMEM); @@ -1193,7 +1291,7 @@ struct typec_altmode * typec_plug_register_altmode(struct typec_plug *plug, const struct typec_altmode_desc *desc) { - return typec_register_altmode(&plug->dev, desc); + return typec_register_altmode(&plug->dev, desc, &typec_plug_altmode_dev_type); } EXPORT_SYMBOL_GPL(typec_plug_register_altmode); @@ -1215,7 +1313,7 @@ struct typec_plug *typec_register_plug(struct typec_cable *cable, char name[8]; int ret; - plug = kzalloc(sizeof(*plug), GFP_KERNEL); + plug = kzalloc_obj(*plug); if (!plug) return ERR_PTR(-ENOMEM); @@ -1368,7 +1466,7 @@ struct typec_cable *typec_register_cable(struct typec_port *port, struct typec_cable *cable; int ret; - cable = kzalloc(sizeof(*cable), GFP_KERNEL); + cable = kzalloc_obj(*cable); if (!cable) return ERR_PTR(-ENOMEM); @@ -2482,6 +2580,7 @@ typec_port_register_altmode(struct typec_port *port, struct typec_altmode *adev; struct typec_mux *mux; struct typec_retimer *retimer; + int ret; mux = typec_mux_get(&port->dev); if (IS_ERR(mux)) @@ -2493,13 +2592,19 @@ typec_port_register_altmode(struct typec_port *port, return ERR_CAST(retimer); } - adev = typec_register_altmode(&port->dev, desc); + adev = typec_register_altmode(&port->dev, desc, &typec_port_altmode_dev_type); if (IS_ERR(adev)) { typec_retimer_put(retimer); typec_mux_put(mux); } else { to_altmode(adev)->mux = mux; to_altmode(adev)->retimer = retimer; + + ret = typec_mode_set_priority(adev, 0); + if (ret) { + typec_unregister_altmode(adev); + return ERR_PTR(ret); + } } return adev; @@ -2598,7 +2703,7 @@ struct typec_port *typec_register_port(struct device *parent, int ret; int id; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return ERR_PTR(-ENOMEM); @@ -2694,6 +2799,7 @@ struct typec_port *typec_register_port(struct device *parent, } port->pd = cap->pd; + port->mode_control = !cap->no_mode_control; ret = device_add(&port->dev); if (ret) { diff --git a/drivers/usb/typec/class.h b/drivers/usb/typec/class.h index db2fe96c48ff..d3435936ee7c 100644 --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -9,6 +9,7 @@ struct typec_mux; struct typec_switch; struct usb_device; +struct mode_selection; struct typec_plug { struct device dev; @@ -39,6 +40,7 @@ struct typec_partner { u8 usb_capability; struct usb_power_delivery *pd; + struct mode_selection *sel; void (*attach)(struct typec_partner *partner, struct device *dev); void (*deattach)(struct typec_partner *partner, struct device *dev); @@ -62,6 +64,7 @@ struct typec_port { struct mutex partner_link_lock; enum typec_orientation orientation; + bool mode_control; struct typec_switch *sw; struct typec_mux *mux; struct typec_retimer *retimer; diff --git a/drivers/usb/typec/hd3ss3220.c b/drivers/usb/typec/hd3ss3220.c index 3876f4faead6..3e39b800e6b5 100644 --- a/drivers/usb/typec/hd3ss3220.c +++ b/drivers/usb/typec/hd3ss3220.c @@ -204,6 +204,23 @@ static const struct typec_operations hd3ss3220_ops = { .port_type_set = hd3ss3220_port_type_set, }; +static void hd3ss3220_regulator_control(struct hd3ss3220 *hd3ss3220, bool on) +{ + int ret; + + if (regulator_is_enabled(hd3ss3220->vbus) == on) + return; + + if (on) + ret = regulator_enable(hd3ss3220->vbus); + else + ret = regulator_disable(hd3ss3220->vbus); + + if (ret) + dev_err(hd3ss3220->dev, + "vbus regulator %s failed: %d\n", on ? "disable" : "enable", ret); +} + static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220) { enum usb_role role_state = hd3ss3220_get_attached_state(hd3ss3220); @@ -221,6 +238,9 @@ static void hd3ss3220_set_role(struct hd3ss3220 *hd3ss3220) break; } + if (hd3ss3220->vbus && !hd3ss3220->id_gpiod) + hd3ss3220_regulator_control(hd3ss3220, role_state == USB_ROLE_HOST); + hd3ss3220->role_state = role_state; } @@ -330,18 +350,10 @@ static const struct regmap_config config = { static irqreturn_t hd3ss3220_id_isr(int irq, void *dev_id) { struct hd3ss3220 *hd3ss3220 = dev_id; - int ret; int id; id = gpiod_get_value_cansleep(hd3ss3220->id_gpiod); - if (!id) - ret = regulator_enable(hd3ss3220->vbus); - else - ret = regulator_disable(hd3ss3220->vbus); - - if (ret) - dev_err(hd3ss3220->dev, - "vbus regulator %s failed: %d\n", id ? "disable" : "enable", ret); + hd3ss3220_regulator_control(hd3ss3220, !id); return IRQ_HANDLED; } diff --git a/drivers/usb/typec/mode_selection.c b/drivers/usb/typec/mode_selection.c new file mode 100644 index 000000000000..cd376f67e445 --- /dev/null +++ b/drivers/usb/typec/mode_selection.c @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Google LLC. + */ + +#include +#include +#include +#include +#include +#include + +#include "class.h" + +/** + * struct mode_state - State tracking for a specific Type-C alternate mode + * @svid: Standard or Vendor ID of the Alternate Mode + * @priority: Mode priority + * @error: Outcome of the last attempt to enter the mode + * @list: List head to link this mode state into a prioritized list + */ +struct mode_state { + u16 svid; + u8 priority; + int error; + struct list_head list; +}; + +/** + * struct mode_selection - Manages the selection and state of Alternate Modes + * @mode_list: Prioritized list of available Alternate Modes + * @lock: Mutex to protect mode_list + * @work: Work structure + * @partner: Handle to the Type-C partner device + * @active_svid: svid of currently active mode + * @timeout: Timeout for a mode entry attempt, ms + * @delay: Delay between mode entry/exit attempts, ms + */ +struct mode_selection { + struct list_head mode_list; + /* Protects the mode_list*/ + struct mutex lock; + struct delayed_work work; + struct typec_partner *partner; + u16 active_svid; + unsigned int timeout; + unsigned int delay; +}; + +/** + * struct mode_order - Mode activation tracking + * @svid: Standard or Vendor ID of the Alternate Mode + * @enter: Flag indicating if the driver is currently attempting to enter or + * exit the mode + * @result: Outcome of the attempt to activate the mode + */ +struct mode_order { + u16 svid; + int enter; + int result; +}; + +static int activate_altmode(struct device *dev, void *data) +{ + if (is_typec_partner_altmode(dev)) { + struct typec_altmode *alt = to_typec_altmode(dev); + struct mode_order *order = (struct mode_order *)data; + + if (order->svid == alt->svid) { + if (alt->ops && alt->ops->activate) + order->result = alt->ops->activate(alt, order->enter); + else + order->result = -EOPNOTSUPP; + return 1; + } + } + return 0; +} + +static int mode_selection_activate(struct mode_selection *sel, + const u16 svid, const int enter) + + __must_hold(&sel->lock) +{ + struct mode_order order = {.svid = svid, .enter = enter, .result = -ENODEV}; + + /* + * The port driver may acquire its internal mutex during alternate mode + * activation. Since this is the same mutex that may be held during the + * execution of typec_altmode_state_update(), it is crucial to release + * sel->mutex before activation to avoid potential deadlock. + * Note that sel->mode_list must remain invariant throughout this unlocked + * interval. + */ + mutex_unlock(&sel->lock); + device_for_each_child(&sel->partner->dev, &order, activate_altmode); + mutex_lock(&sel->lock); + + return order.result; +} + +static void mode_list_clean(struct mode_selection *sel) +{ + struct mode_state *ms, *tmp; + + list_for_each_entry_safe(ms, tmp, &sel->mode_list, list) { + list_del(&ms->list); + kfree(ms); + } +} + +/** + * mode_selection_work_fn() - Alternate mode activation task + * @work: work structure + * + * - If the Alternate Mode currently prioritized at the top of the list is already + * active, the entire selection process is considered finished. + * - If a different Alternate Mode is currently active, the system must exit that + * active mode first before attempting any new entry. + * + * The function then checks the result of the attempt to entre the current mode, + * stored in the `ms->error` field: + * - if the attempt FAILED, the mode is deactivated and removed from the list. + * - `ms->error` value of 0 signifies that the mode has not yet been activated. + * + * Once successfully activated, the task is scheduled for subsequent entry after + * a timeout period. The alternate mode driver is expected to call back with the + * actual mode entry result via `typec_altmode_state_update()`. + */ +static void mode_selection_work_fn(struct work_struct *work) +{ + struct mode_selection *sel = container_of(work, + struct mode_selection, work.work); + struct mode_state *ms; + unsigned int delay = sel->delay; + int result; + + guard(mutex)(&sel->lock); + + ms = list_first_entry_or_null(&sel->mode_list, struct mode_state, list); + if (!ms) + return; + + if (sel->active_svid == ms->svid) { + dev_dbg(&sel->partner->dev, "%x altmode is active\n", ms->svid); + mode_list_clean(sel); + } else if (sel->active_svid != 0) { + result = mode_selection_activate(sel, sel->active_svid, 0); + if (result) + mode_list_clean(sel); + else + sel->active_svid = 0; + } else if (ms->error) { + dev_err(&sel->partner->dev, "%x: entry error %pe\n", + ms->svid, ERR_PTR(ms->error)); + mode_selection_activate(sel, ms->svid, 0); + list_del(&ms->list); + kfree(ms); + } else { + result = mode_selection_activate(sel, ms->svid, 1); + if (result) { + dev_err(&sel->partner->dev, "%x: activation error %pe\n", + ms->svid, ERR_PTR(result)); + list_del(&ms->list); + kfree(ms); + } else { + delay = sel->timeout; + ms->error = -ETIMEDOUT; + } + } + + if (!list_empty(&sel->mode_list)) + schedule_delayed_work(&sel->work, msecs_to_jiffies(delay)); +} + +void typec_altmode_state_update(struct typec_partner *partner, const u16 svid, + const int error) +{ + struct mode_selection *sel = partner->sel; + struct mode_state *ms; + + if (sel) { + mutex_lock(&sel->lock); + ms = list_first_entry_or_null(&sel->mode_list, struct mode_state, list); + if (ms && ms->svid == svid) { + ms->error = error; + if (cancel_delayed_work(&sel->work)) + schedule_delayed_work(&sel->work, 0); + } + if (!error) + sel->active_svid = svid; + else + sel->active_svid = 0; + mutex_unlock(&sel->lock); + } +} +EXPORT_SYMBOL_GPL(typec_altmode_state_update); + +static int compare_priorities(void *priv, + const struct list_head *a, const struct list_head *b) +{ + const struct mode_state *msa = container_of(a, struct mode_state, list); + const struct mode_state *msb = container_of(b, struct mode_state, list); + + if (msa->priority < msb->priority) + return -1; + return 1; +} + +static int altmode_add_to_list(struct device *dev, void *data) +{ + if (is_typec_partner_altmode(dev)) { + struct list_head *list = (struct list_head *)data; + struct typec_altmode *altmode = to_typec_altmode(dev); + const struct typec_altmode *pdev = typec_altmode_get_partner(altmode); + struct mode_state *ms; + + if (pdev && altmode->ops && altmode->ops->activate) { + ms = kzalloc_obj(*ms); + if (!ms) + return -ENOMEM; + ms->svid = pdev->svid; + ms->priority = pdev->priority; + INIT_LIST_HEAD(&ms->list); + list_add_tail(&ms->list, list); + } + } + return 0; +} + +int typec_mode_selection_start(struct typec_partner *partner, + const unsigned int delay, const unsigned int timeout) +{ + struct mode_selection *sel; + int ret; + + if (partner->usb_mode == USB_MODE_USB4) + return -EBUSY; + + if (partner->sel) + return -EALREADY; + + sel = kzalloc_obj(*sel); + if (!sel) + return -ENOMEM; + + INIT_LIST_HEAD(&sel->mode_list); + + ret = device_for_each_child(&partner->dev, &sel->mode_list, + altmode_add_to_list); + + if (ret || list_empty(&sel->mode_list)) { + mode_list_clean(sel); + kfree(sel); + return ret; + } + + list_sort(NULL, &sel->mode_list, compare_priorities); + sel->partner = partner; + sel->delay = delay; + sel->timeout = timeout; + mutex_init(&sel->lock); + INIT_DELAYED_WORK(&sel->work, mode_selection_work_fn); + schedule_delayed_work(&sel->work, msecs_to_jiffies(delay)); + partner->sel = sel; + + return 0; +} +EXPORT_SYMBOL_GPL(typec_mode_selection_start); + +void typec_mode_selection_delete(struct typec_partner *partner) +{ + struct mode_selection *sel = partner->sel; + + if (sel) { + partner->sel = NULL; + cancel_delayed_work_sync(&sel->work); + mode_list_clean(sel); + mutex_destroy(&sel->lock); + kfree(sel); + } +} +EXPORT_SYMBOL_GPL(typec_mode_selection_delete); diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 182c902c42f6..58fb97ea6877 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -76,7 +76,7 @@ struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) int err; int i; - sw = kzalloc(sizeof(*sw), GFP_KERNEL); + sw = kzalloc_obj(*sw); if (!sw) return ERR_PTR(-ENOMEM); @@ -171,7 +171,7 @@ typec_switch_register(struct device *parent, if (!desc || !desc->set) return ERR_PTR(-EINVAL); - sw_dev = kzalloc(sizeof(*sw_dev), GFP_KERNEL); + sw_dev = kzalloc_obj(*sw_dev); if (!sw_dev) return ERR_PTR(-ENOMEM); @@ -301,7 +301,7 @@ struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode) int err; int i; - mux = kzalloc(sizeof(*mux), GFP_KERNEL); + mux = kzalloc_obj(*mux); if (!mux) return ERR_PTR(-ENOMEM); @@ -415,7 +415,7 @@ typec_mux_register(struct device *parent, const struct typec_mux_desc *desc) if (!desc || !desc->set) return ERR_PTR(-EINVAL); - mux_dev = kzalloc(sizeof(*mux_dev), GFP_KERNEL); + mux_dev = kzalloc_obj(*mux_dev); if (!mux_dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/typec/pd.c b/drivers/usb/typec/pd.c index 67f20b5ffdf4..766c76d63328 100644 --- a/drivers/usb/typec/pd.c +++ b/drivers/usb/typec/pd.c @@ -480,7 +480,7 @@ static int add_pdo(struct usb_power_delivery_capabilities *cap, u32 pdo, int pos struct pdo *p; int ret; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; @@ -569,7 +569,7 @@ usb_power_delivery_register_capabilities(struct usb_power_delivery *pd, int ret; int i; - cap = kzalloc(sizeof(*cap), GFP_KERNEL); + cap = kzalloc_obj(*cap); if (!cap) return ERR_PTR(-ENOMEM); @@ -697,7 +697,7 @@ usb_power_delivery_register(struct device *parent, struct usb_power_delivery_des struct usb_power_delivery *pd; int ret; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/typec/retimer.c b/drivers/usb/typec/retimer.c index b519fcf358ca..bfd80292b22a 100644 --- a/drivers/usb/typec/retimer.c +++ b/drivers/usb/typec/retimer.c @@ -110,7 +110,7 @@ typec_retimer_register(struct device *parent, const struct typec_retimer_desc *d if (!desc || !desc->set) return ERR_PTR(-EINVAL); - retimer = kzalloc(sizeof(*retimer), GFP_KERNEL); + retimer = kzalloc_obj(*retimer); if (!retimer) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c index be49a976428f..8e0e14a2704e 100644 --- a/drivers/usb/typec/tcpm/tcpm.c +++ b/drivers/usb/typec/tcpm/tcpm.c @@ -1665,7 +1665,7 @@ static int tcpm_queue_vdm_unlocked(struct tcpm_port *port, const u32 header, u32 *data_cpy; int ret = -ENOMEM; - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) goto err_event; @@ -1808,7 +1808,7 @@ static bool svdm_consume_svids(struct tcpm_port *port, const u32 *p, int cnt, /* * PD3.0 Spec 6.4.4.3.2: The SVIDs are returned 2 per VDO (see Table * 6-43), and can be returned maximum 6 VDOs per response (see Figure - * 6-19). If the Respondersupports 12 or more SVID then the Discover + * 6-19). If the Responder supports 12 or more SVID then the Discover * SVIDs Command Shall be executed multiple times until a Discover * SVIDs VDO is returned ending either with a SVID value of 0x0000 in * the last part of the last VDO or with a VDO containing two SVIDs @@ -3803,7 +3803,7 @@ void tcpm_pd_receive(struct tcpm_port *port, const struct pd_message *msg, { struct pd_rx_event *event; - event = kzalloc(sizeof(*event), GFP_ATOMIC); + event = kzalloc_obj(*event, GFP_ATOMIC); if (!event) return; @@ -7890,7 +7890,7 @@ struct tcpm_port *tcpm_register_port(struct device *dev, struct tcpc_dev *tcpc) port->partner_desc.identity = &port->partner_ident; port->role_sw = fwnode_usb_role_switch_get(tcpc->fwnode); - if (IS_ERR_OR_NULL(port->role_sw)) + if (!port->role_sw) port->role_sw = usb_role_switch_get(port->dev); if (IS_ERR(port->role_sw)) { err = PTR_ERR(port->role_sw); diff --git a/drivers/usb/typec/ucsi/Kconfig b/drivers/usb/typec/ucsi/Kconfig index b812be4d0e67..87dd992a4b9e 100644 --- a/drivers/usb/typec/ucsi/Kconfig +++ b/drivers/usb/typec/ucsi/Kconfig @@ -73,7 +73,6 @@ config CROS_EC_UCSI tristate "UCSI Driver for ChromeOS EC" depends on MFD_CROS_EC_DEV depends on CROS_USBPD_NOTIFY - depends on !EXTCON_TCSS_CROS_EC default MFD_CROS_EC_DEV help This driver enables UCSI support for a ChromeOS EC. The EC is diff --git a/drivers/usb/typec/ucsi/Makefile b/drivers/usb/typec/ucsi/Makefile index dbc571763eff..c7e38bf01350 100644 --- a/drivers/usb/typec/ucsi/Makefile +++ b/drivers/usb/typec/ucsi/Makefile @@ -17,6 +17,10 @@ ifneq ($(CONFIG_TYPEC_DP_ALTMODE),) typec_ucsi-y += displayport.o endif +ifneq ($(CONFIG_TYPEC_TBT_ALTMODE),) + typec_ucsi-y += thunderbolt.o +endif + obj-$(CONFIG_UCSI_ACPI) += ucsi_acpi.o obj-$(CONFIG_UCSI_CCG) += ucsi_ccg.o obj-$(CONFIG_UCSI_STM32G0) += ucsi_stm32g0.o diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c index eed2a7d0ebc6..6bca2dce211c 100644 --- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c +++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ucsi.h" @@ -33,6 +34,11 @@ /* Number of times to attempt recovery from a write timeout before giving up. */ #define WRITE_TMO_CTR_MAX 5 +/* Delay between mode entry/exit attempts, ms */ +static const unsigned int mode_selection_delay = 1000; +/* Timeout for a mode entry attempt, ms */ +static const unsigned int mode_selection_timeout = 4000; + struct cros_ucsi_data { struct device *dev; struct ucsi *ucsi; @@ -134,6 +140,20 @@ static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci, return ret; } +static void cros_ucsi_add_partner_altmodes(struct ucsi_connector *con) +{ + if (!con->typec_cap.no_mode_control) + typec_mode_selection_start(con->partner, + mode_selection_delay, + mode_selection_timeout); +} + +static void cros_ucsi_remove_partner_altmodes(struct ucsi_connector *con) +{ + if (!con->typec_cap.no_mode_control) + typec_mode_selection_delete(con->partner); +} + static const struct ucsi_operations cros_ucsi_ops = { .read_version = cros_ucsi_read_version, .read_cci = cros_ucsi_read_cci, @@ -141,6 +161,8 @@ static const struct ucsi_operations cros_ucsi_ops = { .read_message_in = cros_ucsi_read_message_in, .async_control = cros_ucsi_async_control, .sync_control = cros_ucsi_sync_control, + .add_partner_altmodes = cros_ucsi_add_partner_altmodes, + .remove_partner_altmodes = cros_ucsi_remove_partner_altmodes, }; static void cros_ucsi_work(struct work_struct *work) diff --git a/drivers/usb/typec/ucsi/debugfs.c b/drivers/usb/typec/ucsi/debugfs.c index d1f5832165c3..a4b9a6b51649 100644 --- a/drivers/usb/typec/ucsi/debugfs.c +++ b/drivers/usb/typec/ucsi/debugfs.c @@ -112,7 +112,7 @@ DEFINE_SHOW_ATTRIBUTE(ucsi_vbus_volt); void ucsi_debugfs_register(struct ucsi *ucsi) { - ucsi->debugfs = kzalloc(sizeof(*ucsi->debugfs), GFP_KERNEL); + ucsi->debugfs = kzalloc_obj(*ucsi->debugfs); if (!ucsi->debugfs) return; diff --git a/drivers/usb/typec/ucsi/psy.c b/drivers/usb/typec/ucsi/psy.c index 3abe9370ffaa..c8ebab8ba7e7 100644 --- a/drivers/usb/typec/ucsi/psy.c +++ b/drivers/usb/typec/ucsi/psy.c @@ -112,15 +112,20 @@ static int ucsi_psy_get_voltage_max(struct ucsi_connector *con, union power_supply_propval *val) { u32 pdo; + int max_voltage = 0; switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: - if (con->num_pdos > 0) { - pdo = con->src_pdos[con->num_pdos - 1]; - val->intval = pdo_fixed_voltage(pdo) * 1000; - } else { - val->intval = 0; + for (int i = 0; i < con->num_pdos; i++) { + int pdo_voltage = 0; + + pdo = con->src_pdos[i]; + if (pdo_type(pdo) == PDO_TYPE_FIXED) + pdo_voltage = pdo_fixed_voltage(pdo) * 1000; + max_voltage = (pdo_voltage > max_voltage) ? pdo_voltage + : max_voltage; } + val->intval = max_voltage; break; case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: @@ -168,6 +173,7 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, union power_supply_propval *val) { u32 pdo; + int max_current = 0; if (!UCSI_CONSTAT(con, CONNECTED)) { val->intval = 0; @@ -176,12 +182,16 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, switch (UCSI_CONSTAT(con, PWR_OPMODE)) { case UCSI_CONSTAT_PWR_OPMODE_PD: - if (con->num_pdos > 0) { - pdo = con->src_pdos[con->num_pdos - 1]; - val->intval = pdo_max_current(pdo) * 1000; - } else { - val->intval = 0; + for (int i = 0; i < con->num_pdos; i++) { + int pdo_current = 0; + + pdo = con->src_pdos[i]; + if (pdo_type(pdo) == PDO_TYPE_FIXED) + pdo_current = pdo_max_current(pdo) * 1000; + max_current = (pdo_current > max_current) ? pdo_current + : max_current; } + val->intval = max_current; break; case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: val->intval = UCSI_TYPEC_1_5_CURRENT * 1000; @@ -202,10 +212,28 @@ static int ucsi_psy_get_current_max(struct ucsi_connector *con, static int ucsi_psy_get_current_now(struct ucsi_connector *con, union power_supply_propval *val) { - if (UCSI_CONSTAT(con, PWR_OPMODE) == UCSI_CONSTAT_PWR_OPMODE_PD) - val->intval = rdo_op_current(con->rdo) * 1000; - else + if (!UCSI_CONSTAT(con, CONNECTED)) { val->intval = 0; + return 0; + } + + switch (UCSI_CONSTAT(con, PWR_OPMODE)) { + case UCSI_CONSTAT_PWR_OPMODE_PD: + val->intval = rdo_op_current(con->rdo) * 1000; + break; + case UCSI_CONSTAT_PWR_OPMODE_TYPEC1_5: + val->intval = UCSI_TYPEC_1_5_CURRENT * 1000; + break; + case UCSI_CONSTAT_PWR_OPMODE_TYPEC3_0: + val->intval = UCSI_TYPEC_3_0_CURRENT * 1000; + break; + case UCSI_CONSTAT_PWR_OPMODE_BC: + case UCSI_CONSTAT_PWR_OPMODE_DEFAULT: + /* UCSI can't tell b/w DCP/CDP or USB2/3x1/3x2 SDP chargers */ + default: + val->intval = UCSI_TYPEC_DEFAULT_CURRENT * 1000; + break; + } return 0; } diff --git a/drivers/usb/typec/ucsi/thunderbolt.c b/drivers/usb/typec/ucsi/thunderbolt.c new file mode 100644 index 000000000000..434d3d8ea5b6 --- /dev/null +++ b/drivers/usb/typec/ucsi/thunderbolt.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * UCSI Thunderbolt Alternate Mode Support + * + * Copyright 2026 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ucsi.h" + +/** + * struct ucsi_tbt - Thunderbolt Alternate Mode private data structure + * @con: Pointer to UCSI connector structure + * @alt: Pointer to typec altmode structure + * @work: Work structure + * @cam: An offset into the list of alternate modes supported by the PPM + * @header: VDO header + */ +struct ucsi_tbt { + struct ucsi_connector *con; + struct typec_altmode *alt; + struct work_struct work; + int cam; + u32 header; +}; + +static void ucsi_thunderbolt_work(struct work_struct *work) +{ + struct ucsi_tbt *tbt = container_of(work, struct ucsi_tbt, work); + + if (typec_altmode_vdm(tbt->alt, tbt->header, NULL, 0)) + dev_err(&tbt->alt->dev, "VDM 0x%x failed\n", tbt->header); + + tbt->header = 0; +} + +static int ucsi_thunderbolt_set_altmode(struct ucsi_tbt *tbt, + bool enter, u32 vdo) +{ + int svdm_version; + int cmd; + int ret; + u64 command = UCSI_SET_NEW_CAM | + UCSI_CONNECTOR_NUMBER(tbt->con->num) | + UCSI_SET_NEW_CAM_SET_AM(tbt->cam) | + ((u64)vdo << 32); + + if (enter) + command |= (1 << 23); + + ret = ucsi_send_command(tbt->con->ucsi, command, NULL, 0); + if (ret < 0) + return ret; + + svdm_version = typec_altmode_get_svdm_version(tbt->alt); + if (svdm_version < 0) + return svdm_version; + + if (enter) + cmd = CMD_ENTER_MODE; + else + cmd = CMD_EXIT_MODE; + tbt->header = VDO(USB_TYPEC_TBT_SID, 1, svdm_version, cmd); + tbt->header |= VDO_OPOS(TYPEC_TBT_MODE); + tbt->header |= VDO_CMDT(CMDT_RSP_ACK); + + schedule_work(&tbt->work); + + return 0; +} + +static int ucsi_thunderbolt_enter(struct typec_altmode *alt, u32 *vdo) +{ + struct ucsi_tbt *tbt = typec_altmode_get_drvdata(alt); + struct ucsi_connector *con = tbt->con; + u64 command; + u8 cur = 0; + int ret; + + if (!ucsi_con_mutex_lock(con)) + return -ENOTCONN; + + command = UCSI_GET_CURRENT_CAM | UCSI_CONNECTOR_NUMBER(con->num); + ret = ucsi_send_command(con->ucsi, command, &cur, sizeof(cur)); + if (ret < 0) { + if (con->ucsi->version > 0x0100) + goto err_unlock; + cur = 0xff; + } + + if (cur != 0xff) { + if (cur >= UCSI_MAX_ALTMODES || con->port_altmode[cur] != alt) + ret = -EBUSY; + else + ret = 0; + goto err_unlock; + } + + ret = ucsi_thunderbolt_set_altmode(tbt, true, *vdo); + ucsi_altmode_update_active(tbt->con); + +err_unlock: + ucsi_con_mutex_unlock(con); + + return ret; +} + +static int ucsi_thunderbolt_exit(struct typec_altmode *alt) +{ + struct ucsi_tbt *tbt = typec_altmode_get_drvdata(alt); + int ret; + + if (!ucsi_con_mutex_lock(tbt->con)) + return -ENOTCONN; + + ret = ucsi_thunderbolt_set_altmode(tbt, false, 0); + + ucsi_con_mutex_unlock(tbt->con); + + return ret; +} + +static int ucsi_thunderbolt_vdm(struct typec_altmode *alt, + u32 header, const u32 *data, int count) +{ + struct ucsi_tbt *tbt = typec_altmode_get_drvdata(alt); + int cmd_type = PD_VDO_CMDT(header); + int cmd = PD_VDO_CMD(header); + int svdm_version; + + if (!ucsi_con_mutex_lock(tbt->con)) + return -ENOTCONN; + + svdm_version = typec_altmode_get_svdm_version(alt); + if (svdm_version < 0) { + ucsi_con_mutex_unlock(tbt->con); + return svdm_version; + } + + switch (cmd_type) { + case CMDT_INIT: + if (PD_VDO_SVDM_VER(header) < svdm_version) { + svdm_version = PD_VDO_SVDM_VER(header); + typec_partner_set_svdm_version(tbt->con->partner, svdm_version); + } + tbt->header = VDO(USB_TYPEC_TBT_SID, 1, svdm_version, cmd); + tbt->header |= VDO_OPOS(TYPEC_TBT_MODE); + tbt->header |= VDO_CMDT(CMDT_RSP_ACK); + + schedule_work(&tbt->work); + break; + default: + break; + } + + ucsi_con_mutex_unlock(tbt->con); + + return 0; +} + +static const struct typec_altmode_ops ucsi_thunderbolt_ops = { + .enter = ucsi_thunderbolt_enter, + .exit = ucsi_thunderbolt_exit, + .vdm = ucsi_thunderbolt_vdm, +}; + +struct typec_altmode *ucsi_register_thunderbolt(struct ucsi_connector *con, + bool override, int offset, + struct typec_altmode_desc *desc) +{ + struct typec_altmode *alt; + struct ucsi_tbt *tbt; + + alt = typec_port_register_altmode(con->port, desc); + if (IS_ERR(alt) || !override) + return alt; + + tbt = devm_kzalloc(&alt->dev, sizeof(*tbt), GFP_KERNEL); + if (!tbt) { + typec_unregister_altmode(alt); + return ERR_PTR(-ENOMEM); + } + + tbt->cam = offset; + tbt->con = con; + tbt->alt = alt; + INIT_WORK(&tbt->work, ucsi_thunderbolt_work); + typec_altmode_set_drvdata(alt, tbt); + typec_altmode_set_ops(alt, &ucsi_thunderbolt_ops); + + return alt; +} + +void ucsi_thunderbolt_remove_partner(struct typec_altmode *alt) +{ + struct ucsi_tbt *tbt; + + if (alt) { + tbt = typec_altmode_get_drvdata(alt); + if (tbt) + cancel_work_sync(&tbt->work); + } +} diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index a7b388dc7fa0..f38a4d7ebc42 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "ucsi.h" #include "trace.h" @@ -292,7 +293,7 @@ static int ucsi_partner_task(struct ucsi_connector *con, if (!con->partner) return 0; - uwork = kzalloc(sizeof(*uwork), GFP_KERNEL); + uwork = kzalloc_obj(*uwork); if (!uwork) return -ENOMEM; @@ -314,6 +315,7 @@ void ucsi_altmode_update_active(struct ucsi_connector *con) { const struct typec_altmode *altmode = NULL; u64 command; + u16 svid = 0; int ret; u8 cur; int i; @@ -335,6 +337,10 @@ void ucsi_altmode_update_active(struct ucsi_connector *con) for (i = 0; con->partner_altmode[i]; i++) typec_altmode_update_active(con->partner_altmode[i], con->partner_altmode[i] == altmode); + + if (altmode) + svid = altmode->svid; + typec_altmode_state_update(con->partner, svid, 0); } static int ucsi_altmode_next_mode(struct typec_altmode **alt, u16 svid) @@ -412,6 +418,9 @@ static int ucsi_register_altmode(struct ucsi_connector *con, alt = ucsi_register_displayport(con, override, i, desc); break; + case USB_TYPEC_TBT_SID: + alt = ucsi_register_thunderbolt(con, override, i, desc); + break; default: alt = typec_port_register_altmode(con->port, desc); break; @@ -609,6 +618,8 @@ static int ucsi_register_altmodes(struct ucsi_connector *con, u8 recipient) desc.vdo = alt[j].mid; desc.svid = alt[j].svid; desc.roles = TYPEC_PORT_DRD; + desc.mode_selection = con->ucsi->ops->add_partner_altmodes && + !con->typec_cap.no_mode_control; ret = ucsi_register_altmode(con, &desc, recipient); if (ret) @@ -640,12 +651,15 @@ static void ucsi_unregister_altmodes(struct ucsi_connector *con, u8 recipient) } while (adev[i]) { - if (recipient == UCSI_RECIPIENT_SOP && - (adev[i]->svid == USB_TYPEC_DP_SID || - (adev[i]->svid == USB_TYPEC_NVIDIA_VLINK_SID && - adev[i]->vdo != USB_TYPEC_NVIDIA_VLINK_DBG_VDO))) { + if (recipient == UCSI_RECIPIENT_SOP) { pdev = typec_altmode_get_partner(adev[i]); - ucsi_displayport_remove_partner((void *)pdev); + + if (adev[i]->svid == USB_TYPEC_DP_SID || + (adev[i]->svid == USB_TYPEC_NVIDIA_VLINK_SID && + adev[i]->vdo != USB_TYPEC_NVIDIA_VLINK_DBG_VDO)) + ucsi_displayport_remove_partner((void *)pdev); + else if (adev[i]->svid == USB_TYPEC_TBT_SID) + ucsi_thunderbolt_remove_partner((void *)pdev); } typec_unregister_altmode(adev[i]); adev[i++] = NULL; @@ -831,6 +845,8 @@ static int ucsi_check_altmodes(struct ucsi_connector *con) if (con->partner_altmode[0]) { num_partner_am = ucsi_get_num_altmode(con->partner_altmode); typec_partner_set_num_altmodes(con->partner, num_partner_am); + if (con->ucsi->ops->add_partner_altmodes) + con->ucsi->ops->add_partner_altmodes(con); ucsi_altmode_update_active(con); return 0; } else { @@ -1119,6 +1135,8 @@ static void ucsi_unregister_partner(struct ucsi_connector *con) return; typec_set_mode(con->port, TYPEC_STATE_SAFE); + if (con->ucsi->ops->remove_partner_altmodes) + con->ucsi->ops->remove_partner_altmodes(con); typec_partner_set_usb_power_delivery(con->partner, NULL); ucsi_unregister_partner_pdos(con); @@ -1307,6 +1325,7 @@ static void ucsi_handle_connector_change(struct work_struct *work) if (con->partner && (change & UCSI_CONSTAT_PARTNER_CHANGE)) { ucsi_partner_change(con); + ucsi_altmode_update_active(con); /* Complete pending data role swap */ if (!completion_done(&con->complete)) @@ -1659,6 +1678,7 @@ static int ucsi_register_port(struct ucsi *ucsi, struct ucsi_connector *con) cap->driver_data = con; cap->ops = &ucsi_ops; + cap->no_mode_control = !(con->ucsi->cap.features & UCSI_CAP_ALT_MODE_OVERRIDE); if (ucsi->version >= UCSI_VERSION_2_0) con->typec_cap.orientation_aware = true; @@ -1845,7 +1865,7 @@ static int ucsi_init(struct ucsi *ucsi) } /* Allocate the connectors. Released in ucsi_unregister() */ - connector = kcalloc(ucsi->cap.num_connectors + 1, sizeof(*connector), GFP_KERNEL); + connector = kzalloc_objs(*connector, ucsi->cap.num_connectors + 1); if (!connector) { ret = -ENOMEM; goto err_reset; @@ -2023,7 +2043,7 @@ struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops) !ops->read_message_in || !ops->sync_control || !ops->async_control) return ERR_PTR(-EINVAL); - ucsi = kzalloc(sizeof(*ucsi), GFP_KERNEL); + ucsi = kzalloc_obj(*ucsi); if (!ucsi) return ERR_PTR(-ENOMEM); diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 410389ef173a..43a0d01ade8f 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -70,6 +70,8 @@ struct dentry; * @update_altmodes: Squashes duplicate DP altmodes * @update_connector: Update connector capabilities before registering * @connector_status: Updates connector status, called holding connector lock + * @add_partner_altmodes: Start mode selection + * @remove_partner_altmodes: Clean mode selection * * Read and write routines for UCSI interface. @sync_write must wait for the * Command Completion Event from the PPM before returning, and @async_write must @@ -88,6 +90,8 @@ struct ucsi_operations { struct ucsi_altmode *updated); void (*update_connector)(struct ucsi_connector *con); void (*connector_status)(struct ucsi_connector *con); + void (*add_partner_altmodes)(struct ucsi_connector *con); + void (*remove_partner_altmodes)(struct ucsi_connector *con); }; struct ucsi *ucsi_create(struct device *dev, const struct ucsi_operations *ops); @@ -596,6 +600,26 @@ static inline void ucsi_displayport_remove_partner(struct typec_altmode *adev) { } #endif /* CONFIG_TYPEC_DP_ALTMODE */ +#if IS_ENABLED(CONFIG_TYPEC_TBT_ALTMODE) +struct typec_altmode * +ucsi_register_thunderbolt(struct ucsi_connector *con, + bool override, int offset, + struct typec_altmode_desc *desc); + +void ucsi_thunderbolt_remove_partner(struct typec_altmode *adev); +#else +static inline struct typec_altmode * +ucsi_register_thunderbolt(struct ucsi_connector *con, + bool override, int offset, + struct typec_altmode_desc *desc) +{ + return typec_port_register_altmode(con->port, desc); +} + +static inline void +ucsi_thunderbolt_remove_partner(struct typec_altmode *adev) { } +#endif /* CONFIG_TYPEC_TBT_ALTMODE */ + #ifdef CONFIG_DEBUG_FS void ucsi_debugfs_init(void); void ucsi_debugfs_exit(void); diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 900a64ad25e4..709a24092104 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -493,7 +493,7 @@ static int skel_probe(struct usb_interface *interface, int retval; /* allocate memory for our device state and initialize it */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; diff --git a/drivers/usb/usbip/stub_dev.c b/drivers/usb/usbip/stub_dev.c index ce625b1ce9a5..34990b7e2d18 100644 --- a/drivers/usb/usbip/stub_dev.c +++ b/drivers/usb/usbip/stub_dev.c @@ -263,7 +263,7 @@ static struct stub_device *stub_device_alloc(struct usb_device *udev) dev_dbg(&udev->dev, "allocating stub device"); /* yes, it's a new device */ - sdev = kzalloc(sizeof(struct stub_device), GFP_KERNEL); + sdev = kzalloc_obj(struct stub_device); if (!sdev) return NULL; diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c index 9aa30ef76f3b..1e9ae578810d 100644 --- a/drivers/usb/usbip/stub_rx.c +++ b/drivers/usb/usbip/stub_rx.c @@ -535,7 +535,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev, /* allocate urb array */ priv->num_urbs = num_urbs; - priv->urbs = kmalloc_array(num_urbs, sizeof(*priv->urbs), GFP_KERNEL); + priv->urbs = kmalloc_objs(*priv->urbs, num_urbs); if (!priv->urbs) goto err_urbs; diff --git a/drivers/usb/usbip/stub_tx.c b/drivers/usb/usbip/stub_tx.c index 55919c3762ba..4ffd342250b5 100644 --- a/drivers/usb/usbip/stub_tx.c +++ b/drivers/usb/usbip/stub_tx.c @@ -17,7 +17,7 @@ void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, { struct stub_unlink *unlink; - unlink = kzalloc(sizeof(struct stub_unlink), GFP_ATOMIC); + unlink = kzalloc_obj(struct stub_unlink, GFP_ATOMIC); if (!unlink) { usbip_event_add(&sdev->ud, VDEV_EVENT_ERROR_MALLOC); return; @@ -55,8 +55,8 @@ void stub_complete(struct urb *urb) "stopped by a call to usb_kill_urb() because of cleaning up a virtual connection\n"); return; case -ECONNRESET: - dev_info(&urb->dev->dev, - "unlinked by a call to usb_unlink_urb()\n"); + dev_dbg(&urb->dev->dev, + "unlinked by a call to usb_unlink_urb()\n"); break; case -EPIPE: dev_info(&urb->dev->dev, "endpoint %d is stalled\n", @@ -191,7 +191,7 @@ static int stub_send_ret_submit(struct stub_device *sdev) else iovnum = 2; - iov = kcalloc(iovnum, sizeof(struct kvec), GFP_KERNEL); + iov = kzalloc_objs(struct kvec, iovnum); if (!iov) { usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_MALLOC); diff --git a/drivers/usb/usbip/usbip_event.c b/drivers/usb/usbip/usbip_event.c index 26513540bcdb..0e00c2d000f8 100644 --- a/drivers/usb/usbip/usbip_event.c +++ b/drivers/usb/usbip/usbip_event.c @@ -158,7 +158,7 @@ void usbip_event_add(struct usbip_device *ud, unsigned long event) goto out; } - ue = kmalloc(sizeof(struct usbip_event), GFP_ATOMIC); + ue = kmalloc_obj(struct usbip_event, GFP_ATOMIC); if (ue == NULL) goto out; diff --git a/drivers/usb/usbip/vhci_hcd.c b/drivers/usb/usbip/vhci_hcd.c index e55690da19e5..39e8faf4c18c 100644 --- a/drivers/usb/usbip/vhci_hcd.c +++ b/drivers/usb/usbip/vhci_hcd.c @@ -671,7 +671,7 @@ static void vhci_tx_urb(struct urb *urb, struct vhci_device *vdev) struct vhci_hcd *vhci_hcd = vdev_to_vhci_hcd(vdev); unsigned long flags; - priv = kzalloc(sizeof(struct vhci_priv), GFP_ATOMIC); + priv = kzalloc_obj(struct vhci_priv, GFP_ATOMIC); if (!priv) { usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC); return; @@ -951,7 +951,7 @@ static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) spin_lock(&vdev->priv_lock); /* setup CMD_UNLINK pdu */ - unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC); + unlink = kzalloc_obj(struct vhci_unlink, GFP_ATOMIC); if (!unlink) { spin_unlock(&vdev->priv_lock); spin_unlock_irqrestore(&vhci->lock, flags); @@ -1537,7 +1537,7 @@ static int __init vhci_hcd_init(void) if (vhci_num_controllers < 1) vhci_num_controllers = 1; - vhcis = kcalloc(vhci_num_controllers, sizeof(struct vhci), GFP_KERNEL); + vhcis = kzalloc_objs(struct vhci, vhci_num_controllers); if (vhcis == NULL) return -ENOMEM; diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c index d5865460e82d..bfc10f665e52 100644 --- a/drivers/usb/usbip/vhci_sysfs.c +++ b/drivers/usb/usbip/vhci_sysfs.c @@ -476,8 +476,7 @@ static int init_status_attrs(void) { int id; - status_attrs = kcalloc(vhci_num_controllers, sizeof(struct status_attr), - GFP_KERNEL); + status_attrs = kzalloc_objs(struct status_attr, vhci_num_controllers); if (status_attrs == NULL) return -ENOMEM; @@ -501,8 +500,7 @@ int vhci_init_attr_group(void) struct attribute **attrs; int ret, i; - attrs = kcalloc((vhci_num_controllers + 5), sizeof(struct attribute *), - GFP_KERNEL); + attrs = kzalloc_objs(struct attribute *, (vhci_num_controllers + 5)); if (attrs == NULL) return -ENOMEM; diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c index 0ae40a13a9fe..32e6fabccf72 100644 --- a/drivers/usb/usbip/vhci_tx.c +++ b/drivers/usb/usbip/vhci_tx.c @@ -82,7 +82,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev) else iovnum = 3; - iov = kcalloc(iovnum, sizeof(*iov), GFP_KERNEL); + iov = kzalloc_objs(*iov, iovnum); if (!iov) { usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC); return -ENOMEM; diff --git a/drivers/usb/usbip/vudc_dev.c b/drivers/usb/usbip/vudc_dev.c index f11535020e35..90383107b660 100644 --- a/drivers/usb/usbip/vudc_dev.c +++ b/drivers/usb/usbip/vudc_dev.c @@ -43,7 +43,7 @@ struct urbp *alloc_urbp(void) { struct urbp *urb_p; - urb_p = kzalloc(sizeof(*urb_p), GFP_KERNEL); + urb_p = kzalloc_obj(*urb_p); if (!urb_p) return urb_p; @@ -284,7 +284,7 @@ static struct usb_request *vep_alloc_request(struct usb_ep *_ep, if (!_ep) return NULL; - req = kzalloc(sizeof(*req), mem_flags); + req = kzalloc_obj(*req, mem_flags); if (!req) return NULL; @@ -491,7 +491,7 @@ struct vudc_device *alloc_vudc_device(int devid) { struct vudc_device *udc_dev; - udc_dev = kzalloc(sizeof(*udc_dev), GFP_KERNEL); + udc_dev = kzalloc_obj(*udc_dev); if (!udc_dev) return NULL; @@ -518,7 +518,7 @@ static int init_vudc_hw(struct vudc *udc) struct usbip_device *ud = &udc->ud; struct vep *ep; - udc->ep = kcalloc(VIRTUAL_ENDPOINTS, sizeof(*udc->ep), GFP_KERNEL); + udc->ep = kzalloc_objs(*udc->ep, VIRTUAL_ENDPOINTS); if (!udc->ep) goto nomem_ep; @@ -598,7 +598,7 @@ int vudc_probe(struct platform_device *pdev) struct vudc *udc; int ret = -ENOMEM; - udc = kzalloc(sizeof(*udc), GFP_KERNEL); + udc = kzalloc_obj(*udc); if (!udc) goto out; diff --git a/drivers/usb/usbip/vudc_tx.c b/drivers/usb/usbip/vudc_tx.c index 30c11bf9f4e7..88edfbcc0035 100644 --- a/drivers/usb/usbip/vudc_tx.c +++ b/drivers/usb/usbip/vudc_tx.c @@ -97,7 +97,7 @@ static int v_send_ret_submit(struct vudc *udc, struct urbp *urb_p) else iovnum = 2; - iov = kcalloc(iovnum, sizeof(*iov), GFP_KERNEL); + iov = kzalloc_objs(*iov, iovnum); if (!iov) { usbip_event_add(&udc->ud, VUDC_EVENT_ERROR_MALLOC); ret = -ENOMEM; @@ -246,12 +246,12 @@ void v_enqueue_ret_unlink(struct vudc *udc, __u32 seqnum, __u32 status) struct tx_item *txi; struct v_unlink *unlink; - txi = kzalloc(sizeof(*txi), GFP_ATOMIC); + txi = kzalloc_obj(*txi, GFP_ATOMIC); if (!txi) { usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); return; } - unlink = kzalloc(sizeof(*unlink), GFP_ATOMIC); + unlink = kzalloc_obj(*unlink, GFP_ATOMIC); if (!unlink) { kfree(txi); usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); @@ -271,7 +271,7 @@ void v_enqueue_ret_submit(struct vudc *udc, struct urbp *urb_p) { struct tx_item *txi; - txi = kzalloc(sizeof(*txi), GFP_ATOMIC); + txi = kzalloc_obj(*txi, GFP_ATOMIC); if (!txi) { usbip_event_add(&udc->ud, VDEV_EVENT_ERROR_MALLOC); return; diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c index 6658dc74d915..d46c1606c97a 100644 --- a/drivers/vdpa/ifcvf/ifcvf_main.c +++ b/drivers/vdpa/ifcvf/ifcvf_main.c @@ -793,7 +793,7 @@ static int ifcvf_probe(struct pci_dev *pdev, const struct pci_device_id *id) } pci_set_master(pdev); - ifcvf_mgmt_dev = kzalloc(sizeof(struct ifcvf_vdpa_mgmt_dev), GFP_KERNEL); + ifcvf_mgmt_dev = kzalloc_obj(struct ifcvf_vdpa_mgmt_dev); if (!ifcvf_mgmt_dev) { IFCVF_ERR(pdev, "Failed to alloc memory for the vDPA management device\n"); return -ENOMEM; diff --git a/drivers/vdpa/mlx5/core/mr.c b/drivers/vdpa/mlx5/core/mr.c index 8870a7169267..42c2705077a6 100644 --- a/drivers/vdpa/mlx5/core/mr.c +++ b/drivers/vdpa/mlx5/core/mr.c @@ -215,7 +215,7 @@ static int create_direct_keys(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr * int err = 0; int i = 0; - cmds = kvcalloc(mr->num_directs, sizeof(*cmds), GFP_KERNEL); + cmds = kvzalloc_objs(*cmds, mr->num_directs); if (!cmds) return -ENOMEM; @@ -287,8 +287,8 @@ static int destroy_direct_keys(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr int err = 0; int i = 0; - cmds = kvcalloc(mr->num_directs, sizeof(*cmds), GFP_KERNEL); - cmd_mem = kvcalloc(mr->num_directs, sizeof(*cmd_mem), GFP_KERNEL); + cmds = kvzalloc_objs(*cmds, mr->num_directs); + cmd_mem = kvzalloc_objs(*cmd_mem, mr->num_directs); if (!cmds || !cmd_mem) return -ENOMEM; @@ -456,7 +456,7 @@ static int add_direct_chain(struct mlx5_vdpa_dev *mvdev, st = start; while (size) { sz = (u32)min_t(u64, MAX_KLM_SIZE, size); - dmr = kzalloc(sizeof(*dmr), GFP_KERNEL); + dmr = kzalloc_obj(*dmr); if (!dmr) { err = -ENOMEM; goto err_alloc; @@ -817,7 +817,7 @@ struct mlx5_vdpa_mr *mlx5_vdpa_create_mr(struct mlx5_vdpa_dev *mvdev, struct mlx5_vdpa_mr *mr; int err; - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) return ERR_PTR(-ENOMEM); diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c index b7e46338815f..ad0d5fbbbca8 100644 --- a/drivers/vdpa/mlx5/net/mlx5_vnet.c +++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c @@ -1229,8 +1229,8 @@ static int query_virtqueues(struct mlx5_vdpa_net *ndev, WARN(start_vq + num_vqs > mvdev->max_vqs, "query vq range invalid [%d, %d), max_vqs: %u\n", start_vq, start_vq + num_vqs, mvdev->max_vqs); - cmds = kvcalloc(num_vqs, sizeof(*cmds), GFP_KERNEL); - cmd_mem = kvcalloc(num_vqs, sizeof(*cmd_mem), GFP_KERNEL); + cmds = kvzalloc_objs(*cmds, num_vqs); + cmd_mem = kvzalloc_objs(*cmd_mem, num_vqs); if (!cmds || !cmd_mem) { err = -ENOMEM; goto done; @@ -1562,8 +1562,8 @@ static int modify_virtqueues(struct mlx5_vdpa_net *ndev, int start_vq, int num_v WARN(start_vq + num_vqs > mvdev->max_vqs, "modify vq range invalid [%d, %d), max_vqs: %u\n", start_vq, start_vq + num_vqs, mvdev->max_vqs); - cmds = kvcalloc(num_vqs, sizeof(*cmds), GFP_KERNEL); - cmd_mem = kvcalloc(num_vqs, sizeof(*cmd_mem), GFP_KERNEL); + cmds = kvzalloc_objs(*cmds, num_vqs); + cmd_mem = kvzalloc_objs(*cmd_mem, num_vqs); if (!cmds || !cmd_mem) { err = -ENOMEM; goto done; @@ -1649,7 +1649,7 @@ static int suspend_vqs(struct mlx5_vdpa_net *ndev, int start_vq, int num_vqs) if (err) return err; - attrs = kcalloc(num_vqs, sizeof(struct mlx5_virtq_attr), GFP_KERNEL); + attrs = kzalloc_objs(struct mlx5_virtq_attr, num_vqs); if (!attrs) return -ENOMEM; @@ -1922,7 +1922,7 @@ static int mlx5_vdpa_add_mac_vlan_rules(struct mlx5_vdpa_net *ndev, u8 *mac, int err; u16 vid; - spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + spec = kvzalloc_obj(*spec); if (!spec) return -ENOMEM; @@ -2034,7 +2034,7 @@ static int mac_vlan_add(struct mlx5_vdpa_net *ndev, u8 *mac, u16 vid, bool tagge if (mac_vlan_lookup(ndev, val)) return -EEXIST; - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); if (!ptr) return -ENOMEM; @@ -2846,7 +2846,7 @@ static int queue_link_work(struct mlx5_vdpa_net *ndev) { struct mlx5_vdpa_wq_ent *wqent; - wqent = kzalloc(sizeof(*wqent), GFP_ATOMIC); + wqent = kzalloc_obj(*wqent, GFP_ATOMIC); if (!wqent) return -ENOMEM; @@ -3809,7 +3809,8 @@ static void allocate_irqs(struct mlx5_vdpa_net *ndev) if (!ndev->mvdev.mdev->pdev) return; - ndev->irqp.entries = kcalloc(ndev->mvdev.max_vqs, sizeof(*ndev->irqp.entries), GFP_KERNEL); + ndev->irqp.entries = kzalloc_objs(*ndev->irqp.entries, + ndev->mvdev.max_vqs); if (!ndev->irqp.entries) return; @@ -3901,8 +3902,8 @@ static int mlx5_vdpa_dev_add(struct vdpa_mgmt_dev *v_mdev, const char *name, mlx5_cmd_init_async_ctx(mdev, &mvdev->async_ctx); - ndev->vqs = kcalloc(max_vqs, sizeof(*ndev->vqs), GFP_KERNEL); - ndev->event_cbs = kcalloc(max_vqs + 1, sizeof(*ndev->event_cbs), GFP_KERNEL); + ndev->vqs = kzalloc_objs(*ndev->vqs, max_vqs); + ndev->event_cbs = kzalloc_objs(*ndev->event_cbs, max_vqs + 1); if (!ndev->vqs || !ndev->event_cbs) { err = -ENOMEM; goto err_alloc; @@ -4102,7 +4103,7 @@ static int mlx5v_probe(struct auxiliary_device *adev, struct mlx5_vdpa_mgmtdev *mgtdev; int err; - mgtdev = kzalloc(sizeof(*mgtdev), GFP_KERNEL); + mgtdev = kzalloc_obj(*mgtdev); if (!mgtdev) return -ENOMEM; diff --git a/drivers/vdpa/pds/aux_drv.c b/drivers/vdpa/pds/aux_drv.c index f57330cf9024..61314d56095d 100644 --- a/drivers/vdpa/pds/aux_drv.c +++ b/drivers/vdpa/pds/aux_drv.c @@ -39,7 +39,7 @@ static int pds_vdpa_probe(struct auxiliary_device *aux_dev, struct pds_vdpa_aux *vdpa_aux; int err; - vdpa_aux = kzalloc(sizeof(*vdpa_aux), GFP_KERNEL); + vdpa_aux = kzalloc_obj(*vdpa_aux); if (!vdpa_aux) return -ENOMEM; diff --git a/drivers/vdpa/solidrun/snet_main.c b/drivers/vdpa/solidrun/snet_main.c index 4588211d57eb..28d55315df2a 100644 --- a/drivers/vdpa/solidrun/snet_main.c +++ b/drivers/vdpa/solidrun/snet_main.c @@ -732,7 +732,7 @@ static int psnet_read_cfg(struct pci_dev *pdev, struct psnet *psnet) /* Load device configuration from BAR */ for (i = 0; i < cfg->devices_num; i++) { - cfg->devs[i] = kzalloc(sizeof(*cfg->devs[i]), GFP_KERNEL); + cfg->devs[i] = kzalloc_obj(*cfg->devs[i]); if (!cfg->devs[i]) { snet_free_cfg(cfg); return -ENOMEM; @@ -827,7 +827,7 @@ static int snet_build_vqs(struct snet *snet) /* Allocate the VQs */ for (i = 0; i < snet->cfg->vq_num; i++) { - snet->vqs[i] = kzalloc(sizeof(*snet->vqs[i]), GFP_KERNEL); + snet->vqs[i] = kzalloc_obj(*snet->vqs[i]); if (!snet->vqs[i]) { snet_free_vqs(snet); return -ENOMEM; @@ -902,7 +902,7 @@ static int snet_vdpa_probe_pf(struct pci_dev *pdev) } /* Allocate a PCI physical function device */ - psnet = kzalloc(sizeof(*psnet), GFP_KERNEL); + psnet = kzalloc_obj(*psnet); if (!psnet) return -ENOMEM; diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim.c b/drivers/vdpa/vdpa_sim/vdpa_sim.c index df9c7ddc5d78..8cb1cc2ea139 100644 --- a/drivers/vdpa/vdpa_sim/vdpa_sim.c +++ b/drivers/vdpa/vdpa_sim/vdpa_sim.c @@ -246,18 +246,16 @@ struct vdpasim *vdpasim_create(struct vdpasim_dev_attr *dev_attr, if (!vdpasim->config) goto err_iommu; - vdpasim->vqs = kcalloc(dev_attr->nvqs, sizeof(struct vdpasim_virtqueue), - GFP_KERNEL); + vdpasim->vqs = kzalloc_objs(struct vdpasim_virtqueue, dev_attr->nvqs); if (!vdpasim->vqs) goto err_iommu; - vdpasim->iommu = kmalloc_array(vdpasim->dev_attr.nas, - sizeof(*vdpasim->iommu), GFP_KERNEL); + vdpasim->iommu = kmalloc_objs(*vdpasim->iommu, vdpasim->dev_attr.nas); if (!vdpasim->iommu) goto err_iommu; - vdpasim->iommu_pt = kmalloc_array(vdpasim->dev_attr.nas, - sizeof(*vdpasim->iommu_pt), GFP_KERNEL); + vdpasim->iommu_pt = kmalloc_objs(*vdpasim->iommu_pt, + vdpasim->dev_attr.nas); if (!vdpasim->iommu_pt) goto err_iommu; diff --git a/drivers/vdpa/vdpa_user/iova_domain.c b/drivers/vdpa/vdpa_user/iova_domain.c index 0a9f668467a8..806cec32c4bc 100644 --- a/drivers/vdpa/vdpa_user/iova_domain.c +++ b/drivers/vdpa/vdpa_user/iova_domain.c @@ -25,7 +25,7 @@ static int vduse_iotlb_add_range(struct vduse_iova_domain *domain, struct vdpa_map_file *map_file; int ret; - map_file = kmalloc(sizeof(*map_file), GFP_ATOMIC); + map_file = kmalloc_obj(*map_file, GFP_ATOMIC); if (!map_file) return -ENOMEM; @@ -622,7 +622,7 @@ vduse_domain_create(unsigned long iova_limit, size_t bounce_size) if (iova_limit <= bounce_size) return NULL; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) return NULL; diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c index 405d59610f76..6202f6902fcd 100644 --- a/drivers/vdpa/vdpa_user/vduse_dev.c +++ b/drivers/vdpa/vdpa_user/vduse_dev.c @@ -1232,7 +1232,7 @@ static int vduse_dev_reg_umem(struct vduse_dev *dev, npages = size >> PAGE_SHIFT; page_list = __vmalloc(array_size(npages, sizeof(struct page *)), GFP_KERNEL_ACCOUNT); - umem = kzalloc(sizeof(*umem), GFP_KERNEL); + umem = kzalloc_obj(*umem); if (!page_list || !umem) goto unlock; @@ -1800,12 +1800,12 @@ static int vduse_dev_init_vqs(struct vduse_dev *dev, u32 vq_align, u32 vq_num) dev->vq_align = vq_align; dev->vq_num = vq_num; - dev->vqs = kcalloc(dev->vq_num, sizeof(*dev->vqs), GFP_KERNEL); + dev->vqs = kzalloc_objs(*dev->vqs, dev->vq_num); if (!dev->vqs) return -ENOMEM; for (i = 0; i < vq_num; i++) { - dev->vqs[i] = kzalloc(sizeof(*dev->vqs[i]), GFP_KERNEL); + dev->vqs[i] = kzalloc_obj(*dev->vqs[i]); if (!dev->vqs[i]) { ret = -ENOMEM; goto err; @@ -1839,7 +1839,7 @@ static int vduse_dev_init_vqs(struct vduse_dev *dev, u32 vq_align, u32 vq_num) static struct vduse_dev *vduse_dev_create(void) { - struct vduse_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); + struct vduse_dev *dev = kzalloc_obj(*dev); if (!dev) return NULL; @@ -2076,7 +2076,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, dev->vendor_id = config->vendor_id; dev->nas = (dev->api_version < VDUSE_API_VERSION_1) ? 1 : config->nas; - dev->as = kcalloc(dev->nas, sizeof(dev->as[0]), GFP_KERNEL); + dev->as = kzalloc_objs(dev->as[0], dev->nas); if (!dev->as) goto err_as; for (int i = 0; i < dev->nas; i++) @@ -2085,8 +2085,7 @@ static int vduse_create_dev(struct vduse_dev_config *config, dev->ngroups = (dev->api_version < VDUSE_API_VERSION_1) ? 1 : config->ngroups; - dev->groups = kcalloc(dev->ngroups, sizeof(dev->groups[0]), - GFP_KERNEL); + dev->groups = kzalloc_objs(dev->groups[0], dev->ngroups); if (!dev->groups) goto err_vq_groups; for (u32 i = 0; i < dev->ngroups; ++i) { @@ -2227,7 +2226,7 @@ static int vduse_open(struct inode *inode, struct file *file) { struct vduse_control *control; - control = kmalloc(sizeof(struct vduse_control), GFP_KERNEL); + control = kmalloc_obj(struct vduse_control); if (!control) return -ENOMEM; @@ -2357,7 +2356,7 @@ static int vduse_mgmtdev_init(void) { int ret; - vduse_mgmt = kzalloc(sizeof(*vduse_mgmt), GFP_KERNEL); + vduse_mgmt = kzalloc_obj(*vduse_mgmt); if (!vduse_mgmt) return -ENOMEM; diff --git a/drivers/vdpa/virtio_pci/vp_vdpa.c b/drivers/vdpa/virtio_pci/vp_vdpa.c index 17a19a728c9c..51ffc245a038 100644 --- a/drivers/vdpa/virtio_pci/vp_vdpa.c +++ b/drivers/vdpa/virtio_pci/vp_vdpa.c @@ -608,7 +608,7 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct virtio_device_id *mdev_id = NULL; int err; - vp_vdpa_mgtdev = kzalloc(sizeof(*vp_vdpa_mgtdev), GFP_KERNEL); + vp_vdpa_mgtdev = kzalloc_obj(*vp_vdpa_mgtdev); if (!vp_vdpa_mgtdev) return -ENOMEM; @@ -616,7 +616,7 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) mgtdev->ops = &vp_vdpa_mdev_ops; mgtdev->device = dev; - mdev = kzalloc(sizeof(struct virtio_pci_modern_device), GFP_KERNEL); + mdev = kzalloc_obj(struct virtio_pci_modern_device); if (!mdev) { err = -ENOMEM; goto mdev_err; @@ -626,7 +626,7 @@ static int vp_vdpa_probe(struct pci_dev *pdev, const struct pci_device_id *id) * id_table should be a null terminated array, so allocate one additional * entry here, see vdpa_mgmtdev_get_classes(). */ - mdev_id = kcalloc(2, sizeof(struct virtio_device_id), GFP_KERNEL); + mdev_id = kzalloc_objs(struct virtio_device_id, 2); if (!mdev_id) { err = -ENOMEM; goto mdev_id_err; diff --git a/drivers/vfio/cdx/intr.c b/drivers/vfio/cdx/intr.c index 986fa2a45fa4..8f4402cec9c5 100644 --- a/drivers/vfio/cdx/intr.c +++ b/drivers/vfio/cdx/intr.c @@ -27,7 +27,7 @@ static int vfio_cdx_msi_enable(struct vfio_cdx_device *vdev, int nvec) struct device *dev = vdev->vdev.dev; int msi_idx, ret; - vdev->cdx_irqs = kcalloc(nvec, sizeof(struct vfio_cdx_irq), GFP_KERNEL); + vdev->cdx_irqs = kzalloc_objs(struct vfio_cdx_irq, nvec); if (!vdev->cdx_irqs) return -ENOMEM; diff --git a/drivers/vfio/cdx/main.c b/drivers/vfio/cdx/main.c index 253031b86b60..8ab97405b2bd 100644 --- a/drivers/vfio/cdx/main.c +++ b/drivers/vfio/cdx/main.c @@ -16,8 +16,8 @@ static int vfio_cdx_open_device(struct vfio_device *core_vdev) int count = cdx_dev->res_count; int i, ret; - vdev->regions = kcalloc(count, sizeof(struct vfio_cdx_region), - GFP_KERNEL_ACCOUNT); + vdev->regions = kzalloc_objs(struct vfio_cdx_region, count, + GFP_KERNEL_ACCOUNT); if (!vdev->regions) return -ENOMEM; diff --git a/drivers/vfio/container.c b/drivers/vfio/container.c index d53d08f16973..003281dbf8bc 100644 --- a/drivers/vfio/container.c +++ b/drivers/vfio/container.c @@ -95,7 +95,7 @@ int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops) if (WARN_ON(!ops->register_device != !ops->unregister_device)) return -EINVAL; - driver = kzalloc(sizeof(*driver), GFP_KERNEL); + driver = kzalloc_obj(*driver); if (!driver) return -ENOMEM; @@ -360,7 +360,7 @@ static int vfio_fops_open(struct inode *inode, struct file *filep) { struct vfio_container *container; - container = kzalloc(sizeof(*container), GFP_KERNEL_ACCOUNT); + container = kzalloc_obj(*container, GFP_KERNEL_ACCOUNT); if (!container) return -ENOMEM; diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc.c b/drivers/vfio/fsl-mc/vfio_fsl_mc.c index 3985613e6830..462fae1aa538 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc.c @@ -27,8 +27,8 @@ static int vfio_fsl_mc_open_device(struct vfio_device *core_vdev) int count = mc_dev->obj_desc.region_count; int i; - vdev->regions = kcalloc(count, sizeof(struct vfio_fsl_mc_region), - GFP_KERNEL_ACCOUNT); + vdev->regions = kzalloc_objs(struct vfio_fsl_mc_region, count, + GFP_KERNEL_ACCOUNT); if (!vdev->regions) return -ENOMEM; diff --git a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c index 7e7988c4258f..d0fedd9aa7c5 100644 --- a/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c +++ b/drivers/vfio/fsl-mc/vfio_fsl_mc_intr.c @@ -29,7 +29,7 @@ static int vfio_fsl_mc_irqs_allocate(struct vfio_fsl_mc_device *vdev) irq_count = mc_dev->obj_desc.irq_count; - mc_irq = kcalloc(irq_count, sizeof(*mc_irq), GFP_KERNEL_ACCOUNT); + mc_irq = kzalloc_objs(*mc_irq, irq_count, GFP_KERNEL_ACCOUNT); if (!mc_irq) return -ENOMEM; diff --git a/drivers/vfio/group.c b/drivers/vfio/group.c index d47ffada6912..4f15016d2a5f 100644 --- a/drivers/vfio/group.c +++ b/drivers/vfio/group.c @@ -515,7 +515,7 @@ static struct vfio_group *vfio_group_alloc(struct iommu_group *iommu_group, struct vfio_group *group; int minor; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/mdev/mdev_core.c b/drivers/vfio/mdev/mdev_core.c index f2e686f8f1ef..3b4aa0632fcc 100644 --- a/drivers/vfio/mdev/mdev_core.c +++ b/drivers/vfio/mdev/mdev_core.c @@ -154,7 +154,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid) atomic_dec(&parent->available_instances); } - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) { mutex_unlock(&mdev_list_lock); return -ENOMEM; diff --git a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c index e61df3fe0db9..1d367cff7dcf 100644 --- a/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c +++ b/drivers/vfio/pci/hisilicon/hisi_acc_vfio_pci.c @@ -831,7 +831,7 @@ hisi_acc_vf_pci_resume(struct hisi_acc_vf_core_device *hisi_acc_vdev) { struct hisi_acc_vf_migration_file *migf; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); @@ -953,7 +953,7 @@ hisi_acc_open_saving_migf(struct hisi_acc_vf_core_device *hisi_acc_vdev) struct hisi_acc_vf_migration_file *migf; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); @@ -1498,7 +1498,7 @@ static int hisi_acc_vf_dev_read(struct seq_file *seq, void *data) } mutex_lock(&hisi_acc_vdev->state_mutex); - vf_data = kzalloc(sizeof(*vf_data), GFP_KERNEL); + vf_data = kzalloc_obj(*vf_data); if (!vf_data) { ret = -ENOMEM; goto mutex_release; @@ -1679,7 +1679,7 @@ static void hisi_acc_vfio_debug_init(struct hisi_acc_vf_core_device *hisi_acc_vd return; } - migf = kzalloc(sizeof(*migf), GFP_KERNEL); + migf = kzalloc_obj(*migf); if (!migf) { dput(vfio_dev_migration); return; diff --git a/drivers/vfio/pci/mlx5/cmd.c b/drivers/vfio/pci/mlx5/cmd.c index a92b095b90f6..ca6d95f293cd 100644 --- a/drivers/vfio/pci/mlx5/cmd.c +++ b/drivers/vfio/pci/mlx5/cmd.c @@ -492,7 +492,7 @@ static int mlx5vf_add_pages(struct page ***page_list, unsigned int npages) int i; *page_list = - kvcalloc(npages, sizeof(struct page *), GFP_KERNEL_ACCOUNT); + kvzalloc_objs(struct page *, npages, GFP_KERNEL_ACCOUNT); if (!*page_list) return -ENOMEM; @@ -525,7 +525,7 @@ mlx5vf_alloc_data_buffer(struct mlx5_vf_migration_file *migf, u32 npages, struct mlx5_vhca_data_buffer *buf; int ret; - buf = kzalloc(sizeof(*buf), GFP_KERNEL_ACCOUNT); + buf = kzalloc_obj(*buf, GFP_KERNEL_ACCOUNT); if (!buf) return ERR_PTR(-ENOMEM); @@ -1233,7 +1233,7 @@ mlx5vf_create_rc_qp(struct mlx5_core_dev *mdev, void *in; int err; - qp = kzalloc(sizeof(*qp), GFP_KERNEL_ACCOUNT); + qp = kzalloc_obj(*qp, GFP_KERNEL_ACCOUNT); if (!qp) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/pci/mlx5/main.c b/drivers/vfio/pci/mlx5/main.c index 9c5970411d07..dbba6173894b 100644 --- a/drivers/vfio/pci/mlx5/main.c +++ b/drivers/vfio/pci/mlx5/main.c @@ -608,7 +608,7 @@ mlx5vf_pci_save_device_data(struct mlx5vf_pci_core_device *mvdev, bool track) u64 full_size; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); @@ -989,7 +989,7 @@ mlx5vf_pci_resume_device_data(struct mlx5vf_pci_core_device *mvdev) struct mlx5_vhca_data_buffer *buf; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/pci/pds/dirty.c b/drivers/vfio/pci/pds/dirty.c index 4915a7c1c491..08488eda2b3b 100644 --- a/drivers/vfio/pci/pds/dirty.c +++ b/drivers/vfio/pci/pds/dirty.c @@ -43,9 +43,7 @@ pds_vfio_print_guest_region_info(struct pds_vfio_pci_device *pds_vfio, u8 num_regions; int err; - region_info = kcalloc(max_regions, - sizeof(struct pds_lm_dirty_region_info), - GFP_KERNEL); + region_info = kzalloc_objs(struct pds_lm_dirty_region_info, max_regions); if (!region_info) return; @@ -286,7 +284,7 @@ static int pds_vfio_dirty_enable(struct pds_vfio_pci_device *pds_vfio, num_ranges = max_regions; } - region_info = kcalloc(num_ranges, sizeof(*region_info), GFP_KERNEL); + region_info = kzalloc_objs(*region_info, num_ranges); if (!region_info) return -ENOMEM; len = num_ranges * sizeof(*region_info); @@ -398,7 +396,7 @@ static int pds_vfio_dirty_seq_ack(struct pds_vfio_pci_device *pds_vfio, * will be enough pages to represent the bmp_bytes */ npages = DIV_ROUND_UP_ULL(bmp_bytes + page_offset, PAGE_SIZE); - pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, npages); if (!pages) return -ENOMEM; diff --git a/drivers/vfio/pci/pds/lm.c b/drivers/vfio/pci/pds/lm.c index 4d70c833fa32..08487eab11b0 100644 --- a/drivers/vfio/pci/pds/lm.c +++ b/drivers/vfio/pci/pds/lm.c @@ -24,7 +24,7 @@ pds_vfio_get_lm_file(const struct file_operations *fops, int flags, u64 size) return NULL; /* Alloc file structure */ - lm_file = kzalloc(sizeof(*lm_file), GFP_KERNEL); + lm_file = kzalloc_obj(*lm_file); if (!lm_file) return NULL; @@ -42,7 +42,7 @@ pds_vfio_get_lm_file(const struct file_operations *fops, int flags, u64 size) /* Allocate memory for file pages */ npages = DIV_ROUND_UP_ULL(size, PAGE_SIZE); - pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, npages); if (!pages) goto out_put_file; diff --git a/drivers/vfio/pci/qat/main.c b/drivers/vfio/pci/qat/main.c index 8fbdf7c6d666..b982d4ae666c 100644 --- a/drivers/vfio/pci/qat/main.c +++ b/drivers/vfio/pci/qat/main.c @@ -261,7 +261,7 @@ qat_vf_save_device_data(struct qat_vf_core_device *qat_vdev, bool pre_copy) struct qat_vf_migration_file *migf; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL); + migf = kzalloc_obj(*migf); if (!migf) return ERR_PTR(-ENOMEM); @@ -352,7 +352,7 @@ qat_vf_resume_device_data(struct qat_vf_core_device *qat_vdev) struct qat_vf_migration_file *migf; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL); + migf = kzalloc_obj(*migf); if (!migf) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index dc4e510e6e1b..b4e39253f98d 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1265,7 +1265,7 @@ static int vfio_msi_cap_len(struct vfio_pci_core_device *vdev, u8 pos) if (vdev->msi_perm) return len; - vdev->msi_perm = kmalloc(sizeof(struct perm_bits), GFP_KERNEL_ACCOUNT); + vdev->msi_perm = kmalloc_obj(struct perm_bits, GFP_KERNEL_ACCOUNT); if (!vdev->msi_perm) return -ENOMEM; diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c index 72c33b399800..d43745fe4c84 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -61,7 +61,7 @@ int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, lockdep_assert_held(&vdev->igate); if (ctx) { - new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); + new = kzalloc_obj(*new, GFP_KERNEL_ACCOUNT); if (!new) return -ENOMEM; @@ -175,8 +175,7 @@ static void vfio_pci_probe_mmaps(struct vfio_pci_core_device *vdev) * of the exclusive page in case that hot-add * device's bar is assigned into it. */ - dummy_res = - kzalloc(sizeof(*dummy_res), GFP_KERNEL_ACCOUNT); + dummy_res = kzalloc_obj(*dummy_res, GFP_KERNEL_ACCOUNT); if (dummy_res == NULL) goto no_mmap; @@ -1292,7 +1291,7 @@ static int vfio_pci_ioctl_get_pci_hot_reset_info( goto header; } - devices = kcalloc(count, sizeof(*devices), GFP_KERNEL); + devices = kzalloc_objs(*devices, count); if (!devices) return -ENOMEM; @@ -1351,8 +1350,8 @@ vfio_pci_ioctl_pci_hot_reset_groups(struct vfio_pci_core_device *vdev, if (array_count > count) return -EINVAL; - group_fds = kcalloc(array_count, sizeof(*group_fds), GFP_KERNEL); - files = kcalloc(array_count, sizeof(*files), GFP_KERNEL); + group_fds = kzalloc_objs(*group_fds, array_count); + files = kzalloc_objs(*files, array_count); if (!group_fds || !files) { kfree(group_fds); kfree(files); @@ -2035,7 +2034,7 @@ static int vfio_pci_vf_init(struct vfio_pci_core_device *vdev) if (!pdev->is_physfn) return 0; - vdev->vf_token = kzalloc(sizeof(*vdev->vf_token), GFP_KERNEL); + vdev->vf_token = kzalloc_obj(*vdev->vf_token); if (!vdev->vf_token) return -ENOMEM; diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c index 9918713d5774..478beafc6ac3 100644 --- a/drivers/vfio/pci/vfio_pci_dmabuf.c +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c @@ -246,13 +246,12 @@ int vfio_pci_core_feature_dma_buf(struct vfio_pci_core_device *vdev, u32 flags, if (ret) goto err_free_ranges; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) { ret = -ENOMEM; goto err_free_ranges; } - priv->phys_vec = kcalloc(get_dma_buf.nr_ranges, sizeof(*priv->phys_vec), - GFP_KERNEL); + priv->phys_vec = kzalloc_objs(*priv->phys_vec, get_dma_buf.nr_ranges); if (!priv->phys_vec) { ret = -ENOMEM; goto err_free_priv; diff --git a/drivers/vfio/pci/vfio_pci_igd.c b/drivers/vfio/pci/vfio_pci_igd.c index 988b6919c2c3..24f3118fc61b 100644 --- a/drivers/vfio/pci/vfio_pci_igd.c +++ b/drivers/vfio/pci/vfio_pci_igd.c @@ -180,7 +180,7 @@ static int vfio_pci_igd_opregion_init(struct vfio_pci_core_device *vdev) if (!addr || !(~addr)) return -ENODEV; - opregionvbt = kzalloc(sizeof(*opregionvbt), GFP_KERNEL_ACCOUNT); + opregionvbt = kzalloc_obj(*opregionvbt, GFP_KERNEL_ACCOUNT); if (!opregionvbt) return -ENOMEM; diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index c76e753b3cec..33944d4d9dc4 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -69,7 +69,7 @@ vfio_irq_ctx_alloc(struct vfio_pci_core_device *vdev, unsigned long index) struct vfio_pci_irq_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); + ctx = kzalloc_obj(*ctx, GFP_KERNEL_ACCOUNT); if (!ctx) return NULL; diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c index b38627b35c35..4251ee03e146 100644 --- a/drivers/vfio/pci/vfio_pci_rdwr.c +++ b/drivers/vfio/pci/vfio_pci_rdwr.c @@ -484,7 +484,7 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset, goto out_unlock; } - ioeventfd = kzalloc(sizeof(*ioeventfd), GFP_KERNEL_ACCOUNT); + ioeventfd = kzalloc_obj(*ioeventfd, GFP_KERNEL_ACCOUNT); if (!ioeventfd) { ret = -ENOMEM; goto out_unlock; diff --git a/drivers/vfio/pci/virtio/migrate.c b/drivers/vfio/pci/virtio/migrate.c index 7dd0ac866461..35fa2d6ed611 100644 --- a/drivers/vfio/pci/virtio/migrate.c +++ b/drivers/vfio/pci/virtio/migrate.c @@ -71,7 +71,7 @@ static int virtiovf_add_migration_pages(struct virtiovf_data_buffer *buf, int i; to_fill = min_t(unsigned int, npages, PAGE_SIZE / sizeof(*page_list)); - page_list = kvcalloc(to_fill, sizeof(*page_list), GFP_KERNEL_ACCOUNT); + page_list = kvzalloc_objs(*page_list, to_fill, GFP_KERNEL_ACCOUNT); if (!page_list) return -ENOMEM; @@ -124,7 +124,7 @@ virtiovf_alloc_data_buffer(struct virtiovf_migration_file *migf, size_t length) struct virtiovf_data_buffer *buf; int ret; - buf = kzalloc(sizeof(*buf), GFP_KERNEL_ACCOUNT); + buf = kzalloc_obj(*buf, GFP_KERNEL_ACCOUNT); if (!buf) return ERR_PTR(-ENOMEM); @@ -676,7 +676,7 @@ virtiovf_pci_save_device_data(struct virtiovf_pci_core_device *virtvdev, u32 obj_id; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); @@ -1066,7 +1066,7 @@ virtiovf_pci_resume_device_data(struct virtiovf_pci_core_device *virtvdev) u32 obj_id; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/pci/xe/main.c b/drivers/vfio/pci/xe/main.c index 2a5eb9260ec7..fff95b2d5dde 100644 --- a/drivers/vfio/pci/xe/main.c +++ b/drivers/vfio/pci/xe/main.c @@ -252,7 +252,7 @@ xe_vfio_pci_alloc_file(struct xe_vfio_pci_core_device *xe_vdev, int flags; int ret; - migf = kzalloc(sizeof(*migf), GFP_KERNEL_ACCOUNT); + migf = kzalloc_obj(*migf, GFP_KERNEL_ACCOUNT); if (!migf) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c index c2990b7e900f..c72db5a99ebd 100644 --- a/drivers/vfio/platform/vfio_platform_common.c +++ b/drivers/vfio/platform/vfio_platform_common.c @@ -141,8 +141,8 @@ static int vfio_platform_regions_init(struct vfio_platform_device *vdev) while (vdev->get_resource(vdev, cnt)) cnt++; - vdev->regions = kcalloc(cnt, sizeof(struct vfio_platform_region), - GFP_KERNEL_ACCOUNT); + vdev->regions = kzalloc_objs(struct vfio_platform_region, cnt, + GFP_KERNEL_ACCOUNT); if (!vdev->regions) return -ENOMEM; diff --git a/drivers/vfio/platform/vfio_platform_irq.c b/drivers/vfio/platform/vfio_platform_irq.c index ef41ecef83af..d16596e7f266 100644 --- a/drivers/vfio/platform/vfio_platform_irq.c +++ b/drivers/vfio/platform/vfio_platform_irq.c @@ -291,8 +291,8 @@ int vfio_platform_irq_init(struct vfio_platform_device *vdev) while (vdev->get_irq(vdev, cnt) >= 0) cnt++; - vdev->irqs = kcalloc(cnt, sizeof(struct vfio_platform_irq), - GFP_KERNEL_ACCOUNT); + vdev->irqs = kzalloc_objs(struct vfio_platform_irq, cnt, + GFP_KERNEL_ACCOUNT); if (!vdev->irqs) return -ENOMEM; diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 5f9e7e477078..1c0eec228cc6 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -159,7 +159,7 @@ static long tce_iommu_register_pages(struct tce_container *container, return ret; } - tcemem = kzalloc(sizeof(*tcemem), GFP_KERNEL); + tcemem = kzalloc_obj(*tcemem); if (!tcemem) { ret = -ENOMEM; goto put_exit; @@ -322,7 +322,7 @@ static void *tce_iommu_open(unsigned long arg) return ERR_PTR(-EINVAL); } - container = kzalloc(sizeof(*container), GFP_KERNEL); + container = kzalloc_obj(*container); if (!container) return ERR_PTR(-ENOMEM); @@ -1290,7 +1290,7 @@ static int tce_iommu_attach_group(void *iommu_data, } } - tcegrp = kzalloc(sizeof(*tcegrp), GFP_KERNEL); + tcegrp = kzalloc_obj(*tcegrp); if (!tcegrp) { ret = -ENOMEM; goto unlock_exit; diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 5167bec14e36..03cefdf99a4a 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -388,7 +388,7 @@ static int vfio_add_to_pfn_list(struct vfio_dma *dma, dma_addr_t iova, { struct vfio_pfn *vpfn; - vpfn = kzalloc(sizeof(*vpfn), GFP_KERNEL); + vpfn = kzalloc_obj(*vpfn); if (!vpfn) return -ENOMEM; @@ -1097,7 +1097,7 @@ static size_t unmap_unpin_fast(struct vfio_domain *domain, struct iommu_iotlb_gather *iotlb_gather) { size_t unmapped = 0; - struct vfio_regions *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct vfio_regions *entry = kzalloc_obj(*entry); if (entry) { unmapped = iommu_unmap_fast(domain->domain, iova, len, @@ -1753,7 +1753,7 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, goto out_unlock; } - dma = kzalloc(sizeof(*dma), GFP_KERNEL); + dma = kzalloc_obj(*dma); if (!dma) { ret = -ENOMEM; goto out_unlock; @@ -2017,7 +2017,7 @@ static int vfio_iommu_iova_insert(struct list_head *head, { struct vfio_iova *region; - region = kmalloc(sizeof(*region), GFP_KERNEL); + region = kmalloc_obj(*region); if (!region) return -ENOMEM; @@ -2259,7 +2259,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, goto out_unlock; ret = -ENOMEM; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) goto out_unlock; group->iommu_group = iommu_group; @@ -2278,7 +2278,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, } ret = -ENOMEM; - domain = kzalloc(sizeof(*domain), GFP_KERNEL); + domain = kzalloc_obj(*domain); if (!domain) goto out_free_group; @@ -2625,7 +2625,7 @@ static void *vfio_iommu_type1_open(unsigned long arg) { struct vfio_iommu *iommu; - iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); + iommu = kzalloc_obj(*iommu); if (!iommu) return ERR_PTR(-ENOMEM); diff --git a/drivers/vfio/vfio_main.c b/drivers/vfio/vfio_main.c index f7df90c423b4..742477546b15 100644 --- a/drivers/vfio/vfio_main.c +++ b/drivers/vfio/vfio_main.c @@ -82,7 +82,7 @@ int vfio_assign_device_set(struct vfio_device *device, void *set_id) goto found_get_ref; xa_unlock(&vfio_device_set_xa); - new_dev_set = kzalloc(sizeof(*new_dev_set), GFP_KERNEL); + new_dev_set = kzalloc_obj(*new_dev_set); if (!new_dev_set) return -ENOMEM; mutex_init(&new_dev_set->lock); @@ -495,7 +495,7 @@ vfio_allocate_device_file(struct vfio_device *device) { struct vfio_device_file *df; - df = kzalloc(sizeof(*df), GFP_KERNEL_ACCOUNT); + df = kzalloc_obj(*df, GFP_KERNEL_ACCOUNT); if (!df) return ERR_PTR(-ENOMEM); @@ -1083,8 +1083,7 @@ vfio_ioctl_device_feature_logging_start(struct vfio_device *device, return -E2BIG; ranges = u64_to_user_ptr(control.ranges); - nodes = kmalloc_array(nnodes, sizeof(struct interval_tree_node), - GFP_KERNEL); + nodes = kmalloc_objs(struct interval_tree_node, nnodes); if (!nodes) return -ENOMEM; diff --git a/drivers/vfio/virqfd.c b/drivers/vfio/virqfd.c index aa2891f97508..59105a0ace4c 100644 --- a/drivers/vfio/virqfd.c +++ b/drivers/vfio/virqfd.c @@ -118,7 +118,7 @@ int vfio_virqfd_enable(void *opaque, int ret = 0; __poll_t events; - virqfd = kzalloc(sizeof(*virqfd), GFP_KERNEL_ACCOUNT); + virqfd = kzalloc_obj(*virqfd, GFP_KERNEL_ACCOUNT); if (!virqfd) return -ENOMEM; diff --git a/drivers/vhost/iotlb.c b/drivers/vhost/iotlb.c index ea61330a3431..e1414c774c34 100644 --- a/drivers/vhost/iotlb.c +++ b/drivers/vhost/iotlb.c @@ -79,7 +79,7 @@ int vhost_iotlb_add_range_ctx(struct vhost_iotlb *iotlb, vhost_iotlb_map_free(iotlb, map); } - map = kmalloc(sizeof(*map), GFP_ATOMIC); + map = kmalloc_obj(*map, GFP_ATOMIC); if (!map) return -ENOMEM; @@ -151,7 +151,7 @@ EXPORT_SYMBOL_GPL(vhost_iotlb_init); */ struct vhost_iotlb *vhost_iotlb_alloc(unsigned int limit, unsigned int flags) { - struct vhost_iotlb *iotlb = kzalloc(sizeof(*iotlb), GFP_KERNEL); + struct vhost_iotlb *iotlb = kzalloc_obj(*iotlb); if (!iotlb) return NULL; diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 7f886d3dba7d..80965181920c 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -240,7 +240,7 @@ vhost_net_ubuf_alloc(struct vhost_virtqueue *vq, bool zcopy) /* No zero copy backend? Nothing to count. */ if (!zcopy) return NULL; - ubufs = kmalloc(sizeof(*ubufs), GFP_KERNEL); + ubufs = kmalloc_obj(*ubufs); if (!ubufs) return ERR_PTR(-ENOMEM); atomic_set(&ubufs->refcount, 1); @@ -293,9 +293,7 @@ static int vhost_net_set_ubuf_info(struct vhost_net *n) if (!zcopy) continue; n->vqs[i].ubuf_info = - kmalloc_array(UIO_MAXIOV, - sizeof(*n->vqs[i].ubuf_info), - GFP_KERNEL); + kmalloc_objs(*n->vqs[i].ubuf_info, UIO_MAXIOV); if (!n->vqs[i].ubuf_info) goto err; } @@ -1328,10 +1326,10 @@ static int vhost_net_open(struct inode *inode, struct file *f) struct xdp_buff *xdp; int i; - n = kvmalloc(sizeof *n, GFP_KERNEL | __GFP_RETRY_MAYFAIL); + n = kvmalloc_obj(*n, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!n) return -ENOMEM; - vqs = kmalloc_array(VHOST_NET_VQ_MAX, sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_objs(*vqs, VHOST_NET_VQ_MAX); if (!vqs) { kvfree(n); return -ENOMEM; @@ -1346,7 +1344,7 @@ static int vhost_net_open(struct inode *inode, struct file *f) } n->vqs[VHOST_NET_VQ_RX].rxq.queue = queue; - xdp = kmalloc_array(VHOST_NET_BATCH, sizeof(*xdp), GFP_KERNEL); + xdp = kmalloc_objs(*xdp, VHOST_NET_BATCH); if (!xdp) { kfree(vqs); kvfree(n); diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index f43c1fe9fad9..1c22880e7226 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -382,9 +382,7 @@ static int vhost_scsi_copy_cmd_log(struct vhost_virtqueue *vq, unsigned int log_num) { if (!cmd->tvc_log) - cmd->tvc_log = kmalloc_array(vq->dev->iov_limit, - sizeof(*cmd->tvc_log), - GFP_KERNEL); + cmd->tvc_log = kmalloc_objs(*cmd->tvc_log, vq->dev->iov_limit); if (unlikely(!cmd->tvc_log)) { vq_err(vq, "Failed to alloc tvc_log\n"); @@ -549,7 +547,7 @@ vhost_scsi_allocate_evt(struct vhost_scsi *vs, return NULL; } - evt = kzalloc(sizeof(*evt), GFP_KERNEL); + evt = kzalloc_obj(*evt); if (!evt) { vq_err(vq, "Failed to allocate vhost_scsi_evt\n"); vs->vs_events_missed = true; @@ -897,7 +895,7 @@ vhost_scsi_copy_iov_to_sgl(struct vhost_scsi_cmd *cmd, struct iov_iter *iter, int i, ret; if (data_dir == DMA_FROM_DEVICE) { - cmd->read_iter = kzalloc(sizeof(*cmd->read_iter), GFP_KERNEL); + cmd->read_iter = kzalloc_obj(*cmd->read_iter); if (!cmd->read_iter) return -ENOMEM; @@ -1264,8 +1262,7 @@ vhost_scsi_setup_resp_iovs(struct vhost_scsi_cmd *cmd, struct iovec *in_iovs, * iov per byte. */ cnt = min(VHOST_SCSI_MAX_RESP_IOVS, in_iovs_cnt); - cmd->tvc_resp_iovs = kcalloc(cnt, sizeof(struct iovec), - GFP_KERNEL); + cmd->tvc_resp_iovs = kzalloc_objs(struct iovec, cnt); if (!cmd->tvc_resp_iovs) return -ENOMEM; @@ -1603,7 +1600,7 @@ vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg, goto send_reject; } - tmf = kzalloc(sizeof(*tmf), GFP_KERNEL); + tmf = kzalloc_obj(*tmf); if (!tmf) goto send_reject; @@ -1617,8 +1614,7 @@ vhost_scsi_handle_tmf(struct vhost_scsi *vs, struct vhost_scsi_tpg *tpg, tmf->inflight = vhost_scsi_get_inflight(vq); if (unlikely(log && log_num)) { - tmf->tmf_log = kmalloc_array(log_num, sizeof(*tmf->tmf_log), - GFP_KERNEL); + tmf->tmf_log = kmalloc_objs(*tmf->tmf_log, log_num); if (tmf->tmf_log) { memcpy(tmf->tmf_log, log, sizeof(*tmf->tmf_log) * log_num); tmf->tmf_log_num = log_num; @@ -1936,14 +1932,13 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) return -ENOMEM; svq->max_cmds = max_cmds; - svq->scsi_cmds = kcalloc(max_cmds, sizeof(*tv_cmd), GFP_KERNEL); + svq->scsi_cmds = kzalloc_objs(*tv_cmd, max_cmds); if (!svq->scsi_cmds) { sbitmap_free(&svq->scsi_tags); return -ENOMEM; } - svq->upages = kcalloc(VHOST_SCSI_PREALLOC_UPAGES, sizeof(struct page *), - GFP_KERNEL); + svq->upages = kzalloc_objs(struct page *, VHOST_SCSI_PREALLOC_UPAGES); if (!svq->upages) goto out; @@ -1951,9 +1946,8 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) tv_cmd = &svq->scsi_cmds[i]; if (vs->inline_sg_cnt) { - tv_cmd->sgl = kcalloc(vs->inline_sg_cnt, - sizeof(struct scatterlist), - GFP_KERNEL); + tv_cmd->sgl = kzalloc_objs(struct scatterlist, + vs->inline_sg_cnt); if (!tv_cmd->sgl) { pr_err("Unable to allocate tv_cmd->sgl\n"); goto out; @@ -1962,9 +1956,8 @@ static int vhost_scsi_setup_vq_cmds(struct vhost_virtqueue *vq, int max_cmds) if (vhost_has_feature(vq, VIRTIO_SCSI_F_T10_PI) && vs->inline_sg_cnt) { - tv_cmd->prot_sgl = kcalloc(vs->inline_sg_cnt, - sizeof(struct scatterlist), - GFP_KERNEL); + tv_cmd->prot_sgl = kzalloc_objs(struct scatterlist, + vs->inline_sg_cnt); if (!tv_cmd->prot_sgl) { pr_err("Unable to allocate tv_cmd->prot_sgl\n"); goto out; @@ -2282,7 +2275,7 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) struct vhost_virtqueue **vqs; int r = -ENOMEM, i, nvqs = vhost_scsi_max_io_vqs; - vs = kvzalloc(sizeof(*vs), GFP_KERNEL); + vs = kvzalloc_obj(*vs); if (!vs) goto err_vs; vs->inline_sg_cnt = vhost_scsi_inline_sg_cnt; @@ -2297,17 +2290,16 @@ static int vhost_scsi_open(struct inode *inode, struct file *f) } nvqs += VHOST_SCSI_VQ_IO; - vs->old_inflight = kmalloc_array(nvqs, sizeof(*vs->old_inflight), - GFP_KERNEL | __GFP_ZERO); + vs->old_inflight = kmalloc_objs(*vs->old_inflight, nvqs, + GFP_KERNEL | __GFP_ZERO); if (!vs->old_inflight) goto err_inflight; - vs->vqs = kmalloc_array(nvqs, sizeof(*vs->vqs), - GFP_KERNEL | __GFP_ZERO); + vs->vqs = kmalloc_objs(*vs->vqs, nvqs, GFP_KERNEL | __GFP_ZERO); if (!vs->vqs) goto err_vqs; - vqs = kmalloc_array(nvqs, sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_objs(*vqs, nvqs); if (!vqs) goto err_local_vqs; @@ -2603,7 +2595,7 @@ static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg, return -EEXIST; } - tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL); + tv_nexus = kzalloc_obj(*tv_nexus); if (!tv_nexus) { mutex_unlock(&tpg->tv_tpg_mutex); pr_err("Unable to allocate struct vhost_scsi_nexus\n"); @@ -2798,7 +2790,7 @@ vhost_scsi_make_tpg(struct se_wwn *wwn, const char *name) if (kstrtou16(name + 5, 10, &tpgt) || tpgt >= VHOST_SCSI_MAX_TARGET) return ERR_PTR(-EINVAL); - tpg = kzalloc(sizeof(*tpg), GFP_KERNEL); + tpg = kzalloc_obj(*tpg); if (!tpg) { pr_err("Unable to allocate struct vhost_scsi_tpg"); return ERR_PTR(-ENOMEM); @@ -2852,7 +2844,7 @@ vhost_scsi_make_tport(struct target_fabric_configfs *tf, /* if (vhost_scsi_parse_wwn(name, &wwpn, 1) < 0) return ERR_PTR(-EINVAL); */ - tport = kzalloc(sizeof(*tport), GFP_KERNEL); + tport = kzalloc_obj(*tport); if (!tport) { pr_err("Unable to allocate struct vhost_scsi_tport"); return ERR_PTR(-ENOMEM); diff --git a/drivers/vhost/test.c b/drivers/vhost/test.c index 1e4e36edbcd2..24514c8fdee4 100644 --- a/drivers/vhost/test.c +++ b/drivers/vhost/test.c @@ -110,13 +110,13 @@ static void handle_vq_kick(struct vhost_work *work) static int vhost_test_open(struct inode *inode, struct file *f) { - struct vhost_test *n = kmalloc(sizeof *n, GFP_KERNEL); + struct vhost_test *n = kmalloc_obj(*n); struct vhost_dev *dev; struct vhost_virtqueue **vqs; if (!n) return -ENOMEM; - vqs = kmalloc_array(VHOST_TEST_VQ_MAX, sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_objs(*vqs, VHOST_TEST_VQ_MAX); if (!vqs) { kfree(n); return -ENOMEM; diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c index cdee8f320dca..692564b1bcbb 100644 --- a/drivers/vhost/vdpa.c +++ b/drivers/vhost/vdpa.c @@ -110,7 +110,7 @@ static struct vhost_vdpa_as *vhost_vdpa_alloc_as(struct vhost_vdpa *v, u32 asid) if (asid >= v->vdpa->nas) return NULL; - as = kmalloc(sizeof(*as), GFP_KERNEL); + as = kmalloc_obj(*as); if (!as) return NULL; @@ -1064,7 +1064,7 @@ static int vhost_vdpa_va_map(struct vhost_vdpa *v, !(vma->vm_flags & (VM_IO | VM_PFNMAP)))) goto next; - map_file = kzalloc(sizeof(*map_file), GFP_KERNEL); + map_file = kzalloc_obj(*map_file); if (!map_file) { ret = -ENOMEM; break; @@ -1420,7 +1420,7 @@ static int vhost_vdpa_open(struct inode *inode, struct file *filep) if (r) goto err; - vqs = kmalloc_array(nvqs, sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_objs(*vqs, nvqs); if (!vqs) { r = -ENOMEM; goto err; @@ -1572,7 +1572,7 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa) (vdpa->ngroups > 1 || vdpa->nas > 1)) return -EOPNOTSUPP; - v = kzalloc(sizeof(*v), GFP_KERNEL | __GFP_RETRY_MAYFAIL); + v = kzalloc_obj(*v, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!v) return -ENOMEM; @@ -1593,8 +1593,7 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa) v->dev.release = vhost_vdpa_release_dev; v->dev.parent = &vdpa->dev; v->dev.devt = MKDEV(MAJOR(vhost_vdpa_major), minor); - v->vqs = kmalloc_array(v->nvqs, sizeof(struct vhost_virtqueue), - GFP_KERNEL); + v->vqs = kmalloc_objs(struct vhost_virtqueue, v->nvqs); if (!v->vqs) { r = -ENOMEM; goto err; diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index fcf7f10adbbf..2f2c45d20883 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -514,13 +514,9 @@ static long vhost_dev_alloc_iovecs(struct vhost_dev *dev) for (i = 0; i < dev->nvqs; ++i) { vq = dev->vqs[i]; - vq->indirect = kmalloc_array(UIO_MAXIOV, - sizeof(*vq->indirect), - GFP_KERNEL); - vq->log = kmalloc_array(dev->iov_limit, sizeof(*vq->log), - GFP_KERNEL); - vq->heads = kmalloc_array(dev->iov_limit, sizeof(*vq->heads), - GFP_KERNEL); + vq->indirect = kmalloc_objs(*vq->indirect, UIO_MAXIOV); + vq->log = kmalloc_objs(*vq->log, dev->iov_limit); + vq->heads = kmalloc_objs(*vq->heads, dev->iov_limit); vq->nheads = kmalloc_array(dev->iov_limit, sizeof(*vq->nheads), GFP_KERNEL); if (!vq->indirect || !vq->log || !vq->heads || !vq->nheads) @@ -836,7 +832,7 @@ static struct vhost_worker *vhost_worker_create(struct vhost_dev *dev) const struct vhost_worker_ops *ops = dev->fork_owner ? &vhost_task_ops : &kthread_ops; - worker = kzalloc(sizeof(*worker), GFP_KERNEL_ACCOUNT); + worker = kzalloc_obj(*worker, GFP_KERNEL_ACCOUNT); if (!worker) return NULL; @@ -1982,8 +1978,7 @@ static long vhost_set_memory(struct vhost_dev *d, struct vhost_memory __user *m) return -EOPNOTSUPP; if (mem.nregions > max_mem_regions) return -E2BIG; - newmem = kvzalloc(struct_size(newmem, regions, mem.nregions), - GFP_KERNEL); + newmem = kvzalloc_flex(*newmem, regions, mem.nregions); if (!newmem) return -ENOMEM; @@ -3272,7 +3267,7 @@ EXPORT_SYMBOL_GPL(vhost_disable_notify); struct vhost_msg_node *vhost_new_msg(struct vhost_virtqueue *vq, int type) { /* Make sure all padding within the structure is initialized. */ - struct vhost_msg_node *node = kzalloc(sizeof(*node), GFP_KERNEL); + struct vhost_msg_node *node = kzalloc_obj(*node); if (!node) return NULL; diff --git a/drivers/vhost/vringh.c b/drivers/vhost/vringh.c index 925858cc6096..9066f9f12ba1 100644 --- a/drivers/vhost/vringh.c +++ b/drivers/vhost/vringh.c @@ -227,7 +227,7 @@ static int resize_iovec(struct vringh_kiov *iov, gfp_t gfp) if (flag) new = krealloc_array(iov->iov, new_num, sizeof(*new), gfp); else { - new = kmalloc_array(new_num, sizeof(*new), gfp); + new = kmalloc_objs(*new, new_num, gfp); if (new) { memcpy(new, iov->iov, iov->max_num * sizeof(struct iovec)); diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 488d7fa6e4ec..054f7a718f50 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -676,11 +676,11 @@ static int vhost_vsock_dev_open(struct inode *inode, struct file *file) /* This struct is large and allocation could fail, fall back to vmalloc * if there is no other way. */ - vsock = kvmalloc(sizeof(*vsock), GFP_KERNEL | __GFP_RETRY_MAYFAIL); + vsock = kvmalloc_obj(*vsock, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!vsock) return -ENOMEM; - vqs = kmalloc_array(ARRAY_SIZE(vsock->vqs), sizeof(*vqs), GFP_KERNEL); + vqs = kmalloc_objs(*vqs, ARRAY_SIZE(vsock->vqs)); if (!vqs) { ret = -ENOMEM; goto out; diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index a1422ddd1c22..a7a3fbaf7c29 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -258,6 +258,17 @@ config BACKLIGHT_PWM If you have a LCD backlight adjustable by PWM, say Y to enable this driver. +config BACKLIGHT_CGBC + tristate "Congatec Board Controller (CGBC) backlight support" + depends on MFD_CGBC && X86 + help + Say Y here to enable support for LCD backlight control on Congatec + x86-based boards via the CGBC (Congatec Board Controller). + + This driver provides backlight brightness control through the Linux + backlight subsystem. It communicates with the board controller to + adjust LCD backlight using PWM signals. + config BACKLIGHT_DA903X tristate "Backlight Driver for DA9030/DA9034 using WLED" depends on PMIC_DA903X diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index a5d62b018102..794820a98ed4 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_BACKLIGHT_APPLE_DWI) += apple_dwi_bl.o obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o obj-$(CONFIG_BACKLIGHT_AW99706) += aw99706.o obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o +obj-$(CONFIG_BACKLIGHT_CGBC) += cgbc_bl.o obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o obj-$(CONFIG_BACKLIGHT_DA903X) += da903x_bl.o obj-$(CONFIG_BACKLIGHT_DA9052) += da9052_bl.o diff --git a/drivers/video/backlight/aw99706.c b/drivers/video/backlight/aw99706.c index df5b23b2f753..938f352aaab7 100644 --- a/drivers/video/backlight/aw99706.c +++ b/drivers/video/backlight/aw99706.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 1e9b7e85d99a..a22d0bbb6e63 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -371,7 +371,7 @@ struct backlight_device *backlight_device_register(const char *name, pr_debug("backlight_device_register: name=%s\n", name); - new_bd = kzalloc(sizeof(struct backlight_device), GFP_KERNEL); + new_bd = kzalloc_obj(struct backlight_device); if (!new_bd) return ERR_PTR(-ENOMEM); diff --git a/drivers/video/backlight/cgbc_bl.c b/drivers/video/backlight/cgbc_bl.c new file mode 100644 index 000000000000..ab27e14338a8 --- /dev/null +++ b/drivers/video/backlight/cgbc_bl.c @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Congatec Board Controller (CGBC) Backlight Driver + * + * This driver provides backlight control for LCD displays connected to + * Congatec boards via the CGBC (Congatec Board Controller). It integrates + * with the Linux backlight subsystem and communicates with hardware through + * the cgbc-core module. + * + * Copyright (C) 2025 Novatron Oy + * + * Author: Petri Karhula + */ + +#include +#include +#include +#include +#include +#include + +#define BLT_PWM_DUTY_MASK GENMASK(6, 0) + +/* CGBC command for PWM brightness control*/ +#define CGBC_CMD_BLT0_PWM 0x75 + +#define CGBC_BL_MAX_BRIGHTNESS 100 + +/** + * CGBC backlight driver data + * @dev: Pointer to the platform device + * @cgbc: Pointer to the parent CGBC device data + * @current_brightness: Current brightness level (0-100) + */ +struct cgbc_bl_data { + struct device *dev; + struct cgbc_device_data *cgbc; + unsigned int current_brightness; +}; + +static int cgbc_bl_read_brightness(struct cgbc_bl_data *bl_data) +{ + u8 cmd_buf[4] = { CGBC_CMD_BLT0_PWM }; + u8 reply_buf[3]; + int ret; + + ret = cgbc_command(bl_data->cgbc, cmd_buf, sizeof(cmd_buf), + reply_buf, sizeof(reply_buf), NULL); + if (ret < 0) + return ret; + + /* + * Get only PWM duty factor percentage, + * ignore polarity inversion bit (bit 7) + */ + bl_data->current_brightness = FIELD_GET(BLT_PWM_DUTY_MASK, reply_buf[0]); + + return 0; +} + +static int cgbc_bl_update_status(struct backlight_device *bl) +{ + struct cgbc_bl_data *bl_data = bl_get_data(bl); + u8 cmd_buf[4] = { CGBC_CMD_BLT0_PWM }; + u8 reply_buf[3]; + u8 brightness; + int ret; + + brightness = backlight_get_brightness(bl); + + if (brightness != bl_data->current_brightness) { + /* Read the current values */ + ret = cgbc_command(bl_data->cgbc, cmd_buf, sizeof(cmd_buf), reply_buf, + sizeof(reply_buf), NULL); + if (ret < 0) { + dev_err(bl_data->dev, "Failed to read PWM settings: %d\n", ret); + return ret; + } + + /* + * Prepare command buffer for writing new settings. Only 2nd byte is changed + * to set new brightness (PWM duty cycle %). Other values (polarity, frequency) + * are preserved from the read values. + */ + cmd_buf[1] = (reply_buf[0] & ~BLT_PWM_DUTY_MASK) | + FIELD_PREP(BLT_PWM_DUTY_MASK, brightness); + cmd_buf[2] = reply_buf[1]; + cmd_buf[3] = reply_buf[2]; + + ret = cgbc_command(bl_data->cgbc, cmd_buf, sizeof(cmd_buf), reply_buf, + sizeof(reply_buf), NULL); + if (ret < 0) { + dev_err(bl_data->dev, "Failed to set brightness: %d\n", ret); + return ret; + } + + bl_data->current_brightness = reply_buf[0] & BLT_PWM_DUTY_MASK; + + /* Verify the setting was applied correctly */ + if (bl_data->current_brightness != brightness) { + dev_err(bl_data->dev, + "Brightness setting verification failed (got %u, expected %u)\n", + bl_data->current_brightness, (unsigned int)brightness); + return -EIO; + } + } + + return 0; +} + +static int cgbc_bl_get_brightness(struct backlight_device *bl) +{ + struct cgbc_bl_data *bl_data = bl_get_data(bl); + int ret; + + ret = cgbc_bl_read_brightness(bl_data); + if (ret < 0) { + dev_err(bl_data->dev, "Failed to read brightness: %d\n", ret); + return ret; + } + + return bl_data->current_brightness; +} + +static const struct backlight_ops cgbc_bl_ops = { + .options = BL_CORE_SUSPENDRESUME, + .update_status = cgbc_bl_update_status, + .get_brightness = cgbc_bl_get_brightness, +}; + +static int cgbc_bl_probe(struct platform_device *pdev) +{ + struct cgbc_device_data *cgbc = dev_get_drvdata(pdev->dev.parent); + struct backlight_properties props = { }; + struct backlight_device *bl_dev; + struct cgbc_bl_data *bl_data; + int ret; + + bl_data = devm_kzalloc(&pdev->dev, sizeof(*bl_data), GFP_KERNEL); + if (!bl_data) + return -ENOMEM; + + bl_data->dev = &pdev->dev; + bl_data->cgbc = cgbc; + + ret = cgbc_bl_read_brightness(bl_data); + if (ret < 0) + return dev_err_probe(&pdev->dev, ret, + "Failed to read initial brightness\n"); + + props.type = BACKLIGHT_PLATFORM; + props.max_brightness = CGBC_BL_MAX_BRIGHTNESS; + props.brightness = bl_data->current_brightness; + props.scale = BACKLIGHT_SCALE_LINEAR; + + bl_dev = devm_backlight_device_register(&pdev->dev, "cgbc-backlight", + &pdev->dev, bl_data, + &cgbc_bl_ops, &props); + if (IS_ERR(bl_dev)) + return dev_err_probe(&pdev->dev, PTR_ERR(bl_dev), + "Failed to register backlight device\n"); + + platform_set_drvdata(pdev, bl_data); + + return 0; +} + +static struct platform_driver cgbc_bl_driver = { + .driver = { + .name = "cgbc-backlight", + }, + .probe = cgbc_bl_probe, +}; + +module_platform_driver(cgbc_bl_driver); + +MODULE_AUTHOR("Petri Karhula "); +MODULE_DESCRIPTION("Congatec Board Controller (CGBC) Backlight Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:cgbc-backlight"); diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index affe5c52471a..e918f57608ef 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -197,7 +197,7 @@ struct lcd_device *lcd_device_register(const char *name, struct device *parent, pr_debug("lcd_device_register: name=%s\n", name); - new_ld = kzalloc(sizeof(struct lcd_device), GFP_KERNEL); + new_ld = kzalloc_obj(struct lcd_device); if (!new_ld) return ERR_PTR(-ENOMEM); diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c index a63bb42c8f8b..8054e4787725 100644 --- a/drivers/video/backlight/qcom-wled.c +++ b/drivers/video/backlight/qcom-wled.c @@ -1244,6 +1244,15 @@ static const struct wled_var_cfg wled4_ovp_cfg = { .size = ARRAY_SIZE(wled4_ovp_values), }; +static const u32 pmi8994_wled_ovp_values[] = { + 31000, 29500, 19400, 17800, +}; + +static const struct wled_var_cfg pmi8994_wled_ovp_cfg = { + .values = pmi8994_wled_ovp_values, + .size = ARRAY_SIZE(pmi8994_wled_ovp_values), +}; + static inline u32 wled5_ovp_values_fn(u32 idx) { /* @@ -1357,6 +1366,29 @@ static int wled_configure(struct wled *wled) }, }; + const struct wled_u32_opts pmi8994_wled_opts[] = { + { + .name = "qcom,current-boost-limit", + .val_ptr = &cfg->boost_i_limit, + .cfg = &wled4_boost_i_limit_cfg, + }, + { + .name = "qcom,current-limit-microamp", + .val_ptr = &cfg->string_i_limit, + .cfg = &wled4_string_i_limit_cfg, + }, + { + .name = "qcom,ovp-millivolt", + .val_ptr = &cfg->ovp, + .cfg = &pmi8994_wled_ovp_cfg, + }, + { + .name = "qcom,switching-freq", + .val_ptr = &cfg->switch_freq, + .cfg = &wled3_switch_freq_cfg, + }, + }; + const struct wled_u32_opts wled5_opts[] = { { .name = "qcom,current-boost-limit", @@ -1423,8 +1455,14 @@ static int wled_configure(struct wled *wled) break; case 4: - u32_opts = wled4_opts; - size = ARRAY_SIZE(wled4_opts); + if (of_device_is_compatible(dev->of_node, "qcom,pmi8950-wled") || + of_device_is_compatible(dev->of_node, "qcom,pmi8994-wled")) { + u32_opts = pmi8994_wled_opts; + size = ARRAY_SIZE(pmi8994_wled_opts); + } else { + u32_opts = wled4_opts; + size = ARRAY_SIZE(wled4_opts); + } *cfg = wled4_config_defaults; wled->wled_set_brightness = wled4_set_brightness; wled->wled_sync_toggle = wled3_sync_toggle; diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 242415366074..337e04236d6d 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -95,7 +95,7 @@ static inline void newport_init_cmap(void) static const struct linux_logo *newport_show_logo(void) { -#ifdef CONFIG_LOGO_SGI_CLUT224 +#ifdef CONFIG_LOGO_LINUX_CLUT224 const struct linux_logo *logo = fb_find_logo(8); const unsigned char *clut; const unsigned char *data; @@ -127,7 +127,7 @@ static const struct linux_logo *newport_show_logo(void) return logo; #else return NULL; -#endif /* CONFIG_LOGO_SGI_CLUT224 */ +#endif /* CONFIG_LOGO_LINUX_CLUT224 */ } static inline void newport_clear_screen(int xstart, int ystart, int xend, diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index f1f3ee8e5e8a..6f58e6a9e76a 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -186,7 +186,7 @@ static int sticon_set_font(struct vc_data *vc, const struct console_font *op, new_font->underline_height = 0; new_font->underline_pos = 0; - cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font = kzalloc_obj(*cooked_font); if (!cooked_font) { kfree(new_font); return -ENOMEM; diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index a733f90eca55..ac9ac4287c6a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1345,7 +1345,8 @@ endchoice config FB_AU1100 bool "Au1100 LCD Driver" - depends on (FB = y) && MIPS_ALCHEMY + depends on FB = y + depends on MIPS_ALCHEMY || COMPILE_TEST select FB_IOMEM_HELPERS help This is the framebuffer driver for the AMD Au1100 SOC. It can drive @@ -1770,17 +1771,6 @@ config FB_BROADSHEET and could also have been called by other names when coupled with a bridge adapter. -config FB_HYPERV - tristate "Microsoft Hyper-V Synthetic Video support (DEPRECATED)" - depends on FB && HYPERV_VMBUS - select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA - select FB_IOMEM_HELPERS_DEFERRED - help - This framebuffer driver supports Microsoft Hyper-V Synthetic Video. - - This driver is deprecated, please use the Hyper-V DRM driver at - drivers/gpu/drm/hyperv (CONFIG_DRM_HYPERV) instead. - config FB_SIMPLE tristate "Simple framebuffer support" depends on FB diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile index b3d12f977c06..36a18d958ba0 100644 --- a/drivers/video/fbdev/Makefile +++ b/drivers/video/fbdev/Makefile @@ -111,7 +111,6 @@ obj-y += omap2/ obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o obj-$(CONFIG_FB_CARMINE) += carminefb.o obj-$(CONFIG_FB_MB862XX) += mb862xx/ -obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o obj-$(CONFIG_FB_OPENCORES) += ocfb.o obj-$(CONFIG_FB_SM712) += sm712fb.o diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index ec084323115f..866c1165704e 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -431,7 +431,7 @@ static struct dac_ops ics5342_ops = { static struct dac_info * ics5342_init(dac_read_regs_t drr, dac_write_regs_t dwr, void *data) { - struct ics5342_info *ics_info = kzalloc(sizeof(struct ics5342_info), GFP_KERNEL); + struct ics5342_info *ics_info = kzalloc_obj(struct ics5342_info); struct dac_info *info = &ics_info->dac; if (!ics_info) diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 56ef1d88e003..d5e107730a4d 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -2976,7 +2976,7 @@ static int atyfb_setup_sparc(struct pci_dev *pdev, struct fb_info *info, /* nothing */ ; j = i + 4; - par->mmap_map = kcalloc(j, sizeof(*par->mmap_map), GFP_ATOMIC); + par->mmap_map = kzalloc_objs(*par->mmap_map, j, GFP_ATOMIC); if (!par->mmap_map) { PRINTKE("atyfb_setup_sparc() can't alloc mmap_map\n"); return -ENOMEM; diff --git a/drivers/video/fbdev/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c index bf764c92bcf1..32d7f32db46a 100644 --- a/drivers/video/fbdev/aty/radeon_backlight.c +++ b/drivers/video/fbdev/aty/radeon_backlight.c @@ -136,7 +136,7 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) return; #endif - pdata = kmalloc(sizeof(struct radeon_bl_privdata), GFP_KERNEL); + pdata = kmalloc_obj(struct radeon_bl_privdata); if (!pdata) { printk("radeonfb: Memory allocation failed\n"); goto error; diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 1d2c57ba25a3..cb006484831b 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -1653,7 +1653,7 @@ static int radeonfb_set_par(struct fb_info *info) int depth = var_to_depth(mode); int use_rmx = 0; - newmode = kmalloc(sizeof(struct radeon_regs), GFP_KERNEL); + newmode = kmalloc_obj(struct radeon_regs); if (!newmode) return -ENOMEM; diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 6251a6b07b3a..c54cfcd832bb 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * BRIEF MODULE DESCRIPTION * Au1100 LCD Driver. @@ -20,28 +21,13 @@ * Based on: * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device * Created 28 Dec 1997 by Geert Uytterhoeven - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define pr_fmt(fmt) "au1100fb:" fmt "\n" + #include +#include +#include #include #include #include @@ -55,11 +41,353 @@ #include #include -#include +#if defined(__BIG_ENDIAN) +#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11 +#else +#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00 +#endif +#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565 -#define DEBUG 0 +/********************************************************************/ -#include "au1100fb.h" +/* LCD controller restrictions */ +#define AU1100_LCD_MAX_XRES 800 +#define AU1100_LCD_MAX_YRES 600 +#define AU1100_LCD_MAX_BPP 16 +#define AU1100_LCD_MAX_CLK 48000000 +#define AU1100_LCD_NBR_PALETTE_ENTRIES 256 + +/* Default number of visible screen buffer to allocate */ +#define AU1100FB_NBR_VIDEO_BUFFERS 4 + +/********************************************************************/ + +struct au1100fb_panel +{ + const char name[25]; /* Full name _ */ + + u32 control_base; /* Mode-independent control values */ + u32 clkcontrol_base; /* Panel pixclock preferences */ + + u32 horztiming; + u32 verttiming; + + u32 xres; /* Maximum horizontal resolution */ + u32 yres; /* Maximum vertical resolution */ + u32 bpp; /* Maximum depth supported */ +}; + +struct au1100fb_regs +{ + u32 lcd_control; + u32 lcd_intstatus; + u32 lcd_intenable; + u32 lcd_horztiming; + u32 lcd_verttiming; + u32 lcd_clkcontrol; + u32 lcd_dmaaddr0; + u32 lcd_dmaaddr1; + u32 lcd_words; + u32 lcd_pwmdiv; + u32 lcd_pwmhi; + u32 reserved[(0x0400-0x002C)/4]; + u32 lcd_palettebase[256]; +}; + +struct au1100fb_device { + + struct fb_info info; /* FB driver info record */ + + struct au1100fb_panel *panel; /* Panel connected to this device */ + + struct au1100fb_regs* regs; /* Registers memory map */ + size_t regs_len; + unsigned int regs_phys; + +#ifdef CONFIG_PM + /* stores the register values during suspend */ + struct au1100fb_regs pm_regs; +#endif + + unsigned char* fb_mem; /* FrameBuffer memory map */ + size_t fb_len; + dma_addr_t fb_phys; + int panel_idx; + struct clk *lcdclk; + struct device *dev; +}; + +/********************************************************************/ + +#define LCD_CONTROL (AU1100_LCD_BASE + 0x0) + #define LCD_CONTROL_SBB_BIT 21 + #define LCD_CONTROL_SBB_MASK (0x3 << LCD_CONTROL_SBB_BIT) + #define LCD_CONTROL_SBB_1 (0 << LCD_CONTROL_SBB_BIT) + #define LCD_CONTROL_SBB_2 (1 << LCD_CONTROL_SBB_BIT) + #define LCD_CONTROL_SBB_3 (2 << LCD_CONTROL_SBB_BIT) + #define LCD_CONTROL_SBB_4 (3 << LCD_CONTROL_SBB_BIT) + #define LCD_CONTROL_SBPPF_BIT 18 + #define LCD_CONTROL_SBPPF_MASK (0x7 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_SBPPF_655 (0 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_SBPPF_565 (1 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_SBPPF_556 (2 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_SBPPF_1555 (3 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_SBPPF_5551 (4 << LCD_CONTROL_SBPPF_BIT) + #define LCD_CONTROL_WP (1<<17) + #define LCD_CONTROL_WD (1<<16) + #define LCD_CONTROL_C (1<<15) + #define LCD_CONTROL_SM_BIT 13 + #define LCD_CONTROL_SM_MASK (0x3 << LCD_CONTROL_SM_BIT) + #define LCD_CONTROL_SM_0 (0 << LCD_CONTROL_SM_BIT) + #define LCD_CONTROL_SM_90 (1 << LCD_CONTROL_SM_BIT) + #define LCD_CONTROL_SM_180 (2 << LCD_CONTROL_SM_BIT) + #define LCD_CONTROL_SM_270 (3 << LCD_CONTROL_SM_BIT) + #define LCD_CONTROL_DB (1<<12) + #define LCD_CONTROL_CCO (1<<11) + #define LCD_CONTROL_DP (1<<10) + #define LCD_CONTROL_PO_BIT 8 + #define LCD_CONTROL_PO_MASK (0x3 << LCD_CONTROL_PO_BIT) + #define LCD_CONTROL_PO_00 (0 << LCD_CONTROL_PO_BIT) + #define LCD_CONTROL_PO_01 (1 << LCD_CONTROL_PO_BIT) + #define LCD_CONTROL_PO_10 (2 << LCD_CONTROL_PO_BIT) + #define LCD_CONTROL_PO_11 (3 << LCD_CONTROL_PO_BIT) + #define LCD_CONTROL_MPI (1<<7) + #define LCD_CONTROL_PT (1<<6) + #define LCD_CONTROL_PC (1<<5) + #define LCD_CONTROL_BPP_BIT 1 + #define LCD_CONTROL_BPP_MASK (0x7 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_1 (0 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_2 (1 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_4 (2 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_8 (3 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_12 (4 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_BPP_16 (5 << LCD_CONTROL_BPP_BIT) + #define LCD_CONTROL_GO (1<<0) + +#define LCD_INTSTATUS (AU1100_LCD_BASE + 0x4) +#define LCD_INTENABLE (AU1100_LCD_BASE + 0x8) + #define LCD_INT_SD (1<<7) + #define LCD_INT_OF (1<<6) + #define LCD_INT_UF (1<<5) + #define LCD_INT_SA (1<<3) + #define LCD_INT_SS (1<<2) + #define LCD_INT_S1 (1<<1) + #define LCD_INT_S0 (1<<0) + +#define LCD_HORZTIMING (AU1100_LCD_BASE + 0xC) + #define LCD_HORZTIMING_HN2_BIT 24 + #define LCD_HORZTIMING_HN2_MASK (0xFF << LCD_HORZTIMING_HN2_BIT) + #define LCD_HORZTIMING_HN2_N(N) ((((N)-1) << LCD_HORZTIMING_HN2_BIT) & LCD_HORZTIMING_HN2_MASK) + #define LCD_HORZTIMING_HN1_BIT 16 + #define LCD_HORZTIMING_HN1_MASK (0xFF << LCD_HORZTIMING_HN1_BIT) + #define LCD_HORZTIMING_HN1_N(N) ((((N)-1) << LCD_HORZTIMING_HN1_BIT) & LCD_HORZTIMING_HN1_MASK) + #define LCD_HORZTIMING_HPW_BIT 10 + #define LCD_HORZTIMING_HPW_MASK (0x3F << LCD_HORZTIMING_HPW_BIT) + #define LCD_HORZTIMING_HPW_N(N) ((((N)-1) << LCD_HORZTIMING_HPW_BIT) & LCD_HORZTIMING_HPW_MASK) + #define LCD_HORZTIMING_PPL_BIT 0 + #define LCD_HORZTIMING_PPL_MASK (0x3FF << LCD_HORZTIMING_PPL_BIT) + #define LCD_HORZTIMING_PPL_N(N) ((((N)-1) << LCD_HORZTIMING_PPL_BIT) & LCD_HORZTIMING_PPL_MASK) + +#define LCD_VERTTIMING (AU1100_LCD_BASE + 0x10) + #define LCD_VERTTIMING_VN2_BIT 24 + #define LCD_VERTTIMING_VN2_MASK (0xFF << LCD_VERTTIMING_VN2_BIT) + #define LCD_VERTTIMING_VN2_N(N) ((((N)-1) << LCD_VERTTIMING_VN2_BIT) & LCD_VERTTIMING_VN2_MASK) + #define LCD_VERTTIMING_VN1_BIT 16 + #define LCD_VERTTIMING_VN1_MASK (0xFF << LCD_VERTTIMING_VN1_BIT) + #define LCD_VERTTIMING_VN1_N(N) ((((N)-1) << LCD_VERTTIMING_VN1_BIT) & LCD_VERTTIMING_VN1_MASK) + #define LCD_VERTTIMING_VPW_BIT 10 + #define LCD_VERTTIMING_VPW_MASK (0x3F << LCD_VERTTIMING_VPW_BIT) + #define LCD_VERTTIMING_VPW_N(N) ((((N)-1) << LCD_VERTTIMING_VPW_BIT) & LCD_VERTTIMING_VPW_MASK) + #define LCD_VERTTIMING_LPP_BIT 0 + #define LCD_VERTTIMING_LPP_MASK (0x3FF << LCD_VERTTIMING_LPP_BIT) + #define LCD_VERTTIMING_LPP_N(N) ((((N)-1) << LCD_VERTTIMING_LPP_BIT) & LCD_VERTTIMING_LPP_MASK) + +#define LCD_CLKCONTROL (AU1100_LCD_BASE + 0x14) + #define LCD_CLKCONTROL_IB (1<<18) + #define LCD_CLKCONTROL_IC (1<<17) + #define LCD_CLKCONTROL_IH (1<<16) + #define LCD_CLKCONTROL_IV (1<<15) + #define LCD_CLKCONTROL_BF_BIT 10 + #define LCD_CLKCONTROL_BF_MASK (0x1F << LCD_CLKCONTROL_BF_BIT) + #define LCD_CLKCONTROL_BF_N(N) ((((N)-1) << LCD_CLKCONTROL_BF_BIT) & LCD_CLKCONTROL_BF_MASK) + #define LCD_CLKCONTROL_PCD_BIT 0 + #define LCD_CLKCONTROL_PCD_MASK (0x3FF << LCD_CLKCONTROL_PCD_BIT) + #define LCD_CLKCONTROL_PCD_N(N) (((N) << LCD_CLKCONTROL_PCD_BIT) & LCD_CLKCONTROL_PCD_MASK) + +#define LCD_DMAADDR0 (AU1100_LCD_BASE + 0x18) +#define LCD_DMAADDR1 (AU1100_LCD_BASE + 0x1C) + #define LCD_DMA_SA_BIT 5 + #define LCD_DMA_SA_MASK (0x7FFFFFF << LCD_DMA_SA_BIT) + #define LCD_DMA_SA_N(N) ((N) & LCD_DMA_SA_MASK) + +#define LCD_WORDS (AU1100_LCD_BASE + 0x20) + #define LCD_WRD_WRDS_BIT 0 + #define LCD_WRD_WRDS_MASK (0xFFFFFFFF << LCD_WRD_WRDS_BIT) + #define LCD_WRD_WRDS_N(N) ((((N)-1) << LCD_WRD_WRDS_BIT) & LCD_WRD_WRDS_MASK) + +#define LCD_PWMDIV (AU1100_LCD_BASE + 0x24) + #define LCD_PWMDIV_EN (1<<12) + #define LCD_PWMDIV_PWMDIV_BIT 0 + #define LCD_PWMDIV_PWMDIV_MASK (0xFFF << LCD_PWMDIV_PWMDIV_BIT) + #define LCD_PWMDIV_PWMDIV_N(N) ((((N)-1) << LCD_PWMDIV_PWMDIV_BIT) & LCD_PWMDIV_PWMDIV_MASK) + +#define LCD_PWMHI (AU1100_LCD_BASE + 0x28) + #define LCD_PWMHI_PWMHI1_BIT 12 + #define LCD_PWMHI_PWMHI1_MASK (0xFFF << LCD_PWMHI_PWMHI1_BIT) + #define LCD_PWMHI_PWMHI1_N(N) (((N) << LCD_PWMHI_PWMHI1_BIT) & LCD_PWMHI_PWMHI1_MASK) + #define LCD_PWMHI_PWMHI0_BIT 0 + #define LCD_PWMHI_PWMHI0_MASK (0xFFF << LCD_PWMHI_PWMHI0_BIT) + #define LCD_PWMHI_PWMHI0_N(N) (((N) << LCD_PWMHI_PWMHI0_BIT) & LCD_PWMHI_PWMHI0_MASK) + +#define LCD_PALLETTEBASE (AU1100_LCD_BASE + 0x400) + #define LCD_PALLETTE_MONO_MI_BIT 0 + #define LCD_PALLETTE_MONO_MI_MASK (0xF << LCD_PALLETTE_MONO_MI_BIT) + #define LCD_PALLETTE_MONO_MI_N(N) (((N)<< LCD_PALLETTE_MONO_MI_BIT) & LCD_PALLETTE_MONO_MI_MASK) + + #define LCD_PALLETTE_COLOR_RI_BIT 8 + #define LCD_PALLETTE_COLOR_RI_MASK (0xF << LCD_PALLETTE_COLOR_RI_BIT) + #define LCD_PALLETTE_COLOR_RI_N(N) (((N)<< LCD_PALLETTE_COLOR_RI_BIT) & LCD_PALLETTE_COLOR_RI_MASK) + #define LCD_PALLETTE_COLOR_GI_BIT 4 + #define LCD_PALLETTE_COLOR_GI_MASK (0xF << LCD_PALLETTE_COLOR_GI_BIT) + #define LCD_PALLETTE_COLOR_GI_N(N) (((N)<< LCD_PALLETTE_COLOR_GI_BIT) & LCD_PALLETTE_COLOR_GI_MASK) + #define LCD_PALLETTE_COLOR_BI_BIT 0 + #define LCD_PALLETTE_COLOR_BI_MASK (0xF << LCD_PALLETTE_COLOR_BI_BIT) + #define LCD_PALLETTE_COLOR_BI_N(N) (((N)<< LCD_PALLETTE_COLOR_BI_BIT) & LCD_PALLETTE_COLOR_BI_MASK) + + #define LCD_PALLETTE_TFT_DC_BIT 0 + #define LCD_PALLETTE_TFT_DC_MASK (0xFFFF << LCD_PALLETTE_TFT_DC_BIT) + #define LCD_PALLETTE_TFT_DC_N(N) (((N)<< LCD_PALLETTE_TFT_DC_BIT) & LCD_PALLETTE_TFT_DC_MASK) + +/********************************************************************/ + +/* List of panels known to work with the AU1100 LCD controller. + * To add a new panel, enter the same specifications as the + * Generic_TFT one, and MAKE SURE that it doesn't conflicts + * with the controller restrictions. Restrictions are: + * + * STN color panels: max_bpp <= 12 + * STN mono panels: max_bpp <= 4 + * TFT panels: max_bpp <= 16 + * max_xres <= 800 + * max_yres <= 600 + */ +static struct au1100fb_panel known_lcd_panels[] = +{ + /* 800x600x16bpp CRT */ + [0] = { + .name = "CRT_800x600_16", + .xres = 800, + .yres = 600, + .bpp = 16, + .control_base = 0x0004886A | + LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF | + LCD_CONTROL_BPP_16 | LCD_CONTROL_SBB_4, + .clkcontrol_base = 0x00020000, + .horztiming = 0x005aff1f, + .verttiming = 0x16000e57, + }, + /* just the standard LCD */ + [1] = { + .name = "WWPC LCD", + .xres = 240, + .yres = 320, + .bpp = 16, + .control_base = 0x0006806A, + .horztiming = 0x0A1010EF, + .verttiming = 0x0301013F, + .clkcontrol_base = 0x00018001, + }, + /* Sharp 320x240 TFT panel */ + [2] = { + .name = "Sharp_LQ038Q5DR01", + .xres = 320, + .yres = 240, + .bpp = 16, + .control_base = + ( LCD_CONTROL_SBPPF_565 + | LCD_CONTROL_C + | LCD_CONTROL_SM_0 + | LCD_CONTROL_DEFAULT_PO + | LCD_CONTROL_PT + | LCD_CONTROL_PC + | LCD_CONTROL_BPP_16 ), + .horztiming = + ( LCD_HORZTIMING_HN2_N(8) + | LCD_HORZTIMING_HN1_N(60) + | LCD_HORZTIMING_HPW_N(12) + | LCD_HORZTIMING_PPL_N(320) ), + .verttiming = + ( LCD_VERTTIMING_VN2_N(5) + | LCD_VERTTIMING_VN1_N(17) + | LCD_VERTTIMING_VPW_N(1) + | LCD_VERTTIMING_LPP_N(240) ), + .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1), + }, + + /* Hitachi SP14Q005 and possibly others */ + [3] = { + .name = "Hitachi_SP14Qxxx", + .xres = 320, + .yres = 240, + .bpp = 4, + .control_base = + ( LCD_CONTROL_C + | LCD_CONTROL_BPP_4 ), + .horztiming = + ( LCD_HORZTIMING_HN2_N(1) + | LCD_HORZTIMING_HN1_N(1) + | LCD_HORZTIMING_HPW_N(1) + | LCD_HORZTIMING_PPL_N(320) ), + .verttiming = + ( LCD_VERTTIMING_VN2_N(1) + | LCD_VERTTIMING_VN1_N(1) + | LCD_VERTTIMING_VPW_N(1) + | LCD_VERTTIMING_LPP_N(240) ), + .clkcontrol_base = LCD_CLKCONTROL_PCD_N(4), + }, + + /* Generic 640x480 TFT panel */ + [4] = { + .name = "TFT_640x480_16", + .xres = 640, + .yres = 480, + .bpp = 16, + .control_base = 0x004806a | LCD_CONTROL_DEFAULT_PO, + .horztiming = 0x3434d67f, + .verttiming = 0x0e0e39df, + .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1), + }, + + /* Pb1100 LCDB 640x480 PrimeView TFT panel */ + [5] = { + .name = "PrimeView_640x480_16", + .xres = 640, + .yres = 480, + .bpp = 16, + .control_base = 0x0004886a | LCD_CONTROL_DEFAULT_PO, + .horztiming = 0x0e4bfe7f, + .verttiming = 0x210805df, + .clkcontrol_base = 0x00038001, + }, +}; + +/********************************************************************/ + +/* Inline helpers */ + +#define panel_is_dual(panel) (panel->control_base & LCD_CONTROL_DP) +#define panel_is_active(panel)(panel->control_base & LCD_CONTROL_PT) +#define panel_is_color(panel) (panel->control_base & LCD_CONTROL_PC) +#define panel_swap_rgb(panel) (panel->control_base & LCD_CONTROL_CCO) + +#if defined(CONFIG_COMPILE_TEST) && (!defined(CONFIG_MIPS) || defined(CONFIG_64BIT)) +/* + * KSEG1ADDR() is defined in arch/mips/include/asm/addrspace.h + * for 32 bit configurations. Provide a stub for compile testing + * on other platforms. + */ +#define KSEG1ADDR(x) (x) +#endif #define DRIVER_NAME "au1100fb" #define DRIVER_DESC "LCD controller driver for AU1100 processors" @@ -84,21 +412,6 @@ struct fb_bitfield rgb_bitfields[][4] = { { 8, 4, 0 }, { 4, 4, 0 }, { 0, 4, 0 }, { 0, 0, 0 } }, }; -static struct fb_fix_screeninfo au1100fb_fix = { - .id = "AU1100 FB", - .xpanstep = 1, - .ypanstep = 1, - .type = FB_TYPE_PACKED_PIXELS, - .accel = FB_ACCEL_NONE, -}; - -static struct fb_var_screeninfo au1100fb_var = { - .activate = FB_ACTIVATE_NOW, - .height = -1, - .width = -1, - .vmode = FB_VMODE_NONINTERLACED, -}; - /* fb_blank * Blank the screen. Depending on the mode, the screen will be * activated with the backlight color, or desactivated @@ -107,7 +420,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) { struct au1100fb_device *fbdev = to_au1100fb_device(fbi); - print_dbg("fb_blank %d %p", blank_mode, fbi); + pr_devel("fb_blank %d %p", blank_mode, fbi); switch (blank_mode) { @@ -135,7 +448,7 @@ static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) * Set hardware with var settings. This will enable the controller with a specific * mode, normally validated with the fb_check_var method */ -int au1100fb_setmode(struct au1100fb_device *fbdev) +static int au1100fb_setmode(struct au1100fb_device *fbdev) { struct fb_info *info; u32 words; @@ -234,7 +547,8 @@ int au1100fb_setmode(struct au1100fb_device *fbdev) /* fb_setcolreg * Set color in LCD palette. */ -int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi) +static int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, + unsigned transp, struct fb_info *fbi) { struct au1100fb_device *fbdev; u32 *palette; @@ -293,14 +607,14 @@ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned /* fb_pan_display * Pan display in x and/or y as specified */ -int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) +static int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) { struct au1100fb_device *fbdev; int dy; fbdev = to_au1100fb_device(fbi); - print_dbg("fb_pan_display %p %p", var, fbi); + pr_devel("fb_pan_display %p %p", var, fbi); if (!var || !fbdev) { return -EINVAL; @@ -311,13 +625,13 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) return -EINVAL; } - print_dbg("fb_pan_display 2 %p %p", var, fbi); + pr_devel("fb_pan_display 2 %p %p", var, fbi); dy = var->yoffset - fbi->var.yoffset; if (dy) { u32 dmaaddr; - print_dbg("Panning screen of %d lines", dy); + pr_devel("Panning screen of %d lines", dy); dmaaddr = fbdev->regs->lcd_dmaaddr0; dmaaddr += (fbi->fix.line_length * dy); @@ -331,7 +645,7 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) fbdev->regs->lcd_dmaaddr0 = LCD_DMA_SA_N(dmaaddr); } } - print_dbg("fb_pan_display 3 %p %p", var, fbi); + pr_devel("fb_pan_display 3 %p %p", var, fbi); return 0; } @@ -340,13 +654,16 @@ int au1100fb_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) * Map video memory in user space. We don't use the generic fb_mmap method mainly * to allow the use of the TLB streaming flag (CCA=6) */ -int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) +static int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) { struct au1100fb_device *fbdev = to_au1100fb_device(fbi); vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot); +#ifndef CONFIG_S390 + /* On s390 pgprot_val() is a function and thus not a lvalue */ pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 +#endif return dma_mmap_coherent(fbdev->dev, vma, fbdev->fb_mem, fbdev->fb_phys, fbdev->fb_len); @@ -371,7 +688,7 @@ static int au1100fb_setup(struct au1100fb_device *fbdev) int num_panels = ARRAY_SIZE(known_lcd_panels); if (num_panels <= 0) { - print_err("No LCD panels supported by driver!"); + pr_err("No LCD panels supported by driver!"); return -ENODEV; } @@ -394,16 +711,16 @@ static int au1100fb_setup(struct au1100fb_device *fbdev) } } if (i >= num_panels) { - print_warn("Panel '%s' not supported!", this_opt); + pr_warn("Panel '%s' not supported!", this_opt); return -ENODEV; } } /* Unsupported option */ else - print_warn("Unsupported option \"%s\"", this_opt); + pr_warn("Unsupported option \"%s\"", this_opt); } - print_info("Panel=%s", fbdev->panel->name); + pr_info("Panel=%s", fbdev->panel->name); return 0; } @@ -428,26 +745,33 @@ static int au1100fb_drv_probe(struct platform_device *dev) /* Allocate region for our registers and map them */ regs_res = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!regs_res) { - print_err("fail to retrieve registers resource"); + pr_err("fail to retrieve registers resource"); return -EFAULT; } - au1100fb_fix.mmio_start = regs_res->start; - au1100fb_fix.mmio_len = resource_size(regs_res); + fbdev->info.fix = (struct fb_fix_screeninfo) { + .mmio_start = regs_res->start, + .mmio_len = resource_size(regs_res), + .id = "AU1100 FB", + .xpanstep = 1, + .ypanstep = 1, + .type = FB_TYPE_PACKED_PIXELS, + .accel = FB_ACCEL_NONE, + }; if (!devm_request_mem_region(&dev->dev, - au1100fb_fix.mmio_start, - au1100fb_fix.mmio_len, + fbdev->info.fix.mmio_start, + fbdev->info.fix.mmio_len, DRIVER_NAME)) { - print_err("fail to lock memory region at 0x%08lx", - au1100fb_fix.mmio_start); + pr_err("fail to lock memory region at 0x%08lx", + fbdev->info.fix.mmio_start); return -EBUSY; } - fbdev->regs = (struct au1100fb_regs*)KSEG1ADDR(au1100fb_fix.mmio_start); + fbdev->regs = (struct au1100fb_regs*)KSEG1ADDR(fbdev->info.fix.mmio_start); - print_dbg("Register memory map at %p", fbdev->regs); - print_dbg("phys=0x%08x, size=%d", fbdev->regs_phys, fbdev->regs_len); + pr_devel("Register memory map at %p", fbdev->regs); + pr_devel("phys=0x%08x, size=%zu", fbdev->regs_phys, fbdev->regs_len); c = clk_get(NULL, "lcd_intclk"); if (!IS_ERR(c)) { @@ -464,27 +788,32 @@ static int au1100fb_drv_probe(struct platform_device *dev) PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { - print_err("fail to allocate framebuffer (size: %dK))", + pr_err("fail to allocate framebuffer (size: %zuK))", fbdev->fb_len / 1024); return -ENOMEM; } - au1100fb_fix.smem_start = fbdev->fb_phys; - au1100fb_fix.smem_len = fbdev->fb_len; + fbdev->info.fix.smem_start = fbdev->fb_phys; + fbdev->info.fix.smem_len = fbdev->fb_len; - print_dbg("Framebuffer memory map at %p", fbdev->fb_mem); - print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024); + pr_devel("Framebuffer memory map at %p", fbdev->fb_mem); + pr_devel("phys=0x%pad, size=%zuK", &fbdev->fb_phys, fbdev->fb_len / 1024); /* load the panel info into the var struct */ - au1100fb_var.bits_per_pixel = fbdev->panel->bpp; - au1100fb_var.xres = fbdev->panel->xres; - au1100fb_var.xres_virtual = au1100fb_var.xres; - au1100fb_var.yres = fbdev->panel->yres; - au1100fb_var.yres_virtual = au1100fb_var.yres; + fbdev->info.var = (struct fb_var_screeninfo) { + .activate = FB_ACTIVATE_NOW, + .height = -1, + .width = -1, + .vmode = FB_VMODE_NONINTERLACED, + .bits_per_pixel = fbdev->panel->bpp, + .xres = fbdev->panel->xres, + .xres_virtual = fbdev->panel->xres, + .yres = fbdev->panel->yres, + .yres_virtual = fbdev->panel->yres, + }; fbdev->info.screen_base = fbdev->fb_mem; fbdev->info.fbops = &au1100fb_ops; - fbdev->info.fix = au1100fb_fix; fbdev->info.pseudo_palette = devm_kcalloc(&dev->dev, 16, sizeof(u32), GFP_KERNEL); @@ -492,19 +821,17 @@ static int au1100fb_drv_probe(struct platform_device *dev) return -ENOMEM; if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { - print_err("Fail to allocate colormap (%d entries)", + pr_err("Fail to allocate colormap (%d entries)", AU1100_LCD_NBR_PALETTE_ENTRIES); return -EFAULT; } - fbdev->info.var = au1100fb_var; - /* Set h/w registers */ au1100fb_setmode(fbdev); /* Register new framebuffer */ if (register_framebuffer(&fbdev->info) < 0) { - print_err("cannot register new framebuffer"); + pr_err("cannot register new framebuffer"); goto failed; } @@ -522,7 +849,7 @@ static int au1100fb_drv_probe(struct platform_device *dev) return -ENODEV; } -void au1100fb_drv_remove(struct platform_device *dev) +static void au1100fb_drv_remove(struct platform_device *dev) { struct au1100fb_device *fbdev = NULL; @@ -545,9 +872,7 @@ void au1100fb_drv_remove(struct platform_device *dev) } #ifdef CONFIG_PM -static struct au1100fb_regs fbregs; - -int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) +static int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) { struct au1100fb_device *fbdev = platform_get_drvdata(dev); @@ -559,21 +884,24 @@ int au1100fb_drv_suspend(struct platform_device *dev, pm_message_t state) clk_disable(fbdev->lcdclk); - memcpy(&fbregs, fbdev->regs, sizeof(struct au1100fb_regs)); + memcpy(&fbdev->pm_regs, fbdev->regs, sizeof(struct au1100fb_regs)); return 0; } -int au1100fb_drv_resume(struct platform_device *dev) +static int au1100fb_drv_resume(struct platform_device *dev) { struct au1100fb_device *fbdev = platform_get_drvdata(dev); + int ret; if (!fbdev) return 0; - memcpy(fbdev->regs, &fbregs, sizeof(struct au1100fb_regs)); + memcpy(fbdev->regs, &fbdev->pm_regs, sizeof(struct au1100fb_regs)); - clk_enable(fbdev->lcdclk); + ret = clk_enable(fbdev->lcdclk); + if (ret) + return ret; /* Unblank the LCD */ au1100fb_fb_blank(VESA_NO_BLANKING, &fbdev->info); diff --git a/drivers/video/fbdev/au1100fb.h b/drivers/video/fbdev/au1100fb.h deleted file mode 100644 index 79f4048726f1..000000000000 --- a/drivers/video/fbdev/au1100fb.h +++ /dev/null @@ -1,379 +0,0 @@ -/* - * BRIEF MODULE DESCRIPTION - * Hardware definitions for the Au1100 LCD controller - * - * Copyright 2002 MontaVista Software - * Copyright 2002 Alchemy Semiconductor - * Author: Alchemy Semiconductor, MontaVista Software - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _AU1100LCD_H -#define _AU1100LCD_H - -#include - -#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg) -#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg) -#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg) - -#if DEBUG -#define print_dbg(f, arg...) printk(__FILE__ ": " f "\n", ## arg) -#else -#define print_dbg(f, arg...) do {} while (0) -#endif - -#if defined(__BIG_ENDIAN) -#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11 -#else -#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00 -#endif -#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565 - -/********************************************************************/ - -/* LCD controller restrictions */ -#define AU1100_LCD_MAX_XRES 800 -#define AU1100_LCD_MAX_YRES 600 -#define AU1100_LCD_MAX_BPP 16 -#define AU1100_LCD_MAX_CLK 48000000 -#define AU1100_LCD_NBR_PALETTE_ENTRIES 256 - -/* Default number of visible screen buffer to allocate */ -#define AU1100FB_NBR_VIDEO_BUFFERS 4 - -/********************************************************************/ - -struct au1100fb_panel -{ - const char name[25]; /* Full name _ */ - - u32 control_base; /* Mode-independent control values */ - u32 clkcontrol_base; /* Panel pixclock preferences */ - - u32 horztiming; - u32 verttiming; - - u32 xres; /* Maximum horizontal resolution */ - u32 yres; /* Maximum vertical resolution */ - u32 bpp; /* Maximum depth supported */ -}; - -struct au1100fb_regs -{ - u32 lcd_control; - u32 lcd_intstatus; - u32 lcd_intenable; - u32 lcd_horztiming; - u32 lcd_verttiming; - u32 lcd_clkcontrol; - u32 lcd_dmaaddr0; - u32 lcd_dmaaddr1; - u32 lcd_words; - u32 lcd_pwmdiv; - u32 lcd_pwmhi; - u32 reserved[(0x0400-0x002C)/4]; - u32 lcd_palettebase[256]; -}; - -struct au1100fb_device { - - struct fb_info info; /* FB driver info record */ - - struct au1100fb_panel *panel; /* Panel connected to this device */ - - struct au1100fb_regs* regs; /* Registers memory map */ - size_t regs_len; - unsigned int regs_phys; - - unsigned char* fb_mem; /* FrameBuffer memory map */ - size_t fb_len; - dma_addr_t fb_phys; - int panel_idx; - struct clk *lcdclk; - struct device *dev; -}; - -/********************************************************************/ - -#define LCD_CONTROL (AU1100_LCD_BASE + 0x0) - #define LCD_CONTROL_SBB_BIT 21 - #define LCD_CONTROL_SBB_MASK (0x3 << LCD_CONTROL_SBB_BIT) - #define LCD_CONTROL_SBB_1 (0 << LCD_CONTROL_SBB_BIT) - #define LCD_CONTROL_SBB_2 (1 << LCD_CONTROL_SBB_BIT) - #define LCD_CONTROL_SBB_3 (2 << LCD_CONTROL_SBB_BIT) - #define LCD_CONTROL_SBB_4 (3 << LCD_CONTROL_SBB_BIT) - #define LCD_CONTROL_SBPPF_BIT 18 - #define LCD_CONTROL_SBPPF_MASK (0x7 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_SBPPF_655 (0 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_SBPPF_565 (1 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_SBPPF_556 (2 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_SBPPF_1555 (3 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_SBPPF_5551 (4 << LCD_CONTROL_SBPPF_BIT) - #define LCD_CONTROL_WP (1<<17) - #define LCD_CONTROL_WD (1<<16) - #define LCD_CONTROL_C (1<<15) - #define LCD_CONTROL_SM_BIT 13 - #define LCD_CONTROL_SM_MASK (0x3 << LCD_CONTROL_SM_BIT) - #define LCD_CONTROL_SM_0 (0 << LCD_CONTROL_SM_BIT) - #define LCD_CONTROL_SM_90 (1 << LCD_CONTROL_SM_BIT) - #define LCD_CONTROL_SM_180 (2 << LCD_CONTROL_SM_BIT) - #define LCD_CONTROL_SM_270 (3 << LCD_CONTROL_SM_BIT) - #define LCD_CONTROL_DB (1<<12) - #define LCD_CONTROL_CCO (1<<11) - #define LCD_CONTROL_DP (1<<10) - #define LCD_CONTROL_PO_BIT 8 - #define LCD_CONTROL_PO_MASK (0x3 << LCD_CONTROL_PO_BIT) - #define LCD_CONTROL_PO_00 (0 << LCD_CONTROL_PO_BIT) - #define LCD_CONTROL_PO_01 (1 << LCD_CONTROL_PO_BIT) - #define LCD_CONTROL_PO_10 (2 << LCD_CONTROL_PO_BIT) - #define LCD_CONTROL_PO_11 (3 << LCD_CONTROL_PO_BIT) - #define LCD_CONTROL_MPI (1<<7) - #define LCD_CONTROL_PT (1<<6) - #define LCD_CONTROL_PC (1<<5) - #define LCD_CONTROL_BPP_BIT 1 - #define LCD_CONTROL_BPP_MASK (0x7 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_1 (0 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_2 (1 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_4 (2 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_8 (3 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_12 (4 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_BPP_16 (5 << LCD_CONTROL_BPP_BIT) - #define LCD_CONTROL_GO (1<<0) - -#define LCD_INTSTATUS (AU1100_LCD_BASE + 0x4) -#define LCD_INTENABLE (AU1100_LCD_BASE + 0x8) - #define LCD_INT_SD (1<<7) - #define LCD_INT_OF (1<<6) - #define LCD_INT_UF (1<<5) - #define LCD_INT_SA (1<<3) - #define LCD_INT_SS (1<<2) - #define LCD_INT_S1 (1<<1) - #define LCD_INT_S0 (1<<0) - -#define LCD_HORZTIMING (AU1100_LCD_BASE + 0xC) - #define LCD_HORZTIMING_HN2_BIT 24 - #define LCD_HORZTIMING_HN2_MASK (0xFF << LCD_HORZTIMING_HN2_BIT) - #define LCD_HORZTIMING_HN2_N(N) ((((N)-1) << LCD_HORZTIMING_HN2_BIT) & LCD_HORZTIMING_HN2_MASK) - #define LCD_HORZTIMING_HN1_BIT 16 - #define LCD_HORZTIMING_HN1_MASK (0xFF << LCD_HORZTIMING_HN1_BIT) - #define LCD_HORZTIMING_HN1_N(N) ((((N)-1) << LCD_HORZTIMING_HN1_BIT) & LCD_HORZTIMING_HN1_MASK) - #define LCD_HORZTIMING_HPW_BIT 10 - #define LCD_HORZTIMING_HPW_MASK (0x3F << LCD_HORZTIMING_HPW_BIT) - #define LCD_HORZTIMING_HPW_N(N) ((((N)-1) << LCD_HORZTIMING_HPW_BIT) & LCD_HORZTIMING_HPW_MASK) - #define LCD_HORZTIMING_PPL_BIT 0 - #define LCD_HORZTIMING_PPL_MASK (0x3FF << LCD_HORZTIMING_PPL_BIT) - #define LCD_HORZTIMING_PPL_N(N) ((((N)-1) << LCD_HORZTIMING_PPL_BIT) & LCD_HORZTIMING_PPL_MASK) - -#define LCD_VERTTIMING (AU1100_LCD_BASE + 0x10) - #define LCD_VERTTIMING_VN2_BIT 24 - #define LCD_VERTTIMING_VN2_MASK (0xFF << LCD_VERTTIMING_VN2_BIT) - #define LCD_VERTTIMING_VN2_N(N) ((((N)-1) << LCD_VERTTIMING_VN2_BIT) & LCD_VERTTIMING_VN2_MASK) - #define LCD_VERTTIMING_VN1_BIT 16 - #define LCD_VERTTIMING_VN1_MASK (0xFF << LCD_VERTTIMING_VN1_BIT) - #define LCD_VERTTIMING_VN1_N(N) ((((N)-1) << LCD_VERTTIMING_VN1_BIT) & LCD_VERTTIMING_VN1_MASK) - #define LCD_VERTTIMING_VPW_BIT 10 - #define LCD_VERTTIMING_VPW_MASK (0x3F << LCD_VERTTIMING_VPW_BIT) - #define LCD_VERTTIMING_VPW_N(N) ((((N)-1) << LCD_VERTTIMING_VPW_BIT) & LCD_VERTTIMING_VPW_MASK) - #define LCD_VERTTIMING_LPP_BIT 0 - #define LCD_VERTTIMING_LPP_MASK (0x3FF << LCD_VERTTIMING_LPP_BIT) - #define LCD_VERTTIMING_LPP_N(N) ((((N)-1) << LCD_VERTTIMING_LPP_BIT) & LCD_VERTTIMING_LPP_MASK) - -#define LCD_CLKCONTROL (AU1100_LCD_BASE + 0x14) - #define LCD_CLKCONTROL_IB (1<<18) - #define LCD_CLKCONTROL_IC (1<<17) - #define LCD_CLKCONTROL_IH (1<<16) - #define LCD_CLKCONTROL_IV (1<<15) - #define LCD_CLKCONTROL_BF_BIT 10 - #define LCD_CLKCONTROL_BF_MASK (0x1F << LCD_CLKCONTROL_BF_BIT) - #define LCD_CLKCONTROL_BF_N(N) ((((N)-1) << LCD_CLKCONTROL_BF_BIT) & LCD_CLKCONTROL_BF_MASK) - #define LCD_CLKCONTROL_PCD_BIT 0 - #define LCD_CLKCONTROL_PCD_MASK (0x3FF << LCD_CLKCONTROL_PCD_BIT) - #define LCD_CLKCONTROL_PCD_N(N) (((N) << LCD_CLKCONTROL_PCD_BIT) & LCD_CLKCONTROL_PCD_MASK) - -#define LCD_DMAADDR0 (AU1100_LCD_BASE + 0x18) -#define LCD_DMAADDR1 (AU1100_LCD_BASE + 0x1C) - #define LCD_DMA_SA_BIT 5 - #define LCD_DMA_SA_MASK (0x7FFFFFF << LCD_DMA_SA_BIT) - #define LCD_DMA_SA_N(N) ((N) & LCD_DMA_SA_MASK) - -#define LCD_WORDS (AU1100_LCD_BASE + 0x20) - #define LCD_WRD_WRDS_BIT 0 - #define LCD_WRD_WRDS_MASK (0xFFFFFFFF << LCD_WRD_WRDS_BIT) - #define LCD_WRD_WRDS_N(N) ((((N)-1) << LCD_WRD_WRDS_BIT) & LCD_WRD_WRDS_MASK) - -#define LCD_PWMDIV (AU1100_LCD_BASE + 0x24) - #define LCD_PWMDIV_EN (1<<12) - #define LCD_PWMDIV_PWMDIV_BIT 0 - #define LCD_PWMDIV_PWMDIV_MASK (0xFFF << LCD_PWMDIV_PWMDIV_BIT) - #define LCD_PWMDIV_PWMDIV_N(N) ((((N)-1) << LCD_PWMDIV_PWMDIV_BIT) & LCD_PWMDIV_PWMDIV_MASK) - -#define LCD_PWMHI (AU1100_LCD_BASE + 0x28) - #define LCD_PWMHI_PWMHI1_BIT 12 - #define LCD_PWMHI_PWMHI1_MASK (0xFFF << LCD_PWMHI_PWMHI1_BIT) - #define LCD_PWMHI_PWMHI1_N(N) (((N) << LCD_PWMHI_PWMHI1_BIT) & LCD_PWMHI_PWMHI1_MASK) - #define LCD_PWMHI_PWMHI0_BIT 0 - #define LCD_PWMHI_PWMHI0_MASK (0xFFF << LCD_PWMHI_PWMHI0_BIT) - #define LCD_PWMHI_PWMHI0_N(N) (((N) << LCD_PWMHI_PWMHI0_BIT) & LCD_PWMHI_PWMHI0_MASK) - -#define LCD_PALLETTEBASE (AU1100_LCD_BASE + 0x400) - #define LCD_PALLETTE_MONO_MI_BIT 0 - #define LCD_PALLETTE_MONO_MI_MASK (0xF << LCD_PALLETTE_MONO_MI_BIT) - #define LCD_PALLETTE_MONO_MI_N(N) (((N)<< LCD_PALLETTE_MONO_MI_BIT) & LCD_PALLETTE_MONO_MI_MASK) - - #define LCD_PALLETTE_COLOR_RI_BIT 8 - #define LCD_PALLETTE_COLOR_RI_MASK (0xF << LCD_PALLETTE_COLOR_RI_BIT) - #define LCD_PALLETTE_COLOR_RI_N(N) (((N)<< LCD_PALLETTE_COLOR_RI_BIT) & LCD_PALLETTE_COLOR_RI_MASK) - #define LCD_PALLETTE_COLOR_GI_BIT 4 - #define LCD_PALLETTE_COLOR_GI_MASK (0xF << LCD_PALLETTE_COLOR_GI_BIT) - #define LCD_PALLETTE_COLOR_GI_N(N) (((N)<< LCD_PALLETTE_COLOR_GI_BIT) & LCD_PALLETTE_COLOR_GI_MASK) - #define LCD_PALLETTE_COLOR_BI_BIT 0 - #define LCD_PALLETTE_COLOR_BI_MASK (0xF << LCD_PALLETTE_COLOR_BI_BIT) - #define LCD_PALLETTE_COLOR_BI_N(N) (((N)<< LCD_PALLETTE_COLOR_BI_BIT) & LCD_PALLETTE_COLOR_BI_MASK) - - #define LCD_PALLETTE_TFT_DC_BIT 0 - #define LCD_PALLETTE_TFT_DC_MASK (0xFFFF << LCD_PALLETTE_TFT_DC_BIT) - #define LCD_PALLETTE_TFT_DC_N(N) (((N)<< LCD_PALLETTE_TFT_DC_BIT) & LCD_PALLETTE_TFT_DC_MASK) - -/********************************************************************/ - -/* List of panels known to work with the AU1100 LCD controller. - * To add a new panel, enter the same specifications as the - * Generic_TFT one, and MAKE SURE that it doesn't conflicts - * with the controller restrictions. Restrictions are: - * - * STN color panels: max_bpp <= 12 - * STN mono panels: max_bpp <= 4 - * TFT panels: max_bpp <= 16 - * max_xres <= 800 - * max_yres <= 600 - */ -static struct au1100fb_panel known_lcd_panels[] = -{ - /* 800x600x16bpp CRT */ - [0] = { - .name = "CRT_800x600_16", - .xres = 800, - .yres = 600, - .bpp = 16, - .control_base = 0x0004886A | - LCD_CONTROL_DEFAULT_PO | LCD_CONTROL_DEFAULT_SBPPF | - LCD_CONTROL_BPP_16 | LCD_CONTROL_SBB_4, - .clkcontrol_base = 0x00020000, - .horztiming = 0x005aff1f, - .verttiming = 0x16000e57, - }, - /* just the standard LCD */ - [1] = { - .name = "WWPC LCD", - .xres = 240, - .yres = 320, - .bpp = 16, - .control_base = 0x0006806A, - .horztiming = 0x0A1010EF, - .verttiming = 0x0301013F, - .clkcontrol_base = 0x00018001, - }, - /* Sharp 320x240 TFT panel */ - [2] = { - .name = "Sharp_LQ038Q5DR01", - .xres = 320, - .yres = 240, - .bpp = 16, - .control_base = - ( LCD_CONTROL_SBPPF_565 - | LCD_CONTROL_C - | LCD_CONTROL_SM_0 - | LCD_CONTROL_DEFAULT_PO - | LCD_CONTROL_PT - | LCD_CONTROL_PC - | LCD_CONTROL_BPP_16 ), - .horztiming = - ( LCD_HORZTIMING_HN2_N(8) - | LCD_HORZTIMING_HN1_N(60) - | LCD_HORZTIMING_HPW_N(12) - | LCD_HORZTIMING_PPL_N(320) ), - .verttiming = - ( LCD_VERTTIMING_VN2_N(5) - | LCD_VERTTIMING_VN1_N(17) - | LCD_VERTTIMING_VPW_N(1) - | LCD_VERTTIMING_LPP_N(240) ), - .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1), - }, - - /* Hitachi SP14Q005 and possibly others */ - [3] = { - .name = "Hitachi_SP14Qxxx", - .xres = 320, - .yres = 240, - .bpp = 4, - .control_base = - ( LCD_CONTROL_C - | LCD_CONTROL_BPP_4 ), - .horztiming = - ( LCD_HORZTIMING_HN2_N(1) - | LCD_HORZTIMING_HN1_N(1) - | LCD_HORZTIMING_HPW_N(1) - | LCD_HORZTIMING_PPL_N(320) ), - .verttiming = - ( LCD_VERTTIMING_VN2_N(1) - | LCD_VERTTIMING_VN1_N(1) - | LCD_VERTTIMING_VPW_N(1) - | LCD_VERTTIMING_LPP_N(240) ), - .clkcontrol_base = LCD_CLKCONTROL_PCD_N(4), - }, - - /* Generic 640x480 TFT panel */ - [4] = { - .name = "TFT_640x480_16", - .xres = 640, - .yres = 480, - .bpp = 16, - .control_base = 0x004806a | LCD_CONTROL_DEFAULT_PO, - .horztiming = 0x3434d67f, - .verttiming = 0x0e0e39df, - .clkcontrol_base = LCD_CLKCONTROL_PCD_N(1), - }, - - /* Pb1100 LCDB 640x480 PrimeView TFT panel */ - [5] = { - .name = "PrimeView_640x480_16", - .xres = 640, - .yres = 480, - .bpp = 16, - .control_base = 0x0004886a | LCD_CONTROL_DEFAULT_PO, - .horztiming = 0x0e4bfe7f, - .verttiming = 0x210805df, - .clkcontrol_base = 0x00038001, - }, -}; - -/********************************************************************/ - -/* Inline helpers */ - -#define panel_is_dual(panel) (panel->control_base & LCD_CONTROL_DP) -#define panel_is_active(panel)(panel->control_base & LCD_CONTROL_PT) -#define panel_is_color(panel) (panel->control_base & LCD_CONTROL_PC) -#define panel_swap_rgb(panel) (panel->control_base & LCD_CONTROL_CCO) - -#endif /* _AU1100LCD_H */ diff --git a/drivers/video/fbdev/au1200fb.c b/drivers/video/fbdev/au1200fb.c index ed770222660b..685e629e7e16 100644 --- a/drivers/video/fbdev/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1724,8 +1724,10 @@ static int au1200fb_drv_probe(struct platform_device *dev) /* Now hook interrupt too */ irq = platform_get_irq(dev, 0); - if (irq < 0) - return irq; + if (irq < 0) { + ret = irq; + goto failed; + } ret = request_irq(irq, au1200fb_handle_irq, IRQF_SHARED, "lcd", (void *)dev); diff --git a/drivers/video/fbdev/carminefb.c b/drivers/video/fbdev/carminefb.c index 2bdd67595891..bd4bff6a2484 100644 --- a/drivers/video/fbdev/carminefb.c +++ b/drivers/video/fbdev/carminefb.c @@ -620,7 +620,7 @@ static int carminefb_probe(struct pci_dev *dev, const struct pci_device_id *ent) return ret; ret = -ENOMEM; - hw = kzalloc(sizeof *hw, GFP_KERNEL); + hw = kzalloc_obj(*hw); if (!hw) goto err_enable_pci; diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index 5c5284e8ae0e..4bb821d7f284 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -944,7 +944,7 @@ static int __init control_of_init(struct device_node *dp) printk(KERN_ERR "can't get 2 addresses for control\n"); return -ENXIO; } - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; control_fb = p; /* save it for cleanups */ diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 8df2e51e3390..ca48b89a323d 100644 --- a/drivers/video/fbdev/core/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c @@ -307,7 +307,7 @@ int fb_deferred_io_init(struct fb_info *info) npagerefs = DIV_ROUND_UP(info->fix.smem_len, PAGE_SIZE); /* alloc a page ref for each page of the display memory */ - pagerefs = kvcalloc(npagerefs, sizeof(*pagerefs), GFP_KERNEL); + pagerefs = kvzalloc_objs(*pagerefs, npagerefs); if (!pagerefs) { ret = -ENOMEM; goto err; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 34ea14412ace..666261ae59d8 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -769,7 +769,7 @@ static int fbcon_open(struct fb_info *info) } unlock_fb_info(info); - par = kzalloc(sizeof(*par), GFP_KERNEL); + par = kzalloc_obj(*par); if (!par) { fbcon_release(info); return -ENOMEM; @@ -1068,7 +1068,8 @@ static void fbcon_init(struct vc_data *vc, bool init) return; if (!info->fbcon_par) - con2fb_acquire_newinfo(vc, info, vc->vc_num); + if (con2fb_acquire_newinfo(vc, info, vc->vc_num)) + return; /* If we are not the first console on this fb, copy the font from that console */ @@ -1607,12 +1608,10 @@ static void fbcon_redraw_move(struct vc_data *vc, struct fbcon_display *p, start = s; } } - console_conditional_schedule(); s++; } while (s < le); if (s > start) fbcon_putcs(vc, start, s - start, dy, x); - console_conditional_schedule(); dy++; } } @@ -1648,14 +1647,12 @@ static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, } scr_writew(c, d); - console_conditional_schedule(); s++; d++; } while (s < le); if (s > start) par->bitops->bmove(vc, info, line + ycount, x, line, x, 1, s - start); - console_conditional_schedule(); if (ycount > 0) line++; else { @@ -1703,13 +1700,11 @@ static void fbcon_redraw(struct vc_data *vc, int line, int count, int offset) } } scr_writew(c, d); - console_conditional_schedule(); s++; d++; } while (s < le); if (s > start) fbcon_putcs(vc, start, s - start, line, x); - console_conditional_schedule(); if (offset > 0) line++; else { diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h index 1cd10a7faab0..fca14e9b729b 100644 --- a/drivers/video/fbdev/core/fbcon.h +++ b/drivers/video/fbdev/core/fbcon.h @@ -30,7 +30,6 @@ struct fbcon_display { #ifdef CONFIG_FRAMEBUFFER_CONSOLE_LEGACY_ACCELERATION u_short scrollmode; /* Scroll Method, use fb_scrollmode() */ #endif - u_short inverse; /* != 0 text black on white as default */ short yscroll; /* Hardware scrolling */ int vrows; /* number of virtual rows */ int cursor_shape; diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index eff757ebbed1..cf199038f069 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -100,7 +100,7 @@ EXPORT_SYMBOL(fb_pad_aligned_buffer); void fb_pad_unaligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 idx, u32 height, u32 shift_high, u32 shift_low, u32 mod) { - u8 mask = (u8) (0xfff << shift_high), tmp; + u8 mask = (u8) (0xff << shift_high), tmp; int i, j; for (i = height; i--; ) { diff --git a/drivers/video/fbdev/core/fbmon.c b/drivers/video/fbdev/core/fbmon.c index 07df7e98f8a3..f96b4e7b7f21 100644 --- a/drivers/video/fbdev/core/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -388,7 +388,7 @@ static void calc_mode_timings(int xres, int yres, int refresh, { struct fb_var_screeninfo *var; - var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); + var = kzalloc_obj(struct fb_var_screeninfo); if (var) { var->xres = xres; @@ -626,7 +626,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, int num = 0, i, first = 1; int ver, rev; - mode = kcalloc(50, sizeof(struct fb_videomode), GFP_KERNEL); + mode = kzalloc_objs(struct fb_videomode, 50); if (mode == NULL) return NULL; @@ -677,7 +677,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize, } *dbsize = num; - m = kmalloc_array(num, sizeof(struct fb_videomode), GFP_KERNEL); + m = kmalloc_objs(struct fb_videomode, num); if (!m) return mode; memmove(m, mode, num * sizeof(struct fb_videomode)); @@ -1224,7 +1224,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax, err = 0; - timings = kzalloc(sizeof(struct __fb_timings), GFP_KERNEL); + timings = kzalloc_obj(struct __fb_timings); if (!timings) return -ENOMEM; diff --git a/drivers/video/fbdev/core/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index b8344c40073b..baa2bae0fb5b 100644 --- a/drivers/video/fbdev/core/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -12,8 +12,6 @@ #include "fb_internal.h" -#define FB_SYSFS_FLAG_ATTR 1 - static int activate(struct fb_info *fb_info, struct fb_var_screeninfo *var) { int err; @@ -451,33 +449,7 @@ static struct attribute *fb_device_attrs[] = { NULL, }; -static const struct attribute_group fb_device_attr_group = { - .attrs = fb_device_attrs, -}; - -static int fb_init_device(struct fb_info *fb_info) -{ - int ret; - - dev_set_drvdata(fb_info->dev, fb_info); - - fb_info->class_flag |= FB_SYSFS_FLAG_ATTR; - - ret = device_add_group(fb_info->dev, &fb_device_attr_group); - if (ret) - fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; - - return 0; -} - -static void fb_cleanup_device(struct fb_info *fb_info) -{ - if (fb_info->class_flag & FB_SYSFS_FLAG_ATTR) { - device_remove_group(fb_info->dev, &fb_device_attr_group); - - fb_info->class_flag &= ~FB_SYSFS_FLAG_ATTR; - } -} +ATTRIBUTE_GROUPS(fb_device); int fb_device_create(struct fb_info *fb_info) { @@ -485,14 +457,13 @@ int fb_device_create(struct fb_info *fb_info) dev_t devt = MKDEV(FB_MAJOR, node); int ret; - fb_info->dev = device_create(fb_class, fb_info->device, devt, NULL, "fb%d", node); + fb_info->dev = device_create_with_groups(fb_class, fb_info->device, devt, fb_info, + fb_device_groups, "fb%d", node); if (IS_ERR(fb_info->dev)) { /* Not fatal */ ret = PTR_ERR(fb_info->dev); pr_warn("Unable to create device for framebuffer %d; error %d\n", node, ret); fb_info->dev = NULL; - } else { - fb_init_device(fb_info); } return 0; @@ -505,7 +476,6 @@ void fb_device_destroy(struct fb_info *fb_info) if (!fb_info->dev) return; - fb_cleanup_device(fb_info); device_destroy(fb_class, devt); fb_info->dev = NULL; } diff --git a/drivers/video/fbdev/core/modedb.c b/drivers/video/fbdev/core/modedb.c index 53a610948c4a..703d0b7aec32 100644 --- a/drivers/video/fbdev/core/modedb.c +++ b/drivers/video/fbdev/core/modedb.c @@ -1070,8 +1070,7 @@ int fb_add_videomode(const struct fb_videomode *mode, struct list_head *head) } } if (!found) { - modelist = kmalloc(sizeof(struct fb_modelist), - GFP_KERNEL); + modelist = kmalloc_obj(struct fb_modelist); if (!modelist) return -ENOMEM; diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 5cb5ee517f81..2d12f8e96c7e 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -1363,7 +1363,7 @@ static struct cfb_info *cyberpro_alloc_fb_info(unsigned int id, char *name) { struct cfb_info *cfb; - cfb = kzalloc(sizeof(struct cfb_info), GFP_KERNEL); + cfb = kzalloc_obj(struct cfb_info); if (!cfb) return NULL; diff --git a/drivers/video/fbdev/ffb.c b/drivers/video/fbdev/ffb.c index 34b6abff9493..da531b4cb451 100644 --- a/drivers/video/fbdev/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -335,6 +335,9 @@ struct ffb_dac { }; #define FFB_DAC_UCTRL 0x1001 /* User Control */ +#define FFB_DAC_UCTRL_OVENAB 0x00000008 /* Overlay Enable */ +#define FFB_DAC_UCTRL_WMODE 0x00000030 /* Window Mode */ +#define FFB_DAC_UCTRL_WM_COMB 0x00000000 /* Window Mode = Combined */ #define FFB_DAC_UCTRL_MANREV 0x00000f00 /* 4-bit Manufacturing Revision */ #define FFB_DAC_UCTRL_MANREV_SHIFT 8 #define FFB_DAC_TGEN 0x6000 /* Timing Generator */ @@ -425,7 +428,7 @@ static void ffb_switch_from_graph(struct ffb_par *par) { struct ffb_fbc __iomem *fbc = par->fbc; struct ffb_dac __iomem *dac = par->dac; - unsigned long flags; + unsigned long flags, uctrl; spin_lock_irqsave(&par->lock, flags); FFBWait(par); @@ -450,6 +453,15 @@ static void ffb_switch_from_graph(struct ffb_par *par) upa_writel((FFB_DAC_CUR_CTRL_P0 | FFB_DAC_CUR_CTRL_P1), &dac->value2); + /* Disable overlay and window modes. */ + upa_writel(FFB_DAC_UCTRL, &dac->type); + uctrl = upa_readl(&dac->value); + uctrl &= ~FFB_DAC_UCTRL_WMODE; + uctrl |= FFB_DAC_UCTRL_WM_COMB; + uctrl &= ~FFB_DAC_UCTRL_OVENAB; + upa_writel(FFB_DAC_UCTRL, &dac->type); + upa_writel(uctrl, &dac->value); + spin_unlock_irqrestore(&par->lock, flags); } diff --git a/drivers/video/fbdev/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c index 7704f2ab18c0..ffe33a36b944 100644 --- a/drivers/video/fbdev/goldfishfb.c +++ b/drivers/video/fbdev/goldfishfb.c @@ -180,7 +180,7 @@ static int goldfish_fb_probe(struct platform_device *pdev) u32 width, height; dma_addr_t fbpaddr; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (fb == NULL) { ret = -ENOMEM; goto err_fb_alloc_failed; diff --git a/drivers/video/fbdev/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c deleted file mode 100644 index c99e2ea4b3de..000000000000 --- a/drivers/video/fbdev/hyperv_fb.c +++ /dev/null @@ -1,1388 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012, Microsoft Corporation. - * - * Author: - * Haiyang Zhang - */ - -/* - * Hyper-V Synthetic Video Frame Buffer Driver - * - * This is the driver for the Hyper-V Synthetic Video, which supports - * screen resolution up to Full HD 1920x1080 with 32 bit color on Windows - * Server 2012, and 1600x1200 with 16 bit color on Windows Server 2008 R2 - * or earlier. - * - * It also solves the double mouse cursor issue of the emulated video mode. - * - * The default screen resolution is 1152x864, which may be changed by a - * kernel parameter: - * video=hyperv_fb:x - * For example: video=hyperv_fb:1280x1024 - * - * Portrait orientation is also supported: - * For example: video=hyperv_fb:864x1152 - * - * When a Windows 10 RS5+ host is used, the virtual machine screen - * resolution is obtained from the host. The "video=hyperv_fb" option is - * not needed, but still can be used to overwrite what the host specifies. - * The VM resolution on the host could be set by executing the powershell - * "set-vmvideo" command. For example - * set-vmvideo -vmname name -horizontalresolution:1920 \ - * -verticalresolution:1200 -resolutiontype single - * - * Gen 1 VMs also support direct using VM's physical memory for framebuffer. - * It could improve the efficiency and performance for framebuffer and VM. - * This requires to allocate contiguous physical memory from Linux kernel's - * CMA memory allocator. To enable this, supply a kernel parameter to give - * enough memory space to CMA allocator for framebuffer. For example: - * cma=130m - * This gives 130MB memory to CMA allocator that can be allocated to - * framebuffer. For reference, 8K resolution (7680x4320) takes about - * 127MB memory. - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Hyper-V Synthetic Video Protocol definitions and structures */ -#define MAX_VMBUS_PKT_SIZE 0x4000 - -#define SYNTHVID_VERSION(major, minor) ((minor) << 16 | (major)) -/* Support for VERSION_WIN7 is removed. #define is retained for reference. */ -#define SYNTHVID_VERSION_WIN7 SYNTHVID_VERSION(3, 0) -#define SYNTHVID_VERSION_WIN8 SYNTHVID_VERSION(3, 2) -#define SYNTHVID_VERSION_WIN10 SYNTHVID_VERSION(3, 5) - -#define SYNTHVID_VER_GET_MAJOR(ver) (ver & 0x0000ffff) -#define SYNTHVID_VER_GET_MINOR(ver) ((ver & 0xffff0000) >> 16) - -#define SYNTHVID_DEPTH_WIN8 32 -#define SYNTHVID_FB_SIZE_WIN8 (8 * 1024 * 1024) - -enum pipe_msg_type { - PIPE_MSG_INVALID, - PIPE_MSG_DATA, - PIPE_MSG_MAX -}; - -struct pipe_msg_hdr { - u32 type; - u32 size; /* size of message after this field */ -} __packed; - - -enum synthvid_msg_type { - SYNTHVID_ERROR = 0, - SYNTHVID_VERSION_REQUEST = 1, - SYNTHVID_VERSION_RESPONSE = 2, - SYNTHVID_VRAM_LOCATION = 3, - SYNTHVID_VRAM_LOCATION_ACK = 4, - SYNTHVID_SITUATION_UPDATE = 5, - SYNTHVID_SITUATION_UPDATE_ACK = 6, - SYNTHVID_POINTER_POSITION = 7, - SYNTHVID_POINTER_SHAPE = 8, - SYNTHVID_FEATURE_CHANGE = 9, - SYNTHVID_DIRT = 10, - SYNTHVID_RESOLUTION_REQUEST = 13, - SYNTHVID_RESOLUTION_RESPONSE = 14, - - SYNTHVID_MAX = 15 -}; - -#define SYNTHVID_EDID_BLOCK_SIZE 128 -#define SYNTHVID_MAX_RESOLUTION_COUNT 64 - -struct hvd_screen_info { - u16 width; - u16 height; -} __packed; - -struct synthvid_msg_hdr { - u32 type; - u32 size; /* size of this header + payload after this field*/ -} __packed; - -struct synthvid_version_req { - u32 version; -} __packed; - -struct synthvid_version_resp { - u32 version; - u8 is_accepted; - u8 max_video_outputs; -} __packed; - -struct synthvid_supported_resolution_req { - u8 maximum_resolution_count; -} __packed; - -struct synthvid_supported_resolution_resp { - u8 edid_block[SYNTHVID_EDID_BLOCK_SIZE]; - u8 resolution_count; - u8 default_resolution_index; - u8 is_standard; - struct hvd_screen_info - supported_resolution[SYNTHVID_MAX_RESOLUTION_COUNT]; -} __packed; - -struct synthvid_vram_location { - u64 user_ctx; - u8 is_vram_gpa_specified; - u64 vram_gpa; -} __packed; - -struct synthvid_vram_location_ack { - u64 user_ctx; -} __packed; - -struct video_output_situation { - u8 active; - u32 vram_offset; - u8 depth_bits; - u32 width_pixels; - u32 height_pixels; - u32 pitch_bytes; -} __packed; - -struct synthvid_situation_update { - u64 user_ctx; - u8 video_output_count; - struct video_output_situation video_output[1]; -} __packed; - -struct synthvid_situation_update_ack { - u64 user_ctx; -} __packed; - -struct synthvid_pointer_position { - u8 is_visible; - u8 video_output; - s32 image_x; - s32 image_y; -} __packed; - - -#define CURSOR_MAX_X 96 -#define CURSOR_MAX_Y 96 -#define CURSOR_ARGB_PIXEL_SIZE 4 -#define CURSOR_MAX_SIZE (CURSOR_MAX_X * CURSOR_MAX_Y * CURSOR_ARGB_PIXEL_SIZE) -#define CURSOR_COMPLETE (-1) - -struct synthvid_pointer_shape { - u8 part_idx; - u8 is_argb; - u32 width; /* CURSOR_MAX_X at most */ - u32 height; /* CURSOR_MAX_Y at most */ - u32 hot_x; /* hotspot relative to upper-left of pointer image */ - u32 hot_y; - u8 data[4]; -} __packed; - -struct synthvid_feature_change { - u8 is_dirt_needed; - u8 is_ptr_pos_needed; - u8 is_ptr_shape_needed; - u8 is_situ_needed; -} __packed; - -struct rect { - s32 x1, y1; /* top left corner */ - s32 x2, y2; /* bottom right corner, exclusive */ -} __packed; - -struct synthvid_dirt { - u8 video_output; - u8 dirt_count; - struct rect rect[1]; -} __packed; - -struct synthvid_msg { - struct pipe_msg_hdr pipe_hdr; - struct synthvid_msg_hdr vid_hdr; - union { - struct synthvid_version_req ver_req; - struct synthvid_version_resp ver_resp; - struct synthvid_vram_location vram; - struct synthvid_vram_location_ack vram_ack; - struct synthvid_situation_update situ; - struct synthvid_situation_update_ack situ_ack; - struct synthvid_pointer_position ptr_pos; - struct synthvid_pointer_shape ptr_shape; - struct synthvid_feature_change feature_chg; - struct synthvid_dirt dirt; - struct synthvid_supported_resolution_req resolution_req; - struct synthvid_supported_resolution_resp resolution_resp; - }; -} __packed; - - -/* FB driver definitions and structures */ -#define HVFB_WIDTH 1152 /* default screen width */ -#define HVFB_HEIGHT 864 /* default screen height */ -#define HVFB_WIDTH_MIN 640 -#define HVFB_HEIGHT_MIN 480 - -#define RING_BUFSIZE (256 * 1024) -#define VSP_TIMEOUT (10 * HZ) -#define HVFB_UPDATE_DELAY (HZ / 20) -#define HVFB_ONDEMAND_THROTTLE (HZ / 20) - -struct hvfb_par { - struct fb_info *info; - struct resource *mem; - bool fb_ready; /* fb device is ready */ - struct completion wait; - u32 synthvid_version; - - struct delayed_work dwork; - bool update; - bool update_saved; /* The value of 'update' before hibernation */ - - u32 pseudo_palette[16]; - u8 init_buf[MAX_VMBUS_PKT_SIZE]; - u8 recv_buf[MAX_VMBUS_PKT_SIZE]; - - /* If true, the VSC notifies the VSP on every framebuffer change */ - bool synchronous_fb; - - /* If true, need to copy from deferred IO mem to framebuffer mem */ - bool need_docopy; - - struct notifier_block hvfb_panic_nb; - - /* Memory for deferred IO and frame buffer itself */ - unsigned char *dio_vp; - unsigned char *mmio_vp; - phys_addr_t mmio_pp; - - /* Dirty rectangle, protected by delayed_refresh_lock */ - int x1, y1, x2, y2; - bool delayed_refresh; - spinlock_t delayed_refresh_lock; -}; - -static uint screen_width = HVFB_WIDTH; -static uint screen_height = HVFB_HEIGHT; -static uint screen_depth; -static uint screen_fb_size; -static uint dio_fb_size; /* FB size for deferred IO */ - -static void hvfb_putmem(struct fb_info *info); - -/* Send message to Hyper-V host */ -static inline int synthvid_send(struct hv_device *hdev, - struct synthvid_msg *msg) -{ - static atomic64_t request_id = ATOMIC64_INIT(0); - int ret; - - msg->pipe_hdr.type = PIPE_MSG_DATA; - msg->pipe_hdr.size = msg->vid_hdr.size; - - ret = vmbus_sendpacket(hdev->channel, msg, - msg->vid_hdr.size + sizeof(struct pipe_msg_hdr), - atomic64_inc_return(&request_id), - VM_PKT_DATA_INBAND, 0); - - if (ret) - pr_err_ratelimited("Unable to send packet via vmbus; error %d\n", ret); - - return ret; -} - - -/* Send screen resolution info to host */ -static int synthvid_send_situ(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct synthvid_msg msg; - - if (!info) - return -ENODEV; - - memset(&msg, 0, sizeof(struct synthvid_msg)); - - msg.vid_hdr.type = SYNTHVID_SITUATION_UPDATE; - msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_situation_update); - msg.situ.user_ctx = 0; - msg.situ.video_output_count = 1; - msg.situ.video_output[0].active = 1; - msg.situ.video_output[0].vram_offset = 0; - msg.situ.video_output[0].depth_bits = info->var.bits_per_pixel; - msg.situ.video_output[0].width_pixels = info->var.xres; - msg.situ.video_output[0].height_pixels = info->var.yres; - msg.situ.video_output[0].pitch_bytes = info->fix.line_length; - - synthvid_send(hdev, &msg); - - return 0; -} - -/* Send mouse pointer info to host */ -static int synthvid_send_ptr(struct hv_device *hdev) -{ - struct synthvid_msg msg; - - memset(&msg, 0, sizeof(struct synthvid_msg)); - msg.vid_hdr.type = SYNTHVID_POINTER_POSITION; - msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_pointer_position); - msg.ptr_pos.is_visible = 1; - msg.ptr_pos.video_output = 0; - msg.ptr_pos.image_x = 0; - msg.ptr_pos.image_y = 0; - synthvid_send(hdev, &msg); - - memset(&msg, 0, sizeof(struct synthvid_msg)); - msg.vid_hdr.type = SYNTHVID_POINTER_SHAPE; - msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_pointer_shape); - msg.ptr_shape.part_idx = CURSOR_COMPLETE; - msg.ptr_shape.is_argb = 1; - msg.ptr_shape.width = 1; - msg.ptr_shape.height = 1; - msg.ptr_shape.hot_x = 0; - msg.ptr_shape.hot_y = 0; - msg.ptr_shape.data[0] = 0; - msg.ptr_shape.data[1] = 1; - msg.ptr_shape.data[2] = 1; - msg.ptr_shape.data[3] = 1; - synthvid_send(hdev, &msg); - - return 0; -} - -/* Send updated screen area (dirty rectangle) location to host */ -static int -synthvid_update(struct fb_info *info, int x1, int y1, int x2, int y2) -{ - struct hv_device *hdev = device_to_hv_device(info->device); - struct synthvid_msg msg; - - memset(&msg, 0, sizeof(struct synthvid_msg)); - if (x2 == INT_MAX) - x2 = info->var.xres; - if (y2 == INT_MAX) - y2 = info->var.yres; - - msg.vid_hdr.type = SYNTHVID_DIRT; - msg.vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_dirt); - msg.dirt.video_output = 0; - msg.dirt.dirt_count = 1; - msg.dirt.rect[0].x1 = (x1 > x2) ? 0 : x1; - msg.dirt.rect[0].y1 = (y1 > y2) ? 0 : y1; - msg.dirt.rect[0].x2 = - (x2 < x1 || x2 > info->var.xres) ? info->var.xres : x2; - msg.dirt.rect[0].y2 = - (y2 < y1 || y2 > info->var.yres) ? info->var.yres : y2; - - synthvid_send(hdev, &msg); - - return 0; -} - -static void hvfb_docopy(struct hvfb_par *par, - unsigned long offset, - unsigned long size) -{ - if (!par || !par->mmio_vp || !par->dio_vp || !par->fb_ready || - size == 0 || offset >= dio_fb_size) - return; - - if (offset + size > dio_fb_size) - size = dio_fb_size - offset; - - memcpy(par->mmio_vp + offset, par->dio_vp + offset, size); -} - -/* Deferred IO callback */ -static void synthvid_deferred_io(struct fb_info *p, struct list_head *pagereflist) -{ - struct hvfb_par *par = p->par; - struct fb_deferred_io_pageref *pageref; - unsigned long start, end; - int y1, y2, miny, maxy; - - miny = INT_MAX; - maxy = 0; - - /* - * Merge dirty pages. It is possible that last page cross - * over the end of frame buffer row yres. This is taken care of - * in synthvid_update function by clamping the y2 - * value to yres. - */ - list_for_each_entry(pageref, pagereflist, list) { - start = pageref->offset; - end = start + PAGE_SIZE - 1; - y1 = start / p->fix.line_length; - y2 = end / p->fix.line_length; - miny = min_t(int, miny, y1); - maxy = max_t(int, maxy, y2); - - /* Copy from dio space to mmio address */ - if (par->fb_ready && par->need_docopy) - hvfb_docopy(par, start, PAGE_SIZE); - } - - if (par->fb_ready && par->update) - synthvid_update(p, 0, miny, p->var.xres, maxy + 1); -} - -static struct fb_deferred_io synthvid_defio = { - .delay = HZ / 20, - .deferred_io = synthvid_deferred_io, -}; - -/* - * Actions on received messages from host: - * Complete the wait event. - * Or, reply with screen and cursor info. - */ -static void synthvid_recv_sub(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par; - struct synthvid_msg *msg; - - if (!info) - return; - - par = info->par; - msg = (struct synthvid_msg *)par->recv_buf; - - /* Complete the wait event */ - if (msg->vid_hdr.type == SYNTHVID_VERSION_RESPONSE || - msg->vid_hdr.type == SYNTHVID_RESOLUTION_RESPONSE || - msg->vid_hdr.type == SYNTHVID_VRAM_LOCATION_ACK) { - memcpy(par->init_buf, msg, MAX_VMBUS_PKT_SIZE); - complete(&par->wait); - return; - } - - /* Reply with screen and cursor info */ - if (msg->vid_hdr.type == SYNTHVID_FEATURE_CHANGE) { - if (par->fb_ready) { - synthvid_send_ptr(hdev); - synthvid_send_situ(hdev); - } - - par->update = msg->feature_chg.is_dirt_needed; - if (par->update) - schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); - } -} - -/* Receive callback for messages from the host */ -static void synthvid_receive(void *ctx) -{ - struct hv_device *hdev = ctx; - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par; - struct synthvid_msg *recv_buf; - u32 bytes_recvd; - u64 req_id; - int ret; - - if (!info) - return; - - par = info->par; - recv_buf = (struct synthvid_msg *)par->recv_buf; - - do { - ret = vmbus_recvpacket(hdev->channel, recv_buf, - MAX_VMBUS_PKT_SIZE, - &bytes_recvd, &req_id); - if (bytes_recvd > 0 && - recv_buf->pipe_hdr.type == PIPE_MSG_DATA) - synthvid_recv_sub(hdev); - } while (bytes_recvd > 0 && ret == 0); -} - -/* Check if the ver1 version is equal or greater than ver2 */ -static inline bool synthvid_ver_ge(u32 ver1, u32 ver2) -{ - if (SYNTHVID_VER_GET_MAJOR(ver1) > SYNTHVID_VER_GET_MAJOR(ver2) || - (SYNTHVID_VER_GET_MAJOR(ver1) == SYNTHVID_VER_GET_MAJOR(ver2) && - SYNTHVID_VER_GET_MINOR(ver1) >= SYNTHVID_VER_GET_MINOR(ver2))) - return true; - - return false; -} - -/* Check synthetic video protocol version with the host */ -static int synthvid_negotiate_ver(struct hv_device *hdev, u32 ver) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; - int ret = 0; - unsigned long t; - - memset(msg, 0, sizeof(struct synthvid_msg)); - msg->vid_hdr.type = SYNTHVID_VERSION_REQUEST; - msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_version_req); - msg->ver_req.version = ver; - synthvid_send(hdev, msg); - - t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); - if (!t) { - pr_err("Time out on waiting version response\n"); - ret = -ETIMEDOUT; - goto out; - } - if (!msg->ver_resp.is_accepted) { - ret = -ENODEV; - goto out; - } - - par->synthvid_version = ver; - pr_info("Synthvid Version major %d, minor %d\n", - SYNTHVID_VER_GET_MAJOR(ver), SYNTHVID_VER_GET_MINOR(ver)); - -out: - return ret; -} - -/* Get current resolution from the host */ -static int synthvid_get_supported_resolution(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; - int ret = 0; - unsigned long t; - u8 index; - - memset(msg, 0, sizeof(struct synthvid_msg)); - msg->vid_hdr.type = SYNTHVID_RESOLUTION_REQUEST; - msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_supported_resolution_req); - - msg->resolution_req.maximum_resolution_count = - SYNTHVID_MAX_RESOLUTION_COUNT; - synthvid_send(hdev, msg); - - t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); - if (!t) { - pr_err("Time out on waiting resolution response\n"); - ret = -ETIMEDOUT; - goto out; - } - - if (msg->resolution_resp.resolution_count == 0) { - pr_err("No supported resolutions\n"); - ret = -ENODEV; - goto out; - } - - index = msg->resolution_resp.default_resolution_index; - if (index >= msg->resolution_resp.resolution_count) { - pr_err("Invalid resolution index: %d\n", index); - ret = -ENODEV; - goto out; - } - - screen_width = - msg->resolution_resp.supported_resolution[index].width; - screen_height = - msg->resolution_resp.supported_resolution[index].height; - -out: - return ret; -} - -/* Connect to VSP (Virtual Service Provider) on host */ -static int synthvid_connect_vsp(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - int ret; - - ret = vmbus_open(hdev->channel, RING_BUFSIZE, RING_BUFSIZE, - NULL, 0, synthvid_receive, hdev); - if (ret) { - pr_err("Unable to open vmbus channel\n"); - return ret; - } - - /* Negotiate the protocol version with host */ - switch (vmbus_proto_version) { - case VERSION_WIN10: - case VERSION_WIN10_V5: - ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN10); - if (!ret) - break; - fallthrough; - case VERSION_WIN8: - case VERSION_WIN8_1: - ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN8); - break; - default: - ret = synthvid_negotiate_ver(hdev, SYNTHVID_VERSION_WIN10); - break; - } - - if (ret) { - pr_err("Synthetic video device version not accepted\n"); - goto error; - } - - screen_depth = SYNTHVID_DEPTH_WIN8; - if (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10)) { - ret = synthvid_get_supported_resolution(hdev); - if (ret) - pr_info("Failed to get supported resolution from host, use default\n"); - } - - screen_fb_size = hdev->channel->offermsg.offer. - mmio_megabytes * 1024 * 1024; - - return 0; - -error: - vmbus_close(hdev->channel); - return ret; -} - -/* Send VRAM and Situation messages to the host */ -static int synthvid_send_config(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - struct synthvid_msg *msg = (struct synthvid_msg *)par->init_buf; - int ret = 0; - unsigned long t; - - /* Send VRAM location */ - memset(msg, 0, sizeof(struct synthvid_msg)); - msg->vid_hdr.type = SYNTHVID_VRAM_LOCATION; - msg->vid_hdr.size = sizeof(struct synthvid_msg_hdr) + - sizeof(struct synthvid_vram_location); - msg->vram.user_ctx = msg->vram.vram_gpa = par->mmio_pp; - msg->vram.is_vram_gpa_specified = 1; - synthvid_send(hdev, msg); - - t = wait_for_completion_timeout(&par->wait, VSP_TIMEOUT); - if (!t) { - pr_err("Time out on waiting vram location ack\n"); - ret = -ETIMEDOUT; - goto out; - } - if (msg->vram_ack.user_ctx != par->mmio_pp) { - pr_err("Unable to set VRAM location\n"); - ret = -ENODEV; - goto out; - } - - /* Send pointer and situation update */ - synthvid_send_ptr(hdev); - synthvid_send_situ(hdev); - -out: - return ret; -} - - -/* - * Delayed work callback: - * It is scheduled to call whenever update request is received and it has - * not been called in last HVFB_ONDEMAND_THROTTLE time interval. - */ -static void hvfb_update_work(struct work_struct *w) -{ - struct hvfb_par *par = container_of(w, struct hvfb_par, dwork.work); - struct fb_info *info = par->info; - unsigned long flags; - int x1, x2, y1, y2; - int j; - - spin_lock_irqsave(&par->delayed_refresh_lock, flags); - /* Reset the request flag */ - par->delayed_refresh = false; - - /* Store the dirty rectangle to local variables */ - x1 = par->x1; - x2 = par->x2; - y1 = par->y1; - y2 = par->y2; - - /* Clear dirty rectangle */ - par->x1 = par->y1 = INT_MAX; - par->x2 = par->y2 = 0; - - spin_unlock_irqrestore(&par->delayed_refresh_lock, flags); - - if (x1 > info->var.xres || x2 > info->var.xres || - y1 > info->var.yres || y2 > info->var.yres || x2 <= x1) - return; - - /* Copy the dirty rectangle to frame buffer memory */ - if (par->need_docopy) - for (j = y1; j < y2; j++) - hvfb_docopy(par, - j * info->fix.line_length + - (x1 * screen_depth / 8), - (x2 - x1) * screen_depth / 8); - - /* Refresh */ - if (par->fb_ready && par->update) - synthvid_update(info, x1, y1, x2, y2); -} - -/* - * Control the on-demand refresh frequency. It schedules a delayed - * screen update if it has not yet. - */ -static void hvfb_ondemand_refresh_throttle(struct hvfb_par *par, - int x1, int y1, int w, int h) -{ - unsigned long flags; - int x2 = x1 + w; - int y2 = y1 + h; - - spin_lock_irqsave(&par->delayed_refresh_lock, flags); - - /* Merge dirty rectangle */ - par->x1 = min_t(int, par->x1, x1); - par->y1 = min_t(int, par->y1, y1); - par->x2 = max_t(int, par->x2, x2); - par->y2 = max_t(int, par->y2, y2); - - /* Schedule a delayed screen update if not yet */ - if (par->delayed_refresh == false) { - schedule_delayed_work(&par->dwork, - HVFB_ONDEMAND_THROTTLE); - par->delayed_refresh = true; - } - - spin_unlock_irqrestore(&par->delayed_refresh_lock, flags); -} - -static int hvfb_on_panic(struct notifier_block *nb, - unsigned long e, void *p) -{ - struct hv_device *hdev; - struct hvfb_par *par; - struct fb_info *info; - - par = container_of(nb, struct hvfb_par, hvfb_panic_nb); - info = par->info; - hdev = device_to_hv_device(info->device); - - if (hv_ringbuffer_spinlock_busy(hdev->channel)) - return NOTIFY_DONE; - - par->synchronous_fb = true; - if (par->need_docopy) - hvfb_docopy(par, 0, dio_fb_size); - synthvid_update(info, 0, 0, INT_MAX, INT_MAX); - - return NOTIFY_DONE; -} - -/* Framebuffer operation handlers */ - -static int hvfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - if (var->xres < HVFB_WIDTH_MIN || var->yres < HVFB_HEIGHT_MIN || - var->xres > screen_width || var->yres > screen_height || - var->bits_per_pixel != screen_depth) - return -EINVAL; - - var->xres_virtual = var->xres; - var->yres_virtual = var->yres; - - return 0; -} - -static int hvfb_set_par(struct fb_info *info) -{ - struct hv_device *hdev = device_to_hv_device(info->device); - - return synthvid_send_situ(hdev); -} - - -static inline u32 chan_to_field(u32 chan, struct fb_bitfield *bf) -{ - return ((chan & 0xffff) >> (16 - bf->length)) << bf->offset; -} - -static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green, - unsigned blue, unsigned transp, struct fb_info *info) -{ - u32 *pal = info->pseudo_palette; - - if (regno > 15) - return -EINVAL; - - pal[regno] = chan_to_field(red, &info->var.red) - | chan_to_field(green, &info->var.green) - | chan_to_field(blue, &info->var.blue) - | chan_to_field(transp, &info->var.transp); - - return 0; -} - -static int hvfb_blank(int blank, struct fb_info *info) -{ - return 1; /* get fb_blank to set the colormap to all black */ -} - -static void hvfb_ops_damage_range(struct fb_info *info, off_t off, size_t len) -{ - /* TODO: implement damage handling */ -} - -static void hvfb_ops_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, u32 height) -{ - struct hvfb_par *par = info->par; - - if (par->synchronous_fb) - synthvid_update(info, 0, 0, INT_MAX, INT_MAX); - else - hvfb_ondemand_refresh_throttle(par, x, y, width, height); -} - -/* - * fb_ops.fb_destroy is called by the last put_fb_info() call at the end - * of unregister_framebuffer() or fb_release(). Do any cleanup related to - * framebuffer here. - */ -static void hvfb_destroy(struct fb_info *info) -{ - hvfb_putmem(info); - framebuffer_release(info); -} - -/* - * TODO: GEN1 codepaths allocate from system or DMA-able memory. Fix the - * driver to use the _SYSMEM_ or _DMAMEM_ helpers in these cases. - */ -FB_GEN_DEFAULT_DEFERRED_IOMEM_OPS(hvfb_ops, - hvfb_ops_damage_range, - hvfb_ops_damage_area) - -static const struct fb_ops hvfb_ops = { - .owner = THIS_MODULE, - FB_DEFAULT_DEFERRED_OPS(hvfb_ops), - .fb_check_var = hvfb_check_var, - .fb_set_par = hvfb_set_par, - .fb_setcolreg = hvfb_setcolreg, - .fb_blank = hvfb_blank, - .fb_destroy = hvfb_destroy, -}; - -/* Get options from kernel paramenter "video=" */ -static void hvfb_get_option(struct fb_info *info) -{ - struct hvfb_par *par = info->par; - char *opt = NULL, *p; - uint x = 0, y = 0; - - if (fb_get_options(KBUILD_MODNAME, &opt) || !opt || !*opt) - return; - - p = strsep(&opt, "x"); - if (!*p || kstrtouint(p, 0, &x) || - !opt || !*opt || kstrtouint(opt, 0, &y)) { - pr_err("Screen option is invalid: skipped\n"); - return; - } - - if (x < HVFB_WIDTH_MIN || y < HVFB_HEIGHT_MIN || - (synthvid_ver_ge(par->synthvid_version, SYNTHVID_VERSION_WIN10) && - (x * y * screen_depth / 8 > screen_fb_size)) || - (par->synthvid_version == SYNTHVID_VERSION_WIN8 && - x * y * screen_depth / 8 > SYNTHVID_FB_SIZE_WIN8)) { - pr_err("Screen resolution option is out of range: skipped\n"); - return; - } - - screen_width = x; - screen_height = y; - return; -} - -/* - * Allocate enough contiguous physical memory. - * Return physical address if succeeded or -1 if failed. - */ -static phys_addr_t hvfb_get_phymem(struct hv_device *hdev, - unsigned int request_size) -{ - struct page *page = NULL; - dma_addr_t dma_handle; - void *vmem; - phys_addr_t paddr = 0; - unsigned int order = get_order(request_size); - - if (request_size == 0) - return -1; - - if (order <= MAX_PAGE_ORDER) { - /* Call alloc_pages if the size is less than 2^MAX_PAGE_ORDER */ - page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); - if (!page) - return -1; - - paddr = (page_to_pfn(page) << PAGE_SHIFT); - } else { - /* Allocate from CMA */ - hdev->device.coherent_dma_mask = DMA_BIT_MASK(64); - - vmem = dma_alloc_coherent(&hdev->device, - round_up(request_size, PAGE_SIZE), - &dma_handle, - GFP_KERNEL | __GFP_NOWARN); - - if (!vmem) - return -1; - - paddr = virt_to_phys(vmem); - } - - return paddr; -} - -/* Release contiguous physical memory */ -static void hvfb_release_phymem(struct device *device, - phys_addr_t paddr, unsigned int size) -{ - unsigned int order = get_order(size); - - if (order <= MAX_PAGE_ORDER) - __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order); - else - dma_free_coherent(device, - round_up(size, PAGE_SIZE), - phys_to_virt(paddr), - paddr); -} - - -/* Get framebuffer memory from Hyper-V video pci space */ -static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info) -{ - struct hvfb_par *par = info->par; - struct pci_dev *pdev = NULL; - void __iomem *fb_virt; - int gen2vm = efi_enabled(EFI_BOOT); - resource_size_t base = 0; - resource_size_t size = 0; - phys_addr_t paddr; - int ret; - - if (!gen2vm) { - pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, - PCI_DEVICE_ID_HYPERV_VIDEO, NULL); - if (!pdev) { - pr_err("Unable to find PCI Hyper-V video\n"); - return -ENODEV; - } - - base = pci_resource_start(pdev, 0); - size = pci_resource_len(pdev, 0); - aperture_remove_conflicting_devices(base, size, KBUILD_MODNAME); - - /* - * For Gen 1 VM, we can directly use the contiguous memory - * from VM. If we succeed, deferred IO happens directly - * on this allocated framebuffer memory, avoiding extra - * memory copy. - */ - paddr = hvfb_get_phymem(hdev, screen_fb_size); - if (paddr != (phys_addr_t) -1) { - par->mmio_pp = paddr; - par->mmio_vp = par->dio_vp = __va(paddr); - - info->fix.smem_start = paddr; - info->fix.smem_len = screen_fb_size; - info->screen_base = par->mmio_vp; - info->screen_size = screen_fb_size; - - par->need_docopy = false; - goto getmem_done; - } - pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n"); - } else { - aperture_remove_all_conflicting_devices(KBUILD_MODNAME); - } - - /* - * Cannot use contiguous physical memory, so allocate MMIO space for - * the framebuffer. At this point in the function, conflicting devices - * that might have claimed the framebuffer MMIO space based on - * screen_info.lfb_base must have already been removed so that - * vmbus_allocate_mmio() does not allocate different MMIO space. If the - * kdump image were to be loaded using kexec_file_load(), the - * framebuffer location in the kdump image would be set from - * screen_info.lfb_base at the time that kdump is enabled. If the - * framebuffer has moved elsewhere, this could be the wrong location, - * causing kdump to hang when efifb (for example) loads. - */ - dio_fb_size = - screen_width * screen_height * screen_depth / 8; - - ret = vmbus_allocate_mmio(&par->mem, hdev, 0, -1, - screen_fb_size, 0x100000, true); - if (ret != 0) { - pr_err("Unable to allocate framebuffer memory\n"); - goto err1; - } - - /* - * Map the VRAM cacheable for performance. This is also required for - * VM Connect to display properly for ARM64 Linux VM, as the host also - * maps the VRAM cacheable. - */ - fb_virt = ioremap_cache(par->mem->start, screen_fb_size); - if (!fb_virt) - goto err2; - - /* Allocate memory for deferred IO */ - par->dio_vp = vzalloc(round_up(dio_fb_size, PAGE_SIZE)); - if (par->dio_vp == NULL) - goto err3; - - /* Physical address of FB device */ - par->mmio_pp = par->mem->start; - /* Virtual address of FB device */ - par->mmio_vp = (unsigned char *) fb_virt; - - info->fix.smem_start = par->mem->start; - info->fix.smem_len = dio_fb_size; - info->screen_base = par->dio_vp; - info->screen_size = dio_fb_size; - -getmem_done: - if (!gen2vm) - pci_dev_put(pdev); - - return 0; - -err3: - iounmap(fb_virt); -err2: - vmbus_free_mmio(par->mem->start, screen_fb_size); - par->mem = NULL; -err1: - if (!gen2vm) - pci_dev_put(pdev); - - return -ENOMEM; -} - -/* Release the framebuffer */ -static void hvfb_putmem(struct fb_info *info) -{ - struct hvfb_par *par = info->par; - - if (par->need_docopy) { - vfree(par->dio_vp); - iounmap(par->mmio_vp); - vmbus_free_mmio(par->mem->start, screen_fb_size); - } else { - hvfb_release_phymem(info->device, info->fix.smem_start, - screen_fb_size); - } - - par->mem = NULL; -} - - -static int hvfb_probe(struct hv_device *hdev, - const struct hv_vmbus_device_id *dev_id) -{ - struct fb_info *info; - struct hvfb_par *par; - int ret; - - info = framebuffer_alloc(sizeof(struct hvfb_par), &hdev->device); - if (!info) - return -ENOMEM; - - par = info->par; - par->info = info; - par->fb_ready = false; - par->need_docopy = true; - init_completion(&par->wait); - INIT_DELAYED_WORK(&par->dwork, hvfb_update_work); - - par->delayed_refresh = false; - spin_lock_init(&par->delayed_refresh_lock); - par->x1 = par->y1 = INT_MAX; - par->x2 = par->y2 = 0; - - /* Connect to VSP */ - hv_set_drvdata(hdev, info); - ret = synthvid_connect_vsp(hdev); - if (ret) { - pr_err("Unable to connect to VSP\n"); - goto error1; - } - - hvfb_get_option(info); - pr_info("Screen resolution: %dx%d, Color depth: %d, Frame buffer size: %d\n", - screen_width, screen_height, screen_depth, screen_fb_size); - - ret = hvfb_getmem(hdev, info); - if (ret) { - pr_err("No memory for framebuffer\n"); - goto error2; - } - - /* Set up fb_info */ - info->var.xres_virtual = info->var.xres = screen_width; - info->var.yres_virtual = info->var.yres = screen_height; - info->var.bits_per_pixel = screen_depth; - - if (info->var.bits_per_pixel == 16) { - info->var.red = (struct fb_bitfield){11, 5, 0}; - info->var.green = (struct fb_bitfield){5, 6, 0}; - info->var.blue = (struct fb_bitfield){0, 5, 0}; - info->var.transp = (struct fb_bitfield){0, 0, 0}; - } else { - info->var.red = (struct fb_bitfield){16, 8, 0}; - info->var.green = (struct fb_bitfield){8, 8, 0}; - info->var.blue = (struct fb_bitfield){0, 8, 0}; - info->var.transp = (struct fb_bitfield){24, 8, 0}; - } - - info->var.activate = FB_ACTIVATE_NOW; - info->var.height = -1; - info->var.width = -1; - info->var.vmode = FB_VMODE_NONINTERLACED; - - strcpy(info->fix.id, KBUILD_MODNAME); - info->fix.type = FB_TYPE_PACKED_PIXELS; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.line_length = screen_width * screen_depth / 8; - info->fix.accel = FB_ACCEL_NONE; - - info->fbops = &hvfb_ops; - info->pseudo_palette = par->pseudo_palette; - - /* Initialize deferred IO */ - info->fbdefio = &synthvid_defio; - fb_deferred_io_init(info); - - /* Send config to host */ - ret = synthvid_send_config(hdev); - if (ret) - goto error; - - ret = devm_register_framebuffer(&hdev->device, info); - if (ret) { - pr_err("Unable to register framebuffer\n"); - goto error; - } - - par->fb_ready = true; - - par->synchronous_fb = false; - - /* - * We need to be sure this panic notifier runs _before_ the - * vmbus disconnect, so order it by priority. It must execute - * before the function hv_panic_vmbus_unload() [drivers/hv/vmbus_drv.c], - * which is almost at the end of list, with priority = INT_MIN + 1. - */ - par->hvfb_panic_nb.notifier_call = hvfb_on_panic; - par->hvfb_panic_nb.priority = INT_MIN + 10; - atomic_notifier_chain_register(&panic_notifier_list, - &par->hvfb_panic_nb); - - return 0; - -error: - fb_deferred_io_cleanup(info); - hvfb_putmem(info); -error2: - vmbus_close(hdev->channel); -error1: - cancel_delayed_work_sync(&par->dwork); - hv_set_drvdata(hdev, NULL); - framebuffer_release(info); - return ret; -} - -static void hvfb_remove(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - - atomic_notifier_chain_unregister(&panic_notifier_list, - &par->hvfb_panic_nb); - - par->update = false; - par->fb_ready = false; - - fb_deferred_io_cleanup(info); - - cancel_delayed_work_sync(&par->dwork); - - vmbus_close(hdev->channel); - hv_set_drvdata(hdev, NULL); -} - -static int hvfb_suspend(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - - console_lock(); - - /* 1 means do suspend */ - fb_set_suspend(info, 1); - - cancel_delayed_work_sync(&par->dwork); - cancel_delayed_work_sync(&info->deferred_work); - - par->update_saved = par->update; - par->update = false; - par->fb_ready = false; - - vmbus_close(hdev->channel); - - console_unlock(); - - return 0; -} - -static int hvfb_resume(struct hv_device *hdev) -{ - struct fb_info *info = hv_get_drvdata(hdev); - struct hvfb_par *par = info->par; - int ret; - - console_lock(); - - ret = synthvid_connect_vsp(hdev); - if (ret != 0) - goto out; - - ret = synthvid_send_config(hdev); - if (ret != 0) { - vmbus_close(hdev->channel); - goto out; - } - - par->fb_ready = true; - par->update = par->update_saved; - - schedule_delayed_work(&info->deferred_work, info->fbdefio->delay); - schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY); - - /* 0 means do resume */ - fb_set_suspend(info, 0); - -out: - console_unlock(); - - return ret; -} - - -static const struct pci_device_id pci_stub_id_table[] = { - { - .vendor = PCI_VENDOR_ID_MICROSOFT, - .device = PCI_DEVICE_ID_HYPERV_VIDEO, - }, - { /* end of list */ } -}; - -static const struct hv_vmbus_device_id id_table[] = { - /* Synthetic Video Device GUID */ - {HV_SYNTHVID_GUID}, - {} -}; - -MODULE_DEVICE_TABLE(pci, pci_stub_id_table); -MODULE_DEVICE_TABLE(vmbus, id_table); - -static struct hv_driver hvfb_drv = { - .name = KBUILD_MODNAME, - .id_table = id_table, - .probe = hvfb_probe, - .remove = hvfb_remove, - .suspend = hvfb_suspend, - .resume = hvfb_resume, - .driver = { - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - }, -}; - -static int hvfb_pci_stub_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - return 0; -} - -static void hvfb_pci_stub_remove(struct pci_dev *pdev) -{ -} - -static struct pci_driver hvfb_pci_stub_driver = { - .name = KBUILD_MODNAME, - .id_table = pci_stub_id_table, - .probe = hvfb_pci_stub_probe, - .remove = hvfb_pci_stub_remove, - .driver = { - .probe_type = PROBE_PREFER_ASYNCHRONOUS, - } -}; - -static int __init hvfb_drv_init(void) -{ - int ret; - - pr_warn("Deprecated: use Hyper-V DRM driver instead\n"); - - if (fb_modesetting_disabled("hyper_fb")) - return -ENODEV; - - ret = vmbus_driver_register(&hvfb_drv); - if (ret != 0) - return ret; - - ret = pci_register_driver(&hvfb_pci_stub_driver); - if (ret != 0) { - vmbus_driver_unregister(&hvfb_drv); - return ret; - } - - return 0; -} - -static void __exit hvfb_drv_exit(void) -{ - pci_unregister_driver(&hvfb_pci_stub_driver); - vmbus_driver_unregister(&hvfb_drv); -} - -module_init(hvfb_drv_init); -module_exit(hvfb_drv_exit); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Video Frame Buffer Driver"); diff --git a/drivers/video/fbdev/matrox/i2c-matroxfb.c b/drivers/video/fbdev/matrox/i2c-matroxfb.c index bb048e14b2cf..e02dd11b090e 100644 --- a/drivers/video/fbdev/matrox/i2c-matroxfb.c +++ b/drivers/video/fbdev/matrox/i2c-matroxfb.c @@ -144,7 +144,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) { unsigned long flags; struct matroxfb_dh_maven_info* m2info; - m2info = kzalloc(sizeof(*m2info), GFP_KERNEL); + m2info = kzalloc_obj(*m2info); if (!m2info) return NULL; diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index 5be0cdcd7c71..e1a4bc7c2318 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -2073,7 +2073,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm return -1; } - minfo = kzalloc(sizeof(*minfo), GFP_KERNEL); + minfo = kzalloc_obj(*minfo); if (!minfo) return -ENOMEM; diff --git a/drivers/video/fbdev/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c index 417fc692468d..8de882b09a24 100644 --- a/drivers/video/fbdev/matrox/matroxfb_crtc2.c +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.c @@ -693,7 +693,7 @@ static void* matroxfb_crtc2_probe(struct matrox_fb_info* minfo) { /* hardware is CRTC2 incapable... */ if (!minfo->devflags.crtc2) return NULL; - m2info = kzalloc(sizeof(*m2info), GFP_KERNEL); + m2info = kzalloc_obj(*m2info); if (!m2info) return NULL; diff --git a/drivers/video/fbdev/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c index dcfae770b42d..2ea65da6075c 100644 --- a/drivers/video/fbdev/matrox/matroxfb_maven.c +++ b/drivers/video/fbdev/matrox/matroxfb_maven.c @@ -1260,7 +1260,7 @@ static int maven_probe(struct i2c_client *client) I2C_FUNC_NOSTART | I2C_FUNC_PROTOCOL_MANGLING)) goto ERROR0; - if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) { + if (!(data = kzalloc_obj(*data))) { err = -ENOMEM; goto ERROR0; } diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c index 03707461eced..3c35b0a3ea09 100644 --- a/drivers/video/fbdev/mmp/core.c +++ b/drivers/video/fbdev/mmp/core.c @@ -155,8 +155,7 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info) struct mmp_path *path = NULL; struct mmp_panel *panel; - path = kzalloc(struct_size(path, overlays, info->overlay_num), - GFP_KERNEL); + path = kzalloc_flex(*path, overlays, info->overlay_num); if (!path) return NULL; diff --git a/drivers/video/fbdev/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c index 2d9797c6fb3e..694587256e06 100644 --- a/drivers/video/fbdev/mmp/fb/mmpfb.c +++ b/drivers/video/fbdev/mmp/fb/mmpfb.c @@ -476,8 +476,7 @@ static int modes_setup(struct mmpfb_info *fbi) return 0; } /* put videomode list to info structure */ - videomodes = kcalloc(videomode_num, sizeof(struct fb_videomode), - GFP_KERNEL); + videomodes = kzalloc_objs(struct fb_videomode, videomode_num); if (!videomodes) return -ENOMEM; diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c index 03e23173198c..75bbdc0b4aa6 100644 --- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c +++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c @@ -402,7 +402,7 @@ static int path_init(struct mmphw_path_plat *path_plat, dev_info(ctrl->dev, "%s: %s\n", __func__, config->name); /* init driver data */ - path_info = kzalloc(sizeof(*path_info), GFP_KERNEL); + path_info = kzalloc_obj(*path_info); if (!path_info) return 0; diff --git a/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c index 34fae588e202..d111ec2a4703 100644 --- a/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c +++ b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c @@ -144,7 +144,7 @@ static int tpohvga_probe(struct spi_device *spi) return ret; } - plat_data = kzalloc(sizeof(*plat_data), GFP_KERNEL); + plat_data = kzalloc_obj(*plat_data); if (plat_data == NULL) return -ENOMEM; diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index 632ba2455913..c1cd028b8991 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -1768,7 +1768,7 @@ static int neo_scan_monitor(struct fb_info *info) int w; // Eventually we will have i2c support. - info->monspecs.modedb = kmalloc(sizeof(struct fb_videomode), GFP_KERNEL); + info->monspecs.modedb = kmalloc_obj(struct fb_videomode); if (!info->monspecs.modedb) return -ENOMEM; info->monspecs.modedb_len = 1; diff --git a/drivers/video/fbdev/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c index 5404017e6957..281c7f2ee650 100644 --- a/drivers/video/fbdev/nvidia/nv_setup.c +++ b/drivers/video/fbdev/nvidia/nv_setup.c @@ -283,9 +283,9 @@ int NVCommonSetup(struct fb_info *info) int Television = 0; int err = 0; - var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); - monitorA = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); - monitorB = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); + var = kzalloc_obj(struct fb_var_screeninfo); + monitorA = kzalloc_obj(struct fb_monspecs); + monitorB = kzalloc_obj(struct fb_monspecs); if (!var || !monitorA || !monitorB) { err = -ENOMEM; diff --git a/drivers/video/fbdev/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index a0fc4570403b..72c2a56943c2 100644 --- a/drivers/video/fbdev/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c @@ -552,7 +552,7 @@ static int mipid_spi_probe(struct spi_device *spi) struct mipid_device *md; int r; - md = kzalloc(sizeof(*md), GFP_KERNEL); + md = kzalloc_obj(*md); if (md == NULL) { dev_err(&spi->dev, "out of memory\n"); return -ENOMEM; diff --git a/drivers/video/fbdev/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c index 106d21e74738..cafe859d6e5a 100644 --- a/drivers/video/fbdev/omap/omapfb_main.c +++ b/drivers/video/fbdev/omap/omapfb_main.c @@ -846,12 +846,10 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi) * be reenabled unless its size is > 0. */ if (old_size != size && size) { - if (size) { - memcpy(new_var, &fbi->var, sizeof(*new_var)); - r = set_fb_var(fbi, new_var); - if (r < 0) - goto out; - } + memcpy(new_var, &fbi->var, sizeof(*new_var)); + r = set_fb_var(fbi, new_var); + if (r < 0) + goto out; } if (fbdev->ctrl->sync) @@ -1632,7 +1630,7 @@ static int omapfb_do_probe(struct platform_device *pdev, goto cleanup; } - fbdev = kzalloc(sizeof(*fbdev), GFP_KERNEL); + fbdev = kzalloc_obj(*fbdev); if (fbdev == NULL) { dev_err(&pdev->dev, "unable to allocate memory for device info\n"); diff --git a/drivers/video/fbdev/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig index f4cdf999a080..2d20e79adefc 100644 --- a/drivers/video/fbdev/omap2/omapfb/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/Kconfig @@ -5,7 +5,6 @@ config OMAP2_VRFB menuconfig FB_OMAP2 tristate "OMAP2+ frame buffer support" depends on FB - depends on FB_DEVICE depends on DRM_OMAP = n depends on GPIOLIB select FB_OMAP2_DSS @@ -13,6 +12,8 @@ menuconfig FB_OMAP2 select FB_IOMEM_HELPERS help Frame buffer driver for OMAP2+ based boards. + FB_DEVICE is not required, but if enabled, provides sysfs interface + for framebuffer configuration and debugging. if FB_OMAP2 diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c index 370e8623754e..330d9fb7d2b0 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c @@ -1539,7 +1539,7 @@ static void dsi_dump_dsidev_irqs(struct platform_device *dsidev, unsigned long flags; struct dsi_irq_stats *stats; - stats = kzalloc(sizeof(*stats), GFP_KERNEL); + stats = kzalloc_obj(*stats); if (!stats) { seq_printf(s, "out of memory\n"); return; diff --git a/drivers/video/fbdev/omap2/omapfb/dss/manager.c b/drivers/video/fbdev/omap2/omapfb/dss/manager.c index c59e5689d6cc..c81fe5e68e42 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/manager.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/manager.c @@ -32,8 +32,7 @@ int dss_init_overlay_managers(void) num_managers = dss_feat_get_num_mgrs(); - managers = kcalloc(num_managers, sizeof(struct omap_overlay_manager), - GFP_KERNEL); + managers = kzalloc_objs(struct omap_overlay_manager, num_managers); BUG_ON(managers == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c index d80720c84323..154347e5ddaf 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/omapdss-boot-init.c @@ -46,7 +46,7 @@ static void __init omapdss_update_prop(struct device_node *node, char *compat, { struct property *prop; - prop = kzalloc(sizeof(*prop), GFP_KERNEL); + prop = kzalloc_obj(*prop); if (!prop) return; @@ -110,8 +110,7 @@ static void __init omapdss_omapify_node(struct device_node *node) static void __init omapdss_add_to_list(struct device_node *node, bool root) { - struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node), - GFP_KERNEL); + struct dss_conv_node *n = kmalloc_obj(struct dss_conv_node); if (n) { n->node = node; n->root = root; diff --git a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c index bbbdc233ee61..6b04162aa9fc 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/overlay.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/overlay.c @@ -49,8 +49,7 @@ void dss_init_overlays(struct platform_device *pdev) num_overlays = dss_feat_get_num_ovls(); - overlays = kcalloc(num_overlays, sizeof(struct omap_overlay), - GFP_KERNEL); + overlays = kzalloc_objs(struct omap_overlay, num_overlays); BUG_ON(overlays == NULL); diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index 211f23648686..a8b2930290e1 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -2023,19 +2023,19 @@ static int omapfb_mode_to_timings(const char *mode_str, var = NULL; fbops = NULL; - fbi = kzalloc(sizeof(*fbi), GFP_KERNEL); + fbi = kzalloc_obj(*fbi); if (fbi == NULL) { r = -ENOMEM; goto err; } - var = kzalloc(sizeof(*var), GFP_KERNEL); + var = kzalloc_obj(*var); if (var == NULL) { r = -ENOMEM; goto err; } - fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); + fbops = kzalloc_obj(*fbops); if (fbops == NULL) { r = -ENOMEM; goto err; @@ -2244,7 +2244,7 @@ static int omapfb_find_best_mode(struct omap_dss_device *display, if (r < 0) goto err1; - specs = kzalloc(sizeof(*specs), GFP_KERNEL); + specs = kzalloc_obj(*specs); if (specs == NULL) { r = -ENOMEM; goto err1; diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c index 831b2c2fbdf9..38a635d38d58 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c @@ -558,10 +558,15 @@ int omapfb_create_sysfs(struct omapfb2_device *fbdev) DBG("create sysfs for fbs\n"); for (i = 0; i < fbdev->num_fbs; i++) { + struct device *dev; int t; + + dev = dev_of_fbinfo(fbdev->fbs[i]); + if (!dev) + continue; + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) { - r = device_create_file(fbdev->fbs[i]->dev, - &omapfb_attrs[t]); + r = device_create_file(dev, &omapfb_attrs[t]); if (r) { dev_err(fbdev->dev, "failed to create sysfs " @@ -580,9 +585,14 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev) DBG("remove sysfs for fbs\n"); for (i = 0; i < fbdev->num_fbs; i++) { + struct device *dev; + + dev = dev_of_fbinfo(fbdev->fbs[i]); + if (!dev) + continue; + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) - device_remove_file(fbdev->fbs[i]->dev, - &omapfb_attrs[t]); + device_remove_file(dev, &omapfb_attrs[t]); } } diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 0b8d23c12b77..3f6384e631b1 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -652,7 +652,7 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf, nr_pages = (count + PAGE_SIZE - 1) >> PAGE_SHIFT; - pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, nr_pages); if (!pages) return -ENOMEM; diff --git a/drivers/video/fbdev/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c index 4a78b387b343..a2320e2fb8f2 100644 --- a/drivers/video/fbdev/pxa3xx-gcu.c +++ b/drivers/video/fbdev/pxa3xx-gcu.c @@ -530,7 +530,7 @@ pxa3xx_gcu_add_buffer(struct device *dev, { struct pxa3xx_gcu_batch *buffer; - buffer = kzalloc(sizeof(struct pxa3xx_gcu_batch), GFP_KERNEL); + buffer = kzalloc_obj(struct pxa3xx_gcu_batch); if (!buffer) return -ENOMEM; diff --git a/drivers/video/fbdev/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index 8b829b720064..f292079566cf 100644 --- a/drivers/video/fbdev/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c @@ -436,6 +436,9 @@ static char nv3_arb(nv3_fifo_info * res_info, nv3_sim_state * state, nv3_arb_in vmisses = 2; eburst_size = state->memory_width * 1; mburst_size = 32; + if (!state->mclk_khz) + return (0); + gns = 1000000 * (gmisses*state->mem_page_miss + state->mem_latency)/state->mclk_khz; ainfo->by_gfacc = gns*ainfo->gdrain_rate/1000000; ainfo->wcmocc = 0; diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index dd950e4ab5ce..72969fe8e513 100644 --- a/drivers/video/fbdev/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -1343,14 +1343,17 @@ static DEVICE_ATTR_RW(overlay_mode); static DEVICE_ATTR_RW(overlay_position); static DEVICE_ATTR_RW(overlay_rop3); -static struct attribute *overlay_sysfs_attrs[] = { +static struct attribute *overlay_sysfs_attrs[] __maybe_unused = { &dev_attr_overlay_alpha.attr, &dev_attr_overlay_mode.attr, &dev_attr_overlay_position.attr, &dev_attr_overlay_rop3.attr, NULL, }; + +#ifdef CONFIG_FB_DEVICE ATTRIBUTE_GROUPS(overlay_sysfs); +#endif static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = { .id = "SH Mobile LCDC", @@ -2509,7 +2512,7 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev) return -ENOENT; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c index 92595af022eb..60e5dcec201f 100644 --- a/drivers/video/fbdev/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -249,7 +249,7 @@ static int simplefb_clocks_get(struct simplefb_par *par, if (!par->clk_count) return 0; - par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL); + par->clks = kzalloc_objs(struct clk *, par->clk_count); if (!par->clks) return -ENOMEM; diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index ed6f4f43e2d5..fee4b9f84592 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1947,7 +1947,7 @@ static int sm501fb_probe(struct platform_device *pdev) int ret; /* allocate our framebuffers */ - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { dev_err(dev, "failed to allocate state\n"); return -ENOMEM; diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c index 5f0dd01fd834..5704f60e1741 100644 --- a/drivers/video/fbdev/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -932,7 +932,6 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { struct ufx_data *dev = info->par; - struct dloarea *area = NULL; if (!atomic_read(&dev->usb_active)) return 0; @@ -947,6 +946,10 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, /* TODO: Help propose a standard fb.h ioctl to report mmap damage */ if (cmd == UFX_IOCTL_REPORT_DAMAGE) { + struct dloarea *area __free(kfree) = kmalloc_obj(*area); + if (!area) + return -ENOMEM; + /* If we have a damage-aware client, turn fb_defio "off" * To avoid perf imact of unnecessary page fault handling. * Done by resetting the delay for this fb_info to a very @@ -956,7 +959,8 @@ static int ufx_ops_ioctl(struct fb_info *info, unsigned int cmd, if (info->fbdefio) info->fbdefio->delay = UFX_DEFIO_WRITE_DISABLE; - area = (struct dloarea *)arg; + if (copy_from_user(area, (u8 __user *)arg, sizeof(*area))) + return -EFAULT; if (area->x < 0) area->x = 0; @@ -1033,7 +1037,7 @@ static int ufx_ops_open(struct fb_info *info, int user) struct fb_deferred_io *fbdefio; - fbdefio = kzalloc(sizeof(*fbdefio), GFP_KERNEL); + fbdefio = kzalloc_obj(*fbdefio); if (fbdefio) { fbdefio->delay = UFX_DEFIO_WRITE_DELAY; fbdefio->deferred_io = ufx_dpy_deferred_io; @@ -1590,7 +1594,7 @@ static int ufx_usb_probe(struct usb_interface *interface, usbdev = interface_to_usbdev(interface); BUG_ON(!usbdev); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) { dev_err(&usbdev->dev, "ufx_usb_probe: failed alloc of dev struct\n"); return -ENOMEM; @@ -1847,7 +1851,7 @@ static int ufx_alloc_urb_list(struct ufx_data *dev, int count, size_t size) INIT_LIST_HEAD(&dev->urbs.list); while (i < count) { - unode = kzalloc(sizeof(*unode), GFP_KERNEL); + unode = kzalloc_obj(*unode); if (!unode) break; unode->dev = dev; diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c index ccede85df1e1..3c6a9b5758d9 100644 --- a/drivers/video/fbdev/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -918,7 +918,7 @@ static int dlfb_ops_open(struct fb_info *info, int user) struct fb_deferred_io *fbdefio; - fbdefio = kzalloc(sizeof(struct fb_deferred_io), GFP_KERNEL); + fbdefio = kzalloc_obj(struct fb_deferred_io); if (fbdefio) { fbdefio->delay = DL_DEFIO_WRITE_DELAY; @@ -1164,7 +1164,7 @@ static const struct fb_ops dlfb_ops = { static void dlfb_deferred_vfree(struct dlfb_data *dlfb, void *mem) { - struct dlfb_deferred_free *d = kmalloc(sizeof(struct dlfb_deferred_free), GFP_KERNEL); + struct dlfb_deferred_free *d = kmalloc_obj(struct dlfb_deferred_free); if (!d) return; d->mem = mem; @@ -1606,7 +1606,7 @@ static int dlfb_usb_probe(struct usb_interface *intf, static u8 out_ep[] = {OUT_EP_NUM + USB_DIR_OUT, 0}; /* usb initialization */ - dlfb = kzalloc(sizeof(*dlfb), GFP_KERNEL); + dlfb = kzalloc_obj(*dlfb); if (!dlfb) { dev_err(&intf->dev, "%s: failed to allocate dlfb\n", __func__); return -ENOMEM; @@ -1852,7 +1852,7 @@ static int dlfb_alloc_urb_list(struct dlfb_data *dlfb, int count, size_t size) dlfb->urbs.available = 0; while (dlfb->urbs.count * size < wanted_size) { - unode = kzalloc(sizeof(*unode), GFP_KERNEL); + unode = kzalloc_obj(*unode); if (!unode) break; unode->dlfb = dlfb; diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c index 5d52fd00806e..88667fccc27b 100644 --- a/drivers/video/fbdev/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -258,9 +258,9 @@ static struct uvesafb_ktask *uvesafb_prep(void) { struct uvesafb_ktask *task; - task = kzalloc(sizeof(*task), GFP_KERNEL); + task = kzalloc_obj(*task); if (task) { - task->done = kzalloc(sizeof(*task->done), GFP_KERNEL); + task->done = kzalloc_obj(*task->done); if (!task->done) { kfree(task); task = NULL; @@ -487,9 +487,7 @@ static int uvesafb_vbe_getmodes(struct uvesafb_ktask *task, mode++; } - par->vbe_modes = kcalloc(par->vbe_modes_cnt, - sizeof(struct vbe_mode_ib), - GFP_KERNEL); + par->vbe_modes = kzalloc_objs(struct vbe_mode_ib, par->vbe_modes_cnt); if (!par->vbe_modes) return -ENOMEM; @@ -862,7 +860,7 @@ static int uvesafb_vbe_init_mode(struct fb_info *info) * Convert the modelist into a modedb so that we can use it with * fb_find_mode(). */ - mode = kcalloc(i, sizeof(*mode), GFP_KERNEL); + mode = kzalloc_objs(*mode, i); if (mode) { i = 0; list_for_each(pos, &info->modelist) { @@ -1048,8 +1046,7 @@ static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info) info->cmap.len || cmap->start < info->cmap.start) return -EINVAL; - entries = kmalloc_array(cmap->len, sizeof(*entries), - GFP_KERNEL); + entries = kmalloc_objs(*entries, cmap->len); if (!entries) return -ENOMEM; @@ -1243,7 +1240,7 @@ static int uvesafb_set_par(struct fb_info *info) info->var.pixclock != 0) { task->t.regs.ebx |= 0x0800; /* use CRTC data */ task->t.flags = TF_BUF_ESDI; - crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL); + crtc = kzalloc_obj(struct vbe_crtc_ib); if (!crtc) { err = -ENOMEM; goto out; diff --git a/drivers/video/fbdev/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c index 6ff059ee1694..ec3cf4589056 100644 --- a/drivers/video/fbdev/valkyriefb.c +++ b/drivers/video/fbdev/valkyriefb.c @@ -339,7 +339,7 @@ static int __init valkyriefb_init(void) } #endif /* ppc (!CONFIG_MAC) */ - p = kzalloc(sizeof(*p), GFP_ATOMIC); + p = kzalloc_obj(*p, GFP_ATOMIC); if (!p) return -ENOMEM; diff --git a/drivers/video/fbdev/via/via_aux.c b/drivers/video/fbdev/via/via_aux.c index 902191dddbeb..47f88a2c4524 100644 --- a/drivers/video/fbdev/via/via_aux.c +++ b/drivers/video/fbdev/via/via_aux.c @@ -17,7 +17,7 @@ struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap) if (!adap) return NULL; - bus = kmalloc(sizeof(*bus), GFP_KERNEL); + bus = kmalloc_obj(*bus); if (!bus) return NULL; diff --git a/drivers/video/fbdev/via/via_aux.h b/drivers/video/fbdev/via/via_aux.h index 464723fd514c..6453d6a4fb4e 100644 --- a/drivers/video/fbdev/via/via_aux.h +++ b/drivers/video/fbdev/via/via_aux.h @@ -42,7 +42,7 @@ const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus); static inline bool via_aux_add(struct via_aux_drv *drv) { - struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL); + struct via_aux_drv *data = kmalloc_obj(*data); if (!data) return false; diff --git a/drivers/video/fbdev/via/via_aux_edid.c b/drivers/video/fbdev/via/via_aux_edid.c index 9791381a9865..c4abfb1bcf52 100644 --- a/drivers/video/fbdev/via/via_aux_edid.c +++ b/drivers/video/fbdev/via/via_aux_edid.c @@ -24,7 +24,7 @@ static void query_edid(struct via_aux_drv *drv) if (spec) { fb_destroy_modedb(spec->modedb); } else { - spec = kmalloc(sizeof(*spec), GFP_KERNEL); + spec = kmalloc_obj(*spec); if (!spec) return; } diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 6da5ae7d229a..80f95dac32c8 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -840,7 +840,7 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) struct { u8 data[CURSOR_SIZE]; u32 bak[CURSOR_SIZE / 4]; - } *cr_data = kzalloc(sizeof(*cr_data), GFP_ATOMIC); + } *cr_data = kzalloc_obj(*cr_data, GFP_ATOMIC); int size = ((cursor->image.width + 7) >> 3) * cursor->image.height; diff --git a/drivers/video/fbdev/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index b08a6fdc53fd..85c7a99a7d64 100644 --- a/drivers/video/fbdev/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -369,7 +369,7 @@ static int vt8500lcd_probe(struct platform_device *pdev) if (fbi->palette_cpu == NULL) { dev_err(&pdev->dev, "Failed to allocate palette buffer\n"); ret = -ENOMEM; - goto failed_free_io; + goto failed_free_mem_virt; } irq = platform_get_irq(pdev, 0); @@ -432,6 +432,9 @@ static int vt8500lcd_probe(struct platform_device *pdev) failed_free_palette: dma_free_coherent(&pdev->dev, fbi->palette_size, fbi->palette_cpu, fbi->palette_phys); +failed_free_mem_virt: + dma_free_coherent(&pdev->dev, fbi->fb.fix.smem_len, + fbi->fb.screen_buffer, fbi->fb.fix.smem_start); failed_free_io: iounmap(fbi->regbase); failed_free_res: diff --git a/drivers/video/fbdev/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index d8f3bfb2dd6c..4385976277ac 100644 --- a/drivers/video/fbdev/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -348,7 +348,7 @@ static int xenfb_probe(struct xenbus_device *dev, int val; int ret = 0; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info == NULL) { xenbus_dev_fatal(dev, -ENOMEM, "allocating info structure"); return -ENOMEM; diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index ce6bb753522d..cda15b95891e 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig @@ -20,54 +20,60 @@ config FB_LOGO_EXTRA config LOGO_LINUX_MONO bool "Standard black and white Linux logo" - default y + +config LOGO_LINUX_MONO_FILE + string "Monochrome logo .pbm file" + depends on LOGO_LINUX_MONO + default "drivers/video/logo/logo_superh_mono.pbm" if SUPERH + default "drivers/video/logo/logo_linux_mono.pbm" + help + Takes a path to a monochromatic logo in the portable pixmap file + format (.pbm). This defaults to the Tux penguin. + + For example, the below ImageMagick command can be used to reduce + an image to black and white and convert it into a pbm file: + + magick source_image -compress none destination.pbm config LOGO_LINUX_VGA16 bool "Standard 16-color Linux logo" - default y + +config LOGO_LINUX_VGA16_FILE + string "16-color logo .ppm file" + depends on LOGO_LINUX_VGA16 + default "drivers/video/logo/logo_superh_vga16.ppm" if SUPERH + default "drivers/video/logo/logo_linux_vga16.ppm" + help + Takes a path to a logo in the portable pixmap file format (.ppm), + using the 16 colors from the drivers/video/logo/clut_vga16.ppm + palette. This defaults to the Tux penguin. + + For example, the below ImageMagick command can be used to reduce an + image to the VGA 16 colors palette and convert into a ppm file: + + magick source_image -compress none \ + -remap drivers/video/logo/clut_vga16.ppm destination.ppm config LOGO_LINUX_CLUT224 bool "Standard 224-color Linux logo" default y -config LOGO_DEC_CLUT224 - bool "224-color Digital Equipment Corporation Linux logo" - depends on MACH_DECSTATION || ALPHA - default y +config LOGO_LINUX_CLUT224_FILE + string "224-color logo .ppm file" + depends on LOGO_LINUX_CLUT224 + default "drivers/video/logo/logo_dec_clut224.ppm" if MACH_DECSTATION || ALPHA + default "drivers/video/logo/logo_parisc_clut224.ppm" if PARISC + default "drivers/video/logo/logo_sgi_clut224.ppm" if SGI_IP22 || SGI_IP27 || SGI_IP32 + default "drivers/video/logo/logo_sun_clut224.ppm" if SPARC + default "drivers/video/logo/logo_superh_clut224.ppm" if SUPERH + default "drivers/video/logo/logo_linux_clut224.ppm" + help + Takes a path to a 224-color logo in the portable pixmap file + format (.ppm). This defaults to the Tux penguin. -config LOGO_MAC_CLUT224 - bool "224-color Macintosh Linux logo" - depends on MAC - default y + For example, the below ImageMagick command can be used to reduce + an image palette to 224 colors and convert it into a ppm file: -config LOGO_PARISC_CLUT224 - bool "224-color PA-RISC Linux logo" - depends on PARISC - default y - -config LOGO_SGI_CLUT224 - bool "224-color SGI Linux logo" - depends on SGI_IP22 || SGI_IP27 || SGI_IP32 - default y - -config LOGO_SUN_CLUT224 - bool "224-color Sun Linux logo" - depends on SPARC - default y - -config LOGO_SUPERH_MONO - bool "Black and white SuperH Linux logo" - depends on SUPERH - default y - -config LOGO_SUPERH_VGA16 - bool "16-color SuperH Linux logo" - depends on SUPERH - default y - -config LOGO_SUPERH_CLUT224 - bool "224-color SuperH Linux logo" - depends on SUPERH - default y + magick source_image -compress none -colors 224 destination.ppm endif # LOGO diff --git a/drivers/video/logo/Makefile b/drivers/video/logo/Makefile index 895c60b8402e..937b37d3b6c7 100644 --- a/drivers/video/logo/Makefile +++ b/drivers/video/logo/Makefile @@ -5,14 +5,6 @@ obj-$(CONFIG_LOGO) += logo.o obj-$(CONFIG_LOGO_LINUX_MONO) += logo_linux_mono.o obj-$(CONFIG_LOGO_LINUX_VGA16) += logo_linux_vga16.o obj-$(CONFIG_LOGO_LINUX_CLUT224) += logo_linux_clut224.o -obj-$(CONFIG_LOGO_DEC_CLUT224) += logo_dec_clut224.o -obj-$(CONFIG_LOGO_MAC_CLUT224) += logo_mac_clut224.o -obj-$(CONFIG_LOGO_PARISC_CLUT224) += logo_parisc_clut224.o -obj-$(CONFIG_LOGO_SGI_CLUT224) += logo_sgi_clut224.o -obj-$(CONFIG_LOGO_SUN_CLUT224) += logo_sun_clut224.o -obj-$(CONFIG_LOGO_SUPERH_MONO) += logo_superh_mono.o -obj-$(CONFIG_LOGO_SUPERH_VGA16) += logo_superh_vga16.o -obj-$(CONFIG_LOGO_SUPERH_CLUT224) += logo_superh_clut224.o obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o @@ -20,18 +12,21 @@ obj-$(CONFIG_SPU_BASE) += logo_spe_clut224.o hostprogs := pnmtologo -# Create commands like "pnmtologo -t mono -n logo_mac_mono -o ..." +# Create commands like "pnmtologo -t mono -n logo_linux_mono -o ..." quiet_cmd_logo = LOGO $@ - cmd_logo = $(obj)/pnmtologo -t $(lastword $(subst _, ,$*)) -n $* -o $@ $< + cmd_logo = $(obj)/pnmtologo -t $2 -n $(basename $(notdir $@)) -o $@ $< -$(obj)/%.c: $(src)/%.pbm $(obj)/pnmtologo FORCE - $(call if_changed,logo) +$(obj)/logo_linux_mono.c: $(CONFIG_LOGO_LINUX_MONO_FILE) $(obj)/pnmtologo FORCE + $(call if_changed,logo,mono) -$(obj)/%.c: $(src)/%.ppm $(obj)/pnmtologo FORCE - $(call if_changed,logo) +$(obj)/logo_linux_vga16.c: $(CONFIG_LOGO_LINUX_VGA16_FILE) $(obj)/pnmtologo FORCE + $(call if_changed,logo,vga16) -$(obj)/%.c: $(src)/%.pgm $(obj)/pnmtologo FORCE - $(call if_changed,logo) +$(obj)/logo_linux_clut224.c: $(CONFIG_LOGO_LINUX_CLUT224_FILE) $(obj)/pnmtologo FORCE + $(call if_changed,logo,clut224) + +$(obj)/%_clut224.c: $(src)/%_clut224.ppm $(obj)/pnmtologo FORCE + $(call if_changed,logo,clut224) # generated C files -targets += *_mono.c *_vga16.c *_clut224.c *_gray256.c +targets += *_mono.c *_vga16.c *_clut224.c diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 141f15a9a459..91535f8848da 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -48,59 +48,21 @@ const struct linux_logo * __ref fb_find_logo(int depth) if (nologo || logos_freed) return NULL; - if (depth >= 1) { #ifdef CONFIG_LOGO_LINUX_MONO - /* Generic Linux logo */ + if (depth >= 1) logo = &logo_linux_mono; #endif -#ifdef CONFIG_LOGO_SUPERH_MONO - /* SuperH Linux logo */ - logo = &logo_superh_mono; -#endif - } - if (depth >= 4) { #ifdef CONFIG_LOGO_LINUX_VGA16 - /* Generic Linux logo */ + if (depth >= 4) logo = &logo_linux_vga16; #endif -#ifdef CONFIG_LOGO_SUPERH_VGA16 - /* SuperH Linux logo */ - logo = &logo_superh_vga16; -#endif - } - if (depth >= 8) { #ifdef CONFIG_LOGO_LINUX_CLUT224 - /* Generic Linux logo */ + if (depth >= 8) logo = &logo_linux_clut224; #endif -#ifdef CONFIG_LOGO_DEC_CLUT224 - /* DEC Linux logo on MIPS/MIPS64 or ALPHA */ - logo = &logo_dec_clut224; -#endif -#ifdef CONFIG_LOGO_MAC_CLUT224 - /* Macintosh Linux logo on m68k */ - if (MACH_IS_MAC) - logo = &logo_mac_clut224; -#endif -#ifdef CONFIG_LOGO_PARISC_CLUT224 - /* PA-RISC Linux logo */ - logo = &logo_parisc_clut224; -#endif -#ifdef CONFIG_LOGO_SGI_CLUT224 - /* SGI Linux logo on MIPS/MIPS64 */ - logo = &logo_sgi_clut224; -#endif -#ifdef CONFIG_LOGO_SUN_CLUT224 - /* Sun Linux logo */ - logo = &logo_sun_clut224; -#endif -#ifdef CONFIG_LOGO_SUPERH_CLUT224 - /* SuperH Linux logo */ - logo = &logo_superh_clut224; -#endif - } + return logo; } EXPORT_SYMBOL_GPL(fb_find_logo); diff --git a/drivers/video/logo/logo_mac_clut224.ppm b/drivers/video/logo/logo_mac_clut224.ppm deleted file mode 100644 index 4dad34baea89..000000000000 --- a/drivers/video/logo/logo_mac_clut224.ppm +++ /dev/null @@ -1,1604 +0,0 @@ -P3 -# 224-color Macintosh Linux logo -80 80 -255 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 10 10 10 10 10 10 - 10 10 10 6 6 6 6 6 6 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 22 22 22 26 26 26 30 30 30 34 34 34 - 30 30 30 30 30 30 26 26 26 18 18 18 - 14 14 14 10 10 10 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 26 26 26 42 42 42 - 54 54 54 66 66 66 78 78 78 78 78 78 - 78 78 78 74 74 74 66 66 66 54 54 54 - 42 42 42 26 26 26 18 18 18 10 10 10 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 22 22 22 42 42 42 66 66 66 86 86 86 - 66 66 66 38 38 38 38 38 38 22 22 22 - 26 26 26 34 34 34 54 54 54 66 66 66 - 86 86 86 70 70 70 46 46 46 26 26 26 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 26 26 26 - 50 50 50 82 82 82 58 58 58 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 54 54 54 86 86 86 66 66 66 - 38 38 38 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 22 22 22 50 50 50 - 78 78 78 34 34 34 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 70 70 70 - 78 78 78 46 46 46 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 250 250 250 -250 250 250 250 250 250 250 250 250 242 242 242 -250 250 250 250 250 250 246 246 246 250 250 250 -246 246 246 242 242 242 246 246 246 231 231 231 - 46 46 46 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 46 46 46 34 34 34 6 6 6 2 2 6 - 82 82 82 242 242 242 242 242 242 246 246 246 -242 242 242 250 250 250 242 242 242 246 246 246 -242 242 242 250 250 250 242 242 242 250 250 250 -250 250 250 250 250 250 250 250 250 250 250 250 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 242 242 242 -250 250 250 250 250 250 250 250 250 250 250 250 -242 242 242 246 246 246 250 250 250 250 250 250 -250 250 250 250 250 250 242 242 242 116 116 116 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 86 86 86 101 101 101 46 46 46 10 10 10 - 2 2 6 123 123 123 242 242 242 250 250 250 -246 246 246 250 250 250 242 242 242 250 250 250 -246 246 246 250 250 250 242 242 242 250 250 250 -242 242 242 250 250 250 250 250 250 250 250 250 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 123 123 123 -234 234 234 231 231 231 234 234 234 234 234 234 -234 234 234 221 221 221 234 234 234 231 231 231 -234 234 234 234 234 234 214 214 214 10 10 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 30 30 30 - 94 94 94 94 94 94 58 58 58 26 26 26 - 2 2 6 10 10 10 190 190 190 242 242 242 -242 242 242 250 250 250 250 250 250 242 242 242 -246 246 246 250 250 250 250 250 250 242 242 242 -250 250 250 242 242 242 242 242 242 231 231 231 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 90 90 90 -234 234 234 226 226 226 226 226 226 218 218 218 -226 226 226 214 214 214 231 231 231 221 221 221 -231 231 231 221 221 221 116 116 116 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 26 26 26 - 54 54 54 38 38 38 18 18 18 10 10 10 - 2 2 6 2 2 6 58 58 58 242 242 242 -242 242 242 242 242 242 242 242 242 242 242 242 -242 242 242 242 242 242 242 242 242 242 242 242 -242 242 242 242 242 242 250 250 250 226 226 226 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 82 82 82 -234 234 234 231 231 231 242 242 242 242 242 242 -234 234 234 234 234 234 238 238 238 234 234 234 -238 238 238 238 238 238 50 50 50 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 10 10 10 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 182 182 182 -242 242 242 250 250 250 250 250 250 250 250 250 -242 242 242 250 250 250 250 250 250 250 250 250 -242 242 242 242 242 242 250 250 250 206 206 206 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -250 250 250 226 226 226 234 234 234 10 10 10 - 78 78 78 66 66 66 101 98 89 90 90 90 -110 110 110 106 106 106 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 101 98 89 -210 210 210 238 238 238 226 226 226 238 238 238 -210 210 210 242 242 242 226 226 226 242 242 242 -242 242 242 234 234 234 250 250 250 198 198 198 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 82 82 82 -234 234 234 234 234 234 231 231 231 2 2 6 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 82 82 82 2 2 6 2 2 6 - 2 2 6 6 6 6 10 10 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 6 6 6 - 14 14 14 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 18 18 18 - 82 82 82 34 34 34 10 10 10 0 0 0 - 6 6 6 0 0 0 0 0 0 0 0 0 -144 144 144 250 250 250 242 242 242 202 202 202 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 82 82 82 -226 226 226 231 231 231 234 234 234 90 90 90 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 6 6 6 6 6 6 22 22 22 34 34 34 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 34 34 34 - 10 10 10 50 50 50 22 22 22 2 2 6 - 2 2 6 2 2 6 2 2 6 10 10 10 - 86 86 86 42 42 42 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 -158 158 158 242 242 242 234 234 234 187 187 187 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 66 66 66 -231 231 231 226 226 226 226 226 226 178 178 178 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 2 2 6 - 38 38 38 116 116 116 94 94 94 22 22 22 - 22 22 22 2 2 6 2 2 6 2 2 6 - 14 14 14 86 86 86 138 138 138 162 162 162 -154 154 154 38 38 38 26 26 26 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 -187 187 187 234 234 234 250 250 250 190 190 190 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 82 82 82 -226 226 226 218 218 218 234 234 234 218 218 218 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 14 14 14 -134 134 134 198 198 198 195 195 195 116 116 116 - 10 10 10 2 2 6 2 2 6 6 6 6 -101 98 89 187 187 187 210 210 210 218 218 218 -214 214 214 134 134 134 14 14 14 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 86 86 86 50 50 50 18 18 18 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -214 214 214 226 226 226 242 242 242 187 187 187 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 74 74 74 -226 226 226 214 214 214 226 226 226 190 190 190 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 86 86 86 2 2 6 54 54 54 -218 218 218 195 195 195 226 226 226 246 246 246 - 58 58 58 2 2 6 2 2 6 30 30 30 -210 210 210 253 253 253 174 174 174 123 123 123 -221 221 221 234 234 234 74 74 74 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -195 195 195 226 226 226 234 234 234 206 206 206 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 62 62 62 -226 226 226 218 218 218 234 234 234 226 226 226 - 0 0 0 0 0 0 0 0 0 14 14 14 - 46 46 46 82 82 82 2 2 6 106 106 106 -170 170 170 26 26 26 86 86 86 226 226 226 -123 123 123 10 10 10 14 14 14 46 46 46 -231 231 231 190 190 190 6 6 6 70 70 70 - 90 90 90 238 238 238 158 158 158 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -182 182 182 234 234 234 242 242 242 158 158 158 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 1 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 101 98 89 -214 214 214 214 214 214 226 226 226 242 242 242 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 86 86 86 6 6 6 116 116 116 -106 106 106 6 6 6 70 70 70 149 149 149 -128 128 128 18 18 18 38 38 38 54 54 54 -221 221 221 106 106 106 2 2 6 14 14 14 - 46 46 46 190 190 190 198 198 198 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -190 190 190 226 226 226 226 226 226 178 178 178 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 66 66 66 -210 210 210 214 214 214 210 210 210 250 250 250 - 0 0 0 0 0 0 0 0 0 14 14 14 - 42 42 42 94 94 94 14 14 14 101 101 101 -128 128 128 2 2 6 18 18 18 116 116 116 -118 98 46 121 92 8 121 92 8 98 78 10 -162 162 162 106 106 106 2 2 6 2 2 6 - 2 2 6 195 195 195 195 195 195 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 74 74 74 62 62 62 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -214 214 214 226 226 226 231 231 231 149 149 149 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 1 - 0 0 1 0 0 0 0 0 1 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -226 226 226 218 218 218 210 210 210 231 231 231 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 90 90 90 14 14 14 58 58 58 -210 210 210 26 26 26 54 38 6 154 114 10 -226 170 11 236 186 11 225 175 15 184 144 12 -215 174 15 175 146 61 37 26 9 2 2 6 - 70 70 70 246 246 246 138 138 138 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 70 70 70 66 66 66 26 26 26 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -178 178 178 218 218 218 226 226 226 162 162 162 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -214 214 214 198 198 198 210 210 210 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 14 14 14 10 10 10 -195 195 195 188 164 115 192 133 9 225 175 15 -239 182 13 234 190 10 232 195 16 232 200 30 -245 207 45 241 208 19 232 195 16 184 144 12 -218 194 134 211 206 186 42 42 42 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 74 74 74 30 30 30 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 -187 187 187 231 231 231 226 226 226 182 182 182 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 66 66 66 -218 218 218 210 210 210 210 210 210 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 86 86 86 14 14 14 2 2 6 -121 87 25 192 133 9 219 162 10 239 182 13 -236 186 11 232 195 16 241 208 19 244 214 54 -246 218 60 246 218 38 246 215 20 241 208 19 -241 208 19 226 184 13 121 87 25 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 50 50 50 82 82 82 34 34 34 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 -162 162 162 226 226 226 226 226 226 162 162 162 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 62 62 62 -206 206 206 206 206 206 202 202 202 250 250 250 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 82 82 82 30 30 30 61 42 6 -180 123 7 206 145 10 230 174 11 239 182 13 -234 190 10 238 202 15 241 208 19 246 218 74 -246 218 38 246 215 20 246 215 20 246 215 20 -226 184 13 215 174 15 184 144 12 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 26 26 26 94 94 94 42 42 42 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 -166 166 166 226 226 226 214 214 214 170 170 170 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 66 66 66 -226 226 226 218 218 218 202 202 202 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 50 50 50 104 69 6 -192 133 9 216 158 10 236 178 12 236 186 11 -232 195 16 241 208 19 244 214 54 245 215 43 -246 215 20 246 215 20 241 208 19 198 155 10 -200 144 11 216 158 10 156 118 10 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 6 6 6 90 90 90 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 -178 178 178 226 226 226 226 226 226 158 158 158 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 62 62 62 -214 214 214 198 198 198 202 202 202 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 46 46 46 22 22 22 -137 92 6 210 162 10 239 182 13 238 190 10 -238 202 15 241 208 19 246 215 20 246 215 20 -241 208 19 203 166 17 185 133 11 210 150 10 -216 158 10 210 150 10 102 78 10 2 2 6 - 6 6 6 54 54 54 14 14 14 2 2 6 - 2 2 6 62 62 62 74 74 74 30 30 30 - 10 10 10 0 0 0 0 0 0 0 0 0 -190 190 190 214 214 214 242 242 242 158 158 158 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 66 66 66 -210 210 210 202 202 202 202 202 202 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 34 34 34 78 78 78 50 50 50 6 6 6 - 94 70 30 139 102 15 190 146 13 226 184 13 -232 200 30 232 195 16 215 174 15 190 146 13 -168 122 10 192 133 9 210 150 10 213 154 11 -202 150 34 182 157 106 101 98 89 2 2 6 - 2 2 6 78 78 78 116 116 116 58 58 58 - 2 2 6 22 22 22 90 90 90 46 46 46 - 18 18 18 6 6 6 0 0 0 0 0 0 -195 195 195 214 214 214 226 226 226 162 162 162 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 82 82 82 -198 198 198 190 190 190 187 187 187 242 242 242 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 86 86 86 50 50 50 6 6 6 -128 128 128 174 154 114 156 107 11 168 122 10 -198 155 10 184 144 12 197 138 11 200 144 11 -206 145 10 206 145 10 197 138 11 188 164 115 -195 195 195 198 198 198 174 174 174 14 14 14 - 2 2 6 22 22 22 116 116 116 116 116 116 - 22 22 22 2 2 6 74 74 74 70 70 70 - 30 30 30 10 10 10 0 0 0 0 0 0 -178 178 178 226 226 226 226 226 226 141 141 141 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 62 62 62 -195 195 195 195 195 195 195 195 195 250 250 250 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 101 101 101 26 26 26 10 10 10 -138 138 138 190 190 190 174 154 114 156 107 11 -197 138 11 200 144 11 197 138 11 192 133 9 -180 123 7 190 142 34 190 178 144 187 187 187 -202 202 202 221 221 221 214 214 214 66 66 66 - 2 2 6 2 2 6 50 50 50 62 62 62 - 6 6 6 2 2 6 10 10 10 90 90 90 - 50 50 50 18 18 18 6 6 6 0 0 0 -190 190 190 226 226 226 250 250 250 202 202 202 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -187 187 187 190 190 190 187 187 187 250 250 250 - 0 0 0 0 0 0 10 10 10 34 34 34 - 74 74 74 74 74 74 2 2 6 6 6 6 -144 144 144 198 198 198 190 190 190 178 166 146 -154 121 60 156 107 11 156 107 11 168 124 44 -174 154 114 187 187 187 190 190 190 210 210 210 -246 246 246 253 253 253 253 253 253 182 182 182 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 62 62 62 - 74 74 74 34 34 34 14 14 14 0 0 0 -174 174 174 206 206 206 242 242 242 158 158 158 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -190 190 190 187 187 187 190 190 190 234 234 234 - 0 0 0 10 10 10 22 22 22 54 54 54 - 94 94 94 18 18 18 2 2 6 46 46 46 -234 234 234 221 221 221 190 190 190 190 190 190 -190 190 190 187 187 187 187 187 187 190 190 190 -190 190 190 195 195 195 214 214 214 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 - 82 82 82 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 14 14 14 - 86 86 86 54 54 54 22 22 22 6 6 6 -195 195 195 202 202 202 234 234 234 138 138 138 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -182 182 182 187 187 187 178 178 178 242 242 242 - 6 6 6 18 18 18 46 46 46 90 90 90 - 46 46 46 18 18 18 6 6 6 182 182 182 -253 253 253 246 246 246 206 206 206 190 190 190 -190 190 190 190 190 190 190 190 190 190 190 190 -206 206 206 231 231 231 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -202 202 202 14 14 14 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 42 42 42 86 86 86 42 42 42 18 18 18 -190 190 190 202 202 202 226 226 226 178 178 178 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 62 62 62 -195 195 195 182 182 182 187 187 187 250 250 250 - 14 14 14 38 38 38 74 74 74 66 66 66 - 2 2 6 6 6 6 90 90 90 250 250 250 -253 253 253 253 253 253 238 238 238 198 198 198 -190 190 190 190 190 190 195 195 195 221 221 221 -246 246 246 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 82 82 82 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 78 78 78 70 70 70 34 34 34 -202 202 202 182 182 182 242 242 242 158 158 158 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 26 26 26 -195 195 195 182 182 182 178 178 178 242 242 242 - 34 34 34 66 66 66 78 78 78 6 6 6 - 2 2 6 18 18 18 218 218 218 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -226 226 226 231 231 231 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 178 178 178 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 18 18 18 90 90 90 62 62 62 -218 218 218 198 198 198 250 250 250 141 141 141 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -182 182 182 178 178 178 174 174 174 250 250 250 - 58 58 58 90 90 90 18 18 18 2 2 6 - 2 2 6 110 110 110 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 18 18 18 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 18 18 18 94 94 94 -206 206 206 198 198 198 242 242 242 162 162 162 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 42 42 42 -166 166 166 170 170 170 187 187 187 242 242 242 - 90 90 90 26 26 26 2 2 6 2 2 6 - 14 14 14 195 195 195 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 242 242 242 54 54 54 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 38 38 38 -187 187 187 214 214 214 231 231 231 134 134 134 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -187 187 187 182 182 182 166 166 166 234 234 234 - 34 34 34 2 2 6 2 2 6 2 2 6 - 42 42 42 195 195 195 246 246 246 253 253 253 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 242 242 242 250 250 250 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 246 246 246 238 238 238 -226 226 226 231 231 231 101 101 101 6 6 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 -206 206 206 174 174 174 250 250 250 128 128 128 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 34 34 34 -178 178 178 144 144 144 170 170 170 226 226 226 - 2 2 6 2 2 6 2 2 6 6 6 6 - 70 70 70 170 170 170 206 206 206 234 234 234 -246 246 246 250 250 250 250 250 250 238 238 238 -226 226 226 231 231 231 238 238 238 250 250 250 -250 250 250 250 250 250 246 246 246 231 231 231 -214 214 214 206 206 206 202 202 202 202 202 202 -198 198 198 202 202 202 182 182 182 18 18 18 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 -202 202 202 166 166 166 214 214 214 128 128 128 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -178 178 178 158 158 158 134 134 134 242 242 242 - 2 2 6 2 2 6 2 2 6 10 10 10 - 94 94 94 182 182 182 218 218 218 242 242 242 -250 250 250 253 253 253 253 253 253 250 250 250 -234 234 234 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 246 246 246 -238 238 238 226 226 226 210 210 210 202 202 202 -195 195 195 195 195 195 210 210 210 158 158 158 - 6 6 6 14 14 14 50 50 50 14 14 14 - 2 2 6 2 2 6 2 2 6 2 2 6 -198 198 198 187 187 187 246 246 246 116 116 116 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -195 195 195 154 154 154 154 154 154 250 250 250 -250 250 250 250 250 250 242 242 242 242 242 242 -242 242 242 250 250 250 250 250 250 250 250 250 -250 250 250 250 250 250 242 242 242 250 250 250 -250 250 250 250 250 250 242 242 242 250 250 250 -250 250 250 250 250 250 250 250 250 246 246 246 -234 234 234 250 250 250 242 242 242 242 242 242 -242 242 242 250 250 250 242 242 242 242 242 242 -242 242 242 250 250 250 242 242 242 242 242 242 -250 250 250 242 242 242 242 242 242 250 250 250 -182 182 182 190 190 190 206 206 206 141 141 141 - 26 26 26 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -170 170 170 166 166 166 128 128 128 250 250 250 -242 242 242 250 250 250 250 250 250 242 242 242 -250 250 250 242 242 242 242 242 242 250 250 250 -242 242 242 250 250 250 250 250 250 250 250 250 -250 250 250 250 250 250 242 242 242 250 250 250 -242 242 242 250 250 250 242 242 242 250 250 250 -250 250 250 242 242 242 250 250 250 250 250 250 -242 242 242 250 250 250 250 250 250 250 250 250 -242 242 242 242 242 242 250 250 250 234 234 234 -250 250 250 242 242 242 242 242 242 250 250 250 -195 195 195 195 195 195 206 206 206 128 128 128 - 42 42 42 14 14 14 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 50 50 50 -178 178 178 174 174 174 158 158 158 170 170 170 -162 162 162 170 170 170 170 170 170 162 162 162 -166 166 166 170 170 170 154 154 154 154 154 154 -178 178 178 162 162 162 166 166 166 166 166 166 -166 166 166 158 158 158 178 178 178 162 162 162 -170 170 170 174 174 174 178 178 178 178 178 178 -170 170 170 178 178 178 170 170 170 166 166 166 -170 170 170 182 182 182 187 187 187 178 178 178 -195 195 195 195 195 195 195 195 195 195 195 195 -187 187 187 195 195 195 178 178 178 195 195 195 -206 206 206 195 195 195 210 210 210 116 116 116 - 58 58 58 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 50 50 50 -162 162 162 162 162 162 170 170 170 158 158 158 -162 162 162 158 158 158 162 162 162 166 166 166 -158 158 158 174 174 174 162 162 162 158 158 158 -170 170 170 166 166 166 166 166 166 174 174 174 -166 166 166 174 174 174 174 174 174 174 174 174 -174 174 174 182 182 182 166 166 166 187 187 187 -182 182 182 187 187 187 174 174 174 166 166 166 -166 166 166 187 187 187 182 182 182 158 158 158 -174 174 174 174 174 174 174 174 174 182 182 182 -182 182 182 182 182 182 178 178 178 195 195 195 -178 178 178 182 182 182 174 174 174 30 30 30 - 78 78 78 30 30 30 10 10 10 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 10 10 10 34 34 34 -154 154 154 158 158 158 154 154 154 158 158 158 -154 154 154 166 166 166 162 162 162 178 178 178 -178 178 178 166 166 166 170 170 170 158 158 158 -170 170 170 178 178 178 178 178 178 187 187 187 -195 195 195 178 178 178 178 178 178 178 178 178 -162 162 162 187 187 187 166 166 166 178 178 178 -174 174 174 178 178 178 170 170 170 170 170 170 -174 174 174 170 170 170 187 187 187 178 178 178 -178 178 178 202 202 202 170 170 170 187 187 187 -178 178 178 182 182 182 174 174 174 190 190 190 -182 182 182 166 166 166 149 149 149 6 6 6 - 86 86 86 46 46 46 14 14 14 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 50 50 50 -166 166 166 162 162 162 149 149 149 162 162 162 -158 158 158 170 170 170 158 158 158 158 158 158 -166 166 166 170 170 170 149 149 149 170 170 170 -158 158 158 174 174 174 166 166 166 166 166 166 -166 166 166 166 166 166 182 182 182 158 158 158 -158 158 158 174 174 174 170 170 170 158 158 158 -178 178 178 166 166 166 158 158 158 174 174 174 -170 170 170 166 166 166 174 174 174 166 166 166 -174 174 174 182 182 182 174 174 174 182 182 182 -174 174 174 178 178 178 187 187 187 206 206 206 -187 187 187 178 178 178 128 128 128 2 2 6 - 74 74 74 58 58 58 22 22 22 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 10 10 10 26 26 26 42 42 42 -158 158 158 144 144 144 149 149 149 162 162 162 -149 149 149 170 170 170 170 170 170 170 170 170 -174 174 174 170 170 170 158 158 158 162 162 162 -170 170 170 162 162 162 170 170 170 170 170 170 -162 162 162 162 162 162 170 170 170 170 170 170 -170 170 170 166 166 166 154 154 154 166 166 166 -154 154 154 162 162 162 170 170 170 149 149 149 -170 170 170 144 144 144 187 187 187 170 170 170 -170 170 170 195 195 195 187 187 187 202 202 202 -198 198 198 182 182 182 202 202 202 210 210 210 -187 187 187 178 178 178 106 106 106 2 2 6 - 42 42 42 74 74 74 30 30 30 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 42 42 42 42 42 42 -158 158 158 141 141 141 162 162 162 149 149 149 -154 154 154 158 158 158 166 166 166 174 174 174 -162 162 162 158 158 158 162 162 162 158 158 158 -158 158 158 158 158 158 166 166 166 166 166 166 -158 158 158 158 158 158 158 158 158 166 166 166 -166 166 166 170 170 170 182 182 182 187 187 187 -166 166 166 174 174 174 166 166 166 154 154 154 -174 174 174 174 174 174 166 166 166 190 190 190 - 34 34 34 2 2 6 18 18 18 2 2 6 - 34 34 34 2 2 6 18 18 18 78 78 78 -182 182 182 178 178 178 78 78 78 2 2 6 - 10 10 10 86 86 86 38 38 38 10 10 10 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 10 10 10 26 26 26 66 66 66 30 30 30 -138 138 138 144 144 144 154 154 154 149 149 149 -154 154 154 154 154 154 154 154 154 166 166 166 -162 162 162 158 158 158 162 162 162 154 154 154 -170 170 170 154 154 154 178 178 178 162 162 162 -162 162 162 170 170 170 162 162 162 154 154 154 - 2 2 6 2 2 6 34 34 34 42 42 42 - 42 42 42 34 34 34 22 18 6 34 34 34 - 42 42 42 42 42 42 66 66 66 34 34 34 -128 128 128 10 10 10 10 10 10 18 18 18 - 18 18 18 10 10 10 26 26 26 174 174 174 -187 187 187 138 138 138 34 34 34 2 2 6 - 6 6 6 86 86 86 46 46 46 14 14 14 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 46 46 46 86 86 86 6 6 6 -110 110 110 162 162 162 149 149 149 144 144 144 -149 149 149 166 166 166 149 149 149 162 162 162 -149 149 149 162 162 162 149 149 149 158 158 158 -166 166 166 158 158 158 158 158 158 166 166 166 -166 166 166 149 149 149 158 158 158 166 166 166 -128 128 128 18 18 18 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 22 18 6 26 26 26 - 18 18 18 6 6 6 18 18 18 166 166 166 -174 174 174 110 110 110 18 18 18 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 26 26 26 66 66 66 62 62 62 2 2 6 - 46 46 46 141 141 141 166 166 166 144 144 144 -154 154 154 170 170 170 158 158 158 162 162 162 -149 149 149 162 162 162 154 154 154 154 154 154 -162 162 162 144 144 144 162 162 162 154 154 154 -170 170 170 144 144 144 154 154 154 170 170 170 -116 116 116 144 144 144 110 110 110 116 116 116 -110 110 110 144 144 144 116 116 116 128 128 128 -134 134 134 116 116 116 134 134 134 149 149 149 -158 158 158 231 231 231 234 234 234 214 214 214 -202 202 202 195 195 195 166 166 166 144 144 144 -144 144 144 34 34 34 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 38 38 38 78 78 78 6 6 6 2 2 6 - 14 14 14 123 123 123 138 138 138 90 90 90 -110 110 110 128 128 128 154 154 154 149 149 149 -144 144 144 149 149 149 158 158 158 149 149 149 -166 166 166 158 158 158 158 158 158 166 166 166 -158 158 158 158 158 158 158 158 158 158 158 158 -144 144 144 170 170 170 162 162 162 170 170 170 -187 187 187 174 174 174 170 170 170 170 170 170 -162 162 162 170 170 170 170 170 170 178 178 178 -187 187 187 190 190 190 170 170 170 149 149 149 -149 149 149 138 138 138 170 170 170 116 116 116 - 18 18 18 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 74 74 74 2 2 6 2 2 6 - 14 14 14 94 94 94 134 134 134 74 74 74 - 50 50 50 158 158 158 154 154 154 166 166 166 -162 162 162 170 170 170 162 162 162 178 178 178 -170 170 170 154 154 154 162 162 162 154 154 154 -154 154 154 154 154 154 170 170 170 141 141 141 -149 149 149 166 166 166 166 166 166 166 166 166 -178 178 178 174 174 174 158 158 158 174 174 174 -174 174 174 174 174 174 174 174 174 158 158 158 -166 166 166 166 166 166 170 170 170 170 170 170 -170 170 170 162 162 162 82 82 82 10 10 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 62 62 62 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 54 54 54 62 62 62 2 2 6 2 2 6 - 2 2 6 34 34 34 123 123 123 18 18 18 - 22 18 6 128 128 128 149 149 149 154 154 154 -158 158 158 158 158 158 149 149 149 166 166 166 -166 166 166 158 158 158 158 158 158 182 182 182 -158 158 158 149 149 149 149 149 149 178 178 178 -162 162 162 170 170 170 170 170 170 170 170 170 -174 174 174 178 178 178 170 170 170 178 178 178 -170 170 170 178 178 178 178 178 178 162 162 162 -174 174 174 170 170 170 166 166 166 166 166 166 -141 141 141 50 50 50 30 30 30 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 66 66 66 58 58 58 22 22 22 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 62 62 62 2 2 6 2 2 6 - 2 2 6 2 2 6 38 38 38 144 144 144 -178 178 178 162 162 162 134 134 134 154 154 154 -154 154 154 154 154 154 154 154 154 170 170 170 -154 154 154 154 154 154 162 162 162 170 170 170 -162 162 162 154 154 154 158 158 158 174 174 174 -149 149 149 166 166 166 174 174 174 178 178 178 -174 174 174 174 174 174 166 166 166 174 174 174 -166 166 166 166 166 166 166 166 166 166 166 166 -170 170 170 170 170 170 166 166 166 138 138 138 - 42 42 42 34 34 34 18 14 6 22 22 22 - 26 26 26 18 18 18 6 6 6 2 2 6 - 2 2 6 82 82 82 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 26 26 26 - 62 62 62 106 106 106 74 54 14 185 133 11 -210 162 10 121 92 8 6 6 6 78 78 78 -154 154 154 149 149 149 141 141 141 149 149 149 -149 149 149 149 149 149 158 158 158 141 141 141 -149 149 149 141 141 141 158 158 158 149 149 149 -149 149 149 149 149 149 162 162 162 170 170 170 -154 154 154 170 170 170 162 162 162 166 166 166 -170 170 170 170 170 170 170 170 170 162 162 162 -162 162 162 170 170 170 170 170 170 170 170 170 -170 170 170 162 162 162 162 162 162 38 38 38 - 14 14 14 2 2 6 2 2 6 2 2 6 - 6 6 6 18 18 18 66 66 66 38 38 38 - 6 6 6 94 94 94 50 50 50 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 10 10 10 10 10 10 18 18 18 38 38 38 - 78 78 78 142 134 106 216 158 10 242 186 14 -246 190 14 246 190 14 156 118 10 10 10 10 -116 116 116 182 182 182 138 138 138 154 154 154 -154 154 154 138 138 138 162 162 162 170 170 170 -178 178 178 138 138 138 162 162 162 162 162 162 -162 162 162 158 158 158 149 149 149 174 174 174 -134 134 134 174 174 174 170 170 170 158 158 158 -158 158 158 174 174 174 141 141 141 174 174 174 -149 149 149 166 166 166 158 158 158 174 174 174 -141 141 141 178 178 178 175 146 61 37 26 9 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 38 38 38 46 46 46 - 26 26 26 106 106 106 54 54 54 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 22 22 22 - 30 30 30 38 38 38 50 50 50 70 70 70 -106 106 106 190 142 34 226 170 11 242 186 14 -246 190 14 246 190 14 246 190 14 154 114 10 - 6 6 6 74 74 74 226 226 226 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 231 231 231 250 250 250 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 228 184 62 -241 196 14 241 208 19 232 195 16 38 30 10 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 30 30 30 26 26 26 -203 166 17 154 142 90 66 66 66 26 26 26 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 38 38 38 58 58 58 - 78 78 78 86 86 86 101 101 101 123 123 123 -175 146 61 210 150 10 234 174 13 246 186 14 -246 190 14 246 190 14 246 190 14 238 190 10 -102 78 10 2 2 6 46 46 46 198 198 198 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 234 234 234 242 242 242 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 224 178 62 -242 186 14 241 196 14 210 166 10 22 18 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 6 6 6 121 92 8 -238 202 15 232 195 16 82 82 82 34 34 34 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 14 14 14 38 38 38 70 70 70 154 122 46 -190 142 34 200 144 11 197 138 11 197 138 11 -213 154 11 226 170 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -225 175 15 46 32 6 2 2 6 22 22 22 -158 158 158 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 242 242 242 224 178 62 -239 182 13 236 186 11 213 154 11 46 32 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 225 175 15 -238 190 10 236 186 11 112 100 78 42 42 42 - 14 14 14 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 22 22 22 54 54 54 154 122 46 213 154 11 -226 170 11 230 174 11 226 170 11 226 170 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 184 144 12 10 10 10 2 2 6 - 6 6 6 116 116 116 242 242 242 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 231 231 231 198 198 198 214 170 54 -236 178 12 236 178 12 210 150 10 137 92 6 - 18 14 6 2 2 6 2 2 6 2 2 6 - 6 6 6 70 47 6 200 144 11 236 178 12 -239 182 13 239 182 13 124 112 88 58 58 58 - 22 22 22 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 70 70 70 180 133 36 226 170 11 -239 182 13 242 186 14 242 186 14 246 186 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 98 70 6 2 2 6 - 2 2 6 2 2 6 66 66 66 221 221 221 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 206 206 206 198 198 198 214 166 58 -230 174 11 230 174 11 216 158 10 192 133 9 -163 110 8 116 81 8 102 78 10 116 81 8 -167 114 7 197 138 11 226 170 11 239 182 13 -242 186 14 242 186 14 162 146 94 78 78 78 - 34 34 34 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 30 30 30 78 78 78 190 142 34 226 170 11 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 241 196 14 203 166 17 22 18 6 - 2 2 6 2 2 6 2 2 6 38 38 38 -218 218 218 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 206 206 206 198 198 198 202 162 69 -226 170 11 236 178 12 224 166 10 210 150 10 -200 144 11 197 138 11 192 133 9 197 138 11 -210 150 10 226 170 11 242 186 14 246 190 14 -246 190 14 246 186 14 225 175 15 124 112 88 - 62 62 62 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 174 135 50 224 166 10 -239 182 13 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 139 102 15 - 2 2 6 2 2 6 2 2 6 2 2 6 - 78 78 78 250 250 250 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -250 250 250 214 214 214 198 198 198 190 150 46 -219 162 10 236 178 12 234 174 13 224 166 10 -216 158 10 213 154 11 213 154 11 216 158 10 -226 170 11 239 182 13 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 206 162 42 -101 101 101 58 58 58 30 30 30 14 14 14 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 74 74 74 174 135 50 216 158 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 241 196 14 226 184 13 - 61 42 6 2 2 6 2 2 6 2 2 6 - 22 22 22 238 238 238 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 226 226 226 187 187 187 180 133 36 -216 158 10 236 178 12 239 182 13 236 178 12 -230 174 11 226 170 11 226 170 11 230 174 11 -236 178 12 242 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 186 14 239 182 13 -206 162 42 106 106 106 66 66 66 34 34 34 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 213 154 11 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 241 196 14 -190 146 13 18 14 6 2 2 6 2 2 6 - 46 46 46 246 246 246 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 221 221 221 86 86 86 156 107 11 -216 158 10 236 178 12 242 186 14 246 186 14 -242 186 14 239 182 13 239 182 13 242 186 14 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 225 175 15 142 122 72 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 26 26 26 70 70 70 163 133 67 210 150 10 -236 178 12 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -232 195 16 121 92 8 34 34 34 106 106 106 -221 221 221 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -242 242 242 82 82 82 18 14 6 163 110 8 -216 158 10 236 178 12 242 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 242 186 14 163 133 67 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 10 10 10 - 30 30 30 78 78 78 163 133 67 210 150 10 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -241 196 14 215 174 15 190 178 144 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 218 218 218 - 58 58 58 2 2 6 22 18 6 167 114 7 -216 158 10 236 178 12 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 186 14 242 186 14 190 150 46 - 54 54 54 22 22 22 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 38 38 38 86 86 86 180 133 36 213 154 11 -236 178 12 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 232 195 16 190 146 13 214 214 214 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 250 250 250 170 170 170 26 26 26 - 2 2 6 2 2 6 37 26 9 163 110 8 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 224 166 10 142 122 72 - 46 46 46 18 18 18 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 109 106 95 192 133 9 224 166 10 -242 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -242 186 14 226 184 13 210 162 10 142 110 46 -226 226 226 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -253 253 253 253 253 253 253 253 253 253 253 253 -198 198 198 66 66 66 2 2 6 2 2 6 - 2 2 6 2 2 6 50 34 6 156 107 11 -219 162 10 239 182 13 246 186 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 242 186 14 -234 174 13 213 154 11 154 122 46 66 66 66 - 30 30 30 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 58 58 58 154 121 60 206 145 10 234 174 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 236 178 12 210 162 10 163 110 8 - 61 42 6 138 138 138 218 218 218 250 250 250 -253 253 253 253 253 253 253 253 253 250 250 250 -242 242 242 210 210 210 144 144 144 66 66 66 - 6 6 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 61 42 6 163 110 8 -216 158 10 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 239 182 13 230 174 11 216 158 10 -190 142 34 124 112 88 70 70 70 38 38 38 - 18 18 18 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 22 22 22 - 62 62 62 168 124 44 206 145 10 224 166 10 -236 178 12 239 182 13 242 186 14 242 186 14 -246 186 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 236 178 12 216 158 10 175 118 6 - 80 54 7 2 2 6 6 6 6 30 30 30 - 54 54 54 62 62 62 50 50 50 38 38 38 - 14 14 14 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 167 114 7 -213 154 11 236 178 12 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 190 14 242 186 14 239 182 13 239 182 13 -230 174 11 210 150 10 174 135 50 124 112 88 - 82 82 82 54 54 54 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 18 18 18 - 50 50 50 158 118 36 192 133 9 200 144 11 -216 158 10 219 162 10 224 166 10 226 170 11 -230 174 11 236 178 12 239 182 13 239 182 13 -242 186 14 246 186 14 246 190 14 246 190 14 -246 190 14 246 190 14 246 190 14 246 190 14 -246 186 14 230 174 11 210 150 10 163 110 8 -104 69 6 10 10 10 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 91 60 6 167 114 7 -206 145 10 230 174 11 242 186 14 246 190 14 -246 190 14 246 190 14 246 186 14 242 186 14 -239 182 13 230 174 11 224 166 10 213 154 11 -180 133 36 124 112 88 86 86 86 58 58 58 - 38 38 38 22 22 22 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 14 14 14 - 34 34 34 70 70 70 138 110 50 158 118 36 -167 114 7 180 123 7 192 133 9 197 138 11 -200 144 11 206 145 10 213 154 11 219 162 10 -224 166 10 230 174 11 239 182 13 242 186 14 -246 186 14 246 186 14 246 186 14 246 186 14 -239 182 13 216 158 10 185 133 11 152 99 6 -104 69 6 18 14 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 2 2 6 2 2 6 2 2 6 - 2 2 6 6 6 6 80 54 7 152 99 6 -192 133 9 219 162 10 236 178 12 239 182 13 -246 186 14 242 186 14 239 182 13 236 178 12 -224 166 10 206 145 10 192 133 9 154 121 60 - 94 94 94 62 62 62 42 42 42 22 22 22 - 14 14 14 6 6 6 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 18 18 18 34 34 34 58 58 58 78 78 78 -101 98 89 124 112 88 142 110 46 156 107 11 -163 110 8 167 114 7 175 118 6 180 123 7 -185 133 11 197 138 11 210 150 10 219 162 10 -226 170 11 236 178 12 236 178 12 234 174 13 -219 162 10 197 138 11 163 110 8 130 83 6 - 91 60 6 10 10 10 2 2 6 2 2 6 - 18 18 18 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 38 38 38 38 38 38 - 38 38 38 38 38 38 26 26 26 2 2 6 - 2 2 6 6 6 6 70 47 6 137 92 6 -175 118 6 200 144 11 219 162 10 230 174 11 -234 174 13 230 174 11 219 162 10 210 150 10 -192 133 9 163 110 8 124 112 88 82 82 82 - 50 50 50 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 14 14 14 22 22 22 34 34 34 - 42 42 42 58 58 58 74 74 74 86 86 86 -101 98 89 122 102 70 130 98 46 121 87 25 -137 92 6 152 99 6 163 110 8 180 123 7 -185 133 11 197 138 11 206 145 10 200 144 11 -180 123 7 156 107 11 130 83 6 104 69 6 - 50 34 6 54 54 54 110 110 110 101 98 89 - 86 86 86 82 82 82 78 78 78 78 78 78 - 78 78 78 78 78 78 78 78 78 78 78 78 - 78 78 78 82 82 82 86 86 86 94 94 94 -106 106 106 101 101 101 86 66 34 124 80 6 -156 107 11 180 123 7 192 133 9 200 144 11 -206 145 10 200 144 11 192 133 9 175 118 6 -139 102 15 109 106 95 70 70 70 42 42 42 - 22 22 22 10 10 10 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 6 6 6 10 10 10 - 14 14 14 22 22 22 30 30 30 38 38 38 - 50 50 50 62 62 62 74 74 74 90 90 90 -101 98 89 112 100 78 121 87 25 124 80 6 -137 92 6 152 99 6 152 99 6 152 99 6 -138 86 6 124 80 6 98 70 6 86 66 30 -101 98 89 82 82 82 58 58 58 46 46 46 - 38 38 38 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 34 34 34 34 34 34 - 34 34 34 34 34 34 38 38 38 42 42 42 - 54 54 54 82 82 82 94 86 76 91 60 6 -134 86 6 156 107 11 167 114 7 175 118 6 -175 118 6 167 114 7 152 99 6 121 87 25 -101 98 89 62 62 62 34 34 34 18 18 18 - 6 6 6 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 6 6 6 10 10 10 - 18 18 18 22 22 22 30 30 30 42 42 42 - 50 50 50 66 66 66 86 86 86 101 98 89 -106 86 58 98 70 6 104 69 6 104 69 6 -104 69 6 91 60 6 82 62 34 90 90 90 - 62 62 62 38 38 38 22 22 22 14 14 14 - 10 10 10 10 10 10 10 10 10 10 10 10 - 10 10 10 10 10 10 6 6 6 10 10 10 - 10 10 10 10 10 10 10 10 10 14 14 14 - 22 22 22 42 42 42 70 70 70 89 81 66 - 80 54 7 104 69 6 124 80 6 137 92 6 -134 86 6 116 81 8 100 82 52 86 86 86 - 58 58 58 30 30 30 14 14 14 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 10 10 10 14 14 14 - 18 18 18 26 26 26 38 38 38 54 54 54 - 70 70 70 86 86 86 94 86 76 89 81 66 - 89 81 66 86 86 86 74 74 74 50 50 50 - 30 30 30 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 18 18 18 34 34 34 58 58 58 - 82 82 82 89 81 66 89 81 66 89 81 66 - 94 86 66 94 86 76 74 74 74 50 50 50 - 26 26 26 14 14 14 6 6 6 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 6 6 6 6 6 6 14 14 14 18 18 18 - 30 30 30 38 38 38 46 46 46 54 54 54 - 50 50 50 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 6 6 6 14 14 14 26 26 26 - 38 38 38 50 50 50 58 58 58 58 58 58 - 54 54 54 42 42 42 30 30 30 18 18 18 - 10 10 10 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 6 6 6 10 10 10 14 14 14 18 18 18 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 6 6 6 - 14 14 14 18 18 18 22 22 22 22 22 22 - 18 18 18 14 14 14 10 10 10 6 6 6 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index bebd371c6b93..d3a2bbed5fea 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -157,7 +157,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np) return NULL; } - disp = kzalloc(sizeof(*disp), GFP_KERNEL); + disp = kzalloc_obj(*disp); if (!disp) { pr_err("%pOF: could not allocate struct disp'\n", np); goto dispfail; @@ -181,32 +181,30 @@ struct display_timings *of_get_display_timings(const struct device_node *np) if (disp->num_timings == 0) { /* should never happen, as entry was already found above */ pr_err("%pOF: no timings specified\n", np); - goto entryfail; + goto timingfail; } - disp->timings = kcalloc(disp->num_timings, - sizeof(struct display_timing *), - GFP_KERNEL); + disp->timings = kzalloc_objs(struct display_timing *, disp->num_timings); if (!disp->timings) { pr_err("%pOF: could not allocate timings array\n", np); - goto entryfail; + goto timingfail; } disp->num_timings = 0; disp->native_mode = 0; - for_each_child_of_node(timings_np, entry) { + for_each_child_of_node_scoped(timings_np, child) { struct display_timing *dt; int r; - dt = kmalloc(sizeof(*dt), GFP_KERNEL); + dt = kmalloc_obj(*dt); if (!dt) { pr_err("%pOF: could not allocate display_timing struct\n", np); goto timingfail; } - r = of_parse_display_timing(entry, dt); + r = of_parse_display_timing(child, dt); if (r) { /* * to not encourage wrong devicetrees, fail in case of @@ -218,7 +216,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np) goto timingfail; } - if (native_mode == entry) + if (native_mode == child) disp->native_mode = disp->num_timings; disp->timings[disp->num_timings] = dt; diff --git a/drivers/video/sticore.c b/drivers/video/sticore.c index 88a1758616e0..0d37e4b10447 100644 --- a/drivers/video/sticore.c +++ b/drivers/video/sticore.c @@ -558,7 +558,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) dest += sizeof(struct sti_rom_font); memcpy(dest, fbfont->data, bpc * fbfont->charcount); - cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font = kzalloc_obj(*cooked_font); if (!cooked_font) { kfree(nf); return NULL; @@ -678,7 +678,7 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom, struct sti_rom_font *raw_font, *font_start; struct sti_cooked_font *cooked_font; - cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font = kzalloc_obj(*cooked_font); if (!cooked_font) return 0; @@ -692,7 +692,7 @@ static int sti_cook_fonts(struct sti_cooked_rom *cooked_rom, while (raw_font->next_font) { raw_font = ((void *)font_start) + (raw_font->next_font); - cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); + cooked_font->next_font = kzalloc_obj(*cooked_font); if (!cooked_font->next_font) return 1; @@ -806,7 +806,7 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, struct sti_rom *raw = NULL; unsigned long revno; - cooked = kmalloc(sizeof *cooked, GFP_KERNEL); + cooked = kmalloc_obj(*cooked); if (!cooked) goto out_err; @@ -915,7 +915,7 @@ static struct sti_struct *sti_try_rom_generic(unsigned long address, return NULL; } - sti = kzalloc(sizeof(*sti), GFP_KERNEL); + sti = kzalloc_obj(*sti); if (!sti) return NULL; diff --git a/drivers/video/vgastate.c b/drivers/video/vgastate.c index 122fb3c3ec9d..6a29d198f62c 100644 --- a/drivers/video/vgastate.c +++ b/drivers/video/vgastate.c @@ -351,7 +351,7 @@ int save_vga(struct vgastate *state) { struct regstate *saved; - saved = kzalloc(sizeof(struct regstate), GFP_KERNEL); + saved = kzalloc_obj(struct regstate); if (saved == NULL) return 1; diff --git a/drivers/virt/acrn/hsm.c b/drivers/virt/acrn/hsm.c index e4e196abdaac..74f2086fa59f 100644 --- a/drivers/virt/acrn/hsm.c +++ b/drivers/virt/acrn/hsm.c @@ -30,7 +30,7 @@ static int acrn_dev_open(struct inode *inode, struct file *filp) { struct acrn_vm *vm; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = kzalloc_obj(*vm); if (!vm) return -ENOMEM; @@ -64,7 +64,7 @@ static int pmcmd_ioctl(u64 cmd, void __user *uptr) kfree(pm_info); break; case ACRN_PMCMD_GET_PX_DATA: - px_data = kzalloc(sizeof(*px_data), GFP_KERNEL); + px_data = kzalloc_obj(*px_data); if (!px_data) return -ENOMEM; @@ -79,7 +79,7 @@ static int pmcmd_ioctl(u64 cmd, void __user *uptr) kfree(px_data); break; case ACRN_PMCMD_GET_CX_DATA: - cx_data = kzalloc(sizeof(*cx_data), GFP_KERNEL); + cx_data = kzalloc_obj(*cx_data); if (!cx_data) return -ENOMEM; diff --git a/drivers/virt/acrn/ioeventfd.c b/drivers/virt/acrn/ioeventfd.c index 4e845c6ca0b5..66fe9f3cef99 100644 --- a/drivers/virt/acrn/ioeventfd.c +++ b/drivers/virt/acrn/ioeventfd.c @@ -96,7 +96,7 @@ static int acrn_ioeventfd_assign(struct acrn_vm *vm, if (IS_ERR(eventfd)) return PTR_ERR(eventfd); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { ret = -ENOMEM; goto fail; diff --git a/drivers/virt/acrn/ioreq.c b/drivers/virt/acrn/ioreq.c index 55ddfa4840af..584698d30607 100644 --- a/drivers/virt/acrn/ioreq.c +++ b/drivers/virt/acrn/ioreq.c @@ -123,7 +123,7 @@ int acrn_ioreq_range_add(struct acrn_ioreq_client *client, return -EINVAL; } - range = kzalloc(sizeof(*range), GFP_KERNEL); + range = kzalloc_obj(*range); if (!range) return -ENOMEM; @@ -424,7 +424,7 @@ struct acrn_ioreq_client *acrn_ioreq_client_create(struct acrn_vm *vm, "Cannot create non-default client w/o handler!\n"); return NULL; } - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return NULL; @@ -602,7 +602,7 @@ int acrn_ioreq_init(struct acrn_vm *vm, u64 buf_vma) if (vm->ioreq_buf) return -EEXIST; - set_buffer = kzalloc(sizeof(*set_buffer), GFP_KERNEL); + set_buffer = kzalloc_obj(*set_buffer); if (!set_buffer) return -ENOMEM; diff --git a/drivers/virt/acrn/irqfd.c b/drivers/virt/acrn/irqfd.c index 64d32c8fbf79..acf8cd5f8f8c 100644 --- a/drivers/virt/acrn/irqfd.c +++ b/drivers/virt/acrn/irqfd.c @@ -112,7 +112,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args) __poll_t events; int ret = 0; - irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL); + irqfd = kzalloc_obj(*irqfd); if (!irqfd) return -ENOMEM; diff --git a/drivers/virt/acrn/mm.c b/drivers/virt/acrn/mm.c index bfb3031885e8..5bca500a83e0 100644 --- a/drivers/virt/acrn/mm.c +++ b/drivers/virt/acrn/mm.c @@ -21,7 +21,7 @@ static int modify_region(struct acrn_vm *vm, struct vm_memory_region_op *region) struct vm_memory_region_batch *regions; int ret; - regions = kzalloc(sizeof(*regions), GFP_KERNEL); + regions = kzalloc_obj(*regions); if (!regions) return -ENOMEM; @@ -55,7 +55,7 @@ int acrn_mm_region_add(struct acrn_vm *vm, u64 user_gpa, u64 service_gpa, struct vm_memory_region_op *region; int ret = 0; - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) return -ENOMEM; @@ -87,7 +87,7 @@ int acrn_mm_region_del(struct acrn_vm *vm, u64 user_gpa, u64 size) struct vm_memory_region_op *region; int ret = 0; - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) return -ENOMEM; @@ -285,8 +285,7 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap) } /* Prepare the vm_memory_region_batch */ - regions_info = kzalloc(struct_size(regions_info, regions_op, - nr_regions), GFP_KERNEL); + regions_info = kzalloc_flex(*regions_info, regions_op, nr_regions); if (!regions_info) { ret = -ENOMEM; goto unmap_kernel_map; diff --git a/drivers/virt/acrn/vm.c b/drivers/virt/acrn/vm.c index fbc9f1042000..3753b27c5312 100644 --- a/drivers/virt/acrn/vm.c +++ b/drivers/virt/acrn/vm.c @@ -107,7 +107,7 @@ int acrn_msi_inject(struct acrn_vm *vm, u64 msi_addr, u64 msi_data) int ret; /* might be used in interrupt context, so use GFP_ATOMIC */ - msi = kzalloc(sizeof(*msi), GFP_ATOMIC); + msi = kzalloc_obj(*msi, GFP_ATOMIC); if (!msi) return -ENOMEM; diff --git a/drivers/virt/coco/guest/report.c b/drivers/virt/coco/guest/report.c index d3d18fc22bc2..b254a1416286 100644 --- a/drivers/virt/coco/guest/report.c +++ b/drivers/virt/coco/guest/report.c @@ -428,7 +428,7 @@ static struct config_item *tsm_report_make_item(struct config_group *group, if (!provider.ops) return ERR_PTR(-ENXIO); - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return ERR_PTR(-ENOMEM); diff --git a/drivers/virt/coco/guest/tsm-mr.c b/drivers/virt/coco/guest/tsm-mr.c index bc509df04db1..657b9c5739d0 100644 --- a/drivers/virt/coco/guest/tsm-mr.c +++ b/drivers/virt/coco/guest/tsm-mr.c @@ -176,7 +176,7 @@ tsm_mr_create_attribute_group(const struct tsm_measurements *tm) const struct bin_attribute **attrs __free(kfree) = kzalloc(sizeof(*attrs) * (tm->nr_mrs + 1) + nlen, GFP_KERNEL); struct tm_context *ctx __free(kfree) = - kzalloc(struct_size(ctx, mrs, tm->nr_mrs), GFP_KERNEL); + kzalloc_flex(*ctx, mrs, tm->nr_mrs); char *name, *end; if (!ctx || !attrs) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index b01ec99106cd..e001e6769a43 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -75,7 +75,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io if (!arg->req_data || !arg->resp_data) return -EINVAL; - report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT); + report_req = kzalloc_obj(*report_req, GFP_KERNEL_ACCOUNT); if (!report_req) return -ENOMEM; @@ -135,7 +135,7 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque if (!derived_key_resp) return -ENOMEM; - derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT); + derived_key_req = kzalloc_obj(*derived_key_req, GFP_KERNEL_ACCOUNT); if (!derived_key_req) return -ENOMEM; @@ -181,7 +181,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data)) return -EINVAL; - report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT); + report_req = kzalloc_obj(*report_req, GFP_KERNEL_ACCOUNT); if (!report_req) return -ENOMEM; diff --git a/drivers/virt/coco/tdx-guest/tdx-guest.c b/drivers/virt/coco/tdx-guest/tdx-guest.c index 4e239ec960c9..4252b147593a 100644 --- a/drivers/virt/coco/tdx-guest/tdx-guest.c +++ b/drivers/virt/coco/tdx-guest/tdx-guest.c @@ -160,8 +160,10 @@ static void tdx_mr_deinit(const struct attribute_group *mr_grp) /* * Intel's SGX QE implementation generally uses Quote size less * than 8K (2K Quote data + ~5K of certificate blob). + * DICE-based attestation uses layered evidence that requires + * larger Quote size (~100K). */ -#define GET_QUOTE_BUF_SIZE SZ_8K +#define GET_QUOTE_BUF_SIZE SZ_128K #define GET_QUOTE_CMD_VER 1 diff --git a/drivers/virt/coco/tsm-core.c b/drivers/virt/coco/tsm-core.c index 8712df8596a1..98dcf7d836df 100644 --- a/drivers/virt/coco/tsm-core.c +++ b/drivers/virt/coco/tsm-core.c @@ -35,7 +35,7 @@ static struct tsm_dev *alloc_tsm_dev(struct device *parent) int id; struct tsm_dev *tsm_dev __free(kfree) = - kzalloc(sizeof(*tsm_dev), GFP_KERNEL); + kzalloc_obj(*tsm_dev); if (!tsm_dev) return ERR_PTR(-ENOMEM); diff --git a/drivers/virt/fsl_hypervisor.c b/drivers/virt/fsl_hypervisor.c index e92e2ceb12a4..f472c94806da 100644 --- a/drivers/virt/fsl_hypervisor.c +++ b/drivers/virt/fsl_hypervisor.c @@ -226,7 +226,7 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p) * 'pages' is an array of struct page pointers that's initialized by * get_user_pages_fast(). */ - pages = kcalloc(num_pages, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, num_pages); if (!pages) { pr_debug("fsl-hv: could not allocate page list\n"); return -ENOMEM; @@ -660,7 +660,7 @@ static int fsl_hv_open(struct inode *inode, struct file *filp) struct doorbell_queue *dbq; unsigned long flags; - dbq = kzalloc(sizeof(struct doorbell_queue), GFP_KERNEL); + dbq = kzalloc_obj(struct doorbell_queue); if (!dbq) { pr_err("fsl-hv: out of memory\n"); return -ENOMEM; @@ -845,7 +845,7 @@ static int __init fsl_hypervisor_init(void) continue; } - dbisr = kzalloc(sizeof(*dbisr), GFP_KERNEL); + dbisr = kzalloc_obj(*dbisr); if (!dbisr) goto out_of_memory; diff --git a/drivers/virt/nitro_enclaves/ne_misc_dev.c b/drivers/virt/nitro_enclaves/ne_misc_dev.c index 241b94f62e56..c91300a73f50 100644 --- a/drivers/virt/nitro_enclaves/ne_misc_dev.c +++ b/drivers/virt/nitro_enclaves/ne_misc_dev.c @@ -294,9 +294,8 @@ static int ne_setup_cpu_pool(const char *ne_cpu_list) ne_cpu_pool.nr_parent_vm_cores = nr_cpu_ids / ne_cpu_pool.nr_threads_per_core; - ne_cpu_pool.avail_threads_per_core = kcalloc(ne_cpu_pool.nr_parent_vm_cores, - sizeof(*ne_cpu_pool.avail_threads_per_core), - GFP_KERNEL); + ne_cpu_pool.avail_threads_per_core = kzalloc_objs(*ne_cpu_pool.avail_threads_per_core, + ne_cpu_pool.nr_parent_vm_cores); if (!ne_cpu_pool.avail_threads_per_core) { rc = -ENOMEM; @@ -928,23 +927,21 @@ static int ne_set_user_memory_region_ioctl(struct ne_enclave *ne_enclave, if (rc < 0) return rc; - ne_mem_region = kzalloc(sizeof(*ne_mem_region), GFP_KERNEL); + ne_mem_region = kzalloc_obj(*ne_mem_region); if (!ne_mem_region) return -ENOMEM; max_nr_pages = mem_region.memory_size / NE_MIN_MEM_REGION_SIZE; - ne_mem_region->pages = kcalloc(max_nr_pages, sizeof(*ne_mem_region->pages), - GFP_KERNEL); + ne_mem_region->pages = kzalloc_objs(*ne_mem_region->pages, max_nr_pages); if (!ne_mem_region->pages) { rc = -ENOMEM; goto free_mem_region; } - phys_contig_mem_regions.regions = kcalloc(max_nr_pages, - sizeof(*phys_contig_mem_regions.regions), - GFP_KERNEL); + phys_contig_mem_regions.regions = kzalloc_objs(*phys_contig_mem_regions.regions, + max_nr_pages); if (!phys_contig_mem_regions.regions) { rc = -ENOMEM; @@ -1617,7 +1614,7 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui mutex_unlock(&ne_cpu_pool.mutex); - ne_enclave = kzalloc(sizeof(*ne_enclave), GFP_KERNEL); + ne_enclave = kzalloc_obj(*ne_enclave); if (!ne_enclave) return -ENOMEM; @@ -1629,9 +1626,8 @@ static int ne_create_vm_ioctl(struct ne_pci_dev *ne_pci_dev, u64 __user *slot_ui mutex_unlock(&ne_cpu_pool.mutex); - ne_enclave->threads_per_core = kcalloc(ne_enclave->nr_parent_vm_cores, - sizeof(*ne_enclave->threads_per_core), - GFP_KERNEL); + ne_enclave->threads_per_core = kzalloc_objs(*ne_enclave->threads_per_core, + ne_enclave->nr_parent_vm_cores); if (!ne_enclave->threads_per_core) { rc = -ENOMEM; diff --git a/drivers/virt/nitro_enclaves/ne_pci_dev.c b/drivers/virt/nitro_enclaves/ne_pci_dev.c index 6b81e8f3a5dc..3e1455d50526 100644 --- a/drivers/virt/nitro_enclaves/ne_pci_dev.c +++ b/drivers/virt/nitro_enclaves/ne_pci_dev.c @@ -468,7 +468,7 @@ static int ne_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) struct ne_pci_dev *ne_pci_dev = NULL; int rc = -EINVAL; - ne_pci_dev = kzalloc(sizeof(*ne_pci_dev), GFP_KERNEL); + ne_pci_dev = kzalloc_obj(*ne_pci_dev); if (!ne_pci_dev) return -ENOMEM; diff --git a/drivers/virt/vboxguest/vboxguest_core.c b/drivers/virt/vboxguest/vboxguest_core.c index b177a534b6a4..b5dc0d01facd 100644 --- a/drivers/virt/vboxguest/vboxguest_core.c +++ b/drivers/virt/vboxguest/vboxguest_core.c @@ -74,7 +74,7 @@ static void vbg_guest_mappings_init(struct vbg_dev *gdev) /* Add 4M so that we can align the vmap to 4MiB as the host requires. */ size = PAGE_ALIGN(req->hypervisor_size) + SZ_4M; - pages = kmalloc_array(size >> PAGE_SHIFT, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, size >> PAGE_SHIFT); if (!pages) goto out; @@ -275,9 +275,8 @@ static int vbg_balloon_inflate(struct vbg_dev *gdev, u32 chunk_idx) struct page **pages; int i, rc, ret; - pages = kmalloc_array(VMMDEV_MEMORY_BALLOON_CHUNK_PAGES, - sizeof(*pages), - GFP_KERNEL | __GFP_NOWARN); + pages = kmalloc_objs(*pages, VMMDEV_MEMORY_BALLOON_CHUNK_PAGES, + GFP_KERNEL | __GFP_NOWARN); if (!pages) return -ENOMEM; @@ -1081,7 +1080,7 @@ struct vbg_session *vbg_core_open_session(struct vbg_dev *gdev, u32 requestor) { struct vbg_session *session; - session = kzalloc(sizeof(*session), GFP_KERNEL); + session = kzalloc_obj(*session); if (!session) return ERR_PTR(-ENOMEM); diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 4e549abe59ff..d1fbc8fe8470 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c @@ -927,7 +927,7 @@ static int virtballoon_probe(struct virtio_device *vdev) return -EINVAL; } - vdev->priv = vb = kzalloc(sizeof(*vb), GFP_KERNEL); + vdev->priv = vb = kzalloc_obj(*vb); if (!vb) { err = -ENOMEM; goto out; diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c index 74df16677da8..deec24e8e682 100644 --- a/drivers/virtio/virtio_input.c +++ b/drivers/virtio/virtio_input.c @@ -83,7 +83,7 @@ static int virtinput_send_status(struct virtio_input *vi, if (vi->idev->mt && type == EV_MSC && code == MSC_TIMESTAMP) return 0; - stsbuf = kzalloc(sizeof(*stsbuf), GFP_ATOMIC); + stsbuf = kzalloc_obj(*stsbuf, GFP_ATOMIC); if (!stsbuf) return -ENOMEM; @@ -229,7 +229,7 @@ static int virtinput_probe(struct virtio_device *vdev) if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1)) return -ENODEV; - vi = kzalloc(sizeof(*vi), GFP_KERNEL); + vi = kzalloc_obj(*vi); if (!vi) return -ENOMEM; diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c index 1688ecd69a04..48051e9e98ab 100644 --- a/drivers/virtio/virtio_mem.c +++ b/drivers/virtio/virtio_mem.c @@ -2940,7 +2940,7 @@ static int virtio_mem_probe(struct virtio_device *vdev) BUILD_BUG_ON(sizeof(struct virtio_mem_req) != 24); BUILD_BUG_ON(sizeof(struct virtio_mem_resp) != 10); - vdev->priv = vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vdev->priv = vm = kzalloc_obj(*vm); if (!vm) return -ENOMEM; diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index b152a1eca05a..595c2274fbb5 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -575,7 +575,7 @@ static int virtio_mmio_probe(struct platform_device *pdev) unsigned long magic; int rc; - vm_dev = kzalloc(sizeof(*vm_dev), GFP_KERNEL); + vm_dev = kzalloc_obj(*vm_dev); if (!vm_dev) return -ENOMEM; diff --git a/drivers/virtio/virtio_pci_admin_legacy_io.c b/drivers/virtio/virtio_pci_admin_legacy_io.c index 819cfbbc67c3..e3a9d261812a 100644 --- a/drivers/virtio/virtio_pci_admin_legacy_io.c +++ b/drivers/virtio/virtio_pci_admin_legacy_io.c @@ -124,7 +124,7 @@ static int virtio_pci_admin_legacy_io_read(struct pci_dev *pdev, u16 opcode, if (vf_id < 0) return vf_id; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -210,7 +210,7 @@ int virtio_pci_admin_legacy_io_notify_info(struct pci_dev *pdev, if (vf_id < 0) return vf_id; - result = kzalloc(sizeof(*result), GFP_KERNEL); + result = kzalloc_obj(*result); if (!result) return -ENOMEM; diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c index d6d79af44569..da97b6a988de 100644 --- a/drivers/virtio/virtio_pci_common.c +++ b/drivers/virtio/virtio_pci_common.c @@ -134,14 +134,11 @@ static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors, vp_dev->msix_vectors = nvectors; - vp_dev->msix_names = kmalloc_array(nvectors, - sizeof(*vp_dev->msix_names), - GFP_KERNEL); + vp_dev->msix_names = kmalloc_objs(*vp_dev->msix_names, nvectors); if (!vp_dev->msix_names) goto error; vp_dev->msix_affinity_masks - = kcalloc(nvectors, sizeof(*vp_dev->msix_affinity_masks), - GFP_KERNEL); + = kzalloc_objs(*vp_dev->msix_affinity_masks, nvectors); if (!vp_dev->msix_affinity_masks) goto error; for (i = 0; i < nvectors; ++i) @@ -211,7 +208,7 @@ static struct virtqueue *vp_setup_vq(struct virtio_device *vdev, unsigned int in struct virtio_pci_vq_info **p_info) { struct virtio_pci_device *vp_dev = to_vp_device(vdev); - struct virtio_pci_vq_info *info = kmalloc(sizeof *info, GFP_KERNEL); + struct virtio_pci_vq_info *info = kmalloc_obj(*info); struct virtqueue *vq; unsigned long flags; @@ -387,7 +384,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs, bool per_vq_vectors; u16 avq_num = 0; - vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); + vp_dev->vqs = kzalloc_objs(*vp_dev->vqs, nvqs); if (!vp_dev->vqs) return -ENOMEM; @@ -464,7 +461,7 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs, struct virtqueue *vq; u16 avq_num = 0; - vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL); + vp_dev->vqs = kzalloc_objs(*vp_dev->vqs, nvqs); if (!vp_dev->vqs) return -ENOMEM; @@ -686,7 +683,7 @@ static int virtio_pci_probe(struct pci_dev *pci_dev, int rc; /* allocate our structure and fill it out */ - vp_dev = kzalloc(sizeof(struct virtio_pci_device), GFP_KERNEL); + vp_dev = kzalloc_obj(struct virtio_pci_device); if (!vp_dev) return -ENOMEM; diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index dd0e65f71d41..6d8ae2a6a8ca 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -137,11 +137,11 @@ int vp_modern_admin_cmd_exec(struct virtio_device *vdev, if (!virtio_has_feature(vdev, VIRTIO_F_ADMIN_VQ)) return -EOPNOTSUPP; - va_status = kzalloc(sizeof(*va_status), GFP_KERNEL); + va_status = kzalloc_obj(*va_status); if (!va_status) return -ENOMEM; - va_hdr = kzalloc(sizeof(*va_hdr), GFP_KERNEL); + va_hdr = kzalloc_obj(*va_hdr); if (!va_hdr) { ret = -ENOMEM; goto err_alloc; @@ -204,7 +204,7 @@ static void virtio_pci_admin_cmd_list_init(struct virtio_device *virtio_dev) __le64 *data; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return; @@ -246,11 +246,11 @@ virtio_pci_admin_cmd_dev_parts_objects_enable(struct virtio_device *virtio_dev) u16 set_data_size; int ret; - get_data = kzalloc(sizeof(*get_data), GFP_KERNEL); + get_data = kzalloc_obj(*get_data); if (!get_data) return; - result = kzalloc(sizeof(*result), GFP_KERNEL); + result = kzalloc_obj(*result); if (!result) goto end; @@ -310,7 +310,7 @@ static void virtio_pci_admin_cmd_cap_init(struct virtio_device *virtio_dev) struct scatterlist result_sg; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return; @@ -929,7 +929,7 @@ int virtio_pci_admin_mode_set(struct pci_dev *pdev, u8 flags) if (vf_id < 0) return vf_id; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1054,7 +1054,7 @@ int virtio_pci_admin_obj_destroy(struct pci_dev *pdev, u16 obj_type, u32 id) if (obj_type != VIRTIO_RESOURCE_OBJ_DEV_PARTS) return -EINVAL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1109,11 +1109,11 @@ int virtio_pci_admin_dev_parts_metadata_get(struct pci_dev *pdev, u16 obj_type, if (vf_id < 0) return vf_id; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; - result = kzalloc(sizeof(*result), GFP_KERNEL); + result = kzalloc_obj(*result); if (!result) { ret = -ENOMEM; goto end; @@ -1173,7 +1173,7 @@ int virtio_pci_admin_dev_parts_get(struct pci_dev *pdev, u16 obj_type, u32 id, if (vf_id < 0) return vf_id; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 4fe0f78df5ec..335692d41617 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1209,7 +1209,7 @@ static int vring_alloc_state_extra_split(struct vring_virtqueue_split *vring_spl struct vring_desc_extra *extra; u32 num = vring_split->vring.num; - state = kmalloc_array(num, sizeof(struct vring_desc_state_split), GFP_KERNEL); + state = kmalloc_objs(struct vring_desc_state_split, num); if (!state) goto err_state; @@ -1308,7 +1308,7 @@ static struct virtqueue *__vring_new_virtqueue_split(unsigned int index, struct vring_virtqueue *vq; int err; - vq = kmalloc(sizeof(*vq), GFP_KERNEL); + vq = kmalloc_obj(*vq); if (!vq) return NULL; @@ -2349,8 +2349,7 @@ static struct vring_desc_extra *vring_alloc_desc_extra(unsigned int num) struct vring_desc_extra *desc_extra; unsigned int i; - desc_extra = kmalloc_array(num, sizeof(struct vring_desc_extra), - GFP_KERNEL); + desc_extra = kmalloc_objs(struct vring_desc_extra, num); if (!desc_extra) return NULL; @@ -2450,7 +2449,7 @@ static int vring_alloc_state_extra_packed(struct vring_virtqueue_packed *vring_p struct vring_desc_extra *extra; u32 num = vring_packed->vring.num; - state = kmalloc_array(num, sizeof(struct vring_desc_state_packed), GFP_KERNEL); + state = kmalloc_objs(struct vring_desc_state_packed, num); if (!state) goto err_desc_state; @@ -2529,7 +2528,7 @@ static struct virtqueue *__vring_new_virtqueue_packed(unsigned int index, struct vring_virtqueue *vq; int err; - vq = kmalloc(sizeof(*vq), GFP_KERNEL); + vq = kmalloc_obj(*vq); if (!vq) return NULL; diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c index 0a801f67b599..de2af696de6c 100644 --- a/drivers/virtio/virtio_vdpa.c +++ b/drivers/virtio/virtio_vdpa.c @@ -287,7 +287,7 @@ create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) if (!affvecs) return NULL; - masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL); + masks = kzalloc_objs(*masks, nvecs); if (!masks) return NULL; @@ -462,7 +462,7 @@ static int virtio_vdpa_probe(struct vdpa_device *vdpa) struct virtio_vdpa_device *vd_dev, *reg_dev = NULL; int ret = -EINVAL; - vd_dev = kzalloc(sizeof(*vd_dev), GFP_KERNEL); + vd_dev = kzalloc_obj(*vd_dev); if (!vd_dev) return -ENOMEM; diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c index e1cac0730cbb..35e75d07ef5d 100644 --- a/drivers/w1/masters/ds2490.c +++ b/drivers/w1/masters/ds2490.c @@ -1018,7 +1018,7 @@ static int ds_probe(struct usb_interface *intf, struct ds_device *dev; int i, err, alt; - dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL); + dev = kzalloc_obj(struct ds_device); if (!dev) return -ENOMEM; diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 3371d804dc6c..ff61ea4f2030 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c @@ -320,7 +320,7 @@ static int w1_f23_add_slave(struct w1_slave *sl) { struct w1_f23_data *data; - data = kzalloc(sizeof(struct w1_f23_data), GFP_KERNEL); + data = kzalloc_obj(struct w1_f23_data); if (!data) return -ENOMEM; diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c index c577b5973032..3b3c0789e1ad 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c @@ -384,7 +384,7 @@ static int w1_f1C_add_slave(struct w1_slave *sl) struct w1_f1C_data *data = NULL; if (w1_enable_crccheck) { - data = kzalloc(sizeof(struct w1_f1C_data), GFP_KERNEL); + data = kzalloc_obj(struct w1_f1C_data); if (!data) return -ENOMEM; sl->family_data = data; diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 832e3da94b20..d96b224e2215 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -973,8 +973,7 @@ static int w1_therm_add_slave(struct w1_slave *sl) struct w1_therm_family_converter *sl_family_conv; /* Allocate memory */ - sl->family_data = kzalloc(sizeof(struct w1_therm_family_data), - GFP_KERNEL); + sl->family_data = kzalloc_obj(struct w1_therm_family_data); if (!sl->family_data) return -ENOMEM; diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 5f78b0a0b766..486f321eadc8 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -715,7 +715,7 @@ int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) int err; struct w1_netlink_msg msg; - sl = kzalloc(sizeof(struct w1_slave), GFP_KERNEL); + sl = kzalloc_obj(struct w1_slave); if (!sl) { dev_err(&dev->dev, "%s: failed to allocate new slave device.\n", diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index d3b9df7d466b..dc78729ba2a5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1429,14 +1429,6 @@ config ITCO_WDT To compile this driver as a module, choose M here: the module will be called iTCO_wdt. -config ITCO_VENDOR_SUPPORT - bool "Intel TCO Timer/Watchdog Specific Vendor Support" - depends on ITCO_WDT - help - Add vendor specific support to the intel TCO timer based watchdog - devices. At this moment we only have additional support for some - SuperMicro Inc. motherboards. - config IT8712F_WDT tristate "IT8712F (Smart Guardian) Watchdog Timer" depends on (X86 || COMPILE_TEST) && HAS_IOPORT diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index ba52099b1253..d2fb16b9f9ce 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -127,9 +127,6 @@ obj-$(CONFIG_IE6XX_WDT) += ie6xx_wdt.o obj-$(CONFIG_ITCO_WDT) += iTCO_wdt.o obj-$(CONFIG_LENOVO_SE10_WDT) += lenovo_se10_wdt.o obj-$(CONFIG_LENOVO_SE30_WDT) += lenovo_se30_wdt.o -ifeq ($(CONFIG_ITCO_VENDOR_SUPPORT),y) -obj-$(CONFIG_ITCO_WDT) += iTCO_vendor_support.o -endif obj-$(CONFIG_IT8712F_WDT) += it8712f_wdt.o obj-$(CONFIG_IT87_WDT) += it87_wdt.o obj-$(CONFIG_HP_WATCHDOG) += hpwdt.o diff --git a/drivers/watchdog/exar_wdt.c b/drivers/watchdog/exar_wdt.c index c2e3bb08df89..db62c9797406 100644 --- a/drivers/watchdog/exar_wdt.c +++ b/drivers/watchdog/exar_wdt.c @@ -342,7 +342,7 @@ static int __init exar_wdt_register(struct wdt_priv *priv, const int idx) { struct wdt_pdev_node *n; - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) return -ENOMEM; diff --git a/drivers/watchdog/iTCO_vendor.h b/drivers/watchdog/iTCO_vendor.h deleted file mode 100644 index 69e92e692ae0..000000000000 --- a/drivers/watchdog/iTCO_vendor.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* iTCO Vendor Specific Support hooks */ -#ifdef CONFIG_ITCO_VENDOR_SUPPORT -extern int iTCO_vendorsupport; -extern void iTCO_vendor_pre_start(struct resource *, unsigned int); -extern void iTCO_vendor_pre_stop(struct resource *); -extern int iTCO_vendor_check_noreboot_on(void); -#else -#define iTCO_vendorsupport 0 -#define iTCO_vendor_pre_start(acpibase, heartbeat) {} -#define iTCO_vendor_pre_stop(acpibase) {} -#define iTCO_vendor_check_noreboot_on() 1 - /* 1=check noreboot; 0=don't check */ -#endif diff --git a/drivers/watchdog/iTCO_vendor_support.c b/drivers/watchdog/iTCO_vendor_support.c deleted file mode 100644 index cf0eaa04b064..000000000000 --- a/drivers/watchdog/iTCO_vendor_support.c +++ /dev/null @@ -1,216 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * intel TCO vendor specific watchdog driver support - * - * (c) Copyright 2006-2009 Wim Van Sebroeck . - * - * Neither Wim Van Sebroeck nor Iguana vzw. admit liability nor - * provide warranty for any of this software. This material is - * provided "AS-IS" and at no charge. - */ - -/* - * Includes, defines, variables, module parameters, ... - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -/* Module and version information */ -#define DRV_NAME "iTCO_vendor_support" -#define DRV_VERSION "1.04" - -/* Includes */ -#include /* For module specific items */ -#include /* For new moduleparam's */ -#include /* For standard types (like size_t) */ -#include /* For the -ENODEV/... values */ -#include /* For printk/panic/... */ -#include /* For __init/__exit/... */ -#include /* For io-port access */ -#include /* For inb/outb/... */ - -#include "iTCO_vendor.h" - -/* List of vendor support modes */ -/* SuperMicro Pentium 3 Era 370SSE+-OEM1/P3TSSE */ -#define SUPERMICRO_OLD_BOARD 1 -/* SuperMicro Pentium 4 / Xeon 4 / EMT64T Era Systems - no longer supported */ -#define SUPERMICRO_NEW_BOARD 2 -/* Broken BIOS */ -#define BROKEN_BIOS 911 - -int iTCO_vendorsupport; -EXPORT_SYMBOL(iTCO_vendorsupport); - -module_param_named(vendorsupport, iTCO_vendorsupport, int, 0); -MODULE_PARM_DESC(vendorsupport, "iTCO vendor specific support mode, default=" - "0 (none), 1=SuperMicro Pent3, 911=Broken SMI BIOS"); - -/* - * Vendor Specific Support - */ - -/* - * Vendor Support: 1 - * Board: Super Micro Computer Inc. 370SSE+-OEM1/P3TSSE - * iTCO chipset: ICH2 - * - * Code contributed by: R. Seretny - * Documentation obtained by R. Seretny from SuperMicro Technical Support - * - * To enable Watchdog function: - * BIOS setup -> Power -> TCO Logic SMI Enable -> Within5Minutes - * This setting enables SMI to clear the watchdog expired flag. - * If BIOS or CPU fail which may cause SMI hang, then system will - * reboot. When application starts to use watchdog function, - * application has to take over the control from SMI. - * - * For P3TSSE, J36 jumper needs to be removed to enable the Watchdog - * function. - * - * Note: The system will reboot when Expire Flag is set TWICE. - * So, if the watchdog timer is 20 seconds, then the maximum hang - * time is about 40 seconds, and the minimum hang time is about - * 20.6 seconds. - */ - -static void supermicro_old_pre_start(struct resource *smires) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ - val32 = inl(smires->start); - val32 &= 0xffffdfff; /* Turn off SMI clearing watchdog */ - outl(val32, smires->start); /* Needed to activate watchdog */ -} - -static void supermicro_old_pre_stop(struct resource *smires) -{ - unsigned long val32; - - /* Bit 13: TCO_EN -> 1 = Enables the TCO logic to generate SMI# */ - val32 = inl(smires->start); - val32 |= 0x00002000; /* Turn on SMI clearing watchdog */ - outl(val32, smires->start); /* Needed to deactivate watchdog */ -} - -/* - * Vendor Support: 911 - * Board: Some Intel ICHx based motherboards - * iTCO chipset: ICH7+ - * - * Some Intel motherboards have a broken BIOS implementation: i.e. - * the SMI handler clear's the TIMEOUT bit in the TC01_STS register - * and does not reload the time. Thus the TCO watchdog does not reboot - * the system. - * - * These are the conclusions of Andriy Gapon after - * debugging: the SMI handler is quite simple - it tests value in - * TCO1_CNT against 0x800, i.e. checks TCO_TMR_HLT. If the bit is set - * the handler goes into an infinite loop, apparently to allow the - * second timeout and reboot. Otherwise it simply clears TIMEOUT bit - * in TCO1_STS and that's it. - * So the logic seems to be reversed, because it is hard to see how - * TIMEOUT can get set to 1 and SMI generated when TCO_TMR_HLT is set - * (other than a transitional effect). - * - * The only fix found to get the motherboard(s) to reboot is to put - * the glb_smi_en bit to 0. This is a dirty hack that bypasses the - * broken code by disabling Global SMI. - * - * WARNING: globally disabling SMI could possibly lead to dramatic - * problems, especially on laptops! I.e. various ACPI things where - * SMI is used for communication between OS and firmware. - * - * Don't use this fix if you don't need to!!! - */ - -static void broken_bios_start(struct resource *smires) -{ - unsigned long val32; - - val32 = inl(smires->start); - /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# - Bit 0: GBL_SMI_EN -> 0 = No SMI# will be generated by ICH. */ - val32 &= 0xffffdffe; - outl(val32, smires->start); -} - -static void broken_bios_stop(struct resource *smires) -{ - unsigned long val32; - - val32 = inl(smires->start); - /* Bit 13: TCO_EN -> 1 = Enables TCO logic generating an SMI# - Bit 0: GBL_SMI_EN -> 1 = Turn global SMI on again. */ - val32 |= 0x00002001; - outl(val32, smires->start); -} - -/* - * Generic Support Functions - */ - -void iTCO_vendor_pre_start(struct resource *smires, - unsigned int heartbeat) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - supermicro_old_pre_start(smires); - break; - case BROKEN_BIOS: - broken_bios_start(smires); - break; - } -} -EXPORT_SYMBOL(iTCO_vendor_pre_start); - -void iTCO_vendor_pre_stop(struct resource *smires) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - supermicro_old_pre_stop(smires); - break; - case BROKEN_BIOS: - broken_bios_stop(smires); - break; - } -} -EXPORT_SYMBOL(iTCO_vendor_pre_stop); - -int iTCO_vendor_check_noreboot_on(void) -{ - switch (iTCO_vendorsupport) { - case SUPERMICRO_OLD_BOARD: - return 0; - default: - return 1; - } -} -EXPORT_SYMBOL(iTCO_vendor_check_noreboot_on); - -static int __init iTCO_vendor_init_module(void) -{ - if (iTCO_vendorsupport == SUPERMICRO_NEW_BOARD) { - pr_warn("Option vendorsupport=%d is no longer supported, " - "please use the w83627hf_wdt driver instead\n", - SUPERMICRO_NEW_BOARD); - return -EINVAL; - } - pr_info("vendor-support=%d\n", iTCO_vendorsupport); - return 0; -} - -static void __exit iTCO_vendor_exit_module(void) -{ - pr_info("Module Unloaded\n"); -} - -module_init(iTCO_vendor_init_module); -module_exit(iTCO_vendor_exit_module); - -MODULE_AUTHOR("Wim Van Sebroeck , " - "R. Seretny "); -MODULE_DESCRIPTION("Intel TCO Vendor Specific WatchDog Timer Driver Support"); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 4ab3405ef8e6..1dec9cd155b1 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -63,8 +63,6 @@ #include #include -#include "iTCO_vendor.h" - /* Address definitions for the TCO */ /* TCO base address */ #define TCOBASE(p) ((p)->tco_res->start) @@ -283,8 +281,6 @@ static int iTCO_wdt_start(struct watchdog_device *wd_dev) struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); unsigned int val; - iTCO_vendor_pre_start(p->smi_res, wd_dev->timeout); - /* disable chipset's NO_REBOOT bit */ if (p->update_no_reboot_bit(p->no_reboot_priv, false)) { dev_err(wd_dev->parent, "failed to reset NO_REBOOT flag, reboot disabled by hardware/BIOS\n"); @@ -314,8 +310,6 @@ static int iTCO_wdt_stop(struct watchdog_device *wd_dev) struct iTCO_wdt_private *p = watchdog_get_drvdata(wd_dev); unsigned int val; - iTCO_vendor_pre_stop(p->smi_res); - /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ val = inw(TCO1_CNT(p)); val |= 0x0800; @@ -488,8 +482,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) (u64)SMI_EN(p)); return -EBUSY; } - } else if (iTCO_vendorsupport || - turn_SMI_watchdog_clear_off >= p->iTCO_version) { + } else if (turn_SMI_watchdog_clear_off >= p->iTCO_version) { dev_err(dev, "SMI I/O resource is missing\n"); return -ENODEV; } @@ -508,8 +501,7 @@ static int iTCO_wdt_probe(struct platform_device *pdev) } /* Check chipset's NO_REBOOT bit */ - if (p->update_no_reboot_bit(p->no_reboot_priv, false) && - iTCO_vendor_check_noreboot_on()) { + if (p->update_no_reboot_bit(p->no_reboot_priv, false)) { dev_info(dev, "unable to reset NO_REBOOT flag, device disabled by hardware/BIOS\n"); return -ENODEV; /* Cannot reset NO_REBOOT bit */ } diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c index 0f13a3053357..03479110453c 100644 --- a/drivers/watchdog/imx7ulp_wdt.c +++ b/drivers/watchdog/imx7ulp_wdt.c @@ -346,6 +346,7 @@ static int imx7ulp_wdt_probe(struct platform_device *pdev) watchdog_stop_on_reboot(wdog); watchdog_stop_on_unregister(wdog); watchdog_set_drvdata(wdog, imx7ulp_wdt); + watchdog_set_nowayout(wdog, nowayout); imx7ulp_wdt->hw = of_device_get_match_data(dev); ret = imx7ulp_wdt_init(imx7ulp_wdt, wdog->timeout * imx7ulp_wdt->hw->wdog_clock_rate); diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 3b8488c86a2f..1d9f8591f38d 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c @@ -188,6 +188,12 @@ static void _wdt_update_timeout(unsigned int t) superio_outb(t >> 8, WDTVALMSB); } +/* Internal function, should be called after superio_select(GPIO) */ +static bool _wdt_running(void) +{ + return superio_inb(WDTVALLSB) || (max_units > 255 && superio_inb(WDTVALMSB)); +} + static int wdt_update_timeout(unsigned int t) { int ret; @@ -374,6 +380,12 @@ static int __init it87_wdt_init(void) } } + /* wdt already left running by firmware? */ + if (_wdt_running()) { + pr_info("Left running by firmware.\n"); + set_bit(WDOG_HW_RUNNING, &wdt_dev.status); + } + superio_exit(); if (timeout < 1 || timeout > max_units * 60) { diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c index c7a7235e6224..db45b53929a9 100644 --- a/drivers/watchdog/mei_wdt.c +++ b/drivers/watchdog/mei_wdt.c @@ -563,7 +563,7 @@ static int mei_wdt_probe(struct mei_cl_device *cldev, struct mei_wdt *wdt; int ret; - wdt = kzalloc(sizeof(struct mei_wdt), GFP_KERNEL); + wdt = kzalloc_obj(struct mei_wdt); if (!wdt) return -ENOMEM; diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index b636650b714b..d7c18c990649 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c @@ -641,7 +641,7 @@ static int usb_pcwd_probe(struct usb_interface *interface, pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); /* allocate memory for our device and initialize it */ - usb_pcwd = kzalloc(sizeof(struct usb_pcwd_private), GFP_KERNEL); + usb_pcwd = kzalloc_obj(struct usb_pcwd_private); if (usb_pcwd == NULL) goto error; diff --git a/drivers/watchdog/pic32-dmt.c b/drivers/watchdog/pic32-dmt.c index ab0682492c85..12e3a8f63589 100644 --- a/drivers/watchdog/pic32-dmt.c +++ b/drivers/watchdog/pic32-dmt.c @@ -12,12 +12,11 @@ #include #include #include +#include #include #include #include -#include - /* Deadman Timer Regs */ #define DMTCON_REG 0x00 #define DMTPRECLR_REG 0x10 diff --git a/drivers/watchdog/pic32-wdt.c b/drivers/watchdog/pic32-wdt.c index 1d282de312ef..2e7186b85194 100644 --- a/drivers/watchdog/pic32-wdt.c +++ b/drivers/watchdog/pic32-wdt.c @@ -12,12 +12,11 @@ #include #include #include +#include #include #include #include -#include - /* Watchdog Timer Registers */ #define WDTCON_REG 0x00 diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index b774477190b6..e31f93db0509 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -208,11 +208,6 @@ struct s3c2410_wdt { u32 max_cnt; }; -static const struct s3c2410_wdt_variant drv_data_s3c2410 = { - .quirks = 0 -}; - -#ifdef CONFIG_OF static const struct s3c2410_wdt_variant drv_data_s3c6410 = { .quirks = QUIRK_HAS_WTCLRINT_REG, }; @@ -378,8 +373,6 @@ static const struct s3c2410_wdt_variant drv_data_exynosautov920_cl1 = { static const struct of_device_id s3c2410_wdt_match[] = { { .compatible = "google,gs101-wdt", .data = &drv_data_gs101_cl0 }, - { .compatible = "samsung,s3c2410-wdt", - .data = &drv_data_s3c2410 }, { .compatible = "samsung,s3c6410-wdt", .data = &drv_data_s3c6410 }, { .compatible = "samsung,exynos5250-wdt", @@ -399,16 +392,6 @@ static const struct of_device_id s3c2410_wdt_match[] = { {}, }; MODULE_DEVICE_TABLE(of, s3c2410_wdt_match); -#endif - -static const struct platform_device_id s3c2410_wdt_ids[] = { - { - .name = "s3c2410-wdt", - .driver_data = (unsigned long)&drv_data_s3c2410, - }, - {} -}; -MODULE_DEVICE_TABLE(platform, s3c2410_wdt_ids); /* functions */ @@ -720,7 +703,6 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) platform_get_device_id(pdev)->driver_data; } -#ifdef CONFIG_OF /* Choose Exynos850/ExynosAutov9 driver data w.r.t. cluster index */ if (variant == &drv_data_exynos850_cl0 || variant == &drv_data_exynosautov9_cl0 || @@ -756,7 +738,6 @@ s3c2410_get_wdt_drv_data(struct platform_device *pdev, struct s3c2410_wdt *wdt) return dev_err_probe(dev, -EINVAL, "wrong cluster index: %u\n", index); } } -#endif wdt->drv_data = variant; return 0; @@ -949,11 +930,10 @@ static DEFINE_SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, static struct platform_driver s3c2410wdt_driver = { .probe = s3c2410wdt_probe, .shutdown = s3c2410wdt_shutdown, - .id_table = s3c2410_wdt_ids, .driver = { .name = "s3c2410-wdt", .pm = pm_sleep_ptr(&s3c2410wdt_pm_ops), - .of_match_table = of_match_ptr(s3c2410_wdt_match), + .of_match_table = s3c2410_wdt_match, }, }; diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index 6ce1bfb39064..13933e12b754 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c @@ -72,10 +72,10 @@ #define SBSA_GWDT_WCS_WS0 BIT(1) #define SBSA_GWDT_WCS_WS1 BIT(2) -#define SBSA_GWDT_VERSION_MASK 0xF +#define SBSA_GWDT_VERSION_MASK GENMASK(3, 0) #define SBSA_GWDT_VERSION_SHIFT 16 -#define SBSA_GWDT_IMPL_MASK 0x7FF +#define SBSA_GWDT_IMPL_MASK GENMASK(11, 0) #define SBSA_GWDT_IMPL_SHIFT 0 #define SBSA_GWDT_IMPL_MEDIATEK 0x426 diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index ed71d3960a0f..af55adc4a3c6 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -446,7 +446,7 @@ static int starfive_wdt_probe(struct platform_device *pdev) platform_set_drvdata(pdev, wdt); pm_runtime_enable(&pdev->dev); if (pm_runtime_enabled(&pdev->dev)) { - ret = pm_runtime_get_sync(&pdev->dev); + ret = pm_runtime_resume_and_get(&pdev->dev); if (ret < 0) return ret; } else { diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 6152dba4b52c..8300520688d0 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c @@ -117,7 +117,8 @@ static void watchdog_check_min_max_timeout(struct watchdog_device *wdd) * bounds. */ int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev) + unsigned int timeout_parm, + const struct device *dev) { const char *dev_str = wdd->parent ? dev_name(wdd->parent) : (const char *)wdd->info->identity; diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index 8369fd94fc1a..834f65f4b59a 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c @@ -424,20 +424,22 @@ static int watchdog_set_pretimeout(struct watchdog_device *wdd, * * Get the time before a watchdog will reboot (if not pinged). * The caller must hold wd_data->lock. - * - * Return: 0 if successful, error otherwise. */ -static int watchdog_get_timeleft(struct watchdog_device *wdd, - unsigned int *timeleft) +static void watchdog_get_timeleft(struct watchdog_device *wdd, + unsigned int *timeleft) { *timeleft = 0; - if (!wdd->ops->get_timeleft) - return -EOPNOTSUPP; + if (wdd->ops->get_timeleft) { + *timeleft = wdd->ops->get_timeleft(wdd); + } else { + struct watchdog_core_data *wd_data = wdd->wd_data; + s64 last_keepalive_ms = ktime_ms_delta(ktime_get(), wd_data->last_keepalive); + s64 last_keepalive = DIV_ROUND_UP_ULL(last_keepalive_ms, 1000); - *timeleft = wdd->ops->get_timeleft(wdd); - - return 0; + if (wdd->timeout > last_keepalive) + *timeleft = wdd->timeout - last_keepalive; + } } #ifdef CONFIG_WATCHDOG_SYSFS @@ -499,16 +501,13 @@ static ssize_t timeleft_show(struct device *dev, struct device_attribute *attr, { struct watchdog_device *wdd = dev_get_drvdata(dev); struct watchdog_core_data *wd_data = wdd->wd_data; - ssize_t status; unsigned int val; mutex_lock(&wd_data->lock); - status = watchdog_get_timeleft(wdd, &val); + watchdog_get_timeleft(wdd, &val); mutex_unlock(&wd_data->lock); - if (!status) - status = sysfs_emit(buf, "%u\n", val); - return status; + return sysfs_emit(buf, "%u\n", val); } static DEVICE_ATTR_RO(timeleft); @@ -624,9 +623,7 @@ static umode_t wdt_is_visible(struct kobject *kobj, struct attribute *attr, struct watchdog_device *wdd = dev_get_drvdata(dev); umode_t mode = attr->mode; - if (attr == &dev_attr_timeleft.attr && !wdd->ops->get_timeleft) - mode = 0; - else if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) + if (attr == &dev_attr_pretimeout.attr && !watchdog_have_pretimeout(wdd)) mode = 0; else if ((attr == &dev_attr_pretimeout_governor.attr || attr == &dev_attr_pretimeout_available_governors.attr) && @@ -825,9 +822,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, err = put_user(wdd->timeout, p); break; case WDIOC_GETTIMELEFT: - err = watchdog_get_timeleft(wdd, &val); - if (err < 0) - break; + watchdog_get_timeleft(wdd, &val); err = put_user(val, p); break; case WDIOC_SETPRETIMEOUT: @@ -1024,7 +1019,7 @@ static int watchdog_cdev_register(struct watchdog_device *wdd) struct watchdog_core_data *wd_data; int err; - wd_data = kzalloc(sizeof(struct watchdog_core_data), GFP_KERNEL); + wd_data = kzalloc_obj(struct watchdog_core_data); if (!wd_data) return -ENOMEM; mutex_init(&wd_data->lock); diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c index 2526436dc74d..19eb2ed2c7cb 100644 --- a/drivers/watchdog/watchdog_pretimeout.c +++ b/drivers/watchdog/watchdog_pretimeout.c @@ -119,7 +119,7 @@ int watchdog_register_governor(struct watchdog_governor *gov) struct watchdog_pretimeout *p; struct governor_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -183,7 +183,7 @@ int watchdog_register_pretimeout(struct watchdog_device *wdd) if (!watchdog_have_pretimeout(wdd)) return 0; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; diff --git a/drivers/xen/arm-device.c b/drivers/xen/arm-device.c index 87493f92291f..7bc0fc400fd1 100644 --- a/drivers/xen/arm-device.c +++ b/drivers/xen/arm-device.c @@ -59,9 +59,9 @@ static int xen_map_device_mmio(const struct resource *resources, if ((resource_type(r) != IORESOURCE_MEM) || (nr == 0)) continue; - gpfns = kcalloc(nr, sizeof(xen_pfn_t), GFP_KERNEL); - idxs = kcalloc(nr, sizeof(xen_ulong_t), GFP_KERNEL); - errs = kcalloc(nr, sizeof(int), GFP_KERNEL); + gpfns = kzalloc_objs(xen_pfn_t, nr); + idxs = kzalloc_objs(xen_ulong_t, nr); + errs = kzalloc_objs(int, nr); if (!gpfns || !idxs || !errs) { kfree(gpfns); kfree(idxs); diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index 9b6531eb28b6..e7f1d4ca6d75 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -242,7 +242,7 @@ static struct resource *additional_memory_resource(phys_addr_t size) struct resource *res; int ret; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return NULL; diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c index 663df17776fd..bc9a41662efc 100644 --- a/drivers/xen/events/events_base.c +++ b/drivers/xen/events/events_base.c @@ -714,7 +714,7 @@ static struct irq_info *xen_irq_init(unsigned int irq) { struct irq_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (info) { info->irq = irq; info->type = IRQT_UNBOUND; @@ -2292,8 +2292,8 @@ void __init xen_init_IRQ(void) "xen/evtchn:prepare", xen_evtchn_cpu_prepare, xen_evtchn_cpu_dead); - evtchn_to_irq = kcalloc(EVTCHN_ROW(xen_evtchn_max_channels()), - sizeof(*evtchn_to_irq), GFP_KERNEL); + evtchn_to_irq = kzalloc_objs(*evtchn_to_irq, + EVTCHN_ROW(xen_evtchn_max_channels())); BUG_ON(!evtchn_to_irq); /* No event channels are 'live' right now. */ diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index 7e4a13e632dc..b7665bf2774c 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -332,7 +332,7 @@ static int evtchn_resize_ring(struct per_user_data *u) else new_size = 2 * u->ring_size; - new_ring = kvmalloc_array(new_size, sizeof(*new_ring), GFP_KERNEL); + new_ring = kvmalloc_objs(*new_ring, new_size); if (!new_ring) return -ENOMEM; @@ -386,7 +386,7 @@ static int evtchn_bind_to_user(struct per_user_data *u, evtchn_port_t port, * serialized bind operations.) */ - evtchn = kzalloc(sizeof(*evtchn), GFP_KERNEL); + evtchn = kzalloc_obj(*evtchn); if (!evtchn) return -ENOMEM; @@ -642,7 +642,7 @@ static int evtchn_open(struct inode *inode, struct file *filp) { struct per_user_data *u; - u = kzalloc(sizeof(*u), GFP_KERNEL); + u = kzalloc_obj(*u); if (u == NULL) return -ENOMEM; diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c index f93f73ecefee..eadedd1e963e 100644 --- a/drivers/xen/gntalloc.c +++ b/drivers/xen/gntalloc.c @@ -128,7 +128,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op, readonly = !(op->flags & GNTALLOC_FLAG_WRITABLE); for (i = 0; i < op->count; i++) { - gref = kzalloc(sizeof(*gref), GFP_KERNEL); + gref = kzalloc_obj(*gref); if (!gref) { rc = -ENOMEM; goto undo; @@ -229,7 +229,7 @@ static int gntalloc_open(struct inode *inode, struct file *filp) { struct gntalloc_file_private_data *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) goto out_nomem; INIT_LIST_HEAD(&priv->list); @@ -501,7 +501,7 @@ static int gntalloc_mmap(struct file *filp, struct vm_area_struct *vma) return -EINVAL; } - vm_priv = kmalloc(sizeof(*vm_priv), GFP_KERNEL); + vm_priv = kmalloc_obj(*vm_priv); if (!vm_priv) return -ENOMEM; diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c index 550980dd3b0b..83b0df460894 100644 --- a/drivers/xen/gntdev-dmabuf.c +++ b/drivers/xen/gntdev-dmabuf.c @@ -95,7 +95,7 @@ dmabuf_exp_wait_obj_new(struct gntdev_dmabuf_priv *priv, { struct gntdev_dmabuf_wait_obj *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return ERR_PTR(-ENOMEM); @@ -198,7 +198,7 @@ dmabuf_pages_to_sgt(struct page **pages, unsigned int nr_pages) struct sg_table *sgt; int ret; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) { ret = -ENOMEM; goto out; @@ -222,8 +222,7 @@ static int dmabuf_exp_ops_attach(struct dma_buf *dma_buf, { struct gntdev_dmabuf_attachment *gntdev_dmabuf_attach; - gntdev_dmabuf_attach = kzalloc(sizeof(*gntdev_dmabuf_attach), - GFP_KERNEL); + gntdev_dmabuf_attach = kzalloc_obj(*gntdev_dmabuf_attach); if (!gntdev_dmabuf_attach) return -ENOMEM; @@ -363,7 +362,7 @@ static int dmabuf_exp_from_pages(struct gntdev_dmabuf_export_args *args) if (ret < 0) return ret; - gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL); + gntdev_dmabuf = kzalloc_obj(*gntdev_dmabuf); if (!gntdev_dmabuf) return -ENOMEM; @@ -531,13 +530,12 @@ static struct gntdev_dmabuf *dmabuf_imp_alloc_storage(int count) struct gntdev_dmabuf *gntdev_dmabuf; int i; - gntdev_dmabuf = kzalloc(sizeof(*gntdev_dmabuf), GFP_KERNEL); + gntdev_dmabuf = kzalloc_obj(*gntdev_dmabuf); if (!gntdev_dmabuf) goto fail_no_free; - gntdev_dmabuf->u.imp.refs = kcalloc(count, - sizeof(gntdev_dmabuf->u.imp.refs[0]), - GFP_KERNEL); + gntdev_dmabuf->u.imp.refs = kzalloc_objs(gntdev_dmabuf->u.imp.refs[0], + count); if (!gntdev_dmabuf->u.imp.refs) goto fail; @@ -818,7 +816,7 @@ struct gntdev_dmabuf_priv *gntdev_dmabuf_init(struct file *filp) { struct gntdev_dmabuf_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return ERR_PTR(-ENOMEM); diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 2c960f187f7c..61ea855c4508 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -141,19 +141,16 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, struct gntdev_grant_map *add; int i; - add = kzalloc(sizeof(*add), GFP_KERNEL); + add = kzalloc_obj(*add); if (NULL == add) return NULL; - add->grants = kvmalloc_array(count, sizeof(add->grants[0]), - GFP_KERNEL); - add->map_ops = kvmalloc_array(count, sizeof(add->map_ops[0]), - GFP_KERNEL); - add->unmap_ops = kvmalloc_array(count, sizeof(add->unmap_ops[0]), - GFP_KERNEL); - add->pages = kvcalloc(count, sizeof(add->pages[0]), GFP_KERNEL); + add->grants = kvmalloc_objs(add->grants[0], count); + add->map_ops = kvmalloc_objs(add->map_ops[0], count); + add->unmap_ops = kvmalloc_objs(add->unmap_ops[0], count); + add->pages = kvzalloc_objs(add->pages[0], count); add->being_removed = - kvcalloc(count, sizeof(add->being_removed[0]), GFP_KERNEL); + kvzalloc_objs(add->being_removed[0], count); if (NULL == add->grants || NULL == add->map_ops || NULL == add->unmap_ops || @@ -161,10 +158,8 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, NULL == add->being_removed) goto err; if (xen_pv_domain()) { - add->kmap_ops = kvmalloc_array(count, sizeof(add->kmap_ops[0]), - GFP_KERNEL); - add->kunmap_ops = kvmalloc_array(count, sizeof(add->kunmap_ops[0]), - GFP_KERNEL); + add->kmap_ops = kvmalloc_objs(add->kmap_ops[0], count); + add->kunmap_ops = kvmalloc_objs(add->kunmap_ops[0], count); if (NULL == add->kmap_ops || NULL == add->kunmap_ops) goto err; } @@ -179,8 +174,7 @@ struct gntdev_grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count, if (dma_flags & (GNTDEV_DMA_FLAG_WC | GNTDEV_DMA_FLAG_COHERENT)) { struct gnttab_dma_alloc_args args; - add->frames = kvcalloc(count, sizeof(add->frames[0]), - GFP_KERNEL); + add->frames = kvzalloc_objs(add->frames[0], count); if (!add->frames) goto err; @@ -587,7 +581,7 @@ static int gntdev_open(struct inode *inode, struct file *flip) { struct gntdev_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -972,7 +966,7 @@ static long gntdev_ioctl_grant_copy(struct gntdev_priv *priv, void __user *u) mutex_lock(&priv->batch_lock); if (!priv->batch) { - batch = kmalloc(sizeof(*batch), GFP_KERNEL); + batch = kmalloc_obj(*batch); } else { batch = priv->batch; priv->batch = batch->next; diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 3e76e33f6e08..97e27f754d39 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -556,7 +556,7 @@ static void gnttab_add_deferred(grant_ref_t ref, struct page *page) gfp_t gfp = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; uint64_t leaked, deferred; - entry = kmalloc(sizeof(*entry), gfp); + entry = kmalloc_obj(*entry, gfp); if (!page) { unsigned long gfn = gnttab_interface->read_frame(ref); @@ -831,7 +831,7 @@ int gnttab_setup_auto_xlat_frames(phys_addr_t addr) &addr); return -ENOMEM; } - pfn = kcalloc(max_nr_gframes, sizeof(pfn[0]), GFP_KERNEL); + pfn = kzalloc_objs(pfn[0], max_nr_gframes); if (!pfn) { memunmap(vaddr); return -ENOMEM; @@ -868,7 +868,7 @@ int gnttab_pages_set_private(int nr_pages, struct page **pages) #if BITS_PER_LONG < 64 struct xen_page_foreign *foreign; - foreign = kzalloc(sizeof(*foreign), GFP_KERNEL); + foreign = kzalloc_obj(*foreign); if (!foreign) return -ENOMEM; @@ -1635,9 +1635,7 @@ int gnttab_init(void) */ max_nr_glist_frames = max_nr_grefs / RPP; - gnttab_list = kmalloc_array(max_nr_glist_frames, - sizeof(grant_ref_t *), - GFP_KERNEL); + gnttab_list = kmalloc_objs(grant_ref_t *, max_nr_glist_frames); if (gnttab_list == NULL) return -ENOMEM; diff --git a/drivers/xen/mcelog.c b/drivers/xen/mcelog.c index abe658c73b7b..53a8720f5cae 100644 --- a/drivers/xen/mcelog.c +++ b/drivers/xen/mcelog.c @@ -373,8 +373,7 @@ static int bind_virq_for_mce(void) /* Fetch each CPU Physical Info for later reference*/ ncpus = mc_op.u.mc_physcpuinfo.ncpus; - g_physinfo = kcalloc(ncpus, sizeof(struct mcinfo_logical_cpu), - GFP_KERNEL); + g_physinfo = kzalloc_objs(struct mcinfo_logical_cpu, ncpus); if (!g_physinfo) return -ENOMEM; set_xen_guest_handle(mc_op.u.mc_physcpuinfo.info, g_physinfo); diff --git a/drivers/xen/pci.c b/drivers/xen/pci.c index bfe07adb3e3a..385d2587bd1b 100644 --- a/drivers/xen/pci.c +++ b/drivers/xen/pci.c @@ -336,7 +336,7 @@ int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain) { struct xen_device_domain_owner *owner; - owner = kzalloc(sizeof(struct xen_device_domain_owner), GFP_KERNEL); + owner = kzalloc_obj(struct xen_device_domain_owner); if (!owner) return -ENODEV; diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 093ad4a08672..0a20bb7c5438 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c @@ -247,7 +247,7 @@ static struct pcpu *create_and_register_pcpu(struct xenpf_pcpuinfo *info) if (info->flags & XEN_PCPU_FLAGS_INVALID) return ERR_PTR(-ENODEV); - pcpu = kzalloc(sizeof(struct pcpu), GFP_KERNEL); + pcpu = kzalloc_obj(struct pcpu); if (!pcpu) return ERR_PTR(-ENOMEM); diff --git a/drivers/xen/privcmd-buf.c b/drivers/xen/privcmd-buf.c index 0f0dad427d7e..4cb66eb54602 100644 --- a/drivers/xen/privcmd-buf.c +++ b/drivers/xen/privcmd-buf.c @@ -39,7 +39,7 @@ static int privcmd_buf_open(struct inode *ino, struct file *file) { struct privcmd_buf_private *file_priv; - file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL); + file_priv = kzalloc_obj(*file_priv); if (!file_priv) return -ENOMEM; @@ -141,7 +141,7 @@ static int privcmd_buf_mmap(struct file *file, struct vm_area_struct *vma) if (!(vma->vm_flags & VM_SHARED)) return -EINVAL; - vma_priv = kzalloc(struct_size(vma_priv, pages, count), GFP_KERNEL); + vma_priv = kzalloc_flex(*vma_priv, pages, count); if (!vma_priv) return -ENOMEM; diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 402be080ad2c..1759cc18753f 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -433,7 +433,7 @@ static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs) int rc; struct page **pages; - pages = kvcalloc(numpgs, sizeof(pages[0]), GFP_KERNEL); + pages = kvzalloc_objs(pages[0], numpgs); if (pages == NULL) return -ENOMEM; @@ -653,7 +653,7 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata) if (kdata.num > privcmd_dm_op_max_num) return -E2BIG; - kbufs = kcalloc(kdata.num, sizeof(*kbufs), GFP_KERNEL); + kbufs = kzalloc_objs(*kbufs, kdata.num); if (!kbufs) return -ENOMEM; @@ -680,13 +680,13 @@ static long privcmd_ioctl_dm_op(struct file *file, void __user *udata) PAGE_SIZE); } - pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, nr_pages); if (!pages) { rc = -ENOMEM; goto out; } - xbufs = kcalloc(kdata.num, sizeof(*xbufs), GFP_KERNEL); + xbufs = kzalloc_objs(*xbufs, kdata.num); if (!xbufs) { rc = -ENOMEM; goto out; @@ -773,7 +773,7 @@ static long privcmd_ioctl_mmap_resource(struct file *file, goto out; } - pfns = kcalloc(kdata.num, sizeof(*pfns), GFP_KERNEL | __GFP_NOWARN); + pfns = kzalloc_objs(*pfns, kdata.num, GFP_KERNEL | __GFP_NOWARN); if (!pfns) { rc = -ENOMEM; goto out; @@ -1355,7 +1355,7 @@ static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd) if (!ioeventfd->vcpus || ioeventfd->vcpus > 4096) return -EINVAL; - kioeventfd = kzalloc(sizeof(*kioeventfd), GFP_KERNEL); + kioeventfd = kzalloc_obj(*kioeventfd); if (!kioeventfd) return -ENOMEM; @@ -1563,7 +1563,7 @@ static long privcmd_ioctl(struct file *file, static int privcmd_open(struct inode *ino, struct file *file) { - struct privcmd_data *data = kzalloc(sizeof(*data), GFP_KERNEL); + struct privcmd_data *data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/drivers/xen/pvcalls-back.c b/drivers/xen/pvcalls-back.c index c5b6f6fa11eb..ba62651a7f33 100644 --- a/drivers/xen/pvcalls-back.c +++ b/drivers/xen/pvcalls-back.c @@ -324,7 +324,7 @@ static struct sock_mapping *pvcalls_new_active_socket( struct sock_mapping *map; void *page; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { sock_release(sock); return NULL; @@ -632,7 +632,7 @@ static int pvcalls_back_bind(struct xenbus_device *dev, fedata = dev_get_drvdata(&dev->dev); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { ret = -ENOMEM; goto out; @@ -934,7 +934,7 @@ static int backend_connect(struct xenbus_device *dev) grant_ref_t ring_ref; struct pvcalls_fedata *fedata = NULL; - fedata = kzalloc(sizeof(struct pvcalls_fedata), GFP_KERNEL); + fedata = kzalloc_obj(struct pvcalls_fedata); if (!fedata) return -ENOMEM; diff --git a/drivers/xen/pvcalls-front.c b/drivers/xen/pvcalls-front.c index 4926d4badc57..50ce4820f7ee 100644 --- a/drivers/xen/pvcalls-front.c +++ b/drivers/xen/pvcalls-front.c @@ -291,7 +291,7 @@ int pvcalls_front_socket(struct socket *sock) } bedata = dev_get_drvdata(&pvcalls_front_dev->dev); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { pvcalls_exit(); return -ENOMEM; @@ -820,7 +820,7 @@ int pvcalls_front_accept(struct socket *sock, struct socket *newsock, } } - map2 = kzalloc(sizeof(*map2), GFP_KERNEL); + map2 = kzalloc_obj(*map2); if (map2 == NULL) { clear_bit(PVCALLS_FLAG_ACCEPT_INFLIGHT, (void *)&map->passive.flags); @@ -1179,7 +1179,7 @@ static int pvcalls_front_probe(struct xenbus_device *dev, return -ENODEV; pr_info("%s max-page-order is %u\n", __func__, max_page_order); - bedata = kzalloc(sizeof(struct pvcalls_bedata), GFP_KERNEL); + bedata = kzalloc_obj(struct pvcalls_bedata); if (!bedata) return -ENOMEM; diff --git a/drivers/xen/sys-hypervisor.c b/drivers/xen/sys-hypervisor.c index 2f880374b463..b1bb01ba82f8 100644 --- a/drivers/xen/sys-hypervisor.c +++ b/drivers/xen/sys-hypervisor.c @@ -182,7 +182,7 @@ static ssize_t compiler_show(struct hyp_sysfs_attr *attr, char *buffer) int ret = -ENOMEM; struct xen_compile_info *info; - info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); + info = kmalloc_obj(struct xen_compile_info); if (info) { ret = HYPERVISOR_xen_version(XENVER_compile_info, info); if (!ret) @@ -200,7 +200,7 @@ static ssize_t compiled_by_show(struct hyp_sysfs_attr *attr, char *buffer) int ret = -ENOMEM; struct xen_compile_info *info; - info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); + info = kmalloc_obj(struct xen_compile_info); if (info) { ret = HYPERVISOR_xen_version(XENVER_compile_info, info); if (!ret) @@ -218,7 +218,7 @@ static ssize_t compile_date_show(struct hyp_sysfs_attr *attr, char *buffer) int ret = -ENOMEM; struct xen_compile_info *info; - info = kmalloc(sizeof(struct xen_compile_info), GFP_KERNEL); + info = kmalloc_obj(struct xen_compile_info); if (info) { ret = HYPERVISOR_xen_version(XENVER_compile_info, info); if (!ret) @@ -291,7 +291,7 @@ static ssize_t virtual_start_show(struct hyp_sysfs_attr *attr, char *buffer) int ret = -ENOMEM; struct xen_platform_parameters *parms; - parms = kmalloc(sizeof(struct xen_platform_parameters), GFP_KERNEL); + parms = kmalloc_obj(struct xen_platform_parameters); if (parms) { ret = HYPERVISOR_xen_version(XENVER_platform_parameters, parms); diff --git a/drivers/xen/time.c b/drivers/xen/time.c index 0b18d8a5a2dd..a2be0a4d45b0 100644 --- a/drivers/xen/time.c +++ b/drivers/xen/time.c @@ -94,9 +94,8 @@ void xen_manage_runstate_time(int action) pr_warn_once("%s: memory leak as runstate_delta is not NULL\n", __func__); - runstate_delta = kmalloc_array(num_possible_cpus(), - sizeof(*runstate_delta), - GFP_ATOMIC); + runstate_delta = kmalloc_objs(*runstate_delta, + num_possible_cpus(), GFP_ATOMIC); if (unlikely(!runstate_delta)) { pr_warn("%s: failed to allocate runstate_delta\n", __func__); diff --git a/drivers/xen/unpopulated-alloc.c b/drivers/xen/unpopulated-alloc.c index 1dc0b495c8e5..9cdabf18451e 100644 --- a/drivers/xen/unpopulated-alloc.c +++ b/drivers/xen/unpopulated-alloc.c @@ -43,7 +43,7 @@ static int fill_list(unsigned int nr_pages) struct range mhp_range; int ret; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); if (!res) return -ENOMEM; @@ -65,7 +65,7 @@ static int fill_list(unsigned int nr_pages) * re-using it by someone else. */ if (target_resource != &iomem_resource) { - tmp_res = kzalloc(sizeof(*tmp_res), GFP_KERNEL); + tmp_res = kzalloc_obj(*tmp_res); if (!tmp_res) { ret = -ENOMEM; goto err_insert; @@ -84,7 +84,7 @@ static int fill_list(unsigned int nr_pages) } } - pgmap = kzalloc(sizeof(*pgmap), GFP_KERNEL); + pgmap = kzalloc_obj(*pgmap); if (!pgmap) { ret = -ENOMEM; goto err_pgmap; diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index f2e8eaf684ba..897ae2a0b5a0 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -61,8 +61,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) unsigned int i, ok; int ret = 0; - dst_cx_states = kcalloc(_pr->power.count, - sizeof(struct xen_processor_cx), GFP_KERNEL); + dst_cx_states = kzalloc_objs(struct xen_processor_cx, _pr->power.count); if (!dst_cx_states) return -ENOMEM; @@ -142,8 +141,8 @@ xen_copy_pss_data(struct acpi_processor *_pr, BUILD_BUG_ON(sizeof(struct xen_processor_px) != sizeof(struct acpi_processor_px)); - dst_states = kcalloc(_pr->performance->state_count, - sizeof(struct xen_processor_px), GFP_KERNEL); + dst_states = kzalloc_objs(struct xen_processor_px, + _pr->performance->state_count); if (!dst_states) return ERR_PTR(-ENOMEM); @@ -379,11 +378,8 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv) acpi_psd[acpi_id].domain); } - status = acpi_evaluate_object(handle, "_CST", NULL, &buffer); - if (ACPI_FAILURE(status)) { - if (!pblk) - return AE_OK; - } + if (!pblk && !acpi_has_method(handle, "_CST")) + return AE_OK; /* .. and it has a C-state */ __set_bit(acpi_id, acpi_id_cst_present); @@ -412,8 +408,7 @@ static int check_acpi_ids(struct acpi_processor *pr_backup) return -ENOMEM; } - acpi_psd = kcalloc(nr_acpi_bits, sizeof(struct acpi_psd_package), - GFP_KERNEL); + acpi_psd = kzalloc_objs(struct acpi_psd_package, nr_acpi_bits); if (!acpi_psd) { bitmap_free(acpi_id_present); bitmap_free(acpi_id_cst_present); diff --git a/drivers/xen/xen-front-pgdir-shbuf.c b/drivers/xen/xen-front-pgdir-shbuf.c index 223870a0111b..9c7d8af6e6a1 100644 --- a/drivers/xen/xen-front-pgdir-shbuf.c +++ b/drivers/xen/xen-front-pgdir-shbuf.c @@ -205,8 +205,7 @@ static int backend_unmap(struct xen_front_pgdir_shbuf *buf) if (!buf->pages || !buf->backend_map_handles || !buf->grefs) return 0; - unmap_ops = kcalloc(buf->num_pages, sizeof(*unmap_ops), - GFP_KERNEL); + unmap_ops = kzalloc_objs(*unmap_ops, buf->num_pages); if (!unmap_ops) return -ENOMEM; @@ -250,13 +249,12 @@ static int backend_map(struct xen_front_pgdir_shbuf *buf) unsigned char *ptr; int ret, cur_gref, cur_dir_page, cur_page, grefs_left; - map_ops = kcalloc(buf->num_pages, sizeof(*map_ops), GFP_KERNEL); + map_ops = kzalloc_objs(*map_ops, buf->num_pages); if (!map_ops) return -ENOMEM; - buf->backend_map_handles = kcalloc(buf->num_pages, - sizeof(*buf->backend_map_handles), - GFP_KERNEL); + buf->backend_map_handles = kzalloc_objs(*buf->backend_map_handles, + buf->num_pages); if (!buf->backend_map_handles) { kfree(map_ops); return -ENOMEM; @@ -474,7 +472,7 @@ static int grant_references(struct xen_front_pgdir_shbuf *buf) */ static int alloc_storage(struct xen_front_pgdir_shbuf *buf) { - buf->grefs = kcalloc(buf->num_grefs, sizeof(*buf->grefs), GFP_KERNEL); + buf->grefs = kzalloc_objs(*buf->grefs, buf->num_grefs); if (!buf->grefs) return -ENOMEM; diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c index d47eee6c5143..a2ae8de6f9e2 100644 --- a/drivers/xen/xen-pciback/conf_space.c +++ b/drivers/xen/xen-pciback/conf_space.c @@ -401,7 +401,7 @@ int xen_pcibk_config_add_field_offset(struct pci_dev *dev, struct config_field_entry *cfg_entry; void *tmp; - cfg_entry = kmalloc(sizeof(*cfg_entry), GFP_KERNEL); + cfg_entry = kmalloc_obj(*cfg_entry); if (!cfg_entry) { err = -ENOMEM; goto out; diff --git a/drivers/xen/xen-pciback/conf_space_header.c b/drivers/xen/xen-pciback/conf_space_header.c index fc0332645966..8b50cbcbdfe1 100644 --- a/drivers/xen/xen-pciback/conf_space_header.c +++ b/drivers/xen/xen-pciback/conf_space_header.c @@ -33,7 +33,7 @@ struct pci_bar_info { static void *command_init(struct pci_dev *dev, int offset) { - struct pci_cmd_info *cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); + struct pci_cmd_info *cmd = kmalloc_obj(*cmd); int err; if (!cmd) @@ -211,7 +211,7 @@ static void *bar_init(struct pci_dev *dev, int offset) { unsigned int pos; const struct resource *res = dev->resource; - struct pci_bar_info *bar = kzalloc(sizeof(*bar), GFP_KERNEL); + struct pci_bar_info *bar = kzalloc_obj(*bar); if (!bar) return ERR_PTR(-ENOMEM); diff --git a/drivers/xen/xen-pciback/conf_space_quirks.c b/drivers/xen/xen-pciback/conf_space_quirks.c index 7dc281086302..675519b51287 100644 --- a/drivers/xen/xen-pciback/conf_space_quirks.c +++ b/drivers/xen/xen-pciback/conf_space_quirks.c @@ -97,7 +97,7 @@ int xen_pcibk_config_quirks_init(struct pci_dev *dev) struct xen_pcibk_config_quirk *quirk; int ret = 0; - quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); + quirk = kzalloc_obj(*quirk); if (!quirk) { ret = -ENOMEM; goto out; diff --git a/drivers/xen/xen-pciback/passthrough.c b/drivers/xen/xen-pciback/passthrough.c index 66e9b814cc86..7a6df524c071 100644 --- a/drivers/xen/xen-pciback/passthrough.c +++ b/drivers/xen/xen-pciback/passthrough.c @@ -51,7 +51,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, unsigned int domain, bus, devfn; int err; - dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL); + dev_entry = kmalloc_obj(*dev_entry); if (!dev_entry) return -ENOMEM; dev_entry->dev = dev; @@ -101,7 +101,7 @@ static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev) { struct passthrough_dev_data *dev_data; - dev_data = kmalloc(sizeof(*dev_data), GFP_KERNEL); + dev_data = kmalloc_obj(*dev_data); if (!dev_data) return -ENOMEM; diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 045e74847fe6..e4b27aecbf05 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -79,7 +79,7 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) dev_dbg(&dev->dev, "pcistub_device_alloc\n"); - psdev = kzalloc(sizeof(*psdev), GFP_KERNEL); + psdev = kzalloc_obj(*psdev); if (!psdev) return NULL; @@ -623,7 +623,7 @@ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) } if (!match) { - pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); + pci_dev_id = kmalloc_obj(*pci_dev_id); if (!pci_dev_id) { err = -ENOMEM; goto out; @@ -1129,7 +1129,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func) || PCI_FUNC(devfn) != func) return -EINVAL; - pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); + pci_dev_id = kmalloc_obj(*pci_dev_id); if (!pci_dev_id) return -ENOMEM; @@ -1189,7 +1189,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, } dev = psdev->dev; - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) { err = -ENOMEM; goto out; diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 84e014490950..bfc186bf05bc 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -219,7 +219,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev, if (dev->msi_enabled || !(cmd & PCI_COMMAND_MEMORY)) return -ENXIO; - entries = kmalloc_array(op->value, sizeof(*entries), GFP_KERNEL); + entries = kmalloc_objs(*entries, op->value); if (entries == NULL) return -ENOMEM; diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c index cc7450f2b2a9..df292c19effb 100644 --- a/drivers/xen/xen-pciback/vpci.c +++ b/drivers/xen/xen-pciback/vpci.c @@ -81,7 +81,7 @@ static int __xen_pcibk_add_pci_dev(struct xen_pcibk_device *pdev, goto out; } - dev_entry = kmalloc(sizeof(*dev_entry), GFP_KERNEL); + dev_entry = kmalloc_obj(*dev_entry); if (!dev_entry) { err = -ENOMEM; xenbus_dev_fatal(pdev->xdev, err, @@ -186,7 +186,7 @@ static int __xen_pcibk_init_devices(struct xen_pcibk_device *pdev) int slot; struct vpci_dev_data *vpci_dev; - vpci_dev = kmalloc(sizeof(*vpci_dev), GFP_KERNEL); + vpci_dev = kmalloc_obj(*vpci_dev); if (!vpci_dev) return -ENOMEM; diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index b11e401f1b1e..b34785ba72e1 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c @@ -38,7 +38,7 @@ static struct xen_pcibk_device *alloc_pdev(struct xenbus_device *xdev) { struct xen_pcibk_device *pdev; - pdev = kzalloc(sizeof(struct xen_pcibk_device), GFP_KERNEL); + pdev = kzalloc_obj(struct xen_pcibk_device); if (pdev == NULL) goto out; dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev); @@ -149,12 +149,12 @@ static int xen_pcibk_attach(struct xen_pcibk_device *pdev) mutex_lock(&pdev->dev_lock); /* Make sure we only do this setup once */ - if (xenbus_read_driver_state(pdev->xdev->nodename) != + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != XenbusStateInitialised) goto out; /* Wait for frontend to state that it has published the configuration */ - if (xenbus_read_driver_state(pdev->xdev->otherend) != + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->otherend) != XenbusStateInitialised) goto out; @@ -374,7 +374,7 @@ static int xen_pcibk_reconfigure(struct xen_pcibk_device *pdev, dev_dbg(&pdev->xdev->dev, "Reconfiguring device ...\n"); mutex_lock(&pdev->dev_lock); - if (xenbus_read_driver_state(pdev->xdev->nodename) != state) + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != state) goto out; err = xenbus_scanf(XBT_NIL, pdev->xdev->nodename, "num_devs", "%d", @@ -572,7 +572,7 @@ static int xen_pcibk_setup_backend(struct xen_pcibk_device *pdev) /* It's possible we could get the call to setup twice, so make sure * we're not already connected. */ - if (xenbus_read_driver_state(pdev->xdev->nodename) != + if (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename) != XenbusStateInitWait) goto out; @@ -662,7 +662,7 @@ static void xen_pcibk_be_watch(struct xenbus_watch *watch, struct xen_pcibk_device *pdev = container_of(watch, struct xen_pcibk_device, be_watch); - switch (xenbus_read_driver_state(pdev->xdev->nodename)) { + switch (xenbus_read_driver_state(pdev->xdev, pdev->xdev->nodename)) { case XenbusStateInitWait: xen_pcibk_setup_backend(pdev); break; diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c index 7d5117e5efe0..3035c7d0f1b7 100644 --- a/drivers/xen/xen-scsiback.c +++ b/drivers/xen/xen-scsiback.c @@ -543,8 +543,7 @@ static int scsiback_gnttab_data_map(struct vscsiif_request *ring_req, } /* free of (sgl) in fast_flush_area() */ - pending_req->sgl = kmalloc_array(nr_segments, - sizeof(struct scatterlist), GFP_KERNEL); + pending_req->sgl = kmalloc_objs(struct scatterlist, nr_segments); if (!pending_req->sgl) return -ENOMEM; @@ -974,7 +973,7 @@ static int scsiback_add_translation_entry(struct vscsibk_info *info, return -ENODEV; } - new = kmalloc(sizeof(struct v2p_entry), GFP_KERNEL); + new = kmalloc_obj(struct v2p_entry); if (new == NULL) { err = -ENOMEM; goto out_free; @@ -1270,8 +1269,7 @@ static int scsiback_probe(struct xenbus_device *dev, { int err; - struct vscsibk_info *info = kzalloc(sizeof(struct vscsibk_info), - GFP_KERNEL); + struct vscsibk_info *info = kzalloc_obj(struct vscsibk_info); pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); @@ -1352,7 +1350,7 @@ scsiback_make_tport(struct target_fabric_configfs *tf, u64 wwpn = 0; int off = 0; - tport = kzalloc(sizeof(struct scsiback_tport), GFP_KERNEL); + tport = kzalloc_obj(struct scsiback_tport); if (!tport) return ERR_PTR(-ENOMEM); @@ -1532,7 +1530,7 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg, goto out_unlock; } - tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL); + tv_nexus = kzalloc_obj(struct scsiback_nexus); if (!tv_nexus) { ret = -ENOMEM; goto out_unlock; @@ -1759,7 +1757,7 @@ scsiback_make_tpg(struct se_wwn *wwn, const char *name) if (ret) return ERR_PTR(ret); - tpg = kzalloc(sizeof(struct scsiback_tpg), GFP_KERNEL); + tpg = kzalloc_obj(struct scsiback_tpg); if (!tpg) return ERR_PTR(-ENOMEM); diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c index 2dc874fb5506..27682cb5e58a 100644 --- a/drivers/xen/xenbus/xenbus_client.c +++ b/drivers/xen/xenbus/xenbus_client.c @@ -226,8 +226,9 @@ __xenbus_switch_state(struct xenbus_device *dev, struct xenbus_transaction xbt; int current_state; int err, abort; + bool vanished = false; - if (state == dev->state) + if (state == dev->state || dev->vanished) return 0; again: @@ -242,6 +243,10 @@ __xenbus_switch_state(struct xenbus_device *dev, err = xenbus_scanf(xbt, dev->nodename, "state", "%d", ¤t_state); if (err != 1) goto abort; + if (current_state != dev->state && current_state == XenbusStateInitialising) { + vanished = true; + goto abort; + } err = xenbus_printf(xbt, dev->nodename, "state", "%d", state); if (err) { @@ -256,7 +261,7 @@ __xenbus_switch_state(struct xenbus_device *dev, if (err == -EAGAIN && !abort) goto again; xenbus_switch_fatal(dev, depth, err, "ending transaction"); - } else + } else if (!vanished) dev->state = state; return 0; @@ -535,11 +540,11 @@ int xenbus_map_ring_valloc(struct xenbus_device *dev, grant_ref_t *gnt_refs, if (nr_grefs > XENBUS_MAX_RING_GRANTS) return -EINVAL; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; - info->node = kzalloc(sizeof(*info->node), GFP_KERNEL); + info->node = kzalloc_obj(*info->node); if (!info->node) err = -ENOMEM; else @@ -931,14 +936,20 @@ static int xenbus_unmap_ring_hvm(struct xenbus_device *dev, void *vaddr) /** * xenbus_read_driver_state - read state from a store path + * @dev: xenbus device pointer * @path: path for driver * * Returns: the state of the driver rooted at the given store path, or * XenbusStateUnknown if no state can be read. */ -enum xenbus_state xenbus_read_driver_state(const char *path) +enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev, + const char *path) { enum xenbus_state result; + + if (dev && dev->vanished) + return XenbusStateUnknown; + int err = xenbus_gather(XBT_NIL, path, "state", "%d", &result, NULL); if (err) result = XenbusStateUnknown; diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index f5c21ba64df5..61db6932a9d2 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -195,7 +195,7 @@ static int queue_reply(struct list_head *queue, const void *data, size_t len) if (len > XENSTORE_PAYLOAD_MAX) return -EINVAL; - rb = kmalloc(struct_size(rb, msg, len), GFP_KERNEL); + rb = kmalloc_flex(*rb, msg, len); if (rb == NULL) return -ENOMEM; @@ -242,7 +242,7 @@ static struct watch_adapter *alloc_watch_adapter(const char *path, { struct watch_adapter *watch; - watch = kzalloc(sizeof(*watch), GFP_KERNEL); + watch = kzalloc_obj(*watch); if (watch == NULL) goto out_fail; @@ -454,7 +454,7 @@ static int xenbus_write_transaction(unsigned msg_type, } *msg = (void *)u->u.buffer; if (msg_type == XS_TRANSACTION_START) { - trans = kzalloc(sizeof(*trans), GFP_KERNEL); + trans = kzalloc_obj(*trans); if (!trans) { rc = -ENOMEM; goto out; @@ -655,7 +655,7 @@ static int xenbus_file_open(struct inode *inode, struct file *filp) stream_open(inode, filp); - u = kzalloc(sizeof(*u), GFP_KERNEL); + u = kzalloc_obj(*u); if (u == NULL) return -ENOMEM; diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index 9f9011cd7447..eb260eceb4d2 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -191,7 +191,7 @@ void xenbus_otherend_changed(struct xenbus_watch *watch, return; } - state = xenbus_read_driver_state(dev->otherend); + state = xenbus_read_driver_state(dev, dev->otherend); dev_dbg(&dev->dev, "state is %d, (%s), %s, %s\n", state, xenbus_strstate(state), dev->otherend_watch.node, path); @@ -364,7 +364,7 @@ void xenbus_dev_remove(struct device *_dev) * closed. */ if (!drv->allow_rebind || - xenbus_read_driver_state(dev->nodename) == XenbusStateClosing) + xenbus_read_driver_state(dev, dev->nodename) == XenbusStateClosing) xenbus_switch_state(dev, XenbusStateClosed); } EXPORT_SYMBOL_GPL(xenbus_dev_remove); @@ -444,6 +444,9 @@ static void xenbus_cleanup_devices(const char *path, struct bus_type *bus) info.dev = NULL; bus_for_each_dev(bus, NULL, &info, cleanup_dev); if (info.dev) { + dev_warn(&info.dev->dev, + "device forcefully removed from xenstore\n"); + info.dev->vanished = true; device_unregister(&info.dev->dev); put_device(&info.dev->dev); } @@ -514,7 +517,7 @@ int xenbus_probe_node(struct xen_bus_type *bus, size_t stringlen; char *tmpstring; - enum xenbus_state state = xenbus_read_driver_state(nodename); + enum xenbus_state state = xenbus_read_driver_state(NULL, nodename); if (state != XenbusStateInitialising) { /* Device is not new, so ignore it. This can happen if a @@ -659,6 +662,39 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus) return; dev = xenbus_device_find(root, &bus->bus); + /* + * Backend domain crash results in not coordinated frontend removal, + * without going through XenbusStateClosing. If this is a new instance + * of the same device Xen tools will have reset the state to + * XenbusStateInitializing. + * It might be that the backend crashed early during the init phase of + * device setup, in which case the known state would have been + * XenbusStateInitializing. So test the backend domid to match the + * saved one. In case the new backend happens to have the same domid as + * the old one, we can just carry on, as there is no inconsistency + * resulting in this case. + */ + if (dev && !strcmp(bus->root, "device")) { + enum xenbus_state state = xenbus_read_driver_state(dev, dev->nodename); + unsigned int backend = xenbus_read_unsigned(root, "backend-id", + dev->otherend_id); + + if (state == XenbusStateInitialising && + (state != dev->state || backend != dev->otherend_id)) { + /* + * State has been reset, assume the old one vanished + * and new one needs to be probed. + */ + dev_warn(&dev->dev, + "state reset occurred, reconnecting\n"); + dev->vanished = true; + } + if (dev->vanished) { + device_unregister(&dev->dev); + put_device(&dev->dev); + dev = NULL; + } + } if (!dev) xenbus_probe_node(bus, type, root); else diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c index f04707d1f667..ca04609730df 100644 --- a/drivers/xen/xenbus/xenbus_probe_frontend.c +++ b/drivers/xen/xenbus/xenbus_probe_frontend.c @@ -253,7 +253,7 @@ static int print_device_status(struct device *dev, void *data) } else if (xendev->state < XenbusStateConnected) { enum xenbus_state rstate = XenbusStateUnknown; if (xendev->otherend) - rstate = xenbus_read_driver_state(xendev->otherend); + rstate = xenbus_read_driver_state(xendev, xendev->otherend); pr_warn("Timeout connecting to device: %s (local state %d, remote state %d)\n", xendev->nodename, xendev->state, rstate); } diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c index 15f18374020e..82b0a34ded70 100644 --- a/drivers/xen/xenbus/xenbus_xs.c +++ b/drivers/xen/xenbus/xenbus_xs.c @@ -324,7 +324,7 @@ static void *xs_talkv(struct xenbus_transaction t, unsigned int i; int err; - req = kmalloc(sizeof(*req), GFP_NOIO | __GFP_HIGH); + req = kmalloc_obj(*req, GFP_NOIO | __GFP_HIGH); if (!req) return ERR_PTR(-ENOMEM); diff --git a/drivers/xen/xlate_mmu.c b/drivers/xen/xlate_mmu.c index f17c4c03db30..8efd7b55223f 100644 --- a/drivers/xen/xlate_mmu.c +++ b/drivers/xen/xlate_mmu.c @@ -223,11 +223,11 @@ int __init xen_xlate_map_ballooned_pages(xen_pfn_t **gfns, void **virt, BUG_ON(nr_grant_frames == 0); nr_pages = DIV_ROUND_UP(nr_grant_frames, XEN_PFN_PER_PAGE); - pages = kcalloc(nr_pages, sizeof(pages[0]), GFP_KERNEL); + pages = kzalloc_objs(pages[0], nr_pages); if (!pages) return -ENOMEM; - pfns = kcalloc(nr_grant_frames, sizeof(pfns[0]), GFP_KERNEL); + pfns = kzalloc_objs(pfns[0], nr_grant_frames); if (!pfns) { kfree(pages); return -ENOMEM; diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 4e23d53d269e..45495c423c79 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c @@ -135,8 +135,7 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) int error; /* Initialize the Zorro bus */ - bus = kzalloc(struct_size(bus, devices, zorro_num_autocon), - GFP_KERNEL); + bus = kzalloc_flex(*bus, devices, zorro_num_autocon); if (!bus) return -ENOMEM; diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 315336de6f02..0a1c4f7cb001 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -90,7 +90,7 @@ static int v9fs_get_tree(struct fs_context *fc) p9_debug(P9_DEBUG_VFS, "\n"); - v9ses = kzalloc(sizeof(struct v9fs_session_info), GFP_KERNEL); + v9ses = kzalloc_obj(struct v9fs_session_info); if (!v9ses) return -ENOMEM; @@ -308,7 +308,7 @@ static int v9fs_init_fs_context(struct fs_context *fc) { struct v9fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index 4f9dc276da6f..493500f37cb9 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c @@ -108,7 +108,7 @@ int adfs_dir_read_buffers(struct super_block *sb, u32 indaddr, if (dir->bhs != dir->bh) return -EINVAL; - bhs = kcalloc(num, sizeof(*bhs), GFP_KERNEL); + bhs = kzalloc_objs(*bhs, num); if (!bhs) return -ENOMEM; diff --git a/fs/adfs/map.c b/fs/adfs/map.c index a0ce272b4098..9d535a2ca2d1 100644 --- a/fs/adfs/map.c +++ b/fs/adfs/map.c @@ -373,7 +373,7 @@ struct adfs_discmap *adfs_read_map(struct super_block *sb, struct adfs_discrecor ((nzones > 1) ? ADFS_DR_SIZE_BITS : 0); map_addr = signed_asl(map_addr, asb->s_map2blk); - dm = kmalloc_array(nzones, sizeof(*dm), GFP_KERNEL); + dm = kmalloc_objs(*dm, nzones); if (dm == NULL) { adfs_error(sb, "not enough memory"); return ERR_PTR(-ENOMEM); diff --git a/fs/adfs/super.c b/fs/adfs/super.c index fdccdbbfc213..2c5b2076acf9 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -437,7 +437,7 @@ static int adfs_init_fs_context(struct fs_context *fc) { struct adfs_sb_info *asb; - asb = kzalloc(sizeof(struct adfs_sb_info), GFP_KERNEL); + asb = kzalloc_obj(struct adfs_sb_info); if (!asb) return -ENOMEM; diff --git a/fs/affs/dir.c b/fs/affs/dir.c index fe18caaf4d65..5c8d83387a39 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c @@ -36,7 +36,7 @@ static int affs_dir_open(struct inode *inode, struct file *file) { struct affs_dir_data *data; - data = kzalloc(sizeof(struct affs_dir_data), GFP_KERNEL); + data = kzalloc_obj(struct affs_dir_data); if (!data) return -ENOMEM; file->private_data = data; diff --git a/fs/affs/super.c b/fs/affs/super.c index 44f8aa883100..8451647f3fea 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -327,7 +327,7 @@ static int affs_fill_super(struct super_block *sb, struct fs_context *fc) sb->s_time_min = sys_tz.tz_minuteswest * 60 + AFFS_EPOCH_DELTA; sb->s_time_max = 86400LL * U32_MAX + 86400 + sb->s_time_min; - sbi = kzalloc(sizeof(struct affs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct affs_sb_info); if (!sbi) return -ENOMEM; @@ -615,7 +615,7 @@ static int affs_init_fs_context(struct fs_context *fc) { struct affs_context *ctx; - ctx = kzalloc(sizeof(struct affs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct affs_context); if (!ctx) return -ENOMEM; diff --git a/fs/afs/addr_list.c b/fs/afs/addr_list.c index e941da5b6dd9..63bf096b721a 100644 --- a/fs/afs/addr_list.c +++ b/fs/afs/addr_list.c @@ -66,7 +66,7 @@ struct afs_addr_list *afs_alloc_addrlist(unsigned int nr) if (nr > AFS_MAX_ADDRESSES) nr = AFS_MAX_ADDRESSES; - alist = kzalloc(struct_size(alist, addrs, nr), GFP_KERNEL); + alist = kzalloc_flex(*alist, addrs, nr); if (!alist) return NULL; @@ -298,8 +298,8 @@ int afs_merge_fs_addr4(struct afs_net *net, struct afs_addr_list *alist, srx.transport.sin.sin_addr.s_addr = xdr; peer = rxrpc_kernel_lookup_peer(net->socket, &srx, GFP_KERNEL); - if (!peer) - return -ENOMEM; + if (IS_ERR(peer)) + return PTR_ERR(peer); for (i = 0; i < alist->nr_ipv4; i++) { if (peer == alist->addrs[i].peer) { @@ -342,8 +342,8 @@ int afs_merge_fs_addr6(struct afs_net *net, struct afs_addr_list *alist, memcpy(&srx.transport.sin6.sin6_addr, xdr, 16); peer = rxrpc_kernel_lookup_peer(net->socket, &srx, GFP_KERNEL); - if (!peer) - return -ENOMEM; + if (IS_ERR(peer)) + return PTR_ERR(peer); for (i = alist->nr_ipv4; i < alist->nr_addrs; i++) { if (peer == alist->addrs[i].peer) { diff --git a/fs/afs/addr_prefs.c b/fs/afs/addr_prefs.c index 133736412c3d..e8c0640f1c5b 100644 --- a/fs/afs/addr_prefs.c +++ b/fs/afs/addr_prefs.c @@ -401,7 +401,7 @@ int afs_proc_addr_prefs_write(struct file *file, char *buf, size_t size) max_prefs = min_t(size_t, (psize - sizeof(*old)) / sizeof(old->prefs[0]), 255); ret = -ENOMEM; - preflist = kmalloc(struct_size(preflist, prefs, max_prefs), GFP_KERNEL); + preflist = kmalloc_flex(*preflist, prefs, max_prefs); if (!preflist) goto done; diff --git a/fs/afs/cell.c b/fs/afs/cell.c index 71c10a05cebe..9738684dbdd2 100644 --- a/fs/afs/cell.c +++ b/fs/afs/cell.c @@ -134,7 +134,7 @@ static struct afs_cell *afs_alloc_cell(struct afs_net *net, _enter("%*.*s,%s", namelen, namelen, name, addresses); - cell = kzalloc(sizeof(struct afs_cell), GFP_KERNEL); + cell = kzalloc_obj(struct afs_cell); if (!cell) { _leave(" = -ENOMEM"); return ERR_PTR(-ENOMEM); diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c index 1a906805a9e3..5540ae1cad59 100644 --- a/fs/afs/cmservice.c +++ b/fs/afs/cmservice.c @@ -228,9 +228,8 @@ static int afs_deliver_cb_callback(struct afs_call *call) return ret; _debug("unmarshall FID array"); - call->request = kcalloc(call->count, - sizeof(struct afs_callback_break), - GFP_KERNEL); + call->request = kzalloc_objs(struct afs_callback_break, + call->count); if (!call->request) return -ENOMEM; @@ -340,7 +339,7 @@ static int afs_deliver_cb_init_call_back_state3(struct afs_call *call) } _debug("unmarshall UUID"); - call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); + call->request = kmalloc_obj(struct afs_uuid); if (!call->request) return -ENOMEM; @@ -457,7 +456,7 @@ static int afs_deliver_cb_probe_uuid(struct afs_call *call) } _debug("unmarshall UUID"); - call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL); + call->request = kmalloc_obj(struct afs_uuid); if (!call->request) return -ENOMEM; @@ -589,9 +588,8 @@ static int afs_deliver_yfs_cb_callback(struct afs_call *call) return ret; _debug("unmarshall FID array"); - call->request = kcalloc(call->count, - sizeof(struct afs_callback_break), - GFP_KERNEL); + call->request = kzalloc_objs(struct afs_callback_break, + call->count); if (!call->request) return -ENOMEM; diff --git a/fs/afs/dir.c b/fs/afs/dir.c index f4e9e12373ac..78caef3f1338 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c @@ -785,7 +785,7 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry) _enter("{%lu},%p{%pd},", dir->i_ino, dentry, dentry); - cookie = kzalloc(sizeof(struct afs_lookup_cookie), GFP_KERNEL); + cookie = kzalloc_obj(struct afs_lookup_cookie); if (!cookie) return ERR_PTR(-ENOMEM); @@ -834,9 +834,8 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry) /* Need space for examining all the selected files */ if (op->nr_files > 2) { - op->more_files = kvcalloc(op->nr_files - 2, - sizeof(struct afs_vnode_param), - GFP_KERNEL); + op->more_files = kvzalloc_objs(struct afs_vnode_param, + op->nr_files - 2); if (!op->more_files) { afs_op_nomem(op); goto out_op; @@ -2095,7 +2094,7 @@ static int afs_rename(struct mnt_idmap *idmap, struct inode *old_dir, goto error; ret = -ENOMEM; - op->more_files = kvcalloc(2, sizeof(struct afs_vnode_param), GFP_KERNEL); + op->more_files = kvzalloc_objs(struct afs_vnode_param, 2); if (!op->more_files) goto error; diff --git a/fs/afs/dir_silly.c b/fs/afs/dir_silly.c index 014495d4b868..a748fd133faf 100644 --- a/fs/afs/dir_silly.c +++ b/fs/afs/dir_silly.c @@ -69,7 +69,7 @@ static int afs_do_silly_rename(struct afs_vnode *dvnode, struct afs_vnode *vnode if (IS_ERR(op)) return PTR_ERR(op); - op->more_files = kvcalloc(2, sizeof(struct afs_vnode_param), GFP_KERNEL); + op->more_files = kvzalloc_objs(struct afs_vnode_param, 2); if (!op->more_files) { afs_put_operation(op); return -ENOMEM; diff --git a/fs/afs/file.c b/fs/afs/file.c index f66a92294284..f609366fd2ac 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -86,7 +86,7 @@ int afs_cache_wb_key(struct afs_vnode *vnode, struct afs_file *af) { struct afs_wb_key *wbk, *p; - wbk = kzalloc(sizeof(struct afs_wb_key), GFP_KERNEL); + wbk = kzalloc_obj(struct afs_wb_key); if (!wbk) return -ENOMEM; refcount_set(&wbk->usage, 2); @@ -130,7 +130,7 @@ int afs_open(struct inode *inode, struct file *file) goto error; } - af = kzalloc(sizeof(*af), GFP_KERNEL); + af = kzalloc_obj(*af); if (!af) { ret = -ENOMEM; goto error_key; diff --git a/fs/afs/fs_operation.c b/fs/afs/fs_operation.c index 8418813ee043..c0dbbc6d3716 100644 --- a/fs/afs/fs_operation.c +++ b/fs/afs/fs_operation.c @@ -21,7 +21,7 @@ struct afs_operation *afs_alloc_operation(struct key *key, struct afs_volume *vo _enter(""); - op = kzalloc(sizeof(*op), GFP_KERNEL); + op = kzalloc_obj(*op); if (!op) return ERR_PTR(-ENOMEM); diff --git a/fs/afs/fs_probe.c b/fs/afs/fs_probe.c index e0030ac74ea0..a91ad1938d07 100644 --- a/fs/afs/fs_probe.c +++ b/fs/afs/fs_probe.c @@ -244,7 +244,7 @@ int afs_fs_probe_fileserver(struct afs_net *net, struct afs_server *server, _enter("%pU", &server->uuid); - estate = kzalloc(sizeof(*estate), GFP_KERNEL); + estate = kzalloc_obj(*estate); if (!estate) return -ENOMEM; diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c index bc9556991d7c..95494d5f2b8a 100644 --- a/fs/afs/fsclient.c +++ b/fs/afs/fsclient.c @@ -2010,7 +2010,7 @@ static int afs_deliver_fs_fetch_acl(struct afs_call *call) size = call->count2 = ntohl(call->tmp); size = round_up(size, 4); - acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); + acl = kmalloc_flex(*acl, data, size); if (!acl) return -ENOMEM; op->acl = acl; diff --git a/fs/afs/main.c b/fs/afs/main.c index e6bb8237db98..7a883c59976f 100644 --- a/fs/afs/main.c +++ b/fs/afs/main.c @@ -93,7 +93,7 @@ static int __net_init afs_net_init(struct net *net_ns) atomic_set(&net->servers_outstanding, 1); ret = -ENOMEM; - sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); + sysnames = kzalloc_obj(*sysnames); if (!sysnames) goto error_sysnames; sysnames->subs[0] = (char *)&afs_init_sysname; diff --git a/fs/afs/proc.c b/fs/afs/proc.c index 44520549b509..a9cc5cdb4ca2 100644 --- a/fs/afs/proc.c +++ b/fs/afs/proc.c @@ -572,7 +572,7 @@ static int afs_proc_sysname_write(struct file *file, char *buf, size_t size) char *s, *p, *sub; int ret, len; - sysnames = kzalloc(sizeof(*sysnames), GFP_KERNEL); + sysnames = kzalloc_obj(*sysnames); if (!sysnames) return -ENOMEM; refcount_set(&sysnames->usage, 1); diff --git a/fs/afs/rotate.c b/fs/afs/rotate.c index 6a4e7da10fc4..490b433e4395 100644 --- a/fs/afs/rotate.c +++ b/fs/afs/rotate.c @@ -46,8 +46,8 @@ static bool afs_start_fs_iteration(struct afs_operation *op, lockdep_is_held(&op->volume->servers_lock))); read_unlock(&op->volume->servers_lock); - op->server_states = kcalloc(op->server_list->nr_servers, sizeof(op->server_states[0]), - GFP_KERNEL); + op->server_states = kzalloc_objs(op->server_states[0], + op->server_list->nr_servers); if (!op->server_states) { afs_op_nomem(op); trace_afs_rotate(op, afs_rotate_trace_nomem, 0); diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c index bf0e4ea0aafd..588f8de51167 100644 --- a/fs/afs/rxrpc.c +++ b/fs/afs/rxrpc.c @@ -160,7 +160,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net, struct afs_call *call; int o; - call = kzalloc(sizeof(*call), gfp); + call = kzalloc_obj(*call, gfp); if (!call) return NULL; diff --git a/fs/afs/security.c b/fs/afs/security.c index 55ddce94af03..6d00d62a65ed 100644 --- a/fs/afs/security.c +++ b/fs/afs/security.c @@ -252,7 +252,7 @@ void afs_cache_permit(struct afs_vnode *vnode, struct key *key, * yet. */ size++; - new = kzalloc(struct_size(new, permits, size), GFP_NOFS); + new = kzalloc_flex(*new, permits, size, GFP_NOFS); if (!new) goto out_put; diff --git a/fs/afs/server.c b/fs/afs/server.c index c4428ebddb1d..0fe162ea2a36 100644 --- a/fs/afs/server.c +++ b/fs/afs/server.c @@ -117,7 +117,7 @@ static struct afs_server *afs_alloc_server(struct afs_cell *cell, const uuid_t * _enter(""); - server = kzalloc(sizeof(struct afs_server), GFP_KERNEL); + server = kzalloc_obj(struct afs_server); if (!server) return NULL; diff --git a/fs/afs/server_list.c b/fs/afs/server_list.c index 20d5474837df..4178d39b2d60 100644 --- a/fs/afs/server_list.c +++ b/fs/afs/server_list.c @@ -51,7 +51,7 @@ struct afs_server_list *afs_alloc_server_list(struct afs_volume *volume, newrep++; } - slist = kzalloc(struct_size(slist, servers, nr_servers), GFP_KERNEL); + slist = kzalloc_flex(*slist, servers, nr_servers); if (!slist) goto error; diff --git a/fs/afs/super.c b/fs/afs/super.c index d672b7ab57ae..942f3e9800d7 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -502,7 +502,7 @@ static struct afs_super_info *afs_alloc_sbi(struct fs_context *fc) struct afs_fs_context *ctx = fc->fs_private; struct afs_super_info *as; - as = kzalloc(sizeof(struct afs_super_info), GFP_KERNEL); + as = kzalloc_obj(struct afs_super_info); if (as) { as->net_ns = get_net(fc->net_ns); as->flock_mode = ctx->flock_mode; @@ -623,7 +623,7 @@ static int afs_init_fs_context(struct fs_context *fc) struct afs_fs_context *ctx; struct afs_cell *cell; - ctx = kzalloc(sizeof(struct afs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct afs_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/afs/vl_list.c b/fs/afs/vl_list.c index 9b1c20daac53..3e4966915ea4 100644 --- a/fs/afs/vl_list.c +++ b/fs/afs/vl_list.c @@ -15,8 +15,7 @@ struct afs_vlserver *afs_alloc_vlserver(const char *name, size_t name_len, struct afs_vlserver *vlserver; static atomic_t debug_ids; - vlserver = kzalloc(struct_size(vlserver, name, name_len + 1), - GFP_KERNEL); + vlserver = kzalloc_flex(*vlserver, name, name_len + 1); if (vlserver) { refcount_set(&vlserver->ref, 1); rwlock_init(&vlserver->lock); @@ -52,7 +51,7 @@ struct afs_vlserver_list *afs_alloc_vlserver_list(unsigned int nr_servers) { struct afs_vlserver_list *vllist; - vllist = kzalloc(struct_size(vllist, servers, nr_servers), GFP_KERNEL); + vllist = kzalloc_flex(*vllist, servers, nr_servers); if (vllist) { refcount_set(&vllist->ref, 1); rwlock_init(&vllist->lock); diff --git a/fs/afs/vlclient.c b/fs/afs/vlclient.c index 3a23c0b08eb6..a40b43464cfa 100644 --- a/fs/afs/vlclient.c +++ b/fs/afs/vlclient.c @@ -122,7 +122,7 @@ struct afs_vldb_entry *afs_vl_get_entry_by_name_u(struct afs_vl_cursor *vc, padsz = (4 - (volnamesz & 3)) & 3; reqsz = 8 + volnamesz + padsz; - entry = kzalloc(sizeof(struct afs_vldb_entry), GFP_KERNEL); + entry = kzalloc_obj(struct afs_vldb_entry); if (!entry) return ERR_PTR(-ENOMEM); diff --git a/fs/afs/volume.c b/fs/afs/volume.c index 0efff3d25133..9ae5c8ad2e04 100644 --- a/fs/afs/volume.c +++ b/fs/afs/volume.c @@ -81,7 +81,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params, struct afs_volume *volume; int ret = -ENOMEM, i; - volume = kzalloc(sizeof(struct afs_volume), GFP_KERNEL); + volume = kzalloc_obj(struct afs_volume); if (!volume) goto error_0; diff --git a/fs/afs/xattr.c b/fs/afs/xattr.c index e19f396aa370..3770ed236f67 100644 --- a/fs/afs/xattr.c +++ b/fs/afs/xattr.c @@ -75,7 +75,7 @@ static bool afs_make_acl(struct afs_operation *op, { struct afs_acl *acl; - acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); + acl = kmalloc_flex(*acl, data, size); if (!acl) { afs_op_nomem(op); return false; @@ -157,7 +157,7 @@ static int afs_xattr_get_yfs(const struct xattr_handler *handler, else return -EOPNOTSUPP; - yacl = kzalloc(sizeof(struct yfs_acl), GFP_KERNEL); + yacl = kzalloc_obj(struct yfs_acl); if (!yacl) goto error; diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c index febf13a49f0b..24fb562ebd33 100644 --- a/fs/afs/yfsclient.c +++ b/fs/afs/yfsclient.c @@ -2048,7 +2048,7 @@ static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) size = round_up(size, 4); if (yacl->flags & YFS_ACL_WANT_ACL) { - acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); + acl = kmalloc_flex(*acl, data, size); if (!acl) return -ENOMEM; yacl->acl = acl; @@ -2080,7 +2080,7 @@ static int yfs_deliver_fs_fetch_opaque_acl(struct afs_call *call) size = round_up(size, 4); if (yacl->flags & YFS_ACL_WANT_VOL_ACL) { - acl = kmalloc(struct_size(acl, data, size), GFP_KERNEL); + acl = kmalloc_flex(*acl, data, size); if (!acl) return -ENOMEM; yacl->vol_acl = acl; diff --git a/fs/aio.c b/fs/aio.c index 0a23a8c0717f..a07bdd1aaaa6 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -394,7 +394,7 @@ static const struct vm_operations_struct aio_ring_vm_ops = { static int aio_ring_mmap_prepare(struct vm_area_desc *desc) { - desc->vm_flags |= VM_DONTEXPAND; + vma_desc_set_flags(desc, VMA_DONTEXPAND_BIT); desc->vm_ops = &aio_ring_vm_ops; return 0; } @@ -510,8 +510,7 @@ static int aio_setup_ring(struct kioctx *ctx, unsigned int nr_events) ctx->ring_folios = ctx->internal_folios; if (nr_pages > AIO_RING_PAGES) { - ctx->ring_folios = kcalloc(nr_pages, sizeof(struct folio *), - GFP_KERNEL); + ctx->ring_folios = kzalloc_objs(struct folio *, nr_pages); if (!ctx->ring_folios) { put_aio_ring_file(ctx); return -ENOMEM; @@ -693,7 +692,7 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm) new_nr = (table ? table->nr : 1) * 4; spin_unlock(&mm->ioctx_lock); - table = kzalloc(struct_size(table, table, new_nr), GFP_KERNEL); + table = kzalloc_flex(*table, table, new_nr); if (!table) return -ENOMEM; diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index b932b1719dfc..c53dc551053b 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c @@ -13,7 +13,7 @@ struct autofs_info *autofs_new_ino(struct autofs_sb_info *sbi) { struct autofs_info *ino; - ino = kzalloc(sizeof(*ino), GFP_KERNEL); + ino = kzalloc_obj(*ino); if (ino) { INIT_LIST_HEAD(&ino->active); INIT_LIST_HEAD(&ino->expiring); @@ -242,7 +242,7 @@ static struct autofs_sb_info *autofs_alloc_sbi(void) { struct autofs_sb_info *sbi; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return NULL; @@ -405,7 +405,7 @@ int autofs_init_fs_context(struct fs_context *fc) struct autofs_fs_context *ctx; struct autofs_sb_info *sbi; - ctx = kzalloc(sizeof(struct autofs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct autofs_fs_context); if (!ctx) goto nomem; diff --git a/fs/autofs/waitq.c b/fs/autofs/waitq.c index 33dd4660d82f..d46241342dfc 100644 --- a/fs/autofs/waitq.c +++ b/fs/autofs/waitq.c @@ -376,7 +376,7 @@ int autofs_wait(struct autofs_sb_info *sbi, if (!wq) { /* Create a new wait queue */ - wq = kmalloc(sizeof(struct autofs_wait_queue), GFP_KERNEL); + wq = kmalloc_obj(struct autofs_wait_queue); if (!wq) { kfree(name); mutex_unlock(&sbi->wq_mutex); diff --git a/fs/befs/btree.c b/fs/befs/btree.c index 53b36aa29978..aa24f1daccdd 100644 --- a/fs/befs/btree.c +++ b/fs/befs/btree.c @@ -258,8 +258,7 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds, goto error; } - this_node = kmalloc(sizeof(struct befs_btree_node), - GFP_NOFS); + this_node = kmalloc_obj(struct befs_btree_node, GFP_NOFS); if (!this_node) { befs_error(sb, "befs_btree_find() failed to allocate %zu " "bytes of memory", sizeof(struct befs_btree_node)); @@ -431,7 +430,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds, goto error; } - this_node = kmalloc(sizeof(struct befs_btree_node), GFP_NOFS); + this_node = kmalloc_obj(struct befs_btree_node, GFP_NOFS); if (this_node == NULL) { befs_error(sb, "befs_btree_read() failed to allocate %zu " "bytes of memory", sizeof(struct befs_btree_node)); diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index d7c5d9270387..cecbc92f959a 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -790,7 +790,7 @@ befs_fill_super(struct super_block *sb, struct fs_context *fc) struct befs_mount_options *parsed_opts = fc->fs_private; int silent = fc->sb_flags & SB_SILENT; - sb->s_fs_info = kzalloc(sizeof(*befs_sb), GFP_KERNEL); + sb->s_fs_info = kzalloc_obj(*befs_sb); if (sb->s_fs_info == NULL) goto unacquire_none; @@ -956,7 +956,7 @@ static int befs_init_fs_context(struct fs_context *fc) { struct befs_mount_options *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index ce6f83234b67..9da02f5cb6cd 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -334,7 +334,7 @@ static int bfs_fill_super(struct super_block *s, struct fs_context *fc) unsigned long i_sblock, i_eblock, i_eoff, s_size; int silent = fc->sb_flags & SB_SILENT; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; mutex_init(&info->bfs_lock); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 3eb734c192e9..fb857faaf0d6 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -286,7 +287,7 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec, } #ifdef CONFIG_RSEQ NEW_AUX_ENT(AT_RSEQ_FEATURE_SIZE, offsetof(struct rseq, end)); - NEW_AUX_ENT(AT_RSEQ_ALIGN, __alignof__(struct rseq)); + NEW_AUX_ENT(AT_RSEQ_ALIGN, rseq_alloc_align()); #endif #undef NEW_AUX_ENT /* AT_NULL is zero; clear the rest too */ @@ -916,7 +917,7 @@ static int load_elf_binary(struct linux_binprm *bprm) */ would_dump(bprm, interpreter); - interp_elf_ex = kmalloc(sizeof(*interp_elf_ex), GFP_KERNEL); + interp_elf_ex = kmalloc_obj(*interp_elf_ex); if (!interp_elf_ex) { retval = -ENOMEM; goto out_free_file; @@ -1798,7 +1799,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, fill_note(&t->notes[0], PRSTATUS, sizeof(t->prstatus), &t->prstatus); info->size += notesize(&t->notes[0]); - fpu = kzalloc(sizeof(elf_fpregset_t), GFP_KERNEL); + fpu = kzalloc_obj(elf_fpregset_t); if (!fpu || !elf_core_copy_task_fpregs(p, fpu)) { kfree(fpu); return 1; @@ -1824,7 +1825,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, u16 machine; u32 flags; - psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL); + psinfo = kmalloc_obj(*psinfo); if (!psinfo) return 0; fill_note(&info->psinfo, PRPSINFO, sizeof(*psinfo), psinfo); @@ -1873,15 +1874,13 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, /* * Allocate a structure for each thread. */ - info->thread = kzalloc(struct_size(info->thread, notes, info->thread_notes), - GFP_KERNEL); + info->thread = kzalloc_flex(*info->thread, notes, info->thread_notes); if (unlikely(!info->thread)) return 0; info->thread->task = dump_task; for (ct = dump_task->signal->core_state->dumper.next; ct; ct = ct->next) { - t = kzalloc(struct_size(t, notes, info->thread_notes), - GFP_KERNEL); + t = kzalloc_flex(*t, notes, info->thread_notes); if (unlikely(!t)) return 0; @@ -2037,7 +2036,7 @@ static int elf_core_dump(struct coredump_params *cprm) /* For cell spufs and x86 xstate */ sz += elf_coredump_extra_notes_size(); - phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL); + phdr4note = kmalloc_obj(*phdr4note); if (!phdr4note) goto end_coredump; @@ -2052,7 +2051,7 @@ static int elf_core_dump(struct coredump_params *cprm) e_shoff = offset; if (e_phnum == PN_XNUM) { - shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL); + shdr4extnum = kmalloc_obj(*shdr4extnum); if (!shdr4extnum) goto end_coredump; fill_extnum_info(&elf, shdr4extnum, e_shoff, segs); diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 48fd2de3bca0..95b1d0852135 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c @@ -761,7 +761,7 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params, if (nloads == 0) return -ELIBBAD; - loadmap = kzalloc(struct_size(loadmap, segs, nloads), GFP_KERNEL); + loadmap = kzalloc_flex(*loadmap, segs, nloads); if (!loadmap) return -ENOMEM; @@ -1391,7 +1391,7 @@ static struct elf_thread_status *elf_dump_thread_status(long signr, struct task_ struct elf_thread_status *t; int i, ret; - t = kzalloc(sizeof(struct elf_thread_status), GFP_KERNEL); + t = kzalloc_obj(struct elf_thread_status); if (!t) return t; @@ -1486,10 +1486,10 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) struct elf_thread_status *tmp; /* alloc memory for large data structures: too large to be on stack */ - elf = kmalloc(sizeof(*elf), GFP_KERNEL); + elf = kmalloc_obj(*elf); if (!elf) goto end_coredump; - psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL); + psinfo = kmalloc_obj(*psinfo); if (!psinfo) goto end_coredump; @@ -1547,7 +1547,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) offset += segs * sizeof(struct elf_phdr); /* Program headers */ /* Write notes phdr entry */ - phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL); + phdr4note = kmalloc_obj(*phdr4note); if (!phdr4note) goto end_coredump; @@ -1562,7 +1562,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm) e_shoff = offset; if (e_phnum == PN_XNUM) { - shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL); + shdr4extnum = kmalloc_obj(*shdr4extnum); if (!shdr4extnum) goto end_coredump; fill_extnum_info(elf, shdr4extnum, e_shoff, segs); diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index 2b772613a74c..b3d8fd70e8b1 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -961,7 +961,7 @@ static int bm_fill_super(struct super_block *sb, struct fs_context *fc) * create their own separate binfmt_misc mounts we should * consider turning this into a kmem cache. */ - misc = kzalloc(sizeof(struct binfmt_misc), GFP_KERNEL); + misc = kzalloc_obj(struct binfmt_misc); if (!misc) return -ENOMEM; diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 6c6f3bb58f4e..e6f33d09497f 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c @@ -85,7 +85,7 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, const char *name, unsigned int flags, int limit_active, int thresh) { - struct btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL); + struct btrfs_workqueue *ret = kzalloc_obj(*ret); if (!ret) return NULL; @@ -126,7 +126,7 @@ struct btrfs_workqueue *btrfs_alloc_ordered_workqueue( { struct btrfs_workqueue *ret; - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) return NULL; diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 9bb406f7dd30..af98421e7922 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -78,7 +78,7 @@ static int check_extent_in_eb(struct btrfs_backref_walk_ctx *ctx, } add_inode_elem: - e = kmalloc(sizeof(*e), GFP_NOFS); + e = kmalloc_obj(*e, GFP_NOFS); if (!e) return -ENOMEM; @@ -1805,7 +1805,7 @@ struct btrfs_backref_share_check_ctx *btrfs_alloc_backref_share_check_ctx(void) { struct btrfs_backref_share_check_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -2797,7 +2797,7 @@ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, if (IS_ERR(fspath)) return ERR_CAST(fspath); - ifp = kmalloc(sizeof(*ifp), GFP_KERNEL); + ifp = kmalloc_obj(*ifp); if (!ifp) { kvfree(fspath); return ERR_PTR(-ENOMEM); @@ -2814,7 +2814,7 @@ struct btrfs_backref_iter *btrfs_backref_iter_alloc(struct btrfs_fs_info *fs_inf { struct btrfs_backref_iter *ret; - ret = kzalloc(sizeof(*ret), GFP_NOFS); + ret = kzalloc_obj(*ret, GFP_NOFS); if (!ret) return NULL; @@ -3024,7 +3024,7 @@ struct btrfs_backref_node *btrfs_backref_alloc_node( struct btrfs_backref_node *node; ASSERT(level >= 0 && level < BTRFS_MAX_LEVEL); - node = kzalloc(sizeof(*node), GFP_NOFS); + node = kzalloc_obj(*node, GFP_NOFS); if (!node) return node; @@ -3057,7 +3057,7 @@ struct btrfs_backref_edge *btrfs_backref_alloc_edge( { struct btrfs_backref_edge *edge; - edge = kzalloc(sizeof(*edge), GFP_NOFS); + edge = kzalloc_obj(*edge, GFP_NOFS); if (edge) cache->nr_edges++; return edge; diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index 0a69e09bfe28..2a2a21aec817 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -709,7 +709,7 @@ static bool btrfs_wq_submit_bio(struct btrfs_bio *bbio, struct btrfs_fs_info *fs_info = bbio->inode->root->fs_info; struct async_submit_bio *async; - async = kmalloc(sizeof(*async), GFP_NOFS); + async = kmalloc_obj(*async, GFP_NOFS); if (!async) return false; @@ -934,7 +934,6 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 fileoff, struct bio *bio = NULL; int ret = 0; - ASSERT(!(fs_info->sb->s_flags & SB_RDONLY)); BUG_ON(!mirror_num); /* Basic alignment checks. */ @@ -946,6 +945,13 @@ int btrfs_repair_io_failure(struct btrfs_fs_info *fs_info, u64 ino, u64 fileoff, ASSERT(step <= length); ASSERT(is_power_of_2(step)); + /* + * The fs either mounted RO or hit critical errors, no need + * to continue repairing. + */ + if (unlikely(sb_rdonly(fs_info->sb))) + return 0; + if (btrfs_repair_one_zone(fs_info, logical)) return 0; diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c index 3186ed4fd26d..2a886bece810 100644 --- a/fs/btrfs/block-group.c +++ b/fs/btrfs/block-group.c @@ -947,7 +947,7 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait) if (cache->flags & BTRFS_BLOCK_GROUP_REMAPPED) return 0; - caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS); + caching_ctl = kzalloc_obj(*caching_ctl, GFP_NOFS); if (!caching_ctl) return -ENOMEM; @@ -2312,12 +2312,11 @@ static struct btrfs_block_group *btrfs_create_block_group( { struct btrfs_block_group *cache; - cache = kzalloc(sizeof(*cache), GFP_NOFS); + cache = kzalloc_obj(*cache, GFP_NOFS); if (!cache) return NULL; - cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), - GFP_NOFS); + cache->free_space_ctl = kzalloc_obj(*cache->free_space_ctl, GFP_NOFS); if (!cache->free_space_ctl) { kfree(cache); return NULL; @@ -3341,7 +3340,6 @@ static int cache_save_setup(struct btrfs_block_group *block_group, btrfs_abort_transaction(trans, ret); goto out_put; } - WARN_ON(ret); /* We've already setup this transaction, go ahead and exit */ if (block_group->cache_generation == trans->transid && @@ -3760,6 +3758,14 @@ int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans) return ret; } +static void btrfs_maybe_reset_size_class(struct btrfs_block_group *bg) +{ + lockdep_assert_held(&bg->lock); + if (btrfs_block_group_should_use_size_class(bg) && + bg->used == 0 && bg->reserved == 0) + bg->size_class = BTRFS_BG_SZ_NONE; +} + int btrfs_update_block_group(struct btrfs_trans_handle *trans, u64 bytenr, u64 num_bytes, bool alloc) { @@ -3824,6 +3830,7 @@ int btrfs_update_block_group(struct btrfs_trans_handle *trans, old_val -= num_bytes; cache->used = old_val; cache->pinned += num_bytes; + btrfs_maybe_reset_size_class(cache); btrfs_space_info_update_bytes_pinned(space_info, num_bytes); space_info->bytes_used -= num_bytes; space_info->disk_used -= num_bytes * factor; @@ -3952,6 +3959,7 @@ void btrfs_free_reserved_bytes(struct btrfs_block_group *cache, u64 num_bytes, spin_lock(&cache->lock); bg_ro = cache->ro; cache->reserved -= num_bytes; + btrfs_maybe_reset_size_class(cache); if (is_delalloc) cache->delalloc_bytes -= num_bytes; spin_unlock(&cache->lock); diff --git a/fs/btrfs/block-rsv.c b/fs/btrfs/block-rsv.c index e823230c09b7..6064dd00d041 100644 --- a/fs/btrfs/block-rsv.c +++ b/fs/btrfs/block-rsv.c @@ -192,7 +192,7 @@ struct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info, { struct btrfs_block_rsv *block_rsv; - block_rsv = kmalloc(sizeof(*block_rsv), GFP_NOFS); + block_rsv = kmalloc_obj(*block_rsv, GFP_NOFS); if (!block_rsv) return NULL; @@ -276,10 +276,11 @@ u64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info, struct btrfs_block_rsv *target = NULL; /* - * If we are a delayed block reserve then push to the global rsv, - * otherwise dump into the global delayed reserve if it is not full. + * If we are a delayed refs block reserve then push to the global + * reserve, otherwise dump into the global delayed refs reserve if it is + * not full. */ - if (block_rsv->type == BTRFS_BLOCK_RSV_DELOPS) + if (block_rsv->type == BTRFS_BLOCK_RSV_DELREFS) target = global_rsv; else if (block_rsv != global_rsv && !btrfs_block_rsv_full(delayed_rsv)) target = delayed_rsv; diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 1e7174ad32e2..790518a8c803 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -662,7 +662,7 @@ static struct list_head *alloc_heuristic_ws(struct btrfs_fs_info *fs_info) { struct heuristic_ws *ws; - ws = kzalloc(sizeof(*ws), GFP_KERNEL); + ws = kzalloc_obj(*ws); if (!ws) return ERR_PTR(-ENOMEM); @@ -670,11 +670,11 @@ static struct list_head *alloc_heuristic_ws(struct btrfs_fs_info *fs_info) if (!ws->sample) goto fail; - ws->bucket = kcalloc(BUCKET_SIZE, sizeof(*ws->bucket), GFP_KERNEL); + ws->bucket = kzalloc_objs(*ws->bucket, BUCKET_SIZE); if (!ws->bucket) goto fail; - ws->bucket_b = kcalloc(BUCKET_SIZE, sizeof(*ws->bucket_b), GFP_KERNEL); + ws->bucket_b = kzalloc_objs(*ws->bucket_b, BUCKET_SIZE); if (!ws->bucket_b) goto fail; @@ -734,7 +734,7 @@ static int alloc_workspace_manager(struct btrfs_fs_info *fs_info, struct list_head *workspace; ASSERT(fs_info->compr_wsm[type] == NULL); - gwsm = kzalloc(sizeof(*gwsm), GFP_KERNEL); + gwsm = kzalloc_obj(*gwsm); if (!gwsm) return -ENOMEM; diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index ecf05cd64696..7e2db5d3a4d4 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -1091,7 +1091,7 @@ static int defrag_collect_targets(struct btrfs_inode *inode, } /* Allocate new defrag_target_range */ - new = kmalloc(sizeof(*new), GFP_NOFS); + new = kmalloc_obj(*new, GFP_NOFS); if (!new) { btrfs_free_extent_map(em); ret = -ENOMEM; @@ -1206,7 +1206,7 @@ static int defrag_one_range(struct btrfs_inode *inode, u64 start, u32 len, ASSERT(nr_pages <= CLUSTER_SIZE / PAGE_SIZE); ASSERT(IS_ALIGNED(start, sectorsize) && IS_ALIGNED(len, sectorsize)); - folios = kcalloc(nr_pages, sizeof(struct folio *), GFP_NOFS); + folios = kzalloc_objs(struct folio *, nr_pages, GFP_NOFS); if (!folios) return -ENOMEM; diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 1739a0b29c49..56ff8afe9a22 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c @@ -349,7 +349,7 @@ static struct btrfs_delayed_item *btrfs_alloc_delayed_item(u16 data_len, { struct btrfs_delayed_item *item; - item = kmalloc(struct_size(item, data, data_len), GFP_NOFS); + item = kmalloc_flex(*item, data, data_len, GFP_NOFS); if (item) { item->data_len = data_len; item->type = type; @@ -1384,7 +1384,7 @@ static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root, { struct btrfs_async_delayed_work *async_work; - async_work = kmalloc(sizeof(*async_work), GFP_NOFS); + async_work = kmalloc_obj(*async_work, GFP_NOFS); if (!async_work) return -ENOMEM; @@ -1657,7 +1657,7 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, if (unlikely(ret)) { btrfs_err(trans->fs_info, "failed to add delayed dir index item, root: %llu, inode: %llu, index: %llu, error: %d", - index, btrfs_root_id(node->root), node->inode_id, ret); + btrfs_root_id(node->root), node->inode_id, index, ret); btrfs_delayed_item_release_metadata(dir->root, item); btrfs_release_delayed_item(item); } diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index e8bc37453336..3766ff29fbbb 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c @@ -1027,7 +1027,7 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, delayed_refs = &trans->transaction->delayed_refs; if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) { - record = kzalloc(sizeof(*record), GFP_NOFS); + record = kzalloc_obj(*record, GFP_NOFS); if (!record) { ret = -ENOMEM; goto free_head_ref; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 20c405a4789d..407830d86d0d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -605,7 +605,7 @@ static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info, { struct btrfs_root *root; - root = kzalloc(sizeof(*root), flags); + root = kzalloc_obj(*root, flags); if (!root) return NULL; @@ -1994,7 +1994,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, int level = btrfs_super_log_root_level(disk_super); if (unlikely(fs_devices->rw_devices == 0)) { - btrfs_warn(fs_info, "log replay required on RO media"); + btrfs_err(fs_info, "log replay required on RO media"); return -EIO; } @@ -2008,9 +2008,9 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, check.owner_root = BTRFS_TREE_LOG_OBJECTID; log_tree_root->node = read_tree_block(fs_info, bytenr, &check); if (IS_ERR(log_tree_root->node)) { - btrfs_warn(fs_info, "failed to read log tree"); ret = PTR_ERR(log_tree_root->node); log_tree_root->node = NULL; + btrfs_err(fs_info, "failed to read log tree with error: %d", ret); btrfs_put_root(log_tree_root); return ret; } @@ -2023,9 +2023,9 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, /* returns with log_tree_root freed on success */ ret = btrfs_recover_log_trees(log_tree_root); btrfs_put_root(log_tree_root); - if (ret) { - btrfs_handle_fs_error(fs_info, ret, - "Failed to recover log tree"); + if (unlikely(ret)) { + ASSERT(BTRFS_FS_ERROR(fs_info) != 0); + btrfs_err(fs_info, "failed to recover log trees with error: %d", ret); return ret; } @@ -2416,18 +2416,18 @@ int btrfs_validate_super(const struct btrfs_fs_info *fs_info, /* Root alignment check */ if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) { - btrfs_warn(fs_info, "tree_root block unaligned: %llu", - btrfs_super_root(sb)); + btrfs_err(fs_info, "tree_root block unaligned: %llu", + btrfs_super_root(sb)); ret = -EINVAL; } if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) { - btrfs_warn(fs_info, "chunk_root block unaligned: %llu", + btrfs_err(fs_info, "chunk_root block unaligned: %llu", btrfs_super_chunk_root(sb)); ret = -EINVAL; } if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) { - btrfs_warn(fs_info, "log_root block unaligned: %llu", - btrfs_super_log_root(sb)); + btrfs_err(fs_info, "log_root block unaligned: %llu", + btrfs_super_log_root(sb)); ret = -EINVAL; } @@ -2972,7 +2972,6 @@ static int btrfs_check_uuid_tree(struct btrfs_fs_info *fs_info) task = kthread_run(btrfs_uuid_rescan_kthread, fs_info, "btrfs-uuid"); if (IS_ERR(task)) { /* fs_info->update_uuid_tree_gen remains 0 in all error case */ - btrfs_warn(fs_info, "failed to start uuid_rescan task"); up(&fs_info->uuid_tree_rescan_sem); return PTR_ERR(task); } @@ -3188,7 +3187,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount) if (incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP) { btrfs_err(fs_info, "cannot mount because of unknown incompat features (0x%llx)", - incompat); + incompat & ~BTRFS_FEATURE_INCOMPAT_SUPP); return -EINVAL; } @@ -3220,7 +3219,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount) if (compat_ro_unsupp && is_rw_mount) { btrfs_err(fs_info, "cannot mount read-write because of unknown compat_ro features (0x%llx)", - compat_ro); + compat_ro_unsupp); return -EINVAL; } @@ -3233,7 +3232,7 @@ int btrfs_check_features(struct btrfs_fs_info *fs_info, bool is_rw_mount) !btrfs_test_opt(fs_info, NOLOGREPLAY)) { btrfs_err(fs_info, "cannot replay dirty log with unsupported compat_ro features (0x%llx), try rescue=nologreplay", - compat_ro); + compat_ro_unsupp); return -EINVAL; } @@ -3595,7 +3594,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device } } - btrfs_zoned_reserve_data_reloc_bg(fs_info); btrfs_free_zone_cache(fs_info); btrfs_check_active_zone_reservation(fs_info); @@ -3623,6 +3621,12 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device goto fail_cleaner; } + /* + * Starts a transaction, must be called after the transaction kthread + * is initialized. + */ + btrfs_zoned_reserve_data_reloc_bg(fs_info); + ret = btrfs_read_qgroup_config(fs_info); if (ret) goto fail_trans_kthread; @@ -3642,7 +3646,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device fs_info->fs_root = btrfs_get_fs_root(fs_info, BTRFS_FS_TREE_OBJECTID, true); if (IS_ERR(fs_info->fs_root)) { ret = PTR_ERR(fs_info->fs_root); - btrfs_warn(fs_info, "failed to read fs tree: %d", ret); + btrfs_err(fs_info, "failed to read fs tree: %d", ret); fs_info->fs_root = NULL; goto fail_qgroup; } @@ -3663,8 +3667,7 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device btrfs_info(fs_info, "checking UUID tree"); ret = btrfs_check_uuid_tree(fs_info); if (ret) { - btrfs_warn(fs_info, - "failed to check the UUID tree: %d", ret); + btrfs_err(fs_info, "failed to check the UUID tree: %d", ret); close_ctree(fs_info); return ret; } @@ -4399,9 +4402,17 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) */ btrfs_flush_workqueue(fs_info->delayed_workers); - ret = btrfs_commit_super(fs_info); - if (ret) - btrfs_err(fs_info, "commit super ret %d", ret); + /* + * If the filesystem is shutdown, then an attempt to commit the + * super block (or any write) will just fail. Since we freeze + * the filesystem before shutting it down, the filesystem is in + * a consistent state and we don't need to commit super blocks. + */ + if (!btrfs_is_shutdown(fs_info)) { + ret = btrfs_commit_super(fs_info); + if (ret) + btrfs_err(fs_info, "commit super block returned %d", ret); + } } kthread_stop(fs_info->transaction_kthread); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 03cf9f242c70..b0d9baf5b412 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -2933,9 +2933,15 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans) while (!TRANS_ABORTED(trans) && cached_state) { struct extent_state *next_state; - if (btrfs_test_opt(fs_info, DISCARD_SYNC)) + if (btrfs_test_opt(fs_info, DISCARD_SYNC)) { ret = btrfs_discard_extent(fs_info, start, end + 1 - start, NULL, true); + if (ret) { + btrfs_warn(fs_info, + "discard failed for extent [%llu, %llu]: errno=%d %s", + start, end, ret, btrfs_decode_error(ret)); + } + } next_state = btrfs_next_extent_state(unpin, cached_state); btrfs_clear_extent_dirty(unpin, start, end, &cached_state); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 744a1fff6eef..5f97a3d2a8d7 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -4507,6 +4507,7 @@ static int try_release_subpage_extent_buffer(struct folio *folio) */ if (!test_and_clear_bit(EXTENT_BUFFER_TREE_REF, &eb->bflags)) { spin_unlock(&eb->refs_lock); + rcu_read_lock(); break; } diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 73571d5d3d5a..8d05f1a58b7c 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -200,7 +200,7 @@ static inline struct extent_changeset *extent_changeset_alloc(void) { struct extent_changeset *ret; - ret = kmalloc(sizeof(*ret), GFP_KERNEL); + ret = kmalloc_obj(*ret); if (!ret) return NULL; diff --git a/fs/btrfs/fiemap.c b/fs/btrfs/fiemap.c index f2eaaef8422b..27d361c7adc4 100644 --- a/fs/btrfs/fiemap.c +++ b/fs/btrfs/fiemap.c @@ -646,9 +646,8 @@ static int extent_fiemap(struct btrfs_inode *inode, int ret; cache.entries_size = PAGE_SIZE / sizeof(struct btrfs_fiemap_entry); - cache.entries = kmalloc_array(cache.entries_size, - sizeof(struct btrfs_fiemap_entry), - GFP_KERNEL); + cache.entries = kmalloc_objs(struct btrfs_fiemap_entry, + cache.entries_size); backref_ctx = btrfs_alloc_backref_share_check_ctx(); path = btrfs_alloc_path(); if (!cache.entries || !backref_ctx || !path) { diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c index 7bd715442f3e..927324a2175a 100644 --- a/fs/btrfs/file-item.c +++ b/fs/btrfs/file-item.c @@ -845,7 +845,7 @@ int btrfs_csum_one_bio(struct btrfs_bio *bbio, bool async) */ int btrfs_alloc_dummy_sum(struct btrfs_bio *bbio) { - bbio->sums = kmalloc(sizeof(*bbio->sums), GFP_NOFS); + bbio->sums = kmalloc_obj(*bbio->sums, GFP_NOFS); if (!bbio->sums) return -ENOMEM; bbio->sums->len = bbio->bio.bi_iter.bi_size; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index acaa3dbd2b7b..a4cb9d3cfc4e 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2842,7 +2842,7 @@ static int add_falloc_range(struct list_head *head, u64 start, u64 len) } } - range = kmalloc(sizeof(*range), GFP_KERNEL); + range = kmalloc_obj(*range); if (!range) return -ENOMEM; range->start = start; @@ -3572,7 +3572,7 @@ static loff_t find_desired_extent(struct file *file, loff_t offset, int whence) */ private = NULL; } else if (!private) { - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); /* * No worries if memory allocation failed. * The private structure is used only for speeding up multiple diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index cc075a460a22..ab22e4f9ffdd 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -388,7 +388,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, memset(io_ctl, 0, sizeof(struct btrfs_io_ctl)); - io_ctl->pages = kcalloc(num_pages, sizeof(struct page *), GFP_NOFS); + io_ctl->pages = kzalloc_objs(struct page *, num_pages, GFP_NOFS); if (!io_ctl->pages) return -ENOMEM; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 845164485a00..a6da98435ef7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -781,7 +781,7 @@ static int add_async_extent(struct async_chunk *cow, u64 start, u64 ram_size, { struct async_extent *async_extent; - async_extent = kmalloc(sizeof(*async_extent), GFP_NOFS); + async_extent = kmalloc_obj(*async_extent, GFP_NOFS); if (!async_extent) return -ENOMEM; ASSERT(ram_size < U32_MAX); @@ -1392,10 +1392,25 @@ static int cow_one_range(struct btrfs_inode *inode, struct folio *locked_folio, return ret; free_reserved: + /* + * If we have reserved an extent for the current range and failed to + * create the respective extent map or ordered extent, it means that + * when we reserved the extent we decremented the extent's size from + * the data space_info's bytes_may_use counter and + * incremented the space_info's bytes_reserved counter by the same + * amount. + * + * We must make sure extent_clear_unlock_delalloc() does not try + * to decrement again the data space_info's bytes_may_use counter, which + * will be handled by btrfs_free_reserved_extent(). + * + * Therefore we do not pass it the flag EXTENT_CLEAR_DATA_RESV, but only + * EXTENT_CLEAR_META_RESV. + */ extent_clear_unlock_delalloc(inode, file_offset, cur_end, locked_folio, cached, EXTENT_LOCKED | EXTENT_DELALLOC | EXTENT_DELALLOC_NEW | - EXTENT_DEFRAG | EXTENT_DO_ACCOUNTING, + EXTENT_DEFRAG | EXTENT_CLEAR_META_RESV, PAGE_UNLOCK | PAGE_START_WRITEBACK | PAGE_END_WRITEBACK); btrfs_qgroup_free_data(inode, NULL, file_offset, cur_len, NULL); @@ -1692,7 +1707,7 @@ static bool run_delalloc_compressed(struct btrfs_inode *inode, const blk_opf_t write_flags = wbc_to_write_flags(wbc); nofs_flag = memalloc_nofs_save(); - ctx = kvmalloc(struct_size(ctx, chunks, num_chunks), GFP_KERNEL); + ctx = kvmalloc_flex(*ctx, chunks, num_chunks); memalloc_nofs_restore(nofs_flag); if (!ctx) return false; @@ -2991,7 +3006,7 @@ int btrfs_writepage_cow_fixup(struct folio *folio) if (folio_test_checked(folio)) return -EAGAIN; - fixup = kzalloc(sizeof(*fixup), GFP_NOFS); + fixup = kzalloc_obj(*fixup, GFP_NOFS); if (!fixup) return -EAGAIN; @@ -3967,7 +3982,7 @@ static int btrfs_init_file_extent_tree(struct btrfs_inode *inode) if (btrfs_is_free_space_inode(inode)) return 0; - inode->file_extent_tree = kmalloc(sizeof(struct extent_io_tree), GFP_KERNEL); + inode->file_extent_tree = kmalloc_obj(struct extent_io_tree); if (!inode->file_extent_tree) return -ENOMEM; @@ -4764,7 +4779,7 @@ int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry) spin_unlock(&dest->root_item_lock); btrfs_warn(fs_info, "attempt to delete subvolume %llu with active swapfile", - btrfs_root_id(root)); + btrfs_root_id(dest)); ret = -EPERM; goto out_up_write; } @@ -6146,9 +6161,18 @@ static int btrfs_set_inode_index_count(struct btrfs_inode *inode) ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); if (ret < 0) return ret; - /* FIXME: we should be able to handle this */ - if (ret == 0) - return ret; + + if (unlikely(ret == 0)) { + /* + * Key with offset -1 found, there would have to exist a dir + * index item with such offset, but this is out of the valid + * range. + */ + btrfs_err(root->fs_info, + "unexpected exact match for DIR_INDEX key, inode %llu", + btrfs_ino(inode)); + return -EUCLEAN; + } if (path->slots[0] == 0) { inode->index_cnt = BTRFS_DIR_START_INDEX; @@ -6212,7 +6236,7 @@ static int btrfs_opendir(struct inode *inode, struct file *file) if (ret) return ret; - private = kzalloc(sizeof(struct btrfs_file_private), GFP_KERNEL); + private = kzalloc_obj(struct btrfs_file_private); if (!private) return -ENOMEM; private->last_index = last_index; @@ -6588,6 +6612,25 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, int ret; bool xa_reserved = false; + if (!args->orphan && !args->subvol) { + /* + * Before anything else, check if we can add the name to the + * parent directory. We want to avoid a dir item overflow in + * case we have an existing dir item due to existing name + * hash collisions. We do this check here before we call + * btrfs_add_link() down below so that we can avoid a + * transaction abort (which could be exploited by malicious + * users). + * + * For subvolumes we already do this in btrfs_mksubvol(). + */ + ret = btrfs_check_dir_item_collision(BTRFS_I(dir)->root, + btrfs_ino(BTRFS_I(dir)), + name); + if (ret < 0) + return ret; + } + path = btrfs_alloc_path(); if (!path) return -ENOMEM; @@ -8830,7 +8873,7 @@ static struct btrfs_delalloc_work *btrfs_alloc_delalloc_work(struct inode *inode { struct btrfs_delalloc_work *work; - work = kmalloc(sizeof(*work), GFP_NOFS); + work = kmalloc_obj(*work, GFP_NOFS); if (!work) return NULL; @@ -9529,7 +9572,7 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode, * needs longer time span. */ if (uring_ctx) { - priv = kmalloc(sizeof(struct btrfs_encoded_read_private), GFP_NOFS); + priv = kmalloc_obj(struct btrfs_encoded_read_private, GFP_NOFS); if (!priv) return -ENOMEM; } else { @@ -9599,7 +9642,7 @@ ssize_t btrfs_encoded_read_regular(struct kiocb *iocb, struct iov_iter *iter, ssize_t ret; nr_pages = DIV_ROUND_UP(disk_io_size, PAGE_SIZE); - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); + pages = kzalloc_objs(struct page *, nr_pages, GFP_NOFS); if (!pages) return -ENOMEM; ret = btrfs_alloc_page_array(nr_pages, pages, false); @@ -10083,7 +10126,7 @@ static int btrfs_add_swapfile_pin(struct inode *inode, void *ptr, struct rb_node **p; struct rb_node *parent = NULL; - sp = kmalloc(sizeof(*sp), GFP_NOFS); + sp = kmalloc_obj(*sp, GFP_NOFS); if (!sp) return -ENOMEM; sp->ptr = ptr; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index a6cc2d3b414c..b805dd9227ef 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -672,6 +672,13 @@ static noinline int create_subvol(struct mnt_idmap *idmap, goto out; } + /* + * Subvolumes have orphans cleaned on first dentry lookup. A new + * subvolume cannot have any orphans, so we should set the bit before we + * add the subvolume dentry to the dentry cache, so that it is in the + * same state as a subvolume after first lookup. + */ + set_bit(BTRFS_ROOT_ORPHAN_CLEANUP, &new_root->state); d_instantiate_new(dentry, new_inode_args.inode); new_inode_args.inode = NULL; @@ -726,15 +733,14 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, return -ETXTBSY; } - pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_KERNEL); + pending_snapshot = kzalloc_obj(*pending_snapshot); if (!pending_snapshot) return -ENOMEM; ret = get_anon_bdev(&pending_snapshot->anon_dev); if (ret < 0) goto free_pending; - pending_snapshot->root_item = kzalloc(sizeof(struct btrfs_root_item), - GFP_KERNEL); + pending_snapshot->root_item = kzalloc_obj(struct btrfs_root_item); pending_snapshot->path = btrfs_alloc_path(); if (!pending_snapshot->root_item || !pending_snapshot->path) { ret = -ENOMEM; @@ -1958,7 +1964,7 @@ static int btrfs_ioctl_get_subvol_info(struct inode *inode, void __user *argp) if (!path) return -ENOMEM; - subvol_info = kzalloc(sizeof(*subvol_info), GFP_KERNEL); + subvol_info = kzalloc_obj(*subvol_info); if (!subvol_info) { btrfs_free_path(path); return -ENOMEM; @@ -3423,7 +3429,7 @@ static long btrfs_ioctl_balance(struct file *file, void __user *arg) goto out_unlock; } - bctl = kzalloc(sizeof(*bctl), GFP_KERNEL); + bctl = kzalloc_obj(*bctl); if (!bctl) { ret = -ENOMEM; goto out_unlock; @@ -3604,7 +3610,7 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) } if (sa->assign) { - prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL); + prealloc = kzalloc_obj(*prealloc); if (!prealloc) { ret = -ENOMEM; goto out; @@ -3853,6 +3859,25 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, goto out; } + received_uuid_changed = memcmp(root_item->received_uuid, sa->uuid, + BTRFS_UUID_SIZE); + + /* + * Before we attempt to add the new received uuid, check if we have room + * for it in case there's already an item. If the size of the existing + * item plus this root's ID (u64) exceeds the maximum item size, we can + * return here without the need to abort a transaction. If we don't do + * this check, the btrfs_uuid_tree_add() call below would fail with + * -EOVERFLOW and result in a transaction abort. Malicious users could + * exploit this to turn the fs into RO mode. + */ + if (received_uuid_changed && !btrfs_is_empty_uuid(sa->uuid)) { + ret = btrfs_uuid_tree_check_overflow(fs_info, sa->uuid, + BTRFS_UUID_KEY_RECEIVED_SUBVOL); + if (ret < 0) + goto out; + } + /* * 1 - root item * 2 - uuid items (received uuid + subvol uuid) @@ -3868,15 +3893,12 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, sa->rtime.sec = ct.tv_sec; sa->rtime.nsec = ct.tv_nsec; - received_uuid_changed = memcmp(root_item->received_uuid, sa->uuid, - BTRFS_UUID_SIZE); if (received_uuid_changed && !btrfs_is_empty_uuid(root_item->received_uuid)) { ret = btrfs_uuid_tree_remove(trans, root_item->received_uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, btrfs_root_id(root)); if (unlikely(ret && ret != -ENOENT)) { - btrfs_abort_transaction(trans, ret); btrfs_end_transaction(trans); goto out; } @@ -3891,7 +3913,8 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, ret = btrfs_update_root(trans, fs_info->tree_root, &root->root_key, &root->root_item); - if (ret < 0) { + if (unlikely(ret < 0)) { + btrfs_abort_transaction(trans, ret); btrfs_end_transaction(trans); goto out; } @@ -3924,7 +3947,7 @@ static long btrfs_ioctl_set_received_subvol_32(struct file *file, if (IS_ERR(args32)) return PTR_ERR(args32); - args64 = kmalloc(sizeof(*args64), GFP_KERNEL); + args64 = kmalloc_obj(*args64); if (!args64) { ret = -ENOMEM; goto out; @@ -4234,7 +4257,7 @@ static int _btrfs_ioctl_send(struct btrfs_root *root, void __user *argp, bool co ret = copy_from_user(&args32, argp, sizeof(args32)); if (ret) return -EFAULT; - arg = kzalloc(sizeof(*arg), GFP_KERNEL); + arg = kzalloc_obj(*arg); if (!arg) return -ENOMEM; arg->send_fd = args32.send_fd; @@ -4582,13 +4605,13 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, { struct btrfs_inode *inode = BTRFS_I(file_inode(iocb->ki_filp)); struct extent_io_tree *io_tree = &inode->io_tree; - struct page **pages; + struct page **pages = NULL; struct btrfs_uring_priv *priv = NULL; unsigned long nr_pages; int ret; nr_pages = DIV_ROUND_UP(disk_io_size, PAGE_SIZE); - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); + pages = kzalloc_objs(struct page *, nr_pages, GFP_NOFS); if (!pages) return -ENOMEM; ret = btrfs_alloc_page_array(nr_pages, pages, 0); @@ -4597,7 +4620,7 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, goto out_fail; } - priv = kmalloc(sizeof(*priv), GFP_NOFS); + priv = kmalloc_obj(*priv, GFP_NOFS); if (!priv) { ret = -ENOMEM; goto out_fail; @@ -4640,6 +4663,11 @@ static int btrfs_uring_read_extent(struct kiocb *iocb, struct iov_iter *iter, btrfs_unlock_extent(io_tree, start, lockend, &cached_state); btrfs_inode_unlock(inode, BTRFS_ILOCK_SHARED); kfree(priv); + for (int i = 0; i < nr_pages; i++) { + if (pages[i]) + __free_page(pages[i]); + } + kfree(pages); return ret; } @@ -4682,7 +4710,7 @@ static int btrfs_uring_encoded_read(struct io_uring_cmd *cmd, unsigned int issue } if (!data) { - data = kzalloc(sizeof(*data), GFP_NOFS); + data = kzalloc_obj(*data, GFP_NOFS); if (!data) { ret = -ENOMEM; goto out_acct; @@ -4817,7 +4845,7 @@ static int btrfs_uring_encoded_write(struct io_uring_cmd *cmd, unsigned int issu } if (!data) { - data = kzalloc(sizeof(*data), GFP_NOFS); + data = kzalloc_obj(*data, GFP_NOFS); if (!data) { ret = -ENOMEM; goto out_acct; diff --git a/fs/btrfs/lru_cache.c b/fs/btrfs/lru_cache.c index fd88af17d8d9..f5a053b905e1 100644 --- a/fs/btrfs/lru_cache.c +++ b/fs/btrfs/lru_cache.c @@ -111,7 +111,7 @@ int btrfs_lru_cache_store(struct btrfs_lru_cache *cache, struct list_head *head; int ret; - head = kmalloc(sizeof(*head), gfp); + head = kmalloc_obj(*head, gfp); if (!head) return -ENOMEM; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 8e20497afffe..049a940ba449 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -88,7 +88,7 @@ struct list_head *lzo_alloc_workspace(struct btrfs_fs_info *fs_info) { struct workspace *workspace; - workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); + workspace = kzalloc_obj(*workspace); if (!workspace) return ERR_PTR(-ENOMEM); diff --git a/fs/btrfs/messages.h b/fs/btrfs/messages.h index 943e53980945..c8e92efce405 100644 --- a/fs/btrfs/messages.h +++ b/fs/btrfs/messages.h @@ -28,9 +28,6 @@ void _btrfs_printk(const struct btrfs_fs_info *fs_info, unsigned int level, cons #else -#define btrfs_printk_in_rcu(fs_info, level, fmt, args...) \ - btrfs_no_printk(fs_info, fmt, ##args) - #define btrfs_printk_in_rcu(fs_info, level, fmt, args...) \ btrfs_no_printk(fs_info, fmt, ##args) diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index f189bf09ce6a..b7dfe877cf8d 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c @@ -38,6 +38,7 @@ static const struct root_name_map root_map[] = { { BTRFS_BLOCK_GROUP_TREE_OBJECTID, "BLOCK_GROUP_TREE" }, { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }, { BTRFS_RAID_STRIPE_TREE_OBJECTID, "RAID_STRIPE_TREE" }, + { BTRFS_REMAP_TREE_OBJECTID, "REMAP_TREE" }, }; const char *btrfs_root_name(const struct btrfs_key *key, char *buf) @@ -415,6 +416,9 @@ static void key_type_string(const struct btrfs_key *key, char *buf, int buf_size [BTRFS_UUID_KEY_SUBVOL] = "UUID_KEY_SUBVOL", [BTRFS_UUID_KEY_RECEIVED_SUBVOL] = "UUID_KEY_RECEIVED_SUBVOL", [BTRFS_RAID_STRIPE_KEY] = "RAID_STRIPE", + [BTRFS_IDENTITY_REMAP_KEY] = "IDENTITY_REMAP", + [BTRFS_REMAP_KEY] = "REMAP", + [BTRFS_REMAP_BACKREF_KEY] = "REMAP_BACKREF", }; if (key->type == 0 && key->objectid == BTRFS_FREE_SPACE_OBJECTID) @@ -435,6 +439,7 @@ void btrfs_print_leaf(const struct extent_buffer *l) struct btrfs_extent_data_ref *dref; struct btrfs_shared_data_ref *sref; struct btrfs_dev_extent *dev_extent; + struct btrfs_remap_item *remap; struct btrfs_key key; if (!l) @@ -569,6 +574,11 @@ void btrfs_print_leaf(const struct extent_buffer *l) print_raid_stripe_key(l, btrfs_item_size(l, i), btrfs_item_ptr(l, i, struct btrfs_stripe_extent)); break; + case BTRFS_REMAP_KEY: + case BTRFS_REMAP_BACKREF_KEY: + remap = btrfs_item_ptr(l, i, struct btrfs_remap_item); + pr_info("\t\taddress %llu\n", btrfs_remap_address(l, remap)); + break; } } } diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index f53c313ab6e4..3b2a6517d0b5 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c @@ -370,7 +370,7 @@ static bool squota_check_parent_usage(struct btrfs_fs_info *fs_info, struct btrf nr_members++; } mismatch = (parent->excl != excl_sum || parent->rfer != rfer_sum || - parent->excl_cmpr != excl_cmpr_sum || parent->rfer_cmpr != excl_cmpr_sum); + parent->excl_cmpr != excl_cmpr_sum || parent->rfer_cmpr != rfer_cmpr_sum); WARN(mismatch, "parent squota qgroup %hu/%llu has mismatched usage from its %d members. " @@ -495,7 +495,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info) struct btrfs_qgroup *prealloc; struct btrfs_root *tree_root = fs_info->tree_root; - prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL); + prealloc = kzalloc_obj(*prealloc); if (!prealloc) { ret = -ENOMEM; goto out; @@ -585,7 +585,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info) goto next2; } - list = kzalloc(sizeof(*list), GFP_KERNEL); + list = kzalloc_obj(*list); if (!list) { ret = -ENOMEM; goto out; @@ -1140,7 +1140,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, /* We should not have a stray @prealloc pointer. */ ASSERT(prealloc == NULL); - prealloc = kzalloc(sizeof(*prealloc), GFP_NOFS); + prealloc = kzalloc_obj(*prealloc, GFP_NOFS); if (unlikely(!prealloc)) { ret = -ENOMEM; btrfs_abort_transaction(trans, ret); @@ -1169,11 +1169,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, } if (ret > 0) { /* - * Shouldn't happen, but in case it does we - * don't need to do the btrfs_next_item, just - * continue. + * Shouldn't happen because the key should still + * be there (return 0), but in case it does it + * means we have reached the end of the tree - + * there are no more leaves with items that have + * a key greater than or equals to @found_key, + * so just stop the search loop. */ - continue; + break; } } ret = btrfs_next_item(tree_root, path); @@ -1194,7 +1197,7 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, } ASSERT(prealloc == NULL); - prealloc = kzalloc(sizeof(*prealloc), GFP_NOFS); + prealloc = kzalloc_obj(*prealloc, GFP_NOFS); if (!prealloc) { ret = -ENOMEM; goto out_free_path; @@ -1690,7 +1693,7 @@ int btrfs_create_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid) goto out; } - prealloc = kzalloc(sizeof(*prealloc), GFP_NOFS); + prealloc = kzalloc_obj(*prealloc, GFP_NOFS); if (!prealloc) { ret = -ENOMEM; goto out; @@ -2144,7 +2147,7 @@ int btrfs_qgroup_trace_extent(struct btrfs_trans_handle *trans, u64 bytenr, if (!btrfs_qgroup_full_accounting(fs_info) || bytenr == 0 || num_bytes == 0) return 0; - record = kzalloc(sizeof(*record), GFP_NOFS); + record = kzalloc_obj(*record, GFP_NOFS); if (!record) return -ENOMEM; @@ -3343,7 +3346,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, if (!btrfs_qgroup_enabled(fs_info)) return 0; - prealloc = kzalloc(sizeof(*prealloc), GFP_NOFS); + prealloc = kzalloc_obj(*prealloc, GFP_NOFS); if (!prealloc) return -ENOMEM; @@ -3425,16 +3428,15 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, } ret = 0; - qlist_prealloc = kcalloc(inherit->num_qgroups, - sizeof(struct btrfs_qgroup_list *), - GFP_NOFS); + qlist_prealloc = kzalloc_objs(struct btrfs_qgroup_list *, + inherit->num_qgroups, GFP_NOFS); if (!qlist_prealloc) { ret = -ENOMEM; goto out; } for (int i = 0; i < inherit->num_qgroups; i++) { - qlist_prealloc[i] = kzalloc(sizeof(struct btrfs_qgroup_list), - GFP_NOFS); + qlist_prealloc[i] = kzalloc_obj(struct btrfs_qgroup_list, + GFP_NOFS); if (!qlist_prealloc[i]) { ret = -ENOMEM; goto out; @@ -4750,7 +4752,7 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_root *subvol_root, return -EUCLEAN; } - block = kmalloc(sizeof(*block), GFP_NOFS); + block = kmalloc_obj(*block, GFP_NOFS); if (!block) { ret = -ENOMEM; goto out; diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index baadaaa189c0..b4511f560e92 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -208,7 +208,7 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info) * Try harder to allocate and fallback to vmalloc to lower the chance * of a failing mount. */ - table = kvzalloc(struct_size(table, table, num_entries), GFP_KERNEL); + table = kvzalloc_flex(*table, table, num_entries); if (!table) return -ENOMEM; @@ -1090,13 +1090,15 @@ static struct btrfs_raid_bio *alloc_rbio(struct btrfs_fs_info *fs_info, ASSERT(real_stripes >= 2); ASSERT(real_stripes <= U8_MAX); - rbio = kzalloc(sizeof(*rbio), GFP_NOFS); + rbio = kzalloc_obj(*rbio, GFP_NOFS); if (!rbio) return ERR_PTR(-ENOMEM); - rbio->stripe_pages = kcalloc(num_pages, sizeof(struct page *), - GFP_NOFS); - rbio->bio_paddrs = kcalloc(num_sectors * sector_nsteps, sizeof(phys_addr_t), GFP_NOFS); - rbio->stripe_paddrs = kcalloc(num_sectors * sector_nsteps, sizeof(phys_addr_t), GFP_NOFS); + rbio->stripe_pages = kzalloc_objs(struct page *, num_pages, GFP_NOFS); + rbio->bio_paddrs = kzalloc_objs(phys_addr_t, + num_sectors * sector_nsteps, GFP_NOFS); + rbio->stripe_paddrs = kzalloc_objs(phys_addr_t, + num_sectors * sector_nsteps, + GFP_NOFS); rbio->finish_pointers = kcalloc(real_stripes, sizeof(void *), GFP_NOFS); rbio->error_bitmap = bitmap_zalloc(num_sectors, GFP_NOFS); rbio->stripe_uptodate_bitmap = bitmap_zalloc(num_sectors, GFP_NOFS); diff --git a/fs/btrfs/ref-verify.c b/fs/btrfs/ref-verify.c index e9224145d754..f78369ff2a66 100644 --- a/fs/btrfs/ref-verify.c +++ b/fs/btrfs/ref-verify.c @@ -249,8 +249,8 @@ static struct block_entry *add_block_entry(struct btrfs_fs_info *fs_info, struct block_entry *be = NULL, *exist; struct root_entry *re = NULL; - re = kzalloc(sizeof(struct root_entry), GFP_NOFS); - be = kzalloc(sizeof(struct block_entry), GFP_NOFS); + re = kzalloc_obj(struct root_entry, GFP_NOFS); + be = kzalloc_obj(struct block_entry, GFP_NOFS); if (!be || !re) { kfree(re); kfree(be); @@ -298,7 +298,7 @@ static int add_tree_block(struct btrfs_fs_info *fs_info, u64 ref_root, struct root_entry *re; struct ref_entry *ref = NULL, *exist; - ref = kmalloc(sizeof(struct ref_entry), GFP_NOFS); + ref = kmalloc_obj(struct ref_entry, GFP_NOFS); if (!ref) return -ENOMEM; @@ -343,7 +343,7 @@ static int add_shared_data_ref(struct btrfs_fs_info *fs_info, struct block_entry *be; struct ref_entry *ref; - ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS); + ref = kzalloc_obj(struct ref_entry, GFP_NOFS); if (!ref) return -ENOMEM; be = add_block_entry(fs_info, bytenr, num_bytes, 0); @@ -378,7 +378,7 @@ static int add_extent_data_ref(struct btrfs_fs_info *fs_info, u64 offset = btrfs_extent_data_ref_offset(leaf, dref); u32 num_refs = btrfs_extent_data_ref_count(leaf, dref); - ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS); + ref = kzalloc_obj(struct ref_entry, GFP_NOFS); if (!ref) return -ENOMEM; be = add_block_entry(fs_info, bytenr, num_bytes, ref_root); @@ -680,8 +680,8 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, } metadata = owner < BTRFS_FIRST_FREE_OBJECTID; - ref = kzalloc(sizeof(struct ref_entry), GFP_NOFS); - ra = kmalloc(sizeof(struct ref_action), GFP_NOFS); + ref = kzalloc_obj(struct ref_entry, GFP_NOFS); + ra = kmalloc_obj(struct ref_action, GFP_NOFS); if (!ra || !ref) { kfree(ref); kfree(ra); @@ -755,7 +755,7 @@ int btrfs_ref_tree_mod(struct btrfs_fs_info *fs_info, struct root_entry *tmp; if (!parent) { - re = kmalloc(sizeof(struct root_entry), GFP_NOFS); + re = kmalloc_obj(struct root_entry, GFP_NOFS); if (!re) { kfree(ref); kfree(ra); diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index fcd0a2ba3554..b2343aed7a5d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -483,7 +483,7 @@ static int __add_reloc_root(struct btrfs_root *root) struct mapping_node *node; struct reloc_control *rc = fs_info->reloc_ctl; - node = kmalloc(sizeof(*node), GFP_NOFS); + node = kmalloc_obj(*node, GFP_NOFS); if (!node) return -ENOMEM; @@ -3115,7 +3115,7 @@ static int add_tree_block(struct reloc_control *rc, BUG_ON(level == -1); - block = kmalloc(sizeof(*block), GFP_NOFS); + block = kmalloc_obj(*block, GFP_NOFS); if (!block) return -ENOMEM; @@ -3813,7 +3813,7 @@ static struct reloc_control *alloc_reloc_control(struct btrfs_fs_info *fs_info) { struct reloc_control *rc; - rc = kzalloc(sizeof(*rc), GFP_NOFS); + rc = kzalloc_obj(*rc, GFP_NOFS); if (!rc) return NULL; @@ -4042,7 +4042,7 @@ static int copy_remapped_data(struct btrfs_fs_info *fs_info, u64 old_addr, struct reloc_io_private priv; unsigned int nr_pages = DIV_ROUND_UP(length, PAGE_SIZE); - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); + pages = kzalloc_objs(struct page *, nr_pages, GFP_NOFS); if (!pages) return -ENOMEM; @@ -4399,6 +4399,8 @@ static int move_existing_remaps(struct btrfs_fs_info *fs_info, leaf = path->nodes[0]; } + + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); } remap = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_remap_item); @@ -4723,6 +4725,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map, ret = btrfs_remove_dev_extents(trans, chunk_map); if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); + btrfs_end_transaction(trans); return ret; } @@ -4732,6 +4735,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map, if (unlikely(ret)) { mutex_unlock(&trans->fs_info->chunk_mutex); btrfs_abort_transaction(trans, ret); + btrfs_end_transaction(trans); return ret; } } @@ -4750,6 +4754,7 @@ int btrfs_last_identity_remap_gone(struct btrfs_chunk_map *chunk_map, ret = remove_chunk_stripes(trans, chunk_map, path); if (unlikely(ret)) { btrfs_abort_transaction(trans, ret); + btrfs_end_transaction(trans); return ret; } @@ -5982,6 +5987,9 @@ static int remove_range_from_remap_tree(struct btrfs_trans_handle *trans, struct btrfs_block_group *dest_bg; dest_bg = btrfs_lookup_block_group(fs_info, new_addr); + if (unlikely(!dest_bg)) + return -EUCLEAN; + adjust_block_group_remap_bytes(trans, dest_bg, -overlap_length); btrfs_put_block_group(dest_bg); ret = btrfs_add_to_free_space_tree(trans, diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 37a4173c0a0b..d85a09ae1733 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c @@ -257,7 +257,7 @@ int btrfs_find_orphan_roots(struct btrfs_fs_info *fs_info) root = btrfs_get_fs_root(fs_info, root_objectid, false); ret = PTR_ERR_OR_ZERO(root); if (ret && ret != -ENOENT) { - break; + return ret; } else if (ret == -ENOENT) { struct btrfs_trans_handle *trans; diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 2a64e2d50ced..bc94bbc00772 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -373,9 +373,8 @@ static int init_scrub_stripe(struct btrfs_fs_info *fs_info, if (ret < 0) goto error; - stripe->sectors = kcalloc(stripe->nr_sectors, - sizeof(struct scrub_sector_verification), - GFP_KERNEL); + stripe->sectors = kzalloc_objs(struct scrub_sector_verification, + stripe->nr_sectors); if (!stripe->sectors) goto error; @@ -456,7 +455,7 @@ static noinline_for_stack struct scrub_ctx *scrub_setup_ctx( /* Since sctx has inline 128 stripes, it can go beyond 64K easily. Use * kvzalloc(). */ - sctx = kvzalloc(sizeof(*sctx), GFP_KERNEL); + sctx = kvzalloc_obj(*sctx); if (!sctx) goto nomem; refcount_set(&sctx->refs, 1); @@ -744,7 +743,7 @@ static void scrub_verify_one_metadata(struct scrub_stripe *stripe, int sector_nr btrfs_warn_rl(fs_info, "scrub: tree block %llu mirror %u has bad fsid, has %pU want %pU", logical, stripe->mirror_num, - header->fsid, fs_info->fs_devices->fsid); + header->fsid, fs_info->fs_devices->metadata_uuid); return; } if (memcmp(header->chunk_tree_uuid, fs_info->chunk_tree_uuid, @@ -2474,9 +2473,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, if (profile & BTRFS_BLOCK_GROUP_RAID56_MASK) { ASSERT(sctx->raid56_data_stripes == NULL); - sctx->raid56_data_stripes = kcalloc(nr_data_stripes(map), - sizeof(struct scrub_stripe), - GFP_KERNEL); + sctx->raid56_data_stripes = kzalloc_objs(struct scrub_stripe, + nr_data_stripes(map)); if (!sctx->raid56_data_stripes) { ret = -ENOMEM; goto out; diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 3dcfdba018b5..904a2f57f86d 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c @@ -450,7 +450,7 @@ static struct fs_path *fs_path_alloc(void) { struct fs_path *p; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return NULL; init_path(p); @@ -1429,7 +1429,7 @@ static void store_backref_cache(u64 leaf_bytenr, const struct ulist *root_ids, * fs_info->commit_root_sem (at iterate_extent_inodes()), so must do a * NOFS allocation. */ - new_entry = kmalloc(sizeof(struct backref_cache_entry), GFP_NOFS); + new_entry = kmalloc_obj(struct backref_cache_entry, GFP_NOFS); /* No worries, cache is optional. */ if (!new_entry) return; @@ -2743,7 +2743,7 @@ static int cache_dir_utimes(struct send_ctx *sctx, u64 dir, u64 gen) return 0; /* Caching is optional, don't fail if we can't allocate memory. */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return send_utimes(sctx, dir, gen); @@ -2870,7 +2870,7 @@ static void cache_dir_created(struct send_ctx *sctx, u64 dir) int ret; /* Caching is optional, ignore any failures. */ - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return; @@ -2974,7 +2974,7 @@ static struct recorded_ref *recorded_ref_alloc(void) { struct recorded_ref *ref; - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) return NULL; RB_CLEAR_NODE(&ref->node); @@ -3083,7 +3083,7 @@ static struct orphan_dir_info *add_orphan_dir_info(struct send_ctx *sctx, return entry; } - odi = kmalloc(sizeof(*odi), GFP_KERNEL); + odi = kmalloc_obj(*odi); if (!odi) return ERR_PTR(-ENOMEM); odi->ino = dir_ino; @@ -3284,7 +3284,7 @@ static int add_waiting_dir_move(struct send_ctx *sctx, u64 ino, bool orphanized) struct rb_node *parent = NULL; struct waiting_dir_move *entry, *dm; - dm = kmalloc(sizeof(*dm), GFP_KERNEL); + dm = kmalloc_obj(*dm); if (!dm) return -ENOMEM; dm->ino = ino; @@ -3352,7 +3352,7 @@ static int add_pending_dir_move(struct send_ctx *sctx, int exists = 0; int ret; - pm = kmalloc(sizeof(*pm), GFP_KERNEL); + pm = kmalloc_obj(*pm); if (!pm) return -ENOMEM; pm->parent_ino = parent_ino; @@ -8035,7 +8035,7 @@ long btrfs_ioctl_send(struct btrfs_root *send_root, const struct btrfs_ioctl_sen goto out; } - sctx = kzalloc(sizeof(struct send_ctx), GFP_KERNEL); + sctx = kzalloc_obj(struct send_ctx); if (!sctx) { ret = -ENOMEM; goto out; @@ -8097,9 +8097,8 @@ long btrfs_ioctl_send(struct btrfs_root *send_root, const struct btrfs_ioctl_sen goto out; } send_buf_num_pages = sctx->send_max_size >> PAGE_SHIFT; - sctx->send_buf_pages = kcalloc(send_buf_num_pages, - sizeof(*sctx->send_buf_pages), - GFP_KERNEL); + sctx->send_buf_pages = kzalloc_objs(*sctx->send_buf_pages, + send_buf_num_pages); if (!sctx->send_buf_pages) { ret = -ENOMEM; goto out; @@ -8117,9 +8116,8 @@ long btrfs_ioctl_send(struct btrfs_root *send_root, const struct btrfs_ioctl_sen goto out; } - sctx->clone_roots = kvcalloc(arg->clone_sources_count + 1, - sizeof(*sctx->clone_roots), - GFP_KERNEL); + sctx->clone_roots = kvzalloc_objs(*sctx->clone_roots, + arg->clone_sources_count + 1); if (!sctx->clone_roots) { ret = -ENOMEM; goto out; diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index bb5aac7ee9d2..87cbc051cb12 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -266,7 +266,7 @@ static int create_space_info_sub_group(struct btrfs_space_info *parent, u64 flag "parent->subgroup_id=%d", parent->subgroup_id); ASSERT(id != BTRFS_SUB_GROUP_PRIMARY, "id=%d", id); - sub_group = kzalloc(sizeof(*sub_group), GFP_NOFS); + sub_group = kzalloc_obj(*sub_group, GFP_NOFS); if (!sub_group) return -ENOMEM; @@ -289,7 +289,7 @@ static int create_space_info(struct btrfs_fs_info *info, u64 flags) struct btrfs_space_info *space_info; int ret = 0; - space_info = kzalloc(sizeof(*space_info), GFP_NOFS); + space_info = kzalloc_obj(*space_info, GFP_NOFS); if (!space_info) return -ENOMEM; @@ -2194,8 +2194,11 @@ void btrfs_reclaim_sweep(const struct btrfs_fs_info *fs_info) if (!btrfs_should_periodic_reclaim(space_info)) continue; for (raid = 0; raid < BTRFS_NR_RAID_TYPES; raid++) { - if (do_reclaim_sweep(space_info, raid)) + if (do_reclaim_sweep(space_info, raid)) { + spin_lock(&space_info->lock); btrfs_set_periodic_reclaim_ready(space_info, false); + spin_unlock(&space_info->lock); + } } } } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index d64d303b6edc..b4d26ca9220a 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2054,7 +2054,7 @@ static int btrfs_get_tree_subvol(struct fs_context *fc) * of the fs_info (locks and such) to make cleanup easier if we find a * superblock with our given fs_devices later on at sget() time. */ - fs_info = kvzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); + fs_info = kvzalloc_obj(struct btrfs_fs_info); if (!fs_info) return -ENOMEM; @@ -2173,7 +2173,7 @@ static int btrfs_init_fs_context(struct fs_context *fc) { struct btrfs_fs_context *ctx; - ctx = kzalloc(sizeof(struct btrfs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct btrfs_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index 27bfb7b55ec4..0d14570c8bc2 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c @@ -1833,7 +1833,7 @@ void btrfs_sysfs_add_block_group_type(struct btrfs_block_group *cache) */ nofs_flag = memalloc_nofs_save(); - rkobj = kzalloc(sizeof(*rkobj), GFP_NOFS); + rkobj = kzalloc_obj(*rkobj, GFP_NOFS); if (!rkobj) { memalloc_nofs_restore(nofs_flag); btrfs_warn(cache->fs_info, @@ -2597,7 +2597,7 @@ int btrfs_sysfs_add_qgroups(struct btrfs_fs_info *fs_info) if (fs_info->qgroups_kobj) return 0; - fs_info->qgroups_kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL); + fs_info->qgroups_kobj = kzalloc_obj(struct kobject); if (!fs_info->qgroups_kobj) return -ENOMEM; diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index 7f13c05d3736..90e50e62dd17 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c @@ -98,7 +98,7 @@ struct btrfs_device *btrfs_alloc_dummy_device(struct btrfs_fs_info *fs_info) { struct btrfs_device *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -117,21 +117,18 @@ static void btrfs_free_dummy_device(struct btrfs_device *dev) struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize) { - struct btrfs_fs_info *fs_info = kzalloc(sizeof(struct btrfs_fs_info), - GFP_KERNEL); + struct btrfs_fs_info *fs_info = kzalloc_obj(struct btrfs_fs_info); if (!fs_info) return fs_info; - fs_info->fs_devices = kzalloc(sizeof(struct btrfs_fs_devices), - GFP_KERNEL); + fs_info->fs_devices = kzalloc_obj(struct btrfs_fs_devices); if (!fs_info->fs_devices) { kfree(fs_info); return NULL; } INIT_LIST_HEAD(&fs_info->fs_devices->devices); - fs_info->super_copy = kzalloc(sizeof(struct btrfs_super_block), - GFP_KERNEL); + fs_info->super_copy = kzalloc_obj(struct btrfs_super_block); if (!fs_info->super_copy) { kfree(fs_info->fs_devices); kfree(fs_info); @@ -208,11 +205,10 @@ btrfs_alloc_dummy_block_group(struct btrfs_fs_info *fs_info, { struct btrfs_block_group *cache; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (!cache) return NULL; - cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), - GFP_KERNEL); + cache->free_space_ctl = kzalloc_obj(*cache->free_space_ctl); if (!cache->free_space_ctl) { kfree(cache); return NULL; diff --git a/fs/btrfs/tests/delayed-refs-tests.c b/fs/btrfs/tests/delayed-refs-tests.c index e2248acb906b..ccab45d849bb 100644 --- a/fs/btrfs/tests/delayed-refs-tests.c +++ b/fs/btrfs/tests/delayed-refs-tests.c @@ -985,7 +985,7 @@ int btrfs_test_delayed_refs(u32 sectorsize, u32 nodesize) test_std_err(TEST_ALLOC_FS_INFO); return -ENOMEM; } - transaction = kmalloc(sizeof(*transaction), GFP_KERNEL); + transaction = kmalloc_obj(*transaction); if (!transaction) { test_std_err(TEST_ALLOC_TRANSACTION); ret = -ENOMEM; diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 0b2498749b1e..8dd77c431974 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -315,7 +315,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info, */ BUG_ON(type == TRANS_JOIN_NOLOCK); - cur_trans = kmalloc(sizeof(*cur_trans), GFP_NOFS); + cur_trans = kmalloc_obj(*cur_trans, GFP_NOFS); if (!cur_trans) return -ENOMEM; @@ -726,7 +726,7 @@ start_transaction(struct btrfs_root *root, unsigned int num_items, h->type = type; INIT_LIST_HEAD(&h->new_bgs); - btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELOPS); + btrfs_init_metadata_block_rsv(fs_info, &h->delayed_rsv, BTRFS_BLOCK_RSV_DELREFS); smp_mb(); if (cur_trans->state >= TRANS_STATE_COMMIT_START && @@ -1905,6 +1905,22 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, ret = btrfs_uuid_tree_add(trans, new_root_item->received_uuid, BTRFS_UUID_KEY_RECEIVED_SUBVOL, objectid); + /* + * We are creating of lot of snapshots of the same root that was + * received (has a received UUID) and reached a leaf's limit for + * an item. We can safely ignore this and avoid a transaction + * abort. A deletion of this snapshot will still work since we + * ignore if an item with a BTRFS_UUID_KEY_RECEIVED_SUBVOL key + * is missing (see btrfs_delete_subvolume()). Send/receive will + * work too since it peeks the first root id from the existing + * item (it could peek any), and in case it's missing it + * falls back to search by BTRFS_UUID_KEY_SUBVOL keys. + * Creation of a snapshot does not require CAP_SYS_ADMIN, so + * we don't want users triggering transaction aborts, either + * intentionally or not. + */ + if (ret == -EOVERFLOW) + ret = 0; if (unlikely(ret && ret != -EEXIST)) { btrfs_abort_transaction(trans, ret); goto fail; diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 452394b34d01..516ef62c8f43 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -1284,7 +1284,7 @@ static int check_root_item(struct extent_buffer *leaf, struct btrfs_key *key, } if (unlikely(btrfs_root_drop_level(&ri) >= BTRFS_MAX_LEVEL)) { generic_err(leaf, slot, - "invalid root level, have %u expect [0, %u]", + "invalid root drop_level, have %u expect [0, %u]", btrfs_root_drop_level(&ri), BTRFS_MAX_LEVEL - 1); return -EUCLEAN; } @@ -1740,7 +1740,7 @@ static int check_extent_data_ref(struct extent_buffer *leaf, objectid > BTRFS_LAST_FREE_OBJECTID)) { extent_err(leaf, slot, "invalid extent data backref objectid value %llu", - root); + objectid); return -EUCLEAN; } if (unlikely(!IS_ALIGNED(offset, leaf->fs_info->sectorsize))) { @@ -1921,7 +1921,7 @@ static int check_dev_extent_item(const struct extent_buffer *leaf, if (unlikely(prev_key->offset + prev_len > key->offset)) { generic_err(leaf, slot, "dev extent overlap, prev offset %llu len %llu current offset %llu", - prev_key->objectid, prev_len, key->offset); + prev_key->offset, prev_len, key->offset); return -EUCLEAN; } } diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index e1bd03ebfd98..552fef3c385a 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -5928,7 +5928,7 @@ static int log_new_dir_dentries(struct btrfs_trans_handle *trans, if (ret) goto out; if (ctx->log_new_dentries) { - dir_elem = kmalloc(sizeof(*dir_elem), GFP_NOFS); + dir_elem = kmalloc_obj(*dir_elem, GFP_NOFS); if (!dir_elem) { ret = -ENOMEM; goto out; @@ -6122,7 +6122,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans, return ret; /* Conflicting inode is a directory, so we'll log its parent. */ - ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS); + ino_elem = kmalloc_obj(*ino_elem, GFP_NOFS); if (!ino_elem) return -ENOMEM; ino_elem->ino = ino; @@ -6180,7 +6180,7 @@ static int add_conflicting_inode(struct btrfs_trans_handle *trans, btrfs_add_delayed_iput(inode); - ino_elem = kmalloc(sizeof(*ino_elem), GFP_NOFS); + ino_elem = kmalloc_obj(*ino_elem, GFP_NOFS); if (!ino_elem) return -ENOMEM; ino_elem->ino = ino; @@ -6195,6 +6195,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_log_ctx *ctx) { + const bool orig_log_new_dentries = ctx->log_new_dentries; int ret = 0; /* @@ -6256,7 +6257,11 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, * dir index key range logged for the directory. So we * must make sure the deletion is recorded. */ + ctx->log_new_dentries = false; ret = btrfs_log_inode(trans, inode, LOG_INODE_ALL, ctx); + if (!ret && ctx->log_new_dentries) + ret = log_new_dir_dentries(trans, inode, ctx); + btrfs_add_delayed_iput(inode); if (ret) break; @@ -6291,6 +6296,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans, break; } + ctx->log_new_dentries = orig_log_new_dentries; ctx->logging_conflict_inodes = false; if (ret) free_conflicting_inodes(ctx); diff --git a/fs/btrfs/tree-mod-log.c b/fs/btrfs/tree-mod-log.c index 9e8cb3b7c064..603c1457130e 100644 --- a/fs/btrfs/tree-mod-log.c +++ b/fs/btrfs/tree-mod-log.c @@ -243,7 +243,7 @@ static struct tree_mod_elem *alloc_tree_mod_elem(const struct extent_buffer *eb, ASSERT(op != BTRFS_MOD_LOG_MOVE_KEYS); ASSERT(op != BTRFS_MOD_LOG_ROOT_REPLACE); - tm = kzalloc(sizeof(*tm), GFP_NOFS); + tm = kzalloc_obj(*tm, GFP_NOFS); if (!tm) return NULL; @@ -301,7 +301,7 @@ static struct tree_mod_elem *tree_mod_log_alloc_move(const struct extent_buffer { struct tree_mod_elem *tm; - tm = kzalloc(sizeof(*tm), GFP_NOFS); + tm = kzalloc_obj(*tm, GFP_NOFS); if (!tm) return ERR_PTR(-ENOMEM); @@ -328,7 +328,7 @@ int btrfs_tree_mod_log_insert_move(const struct extent_buffer *eb, if (!tree_mod_need_log(eb->fs_info, eb)) return 0; - tm_list = kcalloc(nr_items, sizeof(struct tree_mod_elem *), GFP_NOFS); + tm_list = kzalloc_objs(struct tree_mod_elem *, nr_items, GFP_NOFS); if (!tm_list) { ret = -ENOMEM; goto lock; @@ -439,8 +439,8 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root, if (log_removal && btrfs_header_level(old_root) > 0) { nritems = btrfs_header_nritems(old_root); - tm_list = kcalloc(nritems, sizeof(struct tree_mod_elem *), - GFP_NOFS); + tm_list = kzalloc_objs(struct tree_mod_elem *, nritems, + GFP_NOFS); if (!tm_list) { ret = -ENOMEM; goto lock; @@ -455,7 +455,7 @@ int btrfs_tree_mod_log_insert_root(struct extent_buffer *old_root, } } - tm = kzalloc(sizeof(*tm), GFP_NOFS); + tm = kzalloc_obj(*tm, GFP_NOFS); if (!tm) { ret = -ENOMEM; goto lock; @@ -595,8 +595,7 @@ int btrfs_tree_mod_log_eb_copy(struct extent_buffer *dst, if (btrfs_header_level(dst) == 0 && btrfs_header_level(src) == 0) return 0; - tm_list = kcalloc(nr_items * 2, sizeof(struct tree_mod_elem *), - GFP_NOFS); + tm_list = kzalloc_objs(struct tree_mod_elem *, nr_items * 2, GFP_NOFS); if (!tm_list) { ret = -ENOMEM; goto lock; @@ -714,7 +713,7 @@ int btrfs_tree_mod_log_free_eb(struct extent_buffer *eb) return 0; nritems = btrfs_header_nritems(eb); - tm_list = kcalloc(nritems, sizeof(struct tree_mod_elem *), GFP_NOFS); + tm_list = kzalloc_objs(struct tree_mod_elem *, nritems, GFP_NOFS); if (!tm_list) { ret = -ENOMEM; goto lock; diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c index 7e16a253fb35..7898076ce41c 100644 --- a/fs/btrfs/ulist.c +++ b/fs/btrfs/ulist.c @@ -98,7 +98,7 @@ void ulist_reinit(struct ulist *ulist) */ struct ulist *ulist_alloc(gfp_t gfp_mask) { - struct ulist *ulist = kmalloc(sizeof(*ulist), gfp_mask); + struct ulist *ulist = kmalloc_obj(*ulist, gfp_mask); if (!ulist) return NULL; @@ -111,7 +111,7 @@ struct ulist *ulist_alloc(gfp_t gfp_mask) void ulist_prealloc(struct ulist *ulist, gfp_t gfp_mask) { if (!ulist->prealloc) - ulist->prealloc = kzalloc(sizeof(*ulist->prealloc), gfp_mask); + ulist->prealloc = kzalloc_obj(*ulist->prealloc, gfp_mask); } /* @@ -219,7 +219,7 @@ int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux, node = ulist->prealloc; ulist->prealloc = NULL; } else { - node = kmalloc(sizeof(*node), gfp_mask); + node = kmalloc_obj(*node, gfp_mask); if (!node) return -ENOMEM; } diff --git a/fs/btrfs/uuid-tree.c b/fs/btrfs/uuid-tree.c index f24c14b9bb2f..43c17a1d3451 100644 --- a/fs/btrfs/uuid-tree.c +++ b/fs/btrfs/uuid-tree.c @@ -199,6 +199,44 @@ int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, const u8 *uuid, u8 return 0; } +/* + * Check if we can add one root ID to a UUID key. + * If the key does not yet exists, we can, otherwise only if extended item does + * not exceeds the maximum item size permitted by the leaf size. + * + * Returns 0 on success, negative value on error. + */ +int btrfs_uuid_tree_check_overflow(struct btrfs_fs_info *fs_info, + const u8 *uuid, u8 type) +{ + BTRFS_PATH_AUTO_FREE(path); + int ret; + u32 item_size; + struct btrfs_key key; + + if (WARN_ON_ONCE(!fs_info->uuid_root)) + return -EINVAL; + + path = btrfs_alloc_path(); + if (!path) + return -ENOMEM; + + btrfs_uuid_to_key(uuid, type, &key); + ret = btrfs_search_slot(NULL, fs_info->uuid_root, &key, path, 0, 0); + if (ret < 0) + return ret; + if (ret > 0) + return 0; + + item_size = btrfs_item_size(path->nodes[0], path->slots[0]); + + if (sizeof(struct btrfs_item) + item_size + sizeof(u64) > + BTRFS_LEAF_DATA_SIZE(fs_info)) + return -EOVERFLOW; + + return 0; +} + static int btrfs_uuid_iter_rem(struct btrfs_root *uuid_root, u8 *uuid, u8 type, u64 subid) { diff --git a/fs/btrfs/uuid-tree.h b/fs/btrfs/uuid-tree.h index c60ad20325cc..02b235a3653f 100644 --- a/fs/btrfs/uuid-tree.h +++ b/fs/btrfs/uuid-tree.h @@ -12,6 +12,8 @@ int btrfs_uuid_tree_add(struct btrfs_trans_handle *trans, const u8 *uuid, u8 typ u64 subid); int btrfs_uuid_tree_remove(struct btrfs_trans_handle *trans, const u8 *uuid, u8 type, u64 subid); +int btrfs_uuid_tree_check_overflow(struct btrfs_fs_info *fs_info, + const u8 *uuid, u8 type); int btrfs_uuid_tree_iterate(struct btrfs_fs_info *fs_info); int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info); int btrfs_uuid_scan_kthread(void *data); diff --git a/fs/btrfs/verity.c b/fs/btrfs/verity.c index d12537a212e9..0062b3a55781 100644 --- a/fs/btrfs/verity.c +++ b/fs/btrfs/verity.c @@ -552,7 +552,7 @@ static int finish_verity(struct btrfs_inode *inode, const void *desc, btrfs_set_fs_compat_ro(root->fs_info, VERITY); end_trans: btrfs_end_transaction(trans); - return 0; + return ret; } diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f281d113519b..be8975ef8b24 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -382,7 +382,7 @@ static struct btrfs_fs_devices *alloc_fs_devices(const u8 *fsid) { struct btrfs_fs_devices *fs_devs; - fs_devs = kzalloc(sizeof(*fs_devs), GFP_KERNEL); + fs_devs = kzalloc_obj(*fs_devs); if (!fs_devs) return ERR_PTR(-ENOMEM); @@ -3587,7 +3587,7 @@ int btrfs_relocate_chunk(struct btrfs_fs_info *fs_info, u64 chunk_offset, bool v /* step one, relocate all the extents inside this chunk */ btrfs_scrub_pause(fs_info); - ret = btrfs_relocate_block_group(fs_info, chunk_offset, true); + ret = btrfs_relocate_block_group(fs_info, chunk_offset, verbose); btrfs_scrub_continue(fs_info); if (ret) { /* @@ -4367,8 +4367,14 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) * this shouldn't happen, it means the last relocate * failed */ - if (ret == 0) - BUG(); /* FIXME break ? */ + if (unlikely(ret == 0)) { + btrfs_err(fs_info, + "unexpected exact match of CHUNK_ITEM in chunk tree, offset 0x%llx", + key.offset); + mutex_unlock(&fs_info->reclaim_bgs_lock); + ret = -EUCLEAN; + goto error; + } ret = btrfs_previous_item(chunk_root, path, 0, BTRFS_CHUNK_ITEM_KEY); @@ -4450,7 +4456,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) if (chunk_type & BTRFS_BLOCK_GROUP_METADATA_REMAP) { mutex_unlock(&fs_info->reclaim_bgs_lock); - rci = kmalloc(sizeof(struct remap_chunk_info), GFP_NOFS); + rci = kmalloc_obj(struct remap_chunk_info, GFP_NOFS); if (!rci) { ret = -ENOMEM; goto error; @@ -4998,7 +5004,7 @@ int btrfs_recover_balance(struct btrfs_fs_info *fs_info) return 0; } - bctl = kzalloc(sizeof(*bctl), GFP_NOFS); + bctl = kzalloc_obj(*bctl, GFP_NOFS); if (!bctl) return -ENOMEM; @@ -6332,7 +6338,7 @@ struct btrfs_io_context *alloc_btrfs_io_context(struct btrfs_fs_info *fs_info, { struct btrfs_io_context *bioc; - bioc = kzalloc(struct_size(bioc, stripes, total_stripes), GFP_NOFS); + bioc = kzalloc_flex(*bioc, stripes, total_stripes, GFP_NOFS); if (!bioc) return NULL; @@ -6465,7 +6471,7 @@ struct btrfs_discard_stripe *btrfs_map_discard(struct btrfs_fs_info *fs_info, stripe_nr /= map->num_stripes; } - stripes = kcalloc(*num_stripes, sizeof(*stripes), GFP_NOFS); + stripes = kzalloc_objs(*stripes, *num_stripes, GFP_NOFS); if (!stripes) { ret = -ENOMEM; goto out_free_map; @@ -6901,7 +6907,7 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op, ret = btrfs_translate_remap(fs_info, &new_logical, length); if (ret) - return ret; + goto out; if (new_logical != logical) { btrfs_free_chunk_map(map); @@ -6915,8 +6921,10 @@ int btrfs_map_block(struct btrfs_fs_info *fs_info, enum btrfs_map_op op, } num_copies = btrfs_chunk_map_num_copies(map); - if (io_geom.mirror_num > num_copies) - return -EINVAL; + if (io_geom.mirror_num > num_copies) { + ret = -EINVAL; + goto out; + } map_offset = logical - map->start; io_geom.raid56_full_stripe_start = (u64)-1; @@ -7196,7 +7204,7 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, if (WARN_ON(!devid && !fs_info)) return ERR_PTR(-EINVAL); - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return ERR_PTR(-ENOMEM); diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 0a8fcee16428..1b7544aa88a2 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -75,7 +75,7 @@ struct list_head *zlib_alloc_workspace(struct btrfs_fs_info *fs_info, unsigned i struct workspace *workspace; int workspacesize; - workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); + workspace = kzalloc_obj(*workspace); if (!workspace) return ERR_PTR(-ENOMEM); diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index ad8621587fd2..817ca4fb9efa 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -337,7 +337,10 @@ int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) if (!btrfs_fs_incompat(fs_info, ZONED)) return 0; - mutex_lock(&fs_devices->device_list_mutex); + /* + * No need to take the device_list mutex here, we're still in the mount + * path and devices cannot be added to or removed from the list yet. + */ list_for_each_entry(device, &fs_devices->devices, dev_list) { /* We can skip reading of zone info for missing devices */ if (!device->bdev) @@ -347,7 +350,6 @@ int btrfs_get_dev_zone_info_all_devices(struct btrfs_fs_info *fs_info) if (ret) break; } - mutex_unlock(&fs_devices->device_list_mutex); return ret; } @@ -377,7 +379,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache) if (device->zone_info) return 0; - zone_info = kzalloc(sizeof(*zone_info), GFP_KERNEL); + zone_info = kzalloc_obj(*zone_info); if (!zone_info) return -ENOMEM; @@ -454,7 +456,7 @@ int btrfs_get_dev_zone_info(struct btrfs_device *device, bool populate_cache) goto out; } - zones = kvcalloc(BTRFS_REPORT_NR_ZONES, sizeof(struct blk_zone), GFP_KERNEL); + zones = kvzalloc_objs(struct blk_zone, BTRFS_REPORT_NR_ZONES); if (!zones) { ret = -ENOMEM; goto out; diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 32fd7f5454d3..6f076fa8f3f9 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -185,7 +185,7 @@ int zstd_alloc_workspace_manager(struct btrfs_fs_info *fs_info) struct list_head *ws; ASSERT(fs_info->compr_wsm[BTRFS_COMPRESS_ZSTD] == NULL); - zwsm = kzalloc(sizeof(*zwsm), GFP_KERNEL); + zwsm = kzalloc_obj(*zwsm); if (!zwsm) return -ENOMEM; zstd_calc_ws_mem_sizes(); @@ -373,7 +373,7 @@ struct list_head *zstd_alloc_workspace(struct btrfs_fs_info *fs_info, int level) const u32 blocksize = fs_info->sectorsize; struct workspace *workspace; - workspace = kzalloc(sizeof(*workspace), GFP_KERNEL); + workspace = kzalloc_obj(*workspace); if (!workspace) return ERR_PTR(-ENOMEM); diff --git a/fs/buffer.c b/fs/buffer.c index ed724a902657..22b43642ba57 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -358,8 +358,7 @@ static void end_buffer_async_read_io(struct buffer_head *bh, int uptodate) /* Decrypt (with fscrypt) and/or verify (with fsverity) if needed. */ if (uptodate && (decrypt || vi)) { - struct postprocess_bh_ctx *ctx = - kmalloc(sizeof(*ctx), GFP_ATOMIC); + struct postprocess_bh_ctx *ctx = kmalloc_obj(*ctx, GFP_ATOMIC); if (ctx) { ctx->bh = bh; diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index 1806bff8e59b..4117b145ac94 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -102,7 +102,7 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) return -EBUSY; /* allocate a cache record */ - cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL); + cache = kzalloc_obj(struct cachefiles_cache); if (!cache) { cachefiles_open = 0; return -ENOMEM; diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c index 3e0576d9db1d..eaf47851c65f 100644 --- a/fs/cachefiles/io.c +++ b/fs/cachefiles/io.c @@ -132,7 +132,7 @@ static int cachefiles_read(struct netfs_cache_resources *cres, } ret = -ENOMEM; - ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL); + ki = kzalloc_obj(struct cachefiles_kiocb); if (!ki) goto presubmission_error; @@ -298,7 +298,7 @@ int __cachefiles_write(struct cachefiles_object *object, file, file_inode(file)->i_ino, start_pos, len, i_size_read(file_inode(file))); - ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL); + ki = kzalloc_obj(struct cachefiles_kiocb); if (!ki) { if (term_func) term_func(term_func_priv, -ENOMEM); diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index a7ed86fa98bb..0849eaf583cd 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -734,8 +734,7 @@ int cachefiles_ondemand_init_obj_info(struct cachefiles_object *object, if (!cachefiles_in_ondemand_mode(volume->cache)) return 0; - object->ondemand = kzalloc(sizeof(struct cachefiles_ondemand_info), - GFP_KERNEL); + object->ondemand = kzalloc_obj(struct cachefiles_ondemand_info); if (!object->ondemand) return -ENOMEM; diff --git a/fs/cachefiles/volume.c b/fs/cachefiles/volume.c index 90ba926f488e..6c0da61362ee 100644 --- a/fs/cachefiles/volume.c +++ b/fs/cachefiles/volume.c @@ -28,7 +28,7 @@ void cachefiles_acquire_volume(struct fscache_volume *vcookie) _enter(""); - volume = kzalloc(sizeof(struct cachefiles_volume), GFP_KERNEL); + volume = kzalloc_obj(struct cachefiles_volume); if (!volume) return; volume->vcookie = vcookie; diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 63b75d214210..2090fc78529c 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -470,7 +470,7 @@ static int ceph_init_request(struct netfs_io_request *rreq, struct file *file) if (rreq->origin != NETFS_READAHEAD) return 0; - priv = kzalloc(sizeof(*priv), GFP_NOFS); + priv = kzalloc_obj(*priv, GFP_NOFS); if (!priv) return -ENOMEM; @@ -1000,7 +1000,8 @@ unsigned int ceph_define_write_size(struct address_space *mapping) { struct inode *inode = mapping->host; struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode); - unsigned int wsize = i_blocksize(inode); + struct ceph_inode_info *ci = ceph_inode(inode); + unsigned int wsize = ci->i_layout.stripe_unit; if (fsc->mount_options->wsize < wsize) wsize = fsc->mount_options->wsize; @@ -1185,9 +1186,7 @@ static inline void __ceph_allocate_page_array(struct ceph_writeback_ctl *ceph_wbc, unsigned int max_pages) { - ceph_wbc->pages = kmalloc_array(max_pages, - sizeof(*ceph_wbc->pages), - GFP_NOFS); + ceph_wbc->pages = kmalloc_objs(*ceph_wbc->pages, max_pages, GFP_NOFS); if (!ceph_wbc->pages) { ceph_wbc->from_pool = true; ceph_wbc->pages = mempool_alloc(ceph_wb_pagevec_pool, GFP_NOFS); @@ -1283,16 +1282,16 @@ static inline int move_dirty_folio_in_page_array(struct address_space *mapping, } static -int ceph_process_folio_batch(struct address_space *mapping, - struct writeback_control *wbc, - struct ceph_writeback_ctl *ceph_wbc) +void ceph_process_folio_batch(struct address_space *mapping, + struct writeback_control *wbc, + struct ceph_writeback_ctl *ceph_wbc) { struct inode *inode = mapping->host; struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode); struct ceph_client *cl = fsc->client; struct folio *folio = NULL; unsigned i; - int rc = 0; + int rc; for (i = 0; can_next_page_be_processed(ceph_wbc, i); i++) { folio = ceph_wbc->fbatch.folios[i]; @@ -1322,14 +1321,11 @@ int ceph_process_folio_batch(struct address_space *mapping, rc = ceph_check_page_before_write(mapping, wbc, ceph_wbc, folio); if (rc == -ENODATA) { - rc = 0; folio_unlock(folio); ceph_wbc->fbatch.folios[i] = NULL; continue; } else if (rc == -E2BIG) { - rc = 0; folio_unlock(folio); - ceph_wbc->fbatch.folios[i] = NULL; break; } @@ -1379,8 +1375,6 @@ int ceph_process_folio_batch(struct address_space *mapping, } ceph_wbc->processed_in_fbatch = i; - - return rc; } static inline @@ -1666,7 +1660,9 @@ static int ceph_writepages_start(struct address_space *mapping, tag_pages_for_writeback(mapping, ceph_wbc.index, ceph_wbc.end); while (!has_writeback_done(&ceph_wbc)) { - ceph_wbc.locked_pages = 0; + BUG_ON(ceph_wbc.locked_pages); + BUG_ON(ceph_wbc.pages); + ceph_wbc.max_pages = ceph_wbc.wsize >> PAGE_SHIFT; get_more_pages: @@ -1684,10 +1680,8 @@ static int ceph_writepages_start(struct address_space *mapping, break; process_folio_batch: - rc = ceph_process_folio_batch(mapping, wbc, &ceph_wbc); + ceph_process_folio_batch(mapping, wbc, &ceph_wbc); ceph_shift_unused_folios_left(&ceph_wbc.fbatch); - if (rc) - goto release_folios; /* did we get anything? */ if (!ceph_wbc.locked_pages) @@ -2199,6 +2193,7 @@ int ceph_uninline_data(struct file *file) struct ceph_osd_request *req = NULL; struct ceph_cap_flush *prealloc_cf = NULL; struct folio *folio = NULL; + struct ceph_snap_context *snapc = NULL; u64 inline_version = CEPH_INLINE_NONE; struct page *pages[1]; int err = 0; @@ -2226,6 +2221,24 @@ int ceph_uninline_data(struct file *file) if (inline_version == 1) /* initial version, no data */ goto out_uninline; + down_read(&fsc->mdsc->snap_rwsem); + spin_lock(&ci->i_ceph_lock); + if (__ceph_have_pending_cap_snap(ci)) { + struct ceph_cap_snap *capsnap = + list_last_entry(&ci->i_cap_snaps, + struct ceph_cap_snap, + ci_item); + snapc = ceph_get_snap_context(capsnap->context); + } else { + if (!ci->i_head_snapc) { + ci->i_head_snapc = ceph_get_snap_context( + ci->i_snap_realm->cached_context); + } + snapc = ceph_get_snap_context(ci->i_head_snapc); + } + spin_unlock(&ci->i_ceph_lock); + up_read(&fsc->mdsc->snap_rwsem); + folio = read_mapping_folio(inode->i_mapping, 0, file); if (IS_ERR(folio)) { err = PTR_ERR(folio); @@ -2241,7 +2254,7 @@ int ceph_uninline_data(struct file *file) req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, ceph_vino(inode), 0, &len, 0, 1, CEPH_OSD_OP_CREATE, CEPH_OSD_FLAG_WRITE, - NULL, 0, 0, false); + snapc, 0, 0, false); if (IS_ERR(req)) { err = PTR_ERR(req); goto out_unlock; @@ -2257,7 +2270,7 @@ int ceph_uninline_data(struct file *file) req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, ceph_vino(inode), 0, &len, 1, 3, CEPH_OSD_OP_WRITE, CEPH_OSD_FLAG_WRITE, - NULL, ci->i_truncate_seq, + snapc, ci->i_truncate_seq, ci->i_truncate_size, false); if (IS_ERR(req)) { err = PTR_ERR(req); @@ -2320,6 +2333,7 @@ int ceph_uninline_data(struct file *file) folio_put(folio); } out: + ceph_put_snap_context(snapc); ceph_free_cap_flush(prealloc_cf); doutc(cl, "%llx.%llx inline_version %llu = %d\n", ceph_vinop(inode), inline_version, err); @@ -2489,7 +2503,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, } pool_ns_len = pool_ns ? pool_ns->len : 0; - perm = kmalloc(struct_size(perm, pool_ns, pool_ns_len + 1), GFP_NOFS); + perm = kmalloc_flex(*perm, pool_ns, pool_ns_len + 1, GFP_NOFS); if (!perm) { err = -ENOMEM; goto out_unlock; diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 2f663972da99..d51454e995a8 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2395,7 +2395,7 @@ static int flush_mdlog_and_wait_inode_unsafe_requests(struct inode *inode) mutex_lock(&mdsc->mutex); max_sessions = mdsc->max_sessions; - sessions = kcalloc(max_sessions, sizeof(s), GFP_KERNEL); + sessions = kzalloc_objs(s, max_sessions); if (!sessions) { mutex_unlock(&mdsc->mutex); err = -ENOMEM; diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c index 9a115282f67d..f3de43ccb470 100644 --- a/fs/ceph/crypto.c +++ b/fs/ceph/crypto.c @@ -50,7 +50,7 @@ static int ceph_crypt_set_context(struct inode *inode, const void *ctx, if (len > FSCRYPT_SET_CONTEXT_MAX_SIZE) return -EINVAL; - cfa = kzalloc(sizeof(*cfa), GFP_KERNEL); + cfa = kzalloc_obj(*cfa); if (!cfa) return -ENOMEM; @@ -112,7 +112,7 @@ int ceph_fscrypt_prepare_context(struct inode *dir, struct inode *inode, if (!encrypted) return 0; - as->fscrypt_auth = kzalloc(sizeof(*as->fscrypt_auth), GFP_KERNEL); + as->fscrypt_auth = kzalloc_obj(*as->fscrypt_auth); if (!as->fscrypt_auth) return -ENOMEM; diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c index f3fe786b4143..7dc307790240 100644 --- a/fs/ceph/debugfs.c +++ b/fs/ceph/debugfs.c @@ -79,7 +79,7 @@ static int mdsc_show(struct seq_file *s, void *p) if (req->r_inode) { seq_printf(s, " #%llx", ceph_ino(req->r_inode)); } else if (req->r_dentry) { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, req->r_dentry, &path_info, 0); if (IS_ERR(path)) path = NULL; @@ -98,7 +98,7 @@ static int mdsc_show(struct seq_file *s, void *p) } if (req->r_old_dentry) { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, req->r_old_dentry, &path_info, 0); if (IS_ERR(path)) path = NULL; diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 86d7aa594ea9..bac9cfb6b982 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -1339,6 +1339,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry) struct ceph_client *cl = fsc->client; struct ceph_mds_client *mdsc = fsc->mdsc; struct inode *inode = d_inode(dentry); + struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_mds_request *req; bool try_async = ceph_test_mount_opt(fsc, ASYNC_DIROPS); struct dentry *dn; @@ -1363,7 +1364,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry) if (!dn) { try_async = false; } else { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, dn, &path_info, 0); if (IS_ERR(path)) { try_async = false; @@ -1424,7 +1425,19 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry) * We have enough caps, so we assume that the unlink * will succeed. Fix up the target inode and dcache. */ - drop_nlink(inode); + + /* + * Protect the i_nlink update with i_ceph_lock + * to precent racing against ceph_fill_inode() + * handling our completion on a worker thread + * and don't decrement if i_nlink has already + * been updated to zero by this completion. + */ + spin_lock(&ci->i_ceph_lock); + if (inode->i_nlink > 0) + drop_nlink(inode); + spin_unlock(&ci->i_ceph_lock); + d_delete(dentry); } else { spin_lock(&fsc->async_unlink_conflict_lock); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 31b691b2aea2..5e7c73a29aa3 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -140,7 +140,7 @@ static ssize_t iter_get_bvecs_alloc(struct iov_iter *iter, size_t maxsize, * __iter_get_bvecs() may populate only part of the array -- zero it * out. */ - bv = kvmalloc_array(npages, sizeof(*bv), GFP_KERNEL | __GFP_ZERO); + bv = kvmalloc_objs(*bv, npages, GFP_KERNEL | __GFP_ZERO); if (!bv) return -ENOMEM; @@ -397,7 +397,7 @@ int ceph_open(struct inode *inode, struct file *file) if (!dentry) { do_sync = true; } else { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, dentry, &path_info, 0); if (IS_ERR(path)) { do_sync = true; @@ -807,7 +807,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, if (!dn) { try_async = false; } else { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, dn, &path_info, 0); if (IS_ERR(path)) { try_async = false; @@ -1344,7 +1344,7 @@ static void ceph_aio_complete_req(struct ceph_osd_request *req) struct ceph_aio_work *aio_work; BUG_ON(!aio_req->write); - aio_work = kmalloc(sizeof(*aio_work), GFP_NOFS); + aio_work = kmalloc_obj(*aio_work, GFP_NOFS); if (aio_work) { INIT_WORK(&aio_work->work, ceph_aio_retry_work); aio_work->req = req; @@ -1572,7 +1572,7 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, */ if (pos == iocb->ki_pos && !is_sync_kiocb(iocb) && (len == count || pos + count <= i_size_read(inode))) { - aio_req = kzalloc(sizeof(*aio_req), GFP_KERNEL); + aio_req = kzalloc_obj(*aio_req); if (aio_req) { aio_req->iocb = iocb; aio_req->write = write; @@ -2568,6 +2568,7 @@ static int ceph_zero_partial_object(struct inode *inode, struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_fs_client *fsc = ceph_inode_to_fs_client(inode); struct ceph_osd_request *req; + struct ceph_snap_context *snapc; int ret = 0; loff_t zero = 0; int op; @@ -2582,12 +2583,25 @@ static int ceph_zero_partial_object(struct inode *inode, op = CEPH_OSD_OP_ZERO; } + spin_lock(&ci->i_ceph_lock); + if (__ceph_have_pending_cap_snap(ci)) { + struct ceph_cap_snap *capsnap = + list_last_entry(&ci->i_cap_snaps, + struct ceph_cap_snap, + ci_item); + snapc = ceph_get_snap_context(capsnap->context); + } else { + BUG_ON(!ci->i_head_snapc); + snapc = ceph_get_snap_context(ci->i_head_snapc); + } + spin_unlock(&ci->i_ceph_lock); + req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, ceph_vino(inode), offset, length, 0, 1, op, CEPH_OSD_FLAG_WRITE, - NULL, 0, 0, false); + snapc, 0, 0, false); if (IS_ERR(req)) { ret = PTR_ERR(req); goto out; @@ -2601,6 +2615,7 @@ static int ceph_zero_partial_object(struct inode *inode, ceph_osdc_put_request(req); out: + ceph_put_snap_context(snapc); return ret; } diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 2966f88310e3..d99e12d1100b 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -321,7 +321,7 @@ static struct ceph_inode_frag *__get_or_create_frag(struct ceph_inode_info *ci, return frag; } - frag = kmalloc(sizeof(*frag), GFP_NOFS); + frag = kmalloc_obj(*frag, GFP_NOFS); if (!frag) return ERR_PTR(-ENOMEM); @@ -2551,7 +2551,7 @@ int __ceph_setattr(struct mnt_idmap *idmap, struct inode *inode, if (!dentry) { do_sync = true; } else { - struct ceph_path_info path_info; + struct ceph_path_info path_info = {0}; path = ceph_mdsc_build_path(mdsc, dentry, &path_info, 0); if (IS_ERR(path)) { do_sync = true; diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index c45bd19d4b1c..b1746273f186 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -973,7 +973,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, if (mds >= mdsc->mdsmap->possible_max_rank) return ERR_PTR(-EINVAL); - s = kzalloc(sizeof(*s), GFP_NOFS); + s = kzalloc_obj(*s, GFP_NOFS); if (!s) return ERR_PTR(-ENOMEM); @@ -2768,6 +2768,7 @@ char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry, if (ret < 0) { dput(parent); dput(cur); + __putname(path); return ERR_PTR(ret); } @@ -2777,6 +2778,7 @@ char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry, if (len < 0) { dput(parent); dput(cur); + __putname(path); return ERR_PTR(len); } } @@ -2813,6 +2815,7 @@ char *ceph_mdsc_build_path(struct ceph_mds_client *mdsc, struct dentry *dentry, * cannot ever succeed. Creating paths that long is * possible with Ceph, but Linux cannot use them. */ + __putname(path); return ERR_PTR(-ENAMETOOLONG); } @@ -4230,9 +4233,8 @@ static void handle_session(struct ceph_mds_session *session, goto skip_cap_auths; } - cap_auths = kcalloc(cap_auths_num, - sizeof(struct ceph_mds_cap_auth), - GFP_KERNEL); + cap_auths = kzalloc_objs(struct ceph_mds_cap_auth, + cap_auths_num); if (!cap_auths) { pr_err_client(cl, "No memory for cap_auths\n"); return; @@ -4731,9 +4733,9 @@ static int reconnect_caps_cb(struct inode *inode, int mds, void *arg) num_flock_locks = 0; } if (num_fcntl_locks + num_flock_locks > 0) { - flocks = kmalloc_array(num_fcntl_locks + num_flock_locks, - sizeof(struct ceph_filelock), - GFP_NOFS); + flocks = kmalloc_objs(struct ceph_filelock, + num_fcntl_locks + num_flock_locks, + GFP_NOFS); if (!flocks) { err = -ENOMEM; goto out_err; @@ -5534,12 +5536,12 @@ int ceph_mdsc_init(struct ceph_fs_client *fsc) struct ceph_mds_client *mdsc; int err; - mdsc = kzalloc(sizeof(struct ceph_mds_client), GFP_NOFS); + mdsc = kzalloc_obj(struct ceph_mds_client, GFP_NOFS); if (!mdsc) return -ENOMEM; mdsc->fsc = fsc; mutex_init(&mdsc->mutex); - mdsc->mdsmap = kzalloc(sizeof(*mdsc->mdsmap), GFP_NOFS); + mdsc->mdsmap = kzalloc_obj(*mdsc->mdsmap, GFP_NOFS); if (!mdsc->mdsmap) { err = -ENOMEM; goto err_mdsc; diff --git a/fs/ceph/mdsmap.c b/fs/ceph/mdsmap.c index b228e5ecfb92..d8e46eb7e5eb 100644 --- a/fs/ceph/mdsmap.c +++ b/fs/ceph/mdsmap.c @@ -127,7 +127,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, u16 mdsmap_ev; u32 target; - m = kzalloc(sizeof(*m), GFP_NOFS); + m = kzalloc_obj(*m, GFP_NOFS); if (!m) return ERR_PTR(-ENOMEM); @@ -169,7 +169,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, */ m->possible_max_rank = max(m->m_num_active_mds, m->m_max_mds); - m->m_info = kcalloc(m->possible_max_rank, sizeof(*m->m_info), GFP_NOFS); + m->m_info = kzalloc_objs(*m->m_info, m->possible_max_rank, GFP_NOFS); if (!m->m_info) goto nomem; diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index d90eda19bcc4..4dc9426643e8 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c @@ -103,7 +103,7 @@ find_quotarealm_inode(struct ceph_mds_client *mdsc, u64 ino) } if (!qri || (qri->ino != ino)) { /* Not found, create a new one and insert it */ - qri = kmalloc(sizeof(*qri), GFP_KERNEL); + qri = kmalloc_obj(*qri); if (qri) { qri->ino = ino; qri->inode = NULL; diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 521507ea8260..52b4c2684f92 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -118,7 +118,7 @@ static struct ceph_snap_realm *ceph_create_snap_realm( lockdep_assert_held_write(&mdsc->snap_rwsem); - realm = kzalloc(sizeof(*realm), GFP_NOFS); + realm = kzalloc_obj(*realm, GFP_NOFS); if (!realm) return ERR_PTR(-ENOMEM); @@ -1216,7 +1216,7 @@ struct ceph_snapid_map* ceph_get_snapid_map(struct ceph_mds_client *mdsc, return exist; } - sm = kmalloc(sizeof(*sm), GFP_NOFS); + sm = kmalloc_obj(*sm, GFP_NOFS); if (!sm) return NULL; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 7c1c1dac320d..2aed6b3359b6 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -809,7 +809,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt, struct ceph_fs_client *fsc; int err; - fsc = kzalloc(sizeof(*fsc), GFP_KERNEL); + fsc = kzalloc_obj(*fsc); if (!fsc) { err = -ENOMEM; goto fail; @@ -1429,7 +1429,7 @@ static int ceph_init_fs_context(struct fs_context *fc) struct ceph_parse_opts_ctx *pctx; struct ceph_mount_options *fsopt; - pctx = kzalloc(sizeof(*pctx), GFP_KERNEL); + pctx = kzalloc_obj(*pctx); if (!pctx) return -ENOMEM; @@ -1437,7 +1437,7 @@ static int ceph_init_fs_context(struct fs_context *fc) if (!pctx->copts) goto nomem; - pctx->opts = kzalloc(sizeof(*pctx->opts), GFP_KERNEL); + pctx->opts = kzalloc_obj(*pctx->opts); if (!pctx->opts) goto nomem; diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index ad1f30bea175..5f87f62091a1 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c @@ -819,15 +819,15 @@ static int __build_xattrs(struct inode *inode) xattr_version = ci->i_xattrs.version; spin_unlock(&ci->i_ceph_lock); - xattrs = kcalloc(numattr, sizeof(struct ceph_inode_xattr *), - GFP_NOFS); + xattrs = kzalloc_objs(struct ceph_inode_xattr *, numattr, + GFP_NOFS); err = -ENOMEM; if (!xattrs) goto bad_lock; for (i = 0; i < numattr; i++) { - xattrs[i] = kmalloc(sizeof(struct ceph_inode_xattr), - GFP_NOFS); + xattrs[i] = kmalloc_obj(struct ceph_inode_xattr, + GFP_NOFS); if (!xattrs[i]) goto bad_lock; } @@ -1220,7 +1220,7 @@ int __ceph_setxattr(struct inode *inode, const char *name, goto out; } - xattr = kmalloc(sizeof(struct ceph_inode_xattr), GFP_NOFS); + xattr = kmalloc_obj(struct ceph_inode_xattr, GFP_NOFS); if (!xattr) goto out; diff --git a/fs/char_dev.c b/fs/char_dev.c index bf7b32650e54..00229e25c10f 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -115,7 +115,7 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, return ERR_PTR(-EINVAL); } - cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL); + cd = kzalloc_obj(struct char_device_struct); if (cd == NULL) return ERR_PTR(-ENOMEM); @@ -636,7 +636,7 @@ static struct kobj_type ktype_cdev_dynamic = { */ struct cdev *cdev_alloc(void) { - struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL); + struct cdev *p = kzalloc_obj(struct cdev); if (p) { INIT_LIST_HEAD(&p->list); kobject_init(&p->kobj, &ktype_cdev_dynamic); diff --git a/fs/coda/dir.c b/fs/coda/dir.c index ca9990017265..c64b8cd81568 100644 --- a/fs/coda/dir.c +++ b/fs/coda/dir.c @@ -362,7 +362,7 @@ static int coda_venus_readdir(struct file *coda_file, struct dir_context *ctx) cii = ITOC(file_inode(coda_file)); - vdir = kmalloc(sizeof(*vdir), GFP_KERNEL); + vdir = kmalloc_obj(*vdir); if (!vdir) return -ENOMEM; if (!dir_emit_dots(coda_file, ctx)) diff --git a/fs/coda/file.c b/fs/coda/file.c index a390b5d21196..6ca8bfcb58f2 100644 --- a/fs/coda/file.c +++ b/fs/coda/file.c @@ -175,7 +175,7 @@ coda_file_mmap(struct file *coda_file, struct vm_area_struct *vma) if (ret) return ret; - cvm_ops = kmalloc(sizeof(struct coda_vm_ops), GFP_KERNEL); + cvm_ops = kmalloc_obj(struct coda_vm_ops); if (!cvm_ops) return -ENOMEM; @@ -231,7 +231,7 @@ int coda_open(struct inode *coda_inode, struct file *coda_file) unsigned short coda_flags = coda_flags_to_cflags(flags); struct coda_file_info *cfi; - cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL); + cfi = kmalloc_obj(struct coda_file_info); if (!cfi) return -ENOMEM; diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 08450d006016..ad1654f3adf8 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -381,7 +381,7 @@ static int coda_init_fs_context(struct fs_context *fc) { struct coda_fs_context *ctx; - ctx = kzalloc(sizeof(struct coda_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct coda_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index cd6a3721f6f6..3438119b5dcf 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -724,7 +724,7 @@ static int coda_upcall(struct venus_comm *vcp, } /* Format the request message. */ - req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); + req = kmalloc_obj(struct upc_req); if (!req) { error = -ENOMEM; goto exit; @@ -788,10 +788,10 @@ static int coda_upcall(struct venus_comm *vcp, } error = -ENOMEM; - sig_req = kmalloc(sizeof(struct upc_req), GFP_KERNEL); + sig_req = kmalloc_obj(struct upc_req); if (!sig_req) goto exit; - sig_inputArgs = kvzalloc(sizeof(*sig_inputArgs), GFP_KERNEL); + sig_inputArgs = kvzalloc_obj(*sig_inputArgs); if (!sig_inputArgs) { kfree(sig_req); goto exit; diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index ba95f636a5ab..362b6ff9b908 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -159,7 +159,7 @@ static struct configfs_fragment *new_fragment(void) { struct configfs_fragment *p; - p = kmalloc(sizeof(struct configfs_fragment), GFP_KERNEL); + p = kmalloc_obj(struct configfs_fragment); if (p) { atomic_set(&p->frag_count, 1); init_rwsem(&p->frag_sem); @@ -1847,7 +1847,7 @@ configfs_register_default_group(struct config_group *parent_group, int ret; struct config_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return ERR_PTR(-ENOMEM); config_group_init_type_name(group, name, item_type); diff --git a/fs/configfs/file.c b/fs/configfs/file.c index affe4742bbb5..ef8c3cd10cc6 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c @@ -296,7 +296,7 @@ static int __configfs_open_file(struct inode *inode, struct file *file, int type int error; error = -ENOMEM; - buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL); + buffer = kzalloc_obj(struct configfs_buffer); if (!buffer) goto out; diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index bcda3372e141..bc507b720a01 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c @@ -47,7 +47,7 @@ int configfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, sd_iattr = sd->s_iattr; if (!sd_iattr) { /* setting attributes for the first time, allocate now */ - sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); + sd_iattr = kzalloc_obj(struct iattr); if (!sd_iattr) return -ENOMEM; /* assign default attributes */ diff --git a/fs/coredump.c b/fs/coredump.c index 4ce7c80b39c8..29df8aa19e2e 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -262,7 +262,7 @@ static bool coredump_parse(struct core_name *cn, struct coredump_params *cprm, switch (cn->core_type) { case COREDUMP_PIPE: { int argvs = sizeof(core_pattern) / 2; - (*argv) = kmalloc_array(argvs, sizeof(**argv), GFP_KERNEL); + (*argv) = kmalloc_objs(**argv, argvs); if (!(*argv)) return false; (*argv)[(*argc)++] = 0; @@ -1736,7 +1736,7 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) gate_vma = get_gate_vma(mm); cprm->vma_count = mm->map_count + (gate_vma ? 1 : 0); - cprm->vma_meta = kvmalloc_array(cprm->vma_count, sizeof(*cprm->vma_meta), GFP_KERNEL); + cprm->vma_meta = kvmalloc_objs(*cprm->vma_meta, cprm->vma_count); if (!cprm->vma_meta) { mmap_write_unlock(mm); return false; diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 41b1a869cf13..e0ba9cd640dc 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -619,7 +619,7 @@ static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *f struct cramfs_super super; int i, err; - sbi = kzalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct cramfs_sb_info); if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; @@ -640,7 +640,7 @@ static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc) struct cramfs_super super; int err; - sbi = kzalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct cramfs_sb_info); if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index a9a4432d12ba..629eb0d72e86 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -76,7 +76,7 @@ struct fscrypt_nokey_name { static inline bool fscrypt_is_dot_dotdot(const struct qstr *str) { - return is_dot_dotdot(str->name, str->len); + return name_is_dot_dotdot(str->name, str->len); } /** diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/inline_crypt.c index ed6e926226b5..c0852b920dbc 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/inline_crypt.c @@ -32,7 +32,7 @@ static struct block_device **fscrypt_get_devices(struct super_block *sb, if (devs) return devs; } - devs = kmalloc(sizeof(*devs), GFP_KERNEL); + devs = kmalloc_obj(*devs); if (!devs) return ERR_PTR(-ENOMEM); devs[0] = sb->s_bdev; @@ -169,7 +169,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key, unsigned int i; int err; - blk_key = kmalloc(sizeof(*blk_key), GFP_KERNEL); + blk_key = kmalloc_obj(*blk_key); if (!blk_key) return -ENOMEM; diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 5e939ea3ac28..9ec6e5ef0947 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -209,7 +209,7 @@ static int allocate_filesystem_keyring(struct super_block *sb) if (sb->s_master_keys) return 0; - keyring = kzalloc(sizeof(*keyring), GFP_KERNEL); + keyring = kzalloc_obj(*keyring); if (!keyring) return -ENOMEM; spin_lock_init(&keyring->lock); @@ -434,7 +434,7 @@ static int add_new_master_key(struct super_block *sb, struct fscrypt_master_key *mk; int err; - mk = kzalloc(sizeof(*mk), GFP_KERNEL); + mk = kzalloc_obj(*mk); if (!mk) return -ENOMEM; diff --git a/fs/crypto/keysetup_v1.c b/fs/crypto/keysetup_v1.c index c4d05168522b..3d673c36b678 100644 --- a/fs/crypto/keysetup_v1.c +++ b/fs/crypto/keysetup_v1.c @@ -221,7 +221,7 @@ fscrypt_get_direct_key(const struct fscrypt_inode_info *ci, const u8 *raw_key) return dk; /* Nope, allocate one. */ - dk = kzalloc(sizeof(*dk), GFP_KERNEL); + dk = kzalloc_obj(*dk); if (!dk) return ERR_PTR(-ENOMEM); dk->dk_sb = ci->ci_inode->i_sb; diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c index bbb2f5ced988..9915e39362db 100644 --- a/fs/crypto/policy.c +++ b/fs/crypto/policy.c @@ -813,7 +813,7 @@ int fscrypt_parse_test_dummy_encryption(const struct fs_parameter *param, if (param->type == fs_value_is_string && *param->string) arg = param->string; - policy = kzalloc(sizeof(*policy), GFP_KERNEL); + policy = kzalloc_obj(*policy); if (!policy) return -ENOMEM; diff --git a/fs/dcache.c b/fs/dcache.c index 2758fe7322d4..7ba1801d8132 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -1298,8 +1298,8 @@ void shrink_dcache_sb(struct super_block *sb) EXPORT_SYMBOL(shrink_dcache_sb); /** - * enum d_walk_ret - action to talke during tree walk - * @D_WALK_CONTINUE: contrinue walk + * enum d_walk_ret - action to take during tree walk + * @D_WALK_CONTINUE: continue walk * @D_WALK_QUIT: quit walk * @D_WALK_NORETRY: quit when retry is needed * @D_WALK_SKIP: skip this dentry and its children @@ -1722,7 +1722,7 @@ void d_invalidate(struct dentry *dentry) EXPORT_SYMBOL(d_invalidate); /** - * __d_alloc - allocate a dcache entry + * __d_alloc - allocate a dcache entry * @sb: filesystem it will belong to * @name: qstr of the name * @@ -1806,7 +1806,7 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) } /** - * d_alloc - allocate a dcache entry + * d_alloc - allocate a dcache entry * @parent: parent of entry to allocate * @name: qstr of the name * @@ -2546,7 +2546,7 @@ static void __d_rehash(struct dentry *entry) } /** - * d_rehash - add an entry back to the hash + * d_rehash - add an entry back to the hash * @entry: dentry to add to the hash * * Adds a dentry to the hash according to its name. diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 3ec3324c2060..3376ab6a519d 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -82,7 +82,7 @@ static int __debugfs_file_get(struct dentry *dentry, enum dbgfs_get_mode mode) if (WARN_ON(mode == DBGFS_GET_ALREADY)) return -EINVAL; - fsd = kmalloc(sizeof(*fsd), GFP_KERNEL); + fsd = kmalloc_obj(*fsd); if (!fsd) return -ENOMEM; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 4005d21cf009..4598142355b9 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -310,7 +310,7 @@ static int debugfs_init_fs_context(struct fs_context *fc) { struct debugfs_fs_info *fsi; - fsi = kzalloc(sizeof(struct debugfs_fs_info), GFP_KERNEL); + fsi = kzalloc_obj(struct debugfs_fs_info); if (!fsi) return -ENOMEM; diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 9f3de528c358..9844dcf354ee 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -420,7 +420,7 @@ static int devpts_init_fs_context(struct fs_context *fc) { struct pts_fs_info *fsi; - fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL); + fsi = kzalloc_obj(struct pts_fs_info); if (!fsi) return -ENOMEM; diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 82cc3215663f..53cd33293042 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c @@ -426,9 +426,9 @@ static struct config_group *make_cluster(struct config_group *g, struct dlm_spaces *sps = NULL; struct dlm_comms *cms = NULL; - cl = kzalloc(sizeof(struct dlm_cluster), GFP_NOFS); - sps = kzalloc(sizeof(struct dlm_spaces), GFP_NOFS); - cms = kzalloc(sizeof(struct dlm_comms), GFP_NOFS); + cl = kzalloc_obj(struct dlm_cluster, GFP_NOFS); + sps = kzalloc_obj(struct dlm_spaces, GFP_NOFS); + cms = kzalloc_obj(struct dlm_comms, GFP_NOFS); if (!cl || !sps || !cms) goto fail; @@ -480,8 +480,8 @@ static struct config_group *make_space(struct config_group *g, const char *name) struct dlm_space *sp = NULL; struct dlm_nodes *nds = NULL; - sp = kzalloc(sizeof(struct dlm_space), GFP_NOFS); - nds = kzalloc(sizeof(struct dlm_nodes), GFP_NOFS); + sp = kzalloc_obj(struct dlm_space, GFP_NOFS); + nds = kzalloc_obj(struct dlm_nodes, GFP_NOFS); if (!sp || !nds) goto fail; @@ -531,7 +531,7 @@ static struct config_item *make_comm(struct config_group *g, const char *name) if (rv) return ERR_PTR(rv); - cm = kzalloc(sizeof(struct dlm_comm), GFP_NOFS); + cm = kzalloc_obj(struct dlm_comm, GFP_NOFS); if (!cm) return ERR_PTR(-ENOMEM); @@ -577,7 +577,7 @@ static struct config_item *make_node(struct config_group *g, const char *name) if (rv) return ERR_PTR(rv); - nd = kzalloc(sizeof(struct dlm_node), GFP_NOFS); + nd = kzalloc_obj(struct dlm_node, GFP_NOFS); if (!nd) return ERR_PTR(-ENOMEM); @@ -602,7 +602,7 @@ static void drop_node(struct config_group *g, struct config_item *i) struct dlm_node *nd = config_item_to_node(i); struct dlm_member_gone *mb_gone; - mb_gone = kzalloc(sizeof(*mb_gone), GFP_KERNEL); + mb_gone = kzalloc_obj(*mb_gone); if (!mb_gone) return; @@ -701,7 +701,7 @@ static ssize_t comm_addr_store(struct config_item *item, const char *buf, if (cm->addr_count >= DLM_MAX_ADDR_COUNT) return -ENOSPC; - addr = kzalloc(sizeof(*addr), GFP_NOFS); + addr = kzalloc_obj(*addr, GFP_NOFS); if (!addr) return -ENOMEM; @@ -946,7 +946,7 @@ int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, count = sp->members_count + sp->members_gone_count; - nodes = kcalloc(count, sizeof(struct dlm_config_node), GFP_NOFS); + nodes = kzalloc_objs(struct dlm_config_node, count, GFP_NOFS); if (!nodes) { rv = -ENOMEM; goto out; diff --git a/fs/dlm/dir.c b/fs/dlm/dir.c index 01c292379f5b..aa08e8f446a1 100644 --- a/fs/dlm/dir.c +++ b/fs/dlm/dir.c @@ -276,7 +276,7 @@ static struct dlm_dir_dump *init_dir_dump(struct dlm_ls *ls, int nodeid) drop_dir_ctx(ls, nodeid); } - dd = kzalloc(sizeof(*dd), GFP_ATOMIC); + dd = kzalloc_obj(*dd, GFP_ATOMIC); if (!dd) return NULL; diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 47a09d6748cb..c381e1028446 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c @@ -5050,7 +5050,7 @@ void dlm_recover_waiters_pre(struct dlm_ls *ls) int wait_type, local_unlock_result, local_cancel_result; int dir_nodeid; - ms_local = kmalloc(sizeof(*ms_local), GFP_KERNEL); + ms_local = kmalloc_obj(*ms_local); if (!ms_local) return; @@ -6288,7 +6288,7 @@ int dlm_debug_add_lkb(struct dlm_ls *ls, uint32_t lkb_id, char *name, int len, if (lkb_dflags & BIT(DLM_DFL_USER_BIT)) return -EOPNOTSUPP; - lksb = kzalloc(sizeof(*lksb), GFP_NOFS); + lksb = kzalloc_obj(*lksb, GFP_NOFS); if (!lksb) return -ENOMEM; diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c index ddaa76558706..a9c98b4f378f 100644 --- a/fs/dlm/lockspace.c +++ b/fs/dlm/lockspace.c @@ -427,7 +427,7 @@ static int new_lockspace(const char *name, const char *cluster, error = -ENOMEM; - ls = kzalloc(sizeof(*ls), GFP_NOFS); + ls = kzalloc_obj(*ls, GFP_NOFS); if (!ls) goto out; memcpy(ls->ls_name, name, namelen); diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index b3958008ba3f..5b6142787919 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -305,7 +305,7 @@ static struct connection *nodeid2con(int nodeid, gfp_t alloc) if (con || !alloc) return con; - con = kzalloc(sizeof(*con), alloc); + con = kzalloc_obj(*con, alloc); if (!con) return NULL; @@ -838,7 +838,7 @@ static struct processqueue_entry *new_processqueue_entry(int nodeid, { struct processqueue_entry *pentry; - pentry = kmalloc(sizeof(*pentry), GFP_NOFS); + pentry = kmalloc_obj(*pentry, GFP_NOFS); if (!pentry) return NULL; @@ -1052,7 +1052,7 @@ static int accept_from_sock(void) struct connection *othercon = newcon->othercon; if (!othercon) { - othercon = kzalloc(sizeof(*othercon), GFP_NOFS); + othercon = kzalloc_obj(*othercon, GFP_NOFS); if (!othercon) { log_print("failed to allocate incoming socket"); up_write(&newcon->sock_lock); diff --git a/fs/dlm/member.c b/fs/dlm/member.c index c1b5598997b7..f84233a0fe4a 100644 --- a/fs/dlm/member.c +++ b/fs/dlm/member.c @@ -211,7 +211,7 @@ int dlm_slots_assign(struct dlm_ls *ls, int *num_slots, int *slots_size, } array_size = max + need; - array = kcalloc(array_size, sizeof(*array), GFP_NOFS); + array = kzalloc_objs(*array, array_size, GFP_NOFS); if (!array) return -ENOMEM; @@ -323,7 +323,7 @@ static int dlm_add_member(struct dlm_ls *ls, struct dlm_config_node *node) struct dlm_member *memb; int error; - memb = kzalloc(sizeof(*memb), GFP_NOFS); + memb = kzalloc_obj(*memb, GFP_NOFS); if (!memb) return -ENOMEM; @@ -423,7 +423,7 @@ static void make_member_array(struct dlm_ls *ls) } ls->ls_total_weight = total; - array = kmalloc_array(total, sizeof(*array), GFP_NOFS); + array = kmalloc_objs(*array, total, GFP_NOFS); if (!array) return; @@ -511,7 +511,7 @@ void dlm_lsop_recover_done(struct dlm_ls *ls) return; num = ls->ls_num_nodes; - slots = kcalloc(num, sizeof(*slots), GFP_KERNEL); + slots = kzalloc_objs(*slots, num); if (!slots) return; @@ -726,7 +726,7 @@ int dlm_ls_start(struct dlm_ls *ls) struct dlm_config_node *nodes = NULL; int error, count; - rv = kzalloc(sizeof(*rv), GFP_NOFS); + rv = kzalloc_obj(*rv, GFP_NOFS); if (!rv) return -ENOMEM; diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c index 2c101bbe261a..d54bdd8fc4f2 100644 --- a/fs/dlm/midcomms.c +++ b/fs/dlm/midcomms.c @@ -351,7 +351,7 @@ int dlm_midcomms_addr(int nodeid, struct sockaddr_storage *addr) } srcu_read_unlock(&nodes_srcu, idx); - node = kmalloc(sizeof(*node), GFP_NOFS); + node = kmalloc_obj(*node, GFP_NOFS); if (!node) return -ENOMEM; diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 9ca83ef70ed1..e9598b3fe5d0 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c @@ -102,7 +102,7 @@ static int do_lock_cancel(const struct dlm_plock_info *orig_info) struct plock_op *op; int rv; - op = kzalloc(sizeof(*op), GFP_NOFS); + op = kzalloc_obj(*op, GFP_NOFS); if (!op) return -ENOMEM; @@ -131,7 +131,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, if (!ls) return -EINVAL; - op = kzalloc(sizeof(*op), GFP_NOFS); + op = kzalloc_obj(*op, GFP_NOFS); if (!op) { rv = -ENOMEM; goto out; @@ -148,7 +148,7 @@ int dlm_posix_lock(dlm_lockspace_t *lockspace, u64 number, struct file *file, op->info.owner = (__u64)(long) fl->c.flc_owner; /* async handling */ if (fl->fl_lmops && fl->fl_lmops->lm_grant) { - op_data = kzalloc(sizeof(*op_data), GFP_NOFS); + op_data = kzalloc_obj(*op_data, GFP_NOFS); if (!op_data) { dlm_release_plock_op(op); rv = -ENOMEM; @@ -297,7 +297,7 @@ int dlm_posix_unlock(dlm_lockspace_t *lockspace, u64 number, struct file *file, if (!ls) return -EINVAL; - op = kzalloc(sizeof(*op), GFP_NOFS); + op = kzalloc_obj(*op, GFP_NOFS); if (!op) { rv = -ENOMEM; goto out; @@ -430,7 +430,7 @@ int dlm_posix_get(dlm_lockspace_t *lockspace, u64 number, struct file *file, if (!ls) return -EINVAL; - op = kzalloc(sizeof(*op), GFP_NOFS); + op = kzalloc_obj(*op, GFP_NOFS); if (!op) { rv = -ENOMEM; goto out; diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 51daf4acbe31..a8ed4c8fdc5b 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c @@ -262,7 +262,7 @@ static int device_user_lock(struct dlm_user_proc *proc, goto out; } - ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS); + ua = kzalloc_obj(struct dlm_user_args, GFP_NOFS); if (!ua) goto out; ua->proc = proc; @@ -307,7 +307,7 @@ static int device_user_unlock(struct dlm_user_proc *proc, if (!ls) return -ENOENT; - ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS); + ua = kzalloc_obj(struct dlm_user_args, GFP_NOFS); if (!ua) goto out; ua->proc = proc; @@ -645,7 +645,7 @@ static int device_open(struct inode *inode, struct file *file) if (!ls) return -ENOENT; - proc = kzalloc(sizeof(struct dlm_user_proc), GFP_NOFS); + proc = kzalloc_obj(struct dlm_user_proc, GFP_NOFS); if (!proc) { dlm_put_lockspace(ls); return -ENOMEM; diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index 260f8a4938b0..3b59346d68c5 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -645,7 +646,7 @@ static void ecryptfs_set_default_crypt_stat_vals( ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, mount_crypt_stat); ecryptfs_set_default_sizes(crypt_stat); - strcpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); + strscpy(crypt_stat->cipher, ECRYPTFS_DEFAULT_CIPHER); crypt_stat->key_size = ECRYPTFS_DEFAULT_KEY_BYTES; crypt_stat->flags &= ~(ECRYPTFS_KEY_VALID); crypt_stat->file_version = ECRYPTFS_FILE_VERSION; @@ -678,7 +679,6 @@ int ecryptfs_new_file_context(struct inode *ecryptfs_inode) struct ecryptfs_mount_crypt_stat *mount_crypt_stat = &ecryptfs_superblock_to_private( ecryptfs_inode->i_sb)->mount_crypt_stat; - int cipher_name_len; int rc = 0; ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat); @@ -692,12 +692,8 @@ int ecryptfs_new_file_context(struct inode *ecryptfs_inode) "to the inode key sigs; rc = [%d]\n", rc); goto out; } - cipher_name_len = - strlen(mount_crypt_stat->global_default_cipher_name); - memcpy(crypt_stat->cipher, - mount_crypt_stat->global_default_cipher_name, - cipher_name_len); - crypt_stat->cipher[cipher_name_len] = '\0'; + strscpy(crypt_stat->cipher, + mount_crypt_stat->global_default_cipher_name); crypt_stat->key_size = mount_crypt_stat->global_default_cipher_key_size; ecryptfs_generate_new_key(crypt_stat); @@ -861,11 +857,12 @@ u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes) /** * ecryptfs_cipher_code_to_string * @str: Destination to write out the cipher name + * @size: Destination buffer size * @cipher_code: The code to convert to cipher name string * * Returns zero on success */ -int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code) +int ecryptfs_cipher_code_to_string(char *str, size_t size, u8 cipher_code) { int rc = 0; int i; @@ -873,7 +870,8 @@ int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code) str[0] = '\0'; for (i = 0; i < ARRAY_SIZE(ecryptfs_cipher_code_str_map); i++) if (cipher_code == ecryptfs_cipher_code_str_map[i].cipher_code) - strcpy(str, ecryptfs_cipher_code_str_map[i].cipher_str); + strscpy(str, ecryptfs_cipher_code_str_map[i].cipher_str, + size); if (str[0] == '\0') { ecryptfs_printk(KERN_WARNING, "Cipher code not recognized: " "[%d]\n", cipher_code); @@ -1220,7 +1218,7 @@ static int ecryptfs_read_headers_virt(char *page_virt, /** * ecryptfs_read_xattr_region - * @page_virt: The vitual address into which to read the xattr data + * @page_virt: The virtual address into which to read the xattr data * @ecryptfs_inode: The eCryptfs inode * * Attempts to read the crypto metadata from the extended attribute @@ -1420,21 +1418,11 @@ ecryptfs_encrypt_filename(struct ecryptfs_filename *filename, static int ecryptfs_copy_filename(char **copied_name, size_t *copied_name_size, const char *name, size_t name_size) { - int rc = 0; - - (*copied_name) = kmalloc((name_size + 1), GFP_KERNEL); - if (!(*copied_name)) { - rc = -ENOMEM; - goto out; - } - memcpy((void *)(*copied_name), (void *)name, name_size); - (*copied_name)[(name_size)] = '\0'; /* Only for convenience - * in printing out the - * string in debug - * messages */ + (*copied_name) = kmemdup_nul(name, name_size, GFP_KERNEL); + if (!(*copied_name)) + return -ENOMEM; (*copied_name_size) = name_size; -out: - return rc; + return 0; } /** @@ -1805,7 +1793,7 @@ int ecryptfs_encrypt_and_encode_filename( & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES)) { struct ecryptfs_filename *filename; - filename = kzalloc(sizeof(*filename), GFP_KERNEL); + filename = kzalloc_obj(*filename); if (!filename) { rc = -ENOMEM; goto out; @@ -1904,7 +1892,7 @@ int ecryptfs_decode_and_decrypt_filename(char **plaintext_name, if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) && !(mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED)) { - if (is_dot_dotdot(name, name_size)) { + if (name_is_dot_dotdot(name, name_size)) { rc = ecryptfs_copy_filename(plaintext_name, plaintext_name_size, name, name_size); diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c index cf6d0e8e25a1..c185a8cb5fe2 100644 --- a/fs/ecryptfs/debug.c +++ b/fs/ecryptfs/debug.c @@ -28,7 +28,6 @@ void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok) ecryptfs_printk(KERN_DEBUG, " * passphrase type\n"); ecryptfs_to_hex(salt, auth_tok->token.password.salt, ECRYPTFS_SALT_SIZE); - salt[ECRYPTFS_SALT_SIZE * 2] = '\0'; ecryptfs_printk(KERN_DEBUG, " * salt = [%s]\n", salt); if (auth_tok->token.password.flags & ECRYPTFS_PERSISTENT_PASSWORD) { diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 509293745ce9..f4f56a92bd56 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h @@ -543,7 +543,6 @@ int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, size_t *decrypted_name_size, struct super_block *sb, const char *name, size_t name_size); -int ecryptfs_fill_zeros(struct file *file, loff_t new_length); int ecryptfs_encrypt_and_encode_filename( char **encoded_name, size_t *encoded_name_size, @@ -573,7 +572,7 @@ int ecryptfs_read_and_validate_header_region(struct inode *inode); int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, struct inode *inode); u8 ecryptfs_code_for_cipher_string(char *cipher_name, size_t key_bytes); -int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); +int ecryptfs_cipher_code_to_string(char *str, size_t size, u8 cipher_code); void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); int ecryptfs_generate_key_packet_set(char *dest_base, struct ecryptfs_crypt_stat *crypt_stat, diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index bbf8603242fa..e8494903bb42 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c @@ -354,7 +354,7 @@ parse_tag_67_packet(struct ecryptfs_key_record *key_rec, int rc; /* - * ***** TAG 65 Packet Format ***** + * ***** TAG 67 Packet Format ***** * | Content Type | 1 byte | * | Status Indicator | 1 byte | * | Encrypted File Encryption Key Size | 1 or 2 bytes | @@ -623,7 +623,7 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, struct key *auth_tok_key = NULL; int rc = 0; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; @@ -837,7 +837,7 @@ struct ecryptfs_parse_tag_70_packet_silly_stack { * @filename: This function kmalloc's the memory for the filename * @filename_size: This function sets this to the amount of memory * kmalloc'd for the filename - * @packet_size: This function sets this to the the number of octets + * @packet_size: This function sets this to the number of octets * in the packet parsed * @mount_crypt_stat: The mount-wide cryptographic context * @data: The memory location containing the start of the tag 70 @@ -860,7 +860,7 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, (*packet_size) = 0; (*filename_size) = 0; (*filename) = NULL; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; @@ -908,10 +908,11 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size, (*packet_size) += s->packet_size_len; ecryptfs_to_hex(s->fnek_sig_hex, &data[(*packet_size)], ECRYPTFS_SIG_SIZE); - s->fnek_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0'; (*packet_size) += ECRYPTFS_SIG_SIZE; s->cipher_code = data[(*packet_size)++]; - rc = ecryptfs_cipher_code_to_string(s->cipher_string, s->cipher_code); + rc = ecryptfs_cipher_code_to_string(s->cipher_string, + sizeof(s->cipher_string), + s->cipher_code); if (rc) { printk(KERN_WARNING "%s: Cipher code [%d] is invalid\n", __func__, s->cipher_code); @@ -1129,7 +1130,9 @@ decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, auth_tok->session_key.decrypted_key_size); crypt_stat->key_size = auth_tok->session_key.decrypted_key_size; - rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, cipher_code); + rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, + sizeof(crypt_stat->cipher), + cipher_code); if (rc) { ecryptfs_printk(KERN_ERR, "Cipher code [%d] is invalid\n", cipher_code); @@ -1395,6 +1398,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat, goto out_free; } rc = ecryptfs_cipher_code_to_string(crypt_stat->cipher, + sizeof(crypt_stat->cipher), (u16)data[(*packet_size)]); if (rc) goto out_free; @@ -1716,7 +1720,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, size_t i = 0; size_t found_auth_tok; size_t next_packet_is_auth_tok_packet; - struct list_head auth_tok_list; + LIST_HEAD(auth_tok_list); struct ecryptfs_auth_tok *matching_auth_tok; struct ecryptfs_auth_tok *candidate_auth_tok; char *candidate_auth_tok_sig; @@ -1729,7 +1733,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, struct key *auth_tok_key = NULL; int rc = 0; - INIT_LIST_HEAD(&auth_tok_list); /* Parse the header to find as many packets as we can; these will be * added the our &auth_tok_list */ next_packet_is_auth_tok_packet = 1; @@ -1777,8 +1780,6 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, } ecryptfs_to_hex(new_auth_tok->token.password.signature, sig_tmp_space, tag_11_contents_size); - new_auth_tok->token.password.signature[ - ECRYPTFS_PASSWORD_SIG_SIZE] = '\0'; crypt_stat->flags |= ECRYPTFS_ENCRYPTED; break; case ECRYPTFS_TAG_1_PACKET_TYPE: diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index c12dc680f8fe..f4ab387eb4ed 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "ecryptfs_kernel.h" @@ -354,13 +355,13 @@ static int ecryptfs_validate_options(struct fs_context *fc) int cipher_name_len = strlen(ECRYPTFS_DEFAULT_CIPHER); BUG_ON(cipher_name_len > ECRYPTFS_MAX_CIPHER_NAME_SIZE); - strcpy(mount_crypt_stat->global_default_cipher_name, - ECRYPTFS_DEFAULT_CIPHER); + strscpy(mount_crypt_stat->global_default_cipher_name, + ECRYPTFS_DEFAULT_CIPHER); } if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) && !ctx->fn_cipher_name_set) - strcpy(mount_crypt_stat->global_default_fn_cipher_name, - mount_crypt_stat->global_default_cipher_name); + strscpy(mount_crypt_stat->global_default_fn_cipher_name, + mount_crypt_stat->global_default_cipher_name); if (!ctx->cipher_key_bytes_set) mount_crypt_stat->global_default_cipher_key_size = 0; if ((mount_crypt_stat->flags & ECRYPTFS_GLOBAL_ENCRYPT_FILENAMES) @@ -609,7 +610,7 @@ static int ecryptfs_init_fs_context(struct fs_context *fc) struct ecryptfs_fs_context *ctx; struct ecryptfs_sb_info *sbi = NULL; - ctx = kzalloc(sizeof(struct ecryptfs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct ecryptfs_fs_context); if (!ctx) return -ENOMEM; sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index 6318f3500e5c..30c8e15d87b5 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c @@ -131,7 +131,7 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) { int rc = 0; - (*daemon) = kzalloc(sizeof(**daemon), GFP_KERNEL); + (*daemon) = kzalloc_obj(**daemon); if (!(*daemon)) { rc = -ENOMEM; goto out; diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 9da992925920..1c5224cf183e 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -44,7 +44,7 @@ static int efivarfs_ops_notifier(struct notifier_block *nb, unsigned long event, static struct inode *efivarfs_alloc_inode(struct super_block *sb) { - struct efivar_entry *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct efivar_entry *entry = kzalloc_obj(*entry); if (!entry) return NULL; @@ -505,7 +505,7 @@ static int efivarfs_init_fs_context(struct fs_context *fc) if (!efivar_is_available()) return -EOPNOTSUPP; - sfi = kzalloc(sizeof(*sfi), GFP_KERNEL); + sfi = kzalloc_obj(*sfi); if (!sfi) return -ENOMEM; diff --git a/fs/efs/super.c b/fs/efs/super.c index c59086b7eabf..11fea3bbce7c 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -243,7 +243,7 @@ static int efs_fill_super(struct super_block *s, struct fs_context *fc) struct buffer_head *bh; struct inode *root; - sb = kzalloc(sizeof(struct efs_sb_info), GFP_KERNEL); + sb = kzalloc_obj(struct efs_sb_info); if (!sb) return -ENOMEM; s->s_fs_info = sb; diff --git a/fs/erofs/data.c b/fs/erofs/data.c index a28084ef796b..f79ee80627d9 100644 --- a/fs/erofs/data.c +++ b/fs/erofs/data.c @@ -473,11 +473,12 @@ static int erofs_file_mmap_prepare(struct vm_area_desc *desc) if (!IS_DAX(file_inode(desc->file))) return generic_file_readonly_mmap_prepare(desc); - if ((desc->vm_flags & VM_SHARED) && (desc->vm_flags & VM_MAYWRITE)) + if (vma_desc_test_flags(desc, VMA_SHARED_BIT) && + vma_desc_test_flags(desc, VMA_MAYWRITE_BIT)) return -EINVAL; desc->vm_ops = &erofs_dax_vm_ops; - desc->vm_flags |= VM_HUGEPAGE; + vma_desc_set_flags(desc, VMA_HUGEPAGE_BIT); return 0; } #else diff --git a/fs/erofs/decompressor_deflate.c b/fs/erofs/decompressor_deflate.c index 4f26ab767645..6167af1ffeb9 100644 --- a/fs/erofs/decompressor_deflate.c +++ b/fs/erofs/decompressor_deflate.c @@ -71,7 +71,7 @@ static int z_erofs_load_deflate_config(struct super_block *sb, ++z_erofs_deflate_avail_strms) { struct z_erofs_deflate *strm; - strm = kzalloc(sizeof(*strm), GFP_KERNEL); + strm = kzalloc_obj(*strm); if (!strm) goto failed; /* XXX: in-kernel zlib cannot customize windowbits */ diff --git a/fs/erofs/decompressor_lzma.c b/fs/erofs/decompressor_lzma.c index b4ea6978faae..f6692d0f2f04 100644 --- a/fs/erofs/decompressor_lzma.c +++ b/fs/erofs/decompressor_lzma.c @@ -54,7 +54,7 @@ static int __init z_erofs_lzma_init(void) z_erofs_lzma_nstrms = num_possible_cpus(); for (i = 0; i < z_erofs_lzma_nstrms; ++i) { - struct z_erofs_lzma *strm = kzalloc(sizeof(*strm), GFP_KERNEL); + struct z_erofs_lzma *strm = kzalloc_obj(*strm); if (!strm) { z_erofs_lzma_exit(); diff --git a/fs/erofs/decompressor_zstd.c b/fs/erofs/decompressor_zstd.c index beae49165c69..ab318a2400f9 100644 --- a/fs/erofs/decompressor_zstd.c +++ b/fs/erofs/decompressor_zstd.c @@ -59,7 +59,7 @@ static int __init z_erofs_zstd_init(void) ++z_erofs_zstd_avail_strms) { struct z_erofs_zstd *strm; - strm = kzalloc(sizeof(*strm), GFP_KERNEL); + strm = kzalloc_obj(*strm); if (!strm) { z_erofs_zstd_exit(); return -ENOMEM; diff --git a/fs/erofs/fileio.c b/fs/erofs/fileio.c index 4d5054dcac95..abe873f01297 100644 --- a/fs/erofs/fileio.c +++ b/fs/erofs/fileio.c @@ -68,8 +68,7 @@ static void erofs_fileio_rq_submit(struct erofs_fileio_rq *rq) static struct erofs_fileio_rq *erofs_fileio_rq_alloc(struct erofs_map_dev *mdev) { - struct erofs_fileio_rq *rq = kzalloc(sizeof(*rq), - GFP_KERNEL | __GFP_NOFAIL); + struct erofs_fileio_rq *rq = kzalloc_obj(*rq, GFP_KERNEL | __GFP_NOFAIL); bio_init(&rq->bio, NULL, rq->bvecs, ARRAY_SIZE(rq->bvecs), REQ_OP_READ); rq->iocb.ki_filp = mdev->m_dif->file; diff --git a/fs/erofs/fscache.c b/fs/erofs/fscache.c index a2cc0f3fa9d0..685c68774379 100644 --- a/fs/erofs/fscache.c +++ b/fs/erofs/fscache.c @@ -70,7 +70,7 @@ static void erofs_fscache_req_put(struct erofs_fscache_rq *req) static struct erofs_fscache_rq *erofs_fscache_req_alloc(struct address_space *mapping, loff_t start, size_t len) { - struct erofs_fscache_rq *req = kzalloc(sizeof(*req), GFP_KERNEL); + struct erofs_fscache_rq *req = kzalloc_obj(*req); if (!req) return NULL; @@ -101,7 +101,7 @@ static void erofs_fscache_req_end_io(void *priv, ssize_t transferred_or_error) static struct erofs_fscache_io *erofs_fscache_req_io_alloc(struct erofs_fscache_rq *req) { - struct erofs_fscache_io *io = kzalloc(sizeof(*io), GFP_KERNEL); + struct erofs_fscache_io *io = kzalloc_obj(*io); if (!io) return NULL; @@ -181,7 +181,7 @@ struct bio *erofs_fscache_bio_alloc(struct erofs_map_dev *mdev) { struct erofs_fscache_bio *io; - io = kmalloc(sizeof(*io), GFP_KERNEL | __GFP_NOFAIL); + io = kmalloc_obj(*io, GFP_KERNEL | __GFP_NOFAIL); bio_init(&io->bio, NULL, io->bvecs, BIO_MAX_VECS, REQ_OP_READ); io->io.private = mdev->m_dif->fscache->cookie; io->io.end_io = erofs_fscache_bio_endio; @@ -417,7 +417,7 @@ static int erofs_fscache_init_domain(struct super_block *sb) struct erofs_domain *domain; struct erofs_sb_info *sbi = EROFS_SB(sb); - domain = kzalloc(sizeof(struct erofs_domain), GFP_KERNEL); + domain = kzalloc_obj(struct erofs_domain); if (!domain) return -ENOMEM; @@ -482,7 +482,7 @@ static struct erofs_fscache *erofs_fscache_acquire_cookie(struct super_block *sb struct inode *inode; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&ctx->node); diff --git a/fs/erofs/inode.c b/fs/erofs/inode.c index 4f86169c23f1..4b3d21402e10 100644 --- a/fs/erofs/inode.c +++ b/fs/erofs/inode.c @@ -222,6 +222,7 @@ static int erofs_read_inode(struct inode *inode) static int erofs_fill_inode(struct inode *inode) { + const struct address_space_operations *aops; int err; trace_erofs_fill_inode(inode); @@ -254,7 +255,11 @@ static int erofs_fill_inode(struct inode *inode) } mapping_set_large_folios(inode->i_mapping); - return erofs_inode_set_aops(inode, inode, false); + aops = erofs_get_aops(inode, false); + if (IS_ERR(aops)) + return PTR_ERR(aops); + inode->i_mapping->a_ops = aops; + return 0; } /* diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h index d1634455e389..a4f0a42cf8c3 100644 --- a/fs/erofs/internal.h +++ b/fs/erofs/internal.h @@ -471,26 +471,24 @@ static inline void *erofs_vm_map_ram(struct page **pages, unsigned int count) return NULL; } -static inline int erofs_inode_set_aops(struct inode *inode, - struct inode *realinode, bool no_fscache) +static inline const struct address_space_operations * +erofs_get_aops(struct inode *realinode, bool no_fscache) { if (erofs_inode_is_data_compressed(EROFS_I(realinode)->datalayout)) { if (!IS_ENABLED(CONFIG_EROFS_FS_ZIP)) - return -EOPNOTSUPP; + return ERR_PTR(-EOPNOTSUPP); DO_ONCE_LITE_IF(realinode->i_blkbits != PAGE_SHIFT, erofs_info, realinode->i_sb, "EXPERIMENTAL EROFS subpage compressed block support in use. Use at your own risk!"); - inode->i_mapping->a_ops = &z_erofs_aops; - return 0; + return &z_erofs_aops; } - inode->i_mapping->a_ops = &erofs_aops; if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND) && !no_fscache && erofs_is_fscache_mode(realinode->i_sb)) - inode->i_mapping->a_ops = &erofs_fscache_access_aops; + return &erofs_fscache_access_aops; if (IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) && erofs_is_fileio_mode(EROFS_SB(realinode->i_sb))) - inode->i_mapping->a_ops = &erofs_fileio_aops; - return 0; + return &erofs_fileio_aops; + return &erofs_aops; } int erofs_register_sysfs(struct super_block *sb); diff --git a/fs/erofs/ishare.c b/fs/erofs/ishare.c index ce980320a8b9..829d50d5c717 100644 --- a/fs/erofs/ishare.c +++ b/fs/erofs/ishare.c @@ -40,10 +40,14 @@ bool erofs_ishare_fill_inode(struct inode *inode) { struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb); struct erofs_inode *vi = EROFS_I(inode); + const struct address_space_operations *aops; struct erofs_inode_fingerprint fp; struct inode *sharedinode; unsigned long hash; + aops = erofs_get_aops(inode, true); + if (IS_ERR(aops)) + return false; if (erofs_xattr_fill_inode_fingerprint(&fp, inode, sbi->domain_id)) return false; hash = xxh32(fp.opaque, fp.size, 0); @@ -56,15 +60,15 @@ bool erofs_ishare_fill_inode(struct inode *inode) } if (inode_state_read_once(sharedinode) & I_NEW) { - if (erofs_inode_set_aops(sharedinode, inode, true)) { - iget_failed(sharedinode); - kfree(fp.opaque); - return false; - } + sharedinode->i_mapping->a_ops = aops; sharedinode->i_size = vi->vfs_inode.i_size; unlock_new_inode(sharedinode); } else { kfree(fp.opaque); + if (aops != sharedinode->i_mapping->a_ops) { + iput(sharedinode); + return false; + } if (sharedinode->i_size != vi->vfs_inode.i_size) { _erofs_printk(inode->i_sb, KERN_WARNING "size(%lld:%lld) not matches for the same fingerprint\n", diff --git a/fs/erofs/super.c b/fs/erofs/super.c index 7827e61424b7..972a0c82198d 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -226,7 +226,7 @@ static int erofs_scan_devices(struct super_block *sb, } } else { for (id = 0; id < ondisk_extradevs; id++) { - dif = kzalloc(sizeof(*dif), GFP_KERNEL); + dif = kzalloc_obj(*dif); if (!dif) { err = -ENOMEM; break; @@ -424,26 +424,23 @@ static const struct fs_parameter_spec erofs_fs_parameters[] = { static bool erofs_fc_set_dax_mode(struct fs_context *fc, unsigned int mode) { -#ifdef CONFIG_FS_DAX - struct erofs_sb_info *sbi = fc->s_fs_info; + if (IS_ENABLED(CONFIG_FS_DAX)) { + struct erofs_sb_info *sbi = fc->s_fs_info; - switch (mode) { - case EROFS_MOUNT_DAX_ALWAYS: - set_opt(&sbi->opt, DAX_ALWAYS); - clear_opt(&sbi->opt, DAX_NEVER); - return true; - case EROFS_MOUNT_DAX_NEVER: - set_opt(&sbi->opt, DAX_NEVER); - clear_opt(&sbi->opt, DAX_ALWAYS); - return true; - default: + if (mode == EROFS_MOUNT_DAX_ALWAYS) { + set_opt(&sbi->opt, DAX_ALWAYS); + clear_opt(&sbi->opt, DAX_NEVER); + return true; + } else if (mode == EROFS_MOUNT_DAX_NEVER) { + set_opt(&sbi->opt, DAX_NEVER); + clear_opt(&sbi->opt, DAX_ALWAYS); + return true; + } DBG_BUGON(1); return false; } -#else errorfc(fc, "dax options not supported"); return false; -#endif } static int erofs_fc_parse_param(struct fs_context *fc, @@ -460,31 +457,26 @@ static int erofs_fc_parse_param(struct fs_context *fc, switch (opt) { case Opt_user_xattr: -#ifdef CONFIG_EROFS_FS_XATTR - if (result.boolean) + if (!IS_ENABLED(CONFIG_EROFS_FS_XATTR)) + errorfc(fc, "{,no}user_xattr options not supported"); + else if (result.boolean) set_opt(&sbi->opt, XATTR_USER); else clear_opt(&sbi->opt, XATTR_USER); -#else - errorfc(fc, "{,no}user_xattr options not supported"); -#endif break; case Opt_acl: -#ifdef CONFIG_EROFS_FS_POSIX_ACL - if (result.boolean) + if (!IS_ENABLED(CONFIG_EROFS_FS_POSIX_ACL)) + errorfc(fc, "{,no}acl options not supported"); + else if (result.boolean) set_opt(&sbi->opt, POSIX_ACL); else clear_opt(&sbi->opt, POSIX_ACL); -#else - errorfc(fc, "{,no}acl options not supported"); -#endif break; case Opt_cache_strategy: -#ifdef CONFIG_EROFS_FS_ZIP - sbi->opt.cache_strategy = result.uint_32; -#else - errorfc(fc, "compression not supported, cache_strategy ignored"); -#endif + if (!IS_ENABLED(CONFIG_EROFS_FS_ZIP)) + errorfc(fc, "compression not supported, cache_strategy ignored"); + else + sbi->opt.cache_strategy = result.uint_32; break; case Opt_dax: if (!erofs_fc_set_dax_mode(fc, EROFS_MOUNT_DAX_ALWAYS)) @@ -495,7 +487,7 @@ static int erofs_fc_parse_param(struct fs_context *fc, return -EINVAL; break; case Opt_device: - dif = kzalloc(sizeof(*dif), GFP_KERNEL); + dif = kzalloc_obj(*dif); if (!dif) return -ENOMEM; dif->path = kstrdup(param->string, GFP_KERNEL); @@ -533,24 +525,21 @@ static int erofs_fc_parse_param(struct fs_context *fc, break; #endif case Opt_directio: -#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE - if (result.boolean) + if (!IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE)) + errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name); + else if (result.boolean) set_opt(&sbi->opt, DIRECT_IO); else clear_opt(&sbi->opt, DIRECT_IO); -#else - errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name); -#endif break; case Opt_fsoffset: sbi->dif0.fsoff = result.uint_64; break; case Opt_inode_share: -#ifdef CONFIG_EROFS_FS_PAGE_CACHE_SHARE - set_opt(&sbi->opt, INODE_SHARE); -#else - errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name); -#endif + if (!IS_ENABLED(CONFIG_EROFS_FS_PAGE_CACHE_SHARE)) + errorfc(fc, "%s option not supported", erofs_fs_parameters[opt].name); + else + set_opt(&sbi->opt, INODE_SHARE); break; } return 0; @@ -809,8 +798,7 @@ static int erofs_fc_get_tree(struct fs_context *fc) ret = get_tree_bdev_flags(fc, erofs_fc_fill_super, IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) ? GET_TREE_BDEV_QUIET_LOOKUP : 0); -#ifdef CONFIG_EROFS_FS_BACKED_BY_FILE - if (ret == -ENOTBLK) { + if (IS_ENABLED(CONFIG_EROFS_FS_BACKED_BY_FILE) && ret == -ENOTBLK) { struct file *file; if (!fc->source) @@ -824,7 +812,6 @@ static int erofs_fc_get_tree(struct fs_context *fc) sbi->dif0.file->f_mapping->a_ops->read_folio) return get_tree_nodev(fc, erofs_fc_fill_super); } -#endif return ret; } @@ -903,11 +890,11 @@ static int erofs_init_fs_context(struct fs_context *fc) { struct erofs_sb_info *sbi; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; - sbi->devs = kzalloc(sizeof(struct erofs_dev_context), GFP_KERNEL); + sbi->devs = kzalloc_obj(struct erofs_dev_context); if (!sbi->devs) { kfree(sbi); return -ENOMEM; @@ -1108,12 +1095,12 @@ static int erofs_show_options(struct seq_file *seq, struct dentry *root) seq_puts(seq, ",dax=never"); if (erofs_is_fileio_mode(sbi) && test_opt(opt, DIRECT_IO)) seq_puts(seq, ",directio"); -#ifdef CONFIG_EROFS_FS_ONDEMAND - if (sbi->fsid) - seq_printf(seq, ",fsid=%s", sbi->fsid); - if (sbi->domain_id) - seq_printf(seq, ",domain_id=%s", sbi->domain_id); -#endif + if (IS_ENABLED(CONFIG_EROFS_FS_ONDEMAND)) { + if (sbi->fsid) + seq_printf(seq, ",fsid=%s", sbi->fsid); + if (sbi->domain_id) + seq_printf(seq, ",domain_id=%s", sbi->domain_id); + } if (sbi->dif0.fsoff) seq_printf(seq, ",fsoffset=%llu", sbi->dif0.fsoff); if (test_opt(opt, INODE_SHARE)) diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c index b7da1ed83160..c411df5d9dfc 100644 --- a/fs/erofs/xattr.c +++ b/fs/erofs/xattr.c @@ -85,8 +85,7 @@ static int erofs_init_inode_xattrs(struct inode *inode) } vi->xattr_name_filter = le32_to_cpu(ih->h_name_filter); vi->xattr_shared_count = ih->h_shared_count; - vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count, - sizeof(uint), GFP_KERNEL); + vi->xattr_shared_xattrs = kmalloc_objs(uint, vi->xattr_shared_count); if (!vi->xattr_shared_xattrs) { erofs_put_metabuf(&buf); ret = -ENOMEM; @@ -498,7 +497,7 @@ int erofs_xattr_prefixes_init(struct super_block *sb) if (!sbi->xattr_prefix_count) return 0; - pfs = kcalloc(sbi->xattr_prefix_count, sizeof(*pfs), GFP_KERNEL); + pfs = kzalloc_objs(*pfs, sbi->xattr_prefix_count); if (!pfs) return -ENOMEM; diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c index ea9d32e9cb12..3977e42b9516 100644 --- a/fs/erofs/zdata.c +++ b/fs/erofs/zdata.c @@ -323,8 +323,8 @@ static int erofs_init_percpu_workers(void) struct kthread_worker *worker; unsigned int cpu; - z_erofs_pcpu_workers = kcalloc(num_possible_cpus(), - sizeof(struct kthread_worker *), GFP_ATOMIC); + z_erofs_pcpu_workers = kzalloc_objs(struct kthread_worker *, + num_possible_cpus(), GFP_ATOMIC); if (!z_erofs_pcpu_workers) return -ENOMEM; @@ -1144,7 +1144,7 @@ static void z_erofs_do_decompressed_bvec(struct z_erofs_backend *be, } /* (cold path) one pcluster is requested multiple times */ - item = kmalloc(sizeof(*item), GFP_KERNEL | __GFP_NOFAIL); + item = kmalloc_obj(*item, GFP_KERNEL | __GFP_NOFAIL); item->bvec = *bvec; list_add(&item->list, &be->decompressed_secondary_bvecs); } @@ -1282,12 +1282,12 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, bool eio) if (!be->decompressed_pages) be->decompressed_pages = - kvcalloc(be->nr_pages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kvzalloc_objs(struct page *, be->nr_pages, + GFP_KERNEL | __GFP_NOFAIL); if (!be->compressed_pages) be->compressed_pages = - kvcalloc(pclusterpages, sizeof(struct page *), - GFP_KERNEL | __GFP_NOFAIL); + kvzalloc_objs(struct page *, pclusterpages, + GFP_KERNEL | __GFP_NOFAIL); z_erofs_parse_out_bvecs(be); err2 = z_erofs_parse_in_bvecs(be, &overlapped); @@ -1590,7 +1590,7 @@ static struct z_erofs_decompressqueue *jobqueue_init(struct super_block *sb, struct z_erofs_decompressqueue *q; if (fg && !*fg) { - q = kvzalloc(sizeof(*q), GFP_KERNEL | __GFP_NOWARN); + q = kvzalloc_obj(*q, GFP_KERNEL | __GFP_NOWARN); if (!q) { *fg = true; goto fg_out; diff --git a/fs/erofs/zmap.c b/fs/erofs/zmap.c index c8d8e129eb4b..30775502b56d 100644 --- a/fs/erofs/zmap.c +++ b/fs/erofs/zmap.c @@ -513,6 +513,7 @@ static int z_erofs_map_blocks_ext(struct inode *inode, unsigned int recsz = z_erofs_extent_recsize(vi->z_advise); erofs_off_t pos = round_up(Z_EROFS_MAP_HEADER_END(erofs_iloc(inode) + vi->inode_isize + vi->xattr_isize), recsz); + unsigned int bmask = sb->s_blocksize - 1; bool in_mbox = erofs_inode_in_metabox(inode); erofs_off_t lend = inode->i_size; erofs_off_t l, r, mid, pa, la, lstart; @@ -596,17 +597,17 @@ static int z_erofs_map_blocks_ext(struct inode *inode, map->m_flags |= EROFS_MAP_MAPPED | EROFS_MAP_FULL_MAPPED | EROFS_MAP_ENCODED; fmt = map->m_plen >> Z_EROFS_EXTENT_PLEN_FMT_BIT; + if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL) + map->m_flags |= EROFS_MAP_PARTIAL_REF; + map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK; if (fmt) map->m_algorithmformat = fmt - 1; - else if (interlaced && !erofs_blkoff(sb, map->m_pa)) + else if (interlaced && !((map->m_pa | map->m_plen) & bmask)) map->m_algorithmformat = Z_EROFS_COMPRESSION_INTERLACED; else map->m_algorithmformat = Z_EROFS_COMPRESSION_SHIFTED; - if (map->m_plen & Z_EROFS_EXTENT_PLEN_PARTIAL) - map->m_flags |= EROFS_MAP_PARTIAL_REF; - map->m_plen &= Z_EROFS_EXTENT_PLEN_MASK; } } map->m_llen = lend - map->m_la; diff --git a/fs/erofs/zutil.c b/fs/erofs/zutil.c index 55ff2ab5128e..a0ce9226bc02 100644 --- a/fs/erofs/zutil.c +++ b/fs/erofs/zutil.c @@ -79,7 +79,7 @@ int z_erofs_gbuf_growsize(unsigned int nrpages) for (i = 0; i < z_erofs_gbuf_count; ++i) { gbuf = &z_erofs_gbufpool[i]; - tmp_pages = kcalloc(nrpages, sizeof(*tmp_pages), GFP_KERNEL); + tmp_pages = kzalloc_objs(*tmp_pages, nrpages); if (!tmp_pages) goto out; @@ -131,15 +131,14 @@ int __init z_erofs_gbuf_init(void) /* The last (special) global buffer is the reserved buffer */ total += !!z_erofs_rsv_nrpages; - z_erofs_gbufpool = kcalloc(total, sizeof(*z_erofs_gbufpool), - GFP_KERNEL); + z_erofs_gbufpool = kzalloc_objs(*z_erofs_gbufpool, total); if (!z_erofs_gbufpool) return -ENOMEM; if (z_erofs_rsv_nrpages) { z_erofs_rsvbuf = &z_erofs_gbufpool[total - 1]; - z_erofs_rsvbuf->pages = kcalloc(z_erofs_rsv_nrpages, - sizeof(*z_erofs_rsvbuf->pages), GFP_KERNEL); + z_erofs_rsvbuf->pages = kzalloc_objs(*z_erofs_rsvbuf->pages, + z_erofs_rsv_nrpages); if (!z_erofs_rsvbuf->pages) { z_erofs_rsvbuf = NULL; z_erofs_rsv_nrpages = 0; diff --git a/fs/eventfd.c b/fs/eventfd.c index 3219e0d596fe..9d33a02757d5 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c @@ -388,7 +388,7 @@ static int do_eventfd(unsigned int count, int flags) if (flags & ~EFD_FLAGS_SET) return -EINVAL; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 6c36d9dc6926..5714e900567c 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1147,7 +1147,7 @@ static int ep_alloc(struct eventpoll **pep) { struct eventpoll *ep; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (unlikely(!ep)) return -ENOMEM; @@ -2061,7 +2061,8 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, * @ep: the &struct eventpoll to be currently checked. * @depth: Current depth of the path being checked. * - * Return: depth of the subtree, or INT_MAX if we found a loop or went too deep. + * Return: depth of the subtree, or a value bigger than EP_MAX_NESTS if we found + * a loop or went too deep. */ static int ep_loop_check_proc(struct eventpoll *ep, int depth) { @@ -2080,7 +2081,7 @@ static int ep_loop_check_proc(struct eventpoll *ep, int depth) struct eventpoll *ep_tovisit; ep_tovisit = epi->ffd.file->private_data; if (ep_tovisit == inserting_into || depth > EP_MAX_NESTS) - result = INT_MAX; + result = EP_MAX_NESTS+1; else result = max(result, ep_loop_check_proc(ep_tovisit, depth + 1) + 1); if (result > EP_MAX_NESTS) diff --git a/fs/exec.c b/fs/exec.c index 2e3a6593c6fd..9ea3a775d51e 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1402,7 +1402,7 @@ static struct linux_binprm *alloc_bprm(int fd, struct filename *filename, int fl if (IS_ERR(file)) return ERR_CAST(file); - bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); + bprm = kzalloc_obj(*bprm); if (!bprm) { do_close_execat(file); return ERR_PTR(-ENOMEM); diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c index 5429041c7eaf..3a32f49f9dbd 100644 --- a/fs/exfat/balloc.c +++ b/fs/exfat/balloc.c @@ -96,8 +96,7 @@ static int exfat_allocate_bitmap(struct super_block *sb, } sbi->map_sectors = ((need_map_size - 1) >> (sb->s_blocksize_bits)) + 1; - sbi->vol_amap = kvmalloc_array(sbi->map_sectors, - sizeof(struct buffer_head *), GFP_KERNEL); + sbi->vol_amap = kvmalloc_objs(struct buffer_head *, sbi->map_sectors); if (!sbi->vol_amap) return -ENOMEM; diff --git a/fs/exfat/cache.c b/fs/exfat/cache.c index d5ce0ae660ba..7c8b4182f5de 100644 --- a/fs/exfat/cache.c +++ b/fs/exfat/cache.c @@ -80,41 +80,66 @@ static inline void exfat_cache_update_lru(struct inode *inode, list_move(&cache->cache_list, &ei->cache_lru); } -static unsigned int exfat_cache_lookup(struct inode *inode, - unsigned int fclus, struct exfat_cache_id *cid, +/* + * Find the cache that covers or precedes 'fclus' and return the last + * cluster before the next cache range. + */ +static inline unsigned int +exfat_cache_lookup(struct inode *inode, struct exfat_cache_id *cid, + unsigned int fclus, unsigned int end, unsigned int *cached_fclus, unsigned int *cached_dclus) { struct exfat_inode_info *ei = EXFAT_I(inode); static struct exfat_cache nohit = { .fcluster = 0, }; struct exfat_cache *hit = &nohit, *p; - unsigned int offset = EXFAT_EOF_CLUSTER; + unsigned int tail = 0; /* End boundary of hit cache */ + /* + * Search range [fclus, end]. Stop early if: + * 1. Cache covers entire range, or + * 2. Next cache starts at current cache tail + */ spin_lock(&ei->cache_lru_lock); list_for_each_entry(p, &ei->cache_lru, cache_list) { /* Find the cache of "fclus" or nearest cache. */ - if (p->fcluster <= fclus && hit->fcluster < p->fcluster) { + if (p->fcluster <= fclus) { + if (p->fcluster < hit->fcluster) + continue; + hit = p; - if (hit->fcluster + hit->nr_contig < fclus) { - offset = hit->nr_contig; - } else { - offset = fclus - hit->fcluster; + tail = hit->fcluster + hit->nr_contig; + + /* Current cache covers [fclus, end] completely */ + if (tail >= end) + break; + } else if (p->fcluster <= end) { + end = p->fcluster - 1; + + /* + * If we have a hit and next cache starts within/at + * its tail, caches are contiguous, stop searching. + */ + if (tail && tail >= end) break; - } } } if (hit != &nohit) { - exfat_cache_update_lru(inode, hit); + unsigned int offset; + exfat_cache_update_lru(inode, hit); cid->id = ei->cache_valid_id; cid->nr_contig = hit->nr_contig; cid->fcluster = hit->fcluster; cid->dcluster = hit->dcluster; + + offset = min(cid->nr_contig, fclus - cid->fcluster); *cached_fclus = cid->fcluster + offset; *cached_dclus = cid->dcluster + offset; } spin_unlock(&ei->cache_lru_lock); - return offset; + /* Return next cache start or 'end' if no more caches */ + return end; } static struct exfat_cache *exfat_cache_merge(struct inode *inode, @@ -234,15 +259,15 @@ static inline void cache_init(struct exfat_cache_id *cid, } int exfat_get_cluster(struct inode *inode, unsigned int cluster, - unsigned int *fclus, unsigned int *dclus, - unsigned int *last_dclus, int allow_eof) + unsigned int *dclus, unsigned int *count, + unsigned int *last_dclus) { struct super_block *sb = inode->i_sb; - struct exfat_sb_info *sbi = EXFAT_SB(sb); - unsigned int limit = sbi->num_clusters; struct exfat_inode_info *ei = EXFAT_I(inode); + struct buffer_head *bh = NULL; struct exfat_cache_id cid; - unsigned int content; + unsigned int content, fclus; + unsigned int end = cluster + *count - 1; if (ei->start_clu == EXFAT_FREE_CLUSTER) { exfat_fs_error(sb, @@ -251,64 +276,82 @@ int exfat_get_cluster(struct inode *inode, unsigned int cluster, return -EIO; } - *fclus = 0; + fclus = 0; *dclus = ei->start_clu; *last_dclus = *dclus; /* - * Don`t use exfat_cache if zero offset or non-cluster allocation + * This case should not exist, as exfat_map_cluster function doesn't + * call this routine when start_clu == EXFAT_EOF_CLUSTER. + * This case is retained here for routine completeness. */ - if (cluster == 0 || *dclus == EXFAT_EOF_CLUSTER) + if (*dclus == EXFAT_EOF_CLUSTER) { + *count = 0; return 0; - - cache_init(&cid, EXFAT_EOF_CLUSTER, EXFAT_EOF_CLUSTER); - - if (exfat_cache_lookup(inode, cluster, &cid, fclus, dclus) == - EXFAT_EOF_CLUSTER) { - /* - * dummy, always not contiguous - * This is reinitialized by cache_init(), later. - */ - WARN_ON(cid.id != EXFAT_CACHE_VALID || - cid.fcluster != EXFAT_EOF_CLUSTER || - cid.dcluster != EXFAT_EOF_CLUSTER || - cid.nr_contig != 0); } - if (*fclus == cluster) + /* If only the first cluster is needed, return now. */ + if (fclus == cluster && *count == 1) return 0; - while (*fclus < cluster) { - /* prevent the infinite loop of cluster chain */ - if (*fclus > limit) { - exfat_fs_error(sb, - "detected the cluster chain loop (i_pos %u)", - (*fclus)); - return -EIO; - } + cache_init(&cid, fclus, *dclus); + /* + * Update the 'end' to exclude the next cache range, as clusters in + * different cache are typically not contiguous. + */ + end = exfat_cache_lookup(inode, &cid, cluster, end, &fclus, dclus); - if (exfat_ent_get(sb, *dclus, &content)) + /* Return if the cache covers the entire range. */ + if (cid.fcluster + cid.nr_contig >= end) { + *count = end - cluster + 1; + return 0; + } + + /* Find the first cluster we need. */ + while (fclus < cluster) { + if (exfat_ent_get(sb, *dclus, &content, &bh)) return -EIO; *last_dclus = *dclus; *dclus = content; - (*fclus)++; - - if (content == EXFAT_EOF_CLUSTER) { - if (!allow_eof) { - exfat_fs_error(sb, - "invalid cluster chain (i_pos %u, last_clus 0x%08x is EOF)", - *fclus, (*last_dclus)); - return -EIO; - } + fclus++; + if (content == EXFAT_EOF_CLUSTER) break; - } if (!cache_contiguous(&cid, *dclus)) - cache_init(&cid, *fclus, *dclus); + cache_init(&cid, fclus, *dclus); } + /* + * Now the cid cache contains the first cluster requested, collect + * the remaining clusters of this contiguous extent. + */ + if (*dclus != EXFAT_EOF_CLUSTER) { + unsigned int clu = *dclus; + + while (fclus < end) { + if (exfat_ent_get(sb, clu, &content, &bh)) + return -EIO; + if (++clu != content) + break; + fclus++; + } + cid.nr_contig = fclus - cid.fcluster; + *count = fclus - cluster + 1; + + /* + * Cache this discontiguous cluster, we'll definitely need + * it later + */ + if (fclus < end && content != EXFAT_EOF_CLUSTER) { + exfat_cache_add(inode, &cid); + cache_init(&cid, fclus + 1, content); + } + } else { + *count = 0; + } + brelse(bh); exfat_cache_add(inode, &cid); return 0; } diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index 2dbf335eafef..3a4853693d8b 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -802,7 +802,7 @@ static int __exfat_get_dentry_set(struct exfat_entry_set_cache *es, num_bh = EXFAT_B_TO_BLK_ROUND_UP(off + num_entries * DENTRY_SIZE, sb); if (num_bh > ARRAY_SIZE(es->__bh)) { - es->bh = kmalloc_array(num_bh, sizeof(*es->bh), GFP_NOFS); + es->bh = kmalloc_objs(*es->bh, num_bh, GFP_NOFS); if (!es->bh) { brelse(bh); return -ENOMEM; diff --git a/fs/exfat/exfat_fs.h b/fs/exfat/exfat_fs.h index 176fef62574c..2dbed5f8ec26 100644 --- a/fs/exfat/exfat_fs.h +++ b/fs/exfat/exfat_fs.h @@ -432,13 +432,13 @@ int exfat_set_volume_dirty(struct super_block *sb); int exfat_clear_volume_dirty(struct super_block *sb); /* fatent.c */ -#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu) +#define exfat_get_next_cluster(sb, pclu) exfat_ent_get(sb, *(pclu), pclu, NULL) int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc, struct exfat_chain *p_chain, bool sync_bmap); int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain); int exfat_ent_get(struct super_block *sb, unsigned int loc, - unsigned int *content); + unsigned int *content, struct buffer_head **last); int exfat_ent_set(struct super_block *sb, unsigned int loc, unsigned int content); int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, @@ -486,8 +486,7 @@ int exfat_cache_init(void); void exfat_cache_shutdown(void); void exfat_cache_inval_inode(struct inode *inode); int exfat_get_cluster(struct inode *inode, unsigned int cluster, - unsigned int *fclus, unsigned int *dclus, - unsigned int *last_dclus, int allow_eof); + unsigned int *dclus, unsigned int *count, unsigned int *last_dclus); /* dir.c */ extern const struct inode_operations exfat_dir_inode_operations; diff --git a/fs/exfat/fatent.c b/fs/exfat/fatent.c index c9c5f2e3a05e..f87576ca7032 100644 --- a/fs/exfat/fatent.c +++ b/fs/exfat/fatent.c @@ -36,18 +36,23 @@ static int exfat_mirror_bh(struct super_block *sb, sector_t sec, } static int __exfat_ent_get(struct super_block *sb, unsigned int loc, - unsigned int *content) + unsigned int *content, struct buffer_head **last) { unsigned int off; sector_t sec; - struct buffer_head *bh; + struct buffer_head *bh = last ? *last : NULL; sec = FAT_ENT_OFFSET_SECTOR(sb, loc); off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); - bh = sb_bread(sb, sec); - if (!bh) - return -EIO; + if (!bh || bh->b_blocknr != sec || !buffer_uptodate(bh)) { + brelse(bh); + bh = sb_bread(sb, sec); + if (last) + *last = bh; + if (unlikely(!bh)) + return -EIO; + } *content = le32_to_cpu(*(__le32 *)(&bh->b_data[off])); @@ -55,7 +60,8 @@ static int __exfat_ent_get(struct super_block *sb, unsigned int loc, if (*content > EXFAT_BAD_CLUSTER) *content = EXFAT_EOF_CLUSTER; - brelse(bh); + if (!last) + brelse(bh); return 0; } @@ -82,49 +88,58 @@ int exfat_ent_set(struct super_block *sb, unsigned int loc, return 0; } +/* + * Caller must release the buffer_head if no error return. + */ int exfat_ent_get(struct super_block *sb, unsigned int loc, - unsigned int *content) + unsigned int *content, struct buffer_head **last) { struct exfat_sb_info *sbi = EXFAT_SB(sb); - int err; if (!is_valid_cluster(sbi, loc)) { exfat_fs_error_ratelimit(sb, "invalid access to FAT (entry 0x%08x)", loc); - return -EIO; + goto err; } - err = __exfat_ent_get(sb, loc, content); - if (err) { + if (unlikely(__exfat_ent_get(sb, loc, content, last))) { exfat_fs_error_ratelimit(sb, - "failed to access to FAT (entry 0x%08x, err:%d)", - loc, err); - return err; + "failed to access to FAT (entry 0x%08x)", + loc); + goto err; } - if (*content == EXFAT_FREE_CLUSTER) { + if (unlikely(*content == EXFAT_FREE_CLUSTER)) { exfat_fs_error_ratelimit(sb, "invalid access to FAT free cluster (entry 0x%08x)", loc); - return -EIO; + goto err; } - if (*content == EXFAT_BAD_CLUSTER) { + if (unlikely(*content == EXFAT_BAD_CLUSTER)) { exfat_fs_error_ratelimit(sb, "invalid access to FAT bad cluster (entry 0x%08x)", loc); - return -EIO; + goto err; } if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, *content)) { exfat_fs_error_ratelimit(sb, "invalid access to FAT (entry 0x%08x) bogus content (0x%08x)", loc, *content); - return -EIO; + goto err; } return 0; +err: + if (last) { + brelse(*last); + + /* Avoid double release */ + *last = NULL; + } + return -EIO; } int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, @@ -192,6 +207,7 @@ static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { int err; unsigned int last_cluster = p_chain->dir + p_chain->size - 1; + do { bool sync = false; @@ -281,6 +297,7 @@ int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain, unsigned int *ret_clu) { + struct buffer_head *bh = NULL; unsigned int clu, next; unsigned int count = 0; @@ -293,10 +310,11 @@ int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain, do { count++; clu = next; - if (exfat_ent_get(sb, clu, &next)) + if (exfat_ent_get(sb, clu, &next, &bh)) return -EIO; } while (next != EXFAT_EOF_CLUSTER && count <= p_chain->size); + brelse(bh); if (p_chain->size != count) { exfat_fs_error(sb, "bogus directory size (clus : ondisk(%d) != counted(%d))", @@ -469,6 +487,7 @@ int exfat_count_num_clusters(struct super_block *sb, unsigned int i, count; unsigned int clu; struct exfat_sb_info *sbi = EXFAT_SB(sb); + struct buffer_head *bh = NULL; if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) { *ret_count = 0; @@ -484,12 +503,13 @@ int exfat_count_num_clusters(struct super_block *sb, count = 0; for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) { count++; - if (exfat_ent_get(sb, clu, &clu)) + if (exfat_ent_get(sb, clu, &clu, &bh)) return -EIO; if (clu == EXFAT_EOF_CLUSTER) break; } + brelse(bh); *ret_count = count; /* diff --git a/fs/exfat/file.c b/fs/exfat/file.c index b60ee0e1bec9..90cd540afeaa 100644 --- a/fs/exfat/file.c +++ b/fs/exfat/file.c @@ -683,6 +683,7 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) if (iocb->ki_pos > pos) { ssize_t err = generic_write_sync(iocb, iocb->ki_pos - pos); + if (err < 0) return err; } @@ -708,21 +709,18 @@ static ssize_t exfat_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) static vm_fault_t exfat_page_mkwrite(struct vm_fault *vmf) { int err; - struct vm_area_struct *vma = vmf->vma; - struct file *file = vma->vm_file; - struct inode *inode = file_inode(file); + struct inode *inode = file_inode(vmf->vma->vm_file); struct exfat_inode_info *ei = EXFAT_I(inode); - loff_t start, end; + loff_t new_valid_size; if (!inode_trylock(inode)) return VM_FAULT_RETRY; - start = ((loff_t)vma->vm_pgoff << PAGE_SHIFT); - end = min_t(loff_t, i_size_read(inode), - start + vma->vm_end - vma->vm_start); + new_valid_size = ((loff_t)vmf->pgoff + 1) << PAGE_SHIFT; + new_valid_size = min(new_valid_size, i_size_read(inode)); - if (ei->valid_size < end) { - err = exfat_extend_valid_size(inode, end); + if (ei->valid_size < new_valid_size) { + err = exfat_extend_valid_size(inode, new_valid_size); if (err < 0) { inode_unlock(inode); return vmf_fs_error(err); diff --git a/fs/exfat/inode.c b/fs/exfat/inode.c index f9501c3a3666..2fb2d2d5d503 100644 --- a/fs/exfat/inode.c +++ b/fs/exfat/inode.c @@ -124,7 +124,7 @@ void exfat_sync_inode(struct inode *inode) * *clu = (~0), if it's unable to allocate a new cluster */ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, - unsigned int *clu, int create) + unsigned int *clu, unsigned int *count, int create) { int ret; unsigned int last_clu; @@ -147,39 +147,22 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, *clu = last_clu = ei->start_clu; - if (ei->flags == ALLOC_NO_FAT_CHAIN) { - if (clu_offset > 0 && *clu != EXFAT_EOF_CLUSTER) { - last_clu += clu_offset - 1; - - if (clu_offset == num_clusters) - *clu = EXFAT_EOF_CLUSTER; - else - *clu += clu_offset; + if (*clu == EXFAT_EOF_CLUSTER) { + *count = 0; + } else if (ei->flags == ALLOC_NO_FAT_CHAIN) { + last_clu += num_clusters - 1; + if (clu_offset < num_clusters) { + *clu += clu_offset; + *count = min(num_clusters - clu_offset, *count); + } else { + *clu = EXFAT_EOF_CLUSTER; + *count = 0; } - } else if (ei->type == TYPE_FILE) { - unsigned int fclus = 0; + } else { int err = exfat_get_cluster(inode, clu_offset, - &fclus, clu, &last_clu, 1); + clu, count, &last_clu); if (err) return -EIO; - - clu_offset -= fclus; - } else { - /* hint information */ - if (clu_offset > 0 && ei->hint_bmap.off != EXFAT_EOF_CLUSTER && - ei->hint_bmap.off > 0 && clu_offset >= ei->hint_bmap.off) { - clu_offset -= ei->hint_bmap.off; - /* hint_bmap.clu should be valid */ - WARN_ON(ei->hint_bmap.clu < 2); - *clu = ei->hint_bmap.clu; - } - - while (clu_offset > 0 && *clu != EXFAT_EOF_CLUSTER) { - last_clu = *clu; - if (exfat_get_next_cluster(sb, clu)) - return -EIO; - clu_offset--; - } } if (*clu == EXFAT_EOF_CLUSTER) { @@ -251,7 +234,7 @@ static int exfat_map_cluster(struct inode *inode, unsigned int clu_offset, num_to_be_allocated--; } } - + *count = 1; } /* hint information */ @@ -270,7 +253,7 @@ static int exfat_get_block(struct inode *inode, sector_t iblock, unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; int err = 0; unsigned long mapped_blocks = 0; - unsigned int cluster, sec_offset; + unsigned int cluster, sec_offset, count; sector_t last_block; sector_t phys = 0; sector_t valid_blks; @@ -283,8 +266,9 @@ static int exfat_get_block(struct inode *inode, sector_t iblock, goto done; /* Is this block already allocated? */ + count = EXFAT_B_TO_CLU_ROUND_UP(bh_result->b_size, sbi); err = exfat_map_cluster(inode, iblock >> sbi->sect_per_clus_bits, - &cluster, create); + &cluster, &count, create); if (err) { if (err != -ENOSPC) exfat_fs_error_ratelimit(sb, @@ -300,7 +284,7 @@ static int exfat_get_block(struct inode *inode, sector_t iblock, sec_offset = iblock & (sbi->sect_per_clus - 1); phys = exfat_cluster_to_sector(sbi, cluster) + sec_offset; - mapped_blocks = sbi->sect_per_clus - sec_offset; + mapped_blocks = ((unsigned long)count << sbi->sect_per_clus_bits) - sec_offset; max_blocks = min(mapped_blocks, max_blocks); map_bh(bh_result, sb, phys); @@ -511,8 +495,9 @@ static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter) exfat_write_failed(mapping, size); return ret; - } else - size = pos + ret; + } + + size = pos + ret; if (rw == WRITE) { /* diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c index dfe957493d49..670116ae9ec8 100644 --- a/fs/exfat/namei.c +++ b/fs/exfat/namei.c @@ -304,8 +304,8 @@ int exfat_find_empty_entry(struct inode *inode, struct exfat_chain *p_dir, int num_entries, struct exfat_entry_set_cache *es) { - int dentry; - unsigned int ret, last_clu; + int dentry, ret; + unsigned int last_clu; loff_t size = 0; struct exfat_chain clu; struct super_block *sb = inode->i_sb; diff --git a/fs/exfat/super.c b/fs/exfat/super.c index 10e872a99663..83396fd265cd 100644 --- a/fs/exfat/super.c +++ b/fs/exfat/super.c @@ -815,7 +815,7 @@ static int exfat_init_fs_context(struct fs_context *fc) { struct exfat_sb_info *sbi; - sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct exfat_sb_info); if (!sbi) return -ENOMEM; diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index d3e55de4a2a2..6c9be60a3e48 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c @@ -253,7 +253,8 @@ static bool filldir_one(struct dir_context *ctx, const char *name, int len, container_of(ctx, struct getdents_callback, ctx); buf->sequence++; - if (buf->ino == ino && len <= NAME_MAX && !is_dot_dotdot(name, len)) { + if (buf->ino == ino && len <= NAME_MAX && + !name_is_dot_dotdot(name, len)) { memcpy(buf->name, name, len); buf->name[len] = '\0'; buf->found = 1; diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index b8cfab8f98b9..007eee794bd1 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c @@ -419,7 +419,7 @@ void ext2_init_block_alloc_info(struct inode *inode) struct ext2_block_alloc_info *block_i; struct super_block *sb = inode->i_sb; - block_i = kmalloc(sizeof(*block_i), GFP_KERNEL); + block_i = kmalloc_obj(*block_i); if (block_i) { struct ext2_reserve_window_node *rsv = &block_i->rsv_window_node; diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 121e634c792a..603f2641fe10 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -893,12 +893,12 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc) __le32 features; int err; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; sbi->s_blockgroup_lock = - kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); + kzalloc_obj(struct blockgroup_lock); if (!sbi->s_blockgroup_lock) { kfree(sbi); return -ENOMEM; @@ -1122,9 +1122,7 @@ static int ext2_fill_super(struct super_block *sb, struct fs_context *fc) } db_count = (sbi->s_groups_count + EXT2_DESC_PER_BLOCK(sb) - 1) / EXT2_DESC_PER_BLOCK(sb); - sbi->s_group_desc = kvmalloc_array(db_count, - sizeof(struct buffer_head *), - GFP_KERNEL); + sbi->s_group_desc = kvmalloc_objs(struct buffer_head *, db_count); if (sbi->s_group_desc == NULL) { ret = -ENOMEM; ext2_msg(sb, KERN_ERR, "error: not enough memory"); @@ -1670,7 +1668,7 @@ static int ext2_init_fs_context(struct fs_context *fc) { struct ext2_fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index e8c5525afc67..3a31e3d718c9 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -217,7 +217,7 @@ int ext4_setup_system_zone(struct super_block *sb) ext4_group_t i; int ret; - system_blks = kzalloc(sizeof(*system_blks), GFP_KERNEL); + system_blks = kzalloc_obj(*system_blks); if (!system_blks) return -ENOMEM; diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index 00c4b3c82b65..28b2a3deb954 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -480,8 +480,7 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, p = &info->root.rb_node; /* Create and allocate the fname structure */ - new_fn = kzalloc(struct_size(new_fn, name, ent_name->len + 1), - GFP_KERNEL); + new_fn = kzalloc_flex(*new_fn, name, ent_name->len + 1); if (!new_fn) return -ENOMEM; new_fn->hash = hash; @@ -673,7 +672,7 @@ static int ext4_dir_open(struct inode *inode, struct file *file) { struct dir_private_info *info; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; file->private_data = info; diff --git a/fs/ext4/extents-test.c b/fs/ext4/extents-test.c index 4879e68e465d..7c4690eb7dad 100644 --- a/fs/ext4/extents-test.c +++ b/fs/ext4/extents-test.c @@ -229,7 +229,7 @@ static int extents_kunit_init(struct kunit *test) sb->s_blocksize = 4096; sb->s_blocksize_bits = 12; - sbi = kzalloc(sizeof(struct ext4_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct ext4_sb_info); if (sbi == NULL) return -ENOMEM; @@ -240,7 +240,7 @@ static int extents_kunit_init(struct kunit *test) sbi->s_extent_max_zeroout_kb = 32; /* setup the mock inode */ - k_ctx.k_ei = kzalloc(sizeof(struct ext4_inode_info), GFP_KERNEL); + k_ctx.k_ei = kzalloc_obj(struct ext4_inode_info); if (k_ctx.k_ei == NULL) return -ENOMEM; ei = k_ctx.k_ei; diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 3630b27e4fd7..ae3804f36535 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -621,8 +621,7 @@ int ext4_ext_precache(struct inode *inode) return ret; } - path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), - GFP_NOFS); + path = kzalloc_objs(struct ext4_ext_path, depth + 1, GFP_NOFS); if (path == NULL) { up_read(&ei->i_data_sem); return -ENOMEM; @@ -916,8 +915,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block, } if (!path) { /* account possible depth increase */ - path = kcalloc(depth + 2, sizeof(struct ext4_ext_path), - gfp_flags); + path = kzalloc_objs(struct ext4_ext_path, depth + 2, gfp_flags); if (unlikely(!path)) return ERR_PTR(-ENOMEM); path[0].p_maxdepth = depth + 1; @@ -1105,7 +1103,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode, * We need this to handle errors and free blocks * upon them. */ - ablocks = kcalloc(depth, sizeof(ext4_fsblk_t), gfp_flags); + ablocks = kzalloc_objs(ext4_fsblk_t, depth, gfp_flags); if (!ablocks) return -ENOMEM; @@ -2947,8 +2945,8 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start, path[k].p_block = le16_to_cpu(path[k].p_hdr->eh_entries)+1; } else { - path = kcalloc(depth + 1, sizeof(struct ext4_ext_path), - GFP_NOFS | __GFP_NOFAIL); + path = kzalloc_objs(struct ext4_ext_path, depth + 1, + GFP_NOFS | __GFP_NOFAIL); path[0].p_maxdepth = path[0].p_depth = depth; path[0].p_hdr = ext_inode_hdr(inode); i = 0; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 4320ebff74f3..f1dc5ce791a7 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -818,13 +818,13 @@ static int ext4_file_mmap_prepare(struct vm_area_desc *desc) * We don't support synchronous mappings for non-DAX files and * for DAX files if underneath dax_device is not synchronous. */ - if (!daxdev_mapping_supported(desc->vm_flags, file_inode(file), dax_dev)) + if (!daxdev_mapping_supported(desc, file_inode(file), dax_dev)) return -EOPNOTSUPP; file_accessed(file); if (IS_DAX(file_inode(file))) { desc->vm_ops = &ext4_dax_vm_ops; - desc->vm_flags |= VM_HUGEPAGE; + vma_desc_set_flags(desc, VMA_HUGEPAGE_BIT); } else { desc->vm_ops = &ext4_file_vm_ops; } diff --git a/fs/ext4/fsmap.c b/fs/ext4/fsmap.c index 22fc333244ef..8b1138d2dc8e 100644 --- a/fs/ext4/fsmap.c +++ b/fs/ext4/fsmap.c @@ -348,7 +348,7 @@ static inline int ext4_getfsmap_fill(struct list_head *meta_list, { struct ext4_fsmap *fsm; - fsm = kmalloc(sizeof(*fsm), GFP_NOFS); + fsm = kmalloc_obj(*fsm, GFP_NOFS); if (!fsm) return -ENOMEM; fsm->fmr_device = 0; diff --git a/fs/ext4/mballoc-test.c b/fs/ext4/mballoc-test.c index 4abb40d4561c..9fbdf6a09489 100644 --- a/fs/ext4/mballoc-test.c +++ b/fs/ext4/mballoc-test.c @@ -34,7 +34,7 @@ static struct inode *mbt_alloc_inode(struct super_block *sb) { struct ext4_inode_info *ei; - ei = kmalloc(sizeof(struct ext4_inode_info), GFP_KERNEL); + ei = kmalloc_obj(struct ext4_inode_info); if (!ei) return NULL; @@ -73,11 +73,11 @@ static int mbt_mb_init(struct super_block *sb) int ret; /* needed by ext4_mb_init->bdev_nonrot(sb->s_bdev) */ - sb->s_bdev = kzalloc(sizeof(*sb->s_bdev), GFP_KERNEL); + sb->s_bdev = kzalloc_obj(*sb->s_bdev); if (sb->s_bdev == NULL) return -ENOMEM; - sb->s_bdev->bd_queue = kzalloc(sizeof(struct request_queue), GFP_KERNEL); + sb->s_bdev->bd_queue = kzalloc_obj(struct request_queue); if (sb->s_bdev->bd_queue == NULL) { kfree(sb->s_bdev); return -ENOMEM; @@ -137,7 +137,7 @@ static struct super_block *mbt_ext4_alloc_super_block(void) struct super_block *sb; struct ext4_sb_info *sbi; - fsb = kzalloc(sizeof(*fsb), GFP_KERNEL); + fsb = kzalloc_obj(*fsb); if (fsb == NULL) return NULL; @@ -148,7 +148,7 @@ static struct super_block *mbt_ext4_alloc_super_block(void) sbi = &fsb->sbi; sbi->s_blockgroup_lock = - kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); + kzalloc_obj(struct blockgroup_lock); if (!sbi->s_blockgroup_lock) goto out_deactivate; @@ -252,8 +252,7 @@ static int mbt_ctx_init(struct super_block *sb) struct mbt_ctx *ctx = MBT_CTX(sb); ext4_group_t i, ngroups = ext4_get_groups_count(sb); - ctx->grp_ctx = kcalloc(ngroups, sizeof(struct mbt_grp_ctx), - GFP_KERNEL); + ctx->grp_ctx = kzalloc_objs(struct mbt_grp_ctx, ngroups); if (ctx->grp_ctx == NULL) return -ENOMEM; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index b99d1a7e580e..20e9fdaf4301 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3754,8 +3754,7 @@ int ext4_mb_init(struct super_block *sb) } while (i < MB_NUM_ORDERS(sb)); sbi->s_mb_avg_fragment_size = - kmalloc_array(MB_NUM_ORDERS(sb), sizeof(struct xarray), - GFP_KERNEL); + kmalloc_objs(struct xarray, MB_NUM_ORDERS(sb)); if (!sbi->s_mb_avg_fragment_size) { ret = -ENOMEM; goto out; @@ -3764,8 +3763,7 @@ int ext4_mb_init(struct super_block *sb) xa_init(&sbi->s_mb_avg_fragment_size[i]); sbi->s_mb_largest_free_orders = - kmalloc_array(MB_NUM_ORDERS(sb), sizeof(struct xarray), - GFP_KERNEL); + kmalloc_objs(struct xarray, MB_NUM_ORDERS(sb)); if (!sbi->s_mb_largest_free_orders) { ret = -ENOMEM; goto out; @@ -3817,8 +3815,8 @@ int ext4_mb_init(struct super_block *sb) sbi->s_mb_nr_global_goals = umin(num_possible_cpus(), DIV_ROUND_UP(sbi->s_groups_count, 4)); - sbi->s_mb_last_groups = kcalloc(sbi->s_mb_nr_global_goals, - sizeof(ext4_group_t), GFP_KERNEL); + sbi->s_mb_last_groups = kzalloc_objs(ext4_group_t, + sbi->s_mb_nr_global_goals); if (sbi->s_mb_last_groups == NULL) { ret = -ENOMEM; goto out; diff --git a/fs/ext4/orphan.c b/fs/ext4/orphan.c index c9b93b670b0f..c0022f0bff87 100644 --- a/fs/ext4/orphan.c +++ b/fs/ext4/orphan.c @@ -598,9 +598,7 @@ int ext4_init_orphan_info(struct super_block *sb) } oi->of_blocks = inode->i_size >> sb->s_blocksize_bits; oi->of_csum_seed = EXT4_I(inode)->i_csum_seed; - oi->of_binfo = kvmalloc_array(oi->of_blocks, - sizeof(struct ext4_orphan_block), - GFP_KERNEL); + oi->of_binfo = kvmalloc_objs(struct ext4_orphan_block, oi->of_blocks); if (!oi->of_binfo) { ret = -ENOMEM; goto out_put; diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index 76842f0957b5..2c5b851c552a 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -32,7 +32,7 @@ static void ext4_rcu_ptr_callback(struct rcu_head *head) void ext4_kvfree_array_rcu(void *to_free) { - struct ext4_rcu_ptr *ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + struct ext4_rcu_ptr *ptr = kzalloc_obj(*ptr); if (ptr) { ptr->ptr = to_free; @@ -242,7 +242,7 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size, unsigned int max_resize_bg; struct ext4_new_flex_group_data *flex_gd; - flex_gd = kmalloc(sizeof(*flex_gd), GFP_NOFS); + flex_gd = kmalloc_obj(*flex_gd, GFP_NOFS); if (flex_gd == NULL) goto out3; @@ -260,9 +260,8 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned int flexbg_size, if (WARN_ON_ONCE(flex_gd->resize_bg > max_resize_bg)) flex_gd->resize_bg = max_resize_bg; - flex_gd->groups = kmalloc_array(flex_gd->resize_bg, - sizeof(struct ext4_new_group_data), - GFP_NOFS); + flex_gd->groups = kmalloc_objs(struct ext4_new_group_data, + flex_gd->resize_bg, GFP_NOFS); if (flex_gd->groups == NULL) goto out2; @@ -1031,7 +1030,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, int res, i; int err; - primary = kmalloc_array(reserved_gdb, sizeof(*primary), GFP_NOFS); + primary = kmalloc_objs(*primary, reserved_gdb, GFP_NOFS); if (!primary) return -ENOMEM; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 504148b2142b..43f680c750ae 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -2016,7 +2016,7 @@ int ext4_init_fs_context(struct fs_context *fc) { struct ext4_fs_context *ctx; - ctx = kzalloc(sizeof(struct ext4_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct ext4_fs_context); if (!ctx) return -ENOMEM; @@ -2496,11 +2496,11 @@ static int parse_apply_sb_mount_options(struct super_block *sb, if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts) < 0) return -E2BIG; - fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL); + fc = kzalloc_obj(struct fs_context); if (!fc) return -ENOMEM; - s_ctx = kzalloc(sizeof(struct ext4_fs_context), GFP_KERNEL); + s_ctx = kzalloc_obj(struct ext4_fs_context); if (!s_ctx) goto out_free; @@ -3962,7 +3962,7 @@ static int ext4_li_info_new(void) { struct ext4_lazy_init *eli = NULL; - eli = kzalloc(sizeof(*eli), GFP_KERNEL); + eli = kzalloc_obj(*eli); if (!eli) return -ENOMEM; @@ -3981,7 +3981,7 @@ static struct ext4_li_request *ext4_li_request_new(struct super_block *sb, { struct ext4_li_request *elr; - elr = kzalloc(sizeof(*elr), GFP_KERNEL); + elr = kzalloc_obj(*elr); if (!elr) return NULL; @@ -4328,7 +4328,7 @@ static struct ext4_sb_info *ext4_alloc_sbi(struct super_block *sb) { struct ext4_sb_info *sbi; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return NULL; @@ -4336,7 +4336,7 @@ static struct ext4_sb_info *ext4_alloc_sbi(struct super_block *sb) NULL, NULL); sbi->s_blockgroup_lock = - kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL); + kzalloc_obj(struct blockgroup_lock); if (!sbi->s_blockgroup_lock) goto err_out; @@ -4879,9 +4879,7 @@ static int ext4_group_desc_init(struct super_block *sb, } } rcu_assign_pointer(sbi->s_group_desc, - kvmalloc_array(db_count, - sizeof(struct buffer_head *), - GFP_KERNEL)); + kvmalloc_objs(struct buffer_head *, db_count)); if (sbi->s_group_desc == NULL) { ext4_msg(sb, KERN_ERR, "not enough memory"); return -ENOMEM; diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index d2ecc1026c0c..b87d7bdab06a 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -655,7 +655,7 @@ int __init ext4_init_sysfs(void) if (!ext4_root) return -ENOMEM; - ext4_feat = kzalloc(sizeof(*ext4_feat), GFP_KERNEL); + ext4_feat = kzalloc_obj(*ext4_feat); if (!ext4_feat) { ret = -ENOMEM; goto root_err; diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 4ed8ddf2a60b..7bf9ba19a89d 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -390,7 +390,7 @@ static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size) int i, ret; if (bh_count > ARRAY_SIZE(bhs_inline)) { - bhs = kmalloc_array(bh_count, sizeof(*bhs), GFP_NOFS); + bhs = kmalloc_objs(*bhs, bh_count, GFP_NOFS); if (!bhs) return -ENOMEM; } @@ -2618,8 +2618,8 @@ static int ext4_xattr_move_to_block(handle_t *handle, struct inode *inode, int needs_kvfree = 0; int error; - is = kzalloc(sizeof(struct ext4_xattr_ibody_find), GFP_NOFS); - bs = kzalloc(sizeof(struct ext4_xattr_block_find), GFP_NOFS); + is = kzalloc_obj(struct ext4_xattr_ibody_find, GFP_NOFS); + bs = kzalloc_obj(struct ext4_xattr_block_find, GFP_NOFS); b_entry_name = kmalloc(entry->e_name_len + 1, GFP_NOFS); if (!is || !bs || !b_entry_name) { error = -ENOMEM; @@ -2876,9 +2876,8 @@ ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array, /* * Start with 15 inodes, so it fits into a power-of-two size. */ - (*ea_inode_array) = kmalloc( - struct_size(*ea_inode_array, inodes, EIA_MASK), - GFP_NOFS); + (*ea_inode_array) = kmalloc_flex(**ea_inode_array, inodes, + EIA_MASK, GFP_NOFS); if (*ea_inode_array == NULL) return -ENOMEM; (*ea_inode_array)->count = 0; @@ -2886,10 +2885,9 @@ ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array, /* expand the array once all 15 + n * 16 slots are full */ struct ext4_xattr_inode_array *new_array = NULL; - new_array = kmalloc( - struct_size(*ea_inode_array, inodes, - (*ea_inode_array)->count + EIA_INCR), - GFP_NOFS); + new_array = kmalloc_flex(**ea_inode_array, inodes, + (*ea_inode_array)->count + EIA_INCR, + GFP_NOFS); if (new_array == NULL) return -ENOMEM; memcpy(new_array, *ea_inode_array, diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 300664269eb6..6dd39b7de11a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include "f2fs.h" #include "node.h" @@ -21,6 +24,209 @@ #include "iostat.h" #include +static inline void get_lock_elapsed_time(struct f2fs_time_stat *ts) +{ + ts->total_time = ktime_get(); +#ifdef CONFIG_64BIT + ts->running_time = current->se.sum_exec_runtime; +#endif +#if defined(CONFIG_SCHED_INFO) && defined(CONFIG_SCHEDSTATS) + ts->runnable_time = current->sched_info.run_delay; +#endif +#ifdef CONFIG_TASK_DELAY_ACCT + if (current->delays) + ts->io_sleep_time = current->delays->blkio_delay; +#endif +} + +static inline void trace_lock_elapsed_time_start(struct f2fs_rwsem *sem, + struct f2fs_lock_context *lc) +{ + lc->lock_trace = trace_f2fs_lock_elapsed_time_enabled(); + if (!lc->lock_trace) + return; + + get_lock_elapsed_time(&lc->ts); +} + +static inline void trace_lock_elapsed_time_end(struct f2fs_rwsem *sem, + struct f2fs_lock_context *lc, bool is_write) +{ + struct f2fs_time_stat tts; + unsigned long long total_time; + unsigned long long running_time = 0; + unsigned long long runnable_time = 0; + unsigned long long io_sleep_time = 0; + unsigned long long other_time = 0; + unsigned npm = NSEC_PER_MSEC; + + if (!lc->lock_trace) + return; + + if (time_to_inject(sem->sbi, FAULT_LOCK_TIMEOUT)) + f2fs_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT, true); + + get_lock_elapsed_time(&tts); + + total_time = div_u64(tts.total_time - lc->ts.total_time, npm); + if (total_time <= sem->sbi->max_lock_elapsed_time) + return; + +#ifdef CONFIG_64BIT + running_time = div_u64(tts.running_time - lc->ts.running_time, npm); +#endif +#if defined(CONFIG_SCHED_INFO) && defined(CONFIG_SCHEDSTATS) + runnable_time = div_u64(tts.runnable_time - lc->ts.runnable_time, npm); +#endif +#ifdef CONFIG_TASK_DELAY_ACCT + io_sleep_time = div_u64(tts.io_sleep_time - lc->ts.io_sleep_time, npm); +#endif + if (total_time > running_time + io_sleep_time + runnable_time) + other_time = total_time - running_time - + io_sleep_time - runnable_time; + + trace_f2fs_lock_elapsed_time(sem->sbi, sem->name, is_write, current, + get_current_ioprio(), total_time, running_time, + runnable_time, io_sleep_time, other_time); +} + +static bool need_uplift_priority(struct f2fs_rwsem *sem, bool is_write) +{ + if (!(sem->sbi->adjust_lock_priority & BIT(sem->name - 1))) + return false; + + switch (sem->name) { + /* + * writer is checkpoint which has high priority, let's just uplift + * priority for reader + */ + case LOCK_NAME_CP_RWSEM: + case LOCK_NAME_NODE_CHANGE: + case LOCK_NAME_NODE_WRITE: + return !is_write; + case LOCK_NAME_GC_LOCK: + case LOCK_NAME_CP_GLOBAL: + case LOCK_NAME_IO_RWSEM: + return true; + default: + f2fs_bug_on(sem->sbi, 1); + } + return false; +} + +static void uplift_priority(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc, + bool is_write) +{ + lc->need_restore = false; + if (!sem->sbi->adjust_lock_priority) + return; + if (rt_task(current)) + return; + if (!need_uplift_priority(sem, is_write)) + return; + lc->orig_nice = task_nice(current); + lc->new_nice = PRIO_TO_NICE(sem->sbi->lock_duration_priority); + if (lc->orig_nice <= lc->new_nice) + return; + set_user_nice(current, lc->new_nice); + lc->need_restore = true; + + trace_f2fs_priority_uplift(sem->sbi, sem->name, is_write, current, + NICE_TO_PRIO(lc->orig_nice), NICE_TO_PRIO(lc->new_nice)); +} + +static void restore_priority(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc, + bool is_write) +{ + if (!lc->need_restore) + return; + /* someone has updated the priority */ + if (task_nice(current) != lc->new_nice) + return; + set_user_nice(current, lc->orig_nice); + + trace_f2fs_priority_restore(sem->sbi, sem->name, is_write, current, + NICE_TO_PRIO(lc->orig_nice), NICE_TO_PRIO(lc->new_nice)); +} + +void f2fs_down_read_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + uplift_priority(sem, lc, false); + f2fs_down_read(sem); + trace_lock_elapsed_time_start(sem, lc); +} + +int f2fs_down_read_trylock_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + uplift_priority(sem, lc, false); + if (!f2fs_down_read_trylock(sem)) { + restore_priority(sem, lc, false); + return 0; + } + trace_lock_elapsed_time_start(sem, lc); + return 1; +} + +void f2fs_up_read_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + f2fs_up_read(sem); + restore_priority(sem, lc, false); + trace_lock_elapsed_time_end(sem, lc, false); +} + +void f2fs_down_write_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + uplift_priority(sem, lc, true); + f2fs_down_write(sem); + trace_lock_elapsed_time_start(sem, lc); +} + +int f2fs_down_write_trylock_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + uplift_priority(sem, lc, true); + if (!f2fs_down_write_trylock(sem)) { + restore_priority(sem, lc, true); + return 0; + } + trace_lock_elapsed_time_start(sem, lc); + return 1; +} + +void f2fs_up_write_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc) +{ + f2fs_up_write(sem); + restore_priority(sem, lc, true); + trace_lock_elapsed_time_end(sem, lc, true); +} + +void f2fs_lock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc) +{ + f2fs_down_read_trace(&sbi->cp_rwsem, lc); +} + +int f2fs_trylock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc) +{ + if (time_to_inject(sbi, FAULT_LOCK_OP)) + return 0; + + return f2fs_down_read_trylock_trace(&sbi->cp_rwsem, lc); +} + +void f2fs_unlock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc) +{ + f2fs_up_read_trace(&sbi->cp_rwsem, lc); +} + +static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) +{ + f2fs_down_write(&sbi->cp_rwsem); +} + +static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) +{ + f2fs_up_write(&sbi->cp_rwsem); +} + #define DEFAULT_CHECKPOINT_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 3)) static struct kmem_cache *ino_entry_slab; @@ -379,6 +585,7 @@ static int f2fs_write_meta_pages(struct address_space *mapping, struct writeback_control *wbc) { struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + struct f2fs_lock_context lc; long diff, written; if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) @@ -391,13 +598,13 @@ static int f2fs_write_meta_pages(struct address_space *mapping, goto skip_write; /* if locked failed, cp will flush dirty pages instead */ - if (!f2fs_down_write_trylock(&sbi->cp_global_sem)) + if (!f2fs_down_write_trylock_trace(&sbi->cp_global_sem, &lc)) goto skip_write; trace_f2fs_writepages(mapping->host, wbc, META); diff = nr_pages_to_write(sbi, META, wbc); - written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO); - f2fs_up_write(&sbi->cp_global_sem); + written = f2fs_sync_meta_pages(sbi, wbc->nr_to_write, FS_META_IO); + f2fs_up_write_trace(&sbi->cp_global_sem, &lc); wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); return 0; @@ -407,8 +614,8 @@ static int f2fs_write_meta_pages(struct address_space *mapping, return 0; } -long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, - long nr_to_write, enum iostat_type io_type) +long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write, + enum iostat_type io_type) { struct address_space *mapping = META_MAPPING(sbi); pgoff_t index = 0, prev = ULONG_MAX; @@ -469,7 +676,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, } stop: if (nwritten) - f2fs_submit_merged_write(sbi, type); + f2fs_submit_merged_write(sbi, META); blk_finish_plug(&plug); @@ -1312,8 +1519,7 @@ void f2fs_wait_on_all_pages(struct f2fs_sb_info *sbi, int type) break; if (type == F2FS_DIRTY_META) - f2fs_sync_meta_pages(sbi, META, LONG_MAX, - FS_CP_META_IO); + f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); else if (type == F2FS_WB_CP_DATA) f2fs_submit_merged_write(sbi, DATA); @@ -1485,7 +1691,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) int err; /* Flush all the NAT/SIT pages */ - f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); + f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); stat_cp_time(cpc, CP_TIME_SYNC_META); @@ -1584,7 +1790,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) } /* Here, we have one bio having CP pack except cp pack 2 page */ - f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_CP_META_IO); + f2fs_sync_meta_pages(sbi, LONG_MAX, FS_CP_META_IO); stat_cp_time(cpc, CP_TIME_SYNC_CP_META); /* Wait for all dirty meta pages to be submitted for IO */ @@ -1646,6 +1852,7 @@ static int do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); + struct f2fs_lock_context lc; unsigned long long ckpt_ver; int err = 0; @@ -1660,7 +1867,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_warn(sbi, "Start checkpoint disabled!"); } if (cpc->reason != CP_RESIZE) - f2fs_down_write(&sbi->cp_global_sem); + f2fs_down_write_trace(&sbi->cp_global_sem, &lc); stat_cp_time(cpc, CP_TIME_LOCK); @@ -1701,6 +1908,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) goto out; } } + stat_cp_time(cpc, CP_TIME_MERGE_WRITE); /* * update checkpoint pack index @@ -1717,10 +1925,11 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_bug_on(sbi, !f2fs_cp_error(sbi)); goto stop; } + stat_cp_time(cpc, CP_TIME_FLUSH_NAT); f2fs_flush_sit_entries(sbi, cpc); - stat_cp_time(cpc, CP_TIME_FLUSH_META); + stat_cp_time(cpc, CP_TIME_FLUSH_SIT); /* save inmem log status */ f2fs_save_inmem_curseg(sbi); @@ -1750,7 +1959,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, CP_PHASE_FINISH_CHECKPOINT); out: if (cpc->reason != CP_RESIZE) - f2fs_up_write(&sbi->cp_global_sem); + f2fs_up_write_trace(&sbi->cp_global_sem, &lc); return err; } @@ -1796,11 +2005,12 @@ void f2fs_destroy_checkpoint_caches(void) static int __write_checkpoint_sync(struct f2fs_sb_info *sbi) { struct cp_control cpc = { .reason = CP_SYNC, }; + struct f2fs_lock_context lc; int err; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); err = f2fs_write_checkpoint(sbi, &cpc); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); return err; } @@ -1888,11 +2098,12 @@ int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi) cpc.reason = __get_cp_reason(sbi); if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC || sbi->umount_lock_holder == current) { + struct f2fs_lock_context lc; int ret; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); ret = f2fs_write_checkpoint(sbi, &cpc); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); return ret; } @@ -1947,6 +2158,8 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi) } set_task_ioprio(cprc->f2fs_issue_ckpt, cprc->ckpt_thread_ioprio); + set_user_nice(cprc->f2fs_issue_ckpt, + PRIO_TO_NICE(sbi->critical_task_priority)); return 0; } diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index ef1225af2acf..8c76400ba631 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1291,6 +1291,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, struct dnode_of_data dn; struct node_info ni; struct compress_io_ctx *cic; + struct f2fs_lock_context lc; pgoff_t start_idx = start_idx_of_cluster(cc); unsigned int last_index = cc->cluster_size - 1; loff_t psize; @@ -1309,8 +1310,8 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, * checkpoint. This can only happen to quota writes which can cause * the below discard race condition. */ - f2fs_down_read(&sbi->node_write); - } else if (!f2fs_trylock_op(sbi)) { + f2fs_down_read_trace(&sbi->node_write, &lc); + } else if (!f2fs_trylock_op(sbi, &lc)) { goto out_free; } @@ -1434,9 +1435,9 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, f2fs_put_dnode(&dn); if (quota_inode) - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); else - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); spin_lock(&fi->i_size_lock); if (fi->last_disk_size < psize) @@ -1463,9 +1464,9 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, f2fs_put_dnode(&dn); out_unlock_op: if (quota_inode) - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); else - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); out_free: for (i = 0; i < cc->valid_nr_cpages; i++) { f2fs_compress_free_page(cc->cpages[i]); @@ -1512,6 +1513,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, { struct address_space *mapping = cc->inode->i_mapping; struct f2fs_sb_info *sbi = F2FS_M_SB(mapping); + struct f2fs_lock_context lc; int submitted, compr_blocks, i; int ret = 0; @@ -1530,7 +1532,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, /* overwrite compressed cluster w/ normal cluster */ if (compr_blocks > 0) - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); for (i = 0; i < cc->cluster_size; i++) { struct folio *folio; @@ -1586,7 +1588,7 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, out: if (compr_blocks > 0) - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_balance_fs(sbi, true); return ret; @@ -1811,15 +1813,14 @@ static void f2fs_verify_cluster(struct work_struct *work) /* Verify, update, and unlock the decompressed pages. */ for (i = 0; i < dic->cluster_size; i++) { struct page *rpage = dic->rpages[i]; + struct folio *rfolio; if (!rpage) continue; - - if (fsverity_verify_page(dic->vi, rpage)) - SetPageUptodate(rpage); - else - ClearPageUptodate(rpage); - unlock_page(rpage); + rfolio = page_folio(rpage); + if (fsverity_verify_folio(dic->vi, rfolio)) + folio_mark_uptodate(rfolio); + folio_unlock(rfolio); } f2fs_put_dic(dic, true); diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 491f66511201..338df7a2aea6 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -31,9 +31,15 @@ static struct kmem_cache *bio_post_read_ctx_cache; static struct kmem_cache *bio_entry_slab; +static struct kmem_cache *ffs_entry_slab; static mempool_t *bio_post_read_ctx_pool; static struct bio_set f2fs_bioset; +struct f2fs_folio_state { + spinlock_t state_lock; + unsigned int read_pages_pending; +}; + #define F2FS_BIO_POOL_SIZE NR_CURSEG_TYPE int __init f2fs_init_bioset(void) @@ -139,11 +145,15 @@ static void f2fs_finish_read_bio(struct bio *bio, bool in_task) { struct folio_iter fi; struct bio_post_read_ctx *ctx = bio->bi_private; + unsigned long flags; bio_for_each_folio_all(fi, bio) { struct folio *folio = fi.folio; + unsigned nr_pages = fi.length >> PAGE_SHIFT; + bool finished = true; - if (f2fs_is_compressed_page(folio)) { + if (!folio_test_large(folio) && + f2fs_is_compressed_page(folio)) { if (ctx && !ctx->decompression_attempted) f2fs_end_read_compressed_page(folio, true, 0, in_task); @@ -151,8 +161,25 @@ static void f2fs_finish_read_bio(struct bio *bio, bool in_task) continue; } - dec_page_count(F2FS_F_SB(folio), __read_io_type(folio)); - folio_end_read(folio, bio->bi_status == BLK_STS_OK); + if (folio_test_large(folio)) { + struct f2fs_folio_state *ffs = folio->private; + + spin_lock_irqsave(&ffs->state_lock, flags); + ffs->read_pages_pending -= nr_pages; + finished = !ffs->read_pages_pending; + spin_unlock_irqrestore(&ffs->state_lock, flags); + } + + while (nr_pages--) + dec_page_count(F2FS_F_SB(folio), __read_io_type(folio)); + + if (F2FS_F_SB(folio)->node_inode && is_node_folio(folio) && + f2fs_sanity_check_node_footer(F2FS_F_SB(folio), + folio, folio->index, NODE_TYPE_REGULAR, true)) + bio->bi_status = BLK_STS_IOERR; + + if (finished) + folio_end_read(folio, bio->bi_status == BLK_STS_OK); } if (ctx) @@ -189,7 +216,7 @@ static void f2fs_verify_bio(struct work_struct *work) struct folio *folio = fi.folio; if (!f2fs_is_compressed_page(folio) && - !fsverity_verify_page(vi, &folio->page)) { + !fsverity_verify_folio(vi, folio)) { bio->bi_status = BLK_STS_IOERR; break; } @@ -354,18 +381,27 @@ static void f2fs_write_end_io(struct bio *bio) STOP_CP_REASON_WRITE_FAIL); } - f2fs_bug_on(sbi, is_node_folio(folio) && - folio->index != nid_of_node(folio)); + if (is_node_folio(folio)) { + f2fs_sanity_check_node_footer(sbi, folio, + folio->index, NODE_TYPE_REGULAR, true); + f2fs_bug_on(sbi, folio->index != nid_of_node(folio)); + } dec_page_count(sbi, type); + + /* + * we should access sbi before folio_end_writeback() to + * avoid racing w/ kill_f2fs_super() + */ + if (type == F2FS_WB_CP_DATA && !get_pages(sbi, type) && + wq_has_sleeper(&sbi->cp_wait)) + wake_up(&sbi->cp_wait); + if (f2fs_in_warm_node_list(sbi, folio)) f2fs_del_fsync_node_entry(sbi, folio); folio_clear_f2fs_gcing(folio); folio_end_writeback(folio); } - if (!get_pages(sbi, F2FS_WB_CP_DATA) && - wq_has_sleeper(&sbi->cp_wait)) - wake_up(&sbi->cp_wait); bio_put(bio); } @@ -511,6 +547,9 @@ static bool f2fs_crypt_mergeable_bio(struct bio *bio, const struct inode *inode, void f2fs_submit_read_bio(struct f2fs_sb_info *sbi, struct bio *bio, enum page_type type) { + if (!bio) + return; + WARN_ON_ONCE(!is_read_io(bio_op(bio))); trace_f2fs_submit_read_bio(sbi->sb, type, bio); @@ -597,7 +636,8 @@ int f2fs_init_write_merge_io(struct f2fs_sb_info *sbi) for (j = HOT; j < n; j++) { struct f2fs_bio_info *io = &sbi->write_io[i][j]; - init_f2fs_rwsem(&io->io_rwsem); + init_f2fs_rwsem_trace(&io->io_rwsem, sbi, + LOCK_NAME_IO_RWSEM); io->sbi = sbi; io->bio = NULL; io->last_block_in_bio = 0; @@ -621,8 +661,9 @@ static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi, { enum page_type btype = PAGE_TYPE_OF_BIO(type); struct f2fs_bio_info *io = sbi->write_io[btype] + temp; + struct f2fs_lock_context lc; - f2fs_down_write(&io->io_rwsem); + f2fs_down_write_trace(&io->io_rwsem, &lc); if (!io->bio) goto unlock_out; @@ -636,27 +677,37 @@ static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi, } __submit_merged_bio(io); unlock_out: - f2fs_up_write(&io->io_rwsem); + f2fs_up_write_trace(&io->io_rwsem, &lc); } static void __submit_merged_write_cond(struct f2fs_sb_info *sbi, struct inode *inode, struct folio *folio, - nid_t ino, enum page_type type, bool force) + nid_t ino, enum page_type type, bool writeback) { enum temp_type temp; bool ret = true; + bool force = !inode && !folio && !ino; for (temp = HOT; temp < NR_TEMP_TYPE; temp++) { if (!force) { enum page_type btype = PAGE_TYPE_OF_BIO(type); struct f2fs_bio_info *io = sbi->write_io[btype] + temp; + struct f2fs_lock_context lc; - f2fs_down_read(&io->io_rwsem); + f2fs_down_read_trace(&io->io_rwsem, &lc); ret = __has_merged_page(io->bio, inode, folio, ino); - f2fs_up_read(&io->io_rwsem); + f2fs_up_read_trace(&io->io_rwsem, &lc); } - if (ret) + if (ret) { __f2fs_submit_merged_write(sbi, type, temp); + /* + * For waitting writebck case, if the bio owned by the + * folio is already submitted, we do not need to submit + * other types of bios. + */ + if (writeback) + break; + } /* TODO: use HOT temp only for meta pages now. */ if (type >= META) @@ -666,7 +717,7 @@ static void __submit_merged_write_cond(struct f2fs_sb_info *sbi, void f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type) { - __submit_merged_write_cond(sbi, NULL, NULL, 0, type, true); + __submit_merged_write_cond(sbi, NULL, NULL, 0, type, false); } void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi, @@ -676,6 +727,12 @@ void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi, __submit_merged_write_cond(sbi, inode, folio, ino, type, false); } +void f2fs_submit_merged_write_folio(struct f2fs_sb_info *sbi, + struct folio *folio, enum page_type type) +{ + __submit_merged_write_cond(sbi, NULL, folio, 0, type, true); +} + void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi) { f2fs_submit_merged_write(sbi, DATA); @@ -949,11 +1006,12 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) enum page_type btype = PAGE_TYPE_OF_BIO(fio->type); struct f2fs_bio_info *io = sbi->write_io[btype] + fio->temp; struct folio *bio_folio; + struct f2fs_lock_context lc; enum count_type type; f2fs_bug_on(sbi, is_read_io(fio->op)); - f2fs_down_write(&io->io_rwsem); + f2fs_down_write_trace(&io->io_rwsem, &lc); next: #ifdef CONFIG_BLK_DEV_ZONED if (f2fs_sb_has_blkzoned(sbi) && btype < META && io->zone_pending_bio) { @@ -1035,7 +1093,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || !f2fs_is_checkpoint_ready(sbi)) __submit_merged_bio(io); - f2fs_up_write(&io->io_rwsem); + f2fs_up_write_trace(&io->io_rwsem, &lc); } static struct bio *f2fs_grab_read_bio(struct inode *inode, @@ -1212,11 +1270,21 @@ struct folio *f2fs_get_read_data_folio(struct inode *inode, pgoff_t index, struct dnode_of_data dn; struct folio *folio; int err; - +retry: folio = f2fs_grab_cache_folio(mapping, index, for_write); if (IS_ERR(folio)) return folio; + if (folio_test_large(folio)) { + pgoff_t folio_index = mapping_align_index(mapping, index); + + f2fs_folio_put(folio, true); + invalidate_inode_pages2_range(mapping, folio_index, + folio_index + folio_nr_pages(folio) - 1); + f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT); + goto retry; + } + if (f2fs_lookup_read_extent_cache_block(inode, index, &dn.data_blkaddr)) { if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), dn.data_blkaddr, @@ -1428,34 +1496,37 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) return 0; } -static void f2fs_map_lock(struct f2fs_sb_info *sbi, int flag) +static void f2fs_map_lock(struct f2fs_sb_info *sbi, + struct f2fs_lock_context *lc, + int flag) { - f2fs_down_read(&sbi->cp_enable_rwsem); if (flag == F2FS_GET_BLOCK_PRE_AIO) - f2fs_down_read(&sbi->node_change); + f2fs_down_read_trace(&sbi->node_change, lc); else - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, lc); } -static void f2fs_map_unlock(struct f2fs_sb_info *sbi, int flag) +static void f2fs_map_unlock(struct f2fs_sb_info *sbi, + struct f2fs_lock_context *lc, + int flag) { if (flag == F2FS_GET_BLOCK_PRE_AIO) - f2fs_up_read(&sbi->node_change); + f2fs_up_read_trace(&sbi->node_change, lc); else - f2fs_unlock_op(sbi); - f2fs_up_read(&sbi->cp_enable_rwsem); + f2fs_unlock_op(sbi, lc); } int f2fs_get_block_locked(struct dnode_of_data *dn, pgoff_t index) { struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); + struct f2fs_lock_context lc; int err = 0; - f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO); + f2fs_map_lock(sbi, &lc, F2FS_GET_BLOCK_PRE_AIO); if (!f2fs_lookup_read_extent_cache_block(dn->inode, index, &dn->data_blkaddr)) err = f2fs_reserve_block(dn, index); - f2fs_map_unlock(sbi, F2FS_GET_BLOCK_PRE_AIO); + f2fs_map_unlock(sbi, &lc, F2FS_GET_BLOCK_PRE_AIO); return err; } @@ -1546,6 +1617,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) unsigned int maxblocks = map->m_len; struct dnode_of_data dn; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_lock_context lc; int mode = map->m_may_create ? ALLOC_NODE : LOOKUP_NODE; pgoff_t pgofs, end_offset, end; int err = 0, ofs = 1; @@ -1584,7 +1656,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) if (map->m_may_create) { if (f2fs_lfs_mode(sbi)) f2fs_balance_fs(sbi, true); - f2fs_map_lock(sbi, flag); + f2fs_map_lock(sbi, &lc, flag); } /* When reading holes, we need its node page */ @@ -1750,7 +1822,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) f2fs_put_dnode(&dn); if (map->m_may_create) { - f2fs_map_unlock(sbi, flag); + f2fs_map_unlock(sbi, &lc, flag); f2fs_balance_fs(sbi, dn.node_changed); } goto next_dnode; @@ -1797,7 +1869,7 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) f2fs_put_dnode(&dn); unlock_out: if (map->m_may_create) { - f2fs_map_unlock(sbi, flag); + f2fs_map_unlock(sbi, &lc, flag); f2fs_balance_fs(sbi, dn.node_changed); } out: @@ -1805,7 +1877,8 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag) return err; } -bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len) +static bool __f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len, + bool check_first) { struct f2fs_map_blocks map; block_t last_lblk; @@ -1827,10 +1900,17 @@ bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len) if (err || map.m_len == 0) return false; map.m_lblk += map.m_len; + if (check_first) + break; } return true; } +bool f2fs_overwrite_io(struct inode *inode, loff_t pos, size_t len) +{ + return __f2fs_overwrite_io(inode, pos, len, false); +} + static int f2fs_xattr_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo) { @@ -2104,10 +2184,13 @@ static int f2fs_read_single_page(struct inode *inode, struct fsverity_info *vi, /* * Map blocks using the previous result first. */ - if ((map->m_flags & F2FS_MAP_MAPPED) && - block_in_file > map->m_lblk && + if (map->m_flags & F2FS_MAP_MAPPED) { + if (block_in_file > map->m_lblk && block_in_file < (map->m_lblk + map->m_len)) + goto got_it; + } else if (block_in_file < *map->m_next_pgofs) { goto got_it; + } /* * Then do more f2fs_map_blocks() calls until we are @@ -2343,6 +2426,185 @@ int f2fs_read_multi_pages(struct compress_ctx *cc, struct bio **bio_ret, } #endif +static struct f2fs_folio_state *ffs_find_or_alloc(struct folio *folio) +{ + struct f2fs_folio_state *ffs = folio->private; + + if (ffs) + return ffs; + + ffs = f2fs_kmem_cache_alloc(ffs_entry_slab, + GFP_NOIO | __GFP_ZERO, true, NULL); + + spin_lock_init(&ffs->state_lock); + folio_attach_private(folio, ffs); + return ffs; +} + +static void ffs_detach_free(struct folio *folio) +{ + struct f2fs_folio_state *ffs; + + if (!folio_test_large(folio)) { + folio_detach_private(folio); + return; + } + + ffs = folio_detach_private(folio); + if (!ffs) + return; + + WARN_ON_ONCE(ffs->read_pages_pending != 0); + kmem_cache_free(ffs_entry_slab, ffs); +} + +static int f2fs_read_data_large_folio(struct inode *inode, + struct fsverity_info *vi, + struct readahead_control *rac, struct folio *folio) +{ + struct bio *bio = NULL; + sector_t last_block_in_bio = 0; + struct f2fs_map_blocks map = {0, }; + pgoff_t index, offset, next_pgofs = 0; + unsigned max_nr_pages = rac ? readahead_count(rac) : + folio_nr_pages(folio); + unsigned nrpages; + struct f2fs_folio_state *ffs; + int ret = 0; + bool folio_in_bio; + + if (!IS_IMMUTABLE(inode) || f2fs_compressed_file(inode)) { + if (folio) + folio_unlock(folio); + return -EOPNOTSUPP; + } + + map.m_seg_type = NO_CHECK_TYPE; + + if (rac) + folio = readahead_folio(rac); +next_folio: + if (!folio) + goto out; + + folio_in_bio = false; + index = folio->index; + offset = 0; + ffs = NULL; + nrpages = folio_nr_pages(folio); + + for (; nrpages; nrpages--, max_nr_pages--, index++, offset++) { + sector_t block_nr; + /* + * Map blocks using the previous result first. + */ + if (map.m_flags & F2FS_MAP_MAPPED) { + if (index > map.m_lblk && + index < (map.m_lblk + map.m_len)) + goto got_it; + } else if (index < next_pgofs) { + /* hole case */ + goto got_it; + } + + /* + * Then do more f2fs_map_blocks() calls until we are + * done with this page. + */ + memset(&map, 0, sizeof(map)); + map.m_next_pgofs = &next_pgofs; + map.m_seg_type = NO_CHECK_TYPE; + map.m_lblk = index; + map.m_len = max_nr_pages; + + ret = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DEFAULT); + if (ret) + goto err_out; +got_it: + if ((map.m_flags & F2FS_MAP_MAPPED)) { + block_nr = map.m_pblk + index - map.m_lblk; + if (!f2fs_is_valid_blkaddr(F2FS_I_SB(inode), block_nr, + DATA_GENERIC_ENHANCE_READ)) { + ret = -EFSCORRUPTED; + goto err_out; + } + } else { + size_t page_offset = offset << PAGE_SHIFT; + folio_zero_range(folio, page_offset, PAGE_SIZE); + if (vi && !fsverity_verify_blocks(vi, folio, PAGE_SIZE, page_offset)) { + ret = -EIO; + goto err_out; + } + continue; + } + + /* We must increment read_pages_pending before possible BIOs submitting + * to prevent from premature folio_end_read() call on folio + */ + if (folio_test_large(folio)) { + ffs = ffs_find_or_alloc(folio); + + /* set the bitmap to wait */ + spin_lock_irq(&ffs->state_lock); + ffs->read_pages_pending++; + spin_unlock_irq(&ffs->state_lock); + } + + /* + * This page will go to BIO. Do we need to send this + * BIO off first? + */ + if (bio && (!page_is_mergeable(F2FS_I_SB(inode), bio, + last_block_in_bio, block_nr) || + !f2fs_crypt_mergeable_bio(bio, inode, index, NULL))) { +submit_and_realloc: + f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA); + bio = NULL; + } + if (bio == NULL) + bio = f2fs_grab_read_bio(inode, vi, + block_nr, max_nr_pages, + f2fs_ra_op_flags(rac), + index, false); + + /* + * If the page is under writeback, we need to wait for + * its completion to see the correct decrypted data. + */ + f2fs_wait_on_block_writeback(inode, block_nr); + + if (!bio_add_folio(bio, folio, F2FS_BLKSIZE, + offset << PAGE_SHIFT)) + goto submit_and_realloc; + + folio_in_bio = true; + inc_page_count(F2FS_I_SB(inode), F2FS_RD_DATA); + f2fs_update_iostat(F2FS_I_SB(inode), NULL, FS_DATA_READ_IO, + F2FS_BLKSIZE); + last_block_in_bio = block_nr; + } + trace_f2fs_read_folio(folio, DATA); +err_out: + if (!folio_in_bio) { + folio_end_read(folio, !ret); + if (ret) + return ret; + } + if (rac) { + folio = readahead_folio(rac); + goto next_folio; + } +out: + f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA); + if (ret) { + /* Wait bios and clear uptodate. */ + folio_lock(folio); + folio_clear_uptodate(folio); + folio_unlock(folio); + } + return ret; +} + /* * This function was originally taken from fs/mpage.c, and customized for f2fs. * Major change was from block_size == page_size in f2fs by default. @@ -2367,10 +2629,15 @@ static int f2fs_mpage_readpages(struct inode *inode, struct fsverity_info *vi, pgoff_t nc_cluster_idx = NULL_CLUSTER; pgoff_t index; #endif + pgoff_t next_pgofs = 0; unsigned nr_pages = rac ? readahead_count(rac) : 1; + struct address_space *mapping = rac ? rac->mapping : folio->mapping; unsigned max_nr_pages = nr_pages; int ret = 0; + if (mapping_large_folio_support(mapping)) + return f2fs_read_data_large_folio(inode, vi, rac, folio); + #ifdef CONFIG_F2FS_FS_COMPRESSION if (f2fs_compressed_file(inode)) { index = rac ? readahead_index(rac) : folio->index; @@ -2383,7 +2650,7 @@ static int f2fs_mpage_readpages(struct inode *inode, struct fsverity_info *vi, map.m_lblk = 0; map.m_len = 0; map.m_flags = 0; - map.m_next_pgofs = NULL; + map.m_next_pgofs = &next_pgofs; map.m_next_extent = NULL; map.m_seg_type = NO_CHECK_TYPE; map.m_may_create = false; @@ -2464,8 +2731,7 @@ static int f2fs_mpage_readpages(struct inode *inode, struct fsverity_info *vi, } #endif } - if (bio) - f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA); + f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA); return ret; } @@ -2663,6 +2929,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) struct inode *inode = folio->mapping->host; struct dnode_of_data dn; struct node_info ni; + struct f2fs_lock_context lc; bool ipu_force = false; bool atomic_commit; int err = 0; @@ -2687,8 +2954,12 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) goto got_it; } + if (is_sbi_flag_set(fio->sbi, SBI_ENABLE_CHECKPOINT) && + time_to_inject(fio->sbi, FAULT_SKIP_WRITE)) + return -EINVAL; + /* Deadlock due to between page->lock and f2fs_lock_op */ - if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi)) + if (fio->need_lock == LOCK_REQ && !f2fs_trylock_op(fio->sbi, &lc)) return -EAGAIN; err = f2fs_get_dnode_of_data(&dn, folio->index, LOOKUP_NODE); @@ -2729,7 +3000,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) folio_start_writeback(folio); f2fs_put_dnode(&dn); if (fio->need_lock == LOCK_REQ) - f2fs_unlock_op(fio->sbi); + f2fs_unlock_op(fio->sbi, &lc); err = f2fs_inplace_write_data(fio); if (err) { if (fscrypt_inode_uses_fs_layer_crypto(inode)) @@ -2743,7 +3014,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) } if (fio->need_lock == LOCK_RETRY) { - if (!f2fs_trylock_op(fio->sbi)) { + if (!f2fs_trylock_op(fio->sbi, &lc)) { err = -EAGAIN; goto out_writepage; } @@ -2775,7 +3046,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) f2fs_put_dnode(&dn); out: if (fio->need_lock == LOCK_REQ) - f2fs_unlock_op(fio->sbi); + f2fs_unlock_op(fio->sbi, &lc); return err; } @@ -2855,19 +3126,21 @@ int f2fs_write_single_data_page(struct folio *folio, int *submitted, write: /* Dentry/quota blocks are controlled by checkpoint */ if (S_ISDIR(inode->i_mode) || quota_inode) { + struct f2fs_lock_context lc; + /* * We need to wait for node_write to avoid block allocation during * checkpoint. This can only happen to quota writes which can cause * the below discard race condition. */ if (quota_inode) - f2fs_down_read(&sbi->node_write); + f2fs_down_read_trace(&sbi->node_write, &lc); fio.need_lock = LOCK_DONE; err = f2fs_do_write_data_page(&fio); if (quota_inode) - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); goto done; } @@ -3237,6 +3510,8 @@ static inline bool __should_serialize_io(struct inode *inode, if (IS_NOQUOTA(inode)) return false; + if (f2fs_is_pinned_file(inode)) + return false; if (f2fs_need_compress_data(inode)) return true; if (wbc->sync_mode != WB_SYNC_ALL) @@ -3259,6 +3534,16 @@ static inline void account_writeback(struct inode *inode, bool inc) f2fs_up_read(&F2FS_I(inode)->i_sem); } +static inline void update_skipped_write(struct f2fs_sb_info *sbi, + struct writeback_control *wbc) +{ + long skipped = wbc->pages_skipped; + + if (is_sbi_flag_set(sbi, SBI_ENABLE_CHECKPOINT) && skipped && + wbc->sync_mode == WB_SYNC_ALL) + atomic_add(skipped, &sbi->nr_pages[F2FS_SKIPPED_WRITE]); +} + static int __f2fs_write_data_pages(struct address_space *mapping, struct writeback_control *wbc, enum iostat_type io_type) @@ -3323,10 +3608,19 @@ static int __f2fs_write_data_pages(struct address_space *mapping, */ f2fs_remove_dirty_inode(inode); + + /* + * f2fs_write_cache_pages() has retry logic for EAGAIN case which is + * common when racing w/ checkpoint, so only update skipped write + * when ret is non-zero. + */ + if (ret) + update_skipped_write(sbi, wbc); return ret; skip_write: wbc->pages_skipped += get_dirty_pages(inode); + update_skipped_write(sbi, wbc); trace_f2fs_writepages(mapping->host, wbc, DATA); return 0; } @@ -3368,6 +3662,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, struct inode *inode = folio->mapping->host; pgoff_t index = folio->index; struct dnode_of_data dn; + struct f2fs_lock_context lc; struct folio *ifolio; bool locked = false; int flag = F2FS_GET_BLOCK_PRE_AIO; @@ -3384,10 +3679,10 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, if (f2fs_has_inline_data(inode)) { if (pos + len > MAX_INLINE_DATA(inode)) flag = F2FS_GET_BLOCK_DEFAULT; - f2fs_map_lock(sbi, flag); + f2fs_map_lock(sbi, &lc, flag); locked = true; } else if ((pos & PAGE_MASK) >= i_size_read(inode)) { - f2fs_map_lock(sbi, flag); + f2fs_map_lock(sbi, &lc, flag); locked = true; } @@ -3431,7 +3726,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, if (!err && dn.data_blkaddr != NULL_ADDR) goto out; f2fs_put_dnode(&dn); - f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO); + f2fs_map_lock(sbi, &lc, F2FS_GET_BLOCK_PRE_AIO); WARN_ON(flag != F2FS_GET_BLOCK_PRE_AIO); locked = true; goto restart; @@ -3445,7 +3740,7 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi, f2fs_put_dnode(&dn); unlock_out: if (locked) - f2fs_map_unlock(sbi, flag); + f2fs_map_unlock(sbi, &lc, flag); return err; } @@ -3481,10 +3776,11 @@ static int __reserve_data_block(struct inode *inode, pgoff_t index, { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; + struct f2fs_lock_context lc; struct folio *ifolio; int err = 0; - f2fs_map_lock(sbi, F2FS_GET_BLOCK_PRE_AIO); + f2fs_map_lock(sbi, &lc, F2FS_GET_BLOCK_PRE_AIO); ifolio = f2fs_get_inode_folio(sbi, inode->i_ino); if (IS_ERR(ifolio)) { @@ -3502,7 +3798,7 @@ static int __reserve_data_block(struct inode *inode, pgoff_t index, f2fs_put_dnode(&dn); unlock_out: - f2fs_map_unlock(sbi, F2FS_GET_BLOCK_PRE_AIO); + f2fs_map_unlock(sbi, &lc, F2FS_GET_BLOCK_PRE_AIO); return err; } @@ -3761,7 +4057,12 @@ void f2fs_invalidate_folio(struct folio *folio, size_t offset, size_t length) f2fs_remove_dirty_inode(inode); } } - folio_detach_private(folio); + + if (offset || length != folio_size(folio)) + return; + + folio_cancel_dirty(folio); + ffs_detach_free(folio); } bool f2fs_release_folio(struct folio *folio, gfp_t wait) @@ -3770,7 +4071,7 @@ bool f2fs_release_folio(struct folio *folio, gfp_t wait) if (folio_test_dirty(folio)) return false; - folio_detach_private(folio); + ffs_detach_free(folio); return true; } @@ -3955,6 +4256,7 @@ static int check_swap_activate(struct swap_info_struct *sis, while (cur_lblock < last_lblock && cur_lblock < sis->max) { struct f2fs_map_blocks map; + bool last_extent = false; retry: cond_resched(); @@ -3980,11 +4282,10 @@ static int check_swap_activate(struct swap_info_struct *sis, pblock = map.m_pblk; nr_pblocks = map.m_len; - if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || - nr_pblocks % blks_per_sec || - f2fs_is_sequential_zone_area(sbi, pblock)) { - bool last_extent = false; - + if (!last_extent && + ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || + nr_pblocks % blks_per_sec || + f2fs_is_sequential_zone_area(sbi, pblock))) { not_aligned++; nr_pblocks = roundup(nr_pblocks, blks_per_sec); @@ -4005,8 +4306,8 @@ static int check_swap_activate(struct swap_info_struct *sis, goto out; } - if (!last_extent) - goto retry; + /* lookup block mapping info after block migration */ + goto retry; } if (cur_lblock + nr_pblocks >= sis->max) @@ -4176,12 +4477,25 @@ int __init f2fs_init_bio_entry_cache(void) { bio_entry_slab = f2fs_kmem_cache_create("f2fs_bio_entry_slab", sizeof(struct bio_entry)); - return bio_entry_slab ? 0 : -ENOMEM; + + if (!bio_entry_slab) + return -ENOMEM; + + ffs_entry_slab = f2fs_kmem_cache_create("f2fs_ffs_slab", + sizeof(struct f2fs_folio_state)); + + if (!ffs_entry_slab) { + kmem_cache_destroy(bio_entry_slab); + return -ENOMEM; + } + + return 0; } void f2fs_destroy_bio_entry_cache(void) { kmem_cache_destroy(bio_entry_slab); + kmem_cache_destroy(ffs_entry_slab); } static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, @@ -4207,7 +4521,7 @@ static int f2fs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, * f2fs_map_lock and f2fs_balance_fs are not necessary. */ if ((flags & IOMAP_WRITE) && - !f2fs_overwrite_io(inode, offset, length)) + !__f2fs_overwrite_io(inode, offset, length, true)) map.m_may_create = true; err = f2fs_map_blocks(inode, &map, F2FS_GET_BLOCK_DIO); diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index 032683835569..8e1040e375a7 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -423,6 +423,7 @@ static const char *s_flag[MAX_SBI_FLAG] = { [SBI_IS_RESIZEFS] = "resizefs", [SBI_IS_FREEZING] = "freezefs", [SBI_IS_WRITABLE] = "writable", + [SBI_ENABLE_CHECKPOINT] = "enable_checkpoint", }; static const char *ipu_mode_names[F2FS_IPU_MAX] = { diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index be70dfb3b152..f70092e231f0 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -68,7 +68,7 @@ int f2fs_init_casefolded_name(const struct inode *dir, int len; if (IS_CASEFOLDED(dir) && - !is_dot_dotdot(fname->usr_fname->name, fname->usr_fname->len)) { + !name_is_dot_dotdot(fname->usr_fname->name, fname->usr_fname->len)) { buf = f2fs_kmem_cache_alloc(f2fs_cf_name_slab, GFP_NOFS, false, F2FS_SB(sb)); if (!buf) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a90a62cfe617..bb34e864d0ef 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -54,7 +54,7 @@ enum { FAULT_TRUNCATE, FAULT_READ_IO, FAULT_CHECKPOINT, - FAULT_DISCARD, + FAULT_DISCARD, /* it's obsolete due to __blkdev_issue_discard() will never fail */ FAULT_WRITE_IO, FAULT_SLAB_ALLOC, FAULT_DQUOT_INIT, @@ -63,8 +63,10 @@ enum { FAULT_BLKADDR_CONSISTENCE, FAULT_NO_SEGMENT, FAULT_INCONSISTENT_FOOTER, - FAULT_TIMEOUT, + FAULT_ATOMIC_TIMEOUT, FAULT_VMALLOC, + FAULT_LOCK_TIMEOUT, + FAULT_SKIP_WRITE, FAULT_MAX, }; @@ -72,7 +74,8 @@ enum { enum fault_option { FAULT_RATE = 1, /* only update fault rate */ FAULT_TYPE = 2, /* only update fault type */ - FAULT_ALL = 4, /* reset all fault injection options/stats */ + FAULT_TIMEOUT = 4, /* only update fault timeout type */ + FAULT_ALL = 8, /* reset all fault injection options/stats */ }; #ifdef CONFIG_F2FS_FAULT_INJECTION @@ -82,6 +85,7 @@ struct f2fs_fault_info { unsigned int inject_type; /* Used to account total count of injection for each type */ unsigned int inject_count[FAULT_MAX]; + unsigned int inject_lock_timeout; /* inject lock timeout */ }; extern const char *f2fs_fault_name[FAULT_MAX]; @@ -173,6 +177,26 @@ enum device_allocation_policy { ALLOCATE_FORWARD_FROM_HINT, }; +enum f2fs_lock_name { + LOCK_NAME_NONE, + LOCK_NAME_CP_RWSEM, + LOCK_NAME_NODE_CHANGE, + LOCK_NAME_NODE_WRITE, + LOCK_NAME_GC_LOCK, + LOCK_NAME_CP_GLOBAL, + LOCK_NAME_IO_RWSEM, + LOCK_NAME_MAX, +}; + +enum f2fs_timeout_type { + TIMEOUT_TYPE_NONE, + TIMEOUT_TYPE_RUNNING, + TIMEOUT_TYPE_IO_SLEEP, + TIMEOUT_TYPE_NONIO_SLEEP, + TIMEOUT_TYPE_RUNNABLE, + TIMEOUT_TYPE_MAX, +}; + /* * An implementation of an rwsem that is explicitly unfair to readers. This * prevents priority inversion when a low-priority reader acquires the read lock @@ -181,6 +205,8 @@ enum device_allocation_policy { */ struct f2fs_rwsem { + struct f2fs_sb_info *sbi; + enum f2fs_lock_name name; struct rw_semaphore internal_rwsem; #ifdef CONFIG_F2FS_UNFAIR_RWSEM wait_queue_head_t read_waiters; @@ -287,7 +313,6 @@ enum { #define DEF_CP_INTERVAL 60 /* 60 secs */ #define DEF_IDLE_INTERVAL 5 /* 5 secs */ #define DEF_DISABLE_INTERVAL 5 /* 5 secs */ -#define DEF_ENABLE_INTERVAL 5 /* 5 secs */ #define DEF_DISABLE_QUICK_INTERVAL 1 /* 1 secs */ #define DEF_UMOUNT_DISCARD_TIMEOUT 5 /* 5 secs */ @@ -295,7 +320,9 @@ enum cp_time { CP_TIME_START, /* begin */ CP_TIME_LOCK, /* after cp_global_sem */ CP_TIME_OP_LOCK, /* after block_operation */ - CP_TIME_FLUSH_META, /* after flush sit/nat */ + CP_TIME_MERGE_WRITE, /* after flush DATA/NODE/META */ + CP_TIME_FLUSH_NAT, /* after flush nat */ + CP_TIME_FLUSH_SIT, /* after flush sit */ CP_TIME_SYNC_META, /* after sync_meta_pages */ CP_TIME_SYNC_CP_META, /* after sync cp meta pages */ CP_TIME_WAIT_DIRTY_META,/* after wait on dirty meta */ @@ -521,13 +548,25 @@ struct fsync_inode_entry { #define nats_in_cursum(jnl) (le16_to_cpu((jnl)->n_nats)) #define sits_in_cursum(jnl) (le16_to_cpu((jnl)->n_sits)) -#define nat_in_journal(jnl, i) ((jnl)->nat_j.entries[i].ne) -#define nid_in_journal(jnl, i) ((jnl)->nat_j.entries[i].nid) -#define sit_in_journal(jnl, i) ((jnl)->sit_j.entries[i].se) -#define segno_in_journal(jnl, i) ((jnl)->sit_j.entries[i].segno) +#define nat_in_journal(jnl, i) \ + (((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].ne) +#define nid_in_journal(jnl, i) \ + (((struct nat_journal_entry *)(jnl)->nat_j.entries)[i].nid) +#define sit_in_journal(jnl, i) \ + (((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].se) +#define segno_in_journal(jnl, i) \ + (((struct sit_journal_entry *)(jnl)->sit_j.entries)[i].segno) -#define MAX_NAT_JENTRIES(jnl) (NAT_JOURNAL_ENTRIES - nats_in_cursum(jnl)) -#define MAX_SIT_JENTRIES(jnl) (SIT_JOURNAL_ENTRIES - sits_in_cursum(jnl)) +#define sum_entries(sum) ((struct f2fs_summary *)(sum)) +#define sum_journal(sbi, sum) \ + ((struct f2fs_journal *)((char *)(sum) + \ + ((sbi)->entries_in_sum * sizeof(struct f2fs_summary)))) +#define sum_footer(sbi, sum) \ + ((struct summary_footer *)((char *)(sum) + (sbi)->sum_blocksize - \ + sizeof(struct summary_footer))) + +#define MAX_NAT_JENTRIES(sbi, jnl) ((sbi)->nat_journal_entries - nats_in_cursum(jnl)) +#define MAX_SIT_JENTRIES(sbi, jnl) ((sbi)->sit_journal_entries - sits_in_cursum(jnl)) static inline int update_nats_in_cursum(struct f2fs_journal *journal, int i) { @@ -545,14 +584,6 @@ static inline int update_sits_in_cursum(struct f2fs_journal *journal, int i) return before; } -static inline bool __has_cursum_space(struct f2fs_journal *journal, - int size, int type) -{ - if (type == NAT_JOURNAL) - return size <= MAX_NAT_JENTRIES(journal); - return size <= MAX_SIT_JENTRIES(journal); -} - /* for inline stuff */ #define DEF_INLINE_RESERVED_SIZE 1 static inline int get_extra_isize(struct inode *inode); @@ -669,8 +700,10 @@ enum { #define DEFAULT_RETRY_IO_COUNT 8 /* maximum retry read IO or flush count */ -/* IO/non-IO congestion wait timeout value, default: 1ms */ -#define DEFAULT_SCHEDULE_TIMEOUT (msecs_to_jiffies(1)) +#define MAX_FLUSH_RETRY_COUNT 3 /* maximum flush retry count in f2fs_enable_checkpoint() */ + +/* IO/non-IO congestion wait timeout value, default: 1 jiffies */ +#define DEFAULT_SCHEDULE_TIMEOUT 1 /* timeout value injected, default: 1000ms */ #define DEFAULT_FAULT_TIMEOUT (msecs_to_jiffies(1000)) @@ -1208,6 +1241,7 @@ enum count_type { F2FS_RD_META, F2FS_DIO_WRITE, F2FS_DIO_READ, + F2FS_SKIPPED_WRITE, /* skip or fail during f2fs_enable_checkpoint() */ NR_COUNT_TYPE, }; @@ -1396,6 +1430,27 @@ struct atgc_management { unsigned long long age_threshold; /* age threshold */ }; +struct f2fs_time_stat { + unsigned long long total_time; /* total wall clock time */ +#ifdef CONFIG_64BIT + unsigned long long running_time; /* running time */ +#endif +#if defined(CONFIG_SCHED_INFO) && defined(CONFIG_SCHEDSTATS) + unsigned long long runnable_time; /* runnable(including preempted) time */ +#endif +#ifdef CONFIG_TASK_DELAY_ACCT + unsigned long long io_sleep_time; /* IO sleep time */ +#endif +}; + +struct f2fs_lock_context { + struct f2fs_time_stat ts; + int orig_nice; + int new_nice; + bool lock_trace; + bool need_restore; +}; + struct f2fs_gc_control { unsigned int victim_segno; /* target victim segment number */ int init_gc_type; /* FG_GC or BG_GC */ @@ -1404,6 +1459,7 @@ struct f2fs_gc_control { bool err_gc_skipped; /* return EAGAIN if GC skipped */ bool one_time; /* require one time GC in one migration unit */ unsigned int nr_free_secs; /* # of free sections to do GC */ + struct f2fs_lock_context lc; /* lock context for gc_lock */ }; /* @@ -1427,6 +1483,7 @@ enum { SBI_IS_RESIZEFS, /* resizefs is in process */ SBI_IS_FREEZING, /* freezefs is in process */ SBI_IS_WRITABLE, /* remove ro mountoption transiently */ + SBI_ENABLE_CHECKPOINT, /* indicate it's during f2fs_enable_checkpoint() */ MAX_SBI_FLAG, }; @@ -1436,7 +1493,6 @@ enum { DISCARD_TIME, GC_TIME, DISABLE_TIME, - ENABLE_TIME, UMOUNT_DISCARD_TIMEOUT, MAX_TIME, }; @@ -1522,6 +1578,20 @@ enum f2fs_lookup_mode { LOOKUP_AUTO, }; +/* For node type in __get_node_folio() */ +enum node_type { + NODE_TYPE_REGULAR, + NODE_TYPE_INODE, + NODE_TYPE_XATTR, + NODE_TYPE_NON_INODE, +}; + +/* a threshold of maximum elapsed time in critical region to print tracepoint */ +#define MAX_LOCK_ELAPSED_TIME 500 + +#define F2FS_DEFAULT_TASK_PRIORITY (DEFAULT_PRIO) +#define F2FS_CRITICAL_TASK_PRIORITY NICE_TO_PRIO(0) + static inline int f2fs_test_bit(unsigned int nr, char *addr); static inline void f2fs_set_bit(unsigned int nr, char *addr); static inline void f2fs_clear_bit(unsigned int nr, char *addr); @@ -1714,7 +1784,6 @@ struct f2fs_sb_info { long interval_time[MAX_TIME]; /* to store thresholds */ struct ckpt_req_control cprc_info; /* for checkpoint request control */ struct cp_stats cp_stats; /* for time stat of checkpoint */ - struct f2fs_rwsem cp_enable_rwsem; /* block cache/dio write */ struct inode_management im[MAX_INO_ENTRY]; /* manage inode cache */ @@ -1760,7 +1829,16 @@ struct f2fs_sb_info { unsigned int total_valid_node_count; /* valid node block count */ int dir_level; /* directory level */ bool readdir_ra; /* readahead inode in readdir */ - u64 max_io_bytes; /* max io bytes to merge IOs */ + unsigned int max_io_bytes; /* max io bytes to merge IOs */ + + /* variable summary block units */ + unsigned int sum_blocksize; /* sum block size */ + unsigned int sums_per_block; /* sum block count per block */ + unsigned int entries_in_sum; /* entry count in sum block */ + unsigned int sum_entry_size; /* total entry size in sum block */ + unsigned int sum_journal_size; /* journal size in sum block */ + unsigned int nat_journal_entries; /* nat journal entry count in the journal */ + unsigned int sit_journal_entries; /* sit journal entry count in the journal */ block_t user_block_count; /* # of user blocks */ block_t total_valid_block_count; /* # of valid blocks */ @@ -1908,7 +1986,7 @@ struct f2fs_sb_info { unsigned int gc_segment_mode; /* GC state for reclaimed segments */ unsigned int gc_reclaimed_segs[MAX_GC_MODE]; /* Reclaimed segs for each mode */ - unsigned long seq_file_ra_mul; /* multiplier for ra_pages of seq. files in fadvise */ + unsigned int seq_file_ra_mul; /* multiplier for ra_pages of seq. files in fadvise */ int max_fragment_chunk; /* max chunk size for block fragmentation mode */ int max_fragment_hole; /* max hole size for block fragmentation mode */ @@ -1922,6 +2000,18 @@ struct f2fs_sb_info { /* carve out reserved_blocks from total blocks */ bool carve_out; + /* max elapsed time threshold in critical region that lock covered */ + unsigned long long max_lock_elapsed_time; + + /* enable/disable to adjust task priority in critical region covered by lock */ + unsigned int adjust_lock_priority; + + /* adjust priority for task which is in critical region covered by lock */ + unsigned int lock_duration_priority; + + /* priority for critical task, e.g. f2fs_ckpt, f2fs_gc threads */ + long critical_task_priority; + #ifdef CONFIG_F2FS_FS_COMPRESSION struct kmem_cache *page_array_slab; /* page array entry */ unsigned int page_array_slab_size; /* default page array slab size */ @@ -2261,16 +2351,22 @@ static inline void clear_ckpt_flags(struct f2fs_sb_info *sbi, unsigned int f) spin_unlock_irqrestore(&sbi->cp_lock, flags); } -#define init_f2fs_rwsem(sem) \ +#define init_f2fs_rwsem(sem) __init_f2fs_rwsem(sem, NULL, LOCK_NAME_NONE) +#define init_f2fs_rwsem_trace __init_f2fs_rwsem + +#define __init_f2fs_rwsem(sem, sbi, name) \ do { \ static struct lock_class_key __key; \ \ - __init_f2fs_rwsem((sem), #sem, &__key); \ + do_init_f2fs_rwsem((sem), #sem, &__key, sbi, name); \ } while (0) -static inline void __init_f2fs_rwsem(struct f2fs_rwsem *sem, - const char *sem_name, struct lock_class_key *key) +static inline void do_init_f2fs_rwsem(struct f2fs_rwsem *sem, + const char *sem_name, struct lock_class_key *key, + struct f2fs_sb_info *sbi, enum f2fs_lock_name name) { + sem->sbi = sbi; + sem->name = name; __init_rwsem(&sem->internal_rwsem, sem_name, key); #ifdef CONFIG_F2FS_UNFAIR_RWSEM init_waitqueue_head(&sem->read_waiters); @@ -2339,6 +2435,16 @@ static inline void f2fs_up_write(struct f2fs_rwsem *sem) #endif } +void f2fs_down_read_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc); +int f2fs_down_read_trylock_trace(struct f2fs_rwsem *sem, + struct f2fs_lock_context *lc); +void f2fs_up_read_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc); +void f2fs_down_write_trace(struct f2fs_rwsem *sem, + struct f2fs_lock_context *lc); +int f2fs_down_write_trylock_trace(struct f2fs_rwsem *sem, + struct f2fs_lock_context *lc); +void f2fs_up_write_trace(struct f2fs_rwsem *sem, struct f2fs_lock_context *lc); + static inline void disable_nat_bits(struct f2fs_sb_info *sbi, bool lock) { unsigned long flags; @@ -2369,33 +2475,6 @@ static inline bool enabled_nat_bits(struct f2fs_sb_info *sbi, return (cpc) ? (cpc->reason & CP_UMOUNT) && set : set; } -static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) -{ - f2fs_down_read(&sbi->cp_rwsem); -} - -static inline int f2fs_trylock_op(struct f2fs_sb_info *sbi) -{ - if (time_to_inject(sbi, FAULT_LOCK_OP)) - return 0; - return f2fs_down_read_trylock(&sbi->cp_rwsem); -} - -static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi) -{ - f2fs_up_read(&sbi->cp_rwsem); -} - -static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) -{ - f2fs_down_write(&sbi->cp_rwsem); -} - -static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) -{ - f2fs_up_write(&sbi->cp_rwsem); -} - static inline int __get_cp_reason(struct f2fs_sb_info *sbi) { int reason = CP_SYNC; @@ -2811,6 +2890,14 @@ static inline block_t __start_sum_addr(struct f2fs_sb_info *sbi) return le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum); } +static inline bool __has_cursum_space(struct f2fs_sb_info *sbi, + struct f2fs_journal *journal, unsigned int size, int type) +{ + if (type == NAT_JOURNAL) + return size <= MAX_NAT_JENTRIES(sbi, journal); + return size <= MAX_SIT_JENTRIES(sbi, journal); +} + extern void f2fs_mark_inode_dirty_sync(struct inode *inode, bool sync); static inline int inc_valid_node_count(struct f2fs_sb_info *sbi, struct inode *inode, bool is_inode) @@ -3722,7 +3809,7 @@ void f2fs_update_inode_page(struct inode *inode); int f2fs_write_inode(struct inode *inode, struct writeback_control *wbc); void f2fs_remove_donate_inode(struct inode *inode); void f2fs_evict_inode(struct inode *inode); -void f2fs_handle_failed_inode(struct inode *inode); +void f2fs_handle_failed_inode(struct inode *inode, struct f2fs_lock_context *lc); /* * namei.c @@ -3855,6 +3942,9 @@ struct folio *f2fs_new_node_folio(struct dnode_of_data *dn, unsigned int ofs); void f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid); struct folio *f2fs_get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid, enum node_type node_type); +int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi, + struct folio *folio, pgoff_t nid, + enum node_type ntype, bool in_irq); struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t ino); struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t xnid); int f2fs_move_node_folio(struct folio *node_folio, int gc_type); @@ -3954,7 +4044,8 @@ void f2fs_wait_on_block_writeback_range(struct inode *inode, block_t blkaddr, block_t len); void f2fs_write_data_summaries(struct f2fs_sb_info *sbi, block_t start_blk); void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk); -int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, +int f2fs_lookup_journal_in_cursum(struct f2fs_sb_info *sbi, + struct f2fs_journal *journal, int type, unsigned int val, int alloc); void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc); int f2fs_check_and_fix_write_pointer(struct f2fs_sb_info *sbi); @@ -3989,6 +4080,9 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi) /* * checkpoint.c */ +void f2fs_lock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc); +int f2fs_trylock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc); +void f2fs_unlock_op(struct f2fs_sb_info *sbi, struct f2fs_lock_context *lc); void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io, unsigned char reason); void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi); @@ -4004,8 +4098,8 @@ int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages, int type, bool sync); void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index, unsigned int ra_blocks); -long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type, - long nr_to_write, enum iostat_type io_type); +long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, long nr_to_write, + enum iostat_type io_type); void f2fs_add_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); void f2fs_remove_ino_entry(struct f2fs_sb_info *sbi, nid_t ino, int type); void f2fs_release_ino_entry(struct f2fs_sb_info *sbi, bool all); @@ -4050,6 +4144,8 @@ void f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type type); void f2fs_submit_merged_write_cond(struct f2fs_sb_info *sbi, struct inode *inode, struct folio *folio, nid_t ino, enum page_type type); +void f2fs_submit_merged_write_folio(struct f2fs_sb_info *sbi, + struct folio *folio, enum page_type type); void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi, struct bio **bio, struct folio *folio); void f2fs_flush_merged_writes(struct f2fs_sb_info *sbi); @@ -4887,6 +4983,7 @@ static inline bool f2fs_allow_multi_device_dio(struct f2fs_sb_info *sbi, #ifdef CONFIG_F2FS_FAULT_INJECTION extern int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate, unsigned long type, enum fault_option fo); +extern void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi); #else static inline int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate, unsigned long type, @@ -4894,6 +4991,10 @@ static inline int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, { return 0; } +static inline void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi) +{ + return; +} #endif static inline bool is_journalled_quota(struct f2fs_sb_info *sbi) @@ -4909,6 +5010,22 @@ static inline bool is_journalled_quota(struct f2fs_sb_info *sbi) return false; } +static inline bool f2fs_quota_file(struct f2fs_sb_info *sbi, nid_t ino) +{ +#ifdef CONFIG_QUOTA + int i; + + if (!f2fs_sb_has_quota_ino(sbi)) + return false; + + for (i = 0; i < MAXQUOTAS; i++) { + if (f2fs_qf_ino(sbi->sb, i) == ino) + return true; + } +#endif + return false; +} + static inline bool f2fs_block_unit_discard(struct f2fs_sb_info *sbi) { return F2FS_OPTION(sbi).discard_unit == DISCARD_UNIT_BLOCK; @@ -4928,16 +5045,14 @@ static inline void __f2fs_schedule_timeout(long timeout, bool io) #define f2fs_schedule_timeout(timeout) \ __f2fs_schedule_timeout(timeout, false) -static inline void f2fs_io_schedule_timeout_killable(long timeout) +static inline void f2fs_schedule_timeout_killable(long timeout, bool io) { - while (timeout) { + unsigned long last_time = jiffies + timeout; + + while (jiffies < last_time) { if (fatal_signal_pending(current)) return; - set_current_state(TASK_UNINTERRUPTIBLE); - io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT); - if (timeout <= DEFAULT_SCHEDULE_TIMEOUT) - return; - timeout -= DEFAULT_SCHEDULE_TIMEOUT; + __f2fs_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT, io); } } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 1fdbe18692be..c8a2f17a8f11 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -626,6 +626,10 @@ static int f2fs_file_open(struct inode *inode, struct file *filp) if (!f2fs_is_compress_backend_ready(inode)) return -EOPNOTSUPP; + if (mapping_large_folio_support(inode->i_mapping) && + filp->f_mode & FMODE_WRITE) + return -EOPNOTSUPP; + err = fsverity_file_open(inode, filp); if (err) return err; @@ -772,6 +776,7 @@ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; + struct f2fs_lock_context lc; pgoff_t free_from; int count = 0, err = 0; struct folio *ifolio; @@ -790,7 +795,7 @@ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock) goto free_partial; if (lock) - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); ifolio = f2fs_get_inode_folio(sbi, inode->i_ino); if (IS_ERR(ifolio)) { @@ -841,7 +846,7 @@ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock) err = f2fs_truncate_inode_blocks(inode, free_from); out: if (lock) - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); free_partial: /* lastly zero out the first data page */ if (!err) @@ -1112,11 +1117,13 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, } if (i_uid_needs_update(idmap, attr, inode) || i_gid_needs_update(idmap, attr, inode)) { - f2fs_lock_op(sbi); + struct f2fs_lock_context lc; + + f2fs_lock_op(sbi, &lc); err = dquot_transfer(idmap, inode, attr); if (err) { set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); return err; } /* @@ -1126,7 +1133,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, i_uid_update(idmap, attr, inode); i_gid_update(idmap, attr, inode); f2fs_mark_inode_dirty_sync(inode, true); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); } if (attr->ia_valid & ATTR_SIZE) { @@ -1210,15 +1217,16 @@ static int fill_zero(struct inode *inode, pgoff_t index, { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct folio *folio; + struct f2fs_lock_context lc; if (!len) return 0; f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); folio = f2fs_get_new_data_folio(inode, NULL, index, false); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (IS_ERR(folio)) return PTR_ERR(folio); @@ -1301,6 +1309,7 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len) if (pg_start < pg_end) { loff_t blk_start, blk_end; struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_lock_context lc; f2fs_balance_fs(sbi, true); @@ -1312,9 +1321,9 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len) truncate_pagecache_range(inode, blk_start, blk_end - 1); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); ret = f2fs_truncate_hole(inode, pg_start, pg_end); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); filemap_invalidate_unlock(inode->i_mapping); f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); @@ -1546,6 +1555,7 @@ static int __exchange_data_block(struct inode *src_inode, static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_lock_context lc; pgoff_t nrpages = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); pgoff_t start = offset >> PAGE_SHIFT; pgoff_t end = (offset + len) >> PAGE_SHIFT; @@ -1559,11 +1569,11 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) f2fs_zero_post_eof_page(inode, offset + len, false); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); f2fs_drop_extent_tree(inode); truncate_pagecache(inode, offset); ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); filemap_invalidate_unlock(inode->i_mapping); f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); @@ -1711,6 +1721,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, for (index = pg_start; index < pg_end;) { struct dnode_of_data dn; + struct f2fs_lock_context lc; unsigned int end_offset; pgoff_t end; @@ -1721,12 +1732,12 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, (loff_t)index << PAGE_SHIFT, ((loff_t)pg_end << PAGE_SHIFT) - 1); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); set_new_dnode(&dn, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE); if (ret) { - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); filemap_invalidate_unlock(mapping); f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); goto out; @@ -1738,7 +1749,7 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, ret = f2fs_do_zero_range(&dn, index, end); f2fs_put_dnode(&dn); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); filemap_invalidate_unlock(mapping); f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); @@ -1821,17 +1832,19 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) truncate_pagecache(inode, offset); while (!ret && idx > pg_start) { + struct f2fs_lock_context lc; + nr = idx - pg_start; if (nr > delta) nr = delta; idx -= nr; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); f2fs_drop_extent_tree(inode); ret = __exchange_data_block(inode, inode, idx, idx + delta, nr, false); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); } filemap_invalidate_unlock(mapping); f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); @@ -1913,7 +1926,7 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset, if (has_not_enough_free_secs(sbi, 0, sbi->reserved_pin_section)) { - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); stat_inc_gc_call_count(sbi, FOREGROUND); err = f2fs_gc(sbi, &gc_control); if (err && err != -ENODATA) { @@ -2448,7 +2461,7 @@ int f2fs_do_shutdown(struct f2fs_sb_info *sbi, unsigned int flag, f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); break; case F2FS_GOING_DOWN_METAFLUSH: - f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO); + f2fs_sync_meta_pages(sbi, LONG_MAX, FS_META_IO); f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN); break; case F2FS_GOING_DOWN_NEED_FSCK: @@ -2764,12 +2777,13 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg) return ret; if (!sync) { - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, + &gc_control.lc)) { ret = -EBUSY; goto out; } } else { - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); } gc_control.init_gc_type = sync ? FG_GC : BG_GC; @@ -2809,12 +2823,12 @@ static int __f2fs_ioc_gc_range(struct file *filp, struct f2fs_gc_range *range) do_more: if (!range->sync) { - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &gc_control.lc)) { ret = -EBUSY; goto out; } } else { - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); } gc_control.victim_segno = GET_SEGNO(sbi, range->start); @@ -3087,6 +3101,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, struct inode *src = file_inode(file_in); struct inode *dst = file_inode(file_out); struct f2fs_sb_info *sbi = F2FS_I_SB(src); + struct f2fs_lock_context lc; size_t olen = len, dst_max_i_size = 0; size_t dst_osize; int ret; @@ -3182,7 +3197,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, goto out_src; } - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); ret = __exchange_data_block(src, dst, F2FS_BYTES_TO_BLK(pos_in), F2FS_BYTES_TO_BLK(pos_out), F2FS_BYTES_TO_BLK(len), false); @@ -3193,7 +3208,7 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, else if (dst_osize != dst->i_size) f2fs_i_size_write(dst, dst_osize); } - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (src != dst) f2fs_up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]); @@ -3304,7 +3319,7 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg) end_segno = min(start_segno + range.segments, dev_end_segno); while (start_segno < end_segno) { - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &gc_control.lc)) { ret = -EBUSY; goto out; } @@ -3361,6 +3376,7 @@ static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode *ri = NULL; + struct f2fs_lock_context lc; kprojid_t kprojid; int err; @@ -3391,7 +3407,7 @@ static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) if (err) return err; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_transfer_project_quota(inode, kprojid); if (err) goto out_unlock; @@ -3400,7 +3416,7 @@ static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) inode_set_ctime_current(inode); f2fs_mark_inode_dirty_sync(inode, true); out_unlock: - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); return err; } #else @@ -3833,6 +3849,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_lock_context lc; pgoff_t page_idx = 0, last_idx; unsigned int released_blocks = 0; int ret; @@ -3887,12 +3904,12 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) struct dnode_of_data dn; pgoff_t end_offset, count; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); set_new_dnode(&dn, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE); if (ret) { - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (ret == -ENOENT) { page_idx = f2fs_get_next_page_offset(&dn, page_idx); @@ -3910,7 +3927,7 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) f2fs_put_dnode(&dn); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (ret < 0) break; @@ -4063,14 +4080,15 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) while (page_idx < last_idx) { struct dnode_of_data dn; + struct f2fs_lock_context lc; pgoff_t end_offset, count; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); set_new_dnode(&dn, inode, NULL, NULL, 0); ret = f2fs_get_dnode_of_data(&dn, page_idx, LOOKUP_NODE); if (ret) { - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (ret == -ENOENT) { page_idx = f2fs_get_next_page_offset(&dn, page_idx); @@ -4088,7 +4106,7 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) f2fs_put_dnode(&dn); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (ret < 0) break; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 384fa7e2085b..f46b2673d31f 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -102,21 +102,22 @@ static int gc_thread_func(void *data) if (sbi->gc_mode == GC_URGENT_HIGH || sbi->gc_mode == GC_URGENT_MID) { wait_ms = gc_th->urgent_sleep_time; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); goto do_gc; } if (foreground) { - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); goto do_gc; - } else if (!f2fs_down_write_trylock(&sbi->gc_lock)) { + } else if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, + &gc_control.lc)) { stat_other_skip_bggc_count(sbi); goto next; } if (!is_idle(sbi, GC_TIME)) { increase_sleep_time(gc_th, &wait_ms); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &gc_control.lc); stat_io_skip_bggc_count(sbi); goto next; } @@ -125,7 +126,8 @@ static int gc_thread_func(void *data) if (has_enough_free_blocks(sbi, gc_th->no_zoned_gc_percent)) { wait_ms = gc_th->no_gc_sleep_time; - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, + &gc_control.lc); goto next; } if (wait_ms == gc_th->no_gc_sleep_time) @@ -232,6 +234,8 @@ int f2fs_start_gc_thread(struct f2fs_sb_info *sbi) return err; } + set_user_nice(gc_th->f2fs_gc_task, + PRIO_TO_NICE(sbi->critical_task_priority)); return 0; } @@ -1031,7 +1035,8 @@ static int check_valid_map(struct f2fs_sb_info *sbi, * ignore that. */ static int gc_node_segment(struct f2fs_sb_info *sbi, - struct f2fs_summary *sum, unsigned int segno, int gc_type) + struct f2fs_summary *sum, unsigned int segno, int gc_type, + struct blk_plug *plug) { struct f2fs_summary *entry; block_t start_addr; @@ -1100,8 +1105,11 @@ static int gc_node_segment(struct f2fs_sb_info *sbi, stat_inc_node_blk_count(sbi, 1, gc_type); } - if (++phase < 3) + if (++phase < 3) { + blk_finish_plug(plug); + blk_start_plug(plug); goto next_step; + } if (fggc) atomic_dec(&sbi->wb_sync_req[NODE]); @@ -1453,7 +1461,11 @@ static int move_data_block(struct inode *inode, block_t bidx, put_out: f2fs_put_dnode(&dn); out: - f2fs_folio_put(folio, true); + if (!folio_test_uptodate(folio)) + __folio_set_dropbehind(folio); + folio_unlock(folio); + folio_end_dropbehind(folio); + folio_put(folio); return err; } @@ -1535,7 +1547,7 @@ static int move_data_page(struct inode *inode, block_t bidx, int gc_type, */ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, struct gc_inode_list *gc_list, unsigned int segno, int gc_type, - bool force_migrate) + bool force_migrate, struct blk_plug *plug) { struct super_block *sb = sbi->sb; struct f2fs_summary *entry; @@ -1703,8 +1715,11 @@ static int gc_data_segment(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } } - if (++phase < 5) + if (++phase < 5) { + blk_finish_plug(plug); + blk_start_plug(plug); goto next_step; + } return submitted; } @@ -1769,8 +1784,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, sanity_check_seg_type(sbi, get_seg_entry(sbi, segno)->type); - segno = rounddown(segno, SUMS_PER_BLOCK); - sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, SUMS_PER_BLOCK); + segno = rounddown(segno, sbi->sums_per_block); + sum_blk_cnt = DIV_ROUND_UP(end_segno - segno, sbi->sums_per_block); /* readahead multi ssa blocks those have contiguous address */ if (__is_large_section(sbi)) f2fs_ra_meta_pages(sbi, GET_SUM_BLOCK(sbi, segno), @@ -1780,17 +1795,17 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, while (segno < end_segno) { struct folio *sum_folio = f2fs_get_sum_folio(sbi, segno); - segno += SUMS_PER_BLOCK; + segno += sbi->sums_per_block; if (IS_ERR(sum_folio)) { int err = PTR_ERR(sum_folio); - end_segno = segno - SUMS_PER_BLOCK; - segno = rounddown(start_segno, SUMS_PER_BLOCK); + end_segno = segno - sbi->sums_per_block; + segno = rounddown(start_segno, sbi->sums_per_block); while (segno < end_segno) { sum_folio = filemap_get_folio(META_MAPPING(sbi), GET_SUM_BLOCK(sbi, segno)); folio_put_refs(sum_folio, 2); - segno += SUMS_PER_BLOCK; + segno += sbi->sums_per_block; } return err; } @@ -1806,8 +1821,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, /* find segment summary of victim */ struct folio *sum_folio = filemap_get_folio(META_MAPPING(sbi), GET_SUM_BLOCK(sbi, segno)); - unsigned int block_end_segno = rounddown(segno, SUMS_PER_BLOCK) - + SUMS_PER_BLOCK; + unsigned int block_end_segno = rounddown(segno, sbi->sums_per_block) + + sbi->sums_per_block; if (block_end_segno > end_segno) block_end_segno = end_segno; @@ -1833,12 +1848,13 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, migrated >= sbi->migration_granularity) continue; - sum = SUM_BLK_PAGE_ADDR(sum_folio, cur_segno); - if (type != GET_SUM_TYPE((&sum->footer))) { + sum = SUM_BLK_PAGE_ADDR(sbi, sum_folio, cur_segno); + if (type != GET_SUM_TYPE(sum_footer(sbi, sum))) { f2fs_err(sbi, "Inconsistent segment (%u) type " "[%d, %d] in SSA and SIT", cur_segno, type, - GET_SUM_TYPE((&sum->footer))); + GET_SUM_TYPE( + sum_footer(sbi, sum))); f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_CORRUPTED_SUMMARY); continue; @@ -1853,11 +1869,11 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi, */ if (type == SUM_TYPE_NODE) submitted += gc_node_segment(sbi, sum->entries, - cur_segno, gc_type); + cur_segno, gc_type, &plug); else submitted += gc_data_segment(sbi, sum->entries, gc_list, cur_segno, - gc_type, force_migrate); + gc_type, force_migrate, &plug); stat_inc_gc_seg_count(sbi, data_type, gc_type); sbi->gc_reclaimed_segs[sbi->gc_mode]++; @@ -2000,7 +2016,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control) goto stop; } - __get_secs_required(sbi, NULL, &upper_secs, NULL); + upper_secs = __get_secs_required(sbi); /* * Write checkpoint to reclaim prefree segments. @@ -2035,7 +2051,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, struct f2fs_gc_control *gc_control) reserved_segments(sbi), prefree_segments(sbi)); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &gc_control->lc); put_gc_inode(&gc_list); @@ -2096,6 +2112,7 @@ int f2fs_gc_range(struct f2fs_sb_info *sbi, if (unlikely(f2fs_cp_error(sbi))) return -EIO; + stat_inc_gc_call_count(sbi, FOREGROUND); for (segno = start_seg; segno <= end_seg; segno += SEGS_PER_SEC(sbi)) { struct gc_inode_list gc_list = { .ilist = LIST_HEAD_INIT(gc_list.ilist), @@ -2251,6 +2268,9 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) struct f2fs_sb_info *sbi = F2FS_I_SB(file_inode(filp)); __u64 old_block_count, shrunk_blocks; struct cp_control cpc = { CP_RESIZE, 0, 0, 0 }; + struct f2fs_lock_context lc; + struct f2fs_lock_context glc; + struct f2fs_lock_context clc; unsigned int secs; int err = 0; __u32 rem; @@ -2294,13 +2314,13 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi)); /* stop other GC */ - if (!f2fs_down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock_trace(&sbi->gc_lock, &glc)) { err = -EAGAIN; goto out_drop_write; } /* stop CP to protect MAIN_SEC in free_segment_range */ - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); spin_lock(&sbi->stat_lock); if (shrunk_blocks + valid_user_blocks(sbi) + @@ -2315,8 +2335,8 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) err = free_segment_range(sbi, secs, true); out_unlock: - f2fs_unlock_op(sbi); - f2fs_up_write(&sbi->gc_lock); + f2fs_unlock_op(sbi, &lc); + f2fs_up_write_trace(&sbi->gc_lock, &glc); out_drop_write: mnt_drop_write_file(filp); if (err) @@ -2333,8 +2353,8 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) return -EROFS; } - f2fs_down_write(&sbi->gc_lock); - f2fs_down_write(&sbi->cp_global_sem); + f2fs_down_write_trace(&sbi->gc_lock, &glc); + f2fs_down_write_trace(&sbi->cp_global_sem, &clc); spin_lock(&sbi->stat_lock); if (shrunk_blocks + valid_user_blocks(sbi) + @@ -2382,8 +2402,8 @@ int f2fs_resize_fs(struct file *filp, __u64 block_count) spin_unlock(&sbi->stat_lock); } out_err: - f2fs_up_write(&sbi->cp_global_sem); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->cp_global_sem, &clc); + f2fs_up_write_trace(&sbi->gc_lock, &glc); thaw_super(sbi->sb, FREEZE_HOLDER_KERNEL, NULL); return err; } diff --git a/fs/f2fs/hash.c b/fs/f2fs/hash.c index 049ce50cec9b..14082fe5e6b2 100644 --- a/fs/f2fs/hash.c +++ b/fs/f2fs/hash.c @@ -100,7 +100,7 @@ void f2fs_hash_filename(const struct inode *dir, struct f2fs_filename *fname) WARN_ON_ONCE(!name); - if (is_dot_dotdot(name, len)) { + if (name_is_dot_dotdot(name, len)) { fname->hash = 0; return; } diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index e5c6a08b7e4f..0a1052d5ee62 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -218,6 +218,7 @@ int f2fs_convert_inline_inode(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct dnode_of_data dn; + struct f2fs_lock_context lc; struct folio *ifolio, *folio; int err = 0; @@ -235,7 +236,7 @@ int f2fs_convert_inline_inode(struct inode *inode) if (IS_ERR(folio)) return PTR_ERR(folio); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); ifolio = f2fs_get_inode_folio(sbi, inode->i_ino); if (IS_ERR(ifolio)) { @@ -250,7 +251,7 @@ int f2fs_convert_inline_inode(struct inode *inode) f2fs_put_dnode(&dn); out: - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_folio_put(folio, true); @@ -597,13 +598,14 @@ int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry) struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct folio *ifolio; struct f2fs_filename fname; + struct f2fs_lock_context lc; void *inline_dentry = NULL; int err = 0; if (!f2fs_has_inline_dentry(dir)) return 0; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_setup_filename(dir, &dentry->d_name, 0, &fname); if (err) @@ -628,7 +630,7 @@ int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry) out_fname: f2fs_free_filename(&fname); out: - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); return err; } diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index ee332b994348..e0f850b3f0c3 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -597,6 +597,8 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) if (ret) goto bad_inode; make_now: + f2fs_set_inode_flags(inode); + if (ino == F2FS_NODE_INO(sbi)) { inode->i_mapping->a_ops = &f2fs_node_aops; mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); @@ -618,6 +620,9 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) inode->i_op = &f2fs_file_inode_operations; inode->i_fop = &f2fs_file_operations; inode->i_mapping->a_ops = &f2fs_dblock_aops; + if (IS_IMMUTABLE(inode) && !f2fs_compressed_file(inode) && + !f2fs_quota_file(sbi, inode->i_ino)) + mapping_set_folio_min_order(inode->i_mapping, 0); } else if (S_ISDIR(inode->i_mode)) { inode->i_op = &f2fs_dir_inode_operations; inode->i_fop = &f2fs_dir_operations; @@ -638,7 +643,6 @@ struct inode *f2fs_iget(struct super_block *sb, unsigned long ino) ret = -EIO; goto bad_inode; } - f2fs_set_inode_flags(inode); unlock_new_inode(inode); trace_f2fs_iget(inode); @@ -906,9 +910,11 @@ void f2fs_evict_inode(struct inode *inode) err = -EIO; if (!err) { - f2fs_lock_op(sbi); + struct f2fs_lock_context lc; + + f2fs_lock_op(sbi, &lc); err = f2fs_remove_inode_page(inode); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (err == -ENOENT) { err = 0; @@ -1004,7 +1010,7 @@ void f2fs_evict_inode(struct inode *inode) } /* caller should call f2fs_lock_op() */ -void f2fs_handle_failed_inode(struct inode *inode) +void f2fs_handle_failed_inode(struct inode *inode, struct f2fs_lock_context *lc) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct node_info ni; @@ -1053,7 +1059,7 @@ void f2fs_handle_failed_inode(struct inode *inode) } out: - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, lc); /* iput will drop the inode object */ iput(inode); diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 043d20516a21..e360f08a9586 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -354,6 +354,7 @@ static int f2fs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool excl) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; struct inode *inode; nid_t ino = 0; int err; @@ -376,11 +377,11 @@ static int f2fs_create(struct mnt_idmap *idmap, struct inode *dir, inode->i_mapping->a_ops = &f2fs_dblock_aops; ino = inode->i_ino; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(dentry, inode); if (err) goto out; - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_alloc_nid_done(sbi, ino); @@ -392,7 +393,7 @@ static int f2fs_create(struct mnt_idmap *idmap, struct inode *dir, f2fs_balance_fs(sbi, true); return 0; out: - f2fs_handle_failed_inode(inode); + f2fs_handle_failed_inode(inode, &lc); return err; } @@ -401,6 +402,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, { struct inode *inode = d_inode(old_dentry); struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; int err; if (unlikely(f2fs_cp_error(sbi))) @@ -427,11 +429,11 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, ihold(inode); set_inode_flag(inode, FI_INC_LINK); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(dentry, inode); if (err) goto out; - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); d_instantiate(dentry, inode); @@ -441,7 +443,7 @@ static int f2fs_link(struct dentry *old_dentry, struct inode *dir, out: clear_inode_flag(inode, FI_INC_LINK); iput(inode); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); return err; } @@ -545,6 +547,7 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) struct f2fs_sb_info *sbi = F2FS_I_SB(dir); struct inode *inode = d_inode(dentry); struct f2fs_dir_entry *de; + struct f2fs_lock_context lc; struct folio *folio; int err; @@ -581,15 +584,15 @@ static int f2fs_unlink(struct inode *dir, struct dentry *dentry) f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_acquire_orphan_inode(sbi); if (err) { - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_folio_put(folio, false); goto out; } f2fs_delete_entry(de, folio, dir, inode); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); /* VFS negative dentries are incompatible with Encoding and * Case-insensitiveness. Eventually we'll want avoid @@ -632,6 +635,7 @@ static int f2fs_symlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, const char *symname) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; struct inode *inode; size_t len = strlen(symname); struct fscrypt_str disk_link; @@ -662,11 +666,11 @@ static int f2fs_symlink(struct mnt_idmap *idmap, struct inode *dir, inode_nohighmem(inode); inode->i_mapping->a_ops = &f2fs_dblock_aops; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(dentry, inode); if (err) goto out_f2fs_handle_failed_inode; - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_alloc_nid_done(sbi, inode->i_ino); err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link); @@ -701,7 +705,7 @@ static int f2fs_symlink(struct mnt_idmap *idmap, struct inode *dir, goto out_free_encrypted_link; out_f2fs_handle_failed_inode: - f2fs_handle_failed_inode(inode); + f2fs_handle_failed_inode(inode, &lc); out_free_encrypted_link: if (disk_link.name != (unsigned char *)symname) kfree(disk_link.name); @@ -712,6 +716,7 @@ static struct dentry *f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; struct inode *inode; int err; @@ -732,11 +737,11 @@ static struct dentry *f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir, mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); set_inode_flag(inode, FI_INC_LINK); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(dentry, inode); if (err) goto out_fail; - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_alloc_nid_done(sbi, inode->i_ino); @@ -750,7 +755,7 @@ static struct dentry *f2fs_mkdir(struct mnt_idmap *idmap, struct inode *dir, out_fail: clear_inode_flag(inode, FI_INC_LINK); - f2fs_handle_failed_inode(inode); + f2fs_handle_failed_inode(inode, &lc); return ERR_PTR(err); } @@ -767,6 +772,7 @@ static int f2fs_mknod(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t rdev) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; struct inode *inode; int err = 0; @@ -786,11 +792,11 @@ static int f2fs_mknod(struct mnt_idmap *idmap, struct inode *dir, init_special_inode(inode, inode->i_mode, rdev); inode->i_op = &f2fs_special_inode_operations; - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(dentry, inode); if (err) goto out; - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_alloc_nid_done(sbi, inode->i_ino); @@ -802,7 +808,7 @@ static int f2fs_mknod(struct mnt_idmap *idmap, struct inode *dir, f2fs_balance_fs(sbi, true); return 0; out: - f2fs_handle_failed_inode(inode); + f2fs_handle_failed_inode(inode, &lc); return err; } @@ -811,6 +817,7 @@ static int __f2fs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, struct inode **new_inode, struct f2fs_filename *fname) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); + struct f2fs_lock_context lc; struct inode *inode; int err; @@ -831,7 +838,7 @@ static int __f2fs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, inode->i_mapping->a_ops = &f2fs_dblock_aops; } - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_acquire_orphan_inode(sbi); if (err) goto out; @@ -860,7 +867,7 @@ static int __f2fs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, f2fs_i_links_write(inode, false); } /* link_count was changed by d_tmpfile as well. */ - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); unlock_new_inode(inode); if (new_inode) @@ -872,7 +879,7 @@ static int __f2fs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, release_out: f2fs_release_orphan_inode(sbi); out: - f2fs_handle_failed_inode(inode); + f2fs_handle_failed_inode(inode, &lc); return err; } @@ -920,6 +927,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct f2fs_dir_entry *old_dir_entry = NULL; struct f2fs_dir_entry *old_entry; struct f2fs_dir_entry *new_entry; + struct f2fs_lock_context lc; bool old_is_dir = S_ISDIR(old_inode->i_mode); int err; @@ -1008,7 +1016,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_acquire_orphan_inode(sbi); if (err) @@ -1031,11 +1039,11 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, } else { f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_add_link(new_dentry, old_inode); if (err) { - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); goto out_dir; } @@ -1084,7 +1092,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, TRANS_DIR_INO); } - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) f2fs_sync_fs(sbi->sb, 1); @@ -1093,7 +1101,7 @@ static int f2fs_rename(struct mnt_idmap *idmap, struct inode *old_dir, return 0; put_out_dir: - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_folio_put(new_folio, false); out_dir: if (old_dir_entry) @@ -1115,6 +1123,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, struct folio *old_folio, *new_folio; struct f2fs_dir_entry *old_dir_entry = NULL, *new_dir_entry = NULL; struct f2fs_dir_entry *old_entry, *new_entry; + struct f2fs_lock_context lc; int old_nlink = 0, new_nlink = 0; int err; @@ -1194,7 +1203,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); /* update ".." directory entry info of old dentry */ if (old_dir_entry) @@ -1247,7 +1256,7 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO); } - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) f2fs_sync_fs(sbi->sb, 1); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 482a362f2625..74992fd9c9b6 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -606,7 +606,7 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, goto retry; } - i = f2fs_lookup_journal_in_cursum(journal, NAT_JOURNAL, nid, 0); + i = f2fs_lookup_journal_in_cursum(sbi, journal, NAT_JOURNAL, nid, 0); if (i >= 0) { ne = nat_in_journal(journal, i); node_info_from_raw_nat(ni, &ne); @@ -643,6 +643,17 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, return -EFSCORRUPTED; } + if (unlikely(f2fs_quota_file(sbi, ni->nid) && + !__is_valid_data_blkaddr(ni->blk_addr))) { + set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_err_ratelimited(sbi, + "f2fs_get_node_info of %pS: inconsistent nat entry from qf_ino, " + "ino:%u, nid:%u, blkaddr:%u, ver:%u, flag:%u", + __builtin_return_address(0), + ni->ino, ni->nid, ni->blk_addr, ni->version, ni->flag); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_NAT); + } + /* cache nat entry */ if (need_cache) cache_nat_entry(sbi, nid, &ne); @@ -1500,24 +1511,33 @@ void f2fs_ra_node_page(struct f2fs_sb_info *sbi, nid_t nid) f2fs_folio_put(afolio, err ? true : false); } -static int sanity_check_node_footer(struct f2fs_sb_info *sbi, +int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi, struct folio *folio, pgoff_t nid, - enum node_type ntype) + enum node_type ntype, bool in_irq) { + bool is_inode, is_xnode; + if (unlikely(nid != nid_of_node(folio))) goto out_err; + is_inode = IS_INODE(folio); + is_xnode = f2fs_has_xattr_block(ofs_of_node(folio)); + switch (ntype) { + case NODE_TYPE_REGULAR: + if (is_inode && is_xnode) + goto out_err; + break; case NODE_TYPE_INODE: - if (!IS_INODE(folio)) + if (!is_inode || is_xnode) goto out_err; break; case NODE_TYPE_XATTR: - if (!f2fs_has_xattr_block(ofs_of_node(folio))) + if (is_inode || !is_xnode) goto out_err; break; case NODE_TYPE_NON_INODE: - if (IS_INODE(folio)) + if (is_inode) goto out_err; break; default: @@ -1527,12 +1547,13 @@ static int sanity_check_node_footer(struct f2fs_sb_info *sbi, goto out_err; return 0; out_err: - f2fs_warn(sbi, "inconsistent node block, node_type:%d, nid:%lu, " - "node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]", - ntype, nid, nid_of_node(folio), ino_of_node(folio), - ofs_of_node(folio), cpver_of_node(folio), - next_blkaddr_of_node(folio)); set_sbi_flag(sbi, SBI_NEED_FSCK); + f2fs_warn_ratelimited(sbi, "inconsistent node block, node_type:%d, nid:%lu, " + "node_footer[nid:%u,ino:%u,ofs:%u,cpver:%llu,blkaddr:%u]", + ntype, nid, nid_of_node(folio), ino_of_node(folio), + ofs_of_node(folio), cpver_of_node(folio), + next_blkaddr_of_node(folio)); + f2fs_handle_error(sbi, ERROR_INCONSISTENT_FOOTER); return -EFSCORRUPTED; } @@ -1578,7 +1599,7 @@ static struct folio *__get_node_folio(struct f2fs_sb_info *sbi, pgoff_t nid, goto out_err; } page_hit: - err = sanity_check_node_footer(sbi, folio, nid, ntype); + err = f2fs_sanity_check_node_footer(sbi, folio, nid, ntype, false); if (!err) return folio; out_err: @@ -1727,6 +1748,7 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted .io_type = io_type, .io_wbc = wbc, }; + struct f2fs_lock_context lc; unsigned int seq; trace_f2fs_writepage(folio, NODE); @@ -1751,18 +1773,23 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted /* get old block addr of this node page */ nid = nid_of_node(folio); - f2fs_bug_on(sbi, folio->index != nid); + + if (f2fs_sanity_check_node_footer(sbi, folio, nid, + NODE_TYPE_REGULAR, false)) { + f2fs_handle_critical_error(sbi, STOP_CP_REASON_CORRUPTED_NID); + goto redirty_out; + } if (f2fs_get_node_info(sbi, nid, &ni, !do_balance)) goto redirty_out; - f2fs_down_read(&sbi->node_write); + f2fs_down_read_trace(&sbi->node_write, &lc); /* This page is already truncated */ if (unlikely(ni.blk_addr == NULL_ADDR)) { folio_clear_uptodate(folio); dec_page_count(sbi, F2FS_DIRTY_NODES); - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); folio_unlock(folio); return true; } @@ -1770,12 +1797,17 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted if (__is_valid_data_blkaddr(ni.blk_addr) && !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC_ENHANCE)) { - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); goto redirty_out; } - if (atomic && !test_opt(sbi, NOBARRIER)) - fio.op_flags |= REQ_PREFLUSH | REQ_FUA; + if (atomic) { + if (!test_opt(sbi, NOBARRIER)) + fio.op_flags |= REQ_PREFLUSH | REQ_FUA; + if (IS_INODE(folio)) + set_dentry_mark(folio, + f2fs_need_dentry_mark(sbi, ino_of_node(folio))); + } /* should add to global list before clearing PAGECACHE status */ if (f2fs_in_warm_node_list(sbi, folio)) { @@ -1790,7 +1822,7 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted f2fs_do_write_node_page(nid, &fio); set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(folio)); dec_page_count(sbi, F2FS_DIRTY_NODES); - f2fs_up_read(&sbi->node_write); + f2fs_up_read_trace(&sbi->node_write, &lc); folio_unlock(folio); @@ -1916,8 +1948,9 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, if (is_inode_flag_set(inode, FI_DIRTY_INODE)) f2fs_update_inode(inode, folio); - set_dentry_mark(folio, - f2fs_need_dentry_mark(sbi, ino)); + if (!atomic) + set_dentry_mark(folio, + f2fs_need_dentry_mark(sbi, ino)); } /* may be written by other thread */ if (!folio_test_dirty(folio)) @@ -2937,7 +2970,7 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi, /* scan the node segment */ last_offset = BLKS_PER_SEG(sbi); addr = START_BLOCK(sbi, segno); - sum_entry = &sum->entries[0]; + sum_entry = sum_entries(sum); for (i = 0; i < last_offset; i += nrpages, addr += nrpages) { nrpages = bio_max_segs(last_offset - i); @@ -3078,7 +3111,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi, * #2, flush nat entries to nat page. */ if (enabled_nat_bits(sbi, cpc) || - !__has_cursum_space(journal, set->entry_cnt, NAT_JOURNAL)) + !__has_cursum_space(sbi, journal, set->entry_cnt, NAT_JOURNAL)) to_journal = false; if (to_journal) { @@ -3101,7 +3134,7 @@ static int __flush_nat_entry_set(struct f2fs_sb_info *sbi, f2fs_bug_on(sbi, nat_get_blkaddr(ne) == NEW_ADDR); if (to_journal) { - offset = f2fs_lookup_journal_in_cursum(journal, + offset = f2fs_lookup_journal_in_cursum(sbi, journal, NAT_JOURNAL, nid, 1); f2fs_bug_on(sbi, offset < 0); raw_ne = &nat_in_journal(journal, offset); @@ -3146,7 +3179,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) struct f2fs_journal *journal = curseg->journal; struct nat_entry_set *setvec[NAT_VEC_SIZE]; struct nat_entry_set *set, *tmp; - unsigned int found; + unsigned int found, entry_count = 0; nid_t set_idx = 0; LIST_HEAD(sets); int err = 0; @@ -3172,7 +3205,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) * into nat entry set. */ if (enabled_nat_bits(sbi, cpc) || - !__has_cursum_space(journal, + !__has_cursum_space(sbi, journal, nm_i->nat_cnt[DIRTY_NAT], NAT_JOURNAL)) remove_nats_in_journal(sbi); @@ -3183,9 +3216,21 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) set_idx = setvec[found - 1]->set + 1; for (idx = 0; idx < found; idx++) __adjust_nat_entry_set(setvec[idx], &sets, - MAX_NAT_JENTRIES(journal)); + MAX_NAT_JENTRIES(sbi, journal)); } + /* + * Readahead the current NAT block to prevent read requests from + * being issued and waited on one by one. + */ + list_for_each_entry(set, &sets, set_list) { + entry_count += set->entry_cnt; + if (!enabled_nat_bits(sbi, cpc) && + __has_cursum_space(sbi, journal, + entry_count, NAT_JOURNAL)) + continue; + f2fs_ra_meta_pages(sbi, set->set, 1, META_NAT, true); + } /* flush dirty nats in nat entry set */ list_for_each_entry_safe(set, tmp, &sets, set_list) { err = __flush_nat_entry_set(sbi, set, cpc); diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 9cb8dcf8d417..824ac9f0e6e4 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -52,14 +52,6 @@ enum { IS_PREALLOC, /* nat entry is preallocated */ }; -/* For node type in __get_node_folio() */ -enum node_type { - NODE_TYPE_REGULAR, - NODE_TYPE_INODE, - NODE_TYPE_XATTR, - NODE_TYPE_NON_INODE, -}; - /* * For node information */ diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index c3415ebb9f50..a26071f2b0bc 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -514,7 +514,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, struct curseg_info *curseg = CURSEG_I(sbi, i); if (curseg->segno == segno) { - sum = curseg->sum_blk->entries[blkoff]; + sum = sum_entries(curseg->sum_blk)[blkoff]; goto got_it; } } @@ -522,8 +522,8 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, sum_folio = f2fs_get_sum_folio(sbi, segno); if (IS_ERR(sum_folio)) return PTR_ERR(sum_folio); - sum_node = SUM_BLK_PAGE_ADDR(sum_folio, segno); - sum = sum_node->entries[blkoff]; + sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, segno); + sum = sum_entries(sum_node)[blkoff]; f2fs_folio_put(sum_folio, true); got_it: /* Use the locked dnode page and inode */ @@ -875,6 +875,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) LIST_HEAD(inode_list); LIST_HEAD(tmp_inode_list); LIST_HEAD(dir_list); + struct f2fs_lock_context lc; int err; int ret = 0; unsigned long s_flags = sbi->sb->s_flags; @@ -888,7 +889,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) f2fs_info(sbi, "recover fsync data on readonly fs"); /* prevent checkpoint */ - f2fs_down_write(&sbi->cp_global_sem); + f2fs_down_write_trace(&sbi->cp_global_sem, &lc); /* step #1: find fsynced inode numbers */ err = find_fsync_dnodes(sbi, &inode_list, check_only, &new_inode); @@ -932,7 +933,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) if (!err) clear_sbi_flag(sbi, SBI_POR_DOING); - f2fs_up_write(&sbi->cp_global_sem); + f2fs_up_write_trace(&sbi->cp_global_sem, &lc); /* let's drop all the directory inodes for clean checkpoint */ destroy_fsync_dnodes(&dir_list, err); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index c26424f47686..6a97fe76712b 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -371,8 +371,8 @@ static int __f2fs_commit_atomic_write(struct inode *inode) } out: - if (time_to_inject(sbi, FAULT_TIMEOUT)) - f2fs_io_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT); + if (time_to_inject(sbi, FAULT_ATOMIC_TIMEOUT)) + f2fs_schedule_timeout_killable(DEFAULT_FAULT_TIMEOUT, true); if (ret) { sbi->revoked_atomic_block += fi->atomic_write_cnt; @@ -400,6 +400,7 @@ int f2fs_commit_atomic_write(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_inode_info *fi = F2FS_I(inode); + struct f2fs_lock_context lc; int err; err = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX); @@ -407,11 +408,11 @@ int f2fs_commit_atomic_write(struct inode *inode) return err; f2fs_down_write(&fi->i_gc_rwsem[WRITE]); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = __f2fs_commit_atomic_write(inode); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_up_write(&fi->i_gc_rwsem[WRITE]); return err; @@ -461,7 +462,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need) .should_migrate_blocks = false, .err_gc_skipped = false, .nr_free_secs = 1 }; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); stat_inc_gc_call_count(sbi, FOREGROUND); f2fs_gc(sbi, &gc_control); } @@ -1286,7 +1287,6 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, &(dcc->fstrim_list) : &(dcc->wait_list); blk_opf_t flag = dpolicy->sync ? REQ_SYNC : 0; block_t lstart, start, len, total_len; - int err = 0; if (dc->state != D_PREP) return 0; @@ -1327,7 +1327,7 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, dc->di.len = 0; - while (total_len && *issued < dpolicy->max_requests && !err) { + while (total_len && *issued < dpolicy->max_requests) { struct bio *bio = NULL; unsigned long flags; bool last = true; @@ -1343,17 +1343,6 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, dc->di.len += len; - err = 0; - if (time_to_inject(sbi, FAULT_DISCARD)) { - err = -EIO; - spin_lock_irqsave(&dc->lock, flags); - if (dc->state == D_PARTIAL) - dc->state = D_SUBMIT; - spin_unlock_irqrestore(&dc->lock, flags); - - break; - } - __blkdev_issue_discard(bdev, SECTOR_FROM_BLOCK(start), SECTOR_FROM_BLOCK(len), GFP_NOFS, &bio); f2fs_bug_on(sbi, !bio); @@ -1392,11 +1381,11 @@ static int __submit_discard_cmd(struct f2fs_sb_info *sbi, len = total_len; } - if (!err && len) { + if (len) { dcc->undiscard_blks -= len; __update_discard_tree_range(sbi, bdev, lstart, start, len); } - return err; + return 0; } static void __insert_discard_cmd(struct f2fs_sb_info *sbi, @@ -2685,12 +2674,12 @@ int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra) valid_sum_count += f2fs_curseg_valid_blocks(sbi, i); } - sum_in_page = (PAGE_SIZE - 2 * SUM_JOURNAL_SIZE - + sum_in_page = (sbi->blocksize - 2 * sbi->sum_journal_size - SUM_FOOTER_SIZE) / SUMMARY_SIZE; if (valid_sum_count <= sum_in_page) return 1; else if ((valid_sum_count - sum_in_page) <= - (PAGE_SIZE - SUM_FOOTER_SIZE) / SUMMARY_SIZE) + (sbi->blocksize - SUM_FOOTER_SIZE) / SUMMARY_SIZE) return 2; return 3; } @@ -2710,7 +2699,7 @@ void f2fs_update_meta_page(struct f2fs_sb_info *sbi, { struct folio *folio; - if (SUMS_PER_BLOCK == 1) + if (!f2fs_sb_has_packed_ssa(sbi)) folio = f2fs_grab_meta_folio(sbi, blk_addr); else folio = f2fs_get_meta_folio_retry(sbi, blk_addr); @@ -2728,7 +2717,7 @@ static void write_sum_page(struct f2fs_sb_info *sbi, { struct folio *folio; - if (SUMS_PER_BLOCK == 1) + if (!f2fs_sb_has_packed_ssa(sbi)) return f2fs_update_meta_page(sbi, (void *)sum_blk, GET_SUM_BLOCK(sbi, segno)); @@ -2736,7 +2725,8 @@ static void write_sum_page(struct f2fs_sb_info *sbi, if (IS_ERR(folio)) return; - memcpy(SUM_BLK_PAGE_ADDR(folio, segno), sum_blk, sizeof(*sum_blk)); + memcpy(SUM_BLK_PAGE_ADDR(sbi, folio, segno), sum_blk, + sbi->sum_blocksize); folio_mark_dirty(folio); f2fs_folio_put(folio, true); } @@ -2755,11 +2745,11 @@ static void write_current_sum_page(struct f2fs_sb_info *sbi, mutex_lock(&curseg->curseg_mutex); down_read(&curseg->journal_rwsem); - memcpy(&dst->journal, curseg->journal, SUM_JOURNAL_SIZE); + memcpy(sum_journal(sbi, dst), curseg->journal, sbi->sum_journal_size); up_read(&curseg->journal_rwsem); - memcpy(dst->entries, src->entries, SUM_ENTRY_SIZE); - memcpy(&dst->footer, &src->footer, SUM_FOOTER_SIZE); + memcpy(sum_entries(dst), sum_entries(src), sbi->sum_entry_size); + memcpy(sum_footer(sbi, dst), sum_footer(sbi, src), SUM_FOOTER_SIZE); mutex_unlock(&curseg->curseg_mutex); @@ -2932,7 +2922,7 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) curseg->next_blkoff = 0; curseg->next_segno = NULL_SEGNO; - sum_footer = &(curseg->sum_blk->footer); + sum_footer = sum_footer(sbi, curseg->sum_blk); memset(sum_footer, 0, sizeof(struct summary_footer)); sanity_check_seg_type(sbi, seg_type); @@ -3078,11 +3068,11 @@ static int change_curseg(struct f2fs_sb_info *sbi, int type) sum_folio = f2fs_get_sum_folio(sbi, new_segno); if (IS_ERR(sum_folio)) { /* GC won't be able to use stale summary pages by cp_error */ - memset(curseg->sum_blk, 0, SUM_ENTRY_SIZE); + memset(curseg->sum_blk, 0, sbi->sum_entry_size); return PTR_ERR(sum_folio); } - sum_node = SUM_BLK_PAGE_ADDR(sum_folio, new_segno); - memcpy(curseg->sum_blk, sum_node, SUM_ENTRY_SIZE); + sum_node = SUM_BLK_PAGE_ADDR(sbi, sum_folio, new_segno); + memcpy(curseg->sum_blk, sum_node, sbi->sum_entry_size); f2fs_folio_put(sum_folio, true); return 0; } @@ -3362,19 +3352,20 @@ int f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force) int f2fs_allocate_pinning_section(struct f2fs_sb_info *sbi) { + struct f2fs_lock_context lc; int err; bool gc_required = true; retry: - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); err = f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) { - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); err = f2fs_gc_range(sbi, 0, sbi->first_seq_zone_segno - 1, true, ZONED_PIN_SEC_REQUIRED_COUNT); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); gc_required = false; if (!err) @@ -3494,6 +3485,7 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) block_t start_block, end_block; struct cp_control cpc; struct discard_policy dpolicy; + struct f2fs_lock_context lc; unsigned long long trimmed = 0; int err = 0; bool need_align = f2fs_lfs_mode(sbi) && __is_large_section(sbi); @@ -3526,10 +3518,10 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) if (sbi->discard_blks == 0) goto out; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); stat_inc_cp_call_count(sbi, TOTAL_CALL); err = f2fs_write_checkpoint(sbi, &cpc); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); if (err) goto out; @@ -3814,7 +3806,7 @@ int f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct folio *folio, f2fs_wait_discard_bio(sbi, *new_blkaddr); - curseg->sum_blk->entries[curseg->next_blkoff] = *sum; + sum_entries(curseg->sum_blk)[curseg->next_blkoff] = *sum; if (curseg->alloc_type == SSR) { curseg->next_blkoff = f2fs_find_next_ssr_block(sbi, curseg); } else { @@ -4183,7 +4175,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, } curseg->next_blkoff = GET_BLKOFF_FROM_SEG0(sbi, new_blkaddr); - curseg->sum_blk->entries[curseg->next_blkoff] = *sum; + sum_entries(curseg->sum_blk)[curseg->next_blkoff] = *sum; if (!recover_curseg || recover_newaddr) { if (!from_gc) @@ -4240,7 +4232,7 @@ void f2fs_folio_wait_writeback(struct folio *folio, enum page_type type, struct f2fs_sb_info *sbi = F2FS_F_SB(folio); /* submit cached LFS IO */ - f2fs_submit_merged_write_cond(sbi, NULL, folio, 0, type); + f2fs_submit_merged_write_folio(sbi, folio, type); /* submit cached IPU IO */ f2fs_submit_merged_ipu_write(sbi, NULL, folio); if (ordered) { @@ -4303,12 +4295,12 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) /* Step 1: restore nat cache */ seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); - memcpy(seg_i->journal, kaddr, SUM_JOURNAL_SIZE); + memcpy(seg_i->journal, kaddr, sbi->sum_journal_size); /* Step 2: restore sit cache */ seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA); - memcpy(seg_i->journal, kaddr + SUM_JOURNAL_SIZE, SUM_JOURNAL_SIZE); - offset = 2 * SUM_JOURNAL_SIZE; + memcpy(seg_i->journal, kaddr + sbi->sum_journal_size, sbi->sum_journal_size); + offset = 2 * sbi->sum_journal_size; /* Step 3: restore summary entries */ for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { @@ -4330,9 +4322,9 @@ static int read_compacted_summaries(struct f2fs_sb_info *sbi) struct f2fs_summary *s; s = (struct f2fs_summary *)(kaddr + offset); - seg_i->sum_blk->entries[j] = *s; + sum_entries(seg_i->sum_blk)[j] = *s; offset += SUMMARY_SIZE; - if (offset + SUMMARY_SIZE <= PAGE_SIZE - + if (offset + SUMMARY_SIZE <= sbi->blocksize - SUM_FOOTER_SIZE) continue; @@ -4388,7 +4380,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) if (IS_NODESEG(type)) { if (__exist_node_summaries(sbi)) { - struct f2fs_summary *ns = &sum->entries[0]; + struct f2fs_summary *ns = sum_entries(sum); int i; for (i = 0; i < BLKS_PER_SEG(sbi); i++, ns++) { @@ -4408,11 +4400,13 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) /* update journal info */ down_write(&curseg->journal_rwsem); - memcpy(curseg->journal, &sum->journal, SUM_JOURNAL_SIZE); + memcpy(curseg->journal, sum_journal(sbi, sum), sbi->sum_journal_size); up_write(&curseg->journal_rwsem); - memcpy(curseg->sum_blk->entries, sum->entries, SUM_ENTRY_SIZE); - memcpy(&curseg->sum_blk->footer, &sum->footer, SUM_FOOTER_SIZE); + memcpy(sum_entries(curseg->sum_blk), sum_entries(sum), + sbi->sum_entry_size); + memcpy(sum_footer(sbi, curseg->sum_blk), sum_footer(sbi, sum), + SUM_FOOTER_SIZE); curseg->next_segno = segno; reset_curseg(sbi, type, 0); curseg->alloc_type = ckpt->alloc_type[type]; @@ -4456,8 +4450,8 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) } /* sanity check for summary blocks */ - if (nats_in_cursum(nat_j) > NAT_JOURNAL_ENTRIES || - sits_in_cursum(sit_j) > SIT_JOURNAL_ENTRIES) { + if (nats_in_cursum(nat_j) > sbi->nat_journal_entries || + sits_in_cursum(sit_j) > sbi->sit_journal_entries) { f2fs_err(sbi, "invalid journal entries nats %u sits %u", nats_in_cursum(nat_j), sits_in_cursum(sit_j)); return -EINVAL; @@ -4481,13 +4475,13 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) /* Step 1: write nat cache */ seg_i = CURSEG_I(sbi, CURSEG_HOT_DATA); - memcpy(kaddr, seg_i->journal, SUM_JOURNAL_SIZE); - written_size += SUM_JOURNAL_SIZE; + memcpy(kaddr, seg_i->journal, sbi->sum_journal_size); + written_size += sbi->sum_journal_size; /* Step 2: write sit cache */ seg_i = CURSEG_I(sbi, CURSEG_COLD_DATA); - memcpy(kaddr + written_size, seg_i->journal, SUM_JOURNAL_SIZE); - written_size += SUM_JOURNAL_SIZE; + memcpy(kaddr + written_size, seg_i->journal, sbi->sum_journal_size); + written_size += sbi->sum_journal_size; /* Step 3: write summary entries */ for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { @@ -4500,10 +4494,10 @@ static void write_compacted_summaries(struct f2fs_sb_info *sbi, block_t blkaddr) written_size = 0; } summary = (struct f2fs_summary *)(kaddr + written_size); - *summary = seg_i->sum_blk->entries[j]; + *summary = sum_entries(seg_i->sum_blk)[j]; written_size += SUMMARY_SIZE; - if (written_size + SUMMARY_SIZE <= PAGE_SIZE - + if (written_size + SUMMARY_SIZE <= sbi->blocksize - SUM_FOOTER_SIZE) continue; @@ -4545,8 +4539,9 @@ void f2fs_write_node_summaries(struct f2fs_sb_info *sbi, block_t start_blk) write_normal_summaries(sbi, start_blk, CURSEG_HOT_NODE); } -int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, - unsigned int val, int alloc) +int f2fs_lookup_journal_in_cursum(struct f2fs_sb_info *sbi, + struct f2fs_journal *journal, int type, + unsigned int val, int alloc) { int i; @@ -4555,13 +4550,13 @@ int f2fs_lookup_journal_in_cursum(struct f2fs_journal *journal, int type, if (le32_to_cpu(nid_in_journal(journal, i)) == val) return i; } - if (alloc && __has_cursum_space(journal, 1, NAT_JOURNAL)) + if (alloc && __has_cursum_space(sbi, journal, 1, NAT_JOURNAL)) return update_nats_in_cursum(journal, 1); } else if (type == SIT_JOURNAL) { for (i = 0; i < sits_in_cursum(journal); i++) if (le32_to_cpu(segno_in_journal(journal, i)) == val) return i; - if (alloc && __has_cursum_space(journal, 1, SIT_JOURNAL)) + if (alloc && __has_cursum_space(sbi, journal, 1, SIT_JOURNAL)) return update_sits_in_cursum(journal, 1); } return -1; @@ -4709,8 +4704,8 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) * entries, remove all entries from journal and add and account * them in sit entry set. */ - if (!__has_cursum_space(journal, sit_i->dirty_sentries, SIT_JOURNAL) || - !to_journal) + if (!__has_cursum_space(sbi, journal, + sit_i->dirty_sentries, SIT_JOURNAL) || !to_journal) remove_sits_in_journal(sbi); /* @@ -4727,7 +4722,8 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) unsigned int segno = start_segno; if (to_journal && - !__has_cursum_space(journal, ses->entry_cnt, SIT_JOURNAL)) + !__has_cursum_space(sbi, journal, ses->entry_cnt, + SIT_JOURNAL)) to_journal = false; if (to_journal) { @@ -4755,7 +4751,7 @@ void f2fs_flush_sit_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) } if (to_journal) { - offset = f2fs_lookup_journal_in_cursum(journal, + offset = f2fs_lookup_journal_in_cursum(sbi, journal, SIT_JOURNAL, segno, 1); f2fs_bug_on(sbi, offset < 0); segno_in_journal(journal, offset) = @@ -4962,12 +4958,13 @@ static int build_curseg(struct f2fs_sb_info *sbi) for (i = 0; i < NO_CHECK_TYPE; i++) { mutex_init(&array[i].curseg_mutex); - array[i].sum_blk = f2fs_kzalloc(sbi, PAGE_SIZE, GFP_KERNEL); + array[i].sum_blk = f2fs_kzalloc(sbi, sbi->sum_blocksize, + GFP_KERNEL); if (!array[i].sum_blk) return -ENOMEM; init_rwsem(&array[i].journal_rwsem); array[i].journal = f2fs_kzalloc(sbi, - sizeof(struct f2fs_journal), GFP_KERNEL); + sbi->sum_journal_size, GFP_KERNEL); if (!array[i].journal) return -ENOMEM; array[i].seg_type = log_type_to_seg_type(i); diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h index 07dcbcbeb7c6..068845660b0f 100644 --- a/fs/f2fs/segment.h +++ b/fs/f2fs/segment.h @@ -90,12 +90,11 @@ static inline void sanity_check_seg_type(struct f2fs_sb_info *sbi, #define GET_ZONE_FROM_SEG(sbi, segno) \ GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno)) -#define SUMS_PER_BLOCK (F2FS_BLKSIZE / F2FS_SUM_BLKSIZE) #define GET_SUM_BLOCK(sbi, segno) \ - (SM_I(sbi)->ssa_blkaddr + (segno / SUMS_PER_BLOCK)) -#define GET_SUM_BLKOFF(segno) (segno % SUMS_PER_BLOCK) -#define SUM_BLK_PAGE_ADDR(folio, segno) \ - (folio_address(folio) + GET_SUM_BLKOFF(segno) * F2FS_SUM_BLKSIZE) + (SM_I(sbi)->ssa_blkaddr + (segno / (sbi)->sums_per_block)) +#define GET_SUM_BLKOFF(sbi, segno) (segno % (sbi)->sums_per_block) +#define SUM_BLK_PAGE_ADDR(sbi, folio, segno) \ + (folio_address(folio) + GET_SUM_BLKOFF(sbi, segno) * (sbi)->sum_blocksize) #define GET_SUM_TYPE(footer) ((footer)->entry_type) #define SET_SUM_TYPE(footer, type) ((footer)->entry_type = (type)) @@ -621,97 +620,90 @@ static inline unsigned int get_left_section_blocks(struct f2fs_sb_info *sbi, return CAP_BLKS_PER_SEC(sbi) - get_ckpt_valid_blocks(sbi, segno, true); } -static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi, - unsigned int node_blocks, unsigned int data_blocks, - unsigned int dent_blocks) +static inline void get_additional_blocks_required(struct f2fs_sb_info *sbi, + unsigned int *total_node_blocks, unsigned int *total_data_blocks, + unsigned int *total_dent_blocks, bool separate_dent) { - unsigned int segno, left_blocks, blocks; + unsigned int segno, left_blocks; int i; + unsigned int min_free_node_blocks = CAP_BLKS_PER_SEC(sbi); + unsigned int min_free_dent_blocks = CAP_BLKS_PER_SEC(sbi); + unsigned int min_free_data_blocks = CAP_BLKS_PER_SEC(sbi); /* check current data/node sections in the worst case. */ for (i = CURSEG_HOT_DATA; i < NR_PERSISTENT_LOG; i++) { segno = CURSEG_I(sbi, i)->segno; if (unlikely(segno == NULL_SEGNO)) - return false; + return; left_blocks = get_left_section_blocks(sbi, i, segno); - blocks = i <= CURSEG_COLD_DATA ? data_blocks : node_blocks; - if (blocks > left_blocks) - return false; + if (i > CURSEG_COLD_DATA) + min_free_node_blocks = min(min_free_node_blocks, left_blocks); + else if (i == CURSEG_HOT_DATA && separate_dent) + min_free_dent_blocks = left_blocks; + else + min_free_data_blocks = min(min_free_data_blocks, left_blocks); } - /* check current data section for dentry blocks. */ - segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno; - - if (unlikely(segno == NULL_SEGNO)) - return false; - - left_blocks = get_left_section_blocks(sbi, CURSEG_HOT_DATA, segno); - - if (dent_blocks > left_blocks) - return false; - return true; + *total_node_blocks = (*total_node_blocks > min_free_node_blocks) ? + *total_node_blocks - min_free_node_blocks : 0; + *total_dent_blocks = (*total_dent_blocks > min_free_dent_blocks) ? + *total_dent_blocks - min_free_dent_blocks : 0; + *total_data_blocks = (*total_data_blocks > min_free_data_blocks) ? + *total_data_blocks - min_free_data_blocks : 0; } /* - * calculate needed sections for dirty node/dentry and call - * has_curseg_enough_space, please note that, it needs to account - * dirty data as well in lfs mode when checkpoint is disabled. + * call get_additional_blocks_required to calculate dirty blocks + * needing to be placed in free sections, please note that, it + * needs to account dirty data as well in lfs mode when checkpoint + * is disabled. */ -static inline void __get_secs_required(struct f2fs_sb_info *sbi, - unsigned int *lower_p, unsigned int *upper_p, bool *curseg_p) +static inline int __get_secs_required(struct f2fs_sb_info *sbi) { unsigned int total_node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) + get_pages(sbi, F2FS_DIRTY_DENTS) + get_pages(sbi, F2FS_DIRTY_IMETA); unsigned int total_dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS); unsigned int total_data_blocks = 0; - unsigned int node_secs = total_node_blocks / CAP_BLKS_PER_SEC(sbi); - unsigned int dent_secs = total_dent_blocks / CAP_BLKS_PER_SEC(sbi); - unsigned int data_secs = 0; - unsigned int node_blocks = total_node_blocks % CAP_BLKS_PER_SEC(sbi); - unsigned int dent_blocks = total_dent_blocks % CAP_BLKS_PER_SEC(sbi); - unsigned int data_blocks = 0; + bool separate_dent = true; - if (f2fs_lfs_mode(sbi)) { + if (f2fs_lfs_mode(sbi)) total_data_blocks = get_pages(sbi, F2FS_DIRTY_DATA); - data_secs = total_data_blocks / CAP_BLKS_PER_SEC(sbi); - data_blocks = total_data_blocks % CAP_BLKS_PER_SEC(sbi); + + /* + * When active_logs != 4, dentry blocks and data blocks can be + * mixed in the same logs, so check their space together. + */ + if (F2FS_OPTION(sbi).active_logs != 4) { + total_data_blocks += total_dent_blocks; + total_dent_blocks = 0; + separate_dent = false; } - if (lower_p) - *lower_p = node_secs + dent_secs + data_secs; - if (upper_p) - *upper_p = node_secs + dent_secs + data_secs + - (node_blocks ? 1 : 0) + (dent_blocks ? 1 : 0) + - (data_blocks ? 1 : 0); - if (curseg_p) - *curseg_p = has_curseg_enough_space(sbi, - node_blocks, data_blocks, dent_blocks); + get_additional_blocks_required(sbi, &total_node_blocks, &total_dent_blocks, + &total_data_blocks, separate_dent); + + return DIV_ROUND_UP(total_node_blocks, CAP_BLKS_PER_SEC(sbi)) + + DIV_ROUND_UP(total_dent_blocks, CAP_BLKS_PER_SEC(sbi)) + + DIV_ROUND_UP(total_data_blocks, CAP_BLKS_PER_SEC(sbi)); } static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi, int freed, int needed) { - unsigned int free_secs, lower_secs, upper_secs; - bool curseg_space; + unsigned int free_secs, required_secs; if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING))) return false; - __get_secs_required(sbi, &lower_secs, &upper_secs, &curseg_space); - free_secs = free_sections(sbi) + freed; - lower_secs += needed + reserved_sections(sbi); - upper_secs += needed + reserved_sections(sbi); + required_secs = needed + reserved_sections(sbi) + + __get_secs_required(sbi); - if (free_secs > upper_secs) - return false; - if (free_secs <= lower_secs) - return true; - return !curseg_space; + return free_secs < required_secs; } static inline bool has_enough_free_secs(struct f2fs_sb_info *sbi, diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index cd00d030edda..8774c60b4be4 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -67,8 +67,10 @@ const char *f2fs_fault_name[FAULT_MAX] = { [FAULT_BLKADDR_CONSISTENCE] = "inconsistent blkaddr", [FAULT_NO_SEGMENT] = "no free segment", [FAULT_INCONSISTENT_FOOTER] = "inconsistent footer", - [FAULT_TIMEOUT] = "timeout", + [FAULT_ATOMIC_TIMEOUT] = "atomic timeout", [FAULT_VMALLOC] = "vmalloc", + [FAULT_LOCK_TIMEOUT] = "lock timeout", + [FAULT_SKIP_WRITE] = "skip write", }; int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate, @@ -96,8 +98,57 @@ int f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned long rate, f2fs_info(sbi, "build fault injection type: 0x%lx", type); } + if (fo & FAULT_TIMEOUT) { + if (type >= TIMEOUT_TYPE_MAX) + return -EINVAL; + ffi->inject_lock_timeout = (unsigned int)type; + f2fs_info(sbi, "build fault timeout injection type: 0x%lx", type); + } + return 0; } + +static void inject_timeout(struct f2fs_sb_info *sbi) +{ + struct f2fs_fault_info *ffi = &F2FS_OPTION(sbi).fault_info; + enum f2fs_timeout_type type = ffi->inject_lock_timeout; + unsigned long start_time = jiffies; + unsigned long timeout = HZ; + + switch (type) { + case TIMEOUT_TYPE_RUNNING: + while (!time_after(jiffies, start_time + timeout)) { + if (fatal_signal_pending(current)) + return; + ; + } + break; + case TIMEOUT_TYPE_IO_SLEEP: + f2fs_schedule_timeout_killable(timeout, true); + break; + case TIMEOUT_TYPE_NONIO_SLEEP: + f2fs_schedule_timeout_killable(timeout, false); + break; + case TIMEOUT_TYPE_RUNNABLE: + while (!time_after(jiffies, start_time + timeout)) { + if (fatal_signal_pending(current)) + return; + schedule(); + } + break; + default: + return; + } +} + +void f2fs_simulate_lock_timeout(struct f2fs_sb_info *sbi) +{ + struct f2fs_lock_context lc; + + f2fs_lock_op(sbi, &lc); + inject_timeout(sbi); + f2fs_unlock_op(sbi, &lc); +} #endif /* f2fs-wide shrinker description */ @@ -2556,6 +2607,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) { unsigned int s_flags = sbi->sb->s_flags; struct cp_control cpc; + struct f2fs_lock_context lc; unsigned int gc_mode = sbi->gc_mode; int err = 0; int ret; @@ -2585,7 +2637,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) .no_bg_gc = true, .nr_free_secs = 1 }; - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &gc_control.lc); stat_inc_gc_call_count(sbi, FOREGROUND); err = f2fs_gc(sbi, &gc_control); if (err == -ENODATA) { @@ -2609,7 +2661,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) } skip_gc: - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); cpc.reason = CP_PAUSE; set_sbi_flag(sbi, SBI_CP_DISABLED); stat_inc_cp_call_count(sbi, TOTAL_CALL); @@ -2622,7 +2674,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) spin_unlock(&sbi->stat_lock); out_unlock: - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); restore_flag: sbi->gc_mode = gc_mode; sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ @@ -2632,57 +2684,66 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) static int f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) { - unsigned int nr_pages = get_pages(sbi, F2FS_DIRTY_DATA) / 16; - long long start, writeback, lock, sync_inode, end; + int retry = MAX_FLUSH_RETRY_COUNT; + long long start, writeback, end; int ret; + struct f2fs_lock_context lc; + long long skipped_write, dirty_data; - f2fs_info(sbi, "%s start, meta: %lld, node: %lld, data: %lld", - __func__, + f2fs_info(sbi, "f2fs_enable_checkpoint() starts, meta: %lld, node: %lld, data: %lld", get_pages(sbi, F2FS_DIRTY_META), get_pages(sbi, F2FS_DIRTY_NODES), get_pages(sbi, F2FS_DIRTY_DATA)); - f2fs_update_time(sbi, ENABLE_TIME); - start = ktime_get(); + set_sbi_flag(sbi, SBI_ENABLE_CHECKPOINT); + /* we should flush all the data to keep data consistency */ - while (get_pages(sbi, F2FS_DIRTY_DATA)) { - writeback_inodes_sb_nr(sbi->sb, nr_pages, WB_REASON_SYNC); + do { + skipped_write = get_pages(sbi, F2FS_SKIPPED_WRITE); + dirty_data = get_pages(sbi, F2FS_DIRTY_DATA); + + sync_inodes_sb(sbi->sb); f2fs_io_schedule_timeout(DEFAULT_SCHEDULE_TIMEOUT); - if (f2fs_time_over(sbi, ENABLE_TIME)) + f2fs_info(sbi, "sync_inode_sb done, dirty_data: %lld, %lld, " + "skipped write: %lld, %lld, retry: %d", + get_pages(sbi, F2FS_DIRTY_DATA), + dirty_data, + get_pages(sbi, F2FS_SKIPPED_WRITE), + skipped_write, retry); + + /* + * sync_inodes_sb() has retry logic, so let's check dirty_data + * in prior to skipped_write in case there is no dirty data. + */ + if (!get_pages(sbi, F2FS_DIRTY_DATA)) break; - } + if (get_pages(sbi, F2FS_SKIPPED_WRITE) == skipped_write) + break; + } while (retry--); + + clear_sbi_flag(sbi, SBI_ENABLE_CHECKPOINT); + writeback = ktime_get(); - f2fs_down_write(&sbi->cp_enable_rwsem); + if (unlikely(get_pages(sbi, F2FS_DIRTY_DATA) || + get_pages(sbi, F2FS_SKIPPED_WRITE))) + f2fs_warn(sbi, "checkpoint=enable unwritten data: %lld, skipped data: %lld, retry: %d", + get_pages(sbi, F2FS_DIRTY_DATA), + get_pages(sbi, F2FS_SKIPPED_WRITE), retry); - lock = ktime_get(); + if (get_pages(sbi, F2FS_SKIPPED_WRITE)) + atomic_set(&sbi->nr_pages[F2FS_SKIPPED_WRITE], 0); - if (get_pages(sbi, F2FS_DIRTY_DATA)) - sync_inodes_sb(sbi->sb); - - if (unlikely(get_pages(sbi, F2FS_DIRTY_DATA))) - f2fs_warn(sbi, "%s: has some unwritten data: %lld", - __func__, get_pages(sbi, F2FS_DIRTY_DATA)); - - sync_inode = ktime_get(); - - f2fs_down_write(&sbi->gc_lock); + f2fs_down_write_trace(&sbi->gc_lock, &lc); f2fs_dirty_to_prefree(sbi); clear_sbi_flag(sbi, SBI_CP_DISABLED); set_sbi_flag(sbi, SBI_IS_DIRTY); - f2fs_up_write(&sbi->gc_lock); + f2fs_up_write_trace(&sbi->gc_lock, &lc); - f2fs_info(sbi, "%s sync_fs, meta: %lld, imeta: %lld, node: %lld, dents: %lld, qdata: %lld", - __func__, - get_pages(sbi, F2FS_DIRTY_META), - get_pages(sbi, F2FS_DIRTY_IMETA), - get_pages(sbi, F2FS_DIRTY_NODES), - get_pages(sbi, F2FS_DIRTY_DENTS), - get_pages(sbi, F2FS_DIRTY_QDATA)); ret = f2fs_sync_fs(sbi->sb, 1); if (ret) f2fs_err(sbi, "%s sync_fs failed, ret: %d", __func__, ret); @@ -2690,17 +2751,11 @@ static int f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) /* Let's ensure there's no pending checkpoint anymore */ f2fs_flush_ckpt_thread(sbi); - f2fs_up_write(&sbi->cp_enable_rwsem); - end = ktime_get(); - f2fs_info(sbi, "%s end, writeback:%llu, " - "lock:%llu, sync_inode:%llu, sync_fs:%llu", - __func__, - ktime_ms_delta(writeback, start), - ktime_ms_delta(lock, writeback), - ktime_ms_delta(sync_inode, lock), - ktime_ms_delta(end, sync_inode)); + f2fs_info(sbi, "f2fs_enable_checkpoint() finishes, writeback:%llu, sync:%llu", + ktime_ms_delta(writeback, start), + ktime_ms_delta(end, writeback)); return ret; } @@ -3219,19 +3274,12 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly) } static int f2fs_quota_enable(struct super_block *sb, int type, int format_id, - unsigned int flags) + unsigned int flags, unsigned long qf_inum) { struct inode *qf_inode; - unsigned long qf_inum; unsigned long qf_flag = F2FS_QUOTA_DEFAULT_FL; int err; - BUG_ON(!f2fs_sb_has_quota_ino(F2FS_SB(sb))); - - qf_inum = f2fs_qf_ino(sb, type); - if (!qf_inum) - return -EPERM; - qf_inode = f2fs_iget(sb, qf_inum); if (IS_ERR(qf_inode)) { f2fs_err(F2FS_SB(sb), "Bad quota inode %u:%lu", type, qf_inum); @@ -3264,7 +3312,7 @@ static int f2fs_enable_quotas(struct super_block *sb) test_opt(sbi, PRJQUOTA), }; - if (is_set_ckpt_flags(F2FS_SB(sb), CP_QUOTA_NEED_FSCK_FLAG)) { + if (is_set_ckpt_flags(sbi, CP_QUOTA_NEED_FSCK_FLAG)) { f2fs_err(sbi, "quota file may be corrupted, skip loading it"); return 0; } @@ -3276,14 +3324,13 @@ static int f2fs_enable_quotas(struct super_block *sb) if (qf_inum) { err = f2fs_quota_enable(sb, type, QFMT_VFS_V1, DQUOT_USAGE_ENABLED | - (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0)); + (quota_mopt[type] ? DQUOT_LIMITS_ENABLED : 0), qf_inum); if (err) { f2fs_err(sbi, "Failed to enable quota tracking (type=%d, err=%d). Please run fsck to fix.", type, err); for (type--; type >= 0; type--) dquot_quota_off(sb, type); - set_sbi_flag(F2FS_SB(sb), - SBI_QUOTA_NEED_REPAIR); + set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); return err; } } @@ -3330,6 +3377,7 @@ int f2fs_do_quota_sync(struct super_block *sb, int type) * that userspace sees the changes. */ for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + struct f2fs_lock_context lc; if (type != -1 && cnt != type) continue; @@ -3349,13 +3397,13 @@ int f2fs_do_quota_sync(struct super_block *sb, int type) * block_operation * f2fs_down_read(quota_sem) */ - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); f2fs_down_read(&sbi->quota_sem); ret = f2fs_quota_sync_file(sbi, cnt); f2fs_up_read(&sbi->quota_sem); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); if (!f2fs_sb_has_quota_ino(sbi)) inode_unlock(dqopt->files[cnt]); @@ -3677,7 +3725,7 @@ static struct block_device **f2fs_get_devices(struct super_block *sb, if (!f2fs_is_multi_device(sbi)) return NULL; - devs = kmalloc_array(sbi->s_ndevs, sizeof(*devs), GFP_KERNEL); + devs = kmalloc_objs(*devs, sbi->s_ndevs); if (!devs) return ERR_PTR(-ENOMEM); @@ -4077,20 +4125,6 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, if (sanity_check_area_boundary(sbi, folio, index)) return -EFSCORRUPTED; - /* - * Check for legacy summary layout on 16KB+ block devices. - * Modern f2fs-tools packs multiple 4KB summary areas into one block, - * whereas legacy versions used one block per summary, leading - * to a much larger SSA. - */ - if (SUMS_PER_BLOCK > 1 && - !(__F2FS_HAS_FEATURE(raw_super, F2FS_FEATURE_PACKED_SSA))) { - f2fs_info(sbi, "Error: Device formatted with a legacy version. " - "Please reformat with a tool supporting the packed ssa " - "feature for block sizes larger than 4kb."); - return -EOPNOTSUPP; - } - return 0; } @@ -4300,6 +4334,22 @@ static void init_sb_info(struct f2fs_sb_info *sbi) sbi->max_fragment_hole = DEF_FRAGMENT_SIZE; spin_lock_init(&sbi->gc_remaining_trials_lock); atomic64_set(&sbi->current_atomic_write, 0); + sbi->max_lock_elapsed_time = MAX_LOCK_ELAPSED_TIME; + sbi->adjust_lock_priority = 0; + sbi->lock_duration_priority = F2FS_DEFAULT_TASK_PRIORITY; + sbi->critical_task_priority = F2FS_CRITICAL_TASK_PRIORITY; + + sbi->sum_blocksize = f2fs_sb_has_packed_ssa(sbi) ? + 4096 : sbi->blocksize; + sbi->sums_per_block = sbi->blocksize / sbi->sum_blocksize; + sbi->entries_in_sum = sbi->sum_blocksize / 8; + sbi->sum_entry_size = SUMMARY_SIZE * sbi->entries_in_sum; + sbi->sum_journal_size = sbi->sum_blocksize - SUM_FOOTER_SIZE - + sbi->sum_entry_size; + sbi->nat_journal_entries = (sbi->sum_journal_size - 2) / + sizeof(struct nat_journal_entry); + sbi->sit_journal_entries = (sbi->sum_journal_size - 2) / + sizeof(struct sit_journal_entry); sbi->dir_level = DEF_DIR_LEVEL; sbi->interval_time[CP_TIME] = DEF_CP_INTERVAL; @@ -4307,7 +4357,6 @@ static void init_sb_info(struct f2fs_sb_info *sbi) sbi->interval_time[DISCARD_TIME] = DEF_IDLE_INTERVAL; sbi->interval_time[GC_TIME] = DEF_IDLE_INTERVAL; sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_INTERVAL; - sbi->interval_time[ENABLE_TIME] = DEF_ENABLE_INTERVAL; sbi->interval_time[UMOUNT_DISCARD_TIMEOUT] = DEF_UMOUNT_DISCARD_TIMEOUT; clear_sbi_flag(sbi, SBI_NEED_FSCK); @@ -4452,7 +4501,7 @@ static int read_raw_super_block(struct f2fs_sb_info *sbi, struct f2fs_super_block *super; int err = 0; - super = kzalloc(sizeof(struct f2fs_super_block), GFP_KERNEL); + super = kzalloc_obj(struct f2fs_super_block); if (!super) return -ENOMEM; @@ -4889,21 +4938,20 @@ static int f2fs_fill_super(struct super_block *sb, struct fs_context *fc) recovery = 0; /* allocate memory for f2fs-specific super block info */ - sbi = kzalloc(sizeof(struct f2fs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct f2fs_sb_info); if (!sbi) return -ENOMEM; sbi->sb = sb; /* initialize locks within allocated memory */ - init_f2fs_rwsem(&sbi->gc_lock); + init_f2fs_rwsem_trace(&sbi->gc_lock, sbi, LOCK_NAME_GC_LOCK); mutex_init(&sbi->writepages); - init_f2fs_rwsem(&sbi->cp_global_sem); - init_f2fs_rwsem(&sbi->node_write); - init_f2fs_rwsem(&sbi->node_change); + init_f2fs_rwsem_trace(&sbi->cp_global_sem, sbi, LOCK_NAME_CP_GLOBAL); + init_f2fs_rwsem_trace(&sbi->node_write, sbi, LOCK_NAME_NODE_WRITE); + init_f2fs_rwsem_trace(&sbi->node_change, sbi, LOCK_NAME_NODE_CHANGE); spin_lock_init(&sbi->stat_lock); - init_f2fs_rwsem(&sbi->cp_rwsem); - init_f2fs_rwsem(&sbi->cp_enable_rwsem); + init_f2fs_rwsem_trace(&sbi->cp_rwsem, sbi, LOCK_NAME_CP_RWSEM); init_f2fs_rwsem(&sbi->quota_sem); init_waitqueue_head(&sbi->cp_wait); spin_lock_init(&sbi->error_lock); @@ -5461,7 +5509,7 @@ static int f2fs_init_fs_context(struct fs_context *fc) { struct f2fs_fs_context *ctx; - ctx = kzalloc(sizeof(struct f2fs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct f2fs_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index c42f4f979d13..5fbfdc96e502 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -35,6 +35,7 @@ enum { #ifdef CONFIG_F2FS_FAULT_INJECTION FAULT_INFO_RATE, /* struct f2fs_fault_info */ FAULT_INFO_TYPE, /* struct f2fs_fault_info */ + FAULT_INFO_TIMEOUT, /* struct f2fs_fault_info */ #endif RESERVED_BLOCKS, /* struct f2fs_sb_info */ CPRC_INFO, /* struct ckpt_req_control */ @@ -58,6 +59,7 @@ struct f2fs_attr { const char *buf, size_t len); int struct_type; int offset; + int size; int id; }; @@ -84,7 +86,8 @@ static unsigned char *__struct_ptr(struct f2fs_sb_info *sbi, int struct_type) return (unsigned char *)sbi; #ifdef CONFIG_F2FS_FAULT_INJECTION else if (struct_type == FAULT_INFO_RATE || - struct_type == FAULT_INFO_TYPE) + struct_type == FAULT_INFO_TYPE || + struct_type == FAULT_INFO_TIMEOUT) return (unsigned char *)&F2FS_OPTION(sbi).fault_info; #endif #ifdef CONFIG_F2FS_STAT_FS @@ -344,11 +347,30 @@ static ssize_t main_blkaddr_show(struct f2fs_attr *a, (unsigned long long)MAIN_BLKADDR(sbi)); } +static ssize_t __sbi_show_value(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, char *buf, + unsigned char *value) +{ + switch (a->size) { + case 1: + return sysfs_emit(buf, "%u\n", *(u8 *)value); + case 2: + return sysfs_emit(buf, "%u\n", *(u16 *)value); + case 4: + return sysfs_emit(buf, "%u\n", *(u32 *)value); + case 8: + return sysfs_emit(buf, "%llu\n", *(u64 *)value); + default: + f2fs_bug_on(sbi, 1); + return sysfs_emit(buf, + "show sysfs node value with wrong type\n"); + } +} + static ssize_t f2fs_sbi_show(struct f2fs_attr *a, struct f2fs_sb_info *sbi, char *buf) { unsigned char *ptr = NULL; - unsigned int *ui; ptr = __struct_ptr(sbi, a->struct_type); if (!ptr) @@ -428,9 +450,30 @@ static ssize_t f2fs_sbi_show(struct f2fs_attr *a, atomic_read(&sbi->cp_call_count[BACKGROUND])); #endif - ui = (unsigned int *)(ptr + a->offset); + return __sbi_show_value(a, sbi, buf, ptr + a->offset); +} - return sysfs_emit(buf, "%u\n", *ui); +static void __sbi_store_value(struct f2fs_attr *a, + struct f2fs_sb_info *sbi, + unsigned char *ui, unsigned long value) +{ + switch (a->size) { + case 1: + *(u8 *)ui = value; + break; + case 2: + *(u16 *)ui = value; + break; + case 4: + *(u32 *)ui = value; + break; + case 8: + *(u64 *)ui = value; + break; + default: + f2fs_bug_on(sbi, 1); + f2fs_err(sbi, "store sysfs node value with wrong type"); + } } static ssize_t __sbi_store(struct f2fs_attr *a, @@ -529,6 +572,12 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return -EINVAL; return count; } + if (a->struct_type == FAULT_INFO_TIMEOUT) { + if (f2fs_build_fault_attr(sbi, 0, t, FAULT_TIMEOUT)) + return -EINVAL; + f2fs_simulate_lock_timeout(sbi); + return count; + } #endif if (a->struct_type == RESERVED_BLOCKS) { spin_lock(&sbi->stat_lock); @@ -749,7 +798,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return count; } - if (!strcmp(a->attr.name, "gc_pin_file_threshold")) { + if (!strcmp(a->attr.name, "gc_pin_file_thresh")) { if (t > MAX_GC_FAILED_PINNED_FILES) return -EINVAL; sbi->gc_pin_file_threshold = t; @@ -906,7 +955,36 @@ static ssize_t __sbi_store(struct f2fs_attr *a, return count; } - *ui = (unsigned int)t; + if (!strcmp(a->attr.name, "adjust_lock_priority")) { + if (t >= BIT(LOCK_NAME_MAX - 1)) + return -EINVAL; + sbi->adjust_lock_priority = t; + return count; + } + + if (!strcmp(a->attr.name, "lock_duration_priority")) { + if (t < NICE_TO_PRIO(MIN_NICE) || t > NICE_TO_PRIO(MAX_NICE)) + return -EINVAL; + sbi->lock_duration_priority = t; + return count; + } + + if (!strcmp(a->attr.name, "critical_task_priority")) { + if (t < NICE_TO_PRIO(MIN_NICE) || t > NICE_TO_PRIO(MAX_NICE)) + return -EINVAL; + if (!capable(CAP_SYS_NICE)) + return -EPERM; + sbi->critical_task_priority = t; + if (sbi->cprc_info.f2fs_issue_ckpt) + set_user_nice(sbi->cprc_info.f2fs_issue_ckpt, + PRIO_TO_NICE(sbi->critical_task_priority)); + if (sbi->gc_thread && sbi->gc_thread->f2fs_gc_task) + set_user_nice(sbi->gc_thread->f2fs_gc_task, + PRIO_TO_NICE(sbi->critical_task_priority)); + return count; + } + + __sbi_store_value(a, sbi, ptr + a->offset, t); return count; } @@ -1053,24 +1131,27 @@ static struct f2fs_attr f2fs_attr_sb_##_name = { \ .id = F2FS_FEATURE_##_feat, \ } -#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset) \ +#define F2FS_ATTR_OFFSET(_struct_type, _name, _mode, _show, _store, _offset, _size) \ static struct f2fs_attr f2fs_attr_##_name = { \ .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ .struct_type = _struct_type, \ - .offset = _offset \ + .offset = _offset, \ + .size = _size \ } #define F2FS_RO_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0444, \ f2fs_sbi_show, NULL, \ - offsetof(struct struct_name, elname)) + offsetof(struct struct_name, elname), \ + sizeof_field(struct struct_name, elname)) #define F2FS_RW_ATTR(struct_type, struct_name, name, elname) \ F2FS_ATTR_OFFSET(struct_type, name, 0644, \ f2fs_sbi_show, f2fs_sbi_store, \ - offsetof(struct struct_name, elname)) + offsetof(struct struct_name, elname), \ + sizeof_field(struct struct_name, elname)) #define F2FS_GENERAL_RO_ATTR(name) \ static struct f2fs_attr f2fs_attr_##name = __ATTR(name, 0444, name##_show, NULL) @@ -1219,6 +1300,10 @@ F2FS_SBI_GENERAL_RW_ATTR(blkzone_alloc_policy); F2FS_SBI_GENERAL_RW_ATTR(carve_out); F2FS_SBI_GENERAL_RW_ATTR(reserved_pin_section); F2FS_SBI_GENERAL_RW_ATTR(bggc_io_aware); +F2FS_SBI_GENERAL_RW_ATTR(max_lock_elapsed_time); +F2FS_SBI_GENERAL_RW_ATTR(lock_duration_priority); +F2FS_SBI_GENERAL_RW_ATTR(adjust_lock_priority); +F2FS_SBI_GENERAL_RW_ATTR(critical_task_priority); /* STAT_INFO ATTR */ #ifdef CONFIG_F2FS_STAT_FS @@ -1232,6 +1317,7 @@ STAT_INFO_RO_ATTR(gc_background_calls, gc_call_count[BACKGROUND]); #ifdef CONFIG_F2FS_FAULT_INJECTION FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_RATE, inject_rate); FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TYPE, inject_type); +FAULT_INFO_GENERAL_RW_ATTR(FAULT_INFO_TIMEOUT, inject_lock_timeout); #endif /* RESERVED_BLOCKS ATTR */ @@ -1361,6 +1447,7 @@ static struct attribute *f2fs_attrs[] = { #ifdef CONFIG_F2FS_FAULT_INJECTION ATTR_LIST(inject_rate), ATTR_LIST(inject_type), + ATTR_LIST(inject_lock_timeout), #endif ATTR_LIST(data_io_flag), ATTR_LIST(node_io_flag), @@ -1422,6 +1509,10 @@ static struct attribute *f2fs_attrs[] = { ATTR_LIST(reserved_pin_section), ATTR_LIST(allocate_section_hint), ATTR_LIST(allocate_section_policy), + ATTR_LIST(max_lock_elapsed_time), + ATTR_LIST(lock_duration_priority), + ATTR_LIST(adjust_lock_priority), + ATTR_LIST(critical_task_priority), NULL, }; ATTRIBUTE_GROUPS(f2fs); diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index b4e5c406632f..941dc62a6d6f 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -804,6 +804,7 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, struct folio *ifolio, int flags) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + struct f2fs_lock_context lc; int err; if (unlikely(f2fs_cp_error(sbi))) @@ -821,11 +822,11 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, size, ifolio, flags); f2fs_balance_fs(sbi, true); - f2fs_lock_op(sbi); + f2fs_lock_op(sbi, &lc); f2fs_down_write(&F2FS_I(inode)->i_xattr_sem); err = __f2fs_setxattr(inode, index, name, value, size, NULL, flags); f2fs_up_write(&F2FS_I(inode)->i_xattr_sem); - f2fs_unlock_op(sbi); + f2fs_unlock_op(sbi, &lc); f2fs_update_time(sbi, REQ_TIME); return err; diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 59fa90617b5b..3cc5fb01afa1 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1554,7 +1554,7 @@ int fat_fill_super(struct super_block *sb, struct fs_context *fc, * the filesystem, since we're only just about to mount * it and have no inodes etc active! */ - sbi = kzalloc(sizeof(struct msdos_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct msdos_sb_info); if (!sbi) return -ENOMEM; sb->s_fs_info = sbi; @@ -1905,7 +1905,7 @@ int fat_init_fs_context(struct fs_context *fc, bool is_vfat) { struct fat_mount_options *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 2acfe3123a72..87dcdd86272b 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -663,7 +663,7 @@ static int vfat_add_entry(struct inode *dir, const struct qstr *qname, if (len == 0) return -ENOENT; - slots = kmalloc_array(MSDOS_SLOTS, sizeof(*slots), GFP_NOFS); + slots = kmalloc_objs(*slots, MSDOS_SLOTS, GFP_NOFS); if (slots == NULL) return -ENOMEM; diff --git a/fs/fcntl.c b/fs/fcntl.c index f93dbca08435..beab8080badf 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -100,7 +100,7 @@ int file_f_owner_allocate(struct file *file) if (f_owner) return 0; - f_owner = kzalloc(sizeof(struct fown_struct), GFP_KERNEL); + f_owner = kzalloc_obj(struct fown_struct); if (!f_owner) return -ENOMEM; diff --git a/fs/fhandle.c b/fs/fhandle.c index e15bcf4b0b23..642e3d569497 100644 --- a/fs/fhandle.c +++ b/fs/fhandle.c @@ -46,8 +46,7 @@ static long do_sys_name_to_handle(const struct path *path, if (f_handle.handle_bytes > MAX_HANDLE_SZ) return -EINVAL; - handle = kzalloc(struct_size(handle, f_handle, f_handle.handle_bytes), - GFP_KERNEL); + handle = kzalloc_flex(*handle, f_handle, f_handle.handle_bytes); if (!handle) return -ENOMEM; @@ -368,8 +367,7 @@ static int handle_to_path(int mountdirfd, struct file_handle __user *ufh, if (retval) goto out_path; - handle = kmalloc(struct_size(handle, f_handle, f_handle.handle_bytes), - GFP_KERNEL); + handle = kmalloc_flex(*handle, f_handle, f_handle.handle_bytes); if (!handle) { retval = -ENOMEM; goto out_path; diff --git a/fs/file.c b/fs/file.c index 0a4f3bdb2dec..384c83ce768d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -212,11 +212,11 @@ static struct fdtable *alloc_fdtable(unsigned int slots_wanted) if (unlikely(nr > INT_MAX / sizeof(struct file *))) return ERR_PTR(-EMFILE); - fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL_ACCOUNT); + fdt = kmalloc_obj(struct fdtable, GFP_KERNEL_ACCOUNT); if (!fdt) goto out; fdt->max_fds = nr; - data = kvmalloc_array(nr, sizeof(struct file *), GFP_KERNEL_ACCOUNT); + data = kvmalloc_objs(struct file *, nr, GFP_KERNEL_ACCOUNT); if (!data) goto out_fdt; fdt->fd = data; @@ -777,23 +777,29 @@ static inline void __range_close(struct files_struct *files, unsigned int fd, unsigned int max_fd) { struct file *file; + struct fdtable *fdt; unsigned n; spin_lock(&files->file_lock); - n = last_fd(files_fdtable(files)); + fdt = files_fdtable(files); + n = last_fd(fdt); max_fd = min(max_fd, n); - for (; fd <= max_fd; fd++) { + for (fd = find_next_bit(fdt->open_fds, max_fd + 1, fd); + fd <= max_fd; + fd = find_next_bit(fdt->open_fds, max_fd + 1, fd + 1)) { file = file_close_fd_locked(files, fd); if (file) { spin_unlock(&files->file_lock); filp_close(file, files); cond_resched(); spin_lock(&files->file_lock); + fdt = files_fdtable(files); } else if (need_resched()) { spin_unlock(&files->file_lock); cond_resched(); spin_lock(&files->file_lock); + fdt = files_fdtable(files); } } spin_unlock(&files->file_lock); diff --git a/fs/file_attr.c b/fs/file_attr.c index 42721427245a..da983e105d70 100644 --- a/fs/file_attr.c +++ b/fs/file_attr.c @@ -37,6 +37,8 @@ void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags) fa->flags |= FS_DAX_FL; if (fa->fsx_xflags & FS_XFLAG_PROJINHERIT) fa->flags |= FS_PROJINHERIT_FL; + if (fa->fsx_xflags & FS_XFLAG_VERITY) + fa->flags |= FS_VERITY_FL; } EXPORT_SYMBOL(fileattr_fill_xflags); @@ -67,6 +69,8 @@ void fileattr_fill_flags(struct file_kattr *fa, u32 flags) fa->fsx_xflags |= FS_XFLAG_DAX; if (fa->flags & FS_PROJINHERIT_FL) fa->fsx_xflags |= FS_XFLAG_PROJINHERIT; + if (fa->flags & FS_VERITY_FL) + fa->fsx_xflags |= FS_XFLAG_VERITY; } EXPORT_SYMBOL(fileattr_fill_flags); @@ -142,8 +146,7 @@ static int file_attr_to_fileattr(const struct file_attr *fattr, if (fattr->fa_xflags & ~mask) return -EINVAL; - fileattr_fill_xflags(fa, fattr->fa_xflags); - fa->fsx_xflags &= ~FS_XFLAG_RDONLY_MASK; + fileattr_fill_xflags(fa, fattr->fa_xflags & ~FS_XFLAG_RDONLY_MASK); fa->fsx_extsize = fattr->fa_extsize; fa->fsx_projid = fattr->fa_projid; fa->fsx_cowextsize = fattr->fa_cowextsize; @@ -163,8 +166,7 @@ static int copy_fsxattr_from_user(struct file_kattr *fa, if (xfa.fsx_xflags & ~mask) return -EOPNOTSUPP; - fileattr_fill_xflags(fa, xfa.fsx_xflags); - fa->fsx_xflags &= ~FS_XFLAG_RDONLY_MASK; + fileattr_fill_xflags(fa, xfa.fsx_xflags & ~FS_XFLAG_RDONLY_MASK); fa->fsx_extsize = xfa.fsx_extsize; fa->fsx_nextents = xfa.fsx_nextents; fa->fsx_projid = xfa.fsx_projid; @@ -376,7 +378,7 @@ SYSCALL_DEFINE5(file_getattr, int, dfd, const char __user *, filename, struct path filepath __free(path_put) = {}; unsigned int lookup_flags = 0; struct file_attr fattr; - struct file_kattr fa; + struct file_kattr fa = { .flags_valid = true }; /* hint only */ int error; BUILD_BUG_ON(sizeof(struct file_attr) < FILE_ATTR_SIZE_VER0); diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c index c1174a3f8990..e6ab8bdf7a6c 100644 --- a/fs/freevxfs/vxfs_fshead.c +++ b/fs/freevxfs/vxfs_fshead.c @@ -58,7 +58,7 @@ vxfs_getfsh(struct inode *ip, int which) if (bp) { struct vxfs_fsh *fhp; - if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL))) + if (!(fhp = kmalloc_obj(*fhp))) goto out; memcpy(fhp, bp->b_data, sizeof(*fhp)); diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index fabe60778658..d7d847d75c3d 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -193,7 +193,7 @@ static int vxfs_fill_super(struct super_block *sbp, struct fs_context *fc) sbp->s_flags |= SB_RDONLY; - infp = kzalloc(sizeof(*infp), GFP_KERNEL); + infp = kzalloc_obj(*infp); if (!infp) { warnf(fc, "vxfs: unable to allocate incore superblock"); return -ENOMEM; diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 68228bf89b82..7c75ed7e8979 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -198,10 +198,11 @@ static void wb_queue_work(struct bdi_writeback *wb, static bool wb_wait_for_completion_cb(struct wb_completion *done) { + unsigned long timeout = sysctl_hung_task_timeout_secs; unsigned long waited_secs = (jiffies - done->wait_start) / HZ; done->progress_stamp = jiffies; - if (waited_secs > sysctl_hung_task_timeout_secs) + if (timeout && (waited_secs > timeout)) pr_info("INFO: The task %s:%d has been waiting for writeback " "completion for more than %lu seconds.", current->comm, current->pid, waited_secs); @@ -653,7 +654,7 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id) if (atomic_read(&isw_nr_in_flight) > WB_FRN_MAX_IN_FLIGHT) return; - isw = kzalloc(struct_size(isw, inodes, 2), GFP_ATOMIC); + isw = kzalloc_flex(*isw, inodes, 2, GFP_ATOMIC); if (!isw) return; @@ -724,8 +725,7 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) int nr; bool restart = false; - isw = kzalloc(struct_size(isw, inodes, WB_MAX_INODES_PER_ISW), - GFP_KERNEL); + isw = kzalloc_flex(*isw, inodes, WB_MAX_INODES_PER_ISW); if (!isw) return restart; @@ -1075,7 +1075,7 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, nr_pages = wb_split_bdi_pages(wb, base_work->nr_pages); - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) { *work = *base_work; work->nr_pages = nr_pages; @@ -1173,7 +1173,7 @@ int cgroup_writeback_by_id(u64 bdi_id, int memcg_id, dirty = dirty * 10 / 8; /* issue the writeback work */ - work = kzalloc(sizeof(*work), GFP_NOWAIT); + work = kzalloc_obj(*work, GFP_NOWAIT); if (work) { work->nr_pages = dirty; work->sync_mode = WB_SYNC_NONE; @@ -1955,6 +1955,7 @@ static long writeback_sb_inodes(struct super_block *sb, .range_end = LLONG_MAX, }; unsigned long start_time = jiffies; + unsigned long timeout = sysctl_hung_task_timeout_secs; long write_chunk; long total_wrote = 0; /* count both pages and inodes */ unsigned long dirtied_before = jiffies; @@ -2041,9 +2042,8 @@ static long writeback_sb_inodes(struct super_block *sb, __writeback_single_inode(inode, &wbc); /* Report progress to inform the hung task detector of the progress. */ - if (work->done && work->done->progress_stamp && - (jiffies - work->done->progress_stamp) > HZ * - sysctl_hung_task_timeout_secs / 2) + if (work->done && work->done->progress_stamp && timeout && + (jiffies - work->done->progress_stamp) > HZ * timeout / 2) wake_up_all(work->done->waitq); wbc_detach_inode(&wbc); diff --git a/fs/fs_context.c b/fs/fs_context.c index 81ed94f46cac..a37b0a093505 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -264,7 +264,7 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type, struct fs_context *fc; int ret = -ENOMEM; - fc = kzalloc(sizeof(struct fs_context), GFP_KERNEL_ACCOUNT); + fc = kzalloc_obj(struct fs_context, GFP_KERNEL_ACCOUNT); if (!fc) return ERR_PTR(-ENOMEM); diff --git a/fs/fsopen.c b/fs/fsopen.c index 614922623675..ae19e5136598 100644 --- a/fs/fsopen.c +++ b/fs/fsopen.c @@ -102,7 +102,7 @@ static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags) static int fscontext_alloc_log(struct fs_context *fc) { - fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL); + fc->log.log = kzalloc_obj(*fc->log.log); if (!fc->log.log) return -ENOMEM; refcount_set(&fc->log.log->usage, 1); diff --git a/fs/fuse/backing.c b/fs/fuse/backing.c index 4afda419dd14..d95dfa48483f 100644 --- a/fs/fuse/backing.c +++ b/fs/fuse/backing.c @@ -112,7 +112,7 @@ int fuse_backing_open(struct fuse_conn *fc, struct fuse_backing_map *map) if (backing_sb->s_stack_depth >= fc->max_stack_depth) goto out_fput; - fb = kmalloc(sizeof(struct fuse_backing), GFP_KERNEL); + fb = kmalloc_obj(struct fuse_backing); res = -ENOMEM; if (!fb) goto out_fput; diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 28c96961e85d..dfcb98a654d8 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -362,7 +362,7 @@ static void cuse_process_init_reply(struct fuse_mount *fm, /* devt determined, create device */ rc = -ENOMEM; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto err_region; @@ -443,7 +443,7 @@ static int cuse_send_init(struct cuse_conn *cc) if (!folio) goto err; - ia = kzalloc(sizeof(*ia), GFP_KERNEL); + ia = kzalloc_obj(*ia); if (!ia) goto err_free_folio; @@ -505,7 +505,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file) int rc; /* set up cuse_conn */ - cc = kzalloc(sizeof(*cc), GFP_KERNEL); + cc = kzalloc_obj(*cc); if (!cc) return -ENOMEM; diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c index ac6d4c1064cc..f6cf00a8938c 100644 --- a/fs/fuse/dax.c +++ b/fs/fuse/dax.c @@ -257,7 +257,7 @@ static int dmap_removemapping_list(struct inode *inode, unsigned int num, int ret, i = 0, nr_alloc; nr_alloc = min_t(unsigned int, num, FUSE_REMOVEMAPPING_MAX_ENTRY); - remove_one = kmalloc_array(nr_alloc, sizeof(*remove_one), GFP_NOFS); + remove_one = kmalloc_objs(*remove_one, nr_alloc, GFP_NOFS); if (!remove_one) return -ENOMEM; @@ -1219,7 +1219,7 @@ static int fuse_dax_mem_range_init(struct fuse_conn_dax *fcd) __func__, nr_pages, nr_ranges); for (i = 0; i < nr_ranges; i++) { - range = kzalloc(sizeof(struct fuse_dax_mapping), GFP_KERNEL); + range = kzalloc_obj(struct fuse_dax_mapping); ret = -ENOMEM; if (!range) goto out_err; @@ -1255,7 +1255,7 @@ int fuse_dax_conn_alloc(struct fuse_conn *fc, enum fuse_dax_mode dax_mode, if (!dax_dev) return 0; - fcd = kzalloc(sizeof(*fcd), GFP_KERNEL); + fcd = kzalloc_obj(*fcd); if (!fcd) return -ENOMEM; @@ -1277,7 +1277,7 @@ bool fuse_dax_inode_alloc(struct super_block *sb, struct fuse_inode *fi) fi->dax = NULL; if (fc->dax) { - fi->dax = kzalloc(sizeof(*fi->dax), GFP_KERNEL_ACCOUNT); + fi->dax = kzalloc_obj(*fi->dax, GFP_KERNEL_ACCOUNT); if (!fi->dax) return false; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index a30c8b57d478..0b0241f47170 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1598,8 +1598,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, if (IS_ERR(fud)) return PTR_ERR(fud); - bufs = kvmalloc_array(pipe->max_usage, sizeof(struct pipe_buffer), - GFP_KERNEL); + bufs = kvmalloc_objs(struct pipe_buffer, pipe->max_usage); if (!bufs) return -ENOMEM; @@ -2311,7 +2310,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, tail = pipe->tail; count = pipe_occupancy(head, tail); - bufs = kvmalloc_array(count, sizeof(struct pipe_buffer), GFP_KERNEL); + bufs = kvmalloc_objs(struct pipe_buffer, count); if (!bufs) { pipe_unlock(pipe); return -ENOMEM; diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index 5ceb217ced1b..3a38b61aac26 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -231,12 +231,12 @@ static struct fuse_ring *fuse_uring_create(struct fuse_conn *fc) struct fuse_ring *res = NULL; size_t max_payload_size; - ring = kzalloc(sizeof(*fc->ring), GFP_KERNEL_ACCOUNT); + ring = kzalloc_obj(*fc->ring, GFP_KERNEL_ACCOUNT); if (!ring) return NULL; - ring->queues = kcalloc(nr_queues, sizeof(struct fuse_ring_queue *), - GFP_KERNEL_ACCOUNT); + ring->queues = kzalloc_objs(struct fuse_ring_queue *, nr_queues, + GFP_KERNEL_ACCOUNT); if (!ring->queues) goto out_err; @@ -274,10 +274,10 @@ static struct fuse_ring_queue *fuse_uring_create_queue(struct fuse_ring *ring, struct fuse_ring_queue *queue; struct list_head *pq; - queue = kzalloc(sizeof(*queue), GFP_KERNEL_ACCOUNT); + queue = kzalloc_obj(*queue, GFP_KERNEL_ACCOUNT); if (!queue) return NULL; - pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL); + pq = kzalloc_objs(struct list_head, FUSE_PQ_HASH_SIZE); if (!pq) { kfree(queue); return NULL; @@ -879,7 +879,8 @@ static int fuse_ring_ent_set_commit(struct fuse_ring_ent *ent) static int fuse_uring_commit_fetch(struct io_uring_cmd *cmd, int issue_flags, struct fuse_conn *fc) { - const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe_cmd(cmd->sqe); + const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe128_cmd(cmd->sqe, + struct fuse_uring_cmd_req); struct fuse_ring_ent *ent; int err; struct fuse_ring *ring = fc->ring; @@ -1062,7 +1063,7 @@ fuse_uring_create_ring_ent(struct io_uring_cmd *cmd, } err = -ENOMEM; - ent = kzalloc(sizeof(*ent), GFP_KERNEL_ACCOUNT); + ent = kzalloc_obj(*ent, GFP_KERNEL_ACCOUNT); if (!ent) return ERR_PTR(err); @@ -1083,7 +1084,8 @@ fuse_uring_create_ring_ent(struct io_uring_cmd *cmd, static int fuse_uring_register(struct io_uring_cmd *cmd, unsigned int issue_flags, struct fuse_conn *fc) { - const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe_cmd(cmd->sqe); + const struct fuse_uring_cmd_req *cmd_req = io_uring_sqe128_cmd(cmd->sqe, + struct fuse_uring_cmd_req); struct fuse_ring *ring = smp_load_acquire(&fc->ring); struct fuse_ring_queue *queue; struct fuse_ring_ent *ent; diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index f25ee47822ad..7ac6b232ef12 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -473,8 +473,8 @@ static int fuse_dentry_init(struct dentry *dentry) { struct fuse_dentry *fd; - fd = kzalloc(sizeof(struct fuse_dentry), - GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); + fd = kzalloc_obj(struct fuse_dentry, + GFP_KERNEL_ACCOUNT | __GFP_RECLAIMABLE); if (!fd) return -ENOMEM; diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 80765ab6d04a..b1bb7153cb78 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -56,13 +56,13 @@ struct fuse_file *fuse_file_alloc(struct fuse_mount *fm, bool release) { struct fuse_file *ff; - ff = kzalloc(sizeof(struct fuse_file), GFP_KERNEL_ACCOUNT); + ff = kzalloc_obj(struct fuse_file, GFP_KERNEL_ACCOUNT); if (unlikely(!ff)) return NULL; ff->fm = fm; if (release) { - ff->args = kzalloc(sizeof(*ff->args), GFP_KERNEL_ACCOUNT); + ff->args = kzalloc_obj(*ff->args, GFP_KERNEL_ACCOUNT); if (!ff->args) { kfree(ff); return NULL; @@ -684,7 +684,7 @@ static struct fuse_io_args *fuse_io_alloc(struct fuse_io_priv *io, { struct fuse_io_args *ia; - ia = kzalloc(sizeof(*ia), GFP_KERNEL); + ia = kzalloc_obj(*ia); if (ia) { ia->io = io; ia->ap.folios = fuse_folios_alloc(nfolios, GFP_KERNEL, @@ -2045,7 +2045,7 @@ static struct fuse_writepage_args *fuse_writepage_args_alloc(void) struct fuse_writepage_args *wpa; struct fuse_args_pages *ap; - wpa = kzalloc(sizeof(*wpa), GFP_NOFS); + wpa = kzalloc_obj(*wpa, GFP_NOFS); if (wpa) { ap = &wpa->ia.ap; ap->num_folios = 0; @@ -2834,7 +2834,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if ((iov_iter_rw(iter) == READ) && (offset >= i_size)) return 0; - io = kmalloc(sizeof(struct fuse_io_priv), GFP_KERNEL); + io = kmalloc_obj(struct fuse_io_priv); if (!io) return -ENOMEM; spin_lock_init(&io->lock); diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 819e50d66622..e57b8af06be9 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -74,14 +74,14 @@ static struct file_system_type fuseblk_fs_type; struct fuse_forget_link *fuse_alloc_forget(void) { - return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL_ACCOUNT); + return kzalloc_obj(struct fuse_forget_link, GFP_KERNEL_ACCOUNT); } static struct fuse_submount_lookup *fuse_alloc_submount_lookup(void) { struct fuse_submount_lookup *sl; - sl = kzalloc(sizeof(struct fuse_submount_lookup), GFP_KERNEL_ACCOUNT); + sl = kzalloc_obj(struct fuse_submount_lookup, GFP_KERNEL_ACCOUNT); if (!sl) return NULL; sl->forget = fuse_alloc_forget(); @@ -684,7 +684,7 @@ static struct fuse_sync_bucket *fuse_sync_bucket_alloc(void) { struct fuse_sync_bucket *bucket; - bucket = kzalloc(sizeof(*bucket), GFP_KERNEL | __GFP_NOFAIL); + bucket = kzalloc_obj(*bucket, GFP_KERNEL | __GFP_NOFAIL); if (bucket) { init_waitqueue_head(&bucket->waitq); /* Initial active count */ @@ -1487,7 +1487,7 @@ static struct fuse_init_args *fuse_new_init(struct fuse_mount *fm) struct fuse_init_args *ia; u64 flags; - ia = kzalloc(sizeof(*ia), GFP_KERNEL | __GFP_NOFAIL); + ia = kzalloc_obj(*ia, GFP_KERNEL | __GFP_NOFAIL); ia->in.major = FUSE_KERNEL_VERSION; ia->in.minor = FUSE_KERNEL_MINOR_VERSION; @@ -1618,11 +1618,11 @@ struct fuse_dev *fuse_dev_alloc(void) struct fuse_dev *fud; struct list_head *pq; - fud = kzalloc(sizeof(struct fuse_dev), GFP_KERNEL); + fud = kzalloc_obj(struct fuse_dev); if (!fud) return NULL; - pq = kcalloc(FUSE_PQ_HASH_SIZE, sizeof(struct list_head), GFP_KERNEL); + pq = kzalloc_objs(struct list_head, FUSE_PQ_HASH_SIZE); if (!pq) { kfree(fud); return NULL; @@ -1780,7 +1780,7 @@ static int fuse_get_tree_submount(struct fs_context *fsc) struct super_block *sb; int err; - fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL); + fm = kzalloc_obj(struct fuse_mount); if (!fm) return -ENOMEM; @@ -1981,11 +1981,11 @@ static int fuse_get_tree(struct fs_context *fsc) struct super_block *sb; int err; - fc = kmalloc(sizeof(*fc), GFP_KERNEL); + fc = kmalloc_obj(*fc); if (!fc) return -ENOMEM; - fm = kzalloc(sizeof(*fm), GFP_KERNEL); + fm = kzalloc_obj(*fm); if (!fm) { kfree(fc); return -ENOMEM; @@ -2047,7 +2047,7 @@ static int fuse_init_fs_context(struct fs_context *fsc) { struct fuse_fs_context *ctx; - ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct fuse_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index b2f6486fe1d5..057e65b51b99 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -839,7 +839,7 @@ static void virtio_fs_requests_done_work(struct work_struct *work) if (req->args->may_block) { struct virtio_fs_req_work *w; - w = kzalloc(sizeof(*w), GFP_NOFS | __GFP_NOFAIL); + w = kzalloc_obj(*w, GFP_NOFS | __GFP_NOFAIL); INIT_WORK(&w->done_work, virtio_fs_complete_req_work); w->fsvq = fsvq; w->req = req; @@ -947,14 +947,14 @@ static int virtio_fs_setup_vqs(struct virtio_device *vdev, fs->num_request_queues = min_t(unsigned int, fs->num_request_queues, nr_cpu_ids); fs->nvqs = VQ_REQUEST + fs->num_request_queues; - fs->vqs = kcalloc(fs->nvqs, sizeof(fs->vqs[VQ_HIPRIO]), GFP_KERNEL); + fs->vqs = kzalloc_objs(fs->vqs[VQ_HIPRIO], fs->nvqs); if (!fs->vqs) return -ENOMEM; - vqs = kmalloc_array(fs->nvqs, sizeof(vqs[VQ_HIPRIO]), GFP_KERNEL); + vqs = kmalloc_objs(vqs[VQ_HIPRIO], fs->nvqs); fs->mq_map = kcalloc_node(nr_cpu_ids, sizeof(*fs->mq_map), GFP_KERNEL, dev_to_node(&vdev->dev)); - vqs_info = kcalloc(fs->nvqs, sizeof(*vqs_info), GFP_KERNEL); + vqs_info = kzalloc_objs(*vqs_info, fs->nvqs); if (!vqs || !vqs_info || !fs->mq_map) { ret = -ENOMEM; goto out; @@ -1120,7 +1120,7 @@ static int virtio_fs_probe(struct virtio_device *vdev) struct virtio_fs *fs; int ret; - fs = kzalloc(sizeof(*fs), GFP_KERNEL); + fs = kzalloc_obj(*fs); if (!fs) return -ENOMEM; kobject_init(&fs->kobj, &virtio_fs_ktype); @@ -1240,7 +1240,7 @@ static void virtio_fs_send_forget(struct fuse_iqueue *fiq, struct fuse_forget_li u64 unique = fuse_get_unique(fiq); /* Allocate a buffer for the request */ - forget = kmalloc(sizeof(*forget), GFP_NOFS | __GFP_NOFAIL); + forget = kmalloc_obj(*forget, GFP_NOFS | __GFP_NOFAIL); req = &forget->req; req->ih = (struct fuse_in_header){ @@ -1390,8 +1390,8 @@ static int virtio_fs_enqueue_req(struct virtio_fs_vq *fsvq, /* Does the sglist fit on the stack? */ total_sgs = sg_count_fuse_req(req); if (total_sgs > ARRAY_SIZE(stack_sgs)) { - sgs = kmalloc_array(total_sgs, sizeof(sgs[0]), gfp); - sg = kmalloc_array(total_sgs, sizeof(sg[0]), gfp); + sgs = kmalloc_objs(sgs[0], total_sgs, gfp); + sg = kmalloc_objs(sg[0], total_sgs, gfp); if (!sgs || !sg) { ret = -ENOMEM; goto out; @@ -1684,11 +1684,11 @@ static int virtio_fs_get_tree(struct fs_context *fsc) goto out_err; err = -ENOMEM; - fc = kzalloc(sizeof(struct fuse_conn), GFP_KERNEL); + fc = kzalloc_obj(struct fuse_conn); if (!fc) goto out_err; - fm = kzalloc(sizeof(struct fuse_mount), GFP_KERNEL); + fm = kzalloc_obj(struct fuse_mount); if (!fm) goto out_err; @@ -1743,7 +1743,7 @@ static int virtio_fs_init_fs_context(struct fs_context *fsc) if (fsc->purpose == FS_CONTEXT_FOR_SUBMOUNT) return fuse_init_fs_context_submount(fsc); - ctx = kzalloc(sizeof(struct fuse_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct fuse_fs_context); if (!ctx) return -ENOMEM; fsc->fs_private = ctx; diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index fdcac8e3f2ba..1cd8ec0bce83 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c @@ -2225,7 +2225,7 @@ static int gfs2_add_jextent(struct gfs2_jdesc *jd, u64 lblock, u64 dblock, u64 b } } - jext = kzalloc(sizeof(struct gfs2_journal_extent), GFP_NOFS); + jext = kzalloc_obj(struct gfs2_journal_extent, GFP_NOFS); if (jext == NULL) return -ENOMEM; jext->dblock = dblock; diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 509e2f0d97e7..022dbb31e0d9 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -1593,7 +1593,7 @@ int gfs2_dir_read(struct inode *inode, struct dir_context *ctx, error = -ENOMEM; /* 96 is max number of dirents which can be stuffed into an inode */ - darr = kmalloc_array(96, sizeof(struct gfs2_dirent *), GFP_NOFS); + darr = kmalloc_objs(struct gfs2_dirent *, 96, GFP_NOFS); if (darr) { g.pdent = (const struct gfs2_dirent **)darr; g.offset = 0; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 3e061e8115ec..9704f1ef6ad1 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -637,7 +637,7 @@ int gfs2_open_common(struct inode *inode, struct file *file) file->f_mode |= FMODE_CAN_ODIRECT; } - fp = kzalloc(sizeof(struct gfs2_file), GFP_NOFS); + fp = kzalloc_obj(struct gfs2_file, GFP_NOFS); if (!fp) return -ENOMEM; @@ -1029,7 +1029,7 @@ static ssize_t gfs2_file_buffered_write(struct kiocb *iocb, */ if (inode == sdp->sd_rindex) { - statfs_gh = kmalloc(sizeof(*statfs_gh), GFP_NOFS); + statfs_gh = kmalloc_obj(*statfs_gh, GFP_NOFS); if (!statfs_gh) return -ENOMEM; } diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 6fb2731e8be1..2acbabccc8ad 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1764,8 +1764,7 @@ int gfs2_glock_nq_m(unsigned int num_gh, struct gfs2_holder *ghs) default: if (num_gh <= 4) break; - pph = kmalloc_array(num_gh, sizeof(struct gfs2_holder *), - GFP_NOFS); + pph = kmalloc_objs(struct gfs2_holder *, num_gh, GFP_NOFS); if (!pph) return -ENOMEM; } diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c7d57de7c8f0..9b9e70f14d25 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -76,7 +76,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) { struct gfs2_sbd *sdp; - sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL); + sdp = kzalloc_obj(struct gfs2_sbd); if (!sdp) return NULL; @@ -562,7 +562,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) break; error = -ENOMEM; - jd = kzalloc(sizeof(struct gfs2_jdesc), GFP_KERNEL); + jd = kzalloc_obj(struct gfs2_jdesc); if (!jd) break; @@ -631,7 +631,7 @@ static int init_statfs(struct gfs2_sbd *sdp) * per_node metafs directory and save it in the sdp->sd_sc_inodes_list. */ list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { struct local_statfs_inode *lsi = - kmalloc(sizeof(struct local_statfs_inode), GFP_NOFS); + kmalloc_obj(struct local_statfs_inode, GFP_NOFS); if (!lsi) { error = -ENOMEM; goto free_local; @@ -1637,7 +1637,7 @@ static int gfs2_init_fs_context(struct fs_context *fc) { struct gfs2_args *args; - args = kmalloc(sizeof(*args), GFP_KERNEL); + args = kmalloc_obj(*args); if (args == NULL) return -ENOMEM; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 1c3455093ae8..5290865f27f1 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -908,7 +908,7 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda, gfs2_write_calc_reserv(ip, sizeof(struct gfs2_quota), &data_blocks, &ind_blocks); - ghs = kmalloc_array(num_qd, sizeof(struct gfs2_holder), GFP_NOFS); + ghs = kmalloc_objs(struct gfs2_holder, num_qd, GFP_NOFS); if (!ghs) return -ENOMEM; @@ -1318,7 +1318,7 @@ int gfs2_quota_sync(struct super_block *sb, int type) if (sb_rdonly(sdp->sd_vfs)) return 0; - qda = kcalloc(max_qd, sizeof(struct gfs2_quota_data *), GFP_KERNEL); + qda = kzalloc_objs(struct gfs2_quota_data *, max_qd); if (!qda) return -ENOMEM; diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 8c8202c68b64..616c46aa3434 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -69,7 +69,7 @@ int gfs2_revoke_add(struct gfs2_jdesc *jd, u64 blkno, unsigned int where) return 0; } - rr = kmalloc(sizeof(struct gfs2_revoke_replay), GFP_NOFS); + rr = kmalloc_obj(struct gfs2_revoke_replay, GFP_NOFS); if (!rr) return -ENOMEM; diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 8a97ca734afc..441774cc07ce 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -763,7 +763,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) if (!length) return -EINVAL; - rgd->rd_bits = kcalloc(length, sizeof(struct gfs2_bitmap), GFP_NOFS); + rgd->rd_bits = kzalloc_objs(struct gfs2_bitmap, length, GFP_NOFS); if (!rgd->rd_bits) return -ENOMEM; @@ -2699,8 +2699,8 @@ void gfs2_rlist_add(struct gfs2_inode *ip, struct gfs2_rgrp_list *rlist, if (rlist->rl_rgrps == rlist->rl_space) { new_space = rlist->rl_space + 10; - tmp = kcalloc(new_space, sizeof(struct gfs2_rgrpd *), - GFP_NOFS | __GFP_NOFAIL); + tmp = kzalloc_objs(struct gfs2_rgrpd *, new_space, + GFP_NOFS | __GFP_NOFAIL); if (rlist->rl_rgd) { memcpy(tmp, rlist->rl_rgd, @@ -2731,9 +2731,8 @@ void gfs2_rlist_alloc(struct gfs2_rgrp_list *rlist, { unsigned int x; - rlist->rl_ghs = kmalloc_array(rlist->rl_rgrps, - sizeof(struct gfs2_holder), - GFP_NOFS | __GFP_NOFAIL); + rlist->rl_ghs = kmalloc_objs(struct gfs2_holder, rlist->rl_rgrps, + GFP_NOFS | __GFP_NOFAIL); for (x = 0; x < rlist->rl_rgrps; x++) gfs2_holder_init(rlist->rl_rgd[x]->rd_gl, state, flags, &rlist->rl_ghs[x]); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index d96160636161..bc191b55b18e 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -336,7 +336,7 @@ static int gfs2_lock_fs_check_clean(struct gfs2_sbd *sdp) */ list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { - lfcc = kmalloc(sizeof(struct lfcc), GFP_KERNEL); + lfcc = kmalloc_obj(struct lfcc); if (!lfcc) { error = -ENOMEM; goto out; @@ -860,7 +860,7 @@ static int gfs2_statfs_slow(struct gfs2_sbd *sdp, struct gfs2_statfs_change_host int error = 0, err; memset(sc, 0, sizeof(struct gfs2_statfs_change_host)); - gha = kmalloc_array(slots, sizeof(struct gfs2_holder), GFP_KERNEL); + gha = kmalloc_objs(struct gfs2_holder, slots); if (!gha) return -ENOMEM; for (x = 0; x < slots; x++) diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index df9c93de94c7..b9f48d6f10a9 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c @@ -467,7 +467,7 @@ static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea, unsigned char *pos; unsigned cp_size; - bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS); + bh = kzalloc_objs(struct buffer_head *, nptrs, GFP_NOFS); if (!bh) return -ENOMEM; diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 7bc425283d49..2eb37a2f64e8 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c @@ -28,7 +28,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke sector_t start_block; loff_t offset; - tree = kzalloc(sizeof(*tree), GFP_KERNEL); + tree = kzalloc_obj(*tree); if (!tree) return NULL; diff --git a/fs/hfs/dir.c b/fs/hfs/dir.c index 0c615c078650..f5e7efe924e7 100644 --- a/fs/hfs/dir.c +++ b/fs/hfs/dir.c @@ -148,7 +148,7 @@ static int hfs_readdir(struct file *file, struct dir_context *ctx) } rd = file->private_data; if (!rd) { - rd = kmalloc(sizeof(struct hfs_readdir_data), GFP_KERNEL); + rd = kmalloc_obj(struct hfs_readdir_data); if (!rd) { err = -ENOMEM; goto out; diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 97546d6b41f4..a4f2a2bfa6d3 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -411,7 +411,7 @@ static int hfs_init_fs_context(struct fs_context *fc) { struct hfs_sb_info *hsb; - hsb = kzalloc(sizeof(struct hfs_sb_info), GFP_KERNEL); + hsb = kzalloc_obj(struct hfs_sb_info); if (!hsb) return -ENOMEM; diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 229f25dc7c49..1220a2f22737 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -139,7 +139,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) struct page *page; unsigned int size; - tree = kzalloc(sizeof(*tree), GFP_KERNEL); + tree = kzalloc_obj(*tree); if (!tree) return NULL; diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index ca5f74a140ec..d559bf8625f8 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -263,7 +263,7 @@ static int hfsplus_readdir(struct file *file, struct dir_context *ctx) } rd = file->private_data; if (!rd) { - rd = kmalloc(sizeof(struct hfsplus_readdir_data), GFP_KERNEL); + rd = kmalloc_obj(struct hfsplus_readdir_data); if (!rd) { err = -ENOMEM; goto out; diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 592d8fbb748c..7229a8ae89f9 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -698,7 +698,7 @@ static int hfsplus_init_fs_context(struct fs_context *fc) { struct hfsplus_sb_info *sbi; - sbi = kzalloc(sizeof(struct hfsplus_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct hfsplus_sb_info); if (!sbi) return -ENOMEM; diff --git a/fs/hfsplus/unicode_test.c b/fs/hfsplus/unicode_test.c index 5a7a6859efe3..26145bf88946 100644 --- a/fs/hfsplus/unicode_test.c +++ b/fs/hfsplus/unicode_test.c @@ -22,7 +22,7 @@ static struct test_mock_string_env *setup_mock_str_env(u32 buf_size) { struct test_mock_string_env *env; - env = kzalloc(sizeof(struct test_mock_string_env), GFP_KERNEL); + env = kzalloc_obj(struct test_mock_string_env); if (!env) return NULL; @@ -393,7 +393,7 @@ static struct test_mock_sb *setup_mock_sb(void) { struct test_mock_sb *ptr; - ptr = kzalloc(sizeof(struct test_mock_sb), GFP_KERNEL); + ptr = kzalloc_obj(struct test_mock_sb); if (!ptr) return NULL; diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index 51d26aa2b93e..abe86d72d9ef 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c @@ -1047,7 +1047,7 @@ static int hostfs_init_fs_context(struct fs_context *fc) { struct hostfs_fs_info *fsi; - fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); + fsi = kzalloc_obj(*fsi); if (!fsi) return -ENOMEM; diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c index 4ada525c5c43..dde764ebe246 100644 --- a/fs/hpfs/dnode.c +++ b/fs/hpfs/dnode.c @@ -33,7 +33,7 @@ int hpfs_add_pos(struct inode *inode, loff_t *pos) if (hpfs_inode->i_rddir_off[i] == pos) return 0; if (!(i&0x0f)) { - ppos = kmalloc_array(i + 0x11, sizeof(loff_t *), GFP_NOFS); + ppos = kmalloc_objs(loff_t *, i + 0x11, GFP_NOFS); if (!ppos) { pr_err("out of memory for position list\n"); return -ENOMEM; diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c index 371aa6de8075..c16d5d4caead 100644 --- a/fs/hpfs/super.c +++ b/fs/hpfs/super.c @@ -513,7 +513,7 @@ static int hpfs_fill_super(struct super_block *s, struct fs_context *fc) struct hpfs_dirent *de = NULL; struct quad_buffer_head qbh; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) { return -ENOMEM; } @@ -715,7 +715,7 @@ static int hpfs_init_fs_context(struct fs_context *fc) { struct hpfs_fc_context *ctx; - ctx = kzalloc(sizeof(struct hpfs_fc_context), GFP_KERNEL); + ctx = kzalloc_obj(struct hpfs_fc_context); if (!ctx) return -ENOMEM; diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 3b4c152c5c73..3f70c47981de 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -109,7 +109,7 @@ static int hugetlbfs_file_mmap_prepare(struct vm_area_desc *desc) loff_t len, vma_len; int ret; struct hstate *h = hstate_file(file); - vm_flags_t vm_flags; + vma_flags_t vma_flags; /* * vma address alignment (but not the pgoff alignment) has @@ -119,7 +119,7 @@ static int hugetlbfs_file_mmap_prepare(struct vm_area_desc *desc) * way when do_mmap unwinds (may be important on powerpc * and ia64). */ - desc->vm_flags |= VM_HUGETLB | VM_DONTEXPAND; + vma_desc_set_flags(desc, VMA_HUGETLB_BIT, VMA_DONTEXPAND_BIT); desc->vm_ops = &hugetlb_vm_ops; /* @@ -148,23 +148,23 @@ static int hugetlbfs_file_mmap_prepare(struct vm_area_desc *desc) ret = -ENOMEM; - vm_flags = desc->vm_flags; + vma_flags = desc->vma_flags; /* * for SHM_HUGETLB, the pages are reserved in the shmget() call so skip * reserving here. Note: only for SHM hugetlbfs file, the inode * flag S_PRIVATE is set. */ if (inode->i_flags & S_PRIVATE) - vm_flags |= VM_NORESERVE; + vma_flags_set(&vma_flags, VMA_NORESERVE_BIT); if (hugetlb_reserve_pages(inode, desc->pgoff >> huge_page_order(h), len >> huge_page_shift(h), desc, - vm_flags) < 0) + vma_flags) < 0) goto out; ret = 0; - if ((desc->vm_flags & VM_WRITE) && inode->i_size < len) + if (vma_desc_test_flags(desc, VMA_WRITE_BIT) && inode->i_size < len) i_size_write(inode, len); out: inode_unlock(inode); @@ -1407,7 +1407,7 @@ hugetlbfs_fill_super(struct super_block *sb, struct fs_context *fc) struct hugetlbfs_fs_context *ctx = fc->fs_private; struct hugetlbfs_sb_info *sbinfo; - sbinfo = kmalloc(sizeof(struct hugetlbfs_sb_info), GFP_KERNEL); + sbinfo = kmalloc_obj(struct hugetlbfs_sb_info); if (!sbinfo) return -ENOMEM; sb->s_fs_info = sbinfo; @@ -1478,7 +1478,7 @@ static int hugetlbfs_init_fs_context(struct fs_context *fc) { struct hugetlbfs_fs_context *ctx; - ctx = kzalloc(sizeof(struct hugetlbfs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct hugetlbfs_fs_context); if (!ctx) return -ENOMEM; @@ -1527,7 +1527,7 @@ static int get_hstate_idx(int page_size_log) * otherwise hugetlb_reserve_pages reserves one less hugepages than intended. */ struct file *hugetlb_file_setup(const char *name, size_t size, - vm_flags_t acctflag, int creat_flags, + vma_flags_t acctflag, int creat_flags, int page_size_log) { struct inode *inode; diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index 1fe19b4ee2f4..00f0efaf12b2 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -80,18 +80,27 @@ static void iomap_set_range_uptodate(struct folio *folio, size_t off, { struct iomap_folio_state *ifs = folio->private; unsigned long flags; - bool uptodate = true; + bool mark_uptodate = true; if (folio_test_uptodate(folio)) return; if (ifs) { spin_lock_irqsave(&ifs->state_lock, flags); - uptodate = ifs_set_range_uptodate(folio, ifs, off, len); + /* + * If a read with bytes pending is in progress, we must not call + * folio_mark_uptodate(). The read completion path + * (iomap_read_end()) will call folio_end_read(), which uses XOR + * semantics to set the uptodate bit. If we set it here, the XOR + * in folio_end_read() will clear it, leaving the folio not + * uptodate. + */ + mark_uptodate = ifs_set_range_uptodate(folio, ifs, off, len) && + !ifs->read_bytes_pending; spin_unlock_irqrestore(&ifs->state_lock, flags); } - if (uptodate) + if (mark_uptodate) folio_mark_uptodate(folio); } @@ -229,8 +238,7 @@ static struct iomap_folio_state *ifs_alloc(struct inode *inode, * The first state tracks per-block uptodate and the * second tracks per-block dirty state. */ - ifs = kzalloc(struct_size(ifs, state, - BITS_TO_LONGS(2 * nr_blocks)), gfp); + ifs = kzalloc_flex(*ifs, state, BITS_TO_LONGS(2 * nr_blocks), gfp); if (!ifs) return ifs; @@ -625,6 +633,7 @@ static int iomap_readahead_iter(struct iomap_iter *iter, * iomap_readahead - Attempt to read pages from a file. * @ops: The operations vector for the filesystem. * @ctx: The ctx used for issuing readahead. + * @private: The filesystem-specific information for issuing iomap_iter. * * This function is for filesystems to call to implement their readahead * address_space operation. diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c index 8c1fd7573aee..e911daedff65 100644 --- a/fs/iomap/direct-io.c +++ b/fs/iomap/direct-io.c @@ -87,6 +87,19 @@ static inline enum fserror_type iomap_dio_err_type(const struct iomap_dio *dio) return FSERR_DIRECTIO_READ; } +static inline bool should_report_dio_fserror(const struct iomap_dio *dio) +{ + switch (dio->error) { + case 0: + case -EAGAIN: + case -ENOTBLK: + /* don't send fsnotify for success or magic retry codes */ + return false; + default: + return true; + } +} + ssize_t iomap_dio_complete(struct iomap_dio *dio) { const struct iomap_dio_ops *dops = dio->dops; @@ -96,7 +109,7 @@ ssize_t iomap_dio_complete(struct iomap_dio *dio) if (dops && dops->end_io) ret = dops->end_io(iocb, dio->size, ret, dio->flags); - if (dio->error) + if (should_report_dio_fserror(dio)) fserror_report_io(file_inode(iocb->ki_filp), iomap_dio_err_type(dio), offset, dio->size, dio->error, GFP_NOFS); @@ -677,7 +690,7 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, if (!iomi.len) return NULL; - dio = kmalloc(sizeof(*dio), GFP_KERNEL); + dio = kmalloc_obj(*dio); if (!dio) return ERR_PTR(-ENOMEM); diff --git a/fs/iomap/ioend.c b/fs/iomap/ioend.c index e4d57cb969f1..60546fa14dfe 100644 --- a/fs/iomap/ioend.c +++ b/fs/iomap/ioend.c @@ -69,11 +69,57 @@ static u32 iomap_finish_ioend_buffered(struct iomap_ioend *ioend) return folio_count; } +static DEFINE_SPINLOCK(failed_ioend_lock); +static LIST_HEAD(failed_ioend_list); + +static void +iomap_fail_ioends( + struct work_struct *work) +{ + struct iomap_ioend *ioend; + struct list_head tmp; + unsigned long flags; + + spin_lock_irqsave(&failed_ioend_lock, flags); + list_replace_init(&failed_ioend_list, &tmp); + spin_unlock_irqrestore(&failed_ioend_lock, flags); + + while ((ioend = list_first_entry_or_null(&tmp, struct iomap_ioend, + io_list))) { + list_del_init(&ioend->io_list); + iomap_finish_ioend_buffered(ioend); + cond_resched(); + } +} + +static DECLARE_WORK(failed_ioend_work, iomap_fail_ioends); + +static void iomap_fail_ioend_buffered(struct iomap_ioend *ioend) +{ + unsigned long flags; + + /* + * Bounce I/O errors to a workqueue to avoid nested i_lock acquisitions + * in the fserror code. The caller no longer owns the ioend reference + * after the spinlock drops. + */ + spin_lock_irqsave(&failed_ioend_lock, flags); + if (list_empty(&failed_ioend_list)) + WARN_ON_ONCE(!schedule_work(&failed_ioend_work)); + list_add_tail(&ioend->io_list, &failed_ioend_list); + spin_unlock_irqrestore(&failed_ioend_lock, flags); +} + static void ioend_writeback_end_bio(struct bio *bio) { struct iomap_ioend *ioend = iomap_ioend_from_bio(bio); ioend->io_error = blk_status_to_errno(bio->bi_status); + if (ioend->io_error) { + iomap_fail_ioend_buffered(ioend); + return; + } + iomap_finish_ioend_buffered(ioend); } @@ -169,17 +215,18 @@ ssize_t iomap_add_to_ioend(struct iomap_writepage_ctx *wpc, struct folio *folio, WARN_ON_ONCE(!folio->private && map_len < dirty_len); switch (wpc->iomap.type) { - case IOMAP_INLINE: - WARN_ON_ONCE(1); - return -EIO; + case IOMAP_UNWRITTEN: + ioend_flags |= IOMAP_IOEND_UNWRITTEN; + break; + case IOMAP_MAPPED: + break; case IOMAP_HOLE: return map_len; default: - break; + WARN_ON_ONCE(1); + return -EIO; } - if (wpc->iomap.type == IOMAP_UNWRITTEN) - ioend_flags |= IOMAP_IOEND_UNWRITTEN; if (wpc->iomap.flags & IOMAP_F_SHARED) ioend_flags |= IOMAP_IOEND_SHARED; if (folio_test_dropbehind(folio)) diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c index 5f3b6da0e022..50b4cb3aea87 100644 --- a/fs/isofs/compress.c +++ b/fs/isofs/compress.c @@ -75,7 +75,7 @@ static loff_t zisofs_uncompress_block(struct inode *inode, loff_t block_start, /* Because zlib is not thread-safe, do all the I/O at the top. */ blocknum = block_start >> bufshift; - bhs = kcalloc(needblocks + 1, sizeof(*bhs), GFP_KERNEL); + bhs = kzalloc_objs(*bhs, needblocks + 1); if (!bhs) { *errp = -ENOMEM; return 0; @@ -333,8 +333,8 @@ static int zisofs_read_folio(struct file *file, struct folio *folio) full_page = 0; pcount = 1; } - pages = kcalloc(max_t(unsigned int, zisofs_pages_per_cblock, 1), - sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, + max_t(unsigned int, zisofs_pages_per_cblock, 1)); if (!pages) { folio_unlock(folio); return -ENOMEM; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index b7cbe126faf3..5c01536c5e8f 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -589,7 +589,7 @@ static int isofs_fill_super(struct super_block *s, struct fs_context *fc) unsigned int vol_desc_start; int silent = fc->sb_flags & SB_SILENT; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; s->s_fs_info = sbi; @@ -1557,7 +1557,7 @@ static int isofs_init_fs_context(struct fs_context *fc) { struct isofs_options *opt; - opt = kzalloc(sizeof(*opt), GFP_KERNEL); + opt = kzalloc_obj(*opt); if (!opt) return -ENOMEM; diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index c973162d5b31..cb2c529a8f1b 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -1175,7 +1175,7 @@ static int jbd2_seq_info_open(struct inode *inode, struct file *file) struct jbd2_stats_proc_session *s; int rc, size; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (s == NULL) return -ENOMEM; size = sizeof(struct transaction_stats_s); @@ -1525,7 +1525,7 @@ static journal_t *journal_init_common(struct block_device *bdev, int err; int n; - journal = kzalloc(sizeof(*journal), GFP_KERNEL); + journal = kzalloc_obj(*journal); if (!journal) return ERR_PTR(-ENOMEM); @@ -1578,8 +1578,7 @@ static journal_t *journal_init_common(struct block_device *bdev, n = journal->j_blocksize / jbd2_min_tag_size(); journal->j_wbufsize = n; journal->j_fc_wbuf = NULL; - journal->j_wbuf = kmalloc_array(n, sizeof(struct buffer_head *), - GFP_KERNEL); + journal->j_wbuf = kmalloc_objs(struct buffer_head *, n); if (!journal->j_wbuf) goto err_cleanup; @@ -2269,8 +2268,7 @@ jbd2_journal_initialize_fast_commit(journal_t *journal) /* Are we called twice? */ WARN_ON(journal->j_fc_wbuf != NULL); - journal->j_fc_wbuf = kmalloc_array(num_fc_blks, - sizeof(struct buffer_head *), GFP_KERNEL); + journal->j_fc_wbuf = kmalloc_objs(struct buffer_head *, num_fc_blks); if (!journal->j_fc_wbuf) return -ENOMEM; diff --git a/fs/jbd2/revoke.c b/fs/jbd2/revoke.c index 1467f6790747..9016ddb82447 100644 --- a/fs/jbd2/revoke.c +++ b/fs/jbd2/revoke.c @@ -231,7 +231,7 @@ struct jbd2_revoke_table_s *jbd2_journal_init_revoke_table(int hash_size) table->hash_size = hash_size; table->hash_shift = shift; table->hash_table = - kvmalloc_array(hash_size, sizeof(struct list_head), GFP_KERNEL); + kvmalloc_objs(struct list_head, hash_size); if (!table->hash_table) { kmem_cache_free(jbd2_revoke_table_cache, table); table = NULL; diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 888a7ceb6479..f0f8a4f57add 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -133,8 +133,7 @@ static void *jffs2_acl_to_medium(const struct posix_acl *acl, size_t *size) size_t i; *size = jffs2_acl_size(acl->a_count); - header = kmalloc(struct_size(header, a_entries, acl->a_count), - GFP_KERNEL); + header = kmalloc_flex(*header, a_entries, acl->a_count); if (!header) return ERR_PTR(-ENOMEM); header->a_version = cpu_to_je32(JFFS2_ACL_VERSION); diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c index fda9f4d6093f..a99ee831bab8 100644 --- a/fs/jffs2/erase.c +++ b/fs/jffs2/erase.c @@ -43,7 +43,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c, jffs2_dbg(1, "%s(): erase block %#08x (range %#08x-%#08x)\n", __func__, jeb->offset, jeb->offset, jeb->offset + c->sector_size); - instr = kzalloc(sizeof(struct erase_info), GFP_KERNEL); + instr = kzalloc_obj(struct erase_info); if (!instr) { pr_warn("kzalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); mutex_lock(&c->erase_free_sem); diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 764bba8ba999..c3ce2c868f7a 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -562,7 +562,8 @@ int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc) return ret; c->inocache_hashsize = calculate_inocache_hashsize(c->flash_size); - c->inocache_list = kcalloc(c->inocache_hashsize, sizeof(struct jffs2_inode_cache *), GFP_KERNEL); + c->inocache_list = kzalloc_objs(struct jffs2_inode_cache *, + c->inocache_hashsize); if (!c->inocache_list) { ret = -ENOMEM; goto out_wbuf; diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index f987f78a894e..1caabff9dc91 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c @@ -1392,7 +1392,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { struct jffs2_raw_inode n; - struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL); + struct jffs2_inode_info *f = kzalloc_obj(*f); int ret; if (!f) diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 62879c218d4b..06e494797724 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c @@ -132,7 +132,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c) } if (jffs2_sum_active()) { - s = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); + s = kzalloc_obj(struct jffs2_summary); if (!s) { JFFS2_WARNING("Can't allocate memory for summary\n"); ret = -ENOMEM; diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c index d83372d3e1a0..4521a7723f30 100644 --- a/fs/jffs2/summary.c +++ b/fs/jffs2/summary.c @@ -27,7 +27,7 @@ int jffs2_sum_init(struct jffs2_sb_info *c) { uint32_t sum_size = min_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE); - c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); + c->summary = kzalloc_obj(struct jffs2_summary); if (!c->summary) { JFFS2_WARNING("Can't allocate memory for summary information!\n"); @@ -115,7 +115,7 @@ int jffs2_sum_add_padding_mem(struct jffs2_summary *s, uint32_t size) int jffs2_sum_add_inode_mem(struct jffs2_summary *s, struct jffs2_raw_inode *ri, uint32_t ofs) { - struct jffs2_sum_inode_mem *temp = kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL); + struct jffs2_sum_inode_mem *temp = kmalloc_obj(struct jffs2_sum_inode_mem); if (!temp) return -ENOMEM; @@ -159,7 +159,7 @@ int jffs2_sum_add_xattr_mem(struct jffs2_summary *s, struct jffs2_raw_xattr *rx, { struct jffs2_sum_xattr_mem *temp; - temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL); + temp = kmalloc_obj(struct jffs2_sum_xattr_mem); if (!temp) return -ENOMEM; @@ -177,7 +177,7 @@ int jffs2_sum_add_xref_mem(struct jffs2_summary *s, struct jffs2_raw_xref *rr, u { struct jffs2_sum_xref_mem *temp; - temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL); + temp = kmalloc_obj(struct jffs2_sum_xref_mem); if (!temp) return -ENOMEM; @@ -263,7 +263,7 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, switch (je16_to_cpu(node->u.nodetype)) { case JFFS2_NODETYPE_INODE: { struct jffs2_sum_inode_mem *temp = - kmalloc(sizeof(struct jffs2_sum_inode_mem), GFP_KERNEL); + kmalloc_obj(struct jffs2_sum_inode_mem); if (!temp) goto no_mem; @@ -314,7 +314,7 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, #ifdef CONFIG_JFFS2_FS_XATTR case JFFS2_NODETYPE_XATTR: { struct jffs2_sum_xattr_mem *temp; - temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL); + temp = kmalloc_obj(struct jffs2_sum_xattr_mem); if (!temp) goto no_mem; @@ -329,7 +329,7 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs, } case JFFS2_NODETYPE_XREF: { struct jffs2_sum_xref_mem *temp; - temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL); + temp = kmalloc_obj(struct jffs2_sum_xref_mem); if (!temp) goto no_mem; temp->nodetype = node->r.nodetype; diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 4545f885c41e..81396a092ba8 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -311,7 +311,7 @@ static int jffs2_init_fs_context(struct fs_context *fc) { struct jffs2_sb_info *ctx; - ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL); + ctx = kzalloc_obj(struct jffs2_sb_info); if (!ctx) return -ENOMEM; diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index 3ab3f0ff7ebb..8ff7a0b6add2 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c @@ -92,7 +92,7 @@ static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino) if (jffs2_wbuf_pending_for_ino(c, ino)) return; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) { jffs2_dbg(1, "No memory to allocate inodirty. Fallback to all considered dirty\n"); jffs2_clear_wbuf_ino_list(c); diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index defb4162c3d5..6b4f68593c29 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -784,8 +784,7 @@ int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); - xref_tmphash = kcalloc(XREF_TMPHASH_SIZE, - sizeof(struct jffs2_xattr_ref *), GFP_KERNEL); + xref_tmphash = kzalloc_objs(struct jffs2_xattr_ref *, XREF_TMPHASH_SIZE); if (!xref_tmphash) return -ENOMEM; diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index cdfa699cd7c8..2abe8cc02ee6 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -161,7 +161,7 @@ int dbMount(struct inode *ipbmap) * allocate/initialize the in-memory bmap descriptor */ /* allocate memory for the in-memory bmap descriptor */ - bmp = kmalloc(sizeof(struct bmap), GFP_KERNEL); + bmp = kmalloc_obj(struct bmap); if (bmp == NULL) return -ENOMEM; @@ -1593,7 +1593,7 @@ s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen) max_ranges = nblocks; do_div(max_ranges, minlen); range_cnt = min_t(u64, max_ranges + 1, 32 * 1024); - totrim = kmalloc_array(range_cnt, sizeof(struct range2trim), GFP_NOFS); + totrim = kmalloc_objs(struct range2trim, range_cnt, GFP_NOFS); if (totrim == NULL) { jfs_error(bmp->db_ipbmap->i_sb, "no memory for trim array\n"); IWRITE_UNLOCK(ipbmap); diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index ecb8e05b8b84..294a67327c73 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -102,7 +102,7 @@ int diMount(struct inode *ipimap) * allocate/initialize the in-memory inode map control structure */ /* allocate the in-memory inode map control structure. */ - imap = kzalloc(sizeof(struct inomap), GFP_KERNEL); + imap = kzalloc_obj(struct inomap); if (imap == NULL) return -ENOMEM; diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 5b1c5da04163..ada00d5bc214 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1087,7 +1087,7 @@ int lmLogOpen(struct super_block *sb) } } - if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) { + if (!(log = kzalloc_obj(struct jfs_log))) { mutex_unlock(&jfs_log_mutex); return -ENOMEM; } @@ -1156,7 +1156,7 @@ static int open_inline_log(struct super_block *sb) struct jfs_log *log; int rc; - if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) + if (!(log = kzalloc_obj(struct jfs_log))) return -ENOMEM; INIT_LIST_HEAD(&log->sb_list); init_waitqueue_head(&log->syncwait); @@ -1190,7 +1190,7 @@ static int open_dummy_log(struct super_block *sb) mutex_lock(&jfs_log_mutex); if (!dummy_log) { - dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL); + dummy_log = kzalloc_obj(struct jfs_log); if (!dummy_log) { mutex_unlock(&jfs_log_mutex); return -ENOMEM; @@ -1818,7 +1818,7 @@ static int lbmLogInit(struct jfs_log * log) goto error; buffer = page_address(page); for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) { - lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL); + lbuf = kmalloc_obj(struct lbuf); if (lbuf == NULL) { if (offset == 0) __free_page(page); diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 871cf4fb3636..64c6eaa7f3f2 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -98,7 +98,7 @@ static inline int insert_metapage(struct folio *folio, struct metapage *mp) a = folio->private; if (!a) { - a = kzalloc(sizeof(struct meta_anchor), GFP_NOFS); + a = kzalloc_obj(struct meta_anchor, GFP_NOFS); if (!a) return -ENOMEM; folio_attach_private(folio, a); diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 3cfb86c5a36e..61575f7397ae 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -449,7 +449,7 @@ static int jfs_fill_super(struct super_block *sb, struct fs_context *fc) jfs_info("In jfs_read_super: s_flags=0x%lx", sb->s_flags); - sbi = kzalloc(sizeof(struct jfs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct jfs_sb_info); if (!sbi) return -ENOMEM; @@ -912,7 +912,7 @@ static int jfs_init_fs_context(struct fs_context *fc) { struct jfs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 29baeeb97871..8d40c4b1db9f 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -989,7 +989,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, struct kernfs_root *root; struct kernfs_node *kn; - root = kzalloc(sizeof(*root), GFP_KERNEL); + root = kzalloc_obj(*root); if (!root) return ERR_PTR(-ENOMEM); diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c index 9adf36e6364b..e32406d62c0d 100644 --- a/fs/kernfs/file.c +++ b/fs/kernfs/file.c @@ -540,7 +540,7 @@ static int kernfs_get_open_node(struct kernfs_node *kn, if (!on) { /* not there, initialize a new one */ - on = kzalloc(sizeof(*on), GFP_KERNEL); + on = kzalloc_obj(*on); if (!on) { mutex_unlock(mutex); return -ENOMEM; @@ -638,7 +638,7 @@ static int kernfs_fop_open(struct inode *inode, struct file *file) /* allocate a kernfs_open_file for the file */ error = -ENOMEM; - of = kzalloc(sizeof(struct kernfs_open_file), GFP_KERNEL); + of = kzalloc_obj(struct kernfs_open_file); if (!of) goto err_out; diff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c index 3ac52e141766..048f00b73b71 100644 --- a/fs/kernfs/mount.c +++ b/fs/kernfs/mount.c @@ -370,7 +370,7 @@ int kernfs_get_tree(struct fs_context *fc) struct kernfs_super_info *info; int error; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; @@ -451,7 +451,7 @@ static void __init kernfs_mutex_init(void) static void __init kernfs_lock_init(void) { - kernfs_locks = kmalloc(sizeof(struct kernfs_global_locks), GFP_KERNEL); + kernfs_locks = kmalloc_obj(struct kernfs_global_locks); WARN_ON(!kernfs_locks); kernfs_mutex_init(); diff --git a/fs/libfs.c b/fs/libfs.c index f1860dff86f2..74134ba2e8d1 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -731,7 +731,7 @@ struct pseudo_fs_context *init_pseudo(struct fs_context *fc, { struct pseudo_fs_context *ctx; - ctx = kzalloc(sizeof(struct pseudo_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct pseudo_fs_context); if (likely(ctx)) { ctx->magic = magic; fc->fs_private = ctx; @@ -1320,7 +1320,7 @@ int simple_attr_open(struct inode *inode, struct file *file, { struct simple_attr *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) return -ENOMEM; diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index a7e0519ec024..85bc0f3e91df 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -233,7 +233,7 @@ reclaimer(void *ptr) u32 nsmstate; struct net *net = host->net; - req = kmalloc(sizeof(*req), GFP_KERNEL); + req = kmalloc_obj(*req); if (!req) return 0; diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index cebcc283b7ce..fb4d0752c9bb 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -105,7 +105,7 @@ static struct nlm_lockowner *nlmclnt_find_lockowner(struct nlm_host *host, fl_ow res = __nlmclnt_find_lockowner(host, owner); if (res == NULL) { spin_unlock(&host->h_lock); - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); spin_lock(&host->h_lock); res = __nlmclnt_find_lockowner(host, owner); if (res == NULL && new != NULL) { @@ -208,7 +208,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) struct nlm_rqst *call; for(;;) { - call = kzalloc(sizeof(*call), GFP_KERNEL); + call = kzalloc_obj(*call); if (call != NULL) { refcount_set(&call->a_count, 1); locks_init_lock(&call->a_args.lock.fl); diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 5e6877c37f73..1a9582a10a86 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -126,7 +126,7 @@ static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, } } - host = kmalloc(sizeof(*host), GFP_KERNEL); + host = kmalloc_obj(*host); if (unlikely(host == NULL)) { dprintk("lockd: %s failed; no memory\n", __func__); nsm_release(nsm); diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 712df1e025d8..255a847ca0b6 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -233,7 +233,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host, return NULL; /* Allocate memory for block, and initialize arguments */ - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (block == NULL) goto failed; kref_init(&block->b_count); @@ -380,7 +380,7 @@ static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t if (res == NULL) { spin_unlock(&host->h_lock); - new = kmalloc(sizeof(*res), GFP_KERNEL); + new = kmalloc_obj(*res); spin_lock(&host->h_lock); res = __nlmsvc_find_lockowner(host, pid); if (res == NULL && new != NULL) { diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 9103896164f6..dd0214dcb695 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -128,7 +128,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, nlm_debug_print_fh("creating file for", &lock->fh); nfserr = nlm_lck_denied_nolocks; - file = kzalloc(sizeof(*file), GFP_KERNEL); + file = kzalloc_obj(*file); if (!file) goto out_free; diff --git a/fs/mbcache.c b/fs/mbcache.c index e60a840999aa..480d02d6ebf0 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -358,16 +358,14 @@ struct mb_cache *mb_cache_create(int bucket_bits) unsigned long bucket_count = 1UL << bucket_bits; unsigned long i; - cache = kzalloc(sizeof(struct mb_cache), GFP_KERNEL); + cache = kzalloc_obj(struct mb_cache); if (!cache) goto err_out; cache->c_bucket_bits = bucket_bits; cache->c_max_entries = bucket_count << 4; INIT_LIST_HEAD(&cache->c_list); spin_lock_init(&cache->c_list_lock); - cache->c_hash = kmalloc_array(bucket_count, - sizeof(struct hlist_bl_head), - GFP_KERNEL); + cache->c_hash = kmalloc_objs(struct hlist_bl_head, bucket_count); if (!cache->c_hash) { kfree(cache); goto err_out; diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c index 7da66ca184f4..abec438330a7 100644 --- a/fs/minix/bitmap.c +++ b/fs/minix/bitmap.c @@ -247,7 +247,7 @@ struct inode *minix_new_inode(const struct inode *dir, umode_t mode) j += i * bits_per_zone; if (!j || j > sbi->s_ninodes) { iput(inode); - return ERR_PTR(-ENOSPC); + return ERR_PTR(-EFSCORRUPTED); } inode_init_owner(&nop_mnt_idmap, inode, dir, mode); inode->i_ino = j; diff --git a/fs/minix/inode.c b/fs/minix/inode.c index c8c6b2135abe..99541c6a5bbf 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -226,7 +226,7 @@ static int minix_fill_super(struct super_block *s, struct fs_context *fc) int ret = -EINVAL; int silent = fc->sb_flags & SB_SILENT; - sbi = kzalloc(sizeof(struct minix_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct minix_sb_info); if (!sbi) return -ENOMEM; s->s_fs_info = sbi; diff --git a/fs/mnt_idmapping.c b/fs/mnt_idmapping.c index a37991fdb194..6472c4ea3d1e 100644 --- a/fs/mnt_idmapping.c +++ b/fs/mnt_idmapping.c @@ -289,7 +289,7 @@ struct mnt_idmap *alloc_mnt_idmap(struct user_namespace *mnt_userns) struct mnt_idmap *idmap; int ret; - idmap = kzalloc(sizeof(struct mnt_idmap), GFP_KERNEL_ACCOUNT); + idmap = kzalloc_obj(struct mnt_idmap, GFP_KERNEL_ACCOUNT); if (!idmap) return ERR_PTR(-ENOMEM); diff --git a/fs/namei.c b/fs/namei.c index 8e7792de0000..58f715f7657e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -790,8 +790,8 @@ static bool nd_alloc_stack(struct nameidata *nd) { struct saved *p; - p= kmalloc_array(MAXSYMLINKS, sizeof(struct saved), - nd->flags & LOOKUP_RCU ? GFP_ATOMIC : GFP_KERNEL); + p= kmalloc_objs(struct saved, MAXSYMLINKS, + nd->flags & LOOKUP_RCU ? GFP_ATOMIC : GFP_KERNEL); if (unlikely(!p)) return false; memcpy(p, nd->internal, sizeof(nd->internal)); @@ -3088,7 +3088,7 @@ int lookup_noperm_common(struct qstr *qname, struct dentry *base) if (!len) return -EACCES; - if (is_dot_dotdot(name, len)) + if (name_is_dot_dotdot(name, len)) return -EACCES; while (len--) { diff --git a/fs/namespace.c b/fs/namespace.c index a67cbe42746d..854f4fc66469 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -889,7 +889,7 @@ static int get_mountpoint(struct dentry *dentry, struct pinned_mountpoint *m) } if (!mp) - mp = kmalloc(sizeof(struct mountpoint), GFP_KERNEL); + mp = kmalloc_obj(struct mountpoint); if (!mp) return -ENOMEM; @@ -1531,23 +1531,33 @@ static struct mount *mnt_find_id_at_reverse(struct mnt_namespace *ns, u64 mnt_id static void *m_start(struct seq_file *m, loff_t *pos) { struct proc_mounts *p = m->private; + struct mount *mnt; down_read(&namespace_sem); - return mnt_find_id_at(p->ns, *pos); + mnt = mnt_find_id_at(p->ns, *pos); + if (mnt) + *pos = mnt->mnt_id_unique; + return mnt; } static void *m_next(struct seq_file *m, void *v, loff_t *pos) { - struct mount *next = NULL, *mnt = v; + struct mount *mnt = v; struct rb_node *node = rb_next(&mnt->mnt_node); - ++*pos; if (node) { - next = node_to_mount(node); + struct mount *next = node_to_mount(node); *pos = next->mnt_id_unique; + return next; } - return next; + + /* + * No more mounts. Set pos past current mount's ID so that if + * iteration restarts, mnt_find_id_at() returns NULL. + */ + *pos = mnt->mnt_id_unique + 1; + return NULL; } static void m_stop(struct seq_file *m, void *v) @@ -2226,7 +2236,7 @@ static inline bool extend_array(struct path **res, struct path **to_free, if (likely(n < *count)) return true; - p = kmalloc_array(new_count, sizeof(struct path), GFP_KERNEL); + p = kmalloc_objs(struct path, new_count); if (p && *count) memcpy(p, *res, *count * sizeof(struct path)); *count = new_count; @@ -2791,7 +2801,8 @@ static inline void unlock_mount(struct pinned_mountpoint *m) } static void lock_mount_exact(const struct path *path, - struct pinned_mountpoint *mp); + struct pinned_mountpoint *mp, bool copy_mount, + unsigned int copy_flags); #define LOCK_MOUNT_MAYBE_BENEATH(mp, path, beneath) \ struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \ @@ -2799,7 +2810,10 @@ static void lock_mount_exact(const struct path *path, #define LOCK_MOUNT(mp, path) LOCK_MOUNT_MAYBE_BENEATH(mp, (path), false) #define LOCK_MOUNT_EXACT(mp, path) \ struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \ - lock_mount_exact((path), &mp) + lock_mount_exact((path), &mp, false, 0) +#define LOCK_MOUNT_EXACT_COPY(mp, path, copy_flags) \ + struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \ + lock_mount_exact((path), &mp, true, (copy_flags)) static int graft_tree(struct mount *mnt, const struct pinned_mountpoint *mp) { @@ -3073,16 +3087,13 @@ static struct file *open_detached_copy(struct path *path, unsigned int flags) return file; } -DEFINE_FREE(put_empty_mnt_ns, struct mnt_namespace *, - if (!IS_ERR_OR_NULL(_T)) free_mnt_ns(_T)) - static struct mnt_namespace *create_new_namespace(struct path *path, unsigned int flags) { - struct mnt_namespace *new_ns __free(put_empty_mnt_ns) = NULL; - struct path to_path __free(path_put) = {}; struct mnt_namespace *ns = current->nsproxy->mnt_ns; struct user_namespace *user_ns = current_user_ns(); - struct mount *new_ns_root; + struct mnt_namespace *new_ns; + struct mount *new_ns_root, *old_ns_root; + struct path to_path; struct mount *mnt; unsigned int copy_flags = 0; bool locked = false; @@ -3094,71 +3105,63 @@ static struct mnt_namespace *create_new_namespace(struct path *path, unsigned in if (IS_ERR(new_ns)) return ERR_CAST(new_ns); - scoped_guard(namespace_excl) { - new_ns_root = clone_mnt(ns->root, ns->root->mnt.mnt_root, copy_flags); - if (IS_ERR(new_ns_root)) - return ERR_CAST(new_ns_root); + old_ns_root = ns->root; + to_path.mnt = &old_ns_root->mnt; + to_path.dentry = old_ns_root->mnt.mnt_root; - /* - * If the real rootfs had a locked mount on top of it somewhere - * in the stack, lock the new mount tree as well so it can't be - * exposed. - */ - mnt = ns->root; - while (mnt->overmount) { - mnt = mnt->overmount; - if (mnt->mnt.mnt_flags & MNT_LOCKED) - locked = true; - } + VFS_WARN_ON_ONCE(old_ns_root->mnt.mnt_sb->s_type != &nullfs_fs_type); + + LOCK_MOUNT_EXACT_COPY(mp, &to_path, copy_flags); + if (IS_ERR(mp.parent)) { + free_mnt_ns(new_ns); + return ERR_CAST(mp.parent); + } + new_ns_root = mp.parent; + + /* + * If the real rootfs had a locked mount on top of it somewhere + * in the stack, lock the new mount tree as well so it can't be + * exposed. + */ + mnt = old_ns_root; + while (mnt->overmount) { + mnt = mnt->overmount; + if (mnt->mnt.mnt_flags & MNT_LOCKED) + locked = true; } /* - * We dropped the namespace semaphore so we can actually lock - * the copy for mounting. The copied mount isn't attached to any - * mount namespace and it is thus excluded from any propagation. - * So realistically we're isolated and the mount can't be - * overmounted. - */ - - /* Borrow the reference from clone_mnt(). */ - to_path.mnt = &new_ns_root->mnt; - to_path.dentry = dget(new_ns_root->mnt.mnt_root); - - /* Now lock for actual mounting. */ - LOCK_MOUNT_EXACT(mp, &to_path); - if (unlikely(IS_ERR(mp.parent))) - return ERR_CAST(mp.parent); - - /* - * We don't emulate unshare()ing a mount namespace. We stick to the - * restrictions of creating detached bind-mounts. It has a lot - * saner and simpler semantics. + * We don't emulate unshare()ing a mount namespace. We stick + * to the restrictions of creating detached bind-mounts. It + * has a lot saner and simpler semantics. */ mnt = __do_loopback(path, flags, copy_flags); - if (IS_ERR(mnt)) - return ERR_CAST(mnt); - scoped_guard(mount_writer) { + if (IS_ERR(mnt)) { + emptied_ns = new_ns; + umount_tree(new_ns_root, 0); + return ERR_CAST(mnt); + } + if (locked) mnt->mnt.mnt_flags |= MNT_LOCKED; /* - * Now mount the detached tree on top of the copy of the - * real rootfs we created. + * now mount the detached tree on top of the copy + * of the real rootfs we created. */ attach_mnt(mnt, new_ns_root, mp.mp); if (user_ns != ns->user_ns) lock_mnt_tree(new_ns_root); } - /* Add all mounts to the new namespace. */ - for (struct mount *p = new_ns_root; p; p = next_mnt(p, new_ns_root)) { - mnt_add_to_ns(new_ns, p); + for (mnt = new_ns_root; mnt; mnt = next_mnt(mnt, new_ns_root)) { + mnt_add_to_ns(new_ns, mnt); new_ns->nr_mounts++; } - new_ns->root = real_mount(no_free_ptr(to_path.mnt)); + new_ns->root = new_ns_root; ns_tree_add_raw(new_ns); - return no_free_ptr(new_ns); + return new_ns; } static struct file *open_new_namespace(struct path *path, unsigned int flags) @@ -3840,16 +3843,20 @@ static int do_new_mount(const struct path *path, const char *fstype, } static void lock_mount_exact(const struct path *path, - struct pinned_mountpoint *mp) + struct pinned_mountpoint *mp, bool copy_mount, + unsigned int copy_flags) { struct dentry *dentry = path->dentry; int err; + /* Assert that inode_lock() locked the correct inode. */ + VFS_WARN_ON_ONCE(copy_mount && !path_mounted(path)); + inode_lock(dentry->d_inode); namespace_lock(); if (unlikely(cant_mount(dentry))) err = -ENOENT; - else if (path_overmounted(path)) + else if (!copy_mount && path_overmounted(path)) err = -EBUSY; else err = get_mountpoint(dentry, mp); @@ -3857,9 +3864,15 @@ static void lock_mount_exact(const struct path *path, namespace_unlock(); inode_unlock(dentry->d_inode); mp->parent = ERR_PTR(err); - } else { - mp->parent = real_mount(path->mnt); + return; } + + if (copy_mount) + mp->parent = clone_mnt(real_mount(path->mnt), dentry, copy_flags); + else + mp->parent = real_mount(path->mnt); + if (unlikely(IS_ERR(mp->parent))) + __unlock_mount(mp); } int finish_automount(struct vfsmount *__m, const struct path *path) @@ -4187,7 +4200,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns, bool a if (!ucounts) return ERR_PTR(-ENOSPC); - new_ns = kzalloc(sizeof(struct mnt_namespace), GFP_KERNEL_ACCOUNT); + new_ns = kzalloc_obj(struct mnt_namespace, GFP_KERNEL_ACCOUNT); if (!new_ns) { dec_mnt_namespaces(ucounts); return ERR_PTR(-ENOMEM); @@ -5678,6 +5691,8 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id, s->mnt = mnt_file->f_path.mnt; ns = real_mount(s->mnt)->mnt_ns; + if (IS_ERR(ns)) + return PTR_ERR(ns); if (!ns) /* * We can't set mount point and mnt_ns_id since we don't have a diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c index 37ab6f28b5ad..88a0d801525f 100644 --- a/fs/netfs/buffered_read.c +++ b/fs/netfs/buffered_read.c @@ -429,7 +429,7 @@ static int netfs_read_gaps(struct file *file, struct folio *folio) * end get copied to, but the middle is discarded. */ ret = -ENOMEM; - bvec = kmalloc_array(nr_bvec, sizeof(*bvec), GFP_KERNEL); + bvec = kmalloc_objs(*bvec, nr_bvec); if (!bvec) goto discard; diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c index f9d62abef2ac..22a4d61631c9 100644 --- a/fs/netfs/buffered_write.c +++ b/fs/netfs/buffered_write.c @@ -302,7 +302,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter, goto copied; } - finfo = kzalloc(sizeof(*finfo), GFP_KERNEL); + finfo = kzalloc_obj(*finfo); if (!finfo) { iov_iter_revert(iter, copied); ret = -ENOMEM; diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c index a9d1c3b2c084..dd1451bf7543 100644 --- a/fs/netfs/direct_write.c +++ b/fs/netfs/direct_write.c @@ -9,6 +9,202 @@ #include #include "internal.h" +/* + * Perform the cleanup rituals after an unbuffered write is complete. + */ +static void netfs_unbuffered_write_done(struct netfs_io_request *wreq) +{ + struct netfs_inode *ictx = netfs_inode(wreq->inode); + + _enter("R=%x", wreq->debug_id); + + /* Okay, declare that all I/O is complete. */ + trace_netfs_rreq(wreq, netfs_rreq_trace_write_done); + + if (!wreq->error) + netfs_update_i_size(ictx, &ictx->inode, wreq->start, wreq->transferred); + + if (wreq->origin == NETFS_DIO_WRITE && + wreq->mapping->nrpages) { + /* mmap may have got underfoot and we may now have folios + * locally covering the region we just wrote. Attempt to + * discard the folios, but leave in place any modified locally. + * ->write_iter() is prevented from interfering by the DIO + * counter. + */ + pgoff_t first = wreq->start >> PAGE_SHIFT; + pgoff_t last = (wreq->start + wreq->transferred - 1) >> PAGE_SHIFT; + + invalidate_inode_pages2_range(wreq->mapping, first, last); + } + + if (wreq->origin == NETFS_DIO_WRITE) + inode_dio_end(wreq->inode); + + _debug("finished"); + netfs_wake_rreq_flag(wreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip); + /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */ + + if (wreq->iocb) { + size_t written = umin(wreq->transferred, wreq->len); + + wreq->iocb->ki_pos += written; + if (wreq->iocb->ki_complete) { + trace_netfs_rreq(wreq, netfs_rreq_trace_ki_complete); + wreq->iocb->ki_complete(wreq->iocb, wreq->error ?: written); + } + wreq->iocb = VFS_PTR_POISON; + } + + netfs_clear_subrequests(wreq); +} + +/* + * Collect the subrequest results of unbuffered write subrequests. + */ +static void netfs_unbuffered_write_collect(struct netfs_io_request *wreq, + struct netfs_io_stream *stream, + struct netfs_io_subrequest *subreq) +{ + trace_netfs_collect_sreq(wreq, subreq); + + spin_lock(&wreq->lock); + list_del_init(&subreq->rreq_link); + spin_unlock(&wreq->lock); + + wreq->transferred += subreq->transferred; + iov_iter_advance(&wreq->buffer.iter, subreq->transferred); + + stream->collected_to = subreq->start + subreq->transferred; + wreq->collected_to = stream->collected_to; + netfs_put_subrequest(subreq, netfs_sreq_trace_put_done); + + trace_netfs_collect_stream(wreq, stream); + trace_netfs_collect_state(wreq, wreq->collected_to, 0); +} + +/* + * Write data to the server without going through the pagecache and without + * writing it to the local cache. We dispatch the subrequests serially and + * wait for each to complete before dispatching the next, lest we leave a gap + * in the data written due to a failure such as ENOSPC. We could, however + * attempt to do preparation such as content encryption for the next subreq + * whilst the current is in progress. + */ +static int netfs_unbuffered_write(struct netfs_io_request *wreq) +{ + struct netfs_io_subrequest *subreq = NULL; + struct netfs_io_stream *stream = &wreq->io_streams[0]; + int ret; + + _enter("%llx", wreq->len); + + if (wreq->origin == NETFS_DIO_WRITE) + inode_dio_begin(wreq->inode); + + stream->collected_to = wreq->start; + + for (;;) { + bool retry = false; + + if (!subreq) { + netfs_prepare_write(wreq, stream, wreq->start + wreq->transferred); + subreq = stream->construct; + stream->construct = NULL; + stream->front = NULL; + } + + /* Check if (re-)preparation failed. */ + if (unlikely(test_bit(NETFS_SREQ_FAILED, &subreq->flags))) { + netfs_write_subrequest_terminated(subreq, subreq->error); + wreq->error = subreq->error; + break; + } + + iov_iter_truncate(&subreq->io_iter, wreq->len - wreq->transferred); + if (!iov_iter_count(&subreq->io_iter)) + break; + + subreq->len = netfs_limit_iter(&subreq->io_iter, 0, + stream->sreq_max_len, + stream->sreq_max_segs); + iov_iter_truncate(&subreq->io_iter, subreq->len); + stream->submit_extendable_to = subreq->len; + + trace_netfs_sreq(subreq, netfs_sreq_trace_submit); + stream->issue_write(subreq); + + /* Async, need to wait. */ + netfs_wait_for_in_progress_stream(wreq, stream); + + if (test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) { + retry = true; + } else if (test_bit(NETFS_SREQ_FAILED, &subreq->flags)) { + ret = subreq->error; + wreq->error = ret; + netfs_see_subrequest(subreq, netfs_sreq_trace_see_failed); + subreq = NULL; + break; + } + ret = 0; + + if (!retry) { + netfs_unbuffered_write_collect(wreq, stream, subreq); + subreq = NULL; + if (wreq->transferred >= wreq->len) + break; + if (!wreq->iocb && signal_pending(current)) { + ret = wreq->transferred ? -EINTR : -ERESTARTSYS; + trace_netfs_rreq(wreq, netfs_rreq_trace_intr); + break; + } + continue; + } + + /* We need to retry the last subrequest, so first reset the + * iterator, taking into account what, if anything, we managed + * to transfer. + */ + subreq->error = -EAGAIN; + trace_netfs_sreq(subreq, netfs_sreq_trace_retry); + if (subreq->transferred > 0) + iov_iter_advance(&wreq->buffer.iter, subreq->transferred); + + if (stream->source == NETFS_UPLOAD_TO_SERVER && + wreq->netfs_ops->retry_request) + wreq->netfs_ops->retry_request(wreq, stream); + + __clear_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags); + __clear_bit(NETFS_SREQ_BOUNDARY, &subreq->flags); + __clear_bit(NETFS_SREQ_FAILED, &subreq->flags); + subreq->io_iter = wreq->buffer.iter; + subreq->start = wreq->start + wreq->transferred; + subreq->len = wreq->len - wreq->transferred; + subreq->transferred = 0; + subreq->retry_count += 1; + stream->sreq_max_len = UINT_MAX; + stream->sreq_max_segs = INT_MAX; + + netfs_get_subrequest(subreq, netfs_sreq_trace_get_resubmit); + stream->prepare_write(subreq); + + __set_bit(NETFS_SREQ_IN_PROGRESS, &subreq->flags); + netfs_stat(&netfs_n_wh_retry_write_subreq); + } + + netfs_unbuffered_write_done(wreq); + _leave(" = %d", ret); + return ret; +} + +static void netfs_unbuffered_write_async(struct work_struct *work) +{ + struct netfs_io_request *wreq = container_of(work, struct netfs_io_request, work); + + netfs_unbuffered_write(wreq); + netfs_put_request(wreq, netfs_rreq_trace_put_complete); +} + /* * Perform an unbuffered write where we may have to do an RMW operation on an * encrypted file. This can also be used for direct I/O writes. @@ -70,35 +266,35 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter * */ wreq->buffer.iter = *iter; } + + wreq->len = iov_iter_count(&wreq->buffer.iter); } __set_bit(NETFS_RREQ_USE_IO_ITER, &wreq->flags); - if (async) - __set_bit(NETFS_RREQ_OFFLOAD_COLLECTION, &wreq->flags); /* Copy the data into the bounce buffer and encrypt it. */ // TODO /* Dispatch the write. */ __set_bit(NETFS_RREQ_UPLOAD_TO_SERVER, &wreq->flags); - if (async) + + if (async) { + INIT_WORK(&wreq->work, netfs_unbuffered_write_async); wreq->iocb = iocb; - wreq->len = iov_iter_count(&wreq->buffer.iter); - ret = netfs_unbuffered_write(wreq, is_sync_kiocb(iocb), wreq->len); - if (ret < 0) { - _debug("begin = %zd", ret); - goto out; - } - - if (!async) { - ret = netfs_wait_for_write(wreq); - if (ret > 0) - iocb->ki_pos += ret; - } else { + queue_work(system_dfl_wq, &wreq->work); ret = -EIOCBQUEUED; + } else { + ret = netfs_unbuffered_write(wreq); + if (ret < 0) { + _debug("begin = %zd", ret); + } else { + iocb->ki_pos += wreq->transferred; + ret = wreq->transferred ?: wreq->error; + } + + netfs_put_request(wreq, netfs_rreq_trace_put_complete); } -out: netfs_put_request(wreq, netfs_rreq_trace_put_return); return ret; diff --git a/fs/netfs/fscache_cache.c b/fs/netfs/fscache_cache.c index 8f70f8da064b..15b54d133633 100644 --- a/fs/netfs/fscache_cache.c +++ b/fs/netfs/fscache_cache.c @@ -25,7 +25,7 @@ static struct fscache_cache *fscache_alloc_cache(const char *name) { struct fscache_cache *cache; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (cache) { if (name) { cache->name = kstrdup(name, GFP_KERNEL); diff --git a/fs/netfs/fscache_io.c b/fs/netfs/fscache_io.c index e4308457633c..37f05b4d3469 100644 --- a/fs/netfs/fscache_io.c +++ b/fs/netfs/fscache_io.c @@ -223,7 +223,7 @@ void __fscache_write_to_cache(struct fscache_cookie *cookie, _enter("%llx,%zx", start, len); - wreq = kzalloc(sizeof(struct fscache_write_request), GFP_NOFS); + wreq = kzalloc_obj(struct fscache_write_request, GFP_NOFS); if (!wreq) goto abandon; wreq->mapping = mapping; diff --git a/fs/netfs/fscache_volume.c b/fs/netfs/fscache_volume.c index ced14ac78cc1..78412fb8548e 100644 --- a/fs/netfs/fscache_volume.c +++ b/fs/netfs/fscache_volume.c @@ -230,8 +230,7 @@ static struct fscache_volume *fscache_alloc_volume(const char *volume_key, if (IS_ERR(cache)) return NULL; - volume = kzalloc(struct_size(volume, coherency, coherency_len), - GFP_KERNEL); + volume = kzalloc_flex(*volume, coherency, coherency_len); if (!volume) goto err_cache; diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h index 4319611f5354..d436e20d3418 100644 --- a/fs/netfs/internal.h +++ b/fs/netfs/internal.h @@ -198,6 +198,9 @@ struct netfs_io_request *netfs_create_write_req(struct address_space *mapping, struct file *file, loff_t start, enum netfs_io_origin origin); +void netfs_prepare_write(struct netfs_io_request *wreq, + struct netfs_io_stream *stream, + loff_t start); void netfs_reissue_write(struct netfs_io_stream *stream, struct netfs_io_subrequest *subreq, struct iov_iter *source); @@ -212,7 +215,6 @@ int netfs_advance_writethrough(struct netfs_io_request *wreq, struct writeback_c struct folio **writethrough_cache); ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_control *wbc, struct folio *writethrough_cache); -int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t len); /* * write_retry.c diff --git a/fs/netfs/rolling_buffer.c b/fs/netfs/rolling_buffer.c index 207b6a326651..a17fbf9853a4 100644 --- a/fs/netfs/rolling_buffer.c +++ b/fs/netfs/rolling_buffer.c @@ -27,7 +27,7 @@ struct folio_queue *netfs_folioq_alloc(unsigned int rreq_id, gfp_t gfp, { struct folio_queue *fq; - fq = kmalloc(sizeof(*fq), gfp); + fq = kmalloc_obj(*fq, gfp); if (fq) { netfs_stat(&netfs_n_folioq); folioq_init(fq, rreq_id); diff --git a/fs/netfs/write_collect.c b/fs/netfs/write_collect.c index 61eab34ea67e..83eb3dc1adf8 100644 --- a/fs/netfs/write_collect.c +++ b/fs/netfs/write_collect.c @@ -399,27 +399,6 @@ bool netfs_write_collection(struct netfs_io_request *wreq) ictx->ops->invalidate_cache(wreq); } - if ((wreq->origin == NETFS_UNBUFFERED_WRITE || - wreq->origin == NETFS_DIO_WRITE) && - !wreq->error) - netfs_update_i_size(ictx, &ictx->inode, wreq->start, wreq->transferred); - - if (wreq->origin == NETFS_DIO_WRITE && - wreq->mapping->nrpages) { - /* mmap may have got underfoot and we may now have folios - * locally covering the region we just wrote. Attempt to - * discard the folios, but leave in place any modified locally. - * ->write_iter() is prevented from interfering by the DIO - * counter. - */ - pgoff_t first = wreq->start >> PAGE_SHIFT; - pgoff_t last = (wreq->start + wreq->transferred - 1) >> PAGE_SHIFT; - invalidate_inode_pages2_range(wreq->mapping, first, last); - } - - if (wreq->origin == NETFS_DIO_WRITE) - inode_dio_end(wreq->inode); - _debug("finished"); netfs_wake_rreq_flag(wreq, NETFS_RREQ_IN_PROGRESS, netfs_rreq_trace_wake_ip); /* As we cleared NETFS_RREQ_IN_PROGRESS, we acquired its ref. */ diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c index 34894da5a23e..437268f65640 100644 --- a/fs/netfs/write_issue.c +++ b/fs/netfs/write_issue.c @@ -154,9 +154,9 @@ EXPORT_SYMBOL(netfs_prepare_write_failed); * Prepare a write subrequest. We need to allocate a new subrequest * if we don't have one. */ -static void netfs_prepare_write(struct netfs_io_request *wreq, - struct netfs_io_stream *stream, - loff_t start) +void netfs_prepare_write(struct netfs_io_request *wreq, + struct netfs_io_stream *stream, + loff_t start) { struct netfs_io_subrequest *subreq; struct iov_iter *wreq_iter = &wreq->buffer.iter; @@ -698,41 +698,6 @@ ssize_t netfs_end_writethrough(struct netfs_io_request *wreq, struct writeback_c return ret; } -/* - * Write data to the server without going through the pagecache and without - * writing it to the local cache. - */ -int netfs_unbuffered_write(struct netfs_io_request *wreq, bool may_wait, size_t len) -{ - struct netfs_io_stream *upload = &wreq->io_streams[0]; - ssize_t part; - loff_t start = wreq->start; - int error = 0; - - _enter("%zx", len); - - if (wreq->origin == NETFS_DIO_WRITE) - inode_dio_begin(wreq->inode); - - while (len) { - // TODO: Prepare content encryption - - _debug("unbuffered %zx", len); - part = netfs_advance_write(wreq, upload, start, len, false); - start += part; - len -= part; - rolling_buffer_advance(&wreq->buffer, part); - if (test_bit(NETFS_RREQ_PAUSE, &wreq->flags)) - netfs_wait_for_paused_write(wreq); - if (test_bit(NETFS_RREQ_FAILED, &wreq->flags)) - break; - } - - netfs_end_issue_write(wreq); - _leave(" = %d", error); - return error; -} - /* * Write some of a pending folio data back to the server and/or the cache. */ diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 12cb0ca738af..6bb30543eff0 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig @@ -87,7 +87,7 @@ config NFS_V4 space programs which can be found in the Linux nfs-utils package, available from http://linux-nfs.org/. - If unsure, say Y. + If unsure, say N. config NFS_SWAP bool "Provide swap over NFS support" @@ -100,6 +100,7 @@ config NFS_SWAP config NFS_V4_0 bool "NFS client support for NFSv4.0" depends on NFS_V4 + default y help This option enables support for minor version 0 of the NFSv4 protocol (RFC 3530) in the kernel's NFS client. diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 0e4c67373e4f..cb0a645aeb50 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -74,7 +74,7 @@ static inline struct parallel_io *alloc_parallel(void *data) { struct parallel_io *rv; - rv = kmalloc(sizeof(*rv), GFP_NOFS); + rv = kmalloc_obj(*rv, GFP_NOFS); if (rv) { rv->data = data; kref_init(&rv->refcnt); @@ -461,7 +461,7 @@ static struct pnfs_layout_hdr *__bl_alloc_layout_hdr(struct inode *inode, struct pnfs_block_layout *bl; dprintk("%s enter\n", __func__); - bl = kzalloc(sizeof(*bl), gfp_flags); + bl = kzalloc_obj(*bl, gfp_flags); if (!bl) return NULL; @@ -619,7 +619,7 @@ bl_alloc_extent(struct xdr_stream *xdr, struct pnfs_layout_hdr *lo, if (!p) return -EIO; - be = kzalloc(sizeof(*be), GFP_NOFS); + be = kzalloc_obj(*be, GFP_NOFS); if (!be) return -ENOMEM; @@ -684,7 +684,7 @@ bl_alloc_lseg(struct pnfs_layout_hdr *lo, struct nfs4_layoutget_res *lgr, dprintk("---> %s\n", __func__); - lseg = kzalloc(sizeof(*lseg), gfp_mask); + lseg = kzalloc_obj(*lseg, gfp_mask); if (!lseg) return ERR_PTR(-ENOMEM); diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c index 134d7f760a33..cc6327d97a91 100644 --- a/fs/nfs/blocklayout/dev.c +++ b/fs/nfs/blocklayout/dev.c @@ -461,8 +461,8 @@ bl_parse_concat(struct nfs_server *server, struct pnfs_block_dev *d, u64 len = 0; int ret, i; - d->children = kcalloc(v->concat.volumes_count, - sizeof(struct pnfs_block_dev), gfp_mask); + d->children = kzalloc_objs(struct pnfs_block_dev, + v->concat.volumes_count, gfp_mask); if (!d->children) return -ENOMEM; @@ -490,8 +490,8 @@ bl_parse_stripe(struct nfs_server *server, struct pnfs_block_dev *d, u64 len = 0; int ret, i; - d->children = kcalloc(v->stripe.volumes_count, - sizeof(struct pnfs_block_dev), gfp_mask); + d->children = kzalloc_objs(struct pnfs_block_dev, + v->stripe.volumes_count, gfp_mask); if (!d->children) return -ENOMEM; @@ -559,8 +559,7 @@ bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, goto out_free_scratch; nr_volumes = be32_to_cpup(p++); - volumes = kcalloc(nr_volumes, sizeof(struct pnfs_block_volume), - gfp_mask); + volumes = kzalloc_objs(struct pnfs_block_volume, nr_volumes, gfp_mask); if (!volumes) goto out_free_scratch; @@ -570,7 +569,7 @@ bl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, goto out_free_volumes; } - top = kzalloc(sizeof(*top), gfp_mask); + top = kzalloc_obj(*top, gfp_mask); if (!top) goto out_free_volumes; diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c index 315949a7e92d..7393118c42a2 100644 --- a/fs/nfs/blocklayout/extent_tree.c +++ b/fs/nfs/blocklayout/extent_tree.c @@ -201,7 +201,7 @@ __ext_tree_remove(struct rb_root *root, if (len1 > 0) { struct pnfs_block_extent *new; - new = kzalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc_obj(*new, GFP_ATOMIC); if (!new) return -ENOMEM; @@ -384,7 +384,7 @@ ext_tree_split(struct rb_root *root, struct pnfs_block_extent *be, struct pnfs_block_extent *new; sector_t orig_len = be->be_length; - new = kzalloc(sizeof(*new), GFP_ATOMIC); + new = kzalloc_obj(*new, GFP_ATOMIC); if (!new) return -ENOMEM; @@ -653,8 +653,9 @@ ext_tree_prepare_commit(struct nfs4_layoutcommit_args *arg) count = 0; arg->layoutupdate_pages = - kcalloc(DIV_ROUND_UP(buffer_size, PAGE_SIZE), - sizeof(struct page *), GFP_NOFS); + kzalloc_objs(struct page *, + DIV_ROUND_UP(buffer_size, PAGE_SIZE), + GFP_NOFS); if (!arg->layoutupdate_pages) return -ENOMEM; diff --git a/fs/nfs/cache_lib.c b/fs/nfs/cache_lib.c index ef6729568432..9738a1ae92ca 100644 --- a/fs/nfs/cache_lib.c +++ b/fs/nfs/cache_lib.c @@ -96,7 +96,7 @@ struct nfs_cache_defer_req *nfs_cache_defer_req_alloc(void) { struct nfs_cache_defer_req *dreq; - dreq = kzalloc(sizeof(*dreq), GFP_KERNEL); + dreq = kzalloc_obj(*dreq); if (dreq) { init_completion(&dreq->completion); refcount_set(&dreq->count, 1); diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 805eb3764186..4ea9221ded42 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -718,7 +718,7 @@ __be32 nfs4_callback_offload(void *data, void *dummy, struct nfs4_copy_state *copy, *tmp_copy; bool found = false; - copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_KERNEL); + copy = kzalloc_obj(struct nfs4_copy_state); if (!copy) return cpu_to_be32(NFS4ERR_DELAY); diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index c2fa4a91db26..176873f45677 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -272,7 +272,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, if (n == 0) goto out; - args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL); + args->devs = kmalloc_objs(*args->devs, n); if (!args->devs) { status = htonl(NFS4ERR_DELAY); goto out; @@ -378,9 +378,8 @@ static __be32 decode_rc_list(struct xdr_stream *xdr, rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); if (unlikely(p == NULL)) goto out; - rc_list->rcl_refcalls = kmalloc_array(rc_list->rcl_nrefcalls, - sizeof(*rc_list->rcl_refcalls), - GFP_KERNEL); + rc_list->rcl_refcalls = kmalloc_objs(*rc_list->rcl_refcalls, + rc_list->rcl_nrefcalls); if (unlikely(rc_list->rcl_refcalls == NULL)) goto out; for (i = 0; i < rc_list->rcl_nrefcalls; i++) { @@ -419,9 +418,8 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, args->csa_nrclists = ntohl(*p++); args->csa_rclists = NULL; if (args->csa_nrclists) { - args->csa_rclists = kmalloc_array(args->csa_nrclists, - sizeof(*args->csa_rclists), - GFP_KERNEL); + args->csa_rclists = kmalloc_objs(*args->csa_rclists, + args->csa_nrclists); if (unlikely(args->csa_rclists == NULL)) return htonl(NFS4ERR_RESOURCE); diff --git a/fs/nfs/client.c b/fs/nfs/client.c index fd15731cf361..be02bb227741 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -150,7 +150,7 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init) struct nfs_client *clp; int err = -ENOMEM; - if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) + if ((clp = kzalloc_obj(*clp)) == NULL) goto error_0; clp->cl_minorversion = cl_init->minorversion; @@ -1044,7 +1044,7 @@ struct nfs_server *nfs_alloc_server(void) { struct nfs_server *server; - server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL); + server = kzalloc_obj(struct nfs_server); if (!server) return NULL; diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 94103f8d3f21..122fb3f14ffb 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -442,7 +442,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred, struct nfs_delegation *freeme = NULL; int status = 0; - delegation = kmalloc(sizeof(*delegation), GFP_KERNEL_ACCOUNT); + delegation = kmalloc_obj(*delegation, GFP_KERNEL_ACCOUNT); if (delegation == NULL) return -ENOMEM; nfs4_stateid_copy(&delegation->stateid, stateid); @@ -1602,8 +1602,8 @@ int nfs4_delegation_hash_alloc(struct nfs_server *server) delegation_buckets = roundup_pow_of_two(nfs_delegation_watermark / 16); server->delegation_hash_mask = delegation_buckets - 1; - server->delegation_hash_table = kmalloc_array(delegation_buckets, - sizeof(*server->delegation_hash_table), GFP_KERNEL); + server->delegation_hash_table = kmalloc_objs(*server->delegation_hash_table, + delegation_buckets); if (!server->delegation_hash_table) return -ENOMEM; for (i = 0; i < delegation_buckets; i++) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b3f5c9461204..2402f57c8e7d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -80,7 +80,7 @@ alloc_nfs_open_dir_context(struct inode *dir) struct nfs_inode *nfsi = NFS_I(dir); struct nfs_open_dir_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); + ctx = kzalloc_obj(*ctx, GFP_KERNEL_ACCOUNT); if (ctx != NULL) { ctx->attr_gencount = nfsi->attr_gencount; ctx->dtsize = min(NFS_SERVER(dir)->dtsize, NFS_INIT_DTSIZE); @@ -912,7 +912,7 @@ static struct page **nfs_readdir_alloc_pages(size_t npages) struct page **pages; size_t i; - pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, npages); if (!pages) return NULL; for (i = 0; i < npages; i++) { @@ -942,7 +942,7 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, unsigned int pglen; int status = -ENOMEM; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; entry->cookie = nfs_readdir_folio_last_cookie(folio); @@ -1154,7 +1154,7 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc) dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %llu\n", (unsigned long long)desc->dir_cookie); - arrays = kcalloc(sz, sizeof(*arrays), GFP_KERNEL); + arrays = kzalloc_objs(*arrays, sz); if (!arrays) goto out; arrays[0] = nfs_readdir_folio_array_alloc(desc->dir_cookie, GFP_KERNEL); @@ -1245,7 +1245,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) nfs_revalidate_mapping(inode, file->f_mapping); res = -ENOMEM; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) goto out; desc->file = file; @@ -3216,7 +3216,7 @@ static void nfs_access_add_rbtree(struct inode *inode, void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set, const struct cred *cred) { - struct nfs_access_entry *cache = kmalloc(sizeof(*cache), GFP_KERNEL); + struct nfs_access_entry *cache = kmalloc_obj(*cache); if (cache == NULL) return; RB_CLEAR_NODE(&cache->rb_node); diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c index 714975e5c0db..2ed2126201f4 100644 --- a/fs/nfs/dns_resolve.c +++ b/fs/nfs/dns_resolve.c @@ -120,7 +120,7 @@ static void nfs_dns_ent_put(struct kref *ref) static struct cache_head *nfs_dns_ent_alloc(void) { - struct nfs_dns_ent *item = kmalloc(sizeof(*item), GFP_KERNEL); + struct nfs_dns_ent *item = kmalloc_obj(*item); if (item != NULL) { item->hostname = NULL; diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 5c4551117c58..90a11afa5d05 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -694,15 +694,15 @@ filelayout_decode_layout(struct pnfs_layout_hdr *flo, goto out_err; if (fl->num_fh > 0) { - fl->fh_array = kcalloc(fl->num_fh, sizeof(fl->fh_array[0]), - gfp_flags); + fl->fh_array = kzalloc_objs(fl->fh_array[0], fl->num_fh, + gfp_flags); if (!fl->fh_array) goto out_err; } for (i = 0; i < fl->num_fh; i++) { /* Do we want to use a mempool here? */ - fl->fh_array[i] = kmalloc(sizeof(struct nfs_fh), gfp_flags); + fl->fh_array[i] = kmalloc_obj(struct nfs_fh, gfp_flags); if (!fl->fh_array[i]) goto out_err; @@ -763,7 +763,7 @@ filelayout_alloc_lseg(struct pnfs_layout_hdr *layoutid, int rc; dprintk("--> %s\n", __func__); - fl = kzalloc(sizeof(*fl), gfp_flags); + fl = kzalloc_obj(*fl, gfp_flags); if (!fl) return NULL; @@ -1049,7 +1049,7 @@ filelayout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) { struct nfs4_filelayout *flo; - flo = kzalloc(sizeof(*flo), gfp_flags); + flo = kzalloc_obj(*flo, gfp_flags); if (flo == NULL) return NULL; pnfs_init_ds_commit_info(&flo->commit_info); diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c index df79aeb68db4..7226989ee4d5 100644 --- a/fs/nfs/filelayout/filelayoutdev.c +++ b/fs/nfs/filelayout/filelayoutdev.c @@ -138,7 +138,7 @@ nfs4_fl_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, goto out_err_free_stripe_indices; } - dsaddr = kzalloc(struct_size(dsaddr, ds_list, num), gfp_flags); + dsaddr = kzalloc_flex(*dsaddr, ds_list, num, gfp_flags); if (!dsaddr) goto out_err_free_stripe_indices; diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 9056f05a67dc..f67773d52830 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c @@ -54,7 +54,7 @@ ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags) { struct nfs4_flexfile_layout *ffl; - ffl = kzalloc(sizeof(*ffl), gfp_flags); + ffl = kzalloc_obj(*ffl, gfp_flags); if (ffl) { pnfs_init_ds_commit_info(&ffl->commit_info); INIT_LIST_HEAD(&ffl->error_list); @@ -275,7 +275,7 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(u32 dss_count, { struct nfs4_ff_layout_mirror *mirror; - mirror = kzalloc(sizeof(*mirror), gfp_flags); + mirror = kzalloc_obj(*mirror, gfp_flags); if (mirror == NULL) return NULL; @@ -285,8 +285,8 @@ static struct nfs4_ff_layout_mirror *ff_layout_alloc_mirror(u32 dss_count, mirror->dss_count = dss_count; mirror->dss = - kcalloc(dss_count, sizeof(struct nfs4_ff_layout_ds_stripe), - gfp_flags); + kzalloc_objs(struct nfs4_ff_layout_ds_stripe, dss_count, + gfp_flags); if (mirror->dss == NULL) { kfree(mirror); return NULL; @@ -483,8 +483,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, goto out_err_free; rc = -ENOMEM; - fls = kzalloc(struct_size(fls, mirror_array, mirror_array_cnt), - gfp_flags); + fls = kzalloc_flex(*fls, mirror_array, mirror_array_cnt, gfp_flags); if (!fls) goto out_err_free; @@ -554,8 +553,7 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, fh_count = be32_to_cpup(p); dss_info->fh_versions = - kcalloc(fh_count, sizeof(struct nfs_fh), - gfp_flags); + kzalloc_objs(struct nfs_fh, fh_count, gfp_flags); if (dss_info->fh_versions == NULL) { rc = -ENOMEM; goto out_err_free; @@ -2633,7 +2631,7 @@ ff_layout_prepare_layoutreturn(struct nfs4_layoutreturn_args *args) struct nfs4_flexfile_layoutreturn_args *ff_args; struct nfs4_flexfile_layout *ff_layout = FF_LAYOUT_FROM_HDR(args->layout); - ff_args = kmalloc(sizeof(*ff_args), nfs_io_gfp_mask()); + ff_args = kmalloc_obj(*ff_args, nfs_io_gfp_mask()); if (!ff_args) goto out_nomem; ff_args->pages[0] = alloc_page(nfs_io_gfp_mask()); @@ -2674,8 +2672,7 @@ ff_layout_send_layouterror(struct pnfs_layout_segment *lseg) if (list_empty(&head)) return; - errors = kmalloc_array(NFS42_LAYOUTERROR_MAX, sizeof(*errors), - nfs_io_gfp_mask()); + errors = kmalloc_objs(*errors, NFS42_LAYOUTERROR_MAX, nfs_io_gfp_mask()); if (errors != NULL) { const struct nfs4_ff_layout_ds_err *pos; size_t n = 0; @@ -2943,8 +2940,8 @@ static int ff_layout_prepare_layoutstats(struct nfs42_layoutstat_args *args) const int dev_count = PNFS_LAYOUTSTATS_MAXDEV; /* For now, send at most PNFS_LAYOUTSTATS_MAXDEV statistics */ - args->devinfo = kmalloc_array(dev_count, sizeof(*args->devinfo), - nfs_io_gfp_mask()); + args->devinfo = kmalloc_objs(*args->devinfo, dev_count, + nfs_io_gfp_mask()); if (!args->devinfo) return -ENOMEM; diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index c2d8a13a9dbd..c40395ae0814 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c @@ -60,7 +60,7 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, if (!scratch) goto out_err; - new_ds = kzalloc(sizeof(struct nfs4_ff_layout_ds), gfp_flags); + new_ds = kzalloc_obj(struct nfs4_ff_layout_ds, gfp_flags); if (!new_ds) goto out_scratch; @@ -99,9 +99,8 @@ nfs4_ff_alloc_deviceid_node(struct nfs_server *server, struct pnfs_device *pdev, version_count = be32_to_cpup(p); dprintk("%s: version count %d\n", __func__, version_count); - ds_versions = kcalloc(version_count, - sizeof(struct nfs4_ff_ds_version), - gfp_flags); + ds_versions = kzalloc_objs(struct nfs4_ff_ds_version, version_count, + gfp_flags); if (!ds_versions) goto out_err_drain_dsaddrs; @@ -262,7 +261,7 @@ int ff_layout_track_ds_error(struct nfs4_flexfile_layout *flo, if (IS_ERR_OR_NULL(mirror->dss[dss_id].mirror_ds)) return -EINVAL; - dserr = kmalloc(sizeof(*dserr), gfp_flags); + dserr = kmalloc_obj(*dserr, gfp_flags); if (!dserr) return -ENOMEM; diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c index 86750f110053..c105882edd16 100644 --- a/fs/nfs/fs_context.c +++ b/fs/nfs/fs_context.c @@ -1692,7 +1692,7 @@ static int nfs_init_fs_context(struct fs_context *fc) { struct nfs_fs_context *ctx; - ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct nfs_fs_context); if (unlikely(!ctx)) return -ENOMEM; diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 8b0785178731..9b7fdad4a920 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c @@ -288,7 +288,7 @@ static struct nfs_netfs_io_data *nfs_netfs_alloc(struct netfs_io_subrequest *sre { struct nfs_netfs_io_data *netfs; - netfs = kzalloc(sizeof(*netfs), GFP_KERNEL_ACCOUNT); + netfs = kzalloc_obj(*netfs, GFP_KERNEL_ACCOUNT); if (!netfs) return NULL; netfs->sreq = sreq; diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 331cdecdd966..4786343eeee0 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -383,7 +383,7 @@ struct nfs4_label *nfs4_label_alloc(struct nfs_server *server, gfp_t flags) if (!(server->caps & NFS_CAP_SECURITY_LABEL)) return NULL; - label = kzalloc(sizeof(struct nfs4_label), flags); + label = kzalloc_obj(struct nfs4_label, flags); if (label == NULL) return ERR_PTR(-ENOMEM); @@ -1131,7 +1131,7 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx) res = __nfs_find_lock_context(ctx); rcu_read_unlock(); if (res == NULL) { - new = kmalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); + new = kmalloc_obj(*new, GFP_KERNEL_ACCOUNT); if (new == NULL) return ERR_PTR(-ENOMEM); nfs_init_lock_context(new); @@ -1209,7 +1209,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, { struct nfs_open_context *ctx; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); + ctx = kmalloc_obj(*ctx, GFP_KERNEL_ACCOUNT); if (!ctx) return ERR_PTR(-ENOMEM); nfs_sb_active(dentry->d_sb); @@ -1777,7 +1777,7 @@ struct nfs_fattr *nfs_alloc_fattr(void) { struct nfs_fattr *fattr; - fattr = kmalloc(sizeof(*fattr), GFP_KERNEL); + fattr = kmalloc_obj(*fattr); if (fattr != NULL) { nfs_fattr_init(fattr); fattr->label = NULL; @@ -1807,7 +1807,7 @@ struct nfs_fh *nfs_alloc_fhandle(void) { struct nfs_fh *fh; - fh = kmalloc(sizeof(struct nfs_fh), GFP_KERNEL); + fh = kmalloc_obj(struct nfs_fh); if (fh != NULL) fh->size = 0; return fh; @@ -2015,7 +2015,7 @@ static void nfs_ooo_merge(struct nfs_inode *nfsi, return; if (!nfsi->ooo) { - nfsi->ooo = kmalloc(sizeof(*nfsi->ooo), GFP_ATOMIC); + nfsi->ooo = kmalloc_obj(*nfsi->ooo, GFP_ATOMIC); if (!nfsi->ooo) { nfsi->cache_validity |= NFS_INO_DATA_INVAL_DEFER; return; diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c index 3b47be4e693a..4c7d16a99ed6 100644 --- a/fs/nfs/localio.c +++ b/fs/nfs/localio.c @@ -316,12 +316,11 @@ nfs_local_iocb_alloc(struct nfs_pgio_header *hdr, { struct nfs_local_kiocb *iocb; - iocb = kzalloc(sizeof(*iocb), flags); + iocb = kzalloc_obj(*iocb, flags); if (iocb == NULL) return NULL; - iocb->bvec = kmalloc_array(hdr->page_array.npages, - sizeof(struct bio_vec), flags); + iocb->bvec = kmalloc_objs(struct bio_vec, hdr->page_array.npages, flags); if (iocb->bvec == NULL) { kfree(iocb); return NULL; @@ -1070,7 +1069,7 @@ static struct nfs_local_fsync_ctx * nfs_local_fsync_ctx_alloc(struct nfs_commit_data *data, struct nfsd_file *localio, gfp_t flags) { - struct nfs_local_fsync_ctx *ctx = kmalloc(sizeof(*ctx), flags); + struct nfs_local_fsync_ctx *ctx = kmalloc_obj(*ctx, flags); if (ctx != NULL) { ctx->localio = localio; diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d3d2fbeba89d..be2aebf62056 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -299,7 +299,7 @@ static struct nfs3_createdata *nfs3_alloc_createdata(void) { struct nfs3_createdata *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (data != NULL) { data->msg.rpc_argp = &data->arg; data->msg.rpc_resp = &data->res; @@ -392,8 +392,13 @@ nfs3_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, if (status != 0) goto out_release_acls; - if (d_alias) + if (d_alias) { + if (d_is_dir(d_alias)) { + status = -EISDIR; + goto out_dput; + } dentry = d_alias; + } /* When we created the file with exclusive semantics, make * sure we set the attributes afterwards. */ diff --git a/fs/nfs/nfs40client.c b/fs/nfs/nfs40client.c index fc0c6b48fc94..f44d68faea93 100644 --- a/fs/nfs/nfs40client.c +++ b/fs/nfs/nfs40client.c @@ -65,7 +65,7 @@ int nfs40_init_client(struct nfs_client *clp) struct nfs4_slot_table *tbl; int ret; - tbl = kzalloc(sizeof(*tbl), GFP_NOFS); + tbl = kzalloc_obj(*tbl, GFP_NOFS); if (tbl == NULL) return -ENOMEM; diff --git a/fs/nfs/nfs40proc.c b/fs/nfs/nfs40proc.c index 32a2a1a2b216..b07f2d6ccde4 100644 --- a/fs/nfs/nfs40proc.c +++ b/fs/nfs/nfs40proc.c @@ -122,7 +122,7 @@ static int nfs4_proc_async_renew(struct nfs_client *clp, const struct cred *cred return 0; if (!refcount_inc_not_zero(&clp->cl_count)) return -EIO; - data = kmalloc(sizeof(*data), GFP_NOFS); + data = kmalloc_obj(*data, GFP_NOFS); if (data == NULL) { nfs_put_client(clp); return -ENOMEM; @@ -320,7 +320,7 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) if (clp->cl_mvops->minor_version != 0) return; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return; data->lsp = lsp; diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index 3487948d7181..7b3ca68fb4bb 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c @@ -247,7 +247,7 @@ static int handle_async_copy(struct nfs42_copy_res *res, int status = NFS4_OK; u64 copied; - copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_KERNEL); + copy = kzalloc_obj(struct nfs4_copy_state); if (!copy) return -ENOMEM; @@ -351,7 +351,7 @@ static int process_copy_commit(struct file *dst, loff_t pos_dst, struct nfs_commitres cres; int status = -ENOMEM; - cres.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_KERNEL); + cres.verf = kzalloc_obj(struct nfs_writeverf); if (!cres.verf) goto out; @@ -461,7 +461,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, res->commit_res.verf = NULL; if (args->sync) { res->commit_res.verf = - kzalloc(sizeof(struct nfs_writeverf), GFP_KERNEL); + kzalloc_obj(struct nfs_writeverf); if (!res->commit_res.verf) return -ENOMEM; } @@ -659,7 +659,7 @@ static int nfs42_do_offload_cancel_async(struct file *dst, if (!(dst_server->caps & NFS_CAP_OFFLOAD_CANCEL)) return -EOPNOTSUPP; - data = kzalloc(sizeof(struct nfs42_offload_data), GFP_KERNEL); + data = kzalloc_obj(struct nfs42_offload_data); if (data == NULL) return -ENOMEM; @@ -756,7 +756,7 @@ nfs42_proc_offload_status(struct file *dst, nfs4_stateid *stateid, u64 *copied) if (!(server->caps & NFS_CAP_OFFLOAD_STATUS)) return -EOPNOTSUPP; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; data->seq_server = server; @@ -838,7 +838,7 @@ int nfs42_proc_copy_notify(struct file *src, struct file *dst, if (!(src_server->caps & NFS_CAP_COPY_NOTIFY)) return -EOPNOTSUPP; - args = kzalloc(sizeof(struct nfs42_copy_notify_args), GFP_KERNEL); + args = kzalloc_obj(struct nfs42_copy_notify_args); if (args == NULL) return -ENOMEM; @@ -1087,7 +1087,7 @@ nfs42_alloc_layouterror_data(struct pnfs_layout_segment *lseg, gfp_t gfp_flags) struct nfs42_layouterror_data *data; struct inode *inode = lseg->pls_layout->plh_inode; - data = kzalloc(sizeof(*data), gfp_flags); + data = kzalloc_obj(*data, gfp_flags); if (data) { data->args.inode = data->inode = nfs_igrab_and_active(inode); if (data->inode) { @@ -1535,7 +1535,7 @@ static ssize_t _nfs42_proc_listxattrs(struct inode *inode, void *buf, xdrlen = server->lxasize; np = xdrlen / PAGE_SIZE + 1; - pages = kcalloc(np, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, np); if (!pages) goto out_free_scratch; for (i = 0; i < np; i++) { @@ -1578,7 +1578,7 @@ ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name, struct page **pages; np = nfs_page_array_len(0, buflen ?: XATTR_SIZE_MAX); - pages = kmalloc_array(np, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, np); if (!pages) return -ENOMEM; diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index e10d83ba835e..5c7452ce6e8a 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -1159,7 +1159,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res) if (segments == 0) return 0; - segs = kmalloc_array(segments, sizeof(*segs), GFP_KERNEL); + segs = kmalloc_objs(*segs, segments); if (!segs) return -ENOMEM; diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 51cf4a37d652..c211639949c2 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c @@ -99,7 +99,7 @@ nfs4_alloc_ds_server(struct nfs_client *ds_clp, rpc_authflavor_t flavor) { struct nfs4_ds_server *dss; - dss = kmalloc(sizeof(*dss), GFP_NOFS); + dss = kmalloc_obj(*dss, GFP_NOFS); if (dss == NULL) return ERR_PTR(-ENOMEM); diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index 7f43e890d356..be40e126c539 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c @@ -164,8 +164,7 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in, */ if (sync) return -EOPNOTSUPP; - cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res), - GFP_KERNEL); + cn_resp = kzalloc_obj(struct nfs42_copy_notify_res); if (unlikely(cn_resp == NULL)) return -ENOMEM; diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 9e1c48c5c0b8..bc397110d977 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -445,7 +445,7 @@ nfs_idmap_new(struct nfs_client *clp) struct rpc_pipe *pipe; int error; - idmap = kzalloc(sizeof(*idmap), GFP_KERNEL); + idmap = kzalloc_obj(*idmap); if (idmap == NULL) return -ENOMEM; @@ -579,7 +579,7 @@ static int nfs_idmap_legacy_upcall(struct key *authkey, void *aux) /* msg and im are freed in idmap_pipe_destroy_msg */ ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto out1; diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 9a98595bb160..14f72baf3b30 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c @@ -415,7 +415,7 @@ static int nfs_do_refmount(struct fs_context *fc, struct rpc_clnt *client) if (!page) return -ENOMEM; - fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); + fs_locations = kmalloc_obj(struct nfs4_fs_locations); if (!fs_locations) goto out_free; fs_locations->fattr = nfs_alloc_fattr(); @@ -490,7 +490,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server, size_t salen; int error; - sap = kmalloc(sizeof(*sap), GFP_KERNEL); + sap = kmalloc_obj(*sap); if (sap == NULL) return -ENOMEM; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 180229320731..91bcf67bd743 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1370,7 +1370,7 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry, struct nfs4_label *label = (c != NULL) ? c->label : NULL; struct nfs4_opendata *p; - p = kzalloc(sizeof(*p), gfp_mask); + p = kzalloc_obj(*p, gfp_mask); if (p == NULL) goto err; @@ -3774,7 +3774,7 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait) nfs4_state_protect(clp, NFS_SP4_MACH_CRED_CLEANUP, &task_setup_data.rpc_client, &msg); - calldata = kzalloc(sizeof(*calldata), gfp_mask); + calldata = kzalloc_obj(*calldata, gfp_mask); if (calldata == NULL) goto out; nfs4_init_sequence(clp, &calldata->arg.seq_args, @@ -4107,7 +4107,7 @@ static int _nfs4_discover_trunking(struct nfs_server *server, page = alloc_page(GFP_KERNEL); if (!page) goto out_put_cred; - locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); + locations = kmalloc_obj(struct nfs4_fs_locations); if (!locations) goto out_free; locations->fattr = nfs_alloc_fattr(); @@ -4341,7 +4341,7 @@ static int nfs4_get_referral(struct rpc_clnt *client, struct inode *dir, page = alloc_page(GFP_KERNEL); if (page == NULL) goto out; - locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); + locations = kmalloc_obj(struct nfs4_fs_locations); if (locations == NULL) goto out; @@ -5130,7 +5130,7 @@ static struct nfs4_createdata *nfs4_alloc_createdata(struct inode *dir, { struct nfs4_createdata *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (data != NULL) { struct nfs_server *server = NFS_SERVER(dir); @@ -6023,7 +6023,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, acl->cached = 1; _copy_from_pages(acl->data, pages, pgbase, acl_len); } else { - acl = kmalloc(sizeof(*acl), GFP_KERNEL); + acl = kmalloc_obj(*acl); if (acl == NULL) goto out; acl->cached = 0; @@ -6070,7 +6070,7 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, buflen = server->rsize; npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1; - pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, npages); if (!pages) return -ENOMEM; @@ -6822,7 +6822,7 @@ static int _nfs4_proc_delegreturn(struct inode *inode, const struct cred *cred, if (nfs_server_capable(inode, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (data == NULL) return -ENOMEM; @@ -7026,7 +7026,7 @@ static struct nfs4_unlockdata *nfs4_alloc_unlockdata(struct file_lock *fl, struct inode *inode = state->inode; struct nfs_lock_context *l_ctx; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (p == NULL) return NULL; l_ctx = nfs_get_lock_context(ctx); @@ -7260,7 +7260,7 @@ static struct nfs4_lockdata *nfs4_alloc_lockdata(struct file_lock *fl, struct nfs_server *server = NFS_SERVER(inode); struct nfs_seqid *(*alloc_seqid)(struct nfs_seqid_counter *, gfp_t); - p = kzalloc(sizeof(*p), gfp_mask); + p = kzalloc_obj(*p, gfp_mask); if (p == NULL) return NULL; @@ -8706,7 +8706,7 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred, return ERR_PTR(-EIO); status = -ENOMEM; - calldata = kzalloc(sizeof(*calldata), GFP_NOFS); + calldata = kzalloc_obj(*calldata, GFP_NOFS); if (!calldata) goto out; @@ -8716,18 +8716,18 @@ nfs4_run_exchange_id(struct nfs_client *clp, const struct cred *cred, if (status) goto out_calldata; - calldata->res.server_owner = kzalloc(sizeof(struct nfs41_server_owner), - GFP_NOFS); + calldata->res.server_owner = kzalloc_obj(struct nfs41_server_owner, + GFP_NOFS); status = -ENOMEM; if (unlikely(calldata->res.server_owner == NULL)) goto out_calldata; - calldata->res.server_scope = kzalloc(sizeof(struct nfs41_server_scope), - GFP_NOFS); + calldata->res.server_scope = kzalloc_obj(struct nfs41_server_scope, + GFP_NOFS); if (unlikely(calldata->res.server_scope == NULL)) goto out_server_owner; - calldata->res.impl_id = kzalloc(sizeof(struct nfs41_impl_id), GFP_NOFS); + calldata->res.impl_id = kzalloc_obj(struct nfs41_impl_id, GFP_NOFS); if (unlikely(calldata->res.impl_id == NULL)) goto out_server_scope; @@ -9396,7 +9396,7 @@ static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, goto out_err; ret = ERR_PTR(-ENOMEM); - calldata = kzalloc(sizeof(*calldata), GFP_KERNEL); + calldata = kzalloc_obj(*calldata); if (calldata == NULL) goto out_put_clp; nfs4_init_sequence(clp, &calldata->args, &calldata->res, 0, is_privileged); @@ -9543,7 +9543,7 @@ static int nfs41_proc_reclaim_complete(struct nfs_client *clp, }; int status = -ENOMEM; - calldata = kzalloc(sizeof(*calldata), GFP_NOFS); + calldata = kzalloc_obj(*calldata, GFP_NOFS); if (calldata == NULL) goto out; calldata->clp = clp; @@ -10358,7 +10358,7 @@ static int nfs41_free_stateid(struct nfs_server *server, &task_setup.rpc_client, &msg); dprintk("NFS call free_stateid %p\n", stateid); - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; data->server = server; diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c index a2fdd4b80dc4..5c128957a0a4 100644 --- a/fs/nfs/nfs4session.c +++ b/fs/nfs/nfs4session.c @@ -106,7 +106,7 @@ static struct nfs4_slot *nfs4_new_slot(struct nfs4_slot_table *tbl, { struct nfs4_slot *slot; - slot = kzalloc(sizeof(*slot), gfp_mask); + slot = kzalloc_obj(*slot, gfp_mask); if (slot) { slot->table = tbl; slot->slot_nr = slotid; @@ -558,7 +558,7 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp) { struct nfs4_session *session; - session = kzalloc(sizeof(struct nfs4_session), GFP_NOFS); + session = kzalloc_obj(struct nfs4_session, GFP_NOFS); if (!session) return NULL; diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 963719f35467..305a772e5497 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -446,7 +446,7 @@ nfs4_alloc_state_owner(struct nfs_server *server, { struct nfs4_state_owner *sp; - sp = kzalloc(sizeof(*sp), gfp_flags); + sp = kzalloc_obj(*sp, gfp_flags); if (!sp) return NULL; sp->so_seqid.owner_id = atomic64_inc_return(&server->owner_ctr); @@ -612,7 +612,7 @@ nfs4_alloc_open_state(void) { struct nfs4_state *state; - state = kzalloc(sizeof(*state), GFP_KERNEL_ACCOUNT); + state = kzalloc_obj(*state, GFP_KERNEL_ACCOUNT); if (!state) return NULL; refcount_set(&state->count, 1); @@ -815,7 +815,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f struct nfs4_lock_state *lsp; struct nfs_server *server = state->owner->so_server; - lsp = kzalloc(sizeof(*lsp), GFP_KERNEL_ACCOUNT); + lsp = kzalloc_obj(*lsp, GFP_KERNEL_ACCOUNT); if (lsp == NULL) return NULL; nfs4_init_seqid_counter(&lsp->ls_seqid); @@ -1014,7 +1014,7 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_m { struct nfs_seqid *new; - new = kmalloc(sizeof(*new), gfp_mask); + new = kmalloc_obj(*new, gfp_mask); if (new == NULL) return ERR_PTR(-ENOMEM); new->sequence = counter; @@ -2054,7 +2054,7 @@ static int nfs4_try_migration(struct nfs_server *server, const struct cred *cred clp->cl_hostname); page = alloc_page(GFP_KERNEL); - locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL); + locations = kmalloc_obj(struct nfs4_fs_locations); fattr = nfs_alloc_fattr(); if (page == NULL || locations == NULL || fattr == NULL) { dprintk("<-- %s: no memory\n", __func__); diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c index 5ec9c83f1ef0..9c5895b551a1 100644 --- a/fs/nfs/nfs4super.c +++ b/fs/nfs/nfs4super.c @@ -100,7 +100,7 @@ static int nfs_referral_loop_protect(void) struct nfs_referral_count *p, *new; int ret = -ENOMEM; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) goto out; new->task = current; diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 6e69ce43a13f..a9373de891c9 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -893,7 +893,8 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, if (pagecount <= ARRAY_SIZE(pg_array->page_array)) pg_array->pagevec = pg_array->page_array; else { - pg_array->pagevec = kcalloc(pagecount, sizeof(struct page *), gfp_flags); + pg_array->pagevec = kzalloc_objs(struct page *, pagecount, + gfp_flags); if (!pg_array->pagevec) { pg_array->npages = 0; nfs_pgio_error(hdr); @@ -991,7 +992,7 @@ nfs_pageio_alloc_mirrors(struct nfs_pageio_descriptor *desc, desc->pg_mirrors_dynamic = NULL; if (mirror_count == 1) return desc->pg_mirrors_static; - ret = kmalloc_array(mirror_count, sizeof(*ret), nfs_io_gfp_mask()); + ret = kmalloc_objs(*ret, mirror_count, nfs_io_gfp_mask()); if (ret != NULL) { for (i = 0; i < mirror_count; i++) nfs_pageio_mirror_init(&ret[i], desc->pg_bsize); diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index ff8483d3373a..bc13d1e69449 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c @@ -1143,7 +1143,7 @@ static struct page **nfs4_alloc_pages(size_t size, gfp_t gfp_flags) struct page **pages; int i; - pages = kmalloc_array(size, sizeof(struct page *), gfp_flags); + pages = kmalloc_objs(struct page *, size, gfp_flags); if (!pages) { dprintk("%s: can't alloc array of %zu pages\n", __func__, size); return NULL; @@ -1175,7 +1175,7 @@ pnfs_alloc_init_layoutget_args(struct inode *ino, dprintk("--> %s\n", __func__); - lgp = kzalloc(sizeof(*lgp), gfp_flags); + lgp = kzalloc_obj(*lgp, gfp_flags); if (lgp == NULL) return NULL; @@ -1357,7 +1357,7 @@ pnfs_send_layoutreturn(struct pnfs_layout_hdr *lo, int status = 0; *pcred = NULL; - lrp = kzalloc(sizeof(*lrp), nfs_io_gfp_mask()); + lrp = kzalloc_obj(*lrp, nfs_io_gfp_mask()); if (unlikely(lrp == NULL)) { status = -ENOMEM; spin_lock(&ino->i_lock); @@ -3379,7 +3379,7 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) status = -ENOMEM; /* Note kzalloc ensures data->res.seq_res.sr_slot == NULL */ - data = kzalloc(sizeof(*data), nfs_io_gfp_mask()); + data = kzalloc_obj(*data, nfs_io_gfp_mask()); if (!data) goto clear_layoutcommitting; @@ -3450,7 +3450,7 @@ struct nfs4_threshold *pnfs_mdsthreshold_alloc(void) { struct nfs4_threshold *thp; - thp = kzalloc(sizeof(*thp), nfs_io_gfp_mask()); + thp = kzalloc_obj(*thp, nfs_io_gfp_mask()); if (!thp) { dprintk("%s mdsthreshold allocation failed\n", __func__); return NULL; @@ -3487,7 +3487,7 @@ pnfs_report_layoutstat(struct inode *inode, gfp_t gfp_flags) pnfs_get_layout_hdr(hdr); spin_unlock(&inode->i_lock); - data = kzalloc(sizeof(*data), gfp_flags); + data = kzalloc_obj(*data, gfp_flags); if (!data) { status = -ENOMEM; goto out_put; diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c index bf0f2d67e96c..274abdd6d5f3 100644 --- a/fs/nfs/pnfs_dev.c +++ b/fs/nfs/pnfs_dev.c @@ -114,11 +114,11 @@ nfs4_get_device_info(struct nfs_server *server, dprintk("%s: server %p max_resp_sz %u max_pages %d\n", __func__, server, max_resp_sz, max_pages); - pdev = kzalloc(sizeof(*pdev), gfp_flags); + pdev = kzalloc_obj(*pdev, gfp_flags); if (!pdev) return NULL; - pages = kcalloc(max_pages, sizeof(struct page *), gfp_flags); + pages = kzalloc_objs(struct page *, max_pages, gfp_flags); if (!pages) goto out_free_pdev; diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c index 9976cc16b689..12632a706da8 100644 --- a/fs/nfs/pnfs_nfs.c +++ b/fs/nfs/pnfs_nfs.c @@ -101,7 +101,7 @@ pnfs_alloc_commit_array(size_t n, gfp_t gfp_flags) struct pnfs_commit_array *p; struct pnfs_commit_bucket *b; - p = kmalloc(struct_size(p, buckets, n), gfp_flags); + p = kmalloc_flex(*p, buckets, n, gfp_flags); if (!p) return NULL; p->nbuckets = n; @@ -618,7 +618,7 @@ _data_server_lookup_locked(const struct nfs_net *nn, const struct list_head *dsa static struct nfs4_pnfs_ds_addr *nfs4_pnfs_ds_addr_alloc(gfp_t gfp_flags) { - struct nfs4_pnfs_ds_addr *da = kzalloc(sizeof(*da), gfp_flags); + struct nfs4_pnfs_ds_addr *da = kzalloc_obj(*da, gfp_flags); if (da) INIT_LIST_HEAD(&da->da_node); return da; @@ -730,7 +730,7 @@ nfs4_pnfs_ds_add(const struct net *net, struct list_head *dsaddrs, gfp_t gfp_fla goto out; } - ds = kzalloc(sizeof(*ds), gfp_flags); + ds = kzalloc_obj(*ds, gfp_flags); if (!ds) goto out; diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 0e440ebf5335..8c3d2efa2636 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -217,7 +217,7 @@ static struct nfs_createdata *nfs_alloc_createdata(struct inode *dir, { struct nfs_createdata *data; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (data != NULL) { data->arg.fh = NFS_FH(dir); diff --git a/fs/nfs/sysfs.c b/fs/nfs/sysfs.c index 7bf650fda1cb..7d8921f524a6 100644 --- a/fs/nfs/sysfs.c +++ b/fs/nfs/sysfs.c @@ -43,7 +43,7 @@ int nfs_sysfs_init(void) { int ret; - nfs_kset = kzalloc(sizeof(*nfs_kset), GFP_KERNEL); + nfs_kset = kzalloc_obj(*nfs_kset); if (!nfs_kset) return -ENOMEM; @@ -172,7 +172,7 @@ static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent, { struct nfs_netns_client *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (p) { p->net = net; p->kobject.kset = nfs_kset; diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 4db818c0f9dd..df3ca4669df6 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -175,7 +175,7 @@ nfs_async_unlink(struct dentry *dentry, const struct qstr *name) int status = -ENOMEM; void *devname_garbage = NULL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (data == NULL) goto out; data->args.name.name = kstrdup(name->name, GFP_KERNEL); @@ -355,7 +355,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, nfs_server_capable(new_dir, NFS_CAP_MOVEABLE)) task_setup_data.flags |= RPC_TASK_MOVEABLE; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (data == NULL) return ERR_PTR(-ENOMEM); task_setup_data.task = &data->task; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2d0e4a765aeb..1ed4b3590b1a 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -113,7 +113,7 @@ static void nfs_writehdr_free(struct nfs_pgio_header *hdr) static struct nfs_io_completion *nfs_io_completion_alloc(gfp_t gfp_flags) { - return kmalloc(sizeof(struct nfs_io_completion), gfp_flags); + return kmalloc_obj(struct nfs_io_completion, gfp_flags); } static void nfs_io_completion_init(struct nfs_io_completion *ioc, diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c index afa16d7a8013..a7cfba29990e 100644 --- a/fs/nfsd/blocklayout.c +++ b/fs/nfsd/blocklayout.c @@ -131,7 +131,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, * layouts, so make sure to zero the whole structure. */ nfserr = nfserrno(-ENOMEM); - bl = kzalloc(struct_size(bl, extents, nr_extents_max), GFP_KERNEL); + bl = kzalloc_flex(*bl, extents, nr_extents_max); if (!bl) goto out_error; bl->nr_extents = nr_extents_max; @@ -208,7 +208,7 @@ nfsd4_block_get_device_info_simple(struct super_block *sb, struct pnfs_block_deviceaddr *dev; struct pnfs_block_volume *b; - dev = kzalloc(struct_size(dev, volumes, 1), GFP_KERNEL); + dev = kzalloc_flex(*dev, volumes, 1); if (!dev) return -ENOMEM; gdp->gd_device = dev; @@ -319,7 +319,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb, const struct pr_ops *ops; int ret; - dev = kzalloc(struct_size(dev, volumes, 1), GFP_KERNEL); + dev = kzalloc_flex(*dev, volumes, 1); if (!dev) return -ENOMEM; gdp->gd_device = dev; diff --git a/fs/nfsd/blocklayoutxdr.c b/fs/nfsd/blocklayoutxdr.c index 196ef4245604..f80dbc41fd5f 100644 --- a/fs/nfsd/blocklayoutxdr.c +++ b/fs/nfsd/blocklayoutxdr.c @@ -164,7 +164,7 @@ nfsd4_block_decode_layoutupdate(struct xdr_stream *xdr, struct iomap **iomapp, if (len != expected) return nfserr_bad_xdr; - iomaps = kcalloc(nr_iomaps, sizeof(*iomaps), GFP_KERNEL); + iomaps = kzalloc_objs(*iomaps, nr_iomaps); if (!iomaps) return nfserr_delay; @@ -258,7 +258,7 @@ nfsd4_scsi_decode_layoutupdate(struct xdr_stream *xdr, struct iomap **iomapp, if (len != expected) return nfserr_bad_xdr; - iomaps = kcalloc(nr_iomaps, sizeof(*iomaps), GFP_KERNEL); + iomaps = kzalloc_objs(*iomaps, nr_iomaps); if (!iomaps) return nfserr_delay; diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 2a1499f2ad19..8fdbba7cad96 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -234,7 +234,7 @@ static inline void expkey_update(struct cache_head *cnew, static struct cache_head *expkey_alloc(void) { - struct svc_expkey *i = kmalloc(sizeof(*i), GFP_KERNEL); + struct svc_expkey *i = kmalloc_obj(*i); if (i) return &i->h; else @@ -427,7 +427,8 @@ static int check_export(const struct path *path, int *flags, unsigned char *uuid * either a device number (so FS_REQUIRES_DEV needed) * or an FSID number (so NFSEXP_FSID or ->uuid is needed). * 2: We must be able to find an inode from a filehandle. - * This means that s_export_op must be set. + * This means that s_export_op must be set and comply with + * the requirements for remote filesystem export. * 3: We must not currently be on an idmapped mount. */ if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) && @@ -437,8 +438,9 @@ static int check_export(const struct path *path, int *flags, unsigned char *uuid return -EINVAL; } - if (!exportfs_can_decode_fh(inode->i_sb->s_export_op)) { - dprintk("exp_export: export of invalid fs type.\n"); + if (!exportfs_may_export(inode->i_sb->s_export_op)) { + dprintk("exp_export: export of invalid fs type (%s).\n", + inode->i_sb->s_type->name); return -EINVAL; } @@ -477,9 +479,8 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc) if (fsloc->locations_count == 0) return 0; - fsloc->locations = kcalloc(fsloc->locations_count, - sizeof(struct nfsd4_fs_location), - GFP_KERNEL); + fsloc->locations = kzalloc_objs(struct nfsd4_fs_location, + fsloc->locations_count); if (!fsloc->locations) return -ENOMEM; for (i=0; i < fsloc->locations_count; i++) { @@ -869,11 +870,11 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem) static struct cache_head *svc_export_alloc(void) { - struct svc_export *i = kmalloc(sizeof(*i), GFP_KERNEL); + struct svc_export *i = kmalloc_obj(*i); if (!i) return NULL; - i->ex_stats = kmalloc(sizeof(*(i->ex_stats)), GFP_KERNEL); + i->ex_stats = kmalloc_obj(*(i->ex_stats)); if (!i->ex_stats) { kfree(i); return NULL; diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c index 93798575b807..1e2b38ed1d35 100644 --- a/fs/nfsd/filecache.c +++ b/fs/nfsd/filecache.c @@ -899,7 +899,7 @@ nfsd_alloc_fcache_disposal(void) { struct nfsd_fcache_disposal *l; - l = kmalloc(sizeof(*l), GFP_KERNEL); + l = kmalloc_obj(*l); if (!l) return NULL; spin_lock_init(&l->lock); diff --git a/fs/nfsd/flexfilelayout.c b/fs/nfsd/flexfilelayout.c index 0f1a35400cd5..6d531285ab43 100644 --- a/fs/nfsd/flexfilelayout.c +++ b/fs/nfsd/flexfilelayout.c @@ -36,7 +36,7 @@ nfsd4_ff_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, * Zero it out for the stateid - don't want junk in there! */ error = -ENOMEM; - fl = kzalloc(sizeof(*fl), GFP_KERNEL); + fl = kzalloc_obj(*fl); if (!fl) goto out_error; args->lg_content = fl; @@ -86,7 +86,7 @@ nfsd4_ff_proc_getdeviceinfo(struct super_block *sb, struct svc_rqst *rqstp, u16 port; char addr[INET6_ADDRSTRLEN]; - da = kzalloc(sizeof(struct pnfs_ff_device_addr), GFP_KERNEL); + da = kzalloc_obj(struct pnfs_ff_device_addr); if (!da) return nfserrno(-ENOMEM); diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index e00b2aea8da2..aea8bdd2fdc4 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -1378,7 +1378,7 @@ void nfsd41_cb_referring_call(struct nfsd4_callback *cb, } } if (!found) { - rcl = kmalloc(sizeof(*rcl), GFP_KERNEL); + rcl = kmalloc_obj(*rcl); if (!rcl) return; memcpy(rcl->rcl_sessionid.data, sessionid->data, @@ -1397,7 +1397,7 @@ void nfsd41_cb_referring_call(struct nfsd4_callback *cb, } } if (!found) { - rc = kmalloc(sizeof(*rc), GFP_KERNEL); + rc = kmalloc_obj(*rc); if (!rc) goto out; rc->rc_sequenceid = seqno; diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index c319c31b0f64..ba06d3d3e6dd 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c @@ -97,7 +97,7 @@ ent_put(struct kref *ref) static struct cache_head * ent_alloc(void) { - struct ent *e = kmalloc(sizeof(*e), GFP_KERNEL); + struct ent *e = kmalloc_obj(*e); if (e) return &e->h; else diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 37ab3a69c4b6..6880c5c520e7 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -451,7 +451,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru int accmode; __be32 status; - *resfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); + *resfh = kmalloc_obj(struct svc_fh); if (!*resfh) return nfserr_jukebox; fh_init(*resfh, NFS4_FHSIZE); @@ -1630,7 +1630,7 @@ static __be32 nfsd4_ssc_setup_dul(struct nfsd_net *nn, char *ipaddr, __be32 status = 0; *nsui = NULL; - work = kzalloc(sizeof(*work), GFP_KERNEL); + work = kzalloc_obj(*work); try_again: spin_lock(&nn->nfsd_ssc_lock); list_for_each_entry_safe(ni, tmp, &nn->nfsd_ssc_mount_list, nsui_list) { @@ -2160,7 +2160,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, memcpy(©->fh, &cstate->current_fh.fh_handle, sizeof(struct knfsd_fh)); if (nfsd4_copy_is_async(copy)) { - async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); + async_copy = kzalloc_obj(struct nfsd4_copy); if (!async_copy) goto out_err; async_copy->cp_nn = nn; @@ -2171,7 +2171,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, if (atomic_inc_return(&nn->pending_async_copies) > (int)rqstp->rq_pool->sp_nrthreads) goto out_dec_async_copy_err; - async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL); + async_copy->cp_src = kmalloc_obj(*async_copy->cp_src); if (!async_copy->cp_src) goto out_dec_async_copy_err; if (!nfs4_init_copy_state(nn, copy)) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 1e6b2dd47ba7..b4bf85f96f6e 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -203,7 +203,7 @@ nfsd4_build_namelist(struct dir_context *__ctx, const char *name, int namlen, if (namlen != HEXDIR_LEN - 1) return true; - entry = kmalloc(sizeof(struct name_list), GFP_KERNEL); + entry = kmalloc_obj(struct name_list); if (entry == NULL) return false; memcpy(entry->name, name, HEXDIR_LEN - 1); @@ -478,9 +478,8 @@ nfs4_legacy_state_init(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int i; - nn->reclaim_str_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + nn->reclaim_str_hashtbl = kmalloc_objs(struct list_head, + CLIENT_HASH_SIZE); if (!nn->reclaim_str_hashtbl) return -ENOMEM; @@ -898,7 +897,7 @@ __nfsd4_init_cld_pipe(struct net *net) if (nn->cld_net) return 0; - cn = kzalloc(sizeof(*cn), GFP_KERNEL); + cn = kzalloc_obj(*cn); if (!cn) { ret = -ENOMEM; goto err; @@ -960,7 +959,7 @@ alloc_cld_upcall(struct nfsd_net *nn) struct cld_upcall *new, *tmp; struct cld_net *cn = nn->cld_net; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return new; @@ -1356,9 +1355,8 @@ nfs4_cld_state_init(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int i; - nn->reclaim_str_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + nn->reclaim_str_hashtbl = kmalloc_objs(struct list_head, + CLIENT_HASH_SIZE); if (!nn->reclaim_str_hashtbl) return -ENOMEM; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index f5cb067a1e50..6b9c399b89df 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -299,7 +299,7 @@ find_or_allocate_block(struct nfs4_lockowner *lo, struct knfsd_fh *fh, nbl = find_blocked_lock(lo, fh, nn); if (!nbl) { - nbl = kmalloc(sizeof(*nbl), GFP_KERNEL); + nbl = kmalloc_obj(*nbl); if (nbl) { INIT_LIST_HEAD(&nbl->nbl_list); INIT_LIST_HEAD(&nbl->nbl_lru); @@ -974,7 +974,7 @@ struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn, { struct nfs4_cpntf_state *cps; - cps = kzalloc(sizeof(struct nfs4_cpntf_state), GFP_KERNEL); + cps = kzalloc_obj(struct nfs4_cpntf_state); if (!cps) return NULL; cps->cpntf_time = ktime_get_boottime_seconds(); @@ -2032,7 +2032,7 @@ static struct nfsd4_slot *nfsd4_alloc_slot(struct nfsd4_channel_attrs *fattrs, size = fattrs->maxresp_cached < NFSD_MIN_HDR_SEQ_SZ ? 0 : fattrs->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; - slot = kzalloc(struct_size(slot, sl_data, size), gfp); + slot = kzalloc_flex(*slot, sl_data, size, gfp); if (!slot) return NULL; slot->sl_index = index; @@ -2047,7 +2047,7 @@ static struct nfsd4_session *alloc_session(struct nfsd4_channel_attrs *fattrs, struct nfsd4_slot *slot; int i; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; xa_init(&new->se_slots); @@ -2108,7 +2108,7 @@ static struct nfsd4_conn *alloc_conn(struct svc_rqst *rqstp, u32 flags) { struct nfsd4_conn *conn; - conn = kmalloc(sizeof(struct nfsd4_conn), GFP_KERNEL); + conn = kmalloc_obj(struct nfsd4_conn); if (!conn) return NULL; svc_xprt_get(rqstp->rq_xprt); @@ -2357,9 +2357,8 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name, xdr_netobj_dup(&clp->cl_name, &name, GFP_KERNEL); if (clp->cl_name.data == NULL) goto err_no_name; - clp->cl_ownerstr_hashtbl = kmalloc_array(OWNER_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + clp->cl_ownerstr_hashtbl = kmalloc_objs(struct list_head, + OWNER_HASH_SIZE); if (!clp->cl_ownerstr_hashtbl) goto err_no_hashtbl; clp->cl_callback_wq = alloc_ordered_workqueue("nfsd4_callbacks", 0); @@ -3309,7 +3308,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name, free_client(clp); return NULL; } - clp->cl_ra = kzalloc(sizeof(*clp->cl_ra), GFP_KERNEL); + clp->cl_ra = kzalloc_obj(*clp->cl_ra); if (!clp->cl_ra) { free_client(clp); return NULL; @@ -8823,7 +8822,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, static inline struct nfs4_client_reclaim * alloc_reclaim(void) { - return kmalloc(sizeof(struct nfs4_client_reclaim), GFP_KERNEL); + return kmalloc_obj(struct nfs4_client_reclaim); } bool @@ -8960,19 +8959,14 @@ static int nfs4_state_create_net(struct net *net) struct nfsd_net *nn = net_generic(net, nfsd_net_id); int i; - nn->conf_id_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + nn->conf_id_hashtbl = kmalloc_objs(struct list_head, CLIENT_HASH_SIZE); if (!nn->conf_id_hashtbl) goto err; - nn->unconf_id_hashtbl = kmalloc_array(CLIENT_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + nn->unconf_id_hashtbl = kmalloc_objs(struct list_head, CLIENT_HASH_SIZE); if (!nn->unconf_id_hashtbl) goto err_unconf_id; - nn->sessionid_hashtbl = kmalloc_array(SESSION_HASH_SIZE, - sizeof(struct list_head), - GFP_KERNEL); + nn->sessionid_hashtbl = kmalloc_objs(struct list_head, + SESSION_HASH_SIZE); if (!nn->sessionid_hashtbl) goto err_sessionid; diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 5172dbd0cb05..41dfba5ab8b8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -124,7 +124,7 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, size_t len) { struct svcxdr_tmpbuf *tb; - tb = kmalloc(struct_size(tb, buf, len), GFP_KERNEL); + tb = kmalloc_flex(*tb, buf, len); if (!tb) return NULL; tb->next = argp->to_free; @@ -2184,7 +2184,7 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, union nfsd4_op_u *u) if (status) return status; - ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL); + ns_dummy = kmalloc_obj(struct nl4_server); if (ns_dummy == NULL) return nfserr_jukebox; for (i = 0; i < count - 1; i++) { @@ -3956,7 +3956,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, } if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && !fhp) { - tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL); + tempfh = kmalloc_obj(struct svc_fh); status = nfserr_jukebox; if (!tempfh) goto out; diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 89fe2c0e8d44..4cc8a58fa56a 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -377,15 +377,15 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) } /* - * write_threads - Start NFSD, or report the current number of running threads + * write_threads - Start NFSD, or report the configured number of threads * * Input: * buf: ignored * size: zero * Output: * On success: passed-in buffer filled with '\n'-terminated C - * string numeric value representing the number of - * running NFSD threads; + * string numeric value representing the configured + * number of NFSD threads; * return code is the size in bytes of the string * On error: return code is zero * @@ -399,8 +399,8 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size) * Output: * On success: NFS service is started; * passed-in buffer filled with '\n'-terminated C - * string numeric value representing the number of - * running NFSD threads; + * string numeric value representing the configured + * number of NFSD threads; * return code is the size in bytes of the string * On error: return code is zero or a negative errno value */ @@ -430,7 +430,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) } /* - * write_pool_threads - Set or report the current number of threads per pool + * write_pool_threads - Set or report the configured number of threads per pool * * Input: * buf: ignored @@ -447,7 +447,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size) * Output: * On success: passed-in buffer filled with '\n'-terminated C * string containing integer values representing the - * number of NFSD threads in each pool; + * configured number of NFSD threads in each pool; * return code is the size in bytes of the string * On error: return code is zero or a negative errno value */ @@ -477,7 +477,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size) return strlen(buf); } - nthreads = kcalloc(npools, sizeof(int), GFP_KERNEL); + nthreads = kzalloc_objs(int, npools); rv = -ENOMEM; if (nthreads == NULL) goto out_free; @@ -1596,7 +1596,7 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info) mutex_lock(&nfsd_mutex); - nthreads = kcalloc(nrpools, sizeof(int), GFP_KERNEL); + nthreads = kzalloc_objs(int, nrpools); if (!nthreads) { ret = -ENOMEM; goto out_unlock; @@ -1647,7 +1647,7 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info) if (attr) nn->min_threads = nla_get_u32(attr); - ret = nfsd_svc(nrpools, nthreads, net, get_current_cred(), scope); + ret = nfsd_svc(nrpools, nthreads, net, current_cred(), scope); if (ret > 0) ret = 0; out_unlock: @@ -1657,7 +1657,7 @@ int nfsd_nl_threads_set_doit(struct sk_buff *skb, struct genl_info *info) } /** - * nfsd_nl_threads_get_doit - get the number of running threads + * nfsd_nl_threads_get_doit - get the maximum number of running threads * @skb: reply buffer * @info: netlink metadata and command arguments * @@ -1700,7 +1700,7 @@ int nfsd_nl_threads_get_doit(struct sk_buff *skb, struct genl_info *info) struct svc_pool *sp = &nn->nfsd_serv->sv_pools[i]; err = nla_put_u32(skb, NFSD_A_SERVER_THREADS, - sp->sp_nrthreads); + sp->sp_nrthrmax); if (err) goto err_unlock; } @@ -2000,7 +2000,7 @@ int nfsd_nl_listener_set_doit(struct sk_buff *skb, struct genl_info *info) } ret = svc_xprt_create_from_sa(serv, xcl_name, net, sa, 0, - get_current_cred()); + current_cred()); /* always save the latest error */ if (ret < 0) err = ret; diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 0887ee601d3c..4a04208393b8 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -239,12 +239,13 @@ static void nfsd_net_free(struct percpu_ref *ref) int nfsd_nrthreads(struct net *net) { - int rv = 0; + int i, rv = 0; struct nfsd_net *nn = net_generic(net, nfsd_net_id); mutex_lock(&nfsd_mutex); if (nn->nfsd_serv) - rv = nn->nfsd_serv->sv_nrthreads; + for (i = 0; i < nn->nfsd_serv->sv_nrpools; ++i) + rv += nn->nfsd_serv->sv_pools[i].sp_nrthrmax; mutex_unlock(&nfsd_mutex); return rv; } @@ -659,7 +660,7 @@ int nfsd_get_nrthreads(int n, int *nthreads, struct net *net) if (serv) for (i = 0; i < serv->sv_nrpools && i < n; i++) - nthreads[i] = serv->sv_pools[i].sp_nrthreads; + nthreads[i] = serv->sv_pools[i].sp_nrthrmax; return 0; } diff --git a/fs/nilfs2/alloc.c b/fs/nilfs2/alloc.c index 6b506995818d..e7eebb04f9a4 100644 --- a/fs/nilfs2/alloc.c +++ b/fs/nilfs2/alloc.c @@ -54,7 +54,7 @@ int nilfs_palloc_init_blockgroup(struct inode *inode, unsigned int entry_size) { struct nilfs_mdt_info *mi = NILFS_MDT(inode); - mi->mi_bgl = kmalloc(sizeof(*mi->mi_bgl), GFP_NOFS); + mi->mi_bgl = kmalloc_obj(*mi->mi_bgl, GFP_NOFS); if (!mi->mi_bgl) return -ENOMEM; diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index a9c61d0492cb..4d5a6aa5214c 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c @@ -370,7 +370,7 @@ static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr, if (unlikely(!binfo)) goto out; - rb = kmalloc(sizeof(*rb), GFP_NOFS); + rb = kmalloc_obj(*rb, GFP_NOFS); if (unlikely(!rb)) { err = -ENOMEM; goto out; @@ -414,7 +414,7 @@ struct nilfs_segment_entry { static int nilfs_segment_list_add(struct list_head *head, __u64 segnum) { - struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS); + struct nilfs_segment_entry *ent = kmalloc_obj(*ent, GFP_NOFS); if (unlikely(!ent)) return -ENOMEM; diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index deee16bc9d4e..098a3bd103e0 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c @@ -2701,7 +2701,7 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct super_block *sb, struct the_nilfs *nilfs = sb->s_fs_info; struct nilfs_sc_info *sci; - sci = kzalloc(sizeof(*sci), GFP_KERNEL); + sci = kzalloc_obj(*sci); if (!sci) return NULL; diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index badc2cbc895e..7aa5ef8606cd 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1292,7 +1292,7 @@ static int nilfs_init_fs_context(struct fs_context *fc) { struct nilfs_fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index d0bcf744c553..7b23e373a106 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c @@ -56,7 +56,7 @@ struct the_nilfs *alloc_nilfs(struct super_block *sb) { struct the_nilfs *nilfs; - nilfs = kzalloc(sizeof(*nilfs), GFP_KERNEL); + nilfs = kzalloc_obj(*nilfs); if (!nilfs) return NULL; @@ -877,7 +877,7 @@ nilfs_find_or_create_root(struct the_nilfs *nilfs, __u64 cno) if (root) return root; - new = kzalloc(sizeof(*root), GFP_KERNEL); + new = kzalloc_obj(*root); if (!new) return NULL; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index d0b9b984002f..c2dcb25151de 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -1573,7 +1573,7 @@ static struct fsnotify_event *fanotify_alloc_overflow_event(void) { struct fanotify_event *oevent; - oevent = kmalloc(sizeof(*oevent), GFP_KERNEL_ACCOUNT); + oevent = kmalloc_obj(*oevent, GFP_KERNEL_ACCOUNT); if (!oevent) return NULL; diff --git a/fs/notify/group.c b/fs/notify/group.c index 18446b7b0d49..b56d1c1d9644 100644 --- a/fs/notify/group.c +++ b/fs/notify/group.c @@ -117,7 +117,7 @@ static struct fsnotify_group *__fsnotify_alloc_group( { struct fsnotify_group *group; - group = kzalloc(sizeof(struct fsnotify_group), gfp); + group = kzalloc_obj(struct fsnotify_group, gfp); if (!group) return ERR_PTR(-ENOMEM); diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index b372fb2c56bd..5e1845f2c25d 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -660,7 +660,7 @@ static struct fsnotify_group *inotify_new_group(unsigned int max_events) if (IS_ERR(group)) return group; - oevent = kmalloc(sizeof(struct inotify_event_info), GFP_KERNEL_ACCOUNT); + oevent = kmalloc_obj(struct inotify_event_info, GFP_KERNEL_ACCOUNT); if (unlikely(!oevent)) { fsnotify_destroy_group(group); return ERR_PTR(-ENOMEM); diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 8e6997e9aebb..c2ed5b11b0fe 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -644,7 +644,7 @@ static int fsnotify_attach_info_to_sb(struct super_block *sb) struct fsnotify_sb_info *sbinfo; /* sb info is freed on fsnotify_sb_delete() */ - sbinfo = kzalloc(sizeof(*sbinfo), GFP_KERNEL); + sbinfo = kzalloc_obj(*sbinfo); if (!sbinfo) return -ENOMEM; diff --git a/fs/nsfs.c b/fs/nsfs.c index db91de208645..c215878d55e8 100644 --- a/fs/nsfs.c +++ b/fs/nsfs.c @@ -199,6 +199,17 @@ static bool nsfs_ioctl_valid(unsigned int cmd) return false; } +static bool may_use_nsfs_ioctl(unsigned int cmd) +{ + switch (_IOC_NR(cmd)) { + case _IOC_NR(NS_MNT_GET_NEXT): + fallthrough; + case _IOC_NR(NS_MNT_GET_PREV): + return may_see_all_namespaces(); + } + return true; +} + static long ns_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) { @@ -214,6 +225,8 @@ static long ns_ioctl(struct file *filp, unsigned int ioctl, if (!nsfs_ioctl_valid(ioctl)) return -ENOIOCTLCMD; + if (!may_use_nsfs_ioctl(ioctl)) + return -EPERM; ns = get_proc_ns(file_inode(filp)); switch (ioctl) { @@ -614,7 +627,7 @@ static struct dentry *nsfs_fh_to_dentry(struct super_block *sb, struct fid *fh, return ERR_PTR(-EOPNOTSUPP); } - if (owning_ns && !ns_capable(owning_ns, CAP_SYS_ADMIN)) { + if (owning_ns && !may_see_all_namespaces()) { ns->ops->put(ns); return ERR_PTR(-EPERM); } diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c index 980ae9157248..6cb9bc5d605c 100644 --- a/fs/ntfs3/attrib.c +++ b/fs/ntfs3/attrib.c @@ -91,7 +91,8 @@ static int attr_load_runs(struct ATTRIB *attr, struct ntfs_inode *ni, * run_deallocate_ex - Deallocate clusters. */ static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run, - CLST vcn, CLST len, CLST *done, bool trim) + CLST vcn, CLST len, CLST *done, bool trim, + struct runs_tree *run_da) { int err = 0; CLST vcn_next, vcn0 = vcn, lcn, clen, dn = 0; @@ -120,6 +121,16 @@ static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run, if (sbi) { /* mark bitmap range [lcn + clen) as free and trim clusters. */ mark_as_free_ex(sbi, lcn, clen, trim); + + if (run_da) { + CLST da_len; + if (!run_remove_range(run_da, vcn, clen, + &da_len)) { + err = -ENOMEM; + goto failed; + } + ntfs_sub_da(sbi, da_len); + } } dn += clen; } @@ -147,9 +158,10 @@ static int run_deallocate_ex(struct ntfs_sb_info *sbi, struct runs_tree *run, * attr_allocate_clusters - Find free space, mark it as used and store in @run. */ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, - CLST vcn, CLST lcn, CLST len, CLST *pre_alloc, - enum ALLOCATE_OPT opt, CLST *alen, const size_t fr, - CLST *new_lcn, CLST *new_len) + struct runs_tree *run_da, CLST vcn, CLST lcn, + CLST len, CLST *pre_alloc, enum ALLOCATE_OPT opt, + CLST *alen, const size_t fr, CLST *new_lcn, + CLST *new_len) { int err; CLST flen, vcn0 = vcn, pre = pre_alloc ? *pre_alloc : 0; @@ -166,6 +178,12 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, continue; } + if (err == -ENOSPC && new_len && vcn - vcn0) { + /* Keep already allocated clusters. */ + *alen = vcn - vcn0; + return 0; + } + if (err) goto out; @@ -179,12 +197,21 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, /* Add new fragment into run storage. */ if (!run_add_entry(run, vcn, lcn, flen, opt & ALLOCATE_MFT)) { +undo_alloc: /* Undo last 'ntfs_look_for_free_space' */ mark_as_free_ex(sbi, lcn, len, false); err = -ENOMEM; goto out; } + if (run_da) { + CLST da_len; + if (!run_remove_range(run_da, vcn, flen, &da_len)) { + goto undo_alloc; + } + ntfs_sub_da(sbi, da_len); + } + if (opt & ALLOCATE_ZERO) { u8 shift = sbi->cluster_bits - SECTOR_SHIFT; @@ -199,7 +226,7 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, vcn += flen; if (flen >= len || (opt & ALLOCATE_MFT) || - (fr && run->count - cnt >= fr)) { + (opt & ALLOCATE_ONE_FR) || (fr && run->count - cnt >= fr)) { *alen = vcn - vcn0; return 0; } @@ -210,7 +237,8 @@ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, out: /* Undo 'ntfs_look_for_free_space' */ if (vcn - vcn0) { - run_deallocate_ex(sbi, run, vcn0, vcn - vcn0, NULL, false); + run_deallocate_ex(sbi, run, vcn0, vcn - vcn0, NULL, false, + run_da); run_truncate(run, vcn0); } @@ -275,7 +303,7 @@ int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr, } else { const char *data = resident_data(attr); - err = attr_allocate_clusters(sbi, run, 0, 0, len, NULL, + err = attr_allocate_clusters(sbi, run, NULL, 0, 0, len, NULL, ALLOCATE_DEF, &alen, 0, NULL, NULL); if (err) @@ -391,7 +419,7 @@ static int attr_set_size_res(struct ntfs_inode *ni, struct ATTRIB *attr, } /* - * attr_set_size - Change the size of attribute. + * attr_set_size_ex - Change the size of attribute. * * Extend: * - Sparse/compressed: No allocated clusters. @@ -399,24 +427,28 @@ static int attr_set_size_res(struct ntfs_inode *ni, struct ATTRIB *attr, * Shrink: * - No deallocate if @keep_prealloc is set. */ -int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, - const __le16 *name, u8 name_len, struct runs_tree *run, - u64 new_size, const u64 *new_valid, bool keep_prealloc, - struct ATTRIB **ret) +int attr_set_size_ex(struct ntfs_inode *ni, enum ATTR_TYPE type, + const __le16 *name, u8 name_len, struct runs_tree *run, + u64 new_size, const u64 *new_valid, bool keep_prealloc, + struct ATTRIB **ret, bool no_da) { int err = 0; struct ntfs_sb_info *sbi = ni->mi.sbi; u8 cluster_bits = sbi->cluster_bits; bool is_mft = ni->mi.rno == MFT_REC_MFT && type == ATTR_DATA && !name_len; - u64 old_valid, old_size, old_alloc, new_alloc, new_alloc_tmp; + u64 old_valid, old_size, old_alloc, new_alloc_tmp; + u64 new_alloc = 0; struct ATTRIB *attr = NULL, *attr_b; struct ATTR_LIST_ENTRY *le, *le_b; struct mft_inode *mi, *mi_b; CLST alen, vcn, lcn, new_alen, old_alen, svcn, evcn; CLST next_svcn, pre_alloc = -1, done = 0; - bool is_ext, is_bad = false; + bool is_ext = false, is_bad = false; bool dirty = false; + struct runs_tree *run_da = run == &ni->file.run ? &ni->file.run_da : + NULL; + bool da = !is_mft && sbi->options->delalloc && run_da && !no_da; u32 align; struct MFT_REC *rec; @@ -448,8 +480,11 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, is_ext = is_attr_ext(attr_b); align = sbi->cluster_size; - if (is_ext) + if (is_ext) { align <<= attr_b->nres.c_unit; + keep_prealloc = false; + da = false; + } old_valid = le64_to_cpu(attr_b->nres.valid_size); old_size = le64_to_cpu(attr_b->nres.data_size); @@ -467,6 +502,37 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, goto ok; } + if (da && + (vcn = old_alen + run_len(&ni->file.run_da), new_alen > vcn)) { + /* Resize up normal file. Delay new clusters allocation. */ + alen = new_alen - vcn; + + if (ntfs_check_free_space(sbi, alen, 0, true)) { + if (!run_add_entry(&ni->file.run_da, vcn, SPARSE_LCN, + alen, false)) { + err = -ENOMEM; + goto out; + } + + ntfs_add_da(sbi, alen); + goto ok1; + } + } + + if (!keep_prealloc && run_da && run_da->count && + (vcn = run_get_max_vcn(run_da), new_alen < vcn)) { + /* Shrink delayed clusters. */ + + /* Try to remove fragment from delay allocated run. */ + if (!run_remove_range(run_da, new_alen, vcn - new_alen, + &alen)) { + err = -ENOMEM; + goto out; + } + + ntfs_sub_da(sbi, alen); + } + vcn = old_alen - 1; svcn = le64_to_cpu(attr_b->nres.svcn); @@ -572,7 +638,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, } else { /* ~3 bytes per fragment. */ err = attr_allocate_clusters( - sbi, run, vcn, lcn, to_allocate, &pre_alloc, + sbi, run, run_da, vcn, lcn, to_allocate, + &pre_alloc, is_mft ? ALLOCATE_MFT : ALLOCATE_DEF, &alen, is_mft ? 0 : (sbi->record_size - @@ -751,14 +818,14 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, mi_b->dirty = dirty = true; err = run_deallocate_ex(sbi, run, vcn, evcn - vcn + 1, &dlen, - true); + true, run_da); if (err) goto out; if (is_ext) { /* dlen - really deallocated clusters. */ le64_sub_cpu(&attr_b->nres.total_size, - ((u64)dlen << cluster_bits)); + (u64)dlen << cluster_bits); } run_truncate(run, vcn); @@ -813,14 +880,14 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, if (((type == ATTR_DATA && !name_len) || (type == ATTR_ALLOC && name == I30_NAME))) { /* Update inode_set_bytes. */ - if (attr_b->non_res) { - new_alloc = le64_to_cpu(attr_b->nres.alloc_size); - if (inode_get_bytes(&ni->vfs_inode) != new_alloc) { - inode_set_bytes(&ni->vfs_inode, new_alloc); - dirty = true; - } + if (attr_b->non_res && + inode_get_bytes(&ni->vfs_inode) != new_alloc) { + inode_set_bytes(&ni->vfs_inode, new_alloc); + dirty = true; } + i_size_write(&ni->vfs_inode, new_size); + /* Don't forget to update duplicate information in parent. */ if (dirty) { ni->ni_flags |= NI_FLAG_UPDATE_PARENT; @@ -861,7 +928,7 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, is_bad = true; undo_1: - run_deallocate_ex(sbi, run, vcn, alen, NULL, false); + run_deallocate_ex(sbi, run, vcn, alen, NULL, false, run_da); run_truncate(run, vcn); out: @@ -884,43 +951,74 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, * - new allocated clusters are zeroed via blkdev_issue_zeroout. */ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, - CLST *len, bool *new, bool zero) + CLST *len, bool *new, bool zero, void **res, bool no_da) { - int err = 0; - struct runs_tree *run = &ni->file.run; - struct ntfs_sb_info *sbi; - u8 cluster_bits; - struct ATTRIB *attr, *attr_b; - struct ATTR_LIST_ENTRY *le, *le_b; - struct mft_inode *mi, *mi_b; - CLST hint, svcn, to_alloc, evcn1, next_svcn, asize, end, vcn0, alen; - CLST alloc, evcn; - unsigned fr; - u64 total_size, total_size0; - int step = 0; + int err; if (new) *new = false; + if (res) + *res = NULL; /* Try to find in cache. */ down_read(&ni->file.run_lock); - if (!run_lookup_entry(run, vcn, lcn, len, NULL)) + if (!no_da && run_lookup_entry(&ni->file.run_da, vcn, lcn, len, NULL)) { + /* The requested vcn is delay allocated. */ + *lcn = DELALLOC_LCN; + } else if (run_lookup_entry(&ni->file.run, vcn, lcn, len, NULL)) { + /* The requested vcn is known in current run. */ + } else { *len = 0; + } up_read(&ni->file.run_lock); if (*len && (*lcn != SPARSE_LCN || !new)) return 0; /* Fast normal way without allocation. */ /* No cluster in cache or we need to allocate cluster in hole. */ - sbi = ni->mi.sbi; - cluster_bits = sbi->cluster_bits; - ni_lock(ni); down_write(&ni->file.run_lock); - /* Repeat the code above (under write lock). */ - if (!run_lookup_entry(run, vcn, lcn, len, NULL)) + err = attr_data_get_block_locked(ni, vcn, clen, lcn, len, new, zero, + res, no_da); + + up_write(&ni->file.run_lock); + ni_unlock(ni); + + return err; +} + +/* + * attr_data_get_block_locked - Helper for attr_data_get_block. + */ +int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen, + CLST *lcn, CLST *len, bool *new, bool zero, + void **res, bool no_da) +{ + int err = 0; + struct ntfs_sb_info *sbi = ni->mi.sbi; + struct runs_tree *run = &ni->file.run; + struct runs_tree *run_da = &ni->file.run_da; + bool da = sbi->options->delalloc && !no_da; + u8 cluster_bits; + struct ATTRIB *attr, *attr_b; + struct ATTR_LIST_ENTRY *le, *le_b; + struct mft_inode *mi, *mi_b; + CLST hint, svcn, to_alloc, evcn1, next_svcn, asize, end, vcn0; + CLST alloc, evcn; + unsigned fr; + u64 total_size, total_size0; + int step; + +again: + if (da && run_lookup_entry(run_da, vcn, lcn, len, NULL)) { + /* The requested vcn is delay allocated. */ + *lcn = DELALLOC_LCN; + } else if (run_lookup_entry(run, vcn, lcn, len, NULL)) { + /* The requested vcn is known in current run. */ + } else { *len = 0; + } if (*len) { if (*lcn != SPARSE_LCN || !new) @@ -929,6 +1027,9 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, clen = *len; } + cluster_bits = sbi->cluster_bits; + step = 0; + le_b = NULL; attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, &mi_b); if (!attr_b) { @@ -937,8 +1038,15 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, } if (!attr_b->non_res) { + u32 data_size = le32_to_cpu(attr_b->res.data_size); *lcn = RESIDENT_LCN; - *len = 1; + *len = data_size; + if (res && data_size) { + *res = kmemdup(resident_data(attr_b), data_size, + GFP_KERNEL); + if (!*res) + err = -ENOMEM; + } goto out; } @@ -948,7 +1056,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, err = -EINVAL; } else { *len = 1; - *lcn = SPARSE_LCN; + *lcn = EOF_LCN; } goto out; } @@ -1026,7 +1134,8 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, to_alloc = ((vcn0 + clen + clst_per_frame - 1) & cmask) - vcn; if (fr < clst_per_frame) fr = clst_per_frame; - zero = true; + if (vcn != vcn0) + zero = true; /* Check if 'vcn' and 'vcn0' in different attribute segments. */ if (vcn < svcn || evcn1 <= vcn) { @@ -1043,11 +1152,38 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, if (err) goto out; } + da = false; /* no delalloc for compressed file. */ } if (vcn + to_alloc > asize) to_alloc = asize - vcn; + if (da) { + CLST rlen1, rlen2; + if (!ntfs_check_free_space(sbi, to_alloc, 0, true)) { + err = ni_allocate_da_blocks_locked(ni); + if (err) + goto out; + /* Layout of records may be changed. Start again without 'da'. */ + da = false; + goto again; + } + + /* run_add_entry consolidates existed ranges. */ + rlen1 = run_len(run_da); + if (!run_add_entry(run_da, vcn, SPARSE_LCN, to_alloc, false)) { + err = -ENOMEM; + goto out; + } + rlen2 = run_len(run_da); + + /* new added delay clusters = rlen2 - rlen1. */ + ntfs_add_da(sbi, rlen2 - rlen1); + *len = to_alloc; + *lcn = DELALLOC_LCN; + goto ok; + } + /* Get the last LCN to allocate from. */ hint = 0; @@ -1062,18 +1198,19 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, } /* Allocate and zeroout new clusters. */ - err = attr_allocate_clusters(sbi, run, vcn, hint + 1, to_alloc, NULL, - zero ? ALLOCATE_ZERO : ALLOCATE_DEF, &alen, - fr, lcn, len); + err = attr_allocate_clusters(sbi, run, run_da, vcn, hint + 1, to_alloc, + NULL, + zero ? ALLOCATE_ZERO : ALLOCATE_ONE_FR, + len, fr, lcn, len); if (err) goto out; *new = true; step = 1; - end = vcn + alen; + end = vcn + *len; /* Save 'total_size0' to restore if error. */ total_size0 = le64_to_cpu(attr_b->nres.total_size); - total_size = total_size0 + ((u64)alen << cluster_bits); + total_size = total_size0 + ((u64)*len << cluster_bits); if (vcn != vcn0) { if (!run_lookup_entry(run, vcn0, lcn, len, NULL)) { @@ -1139,7 +1276,7 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, * in 'ni_insert_nonresident'. * Return in advance -ENOSPC here if there are no free cluster and no free MFT. */ - if (!ntfs_check_for_free_space(sbi, 1, 1)) { + if (!ntfs_check_free_space(sbi, 1, 1, false)) { /* Undo step 1. */ err = -ENOSPC; goto undo1; @@ -1224,8 +1361,6 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, /* Too complex to restore. */ _ntfs_bad_inode(&ni->vfs_inode); } - up_write(&ni->file.run_lock); - ni_unlock(ni); return err; @@ -1234,41 +1369,14 @@ int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, attr_b->nres.total_size = cpu_to_le64(total_size0); inode_set_bytes(&ni->vfs_inode, total_size0); - if (run_deallocate_ex(sbi, run, vcn, alen, NULL, false) || - !run_add_entry(run, vcn, SPARSE_LCN, alen, false) || + if (run_deallocate_ex(sbi, run, vcn, *len, NULL, false, run_da) || + !run_add_entry(run, vcn, SPARSE_LCN, *len, false) || mi_pack_runs(mi, attr, run, max(end, evcn1) - svcn)) { _ntfs_bad_inode(&ni->vfs_inode); } goto out; } -int attr_data_read_resident(struct ntfs_inode *ni, struct folio *folio) -{ - u64 vbo; - struct ATTRIB *attr; - u32 data_size; - size_t len; - - attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, NULL); - if (!attr) - return -EINVAL; - - if (attr->non_res) - return E_NTFS_NONRESIDENT; - - vbo = folio->index << PAGE_SHIFT; - data_size = le32_to_cpu(attr->res.data_size); - if (vbo > data_size) - len = 0; - else - len = min(data_size - vbo, folio_size(folio)); - - folio_fill_tail(folio, 0, resident_data(attr) + vbo, len); - folio_mark_uptodate(folio); - - return 0; -} - int attr_data_write_resident(struct ntfs_inode *ni, struct folio *folio) { u64 vbo; @@ -1285,7 +1393,7 @@ int attr_data_write_resident(struct ntfs_inode *ni, struct folio *folio) return E_NTFS_NONRESIDENT; } - vbo = folio->index << PAGE_SHIFT; + vbo = folio_pos(folio); data_size = le32_to_cpu(attr->res.data_size); if (vbo < data_size) { char *data = resident_data(attr); @@ -1354,19 +1462,27 @@ int attr_load_runs_range(struct ntfs_inode *ni, enum ATTR_TYPE type, CLST vcn; CLST vcn_last = (to - 1) >> cluster_bits; CLST lcn, clen; - int err; + int err = 0; + int retry = 0; for (vcn = from >> cluster_bits; vcn <= vcn_last; vcn += clen) { - if (!run_lookup_entry(run, vcn, &lcn, &clen, NULL)) { - err = attr_load_runs_vcn(ni, type, name, name_len, run, - vcn); - if (err) - return err; - clen = 0; /* Next run_lookup_entry(vcn) must be success. */ + if (run_lookup_entry(run, vcn, &lcn, &clen, NULL)) { + retry = 0; + continue; } + if (retry) { + err = -EINVAL; + break; + } + err = attr_load_runs_vcn(ni, type, name, name_len, run, vcn); + if (err) + break; + + clen = 0; /* Next run_lookup_entry(vcn) must be success. */ + retry++; } - return 0; + return err; } #ifdef CONFIG_NTFS3_LZX_XPRESS @@ -1689,7 +1805,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, if (len < clst_data) { err = run_deallocate_ex(sbi, run, vcn + len, clst_data - len, - NULL, true); + NULL, true, NULL); if (err) goto out; @@ -1709,7 +1825,7 @@ int attr_allocate_frame(struct ntfs_inode *ni, CLST frame, size_t compr_size, hint = -1; } - err = attr_allocate_clusters(sbi, run, vcn + clst_data, + err = attr_allocate_clusters(sbi, run, NULL, vcn + clst_data, hint + 1, len - clst_data, NULL, ALLOCATE_DEF, &alen, 0, NULL, NULL); @@ -1864,6 +1980,7 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) CLST vcn, end; u64 valid_size, data_size, alloc_size, total_size; u32 mask; + u64 i_size; __le16 a_flags; if (!bytes) @@ -1879,52 +1996,79 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) return 0; } - data_size = le64_to_cpu(attr_b->nres.data_size); - alloc_size = le64_to_cpu(attr_b->nres.alloc_size); - a_flags = attr_b->flags; - - if (is_attr_ext(attr_b)) { - total_size = le64_to_cpu(attr_b->nres.total_size); - mask = (sbi->cluster_size << attr_b->nres.c_unit) - 1; - } else { - total_size = alloc_size; - mask = sbi->cluster_mask; - } - - if ((vbo & mask) || (bytes & mask)) { + mask = is_attr_ext(attr_b) ? + ((sbi->cluster_size << attr_b->nres.c_unit) - 1) : + sbi->cluster_mask; + if ((vbo | bytes) & mask) { /* Allow to collapse only cluster aligned ranges. */ return -EINVAL; } - if (vbo > data_size) + /* i_size - size of file with delay allocated clusters. */ + i_size = ni->vfs_inode.i_size; + + if (vbo > i_size) return -EINVAL; down_write(&ni->file.run_lock); - if (vbo + bytes >= data_size) { - u64 new_valid = min(ni->i_valid, vbo); + if (vbo + bytes >= i_size) { + valid_size = min(ni->i_valid, vbo); /* Simple truncate file at 'vbo'. */ truncate_setsize(&ni->vfs_inode, vbo); err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, vbo, - &new_valid, true, NULL); + &valid_size, true); - if (!err && new_valid < ni->i_valid) - ni->i_valid = new_valid; + if (!err && valid_size < ni->i_valid) + ni->i_valid = valid_size; goto out; } - /* - * Enumerate all attribute segments and collapse. - */ - alen = alloc_size >> sbi->cluster_bits; vcn = vbo >> sbi->cluster_bits; len = bytes >> sbi->cluster_bits; end = vcn + len; dealloc = 0; done = 0; + /* + * Check delayed clusters. + */ + if (ni->file.run_da.count) { + struct runs_tree *run_da = &ni->file.run_da; + if (run_is_mapped_full(run_da, vcn, end - 1)) { + /* + * The requested range is full in delayed clusters. + */ + err = attr_set_size_ex(ni, ATTR_DATA, NULL, 0, run, + i_size - bytes, NULL, false, + NULL, true); + goto out; + } + + /* Collapse request crosses real and delayed clusters. */ + err = ni_allocate_da_blocks_locked(ni); + if (err) + goto out; + + /* Layout of records maybe changed. */ + le_b = NULL; + attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, + &mi_b); + if (!attr_b || !attr_b->non_res) { + err = -ENOENT; + goto out; + } + } + + data_size = le64_to_cpu(attr_b->nres.data_size); + alloc_size = le64_to_cpu(attr_b->nres.alloc_size); + total_size = is_attr_ext(attr_b) ? + le64_to_cpu(attr_b->nres.total_size) : + alloc_size; + alen = alloc_size >> sbi->cluster_bits; + a_flags = attr_b->flags; svcn = le64_to_cpu(attr_b->nres.svcn); evcn1 = le64_to_cpu(attr_b->nres.evcn) + 1; @@ -1947,6 +2091,9 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) goto out; } + /* + * Enumerate all attribute segments and collapse. + */ for (;;) { CLST vcn1, eat, next_svcn; @@ -1974,13 +2121,13 @@ int attr_collapse_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) vcn1 = vcn + done; /* original vcn in attr/run. */ eat = min(end, evcn1) - vcn1; - err = run_deallocate_ex(sbi, run, vcn1, eat, &dealloc, true); + err = run_deallocate_ex(sbi, run, vcn1, eat, &dealloc, true, + NULL); if (err) goto out; if (svcn + eat < evcn1) { /* Collapse a part of this attribute segment. */ - if (!run_collapse_range(run, vcn1, eat, done)) { err = -ENOMEM; goto out; @@ -2161,9 +2308,9 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size) bytes = alloc_size; bytes -= vbo; - if ((vbo & mask) || (bytes & mask)) { + if ((vbo | bytes) & mask) { /* We have to zero a range(s). */ - if (frame_size == NULL) { + if (!frame_size) { /* Caller insists range is aligned. */ return -EINVAL; } @@ -2222,7 +2369,8 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size) * Calculate how many clusters there are. * Don't do any destructive actions. */ - err = run_deallocate_ex(NULL, run, vcn1, zero, &hole2, false); + err = run_deallocate_ex(NULL, run, vcn1, zero, &hole2, false, + NULL); if (err) goto done; @@ -2260,7 +2408,8 @@ int attr_punch_hole(struct ntfs_inode *ni, u64 vbo, u64 bytes, u32 *frame_size) } /* Real deallocate. Should not fail. */ - run_deallocate_ex(sbi, &run2, vcn1, zero, &hole, true); + run_deallocate_ex(sbi, &run2, vcn1, zero, &hole, true, + &ni->file.run_da); next_attr: /* Free all allocated memory. */ @@ -2372,7 +2521,7 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) return -EINVAL; } - if ((vbo & mask) || (bytes & mask)) { + if ((vbo | bytes) & mask) { /* Allow to insert only frame aligned ranges. */ return -EINVAL; } @@ -2391,7 +2540,7 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) if (!attr_b->non_res) { err = attr_set_size(ni, ATTR_DATA, NULL, 0, run, - data_size + bytes, NULL, false, NULL); + data_size + bytes, NULL, false); le_b = NULL; attr_b = ni_find_attr(ni, NULL, &le_b, ATTR_DATA, NULL, 0, NULL, @@ -2414,7 +2563,7 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) goto done; } - /* Resident files becomes nonresident. */ + /* Resident file becomes nonresident. */ data_size = le64_to_cpu(attr_b->nres.data_size); alloc_size = le64_to_cpu(attr_b->nres.alloc_size); } @@ -2451,10 +2600,13 @@ int attr_insert_range(struct ntfs_inode *ni, u64 vbo, u64 bytes) if (err) goto out; - if (!run_insert_range(run, vcn, len)) { - err = -ENOMEM; + err = run_insert_range(run, vcn, len); + if (err) + goto out; + + err = run_insert_range_da(&ni->file.run_da, vcn, len); + if (err) goto out; - } /* Try to pack in current record as much as possible. */ err = mi_pack_runs(mi, attr, run, evcn1 + len - svcn); diff --git a/fs/ntfs3/attrlist.c b/fs/ntfs3/attrlist.c index a4d74bed74fa..270a29323530 100644 --- a/fs/ntfs3/attrlist.c +++ b/fs/ntfs3/attrlist.c @@ -52,6 +52,11 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) if (!attr->non_res) { lsize = le32_to_cpu(attr->res.data_size); + if (!lsize) { + err = -EINVAL; + goto out; + } + /* attr is resident: lsize < record_size (1K or 4K) */ le = kvmalloc(al_aligned(lsize), GFP_KERNEL); if (!le) { @@ -66,6 +71,10 @@ int ntfs_load_attr_list(struct ntfs_inode *ni, struct ATTRIB *attr) u16 run_off = le16_to_cpu(attr->nres.run_off); lsize = le64_to_cpu(attr->nres.data_size); + if (!lsize) { + err = -EINVAL; + goto out; + } run_init(&ni->attr_list.run); @@ -336,8 +345,8 @@ int al_add_le(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name, le->id = id; memcpy(le->name, name, sizeof(short) * name_len); - err = attr_set_size(ni, ATTR_LIST, NULL, 0, &al->run, new_size, - &new_size, true, &attr); + err = attr_set_size_ex(ni, ATTR_LIST, NULL, 0, &al->run, new_size, + &new_size, true, &attr, false); if (err) { /* Undo memmove above. */ memmove(le, Add2Ptr(le, sz), old_size - off); @@ -395,8 +404,8 @@ int al_update(struct ntfs_inode *ni, int sync) * Attribute list increased on demand in al_add_le. * Attribute list decreased here. */ - err = attr_set_size(ni, ATTR_LIST, NULL, 0, &al->run, al->size, NULL, - false, &attr); + err = attr_set_size_ex(ni, ATTR_LIST, NULL, 0, &al->run, al->size, NULL, + false, &attr, false); if (err) goto out; diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c index 65d05e6a0566..60b362f388d9 100644 --- a/fs/ntfs3/bitmap.c +++ b/fs/ntfs3/bitmap.c @@ -508,6 +508,8 @@ static int wnd_rescan(struct wnd_bitmap *wnd) size_t wpos, wbit, iw, vbo; struct buffer_head *bh = NULL; CLST lcn, clen; + struct file_ra_state *ra; + struct address_space *mapping = sb->s_bdev->bd_mapping; wnd->uptodated = 0; wnd->extent_max = 0; @@ -516,6 +518,13 @@ static int wnd_rescan(struct wnd_bitmap *wnd) vbo = 0; + /* Allocate in memory instead of stack. Not critical if failed. */ + ra = kzalloc_obj(*ra, GFP_NOFS); + if (ra) { + file_ra_state_init(ra, mapping); + ra->ra_pages = (wnd->nbits / 8 + PAGE_SIZE - 1) >> PAGE_SHIFT; + } + for (iw = 0; iw < wnd->nwnd; iw++) { if (iw + 1 == wnd->nwnd) wbits = wnd->bits_last; @@ -552,6 +561,13 @@ static int wnd_rescan(struct wnd_bitmap *wnd) len = ((u64)clen << cluster_bits) - off; } + if (ra) { + pgoff_t idx = lbo >> PAGE_SHIFT; + if (!ra_has_index(ra, idx)) + page_cache_sync_readahead(mapping, ra, NULL, + idx, 1); + } + bh = ntfs_bread(sb, lbo >> sb->s_blocksize_bits); if (!bh) { err = -EIO; @@ -638,6 +654,7 @@ static int wnd_rescan(struct wnd_bitmap *wnd) } out: + kfree(ra); return err; } diff --git a/fs/ntfs3/dir.c b/fs/ntfs3/dir.c index 596f8c62f033..4652a56ad105 100644 --- a/fs/ntfs3/dir.c +++ b/fs/ntfs3/dir.c @@ -393,33 +393,77 @@ static int ntfs_read_hdr(struct ntfs_sb_info *sbi, struct ntfs_inode *ni, * ntfs_readdir - file_operations::iterate_shared * * Use non sorted enumeration. - * We have an example of broken volume where sorted enumeration - * counts each name twice. + * Sorted enumeration may result infinite loop if names tree contains loop. */ static int ntfs_readdir(struct file *file, struct dir_context *ctx) { const struct INDEX_ROOT *root; - u64 vbo; size_t bit; - loff_t eod; int err = 0; struct inode *dir = file_inode(file); struct ntfs_inode *ni = ntfs_i(dir); struct super_block *sb = dir->i_sb; struct ntfs_sb_info *sbi = sb->s_fs_info; loff_t i_size = i_size_read(dir); - u32 pos = ctx->pos; + u64 pos = ctx->pos; u8 *name = NULL; struct indx_node *node = NULL; u8 index_bits = ni->dir.index_bits; + size_t max_bit = i_size >> ni->dir.index_bits; + loff_t eod = i_size + sbi->record_size; /* Name is a buffer of PATH_MAX length. */ static_assert(NTFS_NAME_LEN * 4 < PATH_MAX); - eod = i_size + sbi->record_size; + if (!pos) { + /* + * ni->dir.version increments each directory change. + * Save the initial value of ni->dir.version. + */ + file->private_data = (void *)ni->dir.version; + } - if (pos >= eod) - return 0; + if (pos >= eod) { + if (file->private_data == (void *)ni->dir.version) { + /* No changes since first readdir. */ + return 0; + } + + /* + * Handle directories that changed after the initial readdir(). + * + * Some user space code implements recursive removal like this instead + * of calling rmdir(2) directly: + * + * fd = opendir(path); + * while ((dent = readdir(fd))) + * unlinkat(dirfd(fd), dent->d_name, 0); + * closedir(fd); + * + * POSIX leaves unspecified what readdir() should return once the + * directory has been modified after opendir()/rewinddir(), so this + * pattern is not guaranteed to work on all filesystems or platforms. + * + * In ntfs3 the internal name tree may be reshaped while entries are + * being removed, so there is no stable anchor for continuing a + * single-pass walk based on the original readdir() order. + * + * In practice some widely used tools (for example certain rm(1) + * implementations) have used this readdir()/unlink() loop, and some + * filesystems behave in a way that effectively makes it work in the + * common case. + * + * The code below follows that practice and tries to provide + * "rmdir-like" behaviour for such callers on ntfs3, even though the + * situation is not strictly defined by the APIs. + * + * Apple documents the same readdir()/unlink() issue and a workaround + * for HFS file systems in: + * https://web.archive.org/web/20220122122948/https:/support.apple.com/kb/TA21420?locale=en_US + */ + ctx->pos = pos = 3; + file->private_data = (void *)ni->dir.version; + } if (!dir_emit_dots(file, ctx)) return 0; @@ -454,58 +498,58 @@ static int ntfs_readdir(struct file *file, struct dir_context *ctx) if (pos >= sbi->record_size) { bit = (pos - sbi->record_size) >> index_bits; } else { + /* + * Add each name from root in 'ctx'. + */ err = ntfs_read_hdr(sbi, ni, &root->ihdr, 0, pos, name, ctx); if (err) goto out; bit = 0; } - if (!i_size) { - ctx->pos = eod; - goto out; - } - - for (;;) { - vbo = (u64)bit << index_bits; - if (vbo >= i_size) { - ctx->pos = eod; - goto out; - } - + /* + * Enumerate indexes until the end of dir. + */ + for (; bit < max_bit; bit += 1) { + /* Get the next used index. */ err = indx_used_bit(&ni->dir, ni, &bit); if (err) goto out; if (bit == MINUS_ONE_T) { - ctx->pos = eod; - goto out; + /* no more used indexes. end of dir. */ + break; } - vbo = (u64)bit << index_bits; - if (vbo >= i_size) { + if (bit >= max_bit) { + /* Corrupted directory. */ err = -EINVAL; goto out; } - err = indx_read(&ni->dir, ni, bit << ni->dir.idx2vbn_bits, - &node); + err = indx_read_ra(&ni->dir, ni, bit << ni->dir.idx2vbn_bits, + &node, &file->f_ra); if (err) goto out; + /* + * Add each name from index in 'ctx'. + */ err = ntfs_read_hdr(sbi, ni, &node->index->ihdr, - vbo + sbi->record_size, pos, name, ctx); + ((u64)bit << index_bits) + sbi->record_size, + pos, name, ctx); if (err) goto out; - - bit += 1; } out: - kfree(name); put_indx_node(node); - if (err == 1) { + if (!err) { + /* End of directory. */ + ctx->pos = eod; + } else if (err == 1) { /* 'ctx' is full. */ err = 0; } else if (err == -ENOENT) { @@ -624,7 +668,7 @@ const struct file_operations ntfs_dir_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .iterate_shared = ntfs_readdir, - .fsync = generic_file_fsync, + .fsync = ntfs_file_fsync, .open = ntfs_file_open, .unlocked_ioctl = ntfs_ioctl, #ifdef CONFIG_COMPAT diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 6cb4479072a6..7eecf1e01f74 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "debug.h" #include "ntfs.h" @@ -26,6 +27,38 @@ */ #define NTFS3_IOC_SHUTDOWN _IOR('X', 125, __u32) +/* + * Helper for ntfs_should_use_dio. + */ +static u32 ntfs_dio_alignment(struct inode *inode) +{ + struct ntfs_inode *ni = ntfs_i(inode); + + if (is_resident(ni)) { + /* Check delalloc. */ + if (!ni->file.run_da.count) + return 0; + } + + /* In most cases this is bdev_logical_block_size(bdev). */ + return ni->mi.sbi->bdev_blocksize; +} + +/* + * Returns %true if the given DIO request should be attempted with DIO, or + * %false if it should fall back to buffered I/O. + */ +static bool ntfs_should_use_dio(struct kiocb *iocb, struct iov_iter *iter) +{ + struct inode *inode = file_inode(iocb->ki_filp); + u32 dio_align = ntfs_dio_alignment(inode); + + if (!dio_align) + return false; + + return IS_ALIGNED(iocb->ki_pos | iov_iter_alignment(iter), dio_align); +} + static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg) { struct fstrim_range __user *user_range; @@ -186,13 +219,10 @@ int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path, static int ntfs_extend_initialized_size(struct file *file, struct ntfs_inode *ni, - const loff_t valid, const loff_t new_valid) { struct inode *inode = &ni->vfs_inode; - struct address_space *mapping = inode->i_mapping; - struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info; - loff_t pos = valid; + const loff_t valid = ni->i_valid; int err; if (valid >= new_valid) @@ -203,142 +233,41 @@ static int ntfs_extend_initialized_size(struct file *file, return 0; } - WARN_ON(is_compressed(ni)); - - for (;;) { - u32 zerofrom, len; - struct folio *folio; - u8 bits; - CLST vcn, lcn, clen; - - if (is_sparsed(ni)) { - bits = sbi->cluster_bits; - vcn = pos >> bits; - - err = attr_data_get_block(ni, vcn, 1, &lcn, &clen, NULL, - false); - if (err) - goto out; - - if (lcn == SPARSE_LCN) { - pos = ((loff_t)clen + vcn) << bits; - ni->i_valid = pos; - goto next; - } - } - - zerofrom = pos & (PAGE_SIZE - 1); - len = PAGE_SIZE - zerofrom; - - if (pos + len > new_valid) - len = new_valid - pos; - - err = ntfs_write_begin(NULL, mapping, pos, len, &folio, NULL); - if (err) - goto out; - - folio_zero_range(folio, zerofrom, folio_size(folio) - zerofrom); - - err = ntfs_write_end(NULL, mapping, pos, len, len, folio, NULL); - if (err < 0) - goto out; - pos += len; - -next: - if (pos >= new_valid) - break; - - balance_dirty_pages_ratelimited(mapping); - cond_resched(); + err = iomap_zero_range(inode, valid, new_valid - valid, NULL, + &ntfs_iomap_ops, &ntfs_iomap_folio_ops, NULL); + if (err) { + ni->i_valid = valid; + ntfs_inode_warn(inode, + "failed to extend initialized size to %llx.", + new_valid); + return err; } return 0; - -out: - ni->i_valid = valid; - ntfs_inode_warn(inode, "failed to extend initialized size to %llx.", - new_valid); - return err; } -/* - * ntfs_zero_range - Helper function for punch_hole. - * - * It zeroes a range [vbo, vbo_to). - */ -static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to) +static void ntfs_filemap_close(struct vm_area_struct *vma) { - int err = 0; - struct address_space *mapping = inode->i_mapping; - u32 blocksize = i_blocksize(inode); - pgoff_t idx = vbo >> PAGE_SHIFT; - u32 from = vbo & (PAGE_SIZE - 1); - pgoff_t idx_end = (vbo_to + PAGE_SIZE - 1) >> PAGE_SHIFT; - loff_t page_off; - struct buffer_head *head, *bh; - u32 bh_next, bh_off, to; - sector_t iblock; - struct folio *folio; - bool dirty = false; + struct inode *inode = file_inode(vma->vm_file); + struct ntfs_inode *ni = ntfs_i(inode); + u64 from = (u64)vma->vm_pgoff << PAGE_SHIFT; + u64 to = min_t(u64, i_size_read(inode), + from + vma->vm_end - vma->vm_start); - for (; idx < idx_end; idx += 1, from = 0) { - page_off = (loff_t)idx << PAGE_SHIFT; - to = (page_off + PAGE_SIZE) > vbo_to ? (vbo_to - page_off) : - PAGE_SIZE; - iblock = page_off >> inode->i_blkbits; - - folio = __filemap_get_folio( - mapping, idx, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, - mapping_gfp_constraint(mapping, ~__GFP_FS)); - if (IS_ERR(folio)) - return PTR_ERR(folio); - - head = folio_buffers(folio); - if (!head) - head = create_empty_buffers(folio, blocksize, 0); - - bh = head; - bh_off = 0; - do { - bh_next = bh_off + blocksize; - - if (bh_next <= from || bh_off >= to) - continue; - - if (!buffer_mapped(bh)) { - ntfs_get_block(inode, iblock, bh, 0); - /* Unmapped? It's a hole - nothing to do. */ - if (!buffer_mapped(bh)) - continue; - } - - /* Ok, it's mapped. Make sure it's up-to-date. */ - if (folio_test_uptodate(folio)) - set_buffer_uptodate(bh); - else if (bh_read(bh, 0) < 0) { - err = -EIO; - folio_unlock(folio); - folio_put(folio); - goto out; - } - - mark_buffer_dirty(bh); - } while (bh_off = bh_next, iblock += 1, - head != (bh = bh->b_this_page)); - - folio_zero_segment(folio, from, to); - dirty = true; - - folio_unlock(folio); - folio_put(folio); - cond_resched(); - } -out: - if (dirty) + if (ni->i_valid < to) { + ni->i_valid = to; mark_inode_dirty(inode); - return err; + } } +/* Copy of generic_file_vm_ops. */ +static const struct vm_operations_struct ntfs_file_vm_ops = { + .close = ntfs_filemap_close, + .fault = filemap_fault, + .map_pages = filemap_map_pages, + .page_mkwrite = filemap_page_mkwrite, +}; + /* * ntfs_file_mmap_prepare - file_operations::mmap_prepare */ @@ -347,8 +276,7 @@ static int ntfs_file_mmap_prepare(struct vm_area_desc *desc) struct file *file = desc->file; struct inode *inode = file_inode(file); struct ntfs_inode *ni = ntfs_i(inode); - u64 from = ((u64)desc->pgoff << PAGE_SHIFT); - bool rw = desc->vm_flags & VM_WRITE; + const bool rw = vma_desc_test_flags(desc, VMA_WRITE_BIT); int err; /* Avoid any operation if inode is bad. */ @@ -379,7 +307,8 @@ static int ntfs_file_mmap_prepare(struct vm_area_desc *desc) } if (rw) { - u64 to = min_t(loff_t, i_size_read(inode), + u64 from = (u64)desc->pgoff << PAGE_SHIFT; + u64 to = min_t(u64, i_size_read(inode), from + vma_desc_size(desc)); if (is_sparsed(ni)) { @@ -392,7 +321,8 @@ static int ntfs_file_mmap_prepare(struct vm_area_desc *desc) for (; vcn < end; vcn += len) { err = attr_data_get_block(ni, vcn, 1, &lcn, - &len, &new, true); + &len, &new, true, + NULL, false); if (err) goto out; } @@ -403,8 +333,7 @@ static int ntfs_file_mmap_prepare(struct vm_area_desc *desc) err = -EAGAIN; goto out; } - err = ntfs_extend_initialized_size(file, ni, - ni->i_valid, to); + err = ntfs_extend_initialized_size(file, ni, to); inode_unlock(inode); if (err) goto out; @@ -412,6 +341,8 @@ static int ntfs_file_mmap_prepare(struct vm_area_desc *desc) } err = generic_file_mmap_prepare(desc); + if (!err && rw) + desc->vm_ops = &ntfs_file_vm_ops; out: return err; } @@ -432,55 +363,23 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count, ntfs_set_state(ni->mi.sbi, NTFS_DIRTY_DIRTY); if (end > inode->i_size) { + /* + * Normal files: increase file size, allocate space. + * Sparse/Compressed: increase file size. No space allocated. + */ err = ntfs_set_size(inode, end); if (err) goto out; } if (extend_init && !is_compressed(ni)) { - err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos); + err = ntfs_extend_initialized_size(file, ni, pos); if (err) goto out; } else { err = 0; } - if (file && is_sparsed(ni)) { - /* - * This code optimizes large writes to sparse file. - * TODO: merge this fragment with fallocate fragment. - */ - struct ntfs_sb_info *sbi = ni->mi.sbi; - CLST vcn = pos >> sbi->cluster_bits; - CLST cend = bytes_to_cluster(sbi, end); - CLST cend_v = bytes_to_cluster(sbi, ni->i_valid); - CLST lcn, clen; - bool new; - - if (cend_v > cend) - cend_v = cend; - - /* - * Allocate and zero new clusters. - * Zeroing these clusters may be too long. - */ - for (; vcn < cend_v; vcn += clen) { - err = attr_data_get_block(ni, vcn, cend_v - vcn, &lcn, - &clen, &new, true); - if (err) - goto out; - } - /* - * Allocate but not zero new clusters. - */ - for (; vcn < cend; vcn += clen) { - err = attr_data_get_block(ni, vcn, cend - vcn, &lcn, - &clen, &new, false); - if (err) - goto out; - } - } - inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); mark_inode_dirty(inode); @@ -504,53 +403,37 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count, static int ntfs_truncate(struct inode *inode, loff_t new_size) { - struct super_block *sb = inode->i_sb; + int err; struct ntfs_inode *ni = ntfs_i(inode); - int err, dirty = 0; - u64 new_valid; - - if (!S_ISREG(inode->i_mode)) - return 0; - - if (is_compressed(ni)) { - if (ni->i_valid > new_size) - ni->i_valid = new_size; - } else { - err = block_truncate_page(inode->i_mapping, new_size, - ntfs_get_block); - if (err) - return err; - } - - new_valid = ntfs_up_block(sb, min_t(u64, ni->i_valid, new_size)); + u64 new_valid = min_t(u64, ni->i_valid, new_size); truncate_setsize(inode, new_size); ni_lock(ni); down_write(&ni->file.run_lock); - err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size, - &new_valid, ni->mi.sbi->options->prealloc, NULL); + err = attr_set_size_ex(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size, + &new_valid, ni->mi.sbi->options->prealloc, NULL, + false); up_write(&ni->file.run_lock); - if (new_valid < ni->i_valid) - ni->i_valid = new_valid; + ni->i_valid = new_valid; ni_unlock(ni); + if (err) + return err; + ni->std_fa |= FILE_ATTRIBUTE_ARCHIVE; inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode)); if (!IS_DIRSYNC(inode)) { - dirty = 1; + mark_inode_dirty(inode); } else { err = ntfs_sync_inode(inode); if (err) return err; } - if (dirty) - mark_inode_dirty(inode); - return 0; } @@ -623,7 +506,7 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) if (mode & FALLOC_FL_PUNCH_HOLE) { u32 frame_size; - loff_t mask, vbo_a, end_a, tmp; + loff_t mask, vbo_a, end_a, tmp, from; err = filemap_write_and_wait_range(mapping, vbo_down, LLONG_MAX); @@ -643,24 +526,24 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) /* Process not aligned punch. */ err = 0; + if (end > i_size) + end = i_size; mask = frame_size - 1; vbo_a = (vbo + mask) & ~mask; end_a = end & ~mask; tmp = min(vbo_a, end); - if (tmp > vbo) { - err = ntfs_zero_range(inode, vbo, tmp); + from = min_t(loff_t, ni->i_valid, vbo); + /* Zero head of punch. */ + if (tmp > from) { + err = iomap_zero_range(inode, from, tmp - from, NULL, + &ntfs_iomap_ops, + &ntfs_iomap_folio_ops, NULL); if (err) goto out; } - if (vbo < end_a && end_a < end) { - err = ntfs_zero_range(inode, end_a, end); - if (err) - goto out; - } - - /* Aligned punch_hole */ + /* Aligned punch_hole. Deallocate clusters. */ if (end_a > vbo_a) { ni_lock(ni); err = attr_punch_hole(ni, vbo_a, end_a - vbo_a, NULL); @@ -668,6 +551,15 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) if (err) goto out; } + + /* Zero tail of punch. */ + if (vbo < end_a && end_a < end) { + err = iomap_zero_range(inode, end_a, end - end_a, NULL, + &ntfs_iomap_ops, + &ntfs_iomap_folio_ops, NULL); + if (err) + goto out; + } } else if (mode & FALLOC_FL_COLLAPSE_RANGE) { /* * Write tail of the last page before removed range since @@ -765,17 +657,26 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) for (; vcn < cend_v; vcn += clen) { err = attr_data_get_block(ni, vcn, cend_v - vcn, &lcn, &clen, &new, - true); + true, NULL, false); if (err) goto out; } + + /* + * Moving up 'valid size'. + */ + err = ntfs_extend_initialized_size( + file, ni, (u64)cend_v << cluster_bits); + if (err) + goto out; + /* * Allocate but not zero new clusters. */ for (; vcn < cend; vcn += clen) { err = attr_data_get_block(ni, vcn, cend - vcn, &lcn, &clen, &new, - false); + false, NULL, false); if (err) goto out; } @@ -786,10 +687,11 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len) /* True - Keep preallocated. */ err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, i_size, &ni->i_valid, - true, NULL); + true); ni_unlock(ni); if (err) goto out; + i_size_write(inode, i_size); } else if (new_size > i_size) { i_size_write(inode, new_size); } @@ -926,12 +828,18 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct ntfs_inode *ni = ntfs_i(inode); + size_t bytes = iov_iter_count(iter); + loff_t valid, i_size, vbo, end; + unsigned int dio_flags; ssize_t err; err = check_read_restriction(inode); if (err) return err; + if (!bytes) + return 0; /* skip atime */ + if (is_compressed(ni)) { if (iocb->ki_flags & IOCB_DIRECT) { ntfs_inode_warn( @@ -942,17 +850,63 @@ static ssize_t ntfs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) file->f_ra.ra_pages = 0; } - /* Check minimum alignment for dio. */ - if (iocb->ki_flags & IOCB_DIRECT) { - struct super_block *sb = inode->i_sb; - struct ntfs_sb_info *sbi = sb->s_fs_info; - if ((iocb->ki_pos | iov_iter_alignment(iter)) & - sbi->bdev_blocksize_mask) { - iocb->ki_flags &= ~IOCB_DIRECT; - } + /* Fallback to buffered I/O if the inode does not support direct I/O. */ + if (!(iocb->ki_flags & IOCB_DIRECT) || + !ntfs_should_use_dio(iocb, iter)) { + iocb->ki_flags &= ~IOCB_DIRECT; + return generic_file_read_iter(iocb, iter); } - return generic_file_read_iter(iocb, iter); + if (iocb->ki_flags & IOCB_NOWAIT) { + if (!inode_trylock_shared(inode)) + return -EAGAIN; + } else { + inode_lock_shared(inode); + } + + vbo = iocb->ki_pos; + end = vbo + bytes; + dio_flags = 0; + valid = ni->i_valid; + i_size = inode->i_size; + + if (vbo < valid) { + if (valid < end) { + /* read cross 'valid' size. */ + dio_flags |= IOMAP_DIO_FORCE_WAIT; + } + + if (ni->file.run_da.count) { + /* Direct I/O is not compatible with delalloc. */ + err = ni_allocate_da_blocks(ni); + if (err) + goto out; + } + + err = iomap_dio_rw(iocb, iter, &ntfs_iomap_ops, NULL, dio_flags, + NULL, 0); + + if (err <= 0) + goto out; + end = vbo + err; + if (valid < end) { + size_t to_zero = end - valid; + /* Fix iter. */ + iov_iter_revert(iter, to_zero); + iov_iter_zero(to_zero, iter); + } + } else if (vbo < i_size) { + if (end > i_size) + bytes = i_size - vbo; + iov_iter_zero(bytes, iter); + iocb->ki_pos += bytes; + err = bytes; + } + +out: + inode_unlock_shared(inode); + file_accessed(iocb->ki_filp); + return err; } /* @@ -996,7 +950,7 @@ static int ntfs_get_frame_pages(struct address_space *mapping, pgoff_t index, folio = __filemap_get_folio(mapping, index, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, - gfp_mask); + gfp_mask | __GFP_ZERO); if (IS_ERR(folio)) { while (npages--) { folio = page_folio(pages[npages]); @@ -1052,7 +1006,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) return -EOPNOTSUPP; } - pages = kmalloc_array(pages_per_frame, sizeof(struct page *), GFP_NOFS); + pages = kmalloc_objs(struct page *, pages_per_frame, GFP_NOFS); if (!pages) return -ENOMEM; @@ -1073,7 +1027,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb, struct iov_iter *from) off = valid & (frame_size - 1); err = attr_data_get_block(ni, frame << NTFS_LZNT_CUNIT, 1, &lcn, - &clen, NULL, false); + &clen, NULL, false, NULL, false); if (err) goto out; @@ -1265,6 +1219,9 @@ static int check_write_restriction(struct inode *inode) return -EOPNOTSUPP; } + if (unlikely(IS_IMMUTABLE(inode))) + return -EPERM; + return 0; } @@ -1276,8 +1233,7 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); struct ntfs_inode *ni = ntfs_i(inode); - ssize_t ret; - int err; + ssize_t ret, err; if (!inode_trylock(inode)) { if (iocb->ki_flags & IOCB_NOWAIT) @@ -1315,15 +1271,75 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) if (ret) goto out; - ret = is_compressed(ni) ? ntfs_compress_write(iocb, from) : - __generic_file_write_iter(iocb, from); + if (is_compressed(ni)) { + ret = ntfs_compress_write(iocb, from); + goto out; + } + + /* Fallback to buffered I/O if the inode does not support direct I/O. */ + if (!(iocb->ki_flags & IOCB_DIRECT) || + !ntfs_should_use_dio(iocb, from)) { + iocb->ki_flags &= ~IOCB_DIRECT; + + ret = iomap_file_buffered_write(iocb, from, &ntfs_iomap_ops, + &ntfs_iomap_folio_ops, NULL); + inode_unlock(inode); + + if (likely(ret > 0)) + ret = generic_write_sync(iocb, ret); + + return ret; + } + + if (ni->file.run_da.count) { + /* Direct I/O is not compatible with delalloc. */ + ret = ni_allocate_da_blocks(ni); + if (ret) + goto out; + } + + ret = iomap_dio_rw(iocb, from, &ntfs_iomap_ops, NULL, 0, NULL, 0); + + if (ret == -ENOTBLK) { + /* Returns -ENOTBLK in case of a page invalidation failure for writes.*/ + /* The callers needs to fall back to buffered I/O in this case. */ + ret = 0; + } + + if (ret >= 0 && iov_iter_count(from)) { + loff_t offset = iocb->ki_pos, endbyte; + + iocb->ki_flags &= ~IOCB_DIRECT; + err = iomap_file_buffered_write(iocb, from, &ntfs_iomap_ops, + &ntfs_iomap_folio_ops, NULL); + if (err < 0) { + ret = err; + goto out; + } + + /* + * We need to ensure that the pages within the page cache for + * the range covered by this I/O are written to disk and + * invalidated. This is in attempt to preserve the expected + * direct I/O semantics in the case we fallback to buffered I/O + * to complete off the I/O request. + */ + ret += err; + endbyte = offset + err - 1; + err = filemap_write_and_wait_range(inode->i_mapping, offset, + endbyte); + if (err) { + ret = err; + goto out; + } + + invalidate_mapping_pages(inode->i_mapping, offset >> PAGE_SHIFT, + endbyte >> PAGE_SHIFT); + } out: inode_unlock(inode); - if (ret > 0) - ret = generic_write_sync(iocb, ret); - return ret; } @@ -1362,39 +1378,49 @@ int ntfs_file_open(struct inode *inode, struct file *file) #endif } + file->f_mode |= FMODE_NOWAIT | FMODE_CAN_ODIRECT; + return generic_file_open(inode, file); } /* * ntfs_file_release - file_operations::release + * + * Called when an inode is released. Note that this is different + * from ntfs_file_open: open gets called at every open, but release + * gets called only when /all/ the files are closed. */ static int ntfs_file_release(struct inode *inode, struct file *file) { - struct ntfs_inode *ni = ntfs_i(inode); - struct ntfs_sb_info *sbi = ni->mi.sbi; - int err = 0; + int err; + struct ntfs_inode *ni; - /* If we are last writer on the inode, drop the block reservation. */ - if (sbi->options->prealloc && - ((file->f_mode & FMODE_WRITE) && - atomic_read(&inode->i_writecount) == 1) - /* - * The only file when inode->i_fop = &ntfs_file_operations and - * init_rwsem(&ni->file.run_lock) is not called explicitly is MFT. - * - * Add additional check here. - */ - && inode->i_ino != MFT_REC_MFT) { + if (!(file->f_mode & FMODE_WRITE) || + atomic_read(&inode->i_writecount) != 1 || + inode->i_ino == MFT_REC_MFT) { + return 0; + } + + /* Close the last writer on the inode. */ + ni = ntfs_i(inode); + + /* Allocate delayed blocks (clusters). */ + err = ni_allocate_da_blocks(ni); + if (err) + goto out; + + if (ni->mi.sbi->options->prealloc) { ni_lock(ni); down_write(&ni->file.run_lock); + /* Deallocate preallocated. */ err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, - i_size_read(inode), &ni->i_valid, false, - NULL); + inode->i_size, &ni->i_valid, false); up_write(&ni->file.run_lock); ni_unlock(ni); } +out: return err; } @@ -1411,16 +1437,30 @@ int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, if (unlikely(is_bad_ni(ni))) return -EINVAL; - err = fiemap_prep(inode, fieinfo, start, &len, ~FIEMAP_FLAG_XATTR); - if (err) - return err; + if (is_compressed(ni)) { + /* Unfortunately cp -r incorrectly treats compressed clusters. */ + ntfs_inode_warn(inode, + "fiemap is not supported for compressed file"); + return -EOPNOTSUPP; + } - ni_lock(ni); + if (S_ISDIR(inode->i_mode)) { + /* TODO: add support for dirs (ATTR_ALLOC). */ + ntfs_inode_warn(inode, + "fiemap is not supported for directories"); + return -EOPNOTSUPP; + } - err = ni_fiemap(ni, fieinfo, start, len); + if (fieinfo->fi_flags & FIEMAP_FLAG_XATTR) { + ntfs_inode_warn(inode, "fiemap(xattr) is not supported"); + return -EOPNOTSUPP; + } - ni_unlock(ni); + inode_lock_shared(inode); + err = iomap_fiemap(inode, fieinfo, start, len, &ntfs_iomap_ops); + + inode_unlock_shared(inode); return err; } @@ -1444,13 +1484,62 @@ static ssize_t ntfs_file_splice_write(struct pipe_inode_info *pipe, /* * ntfs_file_fsync - file_operations::fsync */ -static int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) +int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) { struct inode *inode = file_inode(file); - if (unlikely(ntfs3_forced_shutdown(inode->i_sb))) + struct super_block *sb = inode->i_sb; + struct ntfs_sb_info *sbi = sb->s_fs_info; + int err, ret; + + if (unlikely(ntfs3_forced_shutdown(sb))) return -EIO; - return generic_file_fsync(file, start, end, datasync); + ret = file_write_and_wait_range(file, start, end); + if (ret) + return ret; + + ret = write_inode_now(inode, !datasync); + + if (!ret) { + ret = ni_write_parents(ntfs_i(inode), !datasync); + } + + if (!ret) { + ntfs_set_state(sbi, NTFS_DIRTY_CLEAR); + ntfs_update_mftmirr(sbi); + } + + err = sync_blockdev(sb->s_bdev); + if (unlikely(err && !ret)) + ret = err; + if (!ret) + blkdev_issue_flush(sb->s_bdev); + return ret; +} + +/* + * ntfs_llseek - file_operations::llseek + */ +static loff_t ntfs_llseek(struct file *file, loff_t offset, int whence) +{ + struct inode *inode = file->f_mapping->host; + struct ntfs_inode *ni = ntfs_i(inode); + loff_t maxbytes = ntfs_get_maxbytes(ni); + loff_t ret; + + if (whence == SEEK_DATA || whence == SEEK_HOLE) { + inode_lock_shared(inode); + /* Scan file for hole or data. */ + ret = ni_seek_data_or_hole(ni, offset, whence == SEEK_DATA); + inode_unlock_shared(inode); + + if (ret >= 0) + ret = vfs_setpos(file, ret, maxbytes); + } else { + ret = generic_file_llseek_size(file, offset, whence, maxbytes, + i_size_read(inode)); + } + return ret; } // clang-format off @@ -1464,7 +1553,7 @@ const struct inode_operations ntfs_file_inode_operations = { }; const struct file_operations ntfs_file_operations = { - .llseek = generic_file_llseek, + .llseek = ntfs_llseek, .read_iter = ntfs_file_read_iter, .write_iter = ntfs_file_write_iter, .unlocked_ioctl = ntfs_ioctl, diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index 641ddaf8d4a0..2e901d073fe9 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -123,6 +123,8 @@ void ni_clear(struct ntfs_inode *ni) indx_clear(&ni->dir); else { run_close(&ni->file.run); + ntfs_sub_da(ni->mi.sbi, run_len(&ni->file.run_da)); + run_close(&ni->file.run_da); #ifdef CONFIG_NTFS3_LZX_XPRESS if (ni->file.offs_folio) { /* On-demand allocated page for offsets. */ @@ -314,7 +316,7 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) { struct mft_inode *m; - m = kzalloc(sizeof(struct mft_inode), GFP_NOFS); + m = kzalloc_obj(struct mft_inode, GFP_NOFS); if (!m) return false; @@ -1850,183 +1852,11 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, return REPARSE_LINK; } -/* - * ni_fiemap - Helper for file_fiemap(). - * - * Assumed ni_lock. - * TODO: Less aggressive locks. - */ -int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - __u64 vbo, __u64 len) -{ - int err = 0; - struct ntfs_sb_info *sbi = ni->mi.sbi; - u8 cluster_bits = sbi->cluster_bits; - struct runs_tree run; - struct ATTRIB *attr; - CLST vcn = vbo >> cluster_bits; - CLST lcn, clen; - u64 valid = ni->i_valid; - u64 lbo, bytes; - u64 end, alloc_size; - size_t idx = -1; - u32 flags; - bool ok; - - run_init(&run); - if (S_ISDIR(ni->vfs_inode.i_mode)) { - attr = ni_find_attr(ni, NULL, NULL, ATTR_ALLOC, I30_NAME, - ARRAY_SIZE(I30_NAME), NULL, NULL); - } else { - attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, - NULL); - if (!attr) { - err = -EINVAL; - goto out; - } - if (is_attr_compressed(attr)) { - /* Unfortunately cp -r incorrectly treats compressed clusters. */ - err = -EOPNOTSUPP; - ntfs_inode_warn( - &ni->vfs_inode, - "fiemap is not supported for compressed file (cp -r)"); - goto out; - } - } - - if (!attr || !attr->non_res) { - err = fiemap_fill_next_extent( - fieinfo, 0, 0, - attr ? le32_to_cpu(attr->res.data_size) : 0, - FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_LAST | - FIEMAP_EXTENT_MERGED); - goto out; - } - - end = vbo + len; - alloc_size = le64_to_cpu(attr->nres.alloc_size); - if (end > alloc_size) - end = alloc_size; - - while (vbo < end) { - if (idx == -1) { - ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); - } else { - CLST vcn_next = vcn; - - ok = run_get_entry(&run, ++idx, &vcn, &lcn, &clen) && - vcn == vcn_next; - if (!ok) - vcn = vcn_next; - } - - if (!ok) { - err = attr_load_runs_vcn(ni, attr->type, - attr_name(attr), - attr->name_len, &run, vcn); - - if (err) - break; - - ok = run_lookup_entry(&run, vcn, &lcn, &clen, &idx); - - if (!ok) { - err = -EINVAL; - break; - } - } - - if (!clen) { - err = -EINVAL; // ? - break; - } - - if (lcn == SPARSE_LCN) { - vcn += clen; - vbo = (u64)vcn << cluster_bits; - continue; - } - - flags = FIEMAP_EXTENT_MERGED; - if (S_ISDIR(ni->vfs_inode.i_mode)) { - ; - } else if (is_attr_compressed(attr)) { - CLST clst_data; - - err = attr_is_frame_compressed(ni, attr, - vcn >> attr->nres.c_unit, - &clst_data, &run); - if (err) - break; - if (clst_data < NTFS_LZNT_CLUSTERS) - flags |= FIEMAP_EXTENT_ENCODED; - } else if (is_attr_encrypted(attr)) { - flags |= FIEMAP_EXTENT_DATA_ENCRYPTED; - } - - vbo = (u64)vcn << cluster_bits; - bytes = (u64)clen << cluster_bits; - lbo = (u64)lcn << cluster_bits; - - vcn += clen; - - if (vbo + bytes >= end) - bytes = end - vbo; - - if (vbo + bytes <= valid) { - ; - } else if (vbo >= valid) { - flags |= FIEMAP_EXTENT_UNWRITTEN; - } else { - /* vbo < valid && valid < vbo + bytes */ - u64 dlen = valid - vbo; - - if (vbo + dlen >= end) - flags |= FIEMAP_EXTENT_LAST; - - err = fiemap_fill_next_extent(fieinfo, vbo, lbo, dlen, - flags); - - if (err < 0) - break; - if (err == 1) { - err = 0; - break; - } - - vbo = valid; - bytes -= dlen; - if (!bytes) - continue; - - lbo += dlen; - flags |= FIEMAP_EXTENT_UNWRITTEN; - } - - if (vbo + bytes >= end) - flags |= FIEMAP_EXTENT_LAST; - - err = fiemap_fill_next_extent(fieinfo, vbo, lbo, bytes, flags); - if (err < 0) - break; - if (err == 1) { - err = 0; - break; - } - - vbo += bytes; - } - -out: - run_close(&run); - return err; -} - static struct page *ntfs_lock_new_page(struct address_space *mapping, - pgoff_t index, gfp_t gfp) + pgoff_t index, gfp_t gfp) { - struct folio *folio = __filemap_get_folio(mapping, index, - FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp); + struct folio *folio = __filemap_get_folio( + mapping, index, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp); struct page *page; if (IS_ERR(folio)) @@ -2046,18 +1876,18 @@ static struct page *ntfs_lock_new_page(struct address_space *mapping, } /* - * ni_readpage_cmpr + * ni_read_folio_cmpr * * When decompressing, we typically obtain more than one page per reference. * We inject the additional pages into the page cache. */ -int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio) +int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio) { int err; struct ntfs_sb_info *sbi = ni->mi.sbi; struct address_space *mapping = folio->mapping; - pgoff_t index = folio->index; - u64 frame_vbo, vbo = (u64)index << PAGE_SHIFT; + pgoff_t index; + u64 frame_vbo, vbo = folio_pos(folio); struct page **pages = NULL; /* Array of at most 16 pages. stack? */ u8 frame_bits; CLST frame; @@ -2085,7 +1915,7 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio) idx = (vbo - frame_vbo) >> PAGE_SHIFT; pages_per_frame = frame_size >> PAGE_SHIFT; - pages = kcalloc(pages_per_frame, sizeof(struct page *), GFP_NOFS); + pages = kzalloc_objs(struct page *, pages_per_frame, GFP_NOFS); if (!pages) { err = -ENOMEM; goto out; @@ -2107,7 +1937,9 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio) pages[i] = pg; } + ni_lock(ni); err = ni_read_frame(ni, frame_vbo, pages, pages_per_frame, 0); + ni_unlock(ni); out1: for (i = 0; i < pages_per_frame; i++) { @@ -2166,7 +1998,7 @@ int ni_decompress_file(struct ntfs_inode *ni) frame_bits = ni_ext_compress_bits(ni); frame_size = 1u << frame_bits; pages_per_frame = frame_size >> PAGE_SHIFT; - pages = kcalloc(pages_per_frame, sizeof(struct page *), GFP_NOFS); + pages = kzalloc_objs(struct page *, pages_per_frame, GFP_NOFS); if (!pages) { err = -ENOMEM; goto out; @@ -2184,7 +2016,8 @@ int ni_decompress_file(struct ntfs_inode *ni) for (vcn = vbo >> sbi->cluster_bits; vcn < end; vcn += clen) { err = attr_data_get_block(ni, vcn, cend - vcn, &lcn, - &clen, &new, false); + &clen, &new, false, NULL, + false); if (err) goto out; } @@ -2405,7 +2238,7 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, struct runs_tree *run = &ni->file.run; u64 valid_size = ni->i_valid; u64 vbo_disk; - size_t unc_size; + size_t unc_size = 0; u32 frame_size, i, ondisk_size; struct page *pg; struct ATTRIB *attr; @@ -3001,6 +2834,134 @@ bool ni_is_dirty(struct inode *inode) return false; } +/* + * ni_seek_data_or_hole + * + * Helper function for ntfs_llseek( SEEK_DATA/SEEK_HOLE ) + */ +loff_t ni_seek_data_or_hole(struct ntfs_inode *ni, loff_t offset, bool data) +{ + int err; + u8 cluster_bits = ni->mi.sbi->cluster_bits; + CLST vcn, lcn, clen; + loff_t vbo; + + /* Enumerate all fragments. */ + for (vcn = offset >> cluster_bits;; vcn += clen) { + err = attr_data_get_block(ni, vcn, 1, &lcn, &clen, NULL, false, + NULL, false); + if (err) { + return err; + } + + if (lcn == RESIDENT_LCN) { + /* clen - resident size in bytes. clen == ni->vfs_inode.i_size */ + if (offset >= clen) { + /* check eof. */ + return -ENXIO; + } + + if (data) { + return offset; + } + + return clen; + } + + if (lcn == EOF_LCN) { + if (data) { + return -ENXIO; + } + + /* implicit hole at the end of file. */ + return ni->vfs_inode.i_size; + } + + if (data) { + /* + * Adjust the file offset to the next location in the file greater than + * or equal to offset containing data. If offset points to data, then + * the file offset is set to offset. + */ + if (lcn != SPARSE_LCN) { + vbo = (u64)vcn << cluster_bits; + return max(vbo, offset); + } + } else { + /* + * Adjust the file offset to the next hole in the file greater than or + * equal to offset. If offset points into the middle of a hole, then the + * file offset is set to offset. If there is no hole past offset, then the + * file offset is adjusted to the end of the file + * (i.e., there is an implicit hole at the end of any file). + */ + if (lcn == SPARSE_LCN && + /* native compression hole begins at aligned vcn. */ + (!(ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) || + !(vcn & (NTFS_LZNT_CLUSTERS - 1)))) { + vbo = (u64)vcn << cluster_bits; + return max(vbo, offset); + } + } + + if (!clen) { + /* Corrupted file. */ + return -EINVAL; + } + } +} + +/* + * ni_write_parents + * + * Helper function for ntfs_file_fsync. + */ +int ni_write_parents(struct ntfs_inode *ni, int sync) +{ + int err = 0; + struct ATTRIB *attr = NULL; + struct ATTR_LIST_ENTRY *le = NULL; + struct ntfs_sb_info *sbi = ni->mi.sbi; + struct super_block *sb = sbi->sb; + + while ((attr = ni_find_attr(ni, attr, &le, ATTR_NAME, NULL, 0, NULL, + NULL))) { + struct inode *dir; + struct ATTR_FILE_NAME *fname; + + fname = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME); + if (!fname) + continue; + + /* Check simple case when parent inode equals current inode. */ + if (ino_get(&fname->home) == ni->vfs_inode.i_ino) { + if (MFT_REC_ROOT != ni->vfs_inode.i_ino) { + ntfs_set_state(sbi, NTFS_DIRTY_ERROR); + err = -EINVAL; + } + continue; + } + + dir = ntfs_iget5(sb, &fname->home, NULL); + if (IS_ERR(dir)) { + ntfs_inode_warn( + &ni->vfs_inode, + "failed to open parent directory r=%lx to write", + (long)ino_get(&fname->home)); + continue; + } + + if (!is_bad_inode(dir)) { + int err2 = write_inode_now(dir, sync); + if (!err) + err = err2; + } + iput(dir); + } + + return err; +} + /* * ni_update_parent * @@ -3277,3 +3238,62 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint) return 0; } + +/* + * Force to allocate all delay allocated clusters. + */ +int ni_allocate_da_blocks(struct ntfs_inode *ni) +{ + int err; + + ni_lock(ni); + down_write(&ni->file.run_lock); + + err = ni_allocate_da_blocks_locked(ni); + + up_write(&ni->file.run_lock); + ni_unlock(ni); + + return err; +} + +/* + * Force to allocate all delay allocated clusters. + */ +int ni_allocate_da_blocks_locked(struct ntfs_inode *ni) +{ + int err; + + if (!ni->file.run_da.count) + return 0; + + if (is_sparsed(ni)) { + CLST vcn, lcn, clen, alen; + bool new; + + /* + * Sparse file allocates clusters in 'attr_data_get_block_locked' + */ + while (run_get_entry(&ni->file.run_da, 0, &vcn, &lcn, &clen)) { + /* TODO: zero=true? */ + err = attr_data_get_block_locked(ni, vcn, clen, &lcn, + &alen, &new, true, + NULL, true); + if (err) + break; + if (!new) { + err = -EINVAL; + break; + } + } + } else { + /* + * Normal file allocates clusters in 'attr_set_size' + */ + err = attr_set_size_ex(ni, ATTR_DATA, NULL, 0, &ni->file.run, + ni->vfs_inode.i_size, &ni->i_valid, + false, NULL, true); + } + + return err; +} diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c index 38934e6978ec..272e45276143 100644 --- a/fs/ntfs3/fslog.c +++ b/fs/ntfs3/fslog.c @@ -1074,6 +1074,8 @@ struct ntfs_log { u32 client_undo_commit; struct restart_info rst_info, rst_info2; + + struct file_ra_state read_ahead; }; static inline u32 lsn_to_vbo(struct ntfs_log *log, const u64 lsn) @@ -1164,8 +1166,8 @@ static int read_log_page(struct ntfs_log *log, u32 vbo, page_buf = page_off ? log->one_page_buf : *buffer; - err = ntfs_read_run_nb(ni->mi.sbi, &ni->file.run, page_vbo, page_buf, - log->page_size, NULL); + err = ntfs_read_run_nb_ra(ni->mi.sbi, &ni->file.run, page_vbo, page_buf, + log->page_size, NULL, &log->read_ahead); if (err) goto out; @@ -2471,7 +2473,7 @@ static int read_log_rec_lcb(struct ntfs_log *log, u64 lsn, u32 ctx_mode, if (!verify_client_lsn(log, cr, lsn)) return -EINVAL; - lcb = kzalloc(sizeof(struct lcb), GFP_NOFS); + lcb = kzalloc_obj(struct lcb, GFP_NOFS); if (!lcb) return -ENOMEM; lcb->client = log->client_id; @@ -3028,6 +3030,26 @@ static struct ATTRIB *attr_create_nonres_log(struct ntfs_sb_info *sbi, return attr; } +/* + * update_oa_attr - Synchronize OpenAttr's attribute pointer with modified attribute + * @oa2: OpenAttr structure in memory that needs to be updated + * @attr: Modified attribute from MFT record to duplicate + * + * Returns true on success, false on allocation failure. + */ +static bool update_oa_attr(struct OpenAttr *oa2, struct ATTRIB *attr) +{ + void *p2; + + p2 = kmemdup(attr, le32_to_cpu(attr->size), GFP_NOFS); + if (p2) { + kfree(oa2->attr); + oa2->attr = p2; + return true; + } + return false; +} + /* * do_action - Common routine for the Redo and Undo Passes. * @rlsn: If it is NULL then undo. @@ -3095,8 +3117,7 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, /* Read from disk. */ err = mi_get(sbi, rno, &mi); if (err && op == InitializeFileRecordSegment) { - mi = kzalloc(sizeof(struct mft_inode), - GFP_NOFS); + mi = kzalloc_obj(struct mft_inode, GFP_NOFS); if (!mi) return -ENOMEM; err = mi_format_new(mi, sbi, rno, 0, false); @@ -3251,15 +3272,8 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, le16_add_cpu(&rec->hard_links, 1); oa2 = find_loaded_attr(log, attr, rno_base); - if (oa2) { - void *p2 = kmemdup(attr, le32_to_cpu(attr->size), - GFP_NOFS); - if (p2) { - // run_close(oa2->run1); - kfree(oa2->attr); - oa2->attr = p2; - } - } + if (oa2) + update_oa_attr(oa2, attr); mi->dirty = true; break; @@ -3318,16 +3332,8 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, memmove(Add2Ptr(attr, aoff), data, dlen); oa2 = find_loaded_attr(log, attr, rno_base); - if (oa2) { - void *p2 = kmemdup(attr, le32_to_cpu(attr->size), - GFP_NOFS); - if (p2) { - // run_close(&oa2->run0); - oa2->run1 = &oa2->run0; - kfree(oa2->attr); - oa2->attr = p2; - } - } + if (oa2 && update_oa_attr(oa2, attr)) + oa2->run1 = &oa2->run0; mi->dirty = true; break; @@ -3377,14 +3383,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, attr->nres.total_size = new_sz->total_size; oa2 = find_loaded_attr(log, attr, rno_base); - if (oa2) { - void *p2 = kmemdup(attr, le32_to_cpu(attr->size), - GFP_NOFS); - if (p2) { - kfree(oa2->attr); - oa2->attr = p2; - } - } + if (oa2) + update_oa_attr(oa2, attr); + mi->dirty = true; break; @@ -3429,6 +3430,9 @@ static int do_action(struct ntfs_log *log, struct OPEN_ATTR_ENRTY *oe, e1 = Add2Ptr(attr, le16_to_cpu(lrh->attr_off)); esize = le16_to_cpu(e1->size); + if (PtrOffset(e1, Add2Ptr(hdr, used)) < esize) + goto dirty_vol; + e2 = Add2Ptr(e1, esize); memmove(e1, e2, PtrOffset(e2, Add2Ptr(hdr, used))); @@ -3774,7 +3778,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized) u16 t16; u32 t32; - log = kzalloc(sizeof(struct ntfs_log), GFP_NOFS); + log = kzalloc_obj(struct ntfs_log, GFP_NOFS); if (!log) return -ENOMEM; @@ -4720,7 +4724,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized) goto next_dirty_page; } - oa = kzalloc(sizeof(struct OpenAttr), GFP_NOFS); + oa = kzalloc_obj(struct OpenAttr, GFP_NOFS); if (!oa) { err = -ENOMEM; goto out; @@ -5128,7 +5132,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized) undo_action_done: - ntfs_update_mftmirr(sbi, 0); + ntfs_update_mftmirr(sbi); sbi->flags &= ~NTFS_FLAGS_NEED_REPLAY; diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c index bd67ba7b5015..0df2aa81d884 100644 --- a/fs/ntfs3/fsntfs.c +++ b/fs/ntfs3/fsntfs.c @@ -445,36 +445,59 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len, } /* - * ntfs_check_for_free_space + * ntfs_check_free_space * * Check if it is possible to allocate 'clen' clusters and 'mlen' Mft records */ -bool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen) +bool ntfs_check_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen, + bool da) { size_t free, zlen, avail; struct wnd_bitmap *wnd; + CLST da_clusters = ntfs_get_da(sbi); wnd = &sbi->used.bitmap; down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_CLUSTERS); free = wnd_zeroes(wnd); + + if (free >= da_clusters) { + free -= da_clusters; + } else { + free = 0; + } + zlen = min_t(size_t, NTFS_MIN_MFT_ZONE, wnd_zone_len(wnd)); up_read(&wnd->rw_lock); - if (free < zlen + clen) + if (free < zlen + clen) { return false; + } avail = free - (zlen + clen); - wnd = &sbi->mft.bitmap; - down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT); - free = wnd_zeroes(wnd); - zlen = wnd_zone_len(wnd); - up_read(&wnd->rw_lock); + /* + * When delalloc is active then keep in mind some reserved space. + * The worst case: 1 mft record per each ~500 clusters. + */ + if (da) { + /* 1 mft record per each 1024 clusters. */ + mlen += da_clusters >> 10; + } - if (free >= zlen + mlen) - return true; + if (mlen || !avail) { + wnd = &sbi->mft.bitmap; + down_read_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT); + free = wnd_zeroes(wnd); + zlen = wnd_zone_len(wnd); + up_read(&wnd->rw_lock); - return avail >= bytes_to_cluster(sbi, mlen << sbi->record_bits); + if (free < zlen + mlen && + avail < bytes_to_cluster(sbi, mlen << sbi->record_bits)) { + return false; + } + } + + return true; } /* @@ -509,8 +532,8 @@ static int ntfs_extend_mft(struct ntfs_sb_info *sbi) /* Step 1: Resize $MFT::DATA. */ down_write(&ni->file.run_lock); - err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, - new_mft_bytes, NULL, false, &attr); + err = attr_set_size_ex(ni, ATTR_DATA, NULL, 0, &ni->file.run, + new_mft_bytes, NULL, false, &attr, false); if (err) { up_write(&ni->file.run_lock); @@ -525,7 +548,7 @@ static int ntfs_extend_mft(struct ntfs_sb_info *sbi) new_bitmap_bytes = ntfs3_bitmap_size(new_mft_total); err = attr_set_size(ni, ATTR_BITMAP, NULL, 0, &sbi->mft.bitmap.run, - new_bitmap_bytes, &new_bitmap_bytes, true, NULL); + new_bitmap_bytes, &new_bitmap_bytes, true); /* Refresh MFT Zone if necessary. */ down_write_nested(&sbi->used.bitmap.rw_lock, BITMAP_MUTEX_CLUSTERS); @@ -843,9 +866,8 @@ int ntfs_refresh_zone(struct ntfs_sb_info *sbi) /* * ntfs_update_mftmirr - Update $MFTMirr data. */ -void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait) +void ntfs_update_mftmirr(struct ntfs_sb_info *sbi) { - int err; struct super_block *sb = sbi->sb; u32 blocksize, bytes; sector_t block1, block2; @@ -875,9 +897,7 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait) return; } - if (buffer_locked(bh2)) - __wait_on_buffer(bh2); - + wait_on_buffer(bh2); lock_buffer(bh2); memcpy(bh2->b_data, bh1->b_data, blocksize); set_buffer_uptodate(bh2); @@ -886,12 +906,7 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait) put_bh(bh1); bh1 = NULL; - - err = wait ? sync_dirty_buffer(bh2) : 0; - put_bh(bh2); - if (err) - return; } sbi->flags &= ~NTFS_FLAGS_MFTMIRR; @@ -1069,9 +1084,7 @@ int ntfs_sb_write(struct super_block *sb, u64 lbo, size_t bytes, return -ENOMEM; } - if (buffer_locked(bh)) - __wait_on_buffer(bh); - + wait_on_buffer(bh); lock_buffer(bh); if (buf) { memcpy(bh->b_data + off, buf, op); @@ -1168,11 +1181,13 @@ struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi, return ntfs_bread(sb, lbo >> sb->s_blocksize_bits); } -int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, - u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb) +int ntfs_read_run_nb_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, + u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb, + struct file_ra_state *ra) { int err; struct super_block *sb = sbi->sb; + struct address_space *mapping = sb->s_bdev->bd_mapping; u32 blocksize = sb->s_blocksize; u8 cluster_bits = sbi->cluster_bits; u32 off = vbo & sbi->cluster_mask; @@ -1212,10 +1227,22 @@ int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, nb->bytes = bytes; } + if (ra && !ra->ra_pages) + file_ra_state_init(ra, mapping); + for (;;) { u32 len32 = len >= bytes ? bytes : len; sector_t block = lbo >> sb->s_blocksize_bits; + if (ra) { + pgoff_t index = lbo >> PAGE_SHIFT; + if (!ra_has_index(ra, index)) { + page_cache_sync_readahead(mapping, ra, NULL, + index, 1); + ra->prev_pos = (loff_t)index << PAGE_SHIFT; + } + } + do { u32 op = blocksize - off; @@ -1252,6 +1279,12 @@ int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, } while (len32); + if (!run) { + err = -EINVAL; + goto out; + } + + /* Get next fragment to read. */ vcn_next = vcn + clen; if (!run_get_entry(run, ++idx, &vcn, &lcn, &clen) || vcn != vcn_next) { @@ -1286,11 +1319,11 @@ int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, * * Return: < 0 if error, 0 if ok, -E_NTFS_FIXUP if need to update fixups. */ -int ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, - struct NTFS_RECORD_HEADER *rhdr, u32 bytes, - struct ntfs_buffers *nb) +int ntfs_read_bh_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, + u64 vbo, struct NTFS_RECORD_HEADER *rhdr, u32 bytes, + struct ntfs_buffers *nb, struct file_ra_state *ra) { - int err = ntfs_read_run_nb(sbi, run, vbo, rhdr, bytes, nb); + int err = ntfs_read_run_nb_ra(sbi, run, vbo, rhdr, bytes, nb, ra); if (err) return err; @@ -1347,12 +1380,9 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, err = -ENOMEM; goto out; } - if (buffer_locked(bh)) - __wait_on_buffer(bh); - + wait_on_buffer(bh); lock_buffer(bh); - if (!buffer_uptodate(bh)) - { + if (!buffer_uptodate(bh)) { memset(bh->b_data, 0, blocksize); set_buffer_uptodate(bh); } @@ -1427,9 +1457,7 @@ int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr, if (op > bytes) op = bytes; - if (buffer_locked(bh)) - __wait_on_buffer(bh); - + wait_on_buffer(bh); lock_buffer(bh); bh_data = bh->b_data + off; @@ -2186,7 +2214,7 @@ int ntfs_insert_security(struct ntfs_sb_info *sbi, if (new_sds_size > ni->vfs_inode.i_size) { err = attr_set_size(ni, ATTR_DATA, SDS_NAME, ARRAY_SIZE(SDS_NAME), &ni->file.run, - new_sds_size, &new_sds_size, false, NULL); + new_sds_size, &new_sds_size, false); if (err) goto out; } diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c index 7157cfd70fdc..97f06c26fe1a 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -252,9 +252,7 @@ static int bmp_buf_get(struct ntfs_index *indx, struct ntfs_inode *ni, bbuf->bh = bh; - if (buffer_locked(bh)) - __wait_on_buffer(bh); - + wait_on_buffer(bh); lock_buffer(bh); sb = sbi->sb; @@ -942,7 +940,7 @@ static struct indx_node *indx_new(struct ntfs_index *indx, u16 fn; u32 eo; - r = kzalloc(sizeof(struct indx_node), GFP_NOFS); + r = kzalloc_obj(struct indx_node, GFP_NOFS); if (!r) return ERR_PTR(-ENOMEM); @@ -1028,17 +1026,18 @@ static int indx_write(struct ntfs_index *indx, struct ntfs_inode *ni, } /* - * indx_read + * indx_read_ra * * If ntfs_readdir calls this function * inode is shared locked and no ni_lock. * Use rw_semaphore for read/write access to alloc_run. */ -int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, - struct indx_node **node) +int indx_read_ra(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, + struct indx_node **node, struct file_ra_state *ra) { int err; struct INDEX_BUFFER *ib; + struct ntfs_sb_info *sbi = ni->mi.sbi; struct runs_tree *run = &indx->alloc_run; struct rw_semaphore *lock = &indx->run_lock; u64 vbo = (u64)vbn << indx->vbn2vbo_bits; @@ -1047,7 +1046,7 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, const struct INDEX_NAMES *name; if (!in) { - in = kzalloc(sizeof(struct indx_node), GFP_NOFS); + in = kzalloc_obj(struct indx_node, GFP_NOFS); if (!in) return -ENOMEM; } else { @@ -1064,7 +1063,7 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, } down_read(lock); - err = ntfs_read_bh(ni->mi.sbi, run, vbo, &ib->rhdr, bytes, &in->nb); + err = ntfs_read_bh_ra(sbi, run, vbo, &ib->rhdr, bytes, &in->nb, ra); up_read(lock); if (!err) goto ok; @@ -1084,7 +1083,7 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, goto out; down_read(lock); - err = ntfs_read_bh(ni->mi.sbi, run, vbo, &ib->rhdr, bytes, &in->nb); + err = ntfs_read_bh_ra(sbi, run, vbo, &ib->rhdr, bytes, &in->nb, ra); up_read(lock); if (err == -E_NTFS_FIXUP) goto ok; @@ -1100,7 +1099,7 @@ int indx_read(struct ntfs_index *indx, struct ntfs_inode *ni, CLST vbn, } if (err == -E_NTFS_FIXUP) { - ntfs_write_bh(ni->mi.sbi, &ib->rhdr, &in->nb, 0); + ntfs_write_bh(sbi, &ib->rhdr, &in->nb, 0); err = 0; } @@ -1190,7 +1189,12 @@ int indx_find(struct ntfs_index *indx, struct ntfs_inode *ni, return -EINVAL; } - fnd_push(fnd, node, e); + err = fnd_push(fnd, node, e); + + if (err) { + put_indx_node(node); + return err; + } } *entry = e; @@ -1442,8 +1446,8 @@ static int indx_create_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, run_init(&run); - err = attr_allocate_clusters(sbi, &run, 0, 0, len, NULL, ALLOCATE_DEF, - &alen, 0, NULL, NULL); + err = attr_allocate_clusters(sbi, &run, NULL, 0, 0, len, NULL, + ALLOCATE_DEF, &alen, 0, NULL, NULL); if (err) goto out; @@ -1527,8 +1531,7 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, /* Increase bitmap. */ err = attr_set_size(ni, ATTR_BITMAP, in->name, in->name_len, &indx->bitmap_run, - ntfs3_bitmap_size(bit + 1), NULL, true, - NULL); + ntfs3_bitmap_size(bit + 1), NULL, true); if (err) goto out1; } @@ -1549,8 +1552,7 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, /* Increase allocation. */ err = attr_set_size(ni, ATTR_ALLOC, in->name, in->name_len, - &indx->alloc_run, data_size, &data_size, true, - NULL); + &indx->alloc_run, data_size, &data_size, true); if (err) { if (bmp) goto out2; @@ -1568,7 +1570,7 @@ static int indx_add_allocate(struct ntfs_index *indx, struct ntfs_inode *ni, out2: /* Ops. No space? */ attr_set_size(ni, ATTR_BITMAP, in->name, in->name_len, - &indx->bitmap_run, bmp_size, &bmp_size_v, false, NULL); + &indx->bitmap_run, bmp_size, &bmp_size_v, false); out1: return err; @@ -1998,6 +2000,7 @@ int indx_insert_entry(struct ntfs_index *indx, struct ntfs_inode *ni, fnd->level - 1, fnd); } + indx->version += 1; out: fnd_put(fnd_a); out1: @@ -2101,7 +2104,7 @@ static int indx_shrink(struct ntfs_index *indx, struct ntfs_inode *ni, new_data = (u64)bit << indx->index_bits; err = attr_set_size(ni, ATTR_ALLOC, in->name, in->name_len, - &indx->alloc_run, new_data, &new_data, false, NULL); + &indx->alloc_run, new_data, &new_data, false); if (err) return err; @@ -2113,7 +2116,7 @@ static int indx_shrink(struct ntfs_index *indx, struct ntfs_inode *ni, return 0; err = attr_set_size(ni, ATTR_BITMAP, in->name, in->name_len, - &indx->bitmap_run, bpb, &bpb, false, NULL); + &indx->bitmap_run, bpb, &bpb, false); return err; } @@ -2328,6 +2331,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, hdr = &root->ihdr; e = fnd->root_de; n = NULL; + ib = NULL; } e_size = le16_to_cpu(e->size); @@ -2350,7 +2354,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, * Check to see if removing that entry made * the leaf empty. */ - if (ib_is_leaf(ib) && ib_is_empty(ib)) { + if (ib && ib_is_leaf(ib) && ib_is_empty(ib)) { fnd_pop(fnd); fnd_push(fnd2, n, e); } @@ -2598,7 +2602,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, in = &s_index_names[indx->type]; err = attr_set_size(ni, ATTR_ALLOC, in->name, in->name_len, - &indx->alloc_run, 0, NULL, false, NULL); + &indx->alloc_run, 0, NULL, false); if (in->name == I30_NAME) i_size_write(&ni->vfs_inode, 0); @@ -2607,7 +2611,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, run_close(&indx->alloc_run); err = attr_set_size(ni, ATTR_BITMAP, in->name, in->name_len, - &indx->bitmap_run, 0, NULL, false, NULL); + &indx->bitmap_run, 0, NULL, false); err = ni_remove_attr(ni, ATTR_BITMAP, in->name, in->name_len, false, NULL); run_close(&indx->bitmap_run); @@ -2645,6 +2649,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct ntfs_inode *ni, mi->dirty = true; } + indx->version += 1; out: fnd_put(fnd2); out1: diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index edfb973e4e82..6e65066ebcc1 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "debug.h" #include "ntfs.h" @@ -39,7 +40,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, u32 rp_fa = 0, asize, t32; u16 roff, rsize, names = 0, links = 0; const struct ATTR_FILE_NAME *fname = NULL; - const struct INDEX_ROOT *root; + const struct INDEX_ROOT *root = NULL; struct REPARSE_DATA_BUFFER rp; // 0x18 bytes u64 t64; struct MFT_REC *rec; @@ -166,9 +167,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, std5 = Add2Ptr(attr, roff); -#ifdef STATX_BTIME nt2kernel(std5->cr_time, &ni->i_crtime); -#endif nt2kernel(std5->a_time, &ts); inode_set_atime_to_ts(inode, ts); nt2kernel(std5->c_time, &ts); @@ -555,194 +554,148 @@ struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref, return inode; } -enum get_block_ctx { - GET_BLOCK_GENERAL = 0, - GET_BLOCK_WRITE_BEGIN = 1, - GET_BLOCK_DIRECT_IO_R = 2, - GET_BLOCK_DIRECT_IO_W = 3, - GET_BLOCK_BMAP = 4, -}; - -static noinline int ntfs_get_block_vbo(struct inode *inode, u64 vbo, - struct buffer_head *bh, int create, - enum get_block_ctx ctx) -{ - struct super_block *sb = inode->i_sb; - struct ntfs_sb_info *sbi = sb->s_fs_info; - struct ntfs_inode *ni = ntfs_i(inode); - struct folio *folio = bh->b_folio; - u8 cluster_bits = sbi->cluster_bits; - u32 block_size = sb->s_blocksize; - u64 bytes, lbo, valid; - u32 off; - int err; - CLST vcn, lcn, len; - bool new; - - /* Clear previous state. */ - clear_buffer_new(bh); - clear_buffer_uptodate(bh); - - if (is_resident(ni)) { - bh->b_blocknr = RESIDENT_LCN; - bh->b_size = block_size; - if (!folio) { - /* direct io (read) or bmap call */ - err = 0; - } else { - ni_lock(ni); - err = attr_data_read_resident(ni, folio); - ni_unlock(ni); - - if (!err) - set_buffer_uptodate(bh); - } - return err; - } - - vcn = vbo >> cluster_bits; - off = vbo & sbi->cluster_mask; - new = false; - - err = attr_data_get_block(ni, vcn, 1, &lcn, &len, create ? &new : NULL, - create && sbi->cluster_size > PAGE_SIZE); - if (err) - goto out; - - if (!len) - return 0; - - bytes = ((u64)len << cluster_bits) - off; - - if (lcn >= sbi->used.bitmap.nbits) { - /* This case includes resident/compressed/sparse. */ - if (!create) { - if (bh->b_size > bytes) - bh->b_size = bytes; - return 0; - } - WARN_ON(1); - } - - if (new) - set_buffer_new(bh); - - lbo = ((u64)lcn << cluster_bits) + off; - - set_buffer_mapped(bh); - bh->b_bdev = sb->s_bdev; - bh->b_blocknr = lbo >> sb->s_blocksize_bits; - - valid = ni->i_valid; - - if (ctx == GET_BLOCK_DIRECT_IO_W) { - /* ntfs_direct_IO will update ni->i_valid. */ - if (vbo >= valid) - set_buffer_new(bh); - } else if (create) { - /* Normal write. */ - if (bytes > bh->b_size) - bytes = bh->b_size; - - if (vbo >= valid) - set_buffer_new(bh); - - if (vbo + bytes > valid) { - ni->i_valid = vbo + bytes; - mark_inode_dirty(inode); - } - } else if (vbo >= valid) { - /* Read out of valid data. */ - clear_buffer_mapped(bh); - } else if (vbo + bytes <= valid) { - /* Normal read. */ - } else if (vbo + block_size <= valid) { - /* Normal short read. */ - bytes = block_size; - } else { - /* - * Read across valid size: vbo < valid && valid < vbo + block_size - */ - bytes = block_size; - - if (folio) { - u32 voff = valid - vbo; - - bh->b_size = block_size; - off = vbo & (PAGE_SIZE - 1); - folio_set_bh(bh, folio, off); - - if (bh_read(bh, 0) < 0) { - err = -EIO; - goto out; - } - folio_zero_segment(folio, off + voff, off + block_size); - } - } - - if (bh->b_size > bytes) - bh->b_size = bytes; - -#ifndef __LP64__ - if (ctx == GET_BLOCK_DIRECT_IO_W || ctx == GET_BLOCK_DIRECT_IO_R) { - static_assert(sizeof(size_t) < sizeof(loff_t)); - if (bytes > 0x40000000u) - bh->b_size = 0x40000000u; - } -#endif - - return 0; - -out: - return err; -} - -int ntfs_get_block(struct inode *inode, sector_t vbn, - struct buffer_head *bh_result, int create) -{ - return ntfs_get_block_vbo(inode, (u64)vbn << inode->i_blkbits, - bh_result, create, GET_BLOCK_GENERAL); -} - -static int ntfs_get_block_bmap(struct inode *inode, sector_t vsn, - struct buffer_head *bh_result, int create) -{ - return ntfs_get_block_vbo(inode, - (u64)vsn << inode->i_sb->s_blocksize_bits, - bh_result, create, GET_BLOCK_BMAP); -} - static sector_t ntfs_bmap(struct address_space *mapping, sector_t block) { - return generic_block_bmap(mapping, block, ntfs_get_block_bmap); + struct inode *inode = mapping->host; + struct ntfs_inode *ni = ntfs_i(inode); + + /* + * We can get here for an inline file via the FIBMAP ioctl + */ + if (is_resident(ni)) + return 0; + + if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY) && + !run_is_empty(&ni->file.run_da)) { + /* + * With delalloc data we want to sync the file so + * that we can make sure we allocate blocks for file and data + * is in place for the user to see it + */ + ni_allocate_da_blocks(ni); + } + + return iomap_bmap(mapping, block, &ntfs_iomap_ops); } +static void ntfs_iomap_read_end_io(struct bio *bio) +{ + int error = blk_status_to_errno(bio->bi_status); + struct folio_iter fi; + + bio_for_each_folio_all(fi, bio) { + struct folio *folio = fi.folio; + struct inode *inode = folio->mapping->host; + struct ntfs_inode *ni = ntfs_i(inode); + u64 valid = ni->i_valid; + u32 f_size = folio_size(folio); + loff_t f_pos = folio_pos(folio); + + + if (valid < f_pos + f_size) { + u32 z_from = valid <= f_pos ? + 0 : + offset_in_folio(folio, valid); + /* The only thing ntfs_iomap_read_end_io used for. */ + folio_zero_segment(folio, z_from, f_size); + } + + iomap_finish_folio_read(folio, fi.offset, fi.length, error); + } + bio_put(bio); +} + +/* + * Copied from iomap/bio.c. + */ +static int ntfs_iomap_bio_read_folio_range(const struct iomap_iter *iter, + struct iomap_read_folio_ctx *ctx, + size_t plen) +{ + struct folio *folio = ctx->cur_folio; + const struct iomap *iomap = &iter->iomap; + loff_t pos = iter->pos; + size_t poff = offset_in_folio(folio, pos); + loff_t length = iomap_length(iter); + sector_t sector; + struct bio *bio = ctx->read_ctx; + + sector = iomap_sector(iomap, pos); + if (!bio || bio_end_sector(bio) != sector || + !bio_add_folio(bio, folio, plen, poff)) { + gfp_t gfp = mapping_gfp_constraint(folio->mapping, GFP_KERNEL); + gfp_t orig_gfp = gfp; + unsigned int nr_vecs = DIV_ROUND_UP(length, PAGE_SIZE); + + if (bio) + submit_bio(bio); + + if (ctx->rac) /* same as readahead_gfp_mask */ + gfp |= __GFP_NORETRY | __GFP_NOWARN; + bio = bio_alloc(iomap->bdev, bio_max_segs(nr_vecs), REQ_OP_READ, + gfp); + /* + * If the bio_alloc fails, try it again for a single page to + * avoid having to deal with partial page reads. This emulates + * what do_mpage_read_folio does. + */ + if (!bio) + bio = bio_alloc(iomap->bdev, 1, REQ_OP_READ, orig_gfp); + if (ctx->rac) + bio->bi_opf |= REQ_RAHEAD; + bio->bi_iter.bi_sector = sector; + bio->bi_end_io = ntfs_iomap_read_end_io; + bio_add_folio_nofail(bio, folio, plen, poff); + ctx->read_ctx = bio; + } + return 0; +} + +static void ntfs_iomap_bio_submit_read(struct iomap_read_folio_ctx *ctx) +{ + struct bio *bio = ctx->read_ctx; + + if (bio) + submit_bio(bio); +} + +static const struct iomap_read_ops ntfs_iomap_bio_read_ops = { + .read_folio_range = ntfs_iomap_bio_read_folio_range, + .submit_read = ntfs_iomap_bio_submit_read, +}; + static int ntfs_read_folio(struct file *file, struct folio *folio) { int err; struct address_space *mapping = folio->mapping; struct inode *inode = mapping->host; struct ntfs_inode *ni = ntfs_i(inode); + loff_t vbo = folio_pos(folio); + struct iomap_read_folio_ctx ctx = { + .cur_folio = folio, + .ops = &ntfs_iomap_bio_read_ops, + }; - if (is_resident(ni)) { - ni_lock(ni); - err = attr_data_read_resident(ni, folio); - ni_unlock(ni); - if (err != E_NTFS_NONRESIDENT) { - folio_unlock(folio); - return err; - } + if (unlikely(is_bad_ni(ni))) { + folio_unlock(folio); + return -EIO; + } + + if (ni->i_valid <= vbo) { + folio_zero_range(folio, 0, folio_size(folio)); + folio_mark_uptodate(folio); + folio_unlock(folio); + return 0; } if (is_compressed(ni)) { - ni_lock(ni); - err = ni_readpage_cmpr(ni, folio); - ni_unlock(ni); + /* ni_lock is taken inside ni_read_folio_cmpr after page locks */ + err = ni_read_folio_cmpr(ni, folio); return err; } - /* Normal + sparse files. */ - return mpage_read_folio(folio, ntfs_get_block); + iomap_read_folio(&ntfs_iomap_ops, &ctx, NULL); + return 0; } static void ntfs_readahead(struct readahead_control *rac) @@ -750,8 +703,10 @@ static void ntfs_readahead(struct readahead_control *rac) struct address_space *mapping = rac->mapping; struct inode *inode = mapping->host; struct ntfs_inode *ni = ntfs_i(inode); - u64 valid; - loff_t pos; + struct iomap_read_folio_ctx ctx = { + .ops = &ntfs_iomap_bio_read_ops, + .rac = rac, + }; if (is_resident(ni)) { /* No readahead for resident. */ @@ -763,80 +718,7 @@ static void ntfs_readahead(struct readahead_control *rac) return; } - valid = ni->i_valid; - pos = readahead_pos(rac); - - if (valid < i_size_read(inode) && pos <= valid && - valid < pos + readahead_length(rac)) { - /* Range cross 'valid'. Read it page by page. */ - return; - } - - mpage_readahead(rac, ntfs_get_block); -} - -static int ntfs_get_block_direct_IO_R(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) -{ - return ntfs_get_block_vbo(inode, (u64)iblock << inode->i_blkbits, - bh_result, create, GET_BLOCK_DIRECT_IO_R); -} - -static int ntfs_get_block_direct_IO_W(struct inode *inode, sector_t iblock, - struct buffer_head *bh_result, int create) -{ - return ntfs_get_block_vbo(inode, (u64)iblock << inode->i_blkbits, - bh_result, create, GET_BLOCK_DIRECT_IO_W); -} - -static ssize_t ntfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) -{ - struct file *file = iocb->ki_filp; - struct address_space *mapping = file->f_mapping; - struct inode *inode = mapping->host; - struct ntfs_inode *ni = ntfs_i(inode); - loff_t vbo = iocb->ki_pos; - loff_t end; - int wr = iov_iter_rw(iter) & WRITE; - size_t iter_count = iov_iter_count(iter); - loff_t valid; - ssize_t ret; - - if (is_resident(ni)) { - /* Switch to buffered write. */ - ret = 0; - goto out; - } - if (is_compressed(ni)) { - ret = 0; - goto out; - } - - ret = blockdev_direct_IO(iocb, inode, iter, - wr ? ntfs_get_block_direct_IO_W : - ntfs_get_block_direct_IO_R); - - if (ret > 0) - end = vbo + ret; - else if (wr && ret == -EIOCBQUEUED) - end = vbo + iter_count; - else - goto out; - - valid = ni->i_valid; - if (wr) { - if (end > valid && !S_ISBLK(inode->i_mode)) { - ni->i_valid = end; - mark_inode_dirty(inode); - } - } else if (vbo < valid && valid < end) { - /* Fix page. */ - iov_iter_revert(iter, end - valid); - iov_iter_zero(end - valid, iter); - } - -out: - return ret; + iomap_readahead(&ntfs_iomap_ops, &ctx, NULL); } int ntfs_set_size(struct inode *inode, u64 new_size) @@ -849,29 +731,311 @@ int ntfs_set_size(struct inode *inode, u64 new_size) /* Check for maximum file size. */ if (is_sparsed(ni) || is_compressed(ni)) { if (new_size > sbi->maxbytes_sparse) { - err = -EFBIG; - goto out; + return -EFBIG; } } else if (new_size > sbi->maxbytes) { - err = -EFBIG; - goto out; + return -EFBIG; } ni_lock(ni); down_write(&ni->file.run_lock); err = attr_set_size(ni, ATTR_DATA, NULL, 0, &ni->file.run, new_size, - &ni->i_valid, true, NULL); + &ni->i_valid, true); + + if (!err) { + i_size_write(inode, new_size); + mark_inode_dirty(inode); + } up_write(&ni->file.run_lock); ni_unlock(ni); - mark_inode_dirty(inode); - -out: return err; } +/* + * Special value to detect ntfs_writeback_range call + */ +#define WB_NO_DA (struct iomap *)1 +/* + * Function to get mapping vbo -> lbo. + * used with: + * - iomap_zero_range + * - iomap_truncate_page + * - iomap_dio_rw + * - iomap_file_buffered_write + * - iomap_bmap + * - iomap_fiemap + * - iomap_bio_read_folio + * - iomap_bio_readahead + */ +static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length, + unsigned int flags, struct iomap *iomap, + struct iomap *srcmap) +{ + struct ntfs_inode *ni = ntfs_i(inode); + struct ntfs_sb_info *sbi = ni->mi.sbi; + u8 cluster_bits = sbi->cluster_bits; + CLST vcn = offset >> cluster_bits; + u32 off = offset & sbi->cluster_mask; + bool rw = flags & IOMAP_WRITE; + loff_t endbyte = offset + length; + void *res = NULL; + int err; + CLST lcn, clen, clen_max = 1; + bool new_clst = false; + bool no_da; + bool zero = false; + if (unlikely(ntfs3_forced_shutdown(sbi->sb))) + return -EIO; + + if (flags & IOMAP_REPORT) { + if (offset > ntfs_get_maxbytes(ni)) { + /* called from fiemap/bmap. */ + return -EINVAL; + } + + if (offset >= inode->i_size) { + /* special code for report. */ + return -ENOENT; + } + } + + if (IOMAP_ZERO == flags && (endbyte & sbi->cluster_mask)) { + rw = true; + } else if (rw) { + clen_max = bytes_to_cluster(sbi, endbyte) - vcn; + } + + /* + * Force to allocate clusters if directIO(write) or writeback_range. + * NOTE: attr_data_get_block allocates clusters only for sparse file. + * Normal file allocates clusters in attr_set_size. + */ + no_da = flags == (IOMAP_DIRECT | IOMAP_WRITE) || srcmap == WB_NO_DA; + + err = attr_data_get_block(ni, vcn, clen_max, &lcn, &clen, + rw ? &new_clst : NULL, zero, &res, no_da); + + if (err) { + return err; + } + + if (lcn == EOF_LCN) { + /* request out of file. */ + if (flags & IOMAP_REPORT) { + /* special code for report. */ + return -ENOENT; + } + + if (rw) { + /* should never be here. */ + return -EINVAL; + } + lcn = SPARSE_LCN; + } + + iomap->flags = new_clst ? IOMAP_F_NEW : 0; + + if (lcn == RESIDENT_LCN) { + if (offset >= clen) { + kfree(res); + if (flags & IOMAP_REPORT) { + /* special code for report. */ + return -ENOENT; + } + return -EFAULT; + } + + iomap->private = iomap->inline_data = res; + iomap->type = IOMAP_INLINE; + iomap->offset = 0; + iomap->length = clen; /* resident size in bytes. */ + return 0; + } + + if (!clen) { + /* broken file? */ + return -EINVAL; + } + + iomap->bdev = inode->i_sb->s_bdev; + iomap->offset = offset; + iomap->length = ((loff_t)clen << cluster_bits) - off; + + if (lcn == COMPRESSED_LCN) { + /* should never be here. */ + return -EOPNOTSUPP; + } + + if (lcn == DELALLOC_LCN) { + iomap->type = IOMAP_DELALLOC; + iomap->addr = IOMAP_NULL_ADDR; + } else { + + /* Translate clusters into bytes. */ + iomap->addr = ((loff_t)lcn << cluster_bits) + off; + if (length && iomap->length > length) + iomap->length = length; + else + endbyte = offset + iomap->length; + + if (lcn == SPARSE_LCN) { + iomap->addr = IOMAP_NULL_ADDR; + iomap->type = IOMAP_HOLE; + // if (IOMAP_ZERO == flags && !off) { + // iomap->length = (endbyte - offset) & + // sbi->cluster_mask_inv; + // } + } else if (endbyte <= ni->i_valid) { + iomap->type = IOMAP_MAPPED; + } else if (offset < ni->i_valid) { + iomap->type = IOMAP_MAPPED; + if (flags & IOMAP_REPORT) + iomap->length = ni->i_valid - offset; + } else if (rw || (flags & IOMAP_ZERO)) { + iomap->type = IOMAP_MAPPED; + } else { + iomap->type = IOMAP_UNWRITTEN; + } + } + + if ((flags & IOMAP_ZERO) && + (iomap->type == IOMAP_MAPPED || iomap->type == IOMAP_DELALLOC)) { + /* Avoid too large requests. */ + u32 tail; + u32 off_a = offset & (PAGE_SIZE - 1); + if (off_a) + tail = PAGE_SIZE - off_a; + else + tail = PAGE_SIZE; + + if (iomap->length > tail) + iomap->length = tail; + } + + return 0; +} + +static int ntfs_iomap_end(struct inode *inode, loff_t pos, loff_t length, + ssize_t written, unsigned int flags, + struct iomap *iomap) +{ + int err = 0; + struct ntfs_inode *ni = ntfs_i(inode); + loff_t endbyte = pos + written; + + if ((flags & IOMAP_WRITE) || (flags & IOMAP_ZERO)) { + if (iomap->type == IOMAP_INLINE) { + u32 data_size; + struct ATTRIB *attr; + struct mft_inode *mi; + + attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, + NULL, &mi); + if (!attr || attr->non_res) { + err = -EINVAL; + goto out; + } + + data_size = le32_to_cpu(attr->res.data_size); + if (!(pos < data_size && endbyte <= data_size)) { + err = -EINVAL; + goto out; + } + + /* Update resident data. */ + memcpy(resident_data(attr) + pos, + iomap_inline_data(iomap, pos), written); + mi->dirty = true; + ni->i_valid = data_size; + } else if (ni->i_valid < endbyte) { + ni->i_valid = endbyte; + mark_inode_dirty(inode); + } + } + + if ((flags & IOMAP_ZERO) && + (iomap->type == IOMAP_MAPPED || iomap->type == IOMAP_DELALLOC)) { + /* Pair for code in ntfs_iomap_begin. */ + balance_dirty_pages_ratelimited(inode->i_mapping); + cond_resched(); + } + +out: + if (iomap->type == IOMAP_INLINE) { + kfree(iomap->private); + iomap->private = NULL; + } + + return err; +} + +/* + * write_begin + put_folio + write_end. + * iomap_zero_range + * iomap_truncate_page + * iomap_file_buffered_write + */ +static void ntfs_iomap_put_folio(struct inode *inode, loff_t pos, + unsigned int len, struct folio *folio) +{ + struct ntfs_inode *ni = ntfs_i(inode); + loff_t end = pos + len; + u32 f_size = folio_size(folio); + loff_t f_pos = folio_pos(folio); + loff_t f_end = f_pos + f_size; + + if (ni->i_valid <= end && end < f_end) { + /* zero range [end - f_end). */ + /* The only thing ntfs_iomap_put_folio used for. */ + folio_zero_segment(folio, offset_in_folio(folio, end), f_size); + } + folio_unlock(folio); + folio_put(folio); +} + +/* + * iomap_writeback_ops::writeback_range + */ +static ssize_t ntfs_writeback_range(struct iomap_writepage_ctx *wpc, + struct folio *folio, u64 offset, + unsigned int len, u64 end_pos) +{ + struct iomap *iomap = &wpc->iomap; + /* Check iomap position. */ + if (iomap->offset + iomap->length <= offset || offset < iomap->offset) { + int err; + struct inode *inode = wpc->inode; + struct ntfs_inode *ni = ntfs_i(inode); + struct ntfs_sb_info *sbi = ntfs_sb(inode->i_sb); + loff_t i_size_up = ntfs_up_cluster(sbi, inode->i_size); + loff_t len_max = i_size_up - offset; + + err = ni->file.run_da.count ? ni_allocate_da_blocks(ni) : 0; + + if (!err) { + /* Use local special value 'WB_NO_DA' to disable delalloc. */ + err = ntfs_iomap_begin(inode, offset, len_max, + IOMAP_WRITE, iomap, WB_NO_DA); + } + + if (err) { + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); + return err; + } + } + + return iomap_add_to_ioend(wpc, folio, offset, end_pos, len); +} + + +static const struct iomap_writeback_ops ntfs_writeback_ops = { + .writeback_range = ntfs_writeback_range, + .writeback_submit = iomap_ioend_writeback_submit, +}; + static int ntfs_resident_writepage(struct folio *folio, struct writeback_control *wbc) { @@ -899,40 +1063,15 @@ static int ntfs_resident_writepage(struct folio *folio, static int ntfs_writepages(struct address_space *mapping, struct writeback_control *wbc) -{ - struct inode *inode = mapping->host; - - /* Avoid any operation if inode is bad. */ - if (unlikely(is_bad_ni(ntfs_i(inode)))) - return -EINVAL; - - if (unlikely(ntfs3_forced_shutdown(inode->i_sb))) - return -EIO; - - if (is_resident(ntfs_i(inode))) { - struct folio *folio = NULL; - int error; - - while ((folio = writeback_iter(mapping, wbc, folio, &error))) - error = ntfs_resident_writepage(folio, wbc); - return error; - } - return mpage_writepages(mapping, wbc, ntfs_get_block); -} - -static int ntfs_get_block_write_begin(struct inode *inode, sector_t vbn, - struct buffer_head *bh_result, int create) -{ - return ntfs_get_block_vbo(inode, (u64)vbn << inode->i_blkbits, - bh_result, create, GET_BLOCK_WRITE_BEGIN); -} - -int ntfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, - loff_t pos, u32 len, struct folio **foliop, void **fsdata) { int err; struct inode *inode = mapping->host; struct ntfs_inode *ni = ntfs_i(inode); + struct iomap_writepage_ctx wpc = { + .inode = mapping->host, + .wbc = wbc, + .ops = &ntfs_writeback_ops, + }; /* Avoid any operation if inode is bad. */ if (unlikely(is_bad_ni(ni))) @@ -942,100 +1081,15 @@ int ntfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, return -EIO; if (is_resident(ni)) { - struct folio *folio = __filemap_get_folio( - mapping, pos >> PAGE_SHIFT, FGP_WRITEBEGIN, - mapping_gfp_mask(mapping)); + struct folio *folio = NULL; - if (IS_ERR(folio)) { - err = PTR_ERR(folio); - goto out; - } + while ((folio = writeback_iter(mapping, wbc, folio, &err))) + err = ntfs_resident_writepage(folio, wbc); - ni_lock(ni); - err = attr_data_read_resident(ni, folio); - ni_unlock(ni); - - if (!err) { - *foliop = folio; - goto out; - } - folio_unlock(folio); - folio_put(folio); - - if (err != E_NTFS_NONRESIDENT) - goto out; + return err; } - err = block_write_begin(mapping, pos, len, foliop, - ntfs_get_block_write_begin); - -out: - return err; -} - -/* - * ntfs_write_end - Address_space_operations::write_end. - */ -int ntfs_write_end(const struct kiocb *iocb, struct address_space *mapping, - loff_t pos, u32 len, u32 copied, struct folio *folio, - void *fsdata) -{ - struct inode *inode = mapping->host; - struct ntfs_inode *ni = ntfs_i(inode); - u64 valid = ni->i_valid; - bool dirty = false; - int err; - - if (is_resident(ni)) { - ni_lock(ni); - err = attr_data_write_resident(ni, folio); - ni_unlock(ni); - if (!err) { - struct buffer_head *head = folio_buffers(folio); - dirty = true; - /* Clear any buffers in folio. */ - if (head) { - struct buffer_head *bh = head; - - do { - clear_buffer_dirty(bh); - clear_buffer_mapped(bh); - set_buffer_uptodate(bh); - } while (head != (bh = bh->b_this_page)); - } - folio_mark_uptodate(folio); - err = copied; - } - folio_unlock(folio); - folio_put(folio); - } else { - err = generic_write_end(iocb, mapping, pos, len, copied, folio, - fsdata); - } - - if (err >= 0) { - if (!(ni->std_fa & FILE_ATTRIBUTE_ARCHIVE)) { - inode_set_mtime_to_ts(inode, - inode_set_ctime_current(inode)); - ni->std_fa |= FILE_ATTRIBUTE_ARCHIVE; - dirty = true; - } - - if (valid != ni->i_valid) { - /* ni->i_valid is changed in ntfs_get_block_vbo. */ - dirty = true; - } - - if (pos + err > inode->i_size) { - i_size_write(inode, pos + err); - dirty = true; - } - - if (dirty) - mark_inode_dirty(inode); - } - - return err; + return iomap_writepages(&wpc); } int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc) @@ -1050,6 +1104,7 @@ int ntfs_sync_inode(struct inode *inode) /* * Helper function to read file. + * Used to read $AttrDef and $UpCase */ int inode_read_data(struct inode *inode, void *data, size_t bytes) { @@ -1539,9 +1594,10 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, attr->nres.alloc_size = cpu_to_le64(ntfs_up_cluster(sbi, nsize)); - err = attr_allocate_clusters(sbi, &ni->file.run, 0, 0, - clst, NULL, ALLOCATE_DEF, - &alen, 0, NULL, NULL); + err = attr_allocate_clusters(sbi, &ni->file.run, NULL, + 0, 0, clst, NULL, + ALLOCATE_DEF, &alen, 0, + NULL, NULL); if (err) goto out5; @@ -1682,7 +1738,7 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, /* Delete ATTR_EA, if non-resident. */ struct runs_tree run; run_init(&run); - attr_set_size(ni, ATTR_EA, NULL, 0, &run, 0, NULL, false, NULL); + attr_set_size(ni, ATTR_EA, NULL, 0, &run, 0, NULL, false); run_close(&run); } @@ -2094,18 +2150,26 @@ const struct address_space_operations ntfs_aops = { .read_folio = ntfs_read_folio, .readahead = ntfs_readahead, .writepages = ntfs_writepages, - .write_begin = ntfs_write_begin, - .write_end = ntfs_write_end, - .direct_IO = ntfs_direct_IO, .bmap = ntfs_bmap, - .dirty_folio = block_dirty_folio, - .migrate_folio = buffer_migrate_folio, - .invalidate_folio = block_invalidate_folio, + .dirty_folio = iomap_dirty_folio, + .migrate_folio = filemap_migrate_folio, + .release_folio = iomap_release_folio, + .invalidate_folio = iomap_invalidate_folio, }; const struct address_space_operations ntfs_aops_cmpr = { .read_folio = ntfs_read_folio, - .dirty_folio = block_dirty_folio, - .direct_IO = ntfs_direct_IO, + .dirty_folio = iomap_dirty_folio, + .release_folio = iomap_release_folio, + .invalidate_folio = iomap_invalidate_folio, +}; + +const struct iomap_ops ntfs_iomap_ops = { + .iomap_begin = ntfs_iomap_begin, + .iomap_end = ntfs_iomap_end, +}; + +const struct iomap_write_ops ntfs_iomap_folio_ops = { + .put_folio = ntfs_iomap_put_folio, }; // clang-format on diff --git a/fs/ntfs3/lib/lzx_decompress.c b/fs/ntfs3/lib/lzx_decompress.c index 4d5701024f83..9196bf30011a 100644 --- a/fs/ntfs3/lib/lzx_decompress.c +++ b/fs/ntfs3/lib/lzx_decompress.c @@ -572,7 +572,7 @@ static int lzx_decompress_block(const struct lzx_decompressor *d, */ struct lzx_decompressor *lzx_allocate_decompressor(void) { - return kmalloc(sizeof(struct lzx_decompressor), GFP_NOFS); + return kmalloc_obj(struct lzx_decompressor, GFP_NOFS); } /* diff --git a/fs/ntfs3/lib/xpress_decompress.c b/fs/ntfs3/lib/xpress_decompress.c index 769c6d3dde67..402cf21aede2 100644 --- a/fs/ntfs3/lib/xpress_decompress.c +++ b/fs/ntfs3/lib/xpress_decompress.c @@ -39,7 +39,7 @@ struct xpress_decompressor { */ struct xpress_decompressor *xpress_allocate_decompressor(void) { - return kmalloc(sizeof(struct xpress_decompressor), GFP_NOFS); + return kmalloc_obj(struct xpress_decompressor, GFP_NOFS); } /* diff --git a/fs/ntfs3/ntfs.h b/fs/ntfs3/ntfs.h index 552b97905813..892f13e65d42 100644 --- a/fs/ntfs3/ntfs.h +++ b/fs/ntfs3/ntfs.h @@ -77,10 +77,14 @@ static_assert(sizeof(size_t) == 8); typedef u32 CLST; #endif +/* On-disk sparsed cluster is marked as -1. */ #define SPARSE_LCN64 ((u64)-1) #define SPARSE_LCN ((CLST)-1) +/* Below is virtual (not on-disk) values. */ #define RESIDENT_LCN ((CLST)-2) #define COMPRESSED_LCN ((CLST)-3) +#define EOF_LCN ((CLST)-4) +#define DELALLOC_LCN ((CLST)-5) enum RECORD_NUM { MFT_REC_MFT = 0, diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index f18349689458..daf5a1f47275 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -109,6 +109,7 @@ struct ntfs_mount_options { unsigned force : 1; /* RW mount dirty volume. */ unsigned prealloc : 1; /* Preallocate space when file is growing. */ unsigned nocase : 1; /* case insensitive. */ + unsigned delalloc : 1; /* delay allocation. */ }; /* Special value to unpack and deallocate. */ @@ -133,7 +134,8 @@ struct ntfs_buffers { enum ALLOCATE_OPT { ALLOCATE_DEF = 0, // Allocate all clusters. ALLOCATE_MFT = 1, // Allocate for MFT. - ALLOCATE_ZERO = 2, // Zeroout new allocated clusters + ALLOCATE_ZERO = 2, // Zeroout new allocated clusters. + ALLOCATE_ONE_FR = 4, // Allocate one fragment only. }; enum bitmap_mutex_classes { @@ -192,6 +194,7 @@ struct ntfs_index { struct runs_tree alloc_run; /* read/write access to 'bitmap_run'/'alloc_run' while ntfs_readdir */ struct rw_semaphore run_lock; + size_t version; /* increment each change */ /*TODO: Remove 'cmp'. */ NTFS_CMP_FUNC cmp; @@ -213,7 +216,7 @@ struct ntfs_sb_info { u32 discard_granularity; u64 discard_granularity_mask_inv; // ~(discard_granularity_mask_inv-1) - u32 bdev_blocksize_mask; // bdev_logical_block_size(bdev) - 1; + u32 bdev_blocksize; // bdev_logical_block_size(bdev) u32 cluster_size; // bytes per cluster u32 cluster_mask; // == cluster_size - 1 @@ -272,6 +275,12 @@ struct ntfs_sb_info { struct { struct wnd_bitmap bitmap; // $Bitmap::Data CLST next_free_lcn; + /* Total sum of delay allocated clusters in all files. */ +#ifdef CONFIG_NTFS3_64BIT_CLUSTER + atomic64_t da; +#else + atomic_t da; +#endif } used; struct { @@ -379,7 +388,7 @@ struct ntfs_inode { */ u8 mi_loaded; - /* + /* * Use this field to avoid any write(s). * If inode is bad during initialization - use make_bad_inode * If inode is bad during operations - use this field @@ -390,7 +399,14 @@ struct ntfs_inode { struct ntfs_index dir; struct { struct rw_semaphore run_lock; + /* Unpacked runs from just one record. */ struct runs_tree run; + /* + * Pairs [vcn, len] for all delay allocated clusters. + * Normal file always contains delayed clusters in one fragment. + * TODO: use 2 CLST per pair instead of 3. + */ + struct runs_tree run_da; #ifdef CONFIG_NTFS3_LZX_XPRESS struct folio *offs_folio; #endif @@ -430,20 +446,32 @@ enum REPARSE_SIGN { /* Functions from attrib.c */ int attr_allocate_clusters(struct ntfs_sb_info *sbi, struct runs_tree *run, - CLST vcn, CLST lcn, CLST len, CLST *pre_alloc, - enum ALLOCATE_OPT opt, CLST *alen, const size_t fr, - CLST *new_lcn, CLST *new_len); + struct runs_tree *run_da, CLST vcn, CLST lcn, + CLST len, CLST *pre_alloc, enum ALLOCATE_OPT opt, + CLST *alen, const size_t fr, CLST *new_lcn, + CLST *new_len); int attr_make_nonresident(struct ntfs_inode *ni, struct ATTRIB *attr, struct ATTR_LIST_ENTRY *le, struct mft_inode *mi, u64 new_size, struct runs_tree *run, struct ATTRIB **ins_attr, struct page *page); -int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, - const __le16 *name, u8 name_len, struct runs_tree *run, - u64 new_size, const u64 *new_valid, bool keep_prealloc, - struct ATTRIB **ret); +int attr_set_size_ex(struct ntfs_inode *ni, enum ATTR_TYPE type, + const __le16 *name, u8 name_len, struct runs_tree *run, + u64 new_size, const u64 *new_valid, bool keep_prealloc, + struct ATTRIB **ret, bool no_da); +static inline int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type, + const __le16 *name, u8 name_len, + struct runs_tree *run, u64 new_size, + const u64 *new_valid, bool keep_prealloc) +{ + return attr_set_size_ex(ni, type, name, name_len, run, new_size, + new_valid, keep_prealloc, NULL, false); +} int attr_data_get_block(struct ntfs_inode *ni, CLST vcn, CLST clen, CLST *lcn, - CLST *len, bool *new, bool zero); -int attr_data_read_resident(struct ntfs_inode *ni, struct folio *folio); + CLST *len, bool *new, bool zero, void **res, + bool no_da); +int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen, + CLST *lcn, CLST *len, bool *new, bool zero, + void **res, bool no_da); int attr_data_write_resident(struct ntfs_inode *ni, struct folio *folio); int attr_load_runs_vcn(struct ntfs_inode *ni, enum ATTR_TYPE type, const __le16 *name, u8 name_len, struct runs_tree *run, @@ -512,6 +540,7 @@ int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, int ntfs_file_open(struct inode *inode, struct file *file); int ntfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, __u64 start, __u64 len); +int ntfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg); long ntfs_compat_ioctl(struct file *filp, u32 cmd, unsigned long arg); extern const struct inode_operations ntfs_special_inode_operations; @@ -567,9 +596,7 @@ enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr, struct REPARSE_DATA_BUFFER *buffer); int ni_write_inode(struct inode *inode, int sync, const char *hint); #define _ni_write_inode(i, w) ni_write_inode(i, w, __func__) -int ni_fiemap(struct ntfs_inode *ni, struct fiemap_extent_info *fieinfo, - __u64 vbo, __u64 len); -int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio); +int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio); int ni_decompress_file(struct ntfs_inode *ni); int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages, u32 pages_per_frame, int copy); @@ -590,6 +617,10 @@ int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni, struct NTFS_DE *new_de); bool ni_is_dirty(struct inode *inode); +loff_t ni_seek_data_or_hole(struct ntfs_inode *ni, loff_t offset, bool data); +int ni_write_parents(struct ntfs_inode *ni, int sync); +int ni_allocate_da_blocks(struct ntfs_inode *ni); +int ni_allocate_da_blocks_locked(struct ntfs_inode *ni); /* Globals from fslog.c */ bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes); @@ -605,13 +636,14 @@ int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi); int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len, CLST *new_lcn, CLST *new_len, enum ALLOCATE_OPT opt); -bool ntfs_check_for_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen); +bool ntfs_check_free_space(struct ntfs_sb_info *sbi, CLST clen, CLST mlen, + bool da); int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft, struct ntfs_inode *ni, struct mft_inode **mi); void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft); int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to); int ntfs_refresh_zone(struct ntfs_sb_info *sbi); -void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait); +void ntfs_update_mftmirr(struct ntfs_sb_info *sbi); void ntfs_bad_inode(struct inode *inode, const char *hint); #define _ntfs_bad_inode(i) ntfs_bad_inode(i, __func__) enum NTFS_DIRTY_FLAGS { @@ -626,11 +658,27 @@ int ntfs_sb_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, const void *buf, size_t bytes, int sync); struct buffer_head *ntfs_bread_run(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo); -int ntfs_read_run_nb(struct ntfs_sb_info *sbi, const struct runs_tree *run, - u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb); -int ntfs_read_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, - struct NTFS_RECORD_HEADER *rhdr, u32 bytes, - struct ntfs_buffers *nb); +int ntfs_read_run_nb_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, + u64 vbo, void *buf, u32 bytes, struct ntfs_buffers *nb, + struct file_ra_state *ra); +static inline int ntfs_read_run_nb(struct ntfs_sb_info *sbi, + const struct runs_tree *run, u64 vbo, + void *buf, u32 bytes, + struct ntfs_buffers *nb) +{ + return ntfs_read_run_nb_ra(sbi, run, vbo, buf, bytes, nb, NULL); +} +int ntfs_read_bh_ra(struct ntfs_sb_info *sbi, const struct runs_tree *run, + u64 vbo, struct NTFS_RECORD_HEADER *rhdr, u32 bytes, + struct ntfs_buffers *nb, struct file_ra_state *ra); +static inline int ntfs_read_bh(struct ntfs_sb_info *sbi, + const struct runs_tree *run, u64 vbo, + struct NTFS_RECORD_HEADER *rhdr, u32 bytes, + struct ntfs_buffers *nb) +{ + return ntfs_read_bh_ra(sbi, run, vbo, rhdr, bytes, nb, NULL); +} + int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, u32 bytes, struct ntfs_buffers *nb); int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhdr, @@ -682,7 +730,7 @@ int indx_used_bit(struct ntfs_index *indx, struct ntfs_inode *ni, size_t *bit); void fnd_clear(struct ntfs_fnd *fnd); static inline struct ntfs_fnd *fnd_get(void) { - return kzalloc(sizeof(struct ntfs_fnd), GFP_NOFS); + return kzalloc_obj(struct ntfs_fnd, GFP_NOFS); } static inline void fnd_put(struct ntfs_fnd *fnd) { @@ -696,8 +744,13 @@ int indx_init(struct ntfs_index *indx, struct ntfs_sb_info *sbi, const struct ATTRIB *attr, enum index_mutex_classed type); struct INDEX_ROOT *indx_get_root(struct ntfs_index *indx, struct ntfs_inode *ni, struct ATTRIB **attr, struct mft_inode **mi); -int indx_read(struct ntfs_index *idx, struct ntfs_inode *ni, CLST vbn, - struct indx_node **node); +int indx_read_ra(struct ntfs_index *idx, struct ntfs_inode *ni, CLST vbn, + struct indx_node **node, struct file_ra_state *ra); +static inline int indx_read(struct ntfs_index *idx, struct ntfs_inode *ni, + CLST vbn, struct indx_node **node) +{ + return indx_read_ra(idx, ni, vbn, node, NULL); +} int indx_find(struct ntfs_index *indx, struct ntfs_inode *dir, const struct INDEX_ROOT *root, const void *Key, size_t KeyLen, const void *param, int *diff, struct NTFS_DE **entry, @@ -721,13 +774,6 @@ int indx_update_dup(struct ntfs_inode *ni, struct ntfs_sb_info *sbi, struct inode *ntfs_iget5(struct super_block *sb, const struct MFT_REF *ref, const struct cpu_str *name); int ntfs_set_size(struct inode *inode, u64 new_size); -int ntfs_get_block(struct inode *inode, sector_t vbn, - struct buffer_head *bh_result, int create); -int ntfs_write_begin(const struct kiocb *iocb, struct address_space *mapping, - loff_t pos, u32 len, struct folio **foliop, void **fsdata); -int ntfs_write_end(const struct kiocb *iocb, struct address_space *mapping, - loff_t pos, u32 len, u32 copied, struct folio *folio, - void *fsdata); int ntfs3_write_inode(struct inode *inode, struct writeback_control *wbc); int ntfs_sync_inode(struct inode *inode); int inode_read_data(struct inode *inode, void *data, size_t bytes); @@ -738,6 +784,8 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, int ntfs_link_inode(struct inode *inode, struct dentry *dentry); int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry); void ntfs_evict_inode(struct inode *inode); +extern const struct iomap_ops ntfs_iomap_ops; +extern const struct iomap_write_ops ntfs_iomap_folio_ops; extern const struct inode_operations ntfs_link_inode_operations; extern const struct address_space_operations ntfs_aops; extern const struct address_space_operations ntfs_aops_cmpr; @@ -815,7 +863,8 @@ void run_truncate_around(struct runs_tree *run, CLST vcn); bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len, bool is_mft); bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len, CLST sub); -bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len); +int run_insert_range(struct runs_tree *run, CLST vcn, CLST len); +int run_insert_range_da(struct runs_tree *run, CLST vcn, CLST len); bool run_get_entry(const struct runs_tree *run, size_t index, CLST *vcn, CLST *lcn, CLST *len); bool run_is_mapped_full(const struct runs_tree *run, CLST svcn, CLST evcn); @@ -835,6 +884,9 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, #endif int run_get_highest_vcn(CLST vcn, const u8 *run_buf, u64 *highest_vcn); int run_clone(const struct runs_tree *run, struct runs_tree *new_run); +bool run_remove_range(struct runs_tree *run, CLST vcn, CLST len, CLST *done); +CLST run_len(const struct runs_tree *run); +CLST run_get_max_vcn(const struct runs_tree *run); /* Globals from super.c */ void *ntfs_set_shared(void *ptr, u32 bytes); @@ -944,7 +996,7 @@ static inline void run_init(struct runs_tree *run) static inline struct runs_tree *run_alloc(void) { - return kzalloc(sizeof(struct runs_tree), GFP_NOFS); + return kzalloc_obj(struct runs_tree, GFP_NOFS); } static inline void run_close(struct runs_tree *run) @@ -1011,6 +1063,36 @@ static inline int ntfs3_forced_shutdown(struct super_block *sb) return test_bit(NTFS_FLAGS_SHUTDOWN_BIT, &ntfs_sb(sb)->flags); } +/* Returns total sum of delay allocated clusters in all files. */ +static inline CLST ntfs_get_da(struct ntfs_sb_info *sbi) +{ +#ifdef CONFIG_NTFS3_64BIT_CLUSTER + return atomic64_read(&sbi->used.da); +#else + return atomic_read(&sbi->used.da); +#endif +} + +/* Update total count of delay allocated clusters. */ +static inline void ntfs_add_da(struct ntfs_sb_info *sbi, CLST da) +{ +#ifdef CONFIG_NTFS3_64BIT_CLUSTER + atomic64_add(da, &sbi->used.da); +#else + atomic_add(da, &sbi->used.da); +#endif +} + +/* Update total count of delay allocated clusters. */ +static inline void ntfs_sub_da(struct ntfs_sb_info *sbi, CLST da) +{ +#ifdef CONFIG_NTFS3_64BIT_CLUSTER + atomic64_sub(da, &sbi->used.da); +#else + atomic_sub(da, &sbi->used.da); +#endif +} + /* * ntfs_up_cluster - Align up on cluster boundary. */ @@ -1084,6 +1166,13 @@ static inline int is_resident(struct ntfs_inode *ni) return ni->ni_flags & NI_FLAG_RESIDENT; } +static inline loff_t ntfs_get_maxbytes(struct ntfs_inode *ni) +{ + struct ntfs_sb_info *sbi = ni->mi.sbi; + return is_sparsed(ni) || is_compressed(ni) ? sbi->maxbytes_sparse : + sbi->maxbytes; +} + static inline void le16_sub_cpu(__le16 *var, u16 val) { *var = cpu_to_le16(le16_to_cpu(*var) - val); diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c index 167093e8d287..32bdb034c2a3 100644 --- a/fs/ntfs3/record.c +++ b/fs/ntfs3/record.c @@ -71,7 +71,7 @@ static __le16 mi_new_attt_id(struct ntfs_inode *ni, struct mft_inode *mi) int mi_get(struct ntfs_sb_info *sbi, CLST rno, struct mft_inode **mi) { int err; - struct mft_inode *m = kzalloc(sizeof(struct mft_inode), GFP_NOFS); + struct mft_inode *m = kzalloc_obj(struct mft_inode, GFP_NOFS); if (!m) return -ENOMEM; diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c index 395b20492525..c0324cdc174d 100644 --- a/fs/ntfs3/run.c +++ b/fs/ntfs3/run.c @@ -454,7 +454,7 @@ bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len, /* * If existing range fits then were done. - * Otherwise extend found one and fall back to range jocode. + * Otherwise extend found one and fall back to range join code. */ if (r->vcn + r->len < vcn + len) r->len += len - ((r->vcn + r->len) - vcn); @@ -482,7 +482,8 @@ bool run_add_entry(struct runs_tree *run, CLST vcn, CLST lcn, CLST len, return true; } -/* run_collapse_range +/* + * run_collapse_range * * Helper for attr_collapse_range(), * which is helper for fallocate(collapse_range). @@ -493,8 +494,9 @@ bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len, CLST sub) struct ntfs_run *r, *e, *eat_start, *eat_end; CLST end; - if (WARN_ON(!run_lookup(run, vcn, &index))) - return true; /* Should never be here. */ + if (!run_lookup(run, vcn, &index) && index >= run->count) { + return true; + } e = run->runs + run->count; r = run->runs + index; @@ -560,13 +562,13 @@ bool run_collapse_range(struct runs_tree *run, CLST vcn, CLST len, CLST sub) * Helper for attr_insert_range(), * which is helper for fallocate(insert_range). */ -bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len) +int run_insert_range(struct runs_tree *run, CLST vcn, CLST len) { size_t index; struct ntfs_run *r, *e; if (WARN_ON(!run_lookup(run, vcn, &index))) - return false; /* Should never be here. */ + return -EINVAL; /* Should never be here. */ e = run->runs + run->count; r = run->runs + index; @@ -588,13 +590,49 @@ bool run_insert_range(struct runs_tree *run, CLST vcn, CLST len) r->len = len1; if (!run_add_entry(run, vcn + len, lcn2, len2, false)) - return false; + return -ENOMEM; } if (!run_add_entry(run, vcn, SPARSE_LCN, len, false)) - return false; + return -ENOMEM; - return true; + return 0; +} + +/* run_insert_range_da + * + * Helper for attr_insert_range(), + * which is helper for fallocate(insert_range). + */ +int run_insert_range_da(struct runs_tree *run, CLST vcn, CLST len) +{ + struct ntfs_run *r, *r0 = NULL, *e = run->runs + run->count; + ; + + for (r = run->runs; r < e; r++) { + CLST end = r->vcn + r->len; + + if (vcn >= end) + continue; + + if (!r0 && r->vcn < vcn) { + r0 = r; + } else { + r->vcn += len; + } + } + + if (r0) { + /* split fragment. */ + CLST len1 = vcn - r0->vcn; + CLST len2 = r0->len - len1; + + r0->len = len1; + if (!run_add_entry(run, vcn + len, SPARSE_LCN, len2, false)) + return -ENOMEM; + } + + return 0; } /* @@ -1131,11 +1169,14 @@ int run_unpack_ex(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino, struct rw_semaphore *lock = is_mounted(sbi) ? &sbi->mft.ni->file.run_lock : NULL; - if (lock) - down_read(lock); - ntfs_refresh_zone(sbi); - if (lock) - up_read(lock); + if (lock) { + if (down_read_trylock(lock)) { + ntfs_refresh_zone(sbi); + up_read(lock); + } + } else { + ntfs_refresh_zone(sbi); + } } up_write(&wnd->rw_lock); if (err) @@ -1206,3 +1247,97 @@ int run_clone(const struct runs_tree *run, struct runs_tree *new_run) new_run->count = run->count; return 0; } + +/* + * run_remove_range + * + */ +bool run_remove_range(struct runs_tree *run, CLST vcn, CLST len, CLST *done) +{ + size_t index, eat; + struct ntfs_run *r, *e, *eat_start, *eat_end; + CLST end, d; + + *done = 0; + + /* Fast check. */ + if (!run->count) + return true; + + if (!run_lookup(run, vcn, &index) && index >= run->count) { + /* No entries in this run. */ + return true; + } + + + e = run->runs + run->count; + r = run->runs + index; + end = vcn + len; + + if (vcn > r->vcn) { + CLST r_end = r->vcn + r->len; + d = vcn - r->vcn; + + if (r_end > end) { + /* Remove a middle part, split. */ + *done += len; + r->len = d; + return run_add_entry(run, end, r->lcn, r_end - end, + false); + } + /* Remove tail of run .*/ + *done += r->len - d; + r->len = d; + r += 1; + } + + eat_start = r; + eat_end = r; + + for (; r < e; r++) { + if (r->vcn >= end) + continue; + + if (r->vcn + r->len <= end) { + /* Eat this run. */ + *done += r->len; + eat_end = r + 1; + continue; + } + + d = end - r->vcn; + *done += d; + if (r->lcn != SPARSE_LCN) + r->lcn += d; + r->len -= d; + r->vcn = end; + } + + eat = eat_end - eat_start; + memmove(eat_start, eat_end, (e - eat_end) * sizeof(*r)); + run->count -= eat; + + return true; +} + +CLST run_len(const struct runs_tree *run) +{ + const struct ntfs_run *r, *e; + CLST len = 0; + + for (r = run->runs, e = r + run->count; r < e; r++) { + len += r->len; + } + + return len; +} + +CLST run_get_max_vcn(const struct runs_tree *run) +{ + const struct ntfs_run *r; + if (!run->count) + return 0; + + r = run->runs + run->count - 1; + return r->vcn + r->len; +} diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c index 8b0cf0ed4f72..174a7cb202a0 100644 --- a/fs/ntfs3/super.c +++ b/fs/ntfs3/super.c @@ -58,9 +58,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -264,9 +264,13 @@ enum Opt { Opt_windows_names, Opt_showmeta, Opt_acl, + Opt_acl_bool, Opt_iocharset, Opt_prealloc, + Opt_prealloc_bool, Opt_nocase, + Opt_delalloc, + Opt_delalloc_bool, Opt_err, }; @@ -285,10 +289,14 @@ static const struct fs_parameter_spec ntfs_fs_parameters[] = { fsparam_flag("hide_dot_files", Opt_hide_dot_files), fsparam_flag("windows_names", Opt_windows_names), fsparam_flag("showmeta", Opt_showmeta), - fsparam_flag_no("acl", Opt_acl), + fsparam_flag("acl", Opt_acl), + fsparam_bool("acl", Opt_acl_bool), fsparam_string("iocharset", Opt_iocharset), - fsparam_flag_no("prealloc", Opt_prealloc), + fsparam_flag("prealloc", Opt_prealloc), + fsparam_bool("prealloc", Opt_prealloc_bool), fsparam_flag("nocase", Opt_nocase), + fsparam_flag("delalloc", Opt_delalloc), + fsparam_bool("delalloc", Opt_delalloc_bool), {} }; // clang-format on @@ -379,15 +387,17 @@ static int ntfs_fs_parse_param(struct fs_context *fc, case Opt_showmeta: opts->showmeta = 1; break; - case Opt_acl: - if (!result.negated) + case Opt_acl_bool: + if (result.boolean) { + fallthrough; + case Opt_acl: #ifdef CONFIG_NTFS3_FS_POSIX_ACL fc->sb_flags |= SB_POSIXACL; #else return invalf( fc, "ntfs3: Support for ACL not compiled in!"); #endif - else + } else fc->sb_flags &= ~SB_POSIXACL; break; case Opt_iocharset: @@ -396,11 +406,20 @@ static int ntfs_fs_parse_param(struct fs_context *fc, param->string = NULL; break; case Opt_prealloc: - opts->prealloc = !result.negated; + opts->prealloc = 1; + break; + case Opt_prealloc_bool: + opts->prealloc = result.boolean; break; case Opt_nocase: opts->nocase = 1; break; + case Opt_delalloc: + opts->delalloc = 1; + break; + case Opt_delalloc_bool: + opts->delalloc = result.boolean; + break; default: /* Should not be here unless we forget add case. */ return -EINVAL; @@ -674,7 +693,7 @@ static noinline void ntfs3_put_sbi(struct ntfs_sb_info *sbi) sbi->volume.ni = NULL; } - ntfs_update_mftmirr(sbi, 0); + ntfs_update_mftmirr(sbi); indx_clear(&sbi->security.index_sii); indx_clear(&sbi->security.index_sdh); @@ -705,9 +724,7 @@ static void ntfs_put_super(struct super_block *sb) ntfs_set_state(sbi, NTFS_DIRTY_CLEAR); if (sbi->options) { - unload_nls(sbi->options->nls); - kfree(sbi->options->nls_name); - kfree(sbi->options); + put_mount_options(sbi->options); sbi->options = NULL; } @@ -719,14 +736,22 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *buf) struct super_block *sb = dentry->d_sb; struct ntfs_sb_info *sbi = sb->s_fs_info; struct wnd_bitmap *wnd = &sbi->used.bitmap; + CLST da_clusters = ntfs_get_da(sbi); buf->f_type = sb->s_magic; - buf->f_bsize = sbi->cluster_size; + buf->f_bsize = buf->f_frsize = sbi->cluster_size; buf->f_blocks = wnd->nbits; - buf->f_bfree = buf->f_bavail = wnd_zeroes(wnd); + buf->f_bfree = wnd_zeroes(wnd); + if (buf->f_bfree > da_clusters) { + buf->f_bfree -= da_clusters; + } else { + buf->f_bfree = 0; + } + buf->f_bavail = buf->f_bfree; + buf->f_fsid.val[0] = sbi->volume.ser_num; - buf->f_fsid.val[1] = (sbi->volume.ser_num >> 32); + buf->f_fsid.val[1] = sbi->volume.ser_num >> 32; buf->f_namelen = NTFS_NAME_LEN; return 0; @@ -771,6 +796,8 @@ static int ntfs_show_options(struct seq_file *m, struct dentry *root) seq_puts(m, ",prealloc"); if (opts->nocase) seq_puts(m, ",nocase"); + if (opts->delalloc) + seq_puts(m, ",delalloc"); return 0; } @@ -823,7 +850,12 @@ static int ntfs_sync_fs(struct super_block *sb, int wait) if (!err) ntfs_set_state(sbi, NTFS_DIRTY_CLEAR); - ntfs_update_mftmirr(sbi, wait); + ntfs_update_mftmirr(sbi); + + if (wait) { + sync_blockdev(sb->s_bdev); + blkdev_issue_flush(sb->s_bdev); + } return err; } @@ -1076,7 +1108,7 @@ static int ntfs_init_from_boot(struct super_block *sb, u32 sector_size, dev_size += sector_size - 1; } - sbi->bdev_blocksize_mask = max(boot_sector_size, sector_size) - 1; + sbi->bdev_blocksize = max(boot_sector_size, sector_size); sbi->mft.lbo = mlcn << cluster_bits; sbi->mft.lbo2 = mlcn2 << cluster_bits; @@ -1253,7 +1285,6 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) } } sbi->options = options; - fc->fs_private = NULL; sb->s_flags |= SB_NODIRATIME; sb->s_magic = 0x7366746e; // "ntfs" sb->s_op = &ntfs_sops; @@ -1652,9 +1683,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) */ struct buffer_head *bh0 = sb_getblk(sb, 0); if (bh0) { - if (buffer_locked(bh0)) - __wait_on_buffer(bh0); - + wait_on_buffer(bh0); lock_buffer(bh0); memcpy(bh0->b_data, boot2, sizeof(*boot2)); set_buffer_uptodate(bh0); @@ -1679,9 +1708,7 @@ static int ntfs_fill_super(struct super_block *sb, struct fs_context *fc) out: /* sbi->options == options */ if (options) { - unload_nls(options->nls); - kfree(options->nls_name); - kfree(options); + put_mount_options(sbi->options); sbi->options = NULL; } @@ -1801,7 +1828,7 @@ static int __ntfs_init_fs_context(struct fs_context *fc) struct ntfs_mount_options *opts; struct ntfs_sb_info *sbi; - opts = kzalloc(sizeof(struct ntfs_mount_options), GFP_NOFS); + opts = kzalloc_obj(struct ntfs_mount_options, GFP_NOFS); if (!opts) return -ENOMEM; @@ -1820,7 +1847,7 @@ static int __ntfs_init_fs_context(struct fs_context *fc) if (fc->purpose == FS_CONTEXT_FOR_RECONFIGURE) goto ok; - sbi = kzalloc(sizeof(struct ntfs_sb_info), GFP_NOFS); + sbi = kzalloc_obj(struct ntfs_sb_info, GFP_NOFS); if (!sbi) goto free_opts; diff --git a/fs/ntfs3/xattr.c b/fs/ntfs3/xattr.c index b96e6ac90e9f..3fffda784892 100644 --- a/fs/ntfs3/xattr.c +++ b/fs/ntfs3/xattr.c @@ -460,7 +460,7 @@ static noinline int ntfs_set_ea(struct inode *inode, const char *name, new_sz = size; err = attr_set_size(ni, ATTR_EA, NULL, 0, &ea_run, new_sz, &new_sz, - false, NULL); + false); if (err) goto out; diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index b7db177d17d6..344fd4d95fbc 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -686,7 +686,7 @@ static struct ocfs2_path *ocfs2_new_path(struct buffer_head *root_bh, BUG_ON(le16_to_cpu(root_el->l_tree_depth) >= OCFS2_MAX_PATH_DEPTH); - path = kzalloc(sizeof(*path), GFP_NOFS); + path = kzalloc_obj(*path, GFP_NOFS); if (path) { path->p_tree_depth = le16_to_cpu(root_el->l_tree_depth); get_bh(root_bh); @@ -1202,8 +1202,7 @@ static int ocfs2_add_branch(handle_t *handle, } /* allocate the number of new eb blocks we need */ - new_eb_bhs = kcalloc(new_blocks, sizeof(struct buffer_head *), - GFP_KERNEL); + new_eb_bhs = kzalloc_objs(struct buffer_head *, new_blocks); if (!new_eb_bhs) { status = -ENOMEM; mlog_errno(status); @@ -6493,7 +6492,7 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, int ret = 0; struct ocfs2_cached_block_free *item; - item = kzalloc(sizeof(*item), GFP_NOFS); + item = kzalloc_obj(*item, GFP_NOFS); if (item == NULL) { ret = -ENOMEM; mlog_errno(ret); @@ -6619,7 +6618,7 @@ ocfs2_find_per_slot_free_list(int type, fl = fl->f_next_suballocator; } - fl = kmalloc(sizeof(*fl), GFP_NOFS); + fl = kmalloc_obj(*fl, GFP_NOFS); if (fl) { fl->f_inode_type = type; fl->f_slot = slot; @@ -6794,7 +6793,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, goto out; } - item = kzalloc(sizeof(*item), GFP_NOFS); + item = kzalloc_obj(*item, GFP_NOFS); if (item == NULL) { ret = -ENOMEM; mlog_errno(ret); @@ -6984,8 +6983,8 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle, if (range_start >= range_end) return 0; - folios = kcalloc(ocfs2_pages_per_cluster(sb), - sizeof(struct folio *), GFP_NOFS); + folios = kzalloc_objs(struct folio *, ocfs2_pages_per_cluster(sb), + GFP_NOFS); if (folios == NULL) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 76c86f1c2b1c..17ba79f443ee 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -823,7 +823,7 @@ static int ocfs2_alloc_write_ctxt(struct ocfs2_write_ctxt **wcp, u32 cend; struct ocfs2_write_ctxt *wc; - wc = kzalloc(sizeof(struct ocfs2_write_ctxt), GFP_NOFS); + wc = kzalloc_obj(struct ocfs2_write_ctxt, GFP_NOFS); if (!wc) return -ENOMEM; @@ -1325,8 +1325,7 @@ static int ocfs2_unwritten_check(struct inode *inode, if (new == NULL) { spin_unlock(&oi->ip_lock); - new = kmalloc(sizeof(struct ocfs2_unwritten_extent), - GFP_NOFS); + new = kmalloc_obj(struct ocfs2_unwritten_extent, GFP_NOFS); if (new == NULL) { ret = -ENOMEM; goto out; @@ -2080,7 +2079,7 @@ ocfs2_dio_alloc_write_ctx(struct buffer_head *bh, int *alloc) if (bh->b_private) return bh->b_private; - dwc = kmalloc(sizeof(struct ocfs2_dio_write_ctxt), GFP_NOFS); + dwc = kmalloc_obj(struct ocfs2_dio_write_ctxt, GFP_NOFS); if (dwc == NULL) return NULL; INIT_LIST_HEAD(&dwc->dw_zero_list); diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 8e9cbc334cf4..fe1949578336 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1677,8 +1677,7 @@ static int o2hb_map_slot_data(struct o2hb_region *reg) if (reg->hr_tmp_block == NULL) return -ENOMEM; - reg->hr_slots = kcalloc(reg->hr_blocks, - sizeof(struct o2hb_disk_slot), GFP_KERNEL); + reg->hr_slots = kzalloc_objs(struct o2hb_disk_slot, reg->hr_blocks); if (reg->hr_slots == NULL) return -ENOMEM; @@ -1694,8 +1693,7 @@ static int o2hb_map_slot_data(struct o2hb_region *reg) "at %u blocks per page\n", reg->hr_num_pages, reg->hr_blocks, spp); - reg->hr_slot_data = kcalloc(reg->hr_num_pages, sizeof(struct page *), - GFP_KERNEL); + reg->hr_slot_data = kzalloc_objs(struct page *, reg->hr_num_pages); if (!reg->hr_slot_data) return -ENOMEM; @@ -2001,7 +1999,7 @@ static struct config_item *o2hb_heartbeat_group_make_item(struct config_group *g struct o2hb_region *reg = NULL; int ret; - reg = kzalloc(sizeof(struct o2hb_region), GFP_KERNEL); + reg = kzalloc_obj(struct o2hb_region); if (reg == NULL) return ERR_PTR(-ENOMEM); @@ -2211,7 +2209,7 @@ struct config_group *o2hb_alloc_hb_set(void) struct o2hb_heartbeat_group *hs = NULL; struct config_group *ret = NULL; - hs = kzalloc(sizeof(struct o2hb_heartbeat_group), GFP_KERNEL); + hs = kzalloc_obj(struct o2hb_heartbeat_group); if (hs == NULL) goto out; diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index bc27301eab6d..f7ab66e70799 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -380,7 +380,7 @@ static int sc_common_open(struct file *file, int ctxt) struct o2net_sock_debug *sd; struct o2net_sock_container *dummy_sc; - dummy_sc = kzalloc(sizeof(*dummy_sc), GFP_KERNEL); + dummy_sc = kzalloc_obj(*dummy_sc); if (!dummy_sc) return -ENOMEM; diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c index c5e83c774d73..402563154550 100644 --- a/fs/ocfs2/cluster/nodemanager.c +++ b/fs/ocfs2/cluster/nodemanager.c @@ -587,7 +587,7 @@ static struct config_item *o2nm_node_group_make_item(struct config_group *group, if (strlen(name) > O2NM_MAX_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); - node = kzalloc(sizeof(struct o2nm_node), GFP_KERNEL); + node = kzalloc_obj(struct o2nm_node); if (node == NULL) return ERR_PTR(-ENOMEM); @@ -695,8 +695,8 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g if (o2nm_single_cluster) return ERR_PTR(-ENOSPC); - cluster = kzalloc(sizeof(struct o2nm_cluster), GFP_KERNEL); - ns = kzalloc(sizeof(struct o2nm_node_group), GFP_KERNEL); + cluster = kzalloc_obj(struct o2nm_cluster); + ns = kzalloc_obj(struct o2nm_node_group); o2hb_group = o2hb_alloc_hb_set(); if (cluster == NULL || ns == NULL || o2hb_group == NULL) goto out; diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 79b281e32f4c..09a1f3b77bb8 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -415,7 +415,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) int status = 0; page = alloc_page(GFP_NOFS); - sc = kzalloc(sizeof(*sc), GFP_NOFS); + sc = kzalloc_obj(*sc, GFP_NOFS); if (sc == NULL || page == NULL) goto out; @@ -825,7 +825,7 @@ int o2net_register_handler(u32 msg_type, u32 key, u32 max_len, goto out; } - nmh = kzalloc(sizeof(struct o2net_msg_handler), GFP_NOFS); + nmh = kzalloc_obj(struct o2net_msg_handler, GFP_NOFS); if (nmh == NULL) { ret = -ENOMEM; goto out; @@ -1064,14 +1064,14 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, o2net_set_nst_sock_container(&nst, sc); veclen = caller_veclen + 1; - vec = kmalloc_array(veclen, sizeof(struct kvec), GFP_ATOMIC); + vec = kmalloc_objs(struct kvec, veclen, GFP_ATOMIC); if (vec == NULL) { mlog(0, "failed to %zu element kvec!\n", veclen); ret = -ENOMEM; goto out; } - msg = kmalloc(sizeof(struct o2net_msg), GFP_ATOMIC); + msg = kmalloc_obj(struct o2net_msg, GFP_ATOMIC); if (!msg) { mlog(0, "failed to allocate a o2net_msg!\n"); ret = -ENOMEM; diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c index 1873bbbb7e5b..c4ba968e778b 100644 --- a/fs/ocfs2/dcache.c +++ b/fs/ocfs2/dcache.c @@ -265,7 +265,7 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry, /* * There are no other aliases */ - dl = kmalloc(sizeof(*dl), GFP_NOFS); + dl = kmalloc_obj(*dl, GFP_NOFS); if (!dl) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index 782afd9fa934..1c8abf2c592c 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c @@ -2550,8 +2550,7 @@ static struct buffer_head **ocfs2_dx_dir_kmalloc_leaves(struct super_block *sb, int num_dx_leaves = ocfs2_clusters_to_blocks(sb, 1); struct buffer_head **dx_leaves; - dx_leaves = kcalloc(num_dx_leaves, sizeof(struct buffer_head *), - GFP_NOFS); + dx_leaves = kzalloc_objs(struct buffer_head *, num_dx_leaves, GFP_NOFS); if (dx_leaves && ret_num_leaves) *ret_num_leaves = num_dx_leaves; diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index cf3ca2f597c2..70ca79e4bdc3 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -1048,7 +1048,7 @@ static int dlm_send_regions(struct dlm_ctxt *dlm, unsigned long *node_map) if (find_first_bit(node_map, O2NM_MAX_NODES) >= O2NM_MAX_NODES) goto bail; - qr = kzalloc(sizeof(struct dlm_query_region), GFP_KERNEL); + qr = kzalloc_obj(struct dlm_query_region); if (!qr) { ret = -ENOMEM; mlog_errno(ret); @@ -1220,7 +1220,7 @@ static int dlm_send_nodeinfo(struct dlm_ctxt *dlm, unsigned long *node_map) if (find_first_bit(node_map, O2NM_MAX_NODES) >= O2NM_MAX_NODES) goto bail; - qn = kzalloc(sizeof(struct dlm_query_nodeinfo), GFP_KERNEL); + qn = kzalloc_obj(struct dlm_query_nodeinfo); if (!qn) { ret = -ENOMEM; mlog_errno(ret); @@ -1592,7 +1592,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm) mlog(0, "%p", dlm); - ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); + ctxt = kzalloc_obj(*ctxt); if (!ctxt) { status = -ENOMEM; mlog_errno(status); @@ -1946,7 +1946,7 @@ static struct dlm_ctxt *dlm_alloc_ctxt(const char *domain, int ret; struct dlm_ctxt *dlm = NULL; - dlm = kzalloc(sizeof(*dlm), GFP_KERNEL); + dlm = kzalloc_obj(*dlm); if (!dlm) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 041fd1791ae7..46120eb75d90 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -414,7 +414,7 @@ struct dlm_lock * dlm_new_lock(int type, u8 node, u64 cookie, if (!lksb) { /* zero memory only if kernel-allocated */ - lksb = kzalloc(sizeof(*lksb), GFP_NOFS); + lksb = kzalloc_obj(*lksb, GFP_NOFS); if (!lksb) { kmem_cache_free(dlm_lock_cache, lock); return NULL; diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 4145e06d2c08..eb62724bbe9b 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2040,7 +2040,7 @@ int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, int ignore_higher, u8 request_from, u32 flags) { struct dlm_work_item *item; - item = kzalloc(sizeof(*item), GFP_ATOMIC); + item = kzalloc_obj(*item, GFP_ATOMIC); if (!item) return -ENOMEM; @@ -2303,7 +2303,7 @@ int dlm_deref_lockres_handler(struct o2net_msg *msg, u32 len, void *data, goto done; } - item = kzalloc(sizeof(*item), GFP_NOFS); + item = kzalloc_obj(*item, GFP_NOFS); if (!item) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 843ee02bd85f..128872bd945d 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c @@ -743,7 +743,7 @@ static int dlm_init_recovery_area(struct dlm_ctxt *dlm, u8 dead_node) } BUG_ON(num == dead_node); - ndata = kzalloc(sizeof(*ndata), GFP_NOFS); + ndata = kzalloc_obj(*ndata, GFP_NOFS); if (!ndata) { dlm_destroy_recovery_area(dlm); return -ENOMEM; @@ -830,7 +830,7 @@ int dlm_request_all_locks_handler(struct o2net_msg *msg, u32 len, void *data, } BUG_ON(lr->dead_node != dlm->reco.dead_node); - item = kzalloc(sizeof(*item), GFP_NOFS); + item = kzalloc_obj(*item, GFP_NOFS); if (!item) { dlm_put(dlm); return -ENOMEM; @@ -1382,7 +1382,7 @@ int dlm_mig_lockres_handler(struct o2net_msg *msg, u32 len, void *data, ret = -ENOMEM; buf = kmalloc(be16_to_cpu(msg->data_len), GFP_NOFS); - item = kzalloc(sizeof(*item), GFP_NOFS); + item = kzalloc_obj(*item, GFP_NOFS); if (!buf || !item) goto leave; diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 339f0b11cdc8..45cce261da65 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -134,7 +134,7 @@ static int dlmfs_file_open(struct inode *inode, * doesn't make sense for LVB writes. */ file->f_flags &= ~O_APPEND; - fp = kmalloc(sizeof(*fp), GFP_NOFS); + fp = kmalloc_obj(*fp, GFP_NOFS); if (!fp) { status = -ENOMEM; goto bail; diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c index 619ff03b15d6..bd2ddb7d841d 100644 --- a/fs/ocfs2/dlmglue.c +++ b/fs/ocfs2/dlmglue.c @@ -3030,7 +3030,7 @@ struct ocfs2_dlm_debug *ocfs2_new_dlm_debug(void) { struct ocfs2_dlm_debug *dlm_debug; - dlm_debug = kmalloc(sizeof(struct ocfs2_dlm_debug), GFP_KERNEL); + dlm_debug = kmalloc_obj(struct ocfs2_dlm_debug); if (!dlm_debug) { mlog_errno(-ENOMEM); goto out; diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index ef147e8b3271..d68229422dda 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c @@ -246,7 +246,7 @@ void ocfs2_extent_map_insert_rec(struct inode *inode, if (new_emi == NULL) { spin_unlock(&oi->ip_lock); - new_emi = kmalloc(sizeof(*new_emi), GFP_NOFS); + new_emi = kmalloc_obj(*new_emi, GFP_NOFS); if (new_emi == NULL) goto out; diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index ed961a854983..7df9921c1a38 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -54,7 +54,7 @@ static int ocfs2_init_file_private(struct inode *inode, struct file *file) { struct ocfs2_file_private *fp; - fp = kzalloc(sizeof(struct ocfs2_file_private), GFP_KERNEL); + fp = kzalloc_obj(struct ocfs2_file_private); if (!fp) return -ENOMEM; diff --git a/fs/ocfs2/filecheck.c b/fs/ocfs2/filecheck.c index 3ad7baf67658..be713d7d24a7 100644 --- a/fs/ocfs2/filecheck.c +++ b/fs/ocfs2/filecheck.c @@ -169,7 +169,7 @@ int ocfs2_filecheck_create_sysfs(struct ocfs2_super *osb) struct ocfs2_filecheck *fcheck; struct ocfs2_filecheck_sysfs_entry *entry = &osb->osb_fc_ent; - fcheck = kmalloc(sizeof(struct ocfs2_filecheck), GFP_NOFS); + fcheck = kmalloc_obj(struct ocfs2_filecheck, GFP_NOFS); if (!fcheck) return -ENOMEM; @@ -464,7 +464,7 @@ static ssize_t ocfs2_filecheck_attr_store(struct kobject *kobj, goto exit; } - entry = kmalloc(sizeof(struct ocfs2_filecheck_entry), GFP_NOFS); + entry = kmalloc_obj(struct ocfs2_filecheck_entry, GFP_NOFS); if (!entry) { ret = -ENOMEM; goto exit; diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index b6864602814c..bfed0fb35f9b 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -334,7 +334,7 @@ static int ocfs2_info_handle_freeinode(struct inode *inode, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct inode *inode_alloc = NULL; - oifi = kzalloc(sizeof(struct ocfs2_info_freeinode), GFP_KERNEL); + oifi = kzalloc_obj(struct ocfs2_info_freeinode); if (!oifi) { status = -ENOMEM; mlog_errno(status); @@ -620,7 +620,7 @@ static int ocfs2_info_handle_freefrag(struct inode *inode, struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); struct inode *gb_inode = NULL; - oiff = kzalloc(sizeof(struct ocfs2_info_freefrag), GFP_KERNEL); + oiff = kzalloc_obj(struct ocfs2_info_freefrag); if (!oiff) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 85239807dec7..4c86a9d46870 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c @@ -114,9 +114,7 @@ int ocfs2_compute_replay_slots(struct ocfs2_super *osb) if (osb->replay_map) return 0; - replay_map = kzalloc(struct_size(replay_map, rm_replay_slots, - osb->max_slots), - GFP_KERNEL); + replay_map = kzalloc_flex(*replay_map, rm_replay_slots, osb->max_slots); if (!replay_map) { mlog_errno(-ENOMEM); return -ENOMEM; @@ -178,8 +176,7 @@ int ocfs2_recovery_init(struct ocfs2_super *osb) osb->recovery_thread_task = NULL; init_waitqueue_head(&osb->recovery_event); - rm = kzalloc(struct_size(rm, rm_entries, osb->max_slots), - GFP_KERNEL); + rm = kzalloc_flex(*rm, rm_entries, osb->max_slots); if (!rm) { mlog_errno(-ENOMEM); return -ENOMEM; @@ -878,7 +875,7 @@ int ocfs2_journal_alloc(struct ocfs2_super *osb) int status = 0; struct ocfs2_journal *journal; - journal = kzalloc(sizeof(struct ocfs2_journal), GFP_KERNEL); + journal = kzalloc_obj(struct ocfs2_journal); if (!journal) { mlog(ML_ERROR, "unable to alloc journal\n"); status = -ENOMEM; @@ -1394,7 +1391,7 @@ static void ocfs2_queue_recovery_completion(struct ocfs2_journal *journal, { struct ocfs2_la_recovery_item *item; - item = kmalloc(sizeof(struct ocfs2_la_recovery_item), GFP_NOFS); + item = kmalloc_obj(struct ocfs2_la_recovery_item, GFP_NOFS); if (!item) { /* Though we wish to avoid it, we are in fact safe in * skipping local alloc cleanup as fsck.ocfs2 is more @@ -1480,7 +1477,7 @@ static int __ocfs2_recovery_thread(void *arg) } if (quota_enabled) { - rm_quota = kcalloc(osb->max_slots, sizeof(int), GFP_NOFS); + rm_quota = kzalloc_objs(int, osb->max_slots, GFP_NOFS); if (!rm_quota) { status = -ENOMEM; goto bail; diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index 56be21c695d6..82d290cf4432 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c @@ -1094,7 +1094,7 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, { int status; - *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); + *ac = kzalloc_obj(struct ocfs2_alloc_context); if (!(*ac)) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index e3cdf8788484..c53de4439d93 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c @@ -1011,7 +1011,7 @@ int ocfs2_ioctl_move_extents(struct file *filp, void __user *argp) goto out_drop; } - context = kzalloc(sizeof(struct ocfs2_move_extents_context), GFP_NOFS); + context = kzalloc_obj(struct ocfs2_move_extents_context, GFP_NOFS); if (!context) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 4ec6dbed65a8..268b79339a51 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1736,7 +1736,7 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, goto bail; } - bhs = kcalloc(blocks, sizeof(struct buffer_head *), GFP_KERNEL); + bhs = kzalloc_objs(struct buffer_head *, blocks); if (!bhs) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index de7f12858729..c4e0117d8977 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c @@ -298,7 +298,7 @@ static int ocfs2_add_recovery_chunk(struct super_block *sb, { struct ocfs2_recovery_chunk *rc; - rc = kmalloc(sizeof(struct ocfs2_recovery_chunk), GFP_NOFS); + rc = kmalloc_obj(struct ocfs2_recovery_chunk, GFP_NOFS); if (!rc) return -ENOMEM; rc->rc_chunk = chunk; @@ -372,7 +372,7 @@ static struct ocfs2_quota_recovery *ocfs2_alloc_quota_recovery(void) int type; struct ocfs2_quota_recovery *rec; - rec = kmalloc(sizeof(struct ocfs2_quota_recovery), GFP_NOFS); + rec = kmalloc_obj(struct ocfs2_quota_recovery, GFP_NOFS); if (!rec) return NULL; for (type = 0; type < OCFS2_MAXQUOTAS; type++) @@ -692,7 +692,7 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) info->dqi_max_spc_limit = 0x7fffffffffffffffLL; info->dqi_max_ino_limit = 0x7fffffffffffffffLL; - oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS); + oinfo = kmalloc_obj(struct ocfs2_mem_dqinfo, GFP_NOFS); if (!oinfo) { mlog(ML_ERROR, "failed to allocate memory for ocfs2 quota" " info."); diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index c92e0ea85bca..c1cdececdfa4 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c @@ -311,7 +311,7 @@ ocfs2_allocate_refcount_tree(struct ocfs2_super *osb, u64 rf_blkno) { struct ocfs2_refcount_tree *new; - new = kzalloc(sizeof(struct ocfs2_refcount_tree), GFP_NOFS); + new = kzalloc_obj(struct ocfs2_refcount_tree, GFP_NOFS); if (!new) return NULL; @@ -3397,7 +3397,7 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode, BUG_ON(cow_len == 0); - context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); + context = kzalloc_obj(struct ocfs2_cow_context, GFP_NOFS); if (!context) { ret = -ENOMEM; mlog_errno(ret); @@ -3606,7 +3606,7 @@ int ocfs2_refcount_cow_xattr(struct inode *inode, BUG_ON(cow_len == 0); - context = kzalloc(sizeof(struct ocfs2_cow_context), GFP_NOFS); + context = kzalloc_obj(struct ocfs2_cow_context, GFP_NOFS); if (!context) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c index ea4a68abc25b..3aa4a082ea03 100644 --- a/fs/ocfs2/slot_map.c +++ b/fs/ocfs2/slot_map.c @@ -385,8 +385,7 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb, trace_ocfs2_map_slot_buffers(bytes, si->si_blocks); - si->si_bh = kcalloc(si->si_blocks, sizeof(struct buffer_head *), - GFP_KERNEL); + si->si_bh = kzalloc_objs(struct buffer_head *, si->si_blocks); if (!si->si_bh) { status = -ENOMEM; mlog_errno(status); @@ -425,7 +424,7 @@ int ocfs2_init_slot_info(struct ocfs2_super *osb) struct inode *inode = NULL; struct ocfs2_slot_info *si; - si = kzalloc(struct_size(si, si_slots, osb->max_slots), GFP_KERNEL); + si = kzalloc_flex(*si, si_slots, osb->max_slots); if (!si) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/stack_o2cb.c b/fs/ocfs2/stack_o2cb.c index f58e891aa2da..7a55b1a071db 100644 --- a/fs/ocfs2/stack_o2cb.c +++ b/fs/ocfs2/stack_o2cb.c @@ -334,7 +334,7 @@ static int o2cb_cluster_connect(struct ocfs2_cluster_connection *conn) goto out; } - priv = kzalloc(sizeof(struct o2dlm_private), GFP_KERNEL); + priv = kzalloc_obj(struct o2dlm_private); if (!priv) { rc = -ENOMEM; goto out_free; diff --git a/fs/ocfs2/stack_user.c b/fs/ocfs2/stack_user.c index be0a5758bd40..5803f1dee679 100644 --- a/fs/ocfs2/stack_user.c +++ b/fs/ocfs2/stack_user.c @@ -593,7 +593,7 @@ static int ocfs2_control_open(struct inode *inode, struct file *file) { struct ocfs2_control_private *p; - p = kzalloc(sizeof(struct ocfs2_control_private), GFP_KERNEL); + p = kzalloc_obj(struct ocfs2_control_private); if (!p) return -ENOMEM; p->op_this_node = -1; @@ -967,7 +967,7 @@ static int user_cluster_connect(struct ocfs2_cluster_connection *conn) BUG_ON(conn == NULL); - lc = kzalloc(sizeof(struct ocfs2_live_connection), GFP_KERNEL); + lc = kzalloc_obj(struct ocfs2_live_connection); if (!lc) return -ENOMEM; diff --git a/fs/ocfs2/stackglue.c b/fs/ocfs2/stackglue.c index fca2fd07c881..741d6191d871 100644 --- a/fs/ocfs2/stackglue.c +++ b/fs/ocfs2/stackglue.c @@ -328,8 +328,7 @@ int ocfs2_cluster_connect(const char *stack_name, goto out; } - new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection), - GFP_KERNEL); + new_conn = kzalloc_obj(struct ocfs2_cluster_connection); if (!new_conn) { rc = -ENOMEM; goto out; diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 79d1325b2111..bb98bd51338e 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -1034,7 +1034,7 @@ int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb, int status; int slot = ocfs2_get_meta_steal_slot(osb); - *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); + *ac = kzalloc_obj(struct ocfs2_alloc_context); if (!(*ac)) { status = -ENOMEM; mlog_errno(status); @@ -1105,7 +1105,7 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb, int slot = ocfs2_get_inode_steal_slot(osb); u64 alloc_group; - *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); + *ac = kzalloc_obj(struct ocfs2_alloc_context); if (!(*ac)) { status = -ENOMEM; mlog_errno(status); @@ -1221,7 +1221,7 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb, int status, ret = 0; int retried = 0; - *ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL); + *ac = kzalloc_obj(struct ocfs2_alloc_context); if (!(*ac)) { status = -ENOMEM; mlog_errno(status); @@ -2245,7 +2245,7 @@ int ocfs2_find_new_inode_loc(struct inode *dir, BUG_ON(ac->ac_bits_wanted != 1); BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); - res = kzalloc(sizeof(*res), GFP_NOFS); + res = kzalloc_obj(*res, GFP_NOFS); if (res == NULL) { ret = -ENOMEM; mlog_errno(ret); diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 3cbafac50cd1..d7c58fd7d438 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -1200,7 +1200,7 @@ static int ocfs2_init_fs_context(struct fs_context *fc) { struct mount_options *mopt; - mopt = kzalloc(sizeof(struct mount_options), GFP_KERNEL); + mopt = kzalloc_obj(struct mount_options); if (!mopt) return -EINVAL; @@ -1953,7 +1953,7 @@ static int ocfs2_initialize_super(struct super_block *sb, struct ocfs2_super *osb; u64 total_blocks; - osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL); + osb = kzalloc_obj(struct ocfs2_super); if (!osb) { status = -ENOMEM; mlog_errno(status); diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index e434a62dd69f..42ee5db362d3 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c @@ -324,7 +324,7 @@ static struct ocfs2_xattr_bucket *ocfs2_xattr_bucket_new(struct inode *inode) BUG_ON(blks > OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET); - bucket = kzalloc(sizeof(struct ocfs2_xattr_bucket), GFP_NOFS); + bucket = kzalloc_obj(struct ocfs2_xattr_bucket, GFP_NOFS); if (bucket) { bucket->bu_inode = inode; bucket->bu_blocks = blks; diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index 701ed85d9831..90ae07c69349 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c @@ -464,7 +464,7 @@ static int omfs_fill_super(struct super_block *sb, struct fs_context *fc) int ret = -EINVAL; int silent = fc->sb_flags & SB_SILENT; - sbi = kzalloc(sizeof(struct omfs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct omfs_sb_info); if (!sbi) return -ENOMEM; @@ -612,7 +612,7 @@ static int omfs_init_fs_context(struct fs_context *fc) { struct omfs_mount_options *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; diff --git a/fs/orangefs/dir.c b/fs/orangefs/dir.c index 3c32bf9f1296..6e2ebc8b9867 100644 --- a/fs/orangefs/dir.c +++ b/fs/orangefs/dir.c @@ -363,8 +363,7 @@ static int orangefs_dir_iterate(struct file *file, static int orangefs_dir_open(struct inode *inode, struct file *file) { struct orangefs_dir *od; - file->private_data = kmalloc(sizeof(struct orangefs_dir), - GFP_KERNEL); + file->private_data = kmalloc_obj(struct orangefs_dir); if (!file->private_data) return -ENOMEM; od = file->private_data; diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index afd610a3fc68..42591252e239 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -411,8 +411,8 @@ static int orangefs_file_mmap_prepare(struct vm_area_desc *desc) "orangefs_file_mmap: called on %pD\n", file); /* set the sequential readahead hint */ - desc->vm_flags |= VM_SEQ_READ; - desc->vm_flags &= ~VM_RAND_READ; + vma_desc_set_flags(desc, VMA_SEQ_READ_BIT); + vma_desc_clear_flags(desc, VMA_RAND_READ_BIT); file_accessed(file); desc->vm_ops = &orangefs_file_vm_ops; diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index f420f48fc069..2d4710d0e05e 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -184,16 +184,16 @@ static int orangefs_writepages(struct address_space *mapping, int error; struct folio *folio = NULL; - ow = kzalloc(sizeof(struct orangefs_writepages), GFP_KERNEL); + ow = kzalloc_obj(struct orangefs_writepages); if (!ow) return -ENOMEM; ow->maxpages = orangefs_bufmap_size_query()/PAGE_SIZE; - ow->folios = kcalloc(ow->maxpages, sizeof(struct folio *), GFP_KERNEL); + ow->folios = kzalloc_objs(struct folio *, ow->maxpages); if (!ow->folios) { kfree(ow); return -ENOMEM; } - ow->bv = kcalloc(ow->maxpages, sizeof(struct bio_vec), GFP_KERNEL); + ow->bv = kzalloc_objs(struct bio_vec, ow->maxpages); if (!ow->bv) { kfree(ow->folios); kfree(ow); @@ -328,7 +328,7 @@ static int orangefs_write_begin(const struct kiocb *iocb, } } - wr = kmalloc(sizeof *wr, GFP_KERNEL); + wr = kmalloc_obj(*wr); if (!wr) return -ENOMEM; @@ -644,7 +644,7 @@ vm_fault_t orangefs_page_mkwrite(struct vm_fault *vmf) } } } - wr = kmalloc(sizeof *wr, GFP_KERNEL); + wr = kmalloc_obj(*wr); if (!wr) { ret = VM_FAULT_LOCKED|VM_FAULT_RETRY; goto out; diff --git a/fs/orangefs/orangefs-bufmap.c b/fs/orangefs/orangefs-bufmap.c index b562d3dbc76b..5dd2708cce94 100644 --- a/fs/orangefs/orangefs-bufmap.c +++ b/fs/orangefs/orangefs-bufmap.c @@ -205,7 +205,7 @@ orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) { struct orangefs_bufmap *bufmap; - bufmap = kzalloc(sizeof(*bufmap), GFP_KERNEL); + bufmap = kzalloc_obj(*bufmap); if (!bufmap) goto out; @@ -219,8 +219,7 @@ orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) goto out_free_bufmap; bufmap->desc_array = - kcalloc(bufmap->desc_count, sizeof(struct orangefs_bufmap_desc), - GFP_KERNEL); + kzalloc_objs(struct orangefs_bufmap_desc, bufmap->desc_count); if (!bufmap->desc_array) goto out_free_index_array; @@ -228,7 +227,7 @@ orangefs_bufmap_alloc(struct ORANGEFS_dev_map_desc *user_desc) /* allocate storage to track our page mappings */ bufmap->page_array = - kcalloc(bufmap->page_count, sizeof(struct page *), GFP_KERNEL); + kzalloc_objs(struct page *, bufmap->page_count); if (!bufmap->page_array) goto out_free_desc_array; diff --git a/fs/orangefs/orangefs-debugfs.c b/fs/orangefs/orangefs-debugfs.c index 002092950605..e82b934ed074 100644 --- a/fs/orangefs/orangefs-debugfs.c +++ b/fs/orangefs/orangefs-debugfs.c @@ -560,7 +560,7 @@ static int orangefs_prepare_cdm_array(char *debug_array_string) goto out; } - cdm_array = kcalloc(cdm_element_count, sizeof(*cdm_array), GFP_KERNEL); + cdm_array = kzalloc_objs(*cdm_array, cdm_element_count); if (!cdm_array) { rc = -ENOMEM; goto out; diff --git a/fs/orangefs/orangefs-mod.c b/fs/orangefs/orangefs-mod.c index 7ac16a4d2dc6..f591f09531da 100644 --- a/fs/orangefs/orangefs-mod.c +++ b/fs/orangefs/orangefs-mod.c @@ -99,7 +99,7 @@ static int __init orangefs_init(void) goto cleanup_op; orangefs_htable_ops_in_progress = - kcalloc(hash_table_size, sizeof(struct list_head), GFP_KERNEL); + kzalloc_objs(struct list_head, hash_table_size); if (!orangefs_htable_ops_in_progress) { ret = -ENOMEM; goto cleanup_inode; diff --git a/fs/orangefs/orangefs-sysfs.c b/fs/orangefs/orangefs-sysfs.c index 369455b354ef..a02bfc7b3542 100644 --- a/fs/orangefs/orangefs-sysfs.c +++ b/fs/orangefs/orangefs-sysfs.c @@ -1170,7 +1170,7 @@ int orangefs_sysfs_init(void) gossip_debug(GOSSIP_SYSFS_DEBUG, "orangefs_sysfs_init: start\n"); /* create /sys/fs/orangefs. */ - orangefs_obj = kzalloc(sizeof(*orangefs_obj), GFP_KERNEL); + orangefs_obj = kzalloc_obj(*orangefs_obj); if (!orangefs_obj) goto out; @@ -1185,7 +1185,7 @@ int orangefs_sysfs_init(void) kobject_uevent(orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/acache. */ - acache_orangefs_obj = kzalloc(sizeof(*acache_orangefs_obj), GFP_KERNEL); + acache_orangefs_obj = kzalloc_obj(*acache_orangefs_obj); if (!acache_orangefs_obj) { rc = -EINVAL; goto ofs_obj_bail; @@ -1202,8 +1202,7 @@ int orangefs_sysfs_init(void) kobject_uevent(acache_orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/capcache. */ - capcache_orangefs_obj = - kzalloc(sizeof(*capcache_orangefs_obj), GFP_KERNEL); + capcache_orangefs_obj = kzalloc_obj(*capcache_orangefs_obj); if (!capcache_orangefs_obj) { rc = -EINVAL; goto acache_obj_bail; @@ -1219,8 +1218,7 @@ int orangefs_sysfs_init(void) kobject_uevent(capcache_orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/ccache. */ - ccache_orangefs_obj = - kzalloc(sizeof(*ccache_orangefs_obj), GFP_KERNEL); + ccache_orangefs_obj = kzalloc_obj(*ccache_orangefs_obj); if (!ccache_orangefs_obj) { rc = -EINVAL; goto capcache_obj_bail; @@ -1236,7 +1234,7 @@ int orangefs_sysfs_init(void) kobject_uevent(ccache_orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/ncache. */ - ncache_orangefs_obj = kzalloc(sizeof(*ncache_orangefs_obj), GFP_KERNEL); + ncache_orangefs_obj = kzalloc_obj(*ncache_orangefs_obj); if (!ncache_orangefs_obj) { rc = -EINVAL; goto ccache_obj_bail; @@ -1253,7 +1251,7 @@ int orangefs_sysfs_init(void) kobject_uevent(ncache_orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/perf_counters. */ - pc_orangefs_obj = kzalloc(sizeof(*pc_orangefs_obj), GFP_KERNEL); + pc_orangefs_obj = kzalloc_obj(*pc_orangefs_obj); if (!pc_orangefs_obj) { rc = -EINVAL; goto ncache_obj_bail; @@ -1270,7 +1268,7 @@ int orangefs_sysfs_init(void) kobject_uevent(pc_orangefs_obj, KOBJ_ADD); /* create /sys/fs/orangefs/stats. */ - stats_orangefs_obj = kzalloc(sizeof(*stats_orangefs_obj), GFP_KERNEL); + stats_orangefs_obj = kzalloc_obj(*stats_orangefs_obj); if (!stats_orangefs_obj) { rc = -EINVAL; goto pc_obj_bail; diff --git a/fs/orangefs/super.c b/fs/orangefs/super.c index b46100a4f529..4ec7329b41f6 100644 --- a/fs/orangefs/super.c +++ b/fs/orangefs/super.c @@ -578,7 +578,7 @@ int orangefs_init_fs_context(struct fs_context *fc) { struct orangefs_sb_info_s *osi; - osi = kzalloc(sizeof(struct orangefs_sb_info_s), GFP_KERNEL); + osi = kzalloc_obj(struct orangefs_sb_info_s); if (!osi) return -ENOMEM; diff --git a/fs/orangefs/xattr.c b/fs/orangefs/xattr.c index a431aa07a229..1b372189cd10 100644 --- a/fs/orangefs/xattr.c +++ b/fs/orangefs/xattr.c @@ -171,7 +171,7 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, " does not exist!\n", get_khandle_from_ino(inode), (char *)new_op->upcall.req.getxattr.key); - cx = kmalloc(sizeof *cx, GFP_KERNEL); + cx = kmalloc_obj(*cx); if (cx) { strscpy(cx->key, name); cx->length = -1; @@ -225,7 +225,7 @@ ssize_t orangefs_inode_getxattr(struct inode *inode, const char *name, cx->length = length; cx->timeout = jiffies + HZ; } else { - cx = kmalloc(sizeof *cx, GFP_KERNEL); + cx = kmalloc_obj(*cx); if (cx) { strscpy(cx->key, name); memcpy(cx->val, buffer, length); diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 8269431ba3c6..97bed2286030 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -96,7 +96,7 @@ struct ovl_file { struct ovl_file *ovl_file_alloc(struct file *realfile) { - struct ovl_file *of = kzalloc(sizeof(struct ovl_file), GFP_KERNEL); + struct ovl_file *of = kzalloc_obj(struct ovl_file); if (unlikely(!of)) return NULL; diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index cda26bdef3b9..d8dd4b052984 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -159,6 +159,18 @@ static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *upperdentry, goto out; } +bool ovl_uuid_match(struct ovl_fs *ofs, const struct super_block *sb, + const uuid_t *uuid) +{ + /* + * Make sure that the stored uuid matches the uuid of the lower + * layer where file handle will be decoded. + * In case of uuid=off option just make sure that stored uuid is null. + */ + return ovl_origin_uuid(ofs) ? uuid_equal(uuid, &sb->s_uuid) : + uuid_is_null(uuid); +} + struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, struct vfsmount *mnt, bool connected) { @@ -168,14 +180,7 @@ struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, if (!capable(CAP_DAC_READ_SEARCH)) return NULL; - /* - * Make sure that the stored uuid matches the uuid of the lower - * layer where file handle will be decoded. - * In case of uuid=off option just make sure that stored uuid is null. - */ - if (ovl_origin_uuid(ofs) ? - !uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid) : - !uuid_is_null(&fh->fb.uuid)) + if (!ovl_uuid_match(ofs, mnt->mnt_sb, &fh->fb.uuid)) return NULL; bytes = (fh->fb.len - offsetof(struct ovl_fb, fid)); @@ -476,7 +481,7 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, goto invalid; if (!*stackp) - *stackp = kmalloc(sizeof(struct ovl_path), GFP_KERNEL); + *stackp = kmalloc_obj(struct ovl_path); if (!*stackp) { dput(origin); return -ENOMEM; diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 315882a360ce..cad2055ebf18 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -710,6 +710,8 @@ static inline int ovl_check_fh_len(struct ovl_fh *fh, int fh_len) return ovl_check_fb_len(&fh->fb, fh_len - OVL_FH_WIRE_OFFSET); } +bool ovl_uuid_match(struct ovl_fs *ofs, const struct super_block *sb, + const uuid_t *uuid); struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh, struct vfsmount *mnt, bool connected); int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected, diff --git a/fs/overlayfs/params.c b/fs/overlayfs/params.c index 63b7346c5ee1..8111b437ae5d 100644 --- a/fs/overlayfs/params.c +++ b/fs/overlayfs/params.c @@ -777,7 +777,7 @@ int ovl_init_fs_context(struct fs_context *fc) struct ovl_fs_context *ctx; struct ovl_fs *ofs; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL_ACCOUNT); + ctx = kzalloc_obj(*ctx, GFP_KERNEL_ACCOUNT); if (!ctx) return -ENOMEM; @@ -785,12 +785,12 @@ int ovl_init_fs_context(struct fs_context *fc) * By default we allocate for three lower layers. It's likely * that it'll cover most users. */ - ctx->lower = kmalloc_array(3, sizeof(*ctx->lower), GFP_KERNEL_ACCOUNT); + ctx->lower = kmalloc_objs(*ctx->lower, 3, GFP_KERNEL_ACCOUNT); if (!ctx->lower) goto out_err; ctx->capacity = 3; - ofs = kzalloc(sizeof(struct ovl_fs), GFP_KERNEL); + ofs = kzalloc_obj(struct ovl_fs); if (!ofs) goto out_err; diff --git a/fs/overlayfs/readdir.c b/fs/overlayfs/readdir.c index 7fd415d7471e..1dcc75b3a90f 100644 --- a/fs/overlayfs/readdir.c +++ b/fs/overlayfs/readdir.c @@ -77,7 +77,8 @@ static int ovl_casefold(struct ovl_readdir_data *rdd, const char *str, int len, char *cf_name; int cf_len; - if (!IS_ENABLED(CONFIG_UNICODE) || !rdd->map || is_dot_dotdot(str, len)) + if (!IS_ENABLED(CONFIG_UNICODE) || !rdd->map || + name_is_dot_dotdot(str, len)) return 0; cf_name = kmalloc(NAME_MAX, GFP_KERNEL); @@ -154,7 +155,7 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd, return true; /* Always recalc d_ino for parent */ - if (strcmp(p->name, "..") == 0) + if (name_is_dotdot(p->name, p->len)) return true; /* If this is lower, then native d_ino will do */ @@ -165,7 +166,7 @@ static bool ovl_calc_d_ino(struct ovl_readdir_data *rdd, * Recalc d_ino for '.' and for all entries if dir is impure (contains * copied up entries) */ - if ((p->name[0] == '.' && p->len == 1) || + if (name_is_dot(p->name, p->len) || ovl_test_flag(OVL_IMPURE, d_inode(rdd->dentry))) return true; @@ -179,7 +180,7 @@ static struct ovl_cache_entry *ovl_cache_entry_new(struct ovl_readdir_data *rdd, { struct ovl_cache_entry *p; - p = kmalloc(struct_size(p, name, len + 1), GFP_KERNEL); + p = kmalloc_flex(*p, name, len + 1); if (!p) return NULL; @@ -492,7 +493,7 @@ static struct ovl_dir_cache *ovl_cache_get(struct dentry *dentry) } ovl_set_dir_cache(d_inode(dentry), NULL); - cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); + cache = kzalloc_obj(struct ovl_dir_cache); if (!cache) return ERR_PTR(-ENOMEM); @@ -561,12 +562,12 @@ static int ovl_cache_update(const struct path *path, struct ovl_cache_entry *p, if (!ovl_same_dev(ofs) && !p->check_xwhiteout) goto out; - if (p->name[0] == '.') { + if (name_is_dot_dotdot(p->name, p->len)) { if (p->len == 1) { this = dget(dir); goto get; } - if (p->len == 2 && p->name[1] == '.') { + if (p->len == 2) { /* we shall not be moved */ this = dget(dir->d_parent); goto get; @@ -666,8 +667,7 @@ static int ovl_dir_read_impure(const struct path *path, struct list_head *list, return err; list_for_each_entry_safe(p, n, list, l_node) { - if (strcmp(p->name, ".") != 0 && - strcmp(p->name, "..") != 0) { + if (!name_is_dot_dotdot(p->name, p->len)) { err = ovl_cache_update(path, p, true); if (err) return err; @@ -706,7 +706,7 @@ static struct ovl_dir_cache *ovl_cache_get_impure(const struct path *path) ovl_dir_cache_free(inode); ovl_set_dir_cache(inode, NULL); - cache = kzalloc(sizeof(struct ovl_dir_cache), GFP_KERNEL); + cache = kzalloc_obj(struct ovl_dir_cache); if (!cache) return ERR_PTR(-ENOMEM); @@ -756,7 +756,7 @@ static bool ovl_fill_real(struct dir_context *ctx, const char *name, struct dir_context *orig_ctx = rdt->orig_ctx; bool res; - if (rdt->parent_ino && strcmp(name, "..") == 0) { + if (rdt->parent_ino && name_is_dotdot(name, namelen)) { ino = rdt->parent_ino; } else if (rdt->cache) { struct ovl_cache_entry *p; @@ -1098,12 +1098,8 @@ int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list) goto del_entry; } - if (p->name[0] == '.') { - if (p->len == 1) - goto del_entry; - if (p->len == 2 && p->name[1] == '.') - goto del_entry; - } + if (name_is_dot_dotdot(p->name, p->len)) + goto del_entry; err = -ENOTEMPTY; break; @@ -1147,7 +1143,7 @@ static bool ovl_check_d_type(struct dir_context *ctx, const char *name, container_of(ctx, struct ovl_readdir_data, ctx); /* Even if d_type is not supported, DT_DIR is returned for . and .. */ - if (!strncmp(name, ".", namelen) || !strncmp(name, "..", namelen)) + if (name_is_dot_dotdot(name, namelen)) return true; if (d_type != DT_UNKNOWN) @@ -1210,11 +1206,8 @@ static int ovl_workdir_cleanup_recurse(struct ovl_fs *ofs, const struct path *pa list_for_each_entry(p, &list, l_node) { struct dentry *dentry; - if (p->name[0] == '.') { - if (p->len == 1) - continue; - if (p->len == 2 && p->name[1] == '.') - continue; + if (name_is_dot_dotdot(p->name, p->len)) { + continue; } else if (incompat) { pr_err("overlay with incompat feature '%s' cannot be mounted\n", p->name); @@ -1279,12 +1272,8 @@ int ovl_indexdir_cleanup(struct ovl_fs *ofs) goto out; list_for_each_entry(p, &list, l_node) { - if (p->name[0] == '.') { - if (p->len == 1) - continue; - if (p->len == 2 && p->name[1] == '.') - continue; - } + if (name_is_dot_dotdot(p->name, p->len)) + continue; index = ovl_lookup_upper_unlocked(ofs, p->name, indexdir, p->len); if (IS_ERR(index)) { err = PTR_ERR(index); diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c index ba9146f22a2c..d4c12feec039 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -940,7 +940,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) * disable lower file handle decoding on all of them. */ if (ofs->fs[i].is_lower && - uuid_equal(&ofs->fs[i].sb->s_uuid, uuid)) { + ovl_uuid_match(ofs, ofs->fs[i].sb, uuid)) { ofs->fs[i].bad_uuid = true; return false; } @@ -952,6 +952,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid) static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) { struct super_block *sb = path->mnt->mnt_sb; + const uuid_t *uuid = ovl_origin_uuid(ofs) ? &sb->s_uuid : &uuid_null; unsigned int i; dev_t dev; int err; @@ -963,7 +964,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) return i; } - if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) { + if (!ovl_lower_uuid_ok(ofs, uuid)) { bad_uuid = true; if (ofs->config.xino == OVL_XINO_AUTO) { ofs->config.xino = OVL_XINO_OFF; @@ -975,9 +976,8 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path) warn = true; } if (warn) { - pr_warn("%s uuid detected in lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n", - uuid_is_null(&sb->s_uuid) ? "null" : - "conflicting", + pr_warn("%s uuid in non-single lower fs '%pd2', falling back to xino=%s,index=off,nfs_export=off.\n", + uuid_is_null(uuid) ? "null" : "conflicting", path->dentry, ovl_xino_mode(&ofs->config)); } } @@ -1031,7 +1031,7 @@ static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs, unsigned int i; size_t nr_merged_lower; - ofs->fs = kcalloc(ctx->nr + 2, sizeof(struct ovl_sb), GFP_KERNEL); + ofs->fs = kzalloc_objs(struct ovl_sb, ctx->nr + 2); if (ofs->fs == NULL) return -ENOMEM; @@ -1393,7 +1393,7 @@ static int ovl_fill_super_creds(struct fs_context *fc, struct super_block *sb) } err = -ENOMEM; - layers = kcalloc(ctx->nr + 1, sizeof(struct ovl_layer), GFP_KERNEL); + layers = kzalloc_objs(struct ovl_layer, ctx->nr + 1); if (!layers) return err; @@ -1469,10 +1469,7 @@ static int ovl_fill_super_creds(struct fs_context *fc, struct super_block *sb) if (!ovl_upper_mnt(ofs)) sb->s_flags |= SB_RDONLY; - if (!ovl_origin_uuid(ofs) && ofs->numfs > 1) { - pr_warn("The uuid=off requires a single fs for lower and upper, falling back to uuid=null.\n"); - ofs->config.uuid = OVL_UUID_NULL; - } else if (ovl_has_fsid(ofs) && ovl_upper_mnt(ofs)) { + if (ovl_has_fsid(ofs) && ovl_upper_mnt(ofs)) { /* Use per instance persistent uuid/fsid */ ovl_init_uuid_xattr(sb, ofs, &ctx->upper); } diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 94986d11a166..3f1b763a8bb4 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -113,7 +113,7 @@ bool ovl_verify_lower(struct super_block *sb) struct ovl_path *ovl_stack_alloc(unsigned int n) { - return kcalloc(n, sizeof(struct ovl_path), GFP_KERNEL); + return kzalloc_objs(struct ovl_path, n); } void ovl_stack_cpy(struct ovl_path *dst, struct ovl_path *src, unsigned int n) @@ -143,7 +143,7 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower) { struct ovl_entry *oe; - oe = kzalloc(struct_size(oe, __lowerstack, numlower), GFP_KERNEL); + oe = kzalloc_flex(*oe, __lowerstack, numlower); if (oe) oe->__numlower = numlower; diff --git a/fs/pidfs.c b/fs/pidfs.c index 1e20e36e0ed5..e3825ee246be 100644 --- a/fs/pidfs.c +++ b/fs/pidfs.c @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include "internal.h" #include "mount.h" @@ -55,9 +57,48 @@ struct pidfs_attr { __u32 coredump_signal; }; -static struct rb_root pidfs_ino_tree = RB_ROOT; +static struct rhashtable pidfs_ino_ht; + +static const struct rhashtable_params pidfs_ino_ht_params = { + .key_offset = offsetof(struct pid, ino), + .key_len = sizeof(u64), + .head_offset = offsetof(struct pid, pidfs_hash), + .automatic_shrinking = true, +}; + +/* + * inode number handling + * + * On 64 bit nothing special happens. The 64bit number assigned + * to struct pid is the inode number. + * + * On 32 bit the 64 bit number assigned to struct pid is split + * into two 32 bit numbers. The lower 32 bits are used as the + * inode number and the upper 32 bits are used as the inode + * generation number. + * + * On 32 bit pidfs_ino() will return the lower 32 bit. When + * pidfs_ino() returns zero a wrap around happened. When a + * wraparound happens the 64 bit number will be incremented by 1 + * so inode numbering starts at 1 again. + * + * On 64 bit comparing two pidfds is as simple as comparing + * inode numbers. + * + * When a wraparound happens on 32 bit multiple pidfds with the + * same inode number are likely to exist (This isn't a problem + * since before pidfs pidfds used the anonymous inode meaning + * all pidfds had the same inode number.). Userspace can + * reconstruct the 64 bit identifier by retrieving both the + * inode number and the inode generation number to compare or + * use file handles. + */ #if BITS_PER_LONG == 32 + +DEFINE_SPINLOCK(pidfs_ino_lock); +static u64 pidfs_ino_nr = 1; + static inline unsigned long pidfs_ino(u64 ino) { return lower_32_bits(ino); @@ -69,6 +110,18 @@ static inline u32 pidfs_gen(u64 ino) return upper_32_bits(ino); } +static inline u64 pidfs_alloc_ino(void) +{ + u64 ino; + + spin_lock(&pidfs_ino_lock); + if (pidfs_ino(pidfs_ino_nr) == 0) + pidfs_ino_nr++; + ino = pidfs_ino_nr++; + spin_unlock(&pidfs_ino_lock); + return ino; +} + #else /* On 64 bit simply return ino. */ @@ -82,69 +135,47 @@ static inline u32 pidfs_gen(u64 ino) { return 0; } -#endif -static int pidfs_ino_cmp(struct rb_node *a, const struct rb_node *b) +DEFINE_COOKIE(pidfs_ino_cookie); + +static u64 pidfs_alloc_ino(void) { - struct pid *pid_a = rb_entry(a, struct pid, pidfs_node); - struct pid *pid_b = rb_entry(b, struct pid, pidfs_node); - u64 pid_ino_a = pid_a->ino; - u64 pid_ino_b = pid_b->ino; + u64 ino; - if (pid_ino_a < pid_ino_b) - return -1; - if (pid_ino_a > pid_ino_b) - return 1; - return 0; + preempt_disable(); + ino = gen_cookie_next(&pidfs_ino_cookie); + preempt_enable(); + + VFS_WARN_ON_ONCE(ino < 1); + return ino; } -void pidfs_add_pid(struct pid *pid) +#endif + +void pidfs_prepare_pid(struct pid *pid) { - static u64 pidfs_ino_nr = 2; - - /* - * On 64 bit nothing special happens. The 64bit number assigned - * to struct pid is the inode number. - * - * On 32 bit the 64 bit number assigned to struct pid is split - * into two 32 bit numbers. The lower 32 bits are used as the - * inode number and the upper 32 bits are used as the inode - * generation number. - * - * On 32 bit pidfs_ino() will return the lower 32 bit. When - * pidfs_ino() returns zero a wrap around happened. When a - * wraparound happens the 64 bit number will be incremented by 2 - * so inode numbering starts at 2 again. - * - * On 64 bit comparing two pidfds is as simple as comparing - * inode numbers. - * - * When a wraparound happens on 32 bit multiple pidfds with the - * same inode number are likely to exist (This isn't a problem - * since before pidfs pidfds used the anonymous inode meaning - * all pidfds had the same inode number.). Userspace can - * reconstruct the 64 bit identifier by retrieving both the - * inode number and the inode generation number to compare or - * use file handles. - */ - if (pidfs_ino(pidfs_ino_nr) == 0) - pidfs_ino_nr += 2; - - pid->ino = pidfs_ino_nr; pid->stashed = NULL; pid->attr = NULL; - pidfs_ino_nr++; + pid->ino = 0; +} - write_seqcount_begin(&pidmap_lock_seq); - rb_find_add_rcu(&pid->pidfs_node, &pidfs_ino_tree, pidfs_ino_cmp); - write_seqcount_end(&pidmap_lock_seq); +int pidfs_add_pid(struct pid *pid) +{ + int ret; + + pid->ino = pidfs_alloc_ino(); + ret = rhashtable_insert_fast(&pidfs_ino_ht, &pid->pidfs_hash, + pidfs_ino_ht_params); + if (unlikely(ret)) + pid->ino = 0; + return ret; } void pidfs_remove_pid(struct pid *pid) { - write_seqcount_begin(&pidmap_lock_seq); - rb_erase(&pid->pidfs_node, &pidfs_ino_tree); - write_seqcount_end(&pidmap_lock_seq); + if (likely(pid->ino)) + rhashtable_remove_fast(&pidfs_ino_ht, &pid->pidfs_hash, + pidfs_ino_ht_params); } void pidfs_free_pid(struct pid *pid) @@ -329,7 +360,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) * namespace hierarchy. */ if (!pid_in_current_pidns(pid)) - return -ESRCH; + return -EREMOTE; attr = READ_ONCE(pid->attr); if (mask & PIDFD_INFO_EXIT) { @@ -415,7 +446,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) * the fields are set correctly, or return ESRCH to avoid providing * incomplete information. */ - kinfo.ppid = task_ppid_nr_ns(task, NULL); + kinfo.ppid = task_ppid_vnr(task); kinfo.tgid = task_tgid_vnr(task); kinfo.pid = task_pid_vnr(task); kinfo.mask |= PIDFD_INFO_PID; @@ -577,9 +608,8 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct user_namespace *user_ns; user_ns = task_cred_xxx(task, user_ns); - if (!ns_ref_get(user_ns)) - break; - ns_common = to_ns_common(user_ns); + if (ns_ref_get(user_ns)) + ns_common = to_ns_common(user_ns); } #endif break; @@ -589,9 +619,8 @@ static long pidfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct pid_namespace *pid_ns; pid_ns = task_active_pid_ns(task); - if (!ns_ref_get(pid_ns)) - break; - ns_common = to_ns_common(pid_ns); + if (ns_ref_get(pid_ns)) + ns_common = to_ns_common(pid_ns); } #endif break; @@ -791,42 +820,24 @@ static int pidfs_encode_fh(struct inode *inode, u32 *fh, int *max_len, return FILEID_KERNFS; } -static int pidfs_ino_find(const void *key, const struct rb_node *node) -{ - const u64 pid_ino = *(u64 *)key; - const struct pid *pid = rb_entry(node, struct pid, pidfs_node); - - if (pid_ino < pid->ino) - return -1; - if (pid_ino > pid->ino) - return 1; - return 0; -} - /* Find a struct pid based on the inode number. */ static struct pid *pidfs_ino_get_pid(u64 ino) { struct pid *pid; - struct rb_node *node; - unsigned int seq; + struct pidfs_attr *attr; guard(rcu)(); - do { - seq = read_seqcount_begin(&pidmap_lock_seq); - node = rb_find_rcu(&ino, &pidfs_ino_tree, pidfs_ino_find); - if (node) - break; - } while (read_seqcount_retry(&pidmap_lock_seq, seq)); - - if (!node) + pid = rhashtable_lookup(&pidfs_ino_ht, &ino, pidfs_ino_ht_params); + if (!pid) + return NULL; + attr = READ_ONCE(pid->attr); + if (IS_ERR_OR_NULL(attr)) + return NULL; + if (test_bit(PIDFS_ATTR_BIT_EXIT, &attr->attr_mask)) return NULL; - - pid = rb_entry(node, struct pid, pidfs_node); - /* Within our pid namespace hierarchy? */ if (pid_vnr(pid) == 0) return NULL; - return get_pid(pid); } @@ -1104,6 +1115,9 @@ struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags) void __init pidfs_init(void) { + if (rhashtable_init(&pidfs_ino_ht, &pidfs_ino_ht_params)) + panic("Failed to initialize pidfs hashtable"); + pidfs_attr_cachep = kmem_cache_create("pidfs_attr_cache", sizeof(struct pidfs_attr), 0, (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | SLAB_ACCOUNT | SLAB_PANIC), NULL); diff --git a/fs/pipe.c b/fs/pipe.c index 9e6a01475815..b44a756c0b41 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -797,7 +797,7 @@ struct pipe_inode_info *alloc_pipe_info(void) unsigned long user_bufs; unsigned int max_size = READ_ONCE(pipe_max_size); - pipe = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL_ACCOUNT); + pipe = kzalloc_obj(struct pipe_inode_info, GFP_KERNEL_ACCOUNT); if (pipe == NULL) goto out_free_uid; @@ -814,8 +814,8 @@ struct pipe_inode_info *alloc_pipe_info(void) if (too_many_pipe_buffers_hard(user_bufs) && pipe_is_unprivileged_user()) goto out_revert_acct; - pipe->bufs = kcalloc(pipe_bufs, sizeof(struct pipe_buffer), - GFP_KERNEL_ACCOUNT); + pipe->bufs = kzalloc_objs(struct pipe_buffer, pipe_bufs, + GFP_KERNEL_ACCOUNT); if (pipe->bufs) { init_waitqueue_head(&pipe->rd_wait); @@ -1297,8 +1297,7 @@ int pipe_resize_ring(struct pipe_inode_info *pipe, unsigned int nr_slots) if (unlikely(nr_slots > (pipe_index_t)-1u)) return -EINVAL; - bufs = kcalloc(nr_slots, sizeof(*bufs), - GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + bufs = kzalloc_objs(*bufs, nr_slots, GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (unlikely(!bufs)) return -ENOMEM; @@ -1481,10 +1480,24 @@ static struct file_system_type pipe_fs_type = { }; #ifdef CONFIG_SYSCTL -static SYSCTL_USER_TO_KERN_UINT_CONV(_pipe_maxsz, round_pipe_size) -static SYSCTL_UINT_CONV_CUSTOM(_pipe_maxsz, - sysctl_user_to_kern_uint_conv_pipe_maxsz, - sysctl_kern_to_user_uint_conv, true) + +static ulong round_pipe_size_ul(ulong size) +{ + return round_pipe_size(size); +} + +static int u2k_pipe_maxsz(const ulong *u_ptr, uint *k_ptr) +{ + return proc_uint_u2k_conv_uop(u_ptr, k_ptr, round_pipe_size_ul); +} + +static int do_proc_uint_conv_pipe_maxsz(ulong *u_ptr, uint *k_ptr, + int dir, const struct ctl_table *table) +{ + return proc_uint_conv(u_ptr, k_ptr, dir, table, true, + u2k_pipe_maxsz, + proc_uint_k2u_conv); +} static int proc_dopipe_max_size(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos) diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4ef6f9d2b8d6..12591c95c925 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -204,7 +204,7 @@ posix_acl_alloc(unsigned int count, gfp_t flags) { struct posix_acl *acl; - acl = kmalloc(struct_size(acl, a_entries, count), flags); + acl = kmalloc_flex(*acl, a_entries, count, flags); if (acl) posix_acl_init(acl, count); return acl; diff --git a/fs/proc/base.c b/fs/proc/base.c index 4eec684baca9..4c863d17dfb4 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2128,6 +2128,9 @@ bool proc_fill_cache(struct file *file, struct dir_context *ctx, ino_t ino = 1; child = try_lookup_noperm(&qname, dir); + if (IS_ERR(child)) + goto end_instantiate; + if (!child) { DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); child = d_alloc_parallel(dir, &qname, &wq); diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 728630b10fdf..390547b992ac 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -143,7 +143,7 @@ static int kcore_ram_list(struct list_head *head) { struct kcore_list *ent; - ent = kmalloc(sizeof(*ent), GFP_KERNEL); + ent = kmalloc_obj(*ent); if (!ent) return -ENOMEM; ent->addr = (unsigned long)__va(0); @@ -178,7 +178,7 @@ get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head) end = tmp->addr; } if (start < end) { - vmm = kmalloc(sizeof(*vmm), GFP_KERNEL); + vmm = kmalloc_obj(*vmm); if (!vmm) return 0; vmm->addr = start; @@ -210,7 +210,7 @@ kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg) p = pfn_to_page(pfn); - ent = kmalloc(sizeof(*ent), GFP_KERNEL); + ent = kmalloc_obj(*ent); if (!ent) return -ENOMEM; ent->addr = (unsigned long)page_to_virt(p); diff --git a/fs/proc/root.c b/fs/proc/root.c index d8ca41d823e4..0f9100559471 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -249,7 +249,7 @@ static int proc_fill_super(struct super_block *s, struct fs_context *fc) struct proc_fs_info *fs_info; int ret; - fs_info = kzalloc(sizeof(*fs_info), GFP_KERNEL); + fs_info = kzalloc_obj(*fs_info); if (!fs_info) return -ENOMEM; @@ -331,7 +331,7 @@ static int proc_init_fs_context(struct fs_context *fc) { struct proc_fs_context *ctx; - ctx = kzalloc(sizeof(struct proc_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct proc_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index d7d52e259055..e091931d7ca1 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -1534,7 +1534,7 @@ static int smaps_rollup_open(struct inode *inode, struct file *file) int ret; struct proc_maps_private *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL_ACCOUNT); + priv = kzalloc_obj(*priv, GFP_KERNEL_ACCOUNT); if (!priv) return -ENOMEM; @@ -2981,8 +2981,7 @@ static int pagemap_scan_init_bounce_buffer(struct pagemap_scan_private *p) p->vec_buf_len = min_t(size_t, PAGEMAP_WALK_SIZE >> PAGE_SHIFT, p->arg.vec_len); - p->vec_buf = kmalloc_array(p->vec_buf_len, sizeof(*p->vec_buf), - GFP_KERNEL); + p->vec_buf = kmalloc_objs(*p->vec_buf, p->vec_buf_len); if (!p->vec_buf) return -ENOMEM; diff --git a/fs/pstore/blk.c b/fs/pstore/blk.c index fa6b8cb788a1..12070b6a7b11 100644 --- a/fs/pstore/blk.c +++ b/fs/pstore/blk.c @@ -297,7 +297,7 @@ static int __init __best_effort_init(void) return -EINVAL; } - best_effort_dev = kzalloc(sizeof(*best_effort_dev), GFP_KERNEL); + best_effort_dev = kzalloc_obj(*best_effort_dev); if (!best_effort_dev) return -ENOMEM; diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c index 71deffcc3356..83fa0bb3435a 100644 --- a/fs/pstore/inode.c +++ b/fs/pstore/inode.c @@ -70,7 +70,7 @@ static void *pstore_ftrace_seq_start(struct seq_file *s, loff_t *pos) struct pstore_private *ps = s->private; struct pstore_ftrace_seq_data *data __free(kfree) = NULL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; @@ -365,7 +365,7 @@ int pstore_mkfile(struct dentry *root, struct pstore_record *record) record->psi->name, record->id, record->compressed ? ".enc.z" : ""); - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (!private) return -ENOMEM; @@ -477,7 +477,7 @@ static int pstore_init_fs_context(struct fs_context *fc) { struct pstore_context *ctx; - ctx = kzalloc(sizeof(struct pstore_context), GFP_KERNEL); + ctx = kzalloc_obj(struct pstore_context); if (!ctx) return -ENOMEM; diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index f8b9c9c73997..1d76c9d92056 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -683,7 +683,7 @@ void pstore_get_backend_records(struct pstore_info *psi, struct pstore_record *record; int rc; - record = kzalloc(sizeof(*record), GFP_KERNEL); + record = kzalloc_obj(*record); if (!record) { pr_err("out of memory creating record\n"); break; diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c index 39936d6da0dd..d1f895e57a95 100644 --- a/fs/pstore/ram.c +++ b/fs/pstore/ram.c @@ -232,8 +232,7 @@ static ssize_t ramoops_pstore_read(struct pstore_record *record) */ struct persistent_ram_zone *tmp_prz, *prz_next; - tmp_prz = kzalloc(sizeof(struct persistent_ram_zone), - GFP_KERNEL); + tmp_prz = kzalloc_obj(struct persistent_ram_zone); if (!tmp_prz) return -ENOMEM; prz = tmp_prz; @@ -539,7 +538,7 @@ static int ramoops_init_przs(const char *name, goto fail; } - prz_ar = kcalloc(*cnt, sizeof(**przs), GFP_KERNEL); + prz_ar = kzalloc_objs(**przs, *cnt); if (!prz_ar) goto fail; diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 7b6d6378a3b8..ed97494abf60 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c @@ -229,9 +229,8 @@ static int persistent_ram_init_ecc(struct persistent_ram_zone *prz, } /* allocate workspace instead of using stack VLA */ - prz->ecc_info.par = kmalloc_array(prz->ecc_info.ecc_size, - sizeof(*prz->ecc_info.par), - GFP_KERNEL); + prz->ecc_info.par = kmalloc_objs(*prz->ecc_info.par, + prz->ecc_info.ecc_size); if (!prz->ecc_info.par) { pr_err("cannot allocate ECC parity workspace\n"); return -ENOMEM; @@ -439,7 +438,7 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size, return NULL; } - pages = kmalloc_array(page_count, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, page_count); if (!pages) { pr_err("%s: Failed to allocate array for %u pages\n", __func__, page_count); @@ -606,7 +605,7 @@ struct persistent_ram_zone *persistent_ram_new(phys_addr_t start, size_t size, struct persistent_ram_zone *prz; int ret = -ENOMEM; - prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); + prz = kzalloc_obj(struct persistent_ram_zone); if (!prz) { pr_err("failed to allocate persistent ram zone\n"); goto err; diff --git a/fs/pstore/zone.c b/fs/pstore/zone.c index eb61ba5bb964..a3b003f9a3a0 100644 --- a/fs/pstore/zone.c +++ b/fs/pstore/zone.c @@ -1166,7 +1166,7 @@ static struct pstore_zone *psz_init_zone(enum pstore_type_id type, return ERR_PTR(-ENOMEM); } - zone = kzalloc(sizeof(struct pstore_zone), GFP_KERNEL); + zone = kzalloc_obj(struct pstore_zone); if (!zone) return ERR_PTR(-ENOMEM); @@ -1218,7 +1218,7 @@ static struct pstore_zone **psz_init_zones(enum pstore_type_id type, return ERR_PTR(-EINVAL); } - zones = kcalloc(c, sizeof(*zones), GFP_KERNEL); + zones = kzalloc_objs(*zones, c); if (!zones) { pr_err("allocate for zones %s failed\n", name); return ERR_PTR(-ENOMEM); diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 31d78da203ea..8aeb63d397cf 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -197,7 +197,7 @@ static int qnx4_fill_super(struct super_block *s, struct fs_context *fc) struct qnx4_sb_info *qs; int silent = fc->sb_flags & SB_SILENT; - qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); + qs = kzalloc_obj(struct qnx4_sb_info); if (!qs) return -ENOMEM; s->s_fs_info = qs; diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 88d285005083..c4049bb8bd60 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c @@ -302,7 +302,7 @@ static int qnx6_fill_super(struct super_block *s, struct fs_context *fc) int bootblock_offset = QNX6_BOOTBLOCK_SIZE; int silent = fc->sb_flags & SB_SILENT; - qs = kzalloc(sizeof(struct qnx6_sb_info), GFP_KERNEL); + qs = kzalloc_obj(struct qnx6_sb_info); if (!qs) return -ENOMEM; s->s_fs_info = qs; @@ -645,7 +645,7 @@ static int qnx6_init_fs_context(struct fs_context *fc) { struct qnx6_context *ctx; - ctx = kzalloc(sizeof(struct qnx6_context), GFP_KERNEL); + ctx = kzalloc_obj(struct qnx6_context); if (!ctx) return -ENOMEM; fc->ops = &qnx6_context_ops; diff --git a/fs/qnx6/super_mmi.c b/fs/qnx6/super_mmi.c index d282c2c73404..b8afb6f388b2 100644 --- a/fs/qnx6/super_mmi.c +++ b/fs/qnx6/super_mmi.c @@ -100,7 +100,7 @@ struct qnx6_super_block *qnx6_mmi_fill_super(struct super_block *s, int silent) goto out; } - qsb = kmalloc(sizeof(*qsb), GFP_KERNEL); + qsb = kmalloc_obj(*qsb); if (!qsb) { pr_err("unable to allocate memory.\n"); goto out; diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 1fda93dcbc1b..a24fab5f9f80 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c @@ -121,7 +121,7 @@ static int v2_read_file_info(struct super_block *sb, int type) ret = -EIO; goto out; } - info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_KERNEL); + info->dqi_priv = kmalloc_obj(struct qtree_mem_dqinfo); if (!info->dqi_priv) { ret = -ENOMEM; goto out; diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 77b8ca2757e0..0f8e838ece07 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -264,7 +264,7 @@ static unsigned long ramfs_nommu_get_unmapped_area(struct file *file, */ static int ramfs_nommu_mmap_prepare(struct vm_area_desc *desc) { - if (!is_nommu_shared_mapping(desc->vm_flags)) + if (!is_nommu_shared_vma_flags(&desc->vma_flags)) return -ENOSYS; file_accessed(desc->file); diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index 505d10a0cb36..3987639ed132 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -298,7 +298,7 @@ int ramfs_init_fs_context(struct fs_context *fc) { struct ramfs_fs_info *fsi; - fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); + fsi = kzalloc_obj(*fsi); if (!fsi) return -ENOMEM; diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index 0cd5476a483a..49f3f6b846b2 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -923,7 +923,7 @@ int setup_rmid_lru_list(void) return 0; idx_limit = resctrl_arch_system_num_rmid_idx(); - rmid_ptrs = kcalloc(idx_limit, sizeof(struct rmid_entry), GFP_KERNEL); + rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit); if (!rmid_ptrs) return -ENOMEM; diff --git a/fs/resctrl/pseudo_lock.c b/fs/resctrl/pseudo_lock.c index 0bfc13c5b96d..fa3687d69ebd 100644 --- a/fs/resctrl/pseudo_lock.c +++ b/fs/resctrl/pseudo_lock.c @@ -154,7 +154,7 @@ static int pseudo_lock_cstates_constrain(struct pseudo_lock_region *plr) int ret; for_each_cpu(cpu, &plr->d->hdr.cpu_mask) { - pm_req = kzalloc(sizeof(*pm_req), GFP_KERNEL); + pm_req = kzalloc_obj(*pm_req); if (!pm_req) { rdt_last_cmd_puts("Failure to allocate memory for PM QoS\n"); ret = -ENOMEM; @@ -270,7 +270,7 @@ static int pseudo_lock_init(struct rdtgroup *rdtgrp) { struct pseudo_lock_region *plr; - plr = kzalloc(sizeof(*plr), GFP_KERNEL); + plr = kzalloc_obj(*plr); if (!plr) return -ENOMEM; @@ -1044,7 +1044,7 @@ static int pseudo_lock_dev_mmap_prepare(struct vm_area_desc *desc) * Ensure changes are carried directly to the memory being mapped, * do not allow copy-on-write mapping. */ - if (!(desc->vm_flags & VM_SHARED)) { + if (!vma_desc_test_flags(desc, VMA_SHARED_BIT)) { mutex_unlock(&rdtgroup_mutex); return -EINVAL; } diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index ba8d503551cd..5da305bd36c9 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -2686,7 +2686,7 @@ static int schemata_list_add(struct rdt_resource *r, enum resctrl_conf_type type const char *suffix = ""; int ret, cl; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; @@ -2966,7 +2966,7 @@ static int rdt_init_fs_context(struct fs_context *fc) { struct rdt_fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -3117,7 +3117,7 @@ static struct mon_data *mon_get_kn_priv(enum resctrl_res_level rid, int domid, return priv; } - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; @@ -3753,7 +3753,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn, } /* allocate the rdtgroup. */ - rdtgrp = kzalloc(sizeof(*rdtgrp), GFP_KERNEL); + rdtgrp = kzalloc_obj(*rdtgrp); if (!rdtgrp) { ret = -ENOSPC; rdt_last_cmd_puts("Kernel out of memory\n"); diff --git a/fs/romfs/mmap-nommu.c b/fs/romfs/mmap-nommu.c index 4b77c6dc4418..7c3a1a7fecee 100644 --- a/fs/romfs/mmap-nommu.c +++ b/fs/romfs/mmap-nommu.c @@ -63,7 +63,7 @@ static unsigned long romfs_get_unmapped_area(struct file *file, */ static int romfs_mmap_prepare(struct vm_area_desc *desc) { - return is_nommu_shared_mapping(desc->vm_flags) ? 0 : -ENOSYS; + return is_nommu_shared_vma_flags(&desc->vma_flags) ? 0 : -ENOSYS; } static unsigned romfs_mmap_capabilities(struct file *file) diff --git a/fs/select.c b/fs/select.c index 78a1508c84d3..e0244dbe4429 100644 --- a/fs/select.c +++ b/fs/select.c @@ -993,8 +993,7 @@ static int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, todo -= walk->len; len = min(todo, POLLFD_PER_PAGE); - walk = walk->next = kmalloc(struct_size(walk, entries, len), - GFP_KERNEL); + walk = walk->next = kmalloc_flex(*walk, entries, len); if (!walk) { err = -ENOMEM; goto out_fds; diff --git a/fs/seq_file.c b/fs/seq_file.c index 8894cbde8d3a..4745db2a34d1 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -573,7 +573,7 @@ static void single_stop(struct seq_file *p, void *v) int single_open(struct file *file, int (*show)(struct seq_file *, void *), void *data) { - struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL_ACCOUNT); + struct seq_operations *op = kmalloc_obj(*op, GFP_KERNEL_ACCOUNT); int res = -ENOMEM; if (op) { diff --git a/fs/signalfd.c b/fs/signalfd.c index d69eab584bc6..dff53745e352 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -264,7 +264,7 @@ static int do_signalfd4(int ufd, sigset_t *mask, int flags) int fd; struct signalfd_ctx *ctx __free(kfree) = NULL; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/smb/client/Makefile b/fs/smb/client/Makefile index 3abd357d6df6..26b6105f04d1 100644 --- a/fs/smb/client/Makefile +++ b/fs/smb/client/Makefile @@ -56,4 +56,6 @@ $(obj)/smb2maperror.o: $(obj)/smb2_mapping_table.c quiet_cmd_gen_smb2_mapping = GEN $@ cmd_gen_smb2_mapping = perl $(src)/gen_smb2_mapping $< $@ +obj-$(CONFIG_SMB_KUNIT_TESTS) += smb2maperror_test.o + clean-files += smb2_mapping_table.c diff --git a/fs/smb/client/cached_dir.c b/fs/smb/client/cached_dir.c index 2a6b8ce80be2..04bb95091f49 100644 --- a/fs/smb/client/cached_dir.c +++ b/fs/smb/client/cached_dir.c @@ -118,7 +118,7 @@ static const char *path_no_prefix(struct cifs_sb_info *cifs_sb, if (!*path) return path; - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && + if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH) && cifs_sb->prepath) { len = strlen(cifs_sb->prepath) + 1; if (unlikely(len > strlen(path))) @@ -556,7 +556,7 @@ void close_all_cached_dirs(struct cifs_sb_info *cifs_sb) continue; spin_lock(&cfids->cfid_list_lock); list_for_each_entry(cfid, &cfids->entries, entry) { - tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC); + tmp_list = kmalloc_obj(*tmp_list, GFP_ATOMIC); if (tmp_list == NULL) { /* * If the malloc() fails, we won't drop all @@ -698,7 +698,7 @@ static struct cached_fid *init_cached_dir(const char *path) { struct cached_fid *cfid; - cfid = kzalloc(sizeof(*cfid), GFP_ATOMIC); + cfid = kzalloc_obj(*cfid, GFP_ATOMIC); if (!cfid) return NULL; cfid->path = kstrdup(path, GFP_ATOMIC); @@ -813,7 +813,7 @@ struct cached_fids *init_cached_dirs(void) { struct cached_fids *cfids; - cfids = kzalloc(sizeof(*cfids), GFP_KERNEL); + cfids = kzalloc_obj(*cfids); if (!cfids) return NULL; spin_lock_init(&cfids->cfid_list_lock); diff --git a/fs/smb/client/cifs_fs_sb.h b/fs/smb/client/cifs_fs_sb.h index 5e8d163cb5f8..84e7e366b0ff 100644 --- a/fs/smb/client/cifs_fs_sb.h +++ b/fs/smb/client/cifs_fs_sb.h @@ -55,7 +55,7 @@ struct cifs_sb_info { struct nls_table *local_nls; struct smb3_fs_context *ctx; atomic_t active; - unsigned int mnt_cifs_flags; + atomic_t mnt_cifs_flags; struct delayed_work prune_tlinks; struct rcu_head rcu; diff --git a/fs/smb/client/cifs_ioctl.h b/fs/smb/client/cifs_ioctl.h index b51ce64fcccf..147496ac9f9f 100644 --- a/fs/smb/client/cifs_ioctl.h +++ b/fs/smb/client/cifs_ioctl.h @@ -122,11 +122,3 @@ struct smb3_notify_info { #define CIFS_GOING_FLAGS_DEFAULT 0x0 /* going down */ #define CIFS_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ #define CIFS_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ - -static inline bool cifs_forced_shutdown(struct cifs_sb_info *sbi) -{ - if (CIFS_MOUNT_SHUTDOWN & sbi->mnt_cifs_flags) - return true; - else - return false; -} diff --git a/fs/smb/client/cifs_swn.c b/fs/smb/client/cifs_swn.c index 68a1f87c446d..9753a432d099 100644 --- a/fs/smb/client/cifs_swn.c +++ b/fs/smb/client/cifs_swn.c @@ -315,7 +315,7 @@ static struct cifs_swn_reg *cifs_get_swn_reg(struct cifs_tcon *tcon) goto unlock; } - reg = kmalloc(sizeof(struct cifs_swn_reg), GFP_ATOMIC); + reg = kmalloc_obj(struct cifs_swn_reg, GFP_ATOMIC); if (reg == NULL) { ret = -ENOMEM; goto fail_unlock; diff --git a/fs/smb/client/cifs_unicode.c b/fs/smb/client/cifs_unicode.c index e7891b4406f2..e2edc207cef2 100644 --- a/fs/smb/client/cifs_unicode.c +++ b/fs/smb/client/cifs_unicode.c @@ -11,20 +11,6 @@ #include "cifsglob.h" #include "cifs_debug.h" -int cifs_remap(struct cifs_sb_info *cifs_sb) -{ - int map_type; - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR) - map_type = SFM_MAP_UNI_RSVD; - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) - map_type = SFU_MAP_UNI_RSVD; - else - map_type = NO_MAP_UNI_RSVD; - - return map_type; -} - /* Convert character using the SFU - "Services for Unix" remapping range */ static bool convert_sfu_char(const __u16 src_char, char *target) diff --git a/fs/smb/client/cifs_unicode.h b/fs/smb/client/cifs_unicode.h index 9249db3b78c3..3e9cd9acf0a9 100644 --- a/fs/smb/client/cifs_unicode.h +++ b/fs/smb/client/cifs_unicode.h @@ -22,6 +22,7 @@ #include #include #include "../../nls/nls_ucs2_utils.h" +#include "cifsglob.h" /* * Macs use an older "SFM" mapping of the symbols above. Fortunately it does @@ -65,10 +66,21 @@ char *cifs_strndup_from_utf16(const char *src, const int maxlen, const struct nls_table *codepage); int cifsConvertToUTF16(__le16 *target, const char *source, int srclen, const struct nls_table *cp, int map_chars); -int cifs_remap(struct cifs_sb_info *cifs_sb); __le16 *cifs_strndup_to_utf16(const char *src, const int maxlen, int *utf16_len, const struct nls_table *cp, int remap); wchar_t cifs_toupper(wchar_t in); +static inline int cifs_remap(const struct cifs_sb_info *cifs_sb) +{ + unsigned int sbflags = cifs_sb_flags(cifs_sb); + + if (sbflags & CIFS_MOUNT_MAP_SFM_CHR) + return SFM_MAP_UNI_RSVD; + if (sbflags & CIFS_MOUNT_MAP_SPECIAL_CHR) + return SFU_MAP_UNI_RSVD; + + return NO_MAP_UNI_RSVD; +} + #endif /* _CIFS_UNICODE_H */ diff --git a/fs/smb/client/cifsacl.c b/fs/smb/client/cifsacl.c index f03eda46f452..c920039d733c 100644 --- a/fs/smb/client/cifsacl.c +++ b/fs/smb/client/cifsacl.c @@ -356,7 +356,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct smb_sid *psid, psid->num_subauth, SID_MAX_SUB_AUTHORITIES); } - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) || + if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_UID_FROM_ACL) || (cifs_sb_master_tcon(cifs_sb)->posix_extensions)) { uint32_t unix_id; bool is_group; @@ -805,8 +805,7 @@ static void parse_dacl(struct smb_acl *pdacl, char *end_of_acl, offsetof(struct smb_sid, sub_auth) + sizeof(__le16))) return; - ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), - GFP_KERNEL); + ppace = kmalloc_objs(struct smb_ace *, num_aces); if (!ppace) return; @@ -1332,8 +1331,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, if (uid_valid(uid)) { /* chown */ uid_t id; - nowner_sid_ptr = kzalloc(sizeof(struct smb_sid), - GFP_KERNEL); + nowner_sid_ptr = kzalloc_obj(struct smb_sid); if (!nowner_sid_ptr) { rc = -ENOMEM; goto chown_chgrp_exit; @@ -1361,8 +1359,7 @@ static int build_sec_desc(struct smb_ntsd *pntsd, struct smb_ntsd *pnntsd, } if (gid_valid(gid)) { /* chgrp */ gid_t id; - ngroup_sid_ptr = kzalloc(sizeof(struct smb_sid), - GFP_KERNEL); + ngroup_sid_ptr = kzalloc_obj(struct smb_sid); if (!ngroup_sid_ptr) { rc = -ENOMEM; goto chown_chgrp_exit; @@ -1492,7 +1489,7 @@ struct smb_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, struct cifsFileInfo *open_file = NULL; if (inode) - open_file = find_readable_file(CIFS_I(inode), true); + open_file = find_readable_file(CIFS_I(inode), FIND_FSUID_ONLY); if (!open_file) return get_cifs_acl_by_path(cifs_sb, path, pacllen, info); @@ -1615,7 +1612,8 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, struct smb_acl *dacl_ptr = NULL; struct smb_ntsd *pntsd = NULL; /* acl obtained from server */ struct smb_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + unsigned int sbflags; struct tcon_link *tlink; struct smb_version_operations *ops; bool mode_from_sid, id_from_sid; @@ -1646,15 +1644,9 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 *pnmode, return rc; } - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) - mode_from_sid = true; - else - mode_from_sid = false; - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) - id_from_sid = true; - else - id_from_sid = false; + sbflags = cifs_sb_flags(cifs_sb); + mode_from_sid = sbflags & CIFS_MOUNT_MODE_FROM_SID; + id_from_sid = sbflags & CIFS_MOUNT_UID_FROM_ACL; /* Potentially, five new ACEs can be added to the ACL for U,G,O mapping */ if (pnmode && *pnmode != NO_CHANGE_64) { /* chmod */ diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c index 50b7ec39053c..3d731f3af235 100644 --- a/fs/smb/client/cifsencrypt.c +++ b/fs/smb/client/cifsencrypt.c @@ -500,7 +500,7 @@ calc_seckey(struct cifs_ses *ses) get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE); - ctx_arc4 = kmalloc(sizeof(*ctx_arc4), GFP_KERNEL); + ctx_arc4 = kmalloc_obj(*ctx_arc4); if (!ctx_arc4) { cifs_dbg(VFS, "Could not allocate arc4 context\n"); return -ENOMEM; diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c index afda1d7c1ee1..32d0305a1239 100644 --- a/fs/smb/client/cifsfs.c +++ b/fs/smb/client/cifsfs.c @@ -226,16 +226,18 @@ cifs_sb_deactive(struct super_block *sb) static int cifs_read_super(struct super_block *sb) { - struct inode *inode; struct cifs_sb_info *cifs_sb; struct cifs_tcon *tcon; + unsigned int sbflags; struct timespec64 ts; + struct inode *inode; int rc = 0; cifs_sb = CIFS_SB(sb); tcon = cifs_sb_master_tcon(cifs_sb); + sbflags = cifs_sb_flags(cifs_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL) + if (sbflags & CIFS_MOUNT_POSIXACL) sb->s_flags |= SB_POSIXACL; if (tcon->snapshot_time) @@ -311,7 +313,7 @@ cifs_read_super(struct super_block *sb) } #ifdef CONFIG_CIFS_NFSD_EXPORT - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + if (sbflags & CIFS_MOUNT_SERVER_INUM) { cifs_dbg(FYI, "export ops supported\n"); sb->s_export_op = &cifs_export_ops; } @@ -330,10 +332,14 @@ static void cifs_kill_sb(struct super_block *sb) /* * We need to release all dentries for the cached directories - * before we kill the sb. + * and close all deferred file handles before we kill the sb. */ if (cifs_sb->root) { close_all_cached_dirs(cifs_sb); + cifs_close_all_deferred_files_sb(cifs_sb); + + /* Wait for all pending oplock breaks to complete */ + flush_workqueue(cifsoplockd_wq); /* finally release root dentry */ dput(cifs_sb->root); @@ -389,8 +395,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) { - struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); - struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + struct cifs_tcon *tcon = cifs_sb_master_tcon(CIFS_SB(file)); struct TCP_Server_Info *server = tcon->ses->server; struct inode *inode = file_inode(file); int rc; @@ -418,11 +423,9 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len) static int cifs_permission(struct mnt_idmap *idmap, struct inode *inode, int mask) { - struct cifs_sb_info *cifs_sb; + unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode)); - cifs_sb = CIFS_SB(inode->i_sb); - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { + if (sbflags & CIFS_MOUNT_NO_PERM) { if ((mask & MAY_EXEC) && !execute_ok(inode)) return -EACCES; else @@ -568,15 +571,17 @@ cifs_show_security(struct seq_file *s, struct cifs_ses *ses) static void cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb) { + unsigned int sbflags = cifs_sb_flags(cifs_sb); + seq_puts(s, ",cache="); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) + if (sbflags & CIFS_MOUNT_STRICT_IO) seq_puts(s, "strict"); - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) + else if (sbflags & CIFS_MOUNT_DIRECT_IO) seq_puts(s, "none"); - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) + else if (sbflags & CIFS_MOUNT_RW_CACHE) seq_puts(s, "singleclient"); /* assume only one client access */ - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) + else if (sbflags & CIFS_MOUNT_RO_CACHE) seq_puts(s, "ro"); /* read only caching assumed */ else seq_puts(s, "loose"); @@ -637,6 +642,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct sockaddr *srcaddr; + unsigned int sbflags; + srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; seq_show_option(s, "vers", tcon->ses->server->vals->version_string); @@ -670,16 +677,17 @@ cifs_show_options(struct seq_file *s, struct dentry *root) (int)(srcaddr->sa_family)); } + sbflags = cifs_sb_flags(cifs_sb); seq_printf(s, ",uid=%u", from_kuid_munged(&init_user_ns, cifs_sb->ctx->linux_uid)); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) + if (sbflags & CIFS_MOUNT_OVERR_UID) seq_puts(s, ",forceuid"); else seq_puts(s, ",noforceuid"); seq_printf(s, ",gid=%u", from_kgid_munged(&init_user_ns, cifs_sb->ctx->linux_gid)); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) + if (sbflags & CIFS_MOUNT_OVERR_GID) seq_puts(s, ",forcegid"); else seq_puts(s, ",noforcegid"); @@ -722,53 +730,53 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_puts(s, ",unix"); else seq_puts(s, ",nounix"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) + if (sbflags & CIFS_MOUNT_NO_DFS) seq_puts(s, ",nodfs"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) + if (sbflags & CIFS_MOUNT_POSIX_PATHS) seq_puts(s, ",posixpaths"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) + if (sbflags & CIFS_MOUNT_SET_UID) seq_puts(s, ",setuids"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) + if (sbflags & CIFS_MOUNT_UID_FROM_ACL) seq_puts(s, ",idsfromsid"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + if (sbflags & CIFS_MOUNT_SERVER_INUM) seq_puts(s, ",serverino"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) + if (sbflags & CIFS_MOUNT_RWPIDFORWARD) seq_puts(s, ",rwpidforward"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) + if (sbflags & CIFS_MOUNT_NOPOSIXBRL) seq_puts(s, ",forcemand"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + if (sbflags & CIFS_MOUNT_NO_XATTR) seq_puts(s, ",nouser_xattr"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) + if (sbflags & CIFS_MOUNT_MAP_SPECIAL_CHR) seq_puts(s, ",mapchars"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR) + if (sbflags & CIFS_MOUNT_MAP_SFM_CHR) seq_puts(s, ",mapposix"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) + if (sbflags & CIFS_MOUNT_UNX_EMUL) seq_puts(s, ",sfu"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + if (sbflags & CIFS_MOUNT_NO_BRL) seq_puts(s, ",nobrl"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE) + if (sbflags & CIFS_MOUNT_NO_HANDLE_CACHE) seq_puts(s, ",nohandlecache"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) + if (sbflags & CIFS_MOUNT_MODE_FROM_SID) seq_puts(s, ",modefromsid"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) + if (sbflags & CIFS_MOUNT_CIFS_ACL) seq_puts(s, ",cifsacl"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) + if (sbflags & CIFS_MOUNT_DYNPERM) seq_puts(s, ",dynperm"); if (root->d_sb->s_flags & SB_POSIXACL) seq_puts(s, ",acl"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) + if (sbflags & CIFS_MOUNT_MF_SYMLINKS) seq_puts(s, ",mfsymlinks"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) + if (sbflags & CIFS_MOUNT_FSCACHE) seq_puts(s, ",fsc"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC) + if (sbflags & CIFS_MOUNT_NOSSYNC) seq_puts(s, ",nostrictsync"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) + if (sbflags & CIFS_MOUNT_NO_PERM) seq_puts(s, ",noperm"); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) + if (sbflags & CIFS_MOUNT_CIFS_BACKUPUID) seq_printf(s, ",backupuid=%u", from_kuid_munged(&init_user_ns, cifs_sb->ctx->backupuid)); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) + if (sbflags & CIFS_MOUNT_CIFS_BACKUPGID) seq_printf(s, ",backupgid=%u", from_kgid_munged(&init_user_ns, cifs_sb->ctx->backupgid)); @@ -864,7 +872,6 @@ static void cifs_umount_begin(struct super_block *sb) spin_unlock(&tcon->tc_lock); spin_unlock(&cifs_tcp_ses_lock); - cifs_close_all_deferred_files(tcon); /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */ /* cancel_notify_requests(tcon); */ if (tcon->ses && tcon->ses->server) { @@ -909,10 +916,10 @@ static int cifs_write_inode(struct inode *inode, struct writeback_control *wbc) static int cifs_drop_inode(struct inode *inode) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode)); /* no serverino => unconditional eviction */ - return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) || + return !(sbflags & CIFS_MOUNT_SERVER_INUM) || inode_generic_drop(inode); } @@ -950,7 +957,7 @@ cifs_get_root(struct smb3_fs_context *ctx, struct super_block *sb) char *s, *p; char sep; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH) return dget(sb->s_root); full_path = cifs_build_path_to_root(ctx, cifs_sb, @@ -1016,11 +1023,11 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, } else { cifs_info("Attempting to mount %s\n", old_ctx->source); } - cifs_sb = kzalloc(sizeof(*cifs_sb), GFP_KERNEL); + cifs_sb = kzalloc_obj(*cifs_sb); if (!cifs_sb) return ERR_PTR(-ENOMEM); - cifs_sb->ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL); + cifs_sb->ctx = kzalloc_obj(struct smb3_fs_context); if (!cifs_sb->ctx) { root = ERR_PTR(-ENOMEM); goto out; @@ -1262,7 +1269,7 @@ static int cifs_precopy_set_eof(struct inode *src_inode, struct cifsInodeInfo *s struct cifsFileInfo *writeable_srcfile; int rc = -EINVAL; - writeable_srcfile = find_writable_file(src_cifsi, FIND_WR_FSUID_ONLY); + writeable_srcfile = find_writable_file(src_cifsi, FIND_FSUID_ONLY); if (writeable_srcfile) { if (src_tcon->ses->server->ops->set_file_size) rc = src_tcon->ses->server->ops->set_file_size( diff --git a/fs/smb/client/cifsfs.h b/fs/smb/client/cifsfs.h index 121821e6c872..e320d39b01f5 100644 --- a/fs/smb/client/cifsfs.h +++ b/fs/smb/client/cifsfs.h @@ -147,6 +147,6 @@ extern const struct export_operations cifs_export_ops; #endif /* CONFIG_CIFS_NFSD_EXPORT */ /* when changing internal version - update following two lines at same time */ -#define SMB3_PRODUCT_BUILD 58 -#define CIFS_VERSION "2.58" +#define SMB3_PRODUCT_BUILD 59 +#define CIFS_VERSION "2.59" #endif /* _CIFSFS_H */ diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 7eb0131963dd..7877d327dbb0 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "cifs_fs_sb.h" #include "cifsacl.h" #include @@ -515,8 +516,10 @@ struct smb_version_operations { /* check for STATUS_NETWORK_SESSION_EXPIRED */ bool (*is_session_expired)(char *); /* send oplock break response */ - int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, __u64 volatile_fid, - __u16 net_fid, struct cifsInodeInfo *cifs_inode); + int (*oplock_response)(struct cifs_tcon *tcon, __u64 persistent_fid, + __u64 volatile_fid, __u16 net_fid, + struct cifsInodeInfo *cifs_inode, + unsigned int oplock); /* query remote filesystem */ int (*queryfs)(const unsigned int, struct cifs_tcon *, const char *, struct cifs_sb_info *, struct kstatfs *); @@ -1531,10 +1534,6 @@ int cifs_file_set_size(const unsigned int xid, struct dentry *dentry, #define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) #define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) -#define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) -#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->netfs.inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)) - /* * One of these for each file inode */ @@ -1582,24 +1581,59 @@ CIFS_I(struct inode *inode) return container_of(inode, struct cifsInodeInfo, netfs.inode); } -static inline struct cifs_sb_info * -CIFS_SB(struct super_block *sb) +static inline void *cinode_to_fsinfo(struct cifsInodeInfo *cinode) +{ + return cinode->netfs.inode.i_sb->s_fs_info; +} + +static inline void *super_to_fsinfo(struct super_block *sb) { return sb->s_fs_info; } -static inline struct cifs_sb_info * -CIFS_FILE_SB(struct file *file) +static inline void *inode_to_fsinfo(struct inode *inode) { - return CIFS_SB(file_inode(file)->i_sb); + return inode->i_sb->s_fs_info; +} + +static inline void *file_to_fsinfo(struct file *file) +{ + return file_inode(file)->i_sb->s_fs_info; +} + +static inline void *dentry_to_fsinfo(struct dentry *dentry) +{ + return dentry->d_sb->s_fs_info; +} + +static inline void *const_dentry_to_fsinfo(const struct dentry *dentry) +{ + return dentry->d_sb->s_fs_info; +} + +#define CIFS_SB(_ptr) \ + ((struct cifs_sb_info *) \ + _Generic((_ptr), \ + struct cifsInodeInfo * : cinode_to_fsinfo, \ + const struct dentry * : const_dentry_to_fsinfo, \ + struct super_block * : super_to_fsinfo, \ + struct dentry * : dentry_to_fsinfo, \ + struct inode * : inode_to_fsinfo, \ + struct file * : file_to_fsinfo)(_ptr)) + +/* + * Use atomic_t for @cifs_sb->mnt_cifs_flags as it is currently accessed + * locklessly and may be changed concurrently by mount/remount and reconnect + * paths. + */ +static inline unsigned int cifs_sb_flags(const struct cifs_sb_info *cifs_sb) +{ + return atomic_read(&cifs_sb->mnt_cifs_flags); } static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) - return '/'; - else - return '\\'; + return (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) ? '/' : '\\'; } static inline void @@ -1851,12 +1885,12 @@ static inline bool is_replayable_error(int error) } -/* cifs_get_writable_file() flags */ -enum cifs_writable_file_flags { - FIND_WR_ANY = 0U, - FIND_WR_FSUID_ONLY = (1U << 0), - FIND_WR_WITH_DELETE = (1U << 1), - FIND_WR_NO_PENDING_DELETE = (1U << 2), +enum cifs_find_flags { + FIND_ANY = 0U, + FIND_FSUID_ONLY = (1U << 0), + FIND_WITH_DELETE = (1U << 1), + FIND_NO_PENDING_DELETE = (1U << 2), + FIND_OPEN_FLAGS = (1U << 3), }; #define MID_FREE 0 @@ -2312,4 +2346,44 @@ static inline void cifs_requeue_server_reconn(struct TCP_Server_Info *server) queue_delayed_work(cifsiod_wq, &server->reconnect, delay * HZ); } +static inline bool __cifs_cache_state_check(struct cifsInodeInfo *cinode, + unsigned int oplock_flags, + unsigned int sb_flags) +{ + unsigned int sflags = cifs_sb_flags(CIFS_SB(cinode)); + unsigned int oplock = READ_ONCE(cinode->oplock); + + return (oplock & oplock_flags) || (sflags & sb_flags); +} + +#define CIFS_CACHE_READ(cinode) \ + __cifs_cache_state_check(cinode, CIFS_CACHE_READ_FLG, \ + CIFS_MOUNT_RO_CACHE) +#define CIFS_CACHE_HANDLE(cinode) \ + __cifs_cache_state_check(cinode, CIFS_CACHE_HANDLE_FLG, 0) +#define CIFS_CACHE_WRITE(cinode) \ + __cifs_cache_state_check(cinode, CIFS_CACHE_WRITE_FLG, \ + CIFS_MOUNT_RW_CACHE) + +static inline void cifs_reset_oplock(struct cifsInodeInfo *cinode) +{ + scoped_guard(spinlock, &cinode->open_file_lock) + WRITE_ONCE(cinode->oplock, 0); +} + +static inline bool cifs_forced_shutdown(const struct cifs_sb_info *sbi) +{ + return cifs_sb_flags(sbi) & CIFS_MOUNT_SHUTDOWN; +} + +static inline int cifs_open_create_options(unsigned int oflags, int opts) +{ + /* O_SYNC also has bit for O_DSYNC so following check picks up either */ + if (oflags & O_SYNC) + opts |= CREATE_WRITE_THROUGH; + if (oflags & O_DIRECT) + opts |= CREATE_NO_BUFFER; + return opts; +} + #endif /* _CIFS_GLOB_H */ diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h index 96d6b5325aa3..884bfa1cf0b4 100644 --- a/fs/smb/client/cifsproto.h +++ b/fs/smb/client/cifsproto.h @@ -138,12 +138,14 @@ void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result); struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, int flags); -int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, - struct cifsFileInfo **ret_file); +int __cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, + unsigned int find_flags, unsigned int open_flags, + struct cifsFileInfo **ret_file); int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, int flags, struct cifsFileInfo **ret_file); -struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, - bool fsuid_only); +struct cifsFileInfo *__find_readable_file(struct cifsInodeInfo *cifs_inode, + unsigned int find_flags, + unsigned int open_flags); int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, struct cifsFileInfo **ret_file); int cifs_get_hardlink_path(struct cifs_tcon *tcon, struct inode *inode, @@ -261,6 +263,7 @@ void cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode); void cifs_close_all_deferred_files(struct cifs_tcon *tcon); +void cifs_close_all_deferred_files_sb(struct cifs_sb_info *cifs_sb); void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, struct dentry *dentry); @@ -595,4 +598,20 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable, } } +static inline int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, + unsigned int find_flags, + struct cifsFileInfo **ret_file) +{ + find_flags &= ~FIND_OPEN_FLAGS; + return __cifs_get_writable_file(cifs_inode, find_flags, 0, ret_file); +} + +static inline struct cifsFileInfo * +find_readable_file(struct cifsInodeInfo *cinode, unsigned int find_flags) +{ + find_flags &= ~FIND_OPEN_FLAGS; + find_flags |= FIND_NO_PENDING_DELETE; + return __find_readable_file(cinode, find_flags, 0); +} + #endif /* _CIFSPROTO_H */ diff --git a/fs/smb/client/compress.c b/fs/smb/client/compress.c index e0c44b46080e..3d1e73f5d9af 100644 --- a/fs/smb/client/compress.c +++ b/fs/smb/client/compress.c @@ -229,7 +229,7 @@ static bool is_compressible(const struct iov_iter *data) if (has_repeated_data(sample, len)) goto out; - bkt = kcalloc(bkt_size, sizeof(*bkt), GFP_KERNEL); + bkt = kzalloc_objs(*bkt, bkt_size); if (!bkt) { WARN_ON_ONCE(1); ret = false; diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index 1b479561cbf9..3bad2c5c523d 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -1755,7 +1755,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx, if (tcp_ses) return tcp_ses; - tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); + tcp_ses = kzalloc_obj(struct TCP_Server_Info); if (!tcp_ses) { rc = -ENOMEM; goto out_err; @@ -2167,9 +2167,6 @@ void __cifs_put_smb_ses(struct cifs_ses *ses) #ifdef CONFIG_KEYS -/* strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1 */ -#define CIFSCREDS_DESC_SIZE (7 + CIFS_MAX_DOMAINNAME_LEN + 1) - /* Populate username and pw fields from keyring if possible */ static int cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) @@ -2177,6 +2174,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) int rc = 0; int is_domain = 0; const char *delim, *payload; + size_t desc_sz; char *desc; ssize_t len; struct key *key; @@ -2185,7 +2183,9 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) struct sockaddr_in6 *sa6; const struct user_key_payload *upayload; - desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL); + /* "cifs:a:" and "cifs:d:" are the same length; +1 for NUL terminator */ + desc_sz = strlen("cifs:a:") + CIFS_MAX_DOMAINNAME_LEN + 1; + desc = kmalloc(desc_sz, GFP_KERNEL); if (!desc) return -ENOMEM; @@ -2193,11 +2193,11 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) switch (server->dstaddr.ss_family) { case AF_INET: sa = (struct sockaddr_in *)&server->dstaddr; - sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr); + snprintf(desc, desc_sz, "cifs:a:%pI4", &sa->sin_addr.s_addr); break; case AF_INET6: sa6 = (struct sockaddr_in6 *)&server->dstaddr; - sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr); + snprintf(desc, desc_sz, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr); break; default: cifs_dbg(FYI, "Bad ss_family (%hu)\n", @@ -2216,7 +2216,7 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) } /* didn't work, try to find a domain key */ - sprintf(desc, "cifs:d:%s", ses->domainName); + snprintf(desc, desc_sz, "cifs:d:%s", ses->domainName); cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc); key = request_key(&key_type_logon, desc, ""); if (IS_ERR(key)) { @@ -2236,7 +2236,6 @@ cifs_set_cifscreds(struct smb3_fs_context *ctx, struct cifs_ses *ses) /* find first : in payload */ payload = upayload->data; delim = strnchr(payload, upayload->datalen, ':'); - cifs_dbg(FYI, "payload=%s\n", payload); if (!delim) { cifs_dbg(FYI, "Unable to find ':' in payload (datalen=%d)\n", upayload->datalen); @@ -2915,8 +2914,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data) { struct cifs_sb_info *old = CIFS_SB(sb); struct cifs_sb_info *new = mnt_data->cifs_sb; - unsigned int oldflags = old->mnt_cifs_flags & CIFS_MOUNT_MASK; - unsigned int newflags = new->mnt_cifs_flags & CIFS_MOUNT_MASK; + unsigned int oldflags = cifs_sb_flags(old) & CIFS_MOUNT_MASK; + unsigned int newflags = cifs_sb_flags(new) & CIFS_MOUNT_MASK; if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK)) return 0; @@ -2971,9 +2970,9 @@ static int match_prepath(struct super_block *sb, struct smb3_fs_context *ctx = mnt_data->ctx; struct cifs_sb_info *old = CIFS_SB(sb); struct cifs_sb_info *new = mnt_data->cifs_sb; - bool old_set = (old->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && + bool old_set = (cifs_sb_flags(old) & CIFS_MOUNT_USE_PREFIX_PATH) && old->prepath; - bool new_set = (new->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) && + bool new_set = (cifs_sb_flags(new) & CIFS_MOUNT_USE_PREFIX_PATH) && new->prepath; if (tcon->origin_fullpath && @@ -3004,7 +3003,7 @@ cifs_match_super(struct super_block *sb, void *data) cifs_sb = CIFS_SB(sb); /* We do not want to use a superblock that has been shutdown */ - if (CIFS_MOUNT_SHUTDOWN & cifs_sb->mnt_cifs_flags) { + if (cifs_forced_shutdown(cifs_sb)) { spin_unlock(&cifs_tcp_ses_lock); return 0; } @@ -3469,6 +3468,8 @@ ip_connect(struct TCP_Server_Info *server) int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb) { struct smb3_fs_context *ctx = cifs_sb->ctx; + unsigned int sbflags; + int rc = 0; INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); INIT_LIST_HEAD(&cifs_sb->tcon_sb_link); @@ -3493,17 +3494,16 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb) } ctx->local_nls = cifs_sb->local_nls; - smb3_update_mnt_flags(cifs_sb); + sbflags = smb3_update_mnt_flags(cifs_sb); if (ctx->direct_io) cifs_dbg(FYI, "mounting share using direct i/o\n"); if (ctx->cache_ro) { cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; + sbflags |= CIFS_MOUNT_RO_CACHE; } else if (ctx->cache_rw) { cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n"); - cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | - CIFS_MOUNT_RW_CACHE); + sbflags |= CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE; } if ((ctx->cifs_acl) && (ctx->dynperm)) @@ -3512,16 +3512,19 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb) if (ctx->prepath) { cifs_sb->prepath = kstrdup(ctx->prepath, GFP_KERNEL); if (cifs_sb->prepath == NULL) - return -ENOMEM; - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + rc = -ENOMEM; + else + sbflags |= CIFS_MOUNT_USE_PREFIX_PATH; } - return 0; + atomic_set(&cifs_sb->mnt_cifs_flags, sbflags); + return rc; } /* Release all succeed connections */ void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx) { + struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; int rc = 0; if (mnt_ctx->tcon) @@ -3533,7 +3536,7 @@ void cifs_mount_put_conns(struct cifs_mount_ctx *mnt_ctx) mnt_ctx->ses = NULL; mnt_ctx->tcon = NULL; mnt_ctx->server = NULL; - mnt_ctx->cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_POSIX_PATHS; + atomic_andnot(CIFS_MOUNT_POSIX_PATHS, &cifs_sb->mnt_cifs_flags); free_xid(mnt_ctx->xid); } @@ -3587,19 +3590,23 @@ int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx) int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) { struct TCP_Server_Info *server; + struct cifs_tcon *tcon = NULL; struct cifs_sb_info *cifs_sb; struct smb3_fs_context *ctx; - struct cifs_tcon *tcon = NULL; + unsigned int sbflags; int rc = 0; - if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx || - !mnt_ctx->cifs_sb)) { - rc = -EINVAL; - goto out; + if (WARN_ON_ONCE(!mnt_ctx)) + return -EINVAL; + if (WARN_ON_ONCE(!mnt_ctx->server || !mnt_ctx->ses || + !mnt_ctx->fs_ctx || !mnt_ctx->cifs_sb)) { + mnt_ctx->tcon = NULL; + return -EINVAL; } server = mnt_ctx->server; ctx = mnt_ctx->fs_ctx; cifs_sb = mnt_ctx->cifs_sb; + sbflags = cifs_sb_flags(cifs_sb); /* search for existing tcon to this server share */ tcon = cifs_get_tcon(mnt_ctx->ses, ctx); @@ -3614,9 +3621,9 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) * path (i.e., do not remap / and \ and do not map any special characters) */ if (tcon->posix_extensions) { - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; - cifs_sb->mnt_cifs_flags &= ~(CIFS_MOUNT_MAP_SFM_CHR | - CIFS_MOUNT_MAP_SPECIAL_CHR); + sbflags |= CIFS_MOUNT_POSIX_PATHS; + sbflags &= ~(CIFS_MOUNT_MAP_SFM_CHR | + CIFS_MOUNT_MAP_SPECIAL_CHR); } #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY @@ -3643,12 +3650,11 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) /* do not care if a following call succeed - informational */ if (!tcon->pipe && server->ops->qfs_tcon) { server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { + if (sbflags & CIFS_MOUNT_RO_CACHE) { if (tcon->fsDevInfo.DeviceCharacteristics & cpu_to_le32(FILE_READ_ONLY_DEVICE)) cifs_dbg(VFS, "mounted to read only share\n"); - else if ((cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_RW_CACHE) == 0) + else if (!(sbflags & CIFS_MOUNT_RW_CACHE)) cifs_dbg(VFS, "read only mount of RW share\n"); /* no need to log a RW mount of a typical RW share */ } @@ -3660,11 +3666,12 @@ int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) * Inside cifs_fscache_get_super_cookie it checks * that we do not get super cookie twice. */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) + if (sbflags & CIFS_MOUNT_FSCACHE) cifs_fscache_get_super_cookie(tcon); out: mnt_ctx->tcon = tcon; + atomic_set(&cifs_sb->mnt_cifs_flags, sbflags); return rc; } @@ -3674,7 +3681,7 @@ static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, struct tcon_link *tlink; /* hang the tcon off of the superblock */ - tlink = kzalloc(sizeof(*tlink), GFP_KERNEL); + tlink = kzalloc_obj(*tlink); if (tlink == NULL) return -ENOMEM; @@ -3783,7 +3790,8 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx) cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); if (rc != 0) { cifs_server_dbg(VFS, "cannot query dirs between root and final path, enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, + &cifs_sb->mnt_cifs_flags); rc = 0; } } @@ -3798,7 +3806,7 @@ mchan_mount_alloc(struct cifs_ses *ses) { struct mchan_mount *mchan_mount; - mchan_mount = kzalloc(sizeof(*mchan_mount), GFP_KERNEL); + mchan_mount = kzalloc_obj(*mchan_mount); if (!mchan_mount) return ERR_PTR(-ENOMEM); @@ -3863,7 +3871,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) * Force the use of prefix path to support failover on DFS paths that resolve to targets * that have different prefix paths. */ - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags); kfree(cifs_sb->prepath); cifs_sb->prepath = ctx->prepath; ctx->prepath = NULL; @@ -4193,7 +4201,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) struct smb3_fs_context *ctx; char *origin_fullpath = NULL; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (ctx == NULL) return ERR_PTR(-ENOMEM); @@ -4357,7 +4365,7 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) kuid_t fsuid = current_fsuid(); int err; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER)) return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); spin_lock(&cifs_sb->tlink_tree_lock); @@ -4367,7 +4375,7 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) spin_unlock(&cifs_sb->tlink_tree_lock); if (tlink == NULL) { - newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); + newtlink = kzalloc_obj(*tlink); if (newtlink == NULL) return ERR_PTR(-ENOMEM); newtlink->tl_uid = fsuid; diff --git a/fs/smb/client/dfs.h b/fs/smb/client/dfs.h index 6b5b5ca0f55c..16ac2cdd5c82 100644 --- a/fs/smb/client/dfs.h +++ b/fs/smb/client/dfs.h @@ -46,7 +46,7 @@ static inline struct dfs_ref_walk *ref_walk_alloc(void) { struct dfs_ref_walk *rw; - rw = kmalloc(sizeof(*rw), GFP_KERNEL); + rw = kmalloc_obj(*rw); if (!rw) return ERR_PTR(-ENOMEM); return rw; diff --git a/fs/smb/client/dfs_cache.c b/fs/smb/client/dfs_cache.c index f2ad0ccd08a7..83f8cf2f8d2b 100644 --- a/fs/smb/client/dfs_cache.c +++ b/fs/smb/client/dfs_cache.c @@ -363,7 +363,7 @@ static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed) { struct cache_dfs_tgt *t; - t = kmalloc(sizeof(*t), GFP_ATOMIC); + t = kmalloc_obj(*t, GFP_ATOMIC); if (!t) return ERR_PTR(-ENOMEM); t->name = kstrdup(name, GFP_ATOMIC); @@ -796,7 +796,7 @@ static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl) INIT_LIST_HEAD(head); list_for_each_entry(t, &ce->tlist, list) { - it = kzalloc(sizeof(*it), GFP_ATOMIC); + it = kzalloc_obj(*it, GFP_ATOMIC); if (!it) { rc = -ENOMEM; goto err_free_it; @@ -1333,7 +1333,7 @@ int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb) * Force the use of prefix path to support failover on DFS paths that resolve to targets * that have different prefix paths. */ - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags); refresh_tcon_referral(tcon, true); return 0; diff --git a/fs/smb/client/dir.c b/fs/smb/client/dir.c index cb10088197d2..6d2378eeb7f6 100644 --- a/fs/smb/client/dir.c +++ b/fs/smb/client/dir.c @@ -82,10 +82,11 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa const char *tree, int tree_len, bool prefix) { - int dfsplen; - int pplen = 0; - struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(direntry); + unsigned int sbflags = cifs_sb_flags(cifs_sb); char dirsep = CIFS_DIR_SEP(cifs_sb); + int pplen = 0; + int dfsplen; char *s; if (unlikely(!page)) @@ -96,7 +97,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa else dfsplen = 0; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + if (sbflags & CIFS_MOUNT_USE_PREFIX_PATH) pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0; s = dentry_path_raw(direntry, page, PATH_MAX); @@ -123,7 +124,7 @@ char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *pa if (dfsplen) { s -= dfsplen; memcpy(s, tree, dfsplen); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { + if (sbflags & CIFS_MOUNT_POSIX_PATHS) { int i; for (i = 0; i < dfsplen; i++) { if (s[i] == '\\') @@ -152,7 +153,7 @@ char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page static int check_name(struct dentry *direntry, struct cifs_tcon *tcon) { - struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(direntry); int i; if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength && @@ -160,7 +161,7 @@ check_name(struct dentry *direntry, struct cifs_tcon *tcon) le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength))) return -ENAMETOOLONG; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS)) { for (i = 0; i < direntry->d_name.len; i++) { if (direntry->d_name.name[i] == '\\') { cifs_dbg(FYI, "Invalid file name\n"); @@ -181,11 +182,12 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int rc = -ENOENT; int create_options = CREATE_NOT_DIR; int desired_access; - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct cifs_tcon *tcon = tlink_tcon(tlink); const char *full_path; void *page = alloc_dentry_path(); struct inode *newinode = NULL; + unsigned int sbflags = cifs_sb_flags(cifs_sb); int disposition; struct TCP_Server_Info *server = tcon->ses->server; struct cifs_open_parms oparms; @@ -306,6 +308,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned goto out; } + create_options |= cifs_open_create_options(oflags, create_options); /* * if we're not using unix extensions, see if we need to set * ATTR_READONLY on the create call @@ -374,7 +377,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned .device = 0, }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (sbflags & CIFS_MOUNT_SET_UID) { args.uid = current_fsuid(); if (inode->i_mode & S_ISGID) args.gid = inode->i_gid; @@ -411,9 +414,9 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned if (server->ops->set_lease_key) server->ops->set_lease_key(newinode, fid); if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) + if (sbflags & CIFS_MOUNT_DYNPERM) newinode->i_mode = mode; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (sbflags & CIFS_MOUNT_SET_UID) { newinode->i_uid = current_fsuid(); if (inode->i_mode & S_ISGID) newinode->i_gid = inode->i_gid; @@ -458,18 +461,20 @@ int cifs_atomic_open(struct inode *inode, struct dentry *direntry, struct file *file, unsigned int oflags, umode_t mode) { - int rc; - unsigned int xid; + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + struct cifs_open_info_data buf = {}; + struct TCP_Server_Info *server; + struct cifsFileInfo *file_info; + struct cifs_pending_open open; + struct cifs_fid fid = {}; struct tcon_link *tlink; struct cifs_tcon *tcon; - struct TCP_Server_Info *server; - struct cifs_fid fid = {}; - struct cifs_pending_open open; + unsigned int sbflags; + unsigned int xid; __u32 oplock; - struct cifsFileInfo *file_info; - struct cifs_open_info_data buf = {}; + int rc; - if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) + if (unlikely(cifs_forced_shutdown(cifs_sb))) return smb_EIO(smb_eio_trace_forced_shutdown); /* @@ -499,7 +504,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", inode, direntry, direntry); - tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb)); + tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto out_free_xid; @@ -536,13 +541,13 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, goto out; } - if (file->f_flags & O_DIRECT && - CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { - if (CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + sbflags = cifs_sb_flags(cifs_sb); + if ((file->f_flags & O_DIRECT) && (sbflags & CIFS_MOUNT_STRICT_IO)) { + if (sbflags & CIFS_MOUNT_NO_BRL) file->f_op = &cifs_file_direct_nobrl_ops; else file->f_op = &cifs_file_direct_ops; - } + } file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target); if (file_info == NULL) { diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index 51360d64b7b2..27f61fe7e4e2 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -255,7 +255,7 @@ static void cifs_begin_writeback(struct netfs_io_request *wreq) struct cifs_io_request *req = container_of(wreq, struct cifs_io_request, rreq); int ret; - ret = cifs_get_writable_file(CIFS_I(wreq->inode), FIND_WR_ANY, &req->cfile); + ret = cifs_get_writable_file(CIFS_I(wreq->inode), FIND_ANY, &req->cfile); if (ret) { cifs_dbg(VFS, "No writable handle in writepages ret=%d\n", ret); return; @@ -270,7 +270,7 @@ static void cifs_begin_writeback(struct netfs_io_request *wreq) static int cifs_init_request(struct netfs_io_request *rreq, struct file *file) { struct cifs_io_request *req = container_of(rreq, struct cifs_io_request, rreq); - struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode); struct cifsFileInfo *open_file = NULL; rreq->rsize = cifs_sb->ctx->rsize; @@ -281,7 +281,7 @@ static int cifs_init_request(struct netfs_io_request *rreq, struct file *file) open_file = file->private_data; rreq->netfs_priv = file->private_data; req->cfile = cifsFileInfo_get(open_file); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RWPIDFORWARD) req->pid = req->cfile->pid; } else if (rreq->origin != NETFS_WRITEBACK) { WARN_ON_ONCE(1); @@ -489,7 +489,7 @@ int cifs_posix_open(const char *full_path, struct inode **pinode, cifs_dbg(FYI, "posix open %s\n", full_path); - presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); + presp_data = kzalloc_obj(FILE_UNIX_BASIC_INFO); if (presp_data == NULL) return -ENOMEM; @@ -584,15 +584,8 @@ static int cifs_nt_open(const char *full_path, struct inode *inode, struct cifs_ *********************************************************************/ disposition = cifs_get_disposition(f_flags); - /* BB pass O_SYNC flag through on file attributes .. BB */ - - /* O_SYNC also has bit for O_DSYNC so following check picks up either */ - if (f_flags & O_SYNC) - create_options |= CREATE_WRITE_THROUGH; - - if (f_flags & O_DIRECT) - create_options |= CREATE_NO_BUFFER; + create_options |= cifs_open_create_options(f_flags, create_options); retry_open: oparms = (struct cifs_open_parms) { @@ -673,11 +666,11 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, struct cifs_tcon *tcon = tlink_tcon(tlink); struct TCP_Server_Info *server = tcon->ses->server; - cfile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); + cfile = kzalloc_obj(struct cifsFileInfo); if (cfile == NULL) return cfile; - fdlocks = kzalloc(sizeof(struct cifs_fid_locks), GFP_KERNEL); + fdlocks = kzalloc_obj(struct cifs_fid_locks); if (!fdlocks) { kfree(cfile); return NULL; @@ -711,8 +704,6 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, mutex_init(&cfile->fh_mutex); spin_lock_init(&cfile->file_info_lock); - cifs_sb_active(inode->i_sb); - /* * If the server returned a read oplock and we have mandatory brlocks, * set oplock level to None. @@ -731,14 +722,14 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file, oplock = fid->pending_open->oplock; list_del(&fid->pending_open->olist); - fid->purge_cache = false; - server->ops->set_fid(cfile, fid, oplock); - list_add(&cfile->tlist, &tcon->openFileList); atomic_inc(&tcon->num_local_opens); /* if readable file instance put first in list*/ spin_lock(&cinode->open_file_lock); + fid->purge_cache = false; + server->ops->set_fid(cfile, fid, oplock); + if (file->f_mode & FMODE_READ) list_add(&cfile->flist, &cinode->openFileList); else @@ -767,7 +758,6 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file) struct inode *inode = d_inode(cifs_file->dentry); struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifsLockInfo *li, *tmp; - struct super_block *sb = inode->i_sb; /* * Delete any outstanding lock records. We'll lose them when the file @@ -785,7 +775,6 @@ static void cifsFileInfo_put_final(struct cifsFileInfo *cifs_file) cifs_put_tlink(cifs_file->tlink); dput(cifs_file->dentry); - cifs_sb_deactive(sb); kfree(cifs_file->symlink_target); kfree(cifs_file); } @@ -906,7 +895,7 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, * close because it may cause a error when we open this file * again and get at least level II oplock. */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_STRICT_IO) set_bit(CIFS_INO_INVALID_MAPPING, &cifsi->flags); cifs_set_oplock_level(cifsi, 0); } @@ -955,11 +944,11 @@ void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, int cifs_file_flush(const unsigned int xid, struct inode *inode, struct cifsFileInfo *cfile) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct cifs_tcon *tcon; int rc; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOSSYNC) return 0; if (cfile && (OPEN_FMODE(cfile->f_flags) & FMODE_WRITE)) { @@ -967,7 +956,7 @@ int cifs_file_flush(const unsigned int xid, struct inode *inode, return tcon->ses->server->ops->flush(xid, tcon, &cfile->fid); } - rc = cifs_get_writable_file(CIFS_I(inode), FIND_WR_ANY, &cfile); + rc = cifs_get_writable_file(CIFS_I(inode), FIND_ANY, &cfile); if (!rc) { tcon = tlink_tcon(cfile->tlink); rc = tcon->ses->server->ops->flush(xid, tcon, &cfile->fid); @@ -992,7 +981,7 @@ static int cifs_do_truncate(const unsigned int xid, struct dentry *dentry) return -ERESTARTSYS; mapping_set_error(inode->i_mapping, rc); - cfile = find_writable_file(cinode, FIND_WR_FSUID_ONLY); + cfile = find_writable_file(cinode, FIND_FSUID_ONLY); rc = cifs_file_flush(xid, inode, cfile); if (!rc) { if (cfile) { @@ -1015,24 +1004,24 @@ static int cifs_do_truncate(const unsigned int xid, struct dentry *dentry) int cifs_open(struct inode *inode, struct file *file) { + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + struct cifs_open_info_data data = {}; + struct cifsFileInfo *cfile = NULL; + struct TCP_Server_Info *server; + struct cifs_pending_open open; + bool posix_open_ok = false; + struct cifs_fid fid = {}; + struct tcon_link *tlink; + struct cifs_tcon *tcon; + const char *full_path; + unsigned int sbflags; int rc = -EACCES; unsigned int xid; __u32 oplock; - struct cifs_sb_info *cifs_sb; - struct TCP_Server_Info *server; - struct cifs_tcon *tcon; - struct tcon_link *tlink; - struct cifsFileInfo *cfile = NULL; void *page; - const char *full_path; - bool posix_open_ok = false; - struct cifs_fid fid = {}; - struct cifs_pending_open open; - struct cifs_open_info_data data = {}; xid = get_xid(); - cifs_sb = CIFS_SB(inode->i_sb); if (unlikely(cifs_forced_shutdown(cifs_sb))) { free_xid(xid); return smb_EIO(smb_eio_trace_forced_shutdown); @@ -1056,9 +1045,9 @@ int cifs_open(struct inode *inode, struct file *file) cifs_dbg(FYI, "inode = 0x%p file flags are 0x%x for %s\n", inode, file->f_flags, full_path); - if (file->f_flags & O_DIRECT && - cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + sbflags = cifs_sb_flags(cifs_sb); + if ((file->f_flags & O_DIRECT) && (sbflags & CIFS_MOUNT_STRICT_IO)) { + if (sbflags & CIFS_MOUNT_NO_BRL) file->f_op = &cifs_file_direct_nobrl_ops; else file->f_op = &cifs_file_direct_ops; @@ -1072,32 +1061,29 @@ int cifs_open(struct inode *inode, struct file *file) /* Get the cached handle as SMB2 close is deferred */ if (OPEN_FMODE(file->f_flags) & FMODE_WRITE) { - rc = cifs_get_writable_path(tcon, full_path, - FIND_WR_FSUID_ONLY | - FIND_WR_NO_PENDING_DELETE, - &cfile); + rc = __cifs_get_writable_file(CIFS_I(inode), + FIND_FSUID_ONLY | + FIND_NO_PENDING_DELETE | + FIND_OPEN_FLAGS, + file->f_flags, &cfile); } else { - rc = cifs_get_readable_path(tcon, full_path, &cfile); + cfile = __find_readable_file(CIFS_I(inode), + FIND_NO_PENDING_DELETE | + FIND_OPEN_FLAGS, + file->f_flags); + rc = cfile ? 0 : -ENOENT; } if (rc == 0) { - unsigned int oflags = file->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC); - unsigned int cflags = cfile->f_flags & ~(O_CREAT|O_EXCL|O_TRUNC); - - if (cifs_convert_flags(oflags, 0) == cifs_convert_flags(cflags, 0) && - (oflags & (O_SYNC|O_DIRECT)) == (cflags & (O_SYNC|O_DIRECT))) { - file->private_data = cfile; - spin_lock(&CIFS_I(inode)->deferred_lock); - cifs_del_deferred_close(cfile); - spin_unlock(&CIFS_I(inode)->deferred_lock); - goto use_cache; - } - _cifsFileInfo_put(cfile, true, false); - } else { - /* hard link on the defeered close file */ - rc = cifs_get_hardlink_path(tcon, inode, file); - if (rc) - cifs_close_deferred_file(CIFS_I(inode)); + file->private_data = cfile; + spin_lock(&CIFS_I(inode)->deferred_lock); + cifs_del_deferred_close(cfile); + spin_unlock(&CIFS_I(inode)->deferred_lock); + goto use_cache; } + /* hard link on the deferred close file */ + rc = cifs_get_hardlink_path(tcon, inode, file); + if (rc) + cifs_close_deferred_file(CIFS_I(inode)); if (server->oplocks) oplock = REQ_OPLOCK; @@ -1209,7 +1195,7 @@ cifs_relock_file(struct cifsFileInfo *cfile) struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); int rc = 0; #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY - struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(cinode); #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ down_read_nested(&cinode->lock_sem, SINGLE_DEPTH_NESTING); @@ -1222,7 +1208,7 @@ cifs_relock_file(struct cifsFileInfo *cfile) #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) + ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) rc = cifs_push_posix_locks(cfile); else #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ @@ -1318,13 +1304,8 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) rdwr_for_fscache = 1; desired_access = cifs_convert_flags(cfile->f_flags, rdwr_for_fscache); - - /* O_SYNC also has bit for O_DSYNC so following check picks up either */ - if (cfile->f_flags & O_SYNC) - create_options |= CREATE_WRITE_THROUGH; - - if (cfile->f_flags & O_DIRECT) - create_options |= CREATE_NO_BUFFER; + create_options |= cifs_open_create_options(cfile->f_flags, + create_options); if (server->ops->get_lease_key) server->ops->get_lease_key(inode, &cfile->fid); @@ -1410,7 +1391,8 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) oplock = 0; } - server->ops->set_fid(cfile, &cfile->fid, oplock); + scoped_guard(spinlock, &cinode->open_file_lock) + server->ops->set_fid(cfile, &cfile->fid, oplock); if (oparms.reconnect) cifs_relock_file(cfile); @@ -1437,11 +1419,11 @@ smb2_can_defer_close(struct inode *inode, struct cifs_deferred_close *dclose) { struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsInodeInfo *cinode = CIFS_I(inode); + unsigned int oplock = READ_ONCE(cinode->oplock); - return (cifs_sb->ctx->closetimeo && cinode->lease_granted && dclose && - (cinode->oplock == CIFS_CACHE_RHW_FLG || - cinode->oplock == CIFS_CACHE_RH_FLG) && - !test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags)); + return cifs_sb->ctx->closetimeo && cinode->lease_granted && dclose && + (oplock == CIFS_CACHE_RHW_FLG || oplock == CIFS_CACHE_RH_FLG) && + !test_bit(CIFS_INO_CLOSE_ON_LOCK, &cinode->flags); } @@ -1457,7 +1439,7 @@ int cifs_close(struct inode *inode, struct file *file) if (file->private_data != NULL) { cfile = file->private_data; file->private_data = NULL; - dclose = kmalloc(sizeof(struct cifs_deferred_close), GFP_KERNEL); + dclose = kmalloc_obj(struct cifs_deferred_close); if ((cfile->status_file_deleted == false) && (smb2_can_defer_close(inode, dclose))) { if (test_and_clear_bit(NETFS_ICTX_MODIFIED_ATTR, &cinode->netfs.flags)) { @@ -1581,7 +1563,7 @@ static struct cifsLockInfo * cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 flags) { struct cifsLockInfo *lock = - kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); + kmalloc_obj(struct cifsLockInfo); if (!lock) return lock; lock->offset = offset; @@ -1852,7 +1834,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) PAGE_SIZE); max_num = (max_buf - sizeof(struct smb_hdr)) / sizeof(LOCKING_ANDX_RANGE); - buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); + buf = kzalloc_objs(LOCKING_ANDX_RANGE, max_num); if (!buf) { free_xid(xid); return -ENOMEM; @@ -1944,7 +1926,7 @@ cifs_push_posix_locks(struct cifsFileInfo *cfile) * protects locking operations of this inode. */ for (i = 0; i < count; i++) { - lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL); + lck = kmalloc_obj(struct lock_to_push); if (!lck) { rc = -ENOMEM; goto err_out; @@ -2010,7 +1992,7 @@ cifs_push_locks(struct cifsFileInfo *cfile) struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); int rc = 0; #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY - struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(cinode); #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ /* we are going to update can_cache_brlcks here - need a write access */ @@ -2023,7 +2005,7 @@ cifs_push_locks(struct cifsFileInfo *cfile) #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) + ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) rc = cifs_push_posix_locks(cfile); else #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ @@ -2228,7 +2210,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, PAGE_SIZE); max_num = (max_buf - sizeof(struct smb_hdr)) / sizeof(LOCKING_ANDX_RANGE); - buf = kcalloc(max_num, sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); + buf = kzalloc_objs(LOCKING_ANDX_RANGE, max_num); if (!buf) return -ENOMEM; @@ -2371,7 +2353,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type, cifs_zap_mapping(inode); cifs_dbg(FYI, "Set no oplock for inode=%p due to mand locks\n", inode); - CIFS_I(inode)->oplock = 0; + cifs_reset_oplock(CIFS_I(inode)); } rc = server->ops->mand_lock(xid, cfile, flock->fl_start, length, @@ -2427,11 +2409,11 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl) cifs_read_flock(fl, &type, &lock, &unlock, &wait_flag, tcon->ses->server); - cifs_sb = CIFS_FILE_SB(file); + cifs_sb = CIFS_SB(file); if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) + ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) posix_lck = true; if (!lock && !unlock) { @@ -2454,14 +2436,14 @@ int cifs_flock(struct file *file, int cmd, struct file_lock *fl) int cifs_lock(struct file *file, int cmd, struct file_lock *flock) { - int rc, xid; + struct cifs_sb_info *cifs_sb = CIFS_SB(file); + struct cifsFileInfo *cfile; int lock = 0, unlock = 0; bool wait_flag = false; bool posix_lck = false; - struct cifs_sb_info *cifs_sb; struct cifs_tcon *tcon; - struct cifsFileInfo *cfile; __u32 type; + int rc, xid; rc = -EACCES; xid = get_xid(); @@ -2476,12 +2458,11 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag, tcon->ses->server); - cifs_sb = CIFS_FILE_SB(file); set_bit(CIFS_INO_CLOSE_ON_LOCK, &CIFS_I(d_inode(cfile->dentry))->flags); if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) + ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) posix_lck = true; /* * BB add code here to normalize offset and length to account for @@ -2528,14 +2509,37 @@ void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t netfs_write_subrequest_terminated(&wdata->subreq, result); } -struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, - bool fsuid_only) +static bool open_flags_match(struct cifsInodeInfo *cinode, + unsigned int oflags, unsigned int cflags) { + struct inode *inode = &cinode->netfs.inode; + int crw = 0, orw = 0; + + oflags &= ~(O_CREAT | O_EXCL | O_TRUNC); + cflags &= ~(O_CREAT | O_EXCL | O_TRUNC); + + if (cifs_fscache_enabled(inode)) { + if (OPEN_FMODE(cflags) & FMODE_WRITE) + crw = 1; + if (OPEN_FMODE(oflags) & FMODE_WRITE) + orw = 1; + } + if (cifs_convert_flags(oflags, orw) != cifs_convert_flags(cflags, crw)) + return false; + + return (oflags & (O_SYNC | O_DIRECT)) == (cflags & (O_SYNC | O_DIRECT)); +} + +struct cifsFileInfo *__find_readable_file(struct cifsInodeInfo *cifs_inode, + unsigned int find_flags, + unsigned int open_flags) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode); + bool fsuid_only = find_flags & FIND_FSUID_ONLY; struct cifsFileInfo *open_file = NULL; - struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb); /* only filter by fsuid on multiuser mounts */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; spin_lock(&cifs_inode->open_file_lock); @@ -2545,6 +2549,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { if (fsuid_only && !uid_eq(open_file->uid, current_fsuid())) continue; + if ((find_flags & FIND_NO_PENDING_DELETE) && + open_file->status_file_deleted) + continue; + if ((find_flags & FIND_OPEN_FLAGS) && + !open_flags_match(cifs_inode, open_flags, + open_file->f_flags)) + continue; if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) { if ((!open_file->invalidHandle)) { /* found a good file */ @@ -2563,17 +2574,17 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, } /* Return -EBADF if no handle is found and general rc otherwise */ -int -cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, - struct cifsFileInfo **ret_file) +int __cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, + unsigned int find_flags, unsigned int open_flags, + struct cifsFileInfo **ret_file) { struct cifsFileInfo *open_file, *inv_file = NULL; struct cifs_sb_info *cifs_sb; bool any_available = false; int rc = -EBADF; unsigned int refind = 0; - bool fsuid_only = flags & FIND_WR_FSUID_ONLY; - bool with_delete = flags & FIND_WR_WITH_DELETE; + bool fsuid_only = find_flags & FIND_FSUID_ONLY; + bool with_delete = find_flags & FIND_WITH_DELETE; *ret_file = NULL; /* @@ -2588,10 +2599,10 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, return rc; } - cifs_sb = CIFS_SB(cifs_inode->netfs.inode.i_sb); + cifs_sb = CIFS_SB(cifs_inode); /* only filter by fsuid on multiuser mounts */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; spin_lock(&cifs_inode->open_file_lock); @@ -2607,9 +2618,13 @@ cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, int flags, continue; if (with_delete && !(open_file->fid.access & DELETE)) continue; - if ((flags & FIND_WR_NO_PENDING_DELETE) && + if ((find_flags & FIND_NO_PENDING_DELETE) && open_file->status_file_deleted) continue; + if ((find_flags & FIND_OPEN_FLAGS) && + !open_flags_match(cifs_inode, open_flags, + open_file->f_flags)) + continue; if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { if (!open_file->invalidHandle) { /* found a good writable file */ @@ -2726,17 +2741,7 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, cinode = CIFS_I(d_inode(cfile->dentry)); spin_unlock(&tcon->open_file_lock); free_dentry_path(page); - *ret_file = find_readable_file(cinode, 0); - if (*ret_file) { - spin_lock(&cinode->open_file_lock); - if ((*ret_file)->status_file_deleted) { - spin_unlock(&cinode->open_file_lock); - cifsFileInfo_put(*ret_file); - *ret_file = NULL; - } else { - spin_unlock(&cinode->open_file_lock); - } - } + *ret_file = find_readable_file(cinode, FIND_ANY); return *ret_file ? 0 : -ENOENT; } @@ -2786,7 +2791,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) struct TCP_Server_Info *server; struct cifsFileInfo *smbfile = file->private_data; struct inode *inode = file_inode(file); - struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); + struct cifs_sb_info *cifs_sb = CIFS_SB(file); rc = file_write_and_wait_range(file, start, end); if (rc) { @@ -2800,7 +2805,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) file, datasync); tcon = tlink_tcon(smbfile->tlink); - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)) { + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOSSYNC)) { server = tcon->ses->server; if (server->ops->flush == NULL) { rc = -ENOSYS; @@ -2808,7 +2813,7 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) } if ((OPEN_FMODE(smbfile->f_flags) & FMODE_WRITE) == 0) { - smbfile = find_writable_file(CIFS_I(inode), FIND_WR_ANY); + smbfile = find_writable_file(CIFS_I(inode), FIND_ANY); if (smbfile) { rc = server->ops->flush(xid, tcon, &smbfile->fid); cifsFileInfo_put(smbfile); @@ -2852,7 +2857,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) struct inode *inode = file->f_mapping->host; struct cifsInodeInfo *cinode = CIFS_I(inode); struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); ssize_t rc; rc = netfs_start_io_write(inode); @@ -2869,7 +2874,7 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) if (rc <= 0) goto out; - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) && + if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) && (cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), server->vals->exclusive_lock_type, 0, NULL, CIFS_WRITE_OP))) { @@ -2892,7 +2897,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) { struct inode *inode = file_inode(iocb->ki_filp); struct cifsInodeInfo *cinode = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct cifsFileInfo *cfile = (struct cifsFileInfo *) iocb->ki_filp->private_data; struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); @@ -2905,7 +2910,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) if (CIFS_CACHE_WRITE(cinode)) { if (cap_unix(tcon->ses) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && - ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { + ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0)) { written = netfs_file_write_iter(iocb, from); goto out; } @@ -2930,7 +2935,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) cifs_zap_mapping(inode); cifs_dbg(FYI, "Set Oplock/Lease to NONE for inode=%p after write\n", inode); - cinode->oplock = 0; + cifs_reset_oplock(cinode); } out: cifs_put_writer(cinode); @@ -2966,7 +2971,7 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) cifs_dbg(FYI, "Set no oplock for inode=%p after a write operation\n", inode); - cinode->oplock = 0; + cifs_reset_oplock(cinode); } return written; } @@ -2993,7 +2998,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to) { struct inode *inode = file_inode(iocb->ki_filp); struct cifsInodeInfo *cinode = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct cifsFileInfo *cfile = (struct cifsFileInfo *) iocb->ki_filp->private_data; struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); @@ -3010,7 +3015,7 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to) if (!CIFS_CACHE_READ(cinode)) return netfs_unbuffered_read_iter(iocb, to); - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) { + if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NOPOSIXBRL) == 0) { if (iocb->ki_flags & IOCB_DIRECT) return netfs_unbuffered_read_iter(iocb, to); return netfs_buffered_read_iter(iocb, to); @@ -3129,10 +3134,9 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file, if (is_inode_writable(cifsInode) || ((cifsInode->oplock & CIFS_CACHE_RW_FLG) != 0 && from_readdir)) { /* This inode is open for write at least once */ - struct cifs_sb_info *cifs_sb; + struct cifs_sb_info *cifs_sb = CIFS_SB(cifsInode); - cifs_sb = CIFS_SB(cifsInode->netfs.inode.i_sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_DIRECT_IO) { /* since no page cache to corrupt on directio we can change size safely */ return true; @@ -3154,20 +3158,16 @@ void cifs_oplock_break(struct work_struct *work) struct super_block *sb = inode->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifsInodeInfo *cinode = CIFS_I(inode); + bool cache_read, cache_write, cache_handle; struct cifs_tcon *tcon; struct TCP_Server_Info *server; struct tcon_link *tlink; + unsigned int oplock; int rc = 0; bool purge_cache = false, oplock_break_cancelled; __u64 persistent_fid, volatile_fid; __u16 net_fid; - /* - * Hold a reference to the superblock to prevent it and its inodes from - * being freed while we are accessing cinode. Otherwise, _cifsFileInfo_put() - * may release the last reference to the sb and trigger inode eviction. - */ - cifs_sb_active(sb); wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS, TASK_UNINTERRUPTIBLE); @@ -3177,29 +3177,40 @@ void cifs_oplock_break(struct work_struct *work) tcon = tlink_tcon(tlink); server = tcon->ses->server; - server->ops->downgrade_oplock(server, cinode, cfile->oplock_level, - cfile->oplock_epoch, &purge_cache); + scoped_guard(spinlock, &cinode->open_file_lock) { + unsigned int sbflags = cifs_sb_flags(cifs_sb); - if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) && - cifs_has_mand_locks(cinode)) { + server->ops->downgrade_oplock(server, cinode, cfile->oplock_level, + cfile->oplock_epoch, &purge_cache); + oplock = READ_ONCE(cinode->oplock); + cache_read = (oplock & CIFS_CACHE_READ_FLG) || + (sbflags & CIFS_MOUNT_RO_CACHE); + cache_write = (oplock & CIFS_CACHE_WRITE_FLG) || + (sbflags & CIFS_MOUNT_RW_CACHE); + cache_handle = oplock & CIFS_CACHE_HANDLE_FLG; + } + + if (!cache_write && cache_read && cifs_has_mand_locks(cinode)) { cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n", inode); - cinode->oplock = 0; + cifs_reset_oplock(cinode); + oplock = 0; + cache_read = cache_write = cache_handle = false; } if (S_ISREG(inode->i_mode)) { - if (CIFS_CACHE_READ(cinode)) + if (cache_read) break_lease(inode, O_RDONLY); else break_lease(inode, O_WRONLY); rc = filemap_fdatawrite(inode->i_mapping); - if (!CIFS_CACHE_READ(cinode) || purge_cache) { + if (!cache_read || purge_cache) { rc = filemap_fdatawait(inode->i_mapping); mapping_set_error(inode->i_mapping, rc); cifs_zap_mapping(inode); } cifs_dbg(FYI, "Oplock flush inode %p rc %d\n", inode, rc); - if (CIFS_CACHE_WRITE(cinode)) + if (cache_write) goto oplock_break_ack; } @@ -3214,7 +3225,7 @@ void cifs_oplock_break(struct work_struct *work) * So, new open will not use cached handle. */ - if (!CIFS_CACHE_HANDLE(cinode) && !list_empty(&cinode->deferred_closes)) + if (!cache_handle && !list_empty(&cinode->deferred_closes)) cifs_close_deferred_file(cinode); persistent_fid = cfile->fid.persistent_fid; @@ -3232,7 +3243,8 @@ void cifs_oplock_break(struct work_struct *work) if (!oplock_break_cancelled && !list_empty(&cinode->openFileList)) { spin_unlock(&cinode->open_file_lock); rc = server->ops->oplock_response(tcon, persistent_fid, - volatile_fid, net_fid, cinode); + volatile_fid, net_fid, + cinode, oplock); cifs_dbg(FYI, "Oplock release rc = %d\n", rc); } else spin_unlock(&cinode->open_file_lock); @@ -3240,7 +3252,6 @@ void cifs_oplock_break(struct work_struct *work) cifs_put_tlink(tlink); out: cifs_done_oplock_break(cinode); - cifs_sb_deactive(sb); } static int cifs_swap_activate(struct swap_info_struct *sis, diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c index ec84204aee18..a4a7c7eee038 100644 --- a/fs/smb/client/fs_context.c +++ b/fs/smb/client/fs_context.c @@ -825,9 +825,7 @@ static int smb3_fs_context_parse_monolithic(struct fs_context *fc, if (ret < 0) break; } - ret = smb3_handle_conflicting_options(fc); - - return ret; + return ret ?: smb3_handle_conflicting_options(fc); } /* @@ -1926,7 +1924,7 @@ int smb3_init_fs_context(struct fs_context *fc) char *nodename = utsname()->nodename; int i; - ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct smb3_fs_context); if (unlikely(!ctx)) return -ENOMEM; @@ -1999,7 +1997,7 @@ int smb3_init_fs_context(struct fs_context *fc) ctx->backupuid_specified = false; /* no backup intent for a user */ ctx->backupgid_specified = false; /* no backup intent for a group */ - ctx->retrans = 1; + ctx->retrans = 0; ctx->reparse_type = CIFS_REPARSE_TYPE_DEFAULT; ctx->symlink_type = CIFS_SYMLINK_TYPE_DEFAULT; ctx->nonativesocket = 0; @@ -2064,161 +2062,160 @@ smb3_cleanup_fs_context(struct smb3_fs_context *ctx) kfree(ctx); } -void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb) +unsigned int smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb) { + unsigned int sbflags = cifs_sb_flags(cifs_sb); struct smb3_fs_context *ctx = cifs_sb->ctx; if (ctx->nodfs) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS; + sbflags |= CIFS_MOUNT_NO_DFS; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_DFS; + sbflags &= ~CIFS_MOUNT_NO_DFS; if (ctx->noperm) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; + sbflags |= CIFS_MOUNT_NO_PERM; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_PERM; + sbflags &= ~CIFS_MOUNT_NO_PERM; if (ctx->setuids) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; + sbflags |= CIFS_MOUNT_SET_UID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SET_UID; + sbflags &= ~CIFS_MOUNT_SET_UID; if (ctx->setuidfromacl) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL; + sbflags |= CIFS_MOUNT_UID_FROM_ACL; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UID_FROM_ACL; + sbflags &= ~CIFS_MOUNT_UID_FROM_ACL; if (ctx->server_ino) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; + sbflags |= CIFS_MOUNT_SERVER_INUM; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; + sbflags &= ~CIFS_MOUNT_SERVER_INUM; if (ctx->remap) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR; + sbflags |= CIFS_MOUNT_MAP_SFM_CHR; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SFM_CHR; + sbflags &= ~CIFS_MOUNT_MAP_SFM_CHR; if (ctx->sfu_remap) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; + sbflags |= CIFS_MOUNT_MAP_SPECIAL_CHR; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR; + sbflags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR; if (ctx->no_xattr) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; + sbflags |= CIFS_MOUNT_NO_XATTR; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_XATTR; + sbflags &= ~CIFS_MOUNT_NO_XATTR; if (ctx->sfu_emul) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL; + sbflags |= CIFS_MOUNT_UNX_EMUL; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UNX_EMUL; + sbflags &= ~CIFS_MOUNT_UNX_EMUL; if (ctx->nobrl) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL; + sbflags |= CIFS_MOUNT_NO_BRL; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_BRL; + sbflags &= ~CIFS_MOUNT_NO_BRL; if (ctx->nohandlecache) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE; + sbflags |= CIFS_MOUNT_NO_HANDLE_CACHE; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_HANDLE_CACHE; + sbflags &= ~CIFS_MOUNT_NO_HANDLE_CACHE; if (ctx->nostrictsync) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; + sbflags |= CIFS_MOUNT_NOSSYNC; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOSSYNC; + sbflags &= ~CIFS_MOUNT_NOSSYNC; if (ctx->mand_lock) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; + sbflags |= CIFS_MOUNT_NOPOSIXBRL; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOPOSIXBRL; + sbflags &= ~CIFS_MOUNT_NOPOSIXBRL; if (ctx->rwpidforward) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; + sbflags |= CIFS_MOUNT_RWPIDFORWARD; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_RWPIDFORWARD; + sbflags &= ~CIFS_MOUNT_RWPIDFORWARD; if (ctx->mode_ace) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID; + sbflags |= CIFS_MOUNT_MODE_FROM_SID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MODE_FROM_SID; + sbflags &= ~CIFS_MOUNT_MODE_FROM_SID; if (ctx->cifs_acl) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; + sbflags |= CIFS_MOUNT_CIFS_ACL; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_ACL; + sbflags &= ~CIFS_MOUNT_CIFS_ACL; if (ctx->backupuid_specified) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID; + sbflags |= CIFS_MOUNT_CIFS_BACKUPUID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPUID; + sbflags &= ~CIFS_MOUNT_CIFS_BACKUPUID; if (ctx->backupgid_specified) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID; + sbflags |= CIFS_MOUNT_CIFS_BACKUPGID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPGID; + sbflags &= ~CIFS_MOUNT_CIFS_BACKUPGID; if (ctx->override_uid) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; + sbflags |= CIFS_MOUNT_OVERR_UID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_UID; + sbflags &= ~CIFS_MOUNT_OVERR_UID; if (ctx->override_gid) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID; + sbflags |= CIFS_MOUNT_OVERR_GID; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_GID; + sbflags &= ~CIFS_MOUNT_OVERR_GID; if (ctx->dynperm) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM; + sbflags |= CIFS_MOUNT_DYNPERM; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DYNPERM; + sbflags &= ~CIFS_MOUNT_DYNPERM; if (ctx->fsc) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE; + sbflags |= CIFS_MOUNT_FSCACHE; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_FSCACHE; + sbflags &= ~CIFS_MOUNT_FSCACHE; if (ctx->multiuser) - cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER | - CIFS_MOUNT_NO_PERM); + sbflags |= CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_NO_PERM; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MULTIUSER; + sbflags &= ~CIFS_MOUNT_MULTIUSER; if (ctx->strict_io) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO; + sbflags |= CIFS_MOUNT_STRICT_IO; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_STRICT_IO; + sbflags &= ~CIFS_MOUNT_STRICT_IO; if (ctx->direct_io) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; + sbflags |= CIFS_MOUNT_DIRECT_IO; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DIRECT_IO; + sbflags &= ~CIFS_MOUNT_DIRECT_IO; if (ctx->mfsymlinks) - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS; + sbflags |= CIFS_MOUNT_MF_SYMLINKS; else - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MF_SYMLINKS; - if (ctx->mfsymlinks) { - if (ctx->sfu_emul) { - /* - * Our SFU ("Services for Unix") emulation allows now - * creating new and reading existing SFU symlinks. - * Older Linux kernel versions were not able to neither - * read existing nor create new SFU symlinks. But - * creating and reading SFU style mknod and FIFOs was - * supported for long time. When "mfsymlinks" and - * "sfu" are both enabled at the same time, it allows - * reading both types of symlinks, but will only create - * them with mfsymlinks format. This allows better - * Apple compatibility, compatibility with older Linux - * kernel clients (probably better for Samba too) - * while still recognizing old Windows style symlinks. - */ - cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n"); - } - } - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SHUTDOWN; + sbflags &= ~CIFS_MOUNT_MF_SYMLINKS; - return; + if (ctx->mfsymlinks && ctx->sfu_emul) { + /* + * Our SFU ("Services for Unix") emulation allows now + * creating new and reading existing SFU symlinks. + * Older Linux kernel versions were not able to neither + * read existing nor create new SFU symlinks. But + * creating and reading SFU style mknod and FIFOs was + * supported for long time. When "mfsymlinks" and + * "sfu" are both enabled at the same time, it allows + * reading both types of symlinks, but will only create + * them with mfsymlinks format. This allows better + * Apple compatibility, compatibility with older Linux + * kernel clients (probably better for Samba too) + * while still recognizing old Windows style symlinks. + */ + cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n"); + } + sbflags &= ~CIFS_MOUNT_SHUTDOWN; + atomic_set(&cifs_sb->mnt_cifs_flags, sbflags); + return sbflags; } diff --git a/fs/smb/client/fs_context.h b/fs/smb/client/fs_context.h index 49b2a6f09ca2..0b64fcb5d302 100644 --- a/fs/smb/client/fs_context.h +++ b/fs/smb/client/fs_context.h @@ -374,7 +374,7 @@ int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx); int smb3_sync_session_ctx_passwords(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses); -void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb); +unsigned int smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb); /* * max deferred close timeout (jiffies) - 2^30 diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index c23c057162e6..143fa2e665ed 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -40,32 +40,33 @@ static void cifs_set_netfs_context(struct inode *inode) static void cifs_set_ops(struct inode *inode) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct netfs_inode *ictx = netfs_inode(inode); + unsigned int sbflags = cifs_sb_flags(cifs_sb); switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &cifs_file_inode_ops; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { + if (sbflags & CIFS_MOUNT_DIRECT_IO) { set_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + if (sbflags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_direct_nobrl_ops; else inode->i_fop = &cifs_file_direct_ops; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + } else if (sbflags & CIFS_MOUNT_STRICT_IO) { + if (sbflags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_strict_nobrl_ops; else inode->i_fop = &cifs_file_strict_ops; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) + } else if (sbflags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_nobrl_ops; else { /* not direct, send byte range locks */ inode->i_fop = &cifs_file_ops; } /* check if server can support readahead */ - if (cifs_sb_master_tcon(cifs_sb)->ses->server->max_read < - PAGE_SIZE + MAX_CIFS_HDR_SIZE) + if (tcon->ses->server->max_read < PAGE_SIZE + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops = &cifs_addr_ops_smallbuf; else inode->i_data.a_ops = &cifs_addr_ops; @@ -194,8 +195,8 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr, inode->i_gid = fattr->cf_gid; /* if dynperm is set, don't clobber existing mode */ - if (inode_state_read(inode) & I_NEW || - !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) + if ((inode_state_read(inode) & I_NEW) || + !(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_DYNPERM)) inode->i_mode = fattr->cf_mode; cifs_i->cifsAttrs = fattr->cf_cifsattrs; @@ -248,10 +249,8 @@ cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) - return; - - fattr->cf_uniqueid = iunique(sb, ROOT_I); + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM)) + fattr->cf_uniqueid = iunique(sb, ROOT_I); } /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */ @@ -259,6 +258,8 @@ void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, struct cifs_sb_info *cifs_sb) { + unsigned int sbflags; + memset(fattr, 0, sizeof(*fattr)); fattr->cf_uniqueid = le64_to_cpu(info->UniqueId); fattr->cf_bytes = le64_to_cpu(info->NumOfBytes); @@ -317,8 +318,9 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, break; } + sbflags = cifs_sb_flags(cifs_sb); fattr->cf_uid = cifs_sb->ctx->linux_uid; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) { + if (!(sbflags & CIFS_MOUNT_OVERR_UID)) { u64 id = le64_to_cpu(info->Uid); if (id < ((uid_t)-1)) { kuid_t uid = make_kuid(&init_user_ns, id); @@ -328,7 +330,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, } fattr->cf_gid = cifs_sb->ctx->linux_gid; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) { + if (!(sbflags & CIFS_MOUNT_OVERR_GID)) { u64 id = le64_to_cpu(info->Gid); if (id < ((gid_t)-1)) { kgid_t gid = make_kgid(&init_user_ns, id); @@ -382,7 +384,7 @@ static int update_inode_info(struct super_block *sb, * * If file type or uniqueid is different, return error. */ - if (unlikely((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && + if (unlikely((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) && CIFS_I(*inode)->uniqueid != fattr->cf_uniqueid)) { CIFS_I(*inode)->time = 0; /* force reval */ return -ESTALE; @@ -468,7 +470,7 @@ static int cifs_get_unix_fattr(const unsigned char *full_path, cifs_fill_uniqueid(sb, fattr); /* check for Minshall+French symlinks */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MF_SYMLINKS) { tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } @@ -1081,7 +1083,7 @@ cifs_backup_query_path_info(int xid, else if ((tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find) == 0) info.info_level = SMB_FIND_FILE_INFO_STANDARD; - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + else if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) info.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; else /* no srvino useful for fallback to some netapp */ info.info_level = SMB_FIND_FILE_DIRECTORY_INFO; @@ -1109,7 +1111,7 @@ static void cifs_set_fattr_ino(int xid, struct cifs_tcon *tcon, struct super_blo struct TCP_Server_Info *server = tcon->ses->server; int rc; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM)) { if (*inode) fattr->cf_uniqueid = CIFS_I(*inode)->uniqueid; else @@ -1263,14 +1265,15 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, struct inode **inode, const char *full_path) { - struct cifs_open_info_data tmp_data = {}; - struct cifs_tcon *tcon; - struct TCP_Server_Info *server; - struct tcon_link *tlink; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); + struct cifs_open_info_data tmp_data = {}; void *smb1_backup_rsp_buf = NULL; - int rc = 0; + struct TCP_Server_Info *server; + struct cifs_tcon *tcon; + struct tcon_link *tlink; + unsigned int sbflags; int tmprc = 0; + int rc = 0; tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) @@ -1370,16 +1373,17 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY handle_mnt_opt: #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ + sbflags = cifs_sb_flags(cifs_sb); /* query for SFU type info if supported and needed */ if ((fattr->cf_cifsattrs & ATTR_SYSTEM) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { + (sbflags & CIFS_MOUNT_UNX_EMUL)) { tmprc = cifs_sfu_type(fattr, full_path, cifs_sb, xid); if (tmprc) cifs_dbg(FYI, "cifs_sfu_type failed: %d\n", tmprc); } /* fill in 0777 bits from ACL */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) { + if (sbflags & CIFS_MOUNT_MODE_FROM_SID) { rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode, true, full_path, fid); if (rc == -EREMOTE) @@ -1389,7 +1393,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, __func__, rc); goto out; } - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { + } else if (sbflags & CIFS_MOUNT_CIFS_ACL) { rc = cifs_acl_to_fattr(cifs_sb, fattr, *inode, false, full_path, fid); if (rc == -EREMOTE) @@ -1399,7 +1403,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, __func__, rc); goto out; } - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) + } else if (sbflags & CIFS_MOUNT_UNX_EMUL) /* fill in remaining high mode bits e.g. SUID, VTX */ cifs_sfu_mode(fattr, full_path, cifs_sb, xid); else if (!(tcon->posix_extensions)) @@ -1409,7 +1413,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data, /* check for Minshall+French symlinks */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { + if (sbflags & CIFS_MOUNT_MF_SYMLINKS) { tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } @@ -1509,7 +1513,7 @@ static int smb311_posix_get_fattr(struct cifs_open_info_data *data, * 3. Tweak fattr based on mount options */ /* check for Minshall+French symlinks */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_MF_SYMLINKS) { tmprc = check_mf_symlink(xid, tcon, cifs_sb, fattr, full_path); cifs_dbg(FYI, "check_mf_symlink: %d\n", tmprc); } @@ -1660,7 +1664,7 @@ struct inode *cifs_root_iget(struct super_block *sb) int len; int rc; - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) + if ((cifs_sb_flags(cifs_sb) & CIFS_MOUNT_USE_PREFIX_PATH) && cifs_sb->prepath) { len = strlen(cifs_sb->prepath); path = kzalloc(len + 2 /* leading sep + null */, GFP_KERNEL); @@ -1841,7 +1845,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry, /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */ if (dosattr != origattr) { - info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL); + info_buf = kzalloc_obj(*info_buf); if (info_buf == NULL) { rc = -ENOMEM; goto out_close; @@ -2041,7 +2045,7 @@ static int __cifs_unlink(struct inode *dir, struct dentry *dentry, bool sillyren } } } else if ((rc == -EACCES) && (dosattr == 0) && inode) { - attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_obj(*attrs); if (attrs == NULL) { rc = -ENOMEM; goto out_reval; @@ -2098,8 +2102,9 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, const char *full_path, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { - int rc = 0; struct inode *inode = NULL; + unsigned int sbflags; + int rc = 0; if (tcon->posix_extensions) { rc = smb311_posix_get_inode_info(&inode, full_path, @@ -2139,6 +2144,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, if (parent->i_mode & S_ISGID) mode |= S_ISGID; + sbflags = cifs_sb_flags(cifs_sb); #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY if (tcon->unix_ext) { struct cifs_unix_set_info_args args = { @@ -2148,7 +2154,7 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, .mtime = NO_CHANGE_64, .device = 0, }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (sbflags & CIFS_MOUNT_SET_UID) { args.uid = current_fsuid(); if (parent->i_mode & S_ISGID) args.gid = parent->i_gid; @@ -2166,14 +2172,14 @@ cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode, { #endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */ struct TCP_Server_Info *server = tcon->ses->server; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && + if (!(sbflags & CIFS_MOUNT_CIFS_ACL) && (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) server->ops->mkdir_setinfo(inode, full_path, cifs_sb, tcon, xid); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) + if (sbflags & CIFS_MOUNT_DYNPERM) inode->i_mode = (mode | S_IFDIR); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (sbflags & CIFS_MOUNT_SET_UID) { inode->i_uid = current_fsuid(); if (inode->i_mode & S_ISGID) inode->i_gid = parent->i_gid; @@ -2197,7 +2203,7 @@ cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, struct inode *newinode = NULL; struct cifs_fattr fattr; - info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); + info = kzalloc_obj(FILE_UNIX_BASIC_INFO); if (info == NULL) { rc = -ENOMEM; goto posix_mkdir_out; @@ -2585,8 +2591,7 @@ cifs_rename2(struct mnt_idmap *idmap, struct inode *source_dir, * with unix extensions enabled. */ info_buf_source = - kmalloc_array(2, sizeof(FILE_UNIX_BASIC_INFO), - GFP_KERNEL); + kmalloc_objs(FILE_UNIX_BASIC_INFO, 2); if (info_buf_source == NULL) { rc = -ENOMEM; goto cifs_rename_exit; @@ -2687,7 +2692,7 @@ cifs_dentry_needs_reval(struct dentry *dentry) { struct inode *inode = d_inode(dentry); struct cifsInodeInfo *cifs_i = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); struct cached_fid *cfid = NULL; @@ -2728,7 +2733,7 @@ cifs_dentry_needs_reval(struct dentry *dentry) } /* hardlinked files w/ noserverino get "special" treatment */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM) && S_ISREG(inode->i_mode) && inode->i_nlink != 1) return true; @@ -2753,10 +2758,10 @@ cifs_wait_bit_killable(struct wait_bit_key *key, int mode) int cifs_revalidate_mapping(struct inode *inode) { - int rc; struct cifsInodeInfo *cifs_inode = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); unsigned long *flags = &cifs_inode->flags; - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + int rc; /* swapfiles are not supposed to be shared */ if (IS_SWAPFILE(inode)) @@ -2769,7 +2774,7 @@ cifs_revalidate_mapping(struct inode *inode) if (test_and_clear_bit(CIFS_INO_INVALID_MAPPING, flags)) { /* for cache=singleclient, do not invalidate */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_RW_CACHE) goto skip_invalidate; cifs_inode->netfs.zero_point = cifs_inode->netfs.remote_i_size; @@ -2893,10 +2898,11 @@ int cifs_revalidate_dentry(struct dentry *dentry) int cifs_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags) { - struct dentry *dentry = path->dentry; - struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(path->dentry); struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); + struct dentry *dentry = path->dentry; struct inode *inode = d_inode(dentry); + unsigned int sbflags; int rc; if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) @@ -2953,12 +2959,13 @@ int cifs_getattr(struct mnt_idmap *idmap, const struct path *path, * enabled, and the admin hasn't overridden them, set the ownership * to the fsuid/fsgid of the current process. */ - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && - !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && + sbflags = cifs_sb_flags(cifs_sb); + if ((sbflags & CIFS_MOUNT_MULTIUSER) && + !(sbflags & CIFS_MOUNT_CIFS_ACL) && !tcon->unix_ext) { - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) + if (!(sbflags & CIFS_MOUNT_OVERR_UID)) stat->uid = current_fsuid(); - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) + if (!(sbflags & CIFS_MOUNT_OVERR_GID)) stat->gid = current_fsgid(); } return 0; @@ -2990,7 +2997,7 @@ int cifs_fiemap(struct inode *inode, struct fiemap_extent_info *fei, u64 start, } } - cfile = find_readable_file(cifs_i, false); + cfile = find_readable_file(cifs_i, FIND_ANY); if (cfile == NULL) return -EINVAL; @@ -3043,7 +3050,7 @@ int cifs_file_set_size(const unsigned int xid, struct dentry *dentry, size, false); cifs_dbg(FYI, "%s: set_file_size: rc = %d\n", __func__, rc); } else { - open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); + open_file = find_writable_file(cifsInode, FIND_FSUID_ONLY); if (open_file) { tcon = tlink_tcon(open_file->tlink); server = tcon->ses->server; @@ -3103,7 +3110,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) void *page = alloc_dentry_path(); struct inode *inode = d_inode(direntry); struct cifsInodeInfo *cifsInode = CIFS_I(inode); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); struct tcon_link *tlink; struct cifs_tcon *pTcon; struct cifs_unix_set_info_args *args = NULL; @@ -3114,7 +3121,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) xid = get_xid(); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs); @@ -3167,7 +3174,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; - args = kmalloc(sizeof(*args), GFP_KERNEL); + args = kmalloc_obj(*args); if (args == NULL) { rc = -ENOMEM; goto out; @@ -3212,7 +3219,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) open_file->fid.netfid, open_file->pid); } else { - open_file = find_writable_file(cifsInode, FIND_WR_FSUID_ONLY); + open_file = find_writable_file(cifsInode, FIND_FSUID_ONLY); if (open_file) { pTcon = tlink_tcon(open_file->tlink); rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, @@ -3267,26 +3274,26 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) static int cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) { - unsigned int xid; + struct inode *inode = d_inode(direntry); + struct cifsInodeInfo *cifsInode = CIFS_I(inode); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + unsigned int sbflags = cifs_sb_flags(cifs_sb); + struct cifsFileInfo *cfile = NULL; + void *page = alloc_dentry_path(); + __u64 mode = NO_CHANGE_64; kuid_t uid = INVALID_UID; kgid_t gid = INVALID_GID; - struct inode *inode = d_inode(direntry); - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); - struct cifsInodeInfo *cifsInode = CIFS_I(inode); - struct cifsFileInfo *cfile = NULL; const char *full_path; - void *page = alloc_dentry_path(); - int rc = -EACCES; __u32 dosattr = 0; - __u64 mode = NO_CHANGE_64; - bool posix = cifs_sb_master_tcon(cifs_sb)->posix_extensions; + int rc = -EACCES; + unsigned int xid; xid = get_xid(); cifs_dbg(FYI, "setattr on file %pd attrs->ia_valid 0x%x\n", direntry, attrs->ia_valid); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) + if (sbflags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; rc = setattr_prepare(&nop_mnt_idmap, direntry, attrs); @@ -3347,8 +3354,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & ATTR_GID) gid = attrs->ia_gid; - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { + if (sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)) { if (uid_valid(uid) || gid_valid(gid)) { mode = NO_CHANGE_64; rc = id_mode_to_cifs_acl(inode, full_path, &mode, @@ -3359,9 +3365,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) goto cifs_setattr_exit; } } - } else - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) + } else if (!(sbflags & CIFS_MOUNT_SET_UID)) { attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); + } /* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) @@ -3370,9 +3376,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) if (attrs->ia_valid & ATTR_MODE) { mode = attrs->ia_mode; rc = 0; - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) || - posix) { + if ((sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)) || + cifs_sb_master_tcon(cifs_sb)->posix_extensions) { rc = id_mode_to_cifs_acl(inode, full_path, &mode, INVALID_UID, INVALID_GID); if (rc) { @@ -3394,7 +3399,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) dosattr = cifsInode->cifsAttrs | ATTR_READONLY; /* fix up mode if we're not using dynperm */ - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) + if ((sbflags & CIFS_MOUNT_DYNPERM) == 0) attrs->ia_mode = inode->i_mode & ~S_IWUGO; } else if ((mode & S_IWUGO) && (cifsInode->cifsAttrs & ATTR_READONLY)) { @@ -3405,7 +3410,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) dosattr |= ATTR_NORMAL; /* reset local inode permissions to normal */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { + if (!(sbflags & CIFS_MOUNT_DYNPERM)) { attrs->ia_mode &= ~(S_IALLUGO); if (S_ISDIR(inode->i_mode)) attrs->ia_mode |= @@ -3414,7 +3419,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) attrs->ia_mode |= cifs_sb->ctx->file_mode; } - } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { + } else if (!(sbflags & CIFS_MOUNT_DYNPERM)) { /* ignore mode change - ATTR_READONLY hasn't changed */ attrs->ia_valid &= ~ATTR_MODE; } diff --git a/fs/smb/client/ioctl.c b/fs/smb/client/ioctl.c index a4aa063cf5ea..9afab3237e54 100644 --- a/fs/smb/client/ioctl.c +++ b/fs/smb/client/ioctl.c @@ -133,7 +133,7 @@ static long smb_mnt_get_fsinfo(unsigned int xid, struct cifs_tcon *tcon, int rc = 0; struct smb_mnt_fs_info *fsinf; - fsinf = kzalloc(sizeof(struct smb_mnt_fs_info), GFP_KERNEL); + fsinf = kzalloc_obj(struct smb_mnt_fs_info); if (fsinf == NULL) return -ENOMEM; @@ -216,7 +216,7 @@ static int cifs_shutdown(struct super_block *sb, unsigned long arg) */ case CIFS_GOING_FLAGS_LOGFLUSH: case CIFS_GOING_FLAGS_NOLOGFLUSH: - sbi->mnt_cifs_flags |= CIFS_MOUNT_SHUTDOWN; + atomic_or(CIFS_MOUNT_SHUTDOWN, &sbi->mnt_cifs_flags); goto shutdown_good; default: rc = -EINVAL; diff --git a/fs/smb/client/link.c b/fs/smb/client/link.c index a2f7bfa8ad1e..434e8fe74080 100644 --- a/fs/smb/client/link.c +++ b/fs/smb/client/link.c @@ -544,14 +544,15 @@ int cifs_symlink(struct mnt_idmap *idmap, struct inode *inode, struct dentry *direntry, const char *symname) { - int rc = -EOPNOTSUPP; - unsigned int xid; - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + struct inode *newinode = NULL; struct tcon_link *tlink; struct cifs_tcon *pTcon; const char *full_path; + int rc = -EOPNOTSUPP; + unsigned int sbflags; + unsigned int xid; void *page; - struct inode *newinode = NULL; if (unlikely(cifs_forced_shutdown(cifs_sb))) return smb_EIO(smb_eio_trace_forced_shutdown); @@ -580,6 +581,7 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode, cifs_dbg(FYI, "symname is %s\n", symname); /* BB what if DFS and this volume is on different share? BB */ + sbflags = cifs_sb_flags(cifs_sb); rc = -EOPNOTSUPP; switch (cifs_symlink_type(cifs_sb)) { case CIFS_SYMLINK_TYPE_UNIX: @@ -594,14 +596,14 @@ cifs_symlink(struct mnt_idmap *idmap, struct inode *inode, break; case CIFS_SYMLINK_TYPE_MFSYMLINKS: - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { + if (sbflags & CIFS_MOUNT_MF_SYMLINKS) { rc = create_mf_symlink(xid, pTcon, cifs_sb, full_path, symname); } break; case CIFS_SYMLINK_TYPE_SFU: - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { + if (sbflags & CIFS_MOUNT_UNX_EMUL) { rc = __cifs_sfu_make_node(xid, inode, direntry, pTcon, full_path, S_IFLNK, 0, symname); diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index 1773e3b471aa..2aff1cab6c31 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -28,6 +28,11 @@ #include "fs_context.h" #include "cached_dir.h" +struct tcon_list { + struct list_head entry; + struct cifs_tcon *tcon; +}; + /* The xid serves as a useful identifier for each incoming vfs request, in a similar way to the mid which is useful to track each sent smb, and CurrentXid can also provide a running counter (although it @@ -67,7 +72,7 @@ sesInfoAlloc(void) { struct cifs_ses *ret_buf; - ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL); + ret_buf = kzalloc_obj(struct cifs_ses); if (ret_buf) { atomic_inc(&sesInfoAllocCount); spin_lock_init(&ret_buf->ses_lock); @@ -118,7 +123,7 @@ tcon_info_alloc(bool dir_leases_enabled, enum smb3_tcon_ref_trace trace) struct cifs_tcon *ret_buf; static atomic_t tcon_debug_id; - ret_buf = kzalloc(sizeof(*ret_buf), GFP_KERNEL); + ret_buf = kzalloc_obj(*ret_buf); if (!ret_buf) return NULL; @@ -275,13 +280,15 @@ dump_smb(void *buf, int smb_buf_length) void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + unsigned int sbflags = cifs_sb_flags(cifs_sb); + + if (sbflags & CIFS_MOUNT_SERVER_INUM) { struct cifs_tcon *tcon = NULL; if (cifs_sb->master_tlink) tcon = cifs_sb_master_tcon(cifs_sb); - cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; + atomic_andnot(CIFS_MOUNT_SERVER_INUM, &cifs_sb->mnt_cifs_flags); cifs_sb->mnt_cifs_serverino_autodisabled = true; cifs_dbg(VFS, "Autodisabling the use of server inode numbers on %s\n", tcon ? tcon->tree_name : "new server"); @@ -382,11 +389,13 @@ void cifs_done_oplock_break(struct cifsInodeInfo *cinode) bool backup_cred(struct cifs_sb_info *cifs_sb) { - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) { + unsigned int sbflags = cifs_sb_flags(cifs_sb); + + if (sbflags & CIFS_MOUNT_CIFS_BACKUPUID) { if (uid_eq(cifs_sb->ctx->backupuid, current_fsuid())) return true; } - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) { + if (sbflags & CIFS_MOUNT_CIFS_BACKUPGID) { if (in_group_p(cifs_sb->ctx->backupgid)) return true; } @@ -499,7 +508,8 @@ cifs_close_deferred_file(struct cifsInodeInfo *cifs_inode) cifs_del_deferred_close(cfile); spin_unlock(&cifs_inode->deferred_lock); - tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC); + tmp_list = kmalloc_obj(struct file_list, + GFP_ATOMIC); if (tmp_list == NULL) break; tmp_list->cfile = cfile; @@ -531,7 +541,8 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon) cifs_del_deferred_close(cfile); spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock); - tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC); + tmp_list = kmalloc_obj(struct file_list, + GFP_ATOMIC); if (tmp_list == NULL) break; tmp_list->cfile = cfile; @@ -548,6 +559,43 @@ cifs_close_all_deferred_files(struct cifs_tcon *tcon) } } +void cifs_close_all_deferred_files_sb(struct cifs_sb_info *cifs_sb) +{ + struct rb_root *root = &cifs_sb->tlink_tree; + struct rb_node *node; + struct cifs_tcon *tcon; + struct tcon_link *tlink; + struct tcon_list *tmp_list, *q; + LIST_HEAD(tcon_head); + + spin_lock(&cifs_sb->tlink_tree_lock); + for (node = rb_first(root); node; node = rb_next(node)) { + tlink = rb_entry(node, struct tcon_link, tl_rbnode); + tcon = tlink_tcon(tlink); + if (IS_ERR(tcon)) + continue; + tmp_list = kmalloc_obj(struct tcon_list, GFP_ATOMIC); + if (tmp_list == NULL) + break; + tmp_list->tcon = tcon; + /* Take a reference on tcon to prevent it from being freed */ + spin_lock(&tcon->tc_lock); + ++tcon->tc_count; + trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count, + netfs_trace_tcon_ref_get_close_defer_files); + spin_unlock(&tcon->tc_lock); + list_add_tail(&tmp_list->entry, &tcon_head); + } + spin_unlock(&cifs_sb->tlink_tree_lock); + + list_for_each_entry_safe(tmp_list, q, &tcon_head, entry) { + cifs_close_all_deferred_files(tmp_list->tcon); + list_del(&tmp_list->entry); + cifs_put_tcon(tmp_list->tcon, netfs_trace_tcon_ref_put_close_defer_files); + kfree(tmp_list); + } +} + void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, struct dentry *dentry) { @@ -564,7 +612,7 @@ void cifs_close_deferred_file_under_dentry(struct cifs_tcon *tcon, cifs_del_deferred_close(cfile); spin_unlock(&CIFS_I(d_inode(cfile->dentry))->deferred_lock); - tmp_list = kmalloc(sizeof(struct file_list), GFP_ATOMIC); + tmp_list = kmalloc_obj(struct file_list, GFP_ATOMIC); if (tmp_list == NULL) break; tmp_list->cfile = cfile; @@ -671,8 +719,7 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size, cifs_dbg(FYI, "num_referrals: %d dfs flags: 0x%x ...\n", *num_of_nodes, le32_to_cpu(rsp->DFSFlags)); - *target_nodes = kcalloc(*num_of_nodes, sizeof(struct dfs_info3_param), - GFP_KERNEL); + *target_nodes = kzalloc_objs(struct dfs_info3_param, *num_of_nodes); if (*target_nodes == NULL) { rc = -ENOMEM; goto parse_DFS_referrals_exit; @@ -954,7 +1001,7 @@ int cifs_update_super_prepath(struct cifs_sb_info *cifs_sb, char *prefix) convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); } - cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; + atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags); return 0; } @@ -983,7 +1030,7 @@ int cifs_inval_name_dfs_link_error(const unsigned int xid, * look up or tcon is not DFS. */ if (strlen(full_path) < 2 || !cifs_sb || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) || + (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_DFS) || !is_tcon_dfs(tcon)) return 0; diff --git a/fs/smb/client/nterr.c b/fs/smb/client/nterr.c index ab5a2119efd0..279566cac435 100644 --- a/fs/smb/client/nterr.c +++ b/fs/smb/client/nterr.c @@ -14,6 +14,7 @@ const struct nt_err_code_struct nt_errs[] = { {"NT_STATUS_OK", NT_STATUS_OK}, {"NT_STATUS_PENDING", NT_STATUS_PENDING}, + {"NT_STATUS_NOTIFY_ENUM_DIR", NT_STATUS_NOTIFY_ENUM_DIR}, {"NT_STATUS_MEDIA_CHANGED", NT_STATUS_MEDIA_CHANGED}, {"NT_STATUS_END_OF_MEDIA", NT_STATUS_END_OF_MEDIA}, {"NT_STATUS_MEDIA_CHECK", NT_STATUS_MEDIA_CHECK}, @@ -694,7 +695,7 @@ const struct nt_err_code_struct nt_errs[] = { {"NT_STATUS_NETWORK_SESSION_EXPIRED", NT_STATUS_NETWORK_SESSION_EXPIRED}, {"NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES}, {"NT_STATUS_MORE_ENTRIES", NT_STATUS_MORE_ENTRIES}, - {"NT_STATUS_SOME_UNMAPPED", NT_STATUS_SOME_UNMAPPED}, + {"NT_STATUS_SOME_NOT_MAPPED", NT_STATUS_SOME_NOT_MAPPED}, {"NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB}, {"NT_STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP", NT_STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP}, diff --git a/fs/smb/client/nterr.h b/fs/smb/client/nterr.h index b04cd0d786b1..9a4a450c6571 100644 --- a/fs/smb/client/nterr.h +++ b/fs/smb/client/nterr.h @@ -22,21 +22,21 @@ struct nt_err_code_struct { extern const struct nt_err_code_struct nt_errs[]; -/* Win32 Status codes. */ -#define NT_STATUS_MORE_ENTRIES 0x0105 +/* Win32 Error Codes. */ #define NT_ERROR_INVALID_PARAMETER 0x0057 #define NT_ERROR_INSUFFICIENT_BUFFER 0x007a -#define NT_STATUS_1804 0x070c -#define NT_STATUS_NOTIFY_ENUM_DIR 0x010c +#define NT_ERROR_INVALID_DATATYPE 0x070c /* - * Win32 Error codes extracted using a loop in smbclient then printing a netmon + * NTSTATUS Values extracted using a loop in smbclient then printing a netmon * sniff to a file. */ #define NT_STATUS_OK 0x0000 #define NT_STATUS_PENDING 0x0103 -#define NT_STATUS_SOME_UNMAPPED 0x0107 +#define NT_STATUS_MORE_ENTRIES 0x0105 +#define NT_STATUS_SOME_NOT_MAPPED 0x0107 +#define NT_STATUS_NOTIFY_ENUM_DIR 0x010c #define NT_STATUS_BUFFER_OVERFLOW 0x80000005 #define NT_STATUS_NO_MORE_ENTRIES 0x8000001a #define NT_STATUS_MEDIA_CHANGED 0x8000001c diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c index 67a8555efa1e..be22bbc4a65a 100644 --- a/fs/smb/client/readdir.c +++ b/fs/smb/client/readdir.c @@ -121,7 +121,7 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, * want to clobber the existing one with the one that * the readdir code created. */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_SERVER_INUM)) fattr->cf_uniqueid = CIFS_I(inode)->uniqueid; /* @@ -177,6 +177,7 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) struct cifs_open_info_data data = { .reparse = { .tag = fattr->cf_cifstag, }, }; + unsigned int sbflags; fattr->cf_uid = cifs_sb->ctx->linux_uid; fattr->cf_gid = cifs_sb->ctx->linux_gid; @@ -215,12 +216,12 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) * may look wrong since the inodes may not have timed out by the time * "ls" does a stat() call on them. */ - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) + sbflags = cifs_sb_flags(cifs_sb); + if (sbflags & (CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_MODE_FROM_SID)) fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && - fattr->cf_cifsattrs & ATTR_SYSTEM) { + if ((sbflags & CIFS_MOUNT_UNX_EMUL) && + (fattr->cf_cifsattrs & ATTR_SYSTEM)) { if (fattr->cf_eof == 0) { fattr->cf_mode &= ~S_IFMT; fattr->cf_mode |= S_IFIFO; @@ -345,20 +346,21 @@ static int _initiate_cifs_search(const unsigned int xid, struct file *file, const char *full_path) { + struct cifs_sb_info *cifs_sb = CIFS_SB(file); + struct tcon_link *tlink = NULL; + struct TCP_Server_Info *server; + struct cifsFileInfo *cifsFile; + struct cifs_tcon *tcon; + unsigned int sbflags; __u16 search_flags; int rc = 0; - struct cifsFileInfo *cifsFile; - struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); - struct tcon_link *tlink = NULL; - struct cifs_tcon *tcon; - struct TCP_Server_Info *server; if (file->private_data == NULL) { tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); - cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); + cifsFile = kzalloc_obj(struct cifsFileInfo); if (cifsFile == NULL) { rc = -ENOMEM; goto error_exit; @@ -385,6 +387,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, cifs_dbg(FYI, "Full path: %s start at: %lld\n", full_path, file->f_pos); ffirst_retry: + sbflags = cifs_sb_flags(cifs_sb); /* test for Unix extensions */ /* but now check for them on the share/mount not on the SMB session */ /* if (cap_unix(tcon->ses) { */ @@ -395,7 +398,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, else if ((tcon->ses->capabilities & tcon->ses->server->vals->cap_nt_find) == 0) { cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + } else if (sbflags & CIFS_MOUNT_SERVER_INUM) { cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; } else /* not srvinos - BB fixme add check for backlevel? */ { cifsFile->srch_inf.info_level = SMB_FIND_FILE_FULL_DIRECTORY_INFO; @@ -411,8 +414,7 @@ _initiate_cifs_search(const unsigned int xid, struct file *file, if (rc == 0) { cifsFile->invalidHandle = false; - } else if ((rc == -EOPNOTSUPP) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { + } else if (rc == -EOPNOTSUPP && (sbflags & CIFS_MOUNT_SERVER_INUM)) { cifs_autodisable_serverino(cifs_sb); goto ffirst_retry; } @@ -690,7 +692,7 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos, loff_t first_entry_in_buffer; loff_t index_to_find = pos; struct cifsFileInfo *cfile = file->private_data; - struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); + struct cifs_sb_info *cifs_sb = CIFS_SB(file); struct TCP_Server_Info *server = tcon->ses->server; /* check if index in the buffer */ @@ -888,7 +890,7 @@ static bool add_cached_dirent(struct cached_dirents *cde, cde->is_failed = 1; return false; } - de = kzalloc(sizeof(*de), GFP_ATOMIC); + de = kzalloc_obj(*de, GFP_ATOMIC); if (de == NULL) { cde->is_failed = 1; return false; @@ -955,6 +957,7 @@ static int cifs_filldir(char *find_entry, struct file *file, struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_dirent de = { NULL, }; struct cifs_fattr fattr; + unsigned int sbflags; struct qstr name; int rc = 0; @@ -1019,15 +1022,15 @@ static int cifs_filldir(char *find_entry, struct file *file, break; } - if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { + sbflags = cifs_sb_flags(cifs_sb); + if (de.ino && (sbflags & CIFS_MOUNT_SERVER_INUM)) { fattr.cf_uniqueid = de.ino; } else { fattr.cf_uniqueid = iunique(sb, ROOT_I); cifs_autodisable_serverino(cifs_sb); } - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && - couldbe_mf_symlink(&fattr)) + if ((sbflags & CIFS_MOUNT_MF_SYMLINKS) && couldbe_mf_symlink(&fattr)) /* * trying to get the type and mode can be slow, * so just call those regular files for now, and mark @@ -1058,7 +1061,7 @@ int cifs_readdir(struct file *file, struct dir_context *ctx) const char *full_path; void *page = alloc_dentry_path(); struct cached_fid *cfid = NULL; - struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file); + struct cifs_sb_info *cifs_sb = CIFS_SB(file); xid = get_xid(); diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index ce9b923498b5..cd1e1eaee67a 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -55,17 +55,18 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode, const char *full_path, const char *symname) { struct reparse_symlink_data_buffer *buf = NULL; - struct cifs_open_info_data data = {}; - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); const char *symroot = cifs_sb->ctx->symlinkroot; - struct inode *new; - struct kvec iov; - __le16 *path = NULL; - bool directory; - char *symlink_target = NULL; - char *sym = NULL; + struct cifs_open_info_data data = {}; char sep = CIFS_DIR_SEP(cifs_sb); + char *symlink_target = NULL; u16 len, plen, poff, slen; + unsigned int sbflags; + __le16 *path = NULL; + struct inode *new; + char *sym = NULL; + struct kvec iov; + bool directory; int rc = 0; if (strlen(symname) > REPARSE_SYM_PATH_MAX) @@ -83,8 +84,8 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode, .symlink_target = symlink_target, }; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && - symroot && symname[0] == '/') { + sbflags = cifs_sb_flags(cifs_sb); + if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symroot && symname[0] == '/') { /* * This is a request to create an absolute symlink on the server * which does not support POSIX paths, and expects symlink in @@ -164,7 +165,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode, * mask these characters in NT object prefix by '_' and then change * them back. */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') + if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') sym[0] = sym[1] = sym[2] = sym[5] = '_'; path = cifs_convert_path_to_utf16(sym, cifs_sb); @@ -173,7 +174,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode, goto out; } - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') { + if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') { sym[0] = '\\'; sym[1] = sym[2] = '?'; sym[5] = ':'; @@ -197,7 +198,7 @@ static int create_native_symlink(const unsigned int xid, struct inode *inode, slen = 2 * UniStrnlen((wchar_t *)path, REPARSE_SYM_PATH_MAX); poff = 0; plen = slen; - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') { + if (!(sbflags & CIFS_MOUNT_POSIX_PATHS) && symname[0] == '/') { /* * For absolute NT symlinks skip leading "\\??\\" in PrintName as * PrintName is user visible location in DOS/Win32 format (not in NT format). @@ -824,7 +825,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, goto out; } - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) && + if (!(cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) && symroot && !relative) { /* * This is an absolute symlink from the server which does not diff --git a/fs/smb/client/reparse.h b/fs/smb/client/reparse.h index 570b0d25aeba..0164dc47bdfd 100644 --- a/fs/smb/client/reparse.h +++ b/fs/smb/client/reparse.h @@ -33,7 +33,7 @@ static inline kuid_t wsl_make_kuid(struct cifs_sb_info *cifs_sb, { u32 uid = le32_to_cpu(*(__le32 *)ptr); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_UID) return cifs_sb->ctx->linux_uid; return make_kuid(current_user_ns(), uid); } @@ -43,7 +43,7 @@ static inline kgid_t wsl_make_kgid(struct cifs_sb_info *cifs_sb, { u32 gid = le32_to_cpu(*(__le32 *)ptr); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_OVERR_GID) return cifs_sb->ctx->linux_gid; return make_kgid(current_user_ns(), gid); } diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index d523540565ef..698bd27119ae 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -510,7 +510,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, * the session and server without caring about memory * management. */ - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { rc = -ENOMEM; goto out_free_xid; diff --git a/fs/smb/client/smb1encrypt.c b/fs/smb/client/smb1encrypt.c index 0dbbce2431ff..bf10fdeeedca 100644 --- a/fs/smb/client/smb1encrypt.c +++ b/fs/smb/client/smb1encrypt.c @@ -11,6 +11,7 @@ #include #include +#include #include "cifsproto.h" #include "smb1proto.h" #include "cifs_debug.h" @@ -131,7 +132,7 @@ int cifs_verify_signature(struct smb_rqst *rqst, /* cifs_dump_mem("what we think it should be: ", what_we_think_sig_should_be, 16); */ - if (memcmp(server_response_sig, what_we_think_sig_should_be, 8)) + if (crypto_memneq(server_response_sig, what_we_think_sig_should_be, 8)) return -EACCES; else return 0; diff --git a/fs/smb/client/smb1maperror.c b/fs/smb/client/smb1maperror.c index 277ef0865be0..e1964fd2b85e 100644 --- a/fs/smb/client/smb1maperror.c +++ b/fs/smb/client/smb1maperror.c @@ -112,6 +112,10 @@ static const struct { __u32 ntstatus; } ntstatus_to_dos_map[] = { { + ERRSRV, ERR_NOTIFY_ENUM_DIR, NT_STATUS_NOTIFY_ENUM_DIR}, { + ERRDOS, ERRmoredata, NT_STATUS_BUFFER_OVERFLOW}, { + ERRDOS, ERRmoredata, NT_STATUS_MORE_PROCESSING_REQUIRED}, { + ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, { ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, { ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, { ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, { diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index 9c3b97d2a20a..9694117050a6 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -49,6 +49,7 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, if (!CIFSSMBQFSUnixInfo(xid, tcon)) { __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); + unsigned int sbflags; cifs_dbg(FYI, "unix caps which server supports %lld\n", cap); /* @@ -75,14 +76,16 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP) cifs_dbg(VFS, "per-share encryption not supported yet\n"); + if (cifs_sb) + sbflags = cifs_sb_flags(cifs_sb); + cap &= CIFS_UNIX_CAP_MASK; if (ctx && ctx->no_psx_acl) cap &= ~CIFS_UNIX_POSIX_ACL_CAP; else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { cifs_dbg(FYI, "negotiated posix acl support\n"); if (cifs_sb) - cifs_sb->mnt_cifs_flags |= - CIFS_MOUNT_POSIXACL; + sbflags |= CIFS_MOUNT_POSIXACL; } if (ctx && ctx->posix_paths == 0) @@ -90,10 +93,12 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon, else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { cifs_dbg(FYI, "negotiate posix pathnames\n"); if (cifs_sb) - cifs_sb->mnt_cifs_flags |= - CIFS_MOUNT_POSIX_PATHS; + sbflags |= CIFS_MOUNT_POSIX_PATHS; } + if (cifs_sb) + atomic_set(&cifs_sb->mnt_cifs_flags, sbflags); + cifs_dbg(FYI, "Negotiate caps 0x%x\n", (int)cap); #ifdef CONFIG_CIFS_DEBUG2 if (cap & CIFS_UNIX_FCNTL_CAP) @@ -395,6 +400,7 @@ cifs_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch, bool *purge_cache) { + lockdep_assert_held(&cinode->open_file_lock); cifs_set_oplock_level(cinode, oplock); } @@ -505,7 +511,7 @@ cifs_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, int rc; FILE_ALL_INFO *file_info; - file_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); + file_info = kmalloc_obj(FILE_ALL_INFO); if (file_info == NULL) return -ENOMEM; @@ -894,6 +900,9 @@ static void cifs_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) { struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); + + lockdep_assert_held(&cinode->open_file_lock); + cfile->fid.netfid = fid->netfid; cifs_set_oplock_level(cinode, oplock); cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode); @@ -951,7 +960,7 @@ smb_set_file_info(struct inode *inode, const char *full_path, struct cifs_tcon *tcon; /* if the file is already open for write, just use that fileid */ - open_file = find_writable_file(cinode, FIND_WR_FSUID_ONLY); + open_file = find_writable_file(cinode, FIND_FSUID_ONLY); if (open_file) { fid.netfid = open_file->fid.netfid; @@ -1139,12 +1148,16 @@ cifs_close_dir(const unsigned int xid, struct cifs_tcon *tcon, return CIFSFindClose(xid, tcon, fid->netfid); } -static int -cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, - __u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode) +static int cifs_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, + __u64 volatile_fid, __u16 net_fid, + struct cifsInodeInfo *cinode, unsigned int oplock) { + unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode)); + __u8 op; + + op = !!((oplock & CIFS_CACHE_READ_FLG) || (sbflags & CIFS_MOUNT_RO_CACHE)); return CIFSSMBLock(0, tcon, net_fid, current->tgid, 0, 0, 0, 0, - LOCKING_ANDX_OPLOCK_RELEASE, false, CIFS_CACHE_READ(cinode) ? 1 : 0); + LOCKING_ANDX_OPLOCK_RELEASE, false, op); } static int @@ -1274,7 +1287,8 @@ cifs_make_node(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, umode_t mode, dev_t dev) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + struct cifs_sb_info *cifs_sb = CIFS_SB(inode); + unsigned int sbflags = cifs_sb_flags(cifs_sb); struct inode *newinode = NULL; int rc; @@ -1290,7 +1304,7 @@ cifs_make_node(unsigned int xid, struct inode *inode, .mtime = NO_CHANGE_64, .device = dev, }; - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (sbflags & CIFS_MOUNT_SET_UID) { args.uid = current_fsuid(); args.gid = current_fsgid(); } else { @@ -1309,7 +1323,7 @@ cifs_make_node(unsigned int xid, struct inode *inode, if (rc == 0) d_instantiate(dentry, newinode); return rc; - } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { + } else if (sbflags & CIFS_MOUNT_UNX_EMUL) { /* * Check if mounted with mount parm 'sfu' mount parm. * SFU emulation should work with all servers diff --git a/fs/smb/client/smb1session.c b/fs/smb/client/smb1session.c index 1cf6bd640fde..83bfbf0c068e 100644 --- a/fs/smb/client/smb1session.c +++ b/fs/smb/client/smb1session.c @@ -725,7 +725,7 @@ sess_auth_rawntlmssp_negotiate(struct sess_data *sess_data) * if memory allocation is successful, caller of this function * frees it. */ - ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL); + ses->ntlmssp = kmalloc_obj(struct ntlmssp_auth); if (!ses->ntlmssp) { rc = -ENOMEM; goto out; @@ -969,7 +969,7 @@ int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, return -EINVAL; } - sess_data = kzalloc(sizeof(struct sess_data), GFP_KERNEL); + sess_data = kzalloc_obj(struct sess_data); if (!sess_data) return -ENOMEM; diff --git a/fs/smb/client/smb1transport.c b/fs/smb/client/smb1transport.c index 0b8b852cfc0d..38d6d5538b96 100644 --- a/fs/smb/client/smb1transport.c +++ b/fs/smb/client/smb1transport.c @@ -29,7 +29,6 @@ #include "cifs_debug.h" #include "smbdirect.h" #include "compress.h" -#include "cifs_debug.h" /* Max number of iovectors we can use off the stack when sending requests. */ #define CIFS_MAX_IOV_SIZE 8 @@ -170,12 +169,18 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, iov[0].iov_base = mid->resp_buf; iov[0].iov_len = len; - /* FIXME: add code to kill session */ + rc = cifs_verify_signature(&rqst, server, mid->sequence_number); - if (rc) + if (rc) { cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", rc); + + if (!(server->sec_mode & SECMODE_SIGN_REQUIRED)) { + cifs_reconnect(server, true); + return rc; + } + } } /* BB special case reconnect tid and uid here? */ diff --git a/fs/smb/client/smb2file.c b/fs/smb/client/smb2file.c index 476c53b3711f..ed651c946251 100644 --- a/fs/smb/client/smb2file.c +++ b/fs/smb/client/smb2file.c @@ -72,7 +72,7 @@ int smb2_fix_symlink_target_type(char **target, bool directory, struct cifs_sb_i * POSIX server does not distinguish between symlinks to file and * symlink directory. So nothing is needed to fix on the client side. */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_POSIX_PATHS) return 0; if (!*target) @@ -281,7 +281,7 @@ smb2_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE); max_buf = min_t(unsigned int, max_buf, PAGE_SIZE); max_num = max_buf / sizeof(struct smb2_lock_element); - buf = kcalloc(max_num, sizeof(struct smb2_lock_element), GFP_KERNEL); + buf = kzalloc_objs(struct smb2_lock_element, max_num); if (!buf) return -ENOMEM; @@ -424,7 +424,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) BUILD_BUG_ON(sizeof(struct smb2_lock_element) > PAGE_SIZE); max_buf = min_t(unsigned int, max_buf, PAGE_SIZE); max_num = max_buf / sizeof(struct smb2_lock_element); - buf = kcalloc(max_num, sizeof(struct smb2_lock_element), GFP_KERNEL); + buf = kzalloc_objs(struct smb2_lock_element, max_num); if (!buf) { free_xid(xid); return -ENOMEM; diff --git a/fs/smb/client/smb2glob.h b/fs/smb/client/smb2glob.h index e56e4d402f13..19da74b1edab 100644 --- a/fs/smb/client/smb2glob.h +++ b/fs/smb/client/smb2glob.h @@ -46,4 +46,16 @@ enum smb2_compound_ops { #define END_OF_CHAIN 4 #define RELATED_REQUEST 8 +/* + ***************************************************************** + * Struct definitions go here + ***************************************************************** + */ + +struct status_to_posix_error { + __u32 smb2_status; + int posix_error; + char *status_string; +}; + #endif /* _SMB2_GLOB_H */ diff --git a/fs/smb/client/smb2inode.c b/fs/smb/client/smb2inode.c index 8a30088fed15..364bdcff9c9d 100644 --- a/fs/smb/client/smb2inode.c +++ b/fs/smb/client/smb2inode.c @@ -209,7 +209,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, num_rqst = 0; server = cifs_pick_channel(ses); - vars = kzalloc(sizeof(*vars), GFP_ATOMIC); + vars = kzalloc_obj(*vars, GFP_ATOMIC); if (vars == NULL) { rc = -ENOMEM; goto out; @@ -325,7 +325,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, cfile->fid.volatile_fid, SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, - sizeof(struct smb311_posix_qinfo *) + + sizeof(struct smb311_posix_qinfo) + (PATH_MAX * 2) + (sizeof(struct smb_sid) * 2), 0, NULL); } else { @@ -335,7 +335,7 @@ static int smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, COMPOUND_FID, SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, - sizeof(struct smb311_posix_qinfo *) + + sizeof(struct smb311_posix_qinfo) + (PATH_MAX * 2) + (sizeof(struct smb_sid) * 2), 0, NULL); } @@ -1156,7 +1156,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, cifs_i = CIFS_I(inode); dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; data.Attributes = cpu_to_le32(dosattrs); - cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, name, FIND_ANY, &cfile); oparms = CIFS_OPARMS(cifs_sb, tcon, name, FILE_WRITE_ATTRIBUTES, FILE_CREATE, CREATE_NOT_FILE, ACL_NO_MODE); tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, @@ -1216,6 +1216,7 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, memset(resp_buftype, 0, sizeof(resp_buftype)); memset(rsp_iov, 0, sizeof(rsp_iov)); + memset(open_iov, 0, sizeof(open_iov)); rqst[0].rq_iov = open_iov; rqst[0].rq_nvec = ARRAY_SIZE(open_iov); @@ -1240,14 +1241,15 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, creq = rqst[0].rq_iov[0].iov_base; creq->ShareAccess = FILE_SHARE_DELETE_LE; + memset(&close_iov, 0, sizeof(close_iov)); rqst[1].rq_iov = &close_iov; rqst[1].rq_nvec = 1; rc = SMB2_close_init(tcon, server, &rqst[1], COMPOUND_FID, COMPOUND_FID, false); - smb2_set_related(&rqst[1]); if (rc) goto err_free; + smb2_set_related(&rqst[1]); if (retries) { /* Back-off before retry */ @@ -1334,14 +1336,13 @@ int smb2_rename_path(const unsigned int xid, __u32 co = file_create_options(source_dentry); drop_cached_dir_by_name(xid, tcon, from_name, cifs_sb); - cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); + cifs_get_writable_path(tcon, from_name, FIND_WITH_DELETE, &cfile); int rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, co, DELETE, SMB2_OP_RENAME, cfile, source_dentry); if (rc == -EINVAL) { cifs_dbg(FYI, "invalid lease key, resending request without lease"); - cifs_get_writable_path(tcon, from_name, - FIND_WR_WITH_DELETE, &cfile); + cifs_get_writable_path(tcon, from_name, FIND_WITH_DELETE, &cfile); rc = smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, co, DELETE, SMB2_OP_RENAME, cfile, NULL); } @@ -1375,7 +1376,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, in_iov.iov_base = &eof; in_iov.iov_len = sizeof(eof); - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE); @@ -1385,7 +1386,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, cfile, NULL, NULL, dentry); if (rc == -EINVAL) { cifs_dbg(FYI, "invalid lease key, resending request without lease"); - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, &in_iov, &(int){SMB2_OP_SET_EOF}, 1, @@ -1415,7 +1416,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path, (buf->LastWriteTime == 0) && (buf->ChangeTime == 0)) { if (buf->Attributes == 0) goto out; /* would be a no op, no sense sending this */ - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); } oparms = CIFS_OPARMS(cifs_sb, tcon, full_path, FILE_WRITE_ATTRIBUTES, @@ -1474,7 +1475,7 @@ struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data, if (tcon->posix_extensions) { cmds[1] = SMB2_OP_POSIX_QUERY_INFO; - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); if (!rc) { @@ -1483,7 +1484,7 @@ struct inode *smb2_create_reparse_inode(struct cifs_open_info_data *data, } } else { cmds[1] = SMB2_OP_QUERY_INFO; - cifs_get_writable_path(tcon, full_path, FIND_WR_ANY, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_ANY, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, in_iov, cmds, 2, cfile, out_iov, out_buftype, NULL); if (!rc) { @@ -1634,13 +1635,12 @@ int smb2_rename_pending_delete(const char *full_path, iov[1].iov_base = utf16_path; iov[1].iov_len = sizeof(*utf16_path) * UniStrlen((wchar_t *)utf16_path); - cifs_get_writable_path(tcon, full_path, FIND_WR_WITH_DELETE, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_WITH_DELETE, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, cmds, num_cmds, cfile, NULL, NULL, dentry); if (rc == -EINVAL) { cifs_dbg(FYI, "invalid lease key, resending request without lease\n"); - cifs_get_writable_path(tcon, full_path, - FIND_WR_WITH_DELETE, &cfile); + cifs_get_writable_path(tcon, full_path, FIND_WITH_DELETE, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, &oparms, iov, cmds, num_cmds, cfile, NULL, NULL, NULL); } diff --git a/fs/smb/client/smb2maperror.c b/fs/smb/client/smb2maperror.c index cd036365201f..2b8782c4f684 100644 --- a/fs/smb/client/smb2maperror.c +++ b/fs/smb/client/smb2maperror.c @@ -8,7 +8,6 @@ * */ #include -#include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" #include "smb2proto.h" @@ -16,12 +15,6 @@ #include "../common/smb2status.h" #include "trace.h" -struct status_to_posix_error { - __u32 smb2_status; - int posix_error; - char *status_string; -}; - static const struct status_to_posix_error smb2_error_map_table[] = { /* * Automatically generated by the `gen_smb2_mapping` script, @@ -115,10 +108,22 @@ int __init smb2_init_maperror(void) return 0; } -#define SMB_CLIENT_KUNIT_AVAILABLE \ - ((IS_MODULE(CONFIG_CIFS) && IS_ENABLED(CONFIG_KUNIT)) || \ - (IS_BUILTIN(CONFIG_CIFS) && IS_BUILTIN(CONFIG_KUNIT))) +#if IS_ENABLED(CONFIG_SMB_KUNIT_TESTS) +#define EXPORT_SYMBOL_FOR_SMB_TEST(sym) \ + EXPORT_SYMBOL_FOR_MODULES(sym, "smb2maperror_test") -#if SMB_CLIENT_KUNIT_AVAILABLE && IS_ENABLED(CONFIG_SMB_KUNIT_TESTS) -#include "smb2maperror_test.c" -#endif /* CONFIG_SMB_KUNIT_TESTS */ +/* Previous prototype for eliminating the build warning. */ +const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status); + +const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status) +{ + return smb2_get_err_map(smb2_status); +} +EXPORT_SYMBOL_FOR_SMB_TEST(smb2_get_err_map_test); + +const struct status_to_posix_error *smb2_error_map_table_test = smb2_error_map_table; +EXPORT_SYMBOL_FOR_SMB_TEST(smb2_error_map_table_test); + +unsigned int smb2_error_map_num = ARRAY_SIZE(smb2_error_map_table); +EXPORT_SYMBOL_FOR_SMB_TEST(smb2_error_map_num); +#endif diff --git a/fs/smb/client/smb2maperror_test.c b/fs/smb/client/smb2maperror_test.c index 38ea6b846a99..8c47dea7a2c1 100644 --- a/fs/smb/client/smb2maperror_test.c +++ b/fs/smb/client/smb2maperror_test.c @@ -9,13 +9,18 @@ */ #include +#include "smb2glob.h" + +const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status); +extern const struct status_to_posix_error *smb2_error_map_table_test; +extern unsigned int smb2_error_map_num; static void test_cmp_map(struct kunit *test, const struct status_to_posix_error *expect) { const struct status_to_posix_error *result; - result = smb2_get_err_map(expect->smb2_status); + result = smb2_get_err_map_test(expect->smb2_status); KUNIT_EXPECT_PTR_NE(test, NULL, result); KUNIT_EXPECT_EQ(test, expect->smb2_status, result->smb2_status); KUNIT_EXPECT_EQ(test, expect->posix_error, result->posix_error); @@ -26,8 +31,8 @@ static void maperror_test_check_search(struct kunit *test) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(smb2_error_map_table); i++) - test_cmp_map(test, &smb2_error_map_table[i]); + for (i = 0; i < smb2_error_map_num; i++) + test_cmp_map(test, &smb2_error_map_table_test[i]); } static struct kunit_case maperror_test_cases[] = { @@ -43,3 +48,4 @@ static struct kunit_suite maperror_suite = { kunit_test_suite(maperror_suite); MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit tests of SMB2 maperror"); diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c index 0871b9f1f86a..973fce3c959c 100644 --- a/fs/smb/client/smb2misc.c +++ b/fs/smb/client/smb2misc.c @@ -455,17 +455,8 @@ smb2_calc_size(void *buf) __le16 * cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) { - int len; const char *start_of_path; - __le16 *to; - int map_type; - - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SFM_CHR) - map_type = SFM_MAP_UNI_RSVD; - else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) - map_type = SFU_MAP_UNI_RSVD; - else - map_type = NO_MAP_UNI_RSVD; + int len; /* Windows doesn't allow paths beginning with \ */ if (from[0] == '\\') @@ -479,21 +470,20 @@ cifs_convert_path_to_utf16(const char *from, struct cifs_sb_info *cifs_sb) } else start_of_path = from; - to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, - cifs_sb->local_nls, map_type); - return to; + return cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, + cifs_sb->local_nls, cifs_remap(cifs_sb)); } -__le32 -smb2_get_lease_state(struct cifsInodeInfo *cinode) +__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode, unsigned int oplock) { + unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode)); __le32 lease = 0; - if (CIFS_CACHE_WRITE(cinode)) + if ((oplock & CIFS_CACHE_WRITE_FLG) || (sbflags & CIFS_MOUNT_RW_CACHE)) lease |= SMB2_LEASE_WRITE_CACHING_LE; - if (CIFS_CACHE_HANDLE(cinode)) + if (oplock & CIFS_CACHE_HANDLE_FLG) lease |= SMB2_LEASE_HANDLE_CACHING_LE; - if (CIFS_CACHE_READ(cinode)) + if ((oplock & CIFS_CACHE_READ_FLG) || (sbflags & CIFS_MOUNT_RO_CACHE)) lease |= SMB2_LEASE_READ_CACHING_LE; return lease; } @@ -526,7 +516,7 @@ smb2_queue_pending_open_break(struct tcon_link *tlink, __u8 *lease_key, { struct smb2_lease_break_work *lw; - lw = kmalloc(sizeof(struct smb2_lease_break_work), GFP_KERNEL); + lw = kmalloc_obj(struct smb2_lease_break_work); if (!lw) { cifs_put_tlink(tlink); return; @@ -798,7 +788,7 @@ __smb2_handle_cancelled_cmd(struct cifs_tcon *tcon, __u16 cmd, __u64 mid, { struct close_cancelled_open *cancelled; - cancelled = kzalloc(sizeof(*cancelled), GFP_KERNEL); + cancelled = kzalloc_obj(*cancelled); if (!cancelled) return -ENOMEM; diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 262df6d2c2c8..98ac4e86bf99 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -628,6 +628,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, struct smb_sockaddr_in6 *p6; struct cifs_server_iface *info = NULL, *iface = NULL, *niface = NULL; struct cifs_server_iface tmp_iface; + __be16 port; ssize_t bytes_left; size_t next = 0; int nb_iface = 0; @@ -662,6 +663,15 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, goto out; } + spin_lock(&ses->server->srv_lock); + if (ses->server->dstaddr.ss_family == AF_INET) + port = ((struct sockaddr_in *)&ses->server->dstaddr)->sin_port; + else if (ses->server->dstaddr.ss_family == AF_INET6) + port = ((struct sockaddr_in6 *)&ses->server->dstaddr)->sin6_port; + else + port = cpu_to_be16(CIFS_PORT); + spin_unlock(&ses->server->srv_lock); + while (bytes_left >= (ssize_t)sizeof(*p)) { memset(&tmp_iface, 0, sizeof(tmp_iface)); /* default to 1Gbps when link speed is unset */ @@ -682,7 +692,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, memcpy(&addr4->sin_addr, &p4->IPv4Address, 4); /* [MS-SMB2] 2.2.32.5.1.1 Clients MUST ignore these */ - addr4->sin_port = cpu_to_be16(CIFS_PORT); + addr4->sin_port = port; cifs_dbg(FYI, "%s: ipv4 %pI4\n", __func__, &addr4->sin_addr); @@ -696,7 +706,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, /* [MS-SMB2] 2.2.32.5.1.2 Clients MUST ignore these */ addr6->sin6_flowinfo = 0; addr6->sin6_scope_id = 0; - addr6->sin6_port = cpu_to_be16(CIFS_PORT); + addr6->sin6_port = port; cifs_dbg(FYI, "%s: ipv6 %pI6\n", __func__, &addr6->sin6_addr); @@ -731,8 +741,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf, spin_unlock(&ses->iface_lock); /* no match. insert the entry in the list */ - info = kmalloc(sizeof(struct cifs_server_iface), - GFP_KERNEL); + info = kmalloc_obj(struct cifs_server_iface); if (!info) { rc = -ENOMEM; goto out; @@ -987,7 +996,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon, rc = -EREMOTE; } if (rc == -EREMOTE && IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS)) + (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_DFS)) rc = -EOPNOTSUPP; goto out; } @@ -1185,6 +1194,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, replay_again: /* reinitialize for possible replay */ + used_len = 0; flags = CIFS_CP_CREATE_CLOSE_OP; oplock = SMB2_OPLOCK_LEVEL_NONE; server = cifs_pick_channel(ses); @@ -1201,7 +1211,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon, ea = NULL; resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - vars = kzalloc(sizeof(*vars), GFP_KERNEL); + vars = kzalloc_obj(*vars); if (!vars) { rc = -ENOMEM; goto out_free_path; @@ -1460,6 +1470,8 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock) struct cifsInodeInfo *cinode = CIFS_I(d_inode(cfile->dentry)); struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; + lockdep_assert_held(&cinode->open_file_lock); + cfile->fid.persistent_fid = fid->persistent_fid; cfile->fid.volatile_fid = fid->volatile_fid; cfile->fid.access = fid->access; @@ -1586,11 +1598,12 @@ smb2_ioctl_query_info(const unsigned int xid, replay_again: /* reinitialize for possible replay */ + buffer = NULL; flags = CIFS_CP_CREATE_CLOSE_OP; oplock = SMB2_OPLOCK_LEVEL_NONE; server = cifs_pick_channel(ses); - vars = kzalloc(sizeof(*vars), GFP_ATOMIC); + vars = kzalloc_obj(*vars, GFP_ATOMIC); if (vars == NULL) return -ENOMEM; rqst = &vars->rqst[0]; @@ -1885,7 +1898,7 @@ smb2_copychunk_range(const unsigned int xid, goto out; } - cc_req = kzalloc(struct_size(cc_req, Chunks, chunk_count), GFP_KERNEL); + cc_req = kzalloc_flex(*cc_req, Chunks, chunk_count); if (!cc_req) { rc = -ENOMEM; goto out; @@ -2684,16 +2697,19 @@ smb2_is_network_name_deleted(char *buf, struct TCP_Server_Info *server) return false; } -static int -smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, - __u64 volatile_fid, __u16 net_fid, struct cifsInodeInfo *cinode) +static int smb2_oplock_response(struct cifs_tcon *tcon, __u64 persistent_fid, + __u64 volatile_fid, __u16 net_fid, + struct cifsInodeInfo *cinode, unsigned int oplock) { + unsigned int sbflags = cifs_sb_flags(CIFS_SB(cinode)); + __u8 op; + if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) return SMB2_lease_break(0, tcon, cinode->lease_key, - smb2_get_lease_state(cinode)); + smb2_get_lease_state(cinode, oplock)); - return SMB2_oplock_break(0, tcon, persistent_fid, volatile_fid, - CIFS_CACHE_READ(cinode) ? 1 : 0); + op = !!((oplock & CIFS_CACHE_READ_FLG) || (sbflags & CIFS_MOUNT_RO_CACHE)); + return SMB2_oplock_break(0, tcon, persistent_fid, volatile_fid, op); } void @@ -2843,7 +2859,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, flags |= CIFS_TRANSFORM_REQ; resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; - vars = kzalloc(sizeof(*vars), GFP_KERNEL); + vars = kzalloc_obj(*vars); if (!vars) { rc = -ENOMEM; goto out_free_path; @@ -3176,8 +3192,6 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, if (tcon && !tcon->ipc) { /* ipc tcons are not refcounted */ cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_dfs_refer); - trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count, - netfs_trace_tcon_ref_dec_dfs_refer); } kfree(utf16_path); kfree(dfs_req); @@ -3348,7 +3362,7 @@ get_smb2_acl(struct cifs_sb_info *cifs_sb, struct cifsFileInfo *open_file = NULL; if (inode && !(info & SACL_SECINFO)) - open_file = find_readable_file(CIFS_I(inode), true); + open_file = find_readable_file(CIFS_I(inode), FIND_FSUID_ONLY); if (!open_file || (info & SACL_SECINFO)) return get_smb2_acl_by_path(cifs_sb, path, pacllen, info); @@ -3894,7 +3908,7 @@ static loff_t smb3_llseek(struct file *file, struct cifs_tcon *tcon, loff_t offs * some servers (Windows2016) will not reflect recent writes in * QUERY_ALLOCATED_RANGES until SMB2_flush is called. */ - wrcfile = find_writable_file(cifsi, FIND_WR_ANY); + wrcfile = find_writable_file(cifsi, FIND_ANY); if (wrcfile) { filemap_write_and_wait(inode->i_mapping); smb2_flush_file(xid, tcon, &wrcfile->fid); @@ -4053,6 +4067,7 @@ smb2_downgrade_oplock(struct TCP_Server_Info *server, struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch, bool *purge_cache) { + lockdep_assert_held(&cinode->open_file_lock); server->ops->set_oplock_level(cinode, oplock, 0, NULL); } @@ -4093,19 +4108,19 @@ smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE) return; if (oplock == SMB2_OPLOCK_LEVEL_BATCH) { - cinode->oplock = CIFS_CACHE_RHW_FLG; + WRITE_ONCE(cinode->oplock, CIFS_CACHE_RHW_FLG); cifs_dbg(FYI, "Batch Oplock granted on inode %p\n", &cinode->netfs.inode); } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) { - cinode->oplock = CIFS_CACHE_RW_FLG; + WRITE_ONCE(cinode->oplock, CIFS_CACHE_RW_FLG); cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n", &cinode->netfs.inode); } else if (oplock == SMB2_OPLOCK_LEVEL_II) { - cinode->oplock = CIFS_CACHE_READ_FLG; + WRITE_ONCE(cinode->oplock, CIFS_CACHE_READ_FLG); cifs_dbg(FYI, "Level II Oplock granted on inode %p\n", &cinode->netfs.inode); } else - cinode->oplock = 0; + WRITE_ONCE(cinode->oplock, 0); } static void @@ -4140,7 +4155,7 @@ smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, if (!new_oplock) strscpy(message, "None"); - cinode->oplock = new_oplock; + WRITE_ONCE(cinode->oplock, new_oplock); cifs_dbg(FYI, "%s Lease granted on inode %p\n", message, &cinode->netfs.inode); } @@ -4149,30 +4164,32 @@ static void smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock, __u16 epoch, bool *purge_cache) { - unsigned int old_oplock = cinode->oplock; + unsigned int old_oplock = READ_ONCE(cinode->oplock); + unsigned int new_oplock; smb21_set_oplock_level(cinode, oplock, epoch, purge_cache); + new_oplock = READ_ONCE(cinode->oplock); if (purge_cache) { *purge_cache = false; if (old_oplock == CIFS_CACHE_READ_FLG) { - if (cinode->oplock == CIFS_CACHE_READ_FLG && + if (new_oplock == CIFS_CACHE_READ_FLG && (epoch - cinode->epoch > 0)) *purge_cache = true; - else if (cinode->oplock == CIFS_CACHE_RH_FLG && + else if (new_oplock == CIFS_CACHE_RH_FLG && (epoch - cinode->epoch > 1)) *purge_cache = true; - else if (cinode->oplock == CIFS_CACHE_RHW_FLG && + else if (new_oplock == CIFS_CACHE_RHW_FLG && (epoch - cinode->epoch > 1)) *purge_cache = true; - else if (cinode->oplock == 0 && + else if (new_oplock == 0 && (epoch - cinode->epoch > 0)) *purge_cache = true; } else if (old_oplock == CIFS_CACHE_RH_FLG) { - if (cinode->oplock == CIFS_CACHE_RH_FLG && + if (new_oplock == CIFS_CACHE_RH_FLG && (epoch - cinode->epoch > 0)) *purge_cache = true; - else if (cinode->oplock == CIFS_CACHE_RHW_FLG && + else if (new_oplock == CIFS_CACHE_RHW_FLG && (epoch - cinode->epoch > 1)) *purge_cache = true; } @@ -4213,7 +4230,7 @@ smb2_create_lease_buf(u8 *lease_key, u8 oplock, u8 *parent_lease_key, __le32 fla { struct create_lease *buf; - buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL); + buf = kzalloc_obj(struct create_lease); if (!buf) return NULL; @@ -4239,7 +4256,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock, u8 *parent_lease_key, __le32 fla { struct create_lease_v2 *buf; - buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL); + buf = kzalloc_obj(struct create_lease_v2); if (!buf) return NULL; @@ -4923,7 +4940,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, int rc; struct smb2_decrypt_work *dw; - dw = kzalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); + dw = kzalloc_obj(struct smb2_decrypt_work); if (!dw) return -ENOMEM; INIT_WORK(&dw->decrypt, smb2_decrypt_offload); @@ -5325,7 +5342,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode, struct dentry *dentry, struct cifs_tcon *tcon, const char *full_path, umode_t mode, dev_t dev) { - struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + unsigned int sbflags = cifs_sb_flags(CIFS_SB(inode)); int rc = -EOPNOTSUPP; /* @@ -5334,7 +5351,7 @@ static int smb2_make_node(unsigned int xid, struct inode *inode, * supports block and char device, socket & fifo, * and was used by default in earlier versions of Windows */ - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { + if (sbflags & CIFS_MOUNT_UNX_EMUL) { rc = cifs_sfu_make_node(xid, inode, dentry, tcon, full_path, mode, dev); } else if (CIFS_REPARSE_SUPPORT(tcon)) { diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c index 4602b4dfe832..5188218c25be 100644 --- a/fs/smb/client/smb2pdu.c +++ b/fs/smb/client/smb2pdu.c @@ -1009,8 +1009,7 @@ create_posix_buf(umode_t mode) { struct create_posix *buf; - buf = kzalloc(sizeof(struct create_posix), - GFP_KERNEL); + buf = kzalloc_obj(struct create_posix); if (!buf) return NULL; @@ -1359,7 +1358,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) cifs_tcon_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); - pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS); + pneg_inbuf = kmalloc_obj(*pneg_inbuf, GFP_NOFS); if (!pneg_inbuf) return -ENOMEM; @@ -1715,19 +1714,17 @@ SMB2_auth_kerberos(struct SMB2_sess_data *sess_data) is_binding = (ses->ses_status == SES_GOOD); spin_unlock(&ses->ses_lock); - /* keep session key if binding */ - if (!is_binding) { - kfree_sensitive(ses->auth_key.response); - ses->auth_key.response = kmemdup(msg->data, msg->sesskey_len, - GFP_KERNEL); - if (!ses->auth_key.response) { - cifs_dbg(VFS, "Kerberos can't allocate (%u bytes) memory\n", - msg->sesskey_len); - rc = -ENOMEM; - goto out_put_spnego_key; - } - ses->auth_key.len = msg->sesskey_len; + kfree_sensitive(ses->auth_key.response); + ses->auth_key.response = kmemdup(msg->data, + msg->sesskey_len, + GFP_KERNEL); + if (!ses->auth_key.response) { + cifs_dbg(VFS, "%s: can't allocate (%u bytes) memory\n", + __func__, msg->sesskey_len); + rc = -ENOMEM; + goto out_put_spnego_key; } + ses->auth_key.len = msg->sesskey_len; sess_data->iov[1].iov_base = msg->data + msg->sesskey_len; sess_data->iov[1].iov_len = msg->secblob_len; @@ -1786,7 +1783,7 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data) * If memory allocation is successful, caller of this function * frees it. */ - ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL); + ses->ntlmssp = kmalloc_obj(struct ntlmssp_auth); if (!ses->ntlmssp) { rc = -ENOMEM; goto out_err; @@ -1984,7 +1981,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, return smb_EIO(smb_eio_trace_null_pointers); } - sess_data = kzalloc(sizeof(struct SMB2_sess_data), GFP_KERNEL); + sess_data = kzalloc_obj(struct SMB2_sess_data); if (!sess_data) return -ENOMEM; @@ -2298,7 +2295,7 @@ create_durable_buf(void) { create_durable_req_t *buf; - buf = kzalloc(sizeof(create_durable_req_t), GFP_KERNEL); + buf = kzalloc_obj(create_durable_req_t); if (!buf) return NULL; @@ -2321,7 +2318,7 @@ create_reconnect_durable_buf(struct cifs_fid *fid) { create_durable_req_t *buf; - buf = kzalloc(sizeof(create_durable_req_t), GFP_KERNEL); + buf = kzalloc_obj(create_durable_req_t); if (!buf) return NULL; @@ -2493,7 +2490,7 @@ create_durable_v2_buf(struct cifs_open_parms *oparms) struct cifs_fid *pfid = oparms->fid; struct create_durable_req_v2 *buf; - buf = kzalloc(sizeof(struct create_durable_req_v2), GFP_KERNEL); + buf = kzalloc_obj(struct create_durable_req_v2); if (!buf) return NULL; @@ -2534,8 +2531,7 @@ create_reconnect_durable_v2_buf(struct cifs_fid *fid) { struct create_durable_handle_reconnect_v2 *buf; - buf = kzalloc(sizeof(struct create_durable_handle_reconnect_v2), - GFP_KERNEL); + buf = kzalloc_obj(struct create_durable_handle_reconnect_v2); if (!buf) return NULL; @@ -2626,7 +2622,7 @@ create_twarp_buf(__u64 timewarp) { struct crt_twarp_ctxt *buf; - buf = kzalloc(sizeof(struct crt_twarp_ctxt), GFP_KERNEL); + buf = kzalloc_obj(struct crt_twarp_ctxt); if (!buf) return NULL; @@ -2793,7 +2789,7 @@ create_query_id_buf(void) { struct crt_query_id_ctxt *buf; - buf = kzalloc(sizeof(struct crt_query_id_ctxt), GFP_KERNEL); + buf = kzalloc_obj(struct crt_query_id_ctxt); if (!buf) return NULL; @@ -2908,6 +2904,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, replay_again: /* reinitialize for possible replay */ + pc_buf = NULL; flags = 0; n_iov = 2; server = cifs_pick_channel(ses); @@ -3183,22 +3180,19 @@ SMB2_open_init(struct cifs_tcon *tcon, struct TCP_Server_Info *server, } if ((oparms->disposition != FILE_OPEN) && (oparms->cifs_sb)) { + unsigned int sbflags = cifs_sb_flags(oparms->cifs_sb); bool set_mode; bool set_owner; - if ((oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) && - (oparms->mode != ACL_NO_MODE)) + if ((sbflags & CIFS_MOUNT_MODE_FROM_SID) && + oparms->mode != ACL_NO_MODE) { set_mode = true; - else { + } else { set_mode = false; oparms->mode = ACL_NO_MODE; } - if (oparms->cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) - set_owner = true; - else - set_owner = false; - + set_owner = sbflags & CIFS_MOUNT_UID_FROM_ACL; if (set_owner | set_mode) { cifs_dbg(FYI, "add sd with mode 0x%x\n", oparms->mode); rc = add_sd_context(iov, &n_iov, oparms->mode, set_owner); @@ -3995,24 +3989,6 @@ int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, NULL); } -#if 0 -/* currently unused, as now we are doing compounding instead (see smb311_posix_query_path_info) */ -int -SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid, - struct smb311_posix_qinfo *data, u32 *plen) -{ - size_t output_len = sizeof(struct smb311_posix_qinfo *) + - (sizeof(struct smb_sid) * 2) + (PATH_MAX * 2); - *plen = 0; - - return query_info(xid, tcon, persistent_fid, volatile_fid, - SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, - output_len, sizeof(struct smb311_posix_qinfo), (void **)&data, plen); - /* Note caller must free "data" (passed in above). It may be allocated in query_info call */ -} -#endif - int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, @@ -5331,7 +5307,10 @@ SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, memset(&rqst, 0, sizeof(struct smb_rqst)); rqst.rq_iov = iov; - rqst.rq_nvec = n_vec + 1; + /* iov[0] is the SMB header; move payload to rq_iter for encryption safety */ + rqst.rq_nvec = 1; + iov_iter_kvec(&rqst.rq_iter, ITER_SOURCE, &iov[1], n_vec, + io_parms->length); if (retries) { /* Back-off before retry */ @@ -5844,7 +5823,7 @@ send_set_info(const unsigned int xid, struct cifs_tcon *tcon, if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; - iov = kmalloc_array(num, sizeof(struct kvec), GFP_KERNEL); + iov = kmalloc_objs(struct kvec, num); if (!iov) return -ENOMEM; diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h index 78bb99f29d38..30d70097fe2f 100644 --- a/fs/smb/client/smb2pdu.h +++ b/fs/smb/client/smb2pdu.h @@ -224,7 +224,7 @@ struct smb2_file_reparse_point_info { __le32 Tag; } __packed; -/* See MS-FSCC 2.4.21 */ +/* See MS-FSCC 2.4.26 */ struct smb2_file_id_information { __le64 VolumeSerialNumber; __u64 PersistentFileId; /* opaque endianness */ @@ -251,7 +251,10 @@ struct smb2_file_id_extd_directory_info { extern char smb2_padding[7]; -/* equivalent of the contents of SMB3.1.1 POSIX open context response */ +/* + * See POSIX-SMB2 2.2.14.2.16 + * Link: https://gitlab.com/samba-team/smb3-posix-spec/-/blob/master/smb3_posix_extensions.md + */ struct create_posix_rsp { u32 nlink; u32 reparse_tag; diff --git a/fs/smb/client/smb2proto.h b/fs/smb/client/smb2proto.h index c7759e37d975..230bb1e9f4e1 100644 --- a/fs/smb/client/smb2proto.h +++ b/fs/smb/client/smb2proto.h @@ -42,7 +42,7 @@ struct mid_q_entry *smb2_setup_async_request(struct TCP_Server_Info *server, struct smb_rqst *rqst); struct cifs_tcon *smb2_find_smb_tcon(struct TCP_Server_Info *server, __u64 ses_id, __u32 tid); -__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode); +__le32 smb2_get_lease_state(struct cifsInodeInfo *cinode, unsigned int oplock); bool smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server); int smb3_handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid); @@ -167,9 +167,6 @@ int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, struct cifs_tcon *tcon, struct TCP_Server_Info *server, u64 persistent_fid, u64 volatile_fid); void SMB2_flush_free(struct smb_rqst *rqst); -int SMB311_posix_query_info(const unsigned int xid, struct cifs_tcon *tcon, - u64 persistent_fid, u64 volatile_fid, - struct smb311_posix_qinfo *data, u32 *plen); int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, struct smb2_file_all_info *data); diff --git a/fs/smb/client/smb2transport.c b/fs/smb/client/smb2transport.c index 8b9000a83181..81be2b226e26 100644 --- a/fs/smb/client/smb2transport.c +++ b/fs/smb/client/smb2transport.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "cifsglob.h" #include "cifsproto.h" #include "smb2proto.h" @@ -617,7 +618,8 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) if (rc) return rc; - if (memcmp(server_response_sig, shdr->Signature, SMB2_SIGNATURE_SIZE)) { + if (crypto_memneq(server_response_sig, shdr->Signature, + SMB2_SIGNATURE_SIZE)) { cifs_dbg(VFS, "sign fail cmd 0x%x message id 0x%llx\n", shdr->Command, shdr->MessageId); return -EACCES; diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c index d44847c9d8fc..c79304012b08 100644 --- a/fs/smb/client/smbdirect.c +++ b/fs/smb/client/smbdirect.c @@ -2098,7 +2098,7 @@ static struct smbd_connection *_smbd_get_connection( char wq_name[80]; struct workqueue_struct *workqueue; - info = kzalloc(sizeof(struct smbd_connection), GFP_KERNEL); + info = kzalloc_obj(struct smbd_connection); if (!info) return NULL; sc = &info->socket; @@ -2786,7 +2786,7 @@ static int allocate_mr_list(struct smbdirect_socket *sc) /* Allocate more MRs (2x) than hardware responder_resources */ for (i = 0; i < sp->responder_resources * 2; i++) { - mr = kzalloc(sizeof(*mr), GFP_KERNEL); + mr = kzalloc_obj(*mr); if (!mr) { ret = -ENOMEM; goto kzalloc_mr_failed; @@ -2805,9 +2805,8 @@ static int allocate_mr_list(struct smbdirect_socket *sc) goto ib_alloc_mr_failed; } - mr->sgt.sgl = kcalloc(sp->max_frmr_depth, - sizeof(struct scatterlist), - GFP_KERNEL); + mr->sgt.sgl = kzalloc_objs(struct scatterlist, + sp->max_frmr_depth); if (!mr->sgt.sgl) { ret = -ENOMEM; log_rdma_mr(ERR, "failed to allocate sgl\n"); diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h index 191f02344dcd..acfbb63086ea 100644 --- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -168,7 +168,6 @@ E_(cifs_trace_rw_credits_zero_in_flight, "ZERO-IN-FLT") #define smb3_tcon_ref_traces \ - EM(netfs_trace_tcon_ref_dec_dfs_refer, "DEC DfsRef") \ EM(netfs_trace_tcon_ref_free, "FRE ") \ EM(netfs_trace_tcon_ref_free_fail, "FRE Fail ") \ EM(netfs_trace_tcon_ref_free_ipc, "FRE Ipc ") \ @@ -177,6 +176,7 @@ EM(netfs_trace_tcon_ref_get_cached_laundromat, "GET Ch-Lau") \ EM(netfs_trace_tcon_ref_get_cached_lease_break, "GET Ch-Lea") \ EM(netfs_trace_tcon_ref_get_cancelled_close, "GET Cn-Cls") \ + EM(netfs_trace_tcon_ref_get_close_defer_files, "GET Cl-Def") \ EM(netfs_trace_tcon_ref_get_dfs_refer, "GET DfsRef") \ EM(netfs_trace_tcon_ref_get_find, "GET Find ") \ EM(netfs_trace_tcon_ref_get_find_sess_tcon, "GET FndSes") \ @@ -188,6 +188,7 @@ EM(netfs_trace_tcon_ref_put_cancelled_close, "PUT Cn-Cls") \ EM(netfs_trace_tcon_ref_put_cancelled_close_fid, "PUT Cn-Fid") \ EM(netfs_trace_tcon_ref_put_cancelled_mid, "PUT Cn-Mid") \ + EM(netfs_trace_tcon_ref_put_close_defer_files, "PUT Cl-Def") \ EM(netfs_trace_tcon_ref_put_mnt_ctx, "PUT MntCtx") \ EM(netfs_trace_tcon_ref_put_dfs_refer, "PUT DfsRfr") \ EM(netfs_trace_tcon_ref_put_reconnect_server, "PUT Reconn") \ diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c index 75697f6d2566..05f8099047e1 100644 --- a/fs/smb/client/transport.c +++ b/fs/smb/client/transport.c @@ -807,16 +807,21 @@ cifs_cancelled_callback(struct TCP_Server_Info *server, struct mid_q_entry *mid) } /* - * Return a channel (master if none) of @ses that can be used to send - * regular requests. + * cifs_pick_channel - pick an eligible channel for network operations * - * If we are currently binding a new channel (negprot/sess.setup), - * return the new incomplete channel. + * @ses: session reference + * + * Select an eligible channel (not terminating and not marked as needing + * reconnect), preferring the least loaded one. If no eligible channel is + * found, fall back to the primary channel (index 0). + * + * Return: TCP_Server_Info pointer for the chosen channel, or NULL if @ses is + * NULL. */ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) { uint index = 0; - unsigned int min_in_flight = UINT_MAX, max_in_flight = 0; + unsigned int min_in_flight = UINT_MAX; struct TCP_Server_Info *server = NULL; int i, start, cur; @@ -846,14 +851,8 @@ struct TCP_Server_Info *cifs_pick_channel(struct cifs_ses *ses) min_in_flight = server->in_flight; index = cur; } - if (server->in_flight > max_in_flight) - max_in_flight = server->in_flight; } - /* if all channels are equally loaded, fall back to round-robin */ - if (min_in_flight == max_in_flight) - index = (uint)start % ses->chan_count; - server = ses->chans[index].server; spin_unlock(&ses->chan_lock); diff --git a/fs/smb/client/xattr.c b/fs/smb/client/xattr.c index e1a7d9a10a53..23227f2f9428 100644 --- a/fs/smb/client/xattr.c +++ b/fs/smb/client/xattr.c @@ -149,7 +149,7 @@ static int cifs_xattr_set(const struct xattr_handler *handler, break; } - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR) goto out; if (pTcon->ses->server->ops->set_EA) { @@ -309,7 +309,7 @@ static int cifs_xattr_get(const struct xattr_handler *handler, break; } - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR) goto out; if (pTcon->ses->server->ops->query_all_EAs) @@ -398,7 +398,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) if (unlikely(cifs_forced_shutdown(cifs_sb))) return smb_EIO(smb_eio_trace_forced_shutdown); - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + if (cifs_sb_flags(cifs_sb) & CIFS_MOUNT_NO_XATTR) return -EOPNOTSUPP; tlink = cifs_sb_tlink(cifs_sb); diff --git a/fs/smb/server/Kconfig b/fs/smb/server/Kconfig index 2775162c535c..12594879cb64 100644 --- a/fs/smb/server/Kconfig +++ b/fs/smb/server/Kconfig @@ -13,6 +13,7 @@ config SMB_SERVER select CRYPTO_LIB_MD5 select CRYPTO_LIB_SHA256 select CRYPTO_LIB_SHA512 + select CRYPTO_LIB_UTILS select CRYPTO_CMAC select CRYPTO_AEAD2 select CRYPTO_CCM diff --git a/fs/smb/server/auth.c b/fs/smb/server/auth.c index 09af55b71153..af5f40304331 100644 --- a/fs/smb/server/auth.c +++ b/fs/smb/server/auth.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -165,7 +166,8 @@ int ksmbd_auth_ntlmv2(struct ksmbd_conn *conn, struct ksmbd_session *sess, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE, sess->sess_key); - if (memcmp(ntlmv2->ntlmv2_hash, ntlmv2_rsp, CIFS_HMAC_MD5_HASH_SIZE) != 0) + if (crypto_memneq(ntlmv2->ntlmv2_hash, ntlmv2_rsp, + CIFS_HMAC_MD5_HASH_SIZE)) return -EINVAL; return 0; } @@ -239,7 +241,7 @@ int ksmbd_decode_ntlmssp_auth_blob(struct authenticate_message *authblob, if (sess_key_len > CIFS_KEY_SIZE) return -EINVAL; - ctx_arc4 = kmalloc(sizeof(*ctx_arc4), KSMBD_DEFAULT_GFP); + ctx_arc4 = kmalloc_obj(*ctx_arc4, KSMBD_DEFAULT_GFP); if (!ctx_arc4) return -ENOMEM; @@ -587,12 +589,8 @@ static int generate_smb3signingkey(struct ksmbd_session *sess, if (!(conn->dialect >= SMB30_PROT_ID && signing->binding)) memcpy(chann->smb3signingkey, key, SMB3_SIGN_KEY_SIZE); - ksmbd_debug(AUTH, "dumping generated AES signing keys\n"); + ksmbd_debug(AUTH, "generated SMB3 signing key\n"); ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); - ksmbd_debug(AUTH, "Session Key %*ph\n", - SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); - ksmbd_debug(AUTH, "Signing Key %*ph\n", - SMB3_SIGN_KEY_SIZE, key); return 0; } @@ -650,23 +648,9 @@ static void generate_smb3encryptionkey(struct ksmbd_conn *conn, ptwin->decryption.context, sess->smb3decryptionkey, SMB3_ENC_DEC_KEY_SIZE); - ksmbd_debug(AUTH, "dumping generated AES encryption keys\n"); + ksmbd_debug(AUTH, "generated SMB3 encryption/decryption keys\n"); ksmbd_debug(AUTH, "Cipher type %d\n", conn->cipher_type); ksmbd_debug(AUTH, "Session Id %llu\n", sess->id); - ksmbd_debug(AUTH, "Session Key %*ph\n", - SMB2_NTLMV2_SESSKEY_SIZE, sess->sess_key); - if (conn->cipher_type == SMB2_ENCRYPTION_AES256_CCM || - conn->cipher_type == SMB2_ENCRYPTION_AES256_GCM) { - ksmbd_debug(AUTH, "ServerIn Key %*ph\n", - SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3encryptionkey); - ksmbd_debug(AUTH, "ServerOut Key %*ph\n", - SMB3_GCM256_CRYPTKEY_SIZE, sess->smb3decryptionkey); - } else { - ksmbd_debug(AUTH, "ServerIn Key %*ph\n", - SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3encryptionkey); - ksmbd_debug(AUTH, "ServerOut Key %*ph\n", - SMB3_GCM128_CRYPTKEY_SIZE, sess->smb3decryptionkey); - } } void ksmbd_gen_smb30_encryptionkey(struct ksmbd_conn *conn, @@ -774,7 +758,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, if (!nvec) return NULL; - nr_entries = kcalloc(nvec, sizeof(int), KSMBD_DEFAULT_GFP); + nr_entries = kzalloc_objs(int, nvec, KSMBD_DEFAULT_GFP); if (!nr_entries) return NULL; @@ -794,8 +778,7 @@ static struct scatterlist *ksmbd_init_sg(struct kvec *iov, unsigned int nvec, /* Add two entries for transform header and signature */ total_entries += 2; - sg = kmalloc_array(total_entries, sizeof(struct scatterlist), - KSMBD_DEFAULT_GFP); + sg = kmalloc_objs(struct scatterlist, total_entries, KSMBD_DEFAULT_GFP); if (!sg) { kfree(nr_entries); return NULL; diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c index e7e3e77006b1..1bb2081c492c 100644 --- a/fs/smb/server/connection.c +++ b/fs/smb/server/connection.c @@ -111,7 +111,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) { struct ksmbd_conn *conn; - conn = kzalloc(sizeof(struct ksmbd_conn), KSMBD_DEFAULT_GFP); + conn = kzalloc_obj(struct ksmbd_conn, KSMBD_DEFAULT_GFP); if (!conn) return NULL; diff --git a/fs/smb/server/crypto_ctx.c b/fs/smb/server/crypto_ctx.c index fe29d186baf6..8fd9713b00b7 100644 --- a/fs/smb/server/crypto_ctx.c +++ b/fs/smb/server/crypto_ctx.c @@ -121,7 +121,7 @@ static struct ksmbd_crypto_ctx *ksmbd_find_crypto_ctx(void) ctx_list.avail_ctx++; spin_unlock(&ctx_list.ctx_lock); - ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP); + ctx = kzalloc_obj(struct ksmbd_crypto_ctx, KSMBD_DEFAULT_GFP); if (!ctx) { spin_lock(&ctx_list.ctx_lock); ctx_list.avail_ctx--; @@ -226,7 +226,7 @@ int ksmbd_crypto_create(void) init_waitqueue_head(&ctx_list.ctx_wait); ctx_list.avail_ctx = 1; - ctx = kzalloc(sizeof(struct ksmbd_crypto_ctx), KSMBD_DEFAULT_GFP); + ctx = kzalloc_obj(struct ksmbd_crypto_ctx, KSMBD_DEFAULT_GFP); if (!ctx) return -ENOMEM; list_add(&ctx->list, &ctx_list.idle_ctx); diff --git a/fs/smb/server/ksmbd_work.c b/fs/smb/server/ksmbd_work.c index 4a71f46d7020..ab4958dc3eb0 100644 --- a/fs/smb/server/ksmbd_work.c +++ b/fs/smb/server/ksmbd_work.c @@ -28,8 +28,8 @@ struct ksmbd_work *ksmbd_alloc_work_struct(void) INIT_LIST_HEAD(&work->fp_entry); INIT_LIST_HEAD(&work->aux_read_list); work->iov_alloc_cnt = 4; - work->iov = kcalloc(work->iov_alloc_cnt, sizeof(struct kvec), - KSMBD_DEFAULT_GFP); + work->iov = kzalloc_objs(struct kvec, work->iov_alloc_cnt, + KSMBD_DEFAULT_GFP); if (!work->iov) { kmem_cache_free(work_cache, work); work = NULL; @@ -111,7 +111,7 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, if (aux_size) { need_iov_cnt++; - ar = kmalloc(sizeof(struct aux_read), KSMBD_DEFAULT_GFP); + ar = kmalloc_obj(struct aux_read, KSMBD_DEFAULT_GFP); if (!ar) return -ENOMEM; } diff --git a/fs/smb/server/mgmt/share_config.c b/fs/smb/server/mgmt/share_config.c index c9b1108d6e96..53f44ff4d376 100644 --- a/fs/smb/server/mgmt/share_config.c +++ b/fs/smb/server/mgmt/share_config.c @@ -102,7 +102,7 @@ static int parse_veto_list(struct ksmbd_share_config *share, if (!sz) break; - p = kzalloc(sizeof(struct ksmbd_veto_pattern), KSMBD_DEFAULT_GFP); + p = kzalloc_obj(struct ksmbd_veto_pattern, KSMBD_DEFAULT_GFP); if (!p) return -ENOMEM; @@ -150,7 +150,7 @@ static struct ksmbd_share_config *share_config_request(struct ksmbd_work *work, goto out; } - share = kzalloc(sizeof(struct ksmbd_share_config), KSMBD_DEFAULT_GFP); + share = kzalloc_obj(struct ksmbd_share_config, KSMBD_DEFAULT_GFP); if (!share) goto out; diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c index 57dd47ef688c..a72d7e42a6c2 100644 --- a/fs/smb/server/mgmt/tree_connect.c +++ b/fs/smb/server/mgmt/tree_connect.c @@ -32,8 +32,7 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name) if (!sc) return status; - tree_conn = kzalloc(sizeof(struct ksmbd_tree_connect), - KSMBD_DEFAULT_GFP); + tree_conn = kzalloc_obj(struct ksmbd_tree_connect, KSMBD_DEFAULT_GFP); if (!tree_conn) { status.ret = -ENOMEM; goto out_error; diff --git a/fs/smb/server/mgmt/user_config.c b/fs/smb/server/mgmt/user_config.c index 3267b86b8c16..a3183fe5c536 100644 --- a/fs/smb/server/mgmt/user_config.c +++ b/fs/smb/server/mgmt/user_config.c @@ -36,7 +36,7 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, { struct ksmbd_user *user; - user = kmalloc(sizeof(struct ksmbd_user), KSMBD_DEFAULT_GFP); + user = kmalloc_obj(struct ksmbd_user, KSMBD_DEFAULT_GFP); if (!user) return NULL; diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c index 957a12de6a9d..39be2d2be86c 100644 --- a/fs/smb/server/mgmt/user_session.c +++ b/fs/smb/server/mgmt/user_session.c @@ -322,7 +322,7 @@ int ksmbd_session_rpc_open(struct ksmbd_session *sess, char *rpc_name) if (!method) return -EINVAL; - entry = kzalloc(sizeof(struct ksmbd_session_rpc), KSMBD_DEFAULT_GFP); + entry = kzalloc_obj(struct ksmbd_session_rpc, KSMBD_DEFAULT_GFP); if (!entry) return -ENOMEM; @@ -579,7 +579,7 @@ struct preauth_session *ksmbd_preauth_session_alloc(struct ksmbd_conn *conn, { struct preauth_session *sess; - sess = kmalloc(sizeof(struct preauth_session), KSMBD_DEFAULT_GFP); + sess = kmalloc_obj(struct preauth_session, KSMBD_DEFAULT_GFP); if (!sess) return NULL; @@ -663,7 +663,7 @@ static struct ksmbd_session *__session_create(int protocol) if (protocol != CIFDS_SESSION_FLAG_SMB2) return NULL; - sess = kzalloc(sizeof(struct ksmbd_session), KSMBD_DEFAULT_GFP); + sess = kzalloc_obj(struct ksmbd_session, KSMBD_DEFAULT_GFP); if (!sess) return NULL; diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c index a5967ac46604..393a4ae47cc1 100644 --- a/fs/smb/server/oplock.c +++ b/fs/smb/server/oplock.c @@ -34,7 +34,7 @@ static struct oplock_info *alloc_opinfo(struct ksmbd_work *work, struct ksmbd_session *sess = work->sess; struct oplock_info *opinfo; - opinfo = kzalloc(sizeof(struct oplock_info), KSMBD_DEFAULT_GFP); + opinfo = kzalloc_obj(struct oplock_info, KSMBD_DEFAULT_GFP); if (!opinfo) return NULL; @@ -93,7 +93,7 @@ static int alloc_lease(struct oplock_info *opinfo, struct lease_ctx_info *lctx) { struct lease *lease; - lease = kmalloc(sizeof(struct lease), KSMBD_DEFAULT_GFP); + lease = kmalloc_obj(struct lease, KSMBD_DEFAULT_GFP); if (!lease) return -ENOMEM; @@ -120,7 +120,7 @@ static void free_lease(struct oplock_info *opinfo) kfree(lease); } -static void free_opinfo(struct oplock_info *opinfo) +static void __free_opinfo(struct oplock_info *opinfo) { if (opinfo->is_lease) free_lease(opinfo); @@ -129,6 +129,18 @@ static void free_opinfo(struct oplock_info *opinfo) kfree(opinfo); } +static void free_opinfo_rcu(struct rcu_head *rcu) +{ + struct oplock_info *opinfo = container_of(rcu, struct oplock_info, rcu); + + __free_opinfo(opinfo); +} + +static void free_opinfo(struct oplock_info *opinfo) +{ + call_rcu(&opinfo->rcu, free_opinfo_rcu); +} + struct oplock_info *opinfo_get(struct ksmbd_file *fp) { struct oplock_info *opinfo; @@ -176,9 +188,9 @@ void opinfo_put(struct oplock_info *opinfo) free_opinfo(opinfo); } -static void opinfo_add(struct oplock_info *opinfo) +static void opinfo_add(struct oplock_info *opinfo, struct ksmbd_file *fp) { - struct ksmbd_inode *ci = opinfo->o_fp->f_ci; + struct ksmbd_inode *ci = fp->f_ci; down_write(&ci->m_lock); list_add(&opinfo->op_entry, &ci->m_op_list); @@ -698,7 +710,7 @@ static int smb2_oplock_break_noti(struct oplock_info *opinfo) if (!work) return -ENOMEM; - br_info = kmalloc(sizeof(struct oplock_break_info), KSMBD_DEFAULT_GFP); + br_info = kmalloc_obj(struct oplock_break_info, KSMBD_DEFAULT_GFP); if (!br_info) { ksmbd_free_work_struct(work); return -ENOMEM; @@ -803,7 +815,7 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) if (!work) return -ENOMEM; - br_info = kmalloc(sizeof(struct lease_break_info), KSMBD_DEFAULT_GFP); + br_info = kmalloc_obj(struct lease_break_info, KSMBD_DEFAULT_GFP); if (!br_info) { ksmbd_free_work_struct(work); return -ENOMEM; @@ -1046,7 +1058,7 @@ static int add_lease_global_list(struct oplock_info *opinfo) } read_unlock(&lease_list_lock); - lb = kmalloc(sizeof(struct lease_table), KSMBD_DEFAULT_GFP); + lb = kmalloc_obj(struct lease_table, KSMBD_DEFAULT_GFP); if (!lb) return -ENOMEM; @@ -1123,10 +1135,12 @@ void smb_lazy_parent_lease_break_close(struct ksmbd_file *fp) rcu_read_lock(); opinfo = rcu_dereference(fp->f_opinfo); - rcu_read_unlock(); - if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) + if (!opinfo || !opinfo->is_lease || opinfo->o_lease->version != 2) { + rcu_read_unlock(); return; + } + rcu_read_unlock(); p_ci = ksmbd_inode_lookup_lock(fp->filp->f_path.dentry->d_parent); if (!p_ci) @@ -1277,20 +1291,21 @@ int smb_grant_oplock(struct ksmbd_work *work, int req_op_level, u64 pid, set_oplock_level(opinfo, req_op_level, lctx); out: - rcu_assign_pointer(fp->f_opinfo, opinfo); - opinfo->o_fp = fp; - opinfo_count_inc(fp); - opinfo_add(opinfo); + opinfo_add(opinfo, fp); + if (opinfo->is_lease) { err = add_lease_global_list(opinfo); if (err) goto err_out; } + rcu_assign_pointer(fp->f_opinfo, opinfo); + opinfo->o_fp = fp; + return 0; err_out: - free_opinfo(opinfo); + __free_opinfo(opinfo); return err; } @@ -1491,7 +1506,7 @@ struct lease_ctx_info *parse_lease_state(void *open_req) if (IS_ERR_OR_NULL(cc)) return NULL; - lreq = kzalloc(sizeof(struct lease_ctx_info), KSMBD_DEFAULT_GFP); + lreq = kzalloc_obj(struct lease_ctx_info, KSMBD_DEFAULT_GFP); if (!lreq) return NULL; diff --git a/fs/smb/server/oplock.h b/fs/smb/server/oplock.h index 9a56eaadd0dd..921e3199e4df 100644 --- a/fs/smb/server/oplock.h +++ b/fs/smb/server/oplock.h @@ -69,8 +69,9 @@ struct oplock_info { struct lease *o_lease; struct list_head op_entry; struct list_head lease_entry; - wait_queue_head_t oplock_q; /* Other server threads */ - wait_queue_head_t oplock_brk; /* oplock breaking wait */ + wait_queue_head_t oplock_q; /* Other server threads */ + wait_queue_head_t oplock_brk; /* oplock breaking wait */ + struct rcu_head rcu; }; struct lease_break_info { diff --git a/fs/smb/server/server.c b/fs/smb/server/server.c index c2c074346da1..422d9d978285 100644 --- a/fs/smb/server/server.c +++ b/fs/smb/server/server.c @@ -21,7 +21,6 @@ #include "mgmt/user_session.h" #include "crypto_ctx.h" #include "auth.h" -#include "misc.h" #include "stats.h" int ksmbd_debug_types; @@ -410,7 +409,7 @@ static int __queue_ctrl_work(int type) { struct server_ctrl_struct *ctrl; - ctrl = kmalloc(sizeof(struct server_ctrl_struct), KSMBD_DEFAULT_GFP); + ctrl = kmalloc_obj(struct server_ctrl_struct, KSMBD_DEFAULT_GFP); if (!ctrl) return -ENOMEM; diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index cbb31efdbaa2..9f7ff7491e9a 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -4,6 +4,7 @@ * Copyright (C) 2018 Samsung Electronics Co., Ltd. */ +#include #include #include #include @@ -1164,8 +1165,8 @@ int smb2_handle_negotiate(struct ksmbd_work *work) switch (conn->dialect) { case SMB311_PROT_ID: conn->preauth_info = - kzalloc(sizeof(struct preauth_integrity_info), - KSMBD_DEFAULT_GFP); + kzalloc_obj(struct preauth_integrity_info, + KSMBD_DEFAULT_GFP); if (!conn->preauth_info) { rc = -ENOMEM; rsp->hdr.Status = STATUS_INVALID_PARAMETER; @@ -1560,7 +1561,7 @@ static int ntlm_authenticate(struct ksmbd_work *work, if (conn->dialect >= SMB30_PROT_ID) { chann = lookup_chann_list(sess, conn); if (!chann) { - chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP); + chann = kmalloc_obj(struct channel, KSMBD_DEFAULT_GFP); if (!chann) return -ENOMEM; @@ -1655,7 +1656,7 @@ static int krb5_authenticate(struct ksmbd_work *work, if (conn->dialect >= SMB30_PROT_ID) { chann = lookup_chann_list(sess, conn); if (!chann) { - chann = kmalloc(sizeof(struct channel), KSMBD_DEFAULT_GFP); + chann = kmalloc_obj(struct channel, KSMBD_DEFAULT_GFP); if (!chann) return -ENOMEM; @@ -3011,13 +3012,14 @@ int smb2_open(struct ksmbd_work *work) goto err_out2; } + fp = dh_info.fp; + if (ksmbd_override_fsids(work)) { rc = -ENOMEM; ksmbd_put_durable_fd(dh_info.fp); goto err_out2; } - fp = dh_info.fp; file_info = FILE_OPENED; rc = ksmbd_vfs_getattr(&fp->filp->f_path, &stat); @@ -3615,10 +3617,8 @@ int smb2_open(struct ksmbd_work *work) reconnected_fp: rsp->StructureSize = cpu_to_le16(89); - rcu_read_lock(); - opinfo = rcu_dereference(fp->f_opinfo); + opinfo = opinfo_get(fp); rsp->OplockLevel = opinfo != NULL ? opinfo->level : 0; - rcu_read_unlock(); rsp->Flags = 0; rsp->CreateAction = cpu_to_le32(file_info); rsp->CreationTime = cpu_to_le64(fp->create_time); @@ -3659,6 +3659,7 @@ int smb2_open(struct ksmbd_work *work) next_ptr = &lease_ccontext->Next; next_off = conn->vals->create_lease_size; } + opinfo_put(opinfo); if (maximal_access_ctxt) { struct create_context *mxac_ccontext; @@ -6115,14 +6116,14 @@ static int smb2_create_link(struct ksmbd_work *work, rc = -EINVAL; ksmbd_debug(SMB, "cannot delete %s\n", link_name); - goto out; } } else { rc = -EEXIST; ksmbd_debug(SMB, "link already exists\n"); - goto out; } ksmbd_vfs_kern_path_end_removing(&path); + if (rc) + goto out; } rc = ksmbd_vfs_link(work, target_name, link_name); if (rc) @@ -7326,7 +7327,7 @@ static struct ksmbd_lock *smb2_lock_init(struct file_lock *flock, { struct ksmbd_lock *lock; - lock = kzalloc(sizeof(struct ksmbd_lock), KSMBD_DEFAULT_GFP); + lock = kzalloc_obj(struct ksmbd_lock, KSMBD_DEFAULT_GFP); if (!lock) return NULL; @@ -8880,7 +8881,7 @@ int smb2_check_sign_req(struct ksmbd_work *work) ksmbd_sign_smb2_pdu(work->conn, work->sess->sess_key, iov, 1, signature); - if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) { + if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) { pr_err("bad smb2 signature\n"); return 0; } @@ -8968,7 +8969,7 @@ int smb3_check_sign_req(struct ksmbd_work *work) if (ksmbd_sign_smb3_pdu(conn, signing_key, iov, 1, signature)) return 0; - if (memcmp(signature, signature_req, SMB2_SIGNATURE_SIZE)) { + if (crypto_memneq(signature, signature_req, SMB2_SIGNATURE_SIZE)) { pr_err("bad smb2 signature\n"); return 0; } diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h index 257c6d26df26..8b6eafb70dca 100644 --- a/fs/smb/server/smb2pdu.h +++ b/fs/smb/server/smb2pdu.h @@ -83,7 +83,10 @@ struct create_durable_rsp { } Data; } __packed; -/* equivalent of the contents of SMB3.1.1 POSIX open context response */ +/* + * See POSIX-SMB2 2.2.14.2.16 + * Link: https://gitlab.com/samba-team/smb3-posix-spec/-/blob/master/smb3_posix_extensions.md + */ struct create_posix_rsp { struct create_context_hdr ccontext; __u8 Name[16]; diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c index 05598d994a68..49c2abb29bf5 100644 --- a/fs/smb/server/smbacl.c +++ b/fs/smb/server/smbacl.c @@ -417,7 +417,7 @@ static void parse_dacl(struct mnt_idmap *idmap, return; } - ppace = kmalloc_array(num_aces, sizeof(struct smb_ace *), KSMBD_DEFAULT_GFP); + ppace = kmalloc_objs(struct smb_ace *, num_aces, KSMBD_DEFAULT_GFP); if (!ppace) { free_acl_state(&default_acl_state); free_acl_state(&acl_state); @@ -603,7 +603,7 @@ static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap, for (i = 0; i < fattr->cf_acls->a_count; i++, pace++) { int flags = 0; - sid = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); + sid = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP); if (!sid) break; @@ -670,7 +670,7 @@ static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap, pace = fattr->cf_dacls->a_entries; for (i = 0; i < fattr->cf_dacls->a_count; i++, pace++) { - sid = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); + sid = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP); if (!sid) break; @@ -930,7 +930,7 @@ int build_sec_desc(struct mnt_idmap *idmap, gid_t gid; unsigned int sid_type = SIDOWNER; - nowner_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); + nowner_sid_ptr = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP); if (!nowner_sid_ptr) return -ENOMEM; @@ -939,7 +939,7 @@ int build_sec_desc(struct mnt_idmap *idmap, sid_type = SIDUNIX_USER; id_to_sid(uid, sid_type, nowner_sid_ptr); - ngroup_sid_ptr = kmalloc(sizeof(struct smb_sid), KSMBD_DEFAULT_GFP); + ngroup_sid_ptr = kmalloc_obj(struct smb_sid, KSMBD_DEFAULT_GFP); if (!ngroup_sid_ptr) { kfree(nowner_sid_ptr); return -ENOMEM; diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c index fb36fb9d5214..188572491d53 100644 --- a/fs/smb/server/transport_rdma.c +++ b/fs/smb/server/transport_rdma.c @@ -411,7 +411,7 @@ static struct smb_direct_transport *alloc_transport(struct rdma_cm_id *cm_id) struct smbdirect_socket_parameters *sp; struct ksmbd_conn *conn; - t = kzalloc(sizeof(*t), KSMBD_DEFAULT_GFP); + t = kzalloc_obj(*t, KSMBD_DEFAULT_GFP); if (!t) return NULL; sc = &t->socket; @@ -1852,8 +1852,8 @@ static int smb_direct_rdma_xmit(struct smb_direct_transport *t, /* build rdma_rw_ctx for each descriptor */ desc_buf = buf; for (i = 0; i < desc_num; i++) { - msg = kzalloc(struct_size(msg, sg_list, SG_CHUNK_SIZE), - KSMBD_DEFAULT_GFP); + msg = kzalloc_flex(*msg, sg_list, SG_CHUNK_SIZE, + KSMBD_DEFAULT_GFP); if (!msg) { ret = -ENOMEM; goto out; @@ -2540,9 +2540,9 @@ static int smb_direct_prepare(struct ksmbd_transport *t) goto put; req = (struct smbdirect_negotiate_req *)recvmsg->packet; - sp->max_recv_size = min_t(int, sp->max_recv_size, + sp->max_recv_size = min_t(u32, sp->max_recv_size, le32_to_cpu(req->preferred_send_size)); - sp->max_send_size = min_t(int, sp->max_send_size, + sp->max_send_size = min_t(u32, sp->max_send_size, le32_to_cpu(req->max_receive_size)); sp->max_fragmented_send_size = le32_to_cpu(req->max_fragmented_size); @@ -2860,7 +2860,7 @@ static int smb_direct_ib_client_add(struct ib_device *ib_dev) if (!rdma_frwr_is_supported(&ib_dev->attrs)) return 0; - smb_dev = kzalloc(sizeof(*smb_dev), KSMBD_DEFAULT_GFP); + smb_dev = kzalloc_obj(*smb_dev, KSMBD_DEFAULT_GFP); if (!smb_dev) return -ENOMEM; smb_dev->ib_dev = ib_dev; diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c index 2436dabada95..7e29b06820e2 100644 --- a/fs/smb/server/transport_tcp.c +++ b/fs/smb/server/transport_tcp.c @@ -61,7 +61,7 @@ static struct tcp_transport *alloc_transport(struct socket *client_sk) struct tcp_transport *t; struct ksmbd_conn *conn; - t = kzalloc(sizeof(*t), KSMBD_DEFAULT_GFP); + t = kzalloc_obj(*t, KSMBD_DEFAULT_GFP); if (!t) return NULL; t->sock = client_sk; @@ -156,7 +156,7 @@ static struct kvec *get_conn_iovec(struct tcp_transport *t, unsigned int nr_segs return t->iov; /* not big enough -- allocate a new one and release the old */ - new_iov = kmalloc_array(nr_segs, sizeof(*new_iov), KSMBD_DEFAULT_GFP); + new_iov = kmalloc_objs(*new_iov, nr_segs, KSMBD_DEFAULT_GFP); if (new_iov) { kfree(t->iov); t->iov = new_iov; @@ -636,7 +636,7 @@ static struct interface *alloc_iface(char *ifname) if (!ifname) return NULL; - iface = kzalloc(sizeof(struct interface), KSMBD_DEFAULT_GFP); + iface = kzalloc_obj(struct interface, KSMBD_DEFAULT_GFP); if (!iface) { kfree(ifname); return NULL; diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c index fbdc854dba0f..d08973b288e5 100644 --- a/fs/smb/server/vfs.c +++ b/fs/smb/server/vfs.c @@ -1044,7 +1044,7 @@ static bool __dir_empty(struct dir_context *ctx, const char *name, int namlen, struct ksmbd_readdir_data *buf; buf = container_of(ctx, struct ksmbd_readdir_data, ctx); - if (!is_dot_dotdot(name, namlen)) + if (!name_is_dot_dotdot(name, namlen)) buf->dirent_count++; return !buf->dirent_count; diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index e302e403e55a..168f2dd7e200 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -87,11 +87,7 @@ static int proc_show_files(struct seq_file *m, void *v) rcu_read_lock(); opinfo = rcu_dereference(fp->f_opinfo); - rcu_read_unlock(); - - if (!opinfo) { - seq_printf(m, " %-15s", " "); - } else { + if (opinfo) { const struct ksmbd_const_name *const_names; int count; unsigned int level; @@ -105,8 +101,12 @@ static int proc_show_files(struct seq_file *m, void *v) count = ARRAY_SIZE(ksmbd_oplock_const_names); level = opinfo->level; } + rcu_read_unlock(); ksmbd_proc_show_const_name(m, " %-15s", const_names, count, level); + } else { + rcu_read_unlock(); + seq_printf(m, " %-15s", " "); } seq_printf(m, " %#010x %#010x %s\n", @@ -303,7 +303,7 @@ static struct ksmbd_inode *ksmbd_inode_get(struct ksmbd_file *fp) if (ci) return ci; - ci = kmalloc(sizeof(struct ksmbd_inode), KSMBD_DEFAULT_GFP); + ci = kmalloc_obj(struct ksmbd_inode, KSMBD_DEFAULT_GFP); if (!ci) return NULL; @@ -1126,7 +1126,7 @@ int ksmbd_reopen_durable_fd(struct ksmbd_work *work, struct ksmbd_file *fp) int ksmbd_init_file_table(struct ksmbd_file_table *ft) { - ft->idr = kzalloc(sizeof(struct idr), KSMBD_DEFAULT_GFP); + ft->idr = kzalloc_obj(struct idr, KSMBD_DEFAULT_GFP); if (!ft->idr) return -ENOMEM; diff --git a/fs/splice.c b/fs/splice.c index 5fb07c01936f..9d8f63e2fd1a 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -275,9 +275,8 @@ int splice_grow_spd(const struct pipe_inode_info *pipe, struct splice_pipe_desc if (max_usage <= PIPE_DEF_BUFFERS) return 0; - spd->pages = kmalloc_array(max_usage, sizeof(struct page *), GFP_KERNEL); - spd->partial = kmalloc_array(max_usage, sizeof(struct partial_page), - GFP_KERNEL); + spd->pages = kmalloc_objs(struct page *, max_usage); + spd->partial = kmalloc_objs(struct partial_page, max_usage); if (spd->pages && spd->partial) return 0; @@ -676,7 +675,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, if (!out->f_op->write_iter) return -EINVAL; - array = kcalloc(nbufs, sizeof(struct bio_vec), GFP_KERNEL); + array = kzalloc_objs(struct bio_vec, nbufs); if (unlikely(!array)) return -ENOMEM; @@ -697,8 +696,7 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, if (unlikely(nbufs < pipe->max_usage)) { kfree(array); nbufs = pipe->max_usage; - array = kcalloc(nbufs, sizeof(struct bio_vec), - GFP_KERNEL); + array = kzalloc_objs(struct bio_vec, nbufs); if (!array) { ret = -ENOMEM; break; diff --git a/fs/squashfs/block.c b/fs/squashfs/block.c index a05e3793f93a..2d5850168026 100644 --- a/fs/squashfs/block.c +++ b/fs/squashfs/block.c @@ -88,8 +88,8 @@ static int squashfs_bio_read_cached(struct bio *fullbio, int idx = 0; int err = 0; #ifdef CONFIG_SQUASHFS_COMP_CACHE_FULL - struct folio **cache_folios = kmalloc_array(page_count, - sizeof(*cache_folios), GFP_KERNEL | __GFP_ZERO); + struct folio **cache_folios = kmalloc_objs(*cache_folios, page_count, + GFP_KERNEL | __GFP_ZERO); #endif bio_for_each_folio_all(fi, fullbio) { diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c index 181260e72680..67abd4dff222 100644 --- a/fs/squashfs/cache.c +++ b/fs/squashfs/cache.c @@ -229,13 +229,13 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries, if (entries == 0) return NULL; - cache = kzalloc(sizeof(*cache), GFP_KERNEL); + cache = kzalloc_obj(*cache); if (cache == NULL) { ERROR("Failed to allocate %s cache\n", name); return ERR_PTR(-ENOMEM); } - cache->entry = kcalloc(entries, sizeof(*(cache->entry)), GFP_KERNEL); + cache->entry = kzalloc_objs(*(cache->entry), entries); if (cache->entry == NULL) { ERROR("Failed to allocate %s cache\n", name); goto cleanup; @@ -344,6 +344,9 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer, if (unlikely(length < 0)) return -EIO; + if (unlikely(*offset < 0 || *offset >= SQUASHFS_METADATA_SIZE)) + return -EIO; + while (length) { entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0); if (entry->error) { diff --git a/fs/squashfs/decompressor_multi.c b/fs/squashfs/decompressor_multi.c index 416c53eedbd1..5c1aede1eddb 100644 --- a/fs/squashfs/decompressor_multi.c +++ b/fs/squashfs/decompressor_multi.c @@ -65,7 +65,7 @@ static void *squashfs_decompressor_create(struct squashfs_sb_info *msblk, struct decomp_stream *decomp_strm = NULL; int err = -ENOMEM; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) goto out; @@ -80,7 +80,7 @@ static void *squashfs_decompressor_create(struct squashfs_sb_info *msblk, * we could always fall back to default decompressor and * file system works. */ - decomp_strm = kmalloc(sizeof(*decomp_strm), GFP_KERNEL); + decomp_strm = kmalloc_obj(*decomp_strm); if (!decomp_strm) goto out; @@ -148,7 +148,7 @@ static struct decomp_stream *get_decomp_stream(struct squashfs_sb_info *msblk, goto wait; /* Let's allocate new decomp */ - decomp_strm = kmalloc(sizeof(*decomp_strm), GFP_KERNEL); + decomp_strm = kmalloc_obj(*decomp_strm); if (!decomp_strm) goto wait; diff --git a/fs/squashfs/decompressor_single.c b/fs/squashfs/decompressor_single.c index 6f161887710b..48501ba55fce 100644 --- a/fs/squashfs/decompressor_single.c +++ b/fs/squashfs/decompressor_single.c @@ -30,7 +30,7 @@ static void *squashfs_decompressor_create(struct squashfs_sb_info *msblk, struct squashfs_stream *stream; int err = -ENOMEM; - stream = kmalloc(sizeof(*stream), GFP_KERNEL); + stream = kmalloc_obj(*stream); if (stream == NULL) goto out; diff --git a/fs/squashfs/file.c b/fs/squashfs/file.c index 4be92206e755..d83594ce91d2 100644 --- a/fs/squashfs/file.c +++ b/fs/squashfs/file.c @@ -103,8 +103,8 @@ static struct meta_index *empty_meta_index(struct inode *inode, int offset, * mount time but doing it here means it is allocated only * if a 'large' file is read. */ - msblk->meta_index = kcalloc(SQUASHFS_META_SLOTS, - sizeof(*(msblk->meta_index)), GFP_KERNEL); + msblk->meta_index = kzalloc_objs(*(msblk->meta_index), + SQUASHFS_META_SLOTS); if (msblk->meta_index == NULL) { ERROR("Failed to allocate meta_index\n"); goto failed; diff --git a/fs/squashfs/lz4_wrapper.c b/fs/squashfs/lz4_wrapper.c index 49797729f143..1646bbee290e 100644 --- a/fs/squashfs/lz4_wrapper.c +++ b/fs/squashfs/lz4_wrapper.c @@ -54,7 +54,7 @@ static void *lz4_init(struct squashfs_sb_info *msblk, void *buff) int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); struct squashfs_lz4 *stream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (stream == NULL) goto failed; stream->input = vmalloc(block_size); diff --git a/fs/squashfs/lzo_wrapper.c b/fs/squashfs/lzo_wrapper.c index d216aeefa865..be1df7a25046 100644 --- a/fs/squashfs/lzo_wrapper.c +++ b/fs/squashfs/lzo_wrapper.c @@ -29,7 +29,7 @@ static void *lzo_init(struct squashfs_sb_info *msblk, void *buff) { int block_size = max_t(int, msblk->block_size, SQUASHFS_METADATA_SIZE); - struct squashfs_lzo *stream = kzalloc(sizeof(*stream), GFP_KERNEL); + struct squashfs_lzo *stream = kzalloc_obj(*stream); if (stream == NULL) goto failed; stream->input = vmalloc(block_size); diff --git a/fs/squashfs/page_actor.c b/fs/squashfs/page_actor.c index 2b3e807d4dea..79b73e98abab 100644 --- a/fs/squashfs/page_actor.c +++ b/fs/squashfs/page_actor.c @@ -43,7 +43,7 @@ static void cache_finish_page(struct squashfs_page_actor *actor) struct squashfs_page_actor *squashfs_page_actor_init(void **buffer, int pages, int length) { - struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL); + struct squashfs_page_actor *actor = kmalloc_obj(*actor); if (actor == NULL) return NULL; @@ -110,7 +110,7 @@ static void direct_finish_page(struct squashfs_page_actor *actor) struct squashfs_page_actor *squashfs_page_actor_init_special(struct squashfs_sb_info *msblk, struct page **page, int pages, int length, loff_t start_index) { - struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL); + struct squashfs_page_actor *actor = kmalloc_obj(*actor); if (actor == NULL) return NULL; diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 4465cf05603a..5dabc5770f1b 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c @@ -196,7 +196,7 @@ static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) return -EINVAL; } - sb->s_fs_info = kzalloc(sizeof(*msblk), GFP_KERNEL); + sb->s_fs_info = kzalloc_obj(*msblk); if (sb->s_fs_info == NULL) { ERROR("Failed to allocate squashfs_sb_info\n"); return -ENOMEM; @@ -549,7 +549,7 @@ static int squashfs_init_fs_context(struct fs_context *fc) { struct squashfs_mount_opts *opts; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; diff --git a/fs/squashfs/xz_wrapper.c b/fs/squashfs/xz_wrapper.c index 6c49481a2f8c..0a4ff3ec9c8c 100644 --- a/fs/squashfs/xz_wrapper.c +++ b/fs/squashfs/xz_wrapper.c @@ -42,7 +42,7 @@ static void *squashfs_xz_comp_opts(struct squashfs_sb_info *msblk, struct comp_opts *opts; int err = 0, n; - opts = kmalloc(sizeof(*opts), GFP_KERNEL); + opts = kmalloc_obj(*opts); if (opts == NULL) { err = -ENOMEM; goto out2; @@ -84,7 +84,7 @@ static void *squashfs_xz_init(struct squashfs_sb_info *msblk, void *buff) struct squashfs_xz *stream; int err; - stream = kmalloc(sizeof(*stream), GFP_KERNEL); + stream = kmalloc_obj(*stream); if (stream == NULL) { err = -ENOMEM; goto failed; diff --git a/fs/squashfs/zlib_wrapper.c b/fs/squashfs/zlib_wrapper.c index cbb7afe7bc46..a29001311939 100644 --- a/fs/squashfs/zlib_wrapper.c +++ b/fs/squashfs/zlib_wrapper.c @@ -23,7 +23,7 @@ static void *zlib_init(struct squashfs_sb_info *dummy, void *buff) { - z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL); + z_stream *stream = kmalloc_obj(z_stream); if (stream == NULL) goto failed; stream->workspace = vmalloc(zlib_inflate_workspacesize()); diff --git a/fs/squashfs/zstd_wrapper.c b/fs/squashfs/zstd_wrapper.c index 0e407c4d8b3b..487fbc51d264 100644 --- a/fs/squashfs/zstd_wrapper.c +++ b/fs/squashfs/zstd_wrapper.c @@ -28,7 +28,7 @@ struct workspace { static void *zstd_init(struct squashfs_sb_info *msblk, void *buff) { - struct workspace *wksp = kmalloc(sizeof(*wksp), GFP_KERNEL); + struct workspace *wksp = kmalloc_obj(*wksp); if (wksp == NULL) goto failed; diff --git a/fs/super.c b/fs/super.c index 784b5297a7d7..378e81efe643 100644 --- a/fs/super.c +++ b/fs/super.c @@ -317,7 +317,7 @@ static void destroy_unused_super(struct super_block *s) static struct super_block *alloc_super(struct file_system_type *type, int flags, struct user_namespace *user_ns) { - struct super_block *s = kzalloc(sizeof(struct super_block), GFP_KERNEL); + struct super_block *s = kzalloc_obj(struct super_block); static const struct super_operations default_op; int i; @@ -1135,7 +1135,7 @@ void emergency_remount(void) { struct work_struct *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) { INIT_WORK(work, do_emergency_remount); schedule_work(work); @@ -1167,7 +1167,7 @@ void emergency_thaw_all(void) { struct work_struct *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) { INIT_WORK(work, do_thaw_all); schedule_work(work); diff --git a/fs/sync.c b/fs/sync.c index f310a550316f..942a60cfedfb 100644 --- a/fs/sync.c +++ b/fs/sync.c @@ -135,7 +135,7 @@ void emergency_sync(void) { struct work_struct *work; - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) { INIT_WORK(work, do_sync_work); schedule_work(work); diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index 98467bb76737..e65c60158a04 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c @@ -62,7 +62,7 @@ static int sysfs_init_fs_context(struct fs_context *fc) return -EPERM; } - kfc = kzalloc(sizeof(struct kernfs_fs_context), GFP_KERNEL); + kfc = kzalloc_obj(struct kernfs_fs_context); if (!kfc) return -ENOMEM; diff --git a/fs/timerfd.c b/fs/timerfd.c index 9fcea7860ddf..73104f36bcae 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -413,7 +413,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) !capable(CAP_WAKE_ALARM)) return -EPERM; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c index 61cbdafa2411..8e5ac464b328 100644 --- a/fs/tracefs/event_inode.c +++ b/fs/tracefs/event_inode.c @@ -191,8 +191,8 @@ static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry, /* Preallocate the children mode array if necessary */ if (!(dentry->d_inode->i_mode & S_IFDIR)) { if (!ei->entry_attrs) { - ei->entry_attrs = kcalloc(ei->nr_entries, sizeof(*ei->entry_attrs), - GFP_NOFS); + ei->entry_attrs = kzalloc_objs(*ei->entry_attrs, + ei->nr_entries, GFP_NOFS); if (!ei->entry_attrs) { ret = -ENOMEM; goto out; @@ -439,7 +439,7 @@ static inline struct eventfs_inode *init_ei(struct eventfs_inode *ei, const char static inline struct eventfs_inode *alloc_ei(const char *name) { - struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL); + struct eventfs_inode *ei = kzalloc_obj(*ei); struct eventfs_inode *result; if (!ei) @@ -454,7 +454,7 @@ static inline struct eventfs_inode *alloc_ei(const char *name) static inline struct eventfs_inode *alloc_root_ei(const char *name) { - struct eventfs_root_inode *rei = kzalloc(sizeof(*rei), GFP_KERNEL); + struct eventfs_root_inode *rei = kzalloc_obj(*rei); struct eventfs_inode *ei; if (!rei) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index d9d8932a7b9c..51c00c8fa175 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -522,7 +522,7 @@ static int tracefs_init_fs_context(struct fs_context *fc) { struct tracefs_fs_info *fsi; - fsi = kzalloc(sizeof(struct tracefs_fs_info), GFP_KERNEL); + fsi = kzalloc_obj(struct tracefs_fs_info); if (!fsi) return -ENOMEM; diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c index b01f382ce8db..160c16aa7b6e 100644 --- a/fs/ubifs/debug.c +++ b/fs/ubifs/debug.c @@ -1846,7 +1846,7 @@ static struct fsck_inode *add_inode(struct ubifs_info *c, return ERR_PTR(-EINVAL); } - fscki = kzalloc(sizeof(struct fsck_inode), GFP_NOFS); + fscki = kzalloc_obj(struct fsck_inode, GFP_NOFS); if (!fscki) return ERR_PTR(-ENOMEM); @@ -3035,7 +3035,7 @@ void ubifs_assert_failed(struct ubifs_info *c, const char *expr, */ int ubifs_debugging_init(struct ubifs_info *c) { - c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); + c->dbg = kzalloc_obj(struct ubifs_debug_info); if (!c->dbg) return -ENOMEM; diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index 3c3d3ad4fa6c..4c9f57f3b2ad 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1099,7 +1099,7 @@ static int ubifs_mknod(struct mnt_idmap *idmap, struct inode *dir, dbg_gen("dent '%pd' in dir ino %lu", dentry, dir->i_ino); if (S_ISBLK(mode) || S_ISCHR(mode)) { - dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); + dev = kmalloc_obj(union ubifs_dev_desc, GFP_NOFS); if (!dev) return -ENOMEM; devlen = ubifs_encode_dev(dev, rdev); @@ -1399,7 +1399,7 @@ static int do_rename(struct inode *old_dir, struct dentry *old_dentry, if (flags & RENAME_WHITEOUT) { union ubifs_dev_desc *dev = NULL; - dev = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); + dev = kmalloc_obj(union ubifs_dev_desc, GFP_NOFS); if (!dev) { err = -ENOMEM; goto out_release; @@ -1725,7 +1725,7 @@ static int ubifs_dir_open(struct inode *inode, struct file *file) { struct ubifs_dir_data *data; - data = kzalloc(sizeof(struct ubifs_dir_data), GFP_KERNEL); + data = kzalloc_obj(struct ubifs_dir_data); if (!data) return -ENOMEM; file->private_data = data; diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 3dc3ca1cd803..cd04755e792a 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -848,7 +848,7 @@ static int ubifs_bulk_read(struct folio *folio) if (mutex_trylock(&c->bu_mutex)) bu = &c->bu; else { - bu = kmalloc(sizeof(struct bu_info), GFP_NOFS | __GFP_NOWARN); + bu = kmalloc_obj(struct bu_info, GFP_NOFS | __GFP_NOWARN); if (!bu) goto out_unlock; diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index 3134d070fcc0..0bf08b7755b8 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c @@ -559,7 +559,7 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp) goto out; } - idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + idx_gc = kmalloc_obj(struct ubifs_gced_idx_leb, GFP_NOFS); if (!idx_gc) { err = -ENOMEM; goto out; @@ -916,7 +916,7 @@ int ubifs_gc_start_commit(struct ubifs_info *c) } if (!lp) break; - idx_gc = kmalloc(sizeof(struct ubifs_gced_idx_leb), GFP_NOFS); + idx_gc = kmalloc_obj(struct ubifs_gced_idx_leb, GFP_NOFS); if (!idx_gc) { err = -ENOMEM; goto out; diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c index b6ac9c4281ef..c6edcbf35ebc 100644 --- a/fs/ubifs/log.c +++ b/fs/ubifs/log.c @@ -167,7 +167,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs) struct ubifs_bud *bud; struct ubifs_ref_node *ref; - bud = kmalloc(sizeof(struct ubifs_bud), GFP_NOFS); + bud = kmalloc_obj(struct ubifs_bud, GFP_NOFS); if (!bud) return -ENOMEM; ref = kzalloc(c->ref_node_alsz, GFP_NOFS); @@ -574,7 +574,7 @@ static int done_already(struct rb_root *done_tree, int lnum) return 1; } - dr = kzalloc(sizeof(struct done_ref), GFP_NOFS); + dr = kzalloc_obj(struct done_ref, GFP_NOFS); if (!dr) return -ENOMEM; diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c index dde0aa3287f4..b3986705cfa0 100644 --- a/fs/ubifs/lpt.c +++ b/fs/ubifs/lpt.c @@ -624,9 +624,9 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first, if (IS_ERR(desc)) return PTR_ERR(desc); - lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_KERNEL); - pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_KERNEL); - nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_KERNEL); + lsave = kmalloc_objs(int, c->lsave_cnt); + pnode = kzalloc_obj(struct ubifs_pnode); + nnode = kzalloc_obj(struct ubifs_nnode); buf = vmalloc(c->leb_size); ltab = vmalloc_array(c->lpt_lebs, sizeof(struct ubifs_lpt_lprops)); @@ -1215,7 +1215,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) lnum = c->lpt_lnum; offs = c->lpt_offs; } - nnode = kzalloc(sizeof(struct ubifs_nnode), GFP_NOFS); + nnode = kzalloc_obj(struct ubifs_nnode, GFP_NOFS); if (!nnode) { err = -ENOMEM; goto out; @@ -1278,7 +1278,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip) branch = &parent->nbranch[iip]; lnum = branch->lnum; offs = branch->offs; - pnode = kzalloc(sizeof(struct ubifs_pnode), GFP_NOFS); + pnode = kzalloc_obj(struct ubifs_pnode, GFP_NOFS); if (!pnode) return -ENOMEM; @@ -1856,7 +1856,7 @@ static int lpt_init_wr(struct ubifs_info *c) return -ENOMEM; if (c->big_lpt) { - c->lsave = kmalloc_array(c->lsave_cnt, sizeof(int), GFP_NOFS); + c->lsave = kmalloc_objs(int, c->lsave_cnt, GFP_NOFS); if (!c->lsave) return -ENOMEM; err = read_lsave(c); @@ -2099,8 +2099,7 @@ int ubifs_lpt_scan_nolock(struct ubifs_info *c, int start_lnum, int end_lnum, return err; } - path = kmalloc_array(c->lpt_hght + 1, sizeof(struct lpt_scan_node), - GFP_NOFS); + path = kmalloc_objs(struct lpt_scan_node, c->lpt_hght + 1, GFP_NOFS); if (!path) return -ENOMEM; diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c index 5555dd740889..85e467646e4a 100644 --- a/fs/ubifs/orphan.c +++ b/fs/ubifs/orphan.c @@ -55,7 +55,7 @@ int ubifs_add_orphan(struct ubifs_info *c, ino_t inum) struct ubifs_orphan *orphan, *o; struct rb_node **p, *parent = NULL; - orphan = kzalloc(sizeof(struct ubifs_orphan), GFP_NOFS); + orphan = kzalloc_obj(struct ubifs_orphan, GFP_NOFS); if (!orphan) return -ENOMEM; orphan->inum = inum; @@ -758,7 +758,7 @@ static int dbg_ins_check_orphan(struct rb_root *root, ino_t inum) struct check_orphan *orphan, *o; struct rb_node **p, *parent = NULL; - orphan = kzalloc(sizeof(struct check_orphan), GFP_NOFS); + orphan = kzalloc_obj(struct check_orphan, GFP_NOFS); if (!orphan) return -ENOMEM; orphan->inum = inum; diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index b36dc9b032f4..5c9dbf0a0806 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c @@ -508,7 +508,7 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb, dbg_rcvry("need to fix LEB %d start %d endpt %d", lnum, start, sleb->endpt); - ucleb = kzalloc(sizeof(struct ubifs_unclean_leb), GFP_NOFS); + ucleb = kzalloc_obj(struct ubifs_unclean_leb, GFP_NOFS); if (!ucleb) return -ENOMEM; ucleb->lnum = lnum; @@ -1258,7 +1258,7 @@ static int add_ino(struct ubifs_info *c, ino_t inum, loff_t i_size, p = &(*p)->rb_right; } - e = kzalloc(sizeof(struct size_entry), GFP_KERNEL); + e = kzalloc_obj(struct size_entry); if (!e) return -ENOMEM; diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index a950c5f2560e..a9a568f4a868 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c @@ -393,7 +393,7 @@ static int insert_node(struct ubifs_info *c, int lnum, int offs, int len, if (key_inum(c, key) >= c->highest_inum) c->highest_inum = key_inum(c, key); - r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); + r = kzalloc_obj(struct replay_entry); if (!r) return -ENOMEM; @@ -443,7 +443,7 @@ static int insert_dent(struct ubifs_info *c, int lnum, int offs, int len, if (key_inum(c, key) >= c->highest_inum) c->highest_inum = key_inum(c, key); - r = kzalloc(sizeof(struct replay_entry), GFP_KERNEL); + r = kzalloc_obj(struct replay_entry); if (!r) return -ENOMEM; @@ -897,11 +897,11 @@ static int add_replay_bud(struct ubifs_info *c, int lnum, int offs, int jhead, dbg_mnt("add replay bud LEB %d:%d, head %d", lnum, offs, jhead); - bud = kmalloc(sizeof(struct ubifs_bud), GFP_KERNEL); + bud = kmalloc_obj(struct ubifs_bud); if (!bud) return -ENOMEM; - b = kmalloc(sizeof(struct bud_entry), GFP_KERNEL); + b = kmalloc_obj(struct bud_entry); if (!b) { err = -ENOMEM; goto out; diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 84a9157dcc32..cbff2d800e27 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c @@ -130,7 +130,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum, dbg_scan("scan LEB %d:%d", lnum, offs); - sleb = kzalloc(sizeof(struct ubifs_scan_leb), GFP_NOFS); + sleb = kzalloc_obj(struct ubifs_scan_leb, GFP_NOFS); if (!sleb) return ERR_PTR(-ENOMEM); @@ -185,7 +185,7 @@ int ubifs_add_snod(const struct ubifs_info *c, struct ubifs_scan_leb *sleb, struct ubifs_ino_node *ino = buf; struct ubifs_scan_node *snod; - snod = kmalloc(sizeof(struct ubifs_scan_node), GFP_NOFS); + snod = kmalloc_obj(struct ubifs_scan_node, GFP_NOFS); if (!snod) return -ENOMEM; diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index f453c37cee37..03bf924756ca 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -208,7 +208,7 @@ struct inode *ubifs_iget(struct super_block *sb, unsigned long inum) dev_t rdev; union ubifs_dev_desc *dev; - ui->data = kmalloc(sizeof(union ubifs_dev_desc), GFP_NOFS); + ui->data = kmalloc_obj(union ubifs_dev_desc, GFP_NOFS); if (!ui->data) { err = -ENOMEM; goto out_ino; @@ -819,8 +819,7 @@ static int alloc_wbufs(struct ubifs_info *c) { int i, err; - c->jheads = kcalloc(c->jhead_cnt, sizeof(struct ubifs_jhead), - GFP_KERNEL); + c->jheads = kzalloc_objs(struct ubifs_jhead, c->jhead_cnt); if (!c->jheads) return -ENOMEM; @@ -1246,8 +1245,7 @@ static int mount_ubifs(struct ubifs_info *c) * never exceed 64. */ err = -ENOMEM; - c->bottom_up_buf = kmalloc_array(BOTTOM_UP_HEIGHT, sizeof(int), - GFP_KERNEL); + c->bottom_up_buf = kmalloc_objs(int, BOTTOM_UP_HEIGHT); if (!c->bottom_up_buf) goto out_free; @@ -2083,7 +2081,7 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi) { struct ubifs_info *c; - c = kzalloc(sizeof(struct ubifs_info), GFP_KERNEL); + c = kzalloc_obj(struct ubifs_info); if (c) { spin_lock_init(&c->cnt_lock); spin_lock_init(&c->cs_lock); @@ -2336,7 +2334,7 @@ static int ubifs_init_fs_context(struct fs_context *fc) { struct ubifs_fs_context *ctx; - ctx = kzalloc(sizeof(struct ubifs_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct ubifs_fs_context); if (!ctx) return -ENOMEM; diff --git a/fs/ubifs/sysfs.c b/fs/ubifs/sysfs.c index aae32222f11b..dbf967dcf26e 100644 --- a/fs/ubifs/sysfs.c +++ b/fs/ubifs/sysfs.c @@ -93,7 +93,7 @@ int ubifs_sysfs_register(struct ubifs_info *c) int ret, n; char dfs_dir_name[UBIFS_DFS_DIR_LEN]; - c->stats = kzalloc(sizeof(struct ubifs_stats_info), GFP_KERNEL); + c->stats = kzalloc_obj(struct ubifs_stats_info); if (!c->stats) { ret = -ENOMEM; goto out_last; diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c index 33946b518148..694b08d27d7d 100644 --- a/fs/ubifs/tnc.c +++ b/fs/ubifs/tnc.c @@ -99,7 +99,7 @@ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs) { struct ubifs_old_idx *old_idx; - old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); + old_idx = kmalloc_obj(struct ubifs_old_idx, GFP_NOFS); if (unlikely(!old_idx)) return -ENOMEM; old_idx->lnum = lnum; @@ -294,7 +294,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c, if (zbr->len) { struct ubifs_old_idx *old_idx; - old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS); + old_idx = kmalloc_obj(struct ubifs_old_idx, GFP_NOFS); if (unlikely(!old_idx)) { err = -ENOMEM; goto out; @@ -1134,9 +1134,8 @@ static struct ubifs_znode *dirty_cow_bottom_up(struct ubifs_info *c, ubifs_assert(c, znode); if (c->zroot.znode->level > BOTTOM_UP_HEIGHT) { kfree(c->bottom_up_buf); - c->bottom_up_buf = kmalloc_array(c->zroot.znode->level, - sizeof(int), - GFP_NOFS); + c->bottom_up_buf = kmalloc_objs(int, c->zroot.znode->level, + GFP_NOFS); if (!c->bottom_up_buf) return ERR_PTR(-ENOMEM); path = c->bottom_up_buf; diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c index 7c43e0ccf6d4..7bf2672062a2 100644 --- a/fs/ubifs/tnc_commit.c +++ b/fs/ubifs/tnc_commit.c @@ -359,8 +359,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt) dbg_gc("%d znodes to write", cnt); - c->gap_lebs = kmalloc_array(c->lst.idx_lebs + 1, sizeof(int), - GFP_NOFS); + c->gap_lebs = kmalloc_objs(int, c->lst.idx_lebs + 1, GFP_NOFS); if (!c->gap_lebs) return -ENOMEM; @@ -692,7 +691,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt) dbg_cmt("need about %d empty LEBS for TNC commit", leb_cnt); if (!leb_cnt) return 0; - c->ilebs = kmalloc_array(leb_cnt, sizeof(int), GFP_NOFS); + c->ilebs = kmalloc_objs(int, leb_cnt, GFP_NOFS); if (!c->ilebs) return -ENOMEM; for (i = 0; i < leb_cnt; i++) { diff --git a/fs/udf/super.c b/fs/udf/super.c index b2f168b0a0d1..27f463fd1d89 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -270,7 +270,7 @@ static int udf_init_fs_context(struct fs_context *fc) { struct udf_options *uopt; - uopt = kzalloc(sizeof(*uopt), GFP_KERNEL); + uopt = kzalloc_obj(*uopt); if (!uopt) return -ENOMEM; @@ -320,7 +320,7 @@ static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count) { struct udf_sb_info *sbi = UDF_SB(sb); - sbi->s_partmaps = kcalloc(count, sizeof(*sbi->s_partmaps), GFP_KERNEL); + sbi->s_partmaps = kzalloc_objs(*sbi->s_partmaps, count); if (!sbi->s_partmaps) { sbi->s_partitions = 0; return -ENOMEM; @@ -1047,8 +1047,7 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) struct udf_bitmap *bitmap; int nr_groups = udf_compute_nr_groups(sb, index); - bitmap = kvzalloc(struct_size(bitmap, s_block_bitmap, nr_groups), - GFP_KERNEL); + bitmap = kvzalloc_flex(*bitmap, s_block_bitmap, nr_groups); if (!bitmap) return NULL; @@ -1697,7 +1696,7 @@ static struct udf_vds_record *handle_partition_descriptor( struct part_desc_seq_scan_data *new_loc; unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP); - new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL); + new_loc = kzalloc_objs(*new_loc, new_size); if (!new_loc) return ERR_PTR(-ENOMEM); memcpy(new_loc, data->part_descs_loc, @@ -1757,9 +1756,8 @@ static noinline int udf_process_sequence( memset(data.vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); data.size_part_descs = PART_DESC_ALLOC_STEP; data.num_part_descs = 0; - data.part_descs_loc = kcalloc(data.size_part_descs, - sizeof(*data.part_descs_loc), - GFP_KERNEL); + data.part_descs_loc = kzalloc_objs(*data.part_descs_loc, + data.size_part_descs); if (!data.part_descs_loc) return -ENOMEM; @@ -2158,7 +2156,7 @@ static int udf_fill_super(struct super_block *sb, struct fs_context *fc) bool lvid_open = false; int silent = fc->sb_flags & SB_SILENT; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 6e4585169f94..c4831a8b9b3f 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -483,8 +483,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) * Read cylinder group (we read only first fragment from block * at this time) and prepare internal data structures for cg caching. */ - sbi->s_ucg = kmalloc_array(uspi->s_ncg, sizeof(struct buffer_head *), - GFP_NOFS); + sbi->s_ucg = kmalloc_objs(struct buffer_head *, uspi->s_ncg, GFP_NOFS); if (!sbi->s_ucg) goto failed; for (i = 0; i < uspi->s_ncg; i++) @@ -503,7 +502,7 @@ static int ufs_read_cylinder_structures(struct super_block *sb) ufs_print_cylinder_stuff(sb, (struct ufs_cylinder_group *) sbi->s_ucg[i]->b_data); } for (i = 0; i < UFS_MAX_GROUP_LOADED; i++) { - if (!(sbi->s_ucpi[i] = kmalloc (sizeof(struct ufs_cg_private_info), GFP_NOFS))) + if (!(sbi->s_ucpi[i] = kmalloc_obj(struct ufs_cg_private_info, GFP_NOFS))) goto failed; sbi->s_cgno[i] = UFS_CGNO_EMPTY; } @@ -744,7 +743,7 @@ static int ufs_fill_super(struct super_block *sb, struct fs_context *fc) } #endif - sbi = kzalloc(sizeof(struct ufs_sb_info), GFP_KERNEL); + sbi = kzalloc_obj(struct ufs_sb_info); if (!sbi) goto failed_nomem; sb->s_fs_info = sbi; @@ -769,7 +768,7 @@ static int ufs_fill_super(struct super_block *sb, struct fs_context *fc) sbi->s_flavour = UFS_MOUNT_UFSTYPE_OLD; } - uspi = kzalloc(sizeof(struct ufs_sb_private_info), GFP_KERNEL); + uspi = kzalloc_obj(struct ufs_sb_private_info); sbi->s_uspi = uspi; if (!uspi) goto failed; @@ -1438,7 +1437,7 @@ static int ufs_init_fs_context(struct fs_context *fc) { struct ufs_fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/ufs/util.c b/fs/ufs/util.c index f0e906ab4ddd..034b1d82c355 100644 --- a/fs/ufs/util.c +++ b/fs/ufs/util.c @@ -27,7 +27,7 @@ struct ufs_buffer_head * _ubh_bread_ (struct ufs_sb_private_info * uspi, count = size >> uspi->s_fshift; if (count > UFS_MAXFRAG) return NULL; - ubh = kmalloc (sizeof (struct ufs_buffer_head), GFP_NOFS); + ubh = kmalloc_obj(struct ufs_buffer_head, GFP_NOFS); if (!ubh) return NULL; ubh->fragment = fragment; diff --git a/fs/unicode/utf8-core.c b/fs/unicode/utf8-core.c index 6fc9ab8667e6..543c60c12461 100644 --- a/fs/unicode/utf8-core.c +++ b/fs/unicode/utf8-core.c @@ -176,7 +176,7 @@ struct unicode_map *utf8_load(unsigned int version) { struct unicode_map *um; - um = kzalloc(sizeof(struct unicode_map), GFP_KERNEL); + um = kzalloc_obj(struct unicode_map); if (!um) return ERR_PTR(-ENOMEM); um->version = version; diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index c5ba1f4487bd..bdc84e5219cd 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -653,7 +653,7 @@ int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs) } if (!ctx) { - fctx = kmalloc(sizeof(*fctx), GFP_KERNEL); + fctx = kmalloc_obj(*fctx); if (!fctx) return -ENOMEM; @@ -840,7 +840,7 @@ int userfaultfd_unmap_prep(struct vm_area_struct *vma, unsigned long start, has_unmap_ctx(ctx, unmaps, start, end)) return 0; - unmap_ctx = kzalloc(sizeof(*unmap_ctx), GFP_KERNEL); + unmap_ctx = kzalloc_obj(*unmap_ctx); if (!unmap_ctx) return -ENOMEM; diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c index 111752010edb..7a7a3fbb2651 100644 --- a/fs/vboxsf/file.c +++ b/fs/vboxsf/file.c @@ -26,7 +26,7 @@ struct vboxsf_handle *vboxsf_create_sf_handle(struct inode *inode, struct vboxsf_inode *sf_i = VBOXSF_I(inode); struct vboxsf_handle *sf_handle; - sf_handle = kmalloc(sizeof(*sf_handle), GFP_KERNEL); + sf_handle = kmalloc_obj(*sf_handle); if (!sf_handle) return ERR_PTR(-ENOMEM); diff --git a/fs/vboxsf/super.c b/fs/vboxsf/super.c index 241647b060ee..a618cb093e00 100644 --- a/fs/vboxsf/super.c +++ b/fs/vboxsf/super.c @@ -122,7 +122,7 @@ static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc) if (!fc->source) return -EINVAL; - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; @@ -427,7 +427,7 @@ static int vboxsf_init_fs_context(struct fs_context *fc) { struct vboxsf_fs_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/fs/vboxsf/utils.c b/fs/vboxsf/utils.c index 9515bbf0b54c..440e8c50629d 100644 --- a/fs/vboxsf/utils.c +++ b/fs/vboxsf/utils.c @@ -478,7 +478,7 @@ static struct vboxsf_dir_buf *vboxsf_dir_buf_alloc(struct list_head *list) { struct vboxsf_dir_buf *b; - b = kmalloc(sizeof(*b), GFP_KERNEL); + b = kmalloc_obj(*b); if (!b) return NULL; @@ -507,7 +507,7 @@ struct vboxsf_dir_info *vboxsf_dir_info_alloc(void) { struct vboxsf_dir_info *p; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return NULL; diff --git a/fs/verity/Kconfig b/fs/verity/Kconfig index 76d1c5971b82..b20882963ffb 100644 --- a/fs/verity/Kconfig +++ b/fs/verity/Kconfig @@ -2,6 +2,9 @@ config FS_VERITY bool "FS Verity (read-only file-based authenticity protection)" + # Filesystems cache the Merkle tree at a 64K aligned offset in the + # pagecache. That approach assumes the page size is at most 64K. + depends on PAGE_SHIFT <= 16 select CRYPTO_HASH_INFO select CRYPTO_LIB_SHA256 select CRYPTO_LIB_SHA512 diff --git a/fs/verity/enable.c b/fs/verity/enable.c index c9448074cce1..42dfed1ce0ce 100644 --- a/fs/verity/enable.c +++ b/fs/verity/enable.c @@ -223,6 +223,8 @@ static int enable_verity(struct file *filp, if (err) goto out; + trace_fsverity_enable(inode, ¶ms); + /* * Start enabling verity on this file, serialized by the inode lock. * Fail if verity is already enabled or is already being enabled. @@ -265,6 +267,8 @@ static int enable_verity(struct file *filp, goto rollback; } + trace_fsverity_tree_done(inode, vi, ¶ms); + /* * Add the fsverity_info into the hash table before finishing the * initialization so that we don't have to undo the enabling when memory diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h index 2887cb849cec..6e6854c19078 100644 --- a/fs/verity/fsverity_private.h +++ b/fs/verity/fsverity_private.h @@ -163,4 +163,6 @@ static inline void fsverity_init_signature(void) void __init fsverity_init_workqueue(void); +#include + #endif /* _FSVERITY_PRIVATE_H */ diff --git a/fs/verity/init.c b/fs/verity/init.c index 6e8d33b50240..d65206608583 100644 --- a/fs/verity/init.c +++ b/fs/verity/init.c @@ -5,6 +5,7 @@ * Copyright 2019 Google LLC */ +#define CREATE_TRACE_POINTS #include "fsverity_private.h" #include diff --git a/fs/verity/verify.c b/fs/verity/verify.c index 31797f9b24d0..4004a1d42875 100644 --- a/fs/verity/verify.c +++ b/fs/verity/verify.c @@ -177,6 +177,9 @@ static bool verify_data_block(struct fsverity_info *vi, /* Byte offset of the wanted hash relative to @addr */ unsigned int hoffset; } hblocks[FS_VERITY_MAX_LEVELS]; + + trace_fsverity_verify_data_block(inode, params, data_pos); + /* * The index of the previous level's block within that level; also the * index of that block's hash within the current level. @@ -255,6 +258,9 @@ static bool verify_data_block(struct fsverity_info *vi, want_hash = _want_hash; kunmap_local(haddr); put_page(hpage); + trace_fsverity_merkle_hit(inode, data_pos, hblock_idx, + level, + hoffset >> params->log_digestsize); goto descend; } hblocks[level].page = hpage; @@ -273,6 +279,9 @@ static bool verify_data_block(struct fsverity_info *vi, unsigned long hblock_idx = hblocks[level - 1].index; unsigned int hoffset = hblocks[level - 1].hoffset; + trace_fsverity_verify_merkle_block(inode, hblock_idx, + level, hoffset >> params->log_digestsize); + fsverity_hash_block(params, haddr, real_hash); if (memcmp(want_hash, real_hash, hsize) != 0) goto corrupted; @@ -433,8 +442,8 @@ EXPORT_SYMBOL_GPL(fsverity_verify_blocks); * This is a helper function for use by the ->readahead() method of filesystems * that issue bios to read data directly into the page cache. Filesystems that * populate the page cache without issuing bios (e.g. non block-based - * filesystems) must instead call fsverity_verify_page() directly on each page. - * All filesystems must also call fsverity_verify_page() on holes. + * filesystems) must instead call fsverity_verify_blocks() directly. All + * filesystems must also call fsverity_verify_blocks() on holes. */ void fsverity_verify_bio(struct fsverity_info *vi, struct bio *bio) { diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c index 586918ed1cbf..bd8fbb40b49e 100644 --- a/fs/xfs/libxfs/xfs_ag.c +++ b/fs/xfs/libxfs/xfs_ag.c @@ -224,7 +224,7 @@ xfs_perag_alloc( struct xfs_perag *pag; int error; - pag = kzalloc(sizeof(*pag), GFP_KERNEL); + pag = kzalloc_obj(*pag); if (!pag) return -ENOMEM; @@ -872,6 +872,34 @@ xfs_ag_shrink_space( return err2; } +void +xfs_growfs_compute_deltas( + struct xfs_mount *mp, + xfs_rfsblock_t nb, + int64_t *deltap, + xfs_agnumber_t *nagcountp) +{ + xfs_rfsblock_t nb_div, nb_mod; + int64_t delta; + xfs_agnumber_t nagcount; + + nb_div = nb; + nb_mod = do_div(nb_div, mp->m_sb.sb_agblocks); + if (nb_mod && nb_mod >= XFS_MIN_AG_BLOCKS) + nb_div++; + else if (nb_mod) + nb = nb_div * mp->m_sb.sb_agblocks; + + if (nb_div > XFS_MAX_AGNUMBER + 1) { + nb_div = XFS_MAX_AGNUMBER + 1; + nb = nb_div * mp->m_sb.sb_agblocks; + } + nagcount = nb_div; + delta = nb - mp->m_sb.sb_dblocks; + *deltap = delta; + *nagcountp = nagcount; +} + /* * Extent the AG indicated by the @id by the length passed in */ diff --git a/fs/xfs/libxfs/xfs_ag.h b/fs/xfs/libxfs/xfs_ag.h index 1f24cfa27321..3cd4790768ff 100644 --- a/fs/xfs/libxfs/xfs_ag.h +++ b/fs/xfs/libxfs/xfs_ag.h @@ -331,6 +331,9 @@ struct aghdr_init_data { int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id); int xfs_ag_shrink_space(struct xfs_perag *pag, struct xfs_trans **tpp, xfs_extlen_t delta); +void +xfs_growfs_compute_deltas(struct xfs_mount *mp, xfs_rfsblock_t nb, + int64_t *deltap, xfs_agnumber_t *nagcountp); int xfs_ag_extend_space(struct xfs_perag *pag, struct xfs_trans *tp, xfs_extlen_t len); int xfs_ag_get_geometry(struct xfs_perag *pag, struct xfs_ag_geometry *ageo); diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c index 766631f0562e..09d4c17b3e7b 100644 --- a/fs/xfs/libxfs/xfs_da_btree.c +++ b/fs/xfs/libxfs/xfs_da_btree.c @@ -2716,12 +2716,8 @@ xfs_dabuf_map( * larger one that needs to be free by the caller. */ if (nirecs > 1) { - map = kzalloc(nirecs * sizeof(struct xfs_buf_map), - GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); - if (!map) { - error = -ENOMEM; - goto out_free_irecs; - } + map = kcalloc(nirecs, sizeof(struct xfs_buf_map), + GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); *mapp = map; } diff --git a/fs/xfs/libxfs/xfs_defer.c b/fs/xfs/libxfs/xfs_defer.c index c39e40dcb0b0..c6909716b041 100644 --- a/fs/xfs/libxfs/xfs_defer.c +++ b/fs/xfs/libxfs/xfs_defer.c @@ -809,7 +809,7 @@ xfs_defer_can_append( /* Paused items cannot absorb more work */ if (dfp->dfp_flags & XFS_DEFER_PAUSED) - return NULL; + return false; /* Already full? */ if (ops->max_items && dfp->dfp_count >= ops->max_items) @@ -982,7 +982,7 @@ xfs_defer_ops_capture( return ERR_PTR(error); /* Create an object to capture the defer ops. */ - dfc = kzalloc(sizeof(*dfc), GFP_KERNEL | __GFP_NOFAIL); + dfc = kzalloc_obj(*dfc, GFP_KERNEL | __GFP_NOFAIL); INIT_LIST_HEAD(&dfc->dfc_list); INIT_LIST_HEAD(&dfc->dfc_dfops); diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 107c1a5b8a96..495620cc001f 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -116,10 +116,10 @@ xfs_da_mount( ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT); ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE); - mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry), - GFP_KERNEL | __GFP_RETRY_MAYFAIL); - mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry), - GFP_KERNEL | __GFP_RETRY_MAYFAIL); + mp->m_dir_geo = kzalloc_obj(struct xfs_da_geometry, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); + mp->m_attr_geo = kzalloc_obj(struct xfs_da_geometry, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!mp->m_dir_geo || !mp->m_attr_geo) { kfree(mp->m_dir_geo); kfree(mp->m_attr_geo); @@ -248,7 +248,7 @@ xfs_dir_init( if (error) return error; - args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); + args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL); if (!args) return -ENOMEM; @@ -341,7 +341,7 @@ xfs_dir_createname( XFS_STATS_INC(dp->i_mount, xs_dir_create); } - args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); + args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL); if (!args) return -ENOMEM; @@ -437,8 +437,7 @@ xfs_dir_lookup( ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_lookup); - args = kzalloc(sizeof(*args), - GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); + args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); args->geo = dp->i_mount->m_dir_geo; args->name = name->name; args->namelen = name->len; @@ -503,7 +502,7 @@ xfs_dir_removename( ASSERT(S_ISDIR(VFS_I(dp)->i_mode)); XFS_STATS_INC(dp->i_mount, xs_dir_remove); - args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); + args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL); if (!args) return -ENOMEM; @@ -563,7 +562,7 @@ xfs_dir_replace( if (rval) return rval; - args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL); + args = kzalloc_obj(*args, GFP_KERNEL | __GFP_NOFAIL); if (!args) return -ENOMEM; diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index a017016e9075..3794e5412eba 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c @@ -268,6 +268,10 @@ xfs_inode_from_disk( } if (xfs_is_reflink_inode(ip)) xfs_ifork_init_cow(ip); + if (xfs_is_metadir_inode(ip)) { + XFS_STATS_DEC(ip->i_mount, xs_inodes_active); + XFS_STATS_INC(ip->i_mount, xs_inodes_meta); + } return 0; out_destroy_data_fork: diff --git a/fs/xfs/libxfs/xfs_metafile.c b/fs/xfs/libxfs/xfs_metafile.c index cf239f862212..71f004e9dc64 100644 --- a/fs/xfs/libxfs/xfs_metafile.c +++ b/fs/xfs/libxfs/xfs_metafile.c @@ -61,6 +61,9 @@ xfs_metafile_set_iflag( ip->i_diflags2 |= XFS_DIFLAG2_METADATA; ip->i_metatype = metafile_type; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + + XFS_STATS_DEC(ip->i_mount, xs_inodes_active); + XFS_STATS_INC(ip->i_mount, xs_inodes_meta); } /* Clear the metadata directory inode flag. */ @@ -74,6 +77,8 @@ xfs_metafile_clear_iflag( ip->i_diflags2 &= ~XFS_DIFLAG2_METADATA; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + XFS_STATS_INC(ip->i_mount, xs_inodes_active); + XFS_STATS_DEC(ip->i_mount, xs_inodes_meta); } /* diff --git a/fs/xfs/libxfs/xfs_ondisk.h b/fs/xfs/libxfs/xfs_ondisk.h index 2e9715cc1641..23cde1248f01 100644 --- a/fs/xfs/libxfs/xfs_ondisk.h +++ b/fs/xfs/libxfs/xfs_ondisk.h @@ -73,7 +73,7 @@ xfs_check_ondisk_structs(void) XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_free_hdr, 64); XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf, 64); XFS_CHECK_STRUCT_SIZE(struct xfs_dir3_leaf_hdr, 64); - XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_entry, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_entry, 8); XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_hdr, 32); XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_map, 4); XFS_CHECK_STRUCT_SIZE(struct xfs_attr_leaf_name_local, 4); @@ -116,7 +116,7 @@ xfs_check_ondisk_structs(void) XFS_CHECK_STRUCT_SIZE(struct xfs_da_intnode, 16); XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_entry, 8); XFS_CHECK_STRUCT_SIZE(struct xfs_da_node_hdr, 16); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free, 4); + XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free, 4); XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr, 16); XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, freetag, 0); XFS_CHECK_OFFSET(struct xfs_dir2_data_unused, length, 2); @@ -136,16 +136,7 @@ xfs_check_ondisk_structs(void) /* ondisk dir/attr structures from xfs/122 */ XFS_CHECK_STRUCT_SIZE(struct xfs_attr_sf_entry, 3); XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_free, 4); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_hdr, 16); XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_data_unused, 6); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free, 16); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_free_hdr, 16); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf, 16); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_entry, 8); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_hdr, 16); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_leaf_tail, 4); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_entry, 3); - XFS_CHECK_STRUCT_SIZE(struct xfs_dir2_sf_hdr, 10); /* log structures */ XFS_CHECK_STRUCT_SIZE(struct xfs_buf_log_format, 88); @@ -217,11 +208,6 @@ xfs_check_ondisk_structs(void) XFS_CHECK_OFFSET(struct xfs_dir3_free, hdr.hdr.magic, 0); XFS_CHECK_OFFSET(struct xfs_attr3_leafblock, hdr.info.hdr, 0); - XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat, 192); - XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers, 24); - XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req, 64); - XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req, 64); - /* * Make sure the incore inode timestamp range corresponds to hand * converted values based on the ondisk format specification. @@ -301,6 +287,40 @@ xfs_check_ondisk_structs(void) XFS_CHECK_SB_OFFSET(sb_pad, 281); XFS_CHECK_SB_OFFSET(sb_rtstart, 288); XFS_CHECK_SB_OFFSET(sb_rtreserved, 296); + + /* + * ioctl UABI + * + * Due to different padding/alignment requirements across + * different architectures, some structures are ommited from + * the size checks. In addition, structures with architecture + * dependent size fields are also ommited (e.g. __kernel_long_t). + */ + XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat, 192); + XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers, 24); + XFS_CHECK_STRUCT_SIZE(struct xfs_bulkstat_req, 64); + XFS_CHECK_STRUCT_SIZE(struct xfs_inumbers_req, 64); + XFS_CHECK_STRUCT_SIZE(struct dioattr, 12); + XFS_CHECK_STRUCT_SIZE(struct getbmap, 32); + XFS_CHECK_STRUCT_SIZE(struct getbmapx, 48); + XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist_cursor, 16); + XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_attrlist_ent, 4); + XFS_CHECK_STRUCT_SIZE(struct xfs_ag_geometry, 128); + XFS_CHECK_STRUCT_SIZE(struct xfs_rtgroup_geometry, 128); + XFS_CHECK_STRUCT_SIZE(struct xfs_error_injection, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_geom, 256); + XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_geom_v4, 112); + XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_counts, 32); + XFS_CHECK_STRUCT_SIZE(struct xfs_fsop_resblks, 16); + XFS_CHECK_STRUCT_SIZE(struct xfs_growfs_log, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_bulk_ireq, 64); + XFS_CHECK_STRUCT_SIZE(struct xfs_fs_eofblocks, 128); + XFS_CHECK_STRUCT_SIZE(struct xfs_fsid, 8); + XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_metadata, 64); + XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_vec, 16); + XFS_CHECK_STRUCT_SIZE(struct xfs_scrub_vec_head, 40); } #endif /* __XFS_ONDISK_H */ diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 915ec85530e7..40c7f0ff6cf3 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -2033,8 +2033,8 @@ xfs_refcount_recover_extent( return -EFSCORRUPTED; } - rr = kmalloc(sizeof(struct xfs_refcount_recovery), - GFP_KERNEL | __GFP_NOFAIL); + rr = kmalloc_obj(struct xfs_refcount_recovery, + GFP_KERNEL | __GFP_NOFAIL); INIT_LIST_HEAD(&rr->rr_list); xfs_refcount_btrec_to_irec(rec, &rr->rr_rrec); diff --git a/fs/xfs/libxfs/xfs_rtgroup.c b/fs/xfs/libxfs/xfs_rtgroup.c index 09328f2d1575..c85d50953218 100644 --- a/fs/xfs/libxfs/xfs_rtgroup.c +++ b/fs/xfs/libxfs/xfs_rtgroup.c @@ -98,7 +98,7 @@ xfs_rtgroup_alloc( struct xfs_rtgroup *rtg; int error; - rtg = kzalloc(sizeof(struct xfs_rtgroup), GFP_KERNEL); + rtg = kzalloc_obj(struct xfs_rtgroup); if (!rtg) return -ENOMEM; diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 38d16fe1f6d8..47322adb7690 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -1347,6 +1347,9 @@ xfs_log_sb( * feature was introduced. This counter can go negative due to the way * we handle nearly-lockless reservations, so we must use the _positive * variant here to avoid writing out nonsense frextents. + * + * RT groups are only supported on v5 file systems, which always + * have lazy SB counters. */ if (xfs_has_rtgroups(mp) && !xfs_has_zoned(mp)) { mp->m_sb.sb_frextents = diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index 7ffe4b0ef0f1..9ed053b5f061 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c @@ -816,8 +816,8 @@ xchk_agfl( xchk_block_set_corrupt(sc, sc->sa.agf_bp); goto out; } - sai.entries = kvcalloc(sai.agflcount, sizeof(xfs_agblock_t), - XCHK_GFP_FLAGS); + sai.entries = kvzalloc_objs(xfs_agblock_t, sai.agflcount, + XCHK_GFP_FLAGS); if (!sai.entries) { error = -ENOMEM; goto out; diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c index 15d58eedb387..ae9ed5f280d0 100644 --- a/fs/xfs/scrub/agheader_repair.c +++ b/fs/xfs/scrub/agheader_repair.c @@ -1719,7 +1719,7 @@ xrep_agi( if (!xfs_has_rmapbt(mp)) return -EOPNOTSUPP; - sc->buf = kzalloc(sizeof(struct xrep_agi), XCHK_GFP_FLAGS); + sc->buf = kzalloc_obj(struct xrep_agi, XCHK_GFP_FLAGS); if (!sc->buf) return -ENOMEM; ragi = sc->buf; diff --git a/fs/xfs/scrub/alloc_repair.c b/fs/xfs/scrub/alloc_repair.c index 5b4c2a39a155..dce6ab0429dc 100644 --- a/fs/xfs/scrub/alloc_repair.c +++ b/fs/xfs/scrub/alloc_repair.c @@ -856,7 +856,7 @@ xrep_allocbt( if (!xfs_has_rmapbt(mp)) return -EOPNOTSUPP; - ra = kzalloc(sizeof(struct xrep_abt), XCHK_GFP_FLAGS); + ra = kzalloc_obj(struct xrep_abt, XCHK_GFP_FLAGS); if (!ra) return -ENOMEM; ra->sc = sc; diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c index c3c122ea2d32..390ac2e11ee0 100644 --- a/fs/xfs/scrub/attr.c +++ b/fs/xfs/scrub/attr.c @@ -85,7 +85,7 @@ xchk_setup_xattr_buf( if (ab) goto resize_value; - ab = kvzalloc(sizeof(struct xchk_xattr_buf), XCHK_GFP_FLAGS); + ab = kvzalloc_obj(struct xchk_xattr_buf, XCHK_GFP_FLAGS); if (!ab) return -ENOMEM; sc->buf = ab; diff --git a/fs/xfs/scrub/attr_repair.c b/fs/xfs/scrub/attr_repair.c index a924b467a844..7d00a1ce0bac 100644 --- a/fs/xfs/scrub/attr_repair.c +++ b/fs/xfs/scrub/attr_repair.c @@ -1534,7 +1534,7 @@ xrep_xattr_setup_scan( int max_len; int error; - rx = kzalloc(sizeof(struct xrep_xattr), XCHK_GFP_FLAGS); + rx = kzalloc_obj(struct xrep_xattr, XCHK_GFP_FLAGS); if (!rx) return -ENOMEM; rx->sc = sc; diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c index 51f3171bc6c8..c7fa908d92b2 100644 --- a/fs/xfs/scrub/bitmap.c +++ b/fs/xfs/scrub/bitmap.c @@ -87,8 +87,8 @@ xbitmap64_clear( xbitmap64_tree_insert(bn, &bitmap->xb_root); /* add an extent */ - new_bn = kmalloc(sizeof(struct xbitmap64_node), - XCHK_GFP_FLAGS); + new_bn = kmalloc_obj(struct xbitmap64_node, + XCHK_GFP_FLAGS); if (!new_bn) return -ENOMEM; new_bn->bn_start = last + 1; @@ -164,7 +164,7 @@ xbitmap64_set( xbitmap64_tree_insert(right, &bitmap->xb_root); } else { /* add an extent */ - left = kmalloc(sizeof(struct xbitmap64_node), XCHK_GFP_FLAGS); + left = kmalloc_obj(struct xbitmap64_node, XCHK_GFP_FLAGS); if (!left) return -ENOMEM; left->bn_start = start; @@ -362,8 +362,8 @@ xbitmap32_clear( xbitmap32_tree_insert(bn, &bitmap->xb_root); /* add an extent */ - new_bn = kmalloc(sizeof(struct xbitmap32_node), - XCHK_GFP_FLAGS); + new_bn = kmalloc_obj(struct xbitmap32_node, + XCHK_GFP_FLAGS); if (!new_bn) return -ENOMEM; new_bn->bn_start = last + 1; @@ -439,7 +439,7 @@ xbitmap32_set( xbitmap32_tree_insert(right, &bitmap->xb_root); } else { /* add an extent */ - left = kmalloc(sizeof(struct xbitmap32_node), XCHK_GFP_FLAGS); + left = kmalloc_obj(struct xbitmap32_node, XCHK_GFP_FLAGS); if (!left) return -ENOMEM; left->bn_start = start; diff --git a/fs/xfs/scrub/bmap_repair.c b/fs/xfs/scrub/bmap_repair.c index 0a83d5845379..822a4af43833 100644 --- a/fs/xfs/scrub/bmap_repair.c +++ b/fs/xfs/scrub/bmap_repair.c @@ -933,7 +933,7 @@ xrep_bmap( if (error) return error; - rb = kzalloc(sizeof(struct xrep_bmap), XCHK_GFP_FLAGS); + rb = kzalloc_obj(struct xrep_bmap, XCHK_GFP_FLAGS); if (!rb) return -ENOMEM; rb->sc = sc; diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c index 1089b1f4c5df..786b1e7c4dc3 100644 --- a/fs/xfs/scrub/btree.c +++ b/fs/xfs/scrub/btree.c @@ -449,7 +449,7 @@ xchk_btree_check_owner( if (xfs_btree_is_bno(cur->bc_ops) || xfs_btree_is_rmap(cur->bc_ops)) { struct check_owner *co; - co = kmalloc(sizeof(struct check_owner), XCHK_GFP_FLAGS); + co = kmalloc_obj(struct check_owner, XCHK_GFP_FLAGS); if (!co) return -ENOMEM; diff --git a/fs/xfs/scrub/cow_repair.c b/fs/xfs/scrub/cow_repair.c index 33749cf43520..bffc4666ce60 100644 --- a/fs/xfs/scrub/cow_repair.c +++ b/fs/xfs/scrub/cow_repair.c @@ -685,7 +685,7 @@ xrep_bmap_cow( return 0; } - xc = kzalloc(sizeof(struct xrep_cow), XCHK_GFP_FLAGS); + xc = kzalloc_obj(struct xrep_cow, XCHK_GFP_FLAGS); if (!xc) return -ENOMEM; diff --git a/fs/xfs/scrub/dabtree.c b/fs/xfs/scrub/dabtree.c index 5858d4d5e279..1a71d36898b1 100644 --- a/fs/xfs/scrub/dabtree.c +++ b/fs/xfs/scrub/dabtree.c @@ -512,7 +512,7 @@ xchk_da_btree( return 0; /* Set up initial da state. */ - ds = kzalloc(sizeof(struct xchk_da_btree), XCHK_GFP_FLAGS); + ds = kzalloc_obj(struct xchk_da_btree, XCHK_GFP_FLAGS); if (!ds) return -ENOMEM; ds->dargs.dp = sc->ip; diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 91228623d016..e09724cd3725 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -1095,7 +1095,7 @@ xchk_directory( if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) return 0; - sd = kvzalloc(sizeof(struct xchk_dir), XCHK_GFP_FLAGS); + sd = kvzalloc_obj(struct xchk_dir, XCHK_GFP_FLAGS); if (!sd) return -ENOMEM; sd->sc = sc; diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c index f105e49f654b..23b80c54aa60 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -177,7 +177,7 @@ xrep_dir_teardown( rd->dir_names = NULL; if (rd->dir_entries) xfarray_destroy(rd->dir_entries); - rd->dir_names = NULL; + rd->dir_entries = NULL; } /* Set up for a directory repair. */ @@ -198,7 +198,7 @@ xrep_setup_directory( if (error) return error; - rd = kvzalloc(sizeof(struct xrep_dir), XCHK_GFP_FLAGS); + rd = kvzalloc_obj(struct xrep_dir, XCHK_GFP_FLAGS); if (!rd) return -ENOMEM; rd->sc = sc; diff --git a/fs/xfs/scrub/dirtree.c b/fs/xfs/scrub/dirtree.c index e95dc74f1145..143114718d75 100644 --- a/fs/xfs/scrub/dirtree.c +++ b/fs/xfs/scrub/dirtree.c @@ -106,7 +106,7 @@ xchk_setup_dirtree( return error; } - dl = kvzalloc(sizeof(struct xchk_dirtree), XCHK_GFP_FLAGS); + dl = kvzalloc_obj(struct xchk_dirtree, XCHK_GFP_FLAGS); if (!dl) return -ENOMEM; dl->sc = sc; @@ -238,7 +238,7 @@ xchk_dirtree_create_path( * Create a new xchk_path structure to remember this parent pointer * and record the first name step. */ - path = kmalloc(sizeof(struct xchk_dirpath), XCHK_GFP_FLAGS); + path = kmalloc_obj(struct xchk_dirpath, XCHK_GFP_FLAGS); if (!path) return -ENOMEM; diff --git a/fs/xfs/scrub/dirtree_repair.c b/fs/xfs/scrub/dirtree_repair.c index 019feaf0d606..bcfbbf5efc6c 100644 --- a/fs/xfs/scrub/dirtree_repair.c +++ b/fs/xfs/scrub/dirtree_repair.c @@ -567,7 +567,7 @@ xrep_dirtree_create_adoption_path( * Create a new xchk_path structure to remember this parent pointer * and record the first name step. */ - path = kmalloc(sizeof(struct xchk_dirpath), XCHK_GFP_FLAGS); + path = kmalloc_obj(struct xchk_dirpath, XCHK_GFP_FLAGS); if (!path) return -ENOMEM; diff --git a/fs/xfs/scrub/fscounters.c b/fs/xfs/scrub/fscounters.c index b35f65b537ba..916699f3da7b 100644 --- a/fs/xfs/scrub/fscounters.c +++ b/fs/xfs/scrub/fscounters.c @@ -207,7 +207,7 @@ xchk_setup_fscounters( if (!xfs_has_lazysbcount(sc->mp)) xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); - sc->buf = kzalloc(sizeof(struct xchk_fscounters), XCHK_GFP_FLAGS); + sc->buf = kzalloc_obj(struct xchk_fscounters, XCHK_GFP_FLAGS); if (!sc->buf) return -ENOMEM; sc->buf_cleanup = xchk_fscounters_cleanup; diff --git a/fs/xfs/scrub/ialloc_repair.c b/fs/xfs/scrub/ialloc_repair.c index 9b63b9d19e1b..608c7022ac15 100644 --- a/fs/xfs/scrub/ialloc_repair.c +++ b/fs/xfs/scrub/ialloc_repair.c @@ -804,7 +804,7 @@ xrep_iallocbt( if (!xfs_has_rmapbt(mp)) return -EOPNOTSUPP; - ri = kzalloc(sizeof(struct xrep_ibt), XCHK_GFP_FLAGS); + ri = kzalloc_obj(struct xrep_ibt, XCHK_GFP_FLAGS); if (!ri) return -ENOMEM; ri->sc = sc; diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c index bf182a18f115..9738b9ce3f2d 100644 --- a/fs/xfs/scrub/inode_repair.c +++ b/fs/xfs/scrub/inode_repair.c @@ -151,7 +151,7 @@ xrep_setup_inode( { struct xrep_inode *ri; - sc->buf = kzalloc(sizeof(struct xrep_inode), XCHK_GFP_FLAGS); + sc->buf = kzalloc_obj(struct xrep_inode, XCHK_GFP_FLAGS); if (!sc->buf) return -ENOMEM; diff --git a/fs/xfs/scrub/metapath.c b/fs/xfs/scrub/metapath.c index 3d9de59c1758..050b86eb12d3 100644 --- a/fs/xfs/scrub/metapath.c +++ b/fs/xfs/scrub/metapath.c @@ -102,7 +102,7 @@ xchk_setup_metapath_scan( return error; } - mpath = kzalloc(sizeof(struct xchk_metapath), XCHK_GFP_FLAGS); + mpath = kzalloc_obj(struct xchk_metapath, XCHK_GFP_FLAGS); if (!mpath) { kfree_const(path); return -ENOMEM; diff --git a/fs/xfs/scrub/newbt.c b/fs/xfs/scrub/newbt.c index 43e868f829aa..2e4981c1baf2 100644 --- a/fs/xfs/scrub/newbt.c +++ b/fs/xfs/scrub/newbt.c @@ -195,7 +195,7 @@ xrep_newbt_add_blocks( struct xrep_newbt_resv *resv; int error; - resv = kmalloc(sizeof(struct xrep_newbt_resv), XCHK_GFP_FLAGS); + resv = kmalloc_obj(struct xrep_newbt_resv, XCHK_GFP_FLAGS); if (!resv) return -ENOMEM; diff --git a/fs/xfs/scrub/nlinks.c b/fs/xfs/scrub/nlinks.c index e80fe7395d78..1e0effdb65a6 100644 --- a/fs/xfs/scrub/nlinks.c +++ b/fs/xfs/scrub/nlinks.c @@ -58,7 +58,7 @@ xchk_setup_nlinks( return error; } - xnc = kvzalloc(sizeof(struct xchk_nlink_ctrs), XCHK_GFP_FLAGS); + xnc = kvzalloc_obj(struct xchk_nlink_ctrs, XCHK_GFP_FLAGS); if (!xnc) return -ENOMEM; xnc->xname.name = xnc->namebuf; diff --git a/fs/xfs/scrub/orphanage.c b/fs/xfs/scrub/orphanage.c index 52a108f6d5f4..33c6db6b4498 100644 --- a/fs/xfs/scrub/orphanage.c +++ b/fs/xfs/scrub/orphanage.c @@ -442,6 +442,11 @@ xrep_adoption_check_dcache( return 0; d_child = try_lookup_noperm(&qname, d_orphanage); + if (IS_ERR(d_child)) { + dput(d_orphanage); + return PTR_ERR(d_child); + } + if (d_child) { trace_xrep_adoption_check_child(sc->mp, d_child); @@ -479,7 +484,7 @@ xrep_adoption_zap_dcache( return; d_child = try_lookup_noperm(&qname, d_orphanage); - while (d_child != NULL) { + while (!IS_ERR_OR_NULL(d_child)) { trace_xrep_adoption_invalidate_child(sc->mp, d_child); ASSERT(d_is_negative(d_child)); diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index 5a259570b154..931604fa1294 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -757,7 +757,7 @@ xchk_parent_pptr( struct xchk_pptrs *pp; int error; - pp = kvzalloc(sizeof(struct xchk_pptrs), XCHK_GFP_FLAGS); + pp = kvzalloc_obj(struct xchk_pptrs, XCHK_GFP_FLAGS); if (!pp) return -ENOMEM; pp->sc = sc; diff --git a/fs/xfs/scrub/parent_repair.c b/fs/xfs/scrub/parent_repair.c index 83a8205ae2f1..2ce0cefad362 100644 --- a/fs/xfs/scrub/parent_repair.c +++ b/fs/xfs/scrub/parent_repair.c @@ -217,7 +217,7 @@ xrep_setup_parent( xchk_fsgates_enable(sc, XCHK_FSGATES_DIRENTS); - rp = kvzalloc(sizeof(struct xrep_parent), XCHK_GFP_FLAGS); + rp = kvzalloc_obj(struct xrep_parent, XCHK_GFP_FLAGS); if (!rp) return -ENOMEM; rp->sc = sc; diff --git a/fs/xfs/scrub/quotacheck.c b/fs/xfs/scrub/quotacheck.c index e8cba19334a0..9ea014e2ecfd 100644 --- a/fs/xfs/scrub/quotacheck.c +++ b/fs/xfs/scrub/quotacheck.c @@ -86,7 +86,7 @@ xchk_setup_quotacheck( xchk_fsgates_enable(sc, XCHK_FSGATES_QUOTA); - sc->buf = kzalloc(sizeof(struct xqcheck), XCHK_GFP_FLAGS); + sc->buf = kzalloc_obj(struct xqcheck, XCHK_GFP_FLAGS); if (!sc->buf) return -ENOMEM; @@ -256,7 +256,7 @@ xqcheck_mod_live_ino_dqtrx( dqa = rhashtable_lookup_fast(&xqc->shadow_dquot_acct, &p->tx_id, xqcheck_dqacct_hash_params); if (!dqa) { - dqa = kzalloc(sizeof(struct xqcheck_dqacct), XCHK_GFP_FLAGS); + dqa = kzalloc_obj(struct xqcheck_dqacct, XCHK_GFP_FLAGS); if (!dqa) goto out_abort; diff --git a/fs/xfs/scrub/rcbag.c b/fs/xfs/scrub/rcbag.c index c1a97a073d92..8f3a10f7c908 100644 --- a/fs/xfs/scrub/rcbag.c +++ b/fs/xfs/scrub/rcbag.c @@ -36,7 +36,7 @@ rcbag_init( struct rcbag *bag; int error; - bag = kzalloc(sizeof(struct rcbag), XCHK_GFP_FLAGS); + bag = kzalloc_obj(struct rcbag, XCHK_GFP_FLAGS); if (!bag) return -ENOMEM; diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c index bf87025f24fc..4e1bf23e5b89 100644 --- a/fs/xfs/scrub/refcount.c +++ b/fs/xfs/scrub/refcount.c @@ -142,8 +142,7 @@ xchk_refcountbt_rmap_check( * is healthy each rmap_irec we see will be in agbno order * so we don't need insertion sort here. */ - frag = kmalloc(sizeof(struct xchk_refcnt_frag), - XCHK_GFP_FLAGS); + frag = kmalloc_obj(struct xchk_refcnt_frag, XCHK_GFP_FLAGS); if (!frag) return -ENOMEM; memcpy(&frag->rm, rec, sizeof(frag->rm)); diff --git a/fs/xfs/scrub/refcount_repair.c b/fs/xfs/scrub/refcount_repair.c index 507993e0fb0f..ca9c382005ff 100644 --- a/fs/xfs/scrub/refcount_repair.c +++ b/fs/xfs/scrub/refcount_repair.c @@ -704,7 +704,7 @@ xrep_refcountbt( if (!xfs_has_rmapbt(mp)) return -EOPNOTSUPP; - rr = kzalloc(sizeof(struct xrep_refc), XCHK_GFP_FLAGS); + rr = kzalloc_obj(struct xrep_refc, XCHK_GFP_FLAGS); if (!rr) return -ENOMEM; rr->sc = sc; diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index 2c25910e2903..0cd3eecd2ca5 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -548,7 +548,7 @@ xchk_rmapbt( struct xchk_rmap *cr; int error; - cr = kzalloc(sizeof(struct xchk_rmap), XCHK_GFP_FLAGS); + cr = kzalloc_obj(struct xchk_rmap, XCHK_GFP_FLAGS); if (!cr) return -ENOMEM; diff --git a/fs/xfs/scrub/rmap_repair.c b/fs/xfs/scrub/rmap_repair.c index ab7053e25e1c..6766df9922e8 100644 --- a/fs/xfs/scrub/rmap_repair.c +++ b/fs/xfs/scrub/rmap_repair.c @@ -172,7 +172,7 @@ xrep_setup_ag_rmapbt( if (error) return error; - rr = kzalloc(sizeof(struct xrep_rmap), XCHK_GFP_FLAGS); + rr = kzalloc_obj(struct xrep_rmap, XCHK_GFP_FLAGS); if (!rr) return -ENOMEM; diff --git a/fs/xfs/scrub/rtbitmap.c b/fs/xfs/scrub/rtbitmap.c index 4bcfd99cec17..b3a4972d423e 100644 --- a/fs/xfs/scrub/rtbitmap.c +++ b/fs/xfs/scrub/rtbitmap.c @@ -41,8 +41,8 @@ xchk_setup_rtbitmap( if (xchk_need_intent_drain(sc)) xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); - rtb = kzalloc(struct_size(rtb, words, xchk_rtbitmap_wordcnt(sc)), - XCHK_GFP_FLAGS); + rtb = kzalloc_flex(*rtb, words, xchk_rtbitmap_wordcnt(sc), + XCHK_GFP_FLAGS); if (!rtb) return -ENOMEM; sc->buf = rtb; diff --git a/fs/xfs/scrub/rtrefcount.c b/fs/xfs/scrub/rtrefcount.c index 8cfe2f120b6b..4951cc271788 100644 --- a/fs/xfs/scrub/rtrefcount.c +++ b/fs/xfs/scrub/rtrefcount.c @@ -156,8 +156,7 @@ xchk_rtrefcountbt_rmap_check( * is healthy each rmap_irec we see will be in agbno order * so we don't need insertion sort here. */ - frag = kmalloc(sizeof(struct xchk_rtrefcnt_frag), - XCHK_GFP_FLAGS); + frag = kmalloc_obj(struct xchk_rtrefcnt_frag, XCHK_GFP_FLAGS); if (!frag) return -ENOMEM; memcpy(&frag->rm, rec, sizeof(frag->rm)); diff --git a/fs/xfs/scrub/rtrefcount_repair.c b/fs/xfs/scrub/rtrefcount_repair.c index f713daf095fb..f165fb397647 100644 --- a/fs/xfs/scrub/rtrefcount_repair.c +++ b/fs/xfs/scrub/rtrefcount_repair.c @@ -709,7 +709,7 @@ xrep_rtrefcountbt( if (error) return error; - rr = kzalloc(sizeof(struct xrep_rtrefc), XCHK_GFP_FLAGS); + rr = kzalloc_obj(struct xrep_rtrefc, XCHK_GFP_FLAGS); if (!rr) return -ENOMEM; rr->sc = sc; diff --git a/fs/xfs/scrub/rtrmap_repair.c b/fs/xfs/scrub/rtrmap_repair.c index 4610d6d80648..f2d16ca8d251 100644 --- a/fs/xfs/scrub/rtrmap_repair.c +++ b/fs/xfs/scrub/rtrmap_repair.c @@ -111,7 +111,7 @@ xrep_setup_rtrmapbt( if (error) return error; - rr = kzalloc(sizeof(struct xrep_rtrmap), XCHK_GFP_FLAGS); + rr = kzalloc_obj(struct xrep_rtrmap, XCHK_GFP_FLAGS); if (!rr) return -ENOMEM; diff --git a/fs/xfs/scrub/rtsummary.c b/fs/xfs/scrub/rtsummary.c index b510e6bbbd3e..efce39d7a1ef 100644 --- a/fs/xfs/scrub/rtsummary.c +++ b/fs/xfs/scrub/rtsummary.c @@ -49,8 +49,7 @@ xchk_setup_rtsummary( if (xchk_need_intent_drain(sc)) xchk_fsgates_enable(sc, XCHK_FSGATES_DRAIN); - rts = kvzalloc(struct_size(rts, words, mp->m_blockwsize), - XCHK_GFP_FLAGS); + rts = kvzalloc_flex(*rts, words, mp->m_blockwsize, XCHK_GFP_FLAGS); if (!rts) return -ENOMEM; sc->buf = rts; diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index c1c6415f5055..27511a125b39 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -632,7 +632,7 @@ xchk_scrub_create_subord( { struct xfs_scrub_subord *sub; - sub = kzalloc(sizeof(*sub), XCHK_GFP_FLAGS); + sub = kzalloc_obj(*sub, XCHK_GFP_FLAGS); if (!sub) return NULL; @@ -680,7 +680,7 @@ xfs_scrub_metadata( if (error) goto out; - sc = kzalloc(sizeof(struct xfs_scrub), XCHK_GFP_FLAGS); + sc = kzalloc_obj(struct xfs_scrub, XCHK_GFP_FLAGS); if (!sc) { error = -ENOMEM; goto out; diff --git a/fs/xfs/scrub/stats.c b/fs/xfs/scrub/stats.c index 4efafc5ae966..ef3f6abdb706 100644 --- a/fs/xfs/scrub/stats.c +++ b/fs/xfs/scrub/stats.c @@ -389,7 +389,7 @@ xchk_mount_stats_alloc( struct xchk_stats *cs; int error; - cs = kvzalloc(sizeof(struct xchk_stats), GFP_KERNEL); + cs = kvzalloc_obj(struct xchk_stats); if (!cs) return -ENOMEM; diff --git a/fs/xfs/scrub/xfblob.c b/fs/xfs/scrub/xfblob.c index 96fc360312de..84237fb41ccb 100644 --- a/fs/xfs/scrub/xfblob.c +++ b/fs/xfs/scrub/xfblob.c @@ -41,7 +41,7 @@ xfblob_create( if (error) return error; - blob = kmalloc(sizeof(struct xfblob), XCHK_GFP_FLAGS); + blob = kmalloc_obj(struct xfblob, XCHK_GFP_FLAGS); if (!blob) { error = -ENOMEM; goto out_xfile; diff --git a/fs/xfs/scrub/xfile.c b/fs/xfs/scrub/xfile.c index 2998c9b62f4b..05581571854d 100644 --- a/fs/xfs/scrub/xfile.c +++ b/fs/xfs/scrub/xfile.c @@ -57,11 +57,12 @@ xfile_create( struct xfile *xf; int error; - xf = kmalloc(sizeof(struct xfile), XCHK_GFP_FLAGS); + xf = kmalloc_obj(struct xfile, XCHK_GFP_FLAGS); if (!xf) return -ENOMEM; - xf->file = shmem_kernel_file_setup(description, isize, VM_NORESERVE); + xf->file = shmem_kernel_file_setup(description, isize, + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(xf->file)) { error = PTR_ERR(xf->file); goto out_xfile; diff --git a/fs/xfs/xfs_bmap_item.c b/fs/xfs/xfs_bmap_item.c index e8775f254c89..b237a25d6045 100644 --- a/fs/xfs/xfs_bmap_item.c +++ b/fs/xfs/xfs_bmap_item.c @@ -245,7 +245,7 @@ xfs_bmap_update_diff_items( struct xfs_bmap_intent *ba = bi_entry(a); struct xfs_bmap_intent *bb = bi_entry(b); - return ba->bi_owner->i_ino - bb->bi_owner->i_ino; + return cmp_int(ba->bi_owner->i_ino, bb->bi_owner->i_ino); } /* Log bmap updates in the intent item. */ diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index db46883991de..d2f3c50d80e7 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -295,8 +295,8 @@ xfs_buf_alloc( if (nmaps == 1) bp->b_maps = &bp->__b_map; else - bp->b_maps = kcalloc(nmaps, sizeof(struct xfs_buf_map), - GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); + bp->b_maps = kzalloc_objs(struct xfs_buf_map, nmaps, + GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL); for (i = 0; i < nmaps; i++) { bp->b_maps[i].bm_bn = map[i].bm_bn; bp->b_maps[i].bm_len = map[i].bm_len; @@ -1799,7 +1799,7 @@ xfs_alloc_buftarg( #if defined(CONFIG_FS_DAX) && defined(CONFIG_MEMORY_FAILURE) ops = &xfs_dax_holder_operations; #endif - btp = kzalloc(sizeof(*btp), GFP_KERNEL | __GFP_NOFAIL); + btp = kzalloc_obj(*btp, GFP_KERNEL | __GFP_NOFAIL); btp->bt_mount = mp; btp->bt_file = bdev_file; diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c index 77ad071ebe78..02b95b89d1b5 100644 --- a/fs/xfs/xfs_buf_item_recover.c +++ b/fs/xfs/xfs_buf_item_recover.c @@ -90,7 +90,7 @@ xlog_add_buffer_cancelled( return false; } - bcp = kmalloc(sizeof(struct xfs_buf_cancel), GFP_KERNEL | __GFP_NOFAIL); + bcp = kmalloc_obj(struct xfs_buf_cancel, GFP_KERNEL | __GFP_NOFAIL); bcp->bc_blkno = blkno; bcp->bc_len = len; bcp->bc_refcount = 1; @@ -1180,8 +1180,7 @@ xlog_alloc_buf_cancel_table( ASSERT(log->l_buf_cancel_table == NULL); - p = kmalloc_array(XLOG_BC_TABLE_SIZE, sizeof(struct list_head), - GFP_KERNEL); + p = kmalloc_objs(struct list_head, XLOG_BC_TABLE_SIZE); if (!p) return -ENOMEM; diff --git a/fs/xfs/xfs_buf_mem.c b/fs/xfs/xfs_buf_mem.c index 0106da0a9f44..b0b3696bf599 100644 --- a/fs/xfs/xfs_buf_mem.c +++ b/fs/xfs/xfs_buf_mem.c @@ -58,11 +58,11 @@ xmbuf_alloc( struct xfs_buftarg *btp; int error; - btp = kzalloc(struct_size(btp, bt_cache, 1), GFP_KERNEL); + btp = kzalloc_flex(*btp, bt_cache, 1); if (!btp) return -ENOMEM; - file = shmem_kernel_file_setup(descr, 0, 0); + file = shmem_kernel_file_setup(descr, 0, EMPTY_VMA_FLAGS); if (IS_ERR(file)) { error = PTR_ERR(file); goto out_free_btp; diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index 31477a74b523..906221ffe9ba 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -349,7 +349,7 @@ xfs_trim_perag_extents( do { struct xfs_busy_extents *extents; - extents = kzalloc(sizeof(*extents), GFP_KERNEL); + extents = kzalloc_obj(*extents); if (!extents) { error = -ENOMEM; break; @@ -537,7 +537,7 @@ xfs_trim_gather_rtextent( return 0; } - busyp = kzalloc(sizeof(struct xfs_rtx_busy), GFP_KERNEL); + busyp = kzalloc_obj(struct xfs_rtx_busy); if (!busyp) return -ENOMEM; @@ -689,7 +689,7 @@ xfs_trim_rtgroup_extents( * trims the extents returned. */ do { - tr.extents = kzalloc(sizeof(*tr.extents), GFP_KERNEL); + tr.extents = kzalloc_obj(*tr.extents); if (!tr.extents) { error = -ENOMEM; break; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 2b208e2c5264..69e9bc588c8b 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -1439,9 +1439,15 @@ xfs_qm_dqflush( return 0; out_abort: + /* + * Shut down the log before removing the dquot item from the AIL. + * Otherwise, the log tail may advance past this item's LSN while + * log writes are still in progress, making these unflushed changes + * unrecoverable on the next mount. + */ + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); dqp->q_flags &= ~XFS_DQFLAG_DIRTY; xfs_trans_ail_delete(lip, 0); - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); xfs_dqfunlock(dqp); return error; } diff --git a/fs/xfs/xfs_extent_busy.c b/fs/xfs/xfs_extent_busy.c index cfecb2959472..3efdca3d675b 100644 --- a/fs/xfs/xfs_extent_busy.c +++ b/fs/xfs/xfs_extent_busy.c @@ -41,8 +41,7 @@ xfs_extent_busy_insert_list( struct rb_node **rbp; struct rb_node *parent = NULL; - new = kzalloc(sizeof(struct xfs_extent_busy), - GFP_KERNEL | __GFP_NOFAIL); + new = kzalloc_obj(struct xfs_extent_busy, GFP_KERNEL | __GFP_NOFAIL); new->group = xfs_group_hold(xg); new->bno = bno; new->length = len; @@ -718,7 +717,7 @@ xfs_extent_busy_alloc(void) { struct xfs_extent_busy_tree *eb; - eb = kzalloc(sizeof(*eb), GFP_KERNEL); + eb = kzalloc_obj(*eb); if (!eb) return NULL; spin_lock_init(&eb->eb_lock); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 43d088a3bceb..6246f34df9fd 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -2010,14 +2010,14 @@ xfs_file_mmap_prepare( * We don't support synchronous mappings for non-DAX files and * for DAX files if underneath dax_device is not synchronous. */ - if (!daxdev_mapping_supported(desc->vm_flags, file_inode(file), + if (!daxdev_mapping_supported(desc, file_inode(file), target->bt_daxdev)) return -EOPNOTSUPP; file_accessed(file); desc->vm_ops = &xfs_file_vm_ops; if (IS_DAX(inode)) - desc->vm_flags |= VM_HUGEPAGE; + vma_desc_set_flags(desc, VMA_HUGEPAGE_BIT); return 0; } diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c index 44e1b14069a3..32e641d76e92 100644 --- a/fs/xfs/xfs_filestream.c +++ b/fs/xfs/xfs_filestream.c @@ -308,7 +308,7 @@ xfs_filestream_create_association( * error for this failure - as long as we return a referenced AG, the * allocation can still go ahead just fine. */ - item = kmalloc(sizeof(*item), GFP_KERNEL | __GFP_RETRY_MAYFAIL); + item = kmalloc_obj(*item, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!item) goto out_put_fstrms; diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c index 098c2b50bc6f..b6a3bc9f143c 100644 --- a/fs/xfs/xfs_fsmap.c +++ b/fs/xfs/xfs_fsmap.c @@ -1326,11 +1326,11 @@ xfs_ioc_getfsmap( */ count = min_t(unsigned int, head.fmh_count, 131072 / sizeof(struct fsmap)); - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); + recs = kvzalloc_objs(struct fsmap, count); if (!recs) { count = min_t(unsigned int, head.fmh_count, PAGE_SIZE / sizeof(struct fsmap)); - recs = kvcalloc(count, sizeof(struct fsmap), GFP_KERNEL); + recs = kvzalloc_objs(struct fsmap, count); if (!recs) return -ENOMEM; } diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 17255c41786b..8d64d904d73c 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -95,18 +95,17 @@ xfs_growfs_data_private( struct xfs_growfs_data *in) /* growfs data input struct */ { xfs_agnumber_t oagcount = mp->m_sb.sb_agcount; + xfs_rfsblock_t nb = in->newblocks; struct xfs_buf *bp; int error; xfs_agnumber_t nagcount; xfs_agnumber_t nagimax = 0; - xfs_rfsblock_t nb, nb_div, nb_mod; int64_t delta; bool lastag_extended = false; struct xfs_trans *tp; struct aghdr_init_data id = {}; struct xfs_perag *last_pag; - nb = in->newblocks; error = xfs_sb_validate_fsb_count(&mp->m_sb, nb); if (error) return error; @@ -125,20 +124,8 @@ xfs_growfs_data_private( mp->m_sb.sb_rextsize); if (error) return error; + xfs_growfs_compute_deltas(mp, nb, &delta, &nagcount); - nb_div = nb; - nb_mod = do_div(nb_div, mp->m_sb.sb_agblocks); - if (nb_mod && nb_mod >= XFS_MIN_AG_BLOCKS) - nb_div++; - else if (nb_mod) - nb = nb_div * mp->m_sb.sb_agblocks; - - if (nb_div > XFS_MAX_AGNUMBER + 1) { - nb_div = XFS_MAX_AGNUMBER + 1; - nb = nb_div * mp->m_sb.sb_agblocks; - } - nagcount = nb_div; - delta = nb - mp->m_sb.sb_dblocks; /* * Reject filesystems with a single AG because they are not * supported, and reject a shrink operation that would cause a diff --git a/fs/xfs/xfs_health.c b/fs/xfs/xfs_health.c index 169123772cb3..239b843e83d4 100644 --- a/fs/xfs/xfs_health.c +++ b/fs/xfs/xfs_health.c @@ -314,6 +314,22 @@ xfs_rgno_mark_sick( xfs_rtgroup_put(rtg); } +static inline void xfs_inode_report_fserror(struct xfs_inode *ip) +{ + /* + * Do not report inodes being constructed or freed, or metadata inodes, + * to fsnotify. + */ + if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIM) || + xfs_is_internal_inode(ip)) { + fserror_report_metadata(ip->i_mount->m_super, -EFSCORRUPTED, + GFP_NOFS); + return; + } + + fserror_report_file_metadata(VFS_I(ip), -EFSCORRUPTED, GFP_NOFS); +} + /* Mark the unhealthy parts of an inode. */ void xfs_inode_mark_sick( @@ -339,7 +355,7 @@ xfs_inode_mark_sick( inode_state_clear(VFS_I(ip), I_DONTCACHE); spin_unlock(&VFS_I(ip)->i_lock); - fserror_report_file_metadata(VFS_I(ip), -EFSCORRUPTED, GFP_NOFS); + xfs_inode_report_fserror(ip); if (mask) xfs_healthmon_report_inode(ip, XFS_HEALTHMON_SICK, old_mask, mask); @@ -371,7 +387,7 @@ xfs_inode_mark_corrupt( inode_state_clear(VFS_I(ip), I_DONTCACHE); spin_unlock(&VFS_I(ip)->i_lock); - fserror_report_file_metadata(VFS_I(ip), -EFSCORRUPTED, GFP_NOFS); + xfs_inode_report_fserror(ip); if (mask) xfs_healthmon_report_inode(ip, XFS_HEALTHMON_CORRUPT, old_mask, mask); diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c index ca7352dcd182..26c325d34bd1 100644 --- a/fs/xfs/xfs_healthmon.c +++ b/fs/xfs/xfs_healthmon.c @@ -69,7 +69,7 @@ xfs_healthmon_get( struct xfs_healthmon *hm; rcu_read_lock(); - hm = mp->m_healthmon; + hm = rcu_dereference(mp->m_healthmon); if (hm && !refcount_inc_not_zero(&hm->ref)) hm = NULL; rcu_read_unlock(); @@ -110,13 +110,13 @@ xfs_healthmon_attach( struct xfs_healthmon *hm) { spin_lock(&xfs_healthmon_lock); - if (mp->m_healthmon != NULL) { + if (rcu_access_pointer(mp->m_healthmon) != NULL) { spin_unlock(&xfs_healthmon_lock); return -EEXIST; } refcount_inc(&hm->ref); - mp->m_healthmon = hm; + rcu_assign_pointer(mp->m_healthmon, hm); hm->mount_cookie = (uintptr_t)mp->m_super; spin_unlock(&xfs_healthmon_lock); @@ -128,16 +128,29 @@ STATIC void xfs_healthmon_detach( struct xfs_healthmon *hm) { + struct xfs_mount *mp; + spin_lock(&xfs_healthmon_lock); if (hm->mount_cookie == DETACHED_MOUNT_COOKIE) { spin_unlock(&xfs_healthmon_lock); return; } - XFS_M((struct super_block *)hm->mount_cookie)->m_healthmon = NULL; + mp = XFS_M((struct super_block *)hm->mount_cookie); + rcu_assign_pointer(mp->m_healthmon, NULL); hm->mount_cookie = DETACHED_MOUNT_COOKIE; spin_unlock(&xfs_healthmon_lock); + /* + * Wake up any readers that might remain. This can happen if unmount + * races with the healthmon fd owner entering ->read_iter, having + * already emptied the event queue. + * + * In the ->release case there shouldn't be any readers because the + * only users of the waiter are read and poll. + */ + wake_up_all(&hm->wait); + trace_xfs_healthmon_detach(hm); xfs_healthmon_put(hm); } @@ -1024,13 +1037,6 @@ xfs_healthmon_release( * process can create another health monitor file. */ xfs_healthmon_detach(hm); - - /* - * Wake up any readers that might be left. There shouldn't be any - * because the only users of the waiter are read and poll. - */ - wake_up_all(&hm->wait); - xfs_healthmon_put(hm); return 0; } @@ -1187,7 +1193,7 @@ xfs_ioc_health_monitor( if (!xfs_healthmon_validate(&hmo)) return -EINVAL; - hm = kzalloc(sizeof(*hm), GFP_KERNEL); + hm = kzalloc_obj(*hm); if (!hm) return -ENOMEM; hm->dev = mp->m_super->s_dev; @@ -1200,7 +1206,7 @@ xfs_ioc_health_monitor( hm->verbose = true; /* Queue up the first event that lets the client know we're running. */ - running_event = kzalloc(sizeof(struct xfs_healthmon_event), GFP_NOFS); + running_event = kzalloc_obj(struct xfs_healthmon_event, GFP_NOFS); if (!running_event) { ret = -ENOMEM; goto out_hm; @@ -1214,8 +1220,7 @@ xfs_ioc_health_monitor( * filesystem later. This is key for triggering fast exit of the * xfs_healer daemon. */ - hm->unmount_event = kzalloc(sizeof(struct xfs_healthmon_event), - GFP_NOFS); + hm->unmount_event = kzalloc_obj(struct xfs_healthmon_event, GFP_NOFS); if (!hm->unmount_event) { ret = -ENOMEM; goto out_hm; diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index dbaab4ae709f..2040a9292ee6 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -106,7 +106,7 @@ xfs_inode_alloc( mapping_set_folio_min_order(VFS_I(ip)->i_mapping, M_IGEO(mp)->min_folio_order); - XFS_STATS_INC(mp, vn_active); + XFS_STATS_INC(mp, xs_inodes_active); ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(ip->i_ino == 0); @@ -159,7 +159,6 @@ xfs_inode_free_callback( ASSERT(!test_bit(XFS_LI_IN_AIL, &ip->i_itemp->ili_item.li_flags)); xfs_inode_item_destroy(ip); - ip->i_itemp = NULL; } kmem_cache_free(xfs_inode_cache, ip); @@ -172,7 +171,10 @@ __xfs_inode_free( /* asserts to verify all state is correct here */ ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!ip->i_itemp || list_empty(&ip->i_itemp->ili_item.li_bio_list)); - XFS_STATS_DEC(ip->i_mount, vn_active); + if (xfs_is_metadir_inode(ip)) + XFS_STATS_DEC(ip->i_mount, xs_inodes_meta); + else + XFS_STATS_DEC(ip->i_mount, xs_inodes_active); call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); } @@ -636,6 +638,14 @@ xfs_iget_cache_miss( if (!ip) return -ENOMEM; + /* + * Set XFS_INEW as early as possible so that the health code won't pass + * the inode to the fserror code if the ondisk inode cannot be loaded. + * We're going to free the xfs_inode immediately if that happens, which + * would lead to UAF problems. + */ + xfs_iflags_set(ip, XFS_INEW); + error = xfs_imap(pag, tp, ip->i_ino, &ip->i_imap, flags); if (error) goto out_destroy; @@ -713,7 +723,6 @@ xfs_iget_cache_miss( ip->i_udquot = NULL; ip->i_gdquot = NULL; ip->i_pdquot = NULL; - xfs_iflags_set(ip, XFS_INEW); /* insert the new inode */ spin_lock(&pag->pag_ici_lock); @@ -2234,7 +2243,7 @@ xfs_inode_mark_reclaimable( struct xfs_mount *mp = ip->i_mount; bool need_inactive; - XFS_STATS_INC(mp, vn_reclaim); + XFS_STATS_INC(mp, xs_inode_mark_reclaimable); /* * We should never get here with any of the reclaim flags already set. diff --git a/fs/xfs/xfs_inode_item_recover.c b/fs/xfs/xfs_inode_item_recover.c index 5d93228783eb..b42106c4a9ef 100644 --- a/fs/xfs/xfs_inode_item_recover.c +++ b/fs/xfs/xfs_inode_item_recover.c @@ -329,8 +329,8 @@ xlog_recover_inode_commit_pass2( if (item->ri_buf[0].iov_len == sizeof(struct xfs_inode_log_format)) { in_f = item->ri_buf[0].iov_base; } else { - in_f = kmalloc(sizeof(struct xfs_inode_log_format), - GFP_KERNEL | __GFP_NOFAIL); + in_f = kmalloc_obj(struct xfs_inode_log_format, + GFP_KERNEL | __GFP_NOFAIL); need_free = 1; error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f); if (error) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 4eeda4d4e3ab..facffdc8dca8 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -896,7 +896,7 @@ xfs_ioc_getbmap( if (bmx.bmv_count >= INT_MAX / recsize) return -ENOMEM; - buf = kvcalloc(bmx.bmv_count, sizeof(*buf), GFP_KERNEL); + buf = kvzalloc_objs(*buf, bmx.bmv_count); if (!buf) return -ENOMEM; diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 9faff287f747..97f106d2b4cd 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c @@ -230,8 +230,8 @@ xfs_bulkstat_one( ASSERT(breq->icount == 1); - bc.buf = kzalloc(sizeof(struct xfs_bulkstat), - GFP_KERNEL | __GFP_RETRY_MAYFAIL); + bc.buf = kzalloc_obj(struct xfs_bulkstat, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!bc.buf) return -ENOMEM; @@ -317,8 +317,8 @@ xfs_bulkstat( if (xfs_bulkstat_already_done(breq->mp, breq->startino)) return 0; - bc.buf = kzalloc(sizeof(struct xfs_bulkstat), - GFP_KERNEL | __GFP_RETRY_MAYFAIL); + bc.buf = kzalloc_obj(struct xfs_bulkstat, + GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!bc.buf) return -ENOMEM; diff --git a/fs/xfs/xfs_iwalk.c b/fs/xfs/xfs_iwalk.c index ed4033006868..96a4cb3360bc 100644 --- a/fs/xfs/xfs_iwalk.c +++ b/fs/xfs/xfs_iwalk.c @@ -659,8 +659,8 @@ xfs_iwalk_threaded( if (xfs_pwork_ctl_want_abort(&pctl)) break; - iwag = kzalloc(sizeof(struct xfs_iwalk_ag), - GFP_KERNEL | __GFP_NOFAIL); + iwag = kzalloc_obj(struct xfs_iwalk_ag, + GFP_KERNEL | __GFP_NOFAIL); iwag->mp = mp; /* diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a26378ca247d..f807f8f4f705 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -1334,7 +1334,7 @@ xlog_alloc_log( int error = -ENOMEM; uint log2_size = 0; - log = kzalloc(sizeof(struct xlog), GFP_KERNEL | __GFP_RETRY_MAYFAIL); + log = kzalloc_obj(struct xlog, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!log) { xfs_warn(mp, "Log allocation failed: No memory!"); goto out; @@ -1357,6 +1357,8 @@ xlog_alloc_log( if (xfs_has_logv2(mp) && mp->m_sb.sb_logsunit > 1) log->l_iclog_roundoff = mp->m_sb.sb_logsunit; + else if (mp->m_sb.sb_logsectsize > 0) + log->l_iclog_roundoff = mp->m_sb.sb_logsectsize; else log->l_iclog_roundoff = BBSIZE; diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 566976b8fef3..edc368938f30 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -100,7 +100,7 @@ xlog_cil_ctx_alloc(void) { struct xfs_cil_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL | __GFP_NOFAIL); + ctx = kzalloc_obj(*ctx, GFP_KERNEL | __GFP_NOFAIL); INIT_LIST_HEAD(&ctx->committing); INIT_LIST_HEAD(&ctx->busy_extents.extent_list); INIT_LIST_HEAD(&ctx->log_items); @@ -2006,7 +2006,7 @@ xlog_cil_init( struct xlog_cil_pcp *cilpcp; int cpu; - cil = kzalloc(sizeof(*cil), GFP_KERNEL | __GFP_RETRY_MAYFAIL); + cil = kzalloc_obj(*cil, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!cil) return -ENOMEM; /* diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 935905743f94..09e6678ca487 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2092,8 +2092,7 @@ xlog_recover_add_item( { struct xlog_recover_item *item; - item = kzalloc(sizeof(struct xlog_recover_item), - GFP_KERNEL | __GFP_NOFAIL); + item = kzalloc_obj(struct xlog_recover_item, GFP_KERNEL | __GFP_NOFAIL); INIT_LIST_HEAD(&item->ri_list); list_add_tail(&item->ri_list, head); } @@ -2223,8 +2222,8 @@ xlog_recover_add_to_trans( } item->ri_total = in_f->ilf_size; - item->ri_buf = kcalloc(item->ri_total, sizeof(*item->ri_buf), - GFP_KERNEL | __GFP_NOFAIL); + item->ri_buf = kzalloc_objs(*item->ri_buf, item->ri_total, + GFP_KERNEL | __GFP_NOFAIL); } if (item->ri_total <= item->ri_cnt) { @@ -2367,7 +2366,7 @@ xlog_recover_ophdr_to_trans( * This is a new transaction so allocate a new recovery container to * hold the recovery ops that will follow. */ - trans = kzalloc(sizeof(struct xlog_recover), GFP_KERNEL | __GFP_NOFAIL); + trans = kzalloc_obj(struct xlog_recover, GFP_KERNEL | __GFP_NOFAIL); trans->r_log_tid = tid; trans->r_lsn = be64_to_cpu(rhead->h_lsn); INIT_LIST_HEAD(&trans->r_itemq); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 61c71128d171..ddd4028be8d6 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -345,7 +345,7 @@ typedef struct xfs_mount { struct xfs_hooks m_dir_update_hooks; /* Private data referring to a health monitor object. */ - struct xfs_healthmon *m_healthmon; + struct xfs_healthmon __rcu *m_healthmon; } xfs_mount_t; #define M_IGEO(mp) (&(mp)->m_ino_geo) diff --git a/fs/xfs/xfs_mru_cache.c b/fs/xfs/xfs_mru_cache.c index 4e417747688f..d61ec8cb126d 100644 --- a/fs/xfs/xfs_mru_cache.c +++ b/fs/xfs/xfs_mru_cache.c @@ -333,7 +333,7 @@ xfs_mru_cache_create( if (!(grp_time = msecs_to_jiffies(lifetime_ms) / grp_count)) return -EINVAL; - mru = kzalloc(sizeof(*mru), GFP_KERNEL | __GFP_NOFAIL); + mru = kzalloc_obj(*mru, GFP_KERNEL | __GFP_NOFAIL); if (!mru) return -ENOMEM; diff --git a/fs/xfs/xfs_notify_failure.c b/fs/xfs/xfs_notify_failure.c index 6be19fa1ebe2..64c8afb935c2 100644 --- a/fs/xfs/xfs_notify_failure.c +++ b/fs/xfs/xfs_notify_failure.c @@ -304,7 +304,7 @@ xfs_dax_notify_dev_failure( error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp); if (error) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } @@ -340,7 +340,7 @@ xfs_dax_notify_dev_failure( if (rtg) xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP); if (error) { - xfs_group_put(xg); + xfs_group_rele(xg); break; } } diff --git a/fs/xfs/xfs_platform.h b/fs/xfs/xfs_platform.h index 1e59bf94d1f2..59a33c60e0ca 100644 --- a/fs/xfs/xfs_platform.h +++ b/fs/xfs/xfs_platform.h @@ -235,6 +235,10 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count, #ifdef XFS_WARN +/* + * Please note that this ASSERT doesn't kill the kernel. It will if the kernel + * has panic_on_warn set. + */ #define ASSERT(expr) \ (likely(expr) ? (void)0 : asswarn(NULL, #expr, __FILE__, __LINE__)) @@ -245,6 +249,11 @@ int xfs_rw_bdev(struct block_device *bdev, sector_t sector, unsigned int count, #endif /* XFS_WARN */ #endif /* DEBUG */ +/* + * Use this to catch metadata corruptions that are not caught by block or + * structure verifiers. The reason is that the verifiers check corruptions only + * within the scope of the object being verified. + */ #define XFS_IS_CORRUPT(mp, expr) \ (unlikely(expr) ? xfs_corruption_error(#expr, XFS_ERRLEVEL_LOW, (mp), \ NULL, 0, __FILE__, __LINE__, \ diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index a3e7d4a107d4..7bd15d9e7fba 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -771,8 +771,8 @@ xfs_qm_init_quotainfo( ASSERT(XFS_IS_QUOTA_ON(mp)); - qinf = mp->m_quotainfo = kzalloc(sizeof(struct xfs_quotainfo), - GFP_KERNEL | __GFP_NOFAIL); + qinf = mp->m_quotainfo = kzalloc_obj(struct xfs_quotainfo, + GFP_KERNEL | __GFP_NOFAIL); error = list_lru_init(&qinf->qi_lru); if (error) diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c index 90a94a5b6f7e..153f3c378f9f 100644 --- a/fs/xfs/xfs_rtalloc.c +++ b/fs/xfs/xfs_rtalloc.c @@ -112,6 +112,10 @@ xfs_rtcopy_summary( error = xfs_rtget_summary(oargs, log, bbno, &sum); if (error) goto out; + if (XFS_IS_CORRUPT(oargs->mp, sum < 0)) { + error = -EFSCORRUPTED; + goto out; + } if (sum == 0) continue; error = xfs_rtmodify_summary(oargs, log, bbno, -sum); @@ -120,7 +124,6 @@ xfs_rtcopy_summary( error = xfs_rtmodify_summary(nargs, log, bbno, sum); if (error) goto out; - ASSERT(sum > 0); } } error = 0; @@ -1047,6 +1050,15 @@ xfs_growfs_rt_bmblock( */ xfs_trans_resv_calc(mp, &mp->m_resv); + /* + * Sync sb counters now to reflect the updated values. Lazy counters are + * not always updated and in order to avoid inconsistencies between + * frextents and rtextents, it is better to sync the counters. + */ + + if (xfs_has_lazysbcount(mp)) + xfs_log_sb(args.tp); + error = xfs_trans_commit(args.tp); if (error) goto out_free; @@ -1079,17 +1091,27 @@ xfs_last_rtgroup_extents( } /* - * Calculate the last rbmblock currently used. + * This will return the bitmap block number (indexed at 0) that will be + * extended/modified. There are 2 cases here: + * 1. The size of the rtg is such that it is a multiple of + * xfs_rtbitmap_rtx_per_rbmblock() i.e, an integral number of bitmap blocks + * are completely filled up. In this case, we should return + * 1 + (the last used bitmap block number). + * 2. The size of the rtg is not an multiple of xfs_rtbitmap_rtx_per_rbmblock(). + * Here we will return the block number of last used block number. In this + * case, we will modify the last used bitmap block to extend the size of the + * rtgroup. * * This also deals with the case where there were no rtextents before. */ static xfs_fileoff_t -xfs_last_rt_bmblock( +xfs_last_rt_bmblock_to_extend( struct xfs_rtgroup *rtg) { struct xfs_mount *mp = rtg_mount(rtg); xfs_rgnumber_t rgno = rtg_rgno(rtg); xfs_fileoff_t bmbno = 0; + unsigned int mod = 0; ASSERT(!mp->m_sb.sb_rgcount || rgno >= mp->m_sb.sb_rgcount - 1); @@ -1097,9 +1119,16 @@ xfs_last_rt_bmblock( xfs_rtxnum_t nrext = xfs_last_rtgroup_extents(mp); /* Also fill up the previous block if not entirely full. */ - bmbno = xfs_rtbitmap_blockcount_len(mp, nrext); - if (xfs_rtx_to_rbmword(mp, nrext) != 0) - bmbno--; + /* We are doing a -1 to convert it to a 0 based index */ + bmbno = xfs_rtbitmap_blockcount_len(mp, nrext) - 1; + div_u64_rem(nrext, xfs_rtbitmap_rtx_per_rbmblock(mp), &mod); + /* + * mod = 0 means that all the current blocks are full. So + * return the next block number to be used for the rtgroup + * growth. + */ + if (mod == 0) + bmbno++; } return bmbno; @@ -1204,7 +1233,8 @@ xfs_growfs_rtg( goto out_rele; } - for (bmbno = xfs_last_rt_bmblock(rtg); bmbno < bmblocks; bmbno++) { + for (bmbno = xfs_last_rt_bmblock_to_extend(rtg); bmbno < bmblocks; + bmbno++) { error = xfs_growfs_rt_bmblock(rtg, nrblocks, rextsize, bmbno); if (error) goto out_error; diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index 017db0361cd8..c13d600732c9 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -42,7 +42,7 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) { "xstrat", xfsstats_offset(xs_write_calls) }, { "rw", xfsstats_offset(xs_attr_get) }, { "attr", xfsstats_offset(xs_iflush_count)}, - { "icluster", xfsstats_offset(vn_active) }, + { "icluster", xfsstats_offset(xs_inodes_active) }, { "vnodes", xfsstats_offset(xb_get) }, { "buf", xfsstats_offset(xs_abtb_2) }, { "abtb2", xfsstats_offset(xs_abtc_2) }, @@ -59,7 +59,8 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) { "rtrefcntbt", xfsstats_offset(xs_qm_dqreclaims)}, /* we print both series of quota information together */ { "qm", xfsstats_offset(xs_gc_read_calls)}, - { "zoned", xfsstats_offset(__pad1)}, + { "zoned", xfsstats_offset(xs_inodes_meta)}, + { "metafile", xfsstats_offset(xs_xstrat_bytes)}, }; /* Loop over all stats groups */ @@ -99,16 +100,20 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) void xfs_stats_clearall(struct xfsstats __percpu *stats) { + uint32_t xs_inodes_active, xs_inodes_meta; int c; - uint32_t vn_active; xfs_notice(NULL, "Clearing xfsstats"); for_each_possible_cpu(c) { preempt_disable(); - /* save vn_active, it's a universal truth! */ - vn_active = per_cpu_ptr(stats, c)->s.vn_active; + /* + * Save the active / meta inode counters, as they are stateful. + */ + xs_inodes_active = per_cpu_ptr(stats, c)->s.xs_inodes_active; + xs_inodes_meta = per_cpu_ptr(stats, c)->s.xs_inodes_meta; memset(per_cpu_ptr(stats, c), 0, sizeof(*stats)); - per_cpu_ptr(stats, c)->s.vn_active = vn_active; + per_cpu_ptr(stats, c)->s.xs_inodes_active = xs_inodes_active; + per_cpu_ptr(stats, c)->s.xs_inodes_meta = xs_inodes_meta; preempt_enable(); } } diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 153d2381d0a8..57c32b86c358 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -100,14 +100,14 @@ struct __xfsstats { uint32_t xs_iflush_count; uint32_t xs_icluster_flushcnt; uint32_t xs_icluster_flushinode; - uint32_t vn_active; /* # vnodes not on free lists */ - uint32_t vn_alloc; /* # times vn_alloc called */ - uint32_t vn_get; /* # times vn_get called */ - uint32_t vn_hold; /* # times vn_hold called */ - uint32_t vn_rele; /* # times vn_rele called */ - uint32_t vn_reclaim; /* # times vn_reclaim called */ - uint32_t vn_remove; /* # times vn_remove called */ - uint32_t vn_free; /* # times vn_free called */ + uint32_t xs_inodes_active; + uint32_t __unused_vn_alloc; + uint32_t __unused_vn_get; + uint32_t __unused_vn_hold; + uint32_t xs_inode_destroy; + uint32_t xs_inode_destroy2; /* same as xs_inode_destroy */ + uint32_t xs_inode_mark_reclaimable; + uint32_t __unused_vn_free; uint32_t xb_get; uint32_t xb_create; uint32_t xb_get_locked; @@ -142,7 +142,8 @@ struct __xfsstats { uint32_t xs_gc_read_calls; uint32_t xs_gc_write_calls; uint32_t xs_gc_zone_reset_calls; - uint32_t __pad1; +/* Metafile counters */ + uint32_t xs_inodes_meta; /* Extra precision counters */ uint64_t xs_xstrat_bytes; uint64_t xs_write_bytes; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 8586f044a14b..f8de44443e81 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -712,8 +712,8 @@ xfs_fs_destroy_inode( trace_xfs_destroy_inode(ip); ASSERT(!rwsem_is_locked(&inode->i_rwsem)); - XFS_STATS_INC(ip->i_mount, vn_rele); - XFS_STATS_INC(ip->i_mount, vn_remove); + XFS_STATS_INC(ip->i_mount, xs_inode_destroy); + XFS_STATS_INC(ip->i_mount, xs_inode_destroy2); xfs_inode_mark_reclaimable(ip); } @@ -2235,12 +2235,11 @@ xfs_init_fs_context( struct xfs_mount *mp; int i; - mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL); + mp = kzalloc_obj(struct xfs_mount); if (!mp) return -ENOMEM; #ifdef DEBUG - mp->m_errortag = kcalloc(XFS_ERRTAG_MAX, sizeof(*mp->m_errortag), - GFP_KERNEL); + mp->m_errortag = kzalloc_objs(*mp->m_errortag, XFS_ERRTAG_MAX); if (!mp->m_errortag) { kfree(mp); return -ENOMEM; diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 363d7f88c2c6..923729af4206 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -922,8 +922,7 @@ xfs_trans_ail_init( { struct xfs_ail *ailp; - ailp = kzalloc(sizeof(struct xfs_ail), - GFP_KERNEL | __GFP_RETRY_MAYFAIL); + ailp = kzalloc_obj(struct xfs_ail, GFP_KERNEL | __GFP_RETRY_MAYFAIL); if (!ailp) return -ENOMEM; diff --git a/fs/xfs/xfs_verify_media.c b/fs/xfs/xfs_verify_media.c index 069cd371619d..8bbd4ec567f8 100644 --- a/fs/xfs/xfs_verify_media.c +++ b/fs/xfs/xfs_verify_media.c @@ -122,7 +122,7 @@ xfs_verify_report_losses( error = xfs_alloc_read_agf(pag, tp, 0, &agf_bp); if (error) { - xfs_perag_put(pag); + xfs_perag_rele(pag); break; } @@ -158,7 +158,7 @@ xfs_verify_report_losses( if (rtg) xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP); if (error) { - xfs_group_put(xg); + xfs_group_rele(xg); break; } } diff --git a/fs/xfs/xfs_zone_alloc.c b/fs/xfs/xfs_zone_alloc.c index b60952565737..e3d19b6dc64a 100644 --- a/fs/xfs/xfs_zone_alloc.c +++ b/fs/xfs/xfs_zone_alloc.c @@ -78,7 +78,7 @@ xfs_zone_account_reclaimable( struct xfs_rtgroup *rtg, uint32_t freed) { - struct xfs_group *xg = &rtg->rtg_group; + struct xfs_group *xg = rtg_group(rtg); struct xfs_mount *mp = rtg_mount(rtg); struct xfs_zone_info *zi = mp->m_zone_info; uint32_t used = rtg_rmap(rtg)->i_used_blocks; @@ -417,7 +417,7 @@ xfs_init_open_zone( { struct xfs_open_zone *oz; - oz = kzalloc(sizeof(*oz), GFP_NOFS | __GFP_NOFAIL); + oz = kzalloc_obj(*oz, GFP_NOFS | __GFP_NOFAIL); spin_lock_init(&oz->oz_alloc_lock); atomic_set(&oz->oz_ref, 1); oz->oz_rtg = rtg; @@ -759,7 +759,7 @@ xfs_zone_alloc_blocks( trace_xfs_zone_alloc_blocks(oz, allocated, count_fsb); - *sector = xfs_gbno_to_daddr(&rtg->rtg_group, 0); + *sector = xfs_gbno_to_daddr(rtg_group(rtg), 0); *is_seq = bdev_zone_is_seq(mp->m_rtdev_targp->bt_bdev, *sector); if (!*is_seq) *sector += XFS_FSB_TO_BB(mp, allocated); @@ -1080,7 +1080,7 @@ xfs_init_zone( if (write_pointer == 0) { /* zone is empty */ atomic_inc(&zi->zi_nr_free_zones); - xfs_group_set_mark(&rtg->rtg_group, XFS_RTG_FREE); + xfs_group_set_mark(rtg_group(rtg), XFS_RTG_FREE); iz->available += rtg_blocks(rtg); } else if (write_pointer < rtg_blocks(rtg)) { /* zone is open */ @@ -1196,7 +1196,7 @@ xfs_alloc_zone_info( struct xfs_zone_info *zi; int i; - zi = kzalloc(sizeof(*zi), GFP_KERNEL); + zi = kzalloc_obj(*zi); if (!zi) return NULL; INIT_LIST_HEAD(&zi->zi_open_zones); diff --git a/fs/xfs/xfs_zone_gc.c b/fs/xfs/xfs_zone_gc.c index 1f1f9fc973af..309f70098524 100644 --- a/fs/xfs/xfs_zone_gc.c +++ b/fs/xfs/xfs_zone_gc.c @@ -96,7 +96,6 @@ struct xfs_gc_bio { */ xfs_fsblock_t old_startblock; xfs_daddr_t new_daddr; - struct xfs_zone_scratch *scratch; /* Are we writing to a sequential write required zone? */ bool is_seq; @@ -199,11 +198,10 @@ xfs_zone_gc_data_alloc( struct xfs_zone_gc_data *data; int i; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return NULL; - data->iter.recs = kcalloc(XFS_ZONE_GC_RECS, sizeof(*data->iter.recs), - GFP_KERNEL); + data->iter.recs = kzalloc_objs(*data->iter.recs, XFS_ZONE_GC_RECS); if (!data->iter.recs) goto out_free_data; @@ -628,7 +626,7 @@ xfs_zone_gc_alloc_blocks( if (!*count_fsb) return NULL; - *daddr = xfs_gbno_to_daddr(&oz->oz_rtg->rtg_group, 0); + *daddr = xfs_gbno_to_daddr(rtg_group(oz->oz_rtg), 0); *is_seq = bdev_zone_is_seq(mp->m_rtdev_targp->bt_bdev, *daddr); if (!*is_seq) *daddr += XFS_FSB_TO_BB(mp, oz->oz_allocated); @@ -703,7 +701,7 @@ xfs_zone_gc_start_chunk( chunk->data = data; chunk->oz = oz; chunk->victim_rtg = iter->victim_rtg; - atomic_inc(&chunk->victim_rtg->rtg_group.xg_active_ref); + atomic_inc(&rtg_group(chunk->victim_rtg)->xg_active_ref); atomic_inc(&chunk->victim_rtg->rtg_gccount); bio->bi_iter.bi_sector = xfs_rtb_to_daddr(mp, chunk->old_startblock); @@ -780,7 +778,6 @@ xfs_zone_gc_split_write( ihold(VFS_I(chunk->ip)); split_chunk->ip = chunk->ip; split_chunk->is_seq = chunk->is_seq; - split_chunk->scratch = chunk->scratch; split_chunk->offset = chunk->offset; split_chunk->len = split_len; split_chunk->old_startblock = chunk->old_startblock; @@ -789,7 +786,7 @@ xfs_zone_gc_split_write( atomic_inc(&chunk->oz->oz_ref); split_chunk->victim_rtg = chunk->victim_rtg; - atomic_inc(&chunk->victim_rtg->rtg_group.xg_active_ref); + atomic_inc(&rtg_group(chunk->victim_rtg)->xg_active_ref); atomic_inc(&chunk->victim_rtg->rtg_gccount); chunk->offset += split_len; @@ -889,7 +886,7 @@ xfs_zone_gc_finish_reset( goto out; } - xfs_group_set_mark(&rtg->rtg_group, XFS_RTG_FREE); + xfs_group_set_mark(rtg_group(rtg), XFS_RTG_FREE); atomic_inc(&zi->zi_nr_free_zones); xfs_zoned_add_available(mp, rtg_blocks(rtg)); @@ -918,7 +915,7 @@ xfs_submit_zone_reset_bio( XFS_STATS_INC(mp, xs_gc_zone_reset_calls); - bio->bi_iter.bi_sector = xfs_gbno_to_daddr(&rtg->rtg_group, 0); + bio->bi_iter.bi_sector = xfs_gbno_to_daddr(rtg_group(rtg), 0); if (!bdev_zone_is_seq(bio->bi_bdev, bio->bi_iter.bi_sector)) { /* * Also use the bio to drive the state machine when neither diff --git a/fs/zonefs/file.c b/fs/zonefs/file.c index c1e5e30e90a0..8a7161fc49e5 100644 --- a/fs/zonefs/file.c +++ b/fs/zonefs/file.c @@ -333,7 +333,8 @@ static int zonefs_file_mmap_prepare(struct vm_area_desc *desc) * ordering between msync() and page cache writeback. */ if (zonefs_inode_is_seq(file_inode(file)) && - (desc->vm_flags & VM_SHARED) && (desc->vm_flags & VM_MAYWRITE)) + vma_desc_test_flags(desc, VMA_SHARED_BIT) && + vma_desc_test_flags(desc, VMA_MAYWRITE_BIT)) return -EINVAL; file_accessed(file); diff --git a/fs/zonefs/super.c b/fs/zonefs/super.c index 086a31269198..e83b2ec5e49f 100644 --- a/fs/zonefs/super.c +++ b/fs/zonefs/super.c @@ -903,8 +903,7 @@ static int zonefs_get_zone_info(struct zonefs_zone_data *zd) struct block_device *bdev = zd->sb->s_bdev; int ret; - zd->zones = kvcalloc(bdev_nr_zones(bdev), sizeof(struct blk_zone), - GFP_KERNEL); + zd->zones = kvzalloc_objs(struct blk_zone, bdev_nr_zones(bdev)); if (!zd->zones) return -ENOMEM; @@ -948,8 +947,7 @@ static int zonefs_init_zgroup(struct super_block *sb, if (!zgroup->g_nr_zones) return 0; - zgroup->g_zones = kvcalloc(zgroup->g_nr_zones, - sizeof(struct zonefs_zone), GFP_KERNEL); + zgroup->g_zones = kvzalloc_objs(struct zonefs_zone, zgroup->g_nr_zones); if (!zgroup->g_zones) return -ENOMEM; @@ -1243,7 +1241,7 @@ static int zonefs_fill_super(struct super_block *sb, struct fs_context *fc) * ZONEFS_F_AGGRCNV which increases the maximum file size of a file * beyond the zone size is taken into account. */ - sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + sbi = kzalloc_obj(*sbi); if (!sbi) return -ENOMEM; @@ -1388,7 +1386,7 @@ static int zonefs_init_fs_context(struct fs_context *fc) { struct zonefs_context *ctx; - ctx = kzalloc(sizeof(struct zonefs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct zonefs_context); if (!ctx) return -ENOMEM; ctx->s_mount_opts = ZONEFS_MNTOPT_ERRORS_RO; diff --git a/include/acpi/pcc.h b/include/acpi/pcc.h index 9af3b502f839..840bfc95bae3 100644 --- a/include/acpi/pcc.h +++ b/include/acpi/pcc.h @@ -17,35 +17,6 @@ struct pcc_mbox_chan { u32 latency; u32 max_access_rate; u16 min_turnaround_time; - - /* Set to true to indicate that the mailbox should manage - * writing the dat to the shared buffer. This differs from - * the case where the drivesr are writing to the buffer and - * using send_data only to ring the doorbell. If this flag - * is set, then the void * data parameter of send_data must - * point to a kernel-memory buffer formatted in accordance with - * the PCC specification. - * - * The active buffer management will include reading the - * notify_on_completion flag, and will then - * call mbox_chan_txdone when the acknowledgment interrupt is - * received. - */ - bool manage_writes; - - /* Optional callback that allows the driver - * to allocate the memory used for receiving - * messages. The return value is the location - * inside the buffer where the mailbox should write the data. - */ - void *(*rx_alloc)(struct mbox_client *cl, int size); -}; - -struct pcc_header { - u32 signature; - u32 flags; - u32 length; - u32 command; }; /* Generic Communications Channel Shared Memory Region */ diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h index ecedab554c80..d37b68238c97 100644 --- a/include/asm-generic/mshyperv.h +++ b/include/asm-generic/mshyperv.h @@ -342,6 +342,9 @@ static inline bool hv_parent_partition(void) { return hv_root_partition() || hv_l1vh_partition(); } + +bool hv_result_needs_memory(u64 status); +int hv_deposit_memory_node(int node, u64 partition_id, u64 status); int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages); int hv_call_add_logical_proc(int node, u32 lp_index, u32 acpi_id); int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); @@ -350,6 +353,11 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags); static inline bool hv_root_partition(void) { return false; } static inline bool hv_l1vh_partition(void) { return false; } static inline bool hv_parent_partition(void) { return false; } +static inline bool hv_result_needs_memory(u64 status) { return false; } +static inline int hv_deposit_memory_node(int node, u64 partition_id, u64 status) +{ + return -EOPNOTSUPP; +} static inline int hv_call_deposit_pages(int node, u64 partition_id, u32 num_pages) { return -EOPNOTSUPP; @@ -364,6 +372,11 @@ static inline int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u3 } #endif /* CONFIG_MSHV_ROOT */ +static inline int hv_deposit_memory(u64 partition_id, u64 status) +{ + return hv_deposit_memory_node(NUMA_NO_NODE, partition_id, status); +} + #if IS_ENABLED(CONFIG_HYPERV_VTL_MODE) u8 __init get_vtl(void); #else diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index eeb070f330bd..1e1580febe4b 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -848,12 +848,14 @@ /* Required sections not related to debugging. */ #define ELF_DETAILS \ - .modinfo : { *(.modinfo) . = ALIGN(8); } \ .comment 0 : { *(.comment) } \ .symtab 0 : { *(.symtab) } \ .strtab 0 : { *(.strtab) } \ .shstrtab 0 : { *(.shstrtab) } +#define MODINFO \ + .modinfo : { *(.modinfo) . = ALIGN(8); } + #ifdef CONFIG_GENERIC_BUG #define BUG_TABLE \ . = ALIGN(8); \ diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h index e4eebabab975..8b15d3eeb716 100644 --- a/include/drm/display/drm_dp.h +++ b/include/drm/display/drm_dp.h @@ -571,6 +571,8 @@ # define DP_PANEL_REPLAY_LINK_OFF_SUPPORTED_IN_PR_AFTER_ADAPTIVE_SYNC_SDP (1 << 7) #define DP_PANEL_REPLAY_CAP_X_GRANULARITY 0xb2 +# define DP_PANEL_REPLAY_FULL_LINE_GRANULARITY 0xffff + #define DP_PANEL_REPLAY_CAP_Y_GRANULARITY 0xb4 /* Link Configuration */ diff --git a/include/drm/drm_pagemap.h b/include/drm/drm_pagemap.h index 2baf0861f78f..c848f578e3da 100644 --- a/include/drm/drm_pagemap.h +++ b/include/drm/drm_pagemap.h @@ -95,7 +95,7 @@ struct drm_pagemap_ops { */ void (*device_unmap)(struct drm_pagemap *dpagemap, struct device *dev, - struct drm_pagemap_addr addr); + const struct drm_pagemap_addr *addr); /** * @populate_mm: Populate part of the mm with @dpagemap memory, diff --git a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h index 861a331963ac..b0fc549f53e3 100644 --- a/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h +++ b/include/dt-bindings/clock/amlogic,s4-peripherals-clkc.h @@ -232,5 +232,16 @@ #define CLKID_HDCP22_SKPCLK_SEL 222 #define CLKID_HDCP22_SKPCLK_DIV 223 #define CLKID_HDCP22_SKPCLK 224 +#define CLKID_CTS_ENCL_SEL 225 +#define CLKID_CTS_ENCL 226 +#define CLKID_CDAC_SEL 227 +#define CLKID_CDAC_DIV 228 +#define CLKID_CDAC 229 +#define CLKID_DEMOD_CORE_SEL 230 +#define CLKID_DEMOD_CORE_DIV 231 +#define CLKID_DEMOD_CORE 232 +#define CLKID_ADC_EXTCLK_IN_SEL 233 +#define CLKID_ADC_EXTCLK_IN_DIV 234 +#define CLKID_ADC_EXTCLK_IN 235 #endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */ diff --git a/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h b/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h new file mode 100644 index 000000000000..32c4b62037de --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-peripherals-clkc.h @@ -0,0 +1,228 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_PERIPHERALS_CLKC_H +#define __T7_PERIPHERALS_CLKC_H + +#define CLKID_RTC_DUALDIV_IN 0 +#define CLKID_RTC_DUALDIV_DIV 1 +#define CLKID_RTC_DUALDIV_SEL 2 +#define CLKID_RTC_DUALDIV 3 +#define CLKID_RTC 4 +#define CLKID_CECA_DUALDIV_IN 5 +#define CLKID_CECA_DUALDIV_DIV 6 +#define CLKID_CECA_DUALDIV_SEL 7 +#define CLKID_CECA_DUALDIV 8 +#define CLKID_CECA 9 +#define CLKID_CECB_DUALDIV_IN 10 +#define CLKID_CECB_DUALDIV_DIV 11 +#define CLKID_CECB_DUALDIV_SEL 12 +#define CLKID_CECB_DUALDIV 13 +#define CLKID_CECB 14 +#define CLKID_SC_SEL 15 +#define CLKID_SC_DIV 16 +#define CLKID_SC 17 +#define CLKID_DSPA_0_SEL 18 +#define CLKID_DSPA_0_DIV 19 +#define CLKID_DSPA_0 20 +#define CLKID_DSPA_1_SEL 21 +#define CLKID_DSPA_1_DIV 22 +#define CLKID_DSPA_1 23 +#define CLKID_DSPA 24 +#define CLKID_DSPB_0_SEL 25 +#define CLKID_DSPB_0_DIV 26 +#define CLKID_DSPB_0 27 +#define CLKID_DSPB_1_SEL 28 +#define CLKID_DSPB_1_DIV 29 +#define CLKID_DSPB_1 30 +#define CLKID_DSPB 31 +#define CLKID_24M 32 +#define CLKID_24M_DIV2 33 +#define CLKID_12M 34 +#define CLKID_25M_DIV 35 +#define CLKID_25M 36 +#define CLKID_ANAKIN_0_SEL 37 +#define CLKID_ANAKIN_0_DIV 38 +#define CLKID_ANAKIN_0 39 +#define CLKID_ANAKIN_1_SEL 40 +#define CLKID_ANAKIN_1_DIV 41 +#define CLKID_ANAKIN_1 42 +#define CLKID_ANAKIN_01_SEL 43 +#define CLKID_ANAKIN 44 +#define CLKID_TS_DIV 45 +#define CLKID_TS 46 +#define CLKID_MIPI_CSI_PHY_0_SEL 47 +#define CLKID_MIPI_CSI_PHY_0_DIV 48 +#define CLKID_MIPI_CSI_PHY_0 49 +#define CLKID_MIPI_CSI_PHY_1_SEL 50 +#define CLKID_MIPI_CSI_PHY_1_DIV 51 +#define CLKID_MIPI_CSI_PHY_1 52 +#define CLKID_MIPI_CSI_PHY 53 +#define CLKID_MIPI_ISP_SEL 54 +#define CLKID_MIPI_ISP_DIV 55 +#define CLKID_MIPI_ISP 56 +#define CLKID_MALI_0_SEL 57 +#define CLKID_MALI_0_DIV 58 +#define CLKID_MALI_0 59 +#define CLKID_MALI_1_SEL 60 +#define CLKID_MALI_1_DIV 61 +#define CLKID_MALI_1 62 +#define CLKID_MALI 63 +#define CLKID_ETH_RMII_SEL 64 +#define CLKID_ETH_RMII_DIV 65 +#define CLKID_ETH_RMII 66 +#define CLKID_FCLK_DIV2_DIV8 67 +#define CLKID_ETH_125M 68 +#define CLKID_SD_EMMC_A_SEL 69 +#define CLKID_SD_EMMC_A_DIV 70 +#define CLKID_SD_EMMC_A 71 +#define CLKID_SD_EMMC_B_SEL 72 +#define CLKID_SD_EMMC_B_DIV 73 +#define CLKID_SD_EMMC_B 74 +#define CLKID_SD_EMMC_C_SEL 75 +#define CLKID_SD_EMMC_C_DIV 76 +#define CLKID_SD_EMMC_C 77 +#define CLKID_SPICC0_SEL 78 +#define CLKID_SPICC0_DIV 79 +#define CLKID_SPICC0 80 +#define CLKID_SPICC1_SEL 81 +#define CLKID_SPICC1_DIV 82 +#define CLKID_SPICC1 83 +#define CLKID_SPICC2_SEL 84 +#define CLKID_SPICC2_DIV 85 +#define CLKID_SPICC2 86 +#define CLKID_SPICC3_SEL 87 +#define CLKID_SPICC3_DIV 88 +#define CLKID_SPICC3 89 +#define CLKID_SPICC4_SEL 90 +#define CLKID_SPICC4_DIV 91 +#define CLKID_SPICC4 92 +#define CLKID_SPICC5_SEL 93 +#define CLKID_SPICC5_DIV 94 +#define CLKID_SPICC5 95 +#define CLKID_SARADC_SEL 96 +#define CLKID_SARADC_DIV 97 +#define CLKID_SARADC 98 +#define CLKID_PWM_A_SEL 99 +#define CLKID_PWM_A_DIV 100 +#define CLKID_PWM_A 101 +#define CLKID_PWM_B_SEL 102 +#define CLKID_PWM_B_DIV 103 +#define CLKID_PWM_B 104 +#define CLKID_PWM_C_SEL 105 +#define CLKID_PWM_C_DIV 106 +#define CLKID_PWM_C 107 +#define CLKID_PWM_D_SEL 108 +#define CLKID_PWM_D_DIV 109 +#define CLKID_PWM_D 110 +#define CLKID_PWM_E_SEL 111 +#define CLKID_PWM_E_DIV 112 +#define CLKID_PWM_E 113 +#define CLKID_PWM_F_SEL 114 +#define CLKID_PWM_F_DIV 115 +#define CLKID_PWM_F 116 +#define CLKID_PWM_AO_A_SEL 117 +#define CLKID_PWM_AO_A_DIV 118 +#define CLKID_PWM_AO_A 119 +#define CLKID_PWM_AO_B_SEL 120 +#define CLKID_PWM_AO_B_DIV 121 +#define CLKID_PWM_AO_B 122 +#define CLKID_PWM_AO_C_SEL 123 +#define CLKID_PWM_AO_C_DIV 124 +#define CLKID_PWM_AO_C 125 +#define CLKID_PWM_AO_D_SEL 126 +#define CLKID_PWM_AO_D_DIV 127 +#define CLKID_PWM_AO_D 128 +#define CLKID_PWM_AO_E_SEL 129 +#define CLKID_PWM_AO_E_DIV 130 +#define CLKID_PWM_AO_E 131 +#define CLKID_PWM_AO_F_SEL 132 +#define CLKID_PWM_AO_F_DIV 133 +#define CLKID_PWM_AO_F 134 +#define CLKID_PWM_AO_G_SEL 135 +#define CLKID_PWM_AO_G_DIV 136 +#define CLKID_PWM_AO_G 137 +#define CLKID_PWM_AO_H_SEL 138 +#define CLKID_PWM_AO_H_DIV 139 +#define CLKID_PWM_AO_H 140 +#define CLKID_SYS_DDR 141 +#define CLKID_SYS_DOS 142 +#define CLKID_SYS_MIPI_DSI_A 143 +#define CLKID_SYS_MIPI_DSI_B 144 +#define CLKID_SYS_ETHPHY 145 +#define CLKID_SYS_MALI 146 +#define CLKID_SYS_AOCPU 147 +#define CLKID_SYS_AUCPU 148 +#define CLKID_SYS_CEC 149 +#define CLKID_SYS_GDC 150 +#define CLKID_SYS_DESWARP 151 +#define CLKID_SYS_AMPIPE_NAND 152 +#define CLKID_SYS_AMPIPE_ETH 153 +#define CLKID_SYS_AM2AXI0 154 +#define CLKID_SYS_AM2AXI1 155 +#define CLKID_SYS_AM2AXI2 156 +#define CLKID_SYS_SD_EMMC_A 157 +#define CLKID_SYS_SD_EMMC_B 158 +#define CLKID_SYS_SD_EMMC_C 159 +#define CLKID_SYS_SMARTCARD 160 +#define CLKID_SYS_ACODEC 161 +#define CLKID_SYS_SPIFC 162 +#define CLKID_SYS_MSR_CLK 163 +#define CLKID_SYS_IR_CTRL 164 +#define CLKID_SYS_AUDIO 165 +#define CLKID_SYS_ETH 166 +#define CLKID_SYS_UART_A 167 +#define CLKID_SYS_UART_B 168 +#define CLKID_SYS_UART_C 169 +#define CLKID_SYS_UART_D 170 +#define CLKID_SYS_UART_E 171 +#define CLKID_SYS_UART_F 172 +#define CLKID_SYS_AIFIFO 173 +#define CLKID_SYS_SPICC2 174 +#define CLKID_SYS_SPICC3 175 +#define CLKID_SYS_SPICC4 176 +#define CLKID_SYS_TS_A73 177 +#define CLKID_SYS_TS_A53 178 +#define CLKID_SYS_SPICC5 179 +#define CLKID_SYS_G2D 180 +#define CLKID_SYS_SPICC0 181 +#define CLKID_SYS_SPICC1 182 +#define CLKID_SYS_PCIE 183 +#define CLKID_SYS_USB 184 +#define CLKID_SYS_PCIE_PHY 185 +#define CLKID_SYS_I2C_AO_A 186 +#define CLKID_SYS_I2C_AO_B 187 +#define CLKID_SYS_I2C_M_A 188 +#define CLKID_SYS_I2C_M_B 189 +#define CLKID_SYS_I2C_M_C 190 +#define CLKID_SYS_I2C_M_D 191 +#define CLKID_SYS_I2C_M_E 192 +#define CLKID_SYS_I2C_M_F 193 +#define CLKID_SYS_HDMITX_APB 194 +#define CLKID_SYS_I2C_S_A 195 +#define CLKID_SYS_HDMIRX_PCLK 196 +#define CLKID_SYS_MMC_APB 197 +#define CLKID_SYS_MIPI_ISP_PCLK 198 +#define CLKID_SYS_RSA 199 +#define CLKID_SYS_PCLK_SYS_APB 200 +#define CLKID_SYS_A73PCLK_APB 201 +#define CLKID_SYS_DSPA 202 +#define CLKID_SYS_DSPB 203 +#define CLKID_SYS_VPU_INTR 204 +#define CLKID_SYS_SAR_ADC 205 +#define CLKID_SYS_GIC 206 +#define CLKID_SYS_TS_GPU 207 +#define CLKID_SYS_TS_NNA 208 +#define CLKID_SYS_TS_VPU 209 +#define CLKID_SYS_TS_HEVC 210 +#define CLKID_SYS_PWM_AB 211 +#define CLKID_SYS_PWM_CD 212 +#define CLKID_SYS_PWM_EF 213 +#define CLKID_SYS_PWM_AO_AB 214 +#define CLKID_SYS_PWM_AO_CD 215 +#define CLKID_SYS_PWM_AO_EF 216 +#define CLKID_SYS_PWM_AO_GH 217 + +#endif /* __T7_PERIPHERALS_CLKC_H */ diff --git a/include/dt-bindings/clock/amlogic,t7-pll-clkc.h b/include/dt-bindings/clock/amlogic,t7-pll-clkc.h new file mode 100644 index 000000000000..e2481f2f1163 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-pll-clkc.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_PLL_CLKC_H +#define __T7_PLL_CLKC_H + +/* GP0 */ +#define CLKID_GP0_PLL_DCO 0 +#define CLKID_GP0_PLL 1 + +/* GP1 */ +#define CLKID_GP1_PLL_DCO 0 +#define CLKID_GP1_PLL 1 + +/* HIFI */ +#define CLKID_HIFI_PLL_DCO 0 +#define CLKID_HIFI_PLL 1 + +/* PCIE */ +#define CLKID_PCIE_PLL_DCO 0 +#define CLKID_PCIE_PLL_DCO_DIV2 1 +#define CLKID_PCIE_PLL_OD 2 +#define CLKID_PCIE_PLL 3 + +/* MPLL */ +#define CLKID_MPLL_PREDIV 0 +#define CLKID_MPLL0_DIV 1 +#define CLKID_MPLL0 2 +#define CLKID_MPLL1_DIV 3 +#define CLKID_MPLL1 4 +#define CLKID_MPLL2_DIV 5 +#define CLKID_MPLL2 6 +#define CLKID_MPLL3_DIV 7 +#define CLKID_MPLL3 8 + +/* HDMI */ +#define CLKID_HDMI_PLL_DCO 0 +#define CLKID_HDMI_PLL_OD 1 +#define CLKID_HDMI_PLL 2 + +/* MCLK */ +#define CLKID_MCLK_PLL_DCO 0 +#define CLKID_MCLK_PRE 1 +#define CLKID_MCLK_PLL 2 +#define CLKID_MCLK_0_SEL 3 +#define CLKID_MCLK_0_DIV2 4 +#define CLKID_MCLK_0_PRE 5 +#define CLKID_MCLK_0 6 +#define CLKID_MCLK_1_SEL 7 +#define CLKID_MCLK_1_DIV2 8 +#define CLKID_MCLK_1_PRE 9 +#define CLKID_MCLK_1 10 + +#endif /* __T7_PLL_CLKC_H */ diff --git a/include/dt-bindings/clock/amlogic,t7-scmi.h b/include/dt-bindings/clock/amlogic,t7-scmi.h new file mode 100644 index 000000000000..27bd257bd4ea --- /dev/null +++ b/include/dt-bindings/clock/amlogic,t7-scmi.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved + */ + +#ifndef __T7_SCMI_CLKC_H +#define __T7_SCMI_CLKC_H + +#define CLKID_DDR_PLL_OSC 0 +#define CLKID_AUD_PLL_OSC 1 +#define CLKID_TOP_PLL_OSC 2 +#define CLKID_TCON_PLL_OSC 3 +#define CLKID_USB_PLL0_OSC 4 +#define CLKID_USB_PLL1_OSC 5 +#define CLKID_MCLK_PLL_OSC 6 +#define CLKID_PCIE_OSC 7 +#define CLKID_ETH_PLL_OSC 8 +#define CLKID_PCIE_REFCLK_PLL_OSC 9 +#define CLKID_EARC_OSC 10 +#define CLKID_SYS1_PLL_OSC 11 +#define CLKID_HDMI_PLL_OSC 12 +#define CLKID_SYS_CLK 13 +#define CLKID_AXI_CLK 14 +#define CLKID_FIXED_PLL_DCO 15 +#define CLKID_FIXED_PLL 16 +#define CLKID_FCLK_DIV2_DIV 17 +#define CLKID_FCLK_DIV2 18 +#define CLKID_FCLK_DIV2P5_DIV 19 +#define CLKID_FCLK_DIV2P5 20 +#define CLKID_FCLK_DIV3_DIV 21 +#define CLKID_FCLK_DIV3 22 +#define CLKID_FCLK_DIV4_DIV 23 +#define CLKID_FCLK_DIV4 24 +#define CLKID_FCLK_DIV5_DIV 25 +#define CLKID_FCLK_DIV5 26 +#define CLKID_FCLK_DIV7_DIV 27 +#define CLKID_FCLK_DIV7 28 +#define CLKID_FCLK_50M_DIV 29 +#define CLKID_FCLK_50M 30 +#define CLKID_CPU_CLK 31 +#define CLKID_A73_CLK 32 +#define CLKID_CPU_CLK_DIV16_DIV 33 +#define CLKID_CPU_CLK_DIV16 34 +#define CLKID_A73_CLK_DIV16_DIV 35 +#define CLKID_A73_CLK_DIV16 36 + +#endif /* __T7_SCMI_CLKC_H */ diff --git a/include/dt-bindings/clock/aspeed-clock.h b/include/dt-bindings/clock/aspeed-clock.h index 06d568382c77..671e5a476eae 100644 --- a/include/dt-bindings/clock/aspeed-clock.h +++ b/include/dt-bindings/clock/aspeed-clock.h @@ -53,5 +53,6 @@ #define ASPEED_RESET_AHB 8 #define ASPEED_RESET_CRT1 9 #define ASPEED_RESET_HACE 10 +#define ASPEED_RESET_VIDEO 11 #endif diff --git a/include/dt-bindings/clock/qcom,gcc-msm8917.h b/include/dt-bindings/clock/qcom,gcc-msm8917.h index 4265460bfb30..c592682d5ba7 100644 --- a/include/dt-bindings/clock/qcom,gcc-msm8917.h +++ b/include/dt-bindings/clock/qcom,gcc-msm8917.h @@ -187,6 +187,7 @@ #define MSM8937_GCC_MDSS_PCLK1_CLK 179 #define MSM8937_GCC_OXILI_AON_CLK 180 #define MSM8937_GCC_OXILI_TIMER_CLK 181 +#define MSM8940_GCC_IPA_TBU_CLK 182 /* GCC block resets */ #define GCC_CAMSS_MICRO_BCR 0 diff --git a/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h new file mode 100644 index 000000000000..ddb083b5289e --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_KAANAPALI_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_DEBUG_CLK 0 +#define CAM_BIST_MCLK_CC_DEBUG_DIV_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK0_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 16 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 17 +#define CAM_BIST_MCLK_CC_PLL0 18 +#define CAM_BIST_MCLK_CC_PLL_TEST_CLK 19 +#define CAM_BIST_MCLK_CC_PLL_TEST_DIV_CLK_SRC 20 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 21 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-camcc.h b/include/dt-bindings/clock/qcom,kaanapali-camcc.h new file mode 100644 index 000000000000..58835136b356 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-camcc.h @@ -0,0 +1,147 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_KAANAPALI_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 6 +#define CAM_CC_CAMNOC_RT_AXI_CLK 7 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 8 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 9 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 10 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 12 +#define CAM_CC_CAMNOC_XO_CLK 13 +#define CAM_CC_CCI_0_CLK 14 +#define CAM_CC_CCI_0_CLK_SRC 15 +#define CAM_CC_CCI_1_CLK 16 +#define CAM_CC_CCI_1_CLK_SRC 17 +#define CAM_CC_CCI_2_CLK 18 +#define CAM_CC_CCI_2_CLK_SRC 19 +#define CAM_CC_CORE_AHB_CLK 20 +#define CAM_CC_CPHY_RX_CLK_SRC 21 +#define CAM_CC_CRE_AHB_CLK 22 +#define CAM_CC_CRE_CLK 23 +#define CAM_CC_CRE_CLK_SRC 24 +#define CAM_CC_CSI0PHYTIMER_CLK 25 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 26 +#define CAM_CC_CSI1PHYTIMER_CLK 27 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 28 +#define CAM_CC_CSI2PHYTIMER_CLK 29 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 30 +#define CAM_CC_CSI3PHYTIMER_CLK 31 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 32 +#define CAM_CC_CSI4PHYTIMER_CLK 33 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 34 +#define CAM_CC_CSI5PHYTIMER_CLK 35 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 36 +#define CAM_CC_CSID_CLK 37 +#define CAM_CC_CSID_CLK_SRC 38 +#define CAM_CC_CSID_CSIPHY_RX_CLK 39 +#define CAM_CC_CSIPHY0_CLK 40 +#define CAM_CC_CSIPHY1_CLK 41 +#define CAM_CC_CSIPHY2_CLK 42 +#define CAM_CC_CSIPHY3_CLK 43 +#define CAM_CC_CSIPHY4_CLK 44 +#define CAM_CC_CSIPHY5_CLK 45 +#define CAM_CC_DRV_AHB_CLK 46 +#define CAM_CC_DRV_XO_CLK 47 +#define CAM_CC_FAST_AHB_CLK_SRC 48 +#define CAM_CC_GDSC_CLK 49 +#define CAM_CC_ICP_0_AHB_CLK 50 +#define CAM_CC_ICP_0_CLK 51 +#define CAM_CC_ICP_0_CLK_SRC 52 +#define CAM_CC_ICP_1_AHB_CLK 53 +#define CAM_CC_ICP_1_CLK 54 +#define CAM_CC_ICP_1_CLK_SRC 55 +#define CAM_CC_IFE_LITE_AHB_CLK 56 +#define CAM_CC_IFE_LITE_CLK 57 +#define CAM_CC_IFE_LITE_CLK_SRC 58 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 59 +#define CAM_CC_IFE_LITE_CSID_CLK 60 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 61 +#define CAM_CC_IPE_NPS_AHB_CLK 62 +#define CAM_CC_IPE_NPS_CLK 63 +#define CAM_CC_IPE_NPS_CLK_SRC 64 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 65 +#define CAM_CC_IPE_PPS_CLK 66 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 67 +#define CAM_CC_JPEG_CLK 68 +#define CAM_CC_JPEG_CLK_SRC 69 +#define CAM_CC_OFE_AHB_CLK 70 +#define CAM_CC_OFE_ANCHOR_CLK 71 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 72 +#define CAM_CC_OFE_CLK_SRC 73 +#define CAM_CC_OFE_HDR_CLK 74 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 75 +#define CAM_CC_OFE_MAIN_CLK 76 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 77 +#define CAM_CC_PLL0 78 +#define CAM_CC_PLL0_OUT_EVEN 79 +#define CAM_CC_PLL0_OUT_ODD 80 +#define CAM_CC_PLL1 81 +#define CAM_CC_PLL1_OUT_EVEN 82 +#define CAM_CC_PLL2 83 +#define CAM_CC_PLL2_OUT_EVEN 84 +#define CAM_CC_PLL3 85 +#define CAM_CC_PLL3_OUT_EVEN 86 +#define CAM_CC_PLL4 87 +#define CAM_CC_PLL4_OUT_EVEN 88 +#define CAM_CC_PLL5 89 +#define CAM_CC_PLL5_OUT_EVEN 90 +#define CAM_CC_PLL6 91 +#define CAM_CC_PLL6_OUT_EVEN 92 +#define CAM_CC_PLL6_OUT_ODD 93 +#define CAM_CC_PLL7 94 +#define CAM_CC_PLL7_OUT_EVEN 95 +#define CAM_CC_QDSS_DEBUG_CLK 96 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 97 +#define CAM_CC_QDSS_DEBUG_XO_CLK 98 +#define CAM_CC_SLEEP_CLK 99 +#define CAM_CC_SLOW_AHB_CLK_SRC 100 +#define CAM_CC_TFE_0_BAYER_CLK 101 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 102 +#define CAM_CC_TFE_0_CLK_SRC 103 +#define CAM_CC_TFE_0_MAIN_CLK 104 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 105 +#define CAM_CC_TFE_1_BAYER_CLK 106 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_1_CLK_SRC 108 +#define CAM_CC_TFE_1_MAIN_CLK 109 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_2_BAYER_CLK 111 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_2_CLK_SRC 113 +#define CAM_CC_TFE_2_MAIN_CLK 114 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TRACENOC_TPDM_1_CMB_CLK 116 +#define CAM_CC_XO_CLK_SRC 117 + +/* CAM_CC power domains */ +#define CAM_CC_IPE_0_GDSC 0 +#define CAM_CC_OFE_GDSC 1 +#define CAM_CC_TFE_0_GDSC 2 +#define CAM_CC_TFE_1_GDSC 3 +#define CAM_CC_TFE_2_GDSC 4 +#define CAM_CC_TITAN_TOP_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-dispcc.h b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h new file mode 100644 index 000000000000..05146f9dfe07 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-dispcc.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_DISP_CC_KAANAPALI_H + +/* DISP_CC clocks */ +#define DISP_CC_ESYNC0_CLK 0 +#define DISP_CC_ESYNC0_CLK_SRC 1 +#define DISP_CC_ESYNC1_CLK 2 +#define DISP_CC_ESYNC1_CLK_SRC 3 +#define DISP_CC_MDSS_ACCU_SHIFT_CLK 4 +#define DISP_CC_MDSS_AHB1_CLK 5 +#define DISP_CC_MDSS_AHB_CLK 6 +#define DISP_CC_MDSS_AHB_CLK_SRC 7 +#define DISP_CC_MDSS_AHB_SWI_CLK 8 +#define DISP_CC_MDSS_AHB_SWI_DIV_CLK_SRC 9 +#define DISP_CC_MDSS_BYTE0_CLK 10 +#define DISP_CC_MDSS_BYTE0_CLK_SRC 11 +#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC 12 +#define DISP_CC_MDSS_BYTE0_INTF_CLK 13 +#define DISP_CC_MDSS_BYTE1_CLK 14 +#define DISP_CC_MDSS_BYTE1_CLK_SRC 15 +#define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC 16 +#define DISP_CC_MDSS_BYTE1_INTF_CLK 17 +#define DISP_CC_MDSS_DPTX0_AUX_CLK 18 +#define DISP_CC_MDSS_DPTX0_AUX_CLK_SRC 19 +#define DISP_CC_MDSS_DPTX0_CRYPTO_CLK 20 +#define DISP_CC_MDSS_DPTX0_LINK_CLK 21 +#define DISP_CC_MDSS_DPTX0_LINK_CLK_SRC 22 +#define DISP_CC_MDSS_DPTX0_LINK_DIV_CLK_SRC 23 +#define DISP_CC_MDSS_DPTX0_LINK_INTF_CLK 24 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK 25 +#define DISP_CC_MDSS_DPTX0_PIXEL0_CLK_SRC 26 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK 27 +#define DISP_CC_MDSS_DPTX0_PIXEL1_CLK_SRC 28 +#define DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK 29 +#define DISP_CC_MDSS_DPTX1_AUX_CLK 30 +#define DISP_CC_MDSS_DPTX1_AUX_CLK_SRC 31 +#define DISP_CC_MDSS_DPTX1_CRYPTO_CLK 32 +#define DISP_CC_MDSS_DPTX1_LINK_CLK 33 +#define DISP_CC_MDSS_DPTX1_LINK_CLK_SRC 34 +#define DISP_CC_MDSS_DPTX1_LINK_DIV_CLK_SRC 35 +#define DISP_CC_MDSS_DPTX1_LINK_INTF_CLK 36 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK 37 +#define DISP_CC_MDSS_DPTX1_PIXEL0_CLK_SRC 38 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK 39 +#define DISP_CC_MDSS_DPTX1_PIXEL1_CLK_SRC 40 +#define DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK 41 +#define DISP_CC_MDSS_DPTX2_AUX_CLK 42 +#define DISP_CC_MDSS_DPTX2_AUX_CLK_SRC 43 +#define DISP_CC_MDSS_DPTX2_CRYPTO_CLK 44 +#define DISP_CC_MDSS_DPTX2_LINK_CLK 45 +#define DISP_CC_MDSS_DPTX2_LINK_CLK_SRC 46 +#define DISP_CC_MDSS_DPTX2_LINK_DIV_CLK_SRC 47 +#define DISP_CC_MDSS_DPTX2_LINK_INTF_CLK 48 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK 49 +#define DISP_CC_MDSS_DPTX2_PIXEL0_CLK_SRC 50 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK 51 +#define DISP_CC_MDSS_DPTX2_PIXEL1_CLK_SRC 52 +#define DISP_CC_MDSS_DPTX3_AUX_CLK 53 +#define DISP_CC_MDSS_DPTX3_AUX_CLK_SRC 54 +#define DISP_CC_MDSS_DPTX3_CRYPTO_CLK 55 +#define DISP_CC_MDSS_DPTX3_LINK_CLK 56 +#define DISP_CC_MDSS_DPTX3_LINK_CLK_SRC 57 +#define DISP_CC_MDSS_DPTX3_LINK_DIV_CLK_SRC 58 +#define DISP_CC_MDSS_DPTX3_LINK_INTF_CLK 59 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK 60 +#define DISP_CC_MDSS_DPTX3_PIXEL0_CLK_SRC 61 +#define DISP_CC_MDSS_ESC0_CLK 62 +#define DISP_CC_MDSS_ESC0_CLK_SRC 63 +#define DISP_CC_MDSS_ESC1_CLK 64 +#define DISP_CC_MDSS_ESC1_CLK_SRC 65 +#define DISP_CC_MDSS_MDP1_CLK 66 +#define DISP_CC_MDSS_MDP_CLK 67 +#define DISP_CC_MDSS_MDP_CLK_SRC 68 +#define DISP_CC_MDSS_MDP_LUT1_CLK 69 +#define DISP_CC_MDSS_MDP_LUT_CLK 70 +#define DISP_CC_MDSS_MDP_SS_IP_CLK 71 +#define DISP_CC_MDSS_NON_GDSC_AHB_CLK 72 +#define DISP_CC_MDSS_PCLK0_CLK 73 +#define DISP_CC_MDSS_PCLK0_CLK_SRC 74 +#define DISP_CC_MDSS_PCLK1_CLK 75 +#define DISP_CC_MDSS_PCLK1_CLK_SRC 76 +#define DISP_CC_MDSS_PCLK2_CLK 77 +#define DISP_CC_MDSS_PCLK2_CLK_SRC 78 +#define DISP_CC_MDSS_VSYNC1_CLK 79 +#define DISP_CC_MDSS_VSYNC_CLK 80 +#define DISP_CC_MDSS_VSYNC_CLK_SRC 81 +#define DISP_CC_OSC_CLK 82 +#define DISP_CC_OSC_CLK_SRC 83 +#define DISP_CC_PLL0 84 +#define DISP_CC_PLL1 85 +#define DISP_CC_PLL2 86 +#define DISP_CC_SLEEP_CLK 87 +#define DISP_CC_XO_CLK 88 + +/* DISP_CC power domains */ +#define DISP_CC_MDSS_CORE_GDSC 0 +#define DISP_CC_MDSS_CORE_INT2_GDSC 1 + +/* DISP_CC resets */ +#define DISP_CC_MDSS_CORE_BCR 0 +#define DISP_CC_MDSS_CORE_INT2_BCR 1 +#define DISP_CC_MDSS_RSCC_BCR 2 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-gpucc.h b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h new file mode 100644 index 000000000000..e8dc2009c71b --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gpucc.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_KAANAPALI_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_GMU_CLK 3 +#define GPU_CC_CXO_AON_CLK 4 +#define GPU_CC_CXO_CLK 5 +#define GPU_CC_DEMET_CLK 6 +#define GPU_CC_DPM_CLK 7 +#define GPU_CC_FF_CLK_SRC 8 +#define GPU_CC_FREQ_MEASURE_CLK 9 +#define GPU_CC_GMU_CLK_SRC 10 +#define GPU_CC_GPU_SMMU_VOTE_CLK 11 +#define GPU_CC_GX_ACCU_SHIFT_CLK 12 +#define GPU_CC_GX_GMU_CLK 13 +#define GPU_CC_HUB_AON_CLK 14 +#define GPU_CC_HUB_CLK_SRC 15 +#define GPU_CC_HUB_CX_INT_CLK 16 +#define GPU_CC_HUB_DIV_CLK_SRC 17 +#define GPU_CC_MEMNOC_GFX_CLK 18 +#define GPU_CC_PLL0 19 +#define GPU_CC_PLL0_OUT_EVEN 20 +#define GPU_CC_RSCC_HUB_AON_CLK 21 +#define GPU_CC_RSCC_XO_AON_CLK 22 +#define GPU_CC_SLEEP_CLK 23 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 + +/* GPU_CC resets */ +#define GPU_CC_CB_BCR 0 +#define GPU_CC_CX_BCR 1 +#define GPU_CC_FAST_HUB_BCR 2 +#define GPU_CC_FF_BCR 3 +#define GPU_CC_GMU_BCR 4 +#define GPU_CC_GX_BCR 5 +#define GPU_CC_XO_BCR 6 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h new file mode 100644 index 000000000000..f32dade67cf2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GX_CLKCTL_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_GX_CLKCTL_KAANAPALI_H + +/* GX_CLKCTL power domains */ +#define GX_CLKCTL_GX_GDSC 0 +#define GX_CLKCTL_GX_SLICE_GDSC 1 + +#endif diff --git a/include/dt-bindings/clock/qcom,kaanapali-videocc.h b/include/dt-bindings/clock/qcom,kaanapali-videocc.h new file mode 100644 index 000000000000..cc0d41b895c9 --- /dev/null +++ b/include/dt-bindings/clock/qcom,kaanapali-videocc.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_KAANAPALI_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_KAANAPALI_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_FREERUN_CLK 4 +#define VIDEO_CC_MVS0_SHIFT_CLK 5 +#define VIDEO_CC_MVS0_VPP0_CLK 6 +#define VIDEO_CC_MVS0_VPP0_FREERUN_CLK 7 +#define VIDEO_CC_MVS0_VPP1_CLK 8 +#define VIDEO_CC_MVS0_VPP1_FREERUN_CLK 9 +#define VIDEO_CC_MVS0A_CLK 10 +#define VIDEO_CC_MVS0A_CLK_SRC 11 +#define VIDEO_CC_MVS0A_FREERUN_CLK 12 +#define VIDEO_CC_MVS0B_CLK 13 +#define VIDEO_CC_MVS0B_CLK_SRC 14 +#define VIDEO_CC_MVS0B_FREERUN_CLK 15 +#define VIDEO_CC_MVS0C_CLK 16 +#define VIDEO_CC_MVS0C_CLK_SRC 17 +#define VIDEO_CC_MVS0C_FREERUN_CLK 18 +#define VIDEO_CC_MVS0C_SHIFT_CLK 19 +#define VIDEO_CC_PLL0 20 +#define VIDEO_CC_PLL1 21 +#define VIDEO_CC_PLL2 22 +#define VIDEO_CC_PLL3 23 +#define VIDEO_CC_SLEEP_CLK 24 +#define VIDEO_CC_TS_XO_CLK 25 +#define VIDEO_CC_XO_CLK 26 +#define VIDEO_CC_XO_CLK_SRC 27 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0A_GDSC 0 +#define VIDEO_CC_MVS0_GDSC 1 +#define VIDEO_CC_MVS0_VPP1_GDSC 2 +#define VIDEO_CC_MVS0_VPP0_GDSC 3 +#define VIDEO_CC_MVS0C_GDSC 4 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_BCR 1 +#define VIDEO_CC_MVS0_VPP0_BCR 2 +#define VIDEO_CC_MVS0_VPP1_BCR 3 +#define VIDEO_CC_MVS0A_BCR 4 +#define VIDEO_CC_MVS0C_CLK_ARES 5 +#define VIDEO_CC_MVS0C_BCR 6 +#define VIDEO_CC_MVS0_FREERUN_CLK_ARES 7 +#define VIDEO_CC_MVS0C_FREERUN_CLK_ARES 8 +#define VIDEO_CC_XO_CLK_ARES 9 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h new file mode 100644 index 000000000000..51615bee307f --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-cambistmclkcc.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_SM8750_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_MCLK0_CLK 0 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_PLL0 16 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 17 +#define CAM_BIST_MCLK_CC_SLEEP_CLK_SRC 18 + +#endif diff --git a/include/dt-bindings/clock/qcom,sm8750-camcc.h b/include/dt-bindings/clock/qcom,sm8750-camcc.h new file mode 100644 index 000000000000..dae788247afe --- /dev/null +++ b/include/dt-bindings/clock/qcom,sm8750-camcc.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8750_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SM8750_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK 6 +#define CAM_CC_CAMNOC_NRT_OFE_HDR_CLK 7 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 8 +#define CAM_CC_CAMNOC_RT_AXI_CLK 9 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK 12 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 13 +#define CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK 14 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 15 +#define CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK 16 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 17 +#define CAM_CC_CAMNOC_XO_CLK 18 +#define CAM_CC_CCI_0_CLK 19 +#define CAM_CC_CCI_0_CLK_SRC 20 +#define CAM_CC_CCI_1_CLK 21 +#define CAM_CC_CCI_1_CLK_SRC 22 +#define CAM_CC_CCI_2_CLK 23 +#define CAM_CC_CCI_2_CLK_SRC 24 +#define CAM_CC_CORE_AHB_CLK 25 +#define CAM_CC_CPHY_RX_CLK_SRC 26 +#define CAM_CC_CRE_AHB_CLK 27 +#define CAM_CC_CRE_CLK 28 +#define CAM_CC_CRE_CLK_SRC 29 +#define CAM_CC_CSI0PHYTIMER_CLK 30 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 31 +#define CAM_CC_CSI1PHYTIMER_CLK 32 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 33 +#define CAM_CC_CSI2PHYTIMER_CLK 34 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 35 +#define CAM_CC_CSI3PHYTIMER_CLK 36 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 37 +#define CAM_CC_CSI4PHYTIMER_CLK 38 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 39 +#define CAM_CC_CSI5PHYTIMER_CLK 40 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 41 +#define CAM_CC_CSID_CLK 42 +#define CAM_CC_CSID_CLK_SRC 43 +#define CAM_CC_CSID_CSIPHY_RX_CLK 44 +#define CAM_CC_CSIPHY0_CLK 45 +#define CAM_CC_CSIPHY1_CLK 46 +#define CAM_CC_CSIPHY2_CLK 47 +#define CAM_CC_CSIPHY3_CLK 48 +#define CAM_CC_CSIPHY4_CLK 49 +#define CAM_CC_CSIPHY5_CLK 50 +#define CAM_CC_DRV_AHB_CLK 51 +#define CAM_CC_DRV_XO_CLK 52 +#define CAM_CC_FAST_AHB_CLK_SRC 53 +#define CAM_CC_GDSC_CLK 54 +#define CAM_CC_ICP_0_AHB_CLK 55 +#define CAM_CC_ICP_0_CLK 56 +#define CAM_CC_ICP_0_CLK_SRC 57 +#define CAM_CC_ICP_1_AHB_CLK 58 +#define CAM_CC_ICP_1_CLK 59 +#define CAM_CC_ICP_1_CLK_SRC 60 +#define CAM_CC_IFE_LITE_AHB_CLK 61 +#define CAM_CC_IFE_LITE_CLK 62 +#define CAM_CC_IFE_LITE_CLK_SRC 63 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 64 +#define CAM_CC_IFE_LITE_CSID_CLK 65 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 66 +#define CAM_CC_IPE_NPS_AHB_CLK 67 +#define CAM_CC_IPE_NPS_CLK 68 +#define CAM_CC_IPE_NPS_CLK_SRC 69 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 70 +#define CAM_CC_IPE_PPS_CLK 71 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 72 +#define CAM_CC_JPEG_0_CLK 73 +#define CAM_CC_JPEG_1_CLK 74 +#define CAM_CC_JPEG_CLK_SRC 75 +#define CAM_CC_OFE_AHB_CLK 76 +#define CAM_CC_OFE_ANCHOR_CLK 77 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 78 +#define CAM_CC_OFE_CLK_SRC 79 +#define CAM_CC_OFE_HDR_CLK 80 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 81 +#define CAM_CC_OFE_MAIN_CLK 82 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 83 +#define CAM_CC_PLL0 84 +#define CAM_CC_PLL0_OUT_EVEN 85 +#define CAM_CC_PLL0_OUT_ODD 86 +#define CAM_CC_PLL1 87 +#define CAM_CC_PLL1_OUT_EVEN 88 +#define CAM_CC_PLL2 89 +#define CAM_CC_PLL2_OUT_EVEN 90 +#define CAM_CC_PLL3 91 +#define CAM_CC_PLL3_OUT_EVEN 92 +#define CAM_CC_PLL4 93 +#define CAM_CC_PLL4_OUT_EVEN 94 +#define CAM_CC_PLL5 95 +#define CAM_CC_PLL5_OUT_EVEN 96 +#define CAM_CC_PLL6 97 +#define CAM_CC_PLL6_OUT_EVEN 98 +#define CAM_CC_PLL6_OUT_ODD 99 +#define CAM_CC_QDSS_DEBUG_CLK 100 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 101 +#define CAM_CC_QDSS_DEBUG_XO_CLK 102 +#define CAM_CC_SLEEP_CLK 103 +#define CAM_CC_SLEEP_CLK_SRC 104 +#define CAM_CC_SLOW_AHB_CLK_SRC 105 +#define CAM_CC_TFE_0_BAYER_CLK 106 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_0_CLK_SRC 108 +#define CAM_CC_TFE_0_MAIN_CLK 109 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_1_BAYER_CLK 111 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_1_CLK_SRC 113 +#define CAM_CC_TFE_1_MAIN_CLK 114 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TFE_2_BAYER_CLK 116 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 117 +#define CAM_CC_TFE_2_CLK_SRC 118 +#define CAM_CC_TFE_2_MAIN_CLK 119 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 120 +#define CAM_CC_XO_CLK_SRC 121 + +/* CAM_CC power domains */ +#define CAM_CC_TITAN_TOP_GDSC 0 +#define CAM_CC_IPE_0_GDSC 1 +#define CAM_CC_OFE_GDSC 2 +#define CAM_CC_TFE_0_GDSC 3 +#define CAM_CC_TFE_1_GDSC 4 +#define CAM_CC_TFE_2_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif diff --git a/include/dt-bindings/clock/samsung,exynosautov920.h b/include/dt-bindings/clock/samsung,exynosautov920.h index 970d05167fc6..06dec27a8c77 100644 --- a/include/dt-bindings/clock/samsung,exynosautov920.h +++ b/include/dt-bindings/clock/samsung,exynosautov920.h @@ -305,4 +305,8 @@ #define CLK_MOUT_MFC_WFD_USER 2 #define CLK_DOUT_MFC_NOCP 3 +/* CMU_MFD */ +#define CLK_MOUT_MFD_NOC_USER 1 +#define CLK_DOUT_MFD_NOCP 2 + #endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */ diff --git a/include/dt-bindings/clock/spacemit,k3-clocks.h b/include/dt-bindings/clock/spacemit,k3-clocks.h new file mode 100644 index 000000000000..b22336f3ae40 --- /dev/null +++ b/include/dt-bindings/clock/spacemit,k3-clocks.h @@ -0,0 +1,390 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2025 SpacemiT Technology Co. Ltd + */ + +#ifndef _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ +#define _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ + +/* APBS (PLL) clocks */ +#define CLK_PLL1 0 +#define CLK_PLL2 1 +#define CLK_PLL3 2 +#define CLK_PLL4 3 +#define CLK_PLL5 4 +#define CLK_PLL6 5 +#define CLK_PLL7 6 +#define CLK_PLL8 7 +#define CLK_PLL1_D2 8 +#define CLK_PLL1_D3 9 +#define CLK_PLL1_D4 10 +#define CLK_PLL1_D5 11 +#define CLK_PLL1_D6 12 +#define CLK_PLL1_D7 13 +#define CLK_PLL1_D8 14 +#define CLK_PLL1_DX 15 +#define CLK_PLL1_D64 16 +#define CLK_PLL1_D10_AUD 17 +#define CLK_PLL1_D100_AUD 18 +#define CLK_PLL2_D1 19 +#define CLK_PLL2_D2 20 +#define CLK_PLL2_D3 21 +#define CLK_PLL2_D4 22 +#define CLK_PLL2_D5 23 +#define CLK_PLL2_D6 24 +#define CLK_PLL2_D7 25 +#define CLK_PLL2_D8 26 +#define CLK_PLL2_66 27 +#define CLK_PLL2_33 28 +#define CLK_PLL2_50 29 +#define CLK_PLL2_25 30 +#define CLK_PLL2_20 31 +#define CLK_PLL2_D24_125 32 +#define CLK_PLL2_D120_25 33 +#define CLK_PLL3_D1 34 +#define CLK_PLL3_D2 35 +#define CLK_PLL3_D3 36 +#define CLK_PLL3_D4 37 +#define CLK_PLL3_D5 38 +#define CLK_PLL3_D6 39 +#define CLK_PLL3_D7 40 +#define CLK_PLL3_D8 41 +#define CLK_PLL4_D1 42 +#define CLK_PLL4_D2 43 +#define CLK_PLL4_D3 44 +#define CLK_PLL4_D4 45 +#define CLK_PLL4_D5 46 +#define CLK_PLL4_D6 47 +#define CLK_PLL4_D7 48 +#define CLK_PLL4_D8 49 +#define CLK_PLL5_D1 50 +#define CLK_PLL5_D2 51 +#define CLK_PLL5_D3 52 +#define CLK_PLL5_D4 53 +#define CLK_PLL5_D5 54 +#define CLK_PLL5_D6 55 +#define CLK_PLL5_D7 56 +#define CLK_PLL5_D8 57 +#define CLK_PLL6_D1 58 +#define CLK_PLL6_D2 59 +#define CLK_PLL6_D3 60 +#define CLK_PLL6_D4 61 +#define CLK_PLL6_D5 62 +#define CLK_PLL6_D6 63 +#define CLK_PLL6_D7 64 +#define CLK_PLL6_D8 65 +#define CLK_PLL6_80 66 +#define CLK_PLL6_40 67 +#define CLK_PLL6_20 68 +#define CLK_PLL7_D1 69 +#define CLK_PLL7_D2 70 +#define CLK_PLL7_D3 71 +#define CLK_PLL7_D4 72 +#define CLK_PLL7_D5 73 +#define CLK_PLL7_D6 74 +#define CLK_PLL7_D7 75 +#define CLK_PLL7_D8 76 +#define CLK_PLL8_D1 77 +#define CLK_PLL8_D2 78 +#define CLK_PLL8_D3 79 +#define CLK_PLL8_D4 80 +#define CLK_PLL8_D5 81 +#define CLK_PLL8_D6 82 +#define CLK_PLL8_D7 83 +#define CLK_PLL8_D8 84 + +/* MPMU clocks */ +#define CLK_MPMU_PLL1_307P2 0 +#define CLK_MPMU_PLL1_76P8 1 +#define CLK_MPMU_PLL1_61P44 2 +#define CLK_MPMU_PLL1_153P6 3 +#define CLK_MPMU_PLL1_102P4 4 +#define CLK_MPMU_PLL1_51P2 5 +#define CLK_MPMU_PLL1_51P2_AP 6 +#define CLK_MPMU_PLL1_57P6 7 +#define CLK_MPMU_PLL1_25P6 8 +#define CLK_MPMU_PLL1_12P8 9 +#define CLK_MPMU_PLL1_12P8_WDT 10 +#define CLK_MPMU_PLL1_6P4 11 +#define CLK_MPMU_PLL1_3P2 12 +#define CLK_MPMU_PLL1_1P6 13 +#define CLK_MPMU_PLL1_0P8 14 +#define CLK_MPMU_PLL1_409P6 15 +#define CLK_MPMU_PLL1_204P8 16 +#define CLK_MPMU_PLL1_491 17 +#define CLK_MPMU_PLL1_245P76 18 +#define CLK_MPMU_PLL1_614 19 +#define CLK_MPMU_PLL1_47P26 20 +#define CLK_MPMU_PLL1_31P5 21 +#define CLK_MPMU_PLL1_819 22 +#define CLK_MPMU_PLL1_1228 23 +#define CLK_MPMU_APB 24 +#define CLK_MPMU_SLOW_UART 25 +#define CLK_MPMU_SLOW_UART1 26 +#define CLK_MPMU_SLOW_UART2 27 +#define CLK_MPMU_WDT 28 +#define CLK_MPMU_WDT_BUS 29 +#define CLK_MPMU_RIPC 30 +#define CLK_MPMU_I2S_153P6 31 +#define CLK_MPMU_I2S_153P6_BASE 32 +#define CLK_MPMU_I2S_SYSCLK_SRC 33 +#define CLK_MPMU_I2S1_SYSCLK 34 +#define CLK_MPMU_I2S_BCLK 35 +#define CLK_MPMU_I2S0_SYSCLK_SEL 36 +#define CLK_MPMU_I2S2_SYSCLK_SEL 37 +#define CLK_MPMU_I2S3_SYSCLK_SEL 38 +#define CLK_MPMU_I2S4_SYSCLK_SEL 39 +#define CLK_MPMU_I2S5_SYSCLK_SEL 40 +#define CLK_MPMU_I2S0_SYSCLK_DIV 41 +#define CLK_MPMU_I2S2_SYSCLK_DIV 42 +#define CLK_MPMU_I2S3_SYSCLK_DIV 43 +#define CLK_MPMU_I2S4_SYSCLK_DIV 44 +#define CLK_MPMU_I2S5_SYSCLK_DIV 45 +#define CLK_MPMU_I2S0_SYSCLK 46 +#define CLK_MPMU_I2S2_SYSCLK 47 +#define CLK_MPMU_I2S3_SYSCLK 48 +#define CLK_MPMU_I2S4_SYSCLK 49 +#define CLK_MPMU_I2S5_SYSCLK 50 + +/* APBC clocks */ +#define CLK_APBC_UART0 0 +#define CLK_APBC_UART2 1 +#define CLK_APBC_UART3 2 +#define CLK_APBC_UART4 3 +#define CLK_APBC_UART5 4 +#define CLK_APBC_UART6 5 +#define CLK_APBC_UART7 6 +#define CLK_APBC_UART8 7 +#define CLK_APBC_UART9 8 +#define CLK_APBC_UART10 9 +#define CLK_APBC_UART0_BUS 10 +#define CLK_APBC_UART2_BUS 11 +#define CLK_APBC_UART3_BUS 12 +#define CLK_APBC_UART4_BUS 13 +#define CLK_APBC_UART5_BUS 14 +#define CLK_APBC_UART6_BUS 15 +#define CLK_APBC_UART7_BUS 16 +#define CLK_APBC_UART8_BUS 17 +#define CLK_APBC_UART9_BUS 18 +#define CLK_APBC_UART10_BUS 19 +#define CLK_APBC_GPIO 20 +#define CLK_APBC_GPIO_BUS 21 +#define CLK_APBC_PWM0 22 +#define CLK_APBC_PWM1 23 +#define CLK_APBC_PWM2 24 +#define CLK_APBC_PWM3 25 +#define CLK_APBC_PWM4 26 +#define CLK_APBC_PWM5 27 +#define CLK_APBC_PWM6 28 +#define CLK_APBC_PWM7 29 +#define CLK_APBC_PWM8 30 +#define CLK_APBC_PWM9 31 +#define CLK_APBC_PWM10 32 +#define CLK_APBC_PWM11 33 +#define CLK_APBC_PWM12 34 +#define CLK_APBC_PWM13 35 +#define CLK_APBC_PWM14 36 +#define CLK_APBC_PWM15 37 +#define CLK_APBC_PWM16 38 +#define CLK_APBC_PWM17 39 +#define CLK_APBC_PWM18 40 +#define CLK_APBC_PWM19 41 +#define CLK_APBC_PWM0_BUS 42 +#define CLK_APBC_PWM1_BUS 43 +#define CLK_APBC_PWM2_BUS 44 +#define CLK_APBC_PWM3_BUS 45 +#define CLK_APBC_PWM4_BUS 46 +#define CLK_APBC_PWM5_BUS 47 +#define CLK_APBC_PWM6_BUS 48 +#define CLK_APBC_PWM7_BUS 49 +#define CLK_APBC_PWM8_BUS 50 +#define CLK_APBC_PWM9_BUS 51 +#define CLK_APBC_PWM10_BUS 52 +#define CLK_APBC_PWM11_BUS 53 +#define CLK_APBC_PWM12_BUS 54 +#define CLK_APBC_PWM13_BUS 55 +#define CLK_APBC_PWM14_BUS 56 +#define CLK_APBC_PWM15_BUS 57 +#define CLK_APBC_PWM16_BUS 58 +#define CLK_APBC_PWM17_BUS 59 +#define CLK_APBC_PWM18_BUS 60 +#define CLK_APBC_PWM19_BUS 61 +#define CLK_APBC_SPI0_I2S_BCLK 62 +#define CLK_APBC_SPI1_I2S_BCLK 63 +#define CLK_APBC_SPI3_I2S_BCLK 64 +#define CLK_APBC_SPI0 65 +#define CLK_APBC_SPI1 66 +#define CLK_APBC_SPI3 67 +#define CLK_APBC_SPI0_BUS 68 +#define CLK_APBC_SPI1_BUS 69 +#define CLK_APBC_SPI3_BUS 70 +#define CLK_APBC_RTC 71 +#define CLK_APBC_RTC_BUS 72 +#define CLK_APBC_TWSI0 73 +#define CLK_APBC_TWSI1 74 +#define CLK_APBC_TWSI2 75 +#define CLK_APBC_TWSI4 76 +#define CLK_APBC_TWSI5 77 +#define CLK_APBC_TWSI6 78 +#define CLK_APBC_TWSI8 79 +#define CLK_APBC_TWSI0_BUS 80 +#define CLK_APBC_TWSI1_BUS 81 +#define CLK_APBC_TWSI2_BUS 82 +#define CLK_APBC_TWSI4_BUS 83 +#define CLK_APBC_TWSI5_BUS 84 +#define CLK_APBC_TWSI6_BUS 85 +#define CLK_APBC_TWSI8_BUS 86 +#define CLK_APBC_TIMERS0 87 +#define CLK_APBC_TIMERS1 88 +#define CLK_APBC_TIMERS2 89 +#define CLK_APBC_TIMERS3 90 +#define CLK_APBC_TIMERS4 91 +#define CLK_APBC_TIMERS5 92 +#define CLK_APBC_TIMERS6 93 +#define CLK_APBC_TIMERS7 94 +#define CLK_APBC_TIMERS0_BUS 95 +#define CLK_APBC_TIMERS1_BUS 96 +#define CLK_APBC_TIMERS2_BUS 97 +#define CLK_APBC_TIMERS3_BUS 98 +#define CLK_APBC_TIMERS4_BUS 99 +#define CLK_APBC_TIMERS5_BUS 100 +#define CLK_APBC_TIMERS6_BUS 101 +#define CLK_APBC_TIMERS7_BUS 102 +#define CLK_APBC_AIB 103 +#define CLK_APBC_AIB_BUS 104 +#define CLK_APBC_ONEWIRE 105 +#define CLK_APBC_ONEWIRE_BUS 106 +#define CLK_APBC_I2S0_BCLK 107 +#define CLK_APBC_I2S1_BCLK 108 +#define CLK_APBC_I2S2_BCLK 109 +#define CLK_APBC_I2S3_BCLK 110 +#define CLK_APBC_I2S4_BCLK 111 +#define CLK_APBC_I2S5_BCLK 112 +#define CLK_APBC_I2S0 113 +#define CLK_APBC_I2S1 114 +#define CLK_APBC_I2S2 115 +#define CLK_APBC_I2S3 116 +#define CLK_APBC_I2S4 117 +#define CLK_APBC_I2S5 118 +#define CLK_APBC_I2S0_BUS 119 +#define CLK_APBC_I2S1_BUS 120 +#define CLK_APBC_I2S2_BUS 121 +#define CLK_APBC_I2S3_BUS 122 +#define CLK_APBC_I2S4_BUS 123 +#define CLK_APBC_I2S5_BUS 124 +#define CLK_APBC_DRO 125 +#define CLK_APBC_IR0 126 +#define CLK_APBC_IR1 127 +#define CLK_APBC_TSEN 128 +#define CLK_APBC_TSEN_BUS 129 +#define CLK_APBC_IPC_AP2RCPU 130 +#define CLK_APBC_IPC_AP2RCPU_BUS 131 +#define CLK_APBC_CAN0 132 +#define CLK_APBC_CAN1 133 +#define CLK_APBC_CAN2 134 +#define CLK_APBC_CAN3 135 +#define CLK_APBC_CAN4 136 +#define CLK_APBC_CAN0_BUS 137 +#define CLK_APBC_CAN1_BUS 138 +#define CLK_APBC_CAN2_BUS 139 +#define CLK_APBC_CAN3_BUS 140 +#define CLK_APBC_CAN4_BUS 141 + +/* APMU clocks */ +#define CLK_APMU_AXICLK 0 +#define CLK_APMU_CCI550 1 +#define CLK_APMU_CPU_C0_CORE 2 +#define CLK_APMU_CPU_C1_CORE 3 +#define CLK_APMU_CPU_C2_CORE 4 +#define CLK_APMU_CPU_C3_CORE 5 +#define CLK_APMU_CCIC2PHY 6 +#define CLK_APMU_CCIC3PHY 7 +#define CLK_APMU_CSI 8 +#define CLK_APMU_ISP_BUS 9 +#define CLK_APMU_D1P_1228P8 10 +#define CLK_APMU_D1P_819P2 11 +#define CLK_APMU_D1P_614P4 12 +#define CLK_APMU_D1P_491P52 13 +#define CLK_APMU_D1P_409P6 14 +#define CLK_APMU_D1P_307P2 15 +#define CLK_APMU_D1P_245P76 16 +#define CLK_APMU_V2D 17 +#define CLK_APMU_DSI_ESC 18 +#define CLK_APMU_LCD_HCLK 19 +#define CLK_APMU_LCD_DSC 20 +#define CLK_APMU_LCD_PXCLK 21 +#define CLK_APMU_LCD_MCLK 22 +#define CLK_APMU_CCIC_4X 23 +#define CLK_APMU_CCIC1PHY 24 +#define CLK_APMU_SC2_HCLK 25 +#define CLK_APMU_SDH_AXI 26 +#define CLK_APMU_SDH0 27 +#define CLK_APMU_SDH1 28 +#define CLK_APMU_SDH2 29 +#define CLK_APMU_USB2_BUS 30 +#define CLK_APMU_USB3_PORTA_BUS 31 +#define CLK_APMU_USB3_PORTB_BUS 32 +#define CLK_APMU_USB3_PORTC_BUS 33 +#define CLK_APMU_USB3_PORTD_BUS 34 +#define CLK_APMU_QSPI 35 +#define CLK_APMU_QSPI_BUS 36 +#define CLK_APMU_DMA 37 +#define CLK_APMU_AES_WTM 38 +#define CLK_APMU_VPU 39 +#define CLK_APMU_DTC 40 +#define CLK_APMU_GPU 41 +#define CLK_APMU_MC_AHB 42 +#define CLK_APMU_TOP_DCLK 43 +#define CLK_APMU_UCIE 44 +#define CLK_APMU_UCIE_SBCLK 45 +#define CLK_APMU_RCPU 46 +#define CLK_APMU_DSI4LN2_DSI_ESC 47 +#define CLK_APMU_DSI4LN2_LCD_DSC 48 +#define CLK_APMU_DSI4LN2_LCD_PXCLK 49 +#define CLK_APMU_DSI4LN2_LCD_MCLK 50 +#define CLK_APMU_DSI4LN2_DPU_ACLK 51 +#define CLK_APMU_DPU_ACLK 52 +#define CLK_APMU_UFS_ACLK 53 +#define CLK_APMU_EDP0_PXCLK 54 +#define CLK_APMU_EDP1_PXCLK 55 +#define CLK_APMU_PCIE_PORTA_MSTE 56 +#define CLK_APMU_PCIE_PORTA_SLV 57 +#define CLK_APMU_PCIE_PORTB_MSTE 58 +#define CLK_APMU_PCIE_PORTB_SLV 59 +#define CLK_APMU_PCIE_PORTC_MSTE 60 +#define CLK_APMU_PCIE_PORTC_SLV 61 +#define CLK_APMU_PCIE_PORTD_MSTE 62 +#define CLK_APMU_PCIE_PORTD_SLV 63 +#define CLK_APMU_PCIE_PORTE_MSTE 64 +#define CLK_APMU_PCIE_PORTE_SLV 65 +#define CLK_APMU_EMAC0_BUS 66 +#define CLK_APMU_EMAC0_REF 67 +#define CLK_APMU_EMAC0_1588 68 +#define CLK_APMU_EMAC0_RGMII_TX 69 +#define CLK_APMU_EMAC1_BUS 70 +#define CLK_APMU_EMAC1_REF 71 +#define CLK_APMU_EMAC1_1588 72 +#define CLK_APMU_EMAC1_RGMII_TX 73 +#define CLK_APMU_EMAC2_BUS 74 +#define CLK_APMU_EMAC2_REF 75 +#define CLK_APMU_EMAC2_1588 76 +#define CLK_APMU_EMAC2_RGMII_TX 77 +#define CLK_APMU_ESPI_SCLK_SRC 78 +#define CLK_APMU_ESPI_SCLK 79 +#define CLK_APMU_ESPI_MCLK 80 +#define CLK_APMU_CAM_SRC1 81 +#define CLK_APMU_CAM_SRC2 82 +#define CLK_APMU_CAM_SRC3 83 +#define CLK_APMU_CAM_SRC4 84 +#define CLK_APMU_ISIM_VCLK0 85 +#define CLK_APMU_ISIM_VCLK1 86 +#define CLK_APMU_ISIM_VCLK2 87 +#define CLK_APMU_ISIM_VCLK3 88 + +/* DCIU clocks */ +#define CLK_DCIU_HDMA 0 +#define CLK_DCIU_DMA350 1 +#define CLK_DCIU_C2_TCM_PIPE 2 +#define CLK_DCIU_C3_TCM_PIPE 3 + +#endif /* _DT_BINDINGS_CLOCK_SPACEMIT_K3_CLOCKS_H_ */ diff --git a/include/dt-bindings/clock/thead,th1520-clk-ap.h b/include/dt-bindings/clock/thead,th1520-clk-ap.h index 09a9aa7b3ab1..68b35cc61204 100644 --- a/include/dt-bindings/clock/thead,th1520-clk-ap.h +++ b/include/dt-bindings/clock/thead,th1520-clk-ap.h @@ -93,6 +93,7 @@ #define CLK_SRAM3 83 #define CLK_PLL_GMAC_100M 84 #define CLK_UART_SCLK 85 +#define CLK_C910_BUS 86 /* VO clocks */ #define CLK_AXI4_VO_ACLK 0 diff --git a/include/dt-bindings/interconnect/mediatek,mt8196.h b/include/dt-bindings/interconnect/mediatek,mt8196.h new file mode 100644 index 000000000000..de700fa73223 --- /dev/null +++ b/include/dt-bindings/interconnect/mediatek,mt8196.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) 2025 Collabora Ltd. + * AngeloGioacchino Del Regno + */ + +#ifndef __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8196_H +#define __DT_BINDINGS_INTERCONNECT_MEDIATEK_MT8196_H + +#define SLAVE_DDR_EMI 0 +#define MASTER_MCUSYS 1 +#define MASTER_MCU_0 2 +#define MASTER_MCU_1 3 +#define MASTER_MCU_2 4 +#define MASTER_MCU_3 5 +#define MASTER_MCU_4 6 +#define MASTER_GPUSYS 7 +#define MASTER_MMSYS 8 +#define MASTER_MM_VPU 9 +#define MASTER_MM_DISP 10 +#define MASTER_MM_VDEC 11 +#define MASTER_MM_VENC 12 +#define MASTER_MM_CAM 13 +#define MASTER_MM_IMG 14 +#define MASTER_MM_MDP 15 +#define MASTER_VPUSYS 16 +#define MASTER_VPU_0 17 +#define MASTER_VPU_1 18 +#define MASTER_MDLASYS 19 +#define MASTER_MDLA_0 20 +#define MASTER_UFS 21 +#define MASTER_PCIE 22 +#define MASTER_USB 23 +#define MASTER_WIFI 24 +#define MASTER_BT 25 +#define MASTER_NETSYS 26 +#define MASTER_DBGIF 27 +#define SLAVE_HRT_DDR_EMI 28 +#define MASTER_HRT_MMSYS 29 +#define MASTER_HRT_MM_DISP 30 +#define MASTER_HRT_MM_VDEC 31 +#define MASTER_HRT_MM_VENC 32 +#define MASTER_HRT_MM_CAM 33 +#define MASTER_HRT_MM_IMG 34 +#define MASTER_HRT_MM_MDP 35 +#define MASTER_HRT_ADSP 36 +#define MASTER_HRT_DBGIF 37 +#endif diff --git a/include/dt-bindings/phy/phy.h b/include/dt-bindings/phy/phy.h index f8d4094f0880..979b5dfd8353 100644 --- a/include/dt-bindings/phy/phy.h +++ b/include/dt-bindings/phy/phy.h @@ -23,6 +23,7 @@ #define PHY_TYPE_DPHY 10 #define PHY_TYPE_CPHY 11 #define PHY_TYPE_USXGMII 12 +#define PHY_TYPE_XAUI 13 #define PHY_POL_NORMAL 0 #define PHY_POL_INVERT 1 diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h index 30fbbde81c5c..056ef7b6b360 100644 --- a/include/hyperv/hvgdk_mini.h +++ b/include/hyperv/hvgdk_mini.h @@ -14,33 +14,36 @@ struct hv_u128 { } __packed; /* NOTE: when adding below, update hv_result_to_string() */ -#define HV_STATUS_SUCCESS 0x0 -#define HV_STATUS_INVALID_HYPERCALL_CODE 0x2 -#define HV_STATUS_INVALID_HYPERCALL_INPUT 0x3 -#define HV_STATUS_INVALID_ALIGNMENT 0x4 -#define HV_STATUS_INVALID_PARAMETER 0x5 -#define HV_STATUS_ACCESS_DENIED 0x6 -#define HV_STATUS_INVALID_PARTITION_STATE 0x7 -#define HV_STATUS_OPERATION_DENIED 0x8 -#define HV_STATUS_UNKNOWN_PROPERTY 0x9 -#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE 0xA -#define HV_STATUS_INSUFFICIENT_MEMORY 0xB -#define HV_STATUS_INVALID_PARTITION_ID 0xD -#define HV_STATUS_INVALID_VP_INDEX 0xE -#define HV_STATUS_NOT_FOUND 0x10 -#define HV_STATUS_INVALID_PORT_ID 0x11 -#define HV_STATUS_INVALID_CONNECTION_ID 0x12 -#define HV_STATUS_INSUFFICIENT_BUFFERS 0x13 -#define HV_STATUS_NOT_ACKNOWLEDGED 0x14 -#define HV_STATUS_INVALID_VP_STATE 0x15 -#define HV_STATUS_NO_RESOURCES 0x1D -#define HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED 0x20 -#define HV_STATUS_INVALID_LP_INDEX 0x41 -#define HV_STATUS_INVALID_REGISTER_VALUE 0x50 -#define HV_STATUS_OPERATION_FAILED 0x71 -#define HV_STATUS_TIME_OUT 0x78 -#define HV_STATUS_CALL_PENDING 0x79 -#define HV_STATUS_VTL_ALREADY_ENABLED 0x86 +#define HV_STATUS_SUCCESS 0x0 +#define HV_STATUS_INVALID_HYPERCALL_CODE 0x2 +#define HV_STATUS_INVALID_HYPERCALL_INPUT 0x3 +#define HV_STATUS_INVALID_ALIGNMENT 0x4 +#define HV_STATUS_INVALID_PARAMETER 0x5 +#define HV_STATUS_ACCESS_DENIED 0x6 +#define HV_STATUS_INVALID_PARTITION_STATE 0x7 +#define HV_STATUS_OPERATION_DENIED 0x8 +#define HV_STATUS_UNKNOWN_PROPERTY 0x9 +#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE 0xA +#define HV_STATUS_INSUFFICIENT_MEMORY 0xB +#define HV_STATUS_INVALID_PARTITION_ID 0xD +#define HV_STATUS_INVALID_VP_INDEX 0xE +#define HV_STATUS_NOT_FOUND 0x10 +#define HV_STATUS_INVALID_PORT_ID 0x11 +#define HV_STATUS_INVALID_CONNECTION_ID 0x12 +#define HV_STATUS_INSUFFICIENT_BUFFERS 0x13 +#define HV_STATUS_NOT_ACKNOWLEDGED 0x14 +#define HV_STATUS_INVALID_VP_STATE 0x15 +#define HV_STATUS_NO_RESOURCES 0x1D +#define HV_STATUS_PROCESSOR_FEATURE_NOT_SUPPORTED 0x20 +#define HV_STATUS_INVALID_LP_INDEX 0x41 +#define HV_STATUS_INVALID_REGISTER_VALUE 0x50 +#define HV_STATUS_OPERATION_FAILED 0x71 +#define HV_STATUS_INSUFFICIENT_ROOT_MEMORY 0x73 +#define HV_STATUS_INSUFFICIENT_CONTIGUOUS_MEMORY 0x75 +#define HV_STATUS_TIME_OUT 0x78 +#define HV_STATUS_CALL_PENDING 0x79 +#define HV_STATUS_INSUFFICIENT_CONTIGUOUS_ROOT_MEMORY 0x83 +#define HV_STATUS_VTL_ALREADY_ENABLED 0x86 /* * The Hyper-V TimeRefCount register and the TSC @@ -474,6 +477,7 @@ union hv_vp_assist_msr_contents { /* HV_REGISTER_VP_ASSIST_PAGE */ #define HVCALL_NOTIFY_PARTITION_EVENT 0x0087 #define HVCALL_ENTER_SLEEP_STATE 0x0084 #define HVCALL_NOTIFY_PORT_RING_EMPTY 0x008b +#define HVCALL_SCRUB_PARTITION 0x008d #define HVCALL_REGISTER_INTERCEPT_RESULT 0x0091 #define HVCALL_ASSERT_VIRTUAL_INTERRUPT 0x0094 #define HVCALL_CREATE_PORT 0x0095 diff --git a/include/hyperv/hvhdk.h b/include/hyperv/hvhdk.h index 08965970c17d..245f3db53bf1 100644 --- a/include/hyperv/hvhdk.h +++ b/include/hyperv/hvhdk.h @@ -10,6 +10,13 @@ #include "hvhdk_mini.h" #include "hvgdk.h" +/* + * Hypervisor statistics page format + */ +struct hv_stats_page { + u64 data[HV_HYP_PAGE_SIZE / sizeof(u64)]; +} __packed; + /* Bits for dirty mask of hv_vp_register_page */ #define HV_X64_REGISTER_CLASS_GENERAL 0 #define HV_X64_REGISTER_CLASS_IP 1 @@ -328,6 +335,8 @@ union hv_partition_isolation_properties { #define HV_PARTITION_ISOLATION_HOST_TYPE_RESERVED 0x2 /* Note: Exo partition is enabled by default */ +#define HV_PARTITION_CREATION_FLAG_SMT_ENABLED_GUEST BIT(0) +#define HV_PARTITION_CREATION_FLAG_NESTED_VIRTUALIZATION_CAPABLE BIT(1) #define HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED BIT(4) #define HV_PARTITION_CREATION_FLAG_EXO_PARTITION BIT(8) #define HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED BIT(13) diff --git a/include/hyperv/hvhdk_mini.h b/include/hyperv/hvhdk_mini.h index 41a29bf8ec14..091c03e26046 100644 --- a/include/hyperv/hvhdk_mini.h +++ b/include/hyperv/hvhdk_mini.h @@ -7,6 +7,8 @@ #include "hvgdk_mini.h" +#define HV_MAX_CONTIGUOUS_ALLOCATION_PAGES 8 + /* * Doorbell connection_info flags. */ @@ -87,6 +89,9 @@ enum hv_partition_property_code { HV_PARTITION_PROPERTY_PRIVILEGE_FLAGS = 0x00010000, HV_PARTITION_PROPERTY_SYNTHETIC_PROC_FEATURES = 0x00010001, + /* Integrated scheduling properties */ + HV_PARTITION_PROPERTY_INTEGRATED_SCHEDULER_ENABLED = 0x00020005, + /* Resource properties */ HV_PARTITION_PROPERTY_GPA_PAGE_ACCESS_TRACKING = 0x00050005, HV_PARTITION_PROPERTY_UNIMPLEMENTED_MSR_ACTION = 0x00050017, @@ -102,7 +107,7 @@ enum hv_partition_property_code { }; #define HV_PARTITION_VMM_CAPABILITIES_BANK_COUNT 1 -#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT 59 +#define HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT 57 struct hv_partition_property_vmm_capabilities { u16 bank_count; @@ -119,6 +124,8 @@ struct hv_partition_property_vmm_capabilities { u64 reservedbit3: 1; #endif u64 assignable_synthetic_proc_features: 1; + u64 reservedbit5: 1; + u64 vmm_enable_integrated_scheduler : 1; u64 reserved0: HV_PARTITION_VMM_CAPABILITIES_RESERVED_BITFIELD_COUNT; } __packed; }; diff --git a/include/kunit/resource.h b/include/kunit/resource.h index 4ad69a2642a5..c330ed3e751c 100644 --- a/include/kunit/resource.h +++ b/include/kunit/resource.h @@ -243,7 +243,7 @@ kunit_alloc_and_get_resource(struct kunit *test, struct kunit_resource *res; int ret; - res = kzalloc(sizeof(*res), internal_gfp); + res = kzalloc_obj(*res, internal_gfp); if (!res) return NULL; @@ -285,7 +285,7 @@ static inline void *kunit_alloc_resource(struct kunit *test, { struct kunit_resource *res; - res = kzalloc(sizeof(*res), internal_gfp); + res = kzalloc_obj(*res, internal_gfp); if (!res) return NULL; diff --git a/include/kunit/run-in-irq-context.h b/include/kunit/run-in-irq-context.h index c89b1b1b12dd..bfe60d6cf28d 100644 --- a/include/kunit/run-in-irq-context.h +++ b/include/kunit/run-in-irq-context.h @@ -12,16 +12,16 @@ #include #include -#define KUNIT_IRQ_TEST_HRTIMER_INTERVAL us_to_ktime(5) - struct kunit_irq_test_state { bool (*func)(void *test_specific_state); void *test_specific_state; bool task_func_reported_failure; bool hardirq_func_reported_failure; bool softirq_func_reported_failure; + atomic_t task_func_calls; atomic_t hardirq_func_calls; atomic_t softirq_func_calls; + ktime_t interval; struct hrtimer timer; struct work_struct bh_work; }; @@ -30,14 +30,25 @@ static enum hrtimer_restart kunit_irq_test_timer_func(struct hrtimer *timer) { struct kunit_irq_test_state *state = container_of(timer, typeof(*state), timer); + int task_calls, hardirq_calls, softirq_calls; WARN_ON_ONCE(!in_hardirq()); - atomic_inc(&state->hardirq_func_calls); + task_calls = atomic_read(&state->task_func_calls); + hardirq_calls = atomic_inc_return(&state->hardirq_func_calls); + softirq_calls = atomic_read(&state->softirq_func_calls); + + /* + * If the timer is firing too often for the softirq or task to ever have + * a chance to run, increase the timer interval. This is needed on very + * slow systems. + */ + if (hardirq_calls >= 20 && (softirq_calls == 0 || task_calls == 0)) + state->interval = ktime_add_ns(state->interval, 250); if (!state->func(state->test_specific_state)) state->hardirq_func_reported_failure = true; - hrtimer_forward_now(&state->timer, KUNIT_IRQ_TEST_HRTIMER_INTERVAL); + hrtimer_forward_now(&state->timer, state->interval); queue_work(system_bh_wq, &state->bh_work); return HRTIMER_RESTART; } @@ -86,10 +97,14 @@ static inline void kunit_run_irq_test(struct kunit *test, bool (*func)(void *), struct kunit_irq_test_state state = { .func = func, .test_specific_state = test_specific_state, + /* + * Start with a 5us timer interval. If the system can't keep + * up, kunit_irq_test_timer_func() will increase it. + */ + .interval = us_to_ktime(5), }; unsigned long end_jiffies; - int hardirq_calls, softirq_calls; - bool allctx = false; + int task_calls, hardirq_calls, softirq_calls; /* * Set up a hrtimer (the way we access hardirq context) and a work @@ -104,21 +119,18 @@ static inline void kunit_run_irq_test(struct kunit *test, bool (*func)(void *), * and hardirq), or 1 second, whichever comes first. */ end_jiffies = jiffies + HZ; - hrtimer_start(&state.timer, KUNIT_IRQ_TEST_HRTIMER_INTERVAL, - HRTIMER_MODE_REL_HARD); - for (int task_calls = 0, calls = 0; - ((calls < max_iterations) || !allctx) && - !time_after(jiffies, end_jiffies); - task_calls++) { + hrtimer_start(&state.timer, state.interval, HRTIMER_MODE_REL_HARD); + do { if (!func(test_specific_state)) state.task_func_reported_failure = true; + task_calls = atomic_inc_return(&state.task_func_calls); hardirq_calls = atomic_read(&state.hardirq_func_calls); softirq_calls = atomic_read(&state.softirq_func_calls); - calls = task_calls + hardirq_calls + softirq_calls; - allctx = (task_calls > 0) && (hardirq_calls > 0) && - (softirq_calls > 0); - } + } while ((task_calls + hardirq_calls + softirq_calls < max_iterations || + (task_calls == 0 || hardirq_calls == 0 || + softirq_calls == 0)) && + !time_after(jiffies, end_jiffies)); /* Cancel the timer and work. */ hrtimer_cancel(&state.timer); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3a412dcebc29..4d2f0bed7a06 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -66,7 +66,7 @@ static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) { struct fwnode_handle *fwnode; - fwnode = kzalloc(sizeof(struct fwnode_handle), GFP_KERNEL); + fwnode = kzalloc_obj(struct fwnode_handle); if (!fwnode) return NULL; diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h index d59553324a84..8808ee76e73c 100644 --- a/include/linux/blk_types.h +++ b/include/linux/blk_types.h @@ -273,7 +273,13 @@ struct bio { * Everything starting with bi_max_vecs will be preserved by bio_reset() */ - unsigned short bi_max_vecs; /* max bvl_vecs we can hold */ + /* + * Number of elements in `bi_io_vec` that were allocated for this bio. + * Only used by the bio submitter to make `bio_add_page` fail once full + * and to free the `bi_io_vec` allocation. Must not be used in drivers + * and does not hold a useful value for cloned bios. + */ + unsigned short bi_max_vecs; atomic_t __bi_cnt; /* pin count */ @@ -339,32 +345,33 @@ typedef __u32 __bitwise blk_mq_req_flags_t; * meaning. */ enum req_op { - /* read sectors from the device */ + /** @REQ_OP_READ: read sectors from the device */ REQ_OP_READ = (__force blk_opf_t)0, - /* write sectors to the device */ + /** @REQ_OP_WRITE: write sectors to the device */ REQ_OP_WRITE = (__force blk_opf_t)1, - /* flush the volatile write cache */ + /** @REQ_OP_FLUSH: flush the volatile write cache */ REQ_OP_FLUSH = (__force blk_opf_t)2, - /* discard sectors */ + /** @REQ_OP_DISCARD: discard sectors */ REQ_OP_DISCARD = (__force blk_opf_t)3, - /* securely erase sectors */ + /** @REQ_OP_SECURE_ERASE: securely erase sectors */ REQ_OP_SECURE_ERASE = (__force blk_opf_t)5, - /* write data at the current zone write pointer */ + /** @REQ_OP_ZONE_APPEND: write data at the current zone write pointer */ REQ_OP_ZONE_APPEND = (__force blk_opf_t)7, - /* write the zero filled sector many times */ + /** @REQ_OP_WRITE_ZEROES: write the zero filled sector many times */ REQ_OP_WRITE_ZEROES = (__force blk_opf_t)9, - /* Open a zone */ + /** @REQ_OP_ZONE_OPEN: Open a zone */ REQ_OP_ZONE_OPEN = (__force blk_opf_t)11, - /* Close a zone */ + /** @REQ_OP_ZONE_CLOSE: Close a zone */ REQ_OP_ZONE_CLOSE = (__force blk_opf_t)13, - /* Transition a zone to full */ + /** @REQ_OP_ZONE_FINISH: Transition a zone to full */ REQ_OP_ZONE_FINISH = (__force blk_opf_t)15, - /* reset a zone write pointer */ + /** @REQ_OP_ZONE_RESET: reset a zone write pointer */ REQ_OP_ZONE_RESET = (__force blk_opf_t)17, - /* reset all the zone present on the device */ + /** @REQ_OP_ZONE_RESET_ALL: reset all the zone present on the device */ REQ_OP_ZONE_RESET_ALL = (__force blk_opf_t)19, /* Driver private requests */ + /* private: */ REQ_OP_DRV_IN = (__force blk_opf_t)34, REQ_OP_DRV_OUT = (__force blk_opf_t)35, diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 99ef8cd7673c..d463b9b5a0a5 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1259,7 +1259,7 @@ extern void blk_io_schedule(void); int blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask); -int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, +void __blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, struct bio **biop); int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp); diff --git a/include/linux/bpf.h b/include/linux/bpf.h index cd9b96434904..05b34a6355b0 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -124,7 +124,7 @@ struct bpf_map_ops { u32 (*map_fd_sys_lookup_elem)(void *ptr); void (*map_seq_show_elem)(struct bpf_map *map, void *key, struct seq_file *m); - int (*map_check_btf)(const struct bpf_map *map, + int (*map_check_btf)(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type); @@ -656,7 +656,7 @@ static inline bool bpf_map_support_seq_show(const struct bpf_map *map) map->ops->map_seq_show_elem; } -int map_check_no_btf(const struct bpf_map *map, +int map_check_no_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type); @@ -2299,7 +2299,7 @@ static inline bool bpf_map_flags_access_ok(u32 access_flags) static inline struct bpf_map_owner *bpf_map_owner_alloc(struct bpf_map *map) { - return kzalloc(sizeof(*map->owner), GFP_ATOMIC); + return kzalloc_obj(*map->owner, GFP_ATOMIC); } static inline void bpf_map_owner_free(struct bpf_map *map) diff --git a/include/linux/bpf_local_storage.h b/include/linux/bpf_local_storage.h index 85efa9772530..8157e8da61d4 100644 --- a/include/linux/bpf_local_storage.h +++ b/include/linux/bpf_local_storage.h @@ -176,7 +176,7 @@ u32 bpf_local_storage_destroy(struct bpf_local_storage *local_storage); void bpf_local_storage_map_free(struct bpf_map *map, struct bpf_local_storage_cache *cache); -int bpf_local_storage_map_check_btf(const struct bpf_map *map, +int bpf_local_storage_map_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type); diff --git a/include/linux/bpf_mem_alloc.h b/include/linux/bpf_mem_alloc.h index e45162ef59bb..4ce0d27f8ea2 100644 --- a/include/linux/bpf_mem_alloc.h +++ b/include/linux/bpf_mem_alloc.h @@ -14,6 +14,8 @@ struct bpf_mem_alloc { struct obj_cgroup *objcg; bool percpu; struct work_struct work; + void (*dtor_ctx_free)(void *ctx); + void *dtor_ctx; }; /* 'size != 0' is for bpf_mem_alloc which manages fixed-size objects. @@ -32,6 +34,10 @@ int bpf_mem_alloc_percpu_init(struct bpf_mem_alloc *ma, struct obj_cgroup *objcg /* The percpu allocation with a specific unit size. */ int bpf_mem_alloc_percpu_unit_init(struct bpf_mem_alloc *ma, int size); void bpf_mem_alloc_destroy(struct bpf_mem_alloc *ma); +void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, + void (*dtor)(void *obj, void *ctx), + void (*dtor_ctx_free)(void *ctx), + void *ctx); /* Check the allocation size for kmalloc equivalent allocator */ int bpf_mem_alloc_check_size(bool percpu, size_t size); diff --git a/include/linux/build_bug.h b/include/linux/build_bug.h index 2cfbb4c65c78..d3dc5dc5f916 100644 --- a/include/linux/build_bug.h +++ b/include/linux/build_bug.h @@ -32,7 +32,8 @@ /** * BUILD_BUG_ON_MSG - break compile if a condition is true & emit supplied * error message. - * @condition: the condition which the compiler should know is false. + * @cond: the condition which the compiler should know is false. + * @msg: build-time error message * * See BUILD_BUG_ON for description. */ @@ -60,6 +61,7 @@ /** * static_assert - check integer constant expression at build time + * @expr: expression to be checked * * static_assert() is a wrapper for the C11 _Static_assert, with a * little macro magic to make the message optional (defaulting to the diff --git a/include/linux/bvec.h b/include/linux/bvec.h index 3fc0efa0825b..06fb60471aaf 100644 --- a/include/linux/bvec.h +++ b/include/linux/bvec.h @@ -75,14 +75,27 @@ static inline void bvec_set_virt(struct bio_vec *bv, void *vaddr, } struct bvec_iter { - sector_t bi_sector; /* device address in 512 byte - sectors */ - unsigned int bi_size; /* residual I/O count */ + /* + * Current device address in 512 byte sectors. Only updated by the bio + * iter wrappers and not the bvec iterator helpers themselves. + */ + sector_t bi_sector; - unsigned int bi_idx; /* current index into bvl_vec */ + /* + * Remaining size in bytes. + */ + unsigned int bi_size; - unsigned int bi_bvec_done; /* number of bytes completed in - current bvec */ + /* + * Current index into the bvec array. This indexes into `bi_io_vec` when + * iterating a bvec array that is part of a `bio`. + */ + unsigned int bi_idx; + + /* + * Current offset in the bvec entry pointed to by `bi_idx`. + */ + unsigned int bi_bvec_done; } __packed __aligned(4); struct bvec_iter_all { diff --git a/include/linux/ceph/ceph_fs.h b/include/linux/ceph/ceph_fs.h index 08e5dbe15ca4..69ac3e55a3fe 100644 --- a/include/linux/ceph/ceph_fs.h +++ b/include/linux/ceph/ceph_fs.h @@ -89,8 +89,9 @@ struct ceph_dir_layout { } __attribute__ ((packed)); /* crypto algorithms */ -#define CEPH_CRYPTO_NONE 0x0 -#define CEPH_CRYPTO_AES 0x1 +#define CEPH_CRYPTO_NONE 0x0 +#define CEPH_CRYPTO_AES 0x1 +#define CEPH_CRYPTO_AES256KRB5 0x2 /* AES256-CTS-HMAC384-192 */ #define CEPH_AES_IV "cephsageyudagreg" diff --git a/include/linux/clk.h b/include/linux/clk.h index c571e294f0ef..998ba3f261da 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -228,7 +228,24 @@ int devm_clk_rate_exclusive_get(struct device *dev, struct clk *clk); */ void clk_rate_exclusive_put(struct clk *clk); -#else +/** + * clk_save_context - save clock context for poweroff + * + * Saves the context of the clock register for powerstates in which the + * contents of the registers will be lost. Occurs deep within the suspend + * code so locking is not necessary. + */ +int clk_save_context(void); + +/** + * clk_restore_context - restore clock context after poweroff + * + * This occurs with all clocks enabled. Occurs deep within the resume code + * so locking is not necessary. + */ +void clk_restore_context(void); + +#else /* !CONFIG_COMMON_CLK */ static inline int clk_notifier_register(struct clk *clk, struct notifier_block *nb) @@ -293,7 +310,14 @@ static inline int devm_clk_rate_exclusive_get(struct device *dev, struct clk *cl static inline void clk_rate_exclusive_put(struct clk *clk) {} -#endif +static inline int clk_save_context(void) +{ + return 0; +} + +static inline void clk_restore_context(void) {} + +#endif /* !CONFIG_COMMON_CLK */ #ifdef CONFIG_HAVE_CLK_PREPARE /** @@ -305,8 +329,21 @@ static inline void clk_rate_exclusive_put(struct clk *clk) {} * Must not be called from within atomic context. */ int clk_prepare(struct clk *clk); + +/** + * clk_unprepare - undo preparation of a clock source + * @clk: clock source + * + * This undoes a previously prepared clock. The caller must balance + * the number of prepare and unprepare calls. + * + * Must not be called from within atomic context. + */ +void clk_unprepare(struct clk *clk); + int __must_check clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks); +void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); /** * clk_is_enabled_when_prepared - indicate if preparing a clock also enables it. @@ -324,13 +361,18 @@ int __must_check clk_bulk_prepare(int num_clks, * to be right. */ bool clk_is_enabled_when_prepared(struct clk *clk); -#else +#else /* !CONFIG_HAVE_CLK_PREPARE */ static inline int clk_prepare(struct clk *clk) { might_sleep(); return 0; } +static inline void clk_unprepare(struct clk *clk) +{ + might_sleep(); +} + static inline int __must_check clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks) { @@ -338,35 +380,17 @@ clk_bulk_prepare(int num_clks, const struct clk_bulk_data *clks) return 0; } -static inline bool clk_is_enabled_when_prepared(struct clk *clk) -{ - return false; -} -#endif - -/** - * clk_unprepare - undo preparation of a clock source - * @clk: clock source - * - * This undoes a previously prepared clock. The caller must balance - * the number of prepare and unprepare calls. - * - * Must not be called from within atomic context. - */ -#ifdef CONFIG_HAVE_CLK_PREPARE -void clk_unprepare(struct clk *clk); -void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks); -#else -static inline void clk_unprepare(struct clk *clk) -{ - might_sleep(); -} static inline void clk_bulk_unprepare(int num_clks, const struct clk_bulk_data *clks) { might_sleep(); } -#endif + +static inline bool clk_is_enabled_when_prepared(struct clk *clk) +{ + return false; +} +#endif /* !CONFIG_HAVE_CLK_PREPARE */ #ifdef CONFIG_HAVE_CLK /** @@ -949,23 +973,6 @@ struct clk *clk_get_parent(struct clk *clk); */ struct clk *clk_get_sys(const char *dev_id, const char *con_id); -/** - * clk_save_context - save clock context for poweroff - * - * Saves the context of the clock register for powerstates in which the - * contents of the registers will be lost. Occurs deep within the suspend - * code so locking is not necessary. - */ -int clk_save_context(void); - -/** - * clk_restore_context - restore clock context after poweroff - * - * This occurs with all clocks enabled. Occurs deep within the resume code - * so locking is not necessary. - */ -void clk_restore_context(void); - #else /* !CONFIG_HAVE_CLK */ static inline struct clk *clk_get(struct device *dev, const char *id) @@ -1152,14 +1159,7 @@ static inline struct clk *clk_get_sys(const char *dev_id, const char *con_id) return NULL; } -static inline int clk_save_context(void) -{ - return 0; -} - -static inline void clk_restore_context(void) {} - -#endif +#endif /* !CONFIG_HAVE_CLK */ /* clk_prepare_enable helps cases using clk_enable in non-atomic context. */ static inline int clk_prepare_enable(struct clk *clk) diff --git a/include/linux/clk/renesas.h b/include/linux/clk/renesas.h index 69d8159deee3..c360df9fa735 100644 --- a/include/linux/clk/renesas.h +++ b/include/linux/clk/renesas.h @@ -35,6 +35,17 @@ void cpg_mssr_detach_dev(struct generic_pm_domain *unused, struct device *dev); #define cpg_mssr_detach_dev NULL #endif +enum { + PLL5_TARGET_DPI, + PLL5_TARGET_DSI +}; + +#ifdef CONFIG_CLK_RZG2L +void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target); +#else +static inline void rzg2l_cpg_dsi_div_set_divider(u8 divider, int target) { } +#endif + /** * struct rzv2h_pll_limits - PLL parameter constraints * diff --git a/include/linux/comedi/comedi_8254.h b/include/linux/comedi/comedi_8254.h index d527f04400df..91f5861061ec 100644 --- a/include/linux/comedi/comedi_8254.h +++ b/include/linux/comedi/comedi_8254.h @@ -83,11 +83,11 @@ typedef unsigned int comedi_8254_iocb_fn(struct comedi_8254 *i8254, int dir, * @divisor: divisor for single counter * @divisor1: divisor loaded into first cascaded counter * @divisor2: divisor loaded into second cascaded counter - * #next_div: next divisor for single counter + * @next_div: next divisor for single counter * @next_div1: next divisor to use for first cascaded counter * @next_div2: next divisor to use for second cascaded counter - * @clock_src; current clock source for each counter (driver specific) - * @gate_src; current gate source for each counter (driver specific) + * @clock_src: current clock source for each counter (driver specific) + * @gate_src: current gate source for each counter (driver specific) * @busy: flags used to indicate that a counter is "busy" * @insn_config: driver specific (*insn_config) callback */ diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index b1b141394d13..890076d0974b 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -552,7 +552,8 @@ struct ftrace_likely_data { * gcc: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fcounted_005fby_005fref * clang: https://clang.llvm.org/docs/LanguageExtensions.html#builtin-counted-by-ref */ -#if __has_builtin(__builtin_counted_by_ref) +#if __has_builtin(__builtin_counted_by_ref) && \ + !defined(CONFIG_CC_HAS_BROKEN_COUNTED_BY_REF) /** * __flex_counter() - Get pointer to counter member for the given * flexible array, if it was annotated with __counted_by() diff --git a/include/linux/console.h b/include/linux/console.h index 1346f0b4cd8b..5520e4477ad7 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -697,7 +697,6 @@ extern int unregister_console(struct console *); extern void console_lock(void); extern int console_trylock(void); extern void console_unlock(void); -extern void console_conditional_schedule(void); extern void console_unblank(void); extern void console_flush_on_panic(enum con_flush_mode mode); extern struct tty_driver *console_device(int *); diff --git a/include/linux/coresight-pmu.h b/include/linux/coresight-pmu.h index 89b0ac0014b0..2e179abe472a 100644 --- a/include/linux/coresight-pmu.h +++ b/include/linux/coresight-pmu.h @@ -21,30 +21,6 @@ */ #define CORESIGHT_LEGACY_CPU_TRACE_ID(cpu) (0x10 + (cpu * 2)) -/* - * Below are the definition of bit offsets for perf option, and works as - * arbitrary values for all ETM versions. - * - * Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore, - * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and - * directly use below macros as config bits. - */ -#define ETM_OPT_BRANCH_BROADCAST 8 -#define ETM_OPT_CYCACC 12 -#define ETM_OPT_CTXTID 14 -#define ETM_OPT_CTXTID2 15 -#define ETM_OPT_TS 28 -#define ETM_OPT_RETSTK 29 - -/* ETMv4 CONFIGR programming bits for the ETM OPTs */ -#define ETM4_CFG_BIT_BB 3 -#define ETM4_CFG_BIT_CYCACC 4 -#define ETM4_CFG_BIT_CTXTID 6 -#define ETM4_CFG_BIT_VMID 7 -#define ETM4_CFG_BIT_TS 11 -#define ETM4_CFG_BIT_RETSTK 12 -#define ETM4_CFG_BIT_VMID_OPT 15 - /* * Interpretation of the PERF_RECORD_AUX_OUTPUT_HW_ID payload. * Used to associate a CPU with the CoreSight Trace ID. diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index cbd402b4f974..65d76a38974b 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -176,7 +176,7 @@ static inline void set_mems_allowed(nodemask_t nodemask) task_unlock(current); } -extern bool cpuset_node_allowed(struct cgroup *cgroup, int nid); +extern void cpuset_nodes_allowed(struct cgroup *cgroup, nodemask_t *mask); #else /* !CONFIG_CPUSETS */ static inline bool cpusets_enabled(void) { return false; } @@ -299,9 +299,9 @@ static inline bool read_mems_allowed_retry(unsigned int seq) return false; } -static inline bool cpuset_node_allowed(struct cgroup *cgroup, int nid) +static inline void cpuset_nodes_allowed(struct cgroup *cgroup, nodemask_t *mask) { - return true; + nodes_copy(*mask, node_states[N_MEMORY]); } #endif /* !CONFIG_CPUSETS */ diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index dd6fc3b2133b..8315270e27b7 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -136,7 +136,7 @@ struct vmcore_range { static inline int vmcore_alloc_add_range(struct list_head *list, unsigned long long paddr, unsigned long long size) { - struct vmcore_range *m = kzalloc(sizeof(*m), GFP_KERNEL); + struct vmcore_range *m = kzalloc_obj(*m); if (!m) return -ENOMEM; diff --git a/include/linux/dax.h b/include/linux/dax.h index 9d624f4d9df6..bf103f317cac 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -65,11 +65,11 @@ size_t dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff, /* * Check if given mapping is supported by the file / underlying device. */ -static inline bool daxdev_mapping_supported(vm_flags_t vm_flags, +static inline bool daxdev_mapping_supported(const struct vm_area_desc *desc, const struct inode *inode, struct dax_device *dax_dev) { - if (!(vm_flags & VM_SYNC)) + if (!vma_desc_test_flags(desc, VMA_SYNC_BIT)) return true; if (!IS_DAX(inode)) return false; @@ -111,11 +111,11 @@ static inline void set_dax_nomc(struct dax_device *dax_dev) static inline void set_dax_synchronous(struct dax_device *dax_dev) { } -static inline bool daxdev_mapping_supported(vm_flags_t vm_flags, +static inline bool daxdev_mapping_supported(const struct vm_area_desc *desc, const struct inode *inode, struct dax_device *dax_dev) { - return !(vm_flags & VM_SYNC); + return !vma_desc_test_flags(desc, VMA_SYNC_BIT); } static inline size_t dax_recovery_write(struct dax_device *dax_dev, pgoff_t pgoff, void *addr, size_t bytes, struct iov_iter *i) diff --git a/include/linux/device/bus.h b/include/linux/device/bus.h index 99c3c83ea520..63de5f053c33 100644 --- a/include/linux/device/bus.h +++ b/include/linux/device/bus.h @@ -35,6 +35,8 @@ struct fwnode_handle; * otherwise. It may also return error code if determining that * the driver supports the device is not possible. In case of * -EPROBE_DEFER it will queue the device for deferred probing. + * Note: This callback may be invoked with or without the device + * lock held. * @uevent: Called when a device is added, removed, or a few other things * that generate uevents to add the environment variables. * @probe: Called when a new device or driver add to this bus, and callback diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h index 68c3c1e41014..5cd3ba53b4a1 100644 --- a/include/linux/dma-fence-chain.h +++ b/include/linux/dma-fence-chain.h @@ -91,7 +91,7 @@ dma_fence_chain_contained(struct dma_fence *fence) * intentional to enforce typesafety. */ #define dma_fence_chain_alloc() \ - ((struct dma_fence_chain *)kmalloc(sizeof(struct dma_fence_chain), GFP_KERNEL)) + kmalloc_obj(struct dma_fence_chain) /** * dma_fence_chain_free diff --git a/include/linux/dma/edma.h b/include/linux/dma/edma.h index 3080747689f6..270b5458aecf 100644 --- a/include/linux/dma/edma.h +++ b/include/linux/dma/edma.h @@ -27,7 +27,7 @@ struct dw_edma_region { }; /** - * struct dw_edma_core_ops - platform-specific eDMA methods + * struct dw_edma_plat_ops - platform-specific eDMA methods * @irq_vector: Get IRQ number of the passed eDMA channel. Note the * method accepts the channel id in the end-to-end * numbering with the eDMA write channels being placed @@ -63,19 +63,17 @@ enum dw_edma_chip_flags { /** * struct dw_edma_chip - representation of DesignWare eDMA controller hardware * @dev: struct device of the eDMA controller - * @id: instance ID * @nr_irqs: total number of DMA IRQs - * @ops DMA channel to IRQ number mapping - * @flags dw_edma_chip_flags - * @reg_base DMA register base address - * @ll_wr_cnt DMA write link list count - * @ll_rd_cnt DMA read link list count - * @rg_region DMA register region - * @ll_region_wr DMA descriptor link list memory for write channel - * @ll_region_rd DMA descriptor link list memory for read channel - * @dt_region_wr DMA data memory for write channel - * @dt_region_rd DMA data memory for read channel - * @mf DMA register map format + * @ops: DMA channel to IRQ number mapping + * @flags: dw_edma_chip_flags + * @reg_base: DMA register base address + * @ll_wr_cnt: DMA write link list count + * @ll_rd_cnt: DMA read link list count + * @ll_region_wr: DMA descriptor link list memory for write channel + * @ll_region_rd: DMA descriptor link list memory for read channel + * @dt_region_wr: DMA data memory for write channel + * @dt_region_rd: DMA data memory for read channel + * @mf: DMA register map format * @dw: struct dw_edma that is filled by dw_edma_probe() */ struct dw_edma_chip { diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h index 3a485cc0e0fa..194a4a49ff1d 100644 --- a/include/linux/eeprom_93cx6.h +++ b/include/linux/eeprom_93cx6.h @@ -31,10 +31,10 @@ * struct eeprom_93cx6 - control structure for setting the commands * for reading the eeprom data. * @data: private pointer for the driver. - * @register_read(struct eeprom_93cx6 *eeprom): handler to - * read the eeprom register, this function should set all reg_* fields. - * @register_write(struct eeprom_93cx6 *eeprom): handler to - * write to the eeprom register by using all reg_* fields. + * @register_read: handler to read the eeprom register; + * this function should set all reg_* fields. + * @register_write: handler to write to the eeprom register by using + * all reg_* fields. * @width: eeprom width, should be one of the PCI_EEPROM_WIDTH_* defines * @quirks: eeprom or controller quirks * @drive_data: Set if we're driving the data line. diff --git a/include/linux/eventpoll.h b/include/linux/eventpoll.h index ccb478eb174b..ea9ca0e4172a 100644 --- a/include/linux/eventpoll.h +++ b/include/linux/eventpoll.h @@ -82,11 +82,14 @@ static inline struct epoll_event __user * epoll_put_uevent(__poll_t revents, __u64 data, struct epoll_event __user *uevent) { - if (__put_user(revents, &uevent->events) || - __put_user(data, &uevent->data)) - return NULL; - + scoped_user_write_access_size(uevent, sizeof(*uevent), efault) { + unsafe_put_user(revents, &uevent->events, efault); + unsafe_put_user(data, &uevent->data, efault); + } return uevent+1; + +efault: + return NULL; } #endif diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 262e24d83313..8bcdba28b406 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h @@ -200,6 +200,10 @@ struct handle_to_path_ctx { * @get_parent: find the parent of a given directory * @commit_metadata: commit metadata changes to stable storage * + * Methods for open_by_handle(2) syscall with special kernel file systems: + * @permission: custom permission for opening a file by handle + * @open: custom open routine for opening file by handle + * * See Documentation/filesystems/nfs/exporting.rst for details on how to use * this interface correctly and the definition of the flags. * @@ -244,10 +248,14 @@ struct handle_to_path_ctx { * space cannot be allocated, a %ERR_PTR should be returned. * * @permission: - * Allow filesystems to specify a custom permission function. + * Allow filesystems to specify a custom permission function for the + * open_by_handle_at(2) syscall instead of the default permission check. + * This custom permission function is not respected by nfsd. * * @open: - * Allow filesystems to specify a custom open function. + * Allow filesystems to specify a custom open function for the + * open_by_handle_at(2) syscall instead of the default file_open_root(). + * This custom open function is not respected by nfsd. * * @commit_metadata: * @commit_metadata should commit metadata changes to stable storage. @@ -330,6 +338,15 @@ static inline bool exportfs_can_decode_fh(const struct export_operations *nop) return nop && nop->fh_to_dentry; } +static inline bool exportfs_may_export(const struct export_operations *nop) +{ + /* + * Do not allow nfs export for filesystems with custom ->open() or + * ->permission() ops, which nfsd does not respect (e.g. pidfs, nsfs). + */ + return exportfs_can_decode_fh(nop) && !nop->open && !nop->permission; +} + static inline bool exportfs_can_encode_fh(const struct export_operations *nop, int fh_flags) { diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index a7880787cad3..dc41722fcc9d 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -17,7 +17,6 @@ #define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */ #define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */ #define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */ -#define F2FS_SUM_BLKSIZE 4096 /* only support 4096 byte sum block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ #define F2FS_EXTENSION_LEN 8 /* max size of extension */ @@ -442,10 +441,8 @@ struct f2fs_sit_block { * from node's page's beginning to get a data block address. * ex) data_blkaddr = (block_t)(nodepage_start_address + ofs_in_node) */ -#define ENTRIES_IN_SUM (F2FS_SUM_BLKSIZE / 8) #define SUMMARY_SIZE (7) /* sizeof(struct f2fs_summary) */ #define SUM_FOOTER_SIZE (5) /* sizeof(struct summary_footer) */ -#define SUM_ENTRY_SIZE (SUMMARY_SIZE * ENTRIES_IN_SUM) /* a summary entry for a block in a segment */ struct f2fs_summary { @@ -468,22 +465,6 @@ struct summary_footer { __le32 check_sum; /* summary checksum */ } __packed; -#define SUM_JOURNAL_SIZE (F2FS_SUM_BLKSIZE - SUM_FOOTER_SIZE -\ - SUM_ENTRY_SIZE) -#define NAT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\ - sizeof(struct nat_journal_entry)) -#define NAT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) %\ - sizeof(struct nat_journal_entry)) -#define SIT_JOURNAL_ENTRIES ((SUM_JOURNAL_SIZE - 2) /\ - sizeof(struct sit_journal_entry)) -#define SIT_JOURNAL_RESERVED ((SUM_JOURNAL_SIZE - 2) %\ - sizeof(struct sit_journal_entry)) - -/* Reserved area should make size of f2fs_extra_info equals to - * that of nat_journal and sit_journal. - */ -#define EXTRA_INFO_RESERVED (SUM_JOURNAL_SIZE - 2 - 8) - /* * frequently updated NAT/SIT entries can be stored in the spare area in * summary blocks @@ -498,9 +479,16 @@ struct nat_journal_entry { struct f2fs_nat_entry ne; } __packed; +/* + * The nat_journal structure is a placeholder whose actual size varies depending + * on the use of packed_ssa. Therefore, it must always be accessed only through + * specific sets of macros and fields, and size calculations should use + * size-related macros instead of sizeof(). + * Relevant macros: sbi->nat_journal_entries, nat_in_journal(), + * nid_in_journal(), MAX_NAT_JENTRIES(). + */ struct nat_journal { - struct nat_journal_entry entries[NAT_JOURNAL_ENTRIES]; - __u8 reserved[NAT_JOURNAL_RESERVED]; + struct nat_journal_entry entries[0]; } __packed; struct sit_journal_entry { @@ -508,14 +496,21 @@ struct sit_journal_entry { struct f2fs_sit_entry se; } __packed; +/* + * The sit_journal structure is a placeholder whose actual size varies depending + * on the use of packed_ssa. Therefore, it must always be accessed only through + * specific sets of macros and fields, and size calculations should use + * size-related macros instead of sizeof(). + * Relevant macros: sbi->sit_journal_entries, sit_in_journal(), + * segno_in_journal(), MAX_SIT_JENTRIES(). + */ struct sit_journal { - struct sit_journal_entry entries[SIT_JOURNAL_ENTRIES]; - __u8 reserved[SIT_JOURNAL_RESERVED]; + struct sit_journal_entry entries[0]; } __packed; struct f2fs_extra_info { __le64 kbytes_written; - __u8 reserved[EXTRA_INFO_RESERVED]; + __u8 reserved[]; } __packed; struct f2fs_journal { @@ -531,11 +526,33 @@ struct f2fs_journal { }; } __packed; -/* Block-sized summary block structure */ +/* + * Block-sized summary block structure + * + * The f2fs_summary_block structure is a placeholder whose actual size varies + * depending on the use of packed_ssa. Therefore, it must always be accessed + * only through specific sets of macros and fields, and size calculations should + * use size-related macros instead of sizeof(). + * Relevant macros: sbi->sum_blocksize, sbi->entries_in_sum, + * sbi->sum_entry_size, sum_entries(), sum_journal(), sum_footer(). + * + * Summary Block Layout + * + * +-----------------------+ <--- Block Start + * | struct f2fs_summary | + * | entries[0] | + * | ... | + * | entries[N-1] | + * +-----------------------+ + * | struct f2fs_journal | + * +-----------------------+ + * | struct summary_footer | + * +-----------------------+ <--- Block End + */ struct f2fs_summary_block { - struct f2fs_summary entries[ENTRIES_IN_SUM]; - struct f2fs_journal journal; - struct summary_footer footer; + struct f2fs_summary entries[0]; + // struct f2fs_journal journal; + // struct summary_footer footer; } __packed; /* diff --git a/include/linux/fb.h b/include/linux/fb.h index 65fb70382675..6d4a58084fd5 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -18,6 +18,7 @@ struct backlight_device; struct device; struct device_node; struct fb_info; +struct fbcon_par; struct file; struct i2c_adapter; struct inode; @@ -493,7 +494,6 @@ struct fb_info { #if defined(CONFIG_FB_DEVICE) struct device *dev; /* This is this fb device */ #endif - int class_flag; /* private sysfs flags */ #ifdef CONFIG_FB_TILEBLITTING struct fb_tile_ops *tileops; /* Tile Blitting */ #endif @@ -506,7 +506,7 @@ struct fb_info { #define FBINFO_STATE_RUNNING 0 #define FBINFO_STATE_SUSPENDED 1 u32 state; /* Hardware state i.e suspend */ - void *fbcon_par; /* fbcon use-only private area */ + struct fbcon_par *fbcon_par; /* fbcon use-only private area */ /* From here on everything is device dependent */ void *par; @@ -624,6 +624,15 @@ static inline void unlock_fb_info(struct fb_info *info) mutex_unlock(&info->lock); } +static inline struct device *dev_of_fbinfo(const struct fb_info *info) +{ +#ifdef CONFIG_FB_DEVICE + return info->dev; +#else + return NULL; +#endif +} + static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch, u8 *src, u32 s_pitch, u32 height) { diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h index f89dcfad3f8f..3780904a63a6 100644 --- a/include/linux/fileattr.h +++ b/include/linux/fileattr.h @@ -7,16 +7,16 @@ #define FS_COMMON_FL \ (FS_SYNC_FL | FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NODUMP_FL | FS_NOATIME_FL | FS_DAX_FL | \ - FS_PROJINHERIT_FL) + FS_PROJINHERIT_FL | FS_VERITY_FL) #define FS_XFLAG_COMMON \ (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND | \ FS_XFLAG_NODUMP | FS_XFLAG_NOATIME | FS_XFLAG_DAX | \ - FS_XFLAG_PROJINHERIT) + FS_XFLAG_PROJINHERIT | FS_XFLAG_VERITY) /* Read-only inode flags */ #define FS_XFLAG_RDONLY_MASK \ - (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR) + (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY) /* Flags to indicate valid value of fsx_ fields */ #define FS_XFLAG_VALUES_MASK \ diff --git a/include/linux/firmware/intel/stratix10-svc-client.h b/include/linux/firmware/intel/stratix10-svc-client.h index d290060f4c73..91013161e9db 100644 --- a/include/linux/firmware/intel/stratix10-svc-client.h +++ b/include/linux/firmware/intel/stratix10-svc-client.h @@ -68,12 +68,12 @@ * timeout value used in Stratix10 FPGA manager driver. * timeout value used in RSU driver */ -#define SVC_RECONFIG_REQUEST_TIMEOUT_MS 300 -#define SVC_RECONFIG_BUFFER_TIMEOUT_MS 720 -#define SVC_RSU_REQUEST_TIMEOUT_MS 300 +#define SVC_RECONFIG_REQUEST_TIMEOUT_MS 5000 +#define SVC_RECONFIG_BUFFER_TIMEOUT_MS 5000 +#define SVC_RSU_REQUEST_TIMEOUT_MS 2000 #define SVC_FCS_REQUEST_TIMEOUT_MS 2000 #define SVC_COMPLETED_TIMEOUT_MS 30000 -#define SVC_HWMON_REQUEST_TIMEOUT_MS 300 +#define SVC_HWMON_REQUEST_TIMEOUT_MS 2000 struct stratix10_svc_chan; diff --git a/include/linux/fs.h b/include/linux/fs.h index 2e4d1e8b0e71..8b3dd145b25e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2872,12 +2872,22 @@ u64 vfsmount_to_propagation_flags(struct vfsmount *mnt); extern char *file_path(struct file *, char *, int); +static inline bool name_is_dot(const char *name, size_t len) +{ + return unlikely(len == 1 && name[0] == '.'); +} + +static inline bool name_is_dotdot(const char *name, size_t len) +{ + return unlikely(len == 2 && name[0] == '.' && name[1] == '.'); +} + /** - * is_dot_dotdot - returns true only if @name is "." or ".." + * name_is_dot_dotdot - returns true only if @name is "." or ".." * @name: file name to check * @len: length of file name, in bytes */ -static inline bool is_dot_dotdot(const char *name, size_t len) +static inline bool name_is_dot_dotdot(const char *name, size_t len) { return len && unlikely(name[0] == '.') && (len == 1 || (len == 2 && name[1] == '.')); @@ -3515,7 +3525,6 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, ssize_t simple_attr_write_signed(struct file *file, const char __user *buf, size_t len, loff_t *ppos); -struct ctl_table; int __init list_bdev_fs_names(char *buf, size_t size); #define __FMODE_EXEC ((__force int) FMODE_EXEC) diff --git a/include/linux/fsi.h b/include/linux/fsi.h index adea1b432f2d..9c67c43f9e6c 100644 --- a/include/linux/fsi.h +++ b/include/linux/fsi.h @@ -19,6 +19,16 @@ struct fsi_device { uint32_t size; }; +static inline void *fsi_get_drvdata(struct fsi_device *fsi_dev) +{ + return dev_get_drvdata(&fsi_dev->dev); +} + +static inline void fsi_set_drvdata(struct fsi_device *fsi_dev, void *data) +{ + dev_set_drvdata(&fsi_dev->dev, data); +} + extern int fsi_device_read(struct fsi_device *dev, uint32_t addr, void *val, size_t size); extern int fsi_device_write(struct fsi_device *dev, uint32_t addr, @@ -39,6 +49,8 @@ struct fsi_device_id { .engine_type = (t), .version = (v), struct fsi_driver { + int (*probe)(struct fsi_device *fsidev); + void (*remove)(struct fsi_device *fsidev); struct device_driver drv; const struct fsi_device_id *id_table; }; @@ -68,7 +80,6 @@ extern int fsi_slave_read(struct fsi_slave *slave, uint32_t addr, extern int fsi_slave_write(struct fsi_slave *slave, uint32_t addr, const void *val, size_t size); -extern const struct bus_type fsi_bus_type; extern const struct device_type fsi_cdev_type; enum fsi_dev_type { diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 28a9cb13fbfa..079c18bcdbde 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -495,19 +495,6 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid) fsnotify_dentry(dentry, mask); } -static inline int fsnotify_sb_error(struct super_block *sb, struct inode *inode, - int error) -{ - struct fs_error_report report = { - .error = error, - .inode = inode, - .sb = sb, - }; - - return fsnotify(FS_ERROR, &report, FSNOTIFY_EVENT_ERROR, - NULL, NULL, NULL, 0); -} - static inline void fsnotify_mnt_attach(struct mnt_namespace *ns, struct vfsmount *mnt) { fsnotify_mnt(FS_MNT_ATTACH, ns, mnt); diff --git a/include/linux/fsverity.h b/include/linux/fsverity.h index fed91023bea9..a8f9aa75b792 100644 --- a/include/linux/fsverity.h +++ b/include/linux/fsverity.h @@ -195,6 +195,8 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg); /* verify.c */ +void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, + unsigned long nr_pages); bool fsverity_verify_blocks(struct fsverity_info *vi, struct folio *folio, size_t len, size_t offset); void fsverity_verify_bio(struct fsverity_info *vi, struct bio *bio); @@ -255,6 +257,11 @@ static inline int fsverity_ioctl_read_metadata(struct file *filp, /* verify.c */ +static inline void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, + unsigned long nr_pages) +{ +} + static inline bool fsverity_verify_blocks(struct fsverity_info *vi, struct folio *folio, size_t len, size_t offset) @@ -282,12 +289,6 @@ static inline bool fsverity_verify_folio(struct fsverity_info *vi, return fsverity_verify_blocks(vi, folio, folio_size(folio), 0); } -static inline bool fsverity_verify_page(struct fsverity_info *vi, - struct page *page) -{ - return fsverity_verify_blocks(vi, page_folio(page), PAGE_SIZE, 0); -} - /** * fsverity_file_open() - prepare to open a verity file * @inode: the inode being opened @@ -309,8 +310,6 @@ static inline int fsverity_file_open(struct inode *inode, struct file *filp) } void fsverity_cleanup_inode(struct inode *inode); -void fsverity_readahead(struct fsverity_info *vi, pgoff_t index, - unsigned long nr_pages); struct page *generic_read_merkle_tree_page(struct inode *inode, pgoff_t index); void generic_readahead_merkle_tree(struct inode *inode, pgoff_t index, diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 1a4d36fc9085..c242fe49af4c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1092,10 +1092,17 @@ static inline bool is_ftrace_trampoline(unsigned long addr) #ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifndef ftrace_graph_func -#define ftrace_graph_func ftrace_stub -#define FTRACE_OPS_GRAPH_STUB FTRACE_OPS_FL_STUB +# define ftrace_graph_func ftrace_stub +# define FTRACE_OPS_GRAPH_STUB FTRACE_OPS_FL_STUB +/* + * The function graph is called every time the function tracer is called. + * It must always test the ops hash and cannot just directly call + * the handler. + */ +# define FGRAPH_NO_DIRECT 1 #else -#define FTRACE_OPS_GRAPH_STUB 0 +# define FTRACE_OPS_GRAPH_STUB 0 +# define FGRAPH_NO_DIRECT 0 #endif #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 86d62fdafd7a..9625347c7ac0 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -97,7 +97,7 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) static inline struct gameport *gameport_allocate_port(void) { - struct gameport *gameport = kzalloc(sizeof(struct gameport), GFP_KERNEL); + struct gameport *gameport = kzalloc_obj(struct gameport); return gameport; } diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 6ecf6dda93e0..51ef13ed756e 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -13,6 +13,10 @@ struct vm_area_struct; struct mempolicy; +/* Helper macro to avoid gfp flags if they are the default one */ +#define __default_gfp(a,b,...) b +#define default_gfp(...) __default_gfp(,##__VA_ARGS__,GFP_KERNEL) + /* Convert GFP flags to their corresponding migrate type */ #define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE) #define GFP_MOVABLE_SHIFT 3 @@ -335,8 +339,11 @@ static inline struct folio *folio_alloc_mpol_noprof(gfp_t gfp, unsigned int orde { return folio_alloc_noprof(gfp, order); } -#define vma_alloc_folio_noprof(gfp, order, vma, addr) \ - folio_alloc_noprof(gfp, order) +static inline struct folio *vma_alloc_folio_noprof(gfp_t gfp, int order, + struct vm_area_struct *vma, unsigned long addr) +{ + return folio_alloc_noprof(gfp, order); +} #endif #define alloc_pages(...) alloc_hooks(alloc_pages_noprof(__VA_ARGS__)) diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h index 814bb2892f99..6c75df30a281 100644 --- a/include/linux/gfp_types.h +++ b/include/linux/gfp_types.h @@ -139,6 +139,8 @@ enum { * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg. * * %__GFP_NO_OBJ_EXT causes slab allocation to have no object extension. + * mark_obj_codetag_empty() should be called upon freeing for objects allocated + * with this flag to indicate that their NULL tags are expected and normal. */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) diff --git a/include/linux/hid.h b/include/linux/hid.h index 31324609af4d..fb1a3f3ad9fa 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -634,6 +634,38 @@ enum hid_battery_status { HID_BATTERY_REPORTED, /* Device sent unsolicited battery strength report */ }; +/** + * struct hid_battery - represents a single battery power supply + * @dev: pointer to the parent hid_device + * @ps: the power supply instance + * @min: minimum battery value from HID descriptor + * @max: maximum battery value from HID descriptor + * @report_type: HID report type (input/feature) + * @report_id: HID report ID for this battery + * @charge_status: current charging status + * @status: battery reporting status + * @capacity: current battery capacity (0-100) + * @avoid_query: if true, avoid querying battery (e.g., for stylus) + * @present: if true, battery is present (may be dynamic) + * @ratelimit_time: rate limiting for battery reports + * @list: list node for linking into hid_device's battery list + */ +struct hid_battery { + struct hid_device *dev; + struct power_supply *ps; + __s32 min; + __s32 max; + __s32 report_type; + __s32 report_id; + __s32 charge_status; + enum hid_battery_status status; + __s32 capacity; + bool avoid_query; + bool present; + ktime_t ratelimit_time; + struct list_head list; +}; + struct hid_driver; struct hid_ll_driver; @@ -670,20 +702,10 @@ struct hid_device { #ifdef CONFIG_HID_BATTERY_STRENGTH /* * Power supply information for HID devices which report - * battery strength. power_supply was successfully registered if - * battery is non-NULL. + * battery strength. Each battery is tracked separately in the + * batteries list. */ - struct power_supply *battery; - __s32 battery_capacity; - __s32 battery_min; - __s32 battery_max; - __s32 battery_report_type; - __s32 battery_report_id; - __s32 battery_charge_status; - enum hid_battery_status battery_status; - bool battery_avoid_query; - bool battery_present; - ktime_t battery_ratelimit_time; + struct list_head batteries; #endif unsigned long status; /* see STAT flags above */ @@ -744,6 +766,15 @@ static inline void hid_set_drvdata(struct hid_device *hdev, void *data) dev_set_drvdata(&hdev->dev, data); } +#ifdef CONFIG_HID_BATTERY_STRENGTH +static inline struct hid_battery *hid_get_battery(struct hid_device *hdev) +{ + if (list_empty(&hdev->batteries)) + return NULL; + return list_first_entry(&hdev->batteries, struct hid_battery, list); +} +#endif + #define HID_GLOBAL_STACK_SIZE 4 #define HID_COLLECTION_STACK_SIZE 4 diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 94a03591990c..65910437be1c 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -16,8 +16,6 @@ #include #include -struct ctl_table; -struct user_struct; struct mmu_gather; struct node; @@ -150,7 +148,7 @@ int hugetlb_mfill_atomic_pte(pte_t *dst_pte, struct folio **foliop); #endif /* CONFIG_USERFAULTFD */ long hugetlb_reserve_pages(struct inode *inode, long from, long to, - struct vm_area_desc *desc, vm_flags_t vm_flags); + struct vm_area_desc *desc, vma_flags_t vma_flags); long hugetlb_unreserve_pages(struct inode *inode, long start, long end, long freed); bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list); @@ -529,7 +527,7 @@ static inline struct hugetlbfs_inode_info *HUGETLBFS_I(struct inode *inode) } extern const struct vm_operations_struct hugetlb_vm_ops; -struct file *hugetlb_file_setup(const char *name, size_t size, vm_flags_t acct, +struct file *hugetlb_file_setup(const char *name, size_t size, vma_flags_t acct, int creat_flags, int page_size_log); static inline bool is_file_hugepages(const struct file *file) @@ -545,7 +543,7 @@ static inline struct hstate *hstate_inode(struct inode *i) #define is_file_hugepages(file) false static inline struct file * -hugetlb_file_setup(const char *name, size_t size, vm_flags_t acctflag, +hugetlb_file_setup(const char *name, size_t size, vma_flags_t acctflag, int creat_flags, int page_size_log) { return ERR_PTR(-ENOSYS); diff --git a/include/linux/hugetlb_inline.h b/include/linux/hugetlb_inline.h index a27aa0162918..593f5d4e108b 100644 --- a/include/linux/hugetlb_inline.h +++ b/include/linux/hugetlb_inline.h @@ -11,6 +11,11 @@ static inline bool is_vm_hugetlb_flags(vm_flags_t vm_flags) return !!(vm_flags & VM_HUGETLB); } +static inline bool is_vma_hugetlb_flags(const vma_flags_t *flags) +{ + return vma_flags_test(flags, VMA_HUGETLB_BIT); +} + #else static inline bool is_vm_hugetlb_flags(vm_flags_t vm_flags) @@ -18,6 +23,11 @@ static inline bool is_vm_hugetlb_flags(vm_flags_t vm_flags) return false; } +static inline bool is_vma_hugetlb_flags(const vma_flags_t *flags) +{ + return false; +} + #endif static inline bool is_vm_hugetlb_page(struct vm_area_struct *vma) diff --git a/include/linux/iio/buffer-dma.h b/include/linux/iio/buffer-dma.h index 4f33e6a39797..ef8687a88b73 100644 --- a/include/linux/iio/buffer-dma.h +++ b/include/linux/iio/buffer-dma.h @@ -119,7 +119,12 @@ struct iio_dma_buffer_queue { struct device *dev; const struct iio_dma_buffer_ops *ops; + /* + * A mutex to protect accessing, configuring (eg: enqueuing DMA blocks) + * and do file IO on struct iio_dma_buffer_queue objects. + */ struct mutex lock; + /* A spin lock to protect adding/removing blocks to the queue list */ spinlock_t list_lock; struct list_head incoming; @@ -136,20 +141,19 @@ struct iio_dma_buffer_queue { */ struct iio_dma_buffer_ops { int (*submit)(struct iio_dma_buffer_queue *queue, - struct iio_dma_buffer_block *block); + struct iio_dma_buffer_block *block); void (*abort)(struct iio_dma_buffer_queue *queue); }; void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block); void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue, - struct list_head *list); + struct list_head *list); -int iio_dma_buffer_enable(struct iio_buffer *buffer, - struct iio_dev *indio_dev); +int iio_dma_buffer_enable(struct iio_buffer *buffer, struct iio_dev *indio_dev); int iio_dma_buffer_disable(struct iio_buffer *buffer, - struct iio_dev *indio_dev); + struct iio_dev *indio_dev); int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n, - char __user *user_buffer); + char __user *user_buffer); int iio_dma_buffer_write(struct iio_buffer *buffer, size_t n, const char __user *user_buffer); size_t iio_dma_buffer_usage(struct iio_buffer *buffer); @@ -157,8 +161,8 @@ int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd); int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length); int iio_dma_buffer_request_update(struct iio_buffer *buffer); -int iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, - struct device *dma_dev, const struct iio_dma_buffer_ops *ops); +void iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, struct device *dev, + const struct iio_dma_buffer_ops *ops); void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue); void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue); diff --git a/include/linux/iio/buffer_impl.h b/include/linux/iio/buffer_impl.h index c0b0e0992a85..9442c165561a 100644 --- a/include/linux/iio/buffer_impl.h +++ b/include/linux/iio/buffer_impl.h @@ -113,10 +113,10 @@ struct iio_buffer { /** @flags: File ops flags including busy flag. */ unsigned long flags; - /** @bytes_per_datum: Size of individual datum including timestamp. */ + /** @bytes_per_datum: Size of individual datum including timestamp. */ size_t bytes_per_datum; - /* @direction: Direction of the data stream (in/out). */ + /** @direction: Direction of the data stream (in/out). */ enum iio_buffer_direction direction; /** @@ -178,7 +178,9 @@ struct iio_buffer { * @insert_buffer: buffer to insert * @remove_buffer: buffer_to_remove * - * Note this will tear down the all buffering and build it up again + * Note this will tear down all the buffering and build it up again + * + * Returns: 0 on success or -errno on error */ int iio_update_buffers(struct iio_dev *indio_dev, struct iio_buffer *insert_buffer, diff --git a/include/linux/iio/frequency/ad9523.h b/include/linux/iio/frequency/ad9523.h index ff22a0ac15f5..236437a226b2 100644 --- a/include/linux/iio/frequency/ad9523.h +++ b/include/linux/iio/frequency/ad9523.h @@ -45,7 +45,7 @@ enum ref_sel_mode { * @output_dis: Disables, powers down the entire channel. * @driver_mode: Output driver mode (logic level family). * @divider_phase: Divider initial phase after a SYNC. Range 0..63 - LSB = 1/2 of a period of the divider input clock. + * LSB = 1/2 of a period of the divider input clock. * @channel_divider: 10-bit channel divider. * @extended_name: Optional descriptive channel name. */ diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 872ebdf0dd77..a9ecff191bd9 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -661,34 +662,148 @@ void iio_device_unregister(struct iio_dev *indio_dev); int __devm_iio_device_register(struct device *dev, struct iio_dev *indio_dev, struct module *this_mod); int iio_push_event(struct iio_dev *indio_dev, u64 ev_code, s64 timestamp); -bool __iio_device_claim_direct(struct iio_dev *indio_dev); -void __iio_device_release_direct(struct iio_dev *indio_dev); + +void __iio_dev_mode_lock(struct iio_dev *indio_dev) __acquires(indio_dev); +void __iio_dev_mode_unlock(struct iio_dev *indio_dev) __releases(indio_dev); /* * Helper functions that allow claim and release of direct mode * in a fashion that doesn't generate many false positives from sparse. * Note this must remain static inline in the header so that sparse - * can see the __acquire() marking. Revisit when sparse supports - * __cond_acquires() + * can see the __acquires() and __releases() annotations. + */ + +/** + * iio_device_claim_direct() - Keep device in direct mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in direct mode it is guaranteed to stay + * that way until iio_device_release_direct() is called. + * + * Use with iio_device_release_direct(). + * + * Returns: true on success, false on failure. */ static inline bool iio_device_claim_direct(struct iio_dev *indio_dev) { - if (!__iio_device_claim_direct(indio_dev)) - return false; + __iio_dev_mode_lock(indio_dev); - __acquire(iio_dev); + if (iio_buffer_enabled(indio_dev)) { + __iio_dev_mode_unlock(indio_dev); + return false; + } return true; } -static inline void iio_device_release_direct(struct iio_dev *indio_dev) +/** + * iio_device_release_direct() - Releases claim on direct mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in direct mode. + * + * Use with iio_device_claim_direct(). + */ +#define iio_device_release_direct(indio_dev) __iio_dev_mode_unlock(indio_dev) + +/** + * iio_device_try_claim_buffer_mode() - Keep device in buffer mode + * @indio_dev: the iio_dev associated with the device + * + * If the device is in buffer mode it is guaranteed to stay + * that way until iio_device_release_buffer_mode() is called. + * + * Use with iio_device_release_buffer_mode(). + * + * Returns: true on success, false on failure. + */ +static inline bool iio_device_try_claim_buffer_mode(struct iio_dev *indio_dev) { - __iio_device_release_direct(indio_dev); - __release(indio_dev); + __iio_dev_mode_lock(indio_dev); + + if (!iio_buffer_enabled(indio_dev)) { + __iio_dev_mode_unlock(indio_dev); + return false; + } + + return true; } -int iio_device_claim_buffer_mode(struct iio_dev *indio_dev); -void iio_device_release_buffer_mode(struct iio_dev *indio_dev); +/** + * iio_device_release_buffer_mode() - releases claim on buffer mode + * @indio_dev: the iio_dev associated with the device + * + * Release the claim. Device is no longer guaranteed to stay + * in buffer mode. + * + * Use with iio_device_try_claim_buffer_mode(). + */ +#define iio_device_release_buffer_mode(indio_dev) __iio_dev_mode_unlock(indio_dev) + +/* + * These classes are not meant to be used directly by drivers (hence the + * __priv__ prefix). Instead, documented wrapper macros are provided below to + * enforce the use of ACQUIRE() or guard() semantics and avoid the problematic + * scoped guard variants. + */ +DEFINE_GUARD(__priv__iio_dev_mode_lock, struct iio_dev *, + __iio_dev_mode_lock(_T), __iio_dev_mode_unlock(_T)); +DEFINE_GUARD_COND(__priv__iio_dev_mode_lock, _try_direct, + iio_device_claim_direct(_T)); + +/** + * IIO_DEV_ACQUIRE_DIRECT_MODE() - Tries to acquire the direct mode lock with + * automatic release + * @dev: IIO device instance + * @claim: Variable identifier to store acquire result + * + * Tries to acquire the direct mode lock with cleanup ACQUIRE() semantics and + * automatically releases it at the end of the scope. It most be always paired + * with IIO_DEV_ACQUIRE_ERR(), for example (notice the scope braces):: + * + * switch() { + * case IIO_CHAN_INFO_RAW: { + * IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim); + * if (IIO_DEV_ACQUIRE_FAILED(claim)) + * return -EBUSY; + * + * ... + * } + * case IIO_CHAN_INFO_SCALE: + * ... + * ... + * } + * + * Context: Can sleep + */ +#define IIO_DEV_ACQUIRE_DIRECT_MODE(dev, claim) \ + ACQUIRE(__priv__iio_dev_mode_lock_try_direct, claim)(dev) + +/** + * IIO_DEV_ACQUIRE_FAILED() - ACQUIRE_ERR() wrapper + * @claim: The claim variable passed to IIO_DEV_ACQUIRE_*_MODE() + * + * Return: true if failed to acquire the mode, otherwise false. + */ +#define IIO_DEV_ACQUIRE_FAILED(claim) \ + ACQUIRE_ERR(__priv__iio_dev_mode_lock_try_direct, &(claim)) + +/** + * IIO_DEV_GUARD_CURRENT_MODE() - Acquires the mode lock with automatic release + * @dev: IIO device instance + * + * Acquires the mode lock with cleanup guard() semantics. It is usually paired + * with iio_buffer_enabled(). + * + * This should *not* be used to protect internal driver state and it's use in + * general is *strongly* discouraged. Use any of the IIO_DEV_ACQUIRE_*_MODE() + * variants. + * + * Context: Can sleep + */ +#define IIO_DEV_GUARD_CURRENT_MODE(dev) \ + guard(__priv__iio_dev_mode_lock)(dev) extern const struct bus_type iio_bus_type; diff --git a/include/linux/indirect_call_wrapper.h b/include/linux/indirect_call_wrapper.h index 35227d47cfc9..dc272b514a01 100644 --- a/include/linux/indirect_call_wrapper.h +++ b/include/linux/indirect_call_wrapper.h @@ -16,22 +16,26 @@ */ #define INDIRECT_CALL_1(f, f1, ...) \ ({ \ - likely(f == f1) ? f1(__VA_ARGS__) : f(__VA_ARGS__); \ + typeof(f) __f1 = (f); \ + likely(__f1 == f1) ? f1(__VA_ARGS__) : __f1(__VA_ARGS__); \ }) #define INDIRECT_CALL_2(f, f2, f1, ...) \ ({ \ - likely(f == f2) ? f2(__VA_ARGS__) : \ - INDIRECT_CALL_1(f, f1, __VA_ARGS__); \ + typeof(f) __f2 = (f); \ + likely(__f2 == f2) ? f2(__VA_ARGS__) : \ + INDIRECT_CALL_1(__f2, f1, __VA_ARGS__); \ }) #define INDIRECT_CALL_3(f, f3, f2, f1, ...) \ ({ \ - likely(f == f3) ? f3(__VA_ARGS__) : \ - INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__); \ + typeof(f) __f3 = (f); \ + likely(__f3 == f3) ? f3(__VA_ARGS__) : \ + INDIRECT_CALL_2(__f3, f2, f1, __VA_ARGS__); \ }) #define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...) \ ({ \ - likely(f == f4) ? f4(__VA_ARGS__) : \ - INDIRECT_CALL_3(f, f3, f2, f1, __VA_ARGS__); \ + typeof(f) __f4 = (f); \ + likely(__f4 == f4) ? f4(__VA_ARGS__) : \ + INDIRECT_CALL_3(__f4, f3, f2, f1, __VA_ARGS__); \ }) #define INDIRECT_CALLABLE_DECLARE(f) f diff --git a/include/linux/input/adp5589.h b/include/linux/input/adp5589.h deleted file mode 100644 index 0e4742c8c81e..000000000000 --- a/include/linux/input/adp5589.h +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Analog Devices ADP5589/ADP5585 I/O Expander and QWERTY Keypad Controller - * - * Copyright 2010-2011 Analog Devices Inc. - */ - -#ifndef _ADP5589_H -#define _ADP5589_H - -/* - * ADP5589 specific GPI and Keymap defines - */ - -#define ADP5589_KEYMAPSIZE 88 - -#define ADP5589_GPI_PIN_ROW0 97 -#define ADP5589_GPI_PIN_ROW1 98 -#define ADP5589_GPI_PIN_ROW2 99 -#define ADP5589_GPI_PIN_ROW3 100 -#define ADP5589_GPI_PIN_ROW4 101 -#define ADP5589_GPI_PIN_ROW5 102 -#define ADP5589_GPI_PIN_ROW6 103 -#define ADP5589_GPI_PIN_ROW7 104 -#define ADP5589_GPI_PIN_COL0 105 -#define ADP5589_GPI_PIN_COL1 106 -#define ADP5589_GPI_PIN_COL2 107 -#define ADP5589_GPI_PIN_COL3 108 -#define ADP5589_GPI_PIN_COL4 109 -#define ADP5589_GPI_PIN_COL5 110 -#define ADP5589_GPI_PIN_COL6 111 -#define ADP5589_GPI_PIN_COL7 112 -#define ADP5589_GPI_PIN_COL8 113 -#define ADP5589_GPI_PIN_COL9 114 -#define ADP5589_GPI_PIN_COL10 115 -#define GPI_LOGIC1 116 -#define GPI_LOGIC2 117 - -#define ADP5589_GPI_PIN_ROW_BASE ADP5589_GPI_PIN_ROW0 -#define ADP5589_GPI_PIN_ROW_END ADP5589_GPI_PIN_ROW7 -#define ADP5589_GPI_PIN_COL_BASE ADP5589_GPI_PIN_COL0 -#define ADP5589_GPI_PIN_COL_END ADP5589_GPI_PIN_COL10 - -#define ADP5589_GPI_PIN_BASE ADP5589_GPI_PIN_ROW_BASE -#define ADP5589_GPI_PIN_END ADP5589_GPI_PIN_COL_END - -#define ADP5589_GPIMAPSIZE_MAX (ADP5589_GPI_PIN_END - ADP5589_GPI_PIN_BASE + 1) - -/* - * ADP5585 specific GPI and Keymap defines - */ - -#define ADP5585_KEYMAPSIZE 30 - -#define ADP5585_GPI_PIN_ROW0 37 -#define ADP5585_GPI_PIN_ROW1 38 -#define ADP5585_GPI_PIN_ROW2 39 -#define ADP5585_GPI_PIN_ROW3 40 -#define ADP5585_GPI_PIN_ROW4 41 -#define ADP5585_GPI_PIN_ROW5 42 -#define ADP5585_GPI_PIN_COL0 43 -#define ADP5585_GPI_PIN_COL1 44 -#define ADP5585_GPI_PIN_COL2 45 -#define ADP5585_GPI_PIN_COL3 46 -#define ADP5585_GPI_PIN_COL4 47 -#define GPI_LOGIC 48 - -#define ADP5585_GPI_PIN_ROW_BASE ADP5585_GPI_PIN_ROW0 -#define ADP5585_GPI_PIN_ROW_END ADP5585_GPI_PIN_ROW5 -#define ADP5585_GPI_PIN_COL_BASE ADP5585_GPI_PIN_COL0 -#define ADP5585_GPI_PIN_COL_END ADP5585_GPI_PIN_COL4 - -#define ADP5585_GPI_PIN_BASE ADP5585_GPI_PIN_ROW_BASE -#define ADP5585_GPI_PIN_END ADP5585_GPI_PIN_COL_END - -#define ADP5585_GPIMAPSIZE_MAX (ADP5585_GPI_PIN_END - ADP5585_GPI_PIN_BASE + 1) - -struct adp5589_gpi_map { - unsigned short pin; - unsigned short sw_evt; -}; - -/* scan_cycle_time */ -#define ADP5589_SCAN_CYCLE_10ms 0 -#define ADP5589_SCAN_CYCLE_20ms 1 -#define ADP5589_SCAN_CYCLE_30ms 2 -#define ADP5589_SCAN_CYCLE_40ms 3 - -/* RESET_CFG */ -#define RESET_PULSE_WIDTH_500us 0 -#define RESET_PULSE_WIDTH_1ms 1 -#define RESET_PULSE_WIDTH_2ms 2 -#define RESET_PULSE_WIDTH_10ms 3 - -#define RESET_TRIG_TIME_0ms (0 << 2) -#define RESET_TRIG_TIME_1000ms (1 << 2) -#define RESET_TRIG_TIME_1500ms (2 << 2) -#define RESET_TRIG_TIME_2000ms (3 << 2) -#define RESET_TRIG_TIME_2500ms (4 << 2) -#define RESET_TRIG_TIME_3000ms (5 << 2) -#define RESET_TRIG_TIME_3500ms (6 << 2) -#define RESET_TRIG_TIME_4000ms (7 << 2) - -#define RESET_PASSTHRU_EN (1 << 5) -#define RESET1_POL_HIGH (1 << 6) -#define RESET1_POL_LOW (0 << 6) -#define RESET2_POL_HIGH (1 << 7) -#define RESET2_POL_LOW (0 << 7) - -/* ADP5589 Mask Bits: - * C C C C C C C C C C C | R R R R R R R R - * 1 9 8 7 6 5 4 3 2 1 0 | 7 6 5 4 3 2 1 0 - * 0 - * ---------------- BIT ------------------ - * 1 1 1 1 1 1 1 1 1 0 0 | 0 0 0 0 0 0 0 0 - * 8 7 6 5 4 3 2 1 0 9 8 | 7 6 5 4 3 2 1 0 - */ - -#define ADP_ROW(x) (1 << (x)) -#define ADP_COL(x) (1 << (x + 8)) -#define ADP5589_ROW_MASK 0xFF -#define ADP5589_COL_MASK 0xFF -#define ADP5589_COL_SHIFT 8 -#define ADP5589_MAX_ROW_NUM 7 -#define ADP5589_MAX_COL_NUM 10 - -/* ADP5585 Mask Bits: - * C C C C C | R R R R R R - * 4 3 2 1 0 | 5 4 3 2 1 0 - * - * ---- BIT -- ----------- - * 1 0 0 0 0 | 0 0 0 0 0 0 - * 0 9 8 7 6 | 5 4 3 2 1 0 - */ - -#define ADP5585_ROW_MASK 0x3F -#define ADP5585_COL_MASK 0x1F -#define ADP5585_ROW_SHIFT 0 -#define ADP5585_COL_SHIFT 6 -#define ADP5585_MAX_ROW_NUM 5 -#define ADP5585_MAX_COL_NUM 4 - -#define ADP5585_ROW(x) (1 << ((x) & ADP5585_ROW_MASK)) -#define ADP5585_COL(x) (1 << (((x) & ADP5585_COL_MASK) + ADP5585_COL_SHIFT)) - -/* Put one of these structures in i2c_board_info platform_data */ - -struct adp5589_kpad_platform_data { - unsigned keypad_en_mask; /* Keypad (Rows/Columns) enable mask */ - const unsigned short *keymap; /* Pointer to keymap */ - unsigned short keymapsize; /* Keymap size */ - bool repeat; /* Enable key repeat */ - bool en_keylock; /* Enable key lock feature (ADP5589 only)*/ - unsigned char unlock_key1; /* Unlock Key 1 (ADP5589 only) */ - unsigned char unlock_key2; /* Unlock Key 2 (ADP5589 only) */ - unsigned char unlock_timer; /* Time in seconds [0..7] between the two unlock keys 0=disable (ADP5589 only) */ - unsigned char scan_cycle_time; /* Time between consecutive scan cycles */ - unsigned char reset_cfg; /* Reset config */ - unsigned short reset1_key_1; /* Reset Key 1 */ - unsigned short reset1_key_2; /* Reset Key 2 */ - unsigned short reset1_key_3; /* Reset Key 3 */ - unsigned short reset2_key_1; /* Reset Key 1 */ - unsigned short reset2_key_2; /* Reset Key 2 */ - unsigned debounce_dis_mask; /* Disable debounce mask */ - unsigned pull_dis_mask; /* Disable all pull resistors mask */ - unsigned pullup_en_100k; /* Pull-Up 100k Enable Mask */ - unsigned pullup_en_300k; /* Pull-Up 300k Enable Mask */ - unsigned pulldown_en_300k; /* Pull-Down 300k Enable Mask */ - const struct adp5589_gpi_map *gpimap; - unsigned short gpimapsize; - const struct adp5589_gpio_platform_data *gpio_data; -}; - -struct i2c_client; /* forward declaration */ - -struct adp5589_gpio_platform_data { - int gpio_start; /* GPIO Chip base # */ -}; - -#endif diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h index f479ef5b3341..fa1f328d6712 100644 --- a/include/linux/intel_rapl.h +++ b/include/linux/intel_rapl.h @@ -152,7 +152,7 @@ struct rapl_if_priv { union rapl_reg reg_unit; union rapl_reg regs[RAPL_DOMAIN_MAX][RAPL_DOMAIN_REG_MAX]; int limits[RAPL_DOMAIN_MAX]; - int (*read_raw)(int id, struct reg_action *ra, bool atomic); + int (*read_raw)(int id, struct reg_action *ra, bool pmu_ctx); int (*write_raw)(int id, struct reg_action *ra); void *defaults; void *rpi; diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index c16353cc6e3c..e5a884e72f29 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -206,7 +206,7 @@ io_mapping_create_wc(resource_size_t base, { struct io_mapping *iomap; - iomap = kmalloc(sizeof(*iomap), GFP_KERNEL); + iomap = kmalloc_obj(*iomap); if (!iomap) return NULL; diff --git a/include/linux/io_uring/cmd.h b/include/linux/io_uring/cmd.h index 375fd048c4cb..331dcbefe72f 100644 --- a/include/linux/io_uring/cmd.h +++ b/include/linux/io_uring/cmd.h @@ -20,10 +20,17 @@ struct io_uring_cmd { u8 unused[8]; }; -static inline const void *io_uring_sqe_cmd(const struct io_uring_sqe *sqe) -{ - return sqe->cmd; -} +#define io_uring_sqe128_cmd(sqe, type) ({ \ + BUILD_BUG_ON(sizeof(type) > ((2 * sizeof(struct io_uring_sqe)) - \ + offsetof(struct io_uring_sqe, cmd))); \ + (const type *)(sqe)->cmd; \ +}) + +#define io_uring_sqe_cmd(sqe, type) ({ \ + BUILD_BUG_ON(sizeof(type) > (sizeof(struct io_uring_sqe) - \ + offsetof(struct io_uring_sqe, cmd))); \ + (const type *)(sqe)->cmd; \ +}) static inline void io_uring_cmd_private_sz_check(size_t cmd_sz) { diff --git a/include/linux/io_uring_types.h b/include/linux/io_uring_types.h index 3e4a82a6f817..dd1420bfcb73 100644 --- a/include/linux/io_uring_types.h +++ b/include/linux/io_uring_types.h @@ -388,6 +388,7 @@ struct io_ring_ctx { * regularly bounce b/w CPUs. */ struct { + struct io_rings __rcu *rings_rcu; struct llist_head work_llist; struct llist_head retry_llist; unsigned long check_cq; diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 443053a76dcf..a7421382a916 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -333,7 +333,12 @@ struct tcp6_timewait_sock { }; #if IS_ENABLED(CONFIG_IPV6) -bool ipv6_mod_enabled(void); +extern int disable_ipv6_mod; + +static inline bool ipv6_mod_enabled(void) +{ + return disable_ipv6_mod == 0; +} static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk) { diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 70c0948f978e..0225121f3013 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -394,6 +394,7 @@ #define GITS_TYPER_VLPIS (1UL << 1) #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 #define GITS_TYPER_ITT_ENTRY_SIZE GENMASK_ULL(7, 4) +#define GITS_TYPER_IDBITS GENMASK_ULL(12, 8) #define GITS_TYPER_IDBITS_SHIFT 8 #define GITS_TYPER_DEVBITS_SHIFT 13 #define GITS_TYPER_DEVBITS GENMASK_ULL(17, 13) diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index fdef2c155c27..d1c3d4941854 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -434,8 +434,44 @@ extern unsigned long preset_lpj; /* * Convert various time units to each other: */ -extern unsigned int jiffies_to_msecs(const unsigned long j); -extern unsigned int jiffies_to_usecs(const unsigned long j); + +#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) +/** + * jiffies_to_msecs - Convert jiffies to milliseconds + * @j: jiffies value + * + * This inline version takes care of HZ in {100,250,1000}. + * + * Return: milliseconds value + */ +static inline unsigned int jiffies_to_msecs(const unsigned long j) +{ + return (MSEC_PER_SEC / HZ) * j; +} +#else +unsigned int jiffies_to_msecs(const unsigned long j); +#endif + +#if !(USEC_PER_SEC % HZ) +/** + * jiffies_to_usecs - Convert jiffies to microseconds + * @j: jiffies value + * + * Return: microseconds value + */ +static inline unsigned int jiffies_to_usecs(const unsigned long j) +{ + /* + * Hz usually doesn't go much further MSEC_PER_SEC. + * jiffies_to_usecs() and usecs_to_jiffies() depend on that. + */ + BUILD_BUG_ON(HZ > USEC_PER_SEC); + + return (USEC_PER_SEC / HZ) * j; +} +#else +unsigned int jiffies_to_usecs(const unsigned long j); +#endif /** * jiffies_to_nsecs - Convert jiffies to nanoseconds diff --git a/include/linux/kdb.h b/include/linux/kdb.h index 741c58e86431..26fe4ab81b42 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -1,13 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _KDB_H #define _KDB_H /* * Kernel Debugger Architecture Independent Global Headers * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (c) 2000-2007 Silicon Graphics, Inc. All Rights Reserved. * Copyright (C) 2000 Stephane Eranian * Copyright (C) 2009 Jason Wessel diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 5eebbe7a3545..22b3f3839f30 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * This provides the callbacks and functions that KGDB needs to share between * the core, I/O and arch-specific portions. @@ -6,9 +7,6 @@ * Tom Rini * * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc. - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. */ #ifndef _KGDB_H_ #define _KGDB_H_ diff --git a/include/linux/kthread.h b/include/linux/kthread.h index c92c1149ee6e..a01a474719a7 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -7,6 +7,24 @@ struct mm_struct; +/* opaque kthread data */ +struct kthread; + +/* + * When "(p->flags & PF_KTHREAD)" is set the task is a kthread and will + * always remain a kthread. For kthreads p->worker_private always + * points to a struct kthread. For tasks that are not kthreads + * p->worker_private is used to point to other things. + * + * Return NULL for any task that is not a kthread. + */ +static inline struct kthread *tsk_is_kthread(struct task_struct *p) +{ + if (p->flags & PF_KTHREAD) + return p->worker_private; + return NULL; +} + __printf(4, 5) struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), void *data, @@ -98,9 +116,10 @@ void *kthread_probe_data(struct task_struct *k); int kthread_park(struct task_struct *k); void kthread_unpark(struct task_struct *k); void kthread_parkme(void); -void kthread_exit(long result) __noreturn; +#define kthread_exit(result) do_exit(result) void kthread_complete_and_exit(struct completion *, long) __noreturn; int kthreads_update_housekeeping(void); +void kthread_do_exit(struct kthread *, long); int kthreadd(void *unused); extern struct task_struct *kthreadd_task; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index d42a95cbcfbc..6b76e7a6f4c2 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -253,7 +253,6 @@ bool kvm_setup_async_pf(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, int kvm_async_pf_wakeup_all(struct kvm_vcpu *vcpu); #endif -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER union kvm_mmu_notifier_arg { unsigned long attributes; }; @@ -275,7 +274,6 @@ struct kvm_gfn_range { bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range); bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range); bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range); -#endif enum { OUTSIDE_GUEST_MODE, @@ -849,13 +847,12 @@ struct kvm { struct hlist_head irq_ack_notifier_list; #endif -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER struct mmu_notifier mmu_notifier; unsigned long mmu_invalidate_seq; long mmu_invalidate_in_progress; gfn_t mmu_invalidate_range_start; gfn_t mmu_invalidate_range_end; -#endif + struct list_head devices; u64 manual_dirty_log_protect; struct dentry *debugfs_dentry; @@ -1664,7 +1661,7 @@ void kvm_arch_create_vm_debugfs(struct kvm *kvm); */ static inline struct kvm *kvm_arch_alloc_vm(void) { - return kzalloc(sizeof(struct kvm), GFP_KERNEL_ACCOUNT); + return kzalloc_obj(struct kvm, GFP_KERNEL_ACCOUNT); } #endif @@ -1943,56 +1940,43 @@ enum kvm_stat_kind { struct kvm_stat_data { struct kvm *kvm; - const struct _kvm_stats_desc *desc; + const struct kvm_stats_desc *desc; enum kvm_stat_kind kind; }; -struct _kvm_stats_desc { - struct kvm_stats_desc desc; - char name[KVM_STATS_NAME_SIZE]; -}; - -#define STATS_DESC_COMMON(type, unit, base, exp, sz, bsz) \ - .flags = type | unit | base | \ - BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) | \ - BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) | \ - BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK), \ - .exponent = exp, \ - .size = sz, \ +#define STATS_DESC_COMMON(type, unit, base, exp, sz, bsz) \ + .flags = type | unit | base | \ + BUILD_BUG_ON_ZERO(type & ~KVM_STATS_TYPE_MASK) | \ + BUILD_BUG_ON_ZERO(unit & ~KVM_STATS_UNIT_MASK) | \ + BUILD_BUG_ON_ZERO(base & ~KVM_STATS_BASE_MASK), \ + .exponent = exp, \ + .size = sz, \ .bucket_size = bsz -#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ - { \ - { \ - STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ - .offset = offsetof(struct kvm_vm_stat, generic.stat) \ - }, \ - .name = #stat, \ - } -#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ - { \ - { \ - STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ - .offset = offsetof(struct kvm_vcpu_stat, generic.stat) \ - }, \ - .name = #stat, \ - } -#define VM_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ - { \ - { \ - STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ - .offset = offsetof(struct kvm_vm_stat, stat) \ - }, \ - .name = #stat, \ - } -#define VCPU_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ - { \ - { \ - STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ - .offset = offsetof(struct kvm_vcpu_stat, stat) \ - }, \ - .name = #stat, \ - } +#define VM_GENERIC_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ +{ \ + STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ + .offset = offsetof(struct kvm_vm_stat, generic.stat), \ + .name = #stat, \ +} +#define VCPU_GENERIC_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ +{ \ + STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ + .offset = offsetof(struct kvm_vcpu_stat, generic.stat), \ + .name = #stat, \ +} +#define VM_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ +{ \ + STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ + .offset = offsetof(struct kvm_vm_stat, stat), \ + .name = #stat, \ +} +#define VCPU_STATS_DESC(stat, type, unit, base, exp, sz, bsz) \ +{ \ + STATS_DESC_COMMON(type, unit, base, exp, sz, bsz), \ + .offset = offsetof(struct kvm_vcpu_stat, stat), \ + .name = #stat, \ +} /* SCOPE: VM, VM_GENERIC, VCPU, VCPU_GENERIC */ #define STATS_DESC(SCOPE, stat, type, unit, base, exp, sz, bsz) \ SCOPE##_STATS_DESC(stat, type, unit, base, exp, sz, bsz) @@ -2069,7 +2053,7 @@ struct _kvm_stats_desc { STATS_DESC_IBOOLEAN(VCPU_GENERIC, blocking) ssize_t kvm_stats_read(char *id, const struct kvm_stats_header *header, - const struct _kvm_stats_desc *desc, + const struct kvm_stats_desc *desc, void *stats, size_t size_stats, char __user *user_buffer, size_t size, loff_t *offset); @@ -2114,11 +2098,10 @@ static inline void kvm_stats_log_hist_update(u64 *data, size_t size, u64 value) extern const struct kvm_stats_header kvm_vm_stats_header; -extern const struct _kvm_stats_desc kvm_vm_stats_desc[]; +extern const struct kvm_stats_desc kvm_vm_stats_desc[]; extern const struct kvm_stats_header kvm_vcpu_stats_header; -extern const struct _kvm_stats_desc kvm_vcpu_stats_desc[]; +extern const struct kvm_stats_desc kvm_vcpu_stats_desc[]; -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER static inline int mmu_invalidate_retry(struct kvm *kvm, unsigned long mmu_seq) { if (unlikely(kvm->mmu_invalidate_in_progress)) @@ -2196,7 +2179,6 @@ static inline bool mmu_invalidate_retry_gfn_unsafe(struct kvm *kvm, return READ_ONCE(kvm->mmu_invalidate_seq) != mmu_seq; } -#endif #ifdef CONFIG_HAVE_KVM_IRQ_ROUTING diff --git a/include/linux/leds-expresswire.h b/include/linux/leds-expresswire.h index a422921f4159..7f8c4795f69f 100644 --- a/include/linux/leds-expresswire.h +++ b/include/linux/leds-expresswire.h @@ -30,9 +30,6 @@ struct expresswire_common_props { void expresswire_power_off(struct expresswire_common_props *props); void expresswire_enable(struct expresswire_common_props *props); -void expresswire_start(struct expresswire_common_props *props); -void expresswire_end(struct expresswire_common_props *props); -void expresswire_set_bit(struct expresswire_common_props *props, bool bit); void expresswire_write_u8(struct expresswire_common_props *props, u8 val); #endif /* _LEDS_EXPRESSWIRE_H */ diff --git a/include/linux/linux_logo.h b/include/linux/linux_logo.h index e37699b7e839..1e727a2cb4c1 100644 --- a/include/linux/linux_logo.h +++ b/include/linux/linux_logo.h @@ -33,14 +33,6 @@ struct linux_logo { extern const struct linux_logo logo_linux_mono; extern const struct linux_logo logo_linux_vga16; extern const struct linux_logo logo_linux_clut224; -extern const struct linux_logo logo_dec_clut224; -extern const struct linux_logo logo_mac_clut224; -extern const struct linux_logo logo_parisc_clut224; -extern const struct linux_logo logo_sgi_clut224; -extern const struct linux_logo logo_sun_clut224; -extern const struct linux_logo logo_superh_mono; -extern const struct linux_logo logo_superh_vga16; -extern const struct linux_logo logo_superh_clut224; extern const struct linux_logo logo_spe_clut224; extern const struct linux_logo *fb_find_logo(int depth); diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index fe82a6c3005f..dd11fdc76a5f 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -23,8 +23,11 @@ struct file; /** * struct liveupdate_file_op_args - Arguments for file operation callbacks. * @handler: The file handler being called. - * @retrieved: The retrieve status for the 'can_finish / finish' - * operation. + * @retrieve_status: The retrieve status for the 'can_finish / finish' + * operation. A value of 0 means the retrieve has not been + * attempted, a positive value means the retrieve was + * successful, and a negative value means the retrieve failed, + * and the value is the error code of the call. * @file: The file object. For retrieve: [OUT] The callback sets * this to the new file. For other ops: [IN] The caller sets * this to the file being operated on. @@ -40,7 +43,7 @@ struct file; */ struct liveupdate_file_op_args { struct liveupdate_file_handler *handler; - bool retrieved; + int retrieve_status; struct file *file; u64 serialized_data; void *private_data; diff --git a/include/linux/mailbox/mtk-vcp-mailbox.h b/include/linux/mailbox/mtk-vcp-mailbox.h new file mode 100644 index 000000000000..16e59d6780a7 --- /dev/null +++ b/include/linux/mailbox/mtk-vcp-mailbox.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (c) 2025 MediaTek Inc. + */ + +#ifndef __MTK_VCP_MAILBOX_H__ +#define __MTK_VCP_MAILBOX_H__ + +#define MTK_VCP_MBOX_SLOT_MAX_SIZE 0x100 /* mbox max slot size */ + +/** + * struct mtk_ipi_info - mailbox message info for mtk-vcp-mailbox + * @msg: The share buffer between IPC and mailbox driver + * @len: Message length + * @id: This is for identification purposes and not actually used + * by the mailbox hardware. + * @index: The signal number of the mailbox message. + * @slot_ofs: Data slot offset. + * @irq_status: Captures incoming signals for the RX path. + * + * It is used between IPC with mailbox driver. + */ +struct mtk_ipi_info { + void *msg; + u32 len; + u32 id; + u32 index; + u32 slot_ofs; + u32 irq_status; +}; + +#endif diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 1baee139999f..70b685a85bf4 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -359,8 +359,7 @@ enum objext_flags { * MEMCG_DATA_OBJEXTS. */ OBJEXTS_ALLOC_FAIL = __OBJEXTS_ALLOC_FAIL, - /* slabobj_ext vector allocated with kmalloc_nolock() */ - OBJEXTS_NOSPIN_ALLOC = __FIRST_OBJEXT_FLAG, + __OBJEXTS_FLAG_UNUSED = __FIRST_OBJEXT_FLAG, /* the next bit after the last actual flag */ __NR_OBJEXTS_FLAGS = (__FIRST_OBJEXT_FLAG << 1), }; @@ -1759,7 +1758,7 @@ static inline void count_objcg_events(struct obj_cgroup *objcg, rcu_read_unlock(); } -bool mem_cgroup_node_allowed(struct mem_cgroup *memcg, int nid); +void mem_cgroup_node_filter_allowed(struct mem_cgroup *memcg, nodemask_t *mask); void mem_cgroup_show_protected_memory(struct mem_cgroup *memcg); @@ -1830,9 +1829,9 @@ static inline ino_t page_cgroup_ino(struct page *page) return 0; } -static inline bool mem_cgroup_node_allowed(struct mem_cgroup *memcg, int nid) +static inline void mem_cgroup_node_filter_allowed(struct mem_cgroup *memcg, + nodemask_t *mask) { - return true; } static inline void mem_cgroup_show_protected_memory(struct mem_cgroup *memcg) diff --git a/include/linux/memory-tiers.h b/include/linux/memory-tiers.h index 7a805796fcfd..96987d9d95a8 100644 --- a/include/linux/memory-tiers.h +++ b/include/linux/memory-tiers.h @@ -53,11 +53,11 @@ struct memory_dev_type *mt_find_alloc_memory_type(int adist, struct list_head *memory_types); void mt_put_memory_types(struct list_head *memory_types); #ifdef CONFIG_MIGRATION -int next_demotion_node(int node); +int next_demotion_node(int node, const nodemask_t *allowed_mask); void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets); bool node_is_toptier(int node); #else -static inline int next_demotion_node(int node) +static inline int next_demotion_node(int node, const nodemask_t *allowed_mask) { return NUMA_NO_NODE; } @@ -101,7 +101,7 @@ static inline void clear_node_memory_type(int node, struct memory_dev_type *memt } -static inline int next_demotion_node(int node) +static inline int next_demotion_node(int node, const nodemask_t *allowed_mask) { return NUMA_NO_NODE; } diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h index 3c5aecf1d4b5..b352661d99a1 100644 --- a/include/linux/mfd/axp20x.h +++ b/include/linux/mfd/axp20x.h @@ -174,6 +174,9 @@ enum axp20x_variants { #define AXP717_ADC_DATA_SEL 0xcd #define AXP717_ADC_DATA_H 0xce #define AXP717_ADC_DATA_L 0xcf +#define AXP717_TYPEC_CC_AA_EN 0xe1 +#define AXP717_TYPEC_CC_MODE_CONTROL 0xe3 +#define AXP717_TYPEC_CC_STATUS 0xe7 #define AXP806_STARTUP_SRC 0x00 #define AXP806_CHIP_ID 0x03 diff --git a/include/linux/mfd/rk808.h b/include/linux/mfd/rk808.h index 28170ee08898..7ffc904c864c 100644 --- a/include/linux/mfd/rk808.h +++ b/include/linux/mfd/rk808.h @@ -340,6 +340,123 @@ enum rk818_reg { #define RK818_USB_ILMIN_2000MA 0x7 #define RK818_USB_CHG_SD_VSEL_MASK 0x70 +/* RK801 */ +enum rk801_reg { + RK801_ID_DCDC1, + RK801_ID_DCDC2, + RK801_ID_DCDC4, + RK801_ID_DCDC3, + RK801_ID_LDO1, + RK801_ID_LDO2, + RK801_ID_SWITCH, + RK801_ID_MAX, +}; + +#define RK801_SLP_REG_OFFSET 5 +#define RK801_NUM_REGULATORS 7 + +#define RK801_HW_SYNC_US 32 + +/* RK801 Register Definitions */ +#define RK801_ID_MSB 0x00 +#define RK801_ID_LSB 0x01 +#define RK801_OTP_VER_REG 0x02 +#define RK801_POWER_EN0_REG 0x03 +#define RK801_POWER_EN1_REG 0x04 +#define RK801_POWER_SLP_EN_REG 0x05 +#define RK801_POWER_FPWM_EN_REG 0x06 +#define RK801_SLP_LP_CONFIG_REG 0x07 +#define RK801_BUCK_CONFIG_REG 0x08 +#define RK801_BUCK1_ON_VSEL_REG 0x09 +#define RK801_BUCK2_ON_VSEL_REG 0x0a +#define RK801_BUCK4_ON_VSEL_REG 0x0b +#define RK801_LDO1_ON_VSEL_REG 0x0c +#define RK801_LDO2_ON_VSEL_REG 0x0d +#define RK801_BUCK1_SLP_VSEL_REG 0x0e +#define RK801_BUCK2_SLP_VSEL_REG 0x0f +#define RK801_BUCK4_SLP_VSEL_REG 0x10 +#define RK801_LDO1_SLP_VSEL_REG 0x11 +#define RK801_LDO2_SLP_VSEL_REG 0x12 +#define RK801_LDO_SW_IMAX_REG 0x13 +#define RK801_SYS_STS_REG 0x14 +#define RK801_SYS_CFG0_REG 0x15 +#define RK801_SYS_CFG1_REG 0x16 +#define RK801_SYS_CFG2_REG 0x17 +#define RK801_SYS_CFG3_REG 0x18 +#define RK801_SYS_CFG4_REG 0x19 +#define RK801_SLEEP_CFG_REG 0x1a +#define RK801_ON_SOURCE_REG 0x1b +#define RK801_OFF_SOURCE_REG 0x1c +#define RK801_PWRON_KEY_REG 0x1d +#define RK801_INT_STS0_REG 0x1e +#define RK801_INT_MASK0_REG 0x1f +#define RK801_INT_CONFIG_REG 0x20 +#define RK801_CON_BACK1_REG 0x21 +#define RK801_CON_BACK2_REG 0x22 +#define RK801_DATA_CON0_REG 0x23 +#define RK801_DATA_CON1_REG 0x24 +#define RK801_DATA_CON2_REG 0x25 +#define RK801_DATA_CON3_REG 0x26 +#define RK801_POWER_EXIT_SLP_SEQ0_REG 0x27 +#define RK801_POWER_EXIT_SLP_SEQ1_REG 0x28 +#define RK801_POWER_EXIT_SLP_SEQ2_REG 0x29 +#define RK801_POWER_EXIT_SLP_SEQ3_REG 0x2a +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ0_REG 0x2b +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ1_REG 0x2c +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ2_REG 0x2d +#define RK801_POWER_ENTER_SLP_OR_SHTD_SEQ3_REG 0x2e +#define RK801_BUCK_DEBUG1_REG 0x2f +#define RK801_BUCK_DEBUG2_REG 0x30 +#define RK801_BUCK_DEBUG3_REG 0x31 +#define RK801_BUCK_DEBUG4_REG 0x32 +#define RK801_BUCK_DEBUG5_REG 0x33 +#define RK801_BUCK_DEBUG7_REG 0x34 +#define RK801_OTP_EN_CON_REG 0x35 +#define RK801_TEST_CON_REG 0x36 +#define RK801_EFUSE_CONTROL_REG 0x37 +#define RK801_SYS_CFG3_OTP_REG 0x38 + +/* RK801 IRQ Definitions */ +#define RK801_IRQ_PWRON_FALL 0 +#define RK801_IRQ_PWRON_RISE 1 +#define RK801_IRQ_PWRON 2 +#define RK801_IRQ_PWRON_LP 3 +#define RK801_IRQ_HOTDIE 4 +#define RK801_IRQ_VDC_RISE 5 +#define RK801_IRQ_VDC_FALL 6 +#define RK801_IRQ_PWRON_FALL_MSK BIT(0) +#define RK801_IRQ_PWRON_RISE_MSK BIT(1) +#define RK801_IRQ_PWRON_MSK BIT(2) +#define RK801_IRQ_PWRON_LP_MSK BIT(3) +#define RK801_IRQ_HOTDIE_MSK BIT(4) +#define RK801_IRQ_VDC_RISE_MSK BIT(5) +#define RK801_IRQ_VDC_FALL_MSK BIT(6) +/* RK801_SLP_LP_CONFIG_REG */ +#define RK801_BUCK_SLP_LP_EN BIT(3) +#define RK801_PLDO_SLP_LP_EN BIT(1) +#define RK801_SLP_LP_MASK (RK801_PLDO_SLP_LP_EN | RK801_BUCK_SLP_LP_EN) +/* RK801_SLEEP_CFG_REG */ +#define RK801_SLEEP_FUN_MSK 0x3 +#define RK801_NONE_FUN 0x0 +#define RK801_SLEEP_FUN 0x1 +#define RK801_SHUTDOWN_FUN 0x2 +#define RK801_RESET_FUN 0x3 +/* RK801_SYS_CFG2_REG */ +#define RK801_SLEEP_POL_MSK BIT(1) +#define RK801_SLEEP_ACT_H BIT(1) +#define RK801_SLEEP_ACT_L 0 +#define RK801_RST_MSK (0x3 << 4) +#define RK801_RST_RESTART_PMU (0x0 << 4) +#define RK801_RST_RESTART_REG (0x1 << 4) +#define RK801_RST_RESTART_REG_RESETB (0x2 << 4) +/* RK801_INT_CONFIG_REG */ +#define RK801_INT_POL_MSK BIT(1) +#define RK801_INT_ACT_H BIT(1) +#define RK801_INT_ACT_L 0 +#define RK801_FPWM_MODE 1 +#define RK801_AUTO_PWM_MODE 0 +#define RK801_PLDO_HRDEC_EN BIT(6) + /* RK805 */ enum rk805_reg { RK805_ID_DCDC1, @@ -1332,6 +1449,7 @@ enum { }; enum { + RK801_ID = 0x8010, RK805_ID = 0x8050, RK806_ID = 0x8060, RK808_ID = 0x0000, diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h index 73a71ef69152..39fe275a8117 100644 --- a/include/linux/mfd/rohm-bd71828.h +++ b/include/linux/mfd/rohm-bd71828.h @@ -249,6 +249,8 @@ enum { #define BD71828_REG_BATCAP_MON_LIMIT_U 0xcc #define BD71828_REG_CONF 0x64 +#define BD71828_REG_ILIM_STAT 0x6d +#define BD71828_REG_DCIN_SET 0x70 #define BD71828_REG_DCIN_CLPS 0x71 #define BD71828_REG_MEAS_CLEAR 0xaf diff --git a/include/linux/mfd/tps6105x.h b/include/linux/mfd/tps6105x.h index b1313411ef09..94e699896240 100644 --- a/include/linux/mfd/tps6105x.h +++ b/include/linux/mfd/tps6105x.h @@ -53,7 +53,7 @@ /** * enum tps6105x_mode - desired mode for the TPS6105x * @TPS6105X_MODE_SHUTDOWN: this instance is inactive, not used for anything - * @TPS61905X_MODE_TORCH: this instance is used as a LED, usually a while + * @TPS6105X_MODE_TORCH: this instance is used as a LED, usually a while * LED, for example as backlight or flashlight. If this is set, the * TPS6105X will register to the LED framework * @TPS6105X_MODE_TORCH_FLASH: this instance is used as a flashgun, usually @@ -82,7 +82,8 @@ struct tps6105x_platform_data { /** * struct tps6105x - state holder for the TPS6105x drivers - * @i2c_client: corresponding I2C client + * @pdata: associated platform data + * @client: corresponding I2C client * @regulator: regulator device if used in voltage mode * @regmap: used for i2c communcation on accessing registers */ diff --git a/include/linux/mfd/tps65219.h b/include/linux/mfd/tps65219.h index 55234e771ba7..3abf937191d0 100644 --- a/include/linux/mfd/tps65219.h +++ b/include/linux/mfd/tps65219.h @@ -149,6 +149,8 @@ enum pmic_id { #define TPS65215_ENABLE_LDO2_EN_MASK BIT(5) #define TPS65214_ENABLE_LDO1_EN_MASK BIT(5) #define TPS65219_ENABLE_LDO4_EN_MASK BIT(6) +/* Register Unlock */ +#define TPS65214_LOCK_ACCESS_CMD 0x5a /* power ON-OFF sequence slot */ #define TPS65219_BUCKS_LDOS_SEQUENCE_OFF_SLOT_MASK GENMASK(3, 0) #define TPS65219_BUCKS_LDOS_SEQUENCE_ON_SLOT_MASK GENMASK(7, 4) diff --git a/include/linux/mhi.h b/include/linux/mhi.h index dd372b0123a6..88ccb3e14f48 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -215,7 +215,6 @@ enum mhi_db_brst_mode { * @lpm_notify: The channel master requires low power mode notifications * @offload_channel: The client manages the channel completely * @doorbell_mode_switch: Channel switches to doorbell mode on M0 transition - * @auto_queue: Framework will automatically queue buffers for DL traffic * @wake-capable: Channel capable of waking up the system */ struct mhi_channel_config { @@ -232,7 +231,6 @@ struct mhi_channel_config { bool lpm_notify; bool offload_channel; bool doorbell_mode_switch; - bool auto_queue; bool wake_capable; }; @@ -743,18 +741,6 @@ void mhi_device_put(struct mhi_device *mhi_dev); */ int mhi_prepare_for_transfer(struct mhi_device *mhi_dev); -/** - * mhi_prepare_for_transfer_autoqueue - Setup UL and DL channels with auto queue - * buffers for DL traffic - * @mhi_dev: Device associated with the channels - * - * Allocate and initialize the channel context and also issue the START channel - * command to both channels. Channels can be started only if both host and - * device execution environments match and channels are in a DISABLED state. - * The MHI core will automatically allocate and queue buffers for the DL traffic. - */ -int mhi_prepare_for_transfer_autoqueue(struct mhi_device *mhi_dev); - /** * mhi_unprepare_from_transfer - Reset UL and DL channels for data transfer. * Issue the RESET channel command and let the diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 26ca00c325d9..d5af2b7f577b 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -65,7 +65,7 @@ bool isolate_folio_to_list(struct folio *folio, struct list_head *list); int migrate_huge_page_move_mapping(struct address_space *mapping, struct folio *dst, struct folio *src); -void migration_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) +void softleaf_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) __releases(ptl); void folio_migrate_flags(struct folio *newfolio, struct folio *folio); int folio_migrate_mapping(struct address_space *mapping, @@ -97,6 +97,14 @@ static inline int set_movable_ops(const struct movable_operations *ops, enum pag return -ENOSYS; } +static inline void softleaf_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) + __releases(ptl) +{ + WARN_ON_ONCE(1); + + spin_unlock(ptl); +} + #endif /* CONFIG_MIGRATION */ #ifdef CONFIG_NUMA_BALANCING diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h index 7d0aa718499c..fa9000f68523 100644 --- a/include/linux/miscdevice.h +++ b/include/linux/miscdevice.h @@ -52,7 +52,6 @@ #define PXA3XX_GCU_MINOR 197 #define TUN_MINOR 200 #define CUSE_MINOR 203 -#define MWAVE_MINOR 219 /* ACP/Mwave Modem */ #define MPT_MINOR 220 #define MPT2SAS_MINOR 221 #define MPT3SAS_MINOR 222 diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index e2d067b1e67b..04dcd09f7517 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -1282,12 +1282,12 @@ static inline bool mlx5_rl_is_supported(struct mlx5_core_dev *dev) static inline int mlx5_core_is_mp_slave(struct mlx5_core_dev *dev) { return MLX5_CAP_GEN(dev, affiliate_nic_vport_criteria) && - MLX5_CAP_GEN(dev, num_vhca_ports) <= 1; + MLX5_CAP_GEN_MAX(dev, num_vhca_ports) <= 1; } static inline int mlx5_core_is_mp_master(struct mlx5_core_dev *dev) { - return MLX5_CAP_GEN(dev, num_vhca_ports) > 1; + return MLX5_CAP_GEN_MAX(dev, num_vhca_ports) > 1; } static inline int mlx5_core_mp_enabled(struct mlx5_core_dev *dev) diff --git a/include/linux/mm.h b/include/linux/mm.h index dc1ad71a2a70..abb4963c1f06 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -2,6 +2,7 @@ #ifndef _LINUX_MM_H #define _LINUX_MM_H +#include #include #include #include @@ -551,17 +552,18 @@ enum { /* * Physically remapped pages are special. Tell the * rest of the world about it: - * VM_IO tells people not to look at these pages + * IO tells people not to look at these pages * (accesses can have side effects). - * VM_PFNMAP tells the core MM that the base pages are just + * PFNMAP tells the core MM that the base pages are just * raw PFN mappings, and do not have a "struct page" associated * with them. - * VM_DONTEXPAND + * DONTEXPAND * Disable vma merging and expanding with mremap(). - * VM_DONTDUMP + * DONTDUMP * Omit vma from core dump, even when VM_IO turned off. */ -#define VM_REMAP_FLAGS (VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP) +#define VMA_REMAP_FLAGS mk_vma_flags(VMA_IO_BIT, VMA_PFNMAP_BIT, \ + VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT) /* This mask prevents VMA from being scanned with khugepaged */ #define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB) @@ -945,7 +947,7 @@ static inline void vm_flags_reset_once(struct vm_area_struct *vma, * system word. */ if (NUM_VMA_FLAG_BITS > BITS_PER_LONG) { - unsigned long *bitmap = ACCESS_PRIVATE(&vma->flags, __vma_flags); + unsigned long *bitmap = vma->flags.__vma_flags; bitmap_zero(&bitmap[1], NUM_VMA_FLAG_BITS - BITS_PER_LONG); } @@ -989,8 +991,7 @@ static inline void vm_flags_mod(struct vm_area_struct *vma, __vm_flags_mod(vma, set, clear); } -static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma, - vma_flag_t bit) +static inline bool __vma_atomic_valid_flag(struct vm_area_struct *vma, vma_flag_t bit) { const vm_flags_t mask = BIT((__force int)bit); @@ -1005,13 +1006,12 @@ static inline bool __vma_flag_atomic_valid(struct vm_area_struct *vma, * Set VMA flag atomically. Requires only VMA/mmap read lock. Only specific * valid flags are allowed to do this. */ -static inline void vma_flag_set_atomic(struct vm_area_struct *vma, - vma_flag_t bit) +static inline void vma_set_atomic_flag(struct vm_area_struct *vma, vma_flag_t bit) { - unsigned long *bitmap = ACCESS_PRIVATE(&vma->flags, __vma_flags); + unsigned long *bitmap = vma->flags.__vma_flags; vma_assert_stabilised(vma); - if (__vma_flag_atomic_valid(vma, bit)) + if (__vma_atomic_valid_flag(vma, bit)) set_bit((__force int)bit, bitmap); } @@ -1022,15 +1022,211 @@ static inline void vma_flag_set_atomic(struct vm_area_struct *vma, * This is necessarily racey, so callers must ensure that serialisation is * achieved through some other means, or that races are permissible. */ -static inline bool vma_flag_test_atomic(struct vm_area_struct *vma, - vma_flag_t bit) +static inline bool vma_test_atomic_flag(struct vm_area_struct *vma, vma_flag_t bit) { - if (__vma_flag_atomic_valid(vma, bit)) + if (__vma_atomic_valid_flag(vma, bit)) return test_bit((__force int)bit, &vma->vm_flags); return false; } +/* Set an individual VMA flag in flags, non-atomically. */ +static inline void vma_flag_set(vma_flags_t *flags, vma_flag_t bit) +{ + unsigned long *bitmap = flags->__vma_flags; + + __set_bit((__force int)bit, bitmap); +} + +static inline vma_flags_t __mk_vma_flags(size_t count, const vma_flag_t *bits) +{ + vma_flags_t flags; + int i; + + vma_flags_clear_all(&flags); + for (i = 0; i < count; i++) + vma_flag_set(&flags, bits[i]); + return flags; +} + +/* + * Helper macro which bitwise-or combines the specified input flags into a + * vma_flags_t bitmap value. E.g.: + * + * vma_flags_t flags = mk_vma_flags(VMA_IO_BIT, VMA_PFNMAP_BIT, + * VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT); + * + * The compiler cleverly optimises away all of the work and this ends up being + * equivalent to aggregating the values manually. + */ +#define mk_vma_flags(...) __mk_vma_flags(COUNT_ARGS(__VA_ARGS__), \ + (const vma_flag_t []){__VA_ARGS__}) + +/* Test each of to_test flags in flags, non-atomically. */ +static __always_inline bool vma_flags_test_mask(const vma_flags_t *flags, + vma_flags_t to_test) +{ + const unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_test = to_test.__vma_flags; + + return bitmap_intersects(bitmap_to_test, bitmap, NUM_VMA_FLAG_BITS); +} + +/* + * Test whether any specified VMA flag is set, e.g.: + * + * if (vma_flags_test(flags, VMA_READ_BIT, VMA_MAYREAD_BIT)) { ... } + */ +#define vma_flags_test(flags, ...) \ + vma_flags_test_mask(flags, mk_vma_flags(__VA_ARGS__)) + +/* Test that ALL of the to_test flags are set, non-atomically. */ +static __always_inline bool vma_flags_test_all_mask(const vma_flags_t *flags, + vma_flags_t to_test) +{ + const unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_test = to_test.__vma_flags; + + return bitmap_subset(bitmap_to_test, bitmap, NUM_VMA_FLAG_BITS); +} + +/* + * Test whether ALL specified VMA flags are set, e.g.: + * + * if (vma_flags_test_all(flags, VMA_READ_BIT, VMA_MAYREAD_BIT)) { ... } + */ +#define vma_flags_test_all(flags, ...) \ + vma_flags_test_all_mask(flags, mk_vma_flags(__VA_ARGS__)) + +/* Set each of the to_set flags in flags, non-atomically. */ +static __always_inline void vma_flags_set_mask(vma_flags_t *flags, vma_flags_t to_set) +{ + unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_set = to_set.__vma_flags; + + bitmap_or(bitmap, bitmap, bitmap_to_set, NUM_VMA_FLAG_BITS); +} + +/* + * Set all specified VMA flags, e.g.: + * + * vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT); + */ +#define vma_flags_set(flags, ...) \ + vma_flags_set_mask(flags, mk_vma_flags(__VA_ARGS__)) + +/* Clear all of the to-clear flags in flags, non-atomically. */ +static __always_inline void vma_flags_clear_mask(vma_flags_t *flags, vma_flags_t to_clear) +{ + unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_clear = to_clear.__vma_flags; + + bitmap_andnot(bitmap, bitmap, bitmap_to_clear, NUM_VMA_FLAG_BITS); +} + +/* + * Clear all specified individual flags, e.g.: + * + * vma_flags_clear(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT); + */ +#define vma_flags_clear(flags, ...) \ + vma_flags_clear_mask(flags, mk_vma_flags(__VA_ARGS__)) + +/* + * Helper to test that ALL specified flags are set in a VMA. + * + * Note: appropriate locks must be held, this function does not acquire them for + * you. + */ +static inline bool vma_test_all_flags_mask(const struct vm_area_struct *vma, + vma_flags_t flags) +{ + return vma_flags_test_all_mask(&vma->flags, flags); +} + +/* + * Helper macro for checking that ALL specified flags are set in a VMA, e.g.: + * + * if (vma_test_all_flags(vma, VMA_READ_BIT, VMA_MAYREAD_BIT) { ... } + */ +#define vma_test_all_flags(vma, ...) \ + vma_test_all_flags_mask(vma, mk_vma_flags(__VA_ARGS__)) + +/* + * Helper to set all VMA flags in a VMA. + * + * Note: appropriate locks must be held, this function does not acquire them for + * you. + */ +static inline void vma_set_flags_mask(struct vm_area_struct *vma, + vma_flags_t flags) +{ + vma_flags_set_mask(&vma->flags, flags); +} + +/* + * Helper macro for specifying VMA flags in a VMA, e.g.: + * + * vma_set_flags(vma, VMA_IO_BIT, VMA_PFNMAP_BIT, VMA_DONTEXPAND_BIT, + * VMA_DONTDUMP_BIT); + * + * Note: appropriate locks must be held, this function does not acquire them for + * you. + */ +#define vma_set_flags(vma, ...) \ + vma_set_flags_mask(vma, mk_vma_flags(__VA_ARGS__)) + +/* Helper to test all VMA flags in a VMA descriptor. */ +static inline bool vma_desc_test_flags_mask(const struct vm_area_desc *desc, + vma_flags_t flags) +{ + return vma_flags_test_mask(&desc->vma_flags, flags); +} + +/* + * Helper macro for testing VMA flags for an input pointer to a struct + * vm_area_desc object describing a proposed VMA, e.g.: + * + * if (vma_desc_test_flags(desc, VMA_IO_BIT, VMA_PFNMAP_BIT, + * VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT)) { ... } + */ +#define vma_desc_test_flags(desc, ...) \ + vma_desc_test_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + +/* Helper to set all VMA flags in a VMA descriptor. */ +static inline void vma_desc_set_flags_mask(struct vm_area_desc *desc, + vma_flags_t flags) +{ + vma_flags_set_mask(&desc->vma_flags, flags); +} + +/* + * Helper macro for specifying VMA flags for an input pointer to a struct + * vm_area_desc object describing a proposed VMA, e.g.: + * + * vma_desc_set_flags(desc, VMA_IO_BIT, VMA_PFNMAP_BIT, VMA_DONTEXPAND_BIT, + * VMA_DONTDUMP_BIT); + */ +#define vma_desc_set_flags(desc, ...) \ + vma_desc_set_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + +/* Helper to clear all VMA flags in a VMA descriptor. */ +static inline void vma_desc_clear_flags_mask(struct vm_area_desc *desc, + vma_flags_t flags) +{ + vma_flags_clear_mask(&desc->vma_flags, flags); +} + +/* + * Helper macro for clearing VMA flags for an input pointer to a struct + * vm_area_desc object describing a proposed VMA, e.g.: + * + * vma_desc_clear_flags(desc, VMA_IO_BIT, VMA_PFNMAP_BIT, VMA_DONTEXPAND_BIT, + * VMA_DONTDUMP_BIT); + */ +#define vma_desc_clear_flags(desc, ...) \ + vma_desc_clear_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + static inline void vma_set_anonymous(struct vm_area_struct *vma) { vma->vm_ops = NULL; @@ -1096,15 +1292,20 @@ static inline bool vma_is_accessible(const struct vm_area_struct *vma) return vma->vm_flags & VM_ACCESS_FLAGS; } -static inline bool is_shared_maywrite(vm_flags_t vm_flags) +static inline bool is_shared_maywrite_vm_flags(vm_flags_t vm_flags) { return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == (VM_SHARED | VM_MAYWRITE); } +static inline bool is_shared_maywrite(const vma_flags_t *flags) +{ + return vma_flags_test_all(flags, VMA_SHARED_BIT, VMA_MAYWRITE_BIT); +} + static inline bool vma_is_shared_maywrite(const struct vm_area_struct *vma) { - return is_shared_maywrite(vma->vm_flags); + return is_shared_maywrite(&vma->flags); } static inline @@ -1732,6 +1933,14 @@ static inline bool is_cow_mapping(vm_flags_t flags) return (flags & (VM_SHARED | VM_MAYWRITE)) == VM_MAYWRITE; } +static inline bool vma_desc_is_cow_mapping(struct vm_area_desc *desc) +{ + const vma_flags_t *flags = &desc->vma_flags; + + return vma_flags_test(flags, VMA_MAYWRITE_BIT) && + !vma_flags_test(flags, VMA_SHARED_BIT); +} + #ifndef CONFIG_MMU static inline bool is_nommu_shared_mapping(vm_flags_t flags) { @@ -1745,6 +1954,11 @@ static inline bool is_nommu_shared_mapping(vm_flags_t flags) */ return flags & (VM_MAYSHARE | VM_MAYOVERLAY); } + +static inline bool is_nommu_shared_vma_flags(const vma_flags_t *flags) +{ + return vma_flags_test(flags, VMA_MAYSHARE_BIT, VMA_MAYOVERLAY_BIT); +} #endif #if defined(CONFIG_SPARSEMEM) && !defined(CONFIG_SPARSEMEM_VMEMMAP) @@ -2627,10 +2841,6 @@ static inline void zap_vma_pages(struct vm_area_struct *vma) zap_page_range_single(vma, vma->vm_start, vma->vm_end - vma->vm_start, NULL); } -void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *start_vma, unsigned long start, - unsigned long end, unsigned long tree_end); - struct mmu_notifier_range; void free_pgd_range(struct mmu_gather *tlb, unsigned long addr, @@ -3304,26 +3514,21 @@ static inline bool ptlock_init(struct ptdesc *ptdesc) { return true; } static inline void ptlock_free(struct ptdesc *ptdesc) {} #endif /* defined(CONFIG_SPLIT_PTE_PTLOCKS) */ -static inline unsigned long ptdesc_nr_pages(const struct ptdesc *ptdesc) -{ - return compound_nr(ptdesc_page(ptdesc)); -} - static inline void __pagetable_ctor(struct ptdesc *ptdesc) { - pg_data_t *pgdat = NODE_DATA(memdesc_nid(ptdesc->pt_flags)); + struct folio *folio = ptdesc_folio(ptdesc); - __SetPageTable(ptdesc_page(ptdesc)); - mod_node_page_state(pgdat, NR_PAGETABLE, ptdesc_nr_pages(ptdesc)); + __folio_set_pgtable(folio); + lruvec_stat_add_folio(folio, NR_PAGETABLE); } static inline void pagetable_dtor(struct ptdesc *ptdesc) { - pg_data_t *pgdat = NODE_DATA(memdesc_nid(ptdesc->pt_flags)); + struct folio *folio = ptdesc_folio(ptdesc); ptlock_free(ptdesc); - __ClearPageTable(ptdesc_page(ptdesc)); - mod_node_page_state(pgdat, NR_PAGETABLE, -ptdesc_nr_pages(ptdesc)); + __folio_clear_pgtable(folio); + lruvec_stat_sub_folio(folio, NR_PAGETABLE); } static inline void pagetable_dtor_free(struct ptdesc *ptdesc) diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 8731606d8d36..3cc8ae722886 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -844,7 +844,7 @@ struct mmap_action { /* * If specified, this hook is invoked when an error occurred when - * attempting the selection action. + * attempting the selected action. * * The hook can return an error code in order to filter the error, but * it is not valid to clear the error here. @@ -866,7 +866,9 @@ struct mmap_action { #define NUM_VMA_FLAG_BITS BITS_PER_LONG typedef struct { DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS); -} __private vma_flags_t; +} vma_flags_t; + +#define EMPTY_VMA_FLAGS ((vma_flags_t){ }) /* * Describes a VMA that is about to be mmap()'ed. Drivers may choose to @@ -885,10 +887,7 @@ struct vm_area_desc { /* Mutable fields. Populated with initial state. */ pgoff_t pgoff; struct file *vm_file; - union { - vm_flags_t vm_flags; - vma_flags_t vma_flags; - }; + vma_flags_t vma_flags; pgprot_t page_prot; /* Write-only fields. */ @@ -1059,7 +1058,7 @@ struct vm_area_struct { /* Clears all bits in the VMA flags bitmap, non-atomically. */ static inline void vma_flags_clear_all(vma_flags_t *flags) { - bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS); + bitmap_zero(flags->__vma_flags, NUM_VMA_FLAG_BITS); } /* @@ -1070,7 +1069,9 @@ static inline void vma_flags_clear_all(vma_flags_t *flags) */ static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value) { - *ACCESS_PRIVATE(flags, __vma_flags) = value; + unsigned long *bitmap = flags->__vma_flags; + + bitmap[0] = value; } /* @@ -1081,7 +1082,7 @@ static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long va */ static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value) { - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + unsigned long *bitmap = flags->__vma_flags; WRITE_ONCE(*bitmap, value); } @@ -1089,7 +1090,7 @@ static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned lo /* Update the first system word of VMA flags setting bits, non-atomically. */ static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value) { - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + unsigned long *bitmap = flags->__vma_flags; *bitmap |= value; } @@ -1097,7 +1098,7 @@ static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value) /* Update the first system word of VMA flags clearing bits, non-atomically. */ static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value) { - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + unsigned long *bitmap = flags->__vma_flags; *bitmap &= ~value; } diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index e0e2c265e5d1..ba84f02c2a10 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -486,14 +486,12 @@ struct mmc_host { struct mmc_ios ios; /* current io bus settings */ + bool claimed; /* host exclusively claimed */ + /* group bitfields together to minimize padding */ unsigned int use_spi_crc:1; - unsigned int claimed:1; /* host exclusively claimed */ unsigned int doing_init_tune:1; /* initial tuning in progress */ - unsigned int can_retune:1; /* re-tuning can be used */ unsigned int doing_retune:1; /* re-tuning in progress */ - unsigned int retune_now:1; /* do re-tuning at next req */ - unsigned int retune_paused:1; /* re-tuning is temporarily disabled */ unsigned int retune_crc_disable:1; /* don't trigger retune upon crc */ unsigned int can_dma_map_merge:1; /* merging can be used */ unsigned int vqmmc_enabled:1; /* vqmmc regulator is enabled */ @@ -508,6 +506,9 @@ struct mmc_host { int rescan_disable; /* disable card detection */ int rescan_entered; /* used with nonremovable devices */ + bool can_retune; /* re-tuning can be used */ + bool retune_now; /* do re-tuning at next req */ + bool retune_paused; /* re-tuning is temporarily disabled */ int need_retune; /* re-tuning is needed */ int hold_retune; /* hold off re-tuning */ unsigned int retune_period; /* re-tuning period in secs */ diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index d1094c2d5fb6..8450e18a87c2 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -234,7 +234,7 @@ struct mmu_notifier { }; /** - * struct mmu_interval_notifier_ops + * struct mmu_interval_notifier_ops - callback for range notification * @invalidate: Upon return the caller must stop using any SPTEs within this * range. This function can sleep. Return false only if sleeping * was required but mmu_notifier_range_blockable(range) is false. @@ -309,8 +309,8 @@ void mmu_interval_notifier_remove(struct mmu_interval_notifier *interval_sub); /** * mmu_interval_set_seq - Save the invalidation sequence - * @interval_sub - The subscription passed to invalidate - * @cur_seq - The cur_seq passed to the invalidate() callback + * @interval_sub: The subscription passed to invalidate + * @cur_seq: The cur_seq passed to the invalidate() callback * * This must be called unconditionally from the invalidate callback of a * struct mmu_interval_notifier_ops under the same lock that is used to call @@ -329,8 +329,8 @@ mmu_interval_set_seq(struct mmu_interval_notifier *interval_sub, /** * mmu_interval_read_retry - End a read side critical section against a VA range - * interval_sub: The subscription - * seq: The return of the paired mmu_interval_read_begin() + * @interval_sub: The subscription + * @seq: The return of the paired mmu_interval_read_begin() * * This MUST be called under a user provided lock that is also held * unconditionally by op->invalidate() when it calls mmu_interval_set_seq(). @@ -338,7 +338,7 @@ mmu_interval_set_seq(struct mmu_interval_notifier *interval_sub, * Each call should be paired with a single mmu_interval_read_begin() and * should be used to conclude the read side. * - * Returns true if an invalidation collided with this critical section, and + * Returns: true if an invalidation collided with this critical section, and * the caller should retry. */ static inline bool @@ -350,20 +350,21 @@ mmu_interval_read_retry(struct mmu_interval_notifier *interval_sub, /** * mmu_interval_check_retry - Test if a collision has occurred - * interval_sub: The subscription - * seq: The return of the matching mmu_interval_read_begin() + * @interval_sub: The subscription + * @seq: The return of the matching mmu_interval_read_begin() * * This can be used in the critical section between mmu_interval_read_begin() - * and mmu_interval_read_retry(). A return of true indicates an invalidation - * has collided with this critical region and a future - * mmu_interval_read_retry() will return true. - * - * False is not reliable and only suggests a collision may not have - * occurred. It can be called many times and does not have to hold the user - * provided lock. + * and mmu_interval_read_retry(). * * This call can be used as part of loops and other expensive operations to * expedite a retry. + * It can be called many times and does not have to hold the user + * provided lock. + * + * Returns: true indicates an invalidation has collided with this critical + * region and a future mmu_interval_read_retry() will return true. + * False is not reliable and only suggests a collision may not have + * occurred. */ static inline bool mmu_interval_check_retry(struct mmu_interval_notifier *interval_sub, @@ -515,16 +516,17 @@ static inline void mmu_notifier_range_init_owner( range->owner = owner; } -#define ptep_clear_flush_young_notify(__vma, __address, __ptep) \ +#define clear_flush_young_ptes_notify(__vma, __address, __ptep, __nr) \ ({ \ int __young; \ struct vm_area_struct *___vma = __vma; \ unsigned long ___address = __address; \ - __young = ptep_clear_flush_young(___vma, ___address, __ptep); \ + unsigned int ___nr = __nr; \ + __young = clear_flush_young_ptes(___vma, ___address, __ptep, ___nr); \ __young |= mmu_notifier_clear_flush_young(___vma->vm_mm, \ ___address, \ ___address + \ - PAGE_SIZE); \ + ___nr * PAGE_SIZE); \ __young; \ }) @@ -650,7 +652,7 @@ static inline void mmu_notifier_subscriptions_destroy(struct mm_struct *mm) #define mmu_notifier_range_update_to_read_only(r) false -#define ptep_clear_flush_young_notify ptep_clear_flush_young +#define clear_flush_young_ptes_notify clear_flush_young_ptes #define pmdp_clear_flush_young_notify pmdp_clear_flush_young #define ptep_clear_young_notify ptep_test_and_clear_young #define pmdp_clear_young_notify pmdp_test_and_clear_young diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d4e6e00bb90a..ae269a2e7f4d 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3576,17 +3576,49 @@ struct page_pool_bh { }; DECLARE_PER_CPU(struct page_pool_bh, system_page_pool); +#define XMIT_RECURSION_LIMIT 8 + #ifndef CONFIG_PREEMPT_RT static inline int dev_recursion_level(void) { return this_cpu_read(softnet_data.xmit.recursion); } + +static inline bool dev_xmit_recursion(void) +{ + return unlikely(__this_cpu_read(softnet_data.xmit.recursion) > + XMIT_RECURSION_LIMIT); +} + +static inline void dev_xmit_recursion_inc(void) +{ + __this_cpu_inc(softnet_data.xmit.recursion); +} + +static inline void dev_xmit_recursion_dec(void) +{ + __this_cpu_dec(softnet_data.xmit.recursion); +} #else static inline int dev_recursion_level(void) { return current->net_xmit.recursion; } +static inline bool dev_xmit_recursion(void) +{ + return unlikely(current->net_xmit.recursion > XMIT_RECURSION_LIMIT); +} + +static inline void dev_xmit_recursion_inc(void) +{ + current->net_xmit.recursion++; +} + +static inline void dev_xmit_recursion_dec(void) +{ + current->net_xmit.recursion--; +} #endif void __netif_schedule(struct Qdisc *q); @@ -4711,7 +4743,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) { spin_lock(&txq->_xmit_lock); - /* Pairs with READ_ONCE() in __dev_queue_xmit() */ + /* Pairs with READ_ONCE() in netif_tx_owned() */ WRITE_ONCE(txq->xmit_lock_owner, cpu); } @@ -4729,7 +4761,7 @@ static inline void __netif_tx_release(struct netdev_queue *txq) static inline void __netif_tx_lock_bh(struct netdev_queue *txq) { spin_lock_bh(&txq->_xmit_lock); - /* Pairs with READ_ONCE() in __dev_queue_xmit() */ + /* Pairs with READ_ONCE() in netif_tx_owned() */ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); } @@ -4738,7 +4770,7 @@ static inline bool __netif_tx_trylock(struct netdev_queue *txq) bool ok = spin_trylock(&txq->_xmit_lock); if (likely(ok)) { - /* Pairs with READ_ONCE() in __dev_queue_xmit() */ + /* Pairs with READ_ONCE() in netif_tx_owned() */ WRITE_ONCE(txq->xmit_lock_owner, smp_processor_id()); } return ok; @@ -4746,14 +4778,14 @@ static inline bool __netif_tx_trylock(struct netdev_queue *txq) static inline void __netif_tx_unlock(struct netdev_queue *txq) { - /* Pairs with READ_ONCE() in __dev_queue_xmit() */ + /* Pairs with READ_ONCE() in netif_tx_owned() */ WRITE_ONCE(txq->xmit_lock_owner, -1); spin_unlock(&txq->_xmit_lock); } static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) { - /* Pairs with READ_ONCE() in __dev_queue_xmit() */ + /* Pairs with READ_ONCE() in netif_tx_owned() */ WRITE_ONCE(txq->xmit_lock_owner, -1); spin_unlock_bh(&txq->_xmit_lock); } @@ -4846,6 +4878,23 @@ static inline void netif_tx_disable(struct net_device *dev) local_bh_enable(); } +#ifndef CONFIG_PREEMPT_RT +static inline bool netif_tx_owned(struct netdev_queue *txq, unsigned int cpu) +{ + /* Other cpus might concurrently change txq->xmit_lock_owner + * to -1 or to their cpu id, but not to our id. + */ + return READ_ONCE(txq->xmit_lock_owner) == cpu; +} + +#else +static inline bool netif_tx_owned(struct netdev_queue *txq, unsigned int cpu) +{ + return rt_mutex_owner(&txq->_xmit_lock.lock) == current; +} + +#endif + static inline void netif_addr_lock(struct net_device *dev) { unsigned char nest_level = 0; diff --git a/include/linux/netfilter/nf_conntrack_amanda.h b/include/linux/netfilter/nf_conntrack_amanda.h index 6f0ac896fcc9..dfe89f38d1f7 100644 --- a/include/linux/netfilter/nf_conntrack_amanda.h +++ b/include/linux/netfilter/nf_conntrack_amanda.h @@ -7,7 +7,7 @@ #include #include -extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb, +extern unsigned int (__rcu *nf_nat_amanda_hook)(struct sk_buff *skb, enum ip_conntrack_info ctinfo, unsigned int protoff, unsigned int matchoff, diff --git a/include/linux/netfilter/nf_conntrack_ftp.h b/include/linux/netfilter/nf_conntrack_ftp.h index 0e38302820b9..f31292642035 100644 --- a/include/linux/netfilter/nf_conntrack_ftp.h +++ b/include/linux/netfilter/nf_conntrack_ftp.h @@ -26,7 +26,7 @@ struct nf_ct_ftp_master { /* For NAT to hook in when we find a packet which describes what other * connection we should expect. */ -extern unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb, +extern unsigned int (__rcu *nf_nat_ftp_hook)(struct sk_buff *skb, enum ip_conntrack_info ctinfo, enum nf_ct_ftp_type type, unsigned int protoff, diff --git a/include/linux/netfilter/nf_conntrack_irc.h b/include/linux/netfilter/nf_conntrack_irc.h index d02255f721e1..4f3ca5621998 100644 --- a/include/linux/netfilter/nf_conntrack_irc.h +++ b/include/linux/netfilter/nf_conntrack_irc.h @@ -8,7 +8,7 @@ #define IRC_PORT 6667 -extern unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb, +extern unsigned int (__rcu *nf_nat_irc_hook)(struct sk_buff *skb, enum ip_conntrack_info ctinfo, unsigned int protoff, unsigned int matchoff, diff --git a/include/linux/netfilter/nf_conntrack_snmp.h b/include/linux/netfilter/nf_conntrack_snmp.h index 87e4f33eb55f..99107e4f5234 100644 --- a/include/linux/netfilter/nf_conntrack_snmp.h +++ b/include/linux/netfilter/nf_conntrack_snmp.h @@ -5,7 +5,7 @@ #include #include -extern int (*nf_nat_snmp_hook)(struct sk_buff *skb, +extern int (__rcu *nf_nat_snmp_hook)(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo); diff --git a/include/linux/netfilter/nf_conntrack_tftp.h b/include/linux/netfilter/nf_conntrack_tftp.h index dc4c1b9beac0..1490b68dd7d1 100644 --- a/include/linux/netfilter/nf_conntrack_tftp.h +++ b/include/linux/netfilter/nf_conntrack_tftp.h @@ -19,7 +19,7 @@ struct tftphdr { #define TFTP_OPCODE_ACK 4 #define TFTP_OPCODE_ERROR 5 -extern unsigned int (*nf_nat_tftp_hook)(struct sk_buff *skb, +extern unsigned int (__rcu *nf_nat_tftp_hook)(struct sk_buff *skb, enum ip_conntrack_info ctinfo, struct nf_conntrack_expect *exp); diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h index 825f5865bfc5..c8e227a3f9e2 100644 --- a/include/linux/ns_common.h +++ b/include/linux/ns_common.h @@ -55,6 +55,8 @@ static __always_inline bool is_ns_init_id(const struct ns_common *ns) #define ns_common_free(__ns) __ns_common_free(to_ns_common((__ns))) +bool may_see_all_namespaces(void); + static __always_inline __must_check int __ns_ref_active_read(const struct ns_common *ns) { return atomic_read(&ns->__ns_ref_active); diff --git a/include/linux/ntb.h b/include/linux/ntb.h index 191b524e5c0d..8ff9d663096b 100644 --- a/include/linux/ntb.h +++ b/include/linux/ntb.h @@ -1647,12 +1647,8 @@ int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, irq_handler_t handler, irq_handler_t thread_fn, const char *name, void *dev_id, struct ntb_msi_desc *msi_desc); -void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, void *dev_id); int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, struct ntb_msi_desc *desc); -int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, - struct ntb_msi_desc *desc, - phys_addr_t *msi_addr); #else /* not CONFIG_NTB_MSI */ @@ -1674,21 +1670,11 @@ static inline int ntbm_msi_request_threaded_irq(struct ntb_dev *ntb, { return -EOPNOTSUPP; } -static inline void ntbm_msi_free_irq(struct ntb_dev *ntb, unsigned int irq, - void *dev_id) {} static inline int ntb_msi_peer_trigger(struct ntb_dev *ntb, int peer, struct ntb_msi_desc *desc) { return -EOPNOTSUPP; } -static inline int ntb_msi_peer_addr(struct ntb_dev *ntb, int peer, - struct ntb_msi_desc *desc, - phys_addr_t *msi_addr) -{ - return -EOPNOTSUPP; - -} - #endif /* CONFIG_NTB_MSI */ static inline int ntbm_msi_request_irq(struct ntb_dev *ntb, diff --git a/include/linux/nvme-auth.h b/include/linux/nvme-auth.h index 60e069a6757f..e75c29c51464 100644 --- a/include/linux/nvme-auth.h +++ b/include/linux/nvme-auth.h @@ -11,7 +11,7 @@ struct nvme_dhchap_key { size_t len; u8 hash; - u8 key[]; + u8 key[] __counted_by(len); }; u32 nvme_auth_get_seqnum(void); diff --git a/include/linux/overflow.h b/include/linux/overflow.h index a5e95dbce220..a8cb6319b4fb 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -42,7 +42,7 @@ * both the type-agnostic benefits of the macros while also being able to * enforce that the return value is, in fact, checked. */ -static inline bool __must_check __must_check_overflow(bool overflow) +static __always_inline bool __must_check __must_check_overflow(bool overflow) { return unlikely(overflow); } @@ -327,7 +327,7 @@ static inline bool __must_check __must_check_overflow(bool overflow) * with any overflow causing the return value to be SIZE_MAX. The * lvalue must be size_t to avoid implicit type conversion. */ -static inline size_t __must_check size_mul(size_t factor1, size_t factor2) +static __always_inline size_t __must_check size_mul(size_t factor1, size_t factor2) { size_t bytes; @@ -346,7 +346,7 @@ static inline size_t __must_check size_mul(size_t factor1, size_t factor2) * with any overflow causing the return value to be SIZE_MAX. The * lvalue must be size_t to avoid implicit type conversion. */ -static inline size_t __must_check size_add(size_t addend1, size_t addend2) +static __always_inline size_t __must_check size_add(size_t addend1, size_t addend2) { size_t bytes; @@ -367,7 +367,7 @@ static inline size_t __must_check size_add(size_t addend1, size_t addend2) * argument may be SIZE_MAX (or the result with be forced to SIZE_MAX). * The lvalue must be size_t to avoid implicit type conversion. */ -static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) +static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) { size_t bytes; @@ -570,7 +570,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend) * @FAM is not annotated with __counted_by(), always returns true. */ #define overflows_flex_counter_type(TYPE, FAM, COUNT) \ - (!overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM))) + (overflows_type(COUNT, typeof_flex_counter(((TYPE *)NULL)->FAM))) /** * __set_flex_counter() - Set the counter associated with the given flexible diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 827dca25c0bc..a50df42a893f 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -22,25 +22,6 @@ #error CONFIG_PGTABLE_LEVELS is not consistent with __PAGETABLE_{P4D,PUD,PMD}_FOLDED #endif -/* - * On almost all architectures and configurations, 0 can be used as the - * upper ceiling to free_pgtables(): on many architectures it has the same - * effect as using TASK_SIZE. However, there is one configuration which - * must impose a more careful limit, to avoid freeing kernel pgtables. - */ -#ifndef USER_PGTABLES_CEILING -#define USER_PGTABLES_CEILING 0UL -#endif - -/* - * This defines the first usable user address. Platforms - * can override its value with custom FIRST_USER_ADDRESS - * defined in their respective . - */ -#ifndef FIRST_USER_ADDRESS -#define FIRST_USER_ADDRESS 0UL -#endif - /* * This defines the generic helper for accessing PMD page * table page. Although platforms can still override this @@ -1087,6 +1068,41 @@ static inline void wrprotect_ptes(struct mm_struct *mm, unsigned long addr, } #endif +#ifndef clear_flush_young_ptes +/** + * clear_flush_young_ptes - Mark PTEs that map consecutive pages of the same + * folio as old and flush the TLB. + * @vma: The virtual memory area the pages are mapped into. + * @addr: Address the first page is mapped at. + * @ptep: Page table pointer for the first entry. + * @nr: Number of entries to clear access bit. + * + * May be overridden by the architecture; otherwise, implemented as a simple + * loop over ptep_clear_flush_young(). + * + * Note that PTE bits in the PTE range besides the PFN can differ. For example, + * some PTEs might be write-protected. + * + * Context: The caller holds the page table lock. The PTEs map consecutive + * pages that belong to the same folio. The PTEs are all in the same PMD. + */ +static inline int clear_flush_young_ptes(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, unsigned int nr) +{ + int young = 0; + + for (;;) { + young |= ptep_clear_flush_young(vma, addr, ptep); + if (--nr == 0) + break; + ptep++; + addr += PAGE_SIZE; + } + + return young; +} +#endif + /* * On some architectures hardware does not set page access bit when accessing * memory page, it is responsibility of software setting this bit. It brings @@ -1629,6 +1645,25 @@ void arch_sync_kernel_mappings(unsigned long start, unsigned long end); #endif /* CONFIG_MMU */ +/* + * On almost all architectures and configurations, 0 can be used as the + * upper ceiling to free_pgtables(): on many architectures it has the same + * effect as using TASK_SIZE. However, there is one configuration which + * must impose a more careful limit, to avoid freeing kernel pgtables. + */ +#ifndef USER_PGTABLES_CEILING +#define USER_PGTABLES_CEILING 0UL +#endif + +/* + * This defines the first usable user address. Platforms + * can override its value with custom FIRST_USER_ADDRESS + * defined in their respective . + */ +#ifndef FIRST_USER_ADDRESS +#define FIRST_USER_ADDRESS 0UL +#endif + /* * No-op macros that just return the current protection value. Defined here * because these macros can be used even if CONFIG_MMU is not defined. diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h index f0ec963c6e84..d4cf4430ee8f 100644 --- a/include/linux/phy/phy-hdmi.h +++ b/include/linux/phy/phy-hdmi.h @@ -6,16 +6,31 @@ #ifndef __PHY_HDMI_H_ #define __PHY_HDMI_H_ +#include + +enum phy_hdmi_mode { + PHY_HDMI_MODE_TMDS, + PHY_HDMI_MODE_FRL, +}; + /** * struct phy_configure_opts_hdmi - HDMI configuration set - * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. * @bpc: Bits per color channel. + * @tmds_char_rate: HDMI TMDS Character Rate in Hertz. + * @frl.rate_per_lane: HDMI FRL Rate per Lane in Gbps. + * @frl.lanes: HDMI FRL lanes count. * * This structure is used to represent the configuration state of a HDMI phy. */ struct phy_configure_opts_hdmi { - unsigned long long tmds_char_rate; unsigned int bpc; + union { + unsigned long long tmds_char_rate; + struct { + u8 rate_per_lane; + u8 lanes; + } frl; + }; }; #endif /* __PHY_HDMI_H_ */ diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index 2af0d01ebb39..ea47975e288a 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -243,7 +243,7 @@ static inline void *phy_get_drvdata(struct phy *phy) #if IS_ENABLED(CONFIG_GENERIC_PHY) int phy_pm_runtime_get(struct phy *phy); int phy_pm_runtime_get_sync(struct phy *phy); -int phy_pm_runtime_put(struct phy *phy); +void phy_pm_runtime_put(struct phy *phy); int phy_pm_runtime_put_sync(struct phy *phy); int phy_init(struct phy *phy); int phy_exit(struct phy *phy); @@ -324,11 +324,8 @@ static inline int phy_pm_runtime_get_sync(struct phy *phy) return -ENOSYS; } -static inline int phy_pm_runtime_put(struct phy *phy) +static inline void phy_pm_runtime_put(struct phy *phy) { - if (!phy) - return 0; - return -ENOSYS; } static inline int phy_pm_runtime_put_sync(struct phy *phy) diff --git a/include/linux/pid.h b/include/linux/pid.h index 003a1027d219..ddaef0bbc8ba 100644 --- a/include/linux/pid.h +++ b/include/linux/pid.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -60,7 +61,7 @@ struct pid { spinlock_t lock; struct { u64 ino; - struct rb_node pidfs_node; + struct rhash_head pidfs_hash; struct dentry *stashed; struct pidfs_attr *attr; }; @@ -73,7 +74,6 @@ struct pid { struct upid numbers[]; }; -extern seqcount_spinlock_t pidmap_lock_seq; extern struct pid init_struct_pid; struct file; @@ -310,6 +310,11 @@ static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_na return pid; } +static inline pid_t task_ppid_vnr(const struct task_struct *tsk) +{ + return task_ppid_nr_ns(tsk, NULL); +} + static inline pid_t task_ppid_nr(const struct task_struct *tsk) { return task_ppid_nr_ns(tsk, &init_pid_ns); diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 0e7ae12c96d2..b20baaa7e62b 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -27,6 +27,13 @@ struct pid_namespace { struct idr idr; struct rcu_head rcu; unsigned int pid_allocated; +#ifdef CONFIG_SYSCTL +#if defined(CONFIG_MEMFD_CREATE) + int memfd_noexec_scope; +#endif + struct ctl_table_set set; + struct ctl_table_header *sysctls; +#endif struct task_struct *child_reaper; struct kmem_cache *pid_cachep; unsigned int level; @@ -40,13 +47,6 @@ struct pid_namespace { int reboot; /* group exit code if this pidns was rebooted */ struct ns_common ns; struct work_struct work; -#ifdef CONFIG_SYSCTL - struct ctl_table_set set; - struct ctl_table_header *sysctls; -#if defined(CONFIG_MEMFD_CREATE) - int memfd_noexec_scope; -#endif -#endif } __randomize_layout; extern struct pid_namespace init_pid_ns; diff --git a/include/linux/pidfs.h b/include/linux/pidfs.h index 3e08c33da2df..416bdff4d6ce 100644 --- a/include/linux/pidfs.h +++ b/include/linux/pidfs.h @@ -6,7 +6,8 @@ struct coredump_params; struct file *pidfs_alloc_file(struct pid *pid, unsigned int flags); void __init pidfs_init(void); -void pidfs_add_pid(struct pid *pid); +void pidfs_prepare_pid(struct pid *pid); +int pidfs_add_pid(struct pid *pid); void pidfs_remove_pid(struct pid *pid); void pidfs_exit(struct task_struct *tsk); #ifdef CONFIG_COREDUMP diff --git a/include/linux/pinctrl/devinfo.h b/include/linux/pinctrl/devinfo.h index bb6653af4f92..de4228eea90a 100644 --- a/include/linux/pinctrl/devinfo.h +++ b/include/linux/pinctrl/devinfo.h @@ -43,7 +43,6 @@ struct dev_pin_info { #endif }; -extern int pinctrl_bind_pins(struct device *dev); extern int pinctrl_init_done(struct device *dev); static inline struct pinctrl *dev_pinctrl(struct device *dev) @@ -58,11 +57,6 @@ static inline struct pinctrl *dev_pinctrl(struct device *dev) /* Stubs if we're not using pinctrl */ -static inline int pinctrl_bind_pins(struct device *dev) -{ - return 0; -} - static inline int pinctrl_init_done(struct device *dev) { return 0; diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 1be4032071c2..89277808ea61 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -250,9 +250,4 @@ static inline int pinconf_generic_dt_node_to_map_all(struct pinctrl_dev *pctldev return pinconf_generic_dt_node_to_map(pctldev, np_config, map, num_maps, PIN_MAP_TYPE_INVALID); } - -int pinconf_generic_dt_node_to_map_pinmux(struct pinctrl_dev *pctldev, - struct device_node *np, - struct pinctrl_map **map, - unsigned int *num_maps); #endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */ diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 1a8084e29405..c329cc693139 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -187,9 +187,6 @@ extern struct pinctrl_dev *devm_pinctrl_register(struct device *dev, const struct pinctrl_desc *pctldesc, void *driver_data); -extern void devm_pinctrl_unregister(struct device *dev, - struct pinctrl_dev *pctldev); - extern void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range); extern void pinctrl_add_gpio_ranges(struct pinctrl_dev *pctldev, diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 8080a6fc6c8c..749d985e9da2 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -2622,13 +2622,19 @@ struct ec_params_motion_sense { /* * Used for MOTIONSENSE_CMD_INFO, MOTIONSENSE_CMD_DATA - * and MOTIONSENSE_CMD_PERFORM_CALIB. */ struct __ec_todo_unpacked { uint8_t sensor_num; - } info, info_3, data, fifo_flush, perform_calib, - list_activities; + } info, info_3, data, fifo_flush, list_activities; + /* + * Used for MOTIONSENSE_CMD_PERFORM_CALIB: + * Allow entering/exiting the calibration mode. + */ + struct __ec_todo_unpacked { + uint8_t sensor_num; + uint8_t enable; + } perform_calib; /* * Used for MOTIONSENSE_CMD_EC_RATE, MOTIONSENSE_CMD_SENSOR_ODR * and MOTIONSENSE_CMD_SENSOR_RANGE. diff --git a/include/linux/platform_data/mlxreg.h b/include/linux/platform_data/mlxreg.h index f6cca7a035c7..50b6be57da66 100644 --- a/include/linux/platform_data/mlxreg.h +++ b/include/linux/platform_data/mlxreg.h @@ -13,10 +13,10 @@ /** * enum mlxreg_wdt_type - type of HW watchdog * - * TYPE1 HW watchdog implementation exist in old systems. - * All new systems have TYPE2 HW watchdog. - * TYPE3 HW watchdog can exist on all systems with new CPLD. - * TYPE3 is selected by WD capability bit. + * @MLX_WDT_TYPE1: HW watchdog implementation in old systems. + * @MLX_WDT_TYPE2: All new systems have TYPE2 HW watchdog. + * @MLX_WDT_TYPE3: HW watchdog that can exist on all systems with new CPLD. + * TYPE3 is selected by WD capability bit. */ enum mlxreg_wdt_type { MLX_WDT_TYPE1, @@ -35,7 +35,7 @@ enum mlxreg_wdt_type { * @MLXREG_HOTPLUG_LC_SYNCED: entry for line card synchronization events, coming * after hardware-firmware synchronization handshake; * @MLXREG_HOTPLUG_LC_READY: entry for line card ready events, indicating line card - PHYs ready / unready state; + * PHYs ready / unready state; * @MLXREG_HOTPLUG_LC_ACTIVE: entry for line card active events, indicating firmware * availability / unavailability for the ports on line card; * @MLXREG_HOTPLUG_LC_THERMAL: entry for line card thermal shutdown events, positive @@ -123,8 +123,8 @@ struct mlxreg_hotplug_device { * @reg_pwr: attribute power register; * @reg_ena: attribute enable register; * @mode: access mode; - * @np - pointer to node platform associated with attribute; - * @hpdev - hotplug device data; + * @np: pointer to node platform associated with attribute; + * @hpdev: hotplug device data; * @notifier: pointer to event notifier block; * @health_cntr: dynamic device health indication counter; * @attached: true if device has been attached after good health indication; diff --git a/arch/mips/include/asm/mach-pic32/pic32.h b/include/linux/platform_data/pic32.h similarity index 70% rename from arch/mips/include/asm/mach-pic32/pic32.h rename to include/linux/platform_data/pic32.h index 53918a671a4c..f0b395fdb784 100644 --- a/arch/mips/include/asm/mach-pic32/pic32.h +++ b/include/linux/platform_data/pic32.h @@ -3,10 +3,10 @@ * Joshua Henderson * Copyright (C) 2015 Microchip Technology Inc. All rights reserved. */ -#ifndef _ASM_MACH_PIC32_H -#define _ASM_MACH_PIC32_H +#ifndef __LINUX_PLATFORM_DATA_PIC32_H +#define __LINUX_PLATFORM_DATA_PIC32_H -#include +#include /* * PIC32 register offsets for SET/CLR/INV where supported. @@ -26,11 +26,14 @@ #define PIC32_BASE_PORT 0x1f860000 #define PIC32_BASE_DEVCFG2 0x1fc4ff44 -/* - * Register unlock sequence required for some register access. - */ +#if defined(CONFIG_MACH_PIC32) +/* Register unlock sequence required for some register access. */ void pic32_syskey_unlock_debug(const char *fn, const ulong ln); #define pic32_syskey_unlock() \ pic32_syskey_unlock_debug(__func__, __LINE__) +#else +/* COMPILE_TEST on all other architectures */ +#define pic32_syskey_unlock() +#endif -#endif /* _ASM_MACH_PIC32_H */ +#endif /* __LINUX_PLATFORM_DATA_PIC32_H */ diff --git a/include/linux/platform_data/x86/int3472.h b/include/linux/platform_data/x86/int3472.h index b1b837583d54..dbe745dc88d5 100644 --- a/include/linux/platform_data/x86/int3472.h +++ b/include/linux/platform_data/x86/int3472.h @@ -26,6 +26,7 @@ #define INT3472_GPIO_TYPE_POWER_ENABLE 0x0b #define INT3472_GPIO_TYPE_CLK_ENABLE 0x0c #define INT3472_GPIO_TYPE_PRIVACY_LED 0x0d +#define INT3472_GPIO_TYPE_DOVDD 0x10 #define INT3472_GPIO_TYPE_HANDSHAKE 0x12 #define INT3472_GPIO_TYPE_HOTPLUG_DETECT 0x13 @@ -33,8 +34,8 @@ #define INT3472_MAX_SENSOR_GPIOS 3 #define INT3472_MAX_REGULATORS 3 -/* E.g. "avdd\0" */ -#define GPIO_SUPPLY_NAME_LENGTH 5 +/* E.g. "dovdd\0" */ +#define GPIO_SUPPLY_NAME_LENGTH 6 /* 12 chars for acpi_dev_name() + "-", e.g. "ABCD1234:00-" */ #define GPIO_REGULATOR_NAME_LENGTH (12 + GPIO_SUPPLY_NAME_LENGTH) /* lower- and upper-case mapping */ diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 41037c513f06..64921b10ac74 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -545,22 +545,10 @@ static inline int pm_runtime_resume_and_get(struct device *dev) * * Decrement the runtime PM usage counter of @dev and if it turns out to be * equal to 0, queue up a work item for @dev like in pm_request_idle(). - * - * Return: - * * 1: Success. Usage counter dropped to zero, but device was already suspended. - * * 0: Success. - * * -EINVAL: Runtime PM error. - * * -EACCES: Runtime PM disabled. - * * -EAGAIN: Runtime PM usage counter became non-zero or Runtime PM status - * change ongoing. - * * -EBUSY: Runtime PM child_count non-zero. - * * -EPERM: Device PM QoS resume latency 0. - * * -EINPROGRESS: Suspend already in progress. - * * -ENOSYS: CONFIG_PM not enabled. */ -static inline int pm_runtime_put(struct device *dev) +static inline void pm_runtime_put(struct device *dev) { - return __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC); + __pm_runtime_idle(dev, RPM_GET_PUT | RPM_ASYNC); } /** diff --git a/include/linux/printk.h b/include/linux/printk.h index 45c663124c9b..63d516c873b4 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -78,7 +78,6 @@ extern void console_verbose(void); /* strlen("ratelimit") + 1 */ #define DEVKMSG_STR_MAX_SIZE 10 extern char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE]; -struct ctl_table; extern int suppress_printk; diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 7729fef249e1..04f3f86a4145 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -1074,8 +1074,8 @@ static inline void rcu_read_unlock_migrate(void) * either fall back to use of call_rcu() or rearrange the structure to * position the rcu_head structure into the first 4096 bytes. * - * The object to be freed can be allocated either by kmalloc() or - * kmem_cache_alloc(). + * The object to be freed can be allocated either by kmalloc(), + * kmalloc_nolock(), or kmem_cache_alloc(). * * Note that the allowable offset might decrease in the future. * diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 876358cfe1b1..d862fa610270 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -248,6 +248,7 @@ int trace_rb_cpu_prepare(unsigned int cpu, struct hlist_node *node); int ring_buffer_map(struct trace_buffer *buffer, int cpu, struct vm_area_struct *vma); +void ring_buffer_map_dup(struct trace_buffer *buffer, int cpu); int ring_buffer_unmap(struct trace_buffer *buffer, int cpu); int ring_buffer_map_get_reader(struct trace_buffer *buffer, int cpu); #endif /* _LINUX_RING_BUFFER_H */ diff --git a/include/linux/rseq.h b/include/linux/rseq.h index 7a01a0760405..b9d62fc2140d 100644 --- a/include/linux/rseq.h +++ b/include/linux/rseq.h @@ -146,6 +146,18 @@ static inline void rseq_fork(struct task_struct *t, u64 clone_flags) t->rseq = current->rseq; } +/* + * Value returned by getauxval(AT_RSEQ_ALIGN) and expected by rseq + * registration. This is the active rseq area size rounded up to next + * power of 2, which guarantees that the rseq structure will always be + * aligned on the nearest power of two large enough to contain it, even + * as it grows. + */ +static inline unsigned int rseq_alloc_align(void) +{ + return 1U << get_count_order(offsetof(struct rseq, end)); +} + #else /* CONFIG_RSEQ */ static inline void rseq_handle_slowpath(struct pt_regs *regs) { } static inline void rseq_signal_deliver(struct ksignal *ksig, struct pt_regs *regs) { } diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h index cbc4a791618b..c6831c93cd6e 100644 --- a/include/linux/rseq_entry.h +++ b/include/linux/rseq_entry.h @@ -216,10 +216,10 @@ static __always_inline bool rseq_grant_slice_extension(bool work_pending) } #else /* CONFIG_RSEQ_SLICE_EXTENSION */ -static inline bool rseq_slice_extension_enabled(void) { return false; } -static inline bool rseq_arm_slice_extension_timer(void) { return false; } -static inline void rseq_slice_clear_grant(struct task_struct *t) { } -static inline bool rseq_grant_slice_extension(bool work_pending) { return false; } +static __always_inline bool rseq_slice_extension_enabled(void) { return false; } +static __always_inline bool rseq_arm_slice_extension_timer(void) { return false; } +static __always_inline void rseq_slice_clear_grant(struct task_struct *t) { } +static __always_inline bool rseq_grant_slice_extension(bool work_pending) { return false; } #endif /* !CONFIG_RSEQ_SLICE_EXTENSION */ bool rseq_debug_update_user_cs(struct task_struct *t, struct pt_regs *regs, unsigned long csaddr); diff --git a/include/linux/rseq_types.h b/include/linux/rseq_types.h index da5fa6f40294..0b42045988db 100644 --- a/include/linux/rseq_types.h +++ b/include/linux/rseq_types.h @@ -133,10 +133,12 @@ struct rseq_data { }; * @active: MM CID is active for the task * @cid: The CID associated to the task either permanently or * borrowed from the CPU + * @node: Queued in the per MM MMCID list */ struct sched_mm_cid { unsigned int active; unsigned int cid; + struct hlist_node node; }; /** @@ -157,6 +159,7 @@ struct mm_cid_pcpu { * @work: Regular work to handle the affinity mode change case * @lock: Spinlock to protect against affinity setting which can't take @mutex * @mutex: Mutex to serialize forks and exits related to this mm + * @user_list: List of the MM CID users of a MM * @nr_cpus_allowed: The number of CPUs in the per MM allowed CPUs map. The map * is growth only. * @users: The number of tasks sharing this MM. Separate from mm::mm_users @@ -177,13 +180,14 @@ struct mm_mm_cid { raw_spinlock_t lock; struct mutex mutex; + struct hlist_head user_list; /* Low frequency modified */ unsigned int nr_cpus_allowed; unsigned int users; unsigned int pcpu_thrs; unsigned int update_deferred; -}____cacheline_aligned_in_smp; +} ____cacheline_aligned; #else /* CONFIG_SCHED_MM_CID */ struct mm_mm_cid { }; struct sched_mm_cid { }; diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 29f6ceb98d74..6de1a2434299 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -441,6 +441,8 @@ static inline void sg_init_marker(struct scatterlist *sgl, int sg_nents(struct scatterlist *sg); int sg_nents_for_len(struct scatterlist *sg, u64 len); +int sg_nents_for_dma(struct scatterlist *sgl, unsigned int sglen, size_t len); + struct scatterlist *sg_last(struct scatterlist *s, unsigned int); void sg_init_table(struct scatterlist *, unsigned int); void sg_init_one(struct scatterlist *, const void *, unsigned int); diff --git a/include/linux/sched.h b/include/linux/sched.h index 074ad4ef3d81..5a5d3dbc9cdf 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -579,6 +579,7 @@ struct sched_entity { u64 deadline; u64 min_vruntime; u64 min_slice; + u64 max_slice; struct list_head group_node; unsigned char on_rq; @@ -2353,7 +2354,6 @@ static __always_inline void alloc_tag_restore(struct alloc_tag *tag, struct allo #ifdef CONFIG_SCHED_MM_CID void sched_mm_cid_before_execve(struct task_struct *t); void sched_mm_cid_after_execve(struct task_struct *t); -void sched_mm_cid_fork(struct task_struct *t); void sched_mm_cid_exit(struct task_struct *t); static __always_inline int task_mm_cid(struct task_struct *t) { @@ -2362,7 +2362,6 @@ static __always_inline int task_mm_cid(struct task_struct *t) #else static inline void sched_mm_cid_before_execve(struct task_struct *t) { } static inline void sched_mm_cid_after_execve(struct task_struct *t) { } -static inline void sched_mm_cid_fork(struct task_struct *t) { } static inline void sched_mm_cid_exit(struct task_struct *t) { } static __always_inline int task_mm_cid(struct task_struct *t) { diff --git a/include/linux/serdev.h b/include/linux/serdev.h index 34562eb99931..5654c58eb73c 100644 --- a/include/linux/serdev.h +++ b/include/linux/serdev.h @@ -65,6 +65,7 @@ struct serdev_device_driver { struct device_driver driver; int (*probe)(struct serdev_device *); void (*remove)(struct serdev_device *); + void (*shutdown)(struct serdev_device *); }; static inline struct serdev_device_driver *to_serdev_device_driver(struct device_driver *d) diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index 03ba4dab2ef7..b6827c06d332 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h @@ -19,11 +19,11 @@ #include /** - * shdma_pm_state - DMA channel PM state - * SHDMA_PM_ESTABLISHED: either idle or during data transfer - * SHDMA_PM_BUSY: during the transfer preparation, when we have to + * enum shdma_pm_state - DMA channel PM state + * @SHDMA_PM_ESTABLISHED: either idle or during data transfer + * @SHDMA_PM_BUSY: during the transfer preparation, when we have to * drop the lock temporarily - * SHDMA_PM_PENDING: transfers pending + * @SHDMA_PM_PENDING: transfers pending */ enum shdma_pm_state { SHDMA_PM_ESTABLISHED, @@ -74,18 +74,18 @@ struct shdma_chan { /** * struct shdma_ops - simple DMA driver operations - * desc_completed: return true, if this is the descriptor, that just has + * @desc_completed: return true, if this is the descriptor, that just has * completed (atomic) - * halt_channel: stop DMA channel operation (atomic) - * channel_busy: return true, if the channel is busy (atomic) - * slave_addr: return slave DMA address - * desc_setup: set up the hardware specific descriptor portion (atomic) - * set_slave: bind channel to a slave - * setup_xfer: configure channel hardware for operation (atomic) - * start_xfer: start the DMA transfer (atomic) - * embedded_desc: return Nth struct shdma_desc pointer from the + * @halt_channel: stop DMA channel operation (atomic) + * @channel_busy: return true, if the channel is busy (atomic) + * @slave_addr: return slave DMA address + * @desc_setup: set up the hardware specific descriptor portion (atomic) + * @set_slave: bind channel to a slave + * @setup_xfer: configure channel hardware for operation (atomic) + * @start_xfer: start the DMA transfer (atomic) + * @embedded_desc: return Nth struct shdma_desc pointer from the * descriptor array - * chan_irq: process channel IRQ, return true if a transfer has + * @chan_irq: process channel IRQ, return true if a transfer has * completed (atomic) */ struct shdma_ops { diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index e2069b3179c4..a8273b32e041 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -102,12 +102,10 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) extern const struct fs_parameter_spec shmem_fs_parameters[]; extern void shmem_init(void); extern int shmem_init_fs_context(struct fs_context *fc); -extern struct file *shmem_file_setup(const char *name, - loff_t size, unsigned long flags); -extern struct file *shmem_kernel_file_setup(const char *name, loff_t size, - unsigned long flags); +struct file *shmem_file_setup(const char *name, loff_t size, vma_flags_t flags); +struct file *shmem_kernel_file_setup(const char *name, loff_t size, vma_flags_t vma_flags); extern struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt, - const char *name, loff_t size, unsigned long flags); + const char *name, loff_t size, vma_flags_t flags); int shmem_zero_setup(struct vm_area_struct *vma); int shmem_zero_setup_desc(struct vm_area_desc *desc); extern unsigned long shmem_get_unmapped_area(struct file *, unsigned long addr, diff --git a/include/linux/skmsg.h b/include/linux/skmsg.h index 829b281d6c9c..19f4f253b4f9 100644 --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -460,8 +460,7 @@ int sk_psock_msg_verdict(struct sock *sk, struct sk_psock *psock, * intentional to enforce typesafety. */ #define sk_psock_init_link() \ - ((struct sk_psock_link *)kzalloc(sizeof(struct sk_psock_link), \ - GFP_ATOMIC | __GFP_NOWARN)) + kzalloc_obj(struct sk_psock_link, GFP_ATOMIC | __GFP_NOWARN) static inline void sk_psock_free_link(struct sk_psock_link *link) { diff --git a/include/linux/slab.h b/include/linux/slab.h index c5fde8740281..15a60b501b95 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -517,18 +517,6 @@ void kfree_sensitive(const void *objp); DEFINE_FREE(kfree, void *, if (!IS_ERR_OR_NULL(_T)) kfree(_T)) DEFINE_FREE(kfree_sensitive, void *, if (_T) kfree_sensitive(_T)) -/** - * ksize - Report actual allocation size of associated object - * - * @objp: Pointer returned from a prior kmalloc()-family allocation. - * - * This should not be used for writing beyond the originally requested - * allocation size. Either use krealloc() or round up the allocation size - * with kmalloc_size_roundup() prior to allocation. If this is used to - * access beyond the originally requested allocation size, UBSAN_BOUNDS - * and/or FORTIFY_SOURCE may trip, since they only know about the - * originally allocated size via the __alloc_size attribute. - */ size_t ksize(const void *objp); #ifdef CONFIG_PRINTK @@ -1003,11 +991,7 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); ({ \ const size_t __count = (COUNT); \ const size_t __obj_size = struct_size_t(TYPE, FAM, __count); \ - TYPE *__obj_ptr; \ - if (WARN_ON_ONCE(overflows_flex_counter_type(TYPE, FAM, __count))) \ - __obj_ptr = NULL; \ - else \ - __obj_ptr = KMALLOC(__obj_size, GFP); \ + TYPE *__obj_ptr = KMALLOC(__obj_size, GFP); \ if (__obj_ptr) \ __set_flex_counter(__obj_ptr->FAM, __count); \ __obj_ptr; \ @@ -1021,8 +1005,8 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL * on failure. */ -#define kmalloc_obj(VAR_OR_TYPE, GFP) \ - __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), 1) +#define kmalloc_obj(VAR_OR_TYPE, ...) \ + __alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), 1) /** * kmalloc_objs - Allocate an array of the given type @@ -1033,8 +1017,8 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success, * or NULL on failure. */ -#define kmalloc_objs(VAR_OR_TYPE, COUNT, GFP) \ - __alloc_objs(kmalloc, GFP, typeof(VAR_OR_TYPE), COUNT) +#define kmalloc_objs(VAR_OR_TYPE, COUNT, ...) \ + __alloc_objs(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), COUNT) /** * kmalloc_flex - Allocate a single instance of the given flexible structure @@ -1048,32 +1032,32 @@ void *kmalloc_nolock_noprof(size_t size, gfp_t gfp_flags, int node); * will immediately fail if @COUNT is larger than what the type of the * struct's counter variable can represent. */ -#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, GFP) \ - __alloc_flex(kmalloc, GFP, typeof(VAR_OR_TYPE), FAM, COUNT) +#define kmalloc_flex(VAR_OR_TYPE, FAM, COUNT, ...) \ + __alloc_flex(kmalloc, default_gfp(__VA_ARGS__), typeof(VAR_OR_TYPE), FAM, COUNT) /* All kzalloc aliases for kmalloc_(obj|objs|flex). */ -#define kzalloc_obj(P, GFP) \ - __alloc_objs(kzalloc, GFP, typeof(P), 1) -#define kzalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kzalloc, GFP, typeof(P), COUNT) -#define kzalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kzalloc, GFP, typeof(P), FAM, COUNT) +#define kzalloc_obj(P, ...) \ + __alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kzalloc_objs(P, COUNT, ...) \ + __alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kzalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kzalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) /* All kvmalloc aliases for kmalloc_(obj|objs|flex). */ -#define kvmalloc_obj(P, GFP) \ - __alloc_objs(kvmalloc, GFP, typeof(P), 1) -#define kvmalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kvmalloc, GFP, typeof(P), COUNT) -#define kvmalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kvmalloc, GFP, typeof(P), FAM, COUNT) +#define kvmalloc_obj(P, ...) \ + __alloc_objs(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kvmalloc_objs(P, COUNT, ...) \ + __alloc_objs(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kvmalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kvmalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) /* All kvzalloc aliases for kmalloc_(obj|objs|flex). */ -#define kvzalloc_obj(P, GFP) \ - __alloc_objs(kvzalloc, GFP, typeof(P), 1) -#define kvzalloc_objs(P, COUNT, GFP) \ - __alloc_objs(kvzalloc, GFP, typeof(P), COUNT) -#define kvzalloc_flex(P, FAM, COUNT, GFP) \ - __alloc_flex(kvzalloc, GFP, typeof(P), FAM, COUNT) +#define kvzalloc_obj(P, ...) \ + __alloc_objs(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), 1) +#define kvzalloc_objs(P, COUNT, ...) \ + __alloc_objs(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), COUNT) +#define kvzalloc_flex(P, FAM, COUNT, ...) \ + __alloc_flex(kvzalloc, default_gfp(__VA_ARGS__), typeof(P), FAM, COUNT) #define kmem_buckets_alloc(_b, _size, _flags) \ alloc_hooks(__kmalloc_node_noprof(PASS_BUCKET_PARAMS(_size, _b), _flags, NUMA_NO_NODE)) diff --git a/include/linux/soc/apple/tunable.h b/include/linux/soc/apple/tunable.h new file mode 100644 index 000000000000..531ca814cd02 --- /dev/null +++ b/include/linux/soc/apple/tunable.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */ +/* + * Apple Silicon hardware tunable support + * + * Each tunable is a list with each entry containing a offset into the MMIO + * region, a mask of bits to be cleared and a set of bits to be set. These + * tunables are passed along by the previous boot stages and vary from device + * to device such that they cannot be hardcoded in the individual drivers. + * + * Copyright (C) The Asahi Linux Contributors + */ + +#ifndef _LINUX_SOC_APPLE_TUNABLE_H_ +#define _LINUX_SOC_APPLE_TUNABLE_H_ + +#include +#include + +/** + * Struct to store an Apple Silicon hardware tunable. + * + * Each tunable is a list with each entry containing a offset into the MMIO + * region, a mask of bits to be cleared and a set of bits to be set. These + * tunables are passed along by the previous boot stages and vary from device + * to device such that they cannot be hardcoded in the individual drivers. + * + * @param sz Number of [offset, mask, value] tuples stored in values. + * @param values [offset, mask, value] array. + */ +struct apple_tunable { + size_t sz; + struct { + u32 offset; + u32 mask; + u32 value; + } values[] __counted_by(sz); +}; + +/** + * Parse an array of hardware tunables from the device tree. + * + * @dev: Device node used for devm_kzalloc internally. + * @np: Device node which contains the tunable array. + * @name: Name of the device tree property which contains the tunables. + * @res: Resource to which the tunables will be applied, used for bound checking + * + * @return: devres allocated struct on success or PTR_ERR on failure. + */ +struct apple_tunable *devm_apple_tunable_parse(struct device *dev, + struct device_node *np, + const char *name, + struct resource *res); + +/** + * Apply a previously loaded hardware tunable. + * + * @param regs: MMIO to which the tunable will be applied. + * @param tunable: Pointer to the tunable. + */ +void apple_tunable_apply(void __iomem *regs, struct apple_tunable *tunable); + +#endif diff --git a/include/linux/soc/samsung/exynos-regs-pmu.h b/include/linux/soc/samsung/exynos-regs-pmu.h index 532c6c2d1195..db8a7ca81080 100644 --- a/include/linux/soc/samsung/exynos-regs-pmu.h +++ b/include/linux/soc/samsung/exynos-regs-pmu.h @@ -1015,4 +1015,7 @@ #define GS101_GRP2_INTR_BID_UPEND (0x0208) #define GS101_GRP2_INTR_BID_CLEAR (0x020c) +/* exynosautov920 */ +#define EXYNOSAUTOV920_PHY_CTRL_USB20 (0x0710) +#define EXYNOSAUTOV920_PHY_CTRL_USB31 (0x0714) #endif /* __LINUX_SOC_EXYNOS_REGS_PMU_H */ diff --git a/include/linux/soundwire/sdw.h b/include/linux/soundwire/sdw.h index e6a3476bcef1..f462717acf20 100644 --- a/include/linux/soundwire/sdw.h +++ b/include/linux/soundwire/sdw.h @@ -705,7 +705,7 @@ struct sdw_master_device { struct sdw_driver { int (*probe)(struct sdw_slave *sdw, const struct sdw_device_id *id); - int (*remove)(struct sdw_slave *sdw); + void (*remove)(struct sdw_slave *sdw); void (*shutdown)(struct sdw_slave *sdw); const struct sdw_device_id *id_table; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index fd8dce4169f7..af7cfee7b8f6 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -1309,7 +1309,7 @@ static inline struct spi_message *spi_message_alloc(unsigned ntrans, gfp_t flags } *mwt; unsigned i; - mwt = kzalloc(struct_size(mwt, t, ntrans), flags); + mwt = kzalloc_flex(*mwt, t, ntrans, flags); if (!mwt) return NULL; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 288fe0055cd5..2886fbceb5d6 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -59,7 +59,6 @@ extern const int sysctl_vals[]; #define SYSCTL_LONG_ONE ((void *)&sysctl_long_vals[1]) #define SYSCTL_LONG_MAX ((void *)&sysctl_long_vals[2]) -#define SYSCTL_CONV_IDENTITY(val) (val) /** * * "dir" originates from read_iter (dir = 0) or write_iter (dir = 1) @@ -73,107 +72,6 @@ extern const int sysctl_vals[]; #define SYSCTL_USER_TO_KERN(dir) (!!(dir)) #define SYSCTL_KERN_TO_USER(dir) (!dir) -#define SYSCTL_USER_TO_KERN_INT_CONV(name, u_ptr_op) \ -int sysctl_user_to_kern_int_conv##name(const bool *negp, \ - const unsigned long *u_ptr,\ - int *k_ptr) \ -{ \ - unsigned long u = u_ptr_op(*u_ptr); \ - if (*negp) { \ - if (u > (unsigned long) INT_MAX + 1) \ - return -EINVAL; \ - WRITE_ONCE(*k_ptr, -u); \ - } else { \ - if (u > (unsigned long) INT_MAX) \ - return -EINVAL; \ - WRITE_ONCE(*k_ptr, u); \ - } \ - return 0; \ -} - -#define SYSCTL_KERN_TO_USER_INT_CONV(name, k_ptr_op) \ -int sysctl_kern_to_user_int_conv##name(bool *negp, \ - unsigned long *u_ptr, \ - const int *k_ptr) \ -{ \ - int val = READ_ONCE(*k_ptr); \ - if (val < 0) { \ - *negp = true; \ - *u_ptr = -k_ptr_op((unsigned long)val); \ - } else { \ - *negp = false; \ - *u_ptr = k_ptr_op((unsigned long)val); \ - } \ - return 0; \ -} - -/** - * To range check on a converted value, use a temp k_ptr - * When checking range, value should be within (tbl->extra1, tbl->extra2) - */ -#define SYSCTL_INT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ - k_ptr_range_check) \ -int do_proc_int_conv##name(bool *negp, unsigned long *u_ptr, int *k_ptr,\ - int dir, const struct ctl_table *tbl) \ -{ \ - if (SYSCTL_KERN_TO_USER(dir)) \ - return kern_to_user(negp, u_ptr, k_ptr); \ - \ - if (k_ptr_range_check) { \ - int tmp_k, ret; \ - if (!tbl) \ - return -EINVAL; \ - ret = user_to_kern(negp, u_ptr, &tmp_k); \ - if (ret) \ - return ret; \ - if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || \ - (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) \ - return -EINVAL; \ - WRITE_ONCE(*k_ptr, tmp_k); \ - } else \ - return user_to_kern(negp, u_ptr, k_ptr); \ - return 0; \ -} - -#define SYSCTL_USER_TO_KERN_UINT_CONV(name, u_ptr_op) \ -int sysctl_user_to_kern_uint_conv##name(const unsigned long *u_ptr,\ - unsigned int *k_ptr) \ -{ \ - unsigned long u = u_ptr_op(*u_ptr); \ - if (u > UINT_MAX) \ - return -EINVAL; \ - WRITE_ONCE(*k_ptr, u); \ - return 0; \ -} - -#define SYSCTL_UINT_CONV_CUSTOM(name, user_to_kern, kern_to_user, \ - k_ptr_range_check) \ -int do_proc_uint_conv##name(unsigned long *u_ptr, unsigned int *k_ptr, \ - int dir, const struct ctl_table *tbl) \ -{ \ - if (SYSCTL_KERN_TO_USER(dir)) \ - return kern_to_user(u_ptr, k_ptr); \ - \ - if (k_ptr_range_check) { \ - unsigned int tmp_k; \ - int ret; \ - if (!tbl) \ - return -EINVAL; \ - ret = user_to_kern(u_ptr, &tmp_k); \ - if (ret) \ - return ret; \ - if ((tbl->extra1 && \ - *(unsigned int *)tbl->extra1 > tmp_k) || \ - (tbl->extra2 && \ - *(unsigned int *)tbl->extra2 < tmp_k)) \ - return -ERANGE; \ - WRITE_ONCE(*k_ptr, tmp_k); \ - } else \ - return user_to_kern(u_ptr, k_ptr); \ - return 0; \ -} - - extern const unsigned long sysctl_long_vals[]; typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer, @@ -182,6 +80,7 @@ typedef int proc_handler(const struct ctl_table *ctl, int write, void *buffer, int proc_dostring(const struct ctl_table *, int, void *, size_t *, loff_t *); int proc_dobool(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); + int proc_dointvec(const struct ctl_table *, int, void *, size_t *, loff_t *); int proc_dointvec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos); @@ -189,6 +88,15 @@ int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, int dir, const struct ctl_table *table)); +int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, + ulong (*k_ptr_op)(const ulong)); +int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, + ulong (*u_ptr_op)(const ulong)); +int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), + int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)); + int proc_douintvec(const struct ctl_table *, int, void *, size_t *, loff_t *); int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); @@ -196,6 +104,13 @@ int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *lvalp, unsigned int *valp, int write, const struct ctl_table *table)); +int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr); +int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, + ulong (*u_ptr_op)(const ulong)); +int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr), + int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr)); int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); @@ -206,7 +121,6 @@ int proc_doulongvec_minmax_conv(const struct ctl_table *table, int dir, int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t *); int proc_do_static_key(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); -int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, const unsigned int *k_ptr); /* * Register a set of sysctl names by calling register_sysctl diff --git a/include/linux/tnum.h b/include/linux/tnum.h index fa4654ffb621..ca2cfec8de08 100644 --- a/include/linux/tnum.h +++ b/include/linux/tnum.h @@ -131,4 +131,7 @@ static inline bool tnum_subreg_is_const(struct tnum a) return !(tnum_subreg(a)).mask; } +/* Returns the smallest member of t larger than z */ +u64 tnum_step(struct tnum t, u64 z); + #endif /* _LINUX_TNUM_H */ diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index 3690221ba3d8..37eb2f0f3dd8 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -38,7 +38,10 @@ const char *trace_print_symbols_seq_u64(struct trace_seq *p, *symbol_array); #endif -const char *trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, +struct trace_iterator; +struct trace_event; + +const char *trace_print_bitmask_seq(struct trace_iterator *iter, void *bitmask_ptr, unsigned int bitmask_size); const char *trace_print_hex_seq(struct trace_seq *p, @@ -54,9 +57,6 @@ trace_print_hex_dump_seq(struct trace_seq *p, const char *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii); -struct trace_iterator; -struct trace_event; - int trace_raw_output_prep(struct trace_iterator *iter, struct trace_event *event); extern __printf(2, 3) @@ -683,6 +683,11 @@ static inline void hist_poll_wakeup(void) #define hist_poll_wait(file, wait) \ poll_wait(file, &hist_poll_wq, wait) + +#else +static inline void hist_poll_wakeup(void) +{ +} #endif #define __TRACE_EVENT_FLAGS(name, value) \ diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 4a0b8c172d27..697d619aafdc 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -114,7 +114,11 @@ extern void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, extern int trace_seq_path(struct trace_seq *s, const struct path *path); extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, - int nmaskbits); + int nmaskbits); + +extern void trace_seq_bitmask_list(struct trace_seq *s, + const unsigned long *maskp, + int nmaskbits); extern int trace_seq_hex_dump(struct trace_seq *s, const char *prefix_str, int prefix_type, int rowsize, int groupsize, @@ -137,6 +141,12 @@ trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, { } +static inline void +trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp, + int nmaskbits) +{ +} + static inline int trace_print_seq(struct seq_file *m, struct trace_seq *s) { return 0; diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 8a56f3278b1b..22ca1c8b54f3 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -108,14 +108,15 @@ void for_each_tracepoint_in_module(struct module *mod, * An alternative is to use the following for batch reclaim associated * with a given tracepoint: * - * - tracepoint_is_faultable() == false: call_rcu() + * - tracepoint_is_faultable() == false: call_srcu() * - tracepoint_is_faultable() == true: call_rcu_tasks_trace() */ #ifdef CONFIG_TRACEPOINTS +extern struct srcu_struct tracepoint_srcu; static inline void tracepoint_synchronize_unregister(void) { synchronize_rcu_tasks_trace(); - synchronize_rcu(); + synchronize_srcu(&tracepoint_srcu); } static inline bool tracepoint_is_faultable(struct tracepoint *tp) { @@ -275,13 +276,13 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p) return static_branch_unlikely(&__tracepoint_##name.key);\ } -#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ +#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \ __DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), PARAMS(data_proto)) \ static inline void __do_trace_##name(proto) \ { \ TRACEPOINT_CHECK(name) \ if (cond) { \ - guard(preempt_notrace)(); \ + guard(srcu_fast_notrace)(&tracepoint_srcu); \ __DO_TRACE_CALL(name, TP_ARGS(args)); \ } \ } \ diff --git a/include/linux/tsm.h b/include/linux/tsm.h index 22e05b2aac69..381c53244c83 100644 --- a/include/linux/tsm.h +++ b/include/linux/tsm.h @@ -8,7 +8,7 @@ #include #define TSM_REPORT_INBLOB_MAX 64 -#define TSM_REPORT_OUTBLOB_MAX SZ_32K +#define TSM_REPORT_OUTBLOB_MAX SZ_16M /* * Privilege level is a nested permission concept to allow confidential diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 1f3804245c06..4fe63169d5a2 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -647,36 +647,22 @@ static inline void user_access_restore(unsigned long flags) { } /* Define RW variant so the below _mode macro expansion works */ #define masked_user_rw_access_begin(u) masked_user_access_begin(u) #define user_rw_access_begin(u, s) user_access_begin(u, s) -#define user_rw_access_end() user_access_end() /* Scoped user access */ -#define USER_ACCESS_GUARD(_mode) \ -static __always_inline void __user * \ -class_user_##_mode##_begin(void __user *ptr) \ -{ \ - return ptr; \ -} \ - \ -static __always_inline void \ -class_user_##_mode##_end(void __user *ptr) \ -{ \ - user_##_mode##_access_end(); \ -} \ - \ -DEFINE_CLASS(user_ ##_mode## _access, void __user *, \ - class_user_##_mode##_end(_T), \ - class_user_##_mode##_begin(ptr), void __user *ptr) \ - \ -static __always_inline class_user_##_mode##_access_t \ -class_user_##_mode##_access_ptr(void __user *scope) \ -{ \ - return scope; \ -} -USER_ACCESS_GUARD(read) -USER_ACCESS_GUARD(write) -USER_ACCESS_GUARD(rw) -#undef USER_ACCESS_GUARD +/* Cleanup wrapper functions */ +static __always_inline void __scoped_user_read_access_end(const void *p) +{ + user_read_access_end(); +}; +static __always_inline void __scoped_user_write_access_end(const void *p) +{ + user_write_access_end(); +}; +static __always_inline void __scoped_user_rw_access_end(const void *p) +{ + user_access_end(); +}; /** * __scoped_user_access_begin - Start a scoped user access @@ -750,13 +736,13 @@ USER_ACCESS_GUARD(rw) * * Don't use directly. Use scoped_masked_user_$MODE_access() instead. */ -#define __scoped_user_access(mode, uptr, size, elbl) \ -for (bool done = false; !done; done = true) \ - for (void __user *_tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \ - !done; done = true) \ - for (CLASS(user_##mode##_access, scope)(_tmpptr); !done; done = true) \ - /* Force modified pointer usage within the scope */ \ - for (const typeof(uptr) uptr = _tmpptr; !done; done = true) +#define __scoped_user_access(mode, uptr, size, elbl) \ +for (bool done = false; !done; done = true) \ + for (auto _tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \ + !done; done = true) \ + /* Force modified pointer usage within the scope */ \ + for (const auto uptr __cleanup(__scoped_user_##mode##_access_end) = \ + _tmpptr; !done; done = true) /** * scoped_user_read_access_size - Start a scoped user read access with given size @@ -806,7 +792,7 @@ for (bool done = false; !done; done = true) \ /** * scoped_user_rw_access_size - Start a scoped user read/write access with given size - * @uptr Pointer to the user space address to read from and write to + * @uptr: Pointer to the user space address to read from and write to * @size: Size of the access starting from @uptr * @elbl: Error label to goto when the access region is rejected * @@ -817,7 +803,7 @@ for (bool done = false; !done; done = true) \ /** * scoped_user_rw_access - Start a scoped user read/write access - * @uptr Pointer to the user space address to read from and write to + * @uptr: Pointer to the user space address to read from and write to * @elbl: Error label to goto when the access region is rejected * * The size of the access starting from @uptr is determined via sizeof(*@uptr)). diff --git a/include/linux/units.h b/include/linux/units.h index 00e15de33eca..80d57c50b9e3 100644 --- a/include/linux/units.h +++ b/include/linux/units.h @@ -21,13 +21,35 @@ #define PICO 1000000000000ULL #define FEMTO 1000000000000000ULL +/* + * Percentage and related scaling units + * + * These macros define scaling factors used to convert between ratio and + * percentage-based representations with different decimal resolutions. + * They are used for precise fractional calculations in engineering, finance, + * and measurement applications. + * + * Examples: + * 1% = 0.01 = 1 / PERCENT + * 0.1% = 0.001 = 1 / PERMILLE + * 0.01% = 0.0001 = 1 / PERMYRIAD (1 basis point) + * 0.001% = 0.00001 = 1 / PERCENTMILLE + */ +#define PERCENT 100 +#define PERMILLE 1000 +#define PERMYRIAD 10000 +#define PERCENTMILLE 100000 + #define NANOHZ_PER_HZ 1000000000UL #define MICROHZ_PER_HZ 1000000UL #define MILLIHZ_PER_HZ 1000UL +/* Hz based multipliers */ #define HZ_PER_KHZ 1000UL #define HZ_PER_MHZ 1000000UL +#define HZ_PER_GHZ 1000000000UL +/* kHz based multipliers */ #define KHZ_PER_MHZ 1000UL #define KHZ_PER_GHZ 1000000UL diff --git a/include/linux/usb.h b/include/linux/usb.h index e85105939af8..04277af4bb9d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1295,8 +1295,7 @@ struct usb_driver { * resume and suspend functions will be called in addition to the driver's * own, so this part of the setup does not need to be replicated. * - * USB drivers must provide all the fields listed above except driver, - * match, and id_table. + * USB device drivers must provide a name, other driver fields are optional. */ struct usb_device_driver { const char *name; @@ -1863,14 +1862,18 @@ void usb_free_noncoherent(struct usb_device *dev, size_t size, * SYNCHRONOUS CALL SUPPORT * *-------------------------------------------------------------------*/ +/* Maximum value allowed for timeout in synchronous routines below */ +#define USB_MAX_SYNCHRONOUS_TIMEOUT 60000 /* ms */ + extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout); extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, - void *data, int len, int *actual_length, - int timeout); + void *data, int len, int *actual_length, int timeout); +extern int usb_bulk_msg_killable(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, int timeout); /* wrappers around usb_control_msg() for the most common standard requests */ int usb_control_msg_send(struct usb_device *dev, __u8 endpoint, __u8 request, diff --git a/include/linux/usb/gadget_configfs.h b/include/linux/usb/gadget_configfs.h index 6b5d6838f865..23c1091e88c0 100644 --- a/include/linux/usb/gadget_configfs.h +++ b/include/linux/usb/gadget_configfs.h @@ -30,7 +30,7 @@ static ssize_t __struct##_##__name##_show(struct config_item *item, char *page) CONFIGFS_ATTR(struct_name##_, _name) #define USB_CONFIG_STRING_RW_OPS(struct_in) \ -static struct configfs_item_operations struct_in##_langid_item_ops = { \ +static const struct configfs_item_operations struct_in##_langid_item_ops = { \ .release = struct_in##_attr_release, \ }; \ \ @@ -86,7 +86,7 @@ static void struct_in##_strings_drop( \ config_item_put(item); \ } \ \ -static struct configfs_group_operations struct_in##_strings_ops = { \ +static const struct configfs_group_operations struct_in##_strings_ops = { \ .make_group = &struct_in##_strings_make, \ .drop_item = &struct_in##_strings_drop, \ }; \ diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index ac95e7c89df5..181db044c4d2 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -760,12 +760,6 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, */ extern struct rw_semaphore ehci_cf_port_reset_rwsem; -/* Keep track of which host controller drivers are loaded */ -#define USB_UHCI_LOADED 0 -#define USB_OHCI_LOADED 1 -#define USB_EHCI_LOADED 2 -extern unsigned long usb_hcds_loaded; - #endif /* __KERNEL__ */ #endif /* __USB_CORE_HCD_H */ diff --git a/include/linux/usb/isp1362.h b/include/linux/usb/isp1362.h deleted file mode 100644 index 5356c4ae386e..000000000000 --- a/include/linux/usb/isp1362.h +++ /dev/null @@ -1,47 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * board initialization code should put one of these into dev->platform_data - * and place the isp1362 onto platform_bus. - */ - -#ifndef __LINUX_USB_ISP1362_H__ -#define __LINUX_USB_ISP1362_H__ - -struct isp1362_platform_data { - /* Enable internal pulldown resistors on downstream ports */ - unsigned sel15Kres:1; - /* Clock cannot be stopped */ - unsigned clknotstop:1; - /* On-chip overcurrent protection */ - unsigned oc_enable:1; - /* INT output polarity */ - unsigned int_act_high:1; - /* INT edge or level triggered */ - unsigned int_edge_triggered:1; - /* DREQ output polarity */ - unsigned dreq_act_high:1; - /* DACK input polarity */ - unsigned dack_act_high:1; - /* chip can be resumed via H_WAKEUP pin */ - unsigned remote_wakeup_connected:1; - /* Switch or not to switch (keep always powered) */ - unsigned no_power_switching:1; - /* Ganged port power switching (0) or individual port power switching (1) */ - unsigned power_switching_mode:1; - /* Given port_power, msec/2 after power on till power good */ - u8 potpg; - /* Hardware reset set/clear */ - void (*reset) (struct device *dev, int set); - /* Clock start/stop */ - void (*clock) (struct device *dev, int start); - /* Inter-io delay (ns). The chip is picky about access timings; it - * expects at least: - * 110ns delay between consecutive accesses to DATA_REG, - * 300ns delay between access to ADDR_REG and DATA_REG (registers) - * 462ns delay between access to ADDR_REG and DATA_REG (buffer memory) - * WE MUST NOT be activated during these intervals (even without CS!) - */ - void (*delay) (struct device *dev, unsigned int delay); -}; - -#endif diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h index 2f7bd2fdc616..b3cc7beab4a3 100644 --- a/include/linux/usb/quirks.h +++ b/include/linux/usb/quirks.h @@ -78,4 +78,7 @@ /* skip BOS descriptor request */ #define USB_QUIRK_NO_BOS BIT(17) +/* Device claims zero configurations, forcing to 1 */ +#define USB_QUIRK_FORCE_ONE_CONFIG BIT(18) + #endif /* __LINUX_USB_QUIRKS_H */ diff --git a/include/linux/usb/r8152.h b/include/linux/usb/r8152.h index 2ca60828f28b..1502b2a355f9 100644 --- a/include/linux/usb/r8152.h +++ b/include/linux/usb/r8152.h @@ -32,6 +32,7 @@ #define VENDOR_ID_DLINK 0x2001 #define VENDOR_ID_DELL 0x413c #define VENDOR_ID_ASUS 0x0b05 +#define VENDOR_ID_TRENDNET 0x20f4 #if IS_REACHABLE(CONFIG_USB_RTL8152) extern u8 rtl8152_get_version(struct usb_interface *intf); diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h index 40afcee8b4f5..6343f88df5de 100644 --- a/include/linux/usb/tegra_usb_phy.h +++ b/include/linux/usb/tegra_usb_phy.h @@ -23,6 +23,11 @@ struct gpio_desc; * requires_extra_tuning_parameters: true if xcvr_hsslew, hssquelch_level * and hsdiscon_level should be set for adequate signal quality * requires_pmc_ao_power_up: true if USB AO is powered down by default + * uhsic_registers_offset: for Tegra30+ where HSIC registers were offset + * comparing to Tegra20 by 0x400, since Tegra20 has no UTMIP on PHY2 + * uhsic_tx_rtune: fine tuned 50 Ohm termination resistor for NMOS/PMOS driver + * uhsic_pts_value: parallel transceiver select enumeration value + * portsc1_offset: register offset of PORTSC1 */ struct tegra_phy_soc_config { @@ -31,6 +36,10 @@ struct tegra_phy_soc_config { bool requires_usbmode_setup; bool requires_extra_tuning_parameters; bool requires_pmc_ao_power_up; + u32 uhsic_registers_offset; + u32 uhsic_tx_rtune; + u32 uhsic_pts_value; + u32 portsc1_offset; }; struct tegra_utmip_config { @@ -72,7 +81,7 @@ struct tegra_usb_phy { struct usb_phy *ulpi; struct usb_phy u_phy; bool is_legacy_phy; - bool is_ulpi_phy; + enum usb_phy_interface phy_type; struct gpio_desc *reset_gpio; struct reset_control *pad_rst; bool wakeup_enabled; diff --git a/include/linux/usb/typec.h b/include/linux/usb/typec.h index 309251572e2e..d61ec38216fa 100644 --- a/include/linux/usb/typec.h +++ b/include/linux/usb/typec.h @@ -20,12 +20,15 @@ struct typec_port; struct typec_altmode_ops; struct typec_cable_ops; +struct bus_type; struct fwnode_handle; struct device; struct usb_power_delivery; struct usb_power_delivery_desc; +extern const struct bus_type typec_bus; + enum typec_port_type { TYPEC_PORT_SRC, TYPEC_PORT_SNK, @@ -152,6 +155,7 @@ struct typec_altmode_desc { /* Only used with ports */ enum typec_port_data roles; bool inactive; + bool mode_selection; }; void typec_partner_set_pd_revision(struct typec_partner *partner, u16 pd_revision); @@ -287,6 +291,7 @@ enum usb_pd_svdm_ver { * @prefer_role: Initial role preference (DRP ports). * @accessory: Supported Accessory Modes * @usb_capability: Supported USB Modes + * @no_mode_control: Ability to manage Alternate Modes * @fwnode: Optional fwnode of the port * @driver_data: Private pointer for driver specific info * @pd: Optional USB Power Delivery Support @@ -304,6 +309,7 @@ struct typec_capability { enum typec_accessory accessory[TYPEC_MAX_ACCESSORY]; unsigned int orientation_aware:1; u8 usb_capability; + bool no_mode_control; struct fwnode_handle *fwnode; void *driver_data; diff --git a/include/linux/usb/typec_altmode.h b/include/linux/usb/typec_altmode.h index f7db3bd4c90e..0513d333b797 100644 --- a/include/linux/usb/typec_altmode.h +++ b/include/linux/usb/typec_altmode.h @@ -9,6 +9,14 @@ #define MODE_DISCOVERY_MAX 6 +extern const struct device_type typec_port_altmode_dev_type; +extern const struct device_type typec_plug_altmode_dev_type; +extern const struct device_type typec_partner_altmode_dev_type; + +#define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type) +#define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type) +#define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type) + struct typec_altmode_ops; /** @@ -28,6 +36,8 @@ struct typec_altmode { int mode; u32 vdo; unsigned int active:1; + u8 priority; + bool mode_selection; char *desc; const struct typec_altmode_ops *ops; @@ -231,4 +241,44 @@ void typec_altmode_unregister_driver(struct typec_altmode_driver *drv); module_driver(__typec_altmode_driver, typec_altmode_register_driver, \ typec_altmode_unregister_driver) +/** + * typec_mode_selection_start - Start an alternate mode selection process + * @partner: Handle to the Type-C partner device + * @delay: Delay between mode entry/exit attempts, ms + * @timeout: Timeout for a mode entry attempt, ms + * + * This function initiates the process of attempting to enter an Alternate Mode + * supported by the connected Type-C partner. + * Returns 0 on success, or a negative error code on failure. + */ +int typec_mode_selection_start(struct typec_partner *partner, + const unsigned int delay, const unsigned int timeout); + +/** + * typec_altmode_state_update - Report the current status of an Alternate Mode + * negotiation + * @partner: Handle to the Type-C partner device + * @svid: Standard or Vendor ID of the Alternate Mode. A value of 0 should be + * passed if no mode is currently active + * @result: Result of the entry operation. This should be 0 on success, or a + * negative error code if the negotiation failed + * + * This function should be called by an Alternate Mode driver to report the + * result of an asynchronous alternate mode entry request. It signals what the + * current active SVID is (or 0 if none) and the success or failure status of + * the last attempt. + */ +void typec_altmode_state_update(struct typec_partner *partner, const u16 svid, + const int result); + +/** + * typec_mode_selection_delete - Delete an alternate mode selection instance + * @partner: Handle to the Type-C partner device. + * + * This function cancels a pending alternate mode selection request that was + * previously started with typec_mode_selection_start(). + * This is typically called when the partner disconnects. + */ +void typec_mode_selection_delete(struct typec_partner *partner); + #endif /* __USB_TYPEC_ALTMODE_H */ diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h index b0e84896e6ac..bbf799ccf3b3 100644 --- a/include/linux/usb/usbnet.h +++ b/include/linux/usb/usbnet.h @@ -132,6 +132,7 @@ struct driver_info { #define FLAG_MULTI_PACKET 0x2000 #define FLAG_RX_ASSEMBLE 0x4000 /* rx packets may span >1 frames */ #define FLAG_NOARP 0x8000 /* device can't do ARP */ +#define FLAG_NOMAXMTU 0x10000 /* allow max_mtu above hard_mtu */ /* init device ... can sleep, or cause probe() failure */ int (*bind)(struct usbnet *, struct usb_interface *); diff --git a/include/linux/wait.h b/include/linux/wait.h index f648044466d5..dce055e6add3 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -937,6 +937,21 @@ extern int do_wait_intr_irq(wait_queue_head_t *, wait_queue_entry_t *); __ret; \ }) +#define __io_wait_event_killable(wq, condition) \ + ___wait_event(wq, condition, TASK_KILLABLE, 0, 0, io_schedule()) + +/* + * wait_event_killable() - link wait_event_killable but with io_schedule() + */ +#define io_wait_event_killable(wq_head, condition) \ +({ \ + int __ret = 0; \ + might_sleep(); \ + if (!(condition)) \ + __ret = __io_wait_event_killable(wq_head, condition); \ + __ret; \ +}) + #define __wait_event_state(wq, condition, state) \ ___wait_event(wq, condition, state, 0, 0, schedule()) diff --git a/include/linux/watchdog.h b/include/linux/watchdog.h index 8c60687a3e55..62cdd26fd025 100644 --- a/include/linux/watchdog.h +++ b/include/linux/watchdog.h @@ -129,7 +129,7 @@ struct watchdog_device { #define WATCHDOG_NOWAYOUT_INIT_STATUS (WATCHDOG_NOWAYOUT << WDOG_NO_WAY_OUT) /* Use the following function to check whether or not the watchdog is active */ -static inline bool watchdog_active(struct watchdog_device *wdd) +static inline bool watchdog_active(const struct watchdog_device *wdd) { return test_bit(WDOG_ACTIVE, &wdd->status); } @@ -138,7 +138,7 @@ static inline bool watchdog_active(struct watchdog_device *wdd) * Use the following function to check whether or not the hardware watchdog * is running */ -static inline bool watchdog_hw_running(struct watchdog_device *wdd) +static inline bool watchdog_hw_running(const struct watchdog_device *wdd) { return test_bit(WDOG_HW_RUNNING, &wdd->status); } @@ -169,7 +169,8 @@ static inline void watchdog_stop_ping_on_suspend(struct watchdog_device *wdd) } /* Use the following function to check if a timeout value is invalid */ -static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigned int t) +static inline bool watchdog_timeout_invalid(const struct watchdog_device *wdd, + unsigned int t) { /* * The timeout is invalid if @@ -188,7 +189,7 @@ static inline bool watchdog_timeout_invalid(struct watchdog_device *wdd, unsigne } /* Use the following function to check if a pretimeout value is invalid */ -static inline bool watchdog_pretimeout_invalid(struct watchdog_device *wdd, +static inline bool watchdog_pretimeout_invalid(const struct watchdog_device *wdd, unsigned int t) { return t && wdd->timeout && t >= wdd->timeout; @@ -218,7 +219,8 @@ static inline void watchdog_notify_pretimeout(struct watchdog_device *wdd) /* drivers/watchdog/watchdog_core.c */ void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority); extern int watchdog_init_timeout(struct watchdog_device *wdd, - unsigned int timeout_parm, struct device *dev); + unsigned int timeout_parm, + const struct device *dev); extern int watchdog_register_device(struct watchdog_device *); extern void watchdog_unregister_device(struct watchdog_device *); int watchdog_dev_suspend(struct watchdog_device *wdd); diff --git a/include/net/act_api.h b/include/net/act_api.h index 91a24b5e0b93..d11b79107930 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -70,6 +70,7 @@ struct tc_action { #define TCA_ACT_FLAGS_REPLACE (1U << (TCA_ACT_FLAGS_USER_BITS + 2)) #define TCA_ACT_FLAGS_NO_RTNL (1U << (TCA_ACT_FLAGS_USER_BITS + 3)) #define TCA_ACT_FLAGS_AT_INGRESS (1U << (TCA_ACT_FLAGS_USER_BITS + 4)) +#define TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT (1U << (TCA_ACT_FLAGS_USER_BITS + 5)) /* Update lastuse only if needed, to avoid dirtying a cache line. * We use a temp variable to avoid fetching jiffies twice. @@ -159,7 +160,7 @@ int tc_action_net_init(struct net *net, struct tc_action_net *tn, { int err = 0; - tn->idrinfo = kmalloc(sizeof(*tn->idrinfo), GFP_KERNEL); + tn->idrinfo = kmalloc_obj(*tn->idrinfo); if (!tn->idrinfo) return -ENOMEM; tn->ops = ops; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 78e8b877fb25..9e96776945e5 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -8,7 +8,8 @@ #define MIN_VALID_LIFETIME (2*3600) /* 2 hours */ -#define TEMP_VALID_LIFETIME (7*86400) /* 1 week */ +/* TEMP_VALID_LIFETIME default value as specified in RFC 8981 3.8 */ +#define TEMP_VALID_LIFETIME (2*86400) /* 2 days */ #define TEMP_PREFERRED_LIFETIME (86400) /* 24 hours */ #define REGEN_MIN_ADVANCE (2) /* 2 seconds */ #define REGEN_MAX_RETRY (3) diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index d3ff48a2fbe0..533d8e75f7bb 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -276,10 +276,19 @@ static inline bool vsock_net_mode_global(struct vsock_sock *vsk) return vsock_net_mode(sock_net(sk_vsock(vsk))) == VSOCK_NET_MODE_GLOBAL; } -static inline void vsock_net_set_child_mode(struct net *net, +static inline bool vsock_net_set_child_mode(struct net *net, enum vsock_net_mode mode) { - WRITE_ONCE(net->vsock.child_ns_mode, mode); + int new_locked = mode + 1; + int old_locked = 0; /* unlocked */ + + if (try_cmpxchg(&net->vsock.child_ns_mode_locked, + &old_locked, new_locked)) { + WRITE_ONCE(net->vsock.child_ns_mode, mode); + return true; + } + + return old_locked == new_locked; } static inline enum vsock_net_mode vsock_net_child_mode(struct net *net) diff --git a/include/net/ax25.h b/include/net/ax25.h index ad3d7626130e..9fc6a6657266 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h @@ -211,8 +211,6 @@ typedef struct { unsigned short slave_timeout; /* when? */ } ax25_dama_info; -struct ctl_table; - typedef struct ax25_dev { struct list_head list; diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index ec3af01e4db9..010f1a8fd15f 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -284,9 +284,9 @@ struct l2cap_conn_rsp { #define L2CAP_CR_LE_BAD_KEY_SIZE 0x0007 #define L2CAP_CR_LE_ENCRYPTION 0x0008 #define L2CAP_CR_LE_INVALID_SCID 0x0009 -#define L2CAP_CR_LE_SCID_IN_USE 0X000A -#define L2CAP_CR_LE_UNACCEPT_PARAMS 0X000B -#define L2CAP_CR_LE_INVALID_PARAMS 0X000C +#define L2CAP_CR_LE_SCID_IN_USE 0x000A +#define L2CAP_CR_LE_UNACCEPT_PARAMS 0x000B +#define L2CAP_CR_LE_INVALID_PARAMS 0x000C /* connect/create channel status */ #define L2CAP_CS_NO_INFO 0x0000 @@ -493,6 +493,8 @@ struct l2cap_ecred_reconf_req { #define L2CAP_RECONF_SUCCESS 0x0000 #define L2CAP_RECONF_INVALID_MTU 0x0001 #define L2CAP_RECONF_INVALID_MPS 0x0002 +#define L2CAP_RECONF_INVALID_CID 0x0003 +#define L2CAP_RECONF_INVALID_PARAMS 0x0004 struct l2cap_ecred_reconf_rsp { __le16 result; diff --git a/include/net/bonding.h b/include/net/bonding.h index 4ad5521e7731..395c6e281c5f 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -699,6 +699,7 @@ void bond_debug_register(struct bonding *bond); void bond_debug_unregister(struct bonding *bond); void bond_debug_reregister(struct bonding *bond); const char *bond_mode_name(int mode); +bool __bond_xdp_check(int mode, int xmit_policy); bool bond_xdp_check(struct bonding *bond, int mode); void bond_setup(struct net_device *bond_dev); unsigned int bond_get_num_tx_queues(void); diff --git a/include/net/fq_impl.h b/include/net/fq_impl.h index 9467e33dfb36..8aca881937da 100644 --- a/include/net/fq_impl.h +++ b/include/net/fq_impl.h @@ -358,7 +358,7 @@ static int fq_init(struct fq *fq, int flows_cnt) fq->limit = 8192; fq->memory_limit = 16 << 20; /* 16 MBytes */ - fq->flows = kvcalloc(fq->flows_cnt, sizeof(fq->flows[0]), GFP_KERNEL); + fq->flows = kvzalloc_objs(fq->flows[0], fq->flows_cnt); if (!fq->flows) return -ENOMEM; diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index 282e29237d93..c16de5b7963f 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -175,7 +175,7 @@ static inline bool inet6_match(const struct net *net, const struct sock *sk, { if (!net_eq(sock_net(sk), net) || sk->sk_family != AF_INET6 || - sk->sk_portpair != ports || + READ_ONCE(sk->sk_portpair) != ports || !ipv6_addr_equal(&sk->sk_v6_daddr, saddr) || !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) return false; diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index ecb362025c4e..5cb3056d6ddc 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -42,7 +42,9 @@ struct inet_connection_sock_af_ops { struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req); + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)); u16 net_header_len; int (*setsockopt)(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen); diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index ac05a52d9e13..5a979dcab538 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -345,7 +345,7 @@ static inline bool inet_match(const struct net *net, const struct sock *sk, int dif, int sdif) { if (!net_eq(sock_net(sk), net) || - sk->sk_portpair != ports || + READ_ONCE(sk->sk_portpair) != ports || sk->sk_addrpair != cookie) return false; diff --git a/include/net/ioam6.h b/include/net/ioam6.h index 2cbbee6e806a..a75912fe247e 100644 --- a/include/net/ioam6.h +++ b/include/net/ioam6.h @@ -60,6 +60,8 @@ void ioam6_fill_trace_data(struct sk_buff *skb, struct ioam6_trace_hdr *trace, bool is_input); +u8 ioam6_trace_compute_nodelen(u32 trace_type); + int ioam6_init(void); void ioam6_exit(void); diff --git a/include/net/ip.h b/include/net/ip.h index 69d5cef46004..7f9abd457e01 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -101,7 +101,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm, ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr; - ipcm->protocol = inet->inet_num; + ipcm->protocol = READ_ONCE(inet->inet_num); } #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb)) diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index 120db2865811..359b595f1df9 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -156,6 +156,18 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, { int pkt_len, err; + if (unlikely(dev_recursion_level() > IP_TUNNEL_RECURSION_LIMIT)) { + if (dev) { + net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n", + dev->name); + DEV_STATS_INC(dev, tx_errors); + } + kfree_skb(skb); + return; + } + + dev_xmit_recursion_inc(); + memset(skb->cb, 0, sizeof(struct inet6_skb_parm)); IP6CB(skb)->flags = ip6cb_flags; pkt_len = skb->len - skb_inner_network_offset(skb); @@ -166,6 +178,8 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, pkt_len = -1; iptunnel_xmit_stats(dev, pkt_len); } + + dev_xmit_recursion_dec(); } #endif #endif diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index b4495c38e0a0..318593743b6e 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -559,7 +559,7 @@ static inline u32 fib_multipath_hash_from_keys(const struct net *net, siphash_aligned_key_t hash_key; u32 mp_seed; - mp_seed = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_seed).mp_seed; + mp_seed = READ_ONCE(net->ipv4.sysctl_fib_multipath_hash_seed.mp_seed); fib_multipath_hash_construct_key(&hash_key, mp_seed); return flow_hash_from_keys_seed(keys, &hash_key); diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 4021e6a73e32..80662f812080 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -27,6 +27,13 @@ #include #endif +/* Recursion limit for tunnel xmit to detect routing loops. + * Unlike XMIT_RECURSION_LIMIT (8) used in the no-qdisc path, tunnel + * recursion involves route lookups and full IP output, consuming much + * more stack per level, so a lower limit is needed. + */ +#define IP_TUNNEL_RECURSION_LIMIT 4 + /* Keep error state on tunnel for 30 sec */ #define IPTUNNEL_ERR_TIMEO (30*HZ) diff --git a/include/net/ipv6.h b/include/net/ipv6.h index cc56e09525d0..53c5056508be 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -1213,12 +1213,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, static inline int ip6_sock_set_v6only(struct sock *sk) { - if (inet_sk(sk)->inet_num) - return -EINVAL; + int ret = 0; + lock_sock(sk); - sk->sk_ipv6only = true; + if (inet_sk(sk)->inet_num) + ret = -EINVAL; + else + sk->sk_ipv6only = true; release_sock(sk); - return 0; + return ret; } static inline void ip6_sock_set_recverr(struct sock *sk) diff --git a/include/net/iucv/iucv.h b/include/net/iucv/iucv.h index 5606ed6e7084..18f511da9a09 100644 --- a/include/net/iucv/iucv.h +++ b/include/net/iucv/iucv.h @@ -211,7 +211,7 @@ static inline struct iucv_path *iucv_path_alloc(u16 msglim, u8 flags, gfp_t gfp) { struct iucv_path *path; - path = kzalloc(sizeof(struct iucv_path), gfp); + path = kzalloc_obj(struct iucv_path, gfp); if (path) { path->msglim = msglim; path->flags = flags; diff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h index 481a7b28e6f2..82b5d21aae87 100644 --- a/include/net/libeth/xsk.h +++ b/include/net/libeth/xsk.h @@ -597,6 +597,7 @@ __libeth_xsk_run_pass(struct libeth_xdp_buff *xdp, * @pending: current number of XSkFQEs to refill * @thresh: threshold below which the queue is refilled * @buf_len: HW-writeable length per each buffer + * @truesize: step between consecutive buffers, 0 if none exists * @nid: ID of the closest NUMA node with memory */ struct libeth_xskfq { @@ -614,6 +615,8 @@ struct libeth_xskfq { u32 thresh; u32 buf_len; + u32 truesize; + int nid; }; diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 426534a711b0..e2d2bfc1f989 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -320,11 +320,13 @@ static inline void *nft_elem_priv_cast(const struct nft_elem_priv *priv) * @NFT_ITER_UNSPEC: unspecified, to catch errors * @NFT_ITER_READ: read-only iteration over set elements * @NFT_ITER_UPDATE: iteration under mutex to update set element state + * @NFT_ITER_UPDATE_CLONE: clone set before iteration under mutex to update element */ enum nft_iter_type { NFT_ITER_UNSPEC, NFT_ITER_READ, NFT_ITER_UPDATE, + NFT_ITER_UPDATE_CLONE, }; struct nft_set; @@ -1861,6 +1863,11 @@ struct nft_trans_gc { struct rcu_head rcu; }; +static inline int nft_trans_gc_space(const struct nft_trans_gc *trans) +{ + return NFT_TRANS_GC_BATCHCOUNT - trans->count; +} + static inline void nft_ctx_update(struct nft_ctx *ctx, const struct nft_trans *trans) { diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 2dbd46fc4734..8e971c7bf164 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -88,6 +88,12 @@ struct netns_ipv4 { int sysctl_tcp_rcvbuf_low_rtt; __cacheline_group_end(netns_ipv4_read_rx); + /* ICMP rate limiter hot cache line. */ + __cacheline_group_begin_aligned(icmp); + atomic_t icmp_global_credit; + u32 icmp_global_stamp; + __cacheline_group_end_aligned(icmp); + struct inet_timewait_death_row tcp_death_row; struct udp_table *udp_table; @@ -141,8 +147,7 @@ struct netns_ipv4 { int sysctl_icmp_ratemask; int sysctl_icmp_msgs_per_sec; int sysctl_icmp_msgs_burst; - atomic_t icmp_global_credit; - u32 icmp_global_stamp; + u32 ip_rt_min_pmtu; int ip_rt_mtu_expires; int ip_rt_min_advmss; diff --git a/include/net/netns/vsock.h b/include/net/netns/vsock.h index b34d69a22fa8..dc8cbe45f406 100644 --- a/include/net/netns/vsock.h +++ b/include/net/netns/vsock.h @@ -17,5 +17,8 @@ struct netns_vsock { enum vsock_net_mode mode; enum vsock_net_mode child_ns_mode; + + /* 0 = unlocked, 1 = locked to global, 2 = locked to local */ + int child_ns_mode_locked; }; #endif /* __NET_NET_NAMESPACE_VSOCK_H */ diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h index 0d453484a585..cdd95477af7a 100644 --- a/include/net/page_pool/types.h +++ b/include/net/page_pool/types.h @@ -247,7 +247,7 @@ struct page_pool { /* User-facing fields, protected by page_pools_lock */ struct { struct hlist_node list; - u64 detach_time; + ktime_t detach_time; u32 id; } user; }; diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c3a7268b567e..d5d55cb21686 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -778,13 +778,23 @@ static inline bool skb_skip_tc_classify(struct sk_buff *skb) static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) { struct Qdisc *qdisc; + bool nolock; for (; i < dev->num_tx_queues; i++) { qdisc = rtnl_dereference(netdev_get_tx_queue(dev, i)->qdisc); if (qdisc) { + nolock = qdisc->flags & TCQ_F_NOLOCK; + + if (nolock) + spin_lock_bh(&qdisc->seqlock); spin_lock_bh(qdisc_lock(qdisc)); qdisc_reset(qdisc); spin_unlock_bh(qdisc_lock(qdisc)); + if (nolock) { + clear_bit(__QDISC_STATE_MISSED, &qdisc->state); + clear_bit(__QDISC_STATE_DRAINING, &qdisc->state); + spin_unlock_bh(&qdisc->seqlock); + } } } } diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h index cddebafb9f77..6f996229167b 100644 --- a/include/net/secure_seq.h +++ b/include/net/secure_seq.h @@ -5,16 +5,47 @@ #include struct net; +extern struct net init_net; + +union tcp_seq_and_ts_off { + struct { + u32 seq; + u32 ts_off; + }; + u64 hash64; +}; u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport); -u32 secure_tcp_seq(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport); -u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr); -u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, - __be16 sport, __be16 dport); -u32 secure_tcpv6_ts_off(const struct net *net, - const __be32 *saddr, const __be32 *daddr); +union tcp_seq_and_ts_off +secure_tcp_seq_and_ts_off(const struct net *net, __be32 saddr, __be32 daddr, + __be16 sport, __be16 dport); +static inline u32 secure_tcp_seq(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) +{ + union tcp_seq_and_ts_off ts; + + ts = secure_tcp_seq_and_ts_off(&init_net, saddr, daddr, + sport, dport); + + return ts.seq; +} + +union tcp_seq_and_ts_off +secure_tcpv6_seq_and_ts_off(const struct net *net, const __be32 *saddr, + const __be32 *daddr, + __be16 sport, __be16 dport); + +static inline u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, + __be16 sport, __be16 dport) +{ + union tcp_seq_and_ts_off ts; + + ts = secure_tcpv6_seq_and_ts_off(&init_net, saddr, daddr, + sport, dport); + + return ts.seq; +} #endif /* _NET_SECURE_SEQ */ diff --git a/include/net/sock.h b/include/net/sock.h index 66b56288c1d3..6c9a83016e95 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -2098,7 +2098,7 @@ static inline int sk_rx_queue_get(const struct sock *sk) static inline void sk_set_socket(struct sock *sk, struct socket *sock) { - sk->sk_socket = sock; + WRITE_ONCE(sk->sk_socket, sock); if (sock) { WRITE_ONCE(sk->sk_uid, SOCK_INODE(sock)->i_uid); WRITE_ONCE(sk->sk_ino, SOCK_INODE(sock)->i_ino); diff --git a/include/net/tc_act/tc_gate.h b/include/net/tc_act/tc_gate.h index c1a67149c6b6..e0fded18e18c 100644 --- a/include/net/tc_act/tc_gate.h +++ b/include/net/tc_act/tc_gate.h @@ -32,6 +32,7 @@ struct tcf_gate_params { s32 tcfg_clockid; size_t num_entries; struct list_head entries; + struct rcu_head rcu; }; #define GATE_ACT_GATE_OPEN BIT(0) @@ -39,7 +40,7 @@ struct tcf_gate_params { struct tcf_gate { struct tc_action common; - struct tcf_gate_params param; + struct tcf_gate_params __rcu *param; u8 current_gate_status; ktime_t current_close_time; u32 current_entry_octets; @@ -51,47 +52,65 @@ struct tcf_gate { #define to_gate(a) ((struct tcf_gate *)a) +static inline struct tcf_gate_params *tcf_gate_params_locked(const struct tc_action *a) +{ + struct tcf_gate *gact = to_gate(a); + + return rcu_dereference_protected(gact->param, + lockdep_is_held(&gact->tcf_lock)); +} + static inline s32 tcf_gate_prio(const struct tc_action *a) { + struct tcf_gate_params *p; s32 tcfg_prio; - tcfg_prio = to_gate(a)->param.tcfg_priority; + p = tcf_gate_params_locked(a); + tcfg_prio = p->tcfg_priority; return tcfg_prio; } static inline u64 tcf_gate_basetime(const struct tc_action *a) { + struct tcf_gate_params *p; u64 tcfg_basetime; - tcfg_basetime = to_gate(a)->param.tcfg_basetime; + p = tcf_gate_params_locked(a); + tcfg_basetime = p->tcfg_basetime; return tcfg_basetime; } static inline u64 tcf_gate_cycletime(const struct tc_action *a) { + struct tcf_gate_params *p; u64 tcfg_cycletime; - tcfg_cycletime = to_gate(a)->param.tcfg_cycletime; + p = tcf_gate_params_locked(a); + tcfg_cycletime = p->tcfg_cycletime; return tcfg_cycletime; } static inline u64 tcf_gate_cycletimeext(const struct tc_action *a) { + struct tcf_gate_params *p; u64 tcfg_cycletimeext; - tcfg_cycletimeext = to_gate(a)->param.tcfg_cycletime_ext; + p = tcf_gate_params_locked(a); + tcfg_cycletimeext = p->tcfg_cycletime_ext; return tcfg_cycletimeext; } static inline u32 tcf_gate_num_entries(const struct tc_action *a) { + struct tcf_gate_params *p; u32 num_entries; - num_entries = to_gate(a)->param.num_entries; + p = tcf_gate_params_locked(a); + num_entries = p->num_entries; return num_entries; } @@ -105,7 +124,7 @@ static inline struct action_gate_entry u32 num_entries; int i = 0; - p = &to_gate(a)->param; + p = tcf_gate_params_locked(a); num_entries = p->num_entries; list_for_each_entry(entry, &p->entries, list) @@ -114,7 +133,7 @@ static inline struct action_gate_entry if (i != num_entries) return NULL; - oe = kcalloc(num_entries, sizeof(*oe), GFP_ATOMIC); + oe = kzalloc_objs(*oe, num_entries, GFP_ATOMIC); if (!oe) return NULL; diff --git a/include/net/tc_act/tc_ife.h b/include/net/tc_act/tc_ife.h index c7f24a2da1ca..24d4d5a62b3c 100644 --- a/include/net/tc_act/tc_ife.h +++ b/include/net/tc_act/tc_ife.h @@ -13,15 +13,13 @@ struct tcf_ife_params { u8 eth_src[ETH_ALEN]; u16 eth_type; u16 flags; - + struct list_head metalist; struct rcu_head rcu; }; struct tcf_ife_info { struct tc_action common; struct tcf_ife_params __rcu *params; - /* list of metaids allowed */ - struct list_head metalist; }; #define to_ife(a) ((struct tcf_ife_info *)a) diff --git a/include/net/tcp.h b/include/net/tcp.h index 40e72b9cb85f..978eea2d5df0 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -544,7 +545,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req); + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)); int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb); int tcp_v4_connect(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len); int tcp_connect(struct sock *sk); @@ -2462,8 +2465,9 @@ struct tcp_request_sock_ops { struct flowi *fl, struct request_sock *req, u32 tw_isn); - u32 (*init_seq)(const struct sk_buff *skb); - u32 (*init_ts_off)(const struct net *net, const struct sk_buff *skb); + union tcp_seq_and_ts_off (*init_seq_and_ts_off)( + const struct net *net, + const struct sk_buff *skb); int (*send_synack)(const struct sock *sk, struct dst_entry *dst, struct flowi *fl, struct request_sock *req, struct tcp_fastopen_cookie *foc, diff --git a/include/net/udp.h b/include/net/udp.h index 700dbedcb15f..da68702ddf6e 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -294,8 +294,7 @@ static inline int udp_lib_init_sock(struct sock *sk) up->forward_threshold = sk->sk_rcvbuf >> 2; set_bit(SOCK_CUSTOM_SOCKOPT, &sk->sk_socket->flags); - up->udp_prod_queue = kcalloc(nr_node_ids, sizeof(*up->udp_prod_queue), - GFP_KERNEL); + up->udp_prod_queue = kzalloc_objs(*up->udp_prod_queue, nr_node_ids); if (!up->udp_prod_queue) return -ENOMEM; for (int i = 0; i < nr_node_ids; i++) diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 242e34f771cc..6b9ebae2dc95 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -51,6 +51,11 @@ static inline u32 xsk_pool_get_rx_frame_size(struct xsk_buff_pool *pool) return xsk_pool_get_chunk_size(pool) - xsk_pool_get_headroom(pool); } +static inline u32 xsk_pool_get_rx_frag_step(struct xsk_buff_pool *pool) +{ + return pool->unaligned ? 0 : xsk_pool_get_chunk_size(pool); +} + static inline void xsk_pool_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq) { @@ -122,7 +127,7 @@ static inline void xsk_buff_free(struct xdp_buff *xdp) goto out; list_for_each_entry_safe(pos, tmp, xskb_list, list_node) { - list_del(&pos->list_node); + list_del_init(&pos->list_node); xp_free(pos); } @@ -157,7 +162,7 @@ static inline struct xdp_buff *xsk_buff_get_frag(const struct xdp_buff *first) frag = list_first_entry_or_null(&xskb->pool->xskb_list, struct xdp_buff_xsk, list_node); if (frag) { - list_del(&frag->list_node); + list_del_init(&frag->list_node); ret = &frag->xdp; } @@ -168,7 +173,7 @@ static inline void xsk_buff_del_frag(struct xdp_buff *xdp) { struct xdp_buff_xsk *xskb = container_of(xdp, struct xdp_buff_xsk, xdp); - list_del(&xskb->list_node); + list_del_init(&xskb->list_node); } static inline struct xdp_buff *xsk_buff_get_head(struct xdp_buff *first) @@ -337,6 +342,11 @@ static inline u32 xsk_pool_get_rx_frame_size(struct xsk_buff_pool *pool) return 0; } +static inline u32 xsk_pool_get_rx_frag_step(struct xsk_buff_pool *pool) +{ + return 0; +} + static inline void xsk_pool_set_rxq_info(struct xsk_buff_pool *pool, struct xdp_rxq_info *rxq) { diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h index 6de6fd8bd15e..d639ff889e64 100644 --- a/include/rdma/rdma_cm.h +++ b/include/rdma/rdma_cm.h @@ -181,7 +181,7 @@ void rdma_destroy_id(struct rdma_cm_id *id); * * It needs to be called before the RDMA identifier is bound * to an device, which mean it should be called before - * rdma_bind_addr(), rdma_bind_addr() and rdma_listen(). + * rdma_bind_addr(), rdma_resolve_addr() and rdma_listen(). */ int rdma_restrict_node_type(struct rdma_cm_id *id, u8 node_type); diff --git a/include/rv/da_monitor.h b/include/rv/da_monitor.h index db11d41bb438..7511f5464c48 100644 --- a/include/rv/da_monitor.h +++ b/include/rv/da_monitor.h @@ -20,6 +20,12 @@ #include #include +/* + * Per-cpu variables require a unique name although static in some + * configurations (e.g. CONFIG_DEBUG_FORCE_WEAK_PER_CPU or alpha modules). + */ +#define DA_MON_NAME CONCATENATE(da_mon_, MONITOR_NAME) + static struct rv_monitor rv_this; static void react(enum states curr_state, enum events event) @@ -183,14 +189,14 @@ static inline bool da_event(struct da_monitor *da_mon, struct task_struct *tsk, /* * global monitor (a single variable) */ -static struct da_monitor da_mon_this; +static struct da_monitor DA_MON_NAME; /* * da_get_monitor - return the global monitor address */ static struct da_monitor *da_get_monitor(void) { - return &da_mon_this; + return &DA_MON_NAME; } /* @@ -223,14 +229,14 @@ static inline void da_monitor_destroy(void) { } /* * per-cpu monitor variables */ -static DEFINE_PER_CPU(struct da_monitor, da_mon_this); +static DEFINE_PER_CPU(struct da_monitor, DA_MON_NAME); /* * da_get_monitor - return current CPU monitor address */ static struct da_monitor *da_get_monitor(void) { - return this_cpu_ptr(&da_mon_this); + return this_cpu_ptr(&DA_MON_NAME); } /* @@ -242,7 +248,7 @@ static void da_monitor_reset_all(void) int cpu; for_each_cpu(cpu, cpu_online_mask) { - da_mon = per_cpu_ptr(&da_mon_this, cpu); + da_mon = per_cpu_ptr(&DA_MON_NAME, cpu); da_monitor_reset(da_mon); } } diff --git a/include/sound/cs35l56.h b/include/sound/cs35l56.h index ae1e1489b671..28f9f5940ab6 100644 --- a/include/sound/cs35l56.h +++ b/include/sound/cs35l56.h @@ -406,6 +406,7 @@ extern const char * const cs35l56_cal_set_status_text[3]; extern const char * const cs35l56_tx_input_texts[CS35L56_NUM_INPUT_SRC]; extern const unsigned int cs35l56_tx_input_values[CS35L56_NUM_INPUT_SRC]; +int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base); int cs35l56_set_patch(struct cs35l56_base *cs35l56_base); int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command); int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base); diff --git a/include/sound/tas2781.h b/include/sound/tas2781.h index 7c03bdc951bb..e847cf51878c 100644 --- a/include/sound/tas2781.h +++ b/include/sound/tas2781.h @@ -151,6 +151,7 @@ struct tasdevice { struct bulk_reg_val *cali_data_backup; struct bulk_reg_val alp_cali_bckp; struct tasdevice_fw *cali_data_fmw; + void *cali_specific; unsigned int dev_addr; unsigned int err_code; unsigned char cur_book; diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index df4017dcc701..9364e6775562 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -184,6 +184,15 @@ TRACE_DEFINE_ENUM(CP_PHASE_FINISH_CHECKPOINT); { CP_PHASE_FINISH_BLOCK_OPS, "finish block_ops" }, \ { CP_PHASE_FINISH_CHECKPOINT, "finish checkpoint" }) +#define show_lock_name(lock) \ + __print_symbolic(lock, \ + { LOCK_NAME_CP_RWSEM, "cp_rwsem" }, \ + { LOCK_NAME_NODE_CHANGE, "node_change" }, \ + { LOCK_NAME_NODE_WRITE, "node_write" }, \ + { LOCK_NAME_GC_LOCK, "gc_lock" }, \ + { LOCK_NAME_CP_GLOBAL, "cp_global" }, \ + { LOCK_NAME_IO_RWSEM, "io_rwsem" }) + struct f2fs_sb_info; struct f2fs_io_info; struct extent_info; @@ -1358,6 +1367,7 @@ DECLARE_EVENT_CLASS(f2fs__folio, __field(int, type) __field(int, dir) __field(pgoff_t, index) + __field(pgoff_t, nrpages) __field(int, dirty) __field(int, uptodate) ), @@ -1368,16 +1378,18 @@ DECLARE_EVENT_CLASS(f2fs__folio, __entry->type = type; __entry->dir = S_ISDIR(folio->mapping->host->i_mode); __entry->index = folio->index; + __entry->nrpages= folio_nr_pages(folio); __entry->dirty = folio_test_dirty(folio); __entry->uptodate = folio_test_uptodate(folio); ), - TP_printk("dev = (%d,%d), ino = %lu, %s, %s, index = %lu, " + TP_printk("dev = (%d,%d), ino = %lu, %s, %s, index = %lu, nr_pages = %lu, " "dirty = %d, uptodate = %d", show_dev_ino(__entry), show_block_type(__entry->type), show_file_type(__entry->dir), (unsigned long)__entry->index, + (unsigned long)__entry->nrpages, __entry->dirty, __entry->uptodate) ); @@ -1403,6 +1415,13 @@ DEFINE_EVENT(f2fs__folio, f2fs_readpage, TP_ARGS(folio, type) ); +DEFINE_EVENT(f2fs__folio, f2fs_read_folio, + + TP_PROTO(struct folio *folio, int type), + + TP_ARGS(folio, type) +); + DEFINE_EVENT(f2fs__folio, f2fs_set_page_dirty, TP_PROTO(struct folio *folio, int type), @@ -2442,6 +2461,127 @@ DEFINE_EVENT(f2fs__rw_end, f2fs_datawrite_end, TP_ARGS(inode, offset, bytes) ); +TRACE_EVENT(f2fs_lock_elapsed_time, + + TP_PROTO(struct f2fs_sb_info *sbi, enum f2fs_lock_name lock_name, + bool is_write, struct task_struct *p, int ioprio, + unsigned long long total_time, + unsigned long long running_time, + unsigned long long runnable_time, + unsigned long long io_sleep_time, + unsigned long long other_time), + + TP_ARGS(sbi, lock_name, is_write, p, ioprio, total_time, running_time, + runnable_time, io_sleep_time, other_time), + + TP_STRUCT__entry( + __field(dev_t, dev) + __array(char, comm, TASK_COMM_LEN) + __field(pid_t, pid) + __field(int, prio) + __field(int, ioprio_class) + __field(int, ioprio_data) + __field(unsigned int, lock_name) + __field(bool, is_write) + __field(unsigned long long, total_time) + __field(unsigned long long, running_time) + __field(unsigned long long, runnable_time) + __field(unsigned long long, io_sleep_time) + __field(unsigned long long, other_time) + ), + + TP_fast_assign( + __entry->dev = sbi->sb->s_dev; + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->prio = p->prio; + __entry->ioprio_class = IOPRIO_PRIO_CLASS(ioprio); + __entry->ioprio_data = IOPRIO_PRIO_DATA(ioprio); + __entry->lock_name = lock_name; + __entry->is_write = is_write; + __entry->total_time = total_time; + __entry->running_time = running_time; + __entry->runnable_time = runnable_time; + __entry->io_sleep_time = io_sleep_time; + __entry->other_time = other_time; + ), + + TP_printk("dev = (%d,%d), comm: %s, pid: %d, prio: %d, " + "ioprio_class: %d, ioprio_data: %d, lock_name: %s, " + "lock_type: %s, total: %llu, running: %llu, " + "runnable: %llu, io_sleep: %llu, other: %llu", + show_dev(__entry->dev), + __entry->comm, + __entry->pid, + __entry->prio, + __entry->ioprio_class, + __entry->ioprio_data, + show_lock_name(__entry->lock_name), + __entry->is_write ? "wlock" : "rlock", + __entry->total_time, + __entry->running_time, + __entry->runnable_time, + __entry->io_sleep_time, + __entry->other_time) +); + +DECLARE_EVENT_CLASS(f2fs_priority_update, + + TP_PROTO(struct f2fs_sb_info *sbi, enum f2fs_lock_name lock_name, + bool is_write, struct task_struct *p, int orig_prio, + int new_prio), + + TP_ARGS(sbi, lock_name, is_write, p, orig_prio, new_prio), + + TP_STRUCT__entry( + __field(dev_t, dev) + __array(char, comm, TASK_COMM_LEN) + __field(pid_t, pid) + __field(unsigned int, lock_name) + __field(bool, is_write) + __field(int, orig_prio) + __field(int, new_prio) + ), + + TP_fast_assign( + __entry->dev = sbi->sb->s_dev; + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); + __entry->pid = p->pid; + __entry->lock_name = lock_name; + __entry->is_write = is_write; + __entry->orig_prio = orig_prio; + __entry->new_prio = new_prio; + ), + + TP_printk("dev = (%d,%d), comm: %s, pid: %d, lock_name: %s, " + "lock_type: %s, orig_prio: %d, new_prio: %d", + show_dev(__entry->dev), + __entry->comm, + __entry->pid, + show_lock_name(__entry->lock_name), + __entry->is_write ? "wlock" : "rlock", + __entry->orig_prio, + __entry->new_prio) +); + +DEFINE_EVENT(f2fs_priority_update, f2fs_priority_uplift, + + TP_PROTO(struct f2fs_sb_info *sbi, enum f2fs_lock_name lock_name, + bool is_write, struct task_struct *p, int orig_prio, + int new_prio), + + TP_ARGS(sbi, lock_name, is_write, p, orig_prio, new_prio) +); + +DEFINE_EVENT(f2fs_priority_update, f2fs_priority_restore, + + TP_PROTO(struct f2fs_sb_info *sbi, enum f2fs_lock_name lock_name, + bool is_write, struct task_struct *p, int orig_prio, + int new_prio), + + TP_ARGS(sbi, lock_name, is_write, p, orig_prio, new_prio) +); + #endif /* _TRACE_F2FS_H */ /* This part must be outside protection */ diff --git a/include/trace/events/fsverity.h b/include/trace/events/fsverity.h new file mode 100644 index 000000000000..a8c52f21cbd5 --- /dev/null +++ b/include/trace/events/fsverity.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM fsverity + +#if !defined(_TRACE_FSVERITY_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_FSVERITY_H + +#include + +struct fsverity_descriptor; +struct merkle_tree_params; +struct fsverity_info; + +TRACE_EVENT(fsverity_enable, + TP_PROTO(const struct inode *inode, + const struct merkle_tree_params *params), + TP_ARGS(inode, params), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_size) + __field(u64, tree_size) + __field(unsigned int, merkle_block) + __field(unsigned int, num_levels) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_size = i_size_read(inode); + __entry->tree_size = params->tree_size; + __entry->merkle_block = params->block_size; + __entry->num_levels = params->num_levels; + ), + TP_printk("ino %lu data_size %llu tree_size %llu merkle_block %u levels %u", + (unsigned long) __entry->ino, + __entry->data_size, + __entry->tree_size, + __entry->merkle_block, + __entry->num_levels) +); + +TRACE_EVENT(fsverity_tree_done, + TP_PROTO(const struct inode *inode, const struct fsverity_info *vi, + const struct merkle_tree_params *params), + TP_ARGS(inode, vi, params), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_size) + __field(u64, tree_size) + __field(unsigned int, merkle_block) + __field(unsigned int, levels) + __dynamic_array(u8, root_hash, params->digest_size) + __dynamic_array(u8, file_digest, params->digest_size) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_size = i_size_read(inode); + __entry->tree_size = params->tree_size; + __entry->merkle_block = params->block_size; + __entry->levels = params->num_levels; + memcpy(__get_dynamic_array(root_hash), vi->root_hash, __get_dynamic_array_len(root_hash)); + memcpy(__get_dynamic_array(file_digest), vi->file_digest, __get_dynamic_array_len(file_digest)); + ), + TP_printk("ino %lu data_size %llu tree_size %lld merkle_block %u levels %u root_hash %s digest %s", + (unsigned long) __entry->ino, + __entry->data_size, + __entry->tree_size, + __entry->merkle_block, + __entry->levels, + __print_hex_str(__get_dynamic_array(root_hash), __get_dynamic_array_len(root_hash)), + __print_hex_str(__get_dynamic_array(file_digest), __get_dynamic_array_len(file_digest))) +); + +TRACE_EVENT(fsverity_verify_data_block, + TP_PROTO(const struct inode *inode, + const struct merkle_tree_params *params, + u64 data_pos), + TP_ARGS(inode, params, data_pos), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_pos) + __field(unsigned int, merkle_block) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_pos = data_pos; + __entry->merkle_block = params->block_size; + ), + TP_printk("ino %lu data_pos %llu merkle_block %u", + (unsigned long) __entry->ino, + __entry->data_pos, + __entry->merkle_block) +); + +TRACE_EVENT(fsverity_merkle_hit, + TP_PROTO(const struct inode *inode, u64 data_pos, + unsigned long hblock_idx, unsigned int level, + unsigned int hidx), + TP_ARGS(inode, data_pos, hblock_idx, level, hidx), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(u64, data_pos) + __field(unsigned long, hblock_idx) + __field(unsigned int, level) + __field(unsigned int, hidx) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->data_pos = data_pos; + __entry->hblock_idx = hblock_idx; + __entry->level = level; + __entry->hidx = hidx; + ), + TP_printk("ino %lu data_pos %llu hblock_idx %lu level %u hidx %u", + (unsigned long) __entry->ino, + __entry->data_pos, + __entry->hblock_idx, + __entry->level, + __entry->hidx) +); + +TRACE_EVENT(fsverity_verify_merkle_block, + TP_PROTO(const struct inode *inode, unsigned long hblock_idx, + unsigned int level, unsigned int hidx), + TP_ARGS(inode, hblock_idx, level, hidx), + TP_STRUCT__entry( + __field(ino_t, ino) + __field(unsigned long, hblock_idx) + __field(unsigned int, level) + __field(unsigned int, hidx) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->hblock_idx = hblock_idx; + __entry->level = level; + __entry->hidx = hidx; + ), + TP_printk("ino %lu hblock_idx %lu level %u hidx %u", + (unsigned long) __entry->ino, + __entry->hblock_idx, + __entry->level, + __entry->hidx) +); + +#endif /* _TRACE_FSVERITY_H */ + +/* This part must be outside protection */ +#include diff --git a/include/trace/events/kmem.h b/include/trace/events/kmem.h index 7f93e754da5c..cd7920c81f85 100644 --- a/include/trace/events/kmem.h +++ b/include/trace/events/kmem.h @@ -440,7 +440,13 @@ TRACE_EVENT(rss_stat, TP_fast_assign( __entry->mm_id = mm_ptr_to_hash(mm); - __entry->curr = !!(current->mm == mm); + /* + * curr is true if the mm matches the current task's mm_struct. + * Since kthreads (PF_KTHREAD) have no mm_struct of their own + * but can borrow one via kthread_use_mm(), we must filter them + * out to avoid incorrectly attributing the RSS update to them. + */ + __entry->curr = current->mm == mm && !(current->flags & PF_KTHREAD); __entry->member = member; __entry->size = (percpu_counter_sum_positive(&mm->rss_stat[member]) << PAGE_SHIFT); diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h index 64a382fbc31a..2d366be46a1c 100644 --- a/include/trace/events/netfs.h +++ b/include/trace/events/netfs.h @@ -57,6 +57,7 @@ EM(netfs_rreq_trace_done, "DONE ") \ EM(netfs_rreq_trace_end_copy_to_cache, "END-C2C") \ EM(netfs_rreq_trace_free, "FREE ") \ + EM(netfs_rreq_trace_intr, "INTR ") \ EM(netfs_rreq_trace_ki_complete, "KI-CMPL") \ EM(netfs_rreq_trace_recollect, "RECLLCT") \ EM(netfs_rreq_trace_redirty, "REDIRTY") \ @@ -169,7 +170,8 @@ EM(netfs_sreq_trace_put_oom, "PUT OOM ") \ EM(netfs_sreq_trace_put_wip, "PUT WIP ") \ EM(netfs_sreq_trace_put_work, "PUT WORK ") \ - E_(netfs_sreq_trace_put_terminated, "PUT TERM ") + EM(netfs_sreq_trace_put_terminated, "PUT TERM ") \ + E_(netfs_sreq_trace_see_failed, "SEE FAILED ") #define netfs_folio_traces \ EM(netfs_folio_is_uptodate, "mod-uptodate") \ diff --git a/include/trace/perf.h b/include/trace/perf.h index a1754b73a8f5..348ad1d9b556 100644 --- a/include/trace/perf.h +++ b/include/trace/perf.h @@ -71,6 +71,7 @@ perf_trace_##call(void *__data, proto) \ u64 __count __attribute__((unused)); \ struct task_struct *__task __attribute__((unused)); \ \ + guard(preempt_notrace)(); \ do_perf_trace_##call(__data, args); \ } @@ -85,9 +86,8 @@ perf_trace_##call(void *__data, proto) \ struct task_struct *__task __attribute__((unused)); \ \ might_fault(); \ - preempt_disable_notrace(); \ + guard(preempt_notrace)(); \ do_perf_trace_##call(__data, args); \ - preempt_enable_notrace(); \ } /* diff --git a/include/trace/stages/stage3_trace_output.h b/include/trace/stages/stage3_trace_output.h index 1e7b0bef95f5..fce85ea2df1c 100644 --- a/include/trace/stages/stage3_trace_output.h +++ b/include/trace/stages/stage3_trace_output.h @@ -39,7 +39,7 @@ void *__bitmask = __get_dynamic_array(field); \ unsigned int __bitmask_size; \ __bitmask_size = __get_dynamic_array_len(field); \ - trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ + trace_print_bitmask_seq(iter, __bitmask, __bitmask_size); \ }) #undef __get_cpumask @@ -51,7 +51,7 @@ void *__bitmask = __get_rel_dynamic_array(field); \ unsigned int __bitmask_size; \ __bitmask_size = __get_rel_dynamic_array_len(field); \ - trace_print_bitmask_seq(p, __bitmask, __bitmask_size); \ + trace_print_bitmask_seq(iter, __bitmask, __bitmask_size); \ }) #undef __get_rel_cpumask diff --git a/include/trace/trace_events.h b/include/trace/trace_events.h index 4f22136fd465..fbc07d353be6 100644 --- a/include/trace/trace_events.h +++ b/include/trace/trace_events.h @@ -436,6 +436,7 @@ __DECLARE_EVENT_CLASS(call, PARAMS(proto), PARAMS(args), PARAMS(tstruct), \ static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ { \ + guard(preempt_notrace)(); \ do_trace_event_raw_event_##call(__data, args); \ } @@ -447,9 +448,8 @@ static notrace void \ trace_event_raw_event_##call(void *__data, proto) \ { \ might_fault(); \ - preempt_disable_notrace(); \ + guard(preempt_notrace)(); \ do_trace_event_raw_event_##call(__data, args); \ - preempt_enable_notrace(); \ } /* diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h index 1d34daa0ebcd..ebbd861ef0bc 100644 --- a/include/uapi/drm/amdgpu_drm.h +++ b/include/uapi/drm/amdgpu_drm.h @@ -1667,6 +1667,7 @@ struct drm_amdgpu_info_uq_metadata { #define AMDGPU_FAMILY_GC_10_3_6 149 /* GC 10.3.6 */ #define AMDGPU_FAMILY_GC_10_3_7 151 /* GC 10.3.7 */ #define AMDGPU_FAMILY_GC_11_5_0 150 /* GC 11.5.0 */ +#define AMDGPU_FAMILY_GC_11_5_4 154 /* GC 11.5.4 */ #define AMDGPU_FAMILY_GC_12_0_0 152 /* GC 12.0.0 */ #if defined(__cplusplus) diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h index e527b24bd824..c89aede3cb12 100644 --- a/include/uapi/drm/drm_fourcc.h +++ b/include/uapi/drm/drm_fourcc.h @@ -401,8 +401,8 @@ extern "C" { * implementation can multiply the values by 2^6=64. For that reason the padding * must only contain zeros. * index 0 = Y plane, [15:0] z:Y [6:10] little endian - * index 1 = Cr plane, [15:0] z:Cr [6:10] little endian - * index 2 = Cb plane, [15:0] z:Cb [6:10] little endian + * index 1 = Cb plane, [15:0] z:Cb [6:10] little endian + * index 2 = Cr plane, [15:0] z:Cr [6:10] little endian */ #define DRM_FORMAT_S010 fourcc_code('S', '0', '1', '0') /* 2x2 subsampled Cb (1) and Cr (2) planes 10 bits per channel */ #define DRM_FORMAT_S210 fourcc_code('S', '2', '1', '0') /* 2x1 subsampled Cb (1) and Cr (2) planes 10 bits per channel */ @@ -414,8 +414,8 @@ extern "C" { * implementation can multiply the values by 2^4=16. For that reason the padding * must only contain zeros. * index 0 = Y plane, [15:0] z:Y [4:12] little endian - * index 1 = Cr plane, [15:0] z:Cr [4:12] little endian - * index 2 = Cb plane, [15:0] z:Cb [4:12] little endian + * index 1 = Cb plane, [15:0] z:Cb [4:12] little endian + * index 2 = Cr plane, [15:0] z:Cr [4:12] little endian */ #define DRM_FORMAT_S012 fourcc_code('S', '0', '1', '2') /* 2x2 subsampled Cb (1) and Cr (2) planes 12 bits per channel */ #define DRM_FORMAT_S212 fourcc_code('S', '2', '1', '2') /* 2x1 subsampled Cb (1) and Cr (2) planes 12 bits per channel */ @@ -424,8 +424,8 @@ extern "C" { /* * 3 plane YCbCr * index 0 = Y plane, [15:0] Y little endian - * index 1 = Cr plane, [15:0] Cr little endian - * index 2 = Cb plane, [15:0] Cb little endian + * index 1 = Cb plane, [15:0] Cb little endian + * index 2 = Cr plane, [15:0] Cr little endian */ #define DRM_FORMAT_S016 fourcc_code('S', '0', '1', '6') /* 2x2 subsampled Cb (1) and Cr (2) planes 16 bits per channel */ #define DRM_FORMAT_S216 fourcc_code('S', '2', '1', '6') /* 2x1 subsampled Cb (1) and Cr (2) planes 16 bits per channel */ diff --git a/include/uapi/linux/android/binder.h b/include/uapi/linux/android/binder.h index 03ee4c7010d7..701cad36de43 100644 --- a/include/uapi/linux/android/binder.h +++ b/include/uapi/linux/android/binder.h @@ -278,7 +278,7 @@ enum { * NOTE: Two special error codes you should check for when calling * in to the driver are: * - * EINTR -- The operation has been interupted. This should be + * EINTR -- The operation has been interrupted. This should be * handled by retrying the ioctl() until a different error code * is returned. * diff --git a/include/uapi/linux/dma-buf.h b/include/uapi/linux/dma-buf.h index 5a6fda66d9ad..e827c9d20c5d 100644 --- a/include/uapi/linux/dma-buf.h +++ b/include/uapi/linux/dma-buf.h @@ -20,6 +20,7 @@ #ifndef _DMA_BUF_UAPI_H_ #define _DMA_BUF_UAPI_H_ +#include #include /** diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 66ca526cf786..70b2b661f42c 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -253,6 +253,7 @@ struct file_attr { #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */ #define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */ +#define FS_XFLAG_VERITY 0x00020000 /* fs-verity enabled */ #define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* the read-only stuff doesn't really belong here, but any other place is diff --git a/include/uapi/linux/idxd.h b/include/uapi/linux/idxd.h index 3d1987e1bb2d..fdcc8eefb925 100644 --- a/include/uapi/linux/idxd.h +++ b/include/uapi/linux/idxd.h @@ -3,11 +3,7 @@ #ifndef _USR_IDXD_H_ #define _USR_IDXD_H_ -#ifdef __KERNEL__ #include -#else -#include -#endif /* Driver command error status */ enum idxd_scmd_stat { @@ -176,132 +172,132 @@ enum iax_completion_status { #define DSA_COMP_STATUS(status) ((status) & DSA_COMP_STATUS_MASK) struct dsa_hw_desc { - uint32_t pasid:20; - uint32_t rsvd:11; - uint32_t priv:1; - uint32_t flags:24; - uint32_t opcode:8; - uint64_t completion_addr; + __u32 pasid:20; + __u32 rsvd:11; + __u32 priv:1; + __u32 flags:24; + __u32 opcode:8; + __u64 completion_addr; union { - uint64_t src_addr; - uint64_t rdback_addr; - uint64_t pattern; - uint64_t desc_list_addr; - uint64_t pattern_lower; - uint64_t transl_fetch_addr; + __u64 src_addr; + __u64 rdback_addr; + __u64 pattern; + __u64 desc_list_addr; + __u64 pattern_lower; + __u64 transl_fetch_addr; }; union { - uint64_t dst_addr; - uint64_t rdback_addr2; - uint64_t src2_addr; - uint64_t comp_pattern; + __u64 dst_addr; + __u64 rdback_addr2; + __u64 src2_addr; + __u64 comp_pattern; }; union { - uint32_t xfer_size; - uint32_t desc_count; - uint32_t region_size; + __u32 xfer_size; + __u32 desc_count; + __u32 region_size; }; - uint16_t int_handle; - uint16_t rsvd1; + __u16 int_handle; + __u16 rsvd1; union { - uint8_t expected_res; + __u8 expected_res; /* create delta record */ struct { - uint64_t delta_addr; - uint32_t max_delta_size; - uint32_t delt_rsvd; - uint8_t expected_res_mask; + __u64 delta_addr; + __u32 max_delta_size; + __u32 delt_rsvd; + __u8 expected_res_mask; }; - uint32_t delta_rec_size; - uint64_t dest2; + __u32 delta_rec_size; + __u64 dest2; /* CRC */ struct { - uint32_t crc_seed; - uint32_t crc_rsvd; - uint64_t seed_addr; + __u32 crc_seed; + __u32 crc_rsvd; + __u64 seed_addr; }; /* DIF check or strip */ struct { - uint8_t src_dif_flags; - uint8_t dif_chk_res; - uint8_t dif_chk_flags; - uint8_t dif_chk_res2[5]; - uint32_t chk_ref_tag_seed; - uint16_t chk_app_tag_mask; - uint16_t chk_app_tag_seed; + __u8 src_dif_flags; + __u8 dif_chk_res; + __u8 dif_chk_flags; + __u8 dif_chk_res2[5]; + __u32 chk_ref_tag_seed; + __u16 chk_app_tag_mask; + __u16 chk_app_tag_seed; }; /* DIF insert */ struct { - uint8_t dif_ins_res; - uint8_t dest_dif_flag; - uint8_t dif_ins_flags; - uint8_t dif_ins_res2[13]; - uint32_t ins_ref_tag_seed; - uint16_t ins_app_tag_mask; - uint16_t ins_app_tag_seed; + __u8 dif_ins_res; + __u8 dest_dif_flag; + __u8 dif_ins_flags; + __u8 dif_ins_res2[13]; + __u32 ins_ref_tag_seed; + __u16 ins_app_tag_mask; + __u16 ins_app_tag_seed; }; /* DIF update */ struct { - uint8_t src_upd_flags; - uint8_t upd_dest_flags; - uint8_t dif_upd_flags; - uint8_t dif_upd_res[5]; - uint32_t src_ref_tag_seed; - uint16_t src_app_tag_mask; - uint16_t src_app_tag_seed; - uint32_t dest_ref_tag_seed; - uint16_t dest_app_tag_mask; - uint16_t dest_app_tag_seed; + __u8 src_upd_flags; + __u8 upd_dest_flags; + __u8 dif_upd_flags; + __u8 dif_upd_res[5]; + __u32 src_ref_tag_seed; + __u16 src_app_tag_mask; + __u16 src_app_tag_seed; + __u32 dest_ref_tag_seed; + __u16 dest_app_tag_mask; + __u16 dest_app_tag_seed; }; /* Fill */ - uint64_t pattern_upper; + __u64 pattern_upper; /* Translation fetch */ struct { - uint64_t transl_fetch_res; - uint32_t region_stride; + __u64 transl_fetch_res; + __u32 region_stride; }; /* DIX generate */ struct { - uint8_t dix_gen_res; - uint8_t dest_dif_flags; - uint8_t dif_flags; - uint8_t dix_gen_res2[13]; - uint32_t ref_tag_seed; - uint16_t app_tag_mask; - uint16_t app_tag_seed; + __u8 dix_gen_res; + __u8 dest_dif_flags; + __u8 dif_flags; + __u8 dix_gen_res2[13]; + __u32 ref_tag_seed; + __u16 app_tag_mask; + __u16 app_tag_seed; }; - uint8_t op_specific[24]; + __u8 op_specific[24]; }; } __attribute__((packed)); struct iax_hw_desc { - uint32_t pasid:20; - uint32_t rsvd:11; - uint32_t priv:1; - uint32_t flags:24; - uint32_t opcode:8; - uint64_t completion_addr; - uint64_t src1_addr; - uint64_t dst_addr; - uint32_t src1_size; - uint16_t int_handle; + __u32 pasid:20; + __u32 rsvd:11; + __u32 priv:1; + __u32 flags:24; + __u32 opcode:8; + __u64 completion_addr; + __u64 src1_addr; + __u64 dst_addr; + __u32 src1_size; + __u16 int_handle; union { - uint16_t compr_flags; - uint16_t decompr_flags; + __u16 compr_flags; + __u16 decompr_flags; }; - uint64_t src2_addr; - uint32_t max_dst_size; - uint32_t src2_size; - uint32_t filter_flags; - uint32_t num_inputs; + __u64 src2_addr; + __u32 max_dst_size; + __u32 src2_size; + __u32 filter_flags; + __u32 num_inputs; } __attribute__((packed)); struct dsa_raw_desc { - uint64_t field[8]; + __u64 field[8]; } __attribute__((packed)); /* @@ -309,91 +305,91 @@ struct dsa_raw_desc { * volatile and prevent the compiler from optimize the read. */ struct dsa_completion_record { - volatile uint8_t status; + volatile __u8 status; union { - uint8_t result; - uint8_t dif_status; + __u8 result; + __u8 dif_status; }; - uint8_t fault_info; - uint8_t rsvd; + __u8 fault_info; + __u8 rsvd; union { - uint32_t bytes_completed; - uint32_t descs_completed; + __u32 bytes_completed; + __u32 descs_completed; }; - uint64_t fault_addr; + __u64 fault_addr; union { /* common record */ struct { - uint32_t invalid_flags:24; - uint32_t rsvd2:8; + __u32 invalid_flags:24; + __u32 rsvd2:8; }; - uint32_t delta_rec_size; - uint64_t crc_val; + __u32 delta_rec_size; + __u64 crc_val; /* DIF check & strip */ struct { - uint32_t dif_chk_ref_tag; - uint16_t dif_chk_app_tag_mask; - uint16_t dif_chk_app_tag; + __u32 dif_chk_ref_tag; + __u16 dif_chk_app_tag_mask; + __u16 dif_chk_app_tag; }; /* DIF insert */ struct { - uint64_t dif_ins_res; - uint32_t dif_ins_ref_tag; - uint16_t dif_ins_app_tag_mask; - uint16_t dif_ins_app_tag; + __u64 dif_ins_res; + __u32 dif_ins_ref_tag; + __u16 dif_ins_app_tag_mask; + __u16 dif_ins_app_tag; }; /* DIF update */ struct { - uint32_t dif_upd_src_ref_tag; - uint16_t dif_upd_src_app_tag_mask; - uint16_t dif_upd_src_app_tag; - uint32_t dif_upd_dest_ref_tag; - uint16_t dif_upd_dest_app_tag_mask; - uint16_t dif_upd_dest_app_tag; + __u32 dif_upd_src_ref_tag; + __u16 dif_upd_src_app_tag_mask; + __u16 dif_upd_src_app_tag; + __u32 dif_upd_dest_ref_tag; + __u16 dif_upd_dest_app_tag_mask; + __u16 dif_upd_dest_app_tag; }; /* DIX generate */ struct { - uint64_t dix_gen_res; - uint32_t dix_ref_tag; - uint16_t dix_app_tag_mask; - uint16_t dix_app_tag; + __u64 dix_gen_res; + __u32 dix_ref_tag; + __u16 dix_app_tag_mask; + __u16 dix_app_tag; }; - uint8_t op_specific[16]; + __u8 op_specific[16]; }; } __attribute__((packed)); struct dsa_raw_completion_record { - uint64_t field[4]; + __u64 field[4]; } __attribute__((packed)); struct iax_completion_record { - volatile uint8_t status; - uint8_t error_code; - uint8_t fault_info; - uint8_t rsvd; - uint32_t bytes_completed; - uint64_t fault_addr; - uint32_t invalid_flags; - uint32_t rsvd2; - uint32_t output_size; - uint8_t output_bits; - uint8_t rsvd3; - uint16_t xor_csum; - uint32_t crc; - uint32_t min; - uint32_t max; - uint32_t sum; - uint64_t rsvd4[2]; + volatile __u8 status; + __u8 error_code; + __u8 fault_info; + __u8 rsvd; + __u32 bytes_completed; + __u64 fault_addr; + __u32 invalid_flags; + __u32 rsvd2; + __u32 output_size; + __u8 output_bits; + __u8 rsvd3; + __u16 xor_csum; + __u32 crc; + __u32 min; + __u32 max; + __u32 sum; + __u64 rsvd4[2]; } __attribute__((packed)); struct iax_raw_completion_record { - uint64_t field[8]; + __u64 field[8]; } __attribute__((packed)); #endif diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index fc473af6feb4..1ff16141c8a5 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -188,7 +188,8 @@ enum io_uring_sqe_flags_bit { /* * If COOP_TASKRUN is set, get notified if task work is available for * running and a kernel transition would be needed to run it. This sets - * IORING_SQ_TASKRUN in the sq ring flags. Not valid with COOP_TASKRUN. + * IORING_SQ_TASKRUN in the sq ring flags. Not valid without COOP_TASKRUN + * or DEFER_TASKRUN. */ #define IORING_SETUP_TASKRUN_FLAG (1U << 9) #define IORING_SETUP_SQE128 (1U << 10) /* SQEs are 128 byte */ @@ -1090,6 +1091,14 @@ enum zcrx_reg_flags { ZCRX_REG_IMPORT = 1, }; +enum zcrx_features { + /* + * The user can ask for the desired rx page size by passing the + * value in struct io_uring_zcrx_ifq_reg::rx_buf_len. + */ + ZCRX_FEATURE_RX_PAGE_SIZE = 1 << 0, +}; + /* * Argument for IORING_REGISTER_ZCRX_IFQ */ diff --git a/include/uapi/linux/io_uring/bpf_filter.h b/include/uapi/linux/io_uring/bpf_filter.h index 220351b81bc0..1b461d792a7b 100644 --- a/include/uapi/linux/io_uring/bpf_filter.h +++ b/include/uapi/linux/io_uring/bpf_filter.h @@ -35,13 +35,19 @@ enum { * If set, any currently unset opcode will have a deny filter attached */ IO_URING_BPF_FILTER_DENY_REST = 1, + /* + * If set, if kernel and application don't agree on pdu_size for + * the given opcode, fail the registration of the filter. + */ + IO_URING_BPF_FILTER_SZ_STRICT = 2, }; struct io_uring_bpf_filter { __u32 opcode; /* io_uring opcode to filter */ __u32 flags; __u32 filter_len; /* number of BPF instructions */ - __u32 resv; + __u8 pdu_size; /* expected pdu size for opcode */ + __u8 resv[3]; __u64 filter_ptr; /* pointer to BPF filter */ __u64 resv2[5]; }; diff --git a/include/uapi/linux/io_uring/query.h b/include/uapi/linux/io_uring/query.h index 2456e6c5ebb5..95500759cc13 100644 --- a/include/uapi/linux/io_uring/query.h +++ b/include/uapi/linux/io_uring/query.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: (GPL-2.0 WITH Linux-syscall-note) OR MIT */ /* * Header file for the io_uring query interface. + * + * Copyright (C) 2026 Pavel Begunkov + * Copyright (C) Meta Platforms, Inc. */ #ifndef LINUX_IO_URING_QUERY_H #define LINUX_IO_URING_QUERY_H @@ -50,7 +53,8 @@ struct io_uring_query_zcrx { __u64 area_flags; /* The number of supported ZCRX_CTRL_* opcodes */ __u32 nr_ctrl_opcodes; - __u32 __resv1; + /* Bitmask of ZCRX_FEATURE_* indicating which features are available */ + __u32 features; /* The refill ring header size */ __u32 rq_hdr_size; /* The alignment for the header */ diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 65500f5db379..80364d4dbebb 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -14,6 +14,10 @@ #include #include +#ifdef __KERNEL__ +#include +#endif + #define KVM_API_VERSION 12 /* @@ -1601,7 +1605,11 @@ struct kvm_stats_desc { __u16 size; __u32 offset; __u32 bucket_size; +#ifdef __KERNEL__ + char name[KVM_STATS_NAME_SIZE]; +#else char name[]; +#endif }; #define KVM_GET_STATS_FD _IO(KVMIO, 0xce) diff --git a/include/uapi/linux/mshv.h b/include/uapi/linux/mshv.h index dee3ece28ce5..e0645a34b55b 100644 --- a/include/uapi/linux/mshv.h +++ b/include/uapi/linux/mshv.h @@ -27,6 +27,8 @@ enum { MSHV_PT_BIT_X2APIC, MSHV_PT_BIT_GPA_SUPER_PAGES, MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES, + MSHV_PT_BIT_NESTED_VIRTUALIZATION, + MSHV_PT_BIT_SMT_ENABLED_GUEST, MSHV_PT_BIT_COUNT, }; diff --git a/include/uapi/linux/netfilter_bridge.h b/include/uapi/linux/netfilter_bridge.h index f6e8d1e05c97..758de72b2764 100644 --- a/include/uapi/linux/netfilter_bridge.h +++ b/include/uapi/linux/netfilter_bridge.h @@ -5,6 +5,10 @@ /* bridge-specific defines for netfilter. */ +#ifndef __KERNEL__ +#include /* for __UAPI_DEF_ETHHDR if defined */ +#endif + #include #include #include diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index ec1c54b5a310..14f634ab9350 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -712,7 +712,7 @@ #define PCI_EXP_LNKCTL2_HASD 0x0020 /* HW Autonomous Speed Disable */ #define PCI_EXP_LNKSTA2 0x32 /* Link Status 2 */ #define PCI_EXP_LNKSTA2_FLIT 0x0400 /* Flit Mode Status */ -#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x32 /* end of v2 EPs w/ link */ +#define PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 0x34 /* end of v2 EPs w/ link */ #define PCI_EXP_SLTCAP2 0x34 /* Slot Capabilities 2 */ #define PCI_EXP_SLTCAP2_IBPD 0x00000001 /* In-band PD Disable Supported */ #define PCI_EXP_SLTCTL2 0x38 /* Slot Control 2 */ diff --git a/include/uapi/linux/rseq.h b/include/uapi/linux/rseq.h index 863c4a00a66b..f69344fe6c08 100644 --- a/include/uapi/linux/rseq.h +++ b/include/uapi/linux/rseq.h @@ -87,10 +87,17 @@ struct rseq_slice_ctrl { }; /* - * struct rseq is aligned on 4 * 8 bytes to ensure it is always - * contained within a single cache-line. + * The original size and alignment of the allocation for struct rseq is + * 32 bytes. * - * A single struct rseq per thread is allowed. + * The allocation size needs to be greater or equal to + * max(getauxval(AT_RSEQ_FEATURE_SIZE), 32), and the allocation needs to + * be aligned on max(getauxval(AT_RSEQ_ALIGN), 32). + * + * As an alternative, userspace is allowed to use both the original size + * and alignment of 32 bytes for backward compatibility. + * + * A single active struct rseq registration per thread is allowed. */ struct rseq { /* @@ -180,10 +187,21 @@ struct rseq { */ struct rseq_slice_ctrl slice_ctrl; + /* + * Before rseq became extensible, its original size was 32 bytes even + * though the active rseq area was only 20 bytes. + * Exposing a 32 bytes feature size would make life needlessly painful + * for userspace. Therefore, add a reserved byte after byte 32 + * to bump the rseq feature size from 32 to 33. + * The next field to be added to the rseq area will be larger + * than one byte, and will replace this reserved byte. + */ + __u8 __reserved; + /* * Flexible array member at end of structure, after last feature field. */ char end[]; -} __attribute__((aligned(4 * sizeof(__u64)))); +} __attribute__((aligned(32))); #endif /* _UAPI_LINUX_RSEQ_H */ diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index c94caf852aea..8ca15743af7f 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h @@ -80,6 +80,7 @@ struct xenbus_device { const char *devicetype; const char *nodename; const char *otherend; + bool vanished; int otherend_id; struct xenbus_watch otherend_watch; struct device dev; @@ -228,7 +229,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr); int xenbus_alloc_evtchn(struct xenbus_device *dev, evtchn_port_t *port); int xenbus_free_evtchn(struct xenbus_device *dev, evtchn_port_t port); -enum xenbus_state xenbus_read_driver_state(const char *path); +enum xenbus_state xenbus_read_driver_state(const struct xenbus_device *dev, + const char *path); __printf(3, 4) void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...); diff --git a/init/Kconfig b/init/Kconfig index e95d43457851..444ce811ea67 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -150,6 +150,11 @@ config CC_HAS_COUNTED_BY_PTR # supported since gcc 16.0.0 default y if CC_IS_GCC && GCC_VERSION >= 160000 +config CC_HAS_BROKEN_COUNTED_BY_REF + bool + # https://github.com/llvm/llvm-project/issues/182575 + default y if CC_IS_CLANG && CLANG_VERSION < 220100 + config CC_HAS_MULTIDIMENSIONAL_NONSTRING def_bool $(success,echo 'char tag[][4] __attribute__((__nonstring__)) = { };' | $(CC) $(CLANG_FLAGS) -x c - -c -o /dev/null -Werror) @@ -1897,7 +1902,7 @@ config IO_URING_MOCK_FILE default n depends on IO_URING help - Enable mock files for io_uring subststem testing. The ABI might + Enable mock files for io_uring subsystem testing. The ABI might still change, so it's still experimental and should only be enabled for specific test purposes. diff --git a/init/initramfs.c b/init/initramfs.c index 6ddbfb17fb8f..139baed06589 100644 --- a/init/initramfs.c +++ b/init/initramfs.c @@ -102,7 +102,7 @@ static char __init *find_link(int major, int minor, int ino, continue; return (*p)->name; } - q = kmalloc(sizeof(struct hash), GFP_KERNEL); + q = kmalloc_obj(struct hash); if (!q) panic_show_mem("can't allocate link hash entry"); q->major = major; @@ -153,7 +153,7 @@ static void __init dir_add(const char *name, size_t nlen, time64_t mtime) { struct dir_entry *de; - de = kmalloc(struct_size(de, name, nlen), GFP_KERNEL); + de = kmalloc_flex(*de, name, nlen); if (!de) panic_show_mem("can't allocate dir_entry buffer"); INIT_LIST_HEAD(&de->list); @@ -517,7 +517,7 @@ char * __init unpack_to_rootfs(char *buf, unsigned long len) char header[CPIO_HDRLEN]; char symlink[PATH_MAX + N_ALIGN(PATH_MAX) + 1]; char name[N_ALIGN(PATH_MAX)]; - } *bufs = kmalloc(sizeof(*bufs), GFP_KERNEL); + } *bufs = kmalloc_obj(*bufs); if (!bufs) panic_show_mem("can't allocate buffers"); diff --git a/init/initramfs_test.c b/init/initramfs_test.c index beb6e3cf7808..2ce38d9a8fd0 100644 --- a/init/initramfs_test.c +++ b/init/initramfs_test.c @@ -403,7 +403,7 @@ static void __init initramfs_test_fname_pad(struct kunit *test) struct test_fname_pad { char padded_fname[4096 - CPIO_HDRLEN]; char cpio_srcbuf[CPIO_HDRLEN + PATH_MAX + 3 + sizeof(fdata)]; - } *tbufs = kzalloc(sizeof(struct test_fname_pad), GFP_KERNEL); + } *tbufs = kzalloc_obj(struct test_fname_pad); struct initramfs_test_cpio c[] = { { .magic = "070701", .ino = 1, @@ -457,7 +457,7 @@ static void __init initramfs_test_fname_path_max(struct kunit *test) char fname_oversize[PATH_MAX + 1]; char fname_ok[PATH_MAX]; char cpio_src[(CPIO_HDRLEN + PATH_MAX + 3 + sizeof(fdata)) * 2]; - } *tbufs = kzalloc(sizeof(struct test_fname_path_max), GFP_KERNEL); + } *tbufs = kzalloc_obj(struct test_fname_path_max); struct initramfs_test_cpio c[] = { { .magic = "070701", .ino = 1, diff --git a/io_uring/bpf_filter.c b/io_uring/bpf_filter.c index 3816883a45ed..c0037632b7af 100644 --- a/io_uring/bpf_filter.c +++ b/io_uring/bpf_filter.c @@ -26,6 +26,8 @@ static const struct io_bpf_filter dummy_filter; static void io_uring_populate_bpf_ctx(struct io_uring_bpf_ctx *bctx, struct io_kiocb *req) { + const struct io_issue_def *def = &io_issue_defs[req->opcode]; + bctx->opcode = req->opcode; bctx->sqe_flags = (__force int) req->flags & SQE_VALID_FLAGS; bctx->user_data = req->cqe.user_data; @@ -34,19 +36,12 @@ static void io_uring_populate_bpf_ctx(struct io_uring_bpf_ctx *bctx, sizeof(*bctx) - offsetof(struct io_uring_bpf_ctx, pdu_size)); /* - * Opcodes can provide a handler fo populating more data into bctx, + * Opcodes can provide a handler for populating more data into bctx, * for filters to use. */ - switch (req->opcode) { - case IORING_OP_SOCKET: - bctx->pdu_size = sizeof(bctx->socket); - io_socket_bpf_populate(bctx, req); - break; - case IORING_OP_OPENAT: - case IORING_OP_OPENAT2: - bctx->pdu_size = sizeof(bctx->open); - io_openat_bpf_populate(bctx, req); - break; + if (def->filter_pdu_size) { + bctx->pdu_size = def->filter_pdu_size; + def->filter_populate(bctx, req); } } @@ -90,7 +85,7 @@ int __io_uring_run_bpf_filters(struct io_bpf_filter __rcu **filters, do { if (filter == &dummy_filter) return -EACCES; - ret = bpf_prog_run(filter->prog, &bpf_ctx); + ret = bpf_prog_run_pin_on_cpu(filter->prog, &bpf_ctx); if (!ret) return -EACCES; filter = filter->next; @@ -157,13 +152,12 @@ static struct io_bpf_filters *io_new_bpf_filters(void) { struct io_bpf_filters *filters __free(kfree) = NULL; - filters = kzalloc(sizeof(*filters), GFP_KERNEL_ACCOUNT); + filters = kzalloc_obj(*filters, GFP_KERNEL_ACCOUNT); if (!filters) return ERR_PTR(-ENOMEM); - filters->filters = kcalloc(IORING_OP_LAST, - sizeof(struct io_bpf_filter *), - GFP_KERNEL_ACCOUNT); + filters->filters = kzalloc_objs(struct io_bpf_filter *, IORING_OP_LAST, + GFP_KERNEL_ACCOUNT); if (!filters->filters) return ERR_PTR(-ENOMEM); @@ -313,7 +307,54 @@ static struct io_bpf_filters *io_bpf_filter_cow(struct io_restriction *src) return ERR_PTR(-EBUSY); } -#define IO_URING_BPF_FILTER_FLAGS IO_URING_BPF_FILTER_DENY_REST +#define IO_URING_BPF_FILTER_FLAGS (IO_URING_BPF_FILTER_DENY_REST | \ + IO_URING_BPF_FILTER_SZ_STRICT) + +static int io_bpf_filter_import(struct io_uring_bpf *reg, + struct io_uring_bpf __user *arg) +{ + const struct io_issue_def *def; + int ret; + + if (copy_from_user(reg, arg, sizeof(*reg))) + return -EFAULT; + if (reg->cmd_type != IO_URING_BPF_CMD_FILTER) + return -EINVAL; + if (reg->cmd_flags || reg->resv) + return -EINVAL; + + if (reg->filter.opcode >= IORING_OP_LAST) + return -EINVAL; + if (reg->filter.flags & ~IO_URING_BPF_FILTER_FLAGS) + return -EINVAL; + if (!mem_is_zero(reg->filter.resv, sizeof(reg->filter.resv))) + return -EINVAL; + if (!mem_is_zero(reg->filter.resv2, sizeof(reg->filter.resv2))) + return -EINVAL; + if (!reg->filter.filter_len || reg->filter.filter_len > BPF_MAXINSNS) + return -EINVAL; + + /* Verify filter size */ + def = &io_issue_defs[array_index_nospec(reg->filter.opcode, IORING_OP_LAST)]; + + /* same size, always ok */ + ret = 0; + if (reg->filter.pdu_size == def->filter_pdu_size) + ; + /* size differs, fail in strict mode */ + else if (reg->filter.flags & IO_URING_BPF_FILTER_SZ_STRICT) + ret = -EMSGSIZE; + /* userspace filter is bigger, always disallow */ + else if (reg->filter.pdu_size > def->filter_pdu_size) + ret = -EMSGSIZE; + + /* copy back kernel filter size */ + reg->filter.pdu_size = def->filter_pdu_size; + if (copy_to_user(&arg->filter, ®->filter, sizeof(reg->filter))) + return -EFAULT; + + return ret; +} int io_register_bpf_filter(struct io_restriction *res, struct io_uring_bpf __user *arg) @@ -325,23 +366,9 @@ int io_register_bpf_filter(struct io_restriction *res, struct sock_fprog fprog; int ret; - if (copy_from_user(®, arg, sizeof(reg))) - return -EFAULT; - if (reg.cmd_type != IO_URING_BPF_CMD_FILTER) - return -EINVAL; - if (reg.cmd_flags || reg.resv) - return -EINVAL; - - if (reg.filter.opcode >= IORING_OP_LAST) - return -EINVAL; - if (reg.filter.flags & ~IO_URING_BPF_FILTER_FLAGS) - return -EINVAL; - if (reg.filter.resv) - return -EINVAL; - if (!mem_is_zero(reg.filter.resv2, sizeof(reg.filter.resv2))) - return -EINVAL; - if (!reg.filter.filter_len || reg.filter.filter_len > BPF_MAXINSNS) - return -EINVAL; + ret = io_bpf_filter_import(®, arg); + if (ret) + return ret; fprog.len = reg.filter.filter_len; fprog.filter = u64_to_user_ptr(reg.filter.filter_ptr); @@ -374,7 +401,7 @@ int io_register_bpf_filter(struct io_restriction *res, old_filters = res->bpf_filters; } - filter = kzalloc(sizeof(*filter), GFP_KERNEL_ACCOUNT); + filter = kzalloc_obj(*filter, GFP_KERNEL_ACCOUNT); if (!filter) { ret = -ENOMEM; goto err; diff --git a/io_uring/cancel.h b/io_uring/cancel.h index 6783961ede1b..1b201a094303 100644 --- a/io_uring/cancel.h +++ b/io_uring/cancel.h @@ -6,10 +6,8 @@ struct io_cancel_data { struct io_ring_ctx *ctx; - union { - u64 data; - struct file *file; - }; + u64 data; + struct file *file; u8 opcode; u32 flags; int seq; diff --git a/io_uring/cmd_net.c b/io_uring/cmd_net.c index cb2775936fb8..125a81c520a6 100644 --- a/io_uring/cmd_net.c +++ b/io_uring/cmd_net.c @@ -146,7 +146,7 @@ static int io_uring_cmd_getsockname(struct socket *sock, return -EINVAL; uaddr = u64_to_user_ptr(READ_ONCE(sqe->addr)); - ulen = u64_to_user_ptr(sqe->addr3); + ulen = u64_to_user_ptr(READ_ONCE(sqe->addr3)); peer = READ_ONCE(sqe->optlen); if (peer > 1) return -EINVAL; @@ -160,16 +160,19 @@ int io_uring_cmd_sock(struct io_uring_cmd *cmd, unsigned int issue_flags) struct proto *prot = READ_ONCE(sk->sk_prot); int ret, arg = 0; - if (!prot || !prot->ioctl) - return -EOPNOTSUPP; - switch (cmd->cmd_op) { case SOCKET_URING_OP_SIOCINQ: + if (!prot || !prot->ioctl) + return -EOPNOTSUPP; + ret = prot->ioctl(sk, SIOCINQ, &arg); if (ret) return ret; return arg; case SOCKET_URING_OP_SIOCOUTQ: + if (!prot || !prot->ioctl) + return -EOPNOTSUPP; + ret = prot->ioctl(sk, SIOCOUTQ, &arg); if (ret) return ret; diff --git a/io_uring/eventfd.c b/io_uring/eventfd.c index 78f8ab7db104..7482a7dc6b38 100644 --- a/io_uring/eventfd.c +++ b/io_uring/eventfd.c @@ -76,11 +76,15 @@ void io_eventfd_signal(struct io_ring_ctx *ctx, bool cqe_event) { bool skip = false; struct io_ev_fd *ev_fd; - - if (READ_ONCE(ctx->rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED) - return; + struct io_rings *rings; guard(rcu)(); + + rings = rcu_dereference(ctx->rings_rcu); + if (!rings) + return; + if (READ_ONCE(rings->cq_flags) & IORING_CQ_EVENTFD_DISABLED) + return; ev_fd = rcu_dereference(ctx->io_ev_fd); /* * Check again if ev_fd exists in case an io_eventfd_unregister call @@ -127,7 +131,7 @@ int io_eventfd_register(struct io_ring_ctx *ctx, void __user *arg, if (copy_from_user(&fd, fds, sizeof(*fds))) return -EFAULT; - ev_fd = kmalloc(sizeof(*ev_fd), GFP_KERNEL); + ev_fd = kmalloc_obj(*ev_fd); if (!ev_fd) return -ENOMEM; diff --git a/io_uring/filetable.c b/io_uring/filetable.c index 794ef95df293..cb1838c9fc37 100644 --- a/io_uring/filetable.c +++ b/io_uring/filetable.c @@ -22,6 +22,10 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx) if (!table->bitmap) return -ENFILE; + if (table->alloc_hint < ctx->file_alloc_start || + table->alloc_hint >= ctx->file_alloc_end) + table->alloc_hint = ctx->file_alloc_start; + do { ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint); if (ret != nr) diff --git a/io_uring/futex.c b/io_uring/futex.c index 1dabcfd503b8..fd503c24b428 100644 --- a/io_uring/futex.c +++ b/io_uring/futex.c @@ -185,8 +185,8 @@ int io_futexv_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) if (!iof->futex_nr || iof->futex_nr > FUTEX_WAITV_MAX) return -EINVAL; - ifd = kzalloc(struct_size_t(struct io_futexv_data, futexv, iof->futex_nr), - GFP_KERNEL_ACCOUNT); + ifd = kzalloc_flex(struct io_futexv_data, futexv, iof->futex_nr, + GFP_KERNEL_ACCOUNT); if (!ifd) return -ENOMEM; diff --git a/io_uring/io-wq.c b/io_uring/io-wq.c index 7ed04911f7b9..7a9f94a0ce6f 100644 --- a/io_uring/io-wq.c +++ b/io_uring/io-wq.c @@ -897,7 +897,7 @@ static bool create_io_worker(struct io_wq *wq, struct io_wq_acct *acct) __set_current_state(TASK_RUNNING); - worker = kzalloc(sizeof(*worker), GFP_KERNEL); + worker = kzalloc_obj(*worker); if (!worker) { fail: atomic_dec(&acct->nr_running); @@ -1255,7 +1255,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) if (WARN_ON_ONCE(!bounded)) return ERR_PTR(-EINVAL); - wq = kzalloc(sizeof(struct io_wq), GFP_KERNEL); + wq = kzalloc_obj(struct io_wq); if (!wq) return ERR_PTR(-ENOMEM); diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 1d5bc669afd9..9a37035e76c0 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -119,7 +119,7 @@ static void io_queue_sqe(struct io_kiocb *req, unsigned int extra_flags); static void __io_req_caches_free(struct io_ring_ctx *ctx); -static __read_mostly DEFINE_STATIC_KEY_FALSE(io_key_has_sqarray); +static __read_mostly DEFINE_STATIC_KEY_DEFERRED_FALSE(io_key_has_sqarray, HZ); struct kmem_cache *req_cachep; static struct workqueue_struct *iou_wq __ro_after_init; @@ -195,8 +195,8 @@ static int io_alloc_hash_table(struct io_hash_table *table, unsigned bits) do { hash_buckets = 1U << bits; - table->hbs = kvmalloc_array(hash_buckets, sizeof(table->hbs[0]), - GFP_KERNEL_ACCOUNT); + table->hbs = kvmalloc_objs(table->hbs[0], hash_buckets, + GFP_KERNEL_ACCOUNT); if (table->hbs) break; if (bits == 1) @@ -226,7 +226,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p) int hash_bits; bool ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -1330,7 +1330,7 @@ static __cold void io_drain_req(struct io_kiocb *req) bool drain = req->flags & IOSQE_IO_DRAIN; struct io_defer_entry *de; - de = kmalloc(sizeof(*de), GFP_KERNEL_ACCOUNT); + de = kmalloc_obj(*de, GFP_KERNEL_ACCOUNT); if (!de) { io_req_defer_failed(req, -ENOMEM); return; @@ -1745,7 +1745,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req, * well as 2 contiguous entries. */ if (!(ctx->flags & IORING_SETUP_SQE_MIXED) || *left < 2 || - !(ctx->cached_sq_head & (ctx->sq_entries - 1))) + (unsigned)(sqe - ctx->sq_sqes) >= ctx->sq_entries - 1) return io_init_fail_req(req, -EINVAL); /* * A 128b operation on a mixed SQ uses two entries, so we have @@ -1978,7 +1978,7 @@ static bool io_get_sqe(struct io_ring_ctx *ctx, const struct io_uring_sqe **sqe) unsigned mask = ctx->sq_entries - 1; unsigned head = ctx->cached_sq_head++ & mask; - if (static_branch_unlikely(&io_key_has_sqarray) && + if (static_branch_unlikely(&io_key_has_sqarray.key) && (!(ctx->flags & IORING_SETUP_NO_SQARRAY))) { head = READ_ONCE(ctx->sq_array[head]); if (unlikely(head >= ctx->sq_entries)) { @@ -2066,6 +2066,7 @@ static void io_rings_free(struct io_ring_ctx *ctx) io_free_region(ctx->user, &ctx->sq_region); io_free_region(ctx->user, &ctx->ring_region); ctx->rings = NULL; + RCU_INIT_POINTER(ctx->rings_rcu, NULL); ctx->sq_sqes = NULL; } @@ -2173,7 +2174,7 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx) io_rings_free(ctx); if (!(ctx->flags & IORING_SETUP_NO_SQARRAY)) - static_branch_dec(&io_key_has_sqarray); + static_branch_slow_dec_deferred(&io_key_has_sqarray); percpu_ref_exit(&ctx->refs); free_uid(ctx->user); @@ -2398,7 +2399,7 @@ static __cold void io_ring_exit_work(struct work_struct *work) static __cold void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx) { unsigned long index; - struct creds *creds; + struct cred *creds; mutex_lock(&ctx->uring_lock); percpu_ref_kill(&ctx->refs); @@ -2703,6 +2704,7 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx, if (ret) return ret; ctx->rings = rings = io_region_get_ptr(&ctx->ring_region); + rcu_assign_pointer(ctx->rings_rcu, rings); if (!(ctx->flags & IORING_SETUP_NO_SQARRAY)) ctx->sq_array = (u32 *)((char *)rings + rl->sq_array_offset); @@ -2946,11 +2948,10 @@ static __cold int io_uring_create(struct io_ctx_config *config) ctx->clock_offset = 0; if (!(ctx->flags & IORING_SETUP_NO_SQARRAY)) - static_branch_inc(&io_key_has_sqarray); + static_branch_deferred_inc(&io_key_has_sqarray); if ((ctx->flags & IORING_SETUP_DEFER_TASKRUN) && - !(ctx->flags & IORING_SETUP_IOPOLL) && - !(ctx->flags & IORING_SETUP_SQPOLL)) + !(ctx->flags & IORING_SETUP_IOPOLL)) ctx->task_complete = true; if (ctx->task_complete || (ctx->flags & IORING_SETUP_IOPOLL)) diff --git a/io_uring/io_uring.h b/io_uring/io_uring.h index 503663d6fd6d..0fa844faf287 100644 --- a/io_uring/io_uring.h +++ b/io_uring/io_uring.h @@ -530,6 +530,12 @@ static inline bool io_file_can_poll(struct io_kiocb *req) return false; } +static inline bool io_is_uring_cmd(const struct io_kiocb *req) +{ + return req->opcode == IORING_OP_URING_CMD || + req->opcode == IORING_OP_URING_CMD128; +} + static inline ktime_t io_get_time(struct io_ring_ctx *ctx) { if (ctx->clockid == CLOCK_MONOTONIC) diff --git a/io_uring/kbuf.c b/io_uring/kbuf.c index 67d4fe576473..26813b0f1dfd 100644 --- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -111,9 +111,18 @@ bool io_kbuf_recycle_legacy(struct io_kiocb *req, unsigned issue_flags) buf = req->kbuf; bl = io_buffer_get_list(ctx, buf->bgid); - list_add(&buf->list, &bl->buf_list); - bl->nbufs++; + /* + * If the buffer list was upgraded to a ring-based one, or removed, + * while the request was in-flight in io-wq, drop it. + */ + if (bl && !(bl->flags & IOBL_BUF_RING)) { + list_add(&buf->list, &bl->buf_list); + bl->nbufs++; + } else { + kfree(buf); + } req->flags &= ~REQ_F_BUFFER_SELECTED; + req->kbuf = NULL; io_ring_submit_unlock(ctx, issue_flags); return true; @@ -171,7 +180,7 @@ static bool io_should_commit(struct io_kiocb *req, unsigned int issue_flags) return true; /* uring_cmd commits kbuf upfront, no need to auto-commit */ - if (!io_file_can_poll(req) && req->opcode != IORING_OP_URING_CMD) + if (!io_file_can_poll(req) && !io_is_uring_cmd(req)) return true; return false; } @@ -265,7 +274,7 @@ static int io_ring_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, * a speculative peek operation. */ if (arg->mode & KBUF_MODE_EXPAND && nr_avail > nr_iovs && arg->max_len) { - iov = kmalloc_array(nr_avail, sizeof(struct iovec), GFP_KERNEL); + iov = kmalloc_objs(struct iovec, nr_avail); if (unlikely(!iov)) return -ENOMEM; if (arg->mode & KBUF_MODE_FREE) @@ -532,7 +541,7 @@ static int io_add_buffers(struct io_ring_ctx *ctx, struct io_provide_buf *pbuf, ret = -EOVERFLOW; break; } - buf = kmalloc(sizeof(*buf), GFP_KERNEL_ACCOUNT); + buf = kmalloc_obj(*buf, GFP_KERNEL_ACCOUNT); if (!buf) break; @@ -559,7 +568,7 @@ static int __io_manage_buffers_legacy(struct io_kiocb *req, if (!bl) { if (req->opcode != IORING_OP_PROVIDE_BUFFERS) return -ENOENT; - bl = kzalloc(sizeof(*bl), GFP_KERNEL_ACCOUNT); + bl = kzalloc_obj(*bl, GFP_KERNEL_ACCOUNT); if (!bl) return -ENOMEM; @@ -628,7 +637,7 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg) io_destroy_bl(ctx, bl); } - bl = kzalloc(sizeof(*bl), GFP_KERNEL_ACCOUNT); + bl = kzalloc_obj(*bl, GFP_KERNEL_ACCOUNT); if (!bl) return -ENOMEM; diff --git a/io_uring/memmap.c b/io_uring/memmap.c index 89f56609e50a..e6958968975a 100644 --- a/io_uring/memmap.c +++ b/io_uring/memmap.c @@ -56,7 +56,7 @@ struct page **io_pin_pages(unsigned long uaddr, unsigned long len, int *npages) if (WARN_ON_ONCE(nr_pages > INT_MAX)) return ERR_PTR(-EOVERFLOW); - pages = kvmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL_ACCOUNT); + pages = kvmalloc_objs(struct page *, nr_pages, GFP_KERNEL_ACCOUNT); if (!pages) return ERR_PTR(-ENOMEM); @@ -158,7 +158,7 @@ static int io_region_allocate_pages(struct io_mapped_region *mr, unsigned long nr_allocated; struct page **pages; - pages = kvmalloc_array(mr->nr_pages, sizeof(*pages), gfp); + pages = kvmalloc_objs(*pages, mr->nr_pages, gfp); if (!pages) return -ENOMEM; diff --git a/io_uring/mock_file.c b/io_uring/mock_file.c index 80c96ad2061f..b318ed697998 100644 --- a/io_uring/mock_file.c +++ b/io_uring/mock_file.c @@ -115,7 +115,7 @@ static ssize_t io_mock_delay_rw(struct kiocb *iocb, size_t len) struct io_mock_file *mf = iocb->ki_filp->private_data; struct io_mock_iocb *mio; - mio = kzalloc(sizeof(*mio), GFP_KERNEL); + mio = kzalloc_obj(*mio); if (!mio) return -ENOMEM; @@ -242,7 +242,7 @@ static int io_create_mock_file(struct io_uring_cmd *cmd, unsigned int issue_flag if (mc.rw_delay_ns > NSEC_PER_SEC) return -EINVAL; - mf = kzalloc(sizeof(*mf), GFP_KERNEL_ACCOUNT); + mf = kzalloc_obj(*mf, GFP_KERNEL_ACCOUNT); if (!mf) return -ENOMEM; diff --git a/io_uring/net.c b/io_uring/net.c index a6f3cbb7dfea..d27adbe3f20b 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -375,6 +375,8 @@ static int io_send_setup(struct io_kiocb *req, const struct io_uring_sqe *sqe) kmsg->msg.msg_namelen = addr_len; } if (sr->flags & IORING_RECVSEND_FIXED_BUF) { + if (sr->flags & IORING_SEND_VECTORIZED) + return -EINVAL; req->flags |= REQ_F_IMPORT_BUFFER; return 0; } @@ -1493,8 +1495,6 @@ int io_send_zc(struct io_kiocb *req, unsigned int issue_flags) return -EAGAIN; if (ret > 0 && io_net_retry(sock, kmsg->msg.msg_flags)) { - zc->len -= ret; - zc->buf += ret; zc->done_io += ret; return -EAGAIN; } diff --git a/io_uring/opdef.c b/io_uring/opdef.c index df52d760240e..91a23baf415e 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -221,8 +221,10 @@ const struct io_issue_def io_issue_defs[] = { .issue = io_fallocate, }, [IORING_OP_OPENAT] = { + .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, open), .prep = io_openat_prep, .issue = io_openat, + .filter_populate = io_openat_bpf_populate, }, [IORING_OP_CLOSE] = { .prep = io_close_prep, @@ -309,8 +311,10 @@ const struct io_issue_def io_issue_defs[] = { #endif }, [IORING_OP_OPENAT2] = { + .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, open), .prep = io_openat2_prep, .issue = io_openat2, + .filter_populate = io_openat_bpf_populate, }, [IORING_OP_EPOLL_CTL] = { .unbound_nonreg_file = 1, @@ -406,8 +410,10 @@ const struct io_issue_def io_issue_defs[] = { [IORING_OP_SOCKET] = { .audit_skip = 1, #if defined(CONFIG_NET) + .filter_pdu_size = sizeof_field(struct io_uring_bpf_ctx, socket), .prep = io_socket_prep, .issue = io_socket, + .filter_populate = io_socket_bpf_populate, #else .prep = io_eopnotsupp_prep, #endif diff --git a/io_uring/opdef.h b/io_uring/opdef.h index aa37846880ff..faf3955dce8b 100644 --- a/io_uring/opdef.h +++ b/io_uring/opdef.h @@ -2,6 +2,8 @@ #ifndef IOU_OP_DEF_H #define IOU_OP_DEF_H +struct io_uring_bpf_ctx; + struct io_issue_def { /* needs req->file assigned */ unsigned needs_file : 1; @@ -33,8 +35,12 @@ struct io_issue_def { /* size of async data needed, if any */ unsigned short async_size; + /* bpf filter pdu size, if any */ + unsigned short filter_pdu_size; + int (*issue)(struct io_kiocb *, unsigned int); int (*prep)(struct io_kiocb *, const struct io_uring_sqe *); + void (*filter_populate)(struct io_uring_bpf_ctx *, struct io_kiocb *); }; struct io_cold_def { diff --git a/io_uring/openclose.c b/io_uring/openclose.c index d617b421b1e6..c71242915dad 100644 --- a/io_uring/openclose.c +++ b/io_uring/openclose.c @@ -345,31 +345,34 @@ static int io_pipe_fixed(struct io_kiocb *req, struct file **files, { struct io_pipe *p = io_kiocb_to_cmd(req, struct io_pipe); struct io_ring_ctx *ctx = req->ctx; + bool alloc_slot; int ret, fds[2] = { -1, -1 }; int slot = p->file_slot; if (p->flags & O_CLOEXEC) return -EINVAL; + alloc_slot = slot == IORING_FILE_INDEX_ALLOC; + io_ring_submit_lock(ctx, issue_flags); ret = __io_fixed_fd_install(ctx, files[0], slot); if (ret < 0) goto err; - fds[0] = ret; + fds[0] = alloc_slot ? ret : slot - 1; files[0] = NULL; /* * If a specific slot is given, next one will be used for * the write side. */ - if (slot != IORING_FILE_INDEX_ALLOC) + if (!alloc_slot) slot++; ret = __io_fixed_fd_install(ctx, files[1], slot); if (ret < 0) goto err; - fds[1] = ret; + fds[1] = alloc_slot ? ret : slot - 1; files[1] = NULL; io_ring_submit_unlock(ctx, issue_flags); diff --git a/io_uring/poll.c b/io_uring/poll.c index aac4b3b881fb..b671b84657d9 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -478,7 +478,7 @@ static void __io_queue_proc(struct io_poll *poll, struct io_poll_table *pt, return; } - poll = kmalloc(sizeof(*poll), GFP_ATOMIC); + poll = kmalloc_obj(*poll, GFP_ATOMIC); if (!poll) { pt->error = -ENOMEM; return; @@ -655,7 +655,7 @@ static struct async_poll *io_req_alloc_apoll(struct io_kiocb *req, if (!(issue_flags & IO_URING_F_UNLOCKED)) apoll = io_cache_alloc(&ctx->apoll_cache, GFP_ATOMIC); else - apoll = kmalloc(sizeof(*apoll), GFP_ATOMIC); + apoll = kmalloc_obj(*apoll, GFP_ATOMIC); if (!apoll) return NULL; apoll->poll.retries = APOLL_MAX_RETRY; diff --git a/io_uring/query.c b/io_uring/query.c index abdd6f3e1223..63cc30c9803d 100644 --- a/io_uring/query.c +++ b/io_uring/query.c @@ -39,7 +39,7 @@ static ssize_t io_query_zcrx(union io_query_data *data) e->nr_ctrl_opcodes = __ZCRX_CTRL_LAST; e->rq_hdr_size = sizeof(struct io_uring); e->rq_hdr_alignment = L1_CACHE_BYTES; - e->__resv1 = 0; + e->features = ZCRX_FEATURE_RX_PAGE_SIZE; e->__resv2 = 0; return sizeof(*e); } diff --git a/io_uring/register.c b/io_uring/register.c index 594b1f2ce875..0148735f7711 100644 --- a/io_uring/register.c +++ b/io_uring/register.c @@ -202,7 +202,7 @@ static int io_register_restrictions_task(void __user *arg, unsigned int nr_args) return -EPERM; /* * Similar to seccomp, disallow setting a filter if task_no_new_privs - * is true and we're not CAP_SYS_ADMIN. + * is false and we're not CAP_SYS_ADMIN. */ if (!task_no_new_privs(current) && !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) @@ -218,7 +218,7 @@ static int io_register_restrictions_task(void __user *arg, unsigned int nr_args) if (!mem_is_zero(tres.resv, sizeof(tres.resv))) return -EINVAL; - res = kzalloc(sizeof(*res), GFP_KERNEL_ACCOUNT); + res = kzalloc_obj(*res, GFP_KERNEL_ACCOUNT); if (!res) return -ENOMEM; @@ -238,7 +238,7 @@ static int io_register_bpf_filter_task(void __user *arg, unsigned int nr_args) /* * Similar to seccomp, disallow setting a filter if task_no_new_privs - * is true and we're not CAP_SYS_ADMIN. + * is false and we're not CAP_SYS_ADMIN. */ if (!task_no_new_privs(current) && !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) @@ -250,7 +250,7 @@ static int io_register_bpf_filter_task(void __user *arg, unsigned int nr_args) /* If no task restrictions exist, setup a new set */ res = current->io_uring_restrict; if (!res) { - res = kzalloc(sizeof(*res), GFP_KERNEL_ACCOUNT); + res = kzalloc_obj(*res, GFP_KERNEL_ACCOUNT); if (!res) return -ENOMEM; } @@ -633,7 +633,15 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg) ctx->sq_entries = p->sq_entries; ctx->cq_entries = p->cq_entries; + /* + * Just mark any flag we may have missed and that the application + * should act on unconditionally. Worst case it'll be an extra + * syscall. + */ + atomic_or(IORING_SQ_TASKRUN | IORING_SQ_NEED_WAKEUP, &n.rings->sq_flags); ctx->rings = n.rings; + rcu_assign_pointer(ctx->rings_rcu, n.rings); + ctx->sq_sqes = n.sq_sqes; swap_old(ctx, o, n, ring_region); swap_old(ctx, o, n, sq_region); @@ -642,6 +650,9 @@ static int io_register_resize_rings(struct io_ring_ctx *ctx, void __user *arg) out: spin_unlock(&ctx->completion_lock); mutex_unlock(&ctx->mmap_lock); + /* Wait for concurrent io_ctx_mark_taskrun() */ + if (to_free == &o) + synchronize_rcu_expedited(); io_register_free_rings(ctx, to_free); if (ctx->sq_data) diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 95ce553fff8d..4fa59bf89bba 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -96,20 +96,6 @@ int io_validate_user_buf_range(u64 uaddr, u64 ulen) return 0; } -static int io_buffer_validate(struct iovec *iov) -{ - /* - * Don't impose further limits on the size and buffer - * constraints here, we'll -EINVAL later when IO is - * submitted if they are wrong. - */ - if (!iov->iov_base) - return iov->iov_len ? -EFAULT : 0; - - return io_validate_user_buf_range((unsigned long)iov->iov_base, - iov->iov_len); -} - static void io_release_ubuf(void *priv) { struct io_mapped_ubuf *imu = priv; @@ -127,8 +113,7 @@ static struct io_mapped_ubuf *io_alloc_imu(struct io_ring_ctx *ctx, { if (nr_bvecs <= IO_CACHED_BVECS_SEGS) return io_cache_alloc(&ctx->imu_cache, GFP_KERNEL); - return kvmalloc(struct_size_t(struct io_mapped_ubuf, bvec, nr_bvecs), - GFP_KERNEL); + return kvmalloc_flex(struct io_mapped_ubuf, bvec, nr_bvecs); } static void io_free_imu(struct io_ring_ctx *ctx, struct io_mapped_ubuf *imu) @@ -214,8 +199,8 @@ __cold void io_rsrc_data_free(struct io_ring_ctx *ctx, __cold int io_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr) { - data->nodes = kvmalloc_array(nr, sizeof(struct io_rsrc_node *), - GFP_KERNEL_ACCOUNT | __GFP_ZERO); + data->nodes = kvmalloc_objs(struct io_rsrc_node *, nr, + GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (data->nodes) { data->nr = nr; return 0; @@ -319,9 +304,6 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx, err = -EFAULT; break; } - err = io_buffer_validate(iov); - if (err) - break; node = io_sqe_buffer_register(ctx, iov, &last_hpage); if (IS_ERR(node)) { err = PTR_ERR(node); @@ -701,7 +683,7 @@ static bool io_coalesce_buffer(struct page ***pages, int *nr_pages, unsigned i, j; /* Store head pages only*/ - new_array = kvmalloc_array(nr_folios, sizeof(struct page *), GFP_KERNEL); + new_array = kvmalloc_objs(struct page *, nr_folios); if (!new_array) return false; @@ -790,8 +772,17 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, struct io_imu_folio_data data; bool coalesced = false; - if (!iov->iov_base) + if (!iov->iov_base) { + if (iov->iov_len) + return ERR_PTR(-EFAULT); + /* remove the buffer without installing a new one */ return NULL; + } + + ret = io_validate_user_buf_range((unsigned long)iov->iov_base, + iov->iov_len); + if (ret) + return ERR_PTR(ret); node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER); if (!node) @@ -828,7 +819,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx, imu->folio_shift = PAGE_SHIFT; imu->release = io_release_ubuf; imu->priv = imu; - imu->is_kbuf = false; + imu->flags = 0; imu->dir = IO_IMU_DEST | IO_IMU_SOURCE; if (coalesced) imu->folio_shift = data.folio_shift; @@ -897,9 +888,6 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg, ret = PTR_ERR(iov); break; } - ret = io_buffer_validate(iov); - if (ret) - break; if (ctx->compat) arg += sizeof(struct compat_iovec); else @@ -985,7 +973,7 @@ int io_buffer_register_bvec(struct io_uring_cmd *cmd, struct request *rq, refcount_set(&imu->refs, 1); imu->release = release; imu->priv = rq; - imu->is_kbuf = true; + imu->flags = IO_REGBUF_F_KBUF; imu->dir = 1 << rq_data_dir(rq); rq_for_each_bvec(bv, rq, rq_iter) @@ -1020,7 +1008,7 @@ int io_buffer_unregister_bvec(struct io_uring_cmd *cmd, unsigned int index, ret = -EINVAL; goto unlock; } - if (!node->buf->is_kbuf) { + if (!(node->buf->flags & IO_REGBUF_F_KBUF)) { ret = -EBUSY; goto unlock; } @@ -1076,7 +1064,7 @@ static int io_import_fixed(int ddir, struct iov_iter *iter, offset = buf_addr - imu->ubuf; - if (imu->is_kbuf) + if (imu->flags & IO_REGBUF_F_KBUF) return io_import_kbuf(ddir, iter, imu, len, offset); /* @@ -1321,7 +1309,7 @@ int io_vec_realloc(struct iou_vec *iv, unsigned nr_entries) gfp_t gfp = GFP_KERNEL_ACCOUNT | __GFP_NOWARN; struct iovec *iov; - iov = kmalloc_array(nr_entries, sizeof(iov[0]), gfp); + iov = kmalloc_objs(iov[0], nr_entries, gfp); if (!iov) return -ENOMEM; @@ -1496,7 +1484,7 @@ int io_import_reg_vec(int ddir, struct iov_iter *iter, iovec_off = vec->nr - nr_iovs; iov = vec->iovec + iovec_off; - if (imu->is_kbuf) { + if (imu->flags & IO_REGBUF_F_KBUF) { int ret = io_kern_bvec_size(iov, nr_iovs, imu, &nr_segs); if (unlikely(ret)) @@ -1534,7 +1522,7 @@ int io_import_reg_vec(int ddir, struct iov_iter *iter, req->flags |= REQ_F_NEED_CLEANUP; } - if (imu->is_kbuf) + if (imu->flags & IO_REGBUF_F_KBUF) return io_vec_fill_kern_bvec(ddir, iter, imu, iov, nr_iovs, vec); return io_vec_fill_bvec(ddir, iter, imu, iov, nr_iovs, vec); diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index 4a5db2ad1af2..cff0f8834c35 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -28,6 +28,10 @@ enum { IO_IMU_SOURCE = 1 << ITER_SOURCE, }; +enum { + IO_REGBUF_F_KBUF = 1, +}; + struct io_mapped_ubuf { u64 ubuf; unsigned int len; @@ -37,7 +41,7 @@ struct io_mapped_ubuf { unsigned long acct_pages; void (*release)(void *); void *priv; - bool is_kbuf; + u8 flags; u8 dir; struct bio_vec bvec[] __counted_by(nr_bvecs); }; diff --git a/io_uring/rw.c b/io_uring/rw.c index d10386f56d49..1a5f262734e8 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -702,7 +702,8 @@ static ssize_t loop_rw_iter(int ddir, struct io_rw *rw, struct iov_iter *iter) if ((kiocb->ki_flags & IOCB_NOWAIT) && !(kiocb->ki_filp->f_flags & O_NONBLOCK)) return -EAGAIN; - if ((req->flags & REQ_F_BUF_NODE) && req->buf_node->buf->is_kbuf) + if ((req->flags & REQ_F_BUF_NODE) && + (req->buf_node->buf->flags & IO_REGBUF_F_KBUF)) return -EFAULT; ppos = io_kiocb_ppos(kiocb); @@ -1253,7 +1254,7 @@ static int io_uring_classic_poll(struct io_kiocb *req, struct io_comp_batch *iob { struct file *file = req->file; - if (req->opcode == IORING_OP_URING_CMD) { + if (io_is_uring_cmd(req)) { struct io_uring_cmd *ioucmd; ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd); @@ -1379,7 +1380,7 @@ int io_do_iopoll(struct io_ring_ctx *ctx, bool force_nonspin) wq_list_add_tail(&req->comp_list, &ctx->submit_state.compl_reqs); nr_events++; req->cqe.flags = io_put_kbuf(req, req->cqe.res, NULL); - if (req->opcode != IORING_OP_URING_CMD) + if (!io_is_uring_cmd(req)) io_req_rw_cleanup(req, 0); } if (nr_events) diff --git a/io_uring/sqpoll.c b/io_uring/sqpoll.c index becdfdd323a9..c6bb938ec5ea 100644 --- a/io_uring/sqpoll.c +++ b/io_uring/sqpoll.c @@ -153,7 +153,7 @@ static struct io_sq_data *io_get_sq_data(struct io_uring_params *p, return sqd; } - sqd = kzalloc(sizeof(*sqd), GFP_KERNEL); + sqd = kzalloc_obj(*sqd); if (!sqd) return ERR_PTR(-ENOMEM); diff --git a/io_uring/tctx.c b/io_uring/tctx.c index ad9e4336d736..7cbcb82aedfb 100644 --- a/io_uring/tctx.c +++ b/io_uring/tctx.c @@ -23,7 +23,7 @@ static struct io_wq *io_init_wq_offload(struct io_ring_ctx *ctx, mutex_lock(&ctx->uring_lock); hash = ctx->hash_map; if (!hash) { - hash = kzalloc(sizeof(*hash), GFP_KERNEL); + hash = kzalloc_obj(*hash); if (!hash) { mutex_unlock(&ctx->uring_lock); return ERR_PTR(-ENOMEM); @@ -80,7 +80,7 @@ __cold int io_uring_alloc_task_context(struct task_struct *task, struct io_uring_task *tctx; int ret; - tctx = kzalloc(sizeof(*tctx), GFP_KERNEL); + tctx = kzalloc_obj(*tctx); if (unlikely(!tctx)) return -ENOMEM; @@ -139,7 +139,7 @@ int __io_uring_add_tctx_node(struct io_ring_ctx *ctx) if (tctx->io_wq) io_wq_set_exit_on_idle(tctx->io_wq, false); if (!xa_load(&tctx->xa, (unsigned long)ctx)) { - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmalloc_obj(*node); if (!node) return -ENOMEM; node->ctx = ctx; @@ -240,14 +240,14 @@ void io_uring_unreg_ringfd(void) int io_ring_add_registered_file(struct io_uring_task *tctx, struct file *file, int start, int end) { - int offset; + int offset, idx; for (offset = start; offset < end; offset++) { - offset = array_index_nospec(offset, IO_RINGFD_REG_MAX); - if (tctx->registered_rings[offset]) + idx = array_index_nospec(offset, IO_RINGFD_REG_MAX); + if (tctx->registered_rings[idx]) continue; - tctx->registered_rings[offset] = file; - return offset; + tctx->registered_rings[idx] = file; + return idx; } return -EBUSY; } @@ -378,7 +378,7 @@ int __io_uring_fork(struct task_struct *tsk) /* Don't leave it dangling on error */ tsk->io_uring_restrict = NULL; - res = kzalloc(sizeof(*res), GFP_KERNEL_ACCOUNT); + res = kzalloc_obj(*res, GFP_KERNEL_ACCOUNT); if (!res) return -ENOMEM; diff --git a/io_uring/timeout.c b/io_uring/timeout.c index 84dda24f3eb2..cb61d4862fc6 100644 --- a/io_uring/timeout.c +++ b/io_uring/timeout.c @@ -462,7 +462,7 @@ int io_timeout_remove_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) tr->ltimeout = true; if (tr->flags & ~(IORING_TIMEOUT_UPDATE_MASK|IORING_TIMEOUT_ABS)) return -EINVAL; - if (get_timespec64(&tr->ts, u64_to_user_ptr(sqe->addr2))) + if (get_timespec64(&tr->ts, u64_to_user_ptr(READ_ONCE(sqe->addr2)))) return -EFAULT; if (tr->ts.tv_sec < 0 || tr->ts.tv_nsec < 0) return -EINVAL; @@ -557,7 +557,7 @@ static int __io_timeout_prep(struct io_kiocb *req, data->req = req; data->flags = flags; - if (get_timespec64(&data->ts, u64_to_user_ptr(sqe->addr))) + if (get_timespec64(&data->ts, u64_to_user_ptr(READ_ONCE(sqe->addr)))) return -EFAULT; if (data->ts.tv_sec < 0 || data->ts.tv_nsec < 0) diff --git a/io_uring/tw.c b/io_uring/tw.c index 1ee2b8ab07c8..2f2b4ac4b126 100644 --- a/io_uring/tw.c +++ b/io_uring/tw.c @@ -152,6 +152,21 @@ void tctx_task_work(struct callback_head *cb) WARN_ON_ONCE(ret); } +/* + * Sets IORING_SQ_TASKRUN in the sq_flags shared with userspace, using the + * RCU protected rings pointer to be safe against concurrent ring resizing. + */ +static void io_ctx_mark_taskrun(struct io_ring_ctx *ctx) +{ + lockdep_assert_in_rcu_read_lock(); + + if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) { + struct io_rings *rings = rcu_dereference(ctx->rings_rcu); + + atomic_or(IORING_SQ_TASKRUN, &rings->sq_flags); + } +} + void io_req_local_work_add(struct io_kiocb *req, unsigned flags) { struct io_ring_ctx *ctx = req->ctx; @@ -206,8 +221,7 @@ void io_req_local_work_add(struct io_kiocb *req, unsigned flags) */ if (!head) { - if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) - atomic_or(IORING_SQ_TASKRUN, &ctx->rings->sq_flags); + io_ctx_mark_taskrun(ctx); if (ctx->has_evfd) io_eventfd_signal(ctx, false); } @@ -231,6 +245,10 @@ void io_req_normal_work_add(struct io_kiocb *req) if (!llist_add(&req->io_task_work.node, &tctx->task_list)) return; + /* + * Doesn't need to use ->rings_rcu, as resizing isn't supported for + * !DEFER_TASKRUN. + */ if (ctx->flags & IORING_SETUP_TASKRUN_FLAG) atomic_or(IORING_SQ_TASKRUN, &ctx->rings->sq_flags); diff --git a/io_uring/xattr.c b/io_uring/xattr.c index ba2b98cf13f9..5303df3f247f 100644 --- a/io_uring/xattr.c +++ b/io_uring/xattr.c @@ -56,7 +56,7 @@ static int __io_getxattr_prep(struct io_kiocb *req, if (ix->ctx.flags) return -EINVAL; - ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL); + ix->ctx.kname = kmalloc_obj(*ix->ctx.kname); if (!ix->ctx.kname) return -ENOMEM; @@ -133,7 +133,7 @@ static int __io_setxattr_prep(struct io_kiocb *req, ix->ctx.size = READ_ONCE(sqe->len); ix->ctx.flags = READ_ONCE(sqe->xattr_flags); - ix->ctx.kname = kmalloc(sizeof(*ix->ctx.kname), GFP_KERNEL); + ix->ctx.kname = kmalloc_obj(*ix->ctx.kname); if (!ix->ctx.kname) return -ENOMEM; diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index d8b6db456bd7..62d693287457 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -205,7 +205,7 @@ static int io_import_umem(struct io_zcrx_ifq *ifq, return PTR_ERR(pages); ret = sg_alloc_table_from_pages(&mem->page_sg_table, pages, nr_pages, - 0, nr_pages << PAGE_SHIFT, + 0, (unsigned long)nr_pages << PAGE_SHIFT, GFP_KERNEL_ACCOUNT); if (ret) { unpin_user_pages(pages, nr_pages); @@ -300,6 +300,9 @@ static int io_zcrx_map_area(struct io_zcrx_ifq *ifq, struct io_zcrx_area *area) } ret = io_populate_area_dma(ifq, area); + if (ret && !area->mem.is_dmabuf) + dma_unmap_sgtable(ifq->dev, &area->mem.page_sg_table, + DMA_FROM_DEVICE, IO_DMA_ATTR); if (ret == 0) area->is_mapped = true; return ret; @@ -346,10 +349,14 @@ static inline atomic_t *io_get_user_counter(struct net_iov *niov) static bool io_zcrx_put_niov_uref(struct net_iov *niov) { atomic_t *uref = io_get_user_counter(niov); + int old; + + old = atomic_read(uref); + do { + if (unlikely(old == 0)) + return false; + } while (!atomic_try_cmpxchg(uref, &old, old - 1)); - if (unlikely(!atomic_read(uref))) - return false; - atomic_dec(uref); return true; } @@ -445,7 +452,7 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, } ret = -ENOMEM; - area = kzalloc(sizeof(*area), GFP_KERNEL); + area = kzalloc_obj(*area); if (!area) goto err; area->ifq = ifq; @@ -464,8 +471,8 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, area->nia.num_niovs = nr_iovs; ret = -ENOMEM; - area->nia.niovs = kvmalloc_array(nr_iovs, sizeof(area->nia.niovs[0]), - GFP_KERNEL_ACCOUNT | __GFP_ZERO); + area->nia.niovs = kvmalloc_objs(area->nia.niovs[0], nr_iovs, + GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!area->nia.niovs) goto err; @@ -474,7 +481,7 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, if (!area->freelist) goto err; - area->user_refs = kvmalloc_array(nr_iovs, sizeof(area->user_refs[0]), + area->user_refs = kvmalloc_objs(area->user_refs[0], nr_iovs, GFP_KERNEL_ACCOUNT | __GFP_ZERO); if (!area->user_refs) goto err; @@ -507,7 +514,7 @@ static struct io_zcrx_ifq *io_zcrx_ifq_alloc(struct io_ring_ctx *ctx) { struct io_zcrx_ifq *ifq; - ifq = kzalloc(sizeof(*ifq), GFP_KERNEL); + ifq = kzalloc_obj(*ifq); if (!ifq) return NULL; @@ -538,9 +545,6 @@ static void io_close_queue(struct io_zcrx_ifq *ifq) .mp_priv = ifq, }; - if (ifq->if_rxq == -1) - return; - scoped_guard(mutex, &ifq->pp_lock) { netdev = ifq->netdev; netdev_tracker = ifq->netdev_tracker; @@ -548,7 +552,8 @@ static void io_close_queue(struct io_zcrx_ifq *ifq) } if (netdev) { - net_mp_close_rxq(netdev, ifq->if_rxq, &p); + if (ifq->if_rxq != -1) + net_mp_close_rxq(netdev, ifq->if_rxq, &p); netdev_put(netdev, &netdev_tracker); } ifq->if_rxq = -1; @@ -702,6 +707,8 @@ static int import_zcrx(struct io_ring_ctx *ctx, return -EINVAL; if (reg->if_rxq || reg->rq_entries || reg->area_ptr || reg->region_ptr) return -EINVAL; + if (reg->flags & ~ZCRX_REG_IMPORT) + return -EINVAL; fd = reg->if_idx; CLASS(fd, f)(fd); @@ -830,7 +837,8 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx, if (ret) goto netdev_put_unlock; - mp_param.rx_page_size = 1U << ifq->niov_shift; + if (reg.rx_buf_len) + mp_param.rx_page_size = 1U << ifq->niov_shift; mp_param.mp_ops = &io_uring_pp_zc_ops; mp_param.mp_priv = ifq; ret = __net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param, NULL); @@ -858,13 +866,12 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx, } return 0; netdev_put_unlock: - netdev_put(ifq->netdev, &ifq->netdev_tracker); netdev_unlock(ifq->netdev); err: scoped_guard(mutex, &ctx->mmap_lock) xa_erase(&ctx->zcrx_ctxs, id); ifq_free: - io_zcrx_ifq_free(ifq); + zcrx_unregister(ifq); return ret; } @@ -920,11 +927,12 @@ static inline bool io_parse_rqe(struct io_uring_zcrx_rqe *rqe, struct io_zcrx_ifq *ifq, struct net_iov **ret_niov) { + __u64 off = READ_ONCE(rqe->off); unsigned niov_idx, area_idx; struct io_zcrx_area *area; - area_idx = rqe->off >> IORING_ZCRX_AREA_SHIFT; - niov_idx = (rqe->off & ~IORING_ZCRX_AREA_MASK) >> ifq->niov_shift; + area_idx = off >> IORING_ZCRX_AREA_SHIFT; + niov_idx = (off & ~IORING_ZCRX_AREA_MASK) >> ifq->niov_shift; if (unlikely(rqe->__pad || area_idx)) return false; diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 53a58f9ba01f..4798b375972b 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * POSIX message queues filesystem for Linux. * @@ -9,8 +10,6 @@ * Manfred Spraul (manfred@colorfullife.com) * * Audit: George Wilson (ltcgcw@us.ibm.com) - * - * This file is released under the GPL. */ #include @@ -211,7 +210,7 @@ static int msg_insert(struct msg_msg *msg, struct mqueue_inode_info *info) leaf = info->node_cache; info->node_cache = NULL; } else { - leaf = kmalloc(sizeof(*leaf), GFP_ATOMIC); + leaf = kmalloc_obj(*leaf, GFP_ATOMIC); if (!leaf) return -ENOMEM; INIT_LIST_HEAD(&leaf->msg_list); @@ -450,7 +449,7 @@ static int mqueue_init_fs_context(struct fs_context *fc) { struct mqueue_fs_context *ctx; - ctx = kzalloc(sizeof(struct mqueue_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct mqueue_fs_context); if (!ctx) return -ENOMEM; @@ -1089,7 +1088,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr, * fall back to that if necessary. */ if (!info->node_cache) - new_leaf = kmalloc(sizeof(*new_leaf), GFP_KERNEL); + new_leaf = kmalloc_obj(*new_leaf); spin_lock(&info->lock); @@ -1182,7 +1181,7 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr, * fall back to that if necessary. */ if (!info->node_cache) - new_leaf = kmalloc(sizeof(*new_leaf), GFP_KERNEL); + new_leaf = kmalloc_obj(*new_leaf); spin_lock(&info->lock); diff --git a/ipc/msg.c b/ipc/msg.c index ee6af4fe52bf..62996b97f0ac 100644 --- a/ipc/msg.c +++ b/ipc/msg.c @@ -148,7 +148,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params) key_t key = params->key; int msgflg = params->flg; - msq = kmalloc(sizeof(*msq), GFP_KERNEL_ACCOUNT); + msq = kmalloc_obj(*msq, GFP_KERNEL_ACCOUNT); if (unlikely(!msq)) return -ENOMEM; diff --git a/ipc/namespace.c b/ipc/namespace.c index 535f16ea40e1..1e71353bdb4a 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -58,7 +58,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, } err = -ENOMEM; - ns = kzalloc(sizeof(struct ipc_namespace), GFP_KERNEL_ACCOUNT); + ns = kzalloc_obj(struct ipc_namespace, GFP_KERNEL_ACCOUNT); if (ns == NULL) goto fail_dec; diff --git a/ipc/sem.c b/ipc/sem.c index 0f06e4bd4673..6cdf862b1f5c 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -514,7 +514,7 @@ static struct sem_array *sem_alloc(size_t nsems) if (nsems > (INT_MAX - sizeof(*sma)) / sizeof(sma->sems[0])) return NULL; - sma = kvzalloc(struct_size(sma, sems, nsems), GFP_KERNEL_ACCOUNT); + sma = kvzalloc_flex(*sma, sems, nsems, GFP_KERNEL_ACCOUNT); if (unlikely(!sma)) return NULL; @@ -1853,7 +1853,7 @@ static inline int get_undo_list(struct sem_undo_list **undo_listp) undo_list = current->sysvsem.undo_list; if (!undo_list) { - undo_list = kzalloc(sizeof(*undo_list), GFP_KERNEL_ACCOUNT); + undo_list = kzalloc_obj(*undo_list, GFP_KERNEL_ACCOUNT); if (undo_list == NULL) return -ENOMEM; spin_lock_init(&undo_list->lock); @@ -1938,7 +1938,7 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid) rcu_read_unlock(); /* step 2: allocate new undo structure */ - new = kvzalloc(struct_size(new, semadj, nsems), GFP_KERNEL_ACCOUNT); + new = kvzalloc_flex(*new, semadj, nsems, GFP_KERNEL_ACCOUNT); if (!new) { ipc_rcu_putref(&sma->sem_perm, sem_rcu_free); return ERR_PTR(-ENOMEM); @@ -2234,7 +2234,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops, return -EINVAL; if (nsops > SEMOPM_FAST) { - sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL); + sops = kvmalloc_objs(*sops, nsops); if (sops == NULL) return -ENOMEM; } diff --git a/ipc/shm.c b/ipc/shm.c index 3db36773dd10..a95dae447707 100644 --- a/ipc/shm.c +++ b/ipc/shm.c @@ -707,9 +707,10 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) int error; struct shmid_kernel *shp; size_t numpages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; + const bool has_no_reserve = shmflg & SHM_NORESERVE; + vma_flags_t acctflag = EMPTY_VMA_FLAGS; struct file *file; char name[13]; - vm_flags_t acctflag = 0; if (size < SHMMIN || size > ns->shm_ctlmax) return -EINVAL; @@ -721,7 +722,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) ns->shm_tot + numpages > ns->shm_ctlall) return -ENOSPC; - shp = kmalloc(sizeof(*shp), GFP_KERNEL_ACCOUNT); + shp = kmalloc_obj(*shp, GFP_KERNEL_ACCOUNT); if (unlikely(!shp)) return -ENOMEM; @@ -749,8 +750,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) hugesize = ALIGN(size, huge_page_size(hs)); /* hugetlb_file_setup applies strict accounting */ - if (shmflg & SHM_NORESERVE) - acctflag = VM_NORESERVE; + if (has_no_reserve) + vma_flags_set(&acctflag, VMA_NORESERVE_BIT); file = hugetlb_file_setup(name, hugesize, acctflag, HUGETLB_SHMFS_INODE, (shmflg >> SHM_HUGE_SHIFT) & SHM_HUGE_MASK); } else { @@ -758,9 +759,8 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params) * Do not allow no accounting for OVERCOMMIT_NEVER, even * if it's asked for. */ - if ((shmflg & SHM_NORESERVE) && - sysctl_overcommit_memory != OVERCOMMIT_NEVER) - acctflag = VM_NORESERVE; + if (has_no_reserve && sysctl_overcommit_memory != OVERCOMMIT_NEVER) + vma_flags_set(&acctflag, VMA_NORESERVE_BIT); file = shmem_kernel_file_setup(name, size, acctflag); } error = PTR_ERR(file); @@ -1618,7 +1618,7 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, rcu_read_unlock(); err = -ENOMEM; - sfd = kzalloc(sizeof(*sfd), GFP_KERNEL); + sfd = kzalloc_obj(*sfd); if (!sfd) { fput(base); goto out_nattch; diff --git a/ipc/util.c b/ipc/util.c index cae60f11d9c2..9eb89820594e 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -141,7 +141,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header, struct proc_dir_entry *pde; struct ipc_proc_iface *iface; - iface = kmalloc(sizeof(*iface), GFP_KERNEL); + iface = kmalloc_obj(*iface); if (!iface) return; iface->path = path; diff --git a/kernel/acct.c b/kernel/acct.c index 812808e5b1b8..1e19722c64c3 100644 --- a/kernel/acct.c +++ b/kernel/acct.c @@ -255,7 +255,7 @@ static int acct_on(const char __user *name) if (!(file->f_mode & FMODE_CAN_WRITE)) return -EIO; - acct = kzalloc(sizeof(struct bsd_acct_struct), GFP_KERNEL); + acct = kzalloc_obj(struct bsd_acct_struct); if (!acct) return -ENOMEM; diff --git a/kernel/async.c b/kernel/async.c index 4c3e6a44595f..0e3a783dc991 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -205,7 +205,7 @@ async_cookie_t async_schedule_node_domain(async_func_t func, void *data, async_cookie_t newcookie; /* allow irq-off callers */ - entry = kzalloc(sizeof(struct async_entry), GFP_ATOMIC); + entry = kzalloc_obj(struct async_entry, GFP_ATOMIC); /* * If we're out of memory or if there's too much work @@ -261,7 +261,7 @@ bool async_schedule_dev_nocall(async_func_t func, struct device *dev) { struct async_entry *entry; - entry = kzalloc(sizeof(struct async_entry), GFP_KERNEL); + entry = kzalloc_obj(struct async_entry); /* Give up if there is no memory or too much work. */ if (!entry || atomic_read(&entry_count) > MAX_WORK) { diff --git a/kernel/audit.c b/kernel/audit.c index 592d927e70f9..5a0216056524 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -545,7 +545,7 @@ static int auditd_set(struct pid *pid, u32 portid, struct net *net, if (!pid || !net) return -EINVAL; - ac_new = kzalloc(sizeof(*ac_new), GFP_KERNEL); + ac_new = kzalloc_obj(*ac_new); if (!ac_new) return -ENOMEM; ac_new->pid = get_pid(pid); @@ -1044,7 +1044,7 @@ static void audit_send_reply(struct sk_buff *request_skb, int seq, int type, int struct task_struct *tsk; struct audit_reply *reply; - reply = kzalloc(sizeof(*reply), GFP_KERNEL); + reply = kzalloc_obj(*reply); if (!reply) return; @@ -1517,8 +1517,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh, if (err < 0) return err; } - sig_data = kmalloc(struct_size(sig_data, ctx, lsmctx.len), - GFP_KERNEL); + sig_data = kmalloc_flex(*sig_data, ctx, lsmctx.len); if (!sig_data) { if (lsmprop_is_set(&audit_sig_lsm)) security_release_secctx(&lsmctx); diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index b92805b317a2..a4401f651060 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -89,7 +89,7 @@ struct audit_fsnotify_mark *audit_alloc_mark(struct audit_krule *krule, char *pa goto out; } - audit_mark = kzalloc(sizeof(*audit_mark), GFP_KERNEL); + audit_mark = kzalloc_obj(*audit_mark); if (unlikely(!audit_mark)) { audit_mark = ERR_PTR(-ENOMEM); goto out; diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index fda6beb041e0..ee84777fdfad 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -96,7 +96,7 @@ static struct audit_tree *alloc_tree(const char *s) size_t sz; sz = strlen(s) + 1; - tree = kmalloc(struct_size(tree, pathname, sz), GFP_KERNEL); + tree = kmalloc_flex(*tree, pathname, sz); if (tree) { refcount_set(&tree->count, 1); tree->goner = 0; @@ -192,7 +192,7 @@ static struct audit_chunk *alloc_chunk(int count) struct audit_chunk *chunk; int i; - chunk = kzalloc(struct_size(chunk, owners, count), GFP_KERNEL); + chunk = kzalloc_flex(*chunk, owners, count); if (!chunk) return NULL; diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index a700e3c8925f..096faac2435c 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -139,7 +139,7 @@ static struct audit_parent *audit_init_parent(const struct path *path) struct audit_parent *parent; int ret; - parent = kzalloc(sizeof(*parent), GFP_KERNEL); + parent = kzalloc_obj(*parent); if (unlikely(!parent)) return ERR_PTR(-ENOMEM); @@ -161,7 +161,7 @@ static struct audit_watch *audit_init_watch(char *path) { struct audit_watch *watch; - watch = kzalloc(sizeof(*watch), GFP_KERNEL); + watch = kzalloc_obj(*watch); if (unlikely(!watch)) return ERR_PTR(-ENOMEM); diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c index 6a86c0683b67..6e3abbf08e3d 100644 --- a/kernel/auditfilter.c +++ b/kernel/auditfilter.c @@ -108,11 +108,11 @@ static inline struct audit_entry *audit_init_entry(u32 field_count) struct audit_entry *entry; struct audit_field *fields; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (unlikely(!entry)) return NULL; - fields = kcalloc(field_count, sizeof(*fields), GFP_KERNEL); + fields = kzalloc_objs(*fields, field_count); if (unlikely(!fields)) { kfree(entry); return NULL; @@ -638,7 +638,7 @@ static struct audit_rule_data *audit_krule_to_data(struct audit_krule *krule) void *bufp; int i; - data = kzalloc(struct_size(data, buf, krule->buflen), GFP_KERNEL); + data = kzalloc_flex(*data, buf, krule->buflen); if (unlikely(!data)) return NULL; @@ -1180,7 +1180,7 @@ int audit_list_rules_send(struct sk_buff *request_skb, int seq) * happen if we're actually running in the context of auditctl * trying to _send_ the stuff */ - dest = kmalloc(sizeof(*dest), GFP_KERNEL); + dest = kmalloc_obj(*dest); if (!dest) return -ENOMEM; dest->net = get_net(sock_net(NETLINK_CB(request_skb).sk)); diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 86a44b162a87..f6af6a8f68c4 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -255,7 +255,7 @@ static int grow_tree_refs(struct audit_context *ctx) { struct audit_tree_refs *p = ctx->trees; - ctx->trees = kzalloc(sizeof(struct audit_tree_refs), GFP_KERNEL); + ctx->trees = kzalloc_obj(struct audit_tree_refs); if (!ctx->trees) { ctx->trees = p; return 0; @@ -1032,7 +1032,7 @@ static inline struct audit_context *audit_alloc_context(enum audit_state state) { struct audit_context *context; - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) return NULL; context->context = AUDIT_CTX_UNUSED; @@ -2153,7 +2153,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context, aname = &context->preallocated_names[context->name_count]; memset(aname, 0, sizeof(*aname)); } else { - aname = kzalloc(sizeof(*aname), GFP_NOFS); + aname = kzalloc_obj(*aname, GFP_NOFS); if (!aname) return NULL; aname->should_free = true; @@ -2650,7 +2650,7 @@ int __audit_sockaddr(int len, void *a) struct audit_context *context = audit_context(); if (!context->sockaddr) { - void *p = kmalloc(sizeof(struct sockaddr_storage), GFP_KERNEL); + void *p = kmalloc_obj(struct sockaddr_storage); if (!p) return -ENOMEM; @@ -2704,7 +2704,7 @@ int audit_signal_info_syscall(struct task_struct *t) axp = (void *)ctx->aux_pids; if (!axp || axp->pid_count == AUDIT_AUX_PIDS) { - axp = kzalloc(sizeof(*axp), GFP_ATOMIC); + axp = kzalloc_obj(*axp, GFP_ATOMIC); if (!axp) return -ENOMEM; @@ -2743,7 +2743,7 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm, struct audit_context *context = audit_context(); struct cpu_vfs_cap_data vcaps; - ax = kmalloc(sizeof(*ax), GFP_KERNEL); + ax = kmalloc_obj(*ax); if (!ax) return -ENOMEM; diff --git a/kernel/bpf/arena.c b/kernel/bpf/arena.c index 42fae0a9f314..f355cf1c1a16 100644 --- a/kernel/bpf/arena.c +++ b/kernel/bpf/arena.c @@ -303,7 +303,7 @@ static long arena_map_update_elem(struct bpf_map *map, void *key, return -EOPNOTSUPP; } -static int arena_map_check_btf(const struct bpf_map *map, const struct btf *btf, +static int arena_map_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) { return 0; @@ -324,7 +324,7 @@ static int remember_vma(struct bpf_arena *arena, struct vm_area_struct *vma) { struct vma_list *vml; - vml = kmalloc(sizeof(*vml), GFP_KERNEL); + vml = kmalloc_obj(*vml); if (!vml) return -ENOMEM; refcount_set(&vml->mmap_count, 1); diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index 67e9e811de3a..33de68c95ad8 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -548,7 +548,7 @@ static void percpu_array_map_seq_show_elem(struct bpf_map *map, void *key, rcu_read_unlock(); } -static int array_map_check_btf(const struct bpf_map *map, +static int array_map_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) @@ -1061,7 +1061,7 @@ static int prog_array_map_poke_track(struct bpf_map *map, goto out; } - elem = kmalloc(sizeof(*elem), GFP_KERNEL); + elem = kmalloc_obj(*elem); if (!elem) { ret = -ENOMEM; goto out; @@ -1174,7 +1174,7 @@ static struct bpf_map *prog_array_map_alloc(union bpf_attr *attr) struct bpf_array_aux *aux; struct bpf_map *map; - aux = kzalloc(sizeof(*aux), GFP_KERNEL_ACCOUNT); + aux = kzalloc_obj(*aux, GFP_KERNEL_ACCOUNT); if (!aux) return ERR_PTR(-ENOMEM); @@ -1237,7 +1237,7 @@ static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, { struct bpf_event_entry *ee; - ee = kzalloc(sizeof(*ee), GFP_KERNEL); + ee = kzalloc_obj(*ee); if (ee) { ee->event = perf_file->private_data; ee->perf_file = perf_file; diff --git a/kernel/bpf/bloom_filter.c b/kernel/bpf/bloom_filter.c index 35e1ddca74d2..b73336c976b7 100644 --- a/kernel/bpf/bloom_filter.c +++ b/kernel/bpf/bloom_filter.c @@ -180,7 +180,7 @@ static long bloom_map_update_elem(struct bpf_map *map, void *key, return -EINVAL; } -static int bloom_map_check_btf(const struct bpf_map *map, +static int bloom_map_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) diff --git a/kernel/bpf/bpf_insn_array.c b/kernel/bpf/bpf_insn_array.c index c0286f25ca3c..a2f84afe6f7c 100644 --- a/kernel/bpf/bpf_insn_array.c +++ b/kernel/bpf/bpf_insn_array.c @@ -98,7 +98,7 @@ static long insn_array_delete_elem(struct bpf_map *map, void *key) return -EINVAL; } -static int insn_array_check_btf(const struct bpf_map *map, +static int insn_array_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c index 4b58d56ecab1..f5eaeb2493d4 100644 --- a/kernel/bpf/bpf_iter.c +++ b/kernel/bpf/bpf_iter.c @@ -295,7 +295,7 @@ int bpf_iter_reg_target(const struct bpf_iter_reg *reg_info) { struct bpf_iter_target_info *tinfo; - tinfo = kzalloc(sizeof(*tinfo), GFP_KERNEL); + tinfo = kzalloc_obj(*tinfo); if (!tinfo) return -ENOMEM; @@ -548,7 +548,7 @@ int bpf_iter_link_attach(const union bpf_attr *attr, bpfptr_t uattr, if (prog->sleepable && !bpf_iter_target_support_resched(tinfo)) return -EINVAL; - link = kzalloc(sizeof(*link), GFP_USER | __GFP_NOWARN); + link = kzalloc_obj(*link, GFP_USER | __GFP_NOWARN); if (!link) return -ENOMEM; diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c index b28f07d3a0db..9c96a4477f81 100644 --- a/kernel/bpf/bpf_local_storage.c +++ b/kernel/bpf/bpf_local_storage.c @@ -107,14 +107,12 @@ static void __bpf_local_storage_free_trace_rcu(struct rcu_head *rcu) { struct bpf_local_storage *local_storage; - /* If RCU Tasks Trace grace period implies RCU grace period, do - * kfree(), else do kfree_rcu(). + /* + * RCU Tasks Trace grace period implies RCU grace period, do + * kfree() directly. */ local_storage = container_of(rcu, struct bpf_local_storage, rcu); - if (rcu_trace_implies_rcu_gp()) - kfree(local_storage); - else - kfree_rcu(local_storage, rcu); + kfree(local_storage); } /* Handle use_kmalloc_nolock == false */ @@ -138,10 +136,11 @@ static void bpf_local_storage_free_rcu(struct rcu_head *rcu) static void bpf_local_storage_free_trace_rcu(struct rcu_head *rcu) { - if (rcu_trace_implies_rcu_gp()) - bpf_local_storage_free_rcu(rcu); - else - call_rcu(rcu, bpf_local_storage_free_rcu); + /* + * RCU Tasks Trace grace period implies RCU grace period, do + * kfree() directly. + */ + bpf_local_storage_free_rcu(rcu); } static void bpf_local_storage_free(struct bpf_local_storage *local_storage, @@ -164,16 +163,29 @@ static void bpf_local_storage_free(struct bpf_local_storage *local_storage, bpf_local_storage_free_trace_rcu); } +/* rcu callback for use_kmalloc_nolock == false */ +static void __bpf_selem_free_rcu(struct rcu_head *rcu) +{ + struct bpf_local_storage_elem *selem; + struct bpf_local_storage_map *smap; + + selem = container_of(rcu, struct bpf_local_storage_elem, rcu); + /* bpf_selem_unlink_nofail may have already cleared smap and freed fields. */ + smap = rcu_dereference_check(SDATA(selem)->smap, 1); + + if (smap) + bpf_obj_free_fields(smap->map.record, SDATA(selem)->data); + kfree(selem); +} + /* rcu tasks trace callback for use_kmalloc_nolock == false */ static void __bpf_selem_free_trace_rcu(struct rcu_head *rcu) { - struct bpf_local_storage_elem *selem; - - selem = container_of(rcu, struct bpf_local_storage_elem, rcu); - if (rcu_trace_implies_rcu_gp()) - kfree(selem); - else - kfree_rcu(selem, rcu); + /* + * RCU Tasks Trace grace period implies RCU grace period, do + * kfree() directly. + */ + __bpf_selem_free_rcu(rcu); } /* Handle use_kmalloc_nolock == false */ @@ -181,7 +193,7 @@ static void __bpf_selem_free(struct bpf_local_storage_elem *selem, bool vanilla_rcu) { if (vanilla_rcu) - kfree_rcu(selem, rcu); + call_rcu(&selem->rcu, __bpf_selem_free_rcu); else call_rcu_tasks_trace(&selem->rcu, __bpf_selem_free_trace_rcu); } @@ -195,37 +207,29 @@ static void bpf_selem_free_rcu(struct rcu_head *rcu) /* The bpf_local_storage_map_free will wait for rcu_barrier */ smap = rcu_dereference_check(SDATA(selem)->smap, 1); - if (smap) { - migrate_disable(); + if (smap) bpf_obj_free_fields(smap->map.record, SDATA(selem)->data); - migrate_enable(); - } kfree_nolock(selem); } static void bpf_selem_free_trace_rcu(struct rcu_head *rcu) { - if (rcu_trace_implies_rcu_gp()) - bpf_selem_free_rcu(rcu); - else - call_rcu(rcu, bpf_selem_free_rcu); + /* + * RCU Tasks Trace grace period implies RCU grace period, do + * kfree() directly. + */ + bpf_selem_free_rcu(rcu); } void bpf_selem_free(struct bpf_local_storage_elem *selem, bool reuse_now) { - struct bpf_local_storage_map *smap; - - smap = rcu_dereference_check(SDATA(selem)->smap, bpf_rcu_lock_held()); - if (!selem->use_kmalloc_nolock) { /* * No uptr will be unpin even when reuse_now == false since uptr * is only supported in task local storage, where * smap->use_kmalloc_nolock == true. */ - if (smap) - bpf_obj_free_fields(smap->map.record, SDATA(selem)->data); __bpf_selem_free(selem, reuse_now); return; } @@ -797,7 +801,7 @@ int bpf_local_storage_map_alloc_check(union bpf_attr *attr) return 0; } -int bpf_local_storage_map_check_btf(const struct bpf_map *map, +int bpf_local_storage_map_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) @@ -958,10 +962,9 @@ void bpf_local_storage_map_free(struct bpf_map *map, */ synchronize_rcu(); - if (smap->use_kmalloc_nolock) { - rcu_barrier_tasks_trace(); - rcu_barrier(); - } + /* smap remains in use regardless of kmalloc_nolock, so wait unconditionally. */ + rcu_barrier_tasks_trace(); + rcu_barrier(); kvfree(smap->buckets); bpf_map_area_free(smap); } diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c index c43346cb3d76..05b366b821c3 100644 --- a/kernel/bpf/bpf_struct_ops.c +++ b/kernel/bpf/bpf_struct_ops.c @@ -218,7 +218,7 @@ static int prepare_arg_info(struct btf *btf, args = btf_params(func_proto); stub_args = btf_params(stub_func_proto); - info_buf = kcalloc(nargs, sizeof(*info_buf), GFP_KERNEL); + info_buf = kzalloc_objs(*info_buf, nargs); if (!info_buf) return -ENOMEM; @@ -378,8 +378,7 @@ int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc, if (!is_valid_value_type(btf, value_id, t, value_name)) return -EINVAL; - arg_info = kcalloc(btf_type_vlen(t), sizeof(*arg_info), - GFP_KERNEL); + arg_info = kzalloc_objs(*arg_info, btf_type_vlen(t)); if (!arg_info) return -ENOMEM; @@ -721,7 +720,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, if (uvalue->common.state || refcount_read(&uvalue->common.refcnt)) return -EINVAL; - tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL); + tlinks = kzalloc_objs(*tlinks, BPF_TRAMP_MAX); if (!tlinks) return -ENOMEM; @@ -815,7 +814,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, /* Poison pointer on error instead of return for backward compatibility */ bpf_prog_assoc_struct_ops(prog, &st_map->map); - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { bpf_prog_put(prog); err = -ENOMEM; @@ -825,7 +824,7 @@ static long bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key, &bpf_struct_ops_link_lops, prog, prog->expected_attach_type); *plink++ = &link->link; - ksym = kzalloc(sizeof(*ksym), GFP_USER); + ksym = kzalloc_obj(*ksym, GFP_USER); if (!ksym) { err = -ENOMEM; goto reset_unlock; @@ -1376,7 +1375,7 @@ int bpf_struct_ops_link_create(union bpf_attr *attr) goto err_out; } - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto err_out; diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 7708958e3fb8..4872d2a6c42d 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -1729,8 +1729,8 @@ static int btf_add_type(struct btf_verifier_env *env, struct btf_type *t) new_size = min_t(u32, BTF_MAX_TYPE, btf->types_size + expand_by); - new_types = kvcalloc(new_size, sizeof(*new_types), - GFP_KERNEL | __GFP_NOWARN); + new_types = kvzalloc_objs(*new_types, new_size, + GFP_KERNEL | __GFP_NOWARN); if (!new_types) return -ENOMEM; @@ -4072,7 +4072,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type /* This needs to be kzalloc to zero out padding and unused fields, see * comment in btf_record_equal. */ - rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + rec = kzalloc_flex(*rec, fields, cnt, GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!rec) return ERR_PTR(-ENOMEM); @@ -5687,7 +5687,7 @@ btf_parse_struct_metas(struct bpf_verifier_log *log, struct btf *btf) BUILD_BUG_ON(offsetof(struct btf_id_set, cnt) != 0); BUILD_BUG_ON(sizeof(struct btf_id_set) != sizeof(u32)); - aof = kmalloc(sizeof(*aof), GFP_KERNEL | __GFP_NOWARN); + aof = kmalloc_obj(*aof, GFP_KERNEL | __GFP_NOWARN); if (!aof) return ERR_PTR(-ENOMEM); aof->cnt = 0; @@ -5885,7 +5885,7 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat if (attr->btf_size > BTF_MAX_SIZE) return ERR_PTR(-E2BIG); - env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN); + env = kzalloc_obj(*env, GFP_KERNEL | __GFP_NOWARN); if (!env) return ERR_PTR(-ENOMEM); @@ -5897,7 +5897,7 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat if (err) goto errout_free; - btf = kzalloc(sizeof(*btf), GFP_KERNEL | __GFP_NOWARN); + btf = kzalloc_obj(*btf, GFP_KERNEL | __GFP_NOWARN); if (!btf) { err = -ENOMEM; goto errout; @@ -6314,7 +6314,7 @@ static struct btf *btf_parse_base(struct btf_verifier_env *env, const char *name if (!IS_ENABLED(CONFIG_DEBUG_INFO_BTF)) return ERR_PTR(-ENOENT); - btf = kzalloc(sizeof(*btf), GFP_KERNEL | __GFP_NOWARN); + btf = kzalloc_obj(*btf, GFP_KERNEL | __GFP_NOWARN); if (!btf) { err = -ENOMEM; goto errout; @@ -6365,7 +6365,7 @@ struct btf *btf_parse_vmlinux(void) struct btf *btf; int err; - env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN); + env = kzalloc_obj(*env, GFP_KERNEL | __GFP_NOWARN); if (!env) return ERR_PTR(-ENOMEM); @@ -6415,7 +6415,7 @@ static struct btf *btf_parse_module(const char *module_name, const void *data, if (!vmlinux_btf) return ERR_PTR(-EINVAL); - env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN); + env = kzalloc_obj(*env, GFP_KERNEL | __GFP_NOWARN); if (!env) return ERR_PTR(-ENOMEM); @@ -6432,7 +6432,7 @@ static struct btf *btf_parse_module(const char *module_name, const void *data, base_btf = vmlinux_btf; } - btf = kzalloc(sizeof(*btf), GFP_KERNEL | __GFP_NOWARN); + btf = kzalloc_obj(*btf, GFP_KERNEL | __GFP_NOWARN); if (!btf) { err = -ENOMEM; goto errout; @@ -8306,7 +8306,7 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, switch (op) { case MODULE_STATE_COMING: - btf_mod = kzalloc(sizeof(*btf_mod), GFP_KERNEL); + btf_mod = kzalloc_obj(*btf_mod); if (!btf_mod) { err = -ENOMEM; goto out; @@ -8341,7 +8341,7 @@ static int btf_module_notify(struct notifier_block *nb, unsigned long op, if (IS_ENABLED(CONFIG_SYSFS)) { struct bin_attribute *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (!attr) goto out; @@ -8689,7 +8689,7 @@ static int btf_populate_kfunc_set(struct btf *btf, enum btf_kfunc_hook hook, } if (!tab) { - tab = kzalloc(sizeof(*tab), GFP_KERNEL | __GFP_NOWARN); + tab = kzalloc_obj(*tab, GFP_KERNEL | __GFP_NOWARN); if (!tab) return -ENOMEM; btf->kfunc_set_tab = tab; @@ -9439,7 +9439,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo, /* ~4k of temp memory necessary to convert LLVM spec like "0:1:0:5" * into arrays of btf_ids of struct fields and array indices. */ - specs = kcalloc(3, sizeof(*specs), GFP_KERNEL_ACCOUNT); + specs = kzalloc_objs(*specs, 3, GFP_KERNEL_ACCOUNT); if (!specs) return -ENOMEM; @@ -9464,7 +9464,8 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo, goto out; } if (cc->cnt) { - cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL_ACCOUNT); + cands.cands = kzalloc_objs(*cands.cands, cc->cnt, + GFP_KERNEL_ACCOUNT); if (!cands.cands) { err = -ENOMEM; goto out; @@ -9616,7 +9617,7 @@ btf_add_struct_ops(struct btf *btf, struct bpf_struct_ops *st_ops, tab = btf->struct_ops_tab; if (!tab) { - tab = kzalloc(struct_size(tab, ops, 4), GFP_KERNEL); + tab = kzalloc_flex(*tab, ops, 4); if (!tab) return -ENOMEM; tab->capacity = 4; @@ -9705,7 +9706,7 @@ int __register_bpf_struct_ops(struct bpf_struct_ops *st_ops) if (IS_ERR(btf)) return PTR_ERR(btf); - log = kzalloc(sizeof(*log), GFP_KERNEL | __GFP_NOWARN); + log = kzalloc_obj(*log, GFP_KERNEL | __GFP_NOWARN); if (!log) { err = -ENOMEM; goto errout; diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index b029f0369ecf..876f6a81a9b6 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -845,7 +845,7 @@ static int __cgroup_bpf_attach(struct cgroup *cgrp, if (pl) { old_prog = pl->prog; } else { - pl = kmalloc(sizeof(*pl), GFP_KERNEL); + pl = kmalloc_obj(*pl); if (!pl) { bpf_cgroup_storages_free(new_storage); return -ENOMEM; @@ -1488,7 +1488,7 @@ int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) if (IS_ERR(cgrp)) return PTR_ERR(cgrp); - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto out_put_cgroup; diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 5ab6bace7d0d..3ece2da55625 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -108,7 +108,7 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag if (fp == NULL) return NULL; - aux = kzalloc(sizeof(*aux), bpf_memcg_flags(GFP_KERNEL | gfp_extra_flags)); + aux = kzalloc_obj(*aux, bpf_memcg_flags(GFP_KERNEL | gfp_extra_flags)); if (aux == NULL) { vfree(fp); return NULL; @@ -180,9 +180,9 @@ int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog) if (!prog->aux->nr_linfo || !prog->jit_requested) return 0; - prog->aux->jited_linfo = kvcalloc(prog->aux->nr_linfo, - sizeof(*prog->aux->jited_linfo), - bpf_memcg_flags(GFP_KERNEL | __GFP_NOWARN)); + prog->aux->jited_linfo = kvzalloc_objs(*prog->aux->jited_linfo, + prog->aux->nr_linfo, + bpf_memcg_flags(GFP_KERNEL | __GFP_NOWARN)); if (!prog->aux->jited_linfo) return -ENOMEM; @@ -910,8 +910,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins struct bpf_prog_pack *pack; int err; - pack = kzalloc(struct_size(pack, bitmap, BITS_TO_LONGS(BPF_PROG_CHUNK_COUNT)), - GFP_KERNEL); + pack = kzalloc_flex(*pack, bitmap, BITS_TO_LONGS(BPF_PROG_CHUNK_COUNT)); if (!pack) return NULL; pack->ptr = bpf_jit_alloc_exec(BPF_PROG_PACK_SIZE); @@ -2597,7 +2596,7 @@ struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags) struct bpf_prog_array *p; if (prog_cnt) - p = kzalloc(struct_size(p, items, prog_cnt + 1), flags); + p = kzalloc_flex(*p, items, prog_cnt + 1, flags); else p = &bpf_empty_prog_array.hdr; diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c index 04171fbc39cb..32b43cb9061b 100644 --- a/kernel/bpf/cpumap.c +++ b/kernel/bpf/cpumap.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,7 @@ struct xdp_bulk_queue { struct list_head flush_node; struct bpf_cpu_map_entry *obj; unsigned int count; + local_lock_t bq_lock; }; /* Struct for every remote "destination" CPU in map */ @@ -451,6 +453,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value, for_each_possible_cpu(i) { bq = per_cpu_ptr(rcpu->bulkq, i); bq->obj = rcpu; + local_lock_init(&bq->bq_lock); } /* Alloc queue */ @@ -722,6 +725,8 @@ static void bq_flush_to_queue(struct xdp_bulk_queue *bq) struct ptr_ring *q; int i; + lockdep_assert_held(&bq->bq_lock); + if (unlikely(!bq->count)) return; @@ -749,11 +754,15 @@ static void bq_flush_to_queue(struct xdp_bulk_queue *bq) } /* Runs under RCU-read-side, plus in softirq under NAPI protection. - * Thus, safe percpu variable access. + * Thus, safe percpu variable access. PREEMPT_RT relies on + * local_lock_nested_bh() to serialise access to the per-CPU bq. */ static void bq_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf) { - struct xdp_bulk_queue *bq = this_cpu_ptr(rcpu->bulkq); + struct xdp_bulk_queue *bq; + + local_lock_nested_bh(&rcpu->bulkq->bq_lock); + bq = this_cpu_ptr(rcpu->bulkq); if (unlikely(bq->count == CPU_MAP_BULK_SIZE)) bq_flush_to_queue(bq); @@ -774,6 +783,8 @@ static void bq_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf) list_add(&bq->flush_node, flush_list); } + + local_unlock_nested_bh(&rcpu->bulkq->bq_lock); } int cpu_map_enqueue(struct bpf_cpu_map_entry *rcpu, struct xdp_frame *xdpf, @@ -810,7 +821,9 @@ void __cpu_map_flush(struct list_head *flush_list) struct xdp_bulk_queue *bq, *tmp; list_for_each_entry_safe(bq, tmp, flush_list, flush_node) { + local_lock_nested_bh(&bq->obj->bulkq->bq_lock); bq_flush_to_queue(bq); + local_unlock_nested_bh(&bq->obj->bulkq->bq_lock); /* If already running, costs spin_lock_irqsave + smb_mb */ wake_up_process(bq->obj->kthread); diff --git a/kernel/bpf/crypto.c b/kernel/bpf/crypto.c index 7e75a1936256..51f89cecefb4 100644 --- a/kernel/bpf/crypto.c +++ b/kernel/bpf/crypto.c @@ -68,7 +68,7 @@ int bpf_crypto_register_type(const struct bpf_crypto_type *type) goto unlock; } - node = kmalloc(sizeof(*node), GFP_KERNEL); + node = kmalloc_obj(*node); err = -ENOMEM; if (!node) goto unlock; @@ -176,7 +176,7 @@ bpf_crypto_ctx_create(const struct bpf_crypto_params *params, u32 params__sz, goto err_module_put; } - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) { *err = -ENOMEM; goto err_module_put; diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index 2625601de76e..3d619d01088e 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -45,6 +45,7 @@ * types of devmap; only the lookup and insertion is different. */ #include +#include #include #include #include @@ -60,6 +61,7 @@ struct xdp_dev_bulk_queue { struct net_device *dev_rx; struct bpf_prog *xdp_prog; unsigned int count; + local_lock_t bq_lock; }; struct bpf_dtab_netdev { @@ -381,6 +383,8 @@ static void bq_xmit_all(struct xdp_dev_bulk_queue *bq, u32 flags) int to_send = cnt; int i; + lockdep_assert_held(&bq->bq_lock); + if (unlikely(!cnt)) return; @@ -425,10 +429,12 @@ void __dev_flush(struct list_head *flush_list) struct xdp_dev_bulk_queue *bq, *tmp; list_for_each_entry_safe(bq, tmp, flush_list, flush_node) { + local_lock_nested_bh(&bq->dev->xdp_bulkq->bq_lock); bq_xmit_all(bq, XDP_XMIT_FLUSH); bq->dev_rx = NULL; bq->xdp_prog = NULL; __list_del_clearprev(&bq->flush_node); + local_unlock_nested_bh(&bq->dev->xdp_bulkq->bq_lock); } } @@ -451,12 +457,16 @@ static void *__dev_map_lookup_elem(struct bpf_map *map, u32 key) /* Runs in NAPI, i.e., softirq under local_bh_disable(). Thus, safe percpu * variable access, and map elements stick around. See comment above - * xdp_do_flush() in filter.c. + * xdp_do_flush() in filter.c. PREEMPT_RT relies on local_lock_nested_bh() + * to serialise access to the per-CPU bq. */ static void bq_enqueue(struct net_device *dev, struct xdp_frame *xdpf, struct net_device *dev_rx, struct bpf_prog *xdp_prog) { - struct xdp_dev_bulk_queue *bq = this_cpu_ptr(dev->xdp_bulkq); + struct xdp_dev_bulk_queue *bq; + + local_lock_nested_bh(&dev->xdp_bulkq->bq_lock); + bq = this_cpu_ptr(dev->xdp_bulkq); if (unlikely(bq->count == DEV_MAP_BULK_SIZE)) bq_xmit_all(bq, 0); @@ -477,6 +487,8 @@ static void bq_enqueue(struct net_device *dev, struct xdp_frame *xdpf, } bq->q[bq->count++] = xdpf; + + local_unlock_nested_bh(&dev->xdp_bulkq->bq_lock); } static inline int __xdp_enqueue(struct net_device *dev, struct xdp_frame *xdpf, @@ -588,18 +600,22 @@ static inline bool is_ifindex_excluded(int *excluded, int num_excluded, int ifin } /* Get ifindex of each upper device. 'indexes' must be able to hold at - * least MAX_NEST_DEV elements. - * Returns the number of ifindexes added. + * least 'max' elements. + * Returns the number of ifindexes added, or -EOVERFLOW if there are too + * many upper devices. */ -static int get_upper_ifindexes(struct net_device *dev, int *indexes) +static int get_upper_ifindexes(struct net_device *dev, int *indexes, int max) { struct net_device *upper; struct list_head *iter; int n = 0; netdev_for_each_upper_dev_rcu(dev, upper, iter) { + if (n >= max) + return -EOVERFLOW; indexes[n++] = upper->ifindex; } + return n; } @@ -615,7 +631,11 @@ int dev_map_enqueue_multi(struct xdp_frame *xdpf, struct net_device *dev_rx, int err; if (exclude_ingress) { - num_excluded = get_upper_ifindexes(dev_rx, excluded_devices); + num_excluded = get_upper_ifindexes(dev_rx, excluded_devices, + ARRAY_SIZE(excluded_devices) - 1); + if (num_excluded < 0) + return num_excluded; + excluded_devices[num_excluded++] = dev_rx->ifindex; } @@ -733,7 +753,11 @@ int dev_map_redirect_multi(struct net_device *dev, struct sk_buff *skb, int err; if (exclude_ingress) { - num_excluded = get_upper_ifindexes(dev, excluded_devices); + num_excluded = get_upper_ifindexes(dev, excluded_devices, + ARRAY_SIZE(excluded_devices) - 1); + if (num_excluded < 0) + return num_excluded; + excluded_devices[num_excluded++] = dev->ifindex; } @@ -1115,8 +1139,13 @@ static int dev_map_notification(struct notifier_block *notifier, if (!netdev->xdp_bulkq) return NOTIFY_BAD; - for_each_possible_cpu(cpu) - per_cpu_ptr(netdev->xdp_bulkq, cpu)->dev = netdev; + for_each_possible_cpu(cpu) { + struct xdp_dev_bulk_queue *bq; + + bq = per_cpu_ptr(netdev->xdp_bulkq, cpu); + bq->dev = netdev; + local_lock_init(&bq->bq_lock); + } break; case NETDEV_UNREGISTER: /* This rcu_read_lock/unlock pair is needed because diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 3b9d297a53be..bc6bc8bb871d 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -125,6 +125,11 @@ struct htab_elem { char key[] __aligned(8); }; +struct htab_btf_record { + struct btf_record *record; + u32 key_size; +}; + static inline bool htab_is_prealloc(const struct bpf_htab *htab) { return !(htab->map.map_flags & BPF_F_NO_PREALLOC); @@ -457,6 +462,83 @@ static int htab_map_alloc_check(union bpf_attr *attr) return 0; } +static void htab_mem_dtor(void *obj, void *ctx) +{ + struct htab_btf_record *hrec = ctx; + struct htab_elem *elem = obj; + void *map_value; + + if (IS_ERR_OR_NULL(hrec->record)) + return; + + map_value = htab_elem_value(elem, hrec->key_size); + bpf_obj_free_fields(hrec->record, map_value); +} + +static void htab_pcpu_mem_dtor(void *obj, void *ctx) +{ + void __percpu *pptr = *(void __percpu **)obj; + struct htab_btf_record *hrec = ctx; + int cpu; + + if (IS_ERR_OR_NULL(hrec->record)) + return; + + for_each_possible_cpu(cpu) + bpf_obj_free_fields(hrec->record, per_cpu_ptr(pptr, cpu)); +} + +static void htab_dtor_ctx_free(void *ctx) +{ + struct htab_btf_record *hrec = ctx; + + btf_record_free(hrec->record); + kfree(ctx); +} + +static int htab_set_dtor(struct bpf_htab *htab, void (*dtor)(void *, void *)) +{ + u32 key_size = htab->map.key_size; + struct bpf_mem_alloc *ma; + struct htab_btf_record *hrec; + int err; + + /* No need for dtors. */ + if (IS_ERR_OR_NULL(htab->map.record)) + return 0; + + hrec = kzalloc(sizeof(*hrec), GFP_KERNEL); + if (!hrec) + return -ENOMEM; + hrec->key_size = key_size; + hrec->record = btf_record_dup(htab->map.record); + if (IS_ERR(hrec->record)) { + err = PTR_ERR(hrec->record); + kfree(hrec); + return err; + } + ma = htab_is_percpu(htab) ? &htab->pcpu_ma : &htab->ma; + bpf_mem_alloc_set_dtor(ma, dtor, htab_dtor_ctx_free, hrec); + return 0; +} + +static int htab_map_check_btf(struct bpf_map *map, const struct btf *btf, + const struct btf_type *key_type, const struct btf_type *value_type) +{ + struct bpf_htab *htab = container_of(map, struct bpf_htab, map); + + if (htab_is_prealloc(htab)) + return 0; + /* + * We must set the dtor using this callback, as map's BTF record is not + * populated in htab_map_alloc(), so it will always appear as NULL. + */ + if (htab_is_percpu(htab)) + return htab_set_dtor(htab, htab_pcpu_mem_dtor); + else + return htab_set_dtor(htab, htab_mem_dtor); +} + static struct bpf_map *htab_map_alloc(union bpf_attr *attr) { bool percpu = (attr->map_type == BPF_MAP_TYPE_PERCPU_HASH || @@ -2281,6 +2363,7 @@ const struct bpf_map_ops htab_map_ops = { .map_seq_show_elem = htab_map_seq_show_elem, .map_set_for_each_callback_args = map_set_for_each_callback_args, .map_for_each_callback = bpf_for_each_hash_elem, + .map_check_btf = htab_map_check_btf, .map_mem_usage = htab_map_mem_usage, BATCH_OPS(htab), .map_btf_id = &htab_map_btf_ids[0], @@ -2303,6 +2386,7 @@ const struct bpf_map_ops htab_lru_map_ops = { .map_seq_show_elem = htab_map_seq_show_elem, .map_set_for_each_callback_args = map_set_for_each_callback_args, .map_for_each_callback = bpf_for_each_hash_elem, + .map_check_btf = htab_map_check_btf, .map_mem_usage = htab_map_mem_usage, BATCH_OPS(htab_lru), .map_btf_id = &htab_map_btf_ids[0], @@ -2482,6 +2566,7 @@ const struct bpf_map_ops htab_percpu_map_ops = { .map_seq_show_elem = htab_percpu_map_seq_show_elem, .map_set_for_each_callback_args = map_set_for_each_callback_args, .map_for_each_callback = bpf_for_each_hash_elem, + .map_check_btf = htab_map_check_btf, .map_mem_usage = htab_map_mem_usage, BATCH_OPS(htab_percpu), .map_btf_id = &htab_map_btf_ids[0], @@ -2502,6 +2587,7 @@ const struct bpf_map_ops htab_lru_percpu_map_ops = { .map_seq_show_elem = htab_percpu_map_seq_show_elem, .map_set_for_each_callback_args = map_set_for_each_callback_args, .map_for_each_callback = bpf_for_each_hash_elem, + .map_check_btf = htab_map_check_btf, .map_mem_usage = htab_map_mem_usage, BATCH_OPS(htab_lru_percpu), .map_btf_id = &htab_map_btf_ids[0], diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 7ac32798eb04..6eb6c82ed2ee 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -3993,7 +3993,7 @@ __bpf_kfunc struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags) if (IS_ERR(key_ref)) return NULL; - bkey = kmalloc(sizeof(*bkey), GFP_KERNEL); + bkey = kmalloc_obj(*bkey); if (!bkey) { key_put(key_ref_to_ptr(key_ref)); return NULL; @@ -4033,7 +4033,7 @@ __bpf_kfunc struct bpf_key *bpf_lookup_system_key(u64 id) if (system_keyring_id_check(id) < 0) return NULL; - bkey = kmalloc(sizeof(*bkey), GFP_ATOMIC); + bkey = kmalloc_obj(*bkey, GFP_ATOMIC); if (!bkey) return NULL; diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 005ea3a2cda7..25c06a011825 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -195,7 +195,7 @@ static struct map_iter *map_iter_alloc(struct bpf_map *map) { struct map_iter *iter; - iter = kzalloc(sizeof(*iter), GFP_KERNEL | __GFP_NOWARN); + iter = kzalloc_obj(*iter, GFP_KERNEL | __GFP_NOWARN); if (!iter) goto error; @@ -1044,7 +1044,7 @@ static int bpf_init_fs_context(struct fs_context *fc) { struct bpf_mount_opts *opts; - opts = kzalloc(sizeof(struct bpf_mount_opts), GFP_KERNEL); + opts = kzalloc_obj(struct bpf_mount_opts); if (!opts) return -ENOMEM; diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c index 60db5d655495..998986853c61 100644 --- a/kernel/bpf/liveness.c +++ b/kernel/bpf/liveness.c @@ -193,8 +193,8 @@ static struct func_instance *__lookup_instance(struct bpf_verifier_env *env, result = kvzalloc(size, GFP_KERNEL_ACCOUNT); if (!result) return ERR_PTR(-ENOMEM); - result->must_write_set = kvcalloc(subprog_sz, sizeof(*result->must_write_set), - GFP_KERNEL_ACCOUNT); + result->must_write_set = kvzalloc_objs(*result->must_write_set, + subprog_sz, GFP_KERNEL_ACCOUNT); if (!result->must_write_set) { kvfree(result); return ERR_PTR(-ENOMEM); @@ -217,7 +217,7 @@ static struct func_instance *lookup_instance(struct bpf_verifier_env *env, int bpf_stack_liveness_init(struct bpf_verifier_env *env) { - env->liveness = kvzalloc(sizeof(*env->liveness), GFP_KERNEL_ACCOUNT); + env->liveness = kvzalloc_obj(*env->liveness, GFP_KERNEL_ACCOUNT); if (!env->liveness) return -ENOMEM; hash_init(env->liveness->func_instances); @@ -266,7 +266,8 @@ static struct per_frame_masks *alloc_frame_masks(struct bpf_verifier_env *env, struct per_frame_masks *arr; if (!instance->frames[frame]) { - arr = kvcalloc(instance->insn_cnt, sizeof(*arr), GFP_KERNEL_ACCOUNT); + arr = kvzalloc_objs(*arr, instance->insn_cnt, + GFP_KERNEL_ACCOUNT); instance->frames[frame] = arr; if (!arr) return ERR_PTR(-ENOMEM); diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c index 1ccbf28b2ad9..8fca0c64f7b1 100644 --- a/kernel/bpf/local_storage.c +++ b/kernel/bpf/local_storage.c @@ -364,7 +364,7 @@ static long cgroup_storage_delete_elem(struct bpf_map *map, void *key) return -EINVAL; } -static int cgroup_storage_check_btf(const struct bpf_map *map, +static int cgroup_storage_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c index be66d7e520e0..0f57608b385d 100644 --- a/kernel/bpf/lpm_trie.c +++ b/kernel/bpf/lpm_trie.c @@ -683,9 +683,9 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key) if (!key || key->prefixlen > trie->max_prefixlen) goto find_leftmost; - node_stack = kmalloc_array(trie->max_prefixlen + 1, - sizeof(struct lpm_trie_node *), - GFP_ATOMIC | __GFP_NOWARN); + node_stack = kmalloc_objs(struct lpm_trie_node *, + trie->max_prefixlen + 1, + GFP_ATOMIC | __GFP_NOWARN); if (!node_stack) return -ENOMEM; @@ -751,7 +751,7 @@ static int trie_get_next_key(struct bpf_map *map, void *_key, void *_next_key) return err; } -static int trie_check_btf(const struct bpf_map *map, +static int trie_check_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c index bd45dda9dc35..682a9f34214b 100644 --- a/kernel/bpf/memalloc.c +++ b/kernel/bpf/memalloc.c @@ -102,6 +102,8 @@ struct bpf_mem_cache { int percpu_size; bool draining; struct bpf_mem_cache *tgt; + void (*dtor)(void *obj, void *ctx); + void *dtor_ctx; /* list of objects to be freed after RCU GP */ struct llist_head free_by_rcu; @@ -260,12 +262,14 @@ static void free_one(void *obj, bool percpu) kfree(obj); } -static int free_all(struct llist_node *llnode, bool percpu) +static int free_all(struct bpf_mem_cache *c, struct llist_node *llnode, bool percpu) { struct llist_node *pos, *t; int cnt = 0; llist_for_each_safe(pos, t, llnode) { + if (c->dtor) + c->dtor((void *)pos + LLIST_NODE_SZ, c->dtor_ctx); free_one(pos, percpu); cnt++; } @@ -276,7 +280,7 @@ static void __free_rcu(struct rcu_head *head) { struct bpf_mem_cache *c = container_of(head, struct bpf_mem_cache, rcu_ttrace); - free_all(llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size); + free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), !!c->percpu_size); atomic_set(&c->call_rcu_ttrace_in_progress, 0); } @@ -308,7 +312,7 @@ static void do_call_rcu_ttrace(struct bpf_mem_cache *c) if (atomic_xchg(&c->call_rcu_ttrace_in_progress, 1)) { if (unlikely(READ_ONCE(c->draining))) { llnode = llist_del_all(&c->free_by_rcu_ttrace); - free_all(llnode, !!c->percpu_size); + free_all(c, llnode, !!c->percpu_size); } return; } @@ -417,7 +421,7 @@ static void check_free_by_rcu(struct bpf_mem_cache *c) dec_active(c, &flags); if (unlikely(READ_ONCE(c->draining))) { - free_all(llist_del_all(&c->waiting_for_gp), !!c->percpu_size); + free_all(c, llist_del_all(&c->waiting_for_gp), !!c->percpu_size); atomic_set(&c->call_rcu_in_progress, 0); } else { call_rcu_hurry(&c->rcu, __free_by_rcu); @@ -635,13 +639,13 @@ static void drain_mem_cache(struct bpf_mem_cache *c) * Except for waiting_for_gp_ttrace list, there are no concurrent operations * on these lists, so it is safe to use __llist_del_all(). */ - free_all(llist_del_all(&c->free_by_rcu_ttrace), percpu); - free_all(llist_del_all(&c->waiting_for_gp_ttrace), percpu); - free_all(__llist_del_all(&c->free_llist), percpu); - free_all(__llist_del_all(&c->free_llist_extra), percpu); - free_all(__llist_del_all(&c->free_by_rcu), percpu); - free_all(__llist_del_all(&c->free_llist_extra_rcu), percpu); - free_all(llist_del_all(&c->waiting_for_gp), percpu); + free_all(c, llist_del_all(&c->free_by_rcu_ttrace), percpu); + free_all(c, llist_del_all(&c->waiting_for_gp_ttrace), percpu); + free_all(c, __llist_del_all(&c->free_llist), percpu); + free_all(c, __llist_del_all(&c->free_llist_extra), percpu); + free_all(c, __llist_del_all(&c->free_by_rcu), percpu); + free_all(c, __llist_del_all(&c->free_llist_extra_rcu), percpu); + free_all(c, llist_del_all(&c->waiting_for_gp), percpu); } static void check_mem_cache(struct bpf_mem_cache *c) @@ -680,6 +684,9 @@ static void check_leaked_objs(struct bpf_mem_alloc *ma) static void free_mem_alloc_no_barrier(struct bpf_mem_alloc *ma) { + /* We can free dtor ctx only once all callbacks are done using it. */ + if (ma->dtor_ctx_free) + ma->dtor_ctx_free(ma->dtor_ctx); check_leaked_objs(ma); free_percpu(ma->cache); free_percpu(ma->caches); @@ -1014,3 +1021,32 @@ int bpf_mem_alloc_check_size(bool percpu, size_t size) return 0; } + +void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, void (*dtor)(void *obj, void *ctx), + void (*dtor_ctx_free)(void *ctx), void *ctx) +{ + struct bpf_mem_caches *cc; + struct bpf_mem_cache *c; + int cpu, i; + + ma->dtor_ctx_free = dtor_ctx_free; + ma->dtor_ctx = ctx; + + if (ma->cache) { + for_each_possible_cpu(cpu) { + c = per_cpu_ptr(ma->cache, cpu); + c->dtor = dtor; + c->dtor_ctx = ctx; + } + } + if (ma->caches) { + for_each_possible_cpu(cpu) { + cc = per_cpu_ptr(ma->caches, cpu); + for (i = 0; i < NUM_CACHES; i++) { + c = &cc->cache[i]; + c->dtor = dtor; + c->dtor_ctx = ctx; + } + } + } +} diff --git a/kernel/bpf/net_namespace.c b/kernel/bpf/net_namespace.c index 8e88201c98bf..25f30f9edaef 100644 --- a/kernel/bpf/net_namespace.c +++ b/kernel/bpf/net_namespace.c @@ -494,7 +494,7 @@ int netns_bpf_link_create(const union bpf_attr *attr, struct bpf_prog *prog) if (IS_ERR(net)) return PTR_ERR(net); - net_link = kzalloc(sizeof(*net_link), GFP_USER); + net_link = kzalloc_obj(*net_link, GFP_USER); if (!net_link) { err = -ENOMEM; goto out_put_net; diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index 227f9b5f388b..0ad97d643bf4 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -72,7 +72,7 @@ static int __bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev, struct bpf_offload_netdev *ondev; int err; - ondev = kzalloc(sizeof(*ondev), GFP_KERNEL); + ondev = kzalloc_obj(*ondev); if (!ondev) return -ENOMEM; @@ -182,7 +182,7 @@ static int __bpf_prog_dev_bound_init(struct bpf_prog *prog, struct net_device *n struct bpf_prog_offload *offload; int err; - offload = kzalloc(sizeof(*offload), GFP_USER); + offload = kzalloc_obj(*offload, GFP_USER); if (!offload) return -ENOMEM; @@ -777,7 +777,7 @@ bpf_offload_dev_create(const struct bpf_prog_offload_ops *ops, void *priv) { struct bpf_offload_dev *offdev; - offdev = kzalloc(sizeof(*offdev), GFP_KERNEL); + offdev = kzalloc_obj(*offdev); if (!offdev) return ERR_PTR(-ENOMEM); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index dd89bf809772..274039e36465 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1234,7 +1234,7 @@ int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size) } EXPORT_SYMBOL_GPL(bpf_obj_name_cpy); -int map_check_no_btf(const struct bpf_map *map, +int map_check_no_btf(struct bpf_map *map, const struct btf *btf, const struct btf_type *key_type, const struct btf_type *value_type) @@ -3633,7 +3633,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, if (prog->expected_attach_type == BPF_TRACE_FSESSION) { struct bpf_fsession_link *fslink; - fslink = kzalloc(sizeof(*fslink), GFP_USER); + fslink = kzalloc_obj(*fslink, GFP_USER); if (fslink) { bpf_link_init(&fslink->fexit.link, BPF_LINK_TYPE_TRACING, &bpf_tracing_link_lops, prog, attach_type); @@ -3643,7 +3643,7 @@ static int bpf_tracing_prog_attach(struct bpf_prog *prog, link = NULL; } } else { - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); } if (!link) { err = -ENOMEM; @@ -4183,7 +4183,7 @@ static int bpf_perf_link_attach(const union bpf_attr *attr, struct bpf_prog *pro if (IS_ERR(perf_file)) return PTR_ERR(perf_file); - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto out_put_file; @@ -4261,7 +4261,7 @@ static int bpf_raw_tp_link_attach(struct bpf_prog *prog, if (!btp) return -ENOENT; - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto out_put_btp; @@ -6076,9 +6076,8 @@ static int bpf_prog_bind_map(union bpf_attr *attr) goto out_unlock; } - used_maps_new = kmalloc_array(prog->aux->used_map_cnt + 1, - sizeof(used_maps_new[0]), - GFP_KERNEL); + used_maps_new = kmalloc_objs(used_maps_new[0], + prog->aux->used_map_cnt + 1); if (!used_maps_new) { ret = -ENOMEM; goto out_unlock; diff --git a/kernel/bpf/tcx.c b/kernel/bpf/tcx.c index efd987ea6872..02db0113b8e7 100644 --- a/kernel/bpf/tcx.c +++ b/kernel/bpf/tcx.c @@ -321,7 +321,7 @@ int tcx_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) ret = -ENODEV; goto out; } - tcx = kzalloc(sizeof(*tcx), GFP_USER); + tcx = kzalloc_obj(*tcx, GFP_USER); if (!tcx) { ret = -ENOMEM; goto out; diff --git a/kernel/bpf/tnum.c b/kernel/bpf/tnum.c index 26fbfbb01700..4abc359b3db0 100644 --- a/kernel/bpf/tnum.c +++ b/kernel/bpf/tnum.c @@ -269,3 +269,59 @@ struct tnum tnum_bswap64(struct tnum a) { return TNUM(swab64(a.value), swab64(a.mask)); } + +/* Given tnum t, and a number z such that tmin <= z < tmax, where tmin + * is the smallest member of the t (= t.value) and tmax is the largest + * member of t (= t.value | t.mask), returns the smallest member of t + * larger than z. + * + * For example, + * t = x11100x0 + * z = 11110001 (241) + * result = 11110010 (242) + * + * Note: if this function is called with z >= tmax, it just returns + * early with tmax; if this function is called with z < tmin, the + * algorithm already returns tmin. + */ +u64 tnum_step(struct tnum t, u64 z) +{ + u64 tmax, j, p, q, r, s, v, u, w, res; + u8 k; + + tmax = t.value | t.mask; + + /* if z >= largest member of t, return largest member of t */ + if (z >= tmax) + return tmax; + + /* if z < smallest member of t, return smallest member of t */ + if (z < t.value) + return t.value; + + /* keep t's known bits, and match all unknown bits to z */ + j = t.value | (z & t.mask); + + if (j > z) { + p = ~z & t.value & ~t.mask; + k = fls64(p); /* k is the most-significant 0-to-1 flip */ + q = U64_MAX << k; + r = q & z; /* positions > k matched to z */ + s = ~q & t.value; /* positions <= k matched to t.value */ + v = r | s; + res = v; + } else { + p = z & ~t.value & ~t.mask; + k = fls64(p); /* k is the most-significant 1-to-0 flip */ + q = U64_MAX << k; + r = q & t.mask & z; /* unknown positions > k, matched to z */ + s = q & ~t.mask; /* known positions > k, set to 1 */ + v = r | s; + /* add 1 to unknown positions > k to make value greater than z */ + u = v + (1ULL << k); + /* extract bits in unknown positions > k from u, rest from t.value */ + w = (u & t.mask) | t.value; + res = w; + } + return res; +} diff --git a/kernel/bpf/token.c b/kernel/bpf/token.c index 7e4aa1e44b50..e85a179523f0 100644 --- a/kernel/bpf/token.c +++ b/kernel/bpf/token.c @@ -172,7 +172,7 @@ int bpf_token_create(union bpf_attr *attr) if (fdf.err) return fdf.err; - token = kzalloc(sizeof(*token), GFP_USER); + token = kzalloc_obj(*token, GFP_USER); if (!token) return -ENOMEM; diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index 952cd7932461..f02254a21585 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -256,7 +256,7 @@ static int direct_ops_mod(struct bpf_trampoline *tr, void *addr, bool lock_direc */ static int direct_ops_alloc(struct bpf_trampoline *tr) { - tr->fops = kzalloc(sizeof(struct ftrace_ops), GFP_KERNEL); + tr->fops = kzalloc_obj(struct ftrace_ops); if (!tr->fops) return -ENOMEM; tr->fops->private = tr; @@ -342,7 +342,7 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key, unsigned long ip) goto out; } } - tr = kzalloc(sizeof(*tr), GFP_KERNEL); + tr = kzalloc_obj(*tr); if (!tr) goto out; if (direct_ops_alloc(tr)) { @@ -446,7 +446,7 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_a int kind; *total = 0; - tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL); + tlinks = kzalloc_objs(*tlinks, BPF_TRAMP_MAX); if (!tlinks) return ERR_PTR(-ENOMEM); @@ -569,7 +569,7 @@ static struct bpf_tramp_image *bpf_tramp_image_alloc(u64 key, int size) void *image; int err = -ENOMEM; - im = kzalloc(sizeof(*im), GFP_KERNEL); + im = kzalloc_obj(*im); if (!im) goto out; @@ -928,7 +928,7 @@ static struct bpf_shim_tramp_link *cgroup_shim_alloc(const struct bpf_prog *prog struct bpf_shim_tramp_link *shim_link = NULL; struct bpf_prog *p; - shim_link = kzalloc(sizeof(*shim_link), GFP_USER); + shim_link = kzalloc_obj(*shim_link, GFP_USER); if (!shim_link) return NULL; @@ -1002,10 +1002,8 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, mutex_lock(&tr->mutex); shim_link = cgroup_shim_find(tr, bpf_func); - if (shim_link) { + if (shim_link && !IS_ERR(bpf_link_inc_not_zero(&shim_link->link.link))) { /* Reusing existing shim attached by the other program. */ - bpf_link_inc(&shim_link->link.link); - mutex_unlock(&tr->mutex); bpf_trampoline_put(tr); /* bpf_trampoline_get above */ return 0; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index edf5342b982f..159b25f8269d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1779,7 +1779,7 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state, for (i = 0; i <= src->curframe; i++) { dst = dst_state->frame[i]; if (!dst) { - dst = kzalloc(sizeof(*dst), GFP_KERNEL_ACCOUNT); + dst = kzalloc_obj(*dst, GFP_KERNEL_ACCOUNT); if (!dst) return -ENOMEM; dst_state->frame[i] = dst; @@ -2127,7 +2127,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env, struct bpf_verifier_stack_elem *elem; int err; - elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT); + elem = kzalloc_obj(struct bpf_verifier_stack_elem, GFP_KERNEL_ACCOUNT); if (!elem) return ERR_PTR(-ENOMEM); @@ -2379,6 +2379,9 @@ static void __update_reg32_bounds(struct bpf_reg_state *reg) static void __update_reg64_bounds(struct bpf_reg_state *reg) { + u64 tnum_next, tmax; + bool umin_in_tnum; + /* min signed is max(sign bit) | min(other bits) */ reg->smin_value = max_t(s64, reg->smin_value, reg->var_off.value | (reg->var_off.mask & S64_MIN)); @@ -2388,6 +2391,33 @@ static void __update_reg64_bounds(struct bpf_reg_state *reg) reg->umin_value = max(reg->umin_value, reg->var_off.value); reg->umax_value = min(reg->umax_value, reg->var_off.value | reg->var_off.mask); + + /* Check if u64 and tnum overlap in a single value */ + tnum_next = tnum_step(reg->var_off, reg->umin_value); + umin_in_tnum = (reg->umin_value & ~reg->var_off.mask) == reg->var_off.value; + tmax = reg->var_off.value | reg->var_off.mask; + if (umin_in_tnum && tnum_next > reg->umax_value) { + /* The u64 range and the tnum only overlap in umin. + * u64: ---[xxxxxx]----- + * tnum: --xx----------x- + */ + ___mark_reg_known(reg, reg->umin_value); + } else if (!umin_in_tnum && tnum_next == tmax) { + /* The u64 range and the tnum only overlap in the maximum value + * represented by the tnum, called tmax. + * u64: ---[xxxxxx]----- + * tnum: xx-----x-------- + */ + ___mark_reg_known(reg, tmax); + } else if (!umin_in_tnum && tnum_next <= reg->umax_value && + tnum_step(reg->var_off, tnum_next) > reg->umax_value) { + /* The u64 range and the tnum only overlap in between umin + * (excluded) and umax. + * u64: ---[xxxxxx]----- + * tnum: xx----x-------x- + */ + ___mark_reg_known(reg, tnum_next); + } } static void __update_reg_bounds(struct bpf_reg_state *reg) @@ -2481,6 +2511,30 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg) if ((u32)reg->s32_min_value <= (u32)reg->s32_max_value) { reg->u32_min_value = max_t(u32, reg->s32_min_value, reg->u32_min_value); reg->u32_max_value = min_t(u32, reg->s32_max_value, reg->u32_max_value); + } else { + if (reg->u32_max_value < (u32)reg->s32_min_value) { + /* See __reg64_deduce_bounds() for detailed explanation. + * Refine ranges in the following situation: + * + * 0 U32_MAX + * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + * |----------------------------|----------------------------| + * |xxxxx s32 range xxxxxxxxx] [xxxxxxx| + * 0 S32_MAX S32_MIN -1 + */ + reg->s32_min_value = (s32)reg->u32_min_value; + reg->u32_max_value = min_t(u32, reg->u32_max_value, reg->s32_max_value); + } else if ((u32)reg->s32_max_value < reg->u32_min_value) { + /* + * 0 U32_MAX + * | [xxxxxxxxxxxxxx u32 range xxxxxxxxxxxxxx] | + * |----------------------------|----------------------------| + * |xxxxxxxxx] [xxxxxxxxxxxx s32 range | + * 0 S32_MAX S32_MIN -1 + */ + reg->s32_max_value = (s32)reg->u32_max_value; + reg->u32_min_value = max_t(u32, reg->u32_min_value, reg->s32_min_value); + } } } @@ -2949,7 +3003,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env, struct bpf_verifier_stack_elem *elem; struct bpf_func_state *frame; - elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT); + elem = kzalloc_obj(struct bpf_verifier_stack_elem, GFP_KERNEL_ACCOUNT); if (!elem) return ERR_PTR(-ENOMEM); @@ -2972,7 +3026,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env, */ elem->st.branches = 1; elem->st.in_sleepable = is_sleepable; - frame = kzalloc(sizeof(*frame), GFP_KERNEL_ACCOUNT); + frame = kzalloc_obj(*frame, GFP_KERNEL_ACCOUNT); if (!frame) return ERR_PTR(-ENOMEM); init_func_state(env, frame, @@ -3410,7 +3464,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset) return -EINVAL; } - tab = kzalloc(sizeof(*tab), GFP_KERNEL_ACCOUNT); + tab = kzalloc_obj(*tab, GFP_KERNEL_ACCOUNT); if (!tab) return -ENOMEM; prog_aux->kfunc_tab = tab; @@ -3426,7 +3480,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset) return 0; if (!btf_tab && offset) { - btf_tab = kzalloc(sizeof(*btf_tab), GFP_KERNEL_ACCOUNT); + btf_tab = kzalloc_obj(*btf_tab, GFP_KERNEL_ACCOUNT); if (!btf_tab) return -ENOMEM; prog_aux->kfunc_btf_tab = btf_tab; @@ -10580,7 +10634,7 @@ static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int calls } caller = state->frame[state->curframe]; - callee = kzalloc(sizeof(*callee), GFP_KERNEL_ACCOUNT); + callee = kzalloc_obj(*callee, GFP_KERNEL_ACCOUNT); if (!callee) return -ENOMEM; state->frame[state->curframe + 1] = callee; @@ -17305,17 +17359,24 @@ static void __collect_linked_regs(struct linked_regs *reg_set, struct bpf_reg_st * in verifier state, save R in linked_regs if R->id == id. * If there are too many Rs sharing same id, reset id for leftover Rs. */ -static void collect_linked_regs(struct bpf_verifier_state *vstate, u32 id, +static void collect_linked_regs(struct bpf_verifier_env *env, + struct bpf_verifier_state *vstate, + u32 id, struct linked_regs *linked_regs) { + struct bpf_insn_aux_data *aux = env->insn_aux_data; struct bpf_func_state *func; struct bpf_reg_state *reg; + u16 live_regs; int i, j; id = id & ~BPF_ADD_CONST; for (i = vstate->curframe; i >= 0; i--) { + live_regs = aux[frame_insn_idx(vstate, i)].live_regs_before; func = vstate->frame[i]; for (j = 0; j < BPF_REG_FP; j++) { + if (!(live_regs & BIT(j))) + continue; reg = &func->regs[j]; __collect_linked_regs(linked_regs, reg, id, i, j, true); } @@ -17530,9 +17591,9 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, * if parent state is created. */ if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id) - collect_linked_regs(this_branch, src_reg->id, &linked_regs); + collect_linked_regs(env, this_branch, src_reg->id, &linked_regs); if (dst_reg->type == SCALAR_VALUE && dst_reg->id) - collect_linked_regs(this_branch, dst_reg->id, &linked_regs); + collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs); if (linked_regs.cnt > 1) { err = push_jmp_history(env, this_branch, 0, linked_regs_pack(&linked_regs)); if (err) @@ -18860,11 +18921,13 @@ static int check_cfg(struct bpf_verifier_env *env) int *insn_stack, *insn_state; int ex_insn_beg, i, ret = 0; - insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT); + insn_state = env->cfg.insn_state = kvzalloc_objs(int, insn_cnt, + GFP_KERNEL_ACCOUNT); if (!insn_state) return -ENOMEM; - insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT); + insn_stack = env->cfg.insn_stack = kvzalloc_objs(int, insn_cnt, + GFP_KERNEL_ACCOUNT); if (!insn_stack) { kvfree(insn_state); return -ENOMEM; @@ -18951,9 +19014,9 @@ static int compute_postorder(struct bpf_verifier_env *env) int *stack = NULL, *postorder = NULL, *state = NULL; struct bpf_iarray *succ; - postorder = kvcalloc(env->prog->len, sizeof(int), GFP_KERNEL_ACCOUNT); - state = kvcalloc(env->prog->len, sizeof(int), GFP_KERNEL_ACCOUNT); - stack = kvcalloc(env->prog->len, sizeof(int), GFP_KERNEL_ACCOUNT); + postorder = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT); + state = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT); + stack = kvzalloc_objs(int, env->prog->len, GFP_KERNEL_ACCOUNT); if (!postorder || !state || !stack) { kvfree(postorder); kvfree(state); @@ -19147,7 +19210,8 @@ static int check_btf_func(struct bpf_verifier_env *env, urecord = make_bpfptr(attr->func_info, uattr.is_kernel); krecord = prog->aux->func_info; - info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + info_aux = kzalloc_objs(*info_aux, nfuncs, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!info_aux) return -ENOMEM; @@ -19232,8 +19296,8 @@ static int check_btf_line(struct bpf_verifier_env *env, /* Need to zero it in case the userspace may * pass in a smaller bpf_line_info object. */ - linfo = kvcalloc(nr_linfo, sizeof(struct bpf_line_info), - GFP_KERNEL_ACCOUNT | __GFP_NOWARN); + linfo = kvzalloc_objs(struct bpf_line_info, nr_linfo, + GFP_KERNEL_ACCOUNT | __GFP_NOWARN); if (!linfo) return -ENOMEM; @@ -20619,7 +20683,8 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) if (loop) { struct bpf_scc_backedge *backedge; - backedge = kzalloc(sizeof(*backedge), GFP_KERNEL_ACCOUNT); + backedge = kzalloc_obj(*backedge, + GFP_KERNEL_ACCOUNT); if (!backedge) return -ENOMEM; err = copy_verifier_state(&backedge->state, cur); @@ -20683,7 +20748,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx) * When looping the sl->state.branches will be > 0 and this state * will not be considered for equivalence until branches == 0. */ - new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL_ACCOUNT); + new_sl = kzalloc_obj(struct bpf_verifier_state_list, GFP_KERNEL_ACCOUNT); if (!new_sl) return -ENOMEM; env->total_states++; @@ -21333,29 +21398,29 @@ static int find_btf_percpu_datasec(struct btf *btf) } /* - * Add btf to the used_btfs array and return the index. (If the btf was - * already added, then just return the index.) Upon successful insertion - * increase btf refcnt, and, if present, also refcount the corresponding - * kernel module. + * Add btf to the env->used_btfs array. If needed, refcount the + * corresponding kernel module. To simplify caller's logic + * in case of error or if btf was added before the function + * decreases the btf refcount. */ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) { struct btf_mod_pair *btf_mod; + int ret = 0; int i; /* check whether we recorded this BTF (and maybe module) already */ for (i = 0; i < env->used_btf_cnt; i++) if (env->used_btfs[i].btf == btf) - return i; + goto ret_put; if (env->used_btf_cnt >= MAX_USED_BTFS) { verbose(env, "The total number of btfs per program has reached the limit of %u\n", MAX_USED_BTFS); - return -E2BIG; + ret = -E2BIG; + goto ret_put; } - btf_get(btf); - btf_mod = &env->used_btfs[env->used_btf_cnt]; btf_mod->btf = btf; btf_mod->module = NULL; @@ -21364,12 +21429,18 @@ static int __add_used_btf(struct bpf_verifier_env *env, struct btf *btf) if (btf_is_module(btf)) { btf_mod->module = btf_try_get_module(btf); if (!btf_mod->module) { - btf_put(btf); - return -ENXIO; + ret = -ENXIO; + goto ret_put; } } - return env->used_btf_cnt++; + env->used_btf_cnt++; + return 0; + +ret_put: + /* Either error or this BTF was already added */ + btf_put(btf); + return ret; } /* replace pseudo btf_id with kernel symbol address */ @@ -21466,9 +21537,7 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, btf_fd = insn[1].imm; if (btf_fd) { - CLASS(fd, f)(btf_fd); - - btf = __btf_get_by_fd(f); + btf = btf_get_by_fd(btf_fd); if (IS_ERR(btf)) { verbose(env, "invalid module BTF object FD specified.\n"); return -EINVAL; @@ -21478,17 +21547,17 @@ static int check_pseudo_btf_id(struct bpf_verifier_env *env, verbose(env, "kernel is missing BTF, make sure CONFIG_DEBUG_INFO_BTF=y is specified in Kconfig.\n"); return -EINVAL; } + btf_get(btf_vmlinux); btf = btf_vmlinux; } err = __check_pseudo_btf_id(env, insn, aux, btf); - if (err) + if (err) { + btf_put(btf); return err; + } - err = __add_used_btf(env, btf); - if (err < 0) - return err; - return 0; + return __add_used_btf(env, btf); } static bool is_tracing_prog_type(enum bpf_prog_type type) @@ -22761,7 +22830,7 @@ static int jit_subprogs(struct bpf_verifier_env *env) goto out_undo_insn; err = -ENOMEM; - func = kcalloc(env->subprog_cnt, sizeof(prog), GFP_KERNEL); + func = kzalloc_objs(prog, env->subprog_cnt); if (!func) goto out_undo_insn; @@ -24468,14 +24537,14 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog) env->prev_linfo = NULL; env->pass_cnt++; - state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL_ACCOUNT); + state = kzalloc_obj(struct bpf_verifier_state, GFP_KERNEL_ACCOUNT); if (!state) return -ENOMEM; state->curframe = 0; state->speculative = false; state->branches = 1; state->in_sleepable = env->prog->sleepable; - state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL_ACCOUNT); + state->frame[0] = kzalloc_obj(struct bpf_func_state, GFP_KERNEL_ACCOUNT); if (!state->frame[0]) { kfree(state); return -ENOMEM; @@ -25223,7 +25292,6 @@ BTF_ID(func, __x64_sys_exit_group) BTF_ID(func, do_exit) BTF_ID(func, do_group_exit) BTF_ID(func, kthread_complete_and_exit) -BTF_ID(func, kthread_exit) BTF_ID(func, make_task_dead) BTF_SET_END(noreturn_deny) @@ -25370,10 +25438,8 @@ static int add_fd_from_fd_array(struct bpf_verifier_env *env, int fd) btf = __btf_get_by_fd(f); if (!IS_ERR(btf)) { - err = __add_used_btf(env, btf); - if (err < 0) - return err; - return 0; + btf_get(btf); + return __add_used_btf(env, btf); } verbose(env, "fd %d is not pointing to valid bpf_map or btf\n", fd); @@ -25598,7 +25664,7 @@ static int compute_live_registers(struct bpf_verifier_env *env) * - repeat the computation while {in,out} fields changes for * any instruction. */ - state = kvcalloc(insn_cnt, sizeof(*state), GFP_KERNEL_ACCOUNT); + state = kvzalloc_objs(*state, insn_cnt, GFP_KERNEL_ACCOUNT); if (!state) { err = -ENOMEM; goto out; @@ -25826,7 +25892,8 @@ static int compute_scc(struct bpf_verifier_env *env) dfs_sz--; } } - env->scc_info = kvcalloc(next_scc_id, sizeof(*env->scc_info), GFP_KERNEL_ACCOUNT); + env->scc_info = kvzalloc_objs(*env->scc_info, next_scc_id, + GFP_KERNEL_ACCOUNT); if (!env->scc_info) { err = -ENOMEM; goto exit; @@ -25857,7 +25924,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 /* 'struct bpf_verifier_env' can be global, but since it's not small, * allocate/free it every time bpf_check() is called */ - env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL_ACCOUNT); + env = kvzalloc_obj(struct bpf_verifier_env, GFP_KERNEL_ACCOUNT); if (!env) return -ENOMEM; @@ -25921,9 +25988,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 env->test_state_freq = attr->prog_flags & BPF_F_TEST_STATE_FREQ; env->test_reg_invariants = attr->prog_flags & BPF_F_TEST_REG_INVARIANTS; - env->explored_states = kvcalloc(state_htab_size(env), - sizeof(struct list_head), - GFP_KERNEL_ACCOUNT); + env->explored_states = kvzalloc_objs(struct list_head, + state_htab_size(env), + GFP_KERNEL_ACCOUNT); ret = -ENOMEM; if (!env->explored_states) goto skip_full_check; @@ -26060,9 +26127,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 if (env->used_map_cnt) { /* if program passed verifier, update used_maps in bpf_prog_info */ - env->prog->aux->used_maps = kmalloc_array(env->used_map_cnt, - sizeof(env->used_maps[0]), - GFP_KERNEL_ACCOUNT); + env->prog->aux->used_maps = kmalloc_objs(env->used_maps[0], + env->used_map_cnt, + GFP_KERNEL_ACCOUNT); if (!env->prog->aux->used_maps) { ret = -ENOMEM; @@ -26075,9 +26142,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3 } if (env->used_btf_cnt) { /* if program passed verifier, update used_btfs in bpf_prog_aux */ - env->prog->aux->used_btfs = kmalloc_array(env->used_btf_cnt, - sizeof(env->used_btfs[0]), - GFP_KERNEL_ACCOUNT); + env->prog->aux->used_btfs = kmalloc_objs(env->used_btfs[0], + env->used_btf_cnt, + GFP_KERNEL_ACCOUNT); if (!env->prog->aux->used_btfs) { ret = -ENOMEM; goto err_release_maps; diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index 724950c4b690..a4337c9b5287 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -317,7 +317,7 @@ static struct cgroup_pidlist *cgroup_pidlist_find_create(struct cgroup *cgrp, return l; /* entry not found; create a new one */ - l = kzalloc(sizeof(struct cgroup_pidlist), GFP_KERNEL); + l = kzalloc_obj(struct cgroup_pidlist); if (!l) return l; @@ -352,7 +352,7 @@ static int pidlist_array_load(struct cgroup *cgrp, enum cgroup_filetype type, * show up until sometime later on. */ length = cgroup_task_count(cgrp); - array = kvmalloc_array(length, sizeof(pid_t), GFP_KERNEL); + array = kvmalloc_objs(pid_t, length); if (!array) return -ENOMEM; /* now, populate the array */ @@ -1237,7 +1237,7 @@ static int cgroup1_root_to_use(struct fs_context *fc) if (ctx->ns != &init_cgroup_ns) return -EPERM; - root = kzalloc(sizeof(*root), GFP_KERNEL); + root = kzalloc_obj(*root); if (!root) return -ENOMEM; diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 8af4351536cf..01fc2a93f3ef 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -1168,7 +1168,7 @@ static int allocate_cgrp_cset_links(int count, struct list_head *tmp_links) INIT_LIST_HEAD(tmp_links); for (i = 0; i < count; i++) { - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) { free_cgrp_cset_links(tmp_links); return -ENOMEM; @@ -1241,7 +1241,7 @@ static struct css_set *find_css_set(struct css_set *old_cset, if (cset) return cset; - cset = kzalloc(sizeof(*cset), GFP_KERNEL); + cset = kzalloc_obj(*cset); if (!cset) return NULL; @@ -2350,7 +2350,7 @@ static int cgroup_init_fs_context(struct fs_context *fc) { struct cgroup_fs_context *ctx; - ctx = kzalloc(sizeof(struct cgroup_fs_context), GFP_KERNEL); + ctx = kzalloc_obj(struct cgroup_fs_context); if (!ctx) return -ENOMEM; @@ -2608,6 +2608,7 @@ static void cgroup_migrate_add_task(struct task_struct *task, mgctx->tset.nr_tasks++; + css_set_skip_task_iters(cset, task); list_move_tail(&task->cg_list, &cset->mg_tasks); if (list_empty(&cset->mg_node)) list_add_tail(&cset->mg_node, @@ -4251,7 +4252,7 @@ static int cgroup_file_open(struct kernfs_open_file *of) struct cgroup_file_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -5108,6 +5109,12 @@ static void css_task_iter_advance(struct css_task_iter *it) return; task = list_entry(it->task_pos, struct task_struct, cg_list); + /* + * Hide tasks that are exiting but not yet removed. Keep zombie + * leaders with live threads visible. + */ + if ((task->flags & PF_EXITING) && !atomic_read(&task->signal->live)) + goto repeat; if (it->flags & CSS_TASK_ITER_PROCS) { /* if PROCS, skip over tasks which aren't group leaders */ @@ -5844,7 +5851,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, int ret; /* allocate the cgroup and its ID, 0 is reserved for the root */ - cgrp = kzalloc(struct_size(cgrp, _low_ancestors, level), GFP_KERNEL); + cgrp = kzalloc_flex(*cgrp, _low_ancestors, level); if (!cgrp) return ERR_PTR(-ENOMEM); diff --git a/kernel/cgroup/cpuset-v1.c b/kernel/cgroup/cpuset-v1.c index 7a23b9e8778f..7308e9b02495 100644 --- a/kernel/cgroup/cpuset-v1.c +++ b/kernel/cgroup/cpuset-v1.c @@ -316,7 +316,7 @@ void cpuset1_hotplug_update_tasks(struct cpuset *cs, css_tryget_online(&cs->css)) { struct cpuset_remove_tasks_struct *s; - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (WARN_ON_ONCE(!s)) { css_put(&cs->css); return; @@ -653,7 +653,7 @@ int cpuset1_generate_sched_domains(cpumask_var_t **domains, if (!doms) goto done; - dattr = kmalloc(sizeof(struct sched_domain_attr), GFP_KERNEL); + dattr = kmalloc_obj(struct sched_domain_attr); if (dattr) { *dattr = SD_ATTR_INIT; update_domain_attr_tree(dattr, &top_cpuset); @@ -664,7 +664,7 @@ int cpuset1_generate_sched_domains(cpumask_var_t **domains, goto done; } - csa = kmalloc_array(nr_cpusets(), sizeof(cp), GFP_KERNEL); + csa = kmalloc_objs(cp, nr_cpusets()); if (!csa) goto done; csn = 0; @@ -727,8 +727,7 @@ int cpuset1_generate_sched_domains(cpumask_var_t **domains, * The rest of the code, including the scheduler, can deal with * dattr==NULL case. No need to abort if alloc fails. */ - dattr = kmalloc_array(ndoms, sizeof(struct sched_domain_attr), - GFP_KERNEL); + dattr = kmalloc_objs(struct sched_domain_attr, ndoms); for (nslot = 0, i = 0; i < csn; i++) { nslot_update = 0; diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 832179236529..d21868455341 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -61,6 +61,75 @@ static const char * const perr_strings[] = { [PERR_REMOTE] = "Have remote partition underneath", }; +/* + * CPUSET Locking Convention + * ------------------------- + * + * Below are the four global/local locks guarding cpuset structures in lock + * acquisition order: + * - cpuset_top_mutex + * - cpu_hotplug_lock (cpus_read_lock/cpus_write_lock) + * - cpuset_mutex + * - callback_lock (raw spinlock) + * + * As cpuset will now indirectly flush a number of different workqueues in + * housekeeping_update() to update housekeeping cpumasks when the set of + * isolated CPUs is going to be changed, it may be vulnerable to deadlock + * if we hold cpus_read_lock while calling into housekeeping_update(). + * + * The first cpuset_top_mutex will be held except when calling into + * cpuset_handle_hotplug() from the CPU hotplug code where cpus_write_lock + * and cpuset_mutex will be held instead. The main purpose of this mutex + * is to prevent regular cpuset control file write actions from interfering + * with the call to housekeeping_update(), though CPU hotplug operation can + * still happen in parallel. This mutex also provides protection for some + * internal variables. + * + * A task must hold all the remaining three locks to modify externally visible + * or used fields of cpusets, though some of the internally used cpuset fields + * and internal variables can be modified without holding callback_lock. If only + * reliable read access of the externally used fields are needed, a task can + * hold either cpuset_mutex or callback_lock which are exposed to other + * external subsystems. + * + * If a task holds cpu_hotplug_lock and cpuset_mutex, it blocks others, + * ensuring that it is the only task able to also acquire callback_lock and + * be able to modify cpusets. It can perform various checks on the cpuset + * structure first, knowing nothing will change. It can also allocate memory + * without holding callback_lock. While it is performing these checks, various + * callback routines can briefly acquire callback_lock to query cpusets. Once + * it is ready to make the changes, it takes callback_lock, blocking everyone + * else. + * + * Calls to the kernel memory allocator cannot be made while holding + * callback_lock which is a spinlock, as the memory allocator may sleep or + * call back into cpuset code and acquire callback_lock. + * + * Now, the task_struct fields mems_allowed and mempolicy may be changed + * by other task, we use alloc_lock in the task_struct fields to protect + * them. + * + * The cpuset_common_seq_show() handlers only hold callback_lock across + * small pieces of code, such as when reading out possibly multi-word + * cpumasks and nodemasks. + */ + +static DEFINE_MUTEX(cpuset_top_mutex); +static DEFINE_MUTEX(cpuset_mutex); + +/* + * File level internal variables below follow one of the following exclusion + * rules. + * + * RWCS: Read/write-able by holding either cpus_write_lock (and optionally + * cpuset_mutex) or both cpus_read_lock and cpuset_mutex. + * + * CSCB: Readable by holding either cpuset_mutex or callback_lock. Writable + * by holding both cpuset_mutex and callback_lock. + * + * T: Read/write-able by holding the cpuset_top_mutex. + */ + /* * For local partitions, update to subpartitions_cpus & isolated_cpus is done * in update_parent_effective_cpumask(). For remote partitions, it is done in @@ -70,19 +139,22 @@ static const char * const perr_strings[] = { * Exclusive CPUs distributed out to local or remote sub-partitions of * top_cpuset */ -static cpumask_var_t subpartitions_cpus; +static cpumask_var_t subpartitions_cpus; /* RWCS */ /* - * Exclusive CPUs in isolated partitions + * Exclusive CPUs in isolated partitions (shown in cpuset.cpus.isolated) */ -static cpumask_var_t isolated_cpus; +static cpumask_var_t isolated_cpus; /* CSCB */ /* - * isolated_cpus updating flag (protected by cpuset_mutex) - * Set if isolated_cpus is going to be updated in the current - * cpuset_mutex crtical section. + * Set if housekeeping cpumasks are to be updated. */ -static bool isolated_cpus_updating; +static bool update_housekeeping; /* RWCS */ + +/* + * Copy of isolated_cpus to be passed to housekeeping_update() + */ +static cpumask_var_t isolated_hk_cpus; /* T */ /* * A flag to force sched domain rebuild at the end of an operation. @@ -98,7 +170,7 @@ static bool isolated_cpus_updating; * Note that update_relax_domain_level() in cpuset-v1.c can still call * rebuild_sched_domains_locked() directly without using this flag. */ -static bool force_sd_rebuild; +static bool force_sd_rebuild; /* RWCS */ /* * Partition root states: @@ -218,42 +290,6 @@ struct cpuset top_cpuset = { .partition_root_state = PRS_ROOT, }; -/* - * There are two global locks guarding cpuset structures - cpuset_mutex and - * callback_lock. The cpuset code uses only cpuset_mutex. Other kernel - * subsystems can use cpuset_lock()/cpuset_unlock() to prevent change to cpuset - * structures. Note that cpuset_mutex needs to be a mutex as it is used in - * paths that rely on priority inheritance (e.g. scheduler - on RT) for - * correctness. - * - * A task must hold both locks to modify cpusets. If a task holds - * cpuset_mutex, it blocks others, ensuring that it is the only task able to - * also acquire callback_lock and be able to modify cpusets. It can perform - * various checks on the cpuset structure first, knowing nothing will change. - * It can also allocate memory while just holding cpuset_mutex. While it is - * performing these checks, various callback routines can briefly acquire - * callback_lock to query cpusets. Once it is ready to make the changes, it - * takes callback_lock, blocking everyone else. - * - * Calls to the kernel memory allocator can not be made while holding - * callback_lock, as that would risk double tripping on callback_lock - * from one of the callbacks into the cpuset code from within - * __alloc_pages(). - * - * If a task is only holding callback_lock, then it has read-only - * access to cpusets. - * - * Now, the task_struct fields mems_allowed and mempolicy may be changed - * by other task, we use alloc_lock in the task_struct fields to protect - * them. - * - * The cpuset_common_seq_show() handlers only hold callback_lock across - * small pieces of code, such as when reading out possibly multi-word - * cpumasks and nodemasks. - */ - -static DEFINE_MUTEX(cpuset_mutex); - /** * cpuset_lock - Acquire the global cpuset mutex * @@ -283,6 +319,7 @@ void lockdep_assert_cpuset_lock_held(void) */ void cpuset_full_lock(void) { + mutex_lock(&cpuset_top_mutex); cpus_read_lock(); mutex_lock(&cpuset_mutex); } @@ -291,12 +328,14 @@ void cpuset_full_unlock(void) { mutex_unlock(&cpuset_mutex); cpus_read_unlock(); + mutex_unlock(&cpuset_top_mutex); } #ifdef CONFIG_LOCKDEP bool lockdep_is_cpuset_held(void) { - return lockdep_is_held(&cpuset_mutex); + return lockdep_is_held(&cpuset_mutex) || + lockdep_is_held(&cpuset_top_mutex); } #endif @@ -536,7 +575,7 @@ static struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs) /* Allocate base structure */ trial = cs ? kmemdup(cs, sizeof(*cs), GFP_KERNEL) : - kzalloc(sizeof(*cs), GFP_KERNEL); + kzalloc_obj(*cs); if (!trial) return NULL; @@ -791,7 +830,7 @@ static int generate_sched_domains(cpumask_var_t **domains, goto generate_doms; } - csa = kmalloc_array(nr_cpusets(), sizeof(cp), GFP_KERNEL); + csa = kmalloc_objs(cp, nr_cpusets()); if (!csa) goto done; @@ -835,13 +874,12 @@ static int generate_sched_domains(cpumask_var_t **domains, * The rest of the code, including the scheduler, can deal with * dattr==NULL case. No need to abort if alloc fails. */ - dattr = kmalloc_array(ndoms, sizeof(struct sched_domain_attr), - GFP_KERNEL); + dattr = kmalloc_objs(struct sched_domain_attr, ndoms); /* * Cgroup v2 doesn't support domain attributes, just set all of them * to SD_ATTR_INIT. Also non-isolating partition root CPUs are a - * subset of HK_TYPE_DOMAIN housekeeping CPUs. + * subset of HK_TYPE_DOMAIN_BOOT housekeeping CPUs. */ for (i = 0; i < ndoms; i++) { /* @@ -850,7 +888,7 @@ static int generate_sched_domains(cpumask_var_t **domains, */ if (!csa || csa[i] == &top_cpuset) cpumask_and(doms[i], top_cpuset.effective_cpus, - housekeeping_cpumask(HK_TYPE_DOMAIN)); + housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT)); else cpumask_copy(doms[i], csa[i]->effective_cpus); if (dattr) @@ -962,7 +1000,7 @@ void rebuild_sched_domains_locked(void) * offline CPUs, a warning is emitted and we return directly to * prevent the panic. */ - for (i = 0; i < ndoms; ++i) { + for (i = 0; doms && i < ndoms; i++) { if (WARN_ON_ONCE(!cpumask_subset(doms[i], cpu_active_mask))) return; } @@ -1162,12 +1200,18 @@ static void reset_partition_data(struct cpuset *cs) static void isolated_cpus_update(int old_prs, int new_prs, struct cpumask *xcpus) { WARN_ON_ONCE(old_prs == new_prs); - if (new_prs == PRS_ISOLATED) + lockdep_assert_held(&callback_lock); + lockdep_assert_held(&cpuset_mutex); + if (new_prs == PRS_ISOLATED) { + if (cpumask_subset(xcpus, isolated_cpus)) + return; cpumask_or(isolated_cpus, isolated_cpus, xcpus); - else + } else { + if (!cpumask_intersects(xcpus, isolated_cpus)) + return; cpumask_andnot(isolated_cpus, isolated_cpus, xcpus); - - isolated_cpus_updating = true; + } + update_housekeeping = true; } /* @@ -1220,8 +1264,8 @@ static void partition_xcpus_del(int old_prs, struct cpuset *parent, isolated_cpus_update(old_prs, parent->partition_root_state, xcpus); - cpumask_and(xcpus, xcpus, cpu_active_mask); cpumask_or(parent->effective_cpus, parent->effective_cpus, xcpus); + cpumask_and(parent->effective_cpus, parent->effective_cpus, cpu_active_mask); } /* @@ -1285,22 +1329,45 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus) } /* - * update_isolation_cpumasks - Update external isolation related CPU masks + * cpuset_update_sd_hk_unlock - Rebuild sched domains, update HK & unlock * - * The following external CPU masks will be updated if necessary: - * - workqueue unbound cpumask + * Update housekeeping cpumasks and rebuild sched domains if necessary and + * then do a cpuset_full_unlock(). + * This should be called at the end of cpuset operation. */ -static void update_isolation_cpumasks(void) +static void cpuset_update_sd_hk_unlock(void) + __releases(&cpuset_mutex) + __releases(&cpuset_top_mutex) { - int ret; + /* force_sd_rebuild will be cleared in rebuild_sched_domains_locked() */ + if (force_sd_rebuild) + rebuild_sched_domains_locked(); - if (!isolated_cpus_updating) - return; + if (update_housekeeping) { + update_housekeeping = false; + cpumask_copy(isolated_hk_cpus, isolated_cpus); - ret = housekeeping_update(isolated_cpus); - WARN_ON_ONCE(ret < 0); + /* + * housekeeping_update() is now called without holding + * cpus_read_lock and cpuset_mutex. Only cpuset_top_mutex + * is still being held for mutual exclusion. + */ + mutex_unlock(&cpuset_mutex); + cpus_read_unlock(); + WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus)); + mutex_unlock(&cpuset_top_mutex); + } else { + cpuset_full_unlock(); + } +} - isolated_cpus_updating = false; +/* + * Work function to invoke cpuset_update_sd_hk_unlock() + */ +static void hk_sd_workfn(struct work_struct *work) +{ + cpuset_full_lock(); + cpuset_update_sd_hk_unlock(); } /** @@ -1451,7 +1518,6 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs, cs->remote_partition = true; cpumask_copy(cs->effective_xcpus, tmp->new_cpus); spin_unlock_irq(&callback_lock); - update_isolation_cpumasks(); cpuset_force_rebuild(); cs->prs_err = 0; @@ -1496,7 +1562,6 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp) compute_excpus(cs, cs->effective_xcpus); reset_partition_data(cs); spin_unlock_irq(&callback_lock); - update_isolation_cpumasks(); cpuset_force_rebuild(); /* @@ -1567,7 +1632,6 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *xcpus, if (xcpus) cpumask_copy(cs->exclusive_cpus, xcpus); spin_unlock_irq(&callback_lock); - update_isolation_cpumasks(); if (adding || deleting) cpuset_force_rebuild(); @@ -1911,7 +1975,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, partition_xcpus_add(new_prs, parent, tmp->delmask); spin_unlock_irq(&callback_lock); - update_isolation_cpumasks(); if ((old_prs != new_prs) && (cmd == partcmd_update)) update_partition_exclusive_flag(cs, new_prs); @@ -2156,7 +2219,7 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp, WARN_ON(!is_in_v2_mode() && !cpumask_equal(cp->cpus_allowed, cp->effective_cpus)); - cpuset_update_tasks_cpumask(cp, cp->effective_cpus); + cpuset_update_tasks_cpumask(cp, tmp->new_cpus); /* * On default hierarchy, inherit the CS_SCHED_LOAD_BALANCE @@ -2479,7 +2542,7 @@ static void cpuset_migrate_mm(struct mm_struct *mm, const nodemask_t *from, return; } - mwork = kzalloc(sizeof(*mwork), GFP_KERNEL); + mwork = kzalloc_obj(*mwork); if (mwork) { mwork->mm = mm; mwork->from = *from; @@ -2501,7 +2564,7 @@ static void schedule_flush_migrate_mm(void) { struct callback_head *flush_cb; - flush_cb = kzalloc(sizeof(struct callback_head), GFP_KERNEL); + flush_cb = kzalloc_obj(struct callback_head); if (!flush_cb) return; @@ -2879,7 +2942,6 @@ static int update_prstate(struct cpuset *cs, int new_prs) else if (isolcpus_updated) isolated_cpus_update(old_prs, new_prs, cs->effective_xcpus); spin_unlock_irq(&callback_lock); - update_isolation_cpumasks(); /* Force update if switching back to member & update effective_xcpus */ update_cpumasks_hier(cs, &tmpmask, !new_prs); @@ -3169,10 +3231,8 @@ ssize_t cpuset_write_resmask(struct kernfs_open_file *of, } free_cpuset(trialcs); - if (force_sd_rebuild) - rebuild_sched_domains_locked(); out_unlock: - cpuset_full_unlock(); + cpuset_update_sd_hk_unlock(); if (of_cft(of)->private == FILE_MEMLIST) schedule_flush_migrate_mm(); return retval ?: nbytes; @@ -3279,7 +3339,7 @@ static ssize_t cpuset_partition_write(struct kernfs_open_file *of, char *buf, cpuset_full_lock(); if (is_cpuset_online(cs)) retval = update_prstate(cs, val); - cpuset_full_unlock(); + cpuset_update_sd_hk_unlock(); return retval ?: nbytes; } @@ -3453,7 +3513,7 @@ static void cpuset_css_killed(struct cgroup_subsys_state *css) /* Reset valid partition back to member */ if (is_partition_valid(cs)) update_prstate(cs, PRS_MEMBER); - cpuset_full_unlock(); + cpuset_update_sd_hk_unlock(); } static void cpuset_css_free(struct cgroup_subsys_state *css) @@ -3608,6 +3668,7 @@ int __init cpuset_init(void) BUG_ON(!alloc_cpumask_var(&top_cpuset.exclusive_cpus, GFP_KERNEL)); BUG_ON(!zalloc_cpumask_var(&subpartitions_cpus, GFP_KERNEL)); BUG_ON(!zalloc_cpumask_var(&isolated_cpus, GFP_KERNEL)); + BUG_ON(!zalloc_cpumask_var(&isolated_hk_cpus, GFP_KERNEL)); cpumask_setall(top_cpuset.cpus_allowed); nodes_setall(top_cpuset.mems_allowed); @@ -3779,6 +3840,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) */ static void cpuset_handle_hotplug(void) { + static DECLARE_WORK(hk_sd_work, hk_sd_workfn); static cpumask_t new_cpus; static nodemask_t new_mems; bool cpus_updated, mems_updated; @@ -3860,9 +3922,25 @@ static void cpuset_handle_hotplug(void) rcu_read_unlock(); } - /* rebuild sched domains if necessary */ + /* + * rebuild_sched_domains() will always be called directly if needed + * to make sure that newly added or removed CPU will be reflected in + * the sched domains. However, if isolated partition invalidation + * or recreation is being done (update_housekeeping set), a work item + * will be queued to call housekeeping_update() to update the + * corresponding housekeeping cpumasks after some slight delay. + * + * We rely on WORK_STRUCT_PENDING_BIT to not requeue a work item that + * is still pending. Before the pending bit is cleared, the work data + * is copied out and work item dequeued. So it is possible to queue + * the work again before the hk_sd_workfn() is invoked to process the + * previously queued work. Since hk_sd_workfn() doesn't use the work + * item at all, this is not a problem. + */ if (force_sd_rebuild) rebuild_sched_domains_cpuslocked(); + if (update_housekeeping) + queue_work(system_dfl_wq, &hk_sd_work); free_tmpmasks(ptmp); } @@ -4145,40 +4223,58 @@ bool cpuset_current_node_allowed(int node, gfp_t gfp_mask) return allowed; } -bool cpuset_node_allowed(struct cgroup *cgroup, int nid) +/** + * cpuset_nodes_allowed - return effective_mems mask from a cgroup cpuset. + * @cgroup: pointer to struct cgroup. + * @mask: pointer to struct nodemask_t to be returned. + * + * Returns effective_mems mask from a cgroup cpuset if it is cgroup v2 and + * has cpuset subsys. Otherwise, returns node_states[N_MEMORY]. + * + * This function intentionally avoids taking the cpuset_mutex or callback_lock + * when accessing effective_mems. This is because the obtained effective_mems + * is stale immediately after the query anyway (e.g., effective_mems is updated + * immediately after releasing the lock but before returning). + * + * As a result, returned @mask may be empty because cs->effective_mems can be + * rebound during this call. Besides, nodes in @mask are not guaranteed to be + * online due to hot plugins. Callers should check the mask for validity on + * return based on its subsequent use. + **/ +void cpuset_nodes_allowed(struct cgroup *cgroup, nodemask_t *mask) { struct cgroup_subsys_state *css; struct cpuset *cs; - bool allowed; /* * In v1, mem_cgroup and cpuset are unlikely in the same hierarchy * and mems_allowed is likely to be empty even if we could get to it, - * so return true to avoid taking a global lock on the empty check. + * so return directly to avoid taking a global lock on the empty check. */ - if (!cpuset_v2()) - return true; + if (!cgroup || !cpuset_v2()) { + nodes_copy(*mask, node_states[N_MEMORY]); + return; + } css = cgroup_get_e_css(cgroup, &cpuset_cgrp_subsys); - if (!css) - return true; + if (!css) { + nodes_copy(*mask, node_states[N_MEMORY]); + return; + } /* + * The reference taken via cgroup_get_e_css is sufficient to + * protect css, but it does not imply safe accesses to effective_mems. + * * Normally, accessing effective_mems would require the cpuset_mutex - * or callback_lock - but node_isset is atomic and the reference - * taken via cgroup_get_e_css is sufficient to protect css. - * - * Since this interface is intended for use by migration paths, we - * relax locking here to avoid taking global locks - while accepting - * there may be rare scenarios where the result may be innaccurate. - * - * Reclaim and migration are subject to these same race conditions, and - * cannot make strong isolation guarantees, so this is acceptable. + * or callback_lock - but the correctness of this information is stale + * immediately after the query anyway. We do not acquire the lock + * during this process to save lock contention in exchange for racing + * against mems_allowed rebinds. */ cs = container_of(css, struct cpuset, css); - allowed = node_isset(nid, cs->effective_mems); + nodes_copy(*mask, cs->effective_mems); css_put(css); - return allowed; } /** diff --git a/kernel/cgroup/debug.c b/kernel/cgroup/debug.c index a5490097fe52..883347b87842 100644 --- a/kernel/cgroup/debug.c +++ b/kernel/cgroup/debug.c @@ -14,7 +14,7 @@ static struct cgroup_subsys_state * debug_css_alloc(struct cgroup_subsys_state *parent_css) { - struct cgroup_subsys_state *css = kzalloc(sizeof(*css), GFP_KERNEL); + struct cgroup_subsys_state *css = kzalloc_obj(*css); if (!css) return ERR_PTR(-ENOMEM); diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c index 1ea6afffa985..9d95824dc6fa 100644 --- a/kernel/cgroup/dmem.c +++ b/kernel/cgroup/dmem.c @@ -222,7 +222,7 @@ static void dmemcs_free(struct cgroup_subsys_state *css) static struct cgroup_subsys_state * dmemcs_alloc(struct cgroup_subsys_state *parent_css) { - struct dmemcg_state *dmemcs = kzalloc(sizeof(*dmemcs), GFP_KERNEL); + struct dmemcg_state *dmemcs = kzalloc_obj(*dmemcs); if (!dmemcs) return ERR_PTR(-ENOMEM); @@ -359,7 +359,7 @@ alloc_pool_single(struct dmemcg_state *dmemcs, struct dmem_cgroup_region *region struct dmem_cgroup_pool_state *pool, *ppool = NULL; if (!*allocpool) { - pool = kzalloc(sizeof(*pool), GFP_NOWAIT); + pool = kzalloc_obj(*pool, GFP_NOWAIT); if (!pool) return ERR_PTR(-ENOMEM); } else { @@ -521,7 +521,7 @@ struct dmem_cgroup_region *dmem_cgroup_register_region(u64 size, const char *fmt if (!region_name) return ERR_PTR(-ENOMEM); - ret = kzalloc(sizeof(*ret), GFP_KERNEL); + ret = kzalloc_obj(*ret); if (!ret) { kfree(region_name); return ERR_PTR(-ENOMEM); @@ -597,7 +597,7 @@ get_cg_pool_unlocked(struct dmemcg_state *cg, struct dmem_cgroup_region *region) if (WARN_ON(allocpool)) continue; - allocpool = kzalloc(sizeof(*allocpool), GFP_KERNEL); + allocpool = kzalloc_obj(*allocpool); if (allocpool) { pool = NULL; continue; diff --git a/kernel/cgroup/legacy_freezer.c b/kernel/cgroup/legacy_freezer.c index 817c33450fee..8545e0d1ba3d 100644 --- a/kernel/cgroup/legacy_freezer.c +++ b/kernel/cgroup/legacy_freezer.c @@ -81,7 +81,7 @@ freezer_css_alloc(struct cgroup_subsys_state *parent_css) { struct freezer *freezer; - freezer = kzalloc(sizeof(struct freezer), GFP_KERNEL); + freezer = kzalloc_obj(struct freezer); if (!freezer) return ERR_PTR(-ENOMEM); diff --git a/kernel/cgroup/misc.c b/kernel/cgroup/misc.c index 6a01d91ea4cb..4a9e2557141c 100644 --- a/kernel/cgroup/misc.c +++ b/kernel/cgroup/misc.c @@ -445,7 +445,7 @@ misc_cg_alloc(struct cgroup_subsys_state *parent_css) if (!parent_css) { cg = &root_cg; } else { - cg = kzalloc(sizeof(*cg), GFP_KERNEL); + cg = kzalloc_obj(*cg); if (!cg) return ERR_PTR(-ENOMEM); } diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index db9617556dd7..ea4ee13936be 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c @@ -24,7 +24,7 @@ static struct cgroup_namespace *alloc_cgroup_ns(void) struct cgroup_namespace *new_ns __free(kfree) = NULL; int ret; - new_ns = kzalloc(sizeof(struct cgroup_namespace), GFP_KERNEL_ACCOUNT); + new_ns = kzalloc_obj(struct cgroup_namespace, GFP_KERNEL_ACCOUNT); if (!new_ns) return ERR_PTR(-ENOMEM); ret = ns_common_init(new_ns); diff --git a/kernel/cgroup/pids.c b/kernel/cgroup/pids.c index 8f61114c36dd..ecbb839d2acb 100644 --- a/kernel/cgroup/pids.c +++ b/kernel/cgroup/pids.c @@ -80,7 +80,7 @@ pids_css_alloc(struct cgroup_subsys_state *parent) { struct pids_cgroup *pids; - pids = kzalloc(sizeof(struct pids_cgroup), GFP_KERNEL); + pids = kzalloc_obj(struct pids_cgroup); if (!pids) return ERR_PTR(-ENOMEM); diff --git a/kernel/cgroup/rdma.c b/kernel/cgroup/rdma.c index ef5878fb2005..09258eebb5c7 100644 --- a/kernel/cgroup/rdma.c +++ b/kernel/cgroup/rdma.c @@ -134,7 +134,7 @@ get_cg_rpool_locked(struct rdma_cgroup *cg, struct rdmacg_device *device) if (rpool) return rpool; - rpool = kzalloc(sizeof(*rpool), GFP_KERNEL); + rpool = kzalloc_obj(*rpool); if (!rpool) return ERR_PTR(-ENOMEM); @@ -443,7 +443,7 @@ static ssize_t rdmacg_resource_set_max(struct kernfs_open_file *of, goto err; } - new_limits = kcalloc(RDMACG_RESOURCE_MAX, sizeof(int), GFP_KERNEL); + new_limits = kzalloc_objs(int, RDMACG_RESOURCE_MAX); if (!new_limits) { ret = -ENOMEM; goto err; @@ -566,7 +566,7 @@ rdmacg_css_alloc(struct cgroup_subsys_state *parent) { struct rdma_cgroup *cg; - cg = kzalloc(sizeof(*cg), GFP_KERNEL); + cg = kzalloc_obj(*cg); if (!cg) return ERR_PTR(-ENOMEM); diff --git a/kernel/configs/debug.config b/kernel/configs/debug.config index 774702591d26..307c97ac5fa9 100644 --- a/kernel/configs/debug.config +++ b/kernel/configs/debug.config @@ -29,7 +29,6 @@ CONFIG_SECTION_MISMATCH_WARN_ONLY=y # CONFIG_UBSAN_ALIGNMENT is not set # CONFIG_UBSAN_DIV_ZERO is not set # CONFIG_UBSAN_TRAP is not set -# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set CONFIG_DEBUG_FS=y CONFIG_DEBUG_FS_ALLOW_ALL=y CONFIG_DEBUG_IRQFLAGS=y diff --git a/kernel/cpu.c b/kernel/cpu.c index 01968a5c4a16..bc4f7a9ba64e 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1,7 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0 /* CPU control. * (C) 2001, 2002, 2003, 2004 Rusty Russell - * - * This code is licenced under the GPL. */ #include #include diff --git a/kernel/crash_core.c b/kernel/crash_core.c index 3952b3e102e0..2c1a3791e410 100644 --- a/kernel/crash_core.c +++ b/kernel/crash_core.c @@ -368,7 +368,7 @@ static int __crash_shrink_memory(struct resource *old_res, { struct resource *ram_res; - ram_res = kzalloc(sizeof(*ram_res), GFP_KERNEL); + ram_res = kzalloc_obj(*ram_res); if (!ram_res) return -ENOMEM; diff --git a/kernel/crash_dump_dm_crypt.c b/kernel/crash_dump_dm_crypt.c index 37129243054d..a20d4097744a 100644 --- a/kernel/crash_dump_dm_crypt.c +++ b/kernel/crash_dump_dm_crypt.c @@ -168,8 +168,8 @@ static int read_key_from_user_keying(struct dm_crypt_key *dm_key) memcpy(dm_key->data, ukp->data, ukp->datalen); dm_key->key_size = ukp->datalen; - kexec_dprintk("Get dm crypt key (size=%u) %s: %8ph\n", dm_key->key_size, - dm_key->key_desc, dm_key->data); + kexec_dprintk("Get dm crypt key (size=%u) %s\n", dm_key->key_size, + dm_key->key_desc); out: up_read(&key->sem); @@ -252,7 +252,7 @@ static struct config_item *config_keys_make_item(struct config_group *group, return ERR_PTR(-EINVAL); } - config_key = kzalloc(sizeof(struct config_key), GFP_KERNEL); + config_key = kzalloc_obj(struct config_key); if (!config_key) return ERR_PTR(-ENOMEM); diff --git a/kernel/debug/debug_core.h b/kernel/debug/debug_core.h index cd22b5f68831..fa1226158b45 100644 --- a/kernel/debug/debug_core.h +++ b/kernel/debug/debug_core.h @@ -1,11 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * Created by: Jason Wessel * * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. */ #ifndef _DEBUG_CORE_H_ diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index c0c2072f5452..eb8d851d620f 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Independent Breakpoint Handler * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. */ diff --git a/kernel/debug/kdb/kdb_bt.c b/kernel/debug/kdb/kdb_bt.c index 137ba73f56fc..c561aa076970 100644 --- a/kernel/debug/kdb/kdb_bt.c +++ b/kernel/debug/kdb/kdb_bt.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Independent Stack Traceback * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. */ diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index e91fc3e4edd5..59b81032bbab 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Created by: Jason Wessel * diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index 61c1690058ed..c399f11740ef 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Independent Console I/O handler * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. */ diff --git a/kernel/debug/kdb/kdb_keyboard.c b/kernel/debug/kdb/kdb_keyboard.c index 386d30e530b7..c7ebcb9e9d8f 100644 --- a/kernel/debug/kdb/kdb_keyboard.c +++ b/kernel/debug/kdb/kdb_keyboard.c @@ -1,9 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Dependent Console I/O handler * - * This file is subject to the terms and conditions of the GNU General Public - * License. - * * Copyright (c) 1999-2006 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. */ diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index dddf2b5aad57..ddce56b47b25 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Independent Main Code * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (C) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. * Copyright (C) 2000 Stephane Eranian * Xscale (R) modifications copyright (C) 2003 Intel Corporation. @@ -664,7 +661,7 @@ static int kdb_defcmd2(const char *cmdstr, const char *argv0) return 0; } - kms = kmalloc(sizeof(*kms), GFP_KDB); + kms = kmalloc_obj(*kms, GFP_KDB); if (!kms) { kdb_printf("Could not allocate new kdb macro command: %s\n", cmdstr); @@ -710,7 +707,7 @@ static int kdb_defcmd(int argc, const char **argv) kdb_printf("Command only available during kdb_init()\n"); return KDB_NOTIMP; } - kdb_macro = kzalloc(sizeof(*kdb_macro), GFP_KDB); + kdb_macro = kzalloc_obj(*kdb_macro, GFP_KDB); if (!kdb_macro) goto fail_defcmd; diff --git a/kernel/debug/kdb/kdb_private.h b/kernel/debug/kdb/kdb_private.h index a2fc7d2bc9fc..92a28b8ab604 100644 --- a/kernel/debug/kdb/kdb_private.h +++ b/kernel/debug/kdb/kdb_private.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _KDBPRIVATE_H #define _KDBPRIVATE_H diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 56f7b906e7cc..0a2e54e77ce6 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Kernel Debugger Architecture Independent Support Functions * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * * Copyright (c) 1999-2004 Silicon Graphics, Inc. All Rights Reserved. * Copyright (c) 2009 Wind River Systems, Inc. All Rights Reserved. * 03/02/13 added new 2.5 kallsyms diff --git a/kernel/dma/coherent.c b/kernel/dma/coherent.c index 77c8d9487a9a..1147497bc512 100644 --- a/kernel/dma/coherent.c +++ b/kernel/dma/coherent.c @@ -49,7 +49,7 @@ static struct dma_coherent_mem *dma_init_coherent_memory(phys_addr_t phys_addr, if (!mem_base) return ERR_PTR(-EINVAL); - dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL); + dma_mem = kzalloc_obj(struct dma_coherent_mem); if (!dma_mem) goto out_unmap_membase; dma_mem->bitmap = bitmap_zalloc(pages, GFP_KERNEL); diff --git a/kernel/dma/debug.c b/kernel/dma/debug.c index 43d6a996d7a7..86f87e43438c 100644 --- a/kernel/dma/debug.c +++ b/kernel/dma/debug.c @@ -900,7 +900,7 @@ void dma_debug_add_bus(const struct bus_type *bus) if (dma_debug_disabled()) return; - nb = kzalloc(sizeof(struct notifier_block), GFP_KERNEL); + nb = kzalloc_obj(struct notifier_block); if (nb == NULL) { pr_err("dma_debug_add_bus: out of memory\n"); return; diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c index c9fa983990cd..8f43a930716d 100644 --- a/kernel/dma/direct.c +++ b/kernel/dma/direct.c @@ -654,7 +654,7 @@ int dma_direct_set_offset(struct device *dev, phys_addr_t cpu_start, if (!offset) return 0; - map = kcalloc(2, sizeof(*map), GFP_KERNEL); + map = kzalloc_objs(*map, 2); if (!map) return -ENOMEM; map[0].cpu_start = cpu_start; diff --git a/kernel/dma/direct.h b/kernel/dma/direct.h index f476c63b668c..e89f175e9c2d 100644 --- a/kernel/dma/direct.h +++ b/kernel/dma/direct.h @@ -85,7 +85,7 @@ static inline dma_addr_t dma_direct_map_phys(struct device *dev, if (is_swiotlb_force_bounce(dev)) { if (attrs & DMA_ATTR_MMIO) - goto err_overflow; + return DMA_MAPPING_ERROR; return swiotlb_map(dev, phys, size, dir, attrs); } diff --git a/kernel/dma/map_benchmark.c b/kernel/dma/map_benchmark.c index 794041a39e65..0f33b3ea7daf 100644 --- a/kernel/dma/map_benchmark.c +++ b/kernel/dma/map_benchmark.c @@ -121,7 +121,7 @@ static int do_map_benchmark(struct map_benchmark_data *map) int ret = 0; int i; - tsk = kmalloc_array(threads, sizeof(*tsk), GFP_KERNEL); + tsk = kmalloc_objs(*tsk, threads); if (!tsk) return -ENOMEM; diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index ee29c47781e3..3928a509c44c 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -768,7 +768,7 @@ static struct sg_table *alloc_single_sgt(struct device *dev, size_t size, struct sg_table *sgt; struct page *page; - sgt = kmalloc(sizeof(*sgt), gfp); + sgt = kmalloc_obj(*sgt, gfp); if (!sgt) return NULL; if (sg_alloc_table(sgt, 1, gfp)) diff --git a/kernel/dma/remap.c b/kernel/dma/remap.c index b7c1c0c92d0c..205c0c0ba2fe 100644 --- a/kernel/dma/remap.c +++ b/kernel/dma/remap.c @@ -45,7 +45,7 @@ void *dma_common_contiguous_remap(struct page *page, size_t size, void *vaddr; int i; - pages = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL); + pages = kvmalloc_objs(struct page *, count); if (!pages) return NULL; for (i = 0; i < count; i++) diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c index a547c7693135..d8e6f1d889d5 100644 --- a/kernel/dma/swiotlb.c +++ b/kernel/dma/swiotlb.c @@ -1809,19 +1809,18 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem, if (!mem) { struct io_tlb_pool *pool; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return -ENOMEM; pool = &mem->defpool; - pool->slots = kcalloc(nslabs, sizeof(*pool->slots), GFP_KERNEL); + pool->slots = kzalloc_objs(*pool->slots, nslabs); if (!pool->slots) { kfree(mem); return -ENOMEM; } - pool->areas = kcalloc(nareas, sizeof(*pool->areas), - GFP_KERNEL); + pool->areas = kzalloc_objs(*pool->areas, nareas); if (!pool->areas) { kfree(pool->slots); kfree(mem); diff --git a/kernel/events/core.c b/kernel/events/core.c index e18119f30c29..1f5699b339ec 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4138,7 +4138,8 @@ static int merge_sched_in(struct perf_event *event, void *data) if (*perf_event_fasync(event)) event->pending_kill = POLL_ERR; - perf_event_wakeup(event); + event->pending_wakeup = 1; + irq_work_queue(&event->pending_irq); } else { struct perf_cpu_pmu_context *cpc = this_cpc(event->pmu_ctx->pmu); @@ -5058,7 +5059,7 @@ alloc_perf_context(struct task_struct *task) { struct perf_event_context *ctx; - ctx = kzalloc(sizeof(struct perf_event_context), GFP_KERNEL); + ctx = kzalloc_obj(struct perf_event_context); if (!ctx) return NULL; @@ -5198,7 +5199,7 @@ find_get_pmu_context(struct pmu *pmu, struct perf_event_context *ctx, return epc; } - new = kzalloc(sizeof(*epc), GFP_KERNEL); + new = kzalloc_obj(*epc); if (!new) return ERR_PTR(-ENOMEM); @@ -5374,7 +5375,7 @@ alloc_perf_ctx_data(struct kmem_cache *ctx_cache, bool global) { struct perf_ctx_data *cd; - cd = kzalloc(sizeof(*cd), GFP_KERNEL); + cd = kzalloc_obj(*cd); if (!cd) return NULL; @@ -7464,29 +7465,29 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma) ret = perf_mmap_aux(vma, event, nr_pages); if (ret) return ret; + + /* + * Since pinned accounting is per vm we cannot allow fork() to copy our + * vma. + */ + vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP); + vma->vm_ops = &perf_mmap_vmops; + + mapped = get_mapped(event, event_mapped); + if (mapped) + mapped(event, vma->vm_mm); + + /* + * Try to map it into the page table. On fail, invoke + * perf_mmap_close() to undo the above, as the callsite expects + * full cleanup in this case and therefore does not invoke + * vmops::close(). + */ + ret = map_range(event->rb, vma); + if (ret) + perf_mmap_close(vma); } - /* - * Since pinned accounting is per vm we cannot allow fork() to copy our - * vma. - */ - vm_flags_set(vma, VM_DONTCOPY | VM_DONTEXPAND | VM_DONTDUMP); - vma->vm_ops = &perf_mmap_vmops; - - mapped = get_mapped(event, event_mapped); - if (mapped) - mapped(event, vma->vm_mm); - - /* - * Try to map it into the page table. On fail, invoke - * perf_mmap_close() to undo the above, as the callsite expects - * full cleanup in this case and therefore does not invoke - * vmops::close(). - */ - ret = map_range(event->rb, vma); - if (ret) - perf_mmap_close(vma); - return ret; } @@ -10776,6 +10777,13 @@ int perf_event_overflow(struct perf_event *event, struct perf_sample_data *data, struct pt_regs *regs) { + /* + * Entry point from hardware PMI, interrupts should be disabled here. + * This serializes us against perf_event_remove_from_context() in + * things like perf_event_release_kernel(). + */ + lockdep_assert_irqs_disabled(); + return __perf_event_overflow(event, 1, data, regs); } @@ -10852,6 +10860,19 @@ static void perf_swevent_event(struct perf_event *event, u64 nr, { struct hw_perf_event *hwc = &event->hw; + /* + * This is: + * - software preempt + * - tracepoint preempt + * - tp_target_task irq (ctx->lock) + * - uprobes preempt/irq + * - kprobes preempt/irq + * - hw_breakpoint irq + * + * Any of these are sufficient to hold off RCU and thus ensure @event + * exists. + */ + lockdep_assert_preemption_disabled(); local64_add(nr, &event->count); if (!regs) @@ -10860,6 +10881,16 @@ static void perf_swevent_event(struct perf_event *event, u64 nr, if (!is_sampling_event(event)) return; + /* + * Serialize against event_function_call() IPIs like normal overflow + * event handling. Specifically, must not allow + * perf_event_release_kernel() -> perf_remove_from_context() to make + * progress and 'release' the event from under us. + */ + guard(irqsave)(); + if (event->state != PERF_EVENT_STATE_ACTIVE) + return; + if ((event->attr.sample_type & PERF_SAMPLE_PERIOD) && !event->attr.freq) { data->period = nr; return perf_swevent_overflow(event, 1, data, regs); @@ -11111,7 +11142,7 @@ static int swevent_hlist_get_cpu(int cpu) cpumask_test_cpu(cpu, perf_online_mask)) { struct swevent_hlist *hlist; - hlist = kzalloc(sizeof(*hlist), GFP_KERNEL); + hlist = kzalloc_obj(*hlist); if (!hlist) { err = -ENOMEM; goto exit; @@ -11358,6 +11389,11 @@ void perf_tp_event(u16 event_type, u64 count, void *record, int entry_size, struct perf_sample_data data; struct perf_event *event; + /* + * Per being a tracepoint, this runs with preemption disabled. + */ + lockdep_assert_preemption_disabled(); + struct perf_raw_record raw = { .frag = { .size = entry_size, @@ -11690,6 +11726,11 @@ void perf_bp_event(struct perf_event *bp, void *data) struct perf_sample_data sample; struct pt_regs *regs = data; + /* + * Exception context, will have interrupts disabled. + */ + lockdep_assert_irqs_disabled(); + perf_sample_data_init(&sample, bp->attr.bp_addr, 0); if (!bp->hw.state && !perf_exclude_event(bp, regs)) @@ -12154,7 +12195,7 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) if (regs && !perf_exclude_event(event, regs)) { if (!(event->attr.exclude_idle && is_idle_task(current))) - if (__perf_event_overflow(event, 1, &data, regs)) + if (perf_event_overflow(event, &data, regs)) ret = HRTIMER_NORESTART; } @@ -12634,7 +12675,7 @@ static int pmu_dev_alloc(struct pmu *pmu) { int ret = -ENOMEM; - pmu->dev = kzalloc(sizeof(struct device), GFP_KERNEL); + pmu->dev = kzalloc_obj(struct device); if (!pmu->dev) goto out; @@ -15269,7 +15310,7 @@ perf_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) { struct perf_cgroup *jc; - jc = kzalloc(sizeof(*jc), GFP_KERNEL); + jc = kzalloc_obj(*jc); if (!jc) return ERR_PTR(-ENOMEM); diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 8ec2cb688903..789add0c185a 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -185,7 +185,8 @@ static inline int hw_breakpoint_slots_cached(int type) static __init bool bp_slots_histogram_alloc(struct bp_slots_histogram *hist, enum bp_type_idx type) { - hist->count = kcalloc(hw_breakpoint_slots_cached(type), sizeof(*hist->count), GFP_KERNEL); + hist->count = kzalloc_objs(*hist->count, + hw_breakpoint_slots_cached(type)); return hist->count; } diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 424ef2235b07..923b24b321cc 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -238,7 +238,7 @@ static int delayed_uprobe_add(struct uprobe *uprobe, struct mm_struct *mm) if (delayed_uprobe_check(uprobe, mm)) return 0; - du = kzalloc(sizeof(*du), GFP_KERNEL); + du = kzalloc_obj(*du); if (!du) return -ENOMEM; @@ -994,7 +994,7 @@ static struct uprobe *alloc_uprobe(struct inode *inode, loff_t offset, { struct uprobe *uprobe, *cur_uprobe; - uprobe = kzalloc(sizeof(struct uprobe), GFP_KERNEL); + uprobe = kzalloc_obj(struct uprobe); if (!uprobe) return ERR_PTR(-ENOMEM); @@ -1219,8 +1219,8 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register) * Needs GFP_NOWAIT to avoid i_mmap_rwsem recursion through * reclaim. This is optimistic, no harm done if it fails. */ - prev = kmalloc(sizeof(struct map_info), - GFP_NOWAIT | __GFP_NOMEMALLOC); + prev = kmalloc_obj(struct map_info, + GFP_NOWAIT | __GFP_NOMEMALLOC); if (prev) prev->next = NULL; } @@ -1252,7 +1252,7 @@ build_map_info(struct address_space *mapping, loff_t offset, bool is_register) } do { - info = kmalloc(sizeof(struct map_info), GFP_KERNEL); + info = kmalloc_obj(struct map_info); if (!info) { curr = ERR_PTR(-ENOMEM); goto out; @@ -1755,7 +1755,7 @@ static struct xol_area *__create_xol_area(unsigned long vaddr) struct xol_area *area; void *insns; - area = kzalloc(sizeof(*area), GFP_KERNEL); + area = kzalloc_obj(*area); if (unlikely(!area)) goto out; @@ -2069,7 +2069,7 @@ static struct uprobe_task *alloc_utask(void) { struct uprobe_task *utask; - utask = kzalloc(sizeof(*utask), GFP_KERNEL); + utask = kzalloc_obj(*utask); if (!utask) return NULL; @@ -2102,7 +2102,7 @@ static struct return_instance *alloc_return_instance(struct uprobe_task *utask) if (ri) return ri; - ri = kzalloc(sizeof(*ri), GFP_KERNEL); + ri = kzalloc_obj(*ri); if (!ri) return ZERO_SIZE_PTR; diff --git a/kernel/exit.c b/kernel/exit.c index 8a87021211ae..ede3117fa7d4 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -896,11 +896,16 @@ static void synchronize_group_exit(struct task_struct *tsk, long code) void __noreturn do_exit(long code) { struct task_struct *tsk = current; + struct kthread *kthread; int group_dead; WARN_ON(irqs_disabled()); WARN_ON(tsk->plug); + kthread = tsk_is_kthread(tsk); + if (unlikely(kthread)) + kthread_do_exit(kthread, code); + kcov_task_exit(tsk); kmsan_task_exit(tsk); @@ -1013,6 +1018,7 @@ void __noreturn do_exit(long code) lockdep_free_task(tsk); do_task_dead(); } +EXPORT_SYMBOL(do_exit); void __noreturn make_task_dead(int signr) { diff --git a/kernel/fail_function.c b/kernel/fail_function.c index d971a0189319..2eaf55005f49 100644 --- a/kernel/fail_function.c +++ b/kernel/fail_function.c @@ -57,7 +57,7 @@ static struct fei_attr *fei_attr_new(const char *sym, unsigned long addr) { struct fei_attr *attr; - attr = kzalloc(sizeof(*attr), GFP_KERNEL); + attr = kzalloc_obj(*attr); if (attr) { attr->kp.symbol_name = kstrdup(sym, GFP_KERNEL); if (!attr->kp.symbol_name) { diff --git a/kernel/fork.c b/kernel/fork.c index e832da9d15a4..bc2bf58b93b6 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1000,6 +1000,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) #ifdef CONFIG_SCHED_MM_CID tsk->mm_cid.cid = MM_CID_UNSET; tsk->mm_cid.active = 0; + INIT_HLIST_NODE(&tsk->mm_cid.node); #endif return tsk; @@ -1586,7 +1587,6 @@ static int copy_mm(u64 clone_flags, struct task_struct *tsk) tsk->mm = mm; tsk->active_mm = mm; - sched_mm_cid_fork(tsk); return 0; } @@ -2498,7 +2498,6 @@ __latent_entropy struct task_struct *copy_process( exit_nsproxy_namespaces(p); bad_fork_cleanup_mm: if (p->mm) { - sched_mm_cid_exit(p); mm_clear_owner(p->mm, p); mmput(p->mm); } @@ -3085,7 +3084,7 @@ static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) return 0; /* don't need lock here; in the worst case we'll do useless copy */ - if (fs->users == 1) + if (!(unshare_flags & CLONE_NEWNS) && fs->users == 1) return 0; *new_fsp = copy_fs_struct(fs); diff --git a/kernel/futex/pi.c b/kernel/futex/pi.c index dacb2330f1fb..bc1f7e83a37e 100644 --- a/kernel/futex/pi.c +++ b/kernel/futex/pi.c @@ -17,7 +17,7 @@ int refill_pi_state_cache(void) if (likely(current->pi_state_cache)) return 0; - pi_state = kzalloc(sizeof(*pi_state), GFP_KERNEL); + pi_state = kzalloc_obj(*pi_state); if (!pi_state) return -ENOMEM; diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c index 880c9bf2f315..743c7a728237 100644 --- a/kernel/futex/syscalls.c +++ b/kernel/futex/syscalls.c @@ -333,7 +333,7 @@ SYSCALL_DEFINE5(futex_waitv, struct futex_waitv __user *, waiters, if (timeout && (ret = futex2_setup_timeout(timeout, clockid, &to))) return ret; - futexv = kcalloc(nr_futexes, sizeof(*futexv), GFP_KERNEL); + futexv = kzalloc_objs(*futexv, nr_futexes); if (!futexv) { ret = -ENOMEM; goto destroy_timer; diff --git a/kernel/gcov/clang.c b/kernel/gcov/clang.c index 8b888a6193cc..fd98ced0e51d 100644 --- a/kernel/gcov/clang.c +++ b/kernel/gcov/clang.c @@ -81,7 +81,7 @@ static LIST_HEAD(clang_gcov_list); void llvm_gcov_init(llvm_gcov_callback writeout, llvm_gcov_callback flush) { - struct gcov_info *info = kzalloc(sizeof(*info), GFP_KERNEL); + struct gcov_info *info = kzalloc_obj(*info); if (!info) return; @@ -112,7 +112,7 @@ EXPORT_SYMBOL(llvm_gcda_start_file); void llvm_gcda_emit_function(u32 ident, u32 func_checksum, u32 cfg_checksum) { - struct gcov_fn_info *info = kzalloc(sizeof(*info), GFP_KERNEL); + struct gcov_fn_info *info = kzalloc_obj(*info); if (!info) return; diff --git a/kernel/gcov/fs.c b/kernel/gcov/fs.c index 01520689b57c..1d19b1be207a 100644 --- a/kernel/gcov/fs.c +++ b/kernel/gcov/fs.c @@ -116,7 +116,7 @@ static struct gcov_iterator *gcov_iter_new(struct gcov_info *info) /* Dry-run to get the actual buffer size. */ size = convert_to_gcda(NULL, info); - iter = kvmalloc(struct_size(iter, buffer, size), GFP_KERNEL); + iter = kvmalloc_flex(*iter, buffer, size); if (!iter) return NULL; @@ -482,7 +482,7 @@ static void add_links(struct gcov_node *node, struct dentry *parent) for (num = 0; gcov_link[num].ext; num++) /* Nothing. */; - node->links = kcalloc(num, sizeof(struct dentry *), GFP_KERNEL); + node->links = kzalloc_objs(struct dentry *, num); if (!node->links) return; for (i = 0; i < num; i++) { @@ -545,8 +545,7 @@ static struct gcov_node *new_node(struct gcov_node *parent, if (!node) goto err_nomem; if (info) { - node->loaded_info = kcalloc(1, sizeof(struct gcov_info *), - GFP_KERNEL); + node->loaded_info = kzalloc_objs(struct gcov_info *, 1); if (!node->loaded_info) goto err_nomem; } @@ -731,7 +730,7 @@ static void add_info(struct gcov_node *node, struct gcov_info *info) * case the new data set is incompatible, the node only contains * unloaded data sets and there's not enough memory for the array. */ - loaded_info = kcalloc(num + 1, sizeof(struct gcov_info *), GFP_KERNEL); + loaded_info = kzalloc_objs(struct gcov_info *, num + 1); if (!loaded_info) { pr_warn("could not add '%s' (out of memory)\n", gcov_info_filename(info)); diff --git a/kernel/gcov/gcc_4_7.c b/kernel/gcov/gcc_4_7.c index ffde93d051a4..8fa22ababd94 100644 --- a/kernel/gcov/gcc_4_7.c +++ b/kernel/gcov/gcc_4_7.c @@ -298,8 +298,7 @@ struct gcov_info *gcov_info_dup(struct gcov_info *info) if (!dup->filename) goto err_free; - dup->functions = kcalloc(info->n_functions, - sizeof(struct gcov_fn_info *), GFP_KERNEL); + dup->functions = kzalloc_objs(struct gcov_fn_info *, info->n_functions); if (!dup->functions) goto err_free; diff --git a/kernel/groups.c b/kernel/groups.c index 9b43da22647d..b5e3be6a6b1f 100644 --- a/kernel/groups.c +++ b/kernel/groups.c @@ -15,7 +15,7 @@ struct group_info *groups_alloc(int gidsetsize) { struct group_info *gi; - gi = kvmalloc(struct_size(gi, gid, gidsetsize), GFP_KERNEL_ACCOUNT); + gi = kvmalloc_flex(*gi, gid, gidsetsize, GFP_KERNEL_ACCOUNT); if (!gi) return NULL; diff --git a/kernel/irq/affinity.c b/kernel/irq/affinity.c index 4013e6ad2b2f..85c45cfe7223 100644 --- a/kernel/irq/affinity.c +++ b/kernel/irq/affinity.c @@ -56,7 +56,7 @@ irq_create_affinity_masks(unsigned int nvecs, struct irq_affinity *affd) if (!affvecs) return NULL; - masks = kcalloc(nvecs, sizeof(*masks), GFP_KERNEL); + masks = kzalloc_objs(*masks, nvecs); if (!masks) return NULL; diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index 3cd0c40282c0..2c8bc6ce082e 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c @@ -240,7 +240,7 @@ irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base, { struct irq_chip_generic *gc; - gc = kzalloc(struct_size(gc, chip_types, num_ct), GFP_KERNEL); + gc = kzalloc_flex(*gc, chip_types, num_ct); if (gc) { irq_init_generic_chip(gc, name, num_ct, irq_base, reg_base, handler); diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c index ae4c9cbd1b4b..44747754530d 100644 --- a/kernel/irq/irq_sim.c +++ b/kernel/irq/irq_sim.c @@ -148,7 +148,7 @@ static int irq_sim_domain_map(struct irq_domain *domain, struct irq_sim_work_ctx *work_ctx = domain->host_data; struct irq_sim_irq_ctx *irq_ctx; - irq_ctx = kzalloc(sizeof(*irq_ctx), GFP_KERNEL); + irq_ctx = kzalloc_obj(*irq_ctx); if (!irq_ctx) return -ENOMEM; @@ -202,7 +202,7 @@ struct irq_domain *irq_domain_create_sim_full(struct fwnode_handle *fwnode, void *data) { struct irq_sim_work_ctx *work_ctx __free(kfree) = - kzalloc(sizeof(*work_ctx), GFP_KERNEL); + kzalloc_obj(*work_ctx); if (!work_ctx) return ERR_PTR(-ENOMEM); diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c index 022b3741dd7a..7173b8b634f2 100644 --- a/kernel/irq/irqdesc.c +++ b/kernel/irq/irqdesc.c @@ -969,7 +969,7 @@ int irq_set_percpu_devid(unsigned int irq) if (!desc || desc->percpu_enabled) return -EINVAL; - desc->percpu_enabled = kzalloc(sizeof(*desc->percpu_enabled), GFP_KERNEL); + desc->percpu_enabled = kzalloc_obj(*desc->percpu_enabled); if (!desc->percpu_enabled) return -ENOMEM; diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c index c2258b133939..cc93abf009e8 100644 --- a/kernel/irq/irqdomain.c +++ b/kernel/irq/irqdomain.c @@ -92,7 +92,7 @@ struct fwnode_handle *__irq_domain_alloc_fwnode(unsigned int type, int id, struct irqchip_fwid *fwid; char *n; - fwid = kzalloc(sizeof(*fwid), GFP_KERNEL); + fwid = kzalloc_obj(*fwid); switch (type) { case IRQCHIP_FWNODE_NAMED: diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index cded3d960eb7..2e8072437826 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -1332,7 +1332,7 @@ static int irq_setup_forced_threading(struct irqaction *new) */ if (new->handler && new->thread_fn) { /* Allocate the secondary action */ - new->secondary = kzalloc(sizeof(struct irqaction), GFP_KERNEL); + new->secondary = kzalloc_obj(struct irqaction); if (!new->secondary) return -ENOMEM; new->secondary->handler = irq_forced_secondary_handler; @@ -2156,7 +2156,7 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler, handler = irq_default_primary_handler; } - action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); + action = kzalloc_obj(struct irqaction); if (!action) return -ENOMEM; @@ -2486,7 +2486,7 @@ struct irqaction *create_percpu_irqaction(irq_handler_t handler, unsigned long f if (!affinity) affinity = cpu_possible_mask; - action = kzalloc(sizeof(struct irqaction), GFP_KERNEL); + action = kzalloc_obj(struct irqaction); if (!action) return NULL; diff --git a/kernel/irq/matrix.c b/kernel/irq/matrix.c index a50f2305a8dc..0f79a4abea05 100644 --- a/kernel/irq/matrix.c +++ b/kernel/irq/matrix.c @@ -51,7 +51,7 @@ __init struct irq_matrix *irq_alloc_matrix(unsigned int matrix_bits, unsigned int cpu, matrix_size = BITS_TO_LONGS(matrix_bits); struct irq_matrix *m; - m = kzalloc(struct_size(m, scratch_map, matrix_size * 2), GFP_KERNEL); + m = kzalloc_flex(*m, scratch_map, matrix_size * 2); if (!m) return NULL; diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 68886881fe10..3cafa40e6ce3 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -76,7 +76,7 @@ static int msi_domain_prepare_irqs(struct irq_domain *domain, struct device *dev static struct msi_desc *msi_alloc_desc(struct device *dev, int nvec, const struct irq_affinity_desc *affinity) { - struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL); + struct msi_desc *desc = kzalloc_obj(*desc); if (!desc) return NULL; @@ -530,7 +530,7 @@ static int msi_sysfs_populate_desc(struct device *dev, struct msi_desc *desc) struct device_attribute *attrs; int ret, i; - attrs = kcalloc(desc->nvec_used, sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_objs(*attrs, desc->nvec_used); if (!attrs) return -ENOMEM; diff --git a/kernel/kallsyms_selftest.c b/kernel/kallsyms_selftest.c index 2b082a7e24a2..8f6c4e9b3a1c 100644 --- a/kernel/kallsyms_selftest.c +++ b/kernel/kallsyms_selftest.c @@ -264,7 +264,7 @@ static int test_kallsyms_basic_function(void) char namebuf[KSYM_NAME_LEN]; struct test_stat *stat, *stat2; - stat = kmalloc_array(2, sizeof(*stat), GFP_KERNEL); + stat = kmalloc_objs(*stat, 2); if (!stat) return -ENOMEM; stat2 = stat + 1; diff --git a/kernel/kcov.c b/kernel/kcov.c index 5397d0c14127..0b369e88c7c9 100644 --- a/kernel/kcov.c +++ b/kernel/kcov.c @@ -122,7 +122,7 @@ static struct kcov_remote *kcov_remote_add(struct kcov *kcov, u64 handle) if (kcov_remote_find(handle)) return ERR_PTR(-EEXIST); - remote = kmalloc(sizeof(*remote), GFP_ATOMIC); + remote = kmalloc_obj(*remote, GFP_ATOMIC); if (!remote) return ERR_PTR(-ENOMEM); remote->handle = handle; @@ -527,7 +527,7 @@ static int kcov_open(struct inode *inode, struct file *filep) { struct kcov *kcov; - kcov = kzalloc(sizeof(*kcov), GFP_KERNEL); + kcov = kzalloc_obj(*kcov); if (!kcov) return -ENOMEM; guard(spinlock_init)(&kcov->lock); diff --git a/kernel/kcsan/kcsan_test.c b/kernel/kcsan/kcsan_test.c index 8ef8167be745..ae758150ccb9 100644 --- a/kernel/kcsan/kcsan_test.c +++ b/kernel/kcsan/kcsan_test.c @@ -168,7 +168,7 @@ static bool __report_matches(const struct expect_report *r) if (!report_available()) return false; - expect = kmalloc(sizeof(observed.lines), GFP_KERNEL); + expect = (typeof(expect))kmalloc_obj(observed.lines); if (WARN_ON(!expect)) return false; @@ -1538,7 +1538,7 @@ static int test_init(struct kunit *test) if (WARN_ON(!nthreads)) goto err; - threads = kcalloc(nthreads + 1, sizeof(struct task_struct *), GFP_KERNEL); + threads = kzalloc_objs(struct task_struct *, nthreads + 1); if (WARN_ON(!threads)) goto err; diff --git a/kernel/kexec.c b/kernel/kexec.c index 28008e3d462e..90756dc6339b 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -284,8 +284,7 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry, if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT) return -EINVAL; - ksegments = kmalloc_array(nr_segments, sizeof(ksegments[0]), - GFP_KERNEL); + ksegments = kmalloc_objs(ksegments[0], nr_segments); if (!ksegments) return -ENOMEM; diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 95c585c6ddc3..2fea396d29b9 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -231,7 +231,7 @@ struct kimage *do_kimage_alloc_init(void) struct kimage *image; /* Allocate a controlling structure */ - image = kzalloc(sizeof(*image), GFP_KERNEL); + image = kzalloc_obj(*image); if (!image) return NULL; @@ -975,7 +975,7 @@ void *kimage_map_segment(struct kimage *image, int idx) * Collect the source pages and map them in a contiguous VA range. */ npages = PFN_UP(eaddr) - PFN_DOWN(addr); - src_pages = kmalloc_array(npages, sizeof(*src_pages), GFP_KERNEL); + src_pages = kmalloc_objs(*src_pages, npages); if (!src_pages) { pr_err("Could not allocate ima pages array.\n"); return NULL; diff --git a/kernel/kprobes.c b/kernel/kprobes.c index ab8f9fc1f0d1..bfc89083daa9 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include @@ -170,7 +172,7 @@ kprobe_opcode_t *__get_insn_slot(struct kprobe_insn_cache *c) } while (c->nr_garbage && collect_garbage_slots(c) == 0); /* All out of space. Need to allocate a new page. */ - kip = kmalloc(struct_size(kip, slot_used, slots_per_page(c)), GFP_KERNEL); + kip = kmalloc_flex(*kip, slot_used, slots_per_page(c)); if (!kip) return NULL; @@ -514,8 +516,18 @@ static LIST_HEAD(optimizing_list); static LIST_HEAD(unoptimizing_list); static LIST_HEAD(freeing_list); -static void kprobe_optimizer(struct work_struct *work); -static DECLARE_DELAYED_WORK(optimizing_work, kprobe_optimizer); +static void optimize_kprobe(struct kprobe *p); +static struct task_struct *kprobe_optimizer_task; +static wait_queue_head_t kprobe_optimizer_wait; +static atomic_t optimizer_state; +enum { + OPTIMIZER_ST_IDLE = 0, + OPTIMIZER_ST_KICKED = 1, + OPTIMIZER_ST_FLUSHING = 2, +}; + +static DECLARE_COMPLETION(optimizer_completion); + #define OPTIMIZE_DELAY 5 /* @@ -593,18 +605,25 @@ static void do_free_cleaned_kprobes(void) */ continue; } + + /* + * The aggregator was holding back another probe while it sat on the + * unoptimizing/freeing lists. Now that the aggregator has been fully + * reverted we can safely retry the optimization of that sibling. + */ + + struct kprobe *_p = get_optimized_kprobe(op->kp.addr); + if (unlikely(_p)) + optimize_kprobe(_p); + free_aggr_kprobe(&op->kp); } } -/* Start optimizer after OPTIMIZE_DELAY passed */ -static void kick_kprobe_optimizer(void) -{ - schedule_delayed_work(&optimizing_work, OPTIMIZE_DELAY); -} +static void kick_kprobe_optimizer(void); /* Kprobe jump optimizer */ -static void kprobe_optimizer(struct work_struct *work) +static void kprobe_optimizer(void) { guard(mutex)(&kprobe_mutex); @@ -635,9 +654,53 @@ static void kprobe_optimizer(struct work_struct *work) do_free_cleaned_kprobes(); } - /* Step 5: Kick optimizer again if needed */ + /* Step 5: Kick optimizer again if needed. But if there is a flush requested, */ + if (completion_done(&optimizer_completion)) + complete(&optimizer_completion); + if (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) - kick_kprobe_optimizer(); + kick_kprobe_optimizer(); /*normal kick*/ +} + +static int kprobe_optimizer_thread(void *data) +{ + while (!kthread_should_stop()) { + /* To avoid hung_task, wait in interruptible state. */ + wait_event_interruptible(kprobe_optimizer_wait, + atomic_read(&optimizer_state) != OPTIMIZER_ST_IDLE || + kthread_should_stop()); + + if (kthread_should_stop()) + break; + + /* + * If it was a normal kick, wait for OPTIMIZE_DELAY. + * This wait can be interrupted by a flush request. + */ + if (atomic_read(&optimizer_state) == 1) + wait_event_interruptible_timeout( + kprobe_optimizer_wait, + atomic_read(&optimizer_state) == OPTIMIZER_ST_FLUSHING || + kthread_should_stop(), + OPTIMIZE_DELAY); + + if (kthread_should_stop()) + break; + + atomic_set(&optimizer_state, OPTIMIZER_ST_IDLE); + + kprobe_optimizer(); + } + return 0; +} + +/* Start optimizer after OPTIMIZE_DELAY passed */ +static void kick_kprobe_optimizer(void) +{ + lockdep_assert_held(&kprobe_mutex); + if (atomic_cmpxchg(&optimizer_state, + OPTIMIZER_ST_IDLE, OPTIMIZER_ST_KICKED) == OPTIMIZER_ST_IDLE) + wake_up(&kprobe_optimizer_wait); } static void wait_for_kprobe_optimizer_locked(void) @@ -645,13 +708,17 @@ static void wait_for_kprobe_optimizer_locked(void) lockdep_assert_held(&kprobe_mutex); while (!list_empty(&optimizing_list) || !list_empty(&unoptimizing_list)) { + init_completion(&optimizer_completion); + /* + * Set state to OPTIMIZER_ST_FLUSHING and wake up the thread if it's + * idle. If it's already kicked, it will see the state change. + */ + if (atomic_xchg_acquire(&optimizer_state, + OPTIMIZER_ST_FLUSHING) != OPTIMIZER_ST_FLUSHING) + wake_up(&kprobe_optimizer_wait); + mutex_unlock(&kprobe_mutex); - - /* This will also make 'optimizing_work' execute immmediately */ - flush_delayed_work(&optimizing_work); - /* 'optimizing_work' might not have been queued yet, relax */ - cpu_relax(); - + wait_for_completion(&optimizer_completion); mutex_lock(&kprobe_mutex); } } @@ -833,7 +900,7 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) { struct optimized_kprobe *op; - op = kzalloc(sizeof(struct optimized_kprobe), GFP_KERNEL); + op = kzalloc_obj(struct optimized_kprobe); if (!op) return NULL; @@ -1002,16 +1069,23 @@ static void __disarm_kprobe(struct kprobe *p, bool reopt) if (unlikely(_p) && reopt) optimize_kprobe(_p); } - /* - * TODO: Since unoptimization and real disarming will be done by - * the worker thread, we can not check whether another probe are - * unoptimized because of this probe here. It should be re-optimized - * by the worker thread. - */ } +static void __init init_optprobe(void) +{ +#ifdef __ARCH_WANT_KPROBES_INSN_SLOT + /* Init 'kprobe_optinsn_slots' for allocation */ + kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; +#endif + + init_waitqueue_head(&kprobe_optimizer_wait); + atomic_set(&optimizer_state, OPTIMIZER_ST_IDLE); + kprobe_optimizer_task = kthread_run(kprobe_optimizer_thread, NULL, + "kprobe-optimizer"); +} #else /* !CONFIG_OPTPROBES */ +#define init_optprobe() do {} while (0) #define optimize_kprobe(p) do {} while (0) #define unoptimize_kprobe(p, f) do {} while (0) #define kill_optimized_kprobe(p) do {} while (0) @@ -1043,7 +1117,7 @@ static void free_aggr_kprobe(struct kprobe *p) static struct kprobe *alloc_aggr_kprobe(struct kprobe *p) { - return kzalloc(sizeof(struct kprobe), GFP_KERNEL); + return kzalloc_obj(struct kprobe); } #endif /* CONFIG_OPTPROBES */ @@ -1070,12 +1144,12 @@ static int __arm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, lockdep_assert_held(&kprobe_mutex); ret = ftrace_set_filter_ip(ops, (unsigned long)p->addr, 0, 0); - if (WARN_ONCE(ret < 0, "Failed to arm kprobe-ftrace at %pS (error %d)\n", p->addr, ret)) + if (ret < 0) return ret; if (*cnt == 0) { ret = register_ftrace_function(ops); - if (WARN(ret < 0, "Failed to register kprobe-ftrace (error %d)\n", ret)) { + if (ret < 0) { /* * At this point, sinec ops is not registered, we should be sefe from * registering empty filter. @@ -1104,6 +1178,10 @@ static int __disarm_kprobe_ftrace(struct kprobe *p, struct ftrace_ops *ops, int ret; lockdep_assert_held(&kprobe_mutex); + if (unlikely(kprobe_ftrace_disabled)) { + /* Now ftrace is disabled forever, disarm is already done. */ + return 0; + } if (*cnt == 1) { ret = unregister_ftrace_function(ops); @@ -2221,7 +2299,7 @@ int register_kretprobe(struct kretprobe *rp) rp->rh = NULL; } #else /* !CONFIG_KRETPROBE_ON_RETHOOK */ - rp->rph = kzalloc(sizeof(struct kretprobe_holder), GFP_KERNEL); + rp->rph = kzalloc_obj(struct kretprobe_holder); if (!rp->rph) return -ENOMEM; @@ -2425,7 +2503,7 @@ int kprobe_add_ksym_blacklist(unsigned long entry) !kallsyms_lookup_size_offset(entry, &size, &offset)) return -EINVAL; - ent = kmalloc(sizeof(*ent), GFP_KERNEL); + ent = kmalloc_obj(*ent); if (!ent) return -ENOMEM; ent->start_addr = entry; @@ -2694,10 +2772,8 @@ static int __init init_kprobes(void) /* By default, kprobes are armed */ kprobes_all_disarmed = false; -#if defined(CONFIG_OPTPROBES) && defined(__ARCH_WANT_KPROBES_INSN_SLOT) - /* Init 'kprobe_optinsn_slots' for allocation */ - kprobe_optinsn_slots.insn_size = MAX_OPTINSN_SIZE; -#endif + /* Initialize the optimization infrastructure */ + init_optprobe(); err = arch_init_kprobes(); if (!err) diff --git a/kernel/kthread.c b/kernel/kthread.c index c9507689e181..791210daf8b4 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -85,24 +85,6 @@ static inline struct kthread *to_kthread(struct task_struct *k) return k->worker_private; } -/* - * Variant of to_kthread() that doesn't assume @p is a kthread. - * - * When "(p->flags & PF_KTHREAD)" is set the task is a kthread and will - * always remain a kthread. For kthreads p->worker_private always - * points to a struct kthread. For tasks that are not kthreads - * p->worker_private is used to point to other things. - * - * Return NULL for any task that is not a kthread. - */ -static inline struct kthread *__to_kthread(struct task_struct *p) -{ - void *kthread = p->worker_private; - if (kthread && !(p->flags & PF_KTHREAD)) - kthread = NULL; - return kthread; -} - void get_kthread_comm(char *buf, size_t buf_size, struct task_struct *tsk) { struct kthread *kthread = to_kthread(tsk); @@ -122,7 +104,7 @@ bool set_kthread_struct(struct task_struct *p) if (WARN_ON_ONCE(to_kthread(p))) return false; - kthread = kzalloc(sizeof(*kthread), GFP_KERNEL); + kthread = kzalloc_obj(*kthread); if (!kthread) return false; @@ -193,7 +175,7 @@ EXPORT_SYMBOL_GPL(kthread_should_park); bool kthread_should_stop_or_park(void) { - struct kthread *kthread = __to_kthread(current); + struct kthread *kthread = tsk_is_kthread(current); if (!kthread) return false; @@ -234,7 +216,7 @@ EXPORT_SYMBOL_GPL(kthread_freezable_should_stop); */ void *kthread_func(struct task_struct *task) { - struct kthread *kthread = __to_kthread(task); + struct kthread *kthread = tsk_is_kthread(task); if (kthread) return kthread->threadfn; return NULL; @@ -266,7 +248,7 @@ EXPORT_SYMBOL_GPL(kthread_data); */ void *kthread_probe_data(struct task_struct *task) { - struct kthread *kthread = __to_kthread(task); + struct kthread *kthread = tsk_is_kthread(task); void *data = NULL; if (kthread) @@ -309,19 +291,8 @@ void kthread_parkme(void) } EXPORT_SYMBOL_GPL(kthread_parkme); -/** - * kthread_exit - Cause the current kthread return @result to kthread_stop(). - * @result: The integer value to return to kthread_stop(). - * - * While kthread_exit can be called directly, it exists so that - * functions which do some additional work in non-modular code such as - * module_put_and_kthread_exit can be implemented. - * - * Does not return. - */ -void __noreturn kthread_exit(long result) +void kthread_do_exit(struct kthread *kthread, long result) { - struct kthread *kthread = to_kthread(current); kthread->result = result; if (!list_empty(&kthread->affinity_node)) { mutex_lock(&kthread_affinity_lock); @@ -333,9 +304,7 @@ void __noreturn kthread_exit(long result) kthread->preferred_affinity = NULL; } } - do_exit(0); } -EXPORT_SYMBOL(kthread_exit); /** * kthread_complete_and_exit - Exit the current kthread. @@ -511,8 +480,7 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), { DECLARE_COMPLETION_ONSTACK(done); struct task_struct *task; - struct kthread_create_info *create = kmalloc(sizeof(*create), - GFP_KERNEL); + struct kthread_create_info *create = kmalloc_obj(*create); if (!create) return ERR_PTR(-ENOMEM); @@ -684,7 +652,7 @@ void kthread_set_per_cpu(struct task_struct *k, int cpu) bool kthread_is_per_cpu(struct task_struct *p) { - struct kthread *kthread = __to_kthread(p); + struct kthread *kthread = tsk_is_kthread(p); if (!kthread) return false; @@ -1084,7 +1052,7 @@ __kthread_create_worker_on_node(unsigned int flags, int node, struct kthread_worker *worker; struct task_struct *task; - worker = kzalloc(sizeof(*worker), GFP_KERNEL); + worker = kzalloc_obj(*worker); if (!worker) return ERR_PTR(-ENOMEM); diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 1acbad2dbfdf..28d15ba58a26 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c @@ -525,7 +525,7 @@ static struct klp_object *klp_alloc_object_dynamic(const char *name, { struct klp_object *obj; - obj = kzalloc(sizeof(*obj), GFP_KERNEL); + obj = kzalloc_obj(*obj); if (!obj) return NULL; @@ -554,7 +554,7 @@ static struct klp_func *klp_alloc_func_nop(struct klp_func *old_func, { struct klp_func *func; - func = kzalloc(sizeof(*func), GFP_KERNEL); + func = kzalloc_obj(*func); if (!func) return NULL; diff --git a/kernel/livepatch/patch.c b/kernel/livepatch/patch.c index 90408500e5a3..3f54a017bbf6 100644 --- a/kernel/livepatch/patch.c +++ b/kernel/livepatch/patch.c @@ -179,7 +179,7 @@ static int klp_patch_func(struct klp_func *func) return -EINVAL; } - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (!ops) return -ENOMEM; diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c index fb3a7b67676e..cc68a3692905 100644 --- a/kernel/liveupdate/kexec_handover.c +++ b/kernel/liveupdate/kexec_handover.c @@ -187,7 +187,7 @@ static int __kho_preserve_order(struct kho_mem_track *track, unsigned long pfn, if (!physxa) { int err; - new_physxa = kzalloc(sizeof(*physxa), GFP_KERNEL); + new_physxa = kzalloc_obj(*physxa); if (!new_physxa) return -ENOMEM; @@ -1090,7 +1090,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) return NULL; total_pages = preservation->total_pages; - pages = kvmalloc_array(total_pages, sizeof(*pages), GFP_KERNEL); + pages = kvmalloc_objs(*pages, total_pages); if (!pages) return NULL; order = preservation->order; @@ -1463,36 +1463,37 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, struct kho_scratch *scratch = NULL; phys_addr_t mem_map_phys; void *fdt = NULL; + bool populated = false; int err; /* Validate the input FDT */ fdt = early_memremap(fdt_phys, fdt_len); if (!fdt) { pr_warn("setup: failed to memremap FDT (0x%llx)\n", fdt_phys); - goto err_report; + goto report; } err = fdt_check_header(fdt); if (err) { pr_warn("setup: handover FDT (0x%llx) is invalid: %d\n", fdt_phys, err); - goto err_unmap_fdt; + goto unmap_fdt; } err = fdt_node_check_compatible(fdt, 0, KHO_FDT_COMPATIBLE); if (err) { pr_warn("setup: handover FDT (0x%llx) is incompatible with '%s': %d\n", fdt_phys, KHO_FDT_COMPATIBLE, err); - goto err_unmap_fdt; + goto unmap_fdt; } mem_map_phys = kho_get_mem_map_phys(fdt); if (!mem_map_phys) - goto err_unmap_fdt; + goto unmap_fdt; scratch = early_memremap(scratch_phys, scratch_len); if (!scratch) { pr_warn("setup: failed to memremap scratch (phys=0x%llx, len=%lld)\n", scratch_phys, scratch_len); - goto err_unmap_fdt; + goto unmap_fdt; } /* @@ -1506,10 +1507,10 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, memblock_add(area->addr, size); err = memblock_mark_kho_scratch(area->addr, size); - if (WARN_ON(err)) { + if (err) { pr_warn("failed to mark the scratch region 0x%pa+0x%pa: %pe", &area->addr, &size, ERR_PTR(err)); - goto err_unmap_scratch; + goto unmap_scratch; } pr_debug("Marked 0x%pa+0x%pa as scratch", &area->addr, &size); } @@ -1529,16 +1530,17 @@ void __init kho_populate(phys_addr_t fdt_phys, u64 fdt_len, kho_in.scratch_phys = scratch_phys; kho_in.mem_map_phys = mem_map_phys; kho_scratch_cnt = scratch_cnt; + + populated = true; pr_info("found kexec handover data.\n"); - return; - -err_unmap_scratch: +unmap_scratch: early_memunmap(scratch, scratch_len); -err_unmap_fdt: +unmap_fdt: early_memunmap(fdt, fdt_len); -err_report: - pr_warn("disabling KHO revival\n"); +report: + if (!populated) + pr_warn("disabling KHO revival\n"); } /* Helper functions for kexec_file_load */ diff --git a/kernel/liveupdate/kexec_handover_debugfs.c b/kernel/liveupdate/kexec_handover_debugfs.c index 2abbf62ba942..2f93939168ab 100644 --- a/kernel/liveupdate/kexec_handover_debugfs.c +++ b/kernel/liveupdate/kexec_handover_debugfs.c @@ -29,7 +29,7 @@ static int __kho_debugfs_fdt_add(struct list_head *list, struct dentry *dir, struct fdt_debugfs *f; struct dentry *file; - f = kmalloc(sizeof(*f), GFP_KERNEL); + f = kmalloc_obj(*f); if (!f) return -ENOMEM; diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index 4c7df52a6507..5acee4174bf0 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -134,9 +134,12 @@ static LIST_HEAD(luo_file_handler_list); * state that is not preserved. Set by the handler's .preserve() * callback, and must be freed in the handler's .unpreserve() * callback. - * @retrieved: A flag indicating whether a user/kernel in the new kernel has + * @retrieve_status: Status code indicating whether a user/kernel in the new kernel has * successfully called retrieve() on this file. This prevents - * multiple retrieval attempts. + * multiple retrieval attempts. A value of 0 means a retrieve() + * has not been attempted, a positive value means the retrieve() + * was successful, and a negative value means the retrieve() + * failed, and the value is the error code of the call. * @mutex: A mutex that protects the fields of this specific instance * (e.g., @retrieved, @file), ensuring that operations like * retrieving or finishing a file are atomic. @@ -161,7 +164,7 @@ struct luo_file { struct file *file; u64 serialized_data; void *private_data; - bool retrieved; + int retrieve_status; struct mutex mutex; struct list_head list; u64 token; @@ -289,7 +292,7 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd) if (err) goto err_free_files_mem; - luo_file = kzalloc(sizeof(*luo_file), GFP_KERNEL); + luo_file = kzalloc_obj(*luo_file); if (!luo_file) { err = -ENOMEM; goto err_flb_unpreserve; @@ -298,7 +301,6 @@ int luo_preserve_file(struct luo_file_set *file_set, u64 token, int fd) luo_file->file = file; luo_file->fh = fh; luo_file->token = token; - luo_file->retrieved = false; mutex_init(&luo_file->mutex); args.handler = fh; @@ -577,7 +579,12 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token, return -ENOENT; guard(mutex)(&luo_file->mutex); - if (luo_file->retrieved) { + if (luo_file->retrieve_status < 0) { + /* Retrieve was attempted and it failed. Return the error code. */ + return luo_file->retrieve_status; + } + + if (luo_file->retrieve_status > 0) { /* * Someone is asking for this file again, so get a reference * for them. @@ -590,16 +597,19 @@ int luo_retrieve_file(struct luo_file_set *file_set, u64 token, args.handler = luo_file->fh; args.serialized_data = luo_file->serialized_data; err = luo_file->fh->ops->retrieve(&args); - if (!err) { - luo_file->file = args.file; - - /* Get reference so we can keep this file in LUO until finish */ - get_file(luo_file->file); - *filep = luo_file->file; - luo_file->retrieved = true; + if (err) { + /* Keep the error code for later use. */ + luo_file->retrieve_status = err; + return err; } - return err; + luo_file->file = args.file; + /* Get reference so we can keep this file in LUO until finish */ + get_file(luo_file->file); + *filep = luo_file->file; + luo_file->retrieve_status = 1; + + return 0; } static int luo_file_can_finish_one(struct luo_file_set *file_set, @@ -615,7 +625,7 @@ static int luo_file_can_finish_one(struct luo_file_set *file_set, args.handler = luo_file->fh; args.file = luo_file->file; args.serialized_data = luo_file->serialized_data; - args.retrieved = luo_file->retrieved; + args.retrieve_status = luo_file->retrieve_status; can_finish = luo_file->fh->ops->can_finish(&args); } @@ -632,7 +642,7 @@ static void luo_file_finish_one(struct luo_file_set *file_set, args.handler = luo_file->fh; args.file = luo_file->file; args.serialized_data = luo_file->serialized_data; - args.retrieved = luo_file->retrieved; + args.retrieve_status = luo_file->retrieve_status; luo_file->fh->ops->finish(&args); luo_flb_file_finish(luo_file->fh); @@ -780,7 +790,7 @@ int luo_file_deserialize(struct luo_file_set *file_set, return -ENOENT; } - luo_file = kzalloc(sizeof(*luo_file), GFP_KERNEL); + luo_file = kzalloc_obj(*luo_file); if (!luo_file) return -ENOMEM; @@ -788,7 +798,6 @@ int luo_file_deserialize(struct luo_file_set *file_set, luo_file->file = NULL; luo_file->serialized_data = file_ser[i].data; luo_file->token = file_ser[i].token; - luo_file->retrieved = false; mutex_init(&luo_file->mutex); list_add_tail(&luo_file->list, &file_set->files_list); } diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index 4c437de5c0b0..f52e8114837e 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -343,7 +343,7 @@ int liveupdate_register_flb(struct liveupdate_file_handler *fh, if (WARN_ON(list_empty(&ACCESS_PRIVATE(fh, list)))) return -EINVAL; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return -ENOMEM; diff --git a/kernel/liveupdate/luo_session.c b/kernel/liveupdate/luo_session.c index dbdbc3bd7929..783677295640 100644 --- a/kernel/liveupdate/luo_session.c +++ b/kernel/liveupdate/luo_session.c @@ -119,7 +119,7 @@ static struct luo_session_global luo_session_global = { static struct luo_session *luo_session_alloc(const char *name) { - struct luo_session *session = kzalloc(sizeof(*session), GFP_KERNEL); + struct luo_session *session = kzalloc_obj(*session); if (!session) return ERR_PTR(-ENOMEM); diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c index 6567e5eeacc0..e618bcf75e2d 100644 --- a/kernel/locking/locktorture.c +++ b/kernel/locking/locktorture.c @@ -610,9 +610,8 @@ static void torture_ww_mutex_init(void) ww_mutex_init(&torture_ww_mutex_1, &torture_ww_class); ww_mutex_init(&torture_ww_mutex_2, &torture_ww_class); - ww_acquire_ctxs = kmalloc_array(cxt.nrealwriters_stress, - sizeof(*ww_acquire_ctxs), - GFP_KERNEL); + ww_acquire_ctxs = kmalloc_objs(*ww_acquire_ctxs, + cxt.nrealwriters_stress); if (!ww_acquire_ctxs) VERBOSE_TOROUT_STRING("ww_acquire_ctx: Out of memory"); } @@ -1129,7 +1128,8 @@ static int call_rcu_chain_init(void) if (call_rcu_chains <= 0) return 0; - call_rcu_chain_list = kcalloc(call_rcu_chains, sizeof(*call_rcu_chain_list), GFP_KERNEL); + call_rcu_chain_list = kzalloc_objs(*call_rcu_chain_list, + call_rcu_chains); if (!call_rcu_chain_list) return -ENOMEM; for (i = 0; i < call_rcu_chains; i++) { @@ -1293,9 +1293,7 @@ static int __init lock_torture_init(void) /* Initialize the statistics so that each run gets its own numbers. */ if (nwriters_stress) { lock_is_write_held = false; - cxt.lwsa = kmalloc_array(cxt.nrealwriters_stress, - sizeof(*cxt.lwsa), - GFP_KERNEL); + cxt.lwsa = kmalloc_objs(*cxt.lwsa, cxt.nrealwriters_stress); if (cxt.lwsa == NULL) { VERBOSE_TOROUT_STRING("cxt.lwsa: Out of memory"); firsterr = -ENOMEM; @@ -1323,9 +1321,8 @@ static int __init lock_torture_init(void) } if (nreaders_stress) { - cxt.lrsa = kmalloc_array(cxt.nrealreaders_stress, - sizeof(*cxt.lrsa), - GFP_KERNEL); + cxt.lrsa = kmalloc_objs(*cxt.lrsa, + cxt.nrealreaders_stress); if (cxt.lrsa == NULL) { VERBOSE_TOROUT_STRING("cxt.lrsa: Out of memory"); firsterr = -ENOMEM; @@ -1372,9 +1369,8 @@ static int __init lock_torture_init(void) } if (nwriters_stress) { - writer_tasks = kcalloc(cxt.nrealwriters_stress, - sizeof(writer_tasks[0]), - GFP_KERNEL); + writer_tasks = kzalloc_objs(writer_tasks[0], + cxt.nrealwriters_stress); if (writer_tasks == NULL) { TOROUT_ERRSTRING("writer_tasks: Out of memory"); firsterr = -ENOMEM; @@ -1387,9 +1383,8 @@ static int __init lock_torture_init(void) nested_locks = MAX_NESTED_LOCKS; if (cxt.cur_ops->readlock) { - reader_tasks = kcalloc(cxt.nrealreaders_stress, - sizeof(reader_tasks[0]), - GFP_KERNEL); + reader_tasks = kzalloc_objs(reader_tasks[0], + cxt.nrealreaders_stress); if (reader_tasks == NULL) { TOROUT_ERRSTRING("reader_tasks: Out of memory"); kfree(writer_tasks); diff --git a/kernel/locking/test-ww_mutex.c b/kernel/locking/test-ww_mutex.c index 79b5e45f8d4c..838d631544ed 100644 --- a/kernel/locking/test-ww_mutex.c +++ b/kernel/locking/test-ww_mutex.c @@ -324,7 +324,7 @@ static int __test_cycle(struct ww_class *class, unsigned int nthreads) unsigned int n, last = nthreads - 1; int ret; - cycles = kmalloc_array(nthreads, sizeof(*cycles), GFP_KERNEL); + cycles = kmalloc_objs(*cycles, nthreads); if (!cycles) return -ENOMEM; @@ -412,7 +412,7 @@ static int *get_random_order(int count) int *order; int n, r; - order = kmalloc_array(count, sizeof(*order), GFP_KERNEL); + order = kmalloc_objs(*order, count); if (!order) return order; @@ -506,7 +506,7 @@ static void stress_reorder_work(struct work_struct *work) return; for (n = 0; n < stress->nlocks; n++) { - ll = kmalloc(sizeof(*ll), GFP_KERNEL); + ll = kmalloc_obj(*ll); if (!ll) goto out; @@ -582,12 +582,11 @@ static int stress(struct ww_class *class, int nlocks, int nthreads, unsigned int struct stress *stress_array; int n, count; - locks = kmalloc_array(nlocks, sizeof(*locks), GFP_KERNEL); + locks = kmalloc_objs(*locks, nlocks); if (!locks) return -ENOMEM; - stress_array = kmalloc_array(nthreads, sizeof(*stress_array), - GFP_KERNEL); + stress_array = kmalloc_objs(*stress_array, nthreads); if (!stress_array) { kfree(locks); return -ENOMEM; diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index be74917802ad..43b1bb01fd27 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -169,9 +169,10 @@ config MODVERSIONS make them incompatible with the kernel you are running. If unsure, say N. +if MODVERSIONS + choice prompt "Module versioning implementation" - depends on MODVERSIONS help Select the tool used to calculate symbol versions for modules. @@ -206,7 +207,7 @@ endchoice config ASM_MODVERSIONS bool - default HAVE_ASM_MODVERSIONS && MODVERSIONS + default HAVE_ASM_MODVERSIONS help This enables module versioning for exported symbols also from assembly. This can be enabled only when the target architecture @@ -214,7 +215,6 @@ config ASM_MODVERSIONS config EXTENDED_MODVERSIONS bool "Extended Module Versioning Support" - depends on MODVERSIONS help This enables extended MODVERSIONs support, allowing long symbol names to be versioned. @@ -224,7 +224,6 @@ config EXTENDED_MODVERSIONS config BASIC_MODVERSIONS bool "Basic Module Versioning Support" - depends on MODVERSIONS default y help This enables basic MODVERSIONS support, allowing older tools or @@ -237,6 +236,8 @@ config BASIC_MODVERSIONS This is enabled by default when MODVERSIONS are enabled. If unsure, say Y. +endif # MODVERSIONS + config MODULE_SRCVERSION_ALL bool "Source checksum for all modules" help @@ -277,10 +278,11 @@ config MODULE_SIG_FORCE Reject unsigned modules or signed modules for which we don't have a key. Without this, such modules will simply taint the kernel. +if MODULE_SIG || IMA_APPRAISE_MODSIG + config MODULE_SIG_ALL bool "Automatically sign all modules" default y - depends on MODULE_SIG || IMA_APPRAISE_MODSIG help Sign all modules during make modules_install. Without this option, modules must be signed manually, using the scripts/sign-file tool. @@ -290,7 +292,6 @@ comment "Do not forget to sign required modules with scripts/sign-file" choice prompt "Hash algorithm to sign modules" - depends on MODULE_SIG || IMA_APPRAISE_MODSIG default MODULE_SIG_SHA512 help This determines which sort of hashing algorithm will be used during @@ -327,7 +328,6 @@ endchoice config MODULE_SIG_HASH string - depends on MODULE_SIG || IMA_APPRAISE_MODSIG default "sha256" if MODULE_SIG_SHA256 default "sha384" if MODULE_SIG_SHA384 default "sha512" if MODULE_SIG_SHA512 @@ -335,6 +335,8 @@ config MODULE_SIG_HASH default "sha3-384" if MODULE_SIG_SHA3_384 default "sha3-512" if MODULE_SIG_SHA3_512 +endif # MODULE_SIG || IMA_APPRAISE_MODSIG + config MODULE_COMPRESS bool "Module compression" help @@ -350,9 +352,10 @@ config MODULE_COMPRESS If unsure, say N. +if MODULE_COMPRESS + choice prompt "Module compression type" - depends on MODULE_COMPRESS help Choose the supported algorithm for module compression. @@ -379,7 +382,6 @@ endchoice config MODULE_COMPRESS_ALL bool "Automatically compress all modules" default y - depends on MODULE_COMPRESS help Compress all modules during 'make modules_install'. @@ -389,7 +391,6 @@ config MODULE_COMPRESS_ALL config MODULE_DECOMPRESS bool "Support in-kernel module decompression" - depends on MODULE_COMPRESS select ZLIB_INFLATE if MODULE_COMPRESS_GZIP select XZ_DEC if MODULE_COMPRESS_XZ select ZSTD_DECOMPRESS if MODULE_COMPRESS_ZSTD @@ -400,6 +401,8 @@ config MODULE_DECOMPRESS If unsure, say N. +endif # MODULE_COMPRESS + config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS bool "Allow loading of modules with missing namespace imports" help diff --git a/kernel/module/dups.c b/kernel/module/dups.c index 0b633f2edda6..1d720a5311ba 100644 --- a/kernel/module/dups.c +++ b/kernel/module/dups.c @@ -125,7 +125,7 @@ bool kmod_dup_request_exists_wait(char *module_name, bool wait, int *dup_ret) * Pre-allocate the entry in case we have to use it later * to avoid contention with the mutex. */ - new_kmod_req = kzalloc(sizeof(*new_kmod_req), GFP_KERNEL); + new_kmod_req = kzalloc_obj(*new_kmod_req); if (!new_kmod_req) return false; diff --git a/kernel/module/main.c b/kernel/module/main.c index 710ee30b3bea..c3ce106c70af 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -662,7 +662,7 @@ static int add_module_usage(struct module *a, struct module *b) struct module_use *use; pr_debug("Allocating new usage for %s.\n", a->name); - use = kmalloc(sizeof(*use), GFP_ATOMIC); + use = kmalloc_obj(*use, GFP_ATOMIC); if (!use) return -ENOMEM; @@ -1568,6 +1568,13 @@ static int simplify_symbols(struct module *mod, const struct load_info *info) break; default: + if (sym[i].st_shndx >= info->hdr->e_shnum) { + pr_err("%s: Symbol %s has an invalid section index %u (max %u)\n", + mod->name, name, sym[i].st_shndx, info->hdr->e_shnum - 1); + ret = -ENOEXEC; + break; + } + /* Divert to percpu allocation if a percpu var. */ if (sym[i].st_shndx == info->index.pcpu) secbase = (unsigned long)mod_percpu(mod); @@ -3024,7 +3031,7 @@ static noinline int do_init_module(struct module *mod) } #endif - freeinit = kmalloc(sizeof(*freeinit), GFP_KERNEL); + freeinit = kmalloc_obj(*freeinit); if (!freeinit) { ret = -ENOMEM; goto fail; @@ -3544,12 +3551,6 @@ static int load_module(struct load_info *info, const char __user *uargs, mutex_unlock(&module_mutex); free_module: mod_stat_bump_invalid(info, flags); - /* Free lock-classes; relies on the preceding sync_rcu() */ - for_class_mod_mem_type(type, core_data) { - lockdep_free_key_range(mod->mem[type].base, - mod->mem[type].size); - } - module_memory_restore_rox(mod); module_deallocate(mod, info); free_copy: diff --git a/kernel/module/stats.c b/kernel/module/stats.c index 3ba0e98b3c91..3a9672f93a8e 100644 --- a/kernel/module/stats.c +++ b/kernel/module/stats.c @@ -250,7 +250,7 @@ int try_add_failed_module(const char *name, enum fail_dup_mod_reason reason) } } - mod_fail = kzalloc(sizeof(*mod_fail), GFP_KERNEL); + mod_fail = kzalloc_obj(*mod_fail); if (!mod_fail) return -ENOMEM; memcpy(mod_fail->name, name, strlen(name)); diff --git a/kernel/module/sysfs.c b/kernel/module/sysfs.c index c7622ff5226a..01c65d608873 100644 --- a/kernel/module/sysfs.c +++ b/kernel/module/sysfs.c @@ -74,11 +74,11 @@ static int add_sect_attrs(struct module *mod, const struct load_info *info) for (i = 0; i < info->hdr->e_shnum; i++) if (!sect_empty(&info->sechdrs[i])) nloaded++; - sect_attrs = kzalloc(struct_size(sect_attrs, attrs, nloaded), GFP_KERNEL); + sect_attrs = kzalloc_flex(*sect_attrs, attrs, nloaded); if (!sect_attrs) return -ENOMEM; - gattr = kcalloc(nloaded + 1, sizeof(*gattr), GFP_KERNEL); + gattr = kzalloc_objs(*gattr, nloaded + 1); if (!gattr) { kfree(sect_attrs); return -ENOMEM; @@ -166,12 +166,11 @@ static int add_notes_attrs(struct module *mod, const struct load_info *info) if (notes == 0) return 0; - notes_attrs = kzalloc(struct_size(notes_attrs, attrs, notes), - GFP_KERNEL); + notes_attrs = kzalloc_flex(*notes_attrs, attrs, notes); if (!notes_attrs) return -ENOMEM; - gattr = kcalloc(notes + 1, sizeof(*gattr), GFP_KERNEL); + gattr = kzalloc_objs(*gattr, notes + 1); if (!gattr) { kfree(notes_attrs); return -ENOMEM; diff --git a/kernel/module/tracking.c b/kernel/module/tracking.c index 4fefec5b683c..9033ff54c4e2 100644 --- a/kernel/module/tracking.c +++ b/kernel/module/tracking.c @@ -33,7 +33,7 @@ int try_add_tainted_module(struct module *mod) } } - mod_taint = kmalloc(sizeof(*mod_taint), GFP_KERNEL); + mod_taint = kmalloc_obj(*mod_taint); if (unlikely(!mod_taint)) return -ENOMEM; strscpy(mod_taint->name, mod->name, MODULE_NAME_LEN); diff --git a/kernel/nscommon.c b/kernel/nscommon.c index bdc3c86231d3..3166c1fd844a 100644 --- a/kernel/nscommon.c +++ b/kernel/nscommon.c @@ -309,3 +309,9 @@ void __ns_ref_active_get(struct ns_common *ns) return; } } + +bool may_see_all_namespaces(void) +{ + return (task_active_pid_ns(current) == &init_pid_ns) && + ns_capable_noaudit(init_pid_ns.user_ns, CAP_SYS_ADMIN); +} diff --git a/kernel/nstree.c b/kernel/nstree.c index f36c59e6951d..6d12e5900ac0 100644 --- a/kernel/nstree.c +++ b/kernel/nstree.c @@ -515,32 +515,11 @@ static inline bool __must_check ns_requested(const struct klistns *kls, static inline bool __must_check may_list_ns(const struct klistns *kls, struct ns_common *ns) { - if (kls->user_ns) { - if (kls->userns_capable) - return true; - } else { - struct ns_common *owner; - struct user_namespace *user_ns; - - owner = ns_owner(ns); - if (owner) - user_ns = to_user_ns(owner); - else - user_ns = &init_user_ns; - if (ns_capable_noaudit(user_ns, CAP_SYS_ADMIN)) - return true; - } - + if (kls->user_ns && kls->userns_capable) + return true; if (is_current_namespace(ns)) return true; - - if (ns->ns_type != CLONE_NEWUSER) - return false; - - if (ns_capable_noaudit(to_user_ns(ns), CAP_SYS_ADMIN)) - return true; - - return false; + return may_see_all_namespaces(); } static inline void ns_put(struct ns_common *ns) @@ -600,7 +579,7 @@ static ssize_t do_listns_userns(struct klistns *kls) ret = 0; head = &to_ns_common(kls->user_ns)->ns_owner_root.ns_list_head; - kls->userns_capable = ns_capable_noaudit(kls->user_ns, CAP_SYS_ADMIN); + kls->userns_capable = may_see_all_namespaces(); rcu_read_lock(); diff --git a/kernel/padata.c b/kernel/padata.c index db7c75787a2b..8657e6e0c224 100644 --- a/kernel/padata.c +++ b/kernel/padata.c @@ -540,7 +540,7 @@ static struct parallel_data *padata_alloc_pd(struct padata_shell *ps) struct padata_instance *pinst = ps->pinst; struct parallel_data *pd; - pd = kzalloc(sizeof(struct parallel_data), GFP_KERNEL); + pd = kzalloc_obj(struct parallel_data); if (!pd) goto err; @@ -952,7 +952,7 @@ struct padata_instance *padata_alloc(const char *name) { struct padata_instance *pinst; - pinst = kzalloc(sizeof(struct padata_instance), GFP_KERNEL); + pinst = kzalloc_obj(struct padata_instance); if (!pinst) goto err; @@ -1038,7 +1038,7 @@ struct padata_shell *padata_alloc_shell(struct padata_instance *pinst) struct parallel_data *pd; struct padata_shell *ps; - ps = kzalloc(sizeof(*ps), GFP_KERNEL); + ps = kzalloc_obj(*ps); if (!ps) goto out; @@ -1106,8 +1106,7 @@ void __init padata_init(void) #endif possible_cpus = num_possible_cpus(); - padata_works = kmalloc_array(possible_cpus, sizeof(struct padata_work), - GFP_KERNEL); + padata_works = kmalloc_objs(struct padata_work, possible_cpus); if (!padata_works) goto remove_dead_state; diff --git a/kernel/params.c b/kernel/params.c index 7c2242f64bf0..7188a12dbe86 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -633,13 +633,12 @@ static __init_or_module int add_sysfs_param(struct module_kobject *mk, if (!mk->mp) { /* First allocation. */ - mk->mp = kzalloc(sizeof(*mk->mp), GFP_KERNEL); + mk->mp = kzalloc_obj(*mk->mp); if (!mk->mp) return -ENOMEM; mk->mp->grp.name = "parameters"; /* NULL-terminated attribute array. */ - mk->mp->grp.attrs = kzalloc(sizeof(mk->mp->grp.attrs[0]), - GFP_KERNEL); + mk->mp->grp.attrs = kzalloc_obj(mk->mp->grp.attrs[0]); /* Caller will cleanup via free_module_param_attrs */ if (!mk->mp->grp.attrs) return -ENOMEM; @@ -766,7 +765,7 @@ lookup_or_create_module_kobject(const char *name) if (kobj) return to_module_kobject(kobj); - mk = kzalloc(sizeof(struct module_kobject), GFP_KERNEL); + mk = kzalloc_obj(struct module_kobject); if (!mk) return NULL; diff --git a/kernel/pid.c b/kernel/pid.c index f45ae56db7da..3b96571d0fe6 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include @@ -85,7 +84,6 @@ struct pid_namespace init_pid_ns = { EXPORT_SYMBOL_GPL(init_pid_ns); static __cacheline_aligned_in_smp DEFINE_SPINLOCK(pidmap_lock); -seqcount_spinlock_t pidmap_lock_seq = SEQCNT_SPINLOCK_ZERO(pidmap_lock_seq, &pidmap_lock); void put_pid(struct pid *pid) { @@ -141,9 +139,9 @@ void free_pid(struct pid *pid) idr_remove(&ns->idr, upid->nr); } - pidfs_remove_pid(pid); spin_unlock(&pidmap_lock); + pidfs_remove_pid(pid); call_rcu(&pid->rcu, delayed_put_pid); } @@ -200,6 +198,7 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *arg_set_tid, INIT_HLIST_HEAD(&pid->tasks[type]); init_waitqueue_head(&pid->wait_pidfd); INIT_HLIST_HEAD(&pid->inodes); + pidfs_prepare_pid(pid); /* * 2. perm check checkpoint_restore_ns_capable() @@ -316,7 +315,6 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *arg_set_tid, retval = -ENOMEM; if (unlikely(!(ns->pid_allocated & PIDNS_ADDING))) goto out_free; - pidfs_add_pid(pid); for (upid = pid->numbers + ns->level; upid >= pid->numbers; --upid) { /* Make the PID visible to find_pid_ns. */ idr_replace(&upid->ns->idr, pid, upid->nr); @@ -326,6 +324,12 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *arg_set_tid, idr_preload_end(); ns_ref_active_get(ns); + retval = pidfs_add_pid(pid); + if (unlikely(retval)) { + free_pid(pid); + pid = ERR_PTR(-ENOMEM); + } + return pid; out_free: @@ -554,8 +558,7 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, rcu_read_lock(); if (!ns) ns = task_active_pid_ns(current); - if (ns) - nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns); + nr = pid_nr_ns(rcu_dereference(*task_pid_ptr(task, type)), ns); rcu_read_unlock(); return nr; diff --git a/kernel/power/console.c b/kernel/power/console.c index a906a0ac0f9b..33ace63b1088 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -58,7 +58,7 @@ int pm_vt_switch_required(struct device *dev, bool required) } } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { ret = -ENOMEM; goto out; diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 5b055cbe5341..e610cf8e9a06 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -439,7 +439,7 @@ static int em_create_pd(struct device *dev, int nr_states, cpumask_copy(em_span_cpus(pd), cpus); } else { - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return -ENOMEM; } diff --git a/kernel/power/qos.c b/kernel/power/qos.c index f7d8064e9adc..398b994b73aa 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -341,7 +341,7 @@ static int cpu_latency_qos_open(struct inode *inode, struct file *filp) { struct pm_qos_request *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; @@ -440,7 +440,7 @@ static int cpu_wakeup_latency_qos_open(struct inode *inode, struct file *filp) { struct pm_qos_request *req; - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) return -ENOMEM; diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 0a946932d5c1..6e1321837c66 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -646,7 +646,7 @@ static int create_mem_extents(struct list_head *list, gfp_t gfp_mask) /* New extent is necessary */ struct mem_extent *new_ext; - new_ext = kzalloc(sizeof(struct mem_extent), gfp_mask); + new_ext = kzalloc_obj(struct mem_extent, gfp_mask); if (!new_ext) { free_mem_extents(list); return -ENOMEM; @@ -1124,7 +1124,7 @@ int create_basic_memory_bitmaps(void) else BUG_ON(forbidden_pages_map || free_pages_map); - bm1 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL); + bm1 = kzalloc_obj(struct memory_bitmap); if (!bm1) return -ENOMEM; @@ -1132,7 +1132,7 @@ int create_basic_memory_bitmaps(void) if (error) goto Free_first_object; - bm2 = kzalloc(sizeof(struct memory_bitmap), GFP_KERNEL); + bm2 = kzalloc_obj(struct memory_bitmap); if (!bm2) goto Free_first_bitmap; diff --git a/kernel/power/swap.c b/kernel/power/swap.c index c4eb284b8e72..2e64869bb5a0 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -155,7 +155,7 @@ static int swsusp_extents_insert(unsigned long swap_offset) } } /* Add the new node and rebalance the tree. */ - ext = kzalloc(sizeof(struct swsusp_extent), GFP_KERNEL); + ext = kzalloc_obj(struct swsusp_extent); if (!ext) return -ENOMEM; @@ -577,7 +577,7 @@ static struct crc_data *alloc_crc_data(int nr_threads) { struct crc_data *crc; - crc = kzalloc(sizeof(*crc), GFP_KERNEL); + crc = kzalloc_obj(*crc); if (!crc) return NULL; @@ -585,7 +585,7 @@ static struct crc_data *alloc_crc_data(int nr_threads) if (!crc->unc) goto err_free_crc; - crc->unc_len = kcalloc(nr_threads, sizeof(*crc->unc_len), GFP_KERNEL); + crc->unc_len = kzalloc_objs(*crc->unc_len, nr_threads); if (!crc->unc_len) goto err_free_unc; @@ -1016,7 +1016,7 @@ static int get_swap_reader(struct swap_map_handle *handle, last = handle->maps = NULL; offset = swsusp_header->image; while (offset) { - tmp = kzalloc(sizeof(*handle->maps), GFP_KERNEL); + tmp = kzalloc_obj(*handle->maps); if (!tmp) { release_swap_reader(handle); return -ENOMEM; diff --git a/kernel/power/wakelock.c b/kernel/power/wakelock.c index 4e941999a53b..fd763da06a87 100644 --- a/kernel/power/wakelock.c +++ b/kernel/power/wakelock.c @@ -178,7 +178,7 @@ static struct wakelock *wakelock_lookup_add(const char *name, size_t len, return ERR_PTR(-ENOSPC); /* Not found, we have to add a new one. */ - wl = kzalloc(sizeof(*wl), GFP_KERNEL); + wl = kzalloc_obj(*wl); if (!wl) return ERR_PTR(-ENOMEM); diff --git a/kernel/printk/internal.h b/kernel/printk/internal.h index 5fdea5682756..85fbf1801cbe 100644 --- a/kernel/printk/internal.h +++ b/kernel/printk/internal.h @@ -4,9 +4,9 @@ */ #include #include +#include #if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL) -struct ctl_table; void __init printk_sysctl_init(void); int devkmsg_sysctl_set_loglvl(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos); diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c index d558b18505cd..d7044a7a214b 100644 --- a/kernel/printk/nbcon.c +++ b/kernel/printk/nbcon.c @@ -1801,7 +1801,7 @@ bool nbcon_alloc(struct console *con) */ con->pbufs = &printk_shared_pbufs; } else { - con->pbufs = kmalloc(sizeof(*con->pbufs), GFP_KERNEL); + con->pbufs = kmalloc_obj(*con->pbufs); if (!con->pbufs) { con_printk(KERN_ERR, con, "failed to allocate printing buffer\n"); return false; diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 4ddeb55e1207..0323149548f6 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -933,7 +933,7 @@ static int devkmsg_open(struct inode *inode, struct file *file) return err; } - user = kvmalloc(sizeof(struct devkmsg_user), GFP_KERNEL); + user = kvmalloc_obj(struct devkmsg_user); if (!user) return -ENOMEM; @@ -3416,22 +3416,6 @@ void console_unlock(void) } EXPORT_SYMBOL(console_unlock); -/** - * console_conditional_schedule - yield the CPU if required - * - * If the console code is currently allowed to sleep, and - * if this CPU should yield the CPU to another task, do - * so here. - * - * Must be called within console_lock();. - */ -void __sched console_conditional_schedule(void) -{ - if (console_may_schedule) - cond_resched(); -} -EXPORT_SYMBOL(console_conditional_schedule); - void console_unblank(void) { bool found_unblank = false; diff --git a/kernel/printk/sysctl.c b/kernel/printk/sysctl.c index da77f3f5c1fe..f15732e93c2e 100644 --- a/kernel/printk/sysctl.c +++ b/kernel/printk/sysctl.c @@ -3,7 +3,6 @@ * sysctl.c: General linux system control interface */ -#include #include #include #include diff --git a/kernel/rcu/rcuscale.c b/kernel/rcu/rcuscale.c index 1c50f89fbd6f..4ac2b134a983 100644 --- a/kernel/rcu/rcuscale.c +++ b/kernel/rcu/rcuscale.c @@ -755,7 +755,7 @@ kfree_scale_thread(void *arg) } for (i = 0; i < kfree_alloc_num; i++) { - alloc_ptr = kcalloc(kfree_mult, sizeof(struct kfree_obj), GFP_KERNEL); + alloc_ptr = kzalloc_objs(struct kfree_obj, kfree_mult); if (!alloc_ptr) return -ENOMEM; @@ -908,8 +908,8 @@ kfree_scale_init(void) kfree_mult * sizeof(struct kfree_obj), kfree_by_call_rcu); - kfree_reader_tasks = kcalloc(kfree_nrealthreads, sizeof(kfree_reader_tasks[0]), - GFP_KERNEL); + kfree_reader_tasks = kzalloc_objs(kfree_reader_tasks[0], + kfree_nrealthreads); if (kfree_reader_tasks == NULL) { firsterr = -ENOMEM; goto unwind; @@ -1129,8 +1129,7 @@ rcu_scale_init(void) goto unwind; schedule_timeout_uninterruptible(1); } - reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]), - GFP_KERNEL); + reader_tasks = kzalloc_objs(reader_tasks[0], nrealreaders); if (reader_tasks == NULL) { SCALEOUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; @@ -1144,10 +1143,10 @@ rcu_scale_init(void) } while (atomic_read(&n_rcu_scale_reader_started) < nrealreaders) schedule_timeout_uninterruptible(1); - writer_tasks = kcalloc(nrealwriters, sizeof(writer_tasks[0]), GFP_KERNEL); + writer_tasks = kzalloc_objs(writer_tasks[0], nrealwriters); writer_durations = kcalloc(nrealwriters, sizeof(*writer_durations), GFP_KERNEL); - writer_n_durations = kcalloc(nrealwriters, sizeof(*writer_n_durations), GFP_KERNEL); - writer_done = kcalloc(nrealwriters, sizeof(writer_done[0]), GFP_KERNEL); + writer_n_durations = kzalloc_objs(*writer_n_durations, nrealwriters); + writer_done = kzalloc_objs(writer_done[0], nrealwriters); if (gp_async) { if (gp_async_max <= 0) { pr_warn("%s: gp_async_max = %d must be greater than zero.\n", @@ -1156,7 +1155,8 @@ rcu_scale_init(void) firsterr = -EINVAL; goto unwind; } - writer_freelists = kcalloc(nrealwriters, sizeof(writer_freelists[0]), GFP_KERNEL); + writer_freelists = kzalloc_objs(writer_freelists[0], + nrealwriters); } if (!writer_tasks || !writer_durations || !writer_n_durations || !writer_done || (gp_async && !writer_freelists)) { @@ -1177,8 +1177,8 @@ rcu_scale_init(void) init_llist_head(&wflp->ws_lhg); init_llist_head(&wflp->ws_lhp); - wflp->ws_mblocks = kcalloc(gp_async_max, sizeof(wflp->ws_mblocks[0]), - GFP_KERNEL); + wflp->ws_mblocks = kzalloc_objs(wflp->ws_mblocks[0], + gp_async_max); if (!wflp->ws_mblocks) { firsterr = -ENOMEM; goto unwind; diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c index 47ce7f49b52c..8a9282a0245c 100644 --- a/kernel/rcu/rcutorture.c +++ b/kernel/rcu/rcutorture.c @@ -1626,7 +1626,7 @@ rcu_torture_writer(void *arg) ulo_size = cur_ops->poll_active; } if (cur_ops->poll_active_full > 0) { - rgo = kcalloc(cur_ops->poll_active_full, sizeof(*rgo), GFP_KERNEL); + rgo = kzalloc_objs(*rgo, cur_ops->poll_active_full); if (!WARN_ON(!rgo)) rgo_size = cur_ops->poll_active_full; } @@ -2462,7 +2462,7 @@ static void rcu_torture_timer(struct timer_list *unused) /* Test call_rcu() invocation from interrupt handler. */ if (cur_ops->call) { - struct rcu_head *rhp = kmalloc(sizeof(*rhp), GFP_NOWAIT); + struct rcu_head *rhp = kmalloc_obj(*rhp, GFP_NOWAIT); if (rhp) cur_ops->call(rhp, rcu_torture_timer_cb); @@ -2558,7 +2558,7 @@ static int rcu_torture_updown_init(void) VERBOSE_TOROUT_STRING("rcu_torture_updown_init: Disabling up/down reader tests due to lack of primitives"); return 0; } - updownreaders = kcalloc(n_up_down, sizeof(*updownreaders), GFP_KERNEL); + updownreaders = kzalloc_objs(*updownreaders, n_up_down); if (!updownreaders) { VERBOSE_TOROUT_STRING("rcu_torture_updown_init: Out of memory, disabling up/down reader tests"); return -ENOMEM; @@ -2891,7 +2891,7 @@ static void rcu_torture_mem_dump_obj(void) mem_dump_obj(&z); kmem_cache_free(kcp, rhp); kmem_cache_destroy(kcp); - rhp = kmalloc(sizeof(*rhp), GFP_KERNEL); + rhp = kmalloc_obj(*rhp); if (WARN_ON_ONCE(!rhp)) return; pr_alert("mem_dump_obj() kmalloc test: rcu_torture_stats = %px, &rhp = %px, rhp = %px\n", stats_task, &rhp, rhp); @@ -3399,7 +3399,7 @@ static void rcu_torture_fwd_prog_cr(struct rcu_fwd *rfp) n_launders++; n_launders_sa++; } else if (!cur_ops->cbflood_max || cur_ops->cbflood_max > n_max_cbs) { - rfcp = kmalloc(sizeof(*rfcp), GFP_KERNEL); + rfcp = kmalloc_obj(*rfcp); if (WARN_ON_ONCE(!rfcp)) { schedule_timeout_interruptible(1); continue; @@ -3587,8 +3587,8 @@ static int __init rcu_torture_fwd_prog_init(void) fwd_progress_holdoff = 1; if (fwd_progress_div <= 0) fwd_progress_div = 4; - rfp = kcalloc(fwd_progress, sizeof(*rfp), GFP_KERNEL); - fwd_prog_tasks = kcalloc(fwd_progress, sizeof(*fwd_prog_tasks), GFP_KERNEL); + rfp = kzalloc_objs(*rfp, fwd_progress); + fwd_prog_tasks = kzalloc_objs(*fwd_prog_tasks, fwd_progress); if (!rfp || !fwd_prog_tasks) { kfree(rfp); kfree(fwd_prog_tasks); @@ -3754,10 +3754,9 @@ static int rcu_torture_barrier_init(void) atomic_set(&barrier_cbs_count, 0); atomic_set(&barrier_cbs_invoked, 0); barrier_cbs_tasks = - kcalloc(n_barrier_cbs, sizeof(barrier_cbs_tasks[0]), - GFP_KERNEL); + kzalloc_objs(barrier_cbs_tasks[0], n_barrier_cbs); barrier_cbs_wq = - kcalloc(n_barrier_cbs, sizeof(barrier_cbs_wq[0]), GFP_KERNEL); + kzalloc_objs(barrier_cbs_wq[0], n_barrier_cbs); if (barrier_cbs_tasks == NULL || !barrier_cbs_wq) return -ENOMEM; for (i = 0; i < n_barrier_cbs; i++) { @@ -4224,7 +4223,7 @@ static void rcu_test_debug_objects(void) (!cur_ops->call || !cur_ops->cb_barrier))) return; - struct rcu_head *rhp = kmalloc(sizeof(*rhp), GFP_KERNEL); + struct rcu_head *rhp = kmalloc_obj(*rhp); init_rcu_head_on_stack(&rh1); init_rcu_head_on_stack(&rh2); @@ -4549,9 +4548,8 @@ rcu_torture_init(void) rcu_torture_write_types(); if (nrealfakewriters > 0) { - fakewriter_tasks = kcalloc(nrealfakewriters, - sizeof(fakewriter_tasks[0]), - GFP_KERNEL); + fakewriter_tasks = kzalloc_objs(fakewriter_tasks[0], + nrealfakewriters); if (fakewriter_tasks == NULL) { TOROUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; @@ -4564,10 +4562,9 @@ rcu_torture_init(void) if (torture_init_error(firsterr)) goto unwind; } - reader_tasks = kcalloc(nrealreaders, sizeof(reader_tasks[0]), - GFP_KERNEL); - rcu_torture_reader_mbchk = kcalloc(nrealreaders, sizeof(*rcu_torture_reader_mbchk), - GFP_KERNEL); + reader_tasks = kzalloc_objs(reader_tasks[0], nrealreaders); + rcu_torture_reader_mbchk = kzalloc_objs(*rcu_torture_reader_mbchk, + nrealreaders); if (!reader_tasks || !rcu_torture_reader_mbchk) { TOROUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; @@ -4595,7 +4592,7 @@ rcu_torture_init(void) if (WARN_ON(nocbs_toggle < 0)) nocbs_toggle = HZ; if (nrealnocbers > 0) { - nocb_tasks = kcalloc(nrealnocbers, sizeof(nocb_tasks[0]), GFP_KERNEL); + nocb_tasks = kzalloc_objs(nocb_tasks[0], nrealnocbers); if (nocb_tasks == NULL) { TOROUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; diff --git a/kernel/rcu/refscale.c b/kernel/rcu/refscale.c index 07a313782dfd..c158b6a947cd 100644 --- a/kernel/rcu/refscale.c +++ b/kernel/rcu/refscale.c @@ -1143,7 +1143,7 @@ static bool typesafe_init(void) else if (si == 0) si = nr_cpu_ids; rtsarray_size = si; - rtsarray = kcalloc(si, sizeof(*rtsarray), GFP_KERNEL); + rtsarray = kzalloc_objs(*rtsarray, si); if (!rtsarray) return false; for (idx = 0; idx < rtsarray_size; idx++) { @@ -1575,8 +1575,7 @@ ref_scale_init(void) "%s: nreaders * loops will overflow, adjusted loops to %d", __func__, INT_MAX / nreaders)) loops = INT_MAX / nreaders; - reader_tasks = kcalloc(nreaders, sizeof(reader_tasks[0]), - GFP_KERNEL); + reader_tasks = kzalloc_objs(reader_tasks[0], nreaders); if (!reader_tasks) { SCALEOUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; diff --git a/kernel/rcu/srcutree.c b/kernel/rcu/srcutree.c index c469c708fdd6..aef8e91ad33e 100644 --- a/kernel/rcu/srcutree.c +++ b/kernel/rcu/srcutree.c @@ -173,7 +173,8 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags) /* Initialize geometry if it has not already been initialized. */ rcu_init_geometry(); - ssp->srcu_sup->node = kcalloc(rcu_num_nodes, sizeof(*ssp->srcu_sup->node), gfp_flags); + ssp->srcu_sup->node = kzalloc_objs(*ssp->srcu_sup->node, rcu_num_nodes, + gfp_flags); if (!ssp->srcu_sup->node) return false; @@ -237,7 +238,7 @@ static bool init_srcu_struct_nodes(struct srcu_struct *ssp, gfp_t gfp_flags) static int init_srcu_struct_fields(struct srcu_struct *ssp, bool is_static) { if (!is_static) - ssp->srcu_sup = kzalloc(sizeof(*ssp->srcu_sup), GFP_KERNEL); + ssp->srcu_sup = kzalloc_obj(*ssp->srcu_sup); if (!ssp->srcu_sup) return -ENOMEM; if (!is_static) @@ -789,7 +790,8 @@ void __srcu_check_read_flavor(struct srcu_struct *ssp, int read_flavor) struct srcu_data *sdp; /* NMI-unsafe use in NMI is a bad sign, as is multi-bit read_flavor values. */ - WARN_ON_ONCE((read_flavor != SRCU_READ_FLAVOR_NMI) && in_nmi()); + WARN_ON_ONCE(read_flavor != SRCU_READ_FLAVOR_NMI && + read_flavor != SRCU_READ_FLAVOR_FAST && in_nmi()); WARN_ON_ONCE(read_flavor & (read_flavor - 1)); sdp = raw_cpu_ptr(ssp->sda); diff --git a/kernel/rcu/tasks.h b/kernel/rcu/tasks.h index 76f952196a29..2b55e6acf3c1 100644 --- a/kernel/rcu/tasks.h +++ b/kernel/rcu/tasks.h @@ -259,7 +259,8 @@ static void cblist_init_generic(struct rcu_tasks *rtp) } lim = rcu_task_enqueue_lim; - rtp->rtpcp_array = kcalloc(num_possible_cpus(), sizeof(struct rcu_tasks_percpu *), GFP_KERNEL); + rtp->rtpcp_array = kzalloc_objs(struct rcu_tasks_percpu *, + num_possible_cpus()); BUG_ON(!rtp->rtpcp_array); for_each_possible_cpu(cpu) { diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index dfeba9b35395..d98a5c38e19c 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -614,7 +614,7 @@ static void early_boot_test_call_rcu(void) call_rcu(&head, test_callback); early_srcu_cookie = start_poll_synchronize_srcu(&early_srcu); call_srcu(&early_srcu, &shead, test_callback); - rhp = kmalloc(sizeof(*rhp), GFP_KERNEL); + rhp = kmalloc_obj(*rhp); if (!WARN_ON_ONCE(!rhp)) kfree_rcu(rhp, rh); } diff --git a/kernel/reboot.c b/kernel/reboot.c index ec087827c85c..695c33e75efd 100644 --- a/kernel/reboot.c +++ b/kernel/reboot.c @@ -374,7 +374,7 @@ static struct sys_off_handler *alloc_sys_off_handler(int priority) else flags = GFP_KERNEL; - handler = kzalloc(sizeof(*handler), flags); + handler = kzalloc_obj(*handler, flags); if (!handler) return ERR_PTR(-ENOMEM); } diff --git a/kernel/relay.c b/kernel/relay.c index e36f6b926f7f..62b059ff2759 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Public API and common code for kernel->userspace relay file support. * @@ -9,8 +10,6 @@ * Moved to kernel/relay.c by Paul Mundt, 2006. * November 2006 - CPU hotplug support by Mathieu Desnoyers * (mathieu.desnoyers@polymtl.ca) - * - * This file is released under the GPL. */ #include #include @@ -60,7 +59,7 @@ static const struct vm_operations_struct relay_file_mmap_ops = { */ static struct page **relay_alloc_page_array(unsigned int n_pages) { - return kvcalloc(n_pages, sizeof(struct page *), GFP_KERNEL); + return kvzalloc_objs(struct page *, n_pages); } /* @@ -92,7 +91,7 @@ static int relay_mmap_prepare_buf(struct rchan_buf *buf, return -EINVAL; desc->vm_ops = &relay_file_mmap_ops; - desc->vm_flags |= VM_DONTEXPAND; + vma_desc_set_flags(desc, VMA_DONTEXPAND_BIT); desc->private_data = buf; return 0; @@ -151,11 +150,10 @@ static struct rchan_buf *relay_create_buf(struct rchan *chan) if (chan->n_subbufs > KMALLOC_MAX_SIZE / sizeof(size_t)) return NULL; - buf = kzalloc(sizeof(struct rchan_buf), GFP_KERNEL); + buf = kzalloc_obj(struct rchan_buf); if (!buf) return NULL; - buf->padding = kmalloc_array(chan->n_subbufs, sizeof(size_t), - GFP_KERNEL); + buf->padding = kmalloc_objs(size_t, chan->n_subbufs); if (!buf->padding) goto free_buf; @@ -491,7 +489,7 @@ struct rchan *relay_open(const char *base_filename, if (!cb || !cb->create_buf_file || !cb->remove_buf_file) return NULL; - chan = kzalloc(sizeof(struct rchan), GFP_KERNEL); + chan = kzalloc_obj(struct rchan); if (!chan) return NULL; diff --git a/kernel/resource.c b/kernel/resource.c index 31341bdd7707..bb966699da31 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -182,7 +182,7 @@ static void free_resource(struct resource *res) static struct resource *alloc_resource(gfp_t flags) { - return kzalloc(sizeof(struct resource), flags); + return kzalloc_obj(struct resource, flags); } /* Return the conflict entry if you can't request it */ @@ -502,7 +502,7 @@ int walk_system_ram_res_rev(u64 start, u64 end, void *arg, int ret = -1; /* create a list */ - rams = kvcalloc(rams_size, sizeof(struct resource), GFP_KERNEL); + rams = kvzalloc_objs(struct resource, rams_size); if (!rams) return ret; diff --git a/kernel/resource_kunit.c b/kernel/resource_kunit.c index b8ef75b99eb2..42785796f1db 100644 --- a/kernel/resource_kunit.c +++ b/kernel/resource_kunit.c @@ -204,7 +204,7 @@ static void resource_test_insert_resource(struct kunit *test, struct resource *p { struct resource *res; - res = kzalloc(sizeof(*res), GFP_KERNEL); + res = kzalloc_obj(*res); KUNIT_ASSERT_NOT_NULL(test, res); res->name = name; diff --git a/kernel/rseq.c b/kernel/rseq.c index b0973d19f366..38d3ef540760 100644 --- a/kernel/rseq.c +++ b/kernel/rseq.c @@ -80,6 +80,7 @@ #include #include #include +#include #include #define CREATE_TRACE_POINTS @@ -449,13 +450,14 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len, int, flags, u32 * auxiliary vector AT_RSEQ_ALIGN. If rseq_len is the original rseq * size, the required alignment is the original struct rseq alignment. * - * In order to be valid, rseq_len is either the original rseq size, or - * large enough to contain all supported fields, as communicated to + * The rseq_len is required to be greater or equal to the original rseq + * size. In order to be valid, rseq_len is either the original rseq size, + * or large enough to contain all supported fields, as communicated to * user-space through the ELF auxiliary vector AT_RSEQ_FEATURE_SIZE. */ if (rseq_len < ORIG_RSEQ_SIZE || (rseq_len == ORIG_RSEQ_SIZE && !IS_ALIGNED((unsigned long)rseq, ORIG_RSEQ_SIZE)) || - (rseq_len != ORIG_RSEQ_SIZE && (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) || + (rseq_len != ORIG_RSEQ_SIZE && (!IS_ALIGNED((unsigned long)rseq, rseq_alloc_align()) || rseq_len < offsetof(struct rseq, end)))) return -EINVAL; if (!access_ok(rseq, rseq_len)) diff --git a/kernel/scftorture.c b/kernel/scftorture.c index d86d2d9c4624..327c315f411c 100644 --- a/kernel/scftorture.c +++ b/kernel/scftorture.c @@ -350,7 +350,7 @@ static void scftorture_invoke_one(struct scf_statistics *scfp, struct torture_ra struct scf_selector *scfsp = scf_sel_rand(trsp); if (scfsp->scfs_prim == SCF_PRIM_SINGLE || scfsp->scfs_wait) { - scfcp = kmalloc(sizeof(*scfcp), GFP_ATOMIC); + scfcp = kmalloc_obj(*scfcp, GFP_ATOMIC); if (!scfcp) { WARN_ON_ONCE(!IS_ENABLED(CONFIG_KASAN)); atomic_inc(&n_alloc_errs); @@ -661,7 +661,7 @@ static int __init scf_torture_init(void) // Worker tasks invoking smp_call_function(). if (nthreads < 0) nthreads = num_online_cpus(); - scf_stats_p = kcalloc(nthreads, sizeof(scf_stats_p[0]), GFP_KERNEL); + scf_stats_p = kzalloc_objs(scf_stats_p[0], nthreads); if (!scf_stats_p) { SCFTORTOUT_ERRSTRING("out of memory"); firsterr = -ENOMEM; diff --git a/kernel/sched/autogroup.c b/kernel/sched/autogroup.c index 954137775f38..e380cf9372bb 100644 --- a/kernel/sched/autogroup.c +++ b/kernel/sched/autogroup.c @@ -86,7 +86,7 @@ static inline struct autogroup *autogroup_task_get(struct task_struct *p) static inline struct autogroup *autogroup_create(void) { - struct autogroup *ag = kzalloc(sizeof(*ag), GFP_KERNEL); + struct autogroup *ag = kzalloc_obj(*ag); struct task_group *tg; if (!ag) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 759777694c78..496dff740dca 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -4729,8 +4729,11 @@ void sched_cancel_fork(struct task_struct *p) scx_cancel_fork(p); } +static void sched_mm_cid_fork(struct task_struct *t); + void sched_post_fork(struct task_struct *p) { + sched_mm_cid_fork(p); uclamp_post_fork(p); scx_post_fork(p); } @@ -6830,6 +6833,7 @@ static void __sched notrace __schedule(int sched_mode) /* SCX must consult the BPF scheduler to tell if rq is empty */ if (!rq->nr_running && !scx_enabled()) { next = prev; + rq->next_class = &idle_sched_class; goto picked; } } else if (!preempt && prev_state) { @@ -10616,13 +10620,10 @@ static inline void mm_cid_transit_to_cpu(struct task_struct *t, struct mm_cid_pc } } -static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm) +static void mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm) { /* Remote access to mm::mm_cid::pcpu requires rq_lock */ guard(task_rq_lock)(t); - /* If the task is not active it is not in the users count */ - if (!t->mm_cid.active) - return false; if (cid_on_task(t->mm_cid.cid)) { /* If running on the CPU, put the CID in transit mode, otherwise drop it */ if (task_rq(t)->curr == t) @@ -10630,69 +10631,43 @@ static bool mm_cid_fixup_task_to_cpu(struct task_struct *t, struct mm_struct *mm else mm_unset_cid_on_task(t); } - return true; -} - -static void mm_cid_do_fixup_tasks_to_cpus(struct mm_struct *mm) -{ - struct task_struct *p, *t; - unsigned int users; - - /* - * This can obviously race with a concurrent affinity change, which - * increases the number of allowed CPUs for this mm, but that does - * not affect the mode and only changes the CID constraints. A - * possible switch back to per task mode happens either in the - * deferred handler function or in the next fork()/exit(). - * - * The caller has already transferred. The newly incoming task is - * already accounted for, but not yet visible. - */ - users = mm->mm_cid.users - 2; - if (!users) - return; - - guard(rcu)(); - for_other_threads(current, t) { - if (mm_cid_fixup_task_to_cpu(t, mm)) - users--; - } - - if (!users) - return; - - /* Happens only for VM_CLONE processes. */ - for_each_process_thread(p, t) { - if (t == current || t->mm != mm) - continue; - if (mm_cid_fixup_task_to_cpu(t, mm)) { - if (--users == 0) - return; - } - } } static void mm_cid_fixup_tasks_to_cpus(void) { struct mm_struct *mm = current->mm; + struct task_struct *t; + + lockdep_assert_held(&mm->mm_cid.mutex); + + hlist_for_each_entry(t, &mm->mm_cid.user_list, mm_cid.node) { + /* Current has already transferred before invoking the fixup. */ + if (t != current) + mm_cid_fixup_task_to_cpu(t, mm); + } - mm_cid_do_fixup_tasks_to_cpus(mm); mm_cid_complete_transit(mm, MM_CID_ONCPU); } static bool sched_mm_cid_add_user(struct task_struct *t, struct mm_struct *mm) { + lockdep_assert_held(&mm->mm_cid.lock); + t->mm_cid.active = 1; + hlist_add_head(&t->mm_cid.node, &mm->mm_cid.user_list); mm->mm_cid.users++; return mm_update_max_cids(mm); } -void sched_mm_cid_fork(struct task_struct *t) +static void sched_mm_cid_fork(struct task_struct *t) { struct mm_struct *mm = t->mm; bool percpu; - WARN_ON_ONCE(!mm || t->mm_cid.cid != MM_CID_UNSET); + if (!mm) + return; + + WARN_ON_ONCE(t->mm_cid.cid != MM_CID_UNSET); guard(mutex)(&mm->mm_cid.mutex); scoped_guard(raw_spinlock_irq, &mm->mm_cid.lock) { @@ -10731,12 +10706,13 @@ void sched_mm_cid_fork(struct task_struct *t) static bool sched_mm_cid_remove_user(struct task_struct *t) { + lockdep_assert_held(&t->mm->mm_cid.lock); + t->mm_cid.active = 0; - scoped_guard(preempt) { - /* Clear the transition bit */ - t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid); - mm_unset_cid_on_task(t); - } + /* Clear the transition bit */ + t->mm_cid.cid = cid_from_transit_cid(t->mm_cid.cid); + mm_unset_cid_on_task(t); + hlist_del_init(&t->mm_cid.node); t->mm->mm_cid.users--; return mm_update_max_cids(t->mm); } @@ -10879,11 +10855,13 @@ void mm_init_cid(struct mm_struct *mm, struct task_struct *p) mutex_init(&mm->mm_cid.mutex); mm->mm_cid.irq_work = IRQ_WORK_INIT_HARD(mm_cid_irq_work); INIT_WORK(&mm->mm_cid.work, mm_cid_work_fn); + INIT_HLIST_HEAD(&mm->mm_cid.user_list); cpumask_copy(mm_cpus_allowed(mm), &p->cpus_mask); bitmap_zero(mm_cidmask(mm), num_possible_cpus()); } #else /* CONFIG_SCHED_MM_CID */ static inline void mm_update_cpus_allowed(struct mm_struct *mm, const struct cpumask *affmsk) { } +static inline void sched_mm_cid_fork(struct task_struct *t) { } #endif /* !CONFIG_SCHED_MM_CID */ static DEFINE_PER_CPU(struct sched_change_ctx, sched_change_ctx); diff --git a/kernel/sched/core_sched.c b/kernel/sched/core_sched.c index 9ede71ecba7f..73b6b2426911 100644 --- a/kernel/sched/core_sched.c +++ b/kernel/sched/core_sched.c @@ -12,7 +12,7 @@ struct sched_core_cookie { static unsigned long sched_core_alloc_cookie(void) { - struct sched_core_cookie *ck = kmalloc(sizeof(*ck), GFP_KERNEL); + struct sched_core_cookie *ck = kmalloc_obj(*ck); if (!ck) return 0; diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c index 23a56ba12d81..ca9d52cb1ebb 100644 --- a/kernel/sched/cpuacct.c +++ b/kernel/sched/cpuacct.c @@ -61,7 +61,7 @@ cpuacct_css_alloc(struct cgroup_subsys_state *parent_css) if (!parent_css) return &root_cpuacct.css; - ca = kzalloc(sizeof(*ca), GFP_KERNEL); + ca = kzalloc_obj(*ca); if (!ca) goto out; diff --git a/kernel/sched/cpudeadline.c b/kernel/sched/cpudeadline.c index 37b572cc8aca..0a2b7e30fd10 100644 --- a/kernel/sched/cpudeadline.c +++ b/kernel/sched/cpudeadline.c @@ -252,9 +252,7 @@ int cpudl_init(struct cpudl *cp) raw_spin_lock_init(&cp->lock); cp->size = 0; - cp->elements = kcalloc(nr_cpu_ids, - sizeof(struct cpudl_item), - GFP_KERNEL); + cp->elements = kzalloc_objs(struct cpudl_item, nr_cpu_ids); if (!cp->elements) return -ENOMEM; diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index cfc40181f66e..153232dd8276 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c @@ -638,7 +638,7 @@ static struct sugov_policy *sugov_policy_alloc(struct cpufreq_policy *policy) { struct sugov_policy *sg_policy; - sg_policy = kzalloc(sizeof(*sg_policy), GFP_KERNEL); + sg_policy = kzalloc_obj(*sg_policy); if (!sg_policy) return NULL; @@ -722,7 +722,7 @@ static struct sugov_tunables *sugov_tunables_alloc(struct sugov_policy *sg_polic { struct sugov_tunables *tunables; - tunables = kzalloc(sizeof(*tunables), GFP_KERNEL); + tunables = kzalloc_obj(*tunables); if (tunables) { gov_attr_set_init(&tunables->attr_set, &sg_policy->tunables_hook); if (!have_governor_per_policy()) diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c index 76a9ac5eb794..8f2237e8b484 100644 --- a/kernel/sched/cpupri.c +++ b/kernel/sched/cpupri.c @@ -288,7 +288,7 @@ int cpupri_init(struct cpupri *cp) goto cleanup; } - cp->cpu_to_pri = kcalloc(nr_cpu_ids, sizeof(int), GFP_KERNEL); + cp->cpu_to_pri = kzalloc_objs(int, nr_cpu_ids); if (!cp->cpu_to_pri) goto cleanup; diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index c18e81e8ef51..26a6ac2f8826 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -976,8 +976,12 @@ static bool scx_dsq_priq_less(struct rb_node *node_a, static void dsq_mod_nr(struct scx_dispatch_q *dsq, s32 delta) { - /* scx_bpf_dsq_nr_queued() reads ->nr without locking, use WRITE_ONCE() */ - WRITE_ONCE(dsq->nr, dsq->nr + delta); + /* + * scx_bpf_dsq_nr_queued() reads ->nr without locking. Use READ_ONCE() + * on the read side and WRITE_ONCE() on the write side to properly + * annotate the concurrent lockless access and avoid KCSAN warnings. + */ + WRITE_ONCE(dsq->nr, READ_ONCE(dsq->nr) + delta); } static void refill_task_slice_dfl(struct scx_sched *sch, struct task_struct *p) @@ -1099,7 +1103,7 @@ static void dispatch_enqueue(struct scx_sched *sch, struct scx_dispatch_q *dsq, } /* seq records the order tasks are queued, used by BPF DSQ iterator */ - dsq->seq++; + WRITE_ONCE(dsq->seq, dsq->seq + 1); p->scx.dsq_seq = dsq->seq; dsq_mod_nr(dsq, 1); @@ -1466,16 +1470,15 @@ static void clr_task_runnable(struct task_struct *p, bool reset_runnable_at) p->scx.flags |= SCX_TASK_RESET_RUNNABLE_AT; } -static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int enq_flags) +static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int core_enq_flags) { struct scx_sched *sch = scx_root; int sticky_cpu = p->scx.sticky_cpu; + u64 enq_flags = core_enq_flags | rq->scx.extra_enq_flags; if (enq_flags & ENQUEUE_WAKEUP) rq->scx.flags |= SCX_RQ_IN_WAKEUP; - enq_flags |= rq->scx.extra_enq_flags; - if (sticky_cpu >= 0) p->scx.sticky_cpu = -1; @@ -2460,7 +2463,7 @@ do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) /* see kick_cpus_irq_workfn() */ smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); - rq->next_class = &ext_sched_class; + rq_modified_begin(rq, &ext_sched_class); rq_unpin_lock(rq, rf); balance_one(rq, prev); @@ -2475,7 +2478,7 @@ do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) * If @force_scx is true, always try to pick a SCHED_EXT task, * regardless of any higher-priority sched classes activity. */ - if (!force_scx && sched_class_above(rq->next_class, &ext_sched_class)) + if (!force_scx && rq_modified_above(rq, &ext_sched_class)) return RETRY_TASK; keep_prev = rq->scx.flags & SCX_RQ_BAL_KEEP; @@ -2735,7 +2738,7 @@ static bool check_rq_for_timeouts(struct rq *rq) unsigned long last_runnable = p->scx.runnable_at; if (unlikely(time_after(jiffies, - last_runnable + scx_watchdog_timeout))) { + last_runnable + READ_ONCE(scx_watchdog_timeout)))) { u32 dur_ms = jiffies_to_msecs(jiffies - last_runnable); scx_exit(sch, SCX_EXIT_ERROR_STALL, 0, @@ -2763,7 +2766,7 @@ static void scx_watchdog_workfn(struct work_struct *work) cond_resched(); } queue_delayed_work(system_unbound_wq, to_delayed_work(work), - scx_watchdog_timeout / 2); + READ_ONCE(scx_watchdog_timeout) / 2); } void scx_tick(struct rq *rq) @@ -3585,7 +3588,6 @@ static int scx_cgroup_init(struct scx_sched *sch) ret = SCX_CALL_OP_RET(sch, SCX_KF_UNLOCKED, cgroup_init, NULL, css->cgroup, &args); if (ret) { - css_put(css); scx_error(sch, "ops.cgroup_init() failed (%d)", ret); return ret; } @@ -3708,7 +3710,9 @@ static void scx_kobj_release(struct kobject *kobj) static ssize_t scx_attr_ops_show(struct kobject *kobj, struct kobj_attribute *ka, char *buf) { - return sysfs_emit(buf, "%s\n", scx_root->ops.name); + struct scx_sched *sch = container_of(kobj, struct scx_sched, kobj); + + return sysfs_emit(buf, "%s\n", sch->ops.name); } SCX_ATTR(ops); @@ -3752,7 +3756,9 @@ static const struct kobj_type scx_ktype = { static int scx_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) { - return add_uevent_var(env, "SCXOPS=%s", scx_root->ops.name); + const struct scx_sched *sch = container_of(kobj, struct scx_sched, kobj); + + return add_uevent_var(env, "SCXOPS=%s", sch->ops.name); } static const struct kset_uevent_ops scx_uevent_ops = { @@ -3901,8 +3907,8 @@ static u32 bypass_lb_cpu(struct scx_sched *sch, struct rq *rq, * consider offloading iff the total queued duration is over the * threshold. */ - min_delta_us = scx_bypass_lb_intv_us / SCX_BYPASS_LB_MIN_DELTA_DIV; - if (delta < DIV_ROUND_UP(min_delta_us, scx_slice_bypass_us)) + min_delta_us = READ_ONCE(scx_bypass_lb_intv_us) / SCX_BYPASS_LB_MIN_DELTA_DIV; + if (delta < DIV_ROUND_UP(min_delta_us, READ_ONCE(scx_slice_bypass_us))) return 0; raw_spin_rq_lock_irq(rq); @@ -4130,7 +4136,7 @@ static void scx_bypass(bool bypass) WARN_ON_ONCE(scx_bypass_depth <= 0); if (scx_bypass_depth != 1) goto unlock; - WRITE_ONCE(scx_slice_dfl, scx_slice_bypass_us * NSEC_PER_USEC); + WRITE_ONCE(scx_slice_dfl, READ_ONCE(scx_slice_bypass_us) * NSEC_PER_USEC); bypass_timestamp = ktime_get_ns(); if (sch) scx_add_event(sch, SCX_EV_BYPASS_ACTIVATE, 1); @@ -4223,11 +4229,11 @@ static struct scx_exit_info *alloc_exit_info(size_t exit_dump_len) { struct scx_exit_info *ei; - ei = kzalloc(sizeof(*ei), GFP_KERNEL); + ei = kzalloc_obj(*ei); if (!ei) return NULL; - ei->bt = kcalloc(SCX_EXIT_BT_LEN, sizeof(ei->bt[0]), GFP_KERNEL); + ei->bt = kzalloc_objs(ei->bt[0], SCX_EXIT_BT_LEN); ei->msg = kzalloc(SCX_EXIT_MSG_LEN, GFP_KERNEL); ei->dump = kvzalloc(exit_dump_len, GFP_KERNEL); @@ -4423,10 +4429,19 @@ static void scx_disable_workfn(struct kthread_work *work) scx_bypass(false); } +/* + * Claim the exit on @sch. The caller must ensure that the helper kthread work + * is kicked before the current task can be preempted. Once exit_kind is + * claimed, scx_error() can no longer trigger, so if the current task gets + * preempted and the BPF scheduler fails to schedule it back, the helper work + * will never be kicked and the whole system can wedge. + */ static bool scx_claim_exit(struct scx_sched *sch, enum scx_exit_kind kind) { int none = SCX_EXIT_NONE; + lockdep_assert_preemption_disabled(); + if (!atomic_try_cmpxchg(&sch->exit_kind, &none, kind)) return false; @@ -4449,6 +4464,7 @@ static void scx_disable(enum scx_exit_kind kind) rcu_read_lock(); sch = rcu_dereference(scx_root); if (sch) { + guard(preempt)(); scx_claim_exit(sch, kind); kthread_queue_work(sch->helper, &sch->disable_work); } @@ -4771,6 +4787,8 @@ static bool scx_vexit(struct scx_sched *sch, { struct scx_exit_info *ei = sch->exit_info; + guard(preempt)(); + if (!scx_claim_exit(sch, kind)) return false; @@ -4824,7 +4842,7 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops) struct scx_sched *sch; int node, ret; - sch = kzalloc(sizeof(*sch), GFP_KERNEL); + sch = kzalloc_obj(*sch); if (!sch) return ERR_PTR(-ENOMEM); @@ -4838,8 +4856,7 @@ static struct scx_sched *scx_alloc_and_add_sched(struct sched_ext_ops *ops) if (ret < 0) goto err_free_ei; - sch->global_dsqs = kcalloc(nr_node_ids, sizeof(sch->global_dsqs[0]), - GFP_KERNEL); + sch->global_dsqs = kzalloc_objs(sch->global_dsqs[0], nr_node_ids); if (!sch->global_dsqs) { ret = -ENOMEM; goto err_free_hash; @@ -4956,20 +4973,30 @@ static int validate_ops(struct scx_sched *sch, const struct sched_ext_ops *ops) return 0; } -static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) +/* + * scx_enable() is offloaded to a dedicated system-wide RT kthread to avoid + * starvation. During the READY -> ENABLED task switching loop, the calling + * thread's sched_class gets switched from fair to ext. As fair has higher + * priority than ext, the calling thread can be indefinitely starved under + * fair-class saturation, leading to a system hang. + */ +struct scx_enable_cmd { + struct kthread_work work; + struct sched_ext_ops *ops; + int ret; +}; + +static void scx_enable_workfn(struct kthread_work *work) { + struct scx_enable_cmd *cmd = + container_of(work, struct scx_enable_cmd, work); + struct sched_ext_ops *ops = cmd->ops; struct scx_sched *sch; struct scx_task_iter sti; struct task_struct *p; unsigned long timeout; int i, cpu, ret; - if (!cpumask_equal(housekeeping_cpumask(HK_TYPE_DOMAIN), - cpu_possible_mask)) { - pr_err("sched_ext: Not compatible with \"isolcpus=\" domain isolation\n"); - return -EINVAL; - } - mutex_lock(&scx_enable_mutex); if (scx_enable_state() != SCX_DISABLED) { @@ -5061,7 +5088,7 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) WRITE_ONCE(scx_watchdog_timeout, timeout); WRITE_ONCE(scx_watchdog_timestamp, jiffies); queue_delayed_work(system_unbound_wq, &scx_watchdog_work, - scx_watchdog_timeout / 2); + READ_ONCE(scx_watchdog_timeout) / 2); /* * Once __scx_enabled is set, %current can be switched to SCX anytime. @@ -5186,13 +5213,15 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) atomic_long_inc(&scx_enable_seq); - return 0; + cmd->ret = 0; + return; err_free_ksyncs: free_kick_syncs(); err_unlock: mutex_unlock(&scx_enable_mutex); - return ret; + cmd->ret = ret; + return; err_disable_unlock_all: scx_cgroup_unlock(); @@ -5211,7 +5240,42 @@ static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) */ scx_error(sch, "scx_enable() failed (%d)", ret); kthread_flush_work(&sch->disable_work); - return 0; + cmd->ret = 0; +} + +static int scx_enable(struct sched_ext_ops *ops, struct bpf_link *link) +{ + static struct kthread_worker *helper; + static DEFINE_MUTEX(helper_mutex); + struct scx_enable_cmd cmd; + + if (!cpumask_equal(housekeeping_cpumask(HK_TYPE_DOMAIN), + cpu_possible_mask)) { + pr_err("sched_ext: Not compatible with \"isolcpus=\" domain isolation\n"); + return -EINVAL; + } + + if (!READ_ONCE(helper)) { + mutex_lock(&helper_mutex); + if (!helper) { + struct kthread_worker *w = + kthread_run_worker(0, "scx_enable_helper"); + if (IS_ERR_OR_NULL(w)) { + mutex_unlock(&helper_mutex); + return -ENOMEM; + } + sched_set_fifo(w->task); + WRITE_ONCE(helper, w); + } + mutex_unlock(&helper_mutex); + } + + kthread_init_work(&cmd.work, scx_enable_workfn); + cmd.ops = ops; + + kthread_queue_work(READ_ONCE(helper), &cmd.work); + kthread_flush_work(&cmd.work); + return cmd.ret; } diff --git a/kernel/sched/ext_idle.c b/kernel/sched/ext_idle.c index 3d9d404d5cd2..ba298ac3ce6c 100644 --- a/kernel/sched/ext_idle.c +++ b/kernel/sched/ext_idle.c @@ -663,9 +663,8 @@ void scx_idle_init_masks(void) BUG_ON(!alloc_cpumask_var(&scx_idle_global_masks.cpu, GFP_KERNEL)); BUG_ON(!alloc_cpumask_var(&scx_idle_global_masks.smt, GFP_KERNEL)); - /* Allocate per-node idle cpumasks */ - scx_idle_node_masks = kcalloc(num_possible_nodes(), - sizeof(*scx_idle_node_masks), GFP_KERNEL); + /* Allocate per-node idle cpumasks (use nr_node_ids for non-contiguous NUMA nodes) */ + scx_idle_node_masks = kzalloc_objs(*scx_idle_node_masks, nr_node_ids); BUG_ON(!scx_idle_node_masks); for_each_node(i) { diff --git a/kernel/sched/ext_internal.h b/kernel/sched/ext_internal.h index 386c677e4c9a..00b450597f3e 100644 --- a/kernel/sched/ext_internal.h +++ b/kernel/sched/ext_internal.h @@ -74,7 +74,7 @@ enum scx_exit_flags { * info communication. The following flag indicates whether ops.init() * finished successfully. */ - SCX_EFLAG_INITIALIZED, + SCX_EFLAG_INITIALIZED = 1LLU << 0, }; /* @@ -1035,26 +1035,108 @@ static const char *scx_enable_state_str[] = { }; /* - * sched_ext_entity->ops_state + * Task Ownership State Machine (sched_ext_entity->ops_state) * - * Used to track the task ownership between the SCX core and the BPF scheduler. - * State transitions look as follows: + * The sched_ext core uses this state machine to track task ownership + * between the SCX core and the BPF scheduler. This allows the BPF + * scheduler to dispatch tasks without strict ordering requirements, while + * the SCX core safely rejects invalid dispatches. * - * NONE -> QUEUEING -> QUEUED -> DISPATCHING - * ^ | | - * | v v - * \-------------------------------/ + * State Transitions * - * QUEUEING and DISPATCHING states can be waited upon. See wait_ops_state() call - * sites for explanations on the conditions being waited upon and why they are - * safe. Transitions out of them into NONE or QUEUED must store_release and the - * waiters should load_acquire. + * .------------> NONE (owned by SCX core) + * | | ^ + * | enqueue | | direct dispatch + * | v | + * | QUEUEING -------' + * | | + * | enqueue | + * | completes | + * | v + * | QUEUED (owned by BPF scheduler) + * | | + * | dispatch | + * | | + * | v + * | DISPATCHING + * | | + * | dispatch | + * | completes | + * `---------------' * - * Tracking scx_ops_state enables sched_ext core to reliably determine whether - * any given task can be dispatched by the BPF scheduler at all times and thus - * relaxes the requirements on the BPF scheduler. This allows the BPF scheduler - * to try to dispatch any task anytime regardless of its state as the SCX core - * can safely reject invalid dispatches. + * State Descriptions + * + * - %SCX_OPSS_NONE: + * Task is owned by the SCX core. It's either on a run queue, running, + * or being manipulated by the core scheduler. The BPF scheduler has no + * claim on this task. + * + * - %SCX_OPSS_QUEUEING: + * Transitional state while transferring a task from the SCX core to + * the BPF scheduler. The task's rq lock is held during this state. + * Since QUEUEING is both entered and exited under the rq lock, dequeue + * can never observe this state (it would be a BUG). When finishing a + * dispatch, if the task is still in %SCX_OPSS_QUEUEING the completion + * path busy-waits for it to leave this state (via wait_ops_state()) + * before retrying. + * + * - %SCX_OPSS_QUEUED: + * Task is owned by the BPF scheduler. It's on a DSQ (dispatch queue) + * and the BPF scheduler is responsible for dispatching it. A QSEQ + * (queue sequence number) is embedded in this state to detect + * dispatch/dequeue races: if a task is dequeued and re-enqueued, the + * QSEQ changes and any in-flight dispatch operations targeting the old + * QSEQ are safely ignored. + * + * - %SCX_OPSS_DISPATCHING: + * Transitional state while transferring a task from the BPF scheduler + * back to the SCX core. This state indicates the BPF scheduler has + * selected the task for execution. When dequeue needs to take the task + * off a DSQ and it is still in %SCX_OPSS_DISPATCHING, the dequeue path + * busy-waits for it to leave this state (via wait_ops_state()) before + * proceeding. Exits to %SCX_OPSS_NONE when dispatch completes. + * + * Memory Ordering + * + * Transitions out of %SCX_OPSS_QUEUEING and %SCX_OPSS_DISPATCHING into + * %SCX_OPSS_NONE or %SCX_OPSS_QUEUED must use atomic_long_set_release() + * and waiters must use atomic_long_read_acquire(). This ensures proper + * synchronization between concurrent operations. + * + * Cross-CPU Task Migration + * + * When moving a task in the %SCX_OPSS_DISPATCHING state, we can't simply + * grab the target CPU's rq lock because a concurrent dequeue might be + * waiting on %SCX_OPSS_DISPATCHING while holding the source rq lock + * (deadlock). + * + * The sched_ext core uses a "lock dancing" protocol coordinated by + * p->scx.holding_cpu. When moving a task to a different rq: + * + * 1. Verify task can be moved (CPU affinity, migration_disabled, etc.) + * 2. Set p->scx.holding_cpu to the current CPU + * 3. Set task state to %SCX_OPSS_NONE; dequeue waits while DISPATCHING + * is set, so clearing DISPATCHING first prevents the circular wait + * (safe to lock the rq we need) + * 4. Unlock the current CPU's rq + * 5. Lock src_rq (where the task currently lives) + * 6. Verify p->scx.holding_cpu == current CPU, if not, dequeue won the + * race (dequeue clears holding_cpu to -1 when it takes the task), in + * this case migration is aborted + * 7. If src_rq == dst_rq: clear holding_cpu and enqueue directly + * into dst_rq's local DSQ (no lock swap needed) + * 8. Otherwise: call move_remote_task_to_local_dsq(), which releases + * src_rq, locks dst_rq, and performs the deactivate/activate + * migration cycle (dst_rq is held on return) + * 9. Unlock dst_rq and re-lock the current CPU's rq to restore + * the lock state expected by the caller + * + * If any verification fails, abort the migration. + * + * This state tracking allows the BPF scheduler to try to dispatch any task + * at any time regardless of its state. The SCX core can safely + * reject/ignore invalid dispatches, simplifying the BPF scheduler + * implementation. */ enum scx_ops_state { SCX_OPSS_NONE, /* owned by the SCX core */ diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 1e22b7fadd70..bf948db905ed 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -589,6 +589,21 @@ static inline bool entity_before(const struct sched_entity *a, return vruntime_cmp(a->deadline, "<", b->deadline); } +/* + * Per avg_vruntime() below, cfs_rq::zero_vruntime is only slightly stale + * and this value should be no more than two lag bounds. Which puts it in the + * general order of: + * + * (slice + TICK_NSEC) << NICE_0_LOAD_SHIFT + * + * which is around 44 bits in size (on 64bit); that is 20 for + * NICE_0_LOAD_SHIFT, another 20 for NSEC_PER_MSEC and then a handful for + * however many msec the actual slice+tick ends up begin. + * + * (disregarding the actual divide-by-weight part makes for the worst case + * weight of 2, which nicely cancels vs the fuzz in zero_vruntime not actually + * being the zero-lag point). + */ static inline s64 entity_key(struct cfs_rq *cfs_rq, struct sched_entity *se) { return vruntime_op(se->vruntime, "-", cfs_rq->zero_vruntime); @@ -676,41 +691,65 @@ sum_w_vruntime_sub(struct cfs_rq *cfs_rq, struct sched_entity *se) } static inline -void sum_w_vruntime_update(struct cfs_rq *cfs_rq, s64 delta) +void update_zero_vruntime(struct cfs_rq *cfs_rq, s64 delta) { /* - * v' = v + d ==> sum_w_vruntime' = sum_runtime - d*sum_weight + * v' = v + d ==> sum_w_vruntime' = sum_w_vruntime - d*sum_weight */ cfs_rq->sum_w_vruntime -= cfs_rq->sum_weight * delta; + cfs_rq->zero_vruntime += delta; } /* - * Specifically: avg_runtime() + 0 must result in entity_eligible() := true + * Specifically: avg_vruntime() + 0 must result in entity_eligible() := true * For this to be so, the result of this function must have a left bias. + * + * Called in: + * - place_entity() -- before enqueue + * - update_entity_lag() -- before dequeue + * - entity_tick() + * + * This means it is one entry 'behind' but that puts it close enough to where + * the bound on entity_key() is at most two lag bounds. */ u64 avg_vruntime(struct cfs_rq *cfs_rq) { struct sched_entity *curr = cfs_rq->curr; - s64 avg = cfs_rq->sum_w_vruntime; - long load = cfs_rq->sum_weight; + long weight = cfs_rq->sum_weight; + s64 delta = 0; - if (curr && curr->on_rq) { - unsigned long weight = scale_load_down(curr->load.weight); + if (curr && !curr->on_rq) + curr = NULL; - avg += entity_key(cfs_rq, curr) * weight; - load += weight; - } + if (weight) { + s64 runtime = cfs_rq->sum_w_vruntime; + + if (curr) { + unsigned long w = scale_load_down(curr->load.weight); + + runtime += entity_key(cfs_rq, curr) * w; + weight += w; + } - if (load) { /* sign flips effective floor / ceiling */ - if (avg < 0) - avg -= (load - 1); - avg = div_s64(avg, load); + if (runtime < 0) + runtime -= (weight - 1); + + delta = div_s64(runtime, weight); + } else if (curr) { + /* + * When there is but one element, it is the average. + */ + delta = curr->vruntime - cfs_rq->zero_vruntime; } - return cfs_rq->zero_vruntime + avg; + update_zero_vruntime(cfs_rq, delta); + + return cfs_rq->zero_vruntime; } +static inline u64 cfs_rq_max_slice(struct cfs_rq *cfs_rq); + /* * lag_i = S - s_i = w_i * (V - v_i) * @@ -724,17 +763,16 @@ u64 avg_vruntime(struct cfs_rq *cfs_rq) * EEVDF gives the following limit for a steady state system: * * -r_max < lag < max(r_max, q) - * - * XXX could add max_slice to the augmented data to track this. */ static void update_entity_lag(struct cfs_rq *cfs_rq, struct sched_entity *se) { + u64 max_slice = cfs_rq_max_slice(cfs_rq) + TICK_NSEC; s64 vlag, limit; WARN_ON_ONCE(!se->on_rq); vlag = avg_vruntime(cfs_rq) - se->vruntime; - limit = calc_delta_fair(max_t(u64, 2*se->slice, TICK_NSEC), se); + limit = calc_delta_fair(max_slice, se); se->vlag = clamp(vlag, -limit, limit); } @@ -777,16 +815,6 @@ int entity_eligible(struct cfs_rq *cfs_rq, struct sched_entity *se) return vruntime_eligible(cfs_rq, se->vruntime); } -static void update_zero_vruntime(struct cfs_rq *cfs_rq) -{ - u64 vruntime = avg_vruntime(cfs_rq); - s64 delta = vruntime_op(vruntime, "-", cfs_rq->zero_vruntime); - - sum_w_vruntime_update(cfs_rq, delta); - - cfs_rq->zero_vruntime = vruntime; -} - static inline u64 cfs_rq_min_slice(struct cfs_rq *cfs_rq) { struct sched_entity *root = __pick_root_entity(cfs_rq); @@ -802,6 +830,21 @@ static inline u64 cfs_rq_min_slice(struct cfs_rq *cfs_rq) return min_slice; } +static inline u64 cfs_rq_max_slice(struct cfs_rq *cfs_rq) +{ + struct sched_entity *root = __pick_root_entity(cfs_rq); + struct sched_entity *curr = cfs_rq->curr; + u64 max_slice = 0ULL; + + if (curr && curr->on_rq) + max_slice = curr->slice; + + if (root) + max_slice = max(max_slice, root->max_slice); + + return max_slice; +} + static inline bool __entity_less(struct rb_node *a, const struct rb_node *b) { return entity_before(__node_2_se(a), __node_2_se(b)); @@ -826,6 +869,15 @@ static inline void __min_slice_update(struct sched_entity *se, struct rb_node *n } } +static inline void __max_slice_update(struct sched_entity *se, struct rb_node *node) +{ + if (node) { + struct sched_entity *rse = __node_2_se(node); + if (rse->max_slice > se->max_slice) + se->max_slice = rse->max_slice; + } +} + /* * se->min_vruntime = min(se->vruntime, {left,right}->min_vruntime) */ @@ -833,6 +885,7 @@ static inline bool min_vruntime_update(struct sched_entity *se, bool exit) { u64 old_min_vruntime = se->min_vruntime; u64 old_min_slice = se->min_slice; + u64 old_max_slice = se->max_slice; struct rb_node *node = &se->run_node; se->min_vruntime = se->vruntime; @@ -843,8 +896,13 @@ static inline bool min_vruntime_update(struct sched_entity *se, bool exit) __min_slice_update(se, node->rb_right); __min_slice_update(se, node->rb_left); + se->max_slice = se->slice; + __max_slice_update(se, node->rb_right); + __max_slice_update(se, node->rb_left); + return se->min_vruntime == old_min_vruntime && - se->min_slice == old_min_slice; + se->min_slice == old_min_slice && + se->max_slice == old_max_slice; } RB_DECLARE_CALLBACKS(static, min_vruntime_cb, struct sched_entity, @@ -856,7 +914,6 @@ RB_DECLARE_CALLBACKS(static, min_vruntime_cb, struct sched_entity, static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) { sum_w_vruntime_add(cfs_rq, se); - update_zero_vruntime(cfs_rq); se->min_vruntime = se->vruntime; se->min_slice = se->slice; rb_add_augmented_cached(&se->run_node, &cfs_rq->tasks_timeline, @@ -868,7 +925,6 @@ static void __dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) rb_erase_augmented_cached(&se->run_node, &cfs_rq->tasks_timeline, &min_vruntime_cb); sum_w_vruntime_sub(cfs_rq, se); - update_zero_vruntime(cfs_rq); } struct sched_entity *__pick_root_entity(struct cfs_rq *cfs_rq) @@ -3427,7 +3483,7 @@ static void task_numa_work(struct callback_head *work) if (!vma->numab_state) { struct vma_numab_state *ptr; - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); if (!ptr) continue; @@ -3790,6 +3846,8 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, unsigned long weight) { bool curr = cfs_rq->curr == se; + bool rel_vprot = false; + u64 vprot; if (se->on_rq) { /* commit outstanding execution time */ @@ -3797,6 +3855,11 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, update_entity_lag(cfs_rq, se); se->deadline -= se->vruntime; se->rel_deadline = 1; + if (curr && protect_slice(se)) { + vprot = se->vprot - se->vruntime; + rel_vprot = true; + } + cfs_rq->nr_queued--; if (!curr) __dequeue_entity(cfs_rq, se); @@ -3812,6 +3875,9 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, if (se->rel_deadline) se->deadline = div_s64(se->deadline * se->load.weight, weight); + if (rel_vprot) + vprot = div_s64(vprot * se->load.weight, weight); + update_load_set(&se->load, weight); do { @@ -3823,6 +3889,8 @@ static void reweight_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, enqueue_load_avg(cfs_rq, se); if (se->on_rq) { place_entity(cfs_rq, se, 0); + if (rel_vprot) + se->vprot = se->vruntime + vprot; update_load_add(&cfs_rq->load, se->load.weight); if (!curr) __enqueue_entity(cfs_rq, se); @@ -5420,7 +5488,7 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags) } static void -set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) +set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, bool first) { clear_buddies(cfs_rq, se); @@ -5435,7 +5503,8 @@ set_next_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) __dequeue_entity(cfs_rq, se); update_load_avg(cfs_rq, se, UPDATE_TG); - set_protect_slice(cfs_rq, se); + if (first) + set_protect_slice(cfs_rq, se); } update_stats_curr_start(cfs_rq, se); @@ -5524,6 +5593,11 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) update_load_avg(cfs_rq, curr, UPDATE_TG); update_cfs_group(curr); + /* + * Pulls along cfs_rq::zero_vruntime. + */ + avg_vruntime(cfs_rq); + #ifdef CONFIG_SCHED_HRTICK /* * queued ticks are scheduled to match the slice, so don't bother @@ -8948,13 +9022,13 @@ pick_next_task_fair(struct rq *rq, struct task_struct *prev, struct rq_flags *rf pse = parent_entity(pse); } if (se_depth >= pse_depth) { - set_next_entity(cfs_rq_of(se), se); + set_next_entity(cfs_rq_of(se), se, true); se = parent_entity(se); } } put_prev_entity(cfs_rq, pse); - set_next_entity(cfs_rq, se); + set_next_entity(cfs_rq, se, true); __set_next_task_fair(rq, p, true); } @@ -12908,7 +12982,7 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) t0 = sched_clock_cpu(this_cpu); __sched_balance_update_blocked_averages(this_rq); - this_rq->next_class = &fair_sched_class; + rq_modified_begin(this_rq, &fair_sched_class); raw_spin_rq_unlock(this_rq); for_each_domain(this_cpu, sd) { @@ -12975,7 +13049,7 @@ static int sched_balance_newidle(struct rq *this_rq, struct rq_flags *rf) pulled_task = 1; /* If a higher prio class was modified, restart the pick */ - if (sched_class_above(this_rq->next_class, &fair_sched_class)) + if (rq_modified_above(this_rq, &fair_sched_class)) pulled_task = -1; out: @@ -13568,7 +13642,7 @@ static void set_next_task_fair(struct rq *rq, struct task_struct *p, bool first) for_each_sched_entity(se) { struct cfs_rq *cfs_rq = cfs_rq_of(se); - set_next_entity(cfs_rq, se); + set_next_entity(cfs_rq, se, first); /* ensure bandwidth has been allocated on our new cfs_rq */ account_cfs_rq_runtime(cfs_rq, 0); } @@ -13622,10 +13696,10 @@ int alloc_fair_sched_group(struct task_group *tg, struct task_group *parent) struct cfs_rq *cfs_rq; int i; - tg->cfs_rq = kcalloc(nr_cpu_ids, sizeof(cfs_rq), GFP_KERNEL); + tg->cfs_rq = kzalloc_objs(cfs_rq, nr_cpu_ids); if (!tg->cfs_rq) goto err; - tg->se = kcalloc(nr_cpu_ids, sizeof(se), GFP_KERNEL); + tg->se = kzalloc_objs(se, nr_cpu_ids); if (!tg->se) goto err; diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c index 3681b6ad9276..b95449165122 100644 --- a/kernel/sched/idle.c +++ b/kernel/sched/idle.c @@ -221,7 +221,7 @@ static void cpuidle_idle_call(void) next_state = cpuidle_find_deepest_state(drv, dev, max_latency_ns); call_cpuidle(drv, dev, next_state); - } else { + } else if (drv->state_count > 1) { bool stop_tick = true; /* @@ -239,6 +239,15 @@ static void cpuidle_idle_call(void) * Give the governor an opportunity to reflect on the outcome */ cpuidle_reflect(dev, entered_state); + } else { + tick_nohz_idle_retain_tick(); + + /* + * If there is only a single idle state (or none), there is + * nothing meaningful for the governor to choose. Skip the + * governor and always use state 0. + */ + call_cpuidle(drv, dev, 0); } exit_idle: diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index 3b725d39c06e..ef152d401fe2 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c @@ -123,8 +123,6 @@ int housekeeping_update(struct cpumask *isol_mask) struct cpumask *trial, *old = NULL; int err; - lockdep_assert_cpus_held(); - trial = kmalloc(cpumask_size(), GFP_KERNEL); if (!trial) return -ENOMEM; @@ -136,7 +134,7 @@ int housekeeping_update(struct cpumask *isol_mask) } if (!housekeeping.flags) - static_branch_enable_cpuslocked(&housekeeping_overridden); + static_branch_enable(&housekeeping_overridden); if (housekeeping.flags & HK_FLAG_DOMAIN) old = housekeeping_cpumask_dereference(HK_TYPE_DOMAIN); diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c index 59fdb7ebbf22..d9c9d9480a45 100644 --- a/kernel/sched/psi.c +++ b/kernel/sched/psi.c @@ -1114,7 +1114,7 @@ int psi_cgroup_alloc(struct cgroup *cgroup) if (!static_branch_likely(&psi_cgroups_enabled)) return 0; - cgroup->psi = kzalloc(sizeof(struct psi_group), GFP_KERNEL); + cgroup->psi = kzalloc_obj(struct psi_group); if (!cgroup->psi) return -ENOMEM; @@ -1340,7 +1340,7 @@ struct psi_trigger *psi_trigger_create(struct psi_group *group, char *buf, if (threshold_us == 0 || threshold_us > window_us) return ERR_PTR(-EINVAL); - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) return ERR_PTR(-ENOMEM); diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index a7680477fa6f..f69e1f16d923 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c @@ -259,10 +259,10 @@ int alloc_rt_sched_group(struct task_group *tg, struct task_group *parent) if (!rt_group_sched_enabled()) return 1; - tg->rt_rq = kcalloc(nr_cpu_ids, sizeof(rt_rq), GFP_KERNEL); + tg->rt_rq = kzalloc_objs(rt_rq, nr_cpu_ids); if (!tg->rt_rq) goto err; - tg->rt_se = kcalloc(nr_cpu_ids, sizeof(rt_se), GFP_KERNEL); + tg->rt_se = kzalloc_objs(rt_se, nr_cpu_ids); if (!tg->rt_se) goto err; diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index b82fb70a9d54..43bbf0693cca 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -2748,6 +2748,17 @@ static inline const struct sched_class *next_active_class(const struct sched_cla #define sched_class_above(_a, _b) ((_a) < (_b)) +static inline void rq_modified_begin(struct rq *rq, const struct sched_class *class) +{ + if (sched_class_above(rq->next_class, class)) + rq->next_class = class; +} + +static inline bool rq_modified_above(struct rq *rq, const struct sched_class *class) +{ + return sched_class_above(rq->next_class, class); +} + static inline bool sched_stop_runnable(struct rq *rq) { return rq->stop && task_on_rq_queued(rq->stop); diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c index 6f10db3646e7..cadb0e9fe19b 100644 --- a/kernel/sched/syscalls.c +++ b/kernel/sched/syscalls.c @@ -284,6 +284,35 @@ static bool check_same_owner(struct task_struct *p) uid_eq(cred->euid, pcred->uid)); } +#ifdef CONFIG_RT_MUTEXES +static inline void __setscheduler_dl_pi(int newprio, int policy, + struct task_struct *p, + struct sched_change_ctx *scope) +{ + /* + * In case a DEADLINE task (either proper or boosted) gets + * setscheduled to a lower priority class, check if it neeeds to + * inherit parameters from a potential pi_task. In that case make + * sure replenishment happens with the next enqueue. + */ + + if (dl_prio(newprio) && !dl_policy(policy)) { + struct task_struct *pi_task = rt_mutex_get_top_task(p); + + if (pi_task) { + p->dl.pi_se = pi_task->dl.pi_se; + scope->flags |= ENQUEUE_REPLENISH; + } + } +} +#else /* !CONFIG_RT_MUTEXES */ +static inline void __setscheduler_dl_pi(int newprio, int policy, + struct task_struct *p, + struct sched_change_ctx *scope) +{ +} +#endif /* !CONFIG_RT_MUTEXES */ + #ifdef CONFIG_UCLAMP_TASK static int uclamp_validate(struct task_struct *p, @@ -655,6 +684,7 @@ int __sched_setscheduler(struct task_struct *p, __setscheduler_params(p, attr); p->sched_class = next_class; p->prio = newprio; + __setscheduler_dl_pi(newprio, policy, p, scope); } __setscheduler_uclamp(p, attr); diff --git a/kernel/sched/topology.c b/kernel/sched/topology.c index ac268da91778..32dcddaead82 100644 --- a/kernel/sched/topology.c +++ b/kernel/sched/topology.c @@ -350,7 +350,7 @@ static struct perf_domain *pd_init(int cpu) return NULL; } - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return NULL; pd->em_pd = obj; @@ -589,7 +589,7 @@ static struct root_domain *alloc_rootdomain(void) { struct root_domain *rd; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return NULL; @@ -1998,7 +1998,7 @@ static int sched_record_numa_dist(int offline_node, int (*n_dist)(int, int), */ nr_levels = bitmap_weight(distance_map, NR_DISTANCE_VALUES); - distances = kcalloc(nr_levels, sizeof(int), GFP_KERNEL); + distances = kzalloc_objs(int, nr_levels); if (!distances) return -ENOMEM; @@ -2734,7 +2734,7 @@ cpumask_var_t *alloc_sched_domains(unsigned int ndoms) int i; cpumask_var_t *doms; - doms = kmalloc_array(ndoms, sizeof(*doms), GFP_KERNEL); + doms = kmalloc_objs(*doms, ndoms); if (!doms) return NULL; for (i = 0; i < ndoms; i++) { diff --git a/kernel/seccomp.c b/kernel/seccomp.c index 25f62867a16d..066909393c38 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -693,7 +693,7 @@ static struct seccomp_filter *seccomp_prepare_filter(struct sock_fprog *fprog) return ERR_PTR(-EACCES); /* Allocate a new seccomp_filter */ - sfilter = kzalloc(sizeof(*sfilter), GFP_KERNEL | __GFP_NOWARN); + sfilter = kzalloc_obj(*sfilter, GFP_KERNEL | __GFP_NOWARN); if (!sfilter) return ERR_PTR(-ENOMEM); @@ -1893,7 +1893,7 @@ static struct file *init_listener(struct seccomp_filter *filter) struct file *ret; ret = ERR_PTR(-ENOMEM); - filter->notif = kzalloc(sizeof(*(filter->notif)), GFP_KERNEL); + filter->notif = kzalloc_obj(*(filter->notif)); if (!filter->notif) goto out; diff --git a/kernel/static_call_inline.c b/kernel/static_call_inline.c index 269683d41aa9..2b6a0d99cdbe 100644 --- a/kernel/static_call_inline.c +++ b/kernel/static_call_inline.c @@ -255,7 +255,7 @@ static int __static_call_init(struct module *mod, goto do_transform; } - site_mod = kzalloc(sizeof(*site_mod), GFP_KERNEL); + site_mod = kzalloc_obj(*site_mod); if (!site_mod) return -ENOMEM; @@ -271,7 +271,7 @@ static int __static_call_init(struct module *mod, key->mods = site_mod; - site_mod = kzalloc(sizeof(*site_mod), GFP_KERNEL); + site_mod = kzalloc_obj(*site_mod); if (!site_mod) return -ENOMEM; } diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 2cd767b9680e..9d3a666ffde1 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -354,29 +354,221 @@ static void proc_put_char(void **buf, size_t *size, char c) } } -static SYSCTL_USER_TO_KERN_INT_CONV(, SYSCTL_CONV_IDENTITY) -static SYSCTL_KERN_TO_USER_INT_CONV(, SYSCTL_CONV_IDENTITY) - -static SYSCTL_INT_CONV_CUSTOM(, sysctl_user_to_kern_int_conv, - sysctl_kern_to_user_int_conv, false) -static SYSCTL_INT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_int_conv, - sysctl_kern_to_user_int_conv, true) - - -static SYSCTL_USER_TO_KERN_UINT_CONV(, SYSCTL_CONV_IDENTITY) - -int sysctl_kern_to_user_uint_conv(unsigned long *u_ptr, - const unsigned int *k_ptr) +/** + * proc_uint_u2k_conv_uop - Assign user value to a kernel pointer + * + * @u_ptr: pointer to user space variable + * @k_ptr: pointer to kernel variable + * @u_ptr_op: execute this function before assigning to k_ptr + * + * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if + * not NULL. Check that the values are less than UINT_MAX to avoid + * having to support wrap around from userspace. + * + * returns 0 on success. + */ +int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, + ulong (*u_ptr_op)(const ulong)) { - unsigned int val = READ_ONCE(*k_ptr); - *u_ptr = (unsigned long)val; + ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr; + + if (u > UINT_MAX) + return -EINVAL; + WRITE_ONCE(*k_ptr, u); return 0; } -static SYSCTL_UINT_CONV_CUSTOM(, sysctl_user_to_kern_uint_conv, - sysctl_kern_to_user_uint_conv, false) -static SYSCTL_UINT_CONV_CUSTOM(_minmax, sysctl_user_to_kern_uint_conv, - sysctl_kern_to_user_uint_conv, true) +/** + * proc_uint_k2u_conv - Assign kernel value to a user space pointer + * + * @u_ptr: pointer to user space variable + * @k_ptr: pointer to kernel variable + * + * Uses READ_ONCE to assign value to u_ptr. + * + * returns 0 on success. + */ +int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr) +{ + uint val = READ_ONCE(*k_ptr); + *u_ptr = (ulong)val; + return 0; +} + +/** + * proc_uint_conv - Change user or kernel pointer based on direction + * + * @u_ptr: pointer to user variable + * @k_ptr: pointer to kernel variable + * @dir: %TRUE if this is a write to the sysctl file + * @tbl: the sysctl table + * @k_ptr_range_check: Check range for k_ptr when %TRUE + * @user_to_kern: Callback used to assign value from user to kernel var + * @kern_to_user: Callback used to assign value from kernel to user var + * + * When direction is kernel to user, then the u_ptr is modified. + * When direction is user to kernel, then the k_ptr is modified. + * + * Returns 0 on success + */ +int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr), + int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr)) +{ + if (SYSCTL_KERN_TO_USER(dir)) + return kern_to_user(u_ptr, k_ptr); + + if (k_ptr_range_check) { + uint tmp_k; + int ret; + + if (!tbl) + return -EINVAL; + ret = user_to_kern(u_ptr, &tmp_k); + if (ret) + return ret; + if ((tbl->extra1 && + *(uint *)tbl->extra1 > tmp_k) || + (tbl->extra2 && + *(uint *)tbl->extra2 < tmp_k)) + return -ERANGE; + WRITE_ONCE(*k_ptr, tmp_k); + } else + return user_to_kern(u_ptr, k_ptr); + return 0; +} + +static int proc_uint_u2k_conv(const ulong *u_ptr, uint *k_ptr) +{ + return proc_uint_u2k_conv_uop(u_ptr, k_ptr, NULL); +} + +static int do_proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return proc_uint_conv(u_ptr, k_ptr, dir, tbl, false, + proc_uint_u2k_conv, proc_uint_k2u_conv); +} + +static int do_proc_uint_conv_minmax(ulong *u_ptr, uint *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return proc_uint_conv(u_ptr, k_ptr, dir, tbl, true, + proc_uint_u2k_conv, proc_uint_k2u_conv); +} + +/** + * proc_int_k2u_conv_kop - Assign kernel value to a user space pointer + * @u_ptr: pointer to user space variable + * @k_ptr: pointer to kernel variable + * @negp: assigned %TRUE if the converted kernel value is negative; + * %FALSE otherweise + * @k_ptr_op: execute this function before assigning to u_ptr + * + * Uses READ_ONCE to get value from k_ptr. Executes k_ptr_op before assigning + * to u_ptr if not NULL. Does **not** check for overflow. + * + * Returns: 0 on success. + */ +int proc_int_k2u_conv_kop(ulong *u_ptr, const int *k_ptr, bool *negp, + ulong (*k_ptr_op)(const ulong)) +{ + int val = READ_ONCE(*k_ptr); + + if (val < 0) { + *negp = true; + *u_ptr = k_ptr_op ? -k_ptr_op((ulong)val) : -(ulong)val; + } else { + *negp = false; + *u_ptr = k_ptr_op ? k_ptr_op((ulong)val) : (ulong) val; + } + return 0; +} + +/** + * proc_int_u2k_conv_uop - Assign user value to a kernel pointer + * @u_ptr: pointer to user space variable + * @k_ptr: pointer to kernel variable + * @negp: If %TRUE, the converted user value is made negative. + * @u_ptr_op: execute this function before assigning to k_ptr + * + * Uses WRITE_ONCE to assign value to k_ptr. Executes u_ptr_op if + * not NULL. Check for overflow with UINT_MAX. + * + * Returns: 0 on success. + */ +int proc_int_u2k_conv_uop(const ulong *u_ptr, int *k_ptr, const bool *negp, + ulong (*u_ptr_op)(const ulong)) +{ + ulong u = u_ptr_op ? u_ptr_op(*u_ptr) : *u_ptr; + + if (*negp) { + if (u > (ulong) INT_MAX + 1) + return -EINVAL; + WRITE_ONCE(*k_ptr, -u); + } else { + if (u > (ulong) INT_MAX) + return -EINVAL; + WRITE_ONCE(*k_ptr, u); + } + return 0; +} + +int proc_int_conv(bool *negp, ulong *u_ptr, int *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const bool *negp, const ulong *u_ptr, int *k_ptr), + int (*kern_to_user)(bool *negp, ulong *u_ptr, const int *k_ptr)) +{ + if (SYSCTL_KERN_TO_USER(dir)) + return kern_to_user(negp, u_ptr, k_ptr); + + if (k_ptr_range_check) { + int tmp_k, ret; + + if (!tbl) + return -EINVAL; + ret = user_to_kern(negp, u_ptr, &tmp_k); + if (ret) + return ret; + if ((tbl->extra1 && *(int *)tbl->extra1 > tmp_k) || + (tbl->extra2 && *(int *)tbl->extra2 < tmp_k)) + return -EINVAL; + WRITE_ONCE(*k_ptr, tmp_k); + } else + return user_to_kern(negp, u_ptr, k_ptr); + return 0; +} + + + +static int sysctl_user_to_kern_int_conv(const bool *negp, const ulong *u_ptr, + int *k_ptr) +{ + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, NULL); +} + +static int sysctl_kern_to_user_int_conv(bool *negp, ulong *u_ptr, const int *k_ptr) +{ + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, NULL); +} + +static int do_proc_int_conv(bool *negp, unsigned long *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, + sysctl_user_to_kern_int_conv, + sysctl_kern_to_user_int_conv); + +} + +static int do_proc_int_conv_minmax(bool *negp, unsigned long *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, true, + sysctl_user_to_kern_int_conv, + sysctl_kern_to_user_int_conv); +} static const char proc_wspace_sep[] = { ' ', '\t', '\n' }; @@ -568,6 +760,22 @@ static int do_proc_douintvec(const struct ctl_table *table, int dir, return do_proc_douintvec_r(table, buffer, lenp, ppos, conv); } +/** + * proc_douintvec_conv - read a vector of unsigned ints with a custom converter + * + * @table: the sysctl table + * @dir: %TRUE if this is a write to the sysctl file + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position + * @conv: Custom converter call back + * + * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer + * values from/to the user buffer, treated as an ASCII string. Negative + * strings are not allowed. + * + * Returns 0 on success + */ int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(unsigned long *u_ptr, unsigned int *k_ptr, @@ -576,7 +784,6 @@ int proc_douintvec_conv(const struct ctl_table *table, int dir, void *buffer, return do_proc_douintvec(table, dir, buffer, lenp, ppos, conv); } - /** * proc_dobool - read/write a bool * @table: the sysctl table @@ -692,10 +899,10 @@ int proc_dointvec_minmax(const struct ctl_table *table, int dir, * values from/to the user buffer, treated as an ASCII string. Negative * strings are not allowed. * - * This routine will ensure the values are within the range specified by - * table->extra1 (min) and table->extra2 (max). There is a final sanity - * check for UINT_MAX to avoid having to support wrap around uses from - * userspace. + * When changing the kernel variable, this routine will ensure the values + * are within the range specified by table->extra1 (min) and table->extra2 + * (max). And Check that the values are less than UINT_MAX to avoid having to + * support wrap around uses from userspace. * * Returns 0 on success or -ERANGE when range check failes and * SYSCTL_USER_TO_KERN(dir) == true @@ -862,6 +1069,22 @@ int proc_doulongvec_minmax(const struct ctl_table *table, int dir, return proc_doulongvec_minmax_conv(table, dir, buffer, lenp, ppos, 1l, 1l); } +/** + * proc_dointvec_conv - read a vector of ints with a custom converter + * @table: the sysctl table + * @dir: %TRUE if this is a write to the sysctl file + * @buffer: the user buffer + * @lenp: the size of the user buffer + * @ppos: file position + * @conv: Custom converter call back + * + * Reads/writes up to table->maxlen/sizeof(unsigned int) unsigned integer + * values from/to the user buffer, treated as an ASCII string. Negative + * strings are not allowed. + * + * Returns: 0 on success + */ + int proc_dointvec_conv(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos, int (*conv)(bool *negp, unsigned long *u_ptr, int *k_ptr, @@ -1055,6 +1278,33 @@ int proc_douintvec_minmax(const struct ctl_table *table, int dir, return -ENOSYS; } +int proc_douintvec_conv(const struct ctl_table *table, int write, void *buffer, + size_t *lenp, loff_t *ppos, + int (*conv)(unsigned long *lvalp, unsigned int *valp, + int write, const struct ctl_table *table)) +{ + return -ENOSYS; +} + +int proc_uint_k2u_conv(ulong *u_ptr, const uint *k_ptr) +{ + return -ENOSYS; +} + +int proc_uint_u2k_conv_uop(const ulong *u_ptr, uint *k_ptr, + ulong (*u_ptr_op)(const ulong)) +{ + return -ENOSYS; +} + +int proc_uint_conv(ulong *u_ptr, uint *k_ptr, int dir, + const struct ctl_table *tbl, bool k_ptr_range_check, + int (*user_to_kern)(const ulong *u_ptr, uint *k_ptr), + int (*kern_to_user)(ulong *u_ptr, const uint *k_ptr)) +{ + return -ENOSYS; +} + int proc_dou8vec_minmax(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index d31a6d40d38d..9daf8c5d9687 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c @@ -100,26 +100,120 @@ void __init register_refined_jiffies(long cycles_per_second) __clocksource_register(&refined_jiffies); } -#define SYSCTL_CONV_MULT_HZ(val) ((val) * HZ) -#define SYSCTL_CONV_DIV_HZ(val) ((val) / HZ) +#ifdef CONFIG_PROC_SYSCTL +static ulong mult_hz(const ulong val) +{ + return val * HZ; +} -static SYSCTL_USER_TO_KERN_INT_CONV(_hz, SYSCTL_CONV_MULT_HZ) -static SYSCTL_KERN_TO_USER_INT_CONV(_hz, SYSCTL_CONV_DIV_HZ) -static SYSCTL_USER_TO_KERN_INT_CONV(_userhz, clock_t_to_jiffies) -static SYSCTL_KERN_TO_USER_INT_CONV(_userhz, jiffies_to_clock_t) -static SYSCTL_USER_TO_KERN_INT_CONV(_ms, msecs_to_jiffies) -static SYSCTL_KERN_TO_USER_INT_CONV(_ms, jiffies_to_msecs) +static ulong div_hz(const ulong val) +{ + return val / HZ; +} -static SYSCTL_INT_CONV_CUSTOM(_jiffies, sysctl_user_to_kern_int_conv_hz, - sysctl_kern_to_user_int_conv_hz, false) -static SYSCTL_INT_CONV_CUSTOM(_userhz_jiffies, - sysctl_user_to_kern_int_conv_userhz, - sysctl_kern_to_user_int_conv_userhz, false) -static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies, sysctl_user_to_kern_int_conv_ms, - sysctl_kern_to_user_int_conv_ms, false) -static SYSCTL_INT_CONV_CUSTOM(_ms_jiffies_minmax, - sysctl_user_to_kern_int_conv_ms, - sysctl_kern_to_user_int_conv_ms, true) +static int sysctl_u2k_int_conv_hz(const bool *negp, const ulong *u_ptr, int *k_ptr) +{ + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, mult_hz); +} + +static int sysctl_k2u_int_conv_hz(bool *negp, ulong *u_ptr, const int *k_ptr) +{ + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, div_hz); +} + +static int sysctl_u2k_int_conv_userhz(const bool *negp, const ulong *u_ptr, int *k_ptr) +{ + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, clock_t_to_jiffies); +} + +static ulong sysctl_jiffies_to_clock_t(const ulong val) +{ + return jiffies_to_clock_t(val); +} + +static int sysctl_k2u_int_conv_userhz(bool *negp, ulong *u_ptr, const int *k_ptr) +{ + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_clock_t); +} + +static ulong sysctl_msecs_to_jiffies(const ulong val) +{ + return msecs_to_jiffies(val); +} + +static int sysctl_u2k_int_conv_ms(const bool *negp, const ulong *u_ptr, int *k_ptr) +{ + return proc_int_u2k_conv_uop(u_ptr, k_ptr, negp, sysctl_msecs_to_jiffies); +} + +static ulong sysctl_jiffies_to_msecs(const ulong val) +{ + return jiffies_to_msecs(val); +} + +static int sysctl_k2u_int_conv_ms(bool *negp, ulong *u_ptr, const int *k_ptr) +{ + return proc_int_k2u_conv_kop(u_ptr, k_ptr, negp, sysctl_jiffies_to_msecs); +} + +static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, + sysctl_u2k_int_conv_hz, sysctl_k2u_int_conv_hz); +} + +static int do_proc_int_conv_userhz_jiffies(bool *negp, ulong *u_ptr, + int *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, + sysctl_u2k_int_conv_userhz, + sysctl_k2u_int_conv_userhz); +} + +static int do_proc_int_conv_ms_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, + sysctl_u2k_int_conv_ms, sysctl_k2u_int_conv_ms); +} + +static int do_proc_int_conv_ms_jiffies_minmax(bool *negp, ulong *u_ptr, + int *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return proc_int_conv(negp, u_ptr, k_ptr, dir, tbl, false, + sysctl_u2k_int_conv_ms, sysctl_k2u_int_conv_ms); +} + +#else // CONFIG_PROC_SYSCTL +static int do_proc_int_conv_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return -ENOSYS; +} + +static int do_proc_int_conv_userhz_jiffies(bool *negp, ulong *u_ptr, + int *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return -ENOSYS; +} + +static int do_proc_int_conv_ms_jiffies(bool *negp, ulong *u_ptr, int *k_ptr, + int dir, const struct ctl_table *tbl) +{ + return -ENOSYS; +} + +static int do_proc_int_conv_ms_jiffies_minmax(bool *negp, ulong *u_ptr, + int *k_ptr, int dir, + const struct ctl_table *tbl) +{ + return -ENOSYS; +} +#endif /** * proc_dointvec_jiffies - read a vector of integers as seconds @@ -162,8 +256,6 @@ EXPORT_SYMBOL(proc_dointvec_jiffies); int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int dir, void *buffer, size_t *lenp, loff_t *ppos) { - if (SYSCTL_USER_TO_KERN(dir) && USER_HZ < HZ) - return -EINVAL; return proc_dointvec_conv(table, dir, buffer, lenp, ppos, do_proc_int_conv_userhz_jiffies); } diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index e76be24b132c..652744e00eb4 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -89,7 +89,7 @@ static struct time_namespace *clone_time_ns(struct user_namespace *user_ns, goto fail; err = -ENOMEM; - ns = kzalloc(sizeof(*ns), GFP_KERNEL_ACCOUNT); + ns = kzalloc_obj(*ns, GFP_KERNEL_ACCOUNT); if (!ns) goto fail_dec; diff --git a/kernel/time/posix-clock.c b/kernel/time/posix-clock.c index 101a0f7c43e0..dab37295c8c2 100644 --- a/kernel/time/posix-clock.c +++ b/kernel/time/posix-clock.c @@ -103,7 +103,7 @@ static int posix_clock_open(struct inode *inode, struct file *fp) err = -ENODEV; goto out; } - pccontext = kzalloc(sizeof(*pccontext), GFP_KERNEL); + pccontext = kzalloc_obj(*pccontext); if (!pccontext) { err = -ENOMEM; goto out; diff --git a/kernel/time/time.c b/kernel/time/time.c index 0ba8e3c50d62..0d832317d576 100644 --- a/kernel/time/time.c +++ b/kernel/time/time.c @@ -365,20 +365,16 @@ SYSCALL_DEFINE1(adjtimex_time32, struct old_timex32 __user *, utp) } #endif +#if HZ > MSEC_PER_SEC || (MSEC_PER_SEC % HZ) /** * jiffies_to_msecs - Convert jiffies to milliseconds * @j: jiffies value * - * Avoid unnecessary multiplications/divisions in the - * two most common HZ cases. - * * Return: milliseconds value */ unsigned int jiffies_to_msecs(const unsigned long j) { -#if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) - return (MSEC_PER_SEC / HZ) * j; -#elif HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) +#if HZ > MSEC_PER_SEC && !(HZ % MSEC_PER_SEC) return (j + (HZ / MSEC_PER_SEC) - 1)/(HZ / MSEC_PER_SEC); #else # if BITS_PER_LONG == 32 @@ -390,7 +386,9 @@ unsigned int jiffies_to_msecs(const unsigned long j) #endif } EXPORT_SYMBOL(jiffies_to_msecs); +#endif +#if (USEC_PER_SEC % HZ) /** * jiffies_to_usecs - Convert jiffies to microseconds * @j: jiffies value @@ -405,17 +403,14 @@ unsigned int jiffies_to_usecs(const unsigned long j) */ BUILD_BUG_ON(HZ > USEC_PER_SEC); -#if !(USEC_PER_SEC % HZ) - return (USEC_PER_SEC / HZ) * j; -#else -# if BITS_PER_LONG == 32 +#if BITS_PER_LONG == 32 return (HZ_TO_USEC_MUL32 * j) >> HZ_TO_USEC_SHR32; -# else +#else return (j * HZ_TO_USEC_NUM) / HZ_TO_USEC_DEN; -# endif #endif } EXPORT_SYMBOL(jiffies_to_usecs); +#endif /** * mktime64 - Converts date to seconds. @@ -702,7 +697,7 @@ EXPORT_SYMBOL(clock_t_to_jiffies); * * Return: jiffies_64 value converted to 64-bit "clock_t" (CLOCKS_PER_SEC) */ -u64 jiffies_64_to_clock_t(u64 x) +notrace u64 jiffies_64_to_clock_t(u64 x) { #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 # if HZ < USER_HZ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 91fa2003351c..c07e562ee4c1 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -2653,7 +2653,8 @@ static int timekeeping_validate_timex(const struct __kernel_timex *txc, bool aux if (aux_clock) { /* Auxiliary clocks are similar to TAI and do not have leap seconds */ - if (txc->status & (STA_INS | STA_DEL)) + if (txc->modes & ADJ_STATUS && + txc->status & (STA_INS | STA_DEL)) return -EINVAL; /* No TAI offset setting */ @@ -2661,7 +2662,8 @@ static int timekeeping_validate_timex(const struct __kernel_timex *txc, bool aux return -EINVAL; /* No PPS support either */ - if (txc->status & (STA_PPSFREQ | STA_PPSTIME)) + if (txc->modes & ADJ_STATUS && + txc->status & (STA_PPSFREQ | STA_PPSTIME)) return -EINVAL; } diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c index 6da9cd562b20..155eeaea4113 100644 --- a/kernel/time/timer_migration.c +++ b/kernel/time/timer_migration.c @@ -1559,8 +1559,6 @@ int tmigr_isolated_exclude_cpumask(struct cpumask *exclude_cpumask) cpumask_var_t cpumask __free(free_cpumask_var) = CPUMASK_VAR_NULL; int cpu; - lockdep_assert_cpus_held(); - if (!works) return -ENOMEM; if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) @@ -1570,6 +1568,7 @@ int tmigr_isolated_exclude_cpumask(struct cpumask *exclude_cpumask) * First set previously isolated CPUs as available (unisolate). * This cpumask contains only CPUs that switched to available now. */ + guard(cpus_read_lock)(); cpumask_andnot(cpumask, cpu_online_mask, exclude_cpumask); cpumask_andnot(cpumask, cpumask, tmigr_available_cpumask); @@ -1626,7 +1625,6 @@ static int __init tmigr_init_isolation(void) cpumask_andnot(cpumask, cpu_possible_mask, housekeeping_cpumask(HK_TYPE_DOMAIN)); /* Protect against RCU torture hotplug testing */ - guard(cpus_read_lock)(); return tmigr_isolated_exclude_cpumask(cpumask); } late_initcall(tmigr_init_isolation); @@ -1766,7 +1764,7 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node, int i, top = 0, err = 0, start_lvl = 0; bool root_mismatch = false; - stack = kcalloc(tmigr_hierarchy_levels, sizeof(*stack), GFP_KERNEL); + stack = kzalloc_objs(*stack, tmigr_hierarchy_levels); if (!stack) return -ENOMEM; @@ -2001,7 +1999,8 @@ static int __init tmigr_init(void) */ tmigr_crossnode_level = cpulvl; - tmigr_level_list = kcalloc(tmigr_hierarchy_levels, sizeof(struct list_head), GFP_KERNEL); + tmigr_level_list = kzalloc_objs(struct list_head, + tmigr_hierarchy_levels); if (!tmigr_level_list) goto err; diff --git a/kernel/torture.c b/kernel/torture.c index 1ea9f67953a7..ec3370986976 100644 --- a/kernel/torture.c +++ b/kernel/torture.c @@ -494,7 +494,7 @@ void torture_shuffle_task_register(struct task_struct *tp) if (WARN_ON_ONCE(tp == NULL)) return; - stp = kmalloc(sizeof(*stp), GFP_KERNEL); + stp = kmalloc_obj(*stp); if (WARN_ON_ONCE(stp == NULL)) return; stp->st_t = tp; diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index d7042a09fe46..49de13cae428 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -136,6 +136,7 @@ config BUILDTIME_MCOUNT_SORT config TRACER_MAX_TRACE bool + select TRACER_SNAPSHOT config TRACE_CLOCK bool @@ -425,7 +426,6 @@ config IRQSOFF_TRACER select GENERIC_TRACER select TRACER_MAX_TRACE select RING_BUFFER_ALLOW_SWAP - select TRACER_SNAPSHOT select TRACER_SNAPSHOT_PER_CPU_SWAP help This option measures the time spent in irqs-off critical @@ -448,7 +448,6 @@ config PREEMPT_TRACER select GENERIC_TRACER select TRACER_MAX_TRACE select RING_BUFFER_ALLOW_SWAP - select TRACER_SNAPSHOT select TRACER_SNAPSHOT_PER_CPU_SWAP select TRACE_PREEMPT_TOGGLE help @@ -470,7 +469,6 @@ config SCHED_TRACER select GENERIC_TRACER select CONTEXT_SWITCH_TRACER select TRACER_MAX_TRACE - select TRACER_SNAPSHOT help This tracer tracks the latency of the highest priority task to be scheduled in, starting from the point it has woken up. @@ -620,7 +618,6 @@ config TRACE_SYSCALL_BUF_SIZE_DEFAULT config TRACER_SNAPSHOT bool "Create a snapshot trace buffer" - select TRACER_MAX_TRACE help Allow tracing users to take snapshot of the current buffer using the ftrace interface, e.g.: @@ -628,6 +625,9 @@ config TRACER_SNAPSHOT echo 1 > /sys/kernel/tracing/snapshot cat snapshot + Note, the latency tracers select this option. To disable it, + all the latency tracers need to be disabled. + config TRACER_SNAPSHOT_PER_CPU_SWAP bool "Allow snapshot to swap per CPU" depends on TRACER_SNAPSHOT diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile index fc5dcc888e13..04096c21d06b 100644 --- a/kernel/trace/Makefile +++ b/kernel/trace/Makefile @@ -68,6 +68,7 @@ obj-$(CONFIG_TRACING) += trace_output.o obj-$(CONFIG_TRACING) += trace_seq.o obj-$(CONFIG_TRACING) += trace_stat.o obj-$(CONFIG_TRACING) += trace_printk.o +obj-$(CONFIG_TRACING) += trace_pid.o obj-$(CONFIG_TRACING) += pid_list.o obj-$(CONFIG_TRACING_MAP) += tracing_map.o obj-$(CONFIG_PREEMPTIRQ_DELAY_TEST) += preemptirq_delay_test.o diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index c4db5c2e7103..8cd2520b4c99 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -383,8 +383,6 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, cpu = raw_smp_processor_id(); if (blk_tracer) { - tracing_record_cmdline(current); - buffer = blk_tr->array_buffer.buffer; trace_ctx = tracing_gen_ctx_flags(0); switch (bt->version) { @@ -419,6 +417,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, if (!event) return; + tracing_record_cmdline(current); switch (bt->version) { case 1: record_blktrace_event(ring_buffer_event_data(event), @@ -559,9 +558,9 @@ int blk_trace_remove(struct request_queue *q) { int ret; - mutex_lock(&q->debugfs_mutex); + blk_debugfs_lock_nomemsave(q); ret = __blk_trace_remove(q); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock_nomemrestore(q); return ret; } @@ -671,7 +670,7 @@ static struct blk_trace *blk_trace_setup_prepare(struct request_queue *q, return ERR_PTR(-EBUSY); } - bt = kzalloc(sizeof(*bt), GFP_KERNEL); + bt = kzalloc_obj(*bt); if (!bt) return ERR_PTR(-ENOMEM); @@ -767,6 +766,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, struct blk_user_trace_setup2 buts2; struct blk_user_trace_setup buts; struct blk_trace *bt; + unsigned int memflags; int ret; ret = copy_from_user(&buts, arg, sizeof(buts)); @@ -785,16 +785,16 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, .pid = buts.pid, }; - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); bt = blk_trace_setup_prepare(q, name, dev, buts.buf_size, buts.buf_nr, bdev); if (IS_ERR(bt)) { - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); return PTR_ERR(bt); } blk_trace_setup_finalize(q, name, 1, bt, &buts2); strscpy(buts.name, buts2.name, BLKTRACE_BDEV_SIZE); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); if (copy_to_user(arg, &buts, sizeof(buts))) { blk_trace_remove(q); @@ -809,6 +809,7 @@ static int blk_trace_setup2(struct request_queue *q, char *name, dev_t dev, { struct blk_user_trace_setup2 buts2; struct blk_trace *bt; + unsigned int memflags; if (copy_from_user(&buts2, arg, sizeof(buts2))) return -EFAULT; @@ -819,15 +820,15 @@ static int blk_trace_setup2(struct request_queue *q, char *name, dev_t dev, if (buts2.flags != 0) return -EINVAL; - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); bt = blk_trace_setup_prepare(q, name, dev, buts2.buf_size, buts2.buf_nr, bdev); if (IS_ERR(bt)) { - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); return PTR_ERR(bt); } blk_trace_setup_finalize(q, name, 2, bt, &buts2); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); if (copy_to_user(arg, &buts2, sizeof(buts2))) { blk_trace_remove(q); @@ -844,6 +845,7 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, struct blk_user_trace_setup2 buts2; struct compat_blk_user_trace_setup cbuts; struct blk_trace *bt; + unsigned int memflags; if (copy_from_user(&cbuts, arg, sizeof(cbuts))) return -EFAULT; @@ -860,15 +862,15 @@ static int compat_blk_trace_setup(struct request_queue *q, char *name, .pid = cbuts.pid, }; - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); bt = blk_trace_setup_prepare(q, name, dev, buts2.buf_size, buts2.buf_nr, bdev); if (IS_ERR(bt)) { - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); return PTR_ERR(bt); } blk_trace_setup_finalize(q, name, 1, bt, &buts2); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); if (copy_to_user(arg, &buts2.name, ARRAY_SIZE(buts2.name))) { blk_trace_remove(q); @@ -898,9 +900,9 @@ int blk_trace_startstop(struct request_queue *q, int start) { int ret; - mutex_lock(&q->debugfs_mutex); + blk_debugfs_lock_nomemsave(q); ret = __blk_trace_startstop(q, start); - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock_nomemrestore(q); return ret; } @@ -1832,7 +1834,9 @@ static struct trace_event trace_blk_event = { .funcs = &trace_blk_event_funcs, }; -static int __init init_blk_tracer(void) +static struct work_struct blktrace_works __initdata; + +static int __init __init_blk_tracer(void) { if (!register_trace_event(&trace_blk_event)) { pr_warn("Warning: could not register block events\n"); @@ -1852,6 +1856,25 @@ static int __init init_blk_tracer(void) return 0; } +static void __init blktrace_works_func(struct work_struct *work) +{ + __init_blk_tracer(); +} + +static int __init init_blk_tracer(void) +{ + int ret = 0; + + if (trace_init_wq) { + INIT_WORK(&blktrace_works, blktrace_works_func); + queue_work(trace_init_wq, &blktrace_works); + } else { + ret = __init_blk_tracer(); + } + + return ret; +} + device_initcall(init_blk_tracer); static int blk_trace_remove_queue(struct request_queue *q) @@ -1880,7 +1903,7 @@ static int blk_trace_setup_queue(struct request_queue *q, struct blk_trace *bt = NULL; int ret = -ENOMEM; - bt = kzalloc(sizeof(*bt), GFP_KERNEL); + bt = kzalloc_obj(*bt); if (!bt) return -ENOMEM; @@ -2020,7 +2043,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, struct blk_trace *bt; ssize_t ret = -ENXIO; - mutex_lock(&q->debugfs_mutex); + blk_debugfs_lock_nomemsave(q); bt = rcu_dereference_protected(q->blk_trace, lockdep_is_held(&q->debugfs_mutex)); @@ -2041,7 +2064,7 @@ static ssize_t sysfs_blk_trace_attr_show(struct device *dev, ret = sprintf(buf, "%llu\n", bt->end_lba); out_unlock_bdev: - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock_nomemrestore(q); return ret; } @@ -2052,6 +2075,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, struct block_device *bdev = dev_to_bdev(dev); struct request_queue *q = bdev_get_queue(bdev); struct blk_trace *bt; + unsigned int memflags; u64 value; ssize_t ret = -EINVAL; @@ -2071,7 +2095,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, goto out; } - mutex_lock(&q->debugfs_mutex); + memflags = blk_debugfs_lock(q); bt = rcu_dereference_protected(q->blk_trace, lockdep_is_held(&q->debugfs_mutex)); @@ -2106,7 +2130,7 @@ static ssize_t sysfs_blk_trace_attr_store(struct device *dev, } out_unlock_bdev: - mutex_unlock(&q->debugfs_mutex); + blk_debugfs_unlock(q, memflags); out: return ret ? ret : count; } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index f7baeb8278ca..0b040a417442 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -2076,7 +2076,7 @@ void __bpf_trace_run(struct bpf_raw_tp_link *link, u64 *args) struct bpf_run_ctx *old_run_ctx; struct bpf_trace_run_ctx run_ctx; - cant_sleep(); + rcu_read_lock_dont_migrate(); if (unlikely(!bpf_prog_get_recursion_context(prog))) { bpf_prog_inc_misses_counter(prog); goto out; @@ -2085,13 +2085,12 @@ void __bpf_trace_run(struct bpf_raw_tp_link *link, u64 *args) run_ctx.bpf_cookie = link->cookie; old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx); - rcu_read_lock(); (void) bpf_prog_run(prog, args); - rcu_read_unlock(); bpf_reset_run_ctx(old_run_ctx); out: bpf_prog_put_recursion_context(prog); + rcu_read_unlock_migrate(); } #define UNPACK(...) __VA_ARGS__ @@ -2244,7 +2243,7 @@ static int bpf_event_notify(struct notifier_block *nb, unsigned long op, switch (op) { case MODULE_STATE_COMING: - btm = kzalloc(sizeof(*btm), GFP_KERNEL); + btm = kzalloc_obj(*btm); if (btm) { btm->module = module; list_add(&btm->list, &bpf_trace_modules); @@ -2455,8 +2454,10 @@ static void bpf_kprobe_multi_show_fdinfo(const struct bpf_link *link, struct seq_file *seq) { struct bpf_kprobe_multi_link *kmulti_link; + bool has_cookies; kmulti_link = container_of(link, struct bpf_kprobe_multi_link, link); + has_cookies = !!kmulti_link->cookies; seq_printf(seq, "kprobe_cnt:\t%u\n" @@ -2468,7 +2469,7 @@ static void bpf_kprobe_multi_show_fdinfo(const struct bpf_link *link, for (int i = 0; i < kmulti_link->cnt; i++) { seq_printf(seq, "%llu\t %pS\n", - kmulti_link->cookies[i], + has_cookies ? kmulti_link->cookies[i] : 0, (void *)kmulti_link->addrs[i]); } } @@ -2820,7 +2821,7 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr goto error; } - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) { err = -ENOMEM; goto error; @@ -3239,8 +3240,8 @@ int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *pr err = -ENOMEM; - link = kzalloc(sizeof(*link), GFP_KERNEL); - uprobes = kvcalloc(cnt, sizeof(*uprobes), GFP_KERNEL); + link = kzalloc_obj(*link); + uprobes = kvzalloc_objs(*uprobes, cnt); if (!uprobes || !link) goto error_free; diff --git a/kernel/trace/fgraph.c b/kernel/trace/fgraph.c index cc48d16be43e..40d373d65f9b 100644 --- a/kernel/trace/fgraph.c +++ b/kernel/trace/fgraph.c @@ -539,7 +539,11 @@ static struct fgraph_ops fgraph_stub = { static struct fgraph_ops *fgraph_direct_gops = &fgraph_stub; DEFINE_STATIC_CALL(fgraph_func, ftrace_graph_entry_stub); DEFINE_STATIC_CALL(fgraph_retfunc, ftrace_graph_ret_stub); +#if FGRAPH_NO_DIRECT +static DEFINE_STATIC_KEY_FALSE(fgraph_do_direct); +#else static DEFINE_STATIC_KEY_TRUE(fgraph_do_direct); +#endif /** * ftrace_graph_stop - set to permanently disable function graph tracing @@ -843,7 +847,7 @@ __ftrace_return_to_handler(struct ftrace_regs *fregs, unsigned long frame_pointe bitmap = get_bitmap_bits(current, offset); #ifdef CONFIG_HAVE_STATIC_CALL - if (static_branch_likely(&fgraph_do_direct)) { + if (!FGRAPH_NO_DIRECT && static_branch_likely(&fgraph_do_direct)) { if (test_bit(fgraph_direct_gops->idx, &bitmap)) static_call(fgraph_retfunc)(&trace, fgraph_direct_gops, fregs); } else @@ -1285,6 +1289,9 @@ static void ftrace_graph_enable_direct(bool enable_branch, struct fgraph_ops *go trace_func_graph_ret_t retfunc = NULL; int i; + if (FGRAPH_NO_DIRECT) + return; + if (gops) { func = gops->entryfunc; retfunc = gops->retfunc; @@ -1303,11 +1310,14 @@ static void ftrace_graph_enable_direct(bool enable_branch, struct fgraph_ops *go static_call_update(fgraph_func, func); static_call_update(fgraph_retfunc, retfunc); if (enable_branch) - static_branch_disable(&fgraph_do_direct); + static_branch_enable(&fgraph_do_direct); } static void ftrace_graph_disable_direct(bool disable_branch) { + if (FGRAPH_NO_DIRECT) + return; + if (disable_branch) static_branch_disable(&fgraph_do_direct); static_call_update(fgraph_func, ftrace_graph_entry_stub); diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index 1188eefef07c..dcadf1d23b8a 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -749,7 +749,7 @@ static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num) return -E2BIG; fp->entry_data_size = size; - hlist_array = kzalloc(struct_size(hlist_array, array, num), GFP_KERNEL); + hlist_array = kzalloc_flex(*hlist_array, array, num); if (!hlist_array) return -ENOMEM; @@ -805,7 +805,7 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter if (!addrs) return -ENOMEM; - mods = kcalloc(num, sizeof(*mods), GFP_KERNEL); + mods = kzalloc_objs(*mods, num); if (!mods) return -ENOMEM; diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 8fb38722fd5c..8df69e702706 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -702,7 +702,7 @@ static int ftrace_profile_init_cpu(int cpu) */ size = FTRACE_PROFILE_HASH_SIZE; - stat->hash = kcalloc(size, sizeof(struct hlist_head), GFP_KERNEL); + stat->hash = kzalloc_objs(struct hlist_head, size); if (!stat->hash) return -ENOMEM; @@ -1147,6 +1147,7 @@ struct ftrace_page { }; #define ENTRY_SIZE sizeof(struct dyn_ftrace) +#define ENTRIES_PER_PAGE_GROUP(order) ((PAGE_SIZE << (order)) / ENTRY_SIZE) static struct ftrace_page *ftrace_pages_start; static struct ftrace_page *ftrace_pages; @@ -1214,7 +1215,7 @@ add_ftrace_hash_entry_direct(struct ftrace_hash *hash, unsigned long ip, unsigne { struct ftrace_func_entry *entry; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return NULL; @@ -1334,12 +1335,12 @@ struct ftrace_hash *alloc_ftrace_hash(int size_bits) struct ftrace_hash *hash; int size; - hash = kzalloc(sizeof(*hash), GFP_KERNEL); + hash = kzalloc_obj(*hash); if (!hash) return NULL; size = 1 << size_bits; - hash->buckets = kcalloc(size, sizeof(*hash->buckets), GFP_KERNEL); + hash->buckets = kzalloc_objs(*hash->buckets, size); if (!hash->buckets) { kfree(hash); @@ -1359,7 +1360,7 @@ static int ftrace_add_mod(struct trace_array *tr, struct ftrace_mod_load *ftrace_mod; struct list_head *mod_head = enable ? &tr->mod_trace : &tr->mod_notrace; - ftrace_mod = kzalloc(sizeof(*ftrace_mod), GFP_KERNEL); + ftrace_mod = kzalloc_obj(*ftrace_mod); if (!ftrace_mod) return -ENOMEM; @@ -3873,7 +3874,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count, *num_pages += 1 << order; ftrace_number_of_groups++; - cnt = (PAGE_SIZE << order) / ENTRY_SIZE; + cnt = ENTRIES_PER_PAGE_GROUP(order); pg->order = order; if (cnt > count) @@ -3910,7 +3911,7 @@ ftrace_allocate_pages(unsigned long num_to_init, unsigned long *num_pages) if (!num_to_init) return NULL; - start_pg = pg = kzalloc(sizeof(*pg), GFP_KERNEL); + start_pg = pg = kzalloc_obj(*pg); if (!pg) return NULL; @@ -3928,7 +3929,7 @@ ftrace_allocate_pages(unsigned long num_to_init, unsigned long *num_pages) if (!num_to_init) break; - pg->next = kzalloc(sizeof(*pg), GFP_KERNEL); + pg->next = kzalloc_obj(*pg); if (!pg->next) goto free_pages; @@ -4685,7 +4686,7 @@ ftrace_regex_open(struct ftrace_ops *ops, int flag, if (tracing_check_open_get_tr(tr)) return -ENODEV; - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc_obj(*iter); if (!iter) goto out; @@ -5333,7 +5334,7 @@ int ftrace_func_mapper_add_ip(struct ftrace_func_mapper *mapper, if (entry) return -EBUSY; - map = kmalloc(sizeof(*map), GFP_KERNEL); + map = kmalloc_obj(*map); if (!map) return -ENOMEM; @@ -5473,7 +5474,7 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr, } } if (!probe) { - probe = kzalloc(sizeof(*probe), GFP_KERNEL); + probe = kzalloc_obj(*probe); if (!probe) { mutex_unlock(&ftrace_lock); return -ENOMEM; @@ -6403,6 +6404,7 @@ int update_ftrace_direct_add(struct ftrace_ops *ops, struct ftrace_hash *hash) new_filter_hash = old_filter_hash; } } else { + guard(mutex)(&ftrace_lock); err = ftrace_update_ops(ops, new_filter_hash, EMPTY_HASH); /* * new_filter_hash is dup-ed, so we need to release it anyway, @@ -6529,6 +6531,7 @@ int update_ftrace_direct_del(struct ftrace_ops *ops, struct ftrace_hash *hash) ops->func_hash->filter_hash = NULL; } } else { + guard(mutex)(&ftrace_lock); err = ftrace_update_ops(ops, new_filter_hash, EMPTY_HASH); /* * new_filter_hash is dup-ed, so we need to release it anyway, @@ -7222,7 +7225,7 @@ ftrace_graph_open(struct inode *inode, struct file *file) if (unlikely(ftrace_disabled)) return -ENODEV; - fgd = kmalloc(sizeof(*fgd), GFP_KERNEL); + fgd = kmalloc_obj(*fgd); if (fgd == NULL) return -ENOMEM; @@ -7250,7 +7253,7 @@ ftrace_graph_notrace_open(struct inode *inode, struct file *file) if (unlikely(ftrace_disabled)) return -ENODEV; - fgd = kmalloc(sizeof(*fgd), GFP_KERNEL); + fgd = kmalloc_obj(*fgd); if (fgd == NULL) return -ENOMEM; @@ -7668,7 +7671,7 @@ static int ftrace_process_locs(struct module *mod, long skip; /* Count the number of entries unused and compare it to skipped. */ - pg_remaining = (PAGE_SIZE << pg->order) / ENTRY_SIZE - pg->index; + pg_remaining = ENTRIES_PER_PAGE_GROUP(pg->order) - pg->index; if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) { @@ -7676,7 +7679,7 @@ static int ftrace_process_locs(struct module *mod, for (pg = pg_unuse; pg && skip > 0; pg = pg->next) { remaining += 1 << pg->order; - skip -= (PAGE_SIZE << pg->order) / ENTRY_SIZE; + skip -= ENTRIES_PER_PAGE_GROUP(pg->order); } pages -= remaining; @@ -8040,7 +8043,7 @@ static void save_ftrace_mod_rec(struct ftrace_mod_map *mod_map, if (!ret) return; - mod_func = kmalloc(sizeof(*mod_func), GFP_KERNEL); + mod_func = kmalloc_obj(*mod_func); if (!mod_func) return; @@ -8067,7 +8070,7 @@ allocate_ftrace_mod_map(struct module *mod, if (ftrace_disabled) return NULL; - mod_map = kmalloc(sizeof(*mod_map), GFP_KERNEL); + mod_map = kmalloc_obj(*mod_map); if (!mod_map) return NULL; @@ -8240,7 +8243,7 @@ static void add_to_clear_hash_list(struct list_head *clear_list, { struct ftrace_init_func *func; - func = kmalloc(sizeof(*func), GFP_KERNEL); + func = kmalloc_obj(*func); if (!func) { MEM_FAIL(1, "alloc failure, ftrace filter could be stale\n"); return; @@ -8610,6 +8613,7 @@ ftrace_pid_follow_sched_process_fork(void *data, struct trace_pid_list *pid_list; struct trace_array *tr = data; + guard(preempt)(); pid_list = rcu_dereference_sched(tr->function_pids); trace_filter_add_remove_task(pid_list, self, task); @@ -8623,6 +8627,7 @@ ftrace_pid_follow_sched_process_exit(void *data, struct task_struct *task) struct trace_pid_list *pid_list; struct trace_array *tr = data; + guard(preempt)(); pid_list = rcu_dereference_sched(tr->function_pids); trace_filter_add_remove_task(pid_list, NULL, task); diff --git a/kernel/trace/pid_list.c b/kernel/trace/pid_list.c index dbee72d69d0a..30e3fdae6a17 100644 --- a/kernel/trace/pid_list.c +++ b/kernel/trace/pid_list.c @@ -359,7 +359,7 @@ static void pid_list_refill_irq(struct irq_work *iwork) while (upper_count-- > 0) { union upper_chunk *chunk; - chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + chunk = kzalloc_obj(*chunk, GFP_NOWAIT); if (!chunk) break; *upper_next = chunk; @@ -370,7 +370,7 @@ static void pid_list_refill_irq(struct irq_work *iwork) while (lower_count-- > 0) { union lower_chunk *chunk; - chunk = kzalloc(sizeof(*chunk), GFP_NOWAIT); + chunk = kzalloc_obj(*chunk, GFP_NOWAIT); if (!chunk) break; *lower_next = chunk; @@ -423,7 +423,7 @@ struct trace_pid_list *trace_pid_list_alloc(void) /* According to linux/thread.h, pids can be no bigger that 30 bits */ WARN_ON_ONCE(init_pid_ns.pid_max > (1 << 30)); - pid_list = kzalloc(sizeof(*pid_list), GFP_KERNEL); + pid_list = kzalloc_obj(*pid_list); if (!pid_list) return NULL; @@ -435,7 +435,7 @@ struct trace_pid_list *trace_pid_list_alloc(void) for (i = 0; i < CHUNK_ALLOC; i++) { union upper_chunk *chunk; - chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); + chunk = kzalloc_obj(*chunk); if (!chunk) break; chunk->next = pid_list->upper_list; @@ -446,7 +446,7 @@ struct trace_pid_list *trace_pid_list_alloc(void) for (i = 0; i < CHUNK_ALLOC; i++) { union lower_chunk *chunk; - chunk = kzalloc(sizeof(*chunk), GFP_KERNEL); + chunk = kzalloc_obj(*chunk); if (!chunk) break; chunk->next = pid_list->lower_list; diff --git a/kernel/trace/rethook.c b/kernel/trace/rethook.c index 30d224946881..5a8bdf88999a 100644 --- a/kernel/trace/rethook.c +++ b/kernel/trace/rethook.c @@ -108,7 +108,7 @@ struct rethook *rethook_alloc(void *data, rethook_handler_t handler, if (!handler || num <= 0 || size < sizeof(struct rethook_node)) return ERR_PTR(-EINVAL); - rh = kzalloc(sizeof(struct rethook), GFP_KERNEL); + rh = kzalloc_obj(struct rethook); if (!rh) return ERR_PTR(-ENOMEM); diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 630221b00838..17d0ea0cc3e6 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c @@ -4,6 +4,7 @@ * * Copyright (C) 2008 Steven Rostedt */ +#include #include #include #include @@ -1848,6 +1849,7 @@ static int rb_read_data_buffer(struct buffer_data_page *dpage, int tail, int cpu struct ring_buffer_event *event; u64 ts, delta; int events = 0; + int len; int e; *delta_ptr = 0; @@ -1855,9 +1857,12 @@ static int rb_read_data_buffer(struct buffer_data_page *dpage, int tail, int cpu ts = dpage->time_stamp; - for (e = 0; e < tail; e += rb_event_length(event)) { + for (e = 0; e < tail; e += len) { event = (struct ring_buffer_event *)(dpage->data + e); + len = rb_event_length(event); + if (len <= 0 || len > tail - e) + return -1; switch (event->type_len) { @@ -1918,6 +1923,8 @@ static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer) if (!meta || !meta->head_buffer) return; + orig_head = head_page = cpu_buffer->head_page; + /* Do the reader page first */ ret = rb_validate_buffer(cpu_buffer->reader_page->page, cpu_buffer->cpu); if (ret < 0) { @@ -1928,7 +1935,6 @@ static void rb_meta_validate_events(struct ring_buffer_per_cpu *cpu_buffer) entry_bytes += local_read(&cpu_buffer->reader_page->page->commit); local_set(&cpu_buffer->reader_page->entries, ret); - orig_head = head_page = cpu_buffer->head_page; ts = head_page->page->time_stamp; /* @@ -4013,19 +4019,36 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer) rb_end_commit(cpu_buffer); } +static bool +rb_irq_work_queue(struct rb_irq_work *irq_work) +{ + int cpu; + + /* irq_work_queue_on() is not NMI-safe */ + if (unlikely(in_nmi())) + return irq_work_queue(&irq_work->work); + + /* + * If CPU isolation is not active, cpu is always the current + * CPU, and the following is equivallent to irq_work_queue(). + */ + cpu = housekeeping_any_cpu(HK_TYPE_KERNEL_NOISE); + return irq_work_queue_on(&irq_work->work, cpu); +} + static __always_inline void rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) { if (buffer->irq_work.waiters_pending) { buffer->irq_work.waiters_pending = false; /* irq_work_queue() supplies it's own memory barriers */ - irq_work_queue(&buffer->irq_work.work); + rb_irq_work_queue(&buffer->irq_work); } if (cpu_buffer->irq_work.waiters_pending) { cpu_buffer->irq_work.waiters_pending = false; /* irq_work_queue() supplies it's own memory barriers */ - irq_work_queue(&cpu_buffer->irq_work.work); + rb_irq_work_queue(&cpu_buffer->irq_work); } if (cpu_buffer->last_pages_touch == local_read(&cpu_buffer->pages_touched)) @@ -4045,7 +4068,7 @@ rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer) cpu_buffer->irq_work.wakeup_full = true; cpu_buffer->irq_work.full_waiters_pending = false; /* irq_work_queue() supplies it's own memory barriers */ - irq_work_queue(&cpu_buffer->irq_work.work); + rb_irq_work_queue(&cpu_buffer->irq_work); } #ifdef CONFIG_RING_BUFFER_RECORD_RECURSION @@ -5978,7 +6001,7 @@ ring_buffer_read_start(struct trace_buffer *buffer, int cpu, gfp_t flags) if (!cpumask_test_cpu(cpu, buffer->cpumask)) return NULL; - iter = kzalloc(sizeof(*iter), flags); + iter = kzalloc_obj(*iter, flags); if (!iter) return NULL; @@ -6486,7 +6509,7 @@ ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu) if (!cpumask_test_cpu(cpu, buffer->cpumask)) return ERR_PTR(-ENODEV); - bpage = kzalloc(sizeof(*bpage), GFP_KERNEL); + bpage = kzalloc_obj(*bpage); if (!bpage) return ERR_PTR(-ENOMEM); @@ -7167,7 +7190,7 @@ static int __rb_map_vma(struct ring_buffer_per_cpu *cpu_buffer, nr_pages = nr_vma_pages; - pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, nr_pages); if (!pages) return -ENOMEM; @@ -7287,6 +7310,27 @@ int ring_buffer_map(struct trace_buffer *buffer, int cpu, return err; } +/* + * This is called when a VMA is duplicated (e.g., on fork()) to increment + * the user_mapped counter without remapping pages. + */ +void ring_buffer_map_dup(struct trace_buffer *buffer, int cpu) +{ + struct ring_buffer_per_cpu *cpu_buffer; + + if (WARN_ON(!cpumask_test_cpu(cpu, buffer->cpumask))) + return; + + cpu_buffer = buffer->buffers[cpu]; + + guard(mutex)(&cpu_buffer->mapping_lock); + + if (cpu_buffer->user_mapped) + __rb_inc_dec_mapped(cpu_buffer, true); + else + WARN(1, "Unexpected buffer stat, it should be mapped"); +} + int ring_buffer_unmap(struct trace_buffer *buffer, int cpu) { struct ring_buffer_per_cpu *cpu_buffer; diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b1cb30a7b83d..ebd996f8710e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -67,7 +67,7 @@ * insertions into the ring-buffer such as trace_printk could occurred * at the same time, giving false positive or negative results. */ -static bool __read_mostly tracing_selftest_running; +bool __read_mostly tracing_selftest_running; /* * If boot-time tracing including tracers/events via kernel cmdline @@ -83,7 +83,6 @@ void __init disable_tracing_selftest(const char *reason) } } #else -#define tracing_selftest_running 0 #define tracing_selftest_disabled 0 #endif @@ -114,7 +113,7 @@ DEFINE_PER_CPU(bool, trace_taskinfo_save); * of the tracer is successful. But that is the only place that sets * this back to zero. */ -static int tracing_disabled = 1; +int tracing_disabled = 1; cpumask_var_t __read_mostly tracing_buffer_mask; @@ -535,22 +534,11 @@ static struct trace_array global_trace = { .trace_flags = TRACE_DEFAULT_FLAGS, }; -static struct trace_array *printk_trace = &global_trace; +struct trace_array *printk_trace = &global_trace; /* List of trace_arrays interested in the top level trace_marker */ static LIST_HEAD(marker_copies); -static __always_inline bool printk_binsafe(struct trace_array *tr) -{ - /* - * The binary format of traceprintk can cause a crash if used - * by a buffer from another boot. Force the use of the - * non binary version of trace_printk if the trace_printk - * buffer is a boot mapped ring buffer. - */ - return !(tr->flags & TRACE_ARRAY_FL_BOOT); -} - static void update_printk_trace(struct trace_array *tr) { if (printk_trace == tr) @@ -649,248 +637,6 @@ int tracing_check_open_get_tr(struct trace_array *tr) return 0; } -/** - * trace_find_filtered_pid - check if a pid exists in a filtered_pid list - * @filtered_pids: The list of pids to check - * @search_pid: The PID to find in @filtered_pids - * - * Returns true if @search_pid is found in @filtered_pids, and false otherwise. - */ -bool -trace_find_filtered_pid(struct trace_pid_list *filtered_pids, pid_t search_pid) -{ - return trace_pid_list_is_set(filtered_pids, search_pid); -} - -/** - * trace_ignore_this_task - should a task be ignored for tracing - * @filtered_pids: The list of pids to check - * @filtered_no_pids: The list of pids not to be traced - * @task: The task that should be ignored if not filtered - * - * Checks if @task should be traced or not from @filtered_pids. - * Returns true if @task should *NOT* be traced. - * Returns false if @task should be traced. - */ -bool -trace_ignore_this_task(struct trace_pid_list *filtered_pids, - struct trace_pid_list *filtered_no_pids, - struct task_struct *task) -{ - /* - * If filtered_no_pids is not empty, and the task's pid is listed - * in filtered_no_pids, then return true. - * Otherwise, if filtered_pids is empty, that means we can - * trace all tasks. If it has content, then only trace pids - * within filtered_pids. - */ - - return (filtered_pids && - !trace_find_filtered_pid(filtered_pids, task->pid)) || - (filtered_no_pids && - trace_find_filtered_pid(filtered_no_pids, task->pid)); -} - -/** - * trace_filter_add_remove_task - Add or remove a task from a pid_list - * @pid_list: The list to modify - * @self: The current task for fork or NULL for exit - * @task: The task to add or remove - * - * If adding a task, if @self is defined, the task is only added if @self - * is also included in @pid_list. This happens on fork and tasks should - * only be added when the parent is listed. If @self is NULL, then the - * @task pid will be removed from the list, which would happen on exit - * of a task. - */ -void trace_filter_add_remove_task(struct trace_pid_list *pid_list, - struct task_struct *self, - struct task_struct *task) -{ - if (!pid_list) - return; - - /* For forks, we only add if the forking task is listed */ - if (self) { - if (!trace_find_filtered_pid(pid_list, self->pid)) - return; - } - - /* "self" is set for forks, and NULL for exits */ - if (self) - trace_pid_list_set(pid_list, task->pid); - else - trace_pid_list_clear(pid_list, task->pid); -} - -/** - * trace_pid_next - Used for seq_file to get to the next pid of a pid_list - * @pid_list: The pid list to show - * @v: The last pid that was shown (+1 the actual pid to let zero be displayed) - * @pos: The position of the file - * - * This is used by the seq_file "next" operation to iterate the pids - * listed in a trace_pid_list structure. - * - * Returns the pid+1 as we want to display pid of zero, but NULL would - * stop the iteration. - */ -void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos) -{ - long pid = (unsigned long)v; - unsigned int next; - - (*pos)++; - - /* pid already is +1 of the actual previous bit */ - if (trace_pid_list_next(pid_list, pid, &next) < 0) - return NULL; - - pid = next; - - /* Return pid + 1 to allow zero to be represented */ - return (void *)(pid + 1); -} - -/** - * trace_pid_start - Used for seq_file to start reading pid lists - * @pid_list: The pid list to show - * @pos: The position of the file - * - * This is used by seq_file "start" operation to start the iteration - * of listing pids. - * - * Returns the pid+1 as we want to display pid of zero, but NULL would - * stop the iteration. - */ -void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos) -{ - unsigned long pid; - unsigned int first; - loff_t l = 0; - - if (trace_pid_list_first(pid_list, &first) < 0) - return NULL; - - pid = first; - - /* Return pid + 1 so that zero can be the exit value */ - for (pid++; pid && l < *pos; - pid = (unsigned long)trace_pid_next(pid_list, (void *)pid, &l)) - ; - return (void *)pid; -} - -/** - * trace_pid_show - show the current pid in seq_file processing - * @m: The seq_file structure to write into - * @v: A void pointer of the pid (+1) value to display - * - * Can be directly used by seq_file operations to display the current - * pid value. - */ -int trace_pid_show(struct seq_file *m, void *v) -{ - unsigned long pid = (unsigned long)v - 1; - - seq_printf(m, "%lu\n", pid); - return 0; -} - -/* 128 should be much more than enough */ -#define PID_BUF_SIZE 127 - -int trace_pid_write(struct trace_pid_list *filtered_pids, - struct trace_pid_list **new_pid_list, - const char __user *ubuf, size_t cnt) -{ - struct trace_pid_list *pid_list; - struct trace_parser parser; - unsigned long val; - int nr_pids = 0; - ssize_t read = 0; - ssize_t ret; - loff_t pos; - pid_t pid; - - if (trace_parser_get_init(&parser, PID_BUF_SIZE + 1)) - return -ENOMEM; - - /* - * Always recreate a new array. The write is an all or nothing - * operation. Always create a new array when adding new pids by - * the user. If the operation fails, then the current list is - * not modified. - */ - pid_list = trace_pid_list_alloc(); - if (!pid_list) { - trace_parser_put(&parser); - return -ENOMEM; - } - - if (filtered_pids) { - /* copy the current bits to the new max */ - ret = trace_pid_list_first(filtered_pids, &pid); - while (!ret) { - ret = trace_pid_list_set(pid_list, pid); - if (ret < 0) - goto out; - - ret = trace_pid_list_next(filtered_pids, pid + 1, &pid); - nr_pids++; - } - } - - ret = 0; - while (cnt > 0) { - - pos = 0; - - ret = trace_get_user(&parser, ubuf, cnt, &pos); - if (ret < 0) - break; - - read += ret; - ubuf += ret; - cnt -= ret; - - if (!trace_parser_loaded(&parser)) - break; - - ret = -EINVAL; - if (kstrtoul(parser.buffer, 0, &val)) - break; - - pid = (pid_t)val; - - if (trace_pid_list_set(pid_list, pid) < 0) { - ret = -1; - break; - } - nr_pids++; - - trace_parser_clear(&parser); - ret = 0; - } - out: - trace_parser_put(&parser); - - if (ret < 0) { - trace_pid_list_free(pid_list); - return ret; - } - - if (!nr_pids) { - /* Cleared the list of pids */ - trace_pid_list_free(pid_list); - pid_list = NULL; - } - - *new_pid_list = pid_list; - - return read; -} - static u64 buffer_ftrace_now(struct array_buffer *buf, int cpu) { u64 ts; @@ -1033,56 +779,6 @@ static inline void trace_access_lock_init(void) #endif -#ifdef CONFIG_STACKTRACE -static void __ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned int trace_ctx, - int skip, struct pt_regs *regs); -static inline void ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned int trace_ctx, - int skip, struct pt_regs *regs); - -#else -static inline void __ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned int trace_ctx, - int skip, struct pt_regs *regs) -{ -} -static inline void ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned long trace_ctx, - int skip, struct pt_regs *regs) -{ -} - -#endif - -static __always_inline void -trace_event_setup(struct ring_buffer_event *event, - int type, unsigned int trace_ctx) -{ - struct trace_entry *ent = ring_buffer_event_data(event); - - tracing_generic_entry_update(ent, type, trace_ctx); -} - -static __always_inline struct ring_buffer_event * -__trace_buffer_lock_reserve(struct trace_buffer *buffer, - int type, - unsigned long len, - unsigned int trace_ctx) -{ - struct ring_buffer_event *event; - - event = ring_buffer_lock_reserve(buffer, len); - if (event != NULL) - trace_event_setup(event, type, trace_ctx); - - return event; -} - void tracer_tracing_on(struct trace_array *tr) { if (tr->array_buffer.buffer) @@ -1110,129 +806,10 @@ void tracing_on(void) } EXPORT_SYMBOL_GPL(tracing_on); - -static __always_inline void -__buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *event) -{ - __this_cpu_write(trace_taskinfo_save, true); - - /* If this is the temp buffer, we need to commit fully */ - if (this_cpu_read(trace_buffered_event) == event) { - /* Length is in event->array[0] */ - ring_buffer_write(buffer, event->array[0], &event->array[1]); - /* Release the temp buffer */ - this_cpu_dec(trace_buffered_event_cnt); - /* ring_buffer_unlock_commit() enables preemption */ - preempt_enable_notrace(); - } else - ring_buffer_unlock_commit(buffer); -} - -int __trace_array_puts(struct trace_array *tr, unsigned long ip, - const char *str, int size) -{ - struct ring_buffer_event *event; - struct trace_buffer *buffer; - struct print_entry *entry; - unsigned int trace_ctx; - int alloc; - - if (!(tr->trace_flags & TRACE_ITER(PRINTK))) - return 0; - - if (unlikely(tracing_selftest_running && tr == &global_trace)) - return 0; - - if (unlikely(tracing_disabled)) - return 0; - - alloc = sizeof(*entry) + size + 2; /* possible \n added */ - - trace_ctx = tracing_gen_ctx(); - buffer = tr->array_buffer.buffer; - guard(ring_buffer_nest)(buffer); - event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, - trace_ctx); - if (!event) - return 0; - - entry = ring_buffer_event_data(event); - entry->ip = ip; - - memcpy(&entry->buf, str, size); - - /* Add a newline if necessary */ - if (entry->buf[size - 1] != '\n') { - entry->buf[size] = '\n'; - entry->buf[size + 1] = '\0'; - } else - entry->buf[size] = '\0'; - - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); - return size; -} -EXPORT_SYMBOL_GPL(__trace_array_puts); - -/** - * __trace_puts - write a constant string into the trace buffer. - * @ip: The address of the caller - * @str: The constant string to write - */ -int __trace_puts(unsigned long ip, const char *str) -{ - return __trace_array_puts(printk_trace, ip, str, strlen(str)); -} -EXPORT_SYMBOL_GPL(__trace_puts); - -/** - * __trace_bputs - write the pointer to a constant string into trace buffer - * @ip: The address of the caller - * @str: The constant string to write to the buffer to - */ -int __trace_bputs(unsigned long ip, const char *str) -{ - struct trace_array *tr = READ_ONCE(printk_trace); - struct ring_buffer_event *event; - struct trace_buffer *buffer; - struct bputs_entry *entry; - unsigned int trace_ctx; - int size = sizeof(struct bputs_entry); - - if (!printk_binsafe(tr)) - return __trace_puts(ip, str); - - if (!(tr->trace_flags & TRACE_ITER(PRINTK))) - return 0; - - if (unlikely(tracing_selftest_running || tracing_disabled)) - return 0; - - trace_ctx = tracing_gen_ctx(); - buffer = tr->array_buffer.buffer; - - guard(ring_buffer_nest)(buffer); - event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, - trace_ctx); - if (!event) - return 0; - - entry = ring_buffer_event_data(event); - entry->ip = ip; - entry->str = str; - - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); - - return 1; -} -EXPORT_SYMBOL_GPL(__trace_bputs); - #ifdef CONFIG_TRACER_SNAPSHOT static void tracing_snapshot_instance_cond(struct trace_array *tr, void *cond_data) { - struct tracer *tracer = tr->current_trace; unsigned long flags; if (in_nmi()) { @@ -1248,15 +825,15 @@ static void tracing_snapshot_instance_cond(struct trace_array *tr, return; } - /* Note, snapshot can not be used when the tracer uses it */ - if (tracer->use_max_tr) { - trace_array_puts(tr, "*** LATENCY TRACER ACTIVE ***\n"); + if (tr->mapped) { + trace_array_puts(tr, "*** BUFFER MEMORY MAPPED ***\n"); trace_array_puts(tr, "*** Can not use snapshot (sorry) ***\n"); return; } - if (tr->mapped) { - trace_array_puts(tr, "*** BUFFER MEMORY MAPPED ***\n"); + /* Note, snapshot can not be used when the tracer uses it */ + if (tracer_uses_snapshot(tr->current_trace)) { + trace_array_puts(tr, "*** LATENCY TRACER ACTIVE ***\n"); trace_array_puts(tr, "*** Can not use snapshot (sorry) ***\n"); return; } @@ -1356,12 +933,12 @@ int tracing_alloc_snapshot_instance(struct trace_array *tr) /* Make the snapshot buffer have the same order as main buffer */ order = ring_buffer_subbuf_order_get(tr->array_buffer.buffer); - ret = ring_buffer_subbuf_order_set(tr->max_buffer.buffer, order); + ret = ring_buffer_subbuf_order_set(tr->snapshot_buffer.buffer, order); if (ret < 0) return ret; /* allocate spare buffer */ - ret = resize_buffer_duplicate_size(&tr->max_buffer, + ret = resize_buffer_duplicate_size(&tr->snapshot_buffer, &tr->array_buffer, RING_BUFFER_ALL_CPUS); if (ret < 0) return ret; @@ -1379,10 +956,10 @@ static void free_snapshot(struct trace_array *tr) * The max_tr ring buffer has some state (e.g. ring->clock) and * we want preserve it. */ - ring_buffer_subbuf_order_set(tr->max_buffer.buffer, 0); - ring_buffer_resize(tr->max_buffer.buffer, 1, RING_BUFFER_ALL_CPUS); - set_buffer_entries(&tr->max_buffer, 1); - tracing_reset_online_cpus(&tr->max_buffer); + ring_buffer_subbuf_order_set(tr->snapshot_buffer.buffer, 0); + ring_buffer_resize(tr->snapshot_buffer.buffer, 1, RING_BUFFER_ALL_CPUS); + set_buffer_entries(&tr->snapshot_buffer, 1); + tracing_reset_online_cpus(&tr->snapshot_buffer); tr->allocated_snapshot = false; } @@ -1487,7 +1064,7 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data, cond_update_fn_t update) { struct cond_snapshot *cond_snapshot __free(kfree) = - kzalloc(sizeof(*cond_snapshot), GFP_KERNEL); + kzalloc_obj(*cond_snapshot); int ret; if (!cond_snapshot) @@ -1498,7 +1075,7 @@ int tracing_snapshot_cond_enable(struct trace_array *tr, void *cond_data, guard(mutex)(&trace_types_lock); - if (tr->current_trace->use_max_tr) + if (tracer_uses_snapshot(tr->current_trace)) return -EBUSY; /* @@ -1665,9 +1242,18 @@ EXPORT_SYMBOL_GPL(tracing_off); void disable_trace_on_warning(void) { if (__disable_trace_on_warning) { + struct trace_array *tr = READ_ONCE(printk_trace); + trace_array_printk_buf(global_trace.array_buffer.buffer, _THIS_IP_, "Disabling tracing due to warning\n"); tracing_off(); + + /* Disable trace_printk() buffer too */ + if (tr != &global_trace) { + trace_array_printk_buf(tr->array_buffer.buffer, _THIS_IP_, + "Disabling tracing due to warning\n"); + tracer_tracing_off(tr); + } } } @@ -1902,10 +1488,7 @@ static ssize_t trace_seq_to_buffer(struct trace_seq *s, void *buf, size_t cnt) unsigned long __read_mostly tracing_thresh; #ifdef CONFIG_TRACER_MAX_TRACE -static const struct file_operations tracing_max_lat_fops; - #ifdef LATENCY_FS_NOTIFY - static struct workqueue_struct *fsnotify_wq; static void latency_fsnotify_workfn(struct work_struct *work) @@ -1922,17 +1505,6 @@ static void latency_fsnotify_workfn_irq(struct irq_work *iwork) queue_work(fsnotify_wq, &tr->fsnotify_work); } -static void trace_create_maxlat_file(struct trace_array *tr, - struct dentry *d_tracer) -{ - INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn); - init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); - tr->d_max_latency = trace_create_file("tracing_max_latency", - TRACE_MODE_WRITE, - d_tracer, tr, - &tracing_max_lat_fops); -} - __init static int latency_fsnotify_init(void) { fsnotify_wq = alloc_workqueue("tr_max_lat_wq", @@ -1957,14 +1529,22 @@ void latency_fsnotify(struct trace_array *tr) */ irq_work_queue(&tr->fsnotify_irqwork); } +#endif /* !LATENCY_FS_NOTIFY */ -#else /* !LATENCY_FS_NOTIFY */ - -#define trace_create_maxlat_file(tr, d_tracer) \ - trace_create_file("tracing_max_latency", TRACE_MODE_WRITE, \ - d_tracer, tr, &tracing_max_lat_fops) +static const struct file_operations tracing_max_lat_fops; +static void trace_create_maxlat_file(struct trace_array *tr, + struct dentry *d_tracer) +{ +#ifdef LATENCY_FS_NOTIFY + INIT_WORK(&tr->fsnotify_work, latency_fsnotify_workfn); + init_irq_work(&tr->fsnotify_irqwork, latency_fsnotify_workfn_irq); #endif + tr->d_max_latency = trace_create_file("tracing_max_latency", + TRACE_MODE_WRITE, + d_tracer, tr, + &tracing_max_lat_fops); +} /* * Copy the new maximum trace into the separate maximum-trace @@ -1975,8 +1555,8 @@ static void __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) { struct array_buffer *trace_buf = &tr->array_buffer; - struct array_buffer *max_buf = &tr->max_buffer; struct trace_array_cpu *data = per_cpu_ptr(trace_buf->data, cpu); + struct array_buffer *max_buf = &tr->snapshot_buffer; struct trace_array_cpu *max_data = per_cpu_ptr(max_buf->data, cpu); max_buf->cpu = cpu; @@ -2005,7 +1585,14 @@ __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu) tracing_record_cmdline(tsk); latency_fsnotify(tr); } +#else +static inline void trace_create_maxlat_file(struct trace_array *tr, + struct dentry *d_tracer) { } +static inline void __update_max_tr(struct trace_array *tr, + struct task_struct *tsk, int cpu) { } +#endif /* CONFIG_TRACER_MAX_TRACE */ +#ifdef CONFIG_TRACER_SNAPSHOT /** * update_max_tr - snapshot all trace buffers from global_trace to max_tr * @tr: tracer @@ -2035,17 +1622,16 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu, /* Inherit the recordable setting from array_buffer */ if (ring_buffer_record_is_set_on(tr->array_buffer.buffer)) - ring_buffer_record_on(tr->max_buffer.buffer); + ring_buffer_record_on(tr->snapshot_buffer.buffer); else - ring_buffer_record_off(tr->max_buffer.buffer); + ring_buffer_record_off(tr->snapshot_buffer.buffer); -#ifdef CONFIG_TRACER_SNAPSHOT if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data)) { arch_spin_unlock(&tr->max_lock); return; } -#endif - swap(tr->array_buffer.buffer, tr->max_buffer.buffer); + + swap(tr->array_buffer.buffer, tr->snapshot_buffer.buffer); __update_max_tr(tr, tsk, cpu); @@ -2080,7 +1666,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) arch_spin_lock(&tr->max_lock); - ret = ring_buffer_swap_cpu(tr->max_buffer.buffer, tr->array_buffer.buffer, cpu); + ret = ring_buffer_swap_cpu(tr->snapshot_buffer.buffer, tr->array_buffer.buffer, cpu); if (ret == -EBUSY) { /* @@ -2090,7 +1676,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) * and flag that it failed. * Another reason is resize is in progress. */ - trace_array_printk_buf(tr->max_buffer.buffer, _THIS_IP_, + trace_array_printk_buf(tr->snapshot_buffer.buffer, _THIS_IP_, "Failed to swap buffers due to commit or resize in progress\n"); } @@ -2099,8 +1685,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu) __update_max_tr(tr, tsk, cpu); arch_spin_unlock(&tr->max_lock); } - -#endif /* CONFIG_TRACER_MAX_TRACE */ +#endif /* CONFIG_TRACER_SNAPSHOT */ struct pipe_wait { struct trace_iterator *iter; @@ -2133,13 +1718,13 @@ static int wait_on_pipe(struct trace_iterator *iter, int full) ret = ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file, full, wait_pipe_cond, &pwait); -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT /* * Make sure this is still the snapshot buffer, as if a snapshot were * to happen, this would now be the main buffer. */ if (iter->snapshot) - iter->array_buffer = &iter->tr->max_buffer; + iter->array_buffer = &iter->tr->snapshot_buffer; #endif return ret; } @@ -2204,10 +1789,10 @@ static int run_tracer_selftest(struct tracer *type) tr->current_trace_flags = type->flags ? : type->default_flags; #ifdef CONFIG_TRACER_MAX_TRACE - if (type->use_max_tr) { + if (tracer_uses_snapshot(type)) { /* If we expanded the buffers, make sure the max is expanded too */ if (tr->ring_buffer_expanded) - ring_buffer_resize(tr->max_buffer.buffer, trace_buf_size, + ring_buffer_resize(tr->snapshot_buffer.buffer, trace_buf_size, RING_BUFFER_ALL_CPUS); tr->allocated_snapshot = true; } @@ -2229,12 +1814,12 @@ static int run_tracer_selftest(struct tracer *type) tracing_reset_online_cpus(&tr->array_buffer); #ifdef CONFIG_TRACER_MAX_TRACE - if (type->use_max_tr) { + if (tracer_uses_snapshot(type)) { tr->allocated_snapshot = false; /* Shrink the max buffer again */ if (tr->ring_buffer_expanded) - ring_buffer_resize(tr->max_buffer.buffer, 1, + ring_buffer_resize(tr->snapshot_buffer.buffer, 1, RING_BUFFER_ALL_CPUS); } #endif @@ -2476,8 +2061,8 @@ void tracing_reset_all_online_cpus_unlocked(void) continue; tr->clear_trace = false; tracing_reset_online_cpus(&tr->array_buffer); -#ifdef CONFIG_TRACER_MAX_TRACE - tracing_reset_online_cpus(&tr->max_buffer); +#ifdef CONFIG_TRACER_SNAPSHOT + tracing_reset_online_cpus(&tr->snapshot_buffer); #endif } } @@ -2516,8 +2101,8 @@ static void tracing_start_tr(struct trace_array *tr) if (buffer) ring_buffer_record_enable(buffer); -#ifdef CONFIG_TRACER_MAX_TRACE - buffer = tr->max_buffer.buffer; +#ifdef CONFIG_TRACER_SNAPSHOT + buffer = tr->snapshot_buffer.buffer; if (buffer) ring_buffer_record_enable(buffer); #endif @@ -2552,8 +2137,8 @@ static void tracing_stop_tr(struct trace_array *tr) if (buffer) ring_buffer_record_disable(buffer); -#ifdef CONFIG_TRACER_MAX_TRACE - buffer = tr->max_buffer.buffer; +#ifdef CONFIG_TRACER_SNAPSHOT + buffer = tr->snapshot_buffer.buffer; if (buffer) ring_buffer_record_disable(buffer); #endif @@ -3001,10 +2586,10 @@ struct ftrace_stacks { static DEFINE_PER_CPU(struct ftrace_stacks, ftrace_stacks); static DEFINE_PER_CPU(int, ftrace_stack_reserve); -static void __ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned int trace_ctx, - int skip, struct pt_regs *regs) +void __ftrace_trace_stack(struct trace_array *tr, + struct trace_buffer *buffer, + unsigned int trace_ctx, + int skip, struct pt_regs *regs) { struct ring_buffer_event *event; unsigned int size, nr_entries; @@ -3087,17 +2672,6 @@ static void __ftrace_trace_stack(struct trace_array *tr, trace_clear_recursion(bit); } -static inline void ftrace_trace_stack(struct trace_array *tr, - struct trace_buffer *buffer, - unsigned int trace_ctx, - int skip, struct pt_regs *regs) -{ - if (!(tr->trace_flags & TRACE_ITER(STACKTRACE))) - return; - - __ftrace_trace_stack(tr, buffer, trace_ctx, skip, regs); -} - void __trace_stack(struct trace_array *tr, unsigned int trace_ctx, int skip) { @@ -3232,324 +2806,6 @@ void trace_last_func_repeats(struct trace_array *tr, __buffer_unlock_commit(buffer, event); } -/* created for use with alloc_percpu */ -struct trace_buffer_struct { - int nesting; - char buffer[4][TRACE_BUF_SIZE]; -}; - -static struct trace_buffer_struct __percpu *trace_percpu_buffer; - -/* - * This allows for lockless recording. If we're nested too deeply, then - * this returns NULL. - */ -static char *get_trace_buf(void) -{ - struct trace_buffer_struct *buffer = this_cpu_ptr(trace_percpu_buffer); - - if (!trace_percpu_buffer || buffer->nesting >= 4) - return NULL; - - buffer->nesting++; - - /* Interrupts must see nesting incremented before we use the buffer */ - barrier(); - return &buffer->buffer[buffer->nesting - 1][0]; -} - -static void put_trace_buf(void) -{ - /* Don't let the decrement of nesting leak before this */ - barrier(); - this_cpu_dec(trace_percpu_buffer->nesting); -} - -static int alloc_percpu_trace_buffer(void) -{ - struct trace_buffer_struct __percpu *buffers; - - if (trace_percpu_buffer) - return 0; - - buffers = alloc_percpu(struct trace_buffer_struct); - if (MEM_FAIL(!buffers, "Could not allocate percpu trace_printk buffer")) - return -ENOMEM; - - trace_percpu_buffer = buffers; - return 0; -} - -static int buffers_allocated; - -void trace_printk_init_buffers(void) -{ - if (buffers_allocated) - return; - - if (alloc_percpu_trace_buffer()) - return; - - /* trace_printk() is for debug use only. Don't use it in production. */ - - pr_warn("\n"); - pr_warn("**********************************************************\n"); - pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); - pr_warn("** **\n"); - pr_warn("** trace_printk() being used. Allocating extra memory. **\n"); - pr_warn("** **\n"); - pr_warn("** This means that this is a DEBUG kernel and it is **\n"); - pr_warn("** unsafe for production use. **\n"); - pr_warn("** **\n"); - pr_warn("** If you see this message and you are not debugging **\n"); - pr_warn("** the kernel, report this immediately to your vendor! **\n"); - pr_warn("** **\n"); - pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); - pr_warn("**********************************************************\n"); - - /* Expand the buffers to set size */ - tracing_update_buffers(&global_trace); - - buffers_allocated = 1; - - /* - * trace_printk_init_buffers() can be called by modules. - * If that happens, then we need to start cmdline recording - * directly here. If the global_trace.buffer is already - * allocated here, then this was called by module code. - */ - if (global_trace.array_buffer.buffer) - tracing_start_cmdline_record(); -} -EXPORT_SYMBOL_GPL(trace_printk_init_buffers); - -void trace_printk_start_comm(void) -{ - /* Start tracing comms if trace printk is set */ - if (!buffers_allocated) - return; - tracing_start_cmdline_record(); -} - -static void trace_printk_start_stop_comm(int enabled) -{ - if (!buffers_allocated) - return; - - if (enabled) - tracing_start_cmdline_record(); - else - tracing_stop_cmdline_record(); -} - -/** - * trace_vbprintk - write binary msg to tracing buffer - * @ip: The address of the caller - * @fmt: The string format to write to the buffer - * @args: Arguments for @fmt - */ -int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) -{ - struct ring_buffer_event *event; - struct trace_buffer *buffer; - struct trace_array *tr = READ_ONCE(printk_trace); - struct bprint_entry *entry; - unsigned int trace_ctx; - char *tbuffer; - int len = 0, size; - - if (!printk_binsafe(tr)) - return trace_vprintk(ip, fmt, args); - - if (unlikely(tracing_selftest_running || tracing_disabled)) - return 0; - - /* Don't pollute graph traces with trace_vprintk internals */ - pause_graph_tracing(); - - trace_ctx = tracing_gen_ctx(); - guard(preempt_notrace)(); - - tbuffer = get_trace_buf(); - if (!tbuffer) { - len = 0; - goto out_nobuffer; - } - - len = vbin_printf((u32 *)tbuffer, TRACE_BUF_SIZE/sizeof(int), fmt, args); - - if (len > TRACE_BUF_SIZE/sizeof(int) || len < 0) - goto out_put; - - size = sizeof(*entry) + sizeof(u32) * len; - buffer = tr->array_buffer.buffer; - scoped_guard(ring_buffer_nest, buffer) { - event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, - trace_ctx); - if (!event) - goto out_put; - entry = ring_buffer_event_data(event); - entry->ip = ip; - entry->fmt = fmt; - - memcpy(entry->buf, tbuffer, sizeof(u32) * len); - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(tr, buffer, trace_ctx, 6, NULL); - } -out_put: - put_trace_buf(); - -out_nobuffer: - unpause_graph_tracing(); - - return len; -} -EXPORT_SYMBOL_GPL(trace_vbprintk); - -static __printf(3, 0) -int __trace_array_vprintk(struct trace_buffer *buffer, - unsigned long ip, const char *fmt, va_list args) -{ - struct ring_buffer_event *event; - int len = 0, size; - struct print_entry *entry; - unsigned int trace_ctx; - char *tbuffer; - - if (tracing_disabled) - return 0; - - /* Don't pollute graph traces with trace_vprintk internals */ - pause_graph_tracing(); - - trace_ctx = tracing_gen_ctx(); - guard(preempt_notrace)(); - - - tbuffer = get_trace_buf(); - if (!tbuffer) { - len = 0; - goto out_nobuffer; - } - - len = vscnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); - - size = sizeof(*entry) + len + 1; - scoped_guard(ring_buffer_nest, buffer) { - event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, - trace_ctx); - if (!event) - goto out; - entry = ring_buffer_event_data(event); - entry->ip = ip; - - memcpy(&entry->buf, tbuffer, len + 1); - __buffer_unlock_commit(buffer, event); - ftrace_trace_stack(printk_trace, buffer, trace_ctx, 6, NULL); - } -out: - put_trace_buf(); - -out_nobuffer: - unpause_graph_tracing(); - - return len; -} - -int trace_array_vprintk(struct trace_array *tr, - unsigned long ip, const char *fmt, va_list args) -{ - if (tracing_selftest_running && tr == &global_trace) - return 0; - - return __trace_array_vprintk(tr->array_buffer.buffer, ip, fmt, args); -} - -/** - * trace_array_printk - Print a message to a specific instance - * @tr: The instance trace_array descriptor - * @ip: The instruction pointer that this is called from. - * @fmt: The format to print (printf format) - * - * If a subsystem sets up its own instance, they have the right to - * printk strings into their tracing instance buffer using this - * function. Note, this function will not write into the top level - * buffer (use trace_printk() for that), as writing into the top level - * buffer should only have events that can be individually disabled. - * trace_printk() is only used for debugging a kernel, and should not - * be ever incorporated in normal use. - * - * trace_array_printk() can be used, as it will not add noise to the - * top level tracing buffer. - * - * Note, trace_array_init_printk() must be called on @tr before this - * can be used. - */ -int trace_array_printk(struct trace_array *tr, - unsigned long ip, const char *fmt, ...) -{ - int ret; - va_list ap; - - if (!tr) - return -ENOENT; - - /* This is only allowed for created instances */ - if (tr == &global_trace) - return 0; - - if (!(tr->trace_flags & TRACE_ITER(PRINTK))) - return 0; - - va_start(ap, fmt); - ret = trace_array_vprintk(tr, ip, fmt, ap); - va_end(ap); - return ret; -} -EXPORT_SYMBOL_GPL(trace_array_printk); - -/** - * trace_array_init_printk - Initialize buffers for trace_array_printk() - * @tr: The trace array to initialize the buffers for - * - * As trace_array_printk() only writes into instances, they are OK to - * have in the kernel (unlike trace_printk()). This needs to be called - * before trace_array_printk() can be used on a trace_array. - */ -int trace_array_init_printk(struct trace_array *tr) -{ - if (!tr) - return -ENOENT; - - /* This is only allowed for created instances */ - if (tr == &global_trace) - return -EINVAL; - - return alloc_percpu_trace_buffer(); -} -EXPORT_SYMBOL_GPL(trace_array_init_printk); - -int trace_array_printk_buf(struct trace_buffer *buffer, - unsigned long ip, const char *fmt, ...) -{ - int ret; - va_list ap; - - if (!(printk_trace->trace_flags & TRACE_ITER(PRINTK))) - return 0; - - va_start(ap, fmt); - ret = __trace_array_vprintk(buffer, ip, fmt, ap); - va_end(ap); - return ret; -} - -int trace_vprintk(unsigned long ip, const char *fmt, va_list args) -{ - return trace_array_vprintk(printk_trace, ip, fmt, args); -} -EXPORT_SYMBOL_GPL(trace_vprintk); - static void trace_iterator_increment(struct trace_iterator *iter) { struct ring_buffer_iter *buf_iter = trace_buffer_iter(iter, iter->cpu); @@ -3986,10 +3242,8 @@ static void *s_start(struct seq_file *m, loff_t *pos) } mutex_unlock(&trace_types_lock); -#ifdef CONFIG_TRACER_MAX_TRACE - if (iter->snapshot && iter->trace->use_max_tr) + if (iter->snapshot && tracer_uses_snapshot(iter->trace)) return ERR_PTR(-EBUSY); -#endif if (*pos != iter->pos) { iter->ent = NULL; @@ -4028,10 +3282,8 @@ static void s_stop(struct seq_file *m, void *p) { struct trace_iterator *iter = m->private; -#ifdef CONFIG_TRACER_MAX_TRACE - if (iter->snapshot && iter->trace->use_max_tr) + if (iter->snapshot && tracer_uses_snapshot(iter->trace)) return; -#endif trace_access_unlock(iter->cpu_file); trace_event_read_unlock(); @@ -4285,7 +3537,7 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter) /* ftrace and system call events are still OK */ if ((event->type > __TRACE_LAST_TYPE) && !is_syscall_event(event)) - return print_event_fields(iter, event); + return print_event_fields(iter, event); } return event->funcs->trace(iter, sym_flags, event); } @@ -4508,7 +3760,7 @@ static void test_ftrace_alive(struct seq_file *m) "# MAY BE MISSING FUNCTION EVENTS\n"); } -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT static void show_snapshot_main_help(struct seq_file *m) { seq_puts(m, "# echo 0 > snapshot : Clears and frees snapshot buffer\n" @@ -4651,8 +3903,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) if (!iter) return ERR_PTR(-ENOMEM); - iter->buffer_iter = kcalloc(nr_cpu_ids, sizeof(*iter->buffer_iter), - GFP_KERNEL); + iter->buffer_iter = kzalloc_objs(*iter->buffer_iter, nr_cpu_ids); if (!iter->buffer_iter) goto release; @@ -4686,10 +3937,10 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot) iter->tr = tr; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT /* Currently only the top directory has a snapshot */ if (tr->current_trace->print_max || snapshot) - iter->array_buffer = &tr->max_buffer; + iter->array_buffer = &tr->snapshot_buffer; else #endif iter->array_buffer = &tr->array_buffer; @@ -4758,11 +4009,6 @@ int tracing_open_generic(struct inode *inode, struct file *filp) return 0; } -bool tracing_is_disabled(void) -{ - return (tracing_disabled) ? true: false; -} - /* * Open and update trace_array ref count. * Must have the current trace_array passed to it. @@ -4880,6 +4126,8 @@ static int tracing_single_release_tr(struct inode *inode, struct file *file) return single_release(inode, file); } +static bool update_last_data_if_empty(struct trace_array *tr); + static int tracing_open(struct inode *inode, struct file *file) { struct trace_array *tr = inode->i_private; @@ -4897,13 +4145,15 @@ static int tracing_open(struct inode *inode, struct file *file) #ifdef CONFIG_TRACER_MAX_TRACE if (tr->current_trace->print_max) - trace_buf = &tr->max_buffer; + trace_buf = &tr->snapshot_buffer; #endif if (cpu == RING_BUFFER_ALL_CPUS) tracing_reset_online_cpus(trace_buf); else tracing_reset_cpu(trace_buf, cpu); + + update_last_data_if_empty(tr); } if (file->f_mode & FMODE_READ) { @@ -4928,11 +4178,9 @@ static int tracing_open(struct inode *inode, struct file *file) static bool trace_ok_for_array(struct tracer *t, struct trace_array *tr) { -#ifdef CONFIG_TRACER_SNAPSHOT /* arrays with mapped buffer range do not have snapshots */ - if (tr->range_addr_start && t->use_max_tr) + if (tr->range_addr_start && tracer_uses_snapshot(t)) return false; -#endif return (tr->flags & TRACE_ARRAY_FL_GLOBAL) || t->allow_instances; } @@ -5109,15 +4357,15 @@ int tracing_set_cpumask(struct trace_array *tr, if (cpumask_test_cpu(cpu, tr->tracing_cpumask) && !cpumask_test_cpu(cpu, tracing_cpumask_new)) { ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu); -#ifdef CONFIG_TRACER_MAX_TRACE - ring_buffer_record_disable_cpu(tr->max_buffer.buffer, cpu); +#ifdef CONFIG_TRACER_SNAPSHOT + ring_buffer_record_disable_cpu(tr->snapshot_buffer.buffer, cpu); #endif } if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) && cpumask_test_cpu(cpu, tracing_cpumask_new)) { ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu); -#ifdef CONFIG_TRACER_MAX_TRACE - ring_buffer_record_enable_cpu(tr->max_buffer.buffer, cpu); +#ifdef CONFIG_TRACER_SNAPSHOT + ring_buffer_record_enable_cpu(tr->snapshot_buffer.buffer, cpu); #endif } } @@ -5326,8 +4574,8 @@ int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled) case TRACE_ITER(OVERWRITE): ring_buffer_change_overwrite(tr->array_buffer.buffer, enabled); -#ifdef CONFIG_TRACER_MAX_TRACE - ring_buffer_change_overwrite(tr->max_buffer.buffer, enabled); +#ifdef CONFIG_TRACER_SNAPSHOT + ring_buffer_change_overwrite(tr->snapshot_buffer.buffer, enabled); #endif break; @@ -5883,7 +5131,7 @@ trace_insert_eval_map_file(struct module *mod, struct trace_eval_map **start, * where the head holds the module and length of array, and the * tail holds a pointer to the next list. */ - map_array = kmalloc_array(len + 2, sizeof(*map_array), GFP_KERNEL); + map_array = kmalloc_objs(*map_array, len + 2); if (!map_array) { pr_warn("Unable to allocate trace eval mapping\n"); return; @@ -5970,6 +5218,7 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf, int tracer_init(struct tracer *t, struct trace_array *tr) { tracing_reset_online_cpus(&tr->array_buffer); + update_last_data_if_empty(tr); return t->init(tr); } @@ -5990,7 +5239,7 @@ static void update_buffer_entries(struct array_buffer *buf, int cpu) } } -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT /* resize @tr's buffer to the size of @size_tr's entries */ static int resize_buffer_duplicate_size(struct array_buffer *trace_buf, struct array_buffer *size_buf, int cpu_id) @@ -6016,7 +5265,7 @@ static int resize_buffer_duplicate_size(struct array_buffer *trace_buf, return ret; } -#endif /* CONFIG_TRACER_MAX_TRACE */ +#endif /* CONFIG_TRACER_SNAPSHOT */ static int __tracing_resize_ring_buffer(struct trace_array *tr, unsigned long size, int cpu) @@ -6041,11 +5290,11 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, if (ret < 0) goto out_start; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT if (!tr->allocated_snapshot) goto out; - ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu); + ret = ring_buffer_resize(tr->snapshot_buffer.buffer, size, cpu); if (ret < 0) { int r = resize_buffer_duplicate_size(&tr->array_buffer, &tr->array_buffer, cpu); @@ -6070,10 +5319,10 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr, goto out_start; } - update_buffer_entries(&tr->max_buffer, cpu); + update_buffer_entries(&tr->snapshot_buffer, cpu); out: -#endif /* CONFIG_TRACER_MAX_TRACE */ +#endif /* CONFIG_TRACER_SNAPSHOT */ update_buffer_entries(&tr->array_buffer, cpu); out_start: @@ -6264,6 +5513,9 @@ int tracing_update_buffers(struct trace_array *tr) { int ret = 0; + if (!tr) + tr = &global_trace; + guard(mutex)(&trace_types_lock); update_last_data(tr); @@ -6298,9 +5550,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) { struct tracer *trace = NULL; struct tracers *t; -#ifdef CONFIG_TRACER_MAX_TRACE bool had_max_tr; -#endif int ret; guard(mutex)(&trace_types_lock); @@ -6328,7 +5578,7 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) return 0; #ifdef CONFIG_TRACER_SNAPSHOT - if (trace->use_max_tr) { + if (tracer_uses_snapshot(trace)) { local_irq_disable(); arch_spin_lock(&tr->max_lock); ret = tr->cond_snapshot ? -EBUSY : 0; @@ -6360,14 +5610,13 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) if (tr->current_trace->reset) tr->current_trace->reset(tr); -#ifdef CONFIG_TRACER_MAX_TRACE - had_max_tr = tr->current_trace->use_max_tr; + had_max_tr = tracer_uses_snapshot(tr->current_trace); /* Current trace needs to be nop_trace before synchronize_rcu */ tr->current_trace = &nop_trace; tr->current_trace_flags = nop_trace.flags; - if (had_max_tr && !trace->use_max_tr) { + if (had_max_tr && !tracer_uses_snapshot(trace)) { /* * We need to make sure that the update_max_tr sees that * current_trace changed to nop_trace to keep it from @@ -6380,24 +5629,19 @@ int tracing_set_tracer(struct trace_array *tr, const char *buf) tracing_disarm_snapshot(tr); } - if (!had_max_tr && trace->use_max_tr) { + if (!had_max_tr && tracer_uses_snapshot(trace)) { ret = tracing_arm_snapshot_locked(tr); if (ret) return ret; } -#else - tr->current_trace = &nop_trace; -#endif tr->current_trace_flags = t->flags ? : t->tracer->flags; if (trace->init) { ret = tracer_init(trace, tr); if (ret) { -#ifdef CONFIG_TRACER_MAX_TRACE - if (trace->use_max_tr) + if (tracer_uses_snapshot(trace)) tracing_disarm_snapshot(tr); -#endif tr->current_trace_flags = nop_trace.flags; return ret; } @@ -6564,7 +5808,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp) goto fail_pipe_on_cpu; /* create a buffer to store the information to pass to userspace */ - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc_obj(*iter); if (!iter) { ret = -ENOMEM; goto fail_alloc_iter; @@ -7383,7 +6627,7 @@ static int user_buffer_init(struct trace_user_buf_info **tinfo, size_t size) if (!*tinfo) { alloc = true; - *tinfo = kzalloc(sizeof(**tinfo), GFP_KERNEL); + *tinfo = kzalloc_obj(**tinfo); if (!*tinfo) return -ENOMEM; } @@ -7602,7 +6846,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf, unsigned long ip; char *buf; - if (tracing_disabled) + if (unlikely(tracing_disabled)) return -EINVAL; if (!(tr->trace_flags & TRACE_ITER(MARKERS))) @@ -7682,7 +6926,7 @@ tracing_mark_raw_write(struct file *filp, const char __user *ubuf, ssize_t written = -ENODEV; char *buf; - if (tracing_disabled) + if (unlikely(tracing_disabled)) return -EINVAL; if (!(tr->trace_flags & TRACE_ITER(MARKERS))) @@ -7783,11 +7027,12 @@ int tracing_set_clock(struct trace_array *tr, const char *clockstr) */ tracing_reset_online_cpus(&tr->array_buffer); -#ifdef CONFIG_TRACER_MAX_TRACE - if (tr->max_buffer.buffer) - ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); - tracing_reset_online_cpus(&tr->max_buffer); +#ifdef CONFIG_TRACER_SNAPSHOT + if (tr->snapshot_buffer.buffer) + ring_buffer_set_clock(tr->snapshot_buffer.buffer, trace_clocks[i].func); + tracing_reset_online_cpus(&tr->snapshot_buffer); #endif + update_last_data_if_empty(tr); if (tr->scratch && !(tr->flags & TRACE_ARRAY_FL_LAST_BOOT)) { struct trace_scratch *tscratch = tr->scratch; @@ -7880,26 +7125,6 @@ u64 tracing_event_time_stamp(struct trace_buffer *buffer, struct ring_buffer_eve return ring_buffer_event_time_stamp(buffer, rbe); } -/* - * Set or disable using the per CPU trace_buffer_event when possible. - */ -int tracing_set_filter_buffering(struct trace_array *tr, bool set) -{ - guard(mutex)(&trace_types_lock); - - if (set && tr->no_filter_buffering_ref++) - return 0; - - if (!set) { - if (WARN_ON_ONCE(!tr->no_filter_buffering_ref)) - return -EINVAL; - - --tr->no_filter_buffering_ref; - } - - return 0; -} - struct ftrace_buffer_info { struct trace_iterator iter; void *spare; @@ -7927,10 +7152,10 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file) } else { /* Writes still need the seq_file to hold the private data */ ret = -ENOMEM; - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (!m) goto out; - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc_obj(*iter); if (!iter) { kfree(m); goto out; @@ -7938,7 +7163,7 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file) ret = 0; iter->tr = tr; - iter->array_buffer = &tr->max_buffer; + iter->array_buffer = &tr->snapshot_buffer; iter->cpu_file = tracing_get_cpu(inode); m->private = iter; file->private_data = m; @@ -7975,7 +7200,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, guard(mutex)(&trace_types_lock); - if (tr->current_trace->use_max_tr) + if (tracer_uses_snapshot(tr->current_trace)) return -EBUSY; local_irq_disable(); @@ -8001,7 +7226,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, return -EINVAL; #endif if (tr->allocated_snapshot) - ret = resize_buffer_duplicate_size(&tr->max_buffer, + ret = resize_buffer_duplicate_size(&tr->snapshot_buffer, &tr->array_buffer, iter->cpu_file); ret = tracing_arm_snapshot_locked(tr); @@ -8022,9 +7247,9 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt, default: if (tr->allocated_snapshot) { if (iter->cpu_file == RING_BUFFER_ALL_CPUS) - tracing_reset_online_cpus(&tr->max_buffer); + tracing_reset_online_cpus(&tr->snapshot_buffer); else - tracing_reset_cpu(&tr->max_buffer, iter->cpu_file); + tracing_reset_cpu(&tr->snapshot_buffer, iter->cpu_file); } break; } @@ -8074,13 +7299,13 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp) info = filp->private_data; - if (info->iter.trace->use_max_tr) { + if (tracer_uses_snapshot(info->iter.trace)) { tracing_buffers_release(inode, filp); return -EBUSY; } info->iter.snapshot = true; - info->iter.array_buffer = &info->iter.tr->max_buffer; + info->iter.array_buffer = &info->iter.tr->snapshot_buffer; return ret; } @@ -8319,7 +7544,7 @@ static struct tracing_log_err *alloc_tracing_log_err(int len) { struct tracing_log_err *err; - err = kzalloc(sizeof(*err), GFP_KERNEL); + err = kzalloc_obj(*err); if (!err) return ERR_PTR(-ENOMEM); @@ -8578,7 +7803,7 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp) if (ret) return ret; - info = kvzalloc(sizeof(*info), GFP_KERNEL); + info = kvzalloc_obj(*info); if (!info) { trace_array_put(tr); return -ENOMEM; @@ -8630,10 +7855,8 @@ tracing_buffers_read(struct file *filp, char __user *ubuf, if (!count) return 0; -#ifdef CONFIG_TRACER_MAX_TRACE - if (iter->snapshot && iter->tr->current_trace->use_max_tr) + if (iter->snapshot && tracer_uses_snapshot(iter->tr->current_trace)) return -EBUSY; -#endif page_size = ring_buffer_subbuf_size_get(iter->array_buffer->buffer); @@ -8817,10 +8040,8 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, int entries, i; ssize_t ret = 0; -#ifdef CONFIG_TRACER_MAX_TRACE - if (iter->snapshot && iter->tr->current_trace->use_max_tr) + if (iter->snapshot && tracer_uses_snapshot(iter->tr->current_trace)) return -EBUSY; -#endif page_size = ring_buffer_subbuf_size_get(iter->array_buffer->buffer); if (*ppos & (page_size - 1)) @@ -8843,7 +8064,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos, struct page *page; int r; - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) { ret = -ENOMEM; break; @@ -8954,7 +8175,7 @@ static long tracing_buffers_ioctl(struct file *file, unsigned int cmd, unsigned return 0; } -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT static int get_snapshot_map(struct trace_array *tr) { int err = 0; @@ -8992,6 +8213,18 @@ static inline int get_snapshot_map(struct trace_array *tr) { return 0; } static inline void put_snapshot_map(struct trace_array *tr) { } #endif +/* + * This is called when a VMA is duplicated (e.g., on fork()) to increment + * the user_mapped counter without remapping pages. + */ +static void tracing_buffers_mmap_open(struct vm_area_struct *vma) +{ + struct ftrace_buffer_info *info = vma->vm_file->private_data; + struct trace_iterator *iter = &info->iter; + + ring_buffer_map_dup(iter->array_buffer->buffer, iter->cpu_file); +} + static void tracing_buffers_mmap_close(struct vm_area_struct *vma) { struct ftrace_buffer_info *info = vma->vm_file->private_data; @@ -9011,6 +8244,7 @@ static int tracing_buffers_may_split(struct vm_area_struct *vma, unsigned long a } static const struct vm_operations_struct tracing_buffers_vmops = { + .open = tracing_buffers_mmap_open, .close = tracing_buffers_mmap_close, .may_split = tracing_buffers_may_split, }; @@ -9062,7 +8296,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf, unsigned long long t; unsigned long usec_rem; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; @@ -9397,7 +8631,7 @@ tracing_init_tracefs_percpu(struct trace_array *tr, long cpu) trace_create_cpu_file("stats", TRACE_MODE_READ, d_cpu, tr, cpu, &tracing_stats_fops); - trace_create_cpu_file("buffer_size_kb", TRACE_MODE_READ, d_cpu, + trace_create_cpu_file("buffer_size_kb", TRACE_MODE_WRITE, d_cpu, tr, cpu, &tracing_entries_fops); if (tr->range_addr_start) @@ -9656,7 +8890,7 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer, for (cnt = 0; opts[cnt].name; cnt++) ; - topts = kcalloc(cnt + 1, sizeof(*topts), GFP_KERNEL); + topts = kzalloc_objs(*topts, cnt + 1); if (!topts) return 0; @@ -9728,7 +8962,7 @@ static int add_tracer(struct trace_array *tr, struct tracer *tracer) if (!trace_ok_for_array(tracer, tr)) return 0; - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) return -ENOMEM; @@ -9745,7 +8979,7 @@ static int add_tracer(struct trace_array *tr, struct tracer *tracer) * If the tracer defines default flags, it means the flags are * per trace instance. */ - flags = kmalloc(sizeof(*flags), GFP_KERNEL); + flags = kmalloc_obj(*flags); if (!flags) return -ENOMEM; @@ -9958,12 +9192,12 @@ buffer_subbuf_size_write(struct file *filp, const char __user *ubuf, if (ret) goto out; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT if (!tr->allocated_snapshot) goto out_max; - ret = ring_buffer_subbuf_order_set(tr->max_buffer.buffer, order); + ret = ring_buffer_subbuf_order_set(tr->snapshot_buffer.buffer, order); if (ret) { /* Put back the old order */ cnt = ring_buffer_subbuf_order_set(tr->array_buffer.buffer, old_order); @@ -10088,7 +9322,7 @@ static void setup_trace_scratch(struct trace_array *tr, mod_addr_comp, NULL, NULL); if (IS_ENABLED(CONFIG_MODULES)) { - module_delta = kzalloc(struct_size(module_delta, delta, nr_entries), GFP_KERNEL); + module_delta = kzalloc_flex(*module_delta, delta, nr_entries); if (!module_delta) { pr_info("module_delta allocation failed. Not able to decode module address."); goto reset; @@ -10116,7 +9350,7 @@ static void setup_trace_scratch(struct trace_array *tr, } static int -allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, int size) +allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, unsigned long size) { enum ring_buffer_flags rb_flags; struct trace_scratch *tscratch; @@ -10171,7 +9405,7 @@ static void free_trace_buffer(struct array_buffer *buf) } } -static int allocate_trace_buffers(struct trace_array *tr, int size) +static int allocate_trace_buffers(struct trace_array *tr, unsigned long size) { int ret; @@ -10179,12 +9413,12 @@ static int allocate_trace_buffers(struct trace_array *tr, int size) if (ret) return ret; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT /* Fix mapped buffer trace arrays do not have snapshot buffers */ if (tr->range_addr_start) return 0; - ret = allocate_trace_buffer(tr, &tr->max_buffer, + ret = allocate_trace_buffer(tr, &tr->snapshot_buffer, allocate_snapshot ? size : 1); if (MEM_FAIL(ret, "Failed to allocate trace buffer\n")) { free_trace_buffer(&tr->array_buffer); @@ -10206,8 +9440,8 @@ static void free_trace_buffers(struct trace_array *tr) free_trace_buffer(&tr->array_buffer); kfree(tr->module_delta); -#ifdef CONFIG_TRACER_MAX_TRACE - free_trace_buffer(&tr->max_buffer); +#ifdef CONFIG_TRACER_SNAPSHOT + free_trace_buffer(&tr->snapshot_buffer); #endif } @@ -10315,7 +9549,7 @@ trace_array_create_systems(const char *name, const char *systems, int ret; ret = -ENOMEM; - tr = kzalloc(sizeof(*tr), GFP_KERNEL); + tr = kzalloc_obj(*tr); if (!tr) return ERR_PTR(ret); @@ -10348,7 +9582,7 @@ trace_array_create_systems(const char *name, const char *systems, tr->syscall_buf_sz = global_trace.syscall_buf_sz; tr->max_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT spin_lock_init(&tr->snapshot_trigger_lock); #endif tr->current_trace = &nop_trace; @@ -10673,9 +9907,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer) create_trace_options_dir(tr); -#ifdef CONFIG_TRACER_MAX_TRACE trace_create_maxlat_file(tr, d_tracer); -#endif if (ftrace_create_function_files(tr, d_tracer)) MEM_FAIL(1, "Could not allocate function filter files"); @@ -10774,7 +10006,7 @@ int tracing_init_dentry(void) extern struct trace_eval_map *__start_ftrace_eval_maps[]; extern struct trace_eval_map *__stop_ftrace_eval_maps[]; -static struct workqueue_struct *eval_map_wq __initdata; +struct workqueue_struct *trace_init_wq __initdata; static struct work_struct eval_map_work __initdata; static struct work_struct tracerfs_init_work __initdata; @@ -10790,15 +10022,15 @@ static int __init trace_eval_init(void) { INIT_WORK(&eval_map_work, eval_map_work_func); - eval_map_wq = alloc_workqueue("eval_map_wq", WQ_UNBOUND, 0); - if (!eval_map_wq) { - pr_err("Unable to allocate eval_map_wq\n"); + trace_init_wq = alloc_workqueue("trace_init_wq", WQ_UNBOUND, 0); + if (!trace_init_wq) { + pr_err("Unable to allocate trace_init_wq\n"); /* Do work here */ eval_map_work_func(&eval_map_work); return -ENOMEM; } - queue_work(eval_map_wq, &eval_map_work); + queue_work(trace_init_wq, &eval_map_work); return 0; } @@ -10807,8 +10039,8 @@ subsys_initcall(trace_eval_init); static int __init trace_eval_sync(void) { /* Make sure the eval map updates are finished */ - if (eval_map_wq) - destroy_workqueue(eval_map_wq); + if (trace_init_wq) + destroy_workqueue(trace_init_wq); return 0; } @@ -10969,9 +10201,9 @@ static __init int tracer_init_tracefs(void) if (ret) return 0; - if (eval_map_wq) { + if (trace_init_wq) { INIT_WORK(&tracerfs_init_work, tracer_init_tracefs_work_func); - queue_work(eval_map_wq, &tracerfs_init_work); + queue_work(trace_init_wq, &tracerfs_init_work); } else { tracer_init_tracefs_work_func(NULL); } @@ -11304,7 +10536,7 @@ ssize_t trace_parse_run_command(struct file *file, const char __user *buffer, return done; } -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT __init static bool tr_needs_alloc_snapshot(const char *name) { char *test; @@ -11494,7 +10726,7 @@ __init static void enable_instances(void) } } else { /* Only non mapped buffers have snapshot buffers */ - if (IS_ENABLED(CONFIG_TRACER_MAX_TRACE)) + if (IS_ENABLED(CONFIG_TRACER_SNAPSHOT)) do_allocate_snapshot(name); } @@ -11537,7 +10769,7 @@ __init static void enable_instances(void) __init static int tracer_alloc_buffers(void) { - int ring_buf_size; + unsigned long ring_buf_size; int ret = -ENOMEM; @@ -11621,7 +10853,7 @@ __init static int tracer_alloc_buffers(void) global_trace.current_trace_flags = nop_trace.flags; global_trace.max_lock = (arch_spinlock_t)__ARCH_SPIN_LOCK_UNLOCKED; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT spin_lock_init(&global_trace.snapshot_trigger_lock); #endif ftrace_init_global_array_ops(&global_trace); @@ -11689,7 +10921,7 @@ struct trace_array *trace_get_global_array(void) void __init ftrace_boot_snapshot(void) { -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT struct trace_array *tr; if (!snapshot_at_boot) @@ -11708,8 +10940,7 @@ void __init ftrace_boot_snapshot(void) void __init early_trace_init(void) { if (tracepoint_printk) { - tracepoint_print_iter = - kzalloc(sizeof(*tracepoint_print_iter), GFP_KERNEL); + tracepoint_print_iter = kzalloc_obj(*tracepoint_print_iter); if (MEM_FAIL(!tracepoint_print_iter, "Failed to allocate trace iterator\n")) tracepoint_printk = 0; diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 8428c437cb9d..b8f3804586a0 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h @@ -131,7 +131,7 @@ enum trace_type { #define FAULT_STRING "(fault)" -#define HIST_STACKTRACE_DEPTH 16 +#define HIST_STACKTRACE_DEPTH 31 #define HIST_STACKTRACE_SIZE (HIST_STACKTRACE_DEPTH * sizeof(unsigned long)) #define HIST_STACKTRACE_SKIP 5 @@ -332,29 +332,33 @@ struct trace_array { struct list_head list; char *name; struct array_buffer array_buffer; -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT /* - * The max_buffer is used to snapshot the trace when a maximum + * The snapshot_buffer is used to snapshot the trace when a maximum * latency is reached, or when the user initiates a snapshot. * Some tracers will use this to store a maximum trace while * it continues examining live traces. * - * The buffers for the max_buffer are set up the same as the array_buffer - * When a snapshot is taken, the buffer of the max_buffer is swapped - * with the buffer of the array_buffer and the buffers are reset for - * the array_buffer so the tracing can continue. + * The buffers for the snapshot_buffer are set up the same as the + * array_buffer. When a snapshot is taken, the buffer of the + * snapshot_buffer is swapped with the buffer of the array_buffer + * and the buffers are reset for the array_buffer so the tracing can + * continue. */ - struct array_buffer max_buffer; + struct array_buffer snapshot_buffer; bool allocated_snapshot; spinlock_t snapshot_trigger_lock; unsigned int snapshot; +#ifdef CONFIG_TRACER_MAX_TRACE unsigned long max_latency; -#ifdef CONFIG_FSNOTIFY struct dentry *d_max_latency; +#ifdef CONFIG_FSNOTIFY struct work_struct fsnotify_work; struct irq_work fsnotify_irqwork; -#endif -#endif +#endif /* CONFIG_FSNOTIFY */ +#endif /* CONFIG_TRACER_MAX_TRACE */ +#endif /* CONFIG_TRACER_SNAPSHOT */ + /* The below is for memory mapped ring buffer */ unsigned int mapped; unsigned long range_addr_start; @@ -380,7 +384,7 @@ struct trace_array { * * It is also used in other places outside the update_max_tr * so it needs to be defined outside of the - * CONFIG_TRACER_MAX_TRACE. + * CONFIG_TRACER_SNAPSHOT. */ arch_spinlock_t max_lock; #ifdef CONFIG_FTRACE_SYSCALLS @@ -479,13 +483,14 @@ extern struct trace_array *trace_array_find(const char *instance); extern struct trace_array *trace_array_find_get(const char *instance); extern u64 tracing_event_time_stamp(struct trace_buffer *buffer, struct ring_buffer_event *rbe); -extern int tracing_set_filter_buffering(struct trace_array *tr, bool set); extern int tracing_set_clock(struct trace_array *tr, const char *clockstr); extern bool trace_clock_in_ns(struct trace_array *tr); extern unsigned long trace_adjust_address(struct trace_array *tr, unsigned long addr); +extern struct trace_array *printk_trace; + /* * The global tracer (top) should be the first trace array added, * but we check the flag anyway. @@ -661,6 +666,8 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu) return iter->buffer_iter ? iter->buffer_iter[cpu] : NULL; } +extern int tracing_disabled; + int tracer_init(struct tracer *t, struct trace_array *tr); int tracing_is_enabled(void); void tracing_reset_online_cpus(struct array_buffer *buf); @@ -672,7 +679,6 @@ int tracing_release_generic_tr(struct inode *inode, struct file *file); int tracing_open_file_tr(struct inode *inode, struct file *filp); int tracing_release_file_tr(struct inode *inode, struct file *filp); int tracing_single_release_file_tr(struct inode *inode, struct file *filp); -bool tracing_is_disabled(void); bool tracer_tracing_is_on(struct trace_array *tr); void tracer_tracing_on(struct trace_array *tr); void tracer_tracing_off(struct trace_array *tr); @@ -772,6 +778,7 @@ extern cpumask_var_t __read_mostly tracing_buffer_mask; extern unsigned long nsecs_to_usecs(unsigned long nsecs); extern unsigned long tracing_thresh; +extern struct workqueue_struct *trace_init_wq __initdata; /* PID filtering */ @@ -790,22 +797,22 @@ int trace_pid_write(struct trace_pid_list *filtered_pids, struct trace_pid_list **new_pid_list, const char __user *ubuf, size_t cnt); -#ifdef CONFIG_TRACER_MAX_TRACE +#ifdef CONFIG_TRACER_SNAPSHOT void update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu, void *cond_data); void update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu); -#ifdef CONFIG_FSNOTIFY -#define LATENCY_FS_NOTIFY +#if defined(CONFIG_TRACER_MAX_TRACE) && defined(CONFIG_FSNOTIFY) +# define LATENCY_FS_NOTIFY #endif -#endif /* CONFIG_TRACER_MAX_TRACE */ #ifdef LATENCY_FS_NOTIFY void latency_fsnotify(struct trace_array *tr); #else static inline void latency_fsnotify(struct trace_array *tr) { } #endif +#endif /* CONFIG_TRACER_SNAPSHOT */ #ifdef CONFIG_STACKTRACE void __trace_stack(struct trace_array *tr, unsigned int trace_ctx, int skip); @@ -816,6 +823,18 @@ static inline void __trace_stack(struct trace_array *tr, unsigned int trace_ctx, } #endif /* CONFIG_STACKTRACE */ +#ifdef CONFIG_TRACER_MAX_TRACE +static inline bool tracer_uses_snapshot(struct tracer *tracer) +{ + return tracer->use_max_tr; +} +#else +static inline bool tracer_uses_snapshot(struct tracer *tracer) +{ + return false; +} +#endif + void trace_last_func_repeats(struct trace_array *tr, struct trace_func_repeats *last_info, unsigned int trace_ctx); @@ -865,6 +884,7 @@ extern int trace_selftest_startup_nop(struct tracer *trace, struct trace_array *tr); extern int trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr); +extern bool __read_mostly tracing_selftest_running; /* * Tracer data references selftest functions that only occur * on boot up. These can be __init functions. Thus, when selftests @@ -877,6 +897,7 @@ static inline void __init disable_tracing_selftest(const char *reason) } /* Tracers are seldom changed. Optimize when selftests are disabled. */ #define __tracer_data __read_mostly +#define tracing_selftest_running 0 #endif /* CONFIG_FTRACE_STARTUP_TEST */ extern void *head_page(struct trace_array_cpu *data); @@ -1414,6 +1435,7 @@ extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf, C(COPY_MARKER, "copy_trace_marker"), \ C(PAUSE_ON_TRACE, "pause-on-trace"), \ C(HASH_PTR, "hash-ptr"), /* Print hashed pointer */ \ + C(BITMASK_LIST, "bitmask-list"), \ FUNCTION_FLAGS \ FGRAPH_FLAGS \ STACK_FLAGS \ @@ -1567,6 +1589,47 @@ char *trace_user_fault_read(struct trace_user_buf_info *tinfo, const char __user *ptr, size_t size, trace_user_buf_copy copy_func, void *data); +static __always_inline void +trace_event_setup(struct ring_buffer_event *event, + int type, unsigned int trace_ctx) +{ + struct trace_entry *ent = ring_buffer_event_data(event); + + tracing_generic_entry_update(ent, type, trace_ctx); +} + +static __always_inline struct ring_buffer_event * +__trace_buffer_lock_reserve(struct trace_buffer *buffer, + int type, + unsigned long len, + unsigned int trace_ctx) +{ + struct ring_buffer_event *event; + + event = ring_buffer_lock_reserve(buffer, len); + if (event != NULL) + trace_event_setup(event, type, trace_ctx); + + return event; +} + +static __always_inline void +__buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *event) +{ + __this_cpu_write(trace_taskinfo_save, true); + + /* If this is the temp buffer, we need to commit fully */ + if (this_cpu_read(trace_buffered_event) == event) { + /* Length is in event->array[0] */ + ring_buffer_write(buffer, event->array[0], &event->array[1]); + /* Release the temp buffer */ + this_cpu_dec(trace_buffered_event_cnt); + /* ring_buffer_unlock_commit() enables preemption */ + preempt_enable_notrace(); + } else + ring_buffer_unlock_commit(buffer); +} + static inline void __trace_event_discard_commit(struct trace_buffer *buffer, struct ring_buffer_event *event) @@ -2087,6 +2150,7 @@ extern const char *__stop___tracepoint_str[]; void trace_printk_control(bool enabled); void trace_printk_start_comm(void); +void trace_printk_start_stop_comm(int enabled); int trace_keep_overwrite(struct tracer *tracer, u64 mask, int set); int set_tracer_flag(struct trace_array *tr, u64 mask, int enabled); @@ -2237,6 +2301,37 @@ static inline void sanitize_event_name(char *name) *name = '_'; } +#ifdef CONFIG_STACKTRACE +void __ftrace_trace_stack(struct trace_array *tr, + struct trace_buffer *buffer, + unsigned int trace_ctx, + int skip, struct pt_regs *regs); + +static __always_inline void ftrace_trace_stack(struct trace_array *tr, + struct trace_buffer *buffer, + unsigned int trace_ctx, + int skip, struct pt_regs *regs) +{ + if (!(tr->trace_flags & TRACE_ITER(STACKTRACE))) + return; + + __ftrace_trace_stack(tr, buffer, trace_ctx, skip, regs); +} +#else +static inline void __ftrace_trace_stack(struct trace_array *tr, + struct trace_buffer *buffer, + unsigned int trace_ctx, + int skip, struct pt_regs *regs) +{ +} +static inline void ftrace_trace_stack(struct trace_array *tr, + struct trace_buffer *buffer, + unsigned long trace_ctx, + int skip, struct pt_regs *regs) +{ +} +#endif + /* * This is a generic way to read and write a u64 value from a file in tracefs. * diff --git a/kernel/trace/trace_btf.c b/kernel/trace/trace_btf.c index 5bbdbcbbde3c..00172f301f25 100644 --- a/kernel/trace/trace_btf.c +++ b/kernel/trace/trace_btf.c @@ -78,7 +78,7 @@ const struct btf_member *btf_find_struct_member(struct btf *btf, const char *name; int i, top = 0; - anon_stack = kcalloc(BTF_ANON_STACK_MAX, sizeof(*anon_stack), GFP_KERNEL); + anon_stack = kzalloc_objs(*anon_stack, BTF_ANON_STACK_MAX); if (!anon_stack) return ERR_PTR(-ENOMEM); diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c index 3ee39715d5e4..b66d6196338d 100644 --- a/kernel/trace/trace_eprobe.c +++ b/kernel/trace/trace_eprobe.c @@ -211,7 +211,7 @@ static struct trace_eprobe *alloc_event_probe(const char *group, sys_name = event->class->system; event_name = trace_event_name(event); - ep = kzalloc(struct_size(ep, tp.args, nargs), GFP_KERNEL); + ep = kzalloc_flex(*ep, tp.args, nargs); if (!ep) { trace_event_put_ref(event); return ERR_PTR(-ENOMEM); @@ -529,8 +529,8 @@ new_eprobe_trigger(struct trace_eprobe *ep, struct trace_event_file *file) struct eprobe_data *edata; int ret; - edata = kzalloc(sizeof(*edata), GFP_KERNEL); - trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); + edata = kzalloc_obj(*edata); + trigger = kzalloc_obj(*trigger); if (!trigger || !edata) { ret = -ENOMEM; goto error; diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index 137b4d9bb116..249d1cba72c0 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -649,6 +649,22 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file) } EXPORT_SYMBOL_GPL(trace_event_ignore_this_pid); +/** + * trace_event_buffer_reserve - reserve space on the ring buffer for an event + * @fbuffer: information about how to save the event + * @trace_file: the instance file descriptor for the event + * @len: The length of the event + * + * The @fbuffer has information about the ring buffer and data will + * be added to it to be used by the call to trace_event_buffer_commit(). + * The @trace_file is the desrciptor with information about the status + * of the given event for a specific trace_array instance. + * The @len is the length of data to save for the event. + * + * Returns a pointer to the data on the ring buffer or NULL if the + * event was not reserved (event was filtered, too big, or the buffer + * simply was disabled for write). + */ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer, struct trace_event_file *trace_file, unsigned long len) @@ -960,7 +976,7 @@ static int cache_mod(struct trace_array *tr, const char *mod, int set, if (!set) return remove_cache_mod(tr, mod, match, system, event); - event_mod = kzalloc(sizeof(*event_mod), GFP_KERNEL); + event_mod = kzalloc_obj(*event_mod); if (!event_mod) return -ENOMEM; @@ -1023,6 +1039,7 @@ event_filter_pid_sched_process_exit(void *data, struct task_struct *task) struct trace_pid_list *pid_list; struct trace_array *tr = data; + guard(preempt)(); pid_list = rcu_dereference_raw(tr->filtered_pids); trace_filter_add_remove_task(pid_list, NULL, task); @@ -1038,6 +1055,7 @@ event_filter_pid_sched_process_fork(void *data, struct trace_pid_list *pid_list; struct trace_array *tr = data; + guard(preempt)(); pid_list = rcu_dereference_sched(tr->filtered_pids); trace_filter_add_remove_task(pid_list, self, task); @@ -1295,6 +1313,9 @@ static void remove_event_file_dir(struct trace_event_file *file) free_event_filter(file->filter); file->flags |= EVENT_FILE_FL_FREED; event_file_put(file); + + /* Wake up hist poll waiters to notice the EVENT_FILE_FL_FREED flag. */ + hist_poll_wakeup(); } /* @@ -1629,7 +1650,7 @@ static void *s_start(struct seq_file *m, loff_t *pos) struct set_event_iter *iter; loff_t l; - iter = kzalloc(sizeof(*iter), GFP_KERNEL); + iter = kzalloc_obj(*iter); mutex_lock(&event_mutex); if (!iter) return NULL; @@ -1662,6 +1683,82 @@ static void t_stop(struct seq_file *m, void *p) mutex_unlock(&event_mutex); } +static int get_call_len(struct trace_event_call *call) +{ + int len; + + /* Get the length of ":" */ + len = strlen(call->class->system) + 1; + len += strlen(trace_event_name(call)); + + /* Set the index to 32 bytes to separate event from data */ + return len >= 32 ? 1 : 32 - len; +} + +/** + * t_show_filters - seq_file callback to display active event filters + * @m: The seq_file interface for formatted output + * @v: The current trace_event_file being iterated + * + * Identifies and prints active filters for the current event file in the + * iteration. If a filter is applied to the current event and, if so, + * prints the system name, event name, and the filter string. + */ +static int t_show_filters(struct seq_file *m, void *v) +{ + struct trace_event_file *file = v; + struct trace_event_call *call = file->event_call; + struct event_filter *filter; + int len; + + guard(rcu)(); + filter = rcu_dereference(file->filter); + if (!filter || !filter->filter_string) + return 0; + + len = get_call_len(call); + + seq_printf(m, "%s:%s%*.s%s\n", call->class->system, + trace_event_name(call), len, "", filter->filter_string); + + return 0; +} + +/** + * t_show_triggers - seq_file callback to display active event triggers + * @m: The seq_file interface for formatted output + * @v: The current trace_event_file being iterated + * + * Iterates through the trigger list of the current event file and prints + * each active trigger's configuration using its associated print + * operation. + */ +static int t_show_triggers(struct seq_file *m, void *v) +{ + struct trace_event_file *file = v; + struct trace_event_call *call = file->event_call; + struct event_trigger_data *data; + int len; + + /* + * The event_mutex is held by t_start(), protecting the + * file->triggers list traversal. + */ + if (list_empty(&file->triggers)) + return 0; + + len = get_call_len(call); + + list_for_each_entry_rcu(data, &file->triggers, list) { + seq_printf(m, "%s:%s%*.s", call->class->system, + trace_event_name(call), len, ""); + + data->cmd_ops->print(m, data); + } + + return 0; +} + #ifdef CONFIG_MODULES static int s_show(struct seq_file *m, void *v) { @@ -2111,7 +2208,7 @@ event_filter_read(struct file *filp, char __user *ubuf, size_t cnt, if (*ppos) return 0; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; @@ -2176,7 +2273,7 @@ static int subsystem_open(struct inode *inode, struct file *filp) struct event_subsystem *system = NULL; int ret; - if (tracing_is_disabled()) + if (unlikely(tracing_disabled)) return -ENODEV; /* Make sure the system still exists */ @@ -2225,7 +2322,7 @@ static int system_tr_open(struct inode *inode, struct file *filp) int ret; /* Make a temporary dir that has no system but points to tr */ - dir = kzalloc(sizeof(*dir), GFP_KERNEL); + dir = kzalloc_obj(*dir); if (!dir) return -ENOMEM; @@ -2271,7 +2368,7 @@ subsystem_filter_read(struct file *filp, char __user *ubuf, size_t cnt, if (*ppos) return 0; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; @@ -2321,7 +2418,7 @@ show_header_page_file(struct file *filp, char __user *ubuf, size_t cnt, loff_t * if (*ppos) return 0; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; @@ -2345,7 +2442,7 @@ show_header_event_file(struct file *filp, char __user *ubuf, size_t cnt, loff_t if (*ppos) return 0; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return -ENOMEM; @@ -2489,6 +2586,8 @@ ftrace_event_npid_write(struct file *filp, const char __user *ubuf, static int ftrace_event_avail_open(struct inode *inode, struct file *file); static int ftrace_event_set_open(struct inode *inode, struct file *file); +static int ftrace_event_show_filters_open(struct inode *inode, struct file *file); +static int ftrace_event_show_triggers_open(struct inode *inode, struct file *file); static int ftrace_event_set_pid_open(struct inode *inode, struct file *file); static int ftrace_event_set_npid_open(struct inode *inode, struct file *file); static int ftrace_event_release(struct inode *inode, struct file *file); @@ -2507,6 +2606,20 @@ static const struct seq_operations show_set_event_seq_ops = { .stop = s_stop, }; +static const struct seq_operations show_show_event_filters_seq_ops = { + .start = t_start, + .next = t_next, + .show = t_show_filters, + .stop = t_stop, +}; + +static const struct seq_operations show_show_event_triggers_seq_ops = { + .start = t_start, + .next = t_next, + .show = t_show_triggers, + .stop = t_stop, +}; + static const struct seq_operations show_set_pid_seq_ops = { .start = p_start, .next = p_next, @@ -2536,6 +2649,20 @@ static const struct file_operations ftrace_set_event_fops = { .release = ftrace_event_release, }; +static const struct file_operations ftrace_show_event_filters_fops = { + .open = ftrace_event_show_filters_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static const struct file_operations ftrace_show_event_triggers_fops = { + .open = ftrace_event_show_triggers_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + static const struct file_operations ftrace_set_event_pid_fops = { .open = ftrace_event_set_pid_open, .read = seq_read, @@ -2680,6 +2807,34 @@ ftrace_event_set_open(struct inode *inode, struct file *file) return ret; } +/** + * ftrace_event_show_filters_open - open interface for set_event_filters + * @inode: The inode of the file + * @file: The file being opened + * + * Connects the set_event_filters file to the sequence operations + * required to iterate over and display active event filters. + */ +static int +ftrace_event_show_filters_open(struct inode *inode, struct file *file) +{ + return ftrace_event_open(inode, file, &show_show_event_filters_seq_ops); +} + +/** + * ftrace_event_show_triggers_open - open interface for show_event_triggers + * @inode: The inode of the file + * @file: The file being opened + * + * Connects the show_event_triggers file to the sequence operations + * required to iterate over and display active event triggers. + */ +static int +ftrace_event_show_triggers_open(struct inode *inode, struct file *file) +{ + return ftrace_event_open(inode, file, &show_show_event_triggers_seq_ops); +} + static int ftrace_event_set_pid_open(struct inode *inode, struct file *file) { @@ -2728,7 +2883,7 @@ create_new_subsystem(const char *name) struct event_subsystem *system; /* need to create new entry */ - system = kmalloc(sizeof(*system), GFP_KERNEL); + system = kmalloc_obj(*system); if (!system) return NULL; @@ -2739,7 +2894,7 @@ create_new_subsystem(const char *name) if (!system->name) goto out_free; - system->filter = kzalloc(sizeof(struct event_filter), GFP_KERNEL); + system->filter = kzalloc_obj(struct event_filter); if (!system->filter) goto out_free; @@ -2807,7 +2962,7 @@ event_subsystem_dir(struct trace_array *tr, const char *name, } } - dir = kmalloc(sizeof(*dir), GFP_KERNEL); + dir = kmalloc_obj(*dir); if (!dir) goto out_fail; @@ -3250,7 +3405,7 @@ static void add_str_to_module(struct module *module, char *str) { struct module_string *modstr; - modstr = kmalloc(sizeof(*modstr), GFP_KERNEL); + modstr = kmalloc_obj(*modstr); /* * If we failed to allocate memory here, then we'll just @@ -3963,11 +4118,6 @@ void trace_put_event_file(struct trace_event_file *file) EXPORT_SYMBOL_GPL(trace_put_event_file); #ifdef CONFIG_DYNAMIC_FTRACE - -/* Avoid typos */ -#define ENABLE_EVENT_STR "enable_event" -#define DISABLE_EVENT_STR "disable_event" - struct event_probe_data { struct trace_event_file *file; unsigned long count; @@ -4217,7 +4367,7 @@ event_enable_func(struct trace_array *tr, struct ftrace_hash *hash, goto out_put; ret = -ENOMEM; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) goto out_put; @@ -4343,7 +4493,11 @@ static char bootup_event_buf[COMMAND_LINE_SIZE] __initdata; static __init int setup_trace_event(char *str) { - strscpy(bootup_event_buf, str, COMMAND_LINE_SIZE); + if (bootup_event_buf[0] != '\0') + strlcat(bootup_event_buf, ",", COMMAND_LINE_SIZE); + + strlcat(bootup_event_buf, str, COMMAND_LINE_SIZE); + trace_set_ring_buffer_expanded(NULL); disable_tracing_selftest("running event tracing"); @@ -4400,6 +4554,12 @@ create_event_toplevel_files(struct dentry *parent, struct trace_array *tr) if (!entry) return -ENOMEM; + trace_create_file("show_event_filters", TRACE_MODE_READ, parent, tr, + &ftrace_show_event_filters_fops); + + trace_create_file("show_event_triggers", TRACE_MODE_READ, parent, tr, + &ftrace_show_event_triggers_fops); + nr_entries = ARRAY_SIZE(events_entries); e_events = eventfs_create_events_dir("events", parent, events_entries, @@ -4514,26 +4674,22 @@ static __init int event_trace_memsetup(void) return 0; } -__init void -early_enable_events(struct trace_array *tr, char *buf, bool disable_first) +/* + * Helper function to enable or disable a comma-separated list of events + * from the bootup buffer. + */ +static __init void __early_set_events(struct trace_array *tr, char *buf, bool enable) { char *token; - int ret; - - while (true) { - token = strsep(&buf, ","); - - if (!token) - break; + while ((token = strsep(&buf, ","))) { if (*token) { - /* Restarting syscalls requires that we stop them first */ - if (disable_first) + if (enable) { + if (ftrace_set_clr_event(tr, token, 1)) + pr_warn("Failed to enable trace event: %s\n", token); + } else { ftrace_set_clr_event(tr, token, 0); - - ret = ftrace_set_clr_event(tr, token, 1); - if (ret) - pr_warn("Failed to enable trace event: %s\n", token); + } } /* Put back the comma to allow this to be called again */ @@ -4542,6 +4698,32 @@ early_enable_events(struct trace_array *tr, char *buf, bool disable_first) } } +/** + * early_enable_events - enable events from the bootup buffer + * @tr: The trace array to enable the events in + * @buf: The buffer containing the comma separated list of events + * @disable_first: If true, disable all events in @buf before enabling them + * + * This function enables events from the bootup buffer. If @disable_first + * is true, it will first disable all events in the buffer before enabling + * them. + * + * For syscall events, which rely on a global refcount to register the + * SYSCALL_WORK_SYSCALL_TRACEPOINT flag (especially for pid 1), we must + * ensure the refcount hits zero before re-enabling them. A simple + * "disable then enable" per-event is not enough if multiple syscalls are + * used, as the refcount will stay above zero. Thus, we need a two-phase + * approach: disable all, then enable all. + */ +__init void +early_enable_events(struct trace_array *tr, char *buf, bool disable_first) +{ + if (disable_first) + __early_set_events(tr, buf, false); + + __early_set_events(tr, buf, true); +} + static __init int event_trace_enable(void) { struct trace_array *tr = top_trace_array(); diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index 385af8405392..609325f57942 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -485,10 +485,10 @@ predicate_parse(const char *str, int nr_parens, int nr_preds, nr_preds += 2; /* For TRUE and FALSE */ - op_stack = kmalloc_array(nr_parens, sizeof(*op_stack), GFP_KERNEL); + op_stack = kmalloc_objs(*op_stack, nr_parens); if (!op_stack) return ERR_PTR(-ENOMEM); - prog_stack = kcalloc(nr_preds, sizeof(*prog_stack), GFP_KERNEL); + prog_stack = kzalloc_objs(*prog_stack, nr_preds); if (!prog_stack) { parse_error(pe, -ENOMEM, 0); goto out_free; @@ -1213,7 +1213,7 @@ static void append_filter_err(struct trace_array *tr, if (WARN_ON(!filter->filter_string)) return; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (!s) return; trace_seq_init(s); @@ -1375,7 +1375,7 @@ static void free_filter_list_tasks(struct rcu_head *rhp) struct filter_head *filter_list = container_of(rhp, struct filter_head, rcu); INIT_RCU_WORK(&filter_list->rwork, free_filter_list_work); - queue_rcu_work(system_wq, &filter_list->rwork); + queue_rcu_work(system_dfl_wq, &filter_list->rwork); } /* @@ -1394,13 +1394,13 @@ static void try_delay_free_filter(struct event_filter *filter) struct filter_head *head; struct filter_list *item; - head = kmalloc(sizeof(*head), GFP_KERNEL); + head = kmalloc_obj(*head); if (!head) goto free_now; INIT_LIST_HEAD(&head->list); - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) { kfree(head); goto free_now; @@ -1442,7 +1442,7 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir, struct filter_head *head; struct filter_list *item; - head = kmalloc(sizeof(*head), GFP_KERNEL); + head = kmalloc_obj(*head); if (!head) goto free_now; @@ -1451,7 +1451,7 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir, list_for_each_entry(file, &tr->events, list) { if (file->system != dir) continue; - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) goto free_now; item->filter = event_filter(file); @@ -1459,7 +1459,7 @@ static void filter_free_subsystem_filters(struct trace_subsystem_dir *dir, event_clear_filter(file); } - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) goto free_now; @@ -1708,7 +1708,7 @@ static int parse_pred(const char *str, void *data, s = i; - pred = kzalloc(sizeof(*pred), GFP_KERNEL); + pred = kzalloc_obj(*pred); if (!pred) return -ENOMEM; @@ -1819,7 +1819,7 @@ static int parse_pred(const char *str, void *data, goto err_free; } - pred->regex = kzalloc(sizeof(*pred->regex), GFP_KERNEL); + pred->regex = kzalloc_obj(*pred->regex); if (!pred->regex) goto err_mem; pred->regex->len = len; @@ -1984,7 +1984,7 @@ static int parse_pred(const char *str, void *data, goto err_free; } - pred->regex = kzalloc(sizeof(*pred->regex), GFP_KERNEL); + pred->regex = kzalloc_obj(*pred->regex); if (!pred->regex) goto err_mem; pred->regex->len = len; @@ -2261,7 +2261,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir, bool fail = true; int err; - filter_list = kmalloc(sizeof(*filter_list), GFP_KERNEL); + filter_list = kmalloc_obj(*filter_list); if (!filter_list) return -ENOMEM; @@ -2272,7 +2272,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir, if (file->system != dir) continue; - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (!filter) goto fail_mem; @@ -2289,7 +2289,7 @@ static int process_system_preds(struct trace_subsystem_dir *dir, event_set_filtered_flag(file); - filter_item = kzalloc(sizeof(*filter_item), GFP_KERNEL); + filter_item = kzalloc_obj(*filter_item); if (!filter_item) goto fail_mem; @@ -2343,14 +2343,14 @@ static int create_filter_start(char *filter_string, bool set_str, if (WARN_ON_ONCE(*pse || *filterp)) return -EINVAL; - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (filter && set_str) { filter->filter_string = kstrdup(filter_string, GFP_KERNEL); if (!filter->filter_string) err = -ENOMEM; } - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc_obj(*pe); if (!filter || !pe || err) { kfree(pe); diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c index c97bb2fda5c0..73ea180cad55 100644 --- a/kernel/trace/trace_events_hist.c +++ b/kernel/trace/trace_events_hist.c @@ -105,38 +105,44 @@ enum field_op_id { FIELD_OP_MULT, }; +#define FIELD_FUNCS \ + C(NOP, "nop"), \ + C(VAR_REF, "var_ref"), \ + C(COUNTER, "counter"), \ + C(CONST, "const"), \ + C(LOG2, "log2"), \ + C(BUCKET, "bucket"), \ + C(TIMESTAMP, "timestamp"), \ + C(CPU, "cpu"), \ + C(COMM, "comm"), \ + C(STRING, "string"), \ + C(DYNSTRING, "dynstring"), \ + C(RELDYNSTRING, "reldynstring"), \ + C(PSTRING, "pstring"), \ + C(S64, "s64"), \ + C(U64, "u64"), \ + C(S32, "s32"), \ + C(U32, "u32"), \ + C(S16, "s16"), \ + C(U16, "u16"), \ + C(S8, "s8"), \ + C(U8, "u8"), \ + C(UMINUS, "uminus"), \ + C(MINUS, "minus"), \ + C(PLUS, "plus"), \ + C(DIV, "div"), \ + C(MULT, "mult"), \ + C(DIV_POWER2, "div_power2"), \ + C(DIV_NOT_POWER2, "div_not_power2"), \ + C(DIV_MULT_SHIFT, "div_mult_shift"), \ + C(EXECNAME, "execname"), \ + C(STACK, "stack"), + +#undef C +#define C(a, b) HIST_FIELD_FN_##a + enum hist_field_fn { - HIST_FIELD_FN_NOP, - HIST_FIELD_FN_VAR_REF, - HIST_FIELD_FN_COUNTER, - HIST_FIELD_FN_CONST, - HIST_FIELD_FN_LOG2, - HIST_FIELD_FN_BUCKET, - HIST_FIELD_FN_TIMESTAMP, - HIST_FIELD_FN_CPU, - HIST_FIELD_FN_COMM, - HIST_FIELD_FN_STRING, - HIST_FIELD_FN_DYNSTRING, - HIST_FIELD_FN_RELDYNSTRING, - HIST_FIELD_FN_PSTRING, - HIST_FIELD_FN_S64, - HIST_FIELD_FN_U64, - HIST_FIELD_FN_S32, - HIST_FIELD_FN_U32, - HIST_FIELD_FN_S16, - HIST_FIELD_FN_U16, - HIST_FIELD_FN_S8, - HIST_FIELD_FN_U8, - HIST_FIELD_FN_UMINUS, - HIST_FIELD_FN_MINUS, - HIST_FIELD_FN_PLUS, - HIST_FIELD_FN_DIV, - HIST_FIELD_FN_MULT, - HIST_FIELD_FN_DIV_POWER2, - HIST_FIELD_FN_DIV_NOT_POWER2, - HIST_FIELD_FN_DIV_MULT_SHIFT, - HIST_FIELD_FN_EXECNAME, - HIST_FIELD_FN_STACK, + FIELD_FUNCS }; /* @@ -726,7 +732,7 @@ static struct track_data *track_data_alloc(unsigned int key_len, struct action_data *action_data, struct hist_trigger_data *hist_data) { - struct track_data *data = kzalloc(sizeof(*data), GFP_KERNEL); + struct track_data *data = kzalloc_obj(*data); struct hist_elt_data *elt_data; if (!data) @@ -742,7 +748,7 @@ static struct track_data *track_data_alloc(unsigned int key_len, data->action_data = action_data; data->hist_data = hist_data; - elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL); + elt_data = kzalloc_obj(*elt_data); if (!elt_data) { track_data_free(data); return ERR_PTR(-ENOMEM); @@ -1080,7 +1086,7 @@ static int save_hist_vars(struct hist_trigger_data *hist_data) if (tracing_check_open_get_tr(tr)) return -ENODEV; - var_data = kzalloc(sizeof(*var_data), GFP_KERNEL); + var_data = kzalloc_obj(*var_data); if (!var_data) { trace_array_put(tr); return -ENOMEM; @@ -1542,7 +1548,7 @@ parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str) struct hist_trigger_attrs *attrs; int ret = 0; - attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_obj(*attrs); if (!attrs) return ERR_PTR(-ENOMEM); @@ -1640,7 +1646,7 @@ static int hist_trigger_elt_data_alloc(struct tracing_map_elt *elt) struct hist_field *hist_field; unsigned int i, n_str; - elt_data = kzalloc(sizeof(*elt_data), GFP_KERNEL); + elt_data = kzalloc_obj(*elt_data); if (!elt_data) return -ENOMEM; @@ -1956,7 +1962,7 @@ static struct hist_field *create_hist_field(struct hist_trigger_data *hist_data, if (field && is_function_field(field)) return NULL; - hist_field = kzalloc(sizeof(struct hist_field), GFP_KERNEL); + hist_field = kzalloc_obj(struct hist_field); if (!hist_field) return NULL; @@ -3043,7 +3049,7 @@ create_field_var_hist(struct hist_trigger_data *target_hist_data, if (!IS_ERR_OR_NULL(event_var)) return event_var; - var_hist = kzalloc(sizeof(*var_hist), GFP_KERNEL); + var_hist = kzalloc_obj(*var_hist); if (!var_hist) return ERR_PTR(-ENOMEM); @@ -3157,7 +3163,7 @@ static inline void __update_field_vars(struct tracing_map_elt *elt, u64 var_val; /* Make sure stacktrace can fit in the string variable length */ - BUILD_BUG_ON((HIST_STACKTRACE_DEPTH + 1) * sizeof(long) >= STR_VAR_LEN_MAX); + BUILD_BUG_ON((HIST_STACKTRACE_DEPTH + 1) * sizeof(long) > STR_VAR_LEN_MAX); for (i = 0, j = field_var_str_start; i < n_field_vars; i++) { struct field_var *field_var = field_vars[i]; @@ -3225,7 +3231,7 @@ static struct hist_field *create_var(struct hist_trigger_data *hist_data, goto out; } - var = kzalloc(sizeof(struct hist_field), GFP_KERNEL); + var = kzalloc_obj(struct hist_field); if (!var) { var = ERR_PTR(-ENOMEM); goto out; @@ -3286,7 +3292,7 @@ static struct field_var *create_field_var(struct hist_trigger_data *hist_data, goto err; } - field_var = kzalloc(sizeof(struct field_var), GFP_KERNEL); + field_var = kzalloc_obj(struct field_var); if (!field_var) { destroy_hist_field(val, 0); kfree_const(var->type); @@ -3825,7 +3831,7 @@ static struct action_data *track_data_parse(struct hist_trigger_data *hist_data, int ret = -EINVAL; char *var_str; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); @@ -4192,7 +4198,7 @@ static struct action_data *onmatch_parse(struct trace_array *tr, char *str) struct action_data *data; int ret = -EINVAL; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); @@ -5130,7 +5136,7 @@ create_hist_data(unsigned int map_bits, struct hist_trigger_data *hist_data; int ret = 0; - hist_data = kzalloc(sizeof(*hist_data), GFP_KERNEL); + hist_data = kzalloc_obj(*hist_data); if (!hist_data) return ERR_PTR(-ENOMEM); @@ -5668,8 +5674,7 @@ static int print_entries(struct seq_file *m, (HIST_FIELD_FL_PERCENT | HIST_FIELD_FL_GRAPH))) continue; if (!stats) { - stats = kcalloc(hist_data->n_vals, sizeof(*stats), - GFP_KERNEL); + stats = kzalloc_objs(*stats, hist_data->n_vals); if (!stats) { n_entries = -ENOMEM; goto out; @@ -5778,7 +5783,7 @@ static __poll_t event_hist_poll(struct file *file, struct poll_table_struct *wai guard(mutex)(&event_mutex); - event_file = event_file_data(file); + event_file = event_file_file(file); if (!event_file) return EPOLLERR; @@ -5816,13 +5821,13 @@ static int event_hist_open(struct inode *inode, struct file *file) guard(mutex)(&event_mutex); - event_file = event_file_data(file); + event_file = event_file_file(file); if (!event_file) { ret = -ENODEV; goto err; } - hist_file = kzalloc(sizeof(*hist_file), GFP_KERNEL); + hist_file = kzalloc_obj(*hist_file); if (!hist_file) { ret = -ENOMEM; goto err; @@ -5854,6 +5859,12 @@ const struct file_operations event_hist_fops = { }; #ifdef CONFIG_HIST_TRIGGERS_DEBUG + +#undef C +#define C(a, b) b + +static const char * const field_funcs[] = { FIELD_FUNCS }; + static void hist_field_debug_show_flags(struct seq_file *m, unsigned long flags) { @@ -5918,6 +5929,7 @@ static int hist_field_debug_show(struct seq_file *m, seq_printf(m, " type: %s\n", field->type); seq_printf(m, " size: %u\n", field->size); seq_printf(m, " is_signed: %u\n", field->is_signed); + seq_printf(m, " function: hist_field_%s()\n", field_funcs[field->fn_num]); return 0; } @@ -6518,6 +6530,26 @@ static bool existing_hist_update_only(char *glob, return updated; } +/* + * Set or disable using the per CPU trace_buffer_event when possible. + */ +static int tracing_set_filter_buffering(struct trace_array *tr, bool set) +{ + guard(mutex)(&trace_types_lock); + + if (set && tr->no_filter_buffering_ref++) + return 0; + + if (!set) { + if (WARN_ON_ONCE(!tr->no_filter_buffering_ref)) + return -EINVAL; + + --tr->no_filter_buffering_ref; + } + + return 0; +} + static int hist_register_trigger(char *glob, struct event_trigger_data *data, struct trace_event_file *file) @@ -6569,7 +6601,7 @@ static int hist_register_trigger(char *glob, data->private_data = named_data->private_data; set_named_trigger_data(data, named_data); /* Copy the command ops and update some of the functions */ - cmd_ops = kmalloc(sizeof(*cmd_ops), GFP_KERNEL); + cmd_ops = kmalloc_obj(*cmd_ops); if (!cmd_ops) { ret = -ENOMEM; goto out; @@ -6907,11 +6939,9 @@ static int event_hist_trigger_parse(struct event_command *cmd_ops, out_unreg: event_trigger_unregister(cmd_ops, file, glob+1, trigger_data); out_free: - event_trigger_reset_filter(cmd_ops, trigger_data); - remove_hist_vars(hist_data); - kfree(trigger_data); + trigger_data_free(trigger_data); destroy_hist_data(hist_data); goto out; diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c index 45c187e77e21..8bb95b2a6fcf 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -499,9 +499,9 @@ static unsigned int trace_stack(struct synth_trace_event *entry, return len; } -static notrace void trace_event_raw_event_synth(void *__data, - u64 *var_ref_vals, - unsigned int *var_ref_idx) +static void trace_event_raw_event_synth(void *__data, + u64 *var_ref_vals, + unsigned int *var_ref_idx) { unsigned int i, n_u64, val_idx, len, data_size = 0; struct trace_event_file *trace_file = __data; @@ -711,7 +711,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv, *field_version = check_field_version(prefix, field_type, field_name); - field = kzalloc(sizeof(*field), GFP_KERNEL); + field = kzalloc_obj(*field); if (!field) return ERR_PTR(-ENOMEM); @@ -819,7 +819,7 @@ static struct tracepoint *alloc_synth_tracepoint(char *name) { struct tracepoint *tp; - tp = kzalloc(sizeof(*tp), GFP_KERNEL); + tp = kzalloc_obj(*tp); if (!tp) return ERR_PTR(-ENOMEM); @@ -973,7 +973,7 @@ static struct synth_event *alloc_synth_event(const char *name, int n_fields, unsigned int i, j, n_dynamic_fields = 0; struct synth_event *event; - event = kzalloc(sizeof(*event), GFP_KERNEL); + event = kzalloc_obj(*event); if (!event) { event = ERR_PTR(-ENOMEM); goto out; @@ -986,7 +986,7 @@ static struct synth_event *alloc_synth_event(const char *name, int n_fields, goto out; } - event->fields = kcalloc(n_fields, sizeof(*event->fields), GFP_KERNEL); + event->fields = kzalloc_objs(*event->fields, n_fields); if (!event->fields) { free_synth_event(event); event = ERR_PTR(-ENOMEM); @@ -998,9 +998,8 @@ static struct synth_event *alloc_synth_event(const char *name, int n_fields, n_dynamic_fields++; if (n_dynamic_fields) { - event->dynamic_fields = kcalloc(n_dynamic_fields, - sizeof(*event->dynamic_fields), - GFP_KERNEL); + event->dynamic_fields = kzalloc_objs(*event->dynamic_fields, + n_dynamic_fields); if (!event->dynamic_fields) { free_synth_event(event); event = ERR_PTR(-ENOMEM); diff --git a/kernel/trace/trace_events_trigger.c b/kernel/trace/trace_events_trigger.c index 06b75bcfc7b8..d5230b759a2d 100644 --- a/kernel/trace/trace_events_trigger.c +++ b/kernel/trace/trace_events_trigger.c @@ -50,6 +50,9 @@ static int trigger_kthread_fn(void *ignore) void trigger_data_free(struct event_trigger_data *data) { + if (!data) + return; + if (data->cmd_ops->set_filter) data->cmd_ops->set_filter(NULL, data, NULL); @@ -914,7 +917,7 @@ struct event_trigger_data *trigger_data_alloc(struct event_command *cmd_ops, { struct event_trigger_data *trigger_data; - trigger_data = kzalloc(sizeof(*trigger_data), GFP_KERNEL); + trigger_data = kzalloc_obj(*trigger_data); if (!trigger_data) return NULL; @@ -1347,18 +1350,13 @@ traceon_trigger(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) { - if (tracer_tracing_is_on(file->tr)) - return; - - tracer_tracing_on(file->tr); - return; - } - - if (tracing_is_on()) + if (WARN_ON_ONCE(!file)) return; - tracing_on(); + if (tracer_tracing_is_on(file->tr)) + return; + + tracer_tracing_on(file->tr); } static bool @@ -1368,13 +1366,11 @@ traceon_count_func(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) { - if (tracer_tracing_is_on(file->tr)) - return false; - } else { - if (tracing_is_on()) - return false; - } + if (WARN_ON_ONCE(!file)) + return false; + + if (tracer_tracing_is_on(file->tr)) + return false; if (!data->count) return false; @@ -1392,18 +1388,13 @@ traceoff_trigger(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) { - if (!tracer_tracing_is_on(file->tr)) - return; - - tracer_tracing_off(file->tr); - return; - } - - if (!tracing_is_on()) + if (WARN_ON_ONCE(!file)) return; - tracing_off(); + if (!tracer_tracing_is_on(file->tr)) + return; + + tracer_tracing_off(file->tr); } static bool @@ -1413,13 +1404,11 @@ traceoff_count_func(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) { - if (!tracer_tracing_is_on(file->tr)) - return false; - } else { - if (!tracing_is_on()) - return false; - } + if (WARN_ON_ONCE(!file)) + return false; + + if (!tracer_tracing_is_on(file->tr)) + return false; if (!data->count) return false; @@ -1481,10 +1470,10 @@ snapshot_trigger(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) - tracing_snapshot_instance(file->tr); - else - tracing_snapshot(); + if (WARN_ON_ONCE(!file)) + return; + + tracing_snapshot_instance(file->tr); } static int @@ -1570,10 +1559,10 @@ stacktrace_trigger(struct event_trigger_data *data, { struct trace_event_file *file = data->private_data; - if (file) - __trace_stack(file->tr, tracing_gen_ctx_dec(), STACK_SKIP); - else - trace_dump_stack(STACK_SKIP); + if (WARN_ON_ONCE(!file)) + return; + + __trace_stack(file->tr, tracing_gen_ctx_dec(), STACK_SKIP); } static int @@ -1738,7 +1727,7 @@ int event_enable_trigger_parse(struct event_command *cmd_ops, #endif ret = -ENOMEM; - enable_data = kzalloc(sizeof(*enable_data), GFP_KERNEL); + enable_data = kzalloc_obj(*enable_data); if (!enable_data) return ret; diff --git a/kernel/trace/trace_events_user.c b/kernel/trace/trace_events_user.c index dca6e50b3b21..c4ba484f7b38 100644 --- a/kernel/trace/trace_events_user.c +++ b/kernel/trace/trace_events_user.c @@ -370,7 +370,7 @@ static struct user_event_group *user_event_group_create(void) { struct user_event_group *group; - group = kzalloc(sizeof(*group), GFP_KERNEL); + group = kzalloc_obj(*group); if (!group) return NULL; @@ -637,7 +637,7 @@ static bool user_event_enabler_dup(struct user_event_enabler *orig, if (unlikely(test_bit(ENABLE_VAL_FREEING_BIT, ENABLE_BITOPS(orig)))) return true; - enabler = kzalloc(sizeof(*enabler), GFP_NOWAIT | __GFP_ACCOUNT); + enabler = kzalloc_obj(*enabler, GFP_NOWAIT | __GFP_ACCOUNT); if (!enabler) return false; @@ -706,7 +706,7 @@ static struct user_event_mm *user_event_mm_alloc(struct task_struct *t) { struct user_event_mm *user_mm; - user_mm = kzalloc(sizeof(*user_mm), GFP_KERNEL_ACCOUNT); + user_mm = kzalloc_obj(*user_mm, GFP_KERNEL_ACCOUNT); if (!user_mm) return NULL; @@ -892,7 +892,7 @@ static struct user_event_enabler if (!user_mm) return NULL; - enabler = kzalloc(sizeof(*enabler), GFP_KERNEL_ACCOUNT); + enabler = kzalloc_obj(*enabler, GFP_KERNEL_ACCOUNT); if (!enabler) goto out; @@ -1113,7 +1113,7 @@ static int user_event_add_field(struct user_event *user, const char *type, struct ftrace_event_field *field; int validator_flags = 0; - field = kmalloc(sizeof(*field), GFP_KERNEL_ACCOUNT); + field = kmalloc_obj(*field, GFP_KERNEL_ACCOUNT); if (!field) return -ENOMEM; @@ -1132,7 +1132,7 @@ static int user_event_add_field(struct user_event *user, const char *type, if (strstr(type, "char") != NULL) validator_flags |= VALIDATOR_ENSURE_NULL; - validator = kmalloc(sizeof(*validator), GFP_KERNEL_ACCOUNT); + validator = kmalloc_obj(*validator, GFP_KERNEL_ACCOUNT); if (!validator) { kfree(field); @@ -2105,7 +2105,7 @@ static int user_event_parse(struct user_event_group *group, char *name, return 0; } - user = kzalloc(sizeof(*user), GFP_KERNEL_ACCOUNT); + user = kzalloc_obj(*user, GFP_KERNEL_ACCOUNT); if (!user) return -ENOMEM; @@ -2315,7 +2315,7 @@ static int user_events_open(struct inode *node, struct file *file) if (!group) return -ENOENT; - info = kzalloc(sizeof(*info), GFP_KERNEL_ACCOUNT); + info = kzalloc_obj(*info, GFP_KERNEL_ACCOUNT); if (!info) return -ENOMEM; diff --git a/kernel/trace/trace_fprobe.c b/kernel/trace/trace_fprobe.c index 262c0556e4af..9f5f08c0e7c2 100644 --- a/kernel/trace/trace_fprobe.c +++ b/kernel/trace/trace_fprobe.c @@ -99,7 +99,7 @@ static struct tracepoint_user *__tracepoint_user_init(const char *name, struct t struct tracepoint_user *tuser __free(tuser_free) = NULL; int ret; - tuser = kzalloc(sizeof(*tuser), GFP_KERNEL); + tuser = kzalloc_obj(*tuser); if (!tuser) return NULL; tuser->name = kstrdup(name, GFP_KERNEL); @@ -579,7 +579,7 @@ static struct trace_fprobe *alloc_trace_fprobe(const char *group, struct trace_fprobe *tf __free(free_trace_fprobe) = NULL; int ret = -ENOMEM; - tf = kzalloc(struct_size(tf, tp.args, nargs), GFP_KERNEL); + tf = kzalloc_flex(*tf, tp.args, nargs); if (!tf) return ERR_PTR(ret); @@ -1403,7 +1403,7 @@ static int trace_fprobe_create_cb(int argc, const char *argv[]) struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) = NULL; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index c12795c2fb39..f283391a4dc8 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c @@ -61,7 +61,7 @@ int ftrace_allocate_ftrace_ops(struct trace_array *tr) if (tr->flags & TRACE_ARRAY_FL_GLOBAL) return 0; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); if (!ops) return -ENOMEM; diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c index 1de6f1573621..0d2d3a2ea7dd 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -400,14 +400,19 @@ static void trace_graph_thresh_return(struct ftrace_graph_ret *trace, struct fgraph_ops *gops, struct ftrace_regs *fregs) { + unsigned long *task_var = fgraph_get_task_var(gops); struct fgraph_times *ftimes; struct trace_array *tr; + unsigned int trace_ctx; + u64 calltime, rettime; int size; + rettime = trace_clock_local(); + ftrace_graph_addr_finish(gops, trace); - if (trace_recursion_test(TRACE_GRAPH_NOTRACE_BIT)) { - trace_recursion_clear(TRACE_GRAPH_NOTRACE_BIT); + if (*task_var & TRACE_GRAPH_NOTRACE) { + *task_var &= ~TRACE_GRAPH_NOTRACE; return; } @@ -418,11 +423,13 @@ static void trace_graph_thresh_return(struct ftrace_graph_ret *trace, tr = gops->private; handle_nosleeptime(tr, trace, ftimes, size); - if (tracing_thresh && - (trace_clock_local() - ftimes->calltime < tracing_thresh)) + calltime = ftimes->calltime; + + if (tracing_thresh && (rettime - calltime < tracing_thresh)) return; - else - trace_graph_return(trace, gops, fregs); + + trace_ctx = tracing_gen_ctx(); + __trace_graph_return(tr, trace, trace_ctx, calltime, rettime); } static struct fgraph_ops funcgraph_ops = { @@ -434,7 +441,7 @@ int allocate_fgraph_ops(struct trace_array *tr, struct ftrace_ops *ops) { struct fgraph_ops *gops; - gops = kzalloc(sizeof(*gops), GFP_KERNEL); + gops = kzalloc_obj(*gops); if (!gops) return -ENOMEM; @@ -1613,7 +1620,7 @@ void graph_trace_open(struct trace_iterator *iter) /* We can be called in atomic context via ftrace_dump() */ gfpflags = (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL; - data = kzalloc(sizeof(*data), gfpflags); + data = kzalloc_obj(*data, gfpflags); if (!data) goto out_err; diff --git a/kernel/trace/trace_hwlat.c b/kernel/trace/trace_hwlat.c index 2f7b94e98317..3fe274b84f1c 100644 --- a/kernel/trace/trace_hwlat.c +++ b/kernel/trace/trace_hwlat.c @@ -102,9 +102,9 @@ struct hwlat_sample { /* keep the global state somewhere. */ static struct hwlat_data { - struct mutex lock; /* protect changes */ + struct mutex lock; /* protect changes */ - u64 count; /* total since reset */ + atomic64_t count; /* total since reset */ u64 sample_window; /* total sampling window (on+off) */ u64 sample_width; /* active sampling portion of window */ @@ -193,8 +193,7 @@ void trace_hwlat_callback(bool enter) * get_sample - sample the CPU TSC and look for likely hardware latencies * * Used to repeatedly capture the CPU TSC (or similar), looking for potential - * hardware-induced latency. Called with interrupts disabled and with - * hwlat_data.lock held. + * hardware-induced latency. Called with interrupts disabled. */ static int get_sample(void) { @@ -204,6 +203,7 @@ static int get_sample(void) time_type start, t1, t2, last_t2; s64 diff, outer_diff, total, last_total = 0; u64 sample = 0; + u64 sample_width = READ_ONCE(hwlat_data.sample_width); u64 thresh = tracing_thresh; u64 outer_sample = 0; int ret = -1; @@ -267,7 +267,7 @@ static int get_sample(void) if (diff > sample) sample = diff; /* only want highest value */ - } while (total <= hwlat_data.sample_width); + } while (total <= sample_width); barrier(); /* finish the above in the view for NMIs */ trace_hwlat_callback_enabled = false; @@ -285,8 +285,7 @@ static int get_sample(void) if (kdata->nmi_total_ts) do_div(kdata->nmi_total_ts, NSEC_PER_USEC); - hwlat_data.count++; - s.seqnum = hwlat_data.count; + s.seqnum = atomic64_inc_return(&hwlat_data.count); s.duration = sample; s.outer_duration = outer_sample; s.nmi_total_ts = kdata->nmi_total_ts; @@ -832,7 +831,7 @@ static int hwlat_tracer_init(struct trace_array *tr) hwlat_trace = tr; - hwlat_data.count = 0; + atomic64_set(&hwlat_data.count, 0); tr->max_latency = 0; save_tracing_thresh = tracing_thresh; diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 9953506370a5..a5dbb72528e0 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -82,6 +82,7 @@ static struct trace_kprobe *to_trace_kprobe(struct dyn_event *ev) #define for_each_trace_kprobe(pos, dpos) \ for_each_dyn_event(dpos) \ if (is_trace_kprobe(dpos) && (pos = to_trace_kprobe(dpos))) +#define trace_kprobe_list_empty() list_empty(&dyn_event_list) static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk) { @@ -274,7 +275,7 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group, struct trace_kprobe *tk __free(free_trace_kprobe) = NULL; int ret = -ENOMEM; - tk = kzalloc(struct_size(tk, tp.args, nargs), GFP_KERNEL); + tk = kzalloc_flex(*tk, tp.args, nargs); if (!tk) return ERR_PTR(ret); @@ -1081,7 +1082,7 @@ static int trace_kprobe_create_cb(int argc, const char *argv[]) struct traceprobe_parse_context *ctx __free(traceprobe_parse_context) = NULL; int ret; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->flags = TPARG_FL_KERNEL; @@ -1982,6 +1983,9 @@ static __init void enable_boot_kprobe_events(void) struct trace_kprobe *tk; struct dyn_event *pos; + if (trace_kprobe_list_empty()) + return; + guard(mutex)(&event_mutex); for_each_trace_kprobe(tk, pos) { list_for_each_entry(file, &tr->events, list) @@ -2048,6 +2052,10 @@ static __init int init_kprobe_trace(void) trace_create_file("kprobe_profile", TRACE_MODE_READ, NULL, NULL, &kprobe_profile_ops); + /* If no 'kprobe_event=' cmd is provided, return directly. */ + if (kprobe_boot_events_buf[0] == '\0') + return 0; + setup_boot_kprobe_events(); return 0; @@ -2079,7 +2087,7 @@ static __init int kprobe_trace_self_tests_init(void) struct trace_kprobe *tk; struct trace_event_file *file; - if (tracing_is_disabled()) + if (unlikely(tracing_disabled)) return -ENODEV; if (tracing_selftest_disabled) diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index c706544be60c..226cf66e0d68 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c @@ -101,7 +101,7 @@ static void mmio_pipe_open(struct trace_iterator *iter) trace_seq_puts(s, "VERSION 20070824\n"); - hiter = kzalloc(sizeof(*hiter), GFP_KERNEL); + hiter = kzalloc_obj(*hiter); if (!hiter) return; diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c index 827104d00bc0..dee610e465b9 100644 --- a/kernel/trace/trace_osnoise.c +++ b/kernel/trace/trace_osnoise.c @@ -122,7 +122,7 @@ static int osnoise_register_instance(struct trace_array *tr) */ lockdep_assert_held(&trace_types_lock); - inst = kmalloc(sizeof(*inst), GFP_KERNEL); + inst = kmalloc_obj(*inst); if (!inst) return -ENOMEM; diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index cc2d3306bb60..1996d7aba038 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -194,13 +194,37 @@ trace_print_symbols_seq_u64(struct trace_seq *p, unsigned long long val, EXPORT_SYMBOL(trace_print_symbols_seq_u64); #endif +/** + * trace_print_bitmask_seq - print a bitmask to a sequence buffer + * @iter: The trace iterator for the current event instance + * @bitmask_ptr: The pointer to the bitmask data + * @bitmask_size: The size of the bitmask in bytes + * + * Prints a bitmask into a sequence buffer as either a hex string or a + * human-readable range list, depending on the instance's "bitmask-list" + * trace option. The bitmask is formatted into the iterator's temporary + * scratchpad rather than the primary sequence buffer. This avoids + * duplication and pointer-collision issues when the returned string is + * processed by a "%s" specifier in a TP_printk() macro. + * + * Returns a pointer to the formatted string within the temporary buffer. + */ const char * -trace_print_bitmask_seq(struct trace_seq *p, void *bitmask_ptr, +trace_print_bitmask_seq(struct trace_iterator *iter, void *bitmask_ptr, unsigned int bitmask_size) { - const char *ret = trace_seq_buffer_ptr(p); + struct trace_seq *p = &iter->tmp_seq; + const struct trace_array *tr = iter->tr; + const char *ret; + + trace_seq_init(p); + ret = trace_seq_buffer_ptr(p); + + if (tr->trace_flags & TRACE_ITER(BITMASK_LIST)) + trace_seq_bitmask_list(p, bitmask_ptr, bitmask_size * 8); + else + trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); - trace_seq_bitmask(p, bitmask_ptr, bitmask_size * 8); trace_seq_putc(p, 0); return ret; diff --git a/kernel/trace/trace_pid.c b/kernel/trace/trace_pid.c new file mode 100644 index 000000000000..7127c8de4174 --- /dev/null +++ b/kernel/trace/trace_pid.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "trace.h" + +/** + * trace_find_filtered_pid - check if a pid exists in a filtered_pid list + * @filtered_pids: The list of pids to check + * @search_pid: The PID to find in @filtered_pids + * + * Returns true if @search_pid is found in @filtered_pids, and false otherwise. + */ +bool +trace_find_filtered_pid(struct trace_pid_list *filtered_pids, pid_t search_pid) +{ + return trace_pid_list_is_set(filtered_pids, search_pid); +} + +/** + * trace_ignore_this_task - should a task be ignored for tracing + * @filtered_pids: The list of pids to check + * @filtered_no_pids: The list of pids not to be traced + * @task: The task that should be ignored if not filtered + * + * Checks if @task should be traced or not from @filtered_pids. + * Returns true if @task should *NOT* be traced. + * Returns false if @task should be traced. + */ +bool +trace_ignore_this_task(struct trace_pid_list *filtered_pids, + struct trace_pid_list *filtered_no_pids, + struct task_struct *task) +{ + /* + * If filtered_no_pids is not empty, and the task's pid is listed + * in filtered_no_pids, then return true. + * Otherwise, if filtered_pids is empty, that means we can + * trace all tasks. If it has content, then only trace pids + * within filtered_pids. + */ + + return (filtered_pids && + !trace_find_filtered_pid(filtered_pids, task->pid)) || + (filtered_no_pids && + trace_find_filtered_pid(filtered_no_pids, task->pid)); +} + +/** + * trace_filter_add_remove_task - Add or remove a task from a pid_list + * @pid_list: The list to modify + * @self: The current task for fork or NULL for exit + * @task: The task to add or remove + * + * If adding a task, if @self is defined, the task is only added if @self + * is also included in @pid_list. This happens on fork and tasks should + * only be added when the parent is listed. If @self is NULL, then the + * @task pid will be removed from the list, which would happen on exit + * of a task. + */ +void trace_filter_add_remove_task(struct trace_pid_list *pid_list, + struct task_struct *self, + struct task_struct *task) +{ + if (!pid_list) + return; + + /* For forks, we only add if the forking task is listed */ + if (self) { + if (!trace_find_filtered_pid(pid_list, self->pid)) + return; + } + + /* "self" is set for forks, and NULL for exits */ + if (self) + trace_pid_list_set(pid_list, task->pid); + else + trace_pid_list_clear(pid_list, task->pid); +} + +/** + * trace_pid_next - Used for seq_file to get to the next pid of a pid_list + * @pid_list: The pid list to show + * @v: The last pid that was shown (+1 the actual pid to let zero be displayed) + * @pos: The position of the file + * + * This is used by the seq_file "next" operation to iterate the pids + * listed in a trace_pid_list structure. + * + * Returns the pid+1 as we want to display pid of zero, but NULL would + * stop the iteration. + */ +void *trace_pid_next(struct trace_pid_list *pid_list, void *v, loff_t *pos) +{ + long pid = (unsigned long)v; + unsigned int next; + + (*pos)++; + + /* pid already is +1 of the actual previous bit */ + if (trace_pid_list_next(pid_list, pid, &next) < 0) + return NULL; + + pid = next; + + /* Return pid + 1 to allow zero to be represented */ + return (void *)(pid + 1); +} + +/** + * trace_pid_start - Used for seq_file to start reading pid lists + * @pid_list: The pid list to show + * @pos: The position of the file + * + * This is used by seq_file "start" operation to start the iteration + * of listing pids. + * + * Returns the pid+1 as we want to display pid of zero, but NULL would + * stop the iteration. + */ +void *trace_pid_start(struct trace_pid_list *pid_list, loff_t *pos) +{ + unsigned long pid; + unsigned int first; + loff_t l = 0; + + if (trace_pid_list_first(pid_list, &first) < 0) + return NULL; + + pid = first; + + /* Return pid + 1 so that zero can be the exit value */ + for (pid++; pid && l < *pos; + pid = (unsigned long)trace_pid_next(pid_list, (void *)pid, &l)) + ; + return (void *)pid; +} + +/** + * trace_pid_show - show the current pid in seq_file processing + * @m: The seq_file structure to write into + * @v: A void pointer of the pid (+1) value to display + * + * Can be directly used by seq_file operations to display the current + * pid value. + */ +int trace_pid_show(struct seq_file *m, void *v) +{ + unsigned long pid = (unsigned long)v - 1; + + seq_printf(m, "%lu\n", pid); + return 0; +} + +/* 128 should be much more than enough */ +#define PID_BUF_SIZE 127 + +int trace_pid_write(struct trace_pid_list *filtered_pids, + struct trace_pid_list **new_pid_list, + const char __user *ubuf, size_t cnt) +{ + struct trace_pid_list *pid_list; + struct trace_parser parser; + unsigned long val; + int nr_pids = 0; + ssize_t read = 0; + ssize_t ret; + loff_t pos; + pid_t pid; + + if (trace_parser_get_init(&parser, PID_BUF_SIZE + 1)) + return -ENOMEM; + + /* + * Always recreate a new array. The write is an all or nothing + * operation. Always create a new array when adding new pids by + * the user. If the operation fails, then the current list is + * not modified. + */ + pid_list = trace_pid_list_alloc(); + if (!pid_list) { + trace_parser_put(&parser); + return -ENOMEM; + } + + if (filtered_pids) { + /* copy the current bits to the new max */ + ret = trace_pid_list_first(filtered_pids, &pid); + while (!ret) { + ret = trace_pid_list_set(pid_list, pid); + if (ret < 0) + goto out; + + ret = trace_pid_list_next(filtered_pids, pid + 1, &pid); + nr_pids++; + } + } + + ret = 0; + while (cnt > 0) { + + pos = 0; + + ret = trace_get_user(&parser, ubuf, cnt, &pos); + if (ret < 0) + break; + + read += ret; + ubuf += ret; + cnt -= ret; + + if (!trace_parser_loaded(&parser)) + break; + + ret = -EINVAL; + if (kstrtoul(parser.buffer, 0, &val)) + break; + + pid = (pid_t)val; + + if (trace_pid_list_set(pid_list, pid) < 0) { + ret = -1; + break; + } + nr_pids++; + + trace_parser_clear(&parser); + ret = 0; + } + out: + trace_parser_put(&parser); + + if (ret < 0) { + trace_pid_list_free(pid_list); + return ret; + } + + if (!nr_pids) { + /* Cleared the list of pids */ + trace_pid_list_free(pid_list); + pid_list = NULL; + } + + *new_pid_list = pid_list; + + return read; +} + diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 29f6e95439b6..5ea5e0d76f00 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c @@ -69,7 +69,7 @@ void hold_module_trace_bprintk_format(const char **start, const char **end) } fmt = NULL; - tb_fmt = kmalloc(sizeof(*tb_fmt), GFP_KERNEL); + tb_fmt = kmalloc_obj(*tb_fmt); if (tb_fmt) { fmt = kmalloc(strlen(*iter) + 1, GFP_KERNEL); if (fmt) { @@ -376,6 +376,436 @@ static const struct file_operations ftrace_formats_fops = { .release = seq_release, }; +static __always_inline bool printk_binsafe(struct trace_array *tr) +{ + /* + * The binary format of traceprintk can cause a crash if used + * by a buffer from another boot. Force the use of the + * non binary version of trace_printk if the trace_printk + * buffer is a boot mapped ring buffer. + */ + return !(tr->flags & TRACE_ARRAY_FL_BOOT); +} + +int __trace_array_puts(struct trace_array *tr, unsigned long ip, + const char *str, int size) +{ + struct ring_buffer_event *event; + struct trace_buffer *buffer; + struct print_entry *entry; + unsigned int trace_ctx; + int alloc; + + if (!(tr->trace_flags & TRACE_ITER(PRINTK))) + return 0; + + if (unlikely(tracing_selftest_running && + (tr->flags & TRACE_ARRAY_FL_GLOBAL))) + return 0; + + if (unlikely(tracing_disabled)) + return 0; + + alloc = sizeof(*entry) + size + 2; /* possible \n added */ + + trace_ctx = tracing_gen_ctx(); + buffer = tr->array_buffer.buffer; + guard(ring_buffer_nest)(buffer); + event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, + trace_ctx); + if (!event) + return 0; + + entry = ring_buffer_event_data(event); + entry->ip = ip; + + memcpy(&entry->buf, str, size); + + /* Add a newline if necessary */ + if (entry->buf[size - 1] != '\n') { + entry->buf[size] = '\n'; + entry->buf[size + 1] = '\0'; + } else + entry->buf[size] = '\0'; + + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); + return size; +} +EXPORT_SYMBOL_GPL(__trace_array_puts); + +/** + * __trace_puts - write a constant string into the trace buffer. + * @ip: The address of the caller + * @str: The constant string to write + */ +int __trace_puts(unsigned long ip, const char *str) +{ + return __trace_array_puts(printk_trace, ip, str, strlen(str)); +} +EXPORT_SYMBOL_GPL(__trace_puts); + +/** + * __trace_bputs - write the pointer to a constant string into trace buffer + * @ip: The address of the caller + * @str: The constant string to write to the buffer to + */ +int __trace_bputs(unsigned long ip, const char *str) +{ + struct trace_array *tr = READ_ONCE(printk_trace); + struct ring_buffer_event *event; + struct trace_buffer *buffer; + struct bputs_entry *entry; + unsigned int trace_ctx; + int size = sizeof(struct bputs_entry); + + if (!printk_binsafe(tr)) + return __trace_puts(ip, str); + + if (!(tr->trace_flags & TRACE_ITER(PRINTK))) + return 0; + + if (unlikely(tracing_selftest_running || tracing_disabled)) + return 0; + + trace_ctx = tracing_gen_ctx(); + buffer = tr->array_buffer.buffer; + + guard(ring_buffer_nest)(buffer); + event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size, + trace_ctx); + if (!event) + return 0; + + entry = ring_buffer_event_data(event); + entry->ip = ip; + entry->str = str; + + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(tr, buffer, trace_ctx, 4, NULL); + + return 1; +} +EXPORT_SYMBOL_GPL(__trace_bputs); + +/* created for use with alloc_percpu */ +struct trace_buffer_struct { + int nesting; + char buffer[4][TRACE_BUF_SIZE]; +}; + +static struct trace_buffer_struct __percpu *trace_percpu_buffer; + +/* + * This allows for lockless recording. If we're nested too deeply, then + * this returns NULL. + */ +static char *get_trace_buf(void) +{ + struct trace_buffer_struct *buffer = this_cpu_ptr(trace_percpu_buffer); + + if (!trace_percpu_buffer || buffer->nesting >= 4) + return NULL; + + buffer->nesting++; + + /* Interrupts must see nesting incremented before we use the buffer */ + barrier(); + return &buffer->buffer[buffer->nesting - 1][0]; +} + +static void put_trace_buf(void) +{ + /* Don't let the decrement of nesting leak before this */ + barrier(); + this_cpu_dec(trace_percpu_buffer->nesting); +} + +static int alloc_percpu_trace_buffer(void) +{ + struct trace_buffer_struct __percpu *buffers; + + if (trace_percpu_buffer) + return 0; + + buffers = alloc_percpu(struct trace_buffer_struct); + if (MEM_FAIL(!buffers, "Could not allocate percpu trace_printk buffer")) + return -ENOMEM; + + trace_percpu_buffer = buffers; + return 0; +} + +static int buffers_allocated; + +void trace_printk_init_buffers(void) +{ + if (buffers_allocated) + return; + + if (alloc_percpu_trace_buffer()) + return; + + /* trace_printk() is for debug use only. Don't use it in production. */ + + pr_warn("\n"); + pr_warn("**********************************************************\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); + pr_warn("** **\n"); + pr_warn("** trace_printk() being used. Allocating extra memory. **\n"); + pr_warn("** **\n"); + pr_warn("** This means that this is a DEBUG kernel and it is **\n"); + pr_warn("** unsafe for production use. **\n"); + pr_warn("** **\n"); + pr_warn("** If you see this message and you are not debugging **\n"); + pr_warn("** the kernel, report this immediately to your vendor! **\n"); + pr_warn("** **\n"); + pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); + pr_warn("**********************************************************\n"); + + /* Expand the buffers to set size */ + if (tracing_update_buffers(NULL) < 0) + pr_err("Failed to expand tracing buffers for trace_printk() calls\n"); + else + buffers_allocated = 1; + + /* + * trace_printk_init_buffers() can be called by modules. + * If that happens, then we need to start cmdline recording + * directly here. + */ + if (system_state == SYSTEM_RUNNING) + tracing_start_cmdline_record(); +} +EXPORT_SYMBOL_GPL(trace_printk_init_buffers); + +void trace_printk_start_comm(void) +{ + /* Start tracing comms if trace printk is set */ + if (!buffers_allocated) + return; + tracing_start_cmdline_record(); +} + +void trace_printk_start_stop_comm(int enabled) +{ + if (!buffers_allocated) + return; + + if (enabled) + tracing_start_cmdline_record(); + else + tracing_stop_cmdline_record(); +} + +/** + * trace_vbprintk - write binary msg to tracing buffer + * @ip: The address of the caller + * @fmt: The string format to write to the buffer + * @args: Arguments for @fmt + */ +int trace_vbprintk(unsigned long ip, const char *fmt, va_list args) +{ + struct ring_buffer_event *event; + struct trace_buffer *buffer; + struct trace_array *tr = READ_ONCE(printk_trace); + struct bprint_entry *entry; + unsigned int trace_ctx; + char *tbuffer; + int len = 0, size; + + if (!printk_binsafe(tr)) + return trace_vprintk(ip, fmt, args); + + if (unlikely(tracing_selftest_running || tracing_disabled)) + return 0; + + /* Don't pollute graph traces with trace_vprintk internals */ + pause_graph_tracing(); + + trace_ctx = tracing_gen_ctx(); + guard(preempt_notrace)(); + + tbuffer = get_trace_buf(); + if (!tbuffer) { + len = 0; + goto out_nobuffer; + } + + len = vbin_printf((u32 *)tbuffer, TRACE_BUF_SIZE/sizeof(int), fmt, args); + + if (len > TRACE_BUF_SIZE/sizeof(int) || len < 0) + goto out_put; + + size = sizeof(*entry) + sizeof(u32) * len; + buffer = tr->array_buffer.buffer; + scoped_guard(ring_buffer_nest, buffer) { + event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size, + trace_ctx); + if (!event) + goto out_put; + entry = ring_buffer_event_data(event); + entry->ip = ip; + entry->fmt = fmt; + + memcpy(entry->buf, tbuffer, sizeof(u32) * len); + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(tr, buffer, trace_ctx, 6, NULL); + } +out_put: + put_trace_buf(); + +out_nobuffer: + unpause_graph_tracing(); + + return len; +} +EXPORT_SYMBOL_GPL(trace_vbprintk); + +static __printf(3, 0) +int __trace_array_vprintk(struct trace_buffer *buffer, + unsigned long ip, const char *fmt, va_list args) +{ + struct ring_buffer_event *event; + int len = 0, size; + struct print_entry *entry; + unsigned int trace_ctx; + char *tbuffer; + + if (unlikely(tracing_disabled)) + return 0; + + /* Don't pollute graph traces with trace_vprintk internals */ + pause_graph_tracing(); + + trace_ctx = tracing_gen_ctx(); + guard(preempt_notrace)(); + + + tbuffer = get_trace_buf(); + if (!tbuffer) { + len = 0; + goto out_nobuffer; + } + + len = vscnprintf(tbuffer, TRACE_BUF_SIZE, fmt, args); + + size = sizeof(*entry) + len + 1; + scoped_guard(ring_buffer_nest, buffer) { + event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size, + trace_ctx); + if (!event) + goto out; + entry = ring_buffer_event_data(event); + entry->ip = ip; + + memcpy(&entry->buf, tbuffer, len + 1); + __buffer_unlock_commit(buffer, event); + ftrace_trace_stack(printk_trace, buffer, trace_ctx, 6, NULL); + } +out: + put_trace_buf(); + +out_nobuffer: + unpause_graph_tracing(); + + return len; +} + +int trace_array_vprintk(struct trace_array *tr, + unsigned long ip, const char *fmt, va_list args) +{ + if (tracing_selftest_running && (tr->flags & TRACE_ARRAY_FL_GLOBAL)) + return 0; + + return __trace_array_vprintk(tr->array_buffer.buffer, ip, fmt, args); +} + +/** + * trace_array_printk - Print a message to a specific instance + * @tr: The instance trace_array descriptor + * @ip: The instruction pointer that this is called from. + * @fmt: The format to print (printf format) + * + * If a subsystem sets up its own instance, they have the right to + * printk strings into their tracing instance buffer using this + * function. Note, this function will not write into the top level + * buffer (use trace_printk() for that), as writing into the top level + * buffer should only have events that can be individually disabled. + * trace_printk() is only used for debugging a kernel, and should not + * be ever incorporated in normal use. + * + * trace_array_printk() can be used, as it will not add noise to the + * top level tracing buffer. + * + * Note, trace_array_init_printk() must be called on @tr before this + * can be used. + */ +int trace_array_printk(struct trace_array *tr, + unsigned long ip, const char *fmt, ...) +{ + int ret; + va_list ap; + + if (!tr) + return -ENOENT; + + /* This is only allowed for created instances */ + if (tr->flags & TRACE_ARRAY_FL_GLOBAL) + return 0; + + if (!(tr->trace_flags & TRACE_ITER(PRINTK))) + return 0; + + va_start(ap, fmt); + ret = trace_array_vprintk(tr, ip, fmt, ap); + va_end(ap); + return ret; +} +EXPORT_SYMBOL_GPL(trace_array_printk); + +/** + * trace_array_init_printk - Initialize buffers for trace_array_printk() + * @tr: The trace array to initialize the buffers for + * + * As trace_array_printk() only writes into instances, they are OK to + * have in the kernel (unlike trace_printk()). This needs to be called + * before trace_array_printk() can be used on a trace_array. + */ +int trace_array_init_printk(struct trace_array *tr) +{ + if (!tr) + return -ENOENT; + + /* This is only allowed for created instances */ + if (tr->flags & TRACE_ARRAY_FL_GLOBAL) + return -EINVAL; + + return alloc_percpu_trace_buffer(); +} +EXPORT_SYMBOL_GPL(trace_array_init_printk); + +int trace_array_printk_buf(struct trace_buffer *buffer, + unsigned long ip, const char *fmt, ...) +{ + int ret; + va_list ap; + + if (!(printk_trace->trace_flags & TRACE_ITER(PRINTK))) + return 0; + + va_start(ap, fmt); + ret = __trace_array_vprintk(buffer, ip, fmt, ap); + va_end(ap); + return ret; +} + +int trace_vprintk(unsigned long ip, const char *fmt, va_list args) +{ + return trace_array_vprintk(printk_trace, ip, fmt, args); +} +EXPORT_SYMBOL_GPL(trace_vprintk); + static __init int init_trace_printk_function_export(void) { int ret; diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index 2f571083ce9e..e0a5dc86c07e 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -838,12 +838,11 @@ static int __store_entry_arg(struct trace_probe *tp, int argnum) int i, offset, last_offset = 0; if (!earg) { - earg = kzalloc(sizeof(*tp->entry_arg), GFP_KERNEL); + earg = kzalloc_obj(*tp->entry_arg); if (!earg) return -ENOMEM; earg->size = 2 * tp->nr_args + 1; - earg->code = kcalloc(earg->size, sizeof(struct fetch_insn), - GFP_KERNEL); + earg->code = kzalloc_objs(struct fetch_insn, earg->size); if (!earg->code) { kfree(earg); return -ENOMEM; @@ -1499,7 +1498,7 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, if (IS_ERR(type)) return PTR_ERR(type); - code = tmp = kcalloc(FETCH_INSN_MAX, sizeof(*code), GFP_KERNEL); + code = tmp = kzalloc_objs(*code, FETCH_INSN_MAX); if (!code) return -ENOMEM; code[FETCH_INSN_MAX - 1].op = FETCH_OP_END; @@ -1543,7 +1542,7 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size, if (code->op == FETCH_OP_END) break; /* Shrink down the code buffer */ - parg->code = kcalloc(code - tmp + 1, sizeof(*code), GFP_KERNEL); + parg->code = kzalloc_objs(*code, code - tmp + 1); if (!parg->code) ret = -ENOMEM; else @@ -2149,7 +2148,7 @@ int trace_probe_add_file(struct trace_probe *tp, struct trace_event_file *file) { struct event_file_link *link; - link = kmalloc(sizeof(*link), GFP_KERNEL); + link = kmalloc_obj(*link); if (!link) return -ENOMEM; diff --git a/kernel/trace/trace_recursion_record.c b/kernel/trace/trace_recursion_record.c index a520b11afb0d..784fe1fbb866 100644 --- a/kernel/trace/trace_recursion_record.c +++ b/kernel/trace/trace_recursion_record.c @@ -129,7 +129,7 @@ static void *recursed_function_seq_start(struct seq_file *m, loff_t *pos) ret = &recursed_functions[*pos]; } - tseq = kzalloc(sizeof(*tseq), GFP_KERNEL); + tseq = kzalloc_obj(*tseq); if (!tseq) return ERR_PTR(-ENOMEM); diff --git a/kernel/trace/trace_sched_switch.c b/kernel/trace/trace_sched_switch.c index c46d584ded3b..e9f0ff962660 100644 --- a/kernel/trace/trace_sched_switch.c +++ b/kernel/trace/trace_sched_switch.c @@ -444,8 +444,7 @@ int trace_alloc_tgid_map(void) return 0; tgid_map_max = init_pid_ns.pid_max; - map = kvcalloc(tgid_map_max + 1, sizeof(*tgid_map), - GFP_KERNEL); + map = kvzalloc_objs(*tgid_map, tgid_map_max + 1); if (!map) return -ENOMEM; diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c index d88c44f1dfa5..929c84075315 100644 --- a/kernel/trace/trace_selftest.c +++ b/kernel/trace/trace_selftest.c @@ -248,7 +248,7 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt) goto out; /* Add a dynamic probe */ - dyn_ops = kzalloc(sizeof(*dyn_ops), GFP_KERNEL); + dyn_ops = kzalloc_obj(*dyn_ops); if (!dyn_ops) { printk("MEMORY ERROR "); goto out; @@ -1225,7 +1225,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr) /* check both trace buffers */ ret = trace_test_buffer(&tr->array_buffer, NULL); if (!ret) - ret = trace_test_buffer(&tr->max_buffer, &count); + ret = trace_test_buffer(&tr->snapshot_buffer, &count); trace->reset(tr); tracing_start(); @@ -1287,7 +1287,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr) /* check both trace buffers */ ret = trace_test_buffer(&tr->array_buffer, NULL); if (!ret) - ret = trace_test_buffer(&tr->max_buffer, &count); + ret = trace_test_buffer(&tr->snapshot_buffer, &count); trace->reset(tr); tracing_start(); @@ -1355,7 +1355,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * if (ret) goto out; - ret = trace_test_buffer(&tr->max_buffer, &count); + ret = trace_test_buffer(&tr->snapshot_buffer, &count); if (ret) goto out; @@ -1385,7 +1385,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * if (ret) goto out; - ret = trace_test_buffer(&tr->max_buffer, &count); + ret = trace_test_buffer(&tr->snapshot_buffer, &count); if (!ret && !count) { printk(KERN_CONT ".. no entries found .."); @@ -1513,7 +1513,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr) /* check both trace buffers */ ret = trace_test_buffer(&tr->array_buffer, NULL); if (!ret) - ret = trace_test_buffer(&tr->max_buffer, &count); + ret = trace_test_buffer(&tr->snapshot_buffer, &count); trace->reset(tr); diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 32684ef4fb9d..85f6f10d107f 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -106,7 +106,7 @@ EXPORT_SYMBOL_GPL(trace_seq_printf); * Writes a ASCII representation of a bitmask string into @s. */ void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, - int nmaskbits) + int nmaskbits) { unsigned int save_len = s->seq.len; @@ -124,6 +124,33 @@ void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, } EXPORT_SYMBOL_GPL(trace_seq_bitmask); +/** + * trace_seq_bitmask_list - write a bitmask array in its list representation + * @s: trace sequence descriptor + * @maskp: points to an array of unsigned longs that represent a bitmask + * @nmaskbits: The number of bits that are valid in @maskp + * + * Writes a list representation (e.g., 0-3,5-7) of a bitmask string into @s. + */ +void trace_seq_bitmask_list(struct trace_seq *s, const unsigned long *maskp, + int nmaskbits) +{ + unsigned int save_len = s->seq.len; + + if (s->full) + return; + + __trace_seq_init(s); + + seq_buf_printf(&s->seq, "%*pbl", nmaskbits, maskp); + + if (unlikely(seq_buf_has_overflowed(&s->seq))) { + s->seq.len = save_len; + s->full = 1; + } +} +EXPORT_SYMBOL_GPL(trace_seq_bitmask_list); + /** * trace_seq_vprintf - sequence printing of trace information * @s: trace sequence descriptor diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index b3b5586f104d..856ece13b7dc 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c @@ -77,7 +77,7 @@ static int insert_stat(struct rb_root *root, void *stat, cmp_func_t cmp) struct rb_node **new = &(root->rb_node), *parent = NULL; struct stat_node *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; data->stat = stat; @@ -322,7 +322,7 @@ int register_stat_tracer(struct tracer_stat *trace) } /* Init the session */ - session = kzalloc(sizeof(*session), GFP_KERNEL); + session = kzalloc_obj(*session); if (!session) return -ENOMEM; diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index e96d0063cbcf..37317b81fcda 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -617,7 +617,7 @@ static int syscall_fault_buffer_enable(void) return 0; } - sbuf = kmalloc(sizeof(*sbuf), GFP_KERNEL); + sbuf = kmalloc_obj(*sbuf); if (!sbuf) return -ENOMEM; @@ -1337,9 +1337,8 @@ void __init init_ftrace_syscalls(void) void *ret; if (!IS_ENABLED(CONFIG_HAVE_SPARSE_SYSCALL_NR)) { - syscalls_metadata = kcalloc(NR_syscalls, - sizeof(*syscalls_metadata), - GFP_KERNEL); + syscalls_metadata = kzalloc_objs(*syscalls_metadata, + NR_syscalls); if (!syscalls_metadata) { WARN_ON(1); return; diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 1b4f32e2b9bd..2cabf8a23ec5 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -338,7 +338,7 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret) struct trace_uprobe *tu; int ret; - tu = kzalloc(struct_size(tu, tp.args, nargs), GFP_KERNEL); + tu = kzalloc_flex(*tu, tp.args, nargs); if (!tu) return ERR_PTR(-ENOMEM); @@ -699,7 +699,7 @@ static int __trace_uprobe_create(int argc, const char **argv) memset(&path, 0, sizeof(path)); tu->filename = no_free_ptr(filename); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; ctx->flags = (is_return ? TPARG_FL_RETURN : 0) | TPARG_FL_USER; diff --git a/kernel/trace/tracing_map.c b/kernel/trace/tracing_map.c index 7f8da4dab69d..bf1a507695b6 100644 --- a/kernel/trace/tracing_map.c +++ b/kernel/trace/tracing_map.c @@ -324,7 +324,7 @@ static struct tracing_map_array *tracing_map_array_alloc(unsigned int n_elts, struct tracing_map_array *a; unsigned int i; - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) return NULL; @@ -405,7 +405,7 @@ static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map) struct tracing_map_elt *elt; int err = 0; - elt = kzalloc(sizeof(*elt), GFP_KERNEL); + elt = kzalloc_obj(*elt); if (!elt) return ERR_PTR(-ENOMEM); @@ -417,19 +417,19 @@ static struct tracing_map_elt *tracing_map_elt_alloc(struct tracing_map *map) goto free; } - elt->fields = kcalloc(map->n_fields, sizeof(*elt->fields), GFP_KERNEL); + elt->fields = kzalloc_objs(*elt->fields, map->n_fields); if (!elt->fields) { err = -ENOMEM; goto free; } - elt->vars = kcalloc(map->n_vars, sizeof(*elt->vars), GFP_KERNEL); + elt->vars = kzalloc_objs(*elt->vars, map->n_vars); if (!elt->vars) { err = -ENOMEM; goto free; } - elt->var_set = kcalloc(map->n_vars, sizeof(*elt->var_set), GFP_KERNEL); + elt->var_set = kzalloc_objs(*elt->var_set, map->n_vars); if (!elt->var_set) { err = -ENOMEM; goto free; @@ -777,7 +777,7 @@ struct tracing_map *tracing_map_create(unsigned int map_bits, map_bits > TRACING_MAP_BITS_MAX) return ERR_PTR(-EINVAL); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return ERR_PTR(-ENOMEM); @@ -949,7 +949,7 @@ create_sort_entry(void *key, struct tracing_map_elt *elt) { struct tracing_map_sort_entry *sort_entry; - sort_entry = kzalloc(sizeof(*sort_entry), GFP_KERNEL); + sort_entry = kzalloc_obj(*sort_entry); if (!sort_entry) return NULL; diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 62719d2941c9..91905aa19294 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -34,9 +34,13 @@ enum tp_transition_sync { struct tp_transition_snapshot { unsigned long rcu; + unsigned long srcu_gp; bool ongoing; }; +DEFINE_SRCU_FAST(tracepoint_srcu); +EXPORT_SYMBOL_GPL(tracepoint_srcu); + /* Protected by tracepoints_mutex */ static struct tp_transition_snapshot tp_transition_snapshot[_NR_TP_TRANSITION_SYNC]; @@ -46,6 +50,7 @@ static void tp_rcu_get_state(enum tp_transition_sync sync) /* Keep the latest get_state snapshot. */ snapshot->rcu = get_state_synchronize_rcu(); + snapshot->srcu_gp = start_poll_synchronize_srcu(&tracepoint_srcu); snapshot->ongoing = true; } @@ -56,6 +61,8 @@ static void tp_rcu_cond_sync(enum tp_transition_sync sync) if (!snapshot->ongoing) return; cond_synchronize_rcu(snapshot->rcu); + if (!poll_state_synchronize_srcu(&tracepoint_srcu, snapshot->srcu_gp)) + synchronize_srcu(&tracepoint_srcu); snapshot->ongoing = false; } @@ -96,8 +103,7 @@ static void tp_stub_func(void) static inline void *allocate_probes(int count) { - struct tp_probes *p = kmalloc(struct_size(p, probes, count), - GFP_KERNEL); + struct tp_probes *p = kmalloc_flex(*p, probes, count); return p == NULL ? NULL : p->probes; } @@ -112,10 +118,13 @@ static inline void release_probes(struct tracepoint *tp, struct tracepoint_func struct tp_probes *tp_probes = container_of(old, struct tp_probes, probes[0]); - if (tracepoint_is_faultable(tp)) - call_rcu_tasks_trace(&tp_probes->rcu, rcu_free_old_probes); - else - call_rcu(&tp_probes->rcu, rcu_free_old_probes); + if (tracepoint_is_faultable(tp)) { + call_rcu_tasks_trace(&tp_probes->rcu, + rcu_free_old_probes); + } else { + call_srcu(&tracepoint_srcu, &tp_probes->rcu, + rcu_free_old_probes); + } } } @@ -605,7 +614,7 @@ static int tracepoint_module_coming(struct module *mod) if (trace_module_has_bad_taint(mod)) return 0; - tp_mod = kmalloc(sizeof(struct tp_module), GFP_KERNEL); + tp_mod = kmalloc_obj(struct tp_module); if (!tp_mod) return -ENOMEM; tp_mod->mod = mod; diff --git a/kernel/ucount.c b/kernel/ucount.c index fc4a8f2d3096..d6dc3e859f12 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -163,7 +163,7 @@ struct ucounts *alloc_ucounts(struct user_namespace *ns, kuid_t uid) if (ucounts) return ucounts; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; diff --git a/kernel/umh.c b/kernel/umh.c index b4da45a3a7cf..cffda97d961c 100644 --- a/kernel/umh.c +++ b/kernel/umh.c @@ -359,7 +359,7 @@ struct subprocess_info *call_usermodehelper_setup(const char *path, char **argv, void *data) { struct subprocess_info *sub_info; - sub_info = kzalloc(sizeof(struct subprocess_info), gfp_mask); + sub_info = kzalloc_obj(struct subprocess_info, gfp_mask); if (!sub_info) goto out; diff --git a/kernel/unwind/deferred.c b/kernel/unwind/deferred.c index a88fb481c4a3..5bea47314254 100644 --- a/kernel/unwind/deferred.c +++ b/kernel/unwind/deferred.c @@ -120,8 +120,7 @@ int unwind_user_faultable(struct unwind_stacktrace *trace) return -EINVAL; if (!info->cache) { - info->cache = kzalloc(struct_size(cache, entries, UNWIND_MAX_ENTRIES), - GFP_KERNEL); + info->cache = kzalloc_flex(*cache, entries, UNWIND_MAX_ENTRIES); if (!info->cache) return -ENOMEM; } diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 03cb63883d04..0bed462e9b2a 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -794,9 +794,8 @@ static int insert_extent(struct uid_gid_map *map, struct uid_gid_extent *extent) struct uid_gid_extent *forward; /* Allocate memory for 340 mappings. */ - forward = kmalloc_array(UID_GID_MAP_MAX_EXTENTS, - sizeof(struct uid_gid_extent), - GFP_KERNEL); + forward = kmalloc_objs(struct uid_gid_extent, + UID_GID_MAP_MAX_EXTENTS); if (!forward) return -ENOMEM; diff --git a/kernel/vhost_task.c b/kernel/vhost_task.c index 27107dcc1cbf..3f1ed7ef0582 100644 --- a/kernel/vhost_task.c +++ b/kernel/vhost_task.c @@ -132,7 +132,7 @@ struct vhost_task *vhost_task_create(bool (*fn)(void *), struct vhost_task *vtsk; struct task_struct *tsk; - vtsk = kzalloc(sizeof(*vtsk), GFP_KERNEL); + vtsk = kzalloc_obj(*vtsk); if (!vtsk) return ERR_PTR(-ENOMEM); init_completion(&vtsk->exited); diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c index 52f89f1137da..538520861e8b 100644 --- a/kernel/watch_queue.c +++ b/kernel/watch_queue.c @@ -278,7 +278,7 @@ long watch_queue_set_size(struct pipe_inode_info *pipe, unsigned int nr_notes) pipe->nr_accounted = nr_pages; ret = -ENOMEM; - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, nr_pages); if (!pages) goto error; @@ -358,7 +358,7 @@ long watch_queue_set_filter(struct pipe_inode_info *pipe, * user-specified filters. */ ret = -ENOMEM; - wfilter = kzalloc(struct_size(wfilter, filters, nr_filter), GFP_KERNEL); + wfilter = kzalloc_flex(*wfilter, filters, nr_filter); if (!wfilter) goto err_filter; wfilter->nr_filters = nr_filter; @@ -692,7 +692,7 @@ int watch_queue_init(struct pipe_inode_info *pipe) { struct watch_queue *wqueue; - wqueue = kzalloc(sizeof(*wqueue), GFP_KERNEL); + wqueue = kzalloc_obj(*wqueue); if (!wqueue) return -ENOMEM; diff --git a/kernel/workqueue.c b/kernel/workqueue.c index c515cff01828..b77119d71641 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -190,7 +190,7 @@ struct worker_pool { int id; /* I: pool ID */ unsigned int flags; /* L: flags */ - unsigned long watchdog_ts; /* L: watchdog timestamp */ + unsigned long last_progress_ts; /* L: last forward progress timestamp */ bool cpu_stall; /* WD: stalled cpu bound pool */ /* @@ -1697,7 +1697,7 @@ static void __pwq_activate_work(struct pool_workqueue *pwq, WARN_ON_ONCE(!(*wdb & WORK_STRUCT_INACTIVE)); trace_workqueue_activate_work(work); if (list_empty(&pwq->pool->worklist)) - pwq->pool->watchdog_ts = jiffies; + pwq->pool->last_progress_ts = jiffies; move_linked_works(work, &pwq->pool->worklist, NULL); __clear_bit(WORK_STRUCT_INACTIVE_BIT, wdb); } @@ -2348,7 +2348,7 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, */ if (list_empty(&pwq->inactive_works) && pwq_tryinc_nr_active(pwq, false)) { if (list_empty(&pool->worklist)) - pool->watchdog_ts = jiffies; + pool->last_progress_ts = jiffies; trace_workqueue_activate_work(work); insert_work(pwq, work, &pool->worklist, work_flags); @@ -3204,6 +3204,7 @@ __acquires(&pool->lock) worker->current_pwq = pwq; if (worker->task) worker->current_at = worker->task->se.sum_exec_runtime; + worker->current_start = jiffies; work_data = *work_data_bits(work); worker->current_color = get_work_color(work_data); @@ -3352,7 +3353,7 @@ static void process_scheduled_works(struct worker *worker) while ((work = list_first_entry_or_null(&worker->scheduled, struct work_struct, entry))) { if (first) { - worker->pool->watchdog_ts = jiffies; + worker->pool->last_progress_ts = jiffies; first = false; } process_one_work(worker, work); @@ -4714,7 +4715,7 @@ struct workqueue_attrs *alloc_workqueue_attrs_noprof(void) { struct workqueue_attrs *attrs; - attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); + attrs = kzalloc_obj(*attrs); if (!attrs) goto fail; if (!alloc_cpumask_var(&attrs->cpumask, GFP_KERNEL)) @@ -4850,7 +4851,7 @@ static int init_worker_pool(struct worker_pool *pool) pool->cpu = -1; pool->node = NUMA_NO_NODE; pool->flags |= POOL_DISASSOCIATED; - pool->watchdog_ts = jiffies; + pool->last_progress_ts = jiffies; INIT_LIST_HEAD(&pool->worklist); INIT_LIST_HEAD(&pool->idle_list); hash_init(pool->busy_hash); @@ -5370,7 +5371,7 @@ apply_wqattrs_prepare(struct workqueue_struct *wq, attrs->affn_scope >= WQ_AFFN_NR_TYPES)) return ERR_PTR(-EINVAL); - ctx = kzalloc(struct_size(ctx, pwq_tbl, nr_cpu_ids), GFP_KERNEL); + ctx = kzalloc_flex(*ctx, pwq_tbl, nr_cpu_ids); new_attrs = alloc_workqueue_attrs(); if (!ctx || !new_attrs) @@ -6274,7 +6275,7 @@ static void pr_cont_worker_id(struct worker *worker) { struct worker_pool *pool = worker->pool; - if (pool->flags & WQ_BH) + if (pool->flags & POOL_BH) pr_cont("bh%s", pool->attrs->nice == HIGHPRI_NICE_LEVEL ? "-hi" : ""); else @@ -6359,6 +6360,8 @@ static void show_pwq(struct pool_workqueue *pwq) pr_cont(" %s", comma ? "," : ""); pr_cont_worker_id(worker); pr_cont(":%ps", worker->current_func); + pr_cont(" for %us", + jiffies_to_msecs(jiffies - worker->current_start) / 1000); list_for_each_entry(work, &worker->scheduled, entry) pr_cont_work(false, work, &pcws); pr_cont_work_flush(comma, (work_func_t)-1L, &pcws); @@ -6462,7 +6465,7 @@ static void show_one_worker_pool(struct worker_pool *pool) /* How long the first pending work is waiting for a worker. */ if (!list_empty(&pool->worklist)) - hung = jiffies_to_msecs(jiffies - pool->watchdog_ts) / 1000; + hung = jiffies_to_msecs(jiffies - pool->last_progress_ts) / 1000; /* * Defer printing to avoid deadlocks in console drivers that @@ -7486,7 +7489,7 @@ int workqueue_sysfs_register(struct workqueue_struct *wq) if (WARN_ON(wq->flags & __WQ_ORDERED)) return -EINVAL; - wq->wq_dev = wq_dev = kzalloc(sizeof(*wq_dev), GFP_KERNEL); + wq->wq_dev = wq_dev = kzalloc_obj(*wq_dev); if (!wq_dev) return -ENOMEM; @@ -7580,11 +7583,11 @@ MODULE_PARM_DESC(panic_on_stall_time, "Panic if stall exceeds this many seconds /* * Show workers that might prevent the processing of pending work items. - * The only candidates are CPU-bound workers in the running state. - * Pending work items should be handled by another idle worker - * in all other situations. + * A busy worker that is not running on the CPU (e.g. sleeping in + * wait_event_idle() with PF_WQ_WORKER cleared) can stall the pool just as + * effectively as a CPU-bound one, so dump every in-flight worker. */ -static void show_cpu_pool_hog(struct worker_pool *pool) +static void show_cpu_pool_busy_workers(struct worker_pool *pool) { struct worker *worker; unsigned long irq_flags; @@ -7593,36 +7596,34 @@ static void show_cpu_pool_hog(struct worker_pool *pool) raw_spin_lock_irqsave(&pool->lock, irq_flags); hash_for_each(pool->busy_hash, bkt, worker, hentry) { - if (task_is_running(worker->task)) { - /* - * Defer printing to avoid deadlocks in console - * drivers that queue work while holding locks - * also taken in their write paths. - */ - printk_deferred_enter(); + /* + * Defer printing to avoid deadlocks in console + * drivers that queue work while holding locks + * also taken in their write paths. + */ + printk_deferred_enter(); - pr_info("pool %d:\n", pool->id); - sched_show_task(worker->task); + pr_info("pool %d:\n", pool->id); + sched_show_task(worker->task); - printk_deferred_exit(); - } + printk_deferred_exit(); } raw_spin_unlock_irqrestore(&pool->lock, irq_flags); } -static void show_cpu_pools_hogs(void) +static void show_cpu_pools_busy_workers(void) { struct worker_pool *pool; int pi; - pr_info("Showing backtraces of running workers in stalled CPU-bound worker pools:\n"); + pr_info("Showing backtraces of busy workers in stalled worker pools:\n"); rcu_read_lock(); for_each_pool(pool, pi) { if (pool->cpu_stall) - show_cpu_pool_hog(pool); + show_cpu_pool_busy_workers(pool); } @@ -7691,7 +7692,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) touched = READ_ONCE(per_cpu(wq_watchdog_touched_cpu, pool->cpu)); else touched = READ_ONCE(wq_watchdog_touched); - pool_ts = READ_ONCE(pool->watchdog_ts); + pool_ts = READ_ONCE(pool->last_progress_ts); if (time_after(pool_ts, touched)) ts = pool_ts; @@ -7719,7 +7720,7 @@ static void wq_watchdog_timer_fn(struct timer_list *unused) show_all_workqueues(); if (cpu_pool_stall) - show_cpu_pools_hogs(); + show_cpu_pools_busy_workers(); if (lockup_detected) panic_on_wq_watchdog(max_stall_time); @@ -7879,9 +7880,9 @@ void __init workqueue_init_early(void) wq_power_efficient = true; /* initialize WQ_AFFN_SYSTEM pods */ - pt->pod_cpus = kcalloc(1, sizeof(pt->pod_cpus[0]), GFP_KERNEL); - pt->pod_node = kcalloc(1, sizeof(pt->pod_node[0]), GFP_KERNEL); - pt->cpu_pod = kcalloc(nr_cpu_ids, sizeof(pt->cpu_pod[0]), GFP_KERNEL); + pt->pod_cpus = kzalloc_objs(pt->pod_cpus[0], 1); + pt->pod_node = kzalloc_objs(pt->pod_node[0], 1); + pt->cpu_pod = kzalloc_objs(pt->cpu_pod[0], nr_cpu_ids); BUG_ON(!pt->pod_cpus || !pt->pod_node || !pt->cpu_pod); BUG_ON(!zalloc_cpumask_var_node(&pt->pod_cpus[0], GFP_KERNEL, NUMA_NO_NODE)); @@ -8063,7 +8064,7 @@ static void __init init_pod_type(struct wq_pod_type *pt, pt->nr_pods = 0; /* init @pt->cpu_pod[] according to @cpus_share_pod() */ - pt->cpu_pod = kcalloc(nr_cpu_ids, sizeof(pt->cpu_pod[0]), GFP_KERNEL); + pt->cpu_pod = kzalloc_objs(pt->cpu_pod[0], nr_cpu_ids); BUG_ON(!pt->cpu_pod); for_each_possible_cpu(cur) { @@ -8080,8 +8081,8 @@ static void __init init_pod_type(struct wq_pod_type *pt, } /* init the rest to match @pt->cpu_pod[] */ - pt->pod_cpus = kcalloc(pt->nr_pods, sizeof(pt->pod_cpus[0]), GFP_KERNEL); - pt->pod_node = kcalloc(pt->nr_pods, sizeof(pt->pod_node[0]), GFP_KERNEL); + pt->pod_cpus = kzalloc_objs(pt->pod_cpus[0], pt->nr_pods); + pt->pod_node = kzalloc_objs(pt->pod_node[0], pt->nr_pods); BUG_ON(!pt->pod_cpus || !pt->pod_node); for (pod = 0; pod < pt->nr_pods; pod++) diff --git a/kernel/workqueue_internal.h b/kernel/workqueue_internal.h index f6275944ada7..8def1ddc5a1b 100644 --- a/kernel/workqueue_internal.h +++ b/kernel/workqueue_internal.h @@ -32,6 +32,7 @@ struct worker { work_func_t current_func; /* K: function */ struct pool_workqueue *current_pwq; /* K: pwq */ u64 current_at; /* K: runtime at start or last wakeup */ + unsigned long current_start; /* K: start time of current work item */ unsigned int current_color; /* K: color */ int sleeping; /* S: is worker sleeping? */ diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 4e2dfbbd3d78..93f356d2b3d9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug @@ -630,7 +630,7 @@ config DEBUG_FORCE_WEAK_PER_CPU config WARN_CONTEXT_ANALYSIS bool "Compiler context-analysis warnings" - depends on CC_IS_CLANG && CLANG_VERSION >= 220000 + depends on CC_IS_CLANG && CLANG_VERSION >= 220100 # Branch profiling re-defines "if", which messes with the compiler's # ability to analyze __cond_acquires(..), resulting in false positives. depends on !TRACE_BRANCH_PROFILING @@ -641,7 +641,7 @@ config WARN_CONTEXT_ANALYSIS and releasing user-definable "context locks". Clang's name of the feature is "Thread Safety Analysis". Requires - Clang 22 or later. + Clang 22.1.0 or later. Produces warnings by default. Select CONFIG_WERROR if you wish to turn these warnings into errors. @@ -760,6 +760,7 @@ source "mm/Kconfig.debug" config DEBUG_OBJECTS bool "Debug object operations" + depends on PREEMPT_COUNT || !DEFERRED_STRUCT_PAGE_INIT depends on DEBUG_KERNEL help If you say Y here, additional code will be inserted into the @@ -1766,33 +1767,6 @@ config STACKTRACE It is also used by various kernel debugging features that require stack trace generation. -config WARN_ALL_UNSEEDED_RANDOM - bool "Warn for all uses of unseeded randomness" - default n - help - Some parts of the kernel contain bugs relating to their use of - cryptographically secure random numbers before it's actually possible - to generate those numbers securely. This setting ensures that these - flaws don't go unnoticed, by enabling a message, should this ever - occur. This will allow people with obscure setups to know when things - are going wrong, so that they might contact developers about fixing - it. - - Unfortunately, on some models of some architectures getting - a fully seeded CRNG is extremely difficult, and so this can - result in dmesg getting spammed for a surprisingly long - time. This is really bad from a security perspective, and - so architecture maintainers really need to do what they can - to get the CRNG seeded sooner after the system is booted. - However, since users cannot do anything actionable to - address this, by default this option is disabled. - - Say Y here if you want to receive warnings for all uses of - unseeded randomness. This will be of use primarily for - those developers interested in improving the security of - Linux kernels running on their architecture (or - subarchitecture). - config DEBUG_KOBJECT bool "kobject debugging" depends on DEBUG_KERNEL diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c index 00ae4673a271..58991ab09d84 100644 --- a/lib/alloc_tag.c +++ b/lib/alloc_tag.c @@ -669,8 +669,9 @@ static int __init alloc_mod_tags_mem(void) return -ENOMEM; } - vm_module_tags->pages = kmalloc_array(get_vm_area_size(vm_module_tags) >> PAGE_SHIFT, - sizeof(struct page *), GFP_KERNEL | __GFP_ZERO); + vm_module_tags->pages = kmalloc_objs(struct page *, + get_vm_area_size(vm_module_tags) >> PAGE_SHIFT, + GFP_KERNEL | __GFP_ZERO); if (!vm_module_tags->pages) { free_vm_area(vm_module_tags); return -ENOMEM; diff --git a/lib/assoc_array.c b/lib/assoc_array.c index 388e656ac974..bcc6e0a013eb 100644 --- a/lib/assoc_array.c +++ b/lib/assoc_array.c @@ -454,7 +454,7 @@ static bool assoc_array_insert_in_empty_tree(struct assoc_array_edit *edit) pr_devel("-->%s()\n", __func__); - new_n0 = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n0 = kzalloc_obj(struct assoc_array_node); if (!new_n0) return false; @@ -536,11 +536,11 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, * those now. We may also need a new shortcut, but we deal with that * when we need it. */ - new_n0 = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n0 = kzalloc_obj(struct assoc_array_node); if (!new_n0) return false; edit->new_meta[0] = assoc_array_node_to_ptr(new_n0); - new_n1 = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n1 = kzalloc_obj(struct assoc_array_node); if (!new_n1) return false; edit->new_meta[1] = assoc_array_node_to_ptr(new_n1); @@ -741,7 +741,7 @@ static bool assoc_array_insert_into_terminal_node(struct assoc_array_edit *edit, keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; - new_s0 = kzalloc(struct_size(new_s0, index_key, keylen), GFP_KERNEL); + new_s0 = kzalloc_flex(*new_s0, index_key, keylen); if (!new_s0) return false; edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s0); @@ -832,7 +832,7 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit, edit->excised_meta[0] = assoc_array_shortcut_to_ptr(shortcut); /* Create a new node now since we're going to need it anyway */ - new_n0 = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n0 = kzalloc_obj(struct assoc_array_node); if (!new_n0) return false; edit->new_meta[0] = assoc_array_node_to_ptr(new_n0); @@ -848,8 +848,7 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit, keylen = round_up(diff, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; - new_s0 = kzalloc(struct_size(new_s0, index_key, keylen), - GFP_KERNEL); + new_s0 = kzalloc_flex(*new_s0, index_key, keylen); if (!new_s0) return false; edit->new_meta[1] = assoc_array_shortcut_to_ptr(new_s0); @@ -898,8 +897,7 @@ static bool assoc_array_insert_mid_shortcut(struct assoc_array_edit *edit, keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; - new_s1 = kzalloc(struct_size(new_s1, index_key, keylen), - GFP_KERNEL); + new_s1 = kzalloc_flex(*new_s1, index_key, keylen); if (!new_s1) return false; edit->new_meta[2] = assoc_array_shortcut_to_ptr(new_s1); @@ -977,7 +975,7 @@ struct assoc_array_edit *assoc_array_insert(struct assoc_array *array, */ BUG_ON(assoc_array_ptr_is_meta(object)); - edit = kzalloc(sizeof(struct assoc_array_edit), GFP_KERNEL); + edit = kzalloc_obj(struct assoc_array_edit); if (!edit) return ERR_PTR(-ENOMEM); edit->array = array; @@ -1089,7 +1087,7 @@ struct assoc_array_edit *assoc_array_delete(struct assoc_array *array, pr_devel("-->%s()\n", __func__); - edit = kzalloc(sizeof(struct assoc_array_edit), GFP_KERNEL); + edit = kzalloc_obj(struct assoc_array_edit); if (!edit) return ERR_PTR(-ENOMEM); edit->array = array; @@ -1206,7 +1204,7 @@ struct assoc_array_edit *assoc_array_delete(struct assoc_array *array, node = parent; /* Create a new node to collapse into */ - new_n0 = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n0 = kzalloc_obj(struct assoc_array_node); if (!new_n0) goto enomem; edit->new_meta[0] = assoc_array_node_to_ptr(new_n0); @@ -1281,7 +1279,7 @@ struct assoc_array_edit *assoc_array_clear(struct assoc_array *array, if (!array->root) return NULL; - edit = kzalloc(sizeof(struct assoc_array_edit), GFP_KERNEL); + edit = kzalloc_obj(struct assoc_array_edit); if (!edit) return ERR_PTR(-ENOMEM); edit->array = array; @@ -1469,7 +1467,7 @@ int assoc_array_gc(struct assoc_array *array, if (!array->root) return 0; - edit = kzalloc(sizeof(struct assoc_array_edit), GFP_KERNEL); + edit = kzalloc_obj(struct assoc_array_edit); if (!edit) return -ENOMEM; edit->array = array; @@ -1490,8 +1488,7 @@ int assoc_array_gc(struct assoc_array *array, shortcut = assoc_array_ptr_to_shortcut(cursor); keylen = round_up(shortcut->skip_to_level, ASSOC_ARRAY_KEY_CHUNK_SIZE); keylen >>= ASSOC_ARRAY_KEY_CHUNK_SHIFT; - new_s = kmalloc(struct_size(new_s, index_key, keylen), - GFP_KERNEL); + new_s = kmalloc_flex(*new_s, index_key, keylen); if (!new_s) goto enomem; pr_devel("dup shortcut %p -> %p\n", shortcut, new_s); @@ -1505,7 +1502,7 @@ int assoc_array_gc(struct assoc_array *array, /* Duplicate the node at this position */ node = assoc_array_ptr_to_node(cursor); - new_n = kzalloc(sizeof(struct assoc_array_node), GFP_KERNEL); + new_n = kzalloc_obj(struct assoc_array_node); if (!new_n) goto enomem; pr_devel("dup node %p -> %p\n", node, new_n); diff --git a/lib/bch.c b/lib/bch.c index 1c0cb07cdfeb..9561c0828802 100644 --- a/lib/bch.c +++ b/lib/bch.c @@ -1320,7 +1320,7 @@ struct bch_control *bch_init(int m, int t, unsigned int prim_poly, if (prim_poly == 0) prim_poly = prim_poly_tab[m-min_m]; - bch = kzalloc(sizeof(*bch), GFP_KERNEL); + bch = kzalloc_obj(*bch); if (bch == NULL) goto fail; diff --git a/lib/bootconfig.c b/lib/bootconfig.c index 81f29c29f47b..2da049216fe0 100644 --- a/lib/bootconfig.c +++ b/lib/bootconfig.c @@ -316,7 +316,7 @@ int __init xbc_node_compose_key_after(struct xbc_node *root, depth ? "." : ""); if (ret < 0) return ret; - if (ret > size) { + if (ret >= size) { size = 0; } else { size -= ret; @@ -532,9 +532,9 @@ static char *skip_spaces_until_newline(char *p) static int __init __xbc_open_brace(char *p) { /* Push the last key as open brace */ - open_brace[brace_index++] = xbc_node_index(last_parent); if (brace_index >= XBC_DEPTH_MAX) return xbc_parse_error("Exceed max depth of braces", p); + open_brace[brace_index++] = xbc_node_index(last_parent); return 0; } @@ -557,17 +557,13 @@ static int __init __xbc_close_brace(char *p) /* * Return delimiter or error, no node added. As same as lib/cmdline.c, * you can use " around spaces, but can't escape " for value. + * *@__v must point real value string. (not including spaces before value.) */ static int __init __xbc_parse_value(char **__v, char **__n) { char *p, *v = *__v; int c, quotes = 0; - v = skip_spaces(v); - while (*v == '#') { - v = skip_comment(v); - v = skip_spaces(v); - } if (*v == '"' || *v == '\'') { quotes = *v; v++; @@ -617,6 +613,13 @@ static int __init xbc_parse_array(char **__v) last_parent = xbc_node_get_child(last_parent); do { + /* Search the next array value beyond comments and empty lines */ + next = skip_spaces(*__v); + while (*next == '#') { + next = skip_comment(next); + next = skip_spaces(next); + } + *__v = next; c = __xbc_parse_value(__v, &next); if (c < 0) return c; @@ -701,9 +704,17 @@ static int __init xbc_parse_kv(char **k, char *v, int op) if (ret) return ret; - c = __xbc_parse_value(&v, &next); - if (c < 0) - return c; + v = skip_spaces_until_newline(v); + /* If there is a comment, this has an empty value. */ + if (*v == '#') { + next = skip_comment(v); + *v = '\0'; + c = '\n'; + } else { + c = __xbc_parse_value(&v, &next); + if (c < 0) + return c; + } child = xbc_node_get_child(last_parent); if (child && xbc_node_is_value(child)) { @@ -791,7 +802,7 @@ static int __init xbc_verify_tree(void) /* Brace closing */ if (brace_index) { - n = &xbc_nodes[open_brace[brace_index]]; + n = &xbc_nodes[open_brace[brace_index - 1]]; return xbc_parse_error("Brace is not closed", xbc_node_get_data(n)); } diff --git a/lib/bucket_locks.c b/lib/bucket_locks.c index 64b92e1dbace..d29516ca0554 100644 --- a/lib/bucket_locks.c +++ b/lib/bucket_locks.c @@ -31,7 +31,7 @@ int __alloc_bucket_spinlocks(spinlock_t **locks, unsigned int *locks_mask, } if (sizeof(spinlock_t) != 0) { - tlocks = kvmalloc_array(size, sizeof(spinlock_t), gfp); + tlocks = kvmalloc_objs(spinlock_t, size, gfp); if (!tlocks) return -ENOMEM; for (i = 0; i < size; i++) { diff --git a/lib/codetag.c b/lib/codetag.c index 545911cebd25..304667897ad4 100644 --- a/lib/codetag.c +++ b/lib/codetag.c @@ -193,7 +193,7 @@ static int codetag_module_init(struct codetag_type *cttype, struct module *mod) BUG_ON(range.start > range.stop); - cmod = kmalloc(sizeof(*cmod), GFP_KERNEL); + cmod = kmalloc_obj(*cmod); if (unlikely(!cmod)) return -ENOMEM; @@ -383,7 +383,7 @@ codetag_register_type(const struct codetag_type_desc *desc) BUG_ON(desc->tag_size <= 0); - cttype = kzalloc(sizeof(*cttype), GFP_KERNEL); + cttype = kzalloc_obj(*cttype); if (unlikely(!cttype)) return ERR_PTR(-ENOMEM); diff --git a/lib/cpu_rmap.c b/lib/cpu_rmap.c index f03d9be3f06b..c86ab6e55d17 100644 --- a/lib/cpu_rmap.c +++ b/lib/cpu_rmap.c @@ -309,7 +309,7 @@ EXPORT_SYMBOL(irq_cpu_rmap_remove); */ int irq_cpu_rmap_add(struct cpu_rmap *rmap, int irq) { - struct irq_glue *glue = kzalloc(sizeof(*glue), GFP_KERNEL); + struct irq_glue *glue = kzalloc_obj(*glue); int rc; if (!glue) diff --git a/lib/crypto/.kunitconfig b/lib/crypto/.kunitconfig new file mode 100644 index 000000000000..6b2ce28ae509 --- /dev/null +++ b/lib/crypto/.kunitconfig @@ -0,0 +1,34 @@ +CONFIG_KUNIT=y + +# These kconfig options select all the CONFIG_CRYPTO_LIB_* symbols that have a +# corresponding KUnit test. Those symbols cannot be directly enabled here, +# since they are hidden symbols. +CONFIG_CRYPTO=y +CONFIG_CRYPTO_ADIANTUM=y +CONFIG_CRYPTO_BLAKE2B=y +CONFIG_CRYPTO_CHACHA20POLY1305=y +CONFIG_CRYPTO_HCTR2=y +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MLDSA=y +CONFIG_CRYPTO_SHA1=y +CONFIG_CRYPTO_SHA256=y +CONFIG_CRYPTO_SHA512=y +CONFIG_CRYPTO_SHA3=y +CONFIG_INET=y +CONFIG_IPV6=y +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_WIREGUARD=y + +CONFIG_CRYPTO_LIB_BLAKE2B_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_BLAKE2S_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_MLDSA_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_NH_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_POLYVAL_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST=y +CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST=y diff --git a/lib/crypto/gf128mul.c b/lib/crypto/gf128mul.c index 2a34590fe3f1..e5a727b15f07 100644 --- a/lib/crypto/gf128mul.c +++ b/lib/crypto/gf128mul.c @@ -245,12 +245,12 @@ struct gf128mul_64k *gf128mul_init_64k_bbe(const be128 *g) struct gf128mul_64k *t; int i, j, k; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) goto out; for (i = 0; i < 16; i++) { - t->t[i] = kzalloc(sizeof(*t->t[i]), GFP_KERNEL); + t->t[i] = kzalloc_obj(*t->t[i]); if (!t->t[i]) { gf128mul_free_64k(t); t = NULL; @@ -326,7 +326,7 @@ struct gf128mul_4k *gf128mul_init_4k_lle(const be128 *g) struct gf128mul_4k *t; int j, k; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) goto out; diff --git a/lib/crypto/mpi/mpih-mul.c b/lib/crypto/mpi/mpih-mul.c index a93647564054..29dd80609c47 100644 --- a/lib/crypto/mpi/mpih-mul.c +++ b/lib/crypto/mpi/mpih-mul.c @@ -372,7 +372,7 @@ mpihelp_mul_karatsuba_case(mpi_ptr_t prodp, return -ENOMEM; } else { if (!ctx->next) { - ctx->next = kzalloc(sizeof *ctx, GFP_KERNEL); + ctx->next = kzalloc_obj(*ctx); if (!ctx->next) return -ENOMEM; } diff --git a/lib/crypto/mpi/mpiutil.c b/lib/crypto/mpi/mpiutil.c index 7f2db830f404..f4faf7c903f9 100644 --- a/lib/crypto/mpi/mpiutil.c +++ b/lib/crypto/mpi/mpiutil.c @@ -33,7 +33,7 @@ MPI mpi_alloc(unsigned nlimbs) { MPI a; - a = kmalloc(sizeof *a, GFP_KERNEL); + a = kmalloc_obj(*a); if (!a) return a; @@ -93,14 +93,14 @@ int mpi_resize(MPI a, unsigned nlimbs) return 0; /* no need to do it */ if (a->d) { - p = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); + p = kzalloc_objs(mpi_limb_t, nlimbs); if (!p) return -ENOMEM; memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t)); kfree_sensitive(a->d); a->d = p; } else { - a->d = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL); + a->d = kzalloc_objs(mpi_limb_t, nlimbs); if (!a->d) return -ENOMEM; } diff --git a/lib/crypto/powerpc/aes.h b/lib/crypto/powerpc/aes.h index 42e0a993c619..5a36b637e6b9 100644 --- a/lib/crypto/powerpc/aes.h +++ b/lib/crypto/powerpc/aes.h @@ -95,7 +95,8 @@ static inline bool is_vsx_format(const struct p8_aes_key *key) } /* - * Convert a round key from VSX to generic format by reflecting the 16 bytes, + * Convert a round key from VSX to generic format by reflecting all 16 bytes (if + * little endian) or reflecting the bytes in each 4-byte word (if big endian), * and (if apply_inv_mix=true) applying InvMixColumn to each column. * * It would be nice if the VSX and generic key formats would be compatible. But @@ -107,6 +108,7 @@ static inline bool is_vsx_format(const struct p8_aes_key *key) */ static void rndkey_from_vsx(u32 out[4], const u32 in[4], bool apply_inv_mix) { + const bool be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); u32 k0 = swab32(in[0]); u32 k1 = swab32(in[1]); u32 k2 = swab32(in[2]); @@ -118,10 +120,10 @@ static void rndkey_from_vsx(u32 out[4], const u32 in[4], bool apply_inv_mix) k2 = inv_mix_columns(k2); k3 = inv_mix_columns(k3); } - out[0] = k3; - out[1] = k2; - out[2] = k1; - out[3] = k0; + out[0] = be ? k0 : k3; + out[1] = be ? k1 : k2; + out[2] = be ? k2 : k1; + out[3] = be ? k3 : k0; } static void aes_preparekey_arch(union aes_enckey_arch *k, diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig index 4970463ea0aa..0de289b429a9 100644 --- a/lib/crypto/tests/Kconfig +++ b/lib/crypto/tests/Kconfig @@ -2,10 +2,9 @@ config CRYPTO_LIB_BLAKE2B_KUNIT_TEST tristate "KUnit tests for BLAKE2b" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_BLAKE2B default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_BLAKE2B help KUnit tests for the BLAKE2b cryptographic hash function. @@ -14,71 +13,64 @@ config CRYPTO_LIB_BLAKE2S_KUNIT_TEST depends on KUNIT default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - # No need to select CRYPTO_LIB_BLAKE2S here, as that option doesn't + # No need to depend on CRYPTO_LIB_BLAKE2S here, as that option doesn't # exist; the BLAKE2s code is always built-in for the /dev/random driver. help KUnit tests for the BLAKE2s cryptographic hash function. config CRYPTO_LIB_CURVE25519_KUNIT_TEST tristate "KUnit tests for Curve25519" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_CURVE25519 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_CURVE25519 help KUnit tests for the Curve25519 Diffie-Hellman function. config CRYPTO_LIB_MD5_KUNIT_TEST tristate "KUnit tests for MD5" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_MD5 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_MD5 help KUnit tests for the MD5 cryptographic hash function and its corresponding HMAC. config CRYPTO_LIB_MLDSA_KUNIT_TEST tristate "KUnit tests for ML-DSA" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_MLDSA default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_MLDSA help KUnit tests for the ML-DSA digital signature algorithm. config CRYPTO_LIB_NH_KUNIT_TEST tristate "KUnit tests for NH" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_NH default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS - select CRYPTO_LIB_NH help KUnit tests for the NH almost-universal hash function. config CRYPTO_LIB_POLY1305_KUNIT_TEST tristate "KUnit tests for Poly1305" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_POLY1305 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_POLY1305 help KUnit tests for the Poly1305 library functions. config CRYPTO_LIB_POLYVAL_KUNIT_TEST tristate "KUnit tests for POLYVAL" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_POLYVAL default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_POLYVAL help KUnit tests for the POLYVAL library functions. config CRYPTO_LIB_SHA1_KUNIT_TEST tristate "KUnit tests for SHA-1" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_SHA1 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_SHA1 help KUnit tests for the SHA-1 cryptographic hash function and its corresponding HMAC. @@ -87,10 +79,9 @@ config CRYPTO_LIB_SHA1_KUNIT_TEST # included, for consistency with the naming used elsewhere (e.g. CRYPTO_SHA256). config CRYPTO_LIB_SHA256_KUNIT_TEST tristate "KUnit tests for SHA-224 and SHA-256" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_SHA256 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_SHA256 help KUnit tests for the SHA-224 and SHA-256 cryptographic hash functions and their corresponding HMACs. @@ -99,20 +90,18 @@ config CRYPTO_LIB_SHA256_KUNIT_TEST # included, for consistency with the naming used elsewhere (e.g. CRYPTO_SHA512). config CRYPTO_LIB_SHA512_KUNIT_TEST tristate "KUnit tests for SHA-384 and SHA-512" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_SHA512 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_SHA512 help KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions and their corresponding HMACs. config CRYPTO_LIB_SHA3_KUNIT_TEST tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS - depends on KUNIT + depends on KUNIT && CRYPTO_LIB_SHA3 default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE - select CRYPTO_LIB_SHA3 help KUnit tests for the SHA3 cryptographic hash and XOF functions, including SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128 and diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 89a1d6745dc2..12f50de85b62 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c @@ -398,9 +398,26 @@ static void fill_pool(void) atomic_inc(&cpus_allocating); while (pool_should_refill(&pool_global)) { + gfp_t gfp = __GFP_HIGH | __GFP_NOWARN; HLIST_HEAD(head); - if (!kmem_alloc_batch(&head, obj_cache, __GFP_HIGH | __GFP_NOWARN)) + /* + * Allow reclaim only in preemptible context and during + * early boot. If not preemptible, the caller might hold + * locks causing a deadlock in the allocator. + * + * If the reclaim flag is not set during early boot then + * allocations, which happen before deferred page + * initialization has completed, will fail. + * + * In preemptible context the flag is harmless and not a + * performance issue as that's usually invoked from slow + * path initialization context. + */ + if (preemptible() || system_state < SYSTEM_SCHEDULING) + gfp |= __GFP_KSWAPD_RECLAIM; + + if (!kmem_alloc_batch(&head, obj_cache, gfp)) break; guard(raw_spinlock_irqsave)(&pool_lock); diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c index 32138bb8ef77..05d5cb490a44 100644 --- a/lib/decompress_unxz.c +++ b/lib/decompress_unxz.c @@ -157,11 +157,11 @@ * when XZ_DYNALLOC is used, but the pre-boot free() doesn't support it. * Workaround it here because the other decompressors don't need it. */ -#undef kmalloc +#undef kmalloc_obj #undef kfree #undef vmalloc #undef vfree -#define kmalloc(size, flags) malloc(size) +#define kmalloc_obj(type) malloc(sizeof(type)) #define kfree(ptr) free(ptr) #define vmalloc(size) malloc(size) #define vfree(ptr) do { if (ptr != NULL) free(ptr); } while (0) diff --git a/lib/dhry_1.c b/lib/dhry_1.c index ca6c87232c58..134cc1c746c2 100644 --- a/lib/dhry_1.c +++ b/lib/dhry_1.c @@ -139,11 +139,11 @@ int dhry(int n) /* Initializations */ - Next_Ptr_Glob = (Rec_Pointer)kzalloc(sizeof(Rec_Type), GFP_ATOMIC); + Next_Ptr_Glob = (Rec_Pointer) kzalloc_obj(Rec_Type, GFP_ATOMIC); if (!Next_Ptr_Glob) return -ENOMEM; - Ptr_Glob = (Rec_Pointer)kzalloc(sizeof(Rec_Type), GFP_ATOMIC); + Ptr_Glob = (Rec_Pointer) kzalloc_obj(Rec_Type, GFP_ATOMIC); if (!Ptr_Glob) { kfree(Next_Ptr_Glob); return -ENOMEM; diff --git a/lib/dim/net_dim.c b/lib/dim/net_dim.c index d6aa09a979b3..d8d4f6553559 100644 --- a/lib/dim/net_dim.c +++ b/lib/dim/net_dim.c @@ -105,7 +105,7 @@ int net_dim_init_irq_moder(struct net_device *dev, u8 profile_flags, struct dim_irq_moder *moder; int len; - dev->irq_moder = kzalloc(sizeof(*dev->irq_moder), GFP_KERNEL); + dev->irq_moder = kzalloc_obj(*dev->irq_moder); if (!dev->irq_moder) return -ENOMEM; diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 7d7892e57a01..18a71a9108d3 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c @@ -1241,7 +1241,7 @@ static int ddebug_add_module(struct _ddebug_info *di, const char *modname) return 0; } - dt = kzalloc(sizeof(*dt), GFP_KERNEL); + dt = kzalloc_obj(*dt); if (dt == NULL) { pr_err("error adding module: %s\n", modname); return -ENOMEM; diff --git a/lib/error-inject.c b/lib/error-inject.c index 887acd9a6ea6..f3d1b70be605 100644 --- a/lib/error-inject.c +++ b/lib/error-inject.c @@ -80,7 +80,7 @@ static void populate_error_injection_list(struct error_injection_entry *start, continue; } - ent = kmalloc(sizeof(*ent), GFP_KERNEL); + ent = kmalloc_obj(*ent); if (!ent) break; ent->start_addr = entry; diff --git a/lib/group_cpus.c b/lib/group_cpus.c index a93df70919df..e6e18d7a49bb 100644 --- a/lib/group_cpus.c +++ b/lib/group_cpus.c @@ -47,7 +47,7 @@ static cpumask_var_t *alloc_node_to_cpumask(void) cpumask_var_t *masks; int node; - masks = kcalloc(nr_node_ids, sizeof(cpumask_var_t), GFP_KERNEL); + masks = kzalloc_objs(cpumask_var_t, nr_node_ids); if (!masks) return NULL; @@ -320,10 +320,10 @@ static int alloc_cluster_groups(unsigned int ncpus, goto no_cluster; /* Allocate memory based on cluster number. */ - clusters = kcalloc(ncluster, sizeof(struct cpumask *), GFP_KERNEL); + clusters = kzalloc_objs(*clusters, ncluster); if (!clusters) goto no_cluster; - cluster_groups = kcalloc(ncluster, sizeof(struct node_groups), GFP_KERNEL); + cluster_groups = kzalloc_objs(struct node_groups, ncluster); if (!cluster_groups) goto fail_cluster_groups; @@ -432,9 +432,7 @@ static int __group_cpus_evenly(unsigned int startgrp, unsigned int numgrps, return numgrps; } - node_groups = kcalloc(nr_node_ids, - sizeof(struct node_groups), - GFP_KERNEL); + node_groups = kzalloc_objs(struct node_groups, nr_node_ids); if (!node_groups) return -ENOMEM; @@ -508,7 +506,7 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks) if (!node_to_cpumask) goto fail_npresmsk; - masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); + masks = kzalloc_objs(*masks, numgrps); if (!masks) goto fail_node_to_cpumask; @@ -574,7 +572,7 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps, unsigned int *nummasks) if (numgrps == 0) return NULL; - masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); + masks = kzalloc_objs(*masks, numgrps); if (!masks) return NULL; diff --git a/lib/idr.c b/lib/idr.c index 457430cff8c5..69bee5369670 100644 --- a/lib/idr.c +++ b/lib/idr.c @@ -417,7 +417,7 @@ int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, } bitmap = alloc; if (!bitmap) - bitmap = kzalloc(sizeof(*bitmap), GFP_NOWAIT); + bitmap = kzalloc_obj(*bitmap, GFP_NOWAIT); if (!bitmap) goto alloc; bitmap->bitmap[0] = tmp; @@ -444,7 +444,7 @@ int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, } else { bitmap = alloc; if (!bitmap) - bitmap = kzalloc(sizeof(*bitmap), GFP_NOWAIT); + bitmap = kzalloc_obj(*bitmap, GFP_NOWAIT); if (!bitmap) goto alloc; __set_bit(bit, bitmap->bitmap); @@ -465,7 +465,7 @@ int ida_alloc_range(struct ida *ida, unsigned int min, unsigned int max, return xas.xa_index * IDA_BITMAP_BITS + bit; alloc: xas_unlock_irqrestore(&xas, flags); - alloc = kzalloc(sizeof(*bitmap), gfp); + alloc = kzalloc_obj(*bitmap, gfp); if (!alloc) return -ENOMEM; xas_set(&xas, min / IDA_BITMAP_BITS); diff --git a/lib/interval_tree_test.c b/lib/interval_tree_test.c index 5fd62656f42e..16200feacbf3 100644 --- a/lib/interval_tree_test.c +++ b/lib/interval_tree_test.c @@ -311,8 +311,7 @@ static inline int span_iteration_check(void) {return 0; } static int interval_tree_test_init(void) { - nodes = kmalloc_array(nnodes, sizeof(struct interval_tree_node), - GFP_KERNEL); + nodes = kmalloc_objs(struct interval_tree_node, nnodes); if (!nodes) return -ENOMEM; diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 545250507f08..0a63c7fba313 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -903,7 +903,7 @@ static int want_pages_array(struct page ***res, size_t size, count = maxpages; WARN_ON(!count); // caller should've prevented that if (!*res) { - *res = kvmalloc_array(count, sizeof(struct page *), GFP_KERNEL); + *res = kvmalloc_objs(struct page *, count); if (!*res) return 0; } @@ -1318,7 +1318,7 @@ struct iovec *iovec_from_user(const struct iovec __user *uvec, if (nr_segs > UIO_MAXIOV) return ERR_PTR(-EINVAL); if (nr_segs > fast_segs) { - iov = kmalloc_array(nr_segs, sizeof(struct iovec), GFP_KERNEL); + iov = kmalloc_objs(struct iovec, nr_segs); if (!iov) return ERR_PTR(-ENOMEM); } diff --git a/lib/kobject.c b/lib/kobject.c index abe5f5b856ce..cfdb2c3f20a2 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -765,7 +765,7 @@ static struct kobject *kobject_create(void) { struct kobject *kobj; - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + kobj = kzalloc_obj(*kobj); if (!kobj) return NULL; @@ -962,7 +962,7 @@ static struct kset *kset_create(const char *name, struct kset *kset; int retval; - kset = kzalloc(sizeof(*kset), GFP_KERNEL); + kset = kzalloc_obj(*kset); if (!kset) return NULL; retval = kobject_set_name(&kset->kobj, "%s", name); diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index 78e16b95d210..871941c9830c 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c @@ -124,7 +124,7 @@ static int kobject_action_args(const char *buf, size_t count, if (!count) return -EINVAL; - env = kzalloc(sizeof(*env), GFP_KERNEL); + env = kzalloc_obj(*env); if (!env) return -ENOMEM; @@ -537,7 +537,7 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action, } /* environment buffer */ - env = kzalloc(sizeof(struct kobj_uevent_env), GFP_KERNEL); + env = kzalloc_obj(struct kobj_uevent_env); if (!env) return -ENOMEM; @@ -776,7 +776,7 @@ static int uevent_net_init(struct net *net) .flags = NL_CFG_F_NONROOT_RECV }; - ue_sk = kzalloc(sizeof(*ue_sk), GFP_KERNEL); + ue_sk = kzalloc_obj(*ue_sk); if (!ue_sk) return -ENOMEM; diff --git a/lib/kunit/attributes.c b/lib/kunit/attributes.c index 2cf04cc09372..6d7a53af94a9 100644 --- a/lib/kunit/attributes.c +++ b/lib/kunit/attributes.c @@ -410,7 +410,7 @@ struct kunit_suite *kunit_filter_attr_tests(const struct kunit_suite *const suit kunit_suite_for_each_test_case(suite, test_case) { n++; } - filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL); + filtered = kzalloc_objs(*filtered, n + 1); if (!filtered) { kfree(copy); return ERR_PTR(-ENOMEM); diff --git a/lib/kunit/device.c b/lib/kunit/device.c index f201aaacd4cf..85d57ad34045 100644 --- a/lib/kunit/device.c +++ b/lib/kunit/device.c @@ -111,7 +111,7 @@ static struct kunit_device *kunit_device_register_internal(struct kunit *test, struct kunit_device *kunit_dev; int err = -ENOMEM; - kunit_dev = kzalloc(sizeof(*kunit_dev), GFP_KERNEL); + kunit_dev = kzalloc_obj(*kunit_dev); if (!kunit_dev) return ERR_PTR(err); diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 02ff380ab793..1fef217de11d 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -131,7 +131,7 @@ kunit_filter_glob_tests(const struct kunit_suite *const suite, const char *test_ if (!copy) return ERR_PTR(-ENOMEM); - filtered = kcalloc(n + 1, sizeof(*filtered), GFP_KERNEL); + filtered = kzalloc_objs(*filtered, n + 1); if (!filtered) { kfree(copy); return ERR_PTR(-ENOMEM); @@ -179,7 +179,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, const size_t max = suite_set->end - suite_set->start; - copy = kcalloc(max, sizeof(*copy), GFP_KERNEL); + copy = kzalloc_objs(*copy, max); if (!copy) { /* won't be able to run anything, return an empty set */ return filtered; } @@ -194,7 +194,7 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, /* Parse attribute filters */ if (filters) { filter_count = kunit_get_filter_count(filters); - parsed_filters = kcalloc(filter_count, sizeof(*parsed_filters), GFP_KERNEL); + parsed_filters = kzalloc_objs(*parsed_filters, filter_count); if (!parsed_filters) { *err = -ENOMEM; goto free_parsed_glob; diff --git a/lib/kunit/executor_test.c b/lib/kunit/executor_test.c index f0090c2729cd..4cb119ad8f64 100644 --- a/lib/kunit/executor_test.c +++ b/lib/kunit/executor_test.c @@ -272,7 +272,7 @@ static void free_suite_set_at_end(struct kunit *test, const void *to_free) if (!((struct kunit_suite_set *)to_free)->start) return; - free = kzalloc(sizeof(struct kunit_suite_set), GFP_KERNEL); + free = kzalloc_obj(struct kunit_suite_set); *free = *(struct kunit_suite_set *)to_free; kunit_add_action(test, free_suite_set, (void *)free); diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c index 9452b163956f..0bae7b7ca0b0 100644 --- a/lib/kunit/kunit-example-test.c +++ b/lib/kunit/kunit-example-test.c @@ -283,7 +283,7 @@ static void example_slow_test(struct kunit *test) */ static int example_resource_init(struct kunit_resource *res, void *context) { - int *info = kmalloc(sizeof(*info), GFP_KERNEL); + int *info = kmalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c index 63130a48e237..126e30879dad 100644 --- a/lib/kunit/kunit-test.c +++ b/lib/kunit/kunit-test.c @@ -538,8 +538,7 @@ static void kunit_resource_test_action_ordering(struct kunit *test) static int kunit_resource_test_init(struct kunit *test) { - struct kunit_test_resource_context *ctx = - kzalloc(sizeof(*ctx), GFP_KERNEL); + struct kunit_test_resource_context *ctx = kzalloc_obj(*ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); diff --git a/lib/kunit/resource.c b/lib/kunit/resource.c index f0209252b179..45e55238ccf6 100644 --- a/lib/kunit/resource.c +++ b/lib/kunit/resource.c @@ -98,7 +98,7 @@ int kunit_add_action(struct kunit *test, void (*action)(void *), void *ctx) KUNIT_ASSERT_NOT_NULL_MSG(test, action, "Tried to action a NULL function!"); - action_ctx = kzalloc(sizeof(*action_ctx), GFP_KERNEL); + action_ctx = kzalloc_obj(*action_ctx); if (!action_ctx) return -ENOMEM; diff --git a/lib/kunit/static_stub.c b/lib/kunit/static_stub.c index 484fd85251b4..d9dd6377aa38 100644 --- a/lib/kunit/static_stub.c +++ b/lib/kunit/static_stub.c @@ -111,7 +111,7 @@ void __kunit_activate_static_stub(struct kunit *test, /* We got an extra reference from find_resource(), so put it. */ kunit_put_resource(res); } else { - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); ctx->real_fn_addr = real_fn_addr; ctx->replacement_addr = replacement_addr; diff --git a/lib/kunit/string-stream.c b/lib/kunit/string-stream.c index 54f4fdcbfac8..0d8f1b30559b 100644 --- a/lib/kunit/string-stream.c +++ b/lib/kunit/string-stream.c @@ -18,7 +18,7 @@ static struct string_stream_fragment *alloc_string_stream_fragment(int len, gfp_ { struct string_stream_fragment *frag; - frag = kzalloc(sizeof(*frag), gfp); + frag = kzalloc_obj(*frag, gfp); if (!frag) return ERR_PTR(-ENOMEM); @@ -158,7 +158,7 @@ struct string_stream *alloc_string_stream(gfp_t gfp) { struct string_stream *stream; - stream = kzalloc(sizeof(*stream), gfp); + stream = kzalloc_obj(*stream, gfp); if (!stream) return ERR_PTR(-ENOMEM); diff --git a/lib/kunit/test.c b/lib/kunit/test.c index 62eb529824c6..41e1c89799b6 100644 --- a/lib/kunit/test.c +++ b/lib/kunit/test.c @@ -94,7 +94,7 @@ struct kunit_result_stats { unsigned long total; }; -static bool kunit_should_print_stats(struct kunit_result_stats stats) +static bool kunit_should_print_stats(struct kunit_result_stats *stats) { if (kunit_stats_enabled == 0) return false; @@ -102,11 +102,11 @@ static bool kunit_should_print_stats(struct kunit_result_stats stats) if (kunit_stats_enabled == 2) return true; - return (stats.total > 1); + return (stats->total > 1); } static void kunit_print_test_stats(struct kunit *test, - struct kunit_result_stats stats) + struct kunit_result_stats *stats) { if (!kunit_should_print_stats(stats)) return; @@ -115,10 +115,10 @@ static void kunit_print_test_stats(struct kunit *test, KUNIT_SUBTEST_INDENT "# %s: pass:%lu fail:%lu skip:%lu total:%lu", test->name, - stats.passed, - stats.failed, - stats.skipped, - stats.total); + stats->passed, + stats->failed, + stats->skipped, + stats->total); } /* Append formatted message to log. */ @@ -600,26 +600,26 @@ static void kunit_run_case_catch_errors(struct kunit_suite *suite, } static void kunit_print_suite_stats(struct kunit_suite *suite, - struct kunit_result_stats suite_stats, - struct kunit_result_stats param_stats) + struct kunit_result_stats *suite_stats, + struct kunit_result_stats *param_stats) { if (kunit_should_print_stats(suite_stats)) { kunit_log(KERN_INFO, suite, "# %s: pass:%lu fail:%lu skip:%lu total:%lu", suite->name, - suite_stats.passed, - suite_stats.failed, - suite_stats.skipped, - suite_stats.total); + suite_stats->passed, + suite_stats->failed, + suite_stats->skipped, + suite_stats->total); } if (kunit_should_print_stats(param_stats)) { kunit_log(KERN_INFO, suite, "# Totals: pass:%lu fail:%lu skip:%lu total:%lu", - param_stats.passed, - param_stats.failed, - param_stats.skipped, - param_stats.total); + param_stats->passed, + param_stats->failed, + param_stats->skipped, + param_stats->total); } } @@ -681,13 +681,116 @@ static void kunit_init_parent_param_test(struct kunit_case *test_case, struct ku } } -int kunit_run_tests(struct kunit_suite *suite) +static noinline_for_stack void +kunit_run_param_test(struct kunit_suite *suite, struct kunit_case *test_case, + struct kunit *test, + struct kunit_result_stats *suite_stats, + struct kunit_result_stats *total_stats, + struct kunit_result_stats *param_stats) { char param_desc[KUNIT_PARAM_DESC_SIZE]; + const void *curr_param; + + kunit_init_parent_param_test(test_case, test); + if (test_case->status == KUNIT_FAILURE) { + kunit_update_stats(param_stats, test->status); + return; + } + /* Get initial param. */ + param_desc[0] = '\0'; + /* TODO: Make generate_params try-catch */ + curr_param = test_case->generate_params(test, NULL, param_desc); + test_case->status = KUNIT_SKIPPED; + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT + "KTAP version 1\n"); + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT + "# Subtest: %s", test_case->name); + if (test->params_array.params && + test_case->generate_params == kunit_array_gen_params) { + kunit_log(KERN_INFO, test, KUNIT_SUBTEST_INDENT + KUNIT_SUBTEST_INDENT "1..%zd\n", + test->params_array.num_params); + } + + while (curr_param) { + struct kunit param_test = { + .param_value = curr_param, + .param_index = ++test->param_index, + .parent = test, + }; + kunit_init_test(¶m_test, test_case->name, NULL); + param_test.log = test_case->log; + kunit_run_case_catch_errors(suite, test_case, ¶m_test); + + if (param_desc[0] == '\0') { + snprintf(param_desc, sizeof(param_desc), + "param-%d", param_test.param_index); + } + + kunit_print_ok_not_ok(¶m_test, KUNIT_LEVEL_CASE_PARAM, + param_test.status, + param_test.param_index, + param_desc, + param_test.status_comment); + + kunit_update_stats(param_stats, param_test.status); + + /* Get next param. */ + param_desc[0] = '\0'; + curr_param = test_case->generate_params(test, curr_param, + param_desc); + } + /* + * TODO: Put into a try catch. Since we don't need suite->exit + * for it we can't reuse kunit_try_run_cleanup for this yet. + */ + if (test_case->param_exit) + test_case->param_exit(test); + /* TODO: Put this kunit_cleanup into a try-catch. */ + kunit_cleanup(test); +} + +static noinline_for_stack void +kunit_run_one_test(struct kunit_suite *suite, struct kunit_case *test_case, + struct kunit_result_stats *suite_stats, + struct kunit_result_stats *total_stats) +{ + struct kunit test = { .param_value = NULL, .param_index = 0 }; + struct kunit_result_stats param_stats = { 0 }; + + kunit_init_test(&test, test_case->name, test_case->log); + if (test_case->status == KUNIT_SKIPPED) { + /* Test marked as skip */ + test.status = KUNIT_SKIPPED; + kunit_update_stats(¶m_stats, test.status); + } else if (!test_case->generate_params) { + /* Non-parameterised test. */ + test_case->status = KUNIT_SKIPPED; + kunit_run_case_catch_errors(suite, test_case, &test); + kunit_update_stats(¶m_stats, test.status); + } else { + kunit_run_param_test(suite, test_case, &test, suite_stats, + total_stats, ¶m_stats); + } + kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE); + + kunit_print_test_stats(&test, ¶m_stats); + + kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status, + kunit_test_case_num(suite, test_case), + test_case->name, + test.status_comment); + + kunit_update_stats(suite_stats, test_case->status); + kunit_accumulate_stats(total_stats, param_stats); +} + + +int kunit_run_tests(struct kunit_suite *suite) +{ struct kunit_case *test_case; struct kunit_result_stats suite_stats = { 0 }; struct kunit_result_stats total_stats = { 0 }; - const void *curr_param; /* Taint the kernel so we know we've run tests. */ add_taint(TAINT_TEST, LOCKDEP_STILL_OK); @@ -703,97 +806,13 @@ int kunit_run_tests(struct kunit_suite *suite) kunit_print_suite_start(suite); - kunit_suite_for_each_test_case(suite, test_case) { - struct kunit test = { .param_value = NULL, .param_index = 0 }; - struct kunit_result_stats param_stats = { 0 }; - - kunit_init_test(&test, test_case->name, test_case->log); - if (test_case->status == KUNIT_SKIPPED) { - /* Test marked as skip */ - test.status = KUNIT_SKIPPED; - kunit_update_stats(¶m_stats, test.status); - } else if (!test_case->generate_params) { - /* Non-parameterised test. */ - test_case->status = KUNIT_SKIPPED; - kunit_run_case_catch_errors(suite, test_case, &test); - kunit_update_stats(¶m_stats, test.status); - } else { - kunit_init_parent_param_test(test_case, &test); - if (test_case->status == KUNIT_FAILURE) { - kunit_update_stats(¶m_stats, test.status); - goto test_case_end; - } - /* Get initial param. */ - param_desc[0] = '\0'; - /* TODO: Make generate_params try-catch */ - curr_param = test_case->generate_params(&test, NULL, param_desc); - test_case->status = KUNIT_SKIPPED; - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT - "KTAP version 1\n"); - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT KUNIT_SUBTEST_INDENT - "# Subtest: %s", test_case->name); - if (test.params_array.params && - test_case->generate_params == kunit_array_gen_params) { - kunit_log(KERN_INFO, &test, KUNIT_SUBTEST_INDENT - KUNIT_SUBTEST_INDENT "1..%zd\n", - test.params_array.num_params); - } - - while (curr_param) { - struct kunit param_test = { - .param_value = curr_param, - .param_index = ++test.param_index, - .parent = &test, - }; - kunit_init_test(¶m_test, test_case->name, NULL); - param_test.log = test_case->log; - kunit_run_case_catch_errors(suite, test_case, ¶m_test); - - if (param_desc[0] == '\0') { - snprintf(param_desc, sizeof(param_desc), - "param-%d", param_test.param_index); - } - - kunit_print_ok_not_ok(¶m_test, KUNIT_LEVEL_CASE_PARAM, - param_test.status, - param_test.param_index, - param_desc, - param_test.status_comment); - - kunit_update_stats(¶m_stats, param_test.status); - - /* Get next param. */ - param_desc[0] = '\0'; - curr_param = test_case->generate_params(&test, curr_param, - param_desc); - } - /* - * TODO: Put into a try catch. Since we don't need suite->exit - * for it we can't reuse kunit_try_run_cleanup for this yet. - */ - if (test_case->param_exit) - test_case->param_exit(&test); - /* TODO: Put this kunit_cleanup into a try-catch. */ - kunit_cleanup(&test); - } -test_case_end: - kunit_print_attr((void *)test_case, true, KUNIT_LEVEL_CASE); - - kunit_print_test_stats(&test, param_stats); - - kunit_print_ok_not_ok(&test, KUNIT_LEVEL_CASE, test_case->status, - kunit_test_case_num(suite, test_case), - test_case->name, - test.status_comment); - - kunit_update_stats(&suite_stats, test_case->status); - kunit_accumulate_stats(&total_stats, param_stats); - } + kunit_suite_for_each_test_case(suite, test_case) + kunit_run_one_test(suite, test_case, &suite_stats, &total_stats); if (suite->suite_exit) suite->suite_exit(suite); - kunit_print_suite_stats(suite, suite_stats, total_stats); + kunit_print_suite_stats(suite, &suite_stats, &total_stats); suite_end: kunit_print_suite_end(suite); diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c index b247d412ddef..42a571d05670 100644 --- a/lib/logic_iomem.c +++ b/lib/logic_iomem.c @@ -48,7 +48,7 @@ int logic_iomem_add_region(struct resource *resource, if (WARN_ON((resource->flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM)) return -EINVAL; - rreg = kzalloc(sizeof(*rreg), GFP_KERNEL); + rreg = kzalloc_obj(*rreg); if (!rreg) return -ENOMEM; diff --git a/lib/lru_cache.c b/lib/lru_cache.c index 9e0d469c7658..82f775044056 100644 --- a/lib/lru_cache.c +++ b/lib/lru_cache.c @@ -94,14 +94,14 @@ struct lru_cache *lc_create(const char *name, struct kmem_cache *cache, if (e_count > LC_MAX_ACTIVE) return NULL; - slot = kcalloc(e_count, sizeof(struct hlist_head), GFP_KERNEL); + slot = kzalloc_objs(struct hlist_head, e_count); if (!slot) goto out_fail; - element = kcalloc(e_count, sizeof(struct lc_element *), GFP_KERNEL); + element = kzalloc_objs(struct lc_element *, e_count); if (!element) goto out_fail; - lc = kzalloc(sizeof(*lc), GFP_KERNEL); + lc = kzalloc_obj(*lc); if (!lc) goto out_fail; diff --git a/lib/lwq.c b/lib/lwq.c index 57d080a4d53d..c1e11ba6f254 100644 --- a/lib/lwq.c +++ b/lib/lwq.c @@ -110,7 +110,7 @@ static int lwq_test(void) for (i = 0; i < ARRAY_SIZE(threads); i++) threads[i] = kthread_run(lwq_exercise, &q, "lwq-test-%d", i); for (i = 0; i < 100; i++) { - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) break; t->i = i; diff --git a/lib/objagg.c b/lib/objagg.c index 363e43e849ac..23c7105a3f9f 100644 --- a/lib/objagg.c +++ b/lib/objagg.c @@ -525,7 +525,7 @@ struct objagg *objagg_create(const struct objagg_ops *ops, !ops->delta_destroy)) return ERR_PTR(-EINVAL); - objagg = kzalloc(sizeof(*objagg), GFP_KERNEL); + objagg = kzalloc_obj(*objagg); if (!objagg) return ERR_PTR(-ENOMEM); objagg->ops = ops; @@ -610,8 +610,8 @@ const struct objagg_stats *objagg_stats_get(struct objagg *objagg) struct objagg_obj *objagg_obj; int i; - objagg_stats = kzalloc(struct_size(objagg_stats, stats_info, - objagg->obj_count), GFP_KERNEL); + objagg_stats = kzalloc_flex(*objagg_stats, stats_info, + objagg->obj_count); if (!objagg_stats) return ERR_PTR(-ENOMEM); @@ -786,11 +786,11 @@ static struct objagg_tmp_graph *objagg_tmp_graph_create(struct objagg *objagg) struct objagg_obj *objagg_obj; int i, j; - graph = kzalloc(sizeof(*graph), GFP_KERNEL); + graph = kzalloc_obj(*graph); if (!graph) return NULL; - graph->nodes = kcalloc(nodes_count, sizeof(*graph->nodes), GFP_KERNEL); + graph->nodes = kzalloc_objs(*graph->nodes, nodes_count); if (!graph->nodes) goto err_nodes_alloc; graph->nodes_count = nodes_count; @@ -930,7 +930,7 @@ struct objagg_hints *objagg_hints_get(struct objagg *objagg, struct objagg_hints *objagg_hints; int err; - objagg_hints = kzalloc(sizeof(*objagg_hints), GFP_KERNEL); + objagg_hints = kzalloc_obj(*objagg_hints); if (!objagg_hints) return ERR_PTR(-ENOMEM); @@ -1010,9 +1010,8 @@ objagg_hints_stats_get(struct objagg_hints *objagg_hints) struct objagg_hints_node *hnode; int i; - objagg_stats = kzalloc(struct_size(objagg_stats, stats_info, - objagg_hints->node_count), - GFP_KERNEL); + objagg_stats = kzalloc_flex(*objagg_stats, stats_info, + objagg_hints->node_count); if (!objagg_stats) return ERR_PTR(-ENOMEM); diff --git a/lib/objpool.c b/lib/objpool.c index b998b720c732..d98fadf1de16 100644 --- a/lib/objpool.c +++ b/lib/objpool.c @@ -142,7 +142,7 @@ int objpool_init(struct objpool_head *pool, int nr_objs, int object_size, pool->gfp = gfp & ~__GFP_ZERO; pool->context = context; pool->release = release; - slot_size = nr_cpu_ids * sizeof(struct objpool_slot); + slot_size = nr_cpu_ids * sizeof(struct objpool_slot *); pool->cpu_slots = kzalloc(slot_size, pool->gfp); if (!pool->cpu_slots) return -ENOMEM; diff --git a/lib/once.c b/lib/once.c index 8557eb489f34..d801bfa945e6 100644 --- a/lib/once.c +++ b/lib/once.c @@ -26,7 +26,7 @@ static void once_disable_jump(struct static_key_true *key, struct module *mod) { struct once_work *w; - w = kmalloc(sizeof(*w), GFP_ATOMIC); + w = kmalloc_obj(*w, GFP_ATOMIC); if (!w) return; diff --git a/lib/parman.c b/lib/parman.c index 3f8f8d422e62..0de691c202ab 100644 --- a/lib/parman.c +++ b/lib/parman.c @@ -268,7 +268,7 @@ struct parman *parman_create(const struct parman_ops *ops, void *priv) { struct parman *parman; - parman = kzalloc(sizeof(*parman), GFP_KERNEL); + parman = kzalloc_obj(*parman); if (!parman) return NULL; INIT_LIST_HEAD(&parman->prio_list); diff --git a/lib/percpu-refcount.c b/lib/percpu-refcount.c index 668f6aa6a75d..97772e42b9b2 100644 --- a/lib/percpu-refcount.c +++ b/lib/percpu-refcount.c @@ -73,7 +73,7 @@ int percpu_ref_init(struct percpu_ref *ref, percpu_ref_func_t *release, if (!ref->percpu_count_ptr) return -ENOMEM; - data = kzalloc(sizeof(*ref->data), gfp); + data = kzalloc_obj(*ref->data, gfp); if (!data) { free_percpu((void __percpu *)ref->percpu_count_ptr); ref->percpu_count_ptr = 0; diff --git a/lib/pldmfw/pldmfw.c b/lib/pldmfw/pldmfw.c index b45ceb725780..e4612ea147bb 100644 --- a/lib/pldmfw/pldmfw.c +++ b/lib/pldmfw/pldmfw.c @@ -287,7 +287,7 @@ pldm_parse_desc_tlvs(struct pldmfw_priv *data, struct pldmfw_record *record, u8 if (err) return err; - desc = kzalloc(sizeof(*desc), GFP_KERNEL); + desc = kzalloc_obj(*desc); if (!desc) return -ENOMEM; @@ -328,7 +328,7 @@ pldm_parse_one_record(struct pldmfw_priv *data, int i; /* Make a copy and insert it into the record list */ - record = kzalloc(sizeof(*record), GFP_KERNEL); + record = kzalloc_obj(*record); if (!record) return -ENOMEM; @@ -465,7 +465,7 @@ static int pldm_parse_components(struct pldmfw_priv *data) if (err) return err; - component = kzalloc(sizeof(*component), GFP_KERNEL); + component = kzalloc_obj(*component); if (!component) return -ENOMEM; @@ -848,7 +848,7 @@ int pldmfw_flash_image(struct pldmfw *context, const struct firmware *fw) struct pldmfw_priv *data; int err; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/lib/rbtree_test.c b/lib/rbtree_test.c index 690cede46ac2..768c5e6453f3 100644 --- a/lib/rbtree_test.c +++ b/lib/rbtree_test.c @@ -399,7 +399,7 @@ static int augmented_check(void) static int __init rbtree_test_init(void) { - nodes = kmalloc_array(nnodes, sizeof(*nodes), GFP_KERNEL); + nodes = kmalloc_objs(*nodes, nnodes); if (!nodes) return -ENOMEM; diff --git a/lib/reed_solomon/reed_solomon.c b/lib/reed_solomon/reed_solomon.c index a9e2dcb6f2a7..864484c01827 100644 --- a/lib/reed_solomon/reed_solomon.c +++ b/lib/reed_solomon/reed_solomon.c @@ -73,7 +73,7 @@ static struct rs_codec *codec_init(int symsize, int gfpoly, int (*gffunc)(int), int i, j, sr, root, iprim; struct rs_codec *rs; - rs = kzalloc(sizeof(*rs), gfp); + rs = kzalloc_obj(*rs, gfp); if (!rs) return NULL; diff --git a/lib/reed_solomon/test_rslib.c b/lib/reed_solomon/test_rslib.c index 75cb1adac884..42b856e6c8a8 100644 --- a/lib/reed_solomon/test_rslib.c +++ b/lib/reed_solomon/test_rslib.c @@ -111,7 +111,7 @@ static struct wspace *alloc_ws(struct rs_codec *rs) struct wspace *ws; int nn = rs->nn; - ws = kzalloc(sizeof(*ws), GFP_KERNEL); + ws = kzalloc_obj(*ws); if (!ws) return NULL; @@ -124,7 +124,7 @@ static struct wspace *alloc_ws(struct rs_codec *rs) ws->s = ws->r + nn; ws->corr = ws->s + nroots; - ws->errlocs = kmalloc_array(nn + nroots, sizeof(int), GFP_KERNEL); + ws->errlocs = kmalloc_objs(int, nn + nroots); if (!ws->errlocs) goto err; diff --git a/lib/ref_tracker.c b/lib/ref_tracker.c index 258fb0e7abdf..30c999d57b10 100644 --- a/lib/ref_tracker.c +++ b/lib/ref_tracker.c @@ -74,8 +74,7 @@ ref_tracker_get_stats(struct ref_tracker_dir *dir, unsigned int limit) struct ref_tracker_dir_stats *stats; struct ref_tracker *tracker; - stats = kmalloc(struct_size(stats, stacks, limit), - GFP_NOWAIT); + stats = kmalloc_flex(*stats, stacks, limit, GFP_NOWAIT); if (!stats) return ERR_PTR(-ENOMEM); stats->total = 0; @@ -268,7 +267,7 @@ int ref_tracker_alloc(struct ref_tracker_dir *dir, } if (gfp & __GFP_DIRECT_RECLAIM) gfp_mask |= __GFP_NOFAIL; - *trackerp = tracker = kzalloc(sizeof(*tracker), gfp_mask); + *trackerp = tracker = kzalloc_obj(*tracker, gfp_mask); if (unlikely(!tracker)) { pr_err_once("memory allocation failure, unreliable refcount tracker.\n"); refcount_inc(&dir->untracked); diff --git a/lib/scatterlist.c b/lib/scatterlist.c index 4af1c8b0775a..d773720d11bf 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -64,6 +64,32 @@ int sg_nents_for_len(struct scatterlist *sg, u64 len) } EXPORT_SYMBOL(sg_nents_for_len); +/** + * sg_nents_for_dma - return the count of DMA-capable entries in scatterlist + * @sgl: The scatterlist + * @sglen: The current number of entries + * @len: The maximum length of DMA-capable block + * + * Description: + * Determines the number of entries in @sgl which would be permitted in + * DMA-capable transfer if list had been split accordingly, taking into + * account chaining as well. + * + * Returns: + * the number of sgl entries needed + * + **/ +int sg_nents_for_dma(struct scatterlist *sgl, unsigned int sglen, size_t len) +{ + struct scatterlist *sg; + int i, nents = 0; + + for_each_sg(sgl, sg, sglen, i) + nents += DIV_ROUND_UP(sg_dma_len(sg), len); + return nents; +} +EXPORT_SYMBOL(sg_nents_for_dma); + /** * sg_last - return the last scatterlist entry in a list * @sgl: First entry in the scatterlist @@ -142,8 +168,7 @@ static struct scatterlist *sg_kmalloc(unsigned int nents, gfp_t gfp_mask) kmemleak_alloc(ptr, PAGE_SIZE, 1, gfp_mask); return ptr; } else - return kmalloc_array(nents, sizeof(struct scatterlist), - gfp_mask); + return kmalloc_objs(struct scatterlist, nents, gfp_mask); } static void sg_kfree(struct scatterlist *sg, unsigned int nents) @@ -606,8 +631,7 @@ struct scatterlist *sgl_alloc_order(unsigned long long length, return NULL; nalloc++; } - sgl = kmalloc_array(nalloc, sizeof(struct scatterlist), - gfp & ~GFP_DMA); + sgl = kmalloc_objs(struct scatterlist, nalloc, gfp & ~GFP_DMA); if (!sgl) return NULL; diff --git a/lib/sg_split.c b/lib/sg_split.c index 0f89aab5c671..24e8f5e48e63 100644 --- a/lib/sg_split.c +++ b/lib/sg_split.c @@ -152,7 +152,7 @@ int sg_split(struct scatterlist *in, const int in_mapped_nents, int i, ret; struct sg_splitter *splitters; - splitters = kcalloc(nb_splits, sizeof(*splitters), gfp_mask); + splitters = kzalloc_objs(*splitters, nb_splits, gfp_mask); if (!splitters) return -ENOMEM; @@ -163,9 +163,8 @@ int sg_split(struct scatterlist *in, const int in_mapped_nents, ret = -ENOMEM; for (i = 0; i < nb_splits; i++) { - splitters[i].out_sg = kmalloc_array(splitters[i].nents, - sizeof(struct scatterlist), - gfp_mask); + splitters[i].out_sg = kmalloc_objs(struct scatterlist, + splitters[i].nents, gfp_mask); if (!splitters[i].out_sg) goto err; } diff --git a/lib/stackdepot.c b/lib/stackdepot.c index 166f50ad8391..dd2717ff94bf 100644 --- a/lib/stackdepot.c +++ b/lib/stackdepot.c @@ -260,7 +260,7 @@ int stack_depot_init(void) entries = 1UL << STACK_BUCKET_NUMBER_ORDER_MAX; pr_info("allocating hash table of %lu entries via kvcalloc\n", entries); - stack_table = kvcalloc(entries, sizeof(struct list_head), GFP_KERNEL); + stack_table = kvzalloc_objs(struct list_head, entries); if (!stack_table) { pr_err("hash table allocation failed, disabling\n"); stack_depot_disabled = true; diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 8cb6f66c9c2b..169eaf583494 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -147,7 +147,7 @@ int parse_int_array(const char *buf, size_t count, int **array) if (!nints) return -ENOENT; - ints = kcalloc(nints + 1, sizeof(*ints), GFP_KERNEL); + ints = kzalloc_objs(*ints, nints + 1); if (!ints) return -ENOMEM; diff --git a/lib/test_bpf.c b/lib/test_bpf.c index af0041df2b72..5892c0f17ddc 100644 --- a/lib/test_bpf.c +++ b/lib/test_bpf.c @@ -94,7 +94,7 @@ static int bpf_fill_maxinsns1(struct bpf_test *self) __u32 k = ~0; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -113,7 +113,7 @@ static int bpf_fill_maxinsns2(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -133,7 +133,7 @@ static int bpf_fill_maxinsns3(struct bpf_test *self) struct rnd_state rnd; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -159,7 +159,7 @@ static int bpf_fill_maxinsns4(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -178,7 +178,7 @@ static int bpf_fill_maxinsns5(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -201,7 +201,7 @@ static int bpf_fill_maxinsns6(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -223,7 +223,7 @@ static int bpf_fill_maxinsns7(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -249,7 +249,7 @@ static int bpf_fill_maxinsns8(struct bpf_test *self) struct sock_filter *insn; int i, jmp_off = len - 3; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -272,7 +272,7 @@ static int bpf_fill_maxinsns9(struct bpf_test *self) struct bpf_insn *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -298,7 +298,7 @@ static int bpf_fill_maxinsns10(struct bpf_test *self) struct bpf_insn *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -324,7 +324,7 @@ static int __bpf_fill_ja(struct bpf_test *self, unsigned int len, unsigned int rlen; int i, j; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -358,7 +358,7 @@ static int bpf_fill_maxinsns12(struct bpf_test *self) struct sock_filter *insn; int i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -381,7 +381,7 @@ static int bpf_fill_maxinsns13(struct bpf_test *self) struct sock_filter *insn; int i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -410,7 +410,7 @@ static int bpf_fill_ld_abs_get_processor_id(struct bpf_test *self) struct sock_filter *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -434,7 +434,7 @@ static int __bpf_fill_stxdw(struct bpf_test *self, int size) struct bpf_insn *insn; int i; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -484,7 +484,7 @@ static int __bpf_fill_max_jmp(struct bpf_test *self, int jmp, int imm, bool alu3 int len = S16_MAX + 5; int i; - insns = kmalloc_array(len, sizeof(*insns), GFP_KERNEL); + insns = kmalloc_objs(*insns, len); if (!insns) return -ENOMEM; @@ -626,7 +626,7 @@ static int __bpf_fill_alu_shift(struct bpf_test *self, u8 op, int imm, k; int i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -759,7 +759,7 @@ static int __bpf_fill_alu_shift_same_reg(struct bpf_test *self, u8 op, int i = 0; u64 val; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -1244,7 +1244,7 @@ static int __bpf_fill_alu_imm_regs(struct bpf_test *self, u8 op, bool alu32) u32 imm; int rd; - insns = kmalloc_array(len, sizeof(*insns), GFP_KERNEL); + insns = kmalloc_objs(*insns, len); if (!insns) return -ENOMEM; @@ -1426,7 +1426,7 @@ static int __bpf_fill_alu_reg_pairs(struct bpf_test *self, u8 op, bool alu32) int rd, rs; int i = 0; - insns = kmalloc_array(len, sizeof(*insns), GFP_KERNEL); + insns = kmalloc_objs(*insns, len); if (!insns) return -ENOMEM; @@ -1917,7 +1917,7 @@ static int __bpf_fill_atomic_reg_pairs(struct bpf_test *self, u8 width, u8 op) u64 mem, upd, res; int rd, rs, i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -2163,7 +2163,7 @@ static int bpf_fill_ld_imm64_magn(struct bpf_test *self) int bit, adj, sign; int i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -2217,7 +2217,7 @@ static int __bpf_fill_ld_imm64_bytes(struct bpf_test *self, u32 rand = 1; int i = 0; - insn = kmalloc_array(len, sizeof(*insn), GFP_KERNEL); + insn = kmalloc_objs(*insn, len); if (!insn) return -ENOMEM; @@ -2724,7 +2724,7 @@ static int __bpf_fill_staggered_jumps(struct bpf_test *self, struct bpf_insn *insns; int off, ind; - insns = kmalloc_array(len, sizeof(*insns), GFP_KERNEL); + insns = kmalloc_objs(*insns, len); if (!insns) return -ENOMEM; @@ -15461,7 +15461,7 @@ static __init int prepare_tail_call_tests(struct bpf_array **pprogs) int which, err; /* Allocate the table of programs to be used for tail calls */ - progs = kzalloc(struct_size(progs, ptrs, ntests + 1), GFP_KERNEL); + progs = kzalloc_flex(*progs, ptrs, ntests + 1); if (!progs) goto out_nomem; diff --git a/lib/test_debug_virtual.c b/lib/test_debug_virtual.c index b7cc0aaee173..518ee8d213cd 100644 --- a/lib/test_debug_virtual.c +++ b/lib/test_debug_virtual.c @@ -29,7 +29,7 @@ static int __init test_debug_virtual_init(void) pr_info("PA: %pa for VA: 0x%lx\n", &pa, (unsigned long)va); - foo = kzalloc(sizeof(*foo), GFP_KERNEL); + foo = kzalloc_obj(*foo); if (!foo) return -ENOMEM; diff --git a/lib/test_firmware.c b/lib/test_firmware.c index be4f93124901..b471d720879a 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -1309,7 +1309,7 @@ static ssize_t upload_register_store(struct device *dev, goto free_name; } - tst = kzalloc(sizeof(*tst), GFP_KERNEL); + tst = kzalloc_obj(*tst); if (!tst) { ret = -ENOMEM; goto free_name; @@ -1526,7 +1526,7 @@ static int __init test_firmware_init(void) { int rc; - test_fw_config = kzalloc(sizeof(struct test_config), GFP_KERNEL); + test_fw_config = kzalloc_obj(struct test_config); if (!test_fw_config) return -ENOMEM; diff --git a/lib/test_hmm.c b/lib/test_hmm.c index 455a6862ae50..0964d53365e6 100644 --- a/lib/test_hmm.c +++ b/lib/test_hmm.c @@ -166,7 +166,7 @@ static int dmirror_fops_open(struct inode *inode, struct file *filp) int ret; /* Mirror this process address space */ - dmirror = kzalloc(sizeof(*dmirror), GFP_KERNEL); + dmirror = kzalloc_obj(*dmirror); if (dmirror == NULL) return -ENOMEM; @@ -504,7 +504,7 @@ static int dmirror_allocate_chunk(struct dmirror_device *mdevice, void *ptr; int ret = -ENOMEM; - devmem = kzalloc(sizeof(*devmem), GFP_KERNEL); + devmem = kzalloc_obj(*devmem); if (!devmem) return ret; diff --git a/lib/test_kho.c b/lib/test_kho.c index a20fafaf9846..7ef9e4061869 100644 --- a/lib/test_kho.c +++ b/lib/test_kho.c @@ -211,7 +211,7 @@ static int kho_test_save(void) max_mem = PAGE_ALIGN(max_mem); max_nr = max_mem >> PAGE_SHIFT; - folios = kvmalloc_array(max_nr, sizeof(*state->folios), GFP_KERNEL); + folios = kvmalloc_objs(*state->folios, max_nr); if (!folios) return -ENOMEM; state->folios = folios; diff --git a/lib/test_memcat_p.c b/lib/test_memcat_p.c index 7e0797a6bebf..62f1633b30f8 100644 --- a/lib/test_memcat_p.c +++ b/lib/test_memcat_p.c @@ -24,20 +24,20 @@ static int __init test_memcat_p_init(void) struct test_struct **in0, **in1, **out, **p; int err = -ENOMEM, i, r, total = 0; - in0 = kcalloc(INPUT_MAX, sizeof(*in0), GFP_KERNEL); + in0 = kzalloc_objs(*in0, INPUT_MAX); if (!in0) return err; - in1 = kcalloc(INPUT_MAX, sizeof(*in1), GFP_KERNEL); + in1 = kzalloc_objs(*in1, INPUT_MAX); if (!in1) goto err_free_in0; for (i = 0, r = 1; i < INPUT_MAX - 1; i++) { - in0[i] = kmalloc(sizeof(**in0), GFP_KERNEL); + in0[i] = kmalloc_obj(**in0); if (!in0[i]) goto err_free_elements; - in1[i] = kmalloc(sizeof(**in1), GFP_KERNEL); + in1[i] = kmalloc_obj(**in1); if (!in1[i]) { kfree(in0[i]); goto err_free_elements; diff --git a/lib/test_objagg.c b/lib/test_objagg.c index ce5c4c36a084..f21e3ae01395 100644 --- a/lib/test_objagg.c +++ b/lib/test_objagg.c @@ -107,7 +107,7 @@ static void *delta_create(void *priv, void *parent_obj, void *obj) if (!delta_check(priv, parent_obj, obj)) return ERR_PTR(-EINVAL); - delta = kzalloc(sizeof(*delta), GFP_KERNEL); + delta = kzalloc_obj(*delta); if (!delta) return ERR_PTR(-ENOMEM); delta->key_id_diff = diff; @@ -130,7 +130,7 @@ static void *root_create(void *priv, void *obj, unsigned int id) struct tokey *key = obj; struct root *root; - root = kzalloc(sizeof(*root), GFP_KERNEL); + root = kzalloc_obj(*root); if (!root) return ERR_PTR(-ENOMEM); memcpy(&root->key, key, sizeof(root->key)); diff --git a/lib/test_parman.c b/lib/test_parman.c index f9b97426a337..28f0951189ab 100644 --- a/lib/test_parman.c +++ b/lib/test_parman.c @@ -219,7 +219,7 @@ static struct test_parman *test_parman_create(const struct parman_ops *ops) struct test_parman *test_parman; int err; - test_parman = kzalloc(sizeof(*test_parman), GFP_KERNEL); + test_parman = kzalloc_obj(*test_parman); if (!test_parman) return ERR_PTR(-ENOMEM); err = test_parman_resize(test_parman, TEST_PARMAN_BASE_COUNT); diff --git a/lib/test_rhashtable.c b/lib/test_rhashtable.c index c63db03ebb9d..0b33559a910b 100644 --- a/lib/test_rhashtable.c +++ b/lib/test_rhashtable.c @@ -524,7 +524,7 @@ static int __init test_insert_dup(struct test_obj_rhl *rhl_test_objects, const char *key; int err = 0; - rhlt = kmalloc(sizeof(*rhlt), GFP_KERNEL); + rhlt = kmalloc_obj(*rhlt); if (WARN_ON(!rhlt)) return -EINVAL; diff --git a/lib/test_vmalloc.c b/lib/test_vmalloc.c index 270b6f7ca807..876c72c18a0c 100644 --- a/lib/test_vmalloc.c +++ b/lib/test_vmalloc.c @@ -396,7 +396,7 @@ vm_map_ram_test(void) int i; map_nr_pages = nr_pages > 0 ? nr_pages:1; - pages = kcalloc(map_nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, map_nr_pages); if (!pages) return -1; @@ -542,7 +542,7 @@ init_test_configuration(void) nr_threads = clamp(nr_threads, 1, (int) USHRT_MAX); /* Allocate the space for test instances. */ - tdriver = kvcalloc(nr_threads, sizeof(*tdriver), GFP_KERNEL); + tdriver = kvzalloc_objs(*tdriver, nr_threads); if (tdriver == NULL) return -1; diff --git a/lib/tests/kunit_iov_iter.c b/lib/tests/kunit_iov_iter.c index 48342736d016..bb847e5010eb 100644 --- a/lib/tests/kunit_iov_iter.c +++ b/lib/tests/kunit_iov_iter.c @@ -387,7 +387,7 @@ static void __init iov_kunit_load_folioq(struct kunit *test, for (i = 0; i < npages; i++) { if (folioq_full(p)) { - p->next = kzalloc(sizeof(struct folio_queue), GFP_KERNEL); + p->next = kzalloc_obj(struct folio_queue); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p->next); folioq_init(p->next, 0); p->next->prev = p; @@ -403,7 +403,7 @@ static struct folio_queue *iov_kunit_create_folioq(struct kunit *test) { struct folio_queue *folioq; - folioq = kzalloc(sizeof(struct folio_queue), GFP_KERNEL); + folioq = kzalloc_obj(struct folio_queue); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, folioq); kunit_add_action_or_reset(test, iov_kunit_destroy_folioq, folioq); folioq_init(folioq, 0); @@ -565,7 +565,7 @@ static struct xarray *iov_kunit_create_xarray(struct kunit *test) { struct xarray *xarray; - xarray = kzalloc(sizeof(struct xarray), GFP_KERNEL); + xarray = kzalloc_obj(struct xarray); xa_init(xarray); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xarray); kunit_add_action_or_reset(test, iov_kunit_destroy_xarray, xarray); diff --git a/lib/tests/list-test.c b/lib/tests/list-test.c index 9135cdc1bb39..6d9227a2b204 100644 --- a/lib/tests/list-test.c +++ b/lib/tests/list-test.c @@ -26,10 +26,10 @@ static void list_test_list_init(struct kunit *test) INIT_LIST_HEAD(&list2); - list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL); + list4 = kzalloc_obj(*list4, GFP_KERNEL | __GFP_NOFAIL); INIT_LIST_HEAD(list4); - list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL); + list5 = kmalloc_obj(*list5, GFP_KERNEL | __GFP_NOFAIL); memset(list5, 0xFF, sizeof(*list5)); INIT_LIST_HEAD(list5); @@ -829,10 +829,10 @@ static void hlist_test_init(struct kunit *test) INIT_HLIST_HEAD(&list2); - list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL); + list4 = kzalloc_obj(*list4, GFP_KERNEL | __GFP_NOFAIL); INIT_HLIST_HEAD(list4); - list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL); + list5 = kmalloc_obj(*list5, GFP_KERNEL | __GFP_NOFAIL); memset(list5, 0xFF, sizeof(*list5)); INIT_HLIST_HEAD(list5); diff --git a/lib/tests/test_ratelimit.c b/lib/tests/test_ratelimit.c index bfaeca49304a..33cea5f3d28b 100644 --- a/lib/tests/test_ratelimit.c +++ b/lib/tests/test_ratelimit.c @@ -104,7 +104,7 @@ static void test_ratelimit_stress(struct kunit *test) int i; const int n_stress_kthread = cpumask_weight(cpu_online_mask); struct stress_kthread skt = { 0 }; - struct stress_kthread *sktp = kcalloc(n_stress_kthread, sizeof(*sktp), GFP_KERNEL); + struct stress_kthread *sktp = kzalloc_objs(*sktp, n_stress_kthread); KUNIT_EXPECT_NOT_NULL_MSG(test, sktp, "Memory allocation failure"); for (i = 0; i < n_stress_kthread; i++) { diff --git a/lib/xz/xz_dec_bcj.c b/lib/xz/xz_dec_bcj.c index 610d58d947ab..cc49a300a5b2 100644 --- a/lib/xz/xz_dec_bcj.c +++ b/lib/xz/xz_dec_bcj.c @@ -591,7 +591,7 @@ enum xz_ret xz_dec_bcj_run(struct xz_dec_bcj *s, struct xz_dec_lzma2 *lzma2, struct xz_dec_bcj *xz_dec_bcj_create(bool single_call) { - struct xz_dec_bcj *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct xz_dec_bcj *s = kmalloc_obj(*s); if (s != NULL) s->single_call = single_call; diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c index 83bb66b6016d..4b783ac94e71 100644 --- a/lib/xz/xz_dec_lzma2.c +++ b/lib/xz/xz_dec_lzma2.c @@ -1138,7 +1138,7 @@ enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s, struct xz_buf *b) struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode, uint32_t dict_max) { - struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct xz_dec_lzma2 *s = kmalloc_obj(*s); if (s == NULL) return NULL; @@ -1296,7 +1296,7 @@ struct xz_dec_microlzma *xz_dec_microlzma_alloc(enum xz_mode mode, if (dict_size < 4096 || dict_size > (3U << 30)) return NULL; - s = kmalloc(sizeof(*s), GFP_KERNEL); + s = kmalloc_obj(*s); if (s == NULL) return NULL; diff --git a/lib/xz/xz_dec_stream.c b/lib/xz/xz_dec_stream.c index f9d003684d56..59bfd54ffee7 100644 --- a/lib/xz/xz_dec_stream.c +++ b/lib/xz/xz_dec_stream.c @@ -784,7 +784,7 @@ enum xz_ret xz_dec_run(struct xz_dec *s, struct xz_buf *b) struct xz_dec *xz_dec_init(enum xz_mode mode, uint32_t dict_max) { - struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct xz_dec *s = kmalloc_obj(*s); if (s == NULL) return NULL; diff --git a/lib/zlib_inflate/infutil.c b/lib/zlib_inflate/infutil.c index 4824c2cc7a09..12169aacd3f1 100644 --- a/lib/zlib_inflate/infutil.c +++ b/lib/zlib_inflate/infutil.c @@ -14,7 +14,7 @@ int zlib_inflate_blob(void *gunzip_buf, unsigned int sz, int rc; rc = -ENOMEM; - strm = kmalloc(sizeof(*strm), GFP_KERNEL); + strm = kmalloc_obj(*strm); if (strm == NULL) goto gunzip_nomem1; strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); diff --git a/mm/backing-dev.c b/mm/backing-dev.c index e319bd5e8b75..7a18fa6c7272 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -689,7 +689,7 @@ static int cgwb_create(struct backing_dev_info *bdi, goto out_put; /* need to create a new one */ - wb = kmalloc(sizeof(*wb), gfp); + wb = kmalloc_obj(*wb, gfp); if (!wb) { ret = -ENOMEM; goto out_put; diff --git a/mm/cma.c b/mm/cma.c index 94b5da468a7d..15cc0ae76c8e 100644 --- a/mm/cma.c +++ b/mm/cma.c @@ -1013,6 +1013,7 @@ bool cma_release(struct cma *cma, const struct page *pages, unsigned long count) { struct cma_memrange *cmr; + unsigned long ret = 0; unsigned long i, pfn; cmr = find_cma_memrange(cma, pages, count); @@ -1021,7 +1022,9 @@ bool cma_release(struct cma *cma, const struct page *pages, pfn = page_to_pfn(pages); for (i = 0; i < count; i++, pfn++) - VM_WARN_ON(!put_page_testzero(pfn_to_page(pfn))); + ret += !put_page_testzero(pfn_to_page(pfn)); + + WARN(ret, "%lu pages are still in use!\n", ret); __cma_release_frozen(cma, cmr, pages, count); diff --git a/mm/cma_debug.c b/mm/cma_debug.c index 8c7d7f8e8fbd..5ae38f5abbcc 100644 --- a/mm/cma_debug.c +++ b/mm/cma_debug.c @@ -131,7 +131,7 @@ static int cma_alloc_mem(struct cma *cma, int count) struct cma_mem *mem; struct page *p; - mem = kzalloc(sizeof(*mem), GFP_KERNEL); + mem = kzalloc_obj(*mem); if (!mem) return -ENOMEM; diff --git a/mm/cma_sysfs.c b/mm/cma_sysfs.c index 97acd3e5a6a5..f52b696bc46d 100644 --- a/mm/cma_sysfs.c +++ b/mm/cma_sysfs.c @@ -117,7 +117,7 @@ static int __init cma_sysfs_init(void) return -ENOMEM; for (i = 0; i < cma_area_count; i++) { - cma_kobj = kzalloc(sizeof(*cma_kobj), GFP_KERNEL); + cma_kobj = kzalloc_obj(*cma_kobj); if (!cma_kobj) { err = -ENOMEM; goto out; diff --git a/mm/damon/core.c b/mm/damon/core.c index 5e2724a4f285..c1d1091d307e 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -273,7 +273,7 @@ struct damos_filter *damos_new_filter(enum damos_filter_type type, { struct damos_filter *filter; - filter = kmalloc(sizeof(*filter), GFP_KERNEL); + filter = kmalloc_obj(*filter); if (!filter) return NULL; filter->type = type; @@ -332,7 +332,7 @@ struct damos_quota_goal *damos_new_quota_goal( { struct damos_quota_goal *goal; - goal = kmalloc(sizeof(*goal), GFP_KERNEL); + goal = kmalloc_obj(*goal); if (!goal) return NULL; goal->metric = metric; @@ -385,7 +385,7 @@ struct damos *damon_new_scheme(struct damos_access_pattern *pattern, { struct damos *scheme; - scheme = kmalloc(sizeof(*scheme), GFP_KERNEL); + scheme = kmalloc_obj(*scheme); if (!scheme) return NULL; scheme->pattern = *pattern; @@ -473,7 +473,7 @@ struct damon_target *damon_new_target(void) { struct damon_target *t; - t = kmalloc(sizeof(*t), GFP_KERNEL); + t = kmalloc_obj(*t); if (!t) return NULL; @@ -529,7 +529,7 @@ struct damon_ctx *damon_new_ctx(void) { struct damon_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return NULL; @@ -1153,7 +1153,7 @@ static int damon_commit_target_regions(struct damon_target *dst, if (!i) return 0; - ranges = kmalloc_array(i, sizeof(*ranges), GFP_KERNEL | __GFP_NOWARN); + ranges = kmalloc_objs(*ranges, i, GFP_KERNEL | __GFP_NOWARN); if (!ranges) return -ENOMEM; i = 0; @@ -1252,6 +1252,9 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) { int err; + if (!is_power_of_2(src->min_region_sz)) + return -EINVAL; + err = damon_commit_schemes(dst, src); if (err) return err; @@ -1559,8 +1562,13 @@ int damos_walk(struct damon_ctx *ctx, struct damos_walk_control *control) } ctx->walk_control = control; mutex_unlock(&ctx->walk_control_lock); - if (!damon_is_running(ctx)) + if (!damon_is_running(ctx)) { + mutex_lock(&ctx->walk_control_lock); + if (ctx->walk_control == control) + ctx->walk_control = NULL; + mutex_unlock(&ctx->walk_control_lock); return -EINVAL; + } wait_for_completion(&control->completion); if (control->canceled) return -ECANCELED; diff --git a/mm/damon/stat.c b/mm/damon/stat.c index bcf6c8ae9b90..25fb44ccf99d 100644 --- a/mm/damon/stat.c +++ b/mm/damon/stat.c @@ -90,8 +90,8 @@ static int damon_stat_sort_regions(struct damon_ctx *c, damon_for_each_target(t, c) { /* there is only one target */ - region_pointers = kmalloc_array(damon_nr_regions(t), - sizeof(*region_pointers), GFP_KERNEL); + region_pointers = kmalloc_objs(*region_pointers, + damon_nr_regions(t)); if (!region_pointers) return -ENOMEM; damon_for_each_region(r, t) { diff --git a/mm/damon/sysfs-common.c b/mm/damon/sysfs-common.c index ffaf285e241a..83e24a9b5a0d 100644 --- a/mm/damon/sysfs-common.c +++ b/mm/damon/sysfs-common.c @@ -19,8 +19,7 @@ struct damon_sysfs_ul_range *damon_sysfs_ul_range_alloc( unsigned long min, unsigned long max) { - struct damon_sysfs_ul_range *range = kmalloc(sizeof(*range), - GFP_KERNEL); + struct damon_sysfs_ul_range *range = kmalloc_obj(*range); if (!range) return NULL; diff --git a/mm/damon/sysfs-schemes.c b/mm/damon/sysfs-schemes.c index 2b05a6477188..3a0782e576fa 100644 --- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -26,8 +26,7 @@ struct damon_sysfs_scheme_region { static struct damon_sysfs_scheme_region *damon_sysfs_scheme_region_alloc( struct damon_region *region) { - struct damon_sysfs_scheme_region *sysfs_region = kmalloc( - sizeof(*sysfs_region), GFP_KERNEL); + struct damon_sysfs_scheme_region *sysfs_region = kmalloc_obj(*sysfs_region); if (!sysfs_region) return NULL; @@ -138,8 +137,7 @@ struct damon_sysfs_scheme_regions { static struct damon_sysfs_scheme_regions * damon_sysfs_scheme_regions_alloc(void) { - struct damon_sysfs_scheme_regions *regions = kmalloc(sizeof(*regions), - GFP_KERNEL); + struct damon_sysfs_scheme_regions *regions = kmalloc_obj(*regions); if (!regions) return NULL; @@ -210,7 +208,7 @@ struct damon_sysfs_stats { static struct damon_sysfs_stats *damon_sysfs_stats_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_stats), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_stats); } static ssize_t nr_tried_show(struct kobject *kobj, struct kobj_attribute *attr, @@ -376,7 +374,7 @@ static struct damon_sysfs_scheme_filter *damon_sysfs_scheme_filter_alloc( { struct damon_sysfs_scheme_filter *filter; - filter = kzalloc(sizeof(struct damon_sysfs_scheme_filter), GFP_KERNEL); + filter = kzalloc_obj(struct damon_sysfs_scheme_filter); if (filter) filter->handle_layer = layer; return filter; @@ -724,7 +722,7 @@ damon_sysfs_scheme_filters_alloc(enum damos_sysfs_filter_handle_layer layer) { struct damon_sysfs_scheme_filters *filters; - filters = kzalloc(sizeof(struct damon_sysfs_scheme_filters), GFP_KERNEL); + filters = kzalloc_obj(struct damon_sysfs_scheme_filters); if (filters) filters->handle_layer = layer; return filters; @@ -753,8 +751,8 @@ static int damon_sysfs_scheme_filters_add_dirs( if (!nr_filters) return 0; - filters_arr = kmalloc_array(nr_filters, sizeof(*filters_arr), - GFP_KERNEL | __GFP_NOWARN); + filters_arr = kmalloc_objs(*filters_arr, nr_filters, + GFP_KERNEL | __GFP_NOWARN); if (!filters_arr) return -ENOMEM; filters->filters_arr = filters_arr; @@ -851,8 +849,7 @@ static struct damon_sysfs_watermarks *damon_sysfs_watermarks_alloc( enum damos_wmark_metric metric, unsigned long interval_us, unsigned long high, unsigned long mid, unsigned long low) { - struct damon_sysfs_watermarks *watermarks = kmalloc( - sizeof(*watermarks), GFP_KERNEL); + struct damon_sysfs_watermarks *watermarks = kmalloc_obj(*watermarks); if (!watermarks) return NULL; @@ -1045,7 +1042,7 @@ struct damos_sysfs_quota_goal { static struct damos_sysfs_quota_goal *damos_sysfs_quota_goal_alloc(void) { - return kzalloc(sizeof(struct damos_sysfs_quota_goal), GFP_KERNEL); + return kzalloc_obj(struct damos_sysfs_quota_goal); } struct damos_sysfs_qgoal_metric_name { @@ -1263,7 +1260,7 @@ struct damos_sysfs_quota_goals { static struct damos_sysfs_quota_goals *damos_sysfs_quota_goals_alloc(void) { - return kzalloc(sizeof(struct damos_sysfs_quota_goals), GFP_KERNEL); + return kzalloc_obj(struct damos_sysfs_quota_goals); } static void damos_sysfs_quota_goals_rm_dirs( @@ -1289,8 +1286,8 @@ static int damos_sysfs_quota_goals_add_dirs( if (!nr_goals) return 0; - goals_arr = kmalloc_array(nr_goals, sizeof(*goals_arr), - GFP_KERNEL | __GFP_NOWARN); + goals_arr = kmalloc_objs(*goals_arr, nr_goals, + GFP_KERNEL | __GFP_NOWARN); if (!goals_arr) return -ENOMEM; goals->goals_arr = goals_arr; @@ -1383,8 +1380,7 @@ struct damon_sysfs_weights { static struct damon_sysfs_weights *damon_sysfs_weights_alloc(unsigned int sz, unsigned int nr_accesses, unsigned int age) { - struct damon_sysfs_weights *weights = kmalloc(sizeof(*weights), - GFP_KERNEL); + struct damon_sysfs_weights *weights = kmalloc_obj(*weights); if (!weights) return NULL; @@ -1496,7 +1492,7 @@ struct damon_sysfs_quotas { static struct damon_sysfs_quotas *damon_sysfs_quotas_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_quotas), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_quotas); } static int damon_sysfs_quotas_add_dirs(struct damon_sysfs_quotas *quotas) @@ -1660,8 +1656,7 @@ struct damon_sysfs_access_pattern { static struct damon_sysfs_access_pattern *damon_sysfs_access_pattern_alloc(void) { - struct damon_sysfs_access_pattern *access_pattern = - kmalloc(sizeof(*access_pattern), GFP_KERNEL); + struct damon_sysfs_access_pattern *access_pattern = kmalloc_obj(*access_pattern); if (!access_pattern) return NULL; @@ -1757,7 +1752,7 @@ struct damos_sysfs_dest { static struct damos_sysfs_dest *damos_sysfs_dest_alloc(void) { - return kzalloc(sizeof(struct damos_sysfs_dest), GFP_KERNEL); + return kzalloc_obj(struct damos_sysfs_dest); } static ssize_t id_show( @@ -1837,7 +1832,7 @@ struct damos_sysfs_dests { static struct damos_sysfs_dests * damos_sysfs_dests_alloc(void) { - return kzalloc(sizeof(struct damos_sysfs_dests), GFP_KERNEL); + return kzalloc_obj(struct damos_sysfs_dests); } static void damos_sysfs_dests_rm_dirs( @@ -1863,8 +1858,8 @@ static int damos_sysfs_dests_add_dirs( if (!nr_dests) return 0; - dests_arr = kmalloc_array(nr_dests, sizeof(*dests_arr), - GFP_KERNEL | __GFP_NOWARN); + dests_arr = kmalloc_objs(*dests_arr, nr_dests, + GFP_KERNEL | __GFP_NOWARN); if (!dests_arr) return -ENOMEM; dests->dests_arr = dests_arr; @@ -2014,8 +2009,7 @@ static struct damos_sysfs_action_name damos_sysfs_action_names[] = { static struct damon_sysfs_scheme *damon_sysfs_scheme_alloc( enum damos_action action, unsigned long apply_interval_us) { - struct damon_sysfs_scheme *scheme = kmalloc(sizeof(*scheme), - GFP_KERNEL); + struct damon_sysfs_scheme *scheme = kmalloc_obj(*scheme); if (!scheme) return NULL; @@ -2376,7 +2370,7 @@ static const struct kobj_type damon_sysfs_scheme_ktype = { struct damon_sysfs_schemes *damon_sysfs_schemes_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_schemes), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_schemes); } void damon_sysfs_schemes_rm_dirs(struct damon_sysfs_schemes *schemes) @@ -2403,8 +2397,8 @@ static int damon_sysfs_schemes_add_dirs(struct damon_sysfs_schemes *schemes, if (!nr_schemes) return 0; - schemes_arr = kmalloc_array(nr_schemes, sizeof(*schemes_arr), - GFP_KERNEL | __GFP_NOWARN); + schemes_arr = kmalloc_objs(*schemes_arr, nr_schemes, + GFP_KERNEL | __GFP_NOWARN); if (!schemes_arr) return -ENOMEM; schemes->schemes_arr = schemes_arr; @@ -2683,12 +2677,10 @@ static int damos_sysfs_add_migrate_dest(struct damos *scheme, struct damos_migrate_dests *dests = &scheme->migrate_dests; int i; - dests->node_id_arr = kmalloc_array(sysfs_dests->nr, - sizeof(*dests->node_id_arr), GFP_KERNEL); + dests->node_id_arr = kmalloc_objs(*dests->node_id_arr, sysfs_dests->nr); if (!dests->node_id_arr) return -ENOMEM; - dests->weight_arr = kmalloc_array(sysfs_dests->nr, - sizeof(*dests->weight_arr), GFP_KERNEL); + dests->weight_arr = kmalloc_objs(*dests->weight_arr, sysfs_dests->nr); if (!dests->weight_arr) /* ->node_id_arr will be freed by scheme destruction */ return -ENOMEM; diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index b7f66196bec4..576d1ddd736b 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -22,7 +22,7 @@ struct damon_sysfs_region { static struct damon_sysfs_region *damon_sysfs_region_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_region), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_region); } static ssize_t start_show(struct kobject *kobj, struct kobj_attribute *attr, @@ -99,7 +99,7 @@ struct damon_sysfs_regions { static struct damon_sysfs_regions *damon_sysfs_regions_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_regions), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_regions); } static void damon_sysfs_regions_rm_dirs(struct damon_sysfs_regions *regions) @@ -124,8 +124,8 @@ static int damon_sysfs_regions_add_dirs(struct damon_sysfs_regions *regions, if (!nr_regions) return 0; - regions_arr = kmalloc_array(nr_regions, sizeof(*regions_arr), - GFP_KERNEL | __GFP_NOWARN); + regions_arr = kmalloc_objs(*regions_arr, nr_regions, + GFP_KERNEL | __GFP_NOWARN); if (!regions_arr) return -ENOMEM; regions->regions_arr = regions_arr; @@ -217,7 +217,7 @@ struct damon_sysfs_target { static struct damon_sysfs_target *damon_sysfs_target_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_target), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_target); } static int damon_sysfs_target_add_dirs(struct damon_sysfs_target *target) @@ -323,7 +323,7 @@ struct damon_sysfs_targets { static struct damon_sysfs_targets *damon_sysfs_targets_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_targets), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_targets); } static void damon_sysfs_targets_rm_dirs(struct damon_sysfs_targets *targets) @@ -350,8 +350,8 @@ static int damon_sysfs_targets_add_dirs(struct damon_sysfs_targets *targets, if (!nr_targets) return 0; - targets_arr = kmalloc_array(nr_targets, sizeof(*targets_arr), - GFP_KERNEL | __GFP_NOWARN); + targets_arr = kmalloc_objs(*targets_arr, nr_targets, + GFP_KERNEL | __GFP_NOWARN); if (!targets_arr) return -ENOMEM; targets->targets_arr = targets_arr; @@ -452,8 +452,7 @@ static struct damon_sysfs_intervals_goal *damon_sysfs_intervals_goal_alloc( unsigned long access_bp, unsigned long aggrs, unsigned long min_sample_us, unsigned long max_sample_us) { - struct damon_sysfs_intervals_goal *goal = kmalloc(sizeof(*goal), - GFP_KERNEL); + struct damon_sysfs_intervals_goal *goal = kmalloc_obj(*goal); if (!goal) return NULL; @@ -610,8 +609,7 @@ static struct damon_sysfs_intervals *damon_sysfs_intervals_alloc( unsigned long sample_us, unsigned long aggr_us, unsigned long update_us) { - struct damon_sysfs_intervals *intervals = kmalloc(sizeof(*intervals), - GFP_KERNEL); + struct damon_sysfs_intervals *intervals = kmalloc_obj(*intervals); if (!intervals) return NULL; @@ -761,7 +759,7 @@ struct damon_sysfs_attrs { static struct damon_sysfs_attrs *damon_sysfs_attrs_alloc(void) { - struct damon_sysfs_attrs *attrs = kmalloc(sizeof(*attrs), GFP_KERNEL); + struct damon_sysfs_attrs *attrs = kmalloc_obj(*attrs); if (!attrs) return NULL; @@ -873,8 +871,7 @@ struct damon_sysfs_context { static struct damon_sysfs_context *damon_sysfs_context_alloc( enum damon_ops_id ops_id) { - struct damon_sysfs_context *context = kmalloc(sizeof(*context), - GFP_KERNEL); + struct damon_sysfs_context *context = kmalloc_obj(*context); if (!context) return NULL; @@ -1096,7 +1093,7 @@ struct damon_sysfs_contexts { static struct damon_sysfs_contexts *damon_sysfs_contexts_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_contexts), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_contexts); } static void damon_sysfs_contexts_rm_dirs(struct damon_sysfs_contexts *contexts) @@ -1123,8 +1120,8 @@ static int damon_sysfs_contexts_add_dirs(struct damon_sysfs_contexts *contexts, if (!nr_contexts) return 0; - contexts_arr = kmalloc_array(nr_contexts, sizeof(*contexts_arr), - GFP_KERNEL | __GFP_NOWARN); + contexts_arr = kmalloc_objs(*contexts_arr, nr_contexts, + GFP_KERNEL | __GFP_NOWARN); if (!contexts_arr) return -ENOMEM; contexts->contexts_arr = contexts_arr; @@ -1223,7 +1220,7 @@ struct damon_sysfs_kdamond { static struct damon_sysfs_kdamond *damon_sysfs_kdamond_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_kdamond), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_kdamond); } static int damon_sysfs_kdamond_add_dirs(struct damon_sysfs_kdamond *kdamond) @@ -1367,8 +1364,9 @@ static int damon_sysfs_set_regions(struct damon_target *t, struct damon_sysfs_regions *sysfs_regions, unsigned long min_region_sz) { - struct damon_addr_range *ranges = kmalloc_array(sysfs_regions->nr, - sizeof(*ranges), GFP_KERNEL | __GFP_NOWARN); + struct damon_addr_range *ranges = kmalloc_objs(*ranges, + sysfs_regions->nr, + GFP_KERNEL | __GFP_NOWARN); int i, err = -EINVAL; if (!ranges) @@ -1643,8 +1641,7 @@ static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond) damon_destroy_ctx(kdamond->damon_ctx); kdamond->damon_ctx = NULL; - repeat_call_control = kmalloc(sizeof(*repeat_call_control), - GFP_KERNEL); + repeat_call_control = kmalloc_obj(*repeat_call_control); if (!repeat_call_control) return -ENOMEM; @@ -1897,7 +1894,7 @@ struct damon_sysfs_kdamonds { static struct damon_sysfs_kdamonds *damon_sysfs_kdamonds_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_kdamonds), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_kdamonds); } static void damon_sysfs_kdamonds_rm_dirs(struct damon_sysfs_kdamonds *kdamonds) @@ -1940,8 +1937,8 @@ static int damon_sysfs_kdamonds_add_dirs(struct damon_sysfs_kdamonds *kdamonds, if (!nr_kdamonds) return 0; - kdamonds_arr = kmalloc_array(nr_kdamonds, sizeof(*kdamonds_arr), - GFP_KERNEL | __GFP_NOWARN); + kdamonds_arr = kmalloc_objs(*kdamonds_arr, nr_kdamonds, + GFP_KERNEL | __GFP_NOWARN); if (!kdamonds_arr) return -ENOMEM; kdamonds->kdamonds_arr = kdamonds_arr; @@ -2038,7 +2035,7 @@ struct damon_sysfs_ui_dir { static struct damon_sysfs_ui_dir *damon_sysfs_ui_dir_alloc(void) { - return kzalloc(sizeof(struct damon_sysfs_ui_dir), GFP_KERNEL); + return kzalloc_obj(struct damon_sysfs_ui_dir); } static int damon_sysfs_ui_dir_add_dirs(struct damon_sysfs_ui_dir *ui_dir) diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h index 92ea25e2dc9e..596f33ec2d81 100644 --- a/mm/damon/tests/core-kunit.h +++ b/mm/damon/tests/core-kunit.h @@ -725,12 +725,10 @@ static int damos_test_help_dests_setup(struct damos_migrate_dests *dests, { size_t i; - dests->node_id_arr = kmalloc_array(nr_dests, - sizeof(*dests->node_id_arr), GFP_KERNEL); + dests->node_id_arr = kmalloc_objs(*dests->node_id_arr, nr_dests); if (!dests->node_id_arr) return -ENOMEM; - dests->weight_arr = kmalloc_array(nr_dests, - sizeof(*dests->weight_arr), GFP_KERNEL); + dests->weight_arr = kmalloc_objs(*dests->weight_arr, nr_dests); if (!dests->weight_arr) { kfree(dests->node_id_arr); dests->node_id_arr = NULL; diff --git a/mm/damon/tests/sysfs-kunit.h b/mm/damon/tests/sysfs-kunit.h index 0c665ed255a3..f9ec5e795b34 100644 --- a/mm/damon/tests/sysfs-kunit.h +++ b/mm/damon/tests/sysfs-kunit.h @@ -48,8 +48,8 @@ static void damon_sysfs_test_add_targets(struct kunit *test) if (!sysfs_targets) kunit_skip(test, "sysfs_targets alloc fail"); sysfs_targets->nr = 1; - sysfs_targets->targets_arr = kmalloc_array(1, - sizeof(*sysfs_targets->targets_arr), GFP_KERNEL); + sysfs_targets->targets_arr = kmalloc_objs(*sysfs_targets->targets_arr, + 1); if (!sysfs_targets->targets_arr) { kfree(sysfs_targets); kunit_skip(test, "targets_arr alloc fail"); diff --git a/mm/damon/vaddr.c b/mm/damon/vaddr.c index 83ab3d8c3792..729b7ffd3565 100644 --- a/mm/damon/vaddr.c +++ b/mm/damon/vaddr.c @@ -821,8 +821,7 @@ static unsigned long damos_va_migrate(struct damon_target *target, use_target_nid = dests->nr_dests == 0; nr_dests = use_target_nid ? 1 : dests->nr_dests; priv.scheme = s; - priv.migration_lists = kmalloc_array(nr_dests, - sizeof(*priv.migration_lists), GFP_KERNEL); + priv.migration_lists = kmalloc_objs(*priv.migration_lists, nr_dests); if (!priv.migration_lists) return 0; diff --git a/mm/dmapool_test.c b/mm/dmapool_test.c index e8172d708308..d829d99aa194 100644 --- a/mm/dmapool_test.c +++ b/mm/dmapool_test.c @@ -67,7 +67,7 @@ static int dmapool_test_block(const struct dmapool_parms *parms) struct dma_pool_pair *p; int i, ret; - p = kcalloc(blocks, sizeof(*p), GFP_KERNEL); + p = kzalloc_objs(*p, blocks); if (!p) return -ENOMEM; diff --git a/mm/filemap.c b/mm/filemap.c index ebd75684cb0a..406cef06b684 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1379,14 +1379,16 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, #ifdef CONFIG_MIGRATION /** - * migration_entry_wait_on_locked - Wait for a migration entry to be removed - * @entry: migration swap entry. + * softleaf_entry_wait_on_locked - Wait for a migration entry or + * device_private entry to be removed. + * @entry: migration or device_private swap entry. * @ptl: already locked ptl. This function will drop the lock. * - * Wait for a migration entry referencing the given page to be removed. This is + * Wait for a migration entry referencing the given page, or device_private + * entry referencing a dvice_private page to be unlocked. This is * equivalent to folio_put_wait_locked(folio, TASK_UNINTERRUPTIBLE) except * this can be called without taking a reference on the page. Instead this - * should be called while holding the ptl for the migration entry referencing + * should be called while holding the ptl for @entry referencing * the page. * * Returns after unlocking the ptl. @@ -1394,7 +1396,7 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, * This follows the same logic as folio_wait_bit_common() so see the comments * there. */ -void migration_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) +void softleaf_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) __releases(ptl) { struct wait_page_queue wait_page; @@ -1428,6 +1430,9 @@ void migration_entry_wait_on_locked(softleaf_t entry, spinlock_t *ptl) * If a migration entry exists for the page the migration path must hold * a valid reference to the page, and it must take the ptl to remove the * migration entry. So the page is valid until the ptl is dropped. + * Similarly any path attempting to drop the last reference to a + * device-private page needs to grab the ptl to remove the device-private + * entry. */ spin_unlock(ptl); @@ -4012,7 +4017,7 @@ int generic_file_readonly_mmap(struct file *file, struct vm_area_struct *vma) int generic_file_readonly_mmap_prepare(struct vm_area_desc *desc) { - if (is_shared_maywrite(desc->vm_flags)) + if (is_shared_maywrite(&desc->vma_flags)) return -EINVAL; return generic_file_mmap_prepare(desc); } diff --git a/mm/hmm.c b/mm/hmm.c index 4ec74c18bef6..f6c4ddff4bd6 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -723,8 +723,8 @@ int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map, use_iova = dma_iova_try_alloc(dev, &map->state, 0, nr_entries * PAGE_SIZE); if (!use_iova && dma_need_unmap(dev)) { - map->dma_list = kvcalloc(nr_entries, sizeof(*map->dma_list), - GFP_KERNEL | __GFP_NOWARN); + map->dma_list = kvzalloc_objs(*map->dma_list, nr_entries, + GFP_KERNEL | __GFP_NOWARN); if (!map->dma_list) goto err_dma; } diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 0d487649e4de..b298cba853ab 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -94,6 +94,9 @@ static inline bool file_thp_enabled(struct vm_area_struct *vma) inode = file_inode(vma->vm_file); + if (IS_ANON_FILE(inode)) + return false; + return !inode_is_open_for_write(inode) && S_ISREG(inode->i_mode); } @@ -718,7 +721,7 @@ static struct thpsize *thpsize_create(int order, struct kobject *parent) struct thpsize *thpsize; int ret = -ENOMEM; - thpsize = kzalloc(sizeof(*thpsize), GFP_KERNEL); + thpsize = kzalloc_obj(*thpsize); if (!thpsize) goto err; @@ -2794,7 +2797,8 @@ int move_pages_huge_pmd(struct mm_struct *mm, pmd_t *dst_pmd, pmd_t *src_pmd, pm _dst_pmd = pmd_mkwrite(pmd_mkdirty(_dst_pmd), dst_vma); } else { src_pmdval = pmdp_huge_clear_flush(src_vma, src_addr, src_pmd); - _dst_pmd = folio_mk_pmd(src_folio, dst_vma->vm_page_prot); + _dst_pmd = move_soft_dirty_pmd(src_pmdval); + _dst_pmd = clear_uffd_wp_pmd(_dst_pmd); } set_pmd_at(mm, dst_addr, dst_pmd, _dst_pmd); @@ -3628,6 +3632,7 @@ static int __split_unmapped_folio(struct folio *folio, int new_order, const bool is_anon = folio_test_anon(folio); int old_order = folio_order(folio); int start_order = split_type == SPLIT_TYPE_UNIFORM ? new_order : old_order - 1; + struct folio *old_folio = folio; int split_order; /* @@ -3648,12 +3653,16 @@ static int __split_unmapped_folio(struct folio *folio, int new_order, * uniform split has xas_split_alloc() called before * irq is disabled to allocate enough memory, whereas * non-uniform split can handle ENOMEM. + * Use the to-be-split folio, so that a parallel + * folio_try_get() waits on it until xarray is updated + * with after-split folios and the original one is + * unfrozen. */ - if (split_type == SPLIT_TYPE_UNIFORM) - xas_split(xas, folio, old_order); - else { + if (split_type == SPLIT_TYPE_UNIFORM) { + xas_split(xas, old_folio, old_order); + } else { xas_set_order(xas, folio->index, split_order); - xas_try_split(xas, folio, old_order); + xas_try_split(xas, old_folio, old_order); if (xas_error(xas)) return xas_error(xas); } diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 90182724d4cf..327eaa4074d3 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -154,7 +154,7 @@ struct hugepage_subpool *hugepage_new_subpool(struct hstate *h, long max_hpages, { struct hugepage_subpool *spool; - spool = kzalloc(sizeof(*spool), GFP_KERNEL); + spool = kzalloc_obj(*spool); if (!spool) return NULL; @@ -429,7 +429,7 @@ int hugetlb_vma_lock_alloc(struct vm_area_struct *vma) if (vma->vm_private_data) return -EINVAL; - vma_lock = kmalloc(sizeof(*vma_lock), GFP_KERNEL); + vma_lock = kmalloc_obj(*vma_lock); if (!vma_lock) { /* * If we can not allocate structure, then vma can not @@ -687,7 +687,7 @@ static int allocate_file_region_entries(struct resv_map *resv, spin_unlock(&resv->lock); for (i = 0; i < to_allocate; i++) { - trg = kmalloc(sizeof(*trg), GFP_KERNEL); + trg = kmalloc_obj(*trg); if (!trg) goto out_of_memory; list_add(&trg->link, &allocated_regions); @@ -891,7 +891,7 @@ static long region_del(struct resv_map *resv, long f, long t) if (!nrg) { spin_unlock(&resv->lock); - nrg = kmalloc(sizeof(*nrg), GFP_KERNEL); + nrg = kmalloc_obj(*nrg); if (!nrg) return -ENOMEM; goto retry; @@ -1105,8 +1105,8 @@ resv_map_set_hugetlb_cgroup_uncharge_info(struct resv_map *resv_map, struct resv_map *resv_map_alloc(void) { - struct resv_map *resv_map = kmalloc(sizeof(*resv_map), GFP_KERNEL); - struct file_region *rg = kmalloc(sizeof(*rg), GFP_KERNEL); + struct resv_map *resv_map = kmalloc_obj(*resv_map); + struct file_region *rg = kmalloc_obj(*rg); if (!resv_map || !rg) { kfree(resv_map); @@ -1193,16 +1193,16 @@ static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags) static void set_vma_desc_resv_map(struct vm_area_desc *desc, struct resv_map *map) { - VM_WARN_ON_ONCE(!is_vm_hugetlb_flags(desc->vm_flags)); - VM_WARN_ON_ONCE(desc->vm_flags & VM_MAYSHARE); + VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags)); + VM_WARN_ON_ONCE(vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)); desc->private_data = map; } static void set_vma_desc_resv_flags(struct vm_area_desc *desc, unsigned long flags) { - VM_WARN_ON_ONCE(!is_vm_hugetlb_flags(desc->vm_flags)); - VM_WARN_ON_ONCE(desc->vm_flags & VM_MAYSHARE); + VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags)); + VM_WARN_ON_ONCE(vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)); desc->private_data = (void *)((unsigned long)desc->private_data | flags); } @@ -1216,7 +1216,7 @@ static int is_vma_resv_set(struct vm_area_struct *vma, unsigned long flag) static bool is_vma_desc_resv_set(struct vm_area_desc *desc, unsigned long flag) { - VM_WARN_ON_ONCE(!is_vm_hugetlb_flags(desc->vm_flags)); + VM_WARN_ON_ONCE(!is_vma_hugetlb_flags(&desc->vma_flags)); return ((unsigned long)desc->private_data) & flag; } @@ -3101,7 +3101,7 @@ static __init void *alloc_bootmem(struct hstate *h, int nid, bool node_exact) * extract the actual node first. */ if (m) - listnode = early_pfn_to_nid(PHYS_PFN(virt_to_phys(m))); + listnode = early_pfn_to_nid(PHYS_PFN(__pa(m))); } if (m) { @@ -3160,7 +3160,7 @@ int __alloc_bootmem_huge_page(struct hstate *h, int nid) * The head struct page is used to get folio information by the HugeTLB * subsystem like zone id and node id. */ - memblock_reserved_mark_noinit(virt_to_phys((void *)m + PAGE_SIZE), + memblock_reserved_mark_noinit(__pa((void *)m + PAGE_SIZE), huge_page_size(h) - PAGE_SIZE); return 1; @@ -4190,8 +4190,7 @@ static int __init hugetlb_init(void) num_fault_mutexes = 1; #endif hugetlb_fault_mutex_table = - kmalloc_array(num_fault_mutexes, sizeof(struct mutex), - GFP_KERNEL); + kmalloc_objs(struct mutex, num_fault_mutexes); BUG_ON(!hugetlb_fault_mutex_table); for (i = 0; i < num_fault_mutexes; i++) @@ -6571,7 +6570,7 @@ long hugetlb_change_protection(struct vm_area_struct *vma, long hugetlb_reserve_pages(struct inode *inode, long from, long to, struct vm_area_desc *desc, - vm_flags_t vm_flags) + vma_flags_t vma_flags) { long chg = -1, add = -1, spool_resv, gbl_resv; struct hstate *h = hstate_inode(inode); @@ -6592,7 +6591,7 @@ long hugetlb_reserve_pages(struct inode *inode, * attempt will be made for VM_NORESERVE to allocate a page * without using reserves */ - if (vm_flags & VM_NORESERVE) + if (vma_flags_test(&vma_flags, VMA_NORESERVE_BIT)) return 0; /* @@ -6601,7 +6600,7 @@ long hugetlb_reserve_pages(struct inode *inode, * to reserve the full area even if read-only as mprotect() may be * called to make the mapping read-write. Assume !desc is a shm mapping */ - if (!desc || desc->vm_flags & VM_MAYSHARE) { + if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)) { /* * resv_map can not be NULL as hugetlb_reserve_pages is only * called for inodes for which resv_maps were created (see @@ -6635,7 +6634,7 @@ long hugetlb_reserve_pages(struct inode *inode, if (err < 0) goto out_err; - if (desc && !(desc->vm_flags & VM_MAYSHARE) && h_cg) { + if (desc && !vma_desc_test_flags(desc, VMA_MAYSHARE_BIT) && h_cg) { /* For private mappings, the hugetlb_cgroup uncharge info hangs * of the resv_map. */ @@ -6672,7 +6671,7 @@ long hugetlb_reserve_pages(struct inode *inode, * consumed reservations are stored in the map. Hence, nothing * else has to be done for private mappings here */ - if (!desc || desc->vm_flags & VM_MAYSHARE) { + if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)) { add = region_add(resv_map, from, to, regions_needed, h, h_cg); if (unlikely(add < 0)) { @@ -6736,7 +6735,7 @@ long hugetlb_reserve_pages(struct inode *inode, hugetlb_cgroup_uncharge_cgroup_rsvd(hstate_index(h), chg * pages_per_huge_page(h), h_cg); out_err: - if (!desc || desc->vm_flags & VM_MAYSHARE) + if (!desc || vma_desc_test_flags(desc, VMA_MAYSHARE_BIT)) /* Only call region_abort if the region_chg succeeded but the * region_add failed or didn't run. */ diff --git a/mm/hugetlb_cgroup.c b/mm/hugetlb_cgroup.c index 792d06538fa9..e0083de1ca82 100644 --- a/mm/hugetlb_cgroup.c +++ b/mm/hugetlb_cgroup.c @@ -139,8 +139,7 @@ hugetlb_cgroup_css_alloc(struct cgroup_subsys_state *parent_css) struct hugetlb_cgroup *h_cgroup; int node; - h_cgroup = kzalloc(struct_size(h_cgroup, nodeinfo, nr_node_ids), - GFP_KERNEL); + h_cgroup = kzalloc_flex(*h_cgroup, nodeinfo, nr_node_ids); if (!h_cgroup) return ERR_PTR(-ENOMEM); @@ -857,10 +856,10 @@ static void __init __hugetlb_cgroup_file_pre_init(void) int cft_count; cft_count = hugetlb_max_hstate * DFL_TMPL_SIZE + 1; /* add terminator */ - dfl_files = kcalloc(cft_count, sizeof(struct cftype), GFP_KERNEL); + dfl_files = kzalloc_objs(struct cftype, cft_count); BUG_ON(!dfl_files); cft_count = hugetlb_max_hstate * LEGACY_TMPL_SIZE + 1; /* add terminator */ - legacy_files = kcalloc(cft_count, sizeof(struct cftype), GFP_KERNEL); + legacy_files = kzalloc_objs(struct cftype, cft_count); BUG_ON(!legacy_files); } diff --git a/mm/internal.h b/mm/internal.h index aee1f72ef6ed..cb0af847d7d9 100644 --- a/mm/internal.h +++ b/mm/internal.h @@ -197,6 +197,9 @@ static inline void vma_close(struct vm_area_struct *vma) } } +/* unmap_vmas is in mm/memory.c */ +void unmap_vmas(struct mmu_gather *tlb, struct unmap_desc *unmap); + #ifdef CONFIG_MMU static inline void get_anon_vma(struct anon_vma *anon_vma) @@ -509,9 +512,8 @@ bool __folio_end_writeback(struct folio *folio); void deactivate_file_folio(struct folio *folio); void folio_activate(struct folio *folio); -void free_pgtables(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *start_vma, unsigned long floor, - unsigned long ceiling, bool mm_wr_locked); +void free_pgtables(struct mmu_gather *tlb, struct unmap_desc *desc); + void pmd_install(struct mm_struct *mm, pmd_t *pmd, pgtable_t *pte); struct zap_details; @@ -809,8 +811,7 @@ static inline void clear_zone_contiguous(struct zone *zone) extern int __isolate_free_page(struct page *page, unsigned int order); extern void __putback_isolated_page(struct page *page, unsigned int order, int mt); -extern void memblock_free_pages(struct page *page, unsigned long pfn, - unsigned int order); +extern void memblock_free_pages(unsigned long pfn, unsigned int order); extern void __free_pages_core(struct page *page, unsigned int order, enum meminit_context context); @@ -1045,7 +1046,7 @@ extern long populate_vma_page_range(struct vm_area_struct *vma, unsigned long start, unsigned long end, int *locked); extern long faultin_page_range(struct mm_struct *mm, unsigned long start, unsigned long end, bool write, int *locked); -bool mlock_future_ok(const struct mm_struct *mm, vm_flags_t vm_flags, +bool mlock_future_ok(const struct mm_struct *mm, bool is_vma_locked, unsigned long bytes); /* diff --git a/mm/kasan/kasan_test_c.c b/mm/kasan/kasan_test_c.c index b4d157962121..32d06cbf6a31 100644 --- a/mm/kasan/kasan_test_c.c +++ b/mm/kasan/kasan_test_c.c @@ -511,7 +511,7 @@ static void kmalloc_oob_16(struct kunit *test) ptr1 = RELOC_HIDE(kmalloc(sizeof(*ptr1) - 3, GFP_KERNEL), 0); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); - ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); + ptr2 = kmalloc_obj(*ptr2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); OPTIMIZER_HIDE_VAR(ptr1); @@ -529,10 +529,10 @@ static void kmalloc_uaf_16(struct kunit *test) KASAN_TEST_NEEDS_CHECKED_MEMINTRINSICS(test); - ptr1 = kmalloc(sizeof(*ptr1), GFP_KERNEL); + ptr1 = kmalloc_obj(*ptr1); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr1); - ptr2 = kmalloc(sizeof(*ptr2), GFP_KERNEL); + ptr2 = kmalloc_obj(*ptr2); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2); kfree(ptr2); @@ -859,7 +859,7 @@ static void kasan_atomics(struct kunit *test) */ a1 = kzalloc(48, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a1); - a2 = kzalloc(sizeof(atomic_long_t), GFP_KERNEL); + a2 = kzalloc_obj(atomic_long_t); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a2); /* Use atomics to access the redzone. */ @@ -954,7 +954,7 @@ static void rcu_uaf(struct kunit *test) { struct kasan_rcu_info *ptr; - ptr = kmalloc(sizeof(struct kasan_rcu_info), GFP_KERNEL); + ptr = kmalloc_obj(struct kasan_rcu_info); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr); global_rcu_ptr = rcu_dereference_protected( @@ -978,7 +978,7 @@ static void workqueue_uaf(struct kunit *test) workqueue = create_workqueue("kasan_workqueue_test"); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, workqueue); - work = kmalloc(sizeof(struct work_struct), GFP_KERNEL); + work = kmalloc_obj(struct work_struct); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, work); INIT_WORK(work, workqueue_uaf_work); diff --git a/mm/kfence/core.c b/mm/kfence/core.c index b4ea3262c925..7393957f9a20 100644 --- a/mm/kfence/core.c +++ b/mm/kfence/core.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -916,6 +917,20 @@ void __init kfence_alloc_pool_and_metadata(void) if (!kfence_sample_interval) return; + /* + * If KASAN hardware tags are enabled, disable KFENCE, because it + * does not support MTE yet. + */ + if (kasan_hw_tags_enabled()) { + pr_info("disabled as KASAN HW tags are enabled\n"); + if (__kfence_pool) { + memblock_free(__kfence_pool, KFENCE_POOL_SIZE); + __kfence_pool = NULL; + } + kfence_sample_interval = 0; + return; + } + /* * If the pool has already been initialized by arch, there is no need to * re-allocate the memory pool. @@ -989,14 +1004,14 @@ static int kfence_init_late(void) #ifdef CONFIG_CONTIG_ALLOC struct page *pages; - pages = alloc_contig_pages(nr_pages_pool, GFP_KERNEL, first_online_node, - NULL); + pages = alloc_contig_pages(nr_pages_pool, GFP_KERNEL | __GFP_SKIP_KASAN, + first_online_node, NULL); if (!pages) return -ENOMEM; __kfence_pool = page_to_virt(pages); - pages = alloc_contig_pages(nr_pages_meta, GFP_KERNEL, first_online_node, - NULL); + pages = alloc_contig_pages(nr_pages_meta, GFP_KERNEL | __GFP_SKIP_KASAN, + first_online_node, NULL); if (pages) kfence_metadata_init = page_to_virt(pages); #else @@ -1006,11 +1021,13 @@ static int kfence_init_late(void) return -EINVAL; } - __kfence_pool = alloc_pages_exact(KFENCE_POOL_SIZE, GFP_KERNEL); + __kfence_pool = alloc_pages_exact(KFENCE_POOL_SIZE, + GFP_KERNEL | __GFP_SKIP_KASAN); if (!__kfence_pool) return -ENOMEM; - kfence_metadata_init = alloc_pages_exact(KFENCE_METADATA_SIZE, GFP_KERNEL); + kfence_metadata_init = alloc_pages_exact(KFENCE_METADATA_SIZE, + GFP_KERNEL | __GFP_SKIP_KASAN); #endif if (!kfence_metadata_init) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index ea7a3ad2a2c2..1dd3cfca610d 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -1732,7 +1732,7 @@ static bool file_backed_vma_is_retractable(struct vm_area_struct *vma) * obtained on guard region installation after the flag is set, so this * check being performed under this lock excludes races. */ - if (vma_flag_test_atomic(vma, VMA_MAYBE_GUARD_BIT)) + if (vma_test_atomic_flag(vma, VMA_MAYBE_GUARD_BIT)) return false; return true; @@ -2769,7 +2769,7 @@ int madvise_collapse(struct vm_area_struct *vma, unsigned long start, if (!thp_vma_allowable_order(vma, vma->vm_flags, TVA_FORCED_COLLAPSE, PMD_ORDER)) return -EINVAL; - cc = kmalloc(sizeof(*cc), GFP_KERNEL); + cc = kmalloc_obj(*cc); if (!cc) return -ENOMEM; cc->is_khugepaged = false; diff --git a/mm/kmemleak.c b/mm/kmemleak.c index fe33f2edfe07..d79acf5c5100 100644 --- a/mm/kmemleak.c +++ b/mm/kmemleak.c @@ -837,13 +837,12 @@ static void delete_object_full(unsigned long ptr, unsigned int objflags) struct kmemleak_object *object; object = find_and_remove_object(ptr, 0, objflags); - if (!object) { -#ifdef DEBUG - kmemleak_warn("Freeing unknown object at 0x%08lx\n", - ptr); -#endif + if (!object) + /* + * kmalloc_nolock() -> kfree() calls kmemleak_free() + * without kmemleak_alloc(). + */ return; - } __delete_object(object); } @@ -926,13 +925,12 @@ static void paint_ptr(unsigned long ptr, int color, unsigned int objflags) struct kmemleak_object *object; object = __find_and_get_object(ptr, 0, objflags); - if (!object) { - kmemleak_warn("Trying to color unknown object at 0x%08lx as %s\n", - ptr, - (color == KMEMLEAK_GREY) ? "Grey" : - (color == KMEMLEAK_BLACK) ? "Black" : "Unknown"); + if (!object) + /* + * kmalloc_nolock() -> kfree_rcu() calls kmemleak_ignore() + * without kmemleak_alloc(). + */ return; - } paint_it(object, color); put_object(object); } diff --git a/mm/kmsan/kmsan_test.c b/mm/kmsan/kmsan_test.c index 7a7fbaff7350..31f47cc4dab4 100644 --- a/mm/kmsan/kmsan_test.c +++ b/mm/kmsan/kmsan_test.c @@ -168,7 +168,7 @@ static void test_uninit_kmalloc(struct kunit *test) int *ptr; kunit_info(test, "uninitialized kmalloc test (UMR report)\n"); - ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kmalloc_obj(*ptr); USE(*ptr); KUNIT_EXPECT_TRUE(test, report_matches(&expect)); } @@ -182,7 +182,7 @@ static void test_init_kmalloc(struct kunit *test) int *ptr; kunit_info(test, "initialized kmalloc test (no reports)\n"); - ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kmalloc_obj(*ptr); memset(ptr, 0, sizeof(*ptr)); USE(*ptr); KUNIT_EXPECT_TRUE(test, report_matches(&expect)); @@ -195,7 +195,7 @@ static void test_init_kzalloc(struct kunit *test) int *ptr; kunit_info(test, "initialized kzalloc test (no reports)\n"); - ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); + ptr = kzalloc_obj(*ptr); USE(*ptr); KUNIT_EXPECT_TRUE(test, report_matches(&expect)); } @@ -322,7 +322,7 @@ static void test_init_kmsan_vmap_vunmap(struct kunit *test) kunit_info(test, "pages initialized via vmap (no reports)\n"); - pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL); + pages = kmalloc_objs(*pages, npages); for (int i = 0; i < npages; i++) pages[i] = alloc_page(GFP_KERNEL); vbuf = vmap(pages, npages, VM_MAP, PAGE_KERNEL); diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c index 9e1c5f2b7a41..8fde939784a7 100644 --- a/mm/kmsan/shadow.c +++ b/mm/kmsan/shadow.c @@ -230,8 +230,8 @@ int kmsan_vmap_pages_range_noflush(unsigned long start, unsigned long end, return 0; nr = (end - start) / PAGE_SIZE; - s_pages = kcalloc(nr, sizeof(*s_pages), gfp_mask); - o_pages = kcalloc(nr, sizeof(*o_pages), gfp_mask); + s_pages = kzalloc_objs(*s_pages, nr, gfp_mask); + o_pages = kzalloc_objs(*o_pages, nr, gfp_mask); if (!s_pages || !o_pages) { err = -ENOMEM; goto ret; diff --git a/mm/ksm.c b/mm/ksm.c index 2d89a7c8b4eb..bda71ae609ff 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -3586,8 +3586,7 @@ static ssize_t merge_across_nodes_store(struct kobject *kobj, * Allocate stable and unstable together: * MAXSMP NODES_SHIFT 10 will use 16kB. */ - buf = kcalloc(nr_node_ids + nr_node_ids, sizeof(*buf), - GFP_KERNEL); + buf = kzalloc_objs(*buf, nr_node_ids + nr_node_ids); /* Let us assume that RB_ROOT is NULL is zero */ if (!buf) err = -ENOMEM; diff --git a/mm/list_lru.c b/mm/list_lru.c index 13b9f66d950e..26463ae29c64 100644 --- a/mm/list_lru.c +++ b/mm/list_lru.c @@ -407,7 +407,7 @@ static struct list_lru_memcg *memcg_init_list_lru_one(struct list_lru *lru, gfp_ int nid; struct list_lru_memcg *mlru; - mlru = kmalloc(struct_size(mlru, node, nr_node_ids), gfp); + mlru = kmalloc_flex(*mlru, node, nr_node_ids, gfp); if (!mlru) return NULL; @@ -585,7 +585,7 @@ int __list_lru_init(struct list_lru *lru, bool memcg_aware, struct shrinker *shr memcg_aware = false; #endif - lru->node = kcalloc(nr_node_ids, sizeof(*lru->node), GFP_KERNEL); + lru->node = kzalloc_objs(*lru->node, nr_node_ids); if (!lru->node) return -ENOMEM; diff --git a/mm/madvise.c b/mm/madvise.c index 1f3040688f04..dbb69400786d 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -91,7 +91,7 @@ struct anon_vma_name *anon_vma_name_alloc(const char *name) /* Add 1 for NUL terminator at the end of the anon_name->name */ count = strlen(name) + 1; - anon_name = kmalloc(struct_size(anon_name, name, count), GFP_KERNEL); + anon_name = kmalloc_flex(*anon_name, name, count); if (anon_name) { kref_init(&anon_name->kref); memcpy(anon_name->name, name, count); @@ -1140,7 +1140,7 @@ static long madvise_guard_install(struct madvise_behavior *madv_behavior) * acquire an mmap/VMA write lock to read it. All remaining readers may * or may not see the flag set, but we don't care. */ - vma_flag_set_atomic(vma, VMA_MAYBE_GUARD_BIT); + vma_set_atomic_flag(vma, VMA_MAYBE_GUARD_BIT); /* * If anonymous and we are establishing page tables the VMA ought to @@ -1389,7 +1389,7 @@ static int madvise_vma_behavior(struct madvise_behavior *madv_behavior) new_flags |= VM_DONTCOPY; break; case MADV_DOFORK: - if (new_flags & VM_IO) + if (new_flags & VM_SPECIAL) return -EINVAL; new_flags &= ~VM_DONTCOPY; break; diff --git a/mm/memblock.c b/mm/memblock.c index d9ede2cfa98f..b3ddfdec7a80 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -1772,7 +1772,7 @@ void __init memblock_free_late(phys_addr_t base, phys_addr_t size) end = PFN_DOWN(base + size); for (; cursor < end; cursor++) { - memblock_free_pages(pfn_to_page(cursor), cursor, 0); + memblock_free_pages(cursor, 0); totalram_pages_inc(); } } @@ -2217,7 +2217,7 @@ static void __init __free_pages_memory(unsigned long start, unsigned long end) while (start + (1UL << order) > end) order--; - memblock_free_pages(pfn_to_page(start), start, order); + memblock_free_pages(start, order); start += (1UL << order); } diff --git a/mm/memcontrol-v1.c b/mm/memcontrol-v1.c index c6078cd7f7e5..597af8a80163 100644 --- a/mm/memcontrol-v1.c +++ b/mm/memcontrol-v1.c @@ -783,7 +783,7 @@ static int __mem_cgroup_usage_register_event(struct mem_cgroup *memcg, size = thresholds->primary ? thresholds->primary->size + 1 : 1; /* Allocate memory for new array of thresholds */ - new = kmalloc(struct_size(new, entries, size), GFP_KERNEL_ACCOUNT); + new = kmalloc_flex(*new, entries, size, GFP_KERNEL_ACCOUNT); if (!new) { ret = -ENOMEM; goto unlock; @@ -946,7 +946,7 @@ static int mem_cgroup_oom_register_event(struct mem_cgroup *memcg, { struct mem_cgroup_eventfd_list *event; - event = kmalloc(sizeof(*event), GFP_KERNEL_ACCOUNT); + event = kmalloc_obj(*event, GFP_KERNEL_ACCOUNT); if (!event) return -ENOMEM; @@ -1109,7 +1109,7 @@ static ssize_t memcg_write_event_control(struct kernfs_open_file *of, CLASS(fd, cfile)(cfd); - event = kzalloc(sizeof(*event), GFP_KERNEL_ACCOUNT); + event = kzalloc_obj(*event, GFP_KERNEL_ACCOUNT); if (!event) return -ENOMEM; diff --git a/mm/memcontrol.c b/mm/memcontrol.c index b730233a481d..772bac21d155 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -192,7 +192,7 @@ static struct obj_cgroup *obj_cgroup_alloc(void) struct obj_cgroup *objcg; int ret; - objcg = kzalloc(sizeof(struct obj_cgroup), GFP_KERNEL); + objcg = kzalloc_obj(struct obj_cgroup); if (!objcg) return NULL; @@ -3086,7 +3086,7 @@ static void refill_obj_stock(struct obj_cgroup *objcg, unsigned int nr_bytes, if (!local_trylock(&obj_stock.lock)) { if (pgdat) - mod_objcg_mlstate(objcg, pgdat, idx, nr_bytes); + mod_objcg_mlstate(objcg, pgdat, idx, nr_acct); nr_pages = nr_bytes >> PAGE_SHIFT; nr_bytes = nr_bytes & (PAGE_SIZE - 1); atomic_add(nr_bytes, &objcg->nr_charged_bytes); @@ -3761,8 +3761,7 @@ static struct mem_cgroup *mem_cgroup_alloc(struct mem_cgroup *parent) goto fail; error = -ENOMEM; - memcg->vmstats = kzalloc(sizeof(struct memcg_vmstats), - GFP_KERNEL_ACCOUNT); + memcg->vmstats = kzalloc_obj(struct memcg_vmstats, GFP_KERNEL_ACCOUNT); if (!memcg->vmstats) goto fail; @@ -5649,9 +5648,21 @@ subsys_initcall(mem_cgroup_swap_init); #endif /* CONFIG_SWAP */ -bool mem_cgroup_node_allowed(struct mem_cgroup *memcg, int nid) +void mem_cgroup_node_filter_allowed(struct mem_cgroup *memcg, nodemask_t *mask) { - return memcg ? cpuset_node_allowed(memcg->css.cgroup, nid) : true; + nodemask_t allowed; + + if (!memcg) + return; + + /* + * Since this interface is intended for use by migration paths, and + * reclaim and migration are subject to race conditions such as changes + * in effective_mems and hot-unpluging of nodes, inaccurate allowed + * mask is acceptable. + */ + cpuset_nodes_allowed(memcg->css.cgroup, &allowed); + nodes_and(*mask, *mask, allowed); } void mem_cgroup_show_protected_memory(struct mem_cgroup *memcg) diff --git a/mm/memfd.c b/mm/memfd.c index 82a3f38aa30a..919c2a53eb96 100644 --- a/mm/memfd.c +++ b/mm/memfd.c @@ -86,7 +86,7 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx) gfp_mask &= ~(__GFP_HIGHMEM | __GFP_MOVABLE); idx >>= huge_page_order(h); - nr_resv = hugetlb_reserve_pages(inode, idx, idx + 1, NULL, 0); + nr_resv = hugetlb_reserve_pages(inode, idx, idx + 1, NULL, EMPTY_VMA_FLAGS); if (nr_resv < 0) return ERR_PTR(nr_resv); @@ -463,12 +463,12 @@ struct file *memfd_alloc_file(const char *name, unsigned int flags) int err = 0; if (flags & MFD_HUGETLB) { - file = hugetlb_file_setup(name, 0, VM_NORESERVE, + file = hugetlb_file_setup(name, 0, mk_vma_flags(VMA_NORESERVE_BIT), HUGETLB_ANONHUGE_INODE, (flags >> MFD_HUGE_SHIFT) & MFD_HUGE_MASK); } else { - file = shmem_file_setup(name, 0, VM_NORESERVE); + file = shmem_file_setup(name, 0, mk_vma_flags(VMA_NORESERVE_BIT)); } if (IS_ERR(file)) return file; diff --git a/mm/memfd_luo.c b/mm/memfd_luo.c index a34fccc23b6a..b8edb9f981d7 100644 --- a/mm/memfd_luo.c +++ b/mm/memfd_luo.c @@ -112,7 +112,7 @@ static int memfd_luo_preserve_folios(struct file *file, * up being smaller if there are higher order folios. */ max_folios = PAGE_ALIGN(size) / PAGE_SIZE; - folios = kvmalloc_array(max_folios, sizeof(*folios), GFP_KERNEL); + folios = kvmalloc_objs(*folios, max_folios); if (!folios) return -ENOMEM; @@ -146,19 +146,56 @@ static int memfd_luo_preserve_folios(struct file *file, for (i = 0; i < nr_folios; i++) { struct memfd_luo_folio_ser *pfolio = &folios_ser[i]; struct folio *folio = folios[i]; - unsigned int flags = 0; err = kho_preserve_folio(folio); if (err) goto err_unpreserve; - if (folio_test_dirty(folio)) - flags |= MEMFD_LUO_FOLIO_DIRTY; - if (folio_test_uptodate(folio)) - flags |= MEMFD_LUO_FOLIO_UPTODATE; + folio_lock(folio); + + /* + * A dirty folio is one which has been written to. A clean folio + * is its opposite. Since a clean folio does not carry user + * data, it can be freed by page reclaim under memory pressure. + * + * Saving the dirty flag at prepare() time doesn't work since it + * can change later. Saving it at freeze() also won't work + * because the dirty bit is normally synced at unmap and there + * might still be a mapping of the file at freeze(). + * + * To see why this is a problem, say a folio is clean at + * preserve, but gets dirtied later. The pfolio flags will mark + * it as clean. After retrieve, the next kernel might try to + * reclaim this folio under memory pressure, losing user data. + * + * Unconditionally mark it dirty to avoid this problem. This + * comes at the cost of making clean folios un-reclaimable after + * live update. + */ + folio_mark_dirty(folio); + + /* + * If the folio is not uptodate, it was fallocated but never + * used. Saving this flag at prepare() doesn't work since it + * might change later when someone uses the folio. + * + * Since we have taken the performance penalty of allocating, + * zeroing, and pinning all the folios in the holes, take a bit + * more and zero all non-uptodate folios too. + * + * NOTE: For someone looking to improve preserve performance, + * this is a good place to look. + */ + if (!folio_test_uptodate(folio)) { + folio_zero_range(folio, 0, folio_size(folio)); + flush_dcache_folio(folio); + folio_mark_uptodate(folio); + } + + folio_unlock(folio); pfolio->pfn = folio_pfn(folio); - pfolio->flags = flags; + pfolio->flags = MEMFD_LUO_FOLIO_DIRTY | MEMFD_LUO_FOLIO_UPTODATE; pfolio->index = folio->index; } @@ -326,7 +363,12 @@ static void memfd_luo_finish(struct liveupdate_file_op_args *args) struct memfd_luo_folio_ser *folios_ser; struct memfd_luo_ser *ser; - if (args->retrieved) + /* + * If retrieve was successful, nothing to do. If it failed, retrieve() + * already cleaned up everything it could. So nothing to do there + * either. Only need to clean up when retrieve was not called. + */ + if (args->retrieve_status) return; ser = phys_to_virt(args->serialized_data); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index ba4231858a36..ee42d4361309 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -387,7 +387,7 @@ static void __add_to_kill(struct task_struct *tsk, const struct page *p, { struct to_kill *tk; - tk = kmalloc(sizeof(struct to_kill), GFP_ATOMIC); + tk = kmalloc_obj(struct to_kill, GFP_ATOMIC); if (!tk) { pr_err("Out of memory while machine check handling\n"); return; @@ -1917,7 +1917,7 @@ static int hugetlb_update_hwpoison(struct folio *folio, struct page *page) return MF_HUGETLB_PAGE_PRE_POISONED; } - raw_hwp = kmalloc(sizeof(struct raw_hwp_page), GFP_ATOMIC); + raw_hwp = kmalloc_obj(struct raw_hwp_page, GFP_ATOMIC); if (raw_hwp) { raw_hwp->page = page; llist_add(&raw_hwp->node, head); @@ -2214,7 +2214,7 @@ static void add_to_kill_pgoff(struct task_struct *tsk, { struct to_kill *tk; - tk = kmalloc(sizeof(*tk), GFP_ATOMIC); + tk = kmalloc_obj(*tk, GFP_ATOMIC); if (!tk) { pr_info("Unable to kill proc %d\n", tsk->pid); return; diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c index 0ae8bec86346..986f809376eb 100644 --- a/mm/memory-tiers.c +++ b/mm/memory-tiers.c @@ -227,7 +227,7 @@ static struct memory_tier *find_create_memory_tier(struct memory_dev_type *memty } } - new_memtier = kzalloc(sizeof(struct memory_tier), GFP_KERNEL); + new_memtier = kzalloc_obj(struct memory_tier); if (!new_memtier) return ERR_PTR(-ENOMEM); @@ -320,16 +320,17 @@ void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) /** * next_demotion_node() - Get the next node in the demotion path * @node: The starting node to lookup the next node + * @allowed_mask: The pointer to allowed node mask * * Return: node id for next memory node in the demotion path hierarchy * from @node; NUMA_NO_NODE if @node is terminal. This does not keep * @node online or guarantee that it *continues* to be the next demotion * target. */ -int next_demotion_node(int node) +int next_demotion_node(int node, const nodemask_t *allowed_mask) { struct demotion_nodes *nd; - int target; + nodemask_t mask; if (!node_demotion) return NUMA_NO_NODE; @@ -344,6 +345,10 @@ int next_demotion_node(int node) * node_demotion[] reads need to be consistent. */ rcu_read_lock(); + /* Filter out nodes that are not in allowed_mask. */ + nodes_and(mask, nd->preferred, *allowed_mask); + rcu_read_unlock(); + /* * If there are multiple target nodes, just select one * target node randomly. @@ -356,10 +361,16 @@ int next_demotion_node(int node) * caching issue, which seems more complicated. So selecting * target node randomly seems better until now. */ - target = node_random(&nd->preferred); - rcu_read_unlock(); + if (!nodes_empty(mask)) + return node_random(&mask); - return target; + /* + * Preferred nodes are not in allowed_mask. Flip bits in + * allowed_mask as used node mask. Then, use it to get the + * closest demotion target. + */ + nodes_complement(mask, *allowed_mask); + return find_next_best_node(node, &mask); } static void disable_all_demotion_targets(void) @@ -614,7 +625,7 @@ struct memory_dev_type *alloc_memory_type(int adistance) { struct memory_dev_type *memtype; - memtype = kmalloc(sizeof(*memtype), GFP_KERNEL); + memtype = kmalloc_obj(*memtype); if (!memtype) return ERR_PTR(-ENOMEM); @@ -901,8 +912,7 @@ static int __init memory_tier_init(void) panic("%s() failed to register memory tier subsystem\n", __func__); #ifdef CONFIG_MIGRATION - node_demotion = kcalloc(nr_node_ids, sizeof(struct demotion_nodes), - GFP_KERNEL); + node_demotion = kzalloc_objs(struct demotion_nodes, nr_node_ids); WARN_ON(!node_demotion); #endif diff --git a/mm/memory.c b/mm/memory.c index b0d487229b2e..2f815a34d924 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -370,11 +370,32 @@ void free_pgd_range(struct mmu_gather *tlb, } while (pgd++, addr = next, addr != end); } -void free_pgtables(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *vma, unsigned long floor, - unsigned long ceiling, bool mm_wr_locked) +/** + * free_pgtables() - Free a range of page tables + * @tlb: The mmu gather + * @unmap: The unmap_desc + * + * Note: pg_start and pg_end are provided to indicate the absolute range of the + * page tables that should be removed. This can differ from the vma mappings on + * some archs that may have mappings that need to be removed outside the vmas. + * Note that the prev->vm_end and next->vm_start are often used. + * + * The vma_end differs from the pg_end when a dup_mmap() failed and the tree has + * unrelated data to the mm_struct being torn down. + */ +void free_pgtables(struct mmu_gather *tlb, struct unmap_desc *unmap) { struct unlink_vma_file_batch vb; + struct ma_state *mas = unmap->mas; + struct vm_area_struct *vma = unmap->first; + + /* + * Note: USER_PGTABLES_CEILING may be passed as the value of pg_end and + * may be 0. Underflow is expected in this case. Otherwise the + * pagetable end is exclusive. vma_end is exclusive. The last vma + * address should never be larger than the pagetable end. + */ + WARN_ON_ONCE(unmap->vma_end - 1 > unmap->pg_end - 1); tlb_free_vmas(tlb); @@ -382,19 +403,13 @@ void free_pgtables(struct mmu_gather *tlb, struct ma_state *mas, unsigned long addr = vma->vm_start; struct vm_area_struct *next; - /* - * Note: USER_PGTABLES_CEILING may be passed as ceiling and may - * be 0. This will underflow and is okay. - */ - next = mas_find(mas, ceiling - 1); - if (unlikely(xa_is_zero(next))) - next = NULL; + next = mas_find(mas, unmap->tree_end - 1); /* * Hide vma from rmap and truncate_pagecache before freeing * pgtables */ - if (mm_wr_locked) + if (unmap->mm_wr_locked) vma_start_write(vma); unlink_anon_vmas(vma); @@ -406,18 +421,16 @@ void free_pgtables(struct mmu_gather *tlb, struct ma_state *mas, */ while (next && next->vm_start <= vma->vm_end + PMD_SIZE) { vma = next; - next = mas_find(mas, ceiling - 1); - if (unlikely(xa_is_zero(next))) - next = NULL; - if (mm_wr_locked) + next = mas_find(mas, unmap->tree_end - 1); + if (unmap->mm_wr_locked) vma_start_write(vma); unlink_anon_vmas(vma); unlink_file_vma_batch_add(&vb, vma); } unlink_file_vma_batch_final(&vb); - free_pgd_range(tlb, addr, vma->vm_end, - floor, next ? next->vm_start : ceiling); + free_pgd_range(tlb, addr, vma->vm_end, unmap->pg_start, + next ? next->vm_start : unmap->pg_end); vma = next; } while (vma); } @@ -2124,11 +2137,7 @@ static void unmap_single_vma(struct mmu_gather *tlb, /** * unmap_vmas - unmap a range of memory covered by a list of vma's * @tlb: address of the caller's struct mmu_gather - * @mas: the maple state - * @vma: the starting vma - * @start_addr: virtual address at which to start unmapping - * @end_addr: virtual address at which to end unmapping - * @tree_end: The maximum index to check + * @unmap: The unmap_desc * * Unmap all pages in the vma list. * @@ -2141,10 +2150,9 @@ static void unmap_single_vma(struct mmu_gather *tlb, * ensure that any thus-far unmapped pages are flushed before unmap_vmas() * drops the lock and schedules. */ -void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, unsigned long tree_end) +void unmap_vmas(struct mmu_gather *tlb, struct unmap_desc *unmap) { + struct vm_area_struct *vma; struct mmu_notifier_range range; struct zap_details details = { .zap_flags = ZAP_FLAG_DROP_MARKER | ZAP_FLAG_UNMAP, @@ -2152,17 +2160,18 @@ void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, .even_cows = true, }; + vma = unmap->first; mmu_notifier_range_init(&range, MMU_NOTIFY_UNMAP, 0, vma->vm_mm, - start_addr, end_addr); + unmap->vma_start, unmap->vma_end); mmu_notifier_invalidate_range_start(&range); do { - unsigned long start = start_addr; - unsigned long end = end_addr; + unsigned long start = unmap->vma_start; + unsigned long end = unmap->vma_end; hugetlb_zap_begin(vma, &start, &end); unmap_single_vma(tlb, vma, start, end, &details); hugetlb_zap_end(vma, &details); - vma = mas_find(mas, tree_end - 1); - } while (vma && likely(!xa_is_zero(vma))); + vma = mas_find(unmap->mas, unmap->tree_end - 1); + } while (vma); mmu_notifier_invalidate_range_end(&range); } @@ -2948,7 +2957,7 @@ static inline int remap_p4d_range(struct mm_struct *mm, pgd_t *pgd, return 0; } -static int get_remap_pgoff(vm_flags_t vm_flags, unsigned long addr, +static int get_remap_pgoff(bool is_cow, unsigned long addr, unsigned long end, unsigned long vm_start, unsigned long vm_end, unsigned long pfn, pgoff_t *vm_pgoff_p) { @@ -2958,7 +2967,7 @@ static int get_remap_pgoff(vm_flags_t vm_flags, unsigned long addr, * un-COW'ed pages by matching them up with "vma->vm_pgoff". * See vm_normal_page() for details. */ - if (is_cow_mapping(vm_flags)) { + if (is_cow) { if (addr != vm_start || end != vm_end) return -EINVAL; *vm_pgoff_p = pfn; @@ -2979,7 +2988,7 @@ static int remap_pfn_range_internal(struct vm_area_struct *vma, unsigned long ad if (WARN_ON_ONCE(!PAGE_ALIGNED(addr))) return -EINVAL; - VM_WARN_ON_ONCE((vma->vm_flags & VM_REMAP_FLAGS) != VM_REMAP_FLAGS); + VM_WARN_ON_ONCE(!vma_test_all_flags_mask(vma, VMA_REMAP_FLAGS)); BUG_ON(addr >= end); pfn -= addr >> PAGE_SHIFT; @@ -3026,7 +3035,7 @@ static inline struct pfnmap_track_ctx *pfnmap_track_ctx_alloc(unsigned long pfn, if (pfnmap_track(pfn, size, prot)) return ERR_PTR(-EINVAL); - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (unlikely(!ctx)) { pfnmap_untrack(pfn, size); return ERR_PTR(-ENOMEM); @@ -3103,9 +3112,9 @@ void remap_pfn_range_prepare(struct vm_area_desc *desc, unsigned long pfn) * check it again on complete and will fail there if specified addr is * invalid. */ - get_remap_pgoff(desc->vm_flags, desc->start, desc->end, + get_remap_pgoff(vma_desc_is_cow_mapping(desc), desc->start, desc->end, desc->start, desc->end, pfn, &desc->pgoff); - desc->vm_flags |= VM_REMAP_FLAGS; + vma_desc_set_flags_mask(desc, VMA_REMAP_FLAGS); } static int remap_pfn_range_prepare_vma(struct vm_area_struct *vma, unsigned long addr, @@ -3114,13 +3123,12 @@ static int remap_pfn_range_prepare_vma(struct vm_area_struct *vma, unsigned long unsigned long end = addr + PAGE_ALIGN(size); int err; - err = get_remap_pgoff(vma->vm_flags, addr, end, - vma->vm_start, vma->vm_end, - pfn, &vma->vm_pgoff); + err = get_remap_pgoff(is_cow_mapping(vma->vm_flags), addr, end, + vma->vm_start, vma->vm_end, pfn, &vma->vm_pgoff); if (err) return err; - vm_flags_set(vma, VM_REMAP_FLAGS); + vma_set_flags_mask(vma, VMA_REMAP_FLAGS); return 0; } @@ -4755,7 +4763,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf) unlock_page(vmf->page); put_page(vmf->page); } else { - pte_unmap_unlock(vmf->pte, vmf->ptl); + pte_unmap(vmf->pte); + softleaf_entry_wait_on_locked(entry, vmf->ptl); } } else if (softleaf_is_hwpoison(entry)) { ret = VM_FAULT_HWPOISON; @@ -7316,7 +7325,7 @@ void folio_zero_user(struct folio *folio, unsigned long addr_hint) const unsigned long base_addr = ALIGN_DOWN(addr_hint, folio_size(folio)); const long fault_idx = (addr_hint - base_addr) / PAGE_SIZE; const struct range pg = DEFINE_RANGE(0, folio_nr_pages(folio) - 1); - const int radius = FOLIO_ZERO_LOCALITY_RADIUS; + const long radius = FOLIO_ZERO_LOCALITY_RADIUS; struct range r[3]; int i; @@ -7324,20 +7333,19 @@ void folio_zero_user(struct folio *folio, unsigned long addr_hint) * Faulting page and its immediate neighbourhood. Will be cleared at the * end to keep its cachelines hot. */ - r[2] = DEFINE_RANGE(clamp_t(s64, fault_idx - radius, pg.start, pg.end), - clamp_t(s64, fault_idx + radius, pg.start, pg.end)); + r[2] = DEFINE_RANGE(fault_idx - radius < (long)pg.start ? pg.start : fault_idx - radius, + fault_idx + radius > (long)pg.end ? pg.end : fault_idx + radius); + /* Region to the left of the fault */ - r[1] = DEFINE_RANGE(pg.start, - clamp_t(s64, r[2].start - 1, pg.start - 1, r[2].start)); + r[1] = DEFINE_RANGE(pg.start, r[2].start - 1); /* Region to the right of the fault: always valid for the common fault_idx=0 case. */ - r[0] = DEFINE_RANGE(clamp_t(s64, r[2].end + 1, r[2].end, pg.end + 1), - pg.end); + r[0] = DEFINE_RANGE(r[2].end + 1, pg.end); for (i = 0; i < ARRAY_SIZE(r); i++) { const unsigned long addr = base_addr + r[i].start * PAGE_SIZE; - const unsigned int nr_pages = range_len(&r[i]); + const long nr_pages = (long)range_len(&r[i]); struct page *page = folio_page(folio, r[i].start); if (nr_pages > 0) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index dbd48502ac24..0e5175f1c767 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -229,8 +229,7 @@ int mempolicy_set_node_perf(unsigned int node, struct access_coordinate *coords) if (!new_bw) return -ENOMEM; - new_wi_state = kmalloc(struct_size(new_wi_state, iw_table, nr_node_ids), - GFP_KERNEL); + new_wi_state = kmalloc_flex(*new_wi_state, iw_table, nr_node_ids); if (!new_wi_state) { kfree(new_bw); return -ENOMEM; @@ -3642,8 +3641,7 @@ static ssize_t node_store(struct kobject *kobj, struct kobj_attribute *attr, kstrtou8(buf, 0, &weight) || weight == 0) return -EINVAL; - new_wi_state = kzalloc(struct_size(new_wi_state, iw_table, nr_node_ids), - GFP_KERNEL); + new_wi_state = kzalloc_flex(*new_wi_state, iw_table, nr_node_ids); if (!new_wi_state) return -ENOMEM; @@ -3695,8 +3693,7 @@ static ssize_t weighted_interleave_auto_store(struct kobject *kobj, if (kstrtobool(buf, &input)) return -EINVAL; - new_wi_state = kzalloc(struct_size(new_wi_state, iw_table, nr_node_ids), - GFP_KERNEL); + new_wi_state = kzalloc_flex(*new_wi_state, iw_table, nr_node_ids); if (!new_wi_state) return -ENOMEM; for (i = 0; i < nr_node_ids; i++) @@ -3815,7 +3812,7 @@ static int sysfs_wi_node_add(int nid) return -EINVAL; } - new_attr = kzalloc(sizeof(*new_attr), GFP_KERNEL); + new_attr = kzalloc_obj(*new_attr); if (!new_attr) return -ENOMEM; @@ -3880,8 +3877,7 @@ static int __init add_weighted_interleave_group(struct kobject *mempolicy_kobj) { int nid, err; - wi_group = kzalloc(struct_size(wi_group, nattrs, nr_node_ids), - GFP_KERNEL); + wi_group = kzalloc_flex(*wi_group, nattrs, nr_node_ids); if (!wi_group) return -ENOMEM; mutex_init(&wi_group->kobj_lock); diff --git a/mm/mempool.c b/mm/mempool.c index c290e5261b47..db23e0eef652 100644 --- a/mm/mempool.c +++ b/mm/mempool.c @@ -371,8 +371,7 @@ int mempool_resize(struct mempool *pool, int new_min_nr) spin_unlock_irqrestore(&pool->lock, flags); /* Grow the pool */ - new_elements = kmalloc_array(new_min_nr, sizeof(*new_elements), - GFP_KERNEL); + new_elements = kmalloc_objs(*new_elements, new_min_nr); if (!new_elements) return -ENOMEM; diff --git a/mm/memtest.c b/mm/memtest.c index c2c609c39119..520d41534cfa 100644 --- a/mm/memtest.c +++ b/mm/memtest.c @@ -50,6 +50,8 @@ static void __init memtest(u64 pattern, phys_addr_t start_phys, phys_addr_t size start_bad = 0; last_bad = 0; + VM_WARN_ON_ONCE(size < start_phys_aligned - start_phys); + for (p = start; p < end; p++) WRITE_ONCE(*p, pattern); diff --git a/mm/migrate.c b/mm/migrate.c index 1bf2cf8c44dd..2c3d489ecf51 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -500,7 +500,7 @@ void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, if (!softleaf_is_migration(entry)) goto out; - migration_entry_wait_on_locked(entry, ptl); + softleaf_entry_wait_on_locked(entry, ptl); return; out: spin_unlock(ptl); @@ -532,10 +532,10 @@ void migration_entry_wait_huge(struct vm_area_struct *vma, unsigned long addr, p * If migration entry existed, safe to release vma lock * here because the pgtable page won't be freed without the * pgtable lock released. See comment right above pgtable - * lock release in migration_entry_wait_on_locked(). + * lock release in softleaf_entry_wait_on_locked(). */ hugetlb_vma_unlock_read(vma); - migration_entry_wait_on_locked(entry, ptl); + softleaf_entry_wait_on_locked(entry, ptl); return; } @@ -553,7 +553,7 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd) ptl = pmd_lock(mm, pmd); if (!pmd_is_migration_entry(*pmd)) goto unlock; - migration_entry_wait_on_locked(softleaf_from_pmd(*pmd), ptl); + softleaf_entry_wait_on_locked(softleaf_from_pmd(*pmd), ptl); return; unlock: spin_unlock(ptl); diff --git a/mm/migrate_device.c b/mm/migrate_device.c index 0a8b31939640..8079676c8f1f 100644 --- a/mm/migrate_device.c +++ b/mm/migrate_device.c @@ -176,7 +176,7 @@ static int migrate_vma_collect_huge_pmd(pmd_t *pmdp, unsigned long start, } if (softleaf_is_migration(entry)) { - migration_entry_wait_on_locked(entry, ptl); + softleaf_entry_wait_on_locked(entry, ptl); spin_unlock(ptl); return -EAGAIN; } diff --git a/mm/mm_init.c b/mm/mm_init.c index 1a29a719af58..df34797691bd 100644 --- a/mm/mm_init.c +++ b/mm/mm_init.c @@ -1896,7 +1896,11 @@ static void __init free_area_init(void) for_each_node(nid) { pg_data_t *pgdat; - if (!node_online(nid)) + /* + * If an architecture has not allocated node data for + * this node, presume the node is memoryless or offline. + */ + if (!NODE_DATA(nid)) alloc_offline_node_data(nid); pgdat = NODE_DATA(nid); @@ -2474,9 +2478,10 @@ void *__init alloc_large_system_hash(const char *tablename, return table; } -void __init memblock_free_pages(struct page *page, unsigned long pfn, - unsigned int order) +void __init memblock_free_pages(unsigned long pfn, unsigned int order) { + struct page *page = pfn_to_page(pfn); + if (IS_ENABLED(CONFIG_DEFERRED_STRUCT_PAGE_INIT)) { int nid = early_pfn_to_nid(pfn); diff --git a/mm/mmap.c b/mm/mmap.c index 4bdb9ffa9e25..843160946aa5 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -108,7 +108,8 @@ static int check_brk_limits(unsigned long addr, unsigned long len) if (IS_ERR_VALUE(mapped_addr)) return mapped_addr; - return mlock_future_ok(current->mm, current->mm->def_flags, len) + return mlock_future_ok(current->mm, + current->mm->def_flags & VM_LOCKED, len) ? 0 : -EAGAIN; } @@ -225,12 +226,12 @@ static inline unsigned long round_hint_to_min(unsigned long hint) return hint; } -bool mlock_future_ok(const struct mm_struct *mm, vm_flags_t vm_flags, - unsigned long bytes) +bool mlock_future_ok(const struct mm_struct *mm, bool is_vma_locked, + unsigned long bytes) { unsigned long locked_pages, limit_pages; - if (!(vm_flags & VM_LOCKED) || capable(CAP_IPC_LOCK)) + if (!is_vma_locked || capable(CAP_IPC_LOCK)) return true; locked_pages = bytes >> PAGE_SHIFT; @@ -416,7 +417,7 @@ unsigned long do_mmap(struct file *file, unsigned long addr, if (!can_do_mlock()) return -EPERM; - if (!mlock_future_ok(mm, vm_flags, len)) + if (!mlock_future_ok(mm, vm_flags & VM_LOCKED, len)) return -EAGAIN; if (file) { @@ -594,7 +595,7 @@ unsigned long ksys_mmap_pgoff(unsigned long addr, unsigned long len, * taken when vm_ops->mmap() is called */ file = hugetlb_file_setup(HUGETLB_ANON_FILE, len, - VM_NORESERVE, + mk_vma_flags(VMA_NORESERVE_BIT), HUGETLB_ANONHUGE_INODE, (flags >> MAP_HUGE_SHIFT) & MAP_HUGE_MASK); if (IS_ERR(file)) @@ -1247,6 +1248,29 @@ int vm_brk_flags(unsigned long addr, unsigned long request, vm_flags_t vm_flags) } EXPORT_SYMBOL(vm_brk_flags); +static +unsigned long tear_down_vmas(struct mm_struct *mm, struct vma_iterator *vmi, + struct vm_area_struct *vma, unsigned long end) +{ + unsigned long nr_accounted = 0; + int count = 0; + + mmap_assert_write_locked(mm); + vma_iter_set(vmi, vma->vm_end); + do { + if (vma->vm_flags & VM_ACCOUNT) + nr_accounted += vma_pages(vma); + vma_mark_detached(vma); + remove_vma(vma); + count++; + cond_resched(); + vma = vma_next(vmi); + } while (vma && vma->vm_end <= end); + + VM_WARN_ON_ONCE(count != mm->map_count); + return nr_accounted; +} + /* Release all mmaps. */ void exit_mmap(struct mm_struct *mm) { @@ -1254,7 +1278,7 @@ void exit_mmap(struct mm_struct *mm) struct vm_area_struct *vma; unsigned long nr_accounted = 0; VMA_ITERATOR(vmi, mm, 0); - int count = 0; + struct unmap_desc unmap; /* mm's last user has gone, and its about to be pulled down */ mmu_notifier_release(mm); @@ -1263,18 +1287,19 @@ void exit_mmap(struct mm_struct *mm) arch_exit_mmap(mm); vma = vma_next(&vmi); - if (!vma || unlikely(xa_is_zero(vma))) { + if (!vma) { /* Can happen if dup_mmap() received an OOM */ mmap_read_unlock(mm); mmap_write_lock(mm); goto destroy; } + unmap_all_init(&unmap, &vmi, vma); flush_cache_mm(mm); tlb_gather_mmu_fullmm(&tlb, mm); /* update_hiwater_rss(mm) here? but nobody should be looking */ /* Use ULONG_MAX here to ensure all VMAs in the mm are unmapped */ - unmap_vmas(&tlb, &vmi.mas, vma, 0, ULONG_MAX, ULONG_MAX); + unmap_vmas(&tlb, &unmap); mmap_read_unlock(mm); /* @@ -1283,10 +1308,10 @@ void exit_mmap(struct mm_struct *mm) */ mm_flags_set(MMF_OOM_SKIP, mm); mmap_write_lock(mm); + unmap.mm_wr_locked = true; mt_clear_in_rcu(&mm->mm_mt); - vma_iter_set(&vmi, vma->vm_end); - free_pgtables(&tlb, &vmi.mas, vma, FIRST_USER_ADDRESS, - USER_PGTABLES_CEILING, true); + unmap_pgtable_init(&unmap, &vmi); + free_pgtables(&tlb, &unmap); tlb_finish_mmu(&tlb); /* @@ -1294,22 +1319,11 @@ void exit_mmap(struct mm_struct *mm) * enabled, without holding any MM locks besides the unreachable * mmap_write_lock. */ - vma_iter_set(&vmi, vma->vm_end); - do { - if (vma->vm_flags & VM_ACCOUNT) - nr_accounted += vma_pages(vma); - vma_mark_detached(vma); - remove_vma(vma); - count++; - cond_resched(); - vma = vma_next(&vmi); - } while (vma && likely(!xa_is_zero(vma))); + nr_accounted = tear_down_vmas(mm, &vmi, vma, ULONG_MAX); - BUG_ON(count != mm->map_count); - - trace_exit_mmap(mm); destroy: __mt_destroy(&mm->mm_mt); + trace_exit_mmap(mm); mmap_write_unlock(mm); vm_unacct_memory(nr_accounted); } @@ -1840,20 +1854,46 @@ __latent_entropy int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) ksm_fork(mm, oldmm); khugepaged_fork(mm, oldmm); } else { + unsigned long end; /* - * The entire maple tree has already been duplicated. If the - * mmap duplication fails, mark the failure point with - * XA_ZERO_ENTRY. In exit_mmap(), if this marker is encountered, - * stop releasing VMAs that have not been duplicated after this - * point. + * The entire maple tree has already been duplicated, but + * replacing the vmas failed at mpnt (which could be NULL if + * all were allocated but the last vma was not fully set up). + * Use the start address of the failure point to clean up the + * partially initialized tree. */ - if (mpnt) { - mas_set_range(&vmi.mas, mpnt->vm_start, mpnt->vm_end - 1); - mas_store(&vmi.mas, XA_ZERO_ENTRY); - /* Avoid OOM iterating a broken tree */ - mm_flags_set(MMF_OOM_SKIP, mm); + if (!mm->map_count) { + /* zero vmas were written to the new tree. */ + end = 0; + } else if (mpnt) { + /* partial tree failure */ + end = mpnt->vm_start; + } else { + /* All vmas were written to the new tree */ + end = ULONG_MAX; } + + /* Hide mm from oom killer because the memory is being freed */ + mm_flags_set(MMF_OOM_SKIP, mm); + if (end) { + vma_iter_set(&vmi, 0); + tmp = vma_next(&vmi); + UNMAP_STATE(unmap, &vmi, /* first = */ tmp, + /* vma_start = */ 0, /* vma_end = */ end, + /* prev = */ NULL, /* next = */ NULL); + + /* + * Don't iterate over vmas beyond the failure point for + * both unmap_vma() and free_pgtables(). + */ + unmap.tree_end = end; + flush_cache_mm(mm); + unmap_region(&unmap); + charge = tear_down_vmas(mm, &vmi, tmp, end); + vm_unacct_memory(charge); + } + __mt_destroy(&mm->mm_mt); /* * The mm_struct is going to exit, but the locks will be dropped * first. Set the mm_struct as unstable is advisable as it is diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c index 8e0125dc0522..a6cdf3674bdc 100644 --- a/mm/mmu_notifier.c +++ b/mm/mmu_notifier.c @@ -618,8 +618,7 @@ int __mmu_notifier_register(struct mmu_notifier *subscription, * know that mm->notifier_subscriptions can't change while we * hold the write side of the mmap_lock. */ - subscriptions = kzalloc( - sizeof(struct mmu_notifier_subscriptions), GFP_KERNEL); + subscriptions = kzalloc_obj(struct mmu_notifier_subscriptions); if (!subscriptions) return -ENOMEM; diff --git a/mm/mremap.c b/mm/mremap.c index 8391ae17de64..2be876a70cc0 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1740,7 +1740,7 @@ static int check_prep_vma(struct vma_remap_struct *vrm) if (vma->vm_flags & (VM_DONTEXPAND | VM_PFNMAP)) return -EFAULT; - if (!mlock_future_ok(mm, vma->vm_flags, vrm->delta)) + if (!mlock_future_ok(mm, vma->vm_flags & VM_LOCKED, vrm->delta)) return -EAGAIN; if (!may_expand_vm(mm, vma->vm_flags, vrm->delta >> PAGE_SHIFT)) diff --git a/mm/numa_memblks.c b/mm/numa_memblks.c index 391f53e63ea3..3c3c4eac3514 100644 --- a/mm/numa_memblks.c +++ b/mm/numa_memblks.c @@ -570,15 +570,16 @@ static int meminfo_to_nid(struct numa_meminfo *mi, u64 start) int phys_to_target_node(u64 start) { int nid = meminfo_to_nid(&numa_meminfo, start); + int reserved_nid = meminfo_to_nid(&numa_reserved_meminfo, start); /* - * Prefer online nodes, but if reserved memory might be - * hot-added continue the search with reserved ranges. + * Prefer online nodes unless the address is also described + * by reserved ranges, in which case use the reserved nid. */ - if (nid != NUMA_NO_NODE) + if (nid != NUMA_NO_NODE && reserved_nid == NUMA_NO_NODE) return nid; - return meminfo_to_nid(&numa_reserved_meminfo, start); + return reserved_nid; } EXPORT_SYMBOL_GPL(phys_to_target_node); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 167d4b710786..2d4b6f1a554e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -1429,6 +1429,7 @@ __always_inline bool __free_pages_prepare(struct page *page, page_cpupid_reset_last(page); page->flags.f &= ~PAGE_FLAGS_CHECK_AT_PREP; + page->private = 0; reset_page_owner(page, order); page_table_check_free(page, order); pgalloc_tag_sub(page, 1 << order); @@ -6927,7 +6928,8 @@ static int __alloc_contig_verify_gfp_mask(gfp_t gfp_mask, gfp_t *gfp_cc_mask) { const gfp_t reclaim_mask = __GFP_IO | __GFP_FS | __GFP_RECLAIM; const gfp_t action_mask = __GFP_COMP | __GFP_RETRY_MAYFAIL | __GFP_NOWARN | - __GFP_ZERO | __GFP_ZEROTAGS | __GFP_SKIP_ZERO; + __GFP_ZERO | __GFP_ZEROTAGS | __GFP_SKIP_ZERO | + __GFP_SKIP_KASAN; const gfp_t cc_action_mask = __GFP_RETRY_MAYFAIL | __GFP_NOWARN; /* diff --git a/mm/page_owner.c b/mm/page_owner.c index b6a394a130ec..8178e0be557f 100644 --- a/mm/page_owner.c +++ b/mm/page_owner.c @@ -181,7 +181,7 @@ static void add_stack_record_to_list(struct stack_record *stack_record, return; set_current_in_page_owner(); - stack = kmalloc(sizeof(*stack), gfp_nested_mask(gfp_mask)); + stack = kmalloc_obj(*stack, gfp_nested_mask(gfp_mask)); if (!stack) { unset_current_in_page_owner(); return; diff --git a/mm/page_reporting.c b/mm/page_reporting.c index 8a03effda749..f0042d5743af 100644 --- a/mm/page_reporting.c +++ b/mm/page_reporting.c @@ -322,7 +322,7 @@ static void page_reporting_process(struct work_struct *work) atomic_set(&prdev->state, state); /* allocate scatterlist to store pages being reported on */ - sgl = kmalloc_array(PAGE_REPORTING_CAPACITY, sizeof(*sgl), GFP_KERNEL); + sgl = kmalloc_objs(*sgl, PAGE_REPORTING_CAPACITY); if (!sgl) goto err_out; diff --git a/mm/rmap.c b/mm/rmap.c index ab099405151f..391337282e3f 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -913,9 +913,11 @@ static bool folio_referenced_one(struct folio *folio, struct folio_referenced_arg *pra = arg; DEFINE_FOLIO_VMA_WALK(pvmw, folio, vma, address, 0); int ptes = 0, referenced = 0; + unsigned int nr; while (page_vma_mapped_walk(&pvmw)) { address = pvmw.address; + nr = 1; if (vma->vm_flags & VM_LOCKED) { ptes++; @@ -960,9 +962,21 @@ static bool folio_referenced_one(struct folio *folio, if (lru_gen_look_around(&pvmw)) referenced++; } else if (pvmw.pte) { - if (ptep_clear_flush_young_notify(vma, address, - pvmw.pte)) + if (folio_test_large(folio)) { + unsigned long end_addr = pmd_addr_end(address, vma->vm_end); + unsigned int max_nr = (end_addr - address) >> PAGE_SHIFT; + pte_t pteval = ptep_get(pvmw.pte); + + nr = folio_pte_batch(folio, pvmw.pte, + pteval, max_nr); + } + + ptes += nr; + if (clear_flush_young_ptes_notify(vma, address, pvmw.pte, nr)) referenced++; + /* Skip the batched PTEs */ + pvmw.pte += nr - 1; + pvmw.address += (nr - 1) * PAGE_SIZE; } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { if (pmdp_clear_flush_young_notify(vma, address, pvmw.pmd)) @@ -972,7 +986,15 @@ static bool folio_referenced_one(struct folio *folio, WARN_ON_ONCE(1); } - pra->mapcount--; + pra->mapcount -= nr; + /* + * If we are sure that we batched the entire folio, + * we can just optimize and stop right here. + */ + if (ptes == pvmw.nr_pages) { + page_vma_mapped_walk_done(&pvmw); + break; + } } if (referenced) @@ -1923,13 +1945,24 @@ static inline unsigned int folio_unmap_pte_batch(struct folio *folio, end_addr = pmd_addr_end(addr, vma->vm_end); max_nr = (end_addr - addr) >> PAGE_SHIFT; - /* We only support lazyfree batching for now ... */ - if (!folio_test_anon(folio) || folio_test_swapbacked(folio)) + /* We only support lazyfree or file folios batching for now ... */ + if (folio_test_anon(folio) && folio_test_swapbacked(folio)) return 1; + if (pte_unused(pte)) return 1; - return folio_pte_batch(folio, pvmw->pte, pte, max_nr); + if (userfaultfd_wp(vma)) + return 1; + + /* + * If unmap fails, we need to restore the ptes. To avoid accidentally + * upgrading write permissions for ptes that were not originally + * writable, and to avoid losing the soft-dirty bit, use the + * appropriate FPB flags. + */ + return folio_pte_batch_flags(folio, vma, pvmw->pte, &pte, max_nr, + FPB_RESPECT_WRITE | FPB_RESPECT_SOFT_DIRTY); } /* @@ -2291,7 +2324,7 @@ static bool try_to_unmap_one(struct folio *folio, struct vm_area_struct *vma, * * See Documentation/mm/mmu_notifier.rst */ - dec_mm_counter(mm, mm_counter_file(folio)); + add_mm_counter(mm, mm_counter_file(folio), -nr_pages); } discard: if (unlikely(folio_test_hugetlb(folio))) { @@ -2417,11 +2450,17 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, __maybe_unused pmd_t pmdval; if (flags & TTU_SPLIT_HUGE_PMD) { + /* + * split_huge_pmd_locked() might leave the + * folio mapped through PTEs. Retry the walk + * so we can detect this scenario and properly + * abort the walk. + */ split_huge_pmd_locked(vma, pvmw.address, pvmw.pmd, true); - ret = false; - page_vma_mapped_walk_done(&pvmw); - break; + flags &= ~TTU_SPLIT_HUGE_PMD; + page_vma_mapped_walk_restart(&pvmw); + continue; } #ifdef CONFIG_ARCH_ENABLE_THP_MIGRATION pmdval = pmdp_get(pvmw.pmd); diff --git a/mm/secretmem.c b/mm/secretmem.c index edf111e0a1bb..11a779c812a7 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -122,13 +122,12 @@ static int secretmem_mmap_prepare(struct vm_area_desc *desc) { const unsigned long len = vma_desc_size(desc); - if ((desc->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) + if (!vma_desc_test_flags(desc, VMA_SHARED_BIT, VMA_MAYSHARE_BIT)) return -EINVAL; - if (!mlock_future_ok(desc->mm, desc->vm_flags | VM_LOCKED, len)) + vma_desc_set_flags(desc, VMA_LOCKED_BIT, VMA_DONTDUMP_BIT); + if (!mlock_future_ok(desc->mm, /*is_vma_locked=*/ true, len)) return -EAGAIN; - - desc->vm_flags |= VM_LOCKED | VM_DONTDUMP; desc->vm_ops = &secretmem_vm_ops; return 0; diff --git a/mm/shmem.c b/mm/shmem.c index c40d786a21c6..b40f3cd48961 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -3062,9 +3062,9 @@ static struct offset_ctx *shmem_get_offset_ctx(struct inode *inode) } static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, - struct super_block *sb, - struct inode *dir, umode_t mode, - dev_t dev, unsigned long flags) + struct super_block *sb, + struct inode *dir, umode_t mode, + dev_t dev, vma_flags_t flags) { struct inode *inode; struct shmem_inode_info *info; @@ -3092,7 +3092,8 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, spin_lock_init(&info->lock); atomic_set(&info->stop_eviction, 0); info->seals = F_SEAL_SEAL; - info->flags = (flags & VM_NORESERVE) ? SHMEM_F_NORESERVE : 0; + info->flags = vma_flags_test(&flags, VMA_NORESERVE_BIT) + ? SHMEM_F_NORESERVE : 0; info->i_crtime = inode_get_mtime(inode); info->fsflags = (dir == NULL) ? 0 : SHMEM_I(dir)->fsflags & SHMEM_FL_INHERITED; @@ -3145,7 +3146,7 @@ static struct inode *__shmem_get_inode(struct mnt_idmap *idmap, #ifdef CONFIG_TMPFS_QUOTA static struct inode *shmem_get_inode(struct mnt_idmap *idmap, struct super_block *sb, struct inode *dir, - umode_t mode, dev_t dev, unsigned long flags) + umode_t mode, dev_t dev, vma_flags_t flags) { int err; struct inode *inode; @@ -3171,9 +3172,9 @@ static struct inode *shmem_get_inode(struct mnt_idmap *idmap, return ERR_PTR(err); } #else -static inline struct inode *shmem_get_inode(struct mnt_idmap *idmap, +static struct inode *shmem_get_inode(struct mnt_idmap *idmap, struct super_block *sb, struct inode *dir, - umode_t mode, dev_t dev, unsigned long flags) + umode_t mode, dev_t dev, vma_flags_t flags) { return __shmem_get_inode(idmap, sb, dir, mode, dev, flags); } @@ -3880,7 +3881,8 @@ shmem_mknod(struct mnt_idmap *idmap, struct inode *dir, if (!generic_ci_validate_strict_name(dir, &dentry->d_name)) return -EINVAL; - inode = shmem_get_inode(idmap, dir->i_sb, dir, mode, dev, VM_NORESERVE); + inode = shmem_get_inode(idmap, dir->i_sb, dir, mode, dev, + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -3915,7 +3917,8 @@ shmem_tmpfile(struct mnt_idmap *idmap, struct inode *dir, struct inode *inode; int error; - inode = shmem_get_inode(idmap, dir->i_sb, dir, mode, 0, VM_NORESERVE); + inode = shmem_get_inode(idmap, dir->i_sb, dir, mode, 0, + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(inode)) { error = PTR_ERR(inode); goto err_out; @@ -4112,7 +4115,7 @@ static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir, return -ENAMETOOLONG; inode = shmem_get_inode(idmap, dir->i_sb, dir, S_IFLNK | 0777, 0, - VM_NORESERVE); + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(inode)) return PTR_ERR(inode); @@ -5113,7 +5116,8 @@ static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) #endif /* CONFIG_TMPFS_QUOTA */ inode = shmem_get_inode(&nop_mnt_idmap, sb, NULL, - S_IFDIR | sbinfo->mode, 0, VM_NORESERVE); + S_IFDIR | sbinfo->mode, 0, + mk_vma_flags(VMA_NORESERVE_BIT)); if (IS_ERR(inode)) { error = PTR_ERR(inode); goto failed; @@ -5324,7 +5328,7 @@ int shmem_init_fs_context(struct fs_context *fc) { struct shmem_options *ctx; - ctx = kzalloc(sizeof(struct shmem_options), GFP_KERNEL); + ctx = kzalloc_obj(struct shmem_options); if (!ctx) return -ENOMEM; @@ -5814,7 +5818,7 @@ static inline void shmem_unacct_size(unsigned long flags, loff_t size) static inline struct inode *shmem_get_inode(struct mnt_idmap *idmap, struct super_block *sb, struct inode *dir, - umode_t mode, dev_t dev, unsigned long flags) + umode_t mode, dev_t dev, vma_flags_t flags) { struct inode *inode = ramfs_get_inode(sb, dir, mode, dev); return inode ? inode : ERR_PTR(-ENOSPC); @@ -5825,10 +5829,11 @@ static inline struct inode *shmem_get_inode(struct mnt_idmap *idmap, /* common code */ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, - loff_t size, unsigned long vm_flags, + loff_t size, vma_flags_t flags, unsigned int i_flags) { - unsigned long flags = (vm_flags & VM_NORESERVE) ? SHMEM_F_NORESERVE : 0; + const unsigned long shmem_flags = + vma_flags_test(&flags, VMA_NORESERVE_BIT) ? SHMEM_F_NORESERVE : 0; struct inode *inode; struct file *res; @@ -5841,13 +5846,13 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, if (is_idmapped_mnt(mnt)) return ERR_PTR(-EINVAL); - if (shmem_acct_size(flags, size)) + if (shmem_acct_size(shmem_flags, size)) return ERR_PTR(-ENOMEM); inode = shmem_get_inode(&nop_mnt_idmap, mnt->mnt_sb, NULL, - S_IFREG | S_IRWXUGO, 0, vm_flags); + S_IFREG | S_IRWXUGO, 0, flags); if (IS_ERR(inode)) { - shmem_unacct_size(flags, size); + shmem_unacct_size(shmem_flags, size); return ERR_CAST(inode); } inode->i_flags |= i_flags; @@ -5870,9 +5875,10 @@ static struct file *__shmem_file_setup(struct vfsmount *mnt, const char *name, * checks are provided at the key or shm level rather than the inode. * @name: name for dentry (to be seen in /proc//maps) * @size: size to be set for the file - * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size + * @flags: VMA_NORESERVE_BIT suppresses pre-accounting of the entire object size */ -struct file *shmem_kernel_file_setup(const char *name, loff_t size, unsigned long flags) +struct file *shmem_kernel_file_setup(const char *name, loff_t size, + vma_flags_t flags) { return __shmem_file_setup(shm_mnt, name, size, flags, S_PRIVATE); } @@ -5882,9 +5888,9 @@ EXPORT_SYMBOL_GPL(shmem_kernel_file_setup); * shmem_file_setup - get an unlinked file living in tmpfs * @name: name for dentry (to be seen in /proc//maps) * @size: size to be set for the file - * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size + * @flags: VMA_NORESERVE_BIT suppresses pre-accounting of the entire object size */ -struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags) +struct file *shmem_file_setup(const char *name, loff_t size, vma_flags_t flags) { return __shmem_file_setup(shm_mnt, name, size, flags, 0); } @@ -5895,16 +5901,17 @@ EXPORT_SYMBOL_GPL(shmem_file_setup); * @mnt: the tmpfs mount where the file will be created * @name: name for dentry (to be seen in /proc//maps) * @size: size to be set for the file - * @flags: VM_NORESERVE suppresses pre-accounting of the entire object size + * @flags: VMA_NORESERVE_BIT suppresses pre-accounting of the entire object size */ struct file *shmem_file_setup_with_mnt(struct vfsmount *mnt, const char *name, - loff_t size, unsigned long flags) + loff_t size, vma_flags_t flags) { return __shmem_file_setup(mnt, name, size, flags, 0); } EXPORT_SYMBOL_GPL(shmem_file_setup_with_mnt); -static struct file *__shmem_zero_setup(unsigned long start, unsigned long end, vm_flags_t vm_flags) +static struct file *__shmem_zero_setup(unsigned long start, unsigned long end, + vma_flags_t flags) { loff_t size = end - start; @@ -5914,7 +5921,7 @@ static struct file *__shmem_zero_setup(unsigned long start, unsigned long end, v * accessible to the user through its mapping, use S_PRIVATE flag to * bypass file security, in the same way as shmem_kernel_file_setup(). */ - return shmem_kernel_file_setup("dev/zero", size, vm_flags); + return shmem_kernel_file_setup("dev/zero", size, flags); } /** @@ -5924,7 +5931,7 @@ static struct file *__shmem_zero_setup(unsigned long start, unsigned long end, v */ int shmem_zero_setup(struct vm_area_struct *vma) { - struct file *file = __shmem_zero_setup(vma->vm_start, vma->vm_end, vma->vm_flags); + struct file *file = __shmem_zero_setup(vma->vm_start, vma->vm_end, vma->flags); if (IS_ERR(file)) return PTR_ERR(file); @@ -5945,7 +5952,7 @@ int shmem_zero_setup(struct vm_area_struct *vma) */ int shmem_zero_setup_desc(struct vm_area_desc *desc) { - struct file *file = __shmem_zero_setup(desc->start, desc->end, desc->vm_flags); + struct file *file = __shmem_zero_setup(desc->start, desc->end, desc->vma_flags); if (IS_ERR(file)) return PTR_ERR(file); diff --git a/mm/shmem_quota.c b/mm/shmem_quota.c index d1e32ac01407..d0b92d6da50f 100644 --- a/mm/shmem_quota.c +++ b/mm/shmem_quota.c @@ -67,7 +67,7 @@ static int shmem_read_file_info(struct super_block *sb, int type) struct quota_info *dqopt = sb_dqopt(sb); struct mem_dqinfo *info = &dqopt->info[type]; - info->dqi_priv = kzalloc(sizeof(struct rb_root), GFP_NOFS); + info->dqi_priv = kzalloc_obj(struct rb_root, GFP_NOFS); if (!info->dqi_priv) return -ENOMEM; @@ -190,7 +190,7 @@ static int shmem_acquire_dquot(struct dquot *dquot) } /* We don't have entry for this id yet, create it */ - new_entry = kzalloc(sizeof(struct quota_id), GFP_NOFS); + new_entry = kzalloc_obj(struct quota_id, GFP_NOFS); if (!new_entry) { ret = -ENOMEM; goto out_unlock; diff --git a/mm/shrinker.c b/mm/shrinker.c index 4a93fd433689..7b61fc0ee78f 100644 --- a/mm/shrinker.c +++ b/mm/shrinker.c @@ -682,7 +682,7 @@ struct shrinker *shrinker_alloc(unsigned int flags, const char *fmt, ...) va_list ap; int err; - shrinker = kzalloc(sizeof(struct shrinker), GFP_KERNEL); + shrinker = kzalloc_obj(struct shrinker); if (!shrinker) return NULL; diff --git a/mm/slab.h b/mm/slab.h index 71c7261bf822..e9ab292acd22 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -59,7 +59,7 @@ struct freelist_counters { * to save memory. In case ->stride field is not available, * such optimizations are disabled. */ - unsigned short stride; + unsigned int stride; #endif }; }; @@ -290,14 +290,14 @@ static inline void *nearest_obj(struct kmem_cache *cache, /* Determine object index from a given position */ static inline unsigned int __obj_to_index(const struct kmem_cache *cache, - void *addr, void *obj) + void *addr, const void *obj) { return reciprocal_divide(kasan_reset_tag(obj) - addr, cache->reciprocal_size); } static inline unsigned int obj_to_index(const struct kmem_cache *cache, - const struct slab *slab, void *obj) + const struct slab *slab, const void *obj) { if (is_kfence_address(obj)) return 0; @@ -559,20 +559,20 @@ static inline void put_slab_obj_exts(unsigned long obj_exts) } #ifdef CONFIG_64BIT -static inline void slab_set_stride(struct slab *slab, unsigned short stride) +static inline void slab_set_stride(struct slab *slab, unsigned int stride) { slab->stride = stride; } -static inline unsigned short slab_get_stride(struct slab *slab) +static inline unsigned int slab_get_stride(struct slab *slab) { return slab->stride; } #else -static inline void slab_set_stride(struct slab *slab, unsigned short stride) +static inline void slab_set_stride(struct slab *slab, unsigned int stride) { VM_WARN_ON_ONCE(stride != sizeof(struct slabobj_ext)); } -static inline unsigned short slab_get_stride(struct slab *slab) +static inline unsigned int slab_get_stride(struct slab *slab) { return sizeof(struct slabobj_ext); } diff --git a/mm/slub.c b/mm/slub.c index 42df791279d9..2b2d33cc735c 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -2040,18 +2041,18 @@ static inline void dec_slabs_node(struct kmem_cache *s, int node, #ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG -static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) +static inline void mark_obj_codetag_empty(const void *obj) { - struct slab *obj_exts_slab; + struct slab *obj_slab; unsigned long slab_exts; - obj_exts_slab = virt_to_slab(obj_exts); - slab_exts = slab_obj_exts(obj_exts_slab); + obj_slab = virt_to_slab(obj); + slab_exts = slab_obj_exts(obj_slab); if (slab_exts) { get_slab_obj_exts(slab_exts); - unsigned int offs = obj_to_index(obj_exts_slab->slab_cache, - obj_exts_slab, obj_exts); - struct slabobj_ext *ext = slab_obj_ext(obj_exts_slab, + unsigned int offs = obj_to_index(obj_slab->slab_cache, + obj_slab, obj); + struct slabobj_ext *ext = slab_obj_ext(obj_slab, slab_exts, offs); if (unlikely(is_codetag_empty(&ext->ref))) { @@ -2089,7 +2090,7 @@ static inline void handle_failed_objexts_alloc(unsigned long obj_exts, #else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */ -static inline void mark_objexts_empty(struct slabobj_ext *obj_exts) {} +static inline void mark_obj_codetag_empty(const void *obj) {} static inline bool mark_failed_objexts_alloc(struct slab *slab) { return false; } static inline void handle_failed_objexts_alloc(unsigned long obj_exts, struct slabobj_ext *vec, unsigned int objects) {} @@ -2118,13 +2119,6 @@ static inline size_t obj_exts_alloc_size(struct kmem_cache *s, size_t sz = sizeof(struct slabobj_ext) * slab->objects; struct kmem_cache *obj_exts_cache; - /* - * slabobj_ext array for KMALLOC_CGROUP allocations - * are served from KMALLOC_NORMAL caches. - */ - if (!mem_alloc_profiling_enabled()) - return sz; - if (sz > KMALLOC_MAX_CACHE_SIZE) return sz; @@ -2189,15 +2183,12 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, virt_to_slab(vec)->slab_cache == s); new_exts = (unsigned long)vec; - if (unlikely(!allow_spin)) - new_exts |= OBJEXTS_NOSPIN_ALLOC; #ifdef CONFIG_MEMCG new_exts |= MEMCG_DATA_OBJEXTS; #endif retry: old_exts = READ_ONCE(slab->obj_exts); handle_failed_objexts_alloc(old_exts, vec, objects); - slab_set_stride(slab, sizeof(struct slabobj_ext)); if (new_slab) { /* @@ -2212,7 +2203,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, * assign slabobj_exts in parallel. In this case the existing * objcg vector should be reused. */ - mark_objexts_empty(vec); + mark_obj_codetag_empty(vec); if (unlikely(!allow_spin)) kfree_nolock(vec); else @@ -2228,7 +2219,7 @@ int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, return 0; } -static inline void free_slab_obj_exts(struct slab *slab) +static inline void free_slab_obj_exts(struct slab *slab, bool allow_spin) { struct slabobj_ext *obj_exts; @@ -2255,11 +2246,11 @@ static inline void free_slab_obj_exts(struct slab *slab) * NULL, therefore replace NULL with CODETAG_EMPTY to indicate that * the extension for obj_exts is expected to be NULL. */ - mark_objexts_empty(obj_exts); - if (unlikely(READ_ONCE(slab->obj_exts) & OBJEXTS_NOSPIN_ALLOC)) - kfree_nolock(obj_exts); - else + mark_obj_codetag_empty(obj_exts); + if (allow_spin) kfree(obj_exts); + else + kfree_nolock(obj_exts); slab->obj_exts = 0; } @@ -2273,6 +2264,9 @@ static void alloc_slab_obj_exts_early(struct kmem_cache *s, struct slab *slab) void *addr; unsigned long obj_exts; + /* Initialize stride early to avoid memory ordering issues */ + slab_set_stride(slab, sizeof(struct slabobj_ext)); + if (!need_slab_obj_exts(s)) return; @@ -2289,7 +2283,6 @@ static void alloc_slab_obj_exts_early(struct kmem_cache *s, struct slab *slab) obj_exts |= MEMCG_DATA_OBJEXTS; #endif slab->obj_exts = obj_exts; - slab_set_stride(slab, sizeof(struct slabobj_ext)); } else if (s->flags & SLAB_OBJ_EXT_IN_OBJ) { unsigned int offset = obj_exts_offset_in_object(s); @@ -2313,6 +2306,10 @@ static void alloc_slab_obj_exts_early(struct kmem_cache *s, struct slab *slab) #else /* CONFIG_SLAB_OBJ_EXT */ +static inline void mark_obj_codetag_empty(const void *obj) +{ +} + static inline void init_slab_obj_exts(struct slab *slab) { } @@ -2323,7 +2320,7 @@ static int alloc_slab_obj_exts(struct slab *slab, struct kmem_cache *s, return 0; } -static inline void free_slab_obj_exts(struct slab *slab) +static inline void free_slab_obj_exts(struct slab *slab, bool allow_spin) { } @@ -2584,6 +2581,24 @@ struct rcu_delayed_free { * Returns true if freeing of the object can proceed, false if its reuse * was delayed by CONFIG_SLUB_RCU_DEBUG or KASAN quarantine, or it was returned * to KFENCE. + * + * For objects allocated via kmalloc_nolock(), only a subset of alloc hooks + * are invoked, so some free hooks must handle asymmetric hook calls. + * + * Alloc hooks called for kmalloc_nolock(): + * - kmsan_slab_alloc() + * - kasan_slab_alloc() + * - memcg_slab_post_alloc_hook() + * - alloc_tagging_slab_alloc_hook() + * + * Free hooks that must handle missing corresponding alloc hooks: + * - kmemleak_free_recursive() + * - kfence_free() + * + * Free hooks that have no alloc hook counterpart, and thus safe to call: + * - debug_check_no_locks_freed() + * - debug_check_no_obj_freed() + * - __kcsan_check_access() */ static __always_inline bool slab_free_hook(struct kmem_cache *s, void *x, bool init, @@ -2619,7 +2634,7 @@ bool slab_free_hook(struct kmem_cache *s, void *x, bool init, if (still_accessible) { struct rcu_delayed_free *delayed_free; - delayed_free = kmalloc(sizeof(*delayed_free), GFP_NOWAIT); + delayed_free = kmalloc_obj(*delayed_free, GFP_NOWAIT); if (delayed_free) { /* * Let KASAN track our call stack as a "related work @@ -2766,6 +2781,16 @@ static inline struct slab_sheaf *alloc_empty_sheaf(struct kmem_cache *s, static void free_empty_sheaf(struct kmem_cache *s, struct slab_sheaf *sheaf) { + /* + * If the sheaf was created with __GFP_NO_OBJ_EXT flag then its + * corresponding extension is NULL and alloc_tag_sub() will throw a + * warning, therefore replace NULL with CODETAG_EMPTY to indicate + * that the extension for this sheaf is expected to be NULL. + */ + if (s->flags & SLAB_KMALLOC) + mark_obj_codetag_empty(sheaf); + + VM_WARN_ON_ONCE(sheaf->size > 0); kfree(sheaf); stat(s, SHEAF_FREE); @@ -2797,6 +2822,7 @@ static int refill_sheaf(struct kmem_cache *s, struct slab_sheaf *sheaf, return 0; } +static void sheaf_flush_unused(struct kmem_cache *s, struct slab_sheaf *sheaf); static struct slab_sheaf *alloc_full_sheaf(struct kmem_cache *s, gfp_t gfp) { @@ -2805,7 +2831,8 @@ static struct slab_sheaf *alloc_full_sheaf(struct kmem_cache *s, gfp_t gfp) if (!sheaf) return NULL; - if (refill_sheaf(s, sheaf, gfp | __GFP_NOMEMALLOC)) { + if (refill_sheaf(s, sheaf, gfp | __GFP_NOMEMALLOC | __GFP_NOWARN)) { + sheaf_flush_unused(s, sheaf); free_empty_sheaf(s, sheaf); return NULL; } @@ -2827,19 +2854,19 @@ static void __kmem_cache_free_bulk(struct kmem_cache *s, size_t size, void **p); * object pointers are moved to a on-stack array under the lock. To bound the * stack usage, limit each batch to PCS_BATCH_MAX. * - * returns true if at least partially flushed + * Must be called with s->cpu_sheaves->lock locked, returns with the lock + * unlocked. + * + * Returns how many objects are remaining to be flushed */ -static bool sheaf_flush_main(struct kmem_cache *s) +static unsigned int __sheaf_flush_main_batch(struct kmem_cache *s) { struct slub_percpu_sheaves *pcs; unsigned int batch, remaining; void *objects[PCS_BATCH_MAX]; struct slab_sheaf *sheaf; - bool ret = false; -next_batch: - if (!local_trylock(&s->cpu_sheaves->lock)) - return ret; + lockdep_assert_held(this_cpu_ptr(&s->cpu_sheaves->lock)); pcs = this_cpu_ptr(s->cpu_sheaves); sheaf = pcs->main; @@ -2857,10 +2884,37 @@ static bool sheaf_flush_main(struct kmem_cache *s) stat_add(s, SHEAF_FLUSH, batch); - ret = true; + return remaining; +} - if (remaining) - goto next_batch; +static void sheaf_flush_main(struct kmem_cache *s) +{ + unsigned int remaining; + + do { + local_lock(&s->cpu_sheaves->lock); + + remaining = __sheaf_flush_main_batch(s); + + } while (remaining); +} + +/* + * Returns true if the main sheaf was at least partially flushed. + */ +static bool sheaf_try_flush_main(struct kmem_cache *s) +{ + unsigned int remaining; + bool ret = false; + + do { + if (!local_trylock(&s->cpu_sheaves->lock)) + return ret; + + ret = true; + remaining = __sheaf_flush_main_batch(s); + + } while (remaining); return ret; } @@ -3311,8 +3365,11 @@ static void *next_freelist_entry(struct kmem_cache *s, return (char *)start + idx; } +static DEFINE_PER_CPU(struct rnd_state, slab_rnd_state); + /* Shuffle the single linked freelist based on a random pre-computed sequence */ -static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) +static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab, + bool allow_spin) { void *start; void *cur; @@ -3323,7 +3380,19 @@ static bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) return false; freelist_count = oo_objects(s->oo); - pos = get_random_u32_below(freelist_count); + if (allow_spin) { + pos = get_random_u32_below(freelist_count); + } else { + struct rnd_state *state; + + /* + * An interrupt or NMI handler might interrupt and change + * the state in the middle, but that's safe. + */ + state = &get_cpu_var(slab_rnd_state); + pos = prandom_u32_state(state) % freelist_count; + put_cpu_var(slab_rnd_state); + } page_limit = slab->objects * s->size; start = fixup_red_left(s, slab_address(slab)); @@ -3350,7 +3419,8 @@ static inline int init_cache_random_seq(struct kmem_cache *s) return 0; } static inline void init_freelist_randomization(void) { } -static inline bool shuffle_freelist(struct kmem_cache *s, struct slab *slab) +static inline bool shuffle_freelist(struct kmem_cache *s, struct slab *slab, + bool allow_spin) { return false; } @@ -3369,14 +3439,14 @@ static __always_inline void account_slab(struct slab *slab, int order, } static __always_inline void unaccount_slab(struct slab *slab, int order, - struct kmem_cache *s) + struct kmem_cache *s, bool allow_spin) { /* * The slab object extensions should now be freed regardless of * whether mem_alloc_profiling_enabled() or not because profiling * might have been disabled after slab->obj_exts got allocated. */ - free_slab_obj_exts(slab); + free_slab_obj_exts(slab, allow_spin); mod_node_page_state(slab_pgdat(slab), cache_vmstat_idx(s), -(PAGE_SIZE << order)); @@ -3441,7 +3511,7 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) alloc_slab_obj_exts_early(s, slab); account_slab(slab, oo_order(oo), s, flags); - shuffle = shuffle_freelist(s, slab); + shuffle = shuffle_freelist(s, slab, allow_spin); if (!shuffle) { start = fixup_red_left(s, start); @@ -3480,7 +3550,7 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab, bool allow_spin page->mapping = NULL; __ClearPageSlab(page); mm_account_reclaimed_pages(pages); - unaccount_slab(slab, order, s); + unaccount_slab(slab, order, s, allow_spin); if (allow_spin) free_frozen_pages(page, order); else @@ -3791,6 +3861,7 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context * struct zone *zone; enum zone_type highest_zoneidx = gfp_zone(pc->flags); unsigned int cpuset_mems_cookie; + bool allow_spin = gfpflags_allow_spinning(pc->flags); /* * The defrag ratio allows a configuration of the tradeoffs between @@ -3815,7 +3886,15 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context * return NULL; do { - cpuset_mems_cookie = read_mems_allowed_begin(); + /* + * read_mems_allowed_begin() accesses current->mems_allowed_seq, + * a seqcount_spinlock_t that is not NMI-safe. Do not access + * current->mems_allowed_seq and avoid retry when GFP flags + * indicate spinning is not allowed. + */ + if (allow_spin) + cpuset_mems_cookie = read_mems_allowed_begin(); + zonelist = node_zonelist(mempolicy_slab_node(), pc->flags); for_each_zone_zonelist(zone, z, zonelist, highest_zoneidx) { struct kmem_cache_node *n; @@ -3839,7 +3918,7 @@ static void *get_from_any_partial(struct kmem_cache *s, struct partial_context * } } } - } while (read_mems_allowed_retry(cpuset_mems_cookie)); + } while (allow_spin && read_mems_allowed_retry(cpuset_mems_cookie)); #endif /* CONFIG_NUMA */ return NULL; } @@ -4484,7 +4563,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, struct slab_sheaf *empty = NULL; struct slab_sheaf *full; struct node_barn *barn; - bool can_alloc; + bool allow_spin; lockdep_assert_held(this_cpu_ptr(&s->cpu_sheaves->lock)); @@ -4505,8 +4584,9 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, return NULL; } - full = barn_replace_empty_sheaf(barn, pcs->main, - gfpflags_allow_spinning(gfp)); + allow_spin = gfpflags_allow_spinning(gfp); + + full = barn_replace_empty_sheaf(barn, pcs->main, allow_spin); if (full) { stat(s, BARN_GET); @@ -4516,9 +4596,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, stat(s, BARN_GET_FAIL); - can_alloc = gfpflags_allow_blocking(gfp); - - if (can_alloc) { + if (allow_spin) { if (pcs->spare) { empty = pcs->spare; pcs->spare = NULL; @@ -4528,18 +4606,20 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, } local_unlock(&s->cpu_sheaves->lock); + pcs = NULL; - if (!can_alloc) + if (!allow_spin) return NULL; if (empty) { - if (!refill_sheaf(s, empty, gfp | __GFP_NOMEMALLOC)) { + if (!refill_sheaf(s, empty, gfp | __GFP_NOMEMALLOC | __GFP_NOWARN)) { full = empty; } else { /* * we must be very low on memory so don't bother * with the barn */ + sheaf_flush_unused(s, empty); free_empty_sheaf(s, empty); } } else { @@ -4549,11 +4629,8 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, if (!full) return NULL; - /* - * we can reach here only when gfpflags_allow_blocking - * so this must not be an irq - */ - local_lock(&s->cpu_sheaves->lock); + if (!local_trylock(&s->cpu_sheaves->lock)) + goto barn_put; pcs = this_cpu_ptr(s->cpu_sheaves); /* @@ -4584,6 +4661,7 @@ __pcs_replace_empty_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, return pcs; } +barn_put: barn_put_full_sheaf(barn, full); stat(s, BARN_PUT); @@ -4848,9 +4926,14 @@ EXPORT_SYMBOL(kmem_cache_alloc_node_noprof); static int __prefill_sheaf_pfmemalloc(struct kmem_cache *s, struct slab_sheaf *sheaf, gfp_t gfp) { - int ret = 0; + gfp_t gfp_nomemalloc; + int ret; - ret = refill_sheaf(s, sheaf, gfp | __GFP_NOMEMALLOC); + gfp_nomemalloc = gfp | __GFP_NOMEMALLOC; + if (gfp_pfmemalloc_allowed(gfp)) + gfp_nomemalloc |= __GFP_NOWARN; + + ret = refill_sheaf(s, sheaf, gfp_nomemalloc); if (likely(!ret || !gfp_pfmemalloc_allowed(gfp))) return ret; @@ -4886,7 +4969,7 @@ kmem_cache_prefill_sheaf(struct kmem_cache *s, gfp_t gfp, unsigned int size) if (unlikely(size > s->sheaf_capacity)) { - sheaf = kzalloc(struct_size(sheaf, objects, size), gfp); + sheaf = kzalloc_flex(*sheaf, objects, size, gfp); if (!sheaf) return NULL; @@ -5643,7 +5726,7 @@ __pcs_replace_full_main(struct kmem_cache *s, struct slub_percpu_sheaves *pcs, if (put_fail) stat(s, BARN_PUT_FAIL); - if (!sheaf_flush_main(s)) + if (!sheaf_try_flush_main(s)) return NULL; if (!local_trylock(&s->cpu_sheaves->lock)) @@ -6372,7 +6455,7 @@ void kvfree_rcu_cb(struct rcu_head *head) /** * kfree - free previously allocated memory - * @object: pointer returned by kmalloc() or kmem_cache_alloc() + * @object: pointer returned by kmalloc(), kmalloc_nolock(), or kmem_cache_alloc() * * If @object is NULL, no operation is performed. */ @@ -6391,6 +6474,7 @@ void kfree(const void *object) page = virt_to_page(object); slab = page_slab(page); if (!slab) { + /* kmalloc_nolock() doesn't support large kmalloc */ free_large_kmalloc(page, (void *)object); return; } @@ -8337,6 +8421,9 @@ void __init kmem_cache_init_late(void) flushwq = alloc_workqueue("slub_flushwq", WQ_MEM_RECLAIM | WQ_PERCPU, 0); WARN_ON(!flushwq); +#ifdef CONFIG_SLAB_FREELIST_RANDOM + prandom_init_once(&slab_rnd_state); +#endif } int do_kmem_cache_create(struct kmem_cache *s, const char *name, @@ -9093,7 +9180,7 @@ static int show_stat(struct kmem_cache *s, char *buf, enum stat_item si) unsigned long sum = 0; int cpu; int len = 0; - int *data = kmalloc_array(nr_cpu_ids, sizeof(int), GFP_KERNEL); + int *data = kmalloc_objs(int, nr_cpu_ids); if (!data) return -ENOMEM; @@ -9464,7 +9551,7 @@ int sysfs_slab_alias(struct kmem_cache *s, const char *name) return sysfs_create_link(&slab_kset->kobj, &s->kobj, name); } - al = kmalloc(sizeof(struct saved_alias), GFP_KERNEL); + al = kmalloc_obj(struct saved_alias); if (!al) return -ENOMEM; diff --git a/mm/swapfile.c b/mm/swapfile.c index c2377c4b6bb9..94af29d1de88 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -2575,7 +2575,7 @@ add_swap_extent(struct swap_info_struct *sis, unsigned long start_page, } /* No merge, insert a new extent. */ - new_se = kmalloc(sizeof(*se), GFP_KERNEL); + new_se = kmalloc_obj(*se); if (new_se == NULL) return -ENOMEM; new_se->start_page = start_page; @@ -3048,7 +3048,7 @@ static struct swap_info_struct *alloc_swap_info(void) struct swap_info_struct *defer = NULL; unsigned int type; - p = kvzalloc(sizeof(struct swap_info_struct), GFP_KERNEL); + p = kvzalloc_obj(struct swap_info_struct); if (!p) return ERR_PTR(-ENOMEM); @@ -3257,7 +3257,7 @@ static struct swap_cluster_info *setup_clusters(struct swap_info_struct *si, int err = -ENOMEM; unsigned long i; - cluster_info = kvcalloc(nr_clusters, sizeof(*cluster_info), GFP_KERNEL); + cluster_info = kvzalloc_objs(*cluster_info, nr_clusters); if (!cluster_info) goto err; @@ -3265,8 +3265,7 @@ static struct swap_cluster_info *setup_clusters(struct swap_info_struct *si, spin_lock_init(&cluster_info[i].lock); if (!(si->flags & SWP_SOLIDSTATE)) { - si->global_cluster = kmalloc(sizeof(*si->global_cluster), - GFP_KERNEL); + si->global_cluster = kmalloc_obj(*si->global_cluster); if (!si->global_cluster) goto err; for (i = 0; i < SWAP_NR_ORDERS; i++) diff --git a/mm/util.c b/mm/util.c index 97cae40c0209..b05ab6f97e11 100644 --- a/mm/util.c +++ b/mm/util.c @@ -1154,7 +1154,7 @@ int __compat_vma_mmap(const struct file_operations *f_op, .pgoff = vma->vm_pgoff, .vm_file = vma->vm_file, - .vm_flags = vma->vm_flags, + .vma_flags = vma->flags, .page_prot = vma->vm_page_prot, .action.type = MMAP_NOTHING, /* Default */ diff --git a/mm/vma.c b/mm/vma.c index 3dbe414eff89..be64f781a3aa 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -15,7 +15,10 @@ struct mmap_state { unsigned long end; pgoff_t pgoff; unsigned long pglen; - vm_flags_t vm_flags; + union { + vm_flags_t vm_flags; + vma_flags_t vma_flags; + }; struct file *file; pgprot_t page_prot; @@ -472,19 +475,16 @@ void remove_vma(struct vm_area_struct *vma) * * Called with the mm semaphore held. */ -void unmap_region(struct ma_state *mas, struct vm_area_struct *vma, - struct vm_area_struct *prev, struct vm_area_struct *next) +void unmap_region(struct unmap_desc *unmap) { - struct mm_struct *mm = vma->vm_mm; + struct mm_struct *mm = unmap->first->vm_mm; struct mmu_gather tlb; tlb_gather_mmu(&tlb, mm); update_hiwater_rss(mm); - unmap_vmas(&tlb, mas, vma, vma->vm_start, vma->vm_end, vma->vm_end); - mas_set(mas, vma->vm_end); - free_pgtables(&tlb, mas, vma, prev ? prev->vm_end : FIRST_USER_ADDRESS, - next ? next->vm_start : USER_PGTABLES_CEILING, - /* mm_wr_locked = */ true); + unmap_vmas(&tlb, unmap); + mas_set(unmap->mas, unmap->tree_reset); + free_pgtables(&tlb, unmap); tlb_finish_mmu(&tlb); } @@ -1256,26 +1256,32 @@ int vma_shrink(struct vma_iterator *vmi, struct vm_area_struct *vma, static inline void vms_clear_ptes(struct vma_munmap_struct *vms, struct ma_state *mas_detach, bool mm_wr_locked) { - struct mmu_gather tlb; + struct unmap_desc unmap = { + .mas = mas_detach, + .first = vms->vma, + /* start and end may be different if there is no prev or next vma. */ + .pg_start = vms->unmap_start, + .pg_end = vms->unmap_end, + .vma_start = vms->start, + .vma_end = vms->end, + /* + * The tree limits and reset differ from the normal case since it's a + * side-tree + */ + .tree_reset = 1, + .tree_end = vms->vma_count, + /* + * We can free page tables without write-locking mmap_lock because VMAs + * were isolated before we downgraded mmap_lock. + */ + .mm_wr_locked = mm_wr_locked, + }; if (!vms->clear_ptes) /* Nothing to do */ return; - /* - * We can free page tables without write-locking mmap_lock because VMAs - * were isolated before we downgraded mmap_lock. - */ mas_set(mas_detach, 1); - tlb_gather_mmu(&tlb, vms->vma->vm_mm); - update_hiwater_rss(vms->vma->vm_mm); - unmap_vmas(&tlb, mas_detach, vms->vma, vms->start, vms->end, - vms->vma_count); - - mas_set(mas_detach, 1); - /* start and end may be different if there is no prev or next vma. */ - free_pgtables(&tlb, mas_detach, vms->vma, vms->unmap_start, - vms->unmap_end, mm_wr_locked); - tlb_finish_mmu(&tlb); + unmap_region(&unmap); vms->clear_ptes = false; } @@ -2366,7 +2372,7 @@ static void set_desc_from_map(struct vm_area_desc *desc, desc->pgoff = map->pgoff; desc->vm_file = map->file; - desc->vm_flags = map->vm_flags; + desc->vma_flags = map->vma_flags; desc->page_prot = map->page_prot; } @@ -2461,13 +2467,14 @@ static int __mmap_new_file_vma(struct mmap_state *map, error = mmap_file(vma->vm_file, vma); if (error) { + UNMAP_STATE(unmap, vmi, vma, vma->vm_start, vma->vm_end, + map->prev, map->next); fput(vma->vm_file); vma->vm_file = NULL; vma_iter_set(vmi, vma->vm_end); /* Undo any partial mapping done by a device driver. */ - unmap_region(&vmi->mas, vma, map->prev, map->next); - + unmap_region(&unmap); return error; } @@ -2646,7 +2653,7 @@ static int call_mmap_prepare(struct mmap_state *map, map->file_doesnt_need_get = true; map->file = desc->vm_file; } - map->vm_flags = desc->vm_flags; + map->vma_flags = desc->vma_flags; map->page_prot = desc->page_prot; /* User-defined fields. */ map->vm_ops = desc->vm_ops; @@ -2819,7 +2826,7 @@ unsigned long mmap_region(struct file *file, unsigned long addr, return -EINVAL; /* Map writable and ensure this isn't a sealed memfd. */ - if (file && is_shared_maywrite(vm_flags)) { + if (file && is_shared_maywrite_vm_flags(vm_flags)) { int error = mapping_map_writable(file->f_mapping); if (error) @@ -3049,7 +3056,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, return -ENOMEM; /* mlock limit tests */ - if (!mlock_future_ok(mm, vma->vm_flags, grow << PAGE_SHIFT)) + if (!mlock_future_ok(mm, vma->vm_flags & VM_LOCKED, grow << PAGE_SHIFT)) return -ENOMEM; /* Check to ensure the stack will not grow into a hugetlb-only region */ diff --git a/mm/vma.h b/mm/vma.h index d51efd9da113..eba388c61ef4 100644 --- a/mm/vma.h +++ b/mm/vma.h @@ -155,6 +155,72 @@ struct vma_merge_struct { }; +struct unmap_desc { + struct ma_state *mas; /* the maple state point to the first vma */ + struct vm_area_struct *first; /* The first vma */ + unsigned long pg_start; /* The first pagetable address to free (floor) */ + unsigned long pg_end; /* The last pagetable address to free (ceiling) */ + unsigned long vma_start; /* The min vma address */ + unsigned long vma_end; /* The max vma address */ + unsigned long tree_end; /* Maximum for the vma tree search */ + unsigned long tree_reset; /* Where to reset the vma tree walk */ + bool mm_wr_locked; /* If the mmap write lock is held */ +}; + +/* + * unmap_all_init() - Initialize unmap_desc to remove all vmas, point the + * pg_start and pg_end to a safe location. + */ +static inline void unmap_all_init(struct unmap_desc *unmap, + struct vma_iterator *vmi, struct vm_area_struct *vma) +{ + unmap->mas = &vmi->mas; + unmap->first = vma; + unmap->pg_start = FIRST_USER_ADDRESS; + unmap->pg_end = USER_PGTABLES_CEILING; + unmap->vma_start = 0; + unmap->vma_end = ULONG_MAX; + unmap->tree_end = ULONG_MAX; + unmap->tree_reset = vma->vm_end; + unmap->mm_wr_locked = false; +} + +/* + * unmap_pgtable_init() - Initialize unmap_desc to remove all page tables within + * the user range. + * + * ARM can have mappings outside of vmas. + * See: e2cdef8c847b4 ("[PATCH] freepgt: free_pgtables from FIRST_USER_ADDRESS") + * + * ARM LPAE uses page table mappings beyond the USER_PGTABLES_CEILING + * See: CONFIG_ARM_LPAE in arch/arm/include/asm/pgtable.h + */ +static inline void unmap_pgtable_init(struct unmap_desc *unmap, + struct vma_iterator *vmi) +{ + vma_iter_set(vmi, unmap->tree_reset); + unmap->vma_start = FIRST_USER_ADDRESS; + unmap->vma_end = USER_PGTABLES_CEILING; + unmap->tree_end = USER_PGTABLES_CEILING; +} + +#define UNMAP_STATE(name, _vmi, _vma, _vma_start, _vma_end, _prev, _next) \ + struct unmap_desc name = { \ + .mas = &(_vmi)->mas, \ + .first = _vma, \ + .pg_start = _prev ? ((struct vm_area_struct *)_prev)->vm_end : \ + FIRST_USER_ADDRESS, \ + .pg_end = _next ? ((struct vm_area_struct *)_next)->vm_start : \ + USER_PGTABLES_CEILING, \ + .vma_start = _vma_start, \ + .vma_end = _vma_end, \ + .tree_end = _next ? \ + ((struct vm_area_struct *)_next)->vm_start : \ + USER_PGTABLES_CEILING, \ + .tree_reset = _vma->vm_end, \ + .mm_wr_locked = true, \ + } + static inline bool vmg_nomem(struct vma_merge_struct *vmg) { return vmg->state == VMA_MERGE_ERROR_NOMEM; @@ -243,8 +309,7 @@ static inline void set_vma_from_desc(struct vm_area_struct *vma, vma->vm_pgoff = desc->pgoff; if (desc->vm_file != vma->vm_file) vma_set_file(vma, desc->vm_file); - if (desc->vm_flags != vma->vm_flags) - vm_flags_set(vma, desc->vm_flags); + vma->flags = desc->vma_flags; vma->vm_page_prot = desc->page_prot; /* User-defined fields. */ @@ -262,9 +327,7 @@ int do_vmi_munmap(struct vma_iterator *vmi, struct mm_struct *mm, bool unlock); void remove_vma(struct vm_area_struct *vma); - -void unmap_region(struct ma_state *mas, struct vm_area_struct *vma, - struct vm_area_struct *prev, struct vm_area_struct *next); +void unmap_region(struct unmap_desc *unmap); /** * vma_modify_flags() - Perform any necessary split/merge in preparation for diff --git a/mm/vma_internal.h b/mm/vma_internal.h index 2f05735ff190..2da6d224c1a8 100644 --- a/mm/vma_internal.h +++ b/mm/vma_internal.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 03e1117480d5..61caa55a4402 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -4920,14 +4920,14 @@ struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets, return NULL; } - vms = kcalloc(nr_vms, sizeof(vms[0]), GFP_KERNEL); - vas = kcalloc(nr_vms, sizeof(vas[0]), GFP_KERNEL); + vms = kzalloc_objs(vms[0], nr_vms); + vas = kzalloc_objs(vas[0], nr_vms); if (!vas || !vms) goto err_free2; for (area = 0; area < nr_vms; area++) { vas[area] = kmem_cache_zalloc(vmap_area_cachep, GFP_KERNEL); - vms[area] = kzalloc(sizeof(struct vm_struct), GFP_KERNEL); + vms[area] = kzalloc_obj(struct vm_struct); if (!vas[area] || !vms[area]) goto err_free; } @@ -5366,7 +5366,7 @@ static void vmap_init_nodes(void) int n = clamp_t(unsigned int, num_possible_cpus(), 1, 128); if (n > 1) { - vn = kmalloc_array(n, sizeof(*vn), GFP_NOWAIT); + vn = kmalloc_objs(*vn, n, GFP_NOWAIT); if (vn) { /* Node partition is 16 pages. */ vmap_zone_size = (1 << 4) * PAGE_SIZE; diff --git a/mm/vmpressure.c b/mm/vmpressure.c index c197ed47bcc4..3fbb86996c4d 100644 --- a/mm/vmpressure.c +++ b/mm/vmpressure.c @@ -402,7 +402,7 @@ int vmpressure_register_event(struct mem_cgroup *memcg, mode = ret; } - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) { ret = -ENOMEM; goto out; diff --git a/mm/vmscan.c b/mm/vmscan.c index 3fc4a4461927..0fc9373e8251 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -343,19 +343,21 @@ static void flush_reclaim_state(struct scan_control *sc) static bool can_demote(int nid, struct scan_control *sc, struct mem_cgroup *memcg) { - int demotion_nid; + struct pglist_data *pgdat = NODE_DATA(nid); + nodemask_t allowed_mask; - if (!numa_demotion_enabled) + if (!pgdat || !numa_demotion_enabled) return false; if (sc && sc->no_demotion) return false; - demotion_nid = next_demotion_node(nid); - if (demotion_nid == NUMA_NO_NODE) + node_get_allowed_targets(pgdat, &allowed_mask); + if (nodes_empty(allowed_mask)) return false; - /* If demotion node isn't in the cgroup's mems_allowed, fall back */ - return mem_cgroup_node_allowed(memcg, demotion_nid); + /* Filter out nodes that are not in cgroup's mems_allowed. */ + mem_cgroup_node_filter_allowed(memcg, &allowed_mask); + return !nodes_empty(allowed_mask); } static inline bool can_reclaim_anon_pages(struct mem_cgroup *memcg, @@ -1017,9 +1019,10 @@ static struct folio *alloc_demote_folio(struct folio *src, * Folios which are not demoted are left on @demote_folios. */ static unsigned int demote_folio_list(struct list_head *demote_folios, - struct pglist_data *pgdat) + struct pglist_data *pgdat, + struct mem_cgroup *memcg) { - int target_nid = next_demotion_node(pgdat->node_id); + int target_nid; unsigned int nr_succeeded; nodemask_t allowed_mask; @@ -1031,7 +1034,6 @@ static unsigned int demote_folio_list(struct list_head *demote_folios, */ .gfp_mask = (GFP_HIGHUSER_MOVABLE & ~__GFP_RECLAIM) | __GFP_NOMEMALLOC | GFP_NOWAIT, - .nid = target_nid, .nmask = &allowed_mask, .reason = MR_DEMOTION, }; @@ -1039,10 +1041,17 @@ static unsigned int demote_folio_list(struct list_head *demote_folios, if (list_empty(demote_folios)) return 0; - if (target_nid == NUMA_NO_NODE) + node_get_allowed_targets(pgdat, &allowed_mask); + mem_cgroup_node_filter_allowed(memcg, &allowed_mask); + if (nodes_empty(allowed_mask)) return 0; - node_get_allowed_targets(pgdat, &allowed_mask); + target_nid = next_demotion_node(pgdat->node_id, &allowed_mask); + if (target_nid == NUMA_NO_NODE) + /* No lower-tier nodes or nodes were hot-unplugged. */ + return 0; + + mtc.nid = target_nid; /* Demotion ignores all cpuset and mempolicy settings */ migrate_pages(demote_folios, alloc_demote_folio, NULL, @@ -1564,7 +1573,7 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, /* 'folio_list' is always empty here */ /* Migrate folios selected for demotion */ - nr_demoted = demote_folio_list(&demote_folios, pgdat); + nr_demoted = demote_folio_list(&demote_folios, pgdat, memcg); nr_reclaimed += nr_demoted; stat->nr_demoted += nr_demoted; /* Folios that could not be demoted are still in @demote_folios */ @@ -3812,7 +3821,8 @@ static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat, bool force } else if (!walk && force_alloc) { VM_WARN_ON_ONCE(current_is_kswapd()); - walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); + walk = kzalloc_obj(*walk, + __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN); } current->reclaim_state->mm_walk = walk; diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index d5d1c27b3852..2c1430bf8d57 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -2062,7 +2062,7 @@ struct zs_pool *zs_create_pool(const char *name) struct zs_pool *pool; struct size_class *prev_class = NULL; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -2128,7 +2128,7 @@ struct zs_pool *zs_create_pool(const char *name) } } - class = kzalloc(sizeof(struct size_class), GFP_KERNEL); + class = kzalloc_obj(struct size_class); if (!class) goto err; diff --git a/mm/zswap.c b/mm/zswap.c index af3f0fbb0558..e6ec3295bdb0 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -251,7 +251,7 @@ static struct zswap_pool *zswap_pool_create(char *compressor) if (!zswap_has_pool && !strcmp(compressor, ZSWAP_PARAM_UNSET)) return NULL; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; @@ -1665,7 +1665,7 @@ int zswap_swapon(int type, unsigned long nr_pages) unsigned int nr, i; nr = DIV_ROUND_UP(nr_pages, ZSWAP_ADDRESS_SPACE_PAGES); - trees = kvcalloc(nr, sizeof(*tree), GFP_KERNEL); + trees = kvzalloc_objs(*tree, nr); if (!trees) { pr_err("alloc failed, zswap disabled for swap type %d\n", type); return -ENOMEM; diff --git a/net/802/garp.c b/net/802/garp.c index 2d1ffc4d9462..6f563b6797d9 100644 --- a/net/802/garp.c +++ b/net/802/garp.c @@ -547,7 +547,7 @@ static int garp_init_port(struct net_device *dev) { struct garp_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; rcu_assign_pointer(dev->garp_port, port); @@ -581,7 +581,7 @@ int garp_init_applicant(struct net_device *dev, struct garp_application *appl) } err = -ENOMEM; - app = kzalloc(sizeof(*app), GFP_KERNEL); + app = kzalloc_obj(*app); if (!app) goto err2; diff --git a/net/802/mrp.c b/net/802/mrp.c index 23a88305f900..ff0e80574e6b 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c @@ -832,7 +832,7 @@ static int mrp_init_port(struct net_device *dev) { struct mrp_port *port; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; rcu_assign_pointer(dev->mrp_port, port); @@ -866,7 +866,7 @@ int mrp_init_applicant(struct net_device *dev, struct mrp_application *appl) } err = -ENOMEM; - app = kzalloc(sizeof(*app), GFP_KERNEL); + app = kzalloc_obj(*app); if (!app) goto err2; diff --git a/net/802/psnap.c b/net/802/psnap.c index 389df460c8c4..8ae835e1cbae 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c @@ -132,7 +132,7 @@ struct datalink_proto *register_snap_client(const unsigned char *desc, if (find_snap_client(desc)) goto out; - proto = kmalloc(sizeof(*proto), GFP_ATOMIC); + proto = kmalloc_obj(*proto, GFP_ATOMIC); if (proto) { memcpy(proto->type, desc, 5); proto->rcvfunc = rcvfunc; diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 9404dd551dfd..d23965e76c16 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -150,7 +150,7 @@ static struct vlan_info *vlan_info_alloc(struct net_device *dev) { struct vlan_info *vlan_info; - vlan_info = kzalloc(sizeof(struct vlan_info), GFP_KERNEL); + vlan_info = kzalloc_obj(struct vlan_info); if (!vlan_info) return NULL; @@ -193,7 +193,7 @@ static struct vlan_vid_info *vlan_vid_info_alloc(__be16 proto, u16 vid) { struct vlan_vid_info *vid_info; - vid_info = kzalloc(sizeof(struct vlan_vid_info), GFP_KERNEL); + vid_info = kzalloc_obj(struct vlan_vid_info); if (!vid_info) return NULL; vid_info->proto = proto; diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index fbf296137b09..c40f7d5c4fca 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -192,7 +192,7 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, /* Create a new mapping then. */ mp = vlan->egress_priority_map[skb_prio & 0xF]; - np = kmalloc(sizeof(struct vlan_priority_tci_mapping), GFP_KERNEL); + np = kmalloc_obj(struct vlan_priority_tci_mapping); if (!np) return -ENOBUFS; @@ -708,7 +708,7 @@ static int vlan_dev_netpoll_setup(struct net_device *dev) struct netpoll *netpoll; int err = 0; - netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); + netpoll = kzalloc_obj(*netpoll); err = -ENOMEM; if (!netpoll) goto out; diff --git a/net/9p/client.c b/net/9p/client.c index f60d1d041adb..f0dcf252af7e 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -590,8 +590,8 @@ p9_client_rpc(struct p9_client *c, int8_t type, const char *fmt, ...) } again: /* Wait for the response */ - err = wait_event_killable(req->wq, - READ_ONCE(req->status) >= REQ_STATUS_RCVD); + err = io_wait_event_killable(req->wq, + READ_ONCE(req->status) >= REQ_STATUS_RCVD); /* Make sure our req is coherent with regard to updates in other * threads - echoes to wmb() in the callback @@ -730,7 +730,7 @@ static struct p9_fid *p9_fid_create(struct p9_client *clnt) struct p9_fid *fid; p9_debug(P9_DEBUG_FID, "clnt %p\n", clnt); - fid = kzalloc(sizeof(*fid), GFP_KERNEL); + fid = kzalloc_obj(*fid); if (!fid) return NULL; @@ -859,7 +859,7 @@ struct p9_client *p9_client_create(struct fs_context *fc) char *client_id; char *cache_name; - clnt = kmalloc(sizeof(*clnt), GFP_KERNEL); + clnt = kmalloc_obj(*clnt); if (!clnt) return ERR_PTR(-ENOMEM); @@ -1615,7 +1615,7 @@ struct p9_wstat *p9_client_stat(struct p9_fid *fid) p9_debug(P9_DEBUG_9P, ">>> TSTAT fid %d\n", fid->fid); - ret = kmalloc(sizeof(*ret), GFP_KERNEL); + ret = kmalloc_obj(*ret); if (!ret) return ERR_PTR(-ENOMEM); @@ -1667,7 +1667,7 @@ struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid, p9_debug(P9_DEBUG_9P, ">>> TGETATTR fid %d, request_mask %lld\n", fid->fid, request_mask); - ret = kmalloc(sizeof(*ret), GFP_KERNEL); + ret = kmalloc_obj(*ret); if (!ret) return ERR_PTR(-ENOMEM); diff --git a/net/9p/protocol.c b/net/9p/protocol.c index 0e6603b1ec90..67b0586d807f 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c @@ -451,9 +451,8 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, p9pdu_readf(pdu, proto_version, "w", nwqid); if (!errcode) { *wqids = - kmalloc_array(*nwqid, - sizeof(struct p9_qid), - GFP_NOFS); + kmalloc_objs(struct p9_qid, *nwqid, + GFP_NOFS); if (*wqids == NULL) errcode = -ENOMEM; } diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 0e331c1b2112..dbad3213ba84 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -719,8 +719,7 @@ static int p9_fd_show_options(struct seq_file *m, struct p9_client *clnt) static int p9_fd_open(struct p9_client *client, int rfd, int wfd) { - struct p9_trans_fd *ts = kzalloc(sizeof(struct p9_trans_fd), - GFP_KERNEL); + struct p9_trans_fd *ts = kzalloc_obj(struct p9_trans_fd); if (!ts) return -ENOMEM; @@ -764,7 +763,7 @@ static int p9_socket_open(struct p9_client *client, struct socket *csocket) struct p9_trans_fd *p; struct file *file; - p = kzalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); + p = kzalloc_obj(struct p9_trans_fd); if (!p) { sock_release(csocket); return -ENOMEM; diff --git a/net/9p/trans_rdma.c b/net/9p/trans_rdma.c index 4d406479f83b..aa5bd74d333f 100644 --- a/net/9p/trans_rdma.c +++ b/net/9p/trans_rdma.c @@ -334,7 +334,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) } /* Allocate an fcall for the reply */ - rpl_context = kmalloc(sizeof *rpl_context, GFP_NOFS); + rpl_context = kmalloc_obj(*rpl_context, GFP_NOFS); if (!rpl_context) { err = -ENOMEM; goto recv_error; @@ -363,7 +363,7 @@ static int rdma_request(struct p9_client *client, struct p9_req_t *req) dont_need_post_recv: /* Post the request */ - c = kmalloc(sizeof *c, GFP_NOFS); + c = kmalloc_obj(*c, GFP_NOFS); if (!c) { err = -ENOMEM; goto send_error; @@ -460,7 +460,7 @@ static struct p9_trans_rdma *alloc_rdma(struct p9_rdma_opts *opts) { struct p9_trans_rdma *rdma; - rdma = kzalloc(sizeof(struct p9_trans_rdma), GFP_KERNEL); + rdma = kzalloc_obj(struct p9_trans_rdma); if (!rdma) return NULL; diff --git a/net/9p/trans_usbg.c b/net/9p/trans_usbg.c index 93547637deae..1ce70338999c 100644 --- a/net/9p/trans_usbg.c +++ b/net/9p/trans_usbg.c @@ -757,7 +757,7 @@ static struct usb_function *usb9pfs_alloc(struct usb_function_instance *fi) struct f_usb9pfs_opts *usb9pfs_opts; struct f_usb9pfs *usb9pfs; - usb9pfs = kzalloc(sizeof(*usb9pfs), GFP_KERNEL); + usb9pfs = kzalloc_obj(*usb9pfs); if (!usb9pfs) return ERR_PTR(-ENOMEM); @@ -910,7 +910,7 @@ static struct usb_function_instance *usb9pfs_alloc_instance(void) struct f_usb9pfs_opts *usb9pfs_opts; struct f_usb9pfs_dev *dev; - usb9pfs_opts = kzalloc(sizeof(*usb9pfs_opts), GFP_KERNEL); + usb9pfs_opts = kzalloc_obj(*usb9pfs_opts); if (!usb9pfs_opts) return ERR_PTR(-ENOMEM); @@ -921,7 +921,7 @@ static struct usb_function_instance *usb9pfs_alloc_instance(void) usb9pfs_opts->buflen = DEFAULT_BUFLEN; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) { kfree(usb9pfs_opts); return ERR_PTR(-ENOMEM); diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index 10c2dd486438..4cdab7094b27 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c @@ -284,8 +284,8 @@ p9_virtio_request(struct p9_client *client, struct p9_req_t *req) if (err == -ENOSPC) { chan->ring_bufs_avail = 0; spin_unlock_irqrestore(&chan->lock, flags); - err = wait_event_killable(*chan->vc_wq, - chan->ring_bufs_avail); + err = io_wait_event_killable(*chan->vc_wq, + chan->ring_bufs_avail); if (err == -ERESTARTSYS) return err; @@ -325,7 +325,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan, * Other zc request to finish here */ if (atomic_read(&vp_pinned) >= chan->p9_max_pages) { - err = wait_event_killable(vp_wq, + err = io_wait_event_killable(vp_wq, (atomic_read(&vp_pinned) < chan->p9_max_pages)); if (err == -ERESTARTSYS) return err; @@ -358,8 +358,7 @@ static int p9_get_mapped_pages(struct virtio_chan *chan, nr_pages = DIV_ROUND_UP((unsigned long)p + len, PAGE_SIZE) - (unsigned long)p / PAGE_SIZE; - *pages = kmalloc_array(nr_pages, sizeof(struct page *), - GFP_NOFS); + *pages = kmalloc_objs(struct page *, nr_pages, GFP_NOFS); if (!*pages) return -ENOMEM; @@ -512,8 +511,8 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, if (err == -ENOSPC) { chan->ring_bufs_avail = 0; spin_unlock_irqrestore(&chan->lock, flags); - err = wait_event_killable(*chan->vc_wq, - chan->ring_bufs_avail); + err = io_wait_event_killable(*chan->vc_wq, + chan->ring_bufs_avail); if (err == -ERESTARTSYS) goto err_out; @@ -531,8 +530,8 @@ p9_virtio_zc_request(struct p9_client *client, struct p9_req_t *req, spin_unlock_irqrestore(&chan->lock, flags); kicked = 1; p9_debug(P9_DEBUG_TRANS, "virtio request kicked\n"); - err = wait_event_killable(req->wq, - READ_ONCE(req->status) >= REQ_STATUS_RCVD); + err = io_wait_event_killable(req->wq, + READ_ONCE(req->status) >= REQ_STATUS_RCVD); // RERROR needs reply (== error string) in static data if (READ_ONCE(req->status) == REQ_STATUS_RCVD && unlikely(req->rc.sdata[4] == P9_RERROR)) @@ -602,7 +601,7 @@ static int p9_virtio_probe(struct virtio_device *vdev) return -EINVAL; } - chan = kmalloc(sizeof(struct virtio_chan), GFP_KERNEL); + chan = kmalloc_obj(struct virtio_chan); if (!chan) { pr_err("Failed to allocate virtio 9P channel\n"); err = -ENOMEM; @@ -642,7 +641,7 @@ static int p9_virtio_probe(struct virtio_device *vdev) if (err) { goto out_free_tag; } - chan->vc_wq = kmalloc(sizeof(wait_queue_head_t), GFP_KERNEL); + chan->vc_wq = kmalloc_obj(wait_queue_head_t); if (!chan->vc_wq) { err = -ENOMEM; goto out_remove_file; diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 12f752a92332..47af5a10e921 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c @@ -136,8 +136,8 @@ static int p9_xen_request(struct p9_client *client, struct p9_req_t *p9_req) ring = &priv->rings[num]; again: - while (wait_event_killable(ring->wq, - p9_xen_write_todo(ring, size)) != 0) + while (io_wait_event_killable(ring->wq, + p9_xen_write_todo(ring, size)) != 0) ; spin_lock_irqsave(&ring->lock, flags); @@ -277,45 +277,52 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv) { int i, j; - write_lock(&xen_9pfs_lock); - list_del(&priv->list); - write_unlock(&xen_9pfs_lock); + if (priv->rings) { + for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) { + struct xen_9pfs_dataring *ring = &priv->rings[i]; - for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) { - struct xen_9pfs_dataring *ring = &priv->rings[i]; + cancel_work_sync(&ring->work); - cancel_work_sync(&ring->work); + if (!priv->rings[i].intf) + break; + if (priv->rings[i].irq > 0) + unbind_from_irqhandler(priv->rings[i].irq, ring); + if (priv->rings[i].data.in) { + for (j = 0; + j < (1 << priv->rings[i].intf->ring_order); + j++) { + grant_ref_t ref; - if (!priv->rings[i].intf) - break; - if (priv->rings[i].irq > 0) - unbind_from_irqhandler(priv->rings[i].irq, ring); - if (priv->rings[i].data.in) { - for (j = 0; - j < (1 << priv->rings[i].intf->ring_order); - j++) { - grant_ref_t ref; - - ref = priv->rings[i].intf->ref[j]; - gnttab_end_foreign_access(ref, NULL); - } - free_pages_exact(priv->rings[i].data.in, + ref = priv->rings[i].intf->ref[j]; + gnttab_end_foreign_access(ref, NULL); + } + free_pages_exact(priv->rings[i].data.in, 1UL << (priv->rings[i].intf->ring_order + XEN_PAGE_SHIFT)); + } + gnttab_end_foreign_access(priv->rings[i].ref, NULL); + free_page((unsigned long)priv->rings[i].intf); } - gnttab_end_foreign_access(priv->rings[i].ref, NULL); - free_page((unsigned long)priv->rings[i].intf); + kfree(priv->rings); } - kfree(priv->rings); kfree(priv->tag); kfree(priv); } static void xen_9pfs_front_remove(struct xenbus_device *dev) { - struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); + struct xen_9pfs_front_priv *priv; + write_lock(&xen_9pfs_lock); + priv = dev_get_drvdata(&dev->dev); + if (priv == NULL) { + write_unlock(&xen_9pfs_lock); + return; + } dev_set_drvdata(&dev->dev, NULL); + list_del(&priv->list); + write_unlock(&xen_9pfs_lock); + xen_9pfs_front_free(priv); } @@ -382,7 +389,7 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) { int ret, i; struct xenbus_transaction xbt; - struct xen_9pfs_front_priv *priv = dev_get_drvdata(&dev->dev); + struct xen_9pfs_front_priv *priv; char *versions, *v; unsigned int max_rings, max_ring_order, len = 0; @@ -410,8 +417,11 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) if (p9_xen_trans.maxsize > XEN_FLEX_RING_SIZE(max_ring_order)) p9_xen_trans.maxsize = XEN_FLEX_RING_SIZE(max_ring_order) / 2; - priv->rings = kcalloc(XEN_9PFS_NUM_RINGS, sizeof(*priv->rings), - GFP_KERNEL); + priv = kzalloc_obj(*priv); + if (!priv) + return -ENOMEM; + priv->dev = dev; + priv->rings = kzalloc_objs(*priv->rings, XEN_9PFS_NUM_RINGS); if (!priv->rings) { kfree(priv); return -ENOMEM; @@ -468,6 +478,11 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) goto error; } + write_lock(&xen_9pfs_lock); + dev_set_drvdata(&dev->dev, priv); + list_add_tail(&priv->list, &xen_9pfs_devs); + write_unlock(&xen_9pfs_lock); + xenbus_switch_state(dev, XenbusStateInitialised); return 0; @@ -482,19 +497,6 @@ static int xen_9pfs_front_init(struct xenbus_device *dev) static int xen_9pfs_front_probe(struct xenbus_device *dev, const struct xenbus_device_id *id) { - struct xen_9pfs_front_priv *priv = NULL; - - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - priv->dev = dev; - dev_set_drvdata(&dev->dev, priv); - - write_lock(&xen_9pfs_lock); - list_add_tail(&priv->list, &xen_9pfs_devs); - write_unlock(&xen_9pfs_lock); - return 0; } diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 4744e3fd4544..e7315c01a299 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -393,7 +393,7 @@ static void aarp_purge(void) */ static struct aarp_entry *aarp_alloc(void) { - struct aarp_entry *a = kmalloc(sizeof(*a), GFP_ATOMIC); + struct aarp_entry *a = kmalloc_obj(*a, GFP_ATOMIC); if (!a) return NULL; diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 2a01fff46c9d..30a6dc06291c 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -233,7 +233,7 @@ static void atif_drop_device(struct net_device *dev) static struct atalk_iface *atif_add_device(struct net_device *dev, struct atalk_addr *sa) { - struct atalk_iface *iface = kzalloc(sizeof(*iface), GFP_KERNEL); + struct atalk_iface *iface = kzalloc_obj(*iface); if (!iface) goto out; @@ -564,7 +564,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) } if (!rt) { - rt = kzalloc(sizeof(*rt), GFP_ATOMIC); + rt = kzalloc_obj(*rt, GFP_ATOMIC); retval = -ENOBUFS; if (!rt) diff --git a/net/atm/addr.c b/net/atm/addr.c index 0530b63f509a..938f360ae230 100644 --- a/net/atm/addr.c +++ b/net/atm/addr.c @@ -87,7 +87,7 @@ int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, return -EEXIST; } } - this = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC); + this = kmalloc_obj(struct atm_dev_addr, GFP_ATOMIC); if (!this) { spin_unlock_irqrestore(&dev->lock, flags); return -ENOMEM; diff --git a/net/atm/br2684.c b/net/atm/br2684.c index f666f2f98ba5..6580d67c3456 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c @@ -538,7 +538,7 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) if (copy_from_user(&be, arg, sizeof be)) return -EFAULT; - brvcc = kzalloc(sizeof(struct br2684_vcc), GFP_KERNEL); + brvcc = kzalloc_obj(struct br2684_vcc); if (!brvcc) return -ENOMEM; /* diff --git a/net/atm/clip.c b/net/atm/clip.c index 8f152e5fa659..516b2214680b 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -431,7 +431,7 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout) return -EBADFD; if (vcc->user_back) return -EINVAL; - clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL); + clip_vcc = kmalloc_obj(struct clip_vcc); if (!clip_vcc) return -ENOMEM; pr_debug("%p vcc %p\n", clip_vcc, vcc); diff --git a/net/atm/lec.c b/net/atm/lec.c index afb8d3eb2185..fb93c6e1c329 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -696,7 +696,7 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF); if (!dev_lec[ioc_data.dev_num]) return -EINVAL; - vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); + vpriv = kmalloc_obj(struct lec_vcc_priv); if (!vpriv) return -ENOMEM; vpriv->xoff = 0; @@ -1260,24 +1260,28 @@ static void lec_arp_clear_vccs(struct lec_arp_table *entry) struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); struct net_device *dev = (struct net_device *)vcc->proto_data; - vcc->pop = vpriv->old_pop; - if (vpriv->xoff) - netif_wake_queue(dev); - kfree(vpriv); - vcc->user_back = NULL; - vcc->push = entry->old_push; - vcc_release_async(vcc, -EPIPE); + if (vpriv) { + vcc->pop = vpriv->old_pop; + if (vpriv->xoff) + netif_wake_queue(dev); + kfree(vpriv); + vcc->user_back = NULL; + vcc->push = entry->old_push; + vcc_release_async(vcc, -EPIPE); + } entry->vcc = NULL; } if (entry->recv_vcc) { struct atm_vcc *vcc = entry->recv_vcc; struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); - kfree(vpriv); - vcc->user_back = NULL; + if (vpriv) { + kfree(vpriv); + vcc->user_back = NULL; - entry->recv_vcc->push = entry->old_recv_push; - vcc_release_async(entry->recv_vcc, -EPIPE); + entry->recv_vcc->push = entry->old_recv_push; + vcc_release_async(entry->recv_vcc, -EPIPE); + } entry->recv_vcc = NULL; } } @@ -1541,7 +1545,7 @@ static struct lec_arp_table *make_entry(struct lec_priv *priv, { struct lec_arp_table *to_return; - to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); + to_return = kzalloc_obj(struct lec_arp_table, GFP_ATOMIC); if (!to_return) return NULL; ether_addr_copy(to_return->mac_addr, mac_addr); @@ -2125,7 +2129,7 @@ static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) struct lec_vcc_priv *vpriv; int err = 0; - vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); + vpriv = kmalloc_obj(struct lec_vcc_priv); if (!vpriv) return -ENOMEM; vpriv->xoff = 0; diff --git a/net/atm/mpc.c b/net/atm/mpc.c index f6b447bba329..ce8e9780373b 100644 --- a/net/atm/mpc.c +++ b/net/atm/mpc.c @@ -184,7 +184,7 @@ struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos) return entry; } - entry = kmalloc(sizeof(struct atm_mpoa_qos), GFP_KERNEL); + entry = kmalloc_obj(struct atm_mpoa_qos); if (entry == NULL) { pr_info("mpoa: out of memory\n"); return entry; @@ -282,7 +282,7 @@ static struct mpoa_client *alloc_mpc(void) { struct mpoa_client *mpc; - mpc = kzalloc(sizeof(struct mpoa_client), GFP_KERNEL); + mpc = kzalloc_obj(struct mpoa_client); if (mpc == NULL) return NULL; rwlock_init(&mpc->ingress_lock); diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c index f7a2f0e41105..c8d4e6f2e831 100644 --- a/net/atm/mpoa_caches.c +++ b/net/atm/mpoa_caches.c @@ -97,7 +97,7 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc, static in_cache_entry *in_cache_add_entry(__be32 dst_ip, struct mpoa_client *client) { - in_cache_entry *entry = kzalloc(sizeof(in_cache_entry), GFP_KERNEL); + in_cache_entry *entry = kzalloc_obj(in_cache_entry); if (entry == NULL) { pr_info("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n"); @@ -456,7 +456,7 @@ static void eg_cache_remove_entry(eg_cache_entry *entry, static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_client *client) { - eg_cache_entry *entry = kzalloc(sizeof(eg_cache_entry), GFP_KERNEL); + eg_cache_entry *entry = kzalloc_obj(eg_cache_entry); if (entry == NULL) { pr_info("out of memory\n"); diff --git a/net/atm/pppoatm.c b/net/atm/pppoatm.c index 3e4f17d335fe..2574aae3e066 100644 --- a/net/atm/pppoatm.c +++ b/net/atm/pppoatm.c @@ -397,7 +397,7 @@ static int pppoatm_assign_vcc(struct atm_vcc *atmvcc, void __user *arg) if (be.encaps != PPPOATM_ENCAPS_AUTODETECT && be.encaps != PPPOATM_ENCAPS_VC && be.encaps != PPPOATM_ENCAPS_LLC) return -EINVAL; - pvcc = kzalloc(sizeof(*pvcc), GFP_KERNEL); + pvcc = kzalloc_obj(*pvcc); if (pvcc == NULL) return -ENOMEM; pvcc->atmvcc = atmvcc; diff --git a/net/atm/resources.c b/net/atm/resources.c index 7c6fdedbcf4e..939452a610c0 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -36,7 +36,7 @@ static struct atm_dev *__alloc_atm_dev(const char *type) { struct atm_dev *dev; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return NULL; dev->type = type; diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 7ebbff2f0020..a76f4793aed2 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -528,7 +528,7 @@ ax25_cb *ax25_create_cb(void) { ax25_cb *ax25; - if ((ax25 = kzalloc(sizeof(*ax25), GFP_ATOMIC)) == NULL) + if ((ax25 = kzalloc_obj(*ax25, GFP_ATOMIC)) == NULL) return NULL; refcount_set(&ax25->refcount, 1); @@ -1249,7 +1249,7 @@ static int __must_check ax25_connect(struct socket *sock, goto out_release; } - if ((digi = kmalloc(sizeof(ax25_digi), GFP_KERNEL)) == NULL) { + if ((digi = kmalloc_obj(ax25_digi)) == NULL) { err = -ENOBUFS; goto out_release; } diff --git a/net/ax25/ax25_dev.c b/net/ax25/ax25_dev.c index c504ed9c3a88..3c0544fc4ad5 100644 --- a/net/ax25/ax25_dev.c +++ b/net/ax25/ax25_dev.c @@ -54,7 +54,7 @@ void ax25_dev_device_up(struct net_device *dev) { ax25_dev *ax25_dev; - ax25_dev = kzalloc(sizeof(*ax25_dev), GFP_KERNEL); + ax25_dev = kzalloc_obj(*ax25_dev); if (!ax25_dev) { printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n"); return; diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c index 979bc4b828a0..3ad454416a5c 100644 --- a/net/ax25/ax25_iface.c +++ b/net/ax25/ax25_iface.c @@ -105,7 +105,7 @@ int ax25_listen_register(const ax25_address *callsign, struct net_device *dev) if (ax25_listen_mine(callsign, dev)) return 0; - if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) + if ((listen = kmalloc_obj(*listen, GFP_ATOMIC)) == NULL) return -ENOMEM; listen->callsign = *callsign; diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c index f2d66af86359..d75b3e9ed93d 100644 --- a/net/ax25/ax25_in.c +++ b/net/ax25/ax25_in.c @@ -377,7 +377,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, * Sort out any digipeated paths. */ if (dp.ndigi && !ax25->digipeat && - (ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { + (ax25->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) { kfree_skb(skb); ax25_destroy_socket(ax25); if (sk) diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 10577434f40b..1d5c59ccf142 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c @@ -91,7 +91,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) kfree(ax25_rt->digipeat); ax25_rt->digipeat = NULL; if (route->digi_count != 0) { - if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { + if ((ax25_rt->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) { write_unlock_bh(&ax25_route_lock); ax25_dev_put(ax25_dev); return -ENOMEM; @@ -110,7 +110,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) ax25_rt = ax25_rt->next; } - if ((ax25_rt = kmalloc(sizeof(ax25_route), GFP_ATOMIC)) == NULL) { + if ((ax25_rt = kmalloc_obj(ax25_route, GFP_ATOMIC)) == NULL) { write_unlock_bh(&ax25_route_lock); ax25_dev_put(ax25_dev); return -ENOMEM; @@ -121,7 +121,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route) ax25_rt->digipeat = NULL; ax25_rt->ip_mode = ' '; if (route->digi_count != 0) { - if ((ax25_rt->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { + if ((ax25_rt->digipeat = kmalloc_obj(ax25_digi, GFP_ATOMIC)) == NULL) { write_unlock_bh(&ax25_route_lock); kfree(ax25_rt); ax25_dev_put(ax25_dev); diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index 241e4680ecb1..159ce74273f0 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c @@ -101,7 +101,7 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) } if (sax->sax25_uid == 0) return -EINVAL; - if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL) + if ((ax25_uid = kmalloc_obj(*ax25_uid)) == NULL) return -ENOMEM; refcount_set(&ax25_uid->refcount, 1); diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c index cb16c1ed2a58..fdc2abe96d77 100644 --- a/net/batman-adv/bat_v_elp.c +++ b/net/batman-adv/bat_v_elp.c @@ -111,7 +111,15 @@ static bool batadv_v_elp_get_throughput(struct batadv_hardif_neigh_node *neigh, /* unsupported WiFi driver version */ goto default_throughput; - real_netdev = batadv_get_real_netdev(hard_iface->net_dev); + /* only use rtnl_trylock because the elp worker will be cancelled while + * the rntl_lock is held. the cancel_delayed_work_sync() would otherwise + * wait forever when the elp work_item was started and it is then also + * trying to rtnl_lock + */ + if (!rtnl_trylock()) + return false; + real_netdev = __batadv_get_real_netdev(hard_iface->net_dev); + rtnl_unlock(); if (!real_netdev) goto default_throughput; @@ -355,7 +363,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work) * context. Therefore add it to metric_queue and process it * outside rcu protected context. */ - metric_entry = kzalloc(sizeof(*metric_entry), GFP_ATOMIC); + metric_entry = kzalloc_obj(*metric_entry, GFP_ATOMIC); if (!metric_entry) { batadv_hardif_neigh_put(hardif_neigh); continue; diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 3dc791c15bf7..49ae92b9a152 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c @@ -505,7 +505,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig, "%s(): not found (%pM, %d), creating new entry\n", __func__, orig, batadv_print_vid(vid)); - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return NULL; @@ -699,7 +699,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv, /* create a new claim entry if it does not exist yet. */ if (!claim) { - claim = kzalloc(sizeof(*claim), GFP_ATOMIC); + claim = kzalloc_obj(*claim, GFP_ATOMIC); if (!claim) return; diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 8b8132eb0a79..3efc4cf50b46 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -381,7 +381,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip, goto out; } - dat_entry = kmalloc(sizeof(*dat_entry), GFP_ATOMIC); + dat_entry = kmalloc_obj(*dat_entry, GFP_ATOMIC); if (!dat_entry) goto out; @@ -635,8 +635,7 @@ batadv_dat_select_candidates(struct batadv_priv *bat_priv, __be32 ip_dst, if (!bat_priv->orig_hash) return NULL; - res = kmalloc_array(BATADV_DAT_CANDIDATES_NUM, sizeof(*res), - GFP_ATOMIC); + res = kmalloc_objs(*res, BATADV_DAT_CANDIDATES_NUM, GFP_ATOMIC); if (!res) return NULL; diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index cc14bc41381e..f4e45cc25816 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -156,7 +156,7 @@ static bool batadv_frag_insert_packet(struct batadv_orig_node *orig_node, seqno = ntohs(frag_packet->seqno); bucket = seqno % BATADV_FRAG_BUFFER_COUNT; - frag_entry_new = kmalloc(sizeof(*frag_entry_new), GFP_ATOMIC); + frag_entry_new = kmalloc_obj(*frag_entry_new, GFP_ATOMIC); if (!frag_entry_new) goto err; diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index 7a11b245e9f4..51e9c081a2a4 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c @@ -332,7 +332,7 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv, if (gateway->bandwidth_down == 0) return; - gw_node = kzalloc(sizeof(*gw_node), GFP_ATOMIC); + gw_node = kzalloc_obj(*gw_node, GFP_ATOMIC); if (!gw_node) return; diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c index 5113f879736b..d6732c34aeaf 100644 --- a/net/batman-adv/hard-interface.c +++ b/net/batman-adv/hard-interface.c @@ -204,7 +204,7 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev) } /** - * batadv_get_real_netdevice() - check if the given netdev struct is a virtual + * __batadv_get_real_netdev() - check if the given netdev struct is a virtual * interface on top of another 'real' interface * @netdev: the device to check * @@ -214,7 +214,7 @@ static bool batadv_is_valid_iface(const struct net_device *net_dev) * Return: the 'real' net device or the original net device and NULL in case * of an error. */ -static struct net_device *batadv_get_real_netdevice(struct net_device *netdev) +struct net_device *__batadv_get_real_netdev(struct net_device *netdev) { struct batadv_hard_iface *hard_iface = NULL; struct net_device *real_netdev = NULL; @@ -267,7 +267,7 @@ struct net_device *batadv_get_real_netdev(struct net_device *net_device) struct net_device *real_netdev; rtnl_lock(); - real_netdev = batadv_get_real_netdevice(net_device); + real_netdev = __batadv_get_real_netdev(net_device); rtnl_unlock(); return real_netdev; @@ -336,7 +336,7 @@ static u32 batadv_wifi_flags_evaluate(struct net_device *net_device) if (batadv_is_cfg80211_netdev(net_device)) wifi_flags |= BATADV_HARDIF_WIFI_CFG80211_DIRECT; - real_netdev = batadv_get_real_netdevice(net_device); + real_netdev = __batadv_get_real_netdev(net_device); if (!real_netdev) return wifi_flags; @@ -871,7 +871,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) if (!batadv_is_valid_iface(net_dev)) return NULL; - hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC); + hard_iface = kzalloc_obj(*hard_iface, GFP_ATOMIC); if (!hard_iface) return NULL; diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h index 9db8a310961e..9ba8fb2bdceb 100644 --- a/net/batman-adv/hard-interface.h +++ b/net/batman-adv/hard-interface.h @@ -67,6 +67,7 @@ enum batadv_hard_if_bcast { extern struct notifier_block batadv_hard_if_notifier; +struct net_device *__batadv_get_real_netdev(struct net_device *net_device); struct net_device *batadv_get_real_netdev(struct net_device *net_device); bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface); bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface); diff --git a/net/batman-adv/hash.c b/net/batman-adv/hash.c index 8016e619787f..759fa29176db 100644 --- a/net/batman-adv/hash.c +++ b/net/batman-adv/hash.c @@ -45,16 +45,15 @@ struct batadv_hashtable *batadv_hash_new(u32 size) { struct batadv_hashtable *hash; - hash = kmalloc(sizeof(*hash), GFP_ATOMIC); + hash = kmalloc_obj(*hash, GFP_ATOMIC); if (!hash) return NULL; - hash->table = kmalloc_array(size, sizeof(*hash->table), GFP_ATOMIC); + hash->table = kmalloc_objs(*hash->table, size, GFP_ATOMIC); if (!hash->table) goto free_hash; - hash->list_locks = kmalloc_array(size, sizeof(*hash->list_locks), - GFP_ATOMIC); + hash->list_locks = kmalloc_objs(*hash->list_locks, size, GFP_ATOMIC); if (!hash->list_locks) goto free_table; diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c index df7e95811ef5..56ca1c1b83f2 100644 --- a/net/batman-adv/mesh-interface.c +++ b/net/batman-adv/mesh-interface.c @@ -555,7 +555,7 @@ int batadv_meshif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid) return -EEXIST; } - vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); + vlan = kzalloc_obj(*vlan, GFP_ATOMIC); if (!vlan) { spin_unlock_bh(&bat_priv->meshif_vlan_list_lock); return -ENOMEM; diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index e8c6b0bf670f..a3d3efe22d30 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -399,7 +399,7 @@ batadv_mcast_mla_meshif_get_ipv4(struct net_device *dev, if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) continue; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) { ret = -ENOMEM; break; @@ -472,7 +472,7 @@ batadv_mcast_mla_meshif_get_ipv6(struct net_device *dev, if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) continue; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) { ret = -ENOMEM; break; @@ -632,7 +632,7 @@ static int batadv_mcast_mla_bridge_get(struct net_device *dev, if (batadv_mcast_mla_is_duplicate(mcast_addr, mcast_list)) continue; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) { ret = -ENOMEM; break; diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index a662408ad867..b3468ccab535 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -179,7 +179,7 @@ batadv_orig_node_vlan_new(struct batadv_orig_node *orig_node, if (vlan) goto out; - vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC); + vlan = kzalloc_obj(*vlan, GFP_ATOMIC); if (!vlan) goto out; @@ -417,7 +417,7 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node, if (orig_ifinfo) goto out; - orig_ifinfo = kzalloc(sizeof(*orig_ifinfo), GFP_ATOMIC); + orig_ifinfo = kzalloc_obj(*orig_ifinfo, GFP_ATOMIC); if (!orig_ifinfo) goto out; @@ -495,7 +495,7 @@ batadv_neigh_ifinfo_new(struct batadv_neigh_node *neigh, if (neigh_ifinfo) goto out; - neigh_ifinfo = kzalloc(sizeof(*neigh_ifinfo), GFP_ATOMIC); + neigh_ifinfo = kzalloc_obj(*neigh_ifinfo, GFP_ATOMIC); if (!neigh_ifinfo) goto out; @@ -575,7 +575,7 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface, if (hardif_neigh) goto out; - hardif_neigh = kzalloc(sizeof(*hardif_neigh), GFP_ATOMIC); + hardif_neigh = kzalloc_obj(*hardif_neigh, GFP_ATOMIC); if (!hardif_neigh) goto out; @@ -683,7 +683,7 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node, if (!hardif_neigh) goto out; - neigh_node = kzalloc(sizeof(*neigh_node), GFP_ATOMIC); + neigh_node = kzalloc_obj(*neigh_node, GFP_ATOMIC); if (!neigh_node) goto out; @@ -947,7 +947,7 @@ struct batadv_orig_node *batadv_orig_node_new(struct batadv_priv *bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv, "Creating new originator: %pM\n", addr); - orig_node = kzalloc(sizeof(*orig_node), GFP_ATOMIC); + orig_node = kzalloc_obj(*orig_node, GFP_ATOMIC); if (!orig_node) return NULL; diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c index 20d85c681064..60cd67ec9cea 100644 --- a/net/batman-adv/send.c +++ b/net/batman-adv/send.c @@ -503,7 +503,7 @@ batadv_forw_packet_alloc(struct batadv_hard_iface *if_incoming, return NULL; } - forw_packet = kmalloc(sizeof(*forw_packet), GFP_ATOMIC); + forw_packet = kmalloc_obj(*forw_packet, GFP_ATOMIC); if (!forw_packet) goto err; diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 350b149e48be..2e42f6b348c8 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c @@ -967,7 +967,7 @@ void batadv_tp_start(struct batadv_priv *bat_priv, const u8 *dst, return; } - tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC); + tp_vars = kmalloc_obj(*tp_vars, GFP_ATOMIC); if (!tp_vars) { spin_unlock_bh(&bat_priv->tp_list_lock); batadv_dbg(BATADV_DBG_TP_METER, bat_priv, @@ -1228,7 +1228,7 @@ static bool batadv_tp_handle_out_of_order(struct batadv_tp_vars *tp_vars, u32 payload_len; bool added = false; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (unlikely(!new)) return false; @@ -1343,7 +1343,7 @@ batadv_tp_init_recv(struct batadv_priv *bat_priv, goto out_unlock; } - tp_vars = kmalloc(sizeof(*tp_vars), GFP_ATOMIC); + tp_vars = kmalloc_obj(*tp_vars, GFP_ATOMIC); if (!tp_vars) goto out_unlock; diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c index 76dff1f9c559..8129a3f9c44d 100644 --- a/net/batman-adv/tvlv.c +++ b/net/batman-adv/tvlv.c @@ -557,7 +557,7 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv, return; } - tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC); + tvlv_handler = kzalloc_obj(*tvlv_handler, GFP_ATOMIC); if (!tvlv_handler) { spin_unlock_bh(&bat_priv->tvlv.handler_list_lock); return; diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 2c21ae8abadc..2f03b780b40d 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c @@ -645,7 +645,7 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, { struct lowpan_peer *peer; - peer = kzalloc(sizeof(*peer), GFP_ATOMIC); + peer = kzalloc_obj(*peer, GFP_ATOMIC); if (!peer) return NULL; @@ -1107,7 +1107,7 @@ static int lowpan_enable_set(void *data, u64 val) { struct set_enable *set_enable; - set_enable = kzalloc(sizeof(*set_enable), GFP_KERNEL); + set_enable = kzalloc_obj(*set_enable); if (!set_enable) return -ENOMEM; @@ -1245,7 +1245,7 @@ static void disconnect_devices(void) rcu_read_lock(); list_for_each_entry_rcu(entry, &bt_6lowpan_devices, list) { - new_dev = kmalloc(sizeof(*new_dev), GFP_ATOMIC); + new_dev = kmalloc_obj(*new_dev, GFP_ATOMIC); if (!new_dev) break; diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c index 884703fda979..b95413bffa16 100644 --- a/net/bluetooth/cmtp/capi.c +++ b/net/bluetooth/cmtp/capi.c @@ -72,7 +72,7 @@ static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl) { - struct cmtp_application *app = kzalloc(sizeof(*app), GFP_KERNEL); + struct cmtp_application *app = kzalloc_obj(*app); BT_DBG("session %p application %p appl %u", session, app, appl); diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c index 90d130588a3e..261aeeda3236 100644 --- a/net/bluetooth/cmtp/core.c +++ b/net/bluetooth/cmtp/core.c @@ -341,7 +341,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock) if (req->flags & ~valid_flags) return -EINVAL; - session = kzalloc(sizeof(struct cmtp_session), GFP_KERNEL); + session = kzalloc_obj(struct cmtp_session); if (!session) return -ENOMEM; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 0795818963a5..4719dac07190 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -462,7 +462,7 @@ bool hci_setup_sync(struct hci_conn *conn, __u16 handle) struct conn_handle_t *conn_handle; if (enhanced_sync_conn_capable(conn->hdev)) { - conn_handle = kzalloc(sizeof(*conn_handle), GFP_KERNEL); + conn_handle = kzalloc_obj(*conn_handle); if (!conn_handle) return false; @@ -726,7 +726,7 @@ static int hci_le_terminate_big(struct hci_dev *hdev, struct hci_conn *conn) bt_dev_dbg(hdev, "big 0x%2.2x bis 0x%2.2x", conn->iso_qos.bcast.big, conn->iso_qos.bcast.bis); - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) return -ENOMEM; @@ -777,7 +777,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, struct hci_conn *conn) bt_dev_dbg(hdev, "hcon %p big 0x%2.2x sync_handle 0x%4.4x", conn, conn->iso_qos.bcast.big, conn->sync_handle); - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (!d) return -ENOMEM; @@ -960,7 +960,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bt_dev_dbg(hdev, "dst %pMR handle 0x%4.4x", dst, handle); - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) return ERR_PTR(-ENOMEM); @@ -1739,7 +1739,7 @@ static struct hci_link *hci_conn_link(struct hci_conn *parent, if (conn->parent) return NULL; - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) return NULL; @@ -2781,7 +2781,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) return NULL; } - chan = kzalloc(sizeof(*chan), GFP_KERNEL); + chan = kzalloc_obj(*chan); if (!chan) return NULL; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index b069607b145b..31308c1de4ec 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -262,7 +262,7 @@ u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data, } /* Entry not in the cache. Add new one. */ - ie = kzalloc(sizeof(*ie), GFP_KERNEL); + ie = kzalloc_obj(*ie); if (!ie) { flags |= MGMT_DEV_FOUND_CONFIRM_NAME; goto done; @@ -797,7 +797,7 @@ int hci_get_dev_list(void __user *arg) if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr)) return -EINVAL; - dl = kzalloc(struct_size(dl, dev_req, dev_num), GFP_KERNEL); + dl = kzalloc_flex(*dl, dev_req, dev_num); if (!dl) return -ENOMEM; @@ -1286,7 +1286,7 @@ struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, key = old_key; } else { old_key_type = conn ? conn->key_type : 0xff; - key = kzalloc(sizeof(*key), GFP_KERNEL); + key = kzalloc_obj(*key); if (!key) return NULL; list_add_rcu(&key->list, &hdev->link_keys); @@ -1331,7 +1331,7 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, if (old_key) key = old_key; else { - key = kzalloc(sizeof(*key), GFP_KERNEL); + key = kzalloc_obj(*key); if (!key) return NULL; list_add_rcu(&key->list, &hdev->long_term_keys); @@ -1356,7 +1356,7 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); if (!irk) { - irk = kzalloc(sizeof(*irk), GFP_KERNEL); + irk = kzalloc_obj(*irk); if (!irk) return NULL; @@ -1550,7 +1550,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, data = hci_find_remote_oob_data(hdev, bdaddr, bdaddr_type); if (!data) { - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; @@ -1718,7 +1718,7 @@ struct adv_info *hci_add_adv_instance(struct hci_dev *hdev, u8 instance, instance < 1 || instance > hdev->le_num_of_adv_sets + 1) return ERR_PTR(-EOVERFLOW); - adv = kzalloc(sizeof(*adv), GFP_KERNEL); + adv = kzalloc_obj(*adv); if (!adv) return ERR_PTR(-ENOMEM); @@ -2107,7 +2107,7 @@ int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type) if (hci_bdaddr_list_lookup(list, bdaddr, type)) return -EEXIST; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -2130,7 +2130,7 @@ int hci_bdaddr_list_add_with_irk(struct list_head *list, bdaddr_t *bdaddr, if (hci_bdaddr_list_lookup(list, bdaddr, type)) return -EEXIST; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -2159,7 +2159,7 @@ int hci_bdaddr_list_add_with_flags(struct list_head *list, bdaddr_t *bdaddr, if (hci_bdaddr_list_lookup(list, bdaddr, type)) return -EEXIST; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -2276,7 +2276,7 @@ struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev, if (params) return params; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) { bt_dev_err(hdev, "out of memory"); return NULL; diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 4e7bf63af9c5..0290dea081f6 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c @@ -2166,6 +2166,7 @@ static void hci_sock_destruct(struct sock *sk) mgmt_cleanup(sk); skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); + skb_queue_purge(&sk->sk_error_queue); } static const struct proto_ops hci_sock_ops = { diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c index f04a90bce4a9..121dbc8208ec 100644 --- a/net/bluetooth/hci_sync.c +++ b/net/bluetooth/hci_sync.c @@ -711,7 +711,7 @@ int hci_cmd_sync_submit(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, goto unlock; } - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto unlock; @@ -2685,7 +2685,7 @@ static struct conn_params *conn_params_copy(struct list_head *list, size_t *n) rcu_read_unlock(); - p = kvcalloc(*n, sizeof(struct conn_params), GFP_KERNEL); + p = kvzalloc_objs(struct conn_params, *n); if (!p) return NULL; @@ -4592,7 +4592,7 @@ static int hci_le_set_host_features_sync(struct hci_dev *hdev) { int err; - if (iso_capable(hdev)) { + if (cis_capable(hdev)) { /* Connected Isochronous Channels (Host Support) */ err = hci_le_set_host_feature_sync(hdev, 32, (iso_enabled(hdev) ? 0x01 : @@ -7341,7 +7341,7 @@ int hci_past_sync(struct hci_conn *conn, struct hci_conn *le) if (!past_sender_capable(conn->hdev)) return -EOPNOTSUPP; - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; @@ -7473,7 +7473,7 @@ int hci_acl_change_pkt_type(struct hci_conn *conn, u16 pkt_type) struct hci_dev *hdev = conn->hdev; struct hci_cp_change_conn_ptype *cp; - cp = kmalloc(sizeof(*cp), GFP_KERNEL); + cp = kmalloc_obj(*cp); if (!cp) return -ENOMEM; @@ -7508,7 +7508,7 @@ int hci_le_set_phy(struct hci_conn *conn, u8 tx_phys, u8 rx_phys) struct hci_dev *hdev = conn->hdev; struct hci_cp_le_set_phy *cp; - cp = kmalloc(sizeof(*cp), GFP_KERNEL); + cp = kmalloc_obj(*cp); if (!cp) return -ENOMEM; diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 6724adce615b..6fe815241b01 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -920,7 +920,7 @@ static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, ctrl = bt_sk(ctrl_sock->sk); intr = bt_sk(intr_sock->sk); - session = kzalloc(sizeof(*session), GFP_KERNEL); + session = kzalloc_obj(*session); if (!session) return -ENOMEM; diff --git a/net/bluetooth/iso.c b/net/bluetooth/iso.c index 1459ab161fd2..be145e2736b7 100644 --- a/net/bluetooth/iso.c +++ b/net/bluetooth/iso.c @@ -212,7 +212,7 @@ static struct iso_conn *iso_conn_add(struct hci_conn *hcon) return conn; } - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) return NULL; @@ -746,6 +746,7 @@ static void iso_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); + skb_queue_purge(&sk->sk_error_queue); } static void iso_sock_cleanup_listen(struct sock *parent) diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index b628b0fa39b2..ad98db9632fd 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -442,7 +442,7 @@ struct l2cap_chan *l2cap_chan_create(void) { struct l2cap_chan *chan; - chan = kzalloc(sizeof(*chan), GFP_ATOMIC); + chan = kzalloc_obj(*chan, GFP_ATOMIC); if (!chan) return NULL; @@ -4916,6 +4916,13 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, goto response_unlock; } + /* Check if Key Size is sufficient for the security level */ + if (!l2cap_check_enc_key_size(conn->hcon, pchan)) { + result = L2CAP_CR_LE_BAD_KEY_SIZE; + chan = NULL; + goto response_unlock; + } + /* Check for valid dynamic CID range */ if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { result = L2CAP_CR_LE_INVALID_SCID; @@ -5051,13 +5058,15 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, struct l2cap_chan *chan, *pchan; u16 mtu, mps; __le16 psm; - u8 result, len = 0; + u8 result, rsp_len = 0; int i, num_scid; bool defer = false; if (!enable_ecred) return -EINVAL; + memset(pdu, 0, sizeof(*pdu)); + if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) { result = L2CAP_CR_LE_INVALID_PARAMS; goto response; @@ -5066,6 +5075,9 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, cmd_len -= sizeof(*req); num_scid = cmd_len / sizeof(u16); + /* Always respond with the same number of scids as in the request */ + rsp_len = cmd_len; + if (num_scid > L2CAP_ECRED_MAX_CID) { result = L2CAP_CR_LE_INVALID_PARAMS; goto response; @@ -5075,7 +5087,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, mps = __le16_to_cpu(req->mps); if (mtu < L2CAP_ECRED_MIN_MTU || mps < L2CAP_ECRED_MIN_MPS) { - result = L2CAP_CR_LE_UNACCEPT_PARAMS; + result = L2CAP_CR_LE_INVALID_PARAMS; goto response; } @@ -5095,8 +5107,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, BT_DBG("psm 0x%2.2x mtu %u mps %u", __le16_to_cpu(psm), mtu, mps); - memset(pdu, 0, sizeof(*pdu)); - /* Check if we have socket listening on psm */ pchan = l2cap_global_chan_by_psm(BT_LISTEN, psm, &conn->hcon->src, &conn->hcon->dst, LE_LINK); @@ -5109,7 +5119,16 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, if (!smp_sufficient_security(conn->hcon, pchan->sec_level, SMP_ALLOW_STK)) { - result = L2CAP_CR_LE_AUTHENTICATION; + result = pchan->sec_level == BT_SECURITY_MEDIUM ? + L2CAP_CR_LE_ENCRYPTION : L2CAP_CR_LE_AUTHENTICATION; + goto unlock; + } + + /* Check if the listening channel has set an output MTU then the + * requested MTU shall be less than or equal to that value. + */ + if (pchan->omtu && mtu < pchan->omtu) { + result = L2CAP_CR_LE_UNACCEPT_PARAMS; goto unlock; } @@ -5121,7 +5140,6 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, BT_DBG("scid[%d] 0x%4.4x", i, scid); pdu->dcid[i] = 0x0000; - len += sizeof(*pdu->dcid); /* Check for valid dynamic CID range */ if (scid < L2CAP_CID_DYN_START || scid > L2CAP_CID_LE_DYN_END) { @@ -5188,7 +5206,7 @@ static inline int l2cap_ecred_conn_req(struct l2cap_conn *conn, return 0; l2cap_send_cmd(conn, cmd->ident, L2CAP_ECRED_CONN_RSP, - sizeof(*pdu) + len, pdu); + sizeof(*pdu) + rsp_len, pdu); return 0; } @@ -5310,14 +5328,14 @@ static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn, struct l2cap_ecred_reconf_req *req = (void *) data; struct l2cap_ecred_reconf_rsp rsp; u16 mtu, mps, result; - struct l2cap_chan *chan; + struct l2cap_chan *chan[L2CAP_ECRED_MAX_CID] = {}; int i, num_scid; if (!enable_ecred) return -EINVAL; - if (cmd_len < sizeof(*req) || cmd_len - sizeof(*req) % sizeof(u16)) { - result = L2CAP_CR_LE_INVALID_PARAMS; + if (cmd_len < sizeof(*req) || (cmd_len - sizeof(*req)) % sizeof(u16)) { + result = L2CAP_RECONF_INVALID_CID; goto respond; } @@ -5327,42 +5345,69 @@ static inline int l2cap_ecred_reconf_req(struct l2cap_conn *conn, BT_DBG("mtu %u mps %u", mtu, mps); if (mtu < L2CAP_ECRED_MIN_MTU) { - result = L2CAP_RECONF_INVALID_MTU; + result = L2CAP_RECONF_INVALID_PARAMS; goto respond; } if (mps < L2CAP_ECRED_MIN_MPS) { - result = L2CAP_RECONF_INVALID_MPS; + result = L2CAP_RECONF_INVALID_PARAMS; goto respond; } cmd_len -= sizeof(*req); num_scid = cmd_len / sizeof(u16); + + if (num_scid > L2CAP_ECRED_MAX_CID) { + result = L2CAP_RECONF_INVALID_PARAMS; + goto respond; + } + result = L2CAP_RECONF_SUCCESS; + /* Check if each SCID, MTU and MPS are valid */ for (i = 0; i < num_scid; i++) { u16 scid; scid = __le16_to_cpu(req->scid[i]); - if (!scid) - return -EPROTO; - - chan = __l2cap_get_chan_by_dcid(conn, scid); - if (!chan) - continue; - - /* If the MTU value is decreased for any of the included - * channels, then the receiver shall disconnect all - * included channels. - */ - if (chan->omtu > mtu) { - BT_ERR("chan %p decreased MTU %u -> %u", chan, - chan->omtu, mtu); - result = L2CAP_RECONF_INVALID_MTU; + if (!scid) { + result = L2CAP_RECONF_INVALID_CID; + goto respond; } - chan->omtu = mtu; - chan->remote_mps = mps; + chan[i] = __l2cap_get_chan_by_dcid(conn, scid); + if (!chan[i]) { + result = L2CAP_RECONF_INVALID_CID; + goto respond; + } + + /* The MTU field shall be greater than or equal to the greatest + * current MTU size of these channels. + */ + if (chan[i]->omtu > mtu) { + BT_ERR("chan %p decreased MTU %u -> %u", chan[i], + chan[i]->omtu, mtu); + result = L2CAP_RECONF_INVALID_MTU; + goto respond; + } + + /* If more than one channel is being configured, the MPS field + * shall be greater than or equal to the current MPS size of + * each of these channels. If only one channel is being + * configured, the MPS field may be less than the current MPS + * of that channel. + */ + if (chan[i]->remote_mps >= mps && i) { + BT_ERR("chan %p decreased MPS %u -> %u", chan[i], + chan[i]->remote_mps, mps); + result = L2CAP_RECONF_INVALID_MPS; + goto respond; + } + } + + /* Commit the new MTU and MPS values after checking they are valid */ + for (i = 0; i < num_scid; i++) { + chan[i]->omtu = mtu; + chan[i]->remote_mps = mps; } respond: @@ -6902,7 +6947,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) if (!hchan) return NULL; - conn = kzalloc(sizeof(*conn), GFP_KERNEL); + conn = kzalloc_obj(*conn); if (!conn) { hci_chan_del(hchan); return NULL; diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 3ba3ce7eaa98..597686790371 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c @@ -1029,10 +1029,17 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, break; } - /* Setting is not supported as it's the remote side that - * decides this. - */ - err = -EPERM; + /* Only allow setting output MTU when not connected */ + if (sk->sk_state == BT_CONNECTED) { + err = -EISCONN; + break; + } + + err = copy_safe_from_sockptr(&mtu, sizeof(mtu), optval, optlen); + if (err) + break; + + chan->omtu = mtu; break; case BT_RCVMTU: @@ -1564,8 +1571,7 @@ static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) (chan->mode == L2CAP_MODE_ERTM || chan->mode == L2CAP_MODE_LE_FLOWCTL || chan->mode == L2CAP_MODE_EXT_FLOWCTL)) { - struct l2cap_rx_busy *rx_busy = - kmalloc(sizeof(*rx_busy), GFP_KERNEL); + struct l2cap_rx_busy *rx_busy = kmalloc_obj(*rx_busy); if (!rx_busy) { err = -ENOMEM; goto done; @@ -1817,6 +1823,7 @@ static void l2cap_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); + skb_queue_purge(&sk->sk_error_queue); } static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name, diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 0e46f9e08b10..a7238fd3b03b 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c @@ -560,7 +560,7 @@ static int read_ext_index_list(struct sock *sk, struct hci_dev *hdev, list_for_each_entry(d, &hci_dev_list, list) count++; - rp = kmalloc(struct_size(rp, entry, count), GFP_ATOMIC); + rp = kmalloc_flex(*rp, entry, count, GFP_ATOMIC); if (!rp) { read_unlock(&hci_dev_list_lock); return -ENOMEM; @@ -2767,7 +2767,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) goto failed; } - uuid = kmalloc(sizeof(*uuid), GFP_KERNEL); + uuid = kmalloc_obj(*uuid); if (!uuid) { err = -ENOMEM; goto failed; @@ -3360,7 +3360,7 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, i++; } - rp = kmalloc(struct_size(rp, addr, i), GFP_KERNEL); + rp = kmalloc_flex(*rp, addr, i); if (!rp) { err = -ENOMEM; goto unlock; @@ -4377,7 +4377,7 @@ static int set_blocked_keys(struct sock *sk, struct hci_dev *hdev, void *data, hci_blocked_keys_clear(hdev); for (i = 0; i < key_count; ++i) { - struct blocked_key *b = kzalloc(sizeof(*b), GFP_KERNEL); + struct blocked_key *b = kzalloc_obj(*b); if (!b) { err = MGMT_STATUS_NO_RESOURCES; @@ -5490,7 +5490,7 @@ static u8 parse_adv_monitor_pattern(struct adv_monitor *m, u8 pattern_count, (offset + length) > HCI_MAX_AD_LENGTH) return MGMT_STATUS_INVALID_PARAMS; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return MGMT_STATUS_NO_RESOURCES; @@ -5527,7 +5527,7 @@ static int add_adv_patterns_monitor(struct sock *sk, struct hci_dev *hdev, goto done; } - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (!m) { status = MGMT_STATUS_NO_RESOURCES; goto done; @@ -5564,7 +5564,7 @@ static int add_adv_patterns_monitor_rssi(struct sock *sk, struct hci_dev *hdev, goto done; } - m = kzalloc(sizeof(*m), GFP_KERNEL); + m = kzalloc_obj(*m); if (!m) { status = MGMT_STATUS_NO_RESOURCES; goto done; diff --git a/net/bluetooth/mgmt_util.c b/net/bluetooth/mgmt_util.c index aa7b5585cb26..4f19654d41a9 100644 --- a/net/bluetooth/mgmt_util.c +++ b/net/bluetooth/mgmt_util.c @@ -266,7 +266,7 @@ struct mgmt_pending_cmd *mgmt_pending_new(struct sock *sk, u16 opcode, { struct mgmt_pending_cmd *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return NULL; @@ -413,7 +413,7 @@ struct mgmt_mesh_tx *mgmt_mesh_add(struct sock *sk, struct hci_dev *hdev, { struct mgmt_mesh_tx *mesh_tx; - mesh_tx = kzalloc(sizeof(*mesh_tx), GFP_KERNEL); + mesh_tx = kzalloc_obj(*mesh_tx); if (!mesh_tx) return NULL; diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c index c560d8467669..2f008167cbaa 100644 --- a/net/bluetooth/msft.c +++ b/net/bluetooth/msft.c @@ -276,7 +276,7 @@ static int msft_le_monitor_advertisement_cb(struct hci_dev *hdev, u16 opcode, if (status) goto unlock; - handle_data = kmalloc(sizeof(*handle_data), GFP_KERNEL); + handle_data = kmalloc_obj(*handle_data); if (!handle_data) { status = HCI_ERROR_UNSPECIFIED; goto unlock; @@ -756,7 +756,7 @@ void msft_register(struct hci_dev *hdev) bt_dev_dbg(hdev, "Register MSFT extension"); - msft = kzalloc(sizeof(*msft), GFP_KERNEL); + msft = kzalloc_obj(*msft); if (!msft) { bt_dev_err(hdev, "Failed to register MSFT extension"); return; @@ -790,7 +790,7 @@ static void msft_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, { struct monitored_device *dev; - dev = kmalloc(sizeof(*dev), GFP_KERNEL); + dev = kmalloc_obj(*dev); if (!dev) { bt_dev_err(hdev, "MSFT vendor event %u: no memory", MSFT_EV_LE_MONITOR_DEVICE); @@ -932,7 +932,7 @@ static struct msft_monitor_addr_filter_data *msft_add_address_filter struct msft_data *msft = hdev->msft_data; int err; - address_filter = kzalloc(sizeof(*address_filter), GFP_KERNEL); + address_filter = kzalloc_obj(*address_filter); if (!address_filter) return NULL; diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index 57b1dca8141f..611a9a94151e 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -302,7 +302,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio) { - struct rfcomm_dlc *d = kzalloc(sizeof(*d), prio); + struct rfcomm_dlc *d = kzalloc_obj(*d, prio); if (!d) return NULL; @@ -680,7 +680,7 @@ int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig) /* ---- RFCOMM sessions ---- */ static struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state) { - struct rfcomm_session *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct rfcomm_session *s = kzalloc_obj(*s); if (!s) return NULL; diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index b783526ab588..91bf5274262e 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c @@ -221,7 +221,7 @@ static struct rfcomm_dev *__rfcomm_dev_add(struct rfcomm_dev_req *req, struct list_head *head = &rfcomm_dev_list; int err = 0; - dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL); + dev = kzalloc_obj(struct rfcomm_dev); if (!dev) return ERR_PTR(-ENOMEM); @@ -510,7 +510,7 @@ static int rfcomm_get_dev_list(void __user *arg) if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di)) return -EINVAL; - dl = kzalloc(struct_size(dl, dev_info, dev_num), GFP_KERNEL); + dl = kzalloc_flex(*dl, dev_info, dev_num); if (!dl) return -ENOMEM; diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 87ba90336e80..e7db50165879 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c @@ -204,7 +204,7 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon) return conn; } - conn = kzalloc(sizeof(struct sco_conn), GFP_KERNEL); + conn = kzalloc_obj(struct sco_conn); if (!conn) return NULL; @@ -470,6 +470,7 @@ static void sco_sock_destruct(struct sock *sk) skb_queue_purge(&sk->sk_receive_queue); skb_queue_purge(&sk->sk_write_queue); + skb_queue_purge(&sk->sk_error_queue); } static void sco_sock_cleanup_listen(struct sock *parent) diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index bf61e8841535..e67bf7b34ea7 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -1344,7 +1344,7 @@ static void smp_distribute_keys(struct smp_chan *smp) /* Generate a new random key */ get_random_bytes(sign.csrk, sizeof(sign.csrk)); - csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); + csrk = kzalloc_obj(*csrk); if (csrk) { if (hcon->sec_level > BT_SECURITY_MEDIUM) csrk->type = MGMT_CSRK_LOCAL_AUTHENTICATED; @@ -1388,7 +1388,7 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) struct l2cap_chan *chan = conn->smp; struct smp_chan *smp; - smp = kzalloc(sizeof(*smp), GFP_ATOMIC); + smp = kzalloc_obj(*smp, GFP_ATOMIC); if (!smp) return NULL; @@ -2664,7 +2664,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) skb_pull(skb, sizeof(*rp)); - csrk = kzalloc(sizeof(*csrk), GFP_KERNEL); + csrk = kzalloc_obj(*csrk); if (csrk) { if (conn->hcon->sec_level > BT_SECURITY_MEDIUM) csrk->type = MGMT_CSRK_REMOTE_AUTHENTICATED; @@ -3293,7 +3293,7 @@ static struct l2cap_chan *smp_add_cid(struct hci_dev *hdev, u16 cid) goto create_chan; } - smp = kzalloc(sizeof(*smp), GFP_KERNEL); + smp = kzalloc_obj(*smp); if (!smp) return ERR_PTR(-ENOMEM); diff --git a/net/bpf/bpf_dummy_struct_ops.c b/net/bpf/bpf_dummy_struct_ops.c index 812457819b5a..ae5a54c350b9 100644 --- a/net/bpf/bpf_dummy_struct_ops.c +++ b/net/bpf/bpf_dummy_struct_ops.c @@ -36,7 +36,7 @@ dummy_ops_init_args(const union bpf_attr *kattr, unsigned int nr) if (size_in != sizeof(u64) * nr) return ERR_PTR(-EINVAL); - args = kzalloc(sizeof(*args), GFP_KERNEL); + args = kzalloc_obj(*args); if (!args) return ERR_PTR(-ENOMEM); @@ -158,13 +158,13 @@ int bpf_struct_ops_test_run(struct bpf_prog *prog, const union bpf_attr *kattr, if (err) goto out; - tlinks = kcalloc(BPF_TRAMP_MAX, sizeof(*tlinks), GFP_KERNEL); + tlinks = kzalloc_objs(*tlinks, BPF_TRAMP_MAX); if (!tlinks) { err = -ENOMEM; goto out; } - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto out; diff --git a/net/bridge/br_cfm.c b/net/bridge/br_cfm.c index c2c1c7d44c61..2c70fe47de38 100644 --- a/net/bridge/br_cfm.c +++ b/net/bridge/br_cfm.c @@ -547,7 +547,7 @@ int br_cfm_mep_create(struct net_bridge *br, } } - mep = kzalloc(sizeof(*mep), GFP_KERNEL); + mep = kzalloc_obj(*mep); if (!mep) return -ENOMEM; @@ -693,7 +693,7 @@ int br_cfm_cc_peer_mep_add(struct net_bridge *br, const u32 instance, return -EEXIST; } - peer_mep = kzalloc(sizeof(*peer_mep), GFP_KERNEL); + peer_mep = kzalloc_obj(*peer_mep); if (!peer_mep) return -ENOMEM; diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index a818fdc22da9..f7502e62dd35 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c @@ -74,7 +74,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) eth_hdr(skb)->h_proto == htons(ETH_P_RARP)) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) { br_do_proxy_suppress_arp(skb, br, vid, NULL); - } else if (IS_ENABLED(CONFIG_IPV6) && + } else if (ipv6_mod_enabled() && skb->protocol == htons(ETH_P_IPV6) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) && pskb_may_pull(skb, sizeof(struct ipv6hdr) + @@ -308,7 +308,7 @@ static int __br_netpoll_enable(struct net_bridge_port *p) struct netpoll *np; int err; - np = kzalloc(sizeof(*p->np), GFP_KERNEL); + np = kzalloc_obj(*p->np); if (!np) return -ENOMEM; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 4c67a32745f6..d39571e13744 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -429,7 +429,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, if (index < 0) return ERR_PTR(index); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (p == NULL) return ERR_PTR(-ENOMEM); diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 1405f1061a54..2cbae0f9ae1f 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -170,7 +170,7 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb (skb->protocol == htons(ETH_P_ARP) || skb->protocol == htons(ETH_P_RARP))) { br_do_proxy_suppress_arp(skb, br, vid, p); - } else if (IS_ENABLED(CONFIG_IPV6) && + } else if (ipv6_mod_enabled() && skb->protocol == htons(ETH_P_IPV6) && br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED) && pskb_may_pull(skb, sizeof(struct ipv6hdr) + diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 6bc0a11f2ed3..766c43b327af 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c @@ -204,7 +204,7 @@ int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, if (num > BR_MAX_PORTS) num = BR_MAX_PORTS; - indices = kcalloc(num, sizeof(int), GFP_KERNEL); + indices = kzalloc_objs(int, num); if (indices == NULL) return -ENOMEM; @@ -357,7 +357,7 @@ static int old_deviceless(struct net *net, void __user *data) if (args[2] >= 2048) return -ENOMEM; - indices = kcalloc(args[2], sizeof(int), GFP_KERNEL); + indices = kzalloc_objs(int, args[2]); if (indices == NULL) return -ENOMEM; diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 400eb872b403..e0c7020b12f5 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -1133,8 +1133,8 @@ static int br_mdb_config_src_list_init(struct nlattr *src_list, return -EINVAL; } - cfg->src_entries = kcalloc(cfg->num_src_entries, - sizeof(struct br_mdb_src_entry), GFP_KERNEL); + cfg->src_entries = kzalloc_objs(struct br_mdb_src_entry, + cfg->num_src_entries); if (!cfg->src_entries) return -ENOMEM; diff --git a/net/bridge/br_mrp.c b/net/bridge/br_mrp.c index 3c36fa24bc05..f1aa67f7a051 100644 --- a/net/bridge/br_mrp.c +++ b/net/bridge/br_mrp.c @@ -516,7 +516,7 @@ int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance) !br_mrp_unique_ifindex(br, instance->s_ifindex)) return -EINVAL; - mrp = kzalloc(sizeof(*mrp), GFP_KERNEL); + mrp = kzalloc_obj(*mrp); if (!mrp) return -ENOMEM; diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index dccae08b4f4c..881d866d687a 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -244,14 +244,11 @@ br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid) lockdep_assert_held_once(&port->br->multicast_lock); - if (!br_opt_get(port->br, BROPT_MCAST_VLAN_SNOOPING_ENABLED)) - return NULL; - /* Take RCU to access the vlan. */ rcu_read_lock(); vlan = br_vlan_find(nbp_vlan_group_rcu(port), vid); - if (vlan && !br_multicast_port_ctx_vlan_disabled(&vlan->port_mcast_ctx)) + if (vlan) pmctx = &vlan->port_mcast_ctx; rcu_read_unlock(); @@ -701,7 +698,10 @@ br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx, u32 max = READ_ONCE(pmctx->mdb_max_entries); u32 n = READ_ONCE(pmctx->mdb_n_entries); - if (max && n >= max) { + /* enforce the max limit when it's a port pmctx or a port-vlan pmctx + * with snooping enabled + */ + if (!br_multicast_port_ctx_vlan_disabled(pmctx) && max && n >= max) { NL_SET_ERR_MSG_FMT_MOD(extack, "%s is already in %u groups, and mcast_max_groups=%u", what, n, max); return -E2BIG; @@ -736,9 +736,7 @@ static int br_multicast_port_ngroups_inc(struct net_bridge_port *port, return err; } - /* Only count on the VLAN context if VID is given, and if snooping on - * that VLAN is enabled. - */ + /* Only count on the VLAN context if VID is given */ if (!group->vid) return 0; @@ -1292,7 +1290,7 @@ struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br, return ERR_PTR(-E2BIG); } - mp = kzalloc(sizeof(*mp), GFP_ATOMIC); + mp = kzalloc_obj(*mp, GFP_ATOMIC); if (unlikely(!mp)) return ERR_PTR(-ENOMEM); @@ -1383,7 +1381,7 @@ br_multicast_new_group_src(struct net_bridge_port_group *pg, struct br_ip *src_i #endif } - grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC); + grp_src = kzalloc_obj(*grp_src, GFP_ATOMIC); if (unlikely(!grp_src)) return NULL; @@ -1416,7 +1414,7 @@ struct net_bridge_port_group *br_multicast_new_port_group( if (err) return NULL; - p = kzalloc(sizeof(*p), GFP_ATOMIC); + p = kzalloc_obj(*p, GFP_ATOMIC); if (unlikely(!p)) { NL_SET_ERR_MSG_MOD(extack, "Couldn't allocate new port group"); goto dec_out; @@ -2011,6 +2009,18 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port, timer_setup(&pmctx->ip6_own_query.timer, br_ip6_multicast_port_query_expired, 0); #endif + /* initialize mdb_n_entries if a new port vlan is being created */ + if (vlan) { + struct net_bridge_port_group *pg; + u32 n = 0; + + spin_lock_bh(&port->br->multicast_lock); + hlist_for_each_entry(pg, &port->mglist, mglist) + if (pg->key.addr.vid == vlan->vid) + n++; + WRITE_ONCE(pmctx->mdb_n_entries, n); + spin_unlock_bh(&port->br->multicast_lock); + } } void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) @@ -2094,25 +2104,6 @@ static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) br_ip4_multicast_add_router(brmctx, pmctx); br_ip6_multicast_add_router(brmctx, pmctx); } - - if (br_multicast_port_ctx_is_vlan(pmctx)) { - struct net_bridge_port_group *pg; - u32 n = 0; - - /* The mcast_n_groups counter might be wrong. First, - * BR_VLFLAG_MCAST_ENABLED is toggled before temporary entries - * are flushed, thus mcast_n_groups after the toggle does not - * reflect the true values. And second, permanent entries added - * while BR_VLFLAG_MCAST_ENABLED was disabled, are not reflected - * either. Thus we have to refresh the counter. - */ - - hlist_for_each_entry(pg, &pmctx->port->mglist, mglist) { - if (pg->key.addr.vid == pmctx->vlan->vid) - n++; - } - WRITE_ONCE(pmctx->mdb_n_entries, n); - } } static void br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx) @@ -4900,7 +4891,7 @@ int br_multicast_list_adjacent(struct net_device *dev, continue; hlist_for_each_entry_rcu(group, &port->mglist, mglist) { - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) goto unlock; diff --git a/net/bridge/br_multicast_eht.c b/net/bridge/br_multicast_eht.c index adfd74102019..18eaf9c0dada 100644 --- a/net/bridge/br_multicast_eht.c +++ b/net/bridge/br_multicast_eht.c @@ -266,7 +266,7 @@ __eht_lookup_create_host(struct net_bridge_port_group *pg, if (br_multicast_eht_hosts_over_limit(pg)) return NULL; - eht_host = kzalloc(sizeof(*eht_host), GFP_ATOMIC); + eht_host = kzalloc_obj(*eht_host, GFP_ATOMIC); if (!eht_host) return NULL; @@ -313,7 +313,7 @@ __eht_lookup_create_set_entry(struct net_bridge *br, if (!allow_zero_src && eht_host->num_entries >= PG_SRC_ENT_LIMIT) return NULL; - set_h = kzalloc(sizeof(*set_h), GFP_ATOMIC); + set_h = kzalloc_obj(*set_h, GFP_ATOMIC); if (!set_h) return NULL; @@ -360,7 +360,7 @@ __eht_lookup_create_set(struct net_bridge_port_group *pg, return this; } - eht_set = kzalloc(sizeof(*eht_set), GFP_ATOMIC); + eht_set = kzalloc_obj(*eht_set, GFP_ATOMIC); if (!eht_set) return NULL; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index b9b2981c4841..9b55d38ea9ed 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -1344,6 +1344,16 @@ br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1, true; } +static inline bool +br_multicast_port_ctx_options_equal(const struct net_bridge_mcast_port *pmctx1, + const struct net_bridge_mcast_port *pmctx2) +{ + return br_multicast_ngroups_get(pmctx1) == + br_multicast_ngroups_get(pmctx2) && + br_multicast_ngroups_get_max(pmctx1) == + br_multicast_ngroups_get_max(pmctx2); +} + static inline bool br_multicast_ctx_matches_vlan_snooping(const struct net_bridge_mcast *brmctx) { diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c index fe3f7bbe86ee..4fac002922d2 100644 --- a/net/bridge/br_switchdev.c +++ b/net/bridge/br_switchdev.c @@ -661,7 +661,7 @@ void br_switchdev_mdb_notify(struct net_device *dev, mdb.obj.orig_dev = pg->key.port->dev; switch (type) { case RTM_NEWMDB: - complete_info = kmalloc(sizeof(*complete_info), GFP_ATOMIC); + complete_info = kmalloc_obj(*complete_info, GFP_ATOMIC); if (!complete_info) break; complete_info->port = pg->key.port; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index ce72b837ff8e..326933b455b3 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -787,7 +787,7 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags, bool *changed, return br_vlan_add_existing(br, vg, vlan, flags, changed, extack); - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return -ENOMEM; @@ -1224,7 +1224,7 @@ int br_vlan_init(struct net_bridge *br) struct net_bridge_vlan_group *vg; int ret = -ENOMEM; - vg = kzalloc(sizeof(*vg), GFP_KERNEL); + vg = kzalloc_obj(*vg); if (!vg) goto out; ret = rhashtable_init(&vg->vlan_hash, &br_vlan_rht_params); @@ -1260,7 +1260,7 @@ int nbp_vlan_init(struct net_bridge_port *p, struct netlink_ext_ack *extack) struct net_bridge_vlan_group *vg; int ret = -ENOMEM; - vg = kzalloc(sizeof(struct net_bridge_vlan_group), GFP_KERNEL); + vg = kzalloc_obj(struct net_bridge_vlan_group); if (!vg) goto out; @@ -1334,7 +1334,7 @@ int nbp_vlan_add(struct net_bridge_port *port, u16 vid, u16 flags, return 0; } - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return -ENOMEM; diff --git a/net/bridge/br_vlan_options.c b/net/bridge/br_vlan_options.c index 8fa89b04ee94..5514e1fc8d1f 100644 --- a/net/bridge/br_vlan_options.c +++ b/net/bridge/br_vlan_options.c @@ -43,9 +43,29 @@ bool br_vlan_opts_eq_range(const struct net_bridge_vlan *v_curr, u8 range_mc_rtr = br_vlan_multicast_router(range_end); u8 curr_mc_rtr = br_vlan_multicast_router(v_curr); - return v_curr->state == range_end->state && - __vlan_tun_can_enter_range(v_curr, range_end) && - curr_mc_rtr == range_mc_rtr; + if (v_curr->state != range_end->state) + return false; + + if (!__vlan_tun_can_enter_range(v_curr, range_end)) + return false; + + if (curr_mc_rtr != range_mc_rtr) + return false; + + /* Check user-visible priv_flags that affect output */ + if ((v_curr->priv_flags ^ range_end->priv_flags) & + (BR_VLFLAG_NEIGH_SUPPRESS_ENABLED | BR_VLFLAG_MCAST_ENABLED)) + return false; + +#ifdef CONFIG_BRIDGE_IGMP_SNOOPING + if (!br_vlan_is_master(v_curr) && + !br_multicast_port_ctx_vlan_disabled(&v_curr->port_mcast_ctx) && + !br_multicast_port_ctx_options_equal(&v_curr->port_mcast_ctx, + &range_end->port_mcast_ctx)) + return false; +#endif + + return true; } bool br_vlan_opts_fill(struct sk_buff *skb, const struct net_bridge_vlan *v, diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index a04fc1757528..aea3e19875c6 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -1303,7 +1303,7 @@ int ebt_register_template(const struct ebt_table *t, int (*table_init)(struct ne } } - tmpl = kzalloc(sizeof(*tmpl), GFP_KERNEL); + tmpl = kzalloc_obj(*tmpl); if (!tmpl) { mutex_unlock(&ebt_mutex); return -ENOMEM; diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 24e85c5487ef..922de3d611c0 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -94,7 +94,7 @@ static struct caif_device_entry *caif_device_alloc(struct net_device *dev) { struct caif_device_entry *caifd; - caifd = kzalloc(sizeof(*caifd), GFP_KERNEL); + caifd = kzalloc_obj(*caifd); if (!caifd) return NULL; caifd->pcpu_refcnt = alloc_percpu(int); diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c index 5dc05a1e3178..4d44960d4c2f 100644 --- a/net/caif/caif_usb.c +++ b/net/caif/caif_usb.c @@ -85,7 +85,7 @@ static void cfusbl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl, static struct cflayer *cfusbl_create(int phyid, const u8 ethaddr[ETH_ALEN], u8 braddr[ETH_ALEN]) { - struct cfusbl *this = kmalloc(sizeof(struct cfusbl), GFP_ATOMIC); + struct cfusbl *this = kmalloc_obj(struct cfusbl, GFP_ATOMIC); if (!this) return NULL; diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 52509e185960..8a80914783e8 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -77,7 +77,7 @@ struct cfcnfg *cfcnfg_create(void) might_sleep(); /* Initiate this layer */ - this = kzalloc(sizeof(struct cfcnfg), GFP_ATOMIC); + this = kzalloc_obj(struct cfcnfg, GFP_ATOMIC); if (!this) return NULL; this->mux = cfmuxl_create(); @@ -477,7 +477,7 @@ cfcnfg_add_phy_layer(struct cfcnfg *cnfg, goto out; got_phyid: - phyinfo = kzalloc(sizeof(struct cfcnfg_phyinfo), GFP_ATOMIC); + phyinfo = kzalloc_obj(struct cfcnfg_phyinfo, GFP_ATOMIC); if (!phyinfo) { res = -ENOMEM; goto out; diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 2aa1e7d46eb2..c6cc2bfed65d 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -36,7 +36,7 @@ struct cflayer *cfctrl_create(void) { struct dev_info dev_info; struct cfctrl *this = - kzalloc(sizeof(struct cfctrl), GFP_ATOMIC); + kzalloc_obj(struct cfctrl, GFP_ATOMIC); if (!this) return NULL; caif_assert(offsetof(struct cfctrl, serv.layer) == 0); @@ -270,7 +270,7 @@ int cfctrl_linkup_request(struct cflayer *layer, cfpkt_destroy(pkt); return -EINVAL; } - req = kzalloc(sizeof(*req), GFP_KERNEL); + req = kzalloc_obj(*req); if (!req) { cfpkt_destroy(pkt); return -ENOMEM; diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 77f428428b47..57ad3f82e004 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c @@ -19,7 +19,7 @@ static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); struct cflayer *cfdbgl_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *dbg = kzalloc(sizeof(struct cfsrvl), GFP_ATOMIC); + struct cfsrvl *dbg = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); if (!dbg) return NULL; caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cfdgml.c b/net/caif/cfdgml.c index eb6f8ef47a79..c451ddd155a7 100644 --- a/net/caif/cfdgml.c +++ b/net/caif/cfdgml.c @@ -26,7 +26,7 @@ static int cfdgml_transmit(struct cflayer *layr, struct cfpkt *pkt); struct cflayer *cfdgml_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *dgm = kzalloc(sizeof(struct cfsrvl), GFP_ATOMIC); + struct cfsrvl *dgm = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); if (!dgm) return NULL; caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cffrml.c b/net/caif/cffrml.c index d4d63586053a..0f4979d89fcb 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c @@ -34,7 +34,7 @@ static u32 cffrml_rcv_error; static u32 cffrml_rcv_checsum_error; struct cflayer *cffrml_create(u16 phyid, bool use_fcs) { - struct cffrml *this = kzalloc(sizeof(struct cffrml), GFP_ATOMIC); + struct cffrml *this = kzalloc_obj(struct cffrml, GFP_ATOMIC); if (!this) return NULL; this->pcpu_refcnt = alloc_percpu(int); diff --git a/net/caif/cfmuxl.c b/net/caif/cfmuxl.c index 4172b0d0db63..77a1f31639b7 100644 --- a/net/caif/cfmuxl.c +++ b/net/caif/cfmuxl.c @@ -47,7 +47,7 @@ static struct cflayer *get_up(struct cfmuxl *muxl, u16 id); struct cflayer *cfmuxl_create(void) { - struct cfmuxl *this = kzalloc(sizeof(struct cfmuxl), GFP_ATOMIC); + struct cfmuxl *this = kzalloc_obj(struct cfmuxl, GFP_ATOMIC); if (!this) return NULL; diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index 3c335057f255..93732ebbd1e2 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -46,7 +46,7 @@ struct cflayer *cfrfml_create(u8 channel_id, struct dev_info *dev_info, int mtu_size) { int tmp; - struct cfrfml *this = kzalloc(sizeof(struct cfrfml), GFP_ATOMIC); + struct cfrfml *this = kzalloc_obj(struct cfrfml, GFP_ATOMIC); if (!this) return NULL; diff --git a/net/caif/cfserl.c b/net/caif/cfserl.c index aee11c74d3c8..faf78fb754e2 100644 --- a/net/caif/cfserl.c +++ b/net/caif/cfserl.c @@ -38,7 +38,7 @@ void cfserl_release(struct cflayer *layer) struct cflayer *cfserl_create(int instance, bool use_stx) { - struct cfserl *this = kzalloc(sizeof(struct cfserl), GFP_ATOMIC); + struct cfserl *this = kzalloc_obj(struct cfserl, GFP_ATOMIC); if (!this) return NULL; caif_assert(offsetof(struct cfserl, layer) == 0); diff --git a/net/caif/cfutill.c b/net/caif/cfutill.c index b2e47ede912f..5111090bb2c0 100644 --- a/net/caif/cfutill.c +++ b/net/caif/cfutill.c @@ -26,7 +26,7 @@ static int cfutill_transmit(struct cflayer *layr, struct cfpkt *pkt); struct cflayer *cfutill_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *util = kzalloc(sizeof(struct cfsrvl), GFP_ATOMIC); + struct cfsrvl *util = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); if (!util) return NULL; caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index db2274b94a5d..53f844c49bbb 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -25,7 +25,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt); struct cflayer *cfvei_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *vei = kzalloc(sizeof(struct cfsrvl), GFP_ATOMIC); + struct cfsrvl *vei = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); if (!vei) return NULL; caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/caif/cfvidl.c b/net/caif/cfvidl.c index 134bad43196c..39e075b0a259 100644 --- a/net/caif/cfvidl.c +++ b/net/caif/cfvidl.c @@ -21,7 +21,7 @@ static int cfvidl_transmit(struct cflayer *layr, struct cfpkt *pkt); struct cflayer *cfvidl_create(u8 channel_id, struct dev_info *dev_info) { - struct cfsrvl *vid = kzalloc(sizeof(struct cfsrvl), GFP_ATOMIC); + struct cfsrvl *vid = kzalloc_obj(struct cfsrvl, GFP_ATOMIC); if (!vid) return NULL; caif_assert(offsetof(struct cfsrvl, layer) == 0); diff --git a/net/can/af_can.c b/net/can/af_can.c index 22c65a014861..f70e2ba0aadc 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -798,14 +798,13 @@ EXPORT_SYMBOL(can_proto_unregister); static int can_pernet_init(struct net *net) { spin_lock_init(&net->can.rcvlists_lock); - net->can.rx_alldev_list = - kzalloc(sizeof(*net->can.rx_alldev_list), GFP_KERNEL); + net->can.rx_alldev_list = kzalloc_obj(*net->can.rx_alldev_list); if (!net->can.rx_alldev_list) goto out; - net->can.pkg_stats = kzalloc(sizeof(*net->can.pkg_stats), GFP_KERNEL); + net->can.pkg_stats = kzalloc_obj(*net->can.pkg_stats); if (!net->can.pkg_stats) goto out_free_rx_alldev_list; - net->can.rcv_lists_stats = kzalloc(sizeof(*net->can.rcv_lists_stats), GFP_KERNEL); + net->can.rcv_lists_stats = kzalloc_obj(*net->can.rcv_lists_stats); if (!net->can.rcv_lists_stats) goto out_free_pkg_stats; diff --git a/net/can/bcm.c b/net/can/bcm.c index b7324e9c955b..fd9fa072881e 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c @@ -1176,6 +1176,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, if (!op) return -ENOMEM; + spin_lock_init(&op->bcm_tx_lock); op->can_id = msg_head->can_id; op->nframes = msg_head->nframes; op->cfsiz = CFSIZ(msg_head->flags); diff --git a/net/can/gw.c b/net/can/gw.c index 61a1e6b1b83f..8ee4d67a07d3 100644 --- a/net/can/gw.c +++ b/net/can/gw.c @@ -1099,7 +1099,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh, if (r->gwtype != CGW_TYPE_CAN_CAN) return -EINVAL; - mod = kmalloc(sizeof(*mod), GFP_KERNEL); + mod = kmalloc_obj(*mod); if (!mod) return -ENOMEM; diff --git a/net/can/j1939/bus.c b/net/can/j1939/bus.c index 797719cb227e..dc374286eeb6 100644 --- a/net/can/j1939/bus.c +++ b/net/can/j1939/bus.c @@ -151,7 +151,7 @@ struct j1939_ecu *j1939_ecu_create_locked(struct j1939_priv *priv, name_t name) lockdep_assert_held(&priv->lock); - ecu = kzalloc(sizeof(*ecu), gfp_any()); + ecu = kzalloc_obj(*ecu, gfp_any()); if (!ecu) return ERR_PTR(-ENOMEM); kref_init(&ecu->kref); diff --git a/net/can/j1939/main.c b/net/can/j1939/main.c index a93af55df5fd..9937c04241bc 100644 --- a/net/can/j1939/main.c +++ b/net/can/j1939/main.c @@ -128,7 +128,7 @@ static struct j1939_priv *j1939_priv_create(struct net_device *ndev) { struct j1939_priv *priv; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return NULL; diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c index 2cbe94fc487a..df93d57907da 100644 --- a/net/can/j1939/transport.c +++ b/net/can/j1939/transport.c @@ -1508,7 +1508,7 @@ static struct j1939_session *j1939_session_new(struct j1939_priv *priv, struct j1939_session *session; struct j1939_sk_buff_cb *skcb; - session = kzalloc(sizeof(*session), gfp_any()); + session = kzalloc_obj(*session, gfp_any()); if (!session) return NULL; diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig index ea60e3ef0834..7e2528cde4b9 100644 --- a/net/ceph/Kconfig +++ b/net/ceph/Kconfig @@ -6,6 +6,7 @@ config CEPH_LIB select CRYPTO_AES select CRYPTO_CBC select CRYPTO_GCM + select CRYPTO_KRB5 select CRYPTO_LIB_SHA256 select CRYPTO select KEYS diff --git a/net/ceph/auth.c b/net/ceph/auth.c index d38c9eadbe2f..901b93530b21 100644 --- a/net/ceph/auth.c +++ b/net/ceph/auth.c @@ -59,7 +59,7 @@ struct ceph_auth_client *ceph_auth_init(const char *name, { struct ceph_auth_client *ac; - ac = kzalloc(sizeof(*ac), GFP_NOFS); + ac = kzalloc_obj(*ac, GFP_NOFS); if (!ac) return ERR_PTR(-ENOMEM); @@ -205,9 +205,9 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, s32 result; u64 global_id; void *payload, *payload_end; - int payload_len; + u32 payload_len; char *result_msg; - int result_msg_len; + u32 result_msg_len; int ret = -EINVAL; mutex_lock(&ac->mutex); @@ -217,10 +217,12 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac, result = ceph_decode_32(&p); global_id = ceph_decode_64(&p); payload_len = ceph_decode_32(&p); + ceph_decode_need(&p, end, payload_len, bad); payload = p; p += payload_len; ceph_decode_need(&p, end, sizeof(u32), bad); result_msg_len = ceph_decode_32(&p); + ceph_decode_need(&p, end, result_msg_len, bad); result_msg = p; p += result_msg_len; if (p != end) diff --git a/net/ceph/auth_none.c b/net/ceph/auth_none.c index 77b5519bc45f..99e1f3e10a4c 100644 --- a/net/ceph/auth_none.c +++ b/net/ceph/auth_none.c @@ -97,7 +97,7 @@ static int ceph_auth_none_create_authorizer( struct ceph_none_authorizer *au; int ret; - au = kmalloc(sizeof(*au), GFP_NOFS); + au = kmalloc_obj(*au, GFP_NOFS); if (!au) return -ENOMEM; @@ -133,7 +133,7 @@ int ceph_auth_none_init(struct ceph_auth_client *ac) struct ceph_auth_none_info *xi; dout("ceph_auth_none_init %p\n", ac); - xi = kzalloc(sizeof(*xi), GFP_NOFS); + xi = kzalloc_obj(*xi, GFP_NOFS); if (!xi) return -ENOMEM; diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c index a21c157daf7d..692e0b868822 100644 --- a/net/ceph/auth_x.c +++ b/net/ceph/auth_x.c @@ -17,6 +17,22 @@ #include "auth_x.h" #include "auth_x_protocol.h" +static const u32 ticket_key_usages[] = { + CEPHX_KEY_USAGE_TICKET_SESSION_KEY, + CEPHX_KEY_USAGE_TICKET_BLOB, + CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET +}; + +static const u32 authorizer_key_usages[] = { + CEPHX_KEY_USAGE_AUTHORIZE, + CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE, + CEPHX_KEY_USAGE_AUTHORIZE_REPLY +}; + +static const u32 client_key_usages[] = { + CEPHX_KEY_USAGE_TICKET_SESSION_KEY +}; + static void ceph_x_validate_tickets(struct ceph_auth_client *ac, int *pneed); static int ceph_x_is_authenticated(struct ceph_auth_client *ac) @@ -44,28 +60,41 @@ static int ceph_x_should_authenticate(struct ceph_auth_client *ac) return !!need; } -static int ceph_x_encrypt_offset(void) +static int __ceph_x_encrypt_offset(const struct ceph_crypto_key *key) { - return sizeof(u32) + sizeof(struct ceph_x_encrypt_header); + return ceph_crypt_data_offset(key) + + sizeof(struct ceph_x_encrypt_header); } -static int ceph_x_encrypt_buflen(int ilen) +static int ceph_x_encrypt_offset(const struct ceph_crypto_key *key) { - return ceph_x_encrypt_offset() + ilen + 16; + return sizeof(u32) + __ceph_x_encrypt_offset(key); } -static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, - int buf_len, int plaintext_len) +/* + * AES: ciphertext_len | hdr | data... | padding + * AES256KRB5: ciphertext_len | confounder | hdr | data... | hmac + */ +static int ceph_x_encrypt_buflen(const struct ceph_crypto_key *key, + int data_len) { - struct ceph_x_encrypt_header *hdr = buf + sizeof(u32); + int encrypt_len = sizeof(struct ceph_x_encrypt_header) + data_len; + return sizeof(u32) + ceph_crypt_buflen(key, encrypt_len); +} + +static int ceph_x_encrypt(const struct ceph_crypto_key *key, int usage_slot, + void *buf, int buf_len, int plaintext_len) +{ + struct ceph_x_encrypt_header *hdr; int ciphertext_len; int ret; + hdr = buf + sizeof(u32) + ceph_crypt_data_offset(key); hdr->struct_v = 1; hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC); - ret = ceph_crypt(secret, true, buf + sizeof(u32), buf_len - sizeof(u32), - plaintext_len + sizeof(struct ceph_x_encrypt_header), + ret = ceph_crypt(key, usage_slot, true, buf + sizeof(u32), + buf_len - sizeof(u32), plaintext_len + sizeof(*hdr), &ciphertext_len); if (ret) return ret; @@ -74,18 +103,19 @@ static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, return sizeof(u32) + ciphertext_len; } -static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p, - int ciphertext_len) +static int __ceph_x_decrypt(const struct ceph_crypto_key *key, int usage_slot, + void *p, int ciphertext_len) { - struct ceph_x_encrypt_header *hdr = p; + struct ceph_x_encrypt_header *hdr; int plaintext_len; int ret; - ret = ceph_crypt(secret, false, p, ciphertext_len, ciphertext_len, - &plaintext_len); + ret = ceph_crypt(key, usage_slot, false, p, ciphertext_len, + ciphertext_len, &plaintext_len); if (ret) return ret; + hdr = p + ceph_crypt_data_offset(key); if (le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) { pr_err("%s bad magic\n", __func__); return -EINVAL; @@ -94,7 +124,8 @@ static int __ceph_x_decrypt(struct ceph_crypto_key *secret, void *p, return plaintext_len - sizeof(*hdr); } -static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end) +static int ceph_x_decrypt(const struct ceph_crypto_key *key, int usage_slot, + void **p, void *end) { int ciphertext_len; int ret; @@ -102,7 +133,7 @@ static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end) ceph_decode_32_safe(p, end, ciphertext_len, e_inval); ceph_decode_need(p, end, ciphertext_len, e_inval); - ret = __ceph_x_decrypt(secret, *p, ciphertext_len); + ret = __ceph_x_decrypt(key, usage_slot, *p, ciphertext_len); if (ret < 0) return ret; @@ -135,7 +166,7 @@ get_ticket_handler(struct ceph_auth_client *ac, int service) } /* add it */ - th = kzalloc(sizeof(*th), GFP_NOFS); + th = kzalloc_obj(*th, GFP_NOFS); if (!th) return ERR_PTR(-ENOMEM); th->service = service; @@ -193,8 +224,10 @@ static int process_one_ticket(struct ceph_auth_client *ac, } /* blob for me */ - dp = *p + ceph_x_encrypt_offset(); - ret = ceph_x_decrypt(secret, p, end); + dp = *p + ceph_x_encrypt_offset(secret); + ret = ceph_x_decrypt(secret, + 0 /* CEPHX_KEY_USAGE_TICKET_SESSION_KEY */, + p, end); if (ret < 0) goto out; dout(" decrypted %d bytes\n", ret); @@ -208,6 +241,11 @@ static int process_one_ticket(struct ceph_auth_client *ac, if (ret) goto out; + ret = ceph_crypto_key_prepare(&new_session_key, ticket_key_usages, + ARRAY_SIZE(ticket_key_usages)); + if (ret) + goto out; + ceph_decode_need(&dp, dend, sizeof(struct ceph_timespec), bad); ceph_decode_timespec64(&validity, dp); dp += sizeof(struct ceph_timespec); @@ -220,8 +258,10 @@ static int process_one_ticket(struct ceph_auth_client *ac, ceph_decode_8_safe(p, end, is_enc, bad); if (is_enc) { /* encrypted */ - tp = *p + ceph_x_encrypt_offset(); - ret = ceph_x_decrypt(&th->session_key, p, end); + tp = *p + ceph_x_encrypt_offset(&th->session_key); + ret = ceph_x_decrypt(&th->session_key, + 1 /* CEPHX_KEY_USAGE_TICKET_BLOB */, + p, end); if (ret < 0) goto out; dout(" encrypted ticket, decrypted %d bytes\n", ret); @@ -312,7 +352,7 @@ static int encrypt_authorizer(struct ceph_x_authorizer *au, p = (void *)(msg_a + 1) + le32_to_cpu(msg_a->ticket_blob.blob_len); end = au->buf->vec.iov_base + au->buf->vec.iov_len; - msg_b = p + ceph_x_encrypt_offset(); + msg_b = p + ceph_x_encrypt_offset(&au->session_key); msg_b->struct_v = 2; msg_b->nonce = cpu_to_le64(au->nonce); if (server_challenge) { @@ -324,7 +364,9 @@ static int encrypt_authorizer(struct ceph_x_authorizer *au, msg_b->server_challenge_plus_one = 0; } - ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b)); + ret = ceph_x_encrypt(&au->session_key, + 0 /* CEPHX_KEY_USAGE_AUTHORIZE */, + p, end - p, sizeof(*msg_b)); if (ret < 0) return ret; @@ -367,8 +409,13 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac, if (ret) goto out_au; + ret = ceph_crypto_key_prepare(&au->session_key, authorizer_key_usages, + ARRAY_SIZE(authorizer_key_usages)); + if (ret) + goto out_au; + maxlen = sizeof(*msg_a) + ticket_blob_len + - ceph_x_encrypt_buflen(sizeof(*msg_b)); + ceph_x_encrypt_buflen(&au->session_key, sizeof(*msg_b)); dout(" need len %d\n", maxlen); if (au->buf && au->buf->alloc_len < maxlen) { ceph_buffer_put(au->buf); @@ -506,8 +553,7 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, if (need & CEPH_ENTITY_TYPE_AUTH) { struct ceph_x_authenticate *auth = (void *)(head + 1); void *enc_buf = xi->auth_authorizer.enc_buf; - struct ceph_x_challenge_blob *blob = enc_buf + - ceph_x_encrypt_offset(); + struct ceph_x_challenge_blob *blob; u64 *u; p = auth + 1; @@ -517,14 +563,29 @@ static int ceph_x_build_request(struct ceph_auth_client *ac, dout(" get_auth_session_key\n"); head->op = cpu_to_le16(CEPHX_GET_AUTH_SESSION_KEY); - /* encrypt and hash */ + if (xi->secret.type == CEPH_CRYPTO_AES) { + blob = enc_buf + ceph_x_encrypt_offset(&xi->secret); + } else { + BUILD_BUG_ON(SHA256_DIGEST_SIZE + sizeof(*blob) > + CEPHX_AU_ENC_BUF_LEN); + blob = enc_buf + SHA256_DIGEST_SIZE; + } + get_random_bytes(&auth->client_challenge, sizeof(u64)); blob->client_challenge = auth->client_challenge; blob->server_challenge = cpu_to_le64(xi->server_challenge); - ret = ceph_x_encrypt(&xi->secret, enc_buf, CEPHX_AU_ENC_BUF_LEN, - sizeof(*blob)); - if (ret < 0) - return ret; + + if (xi->secret.type == CEPH_CRYPTO_AES) { + ret = ceph_x_encrypt(&xi->secret, 0 /* dummy */, + enc_buf, CEPHX_AU_ENC_BUF_LEN, + sizeof(*blob)); + if (ret < 0) + return ret; + } else { + ceph_hmac_sha256(&xi->secret, blob, sizeof(*blob), + enc_buf); + ret = SHA256_DIGEST_SIZE; + } auth->struct_v = 3; /* nautilus+ */ auth->key = 0; @@ -634,8 +695,10 @@ static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id, ceph_decode_need(p, end, len, e_inval); dout("%s connection secret blob len %d\n", __func__, len); if (len > 0) { - dp = *p + ceph_x_encrypt_offset(); - ret = ceph_x_decrypt(&th->session_key, p, *p + len); + dp = *p + ceph_x_encrypt_offset(&th->session_key); + ret = ceph_x_decrypt(&th->session_key, + 2 /* CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET */, + p, *p + len); if (ret < 0) return ret; @@ -745,7 +808,7 @@ static int ceph_x_create_authorizer( if (IS_ERR(th)) return PTR_ERR(th); - au = kzalloc(sizeof(*au), GFP_NOFS); + au = kzalloc_obj(*au, GFP_NOFS); if (!au) return -ENOMEM; @@ -799,12 +862,14 @@ static int decrypt_authorizer_challenge(struct ceph_crypto_key *secret, int ret; /* no leading len */ - ret = __ceph_x_decrypt(secret, challenge, challenge_len); + ret = __ceph_x_decrypt(secret, + 1 /* CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE */, + challenge, challenge_len); if (ret < 0) return ret; dout("%s decrypted %d bytes\n", __func__, ret); - dp = challenge + sizeof(struct ceph_x_encrypt_header); + dp = challenge + __ceph_x_encrypt_offset(secret); dend = dp + ret; ceph_decode_skip_8(&dp, dend, e_inval); /* struct_v */ @@ -851,8 +916,9 @@ static int decrypt_authorizer_reply(struct ceph_crypto_key *secret, u8 struct_v; int ret; - dp = *p + ceph_x_encrypt_offset(); - ret = ceph_x_decrypt(secret, p, end); + dp = *p + ceph_x_encrypt_offset(secret); + ret = ceph_x_decrypt(secret, 2 /* CEPHX_KEY_USAGE_AUTHORIZE_REPLY */, + p, end); if (ret < 0) return ret; @@ -974,7 +1040,8 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, __le32 front_crc; __le32 middle_crc; __le32 data_crc; - } __packed *sigblock = enc_buf + ceph_x_encrypt_offset(); + } __packed *sigblock = enc_buf + + ceph_x_encrypt_offset(&au->session_key); sigblock->len = cpu_to_le32(4*sizeof(u32)); sigblock->header_crc = msg->hdr.crc; @@ -982,8 +1049,9 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, sigblock->middle_crc = msg->footer.middle_crc; sigblock->data_crc = msg->footer.data_crc; - ret = ceph_x_encrypt(&au->session_key, enc_buf, - CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock)); + ret = ceph_x_encrypt(&au->session_key, 0 /* dummy */, + enc_buf, CEPHX_AU_ENC_BUF_LEN, + sizeof(*sigblock)); if (ret < 0) return ret; @@ -998,11 +1066,19 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, __le32 data_crc; __le32 data_len; __le32 seq_lower_word; - } __packed *sigblock = enc_buf; + } __packed *sigblock; struct { __le64 a, b, c, d; } __packed *penc = enc_buf; - int ciphertext_len; + + if (au->session_key.type == CEPH_CRYPTO_AES) { + /* no leading len, no ceph_x_encrypt_header */ + sigblock = enc_buf; + } else { + BUILD_BUG_ON(SHA256_DIGEST_SIZE + sizeof(*sigblock) > + CEPHX_AU_ENC_BUF_LEN); + sigblock = enc_buf + SHA256_DIGEST_SIZE; + } sigblock->header_crc = msg->hdr.crc; sigblock->front_crc = msg->footer.front_crc; @@ -1013,12 +1089,18 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, sigblock->data_len = msg->hdr.data_len; sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq; - /* no leading len, no ceph_x_encrypt_header */ - ret = ceph_crypt(&au->session_key, true, enc_buf, - CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock), - &ciphertext_len); - if (ret) - return ret; + if (au->session_key.type == CEPH_CRYPTO_AES) { + int ciphertext_len; /* unused */ + + ret = ceph_crypt(&au->session_key, 0 /* dummy */, + true, enc_buf, CEPHX_AU_ENC_BUF_LEN, + sizeof(*sigblock), &ciphertext_len); + if (ret) + return ret; + } else { + ceph_hmac_sha256(&au->session_key, sigblock, + sizeof(*sigblock), enc_buf); + } *psig = penc->a ^ penc->b ^ penc->c ^ penc->d; } @@ -1092,21 +1174,27 @@ int ceph_x_init(struct ceph_auth_client *ac) int ret; dout("ceph_x_init %p\n", ac); - ret = -ENOMEM; - xi = kzalloc(sizeof(*xi), GFP_NOFS); + xi = kzalloc_obj(*xi, GFP_NOFS); if (!xi) - goto out; + return -ENOMEM; ret = -EINVAL; if (!ac->key) { pr_err("no secret set (for auth_x protocol)\n"); - goto out_nomem; + goto err_xi; } ret = ceph_crypto_key_clone(&xi->secret, ac->key); if (ret < 0) { pr_err("cannot clone key: %d\n", ret); - goto out_nomem; + goto err_xi; + } + + ret = ceph_crypto_key_prepare(&xi->secret, client_key_usages, + ARRAY_SIZE(client_key_usages)); + if (ret) { + pr_err("cannot prepare key: %d\n", ret); + goto err_secret; } xi->starting = true; @@ -1117,8 +1205,9 @@ int ceph_x_init(struct ceph_auth_client *ac) ac->ops = &ceph_x_ops; return 0; -out_nomem: +err_secret: + ceph_crypto_key_destroy(&xi->secret); +err_xi: kfree(xi); -out: return ret; } diff --git a/net/ceph/auth_x_protocol.h b/net/ceph/auth_x_protocol.h index 9c60feeb1bcb..d097b3651c99 100644 --- a/net/ceph/auth_x_protocol.h +++ b/net/ceph/auth_x_protocol.h @@ -6,6 +6,44 @@ #define CEPHX_GET_PRINCIPAL_SESSION_KEY 0x0200 #define CEPHX_GET_ROTATING_KEY 0x0400 +/* Client <-> AuthMonitor */ +/* + * The AUTH session's connection secret: encrypted with the AUTH + * ticket session key + */ +#define CEPHX_KEY_USAGE_AUTH_CONNECTION_SECRET 0x03 +/* + * The ticket's blob for the client ("blob for me", contains the + * session key): encrypted with the client's secret key in case of + * the AUTH ticket and the AUTH ticket session key in case of other + * service tickets + */ +#define CEPHX_KEY_USAGE_TICKET_SESSION_KEY 0x04 +/* + * The ticket's blob for the service (ceph_x_ticket_blob): possibly + * encrypted with the old AUTH ticket session key in case of the AUTH + * ticket and not encrypted in case of other service tickets + */ +#define CEPHX_KEY_USAGE_TICKET_BLOB 0x05 + +/* Client <-> Service */ +/* + * The client's authorization request (ceph_x_authorize_b): + * encrypted with the service ticket session key + */ +#define CEPHX_KEY_USAGE_AUTHORIZE 0x10 +/* + * The service's challenge (ceph_x_authorize_challenge): + * encrypted with the service ticket session key + */ +#define CEPHX_KEY_USAGE_AUTHORIZE_CHALLENGE 0x11 +/* + * The service's final reply (ceph_x_authorize_reply + the service + * session's connection secret): encrypted with the service ticket + * session key + */ +#define CEPHX_KEY_USAGE_AUTHORIZE_REPLY 0x12 + /* common bits */ struct ceph_x_ticket_blob { __u8 struct_v; diff --git a/net/ceph/buffer.c b/net/ceph/buffer.c index 7e51f128045d..98c2ac4387ae 100644 --- a/net/ceph/buffer.c +++ b/net/ceph/buffer.c @@ -13,7 +13,7 @@ struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) { struct ceph_buffer *b; - b = kmalloc(sizeof(*b), gfp); + b = kmalloc_obj(*b, gfp); if (!b) return NULL; diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index e734e57be083..952121849180 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c @@ -309,13 +309,12 @@ struct ceph_options *ceph_alloc_options(void) { struct ceph_options *opt; - opt = kzalloc(sizeof(*opt), GFP_KERNEL); + opt = kzalloc_obj(*opt); if (!opt) return NULL; opt->crush_locs = RB_ROOT; - opt->mon_addr = kcalloc(CEPH_MAX_MON, sizeof(*opt->mon_addr), - GFP_KERNEL); + opt->mon_addr = kzalloc_objs(*opt->mon_addr, CEPH_MAX_MON); if (!opt->mon_addr) { kfree(opt); return NULL; @@ -456,7 +455,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, ceph_crypto_key_destroy(opt->key); kfree(opt->key); - opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + opt->key = kzalloc_obj(*opt->key); if (!opt->key) return -ENOMEM; err = ceph_crypto_key_unarmor(opt->key, param->string); @@ -469,7 +468,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt, ceph_crypto_key_destroy(opt->key); kfree(opt->key); - opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL); + opt->key = kzalloc_obj(*opt->key); if (!opt->key) return -ENOMEM; return get_secret(opt->key, param->string, &log); @@ -714,7 +713,7 @@ struct ceph_client *ceph_create_client(struct ceph_options *opt, void *private) if (err < 0) return ERR_PTR(err); - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (client == NULL) return ERR_PTR(-ENOMEM); diff --git a/net/ceph/cls_lock_client.c b/net/ceph/cls_lock_client.c index 66136a4c1ce7..c6956f1df333 100644 --- a/net/ceph/cls_lock_client.c +++ b/net/ceph/cls_lock_client.c @@ -300,7 +300,7 @@ static int decode_lockers(void **p, void *end, u8 *type, char **tag, return ret; *num_lockers = ceph_decode_32(p); - *lockers = kcalloc(*num_lockers, sizeof(**lockers), GFP_NOIO); + *lockers = kzalloc_objs(**lockers, *num_lockers, GFP_NOIO); if (!*lockers) return -ENOMEM; diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 01b2ce1e8fc0..de7496791c91 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,77 +17,119 @@ #include #include "crypto.h" -/* - * Set ->key and ->tfm. The rest of the key should be filled in before - * this function is called. - */ -static int set_secret(struct ceph_crypto_key *key, void *buf) +static int set_aes_tfm(struct ceph_crypto_key *key) { unsigned int noio_flag; int ret; - key->key = NULL; - key->tfm = NULL; + noio_flag = memalloc_noio_save(); + key->aes_tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); + memalloc_noio_restore(noio_flag); + if (IS_ERR(key->aes_tfm)) { + ret = PTR_ERR(key->aes_tfm); + key->aes_tfm = NULL; + return ret; + } + ret = crypto_sync_skcipher_setkey(key->aes_tfm, key->key, key->len); + if (ret) + return ret; + + return 0; +} + +static int set_krb5_tfms(struct ceph_crypto_key *key, const u32 *key_usages, + int key_usage_cnt) +{ + struct krb5_buffer TK = { .len = key->len, .data = key->key }; + unsigned int noio_flag; + int ret = 0; + int i; + + if (WARN_ON_ONCE(key_usage_cnt > ARRAY_SIZE(key->krb5_tfms))) + return -EINVAL; + + key->krb5_type = crypto_krb5_find_enctype( + KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192); + if (!key->krb5_type) + return -ENOPKG; + + /* + * Despite crypto_krb5_prepare_encryption() taking a gfp mask, + * crypto_alloc_aead() inside of it allocates with GFP_KERNEL. + */ + noio_flag = memalloc_noio_save(); + for (i = 0; i < key_usage_cnt; i++) { + key->krb5_tfms[i] = crypto_krb5_prepare_encryption( + key->krb5_type, &TK, key_usages[i], + GFP_NOIO); + if (IS_ERR(key->krb5_tfms[i])) { + ret = PTR_ERR(key->krb5_tfms[i]); + key->krb5_tfms[i] = NULL; + goto out_flag; + } + } + +out_flag: + memalloc_noio_restore(noio_flag); + return ret; +} + +int ceph_crypto_key_prepare(struct ceph_crypto_key *key, + const u32 *key_usages, int key_usage_cnt) +{ switch (key->type) { case CEPH_CRYPTO_NONE: return 0; /* nothing to do */ case CEPH_CRYPTO_AES: - break; + return set_aes_tfm(key); + case CEPH_CRYPTO_AES256KRB5: + hmac_sha256_preparekey(&key->hmac_key, key->key, key->len); + return set_krb5_tfms(key, key_usages, key_usage_cnt); default: return -ENOTSUPP; } - - if (!key->len) - return -EINVAL; - - key->key = kmemdup(buf, key->len, GFP_NOIO); - if (!key->key) { - ret = -ENOMEM; - goto fail; - } - - /* crypto_alloc_sync_skcipher() allocates with GFP_KERNEL */ - noio_flag = memalloc_noio_save(); - key->tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0); - memalloc_noio_restore(noio_flag); - if (IS_ERR(key->tfm)) { - ret = PTR_ERR(key->tfm); - key->tfm = NULL; - goto fail; - } - - ret = crypto_sync_skcipher_setkey(key->tfm, key->key, key->len); - if (ret) - goto fail; - - return 0; - -fail: - ceph_crypto_key_destroy(key); - return ret; } +/* + * @dst should be zeroed before this function is called. + */ int ceph_crypto_key_clone(struct ceph_crypto_key *dst, const struct ceph_crypto_key *src) { - memcpy(dst, src, sizeof(struct ceph_crypto_key)); - return set_secret(dst, src->key); + dst->type = src->type; + dst->created = src->created; + dst->len = src->len; + + dst->key = kmemdup(src->key, src->len, GFP_NOIO); + if (!dst->key) + return -ENOMEM; + + return 0; } +/* + * @key should be zeroed before this function is called. + */ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end) { - int ret; - ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad); key->type = ceph_decode_16(p); ceph_decode_copy(p, &key->created, sizeof(key->created)); key->len = ceph_decode_16(p); ceph_decode_need(p, end, key->len, bad); - ret = set_secret(key, *p); + if (key->len > CEPH_MAX_KEY_LEN) { + pr_err("secret too big %d\n", key->len); + return -EINVAL; + } + + key->key = kmemdup(*p, key->len, GFP_NOIO); + if (!key->key) + return -ENOMEM; + memzero_explicit(*p, key->len); *p += key->len; - return ret; + return 0; bad: dout("failed to decode crypto key\n"); @@ -122,12 +165,26 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey) void ceph_crypto_key_destroy(struct ceph_crypto_key *key) { - if (key) { - kfree_sensitive(key->key); - key->key = NULL; - if (key->tfm) { - crypto_free_sync_skcipher(key->tfm); - key->tfm = NULL; + int i; + + if (!key) + return; + + kfree_sensitive(key->key); + key->key = NULL; + + if (key->type == CEPH_CRYPTO_AES) { + if (key->aes_tfm) { + crypto_free_sync_skcipher(key->aes_tfm); + key->aes_tfm = NULL; + } + } else if (key->type == CEPH_CRYPTO_AES256KRB5) { + memzero_explicit(&key->hmac_key, sizeof(key->hmac_key)); + for (i = 0; i < ARRAY_SIZE(key->krb5_tfms); i++) { + if (key->krb5_tfms[i]) { + crypto_free_aead(key->krb5_tfms[i]); + key->krb5_tfms[i] = NULL; + } } } } @@ -207,7 +264,7 @@ static void teardown_sgtable(struct sg_table *sgt) static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, void *buf, int buf_len, int in_len, int *pout_len) { - SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->tfm); + SYNC_SKCIPHER_REQUEST_ON_STACK(req, key->aes_tfm); struct sg_table sgt; struct scatterlist prealloc_sg; char iv[AES_BLOCK_SIZE] __aligned(8); @@ -223,7 +280,7 @@ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, return ret; memcpy(iv, aes_iv, AES_BLOCK_SIZE); - skcipher_request_set_sync_tfm(req, key->tfm); + skcipher_request_set_sync_tfm(req, key->aes_tfm); skcipher_request_set_callback(req, 0, NULL, NULL); skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv); @@ -268,7 +325,68 @@ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, return ret; } -int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, +static int ceph_krb5_encrypt(const struct ceph_crypto_key *key, int usage_slot, + void *buf, int buf_len, int in_len, int *pout_len) +{ + struct sg_table sgt; + struct scatterlist prealloc_sg; + int ret; + + if (WARN_ON_ONCE(usage_slot >= ARRAY_SIZE(key->krb5_tfms))) + return -EINVAL; + + ret = setup_sgtable(&sgt, &prealloc_sg, buf, buf_len); + if (ret) + return ret; + + ret = crypto_krb5_encrypt(key->krb5_type, key->krb5_tfms[usage_slot], + sgt.sgl, sgt.nents, buf_len, AES_BLOCK_SIZE, + in_len, false); + if (ret < 0) { + pr_err("%s encrypt failed: %d\n", __func__, ret); + goto out_sgt; + } + + *pout_len = ret; + ret = 0; + +out_sgt: + teardown_sgtable(&sgt); + return ret; +} + +static int ceph_krb5_decrypt(const struct ceph_crypto_key *key, int usage_slot, + void *buf, int buf_len, int in_len, int *pout_len) +{ + struct sg_table sgt; + struct scatterlist prealloc_sg; + size_t data_off = 0; + size_t data_len = in_len; + int ret; + + if (WARN_ON_ONCE(usage_slot >= ARRAY_SIZE(key->krb5_tfms))) + return -EINVAL; + + ret = setup_sgtable(&sgt, &prealloc_sg, buf, in_len); + if (ret) + return ret; + + ret = crypto_krb5_decrypt(key->krb5_type, key->krb5_tfms[usage_slot], + sgt.sgl, sgt.nents, &data_off, &data_len); + if (ret) { + pr_err("%s decrypt failed: %d\n", __func__, ret); + goto out_sgt; + } + + WARN_ON(data_off != AES_BLOCK_SIZE); + *pout_len = data_len; + +out_sgt: + teardown_sgtable(&sgt); + return ret; +} + +int ceph_crypt(const struct ceph_crypto_key *key, int usage_slot, bool encrypt, void *buf, int buf_len, int in_len, int *pout_len) { switch (key->type) { @@ -278,11 +396,64 @@ int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, case CEPH_CRYPTO_AES: return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len, pout_len); + case CEPH_CRYPTO_AES256KRB5: + return encrypt ? + ceph_krb5_encrypt(key, usage_slot, buf, buf_len, in_len, + pout_len) : + ceph_krb5_decrypt(key, usage_slot, buf, buf_len, in_len, + pout_len); default: return -ENOTSUPP; } } +int ceph_crypt_data_offset(const struct ceph_crypto_key *key) +{ + switch (key->type) { + case CEPH_CRYPTO_NONE: + case CEPH_CRYPTO_AES: + return 0; + case CEPH_CRYPTO_AES256KRB5: + /* confounder */ + return AES_BLOCK_SIZE; + default: + BUG(); + } +} + +int ceph_crypt_buflen(const struct ceph_crypto_key *key, int data_len) +{ + switch (key->type) { + case CEPH_CRYPTO_NONE: + return data_len; + case CEPH_CRYPTO_AES: + /* PKCS#7 padding at the end */ + return data_len + AES_BLOCK_SIZE - + (data_len & (AES_BLOCK_SIZE - 1)); + case CEPH_CRYPTO_AES256KRB5: + /* confounder at the beginning and 192-bit HMAC at the end */ + return AES_BLOCK_SIZE + data_len + 24; + default: + BUG(); + } +} + +void ceph_hmac_sha256(const struct ceph_crypto_key *key, const void *buf, + int buf_len, u8 hmac[SHA256_DIGEST_SIZE]) +{ + switch (key->type) { + case CEPH_CRYPTO_NONE: + case CEPH_CRYPTO_AES: + memset(hmac, 0, SHA256_DIGEST_SIZE); + return; + case CEPH_CRYPTO_AES256KRB5: + hmac_sha256(&key->hmac_key, buf, buf_len, hmac); + return; + default: + BUG(); + } +} + static int ceph_key_preparse(struct key_preparsed_payload *prep) { struct ceph_crypto_key *ckey; @@ -295,7 +466,7 @@ static int ceph_key_preparse(struct key_preparsed_payload *prep) goto err; ret = -ENOMEM; - ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); + ckey = kzalloc_obj(*ckey); if (!ckey) goto err; diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index 23de29fc613c..3a2ade15abbc 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h @@ -2,10 +2,11 @@ #ifndef _FS_CEPH_CRYPTO_H #define _FS_CEPH_CRYPTO_H +#include #include #include -#define CEPH_KEY_LEN 16 +#define CEPH_MAX_KEY_LEN 32 #define CEPH_MAX_CON_SECRET_LEN 64 /* @@ -16,9 +17,19 @@ struct ceph_crypto_key { struct ceph_timespec created; int len; void *key; - struct crypto_sync_skcipher *tfm; + + union { + struct crypto_sync_skcipher *aes_tfm; + struct { + struct hmac_sha256_key hmac_key; + const struct krb5_enctype *krb5_type; + struct crypto_aead *krb5_tfms[3]; + }; + }; }; +int ceph_crypto_key_prepare(struct ceph_crypto_key *key, + const u32 *key_usages, int key_usage_cnt); int ceph_crypto_key_clone(struct ceph_crypto_key *dst, const struct ceph_crypto_key *src); int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end); @@ -26,8 +37,12 @@ int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in); void ceph_crypto_key_destroy(struct ceph_crypto_key *key); /* crypto.c */ -int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, +int ceph_crypt(const struct ceph_crypto_key *key, int usage_slot, bool encrypt, void *buf, int buf_len, int in_len, int *pout_len); +int ceph_crypt_data_offset(const struct ceph_crypto_key *key); +int ceph_crypt_buflen(const struct ceph_crypto_key *key, int data_len); +void ceph_hmac_sha256(const struct ceph_crypto_key *key, const void *buf, + int buf_len, u8 hmac[SHA256_DIGEST_SIZE]); int ceph_crypto_init(void); void ceph_crypto_shutdown(void); diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 70b25f4ecba6..108adb583744 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -1993,8 +1993,7 @@ struct ceph_msg *ceph_msg_new2(int type, int front_len, int max_data_items, m->front_alloc_len = m->front.iov_len = front_len; if (max_data_items) { - m->data = kmalloc_array(max_data_items, sizeof(*m->data), - flags); + m->data = kmalloc_objs(*m->data, max_data_items, flags); if (!m->data) goto out2; diff --git a/net/ceph/messenger_v2.c b/net/ceph/messenger_v2.c index c9d50c0dcd33..50f65820f623 100644 --- a/net/ceph/messenger_v2.c +++ b/net/ceph/messenger_v2.c @@ -392,7 +392,7 @@ static int head_onwire_len(int ctrl_len, bool secure) int head_len; int rem_len; - BUG_ON(ctrl_len < 0 || ctrl_len > CEPH_MSG_MAX_CONTROL_LEN); + BUG_ON(ctrl_len < 1 || ctrl_len > CEPH_MSG_MAX_CONTROL_LEN); if (secure) { head_len = CEPH_PREAMBLE_SECURE_LEN; @@ -401,9 +401,7 @@ static int head_onwire_len(int ctrl_len, bool secure) head_len += padded_len(rem_len) + CEPH_GCM_TAG_LEN; } } else { - head_len = CEPH_PREAMBLE_PLAIN_LEN; - if (ctrl_len) - head_len += ctrl_len + CEPH_CRC_LEN; + head_len = CEPH_PREAMBLE_PLAIN_LEN + ctrl_len + CEPH_CRC_LEN; } return head_len; } @@ -528,11 +526,16 @@ static int decode_preamble(void *p, struct ceph_frame_desc *desc) desc->fd_aligns[i] = ceph_decode_16(&p); } - if (desc->fd_lens[0] < 0 || + /* + * This would fire for FRAME_TAG_WAIT (it has one empty + * segment), but we should never get it as client. + */ + if (desc->fd_lens[0] < 1 || desc->fd_lens[0] > CEPH_MSG_MAX_CONTROL_LEN) { pr_err("bad control segment length %d\n", desc->fd_lens[0]); return -EINVAL; } + if (desc->fd_lens[1] < 0 || desc->fd_lens[1] > CEPH_MSG_MAX_FRONT_LEN) { pr_err("bad front segment length %d\n", desc->fd_lens[1]); @@ -549,10 +552,6 @@ static int decode_preamble(void *p, struct ceph_frame_desc *desc) return -EINVAL; } - /* - * This would fire for FRAME_TAG_WAIT (it has one empty - * segment), but we should never get it as client. - */ if (!desc->fd_lens[desc->fd_seg_cnt - 1]) { pr_err("last segment empty, segment count %d\n", desc->fd_seg_cnt); @@ -779,9 +778,9 @@ static int setup_crypto(struct ceph_connection *con, return 0; /* auth_x, secure mode */ } -static void ceph_hmac_sha256(struct ceph_connection *con, - const struct kvec *kvecs, int kvec_cnt, - u8 hmac[SHA256_DIGEST_SIZE]) +static void con_hmac_sha256(struct ceph_connection *con, + const struct kvec *kvecs, int kvec_cnt, + u8 hmac[SHA256_DIGEST_SIZE]) { struct hmac_sha256_ctx ctx; int i; @@ -1438,8 +1437,8 @@ static int prepare_auth_signature(struct ceph_connection *con) if (!buf) return -ENOMEM; - ceph_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt, - CTRL_BODY(buf)); + con_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt, + CTRL_BODY(buf)); return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf, SHA256_DIGEST_SIZE); @@ -2360,7 +2359,7 @@ static int process_auth_reply_more(struct ceph_connection *con, */ static int process_auth_done(struct ceph_connection *con, void *p, void *end) { - u8 session_key_buf[CEPH_KEY_LEN + 16]; + u8 session_key_buf[CEPH_MAX_KEY_LEN + 16]; u8 con_secret_buf[CEPH_MAX_CON_SECRET_LEN + 16]; u8 *session_key = PTR_ALIGN(&session_key_buf[0], 16); u8 *con_secret = PTR_ALIGN(&con_secret_buf[0], 16); @@ -2436,8 +2435,8 @@ static int process_auth_signature(struct ceph_connection *con, return -EINVAL; } - ceph_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt, - hmac); + con_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt, + hmac); ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad); if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) { @@ -2833,12 +2832,15 @@ static int process_message_header(struct ceph_connection *con, void *p, void *end) { struct ceph_frame_desc *desc = &con->v2.in_desc; - struct ceph_msg_header2 *hdr2 = p; + struct ceph_msg_header2 *hdr2; struct ceph_msg_header hdr; int skip; int ret; u64 seq; + ceph_decode_need(&p, end, sizeof(*hdr2), bad); + hdr2 = p; + /* verify seq# */ seq = le64_to_cpu(hdr2->seq); if ((s64)seq - (s64)con->in_seq < 1) { @@ -2869,6 +2871,10 @@ static int process_message_header(struct ceph_connection *con, WARN_ON(!con->in_msg); WARN_ON(con->in_msg->con != con); return 1; + +bad: + pr_err("failed to decode message header\n"); + return -EINVAL; } static int process_message(struct ceph_connection *con) @@ -2898,6 +2904,11 @@ static int __handle_control(struct ceph_connection *con, void *p) if (con->v2.in_desc.fd_tag != FRAME_TAG_MESSAGE) return process_control(con, p, end); + if (con->state != CEPH_CON_S_OPEN) { + con->error_msg = "protocol error, unexpected message"; + return -EINVAL; + } + ret = process_message_header(con, p, end); if (ret < 0) return ret; diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index fa8dd2a20f7d..d5080530ce0c 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c @@ -72,8 +72,8 @@ static struct ceph_monmap *ceph_monmap_decode(void **p, void *end, bool msgr2) struct ceph_monmap *monmap = NULL; struct ceph_fsid fsid; u32 struct_len; - int blob_len; - int num_mon; + u32 blob_len; + u32 num_mon; u8 struct_v; u32 epoch; int ret; @@ -112,12 +112,12 @@ static struct ceph_monmap *ceph_monmap_decode(void **p, void *end, bool msgr2) } ceph_decode_32_safe(p, end, num_mon, e_inval); - dout("%s fsid %pU epoch %u num_mon %d\n", __func__, &fsid, epoch, + dout("%s fsid %pU epoch %u num_mon %u\n", __func__, &fsid, epoch, num_mon); if (num_mon > CEPH_MAX_MON) goto e_inval; - monmap = kmalloc(struct_size(monmap, mon_inst, num_mon), GFP_NOIO); + monmap = kmalloc_flex(*monmap, mon_inst, num_mon, GFP_NOIO); if (!monmap) { ret = -ENOMEM; goto fail; @@ -611,7 +611,7 @@ alloc_generic_request(struct ceph_mon_client *monc, gfp_t gfp) { struct ceph_mon_generic_request *req; - req = kzalloc(sizeof(*req), gfp); + req = kzalloc_obj(*req, gfp); if (!req) return NULL; @@ -1140,8 +1140,7 @@ static int build_initial_monmap(struct ceph_mon_client *monc) int i; /* build initial monmap */ - monc->monmap = kzalloc(struct_size(monc->monmap, mon_inst, num_mon), - GFP_KERNEL); + monc->monmap = kzalloc_flex(*monc->monmap, mon_inst, num_mon); if (!monc->monmap) return -ENOMEM; monc->monmap->num_mon = num_mon; diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 610e584524d1..2ff00070c181 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -556,7 +556,7 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, req = kmem_cache_alloc(ceph_osd_request_cache, gfp_flags); } else { BUG_ON(num_ops > CEPH_OSD_MAX_OPS); - req = kmalloc(struct_size(req, r_ops, num_ops), gfp_flags); + req = kmalloc_flex(*req, r_ops, num_ops, gfp_flags); } if (unlikely(!req)) return NULL; @@ -1153,9 +1153,8 @@ int __ceph_alloc_sparse_ext_map(struct ceph_osd_req_op *op, int cnt) WARN_ON(op->op != CEPH_OSD_OP_SPARSE_READ); op->extent.sparse_ext_cnt = cnt; - op->extent.sparse_ext = kmalloc_array(cnt, - sizeof(*op->extent.sparse_ext), - GFP_NOFS); + op->extent.sparse_ext = kmalloc_objs(*op->extent.sparse_ext, cnt, + GFP_NOFS); if (!op->extent.sparse_ext) return -ENOMEM; return 0; @@ -1264,7 +1263,7 @@ static struct ceph_osd *create_osd(struct ceph_osd_client *osdc, int onum) WARN_ON(onum == CEPH_HOMELESS_OSD); - osd = kzalloc(sizeof(*osd), GFP_NOIO | __GFP_NOFAIL); + osd = kzalloc_obj(*osd, GFP_NOIO | __GFP_NOFAIL); osd_init(osd); osd->o_osdc = osdc; osd->o_osd = onum; @@ -1718,7 +1717,7 @@ static struct ceph_spg_mapping *alloc_spg_mapping(void) { struct ceph_spg_mapping *spg; - spg = kmalloc(sizeof(*spg), GFP_NOIO); + spg = kmalloc_obj(*spg, GFP_NOIO); if (!spg) return NULL; @@ -1913,7 +1912,7 @@ static struct ceph_osd_backoff *alloc_backoff(void) { struct ceph_osd_backoff *backoff; - backoff = kzalloc(sizeof(*backoff), GFP_NOIO); + backoff = kzalloc_obj(*backoff, GFP_NOIO); if (!backoff) return NULL; @@ -2806,7 +2805,7 @@ linger_alloc(struct ceph_osd_client *osdc) { struct ceph_osd_linger_request *lreq; - lreq = kzalloc(sizeof(*lreq), GFP_NOIO); + lreq = kzalloc_obj(*lreq, GFP_NOIO); if (!lreq) return NULL; @@ -2948,7 +2947,7 @@ static struct linger_work *lwork_alloc(struct ceph_osd_linger_request *lreq, { struct linger_work *lwork; - lwork = kzalloc(sizeof(*lwork), GFP_NOIO); + lwork = kzalloc_obj(*lwork, GFP_NOIO); if (!lwork) return NULL; @@ -4329,7 +4328,7 @@ static int decode_MOSDBackoff(const struct ceph_msg *msg, struct MOSDBackoff *m) ceph_decode_8_safe(&p, end, m->op, e_inval); ceph_decode_64_safe(&p, end, m->id, e_inval); - m->begin = kzalloc(sizeof(*m->begin), GFP_NOIO); + m->begin = kzalloc_obj(*m->begin, GFP_NOIO); if (!m->begin) return -ENOMEM; @@ -4339,7 +4338,7 @@ static int decode_MOSDBackoff(const struct ceph_msg *msg, struct MOSDBackoff *m) return ret; } - m->end = kzalloc(sizeof(*m->end), GFP_NOIO); + m->end = kzalloc_obj(*m->end, GFP_NOIO); if (!m->end) { free_hoid(m->begin); return -ENOMEM; @@ -5032,7 +5031,7 @@ static int decode_watchers(void **p, void *end, return ret; *num_watchers = ceph_decode_32(p); - *watchers = kcalloc(*num_watchers, sizeof(**watchers), GFP_NOIO); + *watchers = kzalloc_objs(**watchers, *num_watchers, GFP_NOIO); if (!*watchers) return -ENOMEM; @@ -5832,9 +5831,8 @@ static int osd_sparse_read(struct ceph_connection *con, if (!sr->sr_extent || count > sr->sr_ext_len) { /* no extent array provided, or too short */ kfree(sr->sr_extent); - sr->sr_extent = kmalloc_array(count, - sizeof(*sr->sr_extent), - GFP_NOIO); + sr->sr_extent = kmalloc_objs(*sr->sr_extent, + count, GFP_NOIO); if (!sr->sr_extent) { pr_err("%s: failed to allocate %u extents\n", __func__, count); diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 92a44026de29..c89e66d4fcb7 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -231,7 +231,7 @@ static struct crush_choose_arg_map *alloc_choose_arg_map(void) { struct crush_choose_arg_map *arg_map; - arg_map = kzalloc(sizeof(*arg_map), GFP_NOIO); + arg_map = kzalloc_obj(*arg_map, GFP_NOIO); if (!arg_map) return NULL; @@ -320,9 +320,8 @@ static int decode_choose_arg(void **p, void *end, struct crush_choose_arg *arg) if (arg->weight_set_size) { u32 i; - arg->weight_set = kmalloc_array(arg->weight_set_size, - sizeof(*arg->weight_set), - GFP_NOIO); + arg->weight_set = kmalloc_objs(*arg->weight_set, + arg->weight_set_size, GFP_NOIO); if (!arg->weight_set) return -ENOMEM; @@ -368,8 +367,8 @@ static int decode_choose_args(void **p, void *end, struct crush_map *c) ceph_decode_64_safe(p, end, arg_map->choose_args_index, e_inval); arg_map->size = c->max_buckets; - arg_map->args = kcalloc(arg_map->size, sizeof(*arg_map->args), - GFP_NOIO); + arg_map->args = kzalloc_objs(*arg_map->args, arg_map->size, + GFP_NOIO); if (!arg_map->args) { ret = -ENOMEM; goto fail; @@ -443,7 +442,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) dout("crush_decode %p to %p len %d\n", *p, end, (int)(end - *p)); - c = kzalloc(sizeof(*c), GFP_NOFS); + c = kzalloc_obj(*c, GFP_NOFS); if (c == NULL) return ERR_PTR(-ENOMEM); @@ -468,10 +467,10 @@ static struct crush_map *crush_decode(void *pbyval, void *end) c->max_rules = ceph_decode_32(p); c->max_devices = ceph_decode_32(p); - c->buckets = kcalloc(c->max_buckets, sizeof(*c->buckets), GFP_NOFS); + c->buckets = kzalloc_objs(*c->buckets, c->max_buckets, GFP_NOFS); if (c->buckets == NULL) goto badmem; - c->rules = kcalloc(c->max_rules, sizeof(*c->rules), GFP_NOFS); + c->rules = kzalloc_objs(*c->rules, c->max_rules, GFP_NOFS); if (c->rules == NULL) goto badmem; @@ -524,7 +523,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) dout("crush_decode bucket size %d off %x %p to %p\n", b->size, (int)(*p-start), *p, end); - b->items = kcalloc(b->size, sizeof(__s32), GFP_NOFS); + b->items = kzalloc_objs(__s32, b->size, GFP_NOFS); if (b->items == NULL) goto badmem; @@ -590,7 +589,7 @@ static struct crush_map *crush_decode(void *pbyval, void *end) / sizeof(struct crush_rule_step)) goto bad; #endif - r = kmalloc(struct_size(r, steps, yes), GFP_NOFS); + r = kmalloc_flex(*r, steps, yes, GFP_NOFS); if (r == NULL) goto badmem; dout(" rule %d is at %p\n", i, r); @@ -1116,7 +1115,7 @@ struct ceph_osdmap *ceph_osdmap_alloc(void) { struct ceph_osdmap *map; - map = kzalloc(sizeof(*map), GFP_NOIO); + map = kzalloc_obj(*map, GFP_NOIO); if (!map) return NULL; @@ -1343,7 +1342,7 @@ static int __decode_pools(void **p, void *end, struct ceph_osdmap *map, pi = lookup_pg_pool(&map->pg_pools, pool); if (!incremental || !pi) { - pi = kzalloc(sizeof(*pi), GFP_NOFS); + pi = kzalloc_obj(*pi, GFP_NOFS); if (!pi) return -ENOMEM; diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c index 5a9c4be5f222..40847d873cff 100644 --- a/net/ceph/pagelist.c +++ b/net/ceph/pagelist.c @@ -10,7 +10,7 @@ struct ceph_pagelist *ceph_pagelist_alloc(gfp_t gfp_flags) { struct ceph_pagelist *pl; - pl = kmalloc(sizeof(*pl), gfp_flags); + pl = kmalloc_obj(*pl, gfp_flags); if (!pl) return NULL; diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index 4509757d8b3b..858359873c4d 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c @@ -41,7 +41,7 @@ struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags) struct page **pages; int i; - pages = kmalloc_array(num_pages, sizeof(*pages), flags); + pages = kmalloc_objs(*pages, num_pages, flags); if (!pages) return ERR_PTR(-ENOMEM); for (i = 0; i < num_pages; i++) { diff --git a/net/ceph/striper.c b/net/ceph/striper.c index 3b3fa75d1189..2b8288858079 100644 --- a/net/ceph/striper.c +++ b/net/ceph/striper.c @@ -230,8 +230,8 @@ int ceph_extent_to_file(struct ceph_file_layout *l, *num_file_extents = DIV_ROUND_UP_ULL(objoff + objlen, l->stripe_unit) - DIV_ROUND_DOWN_ULL(objoff, l->stripe_unit); - *file_extents = kmalloc_array(*num_file_extents, sizeof(**file_extents), - GFP_NOIO); + *file_extents = kmalloc_objs(**file_extents, *num_file_extents, + GFP_NOIO); if (!*file_extents) return -ENOMEM; diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c index 1eb3e060994e..f8338acebf07 100644 --- a/net/core/bpf_sk_storage.c +++ b/net/core/bpf_sk_storage.c @@ -500,7 +500,7 @@ bpf_sk_storage_diag_alloc(const struct nlattr *nla_stgs) nr_maps++; } - diag = kzalloc(struct_size(diag, maps, nr_maps), GFP_KERNEL); + diag = kzalloc_flex(*diag, maps, nr_maps); if (!diag) return ERR_PTR(-ENOMEM); diff --git a/net/core/dev.c b/net/core/dev.c index ac6bcb2a0784..14a83f2035b9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -231,10 +231,13 @@ static bool use_backlog_threads(void) static inline void backlog_lock_irq_save(struct softnet_data *sd, unsigned long *flags) { - if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { spin_lock_irqsave(&sd->input_pkt_queue.lock, *flags); - else + } else { local_irq_save(*flags); + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_lock(&sd->input_pkt_queue.lock); + } } static inline void backlog_lock_irq_disable(struct softnet_data *sd) @@ -248,9 +251,13 @@ static inline void backlog_lock_irq_disable(struct softnet_data *sd) static inline void backlog_unlock_irq_restore(struct softnet_data *sd, unsigned long flags) { - if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) - spin_unlock(&sd->input_pkt_queue.lock); - local_irq_restore(flags); + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + spin_unlock_irqrestore(&sd->input_pkt_queue.lock, flags); + } else { + if (IS_ENABLED(CONFIG_RPS) || use_backlog_threads()) + spin_unlock(&sd->input_pkt_queue.lock); + local_irq_restore(flags); + } } static inline void backlog_unlock_irq_enable(struct softnet_data *sd) @@ -266,7 +273,7 @@ static struct netdev_name_node *netdev_name_node_alloc(struct net_device *dev, { struct netdev_name_node *name_node; - name_node = kmalloc(sizeof(*name_node), GFP_KERNEL); + name_node = kmalloc_obj(*name_node); if (!name_node) return NULL; INIT_HLIST_NODE(&name_node->hlist); @@ -737,7 +744,7 @@ static struct net_device_path *dev_fwd_path(struct net_device_path_stack *stack) { int k = stack->num_paths++; - if (WARN_ON_ONCE(k >= NET_DEVICE_PATH_STACK_MAX)) + if (k >= NET_DEVICE_PATH_STACK_MAX) return NULL; return &stack->path[k]; @@ -3980,7 +3987,7 @@ static struct sk_buff *validate_xmit_unreadable_skb(struct sk_buff *skb, if (shinfo->nr_frags > 0) { niov = netmem_to_net_iov(skb_frag_netmem(&shinfo->frags[0])); if (net_is_devmem_iov(niov) && - net_devmem_iov_binding(niov)->dev != dev) + READ_ONCE(net_devmem_iov_binding(niov)->dev) != dev) goto out_free; } @@ -4811,10 +4818,9 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) if (dev->flags & IFF_UP) { int cpu = smp_processor_id(); /* ok because BHs are off */ - /* Other cpus might concurrently change txq->xmit_lock_owner - * to -1 or to their cpu id, but not to our id. - */ - if (READ_ONCE(txq->xmit_lock_owner) != cpu) { + if (!netif_tx_owned(txq, cpu)) { + bool is_list = false; + if (dev_xmit_recursion()) goto recursion_alert; @@ -4825,17 +4831,28 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) HARD_TX_LOCK(dev, txq, cpu); if (!netif_xmit_stopped(txq)) { + is_list = !!skb->next; + dev_xmit_recursion_inc(); skb = dev_hard_start_xmit(skb, dev, txq, &rc); dev_xmit_recursion_dec(); - if (dev_xmit_complete(rc)) { - HARD_TX_UNLOCK(dev, txq); - goto out; - } + + /* GSO segments a single SKB into + * a list of frames. TCP expects error + * to mean none of the data was sent. + */ + if (is_list) + rc = NETDEV_TX_OK; } HARD_TX_UNLOCK(dev, txq); + if (!skb) /* xmit completed */ + goto out; + net_crit_ratelimited("Virtual device %s asks to queue packet!\n", dev->name); + /* NETDEV_TX_BUSY or queue was stopped */ + if (!is_list) + rc = -ENETDOWN; } else { /* Recursion is detected! It is possible, * unfortunately @@ -4843,10 +4860,10 @@ int __dev_queue_xmit(struct sk_buff *skb, struct net_device *sb_dev) recursion_alert: net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n", dev->name); + rc = -ENETDOWN; } } - rc = -ENETDOWN; rcu_read_unlock_bh(); dev_core_stats_tx_dropped_inc(dev); @@ -4985,8 +5002,7 @@ static bool rps_flow_is_active(struct rps_dev_flow *rflow, static struct rps_dev_flow * set_rps_cpu(struct net_device *dev, struct sk_buff *skb, - struct rps_dev_flow *rflow, u16 next_cpu, u32 hash, - u32 flow_id) + struct rps_dev_flow *rflow, u16 next_cpu, u32 hash) { if (next_cpu < nr_cpu_ids) { u32 head; @@ -4997,6 +5013,7 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, struct rps_dev_flow *tmp_rflow; unsigned int tmp_cpu; u16 rxq_index; + u32 flow_id; int rc; /* Should we steer this flow to a different hardware queue? */ @@ -5012,6 +5029,7 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb, if (!flow_table) goto out; + flow_id = rfs_slot(hash, flow_table); tmp_rflow = &flow_table->flows[flow_id]; tmp_cpu = READ_ONCE(tmp_rflow->cpu); @@ -5059,7 +5077,6 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, struct rps_dev_flow_table *flow_table; struct rps_map *map; int cpu = -1; - u32 flow_id; u32 tcpu; u32 hash; @@ -5106,8 +5123,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, /* OK, now we know there is a match, * we can look at the local (per receive queue) flow table */ - flow_id = rfs_slot(hash, flow_table); - rflow = &flow_table->flows[flow_id]; + rflow = &flow_table->flows[rfs_slot(hash, flow_table)]; tcpu = rflow->cpu; /* @@ -5126,8 +5142,7 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, ((int)(READ_ONCE(per_cpu(softnet_data, tcpu).input_queue_head) - rflow->last_qtail)) >= 0)) { tcpu = next_cpu; - rflow = set_rps_cpu(dev, skb, rflow, next_cpu, hash, - flow_id); + rflow = set_rps_cpu(dev, skb, rflow, next_cpu, hash); } if (tcpu < nr_cpu_ids && cpu_online(tcpu)) { @@ -6503,8 +6518,7 @@ struct flush_backlogs { static struct flush_backlogs *flush_backlogs_alloc(void) { - return kmalloc(struct_size_t(struct flush_backlogs, w, nr_cpu_ids), - GFP_KERNEL); + return kmalloc_flex(struct flush_backlogs, w, nr_cpu_ids); } static struct flush_backlogs *flush_backlogs_fallback; @@ -7777,11 +7791,12 @@ static int napi_thread_wait(struct napi_struct *napi) return -1; } -static void napi_threaded_poll_loop(struct napi_struct *napi, bool busy_poll) +static void napi_threaded_poll_loop(struct napi_struct *napi, + unsigned long *busy_poll_last_qs) { + unsigned long last_qs = busy_poll_last_qs ? *busy_poll_last_qs : jiffies; struct bpf_net_context __bpf_net_ctx, *bpf_net_ctx; struct softnet_data *sd; - unsigned long last_qs = jiffies; for (;;) { bool repoll = false; @@ -7810,12 +7825,12 @@ static void napi_threaded_poll_loop(struct napi_struct *napi, bool busy_poll) /* When busy poll is enabled, the old packets are not flushed in * napi_complete_done. So flush them here. */ - if (busy_poll) + if (busy_poll_last_qs) gro_flush_normal(&napi->gro, HZ >= 1000); local_bh_enable(); /* Call cond_resched here to avoid watchdog warnings. */ - if (repoll || busy_poll) { + if (repoll || busy_poll_last_qs) { rcu_softirq_qs_periodic(last_qs); cond_resched(); } @@ -7823,11 +7838,15 @@ static void napi_threaded_poll_loop(struct napi_struct *napi, bool busy_poll) if (!repoll) break; } + + if (busy_poll_last_qs) + *busy_poll_last_qs = last_qs; } static int napi_threaded_poll(void *data) { struct napi_struct *napi = data; + unsigned long last_qs = jiffies; bool want_busy_poll; bool in_busy_poll; unsigned long val; @@ -7845,7 +7864,7 @@ static int napi_threaded_poll(void *data) assign_bit(NAPI_STATE_IN_BUSY_POLL, &napi->state, want_busy_poll); - napi_threaded_poll_loop(napi, want_busy_poll); + napi_threaded_poll_loop(napi, want_busy_poll ? &last_qs : NULL); } return 0; @@ -8687,7 +8706,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, return 0; } - adj = kmalloc(sizeof(*adj), GFP_KERNEL); + adj = kmalloc_obj(*adj); if (!adj) return -ENOMEM; @@ -9127,8 +9146,7 @@ static int netdev_offload_xstats_enable_l3(struct net_device *dev, int err; int rc; - dev->offload_xstats_l3 = kzalloc(sizeof(*dev->offload_xstats_l3), - GFP_KERNEL); + dev->offload_xstats_l3 = kzalloc_obj(*dev->offload_xstats_l3); if (!dev->offload_xstats_l3) return -ENOMEM; @@ -10653,7 +10671,7 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) return -EINVAL; } - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) { err = -ENOMEM; goto unlock; @@ -11934,7 +11952,7 @@ struct netdev_queue *dev_ingress_queue_create(struct net_device *dev) #ifdef CONFIG_NET_CLS_ACT if (queue) return queue; - queue = kzalloc(sizeof(*queue), GFP_KERNEL); + queue = kzalloc_obj(*queue); if (!queue) return NULL; netdev_init_one_queue(dev, queue, NULL); @@ -12009,8 +12027,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, maxqs = max(txqs, rxqs); - dev = kvzalloc(struct_size(dev, priv, sizeof_priv), - GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); + dev = kvzalloc_flex(*dev, priv, sizeof_priv, + GFP_KERNEL_ACCOUNT | __GFP_RETRY_MAYFAIL); if (!dev) return NULL; @@ -12081,11 +12099,11 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, dev->real_num_rx_queues = rxqs; if (netif_alloc_rx_queues(dev)) goto free_all; - dev->ethtool = kzalloc(sizeof(*dev->ethtool), GFP_KERNEL_ACCOUNT); + dev->ethtool = kzalloc_obj(*dev->ethtool, GFP_KERNEL_ACCOUNT); if (!dev->ethtool) goto free_all; - dev->cfg = kzalloc(sizeof(*dev->cfg), GFP_KERNEL_ACCOUNT); + dev->cfg = kzalloc_obj(*dev->cfg, GFP_KERNEL_ACCOUNT); if (!dev->cfg) goto free_all; dev->cfg_pending = dev->cfg; @@ -12851,7 +12869,7 @@ static struct hlist_head * __net_init netdev_create_hash(void) int i; struct hlist_head *hash; - hash = kmalloc_array(NETDEV_HASHENTRIES, sizeof(*hash), GFP_KERNEL); + hash = kmalloc_objs(*hash, NETDEV_HASHENTRIES); if (hash != NULL) for (i = 0; i < NETDEV_HASHENTRIES; i++) INIT_HLIST_HEAD(&hash[i]); @@ -13159,7 +13177,7 @@ static void run_backlog_napi(unsigned int cpu) { struct softnet_data *sd = per_cpu_ptr(&softnet_data, cpu); - napi_threaded_poll_loop(&sd->backlog, false); + napi_threaded_poll_loop(&sd->backlog, NULL); } static void backlog_napi_setup(unsigned int cpu) diff --git a/net/core/dev.h b/net/core/dev.h index 98793a738f43..781619e76b3e 100644 --- a/net/core/dev.h +++ b/net/core/dev.h @@ -366,41 +366,6 @@ static inline void napi_assert_will_not_race(const struct napi_struct *napi) void kick_defer_list_purge(unsigned int cpu); -#define XMIT_RECURSION_LIMIT 8 - -#ifndef CONFIG_PREEMPT_RT -static inline bool dev_xmit_recursion(void) -{ - return unlikely(__this_cpu_read(softnet_data.xmit.recursion) > - XMIT_RECURSION_LIMIT); -} - -static inline void dev_xmit_recursion_inc(void) -{ - __this_cpu_inc(softnet_data.xmit.recursion); -} - -static inline void dev_xmit_recursion_dec(void) -{ - __this_cpu_dec(softnet_data.xmit.recursion); -} -#else -static inline bool dev_xmit_recursion(void) -{ - return unlikely(current->net_xmit.recursion > XMIT_RECURSION_LIMIT); -} - -static inline void dev_xmit_recursion_inc(void) -{ - current->net_xmit.recursion++; -} - -static inline void dev_xmit_recursion_dec(void) -{ - current->net_xmit.recursion--; -} -#endif - int dev_set_hwtstamp_phylib(struct net_device *dev, struct kernel_hwtstamp_config *cfg, struct netlink_ext_ack *extack); diff --git a/net/core/devmem.c b/net/core/devmem.c index 63f093f7d2b2..69d79aee07ef 100644 --- a/net/core/devmem.c +++ b/net/core/devmem.c @@ -241,9 +241,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, } if (direction == DMA_TO_DEVICE) { - binding->tx_vec = kvmalloc_array(dmabuf->size / PAGE_SIZE, - sizeof(struct net_iov *), - GFP_KERNEL); + binding->tx_vec = kvmalloc_objs(struct net_iov *, + dmabuf->size / PAGE_SIZE); if (!binding->tx_vec) { err = -ENOMEM; goto err_unmap; @@ -289,9 +288,8 @@ net_devmem_bind_dmabuf(struct net_device *dev, goto err_free_chunks; } - owner->area.niovs = kvmalloc_array(owner->area.num_niovs, - sizeof(*owner->area.niovs), - GFP_KERNEL); + owner->area.niovs = kvmalloc_objs(*owner->area.niovs, + owner->area.num_niovs); if (!owner->area.niovs) { err = -ENOMEM; goto err_free_chunks; @@ -398,7 +396,8 @@ struct net_devmem_dmabuf_binding *net_devmem_get_binding(struct sock *sk, * net_device. */ dst_dev = dst_dev_rcu(dst); - if (unlikely(!dst_dev) || unlikely(dst_dev != binding->dev)) { + if (unlikely(!dst_dev) || + unlikely(dst_dev != READ_ONCE(binding->dev))) { err = -ENODEV; goto out_unlock; } @@ -515,7 +514,8 @@ static void mp_dmabuf_devmem_uninstall(void *mp_priv, xa_erase(&binding->bound_rxqs, xa_idx); if (xa_empty(&binding->bound_rxqs)) { mutex_lock(&binding->lock); - binding->dev = NULL; + ASSERT_EXCLUSIVE_WRITER(binding->dev); + WRITE_ONCE(binding->dev, NULL); mutex_unlock(&binding->lock); } break; diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 60d31c2feed3..f23cea9e1aaf 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -306,8 +306,7 @@ net_dm_hw_reset_per_cpu_data(struct per_cpu_dm_data *hw_data) struct net_dm_hw_entries *hw_entries; unsigned long flags; - hw_entries = kzalloc(struct_size(hw_entries, entries, dm_hit_limit), - GFP_KERNEL); + hw_entries = kzalloc_flex(*hw_entries, entries, dm_hit_limit); if (!hw_entries) { /* If the memory allocation failed, we try to perform another * allocation in 1/10 second. Otherwise, the probe function @@ -856,7 +855,7 @@ net_dm_hw_metadata_copy(const struct devlink_trap_metadata *metadata) const char *trap_group_name; const char *trap_name; - hw_metadata = kzalloc(sizeof(*hw_metadata), GFP_ATOMIC); + hw_metadata = kzalloc_obj(*hw_metadata, GFP_ATOMIC); if (!hw_metadata) return NULL; @@ -1583,7 +1582,7 @@ static int dropmon_net_event(struct notifier_block *ev_block, case NETDEV_REGISTER: if (WARN_ON_ONCE(rtnl_dereference(dev->dm_private))) break; - stat = kzalloc(sizeof(*stat), GFP_KERNEL); + stat = kzalloc_obj(*stat); if (!stat) break; diff --git a/net/core/dst.c b/net/core/dst.c index 1dae26c51ebe..092861133023 100644 --- a/net/core/dst.c +++ b/net/core/dst.c @@ -191,7 +191,7 @@ EXPORT_SYMBOL(dst_release_immediate); u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old) { - struct dst_metrics *p = kmalloc(sizeof(*p), GFP_ATOMIC); + struct dst_metrics *p = kmalloc_obj(*p, GFP_ATOMIC); if (p) { struct dst_metrics *old_p = (struct dst_metrics *)__DST_METRICS_PTR(old); @@ -295,8 +295,7 @@ struct metadata_dst *metadata_dst_alloc(u8 optslen, enum metadata_type type, { struct metadata_dst *md_dst; - md_dst = kmalloc(struct_size(md_dst, u.tun_info.options, optslen), - flags); + md_dst = kmalloc_flex(*md_dst, u.tun_info.options, optslen, flags); if (!md_dst) return NULL; diff --git a/net/core/failover.c b/net/core/failover.c index 2a140b3ea669..0eb2e0ec875b 100644 --- a/net/core/failover.c +++ b/net/core/failover.c @@ -247,7 +247,7 @@ struct failover *failover_register(struct net_device *dev, if (dev->type != ARPHRD_ETHER) return ERR_PTR(-EINVAL); - failover = kzalloc(sizeof(*failover), GFP_KERNEL); + failover = kzalloc_obj(*failover); if (!failover) return ERR_PTR(-ENOMEM); diff --git a/net/core/filter.c b/net/core/filter.c index ba019ded773d..78b548158fb0 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -600,8 +600,7 @@ static int bpf_convert_filter(struct sock_filter *prog, int len, if (new_prog) { first_insn = new_prog->insnsi; - addrs = kcalloc(len, sizeof(*addrs), - GFP_KERNEL | __GFP_NOWARN); + addrs = kzalloc_objs(*addrs, len, GFP_KERNEL | __GFP_NOWARN); if (!addrs) return -ENOMEM; } @@ -1162,7 +1161,7 @@ static int bpf_prog_store_orig_filter(struct bpf_prog *fp, unsigned int fsize = bpf_classic_proglen(fprog); struct sock_fprog_kern *fkprog; - fp->orig_prog = kmalloc(sizeof(*fkprog), GFP_KERNEL); + fp->orig_prog = kmalloc_obj(*fkprog); if (!fp->orig_prog) return -ENOMEM; @@ -1482,7 +1481,7 @@ static int __sk_attach_prog(struct bpf_prog *prog, struct sock *sk) { struct sk_filter *fp, *old_fp; - fp = kmalloc(sizeof(*fp), GFP_KERNEL); + fp = kmalloc_obj(*fp); if (!fp) return -ENOMEM; @@ -2229,6 +2228,9 @@ static int bpf_out_neigh_v6(struct net *net, struct sk_buff *skb, return -ENOMEM; } + if (unlikely(!ipv6_mod_enabled())) + goto out_drop; + rcu_read_lock(); if (!nh) { dst = skb_dst(skb); @@ -2336,6 +2338,10 @@ static int bpf_out_neigh_v4(struct net *net, struct sk_buff *skb, neigh = ip_neigh_for_gw(rt, skb, &is_v6gw); } else if (nh->nh_family == AF_INET6) { + if (unlikely(!ipv6_mod_enabled())) { + rcu_read_unlock(); + goto out_drop; + } neigh = ip_neigh_gw6(dev, &nh->ipv6_nh); is_v6gw = true; } else if (nh->nh_family == AF_INET) { @@ -4151,12 +4157,14 @@ static int bpf_xdp_frags_increase_tail(struct xdp_buff *xdp, int offset) struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(xdp); skb_frag_t *frag = &sinfo->frags[sinfo->nr_frags - 1]; struct xdp_rxq_info *rxq = xdp->rxq; - unsigned int tailroom; + int tailroom; if (!rxq->frag_size || rxq->frag_size > xdp->frame_sz) return -EOPNOTSUPP; - tailroom = rxq->frag_size - skb_frag_size(frag) - skb_frag_off(frag); + tailroom = rxq->frag_size - skb_frag_size(frag) - + skb_frag_off(frag) % rxq->frag_size; + WARN_ON_ONCE(tailroom < 0); if (unlikely(offset > tailroom)) return -EINVAL; diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index bc5169482710..5071d7fe6ce2 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -12,8 +12,7 @@ struct flow_rule *flow_rule_alloc(unsigned int num_actions) struct flow_rule *rule; int i; - rule = kzalloc(struct_size(rule, action.entries, num_actions), - GFP_KERNEL); + rule = kzalloc_flex(*rule, action.entries, num_actions); if (!rule) return NULL; @@ -33,8 +32,7 @@ struct flow_offload_action *offload_action_alloc(unsigned int num_actions) struct flow_offload_action *fl_action; int i; - fl_action = kzalloc(struct_size(fl_action, action.entries, num_actions), - GFP_KERNEL); + fl_action = kzalloc_flex(*fl_action, action.entries, num_actions); if (!fl_action) return NULL; @@ -264,7 +262,7 @@ struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb, { struct flow_block_cb *block_cb; - block_cb = kzalloc(sizeof(*block_cb), GFP_KERNEL); + block_cb = kzalloc_obj(*block_cb); if (!block_cb) return ERR_PTR(-ENOMEM); @@ -391,7 +389,7 @@ static struct flow_indr_dev *flow_indr_dev_alloc(flow_indr_block_bind_cb_t *cb, { struct flow_indr_dev *indr_dev; - indr_dev = kmalloc(sizeof(*indr_dev), GFP_KERNEL); + indr_dev = kmalloc_obj(*indr_dev); if (!indr_dev) return NULL; @@ -571,7 +569,7 @@ static int indir_dev_add(void *data, struct net_device *dev, struct Qdisc *sch, if (info) return -EEXIST; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index f112156db587..c34e58c6c3e6 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -154,7 +154,7 @@ int gen_new_estimator(struct gnet_stats_basic_sync *bstats, if (parm->ewma_log == 0 || parm->ewma_log >= 31) return -EINVAL; - est = kzalloc(sizeof(*est), GFP_KERNEL); + est = kzalloc_obj(*est); if (!est) return -ENOBUFS; diff --git a/net/core/gro_cells.c b/net/core/gro_cells.c index a725d21159a6..1b84385c04bd 100644 --- a/net/core/gro_cells.c +++ b/net/core/gro_cells.c @@ -132,7 +132,7 @@ void gro_cells_destroy(struct gro_cells *gcells) * because we might be called from cleanup_net(), and we * definitely do not want to block this critical task. */ - defer = kmalloc(sizeof(*defer), GFP_KERNEL | __GFP_NOWARN); + defer = kmalloc_obj(*defer, GFP_KERNEL | __GFP_NOWARN); if (likely(defer)) { defer->ptr = gcells->cells; call_rcu(&defer->rcu, percpu_free_defer_callback); diff --git a/net/core/neighbour.c b/net/core/neighbour.c index e0897eb41c8d..c56a4e7bf790 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -562,7 +562,7 @@ static struct neigh_hash_table *neigh_hash_alloc(unsigned int shift) struct neigh_hash_table *ret; int i; - ret = kmalloc(sizeof(*ret), GFP_ATOMIC); + ret = kmalloc_obj(*ret, GFP_ATOMIC); if (!ret) return NULL; @@ -820,7 +820,8 @@ int pneigh_create(struct neigh_table *tbl, struct net *net, update: WRITE_ONCE(n->flags, flags); n->permanent = permanent; - WRITE_ONCE(n->protocol, protocol); + if (protocol) + WRITE_ONCE(n->protocol, protocol); out: mutex_unlock(&tbl->phash_lock); return err; diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index aef44e617361..1057d16d5dd2 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -492,7 +492,7 @@ static struct net *net_alloc(void) goto out_free; #ifdef CONFIG_KEYS - net->key_domain = kzalloc(sizeof(struct key_tag), GFP_KERNEL); + net->key_domain = kzalloc_obj(struct key_tag); if (!net->key_domain) goto out_free_2; refcount_set(&net->key_domain->usage, 1); diff --git a/net/core/netclassid_cgroup.c b/net/core/netclassid_cgroup.c index db9a5354f9de..e1e30f0b60cd 100644 --- a/net/core/netclassid_cgroup.c +++ b/net/core/netclassid_cgroup.c @@ -32,7 +32,7 @@ cgrp_css_alloc(struct cgroup_subsys_state *parent_css) { struct cgroup_cls_state *cs; - cs = kzalloc(sizeof(*cs), GFP_KERNEL); + cs = kzalloc_obj(*cs); if (!cs) return ERR_PTR(-ENOMEM); diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 09f72f10813c..cd74beffd209 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -132,7 +132,7 @@ static int netif_local_xmit_active(struct net_device *dev) for (i = 0; i < dev->num_tx_queues; i++) { struct netdev_queue *txq = netdev_get_tx_queue(dev, i); - if (READ_ONCE(txq->xmit_lock_owner) == smp_processor_id()) + if (netif_tx_owned(txq, smp_processor_id())) return 1; } @@ -565,7 +565,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) npinfo = rtnl_dereference(ndev->npinfo); if (!npinfo) { - npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); + npinfo = kmalloc_obj(*npinfo); if (!npinfo) { err = -ENOMEM; goto out; diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 8456dfbe2eb4..76c33ab44761 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c @@ -135,7 +135,7 @@ cgrp_css_alloc(struct cgroup_subsys_state *parent_css) { struct cgroup_subsys_state *css; - css = kzalloc(sizeof(*css), GFP_KERNEL); + css = kzalloc_obj(*css); if (!css) return ERR_PTR(-ENOMEM); diff --git a/net/core/page_pool_user.c b/net/core/page_pool_user.c index c82a95beceff..ee5060d8eec0 100644 --- a/net/core/page_pool_user.c +++ b/net/core/page_pool_user.c @@ -245,7 +245,7 @@ page_pool_nl_fill(struct sk_buff *rsp, const struct page_pool *pool, goto err_cancel; if (pool->user.detach_time && nla_put_uint(rsp, NETDEV_A_PAGE_POOL_DETACH_TIME, - pool->user.detach_time)) + ktime_divns(pool->user.detach_time, NSEC_PER_SEC))) goto err_cancel; if (pool->mp_ops && pool->mp_ops->nl_fill(pool->mp_priv, rsp, NULL)) @@ -337,7 +337,7 @@ int page_pool_list(struct page_pool *pool) void page_pool_detached(struct page_pool *pool) { mutex_lock(&page_pools_lock); - pool->user.detach_time = ktime_get_boottime_seconds(); + pool->user.detach_time = ktime_get_boottime(); netdev_nl_page_pool_event(pool, NETDEV_CMD_PAGE_POOL_CHANGE_NTF); mutex_unlock(&page_pools_lock); } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index b1ed55141d8a..dad4b1054955 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -414,7 +414,7 @@ static int rtnl_register_internal(struct module *owner, if (!link) goto unlock; } else { - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) goto unlock; } @@ -3969,7 +3969,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, int ops_srcu_index; int ret; - tbs = kmalloc(sizeof(*tbs), GFP_KERNEL); + tbs = kmalloc_obj(*tbs); if (!tbs) return -ENOMEM; diff --git a/net/core/scm.c b/net/core/scm.c index cd87f66671aa..a29aa8fb8065 100644 --- a/net/core/scm.c +++ b/net/core/scm.c @@ -83,7 +83,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp) if (!fpl) { - fpl = kmalloc(sizeof(struct scm_fp_list), GFP_KERNEL_ACCOUNT); + fpl = kmalloc_obj(struct scm_fp_list, GFP_KERNEL_ACCOUNT); if (!fpl) return -ENOMEM; *fplp = fpl; diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c index 9a3965680451..6a6f2cda5aae 100644 --- a/net/core/secure_seq.c +++ b/net/core/secure_seq.c @@ -20,7 +20,6 @@ #include static siphash_aligned_key_t net_secret; -static siphash_aligned_key_t ts_secret; #define EPHEMERAL_PORT_SHUFFLE_PERIOD (10 * HZ) @@ -28,11 +27,6 @@ static __always_inline void net_secret_init(void) { net_get_random_once(&net_secret, sizeof(net_secret)); } - -static __always_inline void ts_secret_init(void) -{ - net_get_random_once(&ts_secret, sizeof(ts_secret)); -} #endif #ifdef CONFIG_INET @@ -53,28 +47,9 @@ static u32 seq_scale(u32 seq) #endif #if IS_ENABLED(CONFIG_IPV6) -u32 secure_tcpv6_ts_off(const struct net *net, - const __be32 *saddr, const __be32 *daddr) -{ - const struct { - struct in6_addr saddr; - struct in6_addr daddr; - } __aligned(SIPHASH_ALIGNMENT) combined = { - .saddr = *(struct in6_addr *)saddr, - .daddr = *(struct in6_addr *)daddr, - }; - - if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1) - return 0; - - ts_secret_init(); - return siphash(&combined, offsetofend(typeof(combined), daddr), - &ts_secret); -} -EXPORT_IPV6_MOD(secure_tcpv6_ts_off); - -u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, - __be16 sport, __be16 dport) +union tcp_seq_and_ts_off +secure_tcpv6_seq_and_ts_off(const struct net *net, const __be32 *saddr, + const __be32 *daddr, __be16 sport, __be16 dport) { const struct { struct in6_addr saddr; @@ -87,14 +62,20 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, .sport = sport, .dport = dport }; - u32 hash; + union tcp_seq_and_ts_off st; net_secret_init(); - hash = siphash(&combined, offsetofend(typeof(combined), dport), - &net_secret); - return seq_scale(hash); + + st.hash64 = siphash(&combined, offsetofend(typeof(combined), dport), + &net_secret); + + if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1) + st.ts_off = 0; + + st.seq = seq_scale(st.seq); + return st; } -EXPORT_SYMBOL(secure_tcpv6_seq); +EXPORT_SYMBOL(secure_tcpv6_seq_and_ts_off); u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport) @@ -118,33 +99,30 @@ EXPORT_SYMBOL(secure_ipv6_port_ephemeral); #endif #ifdef CONFIG_INET -u32 secure_tcp_ts_off(const struct net *net, __be32 saddr, __be32 daddr) -{ - if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1) - return 0; - - ts_secret_init(); - return siphash_2u32((__force u32)saddr, (__force u32)daddr, - &ts_secret); -} - /* secure_tcp_seq_and_tsoff(a, b, 0, d) == secure_ipv4_port_ephemeral(a, b, d), * but fortunately, `sport' cannot be 0 in any circumstances. If this changes, * it would be easy enough to have the former function use siphash_4u32, passing * the arguments as separate u32. */ -u32 secure_tcp_seq(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport) +union tcp_seq_and_ts_off +secure_tcp_seq_and_ts_off(const struct net *net, __be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) { - u32 hash; + u32 ports = (__force u32)sport << 16 | (__force u32)dport; + union tcp_seq_and_ts_off st; net_secret_init(); - hash = siphash_3u32((__force u32)saddr, (__force u32)daddr, - (__force u32)sport << 16 | (__force u32)dport, - &net_secret); - return seq_scale(hash); + + st.hash64 = siphash_3u32((__force u32)saddr, (__force u32)daddr, + ports, &net_secret); + + if (READ_ONCE(net->ipv4.sysctl_tcp_timestamps) != 1) + st.ts_off = 0; + + st.seq = seq_scale(st.seq); + return st; } -EXPORT_SYMBOL_GPL(secure_tcp_seq); +EXPORT_SYMBOL_GPL(secure_tcp_seq_and_ts_off); u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) { diff --git a/net/core/selftests.c b/net/core/selftests.c index 8b81feb82c4a..0a203d3fb9dc 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -237,7 +237,7 @@ static int __net_test_loopback(struct net_device *ndev, struct sk_buff *skb = NULL; int ret = 0; - tpriv = kzalloc(sizeof(*tpriv), GFP_KERNEL); + tpriv = kzalloc_obj(*tpriv); if (!tpriv) return -ENOMEM; diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 699c401a5eae..0e217041958a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -5590,15 +5590,28 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, static bool skb_may_tx_timestamp(struct sock *sk, bool tsonly) { - bool ret; + struct socket *sock; + struct file *file; + bool ret = false; if (likely(tsonly || READ_ONCE(sock_net(sk)->core.sysctl_tstamp_allow_data))) return true; - read_lock_bh(&sk->sk_callback_lock); - ret = sk->sk_socket && sk->sk_socket->file && - file_ns_capable(sk->sk_socket->file, &init_user_ns, CAP_NET_RAW); - read_unlock_bh(&sk->sk_callback_lock); + /* The sk pointer remains valid as long as the skb is. The sk_socket and + * file pointer may become NULL if the socket is closed. Both structures + * (including file->cred) are RCU freed which means they can be accessed + * within a RCU read section. + */ + rcu_read_lock(); + sock = READ_ONCE(sk->sk_socket); + if (!sock) + goto out; + file = READ_ONCE(sock->file); + if (!file) + goto out; + ret = file_ns_capable(file, &init_user_ns, CAP_NET_RAW); +out: + rcu_read_unlock(); return ret; } @@ -7266,10 +7279,15 @@ void skb_attempt_defer_free(struct sk_buff *skb) { struct skb_defer_node *sdn; unsigned long defer_count; - int cpu = skb->alloc_cpu; unsigned int defer_max; bool kick; + int cpu; + /* zero copy notifications should not be delayed. */ + if (skb_zcopy(skb)) + goto nodefer; + + cpu = skb->alloc_cpu; if (cpu == raw_smp_processor_id() || WARN_ON_ONCE(cpu >= nr_cpu_ids) || !cpu_online(cpu)) { diff --git a/net/core/skmsg.c b/net/core/skmsg.c index ddde93dd8bc6..3261793abe83 100644 --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -522,7 +522,7 @@ static struct sk_msg *alloc_sk_msg(gfp_t gfp) { struct sk_msg *msg; - msg = kzalloc(sizeof(*msg), gfp | __GFP_NOWARN); + msg = kzalloc_obj(*msg, gfp | __GFP_NOWARN); if (unlikely(!msg)) return NULL; sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS); @@ -1205,8 +1205,8 @@ void sk_psock_start_strp(struct sock *sk, struct sk_psock *psock) return; psock->saved_data_ready = sk->sk_data_ready; - sk->sk_data_ready = sk_psock_strp_data_ready; - sk->sk_write_space = sk_psock_write_space; + WRITE_ONCE(sk->sk_data_ready, sk_psock_strp_data_ready); + WRITE_ONCE(sk->sk_write_space, sk_psock_write_space); } void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock) @@ -1216,8 +1216,8 @@ void sk_psock_stop_strp(struct sock *sk, struct sk_psock *psock) if (!psock->saved_data_ready) return; - sk->sk_data_ready = psock->saved_data_ready; - psock->saved_data_ready = NULL; + WRITE_ONCE(sk->sk_data_ready, psock->saved_data_ready); + WRITE_ONCE(psock->saved_data_ready, NULL); strp_stop(&psock->strp); } @@ -1296,8 +1296,8 @@ void sk_psock_start_verdict(struct sock *sk, struct sk_psock *psock) return; psock->saved_data_ready = sk->sk_data_ready; - sk->sk_data_ready = sk_psock_verdict_data_ready; - sk->sk_write_space = sk_psock_write_space; + WRITE_ONCE(sk->sk_data_ready, sk_psock_verdict_data_ready); + WRITE_ONCE(sk->sk_write_space, sk_psock_write_space); } void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock) @@ -1308,6 +1308,6 @@ void sk_psock_stop_verdict(struct sock *sk, struct sk_psock *psock) if (!psock->saved_data_ready) return; - sk->sk_data_ready = psock->saved_data_ready; + WRITE_ONCE(sk->sk_data_ready, psock->saved_data_ready); psock->saved_data_ready = NULL; } diff --git a/net/core/sock.c b/net/core/sock.c index 693e6d80f501..5976100a9d55 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1097,7 +1097,7 @@ sock_devmem_dontneed(struct sock *sk, sockptr_t optval, unsigned int optlen) return -EINVAL; num_tokens = optlen / sizeof(*tokens); - tokens = kvmalloc_array(num_tokens, sizeof(*tokens), GFP_KERNEL); + tokens = kvmalloc_objs(*tokens, num_tokens); if (!tokens) return -ENOMEM; diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 026ce9bd9e5e..c83335c62360 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -177,7 +177,7 @@ void sock_diag_broadcast_destroy(struct sock *sk) { /* Note, this function is often called from an interrupt context. */ struct broadcast_sk *bsk = - kmalloc(sizeof(struct broadcast_sk), GFP_ATOMIC); + kmalloc_obj(struct broadcast_sk, GFP_ATOMIC); if (!bsk) return sk_destruct(sk); bsk->sk = sk; diff --git a/net/core/sock_map.c b/net/core/sock_map.c index 5947b38e4f8b..b0e96337a269 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -1858,7 +1858,7 @@ int sock_map_link_create(const union bpf_attr *attr, struct bpf_prog *prog) goto out; } - sockmap_link = kzalloc(sizeof(*sockmap_link), GFP_USER); + sockmap_link = kzalloc_obj(*sockmap_link, GFP_USER); if (!sockmap_link) { ret = -ENOMEM; goto out; diff --git a/net/core/sock_reuseport.c b/net/core/sock_reuseport.c index 4211710393a8..29948cb44b7d 100644 --- a/net/core/sock_reuseport.c +++ b/net/core/sock_reuseport.c @@ -175,7 +175,7 @@ static struct sock_reuseport *__reuseport_alloc(unsigned int max_socks) { struct sock_reuseport *reuse; - reuse = kzalloc(struct_size(reuse, socks, max_socks), GFP_ATOMIC); + reuse = kzalloc_flex(*reuse, socks, max_socks, GFP_ATOMIC); if (!reuse) return NULL; diff --git a/net/core/xdp.c b/net/core/xdp.c index fee6d080ee85..9890a30584ba 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c @@ -214,7 +214,7 @@ static int __mem_id_init_hash_table(void) if (unlikely(mem_id_init)) return 0; - rht = kzalloc(sizeof(*rht), GFP_KERNEL); + rht = kzalloc_obj(*rht); if (!rht) return -ENOMEM; @@ -297,7 +297,7 @@ static struct xdp_mem_allocator *__xdp_reg_mem_model(struct xdp_mem_info *mem, return ERR_PTR(ret); } - xdp_alloc = kzalloc(sizeof(*xdp_alloc), gfp); + xdp_alloc = kzalloc_obj(*xdp_alloc, gfp); if (!xdp_alloc) return ERR_PTR(-ENOMEM); diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 03eb1d941fca..35164bfa563d 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c @@ -1021,8 +1021,7 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, */ err = ops->peer_getappinfo(netdev, &info, &app_count); if (!err && app_count) { - table = kmalloc_array(app_count, sizeof(struct dcb_app), - GFP_KERNEL); + table = kmalloc_objs(struct dcb_app, app_count); if (!table) return -ENOMEM; @@ -2004,7 +2003,7 @@ static int dcb_app_add(struct list_head *list, const struct dcb_app *app, { struct dcb_app_type *entry; - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); + entry = kmalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; diff --git a/net/devlink/core.c b/net/devlink/core.c index da56e2b8afc1..d8e509a669bf 100644 --- a/net/devlink/core.c +++ b/net/devlink/core.c @@ -111,7 +111,7 @@ static struct devlink_rel *devlink_rel_alloc(void) static u32 next; int err; - rel = kzalloc(sizeof(*rel), GFP_KERNEL); + rel = kzalloc_obj(*rel); if (!rel) return ERR_PTR(-ENOMEM); @@ -418,7 +418,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops, if (!devlink_reload_actions_valid(ops)) return NULL; - devlink = kvzalloc(struct_size(devlink, priv, priv_size), GFP_KERNEL); + devlink = kvzalloc_flex(*devlink, priv, priv_size); if (!devlink) return NULL; diff --git a/net/devlink/dpipe.c b/net/devlink/dpipe.c index e55701b007f0..c8d4a4374ae1 100644 --- a/net/devlink/dpipe.c +++ b/net/devlink/dpipe.c @@ -851,7 +851,7 @@ int devl_dpipe_table_register(struct devlink *devlink, devlink)) return -EEXIST; - table = kzalloc(sizeof(*table), GFP_KERNEL); + table = kzalloc_obj(*table); if (!table) return -ENOMEM; diff --git a/net/devlink/health.c b/net/devlink/health.c index 136a67c36a20..449c7611c640 100644 --- a/net/devlink/health.c +++ b/net/devlink/health.c @@ -32,7 +32,7 @@ static struct devlink_fmsg *devlink_fmsg_alloc(void) { struct devlink_fmsg *fmsg; - fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL); + fmsg = kzalloc_obj(*fmsg); if (!fmsg) return NULL; @@ -119,7 +119,7 @@ __devlink_health_reporter_create(struct devlink *devlink, if (WARN_ON(ops->default_burst_period && !ops->default_graceful_period)) return ERR_PTR(-EINVAL); - reporter = kzalloc(sizeof(*reporter), GFP_KERNEL); + reporter = kzalloc_obj(*reporter); if (!reporter) return ERR_PTR(-ENOMEM); @@ -738,7 +738,7 @@ static void devlink_fmsg_nest_common(struct devlink_fmsg *fmsg, int attrtype) if (fmsg->err) return; - item = kzalloc(sizeof(*item), GFP_KERNEL); + item = kzalloc_obj(*item); if (!item) { fmsg->err = -ENOMEM; return; diff --git a/net/devlink/linecard.c b/net/devlink/linecard.c index 67f70a621d27..8315d35cb91d 100644 --- a/net/devlink/linecard.c +++ b/net/devlink/linecard.c @@ -404,8 +404,7 @@ static int devlink_linecard_types_init(struct devlink_linecard *linecard) int i; count = linecard->ops->types_count(linecard, linecard->priv); - linecard->types = kmalloc_array(count, sizeof(*linecard_type), - GFP_KERNEL); + linecard->types = kmalloc_objs(*linecard_type, count); if (!linecard->types) return -ENOMEM; linecard->types_count = count; @@ -451,7 +450,7 @@ devl_linecard_create(struct devlink *devlink, unsigned int linecard_index, if (devlink_linecard_index_exists(devlink, linecard_index)) return ERR_PTR(-EEXIST); - linecard = kzalloc(sizeof(*linecard), GFP_KERNEL); + linecard = kzalloc_obj(*linecard); if (!linecard) return ERR_PTR(-ENOMEM); diff --git a/net/devlink/param.c b/net/devlink/param.c index e0ea93eded43..cf95268da5b0 100644 --- a/net/devlink/param.c +++ b/net/devlink/param.c @@ -718,7 +718,7 @@ static int devlink_param_register(struct devlink *devlink, else WARN_ON(!param->get || !param->set); - param_item = kzalloc(sizeof(*param_item), GFP_KERNEL); + param_item = kzalloc_obj(*param_item); if (!param_item) return -ENOMEM; diff --git a/net/devlink/rate.c b/net/devlink/rate.c index 0d68b5c477dc..41be2d6c2954 100644 --- a/net/devlink/rate.c +++ b/net/devlink/rate.c @@ -627,7 +627,7 @@ int devlink_nl_rate_new_doit(struct sk_buff *skb, struct genl_info *info) else if (rate_node == ERR_PTR(-EINVAL)) return -EINVAL; - rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); + rate_node = kzalloc_obj(*rate_node); if (!rate_node) return -ENOMEM; @@ -721,7 +721,7 @@ devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name, if (!IS_ERR(rate_node)) return ERR_PTR(-EEXIST); - rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL); + rate_node = kzalloc_obj(*rate_node); if (!rate_node) return ERR_PTR(-ENOMEM); @@ -766,7 +766,7 @@ int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv, if (WARN_ON(devlink_port->devlink_rate)) return -EBUSY; - devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL); + devlink_rate = kzalloc_obj(*devlink_rate); if (!devlink_rate) return -ENOMEM; diff --git a/net/devlink/region.c b/net/devlink/region.c index d6e5805cf3a0..5588e3d560b9 100644 --- a/net/devlink/region.c +++ b/net/devlink/region.c @@ -428,7 +428,7 @@ __devlink_region_snapshot_create(struct devlink_region *region, if (devlink_region_snapshot_get_by_id(region, snapshot_id)) return -EEXIST; - snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); + snapshot = kzalloc_obj(*snapshot); if (!snapshot) return -ENOMEM; @@ -1055,7 +1055,7 @@ struct devlink_region *devl_region_create(struct devlink *devlink, if (devlink_region_get_by_name(devlink, ops->name)) return ERR_PTR(-EEXIST); - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) return ERR_PTR(-ENOMEM); @@ -1128,7 +1128,7 @@ devlink_port_region_create(struct devlink_port *port, goto unlock; } - region = kzalloc(sizeof(*region), GFP_KERNEL); + region = kzalloc_obj(*region); if (!region) { err = -ENOMEM; goto unlock; diff --git a/net/devlink/resource.c b/net/devlink/resource.c index 2d6324f3d91f..351835a710b1 100644 --- a/net/devlink/resource.c +++ b/net/devlink/resource.c @@ -347,7 +347,7 @@ int devl_resource_register(struct devlink *devlink, if (resource) return -EEXIST; - resource = kzalloc(sizeof(*resource), GFP_KERNEL); + resource = kzalloc_obj(*resource); if (!resource) return -ENOMEM; diff --git a/net/devlink/sb.c b/net/devlink/sb.c index 0a76bb32502b..49fcbfe08f15 100644 --- a/net/devlink/sb.c +++ b/net/devlink/sb.c @@ -943,7 +943,7 @@ int devl_sb_register(struct devlink *devlink, unsigned int sb_index, if (devlink_sb_index_exists(devlink, sb_index)) return -EEXIST; - devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL); + devlink_sb = kzalloc_obj(*devlink_sb); if (!devlink_sb) return -ENOMEM; devlink_sb->index = sb_index; diff --git a/net/devlink/trap.c b/net/devlink/trap.c index f36087f90db5..8edb31654a68 100644 --- a/net/devlink/trap.c +++ b/net/devlink/trap.c @@ -1271,7 +1271,7 @@ devlink_trap_register(struct devlink *devlink, if (devlink_trap_item_lookup(devlink, trap->name)) return -EEXIST; - trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL); + trap_item = kzalloc_obj(*trap_item); if (!trap_item) return -ENOMEM; @@ -1545,7 +1545,7 @@ devlink_trap_group_register(struct devlink *devlink, if (devlink_trap_group_item_lookup(devlink, group->name)) return -EEXIST; - group_item = kzalloc(sizeof(*group_item), GFP_KERNEL); + group_item = kzalloc_obj(*group_item); if (!group_item) return -ENOMEM; @@ -1751,7 +1751,7 @@ devlink_trap_policer_register(struct devlink *devlink, if (devlink_trap_policer_item_lookup(devlink, policer->id)) return -EEXIST; - policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL); + policer_item = kzalloc_obj(*policer_item); if (!policer_item) return -ENOMEM; diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 35ce3941fae3..9cb732f6b1e3 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c @@ -213,7 +213,7 @@ static struct dsa_switch_tree *dsa_tree_alloc(int index) { struct dsa_switch_tree *dst; - dst = kzalloc(sizeof(*dst), GFP_KERNEL); + dst = kzalloc_obj(*dst); if (!dst) return NULL; @@ -298,7 +298,7 @@ static struct dsa_link *dsa_link_touch(struct dsa_port *dp, if (dl->dp == dp && dl->link_dp == link_dp) return dl; - dl = kzalloc(sizeof(*dl), GFP_KERNEL); + dl = kzalloc_obj(*dl); if (!dl) return NULL; @@ -844,7 +844,7 @@ static int dsa_tree_setup_lags(struct dsa_switch_tree *dst) if (!len) return 0; - dst->lags = kcalloc(len, sizeof(*dst->lags), GFP_KERNEL); + dst->lags = kzalloc_objs(*dst->lags, len); if (!dst->lags) return -ENOMEM; @@ -1092,7 +1092,7 @@ static struct dsa_port *dsa_port_touch(struct dsa_switch *ds, int index) if (dp->index == index) return dp; - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); if (!dp) return NULL; diff --git a/net/dsa/port.c b/net/dsa/port.c index ca3a7f52229b..1f5536c0dffc 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -431,7 +431,7 @@ static int dsa_port_bridge_create(struct dsa_port *dp, return 0; } - bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); + bridge = kzalloc_obj(*bridge); if (!bridge) return -ENOMEM; @@ -617,7 +617,7 @@ static int dsa_port_lag_create(struct dsa_port *dp, return 0; } - lag = kzalloc(sizeof(*lag), GFP_KERNEL); + lag = kzalloc_obj(*lag); if (!lag) return -ENOMEM; diff --git a/net/dsa/switch.c b/net/dsa/switch.c index 3d2feeea897b..a670a04edb72 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -182,7 +182,7 @@ static int dsa_port_do_mdb_add(struct dsa_port *dp, goto out; } - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) { err = -ENOMEM; goto out; @@ -280,7 +280,7 @@ static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr, goto out; } - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) { err = -ENOMEM; goto out; @@ -368,7 +368,7 @@ static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag, goto out; } - a = kzalloc(sizeof(*a), GFP_KERNEL); + a = kzalloc_obj(*a); if (!a) { err = -ENOMEM; goto out; @@ -719,7 +719,7 @@ static int dsa_port_do_vlan_add(struct dsa_port *dp, goto out; } - v = kzalloc(sizeof(*v), GFP_KERNEL); + v = kzalloc_obj(*v); if (!v) { err = -ENOMEM; goto out; diff --git a/net/dsa/tag_8021q.c b/net/dsa/tag_8021q.c index 53e03fd8071b..f91646e60246 100644 --- a/net/dsa/tag_8021q.c +++ b/net/dsa/tag_8021q.c @@ -158,7 +158,7 @@ static int dsa_port_do_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, return 0; } - v = kzalloc(sizeof(*v), GFP_KERNEL); + v = kzalloc_obj(*v); if (!v) return -ENOMEM; @@ -420,7 +420,7 @@ int dsa_tag_8021q_register(struct dsa_switch *ds, __be16 proto) struct dsa_8021q_context *ctx; int err; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c index 9170a0148cc4..d2475c3bbb7d 100644 --- a/net/dsa/tag_ksz.c +++ b/net/dsa/tag_ksz.c @@ -62,7 +62,7 @@ static int ksz_connect(struct dsa_switch *ds) struct ksz_tagger_private *priv; int ret; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; @@ -258,7 +258,7 @@ static struct sk_buff *ksz_defer_xmit(struct dsa_port *dp, struct sk_buff *skb) if (!xmit_work_fn || !xmit_worker) return NULL; - xmit_work = kzalloc(sizeof(*xmit_work), GFP_ATOMIC); + xmit_work = kzalloc_obj(*xmit_work, GFP_ATOMIC); if (!xmit_work) return NULL; diff --git a/net/dsa/tag_ocelot_8021q.c b/net/dsa/tag_ocelot_8021q.c index 3929584791e4..e89d9254e90a 100644 --- a/net/dsa/tag_ocelot_8021q.c +++ b/net/dsa/tag_ocelot_8021q.c @@ -43,7 +43,7 @@ static struct sk_buff *ocelot_defer_xmit(struct dsa_port *dp, if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) return NULL; - xmit_work = kzalloc(sizeof(*xmit_work), GFP_ATOMIC); + xmit_work = kzalloc_obj(*xmit_work, GFP_ATOMIC); if (!xmit_work) return NULL; @@ -106,7 +106,7 @@ static int ocelot_connect(struct dsa_switch *ds) struct ocelot_8021q_tagger_private *priv; int err; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c index 6d56a28c914c..9e3b429e8b36 100644 --- a/net/dsa/tag_qca.c +++ b/net/dsa/tag_qca.c @@ -92,7 +92,7 @@ static int qca_tag_connect(struct dsa_switch *ds) { struct qca_tagger_data *tagger_data; - tagger_data = kzalloc(sizeof(*tagger_data), GFP_KERNEL); + tagger_data = kzalloc_obj(*tagger_data); if (!tagger_data) return -ENOMEM; diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c index 02adec693811..de6d4ce8668b 100644 --- a/net/dsa/tag_sja1105.c +++ b/net/dsa/tag_sja1105.c @@ -152,7 +152,7 @@ static struct sk_buff *sja1105_defer_xmit(struct dsa_port *dp, if (!xmit_work_fn || !xmit_worker) return NULL; - xmit_work = kzalloc(sizeof(*xmit_work), GFP_ATOMIC); + xmit_work = kzalloc_obj(*xmit_work, GFP_ATOMIC); if (!xmit_work) return NULL; @@ -701,7 +701,7 @@ static int sja1105_connect(struct dsa_switch *ds) struct kthread_worker *xmit_worker; int err; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (!priv) return -ENOMEM; diff --git a/net/dsa/user.c b/net/dsa/user.c index 5697291d43cf..c4bd6fe90b45 100644 --- a/net/dsa/user.c +++ b/net/dsa/user.c @@ -147,7 +147,7 @@ static int dsa_user_schedule_standalone_work(struct net_device *dev, { struct dsa_standalone_event_work *standalone_work; - standalone_work = kzalloc(sizeof(*standalone_work), GFP_ATOMIC); + standalone_work = kzalloc_obj(*standalone_work, GFP_ATOMIC); if (!standalone_work) return -ENOMEM; @@ -1318,7 +1318,7 @@ static int dsa_user_netpoll_setup(struct net_device *dev) struct netpoll *netpoll; int err = 0; - netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); + netpoll = kzalloc_obj(*netpoll); if (!netpoll) return -ENOMEM; @@ -1430,7 +1430,7 @@ dsa_user_add_cls_matchall_mirred(struct net_device *dev, return -EOPNOTSUPP; } - mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL); + mall_tc_entry = kzalloc_obj(*mall_tc_entry); if (!mall_tc_entry) return -ENOMEM; @@ -1490,7 +1490,7 @@ dsa_user_add_cls_matchall_police(struct net_device *dev, act = &cls->rule->action.entries[0]; - mall_tc_entry = kzalloc(sizeof(*mall_tc_entry), GFP_KERNEL); + mall_tc_entry = kzalloc_obj(*mall_tc_entry); if (!mall_tc_entry) return -ENOMEM; @@ -1823,7 +1823,7 @@ static int dsa_user_vlan_rx_add_vid(struct net_device *dev, __be16 proto, !dsa_switch_supports_mc_filtering(ds)) return 0; - v = kzalloc(sizeof(*v), GFP_KERNEL); + v = kzalloc_obj(*v); if (!v) { ret = -ENOMEM; goto rollback; @@ -2070,7 +2070,7 @@ static void dsa_bridge_mtu_normalization(struct dsa_port *dp) if (min_mtu > user->mtu) min_mtu = user->mtu; - hw_port = kzalloc(sizeof(*hw_port), GFP_KERNEL); + hw_port = kzalloc_obj(*hw_port); if (!hw_port) goto out; @@ -3738,7 +3738,7 @@ static int dsa_user_fdb_event(struct net_device *dev, return -EOPNOTSUPP; } - switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC); + switchdev_work = kzalloc_obj(*switchdev_work, GFP_ATOMIC); if (!switchdev_work) return -ENOMEM; diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c index 3057576bc81e..3670ca42dd40 100644 --- a/net/ethtool/cmis_cdb.c +++ b/net/ethtool/cmis_cdb.c @@ -276,7 +276,7 @@ ethtool_cmis_cdb_init(struct net_device *dev, struct ethtool_cmis_cdb *cdb; int err; - cdb = kzalloc(sizeof(*cdb), GFP_KERNEL); + cdb = kzalloc_obj(*cdb); if (!cdb) return ERR_PTR(-ENOMEM); diff --git a/net/ethtool/common.c b/net/ethtool/common.c index 5fae329795c8..e252cf20c22f 100644 --- a/net/ethtool/common.c +++ b/net/ethtool/common.c @@ -687,7 +687,7 @@ static int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max) if (rule_cnt <= 0) return -EINVAL; - info = kvzalloc(struct_size(info, rule_locs, rule_cnt), GFP_KERNEL); + info = kvzalloc_flex(*info, rule_locs, rule_cnt); if (!info) return -ENOMEM; @@ -770,7 +770,7 @@ static u32 ethtool_get_max_rxfh_channel(struct net_device *dev) if (dev_size == 0) return current_max; - rxfh.indir = kcalloc(dev_size, sizeof(rxfh.indir[0]), GFP_USER); + rxfh.indir = kzalloc_objs(rxfh.indir[0], dev_size, GFP_USER); if (!rxfh.indir) return U32_MAX; @@ -841,7 +841,7 @@ int ethtool_check_rss_ctx_busy(struct net_device *dev, u32 rss_context) if (rule_cnt < 0) return -EINVAL; - info = kvzalloc(struct_size(info, rule_locs, rule_cnt), GFP_KERNEL); + info = kvzalloc_flex(*info, rule_locs, rule_cnt); if (!info) return -ENOMEM; diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 9431e305b233..ff4b4780d6af 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -3040,7 +3040,7 @@ ethtool_set_per_queue_coalesce(struct net_device *dev, bitmap_from_arr32(queue_mask, per_queue_opt->queue_mask, MAX_NUM_QUEUE); n_queue = bitmap_weight(queue_mask, MAX_NUM_QUEUE); - tmp = backup = kmalloc_array(n_queue, sizeof(*backup), GFP_KERNEL); + tmp = backup = kmalloc_objs(*backup, n_queue); if (!backup) return -ENOMEM; @@ -3554,7 +3554,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr, void __user *useraddr) if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) return -EFAULT; - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) return -ENOMEM; diff --git a/net/ethtool/module.c b/net/ethtool/module.c index 4d4e0a82579a..0a761bf4771e 100644 --- a/net/ethtool/module.c +++ b/net/ethtool/module.c @@ -301,7 +301,7 @@ module_flash_fw_schedule(struct net_device *dev, const char *file_name, struct ethtool_module_fw_flash *module_fw; int err; - module_fw = kzalloc(sizeof(*module_fw), GFP_KERNEL); + module_fw = kzalloc_obj(*module_fw); if (!module_fw) return -ENOMEM; diff --git a/net/ethtool/mse.c b/net/ethtool/mse.c index 6aac004c3ffc..8cb3fc5e7be4 100644 --- a/net/ethtool/mse.c +++ b/net/ethtool/mse.c @@ -64,8 +64,7 @@ static int mse_get_channels(struct phy_device *phydev, if (!data->capability.supported_caps) return 0; - data->snapshots = kcalloc(PHY_MSE_CHANNEL_COUNT, - sizeof(*data->snapshots), GFP_KERNEL); + data->snapshots = kzalloc_objs(*data->snapshots, PHY_MSE_CHANNEL_COUNT); if (!data->snapshots) return -ENOMEM; diff --git a/net/ethtool/tsconfig.c b/net/ethtool/tsconfig.c index 169b413b31fc..e49e612a68c2 100644 --- a/net/ethtool/tsconfig.c +++ b/net/ethtool/tsconfig.c @@ -202,10 +202,10 @@ static int tsconfig_send_reply(struct net_device *dev, struct genl_info *info) int reply_len = 0; int ret; - req_info = kzalloc(sizeof(*req_info), GFP_KERNEL); + req_info = kzalloc_obj(*req_info); if (!req_info) return -ENOMEM; - reply_data = kmalloc(sizeof(*reply_data), GFP_KERNEL); + reply_data = kmalloc_obj(*reply_data); if (!reply_data) { kfree(req_info); return -ENOMEM; @@ -280,7 +280,7 @@ tsconfig_set_hwprov_from_desc(struct net_device *dev, source = HWTSTAMP_SOURCE_PHYLIB; } - hwprov = kzalloc(sizeof(*hwprov), GFP_KERNEL); + hwprov = kzalloc_obj(*hwprov); if (!hwprov) return ERR_PTR(-ENOMEM); diff --git a/net/ethtool/tsinfo.c b/net/ethtool/tsinfo.c index 8c654caa6805..c0145c752d2f 100644 --- a/net/ethtool/tsinfo.c +++ b/net/ethtool/tsinfo.c @@ -505,10 +505,10 @@ int ethnl_tsinfo_start(struct netlink_callback *cb) BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx)); - req_info = kzalloc(sizeof(*req_info), GFP_KERNEL); + req_info = kzalloc_obj(*req_info); if (!req_info) return -ENOMEM; - reply_data = kzalloc(sizeof(*reply_data), GFP_KERNEL); + reply_data = kzalloc_obj(*reply_data); if (!reply_data) { ret = -ENOMEM; goto free_req_info; diff --git a/net/handshake/request.c b/net/handshake/request.c index 6b7e3e0bf399..2829adbeb149 100644 --- a/net/handshake/request.c +++ b/net/handshake/request.c @@ -119,7 +119,7 @@ struct handshake_req *handshake_req_alloc(const struct handshake_proto *proto, if (!proto->hp_accept || !proto->hp_done) return NULL; - req = kzalloc(struct_size(req, hr_priv, proto->hp_privsize), flags); + req = kzalloc_flex(*req, hr_priv, proto->hp_privsize, flags); if (!req) return NULL; diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 7d87f304ded4..50996f4de7f9 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c @@ -80,7 +80,7 @@ int hsr_create_self_node(struct hsr_priv *hsr, { struct hsr_self_node *sn, *old; - sn = kmalloc(sizeof(*sn), GFP_KERNEL); + sn = kmalloc_obj(*sn); if (!sn) return -ENOMEM; @@ -159,7 +159,7 @@ static struct hsr_node *hsr_add_node(struct hsr_priv *hsr, size_t block_sz; int i; - new_node = kzalloc(sizeof(*new_node), GFP_ATOMIC); + new_node = kzalloc_obj(*new_node, GFP_ATOMIC); if (!new_node) return NULL; diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index afe06ba00ea4..44f83c8c56a7 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c @@ -198,7 +198,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, if (port) return -EBUSY; /* This port already exists */ - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c index 5a024ca60d35..115f43d0e158 100644 --- a/net/ieee802154/nl802154.c +++ b/net/ieee802154/nl802154.c @@ -603,7 +603,7 @@ nl802154_dump_wpan_phy(struct sk_buff *skb, struct netlink_callback *cb) rtnl_lock(); if (!state) { - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { rtnl_unlock(); return -ENOMEM; @@ -1418,7 +1418,7 @@ static int nl802154_trigger_scan(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; } - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) return -ENOMEM; @@ -1586,7 +1586,7 @@ nl802154_send_beacons(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; } - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) return -ENOMEM; diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index b71c22475c51..df922f9f5289 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -748,6 +748,7 @@ config TCP_SIGPOOL config TCP_AO bool "TCP: Authentication Option (RFC5925)" select CRYPTO + select CRYPTO_LIB_UTILS select TCP_SIGPOOL depends on 64BIT && IPV6 != m # seq-number extension needs WRITE_ONCE(u64) help @@ -761,6 +762,7 @@ config TCP_AO config TCP_MD5SIG bool "TCP: MD5 Signature Option support (RFC2385)" select CRYPTO_LIB_MD5 + select CRYPTO_LIB_UTILS help RFC2385 specifies a method of giving MD5 protection to TCP sessions. Its main (only?) use is to protect BGP sessions between core routers diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 08d811f11896..c7731e300a44 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -124,6 +124,12 @@ #include +/* Keep the definition of IPv6 disable here for now, to avoid annoying linker + * issues in case IPv6=m + */ +int disable_ipv6_mod; +EXPORT_SYMBOL(disable_ipv6_mod); + /* The inetsw table contains everything that inet_create needs to * build a new socket. */ @@ -1737,8 +1743,7 @@ static __net_init int ipv4_mib_init_net(struct net *net) net->mib.icmp_statistics = alloc_percpu(struct icmp_mib); if (!net->mib.icmp_statistics) goto err_icmp_mib; - net->mib.icmpmsg_statistics = kzalloc(sizeof(struct icmpmsg_mib), - GFP_KERNEL); + net->mib.icmpmsg_statistics = kzalloc_obj(struct icmpmsg_mib); if (!net->mib.icmpmsg_statistics) goto err_icmpmsg_mib; diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c index 64aec3dff8ec..5fb812443a08 100644 --- a/net/ipv4/ah4.c +++ b/net/ipv4/ah4.c @@ -484,7 +484,7 @@ static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack) goto error; } - ahp = kzalloc(sizeof(*ahp), GFP_KERNEL); + ahp = kzalloc_obj(*ahp); if (!ahp) return -ENOMEM; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 32b951ebc0c2..a05aa075de1a 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -168,9 +168,8 @@ static int __init cipso_v4_cache_init(void) { u32 iter; - cipso_v4_cache = kcalloc(CIPSO_V4_CACHE_BUCKETS, - sizeof(struct cipso_v4_map_cache_bkt), - GFP_KERNEL); + cipso_v4_cache = kzalloc_objs(struct cipso_v4_map_cache_bkt, + CIPSO_V4_CACHE_BUCKETS); if (!cipso_v4_cache) return -ENOMEM; @@ -308,7 +307,7 @@ int cipso_v4_cache_add(const unsigned char *cipso_ptr, cipso_ptr_len = cipso_ptr[1]; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC); diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 942a887bf089..537bb6c315d2 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -209,7 +209,7 @@ static struct in_ifaddr *inet_alloc_ifa(struct in_device *in_dev) { struct in_ifaddr *ifa; - ifa = kzalloc(sizeof(*ifa), GFP_KERNEL_ACCOUNT); + ifa = kzalloc_obj(*ifa, GFP_KERNEL_ACCOUNT); if (!ifa) return NULL; @@ -270,7 +270,7 @@ static struct in_device *inetdev_init(struct net_device *dev) ASSERT_RTNL(); - in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL); + in_dev = kzalloc_obj(*in_dev); if (!in_dev) goto out; memcpy(&in_dev->cnf, dev_net(dev)->ipv4.devconf_dflt, @@ -2754,9 +2754,8 @@ static __net_init int devinet_init_net(struct net *net) int i; err = -ENOMEM; - net->ipv4.inet_addr_lst = kmalloc_array(IN4_ADDR_HSIZE, - sizeof(struct hlist_head), - GFP_KERNEL); + net->ipv4.inet_addr_lst = kmalloc_objs(struct hlist_head, + IN4_ADDR_HSIZE); if (!net->ipv4.inet_addr_lst) goto err_alloc_hash; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 0caf38e44c73..01cb587866d8 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -365,8 +365,7 @@ static struct hlist_head *fib_info_laddrhash_bucket(const struct net *net, static struct hlist_head *fib_info_hash_alloc(unsigned int hash_bits) { /* The second half is used for prefsrc */ - return kvcalloc((1 << hash_bits) * 2, sizeof(struct hlist_head), - GFP_KERNEL); + return kvzalloc_objs(struct hlist_head, (1 << hash_bits) * 2); } static void fib_info_hash_free(struct hlist_head *head) @@ -1399,7 +1398,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg, fib_info_hash_grow(net); - fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL); + fi = kzalloc_flex(*fi, fib_nh, nhs); if (!fi) { err = -ENOBUFS; goto failure; diff --git a/net/ipv4/fou_core.c b/net/ipv4/fou_core.c index ab8f309f8925..3baaa4df7e42 100644 --- a/net/ipv4/fou_core.c +++ b/net/ipv4/fou_core.c @@ -581,7 +581,7 @@ static int fou_create(struct net *net, struct fou_cfg *cfg, goto error; /* Allocate FOU port structure */ - fou = kzalloc(sizeof(*fou), GFP_KERNEL); + fou = kzalloc_obj(*fou); if (!fou) { err = -ENOMEM; goto error; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e216b6df6331..a62b4c4033cc 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -250,7 +250,8 @@ bool icmp_global_allow(struct net *net) if (delta < HZ / 50) return false; - incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec) * delta / HZ; + incr = READ_ONCE(net->ipv4.sysctl_icmp_msgs_per_sec); + incr = div_u64((u64)incr * delta, HZ); if (!incr) return false; @@ -315,23 +316,29 @@ static bool icmpv4_xrlim_allow(struct net *net, struct rtable *rt, struct dst_entry *dst = &rt->dst; struct inet_peer *peer; struct net_device *dev; + int peer_timeout; bool rc = true; if (!apply_ratelimit) return true; + peer_timeout = READ_ONCE(net->ipv4.sysctl_icmp_ratelimit); + if (!peer_timeout) + goto out; + /* No rate limit on loopback */ rcu_read_lock(); dev = dst_dev_rcu(dst); if (dev && (dev->flags & IFF_LOOPBACK)) - goto out; + goto out_unlock; peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, l3mdev_master_ifindex_rcu(dev)); - rc = inet_peer_xrlim_allow(peer, - READ_ONCE(net->ipv4.sysctl_icmp_ratelimit)); -out: + rc = inet_peer_xrlim_allow(peer, peer_timeout); + +out_unlock: rcu_read_unlock(); +out: if (!rc) __ICMP_INC_STATS(net, ICMP_MIB_RATELIMITHOST); else diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 0adc993c211d..a674fb44ec25 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1187,7 +1187,7 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im, * for deleted items allows change reports to use common code with * non-deleted or query-response MCA's. */ - pmc = kzalloc(sizeof(*pmc), gfp); + pmc = kzalloc_obj(*pmc, gfp); if (!pmc) return; spin_lock_init(&pmc->lock); @@ -1532,7 +1532,7 @@ static void ____ip_mc_inc_group(struct in_device *in_dev, __be32 addr, goto out; } - im = kzalloc(sizeof(*im), gfp); + im = kzalloc_obj(*im, gfp); if (!im) goto out; @@ -2075,7 +2075,7 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode, psf_prev = psf; } if (!psf) { - psf = kzalloc(sizeof(*psf), GFP_ATOMIC); + psf = kzalloc_obj(*psf, GFP_ATOMIC); if (!psf) return -ENOBUFS; psf->sf_inaddr = *psfsrc; @@ -2150,7 +2150,7 @@ static int sf_setstate(struct ip_mc_list *pmc) if (dpsf->sf_inaddr == psf->sf_inaddr) break; if (!dpsf) { - dpsf = kmalloc(sizeof(*dpsf), GFP_ATOMIC); + dpsf = kmalloc_obj(*dpsf, GFP_ATOMIC); if (!dpsf) continue; *dpsf = *psf; diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 3f5b1418a610..9d215485b5c7 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -845,7 +845,7 @@ static int __inet_diag_dump_start(struct netlink_callback *cb, int hdrlen) struct nlattr *nla; int err; - cb_data = kzalloc(sizeof(*cb_data), GFP_KERNEL); + cb_data = kzalloc_obj(*cb_data); if (!cb_data) return -ENOMEM; diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index 4e6d7467ed44..393770920abd 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -188,7 +188,7 @@ static void fqdir_work_fn(struct work_struct *work) int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net) { - struct fqdir *fqdir = kzalloc(sizeof(*fqdir), GFP_KERNEL); + struct fqdir *fqdir = kzalloc_obj(*fqdir); int res; if (!fqdir) diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index f5826ec4bcaa..9bfccc283fa6 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c @@ -200,7 +200,7 @@ static bool inet_bind2_bucket_addr_match(const struct inet_bind2_bucket *tb2, void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, struct inet_bind2_bucket *tb2, unsigned short port) { - inet_sk(sk)->inet_num = port; + WRITE_ONCE(inet_sk(sk)->inet_num, port); inet_csk(sk)->icsk_bind_hash = tb; inet_csk(sk)->icsk_bind2_hash = tb2; sk_add_bind_node(sk, &tb2->owners); @@ -224,7 +224,7 @@ static void __inet_put_port(struct sock *sk) spin_lock(&head->lock); tb = inet_csk(sk)->icsk_bind_hash; inet_csk(sk)->icsk_bind_hash = NULL; - inet_sk(sk)->inet_num = 0; + WRITE_ONCE(inet_sk(sk)->inet_num, 0); sk->sk_userlocks &= ~SOCK_CONNECT_BIND; spin_lock(&head2->lock); @@ -352,7 +352,7 @@ static inline int compute_score(struct sock *sk, const struct net *net, { int score = -1; - if (net_eq(sock_net(sk), net) && sk->sk_num == hnum && + if (net_eq(sock_net(sk), net) && READ_ONCE(sk->sk_num) == hnum && !ipv6_only_sock(sk)) { if (sk->sk_rcv_saddr != daddr) return -1; @@ -1206,7 +1206,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, sk->sk_hash = 0; inet_sk(sk)->inet_sport = 0; - inet_sk(sk)->inet_num = 0; + WRITE_ONCE(inet_sk(sk)->inet_num, 0); if (tw) inet_twsk_bind_unhash(tw, hinfo); @@ -1284,7 +1284,7 @@ void __init inet_hashinfo2_init(struct inet_hashinfo *h, const char *name, int inet_hashinfo2_init_mod(struct inet_hashinfo *h) { - h->lhash2 = kmalloc_array(INET_LHTABLE_SIZE, sizeof(*h->lhash2), GFP_KERNEL); + h->lhash2 = kmalloc_objs(*h->lhash2, INET_LHTABLE_SIZE); if (!h->lhash2) return -ENOMEM; diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index c062d9519818..697e18242d6c 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -350,7 +350,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW) return -EINVAL; - new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; + new_ra = on ? kmalloc_obj(*new_ra) : NULL; if (on && !new_ra) return -ENOMEM; diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 2e61ac137128..5683c328990f 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c @@ -58,6 +58,19 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, struct iphdr *iph; int err; + if (unlikely(dev_recursion_level() > IP_TUNNEL_RECURSION_LIMIT)) { + if (dev) { + net_crit_ratelimited("Dead loop on virtual device %s, fix it urgently!\n", + dev->name); + DEV_STATS_INC(dev, tx_errors); + } + ip_rt_put(rt); + kfree_skb(skb); + return; + } + + dev_xmit_recursion_inc(); + skb_scrub_packet(skb, xnet); skb_clear_hash_if_not_l4(skb); @@ -88,6 +101,8 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb, pkt_len = 0; iptunnel_xmit_stats(dev, pkt_len); } + + dev_xmit_recursion_dec(); } EXPORT_SYMBOL_GPL(iptunnel_xmit); diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index b1e1be00ff8b..a35ffedacc7c 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -244,7 +244,7 @@ static int __init ic_open_devs(void) dev->name); continue; } - if (!(d = kmalloc(sizeof(struct ic_device), GFP_KERNEL))) { + if (!(d = kmalloc_obj(struct ic_device))) { rtnl_unlock(); return -ENOMEM; } diff --git a/net/ipv4/ipmr_base.c b/net/ipv4/ipmr_base.c index 28d77d454d44..2d62526406ca 100644 --- a/net/ipv4/ipmr_base.c +++ b/net/ipv4/ipmr_base.c @@ -38,7 +38,7 @@ mr_table_alloc(struct net *net, u32 id, struct mr_table *mrt; int err; - mrt = kzalloc(sizeof(*mrt), GFP_KERNEL); + mrt = kzalloc_obj(*mrt); if (!mrt) return ERR_PTR(-ENOMEM); mrt->id = id; diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c index 82cf8a9e5ded..c1463add48c4 100644 --- a/net/ipv4/metrics.c +++ b/net/ipv4/metrics.c @@ -73,7 +73,7 @@ struct dst_metrics *ip_fib_metrics_init(struct nlattr *fc_mx, if (!fc_mx) return (struct dst_metrics *)&dst_default_metrics; - fib_metrics = kzalloc(sizeof(*fib_metrics), GFP_KERNEL); + fib_metrics = kzalloc_obj(*fib_metrics); if (unlikely(!fib_metrics)) return ERR_PTR(-ENOMEM); diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 7b9d70f9b31c..c942f1282236 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -116,7 +116,7 @@ static int nh_notifier_single_info_init(struct nh_notifier_info *info, struct nh_info *nhi = rtnl_dereference(nh->nh_info); info->type = NH_NOTIFIER_INFO_TYPE_SINGLE; - info->nh = kzalloc(sizeof(*info->nh), GFP_KERNEL); + info->nh = kzalloc_obj(*info->nh); if (!info->nh) return -ENOMEM; @@ -137,8 +137,7 @@ static int nh_notifier_mpath_info_init(struct nh_notifier_info *info, int i; info->type = NH_NOTIFIER_INFO_TYPE_GRP; - info->nh_grp = kzalloc(struct_size(info->nh_grp, nh_entries, num_nh), - GFP_KERNEL); + info->nh_grp = kzalloc_flex(*info->nh_grp, nh_entries, num_nh); if (!info->nh_grp) return -ENOMEM; @@ -318,8 +317,7 @@ static int nh_notifier_res_bucket_info_init(struct nh_notifier_info *info, return err; info->type = NH_NOTIFIER_INFO_TYPE_RES_BUCKET; - info->nh_res_bucket = kzalloc(sizeof(*info->nh_res_bucket), - GFP_KERNEL); + info->nh_res_bucket = kzalloc_obj(*info->nh_res_bucket); if (!info->nh_res_bucket) return -ENOMEM; @@ -535,7 +533,7 @@ static struct nexthop *nexthop_alloc(void) { struct nexthop *nh; - nh = kzalloc(sizeof(struct nexthop), GFP_KERNEL); + nh = kzalloc_obj(struct nexthop); if (nh) { INIT_LIST_HEAD(&nh->fi_list); INIT_LIST_HEAD(&nh->f6i_list); @@ -550,7 +548,7 @@ static struct nh_group *nexthop_grp_alloc(u16 num_nh) { struct nh_group *nhg; - nhg = kzalloc(struct_size(nhg, nh_entries, num_nh), GFP_KERNEL); + nhg = kzalloc_flex(*nhg, nh_entries, num_nh); if (nhg) nhg->num_nh = num_nh; @@ -715,9 +713,8 @@ static int nh_notifier_grp_hw_stats_init(struct nh_notifier_info *info, info->id = nh->id; info->type = NH_NOTIFIER_INFO_TYPE_GRP_HW_STATS; - info->nh_grp_hw_stats = kzalloc(struct_size(info->nh_grp_hw_stats, - stats, nhg->num_nh), - GFP_KERNEL); + info->nh_grp_hw_stats = kzalloc_flex(*info->nh_grp_hw_stats, stats, + nhg->num_nh); if (!info->nh_grp_hw_stats) return -ENOMEM; @@ -2005,7 +2002,8 @@ static void nh_hthr_group_rebalance(struct nh_group *nhg) } static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge, - struct nl_info *nlinfo) + struct nl_info *nlinfo, + struct list_head *deferred_free) { struct nh_grp_entry *nhges, *new_nhges; struct nexthop *nhp = nhge->nh_parent; @@ -2065,8 +2063,8 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge, rcu_assign_pointer(nhp->nh_grp, newg); list_del(&nhge->nh_list); - free_percpu(nhge->stats); nexthop_put(nhge->nh); + list_add(&nhge->nh_list, deferred_free); /* Removal of a NH from a resilient group is notified through * bucket notifications. @@ -2086,6 +2084,7 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, struct nl_info *nlinfo) { struct nh_grp_entry *nhge, *tmp; + LIST_HEAD(deferred_free); /* If there is nothing to do, let's avoid the costly call to * synchronize_net() @@ -2094,10 +2093,16 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, return; list_for_each_entry_safe(nhge, tmp, &nh->grp_list, nh_list) - remove_nh_grp_entry(net, nhge, nlinfo); + remove_nh_grp_entry(net, nhge, nlinfo, &deferred_free); /* make sure all see the newly published array before releasing rtnl */ synchronize_net(); + + /* Now safe to free percpu stats — all RCU readers have finished */ + list_for_each_entry_safe(nhge, tmp, &deferred_free, nh_list) { + list_del(&nhge->nh_list); + free_percpu(nhge->stats); + } } static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo) @@ -2897,7 +2902,7 @@ static struct nexthop *nexthop_create(struct net *net, struct nh_config *cfg, if (!nh) return ERR_PTR(-ENOMEM); - nhi = kzalloc(sizeof(*nhi), GFP_KERNEL); + nhi = kzalloc_obj(*nhi); if (!nhi) { kfree(nh); return ERR_PTR(-ENOMEM); diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index ebfc5a3d3ad6..71d5e17719de 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -148,7 +148,7 @@ void ping_unhash(struct sock *sk) pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num); spin_lock(&ping_table.lock); if (sk_del_node_init_rcu(sk)) { - isk->inet_num = 0; + WRITE_ONCE(isk->inet_num, 0); isk->inet_sport = 0; sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); } @@ -181,31 +181,35 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) } sk_for_each_rcu(sk, hslot) { + int bound_dev_if; + if (!net_eq(sock_net(sk), net)) continue; isk = inet_sk(sk); pr_debug("iterate\n"); - if (isk->inet_num != ident) + if (READ_ONCE(isk->inet_num) != ident) continue; + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); if (skb->protocol == htons(ETH_P_IP) && sk->sk_family == AF_INET) { - pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, - (int) isk->inet_num, &isk->inet_rcv_saddr, - sk->sk_bound_dev_if); + __be32 rcv_saddr = READ_ONCE(isk->inet_rcv_saddr); - if (isk->inet_rcv_saddr && - isk->inet_rcv_saddr != ip_hdr(skb)->daddr) + pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk, + ident, &rcv_saddr, + bound_dev_if); + + if (rcv_saddr && rcv_saddr != ip_hdr(skb)->daddr) continue; #if IS_ENABLED(CONFIG_IPV6) } else if (skb->protocol == htons(ETH_P_IPV6) && sk->sk_family == AF_INET6) { pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk, - (int) isk->inet_num, + ident, &sk->sk_v6_rcv_saddr, - sk->sk_bound_dev_if); + bound_dev_if); if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) && !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, @@ -216,8 +220,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) continue; } - if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif && - sk->sk_bound_dev_if != sdif) + if (bound_dev_if && bound_dev_if != dif && + bound_dev_if != sdif) continue; goto exit; @@ -392,7 +396,9 @@ static void ping_set_saddr(struct sock *sk, struct sockaddr_unsized *saddr) if (saddr->sa_family == AF_INET) { struct inet_sock *isk = inet_sk(sk); struct sockaddr_in *addr = (struct sockaddr_in *) saddr; - isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr; + + isk->inet_saddr = addr->sin_addr.s_addr; + WRITE_ONCE(isk->inet_rcv_saddr, addr->sin_addr.s_addr); #if IS_ENABLED(CONFIG_IPV6) } else if (saddr->sa_family == AF_INET6) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr; @@ -850,7 +856,8 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int flags, struct sk_buff *skb; int copied, err; - pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num); + pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, + READ_ONCE(isk->inet_num)); err = -EOPNOTSUPP; if (flags & MSG_OOB) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 06aa39ae80d6..463236e0dc2d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -315,7 +315,7 @@ static int rt_acct_proc_show(struct seq_file *m, void *v) struct ip_rt_acct *dst, *src; unsigned int i, j; - dst = kcalloc(256, sizeof(struct ip_rt_acct), GFP_KERNEL); + dst = kzalloc_objs(struct ip_rt_acct, 256); if (!dst) return -ENOMEM; @@ -659,7 +659,7 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr, hash = rcu_dereference(nhc->nhc_exceptions); if (!hash) { - hash = kcalloc(FNHE_HASH_SIZE, sizeof(*hash), GFP_ATOMIC); + hash = kzalloc_objs(*hash, FNHE_HASH_SIZE, GFP_ATOMIC); if (!hash) goto out_unlock; rcu_assign_pointer(nhc->nhc_exceptions, hash); @@ -702,7 +702,7 @@ static void update_or_create_fnhe(struct fib_nh_common *nhc, __be32 daddr, depth--; } - fnhe = kzalloc(sizeof(*fnhe), GFP_ATOMIC); + fnhe = kzalloc_obj(*fnhe, GFP_ATOMIC); if (!fnhe) goto out_unlock; @@ -3687,7 +3687,7 @@ static __net_initdata struct pernet_operations rt_genid_ops = { static int __net_init ipv4_inetpeer_init(struct net *net) { - struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); + struct inet_peer_base *bp = kmalloc_obj(*bp); if (!bp) return -ENOMEM; diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 569befcf021b..fc3affd9c801 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c @@ -203,7 +203,7 @@ struct sock *tcp_get_cookie_sock(struct sock *sk, struct sk_buff *skb, bool own_req; child = icsk->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - NULL, &own_req); + NULL, &own_req, NULL); if (child) { refcount_set(&req->rsk_refcnt, 1); sock_rps_save_rxhash(child, skb); @@ -378,9 +378,14 @@ static struct request_sock *cookie_tcp_check(struct net *net, struct sock *sk, tcp_parse_options(net, skb, &tcp_opt, 0, NULL); if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcp_ts_off(net, - ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr); + union tcp_seq_and_ts_off st; + + st = secure_tcp_seq_and_ts_off(net, + ip_hdr(skb)->daddr, + ip_hdr(skb)->saddr, + tcp_hdr(skb)->dest, + tcp_hdr(skb)->source); + tsoff = st.ts_off; tcp_opt.rcv_tsecr -= tsoff; } diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 643763bc2142..5654cc9c8a0b 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -486,7 +486,8 @@ static void proc_fib_multipath_hash_set_seed(struct net *net, u32 user_seed) proc_fib_multipath_hash_rand_seed), }; - WRITE_ONCE(net->ipv4.sysctl_fib_multipath_hash_seed, new); + WRITE_ONCE(net->ipv4.sysctl_fib_multipath_hash_seed.user_seed, new.user_seed); + WRITE_ONCE(net->ipv4.sysctl_fib_multipath_hash_seed.mp_seed, new.mp_seed); } static int proc_fib_multipath_hash_seed(const struct ctl_table *table, int write, @@ -500,7 +501,7 @@ static int proc_fib_multipath_hash_seed(const struct ctl_table *table, int write int ret; mphs = &net->ipv4.sysctl_fib_multipath_hash_seed; - user_seed = mphs->user_seed; + user_seed = READ_ONCE(mphs->user_seed); tmp = *table; tmp.data = &user_seed; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 6ce03a9adb4a..202a4e57a218 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -244,6 +244,7 @@ #define pr_fmt(fmt) "TCP: " fmt #include +#include #include #include #include @@ -1077,8 +1078,8 @@ int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *copied, if (tp->fastopen_req) return -EALREADY; /* Another Fast Open is in progress */ - tp->fastopen_req = kzalloc(sizeof(struct tcp_fastopen_request), - sk->sk_allocation); + tp->fastopen_req = kzalloc_obj(struct tcp_fastopen_request, + sk->sk_allocation); if (unlikely(!tp->fastopen_req)) return -ENOBUFS; tp->fastopen_req->data = msg; @@ -1446,7 +1447,7 @@ int tcp_sendmsg_locked(struct sock *sk, struct msghdr *msg, size_t size) err = sk_stream_error(sk, flags, err); /* make sure we wake any epoll edge trigger waiter */ if (unlikely(tcp_rtx_and_write_queues_empty(sk) && err == -EAGAIN)) { - sk->sk_write_space(sk); + READ_ONCE(sk->sk_write_space)(sk); tcp_chrono_stop(sk, TCP_CHRONO_SNDBUF_LIMITED); } if (binding) @@ -4181,7 +4182,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname, break; case TCP_NOTSENT_LOWAT: WRITE_ONCE(tp->notsent_lowat, val); - sk->sk_write_space(sk); + READ_ONCE(sk->sk_write_space)(sk); break; case TCP_INQ: if (val > 1 || val < 0) @@ -4970,7 +4971,7 @@ tcp_inbound_md5_hash(const struct sock *sk, const struct sk_buff *skb, tcp_v4_md5_hash_skb(newhash, key, NULL, skb); else tp->af_specific->calc_md5_hash(newhash, key, NULL, skb); - if (memcmp(hash_location, newhash, 16) != 0) { + if (crypto_memneq(hash_location, newhash, 16)) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPMD5FAILURE); trace_tcp_hash_md5_mismatch(sk, skb); return SKB_DROP_REASON_TCP_MD5FAILURE; diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c index 34b8450829d0..a97cdf3e6af4 100644 --- a/net/ipv4/tcp_ao.c +++ b/net/ipv4/tcp_ao.c @@ -10,6 +10,7 @@ #define pr_fmt(fmt) "TCP: " fmt #include +#include #include #include @@ -227,7 +228,7 @@ static struct tcp_ao_info *tcp_ao_alloc_info(gfp_t flags) { struct tcp_ao_info *ao; - ao = kzalloc(sizeof(*ao), flags); + ao = kzalloc_obj(*ao, flags); if (!ao) return NULL; INIT_HLIST_HEAD(&ao->head); @@ -922,7 +923,7 @@ tcp_ao_verify_hash(const struct sock *sk, const struct sk_buff *skb, /* XXX: make it per-AF callback? */ tcp_ao_hash_skb(family, hash_buf, key, sk, skb, traffic_key, (phash - (u8 *)th), sne); - if (memcmp(phash, hash_buf, maclen)) { + if (crypto_memneq(phash, hash_buf, maclen)) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPAOBAD); atomic64_inc(&info->counters.pkt_bad); atomic64_inc(&key->pkt_bad); diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c index ca8a5cb8e569..813d2e498c93 100644 --- a/net/ipv4/tcp_bpf.c +++ b/net/ipv4/tcp_bpf.c @@ -39,7 +39,7 @@ static int bpf_tcp_ingress(struct sock *sk, struct sk_psock *psock, struct sk_msg *tmp; int i, ret = 0; - tmp = kzalloc(sizeof(*tmp), __GFP_NOWARN | GFP_KERNEL); + tmp = kzalloc_obj(*tmp, __GFP_NOWARN | GFP_KERNEL); if (unlikely(!tmp)) return -ENOMEM; @@ -426,8 +426,8 @@ static int tcp_bpf_send_verdict(struct sock *sk, struct sk_psock *psock, msg->cork_bytes > msg->sg.size && !enospc) { psock->cork_bytes = msg->cork_bytes - msg->sg.size; if (!psock->cork) { - psock->cork = kzalloc(sizeof(*psock->cork), - GFP_ATOMIC | __GFP_NOWARN); + psock->cork = kzalloc_obj(*psock->cork, + GFP_ATOMIC | __GFP_NOWARN); if (!psock->cork) { sk_msg_free(sk, msg); *copied = 0; @@ -725,7 +725,7 @@ int tcp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) WRITE_ONCE(sk->sk_prot->unhash, psock->saved_unhash); tcp_update_ulp(sk, psock->sk_proto, psock->saved_write_space); } else { - sk->sk_write_space = psock->saved_write_space; + WRITE_ONCE(sk->sk_write_space, psock->saved_write_space); /* Pairs with lockless read in sk_clone_lock() */ sock_replace_proto(sk, psock->sk_proto); } diff --git a/net/ipv4/tcp_cdg.c b/net/ipv4/tcp_cdg.c index fbad6c35dee9..ceabfd690a29 100644 --- a/net/ipv4/tcp_cdg.c +++ b/net/ipv4/tcp_cdg.c @@ -378,8 +378,8 @@ static void tcp_cdg_init(struct sock *sk) ca->gradients = NULL; /* We silently fall back to window = 1 if allocation fails. */ if (window > 1) - ca->gradients = kcalloc(window, sizeof(ca->gradients[0]), - GFP_NOWAIT); + ca->gradients = kzalloc_objs(ca->gradients[0], window, + GFP_NOWAIT); ca->rtt_seq = tp->snd_nxt; ca->shadow_wnd = tcp_snd_cwnd(tp); } diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index d83efd91f461..7935702e394b 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -509,7 +509,7 @@ static void tcp_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, if (r->sdiag_family != AF_UNSPEC && sk->sk_family != r->sdiag_family) goto next_normal; - if (r->id.idiag_sport != htons(sk->sk_num) && + if (r->id.idiag_sport != htons(READ_ONCE(sk->sk_num)) && r->id.idiag_sport) goto next_normal; if (r->id.idiag_dport != sk->sk_dport && diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c index b30090cff3cf..9fdc19accafd 100644 --- a/net/ipv4/tcp_fastopen.c +++ b/net/ipv4/tcp_fastopen.c @@ -149,7 +149,7 @@ int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk, struct fastopen_queue *q; int err = 0; - ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kmalloc_obj(*ctx); if (!ctx) { err = -ENOMEM; goto out; @@ -333,7 +333,7 @@ static struct sock *tcp_fastopen_create_child(struct sock *sk, bool own_req; child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, - NULL, &own_req); + NULL, &own_req, NULL); if (!child) return NULL; @@ -549,8 +549,8 @@ bool tcp_fastopen_defer_connect(struct sock *sk, int *err) /* Alloc fastopen_req in order for FO option to be included * in SYN */ - tp->fastopen_req = kzalloc(sizeof(*tp->fastopen_req), - sk->sk_allocation); + tp->fastopen_req = kzalloc_obj(*tp->fastopen_req, + sk->sk_allocation); if (tp->fastopen_req) tp->fastopen_req->cookie = cookie; else diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index e7b41abb82aa..cba89733d121 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -4858,15 +4858,24 @@ static enum skb_drop_reason tcp_disordered_ack_check(const struct sock *sk, */ static enum skb_drop_reason tcp_sequence(const struct sock *sk, - u32 seq, u32 end_seq) + u32 seq, u32 end_seq, + const struct tcphdr *th) { const struct tcp_sock *tp = tcp_sk(sk); + u32 seq_limit; if (before(end_seq, tp->rcv_wup)) return SKB_DROP_REASON_TCP_OLD_SEQUENCE; - if (after(end_seq, tp->rcv_nxt + tcp_receive_window(tp))) { - if (after(seq, tp->rcv_nxt + tcp_receive_window(tp))) + seq_limit = tp->rcv_nxt + tcp_receive_window(tp); + if (unlikely(after(end_seq, seq_limit))) { + /* Some stacks are known to handle FIN incorrectly; allow the + * FIN to extend beyond the window and check it in detail later. + */ + if (!after(end_seq - th->fin, seq_limit)) + return SKB_NOT_DROPPED_YET; + + if (after(seq, seq_limit)) return SKB_DROP_REASON_TCP_INVALID_SEQUENCE; /* Only accept this packet if receive queue is empty. */ @@ -5365,25 +5374,11 @@ static void tcp_ofo_queue(struct sock *sk) static bool tcp_prune_ofo_queue(struct sock *sk, const struct sk_buff *in_skb); static int tcp_prune_queue(struct sock *sk, const struct sk_buff *in_skb); -/* Check if this incoming skb can be added to socket receive queues - * while satisfying sk->sk_rcvbuf limit. - * - * In theory we should use skb->truesize, but this can cause problems - * when applications use too small SO_RCVBUF values. - * When LRO / hw gro is used, the socket might have a high tp->scaling_ratio, - * allowing RWIN to be close to available space. - * Whenever the receive queue gets full, we can receive a small packet - * filling RWIN, but with a high skb->truesize, because most NIC use 4K page - * plus sk_buff metadata even when receiving less than 1500 bytes of payload. - * - * Note that we use skb->len to decide to accept or drop this packet, - * but sk->sk_rmem_alloc is the sum of all skb->truesize. - */ static bool tcp_can_ingest(const struct sock *sk, const struct sk_buff *skb) { unsigned int rmem = atomic_read(&sk->sk_rmem_alloc); - return rmem + skb->len <= sk->sk_rcvbuf; + return rmem <= sk->sk_rcvbuf; } static int tcp_try_rmem_schedule(struct sock *sk, const struct sk_buff *skb, @@ -5416,7 +5411,7 @@ static void tcp_data_queue_ofo(struct sock *sk, struct sk_buff *skb) if (unlikely(tcp_try_rmem_schedule(sk, skb, skb->truesize))) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPOFODROP); - sk->sk_data_ready(sk); + READ_ONCE(sk->sk_data_ready)(sk); tcp_drop_reason(sk, skb, SKB_DROP_REASON_PROTO_MEM); return; } @@ -5626,7 +5621,7 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size) void tcp_data_ready(struct sock *sk) { if (tcp_epollin_ready(sk, sk->sk_rcvlowat) || sock_flag(sk, SOCK_DONE)) - sk->sk_data_ready(sk); + READ_ONCE(sk->sk_data_ready)(sk); } static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) @@ -5682,7 +5677,7 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) inet_csk(sk)->icsk_ack.pending |= (ICSK_ACK_NOMEM | ICSK_ACK_NOW); inet_csk_schedule_ack(sk); - sk->sk_data_ready(sk); + READ_ONCE(sk->sk_data_ready)(sk); if (skb_queue_len(&sk->sk_receive_queue) && skb->len) { reason = SKB_DROP_REASON_PROTO_MEM; @@ -6105,7 +6100,9 @@ static void tcp_new_space(struct sock *sk) tp->snd_cwnd_stamp = tcp_jiffies32; } - INDIRECT_CALL_1(sk->sk_write_space, sk_stream_write_space, sk); + INDIRECT_CALL_1(READ_ONCE(sk->sk_write_space), + sk_stream_write_space, + sk); } /* Caller made space either from: @@ -6316,7 +6313,7 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, const struct tcphdr *t BUG(); WRITE_ONCE(tp->urg_data, TCP_URG_VALID | tmp); if (!sock_flag(sk, SOCK_DEAD)) - sk->sk_data_ready(sk); + READ_ONCE(sk->sk_data_ready)(sk); } } } @@ -6379,7 +6376,8 @@ static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, step1: /* Step 1: check sequence number */ - reason = tcp_sequence(sk, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq); + reason = tcp_sequence(sk, TCP_SKB_CB(skb)->seq, + TCP_SKB_CB(skb)->end_seq, th); if (reason) { /* RFC793, page 37: "In all states except SYN-SENT, all reset * (RST) segments are validated by checking their SEQ-fields." @@ -7598,8 +7596,7 @@ static void tcp_reqsk_record_syn(const struct sock *sk, mac_hdrlen = 0; } - saved_syn = kmalloc(struct_size(saved_syn, data, len), - GFP_ATOMIC); + saved_syn = kmalloc_flex(*saved_syn, data, len, GFP_ATOMIC); if (saved_syn) { saved_syn->mac_hdrlen = mac_hdrlen; saved_syn->network_hdrlen = skb_network_header_len(skb); @@ -7649,6 +7646,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, const struct tcp_sock *tp = tcp_sk(sk); struct net *net = sock_net(sk); struct sock *fastopen_sk = NULL; + union tcp_seq_and_ts_off st; struct request_sock *req; bool want_cookie = false; struct dst_entry *dst; @@ -7718,9 +7716,12 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, if (!dst) goto drop_and_free; + if (tmp_opt.tstamp_ok || (!want_cookie && !isn)) + st = af_ops->init_seq_and_ts_off(net, skb); + if (tmp_opt.tstamp_ok) { tcp_rsk(req)->req_usec_ts = dst_tcp_usec_ts(dst); - tcp_rsk(req)->ts_off = af_ops->init_ts_off(net, skb); + tcp_rsk(req)->ts_off = st.ts_off; } if (!want_cookie && !isn) { int max_syn_backlog = READ_ONCE(net->ipv4.sysctl_max_syn_backlog); @@ -7742,7 +7743,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, goto drop_and_release; } - isn = af_ops->init_seq(skb); + isn = st.seq; } tcp_ecn_create_request(req, skb, sk, dst); @@ -7783,7 +7784,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, sock_put(fastopen_sk); goto drop_and_free; } - sk->sk_data_ready(sk); + READ_ONCE(sk->sk_data_ready)(sk); bh_unlock_sock(fastopen_sk); sock_put(fastopen_sk); } else { diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 6264fc0b2be5..c7b2463c2e25 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -88,6 +88,7 @@ #include #include +#include #include @@ -104,17 +105,14 @@ static DEFINE_PER_CPU(struct sock_bh_locked, ipv4_tcp_sk) = { static DEFINE_MUTEX(tcp_exit_batch_mutex); -static u32 tcp_v4_init_seq(const struct sk_buff *skb) +static union tcp_seq_and_ts_off +tcp_v4_init_seq_and_ts_off(const struct net *net, const struct sk_buff *skb) { - return secure_tcp_seq(ip_hdr(skb)->daddr, - ip_hdr(skb)->saddr, - tcp_hdr(skb)->dest, - tcp_hdr(skb)->source); -} - -static u32 tcp_v4_init_ts_off(const struct net *net, const struct sk_buff *skb) -{ - return secure_tcp_ts_off(net, ip_hdr(skb)->daddr, ip_hdr(skb)->saddr); + return secure_tcp_seq_and_ts_off(net, + ip_hdr(skb)->daddr, + ip_hdr(skb)->saddr, + tcp_hdr(skb)->dest, + tcp_hdr(skb)->source); } int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp) @@ -326,15 +324,16 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr_unsized *uaddr, int addr_len rt = NULL; if (likely(!tp->repair)) { + union tcp_seq_and_ts_off st; + + st = secure_tcp_seq_and_ts_off(net, + inet->inet_saddr, + inet->inet_daddr, + inet->inet_sport, + usin->sin_port); if (!tp->write_seq) - WRITE_ONCE(tp->write_seq, - secure_tcp_seq(inet->inet_saddr, - inet->inet_daddr, - inet->inet_sport, - usin->sin_port)); - WRITE_ONCE(tp->tsoffset, - secure_tcp_ts_off(net, inet->inet_saddr, - inet->inet_daddr)); + WRITE_ONCE(tp->write_seq, st.seq); + WRITE_ONCE(tp->tsoffset, st.ts_off); } atomic_set(&inet->inet_id, get_random_u16()); @@ -839,7 +838,7 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb, goto out; tcp_v4_md5_hash_skb(newhash, key, NULL, skb); - if (memcmp(md5_hash_location, newhash, 16) != 0) + if (crypto_memneq(md5_hash_location, newhash, 16)) goto out; } @@ -1354,7 +1353,7 @@ static int tcp_md5sig_info_add(struct sock *sk, gfp_t gfp) struct tcp_sock *tp = tcp_sk(sk); struct tcp_md5sig_info *md5sig; - md5sig = kmalloc(sizeof(*md5sig), gfp); + md5sig = kmalloc_obj(*md5sig, gfp); if (!md5sig) return -ENOMEM; @@ -1676,8 +1675,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = { .cookie_init_seq = cookie_v4_init_sequence, #endif .route_req = tcp_v4_route_req, - .init_seq = tcp_v4_init_seq, - .init_ts_off = tcp_v4_init_ts_off, + .init_seq_and_ts_off = tcp_v4_init_seq_and_ts_off, .send_synack = tcp_v4_send_synack, }; @@ -1705,7 +1703,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req) + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)) { struct inet_request_sock *ireq; bool found_dup_sk = false; @@ -1757,6 +1757,10 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, } sk_setup_caps(newsk, dst); +#if IS_ENABLED(CONFIG_IPV6) + if (opt_child_init) + opt_child_init(newsk, sk); +#endif tcp_ca_openreq_child(newsk, dst); tcp_sync_mss(newsk, dst4_mtu(dst)); diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 45b6ecd16412..06b1d5d3b6df 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c @@ -197,7 +197,7 @@ static struct tcp_metrics_block *tcpm_new(struct dst_entry *dst, } tm = oldest; } else { - tm = kzalloc(sizeof(*tm), GFP_ATOMIC); + tm = kzalloc_obj(*tm, GFP_ATOMIC); if (!tm) goto out_unlock; } diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index ec128865f5c0..dafb63b923d0 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -925,7 +925,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, * socket is created, wait for troubles. */ child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb, req, NULL, - req, &own_req); + req, &own_req, NULL); if (!child) goto listen_overflow; @@ -1004,7 +1004,7 @@ enum skb_drop_reason tcp_child_process(struct sock *parent, struct sock *child, reason = tcp_rcv_state_process(child, skb); /* Wakeup parent, send SIGIO */ if (state == TCP_SYN_RECV && child->sk_state != state) - parent->sk_data_ready(parent); + READ_ONCE(parent->sk_data_ready)(parent); } else { /* Alas, it is possible again, because we do lookup * in main socket hash table and lock on listening diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b96e47f1c8a2..b60fad393e18 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1787,7 +1787,7 @@ int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb) * using prepare_to_wait_exclusive(). */ while (nb) { - INDIRECT_CALL_1(sk->sk_data_ready, + INDIRECT_CALL_1(READ_ONCE(sk->sk_data_ready), sock_def_readable, sk); nb--; } @@ -2287,7 +2287,6 @@ void udp_lib_rehash(struct sock *sk, u16 newhash, u16 newhash4) udp_sk(sk)->udp_port_hash); hslot2 = udp_hashslot2(udptable, udp_sk(sk)->udp_portaddr_hash); nhslot2 = udp_hashslot2(udptable, newhash); - udp_sk(sk)->udp_portaddr_hash = newhash; if (hslot2 != nhslot2 || rcu_access_pointer(sk->sk_reuseport_cb)) { @@ -2321,19 +2320,25 @@ void udp_lib_rehash(struct sock *sk, u16 newhash, u16 newhash4) if (udp_hashed4(sk)) { spin_lock_bh(&hslot->lock); - udp_rehash4(udptable, sk, newhash4); - if (hslot2 != nhslot2) { - spin_lock(&hslot2->lock); - udp_hash4_dec(hslot2); - spin_unlock(&hslot2->lock); + if (inet_rcv_saddr_any(sk)) { + udp_unhash4(udptable, sk); + } else { + udp_rehash4(udptable, sk, newhash4); + if (hslot2 != nhslot2) { + spin_lock(&hslot2->lock); + udp_hash4_dec(hslot2); + spin_unlock(&hslot2->lock); - spin_lock(&nhslot2->lock); - udp_hash4_inc(nhslot2); - spin_unlock(&nhslot2->lock); + spin_lock(&nhslot2->lock); + udp_hash4_inc(nhslot2); + spin_unlock(&nhslot2->lock); + } } spin_unlock_bh(&hslot->lock); } + + udp_sk(sk)->udp_portaddr_hash = newhash; } } EXPORT_IPV6_MOD(udp_lib_rehash); @@ -3859,7 +3864,7 @@ static struct udp_table __net_init *udp_pernet_table_alloc(unsigned int hash_ent unsigned int slot_size; int i; - udptable = kmalloc(sizeof(*udptable), GFP_KERNEL); + udptable = kmalloc_obj(*udptable); if (!udptable) goto out; @@ -3972,8 +3977,8 @@ static int bpf_iter_udp_realloc_batch(struct bpf_udp_iter_state *iter, { union bpf_udp_iter_batch_item *new_batch; - new_batch = kvmalloc_array(new_batch_sz, sizeof(*new_batch), - flags | __GFP_NOWARN); + new_batch = kvmalloc_objs(*new_batch, new_batch_sz, + flags | __GFP_NOWARN); if (!new_batch) return -ENOMEM; diff --git a/net/ipv4/udp_bpf.c b/net/ipv4/udp_bpf.c index 91233e37cd97..779a3a03762f 100644 --- a/net/ipv4/udp_bpf.c +++ b/net/ipv4/udp_bpf.c @@ -158,7 +158,7 @@ int udp_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore) int family = sk->sk_family == AF_INET ? UDP_BPF_IPV4 : UDP_BPF_IPV6; if (restore) { - sk->sk_write_space = psock->saved_write_space; + WRITE_ONCE(sk->sk_write_space, psock->saved_write_space); sock_replace_proto(sk, psock->sk_proto); return 0; } diff --git a/net/ipv4/udp_tunnel_nic.c b/net/ipv4/udp_tunnel_nic.c index 944b3cf25468..9944ed923ddf 100644 --- a/net/ipv4/udp_tunnel_nic.c +++ b/net/ipv4/udp_tunnel_nic.c @@ -753,7 +753,7 @@ udp_tunnel_nic_alloc(const struct udp_tunnel_nic_info *info, struct udp_tunnel_nic *utn; unsigned int i; - utn = kzalloc(struct_size(utn, entries, n_tables), GFP_KERNEL); + utn = kzalloc_flex(*utn, entries, n_tables); if (!utn) return NULL; utn->n_tables = n_tables; @@ -761,8 +761,8 @@ udp_tunnel_nic_alloc(const struct udp_tunnel_nic_info *info, mutex_init(&utn->lock); for (i = 0; i < n_tables; i++) { - utn->entries[i] = kcalloc(info->tables[i].n_entries, - sizeof(*utn->entries[i]), GFP_KERNEL); + utn->entries[i] = kzalloc_objs(*utn->entries[i], + info->tables[i].n_entries); if (!utn->entries[i]) goto err_free_prev_entries; } @@ -820,7 +820,7 @@ static int udp_tunnel_nic_register(struct net_device *dev) /* Create UDP tunnel state structures */ if (info->shared) { - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOMEM; diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index d3e621a11a1a..826e9e79eb19 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c @@ -20,10 +20,9 @@ EXPORT_SYMBOL(udplite_table); /* Designate sk as UDP-Lite socket */ static int udplite_sk_init(struct sock *sk) { - udp_init_sock(sk); pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, " "please contact the netdev mailing list\n"); - return 0; + return udp_init_sock(sk); } static int udplite_rcv(struct sk_buff *skb) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6db9cf9e2a50..0e55f139e05d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -355,12 +355,11 @@ static int snmp6_alloc_dev(struct inet6_dev *idev) } - idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device), - GFP_KERNEL); + idev->stats.icmpv6dev = kzalloc_obj(struct icmpv6_mib_device); if (!idev->stats.icmpv6dev) goto err_icmp; - idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device), - GFP_KERNEL_ACCOUNT); + idev->stats.icmpv6msgdev = kzalloc_obj(struct icmpv6msg_mib_device, + GFP_KERNEL_ACCOUNT); if (!idev->stats.icmpv6msgdev) goto err_icmpmsg; @@ -385,7 +384,7 @@ static struct inet6_dev *ipv6_add_dev(struct net_device *dev) if (dev->mtu < IPV6_MIN_MTU && dev != blackhole_netdev) return ERR_PTR(-EINVAL); - ndev = kzalloc(sizeof(*ndev), GFP_KERNEL_ACCOUNT); + ndev = kzalloc_obj(*ndev, GFP_KERNEL_ACCOUNT); if (!ndev) return ERR_PTR(err); @@ -1117,7 +1116,7 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg, goto out; } - ifa = kzalloc(sizeof(*ifa), gfp_flags | __GFP_ACCOUNT); + ifa = kzalloc_obj(*ifa, gfp_flags | __GFP_ACCOUNT); if (!ifa) { err = -ENOBUFS; goto out; @@ -7398,9 +7397,8 @@ static int __net_init addrconf_init_net(struct net *net) spin_lock_init(&net->ipv6.addrconf_hash_lock); INIT_DEFERRABLE_WORK(&net->ipv6.addr_chk_work, addrconf_verify_work); - net->ipv6.inet6_addr_lst = kcalloc(IN6_ADDR_HSIZE, - sizeof(struct hlist_head), - GFP_KERNEL); + net->ipv6.inet6_addr_lst = kzalloc_objs(struct hlist_head, + IN6_ADDR_HSIZE); if (!net->ipv6.inet6_addr_lst) goto err_alloc_addr; diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 567efd626ab4..f4b2618446bd 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c @@ -180,7 +180,7 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, break; } - newp = kmalloc(sizeof(*newp), GFP_KERNEL); + newp = kmalloc_obj(*newp); if (!newp) return ERR_PTR(-ENOMEM); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 31ba677d0442..4cbd45b68088 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -86,8 +86,6 @@ struct ipv6_params ipv6_defaults = { .autoconf = 1, }; -static int disable_ipv6_mod; - module_param_named(disable, disable_ipv6_mod, int, 0444); MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional"); @@ -97,12 +95,6 @@ MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces"); module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444); MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces"); -bool ipv6_mod_enabled(void) -{ - return disable_ipv6_mod == 0; -} -EXPORT_SYMBOL_GPL(ipv6_mod_enabled); - static struct ipv6_pinfo *inet6_sk_generic(struct sock *sk) { const int offset = sk->sk_prot->ipv6_pinfo_offset; @@ -921,8 +913,7 @@ static int __net_init ipv6_init_mibs(struct net *net) net->mib.icmpv6_statistics = alloc_percpu(struct icmpv6_mib); if (!net->mib.icmpv6_statistics) goto err_icmp_mib; - net->mib.icmpv6msg_statistics = kzalloc(sizeof(struct icmpv6msg_mib), - GFP_KERNEL); + net->mib.icmpv6msg_statistics = kzalloc_obj(struct icmpv6msg_mib); if (!net->mib.icmpv6msg_statistics) goto err_icmpmsg_mib; return 0; @@ -952,7 +943,7 @@ static int __net_init inet6_net_init(struct net *net) int err = 0; net->ipv6.sysctl.bindv6only = 0; - net->ipv6.sysctl.icmpv6_time = 1*HZ; + net->ipv6.sysctl.icmpv6_time = HZ / 10; net->ipv6.sysctl.icmpv6_echo_ignore_all = 0; net->ipv6.sysctl.icmpv6_echo_ignore_multicast = 0; net->ipv6.sysctl.icmpv6_echo_ignore_anycast = 0; diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index 95372e0f1d21..cb26beea4398 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -691,7 +691,7 @@ static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack) goto error; } - ahp = kzalloc(sizeof(*ahp), GFP_KERNEL); + ahp = kzalloc_obj(*ahp); if (!ahp) return -ENOMEM; diff --git a/net/ipv6/anycast.c b/net/ipv6/anycast.c index 52599584422b..67a42e01dfc3 100644 --- a/net/ipv6/anycast.c +++ b/net/ipv6/anycast.c @@ -279,7 +279,7 @@ static struct ifacaddr6 *aca_alloc(struct fib6_info *f6i, { struct ifacaddr6 *aca; - aca = kzalloc(sizeof(*aca), GFP_ATOMIC); + aca = kzalloc_obj(*aca, GFP_ATOMIC); if (!aca) return NULL; diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 21f6ed126253..c6a34334e657 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c @@ -133,9 +133,8 @@ static int __init calipso_cache_init(void) { u32 iter; - calipso_cache = kcalloc(CALIPSO_CACHE_BUCKETS, - sizeof(struct calipso_map_cache_bkt), - GFP_KERNEL); + calipso_cache = kzalloc_objs(struct calipso_map_cache_bkt, + CALIPSO_CACHE_BUCKETS); if (!calipso_cache) return -ENOMEM; @@ -275,7 +274,7 @@ static int calipso_cache_add(const unsigned char *calipso_ptr, calipso_ptr_len = calipso_ptr[1]; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return -ENOMEM; entry->key = kmemdup(calipso_ptr + 2, calipso_ptr_len, GFP_ATOMIC); diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 209fdf1b1aa9..5e3610a926cf 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -931,6 +931,11 @@ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff) if (hdr->opt_len < 2 + sizeof(*trace) + trace->remlen * 4) goto drop; + /* Inconsistent Pre-allocated Trace header */ + if (trace->nodelen != + ioam6_trace_compute_nodelen(be32_to_cpu(trace->type_be32))) + goto drop; + /* Ignore if the IOAM namespace is unknown */ ns = ioam6_namespace(dev_net(skb->dev), trace->namespace_id); if (!ns) diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 375ecd779fda..813d2e9edb8b 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -217,16 +217,15 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type, } else if (dev && (dev->flags & IFF_LOOPBACK)) { res = true; } else { - struct rt6_info *rt = dst_rt6_info(dst); - int tmo = net->ipv6.sysctl.icmpv6_time; + int tmo = READ_ONCE(net->ipv6.sysctl.icmpv6_time); struct inet_peer *peer; - /* Give more bandwidth to wider prefixes. */ - if (rt->rt6i_dst.plen < 128) - tmo >>= ((128 - rt->rt6i_dst.plen)>>5); - - peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); - res = inet_peer_xrlim_allow(peer, tmo); + if (!tmo) { + res = true; + } else { + peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr); + res = inet_peer_xrlim_allow(peer, tmo); + } } rcu_read_unlock(); if (!res) diff --git a/net/ipv6/ila/ila_xlat.c b/net/ipv6/ila/ila_xlat.c index 1d41b2ab4884..8991805fc3d6 100644 --- a/net/ipv6/ila/ila_xlat.c +++ b/net/ipv6/ila/ila_xlat.c @@ -220,7 +220,7 @@ static int ila_add_mapping(struct net *net, struct ila_xlat_params *xp) return err; } - ila = kzalloc(sizeof(*ila), GFP_KERNEL); + ila = kzalloc_obj(*ila); if (!ila) return -ENOMEM; @@ -509,7 +509,7 @@ int ila_xlat_nl_dump_start(struct netlink_callback *cb) struct ila_net *ilan = net_generic(net, ila_net_id); struct ila_dump_iter *iter; - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return -ENOMEM; diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 5e1da088d8e1..182d38e6d6d8 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -95,7 +95,8 @@ static inline int compute_score(struct sock *sk, const struct net *net, { int score = -1; - if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum && + if (net_eq(sock_net(sk), net) && + READ_ONCE(inet_sk(sk)->inet_num) == hnum && sk->sk_family == PF_INET6) { if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) return -1; diff --git a/net/ipv6/ioam6.c b/net/ipv6/ioam6.c index 9553a3200081..b76f89d92e7b 100644 --- a/net/ipv6/ioam6.c +++ b/net/ipv6/ioam6.c @@ -127,7 +127,7 @@ static int ioam6_genl_addns(struct sk_buff *skb, struct genl_info *info) goto out_unlock; } - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_obj(*ns); if (!ns) { err = -ENOMEM; goto out_unlock; @@ -245,7 +245,7 @@ static int ioam6_genl_dumpns_start(struct netlink_callback *cb) struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0]; if (!iter) { - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return -ENOMEM; @@ -431,7 +431,7 @@ static int ioam6_genl_dumpsc_start(struct netlink_callback *cb) struct rhashtable_iter *iter = (struct rhashtable_iter *)cb->args[0]; if (!iter) { - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return -ENOMEM; @@ -690,6 +690,20 @@ struct ioam6_namespace *ioam6_namespace(struct net *net, __be16 id) return rhashtable_lookup_fast(&nsdata->namespaces, &id, rht_ns_params); } +#define IOAM6_MASK_SHORT_FIELDS 0xff1ffc00 +#define IOAM6_MASK_WIDE_FIELDS 0x00e00000 + +u8 ioam6_trace_compute_nodelen(u32 trace_type) +{ + u8 nodelen = hweight32(trace_type & IOAM6_MASK_SHORT_FIELDS) + * (sizeof(__be32) / 4); + + nodelen += hweight32(trace_type & IOAM6_MASK_WIDE_FIELDS) + * (sizeof(__be64) / 4); + + return nodelen; +} + static void __ioam6_fill_trace_data(struct sk_buff *skb, struct ioam6_namespace *ns, struct ioam6_trace_hdr *trace, @@ -961,7 +975,7 @@ static int __net_init ioam6_net_init(struct net *net) struct ioam6_pernet_data *nsdata; int err = -ENOMEM; - nsdata = kzalloc(sizeof(*nsdata), GFP_KERNEL); + nsdata = kzalloc_obj(*nsdata); if (!nsdata) goto out; diff --git a/net/ipv6/ioam6_iptunnel.c b/net/ipv6/ioam6_iptunnel.c index 1fe7894f14dd..b9f6d892a566 100644 --- a/net/ipv6/ioam6_iptunnel.c +++ b/net/ipv6/ioam6_iptunnel.c @@ -22,9 +22,6 @@ #include #include -#define IOAM6_MASK_SHORT_FIELDS 0xff100000 -#define IOAM6_MASK_WIDE_FIELDS 0xe00000 - struct ioam6_lwt_encap { struct ipv6_hopopt_hdr eh; u8 pad[2]; /* 2-octet padding for 4n-alignment */ @@ -93,13 +90,8 @@ static bool ioam6_validate_trace_hdr(struct ioam6_trace_hdr *trace) trace->type.bit21 | trace->type.bit23) return false; - trace->nodelen = 0; fields = be32_to_cpu(trace->type_be32); - - trace->nodelen += hweight32(fields & IOAM6_MASK_SHORT_FIELDS) - * (sizeof(__be32) / 4); - trace->nodelen += hweight32(fields & IOAM6_MASK_WIDE_FIELDS) - * (sizeof(__be64) / 4); + trace->nodelen = ioam6_trace_compute_nodelen(fields); return true; } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 9880d608392b..9058e71241dc 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -234,7 +234,7 @@ static struct fib6_table *fib6_alloc_table(struct net *net, u32 id) { struct fib6_table *table; - table = kzalloc(sizeof(*table), GFP_ATOMIC); + table = kzalloc_obj(*table, GFP_ATOMIC); if (table) { table->tb6_id = id; rcu_assign_pointer(table->tb6_root.leaf, @@ -494,7 +494,7 @@ int fib6_tables_dump(struct net *net, struct notifier_block *nb, unsigned int h; int err = 0; - w = kzalloc(sizeof(*w), GFP_ATOMIC); + w = kzalloc_obj(*w, GFP_ATOMIC); if (!w) return -ENOMEM; @@ -659,7 +659,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) * * 1. allocate and initialize walker. */ - w = kzalloc(sizeof(*w), GFP_ATOMIC); + w = kzalloc_obj(*w, GFP_ATOMIC); if (!w) { err = -ENOMEM; goto unlock; @@ -731,7 +731,7 @@ void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val) return; if (f6i->fib6_metrics == &dst_default_metrics) { - struct dst_metrics *p = kzalloc(sizeof(*p), GFP_ATOMIC); + struct dst_metrics *p = kzalloc_obj(*p, GFP_ATOMIC); if (!p) return; @@ -1139,7 +1139,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, fib6_add_gc_list(iter); } if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT)) && - !iter->fib6_nh->fib_nh_gw_family) { + (iter->nh || !iter->fib6_nh->fib_nh_gw_family)) { iter->fib6_flags &= ~RTF_ADDRCONF; iter->fib6_flags &= ~RTF_PREFIX_RT; } @@ -2464,7 +2464,7 @@ static int __net_init fib6_net_init(struct net *net) INIT_LIST_HEAD(&net->ipv6.fib6_walkers); timer_setup(&net->ipv6.ip6_fib_timer, fib6_gc_timer_cb, 0); - net->ipv6.rt6_stats = kzalloc(sizeof(*net->ipv6.rt6_stats), GFP_KERNEL); + net->ipv6.rt6_stats = kzalloc_obj(*net->ipv6.rt6_stats); if (!net->ipv6.rt6_stats) goto out_notifier; @@ -2477,8 +2477,7 @@ static int __net_init fib6_net_init(struct net *net) spin_lock_init(&net->ipv6.fib_table_hash_lock); - net->ipv6.fib6_main_tbl = kzalloc(sizeof(*net->ipv6.fib6_main_tbl), - GFP_KERNEL); + net->ipv6.fib6_main_tbl = kzalloc_obj(*net->ipv6.fib6_main_tbl); if (!net->ipv6.fib6_main_tbl) goto out_fib_table_hash; @@ -2491,8 +2490,7 @@ static int __net_init fib6_net_init(struct net *net) INIT_HLIST_HEAD(&net->ipv6.fib6_main_tbl->tb6_gc_hlist); #ifdef CONFIG_IPV6_MULTIPLE_TABLES - net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl), - GFP_KERNEL); + net->ipv6.fib6_local_tbl = kzalloc_obj(*net->ipv6.fib6_local_tbl); if (!net->ipv6.fib6_local_tbl) goto out_fib6_main_tbl; net->ipv6.fib6_local_tbl->tb6_id = RT6_TABLE_LOCAL; diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 60d0be47a9f3..7c12bf75beed 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -386,7 +386,7 @@ fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq, goto done; err = -ENOMEM; - fl = kzalloc(sizeof(*fl), GFP_KERNEL); + fl = kzalloc_obj(*fl); if (!fl) goto done; @@ -638,7 +638,7 @@ static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq, if (!fl) return err; - sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL); + sfl1 = kmalloc_obj(*sfl1); if (freq->flr_label) { err = -EEXIST; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 769c39fed1f3..8e2a6b28cea7 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1359,7 +1359,7 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, if (WARN_ON(v6_cork->opt)) return -EINVAL; - nopt = v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation); + nopt = v6_cork->opt = kzalloc_obj(*opt, sk->sk_allocation); if (unlikely(!nopt)) return -ENOBUFS; diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index d784a8644ff2..02c4cab60c69 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -66,7 +66,7 @@ int ip6_ra_control(struct sock *sk, int sel) if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num != IPPROTO_RAW) return -ENOPROTOOPT; - new_ra = (sel >= 0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; + new_ra = (sel >= 0) ? kmalloc_obj(*new_ra) : NULL; if (sel >= 0 && !new_ra) return -ENOMEM; diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 016b572e7d6f..3330adcf26db 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -740,7 +740,7 @@ static void mld_add_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im) * for deleted items allows change reports to use common code with * non-deleted or query-response MCA's. */ - pmc = kzalloc(sizeof(*pmc), GFP_KERNEL); + pmc = kzalloc_obj(*pmc); if (!pmc) return; @@ -868,7 +868,7 @@ static struct ifmcaddr6 *mca_alloc(struct inet6_dev *idev, mc_assert_locked(idev); - mc = kzalloc(sizeof(*mc), GFP_KERNEL); + mc = kzalloc_obj(*mc); if (!mc) return NULL; @@ -2415,7 +2415,7 @@ static int ip6_mc_add1_src(struct ifmcaddr6 *pmc, int sfmode, psf_prev = psf; } if (!psf) { - psf = kzalloc(sizeof(*psf), GFP_KERNEL); + psf = kzalloc_obj(*psf); if (!psf) return -ENOBUFS; @@ -2500,7 +2500,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc) &psf->sf_addr)) break; if (!dpsf) { - dpsf = kmalloc(sizeof(*dpsf), GFP_KERNEL); + dpsf = kmalloc_obj(*dpsf); if (!dpsf) continue; *dpsf = *psf; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index c0350d97307e..08cd86f49bf9 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -684,14 +684,14 @@ static void rt6_probe(struct fib6_nh *fib6_nh) time_after(jiffies, neigh->updated + READ_ONCE(idev->cnf.rtr_probe_interval))) { - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); if (work) __neigh_set_probe_once(neigh); } write_unlock_bh(&neigh->lock); } else if (time_after(jiffies, last_probe + READ_ONCE(idev->cnf.rtr_probe_interval))) { - work = kmalloc(sizeof(*work), GFP_ATOMIC); + work = kmalloc_obj(*work, GFP_ATOMIC); } if (!work || cmpxchg(&fib6_nh->last_probe, @@ -1063,7 +1063,8 @@ static struct net_device *ip6_rt_get_dev_rcu(const struct fib6_result *res) */ if (netif_is_l3_slave(dev) && !rt6_need_strict(&res->f6i->fib6_dst.addr)) - dev = l3mdev_master_dev_rcu(dev); + dev = l3mdev_master_dev_rcu(dev) ? : + dev_net(dev)->loopback_dev; else if (!netif_is_l3_master(dev)) dev = dev_net(dev)->loopback_dev; /* last case is netif_is_l3_master(dev) is true in which @@ -1723,8 +1724,8 @@ static int rt6_insert_exception(struct rt6_info *nrt, bucket = rcu_dereference_protected(nh->rt6i_exception_bucket, lockdep_is_held(&rt6_exception_lock)); if (!bucket) { - bucket = kcalloc(FIB6_EXCEPTION_BUCKET_SIZE, sizeof(*bucket), - GFP_ATOMIC); + bucket = kzalloc_objs(*bucket, FIB6_EXCEPTION_BUCKET_SIZE, + GFP_ATOMIC); if (!bucket) { err = -ENOMEM; goto out; @@ -1759,7 +1760,7 @@ static int rt6_insert_exception(struct rt6_info *nrt, if (rt6_ex) rt6_remove_exception(bucket, rt6_ex); - rt6_ex = kzalloc(sizeof(*rt6_ex), GFP_ATOMIC); + rt6_ex = kzalloc_obj(*rt6_ex, GFP_ATOMIC); if (!rt6_ex) { err = -ENOMEM; goto out; @@ -3582,7 +3583,6 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, netdevice_tracker *dev_tracker = &fib6_nh->fib_nh_dev_tracker; struct net_device *dev = NULL; struct inet6_dev *idev = NULL; - int addr_type; int err; fib6_nh->fib_nh_family = AF_INET6; @@ -3624,11 +3624,10 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh, fib6_nh->fib_nh_weight = 1; - /* We cannot add true routes via loopback here, - * they would result in kernel looping; promote them to reject routes + /* Reset the nexthop device to the loopback device in case of reject + * routes. */ - addr_type = ipv6_addr_type(&cfg->fc_dst); - if (fib6_is_reject(cfg->fc_flags, dev, addr_type)) { + if (cfg->fc_flags & RTF_REJECT) { /* hold loopback dev/idev if we haven't done so. */ if (dev != net->loopback_dev) { if (dev) { @@ -5331,7 +5330,7 @@ static int ip6_route_info_append(struct list_head *rt6_nh_list, return -EEXIST; } - nh = kzalloc(sizeof(*nh), GFP_KERNEL); + nh = kzalloc_obj(*nh); if (!nh) return -ENOMEM; @@ -6778,7 +6777,7 @@ static struct pernet_operations ip6_route_net_ops = { static int __net_init ipv6_inetpeer_init(struct net *net) { - struct inet_peer_base *bp = kmalloc(sizeof(*bp), GFP_KERNEL); + struct inet_peer_base *bp = kmalloc_obj(*bp); if (!bp) return -ENOMEM; diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c index a5c4c629b788..1c3ad25700c4 100644 --- a/net/ipv6/seg6.c +++ b/net/ipv6/seg6.c @@ -202,7 +202,7 @@ static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info) secret = (char *)nla_data(info->attrs[SEG6_ATTR_SECRET]); - hinfo = kzalloc(sizeof(*hinfo), GFP_KERNEL); + hinfo = kzalloc_obj(*hinfo); if (!hinfo) { err = -ENOMEM; goto out_unlock; @@ -339,7 +339,7 @@ static int seg6_genl_dumphmac_start(struct netlink_callback *cb) iter = (struct rhashtable_iter *)cb->args[0]; if (!iter) { - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return -ENOMEM; @@ -421,13 +421,13 @@ static int __net_init seg6_net_init(struct net *net) { struct seg6_pernet_data *sdata; - sdata = kzalloc(sizeof(*sdata), GFP_KERNEL); + sdata = kzalloc_obj(*sdata); if (!sdata) return -ENOMEM; mutex_init(&sdata->lock); - sdata->tun_src = kzalloc(sizeof(*sdata->tun_src), GFP_KERNEL); + sdata->tun_src = kzalloc_obj(*sdata->tun_src); if (!sdata->tun_src) { kfree(sdata); return -ENOMEM; diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 439c8a1c6625..6a7b8abb0477 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -323,7 +323,7 @@ static int ipip6_tunnel_get_prl(struct net_device *dev, struct ip_tunnel_prl __u * we try harder to allocate. */ kp = (cmax <= 1 || capable(CAP_NET_ADMIN)) ? - kcalloc(cmax, sizeof(*kp), GFP_KERNEL_ACCOUNT | __GFP_NOWARN) : + kzalloc_objs(*kp, cmax, GFP_KERNEL_ACCOUNT | __GFP_NOWARN) : NULL; ca = min(t->prl_count, cmax); @@ -334,8 +334,8 @@ static int ipip6_tunnel_get_prl(struct net_device *dev, struct ip_tunnel_prl __u * For root users, retry allocating enough memory for * the answer. */ - kp = kcalloc(ca, sizeof(*kp), GFP_ATOMIC | __GFP_ACCOUNT | - __GFP_NOWARN); + kp = kzalloc_objs(*kp, ca, + GFP_ATOMIC | __GFP_ACCOUNT | __GFP_NOWARN); if (!kp) { ret = -ENOMEM; goto out; @@ -394,7 +394,7 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg) goto out; } - p = kzalloc(sizeof(struct ip_tunnel_prl_entry), GFP_KERNEL); + p = kzalloc_obj(struct ip_tunnel_prl_entry); if (!p) { err = -ENOBUFS; goto out; diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 7e007f013ec8..4f6f0d751d6c 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c @@ -151,9 +151,14 @@ static struct request_sock *cookie_tcp_check(struct net *net, struct sock *sk, tcp_parse_options(net, skb, &tcp_opt, 0, NULL); if (tcp_opt.saw_tstamp && tcp_opt.rcv_tsecr) { - tsoff = secure_tcpv6_ts_off(net, - ipv6_hdr(skb)->daddr.s6_addr32, - ipv6_hdr(skb)->saddr.s6_addr32); + union tcp_seq_and_ts_off st; + + st = secure_tcpv6_seq_and_ts_off(net, + ipv6_hdr(skb)->daddr.s6_addr32, + ipv6_hdr(skb)->saddr.s6_addr32, + tcp_hdr(skb)->dest, + tcp_hdr(skb)->source); + tsoff = st.ts_off; tcp_opt.rcv_tsecr -= tsoff; } diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d10487b4e5bf..bb09d5ccf599 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -68,6 +68,7 @@ #include #include +#include #include @@ -104,18 +105,14 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) } } -static u32 tcp_v6_init_seq(const struct sk_buff *skb) +static union tcp_seq_and_ts_off +tcp_v6_init_seq_and_ts_off(const struct net *net, const struct sk_buff *skb) { - return secure_tcpv6_seq(ipv6_hdr(skb)->daddr.s6_addr32, - ipv6_hdr(skb)->saddr.s6_addr32, - tcp_hdr(skb)->dest, - tcp_hdr(skb)->source); -} - -static u32 tcp_v6_init_ts_off(const struct net *net, const struct sk_buff *skb) -{ - return secure_tcpv6_ts_off(net, ipv6_hdr(skb)->daddr.s6_addr32, - ipv6_hdr(skb)->saddr.s6_addr32); + return secure_tcpv6_seq_and_ts_off(net, + ipv6_hdr(skb)->daddr.s6_addr32, + ipv6_hdr(skb)->saddr.s6_addr32, + tcp_hdr(skb)->dest, + tcp_hdr(skb)->source); } static int tcp_v6_pre_connect(struct sock *sk, struct sockaddr_unsized *uaddr, @@ -319,14 +316,16 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr_unsized *uaddr, sk_set_txhash(sk); if (likely(!tp->repair)) { + union tcp_seq_and_ts_off st; + + st = secure_tcpv6_seq_and_ts_off(net, + np->saddr.s6_addr32, + sk->sk_v6_daddr.s6_addr32, + inet->inet_sport, + inet->inet_dport); if (!tp->write_seq) - WRITE_ONCE(tp->write_seq, - secure_tcpv6_seq(np->saddr.s6_addr32, - sk->sk_v6_daddr.s6_addr32, - inet->inet_sport, - inet->inet_dport)); - tp->tsoffset = secure_tcpv6_ts_off(net, np->saddr.s6_addr32, - sk->sk_v6_daddr.s6_addr32); + WRITE_ONCE(tp->write_seq, st.seq); + tp->tsoffset = st.ts_off; } if (tcp_fastopen_defer_connect(sk, &err)) @@ -816,8 +815,7 @@ const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = { .cookie_init_seq = cookie_v6_init_sequence, #endif .route_req = tcp_v6_route_req, - .init_seq = tcp_v6_init_seq, - .init_ts_off = tcp_v6_init_ts_off, + .init_seq_and_ts_off = tcp_v6_init_seq_and_ts_off, .send_synack = tcp_v6_send_synack, }; @@ -1048,7 +1046,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb, key.type = TCP_KEY_MD5; tcp_v6_md5_hash_skb(newhash, key.md5_key, NULL, skb); - if (memcmp(md5_hash_location, newhash, 16) != 0) + if (crypto_memneq(md5_hash_location, newhash, 16)) goto out; } #endif @@ -1312,11 +1310,48 @@ static void tcp_v6_restore_cb(struct sk_buff *skb) sizeof(struct inet6_skb_parm)); } +/* Called from tcp_v4_syn_recv_sock() for v6_mapped children. */ +static void tcp_v6_mapped_child_init(struct sock *newsk, const struct sock *sk) +{ + struct inet_sock *newinet = inet_sk(newsk); + struct ipv6_pinfo *newnp; + + newinet->pinet6 = newnp = tcp_inet6_sk(newsk); + newinet->ipv6_fl_list = NULL; + + memcpy(newnp, tcp_inet6_sk(sk), sizeof(struct ipv6_pinfo)); + + newnp->saddr = newsk->sk_v6_rcv_saddr; + + inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; + if (sk_is_mptcp(newsk)) + mptcpv6_handle_mapped(newsk, true); + newsk->sk_backlog_rcv = tcp_v4_do_rcv; +#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO) + tcp_sk(newsk)->af_specific = &tcp_sock_ipv6_mapped_specific; +#endif + + newnp->ipv6_mc_list = NULL; + newnp->ipv6_ac_list = NULL; + newnp->pktoptions = NULL; + newnp->opt = NULL; + + /* tcp_v4_syn_recv_sock() has initialized newinet->mc_{index,ttl} */ + newnp->mcast_oif = newinet->mc_index; + newnp->mcast_hops = newinet->mc_ttl; + + newnp->rcv_flowinfo = 0; + if (inet6_test_bit(REPFLOW, sk)) + newnp->flow_label = 0; +} + static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req) + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)) { const struct ipv6_pinfo *np = tcp_inet6_sk(sk); struct inet_request_sock *ireq; @@ -1332,61 +1367,10 @@ static struct sock *tcp_v6_syn_recv_sock(const struct sock *sk, struct sk_buff * #endif struct flowi6 fl6; - if (skb->protocol == htons(ETH_P_IP)) { - /* - * v6 mapped - */ - - newsk = tcp_v4_syn_recv_sock(sk, skb, req, dst, - req_unhash, own_req); - - if (!newsk) - return NULL; - - newinet = inet_sk(newsk); - newinet->pinet6 = tcp_inet6_sk(newsk); - newinet->ipv6_fl_list = NULL; - - newnp = tcp_inet6_sk(newsk); - newtp = tcp_sk(newsk); - - memcpy(newnp, np, sizeof(struct ipv6_pinfo)); - - newnp->saddr = newsk->sk_v6_rcv_saddr; - - inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; - if (sk_is_mptcp(newsk)) - mptcpv6_handle_mapped(newsk, true); - newsk->sk_backlog_rcv = tcp_v4_do_rcv; -#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO) - newtp->af_specific = &tcp_sock_ipv6_mapped_specific; -#endif - - newnp->ipv6_mc_list = NULL; - newnp->ipv6_ac_list = NULL; - newnp->pktoptions = NULL; - newnp->opt = NULL; - newnp->mcast_oif = inet_iif(skb); - newnp->mcast_hops = ip_hdr(skb)->ttl; - newnp->rcv_flowinfo = 0; - if (inet6_test_bit(REPFLOW, sk)) - newnp->flow_label = 0; - - /* - * No need to charge this sock to the relevant IPv6 refcnt debug socks count - * here, tcp_create_openreq_child now does this for us, see the comment in - * that function for the gory details. -acme - */ - - /* It is tricky place. Until this moment IPv4 tcp - worked with IPv6 icsk.icsk_af_ops. - Sync it now. - */ - tcp_sync_mss(newsk, inet_csk(newsk)->icsk_pmtu_cookie); - - return newsk; - } - + if (skb->protocol == htons(ETH_P_IP)) + return tcp_v4_syn_recv_sock(sk, skb, req, dst, + req_unhash, own_req, + tcp_v6_mapped_child_init); ireq = inet_rsk(req); if (sk_acceptq_is_full(sk)) diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 2cec542437f7..e867721cda4d 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c @@ -16,10 +16,9 @@ static int udplitev6_sk_init(struct sock *sk) { - udpv6_init_sock(sk); pr_warn_once("UDP-Lite is deprecated and scheduled to be removed in 2025, " "please contact the netdev mailing list\n"); - return 0; + return udpv6_init_sock(sk); } static int udplitev6_rcv(struct sk_buff *skb) diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 1f19b6f14484..125ea9a5b8a0 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c @@ -57,6 +57,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, struct dst_entry *dst; struct net_device *dev; struct inet6_dev *idev; + int err; dst = xfrm6_dst_lookup(params); if (IS_ERR(dst)) @@ -68,9 +69,11 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr, return -EHOSTUNREACH; } dev = idev->dev; - ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0, - &saddr->in6); + err = ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0, + &saddr->in6); dst_release(dst); + if (err) + return -EHOSTUNREACH; return 0; } diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 1e62fbc22cb7..6554d2cffc19 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c @@ -1719,7 +1719,7 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg) goto out_unlock; save_message: - save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA); + save_msg = kzalloc_obj(struct sock_msg_q, GFP_ATOMIC | GFP_DMA); if (!save_msg) goto out_unlock; save_msg->path = path; diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index b43b1059eea8..6641c49b09ac 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c @@ -90,7 +90,7 @@ struct device *iucv_alloc_device(const struct attribute_group **attrs, char buf[20]; int rc; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) goto out_error; va_start(vargs, fmt); @@ -378,7 +378,7 @@ static int iucv_query_maxconn(void) void *param; int ccode; - param = kzalloc(sizeof(union iucv_param), GFP_KERNEL | GFP_DMA); + param = kzalloc_obj(union iucv_param, GFP_KERNEL | GFP_DMA); if (!param) return -ENOMEM; ccode = __iucv_query_maxconn(param, &max_pathid); @@ -1808,7 +1808,7 @@ static void iucv_external_interrupt(struct ext_code ext_code, return; } BUG_ON(p->iptype < 0x01 || p->iptype > 0x09); - work = kmalloc(sizeof(struct iucv_irq_list), GFP_ATOMIC); + work = kmalloc_obj(struct iucv_irq_list, GFP_ATOMIC); if (!work) { pr_warn("iucv_external_interrupt: out of memory\n"); return; diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index 5dd7e0509a48..3912e75079f5 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c @@ -628,7 +628,7 @@ static int kcm_write_msgs(struct kcm_sock *kcm) skb = txm->frag_skb; } - if (WARN_ON(!skb_shinfo(skb)->nr_frags) || + if (WARN_ON_ONCE(!skb_shinfo(skb)->nr_frags) || WARN_ON_ONCE(!skb_frag_page(&skb_shinfo(skb)->frags[0]))) { ret = -EINVAL; goto out; @@ -749,7 +749,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) { struct sock *sk = sock->sk; struct kcm_sock *kcm = kcm_sk(sk); - struct sk_buff *skb = NULL, *head = NULL; + struct sk_buff *skb = NULL, *head = NULL, *frag_prev = NULL; size_t copy, copied = 0; long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); int eor = (sock->type == SOCK_DGRAM) ? @@ -824,6 +824,7 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) else skb->next = tskb; + frag_prev = skb; skb = tskb; skb->ip_summed = CHECKSUM_UNNECESSARY; continue; @@ -933,6 +934,22 @@ static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) out_error: kcm_push(kcm); + /* When MAX_SKB_FRAGS was reached, a new skb was allocated and + * linked into the frag_list before data copy. If the copy + * subsequently failed, this skb has zero frags. Remove it from + * the frag_list to prevent kcm_write_msgs from later hitting + * WARN_ON(!skb_shinfo(skb)->nr_frags). + */ + if (frag_prev && !skb_shinfo(skb)->nr_frags) { + if (head == frag_prev) + skb_shinfo(head)->frag_list = NULL; + else + frag_prev->next = NULL; + kfree_skb(skb); + /* Update skb as it may be saved in partial_message via goto */ + skb = frag_prev; + } + if (sock->type == SOCK_SEQPACKET) { /* Wrote some bytes before encountering an * error, return partial success. diff --git a/net/key/af_key.c b/net/key/af_key.c index 571200433aa9..0756bac62f7c 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c @@ -1196,7 +1196,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, err = -ENOSYS; goto out; } - x->calg = kmalloc(sizeof(*x->calg), GFP_KERNEL); + x->calg = kmalloc_obj(*x->calg); if (!x->calg) { err = -ENOMEM; goto out; @@ -1261,7 +1261,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, const struct sadb_x_nat_t_type* n_type; struct xfrm_encap_tmpl *natt; - x->encap = kzalloc(sizeof(*x->encap), GFP_KERNEL); + x->encap = kzalloc_obj(*x->encap); if (!x->encap) { err = -ENOMEM; goto out; @@ -1855,7 +1855,7 @@ static int pfkey_dump(struct sock *sk, struct sk_buff *skb, const struct sadb_ms mutex_unlock(&pfk->dump_lock); return -EINVAL; } - filter = kmalloc(sizeof(*filter), GFP_KERNEL); + filter = kmalloc_obj(*filter); if (filter == NULL) { mutex_unlock(&pfk->dump_lock); return -ENOMEM; diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index f9b0f666600f..c89ae52764b8 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c @@ -487,7 +487,7 @@ static int l2tp_session_collision_add(struct l2tp_net *pn, /* First collision. Allocate list to manage the collided sessions * and add the existing session to the list. */ - clist = kmalloc(sizeof(*clist), GFP_ATOMIC); + clist = kmalloc_obj(*clist, GFP_ATOMIC); if (!clist) return -ENOMEM; @@ -1572,7 +1572,7 @@ int l2tp_tunnel_create(int fd, int version, u32 tunnel_id, u32 peer_tunnel_id, if (cfg) encap = cfg->encap; - tunnel = kzalloc(sizeof(*tunnel), GFP_KERNEL); + tunnel = kzalloc_obj(*tunnel); if (!tunnel) { err = -ENOMEM; goto err; diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index 5cfaab7d0890..b26986fda9d6 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c @@ -269,7 +269,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) struct seq_file *seq; int rc = -ENOMEM; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) goto out; diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c index a0596e1f91da..670e0859a3e6 100644 --- a/net/lapb/lapb_iface.c +++ b/net/lapb/lapb_iface.c @@ -110,7 +110,7 @@ static struct lapb_cb *lapb_devtostruct(struct net_device *dev) */ static struct lapb_cb *lapb_create_cb(void) { - struct lapb_cb *lapb = kzalloc(sizeof(*lapb), GFP_ATOMIC); + struct lapb_cb *lapb = kzalloc_obj(*lapb, GFP_ATOMIC); if (!lapb) goto out; diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c index 4f16d9c88350..d73f5414d8ce 100644 --- a/net/llc/llc_core.c +++ b/net/llc/llc_core.c @@ -32,7 +32,7 @@ static DEFINE_SPINLOCK(llc_sap_list_lock); */ static struct llc_sap *llc_sap_alloc(void) { - struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); + struct llc_sap *sap = kzalloc_obj(*sap, GFP_ATOMIC); int i; if (sap) { diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 7da909d78c68..f301a8622bee 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c @@ -395,7 +395,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, } /* prepare A-MPDU MLME for Rx aggregation */ - tid_agg_rx = kzalloc(sizeof(*tid_agg_rx), GFP_KERNEL); + tid_agg_rx = kzalloc_obj(*tid_agg_rx); if (!tid_agg_rx) goto end; @@ -411,7 +411,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, /* prepare reordering buffer */ tid_agg_rx->reorder_buf = - kcalloc(buf_size, sizeof(struct sk_buff_head), GFP_KERNEL); + kzalloc_objs(struct sk_buff_head, buf_size); tid_agg_rx->reorder_time = kcalloc(buf_size, sizeof(unsigned long), GFP_KERNEL); if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) { diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index d981b0fc57bf..93b47a7ba9c4 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c @@ -710,7 +710,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, } /* prepare A-MPDU MLME for Tx aggregation */ - tid_tx = kzalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); + tid_tx = kzalloc_obj(struct tid_ampdu_tx, GFP_ATOMIC); if (!tid_tx) { ret = -ENOMEM; goto err_unlock_sta; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5d04d7d550b0..b92b4a5c2636 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -3940,9 +3940,8 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { new_beacon->mbssid_ies = - kzalloc(struct_size(new_beacon->mbssid_ies, - elem, beacon->mbssid_ies->cnt), - GFP_KERNEL); + kzalloc_flex(*new_beacon->mbssid_ies, elem, + beacon->mbssid_ies->cnt); if (!new_beacon->mbssid_ies) { kfree(new_beacon); return NULL; @@ -3950,9 +3949,8 @@ cfg80211_beacon_dup(struct cfg80211_beacon_data *beacon) if (beacon->rnr_ies && beacon->rnr_ies->cnt) { new_beacon->rnr_ies = - kzalloc(struct_size(new_beacon->rnr_ies, - elem, beacon->rnr_ies->cnt), - GFP_KERNEL); + kzalloc_flex(*new_beacon->rnr_ies, elem, + beacon->rnr_ies->cnt); if (!new_beacon->rnr_ies) { kfree(new_beacon->mbssid_ies); kfree(new_beacon); @@ -4744,7 +4742,7 @@ static int ieee80211_set_qos_map(struct wiphy *wiphy, struct mac80211_qos_map *new_qos_map, *old_qos_map; if (qos_map) { - new_qos_map = kzalloc(sizeof(*new_qos_map), GFP_KERNEL); + new_qos_map = kzalloc_obj(*new_qos_map); if (!new_qos_map) return -ENOMEM; memcpy(&new_qos_map->qos_map, qos_map, sizeof(*qos_map)); diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index d8c5f11afc15..4447cf03c41b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1612,7 +1612,7 @@ static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, lockdep_assert_wiphy(local->hw.wiphy); - vif_chsw = kcalloc(n_vifs, sizeof(vif_chsw[0]), GFP_KERNEL); + vif_chsw = kzalloc_objs(vif_chsw[0], n_vifs); if (!vif_chsw) return -ENOMEM; diff --git a/net/mac80211/eht.c b/net/mac80211/eht.c index 75096b2195d2..078e1e23d8d1 100644 --- a/net/mac80211/eht.c +++ b/net/mac80211/eht.c @@ -154,6 +154,7 @@ void ieee80211_rx_eml_op_mode_notif(struct ieee80211_sub_if_data *sdata, u8 *ptr = mgmt->u.action.u.eml_omn.variable; struct ieee80211_eml_params eml_params = { .link_id = status->link_id, + .control = control, }; struct sta_info *sta; int opt_len = 0; diff --git a/net/mac80211/led.c b/net/mac80211/led.c index fabbffdd3ac2..b5600d223452 100644 --- a/net/mac80211/led.c +++ b/net/mac80211/led.c @@ -298,7 +298,7 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw, if (WARN_ON(local->tpt_led_trigger)) return NULL; - tpt_trig = kzalloc(sizeof(struct tpt_led_trigger), GFP_KERNEL); + tpt_trig = kzalloc_obj(struct tpt_led_trigger); if (!tpt_trig) return NULL; diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 17bf55dabd31..03bfca27d205 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -281,6 +281,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]; struct ieee80211_link_data *old_data[IEEE80211_MLD_MAX_NUM_LINKS]; bool use_deflink = old_links == 0; /* set for error case */ + bool non_sta = sdata->vif.type != NL80211_IFTYPE_STATION; lockdep_assert_wiphy(sdata->local->hw.wiphy); @@ -295,7 +296,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, /* allocate new link structures first */ for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { - link = kzalloc(sizeof(*link), GFP_KERNEL); + link = kzalloc_obj(*link); if (!link) { ret = -ENOMEM; goto free; @@ -337,6 +338,7 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, link = links[link_id]; ieee80211_link_init(sdata, link_id, &link->data, &link->conf); ieee80211_link_setup(&link->data); + ieee80211_set_wmm_default(&link->data, true, non_sta); } if (new_links == 0) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index bedc81956fbc..616f86b1a7e4 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1359,9 +1359,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); - local->int_scan_req = kzalloc(struct_size(local->int_scan_req, - channels, channels), - GFP_KERNEL); + local->int_scan_req = kzalloc_flex(*local->int_scan_req, channels, + channels); if (!local->int_scan_req) return -ENOMEM; diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 68901f1def0d..28624e57aa49 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c @@ -178,7 +178,7 @@ int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) { int i; - sdata->u.mesh.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL); + sdata->u.mesh.rmc = kmalloc_obj(struct mesh_rmc); if (!sdata->u.mesh.rmc) return -ENOMEM; sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1; @@ -1560,8 +1560,7 @@ int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata, lockdep_assert_wiphy(sdata->local->hw.wiphy); - tmp_csa_settings = kmalloc(sizeof(*tmp_csa_settings), - GFP_ATOMIC); + tmp_csa_settings = kmalloc_obj(*tmp_csa_settings, GFP_ATOMIC); if (!tmp_csa_settings) return -ENOMEM; @@ -1636,6 +1635,9 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata, if (!mesh_matches_local(sdata, elems)) goto free; + if (!elems->mesh_chansw_params_ie) + goto free; + ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl; if (!--ifmsh->chsw_ttl) fwd_csa = false; diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index a41b57bd11ff..98d5aaa36d00 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1005,7 +1005,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; struct mesh_preq_queue *preq_node; - preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); + preq_node = kmalloc_obj(struct mesh_preq_queue, GFP_ATOMIC); if (!preq_node) { mhwmp_dbg(sdata, "could not allocate PREQ node\n"); return; diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 0319674be832..03171cf00855 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c @@ -405,7 +405,7 @@ struct mesh_path *mesh_path_new(struct ieee80211_sub_if_data *sdata, { struct mesh_path *new_mpath; - new_mpath = kzalloc(sizeof(struct mesh_path), gfp_flags); + new_mpath = kzalloc_obj(struct mesh_path, gfp_flags); if (!new_mpath) return NULL; diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e83582b2c377..810bea1aacc5 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -7085,6 +7085,9 @@ static void ieee80211_ml_reconfiguration(struct ieee80211_sub_if_data *sdata, control = le16_to_cpu(prof->control); link_id = control & IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID; + if (link_id >= IEEE80211_MLD_MAX_NUM_LINKS) + continue; + removed_links |= BIT(link_id); /* the MAC address should not be included, but handle it */ @@ -10839,7 +10842,7 @@ int ieee80211_mgd_assoc_ml_reconf(struct ieee80211_sub_if_data *sdata, if (added_links) { bool uapsd_supported; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index ae82533e3c02..f60f6a58948b 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -579,7 +579,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, if (!local->emulate_chanctx && !local->ops->remain_on_channel) return -EOPNOTSUPP; - roc = kzalloc(sizeof(*roc), GFP_KERNEL); + roc = kzalloc_obj(*roc); if (!roc) return -ENOMEM; diff --git a/net/mac80211/parse.c b/net/mac80211/parse.c index 8260f6bdd5b2..2b3632c6008a 100644 --- a/net/mac80211/parse.c +++ b/net/mac80211/parse.c @@ -1048,8 +1048,8 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params) if (WARN_ON(params->link_id >= 0 && params->bss)) return NULL; - elems_parse = kzalloc(struct_size(elems_parse, scratch, scratch_len), - GFP_ATOMIC); + elems_parse = kzalloc_flex(*elems_parse, scratch, scratch_len, + GFP_ATOMIC); if (!elems_parse) return NULL; diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index e441f8541603..31af7dd6aedc 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c @@ -163,7 +163,7 @@ int ieee80211_rate_control_register(const struct rate_control_ops *ops) } } - alg = kzalloc(sizeof(*alg), GFP_KERNEL); + alg = kzalloc_obj(*alg); if (alg == NULL) { mutex_unlock(&rate_ctrl_mutex); return -ENOMEM; @@ -263,7 +263,7 @@ rate_control_alloc(const char *name, struct ieee80211_local *local) { struct rate_control_ref *ref; - ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); + ref = kmalloc_obj(struct rate_control_ref); if (!ref) return NULL; ref->ops = ieee80211_rate_control_ops_get(name); diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index f66910013218..62745ca00e06 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c @@ -1553,7 +1553,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) int i = 0; int max_rates = min_t(int, mp->hw->max_rates, IEEE80211_TX_RATE_TABLE_SIZE); - rates = kzalloc(sizeof(*rates), GFP_ATOMIC); + rates = kzalloc_obj(*rates, GFP_ATOMIC); if (!rates) return; @@ -1862,7 +1862,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) max_rates = sband->n_bitrates; } - return kzalloc(sizeof(*mi), gfp); + return kzalloc_obj(*mi, gfp); } static void @@ -1930,7 +1930,7 @@ minstrel_ht_alloc(struct ieee80211_hw *hw) struct minstrel_priv *mp; int i; - mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); + mp = kzalloc_obj(struct minstrel_priv, GFP_ATOMIC); if (!mp) return NULL; diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a79ebeb43585..6dc22f1593be 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -644,7 +644,7 @@ __sta_info_alloc(struct ieee80211_sub_if_data *sdata, wiphy_work_init(&sta->ampdu_mlme.work, ieee80211_ba_session_work); #ifdef CONFIG_MAC80211_MESH if (ieee80211_vif_is_mesh(&sdata->vif)) { - sta->mesh = kzalloc(sizeof(*sta->mesh), gfp); + sta->mesh = kzalloc_obj(*sta->mesh, gfp); if (!sta->mesh) goto free; sta->mesh->plink_sta = sta; @@ -903,7 +903,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) goto out_cleanup; } - sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL); + sinfo = kzalloc_obj(struct station_info); if (!sinfo) { err = -ENOMEM; goto out_cleanup; @@ -1545,7 +1545,7 @@ static void __sta_info_destroy_part2(struct sta_info *sta, bool recalc) } } - sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL); + sinfo = kzalloc_obj(*sinfo); if (sinfo) sta_set_sinfo(sta, sinfo, true); @@ -3306,7 +3306,7 @@ int ieee80211_sta_allocate_link(struct sta_info *sta, unsigned int link_id) sta->link[link_id])) return -EBUSY; - alloc = kzalloc(sizeof(*alloc), GFP_KERNEL); + alloc = kzalloc_obj(*alloc); if (!alloc) return -ENOMEM; diff --git a/net/mac80211/tests/util.c b/net/mac80211/tests/util.c index 9c2d63a5cd2b..0b01264af577 100644 --- a/net/mac80211/tests/util.c +++ b/net/mac80211/tests/util.c @@ -195,16 +195,16 @@ int t_sdata_init(struct kunit_resource *resource, void *ctx) struct kunit *test = kunit_get_current_test(); struct t_sdata *t_sdata; - t_sdata = kzalloc(sizeof(*t_sdata), GFP_KERNEL); + t_sdata = kzalloc_obj(*t_sdata); KUNIT_ASSERT_NOT_NULL(test, t_sdata); resource->data = t_sdata; resource->name = "sdata"; - t_sdata->sdata = kzalloc(sizeof(*t_sdata->sdata), GFP_KERNEL); + t_sdata->sdata = kzalloc_obj(*t_sdata->sdata); KUNIT_ASSERT_NOT_NULL(test, t_sdata->sdata); - t_sdata->wiphy = kzalloc(sizeof(*t_sdata->wiphy), GFP_KERNEL); + t_sdata->wiphy = kzalloc_obj(*t_sdata->wiphy); KUNIT_ASSERT_NOT_NULL(test, t_sdata->wiphy); strscpy(t_sdata->sdata->name, "kunit"); diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 007f5a368d41..8cdbd417d7be 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -1611,8 +1611,7 @@ int ieee80211_txq_setup_flows(struct ieee80211_local *local) local->cparams.target = MS2TIME(20); local->cparams.ecn = true; - local->cvars = kvcalloc(fq->flows_cnt, sizeof(local->cvars[0]), - GFP_KERNEL); + local->cvars = kvzalloc_objs(local->cvars[0], fq->flows_cnt); if (!local->cvars) { spin_lock_bh(&fq->lock); fq_reset(fq, fq_skb_free_func); @@ -5549,8 +5548,7 @@ ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw, if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt) return NULL; - ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt), - GFP_ATOMIC); + ema = kzalloc_flex(*ema, bcn, beacon->mbssid_ies->cnt, GFP_ATOMIC); if (!ema) return NULL; diff --git a/net/mac80211/util.c b/net/mac80211/util.c index a5e09c0fa6b3..b2e6c8b98381 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1742,9 +1742,7 @@ static int ieee80211_reconfig_nan(struct ieee80211_sub_if_data *sdata) if (WARN_ON(res)) return res; - funcs = kcalloc(sdata->local->hw.max_nan_de_entries + 1, - sizeof(*funcs), - GFP_KERNEL); + funcs = kzalloc_objs(*funcs, sdata->local->hw.max_nan_de_entries + 1); if (!funcs) return -ENOMEM; diff --git a/net/mac802154/cfg.c b/net/mac802154/cfg.c index ef7f23af043f..e8484031a390 100644 --- a/net/mac802154/cfg.c +++ b/net/mac802154/cfg.c @@ -339,7 +339,7 @@ static int mac802154_associate(struct wpan_phy *wpan_phy, if (coord->mode == IEEE802154_SHORT_ADDRESSING) return -EINVAL; - parent = kzalloc(sizeof(*parent), GFP_KERNEL); + parent = kzalloc_obj(*parent); if (!parent) return -ENOMEM; diff --git a/net/mac802154/llsec.c b/net/mac802154/llsec.c index f13b07ebfb98..e8512578398e 100644 --- a/net/mac802154/llsec.c +++ b/net/mac802154/llsec.c @@ -117,7 +117,7 @@ llsec_key_alloc(const struct ieee802154_llsec_key *template) struct mac802154_llsec_key *key; int i; - key = kzalloc(sizeof(*key), GFP_KERNEL); + key = kzalloc_obj(*key); if (!key) return NULL; @@ -241,7 +241,7 @@ int mac802154_llsec_key_add(struct mac802154_llsec *sec, break; } - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return -ENOMEM; @@ -369,7 +369,7 @@ int mac802154_llsec_dev_add(struct mac802154_llsec *sec, llsec_dev_find_long(sec, dev->hwaddr)) return -EEXIST; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -441,7 +441,7 @@ int mac802154_llsec_devkey_add(struct mac802154_llsec *sec, if (llsec_devkey_find(dev, &key->key_id)) return -EEXIST; - devkey = kmalloc(sizeof(*devkey), GFP_KERNEL); + devkey = kmalloc_obj(*devkey); if (!devkey) return -ENOMEM; @@ -500,7 +500,7 @@ int mac802154_llsec_seclevel_add(struct mac802154_llsec *sec, if (llsec_find_seclevel(sec, sl)) return -EEXIST; - entry = kmalloc(sizeof(*entry), GFP_KERNEL); + entry = kmalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -925,7 +925,7 @@ llsec_update_devkey_record(struct mac802154_llsec_device *dev, if (!devkey) { struct mac802154_llsec_device_key *next; - next = kzalloc(sizeof(*devkey), GFP_ATOMIC); + next = kzalloc_obj(*devkey, GFP_ATOMIC); if (!next) return -ENOMEM; diff --git a/net/mac802154/rx.c b/net/mac802154/rx.c index aac359b5c71d..cd8f2a11920d 100644 --- a/net/mac802154/rx.c +++ b/net/mac802154/rx.c @@ -213,7 +213,7 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, if (!mac802154_is_scanning(sdata->local)) goto fail; - mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC); + mac_pkt = kzalloc_obj(*mac_pkt, GFP_ATOMIC); if (!mac_pkt) goto fail; @@ -227,7 +227,7 @@ ieee802154_subif_frame(struct ieee802154_sub_if_data *sdata, case IEEE802154_FC_TYPE_MAC_CMD: dev_dbg(&sdata->dev->dev, "MAC COMMAND received\n"); - mac_pkt = kzalloc(sizeof(*mac_pkt), GFP_ATOMIC); + mac_pkt = kzalloc_obj(*mac_pkt, GFP_ATOMIC); if (!mac_pkt) goto fail; diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index a6dab3cc3ad8..0a31ac8d8415 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -798,7 +798,7 @@ int mac802154_process_association_req(struct ieee802154_sub_if_data *sdata, goto unlock; } - child = kzalloc(sizeof(*child), GFP_KERNEL); + child = kzalloc_obj(*child); if (!child) { ret = -ENOMEM; goto unlock; diff --git a/net/mctp/device.c b/net/mctp/device.c index 4d404edd7446..2c84df674669 100644 --- a/net/mctp/device.c +++ b/net/mctp/device.c @@ -70,6 +70,7 @@ static int mctp_fill_addrinfo(struct sk_buff *skb, return -EMSGSIZE; hdr = nlmsg_data(nlh); + memset(hdr, 0, sizeof(*hdr)); hdr->ifa_family = AF_MCTP; hdr->ifa_prefixlen = 0; hdr->ifa_flags = 0; @@ -335,7 +336,7 @@ static struct mctp_dev *mctp_add_dev(struct net_device *dev) ASSERT_RTNL(); - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return ERR_PTR(-ENOMEM); diff --git a/net/mctp/neigh.c b/net/mctp/neigh.c index 05b899f22d90..87e40db0f078 100644 --- a/net/mctp/neigh.c +++ b/net/mctp/neigh.c @@ -40,7 +40,7 @@ static int mctp_neigh_add(struct mctp_dev *mdev, mctp_eid_t eid, goto out; } - neigh = kzalloc(sizeof(*neigh), GFP_KERNEL); + neigh = kzalloc_obj(*neigh); if (!neigh) { rc = -ENOMEM; goto out; @@ -218,6 +218,7 @@ static int mctp_fill_neigh(struct sk_buff *skb, u32 portid, u32 seq, int event, return -EMSGSIZE; hdr = nlmsg_data(nlh); + memset(hdr, 0, sizeof(*hdr)); hdr->ndm_family = AF_MCTP; hdr->ndm_ifindex = dev->ifindex; hdr->ndm_state = 0; // TODO other state bits? diff --git a/net/mctp/route.c b/net/mctp/route.c index 2ac4011a953f..59ad60b88563 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -227,7 +227,7 @@ static struct mctp_sk_key *mctp_key_alloc(struct mctp_sock *msk, { struct mctp_sk_key *key; - key = kzalloc(sizeof(*key), gfp); + key = kzalloc_obj(*key, gfp); if (!key) return NULL; @@ -359,6 +359,7 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) { struct mctp_sk_key *key; struct mctp_flow *flow; + unsigned long flags; flow = skb_ext_find(skb, SKB_EXT_MCTP); if (!flow) @@ -366,12 +367,14 @@ static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) key = flow->key; - if (key->dev) { - WARN_ON(key->dev != dev); - return; - } + spin_lock_irqsave(&key->lock, flags); - mctp_dev_set_key(dev, key); + if (!key->dev) + mctp_dev_set_key(dev, key); + else + WARN_ON(key->dev != dev); + + spin_unlock_irqrestore(&key->lock, flags); } #else static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key) {} @@ -675,7 +678,7 @@ static struct mctp_route *mctp_route_alloc(void) { struct mctp_route *rt; - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) return NULL; @@ -1643,6 +1646,7 @@ static int mctp_fill_rtinfo(struct sk_buff *skb, struct mctp_route *rt, return -EMSGSIZE; hdr = nlmsg_data(nlh); + memset(hdr, 0, sizeof(*hdr)); hdr->rtm_family = AF_MCTP; /* we use the _len fields as a number of EIDs, rather than diff --git a/net/mctp/test/utils.c b/net/mctp/test/utils.c index 37f1ba62a2ab..97afe8cd2b05 100644 --- a/net/mctp/test/utils.c +++ b/net/mctp/test/utils.c @@ -106,7 +106,7 @@ static struct mctp_test_route *mctp_route_test_alloc(void) { struct mctp_test_route *rt; - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) return NULL; diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 580aac112dd2..ef9e749d5e08 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1470,7 +1470,7 @@ static struct mpls_dev *mpls_add_dev(struct net_device *dev) int err = -ENOMEM; int i; - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return ERR_PTR(err); @@ -1977,7 +1977,7 @@ static int mpls_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, struct mpls_route_config *cfg; int err; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; @@ -2002,7 +2002,7 @@ static int mpls_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, struct mpls_route_config *cfg; int err; - cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + cfg = kzalloc_obj(*cfg); if (!cfg) return -ENOMEM; diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index e2040c327af6..57a456690406 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -212,9 +212,24 @@ void mptcp_pm_send_ack(struct mptcp_sock *msk, spin_lock_bh(&msk->pm.lock); } -void mptcp_pm_addr_send_ack(struct mptcp_sock *msk) +static bool subflow_in_rm_list(const struct mptcp_subflow_context *subflow, + const struct mptcp_rm_list *rm_list) { - struct mptcp_subflow_context *subflow, *alt = NULL; + u8 i, id = subflow_get_local_id(subflow); + + for (i = 0; i < rm_list->nr; i++) { + if (rm_list->ids[i] == id) + return true; + } + + return false; +} + +static void +mptcp_pm_addr_send_ack_avoid_list(struct mptcp_sock *msk, + const struct mptcp_rm_list *rm_list) +{ + struct mptcp_subflow_context *subflow, *stale = NULL, *same_id = NULL; msk_owned_by_me(msk); lockdep_assert_held(&msk->pm.lock); @@ -224,19 +239,35 @@ void mptcp_pm_addr_send_ack(struct mptcp_sock *msk) return; mptcp_for_each_subflow(msk, subflow) { - if (__mptcp_subflow_active(subflow)) { - if (!subflow->stale) { - mptcp_pm_send_ack(msk, subflow, false, false); - return; - } + if (!__mptcp_subflow_active(subflow)) + continue; - if (!alt) - alt = subflow; + if (unlikely(subflow->stale)) { + if (!stale) + stale = subflow; + } else if (unlikely(rm_list && + subflow_in_rm_list(subflow, rm_list))) { + if (!same_id) + same_id = subflow; + } else { + goto send_ack; } } - if (alt) - mptcp_pm_send_ack(msk, alt, false, false); + if (same_id) + subflow = same_id; + else if (stale) + subflow = stale; + else + return; + +send_ack: + mptcp_pm_send_ack(msk, subflow, false, false); +} + +void mptcp_pm_addr_send_ack(struct mptcp_sock *msk) +{ + mptcp_pm_addr_send_ack_avoid_list(msk, NULL); } int mptcp_pm_mp_prio_send_ack(struct mptcp_sock *msk, @@ -388,7 +419,7 @@ bool mptcp_pm_alloc_anno_list(struct mptcp_sock *msk, goto reset_timer; } - add_entry = kmalloc(sizeof(*add_entry), GFP_ATOMIC); + add_entry = kmalloc_obj(*add_entry, GFP_ATOMIC); if (!add_entry) return false; @@ -470,7 +501,7 @@ int mptcp_pm_remove_addr(struct mptcp_sock *msk, const struct mptcp_rm_list *rm_ msk->pm.rm_list_tx = *rm_list; rm_addr |= BIT(MPTCP_RM_ADDR_SIGNAL); WRITE_ONCE(msk->pm.addr_signal, rm_addr); - mptcp_pm_addr_send_ack(msk); + mptcp_pm_addr_send_ack_avoid_list(msk, rm_list); return 0; } diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c index b5316a6c7d1b..b2b9df43960e 100644 --- a/net/mptcp/pm_kernel.c +++ b/net/mptcp/pm_kernel.c @@ -418,6 +418,15 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) } exit: + /* If an endpoint has both the signal and subflow flags, but it is not + * possible to create subflows -- the 'while' loop body above never + * executed -- then still mark the endp as used, which is somehow the + * case. This avoids issues later when removing the endpoint and calling + * __mark_subflow_endp_available(), which expects the increment here. + */ + if (signal_and_subflow && local.addr.id != msk->mpc_endpoint_id) + msk->pm.local_addr_used++; + mptcp_pm_nl_check_work_pending(msk); } diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c index f66129f1e649..6716970693e9 100644 --- a/net/mptcp/subflow.c +++ b/net/mptcp/subflow.c @@ -808,7 +808,9 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req) + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)) { struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk); struct mptcp_subflow_request_sock *subflow_req; @@ -855,7 +857,7 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, create_child: child = listener->icsk_af_ops->syn_recv_sock(sk, skb, req, dst, - req_unhash, own_req); + req_unhash, own_req, opt_child_init); if (child && *own_req) { struct mptcp_subflow_context *ctx = mptcp_subflow_ctx(child); @@ -1842,7 +1844,7 @@ static struct mptcp_subflow_context *subflow_create_ctx(struct sock *sk, struct inet_connection_sock *icsk = inet_csk(sk); struct mptcp_subflow_context *ctx; - ctx = kzalloc(sizeof(*ctx), priority); + ctx = kzalloc_obj(*ctx, priority); if (!ctx) return NULL; diff --git a/net/ncsi/ncsi-aen.c b/net/ncsi/ncsi-aen.c index 62fb1031763d..040a31557201 100644 --- a/net/ncsi/ncsi-aen.c +++ b/net/ncsi/ncsi-aen.c @@ -224,7 +224,8 @@ int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb) if (!nah) { netdev_warn(ndp->ndev.dev, "Invalid AEN (0x%x) received\n", h->type); - return -ENOENT; + ret = -ENOENT; + goto out; } ret = ncsi_validate_aen_pkt(h, nah->payload); diff --git a/net/ncsi/ncsi-manage.c b/net/ncsi/ncsi-manage.c index 446e4e3b9553..54d0df0a9efe 100644 --- a/net/ncsi/ncsi-manage.c +++ b/net/ncsi/ncsi-manage.c @@ -211,7 +211,7 @@ struct ncsi_channel *ncsi_add_channel(struct ncsi_package *np, unsigned char id) int index; unsigned long flags; - nc = kzalloc(sizeof(*nc), GFP_ATOMIC); + nc = kzalloc_obj(*nc, GFP_ATOMIC); if (!nc) return NULL; @@ -285,7 +285,7 @@ struct ncsi_package *ncsi_add_package(struct ncsi_dev_priv *ndp, struct ncsi_package *np, *tmp; unsigned long flags; - np = kzalloc(sizeof(*np), GFP_ATOMIC); + np = kzalloc_obj(*np, GFP_ATOMIC); if (!np) return NULL; @@ -1697,7 +1697,7 @@ int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) return -ENOSPC; } - vlan = kzalloc(sizeof(*vlan), GFP_KERNEL); + vlan = kzalloc_obj(*vlan); if (!vlan) return -ENOMEM; @@ -1767,7 +1767,7 @@ struct ncsi_dev *ncsi_register_dev(struct net_device *dev, return nd; /* Create NCSI device */ - ndp = kzalloc(sizeof(*ndp), GFP_ATOMIC); + ndp = kzalloc_obj(*ndp, GFP_ATOMIC); if (!ndp) return NULL; diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index 271ec6c3929e..fbd84bc8026a 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c @@ -1176,8 +1176,10 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, /* Find the NCSI device */ nd = ncsi_find_dev(orig_dev); ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL; - if (!ndp) - return -ENODEV; + if (!ndp) { + ret = -ENODEV; + goto err_free_skb; + } /* Check if it is AEN packet */ hdr = (struct ncsi_pkt_hdr *)skb_network_header(skb); @@ -1199,7 +1201,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, if (!nrh) { netdev_err(nd->dev, "Received unrecognized packet (0x%x)\n", hdr->type); - return -ENOENT; + ret = -ENOENT; + goto err_free_skb; } /* Associate with the request */ @@ -1207,7 +1210,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, nr = &ndp->requests[hdr->id]; if (!nr->used) { spin_unlock_irqrestore(&ndp->lock, flags); - return -ENODEV; + ret = -ENODEV; + goto err_free_skb; } nr->rsp = skb; @@ -1261,4 +1265,8 @@ int ncsi_rcv_rsp(struct sk_buff *skb, struct net_device *dev, out: ncsi_free_request(nr); return ret; + +err_free_skb: + kfree_skb(skb); + return ret; } diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c index cc20e6d56807..a2fe711cb5e3 100644 --- a/net/netfilter/ipset/ip_set_core.c +++ b/net/netfilter/ipset/ip_set_core.c @@ -1077,7 +1077,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, /* First, and without any locks, allocate and initialize * a normal base set structure. */ - set = kzalloc(sizeof(*set), GFP_KERNEL); + set = kzalloc_obj(*set); if (!set) return -ENOMEM; spin_lock_init(&set->lock); @@ -1135,7 +1135,7 @@ static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info, /* Wraparound */ goto cleanup; - list = kvcalloc(i, sizeof(struct ip_set *), GFP_KERNEL); + list = kvzalloc_objs(struct ip_set *, i); if (!list) goto cleanup; /* nfnl mutex is held, both lists are valid */ @@ -2377,7 +2377,7 @@ ip_set_net_init(struct net *net) if (inst->ip_set_max >= IPSET_INVALID_ID) inst->ip_set_max = IPSET_INVALID_ID - 1; - list = kvcalloc(inst->ip_set_max, sizeof(struct ip_set *), GFP_KERNEL); + list = kvzalloc_objs(struct ip_set *, inst->ip_set_max); if (!list) return -ENOMEM; inst->is_deleted = false; diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h index 5e4453e9ef8e..181daa9c2019 100644 --- a/net/netfilter/ipset/ip_set_hash_gen.h +++ b/net/netfilter/ipset/ip_set_hash_gen.h @@ -998,7 +998,7 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, /* Resize is in process and kernel side add, save values */ struct mtype_resize_ad *x; - x = kzalloc(sizeof(struct mtype_resize_ad), GFP_ATOMIC); + x = kzalloc_obj(struct mtype_resize_ad, GFP_ATOMIC); if (!x) /* Don't bother */ goto out; @@ -1086,8 +1086,7 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, /* Resize is in process and kernel side del, * save values */ - x = kzalloc(sizeof(struct mtype_resize_ad), - GFP_ATOMIC); + x = kzalloc_obj(struct mtype_resize_ad, GFP_ATOMIC); if (x) { x->ad = IPSET_DEL; memcpy(&x->d, value, diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 13c7a08aa868..98b91b34c314 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c @@ -598,7 +598,7 @@ init_list_set(struct net *net, struct ip_set *set, u32 size) { struct list_set *map; - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (!map) return false; diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index 50cc492c7553..005c1134d756 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -1510,8 +1510,7 @@ int __init ip_vs_conn_init(void) */ tab_array_size = array_size(ip_vs_conn_tab_size, sizeof(*ip_vs_conn_tab)); - ip_vs_conn_tab = kvmalloc_array(ip_vs_conn_tab_size, - sizeof(*ip_vs_conn_tab), GFP_KERNEL); + ip_vs_conn_tab = kvmalloc_objs(*ip_vs_conn_tab, ip_vs_conn_tab_size); if (!ip_vs_conn_tab) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 068702894377..35642de2a0fe 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -938,7 +938,7 @@ int ip_vs_stats_init_alloc(struct ip_vs_stats *s) struct ip_vs_stats *ip_vs_stats_alloc(void) { - struct ip_vs_stats *s = kzalloc(sizeof(*s), GFP_KERNEL); + struct ip_vs_stats *s = kzalloc_obj(*s); if (s && ip_vs_stats_init_alloc(s) >= 0) return s; @@ -1079,7 +1079,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) return -EINVAL; } - dest = kzalloc(sizeof(struct ip_vs_dest), GFP_KERNEL); + dest = kzalloc_obj(struct ip_vs_dest); if (dest == NULL) return -ENOMEM; @@ -1421,7 +1421,7 @@ ip_vs_add_service(struct netns_ipvs *ipvs, struct ip_vs_service_user_kern *u, ret_hooks = ret; } - svc = kzalloc(sizeof(struct ip_vs_service), GFP_KERNEL); + svc = kzalloc_obj(struct ip_vs_service); if (svc == NULL) { IP_VS_DBG(1, "%s(): no memory\n", __func__); ret = -ENOMEM; @@ -4439,7 +4439,7 @@ int __net_init ip_vs_control_net_init(struct netns_ipvs *ipvs) INIT_DELAYED_WORK(&ipvs->est_reload_work, est_reload_work_handler); /* procfs stats */ - ipvs->tot_stats = kzalloc(sizeof(*ipvs->tot_stats), GFP_KERNEL); + ipvs->tot_stats = kzalloc_obj(*ipvs->tot_stats); if (!ipvs->tot_stats) goto out; if (ip_vs_stats_init_alloc(&ipvs->tot_stats->s) < 0) diff --git a/net/netfilter/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c index bb7aca4601ff..e1f62f6b25e2 100644 --- a/net/netfilter/ipvs/ip_vs_dh.c +++ b/net/netfilter/ipvs/ip_vs_dh.c @@ -153,7 +153,7 @@ static int ip_vs_dh_init_svc(struct ip_vs_service *svc) struct ip_vs_dh_state *s; /* allocate the DH table for this service */ - s = kzalloc(sizeof(struct ip_vs_dh_state), GFP_KERNEL); + s = kzalloc_obj(struct ip_vs_dh_state); if (s == NULL) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index 77f4f637ff67..b17de33314da 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c @@ -325,7 +325,7 @@ static int ip_vs_est_add_kthread(struct netns_ipvs *ipvs) id = i; } - kd = kzalloc(sizeof(*kd), GFP_KERNEL); + kd = kzalloc_obj(*kd); if (!kd) goto out; kd->ipvs = ipvs; @@ -443,7 +443,7 @@ static int ip_vs_enqueue_estimator(struct netns_ipvs *ipvs, td = rcu_dereference_protected(kd->ticks[row], 1); if (!td) { - td = kzalloc(sizeof(*td), GFP_KERNEL); + td = kzalloc_obj(*td); if (!td) { ret = -ENOMEM; goto out; diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c index e6c8ed0c92f6..15ccb2b2fa1f 100644 --- a/net/netfilter/ipvs/ip_vs_lblc.c +++ b/net/netfilter/ipvs/ip_vs_lblc.c @@ -204,7 +204,7 @@ ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, const union nf_inet_addr *daddr, return en; ip_vs_lblc_del(en); } - en = kmalloc(sizeof(*en), GFP_ATOMIC); + en = kmalloc_obj(*en, GFP_ATOMIC); if (!en) return NULL; @@ -347,7 +347,7 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc) /* * Allocate the ip_vs_lblc_table for this service */ - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kmalloc_obj(*tbl); if (tbl == NULL) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c index a25cf7bb6185..c90ea897c3f7 100644 --- a/net/netfilter/ipvs/ip_vs_lblcr.c +++ b/net/netfilter/ipvs/ip_vs_lblcr.c @@ -107,7 +107,7 @@ static void ip_vs_dest_set_insert(struct ip_vs_dest_set *set, } } - e = kmalloc(sizeof(*e), GFP_ATOMIC); + e = kmalloc_obj(*e, GFP_ATOMIC); if (e == NULL) return; @@ -363,7 +363,7 @@ ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, const union nf_inet_addr *daddr, en = ip_vs_lblcr_get(af, tbl, daddr); if (!en) { - en = kmalloc(sizeof(*en), GFP_ATOMIC); + en = kmalloc_obj(*en, GFP_ATOMIC); if (!en) return NULL; @@ -510,7 +510,7 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc) /* * Allocate the ip_vs_lblcr_table for this service */ - tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); + tbl = kmalloc_obj(*tbl); if (tbl == NULL) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_mh.c b/net/netfilter/ipvs/ip_vs_mh.c index f61f54004c9e..020863047562 100644 --- a/net/netfilter/ipvs/ip_vs_mh.c +++ b/net/netfilter/ipvs/ip_vs_mh.c @@ -293,9 +293,8 @@ static int ip_vs_mh_reassign(struct ip_vs_mh_state *s, return -EINVAL; if (svc->num_dests >= 1) { - s->dest_setup = kcalloc(svc->num_dests, - sizeof(struct ip_vs_mh_dest_setup), - GFP_KERNEL); + s->dest_setup = kzalloc_objs(struct ip_vs_mh_dest_setup, + svc->num_dests); if (!s->dest_setup) return -ENOMEM; } @@ -383,12 +382,11 @@ static int ip_vs_mh_init_svc(struct ip_vs_service *svc) struct ip_vs_mh_state *s; /* Allocate the MH table for this service */ - s = kzalloc(sizeof(*s), GFP_KERNEL); + s = kzalloc_obj(*s); if (!s) return -ENOMEM; - s->lookup = kcalloc(IP_VS_MH_TAB_SIZE, sizeof(struct ip_vs_mh_lookup), - GFP_KERNEL); + s->lookup = kzalloc_objs(struct ip_vs_mh_lookup, IP_VS_MH_TAB_SIZE); if (!s->lookup) { kfree(s); return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c index fd9dbca24c85..0046aed1fb38 100644 --- a/net/netfilter/ipvs/ip_vs_proto.c +++ b/net/netfilter/ipvs/ip_vs_proto.c @@ -66,7 +66,7 @@ register_ip_vs_proto_netns(struct netns_ipvs *ipvs, struct ip_vs_protocol *pp) { unsigned int hash = IP_VS_PROTO_HASH(pp->protocol); struct ip_vs_proto_data *pd = - kzalloc(sizeof(struct ip_vs_proto_data), GFP_KERNEL); + kzalloc_obj(struct ip_vs_proto_data); if (!pd) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_proto_sctp.c b/net/netfilter/ipvs/ip_vs_proto_sctp.c index 83e452916403..63c78a1f3918 100644 --- a/net/netfilter/ipvs/ip_vs_proto_sctp.c +++ b/net/netfilter/ipvs/ip_vs_proto_sctp.c @@ -10,7 +10,8 @@ #include static int -sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); +sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int sctphoff); static int sctp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, @@ -108,7 +109,7 @@ sctp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!sctp_csum_check(cp->af, skb, pp)) + if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) return 0; /* Call application helper if needed */ @@ -156,7 +157,7 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!sctp_csum_check(cp->af, skb, pp)) + if (!sctp_csum_check(cp->af, skb, pp, sctphoff)) return 0; /* Call application helper if needed */ @@ -185,19 +186,12 @@ sctp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, } static int -sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) +sctp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int sctphoff) { - unsigned int sctphoff; struct sctphdr *sh; __le32 cmp, val; -#ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) - sctphoff = sizeof(struct ipv6hdr); - else -#endif - sctphoff = ip_hdrlen(skb); - sh = (struct sctphdr *)(skb->data + sctphoff); cmp = sh->checksum; val = sctp_compute_cksum(skb, sctphoff); diff --git a/net/netfilter/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c index f68a1533ee45..8cc0a8ce6241 100644 --- a/net/netfilter/ipvs/ip_vs_proto_tcp.c +++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c @@ -28,7 +28,8 @@ #include static int -tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); +tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int tcphoff); static int tcp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, @@ -165,7 +166,7 @@ tcp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!tcp_csum_check(cp->af, skb, pp)) + if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) return 0; /* Call application helper if needed */ @@ -243,7 +244,7 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!tcp_csum_check(cp->af, skb, pp)) + if (!tcp_csum_check(cp->af, skb, pp, tcphoff)) return 0; /* @@ -300,17 +301,9 @@ tcp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, static int -tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) +tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int tcphoff) { - unsigned int tcphoff; - -#ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) - tcphoff = sizeof(struct ipv6hdr); - else -#endif - tcphoff = ip_hdrlen(skb); - switch (skb->ip_summed) { case CHECKSUM_NONE: skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); @@ -321,7 +314,7 @@ tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->len - tcphoff, - ipv6_hdr(skb)->nexthdr, + IPPROTO_TCP, skb->csum)) { IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); diff --git a/net/netfilter/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c index 0f0107c80dd2..f9de632e38cd 100644 --- a/net/netfilter/ipvs/ip_vs_proto_udp.c +++ b/net/netfilter/ipvs/ip_vs_proto_udp.c @@ -24,7 +24,8 @@ #include static int -udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp); +udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int udphoff); static int udp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb, @@ -154,7 +155,7 @@ udp_snat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!udp_csum_check(cp->af, skb, pp)) + if (!udp_csum_check(cp->af, skb, pp, udphoff)) return 0; /* @@ -237,7 +238,7 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, int ret; /* Some checks before mangling */ - if (!udp_csum_check(cp->af, skb, pp)) + if (!udp_csum_check(cp->af, skb, pp, udphoff)) return 0; /* @@ -296,17 +297,10 @@ udp_dnat_handler(struct sk_buff *skb, struct ip_vs_protocol *pp, static int -udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) +udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp, + unsigned int udphoff) { struct udphdr _udph, *uh; - unsigned int udphoff; - -#ifdef CONFIG_IP_VS_IPV6 - if (af == AF_INET6) - udphoff = sizeof(struct ipv6hdr); - else -#endif - udphoff = ip_hdrlen(skb); uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph); if (uh == NULL) @@ -324,7 +318,7 @@ udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp) if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, skb->len - udphoff, - ipv6_hdr(skb)->nexthdr, + IPPROTO_UDP, skb->csum)) { IP_VS_DBG_RL_PKT(0, af, pp, skb, 0, "Failed checksum for"); diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c index 0e85e07e23b9..cd67066e3b26 100644 --- a/net/netfilter/ipvs/ip_vs_sh.c +++ b/net/netfilter/ipvs/ip_vs_sh.c @@ -229,7 +229,7 @@ static int ip_vs_sh_init_svc(struct ip_vs_service *svc) struct ip_vs_sh_state *s; /* allocate the SH table for this service */ - s = kzalloc(sizeof(struct ip_vs_sh_state), GFP_KERNEL); + s = kzalloc_obj(struct ip_vs_sh_state); if (s == NULL) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 54dd1514ac45..b2ba3befbd55 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c @@ -329,7 +329,7 @@ ip_vs_sync_buff_create(struct netns_ipvs *ipvs, unsigned int len) { struct ip_vs_sync_buff *sb; - if (!(sb=kmalloc(sizeof(struct ip_vs_sync_buff), GFP_ATOMIC))) + if (!(sb=kmalloc_obj(struct ip_vs_sync_buff, GFP_ATOMIC))) return NULL; len = max_t(unsigned int, len + sizeof(struct ip_vs_sync_mesg), @@ -417,7 +417,7 @@ ip_vs_sync_buff_create_v0(struct netns_ipvs *ipvs, unsigned int len) struct ip_vs_sync_buff *sb; struct ip_vs_sync_mesg_v0 *mesg; - if (!(sb=kmalloc(sizeof(struct ip_vs_sync_buff), GFP_ATOMIC))) + if (!(sb=kmalloc_obj(struct ip_vs_sync_buff, GFP_ATOMIC))) return NULL; len = max_t(unsigned int, len + sizeof(struct ip_vs_sync_mesg_v0), @@ -1827,7 +1827,7 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, struct ipvs_master_sync_state *ms; result = -ENOMEM; - ipvs->ms = kcalloc(count, sizeof(ipvs->ms[0]), GFP_KERNEL); + ipvs->ms = kzalloc_objs(ipvs->ms[0], count); if (!ipvs->ms) goto out; ms = ipvs->ms; @@ -1841,8 +1841,7 @@ int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *c, } } result = -ENOMEM; - ti = kcalloc(count, sizeof(struct ip_vs_sync_thread_data), - GFP_KERNEL); + ti = kzalloc_objs(struct ip_vs_sync_thread_data, count); if (!ti) goto out; diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c index 99f09cbf2d9b..2dcff1040da5 100644 --- a/net/netfilter/ipvs/ip_vs_wrr.c +++ b/net/netfilter/ipvs/ip_vs_wrr.c @@ -109,7 +109,7 @@ static int ip_vs_wrr_init_svc(struct ip_vs_service *svc) /* * Allocate the mark variable for WRR scheduling */ - mark = kmalloc(sizeof(struct ip_vs_wrr_mark), GFP_KERNEL); + mark = kmalloc_obj(struct ip_vs_wrr_mark); if (mark == NULL) return -ENOMEM; diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index f861d116cc33..3601eb86d025 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c @@ -57,7 +57,7 @@ enum { static inline struct ip_vs_dest_dst *ip_vs_dest_dst_alloc(void) { - return kmalloc(sizeof(struct ip_vs_dest_dst), GFP_ATOMIC); + return kmalloc_obj(struct ip_vs_dest_dst, GFP_ATOMIC); } static inline void ip_vs_dest_dst_free(struct ip_vs_dest_dst *dest_dst) @@ -294,6 +294,12 @@ static inline bool decrement_ttl(struct netns_ipvs *ipvs, return true; } +/* rt has device that is down */ +static bool rt_dev_is_down(const struct net_device *dev) +{ + return dev && !netif_running(dev); +} + /* Get route to destination or remote server */ static int __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, @@ -309,9 +315,11 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, if (dest) { dest_dst = __ip_vs_dst_check(dest); - if (likely(dest_dst)) + if (likely(dest_dst)) { rt = dst_rtable(dest_dst->dst_cache); - else { + if (ret_saddr) + *ret_saddr = dest_dst->dst_saddr.ip; + } else { dest_dst = ip_vs_dest_dst_alloc(); spin_lock_bh(&dest->dst_lock); if (!dest_dst) { @@ -327,14 +335,22 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, ip_vs_dest_dst_free(dest_dst); goto err_unreach; } - __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); + /* It is forbidden to attach dest->dest_dst if + * device is going down. + */ + if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) + __ip_vs_dst_set(dest, dest_dst, &rt->dst, 0); + else + noref = 0; spin_unlock_bh(&dest->dst_lock); IP_VS_DBG(10, "new dst %pI4, src %pI4, refcnt=%d\n", &dest->addr.ip, &dest_dst->dst_saddr.ip, rcuref_read(&rt->dst.__rcuref)); + if (ret_saddr) + *ret_saddr = dest_dst->dst_saddr.ip; + if (!noref) + ip_vs_dest_dst_free(dest_dst); } - if (ret_saddr) - *ret_saddr = dest_dst->dst_saddr.ip; } else { noref = 0; @@ -471,9 +487,11 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, if (dest) { dest_dst = __ip_vs_dst_check(dest); - if (likely(dest_dst)) + if (likely(dest_dst)) { rt = dst_rt6_info(dest_dst->dst_cache); - else { + if (ret_saddr) + *ret_saddr = dest_dst->dst_saddr.in6; + } else { u32 cookie; dest_dst = ip_vs_dest_dst_alloc(); @@ -494,14 +512,22 @@ __ip_vs_get_out_rt_v6(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb, } rt = dst_rt6_info(dst); cookie = rt6_get_cookie(rt); - __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); + /* It is forbidden to attach dest->dest_dst if + * device is going down. + */ + if (!rt_dev_is_down(dst_dev_rcu(&rt->dst))) + __ip_vs_dst_set(dest, dest_dst, &rt->dst, cookie); + else + noref = 0; spin_unlock_bh(&dest->dst_lock); IP_VS_DBG(10, "new dst %pI6, src %pI6, refcnt=%d\n", &dest->addr.in6, &dest_dst->dst_saddr.in6, rcuref_read(&rt->dst.__rcuref)); + if (ret_saddr) + *ret_saddr = dest_dst->dst_saddr.in6; + if (!noref) + ip_vs_dest_dst_free(dest_dst); } - if (ret_saddr) - *ret_saddr = dest_dst->dst_saddr.in6; } else { noref = 0; dst = __ip_vs_route_output_v6(net, daddr, ret_saddr, do_xfrm, diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c index 46e667a50d98..6f3a6411f4af 100644 --- a/net/netfilter/nf_bpf_link.c +++ b/net/netfilter/nf_bpf_link.c @@ -221,7 +221,7 @@ int bpf_nf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) if (err) return err; - link = kzalloc(sizeof(*link), GFP_USER); + link = kzalloc_obj(*link, GFP_USER); if (!link) return -ENOMEM; diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c index 14e62b3263cd..00eed5b4d1b1 100644 --- a/net/netfilter/nf_conncount.c +++ b/net/netfilter/nf_conncount.c @@ -632,7 +632,7 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen net_get_random_once(&conncount_rnd, sizeof(conncount_rnd)); - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return ERR_PTR(-ENOMEM); diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c index 7be4c35e4795..c0132559f6af 100644 --- a/net/netfilter/nf_conntrack_amanda.c +++ b/net/netfilter/nf_conntrack_amanda.c @@ -37,13 +37,13 @@ MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); module_param(ts_algo, charp, 0400); MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)"); -unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb, - enum ip_conntrack_info ctinfo, - unsigned int protoff, - unsigned int matchoff, - unsigned int matchlen, - struct nf_conntrack_expect *exp) - __read_mostly; +unsigned int (__rcu *nf_nat_amanda_hook)(struct sk_buff *skb, + enum ip_conntrack_info ctinfo, + unsigned int protoff, + unsigned int matchoff, + unsigned int matchlen, + struct nf_conntrack_expect *exp) + __read_mostly; EXPORT_SYMBOL_GPL(nf_nat_amanda_hook); enum amanda_strings { diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index d1f8eb725d42..27ce5fda8993 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -536,7 +536,7 @@ struct nf_conn *nf_ct_tmpl_alloc(struct net *net, if (tmpl != p) tmpl->proto.tmpl_padto = (char *)tmpl - (char *)p; } else { - tmpl = kzalloc(sizeof(*tmpl), flags); + tmpl = kzalloc_obj(*tmpl, flags); if (!tmpl) return NULL; } @@ -2535,7 +2535,7 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls) if (nr_slots > (INT_MAX / sizeof(struct hlist_nulls_head))) return NULL; - hash = kvcalloc(nr_slots, sizeof(struct hlist_nulls_head), GFP_KERNEL); + hash = kvzalloc_objs(struct hlist_nulls_head, nr_slots); if (hash && nulls) for (i = 0; i < nr_slots; i++) diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index 617f744a2e3a..5e00f9123c38 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c @@ -43,13 +43,13 @@ module_param_array(ports, ushort, &ports_c, 0400); static bool loose; module_param(loose, bool, 0600); -unsigned int (*nf_nat_ftp_hook)(struct sk_buff *skb, - enum ip_conntrack_info ctinfo, - enum nf_ct_ftp_type type, - unsigned int protoff, - unsigned int matchoff, - unsigned int matchlen, - struct nf_conntrack_expect *exp); +unsigned int (__rcu *nf_nat_ftp_hook)(struct sk_buff *skb, + enum ip_conntrack_info ctinfo, + enum nf_ct_ftp_type type, + unsigned int protoff, + unsigned int matchoff, + unsigned int matchlen, + struct nf_conntrack_expect *exp); EXPORT_SYMBOL_GPL(nf_nat_ftp_hook); static int try_rfc959(const char *, size_t, struct nf_conntrack_man *, diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c index 540d97715bd2..62aa22a07876 100644 --- a/net/netfilter/nf_conntrack_h323_asn1.c +++ b/net/netfilter/nf_conntrack_h323_asn1.c @@ -796,7 +796,7 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, if (ext || (son->attr & OPEN)) { BYTE_ALIGN(bs); - if (nf_h323_error_boundary(bs, len, 0)) + if (nf_h323_error_boundary(bs, 2, 0)) return H323_ERROR_BOUND; len = get_len(bs); if (nf_h323_error_boundary(bs, len, 0)) diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 17f1f453d481..a2a0e22ccee1 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c @@ -1187,13 +1187,13 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct, { struct net *net = nf_ct_net(ct); struct nf_conntrack_expect *exp; - struct nf_conntrack_tuple tuple; + struct nf_conntrack_tuple tuple = { + .src.l3num = nf_ct_l3num(ct), + .dst.protonum = IPPROTO_TCP, + .dst.u.tcp.port = port, + }; - memset(&tuple.src.u3, 0, sizeof(tuple.src.u3)); - tuple.src.u.tcp.port = 0; memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3)); - tuple.dst.u.tcp.port = port; - tuple.dst.protonum = IPPROTO_TCP; exp = __nf_ct_expect_find(net, nf_ct_zone(ct), &tuple); if (exp && exp->master == ct) diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c index 5703846bea3b..b8e6d724acd1 100644 --- a/net/netfilter/nf_conntrack_irc.c +++ b/net/netfilter/nf_conntrack_irc.c @@ -30,12 +30,13 @@ static unsigned int dcc_timeout __read_mostly = 300; static char *irc_buffer; static DEFINE_SPINLOCK(irc_buffer_lock); -unsigned int (*nf_nat_irc_hook)(struct sk_buff *skb, - enum ip_conntrack_info ctinfo, - unsigned int protoff, - unsigned int matchoff, - unsigned int matchlen, - struct nf_conntrack_expect *exp) __read_mostly; +unsigned int (__rcu *nf_nat_irc_hook)(struct sk_buff *skb, + enum ip_conntrack_info ctinfo, + unsigned int protoff, + unsigned int matchoff, + unsigned int matchlen, + struct nf_conntrack_expect *exp) + __read_mostly; EXPORT_SYMBOL_GPL(nf_nat_irc_hook); #define HELPER_NAME "irc" diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 662f6bbfa805..c9d725fc2d71 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -999,7 +999,7 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family) return ERR_PTR(-EOPNOTSUPP); #endif - filter = kzalloc(sizeof(*filter), GFP_KERNEL); + filter = kzalloc_obj(*filter); if (filter == NULL) return ERR_PTR(-ENOMEM); diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c index b894bb7a97ad..94c19bc4edc5 100644 --- a/net/netfilter/nf_conntrack_proto_gre.c +++ b/net/netfilter/nf_conntrack_proto_gre.c @@ -108,7 +108,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, return -EEXIST; } - km = kmalloc(sizeof(*km), GFP_ATOMIC); + km = kmalloc_obj(*km, GFP_ATOMIC); if (!km) return -ENOMEM; memcpy(&km->tuple, t, sizeof(*t)); diff --git a/net/netfilter/nf_conntrack_snmp.c b/net/netfilter/nf_conntrack_snmp.c index daacf2023fa5..387dd6e58f88 100644 --- a/net/netfilter/nf_conntrack_snmp.c +++ b/net/netfilter/nf_conntrack_snmp.c @@ -25,10 +25,10 @@ static unsigned int timeout __read_mostly = 30; module_param(timeout, uint, 0400); MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); -int (*nf_nat_snmp_hook)(struct sk_buff *skb, - unsigned int protoff, - struct nf_conn *ct, - enum ip_conntrack_info ctinfo); +int (__rcu *nf_nat_snmp_hook)(struct sk_buff *skb, + unsigned int protoff, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo); EXPORT_SYMBOL_GPL(nf_nat_snmp_hook); static int snmp_conntrack_help(struct sk_buff *skb, unsigned int protoff, diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c index 80ee53f29f68..89e9914e5d03 100644 --- a/net/netfilter/nf_conntrack_tftp.c +++ b/net/netfilter/nf_conntrack_tftp.c @@ -32,9 +32,10 @@ static unsigned int ports_c; module_param_array(ports, ushort, &ports_c, 0400); MODULE_PARM_DESC(ports, "Port numbers of TFTP servers"); -unsigned int (*nf_nat_tftp_hook)(struct sk_buff *skb, - enum ip_conntrack_info ctinfo, - struct nf_conntrack_expect *exp) __read_mostly; +unsigned int (__rcu *nf_nat_tftp_hook)(struct sk_buff *skb, + enum ip_conntrack_info ctinfo, + struct nf_conntrack_expect *exp) + __read_mostly; EXPORT_SYMBOL_GPL(nf_nat_tftp_hook); static int tftp_help(struct sk_buff *skb, diff --git a/net/netfilter/nf_flow_table_offload.c b/net/netfilter/nf_flow_table_offload.c index b1966b68c48a..9b677e116487 100644 --- a/net/netfilter/nf_flow_table_offload.c +++ b/net/netfilter/nf_flow_table_offload.c @@ -741,7 +741,7 @@ nf_flow_offload_rule_alloc(struct net *net, struct nf_flow_rule *flow_rule; int err = -ENOMEM; - flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL); + flow_rule = kzalloc_obj(*flow_rule); if (!flow_rule) goto err_flow; @@ -1022,7 +1022,7 @@ nf_flow_offload_work_alloc(struct nf_flowtable *flowtable, if (test_and_set_bit(NF_FLOW_HW_PENDING, &flow->flags)) return NULL; - offload = kmalloc(sizeof(struct flow_offload_work), GFP_ATOMIC); + offload = kmalloc_obj(struct flow_offload_work, GFP_ATOMIC); if (!offload) { clear_bit(NF_FLOW_HW_PENDING, &flow->flags); return NULL; diff --git a/net/netfilter/nf_flow_table_xdp.c b/net/netfilter/nf_flow_table_xdp.c index e1252d042699..86ac65e9b579 100644 --- a/net/netfilter/nf_flow_table_xdp.c +++ b/net/netfilter/nf_flow_table_xdp.c @@ -54,7 +54,7 @@ static int nf_flowtable_by_dev_insert(struct nf_flowtable *ft, unsigned long key = (unsigned long)dev; struct flow_offload_xdp_ft *ft_elem; - ft_elem = kzalloc(sizeof(*ft_elem), GFP_KERNEL_ACCOUNT); + ft_elem = kzalloc_obj(*ft_elem, GFP_KERNEL_ACCOUNT); if (!ft_elem) return -ENOMEM; @@ -70,7 +70,7 @@ static int nf_flowtable_by_dev_insert(struct nf_flowtable *ft, } if (!elem) { - elem = kzalloc(sizeof(*elem), GFP_KERNEL_ACCOUNT); + elem = kzalloc_obj(*elem, GFP_KERNEL_ACCOUNT); if (!elem) goto err_unlock; diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index 62cf6a30875e..f4d80654dfe6 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c @@ -317,7 +317,7 @@ EXPORT_SYMBOL_GPL(nf_log_buf_add); struct nf_log_buf *nf_log_buf_open(void) { - struct nf_log_buf *m = kmalloc(sizeof(*m), GFP_ATOMIC); + struct nf_log_buf *m = kmalloc_obj(*m, GFP_ATOMIC); if (unlikely(!m)) { local_bh_disable(); diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index e6b24586d2fe..3b5434e4ec9c 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c @@ -1213,7 +1213,7 @@ int nf_nat_register_fn(struct net *net, u8 pf, const struct nf_hook_ops *ops, } for (i = 0; i < ops_count; i++) { - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv) { nat_ops[i].priv = priv; continue; diff --git a/net/netfilter/nf_nat_masquerade.c b/net/netfilter/nf_nat_masquerade.c index 1a506b0c6511..a5a23c03fda9 100644 --- a/net/netfilter/nf_nat_masquerade.c +++ b/net/netfilter/nf_nat_masquerade.c @@ -115,7 +115,7 @@ static void nf_nat_masq_schedule(struct net *net, union nf_inet_addr *addr, if (!try_module_get(THIS_MODULE)) goto err_module; - w = kzalloc(sizeof(*w), gfp_flags); + w = kzalloc_obj(*w, gfp_flags); if (w) { /* We can overshoot MAX_MASQ_WORKER_COUNT, no big deal */ atomic_inc(&masq_worker_count); diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 1ed034a47bd0..dacec5f8a11c 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -829,10 +829,14 @@ static void nft_map_catchall_deactivate(const struct nft_ctx *ctx, nft_set_elem_change_active(ctx->net, set, ext); nft_setelem_data_deactivate(ctx->net, set, catchall->elem); - break; } } +/* Use NFT_ITER_UPDATE iterator even if this may be called from the preparation + * phase, the set clone might already exist from a previous command, or it might + * be a set that is going away and does not require a clone. The netns and + * netlink release paths also need to work on the live set. + */ static void nft_map_deactivate(const struct nft_ctx *ctx, struct nft_set *set) { struct nft_set_iter iter = { @@ -1104,7 +1108,7 @@ __printf(2, 3) int nft_request_module(struct net *net, const char *fmt, } } - req = kmalloc(sizeof(*req), GFP_KERNEL); + req = kmalloc_obj(*req); if (!req) return -ENOMEM; @@ -1624,7 +1628,7 @@ static int nf_tables_newtable(struct sk_buff *skb, const struct nfnl_info *info, } err = -ENOMEM; - table = kzalloc(sizeof(*table), GFP_KERNEL_ACCOUNT); + table = kzalloc_obj(*table, GFP_KERNEL_ACCOUNT); if (table == NULL) goto err_kzalloc; @@ -2348,7 +2352,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, struct nft_hook *hook; int err; - hook = kzalloc(sizeof(struct nft_hook), GFP_KERNEL_ACCOUNT); + hook = kzalloc_obj(struct nft_hook, GFP_KERNEL_ACCOUNT); if (!hook) return ERR_PTR(-ENOMEM); @@ -2369,7 +2373,7 @@ static struct nft_hook *nft_netdev_hook_alloc(struct net *net, if (strncmp(dev->name, hook->ifname, hook->ifnamelen)) continue; - ops = kzalloc(sizeof(struct nf_hook_ops), GFP_KERNEL_ACCOUNT); + ops = kzalloc_obj(struct nf_hook_ops, GFP_KERNEL_ACCOUNT); if (!ops) { err = -ENOMEM; goto err_hook_free; @@ -2716,7 +2720,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy, if (err < 0) return err; - basechain = kzalloc(sizeof(*basechain), GFP_KERNEL_ACCOUNT); + basechain = kzalloc_obj(*basechain, GFP_KERNEL_ACCOUNT); if (basechain == NULL) { nft_chain_release_hook(&hook); return -ENOMEM; @@ -2748,7 +2752,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy, if (flags & NFT_CHAIN_HW_OFFLOAD) return -EOPNOTSUPP; - chain = kzalloc(sizeof(*chain), GFP_KERNEL_ACCOUNT); + chain = kzalloc_obj(*chain, GFP_KERNEL_ACCOUNT); if (chain == NULL) return -ENOMEM; @@ -2823,6 +2827,7 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 policy, err_register_hook: nft_chain_del(chain); + synchronize_rcu(); err_chain_add: nft_trans_destroy(trans); err_trans: @@ -3901,23 +3906,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb, return skb->len; } -static int nf_tables_dumpreset_rules(struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); - int ret; - - /* Mutex is held is to prevent that two concurrent dump-and-reset calls - * do not underrun counters and quotas. The commit_mutex is used for - * the lack a better lock, this is not transaction path. - */ - mutex_lock(&nft_net->commit_mutex); - ret = nf_tables_dump_rules(skb, cb); - mutex_unlock(&nft_net->commit_mutex); - - return ret; -} - static int nf_tables_dump_rules_start(struct netlink_callback *cb) { struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; @@ -3937,18 +3925,12 @@ static int nf_tables_dump_rules_start(struct netlink_callback *cb) return -ENOMEM; } } + if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) + ctx->reset = true; + return 0; } -static int nf_tables_dumpreset_rules_start(struct netlink_callback *cb) -{ - struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; - - ctx->reset = true; - - return nf_tables_dump_rules_start(cb); -} - static int nf_tables_dump_rules_done(struct netlink_callback *cb) { struct nft_rule_dump_ctx *ctx = (void *)cb->ctx; @@ -4012,6 +3994,8 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, u32 portid = NETLINK_CB(skb).portid; struct net *net = info->net; struct sk_buff *skb2; + bool reset = false; + char *buf; if (info->nlh->nlmsg_flags & NLM_F_DUMP) { struct netlink_dump_control c = { @@ -4025,46 +4009,15 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); } - skb2 = nf_tables_getrule_single(portid, info, nla, false); + if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETRULE_RESET) + reset = true; + + skb2 = nf_tables_getrule_single(portid, info, nla, reset); if (IS_ERR(skb2)) return PTR_ERR(skb2); - return nfnetlink_unicast(skb2, net, portid); -} - -static int nf_tables_getrule_reset(struct sk_buff *skb, - const struct nfnl_info *info, - const struct nlattr * const nla[]) -{ - struct nftables_pernet *nft_net = nft_pernet(info->net); - u32 portid = NETLINK_CB(skb).portid; - struct net *net = info->net; - struct sk_buff *skb2; - char *buf; - - if (info->nlh->nlmsg_flags & NLM_F_DUMP) { - struct netlink_dump_control c = { - .start= nf_tables_dumpreset_rules_start, - .dump = nf_tables_dumpreset_rules, - .done = nf_tables_dump_rules_done, - .module = THIS_MODULE, - .data = (void *)nla, - }; - - return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); - } - - if (!try_module_get(THIS_MODULE)) - return -EINVAL; - rcu_read_unlock(); - mutex_lock(&nft_net->commit_mutex); - skb2 = nf_tables_getrule_single(portid, info, nla, true); - mutex_unlock(&nft_net->commit_mutex); - rcu_read_lock(); - module_put(THIS_MODULE); - - if (IS_ERR(skb2)) - return PTR_ERR(skb2); + if (!reset) + return nfnetlink_unicast(skb2, net, portid); buf = kasprintf(GFP_ATOMIC, "%.*s:%u", nla_len(nla[NFTA_RULE_TABLE]), @@ -4366,9 +4319,8 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, n = 0; size = 0; if (nla[NFTA_RULE_EXPRESSIONS]) { - expr_info = kvmalloc_array(NFT_RULE_MAXEXPRS, - sizeof(struct nft_expr_info), - GFP_KERNEL); + expr_info = kvmalloc_objs(struct nft_expr_info, + NFT_RULE_MAXEXPRS); if (!expr_info) return -ENOMEM; @@ -5920,7 +5872,6 @@ static void nft_map_catchall_activate(const struct nft_ctx *ctx, nft_clear(ctx->net, ext); nft_setelem_data_activate(ctx->net, set, catchall->elem); - break; } } @@ -6324,6 +6275,10 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) nla_nest_end(skb, nest); nlmsg_end(skb, nlh); + if (dump_ctx->reset && args.iter.count > args.iter.skip) + audit_log_nft_set_reset(table, cb->seq, + args.iter.count - args.iter.skip); + rcu_read_unlock(); if (args.iter.err && args.iter.err != -EMSGSIZE) @@ -6339,26 +6294,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb) return -ENOSPC; } -static int nf_tables_dumpreset_set(struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); - struct nft_set_dump_ctx *dump_ctx = cb->data; - int ret, skip = cb->args[0]; - - mutex_lock(&nft_net->commit_mutex); - - ret = nf_tables_dump_set(skb, cb); - - if (cb->args[0] > skip) - audit_log_nft_set_reset(dump_ctx->ctx.table, cb->seq, - cb->args[0] - skip); - - mutex_unlock(&nft_net->commit_mutex); - - return ret; -} - static int nf_tables_dump_set_start(struct netlink_callback *cb) { struct nft_set_dump_ctx *dump_ctx = cb->data; @@ -6602,8 +6537,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, { struct netlink_ext_ack *extack = info->extack; struct nft_set_dump_ctx dump_ctx; + int rem, err = 0, nelems = 0; + struct net *net = info->net; struct nlattr *attr; - int rem, err = 0; + bool reset = false; + + if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETSETELEM_RESET) + reset = true; if (info->nlh->nlmsg_flags & NLM_F_DUMP) { struct netlink_dump_control c = { @@ -6613,7 +6553,7 @@ static int nf_tables_getsetelem(struct sk_buff *skb, .module = THIS_MODULE, }; - err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false); + err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset); if (err) return err; @@ -6624,75 +6564,21 @@ static int nf_tables_getsetelem(struct sk_buff *skb, if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) return -EINVAL; - err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, false); + err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, reset); if (err) return err; nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { - err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, false); - if (err < 0) { - NL_SET_BAD_ATTR(extack, attr); - break; - } - } - - return err; -} - -static int nf_tables_getsetelem_reset(struct sk_buff *skb, - const struct nfnl_info *info, - const struct nlattr * const nla[]) -{ - struct nftables_pernet *nft_net = nft_pernet(info->net); - struct netlink_ext_ack *extack = info->extack; - struct nft_set_dump_ctx dump_ctx; - int rem, err = 0, nelems = 0; - struct nlattr *attr; - - if (info->nlh->nlmsg_flags & NLM_F_DUMP) { - struct netlink_dump_control c = { - .start = nf_tables_dump_set_start, - .dump = nf_tables_dumpreset_set, - .done = nf_tables_dump_set_done, - .module = THIS_MODULE, - }; - - err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true); - if (err) - return err; - - c.data = &dump_ctx; - return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); - } - - if (!nla[NFTA_SET_ELEM_LIST_ELEMENTS]) - return -EINVAL; - - if (!try_module_get(THIS_MODULE)) - return -EINVAL; - rcu_read_unlock(); - mutex_lock(&nft_net->commit_mutex); - rcu_read_lock(); - - err = nft_set_dump_ctx_init(&dump_ctx, skb, info, nla, true); - if (err) - goto out_unlock; - - nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { - err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, true); + err = nft_get_set_elem(&dump_ctx.ctx, dump_ctx.set, attr, reset); if (err < 0) { NL_SET_BAD_ATTR(extack, attr); break; } nelems++; } - audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(info->net), nelems); - -out_unlock: - rcu_read_unlock(); - mutex_unlock(&nft_net->commit_mutex); - rcu_read_lock(); - module_put(THIS_MODULE); + if (reset) + audit_log_nft_set_reset(dump_ctx.ctx.table, nft_base_seq(net), + nelems); return err; } @@ -7045,7 +6931,7 @@ static int nft_setelem_catchall_insert(const struct net *net, } } - catchall = kmalloc(sizeof(*catchall), GFP_KERNEL_ACCOUNT); + catchall = kmalloc_obj(*catchall, GFP_KERNEL_ACCOUNT); if (!catchall) return -ENOMEM; @@ -7287,6 +7173,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, struct nft_data_desc desc; enum nft_registers dreg; struct nft_trans *trans; + bool set_full = false; u64 expiration; u64 timeout; int err, i; @@ -7578,10 +7465,18 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, if (err < 0) goto err_elem_free; + if (!(flags & NFT_SET_ELEM_CATCHALL)) { + unsigned int max = nft_set_maxsize(set), nelems; + + nelems = atomic_inc_return(&set->nelems); + if (nelems > max) + set_full = true; + } + trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); if (trans == NULL) { err = -ENOMEM; - goto err_elem_free; + goto err_set_size; } ext->genmask = nft_genmask_cur(ctx->net); @@ -7633,7 +7528,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, ue->priv = elem_priv; nft_trans_commit_list_add_elem(ctx->net, trans); - goto err_elem_free; + goto err_set_size; } } } @@ -7651,23 +7546,16 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, goto err_element_clash; } - if (!(flags & NFT_SET_ELEM_CATCHALL)) { - unsigned int max = nft_set_maxsize(set); - - if (!atomic_add_unless(&set->nelems, 1, max)) { - err = -ENFILE; - goto err_set_full; - } - } - nft_trans_container_elem(trans)->elems[0].priv = elem.priv; nft_trans_commit_list_add_elem(ctx->net, trans); - return 0; -err_set_full: - nft_setelem_remove(ctx->net, set, elem.priv); + return set_full ? -ENFILE : 0; + err_element_clash: kfree(trans); +err_set_size: + if (!(flags & NFT_SET_ELEM_CATCHALL)) + atomic_dec(&set->nelems); err_elem_free: nf_tables_set_elem_destroy(ctx, set, elem.priv); err_parse_data: @@ -8018,9 +7906,12 @@ static int nft_set_catchall_flush(const struct nft_ctx *ctx, static int nft_set_flush(struct nft_ctx *ctx, struct nft_set *set, u8 genmask) { + /* The set backend might need to clone the set, do it now from the + * preparation phase, use NFT_ITER_UPDATE_CLONE iterator type. + */ struct nft_set_iter iter = { .genmask = genmask, - .type = NFT_ITER_UPDATE, + .type = NFT_ITER_UPDATE_CLONE, .fn = nft_setelem_flush, }; @@ -8192,7 +8083,7 @@ static struct nft_object *nft_obj_init(const struct nft_ctx *ctx, struct nft_object *obj; int err = -ENOMEM; - tb = kmalloc_array(type->maxattr + 1, sizeof(*tb), GFP_KERNEL); + tb = kmalloc_objs(*tb, type->maxattr + 1); if (!tb) goto err1; @@ -8564,19 +8455,6 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } -static int nf_tables_dumpreset_obj(struct sk_buff *skb, - struct netlink_callback *cb) -{ - struct nftables_pernet *nft_net = nft_pernet(sock_net(skb->sk)); - int ret; - - mutex_lock(&nft_net->commit_mutex); - ret = nf_tables_dump_obj(skb, cb); - mutex_unlock(&nft_net->commit_mutex); - - return ret; -} - static int nf_tables_dump_obj_start(struct netlink_callback *cb) { struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; @@ -8593,18 +8471,12 @@ static int nf_tables_dump_obj_start(struct netlink_callback *cb) if (nla[NFTA_OBJ_TYPE]) ctx->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE])); + if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) + ctx->reset = true; + return 0; } -static int nf_tables_dumpreset_obj_start(struct netlink_callback *cb) -{ - struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; - - ctx->reset = true; - - return nf_tables_dump_obj_start(cb); -} - static int nf_tables_dump_obj_done(struct netlink_callback *cb) { struct nft_obj_dump_ctx *ctx = (void *)cb->ctx; @@ -8665,7 +8537,10 @@ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, const struct nlattr * const nla[]) { u32 portid = NETLINK_CB(skb).portid; + struct net *net = info->net; struct sk_buff *skb2; + bool reset = false; + char *buf; if (info->nlh->nlmsg_flags & NLM_F_DUMP) { struct netlink_dump_control c = { @@ -8679,46 +8554,15 @@ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info, return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); } - skb2 = nf_tables_getobj_single(portid, info, nla, false); + if (NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET) + reset = true; + + skb2 = nf_tables_getobj_single(portid, info, nla, reset); if (IS_ERR(skb2)) return PTR_ERR(skb2); - return nfnetlink_unicast(skb2, info->net, portid); -} - -static int nf_tables_getobj_reset(struct sk_buff *skb, - const struct nfnl_info *info, - const struct nlattr * const nla[]) -{ - struct nftables_pernet *nft_net = nft_pernet(info->net); - u32 portid = NETLINK_CB(skb).portid; - struct net *net = info->net; - struct sk_buff *skb2; - char *buf; - - if (info->nlh->nlmsg_flags & NLM_F_DUMP) { - struct netlink_dump_control c = { - .start = nf_tables_dumpreset_obj_start, - .dump = nf_tables_dumpreset_obj, - .done = nf_tables_dump_obj_done, - .module = THIS_MODULE, - .data = (void *)nla, - }; - - return nft_netlink_dump_start_rcu(info->sk, skb, info->nlh, &c); - } - - if (!try_module_get(THIS_MODULE)) - return -EINVAL; - rcu_read_unlock(); - mutex_lock(&nft_net->commit_mutex); - skb2 = nf_tables_getobj_single(portid, info, nla, true); - mutex_unlock(&nft_net->commit_mutex); - rcu_read_lock(); - module_put(THIS_MODULE); - - if (IS_ERR(skb2)) - return PTR_ERR(skb2); + if (!reset) + return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid); buf = kasprintf(GFP_ATOMIC, "%.*s:%u", nla_len(nla[NFTA_OBJ_TABLE]), @@ -9308,7 +9152,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb, if (!nft_use_inc(&table->use)) return -EMFILE; - flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL_ACCOUNT); + flowtable = kzalloc_obj(*flowtable, GFP_KERNEL_ACCOUNT); if (!flowtable) { err = -ENOMEM; goto flowtable_alloc; @@ -9628,7 +9472,7 @@ static int nf_tables_dump_flowtable_start(struct netlink_callback *cb) struct nft_flowtable_filter *filter = NULL; if (nla[NFTA_FLOWTABLE_TABLE]) { - filter = kzalloc(sizeof(*filter), GFP_ATOMIC); + filter = kzalloc_obj(*filter, GFP_ATOMIC); if (!filter) return -ENOMEM; @@ -9842,11 +9686,11 @@ static int nft_flowtable_event(unsigned long event, struct net_device *dev, break; case NETDEV_REGISTER: /* NOP if not matching or already registered */ - if (!match || (changename && ops)) + if (!match || ops) continue; - ops = kzalloc(sizeof(struct nf_hook_ops), - GFP_KERNEL_ACCOUNT); + ops = kzalloc_obj(struct nf_hook_ops, + GFP_KERNEL_ACCOUNT); if (!ops) return 1; @@ -10037,7 +9881,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_rule_policy, }, [NFT_MSG_GETRULE_RESET] = { - .call = nf_tables_getrule_reset, + .call = nf_tables_getrule, .type = NFNL_CB_RCU, .attr_count = NFTA_RULE_MAX, .policy = nft_rule_policy, @@ -10091,7 +9935,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_set_elem_list_policy, }, [NFT_MSG_GETSETELEM_RESET] = { - .call = nf_tables_getsetelem_reset, + .call = nf_tables_getsetelem, .type = NFNL_CB_RCU, .attr_count = NFTA_SET_ELEM_LIST_MAX, .policy = nft_set_elem_list_policy, @@ -10137,7 +9981,7 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = { .policy = nft_obj_policy, }, [NFT_MSG_GETOBJ_RESET] = { - .call = nf_tables_getobj_reset, + .call = nf_tables_getobj, .type = NFNL_CB_RCU, .attr_count = NFTA_OBJ_MAX, .policy = nft_obj_policy, @@ -10616,7 +10460,7 @@ struct nft_trans_gc *nft_trans_gc_alloc(struct nft_set *set, struct net *net = read_pnet(&set->net); struct nft_trans_gc *trans; - trans = kzalloc(sizeof(*trans), gfp); + trans = kzalloc_obj(*trans, gfp); if (!trans) return NULL; @@ -10647,11 +10491,6 @@ static void nft_trans_gc_queue_work(struct nft_trans_gc *trans) schedule_work(&trans_gc_work); } -static int nft_trans_gc_space(struct nft_trans_gc *trans) -{ - return NFT_TRANS_GC_BATCHCOUNT - trans->count; -} - struct nft_trans_gc *nft_trans_gc_queue_async(struct nft_trans_gc *gc, unsigned int gc_seq, gfp_t gfp) { @@ -10852,7 +10691,7 @@ static int nf_tables_commit_audit_alloc(struct list_head *adl, if (adp->table == table) return 0; } - adp = kzalloc(sizeof(*adp), GFP_KERNEL); + adp = kzalloc_obj(*adp); if (!adp) return -ENOMEM; adp->table = table; diff --git a/net/netfilter/nf_tables_offload.c b/net/netfilter/nf_tables_offload.c index fd30e205de84..9101b1703b52 100644 --- a/net/netfilter/nf_tables_offload.c +++ b/net/netfilter/nf_tables_offload.c @@ -11,7 +11,7 @@ static struct nft_flow_rule *nft_flow_rule_alloc(int num_actions) { struct nft_flow_rule *flow; - flow = kzalloc(sizeof(struct nft_flow_rule), GFP_KERNEL); + flow = kzalloc_obj(struct nft_flow_rule); if (!flow) return NULL; @@ -111,7 +111,7 @@ struct nft_flow_rule *nft_flow_rule_create(struct net *net, expr = nft_expr_first(rule); - ctx = kzalloc(sizeof(struct nft_offload_ctx), GFP_KERNEL); + ctx = kzalloc_obj(struct nft_offload_ctx); if (!ctx) { err = -ENOMEM; goto err_out; diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index 811d02b4c4f7..e62a0dea24ea 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c @@ -325,7 +325,7 @@ static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err, { struct nfnl_err *nfnl_err; - nfnl_err = kmalloc(sizeof(struct nfnl_err), GFP_KERNEL); + nfnl_err = kmalloc_obj(struct nfnl_err); if (nfnl_err == NULL) return -ENOMEM; diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index 505f46a32173..2bfaa773d82f 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c @@ -260,7 +260,7 @@ static int nfnl_acct_start(struct netlink_callback *cb) if (!tb[NFACCT_FILTER_MASK] || !tb[NFACCT_FILTER_VALUE]) return -EINVAL; - filter = kzalloc(sizeof(struct nfacct_filter), GFP_KERNEL); + filter = kzalloc_obj(struct nfacct_filter); if (!filter) return -ENOMEM; diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 97248963a7d3..d545fa459455 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c @@ -192,9 +192,8 @@ nfnl_cthelper_parse_expect_policy(struct nf_conntrack_helper *helper, if (class_max > NF_CT_MAX_EXPECT_CLASSES) return -EOVERFLOW; - expect_policy = kcalloc(class_max, - sizeof(struct nf_conntrack_expect_policy), - GFP_KERNEL); + expect_policy = kzalloc_objs(struct nf_conntrack_expect_policy, + class_max); if (expect_policy == NULL) return -ENOMEM; @@ -228,7 +227,7 @@ nfnl_cthelper_create(const struct nlattr * const tb[], if (!tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_PRIV_DATA_LEN]) return -EINVAL; - nfcth = kzalloc(sizeof(*nfcth), GFP_KERNEL); + nfcth = kzalloc_obj(*nfcth); if (nfcth == NULL) return -ENOMEM; helper = &nfcth->helper; @@ -323,8 +322,7 @@ static int nfnl_cthelper_update_policy_all(struct nlattr *tb[], struct nf_conntrack_expect_policy *policy; int i, ret = 0; - new_policy = kmalloc_array(helper->expect_class_max + 1, - sizeof(*new_policy), GFP_KERNEL); + new_policy = kmalloc_objs(*new_policy, helper->expect_class_max + 1); if (!new_policy) return -ENOMEM; @@ -603,10 +601,10 @@ nfnl_cthelper_dump_table(struct sk_buff *skb, struct netlink_callback *cb) goto out; } } - } - if (cb->args[1]) { - cb->args[1] = 0; - goto restart; + if (cb->args[1]) { + cb->args[1] = 0; + goto restart; + } } out: rcu_read_unlock(); diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 38d75484e531..fd8652aa7e88 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c @@ -74,8 +74,7 @@ ctnl_timeout_parse_policy(void *timeout, struct nlattr **tb; int ret = 0; - tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb), - GFP_KERNEL); + tb = kzalloc_objs(*tb, l4proto->ctnl_timeout.nlattr_max + 1); if (!tb) return -ENOMEM; diff --git a/net/netfilter/nfnetlink_hook.c b/net/netfilter/nfnetlink_hook.c index 92d869317cba..531706982859 100644 --- a/net/netfilter/nfnetlink_hook.c +++ b/net/netfilter/nfnetlink_hook.c @@ -408,7 +408,7 @@ static int nfnl_hook_dump_start(struct netlink_callback *cb) if (head && IS_ERR(head)) return PTR_ERR(head); - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index bfcb9cd335bf..b35a90955e2e 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c @@ -179,7 +179,7 @@ instance_create(struct net *net, u_int16_t group_num, goto out_unlock; } - inst = kzalloc(sizeof(*inst), GFP_ATOMIC); + inst = kzalloc_obj(*inst, GFP_ATOMIC); if (!inst) { err = -ENOMEM; goto out_unlock; diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c index c0fc431991e8..94e3eac5743a 100644 --- a/net/netfilter/nfnetlink_osf.c +++ b/net/netfilter/nfnetlink_osf.c @@ -323,7 +323,7 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, !memchr(f->version, 0, MAXGENRELEN)) return -EINVAL; - kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); + kf = kmalloc_obj(struct nf_osf_finger); if (!kf) return -ENOMEM; diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index f1c8049861a6..47f7f62906e2 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -178,7 +178,7 @@ instance_create(struct nfnl_queue_net *q, u_int16_t queue_num, u32 portid) unsigned int h; int err; - inst = kzalloc(sizeof(*inst), GFP_KERNEL_ACCOUNT); + inst = kzalloc_obj(*inst, GFP_KERNEL_ACCOUNT); if (!inst) return ERR_PTR(-ENOMEM); @@ -1546,8 +1546,10 @@ static int nfqnl_recv_verdict(struct sk_buff *skb, const struct nfnl_info *info, if (entry->state.pf == PF_BRIDGE) { err = nfqa_parse_bridge(entry, nfqa); - if (err < 0) + if (err < 0) { + nfqnl_reinject(entry, NF_DROP); return err; + } } if (nfqa[NFQA_PAYLOAD]) { diff --git a/net/netfilter/nft_chain_filter.c b/net/netfilter/nft_chain_filter.c index b16185e9a6dd..041426e3bdbf 100644 --- a/net/netfilter/nft_chain_filter.c +++ b/net/netfilter/nft_chain_filter.c @@ -344,7 +344,7 @@ static int nft_netdev_event(unsigned long event, struct net_device *dev, break; case NETDEV_REGISTER: /* NOP if not matching or already registered */ - if (!match || (changename && ops)) + if (!match || ops) continue; ops = kmemdup(&basechain->ops, diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 08f620311b03..27cc983a7cdf 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c @@ -815,7 +815,7 @@ nft_match_select_ops(const struct nft_ctx *ctx, goto err; } - ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT); + ops = kzalloc_obj(struct nft_expr_ops, GFP_KERNEL_ACCOUNT); if (!ops) { err = -ENOMEM; goto err; @@ -905,7 +905,7 @@ nft_target_select_ops(const struct nft_ctx *ctx, goto err; } - ops = kzalloc(sizeof(struct nft_expr_ops), GFP_KERNEL_ACCOUNT); + ops = kzalloc_obj(struct nft_expr_ops, GFP_KERNEL_ACCOUNT); if (!ops) { err = -ENOMEM; goto err; diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c index 657764774a2d..43357f99eb00 100644 --- a/net/netfilter/nft_connlimit.c +++ b/net/netfilter/nft_connlimit.c @@ -71,7 +71,7 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx, invert = true; } - priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL_ACCOUNT); + priv->list = kmalloc_obj(*priv->list, GFP_KERNEL_ACCOUNT); if (!priv->list) return -ENOMEM; @@ -220,7 +220,7 @@ static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src, struct nft_connlimit *priv_dst = nft_expr_priv(dst); struct nft_connlimit *priv_src = nft_expr_priv(src); - priv_dst->list = kmalloc(sizeof(*priv_dst->list), gfp); + priv_dst->list = kmalloc_obj(*priv_dst->list, gfp); if (!priv_dst->list) return -ENOMEM; diff --git a/net/netfilter/nft_counter.c b/net/netfilter/nft_counter.c index 0d70325280cc..169ae93688bc 100644 --- a/net/netfilter/nft_counter.c +++ b/net/netfilter/nft_counter.c @@ -32,6 +32,9 @@ struct nft_counter_percpu_priv { static DEFINE_PER_CPU(struct u64_stats_sync, nft_counter_sync); +/* control plane only: sync fetch+reset */ +static DEFINE_SPINLOCK(nft_counter_lock); + static inline void nft_counter_do_eval(struct nft_counter_percpu_priv *priv, struct nft_regs *regs, const struct nft_pktinfo *pkt) @@ -148,13 +151,25 @@ static void nft_counter_fetch(struct nft_counter_percpu_priv *priv, } } +static void nft_counter_fetch_and_reset(struct nft_counter_percpu_priv *priv, + struct nft_counter_tot *total) +{ + spin_lock(&nft_counter_lock); + nft_counter_fetch(priv, total); + nft_counter_reset(priv, total); + spin_unlock(&nft_counter_lock); +} + static int nft_counter_do_dump(struct sk_buff *skb, struct nft_counter_percpu_priv *priv, bool reset) { struct nft_counter_tot total; - nft_counter_fetch(priv, &total); + if (unlikely(reset)) + nft_counter_fetch_and_reset(priv, &total); + else + nft_counter_fetch(priv, &total); if (nla_put_be64(skb, NFTA_COUNTER_BYTES, cpu_to_be64(total.bytes), NFTA_COUNTER_PAD) || @@ -162,9 +177,6 @@ static int nft_counter_do_dump(struct sk_buff *skb, NFTA_COUNTER_PAD)) goto nla_put_failure; - if (reset) - nft_counter_reset(priv, &total); - return 0; nla_put_failure: diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 6f2ae7cad731..47d3ef109a99 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -894,8 +894,7 @@ nft_ct_timeout_parse_policy(void *timeouts, struct nlattr **tb; int ret = 0; - tb = kcalloc(l4proto->ctnl_timeout.nlattr_max + 1, sizeof(*tb), - GFP_KERNEL); + tb = kzalloc_objs(*tb, l4proto->ctnl_timeout.nlattr_max + 1); if (!tb) return -ENOMEM; diff --git a/net/netfilter/nft_last.c b/net/netfilter/nft_last.c index de1b6066bfa8..20706be12807 100644 --- a/net/netfilter/nft_last.c +++ b/net/netfilter/nft_last.c @@ -30,7 +30,7 @@ static int nft_last_init(const struct nft_ctx *ctx, const struct nft_expr *expr, u64 last_jiffies; int err; - last = kzalloc(sizeof(*last), GFP_KERNEL_ACCOUNT); + last = kzalloc_obj(*last, GFP_KERNEL_ACCOUNT); if (!last) return -ENOMEM; @@ -107,7 +107,7 @@ static int nft_last_clone(struct nft_expr *dst, const struct nft_expr *src, gfp_ struct nft_last_priv *priv_dst = nft_expr_priv(dst); struct nft_last_priv *priv_src = nft_expr_priv(src); - priv_dst->last = kzalloc(sizeof(*priv_dst->last), gfp); + priv_dst->last = kzalloc_obj(*priv_dst->last, gfp); if (!priv_dst->last) return -ENOMEM; diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index 21d26b79b460..f3b1f791942b 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -110,7 +110,7 @@ static int nft_limit_init(struct nft_limit_priv *priv, invert = true; } - priv->limit = kmalloc(sizeof(*priv->limit), GFP_KERNEL_ACCOUNT); + priv->limit = kmalloc_obj(*priv->limit, GFP_KERNEL_ACCOUNT); if (!priv->limit) return -ENOMEM; @@ -158,7 +158,7 @@ static int nft_limit_clone(struct nft_limit_priv *priv_dst, priv_dst->burst = priv_src->burst; priv_dst->invert = priv_src->invert; - priv_dst->limit = kmalloc(sizeof(*priv_dst->limit), gfp); + priv_dst->limit = kmalloc_obj(*priv_dst->limit, gfp); if (!priv_dst->limit) return -ENOMEM; diff --git a/net/netfilter/nft_numgen.c b/net/netfilter/nft_numgen.c index bd058babfc82..0a39e51ec9b7 100644 --- a/net/netfilter/nft_numgen.c +++ b/net/netfilter/nft_numgen.c @@ -66,7 +66,7 @@ static int nft_ng_inc_init(const struct nft_ctx *ctx, if (priv->offset + priv->modulus - 1 < priv->offset) return -EOVERFLOW; - priv->counter = kmalloc(sizeof(*priv->counter), GFP_KERNEL_ACCOUNT); + priv->counter = kmalloc_obj(*priv->counter, GFP_KERNEL_ACCOUNT); if (!priv->counter) return -ENOMEM; diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c index df0798da2329..2390a993aed9 100644 --- a/net/netfilter/nft_quota.c +++ b/net/netfilter/nft_quota.c @@ -96,7 +96,7 @@ static int nft_quota_do_init(const struct nlattr * const tb[], return -EOPNOTSUPP; } - priv->consumed = kmalloc(sizeof(*priv->consumed), GFP_KERNEL_ACCOUNT); + priv->consumed = kmalloc_obj(*priv->consumed, GFP_KERNEL_ACCOUNT); if (!priv->consumed) return -ENOMEM; @@ -140,11 +140,16 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, u64 consumed, consumed_cap, quota; u32 flags = priv->flags; - /* Since we inconditionally increment consumed quota for each packet + /* Since we unconditionally increment consumed quota for each packet * that we see, don't go over the quota boundary in what we send to * userspace. */ - consumed = atomic64_read(priv->consumed); + if (reset) { + consumed = atomic64_xchg(priv->consumed, 0); + clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags); + } else { + consumed = atomic64_read(priv->consumed); + } quota = atomic64_read(&priv->quota); if (consumed >= quota) { consumed_cap = quota; @@ -160,10 +165,6 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv, nla_put_be32(skb, NFTA_QUOTA_FLAGS, htonl(flags))) goto nla_put_failure; - if (reset) { - atomic64_sub(consumed, priv->consumed); - clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags); - } return 0; nla_put_failure: @@ -247,7 +248,7 @@ static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src, gfp priv_dst->quota = priv_src->quota; priv_dst->flags = priv_src->flags; - priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), gfp); + priv_dst->consumed = kmalloc_obj(*priv_dst->consumed, gfp); if (!priv_dst->consumed) return -ENOMEM; diff --git a/net/netfilter/nft_set_hash.c b/net/netfilter/nft_set_hash.c index 739b992bde59..b0e571c8e3f3 100644 --- a/net/netfilter/nft_set_hash.c +++ b/net/netfilter/nft_set_hash.c @@ -374,6 +374,7 @@ static void nft_rhash_walk(const struct nft_ctx *ctx, struct nft_set *set, { switch (iter->type) { case NFT_ITER_UPDATE: + case NFT_ITER_UPDATE_CLONE: /* only relevant for netlink dumps which use READ type */ WARN_ON_ONCE(iter->skip != 0); diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c index 18e1903b1d3d..7fd24e0cc428 100644 --- a/net/netfilter/nft_set_pipapo.c +++ b/net/netfilter/nft_set_pipapo.c @@ -652,7 +652,7 @@ static int pipapo_realloc_mt(struct nft_pipapo_field *f, if (rules_alloc > (INT_MAX / sizeof(*new_mt))) return -ENOMEM; - new_mt = kvmalloc_array(rules_alloc, sizeof(*new_mt), GFP_KERNEL_ACCOUNT); + new_mt = kvmalloc_objs(*new_mt, rules_alloc, GFP_KERNEL_ACCOUNT); if (!new_mt) return -ENOMEM; @@ -1413,7 +1413,7 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) struct nft_pipapo_match *new; int i; - new = kmalloc(struct_size(new, f, old->field_count), GFP_KERNEL_ACCOUNT); + new = kmalloc_flex(*new, f, old->field_count, GFP_KERNEL_ACCOUNT); if (!new) return NULL; @@ -1460,9 +1460,8 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) if (src->rules_alloc > (INT_MAX / sizeof(*src->mt))) goto out_mt; - dst->mt = kvmalloc_array(src->rules_alloc, - sizeof(*src->mt), - GFP_KERNEL_ACCOUNT); + dst->mt = kvmalloc_objs(*src->mt, src->rules_alloc, + GFP_KERNEL_ACCOUNT); if (!dst->mt) goto out_mt; @@ -1641,6 +1640,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, int i; nft_pipapo_for_each_field(f, i, m) { + bool last = i == m->field_count - 1; int g; for (g = 0; g < f->groups; g++) { @@ -1660,7 +1660,7 @@ static void pipapo_drop(struct nft_pipapo_match *m, } pipapo_unmap(f->mt, f->rules, rulemap[i].to, rulemap[i].n, - rulemap[i + 1].n, i == m->field_count - 1); + last ? 0 : rulemap[i + 1].n, last); if (pipapo_resize(f, f->rules, f->rules - rulemap[i].n)) { /* We can ignore this, a failure to shrink tables down * doesn't make tables invalid. @@ -1681,11 +1681,11 @@ static void nft_pipapo_gc_deactivate(struct net *net, struct nft_set *set, } /** - * pipapo_gc() - Drop expired entries from set, destroy start and end elements + * pipapo_gc_scan() - Drop expired entries from set and link them to gc list * @set: nftables API set representation * @m: Matching data */ -static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) +static void pipapo_gc_scan(struct nft_set *set, struct nft_pipapo_match *m) { struct nft_pipapo *priv = nft_set_priv(set); struct net *net = read_pnet(&set->net); @@ -1698,6 +1698,8 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) if (!gc) return; + list_add(&gc->list, &priv->gc_head); + while ((rules_f0 = pipapo_rules_same_key(m->f, first_rule))) { union nft_pipapo_map_bucket rulemap[NFT_PIPAPO_MAX_FIELDS]; const struct nft_pipapo_field *f; @@ -1725,9 +1727,13 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) * NFT_SET_ELEM_DEAD_BIT. */ if (__nft_set_elem_expired(&e->ext, tstamp)) { - gc = nft_trans_gc_queue_sync(gc, GFP_KERNEL); - if (!gc) - return; + if (!nft_trans_gc_space(gc)) { + gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); + if (!gc) + return; + + list_add(&gc->list, &priv->gc_head); + } nft_pipapo_gc_deactivate(net, set, e); pipapo_drop(m, rulemap); @@ -1741,10 +1747,30 @@ static void pipapo_gc(struct nft_set *set, struct nft_pipapo_match *m) } } - gc = nft_trans_gc_catchall_sync(gc); + priv->last_gc = jiffies; +} + +/** + * pipapo_gc_queue() - Free expired elements + * @set: nftables API set representation + */ +static void pipapo_gc_queue(struct nft_set *set) +{ + struct nft_pipapo *priv = nft_set_priv(set); + struct nft_trans_gc *gc, *next; + + /* always do a catchall cycle: */ + gc = nft_trans_gc_alloc(set, 0, GFP_KERNEL); if (gc) { + gc = nft_trans_gc_catchall_sync(gc); + if (gc) + nft_trans_gc_queue_sync_done(gc); + } + + /* always purge queued gc elements. */ + list_for_each_entry_safe(gc, next, &priv->gc_head, list) { + list_del(&gc->list); nft_trans_gc_queue_sync_done(gc); - priv->last_gc = jiffies; } } @@ -1798,6 +1824,10 @@ static void pipapo_reclaim_match(struct rcu_head *rcu) * * We also need to create a new working copy for subsequent insertions and * deletions. + * + * After the live copy has been replaced by the clone, we can safely queue + * expired elements that have been collected by pipapo_gc_scan() for + * memory reclaim. */ static void nft_pipapo_commit(struct nft_set *set) { @@ -1808,7 +1838,7 @@ static void nft_pipapo_commit(struct nft_set *set) return; if (time_after_eq(jiffies, priv->last_gc + nft_set_gc_interval(set))) - pipapo_gc(set, priv->clone); + pipapo_gc_scan(set, priv->clone); old = rcu_replace_pointer(priv->match, priv->clone, nft_pipapo_transaction_mutex_held(set)); @@ -1816,6 +1846,8 @@ static void nft_pipapo_commit(struct nft_set *set) if (old) call_rcu(&old->rcu, pipapo_reclaim_match); + + pipapo_gc_queue(set); } static void nft_pipapo_abort(const struct nft_set *set) @@ -2145,13 +2177,20 @@ static void nft_pipapo_walk(const struct nft_ctx *ctx, struct nft_set *set, const struct nft_pipapo_match *m; switch (iter->type) { - case NFT_ITER_UPDATE: + case NFT_ITER_UPDATE_CLONE: m = pipapo_maybe_clone(set); if (!m) { iter->err = -ENOMEM; return; } - + nft_pipapo_do_walk(ctx, set, m, iter); + break; + case NFT_ITER_UPDATE: + if (priv->clone) + m = priv->clone; + else + m = rcu_dereference_protected(priv->match, + nft_pipapo_transaction_mutex_held(set)); nft_pipapo_do_walk(ctx, set, m, iter); break; case NFT_ITER_READ: @@ -2237,7 +2276,7 @@ static int nft_pipapo_init(const struct nft_set *set, if (field_count > NFT_PIPAPO_MAX_FIELDS) return -EINVAL; - m = kmalloc(struct_size(m, f, field_count), GFP_KERNEL); + m = kmalloc_flex(*m, f, field_count); if (!m) return -ENOMEM; @@ -2273,6 +2312,7 @@ static int nft_pipapo_init(const struct nft_set *set, f->mt = NULL; } + INIT_LIST_HEAD(&priv->gc_head); rcu_assign_pointer(priv->match, m); return 0; @@ -2322,6 +2362,8 @@ static void nft_pipapo_destroy(const struct nft_ctx *ctx, struct nft_pipapo *priv = nft_set_priv(set); struct nft_pipapo_match *m; + WARN_ON_ONCE(!list_empty(&priv->gc_head)); + m = rcu_dereference_protected(priv->match, true); if (priv->clone) { diff --git a/net/netfilter/nft_set_pipapo.h b/net/netfilter/nft_set_pipapo.h index eaab422aa56a..9aee9a9eaeb7 100644 --- a/net/netfilter/nft_set_pipapo.h +++ b/net/netfilter/nft_set_pipapo.h @@ -156,12 +156,14 @@ struct nft_pipapo_match { * @clone: Copy where pending insertions and deletions are kept * @width: Total bytes to be matched for one packet, including padding * @last_gc: Timestamp of last garbage collection run, jiffies + * @gc_head: list of nft_trans_gc to queue up for mem reclaim */ struct nft_pipapo { struct nft_pipapo_match __rcu *match; struct nft_pipapo_match *clone; int width; unsigned long last_gc; + struct list_head gc_head; }; struct nft_pipapo_elem; diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index 644d4b916705..ee3d4f5b9ff7 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c @@ -586,8 +586,8 @@ static int nft_array_intervals_alloc(struct nft_array *array, u32 max_intervals) { struct nft_array_interval *intervals; - intervals = kvcalloc(max_intervals, sizeof(struct nft_array_interval), - GFP_KERNEL_ACCOUNT); + intervals = kvzalloc_objs(struct nft_array_interval, max_intervals, + GFP_KERNEL_ACCOUNT); if (!intervals) return -ENOMEM; @@ -604,7 +604,7 @@ static struct nft_array *nft_array_alloc(u32 max_intervals) { struct nft_array *array; - array = kzalloc(sizeof(*array), GFP_KERNEL_ACCOUNT); + array = kzalloc_obj(*array, GFP_KERNEL_ACCOUNT); if (!array) return NULL; @@ -861,13 +861,15 @@ static void nft_rbtree_walk(const struct nft_ctx *ctx, struct nft_rbtree *priv = nft_set_priv(set); switch (iter->type) { - case NFT_ITER_UPDATE: - lockdep_assert_held(&nft_pernet(ctx->net)->commit_mutex); - + case NFT_ITER_UPDATE_CLONE: if (nft_array_may_resize(set) < 0) { iter->err = -ENOMEM; break; } + fallthrough; + case NFT_ITER_UPDATE: + lockdep_assert_held(&nft_pernet(ctx->net)->commit_mutex); + nft_rbtree_do_walk(ctx, set, iter); break; case NFT_ITER_READ: diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 48105ea3df15..e594b3b7ad82 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -1742,7 +1742,7 @@ xt_hook_ops_alloc(const struct xt_table *table, nf_hookfn *fn) if (!num_hooks) return ERR_PTR(-EINVAL); - ops = kcalloc(num_hooks, sizeof(*ops), GFP_KERNEL); + ops = kzalloc_objs(*ops, num_hooks); if (ops == NULL) return ERR_PTR(-ENOMEM); @@ -1775,7 +1775,7 @@ int xt_register_template(const struct xt_table *table, } ret = -ENOMEM; - t = kzalloc(sizeof(*t), GFP_KERNEL); + t = kzalloc_obj(*t); if (!t) goto out_unlock; @@ -1993,7 +1993,7 @@ static int __init xt_init(void) } } - xt = kcalloc(NFPROTO_NUMPROTO, sizeof(struct xt_af), GFP_KERNEL); + xt = kzalloc_objs(struct xt_af, NFPROTO_NUMPROTO); if (!xt) return -ENOMEM; diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index d73957592c9d..517106165ad2 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -135,7 +135,7 @@ static int idletimer_tg_create(struct idletimer_tg_info *info) { int ret; - info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = kzalloc_obj(*info->timer); if (!info->timer) { ret = -ENOMEM; goto out; @@ -184,7 +184,7 @@ static int idletimer_tg_create_v1(struct idletimer_tg_info_v1 *info) { int ret; - info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL); + info->timer = kmalloc_obj(*info->timer); if (!info->timer) { ret = -ENOMEM; goto out; @@ -318,6 +318,12 @@ static int idletimer_tg_checkentry(const struct xt_tgchk_param *par) info->timer = __idletimer_tg_find_by_label(info->label); if (info->timer) { + if (info->timer->timer_type & XT_IDLETIMER_ALARM) { + pr_debug("Adding/Replacing rule with same label and different timer type is not allowed\n"); + mutex_unlock(&list_mutex); + return -EINVAL; + } + info->timer->refcnt++; mod_timer(&info->timer->timer, secs_to_jiffies(info->timeout) + jiffies); diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c index 90dcf088071a..caaaf4d2c584 100644 --- a/net/netfilter/xt_LED.c +++ b/net/netfilter/xt_LED.c @@ -111,7 +111,7 @@ static int led_tg_check(const struct xt_tgchk_param *par) } err = -ENOMEM; - ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL); + ledinternal = kzalloc_obj(struct xt_led_info_internal); if (!ledinternal) goto exit_mutex_only; diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 4f49cfc27831..91270d467ffd 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c @@ -139,7 +139,7 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) } ret = -ENOMEM; - est = kzalloc(sizeof(*est), GFP_KERNEL); + est = kzalloc_obj(*est); if (!est) goto err1; diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c index a5ebd5640457..5d34ceb893ed 100644 --- a/net/netfilter/xt_TEE.c +++ b/net/netfilter/xt_TEE.c @@ -106,7 +106,7 @@ static int tee_tg_check(const struct xt_tgchk_param *par) if (info->oif[sizeof(info->oif)-1] != '\0') return -EINVAL; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return -ENOMEM; diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c index e5a13ecbe67a..037ab93e25d0 100644 --- a/net/netfilter/xt_dccp.c +++ b/net/netfilter/xt_dccp.c @@ -62,10 +62,10 @@ dccp_find_option(u_int8_t option, return true; } - if (op[i] < 2) + if (op[i] < 2 || i == optlen - 1) i++; else - i += op[i+1]?:1; + i += op[i + 1] ? : 1; } spin_unlock_bh(&dccp_buflock); diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c index 3b507694e81e..3bd127bfc114 100644 --- a/net/netfilter/xt_hashlimit.c +++ b/net/netfilter/xt_hashlimit.c @@ -293,7 +293,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg, if (size < 16) size = 16; } - hinfo = kvmalloc(struct_size(hinfo, hash, size), GFP_KERNEL); + hinfo = kvmalloc_flex(*hinfo, hash, size); if (hinfo == NULL) return -ENOMEM; *out_hinfo = hinfo; diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 8b4fd27857f2..87d74da14c0b 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c @@ -115,7 +115,7 @@ static int limit_mt_check(const struct xt_mtchk_param *par) return -ERANGE; } - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (priv == NULL) return -ENOMEM; diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c index 4452cc93b990..b05c5c8dac78 100644 --- a/net/netfilter/xt_quota.c +++ b/net/netfilter/xt_quota.c @@ -50,7 +50,7 @@ static int quota_mt_check(const struct xt_mtchk_param *par) if (q->flags & ~XT_QUOTA_MASK) return -EINVAL; - q->master = kmalloc(sizeof(*q->master), GFP_KERNEL); + q->master = kmalloc_obj(*q->master); if (q->master == NULL) return -ENOMEM; diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 588a5e6ad899..f72752fa4374 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c @@ -188,7 +188,7 @@ recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr, } nstamps_max += 1; - e = kmalloc(struct_size(e, stamps, nstamps_max), GFP_ATOMIC); + e = kmalloc_flex(*e, stamps, nstamps_max, GFP_ATOMIC); if (e == NULL) return NULL; memcpy(&e->addr, addr, sizeof(e->addr)); @@ -391,7 +391,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, goto out; } - t = kvzalloc(struct_size(t, iphash, ip_list_hash_size), GFP_KERNEL); + t = kvzalloc_flex(*t, iphash, ip_list_hash_size); if (t == NULL) { ret = -ENOMEM; goto out; diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c index b26c1dcfc27b..334e09771abf 100644 --- a/net/netfilter/xt_statistic.c +++ b/net/netfilter/xt_statistic.c @@ -58,7 +58,7 @@ static int statistic_mt_check(const struct xt_mtchk_param *par) info->flags & ~XT_STATISTIC_MASK) return -EINVAL; - info->master = kzalloc(sizeof(*info->master), GFP_KERNEL); + info->master = kzalloc_obj(*info->master); if (info->master == NULL) return -ENOMEM; atomic_set(&info->master->count, info->u.nth.count); diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c index e8991130a3de..f76cf18f1a24 100644 --- a/net/netfilter/xt_tcpudp.c +++ b/net/netfilter/xt_tcpudp.c @@ -59,8 +59,10 @@ tcp_find_option(u_int8_t option, for (i = 0; i < optlen; ) { if (op[i] == option) return !invert; - if (op[i] < 2) i++; - else i += op[i+1]?:1; + if (op[i] < 2 || i == optlen - 1) + i++; + else + i += op[i + 1] ? : 1; } return invert; diff --git a/net/netlabel/netlabel_calipso.c b/net/netlabel/netlabel_calipso.c index a07c2216d28b..e1efd888b4a2 100644 --- a/net/netlabel/netlabel_calipso.c +++ b/net/netlabel/netlabel_calipso.c @@ -95,7 +95,7 @@ static int netlbl_calipso_add_pass(struct genl_info *info, int ret_val; struct calipso_doi *doi_def = NULL; - doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL); + doi_def = kmalloc_obj(*doi_def); if (!doi_def) return -ENOMEM; doi_def->type = CALIPSO_MAP_PASS; diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index fa08ee75ac06..b080e666523f 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c @@ -139,10 +139,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info, NULL) != 0) return -EINVAL; - doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL); + doi_def = kmalloc_obj(*doi_def); if (doi_def == NULL) return -ENOMEM; - doi_def->map.std = kzalloc(sizeof(*doi_def->map.std), GFP_KERNEL); + doi_def->map.std = kzalloc_obj(*doi_def->map.std); if (doi_def->map.std == NULL) { kfree(doi_def); return -ENOMEM; @@ -332,7 +332,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info, if (!info->attrs[NLBL_CIPSOV4_A_TAGLST]) return -EINVAL; - doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL); + doi_def = kmalloc_obj(*doi_def); if (doi_def == NULL) return -ENOMEM; doi_def->type = CIPSO_V4_MAP_PASS; @@ -371,7 +371,7 @@ static int netlbl_cipsov4_add_local(struct genl_info *info, if (!info->attrs[NLBL_CIPSOV4_A_TAGLST]) return -EINVAL; - doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL); + doi_def = kmalloc_obj(*doi_def); if (doi_def == NULL) return -ENOMEM; doi_def->type = CIPSO_V4_MAP_LOCAL; diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index 8158a25972b4..3fe31648ba2d 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c @@ -367,13 +367,11 @@ int __init netlbl_domhsh_init(u32 size) if (size == 0) return -EINVAL; - hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL); + hsh_tbl = kmalloc_obj(*hsh_tbl); if (hsh_tbl == NULL) return -ENOMEM; hsh_tbl->size = 1 << size; - hsh_tbl->tbl = kcalloc(hsh_tbl->size, - sizeof(struct list_head), - GFP_KERNEL); + hsh_tbl->tbl = kzalloc_objs(struct list_head, hsh_tbl->size); if (hsh_tbl->tbl == NULL) { kfree(hsh_tbl); return -ENOMEM; @@ -453,7 +451,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ret_val = -EINVAL; goto add_return; } - entry_b = kzalloc(sizeof(*entry_b), GFP_ATOMIC); + entry_b = kzalloc_obj(*entry_b, GFP_ATOMIC); if (entry_b == NULL) { ret_val = -ENOMEM; goto add_return; diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 33b77084a4e5..3583fa63dd01 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c @@ -104,7 +104,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, struct netlbl_domaddr4_map *map4 = NULL; struct netlbl_domaddr6_map *map6 = NULL; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (entry == NULL) return -ENOMEM; if (domain != NULL) { @@ -117,7 +117,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, if (addr == NULL && mask == NULL) entry->def.type = NETLBL_NLTYPE_UNLABELED; else if (addr != NULL && mask != NULL) { - addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); + addrmap = kzalloc_obj(*addrmap, GFP_ATOMIC); if (addrmap == NULL) goto cfg_unlbl_map_add_failure; INIT_LIST_HEAD(&addrmap->list4); @@ -127,7 +127,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, case AF_INET: { const struct in_addr *addr4 = addr; const struct in_addr *mask4 = mask; - map4 = kzalloc(sizeof(*map4), GFP_ATOMIC); + map4 = kzalloc_obj(*map4, GFP_ATOMIC); if (map4 == NULL) goto cfg_unlbl_map_add_failure; map4->def.type = NETLBL_NLTYPE_UNLABELED; @@ -144,7 +144,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, case AF_INET6: { const struct in6_addr *addr6 = addr; const struct in6_addr *mask6 = mask; - map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); + map6 = kzalloc_obj(*map6, GFP_ATOMIC); if (map6 == NULL) goto cfg_unlbl_map_add_failure; map6->def.type = NETLBL_NLTYPE_UNLABELED; @@ -336,7 +336,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, if (doi_def == NULL) return -ENOENT; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (entry == NULL) goto out_entry; entry->family = AF_INET; @@ -350,13 +350,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, entry->def.cipso = doi_def; entry->def.type = NETLBL_NLTYPE_CIPSOV4; } else if (addr != NULL && mask != NULL) { - addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); + addrmap = kzalloc_obj(*addrmap, GFP_ATOMIC); if (addrmap == NULL) goto out_addrmap; INIT_LIST_HEAD(&addrmap->list4); INIT_LIST_HEAD(&addrmap->list6); - addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); + addrinfo = kzalloc_obj(*addrinfo, GFP_ATOMIC); if (addrinfo == NULL) goto out_addrinfo; addrinfo->def.cipso = doi_def; @@ -462,7 +462,7 @@ int netlbl_cfg_calipso_map_add(u32 doi, if (doi_def == NULL) return -ENOENT; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (entry == NULL) goto out_entry; entry->family = AF_INET6; @@ -476,13 +476,13 @@ int netlbl_cfg_calipso_map_add(u32 doi, entry->def.calipso = doi_def; entry->def.type = NETLBL_NLTYPE_CALIPSO; } else if (addr != NULL && mask != NULL) { - addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); + addrmap = kzalloc_obj(*addrmap, GFP_ATOMIC); if (addrmap == NULL) goto out_addrmap; INIT_LIST_HEAD(&addrmap->list4); INIT_LIST_HEAD(&addrmap->list6); - addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); + addrinfo = kzalloc_obj(*addrinfo, GFP_ATOMIC); if (addrinfo == NULL) goto out_addrinfo; addrinfo->def.calipso = doi_def; diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 079fe72a6384..3e89c3b3a1a4 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c @@ -84,7 +84,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, struct calipso_doi *calipso = NULL; #endif u32 tmp_val; - struct netlbl_dom_map *entry = kzalloc(sizeof(*entry), GFP_KERNEL); + struct netlbl_dom_map *entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; @@ -148,7 +148,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, struct in_addr *mask; struct netlbl_domaddr4_map *map; - addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL); + addrmap = kzalloc_obj(*addrmap); if (addrmap == NULL) { ret_val = -ENOMEM; goto add_doi_put_def; @@ -169,7 +169,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, addr = nla_data(info->attrs[NLBL_MGMT_A_IPV4ADDR]); mask = nla_data(info->attrs[NLBL_MGMT_A_IPV4MASK]); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { ret_val = -ENOMEM; goto add_free_addrmap; @@ -195,7 +195,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, struct in6_addr *mask; struct netlbl_domaddr6_map *map; - addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL); + addrmap = kzalloc_obj(*addrmap); if (addrmap == NULL) { ret_val = -ENOMEM; goto add_doi_put_def; @@ -216,7 +216,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, addr = nla_data(info->attrs[NLBL_MGMT_A_IPV6ADDR]); mask = nla_data(info->attrs[NLBL_MGMT_A_IPV6MASK]); - map = kzalloc(sizeof(*map), GFP_KERNEL); + map = kzalloc_obj(*map); if (map == NULL) { ret_val = -ENOMEM; goto add_free_addrmap; diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index dfda9ea61971..ca7a9e2a3de7 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c @@ -236,7 +236,7 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface, int ret_val; struct netlbl_unlhsh_addr4 *entry; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (entry == NULL) return -ENOMEM; @@ -276,7 +276,7 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface, int ret_val; struct netlbl_unlhsh_addr6 *entry; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (entry == NULL) return -ENOMEM; @@ -314,7 +314,7 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) u32 bkt; struct netlbl_unlhsh_iface *iface; - iface = kzalloc(sizeof(*iface), GFP_ATOMIC); + iface = kzalloc_obj(*iface, GFP_ATOMIC); if (iface == NULL) return NULL; @@ -1413,13 +1413,11 @@ int __init netlbl_unlabel_init(u32 size) if (size == 0) return -EINVAL; - hsh_tbl = kmalloc(sizeof(*hsh_tbl), GFP_KERNEL); + hsh_tbl = kmalloc_obj(*hsh_tbl); if (hsh_tbl == NULL) return -ENOMEM; hsh_tbl->size = 1 << size; - hsh_tbl->tbl = kcalloc(hsh_tbl->size, - sizeof(struct list_head), - GFP_KERNEL); + hsh_tbl->tbl = kzalloc_objs(struct list_head, hsh_tbl->size); if (hsh_tbl->tbl == NULL) { kfree(hsh_tbl); return -ENOMEM; @@ -1534,7 +1532,7 @@ int __init netlbl_unlabel_defconf(void) audit_info.loginuid = GLOBAL_ROOT_UID; audit_info.sessionid = 0; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (entry == NULL) return -ENOMEM; entry->family = AF_UNSPEC; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 8e5151f0c6e4..4d609d5cf406 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2927,7 +2927,7 @@ static int __init netlink_proto_init(void) BUILD_BUG_ON(sizeof(struct netlink_skb_parms) > sizeof_field(struct sk_buff, cb)); - nl_table = kcalloc(MAX_LINKS, sizeof(*nl_table), GFP_KERNEL); + nl_table = kzalloc_objs(*nl_table, MAX_LINKS); if (!nl_table) goto panic; diff --git a/net/netlink/diag.c b/net/netlink/diag.c index b8e58132e8af..1dfc340736b8 100644 --- a/net/netlink/diag.c +++ b/net/netlink/diag.c @@ -107,7 +107,7 @@ static int __netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb, num--; if (!hti) { - hti = kmalloc(sizeof(*hti), GFP_KERNEL); + hti = kmalloc_obj(*hti); if (!hti) return -ENOMEM; diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index 978c129c6095..a23d4c51c089 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -659,7 +659,7 @@ static int genl_sk_privs_alloc(struct genl_family *family) if (!family->sock_priv_size) return 0; - family->sock_privs = kzalloc(sizeof(*family->sock_privs), GFP_KERNEL); + family->sock_privs = kzalloc_obj(*family->sock_privs); if (!family->sock_privs) return -ENOMEM; xa_init(family->sock_privs); @@ -912,7 +912,7 @@ EXPORT_SYMBOL(genlmsg_put); static struct genl_dumpit_info *genl_dumpit_info_alloc(void) { - return kmalloc(sizeof(struct genl_dumpit_info), GFP_KERNEL); + return kmalloc_obj(struct genl_dumpit_info); } static void genl_dumpit_info_free(const struct genl_dumpit_info *info) @@ -937,8 +937,7 @@ genl_family_rcv_msg_attrs_parse(const struct genl_family *family, if (!ops->maxattr) return NULL; - attrbuf = kmalloc_array(ops->maxattr + 1, - sizeof(struct nlattr *), GFP_KERNEL); + attrbuf = kmalloc_objs(struct nlattr *, ops->maxattr + 1); if (!attrbuf) return ERR_PTR(-ENOMEM); @@ -1591,7 +1590,7 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb) return 0; } - ctx->op_iter = kmalloc(sizeof(*ctx->op_iter), GFP_KERNEL); + ctx->op_iter = kmalloc_obj(*ctx->op_iter); if (!ctx->op_iter) return -ENOMEM; diff --git a/net/netlink/policy.c b/net/netlink/policy.c index 99458da6be32..f39cd7cc4fb5 100644 --- a/net/netlink/policy.c +++ b/net/netlink/policy.c @@ -102,8 +102,7 @@ static struct netlink_policy_dump_state *alloc_state(void) { struct netlink_policy_dump_state *state; - state = kzalloc(struct_size(state, policies, INITIAL_POLICIES_ALLOC), - GFP_KERNEL); + state = kzalloc_flex(*state, policies, INITIAL_POLICIES_ALLOC); if (!state) return ERR_PTR(-ENOMEM); state->n_alloc = INITIAL_POLICIES_ALLOC; diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 5ed1a71ceec1..b816c56124ab 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -1401,7 +1401,7 @@ static int __init nr_proto_init(void) goto unregister_proto; } - dev_nr = kcalloc(nr_ndevs, sizeof(struct net_device *), GFP_KERNEL); + dev_nr = kzalloc_objs(struct net_device *, nr_ndevs); if (!dev_nr) { pr_err("NET/ROM: %s - unable to allocate device array\n", __func__); diff --git a/net/nfc/core.c b/net/nfc/core.c index f50e5bab35d8..a92a6566e6a0 100644 --- a/net/nfc/core.c +++ b/net/nfc/core.c @@ -879,7 +879,7 @@ int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type) if (se) return -EALREADY; - se = kzalloc(sizeof(struct nfc_se), GFP_KERNEL); + se = kzalloc_obj(struct nfc_se); if (!se) return -ENOMEM; @@ -1062,7 +1062,7 @@ struct nfc_dev *nfc_allocate_device(const struct nfc_ops *ops, if (!supported_protocols) return NULL; - dev = kzalloc(sizeof(struct nfc_dev), GFP_KERNEL); + dev = kzalloc_obj(struct nfc_dev); if (!dev) return NULL; diff --git a/net/nfc/digital_core.c b/net/nfc/digital_core.c index dae378f1d52b..7cb1e6aaae90 100644 --- a/net/nfc/digital_core.c +++ b/net/nfc/digital_core.c @@ -231,7 +231,7 @@ int digital_send_cmd(struct nfc_digital_dev *ddev, u8 cmd_type, { struct digital_cmd *cmd; - cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); + cmd = kzalloc_obj(*cmd); if (!cmd) return -ENOMEM; @@ -279,7 +279,7 @@ static int digital_tg_listen_mdaa(struct nfc_digital_dev *ddev, u8 rf_tech) struct digital_tg_mdaa_params *params; int rc; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -706,9 +706,11 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, struct digital_data_exch *data_exch; int rc; - data_exch = kzalloc(sizeof(*data_exch), GFP_KERNEL); - if (!data_exch) + data_exch = kzalloc_obj(*data_exch); + if (!data_exch) { + kfree_skb(skb); return -ENOMEM; + } data_exch->cb = cb; data_exch->cb_context = cb_context; @@ -731,8 +733,10 @@ static int digital_in_send(struct nfc_dev *nfc_dev, struct nfc_target *target, data_exch); exit: - if (rc) + if (rc) { + kfree_skb(skb); kfree(data_exch); + } return rc; } @@ -762,7 +766,7 @@ struct nfc_digital_dev *nfc_digital_allocate_device(const struct nfc_digital_ops !ops->switch_rf || (ops->tg_listen_md && !ops->tg_get_rf_tech)) return NULL; - ddev = kzalloc(sizeof(*ddev), GFP_KERNEL); + ddev = kzalloc_obj(*ddev); if (!ddev) return NULL; diff --git a/net/nfc/digital_technology.c b/net/nfc/digital_technology.c index 3adf4589852a..63f1b721c71d 100644 --- a/net/nfc/digital_technology.c +++ b/net/nfc/digital_technology.c @@ -490,7 +490,7 @@ static void digital_in_recv_sens_res(struct nfc_digital_dev *ddev, void *arg, goto exit; } - target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); + target = kzalloc_obj(struct nfc_target); if (!target) { rc = -ENOMEM; goto exit; @@ -688,7 +688,7 @@ static void digital_in_recv_sensb_res(struct nfc_digital_dev *ddev, void *arg, else ddev->target_fsc = digital_ats_fsc[fsci]; - target = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); + target = kzalloc_obj(struct nfc_target); if (!target) { rc = -ENOMEM; goto exit; @@ -863,7 +863,7 @@ static void digital_in_recv_iso15693_inv_res(struct nfc_digital_dev *ddev, goto out_free_skb; } - target = kzalloc(sizeof(*target), GFP_KERNEL); + target = kzalloc_obj(*target); if (!target) { rc = -ENOMEM; goto out_free_skb; diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 8618d57c23da..0d33c81a15fe 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c @@ -291,7 +291,7 @@ int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) pr_debug("from gate %d\n", gate); - targets = kzalloc(sizeof(struct nfc_target), GFP_KERNEL); + targets = kzalloc_obj(struct nfc_target); if (targets == NULL) return -ENOMEM; @@ -964,7 +964,7 @@ struct nfc_hci_dev *nfc_hci_allocate_device(const struct nfc_hci_ops *ops, if (protocols == 0) return NULL; - hdev = kzalloc(sizeof(struct nfc_hci_dev), GFP_KERNEL); + hdev = kzalloc_obj(struct nfc_hci_dev); if (hdev == NULL) return NULL; diff --git a/net/nfc/hci/hcp.c b/net/nfc/hci/hcp.c index 4902f5064098..4d19c697d6ec 100644 --- a/net/nfc/hci/hcp.c +++ b/net/nfc/hci/hcp.c @@ -30,7 +30,7 @@ int nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe, int hci_len, err; bool firstfrag = true; - cmd = kzalloc(sizeof(struct hci_msg), GFP_KERNEL); + cmd = kzalloc_obj(struct hci_msg); if (cmd == NULL) return -ENOMEM; diff --git a/net/nfc/hci/llc.c b/net/nfc/hci/llc.c index e6cf4eb06b46..51dfa0d5dfa2 100644 --- a/net/nfc/hci/llc.c +++ b/net/nfc/hci/llc.c @@ -49,7 +49,7 @@ int nfc_llc_register(const char *name, const struct nfc_llc_ops *ops) { struct nfc_llc_engine *llc_engine; - llc_engine = kzalloc(sizeof(struct nfc_llc_engine), GFP_KERNEL); + llc_engine = kzalloc_obj(struct nfc_llc_engine); if (llc_engine == NULL) return -ENOMEM; @@ -90,7 +90,7 @@ struct nfc_llc *nfc_llc_allocate(const char *name, struct nfc_hci_dev *hdev, if (llc_engine == NULL) return NULL; - llc = kzalloc(sizeof(struct nfc_llc), GFP_KERNEL); + llc = kzalloc_obj(struct nfc_llc); if (llc == NULL) return NULL; diff --git a/net/nfc/hci/llc_nop.c b/net/nfc/hci/llc_nop.c index a58716f16954..f9c826a138e5 100644 --- a/net/nfc/hci/llc_nop.c +++ b/net/nfc/hci/llc_nop.c @@ -28,7 +28,7 @@ static void *llc_nop_init(struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv, *rx_headroom = 0; *rx_tailroom = 0; - llc_nop = kzalloc(sizeof(struct llc_nop), GFP_KERNEL); + llc_nop = kzalloc_obj(struct llc_nop); if (llc_nop == NULL) return NULL; diff --git a/net/nfc/hci/llc_shdlc.c b/net/nfc/hci/llc_shdlc.c index 08c8aa1530d8..6819695d993c 100644 --- a/net/nfc/hci/llc_shdlc.c +++ b/net/nfc/hci/llc_shdlc.c @@ -728,7 +728,7 @@ static void *llc_shdlc_init(struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv, *rx_headroom = SHDLC_LLC_HEAD_ROOM; *rx_tailroom = 0; - shdlc = kzalloc(sizeof(struct llc_shdlc), GFP_KERNEL); + shdlc = kzalloc_obj(struct llc_shdlc); if (shdlc == NULL) return NULL; diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index b652323bc2c1..291f26facbf3 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c @@ -108,7 +108,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdres_tlv(u8 tid, u8 sap) struct nfc_llcp_sdp_tlv *sdres; u8 value[2]; - sdres = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL); + sdres = kzalloc_obj(struct nfc_llcp_sdp_tlv); if (sdres == NULL) return NULL; @@ -141,7 +141,7 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, const char *uri, if (WARN_ON_ONCE(uri_len > U8_MAX - 4)) return NULL; - sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL); + sdreq = kzalloc_obj(struct nfc_llcp_sdp_tlv); if (sdreq == NULL) return NULL; diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index 444a3774c8e8..366d7566308c 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c @@ -1621,7 +1621,7 @@ int nfc_llcp_register_device(struct nfc_dev *ndev) { struct nfc_llcp_local *local; - local = kzalloc(sizeof(struct nfc_llcp_local), GFP_KERNEL); + local = kzalloc_obj(struct nfc_llcp_local); if (local == NULL) return -ENOMEM; diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index e419e020a70a..43d871525dbc 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c @@ -567,6 +567,10 @@ static int nci_close_device(struct nci_dev *ndev) flush_workqueue(ndev->cmd_wq); timer_delete_sync(&ndev->cmd_timer); timer_delete_sync(&ndev->data_timer); + if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) + nci_data_exchange_complete(ndev, NULL, + ndev->cur_conn_id, + -ENODEV); mutex_unlock(&ndev->req_lock); return 0; } @@ -598,6 +602,11 @@ static int nci_close_device(struct nci_dev *ndev) flush_workqueue(ndev->cmd_wq); timer_delete_sync(&ndev->cmd_timer); + timer_delete_sync(&ndev->data_timer); + + if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags)) + nci_data_exchange_complete(ndev, NULL, ndev->cur_conn_id, + -ENODEV); /* Clear flags except NCI_UNREG */ ndev->flags &= BIT(NCI_UNREG); @@ -1035,18 +1044,23 @@ static int nci_transceive(struct nfc_dev *nfc_dev, struct nfc_target *target, struct nci_conn_info *conn_info; conn_info = ndev->rf_conn_info; - if (!conn_info) + if (!conn_info) { + kfree_skb(skb); return -EPROTO; + } pr_debug("target_idx %d, len %d\n", target->idx, skb->len); if (!ndev->target_active_prot) { pr_err("unable to exchange data, no active target\n"); + kfree_skb(skb); return -EINVAL; } - if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags)) + if (test_and_set_bit(NCI_DATA_EXCHANGE, &ndev->flags)) { + kfree_skb(skb); return -EBUSY; + } /* store cb and context to be used on receiving data */ conn_info->data_exchange_cb = cb; @@ -1171,7 +1185,7 @@ struct nci_dev *nci_allocate_device(const struct nci_ops *ops, if (!supported_protocols) return NULL; - ndev = kzalloc(sizeof(struct nci_dev), GFP_KERNEL); + ndev = kzalloc_obj(struct nci_dev); if (!ndev) return NULL; @@ -1482,10 +1496,20 @@ static bool nci_valid_size(struct sk_buff *skb) unsigned int hdr_size = NCI_CTRL_HDR_SIZE; if (skb->len < hdr_size || - !nci_plen(skb->data) || skb->len < hdr_size + nci_plen(skb->data)) { return false; } + + if (!nci_plen(skb->data)) { + /* Allow zero length in proprietary notifications (0x20 - 0x3F). */ + if (nci_opcode_oid(nci_opcode(skb->data)) >= 0x20 && + nci_mt(skb->data) == NCI_MT_NTF_PKT) + return true; + + /* Disallow zero length otherwise. */ + return false; + } + return true; } diff --git a/net/nfc/nci/data.c b/net/nfc/nci/data.c index 78f4131af3cf..5f98c73db5af 100644 --- a/net/nfc/nci/data.c +++ b/net/nfc/nci/data.c @@ -33,7 +33,8 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, conn_info = nci_get_conn_info_by_conn_id(ndev, conn_id); if (!conn_info) { kfree_skb(skb); - goto exit; + clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); + return; } cb = conn_info->data_exchange_cb; @@ -45,6 +46,12 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, timer_delete_sync(&ndev->data_timer); clear_bit(NCI_DATA_EXCHANGE_TO, &ndev->flags); + /* Mark the exchange as done before calling the callback. + * The callback (e.g. rawsock_data_exchange_complete) may + * want to immediately queue another data exchange. + */ + clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); + if (cb) { /* forward skb to nfc core */ cb(cb_context, skb, err); @@ -54,9 +61,6 @@ void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, /* no waiting callback, free skb */ kfree_skb(skb); } - -exit: - clear_bit(NCI_DATA_EXCHANGE, &ndev->flags); } /* ----------------- NCI TX Data ----------------- */ diff --git a/net/nfc/nci/hci.c b/net/nfc/nci/hci.c index 082ab66f120b..40ae8e5a7ec7 100644 --- a/net/nfc/nci/hci.c +++ b/net/nfc/nci/hci.c @@ -777,7 +777,7 @@ struct nci_hci_dev *nci_hci_allocate(struct nci_dev *ndev) { struct nci_hci_dev *hdev; - hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); + hdev = kzalloc_obj(*hdev); if (!hdev) return NULL; diff --git a/net/nfc/nci/ntf.c b/net/nfc/nci/ntf.c index 418b84e2b260..c96512bb8653 100644 --- a/net/nfc/nci/ntf.c +++ b/net/nfc/nci/ntf.c @@ -58,7 +58,7 @@ static int nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, struct nci_conn_info *conn_info; int i; - if (skb->len < sizeof(struct nci_core_conn_credit_ntf)) + if (skb->len < offsetofend(struct nci_core_conn_credit_ntf, num_entries)) return -EINVAL; ntf = (struct nci_core_conn_credit_ntf *)skb->data; @@ -68,6 +68,10 @@ static int nci_core_conn_credits_ntf_packet(struct nci_dev *ndev, if (ntf->num_entries > NCI_MAX_NUM_CONN) ntf->num_entries = NCI_MAX_NUM_CONN; + if (skb->len < offsetofend(struct nci_core_conn_credit_ntf, num_entries) + + ntf->num_entries * sizeof(struct conn_credit_entry)) + return -EINVAL; + /* update the credits */ for (i = 0; i < ntf->num_entries; i++) { ntf->conn_entries[i].conn_id = @@ -138,23 +142,48 @@ static int nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev, static const __u8 * nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfca_poll *nfca_poll, - const __u8 *data) + const __u8 *data, ssize_t data_len) { + /* Check if we have enough data for sens_res (2 bytes) */ + if (data_len < 2) + return ERR_PTR(-EINVAL); + nfca_poll->sens_res = __le16_to_cpu(*((__le16 *)data)); data += 2; + data_len -= 2; + + /* Check if we have enough data for nfcid1_len (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); nfca_poll->nfcid1_len = min_t(__u8, *data++, NFC_NFCID1_MAXSIZE); + data_len--; pr_debug("sens_res 0x%x, nfcid1_len %d\n", nfca_poll->sens_res, nfca_poll->nfcid1_len); + /* Check if we have enough data for nfcid1 */ + if (data_len < nfca_poll->nfcid1_len) + return ERR_PTR(-EINVAL); + memcpy(nfca_poll->nfcid1, data, nfca_poll->nfcid1_len); data += nfca_poll->nfcid1_len; + data_len -= nfca_poll->nfcid1_len; + + /* Check if we have enough data for sel_res_len (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); nfca_poll->sel_res_len = *data++; + data_len--; + + if (nfca_poll->sel_res_len != 0) { + /* Check if we have enough data for sel_res (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); - if (nfca_poll->sel_res_len != 0) nfca_poll->sel_res = *data++; + } pr_debug("sel_res_len %d, sel_res 0x%x\n", nfca_poll->sel_res_len, @@ -166,12 +195,21 @@ nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev, static const __u8 * nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcb_poll *nfcb_poll, - const __u8 *data) + const __u8 *data, ssize_t data_len) { + /* Check if we have enough data for sensb_res_len (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + nfcb_poll->sensb_res_len = min_t(__u8, *data++, NFC_SENSB_RES_MAXSIZE); + data_len--; pr_debug("sensb_res_len %d\n", nfcb_poll->sensb_res_len); + /* Check if we have enough data for sensb_res */ + if (data_len < nfcb_poll->sensb_res_len) + return ERR_PTR(-EINVAL); + memcpy(nfcb_poll->sensb_res, data, nfcb_poll->sensb_res_len); data += nfcb_poll->sensb_res_len; @@ -181,14 +219,29 @@ nci_extract_rf_params_nfcb_passive_poll(struct nci_dev *ndev, static const __u8 * nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcf_poll *nfcf_poll, - const __u8 *data) + const __u8 *data, ssize_t data_len) { + /* Check if we have enough data for bit_rate (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + nfcf_poll->bit_rate = *data++; + data_len--; + + /* Check if we have enough data for sensf_res_len (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + nfcf_poll->sensf_res_len = min_t(__u8, *data++, NFC_SENSF_RES_MAXSIZE); + data_len--; pr_debug("bit_rate %d, sensf_res_len %d\n", nfcf_poll->bit_rate, nfcf_poll->sensf_res_len); + /* Check if we have enough data for sensf_res */ + if (data_len < nfcf_poll->sensf_res_len) + return ERR_PTR(-EINVAL); + memcpy(nfcf_poll->sensf_res, data, nfcf_poll->sensf_res_len); data += nfcf_poll->sensf_res_len; @@ -198,22 +251,49 @@ nci_extract_rf_params_nfcf_passive_poll(struct nci_dev *ndev, static const __u8 * nci_extract_rf_params_nfcv_passive_poll(struct nci_dev *ndev, struct rf_tech_specific_params_nfcv_poll *nfcv_poll, - const __u8 *data) + const __u8 *data, ssize_t data_len) { + /* Skip 1 byte (reserved) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + ++data; + data_len--; + + /* Check if we have enough data for dsfid (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + nfcv_poll->dsfid = *data++; + data_len--; + + /* Check if we have enough data for uid (8 bytes) */ + if (data_len < NFC_ISO15693_UID_MAXSIZE) + return ERR_PTR(-EINVAL); + memcpy(nfcv_poll->uid, data, NFC_ISO15693_UID_MAXSIZE); data += NFC_ISO15693_UID_MAXSIZE; + return data; } static const __u8 * nci_extract_rf_params_nfcf_passive_listen(struct nci_dev *ndev, struct rf_tech_specific_params_nfcf_listen *nfcf_listen, - const __u8 *data) + const __u8 *data, ssize_t data_len) { + /* Check if we have enough data for local_nfcid2_len (1 byte) */ + if (data_len < 1) + return ERR_PTR(-EINVAL); + nfcf_listen->local_nfcid2_len = min_t(__u8, *data++, NFC_NFCID2_MAXSIZE); + data_len--; + + /* Check if we have enough data for local_nfcid2 */ + if (data_len < nfcf_listen->local_nfcid2_len) + return ERR_PTR(-EINVAL); + memcpy(nfcf_listen->local_nfcid2, data, nfcf_listen->local_nfcid2_len); data += nfcf_listen->local_nfcid2_len; @@ -364,7 +444,7 @@ static int nci_rf_discover_ntf_packet(struct nci_dev *ndev, const __u8 *data; bool add_target = true; - if (skb->len < sizeof(struct nci_rf_discover_ntf)) + if (skb->len < offsetofend(struct nci_rf_discover_ntf, rf_tech_specific_params_len)) return -EINVAL; data = skb->data; @@ -380,26 +460,42 @@ static int nci_rf_discover_ntf_packet(struct nci_dev *ndev, pr_debug("rf_tech_specific_params_len %d\n", ntf.rf_tech_specific_params_len); + if (skb->len < (data - skb->data) + + ntf.rf_tech_specific_params_len + sizeof(ntf.ntf_type)) + return -EINVAL; + if (ntf.rf_tech_specific_params_len > 0) { switch (ntf.rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfca_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfca_poll), data); + &(ntf.rf_tech_specific_params.nfca_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return PTR_ERR(data); break; case NCI_NFC_B_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcb_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcb_poll), data); + &(ntf.rf_tech_specific_params.nfcb_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return PTR_ERR(data); break; case NCI_NFC_F_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcf_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcf_poll), data); + &(ntf.rf_tech_specific_params.nfcf_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return PTR_ERR(data); break; case NCI_NFC_V_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcv_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcv_poll), data); + &(ntf.rf_tech_specific_params.nfcv_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return PTR_ERR(data); break; default: @@ -596,7 +692,7 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, const __u8 *data; int err = NCI_STATUS_OK; - if (skb->len < sizeof(struct nci_rf_intf_activated_ntf)) + if (skb->len < offsetofend(struct nci_rf_intf_activated_ntf, rf_tech_specific_params_len)) return -EINVAL; data = skb->data; @@ -628,26 +724,41 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, if (ntf.rf_interface == NCI_RF_INTERFACE_NFCEE_DIRECT) goto listen; + if (skb->len < (data - skb->data) + ntf.rf_tech_specific_params_len) + return -EINVAL; + if (ntf.rf_tech_specific_params_len > 0) { switch (ntf.activation_rf_tech_and_mode) { case NCI_NFC_A_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfca_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfca_poll), data); + &(ntf.rf_tech_specific_params.nfca_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return -EINVAL; break; case NCI_NFC_B_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcb_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcb_poll), data); + &(ntf.rf_tech_specific_params.nfcb_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return -EINVAL; break; case NCI_NFC_F_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcf_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcf_poll), data); + &(ntf.rf_tech_specific_params.nfcf_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return -EINVAL; break; case NCI_NFC_V_PASSIVE_POLL_MODE: data = nci_extract_rf_params_nfcv_passive_poll(ndev, - &(ntf.rf_tech_specific_params.nfcv_poll), data); + &(ntf.rf_tech_specific_params.nfcv_poll), data, + ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return -EINVAL; break; case NCI_NFC_A_PASSIVE_LISTEN_MODE: @@ -657,7 +768,9 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, case NCI_NFC_F_PASSIVE_LISTEN_MODE: data = nci_extract_rf_params_nfcf_passive_listen(ndev, &(ntf.rf_tech_specific_params.nfcf_listen), - data); + data, ntf.rf_tech_specific_params_len); + if (IS_ERR(data)) + return -EINVAL; break; default: @@ -668,6 +781,13 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, } } + if (skb->len < (data - skb->data) + + sizeof(ntf.data_exch_rf_tech_and_mode) + + sizeof(ntf.data_exch_tx_bit_rate) + + sizeof(ntf.data_exch_rx_bit_rate) + + sizeof(ntf.activation_params_len)) + return -EINVAL; + ntf.data_exch_rf_tech_and_mode = *data++; ntf.data_exch_tx_bit_rate = *data++; ntf.data_exch_rx_bit_rate = *data++; @@ -679,6 +799,9 @@ static int nci_rf_intf_activated_ntf_packet(struct nci_dev *ndev, pr_debug("data_exch_rx_bit_rate 0x%x\n", ntf.data_exch_rx_bit_rate); pr_debug("activation_params_len %d\n", ntf.activation_params_len); + if (skb->len < (data - skb->data) + ntf.activation_params_len) + return -EINVAL; + if (ntf.activation_params_len > 0) { switch (ntf.rf_interface) { case NCI_RF_INTERFACE_ISO_DEP: diff --git a/net/nfc/nci/uart.c b/net/nfc/nci/uart.c index aab107727f18..5a3aed7f84f5 100644 --- a/net/nfc/nci/uart.c +++ b/net/nfc/nci/uart.c @@ -113,7 +113,7 @@ static int nci_uart_set_driver(struct tty_struct *tty, unsigned int driver) if (!nci_uart_drivers[driver]) return -ENOENT; - nu = kzalloc(sizeof(*nu), GFP_KERNEL); + nu = kzalloc_obj(*nu); if (!nu) return -ENOMEM; diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c index a18e2c503da6..0c58824cb150 100644 --- a/net/nfc/netlink.c +++ b/net/nfc/netlink.c @@ -604,7 +604,7 @@ static int nfc_genl_dump_devices(struct sk_buff *skb, if (!iter) { first_call = true; - iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL); + iter = kmalloc_obj(struct class_dev_iter); if (!iter) return -ENOMEM; cb->args[0] = (long) iter; @@ -1370,7 +1370,7 @@ static int nfc_genl_dump_ses(struct sk_buff *skb, if (!iter) { first_call = true; - iter = kmalloc(sizeof(struct class_dev_iter), GFP_KERNEL); + iter = kmalloc_obj(struct class_dev_iter); if (!iter) return -ENOMEM; cb->args[0] = (long) iter; @@ -1541,7 +1541,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info) apdu = nla_data(info->attrs[NFC_ATTR_SE_APDU]); - ctx = kzalloc(sizeof(struct se_io_ctx), GFP_KERNEL); + ctx = kzalloc_obj(struct se_io_ctx); if (!ctx) { rc = -ENOMEM; goto put_dev; @@ -1875,7 +1875,7 @@ static int nfc_genl_rcv_nl_event(struct notifier_block *this, pr_debug("NETLINK_URELEASE event from id %d\n", n->portid); - w = kmalloc(sizeof(*w), GFP_ATOMIC); + w = kmalloc_obj(*w, GFP_ATOMIC); if (w) { INIT_WORK(&w->w, nfc_urelease_event_work); w->portid = n->portid; diff --git a/net/nfc/rawsock.c b/net/nfc/rawsock.c index b049022399ae..f7d7a599fade 100644 --- a/net/nfc/rawsock.c +++ b/net/nfc/rawsock.c @@ -67,6 +67,17 @@ static int rawsock_release(struct socket *sock) if (sock->type == SOCK_RAW) nfc_sock_unlink(&raw_sk_list, sk); + if (sk->sk_state == TCP_ESTABLISHED) { + /* Prevent rawsock_tx_work from starting new transmits and + * wait for any in-progress work to finish. This must happen + * before the socket is orphaned to avoid a race where + * rawsock_tx_work runs after the NCI device has been freed. + */ + sk->sk_shutdown |= SEND_SHUTDOWN; + cancel_work_sync(&nfc_rawsock(sk)->tx_work); + rawsock_write_queue_purge(sk); + } + sock_orphan(sk); sock_put(sk); diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index a0811e1fba65..7c9256572284 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -1586,15 +1586,13 @@ static int ovs_ct_limit_init(struct net *net, struct ovs_net *ovs_net) { int i, err; - ovs_net->ct_limit_info = kmalloc(sizeof(*ovs_net->ct_limit_info), - GFP_KERNEL); + ovs_net->ct_limit_info = kmalloc_obj(*ovs_net->ct_limit_info); if (!ovs_net->ct_limit_info) return -ENOMEM; ovs_net->ct_limit_info->default_limit = OVS_CT_LIMIT_DEFAULT; ovs_net->ct_limit_info->limits = - kmalloc_array(CT_LIMIT_HASH_BUCKETS, sizeof(struct hlist_head), - GFP_KERNEL); + kmalloc_objs(struct hlist_head, CT_LIMIT_HASH_BUCKETS); if (!ovs_net->ct_limit_info->limits) { kfree(ovs_net->ct_limit_info); return -ENOMEM; @@ -1688,8 +1686,7 @@ static int ovs_ct_limit_set_zone_limit(struct nlattr *nla_zone_limit, } else { struct ovs_ct_limit *ct_limit; - ct_limit = kmalloc(sizeof(*ct_limit), - GFP_KERNEL_ACCOUNT); + ct_limit = kmalloc_obj(*ct_limit, GFP_KERNEL_ACCOUNT); if (!ct_limit) return -ENOMEM; diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index d5b6e2002bc1..e209099218b4 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c @@ -1029,7 +1029,7 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info) } /* Extract key. */ - key = kzalloc(sizeof(*key), GFP_KERNEL); + key = kzalloc_obj(*key); if (!key) { error = -ENOMEM; goto err_kfree_flow; @@ -1797,9 +1797,7 @@ static int ovs_dp_vport_init(struct datapath *dp) { int i; - dp->ports = kmalloc_array(DP_VPORT_HASH_BUCKETS, - sizeof(struct hlist_head), - GFP_KERNEL); + dp->ports = kmalloc_objs(struct hlist_head, DP_VPORT_HASH_BUCKETS); if (!dp->ports) return -ENOMEM; @@ -1828,7 +1826,7 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info) return -ENOMEM; err = -ENOMEM; - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); if (dp == NULL) goto err_destroy_reply; diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 2d536901309e..67fbf6e48a30 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c @@ -1890,7 +1890,7 @@ int ovs_nla_get_identifier(struct sw_flow_id *sfid, const struct nlattr *ufid, return 0; /* If UFID was not provided, use unmasked key. */ - new_key = kmalloc(sizeof(*new_key), GFP_KERNEL); + new_key = kmalloc_obj(*new_key); if (!new_key) return -ENOMEM; memcpy(new_key, key, sizeof(*key)); diff --git a/net/openvswitch/flow_table.c b/net/openvswitch/flow_table.c index ffc72a741a50..61c6a5f77c2e 100644 --- a/net/openvswitch/flow_table.c +++ b/net/openvswitch/flow_table.c @@ -150,14 +150,13 @@ static void __table_instance_destroy(struct table_instance *ti) static struct table_instance *table_instance_alloc(int new_size) { - struct table_instance *ti = kmalloc(sizeof(*ti), GFP_KERNEL); + struct table_instance *ti = kmalloc_obj(*ti); int i; if (!ti) return NULL; - ti->buckets = kvmalloc_array(new_size, sizeof(struct hlist_head), - GFP_KERNEL); + ti->buckets = kvmalloc_objs(struct hlist_head, new_size); if (!ti->buckets) { kfree(ti); return NULL; @@ -367,7 +366,7 @@ static struct mask_cache *tbl_mask_cache_alloc(u32 size) (size * sizeof(struct mask_cache_entry)) > PCPU_MIN_UNIT_SIZE) return NULL; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return NULL; @@ -965,7 +964,7 @@ static struct sw_flow_mask *mask_alloc(void) { struct sw_flow_mask *mask; - mask = kmalloc(sizeof(*mask), GFP_KERNEL); + mask = kmalloc_obj(*mask); if (mask) mask->ref_count = 1; @@ -1110,8 +1109,7 @@ void ovs_flow_masks_rebalance(struct flow_table *table) int i; /* Build array of all current entries with use counters. */ - masks_and_count = kmalloc_array(ma->max, sizeof(*masks_and_count), - GFP_KERNEL); + masks_and_count = kmalloc_objs(*masks_and_count, ma->max); if (!masks_and_count) return; diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c index cc08e0403909..a02c47277337 100644 --- a/net/openvswitch/meter.c +++ b/net/openvswitch/meter.c @@ -69,7 +69,7 @@ static struct dp_meter_instance *dp_meter_instance_alloc(const u32 size) { struct dp_meter_instance *ti; - ti = kvzalloc(struct_size(ti, dp_meters, size), GFP_KERNEL); + ti = kvzalloc_flex(*ti, dp_meters, size); if (!ti) return NULL; @@ -341,7 +341,7 @@ static struct dp_meter *dp_meter_create(struct nlattr **a) return ERR_PTR(-EINVAL); /* Allocate and set up the meter before locking anything. */ - meter = kzalloc(struct_size(meter, bands, n_bands), GFP_KERNEL_ACCOUNT); + meter = kzalloc_flex(*meter, bands, n_bands, GFP_KERNEL_ACCOUNT); if (!meter) return ERR_PTR(-ENOMEM); diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index f0ce8ce1dce0..23f629e94a36 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c @@ -34,8 +34,7 @@ static struct hlist_head *dev_table; */ int ovs_vport_init(void) { - dev_table = kcalloc(VPORT_HASH_BUCKETS, sizeof(struct hlist_head), - GFP_KERNEL); + dev_table = kzalloc_objs(struct hlist_head, VPORT_HASH_BUCKETS); if (!dev_table) return -ENOMEM; diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a1005359085a..72d0935139f0 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1711,7 +1711,7 @@ static int fanout_add(struct sock *sk, struct fanout_args *args) if (type == PACKET_FANOUT_ROLLOVER || (type_flags & PACKET_FANOUT_FLAG_ROLLOVER)) { err = -ENOMEM; - rollover = kzalloc(sizeof(*rollover), GFP_KERNEL); + rollover = kzalloc_obj(*rollover); if (!rollover) goto out; atomic_long_set(&rollover->num, 0); @@ -1754,8 +1754,7 @@ static int fanout_add(struct sock *sk, struct fanout_args *args) /* legacy PACKET_FANOUT_MAX */ args->max_num_members = 256; err = -ENOMEM; - match = kvzalloc(struct_size(match, arr, args->max_num_members), - GFP_KERNEL); + match = kvzalloc_flex(*match, arr, args->max_num_members); if (!match) goto out; write_pnet(&match->net, sock_net(sk)); @@ -3693,7 +3692,7 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq) goto done; err = -ENOBUFS; - i = kmalloc(sizeof(*i), GFP_KERNEL); + i = kmalloc_obj(*i); if (i == NULL) goto done; @@ -4390,7 +4389,7 @@ static struct pgv *alloc_pg_vec(struct tpacket_req *req, int order) struct pgv *pg_vec; int i; - pg_vec = kcalloc(block_nr, sizeof(struct pgv), GFP_KERNEL | __GFP_NOWARN); + pg_vec = kzalloc_objs(struct pgv, block_nr, GFP_KERNEL | __GFP_NOWARN); if (unlikely(!pg_vec)) goto out; diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 5c36bae37b8f..86325b7fc1b6 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c @@ -48,7 +48,7 @@ struct phonet_device_list *phonet_device_list(struct net *net) static struct phonet_device *__phonet_device_alloc(struct net_device *dev) { struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); - struct phonet_device *pnd = kmalloc(sizeof(*pnd), GFP_ATOMIC); + struct phonet_device *pnd = kmalloc_obj(*pnd, GFP_ATOMIC); if (pnd == NULL) return NULL; pnd->netdev = dev; diff --git a/net/psample/psample.c b/net/psample/psample.c index 25f92ba0840c..7763662036fb 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -143,7 +143,7 @@ static struct psample_group *psample_group_create(struct net *net, { struct psample_group *group; - group = kzalloc(sizeof(*group), GFP_ATOMIC); + group = kzalloc_obj(*group, GFP_ATOMIC); if (!group) return NULL; diff --git a/net/psp/Kconfig b/net/psp/Kconfig index 371e8771f3bd..84d6b0f25460 100644 --- a/net/psp/Kconfig +++ b/net/psp/Kconfig @@ -6,6 +6,7 @@ config INET_PSP bool "PSP Security Protocol support" depends on INET select SKB_DECRYPTED + select SKB_EXTENSIONS select SOCK_VALIDATE_XMIT help Enable kernel support for the PSP Security Protocol (PSP). diff --git a/net/psp/psp_main.c b/net/psp/psp_main.c index a8534124f626..d4c04c923c5a 100644 --- a/net/psp/psp_main.c +++ b/net/psp/psp_main.c @@ -64,7 +64,7 @@ psp_dev_create(struct net_device *netdev, !psd_ops->get_stats)) return ERR_PTR(-EINVAL); - psd = kzalloc(sizeof(*psd), GFP_KERNEL); + psd = kzalloc_obj(*psd); if (!psd) return ERR_PTR(-ENOMEM); @@ -166,9 +166,46 @@ static void psp_write_headers(struct net *net, struct sk_buff *skb, __be32 spi, { struct udphdr *uh = udp_hdr(skb); struct psphdr *psph = (struct psphdr *)(uh + 1); + const struct sock *sk = skb->sk; uh->dest = htons(PSP_DEFAULT_UDP_PORT); - uh->source = udp_flow_src_port(net, skb, 0, 0, false); + + /* A bit of theory: Selection of the source port. + * + * We need some entropy, so that multiple flows use different + * source ports for better RSS spreading at the receiver. + * + * We also need that all packets belonging to one TCP flow + * use the same source port through their duration, + * so that all these packets land in the same receive queue. + * + * udp_flow_src_port() is using sk_txhash, inherited from + * skb_set_hash_from_sk() call in __tcp_transmit_skb(). + * This field is subject to reshuffling, thanks to + * sk_rethink_txhash() calls in various TCP functions. + * + * Instead, use sk->sk_hash which is constant through + * the whole flow duration. + */ + if (likely(sk)) { + u32 hash = sk->sk_hash; + int min, max; + + /* These operations are cheap, no need to cache the result + * in another socket field. + */ + inet_get_local_port_range(net, &min, &max); + /* Since this is being sent on the wire obfuscate hash a bit + * to minimize possibility that any useful information to an + * attacker is leaked. Only upper 16 bits are relevant in the + * computation for 16 bit port value because we use a + * reciprocal divide. + */ + hash ^= hash << 16; + uh->source = htons((((u64)hash * (max - min)) >> 32) + min); + } else { + uh->source = udp_flow_src_port(net, skb, 0, 0, false); + } uh->check = 0; uh->len = htons(udp_len); diff --git a/net/psp/psp_sock.c b/net/psp/psp_sock.c index f785672b7df6..a85b0ed88842 100644 --- a/net/psp/psp_sock.c +++ b/net/psp/psp_sock.c @@ -50,8 +50,8 @@ struct psp_assoc *psp_assoc_create(struct psp_dev *psd) lockdep_assert_held(&psd->lock); - pas = kzalloc(struct_size(pas, drv_data, psd->caps->assoc_drv_spc), - GFP_KERNEL_ACCOUNT); + pas = kzalloc_flex(*pas, drv_data, psd->caps->assoc_drv_spc, + GFP_KERNEL_ACCOUNT); if (!pas) return NULL; diff --git a/net/qrtr/af_qrtr.c b/net/qrtr/af_qrtr.c index dab839f61ee9..55fd2dd37588 100644 --- a/net/qrtr/af_qrtr.c +++ b/net/qrtr/af_qrtr.c @@ -271,7 +271,7 @@ static int qrtr_tx_wait(struct qrtr_node *node, int dest_node, int dest_port, mutex_lock(&node->qrtr_tx_lock); flow = radix_tree_lookup(&node->qrtr_tx_flow, key); if (!flow) { - flow = kzalloc(sizeof(*flow), GFP_KERNEL); + flow = kzalloc_obj(*flow); if (flow) { init_waitqueue_head(&flow->resume_tx); if (radix_tree_insert(&node->qrtr_tx_flow, key, flow)) { @@ -589,7 +589,7 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid) if (!ep || !ep->xmit) return -EINVAL; - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return -ENOMEM; diff --git a/net/qrtr/mhi.c b/net/qrtr/mhi.c index 69f53625a049..80e341d2f8a4 100644 --- a/net/qrtr/mhi.c +++ b/net/qrtr/mhi.c @@ -24,13 +24,25 @@ static void qcom_mhi_qrtr_dl_callback(struct mhi_device *mhi_dev, struct qrtr_mhi_dev *qdev = dev_get_drvdata(&mhi_dev->dev); int rc; - if (!qdev || mhi_res->transaction_status) + if (!qdev || (mhi_res->transaction_status && mhi_res->transaction_status != -ENOTCONN)) return; + /* Channel got reset. So just free the buffer */ + if (mhi_res->transaction_status == -ENOTCONN) { + devm_kfree(&mhi_dev->dev, mhi_res->buf_addr); + return; + } + rc = qrtr_endpoint_post(&qdev->ep, mhi_res->buf_addr, mhi_res->bytes_xferd); if (rc == -EINVAL) dev_err(qdev->dev, "invalid ipcrouter packet\n"); + + /* Done with the buffer, now recycle it for future use */ + rc = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, mhi_res->buf_addr, + mhi_dev->mhi_cntrl->buffer_len, MHI_EOT); + if (rc) + dev_err(&mhi_dev->dev, "Failed to recycle the buffer: %d\n", rc); } /* From QRTR to MHI */ @@ -72,6 +84,29 @@ static int qcom_mhi_qrtr_send(struct qrtr_endpoint *ep, struct sk_buff *skb) return rc; } +static int qcom_mhi_qrtr_queue_dl_buffers(struct mhi_device *mhi_dev) +{ + u32 free_desc; + void *buf; + int ret; + + free_desc = mhi_get_free_desc_count(mhi_dev, DMA_FROM_DEVICE); + while (free_desc--) { + buf = devm_kmalloc(&mhi_dev->dev, mhi_dev->mhi_cntrl->buffer_len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + ret = mhi_queue_buf(mhi_dev, DMA_FROM_DEVICE, buf, mhi_dev->mhi_cntrl->buffer_len, + MHI_EOT); + if (ret) { + dev_err(&mhi_dev->dev, "Failed to queue buffer: %d\n", ret); + return ret; + } + } + + return 0; +} + static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, const struct mhi_device_id *id) { @@ -87,20 +122,30 @@ static int qcom_mhi_qrtr_probe(struct mhi_device *mhi_dev, qdev->ep.xmit = qcom_mhi_qrtr_send; dev_set_drvdata(&mhi_dev->dev, qdev); - rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); + + /* start channels */ + rc = mhi_prepare_for_transfer(mhi_dev); if (rc) return rc; - /* start channels */ - rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) { - qrtr_endpoint_unregister(&qdev->ep); - return rc; - } + rc = qrtr_endpoint_register(&qdev->ep, QRTR_EP_NID_AUTO); + if (rc) + goto err_unprepare; + + rc = qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); + if (rc) + goto err_unregister; dev_dbg(qdev->dev, "Qualcomm MHI QRTR driver probed\n"); return 0; + +err_unregister: + qrtr_endpoint_unregister(&qdev->ep); +err_unprepare: + mhi_unprepare_from_transfer(mhi_dev); + + return rc; } static void qcom_mhi_qrtr_remove(struct mhi_device *mhi_dev) @@ -151,11 +196,13 @@ static int __maybe_unused qcom_mhi_qrtr_pm_resume_early(struct device *dev) if (state == MHI_STATE_M3) return 0; - rc = mhi_prepare_for_transfer_autoqueue(mhi_dev); - if (rc) + rc = mhi_prepare_for_transfer(mhi_dev); + if (rc) { dev_err(dev, "failed to prepare for autoqueue transfer %d\n", rc); + return rc; + } - return rc; + return qcom_mhi_qrtr_queue_dl_buffers(mhi_dev); } static const struct dev_pm_ops qcom_mhi_qrtr_pm_ops = { diff --git a/net/qrtr/ns.c b/net/qrtr/ns.c index bfcc1a453f23..3203b2220860 100644 --- a/net/qrtr/ns.c +++ b/net/qrtr/ns.c @@ -78,7 +78,7 @@ static struct qrtr_node *node_get(unsigned int node_id) return node; /* If node didn't exist, allocate and insert it to the tree */ - node = kzalloc(sizeof(*node), GFP_KERNEL); + node = kzalloc_obj(*node); if (!node) return NULL; @@ -229,7 +229,7 @@ static struct qrtr_server *server_add(unsigned int service, if (!service || !port) return NULL; - srv = kzalloc(sizeof(*srv), GFP_KERNEL); + srv = kzalloc_obj(*srv); if (!srv) return NULL; @@ -534,7 +534,7 @@ static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, if (from->sq_node != qrtr_ns.local_node) return -EINVAL; - lookup = kzalloc(sizeof(*lookup), GFP_KERNEL); + lookup = kzalloc_obj(*lookup); if (!lookup) return -ENOMEM; diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c index 304b41fea5ab..9726db31fc7e 100644 --- a/net/qrtr/tun.c +++ b/net/qrtr/tun.c @@ -33,7 +33,7 @@ static int qrtr_tun_open(struct inode *inode, struct file *filp) struct qrtr_tun *tun; int ret; - tun = kzalloc(sizeof(*tun), GFP_KERNEL); + tun = kzalloc_obj(*tun); if (!tun) return -ENOMEM; diff --git a/net/rds/cong.c b/net/rds/cong.c index ac1f120c10f9..3133b91f9e69 100644 --- a/net/rds/cong.c +++ b/net/rds/cong.c @@ -143,7 +143,7 @@ static struct rds_cong_map *rds_cong_from_addr(const struct in6_addr *addr) unsigned long i; unsigned long flags; - map = kzalloc(sizeof(struct rds_cong_map), GFP_KERNEL); + map = kzalloc_obj(struct rds_cong_map); if (!map) return NULL; diff --git a/net/rds/connection.c b/net/rds/connection.c index 185f73b01694..412441aaa298 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -197,7 +197,7 @@ static struct rds_connection *__rds_conn_create(struct net *net, conn = ERR_PTR(-ENOMEM); goto out; } - conn->c_path = kcalloc(npaths, sizeof(struct rds_conn_path), gfp); + conn->c_path = kzalloc_objs(struct rds_conn_path, npaths, gfp); if (!conn->c_path) { kmem_cache_free(rds_conn_slab, conn); conn = ERR_PTR(-ENOMEM); @@ -455,6 +455,9 @@ void rds_conn_shutdown(struct rds_conn_path *cp) rcu_read_unlock(); } + /* we do not hold the socket lock here but it is safe because + * fan-out is disabled when calling conn_slots_available() + */ if (conn->c_trans->conn_slots_available) conn->c_trans->conn_slots_available(conn, false); } diff --git a/net/rds/ib.c b/net/rds/ib.c index 9826fe7f9d00..ac6affa33ce7 100644 --- a/net/rds/ib.c +++ b/net/rds/ib.c @@ -172,9 +172,7 @@ static int rds_ib_add_one(struct ib_device *device) rds_ibdev->max_initiator_depth = device->attrs.max_qp_init_rd_atom; rds_ibdev->max_responder_resources = device->attrs.max_qp_rd_atom; - rds_ibdev->vector_load = kcalloc(device->num_comp_vectors, - sizeof(int), - GFP_KERNEL); + rds_ibdev->vector_load = kzalloc_objs(int, device->num_comp_vectors); if (!rds_ibdev->vector_load) { pr_err("RDS/IB: %s failed to allocate vector memory\n", __func__); diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 26b069e1999d..0c64c504f79d 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -1203,7 +1203,7 @@ int rds_ib_conn_alloc(struct rds_connection *conn, gfp_t gfp) int ret; /* XXX too lazy? */ - ic = kzalloc(sizeof(struct rds_ib_connection), gfp); + ic = kzalloc_obj(struct rds_ib_connection, gfp); if (!ic) return -ENOMEM; diff --git a/net/rds/ib_rdma.c b/net/rds/ib_rdma.c index 6585164c7059..077f7041df15 100644 --- a/net/rds/ib_rdma.c +++ b/net/rds/ib_rdma.c @@ -67,7 +67,7 @@ static int rds_ib_add_ipaddr(struct rds_ib_device *rds_ibdev, __be32 ipaddr) { struct rds_ib_ipaddr *i_ipaddr; - i_ipaddr = kmalloc(sizeof *i_ipaddr, GFP_KERNEL); + i_ipaddr = kmalloc_obj(*i_ipaddr); if (!i_ipaddr) return -ENOMEM; @@ -585,7 +585,7 @@ void *rds_ib_get_mr(struct scatterlist *sg, unsigned long nents, if (key_ret) *key_ret = ib_mr->rkey; - ibmr = kzalloc(sizeof(*ibmr), GFP_KERNEL); + ibmr = kzalloc_obj(*ibmr); if (!ibmr) { ib_dereg_mr(ib_mr); ret = -ENOMEM; @@ -641,7 +641,7 @@ struct rds_ib_mr_pool *rds_ib_create_mr_pool(struct rds_ib_device *rds_ibdev, { struct rds_ib_mr_pool *pool; - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return ERR_PTR(-ENOMEM); diff --git a/net/rds/info.c b/net/rds/info.c index b6b46a8214a0..f1b29994934a 100644 --- a/net/rds/info.c +++ b/net/rds/info.c @@ -187,7 +187,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval, nr_pages = (PAGE_ALIGN(start + len) - (start & PAGE_MASK)) >> PAGE_SHIFT; - pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kmalloc_objs(struct page *, nr_pages); if (!pages) { ret = -ENOMEM; goto out; diff --git a/net/rds/loop.c b/net/rds/loop.c index 1d73ad79c847..ac9295a766b1 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -137,7 +137,7 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) struct rds_loop_connection *lc; unsigned long flags; - lc = kzalloc(sizeof(struct rds_loop_connection), gfp); + lc = kzalloc_obj(struct rds_loop_connection, gfp); if (!lc) return -ENOMEM; diff --git a/net/rds/message.c b/net/rds/message.c index 54fd000806ea..eaa6f22601a4 100644 --- a/net/rds/message.c +++ b/net/rds/message.c @@ -415,7 +415,7 @@ static int rds_message_zcopy_from_user(struct rds_message *rm, struct iov_iter * */ sg = rm->data.op_sg; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; INIT_LIST_HEAD(&info->rs_zcookie_next); diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 00dbcd4d28e6..aa6465dc742c 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c @@ -228,13 +228,13 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, args->vec.addr, args->vec.bytes, nr_pages); /* XXX clamp nr_pages to limit the size of this alloc? */ - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, nr_pages); if (!pages) { ret = -ENOMEM; goto out; } - mr = kzalloc(sizeof(struct rds_mr), GFP_KERNEL); + mr = kzalloc_obj(struct rds_mr); if (!mr) { ret = -ENOMEM; goto out; @@ -269,7 +269,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args, goto out; } else { nents = ret; - sg = kmalloc_array(nents, sizeof(*sg), GFP_KERNEL); + sg = kmalloc_objs(*sg, nents); if (!sg) { ret = -ENOMEM; goto out; @@ -571,9 +571,7 @@ int rds_rdma_extra_size(struct rds_rdma_args *args, if (args->nr_local > UIO_MAXIOV) return -EMSGSIZE; - iov->iov = kcalloc(args->nr_local, - sizeof(struct rds_iovec), - GFP_KERNEL); + iov->iov = kzalloc_objs(struct rds_iovec, args->nr_local); if (!iov->iov) return -ENOMEM; @@ -654,7 +652,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, goto out_ret; } - pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL); + pages = kzalloc_objs(struct page *, nr_pages); if (!pages) { ret = -ENOMEM; goto out_ret; @@ -681,7 +679,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, * would have to use GFP_ATOMIC there, and don't want to deal * with failed allocations. */ - op->op_notifier = kmalloc(sizeof(struct rds_notifier), GFP_KERNEL); + op->op_notifier = kmalloc_obj(struct rds_notifier); if (!op->op_notifier) { ret = -ENOMEM; goto out_pages; @@ -730,8 +728,7 @@ int rds_cmsg_rdma_args(struct rds_sock *rs, struct rds_message *rm, ret = -EOPNOTSUPP; goto out_pages; } - local_odp_mr = - kzalloc(sizeof(*local_odp_mr), GFP_KERNEL); + local_odp_mr = kzalloc_obj(*local_odp_mr); if (!local_odp_mr) { ret = -ENOMEM; goto out_pages; @@ -937,7 +934,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, * would have to use GFP_ATOMIC there, and don't want to deal * with failed allocations. */ - rm->atomic.op_notifier = kmalloc(sizeof(*rm->atomic.op_notifier), GFP_KERNEL); + rm->atomic.op_notifier = kmalloc_obj(*rm->atomic.op_notifier); if (!rm->atomic.op_notifier) { ret = -ENOMEM; goto err; diff --git a/net/rds/send.c b/net/rds/send.c index 6e96f108473e..a1039e422a38 100644 --- a/net/rds/send.c +++ b/net/rds/send.c @@ -1431,9 +1431,11 @@ int rds_sendmsg(struct socket *sock, struct msghdr *msg, size_t payload_len) else queue_delayed_work(cpath->cp_wq, &cpath->cp_send_w, 1); rcu_read_unlock(); + + if (ret) + goto out; } - if (ret) - goto out; + rds_message_put(rm); for (ind = 0; ind < vct.indx; ind++) diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 45484a93d75f..654e23d13e3d 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -373,7 +373,7 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) int ret = 0; for (i = 0; i < RDS_MPATH_WORKERS; i++) { - tc = kmem_cache_alloc(rds_tcp_conn_slab, gfp); + tc = kmem_cache_zalloc(rds_tcp_conn_slab, gfp); if (!tc) { ret = -ENOMEM; goto fail; @@ -490,18 +490,24 @@ bool rds_tcp_tune(struct socket *sock) struct rds_tcp_net *rtn; tcp_sock_set_nodelay(sock->sk); - lock_sock(sk); /* TCP timer functions might access net namespace even after * a process which created this net namespace terminated. */ if (!sk->sk_net_refcnt) { - if (!maybe_get_net(net)) { - release_sock(sk); + if (!maybe_get_net(net)) return false; - } + /* + * sk_net_refcnt_upgrade() must be called before lock_sock() + * because it does a GFP_KERNEL allocation, which can trigger + * fs_reclaim and create a circular lock dependency with the + * socket lock. The fields it modifies (sk_net_refcnt, + * ns_tracker) are not accessed by any concurrent code path + * at this point. + */ sk_net_refcnt_upgrade(sk); put_net(net); } + lock_sock(sk); rtn = net_generic(net, rds_tcp_netid); if (rtn->sndbuf_size > 0) { sk->sk_sndbuf = rtn->sndbuf_size; diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c index 6fb5c928b8fd..08a506aa7ce7 100644 --- a/net/rds/tcp_listen.c +++ b/net/rds/tcp_listen.c @@ -59,30 +59,12 @@ void rds_tcp_keepalive(struct socket *sock) static int rds_tcp_get_peer_sport(struct socket *sock) { - union { - struct sockaddr_storage storage; - struct sockaddr addr; - struct sockaddr_in sin; - struct sockaddr_in6 sin6; - } saddr; - int sport; + struct sock *sk = sock->sk; - if (kernel_getpeername(sock, &saddr.addr) >= 0) { - switch (saddr.addr.sa_family) { - case AF_INET: - sport = ntohs(saddr.sin.sin_port); - break; - case AF_INET6: - sport = ntohs(saddr.sin6.sin6_port); - break; - default: - sport = -1; - } - } else { - sport = -1; - } + if (!sk) + return -1; - return sport; + return ntohs(READ_ONCE(inet_sk(sk)->inet_dport)); } /* rds_tcp_accept_one_path(): if accepting on cp_index > 0, make sure the @@ -177,6 +159,7 @@ int rds_tcp_accept_one(struct rds_tcp_net *rtn) struct rds_tcp_connection *rs_tcp = NULL; int conn_state; struct rds_conn_path *cp; + struct sock *sk; struct in6_addr *my_addr, *peer_addr; #if !IS_ENABLED(CONFIG_IPV6) struct in6_addr saddr, daddr; @@ -298,6 +281,17 @@ int rds_tcp_accept_one(struct rds_tcp_net *rtn) rds_conn_path_drop(cp, 0); goto rst_nsk; } + /* Save a local pointer to sk and hold a reference before setting + * callbacks. Once callbacks are set, a concurrent + * rds_tcp_conn_path_shutdown() may call sock_release(), which + * sets new_sock->sk to NULL and drops a reference on sk. + * The local pointer lets us safely access sk_state below even + * if new_sock->sk has been nulled, and sock_hold() keeps sk + * itself valid until we are done. + */ + sk = new_sock->sk; + sock_hold(sk); + if (rs_tcp->t_sock) { /* Duelling SYN has been handled in rds_tcp_accept_one() */ rds_tcp_reset_callbacks(new_sock, cp); @@ -316,13 +310,15 @@ int rds_tcp_accept_one(struct rds_tcp_net *rtn) * knowing that "rds_tcp_conn_path_shutdown" will * dequeue pending messages. */ - if (new_sock->sk->sk_state == TCP_CLOSE_WAIT || - new_sock->sk->sk_state == TCP_LAST_ACK || - new_sock->sk->sk_state == TCP_CLOSE) + if (READ_ONCE(sk->sk_state) == TCP_CLOSE_WAIT || + READ_ONCE(sk->sk_state) == TCP_LAST_ACK || + READ_ONCE(sk->sk_state) == TCP_CLOSE) rds_conn_path_drop(cp, 0); else queue_delayed_work(cp->cp_wq, &cp->cp_recv_w, 0); + sock_put(sk); + new_sock = NULL; ret = 0; if (conn->c_npaths == 0) diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 7d3e82e4c2fc..2444237bc36a 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c @@ -279,7 +279,7 @@ static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op) struct rfkill_int_event *ev; list_for_each_entry(data, &rfkill_fds, list) { - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) continue; rfkill_fill_event(&ev->ev, rfkill, op); @@ -1165,7 +1165,7 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) struct rfkill *rfkill; struct rfkill_int_event *ev, *tmp; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1182,7 +1182,7 @@ static int rfkill_fop_open(struct inode *inode, struct file *file) */ list_for_each_entry(rfkill, &rfkill_list, node) { - ev = kzalloc(sizeof(*ev), GFP_KERNEL); + ev = kzalloc_obj(*ev); if (!ev) goto free; rfkill_sync(rfkill); diff --git a/net/rfkill/input.c b/net/rfkill/input.c index 53d286b10843..f7cb24ce7754 100644 --- a/net/rfkill/input.c +++ b/net/rfkill/input.c @@ -221,7 +221,7 @@ static int rfkill_connect(struct input_handler *handler, struct input_dev *dev, struct input_handle *handle; int error; - handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); + handle = kzalloc_obj(struct input_handle); if (!handle) return -ENOMEM; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index c0f5a515a8ce..841d62481048 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -1571,8 +1571,7 @@ static int __init rose_proto_init(void) rose_callsign = null_ax25_address; - dev_rose = kcalloc(rose_ndevs, sizeof(struct net_device *), - GFP_KERNEL); + dev_rose = kzalloc_objs(struct net_device *, rose_ndevs); if (dev_rose == NULL) { printk(KERN_ERR "ROSE: rose_proto_init - unable to allocate device structure\n"); rc = -ENOMEM; diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index a1e9b05ef6f5..e31842e6b3c8 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c @@ -82,7 +82,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, } if (rose_neigh == NULL) { - rose_neigh = kmalloc(sizeof(*rose_neigh), GFP_ATOMIC); + rose_neigh = kmalloc_obj(*rose_neigh, GFP_ATOMIC); if (rose_neigh == NULL) { res = -ENOMEM; goto out; @@ -106,7 +106,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, if (rose_route->ndigis != 0) { rose_neigh->digipeat = - kmalloc(sizeof(ax25_digi), GFP_ATOMIC); + kmalloc_obj(ax25_digi, GFP_ATOMIC); if (rose_neigh->digipeat == NULL) { kfree(rose_neigh); res = -ENOMEM; @@ -148,7 +148,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route, } /* create new node */ - rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC); + rose_node = kmalloc_obj(*rose_node, GFP_ATOMIC); if (rose_node == NULL) { res = -ENOMEM; goto out; @@ -368,7 +368,7 @@ void rose_add_loopback_neigh(void) { struct rose_neigh *sn; - rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_KERNEL); + rose_loopback_neigh = kmalloc_obj(struct rose_neigh); if (!rose_loopback_neigh) return; sn = rose_loopback_neigh; @@ -417,7 +417,7 @@ int rose_add_loopback_node(const rose_address *address) if (rose_node != NULL) goto out; - if ((rose_node = kmalloc(sizeof(*rose_node), GFP_ATOMIC)) == NULL) { + if ((rose_node = kmalloc_obj(*rose_node, GFP_ATOMIC)) == NULL) { err = -ENOMEM; goto out; } @@ -1055,7 +1055,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) goto put_neigh; } - if ((rose_route = kmalloc(sizeof(*rose_route), GFP_ATOMIC)) == NULL) { + if ((rose_route = kmalloc_obj(*rose_route, GFP_ATOMIC)) == NULL) { rose_transmit_clear_request(rose_neigh, lci, ROSE_NETWORK_CONGESTION, 120); goto put_neigh; } diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 0c2c68c4b07e..0f90272ac254 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c @@ -267,12 +267,13 @@ static int rxrpc_listen(struct socket *sock, int backlog) * Lookup or create a remote transport endpoint record for the specified * address. * - * Return: The peer record found with a reference, %NULL if no record is found - * or a negative error code if the address is invalid or unsupported. + * Return: The peer record found with a reference or a negative error code if + * the address is invalid or unsupported. */ struct rxrpc_peer *rxrpc_kernel_lookup_peer(struct socket *sock, struct sockaddr_rxrpc *srx, gfp_t gfp) { + struct rxrpc_peer *peer; struct rxrpc_sock *rx = rxrpc_sk(sock->sk); int ret; @@ -280,7 +281,8 @@ struct rxrpc_peer *rxrpc_kernel_lookup_peer(struct socket *sock, if (ret < 0) return ERR_PTR(ret); - return rxrpc_lookup_peer(rx->local, srx, gfp); + peer = rxrpc_lookup_peer(rx->local, srx, gfp); + return peer ?: ERR_PTR(-ENOMEM); } EXPORT_SYMBOL(rxrpc_kernel_lookup_peer); diff --git a/net/rxrpc/call_accept.c b/net/rxrpc/call_accept.c index 00982a030744..ee2d1319e69a 100644 --- a/net/rxrpc/call_accept.c +++ b/net/rxrpc/call_accept.c @@ -164,7 +164,7 @@ int rxrpc_service_prealloc(struct rxrpc_sock *rx, gfp_t gfp) struct rxrpc_backlog *b = rx->backlog; if (!b) { - b = kzalloc(sizeof(struct rxrpc_backlog), gfp); + b = kzalloc_obj(struct rxrpc_backlog, gfp); if (!b) return -ENOMEM; rx->backlog = b; diff --git a/net/rxrpc/conn_client.c b/net/rxrpc/conn_client.c index 63bbcc567f59..9b757798dedd 100644 --- a/net/rxrpc/conn_client.c +++ b/net/rxrpc/conn_client.c @@ -76,7 +76,7 @@ static struct rxrpc_bundle *rxrpc_alloc_bundle(struct rxrpc_call *call, static atomic_t rxrpc_bundle_id; struct rxrpc_bundle *bundle; - bundle = kzalloc(sizeof(*bundle), gfp); + bundle = kzalloc_obj(*bundle, gfp); if (bundle) { bundle->local = call->local; bundle->peer = rxrpc_get_peer(call->peer, rxrpc_peer_get_bundle); diff --git a/net/rxrpc/conn_object.c b/net/rxrpc/conn_object.c index 37340becb224..0ece717db0f8 100644 --- a/net/rxrpc/conn_object.c +++ b/net/rxrpc/conn_object.c @@ -59,7 +59,7 @@ struct rxrpc_connection *rxrpc_alloc_connection(struct rxrpc_net *rxnet, _enter(""); - conn = kzalloc(sizeof(struct rxrpc_connection), gfp); + conn = kzalloc_obj(struct rxrpc_connection, gfp); if (conn) { INIT_LIST_HEAD(&conn->cache_link); timer_setup(&conn->timer, &rxrpc_connection_timer, 0); diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c index 9fdc1f031c9d..85078114b2dd 100644 --- a/net/rxrpc/key.c +++ b/net/rxrpc/key.c @@ -75,7 +75,7 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep, prep->quotalen = datalen + plen; plen -= sizeof(*token); - token = kzalloc(sizeof(*token), GFP_KERNEL); + token = kzalloc_obj(*token); if (!token) return -ENOMEM; @@ -202,7 +202,7 @@ static int rxrpc_preparse_xdr_yfs_rxgk(struct key_preparsed_payload *prep, prep->quotalen = datalen + plen; plen -= sizeof(*token); - token = kzalloc(sizeof(*token), GFP_KERNEL); + token = kzalloc_obj(*token); if (!token) goto nomem; @@ -500,7 +500,7 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep) prep->quotalen = plen + sizeof(*token); ret = -ENOMEM; - token = kzalloc(sizeof(*token), GFP_KERNEL); + token = kzalloc_obj(*token); if (!token) goto error; token->kad = kzalloc(plen, GFP_KERNEL); diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c index a74a4b43904f..111f574fe667 100644 --- a/net/rxrpc/local_object.c +++ b/net/rxrpc/local_object.c @@ -112,7 +112,7 @@ static struct rxrpc_local *rxrpc_alloc_local(struct net *net, struct rxrpc_local *local; u32 tmp; - local = kzalloc(sizeof(struct rxrpc_local), GFP_KERNEL); + local = kzalloc_obj(struct rxrpc_local); if (local) { refcount_set(&local->ref, 1); atomic_set(&local->active_users, 1); diff --git a/net/rxrpc/peer_object.c b/net/rxrpc/peer_object.c index 366431b0736c..fa9a406e1168 100644 --- a/net/rxrpc/peer_object.c +++ b/net/rxrpc/peer_object.c @@ -226,7 +226,7 @@ struct rxrpc_peer *rxrpc_alloc_peer(struct rxrpc_local *local, gfp_t gfp, _enter(""); - peer = kzalloc(sizeof(struct rxrpc_peer), gfp); + peer = kzalloc_obj(struct rxrpc_peer, gfp); if (peer) { refcount_set(&peer->ref, 1); peer->local = rxrpc_get_local(local, rxrpc_local_get_peer); diff --git a/net/rxrpc/rxgk.c b/net/rxrpc/rxgk.c index 43cbf9efd89f..f9f5a2dc62ed 100644 --- a/net/rxrpc/rxgk.c +++ b/net/rxrpc/rxgk.c @@ -351,7 +351,7 @@ static int rxgk_secure_packet_integrity(const struct rxrpc_call *call, _enter(""); - hdr = kzalloc(sizeof(*hdr), GFP_NOFS); + hdr = kzalloc_obj(*hdr, GFP_NOFS); if (!hdr) goto error_gk; @@ -483,7 +483,7 @@ static int rxgk_verify_packet_integrity(struct rxrpc_call *call, crypto_krb5_where_is_the_data(gk->krb5, KRB5_CHECKSUM_MODE, &data_offset, &data_len); - hdr = kzalloc(sizeof(*hdr), GFP_NOFS); + hdr = kzalloc_obj(*hdr, GFP_NOFS); if (!hdr) goto put_gk; diff --git a/net/rxrpc/rxgk_kdf.c b/net/rxrpc/rxgk_kdf.c index b4db5aa30e5b..677981d1ad79 100644 --- a/net/rxrpc/rxgk_kdf.c +++ b/net/rxrpc/rxgk_kdf.c @@ -213,7 +213,7 @@ struct rxgk_context *rxgk_generate_transport_key(struct rxrpc_connection *conn, _enter(""); - gk = kzalloc(sizeof(*gk), GFP_KERNEL); + gk = kzalloc_obj(*gk); if (!gk) return ERR_PTR(-ENOMEM); refcount_set(&gk->usage, 1); diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c index a756855a0a62..e923d6829008 100644 --- a/net/rxrpc/rxkad.c +++ b/net/rxrpc/rxkad.c @@ -511,7 +511,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb, if (nsg <= 4) { nsg = 4; } else { - sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO); + sg = kmalloc_objs(*sg, nsg, GFP_NOIO); if (!sg) return -ENOMEM; } @@ -1139,7 +1139,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn, } ret = -ENOMEM; - response = kzalloc(sizeof(struct rxkad_response), GFP_NOFS); + response = kzalloc_obj(struct rxkad_response, GFP_NOFS); if (!response) goto temporary_error; diff --git a/net/rxrpc/rxperf.c b/net/rxrpc/rxperf.c index 98ea76fae70f..b8df6d22314d 100644 --- a/net/rxrpc/rxperf.c +++ b/net/rxrpc/rxperf.c @@ -151,7 +151,7 @@ static void rxperf_charge_preallocation(struct work_struct *work) struct rxperf_call *call; for (;;) { - call = kzalloc(sizeof(*call), GFP_KERNEL); + call = kzalloc_obj(*call); if (!call) break; diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index ebbb78b842de..04f9c5f2dc24 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c @@ -282,7 +282,7 @@ static int rxrpc_alloc_txqueue(struct sock *sk, struct rxrpc_call *call) { struct rxrpc_txqueue *tq; - tq = kzalloc(sizeof(*tq), sk->sk_allocation); + tq = kzalloc_obj(*tq, sk->sk_allocation); if (!tq) return -ENOMEM; diff --git a/net/rxrpc/txbuf.c b/net/rxrpc/txbuf.c index 29767038691a..55ef7a04852e 100644 --- a/net/rxrpc/txbuf.c +++ b/net/rxrpc/txbuf.c @@ -23,7 +23,7 @@ struct rxrpc_txbuf *rxrpc_alloc_data_txbuf(struct rxrpc_call *call, size_t data_ size_t total, doff, jsize = sizeof(struct rxrpc_jumbo_header); void *buf; - txb = kzalloc(sizeof(*txb), gfp); + txb = kzalloc_obj(*txb, gfp); if (!txb) return NULL; diff --git a/net/sched/act_api.c b/net/sched/act_api.c index e1ab0faeb811..332fd9695e54 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -985,7 +985,7 @@ static int tcf_pernet_add_id_list(unsigned int id) } } - id_ptr = kzalloc(sizeof(*id_ptr), GFP_KERNEL); + id_ptr = kzalloc_obj(*id_ptr); if (!id_ptr) { ret = -ENOMEM; goto err_out; @@ -1272,7 +1272,7 @@ int tcf_action_dump(struct sk_buff *skb, struct tc_action *actions[], static struct tc_cookie *nla_memdup_cookie(struct nlattr **tb) { - struct tc_cookie *c = kzalloc(sizeof(*c), GFP_KERNEL); + struct tc_cookie *c = kzalloc_obj(*c); if (!c) return NULL; diff --git a/net/sched/act_connmark.c b/net/sched/act_connmark.c index 26ba8c2d20ab..c634af5edfcd 100644 --- a/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c @@ -121,7 +121,7 @@ static int tcf_connmark_init(struct net *net, struct nlattr *nla, if (!tb[TCA_CONNMARK_PARMS]) return -EINVAL; - nparms = kzalloc(sizeof(*nparms), GFP_KERNEL); + nparms = kzalloc_obj(*nparms); if (!nparms) return -ENOMEM; diff --git a/net/sched/act_csum.c b/net/sched/act_csum.c index 0939e6b2ba4d..213e1ce9d2da 100644 --- a/net/sched/act_csum.c +++ b/net/sched/act_csum.c @@ -93,7 +93,7 @@ static int tcf_csum_init(struct net *net, struct nlattr *nla, p = to_tcf_csum(*a); - params_new = kzalloc(sizeof(*params_new), GFP_KERNEL); + params_new = kzalloc_obj(*params_new); if (unlikely(!params_new)) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c index 81d488655793..7d5e50c921a0 100644 --- a/net/sched/act_ct.c +++ b/net/sched/act_ct.c @@ -332,7 +332,7 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params) if (ct_ft && refcount_inc_not_zero(&ct_ft->ref)) goto out_unlock; - ct_ft = kzalloc(sizeof(*ct_ft), GFP_KERNEL); + ct_ft = kzalloc_obj(*ct_ft); if (!ct_ft) goto err_alloc; refcount_set(&ct_ft->ref, 1); @@ -1360,6 +1360,12 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, return -EINVAL; } + if (bind && !(flags & TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT)) { + NL_SET_ERR_MSG_MOD(extack, + "Attaching ct to a non ingress/clsact qdisc is unsupported"); + return -EOPNOTSUPP; + } + err = nla_parse_nested(tb, TCA_CT_MAX, nla, ct_policy, extack); if (err < 0) return err; @@ -1397,7 +1403,7 @@ static int tcf_ct_init(struct net *net, struct nlattr *nla, c = to_ct(*a); - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (unlikely(!params)) { err = -ENOMEM; goto cleanup; diff --git a/net/sched/act_ctinfo.c b/net/sched/act_ctinfo.c index d2c750bab1d3..1886ffd2ca95 100644 --- a/net/sched/act_ctinfo.c +++ b/net/sched/act_ctinfo.c @@ -236,7 +236,7 @@ static int tcf_ctinfo_init(struct net *net, struct nlattr *nla, ci = to_ctinfo(*a); - cp_new = kzalloc(sizeof(*cp_new), GFP_KERNEL); + cp_new = kzalloc_obj(*cp_new); if (unlikely(!cp_new)) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/act_gate.c b/net/sched/act_gate.c index c1f75f272757..fdbfcaa3e2ab 100644 --- a/net/sched/act_gate.c +++ b/net/sched/act_gate.c @@ -32,9 +32,12 @@ static ktime_t gate_get_time(struct tcf_gate *gact) return KTIME_MAX; } -static void gate_get_start_time(struct tcf_gate *gact, ktime_t *start) +static void tcf_gate_params_free_rcu(struct rcu_head *head); + +static void gate_get_start_time(struct tcf_gate *gact, + const struct tcf_gate_params *param, + ktime_t *start) { - struct tcf_gate_params *param = &gact->param; ktime_t now, base, cycle; u64 n; @@ -69,12 +72,14 @@ static enum hrtimer_restart gate_timer_func(struct hrtimer *timer) { struct tcf_gate *gact = container_of(timer, struct tcf_gate, hitimer); - struct tcf_gate_params *p = &gact->param; struct tcfg_gate_entry *next; + struct tcf_gate_params *p; ktime_t close_time, now; spin_lock(&gact->tcf_lock); + p = rcu_dereference_protected(gact->param, + lockdep_is_held(&gact->tcf_lock)); next = gact->next_entry; /* cycle start, clear pending bit, clear total octets */ @@ -225,6 +230,35 @@ static void release_entry_list(struct list_head *entries) } } +static int tcf_gate_copy_entries(struct tcf_gate_params *dst, + const struct tcf_gate_params *src, + struct netlink_ext_ack *extack) +{ + struct tcfg_gate_entry *entry; + int i = 0; + + list_for_each_entry(entry, &src->entries, list) { + struct tcfg_gate_entry *new; + + new = kzalloc(sizeof(*new), GFP_ATOMIC); + if (!new) { + NL_SET_ERR_MSG(extack, "Not enough memory for entry"); + return -ENOMEM; + } + + new->index = entry->index; + new->gate_state = entry->gate_state; + new->interval = entry->interval; + new->ipv = entry->ipv; + new->maxoctets = entry->maxoctets; + list_add_tail(&new->list, &dst->entries); + i++; + } + + dst->num_entries = i; + return 0; +} + static int parse_gate_list(struct nlattr *list_attr, struct tcf_gate_params *sched, struct netlink_ext_ack *extack) @@ -243,7 +277,7 @@ static int parse_gate_list(struct nlattr *list_attr, continue; } - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) { NL_SET_ERR_MSG(extack, "Not enough memory for entry"); err = -ENOMEM; @@ -270,24 +304,44 @@ static int parse_gate_list(struct nlattr *list_attr, return err; } -static void gate_setup_timer(struct tcf_gate *gact, u64 basetime, - enum tk_offsets tko, s32 clockid, - bool do_init) +static bool gate_timer_needs_cancel(u64 basetime, u64 old_basetime, + enum tk_offsets tko, + enum tk_offsets old_tko, + s32 clockid, s32 old_clockid) { - if (!do_init) { - if (basetime == gact->param.tcfg_basetime && - tko == gact->tk_offset && - clockid == gact->param.tcfg_clockid) - return; + return basetime != old_basetime || + clockid != old_clockid || + tko != old_tko; +} - spin_unlock_bh(&gact->tcf_lock); - hrtimer_cancel(&gact->hitimer); - spin_lock_bh(&gact->tcf_lock); +static int gate_clock_resolve(s32 clockid, enum tk_offsets *tko, + struct netlink_ext_ack *extack) +{ + switch (clockid) { + case CLOCK_REALTIME: + *tko = TK_OFFS_REAL; + return 0; + case CLOCK_MONOTONIC: + *tko = TK_OFFS_MAX; + return 0; + case CLOCK_BOOTTIME: + *tko = TK_OFFS_BOOT; + return 0; + case CLOCK_TAI: + *tko = TK_OFFS_TAI; + return 0; + default: + NL_SET_ERR_MSG(extack, "Invalid 'clockid'"); + return -EINVAL; } - gact->param.tcfg_basetime = basetime; - gact->param.tcfg_clockid = clockid; - gact->tk_offset = tko; - hrtimer_setup(&gact->hitimer, gate_timer_func, clockid, HRTIMER_MODE_ABS_SOFT); +} + +static void gate_setup_timer(struct tcf_gate *gact, s32 clockid, + enum tk_offsets tko) +{ + WRITE_ONCE(gact->tk_offset, tko); + hrtimer_setup(&gact->hitimer, gate_timer_func, clockid, + HRTIMER_MODE_ABS_SOFT); } static int tcf_gate_init(struct net *net, struct nlattr *nla, @@ -296,15 +350,22 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, struct netlink_ext_ack *extack) { struct tc_action_net *tn = net_generic(net, act_gate_ops.net_id); - enum tk_offsets tk_offset = TK_OFFS_TAI; + u64 cycletime = 0, basetime = 0, cycletime_ext = 0; + struct tcf_gate_params *p = NULL, *old_p = NULL; + enum tk_offsets old_tk_offset = TK_OFFS_TAI; + const struct tcf_gate_params *cur_p = NULL; bool bind = flags & TCA_ACT_FLAGS_BIND; struct nlattr *tb[TCA_GATE_MAX + 1]; + enum tk_offsets tko = TK_OFFS_TAI; struct tcf_chain *goto_ch = NULL; - u64 cycletime = 0, basetime = 0; - struct tcf_gate_params *p; + s32 timer_clockid = CLOCK_TAI; + bool use_old_entries = false; + s32 old_clockid = CLOCK_TAI; + bool need_cancel = false; s32 clockid = CLOCK_TAI; struct tcf_gate *gact; struct tc_gate *parm; + u64 old_basetime = 0; int ret = 0, err; u32 gflags = 0; s32 prio = -1; @@ -321,26 +382,8 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, if (!tb[TCA_GATE_PARMS]) return -EINVAL; - if (tb[TCA_GATE_CLOCKID]) { + if (tb[TCA_GATE_CLOCKID]) clockid = nla_get_s32(tb[TCA_GATE_CLOCKID]); - switch (clockid) { - case CLOCK_REALTIME: - tk_offset = TK_OFFS_REAL; - break; - case CLOCK_MONOTONIC: - tk_offset = TK_OFFS_MAX; - break; - case CLOCK_BOOTTIME: - tk_offset = TK_OFFS_BOOT; - break; - case CLOCK_TAI: - tk_offset = TK_OFFS_TAI; - break; - default: - NL_SET_ERR_MSG(extack, "Invalid 'clockid'"); - return -EINVAL; - } - } parm = nla_data(tb[TCA_GATE_PARMS]); index = parm->index; @@ -366,6 +409,60 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, return -EEXIST; } + gact = to_gate(*a); + + err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); + if (err < 0) + goto release_idr; + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) { + err = -ENOMEM; + goto chain_put; + } + INIT_LIST_HEAD(&p->entries); + + use_old_entries = !tb[TCA_GATE_ENTRY_LIST]; + if (!use_old_entries) { + err = parse_gate_list(tb[TCA_GATE_ENTRY_LIST], p, extack); + if (err < 0) + goto err_free; + use_old_entries = !err; + } + + if (ret == ACT_P_CREATED && use_old_entries) { + NL_SET_ERR_MSG(extack, "The entry list is empty"); + err = -EINVAL; + goto err_free; + } + + if (ret != ACT_P_CREATED) { + rcu_read_lock(); + cur_p = rcu_dereference(gact->param); + + old_basetime = cur_p->tcfg_basetime; + old_clockid = cur_p->tcfg_clockid; + old_tk_offset = READ_ONCE(gact->tk_offset); + + basetime = old_basetime; + cycletime_ext = cur_p->tcfg_cycletime_ext; + prio = cur_p->tcfg_priority; + gflags = cur_p->tcfg_flags; + + if (!tb[TCA_GATE_CLOCKID]) + clockid = old_clockid; + + err = 0; + if (use_old_entries) { + err = tcf_gate_copy_entries(p, cur_p, extack); + if (!err && !tb[TCA_GATE_CYCLE_TIME]) + cycletime = cur_p->tcfg_cycletime; + } + rcu_read_unlock(); + if (err) + goto err_free; + } + if (tb[TCA_GATE_PRIORITY]) prio = nla_get_s32(tb[TCA_GATE_PRIORITY]); @@ -375,25 +472,26 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, if (tb[TCA_GATE_FLAGS]) gflags = nla_get_u32(tb[TCA_GATE_FLAGS]); - gact = to_gate(*a); - if (ret == ACT_P_CREATED) - INIT_LIST_HEAD(&gact->param.entries); - - err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); - if (err < 0) - goto release_idr; - - spin_lock_bh(&gact->tcf_lock); - p = &gact->param; - if (tb[TCA_GATE_CYCLE_TIME]) cycletime = nla_get_u64(tb[TCA_GATE_CYCLE_TIME]); - if (tb[TCA_GATE_ENTRY_LIST]) { - err = parse_gate_list(tb[TCA_GATE_ENTRY_LIST], p, extack); - if (err < 0) - goto chain_put; - } + if (tb[TCA_GATE_CYCLE_TIME_EXT]) + cycletime_ext = nla_get_u64(tb[TCA_GATE_CYCLE_TIME_EXT]); + + err = gate_clock_resolve(clockid, &tko, extack); + if (err) + goto err_free; + timer_clockid = clockid; + + need_cancel = ret != ACT_P_CREATED && + gate_timer_needs_cancel(basetime, old_basetime, + tko, old_tk_offset, + timer_clockid, old_clockid); + + if (need_cancel) + hrtimer_cancel(&gact->hitimer); + + spin_lock_bh(&gact->tcf_lock); if (!cycletime) { struct tcfg_gate_entry *entry; @@ -402,22 +500,20 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, list_for_each_entry(entry, &p->entries, list) cycle = ktime_add_ns(cycle, entry->interval); cycletime = cycle; - if (!cycletime) { - err = -EINVAL; - goto chain_put; - } } p->tcfg_cycletime = cycletime; + p->tcfg_cycletime_ext = cycletime_ext; - if (tb[TCA_GATE_CYCLE_TIME_EXT]) - p->tcfg_cycletime_ext = - nla_get_u64(tb[TCA_GATE_CYCLE_TIME_EXT]); - - gate_setup_timer(gact, basetime, tk_offset, clockid, - ret == ACT_P_CREATED); + if (need_cancel || ret == ACT_P_CREATED) + gate_setup_timer(gact, timer_clockid, tko); p->tcfg_priority = prio; p->tcfg_flags = gflags; - gate_get_start_time(gact, &start); + p->tcfg_basetime = basetime; + p->tcfg_clockid = timer_clockid; + gate_get_start_time(gact, p, &start); + + old_p = rcu_replace_pointer(gact->param, p, + lockdep_is_held(&gact->tcf_lock)); gact->current_close_time = start; gact->current_gate_status = GATE_ACT_GATE_OPEN | GATE_ACT_PENDING; @@ -434,11 +530,15 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, if (goto_ch) tcf_chain_put_by_act(goto_ch); + if (old_p) + call_rcu(&old_p->rcu, tcf_gate_params_free_rcu); + return ret; +err_free: + release_entry_list(&p->entries); + kfree(p); chain_put: - spin_unlock_bh(&gact->tcf_lock); - if (goto_ch) tcf_chain_put_by_act(goto_ch); release_idr: @@ -446,21 +546,29 @@ static int tcf_gate_init(struct net *net, struct nlattr *nla, * without taking tcf_lock. */ if (ret == ACT_P_CREATED) - gate_setup_timer(gact, gact->param.tcfg_basetime, - gact->tk_offset, gact->param.tcfg_clockid, - true); + gate_setup_timer(gact, timer_clockid, tko); + tcf_idr_release(*a, bind); return err; } +static void tcf_gate_params_free_rcu(struct rcu_head *head) +{ + struct tcf_gate_params *p = container_of(head, struct tcf_gate_params, rcu); + + release_entry_list(&p->entries); + kfree(p); +} + static void tcf_gate_cleanup(struct tc_action *a) { struct tcf_gate *gact = to_gate(a); struct tcf_gate_params *p; - p = &gact->param; hrtimer_cancel(&gact->hitimer); - release_entry_list(&p->entries); + p = rcu_dereference_protected(gact->param, 1); + if (p) + call_rcu(&p->rcu, tcf_gate_params_free_rcu); } static int dumping_entry(struct sk_buff *skb, @@ -509,10 +617,9 @@ static int tcf_gate_dump(struct sk_buff *skb, struct tc_action *a, struct nlattr *entry_list; struct tcf_t t; - spin_lock_bh(&gact->tcf_lock); - opt.action = gact->tcf_action; - - p = &gact->param; + rcu_read_lock(); + opt.action = READ_ONCE(gact->tcf_action); + p = rcu_dereference(gact->param); if (nla_put(skb, TCA_GATE_PARMS, sizeof(opt), &opt)) goto nla_put_failure; @@ -552,12 +659,12 @@ static int tcf_gate_dump(struct sk_buff *skb, struct tc_action *a, tcf_tm_dump(&t, &gact->tcf_tm); if (nla_put_64bit(skb, TCA_GATE_TM, sizeof(t), &t, TCA_GATE_PAD)) goto nla_put_failure; - spin_unlock_bh(&gact->tcf_lock); + rcu_read_unlock(); return skb->len; nla_put_failure: - spin_unlock_bh(&gact->tcf_lock); + rcu_read_unlock(); nlmsg_trim(skb, b); return -1; } diff --git a/net/sched/act_ife.c b/net/sched/act_ife.c index 8e8f6af731d5..d5e8a91bb4eb 100644 --- a/net/sched/act_ife.c +++ b/net/sched/act_ife.c @@ -293,13 +293,13 @@ static int load_metaops_and_vet(u32 metaid, void *val, int len, bool rtnl_held) /* called when adding new meta information */ static int __add_metainfo(const struct tcf_meta_ops *ops, - struct tcf_ife_info *ife, u32 metaid, void *metaval, - int len, bool atomic, bool exists) + struct tcf_ife_params *p, u32 metaid, void *metaval, + int len, bool atomic) { struct tcf_meta_info *mi = NULL; int ret = 0; - mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL); + mi = kzalloc_obj(*mi, atomic ? GFP_ATOMIC : GFP_KERNEL); if (!mi) return -ENOMEM; @@ -313,45 +313,40 @@ static int __add_metainfo(const struct tcf_meta_ops *ops, } } - if (exists) - spin_lock_bh(&ife->tcf_lock); - list_add_tail(&mi->metalist, &ife->metalist); - if (exists) - spin_unlock_bh(&ife->tcf_lock); + list_add_tail(&mi->metalist, &p->metalist); return ret; } static int add_metainfo_and_get_ops(const struct tcf_meta_ops *ops, - struct tcf_ife_info *ife, u32 metaid, - bool exists) + struct tcf_ife_params *p, u32 metaid) { int ret; if (!try_module_get(ops->owner)) return -ENOENT; - ret = __add_metainfo(ops, ife, metaid, NULL, 0, true, exists); + ret = __add_metainfo(ops, p, metaid, NULL, 0, true); if (ret) module_put(ops->owner); return ret; } -static int add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, - int len, bool exists) +static int add_metainfo(struct tcf_ife_params *p, u32 metaid, void *metaval, + int len) { const struct tcf_meta_ops *ops = find_ife_oplist(metaid); int ret; if (!ops) return -ENOENT; - ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists); + ret = __add_metainfo(ops, p, metaid, metaval, len, false); if (ret) /*put back what find_ife_oplist took */ module_put(ops->owner); return ret; } -static int use_all_metadata(struct tcf_ife_info *ife, bool exists) +static int use_all_metadata(struct tcf_ife_params *p) { struct tcf_meta_ops *o; int rc = 0; @@ -359,7 +354,7 @@ static int use_all_metadata(struct tcf_ife_info *ife, bool exists) read_lock(&ife_mod_lock); list_for_each_entry(o, &ifeoplist, list) { - rc = add_metainfo_and_get_ops(o, ife, o->metaid, exists); + rc = add_metainfo_and_get_ops(o, p, o->metaid); if (rc == 0) installed += 1; } @@ -371,7 +366,7 @@ static int use_all_metadata(struct tcf_ife_info *ife, bool exists) return -EINVAL; } -static int dump_metalist(struct sk_buff *skb, struct tcf_ife_info *ife) +static int dump_metalist(struct sk_buff *skb, struct tcf_ife_params *p) { struct tcf_meta_info *e; struct nlattr *nest; @@ -379,14 +374,14 @@ static int dump_metalist(struct sk_buff *skb, struct tcf_ife_info *ife) int total_encoded = 0; /*can only happen on decode */ - if (list_empty(&ife->metalist)) + if (list_empty(&p->metalist)) return 0; nest = nla_nest_start_noflag(skb, TCA_IFE_METALST); if (!nest) goto out_nlmsg_trim; - list_for_each_entry(e, &ife->metalist, metalist) { + list_for_each_entry(e, &p->metalist, metalist) { if (!e->ops->get(skb, e)) total_encoded += 1; } @@ -403,13 +398,11 @@ static int dump_metalist(struct sk_buff *skb, struct tcf_ife_info *ife) return -1; } -/* under ife->tcf_lock */ -static void _tcf_ife_cleanup(struct tc_action *a) +static void __tcf_ife_cleanup(struct tcf_ife_params *p) { - struct tcf_ife_info *ife = to_ife(a); struct tcf_meta_info *e, *n; - list_for_each_entry_safe(e, n, &ife->metalist, metalist) { + list_for_each_entry_safe(e, n, &p->metalist, metalist) { list_del(&e->metalist); if (e->metaval) { if (e->ops->release) @@ -422,18 +415,23 @@ static void _tcf_ife_cleanup(struct tc_action *a) } } +static void tcf_ife_cleanup_params(struct rcu_head *head) +{ + struct tcf_ife_params *p = container_of(head, struct tcf_ife_params, + rcu); + + __tcf_ife_cleanup(p); + kfree(p); +} + static void tcf_ife_cleanup(struct tc_action *a) { struct tcf_ife_info *ife = to_ife(a); struct tcf_ife_params *p; - spin_lock_bh(&ife->tcf_lock); - _tcf_ife_cleanup(a); - spin_unlock_bh(&ife->tcf_lock); - p = rcu_dereference_protected(ife->params, 1); if (p) - kfree_rcu(p, rcu); + call_rcu(&p->rcu, tcf_ife_cleanup_params); } static int load_metalist(struct nlattr **tb, bool rtnl_held) @@ -455,8 +453,7 @@ static int load_metalist(struct nlattr **tb, bool rtnl_held) return 0; } -static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb, - bool exists, bool rtnl_held) +static int populate_metalist(struct tcf_ife_params *p, struct nlattr **tb) { int len = 0; int rc = 0; @@ -468,7 +465,7 @@ static int populate_metalist(struct tcf_ife_info *ife, struct nlattr **tb, val = nla_data(tb[i]); len = nla_len(tb[i]); - rc = add_metainfo(ife, i, val, len, exists); + rc = add_metainfo(p, i, val, len); if (rc) return rc; } @@ -520,9 +517,10 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, if (parm->flags & ~IFE_ENCODE) return -EINVAL; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; + INIT_LIST_HEAD(&p->metalist); if (tb[TCA_IFE_METALST]) { err = nla_parse_nested_deprecated(tb2, IFE_META_MAX, @@ -567,8 +565,6 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, } ife = to_ife(*a); - if (ret == ACT_P_CREATED) - INIT_LIST_HEAD(&ife->metalist); err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack); if (err < 0) @@ -600,8 +596,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, } if (tb[TCA_IFE_METALST]) { - err = populate_metalist(ife, tb2, exists, - !(flags & TCA_ACT_FLAGS_NO_RTNL)); + err = populate_metalist(p, tb2); if (err) goto metadata_parse_err; } else { @@ -610,7 +605,7 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, * as we can. You better have at least one else we are * going to bail out */ - err = use_all_metadata(ife, exists); + err = use_all_metadata(p); if (err) goto metadata_parse_err; } @@ -626,13 +621,14 @@ static int tcf_ife_init(struct net *net, struct nlattr *nla, if (goto_ch) tcf_chain_put_by_act(goto_ch); if (p) - kfree_rcu(p, rcu); + call_rcu(&p->rcu, tcf_ife_cleanup_params); return ret; metadata_parse_err: if (goto_ch) tcf_chain_put_by_act(goto_ch); release_idr: + __tcf_ife_cleanup(p); kfree(p); tcf_idr_release(*a, bind); return err; @@ -679,7 +675,7 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind, if (nla_put(skb, TCA_IFE_TYPE, 2, &p->eth_type)) goto nla_put_failure; - if (dump_metalist(skb, ife)) { + if (dump_metalist(skb, p)) { /*ignore failure to dump metalist */ pr_info("Failed to dump metalist\n"); } @@ -693,13 +689,13 @@ static int tcf_ife_dump(struct sk_buff *skb, struct tc_action *a, int bind, return -1; } -static int find_decode_metaid(struct sk_buff *skb, struct tcf_ife_info *ife, +static int find_decode_metaid(struct sk_buff *skb, struct tcf_ife_params *p, u16 metaid, u16 mlen, void *mdata) { struct tcf_meta_info *e; /* XXX: use hash to speed up */ - list_for_each_entry(e, &ife->metalist, metalist) { + list_for_each_entry_rcu(e, &p->metalist, metalist) { if (metaid == e->metaid) { if (e->ops) { /* We check for decode presence already */ @@ -716,10 +712,13 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a, { struct tcf_ife_info *ife = to_ife(a); int action = ife->tcf_action; + struct tcf_ife_params *p; u8 *ifehdr_end; u8 *tlv_data; u16 metalen; + p = rcu_dereference_bh(ife->params); + bstats_update(this_cpu_ptr(ife->common.cpu_bstats), skb); tcf_lastuse_update(&ife->tcf_tm); @@ -745,7 +744,7 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a, return TC_ACT_SHOT; } - if (find_decode_metaid(skb, ife, mtype, dlen, curr_data)) { + if (find_decode_metaid(skb, p, mtype, dlen, curr_data)) { /* abuse overlimits to count when we receive metadata * but dont have an ops for it */ @@ -769,12 +768,12 @@ static int tcf_ife_decode(struct sk_buff *skb, const struct tc_action *a, /*XXX: check if we can do this at install time instead of current * send data path **/ -static int ife_get_sz(struct sk_buff *skb, struct tcf_ife_info *ife) +static int ife_get_sz(struct sk_buff *skb, struct tcf_ife_params *p) { - struct tcf_meta_info *e, *n; + struct tcf_meta_info *e; int tot_run_sz = 0, run_sz = 0; - list_for_each_entry_safe(e, n, &ife->metalist, metalist) { + list_for_each_entry_rcu(e, &p->metalist, metalist) { if (e->ops->check_presence) { run_sz = e->ops->check_presence(skb, e); tot_run_sz += run_sz; @@ -795,7 +794,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a, OUTERHDR:TOTMETALEN:{TLVHDR:Metadatum:TLVHDR..}:ORIGDATA where ORIGDATA = original ethernet header ... */ - u16 metalen = ife_get_sz(skb, ife); + u16 metalen = ife_get_sz(skb, p); int hdrm = metalen + skb->dev->hard_header_len + IFE_METAHDRLEN; unsigned int skboff = 0; int new_len = skb->len + hdrm; @@ -833,25 +832,21 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a, if (!ife_meta) goto drop; - spin_lock(&ife->tcf_lock); - /* XXX: we dont have a clever way of telling encode to * not repeat some of the computations that are done by * ops->presence_check... */ - list_for_each_entry(e, &ife->metalist, metalist) { + list_for_each_entry_rcu(e, &p->metalist, metalist) { if (e->ops->encode) { err = e->ops->encode(skb, (void *)(ife_meta + skboff), e); } if (err < 0) { /* too corrupt to keep around if overwritten */ - spin_unlock(&ife->tcf_lock); goto drop; } skboff += err; } - spin_unlock(&ife->tcf_lock); oethh = (struct ethhdr *)skb->data; if (!is_zero_ether_addr(p->eth_src)) diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c index 6654011dcd2b..1abfaf9d99f1 100644 --- a/net/sched/act_mpls.c +++ b/net/sched/act_mpls.c @@ -279,7 +279,7 @@ static int tcf_mpls_init(struct net *net, struct nlattr *nla, m = to_mpls(*a); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c index 26241d80ebe0..abb332dee836 100644 --- a/net/sched/act_nat.c +++ b/net/sched/act_nat.c @@ -81,7 +81,7 @@ static int tcf_nat_init(struct net *net, struct nlattr *nla, struct nlattr *est, if (err < 0) goto release_idr; - nparm = kzalloc(sizeof(*nparm), GFP_KERNEL); + nparm = kzalloc_obj(*nparm); if (!nparm) { err = -ENOMEM; goto release_idr; diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 4b65901397a8..bc20f08a2789 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -51,7 +51,7 @@ static struct tcf_pedit_key_ex *tcf_pedit_keys_ex_parse(struct nlattr *nla, if (!nla) return NULL; - keys_ex = kcalloc(n, sizeof(*k), GFP_KERNEL); + keys_ex = kzalloc_objs(*k, n); if (!keys_ex) return ERR_PTR(-ENOMEM); @@ -223,7 +223,7 @@ static int tcf_pedit_init(struct net *net, struct nlattr *nla, goto out_release; } - nparms = kzalloc(sizeof(*nparms), GFP_KERNEL); + nparms = kzalloc_obj(*nparms); if (!nparms) { ret = -ENOMEM; goto out_release; diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 0e1c61183379..12ea9e5a6005 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -151,7 +151,7 @@ static int tcf_police_init(struct net *net, struct nlattr *nla, goto failure; } - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (unlikely(!new)) { err = -ENOMEM; goto failure; diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 8c1d1554f657..a778cdba9258 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c @@ -126,7 +126,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, struct tcf_skbedit *d; u32 flags = 0, *priority = NULL, *mark = NULL, *mask = NULL; u16 *queue_mapping = NULL, *ptype = NULL; - u16 mapping_mod = 1; + u32 mapping_mod = 1; bool exists = false; int ret = 0, err; u32 index; @@ -194,6 +194,10 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, } mapping_mod = *queue_mapping_max - *queue_mapping + 1; + if (mapping_mod > U16_MAX) { + NL_SET_ERR_MSG_MOD(extack, "The range of queue_mapping is invalid."); + return -EINVAL; + } flags |= SKBEDIT_F_TXQ_SKBHASH; } if (*pure_flags & SKBEDIT_F_INHERITDSFIELD) @@ -238,7 +242,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, if (err < 0) goto release_idr; - params_new = kzalloc(sizeof(*params_new), GFP_KERNEL); + params_new = kzalloc_obj(*params_new); if (unlikely(!params_new)) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c index a9e0c1326e2a..23ca46138f04 100644 --- a/net/sched/act_skbmod.c +++ b/net/sched/act_skbmod.c @@ -185,7 +185,7 @@ static int tcf_skbmod_init(struct net *net, struct nlattr *nla, d = to_skbmod(*a); - p = kzalloc(sizeof(struct tcf_skbmod_params), GFP_KERNEL); + p = kzalloc_obj(struct tcf_skbmod_params); if (unlikely(!p)) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c index a74621797d69..6a375fdc63dd 100644 --- a/net/sched/act_vlan.c +++ b/net/sched/act_vlan.c @@ -233,7 +233,7 @@ static int tcf_vlan_init(struct net *net, struct nlattr *nla, v = to_vlan(*a); - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { err = -ENOMEM; goto put_chain; diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index ebca4b926dcf..4829c27446e3 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -84,7 +84,7 @@ tcf_exts_miss_cookie_base_alloc(struct tcf_exts *exts, struct tcf_proto *tp, if (WARN_ON(!handle || !tp->ops->get_exts)) return -EINVAL; - n = kzalloc(sizeof(*n), GFP_KERNEL); + n = kzalloc_obj(*n); if (!n) return -ENOMEM; @@ -377,7 +377,7 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol, struct tcf_proto *tp; int err; - tp = kzalloc(sizeof(*tp), GFP_KERNEL); + tp = kzalloc_obj(*tp); if (!tp) return ERR_PTR(-ENOBUFS); @@ -502,7 +502,7 @@ static struct tcf_chain *tcf_chain_create(struct tcf_block *block, ASSERT_BLOCK_LOCKED(block); - chain = kzalloc(sizeof(*chain), GFP_KERNEL); + chain = kzalloc_obj(*chain); if (!chain) return NULL; list_add_tail_rcu(&chain->list, &block->chain_list); @@ -918,7 +918,7 @@ tcf_chain0_head_change_cb_add(struct tcf_block *block, struct tcf_filter_chain_list_item *item; struct tcf_chain *chain0; - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) { NL_SET_ERR_MSG(extack, "Memory allocation for head change callback item failed"); return -ENOMEM; @@ -1016,7 +1016,7 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, { struct tcf_block *block; - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) { NL_SET_ERR_MSG(extack, "Memory allocation for block failed"); return ERR_PTR(-ENOMEM); @@ -1428,7 +1428,7 @@ static int tcf_block_owner_add(struct tcf_block *block, { struct tcf_block_owner_item *item; - item = kmalloc(sizeof(*item), GFP_KERNEL); + item = kmalloc_obj(*item); if (!item) return -ENOMEM; item->q = q; @@ -2228,6 +2228,11 @@ static bool is_qdisc_ingress(__u32 classid) return (TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS)); } +static bool is_ingress_or_clsact(struct tcf_block *block, struct Qdisc *q) +{ + return tcf_block_shared(block) || (q && !!(q->flags & TCQ_F_INGRESS)); +} + static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, struct netlink_ext_ack *extack) { @@ -2420,6 +2425,8 @@ static int tc_new_tfilter(struct sk_buff *skb, struct nlmsghdr *n, flags |= TCA_ACT_FLAGS_NO_RTNL; if (is_qdisc_ingress(parent)) flags |= TCA_ACT_FLAGS_AT_INGRESS; + if (is_ingress_or_clsact(block, q)) + flags |= TCA_ACT_FLAGS_AT_INGRESS_OR_CLSACT; err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh, flags, extack); if (err == 0) { @@ -3341,8 +3348,7 @@ int tcf_exts_init_ex(struct tcf_exts *exts, struct net *net, int action, * This reference might be taken later from tcf_exts_get_net(). */ exts->net = net; - exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), - GFP_KERNEL); + exts->actions = kzalloc_objs(struct tc_action *, TCA_ACT_MAX_PRIO); if (!exts->actions) return -ENOMEM; #endif diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index ecfaa4f9a04e..492cd9ce8d46 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -77,7 +77,7 @@ static int basic_init(struct tcf_proto *tp) { struct basic_head *head; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (head == NULL) return -ENOBUFS; INIT_LIST_HEAD(&head->flist); @@ -193,7 +193,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } - fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); + fnew = kzalloc_obj(*fnew); if (!fnew) return -ENOBUFS; diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index a32754a2658b..9a346b6221b3 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -242,7 +242,7 @@ static int cls_bpf_init(struct tcf_proto *tp) { struct cls_bpf_head *head; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (head == NULL) return -ENOBUFS; @@ -427,7 +427,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, if (ret < 0) return ret; - prog = kzalloc(sizeof(*prog), GFP_KERNEL); + prog = kzalloc_obj(*prog); if (!prog) return -ENOBUFS; diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 424252982d6a..680a5c308094 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -95,7 +95,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, if (head && handle != head->handle) return -ENOENT; - new = kzalloc(sizeof(*head), GFP_KERNEL); + new = kzalloc_obj(*head); if (!new) return -ENOBUFS; diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 5693b41b093f..339c664beff6 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -433,7 +433,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, return -EOPNOTSUPP; } - fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); + fnew = kzalloc_obj(*fnew); if (!fnew) return -ENOBUFS; @@ -583,7 +583,7 @@ static int flow_init(struct tcf_proto *tp) { struct flow_head *head; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (head == NULL) return -ENOBUFS; INIT_LIST_HEAD(&head->filters); diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index 7669371c1354..26070c892305 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -363,7 +363,7 @@ static int fl_init(struct tcf_proto *tp) { struct cls_fl_head *head; - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (!head) return -ENOBUFS; @@ -2237,7 +2237,7 @@ static struct fl_flow_mask *fl_create_new_mask(struct cls_fl_head *head, struct fl_flow_mask *newmask; int err; - newmask = kzalloc(sizeof(*newmask), GFP_KERNEL); + newmask = kzalloc_obj(*newmask); if (!newmask) return ERR_PTR(-ENOMEM); @@ -2376,13 +2376,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, goto errout_fold; } - mask = kzalloc(sizeof(struct fl_flow_mask), GFP_KERNEL); + mask = kzalloc_obj(struct fl_flow_mask); if (!mask) { err = -ENOBUFS; goto errout_fold; } - tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); + tb = kzalloc_objs(struct nlattr *, TCA_FLOWER_MAX + 1); if (!tb) { err = -ENOBUFS; goto errout_mask_alloc; @@ -2398,7 +2398,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb, goto errout_tb; } - fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); + fnew = kzalloc_obj(*fnew); if (!fnew) { err = -ENOBUFS; goto errout_tb; @@ -2815,7 +2815,7 @@ static void *fl_tmplt_create(struct net *net, struct tcf_chain *chain, if (!tca_opts) return ERR_PTR(-EINVAL); - tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); + tb = kzalloc_objs(struct nlattr *, TCA_FLOWER_MAX + 1); if (!tb) return ERR_PTR(-ENOBUFS); err = nla_parse_nested_deprecated(tb, TCA_FLOWER_MAX, @@ -2823,7 +2823,7 @@ static void *fl_tmplt_create(struct net *net, struct tcf_chain *chain, if (err) goto errout_tb; - tmplt = kzalloc(sizeof(*tmplt), GFP_KERNEL); + tmplt = kzalloc_obj(*tmplt); if (!tmplt) { err = -ENOMEM; goto errout_tb; diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index cdddc8695228..be81c108179d 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -262,7 +262,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, if (f->id != handle && handle) return -EINVAL; - fnew = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); + fnew = kzalloc_obj(struct fw_filter); if (!fnew) return -ENOBUFS; @@ -308,7 +308,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, if (tb[TCA_FW_MASK]) mask = nla_get_u32(tb[TCA_FW_MASK]); - head = kzalloc(sizeof(*head), GFP_KERNEL); + head = kzalloc_obj(*head); if (!head) return -ENOBUFS; head->mask = mask; @@ -316,7 +316,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb, rcu_assign_pointer(tp->root, head); } - f = kzalloc(sizeof(struct fw_filter), GFP_KERNEL); + f = kzalloc_obj(struct fw_filter); if (f == NULL) return -ENOBUFS; diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index f03bf5da39ee..6f126872c14a 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c @@ -189,7 +189,7 @@ static int mall_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return -ENOBUFS; diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index b9c58c040c30..bd6f945bd388 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -244,7 +244,7 @@ static int route4_init(struct tcf_proto *tp) { struct route4_head *head; - head = kzalloc(sizeof(struct route4_head), GFP_KERNEL); + head = kzalloc_obj(struct route4_head); if (head == NULL) return -ENOBUFS; @@ -438,7 +438,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp, h1 = to_hash(nhandle); b = rtnl_dereference(head->table[h1]); if (!b) { - b = kzalloc(sizeof(struct route4_bucket), GFP_KERNEL); + b = kzalloc_obj(struct route4_bucket); if (b == NULL) return -ENOBUFS; @@ -507,7 +507,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; err = -ENOBUFS; - f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL); + f = kzalloc_obj(struct route4_filter); if (!f) goto errout; diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 58e849c0acf4..9241c025aa74 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -364,7 +364,7 @@ static int u32_init(struct tcf_proto *tp) void *key = tc_u_common_ptr(tp); struct tc_u_common *tp_c = tc_u_common_find(key); - root_ht = kzalloc(struct_size(root_ht, ht, 1), GFP_KERNEL); + root_ht = kzalloc_flex(*root_ht, ht, 1); if (root_ht == NULL) return -ENOBUFS; @@ -375,7 +375,7 @@ static int u32_init(struct tcf_proto *tp) idr_init(&root_ht->handle_idr); if (tp_c == NULL) { - tp_c = kzalloc(sizeof(*tp_c), GFP_KERNEL); + tp_c = kzalloc_obj(*tp_c); if (tp_c == NULL) { kfree(root_ht); return -ENOBUFS; @@ -825,7 +825,7 @@ static struct tc_u_knode *u32_init_knode(struct net *net, struct tcf_proto *tp, struct tc_u32_sel *s = &n->sel; struct tc_u_knode *new; - new = kzalloc(struct_size(new, sel.keys, s->nkeys), GFP_KERNEL); + new = kzalloc_flex(*new, sel.keys, s->nkeys); if (!new) return NULL; @@ -974,7 +974,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, NL_SET_ERR_MSG_MOD(extack, "Divisor can only be used on a hash table"); return -EINVAL; } - ht = kzalloc(struct_size(ht, ht, divisor + 1), GFP_KERNEL); + ht = kzalloc_flex(*ht, ht, divisor + 1); if (ht == NULL) return -ENOBUFS; if (handle == 0) { @@ -1104,7 +1104,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb, goto erridr; } - n = kzalloc(struct_size(n, sel.keys, s->nkeys), GFP_KERNEL); + n = kzalloc_flex(*n, sel.keys, s->nkeys); if (n == NULL) { err = -ENOBUFS; goto erridr; @@ -1417,7 +1417,7 @@ static int u32_dump(struct net *net, struct tcf_proto *tp, void *fh, goto nla_put_failure; } #ifdef CONFIG_CLS_U32_PERF - gpf = kzalloc(struct_size(gpf, kcnts, n->sel.nkeys), GFP_KERNEL); + gpf = kzalloc_flex(*gpf, kcnts, n->sel.nkeys); if (!gpf) goto nla_put_failure; @@ -1480,9 +1480,7 @@ static int __init init_u32(void) #ifdef CONFIG_NET_CLS_ACT pr_info(" Actions configured\n"); #endif - tc_u_common_hash = kvmalloc_array(U32_HASH_SIZE, - sizeof(struct hlist_head), - GFP_KERNEL); + tc_u_common_hash = kvmalloc_objs(struct hlist_head, U32_HASH_SIZE); if (!tc_u_common_hash) return -ENOMEM; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 3f2e707a11d1..48bdd77df0a3 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -927,7 +927,7 @@ static int em_meta_change(struct net *net, void *data, int len, TCF_META_ID(hdr->right.kind) > TCF_META_ID_MAX) goto errout; - meta = kzalloc(sizeof(*meta), GFP_KERNEL); + meta = kzalloc_obj(*meta); if (meta == NULL) { err = -ENOMEM; goto errout; diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 692e2be1793e..343f1aebeec2 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c @@ -84,7 +84,7 @@ static int em_text_change(struct net *net, void *data, int len, return -EAGAIN; } - tm = kmalloc(sizeof(*tm), GFP_KERNEL); + tm = kmalloc_obj(*tm); if (tm == NULL) { textsearch_destroy(ts_conf); return -ENOBUFS; diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 443c116e8663..cc43e3f7574f 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -437,7 +437,7 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, } } - rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); + rtab = kmalloc_obj(*rtab); if (rtab) { rtab->rate = *r; rtab->refcnt = 1; @@ -530,7 +530,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt, return ERR_PTR(-EINVAL); } - stab = kmalloc(struct_size(stab, data, tsize), GFP_KERNEL); + stab = kmalloc_flex(*stab, data, tsize); if (!stab) return ERR_PTR(-ENOMEM); @@ -668,7 +668,7 @@ static struct hlist_head *qdisc_class_hash_alloc(unsigned int n) struct hlist_head *h; unsigned int i; - h = kvmalloc_array(n, sizeof(struct hlist_head), GFP_KERNEL); + h = kvmalloc_objs(struct hlist_head, n); if (h != NULL) { for (i = 0; i < n; i++) diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c index d2bbd5654d5b..9efe23f8371b 100644 --- a/net/sched/sch_cake.c +++ b/net/sched/sch_cake.c @@ -391,8 +391,8 @@ static const u32 inv_sqrt_cache[REC_INV_SQRT_CACHE] = { 1239850263, 1191209601, 1147878294, 1108955788 }; -static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu, - u64 target_ns, u64 rtt_est_ns); +static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust); + /* http://en.wikipedia.org/wiki/Methods_of_computing_square_roots * new_invsqrt = (invsqrt / 2) * (3 - count * invsqrt^2) * @@ -2013,7 +2013,8 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) u64 delay; u32 len; - if (q->config->is_shared && now - q->last_checked_active >= q->config->sync_time) { + if (q->config->is_shared && q->rate_ns && + now - q->last_checked_active >= q->config->sync_time) { struct net_device *dev = qdisc_dev(sch); struct cake_sched_data *other_priv; u64 new_rate = q->config->rate_bps; @@ -2039,12 +2040,9 @@ static struct sk_buff *cake_dequeue(struct Qdisc *sch) if (num_active_qs > 1) new_rate = div64_u64(q->config->rate_bps, num_active_qs); - /* mtu = 0 is used to only update the rate and not mess with cobalt params */ - cake_set_rate(b, new_rate, 0, 0, 0); + cake_configure_rates(sch, new_rate, true); q->last_checked_active = now; q->active_queues = num_active_qs; - q->rate_ns = b->tin_rate_ns; - q->rate_shft = b->tin_rate_shft; } begin: @@ -2361,12 +2359,10 @@ static void cake_set_rate(struct cake_tin_data *b, u64 rate, u32 mtu, b->cparams.p_dec = 1 << 20; /* 1/4096 */ } -static int cake_config_besteffort(struct Qdisc *sch) +static int cake_config_besteffort(struct Qdisc *sch, u64 rate, u32 mtu) { struct cake_sched_data *q = qdisc_priv(sch); struct cake_tin_data *b = &q->tins[0]; - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->config->rate_bps; q->tin_cnt = 1; @@ -2380,12 +2376,10 @@ static int cake_config_besteffort(struct Qdisc *sch) return 0; } -static int cake_config_precedence(struct Qdisc *sch) +static int cake_config_precedence(struct Qdisc *sch, u64 rate, u32 mtu) { /* convert high-level (user visible) parameters into internal format */ struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->config->rate_bps; u32 quantum = 256; u32 i; @@ -2456,7 +2450,7 @@ static int cake_config_precedence(struct Qdisc *sch) * Total 12 traffic classes. */ -static int cake_config_diffserv8(struct Qdisc *sch) +static int cake_config_diffserv8(struct Qdisc *sch, u64 rate, u32 mtu) { /* Pruned list of traffic classes for typical applications: * @@ -2473,8 +2467,6 @@ static int cake_config_diffserv8(struct Qdisc *sch) */ struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->config->rate_bps; u32 quantum = 256; u32 i; @@ -2504,7 +2496,7 @@ static int cake_config_diffserv8(struct Qdisc *sch) return 0; } -static int cake_config_diffserv4(struct Qdisc *sch) +static int cake_config_diffserv4(struct Qdisc *sch, u64 rate, u32 mtu) { /* Further pruned list of traffic classes for four-class system: * @@ -2517,8 +2509,6 @@ static int cake_config_diffserv4(struct Qdisc *sch) */ struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->config->rate_bps; u32 quantum = 1024; q->tin_cnt = 4; @@ -2546,7 +2536,7 @@ static int cake_config_diffserv4(struct Qdisc *sch) return 0; } -static int cake_config_diffserv3(struct Qdisc *sch) +static int cake_config_diffserv3(struct Qdisc *sch, u64 rate, u32 mtu) { /* Simplified Diffserv structure with 3 tins. * Latency Sensitive (CS7, CS6, EF, VA, TOS4) @@ -2554,8 +2544,6 @@ static int cake_config_diffserv3(struct Qdisc *sch) * Low Priority (LE, CS1) */ struct cake_sched_data *q = qdisc_priv(sch); - u32 mtu = psched_mtu(qdisc_dev(sch)); - u64 rate = q->config->rate_bps; u32 quantum = 1024; q->tin_cnt = 3; @@ -2580,32 +2568,33 @@ static int cake_config_diffserv3(struct Qdisc *sch) return 0; } -static void cake_reconfigure(struct Qdisc *sch) +static void cake_configure_rates(struct Qdisc *sch, u64 rate, bool rate_adjust) { + u32 mtu = likely(rate_adjust) ? 0 : psched_mtu(qdisc_dev(sch)); struct cake_sched_data *qd = qdisc_priv(sch); struct cake_sched_config *q = qd->config; int c, ft; switch (q->tin_mode) { case CAKE_DIFFSERV_BESTEFFORT: - ft = cake_config_besteffort(sch); + ft = cake_config_besteffort(sch, rate, mtu); break; case CAKE_DIFFSERV_PRECEDENCE: - ft = cake_config_precedence(sch); + ft = cake_config_precedence(sch, rate, mtu); break; case CAKE_DIFFSERV_DIFFSERV8: - ft = cake_config_diffserv8(sch); + ft = cake_config_diffserv8(sch, rate, mtu); break; case CAKE_DIFFSERV_DIFFSERV4: - ft = cake_config_diffserv4(sch); + ft = cake_config_diffserv4(sch, rate, mtu); break; case CAKE_DIFFSERV_DIFFSERV3: default: - ft = cake_config_diffserv3(sch); + ft = cake_config_diffserv3(sch, rate, mtu); break; } @@ -2616,6 +2605,14 @@ static void cake_reconfigure(struct Qdisc *sch) qd->rate_ns = qd->tins[ft].tin_rate_ns; qd->rate_shft = qd->tins[ft].tin_rate_shft; +} + +static void cake_reconfigure(struct Qdisc *sch) +{ + struct cake_sched_data *qd = qdisc_priv(sch); + struct cake_sched_config *q = qd->config; + + cake_configure_rates(sch, qd->config->rate_bps, false); if (q->buffer_config_limit) { qd->buffer_limit = q->buffer_config_limit; @@ -2849,8 +2846,7 @@ static int cake_init(struct Qdisc *sch, struct nlattr *opt, for (i = 1; i <= CAKE_QUEUES; i++) quantum_div[i] = 65535 / i; - qd->tins = kvcalloc(CAKE_MAX_TINS, sizeof(struct cake_tin_data), - GFP_KERNEL); + qd->tins = kvzalloc_objs(struct cake_tin_data, CAKE_MAX_TINS); if (!qd->tins) return -ENOMEM; diff --git a/net/sched/sch_choke.c b/net/sched/sch_choke.c index 59e7bdf5063e..94df8e741a97 100644 --- a/net/sched/sch_choke.c +++ b/net/sched/sch_choke.c @@ -370,7 +370,7 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt, if (mask != q->tab_mask) { struct sk_buff **ntab; - ntab = kvcalloc(mask + 1, sizeof(struct sk_buff *), GFP_KERNEL); + ntab = kvzalloc_objs(struct sk_buff *, mask + 1); if (!ntab) return -ENOMEM; diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 9b6d79bd8737..01335a49e091 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c @@ -105,7 +105,7 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid, return 0; } - cl = kzalloc(sizeof(struct drr_class), GFP_KERNEL); + cl = kzalloc_obj(struct drr_class); if (cl == NULL) return -ENOBUFS; diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c index 306e046276d4..a4b07b661b77 100644 --- a/net/sched/sch_ets.c +++ b/net/sched/sch_ets.c @@ -115,12 +115,12 @@ static void ets_offload_change(struct Qdisc *sch) struct ets_sched *q = qdisc_priv(sch); struct tc_ets_qopt_offload qopt; unsigned int w_psum_prev = 0; - unsigned int q_psum = 0; - unsigned int q_sum = 0; unsigned int quantum; unsigned int w_psum; unsigned int weight; unsigned int i; + u64 q_psum = 0; + u64 q_sum = 0; if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) return; @@ -138,8 +138,12 @@ static void ets_offload_change(struct Qdisc *sch) for (i = 0; i < q->nbands; i++) { quantum = q->classes[i].quantum; - q_psum += quantum; - w_psum = quantum ? q_psum * 100 / q_sum : 0; + if (quantum) { + q_psum += quantum; + w_psum = div64_u64(q_psum * 100, q_sum); + } else { + w_psum = 0; + } weight = w_psum - w_psum_prev; w_psum_prev = w_psum; diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index 80235e85f844..05084c9af48e 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -827,6 +827,7 @@ static void fq_reset(struct Qdisc *sch) for (idx = 0; idx < FQ_BANDS; idx++) { q->band_flows[idx].new_flows.first = NULL; q->band_flows[idx].old_flows.first = NULL; + q->band_pkt_count[idx] = 0; } q->delayed = RB_ROOT; q->flows = 0; diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index dc187c7f06b1..8181b52dd9a8 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -496,9 +496,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt, goto init_failure; if (!q->flows) { - q->flows = kvcalloc(q->flows_cnt, - sizeof(struct fq_codel_flow), - GFP_KERNEL); + q->flows = kvzalloc_objs(struct fq_codel_flow, q->flows_cnt); if (!q->flows) { err = -ENOMEM; goto init_failure; diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c index 7b96bc3ff891..d8ac3519e937 100644 --- a/net/sched/sch_fq_pie.c +++ b/net/sched/sch_fq_pie.c @@ -448,8 +448,7 @@ static int fq_pie_init(struct Qdisc *sch, struct nlattr *opt, if (err) goto init_failure; - q->flows = kvcalloc(q->flows_cnt, sizeof(struct fq_pie_flow), - GFP_KERNEL); + q->flows = kvzalloc_objs(struct fq_pie_flow, q->flows_cnt); if (!q->flows) { err = -ENOMEM; goto init_failure; diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 532fde548b88..6706faba95b9 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -359,7 +359,7 @@ static int gred_offload_dump_stats(struct Qdisc *sch) unsigned int i; int ret; - hw_stats = kzalloc(sizeof(*hw_stats), GFP_KERNEL); + hw_stats = kzalloc_obj(*hw_stats); if (!hw_stats) return -ENOMEM; @@ -700,7 +700,7 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt, prio = ctl->prio; } - prealloc = kzalloc(sizeof(*prealloc), GFP_KERNEL); + prealloc = kzalloc_obj(*prealloc); sch_tree_lock(sch); err = gred_change_vq(sch, ctl->DP, ctl, prio, stab, max_P, &prealloc, @@ -757,7 +757,7 @@ static int gred_init(struct Qdisc *sch, struct nlattr *opt, * psched_mtu(qdisc_dev(sch)); if (qdisc_dev(sch)->netdev_ops->ndo_setup_tc) { - table->opt = kzalloc(sizeof(*table->opt), GFP_KERNEL); + table->opt = kzalloc_obj(*table->opt); if (!table->opt) return -ENOMEM; } diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index d8fd35da32a7..b5657ffbbf84 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1025,7 +1025,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (rsc == NULL && fsc == NULL) return -EINVAL; - cl = kzalloc(sizeof(struct hfsc_class), GFP_KERNEL); + cl = kzalloc_obj(struct hfsc_class); if (cl == NULL) return -ENOBUFS; diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index 2d4855e28a28..95e5d9bfd9c8 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c @@ -230,7 +230,7 @@ static struct hh_flow_state *alloc_new_hh(struct list_head *head, return NULL; } /* Create new entry. */ - flow = kzalloc(sizeof(struct hh_flow_state), GFP_ATOMIC); + flow = kzalloc_obj(struct hh_flow_state, GFP_ATOMIC); if (!flow) return NULL; @@ -604,8 +604,7 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt, if (!q->hh_flows) { /* Initialize heavy-hitter flow table. */ - q->hh_flows = kvcalloc(HH_FLOWS_CNT, sizeof(struct list_head), - GFP_KERNEL); + q->hh_flows = kvzalloc_objs(struct list_head, HH_FLOWS_CNT); if (!q->hh_flows) return -ENOMEM; for (i = 0; i < HH_FLOWS_CNT; i++) diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index b5e40c51655a..cf6cd4ccfa20 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c @@ -1095,9 +1095,8 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt, } q->num_direct_qdiscs = dev->real_num_tx_queues; - q->direct_qdiscs = kcalloc(q->num_direct_qdiscs, - sizeof(*q->direct_qdiscs), - GFP_KERNEL); + q->direct_qdiscs = kzalloc_objs(*q->direct_qdiscs, + q->num_direct_qdiscs); if (!q->direct_qdiscs) return -ENOMEM; } @@ -1845,7 +1844,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, goto failure; } err = -ENOBUFS; - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) goto failure; diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c index bb94cd577943..0ed199fa18f0 100644 --- a/net/sched/sch_mq.c +++ b/net/sched/sch_mq.c @@ -82,8 +82,7 @@ int mq_init_common(struct Qdisc *sch, struct nlattr *opt, return -EOPNOTSUPP; /* pre-allocate qdiscs, attachment can't fail */ - priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]), - GFP_KERNEL); + priv->qdiscs = kzalloc_objs(priv->qdiscs[0], dev->num_tx_queues); if (!priv->qdiscs) return -ENOMEM; diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c index f3e5ef9a9592..b83276409416 100644 --- a/net/sched/sch_mqprio.c +++ b/net/sched/sch_mqprio.c @@ -388,8 +388,7 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt, } /* pre-allocate qdisc, attachment can't fail */ - priv->qdiscs = kcalloc(dev->num_tx_queues, sizeof(priv->qdiscs[0]), - GFP_KERNEL); + priv->qdiscs = kzalloc_objs(priv->qdiscs[0], dev->num_tx_queues); if (!priv->qdiscs) return -ENOMEM; diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c index 06e03f5cd7ce..9f822fee113d 100644 --- a/net/sched/sch_multiq.c +++ b/net/sched/sch_multiq.c @@ -249,7 +249,7 @@ static int multiq_init(struct Qdisc *sch, struct nlattr *opt, q->max_bands = qdisc_dev(sch)->num_tx_queues; - q->queues = kcalloc(q->max_bands, sizeof(struct Qdisc *), GFP_KERNEL); + q->queues = kzalloc_objs(struct Qdisc *, q->max_bands); if (!q->queues) return -ENOBUFS; for (i = 0; i < q->max_bands; i++) diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 32a5f3304046..5de1c932944a 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -814,7 +814,7 @@ static int get_dist_table(struct disttable **tbl, const struct nlattr *attr) if (!n || n > NETEM_DIST_MAX) return -EINVAL; - d = kvmalloc(struct_size(d, table, n), GFP_KERNEL); + d = kvmalloc_flex(*d, table, n); if (!d) return -ENOMEM; diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index e7778413e72f..699e45873f86 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c @@ -392,7 +392,7 @@ static int qfq_change_agg(struct Qdisc *sch, struct qfq_class *cl, u32 weight, new_agg = qfq_find_agg(q, lmax, weight); if (new_agg == NULL) { /* create new aggregate */ - new_agg = kzalloc(sizeof(*new_agg), GFP_ATOMIC); + new_agg = kzalloc_obj(*new_agg, GFP_ATOMIC); if (new_agg == NULL) return -ENOBUFS; qfq_init_agg(q, new_agg, lmax, weight); @@ -476,7 +476,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, } /* create and init new class */ - cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL); + cl = kzalloc_obj(struct qfq_class); if (cl == NULL) return -ENOBUFS; @@ -508,7 +508,7 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, new_agg = qfq_find_agg(q, lmax, weight); if (new_agg == NULL) { /* create new aggregate */ sch_tree_unlock(sch); - new_agg = kzalloc(sizeof(*new_agg), GFP_KERNEL); + new_agg = kzalloc_obj(*new_agg); if (new_agg == NULL) { err = -ENOBUFS; gen_kill_estimator(&cl->rate_est); diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 96eb2f122973..503d7d3ca081 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c @@ -668,7 +668,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt, ctl_v1->Wlog, ctl_v1->Scell_log, NULL)) return -EINVAL; if (ctl_v1 && ctl_v1->qth_min) { - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (!p) return -ENOMEM; } diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c index 300d577b3286..f721c03514f6 100644 --- a/net/sched/sch_taprio.c +++ b/net/sched/sch_taprio.c @@ -1103,7 +1103,7 @@ static int parse_sched_list(struct taprio_sched *q, struct nlattr *list, continue; } - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { NL_SET_ERR_MSG(extack, "Not enough memory for entry"); return -ENOMEM; @@ -1376,8 +1376,7 @@ static struct tc_taprio_qopt_offload *taprio_offload_alloc(int num_entries) { struct __tc_taprio_qopt_offload *__offload; - __offload = kzalloc(struct_size(__offload, offload.entries, num_entries), - GFP_KERNEL); + __offload = kzalloc_flex(*__offload, offload.entries, num_entries); if (!__offload) return NULL; @@ -1870,7 +1869,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt, if (err) return err; - new_admin = kzalloc(sizeof(*new_admin), GFP_KERNEL); + new_admin = kzalloc_obj(*new_admin); if (!new_admin) { NL_SET_ERR_MSG(extack, "Not enough memory for a new schedule"); return -ENOMEM; @@ -2091,8 +2090,7 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt, return -EOPNOTSUPP; } - q->qdiscs = kcalloc(dev->num_tx_queues, sizeof(q->qdiscs[0]), - GFP_KERNEL); + q->qdiscs = kzalloc_objs(q->qdiscs[0], dev->num_tx_queues); if (!q->qdiscs) return -ENOMEM; diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 6e4bdaa876ed..783300d8b019 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -315,6 +315,7 @@ static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev) if (__netif_tx_trylock(slave_txq)) { unsigned int length = qdisc_pkt_len(skb); + skb->dev = slave; if (!netif_xmit_frozen_or_stopped(slave_txq) && netdev_start_xmit(skb, slave, slave_txq, false) == NETDEV_TX_OK) { diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 5793d71852b8..62d3cc155809 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -289,7 +289,7 @@ struct sctp_association *sctp_association_new(const struct sctp_endpoint *ep, { struct sctp_association *asoc; - asoc = kzalloc(sizeof(*asoc), gfp); + asoc = kzalloc_obj(*asoc, gfp); if (!asoc) goto fail; diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 82aad477590e..be9782760f50 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c @@ -82,7 +82,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp) struct sctp_shared_key *new; /* Allocate the shared key container */ - new = kzalloc(sizeof(struct sctp_shared_key), gfp); + new = kzalloc_obj(struct sctp_shared_key, gfp); if (!new) return NULL; @@ -931,8 +931,8 @@ int sctp_auth_init(struct sctp_endpoint *ep, gfp_t gfp) if (!ep->auth_hmacs_list) { struct sctp_hmac_algo_param *auth_hmacs; - auth_hmacs = kzalloc(struct_size(auth_hmacs, hmac_ids, - SCTP_AUTH_NUM_HMACS), gfp); + auth_hmacs = kzalloc_flex(*auth_hmacs, hmac_ids, + SCTP_AUTH_NUM_HMACS, gfp); if (!auth_hmacs) goto nomem; /* Initialize the HMACS parameter. diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 6b95d3ba8fe1..75e3e61d494e 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -147,7 +147,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new, struct sctp_sockaddr_entry *addr; /* Add the address to the bind address list. */ - addr = kzalloc(sizeof(*addr), gfp); + addr = kzalloc_obj(*addr, gfp); if (!addr) return -ENOMEM; diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index c655b571ca01..5b889e89e9f2 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -47,7 +47,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) static struct sctp_datamsg *sctp_datamsg_new(gfp_t gfp) { struct sctp_datamsg *msg; - msg = kmalloc(sizeof(struct sctp_datamsg), gfp); + msg = kmalloc_obj(struct sctp_datamsg, gfp); if (msg) { sctp_datamsg_init(msg); SCTP_DBG_OBJCNT_INC(datamsg); diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 31e989dfe846..8d342b514142 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -135,7 +135,7 @@ struct sctp_endpoint *sctp_endpoint_new(struct sock *sk, gfp_t gfp) struct sctp_endpoint *ep; /* Build a local endpoint. */ - ep = kzalloc(sizeof(*ep), gfp); + ep = kzalloc_obj(*ep, gfp); if (!ep) goto fail; diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 531cb0690007..53a5c027f8e3 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -83,7 +83,7 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev, switch (ev) { case NETDEV_UP: - addr = kzalloc(sizeof(*addr), GFP_ATOMIC); + addr = kzalloc_obj(*addr, GFP_ATOMIC); if (addr) { addr->a.v6.sin6_family = AF_INET6; addr->a.v6.sin6_addr = ifa->addr; @@ -471,7 +471,7 @@ static void sctp_v6_copy_addrlist(struct list_head *addrlist, read_lock_bh(&in6_dev->lock); list_for_each_entry(ifp, &in6_dev->addr_list, if_list) { /* Add the address to the local list. */ - addr = kzalloc(sizeof(*addr), GFP_ATOMIC); + addr = kzalloc_obj(*addr, GFP_ATOMIC); if (addr) { addr->a.v6.sin6_family = AF_INET6; addr->a.v6.sin6_addr = ifp->addr; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2c3398f75d76..828a59b8e7bf 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -86,7 +86,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist, in_dev_for_each_ifa_rcu(ifa, in_dev) { /* Add the address to the local list. */ - addr = kzalloc(sizeof(*addr), GFP_ATOMIC); + addr = kzalloc_obj(*addr, GFP_ATOMIC); if (addr) { addr->a.v4.sin_family = AF_INET; addr->a.v4.sin_addr.s_addr = ifa->ifa_local; @@ -774,7 +774,7 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev, switch (ev) { case NETDEV_UP: - addr = kzalloc(sizeof(*addr), GFP_ATOMIC); + addr = kzalloc_obj(*addr, GFP_ATOMIC); if (addr) { addr->a.v4.sin_family = AF_INET; addr->a.v4.sin_addr.s_addr = ifa->ifa_local; @@ -1538,7 +1538,7 @@ static __init int sctp_init(void) /* Allocate and initialize the endpoint hash table. */ sctp_ep_hashsize = 64; sctp_ep_hashtable = - kmalloc_array(64, sizeof(struct sctp_hashbucket), GFP_KERNEL); + kmalloc_objs(struct sctp_hashbucket, 64); if (!sctp_ep_hashtable) { pr_err("Failed endpoint_hash alloc\n"); status = -ENOMEM; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 2493a5b1fa3c..05fb00c9c335 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -828,7 +828,7 @@ static int sctp_send_asconf_del_ip(struct sock *sk, if (asoc->asconf_addr_del_pending) continue; asoc->asconf_addr_del_pending = - kzalloc(sizeof(union sctp_addr), GFP_ATOMIC); + kzalloc_obj(union sctp_addr, GFP_ATOMIC); if (asoc->asconf_addr_del_pending == NULL) { retval = -ENOMEM; goto out; diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 0615e4426341..c2247793c88b 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c @@ -166,7 +166,7 @@ int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid) struct sctp_stream_out_ext *soute; int ret; - soute = kzalloc(sizeof(*soute), GFP_KERNEL); + soute = kzalloc_obj(*soute); if (!soute) return -ENOMEM; SCTP_SO(stream, sid)->ext = soute; diff --git a/net/sctp/stream_sched_prio.c b/net/sctp/stream_sched_prio.c index fb6c55e5615d..bd4f98db2822 100644 --- a/net/sctp/stream_sched_prio.c +++ b/net/sctp/stream_sched_prio.c @@ -42,7 +42,7 @@ static struct sctp_stream_priorities *sctp_sched_prio_new_head( { struct sctp_stream_priorities *p; - p = kmalloc(sizeof(*p), gfp); + p = kmalloc_obj(*p, gfp); if (!p) return NULL; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0c56d9673cc1..6ea55b9fbde4 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -92,7 +92,7 @@ struct sctp_transport *sctp_transport_new(struct net *net, { struct sctp_transport *transport; - transport = kzalloc(sizeof(*transport), gfp); + transport = kzalloc_obj(*transport, gfp); if (!transport) return NULL; diff --git a/net/shaper/shaper.c b/net/shaper/shaper.c index 7101a48bce54..3fd6629cb999 100644 --- a/net/shaper/shaper.c +++ b/net/shaper/shaper.c @@ -272,7 +272,7 @@ net_shaper_hierarchy_setup(struct net_shaper_binding *binding) if (hierarchy) return hierarchy; - hierarchy = kmalloc(sizeof(*hierarchy), GFP_KERNEL); + hierarchy = kmalloc_obj(*hierarchy); if (!hierarchy) return NULL; @@ -329,7 +329,7 @@ static int net_shaper_pre_insert(struct net_shaper_binding *binding, id_allocated = true; } - cur = kzalloc(sizeof(*cur), GFP_KERNEL); + cur = kzalloc_obj(*cur); if (!cur) { ret = -ENOMEM; goto free_id; @@ -759,11 +759,7 @@ int net_shaper_nl_get_doit(struct sk_buff *skb, struct genl_info *info) if (ret) goto free_msg; - ret = genlmsg_reply(msg, info); - if (ret) - goto free_msg; - - return 0; + return genlmsg_reply(msg, info); free_msg: nlmsg_free(msg); @@ -1033,8 +1029,7 @@ static int net_shaper_pre_del_node(struct net_shaper_binding *binding, return -EINVAL; } - leaves = kcalloc(shaper->leaves, sizeof(struct net_shaper), - GFP_KERNEL); + leaves = kzalloc_objs(struct net_shaper, shaper->leaves); if (!leaves) return -ENOMEM; @@ -1314,10 +1309,7 @@ int net_shaper_nl_cap_get_doit(struct sk_buff *skb, struct genl_info *info) if (ret) goto free_msg; - ret = genlmsg_reply(msg, info); - if (ret) - goto free_msg; - return 0; + return genlmsg_reply(msg, info); free_msg: nlmsg_free(msg); diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index d8201eb3ac5f..d0119afcc6a1 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -124,7 +124,9 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk, struct request_sock *req, struct dst_entry *dst, struct request_sock *req_unhash, - bool *own_req) + bool *own_req, + void (*opt_child_init)(struct sock *newsk, + const struct sock *sk)) { struct smc_sock *smc; struct sock *child; @@ -142,7 +144,7 @@ static struct sock *smc_tcp_syn_recv_sock(const struct sock *sk, /* passthrough to original syn recv sock fct */ child = smc->ori_af_ops->syn_recv_sock(sk, skb, req, dst, req_unhash, - own_req); + own_req, opt_child_init); /* child must not inherit smc or its ops */ if (child) { rcu_assign_sk_user_data(child, NULL); @@ -1195,7 +1197,7 @@ void smc_fill_gid_list(struct smc_link_group *lgr, memset(gidlist, 0, sizeof(*gidlist)); memcpy(gidlist->list[gidlist->len++], known_gid, SMC_GID_SIZE); - alt_ini = kzalloc(sizeof(*alt_ini), GFP_KERNEL); + alt_ini = kzalloc_obj(*alt_ini); if (!alt_ini) goto out; @@ -1522,7 +1524,7 @@ static int __smc_connect(struct smc_sock *smc) return smc_connect_decline_fallback(smc, SMC_CLC_DECL_IPSEC, version); - ini = kzalloc(sizeof(*ini), GFP_KERNEL); + ini = kzalloc_obj(*ini); if (!ini) return smc_connect_decline_fallback(smc, SMC_CLC_DECL_MEM, version); @@ -2470,7 +2472,7 @@ static void smc_listen_work(struct work_struct *work) /* do inband token exchange - * wait for and receive SMC Proposal CLC message */ - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) { rc = SMC_CLC_DECL_MEM; goto out_decl; @@ -2490,7 +2492,7 @@ static void smc_listen_work(struct work_struct *work) goto out_decl; } - ini = kzalloc(sizeof(*ini), GFP_KERNEL); + ini = kzalloc_obj(*ini); if (!ini) { rc = SMC_CLC_DECL_MEM; goto out_decl; diff --git a/net/smc/smc_clc.c b/net/smc/smc_clc.c index 87c87edadde7..c38fc7bf0a7e 100644 --- a/net/smc/smc_clc.c +++ b/net/smc/smc_clc.c @@ -88,7 +88,7 @@ static int smc_clc_ueid_add(char *ueid) return -EINVAL; /* add a new ueid entry to the ueid table if there isn't one */ - new_ueid = kzalloc(sizeof(*new_ueid), GFP_KERNEL); + new_ueid = kzalloc_obj(*new_ueid); if (!new_ueid) return -ENOMEM; memcpy(new_ueid->eid, ueid, SMC_MAX_EID_LEN); @@ -861,7 +861,7 @@ int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini) struct kvec vec[8]; struct msghdr msg; - pclc = kzalloc(sizeof(*pclc), GFP_KERNEL); + pclc = kzalloc_obj(*pclc); if (!pclc) return -ENOMEM; diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c index e4eabc83719e..e2d083daeb7e 100644 --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -905,7 +905,7 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini) } } - lgr = kzalloc(sizeof(*lgr), GFP_KERNEL); + lgr = kzalloc_obj(*lgr); if (!lgr) { rc = SMC_CLC_DECL_MEM; goto ism_put_vlan; @@ -2320,7 +2320,7 @@ static struct smc_buf_desc *smcr_new_buf_create(struct smc_link_group *lgr, struct smc_buf_desc *buf_desc; /* try to alloc a new buffer */ - buf_desc = kzalloc(sizeof(*buf_desc), GFP_KERNEL); + buf_desc = kzalloc_obj(*buf_desc); if (!buf_desc) return ERR_PTR(-ENOMEM); @@ -2394,7 +2394,7 @@ static struct smc_buf_desc *smcd_new_buf_create(struct smc_link_group *lgr, int rc; /* try to alloc a new DMB */ - buf_desc = kzalloc(sizeof(*buf_desc), GFP_KERNEL); + buf_desc = kzalloc_obj(*buf_desc); if (!buf_desc) return ERR_PTR(-ENOMEM); if (is_dmb) { @@ -2578,7 +2578,7 @@ int smcd_buf_attach(struct smc_sock *smc) struct smc_buf_desc *buf_desc; int rc; - buf_desc = kzalloc(sizeof(*buf_desc), GFP_KERNEL); + buf_desc = kzalloc_obj(*buf_desc); if (!buf_desc) return -ENOMEM; diff --git a/net/smc/smc_ib.c b/net/smc/smc_ib.c index 1154907c5c05..9bb495707445 100644 --- a/net/smc/smc_ib.c +++ b/net/smc/smc_ib.c @@ -944,7 +944,7 @@ static int smc_ib_add_dev(struct ib_device *ibdev) if (ibdev->node_type != RDMA_NODE_IB_CA) return -EOPNOTSUPP; - smcibdev = kzalloc(sizeof(*smcibdev), GFP_KERNEL); + smcibdev = kzalloc_obj(*smcibdev); if (!smcibdev) return -ENOMEM; diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c index 7b228ca2f96a..e0dba2c7b6e3 100644 --- a/net/smc/smc_ism.c +++ b/net/smc/smc_ism.c @@ -142,7 +142,7 @@ int smc_ism_get_vlan(struct smcd_dev *smcd, unsigned short vlanid) return -EOPNOTSUPP; /* create new vlan entry, in case we need it */ - new_vlan = kzalloc(sizeof(*new_vlan), GFP_KERNEL); + new_vlan = kzalloc_obj(*new_vlan); if (!new_vlan) return -ENOMEM; new_vlan->vlanid = vlanid; @@ -467,11 +467,10 @@ static struct smcd_dev *smcd_alloc_dev(const char *name, int max_dmbs) { struct smcd_dev *smcd; - smcd = kzalloc(sizeof(*smcd), GFP_KERNEL); + smcd = kzalloc_obj(*smcd); if (!smcd) return NULL; - smcd->conn = kcalloc(max_dmbs, sizeof(struct smc_connection *), - GFP_KERNEL); + smcd->conn = kzalloc_objs(struct smc_connection *, max_dmbs); if (!smcd->conn) goto free_smcd; @@ -582,7 +581,7 @@ static void smcd_handle_event(struct dibs_dev *dibs, if (smcd->going_away) return; /* copy event to event work queue, and let it be handled there */ - wrk = kmalloc(sizeof(*wrk), GFP_ATOMIC); + wrk = kmalloc_obj(*wrk, GFP_ATOMIC); if (!wrk) return; INIT_WORK(&wrk->work, smc_ism_event_work); diff --git a/net/smc/smc_llc.c b/net/smc/smc_llc.c index f5d5eb617526..954b2ff1815c 100644 --- a/net/smc/smc_llc.c +++ b/net/smc/smc_llc.c @@ -1040,7 +1040,7 @@ int smc_llc_cli_add_link(struct smc_link *link, struct smc_llc_qentry *qentry) if (!llc->qp_mtu) goto out_reject; - ini = kzalloc(sizeof(*ini), GFP_KERNEL); + ini = kzalloc_obj(*ini); if (!ini) { rc = -ENOMEM; goto out_reject; @@ -1180,7 +1180,7 @@ static void smc_llc_cli_add_link_invite(struct smc_link *link, if (lgr->type == SMC_LGR_SINGLE && lgr->max_links <= 1) goto out; - ini = kzalloc(sizeof(*ini), GFP_KERNEL); + ini = kzalloc_obj(*ini); if (!ini) goto out; @@ -1419,7 +1419,7 @@ int smc_llc_srv_add_link(struct smc_link *link, req_qentry->msg.raw.hdr.common.llc_type == SMC_LLC_REQ_ADD_LINK) send_req_add_link_resp = true; - ini = kzalloc(sizeof(*ini), GFP_KERNEL); + ini = kzalloc_obj(*ini); if (!ini) { rc = -ENOMEM; goto out; @@ -2069,7 +2069,7 @@ static void smc_llc_enqueue(struct smc_link *link, union smc_llc_msg *llc) struct smc_llc_qentry *qentry; unsigned long flags; - qentry = kmalloc(sizeof(*qentry), GFP_ATOMIC); + qentry = kmalloc_obj(*qentry, GFP_ATOMIC); if (!qentry) return; qentry->link = link; diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index a3a1e1fde8eb..63e286e2dfaa 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c @@ -368,7 +368,7 @@ static int smc_pnet_add_eth(struct smc_pnettable *pnettable, struct net *net, /* add a new netdev entry to the pnet table if there isn't one */ rc = -ENOMEM; - new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL); + new_pe = kzalloc_obj(*new_pe); if (!new_pe) goto out_put; new_pe->type = SMC_PNET_ETH; @@ -445,7 +445,7 @@ static int smc_pnet_add_ib(struct smc_pnettable *pnettable, char *ib_name, return -EEXIST; /* add a new ib entry to the pnet table if there isn't one */ - new_pe = kzalloc(sizeof(*new_pe), GFP_KERNEL); + new_pe = kzalloc_obj(*new_pe); if (!new_pe) return -ENOMEM; new_pe->type = SMC_PNET_IB; @@ -747,7 +747,7 @@ static int smc_pnet_add_pnetid(struct net *net, u8 *pnetid) struct smc_net *sn = net_generic(net, smc_net_id); struct smc_pnetids_ndev_entry *pe, *pi; - pe = kzalloc(sizeof(*pe), GFP_KERNEL); + pe = kzalloc_obj(*pe); if (!pe) return -ENOMEM; diff --git a/net/smc/smc_rx.c b/net/smc/smc_rx.c index e7f1134453ef..d833e36f7fd4 100644 --- a/net/smc/smc_rx.c +++ b/net/smc/smc_rx.c @@ -161,17 +161,17 @@ static int smc_rx_splice(struct pipe_inode_info *pipe, char *src, size_t len, nr_pages = !lgr->is_smcd && smc->conn.rmb_desc->is_vm ? PAGE_ALIGN(len + offset) / PAGE_SIZE : 1; - pages = kcalloc(nr_pages, sizeof(*pages), GFP_KERNEL); + pages = kzalloc_objs(*pages, nr_pages); if (!pages) goto out; - partial = kcalloc(nr_pages, sizeof(*partial), GFP_KERNEL); + partial = kzalloc_objs(*partial, nr_pages); if (!partial) goto out_page; - priv = kcalloc(nr_pages, sizeof(*priv), GFP_KERNEL); + priv = kzalloc_objs(*priv, nr_pages); if (!priv) goto out_part; for (i = 0; i < nr_pages; i++) { - priv[i] = kzalloc(sizeof(**priv), GFP_KERNEL); + priv[i] = kzalloc_obj(**priv); if (!priv[i]) goto out_priv; } diff --git a/net/smc/smc_stats.c b/net/smc/smc_stats.c index e71b17d1e21c..59db611821f6 100644 --- a/net/smc/smc_stats.c +++ b/net/smc/smc_stats.c @@ -20,7 +20,7 @@ int smc_stats_init(struct net *net) { - net->smc.fback_rsn = kzalloc(sizeof(*net->smc.fback_rsn), GFP_KERNEL); + net->smc.fback_rsn = kzalloc_obj(*net->smc.fback_rsn); if (!net->smc.fback_rsn) goto err_fback; net->smc.smc_stats = alloc_percpu(struct smc_stats); @@ -285,7 +285,7 @@ int smc_nl_get_stats(struct sk_buff *skb, attrs = nla_nest_start(skb, SMC_GEN_STATS); if (!attrs) goto errnest; - stats = kzalloc(sizeof(*stats), GFP_KERNEL); + stats = kzalloc_obj(*stats); if (!stats) goto erralloc; size = sizeof(*stats) / sizeof(u64); diff --git a/net/smc/smc_wr.c b/net/smc/smc_wr.c index 5feafa98ab1a..59c92b46945c 100644 --- a/net/smc/smc_wr.c +++ b/net/smc/smc_wr.c @@ -749,27 +749,21 @@ int smc_wr_alloc_link_mem(struct smc_link *link) GFP_KERNEL); if (!link->wr_rx_bufs) goto no_mem_wr_tx_bufs; - link->wr_tx_ibs = kcalloc(link->max_send_wr, - sizeof(link->wr_tx_ibs[0]), GFP_KERNEL); + link->wr_tx_ibs = kzalloc_objs(link->wr_tx_ibs[0], link->max_send_wr); if (!link->wr_tx_ibs) goto no_mem_wr_rx_bufs; - link->wr_rx_ibs = kcalloc(link->max_recv_wr, - sizeof(link->wr_rx_ibs[0]), - GFP_KERNEL); + link->wr_rx_ibs = kzalloc_objs(link->wr_rx_ibs[0], link->max_recv_wr); if (!link->wr_rx_ibs) goto no_mem_wr_tx_ibs; - link->wr_tx_rdmas = kcalloc(link->max_send_wr, - sizeof(link->wr_tx_rdmas[0]), - GFP_KERNEL); + link->wr_tx_rdmas = kzalloc_objs(link->wr_tx_rdmas[0], + link->max_send_wr); if (!link->wr_tx_rdmas) goto no_mem_wr_rx_ibs; - link->wr_tx_rdma_sges = kcalloc(link->max_send_wr, - sizeof(link->wr_tx_rdma_sges[0]), - GFP_KERNEL); + link->wr_tx_rdma_sges = kzalloc_objs(link->wr_tx_rdma_sges[0], + link->max_send_wr); if (!link->wr_tx_rdma_sges) goto no_mem_wr_tx_rdmas; - link->wr_tx_sges = kcalloc(link->max_send_wr, sizeof(link->wr_tx_sges[0]), - GFP_KERNEL); + link->wr_tx_sges = kzalloc_objs(link->wr_tx_sges[0], link->max_send_wr); if (!link->wr_tx_sges) goto no_mem_wr_tx_rdma_sges; link->wr_rx_sges = kcalloc(link->max_recv_wr, @@ -780,28 +774,23 @@ int smc_wr_alloc_link_mem(struct smc_link *link) link->wr_tx_mask = bitmap_zalloc(link->max_send_wr, GFP_KERNEL); if (!link->wr_tx_mask) goto no_mem_wr_rx_sges; - link->wr_tx_pends = kcalloc(link->max_send_wr, - sizeof(link->wr_tx_pends[0]), - GFP_KERNEL); + link->wr_tx_pends = kzalloc_objs(link->wr_tx_pends[0], + link->max_send_wr); if (!link->wr_tx_pends) goto no_mem_wr_tx_mask; - link->wr_tx_compl = kcalloc(link->max_send_wr, - sizeof(link->wr_tx_compl[0]), - GFP_KERNEL); + link->wr_tx_compl = kzalloc_objs(link->wr_tx_compl[0], + link->max_send_wr); if (!link->wr_tx_compl) goto no_mem_wr_tx_pends; if (link->lgr->smc_version == SMC_V2) { - link->wr_tx_v2_ib = kzalloc(sizeof(*link->wr_tx_v2_ib), - GFP_KERNEL); + link->wr_tx_v2_ib = kzalloc_obj(*link->wr_tx_v2_ib); if (!link->wr_tx_v2_ib) goto no_mem_tx_compl; - link->wr_tx_v2_sge = kzalloc(sizeof(*link->wr_tx_v2_sge), - GFP_KERNEL); + link->wr_tx_v2_sge = kzalloc_obj(*link->wr_tx_v2_sge); if (!link->wr_tx_v2_sge) goto no_mem_v2_ib; - link->wr_tx_v2_pend = kzalloc(sizeof(*link->wr_tx_v2_pend), - GFP_KERNEL); + link->wr_tx_v2_pend = kzalloc_obj(*link->wr_tx_v2_pend); if (!link->wr_tx_v2_pend) goto no_mem_v2_sge; } diff --git a/net/socket.c b/net/socket.c index 136b98c54fb3..05952188127f 100644 --- a/net/socket.c +++ b/net/socket.c @@ -674,7 +674,7 @@ static void __sock_release(struct socket *sock, struct inode *inode) iput(SOCK_INODE(sock)); return; } - sock->file = NULL; + WRITE_ONCE(sock->file, NULL); } /** diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 5a827afd8e3b..68c0595ea2fd 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -290,12 +290,12 @@ rpcauth_init_credcache(struct rpc_auth *auth) struct rpc_cred_cache *new; unsigned int hashsize; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) goto out_nocache; new->hashbits = auth_hashbits; hashsize = 1U << new->hashbits; - new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL); + new->hashtable = kzalloc_objs(new->hashtable[0], hashsize); if (!new->hashtable) goto out_nohashtbl; spin_lock_init(&new->lock); diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index bb3c3db2713b..9d3fb6848f40 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -164,7 +164,7 @@ gss_alloc_context(void) { struct gss_cl_ctx *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (ctx != NULL) { ctx->gc_proc = RPC_GSS_PROC_DATA; ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ @@ -529,7 +529,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, int vers; int err = -ENOMEM; - gss_msg = kzalloc(sizeof(*gss_msg), GFP_KERNEL); + gss_msg = kzalloc_obj(*gss_msg); if (gss_msg == NULL) goto err; vers = get_pipe_version(gss_auth->net); @@ -914,7 +914,7 @@ static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt, struct gss_pipe *p; int err = -ENOMEM; - p = kmalloc(sizeof(*p), GFP_KERNEL); + p = kmalloc_obj(*p); if (p == NULL) goto err; p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); @@ -1029,7 +1029,7 @@ gss_create_new(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt) if (!try_module_get(THIS_MODULE)) return ERR_PTR(err); - if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) + if (!(gss_auth = kmalloc_obj(*gss_auth))) goto out_dec; INIT_HLIST_NODE(&gss_auth->hash); gss_auth->target_name = NULL; @@ -1246,7 +1246,7 @@ gss_dup_cred(struct gss_auth *gss_auth, struct gss_cred *gss_cred) struct gss_cred *new; /* Make a copy of the cred so that we can reference count it */ - new = kzalloc(sizeof(*gss_cred), GFP_KERNEL); + new = kzalloc_obj(*gss_cred); if (new) { struct auth_cred acred = { .cred = gss_cred->gc_base.cr_cred, @@ -1380,7 +1380,7 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags, gfp_t struct gss_cred *cred = NULL; int err = -ENOMEM; - if (!(cred = kzalloc(sizeof(*cred), gfp))) + if (!(cred = kzalloc_obj(*cred, gfp))) goto out_err; rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); @@ -1817,9 +1817,7 @@ alloc_enc_pages(struct rpc_rqst *rqstp) last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_SHIFT; rqstp->rq_enc_pages_num = last - first + 1 + 1; rqstp->rq_enc_pages - = kmalloc_array(rqstp->rq_enc_pages_num, - sizeof(struct page *), - GFP_KERNEL); + = kmalloc_objs(struct page *, rqstp->rq_enc_pages_num); if (!rqstp->rq_enc_pages) goto out; for (i=0; i < rqstp->rq_enc_pages_num; i++) { diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index 3366505bc669..6db64a9111a9 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c @@ -473,7 +473,7 @@ gss_krb5_import_sec_context(const void *p, size_t len, struct gss_ctx *ctx_id, struct krb5_ctx *ctx; int ret; - ctx = kzalloc(sizeof(*ctx), gfp_mask); + ctx = kzalloc_obj(*ctx, gfp_mask); if (ctx == NULL) return -ENOMEM; diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index c84d0cf61980..78eab245f94a 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c @@ -355,7 +355,7 @@ gss_import_sec_context(const void *input_token, size_t bufsize, time64_t *endtime, gfp_t gfp_mask) { - if (!(*ctx_id = kzalloc(sizeof(**ctx_id), gfp_mask))) + if (!(*ctx_id = kzalloc_obj(**ctx_id, gfp_mask))) return -ENOMEM; (*ctx_id)->mech_type = gss_mech_get(mech); diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index f549e4c05def..0fa4778620d9 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c @@ -214,7 +214,7 @@ static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) unsigned int i; arg->npages = DIV_ROUND_UP(NGROUPS_MAX * 4, PAGE_SIZE); - arg->pages = kcalloc(arg->npages, sizeof(struct page *), GFP_KERNEL); + arg->pages = kzalloc_objs(struct page *, arg->npages); if (!arg->pages) return -ENOMEM; for (i = 0; i < arg->npages; i++) { diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index f320c0a8e604..fceee648d545 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -244,11 +244,11 @@ static int gssx_dec_option_array(struct xdr_stream *xdr, /* we recognize only 1 currently: CREDS_VALUE */ oa->count = 1; - oa->data = kmalloc(sizeof(struct gssx_option), GFP_KERNEL); + oa->data = kmalloc_obj(struct gssx_option); if (!oa->data) return -ENOMEM; - creds = kzalloc(sizeof(struct svc_cred), GFP_KERNEL); + creds = kzalloc_obj(struct svc_cred); if (!creds) { err = -ENOMEM; goto free_oa; diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index e2f0df8cdaa6..161d02cc1c2c 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -197,7 +197,7 @@ static void update_rsi(struct cache_head *cnew, struct cache_head *citem) static struct cache_head *rsi_alloc(void) { - struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL); + struct rsi *rsii = kmalloc_obj(*rsii); if (rsii) return &rsii->h; else @@ -449,7 +449,7 @@ update_rsc(struct cache_head *cnew, struct cache_head *ctmp) static struct cache_head * rsc_alloc(void) { - struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL); + struct rsc *rsci = kmalloc_obj(*rsci); if (rsci) return &rsci->h; else @@ -814,7 +814,7 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) struct auth_domain *test; int stat = -ENOMEM; - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (!new) goto out; kref_init(&new->h.ref); @@ -1069,7 +1069,7 @@ static int gss_read_proxy_verf(struct svc_rqst *rqstp, goto out_denied_free; pages = DIV_ROUND_UP(inlen, PAGE_SIZE); - in_token->pages = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL); + in_token->pages = kzalloc_objs(struct page *, pages + 1); if (!in_token->pages) goto out_denied_free; in_token->page_base = 0; @@ -1631,7 +1631,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp) rqstp->rq_auth_stat = rpc_autherr_failed; if (!svcdata) - svcdata = kmalloc(sizeof(*svcdata), GFP_KERNEL); + svcdata = kmalloc_obj(*svcdata); if (!svcdata) goto auth_err; rqstp->rq_auth_data = svcdata; diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 1e091d3fa607..6c742a3400c4 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c @@ -45,7 +45,7 @@ static struct rpc_cred *unx_lookup_cred(struct rpc_auth *auth, { struct rpc_cred *ret; - ret = kmalloc(sizeof(*ret), rpc_task_gfp_mask()); + ret = kmalloc_obj(*ret, rpc_task_gfp_mask()); if (!ret) { if (!(flags & RPCAUTH_LOOKUP_ASYNC)) return ERR_PTR(-ENOMEM); diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index 6b9dee4119d5..0ffa4d01a938 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c @@ -94,7 +94,7 @@ static struct rpc_rqst *xprt_alloc_bc_req(struct rpc_xprt *xprt) struct rpc_rqst *req; /* Pre-allocate one backchannel rpc_rqst */ - req = kzalloc(sizeof(*req), gfp_flags); + req = kzalloc_obj(*req, gfp_flags); if (req == NULL) return NULL; diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index d808c0b63f30..237f67a5d004 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c @@ -1038,7 +1038,7 @@ static int cache_open(struct inode *inode, struct file *filp, return -EACCES; nonseekable_open(inode, filp); if (filp->f_mode & FMODE_READ) { - rp = kmalloc(sizeof(*rp), GFP_KERNEL); + rp = kmalloc_obj(*rp); if (!rp) { module_put(cd->owner); return -ENOMEM; @@ -1225,7 +1225,7 @@ static int cache_pipe_upcall(struct cache_detail *detail, struct cache_head *h) if (!buf) return -EAGAIN; - crq = kmalloc(sizeof (*crq), GFP_KERNEL); + crq = kmalloc_obj(*crq); if (!crq) { kfree(buf); return -EAGAIN; @@ -1745,8 +1745,7 @@ struct cache_detail *cache_create_net(const struct cache_detail *tmpl, struct ne if (cd == NULL) return ERR_PTR(-ENOMEM); - cd->hash_table = kcalloc(cd->hash_size, sizeof(struct hlist_head), - GFP_KERNEL); + cd->hash_table = kzalloc_objs(struct hlist_head, cd->hash_size); if (cd->hash_table == NULL) { kfree(cd); return ERR_PTR(-ENOMEM); diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 58442ae1c2da..bc8ca470718b 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -374,7 +374,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, goto out_err; err = -ENOMEM; - clnt = kzalloc(sizeof(*clnt), GFP_KERNEL); + clnt = kzalloc_obj(*clnt); if (!clnt) goto out_err; clnt->cl_parent = parent ? : clnt; @@ -2976,7 +2976,7 @@ int rpc_clnt_test_and_add_xprt(struct rpc_clnt *clnt, return -EINVAL; } - data = kmalloc(sizeof(*data), GFP_KERNEL); + data = kmalloc_obj(*data); if (!data) return -ENOMEM; data->xps = xprt_switch_get(xps); diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 379daefc4847..9d349cfbc483 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -511,7 +511,7 @@ struct rpc_pipe *rpc_mkpipe_data(const struct rpc_pipe_ops *ops, int flags) { struct rpc_pipe *pipe; - pipe = kzalloc(sizeof(struct rpc_pipe), GFP_KERNEL); + pipe = kzalloc_obj(struct rpc_pipe); if (!pipe) return ERR_PTR(-ENOMEM); init_pipe(pipe); diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 53bcca365fb1..6aa372188c86 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -737,7 +737,7 @@ void rpcb_getport_async(struct rpc_task *task) goto bailout_nofree; } - map = kzalloc(sizeof(struct rpcbind_args), rpc_task_gfp_mask()); + map = kzalloc_obj(struct rpcbind_args, rpc_task_gfp_mask()); if (!map) { status = -ENOMEM; goto bailout_release_client; diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index 383860cb1d5b..7093e18ac26c 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -126,7 +126,7 @@ struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) struct rpc_iostats *stats; int i; - stats = kcalloc(clnt->cl_maxproc, sizeof(*stats), GFP_KERNEL); + stats = kzalloc_objs(*stats, clnt->cl_maxproc); if (stats) { for (i = 0; i < clnt->cl_maxproc; i++) spin_lock_init(&stats[i].om_lock); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 346ac560dcc2..d8ccb8e4b5c2 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -488,7 +488,7 @@ __svc_create(struct svc_program *prog, int nprogs, struct svc_stat *stats, unsigned int xdrsize; unsigned int i; - if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) + if (!(serv = kzalloc_obj(*serv))) return NULL; serv->sv_name = prog->pg_name; serv->sv_programs = prog; @@ -523,8 +523,7 @@ __svc_create(struct svc_program *prog, int nprogs, struct svc_stat *stats, serv->sv_nrpools = npools; serv->sv_pools = - kcalloc(serv->sv_nrpools, sizeof(struct svc_pool), - GFP_KERNEL); + kzalloc_objs(struct svc_pool, serv->sv_nrpools); if (!serv->sv_pools) { kfree(serv); return NULL; diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 8ca98b146ec8..3be69c145d2a 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c @@ -72,7 +72,7 @@ struct auth_domain *unix_domain_find(char *name) return rv; } - new = kmalloc(sizeof(*new), GFP_KERNEL); + new = kmalloc_obj(*new); if (new == NULL) return NULL; kref_init(&new->h.ref); @@ -143,7 +143,7 @@ static void update(struct cache_head *cnew, struct cache_head *citem) } static struct cache_head *ip_map_alloc(void) { - struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL); + struct ip_map *i = kmalloc_obj(*i); if (i) return &i->h; else @@ -458,7 +458,7 @@ static void unix_gid_update(struct cache_head *cnew, struct cache_head *citem) } static struct cache_head *unix_gid_alloc(void) { - struct unix_gid *g = kmalloc(sizeof(*g), GFP_KERNEL); + struct unix_gid *g = kmalloc_obj(*g); if (g) return &g->h; else diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index d61cd9b40491..f28c6076f7e8 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -1436,12 +1436,12 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, return ERR_PTR(sendpages); pages = svc_serv_maxpages(serv); - svsk = kzalloc(struct_size(svsk, sk_pages, pages), GFP_KERNEL); + svsk = kzalloc_flex(*svsk, sk_pages, pages); if (!svsk) return ERR_PTR(-ENOMEM); if (sendpages) { - svsk->sk_bvec = kcalloc(sendpages, sizeof(*svsk->sk_bvec), GFP_KERNEL); + svsk->sk_bvec = kzalloc_objs(*svsk->sk_bvec, sendpages); if (!svsk->sk_bvec) { kfree(svsk); return ERR_PTR(-ENOMEM); diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c index 8b01b7ae2690..af8fac9cedd4 100644 --- a/net/sunrpc/sysfs.c +++ b/net/sunrpc/sysfs.c @@ -48,7 +48,7 @@ static struct kobject *rpc_sysfs_object_alloc(const char *name, { struct kobject *kobj; - kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + kobj = kzalloc_obj(*kobj); if (kobj) { kobj->kset = kset; if (kobject_init_and_add(kobj, &rpc_sysfs_object_type, @@ -397,7 +397,7 @@ static ssize_t rpc_sysfs_xprt_dstaddr_store(struct kobject *kobj, dst_addr = kstrndup(buf, buf_len, GFP_KERNEL); if (!dst_addr) goto out_err; - saved_addr = kzalloc(sizeof(*saved_addr), GFP_KERNEL); + saved_addr = kzalloc_obj(*saved_addr); if (!saved_addr) goto out_err_free; saved_addr->addr = @@ -663,7 +663,7 @@ static struct rpc_sysfs_client *rpc_sysfs_client_alloc(struct kobject *parent, { struct rpc_sysfs_client *p; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (p) { p->net = net; p->kobject.kset = rpc_sunrpc_kset; @@ -683,7 +683,7 @@ rpc_sysfs_xprt_switch_alloc(struct kobject *parent, { struct rpc_sysfs_xprt_switch *p; - p = kzalloc(sizeof(*p), gfp_flags); + p = kzalloc_obj(*p, gfp_flags); if (p) { p->net = net; p->kobject.kset = rpc_sunrpc_kset; @@ -703,7 +703,7 @@ static struct rpc_sysfs_xprt *rpc_sysfs_xprt_alloc(struct kobject *parent, { struct rpc_sysfs_xprt *p; - p = kzalloc(sizeof(*p), gfp_flags); + p = kzalloc_obj(*p, gfp_flags); if (!p) goto out; p->kobject.kset = rpc_sunrpc_kset; diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 70efc727a9cd..e83d5d0be78b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -118,7 +118,7 @@ xdr_alloc_bvec(struct xdr_buf *buf, gfp_t gfp) size_t i, n = xdr_buf_pagecount(buf); if (n != 0 && buf->bvec == NULL) { - buf->bvec = kmalloc_array(n, sizeof(buf->bvec[0]), gfp); + buf->bvec = kmalloc_objs(buf->bvec[0], n, gfp); if (!buf->bvec) return -ENOMEM; for (i = 0; i < n; i++) { diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 1023361845f9..4fbb57a29704 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c @@ -1709,7 +1709,7 @@ static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt) goto out; ++xprt->num_reqs; spin_unlock(&xprt->reserve_lock); - req = kzalloc(sizeof(*req), rpc_task_gfp_mask()); + req = kzalloc_obj(*req, rpc_task_gfp_mask()); spin_lock(&xprt->reserve_lock); if (req != NULL) goto out; @@ -1829,7 +1829,7 @@ struct rpc_xprt *xprt_alloc(struct net *net, size_t size, xprt_init(xprt, net); for (i = 0; i < num_prealloc; i++) { - req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL); + req = kzalloc_obj(struct rpc_rqst); if (!req) goto out_free; list_add(&req->rq_list, &xprt->free); diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c index 4c5e08b0aa64..3ba818d637be 100644 --- a/net/sunrpc/xprtmultipath.c +++ b/net/sunrpc/xprtmultipath.c @@ -150,7 +150,7 @@ struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt, { struct rpc_xprt_switch *xps; - xps = kmalloc(sizeof(*xps), gfp_flags); + xps = kmalloc_obj(*xps, gfp_flags); if (xps != NULL) { spin_lock_init(&xps->xps_lock); kref_init(&xps->xps_kref); diff --git a/net/sunrpc/xprtrdma/ib_client.c b/net/sunrpc/xprtrdma/ib_client.c index 28c68b5f6823..de49ad02053d 100644 --- a/net/sunrpc/xprtrdma/ib_client.c +++ b/net/sunrpc/xprtrdma/ib_client.c @@ -108,7 +108,7 @@ static int rpcrdma_add_one(struct ib_device *device) { struct rpcrdma_device *rd; - rd = kzalloc(sizeof(*rd), GFP_KERNEL); + rd = kzalloc_obj(*rd); if (!rd) return -ENOMEM; diff --git a/net/sunrpc/xprtrdma/svc_rdma_pcl.c b/net/sunrpc/xprtrdma/svc_rdma_pcl.c index b63cfeaa2923..1f8f7dad8b6f 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_pcl.c +++ b/net/sunrpc/xprtrdma/svc_rdma_pcl.c @@ -29,7 +29,7 @@ static struct svc_rdma_chunk *pcl_alloc_chunk(u32 segcount, u32 position) { struct svc_rdma_chunk *chunk; - chunk = kmalloc(struct_size(chunk, ch_segments, segcount), GFP_KERNEL); + chunk = kmalloc_flex(*chunk, ch_segments, segcount); if (!chunk) return NULL; diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 63262ef0c2e3..b51a162885bb 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c @@ -383,7 +383,7 @@ static int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt) struct rpcrdma_ep *ep; int rc; - ep = kzalloc(sizeof(*ep), XPRTRDMA_GFP_FLAGS); + ep = kzalloc_obj(*ep, XPRTRDMA_GFP_FLAGS); if (!ep) return -ENOTCONN; ep->re_xprt = &r_xprt->rx_xprt; @@ -615,8 +615,8 @@ static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ep *ep) { struct rpcrdma_sendctx *sc; - sc = kzalloc(struct_size(sc, sc_sges, ep->re_attr.cap.max_send_sge), - XPRTRDMA_GFP_FLAGS); + sc = kzalloc_flex(*sc, sc_sges, ep->re_attr.cap.max_send_sge, + XPRTRDMA_GFP_FLAGS); if (!sc) return NULL; @@ -639,7 +639,7 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt) * Sends are posted. */ i = r_xprt->rx_ep->re_max_requests + RPCRDMA_MAX_BC_REQUESTS; - buf->rb_sc_ctxs = kcalloc(i, sizeof(sc), XPRTRDMA_GFP_FLAGS); + buf->rb_sc_ctxs = kzalloc_objs(sc, i, XPRTRDMA_GFP_FLAGS); if (!buf->rb_sc_ctxs) return -ENOMEM; @@ -822,7 +822,7 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, struct rpcrdma_buffer *buffer = &r_xprt->rx_buf; struct rpcrdma_req *req; - req = kzalloc(sizeof(*req), XPRTRDMA_GFP_FLAGS); + req = kzalloc_obj(*req, XPRTRDMA_GFP_FLAGS); if (req == NULL) goto out1; @@ -952,7 +952,7 @@ struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt) struct ib_device *device = ep->re_id->device; struct rpcrdma_rep *rep; - rep = kzalloc(sizeof(*rep), XPRTRDMA_GFP_FLAGS); + rep = kzalloc_obj(*rep, XPRTRDMA_GFP_FLAGS); if (rep == NULL) goto out; @@ -1362,7 +1362,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed) needed += RPCRDMA_MAX_RECV_BATCH; if (atomic_inc_return(&ep->re_receiving) > 1) - goto out; + goto out_dec; /* fast path: all needed reps can be found on the free list */ wr = NULL; @@ -1385,7 +1385,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed) ++count; } if (!wr) - goto out; + goto out_dec; rc = ib_post_recv(ep->re_id->qp, wr, (const struct ib_recv_wr **)&bad_wr); @@ -1400,9 +1400,10 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, int needed) --count; } } + +out_dec: if (atomic_dec_return(&ep->re_receiving) > 0) complete(&ep->re_done); - out: trace_xprtrdma_post_recvs(r_xprt, count); ep->re_receive_count += count; diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c index 4d5fbacef496..b55df183e6d5 100644 --- a/net/switchdev/switchdev.c +++ b/net/switchdev/switchdev.c @@ -114,7 +114,7 @@ static int switchdev_deferred_enqueue(struct net_device *dev, { struct switchdev_deferred_item *dfitem; - dfitem = kmalloc(struct_size(dfitem, data, data_len), GFP_ATOMIC); + dfitem = kmalloc_flex(*dfitem, data, data_len, GFP_ATOMIC); if (!dfitem) return -ENOMEM; dfitem->dev = dev; diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c index 114fef65f92e..76a1585d3f6b 100644 --- a/net/tipc/bcast.c +++ b/net/tipc/bcast.c @@ -692,7 +692,7 @@ int tipc_bcast_init(struct net *net) struct tipc_bc_base *bb = NULL; struct tipc_link *l = NULL; - bb = kzalloc(sizeof(*bb), GFP_KERNEL); + bb = kzalloc_obj(*bb); if (!bb) goto enomem; tn->bcbase = bb; diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index ae1ddbf71853..a3bd1ef17558 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -322,7 +322,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, goto rejected; } - b = kzalloc(sizeof(*b), GFP_ATOMIC); + b = kzalloc_obj(*b, GFP_ATOMIC); if (!b) return -ENOMEM; diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index a3f9ca28c3d5..d3046a39ff72 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -524,7 +524,7 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey, return -EEXIST; /* Allocate a new AEAD */ - tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC); + tmp = kzalloc_obj(*tmp, GFP_ATOMIC); if (unlikely(!tmp)) return -ENOMEM; @@ -560,7 +560,7 @@ static int tipc_aead_init(struct tipc_aead **aead, struct tipc_aead_key *ukey, break; } - tfm_entry = kmalloc(sizeof(*tfm_entry), GFP_KERNEL); + tfm_entry = kmalloc_obj(*tfm_entry); if (unlikely(!tfm_entry)) { crypto_free_aead(tfm); err = -ENOMEM; @@ -637,7 +637,7 @@ static int tipc_aead_clone(struct tipc_aead **dst, struct tipc_aead *src) if (unlikely(*dst)) return -EEXIST; - aead = kzalloc(sizeof(*aead), GFP_ATOMIC); + aead = kzalloc_obj(*aead, GFP_ATOMIC); if (unlikely(!aead)) return -ENOMEM; @@ -1472,7 +1472,7 @@ int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net, return -EEXIST; /* Allocate crypto */ - c = kzalloc(sizeof(*c), GFP_ATOMIC); + c = kzalloc_obj(*c, GFP_ATOMIC); if (!c) return -ENOMEM; diff --git a/net/tipc/discover.c b/net/tipc/discover.c index 775fd4f3f072..3e54d2df5683 100644 --- a/net/tipc/discover.c +++ b/net/tipc/discover.c @@ -353,7 +353,7 @@ int tipc_disc_create(struct net *net, struct tipc_bearer *b, struct tipc_net *tn = tipc_net(net); struct tipc_discoverer *d; - d = kmalloc(sizeof(*d), GFP_ATOMIC); + d = kmalloc_obj(*d, GFP_ATOMIC); if (!d) return -ENOMEM; d->skb = tipc_buf_acquire(MAX_H_SIZE + NODE_ID_LEN, GFP_ATOMIC); diff --git a/net/tipc/group.c b/net/tipc/group.c index 3e137d8c9d2f..e0e6227b433b 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c @@ -169,7 +169,7 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid, struct tipc_group *grp; u32 type = mreq->type; - grp = kzalloc(sizeof(*grp), GFP_ATOMIC); + grp = kzalloc_obj(*grp, GFP_ATOMIC); if (!grp) return NULL; tipc_nlist_init(&grp->dests, tipc_own_addr(net)); @@ -306,7 +306,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp, struct tipc_member *m; int ret; - m = kzalloc(sizeof(*m), GFP_ATOMIC); + m = kzalloc_obj(*m, GFP_ATOMIC); if (!m) return NULL; INIT_LIST_HEAD(&m->list); diff --git a/net/tipc/link.c b/net/tipc/link.c index 931f55f781a1..49dfc098d89b 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -487,7 +487,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id, char self_str[NODE_ID_STR_LEN] = {0,}; struct tipc_link *l; - l = kzalloc(sizeof(*l), GFP_ATOMIC); + l = kzalloc_obj(*l, GFP_ATOMIC); if (!l) return false; *link = l; diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 572b79bf76ce..a94b9b36a700 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -393,7 +393,7 @@ static bool tipc_mon_add_peer(struct tipc_monitor *mon, u32 addr, struct tipc_peer *self = mon->self; struct tipc_peer *cur, *prev, *p; - p = kzalloc(sizeof(*p), GFP_ATOMIC); + p = kzalloc_obj(*p, GFP_ATOMIC); *peer = p; if (!p) return false; @@ -654,9 +654,9 @@ int tipc_mon_create(struct net *net, int bearer_id) if (tn->monitors[bearer_id]) return 0; - mon = kzalloc(sizeof(*mon), GFP_ATOMIC); - self = kzalloc(sizeof(*self), GFP_ATOMIC); - dom = kzalloc(sizeof(*dom), GFP_ATOMIC); + mon = kzalloc_obj(*mon, GFP_ATOMIC); + self = kzalloc_obj(*self, GFP_ATOMIC); + dom = kzalloc_obj(*dom, GFP_ATOMIC); if (!mon || !self || !dom) { kfree(mon); kfree(self); diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index e74940eab3a4..253c72d1366e 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c @@ -230,7 +230,7 @@ static struct publication *tipc_publ_create(struct tipc_uaddr *ua, struct tipc_socket_addr *sk, u32 key) { - struct publication *p = kzalloc(sizeof(*p), GFP_ATOMIC); + struct publication *p = kzalloc_obj(*p, GFP_ATOMIC); if (!p) return NULL; @@ -261,7 +261,7 @@ static struct tipc_service *tipc_service_create(struct net *net, struct tipc_service *service; struct hlist_head *hd; - service = kzalloc(sizeof(*service), GFP_ATOMIC); + service = kzalloc_obj(*service, GFP_ATOMIC); if (!service) { pr_warn("Service creation failed, no memory\n"); return NULL; @@ -314,7 +314,7 @@ static struct service_range *tipc_service_create_range(struct tipc_service *sc, else n = &parent->rb_right; } - sr = kzalloc(sizeof(*sr), GFP_ATOMIC); + sr = kzalloc_obj(*sr, GFP_ATOMIC); if (!sr) return NULL; sr->lower = lower; @@ -348,7 +348,8 @@ static bool tipc_service_insert_publ(struct net *net, /* Return if the publication already exists */ list_for_each_entry(_p, &sr->all_publ, all_publ) { - if (_p->key == key && (!_p->sk.node || _p->sk.node == node)) { + if (_p->key == key && _p->sk.ref == p->sk.ref && + (!_p->sk.node || _p->sk.node == node)) { pr_debug("Failed to bind duplicate %u,%u,%u/%u:%u/%u\n", p->sr.type, p->sr.lower, p->sr.upper, node, p->sk.ref, key); @@ -388,7 +389,8 @@ static struct publication *tipc_service_remove_publ(struct service_range *r, u32 node = sk->node; list_for_each_entry(p, &r->all_publ, all_publ) { - if (p->key != key || (node && node != p->sk.node)) + if (p->key != key || p->sk.ref != sk->ref || + (node && node != p->sk.node)) continue; list_del(&p->all_publ); list_del(&p->local_publ); @@ -888,7 +890,7 @@ int tipc_nametbl_init(struct net *net) struct name_table *nt; int i; - nt = kzalloc(sizeof(*nt), GFP_KERNEL); + nt = kzalloc_obj(*nt); if (!nt) return -ENOMEM; @@ -1156,7 +1158,7 @@ bool tipc_dest_push(struct list_head *l, u32 node, u32 port) if (tipc_dest_find(l, node, port)) return false; - dst = kmalloc(sizeof(*dst), GFP_ATOMIC); + dst = kmalloc_obj(*dst, GFP_ATOMIC); if (unlikely(!dst)) return false; dst->node = node; diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index 079aebb16ed8..2a786c56c8c5 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c @@ -202,8 +202,7 @@ static int __tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd, return -ENOMEM; } - attrbuf = kcalloc(tipc_genl_family.maxattr + 1, - sizeof(struct nlattr *), GFP_KERNEL); + attrbuf = kzalloc_objs(struct nlattr *, tipc_genl_family.maxattr + 1); if (!attrbuf) { err = -ENOMEM; goto err_out; @@ -338,9 +337,7 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, if (!trans_buf) return -ENOMEM; - attrbuf = kmalloc_array(tipc_genl_family.maxattr + 1, - sizeof(struct nlattr *), - GFP_KERNEL); + attrbuf = kmalloc_objs(struct nlattr *, tipc_genl_family.maxattr + 1); if (!attrbuf) { err = -ENOMEM; goto trans_out; diff --git a/net/tipc/node.c b/net/tipc/node.c index a07fb073368c..af442a5ef8f3 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -535,7 +535,7 @@ struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id, goto exit; } - n = kzalloc(sizeof(*n), GFP_ATOMIC); + n = kzalloc_obj(*n, GFP_ATOMIC); if (!n) { pr_warn("Node creation failed, no memory\n"); goto exit; @@ -703,7 +703,7 @@ int tipc_node_add_conn(struct net *net, u32 dnode, u32 port, u32 peer_port) pr_warn("Connecting sock to node 0x%x failed\n", dnode); return -EHOSTUNREACH; } - conn = kmalloc(sizeof(*conn), GFP_ATOMIC); + conn = kmalloc_obj(*conn, GFP_ATOMIC); if (!conn) { err = -EHOSTUNREACH; goto exit; diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 817b07d95a91..9329919fb07f 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -2233,6 +2233,8 @@ static bool tipc_sk_filter_connect(struct tipc_sock *tsk, struct sk_buff *skb, if (skb_queue_empty(&sk->sk_write_queue)) break; get_random_bytes(&delay, 2); + if (tsk->conn_timeout < 4) + tsk->conn_timeout = 4; delay %= (tsk->conn_timeout / 4); delay = msecs_to_jiffies(delay + 100); sk_reset_timer(sk, &sk->sk_timer, jiffies + delay); @@ -3595,7 +3597,7 @@ int __tipc_dump_start(struct netlink_callback *cb, struct net *net) struct tipc_net *tn = tipc_net(net); if (!iter) { - iter = kmalloc(sizeof(*iter), GFP_KERNEL); + iter = kmalloc_obj(*iter); if (!iter) return -ENOMEM; diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c index f8490d94e323..352d304c3acd 100644 --- a/net/tipc/subscr.c +++ b/net/tipc/subscr.c @@ -143,7 +143,7 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net, pr_warn("Subscription rejected, illegal request\n"); return NULL; } - sub = kmalloc(sizeof(*sub), GFP_ATOMIC); + sub = kmalloc_obj(*sub, GFP_ATOMIC); if (!sub) { pr_warn("Subscription rejected, no memory\n"); return NULL; diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c index aad7f96b6009..af530c9ed840 100644 --- a/net/tipc/topsrv.c +++ b/net/tipc/topsrv.c @@ -182,7 +182,7 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *s struct tipc_conn *con; int ret; - con = kzalloc(sizeof(*con), GFP_ATOMIC); + con = kzalloc_obj(*con, GFP_ATOMIC); if (!con) return ERR_PTR(-ENOMEM); @@ -325,7 +325,7 @@ void tipc_topsrv_queue_evt(struct net *net, int conid, if (!connected(con)) goto err; - e = kmalloc(sizeof(*e), GFP_ATOMIC); + e = kmalloc_obj(*e, GFP_ATOMIC); if (!e) goto err; e->inactive = (event == TIPC_SUBSCR_TIMEOUT); @@ -661,7 +661,7 @@ static int tipc_topsrv_start(struct net *net) struct tipc_topsrv *srv; int ret; - srv = kzalloc(sizeof(*srv), GFP_ATOMIC); + srv = kzalloc_obj(*srv, GFP_ATOMIC); if (!srv) return -ENOMEM; diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index b85ab0fb3b8c..2b8e385d1e51 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -309,7 +309,7 @@ static int tipc_udp_rcast_add(struct tipc_bearer *b, if (!ub) return -ENODEV; - rcast = kmalloc(sizeof(*rcast), GFP_ATOMIC); + rcast = kmalloc_obj(*rcast, GFP_ATOMIC); if (!rcast) return -ENOMEM; @@ -675,7 +675,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, struct net_device *dev; int rmcast = 0; - ub = kzalloc(sizeof(*ub), GFP_ATOMIC); + ub = kzalloc_obj(*ub, GFP_ATOMIC); if (!ub) return -ENOMEM; diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 82ea407e520a..99c8eff9783e 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -346,7 +346,7 @@ static int tls_create_new_record(struct tls_offload_context_tx *offload_ctx, struct tls_record_info *record; skb_frag_t *frag; - record = kmalloc(sizeof(*record), GFP_KERNEL); + record = kmalloc_obj(*record); if (!record) return -ENOMEM; @@ -1040,7 +1040,7 @@ static struct tls_offload_context_tx *alloc_offload_ctx_tx(struct tls_context *c struct tls_offload_context_tx *offload_ctx; __be64 rcd_sn; - offload_ctx = kzalloc(sizeof(*offload_ctx), GFP_KERNEL); + offload_ctx = kzalloc_obj(*offload_ctx); if (!offload_ctx) return NULL; @@ -1110,7 +1110,7 @@ int tls_set_device_offload(struct sock *sk) memcpy(ctx->tx.iv + cipher_desc->salt, iv, cipher_desc->iv); memcpy(ctx->tx.rec_seq, rec_seq, cipher_desc->rec_seq); - start_marker_record = kmalloc(sizeof(*start_marker_record), GFP_KERNEL); + start_marker_record = kmalloc_obj(*start_marker_record); if (!start_marker_record) { rc = -ENOMEM; goto release_netdev; @@ -1224,7 +1224,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) goto release_lock; } - context = kzalloc(sizeof(*context), GFP_KERNEL); + context = kzalloc_obj(*context); if (!context) { rc = -ENOMEM; goto release_lock; diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c index 03d508a45aae..d3c72f509baa 100644 --- a/net/tls/tls_device_fallback.c +++ b/net/tls/tls_device_fallback.c @@ -383,7 +383,7 @@ static struct sk_buff *tls_sw_fallback(struct sock *sk, struct sk_buff *skb) if (!payload_len) return skb; - sg_in = kmalloc_array(sg_in_max_elements, sizeof(*sg_in), GFP_ATOMIC); + sg_in = kmalloc_objs(*sg_in, sg_in_max_elements, GFP_ATOMIC); if (!sg_in) goto free_orig; diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 56ce0bc8317b..fd39acf41a61 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c @@ -915,7 +915,7 @@ struct tls_context *tls_ctx_create(struct sock *sk) struct inet_connection_sock *icsk = inet_csk(sk); struct tls_context *ctx; - ctx = kzalloc(sizeof(*ctx), GFP_ATOMIC); + ctx = kzalloc_obj(*ctx, GFP_ATOMIC); if (!ctx) return NULL; diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 9937d4c810f2..5fe07f110fe8 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -2533,7 +2533,7 @@ void tls_sw_cancel_work_tx(struct tls_context *tls_ctx) set_bit(BIT_TX_CLOSING, &ctx->tx_bitmask); set_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask); - cancel_delayed_work_sync(&ctx->tx_work.work); + disable_delayed_work_sync(&ctx->tx_work.work); } void tls_sw_release_resources_tx(struct sock *sk) @@ -2698,7 +2698,7 @@ static struct tls_sw_context_tx *init_ctx_tx(struct tls_context *ctx, struct soc struct tls_sw_context_tx *sw_ctx_tx; if (!ctx->priv_ctx_tx) { - sw_ctx_tx = kzalloc(sizeof(*sw_ctx_tx), GFP_KERNEL); + sw_ctx_tx = kzalloc_obj(*sw_ctx_tx); if (!sw_ctx_tx) return NULL; } else { @@ -2719,7 +2719,7 @@ static struct tls_sw_context_rx *init_ctx_rx(struct tls_context *ctx) struct tls_sw_context_rx *sw_ctx_rx; if (!ctx->priv_ctx_rx) { - sw_ctx_rx = kzalloc(sizeof(*sw_ctx_rx), GFP_KERNEL); + sw_ctx_rx = kzalloc_obj(*sw_ctx_rx); if (!sw_ctx_rx) return NULL; } else { diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f6d56e70c7a2..7eaa5b187fef 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1785,7 +1785,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr_unsized *uad __skb_queue_tail(&other->sk_receive_queue, skb); spin_unlock(&other->sk_receive_queue.lock); unix_state_unlock(other); - other->sk_data_ready(other); + READ_ONCE(other->sk_data_ready)(other); sock_put(other); return 0; @@ -2278,7 +2278,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, scm_stat_add(other, skb); skb_queue_tail(&other->sk_receive_queue, skb); unix_state_unlock(other); - other->sk_data_ready(other); + READ_ONCE(other->sk_data_ready)(other); sock_put(other); scm_destroy(&scm); return len; @@ -2351,7 +2351,7 @@ static int queue_oob(struct sock *sk, struct msghdr *msg, struct sock *other, sk_send_sigurg(other); unix_state_unlock(other); - other->sk_data_ready(other); + READ_ONCE(other->sk_data_ready)(other); return 0; out_unlock: @@ -2477,7 +2477,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg, spin_unlock(&other->sk_receive_queue.lock); unix_state_unlock(other); - other->sk_data_ready(other); + READ_ONCE(other->sk_data_ready)(other); sent += size; } @@ -3798,14 +3798,12 @@ static int __net_init unix_net_init(struct net *net) goto err_sysctl; #endif - net->unx.table.locks = kvmalloc_array(UNIX_HASH_SIZE, - sizeof(spinlock_t), GFP_KERNEL); + net->unx.table.locks = kvmalloc_objs(spinlock_t, UNIX_HASH_SIZE); if (!net->unx.table.locks) goto err_proc; - net->unx.table.buckets = kvmalloc_array(UNIX_HASH_SIZE, - sizeof(struct hlist_head), - GFP_KERNEL); + net->unx.table.buckets = kvmalloc_objs(struct hlist_head, + UNIX_HASH_SIZE); if (!net->unx.table.buckets) goto free_locks; diff --git a/net/unix/garbage.c b/net/unix/garbage.c index 25f65817faab..816e8fa2b062 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -288,15 +288,15 @@ int unix_prepare_fpl(struct scm_fp_list *fpl) return 0; for (i = 0; i < fpl->count_unix; i++) { - vertex = kmalloc(sizeof(*vertex), GFP_KERNEL); + vertex = kmalloc_obj(*vertex); if (!vertex) goto err; list_add(&vertex->entry, &fpl->vertices); } - fpl->edges = kvmalloc_array(fpl->count_unix, sizeof(*fpl->edges), - GFP_KERNEL_ACCOUNT); + fpl->edges = kvmalloc_objs(*fpl->edges, fpl->count_unix, + GFP_KERNEL_ACCOUNT); if (!fpl->edges) goto err; diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 20ad2b2dc17b..2f7d94d682cb 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -90,14 +90,20 @@ * * - /proc/sys/net/vsock/ns_mode (read-only) reports the current namespace's * mode, which is set at namespace creation and immutable thereafter. - * - /proc/sys/net/vsock/child_ns_mode (writable) controls what mode future - * child namespaces will inherit when created. The default is "global". + * - /proc/sys/net/vsock/child_ns_mode (write-once) controls what mode future + * child namespaces will inherit when created. The initial value matches + * the namespace's own ns_mode. * * Changing child_ns_mode only affects newly created namespaces, not the - * current namespace or existing children. At namespace creation, ns_mode + * current namespace or existing children. A "local" namespace cannot set + * child_ns_mode to "global". child_ns_mode is write-once, so that it may be + * configured and locked down by a namespace manager. Writing a different + * value after the first write returns -EBUSY. At namespace creation, ns_mode * is inherited from the parent's child_ns_mode. * - * The init_net mode is "global" and cannot be modified. + * The init_net mode is "global" and cannot be modified. The init_net + * child_ns_mode is also write-once, so an init process (e.g. systemd) can + * set it to "local" to ensure all new namespaces inherit local mode. * * The modes affect the allocation and accessibility of CIDs as follows: * @@ -2823,7 +2829,7 @@ static int vsock_net_mode_string(const struct ctl_table *table, int write, if (write) return -EPERM; - net = current->nsproxy->net_ns; + net = container_of(table->data, struct net, vsock.mode); return __vsock_net_mode_string(table, write, buffer, lenp, ppos, vsock_net_mode(net), NULL); @@ -2836,15 +2842,24 @@ static int vsock_net_child_mode_string(const struct ctl_table *table, int write, struct net *net; int ret; - net = current->nsproxy->net_ns; + net = container_of(table->data, struct net, vsock.child_ns_mode); ret = __vsock_net_mode_string(table, write, buffer, lenp, ppos, vsock_net_child_mode(net), &new_mode); if (ret) return ret; - if (write) - vsock_net_set_child_mode(net, new_mode); + if (write) { + /* Prevent a "local" namespace from escalating to "global", + * which would give nested namespaces access to global CIDs. + */ + if (vsock_net_mode(net) == VSOCK_NET_MODE_LOCAL && + new_mode == VSOCK_NET_MODE_GLOBAL) + return -EPERM; + + if (!vsock_net_set_child_mode(net, new_mode)) + return -EBUSY; + } return 0; } @@ -2912,7 +2927,7 @@ static void vsock_net_init(struct net *net) else net->vsock.mode = vsock_net_child_mode(current->nsproxy->net_ns); - net->vsock.child_ns_mode = VSOCK_NET_MODE_GLOBAL; + net->vsock.child_ns_mode = net->vsock.mode; } static __net_init int vsock_sysctl_init_net(struct net *net) diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index c3010c874308..069386a74557 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -444,7 +444,7 @@ static int hvs_sock_init(struct vsock_sock *vsk, struct vsock_sock *psk) struct hvsock *hvs; struct sock *sk = sk_vsock(vsk); - hvs = kzalloc(sizeof(*hvs), GFP_KERNEL); + hvs = kzalloc_obj(*hvs); if (!hvs) return -ENOMEM; @@ -655,7 +655,7 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg, BUILD_BUG_ON(sizeof(*send_buf) != HV_HYP_PAGE_SIZE); - send_buf = kmalloc(sizeof(*send_buf), GFP_KERNEL); + send_buf = kmalloc_obj(*send_buf); if (!send_buf) return -ENOMEM; diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index 357e80ac3f3a..77fe5b7b066c 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -805,7 +805,7 @@ static int virtio_vsock_probe(struct virtio_device *vdev) goto out; } - vsock = kzalloc(sizeof(*vsock), GFP_KERNEL); + vsock = kzalloc_obj(*vsock); if (!vsock) { ret = -ENOMEM; goto out; diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c index d017ab318a7e..8a9fb23c6e85 100644 --- a/net/vmw_vsock/virtio_transport_common.c +++ b/net/vmw_vsock/virtio_transport_common.c @@ -920,7 +920,7 @@ int virtio_transport_do_socket_init(struct vsock_sock *vsk, { struct virtio_vsock_sock *vvs; - vvs = kzalloc(sizeof(*vvs), GFP_KERNEL); + vvs = kzalloc_obj(*vvs); if (!vvs) return -ENOMEM; diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c index a64522be1bad..4296ca1183f1 100644 --- a/net/vmw_vsock/vmci_transport.c +++ b/net/vmw_vsock/vmci_transport.c @@ -262,7 +262,7 @@ vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src, struct vmci_transport_packet *pkt; int err; - pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); + pkt = kmalloc_obj(*pkt); if (!pkt) return -ENOMEM; @@ -779,7 +779,7 @@ static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg) if (!bh_process_pkt) { struct vmci_transport_recv_pkt_info *recv_pkt_info; - recv_pkt_info = kmalloc(sizeof(*recv_pkt_info), GFP_ATOMIC); + recv_pkt_info = kmalloc_obj(*recv_pkt_info, GFP_ATOMIC); if (!recv_pkt_info) { if (vmci_transport_send_reset_bh(&dst, &src, pkt) < 0) pr_err("unable to send reset\n"); @@ -1583,7 +1583,7 @@ static int vmci_transport_recv_connected(struct sock *sk, static int vmci_transport_socket_init(struct vsock_sock *vsk, struct vsock_sock *psk) { - vsk->trans = kmalloc(sizeof(struct vmci_transport), GFP_KERNEL); + vsk->trans = kmalloc_obj(struct vmci_transport); if (!vsk->trans) return -ENOMEM; diff --git a/net/wireless/core.c b/net/wireless/core.c index 9af85d655027..28ca4290ca99 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1000,9 +1000,8 @@ int wiphy_register(struct wiphy *wiphy) if (wiphy->n_radio > 0) { int idx; - wiphy->radio_cfg = kcalloc(wiphy->n_radio, - sizeof(*wiphy->radio_cfg), - GFP_KERNEL); + wiphy->radio_cfg = kzalloc_objs(*wiphy->radio_cfg, + wiphy->n_radio); if (!wiphy->radio_cfg) return -ENOMEM; /* @@ -1212,6 +1211,7 @@ void wiphy_unregister(struct wiphy *wiphy) /* this has nothing to do now but make sure it's gone */ cancel_work_sync(&rdev->wiphy_work); + cancel_work_sync(&rdev->rfkill_block); cancel_work_sync(&rdev->conn_work); flush_work(&rdev->event_work); cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); @@ -1446,7 +1446,7 @@ void cfg80211_stop_link(struct wiphy *wiphy, struct wireless_dev *wdev, trace_cfg80211_stop_link(wiphy, wdev, link_id); - ev = kzalloc(sizeof(*ev), gfp); + ev = kzalloc_obj(*ev, gfp); if (!ev) return; diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 1e3ed29f7cfc..a7024af39b40 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c @@ -69,7 +69,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, if (WARN_ON(!channel)) return; - ev = kzalloc(sizeof(*ev), gfp); + ev = kzalloc_obj(*ev, gfp); if (!ev) return; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6e58b238a1f8..b94231c8441c 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1106,8 +1106,7 @@ static int nl80211_prepare_wdev_dump(struct netlink_callback *cb, struct nlattr **attrbuf_free = NULL; if (!attrbuf) { - attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), - GFP_KERNEL); + attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR); if (!attrbuf) return -ENOMEM; attrbuf_free = attrbuf; @@ -1615,7 +1614,7 @@ nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, if (!have_key) return NULL; - result = kzalloc(sizeof(*result), GFP_KERNEL); + result = kzalloc_obj(*result); if (!result) return ERR_PTR(-ENOMEM); @@ -3367,7 +3366,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, struct netlink_callback *cb, struct nl80211_dump_wiphy_state *state) { - struct nlattr **tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL); + struct nlattr **tb = kzalloc_objs(*tb, NUM_NL80211_ATTR); int ret; if (!tb) @@ -3419,7 +3418,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) rtnl_lock(); if (!state) { - state = kzalloc(sizeof(*state), GFP_KERNEL); + state = kzalloc_obj(*state); if (!state) { rtnl_unlock(); return -ENOMEM; @@ -5333,7 +5332,7 @@ static struct cfg80211_acl_data *parse_acl_data(struct wiphy *wiphy, if (n_entries > wiphy->max_acl_mac_addrs) return ERR_PTR(-EOPNOTSUPP); - acl = kzalloc(struct_size(acl, mac_addrs, n_entries), GFP_KERNEL); + acl = kzalloc_flex(*acl, mac_addrs, n_entries); if (!acl) return ERR_PTR(-ENOMEM); acl->n_acl_entries = n_entries; @@ -6113,7 +6112,7 @@ nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs) num_elems++; } - elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL); + elems = kzalloc_flex(*elems, elem, num_elems); if (!elems) return ERR_PTR(-ENOMEM); elems->cnt = num_elems; @@ -6145,7 +6144,7 @@ nl80211_parse_rnr_elems(struct wiphy *wiphy, struct nlattr *attrs, num_elems++; } - elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL); + elems = kzalloc_flex(*elems, elem, num_elems); if (!elems) return ERR_PTR(-ENOMEM); elems->cnt = num_elems; @@ -6702,7 +6701,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]) != NL80211_SMPS_OFF) return -EOPNOTSUPP; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -6995,7 +6994,7 @@ static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) if (!wdev->links[link_id].ap.beacon_interval) return -EINVAL; - params = kzalloc(sizeof(*params), GFP_KERNEL); + params = kzalloc_obj(*params); if (!params) return -ENOMEM; @@ -7985,7 +7984,7 @@ static int nl80211_dump_station(struct sk_buff *skb, for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { sinfo.links[i] = - kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL); + kzalloc_obj(*sinfo.links[0]); if (!sinfo.links[i]) { err = -ENOMEM; goto out_err; @@ -8049,7 +8048,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) { - sinfo.links[i] = kzalloc(sizeof(*sinfo.links[0]), GFP_KERNEL); + sinfo.links[i] = kzalloc_obj(*sinfo.links[0]); if (!sinfo.links[i]) { cfg80211_sinfo_release_content(&sinfo); return -ENOMEM; @@ -10157,7 +10156,7 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) goto out; } - rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL); + rd = kzalloc_flex(*rd, reg_rules, num_rules); if (!rd) { r = -ENOMEM; goto out; @@ -11520,8 +11519,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info) if (err) goto free; - csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs), - GFP_KERNEL); + csa_attrs = kzalloc_objs(*csa_attrs, NL80211_ATTR_MAX + 1); if (!csa_attrs) { err = -ENOMEM; goto free; @@ -11781,7 +11779,7 @@ static int nl80211_dump_scan(struct sk_buff *skb, struct netlink_callback *cb) bool dump_include_use_data; int err; - attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL); + attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR); if (!attrbuf) return -ENOMEM; @@ -11921,7 +11919,7 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb) int res; bool radio_stats; - attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL); + attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR); if (!attrbuf) return -ENOMEM; @@ -13112,8 +13110,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb, goto out_err; } } else { - attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), - GFP_KERNEL); + attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR); if (!attrbuf) { err = -ENOMEM; goto out_err; @@ -14310,9 +14307,8 @@ static int nl80211_set_cqm_rssi(struct genl_info *info, } if (n_thresholds) { - cqm_config = kzalloc(struct_size(cqm_config, rssi_thresholds, - n_thresholds), - GFP_KERNEL); + cqm_config = kzalloc_flex(*cqm_config, rssi_thresholds, + n_thresholds); if (!cqm_config) return -ENOMEM; @@ -14938,7 +14934,7 @@ static int nl80211_parse_wowlan_nd(struct cfg80211_registered_device *rdev, struct nlattr **tb; int err; - tb = kcalloc(NUM_NL80211_ATTR, sizeof(*tb), GFP_KERNEL); + tb = kzalloc_objs(*tb, NUM_NL80211_ATTR); if (!tb) return -ENOMEM; @@ -15054,9 +15050,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) if (n_patterns > wowlan->n_patterns) return -EINVAL; - new_triggers.patterns = kcalloc(n_patterns, - sizeof(new_triggers.patterns[0]), - GFP_KERNEL); + new_triggers.patterns = kzalloc_objs(new_triggers.patterns[0], + n_patterns); if (!new_triggers.patterns) return -ENOMEM; @@ -15303,8 +15298,7 @@ static int nl80211_parse_coalesce_rule(struct cfg80211_registered_device *rdev, if (n_patterns > coalesce->n_patterns) return -EINVAL; - new_rule->patterns = kcalloc(n_patterns, sizeof(new_rule->patterns[0]), - GFP_KERNEL); + new_rule->patterns = kzalloc_objs(new_rule->patterns[0], n_patterns); if (!new_rule->patterns) return -ENOMEM; @@ -15382,8 +15376,7 @@ static int nl80211_set_coalesce(struct sk_buff *skb, struct genl_info *info) if (n_rules > coalesce->n_rules) return -EINVAL; - new_coalesce = kzalloc(struct_size(new_coalesce, rules, n_rules), - GFP_KERNEL); + new_coalesce = kzalloc_flex(*new_coalesce, rules, n_rules); if (!new_coalesce) return -ENOMEM; @@ -15543,7 +15536,7 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) return -EOPNOTSUPP; - nreg = kzalloc(sizeof(*nreg), GFP_KERNEL); + nreg = kzalloc_obj(*nreg); if (!nreg) return -ENOMEM; @@ -15900,7 +15893,7 @@ static int handle_nan_filter(struct nlattr *attr_filter, BUILD_BUG_ON(sizeof(*func->rx_filters) != sizeof(*func->tx_filters)); - filter = kcalloc(n_entries, sizeof(*func->rx_filters), GFP_KERNEL); + filter = kzalloc_objs(*func->rx_filters, n_entries); if (!filter) return -ENOMEM; @@ -15960,7 +15953,7 @@ static int nl80211_nan_add_func(struct sk_buff *skb, if (err) return err; - func = kzalloc(sizeof(*func), GFP_KERNEL); + func = kzalloc_obj(*func); if (!func) return -ENOMEM; @@ -16099,8 +16092,7 @@ static int nl80211_nan_add_func(struct sk_buff *skb, func->srf_num_macs = n_entries; func->srf_macs = - kcalloc(n_entries, sizeof(*func->srf_macs), - GFP_KERNEL); + kzalloc_objs(*func->srf_macs, n_entries); if (!func->srf_macs) { err = -ENOMEM; goto out; @@ -16602,7 +16594,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb, return 0; } - attrbuf = kcalloc(NUM_NL80211_ATTR, sizeof(*attrbuf), GFP_KERNEL); + attrbuf = kzalloc_objs(*attrbuf, NUM_NL80211_ATTR); if (!attrbuf) return -ENOMEM; @@ -16833,7 +16825,7 @@ static int nl80211_set_qos_map(struct sk_buff *skb, if (len % 2) return -EINVAL; - qos_map = kzalloc(sizeof(struct cfg80211_qos_map), GFP_KERNEL); + qos_map = kzalloc_obj(struct cfg80211_qos_map); if (!qos_map) return -ENOMEM; @@ -17467,8 +17459,7 @@ static int nl80211_set_tid_config(struct sk_buff *skb, rem_conf) num_conf++; - tid_config = kzalloc(struct_size(tid_config, tid_conf, num_conf), - GFP_KERNEL); + tid_config = kzalloc_flex(*tid_config, tid_conf, num_conf); if (!tid_config) return -ENOMEM; @@ -17534,7 +17525,7 @@ static int nl80211_color_change(struct sk_buff *skb, struct genl_info *info) if (err) return err; - tb = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*tb), GFP_KERNEL); + tb = kzalloc_objs(*tb, NL80211_ATTR_MAX + 1); if (!tb) return -ENOMEM; @@ -18262,7 +18253,7 @@ static int nl80211_set_sar_specs(struct sk_buff *skb, struct genl_info *info) if (specs > rdev->wiphy.sar_capa->num_freq_ranges) return -EINVAL; - sar_spec = kzalloc(struct_size(sar_spec, sub_specs, specs), GFP_KERNEL); + sar_spec = kzalloc_flex(*sar_spec, sub_specs, specs); if (!sar_spec) return -ENOMEM; diff --git a/net/wireless/of.c b/net/wireless/of.c index de221f0edca5..60a864465331 100644 --- a/net/wireless/of.c +++ b/net/wireless/of.c @@ -98,7 +98,7 @@ void wiphy_read_of_freq_limits(struct wiphy *wiphy) } n_freq_limits = len / sizeof(u32) / 2; - freq_limits = kcalloc(n_freq_limits, sizeof(*freq_limits), GFP_KERNEL); + freq_limits = kzalloc_objs(*freq_limits, n_freq_limits); if (!freq_limits) { err = -ENOMEM; goto out_kfree; diff --git a/net/wireless/pmsr.c b/net/wireless/pmsr.c index 60e1e31c2185..44bd88c9ea66 100644 --- a/net/wireless/pmsr.c +++ b/net/wireless/pmsr.c @@ -312,7 +312,7 @@ int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info) } } - req = kzalloc(struct_size(req, peers, count), GFP_KERNEL); + req = kzalloc_flex(*req, peers, count); if (!req) return -ENOMEM; req->n_peers = count; diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c index 326faea38ca3..c85eaa583a46 100644 --- a/net/wireless/radiotap.c +++ b/net/wireless/radiotap.c @@ -239,14 +239,14 @@ int ieee80211_radiotap_iterator_next( default: if (!iterator->current_namespace || iterator->_arg_index >= iterator->current_namespace->n_bits) { - if (iterator->current_namespace == &radiotap_ns) - return -ENOENT; align = 0; } else { align = iterator->current_namespace->align_size[iterator->_arg_index].align; size = iterator->current_namespace->align_size[iterator->_arg_index].size; } if (!align) { + if (iterator->current_namespace == &radiotap_ns) + return -ENOENT; /* skip all subsequent data */ iterator->_arg = iterator->_next_ns_data; /* give up on this namespace */ diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 139cb27e5a81..1c5c38d18feb 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -452,8 +452,7 @@ reg_copy_regd(const struct ieee80211_regdomain *src_regd) struct ieee80211_regdomain *regd; unsigned int i; - regd = kzalloc(struct_size(regd, reg_rules, src_regd->n_reg_rules), - GFP_KERNEL); + regd = kzalloc_flex(*regd, reg_rules, src_regd->n_reg_rules); if (!regd) return ERR_PTR(-ENOMEM); @@ -510,7 +509,7 @@ static int reg_schedule_apply(const struct ieee80211_regdomain *regdom) { struct reg_regdb_apply_request *request; - request = kzalloc(sizeof(struct reg_regdb_apply_request), GFP_KERNEL); + request = kzalloc_obj(struct reg_regdb_apply_request); if (!request) { kfree(regdom); return -ENOMEM; @@ -933,8 +932,7 @@ static int regdb_query_country(const struct fwdb_header *db, struct ieee80211_regdomain *regdom; unsigned int i; - regdom = kzalloc(struct_size(regdom, reg_rules, coll->n_rules), - GFP_KERNEL); + regdom = kzalloc_flex(*regdom, reg_rules, coll->n_rules); if (!regdom) return -ENOMEM; @@ -1100,7 +1098,7 @@ int reg_reload_regdb(void) /* reset regulatory domain */ current_regdomain = get_cfg80211_regdom(); - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) { err = -ENOMEM; goto out_unlock; @@ -1532,7 +1530,7 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, if (!num_rules) return NULL; - rd = kzalloc(struct_size(rd, reg_rules, num_rules), GFP_KERNEL); + rd = kzalloc_flex(*rd, reg_rules, num_rules); if (!rd) return NULL; @@ -3224,7 +3222,7 @@ static int regulatory_hint_core(const char *alpha2) { struct regulatory_request *request; - request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); + request = kzalloc_obj(struct regulatory_request); if (!request) return -ENOMEM; @@ -3250,7 +3248,7 @@ int regulatory_hint_user(const char *alpha2, if (!is_world_regdom(alpha2) && !is_an_alpha2(alpha2)) return -EINVAL; - request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); + request = kzalloc_obj(struct regulatory_request); if (!request) return -ENOMEM; @@ -3320,7 +3318,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2) wiphy->regulatory_flags &= ~REGULATORY_CUSTOM_REG; - request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL); + request = kzalloc_obj(struct regulatory_request); if (!request) return -ENOMEM; @@ -3353,7 +3351,7 @@ void regulatory_hint_country_ie(struct wiphy *wiphy, enum nl80211_band band, if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) return; - request = kzalloc(sizeof(*request), GFP_KERNEL); + request = kzalloc_obj(*request); if (!request) return; @@ -3666,7 +3664,7 @@ void regulatory_hint_found_beacon(struct wiphy *wiphy, if (processing) return; - reg_beacon = kzalloc(sizeof(struct reg_beacon), gfp); + reg_beacon = kzalloc_obj(struct reg_beacon, gfp); if (!reg_beacon) return; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index eb0e77813d46..328af43ef832 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -729,7 +729,7 @@ cfg80211_parse_colocated_ap_iter(void *_data, u8 type, bss_params))) return RNR_ITER_CONTINUE; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) return RNR_ITER_ERROR; @@ -895,7 +895,7 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev, if (ret) continue; - entry = kzalloc(sizeof(*entry), GFP_ATOMIC); + entry = kzalloc_obj(*entry, GFP_ATOMIC); if (!entry) continue; @@ -1085,8 +1085,7 @@ int cfg80211_scan(struct cfg80211_registered_device *rdev) if (!n_channels) return cfg80211_scan_6ghz(rdev, true); - request = kzalloc(struct_size(request, req.channels, n_channels), - GFP_KERNEL); + request = kzalloc_flex(*request, req.channels, n_channels); if (!request) return -ENOMEM; @@ -2694,7 +2693,7 @@ cfg80211_defrag_mle(const struct element *mle, const u8 *ie, size_t ielen, buf_len += elem->datalen; } - res = kzalloc(struct_size(res, data, buf_len), gfp); + res = kzalloc_flex(*res, data, buf_len, gfp); if (!res) return NULL; @@ -2910,9 +2909,8 @@ cfg80211_gen_reporter_rnr(struct cfg80211_bss *source_bss, bool is_mbssid, le16_encode_bits(bss_change_count, IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT); - res = kzalloc(struct_size(res, data, - sizeof(ap_info) + ap_info.tbtt_info_len), - gfp); + res = kzalloc_flex(*res, data, sizeof(ap_info) + ap_info.tbtt_info_len, + gfp); if (!res) return NULL; diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 4e629ca305bc..5b21432450d5 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -570,7 +570,7 @@ static int cfg80211_sme_connect(struct wireless_dev *wdev, if (wdev->conn) return -EINPROGRESS; - wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL); + wdev->conn = kzalloc_obj(*wdev->conn); if (!wdev->conn) return -ENOMEM; diff --git a/net/wireless/tests/util.c b/net/wireless/tests/util.c index 8abdaeb820ce..118f7fb4226d 100644 --- a/net/wireless/tests/util.c +++ b/net/wireless/tests/util.c @@ -17,7 +17,7 @@ int t_wiphy_init(struct kunit_resource *resource, void *ctx) struct wiphy *wiphy; struct t_wiphy_priv *priv; - ops = kzalloc(sizeof(*ops), GFP_KERNEL); + ops = kzalloc_obj(*ops); KUNIT_ASSERT_NOT_NULL(test, ops); wiphy = wiphy_new_nm(ops, sizeof(*priv), "kunit"); diff --git a/net/wireless/util.c b/net/wireless/util.c index 404fe604a8db..b78530c3e3f8 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -2713,8 +2713,8 @@ bool cfg80211_does_bw_fit_range(const struct ieee80211_freq_range *freq_range, int cfg80211_link_sinfo_alloc_tid_stats(struct link_station_info *link_sinfo, gfp_t gfp) { - link_sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, - sizeof(*link_sinfo->pertid), gfp); + link_sinfo->pertid = kzalloc_objs(*link_sinfo->pertid, + IEEE80211_NUM_TIDS + 1, gfp); if (!link_sinfo->pertid) return -ENOMEM; @@ -2724,9 +2724,8 @@ EXPORT_SYMBOL(cfg80211_link_sinfo_alloc_tid_stats); int cfg80211_sinfo_alloc_tid_stats(struct station_info *sinfo, gfp_t gfp) { - sinfo->pertid = kcalloc(IEEE80211_NUM_TIDS + 1, - sizeof(*(sinfo->pertid)), - gfp); + sinfo->pertid = kzalloc_objs(*(sinfo->pertid), IEEE80211_NUM_TIDS + 1, + gfp); if (!sinfo->pertid) return -ENOMEM; diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 1241fda78a68..5a70a0120343 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c @@ -414,8 +414,7 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, * to do it first in case the allocation fails. Don't use wext. */ if (!wdev->wext.keys) { - wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys), - GFP_KERNEL); + wdev->wext.keys = kzalloc_obj(*wdev->wext.keys); if (!wdev->wext.keys) return -ENOMEM; for (i = 0; i < 4; i++) @@ -684,7 +683,7 @@ static int cfg80211_wext_siwencodeext(struct net_device *dev, idx = erq->flags & IW_ENCODE_INDEX; if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) { - if (idx < 4 || idx > 5) { + if (idx < 5 || idx > 6) { idx = wdev->wext.default_mgmt_key; if (idx < 0) return -EINVAL; diff --git a/net/x25/x25_forward.c b/net/x25/x25_forward.c index 21b30b56e889..3b406906eb9e 100644 --- a/net/x25/x25_forward.c +++ b/net/x25/x25_forward.c @@ -55,8 +55,7 @@ int x25_forward_call(struct x25_address *dest_addr, struct x25_neigh *from, /* Save the forwarding details for future traffic */ if (!same_lci){ - if ((new_frwd = kmalloc(sizeof(struct x25_forward), - GFP_ATOMIC)) == NULL){ + if ((new_frwd = kmalloc_obj(struct x25_forward, GFP_ATOMIC)) == NULL){ rc = -ENOMEM; goto out_put_nb; } diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 4608aa5b4f31..d1e8cd81c214 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -262,7 +262,7 @@ void x25_link_terminated(struct x25_neigh *nb) */ void x25_link_device_up(struct net_device *dev) { - struct x25_neigh *nb = kmalloc(sizeof(*nb), GFP_ATOMIC); + struct x25_neigh *nb = kmalloc_obj(*nb, GFP_ATOMIC); if (!nb) return; diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c index 647f325ed867..b28055f852df 100644 --- a/net/x25/x25_route.c +++ b/net/x25/x25_route.c @@ -37,7 +37,7 @@ static int x25_add_route(struct x25_address *address, unsigned int sigdigits, goto out; } - rt = kmalloc(sizeof(*rt), GFP_ATOMIC); + rt = kmalloc_obj(*rt, GFP_ATOMIC); rc = -ENOMEM; if (!rt) goto out; diff --git a/net/xdp/xdp_umem.c b/net/xdp/xdp_umem.c index 9f76ca591d54..066ce07c506d 100644 --- a/net/xdp/xdp_umem.c +++ b/net/xdp/xdp_umem.c @@ -97,7 +97,8 @@ static int xdp_umem_pin_pages(struct xdp_umem *umem, unsigned long address) long npgs; int err; - umem->pgs = kvcalloc(umem->npgs, sizeof(*umem->pgs), GFP_KERNEL | __GFP_NOWARN); + umem->pgs = kvzalloc_objs(*umem->pgs, umem->npgs, + GFP_KERNEL | __GFP_NOWARN); if (!umem->pgs) return -ENOMEM; @@ -249,7 +250,7 @@ struct xdp_umem *xdp_umem_create(struct xdp_umem_reg *mr) struct xdp_umem *umem; int err; - umem = kzalloc(sizeof(*umem), GFP_KERNEL); + umem = kzalloc_obj(*umem); if (!umem) return ERR_PTR(-ENOMEM); diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c index 3b46bc635c43..6149f6a79897 100644 --- a/net/xdp/xsk.c +++ b/net/xdp/xsk.c @@ -167,26 +167,32 @@ static int xsk_rcv_zc(struct xdp_sock *xs, struct xdp_buff *xdp, u32 len) struct xdp_buff_xsk *pos, *tmp; struct list_head *xskb_list; u32 contd = 0; + u32 num_desc; int err; - if (frags) - contd = XDP_PKT_CONTD; - - err = __xsk_rcv_zc(xs, xskb, len, contd); - if (err) - goto err; - if (likely(!frags)) + if (likely(!frags)) { + err = __xsk_rcv_zc(xs, xskb, len, contd); + if (err) + goto err; return 0; + } + contd = XDP_PKT_CONTD; + num_desc = xdp_get_shared_info_from_buff(xdp)->nr_frags + 1; + if (xskq_prod_nb_free(xs->rx, num_desc) < num_desc) { + xs->rx_queue_full++; + err = -ENOBUFS; + goto err; + } + + __xsk_rcv_zc(xs, xskb, len, contd); xskb_list = &xskb->pool->xskb_list; list_for_each_entry_safe(pos, tmp, xskb_list, list_node) { if (list_is_singular(xskb_list)) contd = 0; len = pos->xdp.data_end - pos->xdp.data; - err = __xsk_rcv_zc(xs, pos, len, contd); - if (err) - goto err; - list_del(&pos->list_node); + __xsk_rcv_zc(xs, pos, len, contd); + list_del_init(&pos->list_node); } return 0; diff --git a/net/xdp/xsk_buff_pool.c b/net/xdp/xsk_buff_pool.c index cd5125b6af53..37b7a68b89b3 100644 --- a/net/xdp/xsk_buff_pool.c +++ b/net/xdp/xsk_buff_pool.c @@ -42,8 +42,7 @@ void xp_destroy(struct xsk_buff_pool *pool) int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs) { - pool->tx_descs = kvcalloc(xs->tx->nentries, sizeof(*pool->tx_descs), - GFP_KERNEL); + pool->tx_descs = kvzalloc_objs(*pool->tx_descs, xs->tx->nentries); if (!pool->tx_descs) return -ENOMEM; @@ -59,11 +58,11 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, u32 i, entries; entries = unaligned ? umem->chunks : 0; - pool = kvzalloc(struct_size(pool, free_heads, entries), GFP_KERNEL); + pool = kvzalloc_flex(*pool, free_heads, entries); if (!pool) goto out; - pool->heads = kvcalloc(umem->chunks, sizeof(*pool->heads), GFP_KERNEL); + pool->heads = kvzalloc_objs(*pool->heads, umem->chunks); if (!pool->heads) goto out; @@ -328,11 +327,11 @@ static struct xsk_dma_map *xp_create_dma_map(struct device *dev, struct net_devi { struct xsk_dma_map *dma_map; - dma_map = kzalloc(sizeof(*dma_map), GFP_KERNEL); + dma_map = kzalloc_obj(*dma_map); if (!dma_map) return NULL; - dma_map->dma_pages = kvcalloc(nr_pages, sizeof(*dma_map->dma_pages), GFP_KERNEL); + dma_map->dma_pages = kvzalloc_objs(*dma_map->dma_pages, nr_pages); if (!dma_map->dma_pages) { kfree(dma_map); return NULL; @@ -420,7 +419,8 @@ static int xp_init_dma_info(struct xsk_buff_pool *pool, struct xsk_dma_map *dma_ } } - pool->dma_pages = kvcalloc(dma_map->dma_pages_cnt, sizeof(*pool->dma_pages), GFP_KERNEL); + pool->dma_pages = kvzalloc_objs(*pool->dma_pages, + dma_map->dma_pages_cnt); if (!pool->dma_pages) return -ENOMEM; diff --git a/net/xdp/xsk_queue.c b/net/xdp/xsk_queue.c index d2c264030017..4dd01b7d858e 100644 --- a/net/xdp/xsk_queue.c +++ b/net/xdp/xsk_queue.c @@ -26,7 +26,7 @@ struct xsk_queue *xskq_create(u32 nentries, bool umem_queue) struct xsk_queue *q; size_t size; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c index bf744ac9d5a7..e1b11ab59f6e 100644 --- a/net/xfrm/espintcp.c +++ b/net/xfrm/espintcp.c @@ -465,7 +465,7 @@ static int espintcp_init_sk(struct sock *sk) if (sk->sk_user_data) return -EBUSY; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; @@ -536,7 +536,7 @@ static void espintcp_close(struct sock *sk, long timeout) sk->sk_prot = &tcp_prot; barrier(); - cancel_work_sync(&ctx->work); + disable_work_sync(&ctx->work); strp_done(&ctx->strp); skb_queue_purge(&ctx->out_queue); diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 52ae0e034d29..550457e4c4f0 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -544,6 +544,14 @@ static int xfrm_dev_down(struct net_device *dev) return NOTIFY_DONE; } +static int xfrm_dev_unregister(struct net_device *dev) +{ + xfrm_dev_state_flush(dev_net(dev), dev, true); + xfrm_dev_policy_flush(dev_net(dev), dev, true); + + return NOTIFY_DONE; +} + static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); @@ -556,8 +564,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void return xfrm_api_check(dev); case NETDEV_DOWN: - case NETDEV_UNREGISTER: return xfrm_dev_down(dev); + + case NETDEV_UNREGISTER: + return xfrm_dev_unregister(dev); } return NOTIFY_DONE; } diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c index 43fdc6ed8dd1..5f38dff16177 100644 --- a/net/xfrm/xfrm_ipcomp.c +++ b/net/xfrm/xfrm_ipcomp.c @@ -336,7 +336,7 @@ int ipcomp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack) } err = -ENOMEM; - ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL); + ipcd = kzalloc_obj(*ipcd); if (!ipcd) goto out; diff --git a/net/xfrm/xfrm_iptfs.c b/net/xfrm/xfrm_iptfs.c index 3b6d7284fc70..050a82101ca5 100644 --- a/net/xfrm/xfrm_iptfs.c +++ b/net/xfrm/xfrm_iptfs.c @@ -2526,8 +2526,8 @@ static int iptfs_user_init(struct net *net, struct xfrm_state *x, nla_get_u16(attrs[XFRMA_IPTFS_REORDER_WINDOW]); /* saved array is for saving 1..N seq nums from wantseq */ if (xc->reorder_win_size) { - xtfs->w_saved = kcalloc(xc->reorder_win_size, - sizeof(*xtfs->w_saved), GFP_KERNEL); + xtfs->w_saved = kzalloc_objs(*xtfs->w_saved, + xc->reorder_win_size); if (!xtfs->w_saved) { NL_SET_ERR_MSG(extack, "Cannot alloc reorder window"); return -ENOMEM; @@ -2658,8 +2658,8 @@ static int iptfs_clone_state(struct xfrm_state *x, struct xfrm_state *orig) xtfs->ra_newskb = NULL; if (xtfs->cfg.reorder_win_size) { - xtfs->w_saved = kcalloc(xtfs->cfg.reorder_win_size, - sizeof(*xtfs->w_saved), GFP_KERNEL); + xtfs->w_saved = kzalloc_objs(*xtfs->w_saved, + xtfs->cfg.reorder_win_size); if (!xtfs->w_saved) { kfree_sensitive(xtfs); return -ENOMEM; @@ -2677,7 +2677,7 @@ static int iptfs_init_state(struct xfrm_state *x) /* We have arrived here from xfrm_state_clone() */ xtfs = x->mode_data; } else { - xtfs = kzalloc(sizeof(*xtfs), GFP_KERNEL); + xtfs = kzalloc_obj(*xtfs); if (!xtfs) return -ENOMEM; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 62486f866975..9e1a522ab1c5 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -429,7 +429,7 @@ struct xfrm_policy *xfrm_policy_alloc(struct net *net, gfp_t gfp) { struct xfrm_policy *policy; - policy = kzalloc(sizeof(struct xfrm_policy), gfp); + policy = kzalloc_obj(struct xfrm_policy, gfp); if (policy) { write_pnet(&policy->xp_net, net); @@ -765,7 +765,7 @@ xfrm_policy_inexact_alloc_bin(const struct xfrm_policy *pol, u8 dir) if (bin) return bin; - bin = kzalloc(sizeof(*bin), GFP_ATOMIC); + bin = kzalloc_obj(*bin, GFP_ATOMIC); if (!bin) return NULL; @@ -836,7 +836,7 @@ xfrm_pol_inexact_node_alloc(const xfrm_address_t *addr, u8 prefixlen) { struct xfrm_pol_inexact_node *node; - node = kzalloc(sizeof(*node), GFP_ATOMIC); + node = kzalloc_obj(*node, GFP_ATOMIC); if (node) xfrm_pol_inexact_node_init(node, addr, prefixlen); @@ -3801,8 +3801,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, struct xfrm_tmpl *tp[XFRM_MAX_DEPTH]; struct xfrm_tmpl *stp[XFRM_MAX_DEPTH]; struct xfrm_tmpl **tpp = tp; + int i, k = 0; int ti = 0; - int i, k; sp = skb_sec_path(skb); if (!sp) @@ -3828,6 +3828,12 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, tpp = stp; } + if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET && sp == &dummy) + /* This policy template was already checked by HW + * and secpath was removed in __xfrm_policy_check2. + */ + goto out; + /* For each tunnel xfrm, find the first matching tmpl. * For each tmpl before that, find corresponding xfrm. * Order is _important_. Later we will implement @@ -3837,7 +3843,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, * verified to allow them to be skipped in future policy * checks (e.g. nested tunnels). */ - for (i = xfrm_nr-1, k = 0; i >= 0; i--) { + for (i = xfrm_nr - 1; i >= 0; i--) { k = xfrm_policy_ok(tpp[i], sp, k, family, if_id); if (k < 0) { if (k < -1) @@ -3853,6 +3859,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, goto reject; } +out: xfrm_pols_put(pols, npols); sp->verified_cnt = k; diff --git a/rust/Makefile b/rust/Makefile index 757974551359..9801af2e1e02 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -148,7 +148,8 @@ doctests_modifiers_workaround := $(rustdoc_modifiers_workaround)$(if $(call rust quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) $(filter-out $(skip_flags) --remap-path-prefix=%,$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ + $(RUSTDOC) $(filter-out $(skip_flags) --remap-path-prefix=% --remap-path-scope=%, \ + $(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ $(rustc_target_flags) -L$(objtree)/$(obj) \ -Zunstable-options --generate-link-to-definition \ --output $(rustdoc_output) \ @@ -334,7 +335,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC TK $< rm -rf $(objtree)/$(obj)/test/doctests/kernel; \ mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) --test $(filter-out --remap-path-prefix=%,$(rust_flags)) \ + $(RUSTDOC) --test $(filter-out --remap-path-prefix=% --remap-path-scope=%,$(rust_flags)) \ -L$(objtree)/$(obj) --extern ffi --extern pin_init \ --extern kernel --extern build_error --extern macros \ --extern bindings --extern uapi \ @@ -526,11 +527,9 @@ quiet_cmd_rustc_procmacrolibrary = $(RUSTC_OR_CLIPPY_QUIET) PL $@ cmd_rustc_procmacrolibrary = \ $(if $(skip_clippy),$(RUSTC),$(RUSTC_OR_CLIPPY)) \ $(filter-out $(skip_flags),$(rust_common_flags) $(rustc_target_flags)) \ - --emit=dep-info,link --crate-type rlib -O \ + --emit=dep-info=$(depfile) --emit=link=$@ --crate-type rlib -O \ --out-dir $(objtree)/$(obj) -L$(objtree)/$(obj) \ - --crate-name $(patsubst lib%.rlib,%,$(notdir $@)) $<; \ - mv $(objtree)/$(obj)/$(patsubst lib%.rlib,%,$(notdir $@)).d $(depfile); \ - sed -i '/^\#/d' $(depfile) + --crate-name $(patsubst lib%.rlib,%,$(notdir $@)) $< $(obj)/libproc_macro2.rlib: private skip_clippy = 1 $(obj)/libproc_macro2.rlib: private rustc_target_flags = $(proc_macro2-flags) @@ -570,6 +569,8 @@ $(obj)/$(libpin_init_internal_name): $(src)/pin-init/internal/src/lib.rs \ $(obj)/libproc_macro2.rlib $(obj)/libquote.rlib $(obj)/libsyn.rlib FORCE +$(call if_changed_dep,rustc_procmacro) +# `rustc` requires `-Zunstable-options` to use custom target specifications +# since Rust 1.95.0 (https://github.com/rust-lang/rust/pull/151534). quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L $@ cmd_rustc_library = \ OBJTREE=$(abspath $(objtree)) \ @@ -580,6 +581,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L --crate-type rlib -L$(objtree)/$(obj) \ --crate-name $(patsubst %.o,%,$(notdir $@)) $< \ --sysroot=/dev/null \ + -Zunstable-options \ $(if $(rustc_objcopy),;$(OBJCOPY) $(rustc_objcopy) $@) \ $(cmd_objtool) diff --git a/rust/bindings/lib.rs b/rust/bindings/lib.rs index 0c57cf9b4004..19f57c5b2fa2 100644 --- a/rust/bindings/lib.rs +++ b/rust/bindings/lib.rs @@ -67,3 +67,16 @@ mod bindings_helper { } pub use bindings_raw::*; + +pub const compat_ptr_ioctl: Option< + unsafe extern "C" fn(*mut file, ffi::c_uint, ffi::c_ulong) -> ffi::c_long, +> = { + #[cfg(CONFIG_COMPAT)] + { + Some(bindings_raw::compat_ptr_ioctl) + } + #[cfg(not(CONFIG_COMPAT))] + { + None + } +}; diff --git a/rust/helpers/binder.c b/rust/helpers/binder.c index 224d38a92f1d..a2327f1b3c94 100644 --- a/rust/helpers/binder.c +++ b/rust/helpers/binder.c @@ -7,20 +7,21 @@ #include #include -unsigned long rust_helper_list_lru_count(struct list_lru *lru) +__rust_helper unsigned long rust_helper_list_lru_count(struct list_lru *lru) { return list_lru_count(lru); } -unsigned long rust_helper_list_lru_walk(struct list_lru *lru, - list_lru_walk_cb isolate, void *cb_arg, - unsigned long nr_to_walk) +__rust_helper unsigned long rust_helper_list_lru_walk(struct list_lru *lru, + list_lru_walk_cb isolate, + void *cb_arg, + unsigned long nr_to_walk) { return list_lru_walk(lru, isolate, cb_arg, nr_to_walk); } -void rust_helper_init_task_work(struct callback_head *twork, - task_work_func_t func) +__rust_helper void rust_helper_init_task_work(struct callback_head *twork, + task_work_func_t func) { init_task_work(twork, func); } diff --git a/rust/helpers/usb.c b/rust/helpers/usb.c index fb2aad0cbf4d..eff1cf7be3c2 100644 --- a/rust/helpers/usb.c +++ b/rust/helpers/usb.c @@ -2,7 +2,8 @@ #include -struct usb_device *rust_helper_interface_to_usbdev(struct usb_interface *intf) +__rust_helper struct usb_device * +rust_helper_interface_to_usbdev(struct usb_interface *intf) { return interface_to_usbdev(intf); } diff --git a/rust/kernel/cpufreq.rs b/rust/kernel/cpufreq.rs index 76faa1ac8501..f5adee48d40c 100644 --- a/rust/kernel/cpufreq.rs +++ b/rust/kernel/cpufreq.rs @@ -401,6 +401,7 @@ pub fn to_table(mut self) -> Result { /// ``` /// use kernel::cpufreq::{DEFAULT_TRANSITION_LATENCY_NS, Policy}; /// +/// #[allow(clippy::double_parens, reason = "False positive before 1.92.0")] /// fn update_policy(policy: &mut Policy) { /// policy /// .set_dvfs_possible_from_any_cpu(true) diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs index 909d56fd5118..a396f8435739 100644 --- a/rust/kernel/dma.rs +++ b/rust/kernel/dma.rs @@ -461,6 +461,19 @@ pub fn size(&self) -> usize { self.count * core::mem::size_of::() } + /// Returns the raw pointer to the allocated region in the CPU's virtual address space. + #[inline] + pub fn as_ptr(&self) -> *const [T] { + core::ptr::slice_from_raw_parts(self.cpu_addr.as_ptr(), self.count) + } + + /// Returns the raw pointer to the allocated region in the CPU's virtual address space as + /// a mutable pointer. + #[inline] + pub fn as_mut_ptr(&self) -> *mut [T] { + core::ptr::slice_from_raw_parts_mut(self.cpu_addr.as_ptr(), self.count) + } + /// Returns the base address to the allocated region in the CPU's virtual address space. pub fn start_ptr(&self) -> *const T { self.cpu_addr.as_ptr() @@ -581,23 +594,6 @@ pub unsafe fn write(&mut self, src: &[T], offset: usize) -> Result { Ok(()) } - /// Returns a pointer to an element from the region with bounds checking. `offset` is in - /// units of `T`, not the number of bytes. - /// - /// Public but hidden since it should only be used from [`dma_read`] and [`dma_write`] macros. - #[doc(hidden)] - pub fn item_from_index(&self, offset: usize) -> Result<*mut T> { - if offset >= self.count { - return Err(EINVAL); - } - // SAFETY: - // - The pointer is valid due to type invariant on `CoherentAllocation` - // and we've just checked that the range and index is within bounds. - // - `offset` can't overflow since it is smaller than `self.count` and we've checked - // that `self.count` won't overflow early in the constructor. - Ok(unsafe { self.cpu_addr.as_ptr().add(offset) }) - } - /// Reads the value of `field` and ensures that its type is [`FromBytes`]. /// /// # Safety @@ -670,6 +666,9 @@ unsafe impl Send for CoherentAllocation {} /// Reads a field of an item from an allocated region of structs. /// +/// The syntax is of the form `kernel::dma_read!(dma, proj)` where `dma` is an expression evaluating +/// to a [`CoherentAllocation`] and `proj` is a [projection specification](kernel::ptr::project!). +/// /// # Examples /// /// ``` @@ -684,36 +683,29 @@ unsafe impl Send for CoherentAllocation {} /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; /// /// # fn test(alloc: &kernel::dma::CoherentAllocation) -> Result { -/// let whole = kernel::dma_read!(alloc[2]); -/// let field = kernel::dma_read!(alloc[1].field); +/// let whole = kernel::dma_read!(alloc, [2]?); +/// let field = kernel::dma_read!(alloc, [1]?.field); /// # Ok::<(), Error>(()) } /// ``` #[macro_export] macro_rules! dma_read { - ($dma:expr, $idx: expr, $($field:tt)*) => {{ - (|| -> ::core::result::Result<_, $crate::error::Error> { - let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; - // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be - // dereferenced. The compiler also further validates the expression on whether `field` - // is a member of `item` when expanded by the macro. - unsafe { - let ptr_field = ::core::ptr::addr_of!((*item) $($field)*); - ::core::result::Result::Ok( - $crate::dma::CoherentAllocation::field_read(&$dma, ptr_field) - ) - } - })() + ($dma:expr, $($proj:tt)*) => {{ + let dma = &$dma; + let ptr = $crate::ptr::project!( + $crate::dma::CoherentAllocation::as_ptr(dma), $($proj)* + ); + // SAFETY: The pointer created by the projection is within the DMA region. + unsafe { $crate::dma::CoherentAllocation::field_read(dma, ptr) } }}; - ($dma:ident [ $idx:expr ] $($field:tt)* ) => { - $crate::dma_read!($dma, $idx, $($field)*) - }; - ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => { - $crate::dma_read!($($dma).*, $idx, $($field)*) - }; } /// Writes to a field of an item from an allocated region of structs. /// +/// The syntax is of the form `kernel::dma_write!(dma, proj, val)` where `dma` is an expression +/// evaluating to a [`CoherentAllocation`], `proj` is a +/// [projection specification](kernel::ptr::project!), and `val` is the value to be written to the +/// projected location. +/// /// # Examples /// /// ``` @@ -728,37 +720,31 @@ macro_rules! dma_read { /// unsafe impl kernel::transmute::AsBytes for MyStruct{}; /// /// # fn test(alloc: &kernel::dma::CoherentAllocation) -> Result { -/// kernel::dma_write!(alloc[2].member = 0xf); -/// kernel::dma_write!(alloc[1] = MyStruct { member: 0xf }); +/// kernel::dma_write!(alloc, [2]?.member, 0xf); +/// kernel::dma_write!(alloc, [1]?, MyStruct { member: 0xf }); /// # Ok::<(), Error>(()) } /// ``` #[macro_export] macro_rules! dma_write { - ($dma:ident [ $idx:expr ] $($field:tt)*) => {{ - $crate::dma_write!($dma, $idx, $($field)*) + (@parse [$dma:expr] [$($proj:tt)*] [, $val:expr]) => {{ + let dma = &$dma; + let ptr = $crate::ptr::project!( + mut $crate::dma::CoherentAllocation::as_mut_ptr(dma), $($proj)* + ); + let val = $val; + // SAFETY: The pointer created by the projection is within the DMA region. + unsafe { $crate::dma::CoherentAllocation::field_write(dma, ptr, val) } }}; - ($($dma:ident).* [ $idx:expr ] $($field:tt)* ) => {{ - $crate::dma_write!($($dma).*, $idx, $($field)*) - }}; - ($dma:expr, $idx: expr, = $val:expr) => { - (|| -> ::core::result::Result<_, $crate::error::Error> { - let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; - // SAFETY: `item_from_index` ensures that `item` is always a valid item. - unsafe { $crate::dma::CoherentAllocation::field_write(&$dma, item, $val) } - ::core::result::Result::Ok(()) - })() + (@parse [$dma:expr] [$($proj:tt)*] [.$field:tt $($rest:tt)*]) => { + $crate::dma_write!(@parse [$dma] [$($proj)* .$field] [$($rest)*]) }; - ($dma:expr, $idx: expr, $(.$field:ident)* = $val:expr) => { - (|| -> ::core::result::Result<_, $crate::error::Error> { - let item = $crate::dma::CoherentAllocation::item_from_index(&$dma, $idx)?; - // SAFETY: `item_from_index` ensures that `item` is always a valid pointer and can be - // dereferenced. The compiler also further validates the expression on whether `field` - // is a member of `item` when expanded by the macro. - unsafe { - let ptr_field = ::core::ptr::addr_of_mut!((*item) $(.$field)*); - $crate::dma::CoherentAllocation::field_write(&$dma, ptr_field, $val) - } - ::core::result::Result::Ok(()) - })() + (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr]? $($rest:tt)*]) => { + $crate::dma_write!(@parse [$dma] [$($proj)* [$index]?] [$($rest)*]) + }; + (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr] $($rest:tt)*]) => { + $crate::dma_write!(@parse [$dma] [$($proj)* [$index]] [$($rest)*]) + }; + ($dma:expr, $($rest:tt)*) => { + $crate::dma_write!(@parse [$dma] [] [$($rest)*]) }; } diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs index c1cca7b438c3..e5fba6bf6db0 100644 --- a/rust/kernel/io.rs +++ b/rust/kernel/io.rs @@ -139,9 +139,9 @@ pub fn maxsize(&self) -> usize { /// Internal helper macros used to invoke C MMIO read functions. /// -/// This macro is intended to be used by higher-level MMIO access macros (define_read) and provides -/// a unified expansion for infallible vs. fallible read semantics. It emits a direct call into the -/// corresponding C helper and performs the required cast to the Rust return type. +/// This macro is intended to be used by higher-level MMIO access macros (io_define_read) and +/// provides a unified expansion for infallible vs. fallible read semantics. It emits a direct call +/// into the corresponding C helper and performs the required cast to the Rust return type. /// /// # Parameters /// @@ -166,9 +166,9 @@ macro_rules! call_mmio_read { /// Internal helper macros used to invoke C MMIO write functions. /// -/// This macro is intended to be used by higher-level MMIO access macros (define_write) and provides -/// a unified expansion for infallible vs. fallible write semantics. It emits a direct call into the -/// corresponding C helper and performs the required cast to the Rust return type. +/// This macro is intended to be used by higher-level MMIO access macros (io_define_write) and +/// provides a unified expansion for infallible vs. fallible write semantics. It emits a direct call +/// into the corresponding C helper and performs the required cast to the Rust return type. /// /// # Parameters /// @@ -193,7 +193,30 @@ macro_rules! call_mmio_write { }}; } -macro_rules! define_read { +/// Generates an accessor method for reading from an I/O backend. +/// +/// This macro reduces boilerplate by automatically generating either compile-time bounds-checked +/// (infallible) or runtime bounds-checked (fallible) read methods. It abstracts the address +/// calculation and bounds checking, and delegates the actual I/O read operation to a specified +/// helper macro, making it generic over different I/O backends. +/// +/// # Parameters +/// +/// * `infallible` / `fallible` - Determines the bounds-checking strategy. `infallible` relies on +/// `IoKnownSize` for compile-time checks and returns the value directly. `fallible` performs +/// runtime checks against `maxsize()` and returns a `Result`. +/// * `$(#[$attr:meta])*` - Optional attributes to apply to the generated method (e.g., +/// `#[cfg(CONFIG_64BIT)]` or inline directives). +/// * `$vis:vis` - The visibility of the generated method (e.g., `pub`). +/// * `$name:ident` / `$try_name:ident` - The name of the generated method (e.g., `read32`, +/// `try_read8`). +/// * `$call_macro:ident` - The backend-specific helper macro used to emit the actual I/O call +/// (e.g., `call_mmio_read`). +/// * `$c_fn:ident` - The backend-specific C function or identifier to be passed into the +/// `$call_macro`. +/// * `$type_name:ty` - The Rust type of the value being read (e.g., `u8`, `u32`). +#[macro_export] +macro_rules! io_define_read { (infallible, $(#[$attr:meta])* $vis:vis $name:ident, $call_macro:ident($c_fn:ident) -> $type_name:ty) => { /// Read IO data from a given offset known at compile time. @@ -226,9 +249,33 @@ macro_rules! define_read { } }; } -pub(crate) use define_read; +pub use io_define_read; -macro_rules! define_write { +/// Generates an accessor method for writing to an I/O backend. +/// +/// This macro reduces boilerplate by automatically generating either compile-time bounds-checked +/// (infallible) or runtime bounds-checked (fallible) write methods. It abstracts the address +/// calculation and bounds checking, and delegates the actual I/O write operation to a specified +/// helper macro, making it generic over different I/O backends. +/// +/// # Parameters +/// +/// * `infallible` / `fallible` - Determines the bounds-checking strategy. `infallible` relies on +/// `IoKnownSize` for compile-time checks and returns `()`. `fallible` performs runtime checks +/// against `maxsize()` and returns a `Result`. +/// * `$(#[$attr:meta])*` - Optional attributes to apply to the generated method (e.g., +/// `#[cfg(CONFIG_64BIT)]` or inline directives). +/// * `$vis:vis` - The visibility of the generated method (e.g., `pub`). +/// * `$name:ident` / `$try_name:ident` - The name of the generated method (e.g., `write32`, +/// `try_write8`). +/// * `$call_macro:ident` - The backend-specific helper macro used to emit the actual I/O call +/// (e.g., `call_mmio_write`). +/// * `$c_fn:ident` - The backend-specific C function or identifier to be passed into the +/// `$call_macro`. +/// * `$type_name:ty` - The Rust type of the value being written (e.g., `u8`, `u32`). Note the use +/// of `<-` before the type to denote a write operation. +#[macro_export] +macro_rules! io_define_write { (infallible, $(#[$attr:meta])* $vis:vis $name:ident, $call_macro:ident($c_fn:ident) <- $type_name:ty) => { /// Write IO data from a given offset known at compile time. @@ -259,7 +306,7 @@ macro_rules! define_write { } }; } -pub(crate) use define_write; +pub use io_define_write; /// Checks whether an access of type `U` at the given `offset` /// is valid within this region. @@ -509,40 +556,40 @@ fn maxsize(&self) -> usize { self.0.maxsize() } - define_read!(fallible, try_read8, call_mmio_read(readb) -> u8); - define_read!(fallible, try_read16, call_mmio_read(readw) -> u16); - define_read!(fallible, try_read32, call_mmio_read(readl) -> u32); - define_read!( + io_define_read!(fallible, try_read8, call_mmio_read(readb) -> u8); + io_define_read!(fallible, try_read16, call_mmio_read(readw) -> u16); + io_define_read!(fallible, try_read32, call_mmio_read(readl) -> u32); + io_define_read!( fallible, #[cfg(CONFIG_64BIT)] try_read64, call_mmio_read(readq) -> u64 ); - define_write!(fallible, try_write8, call_mmio_write(writeb) <- u8); - define_write!(fallible, try_write16, call_mmio_write(writew) <- u16); - define_write!(fallible, try_write32, call_mmio_write(writel) <- u32); - define_write!( + io_define_write!(fallible, try_write8, call_mmio_write(writeb) <- u8); + io_define_write!(fallible, try_write16, call_mmio_write(writew) <- u16); + io_define_write!(fallible, try_write32, call_mmio_write(writel) <- u32); + io_define_write!( fallible, #[cfg(CONFIG_64BIT)] try_write64, call_mmio_write(writeq) <- u64 ); - define_read!(infallible, read8, call_mmio_read(readb) -> u8); - define_read!(infallible, read16, call_mmio_read(readw) -> u16); - define_read!(infallible, read32, call_mmio_read(readl) -> u32); - define_read!( + io_define_read!(infallible, read8, call_mmio_read(readb) -> u8); + io_define_read!(infallible, read16, call_mmio_read(readw) -> u16); + io_define_read!(infallible, read32, call_mmio_read(readl) -> u32); + io_define_read!( infallible, #[cfg(CONFIG_64BIT)] read64, call_mmio_read(readq) -> u64 ); - define_write!(infallible, write8, call_mmio_write(writeb) <- u8); - define_write!(infallible, write16, call_mmio_write(writew) <- u16); - define_write!(infallible, write32, call_mmio_write(writel) <- u32); - define_write!( + io_define_write!(infallible, write8, call_mmio_write(writeb) <- u8); + io_define_write!(infallible, write16, call_mmio_write(writew) <- u16); + io_define_write!(infallible, write32, call_mmio_write(writel) <- u32); + io_define_write!( infallible, #[cfg(CONFIG_64BIT)] write64, @@ -566,40 +613,40 @@ pub unsafe fn from_raw(raw: &MmioRaw) -> &Self { unsafe { &*core::ptr::from_ref(raw).cast() } } - define_read!(infallible, pub read8_relaxed, call_mmio_read(readb_relaxed) -> u8); - define_read!(infallible, pub read16_relaxed, call_mmio_read(readw_relaxed) -> u16); - define_read!(infallible, pub read32_relaxed, call_mmio_read(readl_relaxed) -> u32); - define_read!( + io_define_read!(infallible, pub read8_relaxed, call_mmio_read(readb_relaxed) -> u8); + io_define_read!(infallible, pub read16_relaxed, call_mmio_read(readw_relaxed) -> u16); + io_define_read!(infallible, pub read32_relaxed, call_mmio_read(readl_relaxed) -> u32); + io_define_read!( infallible, #[cfg(CONFIG_64BIT)] pub read64_relaxed, call_mmio_read(readq_relaxed) -> u64 ); - define_read!(fallible, pub try_read8_relaxed, call_mmio_read(readb_relaxed) -> u8); - define_read!(fallible, pub try_read16_relaxed, call_mmio_read(readw_relaxed) -> u16); - define_read!(fallible, pub try_read32_relaxed, call_mmio_read(readl_relaxed) -> u32); - define_read!( + io_define_read!(fallible, pub try_read8_relaxed, call_mmio_read(readb_relaxed) -> u8); + io_define_read!(fallible, pub try_read16_relaxed, call_mmio_read(readw_relaxed) -> u16); + io_define_read!(fallible, pub try_read32_relaxed, call_mmio_read(readl_relaxed) -> u32); + io_define_read!( fallible, #[cfg(CONFIG_64BIT)] pub try_read64_relaxed, call_mmio_read(readq_relaxed) -> u64 ); - define_write!(infallible, pub write8_relaxed, call_mmio_write(writeb_relaxed) <- u8); - define_write!(infallible, pub write16_relaxed, call_mmio_write(writew_relaxed) <- u16); - define_write!(infallible, pub write32_relaxed, call_mmio_write(writel_relaxed) <- u32); - define_write!( + io_define_write!(infallible, pub write8_relaxed, call_mmio_write(writeb_relaxed) <- u8); + io_define_write!(infallible, pub write16_relaxed, call_mmio_write(writew_relaxed) <- u16); + io_define_write!(infallible, pub write32_relaxed, call_mmio_write(writel_relaxed) <- u32); + io_define_write!( infallible, #[cfg(CONFIG_64BIT)] pub write64_relaxed, call_mmio_write(writeq_relaxed) <- u64 ); - define_write!(fallible, pub try_write8_relaxed, call_mmio_write(writeb_relaxed) <- u8); - define_write!(fallible, pub try_write16_relaxed, call_mmio_write(writew_relaxed) <- u16); - define_write!(fallible, pub try_write32_relaxed, call_mmio_write(writel_relaxed) <- u32); - define_write!( + io_define_write!(fallible, pub try_write8_relaxed, call_mmio_write(writeb_relaxed) <- u8); + io_define_write!(fallible, pub try_write16_relaxed, call_mmio_write(writew_relaxed) <- u16); + io_define_write!(fallible, pub try_write32_relaxed, call_mmio_write(writel_relaxed) <- u32); + io_define_write!( fallible, #[cfg(CONFIG_64BIT)] pub try_write64_relaxed, diff --git a/rust/kernel/irq/request.rs b/rust/kernel/irq/request.rs index 67769800117c..7a36f790593e 100644 --- a/rust/kernel/irq/request.rs +++ b/rust/kernel/irq/request.rs @@ -260,7 +260,10 @@ pub fn synchronize(&self, dev: &Device) -> Result { /// # Safety /// /// This function should be only used as the callback in `request_irq`. -unsafe extern "C" fn handle_irq_callback(_irq: i32, ptr: *mut c_void) -> c_uint { +unsafe extern "C" fn handle_irq_callback( + _irq: i32, + ptr: *mut c_void, +) -> c_uint { // SAFETY: `ptr` is a pointer to `Registration` set in `Registration::new` let registration = unsafe { &*(ptr as *const Registration) }; // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq @@ -478,7 +481,7 @@ pub fn synchronize(&self, dev: &Device) -> Result { /// # Safety /// /// This function should be only used as the callback in `request_threaded_irq`. -unsafe extern "C" fn handle_threaded_irq_callback( +unsafe extern "C" fn handle_threaded_irq_callback( _irq: i32, ptr: *mut c_void, ) -> c_uint { @@ -494,7 +497,10 @@ pub fn synchronize(&self, dev: &Device) -> Result { /// # Safety /// /// This function should be only used as the callback in `request_threaded_irq`. -unsafe extern "C" fn thread_fn_callback(_irq: i32, ptr: *mut c_void) -> c_uint { +unsafe extern "C" fn thread_fn_callback( + _irq: i32, + ptr: *mut c_void, +) -> c_uint { // SAFETY: `ptr` is a pointer to `ThreadedRegistration` set in `ThreadedRegistration::new` let registration = unsafe { &*(ptr as *const ThreadedRegistration) }; // SAFETY: The irq callback is removed before the device is unbound, so the fact that the irq diff --git a/rust/kernel/kunit.rs b/rust/kernel/kunit.rs index f93f24a60bdd..a1edf7491579 100644 --- a/rust/kernel/kunit.rs +++ b/rust/kernel/kunit.rs @@ -14,6 +14,10 @@ /// Public but hidden since it should only be used from KUnit generated code. #[doc(hidden)] pub fn err(args: fmt::Arguments<'_>) { + // `args` is unused if `CONFIG_PRINTK` is not set - this avoids a build-time warning. + #[cfg(not(CONFIG_PRINTK))] + let _ = args; + // SAFETY: The format string is null-terminated and the `%pA` specifier matches the argument we // are passing. #[cfg(CONFIG_PRINTK)] @@ -30,6 +34,10 @@ pub fn err(args: fmt::Arguments<'_>) { /// Public but hidden since it should only be used from KUnit generated code. #[doc(hidden)] pub fn info(args: fmt::Arguments<'_>) { + // `args` is unused if `CONFIG_PRINTK` is not set - this avoids a build-time warning. + #[cfg(not(CONFIG_PRINTK))] + let _ = args; + // SAFETY: The format string is null-terminated and the `%pA` specifier matches the argument we // are passing. #[cfg(CONFIG_PRINTK)] diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs index 3da92f18f4ee..d93292d47420 100644 --- a/rust/kernel/lib.rs +++ b/rust/kernel/lib.rs @@ -20,6 +20,7 @@ #![feature(generic_nonzero)] #![feature(inline_const)] #![feature(pointer_is_aligned)] +#![feature(slice_ptr_len)] // // Stable since Rust 1.80.0. #![feature(slice_flatten)] @@ -37,6 +38,9 @@ #![feature(const_ptr_write)] #![feature(const_refs_to_cell)] // +// Stable since Rust 1.84.0. +#![feature(strict_provenance)] +// // Expected to become stable. #![feature(arbitrary_self_types)] // diff --git a/rust/kernel/list/impl_list_item_mod.rs b/rust/kernel/list/impl_list_item_mod.rs index 202bc6f97c13..ee53d0387e63 100644 --- a/rust/kernel/list/impl_list_item_mod.rs +++ b/rust/kernel/list/impl_list_item_mod.rs @@ -84,11 +84,12 @@ macro_rules! impl_has_list_links_self_ptr { // right type. unsafe impl$(<$($generics)*>)? $crate::list::HasSelfPtr<$item_type $(, $id)?> for $self {} + // SAFETY: TODO. unsafe impl$(<$($generics)*>)? $crate::list::HasListLinks$(<$id>)? for $self { #[inline] unsafe fn raw_get_list_links(ptr: *mut Self) -> *mut $crate::list::ListLinks$(<$id>)? { - // SAFETY: The caller promises that the pointer is not dangling. let ptr: *mut $crate::list::ListLinksSelfPtr<$item_type $(, $id)?> = + // SAFETY: The caller promises that the pointer is not dangling. unsafe { ::core::ptr::addr_of_mut!((*ptr)$(.$field)*) }; ptr.cast() } @@ -217,7 +218,7 @@ unsafe fn view_value(me: *mut $crate::list::ListLinks<$num>) -> *const Self { // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it // points at the field `$field` in a value of type `Self`. Thus, reversing that // operation is still in-bounds of the allocation. - $crate::container_of!(me, Self, $($field).*) + unsafe { $crate::container_of!(me, Self, $($field).*) } } // GUARANTEES: @@ -242,7 +243,7 @@ unsafe fn post_remove(me: *mut $crate::list::ListLinks<$num>) -> *const Self { // SAFETY: `me` originates from the most recent call to `prepare_to_insert`, so it // points at the field `$field` in a value of type `Self`. Thus, reversing that // operation is still in-bounds of the allocation. - $crate::container_of!(me, Self, $($field).*) + unsafe { $crate::container_of!(me, Self, $($field).*) } } } )*}; @@ -270,9 +271,12 @@ unsafe fn prepare_to_insert(me: *const Self) -> *mut $crate::list::ListLinks<$nu // SAFETY: The caller promises that `me` points at a valid value of type `Self`. let links_field = unsafe { >::view_links(me) }; - let container = $crate::container_of!( - links_field, $crate::list::ListLinksSelfPtr, inner - ); + // SAFETY: TODO. + let container = unsafe { + $crate::container_of!( + links_field, $crate::list::ListLinksSelfPtr, inner + ) + }; // SAFETY: By the same reasoning above, `links_field` is a valid pointer. let self_ptr = unsafe { @@ -319,9 +323,12 @@ unsafe fn view_links(me: *const Self) -> *mut $crate::list::ListLinks<$num> { // `ListArc` containing `Self` until the next call to `post_remove`. The value cannot // be destroyed while a `ListArc` reference exists. unsafe fn view_value(links_field: *mut $crate::list::ListLinks<$num>) -> *const Self { - let container = $crate::container_of!( - links_field, $crate::list::ListLinksSelfPtr, inner - ); + // SAFETY: TODO. + let container = unsafe { + $crate::container_of!( + links_field, $crate::list::ListLinksSelfPtr, inner + ) + }; // SAFETY: By the same reasoning above, `links_field` is a valid pointer. let self_ptr = unsafe { diff --git a/rust/kernel/miscdevice.rs b/rust/kernel/miscdevice.rs index d698cddcb4a5..c3c2052c9206 100644 --- a/rust/kernel/miscdevice.rs +++ b/rust/kernel/miscdevice.rs @@ -20,7 +20,7 @@ seq_file::SeqFile, types::{ForeignOwnable, Opaque}, }; -use core::{marker::PhantomData, mem::MaybeUninit, pin::Pin}; +use core::{marker::PhantomData, pin::Pin}; /// Options for creating a misc device. #[derive(Copy, Clone)] @@ -32,8 +32,7 @@ pub struct MiscDeviceOptions { impl MiscDeviceOptions { /// Create a raw `struct miscdev` ready for registration. pub const fn into_raw(self) -> bindings::miscdevice { - // SAFETY: All zeros is valid for this C type. - let mut result: bindings::miscdevice = unsafe { MaybeUninit::zeroed().assume_init() }; + let mut result: bindings::miscdevice = pin_init::zeroed(); result.minor = bindings::MISC_DYNAMIC_MINOR as ffi::c_int; result.name = crate::str::as_char_ptr_in_const_context(self.name); result.fops = MiscdeviceVTable::::build(); @@ -411,7 +410,7 @@ impl MiscdeviceVTable { compat_ioctl: if T::HAS_COMPAT_IOCTL { Some(Self::compat_ioctl) } else if T::HAS_IOCTL { - Some(bindings::compat_ptr_ioctl) + bindings::compat_ptr_ioctl } else { None }, @@ -420,8 +419,7 @@ impl MiscdeviceVTable { } else { None }, - // SAFETY: All zeros is a valid value for `bindings::file_operations`. - ..unsafe { MaybeUninit::zeroed().assume_init() } + ..pin_init::zeroed() }; const fn build() -> &'static bindings::file_operations { diff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs index 6ca4cf75594c..fb6edab2aea7 100644 --- a/rust/kernel/pci/io.rs +++ b/rust/kernel/pci/io.rs @@ -8,8 +8,8 @@ device, devres::Devres, io::{ - define_read, - define_write, + io_define_read, + io_define_write, Io, IoCapable, IoKnownSize, @@ -88,7 +88,7 @@ pub struct ConfigSpace<'a, S: ConfigSpaceKind = Extended> { /// Internal helper macros used to invoke C PCI configuration space read functions. /// /// This macro is intended to be used by higher-level PCI configuration space access macros -/// (define_read) and provides a unified expansion for infallible vs. fallible read semantics. It +/// (io_define_read) and provides a unified expansion for infallible vs. fallible read semantics. It /// emits a direct call into the corresponding C helper and performs the required cast to the Rust /// return type. /// @@ -117,9 +117,9 @@ macro_rules! call_config_read { /// Internal helper macros used to invoke C PCI configuration space write functions. /// /// This macro is intended to be used by higher-level PCI configuration space access macros -/// (define_write) and provides a unified expansion for infallible vs. fallible read semantics. It -/// emits a direct call into the corresponding C helper and performs the required cast to the Rust -/// return type. +/// (io_define_write) and provides a unified expansion for infallible vs. fallible read semantics. +/// It emits a direct call into the corresponding C helper and performs the required cast to the +/// Rust return type. /// /// # Parameters /// @@ -163,13 +163,13 @@ fn maxsize(&self) -> usize { // PCI configuration space does not support fallible operations. // The default implementations from the Io trait are not used. - define_read!(infallible, read8, call_config_read(pci_read_config_byte) -> u8); - define_read!(infallible, read16, call_config_read(pci_read_config_word) -> u16); - define_read!(infallible, read32, call_config_read(pci_read_config_dword) -> u32); + io_define_read!(infallible, read8, call_config_read(pci_read_config_byte) -> u8); + io_define_read!(infallible, read16, call_config_read(pci_read_config_word) -> u16); + io_define_read!(infallible, read32, call_config_read(pci_read_config_dword) -> u32); - define_write!(infallible, write8, call_config_write(pci_write_config_byte) <- u8); - define_write!(infallible, write16, call_config_write(pci_write_config_word) <- u16); - define_write!(infallible, write32, call_config_write(pci_write_config_dword) <- u32); + io_define_write!(infallible, write8, call_config_write(pci_write_config_byte) <- u8); + io_define_write!(infallible, write16, call_config_write(pci_write_config_word) <- u16); + io_define_write!(infallible, write32, call_config_write(pci_write_config_dword) <- u32); } impl<'a, S: ConfigSpaceKind> IoKnownSize for ConfigSpace<'a, S> { diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs index 5b6a382637fe..bdc2d79ff669 100644 --- a/rust/kernel/ptr.rs +++ b/rust/kernel/ptr.rs @@ -2,7 +2,13 @@ //! Types and functions to work with pointers and addresses. -use core::mem::align_of; +pub mod projection; +pub use crate::project_pointer as project; + +use core::mem::{ + align_of, + size_of, // +}; use core::num::NonZero; /// Type representing an alignment, which is always a power of two. @@ -225,3 +231,25 @@ fn align_up(self, alignment: Alignment) -> Option { } impl_alignable_uint!(u8, u16, u32, u64, usize); + +/// Trait to represent compile-time known size information. +/// +/// This is a generalization of [`size_of`] that works for dynamically sized types. +pub trait KnownSize { + /// Get the size of an object of this type in bytes, with the metadata of the given pointer. + fn size(p: *const Self) -> usize; +} + +impl KnownSize for T { + #[inline(always)] + fn size(_: *const Self) -> usize { + size_of::() + } +} + +impl KnownSize for [T] { + #[inline(always)] + fn size(p: *const Self) -> usize { + p.len() * size_of::() + } +} diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs new file mode 100644 index 000000000000..140ea8e21617 --- /dev/null +++ b/rust/kernel/ptr/projection.rs @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Infrastructure for handling projections. + +use core::{ + mem::MaybeUninit, + ops::Deref, // +}; + +use crate::prelude::*; + +/// Error raised when a projection is attempted on an array or slice out of bounds. +pub struct OutOfBound; + +impl From for Error { + #[inline(always)] + fn from(_: OutOfBound) -> Self { + ERANGE + } +} + +/// A helper trait to perform index projection. +/// +/// This is similar to [`core::slice::SliceIndex`], but operates on raw pointers safely and +/// fallibly. +/// +/// # Safety +/// +/// The implementation of `index` and `get` (if [`Some`] is returned) must ensure that, if provided +/// input pointer `slice` and returned pointer `output`, then: +/// - `output` has the same provenance as `slice`; +/// - `output.byte_offset_from(slice)` is between 0 to +/// `KnownSize::size(slice) - KnownSize::size(output)`. +/// +/// This means that if the input pointer is valid, then pointer returned by `get` or `index` is +/// also valid. +#[diagnostic::on_unimplemented(message = "`{Self}` cannot be used to index `{T}`")] +#[doc(hidden)] +pub unsafe trait ProjectIndex: Sized { + type Output: ?Sized; + + /// Returns an index-projected pointer, if in bounds. + fn get(self, slice: *mut T) -> Option<*mut Self::Output>; + + /// Returns an index-projected pointer; fail the build if it cannot be proved to be in bounds. + #[inline(always)] + fn index(self, slice: *mut T) -> *mut Self::Output { + Self::get(self, slice).unwrap_or_else(|| build_error!()) + } +} + +// Forward array impl to slice impl. +// +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T; N]> for I +where + I: ProjectIndex<[T]>, +{ + type Output = >::Output; + + #[inline(always)] + fn get(self, slice: *mut [T; N]) -> Option<*mut Self::Output> { + >::get(self, slice) + } + + #[inline(always)] + fn index(self, slice: *mut [T; N]) -> *mut Self::Output { + >::index(self, slice) + } +} + +// SAFETY: `get`-returned pointer has the same provenance as `slice` and the offset is checked to +// not exceed the required bound. +unsafe impl ProjectIndex<[T]> for usize { + type Output = T; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut T> { + if self >= slice.len() { + None + } else { + Some(slice.cast::().wrapping_add(self)) + } + } +} + +// SAFETY: `get`-returned pointer has the same provenance as `slice` and the offset is checked to +// not exceed the required bound. +unsafe impl ProjectIndex<[T]> for core::ops::Range { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + let new_len = self.end.checked_sub(self.start)?; + if self.end > slice.len() { + return None; + } + Some(core::ptr::slice_from_raw_parts_mut( + slice.cast::().wrapping_add(self.start), + new_len, + )) + } +} + +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T]> for core::ops::RangeTo { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + (0..self.end).get(slice) + } +} + +// SAFETY: Safety requirement guaranteed by the forwarded impl. +unsafe impl ProjectIndex<[T]> for core::ops::RangeFrom { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + (self.start..slice.len()).get(slice) + } +} + +// SAFETY: `get` returned the pointer as is, so it always has the same provenance and offset of 0. +unsafe impl ProjectIndex<[T]> for core::ops::RangeFull { + type Output = [T]; + + #[inline(always)] + fn get(self, slice: *mut [T]) -> Option<*mut [T]> { + Some(slice) + } +} + +/// A helper trait to perform field projection. +/// +/// This trait has a `DEREF` generic parameter so it can be implemented twice for types that +/// implement [`Deref`]. This will cause an ambiguity error and thus block [`Deref`] types being +/// used as base of projection, as they can inject unsoundness. Users therefore must not specify +/// `DEREF` and should always leave it to be inferred. +/// +/// # Safety +/// +/// `proj` may only invoke `f` with a valid allocation, as the documentation of [`Self::proj`] +/// describes. +#[doc(hidden)] +pub unsafe trait ProjectField { + /// Project a pointer to a type to a pointer of a field. + /// + /// `f` may only be invoked with a valid allocation so it can safely obtain raw pointers to + /// fields using `&raw mut`. + /// + /// This is needed because `base` might not point to a valid allocation, while `&raw mut` + /// requires pointers to be in bounds of a valid allocation. + /// + /// # Safety + /// + /// `f` must return a pointer in bounds of the provided pointer. + unsafe fn proj(base: *mut Self, f: impl FnOnce(*mut Self) -> *mut F) -> *mut F; +} + +// NOTE: in theory, this API should work for `T: ?Sized` and `F: ?Sized`, too. However, we cannot +// currently support that as we need to obtain a valid allocation that `&raw const` can operate on. +// +// SAFETY: `proj` invokes `f` with valid allocation. +unsafe impl ProjectField for T { + #[inline(always)] + unsafe fn proj(base: *mut Self, f: impl FnOnce(*mut Self) -> *mut F) -> *mut F { + // Create a valid allocation to start projection, as `base` is not necessarily so. The + // memory is never actually used so it will be optimized out, so it should work even for + // very large `T` (`memoffset` crate also relies on this). To be extra certain, we also + // annotate `f` closure with `#[inline(always)]` in the macro. + let mut place = MaybeUninit::uninit(); + let place_base = place.as_mut_ptr(); + let field = f(place_base); + // SAFETY: `field` is in bounds from `base` per safety requirement. + let offset = unsafe { field.byte_offset_from(place_base) }; + // Use `wrapping_byte_offset` as `base` does not need to be of valid allocation. + base.wrapping_byte_offset(offset).cast() + } +} + +// SAFETY: Vacuously satisfied. +unsafe impl ProjectField for T { + #[inline(always)] + unsafe fn proj(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F { + build_error!("this function is a guard against `Deref` impl and is never invoked"); + } +} + +/// Create a projection from a raw pointer. +/// +/// The projected pointer is within the memory region marked by the input pointer. There is no +/// requirement that the input raw pointer needs to be valid, so this macro may be used for +/// projecting pointers outside normal address space, e.g. I/O pointers. However, if the input +/// pointer is valid, the projected pointer is also valid. +/// +/// Supported projections include field projections and index projections. +/// It is not allowed to project into types that implement custom [`Deref`] or +/// [`Index`](core::ops::Index). +/// +/// The macro has basic syntax of `kernel::ptr::project!(ptr, projection)`, where `ptr` is an +/// expression that evaluates to a raw pointer which serves as the base of projection. `projection` +/// can be a projection expression of form `.field` (normally identifier, or numeral in case of +/// tuple structs) or of form `[index]`. +/// +/// If a mutable pointer is needed, the macro input can be prefixed with the `mut` keyword, i.e. +/// `kernel::ptr::project!(mut ptr, projection)`. By default, a const pointer is created. +/// +/// `ptr::project!` macro can perform both fallible indexing and build-time checked indexing. +/// `[index]` form performs build-time bounds checking; if compiler fails to prove `[index]` is in +/// bounds, compilation will fail. `[index]?` can be used to perform runtime bounds checking; +/// `OutOfBound` error is raised via `?` if the index is out of bounds. +/// +/// # Examples +/// +/// Field projections are performed with `.field_name`: +/// +/// ``` +/// struct MyStruct { field: u32, } +/// let ptr: *const MyStruct = core::ptr::dangling(); +/// let field_ptr: *const u32 = kernel::ptr::project!(ptr, .field); +/// +/// struct MyTupleStruct(u32, u32); +/// +/// fn proj(ptr: *const MyTupleStruct) { +/// let field_ptr: *const u32 = kernel::ptr::project!(ptr, .1); +/// } +/// ``` +/// +/// Index projections are performed with `[index]`: +/// +/// ``` +/// fn proj(ptr: *const [u8; 32]) -> Result { +/// let field_ptr: *const u8 = kernel::ptr::project!(ptr, [1]); +/// // The following invocation, if uncommented, would fail the build. +/// // +/// // kernel::ptr::project!(ptr, [128]); +/// +/// // This will raise an `OutOfBound` error (which is convertible to `ERANGE`). +/// kernel::ptr::project!(ptr, [128]?); +/// Ok(()) +/// } +/// ``` +/// +/// If you need to match on the error instead of propagate, put the invocation inside a closure: +/// +/// ``` +/// let ptr: *const [u8; 32] = core::ptr::dangling(); +/// let field_ptr: Result<*const u8> = (|| -> Result<_> { +/// Ok(kernel::ptr::project!(ptr, [128]?)) +/// })(); +/// assert!(field_ptr.is_err()); +/// ``` +/// +/// For mutable pointers, put `mut` as the first token in macro invocation. +/// +/// ``` +/// let ptr: *mut [(u8, u16); 32] = core::ptr::dangling_mut(); +/// let field_ptr: *mut u16 = kernel::ptr::project!(mut ptr, [1].1); +/// ``` +#[macro_export] +macro_rules! project_pointer { + (@gen $ptr:ident, ) => {}; + // Field projection. `$field` needs to be `tt` to support tuple index like `.0`. + (@gen $ptr:ident, .$field:tt $($rest:tt)*) => { + // SAFETY: The provided closure always returns an in-bounds pointer. + let $ptr = unsafe { + $crate::ptr::projection::ProjectField::proj($ptr, #[inline(always)] |ptr| { + // Check unaligned field. Not all users (e.g. DMA) can handle unaligned + // projections. + if false { + let _ = &(*ptr).$field; + } + // SAFETY: `$field` is in bounds, and no implicit `Deref` is possible (if the + // type implements `Deref`, Rust cannot infer the generic parameter `DEREF`). + &raw mut (*ptr).$field + }) + }; + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + // Fallible index projection. + (@gen $ptr:ident, [$index:expr]? $($rest:tt)*) => { + let $ptr = $crate::ptr::projection::ProjectIndex::get($index, $ptr) + .ok_or($crate::ptr::projection::OutOfBound)?; + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + // Build-time checked index projection. + (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => { + let $ptr = $crate::ptr::projection::ProjectIndex::index($index, $ptr); + $crate::ptr::project!(@gen $ptr, $($rest)*) + }; + (mut $ptr:expr, $($proj:tt)*) => {{ + let ptr: *mut _ = $ptr; + $crate::ptr::project!(@gen ptr, $($proj)*); + ptr + }}; + ($ptr:expr, $($proj:tt)*) => {{ + let ptr = <*const _>::cast_mut($ptr); + // We currently always project using mutable pointer, as it is not decided whether `&raw + // const` allows the resulting pointer to be mutated (see documentation of `addr_of!`). + $crate::ptr::project!(@gen ptr, $($proj)*); + ptr.cast_const() + }}; +} diff --git a/rust/kernel/seq_file.rs b/rust/kernel/seq_file.rs index 855e533813a6..518265558d66 100644 --- a/rust/kernel/seq_file.rs +++ b/rust/kernel/seq_file.rs @@ -4,7 +4,7 @@ //! //! C header: [`include/linux/seq_file.h`](srctree/include/linux/seq_file.h) -use crate::{bindings, c_str, fmt, str::CStrExt as _, types::NotThreadSafe, types::Opaque}; +use crate::{bindings, fmt, str::CStrExt as _, types::NotThreadSafe, types::Opaque}; /// A utility for generating the contents of a seq file. #[repr(transparent)] @@ -36,7 +36,7 @@ pub fn call_printf(&self, args: fmt::Arguments<'_>) { unsafe { bindings::seq_printf( self.inner.get(), - c_str!("%pA").as_char_ptr(), + c"%pA".as_char_ptr(), core::ptr::from_ref(&args).cast::(), ); } diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs index fa87779d2253..3f8918764640 100644 --- a/rust/kernel/str.rs +++ b/rust/kernel/str.rs @@ -664,13 +664,13 @@ fn write_str(&mut self, s: &str) -> fmt::Result { /// /// * The first byte of `buffer` is always zero. /// * The length of `buffer` is at least 1. -pub(crate) struct NullTerminatedFormatter<'a> { +pub struct NullTerminatedFormatter<'a> { buffer: &'a mut [u8], } impl<'a> NullTerminatedFormatter<'a> { /// Create a new [`Self`] instance. - pub(crate) fn new(buffer: &'a mut [u8]) -> Option> { + pub fn new(buffer: &'a mut [u8]) -> Option> { *(buffer.first_mut()?) = 0; // INVARIANT: diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs index 289f77abf415..921e19333b89 100644 --- a/rust/kernel/sync/arc.rs +++ b/rust/kernel/sync/arc.rs @@ -240,6 +240,9 @@ pub fn new(contents: T, flags: Flags) -> Result { // `Arc` object. Ok(unsafe { Self::from_inner(inner) }) } + + /// The offset that the value is stored at. + pub const DATA_OFFSET: usize = core::mem::offset_of!(ArcInner, data); } impl Arc { diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index 67ce5c85c619..0e1b9a88f4f1 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -6,14 +6,23 @@ //! C header: [`include/linux/usb.h`](srctree/include/linux/usb.h) use crate::{ - bindings, device, - device_id::{RawDeviceId, RawDeviceIdIndex}, + bindings, + device, + device_id::{ + RawDeviceId, + RawDeviceIdIndex, // + }, driver, - error::{from_result, to_result, Result}, + error::{ + from_result, + to_result, // + }, prelude::*, - str::CStr, - types::{AlwaysRefCounted, Opaque}, - ThisModule, + types::{ + AlwaysRefCounted, + Opaque, // + }, + ThisModule, // }; use core::{ marker::PhantomData, diff --git a/rust/pin-init/internal/src/init.rs b/rust/pin-init/internal/src/init.rs index 42936f915a07..2fe918f4d82a 100644 --- a/rust/pin-init/internal/src/init.rs +++ b/rust/pin-init/internal/src/init.rs @@ -62,7 +62,6 @@ fn ident(&self) -> Option<&Ident> { enum InitializerAttribute { DefaultError(DefaultErrorAttribute), - DisableInitializedFieldAccess, } struct DefaultErrorAttribute { @@ -86,6 +85,7 @@ pub(crate) fn expand( let error = error.map_or_else( || { if let Some(default_error) = attrs.iter().fold(None, |acc, attr| { + #[expect(irrefutable_let_patterns)] if let InitializerAttribute::DefaultError(DefaultErrorAttribute { ty }) = attr { Some(ty.clone()) } else { @@ -145,22 +145,9 @@ fn assert_zeroable(_: *mut T) }; // `mixed_site` ensures that the data is not accessible to the user-controlled code. let data = Ident::new("__data", Span::mixed_site()); - let init_fields = init_fields( - &fields, - pinned, - !attrs - .iter() - .any(|attr| matches!(attr, InitializerAttribute::DisableInitializedFieldAccess)), - &data, - &slot, - ); + let init_fields = init_fields(&fields, pinned, &data, &slot); let field_check = make_field_check(&fields, init_kind, &path); Ok(quote! {{ - // We do not want to allow arbitrary returns, so we declare this type as the `Ok` return - // type and shadow it later when we insert the arbitrary user code. That way there will be - // no possibility of returning without `unsafe`. - struct __InitOk; - // Get the data about fields from the supplied type. // SAFETY: TODO let #data = unsafe { @@ -170,18 +157,15 @@ fn assert_zeroable(_: *mut T) #path::#get_data() }; // Ensure that `#data` really is of type `#data` and help with type inference: - let init = ::pin_init::__internal::#data_trait::make_closure::<_, __InitOk, #error>( + let init = ::pin_init::__internal::#data_trait::make_closure::<_, #error>( #data, move |slot| { - { - // Shadow the structure so it cannot be used to return early. - struct __InitOk; - #zeroable_check - #this - #init_fields - #field_check - } - Ok(__InitOk) + #zeroable_check + #this + #init_fields + #field_check + // SAFETY: we are the `init!` macro that is allowed to call this. + Ok(unsafe { ::pin_init::__internal::InitOk::new() }) } ); let init = move |slot| -> ::core::result::Result<(), #error> { @@ -236,7 +220,6 @@ fn get_init_kind(rest: Option<(Token![..], Expr)>, dcx: &mut DiagCtxt) -> InitKi fn init_fields( fields: &Punctuated, pinned: bool, - generate_initialized_accessors: bool, data: &Ident, slot: &Ident, ) -> TokenStream { @@ -260,6 +243,10 @@ fn init_fields( }); // Again span for better diagnostics let write = quote_spanned!(ident.span()=> ::core::ptr::write); + // NOTE: the field accessor ensures that the initialized field is properly aligned. + // Unaligned fields will cause the compiler to emit E0793. We do not support + // unaligned fields since `Init::__init` requires an aligned pointer; the call to + // `ptr::write` below has the same requirement. let accessor = if pinned { let project_ident = format_ident!("__project_{ident}"); quote! { @@ -272,13 +259,6 @@ fn init_fields( unsafe { &mut (*#slot).#ident } } }; - let accessor = generate_initialized_accessors.then(|| { - quote! { - #(#cfgs)* - #[allow(unused_variables)] - let #ident = #accessor; - } - }); quote! { #(#attrs)* { @@ -286,12 +266,18 @@ fn init_fields( // SAFETY: TODO unsafe { #write(::core::ptr::addr_of_mut!((*#slot).#ident), #value_ident) }; } - #accessor + #(#cfgs)* + #[allow(unused_variables)] + let #ident = #accessor; } } InitializerKind::Init { ident, value, .. } => { // Again span for better diagnostics let init = format_ident!("init", span = value.span()); + // NOTE: the field accessor ensures that the initialized field is properly aligned. + // Unaligned fields will cause the compiler to emit E0793. We do not support + // unaligned fields since `Init::__init` requires an aligned pointer; the call to + // `ptr::write` below has the same requirement. let (value_init, accessor) = if pinned { let project_ident = format_ident!("__project_{ident}"); ( @@ -326,20 +312,15 @@ fn init_fields( }, ) }; - let accessor = generate_initialized_accessors.then(|| { - quote! { - #(#cfgs)* - #[allow(unused_variables)] - let #ident = #accessor; - } - }); quote! { #(#attrs)* { let #init = #value; #value_init } - #accessor + #(#cfgs)* + #[allow(unused_variables)] + let #ident = #accessor; } } InitializerKind::Code { block: value, .. } => quote! { @@ -466,10 +447,6 @@ fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { if a.path().is_ident("default_error") { a.parse_args::() .map(InitializerAttribute::DefaultError) - } else if a.path().is_ident("disable_initialized_field_access") { - a.meta - .require_path_only() - .map(|_| InitializerAttribute::DisableInitializedFieldAccess) } else { Err(syn::Error::new_spanned(a, "unknown initializer attribute")) } diff --git a/rust/pin-init/src/__internal.rs b/rust/pin-init/src/__internal.rs index 90f18e9a2912..90adbdc1893b 100644 --- a/rust/pin-init/src/__internal.rs +++ b/rust/pin-init/src/__internal.rs @@ -46,6 +46,24 @@ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { } } +/// Token type to signify successful initialization. +/// +/// Can only be constructed via the unsafe [`Self::new`] function. The initializer macros use this +/// token type to prevent returning `Ok` from an initializer without initializing all fields. +pub struct InitOk(()); + +impl InitOk { + /// Creates a new token. + /// + /// # Safety + /// + /// This function may only be called from the `init!` macro in `../internal/src/init.rs`. + #[inline(always)] + pub unsafe fn new() -> Self { + Self(()) + } +} + /// This trait is only implemented via the `#[pin_data]` proc-macro. It is used to facilitate /// the pin projections within the initializers. /// @@ -68,9 +86,10 @@ pub unsafe trait PinData: Copy { type Datee: ?Sized + HasPinData; /// Type inference helper function. - fn make_closure(self, f: F) -> F + #[inline(always)] + fn make_closure(self, f: F) -> F where - F: FnOnce(*mut Self::Datee) -> Result, + F: FnOnce(*mut Self::Datee) -> Result, { f } @@ -98,9 +117,10 @@ pub unsafe trait InitData: Copy { type Datee: ?Sized + HasInitData; /// Type inference helper function. - fn make_closure(self, f: F) -> F + #[inline(always)] + fn make_closure(self, f: F) -> F where - F: FnOnce(*mut Self::Datee) -> Result, + F: FnOnce(*mut Self::Datee) -> Result, { f } diff --git a/rust/pin-init/src/lib.rs b/rust/pin-init/src/lib.rs index 49945fc07f25..fe4c85ae3f02 100644 --- a/rust/pin-init/src/lib.rs +++ b/rust/pin-init/src/lib.rs @@ -1143,13 +1143,13 @@ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { /// /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a /// pointer must result in a valid `U`. -#[expect(clippy::let_and_return)] pub const unsafe fn cast_pin_init(init: impl PinInit) -> impl PinInit { // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety // requirements. let res = unsafe { pin_init_from_closure(|ptr: *mut U| init.__pinned_init(ptr.cast::())) }; // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a // cycle when computing the type returned by this function) + #[allow(clippy::let_and_return)] res } @@ -1159,13 +1159,13 @@ unsafe fn __pinned_init(self, slot: *mut T) -> Result<(), E> { /// /// - `*mut U` must be castable to `*mut T` and any value of type `T` written through such a /// pointer must result in a valid `U`. -#[expect(clippy::let_and_return)] pub const unsafe fn cast_init(init: impl Init) -> impl Init { // SAFETY: initialization delegated to a valid initializer. Cast is valid by function safety // requirements. let res = unsafe { init_from_closure(|ptr: *mut U| init.__init(ptr.cast::())) }; // FIXME: remove the let statement once the nightly-MSRV allows it (1.78 otherwise encounters a // cycle when computing the type returned by this function) + #[allow(clippy::let_and_return)] res } diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs index 9c45851c876e..ce39b5545097 100644 --- a/samples/rust/rust_dma.rs +++ b/samples/rust/rust_dma.rs @@ -68,7 +68,7 @@ fn probe(pdev: &pci::Device, _info: &Self::IdInfo) -> impl PinInit, _info: &Self::IdInfo) -> impl PinInit Result { + for (i, value) in TEST_VALUES.into_iter().enumerate() { + let val0 = kernel::dma_read!(self.ca, [i]?.h); + let val1 = kernel::dma_read!(self.ca, [i]?.b); + + assert_eq!(val0, value.0); + assert_eq!(val1, value.1); + } + + Ok(()) + } +} + #[pinned_drop] impl PinnedDrop for DmaSampleDriver { fn drop(self: Pin<&mut Self>) { dev_info!(self.pdev, "Unload DMA test driver.\n"); - for (i, value) in TEST_VALUES.into_iter().enumerate() { - let val0 = kernel::dma_read!(self.ca[i].h); - let val1 = kernel::dma_read!(self.ca[i].b); - assert!(val0.is_ok()); - assert!(val1.is_ok()); - - if let Ok(val0) = val0 { - assert_eq!(val0, value.0); - } - if let Ok(val1) = val1 { - assert_eq!(val1, value.1); - } - } + assert!(self.check_dma().is_ok()); for (i, entry) in self.sgt.iter().enumerate() { dev_info!( diff --git a/samples/rust/rust_driver_usb.rs b/samples/rust/rust_driver_usb.rs index 4eaad14867b2..ab72e99e1274 100644 --- a/samples/rust/rust_driver_usb.rs +++ b/samples/rust/rust_driver_usb.rs @@ -3,7 +3,15 @@ //! Rust USB driver sample. -use kernel::{device, device::Core, prelude::*, sync::aref::ARef, usb}; +use kernel::{ + device::{ + self, + Core, // + }, + prelude::*, + sync::aref::ARef, + usb, // +}; struct SampleDriver { _intf: ARef, diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs index 3ef8da543abf..87a1fe63533a 100644 --- a/samples/rust/rust_misc_device.rs +++ b/samples/rust/rust_misc_device.rs @@ -96,7 +96,6 @@ //! ``` use kernel::{ - c_str, device::Device, fs::{File, Kiocb}, ioctl::{_IO, _IOC_SIZE, _IOR, _IOW}, @@ -131,7 +130,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit { pr_info!("Initialising Rust Misc Device Sample\n"); let options = MiscDeviceOptions { - name: c_str!("rust-misc-device"), + name: c"rust-misc-device", }; try_pin_init!(Self { diff --git a/samples/workqueue/stall_detector/Makefile b/samples/workqueue/stall_detector/Makefile new file mode 100644 index 000000000000..8849e85e95bb --- /dev/null +++ b/samples/workqueue/stall_detector/Makefile @@ -0,0 +1 @@ +obj-m += wq_stall.o diff --git a/samples/workqueue/stall_detector/wq_stall.c b/samples/workqueue/stall_detector/wq_stall.c new file mode 100644 index 000000000000..6f4a497b1881 --- /dev/null +++ b/samples/workqueue/stall_detector/wq_stall.c @@ -0,0 +1,98 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * wq_stall - Test module for the workqueue stall detector. + * + * Deliberately creates a workqueue stall so the watchdog fires and + * prints diagnostic output. Useful for verifying that the stall + * detector correctly identifies stuck workers and produces useful + * backtraces. + * + * The stall is triggered by clearing PF_WQ_WORKER before sleeping, + * which hides the worker from the concurrency manager. A second + * work item queued on the same pool then sits in the worklist with + * no worker available to process it. + * + * After ~30s the workqueue watchdog fires: + * BUG: workqueue lockup - pool cpus=N ... + * + * Build: + * make -C M=samples/workqueue/stall_detector modules + * + * Copyright (c) 2026 Meta Platforms, Inc. and affiliates. + * Copyright (c) 2026 Breno Leitao + */ + +#include +#include +#include +#include +#include + +static DECLARE_WAIT_QUEUE_HEAD(stall_wq_head); +static atomic_t wake_condition = ATOMIC_INIT(0); +static struct work_struct stall_work1; +static struct work_struct stall_work2; + +static void stall_work2_fn(struct work_struct *work) +{ + pr_info("wq_stall: second work item finally ran\n"); +} + +static void stall_work1_fn(struct work_struct *work) +{ + pr_info("wq_stall: first work item running on cpu %d\n", + raw_smp_processor_id()); + + /* + * Queue second item while we're still counted as running + * (pool->nr_running > 0). Since schedule_work() on a per-CPU + * workqueue targets raw_smp_processor_id(), item 2 lands on the + * same pool. __queue_work -> kick_pool -> need_more_worker() + * sees nr_running > 0 and does NOT wake a new worker. + */ + schedule_work(&stall_work2); + + /* + * Hide from the workqueue concurrency manager. Without + * PF_WQ_WORKER, schedule() won't call wq_worker_sleeping(), + * so nr_running is never decremented and no replacement + * worker is created. Item 2 stays stuck in pool->worklist. + */ + current->flags &= ~PF_WQ_WORKER; + + pr_info("wq_stall: entering wait_event_idle (PF_WQ_WORKER cleared)\n"); + pr_info("wq_stall: expect 'BUG: workqueue lockup' in ~30-60s\n"); + wait_event_idle(stall_wq_head, atomic_read(&wake_condition) != 0); + + /* Restore so process_one_work() cleanup works correctly */ + current->flags |= PF_WQ_WORKER; + pr_info("wq_stall: woke up, PF_WQ_WORKER restored\n"); +} + +static int __init wq_stall_init(void) +{ + pr_info("wq_stall: loading\n"); + + INIT_WORK(&stall_work1, stall_work1_fn); + INIT_WORK(&stall_work2, stall_work2_fn); + schedule_work(&stall_work1); + + return 0; +} + +static void __exit wq_stall_exit(void) +{ + pr_info("wq_stall: unloading\n"); + atomic_set(&wake_condition, 1); + wake_up(&stall_wq_head); + flush_work(&stall_work1); + flush_work(&stall_work2); + pr_info("wq_stall: all work flushed, module unloaded\n"); +} + +module_init(wq_stall_init); +module_exit(wq_stall_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Reproduce workqueue stall caused by PF_WQ_WORKER misuse"); +MODULE_AUTHOR("Breno Leitao "); diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 32e209bc7985..3652b85be545 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -310,16 +310,18 @@ $(obj)/%.lst: $(obj)/%.c FORCE # The features in this list are the ones allowed for non-`rust/` code. # +# - Stable since Rust 1.79.0: `feature(slice_ptr_len)`. # - Stable since Rust 1.81.0: `feature(lint_reasons)`. # - Stable since Rust 1.82.0: `feature(asm_const)`, # `feature(offset_of_nested)`, `feature(raw_ref_op)`. +# - Stable since Rust 1.84.0: `feature(strict_provenance)`. # - Stable since Rust 1.87.0: `feature(asm_goto)`. # - Expected to become stable: `feature(arbitrary_self_types)`. # - To be determined: `feature(used_with_arg)`. # # Please see https://github.com/Rust-for-Linux/linux/issues/2 for details on # the unstable features in use. -rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,used_with_arg +rust_allowed_features := asm_const,asm_goto,arbitrary_self_types,lint_reasons,offset_of_nested,raw_ref_op,slice_ptr_len,strict_provenance,used_with_arg # `--out-dir` is required to avoid temporaries being created by `rustc` in the # current working directory, which may be not accessible in the out-of-tree diff --git a/scripts/cc-can-link.sh b/scripts/cc-can-link.sh index e67fd8d7b684..58dc7dd6d556 100755 --- a/scripts/cc-can-link.sh +++ b/scripts/cc-can-link.sh @@ -5,7 +5,7 @@ cat << "END" | $@ -Werror -Wl,--fatal-warnings -x c - -o /dev/null >/dev/null 2> #include int main(void) { - printf(""); + printf("\n"); return 0; } END diff --git a/scripts/coccicheck b/scripts/coccicheck index 89d591af5f3e..8dd766009de1 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck @@ -138,7 +138,7 @@ run_cmd_parmap() { if [ $VERBOSE -ne 0 ] ; then echo "Running ($NPROC in parallel): $@" fi - if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then + if [ "$DEBUG_FILE" != "/dev/null" ]; then echo $@>>$DEBUG_FILE $@ 2>>$DEBUG_FILE else @@ -259,13 +259,18 @@ coccinelle () { } -if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then - if [ -f $DEBUG_FILE ]; then - echo "Debug file $DEBUG_FILE exists, bailing" - exit - fi -else - DEBUG_FILE="/dev/null" +if [ "$DEBUG_FILE" = "" ]; then + echo 'You have not explicitly specified the debug file to use.' + echo 'Using default "/dev/null" as debug file.' + echo 'Debug logs will be printed to stdout.' + echo 'You can specify the debug file with "make coccicheck DEBUG_FILE="' + echo '' + DEBUG_FILE="/dev/null" +fi + +if [ -f $DEBUG_FILE ]; then + echo "Debug file $DEBUG_FILE exists, bailing" + exit fi if [ "$COCCI" = "" ] ; then diff --git a/scripts/gdb/linux/constants.py.in b/scripts/gdb/linux/constants.py.in index 6d475540c6ba..dab8b80bed69 100644 --- a/scripts/gdb/linux/constants.py.in +++ b/scripts/gdb/linux/constants.py.in @@ -150,8 +150,8 @@ LX_CONFIG(CONFIG_ARM64_64K_PAGES) if IS_BUILTIN(CONFIG_ARM64): LX_VALUE(CONFIG_ARM64_PA_BITS) LX_VALUE(CONFIG_ARM64_VA_BITS) - LX_VALUE(CONFIG_PAGE_SHIFT) LX_VALUE(CONFIG_ARCH_FORCE_MAX_ORDER) +LX_VALUE(CONFIG_PAGE_SHIFT) LX_CONFIG(CONFIG_SPARSEMEM) LX_CONFIG(CONFIG_SPARSEMEM_EXTREME) LX_CONFIG(CONFIG_SPARSEMEM_VMEMMAP) diff --git a/scripts/gdb/linux/mm.py b/scripts/gdb/linux/mm.py index 7571aebbe650..d78908f6664d 100644 --- a/scripts/gdb/linux/mm.py +++ b/scripts/gdb/linux/mm.py @@ -26,8 +26,179 @@ class page_ops(): raise gdb.GdbError('Only support CONFIG_SPARSEMEM_VMEMMAP now') if constants.LX_CONFIG_ARM64 and utils.is_target_arch('aarch64'): self.ops = aarch64_page_ops() + elif utils.is_target_arch('x86_64') or utils.is_target_arch('x86-64'): + self.ops = x86_page_ops() else: - raise gdb.GdbError('Only support aarch64 now') + raise gdb.GdbError('Only support aarch64 and x86_64 now') + +class x86_page_ops(): + def __init__(self): + self.struct_page_size = utils.get_page_type().sizeof + self.PAGE_SHIFT = constants.LX_CONFIG_PAGE_SHIFT + self.PAGE_SIZE = 1 << self.PAGE_SHIFT + self.PAGE_MASK = (~(self.PAGE_SIZE - 1)) & ((1 << 64) - 1) + + self.PAGE_OFFSET = int(gdb.parse_and_eval("page_offset_base")) + self.VMEMMAP_START = int(gdb.parse_and_eval("vmemmap_base")) + self.PHYS_BASE = int(gdb.parse_and_eval("phys_base")) + self.START_KERNEL_map = 0xffffffff80000000 + + self.KERNEL_START = gdb.parse_and_eval("_text") + self.KERNEL_END = gdb.parse_and_eval("_end") + + self.VMALLOC_START = int(gdb.parse_and_eval("vmalloc_base")) + if self.VMALLOC_START == 0xffffc90000000000: + self.VMALLOC_END = self.VMALLOC_START + (32 * 1024 * 1024 * 1024 * 1024) - 1 + elif self.VMALLOC_START == 0xffa0000000000000: + self.VMALLOC_END = self.VMALLOC_START + (12800 * 1024 * 1024 * 1024 * 1024) - 1 + else: + self.VMALLOC_END = self.VMALLOC_START + (12800 * 1024 * 1024 * 1024 * 1024) - 1 + + self.MAX_PHYSMEM_BITS = 46 + self.SECTION_SIZE_BITS = 27 + self.MAX_ORDER = 10 + + self.SECTIONS_SHIFT = self.MAX_PHYSMEM_BITS - self.SECTION_SIZE_BITS + self.NR_MEM_SECTIONS = 1 << self.SECTIONS_SHIFT + self.PFN_SECTION_SHIFT = self.SECTION_SIZE_BITS - self.PAGE_SHIFT + self.PAGES_PER_SECTION = 1 << self.PFN_SECTION_SHIFT + self.PAGE_SECTION_MASK = (~(self.PAGES_PER_SECTION - 1)) & ((1 << 64) - 1) + + if constants.LX_CONFIG_SPARSEMEM_EXTREME: + self.SECTIONS_PER_ROOT = self.PAGE_SIZE // gdb.lookup_type("struct mem_section").sizeof + else: + self.SECTIONS_PER_ROOT = 1 + + self.NR_SECTION_ROOTS = DIV_ROUND_UP(self.NR_MEM_SECTIONS, self.SECTIONS_PER_ROOT) + self.SECTION_ROOT_MASK = self.SECTIONS_PER_ROOT - 1 + + try: + self.SECTION_HAS_MEM_MAP = 1 << int(gdb.parse_and_eval('SECTION_HAS_MEM_MAP_BIT')) + self.SECTION_IS_EARLY = 1 << int(gdb.parse_and_eval('SECTION_IS_EARLY_BIT')) + except: + self.SECTION_HAS_MEM_MAP = 1 << 0 + self.SECTION_IS_EARLY = 1 << 3 + + self.SUBSECTION_SHIFT = 21 + self.PAGES_PER_SUBSECTION = 1 << (self.SUBSECTION_SHIFT - self.PAGE_SHIFT) + + if constants.LX_CONFIG_NUMA and constants.LX_CONFIG_NODES_SHIFT: + self.NODE_SHIFT = constants.LX_CONFIG_NODES_SHIFT + else: + self.NODE_SHIFT = 0 + + self.MAX_NUMNODES = 1 << self.NODE_SHIFT + + self.vmemmap = gdb.Value(self.VMEMMAP_START).cast(utils.get_page_type().pointer()) + + def kasan_reset_tag(self, addr): + return addr + + def SECTION_NR_TO_ROOT(self, sec): + return sec // self.SECTIONS_PER_ROOT + + def __nr_to_section(self, nr): + root = self.SECTION_NR_TO_ROOT(nr) + mem_section = gdb.parse_and_eval("mem_section") + return mem_section[root][nr & self.SECTION_ROOT_MASK] + + def pfn_to_section_nr(self, pfn): + return pfn >> self.PFN_SECTION_SHIFT + + def section_nr_to_pfn(self, sec): + return sec << self.PFN_SECTION_SHIFT + + def __pfn_to_section(self, pfn): + return self.__nr_to_section(self.pfn_to_section_nr(pfn)) + + def pfn_to_section(self, pfn): + return self.__pfn_to_section(pfn) + + def subsection_map_index(self, pfn): + return (pfn & ~(self.PAGE_SECTION_MASK)) // self.PAGES_PER_SUBSECTION + + def pfn_section_valid(self, ms, pfn): + if constants.LX_CONFIG_SPARSEMEM_VMEMMAP: + idx = self.subsection_map_index(pfn) + return test_bit(idx, ms['usage']['subsection_map']) + else: + return True + + def valid_section(self, mem_section): + if mem_section != None and (mem_section['section_mem_map'] & self.SECTION_HAS_MEM_MAP): + return True + return False + + def early_section(self, mem_section): + if mem_section != None and (mem_section['section_mem_map'] & self.SECTION_IS_EARLY): + return True + return False + + def pfn_valid(self, pfn): + ms = None + if self.PHYS_PFN(self.PFN_PHYS(pfn)) != pfn: + return False + if self.pfn_to_section_nr(pfn) >= self.NR_MEM_SECTIONS: + return False + ms = self.__pfn_to_section(pfn) + + if not self.valid_section(ms): + return False + return self.early_section(ms) or self.pfn_section_valid(ms, pfn) + + def PFN_PHYS(self, pfn): + return pfn << self.PAGE_SHIFT + + def PHYS_PFN(self, phys): + return phys >> self.PAGE_SHIFT + + def __phys_to_virt(self, pa): + return pa + self.PAGE_OFFSET + + def __virt_to_phys(self, va): + if va >= self.START_KERNEL_map: + return va - self.START_KERNEL_map + self.PHYS_BASE + else: + return va - self.PAGE_OFFSET + + def virt_to_phys(self, va): + return self.__virt_to_phys(va) + + def virt_to_page(self, va): + return self.pfn_to_page(self.virt_to_pfn(va)) + + def __pa(self, va): + return self.__virt_to_phys(va) + + def __va(self, pa): + return self.__phys_to_virt(pa) + + def pfn_to_kaddr(self, pfn): + return self.__va(pfn << self.PAGE_SHIFT) + + def virt_to_pfn(self, va): + return self.PHYS_PFN(self.__virt_to_phys(va)) + + def sym_to_pfn(self, x): + return self.PHYS_PFN(self.__virt_to_phys(x)) + + def page_to_pfn(self, page): + return int(page.cast(utils.get_page_type().pointer()) - self.vmemmap) + + def pfn_to_page(self, pfn): + return self.vmemmap + pfn + + def page_to_phys(self, page): + return self.PFN_PHYS(self.page_to_pfn(page)) + + def page_to_virt(self, page): + return self.__va(self.page_to_phys(page)) + + def page_address(self, page): + return self.page_to_virt(page) + + def folio_address(self, folio): + return self.page_address(folio['page'].address) class aarch64_page_ops(): def __init__(self): diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index efdcf07c4eb6..cabcd146f3aa 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -325,8 +325,8 @@ direct_declarator: { $$ = $4; } | direct_declarator BRACKET_PHRASE { $$ = $2; } - | '(' declarator ')' - { $$ = $3; } + | '(' attribute_opt declarator ')' + { $$ = $4; } ; /* Nested declarators differ from regular declarators in that they do diff --git a/scripts/livepatch/init.c b/scripts/livepatch/init.c index 638c95cffe76..f14d8c8fb35f 100644 --- a/scripts/livepatch/init.c +++ b/scripts/livepatch/init.c @@ -28,7 +28,7 @@ static int __init livepatch_mod_init(void) goto err; } - patch = kzalloc(sizeof(*patch), GFP_KERNEL); + patch = kzalloc_obj(*patch); if (!patch) { ret = -ENOMEM; goto err; diff --git a/scripts/make_fit.py b/scripts/make_fit.py index e923cc8b05b7..15ba26974fd7 100755 --- a/scripts/make_fit.py +++ b/scripts/make_fit.py @@ -54,7 +54,7 @@ COMP_TOOLS = { 'bzip2': CompTool('.bz2', 'pbzip2,bzip2'), 'gzip': CompTool('.gz', 'pigz,gzip'), 'lz4': CompTool('.lz4', 'lz4'), - 'lzma': CompTool('.lzma', 'plzip,lzma'), + 'lzma': CompTool('.lzma', 'lzma'), 'lzo': CompTool('.lzo', 'lzop'), 'xz': CompTool('.xz', 'xz'), 'zstd': CompTool('.zstd', 'zstd'), diff --git a/scripts/package/install-extmod-build b/scripts/package/install-extmod-build index 2576cf7902db..f12e1ffe409e 100755 --- a/scripts/package/install-extmod-build +++ b/scripts/package/install-extmod-build @@ -32,6 +32,10 @@ mkdir -p "${destdir}" echo tools/objtool/objtool fi + if is_enabled CONFIG_DEBUG_INFO_BTF_MODULES; then + echo tools/bpf/resolve_btfids/resolve_btfids + fi + echo Module.symvers echo "arch/${SRCARCH}/include/generated" echo include/config/auto.conf diff --git a/scripts/package/kernel.spec b/scripts/package/kernel.spec index 0f1c8de1bd95..b3c956205af0 100644 --- a/scripts/package/kernel.spec +++ b/scripts/package/kernel.spec @@ -2,8 +2,6 @@ %{!?_arch: %define _arch dummy} %{!?make: %define make make} %define makeflags %{?_smp_mflags} ARCH=%{ARCH} -%define __spec_install_post /usr/lib/rpm/brp-compress || : -%define debug_package %{nil} Name: kernel Summary: The Linux Kernel @@ -47,14 +45,50 @@ This package provides kernel headers and makefiles sufficient to build modules against the %{version} kernel package. %endif -%if %{with_debuginfo} +%if %{with_debuginfo_manual} %package debuginfo Summary: Debug information package for the Linux kernel +Group: Development/Debug +AutoReq: 0 +AutoProv: 1 %description debuginfo This package provides debug information for the kernel image and modules from the %{version} package. +%define install_mod_strip 1 %endif +%if %{with_debuginfo_rpm} +# list of debuginfo-related options taken from distribution kernel.spec +# files +%undefine _include_minidebuginfo +%undefine _find_debuginfo_dwz_opts +%undefine _unique_build_ids +%undefine _unique_debug_names +%undefine _unique_debug_srcs +%undefine _debugsource_packages +%undefine _debuginfo_subpackages +%global _find_debuginfo_opts -r +%global _missing_build_ids_terminate_build 1 +%global _no_recompute_build_ids 1 +%{debug_package} + +# later, we make all modules executable so that find-debuginfo.sh strips +# them up. but they don't actually need to be executable, so remove the +# executable bit, taking care to do it _after_ find-debuginfo.sh has run +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \\\ + | xargs --no-run-if-empty chmod u-x +%else +%define __spec_install_post /usr/lib/rpm/brp-compress || : +%endif +# some (but not all) versions of rpmbuild emit %%debug_package with +# %%install. since we've already emitted it manually, that would cause +# a package redefinition error. ensure that doesn't happen +%define debug_package %{nil} + %prep %setup -q -n linux cp %{SOURCE1} .config @@ -67,7 +101,7 @@ patch -p1 < %{SOURCE2} mkdir -p %{buildroot}/lib/modules/%{KERNELRELEASE} cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEASE}/vmlinuz # DEPMOD=true makes depmod no-op. We do not package depmod-generated files. -%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} INSTALL_MOD_STRIP=1 DEPMOD=true modules_install +%{make} %{makeflags} INSTALL_MOD_PATH=%{buildroot} %{?install_mod_strip:INSTALL_MOD_STRIP=1} DEPMOD=true modules_install %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE} cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config @@ -98,22 +132,30 @@ ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEA echo "%exclude /lib/modules/%{KERNELRELEASE}/build" } > %{buildroot}/kernel.list -%if %{with_debuginfo} +%if 0%{with_debuginfo_manual}%{with_debuginfo_rpm} > 0 # copying vmlinux directly to the debug directory means it will not get # stripped (but its source paths will still be collected + fixed up) mkdir -p %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE} cp vmlinux %{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE} +%endif +%if %{with_debuginfo_rpm} +# make modules executable so that find-debuginfo.sh strips them. this +# will be undone later in %%__spec_install_post +find %{buildroot}/lib/modules/%{KERNELRELEASE} -name "*.ko" -type f \ + | xargs --no-run-if-empty chmod u+x +%endif + +%if %{with_debuginfo_manual} echo /usr/lib/debug/lib/modules/%{KERNELRELEASE}/vmlinux > %{buildroot}/debuginfo.list - while read -r mod; do mod="${mod%.o}.ko" dbg="%{buildroot}/usr/lib/debug/lib/modules/%{KERNELRELEASE}/kernel/${mod}" - buildid=$("${READELF}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') + buildid=$("${READELF:-readelf}" -n "${mod}" | sed -n 's@^.*Build ID: \(..\)\(.*\)@\1/\2@p') link="%{buildroot}/usr/lib/debug/.build-id/${buildid}.debug" mkdir -p "${dbg%/*}" "${link%/*}" - "${OBJCOPY}" --only-keep-debug "${mod}" "${dbg}" + "${OBJCOPY:-objcopy}" --only-keep-debug "${mod}" "${dbg}" ln -sf --relative "${dbg}" "${link}" echo "${dbg#%{buildroot}}" >> %{buildroot}/debuginfo.list @@ -123,6 +165,10 @@ done < modules.order %clean rm -rf %{buildroot} +%if %{with_debuginfo_rpm} +rm -f debugfiles.list debuglinks.list debugsourcefiles.list debugsources.list \ + elfbins.list +%endif %post if [ -x /usr/bin/kernel-install ]; then @@ -162,7 +208,7 @@ fi /lib/modules/%{KERNELRELEASE}/build %endif -%if %{with_debuginfo} +%if %{with_debuginfo_manual} %files -f %{buildroot}/debuginfo.list debuginfo %defattr (-, root, root) %exclude /debuginfo.list diff --git a/scripts/package/mkspec b/scripts/package/mkspec index c7375bfc25a9..c604f8c174e2 100755 --- a/scripts/package/mkspec +++ b/scripts/package/mkspec @@ -23,15 +23,47 @@ else echo '%define with_devel 0' fi +# use %{debug_package} machinery to generate -debuginfo +with_debuginfo_rpm=0 +# manually generate -debuginfo package +with_debuginfo_manual=0 # debuginfo package generation uses find-debuginfo.sh under the hood, # which only works on uncompressed modules that contain debuginfo if grep -q CONFIG_DEBUG_INFO=y include/config/auto.conf && (! grep -q CONFIG_MODULE_COMPRESS=y include/config/auto.conf) && (! grep -q CONFIG_DEBUG_INFO_SPLIT=y include/config/auto.conf); then -echo '%define with_debuginfo %{?_without_debuginfo: 0} %{?!_without_debuginfo: 1}' -else -echo '%define with_debuginfo 0' + # If module signing is enabled (which may be required to boot with + # lockdown enabled), the find-debuginfo.sh machinery cannot be used + # because the signatures will be stripped off the modules. However, due + # to an rpm bug in versions prior to 4.20.0 + # + # https://github.com/rpm-software-management/rpm/issues/3057 + # https://github.com/rpm-software-management/rpm/commit/49f906998f3cf1f4152162ca61ac0869251c380f + # + # We cannot provide our own debuginfo package because it does not listen + # to our custom files list, failing the build due to unpackaged files. + # Manually generate the debug info package if using rpm 4.20.0. If not + # using rpm 4.20.0, avoid generating a -debuginfo package altogether, + # as it is not safe. + if grep -q CONFIG_MODULE_SIG=y include/config/auto.conf; then + rpm_ver_str=$(rpm --version 2>/dev/null) + # Split the version on spaces + IFS=' ' + set -- $rpm_ver_str + if [ "${1:-}" = RPM -a "${2:-}" = version ]; then + IFS=. + set -- $3 + rpm_ver=$(( 1000000 * $1 + 10000 * $2 + 100 * $3 + ${4:-0} )) + if [ "$rpm_ver" -ge 4200000 ]; then + with_debuginfo_manual='%{?_without_debuginfo:0}%{?!_without_debuginfo:1}' + fi + fi + else + with_debuginfo_rpm='%{?_without_debuginfo:0}%{?!_without_debuginfo:1}' + fi fi +echo "%define with_debuginfo_manual $with_debuginfo_manual" +echo "%define with_debuginfo_rpm $with_debuginfo_rpm" cat<info); - return fn_for_each_in_ns(peer_label, peerp, + return fn_for_each_in_scope(peer_label, peerp, match_label(profile, rules, state, request, peerp, p, ad)); } diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index 907bd2667e28..242c71b3fb6e 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -32,6 +32,7 @@ #include "include/crypto.h" #include "include/ipc.h" #include "include/label.h" +#include "include/lib.h" #include "include/policy.h" #include "include/policy_ns.h" #include "include/resource.h" @@ -62,6 +63,7 @@ * securityfs and apparmorfs filesystems. */ +#define IREF_POISON 101 /* * support fns @@ -79,7 +81,7 @@ static void rawdata_f_data_free(struct rawdata_f_data *private) if (!private) return; - aa_put_loaddata(private->loaddata); + aa_put_i_loaddata(private->loaddata); kvfree(private); } @@ -153,6 +155,71 @@ static int aafs_show_path(struct seq_file *seq, struct dentry *dentry) return 0; } +static struct aa_ns *get_ns_common_ref(struct aa_common_ref *ref) +{ + if (ref) { + struct aa_label *reflabel = container_of(ref, struct aa_label, + count); + return aa_get_ns(labels_ns(reflabel)); + } + + return NULL; +} + +static struct aa_proxy *get_proxy_common_ref(struct aa_common_ref *ref) +{ + if (ref) + return aa_get_proxy(container_of(ref, struct aa_proxy, count)); + + return NULL; +} + +static struct aa_loaddata *get_loaddata_common_ref(struct aa_common_ref *ref) +{ + if (ref) + return aa_get_i_loaddata(container_of(ref, struct aa_loaddata, + count)); + return NULL; +} + +static void aa_put_common_ref(struct aa_common_ref *ref) +{ + if (!ref) + return; + + switch (ref->reftype) { + case REF_RAWDATA: + aa_put_i_loaddata(container_of(ref, struct aa_loaddata, + count)); + break; + case REF_PROXY: + aa_put_proxy(container_of(ref, struct aa_proxy, + count)); + break; + case REF_NS: + /* ns count is held on its unconfined label */ + aa_put_ns(labels_ns(container_of(ref, struct aa_label, count))); + break; + default: + AA_BUG(true, "unknown refcount type"); + break; + } +} + +static void aa_get_common_ref(struct aa_common_ref *ref) +{ + kref_get(&ref->count); +} + +static void aafs_evict(struct inode *inode) +{ + struct aa_common_ref *ref = inode->i_private; + + clear_inode(inode); + aa_put_common_ref(ref); + inode->i_private = (void *) IREF_POISON; +} + static void aafs_free_inode(struct inode *inode) { if (S_ISLNK(inode->i_mode)) @@ -162,6 +229,7 @@ static void aafs_free_inode(struct inode *inode) static const struct super_operations aafs_super_ops = { .statfs = simple_statfs, + .evict_inode = aafs_evict, .free_inode = aafs_free_inode, .show_path = aafs_show_path, }; @@ -262,7 +330,8 @@ static int __aafs_setup_d_inode(struct inode *dir, struct dentry *dentry, * aafs_remove(). Will return ERR_PTR on failure. */ static struct dentry *aafs_create(const char *name, umode_t mode, - struct dentry *parent, void *data, void *link, + struct dentry *parent, + struct aa_common_ref *data, void *link, const struct file_operations *fops, const struct inode_operations *iops) { @@ -299,6 +368,9 @@ static struct dentry *aafs_create(const char *name, umode_t mode, goto fail_dentry; inode_unlock(dir); + if (data) + aa_get_common_ref(data); + return dentry; fail_dentry: @@ -323,7 +395,8 @@ static struct dentry *aafs_create(const char *name, umode_t mode, * see aafs_create */ static struct dentry *aafs_create_file(const char *name, umode_t mode, - struct dentry *parent, void *data, + struct dentry *parent, + struct aa_common_ref *data, const struct file_operations *fops) { return aafs_create(name, mode, parent, data, NULL, fops, NULL); @@ -409,7 +482,8 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf, data->size = copy_size; if (copy_from_user(data->data, userbuf, copy_size)) { - aa_put_loaddata(data); + /* trigger free - don't need to put pcount */ + aa_put_i_loaddata(data); return ERR_PTR(-EFAULT); } @@ -417,7 +491,8 @@ static struct aa_loaddata *aa_simple_write_to_buffer(const char __user *userbuf, } static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, - loff_t *pos, struct aa_ns *ns) + loff_t *pos, struct aa_ns *ns, + const struct cred *ocred) { struct aa_loaddata *data; struct aa_label *label; @@ -428,7 +503,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, /* high level check about policy management - fine grained in * below after unpack */ - error = aa_may_manage_policy(current_cred(), label, ns, mask); + error = aa_may_manage_policy(current_cred(), label, ns, ocred, mask); if (error) goto end_section; @@ -436,7 +511,10 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, error = PTR_ERR(data); if (!IS_ERR(data)) { error = aa_replace_profiles(ns, label, mask, data); - aa_put_loaddata(data); + /* put pcount, which will put count and free if no + * profiles referencing it. + */ + aa_put_profile_loaddata(data); } end_section: end_current_label_crit_section(label); @@ -448,8 +526,9 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, static ssize_t profile_load(struct file *f, const char __user *buf, size_t size, loff_t *pos) { - struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); - int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns); + struct aa_ns *ns = get_ns_common_ref(f->f_inode->i_private); + int error = policy_update(AA_MAY_LOAD_POLICY, buf, size, pos, ns, + f->f_cred); aa_put_ns(ns); @@ -465,9 +544,9 @@ static const struct file_operations aa_fs_profile_load = { static ssize_t profile_replace(struct file *f, const char __user *buf, size_t size, loff_t *pos) { - struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); + struct aa_ns *ns = get_ns_common_ref(f->f_inode->i_private); int error = policy_update(AA_MAY_LOAD_POLICY | AA_MAY_REPLACE_POLICY, - buf, size, pos, ns); + buf, size, pos, ns, f->f_cred); aa_put_ns(ns); return error; @@ -485,14 +564,14 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, struct aa_loaddata *data; struct aa_label *label; ssize_t error; - struct aa_ns *ns = aa_get_ns(f->f_inode->i_private); + struct aa_ns *ns = get_ns_common_ref(f->f_inode->i_private); label = begin_current_label_crit_section(); /* high level check about policy management - fine grained in * below after unpack */ error = aa_may_manage_policy(current_cred(), label, ns, - AA_MAY_REMOVE_POLICY); + f->f_cred, AA_MAY_REMOVE_POLICY); if (error) goto out; @@ -506,7 +585,7 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, if (!IS_ERR(data)) { data->data[size] = 0; error = aa_remove_profiles(ns, label, data->data, size); - aa_put_loaddata(data); + aa_put_profile_loaddata(data); } out: end_current_label_crit_section(label); @@ -570,12 +649,12 @@ static ssize_t ns_revision_read(struct file *file, char __user *buf, static int ns_revision_open(struct inode *inode, struct file *file) { - struct aa_revision *rev = kzalloc(sizeof(*rev), GFP_KERNEL); + struct aa_revision *rev = kzalloc_obj(*rev); if (!rev) return -ENOMEM; - rev->ns = aa_get_ns(inode->i_private); + rev->ns = get_ns_common_ref(inode->i_private); if (!rev->ns) rev->ns = aa_get_current_ns(); file->private_data = rev; @@ -801,7 +880,7 @@ static ssize_t query_label(char *buf, size_t buf_len, perms = allperms; if (view_only) { - label_for_each_in_ns(i, labels_ns(label), label, profile) { + label_for_each_in_scope(i, labels_ns(label), label, profile) { profile_query_cb(profile, &perms, match_str, match_len); } } else { @@ -1061,7 +1140,7 @@ static const struct file_operations seq_profile_ ##NAME ##_fops = { \ static int seq_profile_open(struct inode *inode, struct file *file, int (*show)(struct seq_file *, void *)) { - struct aa_proxy *proxy = aa_get_proxy(inode->i_private); + struct aa_proxy *proxy = get_proxy_common_ref(inode->i_private); int error = single_open(file, show, proxy); if (error) { @@ -1253,18 +1332,17 @@ static const struct file_operations seq_rawdata_ ##NAME ##_fops = { \ static int seq_rawdata_open(struct inode *inode, struct file *file, int (*show)(struct seq_file *, void *)) { - struct aa_loaddata *data = __aa_get_loaddata(inode->i_private); + struct aa_loaddata *data = get_loaddata_common_ref(inode->i_private); int error; if (!data) - /* lost race this ent is being reaped */ return -ENOENT; error = single_open(file, show, data); if (error) { AA_BUG(file->private_data && ((struct seq_file *)file->private_data)->private); - aa_put_loaddata(data); + aa_put_i_loaddata(data); } return error; @@ -1275,7 +1353,7 @@ static int seq_rawdata_release(struct inode *inode, struct file *file) struct seq_file *seq = (struct seq_file *) file->private_data; if (seq) - aa_put_loaddata(seq->private); + aa_put_i_loaddata(seq->private); return single_release(inode, file); } @@ -1387,9 +1465,8 @@ static int rawdata_open(struct inode *inode, struct file *file) if (!aa_current_policy_view_capable(NULL)) return -EACCES; - loaddata = __aa_get_loaddata(inode->i_private); + loaddata = get_loaddata_common_ref(inode->i_private); if (!loaddata) - /* lost race: this entry is being reaped */ return -ENOENT; private = rawdata_f_data_alloc(loaddata->size); @@ -1414,7 +1491,7 @@ static int rawdata_open(struct inode *inode, struct file *file) return error; fail_private_alloc: - aa_put_loaddata(loaddata); + aa_put_i_loaddata(loaddata); return error; } @@ -1431,7 +1508,6 @@ static void remove_rawdata_dents(struct aa_loaddata *rawdata) for (i = 0; i < AAFS_LOADDATA_NDENTS; i++) { if (!IS_ERR_OR_NULL(rawdata->dents[i])) { - /* no refcounts on i_private */ aafs_remove(rawdata->dents[i]); rawdata->dents[i] = NULL; } @@ -1474,35 +1550,37 @@ int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata) return PTR_ERR(dir); rawdata->dents[AAFS_LOADDATA_DIR] = dir; - dent = aafs_create_file("abi", S_IFREG | 0444, dir, rawdata, + dent = aafs_create_file("abi", S_IFREG | 0444, dir, &rawdata->count, &seq_rawdata_abi_fops); if (IS_ERR(dent)) goto fail; rawdata->dents[AAFS_LOADDATA_ABI] = dent; - dent = aafs_create_file("revision", S_IFREG | 0444, dir, rawdata, - &seq_rawdata_revision_fops); + dent = aafs_create_file("revision", S_IFREG | 0444, dir, + &rawdata->count, + &seq_rawdata_revision_fops); if (IS_ERR(dent)) goto fail; rawdata->dents[AAFS_LOADDATA_REVISION] = dent; if (aa_g_hash_policy) { dent = aafs_create_file("sha256", S_IFREG | 0444, dir, - rawdata, &seq_rawdata_hash_fops); + &rawdata->count, + &seq_rawdata_hash_fops); if (IS_ERR(dent)) goto fail; rawdata->dents[AAFS_LOADDATA_HASH] = dent; } dent = aafs_create_file("compressed_size", S_IFREG | 0444, dir, - rawdata, + &rawdata->count, &seq_rawdata_compressed_size_fops); if (IS_ERR(dent)) goto fail; rawdata->dents[AAFS_LOADDATA_COMPRESSED_SIZE] = dent; - dent = aafs_create_file("raw_data", S_IFREG | 0444, - dir, rawdata, &rawdata_fops); + dent = aafs_create_file("raw_data", S_IFREG | 0444, dir, + &rawdata->count, &rawdata_fops); if (IS_ERR(dent)) goto fail; rawdata->dents[AAFS_LOADDATA_DATA] = dent; @@ -1510,13 +1588,11 @@ int __aa_fs_create_rawdata(struct aa_ns *ns, struct aa_loaddata *rawdata) rawdata->ns = aa_get_ns(ns); list_add(&rawdata->list, &ns->rawdata_list); - /* no refcount on inode rawdata */ return 0; fail: remove_rawdata_dents(rawdata); - return PTR_ERR(dent); } #endif /* CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */ @@ -1540,13 +1616,10 @@ void __aafs_profile_rmdir(struct aa_profile *profile) __aafs_profile_rmdir(child); for (i = AAFS_PROF_SIZEOF - 1; i >= 0; --i) { - struct aa_proxy *proxy; if (!profile->dents[i]) continue; - proxy = d_inode(profile->dents[i])->i_private; aafs_remove(profile->dents[i]); - aa_put_proxy(proxy); profile->dents[i] = NULL; } } @@ -1580,14 +1653,7 @@ static struct dentry *create_profile_file(struct dentry *dir, const char *name, struct aa_profile *profile, const struct file_operations *fops) { - struct aa_proxy *proxy = aa_get_proxy(profile->label.proxy); - struct dentry *dent; - - dent = aafs_create_file(name, S_IFREG | 0444, dir, proxy, fops); - if (IS_ERR(dent)) - aa_put_proxy(proxy); - - return dent; + return aafs_create_file(name, S_IFREG | 0444, dir, &profile->label.proxy->count, fops); } #ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY @@ -1607,16 +1673,20 @@ static char *gen_symlink_name(int depth, const char *dirname, const char *fname) { char *buffer, *s; int error; - int size = depth * 6 + strlen(dirname) + strlen(fname) + 11; + const char *path = "../../"; + size_t path_len = strlen(path); + int size; + /* Extra 11 bytes: "raw_data" (9) + two slashes "//" (2) */ + size = depth * path_len + strlen(dirname) + strlen(fname) + 11; s = buffer = kmalloc(size, GFP_KERNEL); if (!buffer) return ERR_PTR(-ENOMEM); for (; depth > 0; depth--) { - strcpy(s, "../../"); - s += 6; - size -= 6; + memcpy(s, path, path_len); + s += path_len; + size -= path_len; } error = snprintf(s, size, "raw_data/%s/%s", dirname, fname); @@ -1633,7 +1703,8 @@ static const char *rawdata_get_link_base(struct dentry *dentry, struct delayed_call *done, const char *name) { - struct aa_proxy *proxy = inode->i_private; + struct aa_common_ref *ref = inode->i_private; + struct aa_proxy *proxy = container_of(ref, struct aa_proxy, count); struct aa_label *label; struct aa_profile *profile; char *target; @@ -1644,6 +1715,15 @@ static const char *rawdata_get_link_base(struct dentry *dentry, label = aa_get_label_rcu(&proxy->label); profile = labels_profile(label); + + /* rawdata can be null when aa_g_export_binary is unset during + * runtime and a profile is replaced + */ + if (!profile->rawdata) { + aa_put_label(label); + return ERR_PTR(-ENOENT); + } + depth = profile_depth(profile); target = gen_symlink_name(depth, profile->rawdata->name, name); aa_put_label(label); @@ -1766,27 +1846,24 @@ int __aafs_profile_mkdir(struct aa_profile *profile, struct dentry *parent) if (profile->rawdata) { if (aa_g_hash_policy) { dent = aafs_create("raw_sha256", S_IFLNK | 0444, dir, - profile->label.proxy, NULL, NULL, - &rawdata_link_sha256_iops); + &profile->label.proxy->count, NULL, + NULL, &rawdata_link_sha256_iops); if (IS_ERR(dent)) goto fail; - aa_get_proxy(profile->label.proxy); profile->dents[AAFS_PROF_RAW_HASH] = dent; } dent = aafs_create("raw_abi", S_IFLNK | 0444, dir, - profile->label.proxy, NULL, NULL, + &profile->label.proxy->count, NULL, NULL, &rawdata_link_abi_iops); if (IS_ERR(dent)) goto fail; - aa_get_proxy(profile->label.proxy); profile->dents[AAFS_PROF_RAW_ABI] = dent; dent = aafs_create("raw_data", S_IFLNK | 0444, dir, - profile->label.proxy, NULL, NULL, + &profile->label.proxy->count, NULL, NULL, &rawdata_link_data_iops); if (IS_ERR(dent)) goto fail; - aa_get_proxy(profile->label.proxy); profile->dents[AAFS_PROF_RAW_DATA] = dent; } #endif /*CONFIG_SECURITY_APPARMOR_EXPORT_BINARY */ @@ -1817,13 +1894,13 @@ static struct dentry *ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir, int error; label = begin_current_label_crit_section(); - error = aa_may_manage_policy(current_cred(), label, NULL, + error = aa_may_manage_policy(current_cred(), label, NULL, NULL, AA_MAY_LOAD_POLICY); end_current_label_crit_section(label); if (error) return ERR_PTR(error); - parent = aa_get_ns(dir->i_private); + parent = get_ns_common_ref(dir->i_private); AA_BUG(d_inode(ns_subns_dir(parent)) != dir); /* we have to unlock and then relock to get locking order right @@ -1867,13 +1944,13 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry) int error; label = begin_current_label_crit_section(); - error = aa_may_manage_policy(current_cred(), label, NULL, + error = aa_may_manage_policy(current_cred(), label, NULL, NULL, AA_MAY_LOAD_POLICY); end_current_label_crit_section(label); if (error) return error; - parent = aa_get_ns(dir->i_private); + parent = get_ns_common_ref(dir->i_private); /* rmdir calls the generic securityfs functions to remove files * from the apparmor dir. It is up to the apparmor ns locking * to avoid races. @@ -1943,27 +2020,6 @@ void __aafs_ns_rmdir(struct aa_ns *ns) __aa_fs_list_remove_rawdata(ns); - if (ns_subns_dir(ns)) { - sub = d_inode(ns_subns_dir(ns))->i_private; - aa_put_ns(sub); - } - if (ns_subload(ns)) { - sub = d_inode(ns_subload(ns))->i_private; - aa_put_ns(sub); - } - if (ns_subreplace(ns)) { - sub = d_inode(ns_subreplace(ns))->i_private; - aa_put_ns(sub); - } - if (ns_subremove(ns)) { - sub = d_inode(ns_subremove(ns))->i_private; - aa_put_ns(sub); - } - if (ns_subrevision(ns)) { - sub = d_inode(ns_subrevision(ns))->i_private; - aa_put_ns(sub); - } - for (i = AAFS_NS_SIZEOF - 1; i >= 0; --i) { aafs_remove(ns->dents[i]); ns->dents[i] = NULL; @@ -1988,40 +2044,40 @@ static int __aafs_ns_mkdir_entries(struct aa_ns *ns, struct dentry *dir) return PTR_ERR(dent); ns_subdata_dir(ns) = dent; - dent = aafs_create_file("revision", 0444, dir, ns, + dent = aafs_create_file("revision", 0444, dir, + &ns->unconfined->label.count, &aa_fs_ns_revision_fops); if (IS_ERR(dent)) return PTR_ERR(dent); - aa_get_ns(ns); ns_subrevision(ns) = dent; - dent = aafs_create_file(".load", 0640, dir, ns, - &aa_fs_profile_load); + dent = aafs_create_file(".load", 0640, dir, + &ns->unconfined->label.count, + &aa_fs_profile_load); if (IS_ERR(dent)) return PTR_ERR(dent); - aa_get_ns(ns); ns_subload(ns) = dent; - dent = aafs_create_file(".replace", 0640, dir, ns, - &aa_fs_profile_replace); + dent = aafs_create_file(".replace", 0640, dir, + &ns->unconfined->label.count, + &aa_fs_profile_replace); if (IS_ERR(dent)) return PTR_ERR(dent); - aa_get_ns(ns); ns_subreplace(ns) = dent; - dent = aafs_create_file(".remove", 0640, dir, ns, - &aa_fs_profile_remove); + dent = aafs_create_file(".remove", 0640, dir, + &ns->unconfined->label.count, + &aa_fs_profile_remove); if (IS_ERR(dent)) return PTR_ERR(dent); - aa_get_ns(ns); ns_subremove(ns) = dent; /* use create_dentry so we can supply private data */ - dent = aafs_create("namespaces", S_IFDIR | 0755, dir, ns, NULL, NULL, - &ns_dir_inode_operations); + dent = aafs_create("namespaces", S_IFDIR | 0755, dir, + &ns->unconfined->label.count, + NULL, NULL, &ns_dir_inode_operations); if (IS_ERR(dent)) return PTR_ERR(dent); - aa_get_ns(ns); ns_subns_dir(ns) = dent; return 0; diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c index ac89602aa2d9..4a60b6fda75f 100644 --- a/security/apparmor/audit.c +++ b/security/apparmor/audit.c @@ -230,7 +230,7 @@ int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp return -EINVAL; } - rule = kzalloc(sizeof(struct aa_audit_rule), gfp); + rule = kzalloc_obj(struct aa_audit_rule, gfp); if (!rule) return -ENOMEM; diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 267da82afb14..f02bf770f638 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -115,7 +115,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, * @label: label to check access permissions for * @stack: whether this is a stacking request * @state: state to start match in - * @subns: whether to do permission checks on components in a subns + * @inview: whether to match labels in view or only in scope * @request: permissions to request * @perms: perms struct to set * @@ -127,7 +127,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, */ static int label_compound_match(struct aa_profile *profile, struct aa_label *label, bool stack, - aa_state_t state, bool subns, u32 request, + aa_state_t state, bool inview, u32 request, struct aa_perms *perms) { struct aa_ruleset *rules = profile->label.rules[0]; @@ -135,9 +135,9 @@ static int label_compound_match(struct aa_profile *profile, struct label_it i; struct path_cond cond = { }; - /* find first subcomponent that is visible */ + /* find first subcomponent that is in view and going to be interated with */ label_for_each(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, tp, stack, state); if (!state) @@ -151,7 +151,7 @@ static int label_compound_match(struct aa_profile *profile, next: label_for_each_cont(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = aa_dfa_match(rules->file->dfa, state, "//&"); state = match_component(profile, tp, false, state); @@ -177,7 +177,7 @@ static int label_compound_match(struct aa_profile *profile, * @label: label to check access permissions for * @stack: whether this is a stacking request * @start: state to start match in - * @subns: whether to do permission checks on components in a subns + * @inview: whether to match labels in view or only in scope * @request: permissions to request * @perms: an initialized perms struct to add accumulation to * @@ -189,7 +189,7 @@ static int label_compound_match(struct aa_profile *profile, */ static int label_components_match(struct aa_profile *profile, struct aa_label *label, bool stack, - aa_state_t start, bool subns, u32 request, + aa_state_t start, bool inview, u32 request, struct aa_perms *perms) { struct aa_ruleset *rules = profile->label.rules[0]; @@ -201,7 +201,7 @@ static int label_components_match(struct aa_profile *profile, /* find first subcomponent to test */ label_for_each(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, tp, stack, start); if (!state) @@ -218,7 +218,7 @@ static int label_components_match(struct aa_profile *profile, aa_apply_modes_to_perms(profile, &tmp); aa_perms_accum(perms, &tmp); label_for_each_cont(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, tp, stack, start); if (!state) @@ -245,26 +245,26 @@ static int label_components_match(struct aa_profile *profile, * @label: label to match (NOT NULL) * @stack: whether this is a stacking request * @state: state to start in - * @subns: whether to match subns components + * @inview: whether to match labels in view or only in scope * @request: permission request * @perms: Returns computed perms (NOT NULL) * * Returns: the state the match finished in, may be the none matching state */ static int label_match(struct aa_profile *profile, struct aa_label *label, - bool stack, aa_state_t state, bool subns, u32 request, + bool stack, aa_state_t state, bool inview, u32 request, struct aa_perms *perms) { int error; *perms = nullperms; - error = label_compound_match(profile, label, stack, state, subns, + error = label_compound_match(profile, label, stack, state, inview, request, perms); if (!error) return error; *perms = allperms; - return label_components_match(profile, label, stack, state, subns, + return label_components_match(profile, label, stack, state, inview, request, perms); } @@ -529,7 +529,7 @@ struct aa_label *x_table_lookup(struct aa_profile *profile, u32 xindex, /* TODO: move lookup parsing to unpack time so this is a straight * index into the resultant label */ - for (next = rules->file->trans.table[index]; next; + for (next = rules->file->trans.table[index].strs; next; next = next_name(xtype, next)) { const char *lookup = (*next == '&') ? next + 1 : next; *name = next; @@ -880,14 +880,16 @@ static struct aa_label *handle_onexec(const struct cred *subj_cred, AA_BUG(!bprm); AA_BUG(!buffer); - /* TODO: determine how much we want to loosen this */ - error = fn_for_each_in_ns(label, profile, + /* TODO: determine how much we want to loosen this + * only check profiles in scope for permission to change at exec + */ + error = fn_for_each_in_scope(label, profile, profile_onexec(subj_cred, profile, onexec, stack, bprm, buffer, cond, unsafe)); if (error) return ERR_PTR(error); - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, stack ? aa_label_merge(&profile->label, onexec, GFP_KERNEL) : aa_get_newest_label(onexec), @@ -897,7 +899,7 @@ static struct aa_label *handle_onexec(const struct cred *subj_cred, return new; /* TODO: get rid of GLOBAL_ROOT_UID */ - error = fn_for_each_in_ns(label, profile, + error = fn_for_each_in_scope(label, profile, aa_audit_file(subj_cred, profile, &nullperms, OP_CHANGE_ONEXEC, AA_MAY_ONEXEC, bprm->filename, NULL, @@ -1123,7 +1125,7 @@ static struct aa_label *change_hat(const struct cred *subj_cred, /*find first matching hat */ for (i = 0; i < count && !hat; i++) { name = hats[i]; - label_for_each_in_ns(it, labels_ns(label), label, profile) { + label_for_each_in_scope(it, labels_ns(label), label, profile) { if (sibling && PROFILE_IS_HAT(profile)) { root = aa_get_profile_rcu(&profile->parent); } else if (!sibling && !PROFILE_IS_HAT(profile)) { @@ -1159,7 +1161,7 @@ static struct aa_label *change_hat(const struct cred *subj_cred, * change_hat. */ name = NULL; - label_for_each_in_ns(it, labels_ns(label), label, profile) { + label_for_each_in_scope(it, labels_ns(label), label, profile) { if (!list_empty(&profile->base.profiles)) { info = "hat not found"; error = -ENOENT; @@ -1170,7 +1172,7 @@ static struct aa_label *change_hat(const struct cred *subj_cred, error = -ECHILD; fail: - label_for_each_in_ns(it, labels_ns(label), label, profile) { + label_for_each_in_scope(it, labels_ns(label), label, profile) { /* * no target as it has failed to be found or built * @@ -1188,7 +1190,7 @@ static struct aa_label *change_hat(const struct cred *subj_cred, return ERR_PTR(error); build: - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, build_change_hat(subj_cred, profile, name, sibling), aa_get_label(&profile->label)); @@ -1251,7 +1253,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) bool empty = true; rcu_read_lock(); - label_for_each_in_ns(i, labels_ns(label), label, profile) { + label_for_each_in_scope(i, labels_ns(label), label, profile) { empty &= list_empty(&profile->base.profiles); } rcu_read_unlock(); @@ -1338,7 +1340,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) perms.kill = AA_MAY_CHANGEHAT; fail: - fn_for_each_in_ns(label, profile, + fn_for_each_in_scope(label, profile, aa_audit_file(subj_cred, profile, &perms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL, NULL, target, GLOBAL_ROOT_UID, info, error)); @@ -1446,7 +1448,7 @@ int aa_change_profile(const char *fqname, int flags) */ stack = true; perms.audit = request; - (void) fn_for_each_in_ns(label, profile, + (void) fn_for_each_in_scope(label, profile, aa_audit_file(subj_cred, profile, &perms, op, request, auditname, NULL, target, GLOBAL_ROOT_UID, stack_msg, 0)); @@ -1492,7 +1494,7 @@ int aa_change_profile(const char *fqname, int flags) * * if (!stack) { */ - error = fn_for_each_in_ns(label, profile, + error = fn_for_each_in_scope(label, profile, change_profile_perms_wrapper(op, auditname, subj_cred, profile, target, stack, @@ -1506,7 +1508,7 @@ int aa_change_profile(const char *fqname, int flags) check: /* check if tracing task is allowed to trace target domain */ error = may_change_ptraced_domain(subj_cred, target, &info); - if (error && !fn_for_each_in_ns(label, profile, + if (error && !fn_for_each_in_scope(label, profile, COMPLAIN_MODE(profile))) goto audit; @@ -1522,7 +1524,7 @@ int aa_change_profile(const char *fqname, int flags) /* stacking is always a subset, so only check the nonstack case */ if (!stack) { - new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + new = fn_label_build_in_scope(label, profile, GFP_KERNEL, aa_get_label(target), aa_get_label(&profile->label)); /* @@ -1565,7 +1567,7 @@ int aa_change_profile(const char *fqname, int flags) } audit: - error = fn_for_each_in_ns(label, profile, + error = fn_for_each_in_scope(label, profile, aa_audit_file(subj_cred, profile, &perms, op, request, auditname, NULL, new ? new : target, diff --git a/security/apparmor/file.c b/security/apparmor/file.c index c75820402878..694e157149e8 100644 --- a/security/apparmor/file.c +++ b/security/apparmor/file.c @@ -103,6 +103,7 @@ int aa_audit_file(const struct cred *subj_cred, ad.subj_cred = subj_cred; ad.request = request; + ad.tags = perms->tag; ad.name = name; ad.fs.target = target; ad.peer = tlabel; @@ -154,8 +155,12 @@ static int path_name(const char *op, const struct cred *subj_cred, const char *info = NULL; int error; - error = aa_path_name(path, flags, buffer, name, &info, - labels_profile(label)->disconnected); + /* don't reaudit files closed during inheritance */ + if (unlikely(path->dentry == aa_null.dentry)) + error = -EACCES; + else + error = aa_path_name(path, flags, buffer, name, &info, + labels_profile(label)->disconnected); if (error) { fn_for_each_confined(label, profile, aa_audit_file(subj_cred, @@ -567,8 +572,7 @@ static bool __file_is_delegated(struct aa_label *obj_label) return unconfined(obj_label); } -static bool __unix_needs_revalidation(struct file *file, struct aa_label *label, - u32 request) +static bool __is_unix_file(struct file *file) { struct socket *sock = (struct socket *) file->private_data; @@ -576,20 +580,31 @@ static bool __unix_needs_revalidation(struct file *file, struct aa_label *label, if (!S_ISSOCK(file_inode(file)->i_mode)) return false; - if (request & NET_PEER_MASK) + /* sock and sock->sk can be NULL for sockets being set up or torn down */ + if (!sock || !sock->sk) return false; - if (sock->sk->sk_family == PF_UNIX) { - struct aa_sk_ctx *ctx = aa_sock(sock->sk); - - if (rcu_access_pointer(ctx->peer) != - rcu_access_pointer(ctx->peer_lastupdate)) - return true; - return !__aa_subj_label_is_cached(rcu_dereference(ctx->label), - label); - } + if (sock->sk->sk_family == PF_UNIX) + return true; return false; } +static bool __unix_needs_revalidation(struct file *file, struct aa_label *label, + u32 request) +{ + struct socket *sock = (struct socket *) file->private_data; + + AA_BUG(!__is_unix_file(file)); + lockdep_assert_in_rcu_read_lock(); + + struct aa_sk_ctx *skctx = aa_sock(sock->sk); + + if (rcu_access_pointer(skctx->peer) != + rcu_access_pointer(skctx->peer_lastupdate)) + return true; + + return !__aa_subj_label_is_cached(rcu_dereference(skctx->label), label); +} + /** * aa_file_perm - do permission revalidation check & audit for @file * @op: operation being checked @@ -613,6 +628,10 @@ int aa_file_perm(const char *op, const struct cred *subj_cred, AA_BUG(!label); AA_BUG(!file); + /* don't reaudit files closed during inheritance */ + if (unlikely(file->f_path.dentry == aa_null.dentry)) + return -EACCES; + fctx = file_ctx(file); rcu_read_lock(); @@ -628,7 +647,7 @@ int aa_file_perm(const char *op, const struct cred *subj_cred, */ denied = request & ~fctx->allow; if (unconfined(label) || __file_is_delegated(flabel) || - __unix_needs_revalidation(file, label, request) || + (!denied && __is_unix_file(file) && !__unix_needs_revalidation(file, label, request)) || (!denied && __aa_subj_label_is_cached(label, flabel))) { rcu_read_unlock(); goto done; diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h index 1a71a94ea19c..aa00b34404f9 100644 --- a/security/apparmor/include/audit.h +++ b/security/apparmor/include/audit.h @@ -119,6 +119,8 @@ struct apparmor_audit_data { const char *info; u32 request; u32 denied; + u32 tags; + union { /* these entries require a custom callback fn */ struct { diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h index b028e4c13b6f..2b6098149b15 100644 --- a/security/apparmor/include/cred.h +++ b/security/apparmor/include/cred.h @@ -36,22 +36,6 @@ static inline void set_cred_label(const struct cred *cred, *blob = label; } -/** - * aa_cred_raw_label - obtain cred's label - * @cred: cred to obtain label from (NOT NULL) - * - * Returns: confining label - * - * does NOT increment reference count - */ -static inline struct aa_label *aa_cred_raw_label(const struct cred *cred) -{ - struct aa_label *label = cred_label(cred); - - AA_BUG(!label); - return label; -} - /** * aa_get_newest_cred_label - obtain the newest label on a cred * @cred: cred to obtain label from (NOT NULL) @@ -60,13 +44,13 @@ static inline struct aa_label *aa_cred_raw_label(const struct cred *cred) */ static inline struct aa_label *aa_get_newest_cred_label(const struct cred *cred) { - return aa_get_newest_label(aa_cred_raw_label(cred)); + return aa_get_newest_label(cred_label(cred)); } static inline struct aa_label *aa_get_newest_cred_label_condref(const struct cred *cred, bool *needput) { - struct aa_label *l = aa_cred_raw_label(cred); + struct aa_label *l = cred_label(cred); if (unlikely(label_is_stale(l))) { *needput = true; @@ -93,7 +77,7 @@ static inline void aa_put_label_condref(struct aa_label *l, bool needput) */ static inline struct aa_label *aa_current_raw_label(void) { - return aa_cred_raw_label(current_cred()); + return cred_label(current_cred()); } /** @@ -115,19 +99,81 @@ static inline struct aa_label *aa_get_current_label(void) } /** - * __end_current_label_crit_section - end crit section begun with __begin_... - * @label: label obtained from __begin_current_label_crit_section - * @needput: output: bool set by __begin_current_label_crit_section + * __end_cred_crit_section - end crit section begun with __begin_... + * @label: label obtained from __begin_cred_crit_section + * @needput: output: bool set by __begin_cred_crit_section * - * Returns: label to use for this crit section + * While the cred passed to __begin is guaranteed to not change + * and the cred and label could be passed here instead of needput + * using needput with a local var makes it easier for the compiler + * and processor to optimize and speculatively execute the comparison + * than chasing a pointer in the cred struct. */ -static inline void __end_current_label_crit_section(struct aa_label *label, +static inline void __end_cred_crit_section(struct aa_label *label, bool needput) { if (unlikely(needput)) aa_put_label(label); } +/** + * __begin_cred_crit_section - @cred's confining label + * @cred: current's cred to start a crit section on its label + * @needput: store whether the label needs to be put when ending crit section + * + * Returns: up to date confining label or the ns unconfined label (NOT NULL) + * + * safe to call inside locks + * + * The returned reference must be put with __end_cred_crit_section() + * This must NOT be used if the task cred could be updated within the + * critical section between + * __begin_cred_crit_section() .. __end_cred_crit_section() + * + * The crit section is an optimization to avoid having to get and put + * the newest version of the label. While the cred won't change and + * hence the label it contains won't change, the newest version of the + * label can. During the crit section the newest versions of the label + * will be used until the end of the crit section. + * + * If the label has not been updated at the start of the crit section + * no refcount is taken, the cred's refcount is enough to hold the + * label for the duration of the crit section. + * + * If the label has been updated then a refcount will be taken and the + * newest version of the label will be returned. While the cred label + * and the returned label could be compared at the end of the crit + * section, needput is used because it allows better optimization by + * the compiler and the processor's speculative execution. + */ +static inline struct aa_label *__begin_cred_crit_section(const struct cred *cred, + bool *needput) +{ + struct aa_label *label = cred_label(cred); + + if (label_is_stale(label)) { + *needput = true; + return aa_get_newest_label(label); + } + + *needput = false; + return label; +} + +/** + * __end_current_label_crit_section - end crit section begun with __begin_... + * @label: label obtained from __begin_current_label_crit_section + * @needput: output: bool set by __begin_current_label_crit_section + * + * wrapper around __end_cred_crit_section() to pair nicely with + * __begin_current_label_crit_section() + */ +static inline void __end_current_label_crit_section(struct aa_label *label, + bool needput) +{ + __end_cred_crit_section(label, needput); +} + /** * end_current_label_crit_section - put a reference found with begin_current_label.. * @label: label reference to put @@ -157,15 +203,7 @@ static inline void end_current_label_crit_section(struct aa_label *label) */ static inline struct aa_label *__begin_current_label_crit_section(bool *needput) { - struct aa_label *label = aa_current_raw_label(); - - if (label_is_stale(label)) { - *needput = true; - return aa_get_newest_label(label); - } - - *needput = false; - return label; + return __begin_cred_crit_section(current_cred(), needput); } /** diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index c0812dbc1b5b..335f21930702 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -102,7 +102,7 @@ enum label_flags { struct aa_label; struct aa_proxy { - struct kref count; + struct aa_common_ref count; struct aa_label __rcu *label; }; @@ -125,7 +125,7 @@ struct label_it { * vec: vector of profiles comprising the compound label */ struct aa_label { - struct kref count; + struct aa_common_ref count; struct rb_node node; struct rcu_head rcu; struct aa_proxy *proxy; @@ -357,7 +357,7 @@ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, */ static inline struct aa_label *__aa_get_label(struct aa_label *l) { - if (l && kref_get_unless_zero(&l->count)) + if (l && kref_get_unless_zero(&l->count.count)) return l; return NULL; @@ -366,7 +366,7 @@ static inline struct aa_label *__aa_get_label(struct aa_label *l) static inline struct aa_label *aa_get_label(struct aa_label *l) { if (l) - kref_get(&(l->count)); + kref_get(&(l->count.count)); return l; } @@ -386,7 +386,7 @@ static inline struct aa_label *aa_get_label_rcu(struct aa_label __rcu **l) rcu_read_lock(); do { c = rcu_dereference(*l); - } while (c && !kref_get_unless_zero(&c->count)); + } while (c && !kref_get_unless_zero(&c->count.count)); rcu_read_unlock(); return c; @@ -426,7 +426,7 @@ static inline struct aa_label *aa_get_newest_label(struct aa_label *l) static inline void aa_put_label(struct aa_label *l) { if (l) - kref_put(&l->count, aa_label_kref); + kref_put(&l->count.count, aa_label_kref); } /* wrapper fn to indicate semantics of the check */ @@ -443,7 +443,7 @@ void aa_proxy_kref(struct kref *kref); static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy) { if (proxy) - kref_get(&(proxy->count)); + kref_get(&(proxy->count.count)); return proxy; } @@ -451,7 +451,7 @@ static inline struct aa_proxy *aa_get_proxy(struct aa_proxy *proxy) static inline void aa_put_proxy(struct aa_proxy *proxy) { if (proxy) - kref_put(&proxy->count, aa_proxy_kref); + kref_put(&proxy->count.count, aa_proxy_kref); } void __aa_proxy_redirect(struct aa_label *orig, struct aa_label *new); diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h index 444197075fd6..8c6ce8484552 100644 --- a/security/apparmor/include/lib.h +++ b/security/apparmor/include/lib.h @@ -30,8 +30,10 @@ extern struct aa_dfa *stacksplitdfa; #define DEBUG_DOMAIN 4 #define DEBUG_POLICY 8 #define DEBUG_INTERFACE 0x10 +#define DEBUG_UNPACK 0x20 +#define DEBUG_TAGS 0x40 -#define DEBUG_ALL 0x1f /* update if new DEBUG_X added */ +#define DEBUG_ALL 0x7f /* update if new DEBUG_X added */ #define DEBUG_PARSE_ERROR (-1) #define DEBUG_ON (aa_g_debug != DEBUG_NONE) @@ -45,9 +47,11 @@ extern struct aa_dfa *stacksplitdfa; #define AA_DEBUG_LABEL(LAB, X, fmt, args...) \ do { \ if ((LAB)->flags & FLAG_DEBUG1) \ - AA_DEBUG(X, fmt, args); \ + AA_DEBUG(X, fmt, ##args); \ } while (0) +#define AA_DEBUG_PROFILE(PROF, X, fmt...) AA_DEBUG_LABEL(&(PROF)->label, X, ##fmt) + #define AA_WARN(X) WARN((X), "APPARMOR WARN %s: %s\n", __func__, #X) #define AA_BUG(X, args...) \ @@ -76,6 +80,19 @@ int aa_print_debug_params(char *buffer); /* Flag indicating whether initialization completed */ extern int apparmor_initialized; +/* semantic split of scope and view */ +#define aa_in_scope(SUBJ, OBJ) \ + aa_ns_visible(SUBJ, OBJ, false) + +#define aa_in_view(SUBJ, OBJ) \ + aa_ns_visible(SUBJ, OBJ, true) + +#define label_for_each_in_scope(I, NS, L, P) \ + label_for_each_in_ns(I, NS, L, P) + +#define fn_for_each_in_scope(L, P, FN) \ + fn_for_each_in_ns(L, P, FN) + /* fn's in lib */ const char *skipn_spaces(const char *str, size_t n); const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, @@ -85,6 +102,18 @@ void aa_info_message(const char *str); /* Security blob offsets */ extern struct lsm_blob_sizes apparmor_blob_sizes; +enum reftype { + REF_NS, + REF_PROXY, + REF_RAWDATA, +}; + +/* common reference count used by data the shows up in aafs */ +struct aa_common_ref { + struct kref count; + enum reftype reftype; +}; + /** * aa_strneq - compare null terminated @str to a non null terminated substring * @str: a null terminated string @@ -119,13 +148,19 @@ static inline bool path_mediated_fs(struct dentry *dentry) return !(dentry->d_sb->s_flags & SB_NOUSER); } -struct aa_str_table { +struct aa_str_table_ent { + int count; int size; - char **table; + char *strs; +}; + +struct aa_str_table { + int size; + struct aa_str_table_ent *table; }; -void aa_free_str_table(struct aa_str_table *table); bool aa_resize_str_table(struct aa_str_table *t, int newsize, gfp_t gfp); +void aa_destroy_str_table(struct aa_str_table *table); struct counted_str { struct kref count; @@ -306,7 +341,7 @@ __done: \ }) -#define __fn_build_in_ns(NS, P, NS_FN, OTHER_FN) \ +#define __fn_build_in_scope(NS, P, NS_FN, OTHER_FN) \ ({ \ struct aa_label *__new; \ if ((P)->ns != (NS)) \ @@ -316,10 +351,10 @@ __done: \ (__new); \ }) -#define fn_label_build_in_ns(L, P, GFP, NS_FN, OTHER_FN) \ +#define fn_label_build_in_scope(L, P, GFP, NS_FN, OTHER_FN) \ ({ \ fn_label_build((L), (P), (GFP), \ - __fn_build_in_ns(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \ + __fn_build_in_scope(labels_ns(L), (P), (NS_FN), (OTHER_FN))); \ }) #endif /* __AA_LIB_H */ diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h index 1fbe82f5021b..7accb1c39849 100644 --- a/security/apparmor/include/match.h +++ b/security/apparmor/include/match.h @@ -104,16 +104,18 @@ struct aa_dfa { struct table_header *tables[YYTD_ID_TSIZE]; }; -#define byte_to_byte(X) (X) - #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ do { \ typeof(LEN) __i; \ TTYPE *__t = (TTYPE *) TABLE; \ BTYPE *__b = (BTYPE *) BLOB; \ - for (__i = 0; __i < LEN; __i++) { \ - __t[__i] = NTOHX(__b[__i]); \ - } \ + BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \ + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \ + memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \ + else /* copy & convert from big-endian */ \ + for (__i = 0; __i < LEN; __i++) { \ + __t[__i] = NTOHX(&__b[__i]); \ + } \ } while (0) static inline size_t table_size(size_t len, size_t el_size) @@ -183,6 +185,7 @@ static inline void aa_put_dfa(struct aa_dfa *dfa) #define MATCH_FLAG_DIFF_ENCODE 0x80000000 #define MARK_DIFF_ENCODE 0x40000000 #define MATCH_FLAG_OOB_TRANSITION 0x20000000 +#define MARK_DIFF_ENCODE_VERIFIED 0x10000000 #define MATCH_FLAGS_MASK 0xff000000 #define MATCH_FLAGS_VALID (MATCH_FLAG_DIFF_ENCODE | MATCH_FLAG_OOB_TRANSITION) #define MATCH_FLAGS_INVALID (MATCH_FLAGS_MASK & ~MATCH_FLAGS_VALID) diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 4c50875c9d13..3895f8774a3f 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -79,11 +79,33 @@ enum profile_mode { }; +struct aa_tags_header { + u32 mask; /* bit mask matching permissions */ + u32 count; /* number of strings per entry */ + u32 size; /* size of all strings covered by count */ + u32 tags; /* index into string table */ +}; + +struct aa_tags_struct { + struct { + u32 size; /* number of entries in tagsets */ + u32 *table; /* indexes into headers & strs */ + } sets; + struct { + u32 size; /* number of headers == num of strs */ + struct aa_tags_header *table; + } hdrs; + struct aa_str_table strs; +}; + /* struct aa_policydb - match engine for a policy - * count: refcount for the pdb - * dfa: dfa pattern match - * perms: table of permissions - * strs: table of strings, index by x + * @count: refcount for the pdb + * @dfa: dfa pattern match + * @perms: table of permissions + * @size: number of entries in @perms + * @trans: table of strings, index by x + * @tags: table of tags that perms->tag indexes + * @start:_states to start in for each class * start: set of start states for the different classes of data */ struct aa_policydb { @@ -94,11 +116,13 @@ struct aa_policydb { u32 size; }; struct aa_str_table trans; + struct aa_tags_struct tags; aa_state_t start[AA_CLASS_LAST + 1]; }; extern struct aa_policydb *nullpdb; +void aa_destroy_tags(struct aa_tags_struct *tags); struct aa_policydb *aa_alloc_pdb(gfp_t gfp); void aa_pdb_free_kref(struct kref *kref); @@ -355,7 +379,7 @@ static inline bool profile_mediates_safe(struct aa_profile *profile, static inline struct aa_profile *aa_get_profile(struct aa_profile *p) { if (p) - kref_get(&(p->label.count)); + kref_get(&(p->label.count.count)); return p; } @@ -369,7 +393,7 @@ static inline struct aa_profile *aa_get_profile(struct aa_profile *p) */ static inline struct aa_profile *aa_get_profile_not0(struct aa_profile *p) { - if (p && kref_get_unless_zero(&p->label.count)) + if (p && kref_get_unless_zero(&p->label.count.count)) return p; return NULL; @@ -389,7 +413,7 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p) rcu_read_lock(); do { c = rcu_dereference(*p); - } while (c && !kref_get_unless_zero(&c->label.count)); + } while (c && !kref_get_unless_zero(&c->label.count.count)); rcu_read_unlock(); return c; @@ -402,7 +426,7 @@ static inline struct aa_profile *aa_get_profile_rcu(struct aa_profile __rcu **p) static inline void aa_put_profile(struct aa_profile *p) { if (p) - kref_put(&p->label.count, aa_label_kref); + kref_put(&p->label.count.count, aa_label_kref); } static inline int AUDIT_MODE(struct aa_profile *profile) @@ -419,7 +443,7 @@ bool aa_policy_admin_capable(const struct cred *subj_cred, struct aa_label *label, struct aa_ns *ns); int aa_may_manage_policy(const struct cred *subj_cred, struct aa_label *label, struct aa_ns *ns, - u32 mask); + const struct cred *ocred, u32 mask); bool aa_current_policy_view_capable(struct aa_ns *ns); bool aa_current_policy_admin_capable(struct aa_ns *ns); diff --git a/security/apparmor/include/policy_ns.h b/security/apparmor/include/policy_ns.h index d646070fd966..cc6e84151812 100644 --- a/security/apparmor/include/policy_ns.h +++ b/security/apparmor/include/policy_ns.h @@ -18,6 +18,8 @@ #include "label.h" #include "policy.h" +/* Match max depth of user namespaces */ +#define MAX_NS_DEPTH 32 /* struct aa_ns_acct - accounting of profiles in namespace * @max_size: maximum space allowed for all profiles in namespace diff --git a/security/apparmor/include/policy_unpack.h b/security/apparmor/include/policy_unpack.h index a6f4611ee50c..e5a95dc4da1f 100644 --- a/security/apparmor/include/policy_unpack.h +++ b/security/apparmor/include/policy_unpack.h @@ -87,17 +87,29 @@ struct aa_ext { u32 version; }; -/* - * struct aa_loaddata - buffer of policy raw_data set +/* struct aa_loaddata - buffer of policy raw_data set + * @count: inode/filesystem refcount - use aa_get_i_loaddata() + * @pcount: profile refcount - use aa_get_profile_loaddata() + * @list: list the loaddata is on + * @work: used to do a delayed cleanup + * @dents: refs to dents created in aafs + * @ns: the namespace this loaddata was loaded into + * @name: + * @size: the size of the data that was loaded + * @compressed_size: the size of the data when it is compressed + * @revision: unique revision count that this data was loaded as + * @abi: the abi number the loaddata uses + * @hash: a hash of the loaddata, used to help dedup data * - * there is no loaddata ref for being on ns list, nor a ref from - * d_inode(@dentry) when grab a ref from these, @ns->lock must be held - * && __aa_get_loaddata() needs to be used, and the return value - * checked, if NULL the loaddata is already being reaped and should be - * considered dead. + * There is no loaddata ref for being on ns->rawdata_list, so + * @ns->lock must be held when walking the list. Dentries and + * inode opens hold refs on @count; profiles hold refs on @pcount. + * When the last @pcount drops, do_ploaddata_rmfs() removes the + * fs entries and drops the associated @count ref. */ struct aa_loaddata { - struct kref count; + struct aa_common_ref count; + struct kref pcount; struct list_head list; struct work_struct work; struct dentry *dents[AAFS_LOADDATA_NDENTS]; @@ -118,51 +130,54 @@ struct aa_loaddata { int aa_unpack(struct aa_loaddata *udata, struct list_head *lh, const char **ns); -/** - * __aa_get_loaddata - get a reference count to uncounted data reference - * @data: reference to get a count on - * - * Returns: pointer to reference OR NULL if race is lost and reference is - * being repeated. - * Requires: @data->ns->lock held, and the return code MUST be checked - * - * Use only from inode->i_private and @data->list found references - */ -static inline struct aa_loaddata * -__aa_get_loaddata(struct aa_loaddata *data) -{ - if (data && kref_get_unless_zero(&(data->count))) - return data; - - return NULL; -} - /** * aa_get_loaddata - get a reference count from a counted data reference * @data: reference to get a count on * - * Returns: point to reference + * Returns: pointer to reference * Requires: @data to have a valid reference count on it. It is a bug * if the race to reap can be encountered when it is used. */ static inline struct aa_loaddata * -aa_get_loaddata(struct aa_loaddata *data) +aa_get_i_loaddata(struct aa_loaddata *data) { - struct aa_loaddata *tmp = __aa_get_loaddata(data); - AA_BUG(data && !tmp); + if (data) + kref_get(&(data->count.count)); + return data; +} - return tmp; + +/** + * aa_get_profile_loaddata - get a profile reference count on loaddata + * @data: reference to get a count on + * + * Returns: pointer to reference + * Requires: @data to have a valid reference count on it. + */ +static inline struct aa_loaddata * +aa_get_profile_loaddata(struct aa_loaddata *data) +{ + if (data) + kref_get(&(data->pcount)); + return data; } void __aa_loaddata_update(struct aa_loaddata *data, long revision); bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r); void aa_loaddata_kref(struct kref *kref); +void aa_ploaddata_kref(struct kref *kref); struct aa_loaddata *aa_loaddata_alloc(size_t size); -static inline void aa_put_loaddata(struct aa_loaddata *data) +static inline void aa_put_i_loaddata(struct aa_loaddata *data) { if (data) - kref_put(&data->count, aa_loaddata_kref); + kref_put(&data->count.count, aa_loaddata_kref); +} + +static inline void aa_put_profile_loaddata(struct aa_loaddata *data) +{ + if (data) + kref_put(&data->pcount, aa_ploaddata_kref); } #if IS_ENABLED(CONFIG_KUNIT) diff --git a/security/apparmor/label.c b/security/apparmor/label.c index 913678f199c3..3a721fdf1833 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -52,7 +52,8 @@ static void free_proxy(struct aa_proxy *proxy) void aa_proxy_kref(struct kref *kref) { - struct aa_proxy *proxy = container_of(kref, struct aa_proxy, count); + struct aa_proxy *proxy = container_of(kref, struct aa_proxy, + count.count); free_proxy(proxy); } @@ -61,9 +62,10 @@ struct aa_proxy *aa_alloc_proxy(struct aa_label *label, gfp_t gfp) { struct aa_proxy *new; - new = kzalloc(sizeof(struct aa_proxy), gfp); + new = kzalloc_obj(struct aa_proxy, gfp); if (new) { - kref_init(&new->count); + kref_init(&new->count.count); + new->count.reftype = REF_PROXY; rcu_assign_pointer(new->label, aa_get_label(label)); } return new; @@ -375,7 +377,8 @@ static void label_free_rcu(struct rcu_head *head) void aa_label_kref(struct kref *kref) { - struct aa_label *label = container_of(kref, struct aa_label, count); + struct aa_label *label = container_of(kref, struct aa_label, + count.count); struct aa_ns *ns = labels_ns(label); if (!ns) { @@ -412,7 +415,8 @@ bool aa_label_init(struct aa_label *label, int size, gfp_t gfp) label->size = size; /* doesn't include null */ label->vec[size] = NULL; /* null terminate */ - kref_init(&label->count); + kref_init(&label->count.count); + label->count.reftype = REF_NS; /* for aafs purposes */ RB_CLEAR_NODE(&label->node); return true; @@ -434,7 +438,7 @@ struct aa_label *aa_label_alloc(int size, struct aa_proxy *proxy, gfp_t gfp) AA_BUG(size < 1); /* + 1 for null terminator entry on vec */ - new = kzalloc(struct_size(new, vec, size + 1), gfp); + new = kzalloc_flex(*new, vec, size + 1, gfp); AA_DEBUG(DEBUG_LABEL, "%s (%p)\n", __func__, new); if (!new) goto fail; @@ -1274,11 +1278,11 @@ static inline aa_state_t match_component(struct aa_profile *profile, * @rules: ruleset to search * @label: label to check access permissions for * @state: state to start match in - * @subns: whether to do permission checks on components in a subns + * @inview: whether to match labels in view or only in scope * @request: permissions to request * @perms: perms struct to set * - * Returns: 0 on success else ERROR + * Returns: state match stopped at or DFA_NOMATCH if aborted early * * For the label A//&B//&C this does the perm match for A//&B//&C * @perms should be preinitialized with allperms OR a previous permission @@ -1287,7 +1291,7 @@ static inline aa_state_t match_component(struct aa_profile *profile, static int label_compound_match(struct aa_profile *profile, struct aa_ruleset *rules, struct aa_label *label, - aa_state_t state, bool subns, u32 request, + aa_state_t state, bool inview, u32 request, struct aa_perms *perms) { struct aa_profile *tp; @@ -1295,7 +1299,7 @@ static int label_compound_match(struct aa_profile *profile, /* find first subcomponent that is visible */ label_for_each(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, rules, tp, state); if (!state) @@ -1305,11 +1309,11 @@ static int label_compound_match(struct aa_profile *profile, /* no component visible */ *perms = allperms; - return 0; + return state; next: label_for_each_cont(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = aa_dfa_match(rules->policy->dfa, state, "//&"); state = match_component(profile, rules, tp, state); @@ -1317,15 +1321,11 @@ static int label_compound_match(struct aa_profile *profile, goto fail; } *perms = *aa_lookup_perms(rules->policy, state); - aa_apply_modes_to_perms(profile, perms); - if ((perms->allow & request) != request) - return -EACCES; - - return 0; + return state; fail: *perms = nullperms; - return state; + return DFA_NOMATCH; } /** @@ -1334,11 +1334,11 @@ static int label_compound_match(struct aa_profile *profile, * @rules: ruleset to search * @label: label to check access permissions for * @start: state to start match in - * @subns: whether to do permission checks on components in a subns + * @inview: whether to match labels in view or only in scope * @request: permissions to request * @perms: an initialized perms struct to add accumulation to * - * Returns: 0 on success else ERROR + * Returns: the state the match finished in, may be the none matching state * * For the label A//&B//&C this does the perm match for each of A and B and C * @perms should be preinitialized with allperms OR a previous permission @@ -1347,7 +1347,7 @@ static int label_compound_match(struct aa_profile *profile, static int label_components_match(struct aa_profile *profile, struct aa_ruleset *rules, struct aa_label *label, aa_state_t start, - bool subns, u32 request, + bool inview, u32 request, struct aa_perms *perms) { struct aa_profile *tp; @@ -1357,7 +1357,7 @@ static int label_components_match(struct aa_profile *profile, /* find first subcomponent to test */ label_for_each(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, rules, tp, start); if (!state) @@ -1366,31 +1366,29 @@ static int label_components_match(struct aa_profile *profile, } /* no subcomponents visible - no change in perms */ - return 0; + return state; next: tmp = *aa_lookup_perms(rules->policy, state); - aa_apply_modes_to_perms(profile, &tmp); aa_perms_accum(perms, &tmp); label_for_each_cont(i, label, tp) { - if (!aa_ns_visible(profile->ns, tp->ns, subns)) + if (!aa_ns_visible(profile->ns, tp->ns, inview)) continue; state = match_component(profile, rules, tp, start); if (!state) goto fail; tmp = *aa_lookup_perms(rules->policy, state); - aa_apply_modes_to_perms(profile, &tmp); aa_perms_accum(perms, &tmp); } if ((perms->allow & request) != request) - return -EACCES; + return DFA_NOMATCH; - return 0; + return state; fail: *perms = nullperms; - return -EACCES; + return DFA_NOMATCH; } /** @@ -1399,23 +1397,24 @@ static int label_components_match(struct aa_profile *profile, * @rules: ruleset to search * @label: label to match (NOT NULL) * @state: state to start in - * @subns: whether to match subns components + * @inview: whether to match labels in view or only in scope * @request: permission request * @perms: Returns computed perms (NOT NULL) * * Returns: the state the match finished in, may be the none matching state */ int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules, - struct aa_label *label, aa_state_t state, bool subns, + struct aa_label *label, aa_state_t state, bool inview, u32 request, struct aa_perms *perms) { - int error = label_compound_match(profile, rules, label, state, subns, - request, perms); - if (!error) - return error; + aa_state_t tmp = label_compound_match(profile, rules, label, state, + inview, request, perms); + if ((perms->allow & request) == request) + return tmp; + /* failed compound_match try component matches */ *perms = allperms; - return label_components_match(profile, rules, label, state, subns, + return label_components_match(profile, rules, label, state, inview, request, perms); } diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 82dbb97ad406..e41ff57798b2 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c @@ -44,6 +44,8 @@ static struct val_table_ent debug_values_table[] = { { "domain", DEBUG_DOMAIN }, { "policy", DEBUG_POLICY }, { "interface", DEBUG_INTERFACE }, + { "unpack", DEBUG_UNPACK }, + { "tags", DEBUG_TAGS }, { NULL, 0 } }; @@ -118,18 +120,18 @@ int aa_print_debug_params(char *buffer) bool aa_resize_str_table(struct aa_str_table *t, int newsize, gfp_t gfp) { - char **n; + struct aa_str_table_ent *n; int i; if (t->size == newsize) return true; - n = kcalloc(newsize, sizeof(*n), gfp); + n = kzalloc_objs(*n, newsize, gfp); if (!n) return false; for (i = 0; i < min(t->size, newsize); i++) n[i] = t->table[i]; for (; i < t->size; i++) - kfree_sensitive(t->table[i]); + kfree_sensitive(t->table[i].strs); if (newsize > t->size) memset(&n[t->size], 0, (newsize-t->size)*sizeof(*n)); kfree_sensitive(t->table); @@ -140,10 +142,10 @@ bool aa_resize_str_table(struct aa_str_table *t, int newsize, gfp_t gfp) } /** - * aa_free_str_table - free entries str table + * aa_destroy_str_table - free entries str table * @t: the string table to free (MAYBE NULL) */ -void aa_free_str_table(struct aa_str_table *t) +void aa_destroy_str_table(struct aa_str_table *t) { int i; @@ -152,7 +154,7 @@ void aa_free_str_table(struct aa_str_table *t) return; for (i = 0; i < t->size; i++) - kfree_sensitive(t->table[i]); + kfree_sensitive(t->table[i].strs); kfree_sensitive(t->table); t->table = NULL; t->size = 0; @@ -233,7 +235,7 @@ __counted char *aa_str_alloc(int size, gfp_t gfp) { struct counted_str *str; - str = kmalloc(struct_size(str, name, size), gfp); + str = kmalloc_flex(*str, name, size, gfp); if (!str) return NULL; @@ -478,19 +480,17 @@ bool aa_policy_init(struct aa_policy *policy, const char *prefix, const char *name, gfp_t gfp) { char *hname; + size_t hname_sz; + hname_sz = (prefix ? strlen(prefix) + 2 : 0) + strlen(name) + 1; /* freed by policy_free */ - if (prefix) { - hname = aa_str_alloc(strlen(prefix) + strlen(name) + 3, gfp); - if (hname) - sprintf(hname, "%s//%s", prefix, name); - } else { - hname = aa_str_alloc(strlen(name) + 1, gfp); - if (hname) - strcpy(hname, name); - } + hname = aa_str_alloc(hname_sz, gfp); if (!hname) return false; + if (prefix) + scnprintf(hname, hname_sz, "%s//%s", prefix, name); + else + strscpy(hname, name, hname_sz); policy->hname = hname; /* base.name is a substring of fqname */ policy->name = basename(policy->hname); @@ -512,3 +512,4 @@ void aa_policy_destroy(struct aa_policy *policy) /* don't free name as its a subset of hname */ aa_put_str(policy->hname); } + diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index a87cd60ed206..c1d42fc72fdb 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -520,33 +520,26 @@ static void apparmor_file_free_security(struct file *file) aa_put_label(rcu_access_pointer(ctx->label)); } -static int common_file_perm(const char *op, struct file *file, u32 mask, - bool in_atomic) +static int common_file_perm(const char *op, struct file *file, u32 mask) { struct aa_label *label; int error = 0; - bool needput; - /* don't reaudit files closed during inheritance */ - if (unlikely(file->f_path.dentry == aa_null.dentry)) - return -EACCES; - - label = __begin_current_label_crit_section(&needput); - error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic); - __end_current_label_crit_section(label, needput); + label = begin_current_label_crit_section(); + error = aa_file_perm(op, current_cred(), label, file, mask, false); + end_current_label_crit_section(label); return error; } static int apparmor_file_receive(struct file *file) { - return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file), - false); + return common_file_perm(OP_FRECEIVE, file, aa_map_file_to_perms(file)); } static int apparmor_file_permission(struct file *file, int mask) { - return common_file_perm(OP_FPERM, file, mask, false); + return common_file_perm(OP_FPERM, file, mask); } static int apparmor_file_lock(struct file *file, unsigned int cmd) @@ -556,11 +549,11 @@ static int apparmor_file_lock(struct file *file, unsigned int cmd) if (cmd == F_WRLCK) mask |= MAY_WRITE; - return common_file_perm(OP_FLOCK, file, mask, false); + return common_file_perm(OP_FLOCK, file, mask); } static int common_mmap(const char *op, struct file *file, unsigned long prot, - unsigned long flags, bool in_atomic) + unsigned long flags) { int mask = 0; @@ -578,21 +571,20 @@ static int common_mmap(const char *op, struct file *file, unsigned long prot, if (prot & PROT_EXEC) mask |= AA_EXEC_MMAP; - return common_file_perm(op, file, mask, in_atomic); + return common_file_perm(op, file, mask); } static int apparmor_mmap_file(struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags) { - return common_mmap(OP_FMMAP, file, prot, flags, GFP_ATOMIC); + return common_mmap(OP_FMMAP, file, prot, flags); } static int apparmor_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, unsigned long prot) { return common_mmap(OP_FMPROT, vma->vm_file, prot, - !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0, - false); + !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); } #ifdef CONFIG_IO_URING @@ -2133,6 +2125,23 @@ static int param_set_mode(const char *val, const struct kernel_param *kp) return 0; } +/* arbitrary cap on how long to hold buffer because contention was + * encountered before trying to put it back into the global pool + */ +#define MAX_HOLD_COUNT 64 + +/* the hold count is a heuristic for lock contention, and can be + * incremented async to actual buffer alloc/free. Because buffers + * may be put back onto a percpu cache different than the ->hold was + * added to the counts can be out of sync. Guard against underflow + * and overflow + */ +static void cache_hold_inc(unsigned int *hold) +{ + if (*hold > MAX_HOLD_COUNT) + (*hold)++; +} + char *aa_get_buffer(bool in_atomic) { union aa_buffer *aa_buf; @@ -2145,21 +2154,26 @@ char *aa_get_buffer(bool in_atomic) if (!list_empty(&cache->head)) { aa_buf = list_first_entry(&cache->head, union aa_buffer, list); list_del(&aa_buf->list); - cache->hold--; + if (cache->hold) + cache->hold--; cache->count--; put_cpu_ptr(&aa_local_buffers); return &aa_buf->buffer[0]; } + /* exit percpu as spinlocks may sleep on realtime kernels */ put_cpu_ptr(&aa_local_buffers); if (!spin_trylock(&aa_buffers_lock)) { + /* had contention on lock so increase hold count. Doesn't + * really matter if recorded before or after the spin lock + * as there is no way to guarantee the buffer will be put + * back on the same percpu cache. Instead rely on holds + * roughly averaging out over time. + */ cache = get_cpu_ptr(&aa_local_buffers); - cache->hold += 1; + cache_hold_inc(&cache->hold); put_cpu_ptr(&aa_local_buffers); spin_lock(&aa_buffers_lock); - } else { - cache = get_cpu_ptr(&aa_local_buffers); - put_cpu_ptr(&aa_local_buffers); } retry: if (buffer_count > reserve_count || @@ -2214,13 +2228,11 @@ void aa_put_buffer(char *buf) list_add(&aa_buf->list, &aa_global_buffers); buffer_count++; spin_unlock(&aa_buffers_lock); - cache = get_cpu_ptr(&aa_local_buffers); - put_cpu_ptr(&aa_local_buffers); return; } /* contention on global list, fallback to percpu */ cache = get_cpu_ptr(&aa_local_buffers); - cache->hold += 1; + cache_hold_inc(&cache->hold); } /* cache in percpu list */ @@ -2456,7 +2468,7 @@ static int __init aa_setup_dfa_engine(void) goto fail; } nullpdb->dfa = aa_get_dfa(nulldfa); - nullpdb->perms = kcalloc(2, sizeof(struct aa_perms), GFP_KERNEL); + nullpdb->perms = kzalloc_objs(struct aa_perms, 2); if (!nullpdb->perms) goto fail; nullpdb->size = 2; diff --git a/security/apparmor/match.c b/security/apparmor/match.c index c5a91600842a..e9fac67e5178 100644 --- a/security/apparmor/match.c +++ b/security/apparmor/match.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "include/lib.h" #include "include/match.h" @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize) /* loaded td_id's start at 1, subtract 1 now to avoid doing * it every time we use td_id as an index */ - th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1; + th.td_id = get_unaligned_be16(blob) - 1; if (th.td_id > YYTD_ID_MAX) goto out; - th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2)); - th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8)); + th.td_flags = get_unaligned_be16(blob + 2); + th.td_lolen = get_unaligned_be32(blob + 8); blob += sizeof(struct table_header); if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || @@ -66,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize) table->td_flags = th.td_flags; table->td_lolen = th.td_lolen; if (th.td_flags == YYTD_DATA8) - UNPACK_ARRAY(table->td_data, blob, th.td_lolen, - u8, u8, byte_to_byte); + memcpy(table->td_data, blob, th.td_lolen); else if (th.td_flags == YYTD_DATA16) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, - u16, __be16, be16_to_cpu); + u16, __be16, get_unaligned_be16); else if (th.td_flags == YYTD_DATA32) UNPACK_ARRAY(table->td_data, blob, th.td_lolen, - u32, __be32, be32_to_cpu); + u32, __be32, get_unaligned_be32); else goto fail; /* if table was vmalloced make sure the page tables are synced @@ -160,9 +160,10 @@ static int verify_dfa(struct aa_dfa *dfa) if (state_count == 0) goto out; for (i = 0; i < state_count; i++) { - if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) && - (DEFAULT_TABLE(dfa)[i] >= state_count)) + if (DEFAULT_TABLE(dfa)[i] >= state_count) { + pr_err("AppArmor DFA default state out of bounds"); goto out; + } if (BASE_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) { pr_err("AppArmor DFA state with invalid match flags"); goto out; @@ -201,16 +202,31 @@ static int verify_dfa(struct aa_dfa *dfa) size_t j, k; for (j = i; - (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && - !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE); + ((BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE) && + !(BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE_VERIFIED)); j = k) { + if (BASE_TABLE(dfa)[j] & MARK_DIFF_ENCODE) + /* loop in current chain */ + goto out; k = DEFAULT_TABLE(dfa)[j]; if (j == k) + /* self loop */ goto out; - if (k < j) - break; /* already verified */ BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE; } + /* move mark to verified */ + for (j = i; + (BASE_TABLE(dfa)[j] & MATCH_FLAG_DIFF_ENCODE); + j = k) { + k = DEFAULT_TABLE(dfa)[j]; + if (j < i) + /* jumps to state/chain that has been + * verified + */ + break; + BASE_TABLE(dfa)[j] &= ~MARK_DIFF_ENCODE; + BASE_TABLE(dfa)[j] |= MARK_DIFF_ENCODE_VERIFIED; + } } error = 0; @@ -301,7 +317,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) int error = -ENOMEM; char *data = blob; struct table_header *table = NULL; - struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); + struct aa_dfa *dfa = kzalloc_obj(struct aa_dfa); if (!dfa) goto fail; @@ -313,14 +329,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) if (size < sizeof(struct table_set_header)) goto fail; - if (ntohl(*(__be32 *) data) != YYTH_MAGIC) + if (get_unaligned_be32(data) != YYTH_MAGIC) goto fail; - hsize = ntohl(*(__be32 *) (data + 4)); + hsize = get_unaligned_be32(data + 4); if (size < hsize) goto fail; - dfa->flags = ntohs(*(__be16 *) (data + 12)); + dfa->flags = get_unaligned_be16(data + 12); if (dfa->flags & ~(YYTH_FLAGS)) goto fail; @@ -329,7 +345,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) { * if (hsize < 16 + 4) * goto fail; - * dfa->max_oob = ntol(*(__be32 *) (data + 16)); + * dfa->max_oob = get_unaligned_be32(data + 16); * if (dfa->max <= MAX_OOB_SUPPORTED) { * pr_err("AppArmor DFA OOB greater than supported\n"); * goto fail; @@ -463,13 +479,18 @@ aa_state_t aa_dfa_match_len(struct aa_dfa *dfa, aa_state_t start, if (dfa->tables[YYTD_ID_EC]) { /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); - for (; len; len--) - match_char(state, def, base, next, check, - equiv[(u8) *str++]); + for (; len; len--) { + u8 c = equiv[(u8) *str]; + + match_char(state, def, base, next, check, c); + str++; + } } else { /* default is direct to next state */ - for (; len; len--) - match_char(state, def, base, next, check, (u8) *str++); + for (; len; len--) { + match_char(state, def, base, next, check, (u8) *str); + str++; + } } return state; @@ -503,13 +524,18 @@ aa_state_t aa_dfa_match(struct aa_dfa *dfa, aa_state_t start, const char *str) /* Equivalence class table defined */ u8 *equiv = EQUIV_TABLE(dfa); /* default is direct to next state */ - while (*str) - match_char(state, def, base, next, check, - equiv[(u8) *str++]); + while (*str) { + u8 c = equiv[(u8) *str]; + + match_char(state, def, base, next, check, c); + str++; + } } else { /* default is direct to next state */ - while (*str) - match_char(state, def, base, next, check, (u8) *str++); + while (*str) { + match_char(state, def, base, next, check, (u8) *str); + str++; + } } return state; diff --git a/security/apparmor/net.c b/security/apparmor/net.c index 45cf25605c34..44c04102062f 100644 --- a/security/apparmor/net.c +++ b/security/apparmor/net.c @@ -326,8 +326,10 @@ int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, struct socket *sock = (struct socket *) file->private_data; AA_BUG(!label); - AA_BUG(!sock); - AA_BUG(!sock->sk); + + /* sock && sock->sk can be NULL for sockets being set up or torn down */ + if (!sock || !sock->sk) + return 0; if (sock->sk->sk_family == PF_UNIX) return aa_unix_file_perm(subj_cred, label, op, request, file); diff --git a/security/apparmor/path.c b/security/apparmor/path.c index d6c74c357ffd..65a0ca5cc1bd 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,12 +164,15 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* - * Append "/" to the pathname. The root directory is a special - * case; it already ends in slash. + /* Append "/" to directory paths, except for root "/" which + * already ends in a slash. */ - if (!error && isdir && ((*name)[1] != '\0' || (*name)[0] != '/')) - strcpy(&buf[aa_g_path_max - 2], "/"); + if (!error && isdir) { + bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; + + if (!is_root) + buf[aa_g_path_max - 2] = '/'; + } return error; } diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 50d5345ff5cb..b6a5eb4021db 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -98,13 +98,21 @@ const char *const aa_profile_mode_names[] = { "user", }; +void aa_destroy_tags(struct aa_tags_struct *tags) +{ + kfree_sensitive(tags->hdrs.table); + kfree_sensitive(tags->sets.table); + aa_destroy_str_table(&tags->strs); + memset(tags, 0, sizeof(*tags)); +} static void aa_free_pdb(struct aa_policydb *pdb) { if (pdb) { aa_put_dfa(pdb->dfa); kvfree(pdb->perms); - aa_free_str_table(&pdb->trans); + aa_destroy_str_table(&pdb->trans); + aa_destroy_tags(&pdb->tags); kfree(pdb); } } @@ -123,7 +131,7 @@ void aa_pdb_free_kref(struct kref *kref) struct aa_policydb *aa_alloc_pdb(gfp_t gfp) { - struct aa_policydb *pdb = kzalloc(sizeof(struct aa_policydb), gfp); + struct aa_policydb *pdb = kzalloc_obj(struct aa_policydb, gfp); if (!pdb) return NULL; @@ -183,19 +191,43 @@ static void __list_remove_profile(struct aa_profile *profile) } /** - * __remove_profile - remove old profile, and children - * @profile: profile to be replaced (NOT NULL) + * __remove_profile - remove profile, and children + * @profile: profile to be removed (NOT NULL) * * Requires: namespace list lock be held, or list not be shared */ static void __remove_profile(struct aa_profile *profile) { + struct aa_profile *curr, *to_remove; + AA_BUG(!profile); AA_BUG(!profile->ns); AA_BUG(!mutex_is_locked(&profile->ns->lock)); /* release any children lists first */ - __aa_profile_list_release(&profile->base.profiles); + if (!list_empty(&profile->base.profiles)) { + curr = list_first_entry(&profile->base.profiles, struct aa_profile, base.list); + + while (curr != profile) { + + while (!list_empty(&curr->base.profiles)) + curr = list_first_entry(&curr->base.profiles, + struct aa_profile, base.list); + + to_remove = curr; + if (!list_is_last(&to_remove->base.list, + &aa_deref_parent(curr)->base.profiles)) + curr = list_next_entry(to_remove, base.list); + else + curr = aa_deref_parent(curr); + + /* released by free_profile */ + aa_label_remove(&to_remove->label); + __aafs_profile_rmdir(to_remove); + __list_remove_profile(to_remove); + } + } + /* released by free_profile */ aa_label_remove(&profile->label); __aafs_profile_rmdir(profile); @@ -224,6 +256,9 @@ static void aa_free_data(void *ptr, void *arg) { struct aa_data *data = ptr; + if (!ptr) + return; + kvfree_sensitive(data->data, data->size); kfree_sensitive(data->key); kfree_sensitive(data); @@ -233,6 +268,9 @@ static void free_attachment(struct aa_attachment *attach) { int i; + if (!attach) + return; + for (i = 0; i < attach->xattr_count; i++) kfree_sensitive(attach->xattrs[i]); kfree_sensitive(attach->xattrs); @@ -261,7 +299,7 @@ struct aa_ruleset *aa_alloc_ruleset(gfp_t gfp) { struct aa_ruleset *rules; - rules = kzalloc(sizeof(*rules), gfp); + rules = kzalloc_obj(*rules, gfp); return rules; } @@ -312,7 +350,7 @@ void aa_free_profile(struct aa_profile *profile) } kfree_sensitive(profile->hash); - aa_put_loaddata(profile->rawdata); + aa_put_profile_loaddata(profile->rawdata); aa_label_destroy(&profile->label); kfree_sensitive(profile); @@ -335,7 +373,7 @@ struct aa_profile *aa_alloc_profile(const char *hname, struct aa_proxy *proxy, * this adds space for a single ruleset in the rules section of the * label */ - profile = kzalloc(struct_size(profile, label.rules, 1), gfp); + profile = kzalloc_flex(*profile, label.rules, 1, gfp); if (!profile) return NULL; @@ -697,24 +735,27 @@ struct aa_profile *aa_new_learning_profile(struct aa_profile *parent, bool hat, struct aa_profile *p, *profile; const char *bname; char *name = NULL; + size_t name_sz; AA_BUG(!parent); if (base) { - name = kmalloc(strlen(parent->base.hname) + 8 + strlen(base), - gfp); + name_sz = strlen(parent->base.hname) + 8 + strlen(base); + name = kmalloc(name_sz, gfp); if (name) { - sprintf(name, "%s//null-%s", parent->base.hname, base); + snprintf(name, name_sz, "%s//null-%s", + parent->base.hname, base); goto name; } /* fall through to try shorter uniq */ } - name = kmalloc(strlen(parent->base.hname) + 2 + 7 + 8, gfp); + name_sz = strlen(parent->base.hname) + 2 + 7 + 8; + name = kmalloc(name_sz, gfp); if (!name) return NULL; - sprintf(name, "%s//null-%x", parent->base.hname, - atomic_inc_return(&parent->ns->uniq_null)); + snprintf(name, name_sz, "%s//null-%x", parent->base.hname, + atomic_inc_return(&parent->ns->uniq_null)); name: /* lookup to see if this is a dup creation */ @@ -901,17 +942,44 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns) return res; } +static bool is_subset_of_obj_privilege(const struct cred *cred, + struct aa_label *label, + const struct cred *ocred) +{ + if (cred == ocred) + return true; + + if (!aa_label_is_subset(label, cred_label(ocred))) + return false; + /* don't allow crossing userns for now */ + if (cred->user_ns != ocred->user_ns) + return false; + if (!cap_issubset(cred->cap_inheritable, ocred->cap_inheritable)) + return false; + if (!cap_issubset(cred->cap_permitted, ocred->cap_permitted)) + return false; + if (!cap_issubset(cred->cap_effective, ocred->cap_effective)) + return false; + if (!cap_issubset(cred->cap_bset, ocred->cap_bset)) + return false; + if (!cap_issubset(cred->cap_ambient, ocred->cap_ambient)) + return false; + return true; +} + + /** * aa_may_manage_policy - can the current task manage policy * @subj_cred: subjects cred * @label: label to check if it can manage policy * @ns: namespace being managed by @label (may be NULL if @label's ns) + * @ocred: object cred if request is coming from an open object * @mask: contains the policy manipulation operation being done * * Returns: 0 if the task is allowed to manipulate policy else error */ int aa_may_manage_policy(const struct cred *subj_cred, struct aa_label *label, - struct aa_ns *ns, u32 mask) + struct aa_ns *ns, const struct cred *ocred, u32 mask) { const char *op; @@ -927,6 +995,11 @@ int aa_may_manage_policy(const struct cred *subj_cred, struct aa_label *label, return audit_policy(label, op, NULL, NULL, "policy_locked", -EACCES); + if (ocred && !is_subset_of_obj_privilege(subj_cred, label, ocred)) + return audit_policy(label, op, NULL, NULL, + "not privileged for target profile", + -EACCES); + if (!aa_policy_admin_capable(subj_cred, label, ns)) return audit_policy(label, op, NULL, NULL, "not policy admin", -EACCES); @@ -1098,7 +1171,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label, LIST_HEAD(lh); op = mask & AA_MAY_REPLACE_POLICY ? OP_PROF_REPL : OP_PROF_LOAD; - aa_get_loaddata(udata); + aa_get_profile_loaddata(udata); /* released below */ error = aa_unpack(udata, &lh, &ns_name); if (error) @@ -1125,6 +1198,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label, goto fail; } ns_name = ent->ns_name; + ent->ns_name = NULL; } else count++; } @@ -1149,10 +1223,10 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label, if (aa_rawdata_eq(rawdata_ent, udata)) { struct aa_loaddata *tmp; - tmp = __aa_get_loaddata(rawdata_ent); + tmp = aa_get_profile_loaddata(rawdata_ent); /* check we didn't fail the race */ if (tmp) { - aa_put_loaddata(udata); + aa_put_profile_loaddata(udata); udata = tmp; break; } @@ -1165,7 +1239,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label, struct aa_profile *p; if (aa_g_export_binary) - ent->new->rawdata = aa_get_loaddata(udata); + ent->new->rawdata = aa_get_profile_loaddata(udata); error = __lookup_replace(ns, ent->new->base.hname, !(mask & AA_MAY_REPLACE_POLICY), &ent->old, &info); @@ -1298,7 +1372,7 @@ ssize_t aa_replace_profiles(struct aa_ns *policy_ns, struct aa_label *label, out: aa_put_ns(ns); - aa_put_loaddata(udata); + aa_put_profile_loaddata(udata); kfree(ns_name); if (error) diff --git a/security/apparmor/policy_compat.c b/security/apparmor/policy_compat.c index cfc2207e5a12..5fc16d56fbf4 100644 --- a/security/apparmor/policy_compat.c +++ b/security/apparmor/policy_compat.c @@ -158,7 +158,7 @@ static struct aa_perms *compute_fperms(struct aa_dfa *dfa, state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; /* DFAs are restricted from having a state_count of less than 2 */ - table = kvcalloc(state_count * 2, sizeof(struct aa_perms), GFP_KERNEL); + table = kvzalloc_objs(struct aa_perms, state_count * 2); if (!table) return NULL; *size = state_count * 2; @@ -182,7 +182,7 @@ static struct aa_perms *compute_xmatch_perms(struct aa_dfa *xmatch, state_count = xmatch->tables[YYTD_ID_BASE]->td_lolen; /* DFAs are restricted from having a state_count of less than 2 */ - perms = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL); + perms = kvzalloc_objs(struct aa_perms, state_count); if (!perms) return NULL; *size = state_count; @@ -257,15 +257,21 @@ static struct aa_perms *compute_perms(struct aa_dfa *dfa, u32 version, state_count = dfa->tables[YYTD_ID_BASE]->td_lolen; /* DFAs are restricted from having a state_count of less than 2 */ - table = kvcalloc(state_count, sizeof(struct aa_perms), GFP_KERNEL); + table = kvzalloc_objs(struct aa_perms, state_count); if (!table) return NULL; *size = state_count; /* zero init so skip the trap state (state == 0) */ - for (state = 1; state < state_count; state++) + for (state = 1; state < state_count; state++) { table[state] = compute_perms_entry(dfa, state, version); - + AA_DEBUG(DEBUG_UNPACK, + "[%d]: (0x%x/0x%x/0x%x//0x%x/0x%x//0x%x), converted from accept1: 0x%x, accept2: 0x%x", + state, table[state].allow, table[state].deny, + table[state].prompt, table[state].audit, + table[state].quiet, table[state].xindex, + ACCEPT_TABLE(dfa)[state], ACCEPT_TABLE2(dfa)[state]); + } return table; } diff --git a/security/apparmor/policy_ns.c b/security/apparmor/policy_ns.c index 64783ca3b0f2..5a907a875d8f 100644 --- a/security/apparmor/policy_ns.c +++ b/security/apparmor/policy_ns.c @@ -106,7 +106,7 @@ static struct aa_ns *alloc_ns(const char *prefix, const char *name) { struct aa_ns *ns; - ns = kzalloc(sizeof(*ns), GFP_KERNEL); + ns = kzalloc_obj(*ns); AA_DEBUG(DEBUG_POLICY, "%s(%p)\n", __func__, ns); if (!ns) return NULL; @@ -223,6 +223,8 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name, AA_BUG(!name); AA_BUG(!mutex_is_locked(&parent->lock)); + if (parent->level > MAX_NS_DEPTH) + return ERR_PTR(-ENOSPC); ns = alloc_ns(parent->base.hname, name); if (!ns) return ERR_PTR(-ENOMEM); diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c index 7523971e37d9..076d3ff14da6 100644 --- a/security/apparmor/policy_unpack.c +++ b/security/apparmor/policy_unpack.c @@ -109,22 +109,8 @@ bool aa_rawdata_eq(struct aa_loaddata *l, struct aa_loaddata *r) return memcmp(l->data, r->data, r->compressed_size ?: r->size) == 0; } -/* - * need to take the ns mutex lock which is NOT safe most places that - * put_loaddata is called, so we have to delay freeing it - */ -static void do_loaddata_free(struct work_struct *work) +static void do_loaddata_free(struct aa_loaddata *d) { - struct aa_loaddata *d = container_of(work, struct aa_loaddata, work); - struct aa_ns *ns = aa_get_ns(d->ns); - - if (ns) { - mutex_lock_nested(&ns->lock, ns->level); - __aa_fs_remove_rawdata(d); - mutex_unlock(&ns->lock); - aa_put_ns(ns); - } - kfree_sensitive(d->hash); kfree_sensitive(d->name); kvfree(d->data); @@ -133,10 +119,38 @@ static void do_loaddata_free(struct work_struct *work) void aa_loaddata_kref(struct kref *kref) { - struct aa_loaddata *d = container_of(kref, struct aa_loaddata, count); + struct aa_loaddata *d = container_of(kref, struct aa_loaddata, + count.count); + + do_loaddata_free(d); +} + +/* + * need to take the ns mutex lock which is NOT safe most places that + * put_loaddata is called, so we have to delay freeing it + */ +static void do_ploaddata_rmfs(struct work_struct *work) +{ + struct aa_loaddata *d = container_of(work, struct aa_loaddata, work); + struct aa_ns *ns = aa_get_ns(d->ns); + + if (ns) { + mutex_lock_nested(&ns->lock, ns->level); + /* remove fs ref to loaddata */ + __aa_fs_remove_rawdata(d); + mutex_unlock(&ns->lock); + aa_put_ns(ns); + } + /* called by dropping last pcount, so drop its associated icount */ + aa_put_i_loaddata(d); +} + +void aa_ploaddata_kref(struct kref *kref) +{ + struct aa_loaddata *d = container_of(kref, struct aa_loaddata, pcount); if (d) { - INIT_WORK(&d->work, do_loaddata_free); + INIT_WORK(&d->work, do_ploaddata_rmfs); schedule_work(&d->work); } } @@ -145,7 +159,7 @@ struct aa_loaddata *aa_loaddata_alloc(size_t size) { struct aa_loaddata *d; - d = kzalloc(sizeof(*d), GFP_KERNEL); + d = kzalloc_obj(*d); if (d == NULL) return ERR_PTR(-ENOMEM); d->data = kvzalloc(size, GFP_KERNEL); @@ -153,7 +167,9 @@ struct aa_loaddata *aa_loaddata_alloc(size_t size) kfree(d); return ERR_PTR(-ENOMEM); } - kref_init(&d->count); + kref_init(&d->count.count); + d->count.reftype = REF_RAWDATA; + kref_init(&d->pcount); INIT_LIST_HEAD(&d->list); return d; @@ -450,20 +466,73 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e, int flags) return dfa; } +static int process_strs_entry(char *str, int size, bool multi) +{ + int c = 1; + + if (size <= 0) + return -1; + if (multi) { + if (size < 2) + return -2; + /* multi ends with double \0 */ + if (str[size - 2]) + return -3; + } + + char *save = str; + char *pos = str; + char *end = multi ? str + size - 2 : str + size - 1; + /* count # of internal \0 */ + while (str < end) { + if (str == pos) { + /* starts with ... */ + if (!*str) { + AA_DEBUG(DEBUG_UNPACK, + "starting with null save=%lu size %d c=%d", + (unsigned long)(str - save), size, c); + return -4; + } + if (isspace(*str)) + return -5; + if (*str == ':') { + /* :ns_str\0str\0 + * first character after : must be valid + */ + if (!str[1]) + return -6; + } + } else if (!*str) { + if (*pos == ':') + *str = ':'; + else + c++; + pos = str + 1; + } + str++; + } /* while */ + + return c; +} + /** - * unpack_trans_table - unpack a profile transition table + * unpack_strs_table - unpack a profile transition table * @e: serialized data extent information (NOT NULL) + * @name: name of table (MAY BE NULL) + * @multi: allow multiple strings on a single entry * @strs: str table to unpack to (NOT NULL) * - * Returns: true if table successfully unpacked or not present + * Returns: 0 if table successfully unpacked or not present, else error */ -static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs) +static int unpack_strs_table(struct aa_ext *e, const char *name, bool multi, + struct aa_str_table *strs) { void *saved_pos = e->pos; - char **table = NULL; + struct aa_str_table_ent *table = NULL; + int error = -EPROTO; /* exec table is optional */ - if (aa_unpack_nameX(e, AA_STRUCT, "xtable")) { + if (aa_unpack_nameX(e, AA_STRUCT, name)) { u16 size; int i; @@ -475,61 +544,46 @@ static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs) * for size check here */ goto fail; - table = kcalloc(size, sizeof(char *), GFP_KERNEL); - if (!table) + table = kzalloc_objs(struct aa_str_table_ent, size); + if (!table) { + error = -ENOMEM; goto fail; - + } strs->table = table; strs->size = size; for (i = 0; i < size; i++) { char *str; - int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL); + int c, size2 = aa_unpack_strdup(e, &str, NULL); /* aa_unpack_strdup verifies that the last character is * null termination byte. */ - if (!size2) + c = process_strs_entry(str, size2, multi); + if (c <= 0) { + AA_DEBUG(DEBUG_UNPACK, "process_strs %d i %d pos %ld", + c, i, + (unsigned long)(e->pos - saved_pos)); goto fail; - table[i] = str; - /* verify that name doesn't start with space */ - if (isspace(*str)) - goto fail; - - /* count internal # of internal \0 */ - for (c = j = 0; j < size2 - 1; j++) { - if (!str[j]) { - pos = j; - c++; - } } - if (*str == ':') { - /* first character after : must be valid */ - if (!str[1]) - goto fail; - /* beginning with : requires an embedded \0, - * verify that exactly 1 internal \0 exists - * trailing \0 already verified by aa_unpack_strdup - * - * convert \0 back to : for label_parse - */ - if (c == 1) - str[pos] = ':'; - else if (c > 1) - goto fail; - } else if (c) + if (!multi && c > 1) { + AA_DEBUG(DEBUG_UNPACK, "!multi && c > 1"); /* fail - all other cases with embedded \0 */ goto fail; + } + table[i].strs = str; + table[i].count = c; + table[i].size = size2; } if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) goto fail; if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) goto fail; } - return true; + return 0; fail: - aa_free_str_table(strs); + aa_destroy_str_table(strs); e->pos = saved_pos; - return false; + return error; } static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile) @@ -573,8 +627,7 @@ static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules) if (!aa_unpack_array(e, NULL, &size)) goto fail; - rules->secmark = kcalloc(size, sizeof(struct aa_secmark), - GFP_KERNEL); + rules->secmark = kzalloc_objs(struct aa_secmark, size); if (!rules->secmark) goto fail; @@ -644,6 +697,204 @@ static bool unpack_rlimits(struct aa_ext *e, struct aa_ruleset *rules) return false; } + +static bool verify_tags(struct aa_tags_struct *tags, const char **info) +{ + if ((tags->hdrs.size && !tags->hdrs.table) || + (!tags->hdrs.size && tags->hdrs.table)) { + *info = "failed verification tag.hdrs disagree"; + return false; + } + if ((tags->sets.size && !tags->sets.table) || + (!tags->sets.size && tags->sets.table)) { + *info = "failed verification tag.sets disagree"; + return false; + } + if ((tags->strs.size && !tags->strs.table) || + (!tags->strs.size && tags->strs.table)) { + *info = "failed verification tags->strs disagree"; + return false; + } + /* no data present */ + if (!tags->sets.size && !tags->hdrs.size && !tags->strs.size) { + return true; + } else if (!(tags->sets.size && tags->hdrs.size && tags->strs.size)) { + /* some data present but not all */ + *info = "failed verification tags partial data present"; + return false; + } + + u32 i; + + for (i = 0; i < tags->sets.size; i++) { + /* count followed by count indexes into hdrs */ + u32 cnt = tags->sets.table[i]; + + if (i+cnt >= tags->sets.size) { + AA_DEBUG(DEBUG_UNPACK, + "tagset too large %d+%d > sets.table[%d]", + i, cnt, tags->sets.size); + *info = "failed verification tagset too large"; + return false; + } + for (; cnt; cnt--) { + if (tags->sets.table[++i] >= tags->hdrs.size) { + AA_DEBUG(DEBUG_UNPACK, + "tagsets idx out of bounds cnt %d sets.table[%d] >= %d", + cnt, i-1, tags->hdrs.size); + *info = "failed verification tagsets idx out of bounds"; + return false; + } + } + } + for (i = 0; i < tags->hdrs.size; i++) { + u32 idx = tags->hdrs.table[i].tags; + + if (idx >= tags->strs.size) { + AA_DEBUG(DEBUG_UNPACK, + "tag.hdrs idx oob idx %d > tags->strs.size=%d", + idx, tags->strs.size); + *info = "failed verification tags.hdrs idx out of bounds"; + return false; + } + if (tags->hdrs.table[i].count != tags->strs.table[idx].count) { + AA_DEBUG(DEBUG_UNPACK, "hdrs.table[%d].count=%d != tags->strs.table[%d]=%d", + i, tags->hdrs.table[i].count, idx, tags->strs.table[idx].count); + *info = "failed verification tagd.hdrs[idx].count"; + return false; + } + if (tags->hdrs.table[i].size != tags->strs.table[idx].size) { + AA_DEBUG(DEBUG_UNPACK, "hdrs.table[%d].size=%d != strs.table[%d].size=%d", + i, tags->hdrs.table[i].size, idx, tags->strs.table[idx].size); + *info = "failed verification tagd.hdrs[idx].size"; + return false; + } + } + + return true; +} + +static int unpack_tagsets(struct aa_ext *e, struct aa_tags_struct *tags) +{ + u32 *sets; + u16 i, size; + int error = -EPROTO; + void *pos = e->pos; + + if (!aa_unpack_array(e, "sets", &size)) + goto fail_reset; + sets = kcalloc(size, sizeof(u32), GFP_KERNEL); + if (!sets) { + error = -ENOMEM; + goto fail_reset; + } + for (i = 0; i < size; i++) { + if (!aa_unpack_u32(e, &sets[i], NULL)) + goto fail; + } + if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + + tags->sets.size = size; + tags->sets.table = sets; + + return 0; + +fail: + kfree_sensitive(sets); +fail_reset: + e->pos = pos; + return error; +} + +static bool unpack_tag_header_ent(struct aa_ext *e, struct aa_tags_header *h) +{ + return aa_unpack_u32(e, &h->mask, NULL) && + aa_unpack_u32(e, &h->count, NULL) && + aa_unpack_u32(e, &h->size, NULL) && + aa_unpack_u32(e, &h->tags, NULL); +} + +static int unpack_tag_headers(struct aa_ext *e, struct aa_tags_struct *tags) +{ + struct aa_tags_header *hdrs; + u16 i, size; + int error = -EPROTO; + void *pos = e->pos; + + if (!aa_unpack_array(e, "hdrs", &size)) + goto fail_reset; + hdrs = kzalloc_objs(struct aa_tags_header, size); + if (!hdrs) { + error = -ENOMEM; + goto fail_reset; + } + for (i = 0; i < size; i++) { + if (!unpack_tag_header_ent(e, &hdrs[i])) + goto fail; + } + if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + + tags->hdrs.size = size; + tags->hdrs.table = hdrs; + AA_DEBUG(DEBUG_UNPACK, "headers %ld size %d", (long) hdrs, size); + return true; + +fail: + kfree_sensitive(hdrs); +fail_reset: + e->pos = pos; + return error; +} + + +static int unpack_tags(struct aa_ext *e, struct aa_tags_struct *tags, + const char **info) +{ + int error = -EPROTO; + void *pos = e->pos; + + AA_BUG(!tags); + /* policy tags are optional */ + if (aa_unpack_nameX(e, AA_STRUCT, "tags")) { + u32 version; + + if (!aa_unpack_u32(e, &version, "version") || version != 1) { + *info = "invalid tags version"; + goto fail_reset; + } + error = unpack_strs_table(e, "strs", true, &tags->strs); + if (error) { + *info = "failed to unpack profile tag.strs"; + goto fail; + } + error = unpack_tag_headers(e, tags); + if (error) { + *info = "failed to unpack profile tag.headers"; + goto fail; + } + error = unpack_tagsets(e, tags); + if (error) { + *info = "failed to unpack profile tag.sets"; + goto fail; + } + if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + + if (!verify_tags(tags, info)) + goto fail; + } + + return 0; + +fail: + aa_destroy_tags(tags); +fail_reset: + e->pos = pos; + return error; +} + static bool unpack_perm(struct aa_ext *e, u32 version, struct aa_perms *perm) { u32 reserved; @@ -686,9 +937,11 @@ static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms) goto fail_reset; if (!aa_unpack_array(e, NULL, &size)) goto fail_reset; - *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL); - if (!*perms) - goto fail_reset; + *perms = kzalloc_objs(struct aa_perms, size); + if (!*perms) { + e->pos = pos; + return -ENOMEM; + } for (i = 0; i < size; i++) { if (!unpack_perm(e, version, &(*perms)[i])) goto fail; @@ -723,6 +976,11 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy, if (!pdb) return -ENOMEM; + AA_DEBUG(DEBUG_UNPACK, "unpacking tags"); + if (unpack_tags(e, &pdb->tags, info) < 0) + goto fail; + AA_DEBUG(DEBUG_UNPACK, "done unpacking tags"); + size = unpack_perms_table(e, &pdb->perms); if (size < 0) { error = size; @@ -768,7 +1026,17 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy, if (!aa_unpack_u32(e, &pdb->start[AA_CLASS_FILE], "dfa_start")) { /* default start state for xmatch and file dfa */ pdb->start[AA_CLASS_FILE] = DFA_START; - } /* setup class index */ + } + + size_t state_count = pdb->dfa->tables[YYTD_ID_BASE]->td_lolen; + + if (pdb->start[0] >= state_count || + pdb->start[AA_CLASS_FILE] >= state_count) { + *info = "invalid dfa start state"; + goto fail; + } + + /* setup class index */ for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) { pdb->start[i] = aa_dfa_next(pdb->dfa, pdb->start[0], i); @@ -795,13 +1063,14 @@ static int unpack_pdb(struct aa_ext *e, struct aa_policydb **policy, * transition table may be present even when the dfa is * not. For compatibility reasons unpack and discard. */ - if (!unpack_trans_table(e, &pdb->trans) && required_trans) { + error = unpack_strs_table(e, "xtable", false, &pdb->trans); + if (error && required_trans) { *info = "failed to unpack profile transition table"; goto fail; } if (!pdb->dfa && pdb->trans.table) - aa_free_str_table(&pdb->trans); + aa_destroy_str_table(&pdb->trans); /* TODO: * - move compat mapping here, requires dfa merging first @@ -1058,6 +1327,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) goto fail; } else if (rules->file->dfa) { if (!rules->file->perms) { + AA_DEBUG(DEBUG_UNPACK, "compat mapping perms"); error = aa_compat_map_file(rules->file); if (error) { info = "failed to remap file permission table"; @@ -1075,7 +1345,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) error = -EPROTO; if (aa_unpack_nameX(e, AA_STRUCT, "data")) { info = "out of memory"; - profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); + profile->data = kzalloc_obj(*profile->data); if (!profile->data) { error = -ENOMEM; goto fail; @@ -1093,7 +1363,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) } while (aa_unpack_strdup(e, &key, NULL)) { - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { kfree_sensitive(key); error = -ENOMEM; @@ -1165,7 +1435,6 @@ static int verify_header(struct aa_ext *e, int required, const char **ns) { int error = -EPROTONOSUPPORT; const char *name = NULL; - *ns = NULL; /* get the interface version */ if (!aa_unpack_u32(e, &e->version, "version")) { @@ -1260,7 +1529,7 @@ static bool verify_perms(struct aa_policydb *pdb) if (xmax < xidx) xmax = xidx; } - if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->trans.size) + if (pdb->perms[i].tag && pdb->perms[i].tag >= pdb->tags.sets.size) return false; if (pdb->perms[i].label && pdb->perms[i].label >= pdb->trans.size) @@ -1268,7 +1537,7 @@ static bool verify_perms(struct aa_policydb *pdb) } /* deal with incorrectly constructed string tables */ if (xmax == -1) { - aa_free_str_table(&pdb->trans); + aa_destroy_str_table(&pdb->trans); } else if (pdb->trans.size > xmax + 1) { if (!aa_resize_str_table(&pdb->trans, xmax + 1, GFP_KERNEL)) return false; @@ -1338,7 +1607,7 @@ void aa_load_ent_free(struct aa_load_ent *ent) struct aa_load_ent *aa_load_ent_alloc(void) { - struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL); + struct aa_load_ent *ent = kzalloc_obj(*ent); if (ent) INIT_LIST_HEAD(&ent->list); return ent; diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c index 8e80db3ae21c..64212b39ba4b 100644 --- a/security/apparmor/resource.c +++ b/security/apparmor/resource.c @@ -196,6 +196,11 @@ void __aa_transition_rlimits(struct aa_label *old_l, struct aa_label *new_l) rules->rlimits.limits[j].rlim_max); /* soft limit should not exceed hard limit */ rlim->rlim_cur = min(rlim->rlim_cur, rlim->rlim_max); + if (j == RLIMIT_CPU && + rlim->rlim_cur != RLIM_INFINITY && + IS_ENABLED(CONFIG_POSIX_TIMERS)) + (void) update_rlimit_cpu(current->group_leader, + rlim->rlim_cur); } } } diff --git a/security/apparmor/task.c b/security/apparmor/task.c index c9bc9cc69475..0db0e81b4600 100644 --- a/security/apparmor/task.c +++ b/security/apparmor/task.c @@ -15,6 +15,7 @@ #include #include +#include "include/path.h" #include "include/audit.h" #include "include/cred.h" #include "include/policy.h" @@ -300,16 +301,47 @@ int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer, xrequest, &sa)); } +static const char *get_current_exe_path(char *buffer, int buffer_size) +{ + struct file *exe_file; + struct path p; + const char *path_str; + + exe_file = get_task_exe_file(current); + if (!exe_file) + return ERR_PTR(-ENOENT); + p = exe_file->f_path; + path_get(&p); + + if (aa_path_name(&p, FLAG_VIEW_SUBNS, buffer, &path_str, NULL, NULL)) + return ERR_PTR(-ENOMEM); + + fput(exe_file); + path_put(&p); + + return path_str; +} + /* call back to audit ptrace fields */ static void audit_ns_cb(struct audit_buffer *ab, void *va) { struct apparmor_audit_data *ad = aad_of_va(va); + char *buffer; + const char *path; if (ad->request & AA_USERNS_CREATE) audit_log_format(ab, " requested=\"userns_create\""); if (ad->denied & AA_USERNS_CREATE) audit_log_format(ab, " denied=\"userns_create\""); + + buffer = aa_get_buffer(false); + if (!buffer) + return; // OOM + path = get_current_exe_path(buffer, aa_g_path_max); + if (!IS_ERR(path)) + audit_log_format(ab, " execpath=\"%s\"", path); + aa_put_buffer(buffer); } int aa_profile_ns_perm(struct aa_profile *profile, diff --git a/security/commoncap.c b/security/commoncap.c index 8a23dfab7fac..3399535808fe 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1521,3 +1521,7 @@ DEFINE_LSM(capability) = { }; #endif /* CONFIG_SECURITY */ + +#ifdef CONFIG_SECURITY_COMMONCAP_KUNIT_TEST +#include "commoncap_test.c" +#endif diff --git a/security/commoncap_test.c b/security/commoncap_test.c new file mode 100644 index 000000000000..e9b278be37f1 --- /dev/null +++ b/security/commoncap_test.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * KUnit tests for commoncap.c security functions + * + * Tests for security-critical functions in the capability subsystem, + * particularly namespace-related capability checks. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SECURITY_COMMONCAP_KUNIT_TEST + +/* Functions are static in commoncap.c, but we can call them since we're + * included in the same compilation unit when tests are enabled. + */ + +/** + * test_vfsuid_root_in_currentns_init_ns - Test vfsuid_root_in_currentns with init ns + * + * Verifies that UID 0 in the init namespace correctly owns the current + * namespace when running in init_user_ns. + * + * @test: KUnit test context + */ +static void test_vfsuid_root_in_currentns_init_ns(struct kunit *test) +{ + vfsuid_t vfsuid; + kuid_t kuid; + + /* Create UID 0 in init namespace */ + kuid = KUIDT_INIT(0); + vfsuid = VFSUIDT_INIT(kuid); + + /* In init namespace, UID 0 should own current namespace */ + KUNIT_EXPECT_TRUE(test, vfsuid_root_in_currentns(vfsuid)); +} + +/** + * test_vfsuid_root_in_currentns_invalid - Test vfsuid_root_in_currentns with invalid vfsuid + * + * Verifies that an invalid vfsuid correctly returns false. + * + * @test: KUnit test context + */ +static void test_vfsuid_root_in_currentns_invalid(struct kunit *test) +{ + vfsuid_t invalid_vfsuid; + + /* Use the predefined invalid vfsuid */ + invalid_vfsuid = INVALID_VFSUID; + + /* Invalid vfsuid should return false */ + KUNIT_EXPECT_FALSE(test, vfsuid_root_in_currentns(invalid_vfsuid)); +} + +/** + * test_vfsuid_root_in_currentns_nonzero - Test vfsuid_root_in_currentns with non-zero UID + * + * Verifies that a non-zero UID correctly returns false. + * + * @test: KUnit test context + */ +static void test_vfsuid_root_in_currentns_nonzero(struct kunit *test) +{ + vfsuid_t vfsuid; + kuid_t kuid; + + /* Create a non-zero UID */ + kuid = KUIDT_INIT(1000); + vfsuid = VFSUIDT_INIT(kuid); + + /* Non-zero UID should return false */ + KUNIT_EXPECT_FALSE(test, vfsuid_root_in_currentns(vfsuid)); +} + +/** + * test_kuid_root_in_ns_init_ns_uid0 - Test kuid_root_in_ns with init namespace and UID 0 + * + * Verifies that kuid_root_in_ns correctly identifies UID 0 in init namespace. + * This tests the core namespace traversal logic. In init namespace, UID 0 + * maps to itself, so it should own the namespace. + * + * @test: KUnit test context + */ +static void test_kuid_root_in_ns_init_ns_uid0(struct kunit *test) +{ + kuid_t kuid; + struct user_namespace *init_ns; + + kuid = KUIDT_INIT(0); + init_ns = &init_user_ns; + + /* UID 0 should own init namespace */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(kuid, init_ns)); +} + +/** + * test_kuid_root_in_ns_init_ns_nonzero - Test kuid_root_in_ns with init namespace and non-zero UID + * + * Verifies that kuid_root_in_ns correctly rejects non-zero UIDs in init namespace. + * Only UID 0 should own a namespace. + * + * @test: KUnit test context + */ +static void test_kuid_root_in_ns_init_ns_nonzero(struct kunit *test) +{ + kuid_t kuid; + struct user_namespace *init_ns; + + kuid = KUIDT_INIT(1000); + init_ns = &init_user_ns; + + /* Non-zero UID should not own namespace */ + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(kuid, init_ns)); +} + +/** + * create_test_user_ns_with_mapping - Create a mock user namespace with UID mapping + * + * Creates a minimal user namespace structure for testing where uid 0 in the + * namespace maps to a specific kuid in the parent namespace. + * + * @test: KUnit test context + * @parent_ns: Parent namespace (typically init_user_ns) + * @mapped_kuid: The kuid that uid 0 in this namespace maps to in parent + * + * Returns: Pointer to allocated namespace, or NULL on failure + */ +static struct user_namespace *create_test_user_ns_with_mapping(struct kunit *test, + struct user_namespace *parent_ns, + kuid_t mapped_kuid) +{ + struct user_namespace *ns; + struct uid_gid_extent extent; + + /* Allocate a test namespace - use kzalloc to zero all fields */ + ns = kunit_kzalloc(test, sizeof(*ns), GFP_KERNEL); + if (!ns) + return NULL; + + /* Initialize basic namespace structure fields */ + ns->parent = parent_ns; + ns->level = parent_ns ? parent_ns->level + 1 : 0; + ns->owner = mapped_kuid; + ns->group = KGIDT_INIT(0); + + /* Initialize ns_common structure */ + refcount_set(&ns->ns.__ns_ref, 1); + ns->ns.inum = 0; /* Mock inum */ + + /* Set up uid mapping: uid 0 in this namespace maps to mapped_kuid in parent + * Format: first (uid in ns) : lower_first (kuid in parent) : count + * So: uid 0 in ns -> kuid mapped_kuid in parent + * This means from_kuid(ns, mapped_kuid) returns 0 + */ + extent.first = 0; /* uid 0 in this namespace */ + extent.lower_first = __kuid_val(mapped_kuid); /* maps to this kuid in parent */ + extent.count = 1; + + ns->uid_map.extent[0] = extent; + ns->uid_map.nr_extents = 1; + + /* Set up gid mapping: gid 0 maps to gid 0 in parent (simplified) */ + extent.first = 0; + extent.lower_first = 0; + extent.count = 1; + + ns->gid_map.extent[0] = extent; + ns->gid_map.nr_extents = 1; + + return ns; +} + +/** + * test_kuid_root_in_ns_with_mapping - Test kuid_root_in_ns with namespace where uid 0 + * maps to different kuid + * + * Creates a user namespace where uid 0 maps to kuid 1000 in the parent namespace. + * Verifies that kuid_root_in_ns correctly identifies kuid 1000 as owning the namespace. + * + * Note: kuid_root_in_ns walks up the namespace hierarchy, so it checks the current + * namespace first, then parent, then parent's parent, etc. So: + * - kuid 1000 owns test_ns because from_kuid(test_ns, 1000) == 0 + * - kuid 0 also owns test_ns because from_kuid(init_user_ns, 0) == 0 + * (checked in parent) + * + * This tests the actual functionality as requested: creating namespaces with + * different values for the namespace's uid 0. + * + * @test: KUnit test context + */ +static void test_kuid_root_in_ns_with_mapping(struct kunit *test) +{ + struct user_namespace *test_ns; + struct user_namespace *parent_ns; + kuid_t mapped_kuid, other_kuid; + + parent_ns = &init_user_ns; + mapped_kuid = KUIDT_INIT(1000); + other_kuid = KUIDT_INIT(2000); + + test_ns = create_test_user_ns_with_mapping(test, parent_ns, mapped_kuid); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, test_ns); + + /* kuid 1000 should own test_ns because it maps to uid 0 in test_ns */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(mapped_kuid, test_ns)); + + /* kuid 0 should also own test_ns (checked via parent init_user_ns) */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(0), test_ns)); + + /* Other kuids should not own test_ns */ + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(other_kuid, test_ns)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(500), test_ns)); +} + +/** + * test_kuid_root_in_ns_with_different_mappings - Test with multiple namespaces + * + * Creates multiple user namespaces with different UID mappings to verify + * that kuid_root_in_ns correctly distinguishes between namespaces. + * + * Each namespace maps uid 0 to a different kuid, and we verify that each + * kuid only owns its corresponding namespace (plus kuid 0 owns all via + * init_user_ns parent). + * + * @test: KUnit test context + */ +static void test_kuid_root_in_ns_with_different_mappings(struct kunit *test) +{ + struct user_namespace *ns1, *ns2, *ns3; + + /* Create three independent namespaces, each mapping uid 0 to different kuids */ + ns1 = create_test_user_ns_with_mapping(test, &init_user_ns, KUIDT_INIT(1000)); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ns1); + + ns2 = create_test_user_ns_with_mapping(test, &init_user_ns, KUIDT_INIT(2000)); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ns2); + + ns3 = create_test_user_ns_with_mapping(test, &init_user_ns, KUIDT_INIT(3000)); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ns3); + + /* Test ns1: kuid 1000 owns it, kuid 0 owns it (via parent), others do not */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(1000), ns1)); + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(0), ns1)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(2000), ns1)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(3000), ns1)); + + /* Test ns2: kuid 2000 owns it, kuid 0 owns it (via parent), others do not */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(2000), ns2)); + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(0), ns2)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(1000), ns2)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(3000), ns2)); + + /* Test ns3: kuid 3000 owns it, kuid 0 owns it (via parent), others do not */ + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(3000), ns3)); + KUNIT_EXPECT_TRUE(test, kuid_root_in_ns(KUIDT_INIT(0), ns3)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(1000), ns3)); + KUNIT_EXPECT_FALSE(test, kuid_root_in_ns(KUIDT_INIT(2000), ns3)); +} + +static struct kunit_case commoncap_test_cases[] = { + KUNIT_CASE(test_vfsuid_root_in_currentns_init_ns), + KUNIT_CASE(test_vfsuid_root_in_currentns_invalid), + KUNIT_CASE(test_vfsuid_root_in_currentns_nonzero), + KUNIT_CASE(test_kuid_root_in_ns_init_ns_uid0), + KUNIT_CASE(test_kuid_root_in_ns_init_ns_nonzero), + KUNIT_CASE(test_kuid_root_in_ns_with_mapping), + KUNIT_CASE(test_kuid_root_in_ns_with_different_mappings), + {} +}; + +static struct kunit_suite commoncap_test_suite = { + .name = "commoncap", + .test_cases = commoncap_test_cases, +}; + +kunit_test_suite(commoncap_test_suite); + +MODULE_LICENSE("GPL"); + +#endif /* CONFIG_SECURITY_COMMONCAP_KUNIT_TEST */ diff --git a/security/device_cgroup.c b/security/device_cgroup.c index 7fec575d32d6..cd166dee66b7 100644 --- a/security/device_cgroup.c +++ b/security/device_cgroup.c @@ -223,7 +223,7 @@ devcgroup_css_alloc(struct cgroup_subsys_state *parent_css) { struct dev_cgroup *dev_cgroup; - dev_cgroup = kzalloc(sizeof(*dev_cgroup), GFP_KERNEL); + dev_cgroup = kzalloc_obj(*dev_cgroup); if (!dev_cgroup) return ERR_PTR(-ENOMEM); INIT_LIST_HEAD(&dev_cgroup->exceptions); diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c index 45c3e5dda355..75c684cce370 100644 --- a/security/integrity/digsig.c +++ b/security/integrity/digsig.c @@ -141,7 +141,7 @@ int __init integrity_init_keyring(const unsigned int id) if (!IS_ENABLED(CONFIG_INTEGRITY_TRUSTED_KEYRING)) return 0; - restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + restriction = kzalloc_obj(struct key_restriction); if (!restriction) return -ENOMEM; diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 73d500a375cb..41b053c900f2 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c @@ -1045,7 +1045,7 @@ int evm_inode_init_security(struct inode *inode, struct inode *dir, "%s: xattrs terminator is not the first non-filled slot\n", __func__); - xattr_data = kzalloc(sizeof(*xattr_data), GFP_NOFS); + xattr_data = kzalloc_obj(*xattr_data, GFP_NOFS); if (!xattr_data) return -ENOMEM; diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c index c26724690cec..acd840461902 100644 --- a/security/integrity/evm/evm_secfs.c +++ b/security/integrity/evm/evm_secfs.c @@ -199,7 +199,7 @@ static ssize_t evm_write_xattrs(struct file *file, const char __user *buf, if (!ab && IS_ENABLED(CONFIG_AUDIT)) return -ENOMEM; - xattr = kmalloc(sizeof(struct xattr_list), GFP_KERNEL); + xattr = kmalloc_obj(struct xattr_list); if (!xattr) { err = -ENOMEM; goto out; diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index c6d1c7be8a3e..d15becc8c640 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -48,13 +48,14 @@ int ima_alloc_init_template(struct ima_event_data *event_data, else template_desc = ima_template_desc_current(); - *entry = kzalloc(struct_size(*entry, template_data, - template_desc->num_fields), GFP_NOFS); + *entry = kzalloc_flex(**entry, template_data, template_desc->num_fields, + GFP_NOFS); if (!*entry) return -ENOMEM; - digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, - sizeof(*digests), GFP_NOFS); + digests = kzalloc_objs(*digests, + NR_BANKS(ima_tpm_chip) + ima_extra_slots, + GFP_NOFS); if (!digests) { kfree(*entry); *entry = NULL; diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 6f5696d999d0..aff61643415d 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c @@ -138,8 +138,8 @@ int __init ima_init_crypto(void) if (ima_hash_algo_idx < 0) ima_hash_algo_idx = NR_BANKS(ima_tpm_chip) + ima_extra_slots++; - ima_algo_array = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, - sizeof(*ima_algo_array), GFP_KERNEL); + ima_algo_array = kzalloc_objs(*ima_algo_array, + NR_BANKS(ima_tpm_chip) + ima_extra_slots); if (!ima_algo_array) { rc = -ENOMEM; goto out; diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/ima_modsig.c index 3265d744d5ce..9aa92fd35a03 100644 --- a/security/integrity/ima/ima_modsig.c +++ b/security/integrity/ima/ima_modsig.c @@ -65,7 +65,7 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, buf_len -= sig_len + sizeof(*sig); /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */ - hdr = kzalloc(struct_size(hdr, raw_pkcs7, sig_len), GFP_KERNEL); + hdr = kzalloc_flex(*hdr, raw_pkcs7, sig_len); if (!hdr) return -ENOMEM; diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c index 95cc31525c57..14d93d573a6a 100644 --- a/security/integrity/ima/ima_mok.c +++ b/security/integrity/ima/ima_mok.c @@ -27,7 +27,7 @@ static __init int ima_mok_init(void) pr_notice("Allocating IMA blacklist keyring.\n"); - restriction = kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + restriction = kzalloc_obj(struct key_restriction); if (!restriction) panic("Can't allocate IMA blacklist restriction."); diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 8fbd8755f5bc..bf2d7ba4c14a 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -342,7 +342,7 @@ static struct ima_rule_opt_list *ima_alloc_rule_opt_list(const substring_t *src) return ERR_PTR(-EINVAL); } - opt_list = kzalloc(struct_size(opt_list, items, count), GFP_KERNEL); + opt_list = kzalloc_flex(*opt_list, items, count); if (!opt_list) { kfree(src_copy); return ERR_PTR(-ENOMEM); @@ -921,8 +921,7 @@ static int __init ima_init_arch_policy(void) for (rules = arch_rules; *rules != NULL; rules++) arch_entries++; - arch_policy_entry = kcalloc(arch_entries + 1, - sizeof(*arch_policy_entry), GFP_KERNEL); + arch_policy_entry = kzalloc_objs(*arch_policy_entry, arch_entries + 1); if (!arch_policy_entry) return 0; @@ -1976,7 +1975,7 @@ ssize_t ima_parse_add_rule(char *rule) if (*p == '#' || *p == '\0') return len; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, op, "-ENOMEM", -ENOMEM, audit_info); diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 590637e81ad1..319522450854 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -103,7 +103,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry, struct ima_queue_entry *qe; unsigned int key; - qe = kmalloc(sizeof(*qe), GFP_KERNEL); + qe = kmalloc_obj(*qe); if (qe == NULL) { pr_err("OUT OF MEMORY ERROR creating queue entry\n"); return -ENOMEM; @@ -269,8 +269,8 @@ int __init ima_init_digests(void) if (!ima_tpm_chip) return 0; - digests = kcalloc(ima_tpm_chip->nr_allocated_banks, sizeof(*digests), - GFP_NOFS); + digests = kzalloc_objs(*digests, ima_tpm_chip->nr_allocated_banks, + GFP_NOFS); if (!digests) return -ENOMEM; diff --git a/security/integrity/ima/ima_queue_keys.c b/security/integrity/ima/ima_queue_keys.c index 4f0aea155bf9..b5ed33cbb272 100644 --- a/security/integrity/ima/ima_queue_keys.c +++ b/security/integrity/ima/ima_queue_keys.c @@ -72,7 +72,7 @@ static struct ima_key_entry *ima_alloc_key_entry(struct key *keyring, const char *audit_cause = "ENOMEM"; struct ima_key_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (entry) { entry->payload = kmemdup(payload, payload_len, GFP_KERNEL); entry->keyring_name = kstrdup(keyring->description, diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 04c49f05cb74..7034573fb41e 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c @@ -245,7 +245,7 @@ int template_desc_init_fields(const char *template_fmt, } if (fields && num_fields) { - *fields = kmalloc_array(i, sizeof(**fields), GFP_KERNEL); + *fields = kmalloc_objs(**fields, i); if (*fields == NULL) return -ENOMEM; @@ -334,7 +334,7 @@ static struct ima_template_desc *restore_template_fmt(char *template_name) goto out; } - template_desc = kzalloc(sizeof(*template_desc), GFP_KERNEL); + template_desc = kzalloc_obj(*template_desc); if (!template_desc) goto out; @@ -362,13 +362,14 @@ static int ima_restore_template_data(struct ima_template_desc *template_desc, int ret = 0; int i; - *entry = kzalloc(struct_size(*entry, template_data, - template_desc->num_fields), GFP_NOFS); + *entry = kzalloc_flex(**entry, template_data, template_desc->num_fields, + GFP_NOFS); if (!*entry) return -ENOMEM; - digests = kcalloc(NR_BANKS(ima_tpm_chip) + ima_extra_slots, - sizeof(*digests), GFP_NOFS); + digests = kzalloc_objs(*digests, + NR_BANKS(ima_tpm_chip) + ima_extra_slots, + GFP_NOFS); if (!digests) { kfree(*entry); return -ENOMEM; diff --git a/security/ipe/digest.c b/security/ipe/digest.c index 5006366837ba..6e597a6b7633 100644 --- a/security/ipe/digest.c +++ b/security/ipe/digest.c @@ -29,7 +29,7 @@ struct digest_info *ipe_digest_parse(const char *valstr) char *alg = NULL; int rc = 0; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); diff --git a/security/ipe/hooks.c b/security/ipe/hooks.c index 603abdc9ce3b..0ae54a880405 100644 --- a/security/ipe/hooks.c +++ b/security/ipe/hooks.c @@ -287,7 +287,7 @@ int ipe_bdev_setintegrity(struct block_device *bdev, enum lsm_integrity_type typ } digest = value; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; diff --git a/security/ipe/policy.c b/security/ipe/policy.c index 1c58c29886e8..827867be4fac 100644 --- a/security/ipe/policy.c +++ b/security/ipe/policy.c @@ -162,7 +162,7 @@ struct ipe_policy *ipe_new_policy(const char *text, size_t textlen, struct ipe_policy *new = NULL; int rc = 0; - new = kzalloc(sizeof(*new), GFP_KERNEL); + new = kzalloc_obj(*new); if (!new) return ERR_PTR(-ENOMEM); diff --git a/security/ipe/policy_parser.c b/security/ipe/policy_parser.c index 7f27e39931d6..6fa5bebf8471 100644 --- a/security/ipe/policy_parser.c +++ b/security/ipe/policy_parser.c @@ -30,7 +30,7 @@ static struct ipe_parsed_policy *new_parsed_policy(void) struct ipe_op_table *t = NULL; size_t i = 0; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return ERR_PTR(-ENOMEM); @@ -305,7 +305,7 @@ static int parse_property(char *t, struct ipe_rule *r) int token; char *dup = NULL; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return -ENOMEM; @@ -373,7 +373,7 @@ static int parse_rule(char *line, struct ipe_parsed_policy *p) if (IS_ERR_OR_NULL(line)) return -EBADMSG; - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) return -ENOMEM; diff --git a/security/keys/big_key.c b/security/keys/big_key.c index d46862ab90d6..268f702df380 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -103,7 +103,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) 0, enckey); /* save aligned data to file */ - file = shmem_kernel_file_setup("", enclen, 0); + file = shmem_kernel_file_setup("", enclen, EMPTY_VMA_FLAGS); if (IS_ERR(file)) { ret = PTR_ERR(file); goto err_enckey; diff --git a/security/keys/key.c b/security/keys/key.c index 3bbdde778631..091ee084bc30 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -77,7 +77,7 @@ struct key_user *key_user_lookup(kuid_t uid) spin_unlock(&key_user_lock); user = NULL; - candidate = kmalloc(sizeof(struct key_user), GFP_KERNEL); + candidate = kmalloc_obj(struct key_user); if (unlikely(!candidate)) goto out; diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index ab927a142f51..ef855d69c97a 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1796,13 +1796,13 @@ long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id) if (watch_id >= 0) { ret = -ENOMEM; if (!key->watchers) { - wlist = kzalloc(sizeof(*wlist), GFP_KERNEL); + wlist = kzalloc_obj(*wlist); if (!wlist) goto err_wqueue; init_watch_list(wlist, NULL); } - watch = kzalloc(sizeof(*watch), GFP_KERNEL); + watch = kzalloc_obj(*watch); if (!watch) goto err_wlist; diff --git a/security/keys/keyring.c b/security/keys/keyring.c index f331725d5a37..b39038f7dd31 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -977,7 +977,7 @@ static struct key_restriction *keyring_restriction_alloc( key_restrict_link_func_t check) { struct key_restriction *keyres = - kzalloc(sizeof(struct key_restriction), GFP_KERNEL); + kzalloc_obj(struct key_restriction); if (!keyres) return ERR_PTR(-ENOMEM); diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c index 8f33cd170e42..a7d7538c1f70 100644 --- a/security/keys/request_key_auth.c +++ b/security/keys/request_key_auth.c @@ -171,7 +171,7 @@ struct key *request_key_auth_new(struct key *target, const char *op, kenter("%d,", target->serial); /* allocate a auth record */ - rka = kzalloc(sizeof(*rka), GFP_KERNEL); + rka = kzalloc_obj(*rka); if (!rka) goto error; rka->callout_info = kmemdup(callout_info, callout_len, GFP_KERNEL); diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c index 9046123d94de..0b142d941cd2 100644 --- a/security/keys/trusted-keys/trusted_core.c +++ b/security/keys/trusted-keys/trusted_core.c @@ -134,7 +134,7 @@ static struct trusted_key_payload *trusted_payload_alloc(struct key *key) ret = key_payload_reserve(key, sizeof(*p)); if (ret < 0) goto err; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) goto err; diff --git a/security/keys/trusted-keys/trusted_pkwm.c b/security/keys/trusted-keys/trusted_pkwm.c index 4f391b77a907..bf42c6679245 100644 --- a/security/keys/trusted-keys/trusted_pkwm.c +++ b/security/keys/trusted-keys/trusted_pkwm.c @@ -62,10 +62,10 @@ static struct trusted_key_options *trusted_options_alloc(void) struct trusted_key_options *options; struct trusted_pkwm_options *pkwm; - options = kzalloc(sizeof(*options), GFP_KERNEL); + options = kzalloc_obj(*options); if (options) { - pkwm = kzalloc(sizeof(*pkwm), GFP_KERNEL); + pkwm = kzalloc_obj(*pkwm); if (!pkwm) { kfree_sensitive(options); diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c index c865c97aa1b4..6ea728f1eae6 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c @@ -440,7 +440,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, int i; /* alloc some work space for all the hashes */ - td = kmalloc(sizeof *td, GFP_KERNEL); + td = kmalloc_obj(*td); if (!td) return -ENOMEM; @@ -838,7 +838,7 @@ static struct trusted_key_options *trusted_options_alloc(void) if (tpm2 < 0) return NULL; - options = kzalloc(sizeof *options, GFP_KERNEL); + options = kzalloc_obj(*options); if (options) { /* set any non-zero defaults */ options->keytype = SRK_keytype; @@ -946,8 +946,7 @@ static int __init init_digests(void) { int i; - digests = kcalloc(chip->nr_allocated_banks, sizeof(*digests), - GFP_KERNEL); + digests = kzalloc_objs(*digests, chip->nr_allocated_banks); if (!digests) return -ENOMEM; diff --git a/security/landlock/domain.c b/security/landlock/domain.c index 79cb3bbdf4c5..f5b78d4766cd 100644 --- a/security/landlock/domain.c +++ b/security/landlock/domain.c @@ -95,7 +95,7 @@ static struct landlock_details *get_current_details(void) * caller. */ details = - kzalloc(struct_size(details, exe_path, path_size), GFP_KERNEL); + kzalloc_flex(*details, exe_path, path_size); if (!details) return ERR_PTR(-ENOMEM); diff --git a/security/landlock/object.c b/security/landlock/object.c index 1f50612f0185..0d6e159ef8b5 100644 --- a/security/landlock/object.c +++ b/security/landlock/object.c @@ -25,7 +25,7 @@ landlock_create_object(const struct landlock_object_underops *const underops, if (WARN_ON_ONCE(!underops || !underobj)) return ERR_PTR(-ENOENT); - new_object = kzalloc(sizeof(*new_object), GFP_KERNEL_ACCOUNT); + new_object = kzalloc_obj(*new_object, GFP_KERNEL_ACCOUNT); if (!new_object) return ERR_PTR(-ENOMEM); refcount_set(&new_object->usage, 1); diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c index 419b237de635..319873586385 100644 --- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c @@ -33,8 +33,8 @@ static struct landlock_ruleset *create_ruleset(const u32 num_layers) struct landlock_ruleset *new_ruleset; new_ruleset = - kzalloc(struct_size(new_ruleset, access_masks, num_layers), - GFP_KERNEL_ACCOUNT); + kzalloc_flex(*new_ruleset, access_masks, num_layers, + GFP_KERNEL_ACCOUNT); if (!new_ruleset) return ERR_PTR(-ENOMEM); refcount_set(&new_ruleset->usage, 1); @@ -123,8 +123,8 @@ create_rule(const struct landlock_id id, } else { new_num_layers = num_layers; } - new_rule = kzalloc(struct_size(new_rule, layers, new_num_layers), - GFP_KERNEL_ACCOUNT); + new_rule = kzalloc_flex(*new_rule, layers, new_num_layers, + GFP_KERNEL_ACCOUNT); if (!new_rule) return ERR_PTR(-ENOMEM); RB_CLEAR_NODE(&new_rule->node); @@ -559,8 +559,8 @@ landlock_merge_ruleset(struct landlock_ruleset *const parent, if (IS_ERR(new_dom)) return new_dom; - new_dom->hierarchy = - kzalloc(sizeof(*new_dom->hierarchy), GFP_KERNEL_ACCOUNT); + new_dom->hierarchy = kzalloc_obj(*new_dom->hierarchy, + GFP_KERNEL_ACCOUNT); if (!new_dom->hierarchy) return ERR_PTR(-ENOMEM); diff --git a/security/landlock/tsync.c b/security/landlock/tsync.c index 0d2b9c646030..de01aa899751 100644 --- a/security/landlock/tsync.c +++ b/security/landlock/tsync.c @@ -237,7 +237,7 @@ static int tsync_works_grow_by(struct tsync_works *s, size_t n, gfp_t flags) s->works = works; for (i = s->capacity; i < new_capacity; i++) { - work = kzalloc(sizeof(*work), flags); + work = kzalloc_obj(*work, flags); if (!work) { /* * Leave the object in a consistent state, diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index 019840006096..f71861f98e1a 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -53,32 +53,29 @@ static DEFINE_SPINLOCK(pinned_root_spinlock); static bool deny_reading_verity_digests; #endif +// initialized to false +static bool loadpin_root_writable; #ifdef CONFIG_SYSCTL -static struct ctl_table loadpin_sysctl_table[] = { + +static int proc_handler_loadpin(const struct ctl_table *table, int dir, + void *buffer, size_t *lenp, loff_t *ppos) +{ + if (!loadpin_root_writable && SYSCTL_USER_TO_KERN(dir)) + return -EINVAL; + return proc_dointvec_minmax(table, dir, buffer, lenp, ppos); +} + +static const struct ctl_table loadpin_sysctl_table[] = { { .procname = "enforce", .data = &enforce, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax, - .extra1 = SYSCTL_ONE, + .proc_handler = proc_handler_loadpin, + .extra1 = SYSCTL_ZERO, .extra2 = SYSCTL_ONE, }, }; - -static void set_sysctl(bool is_writable) -{ - /* - * If load pinning is not enforced via a read-only block - * device, allow sysctl to change modes for testing. - */ - if (is_writable) - loadpin_sysctl_table[0].extra1 = SYSCTL_ZERO; - else - loadpin_sysctl_table[0].extra1 = SYSCTL_ONE; -} -#else -static inline void set_sysctl(bool is_writable) { } #endif static void report_writable(struct super_block *mnt_sb, bool writable) @@ -132,7 +129,6 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id) struct super_block *load_root; const char *origin = kernel_read_file_id_str(id); bool first_root_pin = false; - bool load_root_writable; /* If the file id is excluded, ignore the pinning. */ if ((unsigned int)id < ARRAY_SIZE(ignore_read_file_id) && @@ -153,7 +149,6 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id) } load_root = file->f_path.mnt->mnt_sb; - load_root_writable = sb_is_writable(load_root); /* First loaded module/firmware defines the root for all others. */ spin_lock(&pinned_root_spinlock); @@ -169,8 +164,8 @@ static int loadpin_check(struct file *file, enum kernel_read_file_id id) spin_unlock(&pinned_root_spinlock); if (first_root_pin) { - report_writable(pinned_root, load_root_writable); - set_sysctl(load_root_writable); + loadpin_root_writable = sb_is_writable(pinned_root); + report_writable(pinned_root, loadpin_root_writable); report_load(origin, file, "pinned"); } @@ -332,7 +327,7 @@ static int read_trusted_verity_root_digests(unsigned int fd) len /= 2; - trd = kzalloc(struct_size(trd, data, len), GFP_KERNEL); + trd = kzalloc_flex(*trd, data, len); if (!trd) { rc = -ENOMEM; goto err; diff --git a/security/safesetid/securityfs.c b/security/safesetid/securityfs.c index ece259f75b0d..a71e548065a9 100644 --- a/security/safesetid/securityfs.c +++ b/security/safesetid/securityfs.c @@ -118,7 +118,7 @@ static int verify_ruleset(struct setid_ruleset *pol) res = -EINVAL; /* fix it up */ - nrule = kmalloc(sizeof(struct setid_rule), GFP_KERNEL); + nrule = kmalloc_obj(struct setid_rule); if (!nrule) return -ENOMEM; if (pol->type == UID){ @@ -146,7 +146,7 @@ static ssize_t handle_policy_update(struct file *file, if (len >= KMALLOC_MAX_SIZE) return -EINVAL; - pol = kmalloc(sizeof(struct setid_ruleset), GFP_KERNEL); + pol = kmalloc_obj(struct setid_ruleset); if (!pol) return -ENOMEM; pol->policy_str = NULL; @@ -175,7 +175,7 @@ static ssize_t handle_policy_update(struct file *file, } *end = '\0'; - rule = kmalloc(sizeof(struct setid_rule), GFP_KERNEL); + rule = kmalloc_obj(struct setid_rule); if (!rule) { err = -ENOMEM; goto out_free_buf; diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 8f77b9a732e1..813e82bcfc27 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -794,7 +794,7 @@ int __init avc_add_callback(int (*callback)(u32 event), u32 events) struct avc_callback_node *c; int rc = 0; - c = kmalloc(sizeof(*c), GFP_KERNEL); + c = kmalloc_obj(*c); if (!c) { rc = -ENOMEM; goto out; diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index feda34b18d83..d8224ea113d1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -1030,7 +1030,7 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) } if (!opts) { - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; *mnt_opts = opts; @@ -2822,7 +2822,7 @@ static int selinux_fs_context_submount(struct fs_context *fc, if (!(sbsec->flags & (FSCONTEXT_MNT|CONTEXT_MNT|DEFCONTEXT_MNT))) return 0; - opts = kzalloc(sizeof(*opts), GFP_KERNEL); + opts = kzalloc_obj(*opts); if (!opts) return -ENOMEM; diff --git a/security/selinux/ibpkey.c b/security/selinux/ibpkey.c index ea1d9b2c7d2b..93a5637fbcd8 100644 --- a/security/selinux/ibpkey.c +++ b/security/selinux/ibpkey.c @@ -147,7 +147,7 @@ static int sel_ib_pkey_sid_slow(u64 subnet_prefix, u16 pkey_num, u32 *sid) if (ret) goto out; - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (!new) { /* If this memory allocation fails still return 0. The SID * is valid, it just won't be added to the cache. diff --git a/security/selinux/netif.c b/security/selinux/netif.c index e24b2cba28ea..fa6d24a37c39 100644 --- a/security/selinux/netif.c +++ b/security/selinux/netif.c @@ -161,7 +161,7 @@ static int sel_netif_sid_slow(struct net *ns, int ifindex, u32 *sid) /* If this memory allocation fails still return 0. The SID * is valid, it just won't be added to the cache. */ - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (new) { new->nsec.ns = ns; new->nsec.ifindex = ifindex; diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 9b3da5ce8d39..adb93003b8c4 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -205,7 +205,7 @@ static int sel_netnode_sid_slow(const void *addr, u16 family, u32 *sid) /* If this memory allocation fails still return 0. The SID * is valid, it just won't be added to the cache. */ - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); switch (family) { case PF_INET: ret = security_node_sid(PF_INET, diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 9e62f7285e81..006a6ec71319 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -150,7 +150,7 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) /* If this memory allocation fails still return 0. The SID * is valid, it just won't be added to the cache. */ - new = kmalloc(sizeof(*new), GFP_ATOMIC); + new = kmalloc_obj(*new, GFP_ATOMIC); if (new) { new->psec.port = pnum; new->psec.protocol = protocol; diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 4d58c7ad1a23..3245cc531555 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -85,7 +85,7 @@ static int selinux_fs_info_create(struct super_block *sb) { struct selinux_fs_info *fsi; - fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); + fsi = kzalloc_obj(*fsi); if (!fsi) return -ENOMEM; @@ -380,7 +380,7 @@ static int sel_open_policy(struct inode *inode, struct file *filp) goto err; rc = -ENOMEM; - plm = kzalloc(sizeof(*plm), GFP_KERNEL); + plm = kzalloc_obj(*plm); if (!plm) goto err; diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index 1bebfcb9c6a1..824c3f896151 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c @@ -165,8 +165,8 @@ void cond_policydb_destroy(struct policydb *p) int cond_init_bool_indexes(struct policydb *p) { kfree(p->bool_val_to_struct); - p->bool_val_to_struct = kmalloc_array( - p->p_bools.nprim, sizeof(*p->bool_val_to_struct), GFP_KERNEL); + p->bool_val_to_struct = kmalloc_objs(*p->bool_val_to_struct, + p->p_bools.nprim); if (!p->bool_val_to_struct) return -ENOMEM; @@ -214,7 +214,7 @@ int cond_read_bool(struct policydb *p, struct symtab *s, struct policy_file *fp) u32 len; int rc; - booldatum = kzalloc(sizeof(*booldatum), GFP_KERNEL); + booldatum = kzalloc_obj(*booldatum); if (!booldatum) return -ENOMEM; @@ -334,7 +334,7 @@ static int cond_read_av_list(struct policydb *p, struct policy_file *fp, if (len == 0) return 0; - list->nodes = kcalloc(len, sizeof(*list->nodes), GFP_KERNEL); + list->nodes = kzalloc_objs(*list->nodes, len); if (!list->nodes) return -ENOMEM; @@ -383,7 +383,7 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, struct pol /* expr */ len = le32_to_cpu(buf[1]); - node->expr.nodes = kcalloc(len, sizeof(*node->expr.nodes), GFP_KERNEL); + node->expr.nodes = kzalloc_objs(*node->expr.nodes, len); if (!node->expr.nodes) return -ENOMEM; @@ -421,7 +421,7 @@ int cond_read_list(struct policydb *p, struct policy_file *fp) len = le32_to_cpu(buf[0]); - p->cond_list = kcalloc(len, sizeof(*p->cond_list), GFP_KERNEL); + p->cond_list = kzalloc_objs(*p->cond_list, len); if (!p->cond_list) return -ENOMEM; @@ -605,7 +605,7 @@ static int cond_dup_av_list(struct cond_av_list *new, memset(new, 0, sizeof(*new)); - new->nodes = kcalloc(orig->len, sizeof(*new->nodes), GFP_KERNEL); + new->nodes = kzalloc_objs(*new->nodes, orig->len); if (!new->nodes) return -ENOMEM; @@ -631,8 +631,7 @@ static int duplicate_policydb_cond_list(struct policydb *newp, return rc; newp->cond_list_len = 0; - newp->cond_list = kcalloc(origp->cond_list_len, - sizeof(*newp->cond_list), GFP_KERNEL); + newp->cond_list = kzalloc_objs(*newp->cond_list, origp->cond_list_len); if (!newp->cond_list) goto error; @@ -710,9 +709,8 @@ static int duplicate_policydb_bools(struct policydb *newdb, struct cond_bool_datum **cond_bool_array; int rc; - cond_bool_array = kmalloc_array(orig->p_bools.nprim, - sizeof(*orig->bool_val_to_struct), - GFP_KERNEL); + cond_bool_array = kmalloc_objs(*orig->bool_val_to_struct, + orig->p_bools.nprim); if (!cond_bool_array) return -ENOMEM; diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index 1382eb3bfde1..9ffc8a371e23 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -40,8 +40,8 @@ int hashtab_init(struct hashtab *h, u32 nel_hint) h->htable = NULL; if (size) { - h->htable = kcalloc(size, sizeof(*h->htable), - GFP_KERNEL | __GFP_NOWARN); + h->htable = kzalloc_objs(*h->htable, size, + GFP_KERNEL | __GFP_NOWARN); if (!h->htable) return -ENOMEM; h->size = size; @@ -149,7 +149,7 @@ int hashtab_duplicate(struct hashtab *new, const struct hashtab *orig, memset(new, 0, sizeof(*new)); - new->htable = kcalloc(orig->size, sizeof(*new->htable), GFP_KERNEL); + new->htable = kzalloc_objs(*new->htable, orig->size); if (!new->htable) return -ENOMEM; diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 91df3db6a88c..738fd47f33e6 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -390,7 +390,7 @@ static int roles_init(struct policydb *p) int rc; struct role_datum *role; - role = kzalloc(sizeof(*role), GFP_KERNEL); + role = kzalloc_obj(*role); if (!role) return -ENOMEM; @@ -738,24 +738,23 @@ static int policydb_index(struct policydb *p) avtab_hash_eval(&p->te_avtab, "rules"); symtab_hash_eval(p->symtab); - p->class_val_to_struct = kcalloc(p->p_classes.nprim, - sizeof(*p->class_val_to_struct), - GFP_KERNEL); + p->class_val_to_struct = kzalloc_objs(*p->class_val_to_struct, + p->p_classes.nprim); if (!p->class_val_to_struct) return -ENOMEM; - p->role_val_to_struct = kcalloc( - p->p_roles.nprim, sizeof(*p->role_val_to_struct), GFP_KERNEL); + p->role_val_to_struct = kzalloc_objs(*p->role_val_to_struct, + p->p_roles.nprim); if (!p->role_val_to_struct) return -ENOMEM; - p->user_val_to_struct = kcalloc( - p->p_users.nprim, sizeof(*p->user_val_to_struct), GFP_KERNEL); + p->user_val_to_struct = kzalloc_objs(*p->user_val_to_struct, + p->p_users.nprim); if (!p->user_val_to_struct) return -ENOMEM; - p->type_val_to_struct = kvcalloc( - p->p_types.nprim, sizeof(*p->type_val_to_struct), GFP_KERNEL); + p->type_val_to_struct = kvzalloc_objs(*p->type_val_to_struct, + p->p_types.nprim); if (!p->type_val_to_struct) return -ENOMEM; @@ -1131,7 +1130,7 @@ static int perm_read(struct policydb *p, struct symtab *s, struct policy_file *f __le32 buf[2]; u32 len; - perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); + perdatum = kzalloc_obj(*perdatum); if (!perdatum) return -ENOMEM; @@ -1164,7 +1163,7 @@ static int common_read(struct policydb *p, struct symtab *s, struct policy_file u32 i, len, nel; int rc; - comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); + comdatum = kzalloc_obj(*comdatum); if (!comdatum) return -ENOMEM; @@ -1237,7 +1236,7 @@ static int read_cons_helper(struct policydb *p, struct constraint_node **nodep, lc = NULL; for (i = 0; i < ncons; i++) { - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) return -ENOMEM; @@ -1254,7 +1253,7 @@ static int read_cons_helper(struct policydb *p, struct constraint_node **nodep, le = NULL; depth = -1; for (j = 0; j < nexpr; j++) { - e = kzalloc(sizeof(*e), GFP_KERNEL); + e = kzalloc_obj(*e); if (!e) return -ENOMEM; @@ -1297,9 +1296,7 @@ static int read_cons_helper(struct policydb *p, struct constraint_node **nodep, return rc; if (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { - e->type_names = - kzalloc(sizeof(*e->type_names), - GFP_KERNEL); + e->type_names = kzalloc_obj(*e->type_names); if (!e->type_names) return -ENOMEM; type_set_init(e->type_names); @@ -1329,7 +1326,7 @@ static int class_read(struct policydb *p, struct symtab *s, struct policy_file * u32 i, len, len2, ncons, nel; int rc; - cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); + cladatum = kzalloc_obj(*cladatum); if (!cladatum) return -ENOMEM; @@ -1427,7 +1424,7 @@ static int role_read(struct policydb *p, struct symtab *s, struct policy_file *f __le32 buf[3]; u32 len; - role = kzalloc(sizeof(*role), GFP_KERNEL); + role = kzalloc_obj(*role); if (!role) return -ENOMEM; @@ -1484,7 +1481,7 @@ static int type_read(struct policydb *p, struct symtab *s, struct policy_file *f __le32 buf[4]; u32 len; - typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); + typdatum = kzalloc_obj(*typdatum); if (!typdatum) return -ENOMEM; @@ -1558,7 +1555,7 @@ static int user_read(struct policydb *p, struct symtab *s, struct policy_file *f __le32 buf[3]; u32 len; - usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); + usrdatum = kzalloc_obj(*usrdatum); if (!usrdatum) return -ENOMEM; @@ -1608,7 +1605,7 @@ static int sens_read(struct policydb *p, struct symtab *s, struct policy_file *f __le32 buf[2]; u32 len; - levdatum = kzalloc(sizeof(*levdatum), GFP_KERNEL); + levdatum = kzalloc_obj(*levdatum); if (!levdatum) return -ENOMEM; @@ -1644,7 +1641,7 @@ static int cat_read(struct policydb *p, struct symtab *s, struct policy_file *fp __le32 buf[3]; u32 len; - catdatum = kzalloc(sizeof(*catdatum), GFP_KERNEL); + catdatum = kzalloc_obj(*catdatum); if (!catdatum) return -ENOMEM; @@ -1864,7 +1861,7 @@ static int range_read(struct policydb *p, struct policy_file *fp) for (i = 0; i < nel; i++) { rc = -ENOMEM; - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) goto out; @@ -1889,7 +1886,7 @@ static int range_read(struct policydb *p, struct policy_file *fp) goto out; rc = -ENOMEM; - r = kzalloc(sizeof(*r), GFP_KERNEL); + r = kzalloc_obj(*r); if (!r) goto out; @@ -1965,7 +1962,7 @@ static int filename_trans_read_helper_compat(struct policydb *p, struct policy_f } if (!datum) { rc = -ENOMEM; - datum = kmalloc(sizeof(*datum), GFP_KERNEL); + datum = kmalloc_obj(*datum); if (!datum) goto out; @@ -2040,7 +2037,7 @@ static int filename_trans_read_helper(struct policydb *p, struct policy_file *fp dst = &first; for (i = 0; i < ndatum; i++) { rc = -ENOMEM; - datum = kmalloc(sizeof(*datum), GFP_KERNEL); + datum = kmalloc_obj(*datum); if (!datum) goto out; @@ -2062,7 +2059,7 @@ static int filename_trans_read_helper(struct policydb *p, struct policy_file *fp } rc = -ENOMEM; - ft = kmalloc(sizeof(*ft), GFP_KERNEL); + ft = kmalloc_obj(*ft); if (!ft) goto out; @@ -2155,7 +2152,7 @@ static int genfs_read(struct policydb *p, struct policy_file *fp) len = le32_to_cpu(buf[0]); rc = -ENOMEM; - newgenfs = kzalloc(sizeof(*newgenfs), GFP_KERNEL); + newgenfs = kzalloc_obj(*newgenfs); if (!newgenfs) goto out; @@ -2194,7 +2191,7 @@ static int genfs_read(struct policydb *p, struct policy_file *fp) len = le32_to_cpu(buf[0]); rc = -ENOMEM; - newc = kzalloc(sizeof(*newc), GFP_KERNEL); + newc = kzalloc_obj(*newc); if (!newc) goto out; @@ -2266,7 +2263,7 @@ static int ocontext_read(struct policydb *p, l = NULL; for (j = 0; j < nel; j++) { rc = -ENOMEM; - c = kzalloc(sizeof(*c), GFP_KERNEL); + c = kzalloc_obj(*c); if (!c) goto out; if (l) @@ -2623,12 +2620,12 @@ int policydb_read(struct policydb *p, struct policy_file *fp) goto bad; for (i = 0; i < nel; i++) { rc = -ENOMEM; - rtk = kmalloc(sizeof(*rtk), GFP_KERNEL); + rtk = kmalloc_obj(*rtk); if (!rtk) goto bad; rc = -ENOMEM; - rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); + rtd = kmalloc_obj(*rtd); if (!rtd) goto bad; @@ -2671,7 +2668,7 @@ int policydb_read(struct policydb *p, struct policy_file *fp) lra = NULL; for (i = 0; i < nel; i++) { rc = -ENOMEM; - ra = kzalloc(sizeof(*ra), GFP_KERNEL); + ra = kzalloc_obj(*ra); if (!ra) goto bad; if (lra) @@ -2726,8 +2723,8 @@ int policydb_read(struct policydb *p, struct policy_file *fp) goto bad; rc = -ENOMEM; - p->type_attr_map_array = kvcalloc( - p->p_types.nprim, sizeof(*p->type_attr_map_array), GFP_KERNEL); + p->type_attr_map_array = kvzalloc_objs(*p->type_attr_map_array, + p->p_types.nprim); if (!p->type_attr_map_array) goto bad; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 13fc712d5923..e8e7ccbd1e44 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -108,7 +108,7 @@ static int selinux_set_mapping(struct policydb *pol, i++; /* Allocate space for the class records, plus one for class zero */ - out_map->mapping = kcalloc(++i, sizeof(*out_map->mapping), GFP_ATOMIC); + out_map->mapping = kzalloc_objs(*out_map->mapping, ++i, GFP_ATOMIC); if (!out_map->mapping) return -ENOMEM; @@ -2312,11 +2312,11 @@ int security_load_policy(void *data, size_t len, int rc = 0; struct policy_file file = { data, len }, *fp = &file; - newpolicy = kzalloc(sizeof(*newpolicy), GFP_KERNEL); + newpolicy = kzalloc_obj(*newpolicy); if (!newpolicy) return -ENOMEM; - newpolicy->sidtab = kzalloc(sizeof(*newpolicy->sidtab), GFP_KERNEL); + newpolicy->sidtab = kzalloc_obj(*newpolicy->sidtab); if (!newpolicy->sidtab) { rc = -ENOMEM; goto err_policy; @@ -2360,7 +2360,7 @@ int security_load_policy(void *data, size_t len, * in the new SID table. */ - convert_data = kmalloc(sizeof(*convert_data), GFP_KERNEL); + convert_data = kmalloc_obj(*convert_data); if (!convert_data) { rc = -ENOMEM; goto err_free_isids; @@ -3065,7 +3065,7 @@ int security_get_bools(struct selinux_policy *policy, goto err; rc = -ENOMEM; - *values = kcalloc(*len, sizeof(int), GFP_ATOMIC); + *values = kzalloc_objs(int, *len, GFP_ATOMIC); if (!*values) goto err; @@ -3629,7 +3629,7 @@ int selinux_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, return -EINVAL; } - tmprule = kzalloc(sizeof(struct selinux_audit_rule), gfp); + tmprule = kzalloc_obj(struct selinux_audit_rule, gfp); if (!tmprule) return -ENOMEM; context_init(&tmprule->au_ctxt); @@ -3844,7 +3844,7 @@ static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, { u32 *sid_cache; - sid_cache = kmalloc(sizeof(*sid_cache), GFP_ATOMIC); + sid_cache = kmalloc_obj(*sid_cache, GFP_ATOMIC); if (sid_cache == NULL) return; secattr->cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 59f8c09158ef..118af0aa2767 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -580,7 +580,7 @@ void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, goto out_unlock; } - cache = kmalloc(struct_size(cache, str, str_len), GFP_ATOMIC); + cache = kmalloc_flex(*cache, str, str_len, GFP_ATOMIC); if (!cache) goto out_unlock; diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 61d56b0c2be1..8e00b3306574 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -88,7 +88,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, if (str_len >= PAGE_SIZE) return -ENOMEM; - ctx = kmalloc(struct_size(ctx, ctx_str, str_len + 1), gfp); + ctx = kmalloc_flex(*ctx, ctx_str, str_len + 1, gfp); if (!ctx) return -ENOMEM; @@ -354,7 +354,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, if (rc) return rc; - ctx = kmalloc(struct_size(ctx, ctx_str, str_len), GFP_ATOMIC); + ctx = kmalloc_flex(*ctx, ctx_str, str_len, GFP_ATOMIC); if (!ctx) { rc = -ENOMEM; goto out; diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 86ad910d5631..350b88d582b3 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -592,7 +592,7 @@ smk_import_allocated_label(char *smack, gfp_t gfp) if (skp != NULL) goto freeout; - skp = kzalloc(sizeof(*skp), gfp); + skp = kzalloc_obj(*skp, gfp); if (skp == NULL) { skp = ERR_PTR(-ENOMEM); goto freeout; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index a0bd4919a9d9..98af9d7b9434 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -372,7 +372,7 @@ static int smk_copy_relabel(struct list_head *nhead, struct list_head *ohead, struct smack_known_list_elem *oklep; list_for_each_entry(oklep, ohead, list) { - nklep = kzalloc(sizeof(struct smack_known_list_elem), gfp); + nklep = kzalloc_obj(struct smack_known_list_elem, gfp); if (nklep == NULL) { smk_destroy_label_list(nhead); return -ENOMEM; @@ -562,7 +562,7 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts) struct smack_known *skp; if (!opts) { - opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); + opts = kzalloc_obj(struct smack_mnt_opts); if (!opts) return -ENOMEM; *mnt_opts = opts; @@ -622,7 +622,7 @@ static int smack_fs_context_submount(struct fs_context *fc, struct smack_mnt_opts *ctx; struct inode_smack *isp; - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); + ctx = kzalloc_obj(*ctx); if (!ctx) return -ENOMEM; fc->security = ctx; @@ -673,7 +673,7 @@ static int smack_fs_context_dup(struct fs_context *fc, if (!src) return 0; - fc->security = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); + fc->security = kzalloc_obj(struct smack_mnt_opts); if (!fc->security) return -ENOMEM; @@ -2817,7 +2817,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address) /* * A new port entry is required. */ - spp = kzalloc(sizeof(*spp), GFP_KERNEL); + spp = kzalloc_obj(*spp); if (spp == NULL) return; diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index 8919e330d2f6..6e62dcb36f74 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c @@ -682,7 +682,7 @@ smk_cipso_doi(u32 ndoi, gfp_t gfp_flags) smk_netlabel_audit_set(&nai); - doip = kmalloc(sizeof(struct cipso_v4_doi), gfp_flags); + doip = kmalloc_obj(struct cipso_v4_doi, gfp_flags); if (!doip) { rc = -ENOMEM; goto clr_doi_lock; @@ -1249,7 +1249,7 @@ static ssize_t smk_write_net4addr(struct file *file, const char __user *buf, smk_netlabel_audit_set(&audit_info); if (found == 0) { - snp = kzalloc(sizeof(*snp), GFP_KERNEL); + snp = kzalloc_obj(*snp); if (snp == NULL) rc = -ENOMEM; else { @@ -1526,7 +1526,7 @@ static ssize_t smk_write_net6addr(struct file *file, const char __user *buf, break; } if (found == 0) { - snp = kzalloc(sizeof(*snp), GFP_KERNEL); + snp = kzalloc_obj(*snp); if (snp == NULL) rc = -ENOMEM; else { @@ -1970,7 +1970,7 @@ static int smk_parse_label_list(char *data, struct list_head *list) if (IS_ERR(skp)) return PTR_ERR(skp); - sklep = kzalloc(sizeof(*sklep), GFP_KERNEL); + sklep = kzalloc_obj(*sklep); if (sklep == NULL) return -ENOMEM; diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c index 610c1536cf70..bfacb3f2e2ed 100644 --- a/security/tomoyo/audit.c +++ b/security/tomoyo/audit.c @@ -376,7 +376,7 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, buf = tomoyo_init_log(r, len, fmt, args); if (!buf) goto out; - entry = kzalloc(sizeof(*entry), GFP_NOFS); + entry = kzalloc_obj(*entry, GFP_NOFS); if (!entry) { kfree(buf); goto out; diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index 7e1f825d903b..fdaeaff01fc1 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c @@ -493,7 +493,7 @@ static struct tomoyo_profile *tomoyo_assign_profile ptr = ns->profile_ptr[profile]; if (ptr) return ptr; - entry = kzalloc(sizeof(*entry), GFP_NOFS | __GFP_NOWARN); + entry = kzalloc_obj(*entry, GFP_NOFS | __GFP_NOWARN); if (mutex_lock_interruptible(&tomoyo_policy_lock)) goto out; ptr = ns->profile_ptr[profile]; @@ -2553,7 +2553,7 @@ static int tomoyo_write_stat(struct tomoyo_io_buffer *head) */ int tomoyo_open_control(const u8 type, struct file *file) { - struct tomoyo_io_buffer *head = kzalloc(sizeof(*head), GFP_NOFS); + struct tomoyo_io_buffer *head = kzalloc_obj(*head, GFP_NOFS); if (!head) return -ENOMEM; diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 0612eac7f2f2..eeaad421f15b 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -708,7 +708,7 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) bool reject_on_transition_failure = false; const struct tomoyo_path_info *candidate; struct tomoyo_path_info exename; - struct tomoyo_execve *ee = kzalloc(sizeof(*ee), GFP_NOFS); + struct tomoyo_execve *ee = kzalloc_obj(*ee, GFP_NOFS); if (!ee) return -ENOMEM; diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 38b21ee0c560..cef3776cf3b2 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -89,7 +89,7 @@ static void report_access(const char *access, struct task_struct *target, return; } - info = kmalloc(sizeof(*info), GFP_ATOMIC); + info = kmalloc_obj(*info, GFP_ATOMIC); if (!info) return; init_task_work(&info->work, __report_access); @@ -143,7 +143,7 @@ static int yama_ptracer_add(struct task_struct *tracer, { struct ptrace_relation *relation, *added; - added = kmalloc(sizeof(*added), GFP_KERNEL); + added = kmalloc_obj(*added); if (!added) return -ENOMEM; diff --git a/sound/ac97/bus.c b/sound/ac97/bus.c index bb9b795e0226..15487837e894 100644 --- a/sound/ac97/bus.c +++ b/sound/ac97/bus.c @@ -104,7 +104,7 @@ static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx, struct ac97_codec_device *codec; int ret; - codec = kzalloc(sizeof(*codec), GFP_KERNEL); + codec = kzalloc_obj(*codec); if (!codec) return -ENOMEM; ac97_ctrl->codecs[idx] = codec; @@ -351,7 +351,7 @@ struct ac97_controller *snd_ac97_controller_register( struct ac97_controller *ac97_ctrl; int ret, i; - ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL); + ac97_ctrl = kzalloc_obj(*ac97_ctrl); if (!ac97_ctrl) return ERR_PTR(-ENOMEM); diff --git a/sound/ac97/snd_ac97_compat.c b/sound/ac97/snd_ac97_compat.c index d2479bba75bf..1a89286d1b67 100644 --- a/sound/ac97/snd_ac97_compat.c +++ b/sound/ac97/snd_ac97_compat.c @@ -69,7 +69,7 @@ struct snd_ac97 *snd_ac97_compat_alloc(struct ac97_codec_device *adev) struct snd_ac97 *ac97; int ret; - ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); + ac97 = kzalloc_obj(struct snd_ac97); if (ac97 == NULL) return ERR_PTR(-ENOMEM); diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 4cf959017c9d..04961c456d2c 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -855,7 +855,7 @@ static int onyx_init_codec(struct aoa_codec *codec) /* if no inputs are present... */ if ((onyx->codec.connected & 0xC) == 0) { if (!onyx->codec_info) - onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL); + onyx->codec_info = kmalloc_obj(struct codec_info); if (!onyx->codec_info) return -ENOMEM; ci = onyx->codec_info; @@ -866,7 +866,7 @@ static int onyx_init_codec(struct aoa_codec *codec) /* if no outputs are present... */ if ((onyx->codec.connected & 3) == 0) { if (!onyx->codec_info) - onyx->codec_info = kmalloc(sizeof(struct codec_info), GFP_KERNEL); + onyx->codec_info = kmalloc_obj(struct codec_info); if (!onyx->codec_info) return -ENOMEM; ci = onyx->codec_info; @@ -957,7 +957,7 @@ static int onyx_i2c_probe(struct i2c_client *client) struct onyx *onyx; u8 dummy; - onyx = kzalloc(sizeof(struct onyx), GFP_KERNEL); + onyx = kzalloc_obj(struct onyx); if (!onyx) return -ENOMEM; diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 7085e0b93e29..13da2b159ad0 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c @@ -845,7 +845,7 @@ static int tas_i2c_probe(struct i2c_client *client) struct device_node *node = client->dev.of_node; struct tas *tas; - tas = kzalloc(sizeof(struct tas), GFP_KERNEL); + tas = kzalloc_obj(struct tas); if (!tas) return -ENOMEM; diff --git a/sound/aoa/codecs/toonie.c b/sound/aoa/codecs/toonie.c index b59967c49e0a..6aaf4c9debdd 100644 --- a/sound/aoa/codecs/toonie.c +++ b/sound/aoa/codecs/toonie.c @@ -121,7 +121,7 @@ static struct toonie *toonie; static int __init toonie_init(void) { - toonie = kzalloc(sizeof(struct toonie), GFP_KERNEL); + toonie = kzalloc_obj(struct toonie); if (!toonie) return -ENOMEM; diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c index e76bde25e41a..2995876df534 100644 --- a/sound/aoa/core/gpio-pmf.c +++ b/sound/aoa/core/gpio-pmf.c @@ -173,8 +173,7 @@ static int pmf_set_notify(struct gpio_runtime *rt, notif->gpio_private = NULL; } if (!old && notify) { - irq_client = kzalloc(sizeof(struct pmf_irq_client), - GFP_KERNEL); + irq_client = kzalloc_obj(struct pmf_irq_client); if (!irq_client) return -ENOMEM; irq_client->data = notif; diff --git a/sound/aoa/fabrics/layout.c b/sound/aoa/fabrics/layout.c index bb2a0ef3004b..c18b55305294 100644 --- a/sound/aoa/fabrics/layout.c +++ b/sound/aoa/fabrics/layout.c @@ -1025,7 +1025,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) goto outnodev; } - ldev = kzalloc(sizeof(struct layout_dev), GFP_KERNEL); + ldev = kzalloc_obj(struct layout_dev); if (!ldev) goto outnodev; diff --git a/sound/aoa/soundbus/i2sbus/control.c b/sound/aoa/soundbus/i2sbus/control.c index a003ef06de63..1e9f258b5e67 100644 --- a/sound/aoa/soundbus/i2sbus/control.c +++ b/sound/aoa/soundbus/i2sbus/control.c @@ -19,7 +19,7 @@ int i2sbus_control_init(struct macio_dev* dev, struct i2sbus_control **c) { - *c = kzalloc(sizeof(struct i2sbus_control), GFP_KERNEL); + *c = kzalloc_obj(struct i2sbus_control); if (!*c) return -ENOMEM; diff --git a/sound/aoa/soundbus/i2sbus/core.c b/sound/aoa/soundbus/i2sbus/core.c index f4d43c854bbd..f974b96e98cd 100644 --- a/sound/aoa/soundbus/i2sbus/core.c +++ b/sound/aoa/soundbus/i2sbus/core.c @@ -171,7 +171,7 @@ static int i2sbus_add_dev(struct macio_dev *macio, if (strncmp(node_name, "i2s-", 4)) return 0; - dev = kzalloc(sizeof(struct i2sbus_dev), GFP_KERNEL); + dev = kzalloc_obj(struct i2sbus_dev); if (!dev) return 0; diff --git a/sound/aoa/soundbus/i2sbus/pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c index 4c480ad2c05d..aff99003d833 100644 --- a/sound/aoa/soundbus/i2sbus/pcm.c +++ b/sound/aoa/soundbus/i2sbus/pcm.c @@ -879,7 +879,7 @@ i2sbus_attach_codec(struct soundbus_dev *dev, struct snd_card *card, tmp++; } - cii = kzalloc(sizeof(struct codec_info_item), GFP_KERNEL); + cii = kzalloc_obj(struct codec_info_item); if (!cii) return -ENOMEM; diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index ed2eeb914c6d..fdba6e4b25fd 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -519,7 +519,7 @@ snd_compr_get_codec_caps(struct snd_compr_stream *stream, unsigned long arg) return -ENXIO; struct snd_compr_codec_caps *caps __free(kfree) = - kzalloc(sizeof(*caps), GFP_KERNEL); + kzalloc_obj(*caps); if (!caps) return -ENOMEM; @@ -539,7 +539,7 @@ int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size) if (snd_BUG_ON(!(stream) || !(stream)->runtime)) return -EINVAL; - dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); + dmab = kzalloc_obj(*dmab); if (!dmab) return -ENOMEM; dmab->dev = stream->dma_buffer.dev; @@ -694,7 +694,7 @@ snd_compr_get_params(struct snd_compr_stream *stream, unsigned long arg) return -EBADFD; struct snd_codec *params __free(kfree) = - kzalloc(sizeof(*params), GFP_KERNEL); + kzalloc_obj(*params); if (!params) return -ENOMEM; retval = stream->ops->get_params(stream, params); @@ -1066,7 +1066,7 @@ static int snd_compr_task_new(struct snd_compr_stream *stream, struct snd_compr_ return -EBUSY; if (utask->origin_seqno != 0 || utask->input_size != 0) return -EINVAL; - task = kzalloc(sizeof(*task), GFP_KERNEL); + task = kzalloc_obj(*task); if (task == NULL) return -ENOMEM; task->seqno = utask->seqno = snd_compr_seqno_next(stream); diff --git a/sound/core/control.c b/sound/core/control.c index 486d1bc4dac2..934e84e93838 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -233,7 +233,7 @@ static int snd_ctl_new(struct snd_kcontrol **kctl, unsigned int count, if (count == 0 || count > MAX_CONTROL_COUNT) return -EINVAL; - *kctl = kzalloc(struct_size(*kctl, vd, count), GFP_KERNEL); + *kctl = kzalloc_flex(**kctl, vd, count); if (!*kctl) return -ENOMEM; @@ -2057,7 +2057,7 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * { struct snd_kctl_ioctl *pn; - pn = kzalloc(sizeof(struct snd_kctl_ioctl), GFP_KERNEL); + pn = kzalloc_obj(struct snd_kctl_ioctl); if (pn == NULL) return -ENOMEM; pn->fioctl = fcn; diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index b8988a4bcd9b..16bc80555f26 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c @@ -82,7 +82,7 @@ static int snd_ctl_elem_info_compat(struct snd_ctl_file *ctl, struct snd_card *card = ctl->card; int err; struct snd_ctl_elem_info *data __free(kfree) = - kzalloc(sizeof(*data), GFP_KERNEL); + kzalloc_obj(*data); if (! data) return -ENOMEM; @@ -177,7 +177,7 @@ static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id, return -ENOENT; struct snd_ctl_elem_info *info __free(kfree) = - kzalloc(sizeof(*info), GFP_KERNEL); + kzalloc_obj(*info); if (info == NULL) return -ENOMEM; info->id = *id; @@ -283,7 +283,7 @@ static int __ctl_elem_read_user(struct snd_card *card, { int err, type, count; struct snd_ctl_elem_value *data __free(kfree) = - kzalloc(sizeof(*data), GFP_KERNEL); + kzalloc_obj(*data); if (data == NULL) return -ENOMEM; @@ -318,7 +318,7 @@ static int __ctl_elem_write_user(struct snd_ctl_file *file, struct snd_card *card = file->card; int err, type, count; struct snd_ctl_elem_value *data __free(kfree) = - kzalloc(sizeof(*data), GFP_KERNEL); + kzalloc_obj(*data); if (data == NULL) return -ENOMEM; @@ -380,7 +380,7 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, int replace) { struct snd_ctl_elem_info *data __free(kfree) = - kzalloc(sizeof(*data), GFP_KERNEL); + kzalloc_obj(*data); if (! data) return -ENOMEM; diff --git a/sound/core/control_led.c b/sound/core/control_led.c index c7641d5084e7..d92b36ab5ec6 100644 --- a/sound/core/control_led.c +++ b/sound/core/control_led.c @@ -653,7 +653,7 @@ static void snd_ctl_led_sysfs_add(struct snd_card *card) for (group = 0; group < MAX_LED; group++) { led = &snd_ctl_leds[group]; - led_card = kzalloc(sizeof(*led_card), GFP_KERNEL); + led_card = kzalloc_obj(*led_card); if (!led_card) goto cerr2; led_card->number = card->number; diff --git a/sound/core/device.c b/sound/core/device.c index cdc5af526739..5f2aa476d89b 100644 --- a/sound/core/device.c +++ b/sound/core/device.c @@ -34,7 +34,7 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type, if (snd_BUG_ON(!card || !device_data || !ops)) return -ENXIO; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; INIT_LIST_HEAD(&dev->list); diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c index 2d5f4d47071f..9fcd1c03dc5b 100644 --- a/sound/core/hrtimer.c +++ b/sound/core/hrtimer.c @@ -64,7 +64,7 @@ static int snd_hrtimer_open(struct snd_timer *t) { struct snd_hrtimer *stime; - stime = kzalloc(sizeof(*stime), GFP_KERNEL); + stime = kzalloc_obj(*stime); if (!stime) return -ENOMEM; stime->timer = t; diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c index 09200df2932c..973d11732bfd 100644 --- a/sound/core/hwdep.c +++ b/sound/core/hwdep.c @@ -375,7 +375,7 @@ int snd_hwdep_new(struct snd_card *card, char *id, int device, return -ENXIO; if (rhwdep) *rhwdep = NULL; - hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL); + hwdep = kzalloc_obj(*hwdep); if (!hwdep) return -ENOMEM; diff --git a/sound/core/info.c b/sound/core/info.c index 1f5b8a3d9e3b..54834dbe6b59 100644 --- a/sound/core/info.c +++ b/sound/core/info.c @@ -79,7 +79,7 @@ static int alloc_info_private(struct snd_info_entry *entry, return -ENODEV; if (!try_module_get(entry->module)) return -EFAULT; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) { module_put(entry->module); return -ENOMEM; @@ -311,7 +311,7 @@ static ssize_t snd_info_text_entry_write(struct file *file, guard(mutex)(&entry->access); buf = data->wbuffer; if (!buf) { - data->wbuffer = buf = kzalloc(sizeof(*buf), GFP_KERNEL); + data->wbuffer = buf = kzalloc_obj(*buf); if (!buf) return -ENOMEM; } @@ -355,7 +355,7 @@ static int snd_info_text_entry_open(struct inode *inode, struct file *file) if (err < 0) return err; - data->rbuffer = kzalloc(sizeof(*data->rbuffer), GFP_KERNEL); + data->rbuffer = kzalloc_obj(*data->rbuffer); if (!data->rbuffer) { err = -ENOMEM; goto error; @@ -663,7 +663,7 @@ snd_info_create_entry(const char *name, struct snd_info_entry *parent, struct module *module) { struct snd_info_entry *entry; - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (entry == NULL) return NULL; entry->name = kstrdup(name, GFP_KERNEL); diff --git a/sound/core/init.c b/sound/core/init.c index c372b3228785..2f1bd9cbdbed 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -129,7 +129,7 @@ int snd_device_alloc(struct device **dev_p, struct snd_card *card) struct device *dev; *dev_p = NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (!dev) return -ENOMEM; device_initialize(dev); @@ -1060,7 +1060,7 @@ int snd_card_file_add(struct snd_card *card, struct file *file) { struct snd_monitor_file *mfile; - mfile = kmalloc(sizeof(*mfile), GFP_KERNEL); + mfile = kmalloc_obj(*mfile); if (mfile == NULL) return -ENOMEM; mfile->file = file; diff --git a/sound/core/jack.c b/sound/core/jack.c index 93e357a23f17..5e8a2f3f4196 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c @@ -440,7 +440,7 @@ static struct snd_jack_kctl * snd_jack_kctl_new(struct snd_card *card, const cha if (err < 0) return NULL; - jack_kctl = kzalloc(sizeof(*jack_kctl), GFP_KERNEL); + jack_kctl = kzalloc_obj(*jack_kctl); if (!jack_kctl) goto error; @@ -516,7 +516,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type, return -ENOMEM; } - jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL); + jack = kzalloc_obj(struct snd_jack); if (jack == NULL) return -ENOMEM; diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index b3853583d2ae..9320671dfcc8 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -719,12 +719,12 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) unsigned int idx, npages; void *p; - sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); + sgbuf = kzalloc_obj(*sgbuf); if (!sgbuf) return NULL; size = PAGE_ALIGN(size); sgbuf->count = size >> PAGE_SHIFT; - sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL); + sgbuf->pages = kvzalloc_objs(*sgbuf->pages, sgbuf->count); sgbuf->npages = kvcalloc(sgbuf->count, sizeof(*sgbuf->npages), GFP_KERNEL); if (!sgbuf->pages || !sgbuf->npages) goto error; diff --git a/sound/core/oss/copy.c b/sound/core/oss/copy.c index 05b58d4fc2b7..467fc6847bc9 100644 --- a/sound/core/oss/copy.c +++ b/sound/core/oss/copy.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * Linear conversion Plug-In * Copyright (c) 2000 by Abramo Bagnara - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/oss/io.c b/sound/core/oss/io.c index d870b2d93135..9317f971a0d3 100644 --- a/sound/core/oss/io.c +++ b/sound/core/oss/io.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * PCM I/O Plug-In Interface * Copyright (c) 1999 by Jaroslav Kysela - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/oss/linear.c b/sound/core/oss/linear.c index 797d838a2f9e..6e51cfdca238 100644 --- a/sound/core/oss/linear.c +++ b/sound/core/oss/linear.c @@ -1,23 +1,8 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * Linear conversion Plug-In * Copyright (c) 1999 by Jaroslav Kysela , * Abramo Bagnara - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index f4ad0bfb4dac..591cff800329 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -47,7 +47,7 @@ static int snd_mixer_oss_open(struct inode *inode, struct file *file) snd_card_unref(card); return err; } - fmixer = kzalloc(sizeof(*fmixer), GFP_KERNEL); + fmixer = kzalloc_obj(*fmixer); if (fmixer == NULL) { snd_card_file_remove(card, file); snd_card_unref(card); @@ -530,9 +530,9 @@ static void snd_mixer_oss_get_volume1_vol(struct snd_mixer_oss_file *fmixer, return; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return; if (kctl->info(kctl, uinfo)) @@ -566,9 +566,9 @@ static void snd_mixer_oss_get_volume1_sw(struct snd_mixer_oss_file *fmixer, return; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return; if (kctl->info(kctl, uinfo)) @@ -629,9 +629,9 @@ static void snd_mixer_oss_put_volume1_vol(struct snd_mixer_oss_file *fmixer, return; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return; if (kctl->info(kctl, uinfo)) @@ -669,9 +669,9 @@ static void snd_mixer_oss_put_volume1_sw(struct snd_mixer_oss_file *fmixer, return; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return; if (kctl->info(kctl, uinfo)) @@ -798,9 +798,9 @@ static int snd_mixer_oss_get_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned int err, idx; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return -ENOMEM; guard(rwsem_read)(&card->controls_rwsem); @@ -843,9 +843,9 @@ static int snd_mixer_oss_put_recsrc2(struct snd_mixer_oss_file *fmixer, unsigned unsigned int idx; struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (uinfo == NULL || uctl == NULL) return -ENOMEM; guard(rwsem_read)(&card->controls_rwsem); @@ -1027,7 +1027,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, kctl = snd_mixer_oss_test_id(mixer, "Capture Source", 0); if (kctl) { struct snd_ctl_elem_info *uinfo __free(kfree) = - kzalloc(sizeof(*uinfo), GFP_KERNEL); + kzalloc_obj(*uinfo); if (!uinfo) return -ENOMEM; @@ -1055,7 +1055,7 @@ static int snd_mixer_oss_build_input(struct snd_mixer_oss *mixer, } } if (slot.present != 0) { - pslot = kmalloc(sizeof(slot), GFP_KERNEL); + pslot = kmalloc_obj(slot); if (! pslot) return -ENOMEM; *pslot = slot; @@ -1315,7 +1315,7 @@ static int snd_mixer_oss_notify_handler(struct snd_card *card, int cmd) if (cmd == SND_MIXER_OSS_NOTIFY_REGISTER) { int idx, err; - mixer = kcalloc(2, sizeof(*mixer), GFP_KERNEL); + mixer = kzalloc_objs(*mixer, 2); if (mixer == NULL) return -ENOMEM; mutex_init(&mixer->reg_mutex); diff --git a/sound/core/oss/mulaw.c b/sound/core/oss/mulaw.c index fe27034f2846..a95386e55fa1 100644 --- a/sound/core/oss/mulaw.c +++ b/sound/core/oss/mulaw.c @@ -1,24 +1,10 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * Mu-Law conversion Plug-In Interface * Copyright (c) 1999 by Jaroslav Kysela * Uros Bizjak * * Based on reference implementation by Sun Microsystems, Inc. - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 3bc94d34b35e..d4fd4dfc7fc3 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -398,7 +398,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, } struct snd_pcm_hw_params *save __free(kfree) = - kmalloc(sizeof(*save), GFP_KERNEL); + kmalloc_obj(*save); if (save == NULL) return -ENOMEM; *save = *params; @@ -411,7 +411,7 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm, goto _end; struct snd_pcm_hw_params *params1 __free(kfree) = - kmalloc(sizeof(*params1), GFP_KERNEL); + kmalloc_obj(*params1); if (params1 == NULL) return -ENOMEM; *params1 = *save; @@ -786,7 +786,7 @@ static int choose_rate(struct snd_pcm_substream *substream, unsigned int rate, prev; struct snd_pcm_hw_params *save __free(kfree) = - kmalloc(sizeof(*save), GFP_KERNEL); + kmalloc_obj(*save); if (save == NULL) return -ENOMEM; *save = *params; @@ -861,9 +861,9 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream) if (!runtime->oss.params) return 0; - sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); - params = kmalloc(sizeof(*params), GFP_KERNEL); - sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); + sw_params = kzalloc_obj(*sw_params); + params = kmalloc_obj(*params); + sparams = kmalloc_obj(*sparams); if (!sw_params || !params || !sparams) { err = -ENOMEM; goto failure; @@ -1859,7 +1859,7 @@ static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file) AFMT_S24_PACKED; struct snd_pcm_hw_params *params __free(kfree) = - kmalloc(sizeof(*params), GFP_KERNEL); + kmalloc_obj(*params); if (!params) return -ENOMEM; _snd_pcm_hw_params_any(params); @@ -2418,7 +2418,7 @@ static int snd_pcm_oss_open_file(struct file *file, if (rpcm_oss_file) *rpcm_oss_file = NULL; - pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL); + pcm_oss_file = kzalloc_obj(*pcm_oss_file); if (pcm_oss_file == NULL) return -ENOMEM; @@ -3032,7 +3032,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, } } while (*str); if (setup == NULL) { - setup = kmalloc(sizeof(*setup), GFP_KERNEL); + setup = kmalloc_obj(*setup); if (! setup) { buffer->error = -ENOMEM; return; diff --git a/sound/core/oss/pcm_plugin.c b/sound/core/oss/pcm_plugin.c index 82e180c776ae..14b4a390a219 100644 --- a/sound/core/oss/pcm_plugin.c +++ b/sound/core/oss/pcm_plugin.c @@ -1,23 +1,8 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * PCM Plug-In shared (kernel/library) code * Copyright (c) 1999 by Jaroslav Kysela * Copyright (c) 2000 by Abramo Bagnara - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #if 0 @@ -178,7 +163,7 @@ int snd_pcm_plugin_build(struct snd_pcm_substream *plug, channels = src_format->channels; else channels = dst_format->channels; - plugin->buf_channels = kcalloc(channels, sizeof(*plugin->buf_channels), GFP_KERNEL); + plugin->buf_channels = kzalloc_objs(*plugin->buf_channels, channels); if (plugin->buf_channels == NULL) { snd_pcm_plugin_free(plugin); return -ENOMEM; diff --git a/sound/core/oss/rate.c b/sound/core/oss/rate.c index b56eeda5e30e..68711ad251ee 100644 --- a/sound/core/oss/rate.c +++ b/sound/core/oss/rate.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * Rate conversion Plug-In * Copyright (c) 1999 by Jaroslav Kysela - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/oss/route.c b/sound/core/oss/route.c index 72dea04197ef..20f7032d12bb 100644 --- a/sound/core/oss/route.c +++ b/sound/core/oss/route.c @@ -1,22 +1,7 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * Route Plug-In * Copyright (c) 2000 by Abramo Bagnara - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include diff --git a/sound/core/pcm.c b/sound/core/pcm.c index 0b512085eb63..bfedf571e021 100644 --- a/sound/core/pcm.c +++ b/sound/core/pcm.c @@ -334,7 +334,7 @@ static void snd_pcm_proc_info_read(struct snd_pcm_substream *substream, return; struct snd_pcm_info *info __free(kfree) = - kmalloc(sizeof(*info), GFP_KERNEL); + kmalloc_obj(*info); if (!info) return; @@ -657,7 +657,7 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } prev = NULL; for (idx = 0, prev = NULL; idx < substream_count; idx++) { - substream = kzalloc(sizeof(*substream), GFP_KERNEL); + substream = kzalloc_obj(*substream); if (!substream) return -ENOMEM; substream->pcm = pcm; @@ -713,7 +713,7 @@ static int _snd_pcm_new(struct snd_card *card, const char *id, int device, return -ENXIO; if (rpcm) *rpcm = NULL; - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + pcm = kzalloc_obj(*pcm); if (!pcm) return -ENOMEM; pcm->card = card; @@ -935,7 +935,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream, if (substream == NULL) return -EAGAIN; - runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + runtime = kzalloc_obj(*runtime); if (runtime == NULL) return -ENOMEM; diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index e86f68f1f23c..e71f393d3b01 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -243,7 +243,7 @@ static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream, return -ENOTTY; struct snd_pcm_hw_params *data __free(kfree) = - kmalloc(sizeof(*data), GFP_KERNEL); + kmalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/core/pcm_dmaengine.c b/sound/core/pcm_dmaengine.c index f0c17503df42..1306b04be171 100644 --- a/sound/core/pcm_dmaengine.c +++ b/sound/core/pcm_dmaengine.c @@ -318,7 +318,7 @@ int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, if (ret < 0) return ret; - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (!prtd) return -ENOMEM; diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 6eaa950504cf..09c421cd9319 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -2601,7 +2601,7 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, if (WARN_ON(pcm->streams[stream].chmap_kctl)) return -EBUSY; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->pcm = pcm; diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c index 56725d36825b..cfe9f10e7359 100644 --- a/sound/core/pcm_memory.c +++ b/sound/core/pcm_memory.c @@ -448,7 +448,7 @@ int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size) /* dma_max=0 means the fixed size preallocation */ if (substream->dma_buffer.area && !substream->dma_max) return -ENOMEM; - dmab = kzalloc(sizeof(*dmab), GFP_KERNEL); + dmab = kzalloc_obj(*dmab); if (! dmab) return -ENOMEM; dmab->dev = substream->dma_buffer.dev; diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 71eec32a7a0a..180b6b64a448 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c @@ -1,24 +1,9 @@ +// SPDX-License-Identifier: LGPL-2.0+ /* * PCM Interface - misc routines * Copyright (c) 1998 by Jaroslav Kysela - * - * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Library General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ - + #include #include #include diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 0a358d94b17c..5a64453da728 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -244,7 +244,7 @@ int snd_pcm_info_user(struct snd_pcm_substream *substream, { int err; struct snd_pcm_info *info __free(kfree) = - kmalloc(sizeof(*info), GFP_KERNEL); + kmalloc_obj(*info); if (! info) return -ENOMEM; @@ -2144,6 +2144,10 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, for (;;) { long tout; struct snd_pcm_runtime *to_check; + unsigned int drain_rate; + snd_pcm_uframes_t drain_bufsz; + bool drain_no_period_wakeup; + if (signal_pending(current)) { result = -ERESTARTSYS; break; @@ -2163,16 +2167,25 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream, snd_pcm_group_unref(group, substream); if (!to_check) break; /* all drained */ + /* + * Cache the runtime fields needed after unlock. + * A concurrent close() on the linked stream may free + * its runtime via snd_pcm_detach_substream() once we + * release the stream lock below. + */ + drain_no_period_wakeup = to_check->no_period_wakeup; + drain_rate = to_check->rate; + drain_bufsz = to_check->buffer_size; init_waitqueue_entry(&wait, current); set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&to_check->sleep, &wait); snd_pcm_stream_unlock_irq(substream); - if (runtime->no_period_wakeup) + if (drain_no_period_wakeup) tout = MAX_SCHEDULE_TIMEOUT; else { tout = 100; - if (runtime->rate) { - long t = runtime->buffer_size * 1100 / runtime->rate; + if (drain_rate) { + long t = drain_bufsz * 1100 / drain_rate; tout = max(t, tout); } tout = msecs_to_jiffies(tout); @@ -2812,7 +2825,7 @@ static int snd_pcm_open_file(struct file *file, if (err < 0) return err; - pcm_file = kzalloc(sizeof(*pcm_file), GFP_KERNEL); + pcm_file = kzalloc_obj(*pcm_file); if (pcm_file == NULL) { snd_pcm_release_substream(substream); return -ENOMEM; @@ -4111,7 +4124,7 @@ static int snd_pcm_hw_refine_old_user(struct snd_pcm_substream *substream, int err; struct snd_pcm_hw_params *params __free(kfree) = - kmalloc(sizeof(*params), GFP_KERNEL); + kmalloc_obj(*params); if (!params) return -ENOMEM; @@ -4140,7 +4153,7 @@ static int snd_pcm_hw_params_old_user(struct snd_pcm_substream *substream, int err; struct snd_pcm_hw_params *params __free(kfree) = - kmalloc(sizeof(*params), GFP_KERNEL); + kmalloc_obj(*params); if (!params) return -ENOMEM; diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c index 8969ee2757f1..3b1034a44938 100644 --- a/sound/core/rawmidi.c +++ b/sound/core/rawmidi.c @@ -159,7 +159,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) { struct snd_rawmidi_runtime *runtime; - runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + runtime = kzalloc_obj(*runtime); if (!runtime) return -ENOMEM; runtime->substream = substream; @@ -472,7 +472,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file) fflags = snd_rawmidi_file_flags(file); if ((file->f_flags & O_APPEND) || maj == SOUND_MAJOR) /* OSS emul? */ fflags |= SNDRV_RAWMIDI_LFLG_APPEND; - rawmidi_file = kmalloc(sizeof(*rawmidi_file), GFP_KERNEL); + rawmidi_file = kmalloc_obj(*rawmidi_file); if (rawmidi_file == NULL) { err = -ENOMEM; goto __error; @@ -1803,7 +1803,7 @@ static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi, int idx; for (idx = 0; idx < count; idx++) { - substream = kzalloc(sizeof(*substream), GFP_KERNEL); + substream = kzalloc_obj(*substream); if (!substream) return -ENOMEM; substream->stream = direction; @@ -1891,7 +1891,7 @@ int snd_rawmidi_new(struct snd_card *card, char *id, int device, if (rrawmidi) *rrawmidi = NULL; - rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); + rmidi = kzalloc_obj(*rmidi); if (!rmidi) return -ENOMEM; err = snd_rawmidi_init(rmidi, card, id, device, diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c index e0c368bd09cb..d3e6a8a8d823 100644 --- a/sound/core/seq/oss/seq_oss_init.c +++ b/sound/core/seq/oss/seq_oss_init.c @@ -65,7 +65,7 @@ snd_seq_oss_create_client(void) int rc; struct snd_seq_port_callback port_callback; struct snd_seq_port_info *port __free(kfree) = - kzalloc(sizeof(*port), GFP_KERNEL); + kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -168,7 +168,7 @@ snd_seq_oss_open(struct file *file, int level) int i, rc; struct seq_oss_devinfo *dp; - dp = kzalloc(sizeof(*dp), GFP_KERNEL); + dp = kzalloc_obj(*dp); if (!dp) return -ENOMEM; diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c index 2d48c25ff4df..b50a49ca42ff 100644 --- a/sound/core/seq/oss/seq_oss_midi.c +++ b/sound/core/seq/oss/seq_oss_midi.c @@ -66,9 +66,9 @@ int snd_seq_oss_midi_lookup_ports(int client) { struct snd_seq_client_info *clinfo __free(kfree) = - kzalloc(sizeof(*clinfo), GFP_KERNEL); + kzalloc_obj(*clinfo); struct snd_seq_port_info *pinfo __free(kfree) = - kzalloc(sizeof(*pinfo), GFP_KERNEL); + kzalloc_obj(*pinfo); if (!clinfo || !pinfo) return -ENOMEM; @@ -153,7 +153,7 @@ snd_seq_oss_midi_check_new_port(struct snd_seq_port_info *pinfo) /* * allocate midi info record */ - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); + mdev = kzalloc_obj(*mdev); if (!mdev) return -ENOMEM; diff --git a/sound/core/seq/oss/seq_oss_readq.c b/sound/core/seq/oss/seq_oss_readq.c index bbaf72e70b35..c880d4771169 100644 --- a/sound/core/seq/oss/seq_oss_readq.c +++ b/sound/core/seq/oss/seq_oss_readq.c @@ -34,11 +34,11 @@ snd_seq_oss_readq_new(struct seq_oss_devinfo *dp, int maxlen) { struct seq_oss_readq *q; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; - q->q = kcalloc(maxlen, sizeof(union evrec), GFP_KERNEL); + q->q = kzalloc_objs(union evrec, maxlen); if (!q->q) { kfree(q); return NULL; diff --git a/sound/core/seq/oss/seq_oss_synth.c b/sound/core/seq/oss/seq_oss_synth.c index c7f81f2053a7..c4b82e29ab05 100644 --- a/sound/core/seq/oss/seq_oss_synth.c +++ b/sound/core/seq/oss/seq_oss_synth.c @@ -213,7 +213,8 @@ snd_seq_oss_synth_setup(struct seq_oss_devinfo *dp) } info->nr_voices = rec->nr_voices; if (info->nr_voices > 0) { - info->ch = kcalloc(info->nr_voices, sizeof(struct seq_oss_chinfo), GFP_KERNEL); + info->ch = kzalloc_objs(struct seq_oss_chinfo, + info->nr_voices); if (!info->ch) { rec->oper.close(&info->arg); module_put(rec->oper.owner); diff --git a/sound/core/seq/oss/seq_oss_timer.c b/sound/core/seq/oss/seq_oss_timer.c index f9f57232a83f..44c04795204e 100644 --- a/sound/core/seq/oss/seq_oss_timer.c +++ b/sound/core/seq/oss/seq_oss_timer.c @@ -34,7 +34,7 @@ snd_seq_oss_timer_new(struct seq_oss_devinfo *dp) { struct seq_oss_timer *rec; - rec = kzalloc(sizeof(*rec), GFP_KERNEL); + rec = kzalloc_obj(*rec); if (rec == NULL) return NULL; diff --git a/sound/core/seq/oss/seq_oss_writeq.c b/sound/core/seq/oss/seq_oss_writeq.c index a93ff8315b8e..09239ea4b5ea 100644 --- a/sound/core/seq/oss/seq_oss_writeq.c +++ b/sound/core/seq/oss/seq_oss_writeq.c @@ -27,7 +27,7 @@ snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen) struct seq_oss_writeq *q; struct snd_seq_client_pool pool; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; q->dp = dp; diff --git a/sound/core/seq/seq_compat.c b/sound/core/seq/seq_compat.c index 260428747e33..22679dca9aae 100644 --- a/sound/core/seq/seq_compat.c +++ b/sound/core/seq/seq_compat.c @@ -33,7 +33,7 @@ static int snd_seq_call_port_info_ioctl(struct snd_seq_client *client, unsigned { int err; struct snd_seq_port_info *data __free(kfree) = - kmalloc(sizeof(*data), GFP_KERNEL); + kmalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/core/seq/seq_dummy.c b/sound/core/seq/seq_dummy.c index 783fc72c2ef6..af45f328ae99 100644 --- a/sound/core/seq/seq_dummy.c +++ b/sound/core/seq/seq_dummy.c @@ -115,7 +115,7 @@ create_port(int idx, int type) struct snd_seq_port_callback pcb; struct snd_seq_dummy_port *rec; - rec = kzalloc(sizeof(*rec), GFP_KERNEL); + rec = kzalloc_obj(*rec); if (!rec) return NULL; diff --git a/sound/core/seq/seq_fifo.c b/sound/core/seq/seq_fifo.c index 91cce1890111..ebe1394c18a9 100644 --- a/sound/core/seq/seq_fifo.c +++ b/sound/core/seq/seq_fifo.c @@ -19,7 +19,7 @@ struct snd_seq_fifo *snd_seq_fifo_new(int poolsize) { struct snd_seq_fifo *f; - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) return NULL; diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c index ccde0ca3d208..aaf808316c30 100644 --- a/sound/core/seq/seq_memory.c +++ b/sound/core/seq/seq_memory.c @@ -441,9 +441,7 @@ int snd_seq_pool_init(struct snd_seq_pool *pool) if (snd_BUG_ON(!pool)) return -EINVAL; - cellptr = kvmalloc_array(pool->size, - sizeof(struct snd_seq_event_cell), - GFP_KERNEL); + cellptr = kvmalloc_objs(struct snd_seq_event_cell, pool->size); if (!cellptr) return -ENOMEM; @@ -518,7 +516,7 @@ struct snd_seq_pool *snd_seq_pool_new(int poolsize) struct snd_seq_pool *pool; /* create pool block */ - pool = kzalloc(sizeof(*pool), GFP_KERNEL); + pool = kzalloc_obj(*pool); if (!pool) return NULL; spin_lock_init(&pool->lock); diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 88e930980f16..ca3f5fc30992 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c @@ -281,7 +281,7 @@ snd_seq_midisynth_probe(struct snd_seq_device *dev) return -EINVAL; struct snd_rawmidi_info *info __free(kfree) = - kmalloc(sizeof(*info), GFP_KERNEL); + kmalloc_obj(*info); if (! info) return -ENOMEM; info->device = device; @@ -305,7 +305,7 @@ snd_seq_midisynth_probe(struct snd_seq_device *dev) client = synths[card->number]; if (client == NULL) { newclient = 1; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (client == NULL) return -ENOMEM; client->seq_client = @@ -318,10 +318,10 @@ snd_seq_midisynth_probe(struct snd_seq_device *dev) } } - msynth = kcalloc(ports, sizeof(struct seq_midisynth), GFP_KERNEL); + msynth = kzalloc_objs(struct seq_midisynth, ports); struct snd_seq_port_info *port __free(kfree) = - kmalloc(sizeof(*port), GFP_KERNEL); + kmalloc_obj(*port); if (msynth == NULL || port == NULL) goto __nomem; diff --git a/sound/core/seq/seq_midi_emul.c b/sound/core/seq/seq_midi_emul.c index 81d2ef5e5811..fd067c85c524 100644 --- a/sound/core/seq/seq_midi_emul.c +++ b/sound/core/seq/seq_midi_emul.c @@ -650,7 +650,7 @@ static struct snd_midi_channel *snd_midi_channel_init_set(int n) struct snd_midi_channel *chan; int i; - chan = kmalloc_array(n, sizeof(struct snd_midi_channel), GFP_KERNEL); + chan = kmalloc_objs(struct snd_midi_channel, n); if (chan) { for (i = 0; i < n; i++) snd_midi_channel_init(chan+i, i); @@ -688,7 +688,7 @@ struct snd_midi_channel_set *snd_midi_channel_alloc_set(int n) { struct snd_midi_channel_set *chset; - chset = kmalloc(sizeof(*chset), GFP_KERNEL); + chset = kmalloc_obj(*chset); if (chset) { chset->channels = snd_midi_channel_init_set(n); chset->private_data = NULL; diff --git a/sound/core/seq/seq_midi_event.c b/sound/core/seq/seq_midi_event.c index fa9dfc53c3fc..0d9269b47b59 100644 --- a/sound/core/seq/seq_midi_event.c +++ b/sound/core/seq/seq_midi_event.c @@ -104,7 +104,7 @@ int snd_midi_event_new(int bufsize, struct snd_midi_event **rdev) struct snd_midi_event *dev; *rdev = NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = kzalloc_obj(*dev); if (dev == NULL) return -ENOMEM; if (bufsize > 0) { diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c index bbec34bba4f9..da8d358958f1 100644 --- a/sound/core/seq/seq_ports.c +++ b/sound/core/seq/seq_ports.c @@ -129,7 +129,7 @@ int snd_seq_create_port(struct snd_seq_client *client, int port, } /* create a new port */ - new_port = kzalloc(sizeof(*new_port), GFP_KERNEL); + new_port = kzalloc_obj(*new_port); if (!new_port) return -ENOMEM; /* failure, out of memory */ /* init port data */ @@ -572,7 +572,7 @@ int snd_seq_port_connect(struct snd_seq_client *connector, bool exclusive; int err; - subs = kzalloc(sizeof(*subs), GFP_KERNEL); + subs = kzalloc_obj(*subs); if (!subs) return -ENOMEM; diff --git a/sound/core/seq/seq_prioq.c b/sound/core/seq/seq_prioq.c index e649485a8772..25c0ed8f9f0f 100644 --- a/sound/core/seq/seq_prioq.c +++ b/sound/core/seq/seq_prioq.c @@ -43,7 +43,7 @@ struct snd_seq_prioq *snd_seq_prioq_new(void) { struct snd_seq_prioq *f; - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) return NULL; diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index c0c5e1424c5a..2c420d249c96 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c @@ -89,7 +89,7 @@ static struct snd_seq_queue *queue_new(int owner, int locked) { struct snd_seq_queue *q; - q = kzalloc(sizeof(*q), GFP_KERNEL); + q = kzalloc_obj(*q); if (!q) return NULL; diff --git a/sound/core/seq/seq_system.c b/sound/core/seq/seq_system.c index 5b5603e5970b..f6132a120048 100644 --- a/sound/core/seq/seq_system.c +++ b/sound/core/seq/seq_system.c @@ -130,7 +130,7 @@ int __init snd_seq_system_client_init(void) struct snd_seq_port_info *port; int err; - port = kzalloc(sizeof(*port), GFP_KERNEL); + port = kzalloc_obj(*port); if (!port) return -ENOMEM; diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index 29b018a212fc..9bef2f792498 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c @@ -43,7 +43,7 @@ struct snd_seq_timer *snd_seq_timer_new(void) { struct snd_seq_timer *tmr; - tmr = kzalloc(sizeof(*tmr), GFP_KERNEL); + tmr = kzalloc_obj(*tmr); if (!tmr) return NULL; spin_lock_init(&tmr->lock); diff --git a/sound/core/seq/seq_ump_client.c b/sound/core/seq/seq_ump_client.c index 7bc18415a540..fdc76f23e03f 100644 --- a/sound/core/seq/seq_ump_client.c +++ b/sound/core/seq/seq_ump_client.c @@ -220,7 +220,7 @@ static int seq_ump_group_init(struct seq_ump_client *client, int group_index) return 0; struct snd_seq_port_info *port __free(kfree) = - kzalloc(sizeof(*port), GFP_KERNEL); + kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -246,9 +246,9 @@ static void update_port_infos(struct seq_ump_client *client) int i, err; struct snd_seq_port_info *old __free(kfree) = - kzalloc(sizeof(*old), GFP_KERNEL); + kzalloc_obj(*old); struct snd_seq_port_info *new __free(kfree) = - kzalloc(sizeof(*new), GFP_KERNEL); + kzalloc_obj(*new); if (!old || !new) return; @@ -283,7 +283,7 @@ static int create_ump_endpoint_port(struct seq_ump_client *client) int err; struct snd_seq_port_info *port __free(kfree) = - kzalloc(sizeof(*port), GFP_KERNEL); + kzalloc_obj(*port); if (!port) return -ENOMEM; @@ -461,7 +461,7 @@ static int snd_seq_ump_probe(struct snd_seq_device *dev) struct snd_seq_client *cptr; int p, err; - client = kzalloc(sizeof(*client), GFP_KERNEL); + client = kzalloc_obj(*client); if (!client) return -ENOMEM; diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 574493fbd50d..982828650d41 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -216,7 +216,7 @@ static int snd_virmidi_output_open(struct snd_rawmidi_substream *substream) struct snd_rawmidi_runtime *runtime = substream->runtime; struct snd_virmidi *vmidi; - vmidi = kzalloc(sizeof(*vmidi), GFP_KERNEL); + vmidi = kzalloc_obj(*vmidi); if (vmidi == NULL) return -ENOMEM; vmidi->substream = substream; @@ -367,7 +367,7 @@ static int snd_virmidi_dev_attach_seq(struct snd_virmidi_dev *rdev) return 0; struct snd_seq_port_info *pinfo __free(kfree) = - kzalloc(sizeof(*pinfo), GFP_KERNEL); + kzalloc_obj(*pinfo); if (!pinfo) return -ENOMEM; @@ -498,7 +498,7 @@ int snd_virmidi_new(struct snd_card *card, int device, struct snd_rawmidi **rrmi if (err < 0) return err; strscpy(rmidi->name, rmidi->id); - rdev = kzalloc(sizeof(*rdev), GFP_KERNEL); + rdev = kzalloc_obj(*rdev); if (rdev == NULL) { snd_device_free(card, rmidi); return -ENOMEM; diff --git a/sound/core/sound.c b/sound/core/sound.c index 6531a67f13b3..93436db24710 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -257,7 +257,7 @@ int snd_register_device(int type, struct snd_card *card, int dev, if (snd_BUG_ON(!device)) return -EINVAL; - preg = kmalloc(sizeof *preg, GFP_KERNEL); + preg = kmalloc_obj(*preg); if (preg == NULL) return -ENOMEM; preg->type = type; diff --git a/sound/core/sound_oss.c b/sound/core/sound_oss.c index d65cc6fee2e6..7eb49f2cada5 100644 --- a/sound/core/sound_oss.c +++ b/sound/core/sound_oss.c @@ -96,7 +96,7 @@ int snd_register_oss_device(int type, struct snd_card *card, int dev, return 0; /* ignore silently */ if (minor < 0) return minor; - preg = kmalloc(sizeof(struct snd_minor), GFP_KERNEL); + preg = kmalloc_obj(struct snd_minor); if (preg == NULL) return -ENOMEM; preg->type = type; diff --git a/sound/core/timer.c b/sound/core/timer.c index 9a4a1748ff80..6a70df7ae019 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -151,7 +151,7 @@ struct snd_timer_instance *snd_timer_instance_new(const char *owner) { struct snd_timer_instance *timeri; - timeri = kzalloc(sizeof(*timeri), GFP_KERNEL); + timeri = kzalloc_obj(*timeri); if (timeri == NULL) return NULL; timeri->owner = kstrdup(owner, GFP_KERNEL); @@ -930,7 +930,7 @@ int snd_timer_new(struct snd_card *card, char *id, struct snd_timer_id *tid, } if (rtimer) *rtimer = NULL; - timer = kzalloc(sizeof(*timer), GFP_KERNEL); + timer = kzalloc_obj(*timer); if (!timer) return -ENOMEM; timer->tmr_class = tid->dev_class; @@ -1197,7 +1197,7 @@ static int snd_timer_register_system(void) return err; strscpy(timer->name, "system timer"); timer->hw = snd_timer_system; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) { snd_timer_free(timer); return -ENOMEM; @@ -1432,11 +1432,11 @@ static int realloc_user_queue(struct snd_timer_user *tu, int size) struct snd_timer_tread64 *tqueue = NULL; if (tu->tread) { - tqueue = kcalloc(size, sizeof(*tqueue), GFP_KERNEL); + tqueue = kzalloc_objs(*tqueue, size); if (!tqueue) return -ENOMEM; } else { - queue = kcalloc(size, sizeof(*queue), GFP_KERNEL); + queue = kzalloc_objs(*queue, size); if (!queue) return -ENOMEM; } @@ -1461,7 +1461,7 @@ static int snd_timer_user_open(struct inode *inode, struct file *file) if (err < 0) return err; - tu = kzalloc(sizeof(*tu), GFP_KERNEL); + tu = kzalloc_obj(*tu); if (tu == NULL) return -ENOMEM; spin_lock_init(&tu->qlock); @@ -2128,7 +2128,7 @@ static int snd_utimer_create(struct snd_timer_uinfo *utimer_info, if (!utimer_info || utimer_info->resolution == 0) return -EINVAL; - utimer = kzalloc(sizeof(*utimer), GFP_KERNEL); + utimer = kzalloc_obj(*utimer); if (!utimer) return -ENOMEM; diff --git a/sound/core/ump.c b/sound/core/ump.c index 8d8681a42ca5..70520c7ca293 100644 --- a/sound/core/ump.c +++ b/sound/core/ump.c @@ -166,7 +166,7 @@ int snd_ump_endpoint_new(struct snd_card *card, char *id, int device, if (input && output) info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX; - ump = kzalloc(sizeof(*ump), GFP_KERNEL); + ump = kzalloc_obj(*ump); if (!ump) return -ENOMEM; INIT_LIST_HEAD(&ump->block_list); @@ -408,7 +408,7 @@ int snd_ump_block_new(struct snd_ump_endpoint *ump, unsigned int blk, if (snd_ump_get_block(ump, blk)) return -EBUSY; - fb = kzalloc(sizeof(*fb), GFP_KERNEL); + fb = kzalloc_obj(*fb); if (!fb) return -ENOMEM; @@ -1352,8 +1352,7 @@ int snd_ump_attach_legacy_rawmidi(struct snd_ump_endpoint *ump, bool input, output; int err, num; - ump->out_cvts = kcalloc(SNDRV_UMP_MAX_GROUPS, - sizeof(*ump->out_cvts), GFP_KERNEL); + ump->out_cvts = kzalloc_objs(*ump->out_cvts, SNDRV_UMP_MAX_GROUPS); if (!ump->out_cvts) return -ENOMEM; diff --git a/sound/core/vmaster.c b/sound/core/vmaster.c index 76cc64245f5d..cd3dcaaf9f72 100644 --- a/sound/core/vmaster.c +++ b/sound/core/vmaster.c @@ -58,7 +58,7 @@ static int follower_update(struct link_follower *follower) { int err, ch; struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (!uctl) return -ENOMEM; @@ -84,7 +84,7 @@ static int follower_init(struct link_follower *follower) } struct snd_ctl_elem_info *uinfo __free(kfree) = - kmalloc(sizeof(*uinfo), GFP_KERNEL); + kmalloc_obj(*uinfo); if (!uinfo) return -ENOMEM; uinfo->id = follower->follower.id; @@ -256,8 +256,7 @@ int _snd_ctl_add_follower(struct snd_kcontrol *master, struct link_master *master_link = snd_kcontrol_chip(master); struct link_follower *srec; - srec = kzalloc(struct_size(srec, follower.vd, follower->count), - GFP_KERNEL); + srec = kzalloc_flex(*srec, follower.vd, follower->count); if (!srec) return -ENOMEM; srec->kctl = follower; @@ -342,7 +341,7 @@ static int sync_followers(struct link_master *master, int old_val, int new_val) { struct link_follower *follower; struct snd_ctl_elem_value *uval __free(kfree) = - kmalloc(sizeof(*uval), GFP_KERNEL); + kmalloc_obj(*uval); if (!uval) return -ENOMEM; @@ -430,7 +429,7 @@ struct snd_kcontrol *snd_ctl_make_virtual_master(char *name, knew.name = name; knew.info = master_info; - master = kzalloc(sizeof(*master), GFP_KERNEL); + master = kzalloc_obj(*master); if (!master) return NULL; INIT_LIST_HEAD(&master->followers); diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 1860ff75fe15..7283f0f18813 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c @@ -329,7 +329,7 @@ static int dummy_systimer_create(struct snd_pcm_substream *substream) { struct dummy_systimer_pcm *dpcm; - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); + dpcm = kzalloc_obj(*dpcm); if (!dpcm) return -ENOMEM; substream->runtime->private_data = dpcm; @@ -450,7 +450,7 @@ static int dummy_hrtimer_create(struct snd_pcm_substream *substream) { struct dummy_hrtimer_pcm *dpcm; - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); + dpcm = kzalloc_obj(*dpcm); if (!dpcm) return -ENOMEM; substream->runtime->private_data = dpcm; diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 4af89822bf32..6de03d72a908 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c @@ -518,7 +518,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, out_enable, in_enable, &rmidi); if (err < 0) return err; - mpu = kzalloc(sizeof(*mpu), GFP_KERNEL); + mpu = kzalloc_obj(*mpu); if (!mpu) { err = -ENOMEM; goto free_device; diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c index fe50b48c10e7..36e9eab204ca 100644 --- a/sound/drivers/mts64.c +++ b/sound/drivers/mts64.c @@ -75,7 +75,7 @@ static int snd_mts64_create(struct snd_card *card, *rchip = NULL; - mts = kzalloc(sizeof(struct mts64), GFP_KERNEL); + mts = kzalloc_obj(struct mts64); if (mts == NULL) return -ENOMEM; diff --git a/sound/drivers/opl3/opl3_lib.c b/sound/drivers/opl3/opl3_lib.c index fa8a2ccbbd51..ea9b258b1e4b 100644 --- a/sound/drivers/opl3/opl3_lib.c +++ b/sound/drivers/opl3/opl3_lib.c @@ -324,7 +324,7 @@ int snd_opl3_new(struct snd_card *card, int err; *ropl3 = NULL; - opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL); + opl3 = kzalloc_obj(*opl3); if (!opl3) return -ENOMEM; diff --git a/sound/drivers/opl3/opl3_synth.c b/sound/drivers/opl3/opl3_synth.c index 10f622b439a0..47a2486be46d 100644 --- a/sound/drivers/opl3/opl3_synth.c +++ b/sound/drivers/opl3/opl3_synth.c @@ -313,7 +313,7 @@ struct fm_patch *snd_opl3_find_patch(struct snd_opl3 *opl3, int prog, int bank, if (!create_patch) return NULL; - patch = kzalloc(sizeof(*patch), GFP_KERNEL); + patch = kzalloc_obj(*patch); if (!patch) return NULL; patch->prog = prog; diff --git a/sound/drivers/opl4/opl4_lib.c b/sound/drivers/opl4/opl4_lib.c index 44fbc6bf0654..6364475a368a 100644 --- a/sound/drivers/opl4/opl4_lib.c +++ b/sound/drivers/opl4/opl4_lib.c @@ -187,7 +187,7 @@ int snd_opl4_create(struct snd_card *card, if (ropl4) *ropl4 = NULL; - opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL); + opl4 = kzalloc_obj(*opl4); if (!opl4) return -ENOMEM; diff --git a/sound/drivers/pcmtest.c b/sound/drivers/pcmtest.c index b8474631f0b5..768bb698adfb 100644 --- a/sound/drivers/pcmtest.c +++ b/sound/drivers/pcmtest.c @@ -377,7 +377,7 @@ static int snd_pcmtst_pcm_open(struct snd_pcm_substream *substream) if (inject_open_err) return -EBUSY; - v_iter = kzalloc(sizeof(*v_iter), GFP_KERNEL); + v_iter = kzalloc_obj(*v_iter); if (!v_iter) return -ENOMEM; @@ -575,7 +575,7 @@ static int snd_pcmtst_create(struct snd_card *card, struct platform_device *pdev .dev_free = snd_pcmtst_dev_free, }; - pcmtst = kzalloc(sizeof(*pcmtst), GFP_KERNEL); + pcmtst = kzalloc_obj(*pcmtst); if (!pcmtst) return -ENOMEM; pcmtst->card = card; diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c index b903a138fc2a..dcc0899cfb99 100644 --- a/sound/drivers/portman2x4.c +++ b/sound/drivers/portman2x4.c @@ -88,7 +88,7 @@ static int portman_create(struct snd_card *card, *rchip = NULL; - pm = kzalloc(sizeof(struct portman), GFP_KERNEL); + pm = kzalloc_obj(struct portman); if (pm == NULL) return -ENOMEM; diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c index 7fd8f413d6cf..d9b94580704a 100644 --- a/sound/drivers/vx/vx_pcm.c +++ b/sound/drivers/vx/vx_pcm.c @@ -414,7 +414,7 @@ static int vx_alloc_pipe(struct vx_core *chip, int capture, return err; /* initialize the pipe record */ - pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); + pipe = kzalloc_obj(*pipe); if (! pipe) { /* release the pipe */ vx_init_rmh(&rmh, CMD_FREE_PIPE); @@ -1154,10 +1154,10 @@ static int vx_init_audio_io(struct vx_core *chip) chip->audio_info = rmh.Stat[1]; /* allocate pipes */ - chip->playback_pipes = kcalloc(chip->audio_outs, sizeof(struct vx_pipe *), GFP_KERNEL); + chip->playback_pipes = kzalloc_objs(struct vx_pipe *, chip->audio_outs); if (!chip->playback_pipes) return -ENOMEM; - chip->capture_pipes = kcalloc(chip->audio_ins, sizeof(struct vx_pipe *), GFP_KERNEL); + chip->capture_pipes = kzalloc_objs(struct vx_pipe *, chip->audio_ins); if (!chip->capture_pipes) { kfree(chip->playback_pipes); return -ENOMEM; diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index 223c880af802..e97721f80f65 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -1735,8 +1735,8 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed, s->ctx_data.tx.cache.size = max_t(unsigned int, s->syt_interval * 2, queue_size * 3 / 2); s->ctx_data.tx.cache.pos = 0; - s->ctx_data.tx.cache.descs = kcalloc(s->ctx_data.tx.cache.size, - sizeof(*s->ctx_data.tx.cache.descs), GFP_KERNEL); + s->ctx_data.tx.cache.descs = kzalloc_objs(*s->ctx_data.tx.cache.descs, + s->ctx_data.tx.cache.size); if (!s->ctx_data.tx.cache.descs) { err = -ENOMEM; goto err_context; @@ -1756,7 +1756,8 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed, [CIP_SFC_176400] = { 0, 67 }, }; - s->ctx_data.rx.seq.descs = kcalloc(queue_size, sizeof(*s->ctx_data.rx.seq.descs), GFP_KERNEL); + s->ctx_data.rx.seq.descs = kzalloc_objs(*s->ctx_data.rx.seq.descs, + queue_size); if (!s->ctx_data.rx.seq.descs) { err = -ENOMEM; goto err_context; @@ -1781,7 +1782,7 @@ static int amdtp_stream_start(struct amdtp_stream *s, int channel, int speed, // for runtime of PCM substream in the interval equivalent to the size of PCM buffer. It // could take a round over queue of AMDTP packet descriptors and small loss of history. For // safe, keep more 8 elements for the queue, equivalent to 1 ms. - descs = kcalloc(s->queue_size + 8, sizeof(*descs), GFP_KERNEL); + descs = kzalloc_objs(*descs, s->queue_size + 8); if (!descs) { err = -ENOMEM; goto err_context; diff --git a/sound/firewire/bebob/bebob_proc.c b/sound/firewire/bebob/bebob_proc.c index f659b888a6d1..ad03734afcb1 100644 --- a/sound/firewire/bebob/bebob_proc.c +++ b/sound/firewire/bebob/bebob_proc.c @@ -38,7 +38,7 @@ proc_read_hw_info(struct snd_info_entry *entry, struct snd_bebob *bebob = entry->private_data; struct hw_info *info; - info = kzalloc(sizeof(struct hw_info), GFP_KERNEL); + info = kzalloc_obj(struct hw_info); if (info == NULL) return; diff --git a/sound/firewire/dice/dice.c b/sound/firewire/dice/dice.c index 85d265c7d544..f7a50bae4b55 100644 --- a/sound/firewire/dice/dice.c +++ b/sound/firewire/dice/dice.c @@ -122,7 +122,7 @@ static void dice_card_strings(struct snd_dice *dice) fw_csr_string(dev->config_rom + 5, CSR_VENDOR, vendor, sizeof(vendor)); strscpy(model, "?"); fw_csr_string(dice->unit->directory, CSR_MODEL, model, sizeof(model)); - snprintf(card->longname, sizeof(card->longname), + scnprintf(card->longname, sizeof(card->longname), "%s %s (serial %u) at %s, S%d", vendor, model, dev->config_rom[4] & 0x3fffff, dev_name(&dice->unit->device), 100 << dev->max_speed); diff --git a/sound/firewire/fireworks/fireworks.c b/sound/firewire/fireworks/fireworks.c index 3378c7dce88a..d69435722abb 100644 --- a/sound/firewire/fireworks/fireworks.c +++ b/sound/firewire/fireworks/fireworks.c @@ -76,7 +76,7 @@ get_hardware_info(struct snd_efw *efw) char version[12] = {0}; int err; - hwinfo = kzalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); + hwinfo = kzalloc_obj(struct snd_efw_hwinfo); if (hwinfo == NULL) return -ENOMEM; diff --git a/sound/firewire/fireworks/fireworks_proc.c b/sound/firewire/fireworks/fireworks_proc.c index 12288567b0cd..aba544b86b99 100644 --- a/sound/firewire/fireworks/fireworks_proc.c +++ b/sound/firewire/fireworks/fireworks_proc.c @@ -31,7 +31,7 @@ proc_read_hwinfo(struct snd_info_entry *entry, struct snd_info_buffer *buffer) unsigned short i; struct snd_efw_hwinfo *hwinfo; - hwinfo = kmalloc(sizeof(struct snd_efw_hwinfo), GFP_KERNEL); + hwinfo = kmalloc_obj(struct snd_efw_hwinfo); if (hwinfo == NULL) return; diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c index 89dc436a0652..56a6f3493f6f 100644 --- a/sound/firewire/motu/motu-hwdep.c +++ b/sound/firewire/motu/motu-hwdep.c @@ -185,7 +185,7 @@ static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, if (!(motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP)) return -ENXIO; - meter = kzalloc(sizeof(*meter), GFP_KERNEL); + meter = kzalloc_obj(*meter); if (!meter) return -ENOMEM; @@ -207,7 +207,7 @@ static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, if (!(motu->spec->flags & SND_MOTU_SPEC_COMMAND_DSP)) return -ENXIO; - meter = kzalloc(sizeof(*meter), GFP_KERNEL); + meter = kzalloc_obj(*meter); if (!meter) return -ENOMEM; @@ -229,7 +229,7 @@ static int hwdep_ioctl(struct snd_hwdep *hwdep, struct file *file, if (!(motu->spec->flags & SND_MOTU_SPEC_REGISTER_DSP)) return -ENXIO; - param = kzalloc(sizeof(*param), GFP_KERNEL); + param = kzalloc_obj(*param); if (!param) return -ENOMEM; diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c index 0ecafd0c6722..2093a5fbd81d 100644 --- a/sound/firewire/packets-buffer.c +++ b/sound/firewire/packets-buffer.c @@ -27,7 +27,7 @@ int iso_packets_buffer_init(struct iso_packets_buffer *b, struct fw_unit *unit, void *p; int err; - b->packets = kmalloc_array(count, sizeof(*b->packets), GFP_KERNEL); + b->packets = kmalloc_objs(*b->packets, count); if (!b->packets) { err = -ENOMEM; goto error; diff --git a/sound/hda/codecs/analog.c b/sound/hda/codecs/analog.c index 357ad5a6c0db..11b1d30b23fd 100644 --- a/sound/hda/codecs/analog.c +++ b/sound/hda/codecs/analog.c @@ -191,7 +191,7 @@ static int alloc_ad_spec(struct hda_codec *codec) { struct ad198x_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; codec->spec = spec; diff --git a/sound/hda/codecs/ca0110.c b/sound/hda/codecs/ca0110.c index c75a9ff9460d..d17fc38784e1 100644 --- a/sound/hda/codecs/ca0110.c +++ b/sound/hda/codecs/ca0110.c @@ -35,7 +35,7 @@ static int ca0110_probe(struct hda_codec *codec, const struct hda_device_id *id) struct hda_gen_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(spec); diff --git a/sound/hda/codecs/ca0132.c b/sound/hda/codecs/ca0132.c index dd054aedd501..a0677d7da8e2 100644 --- a/sound/hda/codecs/ca0132.c +++ b/sound/hda/codecs/ca0132.c @@ -3392,11 +3392,11 @@ static int dspxfr_image(struct hda_codec *codec, if (fls_data == NULL) return -EINVAL; - dma_engine = kzalloc(sizeof(*dma_engine), GFP_KERNEL); + dma_engine = kzalloc_obj(*dma_engine); if (!dma_engine) return -ENOMEM; - dma_engine->dmab = kzalloc(sizeof(*dma_engine->dmab), GFP_KERNEL); + dma_engine->dmab = kzalloc_obj(*dma_engine->dmab); if (!dma_engine->dmab) { kfree(dma_engine); return -ENOMEM; @@ -9816,6 +9816,15 @@ static void ca0132_config(struct hda_codec *codec) spec->dig_in = 0x09; break; } + + /* Default HP/Speaker auto-detect from headphone pin verb: enable if the + * pin config indicates presence detect (not AC_DEFCFG_MISC_NO_PRESENCE). + */ + if (spec->unsol_tag_hp && + (snd_hda_query_pin_caps(codec, spec->unsol_tag_hp) & AC_PINCAP_PRES_DETECT) && + !(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, spec->unsol_tag_hp)) & + AC_DEFCFG_MISC_NO_PRESENCE)) + spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID] = 1; } static int ca0132_prepare_verbs(struct hda_codec *codec) @@ -9831,9 +9840,7 @@ static int ca0132_prepare_verbs(struct hda_codec *codec) */ if (ca0132_use_pci_mmio(spec)) spec->desktop_init_verbs = ca0132_init_verbs1; - spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS, - sizeof(struct hda_verb), - GFP_KERNEL); + spec->spec_init_verbs = kzalloc_objs(struct hda_verb, NUM_SPEC_VERBS); if (!spec->spec_init_verbs) return -ENOMEM; @@ -9900,7 +9907,7 @@ static int ca0132_codec_probe(struct hda_codec *codec, codec_dbg(codec, "%s\n", __func__); - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; codec->spec = spec; diff --git a/sound/hda/codecs/cirrus/cs420x.c b/sound/hda/codecs/cirrus/cs420x.c index 13f5f1711fa4..52eda0a338ea 100644 --- a/sound/hda/codecs/cirrus/cs420x.c +++ b/sound/hda/codecs/cirrus/cs420x.c @@ -524,7 +524,7 @@ static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) { struct cs_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return NULL; codec->spec = spec; diff --git a/sound/hda/codecs/cirrus/cs421x.c b/sound/hda/codecs/cirrus/cs421x.c index a93e2e0bb391..c8349a2c5a36 100644 --- a/sound/hda/codecs/cirrus/cs421x.c +++ b/sound/hda/codecs/cirrus/cs421x.c @@ -162,7 +162,7 @@ static struct cs_spec *cs_alloc_spec(struct hda_codec *codec, int vendor_nid) { struct cs_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return NULL; codec->spec = spec; diff --git a/sound/hda/codecs/cirrus/cs8409.c b/sound/hda/codecs/cirrus/cs8409.c index 61b6a15d6291..fad705092777 100644 --- a/sound/hda/codecs/cirrus/cs8409.c +++ b/sound/hda/codecs/cirrus/cs8409.c @@ -61,7 +61,7 @@ static struct cs8409_spec *cs8409_alloc_spec(struct hda_codec *codec) { struct cs8409_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return NULL; codec->spec = spec; diff --git a/sound/hda/codecs/cm9825.c b/sound/hda/codecs/cm9825.c index 52ee431f2e2c..eeb9ca38d2d8 100644 --- a/sound/hda/codecs/cm9825.c +++ b/sound/hda/codecs/cm9825.c @@ -488,7 +488,7 @@ static int cm9825_probe(struct hda_codec *codec, const struct hda_device_id *id) struct auto_pin_cfg *cfg; int err = 0; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (spec == NULL) return -ENOMEM; diff --git a/sound/hda/codecs/cmedia.c b/sound/hda/codecs/cmedia.c index 15e5a1118a6e..e6e12c01339f 100644 --- a/sound/hda/codecs/cmedia.c +++ b/sound/hda/codecs/cmedia.c @@ -24,7 +24,7 @@ static int cmedia_probe(struct hda_codec *codec, const struct hda_device_id *id) bool is_cmi8888 = id->vendor_id == 0x13f68888; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (spec == NULL) return -ENOMEM; diff --git a/sound/hda/codecs/conexant.c b/sound/hda/codecs/conexant.c index 5623d8c0a0f7..aa726eb323eb 100644 --- a/sound/hda/codecs/conexant.c +++ b/sound/hda/codecs/conexant.c @@ -299,6 +299,7 @@ enum { CXT_PINCFG_SWS_JS201D, CXT_PINCFG_TOP_SPEAKER, CXT_FIXUP_HP_A_U, + CXT_FIXUP_ACER_SWIFT_HP, }; /* for hda_fixup_thinkpad_acpi() */ @@ -1024,6 +1025,14 @@ static const struct hda_fixup cxt_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = cxt_fixup_hp_a_u, }, + [CXT_FIXUP_ACER_SWIFT_HP] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x16, 0x0321403f }, /* Headphone */ + { 0x19, 0x40f001f0 }, /* Mic */ + { } + }, + }, }; static const struct hda_quirk cxt5045_fixups[] = { @@ -1073,6 +1082,7 @@ static const struct hda_quirk cxt5066_fixups[] = { SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC), SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC), + SND_PCI_QUIRK(0x1025, 0x136d, "Acer Swift SF314", CXT_FIXUP_ACER_SWIFT_HP), SND_PCI_QUIRK(0x103c, 0x8079, "HP EliteBook 840 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x807C, "HP EliteBook 820 G3", CXT_FIXUP_HP_DOCK), SND_PCI_QUIRK(0x103c, 0x80FD, "HP ProBook 640 G2", CXT_FIXUP_HP_DOCK), @@ -1177,7 +1187,7 @@ static int cx_probe(struct hda_codec *codec, const struct hda_device_id *id) codec_info(codec, "%s: BIOS auto-probing.\n", codec->core.chip_name); - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(&spec->gen); diff --git a/sound/hda/codecs/generic.c b/sound/hda/codecs/generic.c index b75a5e9470df..092428ada29d 100644 --- a/sound/hda/codecs/generic.c +++ b/sound/hda/codecs/generic.c @@ -1991,7 +1991,7 @@ static int parse_output_paths(struct hda_codec *codec) bool best_wired = true, best_mio = true; bool hp_spk_swapped = false; struct auto_pin_cfg *best_cfg __free(kfree) = - kmalloc(sizeof(*best_cfg), GFP_KERNEL); + kmalloc_obj(*best_cfg); if (!best_cfg) return -ENOMEM; @@ -6095,7 +6095,7 @@ static int snd_hda_gen_probe(struct hda_codec *codec, struct hda_gen_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(spec); diff --git a/sound/hda/codecs/hdmi/hdmi.c b/sound/hda/codecs/hdmi/hdmi.c index 111c9b5335af..f20d1715da62 100644 --- a/sound/hda/codecs/hdmi/hdmi.c +++ b/sound/hda/codecs/hdmi/hdmi.c @@ -1557,6 +1557,7 @@ static const struct snd_pci_quirk force_connect_list[] = { SND_PCI_QUIRK(0x1043, 0x86ae, "ASUS", 1), /* Z170 PRO */ SND_PCI_QUIRK(0x1043, 0x86c7, "ASUS", 1), /* Z170M PLUS */ SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1), + SND_PCI_QUIRK(0x1558, 0x14a1, "TUXEDO InfinityBook S 14 Gen6", 1), SND_PCI_QUIRK(0x8086, 0x2060, "Intel NUC5CPYB", 1), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1), {} @@ -2104,7 +2105,7 @@ int snd_hda_hdmi_generic_alloc(struct hda_codec *codec) { struct hdmi_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; diff --git a/sound/hda/codecs/hdmi/simplehdmi.c b/sound/hda/codecs/hdmi/simplehdmi.c index 193c8dc882af..7bb002113898 100644 --- a/sound/hda/codecs/hdmi/simplehdmi.c +++ b/sound/hda/codecs/hdmi/simplehdmi.c @@ -175,7 +175,7 @@ int snd_hda_hdmi_simple_probe(struct hda_codec *codec, struct hdmi_spec_per_cvt *per_cvt; struct hdmi_spec_per_pin *per_pin; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; diff --git a/sound/hda/codecs/hdmi/tegrahdmi.c b/sound/hda/codecs/hdmi/tegrahdmi.c index 5f6fe31aa202..ebb6410a4831 100644 --- a/sound/hda/codecs/hdmi/tegrahdmi.c +++ b/sound/hda/codecs/hdmi/tegrahdmi.c @@ -299,6 +299,7 @@ static const struct hda_device_id snd_hda_id_tegrahdmi[] = { HDA_CODEC_ID_MODEL(0x10de002f, "Tegra194 HDMI/DP2", MODEL_TEGRA), HDA_CODEC_ID_MODEL(0x10de0030, "Tegra194 HDMI/DP3", MODEL_TEGRA), HDA_CODEC_ID_MODEL(0x10de0031, "Tegra234 HDMI/DP", MODEL_TEGRA234), + HDA_CODEC_ID_MODEL(0x10de0032, "Tegra238 HDMI/DP", MODEL_TEGRA234), HDA_CODEC_ID_MODEL(0x10de0033, "SoC 33 HDMI/DP", MODEL_TEGRA234), HDA_CODEC_ID_MODEL(0x10de0034, "Tegra264 HDMI/DP", MODEL_TEGRA234), HDA_CODEC_ID_MODEL(0x10de0035, "SoC 35 HDMI/DP", MODEL_TEGRA234), diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c index 80f0be13b69f..ab4b22fcb72e 100644 --- a/sound/hda/codecs/realtek/alc269.c +++ b/sound/hda/codecs/realtek/alc269.c @@ -1017,6 +1017,24 @@ static int alc269_resume(struct hda_codec *codec) return 0; } +#define STARLABS_STARFIGHTER_SHUTUP_DELAY_MS 30 + +static void starlabs_starfighter_shutup(struct hda_codec *codec) +{ + if (snd_hda_gen_shutup_speakers(codec)) + msleep(STARLABS_STARFIGHTER_SHUTUP_DELAY_MS); +} + +static void alc233_fixup_starlabs_starfighter(struct hda_codec *codec, + const struct hda_fixup *fix, + int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) + spec->shutup = starlabs_starfighter_shutup; +} + static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -3886,6 +3904,7 @@ enum { ALC294_FIXUP_ASUS_MIC, ALC294_FIXUP_ASUS_HEADSET_MIC, ALC294_FIXUP_ASUS_I2C_HEADSET_MIC, + ALC294_FIXUP_ASUS_SPI_HEADSET_MIC, ALC294_FIXUP_ASUS_SPK, ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE, ALC285_FIXUP_LENOVO_PC_BEEP_IN_NOISE, @@ -4039,6 +4058,7 @@ enum { ALC245_FIXUP_CLEVO_NOISY_MIC, ALC269_FIXUP_VAIO_VJFH52_MIC_NO_PRESENCE, ALC233_FIXUP_MEDION_MTL_SPK, + ALC233_FIXUP_STARLABS_STARFIGHTER, ALC294_FIXUP_BASS_SPEAKER_15, ALC283_FIXUP_DELL_HP_RESUME, ALC294_FIXUP_ASUS_CS35L41_SPI_2, @@ -4055,6 +4075,7 @@ enum { ALC236_FIXUP_HP_MUTE_LED_MICMUTE_GPIO, ALC233_FIXUP_LENOVO_GPIO2_MIC_HOTKEY, ALC245_FIXUP_BASS_HP_DAC, + ALC245_FIXUP_ACER_MICMUTE_LED, }; /* A special fixup for Lenovo C940 and Yoga Duet 7; @@ -5236,6 +5257,15 @@ static const struct hda_fixup alc269_fixups[] = { .chained = true, .chain_id = ALC287_FIXUP_CS35L41_I2C_2 }, + [ALC294_FIXUP_ASUS_SPI_HEADSET_MIC] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x04a11020 }, /* use as headset mic */ + { } + }, + .chained = true, + .chain_id = ALC245_FIXUP_CS35L41_SPI_2 + }, [ALC294_FIXUP_ASUS_SPK] = { .type = HDA_FIXUP_VERBS, .v.verbs = (const struct hda_verb[]) { @@ -6489,6 +6519,10 @@ static const struct hda_fixup alc269_fixups[] = { { } }, }, + [ALC233_FIXUP_STARLABS_STARFIGHTER] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc233_fixup_starlabs_starfighter, + }, [ALC294_FIXUP_BASS_SPEAKER_15] = { .type = HDA_FIXUP_FUNC, .v.func = alc294_fixup_bass_speaker_15, @@ -6566,6 +6600,12 @@ static const struct hda_fixup alc269_fixups[] = { /* Borrow the DAC routing selected for those Thinkpads */ .v.func = alc285_fixup_thinkpad_x1_gen7, }, + [ALC245_FIXUP_ACER_MICMUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_coef_micmute_led, + .chained = true, + .chain_id = ALC2XX_FIXUP_HEADSET_MIC, + } }; static const struct hda_quirk alc269_fixup_tbl[] = { @@ -6581,6 +6621,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS), SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x0840, "Acer Aspire E1", ALC269VB_FIXUP_ASPIRE_E1_COEF), + SND_PCI_QUIRK(0x1025, 0x0943, "Acer Aspire V3-572G", ALC269_FIXUP_ASPIRE_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x100c, "Acer Aspire E5-574G", ALC255_FIXUP_ACER_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x1025, 0x101c, "Acer Veriton N2510G", ALC269_FIXUP_LIFEBOOK), SND_PCI_QUIRK(0x1025, 0x102b, "Acer Aspire C24-860", ALC286_FIXUP_ACER_AIO_MIC_NO_PRESENCE), @@ -6617,6 +6658,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x159c, "Acer Nitro 5 AN515-58", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x1597, "Acer Nitro 5 AN517-55", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1025, 0x169a, "Acer Swift SFG16", ALC256_FIXUP_ACER_SFG16_MICMUTE_LED), + SND_PCI_QUIRK(0x1025, 0x171e, "Acer Nitro ANV15-51", ALC245_FIXUP_ACER_MICMUTE_LED), SND_PCI_QUIRK(0x1025, 0x1826, "Acer Helios ZPC", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), SND_PCI_QUIRK(0x1025, 0x182c, "Acer Helios ZPD", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), SND_PCI_QUIRK(0x1025, 0x1844, "Acer Helios ZPS", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2), @@ -6862,6 +6904,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8898, "HP EliteBook 845 G8 Notebook PC", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x88b3, "HP ENVY x360 Convertible 15-es0xxx", ALC245_FIXUP_HP_ENVY_X360_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x88d0, "HP Pavilion 15-eh1xxx (mainboard 88D0)", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x88d1, "HP Pavilion 15-eh1xxx (mainboard 88D1)", ALC245_FIXUP_HP_MUTE_LED_V1_COEFBIT), SND_PCI_QUIRK(0x103c, 0x88dd, "HP Pavilion 15z-ec200", ALC285_FIXUP_HP_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x88eb, "HP Victus 16-e0xxx", ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8902, "HP OMEN 16", ALC285_FIXUP_HP_MUTE_LED), @@ -6897,6 +6940,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x89da, "HP Spectre x360 14t-ea100", ALC245_FIXUP_HP_SPECTRE_X360_EU0XXX), SND_PCI_QUIRK(0x103c, 0x89e7, "HP Elite x2 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8a0f, "HP Pavilion 14-ec1xxx", ALC287_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8a1f, "HP Laptop 14s-dr5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8a20, "HP Laptop 15s-fq5xxx", ALC236_FIXUP_HP_MUTE_LED_COEFBIT2), SND_PCI_QUIRK(0x103c, 0x8a25, "HP Victus 16-d1xxx (MB 8A25)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), SND_PCI_QUIRK(0x103c, 0x8a26, "HP Victus 16-d1xxx (MB 8A26)", ALC245_FIXUP_HP_MUTE_LED_COEFBIT), @@ -7189,7 +7233,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x19ce, "ASUS B9450FA", ALC294_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x19e1, "ASUS UX581LV", ALC295_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), - SND_PCI_QUIRK(0x1043, 0x1a63, "ASUS UX3405MA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1a63, "ASUS UX3405MA", ALC294_FIXUP_ASUS_SPI_HEADSET_MIC), SND_PCI_QUIRK(0x1043, 0x1a83, "ASUS UM5302LA", ALC294_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1a8e, "ASUS G712LWS", ALC294_FIXUP_LENOVO_MIC_LOCATION), SND_PCI_QUIRK(0x1043, 0x1a8f, "ASUS UX582ZS", ALC245_FIXUP_CS35L41_SPI_2), @@ -7230,6 +7274,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1e93, "ASUS ExpertBook B9403CVAR", ALC294_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1eb3, "ASUS Ally RCLA72", ALC287_FIXUP_TAS2781_I2C), SND_PCI_QUIRK(0x1043, 0x1ed3, "ASUS HN7306W", ALC287_FIXUP_CS35L41_I2C_2), + HDA_CODEC_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC285_FIXUP_ASUS_I2C_SPEAKER2_TO_DAC1), SND_PCI_QUIRK(0x1043, 0x1ee2, "ASUS UM6702RA/RC", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1c52, "ASUS Zephyrus G15 2022", ALC289_FIXUP_ASUS_GA401), SND_PCI_QUIRK(0x1043, 0x1f11, "ASUS Zephyrus G14", ALC289_FIXUP_ASUS_GA401), @@ -7301,7 +7346,8 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc109, "Samsung Ativ book 9 (NP900X3G)", ALC269_FIXUP_INV_DMIC), SND_PCI_QUIRK(0x144d, 0xc169, "Samsung Notebook 9 Pen (NP930SBE-K01US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc176, "Samsung Notebook 9 Pro (NP930MBE-K04US)", ALC298_FIXUP_SAMSUNG_AMP), - SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Flex Book (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xc188, "Samsung Galaxy Book Flex (NT950QCT-A38A)", ALC298_FIXUP_SAMSUNG_AMP), + SND_PCI_QUIRK(0x144d, 0xc189, "Samsung Galaxy Book Flex (NT950QCG-X716)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc18a, "Samsung Galaxy Book Ion (NP930XCJ-K01US)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc1a3, "Samsung Galaxy Book Pro (NP935XDB-KC1SE)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc1a4, "Samsung Galaxy Book Pro 360 (NT935QBD)", ALC298_FIXUP_SAMSUNG_AMP), @@ -7318,7 +7364,9 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc872, "Samsung Galaxy Book2 Pro (NP950XEE)", ALC298_FIXUP_SAMSUNG_AMP_V2_2_AMPS), SND_PCI_QUIRK(0x144d, 0xc886, "Samsung Galaxy Book3 Pro (NP964XFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x144d, 0xc1ca, "Samsung Galaxy Book3 Pro 360 (NP960QFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), + SND_PCI_QUIRK(0x144d, 0xc1cb, "Samsung Galaxy Book3 Pro 360 (NP965QFG)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), SND_PCI_QUIRK(0x144d, 0xc1cc, "Samsung Galaxy Book3 Ultra (NT960XFH)", ALC298_FIXUP_SAMSUNG_AMP_V2_4_AMPS), + SND_PCI_QUIRK(0x1458, 0x900e, "Gigabyte G5 KF5 (2023)", ALC2XX_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), @@ -7447,6 +7495,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x224c, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x224d, "Thinkpad", ALC298_FIXUP_TPT470_DOCK), SND_PCI_QUIRK(0x17aa, 0x225d, "Thinkpad T480", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), + SND_PCI_QUIRK(0x17aa, 0x2288, "Thinkpad X390", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), SND_PCI_QUIRK(0x17aa, 0x2292, "Thinkpad X1 Carbon 7th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), SND_PCI_QUIRK(0x17aa, 0x22be, "Thinkpad X1 Carbon 8th", ALC285_FIXUP_THINKPAD_HEADSET_JACK), SND_PCI_QUIRK(0x17aa, 0x22c1, "Thinkpad P1 Gen 3", ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK), @@ -7639,6 +7688,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x2782, 0x1705, "MEDION E15433", ALC269VC_FIXUP_INFINIX_Y4_MAX), SND_PCI_QUIRK(0x2782, 0x1707, "Vaio VJFE-ADL", ALC298_FIXUP_SPK_VOLUME), SND_PCI_QUIRK(0x2782, 0x4900, "MEDION E15443", ALC233_FIXUP_MEDION_MTL_SPK), + SND_PCI_QUIRK(0x7017, 0x2014, "Star Labs StarFighter", ALC233_FIXUP_STARLABS_STARFIGHTER), SND_PCI_QUIRK(0x8086, 0x2074, "Intel NUC 8", ALC233_FIXUP_INTEL_NUC8_DMIC), SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", ALC256_FIXUP_INTEL_NUC10), @@ -7735,6 +7785,7 @@ static const struct hda_model_fixup alc269_fixup_models[] = { {.id = ALC298_FIXUP_TPT470_DOCK_FIX, .name = "tpt470-dock-fix"}, {.id = ALC298_FIXUP_TPT470_DOCK, .name = "tpt470-dock"}, {.id = ALC233_FIXUP_LENOVO_MULTI_CODECS, .name = "dual-codecs"}, + {.id = ALC233_FIXUP_STARLABS_STARFIGHTER, .name = "starlabs-starfighter"}, {.id = ALC700_FIXUP_INTEL_REFERENCE, .name = "alc700-ref"}, {.id = ALC269_FIXUP_SONY_VAIO, .name = "vaio"}, {.id = ALC269_FIXUP_DELL_M101Z, .name = "dell-m101z"}, diff --git a/sound/hda/codecs/realtek/alc662.c b/sound/hda/codecs/realtek/alc662.c index 5073165d1f3c..3a943adf9087 100644 --- a/sound/hda/codecs/realtek/alc662.c +++ b/sound/hda/codecs/realtek/alc662.c @@ -313,6 +313,7 @@ enum { ALC897_FIXUP_HEADSET_MIC_PIN2, ALC897_FIXUP_UNIS_H3C_X500S, ALC897_FIXUP_HEADSET_MIC_PIN3, + ALC897_FIXUP_H610M_HP_PIN, }; static const struct hda_fixup alc662_fixups[] = { @@ -766,6 +767,13 @@ static const struct hda_fixup alc662_fixups[] = { { } }, }, + [ALC897_FIXUP_H610M_HP_PIN] = { + .type = HDA_FIXUP_PINS, + .v.pins = (const struct hda_pintbl[]) { + { 0x19, 0x0321403f }, /* HP out */ + { } + }, + }, }; static const struct hda_quirk alc662_fixup_tbl[] = { @@ -815,6 +823,7 @@ static const struct hda_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x1458, 0xa194, "H610M H V2 DDR4", ALC897_FIXUP_H610M_HP_PIN), SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), SND_PCI_QUIRK(0x17aa, 0x1057, "Lenovo P360", ALC897_FIXUP_HEADSET_MIC_PIN), diff --git a/sound/hda/codecs/realtek/realtek.c b/sound/hda/codecs/realtek/realtek.c index efe20b450529..aad265c0a5b6 100644 --- a/sound/hda/codecs/realtek/realtek.c +++ b/sound/hda/codecs/realtek/realtek.c @@ -221,7 +221,7 @@ void alc_update_knob_master(struct hda_codec *codec, return; struct snd_ctl_elem_value *uctl __free(kfree) = - kzalloc(sizeof(*uctl), GFP_KERNEL); + kzalloc_obj(*uctl); if (!uctl) return; val = snd_hda_codec_read(codec, jack->nid, 0, @@ -1028,7 +1028,7 @@ EXPORT_SYMBOL_NS_GPL(alc_parse_auto_config, "SND_HDA_CODEC_REALTEK"); /* common preparation job for alc_spec */ int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) { - struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); + struct alc_spec *spec = kzalloc_obj(*spec); int err; if (!spec) diff --git a/sound/hda/codecs/senarytech.c b/sound/hda/codecs/senarytech.c index 63cda57cf786..6239a25bb8f3 100644 --- a/sound/hda/codecs/senarytech.c +++ b/sound/hda/codecs/senarytech.c @@ -19,15 +19,13 @@ #include "hda_jack.h" #include "generic.h" -/* GPIO node ID */ -#define SENARY_GPIO_NODE 0x01 - struct senary_spec { struct hda_gen_spec gen; /* extra EAPD pins */ unsigned int num_eapds; hda_nid_t eapds[4]; + bool dynamic_eapd; hda_nid_t mute_led_eapd; unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ @@ -123,19 +121,23 @@ static void senary_init_gpio_led(struct hda_codec *codec) unsigned int mask = spec->gpio_mute_led_mask | spec->gpio_mic_led_mask; if (mask) { - snd_hda_codec_write(codec, SENARY_GPIO_NODE, 0, AC_VERB_SET_GPIO_MASK, + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_MASK, mask); - snd_hda_codec_write(codec, SENARY_GPIO_NODE, 0, AC_VERB_SET_GPIO_DIRECTION, + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DIRECTION, mask); - snd_hda_codec_write(codec, SENARY_GPIO_NODE, 0, AC_VERB_SET_GPIO_DATA, + snd_hda_codec_write(codec, codec->core.afg, 0, AC_VERB_SET_GPIO_DATA, spec->gpio_led); } } static int senary_init(struct hda_codec *codec) { + struct senary_spec *spec = codec->spec; + snd_hda_gen_init(codec); senary_init_gpio_led(codec); + if (!spec->dynamic_eapd) + senary_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); return 0; @@ -170,7 +172,7 @@ static int senary_probe(struct hda_codec *codec, const struct hda_device_id *id) codec_info(codec, "%s: BIOS auto-probing.\n", codec->core.chip_name); - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(&spec->gen); diff --git a/sound/hda/codecs/si3054.c b/sound/hda/codecs/si3054.c index 87cf9da9f3bf..471260e8deb1 100644 --- a/sound/hda/codecs/si3054.c +++ b/sound/hda/codecs/si3054.c @@ -256,7 +256,7 @@ static void si3054_remove(struct hda_codec *codec) static int si3054_probe(struct hda_codec *codec, const struct hda_device_id *id) { - codec->spec = kzalloc(sizeof(struct si3054_spec), GFP_KERNEL); + codec->spec = kzalloc_obj(struct si3054_spec); if (!codec->spec) return -ENOMEM; return 0; diff --git a/sound/hda/codecs/side-codecs/cs35l56_hda.c b/sound/hda/codecs/side-codecs/cs35l56_hda.c index cfc8de2ae499..1ace4beef508 100644 --- a/sound/hda/codecs/side-codecs/cs35l56_hda.c +++ b/sound/hda/codecs/side-codecs/cs35l56_hda.c @@ -249,7 +249,7 @@ static int cs35l56_hda_posture_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol); - unsigned long pos = ucontrol->value.integer.value[0]; + long pos = ucontrol->value.integer.value[0]; bool changed; int ret; @@ -403,10 +403,6 @@ static void cs35l56_hda_remove_controls(struct cs35l56_hda *cs35l56) snd_ctl_remove(cs35l56->codec->card, cs35l56->volume_ctl); } -static const struct cs_dsp_client_ops cs35l56_hda_client_ops = { - /* cs_dsp requires the client to provide this even if it is empty */ -}; - static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56, const struct firmware **firmware, char **filename, const char *base_name, const char *system_name, @@ -1149,7 +1145,6 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id) cs35l56->base.cal_index = cs35l56->index; cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp); - cs35l56->cs_dsp.client_ops = &cs35l56_hda_client_ops; if (cs35l56->base.reset_gpio) { dev_dbg(cs35l56->base.dev, "Hard reset\n"); diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c index 74c3cf1e45e1..67240ce184e1 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_i2c.c @@ -60,7 +60,6 @@ struct tas2781_hda_i2c_priv { int (*save_calibration)(struct tas2781_hda *h); int hda_chip_id; - bool skip_calibration; }; static int tas2781_get_i2c_res(struct acpi_resource *ares, void *data) @@ -479,8 +478,7 @@ static void tasdevice_dspfw_init(void *context) /* If calibrated data occurs error, dsp will still works with default * calibrated data inside algo. */ - if (!hda_priv->skip_calibration) - hda_priv->save_calibration(tas_hda); + hda_priv->save_calibration(tas_hda); } static void tasdev_fw_ready(const struct firmware *fmw, void *context) @@ -535,7 +533,6 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, void *master_data) { struct tas2781_hda *tas_hda = dev_get_drvdata(dev); - struct tas2781_hda_i2c_priv *hda_priv = tas_hda->hda_priv; struct hda_component_parent *parent = master_data; struct hda_component *comp; struct hda_codec *codec; @@ -564,14 +561,6 @@ static int tas2781_hda_bind(struct device *dev, struct device *master, break; } - /* - * Using ASUS ROG Xbox Ally X (RC73XA) UEFI calibration data - * causes audio dropouts during playback, use fallback data - * from DSP firmware as a workaround. - */ - if (codec->core.subsystem_id == 0x10431384) - hda_priv->skip_calibration = true; - guard(pm_runtime_active_auto)(dev); comp->dev = dev; @@ -643,6 +632,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) */ device_name = "TIAS2781"; hda_priv->hda_chip_id = HDA_TAS2781; + tas_hda->priv->chip_id = TAS2781; hda_priv->save_calibration = tas2781_save_calibration; tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR; } else if (strstarts(dev_name(&clt->dev), "i2c-TXNW2770")) { @@ -656,6 +646,7 @@ static int tas2781_hda_i2c_probe(struct i2c_client *clt) "i2c-TXNW2781:00-tas2781-hda.0")) { device_name = "TXNW2781"; hda_priv->hda_chip_id = HDA_TAS2781; + tas_hda->priv->chip_id = TAS2781; hda_priv->save_calibration = tas2781_save_calibration; tas_hda->priv->global_addr = TAS2781_GLOBAL_ADDR; } else if (strstr(dev_name(&clt->dev), "INT8866")) { diff --git a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c index 0c9b57b6ff55..f860e0eb7602 100644 --- a/sound/hda/codecs/side-codecs/tas2781_hda_spi.c +++ b/sound/hda/codecs/side-codecs/tas2781_hda_spi.c @@ -631,7 +631,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) struct tasdevice_priv *tas_priv = context; struct tas2781_hda *tas_hda = dev_get_drvdata(tas_priv->dev); struct hda_codec *codec = tas_priv->codec; - int ret, val; + int ret; guard(pm_runtime_active_auto)(tas_priv->dev); guard(mutex)(&tas_priv->codec_lock); @@ -670,20 +670,14 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context) tas_priv->rcabin.profile_cfg_id = 0; tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; - ret = tasdevice_spi_dev_read(tas_priv, tas_priv->index, - TAS2781_REG_CLK_CONFIG, &val); - if (ret < 0) - goto out; - if (val == TAS2781_REG_CLK_CONFIG_RESET) { - ret = tasdevice_prmg_load(tas_priv, 0); - if (ret < 0) { - dev_err(tas_priv->dev, "FW download failed = %d\n", - ret); - goto out; - } - tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; + ret = tasdevice_prmg_load(tas_priv, 0); + if (ret < 0) { + dev_err(tas_priv->dev, "FW download failed = %d\n", ret); + goto out; } + tas_priv->fw_state = TASDEVICE_DSP_FW_ALL_OK; + if (tas_priv->fmw->nr_programs > 0) tas_priv->tasdevice[tas_priv->index].cur_prog = 0; if (tas_priv->fmw->nr_configurations > 0) diff --git a/sound/hda/codecs/sigmatel.c b/sound/hda/codecs/sigmatel.c index ecbee408d771..acbbc7c3508b 100644 --- a/sound/hda/codecs/sigmatel.c +++ b/sound/hda/codecs/sigmatel.c @@ -4456,7 +4456,7 @@ static int alloc_stac_spec(struct hda_codec *codec) { struct sigmatel_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(&spec->gen); diff --git a/sound/hda/codecs/via.c b/sound/hda/codecs/via.c index 6becea9bb810..807312cffd35 100644 --- a/sound/hda/codecs/via.c +++ b/sound/hda/codecs/via.c @@ -102,7 +102,7 @@ static struct via_spec *via_new_spec(struct hda_codec *codec) { struct via_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (spec == NULL) return NULL; diff --git a/sound/hda/common/beep.c b/sound/hda/common/beep.c index 13a7d92e8d8d..4cb21ec9035c 100644 --- a/sound/hda/common/beep.c +++ b/sound/hda/common/beep.c @@ -220,7 +220,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) return 0; /* disabled by module option */ } - beep = kzalloc(sizeof(*beep), GFP_KERNEL); + beep = kzalloc_obj(*beep); if (beep == NULL) return -ENOMEM; snprintf(beep->phys, sizeof(beep->phys), diff --git a/sound/hda/common/codec.c b/sound/hda/common/codec.c index ffe7c69d5a32..09b1329bb8f3 100644 --- a/sound/hda/common/codec.c +++ b/sound/hda/common/codec.c @@ -117,7 +117,7 @@ static int add_conn_list(struct hda_codec *codec, hda_nid_t nid, int len, { struct hda_conn_list *p; - p = kmalloc(struct_size(p, conns, len), GFP_KERNEL); + p = kmalloc_flex(*p, conns, len); if (!p) return -ENOMEM; p->len = len; @@ -147,7 +147,7 @@ static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid) len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list)); if (len == -ENOSPC) { len = snd_hda_get_num_raw_conns(codec, nid); - result = kmalloc_array(len, sizeof(hda_nid_t), GFP_KERNEL); + result = kmalloc_objs(hda_nid_t, len); if (!result) return -ENOMEM; len = snd_hda_get_raw_connections(codec, nid, result, len); @@ -703,7 +703,7 @@ struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, struct hda_pcm *pcm; va_list args; - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + pcm = kzalloc_obj(*pcm); if (!pcm) return NULL; @@ -895,7 +895,7 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr, if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) return ERR_PTR(-EINVAL); - codec = kzalloc(sizeof(*codec), GFP_KERNEL); + codec = kzalloc_obj(*codec); if (!codec) return ERR_PTR(-ENOMEM); @@ -1855,7 +1855,7 @@ static int check_follower_present(struct hda_codec *codec, static int put_kctl_with_value(struct snd_kcontrol *kctl, int val) { struct snd_ctl_elem_value *ucontrol __free(kfree) = - kzalloc(sizeof(*ucontrol), GFP_KERNEL); + kzalloc_obj(*ucontrol); if (!ucontrol) return -ENOMEM; diff --git a/sound/hda/common/controller.c b/sound/hda/common/controller.c index b1cfd9bd4dcb..5934e5cdfdfd 100644 --- a/sound/hda/common/controller.c +++ b/sound/hda/common/controller.c @@ -715,7 +715,7 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec, if (err < 0) return err; strscpy(pcm->name, cpcm->name, sizeof(pcm->name)); - apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); + apcm = kzalloc_obj(*apcm); if (apcm == NULL) { snd_device_free(chip->card, pcm); return -ENOMEM; @@ -1283,7 +1283,7 @@ int azx_init_streams(struct azx *chip) * and initialize */ for (i = 0; i < chip->num_streams; i++) { - struct azx_dev *azx_dev = kzalloc(sizeof(*azx_dev), GFP_KERNEL); + struct azx_dev *azx_dev = kzalloc_obj(*azx_dev); int dir, tag; if (!azx_dev) diff --git a/sound/hda/common/jack.c b/sound/hda/common/jack.c index 7d7786df60ea..98ba1c4d5ba4 100644 --- a/sound/hda/common/jack.c +++ b/sound/hda/common/jack.c @@ -329,7 +329,7 @@ snd_hda_jack_detect_enable_callback_mst(struct hda_codec *codec, hda_nid_t nid, callback = find_callback_from_list(jack, func); if (func && !callback) { - callback = kzalloc(sizeof(*callback), GFP_KERNEL); + callback = kzalloc_obj(*callback); if (!callback) return ERR_PTR(-ENOMEM); callback->func = func; diff --git a/sound/hda/common/proc.c b/sound/hda/common/proc.c index 5f3f61519ba6..3bc33c5617b2 100644 --- a/sound/hda/common/proc.c +++ b/sound/hda/common/proc.c @@ -689,7 +689,7 @@ static void print_dpmst_connections(struct snd_info_buffer *buffer, struct hda_c if (conn_len <= 0) return; - conn = kmalloc_array(conn_len, sizeof(hda_nid_t), GFP_KERNEL); + conn = kmalloc_objs(hda_nid_t, conn_len); if (!conn) return; @@ -845,9 +845,7 @@ static void print_codec_info(struct snd_info_entry *entry, if (wid_caps & AC_WCAP_CONN_LIST) { conn_len = snd_hda_get_num_raw_conns(codec, nid); if (conn_len > 0) { - conn = kmalloc_array(conn_len, - sizeof(hda_nid_t), - GFP_KERNEL); + conn = kmalloc_objs(hda_nid_t, conn_len); if (!conn) return; if (snd_hda_get_raw_connections(codec, nid, conn, diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c index 6fddf400c4a3..3f434994c18d 100644 --- a/sound/hda/controllers/intel.c +++ b/sound/hda/controllers/intel.c @@ -1751,6 +1751,8 @@ static int default_bdl_pos_adj(struct azx *chip) return 1; case AZX_DRIVER_ZHAOXINHDMI: return 128; + case AZX_DRIVER_NVIDIA: + return 64; default: return 32; } diff --git a/sound/hda/core/ext/controller.c b/sound/hda/core/ext/controller.c index 9eea3ea2dae0..b1f1eff1d181 100644 --- a/sound/hda/core/ext/controller.c +++ b/sound/hda/core/ext/controller.c @@ -89,7 +89,7 @@ int snd_hdac_ext_bus_get_ml_capabilities(struct hdac_bus *bus) dev_dbg(bus->dev, "In %s Link count: %d\n", __func__, link_count); for (idx = 0; idx < link_count; idx++) { - hlink = kzalloc(sizeof(*hlink), GFP_KERNEL); + hlink = kzalloc_obj(*hlink); if (!hlink) return -ENOMEM; hlink->index = idx; diff --git a/sound/hda/core/ext/stream.c b/sound/hda/core/ext/stream.c index b4759198e51d..4c7506d49f55 100644 --- a/sound/hda/core/ext/stream.c +++ b/sound/hda/core/ext/stream.c @@ -101,8 +101,7 @@ int snd_hdac_ext_stream_init_all(struct hdac_bus *bus, int start_idx, setup_op = snd_hdac_stream_setup; for (i = 0; i < num_stream; i++) { - struct hdac_ext_stream *hext_stream = - kzalloc(sizeof(*hext_stream), GFP_KERNEL); + struct hdac_ext_stream *hext_stream = kzalloc_obj(*hext_stream); if (!hext_stream) return -ENOMEM; tag = ++stream_tag; diff --git a/sound/hda/core/sysfs.c b/sound/hda/core/sysfs.c index bffe52859dba..3e102538e058 100644 --- a/sound/hda/core/sysfs.c +++ b/sound/hda/core/sysfs.c @@ -339,7 +339,7 @@ static int add_widget_node(struct kobject *parent, hda_nid_t nid, const struct attribute_group *group, struct kobject **res) { - struct kobject *kobj = kzalloc(sizeof(*kobj), GFP_KERNEL); + struct kobject *kobj = kzalloc_obj(*kobj); int err; if (!kobj) @@ -366,7 +366,7 @@ static int widget_tree_create(struct hdac_device *codec) int i, err; hda_nid_t nid; - tree = codec->widgets = kzalloc(sizeof(*tree), GFP_KERNEL); + tree = codec->widgets = kzalloc_obj(*tree); if (!tree) return -ENOMEM; @@ -374,8 +374,7 @@ static int widget_tree_create(struct hdac_device *codec) if (!tree->root) return -ENOMEM; - tree->nodes = kcalloc(codec->num_nodes + 1, sizeof(*tree->nodes), - GFP_KERNEL); + tree->nodes = kzalloc_objs(*tree->nodes, codec->num_nodes + 1); if (!tree->nodes) return -ENOMEM; @@ -436,7 +435,7 @@ int hda_widget_sysfs_reinit(struct hdac_device *codec, if (!tree) return -ENOMEM; - tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL); + tree->nodes = kzalloc_objs(*tree->nodes, num_nodes + 1); if (!tree->nodes) { kfree(tree); return -ENOMEM; diff --git a/sound/hda/core/trace.c b/sound/hda/core/trace.c index ca2d6bd94518..c18759ca48ea 100644 --- a/sound/hda/core/trace.c +++ b/sound/hda/core/trace.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * tracepoint definitions for HD-audio core drivers */ diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c index 46f081268348..1de985ba85d9 100644 --- a/sound/i2c/cs8427.c +++ b/sound/i2c/cs8427.c @@ -269,7 +269,7 @@ int snd_cs8427_create(struct snd_i2c_bus *bus, &device); if (err < 0) return err; - chip = device->private_data = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = device->private_data = kzalloc_obj(*chip); if (chip == NULL) { snd_i2c_device_free(device); return -ENOMEM; diff --git a/sound/i2c/i2c.c b/sound/i2c/i2c.c index 847e3b6ca601..46b201188c56 100644 --- a/sound/i2c/i2c.c +++ b/sound/i2c/i2c.c @@ -72,7 +72,7 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name, }; *ri2c = NULL; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (bus == NULL) return -ENOMEM; mutex_init(&bus->lock_mutex); @@ -104,7 +104,7 @@ int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name, *rdevice = NULL; if (snd_BUG_ON(!bus)) return -EINVAL; - device = kzalloc(sizeof(*device), GFP_KERNEL); + device = kzalloc_obj(*device); if (device == NULL) return -ENOMEM; device->addr = addr; diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index 70b3f7e17f9e..6ef5fffda8d7 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c @@ -64,7 +64,7 @@ int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, .dev_free = snd_ak4113_dev_free, }; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->lock); diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index 0e3a272c1490..71efb29b6c7c 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c @@ -64,7 +64,7 @@ int snd_ak4114_create(struct snd_card *card, .dev_free = snd_ak4114_dev_free, }; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->lock); diff --git a/sound/i2c/other/ak4117.c b/sound/i2c/other/ak4117.c index d2ec20f885f0..7ff3730d2a64 100644 --- a/sound/i2c/other/ak4117.c +++ b/sound/i2c/other/ak4117.c @@ -57,7 +57,7 @@ int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t .dev_free = snd_ak4117_dev_free, }; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; spin_lock_init(&chip->lock); diff --git a/sound/i2c/tea6330t.c b/sound/i2c/tea6330t.c index 676d58054944..e8c50a036bea 100644 --- a/sound/i2c/tea6330t.c +++ b/sound/i2c/tea6330t.c @@ -285,7 +285,7 @@ int snd_tea6330t_update_mixer(struct snd_card *card, u8 default_treble, default_bass; unsigned char bytes[7]; - tea = kzalloc(sizeof(*tea), GFP_KERNEL); + tea = kzalloc_obj(*tea); if (tea == NULL) return -ENOMEM; err = snd_i2c_device_create(bus, "TEA6330T", TEA6330T_ADDR, &device); diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 5f50a39c6f16..b2b189c83569 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c @@ -116,7 +116,7 @@ int snd_gus_create(struct snd_card *card, }; *rgus = NULL; - gus = kzalloc(sizeof(*gus), GFP_KERNEL); + gus = kzalloc_obj(*gus); if (gus == NULL) return -ENOMEM; spin_lock_init(&gus->reg_lock); diff --git a/sound/isa/gus/gus_mem.c b/sound/isa/gus/gus_mem.c index 8d95d8d5abdf..927a2bc80511 100644 --- a/sound/isa/gus/gus_mem.c +++ b/sound/isa/gus/gus_mem.c @@ -21,7 +21,7 @@ snd_gf1_mem_xalloc(struct snd_gf1_mem *alloc, struct snd_gf1_mem_block *block, { struct snd_gf1_mem_block *pblock, *nblock; - nblock = kmalloc(sizeof(struct snd_gf1_mem_block), GFP_KERNEL); + nblock = kmalloc_obj(struct snd_gf1_mem_block); if (nblock == NULL) return NULL; *nblock = *block; diff --git a/sound/isa/gus/gus_mem_proc.c b/sound/isa/gus/gus_mem_proc.c index b5e1d1649500..04c212882718 100644 --- a/sound/isa/gus/gus_mem_proc.c +++ b/sound/isa/gus/gus_mem_proc.c @@ -50,7 +50,7 @@ int snd_gf1_mem_proc_init(struct snd_gus_card * gus) for (idx = 0; idx < 4; idx++) { if (gus->gf1.mem_alloc.banks_8[idx].size > 0) { - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return -ENOMEM; priv->gus = gus; @@ -67,7 +67,7 @@ int snd_gf1_mem_proc_init(struct snd_gus_card * gus) } for (idx = 0; idx < 4; idx++) { if (gus->gf1.rom_present & (1 << idx)) { - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc_obj(*priv); if (priv == NULL) return -ENOMEM; priv->rom = 1; diff --git a/sound/isa/gus/gus_pcm.c b/sound/isa/gus/gus_pcm.c index 9249cbff30f3..caf371897b78 100644 --- a/sound/isa/gus/gus_pcm.c +++ b/sound/isa/gus/gus_pcm.c @@ -638,7 +638,7 @@ static int snd_gf1_pcm_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - pcmp = kzalloc(sizeof(*pcmp), GFP_KERNEL); + pcmp = kzalloc_obj(*pcmp); if (pcmp == NULL) return -ENOMEM; pcmp->gus = gus; diff --git a/sound/isa/gus/interwave-stb.c b/sound/isa/gus/interwave-stb.c index dbe4f48a9846..9b3468c8bc43 100644 --- a/sound/isa/gus/interwave-stb.c +++ b/sound/isa/gus/interwave-stb.c @@ -1,2 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 #define SNDRV_STB #include "interwave.c" diff --git a/sound/isa/msnd/msnd_classic.c b/sound/isa/msnd/msnd_classic.c index 3b23a096fa4e..9c37c9fb94ab 100644 --- a/sound/isa/msnd/msnd_classic.c +++ b/sound/isa/msnd/msnd_classic.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* The work is in msnd_pinnacle.c, just define MSND_CLASSIC before it. */ #define MSND_CLASSIC #include "msnd_pinnacle.c" diff --git a/sound/isa/opti9xx/opti92x-cs4231.c b/sound/isa/opti9xx/opti92x-cs4231.c index b17ab19f6d81..e27dc9093c02 100644 --- a/sound/isa/opti9xx/opti92x-cs4231.c +++ b/sound/isa/opti9xx/opti92x-cs4231.c @@ -1,2 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 #define CS4231 #include "opti92x-ad1848.c" diff --git a/sound/isa/opti9xx/opti93x.c b/sound/isa/opti9xx/opti93x.c index bad9da521bf9..cd1fa4635b26 100644 --- a/sound/isa/opti9xx/opti93x.c +++ b/sound/isa/opti9xx/opti93x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 #define OPTi93X #include "opti92x-ad1848.c" diff --git a/sound/isa/sb/emu8000_pcm.c b/sound/isa/sb/emu8000_pcm.c index 656a655d618d..d2ca70aad162 100644 --- a/sound/isa/sb/emu8000_pcm.c +++ b/sound/isa/sb/emu8000_pcm.c @@ -221,7 +221,7 @@ static int emu8k_pcm_open(struct snd_pcm_substream *subs) struct snd_emu8k_pcm *rec; struct snd_pcm_runtime *runtime = subs->runtime; - rec = kzalloc(sizeof(*rec), GFP_KERNEL); + rec = kzalloc_obj(*rec); if (! rec) return -ENOMEM; diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c index 69d9bfb6c14c..3f2a5c4e47a7 100644 --- a/sound/isa/sb/jazz16.c +++ b/sound/isa/sb/jazz16.c @@ -1,14 +1,9 @@ - +// SPDX-License-Identifier: GPL-2.0 /* * jazz16.c - driver for Media Vision Jazz16 based soundcards. * Copyright (C) 2009 Krzysztof Helt * Based on patches posted by Rask Ingemann Lambertsen and Rene Herman. * Based on OSS Sound Blaster driver. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive for - * more details. - * */ #include diff --git a/sound/isa/sb/sb16_csp.c b/sound/isa/sb/sb16_csp.c index 9ad71a9fc18d..bece60051e41 100644 --- a/sound/isa/sb/sb16_csp.c +++ b/sound/isa/sb/sb16_csp.c @@ -117,7 +117,7 @@ int snd_sb_csp_new(struct snd_sb *chip, int device, struct snd_hwdep ** rhwdep) if (err < 0) return err; - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) { snd_device_free(chip->card, hw); return -ENOMEM; diff --git a/sound/isa/sb/sbawe.c b/sound/isa/sb/sbawe.c index 2ec52a3473a2..1e00a6b4a1bd 100644 --- a/sound/isa/sb/sbawe.c +++ b/sound/isa/sb/sbawe.c @@ -1,2 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 #define SNDRV_SBAWE #include "sb16.c" diff --git a/sound/isa/wavefront/wavefront_synth.c b/sound/isa/wavefront/wavefront_synth.c index 0d78533e1cfd..33b563707a58 100644 --- a/sound/isa/wavefront/wavefront_synth.c +++ b/sound/isa/wavefront/wavefront_synth.c @@ -1381,7 +1381,7 @@ wavefront_load_patch (snd_wavefront_t *dev, const char __user *addr) wavefront_patch_info *header; int err; - header = kmalloc(sizeof(*header), GFP_KERNEL); + header = kmalloc_obj(*header); if (! header) return -ENOMEM; diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index f88e6a6733a5..2beb6a0dc3b7 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c @@ -773,7 +773,7 @@ static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip) struct hpc3_regs *hpc3 = hpc3c0; int err; - hal2 = kzalloc(sizeof(*hal2), GFP_KERNEL); + hal2 = kzalloc_obj(*hal2); if (!hal2) return -ENOMEM; diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 077fdf2181c1..497d84cff12f 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c @@ -788,7 +788,7 @@ static int snd_sgio2audio_create(struct snd_card *card, if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) return -ENOENT; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index dea2d9b18fc9..a718b75bb6a0 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * linux/sound/oss/dmasound/dmasound_core.c * @@ -21,10 +22,6 @@ * /dev/sndstat is based on code by Hannu Savolainen, the author of the * VoxWare family of drivers. * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file COPYING in the main directory of this archive - * for more details. - * * History: * * 1995/8/25 First release diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c index 4b5a54da25fb..fb40476c6c91 100644 --- a/sound/parisc/harmony.c +++ b/sound/parisc/harmony.c @@ -852,7 +852,7 @@ snd_harmony_create(struct snd_card *card, *rchip = NULL; - h = kzalloc(sizeof(*h), GFP_KERNEL); + h = kzalloc_obj(*h); if (h == NULL) return -ENOMEM; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index c54bdefa5afe..0bb65be021d9 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1957,7 +1957,7 @@ int snd_ac97_bus(struct snd_card *card, int num, if (snd_BUG_ON(!card)) return -EINVAL; - bus = kzalloc(sizeof(*bus), GFP_KERNEL); + bus = kzalloc_obj(*bus); if (bus == NULL) return -ENOMEM; bus->card = card; @@ -2069,7 +2069,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, return -EBUSY; card = bus->card; - ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); + ac97 = kzalloc_obj(*ac97); if (ac97 == NULL) return -ENOMEM; ac97->private_data = template->private_data; diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 4715d88ff8f4..cbfbabb02818 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c @@ -441,7 +441,7 @@ int snd_ac97_pcm_assign(struct snd_ac97_bus *bus, unsigned int rates; struct snd_ac97 *codec; - rpcms = kcalloc(pcms_count, sizeof(struct ac97_pcm), GFP_KERNEL); + rpcms = kzalloc_objs(struct ac97_pcm, pcms_count); if (rpcms == NULL) return -ENOMEM; memset(avail_slots, 0, sizeof(avail_slots)); diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c index cdad47e4098d..6f35b616efc6 100644 --- a/sound/pci/ak4531_codec.c +++ b/sound/pci/ak4531_codec.c @@ -373,7 +373,7 @@ int snd_ak4531_mixer(struct snd_card *card, return -EINVAL; if (rak4531) *rak4531 = NULL; - ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); + ak4531 = kzalloc_obj(*ak4531); if (ak4531 == NULL) return -ENOMEM; *ak4531 = *_ak4531; diff --git a/sound/pci/als300.c b/sound/pci/als300.c index 733e84def5a7..a73893a2cbd6 100644 --- a/sound/pci/als300.c +++ b/sound/pci/als300.c @@ -342,8 +342,7 @@ static int snd_als300_playback_open(struct snd_pcm_substream *substream) { struct snd_als300 *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_als300_substream_data *data = kzalloc(sizeof(*data), - GFP_KERNEL); + struct snd_als300_substream_data *data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -370,8 +369,7 @@ static int snd_als300_capture_open(struct snd_pcm_substream *substream) { struct snd_als300 *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_als300_substream_data *data = kzalloc(sizeof(*data), - GFP_KERNEL); + struct snd_als300_substream_data *data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index fd0a67b772d1..3a64d0562803 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c @@ -975,7 +975,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_hardware snd_card_asihpi_playback; int err; - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); + dpcm = kzalloc_obj(*dpcm); if (dpcm == NULL) return -ENOMEM; @@ -1145,7 +1145,7 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_hardware snd_card_asihpi_capture; int err; - dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL); + dpcm = kzalloc_obj(*dpcm); if (dpcm == NULL) return -ENOMEM; diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index b08578c93c6a..c8d1518ee3e7 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -406,7 +406,7 @@ static void subsys_create_adapter(struct hpi_message *phm, memset(&ao, 0, sizeof(ao)); - ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); + ao.priv = kzalloc_obj(struct hpi_hw_obj); if (!ao.priv) { HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index c7d7eff86727..98e7f7fa75c3 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -461,7 +461,7 @@ static void subsys_create_adapter(struct hpi_message *phm, memset(&ao, 0, sizeof(ao)); - ao.priv = kzalloc(sizeof(struct hpi_hw_obj), GFP_KERNEL); + ao.priv = kzalloc_obj(struct hpi_hw_obj); if (!ao.priv) { HPI_DEBUG_LOG(ERROR, "can't get mem for adapter object\n"); phr->error = HPI_ERROR_MEMORY_ALLOC; diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 7d1abaedb46a..d846777e7462 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -641,13 +641,12 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, const u32 size_in_bytes, u8 *p_dsp_control_buffer) { - struct hpi_control_cache *p_cache = - kmalloc(sizeof(*p_cache), GFP_KERNEL); + struct hpi_control_cache *p_cache = kmalloc_obj(*p_cache); if (!p_cache) return NULL; p_cache->p_info = - kcalloc(control_count, sizeof(*p_cache->p_info), GFP_KERNEL); + kzalloc_objs(*p_cache->p_info, control_count); if (!p_cache->p_info) { kfree(p_cache); return NULL; diff --git a/sound/pci/asihpi/hpidspcd.c b/sound/pci/asihpi/hpidspcd.c index 9acc0ac75eca..b1b5a131f626 100644 --- a/sound/pci/asihpi/hpidspcd.c +++ b/sound/pci/asihpi/hpidspcd.c @@ -69,7 +69,7 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, } HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); - dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL); + dsp_code->pvt = kmalloc_obj(*dsp_code->pvt); if (!dsp_code->pvt) { err_ret = HPI_ERROR_MEMORY_ALLOC; goto error2; diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index 9fb0c8e503df..9de9ae7032b8 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c @@ -105,8 +105,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (cmd != HPI_IOCTL_LINUX) return -EINVAL; - hm = kmalloc(sizeof(*hm), GFP_KERNEL); - hr = kzalloc(sizeof(*hr), GFP_KERNEL); + hm = kmalloc_obj(*hm); + hr = kzalloc_obj(*hr); if (!hm || !hr) { err = -ENOMEM; goto out; diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 41774e2ef53f..35392f6525b3 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -543,7 +543,7 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr struct snd_pcm_runtime *runtime = substream->runtime; int err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; @@ -638,7 +638,7 @@ static int snd_ca0106_pcm_open_capture_channel(struct snd_pcm_substream *substre struct snd_pcm_runtime *runtime = substream->runtime; int err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (!epcm) return -ENOMEM; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 0666be543474..cd73b6833639 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -1096,7 +1096,7 @@ static int save_mixer_state(struct cmipci *cm) struct snd_ctl_elem_value *val; unsigned int i; - val = kmalloc(sizeof(*val), GFP_KERNEL); + val = kmalloc_obj(*val); if (!val) return -ENOMEM; for (i = 0; i < CM_SAVED_MIXERS; i++) { @@ -1130,7 +1130,7 @@ static void restore_mixer_state(struct cmipci *cm) struct snd_ctl_elem_value *val; unsigned int i; - val = kmalloc(sizeof(*val), GFP_KERNEL); + val = kmalloc_obj(*val); if (!val) return; cm->mixer_insensitive = 0; /* at first clear this; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index b96ab7fd464c..1c11023184ac 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -401,7 +401,7 @@ static int load_firmware(struct snd_cs46xx *chip, } err = -ENOMEM; - module = kzalloc(sizeof(*module), GFP_KERNEL); + module = kzalloc_obj(*module); if (!module) goto error; module->module_name = kstrdup(fw_name, GFP_KERNEL); @@ -414,7 +414,7 @@ static int load_firmware(struct snd_cs46xx *chip, if (nums >= 40) goto error_inval; module->symbol_table.symbols = - kcalloc(nums, sizeof(struct dsp_symbol_entry), GFP_KERNEL); + kzalloc_objs(struct dsp_symbol_entry, nums); if (!module->symbol_table.symbols) goto error; for (i = 0; i < nums; i++) { @@ -434,7 +434,7 @@ static int load_firmware(struct snd_cs46xx *chip, if (nums > 10) goto error_inval; module->segments = - kcalloc(nums, sizeof(struct dsp_segment_desc), GFP_KERNEL); + kzalloc_objs(struct dsp_segment_desc, nums); if (!module->segments) goto error; for (i = 0; i < nums; i++) { diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 3d34575a0e8f..6fd4f629d1d5 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -221,7 +221,7 @@ add_symbol (struct snd_cs46xx * chip, char * symbol_name, u32 address, int type) struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) { - struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); + struct dsp_spos_instance * ins = kzalloc_obj(struct dsp_spos_instance); if (ins == NULL) return NULL; @@ -231,9 +231,7 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) vmalloc(array_size(DSP_MAX_SYMBOLS, sizeof(struct dsp_symbol_entry))); ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); - ins->modules = kmalloc_array(DSP_MAX_MODULES, - sizeof(struct dsp_module_desc), - GFP_KERNEL); + ins->modules = kmalloc_objs(struct dsp_module_desc, DSP_MAX_MODULES); if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) { cs46xx_dsp_spos_destroy(chip); goto error; diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 32ed415bf427..fd19365026b4 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -234,7 +234,7 @@ void cs46xx_dsp_proc_register_scb_desc (struct snd_cs46xx *chip, entry = snd_info_create_card_entry(ins->snd_card, scb->scb_name, ins->proc_dsp_dir); if (entry) { - scb_info = kmalloc(sizeof(struct proc_scb_info), GFP_KERNEL); + scb_info = kmalloc_obj(struct proc_scb_info); if (!scb_info) { snd_info_free_entry(entry); entry = NULL; diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c index c30162be27ee..5fc1c922620a 100644 --- a/sound/pci/ctxfi/ctamixer.c +++ b/sound/pci/ctxfi/ctamixer.c @@ -296,7 +296,7 @@ int amixer_mgr_create(struct hw *hw, void **ramixer_mgr) struct amixer_mgr *amixer_mgr; *ramixer_mgr = NULL; - amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL); + amixer_mgr = kzalloc_obj(*amixer_mgr); if (!amixer_mgr) return -ENOMEM; @@ -448,7 +448,7 @@ int sum_mgr_create(struct hw *hw, void **rsum_mgr) struct sum_mgr *sum_mgr; *rsum_mgr = NULL; - sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL); + sum_mgr = kzalloc_obj(*sum_mgr); if (!sum_mgr) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index a25a599fc5be..f122e396bc55 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c @@ -1723,7 +1723,7 @@ int ct_atc_create(struct snd_card *card, struct pci_dev *pci, *ratc = NULL; - atc = kzalloc(sizeof(*atc), GFP_KERNEL); + atc = kzalloc_obj(*atc); if (!atc) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c index 1c8f8efd836c..b8bde27f3a1d 100644 --- a/sound/pci/ctxfi/ctdaio.c +++ b/sound/pci/ctxfi/ctdaio.c @@ -159,7 +159,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kcalloc(daio->rscl.msr, sizeof(*entry), GFP_KERNEL); + entry = kzalloc_objs(*entry, daio->rscl.msr); if (!entry) return -ENOMEM; @@ -188,7 +188,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input) struct daio *daio = &dao->daio; int i; - entry = kcalloc(daio->rscr.msr, sizeof(*entry), GFP_KERNEL); + entry = kzalloc_objs(*entry, daio->rscr.msr); if (!entry) return -ENOMEM; @@ -660,7 +660,7 @@ int daio_mgr_create(struct hw *hw, void **rdaio_mgr) struct imapper *entry; *rdaio_mgr = NULL; - daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL); + daio_mgr = kzalloc_obj(*daio_mgr); if (!daio_mgr) return -ENOMEM; @@ -671,7 +671,7 @@ int daio_mgr_create(struct hw *hw, void **rdaio_mgr) spin_lock_init(&daio_mgr->mgr_lock); spin_lock_init(&daio_mgr->imap_lock); INIT_LIST_HEAD(&daio_mgr->imappers); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto error2; diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c index ea0a928937b6..06753f555944 100644 --- a/sound/pci/ctxfi/cthw20k1.c +++ b/sound/pci/ctxfi/cthw20k1.c @@ -157,7 +157,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) struct src_rsc_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -483,7 +483,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) struct src_mgr_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -504,7 +504,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) struct srcimp_mgr_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -691,7 +691,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) struct amixer_rsc_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -898,7 +898,7 @@ static int dai_get_ctrl_blk(void **rblk) struct dai_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -947,7 +947,7 @@ static int dao_get_ctrl_blk(void **rblk) struct dao_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -1141,7 +1141,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) struct daio_mgr_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -2227,7 +2227,7 @@ int create_20k1_hw_obj(struct hw **rhw) struct hw20k1 *hw20k1; *rhw = NULL; - hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL); + hw20k1 = kzalloc_obj(*hw20k1); if (!hw20k1) return -ENOMEM; diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c index fac88f5590c9..07e1490a6d17 100644 --- a/sound/pci/ctxfi/cthw20k2.c +++ b/sound/pci/ctxfi/cthw20k2.c @@ -157,7 +157,7 @@ static int src_get_rsc_ctrl_blk(void **rblk) struct src_rsc_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -483,7 +483,7 @@ static int src_mgr_get_ctrl_blk(void **rblk) struct src_mgr_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -504,7 +504,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk) struct srcimp_mgr_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -693,7 +693,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk) struct amixer_rsc_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -882,7 +882,7 @@ static int dai_get_ctrl_blk(void **rblk) struct dai_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -932,7 +932,7 @@ static int dao_get_ctrl_blk(void **rblk) struct dao_ctrl_blk *blk; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -1084,7 +1084,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk) int i; *rblk = NULL; - blk = kzalloc(sizeof(*blk), GFP_KERNEL); + blk = kzalloc_obj(*blk); if (!blk) return -ENOMEM; @@ -2369,7 +2369,7 @@ int create_20k2_hw_obj(struct hw **rhw) struct hw20k2 *hw20k2; *rhw = NULL; - hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL); + hw20k2 = kzalloc_obj(*hw20k2); if (!hw20k2) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c index fc9fde284fb3..e3ee76bd8482 100644 --- a/sound/pci/ctxfi/ctmixer.c +++ b/sound/pci/ctxfi/ctmixer.c @@ -969,7 +969,7 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer) *rmixer = NULL; /* Allocate mem for mixer obj */ - mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); + mixer = kzalloc_obj(*mixer); if (!mixer) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 81dfc6a76b18..fea6024f920e 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c @@ -119,7 +119,7 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream) struct ct_atc_pcm *apcm; int err; - apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); + apcm = kzalloc_obj(*apcm); if (!apcm) return -ENOMEM; @@ -265,7 +265,7 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream) struct ct_atc_pcm *apcm; int err; - apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); + apcm = kzalloc_obj(*apcm); if (!apcm) return -ENOMEM; diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index 46afc9604c08..326997bb885d 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c @@ -540,7 +540,7 @@ int src_mgr_create(struct hw *hw, void **rsrc_mgr) struct src_mgr *src_mgr; *rsrc_mgr = NULL; - src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL); + src_mgr = kzalloc_obj(*src_mgr); if (!src_mgr) return -ENOMEM; @@ -669,8 +669,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp, return err; /* Reserve memory for imapper nodes */ - srcimp->imappers = kcalloc(desc->msr, sizeof(struct imapper), - GFP_KERNEL); + srcimp->imappers = kzalloc_objs(struct imapper, desc->msr); if (!srcimp->imappers) { err = -ENOMEM; goto error1; @@ -811,7 +810,7 @@ int srcimp_mgr_create(struct hw *hw, void **rsrcimp_mgr) struct imapper *entry; *rsrcimp_mgr = NULL; - srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL); + srcimp_mgr = kzalloc_obj(*srcimp_mgr); if (!srcimp_mgr) return -ENOMEM; @@ -822,7 +821,7 @@ int srcimp_mgr_create(struct hw *hw, void **rsrcimp_mgr) spin_lock_init(&srcimp_mgr->mgr_lock); spin_lock_init(&srcimp_mgr->imap_lock); INIT_LIST_HEAD(&srcimp_mgr->imappers); - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) { err = -ENOMEM; goto error2; diff --git a/sound/pci/ctxfi/cttimer.c b/sound/pci/ctxfi/cttimer.c index 609b10320ff7..cc379d880cad 100644 --- a/sound/pci/ctxfi/cttimer.c +++ b/sound/pci/ctxfi/cttimer.c @@ -390,7 +390,7 @@ struct ct_timer *ct_timer_new(struct ct_atc *atc) struct ct_timer *atimer; struct hw *hw; - atimer = kzalloc(sizeof(*atimer), GFP_KERNEL); + atimer = kzalloc_obj(*atimer); if (!atimer) return NULL; spin_lock_init(&atimer->lock); diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c index 823d6e240a07..25e071cae08b 100644 --- a/sound/pci/ctxfi/ctvmem.c +++ b/sound/pci/ctxfi/ctvmem.c @@ -55,7 +55,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size, struct ct_atc *atc) return entry; } - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (!block) return NULL; @@ -170,7 +170,7 @@ int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) *rvm = NULL; - vm = kzalloc(sizeof(*vm), GFP_KERNEL); + vm = kzalloc_obj(*vm); if (!vm) return -ENOMEM; @@ -195,7 +195,7 @@ int ct_vm_create(struct ct_vm **rvm, struct pci_dev *pci) vm->get_ptp_phys = ct_get_ptp_phys; INIT_LIST_HEAD(&vm->unused); INIT_LIST_HEAD(&vm->used); - block = kzalloc(sizeof(*block), GFP_KERNEL); + block = kzalloc_obj(*block); if (NULL != block) { block->addr = 0; block->size = vm->size; diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c index 0356efad7528..5a41644b16b0 100644 --- a/sound/pci/echoaudio/darla20_dsp.c +++ b/sound/pci/echoaudio/darla20_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /*************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c index b96300772aee..5dc0efaca425 100644 --- a/sound/pci/echoaudio/darla24_dsp.c +++ b/sound/pci/echoaudio/darla24_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /*************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c index 9e1f2cad0909..38084c2c3f73 100644 --- a/sound/pci/echoaudio/echo3g_dsp.c +++ b/sound/pci/echoaudio/echo3g_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 8b7b6838106f..214d68657707 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -265,7 +265,7 @@ static int pcm_open(struct snd_pcm_substream *substream, chip = snd_pcm_substream_chip(substream); runtime = substream->runtime; - pipe = kzalloc(sizeof(struct audiopipe), GFP_KERNEL); + pipe = kzalloc_obj(struct audiopipe); if (!pipe) return -ENOMEM; pipe->index = -1; /* Not configured yet */ diff --git a/sound/pci/echoaudio/echoaudio.h b/sound/pci/echoaudio/echoaudio.h index 511f2fcc0fb9..7a5744bf3155 100644 --- a/sound/pci/echoaudio/echoaudio.h +++ b/sound/pci/echoaudio/echoaudio.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - **************************************************************************** Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index c9ee98ea3c71..4b3c6a8bc66a 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index 6e872103305b..4dd494508c9b 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echoaudio_dsp.h b/sound/pci/echoaudio/echoaudio_dsp.h index aa9129519795..4f73bc037f59 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.h +++ b/sound/pci/echoaudio/echoaudio_dsp.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c index 248983fa2959..682a8cc63f0b 100644 --- a/sound/pci/echoaudio/echoaudio_gml.c +++ b/sound/pci/echoaudio/echoaudio_gml.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c index c93939850357..ba4c398f8611 100644 --- a/sound/pci/echoaudio/gina20_dsp.c +++ b/sound/pci/echoaudio/gina20_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c index 78fbac9f3eac..fa1d8c06f059 100644 --- a/sound/pci/echoaudio/gina24_dsp.c +++ b/sound/pci/echoaudio/gina24_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c index 16eb082df56a..c53643279cdd 100644 --- a/sound/pci/echoaudio/indigo_dsp.c +++ b/sound/pci/echoaudio/indigo_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/indigo_express_dsp.c b/sound/pci/echoaudio/indigo_express_dsp.c index ceda2d7046ac..7a032b702498 100644 --- a/sound/pci/echoaudio/indigo_express_dsp.c +++ b/sound/pci/echoaudio/indigo_express_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /************************************************************************ This file is part of Echo Digital Audio's generic driver library. @@ -5,22 +6,6 @@ Copyright Echo Digital Audio Corporation (c) 1998 - 2005 All rights reserved www.echoaudio.com -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -************************************************************************* - Translation from C++ and adaptation for use in ALSA-Driver were made by Giuliano Pochini diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c index 17a1d888d0b9..0f8299ab123f 100644 --- a/sound/pci/echoaudio/indigodj_dsp.c +++ b/sound/pci/echoaudio/indigodj_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/indigodjx_dsp.c b/sound/pci/echoaudio/indigodjx_dsp.c index 5fbd4a3a3083..677cd8ed7cc4 100644 --- a/sound/pci/echoaudio/indigodjx_dsp.c +++ b/sound/pci/echoaudio/indigodjx_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /************************************************************************ This file is part of Echo Digital Audio's generic driver library. @@ -5,22 +6,6 @@ Copyright Echo Digital Audio Corporation (c) 1998 - 2005 All rights reserved www.echoaudio.com -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -************************************************************************* - Translation from C++ and adaptation for use in ALSA-Driver were made by Giuliano Pochini diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c index 791787aa0744..55d6431c8291 100644 --- a/sound/pci/echoaudio/indigoio_dsp.c +++ b/sound/pci/echoaudio/indigoio_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/indigoiox_dsp.c b/sound/pci/echoaudio/indigoiox_dsp.c index 1ae394ea7c7d..48958e51d414 100644 --- a/sound/pci/echoaudio/indigoiox_dsp.c +++ b/sound/pci/echoaudio/indigoiox_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later /************************************************************************ This file is part of Echo Digital Audio's generic driver library. @@ -5,22 +6,6 @@ Copyright Echo Digital Audio Corporation (c) 1998 - 2005 All rights reserved www.echoaudio.com -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -************************************************************************* - Translation from C++ and adaptation for use in ALSA-Driver were made by Giuliano Pochini diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c index 5fb5c4a4598b..e0349a3c20e4 100644 --- a/sound/pci/echoaudio/layla20_dsp.c +++ b/sound/pci/echoaudio/layla20_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c index decfccb1e803..e7b8f5fe7753 100644 --- a/sound/pci/echoaudio/layla24_dsp.c +++ b/sound/pci/echoaudio/layla24_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,21 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c index 8a4dffc68889..f040a09f3191 100644 --- a/sound/pci/echoaudio/mia_dsp.c +++ b/sound/pci/echoaudio/mia_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c index dd5212644844..4d66163a6bb0 100644 --- a/sound/pci/echoaudio/midi.c +++ b/sound/pci/echoaudio/midi.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index 9bb6a174745c..6089152eb246 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /**************************************************************************** Copyright Echo Digital Audio Corporation (c) 1998 - 2004 @@ -5,22 +6,6 @@ www.echoaudio.com This file is part of Echo Digital Audio's generic driver library. - - Echo Digital Audio's generic driver library is free software; - you can redistribute it and/or modify it under the terms of - the GNU General Public License as published by the Free Software - Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. - ************************************************************************* Translation from C++ and adaptation for use in ALSA-Driver diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 9607a0f7174b..1b207ca25814 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -367,7 +367,7 @@ static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream) if (err < 0) return err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = chip; @@ -547,7 +547,7 @@ static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream) if (err < 0) return err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 37af7bf76347..08e0556bf161 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -776,7 +776,7 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, if (snd_emu10k1_look_for_ctl(emu, &id) == NULL) return -ENOENT; } - gctl = kmalloc(sizeof(*gctl), GFP_KERNEL); + gctl = kmalloc_obj(*gctl); if (! gctl) return -ENOMEM; err = 0; @@ -864,9 +864,9 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, struct snd_ctl_elem_value *val; int err = 0; - val = kmalloc(sizeof(*val), GFP_KERNEL); - gctl = kmalloc(sizeof(*gctl), GFP_KERNEL); - nctl = kmalloc(sizeof(*nctl), GFP_KERNEL); + val = kmalloc_obj(*val); + gctl = kmalloc_obj(*gctl); + nctl = kmalloc_obj(*nctl); if (!val || !gctl || !nctl) { err = -ENOMEM; goto __error; @@ -914,7 +914,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, nctl->max = gctl->max; nctl->translation = gctl->translation; if (ctl == NULL) { - ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kmalloc_obj(*ctl); if (ctl == NULL) { err = -ENOMEM; kfree(knew.tlv.p); @@ -980,7 +980,7 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu, struct snd_emu10k1_fx8010_ctl *ctl; struct snd_ctl_elem_id *id; - gctl = kmalloc(sizeof(*gctl), GFP_KERNEL); + gctl = kmalloc_obj(*gctl); if (! gctl) return -ENOMEM; @@ -1282,16 +1282,14 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) u32 *gpr_map; err = -ENOMEM; - icode = kzalloc(sizeof(*icode), GFP_KERNEL); + icode = kzalloc_obj(*icode); if (!icode) return err; - icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024, - sizeof(u_int32_t), GFP_KERNEL); + icode->gpr_map = kzalloc_objs(u_int32_t, 512 + 256 + 256 + 2 * 1024); if (!icode->gpr_map) goto __err_gpr; - controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, - sizeof(*controls), GFP_KERNEL); + controls = kzalloc_objs(*controls, SND_EMU10K1_GPR_CONTROLS); if (!controls) goto __err_ctrls; @@ -1800,22 +1798,20 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) u32 *gpr_map; err = -ENOMEM; - icode = kzalloc(sizeof(*icode), GFP_KERNEL); + icode = kzalloc_obj(*icode); if (!icode) return err; - icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512, - sizeof(u_int32_t), GFP_KERNEL); + icode->gpr_map = kzalloc_objs(u_int32_t, 256 + 160 + 160 + 2 * 512); if (!icode->gpr_map) goto __err_gpr; - controls = kcalloc(SND_EMU10K1_GPR_CONTROLS, - sizeof(struct snd_emu10k1_fx8010_control_gpr), - GFP_KERNEL); + controls = kzalloc_objs(struct snd_emu10k1_fx8010_control_gpr, + SND_EMU10K1_GPR_CONTROLS); if (!controls) goto __err_ctrls; - ipcm = kzalloc(sizeof(*ipcm), GFP_KERNEL); + ipcm = kzalloc_obj(*ipcm); if (!ipcm) goto __err_ipcm; diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 071c75ba81fd..9023f3444d20 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c @@ -1132,7 +1132,7 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int i, j, err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1171,7 +1171,7 @@ static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int i, err, sample_rate; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1222,7 +1222,7 @@ static int snd_emu10k1_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_emu10k1_pcm *epcm; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1259,7 +1259,7 @@ static int snd_emu10k1_capture_mic_open(struct snd_pcm_substream *substream) struct snd_emu10k1_pcm *epcm; struct snd_pcm_runtime *runtime = substream->runtime; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; @@ -1299,7 +1299,7 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream) int nefx = emu->audigy ? 64 : 32; int idx, err; - epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); + epcm = kzalloc_obj(*epcm); if (epcm == NULL) return -ENOMEM; epcm->emu = emu; diff --git a/sound/pci/ens1371.c b/sound/pci/ens1371.c index ca0da0ab40b6..694978c4b22d 100644 --- a/sound/pci/ens1371.c +++ b/sound/pci/ens1371.c @@ -1,2 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0 #define CHIP1371 #include "ens1370.c" diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 51aee2c4d461..b7282b3fa1b1 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1307,7 +1307,7 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) __found: if (buf->buf.bytes > size) { - struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); + struct esm_memory *chunk = kmalloc_obj(*chunk); if (chunk == NULL) return NULL; chunk->buf = buf->buf; @@ -1385,7 +1385,7 @@ snd_es1968_init_dmabuf(struct es1968 *chip) INIT_LIST_HEAD(&chip->buf_list); /* allocate an empty chunk */ - chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); + chunk = kmalloc_obj(*chunk); if (chunk == NULL) { snd_es1968_free_dmabuf(chip); return -ENOMEM; @@ -1488,7 +1488,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) if (apu1 < 0) return apu1; - es = kzalloc(sizeof(*es), GFP_KERNEL); + es = kzalloc_obj(*es); if (!es) { snd_es1968_free_apu_pair(chip, apu1); return -ENOMEM; @@ -1529,7 +1529,7 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) return apu2; } - es = kzalloc(sizeof(*es), GFP_KERNEL); + es = kzalloc_obj(*es); if (!es) { snd_es1968_free_apu_pair(chip, apu1); snd_es1968_free_apu_pair(chip, apu2); diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index cad33a2f26bc..bcafa16ce547 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -115,7 +115,7 @@ int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *t struct snd_ak4xxx_private *priv; if (_priv != NULL) { - priv = kmalloc(sizeof(*priv), GFP_KERNEL); + priv = kmalloc_obj(*priv); if (priv == NULL) return -ENOMEM; *priv = *_priv; diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index b4c9e7d11609..1191a2686dfd 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -2076,7 +2076,7 @@ static int aureon_init(struct snd_ice1712 *ice) struct aureon_spec *spec; int i, err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -2091,7 +2091,7 @@ static int aureon_init(struct snd_ice1712 *ice) } /* to remember the register values of CS8415 */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); if (!ice->akm) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index e5a9585cba4c..897b749c70b5 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -707,7 +707,7 @@ static int snd_ice1712_delta_init(struct snd_ice1712 *ice) } /* second stage of initialization, analog parts and others */ - ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm = kmalloc_obj(struct snd_akm4xxx); if (! ak) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 1dffcb011deb..26f5d5528e27 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -431,7 +431,7 @@ static int snd_ice1712_ews_init(struct snd_ice1712 *ice) break; } - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -530,7 +530,7 @@ static int snd_ice1712_ews_init(struct snd_ice1712 *ice) } /* analog section */ - ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm = kzalloc_obj(struct snd_akm4xxx); if (! ak) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index 071f94dc7390..5294c9dd782d 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -156,7 +156,7 @@ static int hoontech_init(struct snd_ice1712 *ice, bool staudio) ice->num_total_dacs = 8; ice->num_total_adcs = 8; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -301,7 +301,7 @@ static int snd_ice1712_value_init(struct snd_ice1712 *ice) ice->num_total_adcs = 2; /* analog section */ - ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm = kmalloc_obj(struct snd_akm4xxx); if (! ak) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index d679842ae1bd..ab1c8ac07160 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -560,7 +560,7 @@ static int juli_init(struct snd_ice1712 *ice) struct juli_spec *spec; struct snd_akm4xxx *ak; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -594,7 +594,7 @@ static int juli_init(struct snd_ice1712 *ice) ice->num_total_dacs = 2; ice->num_total_adcs = 2; - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); ak = ice->akm; if (!ak) return -ENOMEM; diff --git a/sound/pci/ice1712/maya44.c b/sound/pci/ice1712/maya44.c index 551f478c59c4..fd1427d64a7b 100644 --- a/sound/pci/ice1712/maya44.c +++ b/sound/pci/ice1712/maya44.c @@ -668,7 +668,7 @@ static int maya44_init(struct snd_ice1712 *ice) int i; struct snd_maya44 *chip; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; mutex_init(&chip->mutex); diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 151b740ce66d..37756d06218d 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -125,7 +125,7 @@ static int phase22_init(struct snd_ice1712 *ice) } /* Initialize analog chips */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); ak = ice->akm; if (!ak) return -ENOMEM; @@ -411,13 +411,13 @@ static int phase28_init(struct snd_ice1712 *ice) ice->num_total_dacs = 8; ice->num_total_adcs = 2; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; /* Initialize analog chips */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); ak = ice->akm; if (!ak) return -ENOMEM; diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 557473f0d59e..b2bd64ece862 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -728,7 +728,7 @@ static int pontis_init(struct snd_ice1712 *ice) ice->num_total_adcs = 2; /* to remember the register values */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); if (! ice->akm) return -ENOMEM; ice->akm_codecs = 1; diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index cd7db2b65b51..6c4783b9a983 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -713,7 +713,7 @@ static int prodigy192_init(struct snd_ice1712 *ice) ice->num_total_adcs = 2; ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index eac233093865..bb5169a69b18 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c @@ -1060,12 +1060,12 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) ice->gpio.saved[0] = 0; /* to remember the register values */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); if (! ice->akm) return -ENOMEM; ice->akm_codecs = 1; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -1143,12 +1143,12 @@ static int prodigy_hd2_init(struct snd_ice1712 *ice) ice->gpio.saved[0] = 0; /* to remember the register values */ - ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_obj(struct snd_akm4xxx); if (! ice->akm) return -ENOMEM; ice->akm_codecs = 1; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; diff --git a/sound/pci/ice1712/psc724.c b/sound/pci/ice1712/psc724.c index 0818e42c94ca..7842bf98af19 100644 --- a/sound/pci/ice1712/psc724.c +++ b/sound/pci/ice1712/psc724.c @@ -383,7 +383,7 @@ static int psc724_init(struct snd_ice1712 *ice) { struct psc724_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; diff --git a/sound/pci/ice1712/quartet.c b/sound/pci/ice1712/quartet.c index 099601edf1d0..6a44ae969d15 100644 --- a/sound/pci/ice1712/quartet.c +++ b/sound/pci/ice1712/quartet.c @@ -969,7 +969,7 @@ static int qtet_init(struct snd_ice1712 *ice) val = inb(ICEMT1724(ice, RATE)); outb(val | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; /* qtet is clocked by Xilinx array */ @@ -1005,7 +1005,7 @@ static int qtet_init(struct snd_ice1712 *ice) ice->num_total_dacs = 2; ice->num_total_adcs = 2; - ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); + ice->akm = kzalloc_objs(struct snd_akm4xxx, 2); ak = ice->akm; if (!ak) return -ENOMEM; diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index bcf114152dfd..d9723c297d40 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -147,7 +147,7 @@ static int revo51_i2c_init(struct snd_ice1712 *ice, struct revo51_spec *spec; int err; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -470,7 +470,7 @@ static int ap192_ak4114_init(struct snd_ice1712 *ice) int err; struct revo51_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; @@ -515,7 +515,7 @@ static int revo_init(struct snd_ice1712 *ice) } /* second stage of initialization, analog parts and others */ - ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm = kzalloc_objs(struct snd_akm4xxx, 2); if (! ak) return -ENOMEM; switch (ice->eeprom.subvendor) { diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c index ffa9d8860a5a..d78328288fc6 100644 --- a/sound/pci/ice1712/se.c +++ b/sound/pci/ice1712/se.c @@ -660,7 +660,7 @@ static int se_init(struct snd_ice1712 *ice) { struct se_spec *spec; - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 57a79536e7ba..c38f1bd1948d 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -579,7 +579,7 @@ static int wtm_init(struct snd_ice1712 *ice) ice->force_rdma1 = 1; /*init mutex for dac mute conflict*/ - spec = kzalloc(sizeof(*spec), GFP_KERNEL); + spec = kzalloc_obj(*spec); if (!spec) return -ENOMEM; ice->spec = spec; diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index c6319e75beab..a7760a23bfe9 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -255,7 +255,7 @@ snd_mixart_add_ref_pipe(struct snd_mixart *chip, int pcm_number, int capture, "add_ref_pipe audio chip(%d) pcm(%d)\n", chip->chip_idx, pcm_number); - buf = kmalloc(sizeof(*buf), GFP_KERNEL); + buf = kmalloc_obj(*buf); if (!buf) return NULL; @@ -1017,7 +1017,7 @@ static int snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *card, int .dev_free = snd_mixart_chip_dev_free, }; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; @@ -1243,7 +1243,7 @@ static int snd_mixart_probe(struct pci_dev *pci, /* */ - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (! mgr) { pci_disable_device(pci); return -ENOMEM; diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index 689c0f995a9c..439e3ff05fe1 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -135,9 +135,9 @@ static int mixart_enum_connectors(struct mixart_mgr *mgr) struct mixart_audio_info_req *audio_info_req; struct mixart_audio_info_resp *audio_info; - connector = kmalloc(sizeof(*connector), GFP_KERNEL); - audio_info_req = kmalloc(sizeof(*audio_info_req), GFP_KERNEL); - audio_info = kmalloc(sizeof(*audio_info), GFP_KERNEL); + connector = kmalloc_obj(*connector); + audio_info_req = kmalloc_obj(*audio_info_req); + audio_info = kmalloc_obj(*audio_info); if (! connector || ! audio_info_req || ! audio_info) { err = -ENOMEM; goto __error; diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 83066d08367e..e7d63972c2ca 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -1163,7 +1163,7 @@ static int pcxhr_create(struct pcxhr_mgr *mgr, .dev_free = pcxhr_chip_dev_free, }; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (!chip) return -ENOMEM; @@ -1488,7 +1488,7 @@ static int pcxhr_probe(struct pci_dev *pci, } /* alloc card manager */ - mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); + mgr = kzalloc_obj(*mgr); if (! mgr) { pci_disable_device(pci); return -ENOMEM; diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index f91fe64bf4f9..99c00e46ce23 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1595,7 +1595,7 @@ static int snd_riptide_playback_open(struct snd_pcm_substream *substream) chip->playback_substream[sub_num] = substream; runtime->hw = snd_riptide_playback; - data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); + data = kzalloc_obj(struct pcmhw); if (data == NULL) return -ENOMEM; data->paths = lbus_play_paths[sub_num]; @@ -1618,7 +1618,7 @@ static int snd_riptide_capture_open(struct snd_pcm_substream *substream) chip->capture_substream = substream; runtime->hw = snd_riptide_capture; - data = kzalloc(sizeof(struct pcmhw), GFP_KERNEL); + data = kzalloc_obj(struct pcmhw); if (data == NULL) return -ENOMEM; data->paths = lbus_rec_path; @@ -1768,7 +1768,7 @@ static int snd_riptide_initialize(struct snd_riptide *chip) cif = chip->cif; if (!cif) { - cif = kzalloc(sizeof(struct cmdif), GFP_KERNEL); + cif = kzalloc_obj(struct cmdif); if (!cif) return -ENOMEM; cif->dev = chip->card->dev; diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 3ba5bdc96d9d..d8bbedbc8ff6 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -6671,7 +6671,7 @@ static int snd_hdspm_create(struct snd_card *card, if (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + hdspm->tco = kzalloc_obj(*hdspm->tco); if (hdspm->tco) hdspm_tco_write(hdspm); @@ -6685,7 +6685,7 @@ static int snd_hdspm_create(struct snd_card *card, case AES32: if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { hdspm->midiPorts++; - hdspm->tco = kzalloc(sizeof(*hdspm->tco), GFP_KERNEL); + hdspm->tco = kzalloc_obj(*hdspm->tco); if (hdspm->tco) hdspm_tco_write(hdspm); diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 55515c58b8aa..fa8d7f271eaf 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -2888,7 +2888,7 @@ static int snd_trident_mixer(struct snd_trident *trident, int pcm_spdif_device) .read = snd_trident_codec_read, }; - uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); + uctl = kzalloc_obj(*uctl); if (!uctl) return -ENOMEM; diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 2b0f9e38863e..41b322fbd9ef 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -423,9 +423,7 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre return -ENOMEM; } if (! dev->idx_table) { - dev->idx_table = kmalloc_array(VIA_TABLE_SIZE, - sizeof(*dev->idx_table), - GFP_KERNEL); + dev->idx_table = kmalloc_objs(*dev->idx_table, VIA_TABLE_SIZE); if (! dev->idx_table) return -ENOMEM; } diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 6ce2cd88cda6..a6f176d612e3 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -278,9 +278,7 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre return -ENOMEM; } if (! dev->idx_table) { - dev->idx_table = kmalloc_array(VIA_TABLE_SIZE, - sizeof(*dev->idx_table), - GFP_KERNEL); + dev->idx_table = kmalloc_objs(*dev->idx_table, VIA_TABLE_SIZE); if (! dev->idx_table) return -ENOMEM; } diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index eb373d9395e3..b9a09568afc9 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -864,7 +864,7 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream) if (err < 0) return err; - ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); + ypcm = kzalloc_obj(*ypcm); if (ypcm == NULL) return -ENOMEM; ypcm->chip = chip; @@ -990,7 +990,7 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream, if (err < 0) return err; - ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); + ypcm = kzalloc_obj(*ypcm); if (ypcm == NULL) return -ENOMEM; ypcm->chip = chip; diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c index a104baac3a94..f6fdebcff716 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c @@ -142,7 +142,7 @@ struct snd_pdacf *snd_pdacf_create(struct snd_card *card) { struct snd_pdacf *chip; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return NULL; chip->card = card; diff --git a/sound/ppc/awacs.c b/sound/ppc/awacs.c index c231a9d6d1de..ee36ea2842cd 100644 --- a/sound/ppc/awacs.c +++ b/sound/ppc/awacs.c @@ -896,7 +896,7 @@ snd_pmac_awacs_init(struct snd_pmac *chip) chip->revision = (in_le32(&chip->awacs->codec_stat) >> 12) & 0xf; #ifdef PMAC_AMP_AVAIL if (chip->revision == 3 && chip->has_iic && CHECK_CUDA_AMP()) { - struct awacs_amp *amp = kzalloc(sizeof(*amp), GFP_KERNEL); + struct awacs_amp *amp = kzalloc_obj(*amp); if (! amp) return -ENOMEM; chip->mixer_data = amp; diff --git a/sound/ppc/beep.c b/sound/ppc/beep.c index ab2468790b0c..1b03a7961727 100644 --- a/sound/ppc/beep.c +++ b/sound/ppc/beep.c @@ -208,7 +208,7 @@ int snd_pmac_attach_beep(struct snd_pmac *chip) void *dmabuf; int err = -ENOMEM; - beep = kzalloc(sizeof(*beep), GFP_KERNEL); + beep = kzalloc_obj(*beep); if (! beep) return -ENOMEM; dmabuf = dma_alloc_coherent(&chip->pdev->dev, BEEP_BUFLEN * 4, diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index a74114225b67..f35cb870d26d 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c @@ -244,7 +244,7 @@ int snd_pmac_daca_init(struct snd_pmac *chip) request_module("i2c-powermac"); - mix = kzalloc(sizeof(*mix), GFP_KERNEL); + mix = kzalloc_obj(*mix); if (! mix) return -ENOMEM; chip->mixer_data = mix; diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 6d7dab26ddf2..ba2048ee6550 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c @@ -1143,7 +1143,7 @@ int snd_pmac_new(struct snd_card *card, struct snd_pmac **chip_return) *chip_return = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; chip->card = card; diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 3c09660e1522..139c7b25927a 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c @@ -1348,7 +1348,7 @@ int snd_pmac_tumbler_init(struct snd_pmac *chip) request_module("i2c-powermac"); - mix = kzalloc(sizeof(*mix), GFP_KERNEL); + mix = kzalloc_obj(*mix); if (! mix) return -ENOMEM; mix->headphone_irq = -1; diff --git a/sound/sh/aica.c b/sound/sh/aica.c index fa81bfba59c1..9438c3a68ee9 100644 --- a/sound/sh/aica.c +++ b/sound/sh/aica.c @@ -330,7 +330,7 @@ static int snd_aicapcm_pcm_open(struct snd_pcm_substream if (!enable) return -ENOENT; dreamcastcard = substream->pcm->private_data; - channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL); + channel = kmalloc_obj(struct aica_channel); if (!channel) return -ENOMEM; /* set defaults for channel */ @@ -559,7 +559,7 @@ static int snd_aica_probe(struct platform_device *devptr) { int err; struct snd_card_aica *dreamcastcard; - dreamcastcard = kzalloc(sizeof(struct snd_card_aica), GFP_KERNEL); + dreamcastcard = kzalloc_obj(struct snd_card_aica); if (unlikely(!dreamcastcard)) return -ENOMEM; err = snd_card_new(&devptr->dev, index, SND_AICA_DRIVER, diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c index 164f91240d02..2d9a2d5b824e 100644 --- a/sound/sh/sh_dac_audio.c +++ b/sound/sh/sh_dac_audio.c @@ -306,7 +306,7 @@ static int snd_sh_dac_create(struct snd_card *card, *rchip = NULL; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); + chip = kzalloc_obj(*chip); if (chip == NULL) return -ENOMEM; diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index 897dde630022..c76a4bcc9645 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c @@ -775,7 +775,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_runtime *runtime = substream->runtime; struct audio_drv_data *intr_data = dev_get_drvdata(component->dev); struct audio_substream_data *adata = - kzalloc(sizeof(struct audio_substream_data), GFP_KERNEL); + kzalloc_obj(struct audio_substream_data); if (!adata) return -ENOMEM; diff --git a/sound/soc/amd/acp/acp-mach-common.c b/sound/soc/amd/acp/acp-mach-common.c index 4d99472c75ba..09f6c9a2c041 100644 --- a/sound/soc/amd/acp/acp-mach-common.c +++ b/sound/soc/amd/acp/acp-mach-common.c @@ -127,8 +127,13 @@ static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd) if (drvdata->hs_codec_id != RT5682) return -EINVAL; - drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); - drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); + drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk"); + if (IS_ERR(drvdata->wclk)) + return PTR_ERR(drvdata->wclk); + + drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk"); + if (IS_ERR(drvdata->bclk)) + return PTR_ERR(drvdata->bclk); ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets, ARRAY_SIZE(rt5682_widgets)); @@ -370,8 +375,13 @@ static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd) return -EINVAL; if (!drvdata->soc_mclk) { - drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk"); - drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk"); + drvdata->wclk = devm_clk_get(component->dev, "rt5682-dai-wclk"); + if (IS_ERR(drvdata->wclk)) + return PTR_ERR(drvdata->wclk); + + drvdata->bclk = devm_clk_get(component->dev, "rt5682-dai-bclk"); + if (IS_ERR(drvdata->bclk)) + return PTR_ERR(drvdata->bclk); } ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets, diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index b25ac5612808..88613569fd64 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -196,7 +196,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs struct acp_stream *stream; int ret; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/sound/soc/amd/acp/acp-sdw-legacy-mach.c b/sound/soc/amd/acp/acp-sdw-legacy-mach.c index 9cb55d592c3c..c30ccf23005a 100644 --- a/sound/soc/amd/acp/acp-sdw-legacy-mach.c +++ b/sound/soc/amd/acp/acp-sdw-legacy-mach.c @@ -95,6 +95,22 @@ static const struct dmi_system_id soc_sdw_quirk_table[] = { }, .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YW"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, + { + .callback = soc_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "21YX"), + }, + .driver_data = (void *)(ASOC_SDW_CODEC_SPKR), + }, {} }; @@ -379,13 +395,13 @@ static int soc_card_dai_links_create(struct snd_soc_card *card) /* One per DAI link, worst case is a DAI link for every endpoint */ struct asoc_sdw_dailink *soc_dais __free(kfree) = - kcalloc(num_ends, sizeof(*soc_dais), GFP_KERNEL); + kzalloc_objs(*soc_dais, num_ends); if (!soc_dais) return -ENOMEM; /* One per endpoint, ie. each DAI on each codec/amp */ struct asoc_sdw_endpoint *soc_ends __free(kfree) = - kcalloc(num_ends, sizeof(*soc_ends), GFP_KERNEL); + kzalloc_objs(*soc_ends, num_ends); if (!soc_ends) return -ENOMEM; diff --git a/sound/soc/amd/acp/acp-sdw-sof-mach.c b/sound/soc/amd/acp/acp-sdw-sof-mach.c index da815b3f6389..a0fd8a6f9970 100644 --- a/sound/soc/amd/acp/acp-sdw-sof-mach.c +++ b/sound/soc/amd/acp/acp-sdw-sof-mach.c @@ -288,13 +288,13 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) /* One per DAI link, worst case is a DAI link for every endpoint */ struct asoc_sdw_dailink *sof_dais __free(kfree) = - kcalloc(num_ends, sizeof(*sof_dais), GFP_KERNEL); + kzalloc_objs(*sof_dais, num_ends); if (!sof_dais) return -ENOMEM; /* One per endpoint, ie. each DAI on each codec/amp */ struct asoc_sdw_endpoint *sof_ends __free(kfree) = - kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL); + kzalloc_objs(*sof_ends, num_ends); if (!sof_ends) return -ENOMEM; diff --git a/sound/soc/amd/acp/amd-acp63-acpi-match.c b/sound/soc/amd/acp/amd-acp63-acpi-match.c index 9b6a49c051cd..1dbbaba3c75b 100644 --- a/sound/soc/amd/acp/amd-acp63-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp63-acpi-match.c @@ -30,6 +30,20 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1 }; +static const struct snd_soc_acpi_endpoint spk_2_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 2, + .group_id = 1 +}; + +static const struct snd_soc_acpi_endpoint spk_3_endpoint = { + .num = 0, + .aggregated = 1, + .group_position = 3, + .group_id = 1 +}; + static const struct snd_soc_acpi_adr_device rt711_rt1316_group_adr[] = { { .adr = 0x000030025D071101ull, @@ -103,6 +117,345 @@ static const struct snd_soc_acpi_adr_device rt722_0_single_adr[] = { } }; +static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = { + { /* Jack Playback Endpoint */ + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* DMIC Capture Endpoint */ + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Jack Capture Endpoint */ + .num = 2, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { /* Speaker Playback Endpoint */ + .num = 3, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l56x4_l1u3210_adr[] = { + { + .adr = 0x00013301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013101FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00013001FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l63x2_l0u01_adr[] = { + { + .adr = 0x00003001FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00003101FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l63x2_l1u01_adr[] = { + { + .adr = 0x00013001FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l63x2_l1u13_adr[] = { + { + .adr = 0x00013101FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013301FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, +}; + +static const struct snd_soc_acpi_adr_device cs35l63x4_l0u0246_adr[] = { + { + .adr = 0x00003001FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00003201FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00003401FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00003601FA356301ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l43_l0u0_adr[] = { + { + .adr = 0x00003001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_l0u1_adr[] = { + { + .adr = 0x00003101FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43b_l0u1_adr[] = { + { + .adr = 0x00003101FA2A3B01ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l43_l1u0_cs35l56x4_l1u0123_adr[] = { + { + .adr = 0x00013001FA424301ull, + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints), + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l43" + }, + { + .adr = 0x00013001FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "AMP1" + }, + { + .adr = 0x00013101FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "AMP2" + }, + { + .adr = 0x00013201FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_2_endpoint, + .name_prefix = "AMP3" + }, + { + .adr = 0x00013301FA355601ull, + .num_endpoints = 1, + .endpoints = &spk_3_endpoint, + .name_prefix = "AMP4" + }, +}; + +static const struct snd_soc_acpi_adr_device cs42l45_l0u0_adr[] = { + { + .adr = 0x00003001FA424501ull, + /* Re-use endpoints, but cs42l45 has no speaker */ + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l45" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l45_l1u0_adr[] = { + { + .adr = 0x00013001FA424501ull, + /* Re-use endpoints, but cs42l45 has no speaker */ + .num_endpoints = ARRAY_SIZE(cs42l43_endpoints) - 1, + .endpoints = cs42l43_endpoints, + .name_prefix = "cs42l45" + } +}; + +static const struct snd_soc_acpi_link_adr acp63_cs35l56x4_l1u3210[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), + .adr_d = cs35l56x4_l1u3210_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs35l63x4_l0u0246[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), + .adr_d = cs35l63x4_l0u0246_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_l0u1_adr), + .adr_d = cs42l43_l0u1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l43b_l0u1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43b_l0u1_adr), + .adr_d = cs42l43b_l0u1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l43_l0u0_cs35l56x4_l1u3210[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l43_l0u0_adr), + .adr_d = cs42l43_l0u0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l56x4_l1u3210_adr), + .adr_d = cs35l56x4_l1u3210_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l43_l1u0_cs35l56x4_l1u0123[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs42l43_l1u0_cs35l56x4_l1u0123_adr), + .adr_d = cs42l43_l1u0_cs35l56x4_l1u0123_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), + .adr_d = cs42l45_l0u0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u01[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), + .adr_d = cs42l45_l0u0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l63x2_l1u01_adr), + .adr_d = cs35l63x2_l1u01_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l0u0_cs35l63x2_l1u13[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l45_l0u0_adr), + .adr_d = cs42l45_l0u0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs35l63x2_l1u13_adr), + .adr_d = cs35l63x2_l1u13_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), + .adr_d = cs42l45_l1u0_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x2_l0u01[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), + .adr_d = cs42l45_l1u0_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs35l63x2_l0u01_adr), + .adr_d = cs35l63x2_l0u01_adr, + }, + {} +}; + +static const struct snd_soc_acpi_link_adr acp63_cs42l45_l1u0_cs35l63x4_l0u0246[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(cs42l45_l1u0_adr), + .adr_d = cs42l45_l1u0_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs35l63x4_l0u0246_adr), + .adr_d = cs35l63x4_l0u0246_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr acp63_rt722_only[] = { { .mask = BIT(0), @@ -135,6 +488,66 @@ struct snd_soc_acpi_mach snd_soc_acpi_amd_acp63_sdw_machines[] = { .links = acp63_4_in_1_sdca, .drv_name = "amd_sdw", }, + { + .link_mask = BIT(0) | BIT(1), + .links = acp63_cs42l43_l0u0_cs35l56x4_l1u3210, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0) | BIT(1), + .links = acp63_cs42l45_l1u0_cs35l63x4_l0u0246, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0) | BIT(1), + .links = acp63_cs42l45_l0u0_cs35l63x2_l1u01, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0) | BIT(1), + .links = acp63_cs42l45_l0u0_cs35l63x2_l1u13, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0) | BIT(1), + .links = acp63_cs42l45_l1u0_cs35l63x2_l0u01, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(1), + .links = acp63_cs42l43_l1u0_cs35l56x4_l1u0123, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(1), + .links = acp63_cs35l56x4_l1u3210, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0), + .links = acp63_cs35l63x4_l0u0246, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0), + .links = acp63_cs42l43_l0u1, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0), + .links = acp63_cs42l43b_l0u1, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(0), + .links = acp63_cs42l45_l0u0, + .drv_name = "amd_sdw", + }, + { + .link_mask = BIT(1), + .links = acp63_cs42l45_l1u0, + .drv_name = "amd_sdw", + }, {}, }; EXPORT_SYMBOL(snd_soc_acpi_amd_acp63_sdw_machines); diff --git a/sound/soc/amd/acp/amd-acp70-acpi-match.c b/sound/soc/amd/acp/amd-acp70-acpi-match.c index dd2b010efdaa..7a567ba02292 100644 --- a/sound/soc/amd/acp/amd-acp70-acpi-match.c +++ b/sound/soc/amd/acp/amd-acp70-acpi-match.c @@ -531,7 +531,44 @@ static const struct snd_soc_acpi_link_adr acp70_rt722_l0_rt1320_l1[] = { {} }; +static const struct snd_soc_acpi_adr_device rt1320_0_single_adr[] = { + { + .adr = 0x000030025D132001ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1320-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt722_1_single_adr[] = { + { + .adr = 0x000130025d072201ull, + .num_endpoints = ARRAY_SIZE(rt722_endpoints), + .endpoints = rt722_endpoints, + .name_prefix = "rt722" + } +}; + +static const struct snd_soc_acpi_link_adr acp70_rt1320_l0_rt722_l1[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt1320_0_single_adr), + .adr_d = rt1320_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt722_1_single_adr), + .adr_d = rt722_1_single_adr, + }, + {} +}; + struct snd_soc_acpi_mach snd_soc_acpi_amd_acp70_sdw_machines[] = { + { + .link_mask = BIT(0) | BIT(1), + .links = acp70_rt1320_l0_rt722_l1, + .drv_name = "amd_sdw", + }, { .link_mask = BIT(0) | BIT(1), .links = acp70_rt722_l0_rt1320_l1, diff --git a/sound/soc/amd/acp3x-rt5682-max9836.c b/sound/soc/amd/acp3x-rt5682-max9836.c index 4ca1978020a9..d1eb6f12a183 100644 --- a/sound/soc/amd/acp3x-rt5682-max9836.c +++ b/sound/soc/amd/acp3x-rt5682-max9836.c @@ -94,8 +94,13 @@ static int acp3x_5682_init(struct snd_soc_pcm_runtime *rtd) return ret; } - rt5682_dai_wclk = clk_get(component->dev, "rt5682-dai-wclk"); - rt5682_dai_bclk = clk_get(component->dev, "rt5682-dai-bclk"); + rt5682_dai_wclk = devm_clk_get(component->dev, "rt5682-dai-wclk"); + if (IS_ERR(rt5682_dai_wclk)) + return PTR_ERR(rt5682_dai_wclk); + + rt5682_dai_bclk = devm_clk_get(component->dev, "rt5682-dai-bclk"); + if (IS_ERR(rt5682_dai_bclk)) + return PTR_ERR(rt5682_dai_bclk); ret = snd_soc_card_jack_new_pins(card, "Headset Jack", SND_JACK_HEADSET | diff --git a/sound/soc/amd/ps/ps-pdm-dma.c b/sound/soc/amd/ps/ps-pdm-dma.c index 9cfbe05ad996..7c529fc6ba99 100644 --- a/sound/soc/amd/ps/ps-pdm-dma.c +++ b/sound/soc/amd/ps/ps-pdm-dma.c @@ -189,7 +189,7 @@ static int acp63_pdm_dma_open(struct snd_soc_component *component, runtime = substream->runtime; adata = dev_get_drvdata(component->dev); - pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL); + pdm_data = kzalloc_obj(*pdm_data); if (!pdm_data) return -EINVAL; diff --git a/sound/soc/amd/ps/ps-sdw-dma.c b/sound/soc/amd/ps/ps-sdw-dma.c index 5449323e2728..366d7c4bb07e 100644 --- a/sound/soc/amd/ps/ps-sdw-dma.c +++ b/sound/soc/amd/ps/ps-sdw-dma.c @@ -318,7 +318,7 @@ static int acp63_sdw_dma_open(struct snd_soc_component *component, runtime = substream->runtime; cpu_dai = snd_soc_rtd_to_cpu(prtd, 0); amd_manager = snd_soc_dai_get_drvdata(cpu_dai); - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/sound/soc/amd/raven/acp3x-pcm-dma.c b/sound/soc/amd/raven/acp3x-pcm-dma.c index bb9ed52d744d..4529404ebd93 100644 --- a/sound/soc/amd/raven/acp3x-pcm-dma.c +++ b/sound/soc/amd/raven/acp3x-pcm-dma.c @@ -218,7 +218,7 @@ static int acp3x_dma_open(struct snd_soc_component *component, prtd = snd_soc_substream_to_rtd(substream); component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); adata = dev_get_drvdata(component->dev); - i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL); + i2s_data = kzalloc_obj(*i2s_data); if (!i2s_data) return -EINVAL; diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c index a560d06097d5..e832c7c4b96f 100644 --- a/sound/soc/amd/renoir/acp3x-pdm-dma.c +++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c @@ -211,7 +211,7 @@ static int acp_pdm_dma_open(struct snd_soc_component *component, runtime = substream->runtime; adata = dev_get_drvdata(component->dev); - pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL); + pdm_data = kzalloc_obj(*pdm_data); if (!pdm_data) return -EINVAL; diff --git a/sound/soc/amd/vangogh/acp5x-pcm-dma.c b/sound/soc/amd/vangogh/acp5x-pcm-dma.c index aa4726899434..6ce82cd8859b 100644 --- a/sound/soc/amd/vangogh/acp5x-pcm-dma.c +++ b/sound/soc/amd/vangogh/acp5x-pcm-dma.c @@ -213,7 +213,7 @@ static int acp5x_dma_open(struct snd_soc_component *component, component = snd_soc_rtdcom_lookup(prtd, DRV_NAME); adata = dev_get_drvdata(component->dev); - i2s_data = kzalloc(sizeof(*i2s_data), GFP_KERNEL); + i2s_data = kzalloc_obj(*i2s_data); if (!i2s_data) return -ENOMEM; diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 67f2fee19398..1324543b42d7 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -696,7 +696,27 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_BOARD_NAME, "XyloD5_RBU"), } }, - + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "Vivobook_ASUSLaptop M6501RR_M6501RR"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUS EXPERTBOOK BM1503CDA"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_BOARD_NAME, "PM1503CDA"), + } + }, {} }; diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c index ac758b90f441..1c8aad849916 100644 --- a/sound/soc/amd/yc/acp6x-pdm-dma.c +++ b/sound/soc/amd/yc/acp6x-pdm-dma.c @@ -187,7 +187,7 @@ static int acp6x_pdm_dma_open(struct snd_soc_component *component, runtime = substream->runtime; adata = dev_get_drvdata(component->dev); - pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL); + pdm_data = kzalloc_obj(*pdm_data); if (!pdm_data) return -EINVAL; diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index 7db8df85c54f..1a0c584801f0 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c @@ -288,7 +288,7 @@ static int atmel_pcm_open(struct snd_soc_component *component, if (ret < 0) goto out; - prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL); + prtd = kzalloc_obj(struct atmel_runtime_data); if (prtd == NULL) { ret = -ENOMEM; goto out; diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c index 06dc3c48e7e8..ec7233ce1f78 100644 --- a/sound/soc/atmel/mchp-pdmc.c +++ b/sound/soc/atmel/mchp-pdmc.c @@ -706,7 +706,7 @@ static int mchp_pdmc_add_chmap_ctls(struct snd_pcm *pcm, struct mchp_pdmc *dd) if (WARN_ON(pcm->streams[SNDRV_PCM_STREAM_CAPTURE].chmap_kctl)) return -EBUSY; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return -ENOMEM; info->pcm = pcm; diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c index c9c2b1e71d55..8d91a0e0f112 100644 --- a/sound/soc/au1x/dma.c +++ b/sound/soc/au1x/dma.c @@ -81,7 +81,7 @@ static int au1000_setup_dma_link(struct audio_stream *stream, stream->period_size = period_bytes; stream->periods = periods; - stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL); + stream->buffer = kmalloc_obj(struct pcm_period); if (!stream->buffer) return -ENOMEM; pointer = stream->buffer; @@ -89,8 +89,7 @@ static int au1000_setup_dma_link(struct audio_stream *stream, pointer->start = (u32)(dma_start + (i * period_bytes)); pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1); if (i < periods - 1) { - pointer->next = kmalloc(sizeof(struct pcm_period), - GFP_KERNEL); + pointer->next = kmalloc_obj(struct pcm_period); if (!pointer->next) { au1000_release_dma_link(stream); return -ENOMEM; diff --git a/sound/soc/bcm/bcm63xx-pcm-whistler.c b/sound/soc/bcm/bcm63xx-pcm-whistler.c index efeb06ddabeb..6a3fd0d89365 100644 --- a/sound/soc/bcm/bcm63xx-pcm-whistler.c +++ b/sound/soc/bcm/bcm63xx-pcm-whistler.c @@ -48,7 +48,7 @@ static int bcm63xx_pcm_hw_params(struct snd_soc_component *component, struct i2s_dma_desc *dma_desc; struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); - dma_desc = kzalloc(sizeof(*dma_desc), GFP_NOWAIT); + dma_desc = kzalloc_obj(*dma_desc, GFP_NOWAIT); if (!dma_desc) return -ENOMEM; @@ -210,7 +210,7 @@ static int bcm63xx_pcm_open(struct snd_soc_component *component, goto out; ret = -ENOMEM; - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (!prtd) goto out; diff --git a/sound/soc/codecs/aw88261.c b/sound/soc/codecs/aw88261.c index 29b3fc8a1ea4..43c03d3cb252 100644 --- a/sound/soc/codecs/aw88261.c +++ b/sound/soc/codecs/aw88261.c @@ -424,9 +424,10 @@ static int aw88261_dev_reg_update(struct aw88261 *aw88261, if (ret) break; + /* keep all three bits from current hw status */ read_val &= (~AW88261_AMPPD_MASK) | (~AW88261_PWDN_MASK) | (~AW88261_HMUTE_MASK); - reg_val &= (AW88261_AMPPD_MASK | AW88261_PWDN_MASK | AW88261_HMUTE_MASK); + reg_val &= (AW88261_AMPPD_MASK & AW88261_PWDN_MASK & AW88261_HMUTE_MASK); reg_val |= read_val; /* enable uls hmute */ diff --git a/sound/soc/codecs/aw88395/aw88395_lib.c b/sound/soc/codecs/aw88395/aw88395_lib.c index ceb7fc43d018..056adbcd1ce8 100644 --- a/sound/soc/codecs/aw88395/aw88395_lib.c +++ b/sound/soc/codecs/aw88395/aw88395_lib.c @@ -665,8 +665,7 @@ static int aw_dev_load_cfg_by_hdr(struct aw_device *aw_dev, { int ret; - struct aw_all_prof_info *all_prof_info __free(kfree) = kzalloc(sizeof(*all_prof_info), - GFP_KERNEL); + struct aw_all_prof_info *all_prof_info __free(kfree) = kzalloc_obj(*all_prof_info); if (!all_prof_info) return -ENOMEM; diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c index 42d24ac2977f..30b3192d6ce9 100644 --- a/sound/soc/codecs/cs35l56-sdw.c +++ b/sound/soc/codecs/cs35l56-sdw.c @@ -554,7 +554,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi return 0; } -static int cs35l56_sdw_remove(struct sdw_slave *peripheral) +static void cs35l56_sdw_remove(struct sdw_slave *peripheral) { struct cs35l56_private *cs35l56 = dev_get_drvdata(&peripheral->dev); @@ -566,8 +566,6 @@ static int cs35l56_sdw_remove(struct sdw_slave *peripheral) sdw_write_no_pm(peripheral, CS35L56_SDW_GEN_INT_STAT_1, 0xFF); cs35l56_remove(cs35l56); - - return 0; } static const struct dev_pm_ops cs35l56_sdw_pm = { diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c index 4707f28bfca2..af87ebae98cb 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -26,7 +26,7 @@ #include "cs35l56.h" -static const struct reg_sequence cs35l56_patch[] = { +static const struct reg_sequence cs35l56_asp_patch[] = { /* * Firmware can change these to non-defaults to satisfy SDCA. * Ensure that they are at known defaults. @@ -43,6 +43,20 @@ static const struct reg_sequence cs35l56_patch[] = { { CS35L56_ASP1TX2_INPUT, 0x00000000 }, { CS35L56_ASP1TX3_INPUT, 0x00000000 }, { CS35L56_ASP1TX4_INPUT, 0x00000000 }, +}; + +int cs35l56_set_asp_patch(struct cs35l56_base *cs35l56_base) +{ + return regmap_register_patch(cs35l56_base->regmap, cs35l56_asp_patch, + ARRAY_SIZE(cs35l56_asp_patch)); +} +EXPORT_SYMBOL_NS_GPL(cs35l56_set_asp_patch, "SND_SOC_CS35L56_SHARED"); + +static const struct reg_sequence cs35l56_patch[] = { + /* + * Firmware can change these to non-defaults to satisfy SDCA. + * Ensure that they are at known defaults. + */ { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 }, { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 }, { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 }, diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index 2ff8b172b76e..37909a319f88 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -348,6 +348,13 @@ static int cs35l56_dsp_event(struct snd_soc_dapm_widget *w, return wm_adsp_event(w, kcontrol, event); } +static int cs35l56_asp_dai_probe(struct snd_soc_dai *codec_dai) +{ + struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); + + return cs35l56_set_asp_patch(&cs35l56->base); +} + static int cs35l56_asp_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(codec_dai->component); @@ -552,6 +559,7 @@ static int cs35l56_asp_dai_set_sysclk(struct snd_soc_dai *dai, } static const struct snd_soc_dai_ops cs35l56_ops = { + .probe = cs35l56_asp_dai_probe, .set_fmt = cs35l56_asp_dai_set_fmt, .set_tdm_slot = cs35l56_asp_dai_set_tdm_slot, .hw_params = cs35l56_asp_dai_hw_params, @@ -1617,9 +1625,9 @@ static int cs35l56_process_xu_onchip_speaker_id(struct cs35l56_private *cs35l56, if (num_pulls < 0) return num_pulls; - if (num_pulls != num_gpios) { + if (num_pulls && (num_pulls != num_gpios)) { dev_warn(cs35l56->base.dev, "%s count(%d) != %s count(%d)\n", - pull_name, num_pulls, gpio_name, num_gpios); + pull_name, num_pulls, gpio_name, num_gpios); } ret = cs35l56_check_and_save_onchip_spkid_gpios(&cs35l56->base, diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c index f837c7eff10b..d5999ad9ff9b 100644 --- a/sound/soc/codecs/cs42l42-sdw.c +++ b/sound/soc/codecs/cs42l42-sdw.c @@ -585,14 +585,12 @@ static int cs42l42_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi return 0; } -static int cs42l42_sdw_remove(struct sdw_slave *peripheral) +static void cs42l42_sdw_remove(struct sdw_slave *peripheral) { struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); cs42l42_common_remove(cs42l42); pm_runtime_disable(cs42l42->dev); - - return 0; } static const struct dev_pm_ops cs42l42_sdw_pm = { diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index b83bc4de1301..3e04e6897b14 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -699,6 +699,7 @@ static int cs42l43_run_type_detect(struct cs42l43_codec *priv) switch (type & CS42L43_HSDET_TYPE_STS_MASK) { case 0x0: // CTIA case 0x1: // OMTP + case 0x4: return cs42l43_run_load_detect(priv, true); case 0x2: // 3-pole return cs42l43_run_load_detect(priv, false); diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index d6121c0a2616..c0dc69ce4d0e 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -346,7 +346,7 @@ static int cx20442_component_probe(struct snd_soc_component *component) { struct cx20442_priv *cx20442; - cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL); + cx20442 = kzalloc_obj(struct cx20442_priv); if (cx20442 == NULL) return -ENOMEM; diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 298a626df3ad..ec4059f381be 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -2143,8 +2143,7 @@ static int da7219_register_dai_clks(struct snd_soc_component *component) /* For DT platforms allocate onecell data for clock registration */ if (np) { - clk_data = kzalloc(struct_size(clk_data, hws, DA7219_DAI_NUM_CLKS), - GFP_KERNEL); + clk_data = kzalloc_flex(*clk_data, hws, DA7219_DAI_NUM_CLKS); if (!clk_data) return -ENOMEM; diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 0a8de5620e72..6233aa9f5bc6 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -3820,7 +3820,7 @@ static int rx_macro_probe(struct platform_device *pdev) rx->rxn_reg_stride = 0x80; rx->rxn_reg_stride2 = 0xc; def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_pre_2_5_defaults); - reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL); + reg_defaults = kmalloc_objs(struct reg_default, def_count); if (!reg_defaults) return -ENOMEM; memcpy(®_defaults[0], rx_defaults, sizeof(rx_defaults)); @@ -3834,7 +3834,7 @@ static int rx_macro_probe(struct platform_device *pdev) rx->rxn_reg_stride = 0xc0; rx->rxn_reg_stride2 = 0x0; def_count = ARRAY_SIZE(rx_defaults) + ARRAY_SIZE(rx_2_5_defaults); - reg_defaults = kmalloc_array(def_count, sizeof(struct reg_default), GFP_KERNEL); + reg_defaults = kmalloc_objs(struct reg_default, def_count); if (!reg_defaults) return -ENOMEM; memcpy(®_defaults[0], rx_defaults, sizeof(rx_defaults)); diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index b695c77c18ac..5ad0448af649 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -2725,8 +2725,7 @@ static int wsa_macro_probe(struct platform_device *pdev) case LPASS_CODEC_VERSION_2_1: wsa->reg_layout = &wsa_codec_v2_1; def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_1); - reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults), - GFP_KERNEL); + reg_defaults = kmalloc_objs(*reg_defaults, def_count); if (!reg_defaults) return -ENOMEM; memcpy(®_defaults[0], wsa_defaults, sizeof(wsa_defaults)); @@ -2741,8 +2740,7 @@ static int wsa_macro_probe(struct platform_device *pdev) case LPASS_CODEC_VERSION_2_9: wsa->reg_layout = &wsa_codec_v2_5; def_count = ARRAY_SIZE(wsa_defaults) + ARRAY_SIZE(wsa_defaults_v2_5); - reg_defaults = kmalloc_array(def_count, sizeof(*reg_defaults), - GFP_KERNEL); + reg_defaults = kmalloc_objs(*reg_defaults, def_count); if (!reg_defaults) return -ENOMEM; memcpy(®_defaults[0], wsa_defaults, sizeof(wsa_defaults)); diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 88ff215f52b3..16673440218c 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -839,11 +839,9 @@ static int max98373_sdw_probe(struct sdw_slave *slave, return max98373_init(slave, regmap); } -static int max98373_sdw_remove(struct sdw_slave *slave) +static void max98373_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } #if defined(CONFIG_OF) diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index bde190a659b1..78b21fbfad50 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -1234,7 +1234,7 @@ static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt, struct pcmdevice_block_data **bk_da; unsigned int config_offset = 0, i; - cfg_info = kzalloc(sizeof(struct pcmdevice_config_info), GFP_KERNEL); + cfg_info = kzalloc_obj(struct pcmdevice_config_info); if (!cfg_info) { *status = -ENOMEM; goto out; @@ -1261,8 +1261,8 @@ static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt, get_unaligned_be32(&config_data[config_offset]); config_offset += 4; - bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks, - sizeof(struct pcmdevice_block_data *), GFP_KERNEL); + bk_da = cfg_info->blk_data = kzalloc_objs(struct pcmdevice_block_data *, + cfg_info->nblocks); if (!bk_da) { *status = -ENOMEM; goto out; @@ -1276,8 +1276,7 @@ static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt, __func__, i, cfg_info->nblocks); break; } - bk_da[i] = kzalloc(sizeof(struct pcmdevice_block_data), - GFP_KERNEL); + bk_da[i] = kzalloc_obj(struct pcmdevice_block_data); if (!bk_da[i]) { *status = -ENOMEM; break; @@ -1549,7 +1548,7 @@ static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt) ret = -EINVAL; goto out; } - cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL); + cfg_info = kzalloc_objs(*cfg_info, fw_hdr->nconfig); if (!cfg_info) { pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; ret = -ENOMEM; diff --git a/sound/soc/codecs/pm4125-sdw.c b/sound/soc/codecs/pm4125-sdw.c index 3167b38e2876..1c612ae4a4b2 100644 --- a/sound/soc/codecs/pm4125-sdw.c +++ b/sound/soc/codecs/pm4125-sdw.c @@ -436,13 +436,11 @@ static int pm4125_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) return 0; } -static int pm4125_remove(struct sdw_slave *pdev) +static void pm4125_remove(struct sdw_slave *pdev) { struct device *dev = &pdev->dev; component_del(dev, &wcd_sdw_component_ops); - - return 0; } static const struct sdw_device_id pm4125_slave_id[] = { diff --git a/sound/soc/codecs/rt1011.c b/sound/soc/codecs/rt1011.c index 9f34a6a35487..03f31d9d916e 100644 --- a/sound/soc/codecs/rt1011.c +++ b/sound/soc/codecs/rt1011.c @@ -1047,7 +1047,7 @@ static int rt1011_recv_spk_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt1011_priv *rt1011 = snd_soc_component_get_drvdata(component); diff --git a/sound/soc/codecs/rt1017-sdca-sdw.c b/sound/soc/codecs/rt1017-sdca-sdw.c index a9c000876be8..148b36173a25 100644 --- a/sound/soc/codecs/rt1017-sdca-sdw.c +++ b/sound/soc/codecs/rt1017-sdca-sdw.c @@ -741,14 +741,12 @@ static int rt1017_sdca_sdw_probe(struct sdw_slave *slave, return rt1017_sdca_init(&slave->dev, regmap, slave); } -static int rt1017_sdca_sdw_remove(struct sdw_slave *slave) +static void rt1017_sdca_sdw_remove(struct sdw_slave *slave) { struct rt1017_sdca_priv *rt1017 = dev_get_drvdata(&slave->dev); if (rt1017->first_hw_init) pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt1017_sdca_id[] = { diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index b6c224832a43..e077d096bc23 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -739,11 +739,9 @@ static int rt1308_sdw_probe(struct sdw_slave *slave, return rt1308_sdw_init(&slave->dev, regmap, slave); } -static int rt1308_sdw_remove(struct sdw_slave *slave) +static void rt1308_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt1308_id[] = { diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 01a977398864..20fc1579eb9c 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -716,11 +716,9 @@ static int rt1316_sdw_probe(struct sdw_slave *slave, return rt1316_sdw_init(&slave->dev, regmap, slave); } -static int rt1316_sdw_remove(struct sdw_slave *slave) +static void rt1316_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt1316_id[] = { diff --git a/sound/soc/codecs/rt1318-sdw.c b/sound/soc/codecs/rt1318-sdw.c index 70db5450d6d2..d28f1afe68f1 100644 --- a/sound/soc/codecs/rt1318-sdw.c +++ b/sound/soc/codecs/rt1318-sdw.c @@ -793,11 +793,9 @@ static int rt1318_sdw_probe(struct sdw_slave *slave, return rt1318_sdw_init(&slave->dev, regmap, slave); } -static int rt1318_sdw_remove(struct sdw_slave *slave) +static void rt1318_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt1318_id[] = { diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c index 977881994e60..8bb7e8497c72 100644 --- a/sound/soc/codecs/rt1320-sdw.c +++ b/sound/soc/codecs/rt1320-sdw.c @@ -2629,7 +2629,7 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, struct sdw_port_config port_config; struct sdw_port_config dmic_port_config[2]; struct sdw_stream_runtime *sdw_stream; - int retval; + int retval, num_channels; unsigned int sampling_rate; dev_dbg(dai->dev, "%s %s", __func__, dai->name); @@ -2661,7 +2661,8 @@ static int rt1320_sdw_hw_params(struct snd_pcm_substream *substream, dmic_port_config[1].num = 10; break; case RT1321_DEV_ID: - dmic_port_config[0].ch_mask = BIT(0) | BIT(1); + num_channels = params_channels(params); + dmic_port_config[0].ch_mask = GENMASK(num_channels - 1, 0); dmic_port_config[0].num = 8; break; default: @@ -2950,14 +2951,12 @@ static int rt1320_sdw_probe(struct sdw_slave *slave, return rt1320_sdw_init(&slave->dev, regmap, mbq_regmap, slave); } -static int rt1320_sdw_remove(struct sdw_slave *slave) +static void rt1320_sdw_remove(struct sdw_slave *slave) { struct rt1320_sdw_priv *rt1320 = dev_get_drvdata(&slave->dev); cancel_work_sync(&rt1320->load_dspfw_work); pm_runtime_disable(&slave->dev); - - return 0; } /* diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index 055bea0a4a3b..fc464538ceff 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -690,7 +690,7 @@ static int rt5682_sdw_probe(struct sdw_slave *slave, return rt5682_sdw_init(&slave->dev, regmap, slave); } -static int rt5682_sdw_remove(struct sdw_slave *slave) +static void rt5682_sdw_remove(struct sdw_slave *slave) { struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev); @@ -698,8 +698,6 @@ static int rt5682_sdw_remove(struct sdw_slave *slave) cancel_delayed_work_sync(&rt5682->jack_detect_work); pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt5682_id[] = { diff --git a/sound/soc/codecs/rt700-sdw.c b/sound/soc/codecs/rt700-sdw.c index 44543c0da177..9ce36a66fae1 100644 --- a/sound/soc/codecs/rt700-sdw.c +++ b/sound/soc/codecs/rt700-sdw.c @@ -455,7 +455,7 @@ static int rt700_sdw_probe(struct sdw_slave *slave, return rt700_init(&slave->dev, sdw_regmap, regmap, slave); } -static int rt700_sdw_remove(struct sdw_slave *slave) +static void rt700_sdw_remove(struct sdw_slave *slave) { struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); @@ -465,8 +465,6 @@ static int rt700_sdw_remove(struct sdw_slave *slave) } pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt700_id[] = { diff --git a/sound/soc/codecs/rt711-sdca-sdw.c b/sound/soc/codecs/rt711-sdca-sdw.c index 6eb05871db37..49dacceddf81 100644 --- a/sound/soc/codecs/rt711-sdca-sdw.c +++ b/sound/soc/codecs/rt711-sdca-sdw.c @@ -365,7 +365,7 @@ static int rt711_sdca_sdw_probe(struct sdw_slave *slave, return rt711_sdca_init(&slave->dev, regmap, mbq_regmap, slave); } -static int rt711_sdca_sdw_remove(struct sdw_slave *slave) +static void rt711_sdca_sdw_remove(struct sdw_slave *slave) { struct rt711_sdca_priv *rt711 = dev_get_drvdata(&slave->dev); @@ -378,8 +378,6 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave) mutex_destroy(&rt711->calibrate_mutex); mutex_destroy(&rt711->disable_irq_lock); - - return 0; } static const struct sdw_device_id rt711_sdca_id[] = { diff --git a/sound/soc/codecs/rt711-sdw.c b/sound/soc/codecs/rt711-sdw.c index 93a5a89a96b1..72ddf4cebdf3 100644 --- a/sound/soc/codecs/rt711-sdw.c +++ b/sound/soc/codecs/rt711-sdw.c @@ -458,7 +458,7 @@ static int rt711_sdw_probe(struct sdw_slave *slave, return rt711_init(&slave->dev, sdw_regmap, regmap, slave); } -static int rt711_sdw_remove(struct sdw_slave *slave) +static void rt711_sdw_remove(struct sdw_slave *slave) { struct rt711_priv *rt711 = dev_get_drvdata(&slave->dev); @@ -472,8 +472,6 @@ static int rt711_sdw_remove(struct sdw_slave *slave) mutex_destroy(&rt711->calibrate_mutex); mutex_destroy(&rt711->disable_irq_lock); - - return 0; } static const struct sdw_device_id rt711_id[] = { diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c index 2928649e80e4..4d83544ef204 100644 --- a/sound/soc/codecs/rt712-sdca-dmic.c +++ b/sound/soc/codecs/rt712-sdca-dmic.c @@ -960,11 +960,9 @@ static int rt712_sdca_dmic_sdw_probe(struct sdw_slave *slave, return rt712_sdca_dmic_init(&slave->dev, regmap, mbq_regmap, slave); } -static int rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave) +static void rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static struct sdw_driver rt712_sdca_dmic_sdw_driver = { diff --git a/sound/soc/codecs/rt712-sdca-sdw.c b/sound/soc/codecs/rt712-sdca-sdw.c index ea07131edfa2..8c82887174db 100644 --- a/sound/soc/codecs/rt712-sdca-sdw.c +++ b/sound/soc/codecs/rt712-sdca-sdw.c @@ -374,7 +374,7 @@ static int rt712_sdca_sdw_probe(struct sdw_slave *slave, return rt712_sdca_init(&slave->dev, regmap, mbq_regmap, slave); } -static int rt712_sdca_sdw_remove(struct sdw_slave *slave) +static void rt712_sdca_sdw_remove(struct sdw_slave *slave) { struct rt712_sdca_priv *rt712 = dev_get_drvdata(&slave->dev); @@ -387,8 +387,6 @@ static int rt712_sdca_sdw_remove(struct sdw_slave *slave) mutex_destroy(&rt712->calibrate_mutex); mutex_destroy(&rt712->disable_irq_lock); - - return 0; } static const struct sdw_device_id rt712_sdca_id[] = { diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index ce7d8955efc3..968bc183b8d8 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -191,11 +191,9 @@ static int rt715_sdca_sdw_probe(struct sdw_slave *slave, return rt715_sdca_init(&slave->dev, mbq_regmap, regmap, slave); } -static int rt715_sdca_sdw_remove(struct sdw_slave *slave) +static void rt715_sdca_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt715_sdca_id[] = { diff --git a/sound/soc/codecs/rt715-sdw.c b/sound/soc/codecs/rt715-sdw.c index a3df4bbedf86..49c91d015be4 100644 --- a/sound/soc/codecs/rt715-sdw.c +++ b/sound/soc/codecs/rt715-sdw.c @@ -471,11 +471,9 @@ static int rt715_sdw_probe(struct sdw_slave *slave, return rt715_init(&slave->dev, sdw_regmap, regmap, slave); } -static int rt715_sdw_remove(struct sdw_slave *slave) +static void rt715_sdw_remove(struct sdw_slave *slave) { pm_runtime_disable(&slave->dev); - - return 0; } static const struct sdw_device_id rt715_id[] = { diff --git a/sound/soc/codecs/rt721-sdca-sdw.c b/sound/soc/codecs/rt721-sdca-sdw.c index 4d8a12b13015..6eb8512975b8 100644 --- a/sound/soc/codecs/rt721-sdca-sdw.c +++ b/sound/soc/codecs/rt721-sdca-sdw.c @@ -415,7 +415,7 @@ static int rt721_sdca_sdw_probe(struct sdw_slave *slave, return rt721_sdca_init(&slave->dev, regmap, mbq_regmap, slave); } -static int rt721_sdca_sdw_remove(struct sdw_slave *slave) +static void rt721_sdca_sdw_remove(struct sdw_slave *slave) { struct rt721_sdca_priv *rt721 = dev_get_drvdata(&slave->dev); @@ -429,8 +429,6 @@ static int rt721_sdca_sdw_remove(struct sdw_slave *slave) mutex_destroy(&rt721->calibrate_mutex); mutex_destroy(&rt721->disable_irq_lock); - - return 0; } static const struct sdw_device_id rt721_sdca_id[] = { diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c index 8233532a1752..35960c225224 100644 --- a/sound/soc/codecs/rt721-sdca.c +++ b/sound/soc/codecs/rt721-sdca.c @@ -245,12 +245,12 @@ static void rt721_sdca_jack_preset(struct rt721_sdca_priv *rt721) regmap_write(rt721->mbq_regmap, 0x5b10007, 0x2000); regmap_write(rt721->mbq_regmap, 0x5B10017, 0x1b0f); rt_sdca_index_write(rt721->mbq_regmap, RT721_CBJ_CTRL, - RT721_CBJ_A0_GAT_CTRL1, 0x2a02); + RT721_CBJ_A0_GAT_CTRL1, 0x2205); rt_sdca_index_write(rt721->mbq_regmap, RT721_CAP_PORT_CTRL, RT721_HP_AMP_2CH_CAL4, 0xa105); rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, RT721_UAJ_TOP_TCON14, 0x3b33); - regmap_write(rt721->mbq_regmap, 0x310400, 0x3023); + regmap_write(rt721->mbq_regmap, 0x310400, 0x3043); rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, RT721_UAJ_TOP_TCON14, 0x3f33); rt_sdca_index_write(rt721->mbq_regmap, RT721_VENDOR_ANA_CTL, diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index a0f5601a262a..0a5b3ffa90da 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -428,7 +428,7 @@ static int rt722_sdca_sdw_probe(struct sdw_slave *slave, return rt722_sdca_init(&slave->dev, regmap, slave); } -static int rt722_sdca_sdw_remove(struct sdw_slave *slave) +static void rt722_sdca_sdw_remove(struct sdw_slave *slave) { struct rt722_sdca_priv *rt722 = dev_get_drvdata(&slave->dev); @@ -442,8 +442,6 @@ static int rt722_sdca_sdw_remove(struct sdw_slave *slave) mutex_destroy(&rt722->calibrate_mutex); mutex_destroy(&rt722->disable_irq_lock); - - return 0; } static const struct sdw_device_id rt722_sdca_id[] = { diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c index 201f74e3a7ae..3343dbb63d2b 100644 --- a/sound/soc/codecs/sigmadsp.c +++ b/sound/soc/codecs/sigmadsp.c @@ -270,7 +270,7 @@ static int sigma_fw_load_data(struct sigmadsp *sigmadsp, length -= sizeof(*data_chunk); - data = kzalloc(struct_size(data, data, length), GFP_KERNEL); + data = kzalloc_flex(*data, data, length); if (!data) return -ENOMEM; @@ -413,8 +413,7 @@ static int process_sigma_action(struct sigmadsp *sigmadsp, if (len < 3) return -EINVAL; - data = kzalloc(struct_size(data, data, size_sub(len, 2)), - GFP_KERNEL); + data = kzalloc_flex(*data, data, size_sub(len, 2)); if (!data) return -ENOMEM; diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c index 0e084c3a162d..5798d518d94c 100644 --- a/sound/soc/codecs/tas2781-fmwlib.c +++ b/sound/soc/codecs/tas2781-fmwlib.c @@ -32,6 +32,10 @@ #define TAS2781_YRAM1_PAGE 42 #define TAS2781_YRAM1_START_REG 88 +#define TAS2781_PG_REG TASDEVICE_REG(0x00, 0x00, 0x7c) +#define TAS2781_PG_1_0 0xA0 +#define TAS2781_PG_2_0 0xA8 + #define TAS2781_YRAM2_START_PAGE 43 #define TAS2781_YRAM2_END_PAGE 49 #define TAS2781_YRAM2_START_REG 8 @@ -98,6 +102,12 @@ struct blktyp_devidx_map { unsigned char dev_idx; }; +struct tas2781_cali_specific { + unsigned char sin_gni[4]; + int sin_gni_reg; + bool is_sin_gn_flush; +}; + static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = { 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4, 1, 2 }; @@ -176,7 +186,7 @@ static struct tasdevice_config_info *tasdevice_add_config( * of audio cases, flexible configs have been introduced in the * dsp firmware. */ - cfg_info = kzalloc(sizeof(struct tasdevice_config_info), GFP_KERNEL); + cfg_info = kzalloc_obj(struct tasdevice_config_info); if (!cfg_info) { *status = -ENOMEM; goto out; @@ -217,8 +227,8 @@ static struct tasdevice_config_info *tasdevice_add_config( * the number and size of blk are not fixed and different among * these firmwares. */ - bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks, - sizeof(struct tasdev_blk_data *), GFP_KERNEL); + bk_da = cfg_info->blk_data = kzalloc_objs(struct tasdev_blk_data *, + cfg_info->nblocks); if (!bk_da) { *status = -ENOMEM; goto out; @@ -232,7 +242,7 @@ static struct tasdevice_config_info *tasdevice_add_config( __func__, i, cfg_info->nblocks); break; } - bk_da[i] = kzalloc(sizeof(struct tasdev_blk_data), GFP_KERNEL); + bk_da[i] = kzalloc_obj(struct tasdev_blk_data); if (!bk_da[i]) { *status = -ENOMEM; break; @@ -379,7 +389,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw) goto out; } - cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL); + cfg_info = kzalloc_objs(*cfg_info, fw_hdr->nconfig); if (!cfg_info) { ret = -ENOMEM; tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; @@ -509,8 +519,7 @@ static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw, img_data->nr_blk = get_unaligned_be32(&data[offset]); offset += 4; - img_data->dev_blks = kcalloc(img_data->nr_blk, - sizeof(struct tasdev_blk), GFP_KERNEL); + img_data->dev_blks = kzalloc_objs(struct tasdev_blk, img_data->nr_blk); if (!img_data->dev_blks) { offset = -ENOMEM; goto out; @@ -805,8 +814,8 @@ static int fw_parse_variable_header_kernel( goto out; } - tas_fmw->programs = kcalloc(tas_fmw->nr_programs, - sizeof(struct tasdevice_prog), GFP_KERNEL); + tas_fmw->programs = kzalloc_objs(struct tasdevice_prog, + tas_fmw->nr_programs); if (!tas_fmw->programs) { offset = -ENOMEM; goto out; @@ -844,8 +853,8 @@ static int fw_parse_variable_header_kernel( goto out; } - tas_fmw->configs = kcalloc(tas_fmw->nr_configurations, - sizeof(struct tasdevice_config), GFP_KERNEL); + tas_fmw->configs = kzalloc_objs(struct tasdevice_config, + tas_fmw->nr_configurations); if (!tas_fmw->configs) { offset = -ENOMEM; goto out; @@ -1239,8 +1248,7 @@ static int fw_parse_data(struct tasdevice_fw *tas_fmw, img_data->nr_blk = get_unaligned_be16(&data[offset]); offset += 2; - img_data->dev_blks = kcalloc(img_data->nr_blk, - sizeof(struct tasdev_blk), GFP_KERNEL); + img_data->dev_blks = kzalloc_objs(struct tasdev_blk, img_data->nr_blk); if (!img_data->dev_blks) { offset = -ENOMEM; goto out; @@ -1284,8 +1292,7 @@ static int fw_parse_program_data(struct tasdevice_priv *tas_priv, } tas_fmw->programs = - kcalloc(tas_fmw->nr_programs, sizeof(struct tasdevice_prog), - GFP_KERNEL); + kzalloc_objs(struct tasdevice_prog, tas_fmw->nr_programs); if (!tas_fmw->programs) { offset = -ENOMEM; goto out; @@ -1348,8 +1355,8 @@ static int fw_parse_configuration_data( /*Not error for calibration Data file, return directly*/ goto out; } - tas_fmw->configs = kcalloc(tas_fmw->nr_configurations, - sizeof(struct tasdevice_config), GFP_KERNEL); + tas_fmw->configs = kzalloc_objs(struct tasdevice_config, + tas_fmw->nr_configurations); if (!tas_fmw->configs) { offset = -ENOMEM; goto out; @@ -2143,8 +2150,8 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv, goto out; } - tas_fmw->calibrations = kcalloc(tas_fmw->nr_calibrations, - sizeof(struct tasdevice_calibration), GFP_KERNEL); + tas_fmw->calibrations = kzalloc_objs(struct tasdevice_calibration, + tas_fmw->nr_calibrations); if (!tas_fmw->calibrations) { offset = -ENOMEM; goto out; @@ -2206,8 +2213,7 @@ int tas2781_load_calibration(void *context, char *file_name, fmw.size = fw_entry->size; fmw.data = fw_entry->data; - tas_fmw = tasdev->cali_data_fmw = kzalloc(sizeof(struct tasdevice_fw), - GFP_KERNEL); + tas_fmw = tasdev->cali_data_fmw = kzalloc_obj(struct tasdevice_fw); if (!tasdev->cali_data_fmw) { ret = -ENOMEM; goto out; @@ -2267,7 +2273,7 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw, return -EINVAL; } - tas_priv->fmw = kzalloc(sizeof(struct tasdevice_fw), GFP_KERNEL); + tas_priv->fmw = kzalloc_obj(struct tasdevice_fw); if (!tas_priv->fmw) return -ENOMEM; @@ -2458,6 +2464,84 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv, return ret; } +static int tas2781_cali_preproc(struct tasdevice_priv *priv, int i) +{ + struct tas2781_cali_specific *spec = priv->tasdevice[i].cali_specific; + struct calidata *cali_data = &priv->cali_data; + struct cali_reg *p = &cali_data->cali_reg_array; + unsigned char *data = cali_data->data; + int rc; + + /* + * On TAS2781, if the Speaker calibrated impedance is lower than + * default value hard-coded inside the TAS2781, it will cuase vol + * lower than normal. In order to fix this issue, the parameter of + * SineGainI need updating. + */ + if (spec == NULL) { + int k = i * (cali_data->cali_dat_sz_per_dev + 1); + int re_org, re_cal, corrected_sin_gn, pg_id; + unsigned char r0_deflt[4]; + + spec = devm_kzalloc(priv->dev, sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + priv->tasdevice[i].cali_specific = spec; + rc = tasdevice_dev_bulk_read(priv, i, p->r0_reg, r0_deflt, 4); + if (rc < 0) { + dev_err(priv->dev, "invalid RE from %d = %d\n", i, rc); + return rc; + } + /* + * SineGainI need to be re-calculated, calculate the high 16 + * bits. + */ + re_org = r0_deflt[0] << 8 | r0_deflt[1]; + re_cal = data[k + 1] << 8 | data[k + 2]; + if (re_org > re_cal) { + rc = tasdevice_dev_read(priv, i, TAS2781_PG_REG, + &pg_id); + if (rc < 0) { + dev_err(priv->dev, "invalid PG id %d = %d\n", + i, rc); + return rc; + } + + spec->sin_gni_reg = (pg_id == TAS2781_PG_1_0) ? + TASDEVICE_REG(0, 0x1b, 0x34) : + TASDEVICE_REG(0, 0x18, 0x1c); + + rc = tasdevice_dev_bulk_read(priv, i, + spec->sin_gni_reg, + spec->sin_gni, 4); + if (rc < 0) { + dev_err(priv->dev, "wrong sinegaini %d = %d\n", + i, rc); + return rc; + } + corrected_sin_gn = re_org * ((spec->sin_gni[0] << 8) + + spec->sin_gni[1]); + corrected_sin_gn /= re_cal; + spec->sin_gni[0] = corrected_sin_gn >> 8; + spec->sin_gni[1] = corrected_sin_gn & 0xff; + + spec->is_sin_gn_flush = true; + } + } + + if (spec->is_sin_gn_flush) { + rc = tasdevice_dev_bulk_write(priv, i, spec->sin_gni_reg, + spec->sin_gni, 4); + if (rc < 0) { + dev_err(priv->dev, "update failed %d = %d\n", + i, rc); + return rc; + } + } + + return 0; +} + static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) { struct calidata *cali_data = &priv->cali_data; @@ -2473,6 +2557,12 @@ static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) } k++; + if (priv->chip_id == TAS2781) { + rc = tas2781_cali_preproc(priv, i); + if (rc < 0) + return; + } + rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4); if (rc < 0) { dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc); diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c index 3c1fbf523529..90008d2d06e2 100644 --- a/sound/soc/codecs/tas2783-sdw.c +++ b/sound/soc/codecs/tas2783-sdw.c @@ -733,8 +733,8 @@ static void tas2783_fw_ready(const struct firmware *fmw, void *context) s32 img_sz, ret = 0, cur_file = 0; s32 offset = 0; - struct tas_fw_hdr *hdr __free(kfree) = kzalloc(sizeof(*hdr), GFP_KERNEL); - struct tas_fw_file *file __free(kfree) = kzalloc(sizeof(*file), GFP_KERNEL); + struct tas_fw_hdr *hdr __free(kfree) = kzalloc_obj(*hdr); + struct tas_fw_file *file __free(kfree) = kzalloc_obj(*file); if (!file || !hdr) { ret = -ENOMEM; goto out; @@ -1216,8 +1216,51 @@ static s32 tas_update_status(struct sdw_slave *slave, return tas_io_init(&slave->dev, slave); } +/* + * TAS2783 requires explicit port prepare during playback stream + * setup even when simple_ch_prep_sm is enabled. Without this, + * the port fails to enter the prepared state resulting in no audio output. + */ +static int tas_port_prep(struct sdw_slave *slave, struct sdw_prepare_ch *prep_ch, + enum sdw_port_prep_ops pre_ops) +{ + struct device *dev = &slave->dev; + struct sdw_dpn_prop *dpn_prop; + u32 addr; + int ret; + + dpn_prop = slave->prop.sink_dpn_prop; + if (!dpn_prop || !dpn_prop->simple_ch_prep_sm) + return 0; + + addr = SDW_DPN_PREPARECTRL(prep_ch->num); + switch (pre_ops) { + case SDW_OPS_PORT_PRE_PREP: + ret = sdw_write_no_pm(slave, addr, prep_ch->ch_mask); + if (ret) + dev_err(dev, "prep failed for port %d, err=%d\n", + prep_ch->num, ret); + return ret; + + case SDW_OPS_PORT_PRE_DEPREP: + ret = sdw_write_no_pm(slave, addr, 0x00); + if (ret) + dev_err(dev, "de-prep failed for port %d, err=%d\n", + prep_ch->num, ret); + return ret; + + case SDW_OPS_PORT_POST_PREP: + case SDW_OPS_PORT_POST_DEPREP: + /* No POST handling required for TAS2783 */ + return 0; + } + + return 0; +} + static const struct sdw_slave_ops tas_sdw_ops = { .update_status = tas_update_status, + .port_prep = tas_port_prep, }; static void tas_remove(struct tas2783_prv *tas_dev) @@ -1299,7 +1342,7 @@ static s32 tas_sdw_probe(struct sdw_slave *peripheral, return tas_init(tas_dev); } -static s32 tas_sdw_remove(struct sdw_slave *peripheral) +static void tas_sdw_remove(struct sdw_slave *peripheral) { struct tas2783_prv *tas_dev = dev_get_drvdata(&peripheral->dev); @@ -1308,8 +1351,6 @@ static s32 tas_sdw_remove(struct sdw_slave *peripheral) mutex_destroy(&tas_dev->calib_lock); mutex_destroy(&tas_dev->pde_lock); dev_set_drvdata(&peripheral->dev, NULL); - - return 0; } static const struct sdw_device_id tas_sdw_id[] = { diff --git a/sound/soc/codecs/wcd-clsh-v2.c b/sound/soc/codecs/wcd-clsh-v2.c index d96e23ec43d4..13d07296916f 100644 --- a/sound/soc/codecs/wcd-clsh-v2.c +++ b/sound/soc/codecs/wcd-clsh-v2.c @@ -883,7 +883,7 @@ struct wcd_clsh_ctrl *wcd_clsh_ctrl_alloc(struct snd_soc_component *comp, { struct wcd_clsh_ctrl *ctrl; - ctrl = kzalloc(sizeof(*ctrl), GFP_KERNEL); + ctrl = kzalloc_obj(*ctrl); if (!ctrl) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 0c842aaa7eec..bb0c8478a8eb 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -1515,7 +1515,7 @@ struct wcd_mbhc *wcd_mbhc_init(struct snd_soc_component *component, return ERR_PTR(-EINVAL); } - mbhc = kzalloc(sizeof(*mbhc), GFP_KERNEL); + mbhc = kzalloc_obj(*mbhc); if (!mbhc) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/codecs/wcd937x-sdw.c b/sound/soc/codecs/wcd937x-sdw.c index 1878d67e3fa1..7a18bed7f347 100644 --- a/sound/soc/codecs/wcd937x-sdw.c +++ b/sound/soc/codecs/wcd937x-sdw.c @@ -1056,13 +1056,11 @@ static int wcd9370_probe(struct sdw_slave *pdev, return 0; } -static int wcd9370_remove(struct sdw_slave *pdev) +static void wcd9370_remove(struct sdw_slave *pdev) { struct device *dev = &pdev->dev; component_del(dev, &wcd_sdw_component_ops); - - return 0; } static const struct sdw_device_id wcd9370_slave_id[] = { diff --git a/sound/soc/codecs/wcd938x-sdw.c b/sound/soc/codecs/wcd938x-sdw.c index 8c8f39d04972..0f0cc0ac3056 100644 --- a/sound/soc/codecs/wcd938x-sdw.c +++ b/sound/soc/codecs/wcd938x-sdw.c @@ -1217,13 +1217,11 @@ static int wcd9380_probe(struct sdw_slave *pdev, return 0; } -static int wcd9380_remove(struct sdw_slave *pdev) +static void wcd9380_remove(struct sdw_slave *pdev) { struct device *dev = &pdev->dev; component_del(dev, &wcd_sdw_component_ops); - - return 0; } static const struct sdw_device_id wcd9380_slave_id[] = { diff --git a/sound/soc/codecs/wcd939x-sdw.c b/sound/soc/codecs/wcd939x-sdw.c index 399dfba79aa2..95f4be287e79 100644 --- a/sound/soc/codecs/wcd939x-sdw.c +++ b/sound/soc/codecs/wcd939x-sdw.c @@ -1403,13 +1403,11 @@ static int wcd9390_probe(struct sdw_slave *pdev, const struct sdw_device_id *id) return 0; } -static int wcd9390_remove(struct sdw_slave *pdev) +static void wcd9390_remove(struct sdw_slave *pdev) { struct device *dev = &pdev->dev; component_del(dev, &wcd_sdw_component_ops); - - return 0; } static const struct sdw_device_id wcd9390_slave_id[] = { diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 6e097d8ed288..2a8c61a72c17 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c @@ -396,7 +396,7 @@ static int wm0010_firmware_load(const char *name, struct snd_soc_component *comp rec->command, rec->length); len = rec->length + 8; - xfer = kzalloc(sizeof(*xfer), GFP_KERNEL); + xfer = kzalloc_obj(*xfer); if (!xfer) { ret = -ENOMEM; goto abort; diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 17cec79245d4..2e23848e1dce 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -542,7 +542,7 @@ static void wm_adsp_ctl_work(struct work_struct *work) cs_dsp); struct snd_kcontrol_new *kcontrol; - kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); + kcontrol = kzalloc_obj(*kcontrol); if (!kcontrol) return; @@ -627,7 +627,7 @@ int wm_adsp_control_add(struct cs_dsp_coeff_ctl *cs_ctl) " %.*s", cs_ctl->subname_len - skip, cs_ctl->subname + skip); } - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kzalloc_obj(*ctl); if (!ctl) return -ENOMEM; ctl->cs_ctl = cs_ctl; @@ -1259,7 +1259,7 @@ int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) } } - compr = kzalloc(sizeof(*compr), GFP_KERNEL); + compr = kzalloc_obj(*compr); if (!compr) { ret = -ENOMEM; goto out; @@ -1430,8 +1430,7 @@ static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) u32 offset = 0; int i, ret; - buf->regions = kcalloc(caps->num_regions, sizeof(*buf->regions), - GFP_KERNEL); + buf->regions = kzalloc_objs(*buf->regions, caps->num_regions); if (!buf->regions) return -ENOMEM; @@ -1477,7 +1476,7 @@ static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) { struct wm_adsp_compr_buf *buf; - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kzalloc_obj(*buf); if (!buf) return NULL; diff --git a/sound/soc/fsl/fsl_asrc_m2m.c b/sound/soc/fsl/fsl_asrc_m2m.c index 77999526dd9e..7d39378c0622 100644 --- a/sound/soc/fsl/fsl_asrc_m2m.c +++ b/sound/soc/fsl/fsl_asrc_m2m.c @@ -155,7 +155,7 @@ static int asrc_dmaconfig(struct fsl_asrc_pair *pair, if (buf_len % max_period_size) sg_len += 1; - sg = kmalloc_array(sg_len, sizeof(*sg), GFP_KERNEL); + sg = kmalloc_objs(*sg, sg_len); if (!sg) return -ENOMEM; @@ -420,7 +420,7 @@ static struct sg_table *fsl_asrc_m2m_map_dma_buf(struct dma_buf_attachment *atta struct snd_dma_buffer *dmab = attachment->dmabuf->priv; struct sg_table *sgt; - sgt = kmalloc(sizeof(*sgt), GFP_KERNEL); + sgt = kmalloc_obj(*sgt); if (!sgt) return NULL; diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index aca066b5a43c..26ddbe867b58 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c @@ -848,7 +848,7 @@ static int fsl_soc_dma_probe(struct platform_device *pdev) return ret; } - dma = kzalloc(sizeof(*dma), GFP_KERNEL); + dma = kzalloc_obj(*dma); if (!dma) { of_node_put(ssi_np); return -ENOMEM; diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c index e64a0d97afd0..6c56134c60cc 100644 --- a/sound/soc/fsl/fsl_easrc.c +++ b/sound/soc/fsl/fsl_easrc.c @@ -52,10 +52,13 @@ static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol, struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; unsigned int regval = ucontrol->value.integer.value[0]; + int ret; + + ret = (easrc_priv->bps_iec958[mc->regbase] != regval); easrc_priv->bps_iec958[mc->regbase] = regval; - return 0; + return ret; } static int fsl_easrc_iec958_get_bits(struct snd_kcontrol *kcontrol, @@ -93,14 +96,17 @@ static int fsl_easrc_set_reg(struct snd_kcontrol *kcontrol, struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); struct soc_mreg_control *mc = (struct soc_mreg_control *)kcontrol->private_value; + struct fsl_asrc *easrc = snd_soc_component_get_drvdata(component); unsigned int regval = ucontrol->value.integer.value[0]; + bool changed; int ret; - ret = snd_soc_component_write(component, mc->regbase, regval); - if (ret < 0) + ret = regmap_update_bits_check(easrc->regmap, mc->regbase, + GENMASK(31, 0), regval, &changed); + if (ret != 0) return ret; - return 0; + return changed; } #define SOC_SINGLE_REG_RW(xname, xreg) \ diff --git a/sound/soc/fsl/fsl_qmc_audio.c b/sound/soc/fsl/fsl_qmc_audio.c index 3de448ef724c..43d401ae2d03 100644 --- a/sound/soc/fsl/fsl_qmc_audio.c +++ b/sound/soc/fsl/fsl_qmc_audio.c @@ -316,7 +316,7 @@ static int qmc_audio_pcm_open(struct snd_soc_component *component, if (ret < 0) return ret; - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (!prtd) return -ENOMEM; diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index 5de93f458b56..a268fb81a2f8 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -223,13 +223,10 @@ static int fsl_xcvr_mode_put(struct snd_kcontrol *kcontrol, xcvr->mode = snd_soc_enum_item_to_val(e, item[0]); - down_read(&card->snd_card->controls_rwsem); fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, (xcvr->mode == FSL_XCVR_MODE_ARC)); fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, (xcvr->mode == FSL_XCVR_MODE_EARC)); - up_read(&card->snd_card->controls_rwsem); - /* Allow playback for SPDIF only */ rtd = snd_soc_get_pcm_runtime(card, card->dai_link); rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count = diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c index 83de3ae33691..d51a3de493cb 100644 --- a/sound/soc/fsl/imx-pcm-fiq.c +++ b/sound/soc/fsl/imx-pcm-fiq.c @@ -176,7 +176,7 @@ static int snd_imx_open(struct snd_soc_component *component, struct imx_pcm_runtime_data *iprtd; int ret; - iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); + iprtd = kzalloc_obj(*iprtd); if (iprtd == NULL) return -ENOMEM; runtime->private_data = iprtd; diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c index 345f338251ac..a593a95aa532 100644 --- a/sound/soc/fsl/mpc5200_dma.c +++ b/sound/soc/fsl/mpc5200_dma.c @@ -333,7 +333,7 @@ int mpc5200_audio_dma_create(struct platform_device *op) } /* Allocate and initialize the driver private data */ - psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); + psc_dma = kzalloc_obj(*psc_dma); if (!psc_dma) { ret = -ENOMEM; goto out_unmap; diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index 66db05970d82..db07817a8024 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c @@ -211,7 +211,7 @@ static int p1022_ds_probe(struct platform_device *pdev) return -EINVAL; } - mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL); + mdata = kzalloc_obj(struct machine_data); if (!mdata) { ret = -ENOMEM; goto error_put; diff --git a/sound/soc/fsl/p1022_rdk.c b/sound/soc/fsl/p1022_rdk.c index d4568346714f..f80d6d04e791 100644 --- a/sound/soc/fsl/p1022_rdk.c +++ b/sound/soc/fsl/p1022_rdk.c @@ -226,7 +226,7 @@ static int p1022_rdk_probe(struct platform_device *pdev) return -EINVAL; } - mdata = kzalloc(sizeof(struct machine_data), GFP_KERNEL); + mdata = kzalloc_obj(struct machine_data); if (!mdata) { ret = -ENOMEM; goto error_put; diff --git a/sound/soc/generic/audio-graph-card.c b/sound/soc/generic/audio-graph-card.c index 7720cf1fd6e1..8a5f41704739 100644 --- a/sound/soc/generic/audio-graph-card.c +++ b/sound/soc/generic/audio-graph-card.c @@ -553,7 +553,7 @@ int audio_graph_parse_of(struct simple_util_priv *priv, struct device *dev) struct snd_soc_card *card = simple_priv_to_card(priv); int ret = -ENOMEM; - struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); + struct link_info *li __free(kfree) = kzalloc_obj(*li); if (!li) goto end; diff --git a/sound/soc/generic/audio-graph-card2.c b/sound/soc/generic/audio-graph-card2.c index 5dcc78c551a2..0202ed0ee78e 100644 --- a/sound/soc/generic/audio-graph-card2.c +++ b/sound/soc/generic/audio-graph-card2.c @@ -1305,7 +1305,7 @@ int audio_graph2_parse_of(struct simple_util_priv *priv, struct device *dev, struct snd_soc_card *card = simple_priv_to_card(priv); int ret; - struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); + struct link_info *li __free(kfree) = kzalloc_obj(*li); if (!li) return -ENOMEM; diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c index bdc02e85b089..9e5be0eaa77f 100644 --- a/sound/soc/generic/simple-card-utils.c +++ b/sound/soc/generic/simple-card-utils.c @@ -1038,11 +1038,15 @@ int graph_util_is_ports0(struct device_node *np) else port = np; - struct device_node *ports __free(device_node) = of_get_parent(port); - struct device_node *top __free(device_node) = of_get_parent(ports); - struct device_node *ports0 __free(device_node) = of_get_child_by_name(top, "ports"); + struct device_node *ports __free(device_node) = of_get_parent(port); + const char *at = strchr(kbasename(ports->full_name), '@'); - return ports0 == ports; + /* + * Since child iteration order may differ + * between a base DT and DT overlays, + * string match "ports" or "ports@0" in the node name instead. + */ + return !at || !strcmp(at, "@0"); } EXPORT_SYMBOL_GPL(graph_util_is_ports0); diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 5af6d1b308f2..06638f9a74b8 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -726,7 +726,7 @@ static int simple_probe(struct platform_device *pdev) card->driver_name = "simple-card"; ret = -ENOMEM; - struct link_info *li __free(kfree) = kzalloc(sizeof(*li), GFP_KERNEL); + struct link_info *li __free(kfree) = kzalloc_obj(*li); if (!li) goto end; diff --git a/sound/soc/intel/atom/sst-mfld-platform-compress.c b/sound/soc/intel/atom/sst-mfld-platform-compress.c index 9dfb0a814b94..b0ba1af0a65f 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-compress.c +++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c @@ -47,7 +47,7 @@ static int sst_platform_compr_open(struct snd_soc_component *component, struct snd_compr_runtime *runtime = cstream->runtime; struct sst_runtime_stream *stream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c index 373d68b4cf88..67caea39b557 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c +++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c @@ -306,7 +306,7 @@ static int sst_media_open(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct sst_runtime_stream *stream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; spin_lock_init(&stream->status_lock); diff --git a/sound/soc/intel/atom/sst/sst.c b/sound/soc/intel/atom/sst/sst.c index 3c47c8de04b7..d9d695ed7cfb 100644 --- a/sound/soc/intel/atom/sst/sst.c +++ b/sound/soc/intel/atom/sst/sst.c @@ -463,7 +463,7 @@ static int intel_sst_suspend(struct device *dev) return -EBUSY; /* save the memories */ - fw_save = kzalloc(sizeof(*fw_save), GFP_KERNEL); + fw_save = kzalloc_obj(*fw_save); if (!fw_save) return -ENOMEM; fw_save->iram = kvzalloc(ctx->iram_end - ctx->iram_base, GFP_KERNEL); diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 0630e58b9d6b..0d5e71e8a5b5 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c @@ -31,7 +31,7 @@ struct sst_block *sst_create_block(struct intel_sst_drv *ctx, struct sst_block *msg; dev_dbg(ctx->dev, "Enter\n"); - msg = kzalloc(sizeof(*msg), GFP_KERNEL); + msg = kzalloc_obj(*msg); if (!msg) return NULL; msg->condition = false; diff --git a/sound/soc/intel/atom/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c index bf4ba6bcc429..a043443d2887 100644 --- a/sound/soc/intel/atom/sst/sst_loader.c +++ b/sound/soc/intel/atom/sst/sst_loader.c @@ -148,7 +148,7 @@ static int sst_fill_memcpy_list(struct list_head *memcpy_list, { struct sst_memcpy_list *listnode; - listnode = kzalloc(sizeof(*listnode), GFP_KERNEL); + listnode = kzalloc_obj(*listnode); if (listnode == NULL) return -ENOMEM; listnode->dstn = destn; diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c index c01b29616ebc..67b1ab14239f 100644 --- a/sound/soc/intel/atom/sst/sst_pvt.c +++ b/sound/soc/intel/atom/sst/sst_pvt.c @@ -124,7 +124,7 @@ int sst_create_ipc_msg(struct ipc_post **arg, bool large) { struct ipc_post *msg; - msg = kzalloc(sizeof(*msg), GFP_ATOMIC); + msg = kzalloc_obj(*msg, GFP_ATOMIC); if (!msg) return -ENOMEM; if (large) { diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c index 899906e0bcb4..2291f9728a54 100644 --- a/sound/soc/intel/avs/path.c +++ b/sound/soc/intel/avs/path.c @@ -880,7 +880,7 @@ avs_path_module_create(struct avs_dev *adev, if (module_id < 0) return ERR_PTR(module_id); - mod = kzalloc(sizeof(*mod), GFP_KERNEL); + mod = kzalloc_obj(*mod); if (!mod) return ERR_PTR(-ENOMEM); @@ -968,7 +968,7 @@ static struct avs_path_binding *avs_path_binding_create(struct avs_dev *adev, { struct avs_path_binding *binding; - binding = kzalloc(sizeof(*binding), GFP_KERNEL); + binding = kzalloc_obj(*binding); if (!binding) return ERR_PTR(-ENOMEM); @@ -1043,7 +1043,7 @@ avs_path_pipeline_create(struct avs_dev *adev, struct avs_path *owner, struct avs_tplg_module *tmod; int ret, i; - ppl = kzalloc(sizeof(*ppl), GFP_KERNEL); + ppl = kzalloc_obj(*ppl); if (!ppl) return ERR_PTR(-ENOMEM); @@ -1173,7 +1173,7 @@ static struct avs_path *avs_path_create_unlocked(struct avs_dev *adev, u32 dma_i struct avs_path *path; int ret; - path = kzalloc(sizeof(*path), GFP_KERNEL); + path = kzalloc_obj(*path); if (!path) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 4a6deb599c88..d53c2f76fcd4 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -130,7 +130,7 @@ static int avs_dai_startup(struct snd_pcm_substream *substream, struct snd_soc_d return -EINVAL; } - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/soc/intel/avs/utils.c b/sound/soc/intel/avs/utils.c index 81f9b67d8e29..ee36725ac731 100644 --- a/sound/soc/intel/avs/utils.c +++ b/sound/soc/intel/avs/utils.c @@ -124,7 +124,7 @@ avs_module_ida_alloc(struct avs_dev *adev, struct avs_mods_info *newinfo, bool p tocopy_count = oldinfo->count; } - ida_ptrs = kcalloc(newinfo->count, sizeof(*ida_ptrs), GFP_KERNEL); + ida_ptrs = kzalloc_objs(*ida_ptrs, newinfo->count); if (!ida_ptrs) return -ENOMEM; @@ -132,7 +132,7 @@ avs_module_ida_alloc(struct avs_dev *adev, struct avs_mods_info *newinfo, bool p memcpy(ida_ptrs, adev->mod_idas, tocopy_count * sizeof(*ida_ptrs)); for (i = tocopy_count; i < newinfo->count; i++) { - ida_ptrs[i] = kzalloc(sizeof(**ida_ptrs), GFP_KERNEL); + ida_ptrs[i] = kzalloc_obj(**ida_ptrs); if (!ida_ptrs[i]) { while (i--) kfree(ida_ptrs[i]); @@ -246,7 +246,7 @@ int avs_request_firmware(struct avs_dev *adev, const struct firmware **fw_p, con } /* FW is not loaded, let's load it now and add to the list */ - entry = kzalloc(sizeof(*entry), GFP_KERNEL); + entry = kzalloc_obj(*entry); if (!entry) return -ENOMEM; diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index ee34282828e4..c18ec607e029 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -763,6 +763,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { }, .driver_data = (void *)(SOC_SDW_CODEC_SPKR), }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Alienware"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CCD") + }, + .driver_data = (void *)(SOC_SDW_CODEC_SPKR), + }, /* Pantherlake devices*/ { .callback = sof_sdw_quirk_cb, @@ -1251,12 +1259,12 @@ static int sof_card_dai_links_create(struct snd_soc_card *card) * add one additional to act as a terminator such that code can iterate * until it hits an uninitialised DAI. */ - sof_dais = kcalloc(num_ends + 1, sizeof(*sof_dais), GFP_KERNEL); + sof_dais = kzalloc_objs(*sof_dais, num_ends + 1); if (!sof_dais) return -ENOMEM; /* One per endpoint, ie. each DAI on each codec/amp */ - sof_ends = kcalloc(num_ends, sizeof(*sof_ends), GFP_KERNEL); + sof_ends = kzalloc_objs(*sof_ends, num_ends); if (!sof_ends) { ret = -ENOMEM; goto err_dai; diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c index 2c3405686f79..2c5ea4e0ff3d 100644 --- a/sound/soc/intel/catpt/pcm.c +++ b/sound/soc/intel/catpt/pcm.c @@ -263,7 +263,7 @@ static int catpt_dai_startup(struct snd_pcm_substream *substream, template = catpt_get_stream_template(substream); - stream = kzalloc(sizeof(*stream), GFP_KERNEL); + stream = kzalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c index 20e4a0641340..f26b2951bc9c 100644 --- a/sound/soc/loongson/loongson_dma.c +++ b/sound/soc/loongson/loongson_dma.c @@ -243,7 +243,7 @@ static int loongson_pcm_open(struct snd_soc_component *component, SNDRV_PCM_HW_PARAM_PERIODS); snd_soc_set_runtime_hwparams(substream, &ls_pcm_hardware); - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (!prtd) return -ENOMEM; diff --git a/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c index 5666be6b1bd2..642f4fb55ca6 100644 --- a/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c +++ b/sound/soc/mediatek/mt8186/mt8186-audsys-clk.c @@ -135,7 +135,7 @@ int mt8186_audsys_clk_register(struct mtk_base_afe *afe) } /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */ - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return -ENOMEM; diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c index 40d2ab0a7677..972f097a13ca 100644 --- a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c +++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c @@ -193,7 +193,7 @@ int mt8188_audsys_clk_register(struct mtk_base_afe *afe) } /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */ - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return -ENOMEM; diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c index 38594bc3f2f7..e6fefc320443 100644 --- a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c @@ -199,7 +199,7 @@ int mt8195_audsys_clk_register(struct mtk_base_afe *afe) } /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */ - cl = kzalloc(sizeof(*cl), GFP_KERNEL); + cl = kzalloc_obj(*cl); if (!cl) return -ENOMEM; diff --git a/sound/soc/meson/aiu-fifo.c b/sound/soc/meson/aiu-fifo.c index b222bde1f61b..8b54f9681d00 100644 --- a/sound/soc/meson/aiu-fifo.c +++ b/sound/soc/meson/aiu-fifo.c @@ -196,7 +196,7 @@ int aiu_fifo_dai_probe(struct snd_soc_dai *dai) { struct aiu_fifo *fifo; - fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); + fifo = kzalloc_obj(*fifo); if (!fifo) return -ENOMEM; diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c index a6579efd3775..f451e4dce442 100644 --- a/sound/soc/meson/axg-tdm-formatter.c +++ b/sound/soc/meson/axg-tdm-formatter.c @@ -368,7 +368,7 @@ struct axg_tdm_stream *axg_tdm_stream_alloc(struct axg_tdm_iface *iface) { struct axg_tdm_stream *ts; - ts = kzalloc(sizeof(*ts), GFP_KERNEL); + ts = kzalloc_obj(*ts); if (ts) { INIT_LIST_HEAD(&ts->formatter_list); mutex_init(&ts->lock); diff --git a/sound/soc/meson/meson-codec-glue.c b/sound/soc/meson/meson-codec-glue.c index f8c5643f3cfe..2ff6066e1b6c 100644 --- a/sound/soc/meson/meson-codec-glue.c +++ b/sound/soc/meson/meson-codec-glue.c @@ -122,7 +122,7 @@ int meson_codec_glue_input_dai_probe(struct snd_soc_dai *dai) { struct meson_codec_glue_input *data; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index b8a3cb8b7597..c34bfa27a446 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c @@ -85,7 +85,7 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, clk_prepare_enable(priv->extclk); - dma = kzalloc(sizeof(struct snd_dmaengine_dai_dma_data), GFP_KERNEL); + dma = kzalloc_obj(struct snd_dmaengine_dai_dma_data); if (!dma) return -ENOMEM; dma->chan_name = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? @@ -749,7 +749,7 @@ static int pxa_ssp_probe(struct snd_soc_dai *dai) struct ssp_priv *priv; int ret; - priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL); + priv = kzalloc_obj(struct ssp_priv); if (!priv) return -ENOMEM; diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c index b456e096f138..ce6896cc015d 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -202,7 +202,7 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, struct regmap *map; unsigned int dai_id = cpu_dai->driver->id; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; diff --git a/sound/soc/qcom/qdsp6/q6adm.c b/sound/soc/qcom/qdsp6/q6adm.c index 40bc44003453..db0ae71f2983 100644 --- a/sound/soc/qcom/qdsp6/q6adm.c +++ b/sound/soc/qcom/qdsp6/q6adm.c @@ -284,7 +284,7 @@ static struct q6copp *q6adm_alloc_copp(struct q6adm *adm, int port_idx) if (idx >= MAX_COPPS_PER_PORT) return ERR_PTR(-EBUSY); - c = kzalloc(sizeof(*c), GFP_ATOMIC); + c = kzalloc_obj(*c, GFP_ATOMIC); if (!c) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/qcom/qdsp6/q6afe.c b/sound/soc/qcom/qdsp6/q6afe.c index 76e14fc1b2b5..43d877322bae 100644 --- a/sound/soc/qcom/qdsp6/q6afe.c +++ b/sound/soc/qcom/qdsp6/q6afe.c @@ -1359,7 +1359,7 @@ void q6afe_tdm_port_prepare(struct q6afe_port *port, pcfg->tdm_cfg.slot_width = cfg->slot_width; pcfg->tdm_cfg.slot_mask = cfg->slot_mask; - port->scfg = kzalloc(sizeof(*port->scfg), GFP_KERNEL); + port->scfg = kzalloc_obj(*port->scfg); if (!port->scfg) return; diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c index aaeeadded7aa..168c166c960d 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -348,7 +348,7 @@ static int q6apm_dai_open(struct snd_soc_component *component, return -EINVAL; } - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (prtd == NULL) return -ENOMEM; @@ -490,7 +490,7 @@ static int q6apm_dai_compr_open(struct snd_soc_component *component, if (!pdata) return -EINVAL; - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (prtd == NULL) return -ENOMEM; @@ -838,6 +838,7 @@ static const struct snd_soc_component_driver q6apm_fe_dai_component = { .ack = q6apm_dai_ack, .compress_ops = &q6apm_dai_compress_ops, .use_dai_pcm_id = true, + .remove_order = SND_SOC_COMP_ORDER_EARLY, }; static int q6apm_dai_probe(struct platform_device *pdev) diff --git a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c index 528756f1332b..5be37eeea329 100644 --- a/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c +++ b/sound/soc/qcom/qdsp6/q6apm-lpass-dais.c @@ -278,6 +278,7 @@ static const struct snd_soc_component_driver q6apm_lpass_dai_component = { .of_xlate_dai_name = q6dsp_audio_ports_of_xlate_dai_name, .be_pcm_base = AUDIOREACH_BE_PCM_BASE, .use_dai_pcm_id = true, + .remove_order = SND_SOC_COMP_ORDER_FIRST, }; static int q6apm_lpass_dai_dev_probe(struct platform_device *pdev) diff --git a/sound/soc/qcom/qdsp6/q6apm.c b/sound/soc/qcom/qdsp6/q6apm.c index 1d5edf285793..970b08c89bb3 100644 --- a/sound/soc/qcom/qdsp6/q6apm.c +++ b/sound/soc/qcom/qdsp6/q6apm.c @@ -57,7 +57,7 @@ static struct audioreach_graph *q6apm_get_audioreach_graph(struct q6apm *apm, ui if (!info) return ERR_PTR(-ENODEV); - graph = kzalloc(sizeof(*graph), GFP_KERNEL); + graph = kzalloc_obj(*graph); if (!graph) return ERR_PTR(-ENOMEM); @@ -220,7 +220,7 @@ int q6apm_map_memory_regions(struct q6apm_graph *graph, unsigned int dir, phys_a return 0; } - buf = kcalloc(periods, sizeof(struct audio_buffer), GFP_KERNEL); + buf = kzalloc_objs(struct audio_buffer, periods); if (!buf) { mutex_unlock(&graph->lock); return -ENOMEM; @@ -615,7 +615,7 @@ struct q6apm_graph *q6apm_graph_open(struct device *dev, q6apm_cb cb, return ERR_CAST(ar_graph); } - graph = kzalloc(sizeof(*graph), GFP_KERNEL); + graph = kzalloc_obj(*graph); if (!graph) { ret = -ENOMEM; goto put_ar_graph; @@ -715,6 +715,7 @@ static const struct snd_soc_component_driver q6apm_audio_component = { .name = APM_AUDIO_DRV_NAME, .probe = q6apm_audio_probe, .remove = q6apm_audio_remove, + .remove_order = SND_SOC_COMP_ORDER_LAST, }; static int apm_probe(gpr_device_t *gdev) diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c index 709b4f3318ff..9e3d176f50c2 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -378,7 +378,7 @@ static int q6asm_dai_open(struct snd_soc_component *component, return -EINVAL; } - prtd = kzalloc(sizeof(struct q6asm_dai_rtd), GFP_KERNEL); + prtd = kzalloc_obj(struct q6asm_dai_rtd); if (prtd == NULL) return -ENOMEM; @@ -621,7 +621,7 @@ static int q6asm_dai_compr_open(struct snd_soc_component *component, return -EINVAL; } - prtd = kzalloc(sizeof(*prtd), GFP_KERNEL); + prtd = kzalloc_obj(*prtd); if (!prtd) return -ENOMEM; diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c index 1bb295407c60..de0bd8fd08ee 100644 --- a/sound/soc/qcom/qdsp6/q6asm.c +++ b/sound/soc/qcom/qdsp6/q6asm.c @@ -506,7 +506,7 @@ int q6asm_map_memory_regions(unsigned int dir, struct audio_client *ac, return 0; } - buf = kcalloc(periods, sizeof(*buf), GFP_ATOMIC); + buf = kzalloc_objs(*buf, periods, GFP_ATOMIC); if (!buf) { spin_unlock_irqrestore(&ac->lock, flags); return -ENOMEM; @@ -850,7 +850,7 @@ struct audio_client *q6asm_audio_client_alloc(struct device *dev, q6asm_cb cb, return ac; } - ac = kzalloc(sizeof(*ac), GFP_KERNEL); + ac = kzalloc_obj(*ac); if (!ac) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c index f4939302b88a..48825756a7ab 100644 --- a/sound/soc/qcom/qdsp6/q6core.c +++ b/sound/soc/qcom/qdsp6/q6core.c @@ -327,7 +327,7 @@ EXPORT_SYMBOL_GPL(q6core_is_adsp_ready); static int q6core_probe(struct apr_device *adev) { - g_core = kzalloc(sizeof(*g_core), GFP_KERNEL); + g_core = kzalloc_obj(*g_core); if (!g_core) return -ENOMEM; diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c index aaa3af9f1993..7386226046fa 100644 --- a/sound/soc/qcom/qdsp6/q6routing.c +++ b/sound/soc/qcom/qdsp6/q6routing.c @@ -1133,7 +1133,7 @@ static int q6pcm_routing_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - routing_data = kzalloc(sizeof(*routing_data), GFP_KERNEL); + routing_data = kzalloc_obj(*routing_data); if (!routing_data) return -ENOMEM; diff --git a/sound/soc/qcom/qdsp6/topology.c b/sound/soc/qcom/qdsp6/topology.c index 2e71eaa90441..e732fac9b8ca 100644 --- a/sound/soc/qcom/qdsp6/topology.c +++ b/sound/soc/qcom/qdsp6/topology.c @@ -42,7 +42,7 @@ static struct audioreach_graph_info *audioreach_tplg_alloc_graph_info(struct q6a } *found = false; - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) return ERR_PTR(-ENOMEM); @@ -92,7 +92,7 @@ static struct audioreach_sub_graph *audioreach_tplg_alloc_sub_graph(struct q6apm } *found = false; - sg = kzalloc(sizeof(*sg), GFP_KERNEL); + sg = kzalloc_obj(*sg); if (!sg) return ERR_PTR(-ENOMEM); @@ -134,7 +134,7 @@ static struct audioreach_container *audioreach_tplg_alloc_container(struct q6apm } *found = false; - cont = kzalloc(sizeof(*cont), GFP_KERNEL); + cont = kzalloc_obj(*cont); if (!cont) return ERR_PTR(-ENOMEM); @@ -176,7 +176,7 @@ static struct audioreach_module *audioreach_tplg_alloc_module(struct q6apm *apm, return mod; } *found = false; - mod = kzalloc(sizeof(*mod), GFP_KERNEL); + mod = kzalloc_obj(*mod); if (!mod) return ERR_PTR(-ENOMEM); @@ -317,8 +317,8 @@ audioreach_get_module_priv_data(const struct snd_soc_tplg_private *private) if (le32_to_cpu(mod_array->type) == SND_SOC_AR_TPLG_MODULE_CFG_TYPE) { struct audioreach_module_priv_data *pdata; - pdata = kzalloc(struct_size(pdata, data, le32_to_cpu(mod_array->size)), - GFP_KERNEL); + pdata = kzalloc_flex(*pdata, data, + le32_to_cpu(mod_array->size)); if (!pdata) return ERR_PTR(-ENOMEM); @@ -829,7 +829,7 @@ static int audioreach_widget_load_mixer(struct snd_soc_component *component, w_array = &tplg_w->priv.array[0]; - scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); + scontrol = kzalloc_obj(*scontrol); if (!scontrol) return -ENOMEM; @@ -1246,7 +1246,7 @@ static int audioreach_control_load(struct snd_soc_component *scomp, int index, struct snd_soc_dobj *dobj; int ret = 0; - scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); + scontrol = kzalloc_obj(*scontrol); if (!scontrol) return -ENOMEM; diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 05a8b04e50e0..f193d0ba63d0 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -104,6 +104,14 @@ static int sm8250_snd_startup(struct snd_pcm_substream *substream) snd_soc_dai_set_fmt(cpu_dai, fmt); snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); break; + case QUINARY_MI2S_RX: + codec_dai_fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_I2S; + snd_soc_dai_set_sysclk(cpu_dai, + Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT, + MI2S_BCLK_RATE, SNDRV_PCM_STREAM_PLAYBACK); + snd_soc_dai_set_fmt(cpu_dai, fmt); + snd_soc_dai_set_fmt(codec_dai, codec_dai_fmt); + break; default: break; } diff --git a/sound/soc/renesas/rz-ssi.c b/sound/soc/renesas/rz-ssi.c index 39aa865bdca3..74e078c04150 100644 --- a/sound/soc/renesas/rz-ssi.c +++ b/sound/soc/renesas/rz-ssi.c @@ -180,7 +180,7 @@ static inline bool rz_ssi_stream_is_play(struct snd_pcm_substream *substream) static inline struct rz_ssi_stream * rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_pcm_substream *substream) { - return (ssi->playback.substream == substream) ? &ssi->playback : &ssi->capture; + return (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? &ssi->playback : &ssi->capture; } static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi) diff --git a/sound/soc/renesas/siu_dai.c b/sound/soc/renesas/siu_dai.c index 7e771a164a80..039b1264d90d 100644 --- a/sound/soc/renesas/siu_dai.c +++ b/sound/soc/renesas/siu_dai.c @@ -453,7 +453,7 @@ int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card) struct snd_kcontrol *kctrl; int ret; - *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL); + *port_info = kzalloc_obj(**port_info); if (!*port_info) return -ENOMEM; diff --git a/sound/soc/rockchip/rockchip_i2s_tdm.c b/sound/soc/rockchip/rockchip_i2s_tdm.c index 770b9bfbb384..fc52149ed6ae 100644 --- a/sound/soc/rockchip/rockchip_i2s_tdm.c +++ b/sound/soc/rockchip/rockchip_i2s_tdm.c @@ -22,6 +22,7 @@ #define DRV_NAME "rockchip-i2s-tdm" +#define DEFAULT_MCLK_FS 256 #define CH_GRP_MAX 4 /* The max channel 8 / 2 */ #define MULTIPLEX_CH_MAX 10 @@ -665,6 +666,15 @@ static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream, mclk_rate = i2s_tdm->mclk_rx_freq; } + /* + * When the dai/component driver doesn't need to set mclk-fs for a specific + * clock, it can skip the call to set_sysclk() for that clock. + * In that case, simply use the clock rate from the params and multiply it by + * the default mclk-fs value. + */ + if (!mclk_rate) + mclk_rate = DEFAULT_MCLK_FS * params_rate(params); + err = clk_set_rate(mclk, mclk_rate); if (err) return err; diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 402ccadad46c..beb7e09e9fac 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c @@ -290,7 +290,7 @@ static int idma_open(struct snd_soc_component *component, snd_soc_set_runtime_hwparams(substream, &idma_hardware); - prtd = kzalloc(sizeof(struct idma_ctrl), GFP_KERNEL); + prtd = kzalloc_obj(struct idma_ctrl); if (prtd == NULL) return -ENOMEM; diff --git a/sound/soc/sdca/sdca_asoc.c b/sound/soc/sdca/sdca_asoc.c index bb6e74e80a3e..a0191e5a5a7d 100644 --- a/sound/soc/sdca/sdca_asoc.c +++ b/sound/soc/sdca/sdca_asoc.c @@ -1349,7 +1349,7 @@ int sdca_asoc_set_constraints(struct device *dev, struct regmap *regmap, dev_dbg(dev, "%s: set channel constraint mask: %#x\n", entity->label, channel_mask); - constraint = kzalloc(sizeof(*constraint), GFP_KERNEL); + constraint = kzalloc_obj(*constraint); if (!constraint) return -ENOMEM; diff --git a/sound/soc/sdca/sdca_function_device.c b/sound/soc/sdca/sdca_function_device.c index c6cc880a150e..feacfbc6a518 100644 --- a/sound/soc/sdca/sdca_function_device.c +++ b/sound/soc/sdca/sdca_function_device.c @@ -39,7 +39,7 @@ static struct sdca_dev *sdca_dev_register(struct device *parent, int ret; int rc; - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + sdev = kzalloc_obj(*sdev); if (!sdev) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c index 95b67bb904c3..e0ed593697ba 100644 --- a/sound/soc/sdca/sdca_functions.c +++ b/sound/soc/sdca/sdca_functions.c @@ -1156,9 +1156,12 @@ static int find_sdca_entity_iot(struct device *dev, if (!terminal->is_dataport) { const char *type_name = sdca_find_terminal_name(terminal->type); - if (type_name) + if (type_name) { entity->label = devm_kasprintf(dev, GFP_KERNEL, "%s %s", entity->label, type_name); + if (!entity->label) + return -ENOMEM; + } } ret = fwnode_property_read_u32(entity_node, diff --git a/sound/soc/sdca/sdca_interrupts.c b/sound/soc/sdca/sdca_interrupts.c index d9e22cf40f77..95b1ab4ba1b0 100644 --- a/sound/soc/sdca/sdca_interrupts.c +++ b/sound/soc/sdca/sdca_interrupts.c @@ -265,9 +265,9 @@ static int sdca_irq_request_locked(struct device *dev, } /** - * sdca_request_irq - request an individual SDCA interrupt + * sdca_irq_request - request an individual SDCA interrupt * @dev: Pointer to the struct device against which things should be allocated. - * @interrupt_info: Pointer to the interrupt information structure. + * @info: Pointer to the interrupt information structure. * @sdca_irq: SDCA interrupt position. * @name: Name to be given to the IRQ. * @handler: A callback thread function to be called for the IRQ. diff --git a/sound/soc/sdca/sdca_jack.c b/sound/soc/sdca/sdca_jack.c index 605514f02045..49d317d3b8c8 100644 --- a/sound/soc/sdca/sdca_jack.c +++ b/sound/soc/sdca/sdca_jack.c @@ -99,7 +99,7 @@ int sdca_jack_process(struct sdca_interrupt *interrupt) if (kctl) { struct soc_enum *soc_enum = (struct soc_enum *)kctl->private_value; - ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL); + ucontrol = kzalloc_obj(*ucontrol); if (!ucontrol) return -ENOMEM; diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 37486d6a438e..5f81e3606655 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -181,7 +181,7 @@ struct snd_ac97 *snd_soc_alloc_ac97_component(struct snd_soc_component *componen { struct snd_ac97 *ac97; - ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); + ac97 = kzalloc_obj(struct snd_ac97); if (ac97 == NULL) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5811d053ce7a..573693e21780 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -462,8 +462,7 @@ static void soc_free_pcm_runtime(struct snd_soc_pcm_runtime *rtd) list_del(&rtd->list); - if (delayed_work_pending(&rtd->delayed_work)) - flush_delayed_work(&rtd->delayed_work); + flush_delayed_work(&rtd->delayed_work); snd_soc_pcm_component_free(rtd); /* @@ -507,7 +506,7 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime( /* * for rtd->dev */ - dev = kzalloc(sizeof(struct device), GFP_KERNEL); + dev = kzalloc_obj(struct device); if (!dev) return NULL; @@ -1864,12 +1863,15 @@ static void cleanup_dmi_name(char *name) /* * Check if a DMI field is valid, i.e. not containing any string - * in the black list. + * in the black list and not the empty string. */ static int is_dmi_valid(const char *field) { int i = 0; + if (!field[0]) + return 0; + while (dmi_blacklist[i]) { if (strstr(field, dmi_blacklist[i])) return 0; @@ -2122,6 +2124,9 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card) for_each_card_rtds(card, rtd) if (rtd->initialized) snd_soc_link_exit(rtd); + /* flush delayed work before removing DAIs and DAPM widgets */ + snd_soc_flush_all_delayed_work(card); + /* remove and free each DAI */ soc_remove_link_dais(card); soc_remove_link_components(card); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index c23ccf4a602d..2768ba5bfc9f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -638,7 +638,7 @@ static int dapm_add_path( if (ret) return ret; - path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL); + path = kzalloc_obj(struct snd_soc_dapm_path); if (!path) return -ENOMEM; @@ -713,7 +713,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget, const char *name; int ret; - data = kzalloc(sizeof(*data), GFP_KERNEL); + data = kzalloc_obj(*data); if (!data) return -ENOMEM; @@ -1435,7 +1435,7 @@ static int dapm_widget_list_create(struct snd_soc_dapm_widget_list **list, list_for_each(it, widgets) size++; - *list = kzalloc(struct_size(*list, widgets, size), GFP_KERNEL); + *list = kzalloc_flex(**list, widgets, size); if (*list == NULL) return -ENOMEM; @@ -3332,9 +3332,8 @@ int snd_soc_dapm_new_widgets(struct snd_soc_card *card) continue; if (w->num_kcontrols) { - w->kcontrols = kcalloc(w->num_kcontrols, - sizeof(struct snd_kcontrol *), - GFP_KERNEL); + w->kcontrols = kzalloc_objs(struct snd_kcontrol *, + w->num_kcontrols); if (!w->kcontrols) { snd_soc_dapm_mutex_unlock(card); return -ENOMEM; @@ -3972,12 +3971,11 @@ static int dapm_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w, * stuff that increases stack usage. * So, we use kzalloc()/kfree() for params in this function. */ - struct snd_pcm_hw_params *params __free(kfree) = kzalloc(sizeof(*params), - GFP_KERNEL); + struct snd_pcm_hw_params *params __free(kfree) = kzalloc_obj(*params); if (!params) return -ENOMEM; - runtime = kzalloc(sizeof(*runtime), GFP_KERNEL); + runtime = kzalloc_obj(*runtime); if (!runtime) return -ENOMEM; diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c index a63e942fdc0b..dbec46703b35 100644 --- a/sound/soc/soc-generic-dmaengine-pcm.c +++ b/sound/soc/soc-generic-dmaengine-pcm.c @@ -437,7 +437,7 @@ int snd_dmaengine_pcm_register(struct device *dev, struct dmaengine_pcm *pcm; int ret; - pcm = kzalloc(sizeof(*pcm), GFP_KERNEL); + pcm = kzalloc_obj(*pcm); if (!pcm) return -ENOMEM; diff --git a/sound/soc/soc-ops-test.c b/sound/soc/soc-ops-test.c index 1bafa5626d48..dc83107930e4 100644 --- a/sound/soc/soc-ops-test.c +++ b/sound/soc/soc-ops-test.c @@ -486,7 +486,7 @@ static void soc_ops_test_access(struct kunit *test) /* it is too large struct. use kzalloc() */ struct snd_ctl_elem_value *result; - result = kzalloc(sizeof(*result), GFP_KERNEL); + result = kzalloc_obj(*result); if (!result) return; diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index ba42939d5f01..f966d4e13c7f 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -454,7 +454,7 @@ static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) if (!mc->platform_max) return 0; - uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); + uctl = kzalloc_obj(*uctl); if (!uctl) return -ENOMEM; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 6b134962c71c..afa9fad4457f 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1323,7 +1323,7 @@ static int dpcm_be_connect(struct snd_soc_pcm_runtime *fe, be_substream->pcm->nonatomic = 1; } - dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL); + dpcm = kzalloc_obj(struct snd_soc_dpcm); if (!dpcm) return -ENOMEM; diff --git a/sound/soc/soc-usb.c b/sound/soc/soc-usb.c index 26baa66d29a8..6386404a8db8 100644 --- a/sound/soc/soc-usb.c +++ b/sound/soc/soc-usb.c @@ -189,7 +189,7 @@ struct snd_soc_usb *snd_soc_usb_allocate_port(struct snd_soc_component *componen { struct snd_soc_usb *usb; - usb = kzalloc(sizeof(*usb), GFP_KERNEL); + usb = kzalloc_obj(*usb); if (!usb) return ERR_PTR(-ENOMEM); diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index 86d563c864e5..96570121aae0 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -101,7 +101,7 @@ static int sof_compr_open(struct snd_soc_component *component, struct snd_sof_pcm *spcm; int dir; - sstream = kzalloc(sizeof(*sstream), GFP_KERNEL); + sstream = kzalloc_obj(*sstream); if (!sstream) return -ENOMEM; diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 0c68ae41a8a8..b0072601181e 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -54,7 +54,7 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc_obj(*ipc4_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 69376fb5b20d..660c1475e5a4 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -401,7 +401,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc_obj(*ipc4_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c index 6f15213937a3..ce603a2343de 100644 --- a/sound/soc/sof/intel/hda-mlink.c +++ b/sound/soc/sof/intel/hda-mlink.c @@ -392,7 +392,7 @@ static int hda_ml_alloc_h2link(struct hdac_bus *bus, int index) struct hdac_ext_link *hlink; int ret; - h2link = kzalloc(sizeof(*h2link), GFP_KERNEL); + h2link = kzalloc_obj(*h2link); if (!h2link) return -ENOMEM; diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c index dbc5ad62258b..c1018893750c 100644 --- a/sound/soc/sof/intel/icl.c +++ b/sound/soc/sof/intel/icl.c @@ -122,7 +122,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc_obj(*ipc4_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c index 4ac81537ca05..9503d00e6002 100644 --- a/sound/soc/sof/intel/mtl.c +++ b/sound/soc/sof/intel/mtl.c @@ -734,7 +734,7 @@ int sof_mtl_set_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *dsp_ops) dsp_ops->core_get = mtl_dsp_core_get; dsp_ops->core_put = mtl_dsp_core_put; - sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL); + sdev->private = kzalloc_obj(struct sof_ipc4_fw_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c index 90a3c2e2334c..90519ebd3168 100644 --- a/sound/soc/sof/intel/skl.c +++ b/sound/soc/sof/intel/skl.c @@ -62,7 +62,7 @@ int sof_skl_ops_init(struct snd_sof_dev *sdev) /* probe/remove/shutdown */ sof_skl_ops.shutdown = hda_dsp_shutdown; - sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc_obj(*ipc4_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/intel/telemetry.c b/sound/soc/sof/intel/telemetry.c index dcaaf03599db..05c2eb879481 100644 --- a/sound/soc/sof/intel/telemetry.c +++ b/sound/soc/sof/intel/telemetry.c @@ -29,7 +29,7 @@ void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags) if (!slot_offset) return; - telemetry_data = kmalloc(sizeof(*telemetry_data), GFP_KERNEL); + telemetry_data = kmalloc_obj(*telemetry_data); if (!telemetry_data) return; sof_mailbox_read(sdev, slot_offset, telemetry_data, sizeof(*telemetry_data)); @@ -39,7 +39,7 @@ void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags) goto free_telemetry_data; } - block = kmalloc(sizeof(*block), GFP_KERNEL); + block = kmalloc_obj(*block); if (!block) goto free_telemetry_data; @@ -71,7 +71,7 @@ void sof_ipc4_intel_dump_telemetry_state(struct snd_sof_dev *sdev, u32 flags) break; } - xoops = kzalloc(struct_size(xoops, ar, XTENSA_CORE_AR_REGS_COUNT), GFP_KERNEL); + xoops = kzalloc_flex(*xoops, ar, XTENSA_CORE_AR_REGS_COUNT); if (!xoops) goto free_block; diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c index e68bbe685ba3..7936361e2e39 100644 --- a/sound/soc/sof/intel/tgl.c +++ b/sound/soc/sof/intel/tgl.c @@ -90,7 +90,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev) if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) { struct sof_ipc4_fw_data *ipc4_data; - sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL); + sdev->private = kzalloc_obj(*ipc4_data); if (!sdev->private) return -ENOMEM; diff --git a/sound/soc/sof/ipc3-dtrace.c b/sound/soc/sof/ipc3-dtrace.c index 50700f5cb0ef..22053357731a 100644 --- a/sound/soc/sof/ipc3-dtrace.c +++ b/sound/soc/sof/ipc3-dtrace.c @@ -126,7 +126,7 @@ static int trace_filter_parse(struct snd_sof_dev *sdev, char *string, capacity += TRACE_FILTER_ELEMENTS_PER_ENTRY; entry = strchr(entry + 1, entry_delimiter[0]); } - *out = kmalloc_array(capacity, sizeof(**out), GFP_KERNEL); + *out = kmalloc_objs(**out, capacity); if (!*out) return -ENOMEM; diff --git a/sound/soc/sof/ipc3-topology.c b/sound/soc/sof/ipc3-topology.c index 743f42fb26c0..8006777f2f64 100644 --- a/sound/soc/sof/ipc3-topology.c +++ b/sound/soc/sof/ipc3-topology.c @@ -524,7 +524,7 @@ static int sof_ipc3_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) struct snd_sof_widget *comp_swidget; int ret; - pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); + pipeline = kzalloc_obj(*pipeline); if (!pipeline) return -ENOMEM; @@ -589,7 +589,7 @@ static int sof_ipc3_widget_setup_comp_buffer(struct snd_sof_widget *swidget) struct sof_ipc_buffer *buffer; int ret; - buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + buffer = kzalloc_obj(*buffer); if (!buffer) return -ENOMEM; @@ -893,7 +893,7 @@ static int sof_process_load(struct snd_soc_component *scomp, /* allocate struct for widget control data sizes and types */ if (widget->num_kcontrols) { - wdata = kcalloc(widget->num_kcontrols, sizeof(*wdata), GFP_KERNEL); + wdata = kzalloc_objs(*wdata, widget->num_kcontrols); if (!wdata) return -ENOMEM; @@ -1567,7 +1567,7 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) struct snd_sof_dai_link *slink; int ret; - private = kzalloc(sizeof(*private), GFP_KERNEL); + private = kzalloc_obj(*private); if (!private) return -ENOMEM; @@ -1622,7 +1622,7 @@ static int sof_ipc3_widget_setup_comp_dai(struct snd_sof_widget *swidget) continue; /* Reserve memory for all hw configs, eventually freed by widget */ - config = kcalloc(slink->num_hw_configs, sizeof(*config), GFP_KERNEL); + config = kzalloc_objs(*config, slink->num_hw_configs); if (!config) { ret = -ENOMEM; goto free_comp; diff --git a/sound/soc/sof/ipc4-pcm.c b/sound/soc/sof/ipc4-pcm.c index c3337c3f08c1..fc3ead77e5ea 100644 --- a/sound/soc/sof/ipc4-pcm.c +++ b/sound/soc/sof/ipc4-pcm.c @@ -476,8 +476,8 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component, } /* allocate memory for the pipeline data */ - trigger_list = kzalloc(struct_size(trigger_list, pipeline_instance_ids, - pipeline_list->count), GFP_KERNEL); + trigger_list = kzalloc_flex(*trigger_list, pipeline_instance_ids, + pipeline_list->count); if (!trigger_list) return -ENOMEM; @@ -931,15 +931,14 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm pipeline_list = &spcm->stream[stream].pipeline_list; /* allocate memory for max number of pipeline IDs */ - pipeline_list->pipelines = kcalloc(ipc4_data->max_num_pipelines, - sizeof(*pipeline_list->pipelines), - GFP_KERNEL); + pipeline_list->pipelines = kzalloc_objs(*pipeline_list->pipelines, + ipc4_data->max_num_pipelines); if (!pipeline_list->pipelines) { sof_ipc4_pcm_free(sdev, spcm); return -ENOMEM; } - stream_priv = kzalloc(sizeof(*stream_priv), GFP_KERNEL); + stream_priv = kzalloc_obj(*stream_priv); if (!stream_priv) { sof_ipc4_pcm_free(sdev, spcm); return -ENOMEM; @@ -951,7 +950,7 @@ static int sof_ipc4_pcm_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm if (!support_info || stream == SNDRV_PCM_STREAM_CAPTURE) continue; - time_info = kzalloc(sizeof(*time_info), GFP_KERNEL); + time_info = kzalloc_obj(*time_info); if (!time_info) { sof_ipc4_pcm_free(sdev, spcm); return -ENOMEM; diff --git a/sound/soc/sof/ipc4-topology.c b/sound/soc/sof/ipc4-topology.c index 622bffb50a1c..db077e9d5644 100644 --- a/sound/soc/sof/ipc4-topology.c +++ b/sound/soc/sof/ipc4-topology.c @@ -436,8 +436,8 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, module_base_cfg->is_pages); if (available_fmt->num_input_formats) { - in_format = kcalloc(available_fmt->num_input_formats, - sizeof(*in_format), GFP_KERNEL); + in_format = kzalloc_objs(*in_format, + available_fmt->num_input_formats); if (!in_format) return -ENOMEM; available_fmt->input_pin_fmts = in_format; @@ -457,8 +457,8 @@ static int sof_ipc4_get_audio_fmt(struct snd_soc_component *scomp, } if (available_fmt->num_output_formats) { - out_format = kcalloc(available_fmt->num_output_formats, sizeof(*out_format), - GFP_KERNEL); + out_format = kzalloc_objs(*out_format, + available_fmt->num_output_formats); if (!out_format) { ret = -ENOMEM; goto err_in; @@ -627,7 +627,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) int node_type = 0; int ret, dir; - ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); + ipc4_copier = kzalloc_obj(*ipc4_copier); if (!ipc4_copier) return -ENOMEM; @@ -688,7 +688,7 @@ static int sof_ipc4_widget_setup_pcm(struct snd_sof_widget *swidget) } skip_gtw_cfg: - ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); + ipc4_copier->gtw_attr = kzalloc_obj(*ipc4_copier->gtw_attr); if (!ipc4_copier->gtw_attr) { ret = -ENOMEM; goto free_available_fmt; @@ -757,7 +757,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) int node_type = 0; int ret; - ipc4_copier = kzalloc(sizeof(*ipc4_copier), GFP_KERNEL); + ipc4_copier = kzalloc_obj(*ipc4_copier); if (!ipc4_copier) return -ENOMEM; @@ -824,7 +824,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) break; } - blob = kzalloc(sizeof(*blob), GFP_KERNEL); + blob = kzalloc_obj(*blob); if (!blob) { ret = -ENOMEM; goto free_available_fmt; @@ -863,7 +863,7 @@ static int sof_ipc4_widget_setup_comp_dai(struct snd_sof_widget *swidget) SOF_IPC4_NODE_INDEX_INTEL_DMIC(ipc4_copier->dai_index); break; default: - ipc4_copier->gtw_attr = kzalloc(sizeof(*ipc4_copier->gtw_attr), GFP_KERNEL); + ipc4_copier->gtw_attr = kzalloc_obj(*ipc4_copier->gtw_attr); if (!ipc4_copier->gtw_attr) { ret = -ENOMEM; goto free_available_fmt; @@ -930,7 +930,7 @@ static int sof_ipc4_widget_setup_comp_pipeline(struct snd_sof_widget *swidget) struct snd_sof_pipeline *spipe = swidget->spipe; int ret; - pipeline = kzalloc(sizeof(*pipeline), GFP_KERNEL); + pipeline = kzalloc_obj(*pipeline); if (!pipeline) return -ENOMEM; @@ -989,7 +989,7 @@ static int sof_ipc4_widget_setup_comp_pga(struct snd_sof_widget *swidget) struct sof_ipc4_gain *gain; int ret; - gain = kzalloc(sizeof(*gain), GFP_KERNEL); + gain = kzalloc_obj(*gain); if (!gain) return -ENOMEM; @@ -1048,7 +1048,7 @@ static int sof_ipc4_widget_setup_comp_mixer(struct snd_sof_widget *swidget) dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); - mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); + mixer = kzalloc_obj(*mixer); if (!mixer) return -ENOMEM; @@ -1080,7 +1080,7 @@ static int sof_ipc4_widget_setup_comp_src(struct snd_sof_widget *swidget) dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); - src = kzalloc(sizeof(*src), GFP_KERNEL); + src = kzalloc_obj(*src); if (!src) return -ENOMEM; @@ -1123,7 +1123,7 @@ static int sof_ipc4_widget_setup_comp_asrc(struct snd_sof_widget *swidget) dev_dbg(scomp->dev, "Updating IPC structure for %s\n", swidget->widget->name); - asrc = kzalloc(sizeof(*asrc), GFP_KERNEL); + asrc = kzalloc_obj(*asrc); if (!asrc) return -ENOMEM; @@ -1206,7 +1206,7 @@ static int sof_ipc4_widget_setup_comp_process(struct snd_sof_widget *swidget) void *cfg; int ret; - process = kzalloc(sizeof(*process), GFP_KERNEL); + process = kzalloc_obj(*process); if (!process) return -ENOMEM; diff --git a/sound/soc/sof/sof-client-probes-ipc4.c b/sound/soc/sof/sof-client-probes-ipc4.c index d3fa37106b64..88397c7dc4c3 100644 --- a/sound/soc/sof/sof-client-probes-ipc4.c +++ b/sound/soc/sof/sof-client-probes-ipc4.c @@ -327,7 +327,7 @@ static int ipc4_probes_points_add(struct sof_client_dev *cdev, * performance issue I wrote the conversion explicitly open for * future development. */ - points = kcalloc(num_desc, sizeof(*points), GFP_KERNEL); + points = kzalloc_objs(*points, num_desc); if (!points) return -ENOMEM; diff --git a/sound/soc/sof/sof-client.c b/sound/soc/sof/sof-client.c index 38f1d7cec470..c7bbf09e547f 100644 --- a/sound/soc/sof/sof-client.c +++ b/sound/soc/sof/sof-client.c @@ -554,7 +554,7 @@ int sof_client_register_ipc_rx_handler(struct sof_client_dev *cdev, return -EINVAL; } - event = kmalloc(sizeof(*event), GFP_KERNEL); + event = kmalloc_obj(*event); if (!event) return -ENOMEM; @@ -608,7 +608,7 @@ int sof_client_register_fw_state_handler(struct sof_client_dev *cdev, if (!callback) return -EINVAL; - event = kmalloc(sizeof(*event), GFP_KERNEL); + event = kmalloc_obj(*event); if (!event) return -ENOMEM; diff --git a/sound/soc/sof/stream-ipc.c b/sound/soc/sof/stream-ipc.c index 8262443ac89a..78758cf58f01 100644 --- a/sound/soc/sof/stream-ipc.c +++ b/sound/soc/sof/stream-ipc.c @@ -99,7 +99,7 @@ EXPORT_SYMBOL(sof_set_stream_data_offset); int sof_stream_pcm_open(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream) { - struct sof_stream *stream = kmalloc(sizeof(*stream), GFP_KERNEL); + struct sof_stream *stream = kmalloc_obj(*stream); if (!stream) return -ENOMEM; diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 9bf8ab610a7e..18e2401152c8 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -973,7 +973,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index, dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n", hdr->type, hdr->name); - scontrol = kzalloc(sizeof(*scontrol), GFP_KERNEL); + scontrol = kzalloc_obj(*scontrol); if (!scontrol) return -ENOMEM; @@ -1233,7 +1233,7 @@ static int sof_widget_parse_tokens(struct snd_soc_component *scomp, struct snd_s num_tuples += token_list[object_token_list[i]].count; /* allocate memory for tuples array */ - swidget->tuples = kcalloc(num_tuples, sizeof(*swidget->tuples), GFP_KERNEL); + swidget->tuples = kzalloc_objs(*swidget->tuples, num_tuples); if (!swidget->tuples) return -ENOMEM; @@ -1420,7 +1420,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, int token_list_size = 0; int ret = 0; - swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); + swidget = kzalloc_obj(*swidget); if (!swidget) return -ENOMEM; @@ -1496,7 +1496,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, switch (w->id) { case snd_soc_dapm_dai_in: case snd_soc_dapm_dai_out: - dai = kzalloc(sizeof(*dai), GFP_KERNEL); + dai = kzalloc_obj(*dai); if (!dai) { ret = -ENOMEM; goto widget_free; @@ -1586,7 +1586,7 @@ static int sof_widget_ready(struct snd_soc_component *scomp, int index, if (w->id == snd_soc_dapm_scheduler) { struct snd_sof_pipeline *spipe; - spipe = kzalloc(sizeof(*spipe), GFP_KERNEL); + spipe = kzalloc_obj(*spipe); if (!spipe) { ret = -ENOMEM; goto free; @@ -1739,7 +1739,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, if (!pcm) return 0; - spcm = kzalloc(sizeof(*spcm), GFP_KERNEL); + spcm = kzalloc_obj(*spcm); if (!spcm) return -ENOMEM; @@ -1906,7 +1906,7 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ return -EINVAL; } - slink = kzalloc(sizeof(*slink), GFP_KERNEL); + slink = kzalloc_obj(*slink); if (!slink) return -ENOMEM; @@ -1999,7 +1999,7 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, struct snd_ } /* allocate memory for tuples array */ - slink->tuples = kcalloc(num_tuples, sizeof(*slink->tuples), GFP_KERNEL); + slink->tuples = kzalloc_objs(*slink->tuples, num_tuples); if (!slink->tuples) { kfree(slink->hw_configs); kfree(slink); @@ -2094,7 +2094,7 @@ static int sof_route_load(struct snd_soc_component *scomp, int index, int ret = 0; /* allocate memory for sroute and connect */ - sroute = kzalloc(sizeof(*sroute), GFP_KERNEL); + sroute = kzalloc_obj(*sroute); if (!sroute) return -ENOMEM; @@ -2398,11 +2398,11 @@ static int sof_dspless_widget_ready(struct snd_soc_component *scomp, int index, struct snd_sof_widget *swidget; struct snd_sof_dai *sdai; - swidget = kzalloc(sizeof(*swidget), GFP_KERNEL); + swidget = kzalloc_obj(*swidget); if (!swidget) return -ENOMEM; - sdai = kzalloc(sizeof(*sdai), GFP_KERNEL); + sdai = kzalloc_obj(*sdai); if (!sdai) { kfree(swidget); return -ENOMEM; diff --git a/sound/soc/sprd/sprd-pcm-compress.c b/sound/soc/sprd/sprd-pcm-compress.c index 4b6ebfa5b033..a7d437b49fbf 100644 --- a/sound/soc/sprd/sprd-pcm-compress.c +++ b/sound/soc/sprd/sprd-pcm-compress.c @@ -160,7 +160,7 @@ static int sprd_platform_compr_dma_config(struct snd_soc_component *component, return -ENODEV; } - sgt = sg = kcalloc(sg_num, sizeof(*sg), GFP_KERNEL); + sgt = sg = kzalloc_objs(*sg, sg_num); if (!sg) { ret = -ENOMEM; goto sg_err; diff --git a/sound/soc/tegra/tegra_audio_graph_card.c b/sound/soc/tegra/tegra_audio_graph_card.c index 94b5ab77649b..ea10e6e8a9fe 100644 --- a/sound/soc/tegra/tegra_audio_graph_card.c +++ b/sound/soc/tegra/tegra_audio_graph_card.c @@ -231,6 +231,15 @@ static const struct tegra_audio_cdata tegra186_data = { .plla_out0_rates[x11_RATE] = 45158400, }; +static const struct tegra_audio_cdata tegra238_data = { + /* PLLA */ + .plla_rates[x8_RATE] = 1277952000, + .plla_rates[x11_RATE] = 1264435200, + /* PLLA_OUT0 */ + .plla_out0_rates[x8_RATE] = 49152000, + .plla_out0_rates[x11_RATE] = 45158400, +}; + static const struct tegra_audio_cdata tegra264_data = { /* PLLA1 */ .plla_rates[x8_RATE] = 983040000, @@ -245,6 +254,8 @@ static const struct of_device_id graph_of_tegra_match[] = { .data = &tegra210_data }, { .compatible = "nvidia,tegra186-audio-graph-card", .data = &tegra186_data }, + { .compatible = "nvidia,tegra238-audio-graph-card", + .data = &tegra238_data }, { .compatible = "nvidia,tegra264-audio-graph-card", .data = &tegra264_data }, {}, diff --git a/sound/soc/xilinx/xlnx_formatter_pcm.c b/sound/soc/xilinx/xlnx_formatter_pcm.c index 17ef05309469..04a4eae1bc92 100644 --- a/sound/soc/xilinx/xlnx_formatter_pcm.c +++ b/sound/soc/xilinx/xlnx_formatter_pcm.c @@ -341,7 +341,7 @@ static int xlnx_formatter_pcm_open(struct snd_soc_component *component, !adata->s2mm_presence) return -ENODEV; - stream_data = kzalloc(sizeof(*stream_data), GFP_KERNEL); + stream_data = kzalloc_obj(*stream_data); if (!stream_data) return -ENOMEM; diff --git a/sound/sound_core.c b/sound/sound_core.c index d81fed1c1226..10db8c699630 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c @@ -238,7 +238,7 @@ static DEFINE_SPINLOCK(sound_loader_lock); static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode, struct device *dev) { - struct sound_unit *s = kmalloc(sizeof(*s), GFP_KERNEL); + struct sound_unit *s = kmalloc_obj(*s); int r; if (!s) diff --git a/sound/synth/emux/emux.c b/sound/synth/emux/emux.c index 01444fc960d0..450147b1abed 100644 --- a/sound/synth/emux/emux.c +++ b/sound/synth/emux/emux.c @@ -26,7 +26,7 @@ int snd_emux_new(struct snd_emux **remu) struct snd_emux *emu; *remu = NULL; - emu = kzalloc(sizeof(*emu), GFP_KERNEL); + emu = kzalloc_obj(*emu); if (emu == NULL) return -ENOMEM; @@ -86,8 +86,7 @@ int snd_emux_register(struct snd_emux *emu, struct snd_card *card, int index, ch emu->card = card; emu->name = kstrdup_const(name, GFP_KERNEL); - emu->voices = kcalloc(emu->max_voices, sizeof(struct snd_emux_voice), - GFP_KERNEL); + emu->voices = kzalloc_objs(struct snd_emux_voice, emu->max_voices); if (emu->name == NULL || emu->voices == NULL) return -ENOMEM; diff --git a/sound/synth/emux/emux_effect.c b/sound/synth/emux/emux_effect.c index bfe383fa90ba..258997240a0a 100644 --- a/sound/synth/emux/emux_effect.c +++ b/sound/synth/emux/emux_effect.c @@ -272,8 +272,8 @@ void snd_emux_create_effect(struct snd_emux_port *p) { int i; - p->effect = kcalloc(p->chset.max_channels, - sizeof(struct snd_emux_effect_table), GFP_KERNEL); + p->effect = kzalloc_objs(struct snd_emux_effect_table, + p->chset.max_channels); if (p->effect) { for (i = 0; i < p->chset.max_channels; i++) p->chset.channels[i].private = p->effect + i; diff --git a/sound/synth/emux/emux_seq.c b/sound/synth/emux/emux_seq.c index 9d63ac006aa5..2ed01e9d79bb 100644 --- a/sound/synth/emux/emux_seq.c +++ b/sound/synth/emux/emux_seq.c @@ -132,12 +132,11 @@ snd_emux_create_port(struct snd_emux *emu, char *name, int i, type, cap; /* Allocate structures for this channel */ - p = kzalloc(sizeof(*p), GFP_KERNEL); + p = kzalloc_obj(*p); if (!p) return NULL; - p->chset.channels = kcalloc(max_channels, sizeof(*p->chset.channels), - GFP_KERNEL); + p->chset.channels = kzalloc_objs(*p->chset.channels, max_channels); if (!p->chset.channels) { kfree(p); return NULL; @@ -351,7 +350,7 @@ int snd_emux_init_virmidi(struct snd_emux *emu, struct snd_card *card) if (emu->midi_ports <= 0) return 0; - emu->vmidi = kcalloc(emu->midi_ports, sizeof(*emu->vmidi), GFP_KERNEL); + emu->vmidi = kzalloc_objs(*emu->vmidi, emu->midi_ports); if (!emu->vmidi) return -ENOMEM; diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c index 59f3b1b6df4a..c172b53b17a4 100644 --- a/sound/synth/emux/soundfont.c +++ b/sound/synth/emux/soundfont.c @@ -230,7 +230,7 @@ newsf(struct snd_sf_list *sflist, int type, char *name) } /* not found -- create a new one */ - sf = kzalloc(sizeof(*sf), GFP_KERNEL); + sf = kzalloc_obj(*sf); if (sf == NULL) return NULL; sf->id = sflist->fonts_size; @@ -309,7 +309,7 @@ sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf) { struct snd_sf_zone *zp; - zp = kzalloc(sizeof(*zp), GFP_KERNEL); + zp = kzalloc_obj(*zp); if (!zp) return NULL; zp->next = sf->zones; @@ -342,7 +342,7 @@ sf_sample_new(struct snd_sf_list *sflist, struct snd_soundfont *sf) { struct snd_sf_sample *sp; - sp = kzalloc(sizeof(*sp), GFP_KERNEL); + sp = kzalloc_obj(*sp); if (!sp) return NULL; @@ -1391,7 +1391,7 @@ snd_sf_new(struct snd_sf_callback *callback, struct snd_util_memhdr *hdr) { struct snd_sf_list *sflist; - sflist = kzalloc(sizeof(*sflist), GFP_KERNEL); + sflist = kzalloc_obj(*sflist); if (!sflist) return NULL; diff --git a/sound/synth/util_mem.c b/sound/synth/util_mem.c index 2fd577c2a8eb..21893e5612fb 100644 --- a/sound/synth/util_mem.c +++ b/sound/synth/util_mem.c @@ -26,7 +26,7 @@ snd_util_memhdr_new(int memsize) { struct snd_util_memhdr *hdr; - hdr = kzalloc(sizeof(*hdr), GFP_KERNEL); + hdr = kzalloc_obj(*hdr); if (hdr == NULL) return NULL; hdr->size = memsize; diff --git a/sound/usb/6fire/comm.c b/sound/usb/6fire/comm.c index 49629d4bb327..9a0b85653c61 100644 --- a/sound/usb/6fire/comm.c +++ b/sound/usb/6fire/comm.c @@ -141,8 +141,7 @@ static int usb6fire_comm_write16(struct comm_runtime *rt, u8 request, int usb6fire_comm_init(struct sfire_chip *chip) { - struct comm_runtime *rt = kzalloc(sizeof(struct comm_runtime), - GFP_KERNEL); + struct comm_runtime *rt = kzalloc_obj(struct comm_runtime); struct urb *urb; int ret; diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index 9bd8dcbb68e4..dd25a6407b63 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c @@ -551,8 +551,7 @@ int usb6fire_control_init(struct sfire_chip *chip) { int i; int ret; - struct control_runtime *rt = kzalloc(sizeof(struct control_runtime), - GFP_KERNEL); + struct control_runtime *rt = kzalloc_obj(struct control_runtime); struct comm_runtime *comm_rt = chip->comm; if (!rt) diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index cc8caec946cc..123c1c6539b8 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c @@ -195,8 +195,7 @@ static int usb6fire_fw_ezusb_upload( u8 data; struct usb_device *device = interface_to_usbdev(intf); const struct firmware *fw = NULL; - struct ihex_record *rec = kmalloc(sizeof(struct ihex_record), - GFP_KERNEL); + struct ihex_record *rec = kmalloc_obj(struct ihex_record); if (!rec) return -ENOMEM; diff --git a/sound/usb/6fire/midi.c b/sound/usb/6fire/midi.c index 4d1eeb32c5fe..6b0bb096f27a 100644 --- a/sound/usb/6fire/midi.c +++ b/sound/usb/6fire/midi.c @@ -140,8 +140,7 @@ static const struct snd_rawmidi_ops in_ops = { int usb6fire_midi_init(struct sfire_chip *chip) { int ret; - struct midi_runtime *rt = kzalloc(sizeof(struct midi_runtime), - GFP_KERNEL); + struct midi_runtime *rt = kzalloc_obj(struct midi_runtime); struct comm_runtime *comm_rt = chip->comm; if (!rt) diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index 08515da5dcc8..d2e274b731fe 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c @@ -587,7 +587,7 @@ int usb6fire_pcm_init(struct sfire_chip *chip) int ret; struct snd_pcm *pcm; struct pcm_runtime *rt = - kzalloc(sizeof(struct pcm_runtime), GFP_KERNEL); + kzalloc_obj(struct pcm_runtime); if (!rt) return -ENOMEM; diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c index 95d425dd9d70..ba3f73455ebe 100644 --- a/sound/usb/caiaq/audio.c +++ b/sound/usb/caiaq/audio.c @@ -681,7 +681,7 @@ static struct urb **alloc_urbs(struct snd_usb_caiaqdev *cdev, int dir, int *ret) usb_sndisocpipe(usb_dev, ENDPOINT_PLAYBACK) : usb_rcvisocpipe(usb_dev, ENDPOINT_CAPTURE); - urbs = kmalloc_array(N_URBS, sizeof(*urbs), GFP_KERNEL); + urbs = kmalloc_objs(*urbs, N_URBS); if (!urbs) { *ret = -ENOMEM; return NULL; @@ -813,8 +813,7 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev) NULL, 0, 0); cdev->data_cb_info = - kmalloc_array(N_URBS, sizeof(struct snd_usb_caiaq_cb_info), - GFP_KERNEL); + kmalloc_objs(struct snd_usb_caiaq_cb_info, N_URBS); if (!cdev->data_cb_info) return -ENOMEM; diff --git a/sound/usb/card.h b/sound/usb/card.h index 94404c24d240..e34d92d576a2 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h @@ -90,7 +90,7 @@ struct snd_usb_endpoint { struct snd_urb_ctx urb[MAX_URBS]; struct snd_usb_packet_info { - uint32_t packet_size[MAX_PACKS_HS]; + int packet_size[MAX_PACKS_HS]; int packets; } next_packet[MAX_URBS]; unsigned int next_packet_head; /* ring buffer offset to read */ diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 8f9313857ee9..bf4401aba76c 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -160,8 +160,8 @@ int snd_usb_endpoint_implicit_feedback_sink(struct snd_usb_endpoint *ep) * This won't be used for implicit feedback which takes the packet size * returned from the sync source */ -static int slave_next_packet_size(struct snd_usb_endpoint *ep, - unsigned int avail) +static int synced_next_packet_size(struct snd_usb_endpoint *ep, + unsigned int avail) { unsigned int phase; int ret; @@ -221,13 +221,14 @@ int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep, packet = ctx->packet_size[idx]; if (packet) { + packet = min(packet, ep->maxframesize); if (avail && packet >= avail) return -EAGAIN; return packet; } if (ep->sync_source) - return slave_next_packet_size(ep, avail); + return synced_next_packet_size(ep, avail); else return next_packet_size(ep, avail); } @@ -275,8 +276,8 @@ static inline bool has_tx_length_quirk(struct snd_usb_audio *chip) return chip->quirk_flags & QUIRK_FLAG_TX_LENGTH; } -static void prepare_silent_urb(struct snd_usb_endpoint *ep, - struct snd_urb_ctx *ctx) +static int prepare_silent_urb(struct snd_usb_endpoint *ep, + struct snd_urb_ctx *ctx) { struct urb *urb = ctx->urb; unsigned int offs = 0; @@ -289,28 +290,34 @@ static void prepare_silent_urb(struct snd_usb_endpoint *ep, extra = sizeof(packet_length); for (i = 0; i < ctx->packets; ++i) { - unsigned int offset; - unsigned int length; - int counts; + int length; - counts = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0); - length = counts * ep->stride; /* number of silent bytes */ - offset = offs * ep->stride + extra * i; - urb->iso_frame_desc[i].offset = offset; + length = snd_usb_endpoint_next_packet_size(ep, ctx, i, 0); + if (length < 0) + return length; + length *= ep->stride; /* number of silent bytes */ + if (offs + length + extra > ctx->buffer_size) + break; + urb->iso_frame_desc[i].offset = offs; urb->iso_frame_desc[i].length = length + extra; if (extra) { packet_length = cpu_to_le32(length); - memcpy(urb->transfer_buffer + offset, + memcpy(urb->transfer_buffer + offs, &packet_length, sizeof(packet_length)); + offs += extra; } - memset(urb->transfer_buffer + offset + extra, + memset(urb->transfer_buffer + offs, ep->silence_value, length); - offs += counts; + offs += length; } - urb->number_of_packets = ctx->packets; - urb->transfer_buffer_length = offs * ep->stride + ctx->packets * extra; + if (!offs) + return -EPIPE; + + urb->number_of_packets = i; + urb->transfer_buffer_length = offs; ctx->queued = 0; + return 0; } /* @@ -332,8 +339,7 @@ static int prepare_outbound_urb(struct snd_usb_endpoint *ep, if (data_subs && ep->prepare_data_urb) return ep->prepare_data_urb(data_subs, urb, in_stream_lock); /* no data provider, so send silence */ - prepare_silent_urb(ep, ctx); - break; + return prepare_silent_urb(ep, ctx); case SND_USB_ENDPOINT_TYPE_SYNC: if (snd_usb_get_speed(ep->chip->dev) >= USB_SPEED_HIGH) { @@ -397,18 +403,21 @@ static int prepare_inbound_urb(struct snd_usb_endpoint *ep, } /* notify an error as XRUN to the assigned PCM data substream */ -static void notify_xrun(struct snd_usb_endpoint *ep) +static bool notify_xrun(struct snd_usb_endpoint *ep) { struct snd_usb_substream *data_subs; struct snd_pcm_substream *psubs; data_subs = READ_ONCE(ep->data_subs); if (!data_subs) - return; + return false; psubs = data_subs->pcm_substream; if (psubs && psubs->runtime && - psubs->runtime->state == SNDRV_PCM_STATE_RUNNING) + psubs->runtime->state == SNDRV_PCM_STATE_RUNNING) { snd_pcm_stop_xrun(psubs); + return true; + } + return false; } static struct snd_usb_packet_info * @@ -462,7 +471,7 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, while (ep_state_running(ep)) { struct snd_usb_packet_info *packet; struct snd_urb_ctx *ctx = NULL; - int err, i; + int err; scoped_guard(spinlock_irqsave, &ep->lock) { if ((!implicit_fb || ep->next_packet_queued > 0) && @@ -481,8 +490,9 @@ int snd_usb_queue_pending_output_urbs(struct snd_usb_endpoint *ep, /* copy over the length information */ if (implicit_fb) { - for (i = 0; i < packet->packets; i++) - ctx->packet_size[i] = packet->packet_size[i]; + ctx->packets = packet->packets; + memcpy(ctx->packet_size, packet->packet_size, + packet->packets * sizeof(packet->packet_size[0])); } /* call the data handler to fill in playback data */ @@ -588,8 +598,9 @@ static void snd_complete_urb(struct urb *urb) return; if (!atomic_read(&ep->chip->shutdown)) { - usb_audio_err(ep->chip, "cannot submit urb (err = %d)\n", err); - notify_xrun(ep); + if (notify_xrun(ep)) + usb_audio_err(ep->chip, + "cannot submit urb (err = %d)\n", err); } exit_clear: @@ -611,7 +622,7 @@ iface_ref_find(struct snd_usb_audio *chip, int iface) if (ip->iface == iface) return ip; - ip = kzalloc(sizeof(*ip), GFP_KERNEL); + ip = kzalloc_obj(*ip); if (!ip) return NULL; ip->iface = iface; @@ -629,7 +640,7 @@ clock_ref_find(struct snd_usb_audio *chip, int clock) if (ref->clock == clock) return ref; - ref = kzalloc(sizeof(*ref), GFP_KERNEL); + ref = kzalloc_obj(*ref); if (!ref) return NULL; ref->clock = clock; @@ -688,7 +699,7 @@ int snd_usb_add_endpoint(struct snd_usb_audio *chip, int ep_num, int type) usb_audio_dbg(chip, "Creating new %s endpoint #%x\n", ep_type_name(type), ep_num); - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -1368,6 +1379,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip, return -EINVAL; } + ep->packsize[0] = min(ep->packsize[0], ep->maxframesize); + ep->packsize[1] = min(ep->packsize[1], ep->maxframesize); + /* calculate the frequency in 16.16 format */ ep->freqm = ep->freqn; ep->freqshift = INT_MIN; @@ -1773,10 +1787,11 @@ static void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, spin_lock_irqsave(&ep->lock, flags); if (ep->next_packet_queued >= ARRAY_SIZE(ep->next_packet)) { spin_unlock_irqrestore(&ep->lock, flags); - usb_audio_err(ep->chip, - "next package FIFO overflow EP 0x%x\n", - ep->ep_num); - notify_xrun(ep); + if (notify_xrun(ep)) { + usb_audio_err(ep->chip, + "next packet FIFO overflow EP 0x%x\n", + ep->ep_num); + } return; } diff --git a/sound/usb/fcp.c b/sound/usb/fcp.c index 1f4595d1e217..0fc4d063c48a 100644 --- a/sound/usb/fcp.c +++ b/sound/usb/fcp.c @@ -329,7 +329,7 @@ static int fcp_add_new_ctl(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *elem; int err; - elem = kzalloc(sizeof(*elem), GFP_KERNEL); + elem = kzalloc_obj(*elem); if (!elem) return -ENOMEM; @@ -654,7 +654,7 @@ static int fcp_ioctl_set_meter_map(struct usb_mixer_interface *mixer, if (!private->meter_ctl) { /* Allocate buffer for the map */ s16 *new_map __free(kfree) = - kmalloc_array(map.map_size, sizeof(s16), GFP_KERNEL); + kmalloc_objs(s16, map.map_size); if (!new_map) return -ENOMEM; @@ -1045,7 +1045,7 @@ static int fcp_init(struct usb_mixer_interface *mixer, static int fcp_init_private(struct usb_mixer_interface *mixer) { struct fcp_data *private = - kzalloc(sizeof(struct fcp_data), GFP_KERNEL); + kzalloc_obj(struct fcp_data); if (!private) return -ENOMEM; diff --git a/sound/usb/format.c b/sound/usb/format.c index 64cfe4a9d8cd..1207c507882a 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -305,17 +305,48 @@ static bool s1810c_valid_sample_rate(struct audioformat *fp, } /* - * Many Focusrite devices supports a limited set of sampling rates per - * altsetting. Maximum rate is exposed in the last 4 bytes of Format Type - * descriptor which has a non-standard bLength = 10. + * Focusrite devices use rate pairs: 44100/48000, 88200/96000, and + * 176400/192000. Return true if rate is in the pair for max_rate. + */ +static bool focusrite_rate_pair(unsigned int rate, + unsigned int max_rate) +{ + switch (max_rate) { + case 48000: return rate == 44100 || rate == 48000; + case 96000: return rate == 88200 || rate == 96000; + case 192000: return rate == 176400 || rate == 192000; + default: return true; + } +} + +/* + * Focusrite devices report all supported rates in a single clock + * source but only a subset is valid per altsetting. + * + * Detection uses two descriptor features: + * + * 1. Format Type descriptor bLength == 10: non-standard extension + * with max sample rate in bytes 6..9. + * + * 2. bmControls VAL_ALT_SETTINGS readable bit: when set, the device + * only supports the highest rate pair for that altsetting, and when + * clear, all rates up to max_rate are valid. + * + * For devices without the bLength == 10 extension but with + * VAL_ALT_SETTINGS readable and multiple altsettings (only seen in + * Scarlett 18i8 3rd Gen playback), fall back to the Focusrite + * convention: alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. */ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, struct audioformat *fp, unsigned int rate) { + struct usb_interface *iface; struct usb_host_interface *alts; + struct uac2_as_header_descriptor *as; unsigned char *fmt; unsigned int max_rate; + bool val_alt; alts = snd_usb_get_host_interface(chip, fp->iface, fp->altsetting); if (!alts) @@ -326,9 +357,21 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, if (!fmt) return true; + as = snd_usb_find_csint_desc(alts->extra, alts->extralen, + NULL, UAC_AS_GENERAL); + if (!as) + return true; + + val_alt = uac_v2v3_control_is_readable(as->bmControls, + UAC2_AS_VAL_ALT_SETTINGS); + if (fmt[0] == 10) { /* bLength */ max_rate = combine_quad(&fmt[6]); + if (val_alt) + return focusrite_rate_pair(rate, max_rate); + + /* No val_alt: rates fall through from higher */ switch (max_rate) { case 192000: if (rate == 176400 || rate == 192000) @@ -344,12 +387,29 @@ static bool focusrite_valid_sample_rate(struct snd_usb_audio *chip, usb_audio_info(chip, "%u:%d : unexpected max rate: %u\n", fp->iface, fp->altsetting, max_rate); - return true; } } - return true; + if (!val_alt) + return true; + + /* Multi-altsetting device with val_alt but no max_rate + * in the format descriptor. Use Focusrite convention: + * alt 1 = 48kHz, alt 2 = 96kHz, alt 3 = 192kHz. + */ + iface = usb_ifnum_to_if(chip->dev, fp->iface); + if (!iface || iface->num_altsetting <= 2) + return true; + + switch (fp->altsetting) { + case 1: max_rate = 48000; break; + case 2: max_rate = 96000; break; + case 3: max_rate = 192000; break; + default: return true; + } + + return focusrite_rate_pair(rate, max_rate); } /* diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c index 27cd427fbaa5..cd1a4c871c5d 100644 --- a/sound/usb/hiface/pcm.c +++ b/sound/usb/hiface/pcm.c @@ -547,7 +547,7 @@ int hiface_pcm_init(struct hiface_chip *chip, u8 extra_freq) struct snd_pcm *pcm; struct pcm_runtime *rt; - rt = kzalloc(sizeof(*rt), GFP_KERNEL); + rt = kzalloc_obj(*rt); if (!rt) return -ENOMEM; diff --git a/sound/usb/line6/capture.c b/sound/usb/line6/capture.c index 9ef4faa006a0..6dbaf30232f9 100644 --- a/sound/usb/line6/capture.c +++ b/sound/usb/line6/capture.c @@ -255,8 +255,7 @@ int line6_create_audio_in_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->in.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), - GFP_KERNEL); + line6pcm->in.urbs = kzalloc_objs(struct urb *, line6->iso_buffers); if (line6pcm->in.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c index e97368c31417..191682894f04 100644 --- a/sound/usb/line6/driver.c +++ b/sound/usb/line6/driver.c @@ -202,7 +202,7 @@ int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer, struct urb *urb; /* create message: */ - msg = kzalloc(sizeof(struct message), GFP_ATOMIC); + msg = kzalloc_obj(struct message, GFP_ATOMIC); if (msg == NULL) return -ENOMEM; diff --git a/sound/usb/line6/midi.c b/sound/usb/line6/midi.c index 4731293728e6..af01b649393c 100644 --- a/sound/usb/line6/midi.c +++ b/sound/usb/line6/midi.c @@ -264,7 +264,7 @@ int line6_init_midi(struct usb_line6 *line6) if (err < 0) return err; - line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL); + line6midi = kzalloc_obj(struct snd_line6_midi); if (!line6midi) return -ENOMEM; diff --git a/sound/usb/line6/pcm.c b/sound/usb/line6/pcm.c index f61d9f6cf754..2932eaf157f4 100644 --- a/sound/usb/line6/pcm.c +++ b/sound/usb/line6/pcm.c @@ -528,7 +528,7 @@ int line6_init_pcm(struct usb_line6 *line6, if (err < 0) return err; - line6pcm = kzalloc(sizeof(*line6pcm), GFP_KERNEL); + line6pcm = kzalloc_obj(*line6pcm); if (!line6pcm) return -ENOMEM; diff --git a/sound/usb/line6/playback.c b/sound/usb/line6/playback.c index 9f26f66e6792..7ebaf125f969 100644 --- a/sound/usb/line6/playback.c +++ b/sound/usb/line6/playback.c @@ -404,8 +404,7 @@ int line6_create_audio_out_urbs(struct snd_line6_pcm *line6pcm) struct usb_line6 *line6 = line6pcm->line6; int i; - line6pcm->out.urbs = kcalloc(line6->iso_buffers, sizeof(struct urb *), - GFP_KERNEL); + line6pcm->out.urbs = kzalloc_objs(struct urb *, line6->iso_buffers); if (line6pcm->out.urbs == NULL) return -ENOMEM; diff --git a/sound/usb/line6/toneport.c b/sound/usb/line6/toneport.c index 68cda7bf330c..1df5c0dcd216 100644 --- a/sound/usb/line6/toneport.c +++ b/sound/usb/line6/toneport.c @@ -363,7 +363,7 @@ static int toneport_setup(struct usb_line6_toneport *toneport) struct usb_line6 *line6 = &toneport->line6; struct usb_device *usbdev = line6->usbdev; - ticks = kmalloc(sizeof(*ticks), GFP_KERNEL); + ticks = kmalloc_obj(*ticks); if (!ticks) return -ENOMEM; diff --git a/sound/usb/media.c b/sound/usb/media.c index 0064f8d12422..b7497d18ee3f 100644 --- a/sound/usb/media.c +++ b/sound/usb/media.c @@ -49,7 +49,7 @@ int snd_media_stream_init(struct snd_usb_substream *subs, struct snd_pcm *pcm, return 0; /* allocate media_ctl */ - mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); + mctl = kzalloc_obj(*mctl); if (!mctl) return -ENOMEM; @@ -188,7 +188,7 @@ static int snd_media_mixer_init(struct snd_usb_audio *chip) continue; /* allocate media_mixer_ctl */ - mctl = kzalloc(sizeof(*mctl), GFP_KERNEL); + mctl = kzalloc_obj(*mctl); if (!mctl) return -ENOMEM; diff --git a/sound/usb/midi.c b/sound/usb/midi.c index dd8249e75970..a8bddc90c0ed 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c @@ -1328,7 +1328,7 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi *umidi, int err; rep->in = NULL; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; ep->umidi = umidi; @@ -1414,7 +1414,7 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi *umidi, int err; rep->out = NULL; - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; ep->umidi = umidi; @@ -2506,7 +2506,7 @@ int __snd_usbmidi_create(struct snd_card *card, int out_ports, in_ports; int i, err; - umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); + umidi = kzalloc_obj(*umidi); if (!umidi) return -ENOMEM; umidi->dev = interface_to_usbdev(iface); diff --git a/sound/usb/midi2.c b/sound/usb/midi2.c index e6793f3bdfc3..ef602e81576d 100644 --- a/sound/usb/midi2.c +++ b/sound/usb/midi2.c @@ -432,7 +432,7 @@ static int create_midi2_endpoint(struct snd_usb_midi2_interface *umidi, hostep->desc.bEndpointAddress, ms_ep->bNumGrpTrmBlock); - ep = kzalloc(sizeof(*ep), GFP_KERNEL); + ep = kzalloc_obj(*ep); if (!ep) return -ENOMEM; @@ -693,7 +693,7 @@ static int create_midi2_ump(struct snd_usb_midi2_interface *umidi, char idstr[16]; int err; - rmidi = kzalloc(sizeof(*rmidi), GFP_KERNEL); + rmidi = kzalloc_obj(*rmidi); if (!rmidi) return -ENOMEM; INIT_LIST_HEAD(&rmidi->list); @@ -1101,7 +1101,7 @@ int snd_usb_midi_v2_create(struct snd_usb_audio *chip, hostif->desc.bInterfaceNumber, hostif->desc.bAlternateSetting); - umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); + umidi = kzalloc_obj(*umidi); if (!umidi) return -ENOMEM; umidi->chip = chip; diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c index 76b6eb55dcc2..49b3dd8d827d 100644 --- a/sound/usb/misc/ua101.c +++ b/sound/usb/misc/ua101.c @@ -1062,7 +1062,7 @@ static int alloc_stream_urbs(struct ua101 *ua, struct ua101_stream *stream, while (size >= max_packet_size) { if (u >= stream->queue_length) goto bufsize_error; - urb = kmalloc(sizeof(*urb), GFP_KERNEL); + urb = kmalloc_obj(*urb); if (!urb) return -ENOMEM; usb_init_urb(&urb->urb); diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index bfe15b1cb66c..ac8c71ba9483 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -1684,7 +1684,7 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer, if (check_ignored_ctl(map)) return; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return; snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); @@ -1894,7 +1894,7 @@ static void build_connector_control(struct usb_mixer_interface *mixer, if (check_ignored_ctl(map)) return; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return; snd_usb_mixer_elem_init_std(&cval->head, mixer, term->id); @@ -1956,7 +1956,7 @@ static int parse_clock_source_unit(struct mixer_build *state, int unitid, UAC2_CS_CONTROL_CLOCK_VALID)) return 0; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return -ENOMEM; @@ -2177,7 +2177,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, if (check_ignored_ctl(map)) return; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return; @@ -2525,7 +2525,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, map = find_map(state->map, unitid, valinfo->control); if (check_ignored_ctl(map)) continue; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return -ENOMEM; snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); @@ -2771,7 +2771,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, if (check_ignored_ctl(map)) return 0; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return -ENOMEM; snd_usb_mixer_elem_init_std(&cval->head, state->mixer, unitid); @@ -3598,13 +3598,12 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif) strscpy(chip->card->mixername, "USB Mixer"); - mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); + mixer = kzalloc_obj(*mixer); if (!mixer) return -ENOMEM; mixer->chip = chip; mixer->ignore_ctl_error = !!(chip->quirk_flags & QUIRK_FLAG_IGNORE_CTL_ERROR); - mixer->id_elems = kcalloc(MAX_ID_ELEMS, sizeof(*mixer->id_elems), - GFP_KERNEL); + mixer->id_elems = kzalloc_objs(*mixer->id_elems, MAX_ID_ELEMS); if (!mixer->id_elems) { kfree(mixer); return -ENOMEM; diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index ec65e8a71919..11e205da7964 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -67,7 +67,7 @@ static int snd_create_std_mono_ctl_offset(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *cval; struct snd_kcontrol *kctl; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return -ENOMEM; @@ -151,7 +151,7 @@ static int add_single_ctl_with_resume(struct usb_mixer_interface *mixer, struct usb_mixer_elem_list *list; struct snd_kcontrol *kctl; - list = kzalloc(sizeof(*list), GFP_KERNEL); + list = kzalloc_obj(*list); if (!list) return -ENOMEM; if (listp) @@ -274,7 +274,7 @@ static int snd_usb_soundblaster_remote_init(struct usb_mixer_interface *mixer) mixer->rc_urb = usb_alloc_urb(0, GFP_KERNEL); if (!mixer->rc_urb) return -ENOMEM; - mixer->rc_setup_packet = kmalloc(sizeof(*mixer->rc_setup_packet), GFP_KERNEL); + mixer->rc_setup_packet = kmalloc_obj(*mixer->rc_setup_packet); if (!mixer->rc_setup_packet) { usb_free_urb(mixer->rc_urb); mixer->rc_urb = NULL; @@ -616,7 +616,7 @@ static int snd_dualsense_ih_connect(struct input_handler *handler, struct input_handle *handle; int err; - handle = kzalloc(sizeof(*handle), GFP_KERNEL); + handle = kzalloc_obj(*handle); if (!handle) return -ENOMEM; @@ -713,7 +713,7 @@ static int snd_dualsense_jack_create(struct usb_mixer_interface *mixer, struct snd_kcontrol *kctl; int err; - mei = kzalloc(sizeof(*mei), GFP_KERNEL); + mei = kzalloc_obj(*mei); if (!mei) return -ENOMEM; @@ -2278,7 +2278,7 @@ static int realtek_add_jack(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *cval; struct snd_kcontrol *kctl; - cval = kzalloc(sizeof(*cval), GFP_KERNEL); + cval = kzalloc_obj(*cval); if (!cval) return -ENOMEM; snd_usb_mixer_elem_init_std(&cval->head, mixer, unitid); diff --git a/sound/usb/mixer_s1810c.c b/sound/usb/mixer_s1810c.c index b4ce89afb25b..7eac7d1bce64 100644 --- a/sound/usb/mixer_s1810c.c +++ b/sound/usb/mixer_s1810c.c @@ -71,7 +71,7 @@ * * e I guess the same as with mixer * */ -/** struct s1810c_ctl_packet - basic vendor request +/* struct s1810c_ctl_packet - basic vendor request * @selector: device/mixer/output * @b: request-dependant field b * @tag: fixed value identifying type of request @@ -94,14 +94,14 @@ struct s1810c_ctl_packet { __le32 e; }; -/** selectors for CMD request +/* selectors for CMD request */ #define SC1810C_SEL_DEVICE 0 #define SC1810C_SEL_MIXER 0x64 #define SC1810C_SEL_OUTPUT 0x65 -/** control ids */ +/* control ids */ #define SC1810C_CTL_LINE_SW 0 #define SC1810C_CTL_MUTE_SW 1 #define SC1824C_CTL_MONO_SW 2 @@ -127,7 +127,7 @@ struct s1810c_ctl_packet { #define SC1810C_GET_STATE_TAG SC1810C_SET_STATE_TAG #define SC1810C_GET_STATE_LEN SC1810C_SET_STATE_LEN -/** Mixer levels normally range from 0 (off) to 0x0100 0000 (0 dB). +/* Mixer levels normally range from 0 (off) to 0x0100 0000 (0 dB). * raw_level = 2^24 * 10^(db_level / 20), thus * -3dB = 0xb53bf0 (technically, half-power -3.01...dB would be 0xb504f3) * -96dB = 0x109 @@ -145,7 +145,7 @@ struct s1810c_ctl_packet { #define MIXER_LEVEL_N3DB 0xb53bf0 #define MIXER_LEVEL_0DB 0x1000000 -/** +/* * This packet includes mixer volumes and * various other fields, it's an extended * version of ctl_packet, with a and b @@ -155,7 +155,7 @@ struct s1810c_state_packet { __le32 fields[63]; }; -/** indices into s1810c_state_packet.fields[] +/* indices into s1810c_state_packet.fields[] */ #define SC1810C_STATE_TAG_IDX 2 #define SC1810C_STATE_LEN_IDX 3 @@ -534,7 +534,7 @@ snd_s1810c_switch_init(struct usb_mixer_interface *mixer, struct snd_kcontrol *kctl; struct usb_mixer_elem_info *elem; - elem = kzalloc(sizeof(struct usb_mixer_elem_info), GFP_KERNEL); + elem = kzalloc_obj(struct usb_mixer_elem_info); if (!elem) return -ENOMEM; @@ -645,7 +645,7 @@ int snd_sc1810_init_mixer(struct usb_mixer_interface *mixer) if (ret < 0) return ret; - private = kzalloc(sizeof(struct s1810_mixer_state), GFP_KERNEL); + private = kzalloc_obj(struct s1810_mixer_state); if (!private) return -ENOMEM; diff --git a/sound/usb/mixer_scarlett.c b/sound/usb/mixer_scarlett.c index fa11f25288b7..1bb01e827654 100644 --- a/sound/usb/mixer_scarlett.c +++ b/sound/usb/mixer_scarlett.c @@ -819,7 +819,7 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *elem; int err; - elem = kzalloc(sizeof(*elem), GFP_KERNEL); + elem = kzalloc_obj(*elem); if (!elem) return -ENOMEM; diff --git a/sound/usb/mixer_scarlett2.c b/sound/usb/mixer_scarlett2.c index 88b7e42d159e..fd1fb668929a 100644 --- a/sound/usb/mixer_scarlett2.c +++ b/sound/usb/mixer_scarlett2.c @@ -1328,8 +1328,6 @@ struct scarlett2_data { struct snd_kcontrol *mux_ctls[SCARLETT2_MUX_MAX]; struct snd_kcontrol *mix_ctls[SCARLETT2_MIX_MAX]; struct snd_kcontrol *compressor_ctls[SCARLETT2_COMPRESSOR_CTLS_MAX]; - struct snd_kcontrol *precomp_flt_ctls[SCARLETT2_PRECOMP_FLT_CTLS_MAX]; - struct snd_kcontrol *peq_flt_ctls[SCARLETT2_PEQ_FLT_CTLS_MAX]; struct snd_kcontrol *precomp_flt_switch_ctls[SCARLETT2_DSP_SWITCH_MAX]; struct snd_kcontrol *peq_flt_switch_ctls[SCARLETT2_DSP_SWITCH_MAX]; struct snd_kcontrol *direct_monitor_ctl; @@ -3197,7 +3195,7 @@ static int scarlett2_add_new_ctl(struct usb_mixer_interface *mixer, struct usb_mixer_elem_info *elem; int err; - elem = kzalloc(sizeof(*elem), GFP_KERNEL); + elem = kzalloc_obj(*elem); if (!elem) return -ENOMEM; @@ -3447,7 +3445,6 @@ static int scarlett2_update_autogain(struct usb_mixer_interface *mixer) private->autogain_status[i] = private->num_autogain_status_texts - 1; - for (i = 0; i < SCARLETT2_AG_TARGET_COUNT; i++) if (scarlett2_has_config_item(private, scarlett2_ag_target_configs[i])) { @@ -5372,8 +5369,7 @@ static int scarlett2_update_filter_values(struct usb_mixer_interface *mixer) err = scarlett2_usb_get_config( mixer, SCARLETT2_CONFIG_PEQ_FLT_SWITCH, - info->dsp_input_count * info->peq_flt_count, - private->peq_flt_switch); + info->dsp_input_count, private->peq_flt_switch); if (err < 0) return err; @@ -6546,7 +6542,7 @@ static int scarlett2_add_dsp_ctls(struct usb_mixer_interface *mixer, int i) err = scarlett2_add_new_ctl( mixer, &scarlett2_precomp_flt_ctl, i * info->precomp_flt_count + j, - 1, s, &private->precomp_flt_switch_ctls[j]); + 1, s, NULL); if (err < 0) return err; } @@ -6556,7 +6552,7 @@ static int scarlett2_add_dsp_ctls(struct usb_mixer_interface *mixer, int i) err = scarlett2_add_new_ctl( mixer, &scarlett2_peq_flt_ctl, i * info->peq_flt_count + j, - 1, s, &private->peq_flt_switch_ctls[j]); + 1, s, NULL); if (err < 0) return err; } @@ -8255,6 +8251,8 @@ static int scarlett2_find_fc_interface(struct usb_device *dev, if (desc->bInterfaceClass != 255) continue; + if (desc->bNumEndpoints < 1) + continue; epd = get_endpoint(intf->altsetting, 0); private->bInterfaceNumber = desc->bInterfaceNumber; @@ -8272,7 +8270,7 @@ static int scarlett2_init_private(struct usb_mixer_interface *mixer, const struct scarlett2_device_entry *entry) { struct scarlett2_data *private = - kzalloc(sizeof(struct scarlett2_data), GFP_KERNEL); + kzalloc_obj(struct scarlett2_data); if (!private) return -ENOMEM; diff --git a/sound/usb/mixer_us16x08.c b/sound/usb/mixer_us16x08.c index f9df40730eff..8a02964e5d7b 100644 --- a/sound/usb/mixer_us16x08.c +++ b/sound/usb/mixer_us16x08.c @@ -969,7 +969,7 @@ static struct snd_us16x08_comp_store *snd_us16x08_create_comp_store(void) int i; struct snd_us16x08_comp_store *tmp; - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kmalloc_obj(*tmp); if (!tmp) return NULL; @@ -991,7 +991,7 @@ static struct snd_us16x08_eq_store *snd_us16x08_create_eq_store(void) int i, b_idx; struct snd_us16x08_eq_store *tmp; - tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kmalloc_obj(*tmp); if (!tmp) return NULL; @@ -1027,7 +1027,7 @@ static struct snd_us16x08_meter_store *snd_us16x08_create_meter_store(void) { struct snd_us16x08_meter_store *tmp; - tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); + tmp = kzalloc_obj(*tmp); if (!tmp) return NULL; tmp->comp_index = 1; @@ -1059,7 +1059,7 @@ static int add_new_ctl(struct usb_mixer_interface *mixer, usb_audio_dbg(mixer->chip, "us16x08 add mixer %s\n", name); - elem = kzalloc(sizeof(*elem), GFP_KERNEL); + elem = kzalloc_obj(*elem); if (!elem) return -ENOMEM; diff --git a/sound/usb/power.c b/sound/usb/power.c index 66bd4daa68fd..c2d708c87fc4 100644 --- a/sound/usb/power.c +++ b/sound/usb/power.c @@ -20,7 +20,7 @@ snd_usb_find_power_domain(struct usb_host_interface *ctrl_iface, struct snd_usb_power_domain *pd; void *p; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) return NULL; diff --git a/sound/usb/qcom/qc_audio_offload.c b/sound/usb/qcom/qc_audio_offload.c index cfb30a195364..510b68cced33 100644 --- a/sound/usb/qcom/qc_audio_offload.c +++ b/sound/usb/qcom/qc_audio_offload.c @@ -438,7 +438,7 @@ static unsigned long uaudio_get_iova(unsigned long *curr_iova, } } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = kzalloc_obj(*info); if (!info) { iova = 0; goto done; @@ -1007,7 +1007,7 @@ static int enable_audio_stream(struct snd_usb_substream *subs, /** * uaudio_transfer_buffer_setup() - fetch and populate xfer buffer params * @subs: usb substream - * @xfer_buf: xfer buf to be allocated + * @xfer_buf_cpu: xfer buf to be allocated * @xfer_buf_len: size of allocation * @mem_info: QMI response info * @@ -1432,9 +1432,8 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, init_waitqueue_head(&uadev[card_num].disconnect_wq); uadev[card_num].num_intf = subs->dev->config->desc.bNumInterfaces; - uadev[card_num].info = kcalloc(uadev[card_num].num_intf, - sizeof(struct intf_info), - GFP_KERNEL); + uadev[card_num].info = kzalloc_objs(struct intf_info, + uadev[card_num].num_intf); if (!uadev[card_num].info) { ret = -ENOMEM; goto unmap_er; @@ -1687,7 +1686,7 @@ static struct qmi_msg_handler uaudio_stream_req_handlers = { */ static int qc_usb_audio_offload_init_qmi_dev(void) { - uaudio_qdev = kzalloc(sizeof(*uaudio_qdev), GFP_KERNEL); + uaudio_qdev = kzalloc_obj(*uaudio_qdev); if (!uaudio_qdev) return -ENOMEM; @@ -1759,7 +1758,7 @@ static void qc_usb_audio_offload_probe(struct snd_usb_audio *chip) guard(mutex)(&qdev_mutex); guard(mutex)(&chip->mutex); if (!uadev[chip->card->number].chip) { - sdev = kzalloc(sizeof(*sdev), GFP_KERNEL); + sdev = kzalloc_obj(*sdev); if (!sdev) return; @@ -1914,11 +1913,11 @@ static int qc_usb_audio_probe(struct auxiliary_device *auxdev, struct uaudio_qmi_svc *svc; int ret; - svc = kzalloc(sizeof(*svc), GFP_KERNEL); + svc = kzalloc_obj(*svc); if (!svc) return -ENOMEM; - svc->uaudio_svc_hdl = kzalloc(sizeof(*svc->uaudio_svc_hdl), GFP_KERNEL); + svc->uaudio_svc_hdl = kzalloc_obj(*svc->uaudio_svc_hdl); if (!svc->uaudio_svc_hdl) { ret = -ENOMEM; goto free_svc; diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 86c329632e39..049a94079f9e 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -566,7 +566,7 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac if (err < 0) dev_dbg(&dev->dev, "error sending boot message: %d\n", err); struct usb_device_descriptor *new_device_descriptor __free(kfree) = - kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + kmalloc_obj(*new_device_descriptor); if (!new_device_descriptor) return -ENOMEM; err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, @@ -944,7 +944,7 @@ static int snd_usb_mbox2_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "device initialised!\n"); struct usb_device_descriptor *new_device_descriptor __free(kfree) = - kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + kmalloc_obj(*new_device_descriptor); if (!new_device_descriptor) return -ENOMEM; @@ -1279,7 +1279,7 @@ static int snd_usb_mbox3_boot_quirk(struct usb_device *dev) dev_dbg(&dev->dev, "MBOX3: device initialised!\n"); struct usb_device_descriptor *new_device_descriptor __free(kfree) = - kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL); + kmalloc_obj(*new_device_descriptor); if (!new_device_descriptor) return -ENOMEM; @@ -2148,6 +2148,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { /* Device matches */ DEVICE_FLG(0x001f, 0x0b21, /* AB13X USB Audio */ QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x0020, 0x0b21, /* GHW-123P */ + QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16), DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */ @@ -2217,6 +2219,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x05e1, 0x0480, /* Hauppauge Woodbury */ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), + DEVICE_FLG(0x0624, 0x3d3f, /* AB13X USB Audio */ + QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x0644, 0x8043, /* TEAC UD-501/UD-501V2/UD-503/NT-503 */ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY), @@ -2239,6 +2243,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_IFACE_DELAY | QUIRK_FLAG_FORCE_IFACE_RESET), DEVICE_FLG(0x0661, 0x0883, /* iBasso DC04 Ultra */ QUIRK_FLAG_DSD_RAW), + DEVICE_FLG(0x0666, 0x0880, /* SPACETOUCH USB Audio */ + QUIRK_FLAG_FORCE_IFACE_RESET | QUIRK_FLAG_IFACE_DELAY), DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ QUIRK_FLAG_IGNORE_CTL_ERROR), DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ @@ -2363,6 +2369,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x2040, 0x7281, /* Hauppauge HVR-950Q-MXL */ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), + DEVICE_FLG(0x20b1, 0x2009, /* XMOS Ltd DIYINHK USB Audio 2.0 */ + QUIRK_FLAG_SKIP_IMPLICIT_FB | QUIRK_FLAG_DSD_RAW), DEVICE_FLG(0x2040, 0x8200, /* Hauppauge Woodbury */ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER), DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */ @@ -2422,7 +2430,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { VENDOR_FLG(0x07fd, /* MOTU */ QUIRK_FLAG_VALIDATE_RATES), VENDOR_FLG(0x1235, /* Focusrite Novation */ - QUIRK_FLAG_VALIDATE_RATES), + QUIRK_FLAG_SKIP_CLOCK_SELECTOR | + QUIRK_FLAG_SKIP_IFACE_SETUP), VENDOR_FLG(0x1511, /* AURALiC */ QUIRK_FLAG_DSD_RAW), VENDOR_FLG(0x152a, /* Thesycon devices */ @@ -2504,6 +2513,7 @@ static const char *const snd_usb_audio_quirk_flag_names[] = { QUIRK_STRING_ENTRY(MIC_RES_384), QUIRK_STRING_ENTRY(MIXER_PLAYBACK_MIN_MUTE), QUIRK_STRING_ENTRY(MIXER_CAPTURE_MIN_MUTE), + QUIRK_STRING_ENTRY(SKIP_IFACE_SETUP), NULL }; diff --git a/sound/usb/stream.c b/sound/usb/stream.c index ec7d756d78d1..d38c39e28f38 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -291,7 +291,7 @@ static struct snd_pcm_chmap_elem *convert_chmap(int channels, unsigned int bits, if (channels > ARRAY_SIZE(chmap->map)) return NULL; - chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); + chmap = kzalloc_obj(*chmap); if (!chmap) return NULL; @@ -335,7 +335,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptor if (channels > ARRAY_SIZE(chmap->map)) return NULL; - chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); + chmap = kzalloc_obj(*chmap); if (!chmap) return NULL; @@ -526,7 +526,7 @@ static int __snd_usb_add_audio_stream(struct snd_usb_audio *chip, } /* create a new pcm */ - as = kzalloc(sizeof(*as), GFP_KERNEL); + as = kzalloc_obj(*as); if (!as) return -ENOMEM; as->pcm_index = chip->pcm_devs; @@ -693,7 +693,7 @@ audio_format_alloc_init(struct snd_usb_audio *chip, struct usb_host_endpoint *ep = &alts->endpoint[0]; struct audioformat *fp; - fp = kzalloc(sizeof(*fp), GFP_KERNEL); + fp = kzalloc_obj(*fp); if (!fp) return NULL; @@ -927,7 +927,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, break; } - chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); + chmap = kzalloc_obj(*chmap); if (!chmap) return ERR_PTR(-ENOMEM); @@ -1078,7 +1078,7 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, fp->rate_max = UAC3_BADD_SAMPLING_RATE; fp->rates = SNDRV_PCM_RATE_CONTINUOUS; - pd = kzalloc(sizeof(*pd), GFP_KERNEL); + pd = kzalloc_obj(*pd); if (!pd) { audioformat_free(fp); return NULL; @@ -1259,6 +1259,9 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, set_iface_first = true; /* try to set the interface... */ + if (chip->quirk_flags & QUIRK_FLAG_SKIP_IFACE_SETUP) + continue; + usb_set_interface(chip->dev, iface_no, 0); if (set_iface_first) usb_set_interface(chip->dev, iface_no, altno); diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 79978cae9799..085530cf62d9 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h @@ -224,6 +224,10 @@ extern bool snd_usb_skip_validation; * playback value represents muted state instead of minimum audible volume * QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE * Similar to QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE, but for capture streams + * QUIRK_FLAG_SKIP_IFACE_SETUP + * Skip the probe-time interface setup (usb_set_interface, + * init_pitch, init_sample_rate); redundant with + * snd_usb_endpoint_prepare() at stream-open time */ enum { @@ -253,6 +257,7 @@ enum { QUIRK_TYPE_MIC_RES_384 = 23, QUIRK_TYPE_MIXER_PLAYBACK_MIN_MUTE = 24, QUIRK_TYPE_MIXER_CAPTURE_MIN_MUTE = 25, + QUIRK_TYPE_SKIP_IFACE_SETUP = 26, /* Please also edit snd_usb_audio_quirk_flag_names */ }; @@ -284,5 +289,6 @@ enum { #define QUIRK_FLAG_MIC_RES_384 QUIRK_FLAG(MIC_RES_384) #define QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE QUIRK_FLAG(MIXER_PLAYBACK_MIN_MUTE) #define QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE QUIRK_FLAG(MIXER_CAPTURE_MIN_MUTE) +#define QUIRK_FLAG_SKIP_IFACE_SETUP QUIRK_FLAG(SKIP_IFACE_SETUP) #endif /* __USBAUDIO_H */ diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c index 011ea96e9779..f00b53346abd 100644 --- a/sound/usb/usx2y/us122l.c +++ b/sound/usb/usx2y/us122l.c @@ -520,8 +520,6 @@ static int us122l_usb_probe(struct usb_interface *intf, return err; } - usb_get_intf(usb_ifnum_to_if(device, 0)); - usb_get_dev(device); *cardp = card; return 0; } @@ -542,11 +540,9 @@ static int snd_us122l_probe(struct usb_interface *intf, if (intf->cur_altsetting->desc.bInterfaceNumber != 1) return 0; - err = us122l_usb_probe(usb_get_intf(intf), id, &card); - if (err < 0) { - usb_put_intf(intf); + err = us122l_usb_probe(intf, id, &card); + if (err < 0) return err; - } usb_set_intfdata(intf, card); return 0; @@ -574,10 +570,6 @@ static void snd_us122l_disconnect(struct usb_interface *intf) snd_usbmidi_disconnect(p); } - usb_put_intf(usb_ifnum_to_if(us122l->dev, 0)); - usb_put_intf(usb_ifnum_to_if(us122l->dev, 1)); - usb_put_dev(us122l->dev); - snd_card_free_when_closed(card); } diff --git a/sound/usb/usx2y/us144mkii.c b/sound/usb/usx2y/us144mkii.c index bc71968df8e2..0cf4fa74e210 100644 --- a/sound/usb/usx2y/us144mkii.c +++ b/sound/usb/usx2y/us144mkii.c @@ -10,8 +10,8 @@ MODULE_AUTHOR("Šerif Rami "); MODULE_DESCRIPTION("ALSA Driver for TASCAM US-144MKII"); MODULE_LICENSE("GPL"); -/** - * @brief Module parameters for ALSA card instantiation. +/* + * Module parameters for ALSA card instantiation. * * These parameters allow users to configure how the ALSA sound card * for the TASCAM US-144MKII is instantiated. @@ -269,7 +269,7 @@ void tascam_stop_work_handler(struct work_struct *work) atomic_set(&tascam->active_urbs, 0); } -/** +/* * tascam_card_private_free() - Frees private data associated with the sound * card. * @card: Pointer to the ALSA sound card instance. @@ -291,7 +291,7 @@ static void tascam_card_private_free(struct snd_card *card) } } -/** +/* * tascam_suspend() - Handles device suspension. * @intf: The USB interface being suspended. * @message: Power management message. @@ -332,7 +332,7 @@ static int tascam_suspend(struct usb_interface *intf, pm_message_t message) return 0; } -/** +/* * tascam_resume() - Handles device resumption from suspend. * @intf: The USB interface being resumed. * @@ -390,7 +390,7 @@ static void tascam_error_timer(struct timer_list *t) schedule_work(&tascam->midi_out_work); } -/** +/* * tascam_probe() - Probes for the TASCAM US-144MKII device. * @intf: The USB interface being probed. * @usb_id: The USB device ID. @@ -565,7 +565,7 @@ static int tascam_probe(struct usb_interface *intf, return err; } -/** +/* * tascam_disconnect() - Disconnects the TASCAM US-144MKII device. * @intf: The USB interface being disconnected. * diff --git a/sound/usb/usx2y/us144mkii_capture.c b/sound/usb/usx2y/us144mkii_capture.c index 00188ff6cd51..af120bf62173 100644 --- a/sound/usb/usx2y/us144mkii_capture.c +++ b/sound/usb/usx2y/us144mkii_capture.c @@ -3,7 +3,7 @@ #include "us144mkii.h" -/** +/* * tascam_capture_open() - Opens the PCM capture substream. * @substream: The ALSA PCM substream to open. * @@ -23,7 +23,7 @@ static int tascam_capture_open(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_capture_close() - Closes the PCM capture substream. * @substream: The ALSA PCM substream to close. * @@ -41,7 +41,7 @@ static int tascam_capture_close(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_capture_prepare() - Prepares the PCM capture substream for use. * @substream: The ALSA PCM substream to prepare. * @@ -62,7 +62,7 @@ static int tascam_capture_prepare(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_capture_pointer() - Returns the current capture pointer position. * @substream: The ALSA PCM substream. * @@ -91,7 +91,7 @@ tascam_capture_pointer(struct snd_pcm_substream *substream) return do_div(pos, runtime->buffer_size); } -/** +/* * tascam_capture_ops - ALSA PCM operations for capture. * * This structure defines the callback functions for capture stream operations, @@ -109,7 +109,7 @@ const struct snd_pcm_ops tascam_capture_ops = { .pointer = tascam_capture_pointer, }; -/** +/* * decode_tascam_capture_block() - Decodes a raw 512-byte block from the device. * @src_block: Pointer to the 512-byte raw source block. * @dst_block: Pointer to the destination buffer for decoded audio frames. diff --git a/sound/usb/usx2y/us144mkii_controls.c b/sound/usb/usx2y/us144mkii_controls.c index 62055fb8e7ba..81ded11e3709 100644 --- a/sound/usb/usx2y/us144mkii_controls.c +++ b/sound/usb/usx2y/us144mkii_controls.c @@ -3,8 +3,8 @@ #include "us144mkii.h" -/** - * @brief Text descriptions for playback output source options. +/* + * Text descriptions for playback output source options. * * Used by ALSA kcontrol elements to provide user-friendly names for * the playback routing options (e.g., "Playback 1-2", "Playback 3-4"). @@ -12,15 +12,15 @@ static const char *const playback_source_texts[] = { "Playback 1-2", "Playback 3-4" }; -/** - * @brief Text descriptions for capture input source options. +/* + * Text descriptions for capture input source options. * * Used by ALSA kcontrol elements to provide user-friendly names for * the capture routing options (e.g., "Analog In", "Digital In"). */ static const char *const capture_source_texts[] = { "Analog In", "Digital In" }; -/** +/* * tascam_playback_source_info() - ALSA control info callback for playback * source. * @kcontrol: The ALSA kcontrol instance. @@ -38,7 +38,7 @@ static int tascam_playback_source_info(struct snd_kcontrol *kcontrol, return snd_ctl_enum_info(uinfo, 1, 2, playback_source_texts); } -/** +/* * tascam_line_out_get() - ALSA control get callback for Line Outputs Source. * @kcontrol: The ALSA kcontrol instance. * @ucontrol: The ALSA control element value structure to fill. @@ -60,7 +60,7 @@ static int tascam_line_out_get(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_line_out_put() - ALSA control put callback for Line Outputs Source. * @kcontrol: The ALSA kcontrol instance. * @ucontrol: The ALSA control element value structure containing the new value. @@ -89,7 +89,7 @@ static int tascam_line_out_put(struct snd_kcontrol *kcontrol, return changed; } -/** +/* * tascam_line_out_control - ALSA kcontrol definition for Line Outputs Source. * * This defines a new ALSA mixer control named "Line OUTPUTS Source" that allows @@ -106,7 +106,7 @@ static const struct snd_kcontrol_new tascam_line_out_control = { .put = tascam_line_out_put, }; -/** +/* * tascam_digital_out_get() - ALSA control get callback for Digital Outputs * Source. * @kcontrol: The ALSA kcontrol instance. @@ -129,7 +129,7 @@ static int tascam_digital_out_get(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_digital_out_put() - ALSA control put callback for Digital Outputs * Source. * @kcontrol: The ALSA kcontrol instance. @@ -159,7 +159,7 @@ static int tascam_digital_out_put(struct snd_kcontrol *kcontrol, return changed; } -/** +/* * tascam_digital_out_control - ALSA kcontrol definition for Digital Outputs * Source. * @@ -177,7 +177,7 @@ static const struct snd_kcontrol_new tascam_digital_out_control = { .put = tascam_digital_out_put, }; -/** +/* * tascam_capture_source_info() - ALSA control info callback for capture source. * @kcontrol: The ALSA kcontrol instance. * @uinfo: The ALSA control element info structure to fill. @@ -194,7 +194,7 @@ static int tascam_capture_source_info(struct snd_kcontrol *kcontrol, return snd_ctl_enum_info(uinfo, 1, 2, capture_source_texts); } -/** +/* * tascam_capture_12_get() - ALSA control get callback for Capture channels 1 * and 2 Source. * @kcontrol: The ALSA kcontrol instance. @@ -217,7 +217,7 @@ static int tascam_capture_12_get(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_capture_12_put() - ALSA control put callback for Capture channels 1 * and 2 Source. * @kcontrol: The ALSA kcontrol instance. @@ -247,7 +247,7 @@ static int tascam_capture_12_put(struct snd_kcontrol *kcontrol, return changed; } -/** +/* * tascam_capture_12_control - ALSA kcontrol definition for Capture channels 1 * and 2 Source. * @@ -265,7 +265,7 @@ static const struct snd_kcontrol_new tascam_capture_12_control = { .put = tascam_capture_12_put, }; -/** +/* * tascam_capture_34_get() - ALSA control get callback for Capture channels 3 * and 4 Source. * @kcontrol: The ALSA kcontrol instance. @@ -288,7 +288,7 @@ static int tascam_capture_34_get(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_capture_34_put() - ALSA control put callback for Capture channels 3 * and 4 Source. * @kcontrol: The ALSA kcontrol instance. @@ -318,7 +318,7 @@ static int tascam_capture_34_put(struct snd_kcontrol *kcontrol, return changed; } -/** +/* * tascam_capture_34_control - ALSA kcontrol definition for Capture channels 3 * and 4 Source. * @@ -336,7 +336,7 @@ static const struct snd_kcontrol_new tascam_capture_34_control = { .put = tascam_capture_34_put, }; -/** +/* * tascam_samplerate_info() - ALSA control info callback for Sample Rate. * @kcontrol: The ALSA kcontrol instance. * @uinfo: The ALSA control element info structure to fill. @@ -356,7 +356,7 @@ static int tascam_samplerate_info(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_samplerate_get() - ALSA control get callback for Sample Rate. * @kcontrol: The ALSA kcontrol instance. * @ucontrol: The ALSA control element value structure to fill. @@ -400,7 +400,7 @@ static int tascam_samplerate_get(struct snd_kcontrol *kcontrol, return 0; } -/** +/* * tascam_samplerate_control - ALSA kcontrol definition for Sample Rate. * * This defines a new ALSA mixer control named "Sample Rate" that displays diff --git a/sound/usb/usx2y/us144mkii_midi.c b/sound/usb/usx2y/us144mkii_midi.c index ed2afec2a89a..4871797b1670 100644 --- a/sound/usb/usx2y/us144mkii_midi.c +++ b/sound/usb/usx2y/us144mkii_midi.c @@ -3,7 +3,7 @@ #include "us144mkii.h" -/** +/* * tascam_midi_in_work_handler() - Deferred work for processing MIDI input. * @work: The work_struct instance. * @@ -75,7 +75,7 @@ void tascam_midi_in_urb_complete(struct urb *urb) usb_put_urb(urb); } -/** +/* * tascam_midi_in_open() - Opens the MIDI input substream. * @substream: The ALSA rawmidi substream to open. * @@ -92,7 +92,7 @@ static int tascam_midi_in_open(struct snd_rawmidi_substream *substream) return 0; } -/** +/* * tascam_midi_in_close() - Closes the MIDI input substream. * @substream: The ALSA rawmidi substream to close. * @@ -103,7 +103,7 @@ static int tascam_midi_in_close(struct snd_rawmidi_substream *substream) return 0; } -/** +/* * tascam_midi_in_trigger() - Triggers MIDI input stream activity. * @substream: The ALSA rawmidi substream. * @up: Boolean indicating whether to start (1) or stop (0) the stream. @@ -150,7 +150,7 @@ static void tascam_midi_in_trigger(struct snd_rawmidi_substream *substream, } } -/** +/* * tascam_midi_in_ops - ALSA rawmidi operations for MIDI input. * * This structure defines the callback functions for MIDI input stream @@ -205,7 +205,7 @@ void tascam_midi_out_urb_complete(struct urb *urb) usb_put_urb(urb); } -/** +/* * tascam_midi_out_work_handler() - Deferred work for sending MIDI data * @work: The work_struct instance. * @@ -282,7 +282,7 @@ static void tascam_midi_out_work_handler(struct work_struct *work) } } -/** +/* * tascam_midi_out_open() - Opens the MIDI output substream. * @substream: The ALSA rawmidi substream to open. * @@ -301,7 +301,7 @@ static int tascam_midi_out_open(struct snd_rawmidi_substream *substream) return 0; } -/** +/* * tascam_midi_out_close() - Closes the MIDI output substream. * @substream: The ALSA rawmidi substream to close. * @@ -312,7 +312,7 @@ static int tascam_midi_out_close(struct snd_rawmidi_substream *substream) return 0; } -/** +/* * tascam_midi_out_drain() - Drains the MIDI output stream. * @substream: The ALSA rawmidi substream. * @@ -340,7 +340,7 @@ static void tascam_midi_out_drain(struct snd_rawmidi_substream *substream) usb_kill_anchored_urbs(&tascam->midi_out_anchor); } -/** +/* * tascam_midi_out_trigger() - Triggers MIDI output stream activity. * @substream: The ALSA rawmidi substream. * @up: Boolean indicating whether to start (1) or stop (0) the stream. @@ -361,7 +361,7 @@ static void tascam_midi_out_trigger(struct snd_rawmidi_substream *substream, } } -/** +/* * tascam_midi_out_ops - ALSA rawmidi operations for MIDI output. * * This structure defines the callback functions for MIDI output stream diff --git a/sound/usb/usx2y/us144mkii_playback.c b/sound/usb/usx2y/us144mkii_playback.c index 0cb9699ec211..7efaca0a6489 100644 --- a/sound/usb/usx2y/us144mkii_playback.c +++ b/sound/usb/usx2y/us144mkii_playback.c @@ -3,7 +3,7 @@ #include "us144mkii.h" -/** +/* * tascam_playback_open() - Opens the PCM playback substream. * @substream: The ALSA PCM substream to open. * @@ -23,7 +23,7 @@ static int tascam_playback_open(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_playback_close() - Closes the PCM playback substream. * @substream: The ALSA PCM substream to close. * @@ -41,7 +41,7 @@ static int tascam_playback_close(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_playback_prepare() - Prepares the PCM playback substream for use. * @substream: The ALSA PCM substream to prepare. * @@ -108,7 +108,7 @@ static int tascam_playback_prepare(struct snd_pcm_substream *substream) return 0; } -/** +/* * tascam_playback_pointer() - Returns the current playback pointer position. * @substream: The ALSA PCM substream. * @@ -137,7 +137,7 @@ tascam_playback_pointer(struct snd_pcm_substream *substream) return do_div(pos, runtime->buffer_size); } -/** +/* * tascam_playback_ops - ALSA PCM operations for playback. * * This structure defines the callback functions for playback stream operations, diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c index c7c7ec9c228b..3808df54727d 100644 --- a/sound/usb/usx2y/usbusx2yaudio.c +++ b/sound/usb/usx2y/usbusx2yaudio.c @@ -657,15 +657,13 @@ static int usx2y_rate_set(struct usx2ydev *usx2y, int rate) struct urb *urb; if (usx2y->rate != rate) { - us = kzalloc(struct_size(us, urb, NOOF_SETRATE_URBS), - GFP_KERNEL); + us = kzalloc_flex(*us, urb, NOOF_SETRATE_URBS); if (!us) { err = -ENOMEM; goto cleanup; } us->len = NOOF_SETRATE_URBS; - usbdata = kmalloc_array(NOOF_SETRATE_URBS, sizeof(int), - GFP_KERNEL); + usbdata = kmalloc_objs(int, NOOF_SETRATE_URBS); if (!usbdata) { err = -ENOMEM; goto cleanup; @@ -944,7 +942,7 @@ static int usx2y_audio_stream_new(struct snd_card *card, int playback_endpoint, for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { - usx2y_substream[i] = kzalloc(sizeof(struct snd_usx2y_substream), GFP_KERNEL); + usx2y_substream[i] = kzalloc_obj(struct snd_usx2y_substream); if (!usx2y_substream[i]) return -ENOMEM; diff --git a/sound/usb/validate.c b/sound/usb/validate.c index 4bb4893f6e74..f62b7cc041dc 100644 --- a/sound/usb/validate.c +++ b/sound/usb/validate.c @@ -281,7 +281,7 @@ static const struct usb_desc_validator audio_validators[] = { /* UAC_VERSION_2, UAC2_SAMPLE_RATE_CONVERTER: not implemented yet */ /* UAC3 */ - FIXED(UAC_VERSION_2, UAC_HEADER, struct uac3_ac_header_descriptor), + FIXED(UAC_VERSION_3, UAC_HEADER, struct uac3_ac_header_descriptor), FIXED(UAC_VERSION_3, UAC_INPUT_TERMINAL, struct uac3_input_terminal_descriptor), FIXED(UAC_VERSION_3, UAC_OUTPUT_TERMINAL, diff --git a/sound/virtio/virtio_card.c b/sound/virtio/virtio_card.c index 52c5757585c6..647190f4d5af 100644 --- a/sound/virtio/virtio_card.c +++ b/sound/virtio/virtio_card.c @@ -137,8 +137,7 @@ static int virtsnd_find_vqs(struct virtio_snd *snd) n = virtqueue_get_vring_size(vqs[VIRTIO_SND_VQ_EVENT]); - snd->event_msgs = kmalloc_array(n, sizeof(*snd->event_msgs), - GFP_KERNEL); + snd->event_msgs = kmalloc_objs(*snd->event_msgs, n); if (!snd->event_msgs) return -ENOMEM; diff --git a/sound/virtio/virtio_jack.c b/sound/virtio/virtio_jack.c index c69f1dcdcc84..68e40c7f5039 100644 --- a/sound/virtio/virtio_jack.c +++ b/sound/virtio/virtio_jack.c @@ -144,7 +144,7 @@ int virtsnd_jack_parse_cfg(struct virtio_snd *snd) if (!snd->jacks) return -ENOMEM; - info = kcalloc(snd->njacks, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, snd->njacks); if (!info) return -ENOMEM; diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c index 3602b6690fcd..eb9cc8131905 100644 --- a/sound/virtio/virtio_pcm.c +++ b/sound/virtio/virtio_pcm.c @@ -354,7 +354,7 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd) spin_lock_init(&vss->lock); } - info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL); + info = kzalloc_objs(*info, snd->nsubstreams); if (!info) return -ENOMEM; diff --git a/sound/virtio/virtio_pcm_msg.c b/sound/virtio/virtio_pcm_msg.c index 9778020a7ba8..a5c4e7027717 100644 --- a/sound/virtio/virtio_pcm_msg.c +++ b/sound/virtio/virtio_pcm_msg.c @@ -135,7 +135,7 @@ int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss, struct snd_pcm_runtime *runtime = vss->substream->runtime; unsigned int i; - vss->msgs = kcalloc(periods, sizeof(*vss->msgs), GFP_KERNEL); + vss->msgs = kzalloc_objs(*vss->msgs, periods); if (!vss->msgs) return -ENOMEM; @@ -146,7 +146,7 @@ int virtsnd_pcm_msg_alloc(struct virtio_pcm_substream *vss, int sg_num = virtsnd_pcm_sg_num(data, period_bytes); struct virtio_pcm_msg *msg; - msg = kzalloc(struct_size(msg, sgs, sg_num + 2), GFP_KERNEL); + msg = kzalloc_flex(*msg, sgs, sg_num + 2); if (!msg) return -ENOMEM; diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index f5807fc73c54..91dfcf47e979 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -475,7 +475,7 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; - chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); + chmap = kzalloc_obj(*chmap); if (!chmap) return; diff --git a/sound/xen/xen_snd_front_alsa.c b/sound/xen/xen_snd_front_alsa.c index b229eb6f7057..dc626480123a 100644 --- a/sound/xen/xen_snd_front_alsa.c +++ b/sound/xen/xen_snd_front_alsa.c @@ -442,8 +442,7 @@ static int shbuf_setup_backstore(struct xen_snd_front_pcm_stream_info *stream, stream->buffer_sz = buffer_sz; stream->num_pages = DIV_ROUND_UP(stream->buffer_sz, PAGE_SIZE); - stream->pages = kcalloc(stream->num_pages, sizeof(struct page *), - GFP_KERNEL); + stream->pages = kzalloc_objs(struct page *, stream->num_pages); if (!stream->pages) return -ENOMEM; diff --git a/sound/xen/xen_snd_front_evtchnl.c b/sound/xen/xen_snd_front_evtchnl.c index 2fbed8e4a490..bc03f71bf16e 100644 --- a/sound/xen/xen_snd_front_evtchnl.c +++ b/sound/xen/xen_snd_front_evtchnl.c @@ -267,9 +267,8 @@ int xen_snd_front_evtchnl_create_all(struct xen_snd_front_info *front_info, int d, ret = 0; front_info->evt_pairs = - kcalloc(num_streams, - sizeof(struct xen_snd_front_evtchnl_pair), - GFP_KERNEL); + kzalloc_objs(struct xen_snd_front_evtchnl_pair, + num_streams); if (!front_info->evt_pairs) return -ENOMEM; diff --git a/tools/accounting/getdelays.c b/tools/accounting/getdelays.c index 64796c0223be..50792df27707 100644 --- a/tools/accounting/getdelays.c +++ b/tools/accounting/getdelays.c @@ -196,20 +196,20 @@ static int get_family_id(int sd) #define delay_ms(t) (t / 1000000ULL) /* - * Format timespec64 to human readable string (YYYY-MM-DD HH:MM:SS) + * Format __kernel_timespec to human readable string (YYYY-MM-DD HH:MM:SS) * Returns formatted string or "N/A" if timestamp is zero */ -static const char *format_timespec64(struct timespec64 *ts) +static const char *format_timespec(struct __kernel_timespec *ts) { static char buffer[32]; struct tm tm_info; - time_t time_sec; + __kernel_time_t time_sec; /* Check if timestamp is zero (not set) */ if (ts->tv_sec == 0 && ts->tv_nsec == 0) return "N/A"; - time_sec = (time_t)ts->tv_sec; + time_sec = ts->tv_sec; /* Use thread-safe localtime_r */ if (localtime_r(&time_sec, &tm_info) == NULL) @@ -257,7 +257,7 @@ static const char *format_timespec64(struct timespec64 *ts) average_ms((double)(t)->cpu_delay_total, (t)->cpu_count), \ delay_ms((double)(t)->cpu_delay_max), \ delay_ms((double)(t)->cpu_delay_min), \ - format_timespec64(&(t)->cpu_delay_max_ts)); \ + format_timespec(&(t)->cpu_delay_max_ts)); \ } else if (version >= 16) { \ printf("%-10s%15s%15s%15s%15s%15s%15s%15s\n", \ "CPU", "count", "real total", "virtual total", \ @@ -316,7 +316,7 @@ static const char *format_timespec64(struct timespec64 *ts) average_ms((double)(t)->total, (t)->count), \ delay_ms((double)(t)->max), \ delay_ms((double)(t)->min), \ - format_timespec64(&(t)->max_ts)); \ + format_timespec(&(t)->max_ts)); \ } else if (version >= 16) { \ printf("%-10s%15s%15s%15s%15s%15s\n", \ name, "count", "delay total", "delay average", \ diff --git a/tools/arch/arm64/include/uapi/asm/unistd.h b/tools/arch/arm64/include/uapi/asm/unistd.h index df36f23876e8..9306726337fe 100644 --- a/tools/arch/arm64/include/uapi/asm/unistd.h +++ b/tools/arch/arm64/include/uapi/asm/unistd.h @@ -1,2 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -#include +/* + * Copyright (C) 2012 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#define __ARCH_WANT_RENAMEAT +#define __ARCH_WANT_NEW_STAT +#define __ARCH_WANT_SET_GET_RLIMIT +#define __ARCH_WANT_TIME32_SYSCALLS +#define __ARCH_WANT_MEMFD_SECRET + +#include diff --git a/tools/arch/x86/include/asm/amd/ibs.h b/tools/arch/x86/include/asm/amd/ibs.h index cbce54fec7b9..41e8abd72c8b 100644 --- a/tools/arch/x86/include/asm/amd/ibs.h +++ b/tools/arch/x86/include/asm/amd/ibs.h @@ -110,7 +110,7 @@ union ibs_op_data3 { __u64 ld_op:1, /* 0: load op */ st_op:1, /* 1: store op */ dc_l1tlb_miss:1, /* 2: data cache L1TLB miss */ - dc_l2tlb_miss:1, /* 3: data cache L2TLB hit in 2M page */ + dc_l2tlb_miss:1, /* 3: data cache L2TLB miss in 2M page */ dc_l1tlb_hit_2m:1, /* 4: data cache L1TLB hit in 2M page */ dc_l1tlb_hit_1g:1, /* 5: data cache L1TLB hit in 1G page */ dc_l2tlb_hit_2m:1, /* 6: data cache L2TLB hit in 2M page */ diff --git a/tools/arch/x86/include/asm/cpufeatures.h b/tools/arch/x86/include/asm/cpufeatures.h index c3b53beb1300..dbe104df339b 100644 --- a/tools/arch/x86/include/asm/cpufeatures.h +++ b/tools/arch/x86/include/asm/cpufeatures.h @@ -84,7 +84,7 @@ #define X86_FEATURE_PEBS ( 3*32+12) /* "pebs" Precise-Event Based Sampling */ #define X86_FEATURE_BTS ( 3*32+13) /* "bts" Branch Trace Store */ #define X86_FEATURE_SYSCALL32 ( 3*32+14) /* syscall in IA32 userspace */ -#define X86_FEATURE_SYSENTER32 ( 3*32+15) /* sysenter in IA32 userspace */ +#define X86_FEATURE_SYSFAST32 ( 3*32+15) /* sysenter/syscall in IA32 userspace */ #define X86_FEATURE_REP_GOOD ( 3*32+16) /* "rep_good" REP microcode works well */ #define X86_FEATURE_AMD_LBR_V2 ( 3*32+17) /* "amd_lbr_v2" AMD Last Branch Record Extension Version 2 */ #define X86_FEATURE_CLEAR_CPU_BUF ( 3*32+18) /* Clear CPU buffers using VERW */ @@ -326,6 +326,7 @@ #define X86_FEATURE_AMX_FP16 (12*32+21) /* AMX fp16 Support */ #define X86_FEATURE_AVX_IFMA (12*32+23) /* Support for VPMADD52[H,L]UQ */ #define X86_FEATURE_LAM (12*32+26) /* "lam" Linear Address Masking */ +#define X86_FEATURE_MOVRS (12*32+31) /* MOVRS instructions */ /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */ #define X86_FEATURE_CLZERO (13*32+ 0) /* "clzero" CLZERO instruction */ @@ -472,6 +473,7 @@ #define X86_FEATURE_GP_ON_USER_CPUID (20*32+17) /* User CPUID faulting */ #define X86_FEATURE_PREFETCHI (20*32+20) /* Prefetch Data/Instruction to Cache Level */ +#define X86_FEATURE_ERAPS (20*32+24) /* Enhanced Return Address Predictor Security */ #define X86_FEATURE_SBPB (20*32+27) /* Selective Branch Prediction Barrier */ #define X86_FEATURE_IBPB_BRTYPE (20*32+28) /* MSR_PRED_CMD[IBPB] flushes all branch type predictions */ #define X86_FEATURE_SRSO_NO (20*32+29) /* CPU is not affected by SRSO */ diff --git a/tools/arch/x86/include/asm/msr-index.h b/tools/arch/x86/include/asm/msr-index.h index 43adc38d31d5..da5275d8eda6 100644 --- a/tools/arch/x86/include/asm/msr-index.h +++ b/tools/arch/x86/include/asm/msr-index.h @@ -263,6 +263,11 @@ #define MSR_SNOOP_RSP_0 0x00001328 #define MSR_SNOOP_RSP_1 0x00001329 +#define MSR_OMR_0 0x000003e0 +#define MSR_OMR_1 0x000003e1 +#define MSR_OMR_2 0x000003e2 +#define MSR_OMR_3 0x000003e3 + #define MSR_LBR_SELECT 0x000001c8 #define MSR_LBR_TOS 0x000001c9 @@ -1219,6 +1224,7 @@ #define MSR_CORE_PERF_GLOBAL_STATUS 0x0000038e #define MSR_CORE_PERF_GLOBAL_CTRL 0x0000038f #define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x00000390 +#define MSR_CORE_PERF_GLOBAL_STATUS_SET 0x00000391 #define MSR_PERF_METRICS 0x00000329 diff --git a/tools/arch/x86/include/uapi/asm/kvm.h b/tools/arch/x86/include/uapi/asm/kvm.h index 7ceff6583652..846a63215ce1 100644 --- a/tools/arch/x86/include/uapi/asm/kvm.h +++ b/tools/arch/x86/include/uapi/asm/kvm.h @@ -503,6 +503,7 @@ struct kvm_sync_regs { #define KVM_X86_GRP_SEV 1 # define KVM_X86_SEV_VMSA_FEATURES 0 # define KVM_X86_SNP_POLICY_BITS 1 +# define KVM_X86_SEV_SNP_REQ_CERTS 2 struct kvm_vmx_nested_state_data { __u8 vmcs12[KVM_STATE_NESTED_VMX_VMCS_SIZE]; @@ -743,6 +744,7 @@ enum sev_cmd_id { KVM_SEV_SNP_LAUNCH_START = 100, KVM_SEV_SNP_LAUNCH_UPDATE, KVM_SEV_SNP_LAUNCH_FINISH, + KVM_SEV_SNP_ENABLE_REQ_CERTS, KVM_SEV_NR_MAX, }; @@ -914,8 +916,10 @@ struct kvm_sev_snp_launch_finish { __u64 pad1[4]; }; -#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0) -#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1) +#define KVM_X2APIC_API_USE_32BIT_IDS _BITULL(0) +#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK _BITULL(1) +#define KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST _BITULL(2) +#define KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST _BITULL(3) struct kvm_hyperv_eventfd { __u32 conn_id; diff --git a/tools/bootconfig/samples/bad-array-after-comment.bconf b/tools/bootconfig/samples/bad-array-after-comment.bconf new file mode 100644 index 000000000000..fdb6d4e04447 --- /dev/null +++ b/tools/bootconfig/samples/bad-array-after-comment.bconf @@ -0,0 +1,4 @@ +# the first array value must be on the same line as the key +key = # comment + value1, + value2 diff --git a/tools/bootconfig/samples/bad-array-in-next-line.bconf b/tools/bootconfig/samples/bad-array-in-next-line.bconf new file mode 100644 index 000000000000..95a99a3bde8c --- /dev/null +++ b/tools/bootconfig/samples/bad-array-in-next-line.bconf @@ -0,0 +1,4 @@ +# the first array value must be on the same line as the key +key = + value1, + value2 diff --git a/tools/bootconfig/samples/bad-non-closed-brace.bconf b/tools/bootconfig/samples/bad-non-closed-brace.bconf new file mode 100644 index 000000000000..6ed9f3363dde --- /dev/null +++ b/tools/bootconfig/samples/bad-non-closed-brace.bconf @@ -0,0 +1,4 @@ +foo { + bar { + buz + } diff --git a/tools/bootconfig/samples/bad-over-max-brace.bconf b/tools/bootconfig/samples/bad-over-max-brace.bconf new file mode 100644 index 000000000000..74b5dc9e21dc --- /dev/null +++ b/tools/bootconfig/samples/bad-over-max-brace.bconf @@ -0,0 +1,19 @@ +key1 { +key2 { +key3 { +key4 { +key5 { +key6 { +key7 { +key8 { +key9 { +key10 { +key11 { +key12 { +key13 { +key14 { +key15 { +key16 { +key17 { +}}}}}}}}}}}}}}}}} + diff --git a/tools/bootconfig/samples/exp-good-array-space-comment.bconf b/tools/bootconfig/samples/exp-good-array-space-comment.bconf new file mode 100644 index 000000000000..8d3278fa6af5 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-array-space-comment.bconf @@ -0,0 +1 @@ +key = "value1", "value2", "value3"; diff --git a/tools/bootconfig/samples/exp-good-comment-after-value.bconf b/tools/bootconfig/samples/exp-good-comment-after-value.bconf new file mode 100644 index 000000000000..a8e8450db3c0 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-comment-after-value.bconf @@ -0,0 +1 @@ +key = "value"; diff --git a/tools/bootconfig/samples/exp-good-mixed-append.bconf b/tools/bootconfig/samples/exp-good-mixed-append.bconf new file mode 100644 index 000000000000..c2b407901ddd --- /dev/null +++ b/tools/bootconfig/samples/exp-good-mixed-append.bconf @@ -0,0 +1,2 @@ +key = "foo", "bar"; +keyx.subkey = "value"; diff --git a/tools/bootconfig/samples/exp-good-mixed-kv1.bconf b/tools/bootconfig/samples/exp-good-mixed-kv1.bconf new file mode 100644 index 000000000000..8346287d9251 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-mixed-kv1.bconf @@ -0,0 +1,2 @@ +key = "value"; +key.subkey = "another-value"; diff --git a/tools/bootconfig/samples/exp-good-mixed-kv2.bconf b/tools/bootconfig/samples/exp-good-mixed-kv2.bconf new file mode 100644 index 000000000000..40c6232c7cdd --- /dev/null +++ b/tools/bootconfig/samples/exp-good-mixed-kv2.bconf @@ -0,0 +1,2 @@ +key = "another-value"; +key.subkey = "value"; diff --git a/tools/bootconfig/samples/exp-good-mixed-kv3.bconf b/tools/bootconfig/samples/exp-good-mixed-kv3.bconf new file mode 100644 index 000000000000..8368a7bef60a --- /dev/null +++ b/tools/bootconfig/samples/exp-good-mixed-kv3.bconf @@ -0,0 +1,5 @@ +key = "value"; +key { + subkey1; + subkey2 = "foo"; +} diff --git a/tools/bootconfig/samples/exp-good-mixed-override.bconf b/tools/bootconfig/samples/exp-good-mixed-override.bconf new file mode 100644 index 000000000000..58757712ca45 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-mixed-override.bconf @@ -0,0 +1,2 @@ +key = "value2"; +key.foo = "bar"; diff --git a/tools/bootconfig/samples/exp-good-nested-brace.bconf b/tools/bootconfig/samples/exp-good-nested-brace.bconf new file mode 100644 index 000000000000..19e0f51b4553 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-nested-brace.bconf @@ -0,0 +1 @@ +key1.key2.key3.key4.key5.key6.key7.key8.key9.key10.key11.key12.key13.key14.key15.key16; diff --git a/tools/bootconfig/samples/exp-good-override.bconf b/tools/bootconfig/samples/exp-good-override.bconf new file mode 100644 index 000000000000..00bbd30e99ae --- /dev/null +++ b/tools/bootconfig/samples/exp-good-override.bconf @@ -0,0 +1,4 @@ +key { + word = "2", "3"; + new.word = "new"; +} diff --git a/tools/bootconfig/samples/exp-good-printables.bconf b/tools/bootconfig/samples/exp-good-printables.bconf new file mode 100644 index 000000000000..5981d304eacb --- /dev/null +++ b/tools/bootconfig/samples/exp-good-printables.bconf @@ -0,0 +1,2 @@ +key = " + !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; diff --git a/tools/bootconfig/samples/exp-good-simple.bconf b/tools/bootconfig/samples/exp-good-simple.bconf new file mode 100644 index 000000000000..d17f39421c86 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-simple.bconf @@ -0,0 +1,8 @@ +key { + word1 = "1"; + word2 = "2"; + word3 = "3"; + word4 = "4"; + word5 = "5"; + word6 = "6"; +} diff --git a/tools/bootconfig/samples/exp-good-single.bconf b/tools/bootconfig/samples/exp-good-single.bconf new file mode 100644 index 000000000000..01196910d7f4 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-single.bconf @@ -0,0 +1,3 @@ +key = "1"; +key2 = "2"; +key3 = "alpha", "beta"; diff --git a/tools/bootconfig/samples/exp-good-space-after-value.bconf b/tools/bootconfig/samples/exp-good-space-after-value.bconf new file mode 100644 index 000000000000..a8e8450db3c0 --- /dev/null +++ b/tools/bootconfig/samples/exp-good-space-after-value.bconf @@ -0,0 +1 @@ +key = "value"; diff --git a/tools/bootconfig/samples/exp-good-tree.bconf b/tools/bootconfig/samples/exp-good-tree.bconf new file mode 100644 index 000000000000..b711d38d86fd --- /dev/null +++ b/tools/bootconfig/samples/exp-good-tree.bconf @@ -0,0 +1,8 @@ +key { + word.tree.value = "0"; + word2.tree.value = "1", "2"; +} +other.tree { + value = "2"; + value2 = "3"; +} diff --git a/tools/bootconfig/samples/good-array-space-comment.bconf b/tools/bootconfig/samples/good-array-space-comment.bconf index 45b938dc0695..416fa2ed4109 100644 --- a/tools/bootconfig/samples/good-array-space-comment.bconf +++ b/tools/bootconfig/samples/good-array-space-comment.bconf @@ -1,4 +1,3 @@ -key = # comment - "value1", # comment1 +key = "value1", # comment1 "value2" , # comment2 "value3" diff --git a/tools/bootconfig/samples/good-nested-brace.bconf b/tools/bootconfig/samples/good-nested-brace.bconf new file mode 100644 index 000000000000..980d094f296e --- /dev/null +++ b/tools/bootconfig/samples/good-nested-brace.bconf @@ -0,0 +1,18 @@ +key1 { +key2 { +key3 { +key4 { +key5 { +key6 { +key7 { +key8 { +key9 { +key10 { +key11 { +key12 { +key13 { +key14 { +key15 { +key16 { +}}}}}}}}}}}}}}}} + diff --git a/tools/bootconfig/test-bootconfig.sh b/tools/bootconfig/test-bootconfig.sh index 7594659af1e1..fc69f815ce4a 100755 --- a/tools/bootconfig/test-bootconfig.sh +++ b/tools/bootconfig/test-bootconfig.sh @@ -171,6 +171,15 @@ $BOOTCONF $INITRD > $OUTFILE xfail grep -q 'val[[:space:]]' $OUTFILE xpass grep -q 'val2[[:space:]]' $OUTFILE +echo "Showing correct line:column of no closing brace" +cat > $TEMPCONF << EOF +foo { +bar { +} +EOF +$BOOTCONF -a $TEMPCONF $INITRD 2> $OUTFILE +xpass grep -q "1:1" $OUTFILE + echo "=== expected failure cases ===" for i in samples/bad-* ; do xfail $BOOTCONF -a $i $INITRD @@ -179,6 +188,9 @@ done echo "=== expected success cases ===" for i in samples/good-* ; do xpass $BOOTCONF -a $i $INITRD + x="samples/exp-"`basename $i` + $BOOTCONF $i > $TEMPCONF + xpass diff $x $TEMPCONF done diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index f25d66c8395e..974189da8a91 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -156,7 +156,7 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, bool multipart = true; struct nlmsgerr *err; struct nlmsghdr *nh; - char buf[4096]; + char buf[8192]; int len, ret; while (multipart) { @@ -201,6 +201,9 @@ static int netlink_recv(int sock, __u32 nl_pid, __u32 seq, return ret; } } + + if (len) + p_err("Invalid message or trailing data in Netlink response: %d bytes left", len); } ret = 0; done: diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile index 1733a6e93a07..7672208f65e4 100644 --- a/tools/bpf/resolve_btfids/Makefile +++ b/tools/bpf/resolve_btfids/Makefile @@ -23,6 +23,7 @@ RM ?= rm HOSTCC ?= gcc HOSTLD ?= ld HOSTAR ?= ar +HOSTPKG_CONFIG ?= pkg-config CROSS_COMPILE = OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/ @@ -63,7 +64,14 @@ $(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(LIBBPF_OU $(abspath $@) install_headers LIBELF_FLAGS := $(shell $(HOSTPKG_CONFIG) libelf --cflags 2>/dev/null) + +ifneq ($(filter -static,$(EXTRA_LDFLAGS)),) +LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs --static 2>/dev/null || echo -lelf -lzstd) +else LIBELF_LIBS := $(shell $(HOSTPKG_CONFIG) libelf --libs 2>/dev/null || echo -lelf) +endif + +ZLIB_LIBS := $(shell $(HOSTPKG_CONFIG) zlib --libs 2>/dev/null || echo -lz) HOSTCFLAGS_resolve_btfids += -g \ -I$(srctree)/tools/include \ @@ -73,7 +81,7 @@ HOSTCFLAGS_resolve_btfids += -g \ $(LIBELF_FLAGS) \ -Wall -Werror -LIBS = $(LIBELF_LIBS) -lz +LIBS = $(LIBELF_LIBS) $(ZLIB_LIBS) export srctree OUTPUT HOSTCFLAGS_resolve_btfids Q HOSTCC HOSTLD HOSTAR include $(srctree)/tools/build/Makefile.include @@ -83,7 +91,7 @@ $(BINARY_IN): fixdep FORCE prepare | $(OUTPUT) $(BINARY): $(BPFOBJ) $(SUBCMDOBJ) $(BINARY_IN) $(call msg,LINK,$@) - $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) + $(Q)$(HOSTCC) $(BINARY_IN) $(KBUILD_HOSTLDFLAGS) $(EXTRA_LDFLAGS) -o $@ $(BPFOBJ) $(SUBCMDOBJ) $(LIBS) clean_objects := $(wildcard $(OUTPUT)/*.o \ $(OUTPUT)/.*.o.cmd \ diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c index ca7fcd03efb6..5208f650080f 100644 --- a/tools/bpf/resolve_btfids/main.c +++ b/tools/bpf/resolve_btfids/main.c @@ -226,7 +226,7 @@ static struct btf_id *btf_id__find(struct rb_root *root, const char *name) } static struct btf_id *__btf_id__add(struct rb_root *root, - char *name, + const char *name, enum btf_id_kind kind, bool unique) { @@ -250,7 +250,11 @@ static struct btf_id *__btf_id__add(struct rb_root *root, id = zalloc(sizeof(*id)); if (id) { pr_debug("adding symbol %s\n", name); - id->name = name; + id->name = strdup(name); + if (!id->name) { + free(id); + return NULL; + } id->kind = kind; rb_link_node(&id->rb_node, parent, p); rb_insert_color(&id->rb_node, root); @@ -258,17 +262,21 @@ static struct btf_id *__btf_id__add(struct rb_root *root, return id; } -static inline struct btf_id *btf_id__add(struct rb_root *root, char *name, enum btf_id_kind kind) +static inline struct btf_id *btf_id__add(struct rb_root *root, + const char *name, + enum btf_id_kind kind) { return __btf_id__add(root, name, kind, false); } -static inline struct btf_id *btf_id__add_unique(struct rb_root *root, char *name, enum btf_id_kind kind) +static inline struct btf_id *btf_id__add_unique(struct rb_root *root, + const char *name, + enum btf_id_kind kind) { return __btf_id__add(root, name, kind, true); } -static char *get_id(const char *prefix_end) +static int get_id(const char *prefix_end, char *buf, size_t buf_sz) { /* * __BTF_ID__func__vfs_truncate__0 @@ -277,28 +285,28 @@ static char *get_id(const char *prefix_end) */ int len = strlen(prefix_end); int pos = sizeof("__") - 1; - char *p, *id; + char *p; if (pos >= len) - return NULL; + return -1; - id = strdup(prefix_end + pos); - if (id) { - /* - * __BTF_ID__func__vfs_truncate__0 - * id = ^ - * - * cut the unique id part - */ - p = strrchr(id, '_'); - p--; - if (*p != '_') { - free(id); - return NULL; - } - *p = '\0'; - } - return id; + if (len - pos >= buf_sz) + return -1; + + strcpy(buf, prefix_end + pos); + /* + * __BTF_ID__func__vfs_truncate__0 + * buf = ^ + * + * cut the unique id part + */ + p = strrchr(buf, '_'); + p--; + if (*p != '_') + return -1; + *p = '\0'; + + return 0; } static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind kind) @@ -335,10 +343,9 @@ static struct btf_id *add_set(struct object *obj, char *name, enum btf_id_kind k static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size) { - char *id; + char id[KSYM_NAME_LEN]; - id = get_id(name + size); - if (!id) { + if (get_id(name + size, id, sizeof(id))) { pr_err("FAILED to parse symbol name: %s\n", name); return NULL; } @@ -346,6 +353,21 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size) return btf_id__add(root, id, BTF_ID_KIND_SYM); } +static void btf_id__free_all(struct rb_root *root) +{ + struct rb_node *next; + struct btf_id *id; + + next = rb_first(root); + while (next) { + id = rb_entry(next, struct btf_id, rb_node); + next = rb_next(&id->rb_node); + rb_erase(&id->rb_node, root); + free(id->name); + free(id); + } +} + static void bswap_32_data(void *data, u32 nr_bytes) { u32 cnt, i; @@ -1547,6 +1569,11 @@ int main(int argc, const char **argv) out: btf__free(obj.base_btf); btf__free(obj.btf); + btf_id__free_all(&obj.structs); + btf_id__free_all(&obj.unions); + btf_id__free_all(&obj.typedefs); + btf_id__free_all(&obj.funcs); + btf_id__free_all(&obj.sets); if (obj.efile.elf) { elf_end(obj.efile.elf); close(obj.efile.fd); diff --git a/tools/build/Build.include b/tools/build/Build.include index e45b2eb0d24a..cd0baa7a168d 100644 --- a/tools/build/Build.include +++ b/tools/build/Build.include @@ -98,6 +98,15 @@ c_flags_2 = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(c_flags_1)) c_flags = $(filter-out $(CFLAGS_REMOVE_$(obj)), $(c_flags_2)) cxx_flags = -Wp,-MD,$(depfile) -Wp,-MT,$@ $(CXXFLAGS) -D"BUILD_STR(s)=\#s" $(CXXFLAGS_$(basetarget).o) $(CXXFLAGS_$(obj)) +### +# Rust flags to be used on rule definition, includes: +# - global $(RUST_FLAGS) +# - per target Rust flags +# - per object Rust flags +rust_flags_1 = $(RUST_FLAGS) $(RUST_FLAGS_$(basetarget).o) $(RUST_FLAGS_$(obj)) +rust_flags_2 = $(filter-out $(RUST_FLAGS_REMOVE_$(basetarget).o), $(rust_flags_1)) +rust_flags = $(filter-out $(RUST_FLAGS_REMOVE_$(obj)), $(rust_flags_2)) + ### ## HOSTCC C flags diff --git a/tools/build/Makefile.build b/tools/build/Makefile.build index 3584ff308607..ad69efdd4e85 100644 --- a/tools/build/Makefile.build +++ b/tools/build/Makefile.build @@ -70,11 +70,21 @@ quiet_cmd_gen = GEN $@ # If there's nothing to link, create empty $@ object. quiet_cmd_ld_multi = LD $@ cmd_ld_multi = $(if $(strip $(obj-y)),\ - $(LD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(AR) rcs $@) + printf "$(objprefix)%s " $(patsubst $(objprefix)%,%,$(filter $(obj-y),$^)) | \ + xargs $(LD) -r -o $@,rm -f $@; $(AR) rcs $@) quiet_cmd_host_ld_multi = HOSTLD $@ cmd_host_ld_multi = $(if $(strip $(obj-y)),\ - $(HOSTLD) -r -o $@ $(filter $(obj-y),$^),rm -f $@; $(HOSTAR) rcs $@) + printf "$(objprefix)%s " $(patsubst $(objprefix)%,%,$(filter $(obj-y),$^)) | \ + xargs $(HOSTLD) -r -o $@,rm -f $@; $(HOSTAR) rcs $@) + +rust_common_cmd = \ + $(RUSTC) $(rust_flags) \ + --crate-type staticlib -L $(objtree)/rust/ \ + --emit=dep-info=$(depfile),link + +quiet_cmd_rustc_a_rs = $(RUSTC) $(quiet_modtag) $@ + cmd_rustc_a_rs = $(rust_common_cmd) -o $@ -g $< $(cmd_objtool) ifneq ($(filter $(obj),$(hostprogs)),) host = host_ @@ -105,6 +115,12 @@ $(OUTPUT)%.s: %.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_s_c) +# it's recommended to build a static rust library, when a foreight (to rust) +# linker is used. +$(OUTPUT)%.a: %.rs FORCE + $(call rule_mkdir) + $(call if_changed_dep,rustc_a_rs) + # bison and flex files are generated in the OUTPUT directory # so it needs a separate rule to depend on them properly $(OUTPUT)%-bison.o: $(OUTPUT)%-bison.c FORCE diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 362cf8f4a0a0..0b7a7c38cb88 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -71,7 +71,7 @@ FEATURE_TESTS_BASIC := \ gettid \ glibc \ libbfd \ - libbfd-buildid \ + libbfd-threadsafe \ libelf \ libelf-getphdrnum \ libelf-gelf_getnote \ @@ -149,7 +149,8 @@ FEATURE_DISPLAY ?= \ bpf \ libaio \ libzstd \ - libopenssl + libopenssl \ + rust # # Declare group members of a feature to display the logical OR of the detection diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 0d5a15654b17..1fbcb3ce74d2 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile @@ -13,7 +13,7 @@ FILES= \ test-gtk2-infobar.bin \ test-hello.bin \ test-libbfd.bin \ - test-libbfd-buildid.bin \ + test-libbfd-threadsafe.bin \ test-disassembler-four-args.bin \ test-disassembler-init-styled.bin \ test-reallocarray.bin \ @@ -73,6 +73,7 @@ FILES= \ test-clang-bpf-co-re.bin \ test-file-handle.bin \ test-libpfm4.bin \ + test-rust.bin \ test-libopenssl.bin FILES := $(addprefix $(OUTPUT),$(FILES)) @@ -268,7 +269,7 @@ $(OUTPUT)test-libpython.bin: $(OUTPUT)test-libbfd.bin: $(BUILD_BFD) -$(OUTPUT)test-libbfd-buildid.bin: +$(OUTPUT)test-libbfd-threadsafe.bin: $(BUILD_BFD) || $(BUILD_BFD) -liberty || $(BUILD_BFD) -liberty -lz $(OUTPUT)test-disassembler-four-args.bin: @@ -388,6 +389,15 @@ $(OUTPUT)test-libopenssl.bin: $(OUTPUT)test-bpftool-skeletons.bin: $(SYSTEM_BPFTOOL) version | grep '^features:.*skeletons' \ > $(@:.bin=.make.output) 2>&1 + +# Testing Rust is special: we don't compile anything, it's enough to check the +# compiler presence. Compiling a test code for this purposes is problematic, +# because Rust will emit a dependency file without any external references, +# meaning that if rustc will be removed the build process will still think it's +# there. +$(OUTPUT)test-rust.bin: + $(RUSTC) --version > /dev/null 2>&1 + ############################### clean: diff --git a/tools/build/feature/test-libbfd-buildid.c b/tools/build/feature/test-libbfd-buildid.c deleted file mode 100644 index 157644b04c05..000000000000 --- a/tools/build/feature/test-libbfd-buildid.c +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include - -int main(void) -{ - bfd *abfd = bfd_openr("Pedro", 0); - return abfd && (!abfd->build_id || abfd->build_id->size > 0x506564726f); -} diff --git a/tools/build/feature/test-libbfd-threadsafe.c b/tools/build/feature/test-libbfd-threadsafe.c new file mode 100644 index 000000000000..fe97f95f6f06 --- /dev/null +++ b/tools/build/feature/test-libbfd-threadsafe.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include + +static bool lock(void *unused) +{ + return true; +} + +static bool unlock(void *unused) +{ + return true; +} + +int main(void) +{ + /* Check for presence of new thread safety API (version 2.42) */ + return !bfd_thread_init(lock, unlock, NULL); +} diff --git a/tools/include/linux/args.h b/tools/include/linux/args.h index 2e8e65d975c7..14b268f2389a 100644 --- a/tools/include/linux/args.h +++ b/tools/include/linux/args.h @@ -22,7 +22,11 @@ #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) /* Concatenate two parameters, but allow them to be expanded beforehand. */ +#ifndef __CONCAT #define __CONCAT(a, b) a ## b +#endif +#ifndef CONCATENATE #define CONCATENATE(a, b) __CONCAT(a, b) +#endif #endif /* _LINUX_ARGS_H */ diff --git a/tools/include/linux/bitfield.h b/tools/include/linux/bitfield.h index 6093fa6db260..ddf81f24956b 100644 --- a/tools/include/linux/bitfield.h +++ b/tools/include/linux/bitfield.h @@ -8,6 +8,7 @@ #define _LINUX_BITFIELD_H #include +#include #include /* diff --git a/tools/include/linux/bitmap.h b/tools/include/linux/bitmap.h index 0d992245c600..250883090a5d 100644 --- a/tools/include/linux/bitmap.h +++ b/tools/include/linux/bitmap.h @@ -24,6 +24,10 @@ void __bitmap_set(unsigned long *map, unsigned int start, int len); void __bitmap_clear(unsigned long *map, unsigned int start, int len); bool __bitmap_intersects(const unsigned long *bitmap1, const unsigned long *bitmap2, unsigned int bits); +bool __bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int nbits); +bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int nbits); #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) & (BITS_PER_LONG - 1))) #define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1))) @@ -81,6 +85,15 @@ static inline void bitmap_or(unsigned long *dst, const unsigned long *src1, __bitmap_or(dst, src1, src2, nbits); } +static __always_inline +bool bitmap_andnot(unsigned long *dst, const unsigned long *src1, + const unsigned long *src2, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + return (*dst = *src1 & ~(*src2) & BITMAP_LAST_WORD_MASK(nbits)) != 0; + return __bitmap_andnot(dst, src1, src2, nbits); +} + static inline unsigned long *bitmap_alloc(unsigned int nbits, gfp_t flags __maybe_unused) { return malloc(bitmap_size(nbits)); @@ -157,6 +170,15 @@ static inline bool bitmap_intersects(const unsigned long *src1, return __bitmap_intersects(src1, src2, nbits); } +static __always_inline +bool bitmap_subset(const unsigned long *src1, const unsigned long *src2, unsigned int nbits) +{ + if (small_const_nbits(nbits)) + return ! ((*src1 & ~(*src2)) & BITMAP_LAST_WORD_MASK(nbits)); + else + return __bitmap_subset(src1, src2, nbits); +} + static inline void bitmap_set(unsigned long *map, unsigned int start, unsigned int nbits) { if (__builtin_constant_p(nbits) && nbits == 1) diff --git a/tools/include/linux/coresight-pmu.h b/tools/include/linux/coresight-pmu.h index 89b0ac0014b0..2e179abe472a 100644 --- a/tools/include/linux/coresight-pmu.h +++ b/tools/include/linux/coresight-pmu.h @@ -21,30 +21,6 @@ */ #define CORESIGHT_LEGACY_CPU_TRACE_ID(cpu) (0x10 + (cpu * 2)) -/* - * Below are the definition of bit offsets for perf option, and works as - * arbitrary values for all ETM versions. - * - * Most of them are orignally from ETMv3.5/PTM's ETMCR config, therefore, - * ETMv3.5/PTM doesn't define ETMCR config bits with prefix "ETM3_" and - * directly use below macros as config bits. - */ -#define ETM_OPT_BRANCH_BROADCAST 8 -#define ETM_OPT_CYCACC 12 -#define ETM_OPT_CTXTID 14 -#define ETM_OPT_CTXTID2 15 -#define ETM_OPT_TS 28 -#define ETM_OPT_RETSTK 29 - -/* ETMv4 CONFIGR programming bits for the ETM OPTs */ -#define ETM4_CFG_BIT_BB 3 -#define ETM4_CFG_BIT_CYCACC 4 -#define ETM4_CFG_BIT_CTXTID 6 -#define ETM4_CFG_BIT_VMID 7 -#define ETM4_CFG_BIT_TS 11 -#define ETM4_CFG_BIT_RETSTK 12 -#define ETM4_CFG_BIT_VMID_OPT 15 - /* * Interpretation of the PERF_RECORD_AUX_OUTPUT_HW_ID payload. * Used to associate a CPU with the CoreSight Trace ID. diff --git a/tools/include/linux/gfp.h b/tools/include/linux/gfp.h index 6a10ff5f5be9..9e957b57b694 100644 --- a/tools/include/linux/gfp.h +++ b/tools/include/linux/gfp.h @@ -5,6 +5,10 @@ #include #include +/* Helper macro to avoid gfp flags if they are the default one */ +#define __default_gfp(a,...) a +#define default_gfp(...) __default_gfp(__VA_ARGS__ __VA_OPT__(,) GFP_KERNEL) + static inline bool gfpflags_allow_blocking(const gfp_t gfp_flags) { return !!(gfp_flags & __GFP_DIRECT_RECLAIM); diff --git a/tools/include/linux/gfp_types.h b/tools/include/linux/gfp_types.h index 3de43b12209e..6c75df30a281 100644 --- a/tools/include/linux/gfp_types.h +++ b/tools/include/linux/gfp_types.h @@ -139,6 +139,8 @@ enum { * %__GFP_ACCOUNT causes the allocation to be accounted to kmemcg. * * %__GFP_NO_OBJ_EXT causes slab allocation to have no object extension. + * mark_obj_codetag_empty() should be called upon freeing for objects allocated + * with this flag to indicate that their NULL tags are expected and normal. */ #define __GFP_RECLAIMABLE ((__force gfp_t)___GFP_RECLAIMABLE) #define __GFP_WRITE ((__force gfp_t)___GFP_WRITE) @@ -309,8 +311,10 @@ enum { * * %GFP_ATOMIC users can not sleep and need the allocation to succeed. A lower * watermark is applied to allow access to "atomic reserves". - * The current implementation doesn't support NMI and few other strict - * non-preemptive contexts (e.g. raw_spin_lock). The same applies to %GFP_NOWAIT. + * The current implementation doesn't support NMI, nor contexts that disable + * preemption under PREEMPT_RT. This includes raw_spin_lock() and plain + * preempt_disable() - see "Memory allocation" in + * Documentation/core-api/real-time/differences.rst for more info. * * %GFP_KERNEL is typical for kernel-internal allocations. The caller requires * %ZONE_NORMAL or a lower zone for direct access but can direct reclaim. @@ -321,6 +325,7 @@ enum { * %GFP_NOWAIT is for kernel allocations that should not stall for direct * reclaim, start physical IO or use any filesystem callback. It is very * likely to fail to allocate memory, even for very small allocations. + * The same restrictions on calling contexts apply as for %GFP_ATOMIC. * * %GFP_NOIO will use direct reclaim to discard clean pages or slab pages * that do not require the starting of any physical IO. diff --git a/tools/include/linux/list.h b/tools/include/linux/list.h index a4dfb6a7cc6a..a692ff7aed5c 100644 --- a/tools/include/linux/list.h +++ b/tools/include/linux/list.h @@ -169,6 +169,16 @@ static inline void list_move_tail(struct list_head *list, list_add_tail(list, head); } +/** + * list_is_first -- tests whether @list is the first entry in list @head + * @list: the entry to test + * @head: the head of the list + */ +static inline int list_is_first(const struct list_head *list, const struct list_head *head) +{ + return list->prev == head; +} + /** * list_is_last - tests whether @list is the last entry in list @head * @list: the entry to test diff --git a/tools/include/linux/mm.h b/tools/include/linux/mm.h index 677c37e4a18c..028f3faf46e7 100644 --- a/tools/include/linux/mm.h +++ b/tools/include/linux/mm.h @@ -4,6 +4,7 @@ #include #include +#include #define PAGE_SHIFT 12 #define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT) diff --git a/tools/include/linux/overflow.h b/tools/include/linux/overflow.h index dcb0c1bf6866..3427d7880326 100644 --- a/tools/include/linux/overflow.h +++ b/tools/include/linux/overflow.h @@ -68,6 +68,25 @@ __builtin_mul_overflow(__a, __b, __d); \ }) +/** + * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX + * @factor1: first factor + * @factor2: second factor + * + * Returns: calculate @factor1 * @factor2, both promoted to size_t, + * with any overflow causing the return value to be SIZE_MAX. The + * lvalue must be size_t to avoid implicit type conversion. + */ +static inline size_t __must_check size_mul(size_t factor1, size_t factor2) +{ + size_t bytes; + + if (check_mul_overflow(factor1, factor2, &bytes)) + return SIZE_MAX; + + return bytes; +} + /** * array_size() - Calculate size of 2-dimensional array. * diff --git a/tools/include/linux/slab.h b/tools/include/linux/slab.h index 94937a699402..6d8e9413d5a4 100644 --- a/tools/include/linux/slab.h +++ b/tools/include/linux/slab.h @@ -202,4 +202,13 @@ static inline unsigned int kmem_cache_sheaf_size(struct slab_sheaf *sheaf) return sheaf->size; } +#define __alloc_objs(KMALLOC, GFP, TYPE, COUNT) \ +({ \ + const size_t __obj_size = size_mul(sizeof(TYPE), COUNT); \ + (TYPE *)KMALLOC(__obj_size, GFP); \ +}) + +#define kzalloc_obj(P, ...) \ + __alloc_objs(kzalloc, default_gfp(__VA_ARGS__), typeof(P), 1) + #endif /* _TOOLS_SLAB_H */ diff --git a/tools/include/uapi/asm-generic/unistd.h b/tools/include/uapi/asm-generic/unistd.h index 942370b3f5d2..a627acc8fb5f 100644 --- a/tools/include/uapi/asm-generic/unistd.h +++ b/tools/include/uapi/asm-generic/unistd.h @@ -860,8 +860,11 @@ __SYSCALL(__NR_file_setattr, sys_file_setattr) #define __NR_listns 470 __SYSCALL(__NR_listns, sys_listns) +#define __NR_rseq_slice_yield 471 +__SYSCALL(__NR_rseq_slice_yield, sys_rseq_slice_yield) + #undef __NR_syscalls -#define __NR_syscalls 471 +#define __NR_syscalls 472 /* * 32 bit systems traditionally used different diff --git a/tools/include/uapi/linux/kvm.h b/tools/include/uapi/linux/kvm.h index dddb781b0507..65500f5db379 100644 --- a/tools/include/uapi/linux/kvm.h +++ b/tools/include/uapi/linux/kvm.h @@ -135,6 +135,12 @@ struct kvm_xen_exit { } u; }; +struct kvm_exit_snp_req_certs { + __u64 gpa; + __u64 npages; + __u64 ret; +}; + #define KVM_S390_GET_SKEYS_NONE 1 #define KVM_S390_SKEYS_MAX 1048576 @@ -180,6 +186,8 @@ struct kvm_xen_exit { #define KVM_EXIT_MEMORY_FAULT 39 #define KVM_EXIT_TDX 40 #define KVM_EXIT_ARM_SEA 41 +#define KVM_EXIT_ARM_LDST64B 42 +#define KVM_EXIT_SNP_REQ_CERTS 43 /* For KVM_EXIT_INTERNAL_ERROR */ /* Emulate instruction failed. */ @@ -402,7 +410,7 @@ struct kvm_run { } eoi; /* KVM_EXIT_HYPERV */ struct kvm_hyperv_exit hyperv; - /* KVM_EXIT_ARM_NISV */ + /* KVM_EXIT_ARM_NISV / KVM_EXIT_ARM_LDST64B */ struct { __u64 esr_iss; __u64 fault_ipa; @@ -482,6 +490,8 @@ struct kvm_run { __u64 gva; __u64 gpa; } arm_sea; + /* KVM_EXIT_SNP_REQ_CERTS */ + struct kvm_exit_snp_req_certs snp_req_certs; /* Fix the size of the union. */ char padding[256]; }; @@ -974,6 +984,7 @@ struct kvm_enable_cap { #define KVM_CAP_GUEST_MEMFD_FLAGS 244 #define KVM_CAP_ARM_SEA_TO_USER 245 #define KVM_CAP_S390_USER_OPEREXEC 246 +#define KVM_CAP_S390_KEYOP 247 struct kvm_irq_routing_irqchip { __u32 irqchip; @@ -1219,6 +1230,16 @@ struct kvm_vfio_spapr_tce { __s32 tablefd; }; +#define KVM_S390_KEYOP_ISKE 0x01 +#define KVM_S390_KEYOP_RRBE 0x02 +#define KVM_S390_KEYOP_SSKE 0x03 +struct kvm_s390_keyop { + __u64 guest_addr; + __u8 key; + __u8 operation; + __u8 pad[6]; +}; + /* * KVM_CREATE_VCPU receives as a parameter the vcpu slot, and returns * a vcpu fd. @@ -1238,6 +1259,7 @@ struct kvm_vfio_spapr_tce { #define KVM_S390_UCAS_MAP _IOW(KVMIO, 0x50, struct kvm_s390_ucas_mapping) #define KVM_S390_UCAS_UNMAP _IOW(KVMIO, 0x51, struct kvm_s390_ucas_mapping) #define KVM_S390_VCPU_FAULT _IOW(KVMIO, 0x52, unsigned long) +#define KVM_S390_KEYOP _IOWR(KVMIO, 0x53, struct kvm_s390_keyop) /* Device model IOC */ #define KVM_CREATE_IRQCHIP _IO(KVMIO, 0x60) diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h index 76e9d0664d0c..fd10aa8d697f 100644 --- a/tools/include/uapi/linux/perf_event.h +++ b/tools/include/uapi/linux/perf_event.h @@ -1396,7 +1396,7 @@ union perf_mem_data_src { #define PERF_MEM_LVLNUM_L4 0x0004 /* L4 */ #define PERF_MEM_LVLNUM_L2_MHB 0x0005 /* L2 Miss Handling Buffer */ #define PERF_MEM_LVLNUM_MSC 0x0006 /* Memory-side Cache */ -#define PERF_MEM_LVLNUM_L0 0x0007 /* L0 */ +#define PERF_MEM_LVLNUM_L0 0x0007 /* L0 */ #define PERF_MEM_LVLNUM_UNC 0x0008 /* Uncached */ #define PERF_MEM_LVLNUM_CXL 0x0009 /* CXL */ #define PERF_MEM_LVLNUM_IO 0x000a /* I/O */ diff --git a/tools/lib/bitmap.c b/tools/lib/bitmap.c index 51255c69754d..aa83d22c45e3 100644 --- a/tools/lib/bitmap.c +++ b/tools/lib/bitmap.c @@ -140,3 +140,32 @@ void __bitmap_clear(unsigned long *map, unsigned int start, int len) *p &= ~mask_to_clear; } } + +bool __bitmap_andnot(unsigned long *dst, const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits) +{ + unsigned int k; + unsigned int lim = bits/BITS_PER_LONG; + unsigned long result = 0; + + for (k = 0; k < lim; k++) + result |= (dst[k] = bitmap1[k] & ~bitmap2[k]); + if (bits % BITS_PER_LONG) + result |= (dst[k] = bitmap1[k] & ~bitmap2[k] & + BITMAP_LAST_WORD_MASK(bits)); + return result != 0; +} + +bool __bitmap_subset(const unsigned long *bitmap1, + const unsigned long *bitmap2, unsigned int bits) +{ + unsigned int k, lim = bits/BITS_PER_LONG; + for (k = 0; k < lim; ++k) + if (bitmap1[k] & ~bitmap2[k]) + return false; + + if (bits % BITS_PER_LONG) + if ((bitmap1[k] & ~bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) + return false; + return true; +} diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h index c145da05a67c..9d160b5b9c0e 100644 --- a/tools/lib/bpf/bpf_helpers.h +++ b/tools/lib/bpf/bpf_helpers.h @@ -315,9 +315,6 @@ enum libbpf_tristate { ___param, sizeof(___param)); \ }) -extern int bpf_stream_vprintk(int stream_id, const char *fmt__str, const void *args, - __u32 len__sz) __weak __ksym; - #define bpf_stream_printk(stream_id, fmt, args...) \ ({ \ static const char ___fmt[] = fmt; \ diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c index b842b83e2480..2fa434f09cce 100644 --- a/tools/lib/bpf/features.c +++ b/tools/lib/bpf/features.c @@ -506,6 +506,68 @@ static int probe_kern_arg_ctx_tag(int token_fd) return probe_fd(prog_fd); } +static int probe_ldimm64_full_range_off(int token_fd) +{ + char log_buf[1024]; + int prog_fd, map_fd; + int ret; + LIBBPF_OPTS(bpf_map_create_opts, map_opts, + .token_fd = token_fd, + .map_flags = token_fd ? BPF_F_TOKEN_FD : 0, + ); + LIBBPF_OPTS(bpf_prog_load_opts, prog_opts, + .token_fd = token_fd, + .prog_flags = token_fd ? BPF_F_TOKEN_FD : 0, + .log_buf = log_buf, + .log_size = sizeof(log_buf), + ); + struct bpf_insn insns[] = { + BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1UL << 30), + BPF_EXIT_INSN(), + }; + int insn_cnt = ARRAY_SIZE(insns); + + map_fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "arr", sizeof(int), 1, 1, &map_opts); + if (map_fd < 0) { + ret = -errno; + pr_warn("Error in %s(): %s. Couldn't create simple array map.\n", + __func__, errstr(ret)); + return ret; + } + insns[0].imm = map_fd; + + log_buf[0] = '\0'; + prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, "global_reloc", "GPL", insns, insn_cnt, &prog_opts); + ret = -errno; + + close(map_fd); + + if (prog_fd >= 0) { + pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n", __func__); + close(prog_fd); + return -EINVAL; + } + + /* + * Feature is allowed if we're not failing with the error message + * "direct value offset of %u is not allowed" removed in + * 12a1fe6e12db ("bpf/verifier: Do not limit maximum direct offset into arena map"). + * We should instead fail with "invalid access to map value pointer". + * Ensure we match with one of the two and we're not failing with a + * different, unexpected message. + */ + if (strstr(log_buf, "direct value offset of")) + return 0; + + if (!strstr(log_buf, "invalid access to map value pointer")) { + pr_warn("Error in %s(): Program unexpectedly failed with message: %s.\n", + __func__, log_buf); + return ret; + } + + return 1; +} + typedef int (*feature_probe_fn)(int /* token_fd */); static struct kern_feature_cache feature_cache; @@ -581,6 +643,9 @@ static struct kern_feature_desc { [FEAT_BTF_QMARK_DATASEC] = { "BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec, }, + [FEAT_LDIMM64_FULL_RANGE_OFF] = { + "full range LDIMM64 support", probe_ldimm64_full_range_off, + }, }; bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id) diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 0c8bf0b5cce4..0be7017800fe 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -3009,9 +3009,6 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map, memcpy(obj->arena_data, data, data_sz); obj->arena_data_sz = data_sz; - /* place globals at the end of the arena */ - obj->arena_data_off = mmap_sz - data_alloc_sz; - /* make bpf_map__init_value() work for ARENA maps */ map->mmaped = obj->arena_data; @@ -4669,7 +4666,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog, reloc_desc->type = RELO_DATA; reloc_desc->insn_idx = insn_idx; reloc_desc->map_idx = obj->arena_map_idx; - reloc_desc->sym_off = sym->st_value + obj->arena_data_off; + reloc_desc->sym_off = sym->st_value; map = &obj->maps[obj->arena_map_idx]; pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n", @@ -6383,6 +6380,10 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog) case RELO_DATA: map = &obj->maps[relo->map_idx]; insn[1].imm = insn[0].imm + relo->sym_off; + + if (relo->map_idx == obj->arena_map_idx) + insn[1].imm += obj->arena_data_off; + if (obj->gen_loader) { insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE; insn[0].imm = relo->map_idx; @@ -7384,6 +7385,14 @@ static int bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_pat bpf_object__sort_relos(obj); } + /* place globals at the end of the arena (if supported) */ + if (obj->arena_map_idx >= 0 && kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) { + struct bpf_map *arena_map = &obj->maps[obj->arena_map_idx]; + + obj->arena_data_off = bpf_map_mmap_sz(arena_map) - + roundup(obj->arena_data_sz, sysconf(_SC_PAGE_SIZE)); + } + /* Before relocating calls pre-process relocations and mark * few ld_imm64 instructions that points to subprogs. * Otherwise bpf_object__reloc_code() later would have to consider diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index fc59b21b51b5..974147e8a8aa 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -392,6 +392,8 @@ enum kern_feature_id { FEAT_ARG_CTX_TAG, /* Kernel supports '?' at the front of datasec names */ FEAT_BTF_QMARK_DATASEC, + /* Kernel supports LDIMM64 imm offsets past 512 MiB. */ + FEAT_LDIMM64_FULL_RANGE_OFF, __FEAT_CNT, }; diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c index f4403e3cf994..78f92c39290a 100644 --- a/tools/lib/bpf/linker.c +++ b/tools/lib/bpf/linker.c @@ -581,7 +581,7 @@ int bpf_linker__add_buf(struct bpf_linker *linker, void *buf, size_t buf_sz, written = 0; while (written < buf_sz) { - ret = write(fd, buf, buf_sz); + ret = write(fd, buf + written, buf_sz - written); if (ret < 0) { ret = -errno; pr_warn("failed to write '%s': %s\n", filename, errstr(ret)); diff --git a/tools/lib/bpf/netlink.c b/tools/lib/bpf/netlink.c index c997e69d507f..c9a78fb16f11 100644 --- a/tools/lib/bpf/netlink.c +++ b/tools/lib/bpf/netlink.c @@ -143,7 +143,7 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, struct nlmsghdr *nh; int len, ret; - ret = alloc_iov(&iov, 4096); + ret = alloc_iov(&iov, 8192); if (ret) goto done; @@ -212,6 +212,8 @@ static int libbpf_netlink_recv(int sock, __u32 nl_pid, int seq, } } } + if (len) + pr_warn("Invalid message or trailing data in Netlink response: %d bytes left\n", len); } ret = 0; done: diff --git a/tools/lib/perf/Documentation/libperf.txt b/tools/lib/perf/Documentation/libperf.txt index 4072bc9b7670..576ecc5fc312 100644 --- a/tools/lib/perf/Documentation/libperf.txt +++ b/tools/lib/perf/Documentation/libperf.txt @@ -211,6 +211,8 @@ SYNOPSIS struct perf_record_header_feature; struct perf_record_compressed; struct perf_record_compressed2; + struct perf_record_schedstat_cpu; + struct perf_record_schedstat_domain; -- DESCRIPTION diff --git a/tools/lib/perf/Makefile b/tools/lib/perf/Makefile index 7fbb50b74c00..32301a1d8f0c 100644 --- a/tools/lib/perf/Makefile +++ b/tools/lib/perf/Makefile @@ -42,7 +42,6 @@ libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) TEST_ARGS := $(if $(V),-v) INCLUDES = \ --I$(OUTPUT)arch/$(SRCARCH)/include/generated/uapi \ -I$(srctree)/tools/lib/perf/include \ -I$(srctree)/tools/lib/ \ -I$(srctree)/tools/include \ @@ -51,9 +50,9 @@ INCLUDES = \ -I$(srctree)/tools/include/uapi # Append required CFLAGS +override CFLAGS := $(INCLUDES) $(CFLAGS) override CFLAGS += -g -Werror -Wall override CFLAGS += -fPIC -override CFLAGS += $(INCLUDES) override CFLAGS += -fvisibility=hidden override CFLAGS += $(EXTRA_WARNINGS) override CFLAGS += $(EXTRA_CFLAGS) @@ -100,16 +99,7 @@ $(LIBAPI)-clean: $(call QUIET_CLEAN, libapi) $(Q)$(MAKE) -C $(LIB_DIR) O=$(OUTPUT) clean >/dev/null -uapi-asm := $(OUTPUT)arch/$(SRCARCH)/include/generated/uapi/asm -ifeq ($(SRCARCH),arm64) - syscall-y := $(uapi-asm)/unistd_64.h -endif -uapi-asm-generic: - $(if $(syscall-y),\ - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-headers obj=$(uapi-asm) \ - generic=include/uapi/asm-generic $(syscall-y),) - -$(LIBPERF_IN): uapi-asm-generic FORCE +$(LIBPERF_IN): FORCE $(Q)$(MAKE) $(build)=libperf $(LIBPERF_A): $(LIBPERF_IN) @@ -130,7 +120,7 @@ all: fixdep clean: $(LIBAPI)-clean $(call QUIET_CLEAN, libperf) $(RM) $(LIBPERF_A) \ *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBPERF_VERSION) .*.d .*.cmd tests/*.o LIBPERF-CFLAGS $(LIBPERF_PC) \ - $(TESTS_STATIC) $(TESTS_SHARED) $(syscall-y) + $(TESTS_STATIC) $(TESTS_SHARED) TESTS_IN = tests-in.o @@ -179,6 +169,7 @@ install_lib: libs cp -fpR $(LIBPERF_ALL) $(DESTDIR)$(libdir_SQ) HDRS := bpf_perf.h core.h cpumap.h threadmap.h evlist.h evsel.h event.h mmap.h +HDRS += schedstat-v15.h schedstat-v16.h schedstat-v17.h INTERNAL_HDRS := cpumap.h evlist.h evsel.h lib.h mmap.h rc_check.h threadmap.h xyarray.h INSTALL_HDRS_PFX := $(DESTDIR)$(prefix)/include/perf diff --git a/tools/lib/perf/evlist.c b/tools/lib/perf/evlist.c index 3ed023f4b190..1f210dadd666 100644 --- a/tools/lib/perf/evlist.c +++ b/tools/lib/perf/evlist.c @@ -101,6 +101,28 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, evsel->cpus = perf_cpu_map__get(evlist->user_requested_cpus); } + /* + * Tool events may only read on the first CPU index to avoid double + * counting things like duration_time. Make the evsel->cpus contain just + * that single entry otherwise we may spend time changing affinity to + * CPUs that just have tool events, etc. + */ + if (evsel->reads_only_on_cpu_idx0 && perf_cpu_map__nr(evsel->cpus) > 0) { + struct perf_cpu_map *srcs[3] = { + evlist->all_cpus, + evlist->user_requested_cpus, + evsel->pmu_cpus, + }; + for (size_t i = 0; i < ARRAY_SIZE(srcs); i++) { + if (!srcs[i]) + continue; + + perf_cpu_map__put(evsel->cpus); + evsel->cpus = perf_cpu_map__new_int(perf_cpu_map__cpu(srcs[i], 0).cpu); + break; + } + } + /* Sanity check assert before the evsel is potentially removed. */ assert(!evsel->requires_cpu || !perf_cpu_map__has_any_cpu(evsel->cpus)); @@ -133,16 +155,22 @@ static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, static void perf_evlist__propagate_maps(struct perf_evlist *evlist) { - struct perf_evsel *evsel, *n; - evlist->needs_map_propagation = true; /* Clear the all_cpus set which will be merged into during propagation. */ perf_cpu_map__put(evlist->all_cpus); evlist->all_cpus = NULL; - list_for_each_entry_safe(evsel, n, &evlist->entries, node) - __perf_evlist__propagate_maps(evlist, evsel); + /* 2 rounds so that reads_only_on_cpu_idx0 benefit from knowing the other CPU maps. */ + for (int round = 0; round < 2; round++) { + struct perf_evsel *evsel, *n; + + list_for_each_entry_safe(evsel, n, &evlist->entries, node) { + if ((!evsel->reads_only_on_cpu_idx0 && round == 0) || + (evsel->reads_only_on_cpu_idx0 && round == 1)) + __perf_evlist__propagate_maps(evlist, evsel); + } + } } void perf_evlist__add(struct perf_evlist *evlist, diff --git a/tools/lib/perf/include/internal/evsel.h b/tools/lib/perf/include/internal/evsel.h index fefe64ba5e26..b988034f1371 100644 --- a/tools/lib/perf/include/internal/evsel.h +++ b/tools/lib/perf/include/internal/evsel.h @@ -128,6 +128,8 @@ struct perf_evsel { bool requires_cpu; /** Is the PMU for the event a core one? Effects the handling of own_cpus. */ bool is_pmu_core; + /** Does the evsel on read on the first CPU index such as tool time events? */ + bool reads_only_on_cpu_idx0; int idx; }; diff --git a/tools/lib/perf/include/perf/event.h b/tools/lib/perf/include/perf/event.h index 43a8cb04994f..9043dc72b5d6 100644 --- a/tools/lib/perf/include/perf/event.h +++ b/tools/lib/perf/include/perf/event.h @@ -496,6 +496,71 @@ struct perf_record_bpf_metadata { struct perf_record_bpf_metadata_entry entries[]; }; +struct perf_record_schedstat_cpu_v15 { +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) _type _name +#include "schedstat-v15.h" +#undef CPU_FIELD +}; + +struct perf_record_schedstat_cpu_v16 { +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) _type _name +#include "schedstat-v16.h" +#undef CPU_FIELD +}; + +struct perf_record_schedstat_cpu_v17 { +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) _type _name +#include "schedstat-v17.h" +#undef CPU_FIELD +}; + +struct perf_record_schedstat_cpu { + struct perf_event_header header; + __u64 timestamp; + __u32 cpu; + __u16 version; + /* Padding */ + char __pad[2]; + union { + struct perf_record_schedstat_cpu_v15 v15; + struct perf_record_schedstat_cpu_v16 v16; + struct perf_record_schedstat_cpu_v17 v17; + }; +}; + +struct perf_record_schedstat_domain_v15 { +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) _type _name +#include "schedstat-v15.h" +#undef DOMAIN_FIELD +}; + +struct perf_record_schedstat_domain_v16 { +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) _type _name +#include "schedstat-v16.h" +#undef DOMAIN_FIELD +}; + +struct perf_record_schedstat_domain_v17 { +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) _type _name +#include "schedstat-v17.h" +#undef DOMAIN_FIELD +}; + +#define DOMAIN_NAME_LEN 16 + +struct perf_record_schedstat_domain { + struct perf_event_header header; + __u64 timestamp; + __u32 cpu; + __u16 version; + __u16 domain; + union { + struct perf_record_schedstat_domain_v15 v15; + struct perf_record_schedstat_domain_v16 v16; + struct perf_record_schedstat_domain_v17 v17; + }; +}; + enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_USER_TYPE_START = 64, PERF_RECORD_HEADER_ATTR = 64, @@ -519,6 +584,8 @@ enum perf_user_event_type { /* above any possible kernel type */ PERF_RECORD_FINISHED_INIT = 82, PERF_RECORD_COMPRESSED2 = 83, PERF_RECORD_BPF_METADATA = 84, + PERF_RECORD_SCHEDSTAT_CPU = 85, + PERF_RECORD_SCHEDSTAT_DOMAIN = 86, PERF_RECORD_HEADER_MAX }; @@ -562,6 +629,8 @@ union perf_event { struct perf_record_compressed pack; struct perf_record_compressed2 pack2; struct perf_record_bpf_metadata bpf_metadata; + struct perf_record_schedstat_cpu schedstat_cpu; + struct perf_record_schedstat_domain schedstat_domain; }; #endif /* __LIBPERF_EVENT_H */ diff --git a/tools/lib/perf/include/perf/schedstat-v15.h b/tools/lib/perf/include/perf/schedstat-v15.h new file mode 100644 index 000000000000..639458df05f8 --- /dev/null +++ b/tools/lib/perf/include/perf/schedstat-v15.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CPU_FIELD +CPU_FIELD(__u32, yld_count, "sched_yield() count", + "%11u", false, yld_count, v15); +CPU_FIELD(__u32, array_exp, "Legacy counter can be ignored", + "%11u", false, array_exp, v15); +CPU_FIELD(__u32, sched_count, "schedule() called", + "%11u", false, sched_count, v15); +CPU_FIELD(__u32, sched_goidle, "schedule() left the processor idle", + "%11u", true, sched_count, v15); +CPU_FIELD(__u32, ttwu_count, "try_to_wake_up() was called", + "%11u", false, ttwu_count, v15); +CPU_FIELD(__u32, ttwu_local, "try_to_wake_up() was called to wake up the local cpu", + "%11u", true, ttwu_count, v15); +CPU_FIELD(__u64, rq_cpu_time, "total runtime by tasks on this processor (in jiffies)", + "%11llu", false, rq_cpu_time, v15); +CPU_FIELD(__u64, run_delay, "total waittime by tasks on this processor (in jiffies)", + "%11llu", true, rq_cpu_time, v15); +CPU_FIELD(__u64, pcount, "total timeslices run on this cpu", + "%11llu", false, pcount, v15); +#endif + +#ifdef DOMAIN_FIELD +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, idle_lb_count, + "load_balance() count on cpu idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, idle_lb_balanced, + "load_balance() found balanced on cpu idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, idle_lb_failed, + "load_balance() move task failed on cpu idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, idle_lb_imbalance, + "imbalance sum on cpu idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, idle_lb_gained, + "pull_task() count on cpu idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, idle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, idle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, idle_lb_nobusyg, + "load_balance() failed to find busier group on cpu idle", "%11u", true, v15); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(idle_lb_success_count, "load_balance() success count on cpu idle", "%11u", + idle_lb_count, idle_lb_balanced, idle_lb_failed, v15); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(idle_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu idle)", "%11.2Lf", + idle_lb_count, idle_lb_balanced, idle_lb_failed, idle_lb_gained, v15); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, busy_lb_count, + "load_balance() count on cpu busy", "%11u", true, v15); +DOMAIN_FIELD(__u32, busy_lb_balanced, + "load_balance() found balanced on cpu busy", "%11u", true, v15); +DOMAIN_FIELD(__u32, busy_lb_failed, + "load_balance() move task failed on cpu busy", "%11u", true, v15); +DOMAIN_FIELD(__u32, busy_lb_imbalance, + "imbalance sum on cpu busy", "%11u", false, v15); +DOMAIN_FIELD(__u32, busy_lb_gained, + "pull_task() count on cpu busy", "%11u", false, v15); +DOMAIN_FIELD(__u32, busy_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu busy", "%11u", false, v15); +DOMAIN_FIELD(__u32, busy_lb_nobusyq, + "load_balance() failed to find busier queue on cpu busy", "%11u", true, v15); +DOMAIN_FIELD(__u32, busy_lb_nobusyg, + "load_balance() failed to find busier group on cpu busy", "%11u", true, v15); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(busy_lb_success_count, "load_balance() success count on cpu busy", "%11u", + busy_lb_count, busy_lb_balanced, busy_lb_failed, v15); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(busy_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu busy)", "%11.2Lf", + busy_lb_count, busy_lb_balanced, busy_lb_failed, busy_lb_gained, v15); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, newidle_lb_count, + "load_balance() count on cpu newly idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, newidle_lb_balanced, + "load_balance() found balanced on cpu newly idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, newidle_lb_failed, + "load_balance() move task failed on cpu newly idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, newidle_lb_imbalance, + "imbalance sum on cpu newly idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, newidle_lb_gained, + "pull_task() count on cpu newly idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, newidle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu newly idle", "%11u", false, v15); +DOMAIN_FIELD(__u32, newidle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu newly idle", "%11u", true, v15); +DOMAIN_FIELD(__u32, newidle_lb_nobusyg, + "load_balance() failed to find busier group on cpu newly idle", "%11u", true, v15); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(newidle_lb_success_count, + "load_balance() success count on cpu newly idle", "%11u", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, v15); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(newidle_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu newly idle)", "%11.2Lf", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, newidle_lb_gained, v15); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, alb_count, + "active_load_balance() count", "%11u", false, v15); +DOMAIN_FIELD(__u32, alb_failed, + "active_load_balance() move task failed", "%11u", false, v15); +DOMAIN_FIELD(__u32, alb_pushed, + "active_load_balance() successfully moved a task", "%11u", false, v15); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbe_count, + "sbe_count is not used", "%11u", false, v15); +DOMAIN_FIELD(__u32, sbe_balanced, + "sbe_balanced is not used", "%11u", false, v15); +DOMAIN_FIELD(__u32, sbe_pushed, + "sbe_pushed is not used", "%11u", false, v15); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbf_count, + "sbf_count is not used", "%11u", false, v15); +DOMAIN_FIELD(__u32, sbf_balanced, + "sbf_balanced is not used", "%11u", false, v15); +DOMAIN_FIELD(__u32, sbf_pushed, + "sbf_pushed is not used", "%11u", false, v15); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, ttwu_wake_remote, + "try_to_wake_up() awoke a task that last ran on a diff cpu", "%11u", false, v15); +DOMAIN_FIELD(__u32, ttwu_move_affine, + "try_to_wake_up() moved task because cache-cold on own cpu", "%11u", false, v15); +DOMAIN_FIELD(__u32, ttwu_move_balance, + "try_to_wake_up() started passive balancing", "%11u", false, v15); +#endif /* DOMAIN_FIELD */ diff --git a/tools/lib/perf/include/perf/schedstat-v16.h b/tools/lib/perf/include/perf/schedstat-v16.h new file mode 100644 index 000000000000..3462b79c29af --- /dev/null +++ b/tools/lib/perf/include/perf/schedstat-v16.h @@ -0,0 +1,146 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CPU_FIELD +CPU_FIELD(__u32, yld_count, "sched_yield() count", + "%11u", false, yld_count, v16); +CPU_FIELD(__u32, array_exp, "Legacy counter can be ignored", + "%11u", false, array_exp, v16); +CPU_FIELD(__u32, sched_count, "schedule() called", + "%11u", false, sched_count, v16); +CPU_FIELD(__u32, sched_goidle, "schedule() left the processor idle", + "%11u", true, sched_count, v16); +CPU_FIELD(__u32, ttwu_count, "try_to_wake_up() was called", + "%11u", false, ttwu_count, v16); +CPU_FIELD(__u32, ttwu_local, "try_to_wake_up() was called to wake up the local cpu", + "%11u", true, ttwu_count, v16); +CPU_FIELD(__u64, rq_cpu_time, "total runtime by tasks on this processor (in jiffies)", + "%11llu", false, rq_cpu_time, v16); +CPU_FIELD(__u64, run_delay, "total waittime by tasks on this processor (in jiffies)", + "%11llu", true, rq_cpu_time, v16); +CPU_FIELD(__u64, pcount, "total timeslices run on this cpu", + "%11llu", false, pcount, v16); +#endif /* CPU_FIELD */ + +#ifdef DOMAIN_FIELD +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, busy_lb_count, + "load_balance() count on cpu busy", "%11u", true, v16); +DOMAIN_FIELD(__u32, busy_lb_balanced, + "load_balance() found balanced on cpu busy", "%11u", true, v16); +DOMAIN_FIELD(__u32, busy_lb_failed, + "load_balance() move task failed on cpu busy", "%11u", true, v16); +DOMAIN_FIELD(__u32, busy_lb_imbalance, + "imbalance sum on cpu busy", "%11u", false, v16); +DOMAIN_FIELD(__u32, busy_lb_gained, + "pull_task() count on cpu busy", "%11u", false, v16); +DOMAIN_FIELD(__u32, busy_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu busy", "%11u", false, v16); +DOMAIN_FIELD(__u32, busy_lb_nobusyq, + "load_balance() failed to find busier queue on cpu busy", "%11u", true, v16); +DOMAIN_FIELD(__u32, busy_lb_nobusyg, + "load_balance() failed to find busier group on cpu busy", "%11u", true, v16); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(busy_lb_success_count, "load_balance() success count on cpu busy", "%11u", + busy_lb_count, busy_lb_balanced, busy_lb_failed, v16); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(busy_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu busy)", "%11.2Lf", + busy_lb_count, busy_lb_balanced, busy_lb_failed, busy_lb_gained, v16); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, idle_lb_count, + "load_balance() count on cpu idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, idle_lb_balanced, + "load_balance() found balanced on cpu idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, idle_lb_failed, + "load_balance() move task failed on cpu idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, idle_lb_imbalance, + "imbalance sum on cpu idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, idle_lb_gained, + "pull_task() count on cpu idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, idle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, idle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, idle_lb_nobusyg, + "load_balance() failed to find busier group on cpu idle", "%11u", true, v16); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(idle_lb_success_count, "load_balance() success count on cpu idle", "%11u", + idle_lb_count, idle_lb_balanced, idle_lb_failed, v16); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(idle_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu idle)", "%11.2Lf", + idle_lb_count, idle_lb_balanced, idle_lb_failed, idle_lb_gained, v16); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, newidle_lb_count, + "load_balance() count on cpu newly idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, newidle_lb_balanced, + "load_balance() found balanced on cpu newly idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, newidle_lb_failed, + "load_balance() move task failed on cpu newly idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, newidle_lb_imbalance, + "imbalance sum on cpu newly idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, newidle_lb_gained, + "pull_task() count on cpu newly idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, newidle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu newly idle", "%11u", false, v16); +DOMAIN_FIELD(__u32, newidle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu newly idle", "%11u", true, v16); +DOMAIN_FIELD(__u32, newidle_lb_nobusyg, + "load_balance() failed to find busier group on cpu newly idle", "%11u", true, v16); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(newidle_lb_success_count, + "load_balance() success count on cpu newly idle", "%11u", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, v16); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(newidle_lb_avg_count, + "avg task pulled per successful lb attempt (cpu newly idle)", "%11.2Lf", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, newidle_lb_gained, v16); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, alb_count, + "active_load_balance() count", "%11u", false, v16); +DOMAIN_FIELD(__u32, alb_failed, + "active_load_balance() move task failed", "%11u", false, v16); +DOMAIN_FIELD(__u32, alb_pushed, + "active_load_balance() successfully moved a task", "%11u", false, v16); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbe_count, + "sbe_count is not used", "%11u", false, v16); +DOMAIN_FIELD(__u32, sbe_balanced, + "sbe_balanced is not used", "%11u", false, v16); +DOMAIN_FIELD(__u32, sbe_pushed, + "sbe_pushed is not used", "%11u", false, v16); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbf_count, + "sbf_count is not used", "%11u", false, v16); +DOMAIN_FIELD(__u32, sbf_balanced, + "sbf_balanced is not used", "%11u", false, v16); +DOMAIN_FIELD(__u32, sbf_pushed, + "sbf_pushed is not used", "%11u", false, v16); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, ttwu_wake_remote, + "try_to_wake_up() awoke a task that last ran on a diff cpu", "%11u", false, v16); +DOMAIN_FIELD(__u32, ttwu_move_affine, + "try_to_wake_up() moved task because cache-cold on own cpu", "%11u", false, v16); +DOMAIN_FIELD(__u32, ttwu_move_balance, + "try_to_wake_up() started passive balancing", "%11u", false, v16); +#endif /* DOMAIN_FIELD */ diff --git a/tools/lib/perf/include/perf/schedstat-v17.h b/tools/lib/perf/include/perf/schedstat-v17.h new file mode 100644 index 000000000000..865dc7c1039c --- /dev/null +++ b/tools/lib/perf/include/perf/schedstat-v17.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifdef CPU_FIELD +CPU_FIELD(__u32, yld_count, "sched_yield() count", + "%11u", false, yld_count, v17); +CPU_FIELD(__u32, array_exp, "Legacy counter can be ignored", + "%11u", false, array_exp, v17); +CPU_FIELD(__u32, sched_count, "schedule() called", + "%11u", false, sched_count, v17); +CPU_FIELD(__u32, sched_goidle, "schedule() left the processor idle", + "%11u", true, sched_count, v17); +CPU_FIELD(__u32, ttwu_count, "try_to_wake_up() was called", + "%11u", false, ttwu_count, v17); +CPU_FIELD(__u32, ttwu_local, "try_to_wake_up() was called to wake up the local cpu", + "%11u", true, ttwu_count, v17); +CPU_FIELD(__u64, rq_cpu_time, "total runtime by tasks on this processor (in jiffies)", + "%11llu", false, rq_cpu_time, v17); +CPU_FIELD(__u64, run_delay, "total waittime by tasks on this processor (in jiffies)", + "%11llu", true, rq_cpu_time, v17); +CPU_FIELD(__u64, pcount, "total timeslices run on this cpu", + "%11llu", false, pcount, v17); +#endif /* CPU_FIELD */ + +#ifdef DOMAIN_FIELD +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, busy_lb_count, + "load_balance() count on cpu busy", "%11u", true, v17); +DOMAIN_FIELD(__u32, busy_lb_balanced, + "load_balance() found balanced on cpu busy", "%11u", true, v17); +DOMAIN_FIELD(__u32, busy_lb_failed, + "load_balance() move task failed on cpu busy", "%11u", true, v17); +DOMAIN_FIELD(__u32, busy_lb_imbalance_load, + "imbalance in load on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_imbalance_util, + "imbalance in utilization on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_imbalance_task, + "imbalance in number of tasks on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_imbalance_misfit, + "imbalance in misfit tasks on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_gained, + "pull_task() count on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu busy", "%11u", false, v17); +DOMAIN_FIELD(__u32, busy_lb_nobusyq, + "load_balance() failed to find busier queue on cpu busy", "%11u", true, v17); +DOMAIN_FIELD(__u32, busy_lb_nobusyg, + "load_balance() failed to find busier group on cpu busy", "%11u", true, v17); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(busy_lb_success_count, "load_balance() success count on cpu busy", "%11u", + busy_lb_count, busy_lb_balanced, busy_lb_failed, v17); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(busy_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu busy)", "%11.2Lf", + busy_lb_count, busy_lb_balanced, busy_lb_failed, busy_lb_gained, v17); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, idle_lb_count, + "load_balance() count on cpu idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, idle_lb_balanced, + "load_balance() found balanced on cpu idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, idle_lb_failed, + "load_balance() move task failed on cpu idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, idle_lb_imbalance_load, + "imbalance in load on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_imbalance_util, + "imbalance in utilization on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_imbalance_task, + "imbalance in number of tasks on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_imbalance_misfit, + "imbalance in misfit tasks on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_gained, + "pull_task() count on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, idle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, idle_lb_nobusyg, + "load_balance() failed to find busier group on cpu idle", "%11u", true, v17); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(idle_lb_success_count, "load_balance() success count on cpu idle", "%11u", + idle_lb_count, idle_lb_balanced, idle_lb_failed, v17); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(idle_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu idle)", "%11.2Lf", + idle_lb_count, idle_lb_balanced, idle_lb_failed, idle_lb_gained, v17); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, newidle_lb_count, + "load_balance() count on cpu newly idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, newidle_lb_balanced, + "load_balance() found balanced on cpu newly idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, newidle_lb_failed, + "load_balance() move task failed on cpu newly idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, newidle_lb_imbalance_load, + "imbalance in load on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_imbalance_util, + "imbalance in utilization on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_imbalance_task, + "imbalance in number of tasks on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_imbalance_misfit, + "imbalance in misfit tasks on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_gained, + "pull_task() count on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_hot_gained, + "pull_task() when target task was cache-hot on cpu newly idle", "%11u", false, v17); +DOMAIN_FIELD(__u32, newidle_lb_nobusyq, + "load_balance() failed to find busier queue on cpu newly idle", "%11u", true, v17); +DOMAIN_FIELD(__u32, newidle_lb_nobusyg, + "load_balance() failed to find busier group on cpu newly idle", "%11u", true, v17); +#ifdef DERIVED_CNT_FIELD +DERIVED_CNT_FIELD(newidle_lb_success_count, + "load_balance() success count on cpu newly idle", "%11u", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, v17); +#endif +#ifdef DERIVED_AVG_FIELD +DERIVED_AVG_FIELD(newidle_lb_avg_pulled, + "avg task pulled per successful lb attempt (cpu newly idle)", "%11.2Lf", + newidle_lb_count, newidle_lb_balanced, newidle_lb_failed, newidle_lb_gained, v17); +#endif +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, alb_count, + "active_load_balance() count", "%11u", false, v17); +DOMAIN_FIELD(__u32, alb_failed, + "active_load_balance() move task failed", "%11u", false, v17); +DOMAIN_FIELD(__u32, alb_pushed, + "active_load_balance() successfully moved a task", "%11u", false, v17); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbe_count, + "sbe_count is not used", "%11u", false, v17); +DOMAIN_FIELD(__u32, sbe_balanced, + "sbe_balanced is not used", "%11u", false, v17); +DOMAIN_FIELD(__u32, sbe_pushed, + "sbe_pushed is not used", "%11u", false, v17); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, sbf_count, + "sbf_count is not used", "%11u", false, v17); +DOMAIN_FIELD(__u32, sbf_balanced, + "sbf_balanced is not used", "%11u", false, v17); +DOMAIN_FIELD(__u32, sbf_pushed, + "sbf_pushed is not used", "%11u", false, v17); +#ifdef DOMAIN_CATEGORY +DOMAIN_CATEGORY(" "); +#endif +DOMAIN_FIELD(__u32, ttwu_wake_remote, + "try_to_wake_up() awoke a task that last ran on a diff cpu", "%11u", false, v17); +DOMAIN_FIELD(__u32, ttwu_move_affine, + "try_to_wake_up() moved task because cache-cold on own cpu", "%11u", false, v17); +DOMAIN_FIELD(__u32, ttwu_move_balance, + "try_to_wake_up() started passive balancing", "%11u", false, v17); +#endif /* DOMAIN_FIELD */ diff --git a/tools/lib/python/kdoc/kdoc_parser.py b/tools/lib/python/kdoc/kdoc_parser.py index fd57944ae907..ca00695b47b3 100644 --- a/tools/lib/python/kdoc/kdoc_parser.py +++ b/tools/lib/python/kdoc/kdoc_parser.py @@ -175,6 +175,7 @@ function_xforms = [ (KernRe(r"^__FORTIFY_INLINE +"), ""), (KernRe(r"__init +"), ""), (KernRe(r"__init_or_module +"), ""), + (KernRe(r"__exit +"), ""), (KernRe(r"__deprecated +"), ""), (KernRe(r"__flatten +"), ""), (KernRe(r"__meminit +"), ""), diff --git a/tools/lib/subcmd/help.c b/tools/lib/subcmd/help.c index ddaeb4eb3e24..db94aa685b73 100644 --- a/tools/lib/subcmd/help.c +++ b/tools/lib/subcmd/help.c @@ -97,11 +97,13 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) ei++; } } - if (ci != cj) { - while (ci < cmds->cnt) { - cmds->names[cj++] = cmds->names[ci]; - cmds->names[ci++] = NULL; + while (ci < cmds->cnt) { + if (ci != cj) { + cmds->names[cj] = cmds->names[ci]; + cmds->names[ci] = NULL; } + ci++; + cj++; } for (ci = cj; ci < cmds->cnt; ci++) assert(cmds->names[ci] == NULL); diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index a40f30232929..b71d1886022e 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -13,7 +13,7 @@ endif ifeq ($(ARCH_HAS_KLP),y) HAVE_XXHASH = $(shell printf "$(pound)include \nXXH3_state_t *state;int main() {}" | \ - $(HOSTCC) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) + $(HOSTCC) $(HOSTCFLAGS) -xc - -o /dev/null -lxxhash 2> /dev/null && echo y || echo n) ifeq ($(HAVE_XXHASH),y) BUILD_KLP := y LIBXXHASH_CFLAGS := $(shell $(HOSTPKG_CONFIG) libxxhash --cflags 2>/dev/null) \ @@ -29,6 +29,8 @@ srctree := $(patsubst %/,%,$(dir $(CURDIR))) srctree := $(patsubst %/,%,$(dir $(srctree))) endif +RM ?= rm -f + LIBSUBCMD_DIR = $(srctree)/tools/lib/subcmd/ ifneq ($(OUTPUT),) LIBSUBCMD_OUTPUT = $(abspath $(OUTPUT))/libsubcmd @@ -140,13 +142,15 @@ $(LIBSUBCMD)-clean: $(Q)$(RM) -r -- $(LIBSUBCMD_OUTPUT) clean: $(LIBSUBCMD)-clean - $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) - $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete + $(Q)find $(OUTPUT) \( -name '*.o' -o -name '\.*.cmd' -o -name '\.*.d' \) -type f -print | xargs $(RM) $(Q)$(RM) $(OUTPUT)arch/x86/lib/cpu-feature-names.c $(OUTPUT)fixdep $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep $(Q)$(RM) -- $(OUTPUT)FEATURE-DUMP.objtool $(Q)$(RM) -r -- $(OUTPUT)feature +mrproper: clean + $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL) + FORCE: -.PHONY: clean FORCE +.PHONY: clean mrproper FORCE diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c index 73bfea220d1b..c5817829cdfa 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -395,52 +395,36 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec if (!rex_w) break; - if (modrm_reg == CFI_SP) { - - if (mod_is_reg()) { - /* mov %rsp, reg */ - ADD_OP(op) { - op->src.type = OP_SRC_REG; - op->src.reg = CFI_SP; - op->dest.type = OP_DEST_REG; - op->dest.reg = modrm_rm; - } - break; - - } else { - /* skip RIP relative displacement */ - if (is_RIP()) - break; - - /* skip nontrivial SIB */ - if (have_SIB()) { - modrm_rm = sib_base; - if (sib_index != CFI_SP) - break; - } - - /* mov %rsp, disp(%reg) */ - ADD_OP(op) { - op->src.type = OP_SRC_REG; - op->src.reg = CFI_SP; - op->dest.type = OP_DEST_REG_INDIRECT; - op->dest.reg = modrm_rm; - op->dest.offset = ins.displacement.value; - } - break; - } - - break; - } - - if (rm_is_reg(CFI_SP)) { - - /* mov reg, %rsp */ + if (mod_is_reg()) { + /* mov reg, reg */ ADD_OP(op) { op->src.type = OP_SRC_REG; op->src.reg = modrm_reg; op->dest.type = OP_DEST_REG; - op->dest.reg = CFI_SP; + op->dest.reg = modrm_rm; + } + break; + } + + /* skip RIP relative displacement */ + if (is_RIP()) + break; + + /* skip nontrivial SIB */ + if (have_SIB()) { + modrm_rm = sib_base; + if (sib_index != CFI_SP) + break; + } + + /* mov %rsp, disp(%reg) */ + if (modrm_reg == CFI_SP) { + ADD_OP(op) { + op->src.type = OP_SRC_REG; + op->src.reg = CFI_SP; + op->dest.type = OP_DEST_REG_INDIRECT; + op->dest.reg = modrm_rm; + op->dest.offset = ins.displacement.value; } break; } diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 37f87c4a0134..91b3ff4803cf 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -197,7 +197,8 @@ static bool is_rust_noreturn(const struct symbol *func) * as well as changes to the source code itself between versions (since * these come from the Rust standard library). */ - return str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") || + return str_ends_with(func->name, "_4core3num20from_str_radix_panic") || + str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") || str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || str_ends_with(func->name, "_4core6option13expect_failed") || str_ends_with(func->name, "_4core6option13unwrap_failed") || @@ -2999,6 +3000,20 @@ static int update_cfi_state(struct instruction *insn, cfi->stack_size += 8; } + else if (cfi->vals[op->src.reg].base == CFI_CFA) { + /* + * Clang RSP musical chairs: + * + * mov %rsp, %rdx [handled above] + * ... + * mov %rdx, %rbx [handled here] + * ... + * mov %rbx, %rsp [handled above] + */ + cfi->vals[op->dest.reg].base = CFI_CFA; + cfi->vals[op->dest.reg].offset = cfi->vals[op->src.reg].offset; + } + break; @@ -3733,7 +3748,7 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func, static int validate_branch(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state state); static int do_validate_branch(struct objtool_file *file, struct symbol *func, - struct instruction *insn, struct insn_state state); + struct instruction *insn, struct insn_state *state); static int validate_insn(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state *statep, @@ -3998,7 +4013,7 @@ static int validate_insn(struct objtool_file *file, struct symbol *func, * tools/objtool/Documentation/objtool.txt. */ static int do_validate_branch(struct objtool_file *file, struct symbol *func, - struct instruction *insn, struct insn_state state) + struct instruction *insn, struct insn_state *state) { struct instruction *next_insn, *prev_insn = NULL; bool dead_end; @@ -4029,7 +4044,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func, return 1; } - ret = validate_insn(file, func, insn, &state, prev_insn, next_insn, + ret = validate_insn(file, func, insn, state, prev_insn, next_insn, &dead_end); if (!insn->trace) { @@ -4040,7 +4055,7 @@ static int do_validate_branch(struct objtool_file *file, struct symbol *func, } if (!dead_end && !next_insn) { - if (state.cfi.cfa.base == CFI_UNDEFINED) + if (state->cfi.cfa.base == CFI_UNDEFINED) return 0; if (file->ignore_unreachables) return 0; @@ -4065,7 +4080,7 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, int ret; trace_depth_inc(); - ret = do_validate_branch(file, func, insn, state); + ret = do_validate_branch(file, func, insn, &state); trace_depth_dec(); return ret; diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 2c02c7b49265..3da90686350d 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -1375,7 +1375,7 @@ void *elf_add_data(struct elf *elf, struct section *sec, const void *data, size_ memcpy(sec->data->d_buf, data, size); sec->data->d_size = size; - sec->data->d_align = 1; + sec->data->d_align = sec->sh.sh_addralign; offset = ALIGN(sec->sh.sh_size, sec->sh.sh_addralign); sec->sh.sh_size = offset + size; diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/objtool/warn.h index 2b27b54096b8..fa8b7d292e83 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -107,7 +107,7 @@ static inline char *offstr(struct section *sec, unsigned long offset) #define ERROR_ELF(format, ...) __WARN_ELF(ERROR_STR, format, ##__VA_ARGS__) #define ERROR_GLIBC(format, ...) __WARN_GLIBC(ERROR_STR, format, ##__VA_ARGS__) #define ERROR_FUNC(sec, offset, format, ...) __WARN_FUNC(ERROR_STR, sec, offset, format, ##__VA_ARGS__) -#define ERROR_INSN(insn, format, ...) WARN_FUNC(insn->sec, insn->offset, format, ##__VA_ARGS__) +#define ERROR_INSN(insn, format, ...) ERROR_FUNC(insn->sec, insn->offset, format, ##__VA_ARGS__) extern bool debug; extern int indent; diff --git a/tools/objtool/klp-diff.c b/tools/objtool/klp-diff.c index 9f1f4011eb9c..a3198a63c2f0 100644 --- a/tools/objtool/klp-diff.c +++ b/tools/objtool/klp-diff.c @@ -1334,25 +1334,25 @@ static bool should_keep_special_sym(struct elf *elf, struct symbol *sym) * be applied after static branch/call init, resulting in code corruption. * * Validate a special section entry to avoid that. Note that an inert - * tracepoint is harmless enough, in that case just skip the entry and print a - * warning. Otherwise, return an error. + * tracepoint or pr_debug() is harmless enough, in that case just skip the + * entry and print a warning. Otherwise, return an error. * - * This is only a temporary limitation which will be fixed when livepatch adds - * support for submodules: fully self-contained modules which are embedded in - * the top-level livepatch module's data and which can be loaded on demand when - * their corresponding to-be-patched module gets loaded. Then klp relocs can - * be retired. + * TODO: This is only a temporary limitation which will be fixed when livepatch + * adds support for submodules: fully self-contained modules which are embedded + * in the top-level livepatch module's data and which can be loaded on demand + * when their corresponding to-be-patched module gets loaded. Then klp relocs + * can be retired. * * Return: * -1: error: validation failed - * 1: warning: tracepoint skipped + * 1: warning: disabled tracepoint or pr_debug() * 0: success */ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym) { bool static_branch = !strcmp(sym->sec->name, "__jump_table"); bool static_call = !strcmp(sym->sec->name, ".static_call_sites"); - struct symbol *code_sym = NULL; + const char *code_sym = NULL; unsigned long code_offset = 0; struct reloc *reloc; int ret = 0; @@ -1364,12 +1364,15 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym const char *sym_modname; struct export *export; + if (convert_reloc_sym(e->patched, reloc)) + continue; + /* Static branch/call keys are always STT_OBJECT */ if (reloc->sym->type != STT_OBJECT) { /* Save code location which can be printed below */ if (reloc->sym->type == STT_FUNC && !code_sym) { - code_sym = reloc->sym; + code_sym = reloc->sym->name; code_offset = reloc_addend(reloc); } @@ -1392,16 +1395,26 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym if (!strcmp(sym_modname, "vmlinux")) continue; + if (!code_sym) + code_sym = ""; + if (static_branch) { if (strstarts(reloc->sym->name, "__tracepoint_")) { WARN("%s: disabling unsupported tracepoint %s", - code_sym->name, reloc->sym->name + 13); + code_sym, reloc->sym->name + 13); + ret = 1; + continue; + } + + if (strstr(reloc->sym->name, "__UNIQUE_ID_ddebug_")) { + WARN("%s: disabling unsupported pr_debug()", + code_sym); ret = 1; continue; } ERROR("%s+0x%lx: unsupported static branch key %s. Use static_key_enabled() instead", - code_sym->name, code_offset, reloc->sym->name); + code_sym, code_offset, reloc->sym->name); return -1; } @@ -1412,7 +1425,7 @@ static int validate_special_section_klp_reloc(struct elfs *e, struct symbol *sym } ERROR("%s()+0x%lx: unsupported static call key %s. Use KLP_STATIC_CALL() instead", - code_sym->name, code_offset, reloc->sym->name); + code_sym, code_offset, reloc->sym->name); return -1; } diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index b64302a76144..0f9451a6e39c 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -36,12 +36,18 @@ config.mak.autogen util/intel-pt-decoder/inat-tables.c arch/*/include/generated/ trace/beauty/generated/ +pmu-events/arch/common/common/legacy-cache.json pmu-events/pmu-events.c pmu-events/jevents pmu-events/metric_test.log pmu-events/empty-pmu-events.log pmu-events/test-empty-pmu-events.c *.shellcheck_log +pmu-events/arch/**/extra-metrics.json +pmu-events/arch/**/extra-metricgroups.json +tests/shell/*.shellcheck_log +tests/shell/coresight/*.shellcheck_log +tests/shell/lib/*.shellcheck_log feature/ libapi/ libbpf/ diff --git a/tools/perf/Documentation/perf-c2c.txt b/tools/perf/Documentation/perf-c2c.txt index 40b0f71a2c44..e57a122b8719 100644 --- a/tools/perf/Documentation/perf-c2c.txt +++ b/tools/perf/Documentation/perf-c2c.txt @@ -160,20 +160,43 @@ Following perf record options are configured by default: -W,-d,--phys-data,--sample-cpu -Unless specified otherwise with '-e' option, following events are monitored by -default on Intel: +The following table lists the events monitored on different architectures. +Unless specified otherwise with the -e option, the tool will select the +default events. - cpu/mem-loads,ldlat=30/P - cpu/mem-stores/P - -following on AMD: - - ibs_op// - -and following on PowerPC: - - cpu/mem-loads/ - cpu/mem-stores/ + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | Arch | Configuration | Options | Events | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | Intel | Default | -e ldlat-loads | cpu/mem-loads,ldlat=30/P | + | | | -e ldlat-stores | cpu/mem-stores/P | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Load only | -e ldlat-loads | cpu/mem-loads,ldlat=30/P | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Store only | -e ldlat-stores | cpu/mem-stores/P | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | Intel | Default | -e ldlat-loads | {cpu/mem-loads-aux/,cpu/mem-loads,ldlat=30/}:P | + | with | | -e ldlat-stores | cpu/mem-stores/P | + | AUX |--------------+------------------+--------------------------------------------------------------------------------+ + | | Load only | -e ldlat-loads | {cpu/mem-loads-aux/,cpu/mem-loads,ldlat=30/}:P | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Store only | -e ldlat-stores | cpu/mem-stores/P | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | AMD | Default | -e mem-ldst | ibs_op// (without latency support) | + | | | | ibs_op/ldlat=30/ (with latency support) | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | PowerPC| Default | -e ldlat-loads | cpu/mem-loads/ | + | | | -e ldlat-stores | cpu/mem-stores/ | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Load only | -e ldlat-loads | cpu/mem-loads/ | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Store only | -e ldlat-stores | cpu/mem-stores/ | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ + | Arm | Default | -e spe-ldst | arm_spe_0/ts_enable=1,pa_enable=1,load_filter=1,store_filter=1,min_latency=30/ | + | SPE |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Load only | -e spe-load | arm_spe_0/ts_enable=1,pa_enable=1,load_filter=1,min_latency=30/ | + | |---------------+-----------------+--------------------------------------------------------------------------------+ + | | Store only | -e spe-store | arm_spe_0/ts_enable=1,pa_enable=1,store_filter=1/ | + +--------+---------------+-----------------+--------------------------------------------------------------------------------+ User can pass any 'perf record' option behind '--' mark, like (to enable callchains and system wide monitoring): diff --git a/tools/perf/Documentation/perf-data.txt b/tools/perf/Documentation/perf-data.txt index 417bf17e265c..20f178d61ed7 100644 --- a/tools/perf/Documentation/perf-data.txt +++ b/tools/perf/Documentation/perf-data.txt @@ -40,6 +40,34 @@ OPTIONS for 'convert' --force:: Don't complain, do it. +--time:: + Only convert samples within given time window: ,. Times + have the format seconds.nanoseconds. If start is not given (i.e. time + string is ',x.y') then analysis starts at the beginning of the file. If + stop time is not given (i.e. time string is 'x.y,') then analysis goes + to end of file. Multiple ranges can be separated by spaces, which + requires the argument to be quoted e.g. --time "1234.567,1234.789 1235," + + Also support time percent with multiple time ranges. Time string is + 'a%/n,b%/m,...' or 'a%-b%,c%-%d,...'. + + For example: + Select the second 10% time slice: + + perf data convert --to-json out.json --time 10%/2 + + Select from 0% to 10% time slice: + + perf data convert --to-json out.json --time 0%-10% + + Select the first and second 10% time slices: + + perf data convert --to-json out.json --time 10%/1,10%/2 + + Select from 0% to 10% and 30% to 40% slices: + + perf data convert --to-json out.json --time 0%-10%,30%-40% + -v:: --verbose:: Be more verbose (show counter open errors, etc). diff --git a/tools/perf/Documentation/perf-inject.txt b/tools/perf/Documentation/perf-inject.txt index c972032f4ca0..95dfdf39666e 100644 --- a/tools/perf/Documentation/perf-inject.txt +++ b/tools/perf/Documentation/perf-inject.txt @@ -109,6 +109,11 @@ include::itrace.txt[] should be used, and also --buildid-all and --switch-events may be useful. +--convert-callchain:: + Parse DWARF callchains and convert them to usual callchains. This also + discards stack and register data from the samples. This will lose + inlined callchain entries. + :GMEXAMPLECMD: inject :GMEXAMPLESUBCMD: include::guestmount.txt[] diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt index e8b9aadbbfa5..178f483140ed 100644 --- a/tools/perf/Documentation/perf-record.txt +++ b/tools/perf/Documentation/perf-record.txt @@ -344,7 +344,8 @@ OPTIONS -d:: --data:: - Record the sample virtual addresses. Implies --sample-mem-info. + Record the sample virtual addresses. Implies --sample-mem-info and + --data-mmap. --phys-data:: Record the sample physical addresses. @@ -454,7 +455,7 @@ following filters are defined: - no_tx: only when the target is not in a hardware transaction - abort_tx: only when the target is a hardware transaction abort - cond: conditional branches - - call_stack: save call stack + - stack: save call stack - no_flags: don't save branch flags e.g prediction, misprediction etc - no_cycles: don't save branch cycles - hw_index: save branch hardware index @@ -861,6 +862,11 @@ filtered through the mask provided by -C option. Prepare BPF filter to be used by regular users. The action should be either "pin" or "unpin". The filter can be used after it's pinned. +--data-mmap:: + Enable recording MMAP events for non-executable mappings. Basically + perf only records executable mappings but data mmaping can be useful + when you analyze data access with sample addresses. So using -d option + would enable this unless you specify --no-data-mmap manually. include::intel-hybrid.txt[] diff --git a/tools/perf/Documentation/perf-sched.txt b/tools/perf/Documentation/perf-sched.txt index 6dbbddb6464d..4d9981609c04 100644 --- a/tools/perf/Documentation/perf-sched.txt +++ b/tools/perf/Documentation/perf-sched.txt @@ -8,7 +8,7 @@ perf-sched - Tool to trace/measure scheduler properties (latencies) SYNOPSIS -------- [verse] -'perf sched' {record|latency|map|replay|script|timehist} +'perf sched' {record|latency|map|replay|script|timehist|stats} DESCRIPTION ----------- @@ -80,8 +80,267 @@ There are several variants of 'perf sched': Times are in msec.usec. + 'perf sched stats {record | report | diff} ' to capture, report the diff + in schedstat counters and show the difference between perf sched stats report + respectively. schedstat counters which are present in the linux kernel and are + exposed through the file ``/proc/schedstat``. These counters are enabled or disabled + via the sysctl governed by the file ``/proc/sys/kernel/sched_schedstats``. These + counters accounts for many scheduler events such as ``schedule()`` calls, load-balancing + events, ``try_to_wakeup()`` call among others. This is useful in understanding the + scheduler behavior for the workload. + + Note: The tool will not give correct results if there is topological reordering or + online/offline of cpus in between capturing snapshots of `/proc/schedstat`. + + Example usage: + perf sched stats record -- sleep 1 + perf sched stats report + perf sched stats diff + + A detailed description of the schedstats can be found in the Kernel Documentation: + https://www.kernel.org/doc/html/latest/scheduler/sched-stats.html + + The result can be interpreted as follows: + + The `perf sched stats report` starts with description of the columns present in + the report. These column names are given before cpu and domain stats to improve + the readability of the report. + + ---------------------------------------------------------------------------------------------------- + DESC -> Description of the field + COUNT -> Value of the field + PCT_CHANGE -> Percent change with corresponding base value + AVG_JIFFIES -> Avg time in jiffies between two consecutive occurrence of event + ---------------------------------------------------------------------------------------------------- + + Next is the total profiling time in terms of jiffies: + + ---------------------------------------------------------------------------------------------------- + Time elapsed (in jiffies) : 2323 + ---------------------------------------------------------------------------------------------------- + + Next is CPU scheduling statistics. These are simple diffs of /proc/schedstat CPU lines + along with description. The report also prints % relative to base stat. + + In the example below, schedule() left the CPU0 idle 36.58% of the time. 0.45% of total + try_to_wake_up() was to wakeup local CPU. And, the total waittime by tasks on CPU0 is + 48.70% of the total runtime by tasks on the same CPU. + + ---------------------------------------------------------------------------------------------------- + CPU 0 + ---------------------------------------------------------------------------------------------------- + DESC COUNT PCT_CHANGE + ---------------------------------------------------------------------------------------------------- + yld_count : 0 + array_exp : 0 + sched_count : 402267 + sched_goidle : 147161 ( 36.58% ) + ttwu_count : 236309 + ttwu_local : 1062 ( 0.45% ) + rq_cpu_time : 7083791148 + run_delay : 3449973971 ( 48.70% ) + pcount : 255035 + ---------------------------------------------------------------------------------------------------- + + Next is load balancing statistics. For each of the sched domains + (eg: `SMT`, `MC`, `DIE`...), the scheduler computes statistics under + the following three categories: + + 1) Idle Load Balance: Load balancing performed on behalf of a long + idling CPU by some other CPU. + 2) Busy Load Balance: Load balancing performed when the CPU was busy. + 3) New Idle Balance : Load balancing performed when a CPU just became + idle. + + Under each of these three categories, sched stats report provides + different load balancing statistics. Along with direct stats, the + report also contains derived metrics prefixed with *. Example: + + ---------------------------------------------------------------------------------------------------- + CPU 0, DOMAIN SMT CPUS 0,64 + ---------------------------------------------------------------------------------------------------- + DESC COUNT AVG_JIFFIES + ----------------------------------------- ------------------------------------------ + busy_lb_count : 136 $ 17.08 $ + busy_lb_balanced : 131 $ 17.73 $ + busy_lb_failed : 0 $ 0.00 $ + busy_lb_imbalance_load : 58 + busy_lb_imbalance_util : 0 + busy_lb_imbalance_task : 0 + busy_lb_imbalance_misfit : 0 + busy_lb_gained : 7 + busy_lb_hot_gained : 0 + busy_lb_nobusyq : 2 $ 1161.50 $ + busy_lb_nobusyg : 129 $ 18.01 $ + *busy_lb_success_count : 5 + *busy_lb_avg_pulled : 1.40 + ----------------------------------------- ------------------------------------------ + idle_lb_count : 449 $ 5.17 $ + idle_lb_balanced : 382 $ 6.08 $ + idle_lb_failed : 3 $ 774.33 $ + idle_lb_imbalance_load : 0 + idle_lb_imbalance_util : 0 + idle_lb_imbalance_task : 71 + idle_lb_imbalance_misfit : 0 + idle_lb_gained : 67 + idle_lb_hot_gained : 0 + idle_lb_nobusyq : 0 $ 0.00 $ + idle_lb_nobusyg : 382 $ 6.08 $ + *idle_lb_success_count : 64 + *idle_lb_avg_pulled : 1.05 + ---------------------------------------- ---------------------------------------- + newidle_lb_count : 30471 $ 0.08 $ + newidle_lb_balanced : 28490 $ 0.08 $ + newidle_lb_failed : 633 $ 3.67 $ + newidle_lb_imbalance_load : 0 + newidle_lb_imbalance_util : 0 + newidle_lb_imbalance_task : 2040 + newidle_lb_imbalance_misfit : 0 + newidle_lb_gained : 1348 + newidle_lb_hot_gained : 0 + newidle_lb_nobusyq : 6 $ 387.17 $ + newidle_lb_nobusyg : 26634 $ 0.09 $ + *newidle_lb_success_count : 1348 + *newidle_lb_avg_pulled : 1.00 + ---------------------------------------------------------------------------------------------------- + + Consider following line: + + newidle_lb_balanced : 28490 $ 0.08 $ + + While profiling was active, the load-balancer found 28490 times the load + needs to be balanced on a newly idle CPU 0. Following value encapsulated + inside $ is average jiffies between two events (2323 / 28490 = 0.08). + + Next are active_load_balance() stats. alb did not trigger while the + profiling was active, hence it's all 0s. + + --------------------------------- --------------------------------- + alb_count : 0 + alb_failed : 0 + alb_pushed : 0 + ---------------------------------------------------------------------------------------------------- + + Next are sched_balance_exec() and sched_balance_fork() stats. They are + not used but we kept it in RFC just for legacy purpose. Unless opposed, + we plan to remove them in next revision. + + Next are wakeup statistics. For every domain, the report also shows + task-wakeup statistics. Example: + + ------------------------------------------ ------------------------------------------- + ttwu_wake_remote : 1590 + ttwu_move_affine : 84 + ttwu_move_balance : 0 + ---------------------------------------------------------------------------------------------------- + + Same set of stats are reported for each CPU and each domain level. + + How to interpret the diff + ~~~~~~~~~~~~~~~~~~~~~~~~~ + + The `perf sched stats diff` will also start with explaining the columns + present in the diff. Then it will show the diff in time in terms of + jiffies. The order of the values depends on the order of input data + files. It will take `perf.data.old` and `perf.data` respectively as the + defaults for comparison. Example: + + ---------------------------------------------------------------------------------------------------- + Time elapsed (in jiffies) : 2009, 2001 + ---------------------------------------------------------------------------------------------------- + + Below is the sample representing the difference in cpu and domain stats of + two runs. Here third column or the values enclosed in `|...|` shows the + percent change between the two. Second and fourth columns shows the + side-by-side representions of the corresponding fields from `perf sched + stats report`. + + ---------------------------------------------------------------------------------------------------- + CPU + ---------------------------------------------------------------------------------------------------- + DESC COUNT1 COUNT2 PCT_CHANG> + ---------------------------------------------------------------------------------------------------- + yld_count : 0, 0 | 0.00> + array_exp : 0, 0 | 0.00> + sched_count : 528533, 412573 | -21.94> + sched_goidle : 193426, 146082 | -24.48> + ttwu_count : 313134, 385975 | 23.26> + ttwu_local : 1126, 1282 | 13.85> + rq_cpu_time : 8257200244, 8301250047 | 0.53> + run_delay : 4728347053, 3997100703 | -15.47> + pcount : 335031, 266396 | -20.49> + ---------------------------------------------------------------------------------------------------- + + Below is the sample of domain stats diff: + + ---------------------------------------------------------------------------------------------------- + CPU , DOMAIN SMT + ---------------------------------------------------------------------------------------------------- + DESC COUNT1 COUNT2 PCT_CHANG> + ----------------------------------------- ------------------------------------------ + busy_lb_count : 122, 80 | -34.43> + busy_lb_balanced : 115, 76 | -33.91> + busy_lb_failed : 1, 3 | 200.00> + busy_lb_imbalance_load : 35, 49 | 40.00> + busy_lb_imbalance_util : 0, 0 | 0.00> + busy_lb_imbalance_task : 0, 0 | 0.00> + busy_lb_imbalance_misfit : 0, 0 | 0.00> + busy_lb_gained : 7, 2 | -71.43> + busy_lb_hot_gained : 0, 0 | 0.00> + busy_lb_nobusyq : 0, 0 | 0.00> + busy_lb_nobusyg : 115, 76 | -33.91> + *busy_lb_success_count : 6, 1 | -83.33> + *busy_lb_avg_pulled : 1.17, 2.00 | 71.43> + ----------------------------------------- ------------------------------------------ + idle_lb_count : 568, 620 | 9.15> + idle_lb_balanced : 462, 449 | -2.81> + idle_lb_failed : 11, 21 | 90.91> + idle_lb_imbalance_load : 0, 0 | 0.00> + idle_lb_imbalance_util : 0, 0 | 0.00> + idle_lb_imbalance_task : 115, 189 | 64.35> + idle_lb_imbalance_misfit : 0, 0 | 0.00> + idle_lb_gained : 103, 169 | 64.08> + idle_lb_hot_gained : 0, 0 | 0.00> + idle_lb_nobusyq : 0, 0 | 0.00> + idle_lb_nobusyg : 462, 449 | -2.81> + *idle_lb_success_count : 95, 150 | 57.89> + *idle_lb_avg_pulled : 1.08, 1.13 | 3.92> + ---------------------------------------- ---------------------------------------- + newidle_lb_count : 16961, 3155 | -81.40> + newidle_lb_balanced : 15646, 2556 | -83.66> + newidle_lb_failed : 397, 142 | -64.23> + newidle_lb_imbalance_load : 0, 0 | 0.00> + newidle_lb_imbalance_util : 0, 0 | 0.00> + newidle_lb_imbalance_task : 1376, 655 | -52.40> + newidle_lb_imbalance_misfit : 0, 0 | 0.00> + newidle_lb_gained : 917, 457 | -50.16> + newidle_lb_hot_gained : 0, 0 | 0.00> + newidle_lb_nobusyq : 3, 1 | -66.67> + newidle_lb_nobusyg : 14480, 2103 | -85.48> + *newidle_lb_success_count : 918, 457 | -50.22> + *newidle_lb_avg_pulled : 1.00, 1.00 | 0.11> + --------------------------------- --------------------------------- + alb_count : 0, 1 | 0.00> + alb_failed : 0, 0 | 0.00> + alb_pushed : 0, 1 | 0.00> + --------------------------------- ---------------------------------- + sbe_count : 0, 0 | 0.00> + sbe_balanced : 0, 0 | 0.00> + sbe_pushed : 0, 0 | 0.00> + --------------------------------- ---------------------------------- + sbf_count : 0, 0 | 0.00> + sbf_balanced : 0, 0 | 0.00> + sbf_pushed : 0, 0 | 0.00> + ------------------------------------------ ------------------------------------------- + ttwu_wake_remote : 2031, 2914 | 43.48> + ttwu_move_affine : 73, 124 | 69.86> + ttwu_move_balance : 0, 0 | 0.00> + ---------------------------------------------------------------------------------------------------- + OPTIONS ------- +Applicable to {record|latency|map|replay|script} + -i:: --input=:: Input file name. (default: perf.data unless stdin is a fifo) diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt index 03d112960632..ddf92f9c7821 100644 --- a/tools/perf/Documentation/perf-script.txt +++ b/tools/perf/Documentation/perf-script.txt @@ -98,8 +98,10 @@ OPTIONS -g:: --gen-script=:: - Generate perf-script.[ext] starter script for given language, - using current perf.data. + Generate a starter script. If a language is given then the + script is named perf-script.[ext] according to the + language. If a file path is given then python is used for + files ending '.py' and perl used for files ending '.pl'. --dlfilter=:: Filter sample events using the given shared object file. diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 1a766d4a2233..7cccc3a847d1 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -382,6 +382,11 @@ color the metric's computed value. Don't print output, warnings or messages. This is useful with perf stat record below to only write data to the perf.data file. +--no-affinity:: +Don't change scheduler CPU affinities when iterating over +CPUs. Disables an optimization aimed at minimizing interprocessor +interrupts. + STAT RECORD ----------- Stores stat data into perf data file. diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index c9d4dec65344..0e4d0ecc9e12 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt @@ -447,6 +447,23 @@ struct { } [nr_pmu]; }; + HEADER_CPU_DOMAIN_INFO = 32, + +List of cpu-domain relation info. The format of the data is as below. + +struct domain_info { + int domain; + char dname[]; + char cpumask[]; + char cpulist[]; +}; + +struct cpu_domain_info { + int cpu; + int nr_domains; + struct domain_info domains[]; +}; + other bits are reserved and should ignored for now HEADER_FEAT_BITS = 256, diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index d8d25f62aaad..15fbba9f4ca8 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config @@ -64,7 +64,6 @@ include $(srctree)/tools/scripts/Makefile.arch $(call detected_var,SRCARCH) CFLAGS += -I$(OUTPUT)arch/$(SRCARCH)/include/generated -CFLAGS += -I$(OUTPUT)libperf/arch/$(SRCARCH)/include/generated/uapi # Additional ARCH settings for ppc ifeq ($(SRCARCH),powerpc) @@ -118,14 +117,6 @@ ifeq ($(ARCH),mips) endif endif -# So far there's only x86 and arm libdw unwind support merged in perf. -# Disable it on all other architectures in case libdw unwind -# support is detected in system. Add supported architectures -# to the check. -ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv loongarch)) - NO_LIBDW_DWARF_UNWIND := 1 -endif - ifneq ($(LIBUNWIND),1) NO_LIBUNWIND := 1 endif @@ -379,8 +370,8 @@ ifneq ($(TCMALLOC),) endif ifeq ($(FEATURES_DUMP),) -# We will display at the end of this Makefile.config, using $(call feature_display_entries) -# As we may retry some feature detection here, see the disassembler-four-args case, for instance +# We will display at the end of this Makefile.config, using $(call feature_display_entries), +# as we may retry some feature detection here. FEATURE_DISPLAY_DEFERRED := 1 include $(srctree)/tools/build/Makefile.feature else @@ -456,7 +447,6 @@ endif ifdef NO_LIBELF NO_LIBDW := 1 NO_LIBUNWIND := 1 - NO_LIBDW_DWARF_UNWIND := 1 NO_LIBBPF := 1 NO_JVMTI := 1 else @@ -504,10 +494,6 @@ ifeq ($(feature-libaio), 1) endif endif -ifdef NO_LIBDW - NO_LIBDW_DWARF_UNWIND := 1 -endif - ifeq ($(feature-scandirat), 1) # Ignore having scandirat with memory sanitizer that lacks an interceptor. ifeq ($(filter s% -fsanitize=memory%,$(EXTRA_CFLAGS),),) @@ -757,7 +743,7 @@ dwarf-post-unwind-text := BUG # setup DWARF post unwinder ifdef NO_LIBUNWIND - ifdef NO_LIBDW_DWARF_UNWIND + ifdef NO_LIBDW $(warning Disabling post unwind, no support found.) dwarf-post-unwind := 0 else @@ -767,10 +753,6 @@ ifdef NO_LIBUNWIND else dwarf-post-unwind-text := libunwind $(call detected,CONFIG_LIBUNWIND) - # Enable libunwind support by default. - ifndef NO_LIBDW_DWARF_UNWIND - NO_LIBDW_DWARF_UNWIND := 1 - endif endif ifeq ($(dwarf-post-unwind),1) @@ -931,48 +913,32 @@ ifneq ($(NO_JEVENTS),1) endif ifdef BUILD_NONDISTRO + # call all detections now so we get correct status in VF output $(call feature_check,libbfd) + $(call feature_check,disassembler-four-args) + $(call feature_check,disassembler-init-styled) + $(call feature_check,libbfd-threadsafe) + $(call feature_check,libbfd-liberty) + $(call feature_check,libbfd-liberty-z) + ifneq ($(feature-libbfd-threadsafe), 1) + $(error binutils 2.42 or later is required for non-distro builds) + endif + + # we may be on a system that requires -liberty and (maybe) -lz + # to link against -lbfd; test each case individually here ifeq ($(feature-libbfd), 1) EXTLIBS += -lbfd -lopcodes - FEATURE_CHECK_LDFLAGS-disassembler-four-args = -lbfd -lopcodes -ldl - FEATURE_CHECK_LDFLAGS-disassembler-init-styled = -lbfd -lopcodes -ldl - else - # we are on a system that requires -liberty and (maybe) -lz - # to link against -lbfd; test each case individually here - - # call all detections now so we get correct - # status in VF output - $(call feature_check,libbfd-liberty) - $(call feature_check,libbfd-liberty-z) - - ifeq ($(feature-libbfd-liberty), 1) - EXTLIBS += -lbfd -lopcodes -liberty - FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -ldl - FEATURE_CHECK_LDFLAGS-disassembler-init-styled += -liberty -ldl - else - ifeq ($(feature-libbfd-liberty-z), 1) - EXTLIBS += -lbfd -lopcodes -liberty -lz - FEATURE_CHECK_LDFLAGS-disassembler-four-args += -liberty -lz -ldl - FEATURE_CHECK_LDFLAGS-disassembler-init-styled += -liberty -lz -ldl - endif - endif - $(call feature_check,disassembler-four-args) - $(call feature_check,disassembler-init-styled) + else ifeq ($(feature-libbfd-liberty), 1) + EXTLIBS += -lbfd -lopcodes -liberty + else ifeq ($(feature-libbfd-liberty-z), 1) + EXTLIBS += -lbfd -lopcodes -liberty -lz endif CFLAGS += -DHAVE_LIBBFD_SUPPORT CXXFLAGS += -DHAVE_LIBBFD_SUPPORT $(call detected,CONFIG_LIBBFD) - $(call feature_check,libbfd-buildid) - - ifeq ($(feature-libbfd-buildid), 1) - CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT - else - $(warning Old version of libbfd/binutils things like PE executable profiling will not be available) - endif - ifeq ($(feature-disassembler-four-args), 1) CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE endif @@ -1067,10 +1033,6 @@ ifndef NO_LIBNUMA endif endif -ifdef HAVE_KVM_STAT_SUPPORT - CFLAGS += -DHAVE_KVM_STAT_SUPPORT -endif - ifeq (${IS_64_BIT}, 1) ifndef NO_PERF_READ_VDSO32 $(call feature_check,compile-32) @@ -1112,8 +1074,12 @@ ifndef NO_CAPSTONE $(call feature_check,libcapstone) ifeq ($(feature-libcapstone), 1) CFLAGS += -DHAVE_LIBCAPSTONE_SUPPORT $(LIBCAPSTONE_CFLAGS) - LDFLAGS += $(LICAPSTONE_LDFLAGS) - EXTLIBS += -lcapstone + ifdef LIBCAPSTONE_DLOPEN + CFLAGS += -DLIBCAPSTONE_DLOPEN + else + LDFLAGS += $(LIBCAPSTONE_LDFLAGS) + EXTLIBS += -lcapstone + endif $(call detected,CONFIG_LIBCAPSTONE) else msg := $(warning No libcapstone found, disables disasm engine support for 'perf script', please install libcapstone-dev/capstone-devel); @@ -1187,6 +1153,36 @@ ifneq ($(NO_LIBTRACEEVENT),1) endif endif +ifndef NO_RUST + $(call feature_check,rust) + ifneq ($(feature-rust), 1) + $(warning Rust is not found. Test workloads with rust are disabled.) + NO_RUST := 1 + else + NO_RUST := 0 + CFLAGS += -DHAVE_RUST_SUPPORT + $(call detected,CONFIG_RUST_SUPPORT) + endif + + ifneq ($(CROSS_COMPILE),) + RUST_TARGET_FLAGS_arm := arm-unknown-linux-gnueabi + RUST_TARGET_FLAGS_arm64 := aarch64-unknown-linux-gnu + RUST_TARGET_FLAGS_m68k := m68k-unknown-linux-gnu + RUST_TARGET_FLAGS_mips := mipsel-unknown-linux-gnu + RUST_TARGET_FLAGS_powerpc := powerpc64le-unknown-linux-gnu + RUST_TARGET_FLAGS_riscv := riscv64gc-unknown-linux-gnu + RUST_TARGET_FLAGS_s390 := s390x-unknown-linux-gnu + RUST_TARGET_FLAGS_x86 := x86_64-unknown-linux-gnu + RUST_TARGET_FLAGS_x86_64 := x86_64-unknown-linux-gnu + + ifeq ($(RUST_TARGET_FLAGS_$(ARCH)),) + $(error Unknown rust cross compilation architecture $(ARCH)) + endif + + RUST_FLAGS += --target=$(RUST_TARGET_FLAGS_$(ARCH)) + endif +endif + # Among the variables below, these: # perfexecdir # libbpf_include_dir @@ -1332,6 +1328,6 @@ endif # re-generate FEATURE-DUMP as we may have called feature_check, found out # extra libraries to add to LDFLAGS of some other test and then redo those -# tests, see the block about libbfd, disassembler-four-args, for instance. +# tests. $(shell rm -f $(FEATURE_DUMP_FILENAME)) $(foreach feat,$(FEATURE_TESTS),$(shell echo "$(call feature_assign,$(feat))" >> $(FEATURE_DUMP_FILENAME))) diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index b3f481a626af..f7b936deeaa2 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -35,6 +35,9 @@ include ../scripts/utilities.mak # # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. # +# Define EXTRA_BPF_FLAGS="--sysroot=" or other custom include paths for +# cross-compiling BPF skeletons +# # Define EXCLUDE_EXTLIBS=-lmylib to exclude libmylib from the auto-generated # EXTLIBS. # @@ -86,8 +89,6 @@ include ../scripts/utilities.mak # # Define NO_LIBBPF if you do not want BPF support # -# Define NO_LIBCAP if you do not want process capabilities considered by perf -# # Define NO_SDT if you do not want to define SDT event in perf tools, # note that it doesn't disable SDT scanning support. # @@ -251,11 +252,12 @@ else endif # shellcheck is using in tools/perf/tests/Build with option -a/--check-sourced ( -# introduced in v0.4.7) and -S/--severity (introduced in v0.6.0). So make the -# minimal shellcheck version as v0.6.0. +# introduced in v0.4.7) and -S/--severity (introduced in v0.6.0) as well as +# dynamic source inclusions (properly handled since v0.7.2). +# So make the minimal shellcheck version as v0.7.2. ifneq ($(SHELLCHECK),) ifeq ($(shell expr $(shell $(SHELLCHECK) --version | grep version: | \ - sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 060), 1) + sed -e 's/.\+ \([0-9]\+\).\([0-9]\+\).\([0-9]\+\)/\1\2\3/g') \< 072), 1) SHELLCHECK := else SHELLCHECK := $(SHELLCHECK) -s bash -a -S warning @@ -272,7 +274,7 @@ ifeq ($(PYLINT),1) PYLINT := $(shell which pylint 2> /dev/null) endif -export srctree OUTPUT RM CC CXX LD AR CFLAGS CXXFLAGS V BISON FLEX AWK +export srctree OUTPUT RM CC CXX RUSTC LD AR CFLAGS CXXFLAGS RUST_FLAGS V BISON FLEX AWK export HOSTCC HOSTLD HOSTAR HOSTCFLAGS SHELLCHECK MYPY PYLINT include $(srctree)/tools/build/Makefile.include @@ -807,11 +809,6 @@ $(GTK_IN): FORCE prepare $(OUTPUT)libperf-gtk.so: $(GTK_IN) $(PERFLIBS) $(QUIET_LINK)$(CC) -o $@ -shared $(LDFLAGS) $(filter %.o,$^) $(GTK_LIBS) -$(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt - -$(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt) - $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ - $(SCRIPTS) : % : %.sh $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@' @@ -849,7 +846,7 @@ endif __build-dir = $(subst $(OUTPUT),,$(dir $@)) build-dir = $(or $(__build-dir),.) -prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders \ +prepare: $(OUTPUT)PERF-VERSION-FILE archheaders \ arm64-sysreg-defs \ $(syscall_array) \ $(fs_at_flags_array) \ @@ -1053,7 +1050,7 @@ cscope: # However, the environment gets quite big, and some programs have problems # with that. -check: $(OUTPUT)common-cmds.h +check: prepare if sparse; \ then \ for i in *.c */*.c; \ @@ -1250,7 +1247,7 @@ endif $(SKEL_TMP_OUT)/%.bpf.o: $(OUTPUT)PERF-VERSION-FILE util/bpf_skel/perf_version.h | $(SKEL_TMP_OUT) $(SKEL_TMP_OUT)/%.bpf.o: util/bpf_skel/%.bpf.c $(LIBBPF) $(SKEL_OUT)/vmlinux.h $(QUIET_CLANG)$(CLANG) -g -O2 -fno-stack-protector --target=bpf \ - $(CLANG_OPTIONS) $(BPF_INCLUDE) $(TOOLS_UAPI_INCLUDE) \ + $(CLANG_OPTIONS) $(EXTRA_BPF_FLAGS) $(BPF_INCLUDE) $(TOOLS_UAPI_INCLUDE) \ -include $(OUTPUT)PERF-VERSION-FILE -include util/bpf_skel/perf_version.h \ -c $(filter util/bpf_skel/%.bpf.c,$^) -o $@ @@ -1277,6 +1274,8 @@ ifeq ($(OUTPUT),) pmu-events/metric_test.log \ pmu-events/test-empty-pmu-events.c \ pmu-events/empty-pmu-events.log + $(Q)find pmu-events/arch -name 'extra-metrics.json' -delete -o \ + -name 'extra-metricgroups.json' -delete else # When an OUTPUT directory is present, clean up the copied pmu-events/arch directory. $(call QUIET_CLEAN, pmu-events) $(RM) -r $(OUTPUT)pmu-events/arch \ $(OUTPUT)pmu-events/pmu-events.c \ @@ -1296,7 +1295,7 @@ clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $( $(call QUIET_CLEAN, core-progs) $(RM) $(ALL_PROGRAMS) perf perf-read-vdso32 \ perf-read-vdsox32 $(OUTPUT)$(LIBJVMTI).so $(call QUIET_CLEAN, core-gen) $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo \ - $(OUTPUT)common-cmds.h TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE \ + TAGS tags cscope* $(OUTPUT)PERF-VERSION-FILE \ $(OUTPUT)FEATURE-DUMP $(OUTPUT)util/*-bison* $(OUTPUT)util/*-flex* \ $(OUTPUT)util/intel-pt-decoder/inat-tables.c \ $(OUTPUT)tests/llvm-src-{base,kbuild,prologue,relocation}.c \ diff --git a/tools/perf/arch/arc/annotate/instructions.c b/tools/perf/arch/arc/annotate/instructions.c deleted file mode 100644 index e5619770a1af..000000000000 --- a/tools/perf/arch/arc/annotate/instructions.c +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include - -static int arc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) -{ - arch->initialized = true; - arch->objdump.comment_char = ';'; - arch->e_machine = EM_ARC; - arch->e_flags = 0; - return 0; -} diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl index fd09afae72a2..94351e22bfcf 100644 --- a/tools/perf/arch/arm/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl @@ -485,3 +485,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h index 75ce1c370114..20c54766e3a0 100644 --- a/tools/perf/arch/arm/include/perf_regs.h +++ b/tools/perf/arch/arm/include/perf_regs.h @@ -4,7 +4,7 @@ #include #include -#include +#include "../../../../arch/arm/include/uapi/asm/perf_regs.h" void perf_regs_load(u64 *regs); diff --git a/tools/perf/arch/arm/util/Build b/tools/perf/arch/arm/util/Build index fd695e1fdaee..b94bf3c5279a 100644 --- a/tools/perf/arch/arm/util/Build +++ b/tools/perf/arch/arm/util/Build @@ -1,6 +1,3 @@ -perf-util-y += perf_regs.o - perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += pmu.o auxtrace.o cs-etm.o diff --git a/tools/perf/arch/arm/util/cs-etm.c b/tools/perf/arch/arm/util/cs-etm.c index ea891d12f8f4..4418d21708d6 100644 --- a/tools/perf/arch/arm/util/cs-etm.c +++ b/tools/perf/arch/arm/util/cs-etm.c @@ -89,13 +89,14 @@ static int cs_etm_validate_context_id(struct perf_pmu *cs_etm_pmu, struct evsel struct perf_cpu cpu) { int err; - __u64 val; - u64 contextid = evsel->core.attr.config & - (perf_pmu__format_bits(cs_etm_pmu, "contextid") | - perf_pmu__format_bits(cs_etm_pmu, "contextid1") | - perf_pmu__format_bits(cs_etm_pmu, "contextid2")); + u64 ctxt, ctxt1, ctxt2; + __u64 trcidr2; - if (!contextid) + evsel__get_config_val(evsel, "contextid", &ctxt); + evsel__get_config_val(evsel, "contextid1", &ctxt1); + evsel__get_config_val(evsel, "contextid2", &ctxt2); + + if (!ctxt && !ctxt1 && !ctxt2) return 0; /* Not supported in etmv3 */ @@ -106,12 +107,11 @@ static int cs_etm_validate_context_id(struct perf_pmu *cs_etm_pmu, struct evsel } /* Get a handle on TRCIDR2 */ - err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2], &val); + err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR2], &trcidr2); if (err) return err; - if (contextid & - perf_pmu__format_bits(cs_etm_pmu, "contextid1")) { + if (ctxt1) { /* * TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID * tracing is supported: @@ -119,15 +119,14 @@ static int cs_etm_validate_context_id(struct perf_pmu *cs_etm_pmu, struct evsel * 0b00100 Maximum of 32-bit Context ID size. * All other values are reserved. */ - if (BMVAL(val, 5, 9) != 0x4) { + if (BMVAL(trcidr2, 5, 9) != 0x4) { pr_err("%s: CONTEXTIDR_EL1 isn't supported, disable with %s/contextid1=0/\n", CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME); return -EINVAL; } } - if (contextid & - perf_pmu__format_bits(cs_etm_pmu, "contextid2")) { + if (ctxt2) { /* * TRCIDR2.VMIDOPT[30:29] != 0 and * TRCIDR2.VMIDSIZE[14:10] == 0b00100 (32bit virtual contextid) @@ -135,7 +134,7 @@ static int cs_etm_validate_context_id(struct perf_pmu *cs_etm_pmu, struct evsel * virtual context id is < 32bit. * Any value of VMIDSIZE >= 4 (i.e, > 32bit) is fine for us. */ - if (!BMVAL(val, 29, 30) || BMVAL(val, 10, 14) < 4) { + if (!BMVAL(trcidr2, 29, 30) || BMVAL(trcidr2, 10, 14) < 4) { pr_err("%s: CONTEXTIDR_EL2 isn't supported, disable with %s/contextid2=0/\n", CORESIGHT_ETM_PMU_NAME, CORESIGHT_ETM_PMU_NAME); return -EINVAL; @@ -149,10 +148,11 @@ static int cs_etm_validate_timestamp(struct perf_pmu *cs_etm_pmu, struct evsel * struct perf_cpu cpu) { int err; - __u64 val; + u64 val; + __u64 trcidr0; - if (!(evsel->core.attr.config & - perf_pmu__format_bits(cs_etm_pmu, "timestamp"))) + evsel__get_config_val(evsel, "timestamp", &val); + if (!val) return 0; if (cs_etm_get_version(cs_etm_pmu, cpu) == CS_ETMV3) { @@ -162,7 +162,7 @@ static int cs_etm_validate_timestamp(struct perf_pmu *cs_etm_pmu, struct evsel * } /* Get a handle on TRCIRD0 */ - err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0], &val); + err = cs_etm_get_ro(cs_etm_pmu, cpu, metadata_etmv4_ro[CS_ETMV4_TRCIDR0], &trcidr0); if (err) return err; @@ -173,10 +173,9 @@ static int cs_etm_validate_timestamp(struct perf_pmu *cs_etm_pmu, struct evsel * * 0b00110 Implementation supports a maximum timestamp of 48bits. * 0b01000 Implementation supports a maximum timestamp of 64bits. */ - val &= GENMASK(28, 24); - if (!val) { + trcidr0 &= GENMASK(28, 24); + if (!trcidr0) return -EINVAL; - } return 0; } @@ -259,16 +258,19 @@ static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr, return 0; } +/* + * If the sink name format "@sink_name" is used, lookup the sink by name to convert to + * "sinkid=sink_hash" format. If the user has already manually provided a hash then + * "sinkid" isn't overwritten. If neither are provided then the driver will pick the best + * sink. + */ static int cs_etm_set_sink_attr(struct perf_pmu *pmu, struct evsel *evsel) { char msg[BUFSIZ], path[PATH_MAX], *sink; struct evsel_config_term *term; - int ret = -EINVAL; u32 hash; - - if (evsel->core.attr.config2 & GENMASK(31, 0)) - return 0; + int ret; list_for_each_entry(term, &evsel->config_terms, list) { if (term->type != EVSEL__CONFIG_TERM_DRV_CFG) @@ -291,17 +293,26 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu, return ret; } - evsel->core.attr.config2 |= hash; + evsel__set_config_if_unset(evsel, "sinkid", hash); return 0; } - /* - * No sink was provided on the command line - allow the CoreSight - * system to look for a default - */ return 0; } +static struct evsel *cs_etm_get_evsel(struct evlist *evlist, + struct perf_pmu *cs_etm_pmu) +{ + struct evsel *evsel; + + evlist__for_each_entry(evlist, evsel) { + if (evsel->core.attr.type == cs_etm_pmu->type) + return evsel; + } + + return NULL; +} + static int cs_etm_recording_options(struct auxtrace_record *itr, struct evlist *evlist, struct record_opts *opts) @@ -441,10 +452,8 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, * when a context switch happened. */ if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) { - evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, - "timestamp", 1); - evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, - "contextid", 1); + evsel__set_config_if_unset(cs_etm_evsel, "timestamp", 1); + evsel__set_config_if_unset(cs_etm_evsel, "contextid", 1); } /* @@ -453,8 +462,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, * timestamp tracing. */ if (opts->sample_time_set) - evsel__set_config_if_unset(cs_etm_pmu, cs_etm_evsel, - "timestamp", 1); + evsel__set_config_if_unset(cs_etm_evsel, "timestamp", 1); /* Add dummy event to keep tracking */ err = parse_event(evlist, "dummy:u"); @@ -474,64 +482,64 @@ static int cs_etm_recording_options(struct auxtrace_record *itr, return err; } -static u64 cs_etm_get_config(struct auxtrace_record *itr) +static u64 cs_etm_synth_etmcr(struct auxtrace_record *itr) { - u64 config = 0; struct cs_etm_recording *ptr = - container_of(itr, struct cs_etm_recording, itr); + container_of(itr, struct cs_etm_recording, itr); struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; - struct evlist *evlist = ptr->evlist; - struct evsel *evsel; + struct evsel *evsel = cs_etm_get_evsel(ptr->evlist, cs_etm_pmu); + u64 etmcr = 0; + u64 val; - evlist__for_each_entry(evlist, evsel) { - if (evsel->core.attr.type == cs_etm_pmu->type) { - /* - * Variable perf_event_attr::config is assigned to - * ETMv3/PTM. The bit fields have been made to match - * the ETMv3.5 ETRMCR register specification. See the - * PMU_FORMAT_ATTR() declarations in - * drivers/hwtracing/coresight/coresight-perf.c for - * details. - */ - config = evsel->core.attr.config; - break; - } - } - - return config; -} - -#ifndef BIT -#define BIT(N) (1UL << (N)) -#endif - -static u64 cs_etmv4_get_config(struct auxtrace_record *itr) -{ - u64 config = 0; - u64 config_opts = 0; + if (!evsel) + return 0; /* - * The perf event variable config bits represent both - * the command line options and register programming - * bits in ETMv3/PTM. For ETMv4 we must remap options - * to real bits + * Synthesize what the kernel programmed into ETMCR based on + * what options the event was opened with. This doesn't have to be + * complete or 100% accurate, not all bits used by OpenCSD anyway. */ - config_opts = cs_etm_get_config(itr); - if (config_opts & BIT(ETM_OPT_CYCACC)) - config |= BIT(ETM4_CFG_BIT_CYCACC); - if (config_opts & BIT(ETM_OPT_CTXTID)) - config |= BIT(ETM4_CFG_BIT_CTXTID); - if (config_opts & BIT(ETM_OPT_TS)) - config |= BIT(ETM4_CFG_BIT_TS); - if (config_opts & BIT(ETM_OPT_RETSTK)) - config |= BIT(ETM4_CFG_BIT_RETSTK); - if (config_opts & BIT(ETM_OPT_CTXTID2)) - config |= BIT(ETM4_CFG_BIT_VMID) | - BIT(ETM4_CFG_BIT_VMID_OPT); - if (config_opts & BIT(ETM_OPT_BRANCH_BROADCAST)) - config |= BIT(ETM4_CFG_BIT_BB); + if (!evsel__get_config_val(evsel, "cycacc", &val) && val) + etmcr |= ETMCR_CYC_ACC; + if (!evsel__get_config_val(evsel, "timestamp", &val) && val) + etmcr |= ETMCR_TIMESTAMP_EN; + if (!evsel__get_config_val(evsel, "retstack", &val) && val) + etmcr |= ETMCR_RETURN_STACK; - return config; + return etmcr; +} + +static u64 cs_etmv4_synth_trcconfigr(struct auxtrace_record *itr) +{ + u64 trcconfigr = 0; + struct cs_etm_recording *ptr = + container_of(itr, struct cs_etm_recording, itr); + struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; + struct evsel *evsel = cs_etm_get_evsel(ptr->evlist, cs_etm_pmu); + u64 val; + + if (!evsel) + return 0; + + /* + * Synthesize what the kernel programmed into TRCCONFIGR based on + * what options the event was opened with. This doesn't have to be + * complete or 100% accurate, not all bits used by OpenCSD anyway. + */ + if (!evsel__get_config_val(evsel, "cycacc", &val) && val) + trcconfigr |= TRCCONFIGR_CCI; + if (!evsel__get_config_val(evsel, "contextid1", &val) && val) + trcconfigr |= TRCCONFIGR_CID; + if (!evsel__get_config_val(evsel, "timestamp", &val) && val) + trcconfigr |= TRCCONFIGR_TS; + if (!evsel__get_config_val(evsel, "retstack", &val) && val) + trcconfigr |= TRCCONFIGR_RS; + if (!evsel__get_config_val(evsel, "contextid2", &val) && val) + trcconfigr |= TRCCONFIGR_VMID | TRCCONFIGR_VMIDOPT; + if (!evsel__get_config_val(evsel, "branch_broadcast", &val) && val) + trcconfigr |= TRCCONFIGR_BB; + + return trcconfigr; } static size_t @@ -653,7 +661,7 @@ static void cs_etm_save_etmv4_header(__u64 data[], struct auxtrace_record *itr, struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; /* Get trace configuration register */ - data[CS_ETMV4_TRCCONFIGR] = cs_etmv4_get_config(itr); + data[CS_ETMV4_TRCCONFIGR] = cs_etmv4_synth_trcconfigr(itr); /* traceID set to legacy version, in case new perf running on older system */ data[CS_ETMV4_TRCTRACEIDR] = cs_etm_get_legacy_trace_id(cpu); @@ -685,7 +693,7 @@ static void cs_etm_save_ete_header(__u64 data[], struct auxtrace_record *itr, st struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu; /* Get trace configuration register */ - data[CS_ETE_TRCCONFIGR] = cs_etmv4_get_config(itr); + data[CS_ETE_TRCCONFIGR] = cs_etmv4_synth_trcconfigr(itr); /* traceID set to legacy version, in case new perf running on older system */ data[CS_ETE_TRCTRACEIDR] = cs_etm_get_legacy_trace_id(cpu); @@ -741,7 +749,7 @@ static void cs_etm_get_metadata(struct perf_cpu cpu, u32 *offset, case CS_ETMV3: magic = __perf_cs_etmv3_magic; /* Get configuration register */ - info->priv[*offset + CS_ETM_ETMCR] = cs_etm_get_config(itr); + info->priv[*offset + CS_ETM_ETMCR] = cs_etm_synth_etmcr(itr); /* traceID set to legacy value in case new perf running on old system */ info->priv[*offset + CS_ETM_ETMTRACEIDR] = cs_etm_get_legacy_trace_id(cpu); /* Get read-only information from sysFS */ @@ -832,12 +840,11 @@ static int cs_etm_snapshot_start(struct auxtrace_record *itr) { struct cs_etm_recording *ptr = container_of(itr, struct cs_etm_recording, itr); - struct evsel *evsel; + struct evsel *evsel = cs_etm_get_evsel(ptr->evlist, ptr->cs_etm_pmu); + + if (evsel) + return evsel__disable(evsel); - evlist__for_each_entry(ptr->evlist, evsel) { - if (evsel->core.attr.type == ptr->cs_etm_pmu->type) - return evsel__disable(evsel); - } return -EINVAL; } diff --git a/tools/perf/arch/arm/util/perf_regs.c b/tools/perf/arch/arm/util/perf_regs.c deleted file mode 100644 index f94a0210c7b7..000000000000 --- a/tools/perf/arch/arm/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/arm/util/unwind-libdw.c b/tools/perf/arch/arm/util/unwind-libdw.c deleted file mode 100644 index fbb643f224ec..000000000000 --- a/tools/perf/arch/arm/util/unwind-libdw.c +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[PERF_REG_ARM_MAX]; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_ARM_##r); \ - val; \ -}) - - dwarf_regs[0] = REG(R0); - dwarf_regs[1] = REG(R1); - dwarf_regs[2] = REG(R2); - dwarf_regs[3] = REG(R3); - dwarf_regs[4] = REG(R4); - dwarf_regs[5] = REG(R5); - dwarf_regs[6] = REG(R6); - dwarf_regs[7] = REG(R7); - dwarf_regs[8] = REG(R8); - dwarf_regs[9] = REG(R9); - dwarf_regs[10] = REG(R10); - dwarf_regs[11] = REG(FP); - dwarf_regs[12] = REG(IP); - dwarf_regs[13] = REG(SP); - dwarf_regs[14] = REG(LR); - dwarf_regs[15] = REG(PC); - - return dwfl_thread_state_registers(thread, 0, PERF_REG_ARM_MAX, - dwarf_regs); -} diff --git a/tools/perf/arch/arm64/Makefile b/tools/perf/arch/arm64/Makefile index 087e099fb453..44cc3f023318 100644 --- a/tools/perf/arch/arm64/Makefile +++ b/tools/perf/arch/arm64/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 PERF_HAVE_JITDUMP := 1 -HAVE_KVM_STAT_SUPPORT := 1 diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h index 58639ee9f7ea..372f2565a9dd 100644 --- a/tools/perf/arch/arm64/include/perf_regs.h +++ b/tools/perf/arch/arm64/include/perf_regs.h @@ -5,7 +5,7 @@ #include #include #define perf_event_arm_regs perf_event_arm64_regs -#include +#include "../../../../arch/arm64/include/uapi/asm/perf_regs.h" #undef perf_event_arm_regs void perf_regs_load(u64 *regs); diff --git a/tools/perf/arch/arm64/util/Build b/tools/perf/arch/arm64/util/Build index d63881081d2e..4e06a08d281a 100644 --- a/tools/perf/arch/arm64/util/Build +++ b/tools/perf/arch/arm64/util/Build @@ -1,5 +1,3 @@ -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-y += ../../arm/util/auxtrace.o perf-util-y += ../../arm/util/cs-etm.o @@ -9,6 +7,5 @@ perf-util-y += header.o perf-util-y += hisi-ptt.o perf-util-y += machine.o perf-util-y += mem-events.o -perf-util-y += perf_regs.o perf-util-y += pmu.o perf-util-y += tsc.o diff --git a/tools/perf/arch/arm64/util/arm-spe.c b/tools/perf/arch/arm64/util/arm-spe.c index d5ec1408d0ae..17ced7bbbdda 100644 --- a/tools/perf/arch/arm64/util/arm-spe.c +++ b/tools/perf/arch/arm64/util/arm-spe.c @@ -256,7 +256,7 @@ static __u64 arm_spe_pmu__sample_period(const struct perf_pmu *arm_spe_pmu) static void arm_spe_setup_evsel(struct evsel *evsel, struct perf_cpu_map *cpus) { - u64 bit; + u64 pa_enable_bit; evsel->core.attr.freq = 0; evsel->core.attr.sample_period = arm_spe_pmu__sample_period(evsel->pmu); @@ -274,7 +274,7 @@ static void arm_spe_setup_evsel(struct evsel *evsel, struct perf_cpu_map *cpus) */ if (!perf_cpu_map__is_any_cpu_or_is_empty(cpus)) { evsel__set_sample_bit(evsel, CPU); - evsel__set_config_if_unset(evsel->pmu, evsel, "ts_enable", 1); + evsel__set_config_if_unset(evsel, "ts_enable", 1); } /* @@ -288,9 +288,10 @@ static void arm_spe_setup_evsel(struct evsel *evsel, struct perf_cpu_map *cpus) * inform that the resulting output's SPE samples contain physical addresses * where applicable. */ - bit = perf_pmu__format_bits(evsel->pmu, "pa_enable"); - if (evsel->core.attr.config & bit) - evsel__set_sample_bit(evsel, PHYS_ADDR); + + if (!evsel__get_config_val(evsel, "pa_enable", &pa_enable_bit)) + if (pa_enable_bit) + evsel__set_sample_bit(evsel, PHYS_ADDR); } static int arm_spe_setup_aux_buffer(struct record_opts *opts) @@ -397,6 +398,7 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, struct perf_cpu_map *cpus = evlist->core.user_requested_cpus; bool discard = false; int err; + u64 discard_bit; sper->evlist = evlist; @@ -425,9 +427,8 @@ static int arm_spe_recording_options(struct auxtrace_record *itr, evlist__for_each_entry_safe(evlist, tmp, evsel) { if (evsel__is_aux_event(evsel)) { arm_spe_setup_evsel(evsel, cpus); - if (evsel->core.attr.config & - perf_pmu__format_bits(evsel->pmu, "discard")) - discard = true; + if (!evsel__get_config_val(evsel, "discard", &discard_bit)) + discard = !!discard_bit; } } diff --git a/tools/perf/arch/arm64/util/header.c b/tools/perf/arch/arm64/util/header.c index f445a2dd6293..cbc0ba101636 100644 --- a/tools/perf/arch/arm64/util/header.c +++ b/tools/perf/arch/arm64/util/header.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/tools/perf/arch/arm64/util/machine.c b/tools/perf/arch/arm64/util/machine.c index aab1cc2bc283..80fb13c958d9 100644 --- a/tools/perf/arch/arm64/util/machine.c +++ b/tools/perf/arch/arm64/util/machine.c @@ -1,18 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include "debug.h" -#include "symbol.h" -#include "callchain.h" +#include "callchain.h" // prototype of arch__add_leaf_frame_record_opts #include "perf_regs.h" #include "record.h" -#include "util/perf_regs.h" + +#define SMPL_REG_MASK(b) (1ULL << (b)) void arch__add_leaf_frame_record_opts(struct record_opts *opts) { - const struct sample_reg *sample_reg_masks = arch__sample_reg_masks(); - - opts->sample_user_regs |= sample_reg_masks[PERF_REG_ARM64_LR].mask; + opts->sample_user_regs |= SMPL_REG_MASK(PERF_REG_ARM64_LR); } diff --git a/tools/perf/arch/arm64/util/mem-events.c b/tools/perf/arch/arm64/util/mem-events.c index 9f8da7937255..eaf00e0609c6 100644 --- a/tools/perf/arch/arm64/util/mem-events.c +++ b/tools/perf/arch/arm64/util/mem-events.c @@ -6,7 +6,7 @@ #define E(t, n, s, l, a) { .tag = t, .name = n, .event_name = s, .ldlat = l, .aux_event = a } struct perf_mem_event perf_mem_events_arm[PERF_MEM_EVENTS__MAX] = { - E("spe-load", "%s/ts_enable=1,pa_enable=1,load_filter=1,store_filter=0,min_latency=%u/", NULL, true, 0), - E("spe-store", "%s/ts_enable=1,pa_enable=1,load_filter=0,store_filter=1/", NULL, false, 0), + E("spe-load", "%s/ts_enable=1,pa_enable=1,load_filter=1,min_latency=%u/", NULL, true, 0), + E("spe-store", "%s/ts_enable=1,pa_enable=1,store_filter=1/", NULL, false, 0), E("spe-ldst", "%s/ts_enable=1,pa_enable=1,load_filter=1,store_filter=1,min_latency=%u/", NULL, true, 0), }; diff --git a/tools/perf/arch/arm64/util/perf_regs.c b/tools/perf/arch/arm64/util/perf_regs.c deleted file mode 100644 index 09308665e28a..000000000000 --- a/tools/perf/arch/arm64/util/perf_regs.c +++ /dev/null @@ -1,182 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include -#include - -#include "perf_regs.h" -#include "../../../perf-sys.h" -#include "../../../util/debug.h" -#include "../../../util/event.h" -#include "../../../util/perf_regs.h" - -#ifndef HWCAP_SVE -#define HWCAP_SVE (1 << 22) -#endif - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG(x0, PERF_REG_ARM64_X0), - SMPL_REG(x1, PERF_REG_ARM64_X1), - SMPL_REG(x2, PERF_REG_ARM64_X2), - SMPL_REG(x3, PERF_REG_ARM64_X3), - SMPL_REG(x4, PERF_REG_ARM64_X4), - SMPL_REG(x5, PERF_REG_ARM64_X5), - SMPL_REG(x6, PERF_REG_ARM64_X6), - SMPL_REG(x7, PERF_REG_ARM64_X7), - SMPL_REG(x8, PERF_REG_ARM64_X8), - SMPL_REG(x9, PERF_REG_ARM64_X9), - SMPL_REG(x10, PERF_REG_ARM64_X10), - SMPL_REG(x11, PERF_REG_ARM64_X11), - SMPL_REG(x12, PERF_REG_ARM64_X12), - SMPL_REG(x13, PERF_REG_ARM64_X13), - SMPL_REG(x14, PERF_REG_ARM64_X14), - SMPL_REG(x15, PERF_REG_ARM64_X15), - SMPL_REG(x16, PERF_REG_ARM64_X16), - SMPL_REG(x17, PERF_REG_ARM64_X17), - SMPL_REG(x18, PERF_REG_ARM64_X18), - SMPL_REG(x19, PERF_REG_ARM64_X19), - SMPL_REG(x20, PERF_REG_ARM64_X20), - SMPL_REG(x21, PERF_REG_ARM64_X21), - SMPL_REG(x22, PERF_REG_ARM64_X22), - SMPL_REG(x23, PERF_REG_ARM64_X23), - SMPL_REG(x24, PERF_REG_ARM64_X24), - SMPL_REG(x25, PERF_REG_ARM64_X25), - SMPL_REG(x26, PERF_REG_ARM64_X26), - SMPL_REG(x27, PERF_REG_ARM64_X27), - SMPL_REG(x28, PERF_REG_ARM64_X28), - SMPL_REG(x29, PERF_REG_ARM64_X29), - SMPL_REG(lr, PERF_REG_ARM64_LR), - SMPL_REG(sp, PERF_REG_ARM64_SP), - SMPL_REG(pc, PERF_REG_ARM64_PC), - SMPL_REG(vg, PERF_REG_ARM64_VG), - SMPL_REG_END -}; - -/* %xNUM */ -#define SDT_OP_REGEX1 "^(x[1-2]?[0-9]|3[0-1])$" - -/* [sp], [sp, NUM] */ -#define SDT_OP_REGEX2 "^\\[sp(, )?([0-9]+)?\\]$" - -static regex_t sdt_op_regex1, sdt_op_regex2; - -static int sdt_init_op_regex(void) -{ - static int initialized; - int ret = 0; - - if (initialized) - return 0; - - ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED); - if (ret) - goto error; - - ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED); - if (ret) - goto free_regex1; - - initialized = 1; - return 0; - -free_regex1: - regfree(&sdt_op_regex1); -error: - pr_debug4("Regex compilation error.\n"); - return ret; -} - -/* - * SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently - * support these two formats. - */ -int arch_sdt_arg_parse_op(char *old_op, char **new_op) -{ - int ret, new_len; - regmatch_t rm[5]; - - ret = sdt_init_op_regex(); - if (ret < 0) - return ret; - - if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) { - /* Extract xNUM */ - new_len = 2; /* % NULL */ - new_len += (int)(rm[1].rm_eo - rm[1].rm_so); - - *new_op = zalloc(new_len); - if (!*new_op) - return -ENOMEM; - - scnprintf(*new_op, new_len, "%%%.*s", - (int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so); - } else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) { - /* [sp], [sp, NUM] or [sp,NUM] */ - new_len = 7; /* + ( % s p ) NULL */ - - /* If the argument is [sp], need to fill offset '0' */ - if (rm[2].rm_so == -1) - new_len += 1; - else - new_len += (int)(rm[2].rm_eo - rm[2].rm_so); - - *new_op = zalloc(new_len); - if (!*new_op) - return -ENOMEM; - - if (rm[2].rm_so == -1) - scnprintf(*new_op, new_len, "+0(%%sp)"); - else - scnprintf(*new_op, new_len, "+%.*s(%%sp)", - (int)(rm[2].rm_eo - rm[2].rm_so), - old_op + rm[2].rm_so); - } else { - pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); - return SDT_ARG_SKIP; - } - - return SDT_ARG_VALID; -} - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - .sample_type = PERF_SAMPLE_REGS_USER, - .disabled = 1, - .exclude_kernel = 1, - .sample_period = 1, - .sample_regs_user = PERF_REGS_MASK - }; - int fd; - - if (getauxval(AT_HWCAP) & HWCAP_SVE) - attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG); - - /* - * Check if the pmu supports perf extended regs, before - * returning the register mask to sample. - */ - if (attr.sample_regs_user != PERF_REGS_MASK) { - event_attr_init(&attr); - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd != -1) { - close(fd); - return attr.sample_regs_user; - } - } - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/arm64/util/unwind-libdw.c b/tools/perf/arch/arm64/util/unwind-libdw.c deleted file mode 100644 index b89b0a7e5ad9..000000000000 --- a/tools/perf/arch/arm64/util/unwind-libdw.c +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[PERF_REG_ARM64_MAX], dwarf_pc; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_ARM64_##r); \ - val; \ -}) - - dwarf_regs[0] = REG(X0); - dwarf_regs[1] = REG(X1); - dwarf_regs[2] = REG(X2); - dwarf_regs[3] = REG(X3); - dwarf_regs[4] = REG(X4); - dwarf_regs[5] = REG(X5); - dwarf_regs[6] = REG(X6); - dwarf_regs[7] = REG(X7); - dwarf_regs[8] = REG(X8); - dwarf_regs[9] = REG(X9); - dwarf_regs[10] = REG(X10); - dwarf_regs[11] = REG(X11); - dwarf_regs[12] = REG(X12); - dwarf_regs[13] = REG(X13); - dwarf_regs[14] = REG(X14); - dwarf_regs[15] = REG(X15); - dwarf_regs[16] = REG(X16); - dwarf_regs[17] = REG(X17); - dwarf_regs[18] = REG(X18); - dwarf_regs[19] = REG(X19); - dwarf_regs[20] = REG(X20); - dwarf_regs[21] = REG(X21); - dwarf_regs[22] = REG(X22); - dwarf_regs[23] = REG(X23); - dwarf_regs[24] = REG(X24); - dwarf_regs[25] = REG(X25); - dwarf_regs[26] = REG(X26); - dwarf_regs[27] = REG(X27); - dwarf_regs[28] = REG(X28); - dwarf_regs[29] = REG(X29); - dwarf_regs[30] = REG(LR); - dwarf_regs[31] = REG(SP); - - if (!dwfl_thread_state_registers(thread, 0, PERF_REG_ARM64_MAX, - dwarf_regs)) - return false; - - dwarf_pc = REG(PC); - dwfl_thread_state_register_pc(thread, dwarf_pc); - - return true; -} diff --git a/tools/perf/arch/csky/Build b/tools/perf/arch/csky/Build deleted file mode 100644 index e63eabc2c8f4..000000000000 --- a/tools/perf/arch/csky/Build +++ /dev/null @@ -1 +0,0 @@ -perf-util-y += util/ diff --git a/tools/perf/arch/csky/include/perf_regs.h b/tools/perf/arch/csky/include/perf_regs.h index 076c7746c8a2..0bf7b963909c 100644 --- a/tools/perf/arch/csky/include/perf_regs.h +++ b/tools/perf/arch/csky/include/perf_regs.h @@ -6,7 +6,7 @@ #include #include -#include +#include "../../../../arch/csky/include/uapi/asm/perf_regs.h" #define PERF_REGS_MASK ((1ULL << PERF_REG_CSKY_MAX) - 1) #define PERF_REGS_MAX PERF_REG_CSKY_MAX diff --git a/tools/perf/arch/csky/util/Build b/tools/perf/arch/csky/util/Build deleted file mode 100644 index 5e6ea82c4202..000000000000 --- a/tools/perf/arch/csky/util/Build +++ /dev/null @@ -1,3 +0,0 @@ -perf-util-y += perf_regs.o - -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/csky/util/perf_regs.c b/tools/perf/arch/csky/util/perf_regs.c deleted file mode 100644 index 6b1665f41180..000000000000 --- a/tools/perf/arch/csky/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/csky/util/unwind-libdw.c b/tools/perf/arch/csky/util/unwind-libdw.c deleted file mode 100644 index b20b1569783d..000000000000 --- a/tools/perf/arch/csky/util/unwind-libdw.c +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. - -#include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/event.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[PERF_REG_CSKY_MAX]; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_CSKY_##r); \ - val; \ -}) - -#if defined(__CSKYABIV2__) - dwarf_regs[0] = REG(A0); - dwarf_regs[1] = REG(A1); - dwarf_regs[2] = REG(A2); - dwarf_regs[3] = REG(A3); - dwarf_regs[4] = REG(REGS0); - dwarf_regs[5] = REG(REGS1); - dwarf_regs[6] = REG(REGS2); - dwarf_regs[7] = REG(REGS3); - dwarf_regs[8] = REG(REGS4); - dwarf_regs[9] = REG(REGS5); - dwarf_regs[10] = REG(REGS6); - dwarf_regs[11] = REG(REGS7); - dwarf_regs[12] = REG(REGS8); - dwarf_regs[13] = REG(REGS9); - dwarf_regs[14] = REG(SP); - dwarf_regs[15] = REG(LR); - dwarf_regs[16] = REG(EXREGS0); - dwarf_regs[17] = REG(EXREGS1); - dwarf_regs[18] = REG(EXREGS2); - dwarf_regs[19] = REG(EXREGS3); - dwarf_regs[20] = REG(EXREGS4); - dwarf_regs[21] = REG(EXREGS5); - dwarf_regs[22] = REG(EXREGS6); - dwarf_regs[23] = REG(EXREGS7); - dwarf_regs[24] = REG(EXREGS8); - dwarf_regs[25] = REG(EXREGS9); - dwarf_regs[26] = REG(EXREGS10); - dwarf_regs[27] = REG(EXREGS11); - dwarf_regs[28] = REG(EXREGS12); - dwarf_regs[29] = REG(EXREGS13); - dwarf_regs[30] = REG(EXREGS14); - dwarf_regs[31] = REG(TLS); - dwarf_regs[32] = REG(PC); -#else - dwarf_regs[0] = REG(SP); - dwarf_regs[1] = REG(REGS9); - dwarf_regs[2] = REG(A0); - dwarf_regs[3] = REG(A1); - dwarf_regs[4] = REG(A2); - dwarf_regs[5] = REG(A3); - dwarf_regs[6] = REG(REGS0); - dwarf_regs[7] = REG(REGS1); - dwarf_regs[8] = REG(REGS2); - dwarf_regs[9] = REG(REGS3); - dwarf_regs[10] = REG(REGS4); - dwarf_regs[11] = REG(REGS5); - dwarf_regs[12] = REG(REGS6); - dwarf_regs[13] = REG(REGS7); - dwarf_regs[14] = REG(REGS8); - dwarf_regs[15] = REG(LR); -#endif - dwfl_thread_state_register_pc(thread, REG(PC)); - - return dwfl_thread_state_registers(thread, 0, PERF_REG_CSKY_MAX, - dwarf_regs); -} diff --git a/tools/perf/arch/loongarch/Makefile b/tools/perf/arch/loongarch/Makefile index 087e099fb453..44cc3f023318 100644 --- a/tools/perf/arch/loongarch/Makefile +++ b/tools/perf/arch/loongarch/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 PERF_HAVE_JITDUMP := 1 -HAVE_KVM_STAT_SUPPORT := 1 diff --git a/tools/perf/arch/loongarch/include/perf_regs.h b/tools/perf/arch/loongarch/include/perf_regs.h index 45c799fa5330..b86078a55e90 100644 --- a/tools/perf/arch/loongarch/include/perf_regs.h +++ b/tools/perf/arch/loongarch/include/perf_regs.h @@ -4,7 +4,7 @@ #include #include -#include +#include "../../../../arch/loongarch/include/uapi/asm/perf_regs.h" #define PERF_REGS_MAX PERF_REG_LOONGARCH_MAX diff --git a/tools/perf/arch/loongarch/util/Build b/tools/perf/arch/loongarch/util/Build index 0aa31986ecb5..3ad73d0289f3 100644 --- a/tools/perf/arch/loongarch/util/Build +++ b/tools/perf/arch/loongarch/util/Build @@ -1,6 +1,4 @@ perf-util-y += header.o -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o diff --git a/tools/perf/arch/loongarch/util/perf_regs.c b/tools/perf/arch/loongarch/util/perf_regs.c deleted file mode 100644 index f94a0210c7b7..000000000000 --- a/tools/perf/arch/loongarch/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/loongarch/util/unwind-libdw.c b/tools/perf/arch/loongarch/util/unwind-libdw.c deleted file mode 100644 index 60b1144bedd5..000000000000 --- a/tools/perf/arch/loongarch/util/unwind-libdw.c +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ - -#include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/sample.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[PERF_REG_LOONGARCH_MAX]; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_LOONGARCH_##r); \ - val; \ -}) - - dwarf_regs[0] = 0; - dwarf_regs[1] = REG(R1); - dwarf_regs[2] = REG(R2); - dwarf_regs[3] = REG(R3); - dwarf_regs[4] = REG(R4); - dwarf_regs[5] = REG(R5); - dwarf_regs[6] = REG(R6); - dwarf_regs[7] = REG(R7); - dwarf_regs[8] = REG(R8); - dwarf_regs[9] = REG(R9); - dwarf_regs[10] = REG(R10); - dwarf_regs[11] = REG(R11); - dwarf_regs[12] = REG(R12); - dwarf_regs[13] = REG(R13); - dwarf_regs[14] = REG(R14); - dwarf_regs[15] = REG(R15); - dwarf_regs[16] = REG(R16); - dwarf_regs[17] = REG(R17); - dwarf_regs[18] = REG(R18); - dwarf_regs[19] = REG(R19); - dwarf_regs[20] = REG(R20); - dwarf_regs[21] = REG(R21); - dwarf_regs[22] = REG(R22); - dwarf_regs[23] = REG(R23); - dwarf_regs[24] = REG(R24); - dwarf_regs[25] = REG(R25); - dwarf_regs[26] = REG(R26); - dwarf_regs[27] = REG(R27); - dwarf_regs[28] = REG(R28); - dwarf_regs[29] = REG(R29); - dwarf_regs[30] = REG(R30); - dwarf_regs[31] = REG(R31); - dwfl_thread_state_register_pc(thread, REG(PC)); - - return dwfl_thread_state_registers(thread, 0, PERF_REG_LOONGARCH_MAX, dwarf_regs); -} diff --git a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl index 9b92bddf06b5..630aab9e5425 100644 --- a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl +++ b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl @@ -385,3 +385,4 @@ 468 n64 file_getattr sys_file_getattr 469 n64 file_setattr sys_file_setattr 470 n64 listns sys_listns +471 n64 rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/mips/include/perf_regs.h b/tools/perf/arch/mips/include/perf_regs.h index 7082e91e0ed1..66655f0c4fea 100644 --- a/tools/perf/arch/mips/include/perf_regs.h +++ b/tools/perf/arch/mips/include/perf_regs.h @@ -4,7 +4,7 @@ #include #include -#include +#include "../../../../arch/mips/include/uapi/asm/perf_regs.h" #define PERF_REGS_MAX PERF_REG_MIPS_MAX diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Build index 691fa2051958..818b808a8247 100644 --- a/tools/perf/arch/mips/util/Build +++ b/tools/perf/arch/mips/util/Build @@ -1,2 +1 @@ -perf-util-y += perf_regs.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o diff --git a/tools/perf/arch/mips/util/perf_regs.c b/tools/perf/arch/mips/util/perf_regs.c deleted file mode 100644 index 6b1665f41180..000000000000 --- a/tools/perf/arch/mips/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/powerpc/Makefile b/tools/perf/arch/powerpc/Makefile index a295a80ea078..44cc3f023318 100644 --- a/tools/perf/arch/powerpc/Makefile +++ b/tools/perf/arch/powerpc/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -HAVE_KVM_STAT_SUPPORT := 1 PERF_HAVE_JITDUMP := 1 diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl index ec4458cdb97b..4fcc7c58a105 100644 --- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl @@ -561,3 +561,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 nospu rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/powerpc/include/perf_regs.h b/tools/perf/arch/powerpc/include/perf_regs.h index 1c66f6ba6773..22b492a3dd58 100644 --- a/tools/perf/arch/powerpc/include/perf_regs.h +++ b/tools/perf/arch/powerpc/include/perf_regs.h @@ -4,7 +4,7 @@ #include #include -#include +#include "../../../../arch/powerpc/include/uapi/asm/perf_regs.h" void perf_regs_load(u64 *regs); diff --git a/tools/perf/arch/powerpc/util/Build b/tools/perf/arch/powerpc/util/Build index 3d0d5427aef7..d66574cbb9a9 100644 --- a/tools/perf/arch/powerpc/util/Build +++ b/tools/perf/arch/powerpc/util/Build @@ -1,6 +1,4 @@ perf-util-y += header.o -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += mem-events.o perf-util-y += pmu.o perf-util-y += sym-handling.o @@ -9,5 +7,4 @@ perf-util-y += evsel.o perf-util-$(CONFIG_LIBDW) += skip-callchain-idx.o perf-util-$(CONFIG_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += auxtrace.o diff --git a/tools/perf/arch/powerpc/util/perf_regs.c b/tools/perf/arch/powerpc/util/perf_regs.c deleted file mode 100644 index bd36cfd420a2..000000000000 --- a/tools/perf/arch/powerpc/util/perf_regs.c +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include - -#include "perf_regs.h" -#include "../../../util/perf_regs.h" -#include "../../../util/debug.h" -#include "../../../util/event.h" -#include "../../../util/header.h" -#include "../../../perf-sys.h" -#include "utils_header.h" - -#include - -#define PVR_POWER9 0x004E -#define PVR_POWER10 0x0080 -#define PVR_POWER11 0x0082 - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG(r0, PERF_REG_POWERPC_R0), - SMPL_REG(r1, PERF_REG_POWERPC_R1), - SMPL_REG(r2, PERF_REG_POWERPC_R2), - SMPL_REG(r3, PERF_REG_POWERPC_R3), - SMPL_REG(r4, PERF_REG_POWERPC_R4), - SMPL_REG(r5, PERF_REG_POWERPC_R5), - SMPL_REG(r6, PERF_REG_POWERPC_R6), - SMPL_REG(r7, PERF_REG_POWERPC_R7), - SMPL_REG(r8, PERF_REG_POWERPC_R8), - SMPL_REG(r9, PERF_REG_POWERPC_R9), - SMPL_REG(r10, PERF_REG_POWERPC_R10), - SMPL_REG(r11, PERF_REG_POWERPC_R11), - SMPL_REG(r12, PERF_REG_POWERPC_R12), - SMPL_REG(r13, PERF_REG_POWERPC_R13), - SMPL_REG(r14, PERF_REG_POWERPC_R14), - SMPL_REG(r15, PERF_REG_POWERPC_R15), - SMPL_REG(r16, PERF_REG_POWERPC_R16), - SMPL_REG(r17, PERF_REG_POWERPC_R17), - SMPL_REG(r18, PERF_REG_POWERPC_R18), - SMPL_REG(r19, PERF_REG_POWERPC_R19), - SMPL_REG(r20, PERF_REG_POWERPC_R20), - SMPL_REG(r21, PERF_REG_POWERPC_R21), - SMPL_REG(r22, PERF_REG_POWERPC_R22), - SMPL_REG(r23, PERF_REG_POWERPC_R23), - SMPL_REG(r24, PERF_REG_POWERPC_R24), - SMPL_REG(r25, PERF_REG_POWERPC_R25), - SMPL_REG(r26, PERF_REG_POWERPC_R26), - SMPL_REG(r27, PERF_REG_POWERPC_R27), - SMPL_REG(r28, PERF_REG_POWERPC_R28), - SMPL_REG(r29, PERF_REG_POWERPC_R29), - SMPL_REG(r30, PERF_REG_POWERPC_R30), - SMPL_REG(r31, PERF_REG_POWERPC_R31), - SMPL_REG(nip, PERF_REG_POWERPC_NIP), - SMPL_REG(msr, PERF_REG_POWERPC_MSR), - SMPL_REG(orig_r3, PERF_REG_POWERPC_ORIG_R3), - SMPL_REG(ctr, PERF_REG_POWERPC_CTR), - SMPL_REG(link, PERF_REG_POWERPC_LINK), - SMPL_REG(xer, PERF_REG_POWERPC_XER), - SMPL_REG(ccr, PERF_REG_POWERPC_CCR), - SMPL_REG(softe, PERF_REG_POWERPC_SOFTE), - SMPL_REG(trap, PERF_REG_POWERPC_TRAP), - SMPL_REG(dar, PERF_REG_POWERPC_DAR), - SMPL_REG(dsisr, PERF_REG_POWERPC_DSISR), - SMPL_REG(sier, PERF_REG_POWERPC_SIER), - SMPL_REG(mmcra, PERF_REG_POWERPC_MMCRA), - SMPL_REG(mmcr0, PERF_REG_POWERPC_MMCR0), - SMPL_REG(mmcr1, PERF_REG_POWERPC_MMCR1), - SMPL_REG(mmcr2, PERF_REG_POWERPC_MMCR2), - SMPL_REG(mmcr3, PERF_REG_POWERPC_MMCR3), - SMPL_REG(sier2, PERF_REG_POWERPC_SIER2), - SMPL_REG(sier3, PERF_REG_POWERPC_SIER3), - SMPL_REG(pmc1, PERF_REG_POWERPC_PMC1), - SMPL_REG(pmc2, PERF_REG_POWERPC_PMC2), - SMPL_REG(pmc3, PERF_REG_POWERPC_PMC3), - SMPL_REG(pmc4, PERF_REG_POWERPC_PMC4), - SMPL_REG(pmc5, PERF_REG_POWERPC_PMC5), - SMPL_REG(pmc6, PERF_REG_POWERPC_PMC6), - SMPL_REG(sdar, PERF_REG_POWERPC_SDAR), - SMPL_REG(siar, PERF_REG_POWERPC_SIAR), - SMPL_REG_END -}; - -/* REG or %rREG */ -#define SDT_OP_REGEX1 "^(%r)?([1-2]?[0-9]|3[0-1])$" - -/* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ -#define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$" - -static regex_t sdt_op_regex1, sdt_op_regex2; - -static int sdt_init_op_regex(void) -{ - static int initialized; - int ret = 0; - - if (initialized) - return 0; - - ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED); - if (ret) - goto error; - - ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED); - if (ret) - goto free_regex1; - - initialized = 1; - return 0; - -free_regex1: - regfree(&sdt_op_regex1); -error: - pr_debug4("Regex compilation error.\n"); - return ret; -} - -/* - * Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). - * Possible variants of OP are: - * Format Example - * ------------------------- - * NUM(REG) 48(18) - * -NUM(REG) -48(18) - * NUM(%rREG) 48(%r18) - * -NUM(%rREG) -48(%r18) - * REG 18 - * %rREG %r18 - * iNUM i0 - * i-NUM i-1 - * - * SDT marker arguments on Powerpc uses %rREG form with -mregnames flag - * and REG form with -mno-regnames. Here REG is general purpose register, - * which is in 0 to 31 range. - */ -int arch_sdt_arg_parse_op(char *old_op, char **new_op) -{ - int ret, new_len; - regmatch_t rm[5]; - char prefix; - - /* Constant argument. Uprobe does not support it */ - if (old_op[0] == 'i') { - pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); - return SDT_ARG_SKIP; - } - - ret = sdt_init_op_regex(); - if (ret < 0) - return ret; - - if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) { - /* REG or %rREG --> %gprREG */ - - new_len = 5; /* % g p r NULL */ - new_len += (int)(rm[2].rm_eo - rm[2].rm_so); - - *new_op = zalloc(new_len); - if (!*new_op) - return -ENOMEM; - - scnprintf(*new_op, new_len, "%%gpr%.*s", - (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so); - } else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) { - /* - * -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> - * +/-NUM(%gprREG) - */ - prefix = (rm[1].rm_so == -1) ? '+' : '-'; - - new_len = 8; /* +/- ( % g p r ) NULL */ - new_len += (int)(rm[2].rm_eo - rm[2].rm_so); - new_len += (int)(rm[4].rm_eo - rm[4].rm_so); - - *new_op = zalloc(new_len); - if (!*new_op) - return -ENOMEM; - - scnprintf(*new_op, new_len, "%c%.*s(%%gpr%.*s)", prefix, - (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so, - (int)(rm[4].rm_eo - rm[4].rm_so), old_op + rm[4].rm_so); - } else { - pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); - return SDT_ARG_SKIP; - } - - return SDT_ARG_VALID; -} - -uint64_t arch__intr_reg_mask(void) -{ - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - .sample_type = PERF_SAMPLE_REGS_INTR, - .precise_ip = 1, - .disabled = 1, - .exclude_kernel = 1, - }; - int fd; - u32 version; - u64 extended_mask = 0, mask = PERF_REGS_MASK; - - /* - * Get the PVR value to set the extended - * mask specific to platform. - */ - version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF); - if (version == PVR_POWER9) - extended_mask = PERF_REG_PMU_MASK_300; - else if ((version == PVR_POWER10) || (version == PVR_POWER11)) - extended_mask = PERF_REG_PMU_MASK_31; - else - return mask; - - attr.sample_regs_intr = extended_mask; - attr.sample_period = 1; - event_attr_init(&attr); - - /* - * check if the pmu supports perf extended regs, before - * returning the register mask to sample. - */ - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd != -1) { - close(fd); - mask |= extended_mask; - } - return mask; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/powerpc/util/skip-callchain-idx.c b/tools/perf/arch/powerpc/util/skip-callchain-idx.c index 356786432fd3..e57f10798fa6 100644 --- a/tools/perf/arch/powerpc/util/skip-callchain-idx.c +++ b/tools/perf/arch/powerpc/util/skip-callchain-idx.c @@ -30,14 +30,6 @@ * The libdwfl code in this file is based on code from elfutils * (libdwfl/argp-std.c, libdwfl/tests/addrcfi.c, etc). */ -static char *debuginfo_path; - -static const Dwfl_Callbacks offline_callbacks = { - .debuginfo_path = &debuginfo_path, - .find_debuginfo = dwfl_standard_find_debuginfo, - .section_address = dwfl_offline_section_address, -}; - /* * Use the DWARF expression for the Call-frame-address and determine @@ -149,44 +141,22 @@ static Dwarf_Frame *get_dwarf_frame(Dwfl_Module *mod, Dwarf_Addr pc) * yet used) * -1 in case of errors */ -static int check_return_addr(struct dso *dso, u64 map_start, Dwarf_Addr pc) +static int check_return_addr(struct dso *dso, Dwarf_Addr mapped_pc) { int rc = -1; Dwfl *dwfl; Dwfl_Module *mod; Dwarf_Frame *frame; int ra_regno; - Dwarf_Addr start = pc; - Dwarf_Addr end = pc; + Dwarf_Addr start = mapped_pc; + Dwarf_Addr end = mapped_pc; bool signalp; - const char *exec_file = dso__long_name(dso); - dwfl = RC_CHK_ACCESS(dso)->dwfl; + dwfl = dso__libdw_dwfl(dso); + if (!dwfl) + return -1; - if (!dwfl) { - dwfl = dwfl_begin(&offline_callbacks); - if (!dwfl) { - pr_debug("dwfl_begin() failed: %s\n", dwarf_errmsg(-1)); - return -1; - } - - mod = dwfl_report_elf(dwfl, exec_file, exec_file, -1, - map_start, false); - if (!mod) { - pr_debug("dwfl_report_elf() failed %s\n", - dwarf_errmsg(-1)); - /* - * We normally cache the DWARF debug info and never - * call dwfl_end(). But to prevent fd leak, free in - * case of error. - */ - dwfl_end(dwfl); - goto out; - } - RC_CHK_ACCESS(dso)->dwfl = dwfl; - } - - mod = dwfl_addrmodule(dwfl, pc); + mod = dwfl_addrmodule(dwfl, mapped_pc); if (!mod) { pr_debug("dwfl_addrmodule() failed, %s\n", dwarf_errmsg(-1)); goto out; @@ -196,9 +166,9 @@ static int check_return_addr(struct dso *dso, u64 map_start, Dwarf_Addr pc) * To work with split debug info files (eg: glibc), check both * .eh_frame and .debug_frame sections of the ELF header. */ - frame = get_eh_frame(mod, pc); + frame = get_eh_frame(mod, mapped_pc); if (!frame) { - frame = get_dwarf_frame(mod, pc); + frame = get_dwarf_frame(mod, mapped_pc); if (!frame) goto out; } @@ -264,7 +234,7 @@ int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain) return skip_slot; } - rc = check_return_addr(dso, map__start(al.map), ip); + rc = check_return_addr(dso, map__map_ip(al.map, ip)); pr_debug("[DSO %s, sym %s, ip 0x%" PRIx64 "] rc %d\n", dso__long_name(dso), al.sym->name, ip, rc); diff --git a/tools/perf/arch/powerpc/util/unwind-libdw.c b/tools/perf/arch/powerpc/util/unwind-libdw.c deleted file mode 100644 index 82d0c28ae345..000000000000 --- a/tools/perf/arch/powerpc/util/unwind-libdw.c +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "../../../util/sample.h" - -/* See backends/ppc_initreg.c and backends/ppc_regs.c in elfutils. */ -static const int special_regs[3][2] = { - { 65, PERF_REG_POWERPC_LINK }, - { 101, PERF_REG_POWERPC_XER }, - { 109, PERF_REG_POWERPC_CTR }, -}; - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[32], dwarf_nip; - size_t i; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_POWERPC_##r); \ - val; \ -}) - - dwarf_regs[0] = REG(R0); - dwarf_regs[1] = REG(R1); - dwarf_regs[2] = REG(R2); - dwarf_regs[3] = REG(R3); - dwarf_regs[4] = REG(R4); - dwarf_regs[5] = REG(R5); - dwarf_regs[6] = REG(R6); - dwarf_regs[7] = REG(R7); - dwarf_regs[8] = REG(R8); - dwarf_regs[9] = REG(R9); - dwarf_regs[10] = REG(R10); - dwarf_regs[11] = REG(R11); - dwarf_regs[12] = REG(R12); - dwarf_regs[13] = REG(R13); - dwarf_regs[14] = REG(R14); - dwarf_regs[15] = REG(R15); - dwarf_regs[16] = REG(R16); - dwarf_regs[17] = REG(R17); - dwarf_regs[18] = REG(R18); - dwarf_regs[19] = REG(R19); - dwarf_regs[20] = REG(R20); - dwarf_regs[21] = REG(R21); - dwarf_regs[22] = REG(R22); - dwarf_regs[23] = REG(R23); - dwarf_regs[24] = REG(R24); - dwarf_regs[25] = REG(R25); - dwarf_regs[26] = REG(R26); - dwarf_regs[27] = REG(R27); - dwarf_regs[28] = REG(R28); - dwarf_regs[29] = REG(R29); - dwarf_regs[30] = REG(R30); - dwarf_regs[31] = REG(R31); - if (!dwfl_thread_state_registers(thread, 0, 32, dwarf_regs)) - return false; - - dwarf_nip = REG(NIP); - dwfl_thread_state_register_pc(thread, dwarf_nip); - for (i = 0; i < ARRAY_SIZE(special_regs); i++) { - Dwarf_Word val = 0; - perf_reg_value(&val, user_regs, special_regs[i][1]); - if (!dwfl_thread_state_registers(thread, - special_regs[i][0], 1, - &val)) - return false; - } - - return true; -} diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile index 087e099fb453..44cc3f023318 100644 --- a/tools/perf/arch/riscv/Makefile +++ b/tools/perf/arch/riscv/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 PERF_HAVE_JITDUMP := 1 -HAVE_KVM_STAT_SUPPORT := 1 diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h index d482edb413e5..af7a1b47bf66 100644 --- a/tools/perf/arch/riscv/include/perf_regs.h +++ b/tools/perf/arch/riscv/include/perf_regs.h @@ -6,14 +6,19 @@ #include #include -#include +#include "../../../../arch/riscv/include/uapi/asm/perf_regs.h" #define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1) #define PERF_REGS_MAX PERF_REG_RISCV_MAX + +#if defined(__riscv_xlen) #if __riscv_xlen == 64 -#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 #else #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32 #endif +#else +#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_NONE +#endif #endif /* ARCH_PERF_REGS_H */ diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build index 58a672246024..2328fb9a30a3 100644 --- a/tools/perf/arch/riscv/util/Build +++ b/tools/perf/arch/riscv/util/Build @@ -1,5 +1 @@ -perf-util-y += perf_regs.o perf-util-y += header.o - -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o diff --git a/tools/perf/arch/riscv/util/perf_regs.c b/tools/perf/arch/riscv/util/perf_regs.c deleted file mode 100644 index 6b1665f41180..000000000000 --- a/tools/perf/arch/riscv/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/riscv/util/unwind-libdw.c b/tools/perf/arch/riscv/util/unwind-libdw.c deleted file mode 100644 index dc1476e16321..000000000000 --- a/tools/perf/arch/riscv/util/unwind-libdw.c +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */ - -#include -#include "perf_regs.h" -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/sample.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[32]; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_RISCV_##r); \ - val; \ -}) - - dwarf_regs[0] = 0; - dwarf_regs[1] = REG(RA); - dwarf_regs[2] = REG(SP); - dwarf_regs[3] = REG(GP); - dwarf_regs[4] = REG(TP); - dwarf_regs[5] = REG(T0); - dwarf_regs[6] = REG(T1); - dwarf_regs[7] = REG(T2); - dwarf_regs[8] = REG(S0); - dwarf_regs[9] = REG(S1); - dwarf_regs[10] = REG(A0); - dwarf_regs[11] = REG(A1); - dwarf_regs[12] = REG(A2); - dwarf_regs[13] = REG(A3); - dwarf_regs[14] = REG(A4); - dwarf_regs[15] = REG(A5); - dwarf_regs[16] = REG(A6); - dwarf_regs[17] = REG(A7); - dwarf_regs[18] = REG(S2); - dwarf_regs[19] = REG(S3); - dwarf_regs[20] = REG(S4); - dwarf_regs[21] = REG(S5); - dwarf_regs[22] = REG(S6); - dwarf_regs[23] = REG(S7); - dwarf_regs[24] = REG(S8); - dwarf_regs[25] = REG(S9); - dwarf_regs[26] = REG(S10); - dwarf_regs[27] = REG(S11); - dwarf_regs[28] = REG(T3); - dwarf_regs[29] = REG(T4); - dwarf_regs[30] = REG(T5); - dwarf_regs[31] = REG(T6); - dwfl_thread_state_register_pc(thread, REG(PC)); - - return dwfl_thread_state_registers(thread, 0, PERF_REG_RISCV_MAX, - dwarf_regs); -} diff --git a/tools/perf/arch/riscv64/annotate/instructions.c b/tools/perf/arch/riscv64/annotate/instructions.c deleted file mode 100644 index 55cf911633f8..000000000000 --- a/tools/perf/arch/riscv64/annotate/instructions.c +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -static -struct ins_ops *riscv64__associate_ins_ops(struct arch *arch, const char *name) -{ - struct ins_ops *ops = NULL; - - if (!strncmp(name, "jal", 3) || - !strncmp(name, "jr", 2) || - !strncmp(name, "call", 4)) - ops = &call_ops; - else if (!strncmp(name, "ret", 3)) - ops = &ret_ops; - else if (name[0] == 'j' || name[0] == 'b') - ops = &jump_ops; - else - return NULL; - - arch__associate_ins_ops(arch, name, ops); - - return ops; -} - -static -int riscv64__annotate_init(struct arch *arch, char *cpuid __maybe_unused) -{ - if (!arch->initialized) { - arch->associate_instruction_ops = riscv64__associate_ins_ops; - arch->initialized = true; - arch->objdump.comment_char = '#'; - arch->e_machine = EM_RISCV; - arch->e_flags = 0; - } - - return 0; -} diff --git a/tools/perf/arch/s390/Makefile b/tools/perf/arch/s390/Makefile index 0033698a65ce..8b59ce8efb89 100644 --- a/tools/perf/arch/s390/Makefile +++ b/tools/perf/arch/s390/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0-only -HAVE_KVM_STAT_SUPPORT := 1 PERF_HAVE_JITDUMP := 1 diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl index 5863787ab036..09a7ef04d979 100644 --- a/tools/perf/arch/s390/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/s390/entry/syscalls/syscall.tbl @@ -3,473 +3,398 @@ # System call table for s390 # # Format: +# # -# -# -# where can be common, 64, or 32 +# is always common. -1 common exit sys_exit sys_exit -2 common fork sys_fork sys_fork -3 common read sys_read compat_sys_s390_read -4 common write sys_write compat_sys_s390_write -5 common open sys_open compat_sys_open -6 common close sys_close sys_close -7 common restart_syscall sys_restart_syscall sys_restart_syscall -8 common creat sys_creat sys_creat -9 common link sys_link sys_link -10 common unlink sys_unlink sys_unlink -11 common execve sys_execve compat_sys_execve -12 common chdir sys_chdir sys_chdir -13 32 time - sys_time32 -14 common mknod sys_mknod sys_mknod -15 common chmod sys_chmod sys_chmod -16 32 lchown - sys_lchown16 -19 common lseek sys_lseek compat_sys_lseek -20 common getpid sys_getpid sys_getpid -21 common mount sys_mount sys_mount -22 common umount sys_oldumount sys_oldumount -23 32 setuid - sys_setuid16 -24 32 getuid - sys_getuid16 -25 32 stime - sys_stime32 -26 common ptrace sys_ptrace compat_sys_ptrace -27 common alarm sys_alarm sys_alarm -29 common pause sys_pause sys_pause -30 common utime sys_utime sys_utime32 -33 common access sys_access sys_access -34 common nice sys_nice sys_nice -36 common sync sys_sync sys_sync -37 common kill sys_kill sys_kill -38 common rename sys_rename sys_rename -39 common mkdir sys_mkdir sys_mkdir -40 common rmdir sys_rmdir sys_rmdir -41 common dup sys_dup sys_dup -42 common pipe sys_pipe sys_pipe -43 common times sys_times compat_sys_times -45 common brk sys_brk sys_brk -46 32 setgid - sys_setgid16 -47 32 getgid - sys_getgid16 -48 common signal sys_signal sys_signal -49 32 geteuid - sys_geteuid16 -50 32 getegid - sys_getegid16 -51 common acct sys_acct sys_acct -52 common umount2 sys_umount sys_umount -54 common ioctl sys_ioctl compat_sys_ioctl -55 common fcntl sys_fcntl compat_sys_fcntl -57 common setpgid sys_setpgid sys_setpgid -60 common umask sys_umask sys_umask -61 common chroot sys_chroot sys_chroot -62 common ustat sys_ustat compat_sys_ustat -63 common dup2 sys_dup2 sys_dup2 -64 common getppid sys_getppid sys_getppid -65 common getpgrp sys_getpgrp sys_getpgrp -66 common setsid sys_setsid sys_setsid -67 common sigaction sys_sigaction compat_sys_sigaction -70 32 setreuid - sys_setreuid16 -71 32 setregid - sys_setregid16 -72 common sigsuspend sys_sigsuspend sys_sigsuspend -73 common sigpending sys_sigpending compat_sys_sigpending -74 common sethostname sys_sethostname sys_sethostname -75 common setrlimit sys_setrlimit compat_sys_setrlimit -76 32 getrlimit - compat_sys_old_getrlimit -77 common getrusage sys_getrusage compat_sys_getrusage -78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday -79 common settimeofday sys_settimeofday compat_sys_settimeofday -80 32 getgroups - sys_getgroups16 -81 32 setgroups - sys_setgroups16 -83 common symlink sys_symlink sys_symlink -85 common readlink sys_readlink sys_readlink -86 common uselib sys_uselib sys_uselib -87 common swapon sys_swapon sys_swapon -88 common reboot sys_reboot sys_reboot -89 common readdir - compat_sys_old_readdir -90 common mmap sys_old_mmap compat_sys_s390_old_mmap -91 common munmap sys_munmap sys_munmap -92 common truncate sys_truncate compat_sys_truncate -93 common ftruncate sys_ftruncate compat_sys_ftruncate -94 common fchmod sys_fchmod sys_fchmod -95 32 fchown - sys_fchown16 -96 common getpriority sys_getpriority sys_getpriority -97 common setpriority sys_setpriority sys_setpriority -99 common statfs sys_statfs compat_sys_statfs -100 common fstatfs sys_fstatfs compat_sys_fstatfs -101 32 ioperm - - -102 common socketcall sys_socketcall compat_sys_socketcall -103 common syslog sys_syslog sys_syslog -104 common setitimer sys_setitimer compat_sys_setitimer -105 common getitimer sys_getitimer compat_sys_getitimer -106 common stat sys_newstat compat_sys_newstat -107 common lstat sys_newlstat compat_sys_newlstat -108 common fstat sys_newfstat compat_sys_newfstat -110 common lookup_dcookie - - -111 common vhangup sys_vhangup sys_vhangup -112 common idle - - -114 common wait4 sys_wait4 compat_sys_wait4 -115 common swapoff sys_swapoff sys_swapoff -116 common sysinfo sys_sysinfo compat_sys_sysinfo -117 common ipc sys_s390_ipc compat_sys_s390_ipc -118 common fsync sys_fsync sys_fsync -119 common sigreturn sys_sigreturn compat_sys_sigreturn -120 common clone sys_clone sys_clone -121 common setdomainname sys_setdomainname sys_setdomainname -122 common uname sys_newuname sys_newuname -124 common adjtimex sys_adjtimex sys_adjtimex_time32 -125 common mprotect sys_mprotect sys_mprotect -126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask -127 common create_module - - -128 common init_module sys_init_module sys_init_module -129 common delete_module sys_delete_module sys_delete_module -130 common get_kernel_syms - - -131 common quotactl sys_quotactl sys_quotactl -132 common getpgid sys_getpgid sys_getpgid -133 common fchdir sys_fchdir sys_fchdir -134 common bdflush sys_ni_syscall sys_ni_syscall -135 common sysfs sys_sysfs sys_sysfs -136 common personality sys_s390_personality sys_s390_personality -137 common afs_syscall - - -138 32 setfsuid - sys_setfsuid16 -139 32 setfsgid - sys_setfsgid16 -140 32 _llseek - sys_llseek -141 common getdents sys_getdents compat_sys_getdents -142 32 _newselect - compat_sys_select -142 64 select sys_select - -143 common flock sys_flock sys_flock -144 common msync sys_msync sys_msync -145 common readv sys_readv sys_readv -146 common writev sys_writev sys_writev -147 common getsid sys_getsid sys_getsid -148 common fdatasync sys_fdatasync sys_fdatasync -149 common _sysctl - - -150 common mlock sys_mlock sys_mlock -151 common munlock sys_munlock sys_munlock -152 common mlockall sys_mlockall sys_mlockall -153 common munlockall sys_munlockall sys_munlockall -154 common sched_setparam sys_sched_setparam sys_sched_setparam -155 common sched_getparam sys_sched_getparam sys_sched_getparam -156 common sched_setscheduler sys_sched_setscheduler sys_sched_setscheduler -157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler -158 common sched_yield sys_sched_yield sys_sched_yield -159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max -160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min -161 common sched_rr_get_interval sys_sched_rr_get_interval sys_sched_rr_get_interval_time32 -162 common nanosleep sys_nanosleep sys_nanosleep_time32 -163 common mremap sys_mremap sys_mremap -164 32 setresuid - sys_setresuid16 -165 32 getresuid - sys_getresuid16 -167 common query_module - - -168 common poll sys_poll sys_poll -169 common nfsservctl - - -170 32 setresgid - sys_setresgid16 -171 32 getresgid - sys_getresgid16 -172 common prctl sys_prctl sys_prctl -173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn -174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction -175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask -176 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending -177 common rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time32 -178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo -179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend -180 common pread64 sys_pread64 compat_sys_s390_pread64 -181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64 -182 32 chown - sys_chown16 -183 common getcwd sys_getcwd sys_getcwd -184 common capget sys_capget sys_capget -185 common capset sys_capset sys_capset -186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack -187 common sendfile sys_sendfile64 compat_sys_sendfile -188 common getpmsg - - -189 common putpmsg - - -190 common vfork sys_vfork sys_vfork -191 32 ugetrlimit - compat_sys_getrlimit -191 64 getrlimit sys_getrlimit - -192 32 mmap2 - compat_sys_s390_mmap2 -193 32 truncate64 - compat_sys_s390_truncate64 -194 32 ftruncate64 - compat_sys_s390_ftruncate64 -195 32 stat64 - compat_sys_s390_stat64 -196 32 lstat64 - compat_sys_s390_lstat64 -197 32 fstat64 - compat_sys_s390_fstat64 -198 32 lchown32 - sys_lchown -198 64 lchown sys_lchown - -199 32 getuid32 - sys_getuid -199 64 getuid sys_getuid - -200 32 getgid32 - sys_getgid -200 64 getgid sys_getgid - -201 32 geteuid32 - sys_geteuid -201 64 geteuid sys_geteuid - -202 32 getegid32 - sys_getegid -202 64 getegid sys_getegid - -203 32 setreuid32 - sys_setreuid -203 64 setreuid sys_setreuid - -204 32 setregid32 - sys_setregid -204 64 setregid sys_setregid - -205 32 getgroups32 - sys_getgroups -205 64 getgroups sys_getgroups - -206 32 setgroups32 - sys_setgroups -206 64 setgroups sys_setgroups - -207 32 fchown32 - sys_fchown -207 64 fchown sys_fchown - -208 32 setresuid32 - sys_setresuid -208 64 setresuid sys_setresuid - -209 32 getresuid32 - sys_getresuid -209 64 getresuid sys_getresuid - -210 32 setresgid32 - sys_setresgid -210 64 setresgid sys_setresgid - -211 32 getresgid32 - sys_getresgid -211 64 getresgid sys_getresgid - -212 32 chown32 - sys_chown -212 64 chown sys_chown - -213 32 setuid32 - sys_setuid -213 64 setuid sys_setuid - -214 32 setgid32 - sys_setgid -214 64 setgid sys_setgid - -215 32 setfsuid32 - sys_setfsuid -215 64 setfsuid sys_setfsuid - -216 32 setfsgid32 - sys_setfsgid -216 64 setfsgid sys_setfsgid - -217 common pivot_root sys_pivot_root sys_pivot_root -218 common mincore sys_mincore sys_mincore -219 common madvise sys_madvise sys_madvise -220 common getdents64 sys_getdents64 sys_getdents64 -221 32 fcntl64 - compat_sys_fcntl64 -222 common readahead sys_readahead compat_sys_s390_readahead -223 32 sendfile64 - compat_sys_sendfile64 -224 common setxattr sys_setxattr sys_setxattr -225 common lsetxattr sys_lsetxattr sys_lsetxattr -226 common fsetxattr sys_fsetxattr sys_fsetxattr -227 common getxattr sys_getxattr sys_getxattr -228 common lgetxattr sys_lgetxattr sys_lgetxattr -229 common fgetxattr sys_fgetxattr sys_fgetxattr -230 common listxattr sys_listxattr sys_listxattr -231 common llistxattr sys_llistxattr sys_llistxattr -232 common flistxattr sys_flistxattr sys_flistxattr -233 common removexattr sys_removexattr sys_removexattr -234 common lremovexattr sys_lremovexattr sys_lremovexattr -235 common fremovexattr sys_fremovexattr sys_fremovexattr -236 common gettid sys_gettid sys_gettid -237 common tkill sys_tkill sys_tkill -238 common futex sys_futex sys_futex_time32 -239 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity -240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity -241 common tgkill sys_tgkill sys_tgkill -243 common io_setup sys_io_setup compat_sys_io_setup -244 common io_destroy sys_io_destroy sys_io_destroy -245 common io_getevents sys_io_getevents sys_io_getevents_time32 -246 common io_submit sys_io_submit compat_sys_io_submit -247 common io_cancel sys_io_cancel sys_io_cancel -248 common exit_group sys_exit_group sys_exit_group -249 common epoll_create sys_epoll_create sys_epoll_create -250 common epoll_ctl sys_epoll_ctl sys_epoll_ctl -251 common epoll_wait sys_epoll_wait sys_epoll_wait -252 common set_tid_address sys_set_tid_address sys_set_tid_address -253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64 -254 common timer_create sys_timer_create compat_sys_timer_create -255 common timer_settime sys_timer_settime sys_timer_settime32 -256 common timer_gettime sys_timer_gettime sys_timer_gettime32 -257 common timer_getoverrun sys_timer_getoverrun sys_timer_getoverrun -258 common timer_delete sys_timer_delete sys_timer_delete -259 common clock_settime sys_clock_settime sys_clock_settime32 -260 common clock_gettime sys_clock_gettime sys_clock_gettime32 -261 common clock_getres sys_clock_getres sys_clock_getres_time32 -262 common clock_nanosleep sys_clock_nanosleep sys_clock_nanosleep_time32 -264 32 fadvise64_64 - compat_sys_s390_fadvise64_64 -265 common statfs64 sys_statfs64 compat_sys_statfs64 -266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64 -267 common remap_file_pages sys_remap_file_pages sys_remap_file_pages -268 common mbind sys_mbind sys_mbind -269 common get_mempolicy sys_get_mempolicy sys_get_mempolicy -270 common set_mempolicy sys_set_mempolicy sys_set_mempolicy -271 common mq_open sys_mq_open compat_sys_mq_open -272 common mq_unlink sys_mq_unlink sys_mq_unlink -273 common mq_timedsend sys_mq_timedsend sys_mq_timedsend_time32 -274 common mq_timedreceive sys_mq_timedreceive sys_mq_timedreceive_time32 -275 common mq_notify sys_mq_notify compat_sys_mq_notify -276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr -277 common kexec_load sys_kexec_load compat_sys_kexec_load -278 common add_key sys_add_key sys_add_key -279 common request_key sys_request_key sys_request_key -280 common keyctl sys_keyctl compat_sys_keyctl -281 common waitid sys_waitid compat_sys_waitid -282 common ioprio_set sys_ioprio_set sys_ioprio_set -283 common ioprio_get sys_ioprio_get sys_ioprio_get -284 common inotify_init sys_inotify_init sys_inotify_init -285 common inotify_add_watch sys_inotify_add_watch sys_inotify_add_watch -286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch -287 common migrate_pages sys_migrate_pages sys_migrate_pages -288 common openat sys_openat compat_sys_openat -289 common mkdirat sys_mkdirat sys_mkdirat -290 common mknodat sys_mknodat sys_mknodat -291 common fchownat sys_fchownat sys_fchownat -292 common futimesat sys_futimesat sys_futimesat_time32 -293 32 fstatat64 - compat_sys_s390_fstatat64 -293 64 newfstatat sys_newfstatat - -294 common unlinkat sys_unlinkat sys_unlinkat -295 common renameat sys_renameat sys_renameat -296 common linkat sys_linkat sys_linkat -297 common symlinkat sys_symlinkat sys_symlinkat -298 common readlinkat sys_readlinkat sys_readlinkat -299 common fchmodat sys_fchmodat sys_fchmodat -300 common faccessat sys_faccessat sys_faccessat -301 common pselect6 sys_pselect6 compat_sys_pselect6_time32 -302 common ppoll sys_ppoll compat_sys_ppoll_time32 -303 common unshare sys_unshare sys_unshare -304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list -305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list -306 common splice sys_splice sys_splice -307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range -308 common tee sys_tee sys_tee -309 common vmsplice sys_vmsplice sys_vmsplice -310 common move_pages sys_move_pages sys_move_pages -311 common getcpu sys_getcpu sys_getcpu -312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait -313 common utimes sys_utimes sys_utimes_time32 -314 common fallocate sys_fallocate compat_sys_s390_fallocate -315 common utimensat sys_utimensat sys_utimensat_time32 -316 common signalfd sys_signalfd compat_sys_signalfd -317 common timerfd - - -318 common eventfd sys_eventfd sys_eventfd -319 common timerfd_create sys_timerfd_create sys_timerfd_create -320 common timerfd_settime sys_timerfd_settime sys_timerfd_settime32 -321 common timerfd_gettime sys_timerfd_gettime sys_timerfd_gettime32 -322 common signalfd4 sys_signalfd4 compat_sys_signalfd4 -323 common eventfd2 sys_eventfd2 sys_eventfd2 -324 common inotify_init1 sys_inotify_init1 sys_inotify_init1 -325 common pipe2 sys_pipe2 sys_pipe2 -326 common dup3 sys_dup3 sys_dup3 -327 common epoll_create1 sys_epoll_create1 sys_epoll_create1 -328 common preadv sys_preadv compat_sys_preadv -329 common pwritev sys_pwritev compat_sys_pwritev -330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo -331 common perf_event_open sys_perf_event_open sys_perf_event_open -332 common fanotify_init sys_fanotify_init sys_fanotify_init -333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark -334 common prlimit64 sys_prlimit64 sys_prlimit64 -335 common name_to_handle_at sys_name_to_handle_at sys_name_to_handle_at -336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at -337 common clock_adjtime sys_clock_adjtime sys_clock_adjtime32 -338 common syncfs sys_syncfs sys_syncfs -339 common setns sys_setns sys_setns -340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv -341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev -342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr -343 common kcmp sys_kcmp sys_kcmp -344 common finit_module sys_finit_module sys_finit_module -345 common sched_setattr sys_sched_setattr sys_sched_setattr -346 common sched_getattr sys_sched_getattr sys_sched_getattr -347 common renameat2 sys_renameat2 sys_renameat2 -348 common seccomp sys_seccomp sys_seccomp -349 common getrandom sys_getrandom sys_getrandom -350 common memfd_create sys_memfd_create sys_memfd_create -351 common bpf sys_bpf sys_bpf -352 common s390_pci_mmio_write sys_s390_pci_mmio_write sys_s390_pci_mmio_write -353 common s390_pci_mmio_read sys_s390_pci_mmio_read sys_s390_pci_mmio_read -354 common execveat sys_execveat compat_sys_execveat -355 common userfaultfd sys_userfaultfd sys_userfaultfd -356 common membarrier sys_membarrier sys_membarrier -357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg_time32 -358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg -359 common socket sys_socket sys_socket -360 common socketpair sys_socketpair sys_socketpair -361 common bind sys_bind sys_bind -362 common connect sys_connect sys_connect -363 common listen sys_listen sys_listen -364 common accept4 sys_accept4 sys_accept4 -365 common getsockopt sys_getsockopt sys_getsockopt -366 common setsockopt sys_setsockopt sys_setsockopt -367 common getsockname sys_getsockname sys_getsockname -368 common getpeername sys_getpeername sys_getpeername -369 common sendto sys_sendto sys_sendto -370 common sendmsg sys_sendmsg compat_sys_sendmsg -371 common recvfrom sys_recvfrom compat_sys_recvfrom -372 common recvmsg sys_recvmsg compat_sys_recvmsg -373 common shutdown sys_shutdown sys_shutdown -374 common mlock2 sys_mlock2 sys_mlock2 -375 common copy_file_range sys_copy_file_range sys_copy_file_range -376 common preadv2 sys_preadv2 compat_sys_preadv2 -377 common pwritev2 sys_pwritev2 compat_sys_pwritev2 -378 common s390_guarded_storage sys_s390_guarded_storage sys_s390_guarded_storage -379 common statx sys_statx sys_statx -380 common s390_sthyi sys_s390_sthyi sys_s390_sthyi -381 common kexec_file_load sys_kexec_file_load sys_kexec_file_load -382 common io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents -383 common rseq sys_rseq sys_rseq -384 common pkey_mprotect sys_pkey_mprotect sys_pkey_mprotect -385 common pkey_alloc sys_pkey_alloc sys_pkey_alloc -386 common pkey_free sys_pkey_free sys_pkey_free +1 common exit sys_exit +2 common fork sys_fork +3 common read sys_read +4 common write sys_write +5 common open sys_open +6 common close sys_close +7 common restart_syscall sys_restart_syscall +8 common creat sys_creat +9 common link sys_link +10 common unlink sys_unlink +11 common execve sys_execve +12 common chdir sys_chdir +14 common mknod sys_mknod +15 common chmod sys_chmod +19 common lseek sys_lseek +20 common getpid sys_getpid +21 common mount sys_mount +22 common umount sys_oldumount +26 common ptrace sys_ptrace +27 common alarm sys_alarm +29 common pause sys_pause +30 common utime sys_utime +33 common access sys_access +34 common nice sys_nice +36 common sync sys_sync +37 common kill sys_kill +38 common rename sys_rename +39 common mkdir sys_mkdir +40 common rmdir sys_rmdir +41 common dup sys_dup +42 common pipe sys_pipe +43 common times sys_times +45 common brk sys_brk +48 common signal sys_signal +51 common acct sys_acct +52 common umount2 sys_umount +54 common ioctl sys_ioctl +55 common fcntl sys_fcntl +57 common setpgid sys_setpgid +60 common umask sys_umask +61 common chroot sys_chroot +62 common ustat sys_ustat +63 common dup2 sys_dup2 +64 common getppid sys_getppid +65 common getpgrp sys_getpgrp +66 common setsid sys_setsid +67 common sigaction sys_sigaction +72 common sigsuspend sys_sigsuspend +73 common sigpending sys_sigpending +74 common sethostname sys_sethostname +75 common setrlimit sys_setrlimit +77 common getrusage sys_getrusage +78 common gettimeofday sys_gettimeofday +79 common settimeofday sys_settimeofday +83 common symlink sys_symlink +85 common readlink sys_readlink +86 common uselib sys_uselib +87 common swapon sys_swapon +88 common reboot sys_reboot +89 common readdir sys_ni_syscall +90 common mmap sys_old_mmap +91 common munmap sys_munmap +92 common truncate sys_truncate +93 common ftruncate sys_ftruncate +94 common fchmod sys_fchmod +96 common getpriority sys_getpriority +97 common setpriority sys_setpriority +99 common statfs sys_statfs +100 common fstatfs sys_fstatfs +102 common socketcall sys_socketcall +103 common syslog sys_syslog +104 common setitimer sys_setitimer +105 common getitimer sys_getitimer +106 common stat sys_newstat +107 common lstat sys_newlstat +108 common fstat sys_newfstat +110 common lookup_dcookie sys_ni_syscall +111 common vhangup sys_vhangup +112 common idle sys_ni_syscall +114 common wait4 sys_wait4 +115 common swapoff sys_swapoff +116 common sysinfo sys_sysinfo +117 common ipc sys_s390_ipc +118 common fsync sys_fsync +119 common sigreturn sys_sigreturn +120 common clone sys_clone +121 common setdomainname sys_setdomainname +122 common uname sys_newuname +124 common adjtimex sys_adjtimex +125 common mprotect sys_mprotect +126 common sigprocmask sys_sigprocmask +127 common create_module sys_ni_syscall +128 common init_module sys_init_module +129 common delete_module sys_delete_module +130 common get_kernel_syms sys_ni_syscall +131 common quotactl sys_quotactl +132 common getpgid sys_getpgid +133 common fchdir sys_fchdir +134 common bdflush sys_ni_syscall +135 common sysfs sys_sysfs +136 common personality sys_s390_personality +137 common afs_syscall sys_ni_syscall +141 common getdents sys_getdents +142 common select sys_select +143 common flock sys_flock +144 common msync sys_msync +145 common readv sys_readv +146 common writev sys_writev +147 common getsid sys_getsid +148 common fdatasync sys_fdatasync +149 common _sysctl sys_ni_syscall +150 common mlock sys_mlock +151 common munlock sys_munlock +152 common mlockall sys_mlockall +153 common munlockall sys_munlockall +154 common sched_setparam sys_sched_setparam +155 common sched_getparam sys_sched_getparam +156 common sched_setscheduler sys_sched_setscheduler +157 common sched_getscheduler sys_sched_getscheduler +158 common sched_yield sys_sched_yield +159 common sched_get_priority_max sys_sched_get_priority_max +160 common sched_get_priority_min sys_sched_get_priority_min +161 common sched_rr_get_interval sys_sched_rr_get_interval +162 common nanosleep sys_nanosleep +163 common mremap sys_mremap +167 common query_module sys_ni_syscall +168 common poll sys_poll +169 common nfsservctl sys_ni_syscall +172 common prctl sys_prctl +173 common rt_sigreturn sys_rt_sigreturn +174 common rt_sigaction sys_rt_sigaction +175 common rt_sigprocmask sys_rt_sigprocmask +176 common rt_sigpending sys_rt_sigpending +177 common rt_sigtimedwait sys_rt_sigtimedwait +178 common rt_sigqueueinfo sys_rt_sigqueueinfo +179 common rt_sigsuspend sys_rt_sigsuspend +180 common pread64 sys_pread64 +181 common pwrite64 sys_pwrite64 +183 common getcwd sys_getcwd +184 common capget sys_capget +185 common capset sys_capset +186 common sigaltstack sys_sigaltstack +187 common sendfile sys_sendfile64 +188 common getpmsg sys_ni_syscall +189 common putpmsg sys_ni_syscall +190 common vfork sys_vfork +191 common getrlimit sys_getrlimit +198 common lchown sys_lchown +199 common getuid sys_getuid +200 common getgid sys_getgid +201 common geteuid sys_geteuid +202 common getegid sys_getegid +203 common setreuid sys_setreuid +204 common setregid sys_setregid +205 common getgroups sys_getgroups +206 common setgroups sys_setgroups +207 common fchown sys_fchown +208 common setresuid sys_setresuid +209 common getresuid sys_getresuid +210 common setresgid sys_setresgid +211 common getresgid sys_getresgid +212 common chown sys_chown +213 common setuid sys_setuid +214 common setgid sys_setgid +215 common setfsuid sys_setfsuid +216 common setfsgid sys_setfsgid +217 common pivot_root sys_pivot_root +218 common mincore sys_mincore +219 common madvise sys_madvise +220 common getdents64 sys_getdents64 +222 common readahead sys_readahead +224 common setxattr sys_setxattr +225 common lsetxattr sys_lsetxattr +226 common fsetxattr sys_fsetxattr +227 common getxattr sys_getxattr +228 common lgetxattr sys_lgetxattr +229 common fgetxattr sys_fgetxattr +230 common listxattr sys_listxattr +231 common llistxattr sys_llistxattr +232 common flistxattr sys_flistxattr +233 common removexattr sys_removexattr +234 common lremovexattr sys_lremovexattr +235 common fremovexattr sys_fremovexattr +236 common gettid sys_gettid +237 common tkill sys_tkill +238 common futex sys_futex +239 common sched_setaffinity sys_sched_setaffinity +240 common sched_getaffinity sys_sched_getaffinity +241 common tgkill sys_tgkill +243 common io_setup sys_io_setup +244 common io_destroy sys_io_destroy +245 common io_getevents sys_io_getevents +246 common io_submit sys_io_submit +247 common io_cancel sys_io_cancel +248 common exit_group sys_exit_group +249 common epoll_create sys_epoll_create +250 common epoll_ctl sys_epoll_ctl +251 common epoll_wait sys_epoll_wait +252 common set_tid_address sys_set_tid_address +253 common fadvise64 sys_fadvise64_64 +254 common timer_create sys_timer_create +255 common timer_settime sys_timer_settime +256 common timer_gettime sys_timer_gettime +257 common timer_getoverrun sys_timer_getoverrun +258 common timer_delete sys_timer_delete +259 common clock_settime sys_clock_settime +260 common clock_gettime sys_clock_gettime +261 common clock_getres sys_clock_getres +262 common clock_nanosleep sys_clock_nanosleep +265 common statfs64 sys_statfs64 +266 common fstatfs64 sys_fstatfs64 +267 common remap_file_pages sys_remap_file_pages +268 common mbind sys_mbind +269 common get_mempolicy sys_get_mempolicy +270 common set_mempolicy sys_set_mempolicy +271 common mq_open sys_mq_open +272 common mq_unlink sys_mq_unlink +273 common mq_timedsend sys_mq_timedsend +274 common mq_timedreceive sys_mq_timedreceive +275 common mq_notify sys_mq_notify +276 common mq_getsetattr sys_mq_getsetattr +277 common kexec_load sys_kexec_load +278 common add_key sys_add_key +279 common request_key sys_request_key +280 common keyctl sys_keyctl +281 common waitid sys_waitid +282 common ioprio_set sys_ioprio_set +283 common ioprio_get sys_ioprio_get +284 common inotify_init sys_inotify_init +285 common inotify_add_watch sys_inotify_add_watch +286 common inotify_rm_watch sys_inotify_rm_watch +287 common migrate_pages sys_migrate_pages +288 common openat sys_openat +289 common mkdirat sys_mkdirat +290 common mknodat sys_mknodat +291 common fchownat sys_fchownat +292 common futimesat sys_futimesat +293 common newfstatat sys_newfstatat +294 common unlinkat sys_unlinkat +295 common renameat sys_renameat +296 common linkat sys_linkat +297 common symlinkat sys_symlinkat +298 common readlinkat sys_readlinkat +299 common fchmodat sys_fchmodat +300 common faccessat sys_faccessat +301 common pselect6 sys_pselect6 +302 common ppoll sys_ppoll +303 common unshare sys_unshare +304 common set_robust_list sys_set_robust_list +305 common get_robust_list sys_get_robust_list +306 common splice sys_splice +307 common sync_file_range sys_sync_file_range +308 common tee sys_tee +309 common vmsplice sys_vmsplice +310 common move_pages sys_move_pages +311 common getcpu sys_getcpu +312 common epoll_pwait sys_epoll_pwait +313 common utimes sys_utimes +314 common fallocate sys_fallocate +315 common utimensat sys_utimensat +316 common signalfd sys_signalfd +317 common timerfd sys_ni_syscall +318 common eventfd sys_eventfd +319 common timerfd_create sys_timerfd_create +320 common timerfd_settime sys_timerfd_settime +321 common timerfd_gettime sys_timerfd_gettime +322 common signalfd4 sys_signalfd4 +323 common eventfd2 sys_eventfd2 +324 common inotify_init1 sys_inotify_init1 +325 common pipe2 sys_pipe2 +326 common dup3 sys_dup3 +327 common epoll_create1 sys_epoll_create1 +328 common preadv sys_preadv +329 common pwritev sys_pwritev +330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo +331 common perf_event_open sys_perf_event_open +332 common fanotify_init sys_fanotify_init +333 common fanotify_mark sys_fanotify_mark +334 common prlimit64 sys_prlimit64 +335 common name_to_handle_at sys_name_to_handle_at +336 common open_by_handle_at sys_open_by_handle_at +337 common clock_adjtime sys_clock_adjtime +338 common syncfs sys_syncfs +339 common setns sys_setns +340 common process_vm_readv sys_process_vm_readv +341 common process_vm_writev sys_process_vm_writev +342 common s390_runtime_instr sys_s390_runtime_instr +343 common kcmp sys_kcmp +344 common finit_module sys_finit_module +345 common sched_setattr sys_sched_setattr +346 common sched_getattr sys_sched_getattr +347 common renameat2 sys_renameat2 +348 common seccomp sys_seccomp +349 common getrandom sys_getrandom +350 common memfd_create sys_memfd_create +351 common bpf sys_bpf +352 common s390_pci_mmio_write sys_s390_pci_mmio_write +353 common s390_pci_mmio_read sys_s390_pci_mmio_read +354 common execveat sys_execveat +355 common userfaultfd sys_userfaultfd +356 common membarrier sys_membarrier +357 common recvmmsg sys_recvmmsg +358 common sendmmsg sys_sendmmsg +359 common socket sys_socket +360 common socketpair sys_socketpair +361 common bind sys_bind +362 common connect sys_connect +363 common listen sys_listen +364 common accept4 sys_accept4 +365 common getsockopt sys_getsockopt +366 common setsockopt sys_setsockopt +367 common getsockname sys_getsockname +368 common getpeername sys_getpeername +369 common sendto sys_sendto +370 common sendmsg sys_sendmsg +371 common recvfrom sys_recvfrom +372 common recvmsg sys_recvmsg +373 common shutdown sys_shutdown +374 common mlock2 sys_mlock2 +375 common copy_file_range sys_copy_file_range +376 common preadv2 sys_preadv2 +377 common pwritev2 sys_pwritev2 +378 common s390_guarded_storage sys_s390_guarded_storage +379 common statx sys_statx +380 common s390_sthyi sys_s390_sthyi +381 common kexec_file_load sys_kexec_file_load +382 common io_pgetevents sys_io_pgetevents +383 common rseq sys_rseq +384 common pkey_mprotect sys_pkey_mprotect +385 common pkey_alloc sys_pkey_alloc +386 common pkey_free sys_pkey_free # room for arch specific syscalls -392 64 semtimedop sys_semtimedop - -393 common semget sys_semget sys_semget -394 common semctl sys_semctl compat_sys_semctl -395 common shmget sys_shmget sys_shmget -396 common shmctl sys_shmctl compat_sys_shmctl -397 common shmat sys_shmat compat_sys_shmat -398 common shmdt sys_shmdt sys_shmdt -399 common msgget sys_msgget sys_msgget -400 common msgsnd sys_msgsnd compat_sys_msgsnd -401 common msgrcv sys_msgrcv compat_sys_msgrcv -402 common msgctl sys_msgctl compat_sys_msgctl -403 32 clock_gettime64 - sys_clock_gettime -404 32 clock_settime64 - sys_clock_settime -405 32 clock_adjtime64 - sys_clock_adjtime -406 32 clock_getres_time64 - sys_clock_getres -407 32 clock_nanosleep_time64 - sys_clock_nanosleep -408 32 timer_gettime64 - sys_timer_gettime -409 32 timer_settime64 - sys_timer_settime -410 32 timerfd_gettime64 - sys_timerfd_gettime -411 32 timerfd_settime64 - sys_timerfd_settime -412 32 utimensat_time64 - sys_utimensat -413 32 pselect6_time64 - compat_sys_pselect6_time64 -414 32 ppoll_time64 - compat_sys_ppoll_time64 -416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64 -417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64 -418 32 mq_timedsend_time64 - sys_mq_timedsend -419 32 mq_timedreceive_time64 - sys_mq_timedreceive -420 32 semtimedop_time64 - sys_semtimedop -421 32 rt_sigtimedwait_time64 - compat_sys_rt_sigtimedwait_time64 -422 32 futex_time64 - sys_futex -423 32 sched_rr_get_interval_time64 - sys_sched_rr_get_interval -424 common pidfd_send_signal sys_pidfd_send_signal sys_pidfd_send_signal -425 common io_uring_setup sys_io_uring_setup sys_io_uring_setup -426 common io_uring_enter sys_io_uring_enter sys_io_uring_enter -427 common io_uring_register sys_io_uring_register sys_io_uring_register -428 common open_tree sys_open_tree sys_open_tree -429 common move_mount sys_move_mount sys_move_mount -430 common fsopen sys_fsopen sys_fsopen -431 common fsconfig sys_fsconfig sys_fsconfig -432 common fsmount sys_fsmount sys_fsmount -433 common fspick sys_fspick sys_fspick -434 common pidfd_open sys_pidfd_open sys_pidfd_open -435 common clone3 sys_clone3 sys_clone3 -436 common close_range sys_close_range sys_close_range -437 common openat2 sys_openat2 sys_openat2 -438 common pidfd_getfd sys_pidfd_getfd sys_pidfd_getfd -439 common faccessat2 sys_faccessat2 sys_faccessat2 -440 common process_madvise sys_process_madvise sys_process_madvise -441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2 -442 common mount_setattr sys_mount_setattr sys_mount_setattr -443 common quotactl_fd sys_quotactl_fd sys_quotactl_fd -444 common landlock_create_ruleset sys_landlock_create_ruleset sys_landlock_create_ruleset -445 common landlock_add_rule sys_landlock_add_rule sys_landlock_add_rule -446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self -447 common memfd_secret sys_memfd_secret sys_memfd_secret -448 common process_mrelease sys_process_mrelease sys_process_mrelease -449 common futex_waitv sys_futex_waitv sys_futex_waitv -450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node -451 common cachestat sys_cachestat sys_cachestat -452 common fchmodat2 sys_fchmodat2 sys_fchmodat2 -453 common map_shadow_stack sys_map_shadow_stack sys_map_shadow_stack -454 common futex_wake sys_futex_wake sys_futex_wake -455 common futex_wait sys_futex_wait sys_futex_wait -456 common futex_requeue sys_futex_requeue sys_futex_requeue -457 common statmount sys_statmount sys_statmount -458 common listmount sys_listmount sys_listmount -459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr -460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr -461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules -462 common mseal sys_mseal sys_mseal -463 common setxattrat sys_setxattrat sys_setxattrat -464 common getxattrat sys_getxattrat sys_getxattrat -465 common listxattrat sys_listxattrat sys_listxattrat -466 common removexattrat sys_removexattrat sys_removexattrat -467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr -468 common file_getattr sys_file_getattr sys_file_getattr -469 common file_setattr sys_file_setattr sys_file_setattr -470 common listns sys_listns sys_listns +392 common semtimedop sys_semtimedop +393 common semget sys_semget +394 common semctl sys_semctl +395 common shmget sys_shmget +396 common shmctl sys_shmctl +397 common shmat sys_shmat +398 common shmdt sys_shmdt +399 common msgget sys_msgget +400 common msgsnd sys_msgsnd +401 common msgrcv sys_msgrcv +402 common msgctl sys_msgctl +424 common pidfd_send_signal sys_pidfd_send_signal +425 common io_uring_setup sys_io_uring_setup +426 common io_uring_enter sys_io_uring_enter +427 common io_uring_register sys_io_uring_register +428 common open_tree sys_open_tree +429 common move_mount sys_move_mount +430 common fsopen sys_fsopen +431 common fsconfig sys_fsconfig +432 common fsmount sys_fsmount +433 common fspick sys_fspick +434 common pidfd_open sys_pidfd_open +435 common clone3 sys_clone3 +436 common close_range sys_close_range +437 common openat2 sys_openat2 +438 common pidfd_getfd sys_pidfd_getfd +439 common faccessat2 sys_faccessat2 +440 common process_madvise sys_process_madvise +441 common epoll_pwait2 sys_epoll_pwait2 +442 common mount_setattr sys_mount_setattr +443 common quotactl_fd sys_quotactl_fd +444 common landlock_create_ruleset sys_landlock_create_ruleset +445 common landlock_add_rule sys_landlock_add_rule +446 common landlock_restrict_self sys_landlock_restrict_self +447 common memfd_secret sys_memfd_secret +448 common process_mrelease sys_process_mrelease +449 common futex_waitv sys_futex_waitv +450 common set_mempolicy_home_node sys_set_mempolicy_home_node +451 common cachestat sys_cachestat +452 common fchmodat2 sys_fchmodat2 +453 common map_shadow_stack sys_map_shadow_stack +454 common futex_wake sys_futex_wake +455 common futex_wait sys_futex_wait +456 common futex_requeue sys_futex_requeue +457 common statmount sys_statmount +458 common listmount sys_listmount +459 common lsm_get_self_attr sys_lsm_get_self_attr +460 common lsm_set_self_attr sys_lsm_set_self_attr +461 common lsm_list_modules sys_lsm_list_modules +462 common mseal sys_mseal +463 common setxattrat sys_setxattrat +464 common getxattrat sys_getxattrat +465 common listxattrat sys_listxattrat +466 common removexattrat sys_removexattrat +467 common open_tree_attr sys_open_tree_attr +468 common file_getattr sys_file_getattr +469 common file_setattr sys_file_setattr +470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/s390/include/perf_regs.h b/tools/perf/arch/s390/include/perf_regs.h index 130dfad2b96a..9c95589965fe 100644 --- a/tools/perf/arch/s390/include/perf_regs.h +++ b/tools/perf/arch/s390/include/perf_regs.h @@ -3,7 +3,7 @@ #include #include -#include +#include "../../../../arch/s390/include/uapi/asm/perf_regs.h" void perf_regs_load(u64 *regs); diff --git a/tools/perf/arch/s390/util/Build b/tools/perf/arch/s390/util/Build index c64eb18dbdae..65d75cd5b138 100644 --- a/tools/perf/arch/s390/util/Build +++ b/tools/perf/arch/s390/util/Build @@ -1,8 +1,4 @@ perf-util-y += header.o -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o - -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += machine.o perf-util-y += pmu.o diff --git a/tools/perf/arch/s390/util/perf_regs.c b/tools/perf/arch/s390/util/perf_regs.c deleted file mode 100644 index 6b1665f41180..000000000000 --- a/tools/perf/arch/s390/util/perf_regs.c +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "perf_regs.h" -#include "../../util/perf_regs.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -uint64_t arch__intr_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} diff --git a/tools/perf/arch/s390/util/unwind-libdw.c b/tools/perf/arch/s390/util/unwind-libdw.c deleted file mode 100644 index c27c7a0d1076..000000000000 --- a/tools/perf/arch/s390/util/unwind-libdw.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include "../../util/unwind-libdw.h" -#include "../../util/perf_regs.h" -#include "../../util/event.h" -#include "../../util/sample.h" -#include "dwarf-regs-table.h" -#include "perf_regs.h" - - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[ARRAY_SIZE(s390_dwarf_regs)]; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_S390_##r); \ - val; \ -}) - /* - * For DWARF register mapping details, - * see also perf/arch/s390/include/dwarf-regs-table.h - */ - dwarf_regs[0] = REG(R0); - dwarf_regs[1] = REG(R1); - dwarf_regs[2] = REG(R2); - dwarf_regs[3] = REG(R3); - dwarf_regs[4] = REG(R4); - dwarf_regs[5] = REG(R5); - dwarf_regs[6] = REG(R6); - dwarf_regs[7] = REG(R7); - dwarf_regs[8] = REG(R8); - dwarf_regs[9] = REG(R9); - dwarf_regs[10] = REG(R10); - dwarf_regs[11] = REG(R11); - dwarf_regs[12] = REG(R12); - dwarf_regs[13] = REG(R13); - dwarf_regs[14] = REG(R14); - dwarf_regs[15] = REG(R15); - - dwarf_regs[16] = REG(FP0); - dwarf_regs[17] = REG(FP2); - dwarf_regs[18] = REG(FP4); - dwarf_regs[19] = REG(FP6); - dwarf_regs[20] = REG(FP1); - dwarf_regs[21] = REG(FP3); - dwarf_regs[22] = REG(FP5); - dwarf_regs[23] = REG(FP7); - dwarf_regs[24] = REG(FP8); - dwarf_regs[25] = REG(FP10); - dwarf_regs[26] = REG(FP12); - dwarf_regs[27] = REG(FP14); - dwarf_regs[28] = REG(FP9); - dwarf_regs[29] = REG(FP11); - dwarf_regs[30] = REG(FP13); - dwarf_regs[31] = REG(FP15); - - dwarf_regs[64] = REG(MASK); - dwarf_regs[65] = REG(PC); - - dwfl_thread_state_register_pc(thread, dwarf_regs[65]); - return dwfl_thread_state_registers(thread, 0, 32, dwarf_regs); -} diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl index 969c11325ade..70b315cbe710 100644 --- a/tools/perf/arch/sh/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl @@ -474,3 +474,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl index 39aa26b6a50b..7e71bf7fcd14 100644 --- a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl @@ -480,7 +480,7 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open -# 435 reserved for clone3 +435 common clone3 __sys_clone3 436 common close_range sys_close_range 437 common openat2 sys_openat2 438 common pidfd_getfd sys_pidfd_getfd @@ -516,3 +516,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/x86/Makefile b/tools/perf/arch/x86/Makefile index a295a80ea078..44cc3f023318 100644 --- a/tools/perf/arch/x86/Makefile +++ b/tools/perf/arch/x86/Makefile @@ -1,3 +1,2 @@ # SPDX-License-Identifier: GPL-2.0 -HAVE_KVM_STAT_SUPPORT := 1 PERF_HAVE_JITDUMP := 1 diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl index e979a3eac7a3..f832ebd2d79b 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl @@ -476,3 +476,4 @@ 468 i386 file_getattr sys_file_getattr 469 i386 file_setattr sys_file_setattr 470 i386 listns sys_listns +471 i386 rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index 8a4ac4841be6..524155d655da 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -395,6 +395,7 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield # # Due to a historical design error, certain syscalls are numbered differently diff --git a/tools/perf/arch/x86/include/perf_regs.h b/tools/perf/arch/x86/include/perf_regs.h index f209ce2c1dd9..5495e5ca7cdc 100644 --- a/tools/perf/arch/x86/include/perf_regs.h +++ b/tools/perf/arch/x86/include/perf_regs.h @@ -4,7 +4,7 @@ #include #include -#include +#include "../../../../arch/x86/include/uapi/asm/perf_regs.h" void perf_regs_load(u64 *regs); diff --git a/tools/perf/arch/x86/tests/bp-modify.c b/tools/perf/arch/x86/tests/bp-modify.c index 0924ccd9e36d..589b43273948 100644 --- a/tools/perf/arch/x86/tests/bp-modify.c +++ b/tools/perf/arch/x86/tests/bp-modify.c @@ -80,26 +80,24 @@ static int bp_modify1(void) */ if (ptrace(PTRACE_POKEUSER, child, offsetof(struct user, u_debugreg[0]), bp_2)) { - pr_debug("failed to set breakpoint, 1st time: %s\n", - strerror(errno)); + pr_debug("failed to set breakpoint, 1st time: %m\n"); goto out; } if (ptrace(PTRACE_POKEUSER, child, offsetof(struct user, u_debugreg[0]), bp_1)) { - pr_debug("failed to set breakpoint, 2nd time: %s\n", - strerror(errno)); + pr_debug("failed to set breakpoint, 2nd time: %m\n"); goto out; } if (ptrace(PTRACE_POKEUSER, child, offsetof(struct user, u_debugreg[7]), dr7)) { - pr_debug("failed to set dr7: %s\n", strerror(errno)); + pr_debug("failed to set dr7: %m\n"); goto out; } if (ptrace(PTRACE_CONT, child, NULL, NULL)) { - pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); + pr_debug("failed to PTRACE_CONT: %m\n"); goto out; } @@ -112,19 +110,17 @@ static int bp_modify1(void) rip = ptrace(PTRACE_PEEKUSER, child, offsetof(struct user_regs_struct, rip), NULL); if (rip == (unsigned long) -1) { - pr_debug("failed to PTRACE_PEEKUSER: %s\n", - strerror(errno)); + pr_debug("failed to PTRACE_PEEKUSER: %m\n"); goto out; } pr_debug("rip %lx, bp_1 %p\n", rip, bp_1); - out: if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { - pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); + pr_debug("failed to PTRACE_DETACH: %m\n"); return TEST_FAIL; - } + } return rip == (unsigned long) bp_1 ? TEST_OK : TEST_FAIL; } @@ -157,14 +153,13 @@ static int bp_modify2(void) */ if (ptrace(PTRACE_POKEUSER, child, offsetof(struct user, u_debugreg[0]), bp_1)) { - pr_debug("failed to set breakpoint: %s\n", - strerror(errno)); + pr_debug("failed to set breakpoint: %m\n"); goto out; } if (ptrace(PTRACE_POKEUSER, child, offsetof(struct user, u_debugreg[7]), dr7)) { - pr_debug("failed to set dr7: %s\n", strerror(errno)); + pr_debug("failed to set dr7: %m\n"); goto out; } @@ -175,7 +170,7 @@ static int bp_modify2(void) } if (ptrace(PTRACE_CONT, child, NULL, NULL)) { - pr_debug("failed to PTRACE_CONT: %s\n", strerror(errno)); + pr_debug("failed to PTRACE_CONT: %m\n"); goto out; } @@ -188,8 +183,7 @@ static int bp_modify2(void) rip = ptrace(PTRACE_PEEKUSER, child, offsetof(struct user_regs_struct, rip), NULL); if (rip == (unsigned long) -1) { - pr_debug("failed to PTRACE_PEEKUSER: %s\n", - strerror(errno)); + pr_debug("failed to PTRACE_PEEKUSER: %m\n"); goto out; } @@ -197,7 +191,7 @@ static int bp_modify2(void) out: if (ptrace(PTRACE_DETACH, child, NULL, NULL)) { - pr_debug("failed to PTRACE_DETACH: %s", strerror(errno)); + pr_debug("failed to PTRACE_DETACH: %m\n"); return TEST_FAIL; } diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build index c0dc5965f362..b94c91984c66 100644 --- a/tools/perf/arch/x86/util/Build +++ b/tools/perf/arch/x86/util/Build @@ -1,8 +1,6 @@ perf-util-y += header.o perf-util-y += tsc.o perf-util-y += pmu.o -perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o -perf-util-y += perf_regs.o perf-util-y += topdown.o perf-util-y += machine.o perf-util-y += event.o @@ -12,9 +10,7 @@ perf-util-y += evsel.o perf-util-y += iostat.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-y += auxtrace.o -perf-util-y += archinsn.o perf-util-y += intel-pt.o perf-util-y += intel-bts.o diff --git a/tools/perf/arch/x86/util/archinsn.c b/tools/perf/arch/x86/util/archinsn.c deleted file mode 100644 index 546feda08428..000000000000 --- a/tools/perf/arch/x86/util/archinsn.c +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "archinsn.h" -#include "event.h" -#include "machine.h" -#include "thread.h" -#include "symbol.h" -#include "../../../../arch/x86/include/asm/insn.h" - -void arch_fetch_insn(struct perf_sample *sample, - struct thread *thread, - struct machine *machine) -{ - struct insn insn; - int len, ret; - bool is64bit = false; - - if (!sample->ip) - return; - len = thread__memcpy(thread, machine, sample->insn, sample->ip, sizeof(sample->insn), &is64bit); - if (len <= 0) - return; - - ret = insn_decode(&insn, sample->insn, len, - is64bit ? INSN_MODE_64 : INSN_MODE_32); - if (ret >= 0 && insn.length <= len) - sample->insn_len = insn.length; -} diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c index b394ad9cc635..c131a727774f 100644 --- a/tools/perf/arch/x86/util/intel-pt.c +++ b/tools/perf/arch/x86/util/intel-pt.c @@ -664,8 +664,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr, return 0; if (opts->auxtrace_sample_mode) - evsel__set_config_if_unset(intel_pt_pmu, intel_pt_evsel, - "psb_period", 0); + evsel__set_config_if_unset(intel_pt_evsel, "psb_period", 0); err = intel_pt_validate_config(intel_pt_pmu, intel_pt_evsel); if (err) diff --git a/tools/perf/arch/x86/util/perf_regs.c b/tools/perf/arch/x86/util/perf_regs.c deleted file mode 100644 index 12fd93f04802..000000000000 --- a/tools/perf/arch/x86/util/perf_regs.c +++ /dev/null @@ -1,330 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include -#include -#include -#include - -#include "perf_regs.h" -#include "../../../perf-sys.h" -#include "../../../util/perf_regs.h" -#include "../../../util/debug.h" -#include "../../../util/event.h" -#include "../../../util/pmu.h" -#include "../../../util/pmus.h" - -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG(AX, PERF_REG_X86_AX), - SMPL_REG(BX, PERF_REG_X86_BX), - SMPL_REG(CX, PERF_REG_X86_CX), - SMPL_REG(DX, PERF_REG_X86_DX), - SMPL_REG(SI, PERF_REG_X86_SI), - SMPL_REG(DI, PERF_REG_X86_DI), - SMPL_REG(BP, PERF_REG_X86_BP), - SMPL_REG(SP, PERF_REG_X86_SP), - SMPL_REG(IP, PERF_REG_X86_IP), - SMPL_REG(FLAGS, PERF_REG_X86_FLAGS), - SMPL_REG(CS, PERF_REG_X86_CS), - SMPL_REG(SS, PERF_REG_X86_SS), -#ifdef HAVE_ARCH_X86_64_SUPPORT - SMPL_REG(R8, PERF_REG_X86_R8), - SMPL_REG(R9, PERF_REG_X86_R9), - SMPL_REG(R10, PERF_REG_X86_R10), - SMPL_REG(R11, PERF_REG_X86_R11), - SMPL_REG(R12, PERF_REG_X86_R12), - SMPL_REG(R13, PERF_REG_X86_R13), - SMPL_REG(R14, PERF_REG_X86_R14), - SMPL_REG(R15, PERF_REG_X86_R15), -#endif - SMPL_REG2(XMM0, PERF_REG_X86_XMM0), - SMPL_REG2(XMM1, PERF_REG_X86_XMM1), - SMPL_REG2(XMM2, PERF_REG_X86_XMM2), - SMPL_REG2(XMM3, PERF_REG_X86_XMM3), - SMPL_REG2(XMM4, PERF_REG_X86_XMM4), - SMPL_REG2(XMM5, PERF_REG_X86_XMM5), - SMPL_REG2(XMM6, PERF_REG_X86_XMM6), - SMPL_REG2(XMM7, PERF_REG_X86_XMM7), - SMPL_REG2(XMM8, PERF_REG_X86_XMM8), - SMPL_REG2(XMM9, PERF_REG_X86_XMM9), - SMPL_REG2(XMM10, PERF_REG_X86_XMM10), - SMPL_REG2(XMM11, PERF_REG_X86_XMM11), - SMPL_REG2(XMM12, PERF_REG_X86_XMM12), - SMPL_REG2(XMM13, PERF_REG_X86_XMM13), - SMPL_REG2(XMM14, PERF_REG_X86_XMM14), - SMPL_REG2(XMM15, PERF_REG_X86_XMM15), - SMPL_REG_END -}; - -struct sdt_name_reg { - const char *sdt_name; - const char *uprobe_name; -}; -#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} -#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} - -static const struct sdt_name_reg sdt_reg_tbl[] = { - SDT_NAME_REG(eax, ax), - SDT_NAME_REG(rax, ax), - SDT_NAME_REG(al, ax), - SDT_NAME_REG(ah, ax), - SDT_NAME_REG(ebx, bx), - SDT_NAME_REG(rbx, bx), - SDT_NAME_REG(bl, bx), - SDT_NAME_REG(bh, bx), - SDT_NAME_REG(ecx, cx), - SDT_NAME_REG(rcx, cx), - SDT_NAME_REG(cl, cx), - SDT_NAME_REG(ch, cx), - SDT_NAME_REG(edx, dx), - SDT_NAME_REG(rdx, dx), - SDT_NAME_REG(dl, dx), - SDT_NAME_REG(dh, dx), - SDT_NAME_REG(esi, si), - SDT_NAME_REG(rsi, si), - SDT_NAME_REG(sil, si), - SDT_NAME_REG(edi, di), - SDT_NAME_REG(rdi, di), - SDT_NAME_REG(dil, di), - SDT_NAME_REG(ebp, bp), - SDT_NAME_REG(rbp, bp), - SDT_NAME_REG(bpl, bp), - SDT_NAME_REG(rsp, sp), - SDT_NAME_REG(esp, sp), - SDT_NAME_REG(spl, sp), - - /* rNN registers */ - SDT_NAME_REG(r8b, r8), - SDT_NAME_REG(r8w, r8), - SDT_NAME_REG(r8d, r8), - SDT_NAME_REG(r9b, r9), - SDT_NAME_REG(r9w, r9), - SDT_NAME_REG(r9d, r9), - SDT_NAME_REG(r10b, r10), - SDT_NAME_REG(r10w, r10), - SDT_NAME_REG(r10d, r10), - SDT_NAME_REG(r11b, r11), - SDT_NAME_REG(r11w, r11), - SDT_NAME_REG(r11d, r11), - SDT_NAME_REG(r12b, r12), - SDT_NAME_REG(r12w, r12), - SDT_NAME_REG(r12d, r12), - SDT_NAME_REG(r13b, r13), - SDT_NAME_REG(r13w, r13), - SDT_NAME_REG(r13d, r13), - SDT_NAME_REG(r14b, r14), - SDT_NAME_REG(r14w, r14), - SDT_NAME_REG(r14d, r14), - SDT_NAME_REG(r15b, r15), - SDT_NAME_REG(r15w, r15), - SDT_NAME_REG(r15d, r15), - SDT_NAME_REG_END, -}; - -/* - * Perf only supports OP which is in +/-NUM(REG) form. - * Here plus-minus sign, NUM and parenthesis are optional, - * only REG is mandatory. - * - * SDT events also supports indirect addressing mode with a - * symbol as offset, scaled mode and constants in OP. But - * perf does not support them yet. Below are few examples. - * - * OP with scaled mode: - * (%rax,%rsi,8) - * 10(%ras,%rsi,8) - * - * OP with indirect addressing mode: - * check_action(%rip) - * mp_+52(%rip) - * 44+mp_(%rip) - * - * OP with constant values: - * $0 - * $123 - * $-1 - */ -#define SDT_OP_REGEX "^([+\\-]?)([0-9]*)(\\(?)(%[a-z][a-z0-9]+)(\\)?)$" - -static regex_t sdt_op_regex; - -static int sdt_init_op_regex(void) -{ - static int initialized; - int ret = 0; - - if (initialized) - return 0; - - ret = regcomp(&sdt_op_regex, SDT_OP_REGEX, REG_EXTENDED); - if (ret < 0) { - pr_debug4("Regex compilation error.\n"); - return ret; - } - - initialized = 1; - return 0; -} - -/* - * Max x86 register name length is 5(ex: %r15d). So, 6th char - * should always contain NULL. This helps to find register name - * length using strlen, instead of maintaining one more variable. - */ -#define SDT_REG_NAME_SIZE 6 - -/* - * The uprobe parser does not support all gas register names; - * so, we have to replace them (ex. for x86_64: %rax -> %ax). - * Note: If register does not require renaming, just copy - * paste as it is, but don't leave it empty. - */ -static void sdt_rename_register(char *sdt_reg, int sdt_len, char *uprobe_reg) -{ - int i = 0; - - for (i = 0; sdt_reg_tbl[i].sdt_name != NULL; i++) { - if (!strncmp(sdt_reg_tbl[i].sdt_name, sdt_reg, sdt_len)) { - strcpy(uprobe_reg, sdt_reg_tbl[i].uprobe_name); - return; - } - } - - strncpy(uprobe_reg, sdt_reg, sdt_len); -} - -int arch_sdt_arg_parse_op(char *old_op, char **new_op) -{ - char new_reg[SDT_REG_NAME_SIZE] = {0}; - int new_len = 0, ret; - /* - * rm[0]: +/-NUM(REG) - * rm[1]: +/- - * rm[2]: NUM - * rm[3]: ( - * rm[4]: REG - * rm[5]: ) - */ - regmatch_t rm[6]; - /* - * Max prefix length is 2 as it may contains sign(+/-) - * and displacement 0 (Both sign and displacement 0 are - * optional so it may be empty). Use one more character - * to hold last NULL so that strlen can be used to find - * prefix length, instead of maintaining one more variable. - */ - char prefix[3] = {0}; - - ret = sdt_init_op_regex(); - if (ret < 0) - return ret; - - /* - * If unsupported OR does not match with regex OR - * register name too long, skip it. - */ - if (strchr(old_op, ',') || strchr(old_op, '$') || - regexec(&sdt_op_regex, old_op, 6, rm, 0) || - rm[4].rm_eo - rm[4].rm_so > SDT_REG_NAME_SIZE) { - pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); - return SDT_ARG_SKIP; - } - - /* - * Prepare prefix. - * If SDT OP has parenthesis but does not provide - * displacement, add 0 for displacement. - * SDT Uprobe Prefix - * ----------------------------- - * +24(%rdi) +24(%di) + - * 24(%rdi) +24(%di) + - * %rdi %di - * (%rdi) +0(%di) +0 - * -80(%rbx) -80(%bx) - - */ - if (rm[3].rm_so != rm[3].rm_eo) { - if (rm[1].rm_so != rm[1].rm_eo) - prefix[0] = *(old_op + rm[1].rm_so); - else if (rm[2].rm_so != rm[2].rm_eo) - prefix[0] = '+'; - else - scnprintf(prefix, sizeof(prefix), "+0"); - } - - /* Rename register */ - sdt_rename_register(old_op + rm[4].rm_so, rm[4].rm_eo - rm[4].rm_so, - new_reg); - - /* Prepare final OP which should be valid for uprobe_events */ - new_len = strlen(prefix) + - (rm[2].rm_eo - rm[2].rm_so) + - (rm[3].rm_eo - rm[3].rm_so) + - strlen(new_reg) + - (rm[5].rm_eo - rm[5].rm_so) + - 1; /* NULL */ - - *new_op = zalloc(new_len); - if (!*new_op) - return -ENOMEM; - - scnprintf(*new_op, new_len, "%.*s%.*s%.*s%.*s%.*s", - strlen(prefix), prefix, - (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so, - (int)(rm[3].rm_eo - rm[3].rm_so), old_op + rm[3].rm_so, - strlen(new_reg), new_reg, - (int)(rm[5].rm_eo - rm[5].rm_so), old_op + rm[5].rm_so); - - return SDT_ARG_VALID; -} - -const struct sample_reg *arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} - -uint64_t arch__intr_reg_mask(void) -{ - struct perf_event_attr attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - .sample_type = PERF_SAMPLE_REGS_INTR, - .sample_regs_intr = PERF_REG_EXTENDED_MASK, - .precise_ip = 1, - .disabled = 1, - .exclude_kernel = 1, - }; - int fd; - /* - * In an unnamed union, init it here to build on older gcc versions - */ - attr.sample_period = 1; - - if (perf_pmus__num_core_pmus() > 1) { - struct perf_pmu *pmu = NULL; - __u64 type = PERF_TYPE_RAW; - - /* - * The same register set is supported among different hybrid PMUs. - * Only check the first available one. - */ - while ((pmu = perf_pmus__scan_core(pmu)) != NULL) { - type = pmu->type; - break; - } - attr.config |= type << PERF_PMU_TYPE_SHIFT; - } - - event_attr_init(&attr); - - fd = sys_perf_event_open(&attr, 0, -1, -1, 0); - if (fd != -1) { - close(fd); - return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK); - } - - return PERF_REGS_MASK; -} - -uint64_t arch__user_reg_mask(void) -{ - return PERF_REGS_MASK; -} diff --git a/tools/perf/arch/x86/util/unwind-libdw.c b/tools/perf/arch/x86/util/unwind-libdw.c deleted file mode 100644 index 798493e887d7..000000000000 --- a/tools/perf/arch/x86/util/unwind-libdw.c +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include "perf_regs.h" -#include "../../../util/unwind-libdw.h" -#include "../../../util/perf_regs.h" -#include "util/sample.h" - -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) -{ - struct unwind_info *ui = arg; - struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); - Dwarf_Word dwarf_regs[17]; - unsigned nregs; - -#define REG(r) ({ \ - Dwarf_Word val = 0; \ - perf_reg_value(&val, user_regs, PERF_REG_X86_##r); \ - val; \ -}) - - if (user_regs->abi == PERF_SAMPLE_REGS_ABI_32) { - dwarf_regs[0] = REG(AX); - dwarf_regs[1] = REG(CX); - dwarf_regs[2] = REG(DX); - dwarf_regs[3] = REG(BX); - dwarf_regs[4] = REG(SP); - dwarf_regs[5] = REG(BP); - dwarf_regs[6] = REG(SI); - dwarf_regs[7] = REG(DI); - dwarf_regs[8] = REG(IP); - nregs = 9; - } else { - dwarf_regs[0] = REG(AX); - dwarf_regs[1] = REG(DX); - dwarf_regs[2] = REG(CX); - dwarf_regs[3] = REG(BX); - dwarf_regs[4] = REG(SI); - dwarf_regs[5] = REG(DI); - dwarf_regs[6] = REG(BP); - dwarf_regs[7] = REG(SP); - dwarf_regs[8] = REG(R8); - dwarf_regs[9] = REG(R9); - dwarf_regs[10] = REG(R10); - dwarf_regs[11] = REG(R11); - dwarf_regs[12] = REG(R12); - dwarf_regs[13] = REG(R13); - dwarf_regs[14] = REG(R14); - dwarf_regs[15] = REG(R15); - dwarf_regs[16] = REG(IP); - nregs = 17; - } - - return dwfl_thread_state_registers(thread, 0, nregs, dwarf_regs); -} diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl index 438a3b170402..a9bca4e484de 100644 --- a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl @@ -441,3 +441,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/perf/bench/uprobe.c b/tools/perf/bench/uprobe.c index 0b90275862e1..c4dac868f1ee 100644 --- a/tools/perf/bench/uprobe.c +++ b/tools/perf/bench/uprobe.c @@ -54,7 +54,7 @@ static const char * const bench_uprobe_usage[] = { /*opts=*/&uprobe_opts); \ if (!skel->links.prog) { \ err = -errno; \ - fprintf(stderr, "Failed to attach bench uprobe \"%s\": %s\n", #prog, strerror(errno)); \ + fprintf(stderr, "Failed to attach bench uprobe \"%s\": %m\n", #prog); \ goto cleanup; \ } diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c index d19769a8f689..3641d263b345 100644 --- a/tools/perf/builtin-check.c +++ b/tools/perf/builtin-check.c @@ -43,6 +43,7 @@ struct feature_status supported_features[] = { FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT), FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT), FEATURE_STATUS_TIP("libbfd", HAVE_LIBBFD_SUPPORT, "Deprecated, license incompatibility, use BUILD_NONDISTRO=1 and install binutils-dev[el]"), + FEATURE_STATUS("libbabeltrace", HAVE_LIBBABELTRACE_SUPPORT), FEATURE_STATUS("libbpf-strings", HAVE_LIBBPF_STRINGS_SUPPORT), FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT), FEATURE_STATUS("libdw-dwarf-unwind", HAVE_LIBDW_SUPPORT), @@ -60,6 +61,7 @@ struct feature_status supported_features[] = { FEATURE_STATUS("numa_num_possible_cpus", HAVE_LIBNUMA_SUPPORT), FEATURE_STATUS("zlib", HAVE_ZLIB_SUPPORT), FEATURE_STATUS("zstd", HAVE_ZSTD_SUPPORT), + FEATURE_STATUS("rust", HAVE_RUST_SUPPORT), /* this should remain at end, to know the array end */ FEATURE_STATUS(NULL, _) diff --git a/tools/perf/builtin-daemon.c b/tools/perf/builtin-daemon.c index f0568431fbd5..33473e071392 100644 --- a/tools/perf/builtin-daemon.c +++ b/tools/perf/builtin-daemon.c @@ -265,8 +265,7 @@ static int check_base(struct daemon *daemon) daemon->base); return -EACCES; default: - pr_err("failed: can't access base '%s': %s\n", - daemon->base, strerror(errno)); + pr_err("failed: can't access base '%s': %m\n", daemon->base); return -errno; } } @@ -544,8 +543,7 @@ static int daemon_session__control(struct daemon_session *session, err = writen(control, msg, len); if (err != len) { - pr_err("failed: write to control pipe: %d (%s)\n", - errno, control_path); + pr_err("failed: write to control pipe: %m (%s)\n", control_path); goto out; } @@ -586,7 +584,7 @@ static int setup_server_socket(struct daemon *daemon) int fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { - fprintf(stderr, "socket: %s\n", strerror(errno)); + fprintf(stderr, "socket: %m\n"); return -1; } diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c index ce51cbf6dc97..85f59886b5cf 100644 --- a/tools/perf/builtin-data.c +++ b/tools/perf/builtin-data.c @@ -33,6 +33,7 @@ const char *to_ctf; struct perf_data_convert_opts opts = { .force = false, .all = false, + .time_str = NULL, }; const struct option data_options[] = { @@ -45,6 +46,8 @@ const struct option data_options[] = { #endif OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"), OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"), + OPT_STRING(0, "time", &opts.time_str, "str", + "Time span of interest (start,stop)"), OPT_END() }; diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 53d5ea4a6a4f..59bf1f72d12e 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -178,10 +178,9 @@ static struct header_column { } }; -static int setup_compute_opt_wdiff(char *opt) +static int setup_compute_opt_wdiff(const char *opt) { - char *w1_str = opt; - char *w2_str; + const char *w1_str = opt, *w2_str; int ret = -EINVAL; @@ -192,8 +191,7 @@ static int setup_compute_opt_wdiff(char *opt) if (!w2_str) goto out; - *w2_str++ = 0x0; - if (!*w2_str) + if (!*++w2_str) goto out; compute_wdiff_w1 = strtol(w1_str, NULL, 10); @@ -214,7 +212,7 @@ static int setup_compute_opt_wdiff(char *opt) return ret; } -static int setup_compute_opt(char *opt) +static int setup_compute_opt(const char *opt) { if (compute == COMPUTE_WEIGHTED_DIFF) return setup_compute_opt_wdiff(opt); @@ -234,7 +232,7 @@ static int setup_compute(const struct option *opt, const char *str, char *cstr = (char *) str; char buf[50]; unsigned i; - char *option; + const char *option; if (!str) { *cp = COMPUTE_DELTA; diff --git a/tools/perf/builtin-ftrace.c b/tools/perf/builtin-ftrace.c index 6b6eec65f93f..4cc33452d79b 100644 --- a/tools/perf/builtin-ftrace.c +++ b/tools/perf/builtin-ftrace.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -1209,8 +1210,12 @@ static int prepare_func_profile(struct perf_ftrace *ftrace) ftrace->graph_verbose = 0; ftrace->profile_hash = hashmap__new(profile_hash, profile_equal, NULL); - if (ftrace->profile_hash == NULL) - return -ENOMEM; + if (IS_ERR(ftrace->profile_hash)) { + int err = PTR_ERR(ftrace->profile_hash); + + ftrace->profile_hash = NULL; + return err; + } return 0; } diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 7be6fb6df595..2692b2e40a23 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -9,7 +9,6 @@ #include "util/strbuf.h" #include "builtin.h" #include -#include "common-cmds.h" #include #include #include @@ -301,16 +300,58 @@ static struct cmdnames main_cmds, other_cmds; void list_common_cmds_help(void) { - unsigned int i, longest = 0; + const struct cmdname_help { + const char *name; + const char *help; + } common_cmds[] = { + {"annotate", "Read perf.data (created by perf record) and display annotated code"}, + {"archive", + "Create archive with object files with build-ids found in perf.data file"}, + {"bench", "General framework for benchmark suites"}, + {"buildid-cache", "Manage build-id cache."}, + {"buildid-list", "List the buildids in a perf.data file"}, + {"c2c", "Shared Data C2C/HITM Analyzer."}, + {"config", "Get and set variables in a configuration file."}, + {"daemon", "Run record sessions on background"}, + {"data", "Data file related processing"}, + {"diff", "Read perf.data files and display the differential profile"}, + {"evlist", "List the event names in a perf.data file"}, + {"ftrace", "simple wrapper for kernel's ftrace functionality"}, + {"inject", "Filter to augment the events stream with additional information"}, + {"iostat", "Show I/O performance metrics"}, + {"kallsyms", "Searches running kernel for symbols"}, + {"kvm", "Tool to trace/measure kvm guest os"}, + {"list", "List all symbolic event types"}, + {"mem", "Profile memory accesses"}, + {"record", "Run a command and record its profile into perf.data"}, + {"report", "Read perf.data (created by perf record) and display the profile"}, + {"script", "Read perf.data (created by perf record) and display trace output"}, + {"stat", "Run a command and gather performance counter statistics"}, + {"test", "Runs sanity tests."}, + {"top", "System profiling tool."}, + {"version", "display the version of perf binary"}, + #ifdef HAVE_LIBELF_SUPPORT + {"probe", "Define new dynamic tracepoints"}, + #endif /* HAVE_LIBELF_SUPPORT */ + #ifdef HAVE_LIBTRACEEVENT + {"trace", "strace inspired tool"}, + {"kmem", "Tool to trace/measure kernel memory properties"}, + {"kwork", "Tool to trace/measure kernel work properties (latencies)"}, + {"lock", "Analyze lock events"}, + {"sched", "Tool to trace/measure scheduler properties (latencies)"}, + {"timechart", "Tool to visualize total system behavior during a workload"}, + #endif /* HAVE_LIBTRACEEVENT */ + }; + size_t longest = 0; - for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { + for (size_t i = 0; i < ARRAY_SIZE(common_cmds); i++) { if (longest < strlen(common_cmds[i].name)) longest = strlen(common_cmds[i].name); } puts(" The most commonly used perf commands are:"); - for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { - printf(" %-*s ", longest, common_cmds[i].name); + for (size_t i = 0; i < ARRAY_SIZE(common_cmds); i++) { + printf(" %-*s ", (int)longest, common_cmds[i].name); puts(common_cmds[i].help); } } diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index aa7be4fb5838..5b29f4296861 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -122,6 +122,7 @@ struct perf_inject { bool in_place_update; bool in_place_update_dry_run; bool copy_kcore_dir; + bool convert_callchain; const char *input_name; struct perf_data output; u64 bytes_written; @@ -133,6 +134,7 @@ struct perf_inject { struct guest_session guest_session; struct strlist *known_build_ids; const struct evsel *mmap_evsel; + struct ip_callchain *raw_callchain; }; struct event_entry { @@ -383,6 +385,90 @@ static int perf_event__repipe_sample(const struct perf_tool *tool, return perf_event__repipe_synth(tool, event); } +static int perf_event__convert_sample_callchain(const struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample, + struct evsel *evsel, + struct machine *machine) +{ + struct perf_inject *inject = container_of(tool, struct perf_inject, tool); + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + union perf_event *event_copy = (void *)inject->event_copy; + struct callchain_cursor_node *node; + struct thread *thread; + u64 sample_type = evsel->core.attr.sample_type; + u32 sample_size = event->header.size; + u64 i, k; + int ret; + + if (event_copy == NULL) { + inject->event_copy = malloc(PERF_SAMPLE_MAX_SIZE); + if (!inject->event_copy) + return -ENOMEM; + + event_copy = (void *)inject->event_copy; + } + + if (cursor == NULL) + return -ENOMEM; + + callchain_cursor_reset(cursor); + + thread = machine__find_thread(machine, sample->tid, sample->pid); + if (thread == NULL) + goto out; + + /* this will parse DWARF using stack and register data */ + ret = thread__resolve_callchain(thread, cursor, evsel, sample, + /*parent=*/NULL, /*root_al=*/NULL, + PERF_MAX_STACK_DEPTH); + thread__put(thread); + if (ret != 0) + goto out; + + /* copy kernel callchain and context entries */ + for (i = 0; i < sample->callchain->nr; i++) { + inject->raw_callchain->ips[i] = sample->callchain->ips[i]; + if (sample->callchain->ips[i] == PERF_CONTEXT_USER) { + i++; + break; + } + } + if (i == 0 || inject->raw_callchain->ips[i - 1] != PERF_CONTEXT_USER) + inject->raw_callchain->ips[i++] = PERF_CONTEXT_USER; + + node = cursor->first; + for (k = 0; k < cursor->nr && i < PERF_MAX_STACK_DEPTH; k++) { + if (machine__kernel_ip(machine, node->ip)) + /* kernel IPs were added already */; + else if (node->ms.sym && node->ms.sym->inlined) + /* we can't handle inlined callchains */; + else + inject->raw_callchain->ips[i++] = node->ip; + + node = node->next; + } + + inject->raw_callchain->nr = i; + sample->callchain = inject->raw_callchain; + +out: + memcpy(event_copy, event, sizeof(event->header)); + + /* adjust sample size for stack and regs */ + sample_size -= sample->user_stack.size; + sample_size -= (hweight64(evsel->core.attr.sample_regs_user) + 1) * sizeof(u64); + sample_size += (sample->callchain->nr + 1) * sizeof(u64); + event_copy->header.size = sample_size; + + /* remove sample_type {STACK,REGS}_USER for synthesize */ + sample_type &= ~(PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER); + + perf_event__synthesize_sample(event_copy, sample_type, + evsel->core.attr.read_format, sample); + return perf_event__repipe_synth(tool, event_copy); +} + static struct dso *findnew_dso(int pid, int tid, const char *filename, const struct dso_id *id, struct machine *machine) { @@ -2022,7 +2108,7 @@ static int save_section_info(struct perf_inject *inject) return perf_header__process_sections(header, fd, inject, save_section_info_cb); } -static bool keep_feat(int feat) +static bool keep_feat(struct perf_inject *inject, int feat) { switch (feat) { /* Keep original information that describes the machine or software */ @@ -2047,9 +2133,11 @@ static bool keep_feat(int feat) case HEADER_CLOCK_DATA: case HEADER_HYBRID_TOPOLOGY: case HEADER_PMU_CAPS: + case HEADER_CPU_DOMAIN_INFO: return true; /* Information that can be updated */ case HEADER_BUILD_ID: + return inject->build_id_style == BID_RWS__NONE; case HEADER_CMDLINE: case HEADER_EVENT_DESC: case HEADER_BRANCH_STACK: @@ -2108,7 +2196,7 @@ static int feat_copy_cb(struct feat_copier *fc, int feat, struct feat_writer *fw int ret; if (!inject->secs[feat].offset || - !keep_feat(feat)) + !keep_feat(inject, feat)) return 0; ret = feat_copy(inject, feat, fw); @@ -2269,6 +2357,15 @@ static int __cmd_inject(struct perf_inject *inject) /* Allow space in the header for guest attributes */ output_data_offset += gs->session->header.data_offset; output_data_offset = roundup(output_data_offset, 4096); + } else if (inject->convert_callchain) { + inject->tool.sample = perf_event__convert_sample_callchain; + inject->tool.fork = perf_event__repipe_fork; + inject->tool.comm = perf_event__repipe_comm; + inject->tool.exit = perf_event__repipe_exit; + inject->tool.mmap = perf_event__repipe_mmap; + inject->tool.mmap2 = perf_event__repipe_mmap2; + inject->tool.ordered_events = true; + inject->tool.ordering_requires_timestamps = true; } if (!inject->itrace_synth_opts.set) @@ -2321,6 +2418,23 @@ static int __cmd_inject(struct perf_inject *inject) perf_header__set_feat(&session->header, HEADER_BRANCH_STACK); } + + /* + * The converted data file won't have stack and registers. + * Update the perf_event_attr to remove them before writing. + */ + if (inject->convert_callchain) { + struct evsel *evsel; + + evlist__for_each_entry(session->evlist, evsel) { + evsel__reset_sample_bit(evsel, REGS_USER); + evsel__reset_sample_bit(evsel, STACK_USER); + evsel->core.attr.sample_regs_user = 0; + evsel->core.attr.sample_stack_user = 0; + evsel->core.attr.exclude_callchain_user = 0; + } + } + session->header.data_offset = output_data_offset; session->header.data_size = inject->bytes_written; perf_session__inject_header(session, session->evlist, fd, &inj_fc.fc, @@ -2345,6 +2459,18 @@ static int __cmd_inject(struct perf_inject *inject) return ret; } +static bool evsel__has_dwarf_callchain(struct evsel *evsel) +{ + struct perf_event_attr *attr = &evsel->core.attr; + const u64 dwarf_callchain_flags = + PERF_SAMPLE_STACK_USER | PERF_SAMPLE_REGS_USER | PERF_SAMPLE_CALLCHAIN; + + if (!attr->exclude_callchain_user) + return false; + + return (attr->sample_type & dwarf_callchain_flags) == dwarf_callchain_flags; +} + int cmd_inject(int argc, const char **argv) { struct perf_inject inject = { @@ -2413,6 +2539,8 @@ int cmd_inject(int argc, const char **argv) OPT_STRING(0, "guestmount", &symbol_conf.guestmount, "directory", "guest mount directory under which every guest os" " instance has a subdir"), + OPT_BOOLEAN(0, "convert-callchain", &inject.convert_callchain, + "Generate callchains using DWARF and drop register/stack data"), OPT_END() }; const char * const inject_usage[] = { @@ -2428,6 +2556,9 @@ int cmd_inject(int argc, const char **argv) #ifndef HAVE_JITDUMP set_option_nobuild(options, 'j', "jit", "NO_LIBELF=1", true); +#endif +#ifndef HAVE_LIBDW_SUPPORT + set_option_nobuild(options, 0, "convert-callchain", "NO_LIBDW=1", true); #endif argc = parse_options(argc, argv, options, inject_usage, 0); @@ -2526,6 +2657,8 @@ int cmd_inject(int argc, const char **argv) inject.tool.compressed = perf_event__repipe_op4_synth; inject.tool.auxtrace = perf_event__repipe_auxtrace; inject.tool.bpf_metadata = perf_event__repipe_op2_synth; + inject.tool.schedstat_cpu = perf_event__repipe_op2_synth; + inject.tool.schedstat_domain = perf_event__repipe_op2_synth; inject.tool.dont_split_sample_group = true; inject.tool.merge_deferred_callchains = false; inject.session = __perf_session__new(&data, &inject.tool, @@ -2587,6 +2720,28 @@ int cmd_inject(int argc, const char **argv) } } + if (inject.convert_callchain) { + struct evsel *evsel; + + if (inject.output.is_pipe || inject.session->data->is_pipe) { + pr_err("--convert-callchain cannot work with pipe\n"); + goto out_delete; + } + + evlist__for_each_entry(inject.session->evlist, evsel) { + if (!evsel__has_dwarf_callchain(evsel) && !evsel__is_dummy_event(evsel)) { + pr_err("--convert-callchain requires DWARF call graph.\n"); + goto out_delete; + } + } + + inject.raw_callchain = calloc(PERF_MAX_STACK_DEPTH, sizeof(u64)); + if (inject.raw_callchain == NULL) { + pr_err("callchain allocation failed\n"); + goto out_delete; + } + } + #ifdef HAVE_JITDUMP if (inject.jit_mode) { inject.tool.mmap2 = perf_event__repipe_mmap2; @@ -2617,5 +2772,6 @@ int cmd_inject(int argc, const char **argv) free(inject.itrace_synth_opts.vm_tm_corr_args); free(inject.event_copy); free(inject.guest_session.ev.event_buf); + free(inject.raw_callchain); return ret; } diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index c61369d54dd9..0c5e6b3aac74 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "perf.h" +#include #include "util/build-id.h" #include "util/evsel.h" #include "util/evlist.h" @@ -52,7 +53,7 @@ #include #include -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#if defined(HAVE_LIBTRACEEVENT) #define GET_EVENT_KEY(func, field) \ static u64 get_event_ ##func(struct kvm_event *event, int vcpu) \ { \ @@ -597,7 +598,7 @@ static void kvm_display(struct perf_kvm_stat *kvm) #endif /* HAVE_SLANG_SUPPORT */ -#endif // defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#endif // defined(HAVE_LIBTRACEEVENT) static const char *get_filename_for_perf_kvm(void) { @@ -613,13 +614,13 @@ static const char *get_filename_for_perf_kvm(void) return filename; } -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#if defined(HAVE_LIBTRACEEVENT) -static bool register_kvm_events_ops(struct perf_kvm_stat *kvm) +static bool register_kvm_events_ops(struct perf_kvm_stat *kvm, uint16_t e_machine) { - struct kvm_reg_events_ops *events_ops = kvm_reg_events_ops; + const struct kvm_reg_events_ops *events_ops; - for (events_ops = kvm_reg_events_ops; events_ops->name; events_ops++) { + for (events_ops = kvm_reg_events_ops(e_machine); events_ops->name; events_ops++) { if (!strcmp(events_ops->name, kvm->report_event)) { kvm->events_ops = events_ops->ops; return true; @@ -809,7 +810,7 @@ static bool is_child_event(struct perf_kvm_stat *kvm, struct perf_sample *sample, struct event_key *key) { - struct child_event_ops *child_ops; + const struct child_event_ops *child_ops; child_ops = kvm->events_ops->child_ops; @@ -841,11 +842,11 @@ static bool handle_child_event(struct perf_kvm_stat *kvm, return true; } -static bool skip_event(const char *event) +static bool skip_event(uint16_t e_machine, const char *event) { const char * const *skip_events; - for (skip_events = kvm_skip_events; *skip_events; skip_events++) + for (skip_events = kvm_skip_events(e_machine); *skip_events; skip_events++) if (!strcmp(event, *skip_events)) return true; @@ -901,9 +902,10 @@ static bool handle_end_event(struct perf_kvm_stat *kvm, if (kvm->duration && time_diff > kvm->duration) { char decode[KVM_EVENT_NAME_LEN]; + uint16_t e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); kvm->events_ops->decode_key(kvm, &event->key, decode); - if (!skip_event(decode)) { + if (!skip_event(e_machine, decode)) { pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n", sample->time, sample->pid, vcpu_record->vcpu_id, decode, time_diff / NSEC_PER_USEC); @@ -921,6 +923,8 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, /* Only kvm_entry records vcpu id. */ if (!thread__priv(thread) && kvm_entry_event(evsel)) { struct vcpu_event_record *vcpu_record; + struct machine *machine = maps__machine(thread__maps(thread)); + uint16_t e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL); vcpu_record = zalloc(sizeof(*vcpu_record)); if (!vcpu_record) { @@ -928,7 +932,7 @@ struct vcpu_event_record *per_vcpu_record(struct thread *thread, return NULL; } - vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str); + vcpu_record->vcpu_id = evsel__intval(evsel, sample, vcpu_id_str(e_machine)); thread__set_priv(thread, vcpu_record); } @@ -1163,6 +1167,7 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm) { char buf[128], *cpuid; int err; + uint16_t e_machine; if (kvm->live) { struct perf_cpu cpu = {-1}; @@ -1182,7 +1187,8 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm) return -EINVAL; } - err = cpu_isa_init(kvm, cpuid); + e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); + err = cpu_isa_init(kvm, e_machine, cpuid); if (err == -ENOTSUP) pr_err("CPU %s is not supported.\n", cpuid); @@ -1413,7 +1419,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm) if (!verify_vcpu(kvm->trace_vcpu) || !is_valid_key(kvm) || - !register_kvm_events_ops(kvm)) { + !register_kvm_events_ops(kvm, EM_HOST)) { goto out; } @@ -1543,7 +1549,7 @@ static int kvm_live_open_events(struct perf_kvm_stat *kvm) static int read_events(struct perf_kvm_stat *kvm) { int ret; - + uint16_t e_machine; struct perf_data file = { .path = kvm->file_name, .mode = PERF_DATA_MODE_READ, @@ -1568,6 +1574,12 @@ static int read_events(struct perf_kvm_stat *kvm) goto out_delete; } + e_machine = perf_session__e_machine(kvm->session, /*e_flags=*/NULL); + if (!register_kvm_events_ops(kvm, e_machine)) { + ret = -EINVAL; + goto out_delete; + } + /* * Do not use 'isa' recorded in kvm_exit tracepoint since it is not * traced in the old kernel. @@ -1610,9 +1622,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) if (!is_valid_key(kvm)) goto exit; - if (!register_kvm_events_ops(kvm)) - goto exit; - if (kvm->use_stdio) { use_browser = 0; setup_pager(); @@ -1636,11 +1645,6 @@ static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm) return ret; } -int __weak setup_kvm_events_tp(struct perf_kvm_stat *kvm __maybe_unused) -{ - return 0; -} - static int kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) { @@ -1658,15 +1662,16 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) }; const char * const *events_tp; int ret; + uint16_t e_machine = EM_HOST; events_tp_size = 0; - ret = setup_kvm_events_tp(kvm); + ret = setup_kvm_events_tp(kvm, e_machine); if (ret < 0) { pr_err("Unable to setup the kvm tracepoints\n"); return ret; } - for (events_tp = kvm_events_tp; *events_tp; events_tp++) + for (events_tp = kvm_events_tp(e_machine); *events_tp; events_tp++) events_tp_size++; rec_argc = ARRAY_SIZE(record_args) + argc + 2 + @@ -1681,7 +1686,7 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv) for (j = 0; j < events_tp_size; j++) { rec_argv[i++] = STRDUP_FAIL_EXIT("-e"); - rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]); + rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp(e_machine)[j]); } rec_argv[i++] = STRDUP_FAIL_EXIT("-o"); @@ -1775,7 +1780,7 @@ static struct evlist *kvm_live_event_list(void) if (evlist == NULL) return NULL; - for (events_tp = kvm_events_tp; *events_tp; events_tp++) { + for (events_tp = kvm_events_tp(EM_HOST); *events_tp; events_tp++) { tp = strdup(*events_tp); if (tp == NULL) @@ -1900,7 +1905,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm, /* * generate the event list */ - err = setup_kvm_events_tp(kvm); + err = setup_kvm_events_tp(kvm, EM_HOST); if (err < 0) { pr_err("Unable to setup the kvm tracepoints\n"); return err; @@ -1985,13 +1990,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv) perf_stat: return cmd_stat(argc, argv); } -#endif /* HAVE_KVM_STAT_SUPPORT */ - -int __weak kvm_add_default_arch_event(int *argc __maybe_unused, - const char **argv __maybe_unused) -{ - return 0; -} +#endif /* HAVE_LIBTRACEEVENT */ static int __cmd_record(const char *file_name, int argc, const char **argv) { @@ -2016,7 +2015,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) BUG_ON(i + 2 != rec_argc); - ret = kvm_add_default_arch_event(&i, rec_argv); + ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); if (ret) goto EXIT; @@ -2103,7 +2102,7 @@ static int __cmd_top(int argc, const char **argv) BUG_ON(i != argc); - ret = kvm_add_default_arch_event(&i, rec_argv); + ret = kvm_add_default_arch_event(EM_HOST, &i, rec_argv); if (ret) goto EXIT; @@ -2179,7 +2178,7 @@ int cmd_kvm(int argc, const char **argv) return __cmd_top(argc, argv); else if (strlen(argv[0]) > 2 && strstarts("buildid-list", argv[0])) return __cmd_buildid_list(file_name, argc, argv); -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#if defined(HAVE_LIBTRACEEVENT) else if (strlen(argv[0]) > 2 && strstarts("stat", argv[0])) return kvm_cmd_stat(file_name, argc, argv); #endif diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 87a5491048ac..50f69c2c0d51 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -648,7 +648,7 @@ int cmd_list(int argc, const char **argv) } for (i = 0; i < argc; ++i) { - char *sep, *s; + char *s; if (strcmp(argv[i], "tracepoint") == 0) { char *old_pmu_glob = default_ps.pmu_glob; @@ -720,7 +720,7 @@ int cmd_list(int argc, const char **argv) else if (strcmp(argv[i], "pfm") == 0) print_libpfm_events(&print_cb, ps); #endif - else if ((sep = strchr(argv[i], ':')) != NULL) { + else if (strchr(argv[i], ':') != NULL) { char *old_pmu_glob = ps->pmu_glob; char *old_event_glob = ps->event_glob; diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 69800e4d9530..1b4ba85ee019 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c @@ -211,8 +211,7 @@ static int opt_set_target_ns(const struct option *opt __maybe_unused, ns_pid = (pid_t)strtol(str, NULL, 10); if (errno != 0) { ret = -errno; - pr_warning("Failed to parse %s as a pid: %s\n", str, - strerror(errno)); + pr_warning("Failed to parse %s as a pid: %m\n", str); return ret; } nsip = nsinfo__new(ns_pid); diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 2584d0d8bc82..60d764068302 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1286,7 +1286,6 @@ static int record__mmap_evlist(struct record *rec, struct record_opts *opts = &rec->opts; bool auxtrace_overwrite = opts->auxtrace_snapshot_mode || opts->auxtrace_sample_mode; - char msg[512]; if (opts->affinity != PERF_AFFINITY_SYS) cpu__setup_cpunode_map(); @@ -1305,8 +1304,7 @@ static int record__mmap_evlist(struct record *rec, opts->mmap_pages, opts->auxtrace_mmap_pages); return -errno; } else { - pr_err("failed to mmap with %d (%s)\n", errno, - str_error_r(errno, msg, sizeof(msg))); + pr_err("failed to mmap: %m\n"); if (errno) return -errno; else @@ -1324,7 +1322,8 @@ static int record__mmap_evlist(struct record *rec, if (record__threads_enabled(rec)) { ret = perf_data__create_dir(&rec->data, evlist->core.nr_mmaps); if (ret) { - pr_err("Failed to create data directory: %s\n", strerror(-ret)); + errno = -ret; + pr_err("Failed to create data directory: %m\n"); return ret; } for (i = 0; i < evlist->core.nr_mmaps; i++) { @@ -1404,6 +1403,7 @@ static int record__open(struct record *rec) } #endif if (report_error || verbose > 0) { + evsel__open_strerror(pos, &opts->target, errno, msg, sizeof(msg)); ui__error("Failure to open event '%s' on PMU '%s' which will be " "removed.\n%s\n", evsel__name(pos), evsel__pmu_name(pos), msg); @@ -1461,9 +1461,8 @@ static int record__open(struct record *rec) } if (evlist__apply_filters(evlist, &pos, &opts->target)) { - pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", - pos->filter ?: "BPF", evsel__name(pos), errno, - str_error_r(errno, msg, sizeof(msg))); + pr_err("failed to set filter \"%s\" on event %s: %m\n", + pos->filter ?: "BPF", evsel__name(pos)); rc = -1; goto out; } @@ -1511,6 +1510,8 @@ static int process_buildids(struct record *rec) if (perf_data__size(&rec->data) == 0) return 0; + /* A single DSO is needed and not all inline frames. */ + symbol_conf.inline_name = false; /* * During this process, it'll load kernel map and replace the * dso->long_name to a real pathname it found. In this case @@ -1521,7 +1522,6 @@ static int process_buildids(struct record *rec) * $HOME/.debug/.build-id/f0/6e17aa50adf4d00b88925e03775de107611551 */ symbol_conf.ignore_vmlinux_buildid = true; - /* * If --buildid-all is given, it marks all DSO regardless of hits, * so no need to process samples. But if timestamp_boundary is enabled, @@ -1748,8 +1748,7 @@ static void *record__thread(void *arg) err = write(thread->pipes.ack[1], &msg, sizeof(msg)); if (err == -1) - pr_warning("threads[%d]: failed to notify on start: %s\n", - thread->tid, strerror(errno)); + pr_warning("threads[%d]: failed to notify on start: %m\n", thread->tid); pr_debug("threads[%d]: started on cpu%d\n", thread->tid, sched_getcpu()); @@ -1792,8 +1791,7 @@ static void *record__thread(void *arg) err = write(thread->pipes.ack[1], &msg, sizeof(msg)); if (err == -1) - pr_warning("threads[%d]: failed to notify on termination: %s\n", - thread->tid, strerror(errno)); + pr_warning("threads[%d]: failed to notify on termination: %m\n", thread->tid); return NULL; } @@ -1881,7 +1879,7 @@ static int record__synthesize_workload(struct record *rec, bool tail) process_synthesized_event, &rec->session->machines.host, needs_mmap, - rec->opts.sample_address); + rec->opts.record_data_mmap); perf_thread_map__put(thread_map); return err; } @@ -2191,7 +2189,7 @@ static int record__synthesize(struct record *rec, bool tail) err = __machine__synthesize_threads(machine, tool, &opts->target, rec->evlist->core.threads, - f, needs_mmap, opts->sample_address, + f, needs_mmap, opts->record_data_mmap, rec->opts.nr_threads_synthesize); } @@ -2338,7 +2336,7 @@ static int record__start_threads(struct record *rec) sigfillset(&full); if (sigprocmask(SIG_SETMASK, &full, &mask)) { - pr_err("Failed to block signals on threads start: %s\n", strerror(errno)); + pr_err("Failed to block signals on threads start: %m\n"); return -1; } @@ -2356,7 +2354,7 @@ static int record__start_threads(struct record *rec) if (pthread_create(&handle, &attrs, record__thread, &thread_data[t])) { for (tt = 1; tt < t; tt++) record__terminate_thread(&thread_data[t]); - pr_err("Failed to start threads: %s\n", strerror(errno)); + pr_err("Failed to start threads: %m\n"); ret = -1; goto out_err; } @@ -2379,7 +2377,7 @@ static int record__start_threads(struct record *rec) pthread_attr_destroy(&attrs); if (sigprocmask(SIG_SETMASK, &mask, NULL)) { - pr_err("Failed to unblock signals on threads start: %s\n", strerror(errno)); + pr_err("Failed to unblock signals on threads start: %m\n"); ret = -1; } @@ -3006,8 +3004,9 @@ int record_opts__parse_callchain(struct record_opts *record, ret = parse_callchain_record_opt(arg, callchain); if (!ret) { /* Enable data address sampling for DWARF unwind. */ - if (callchain->record_mode == CALLCHAIN_DWARF) - record->sample_address = true; + if (callchain->record_mode == CALLCHAIN_DWARF && + !record->record_data_mmap_set) + record->record_data_mmap = true; callchain_debug(callchain); } @@ -3686,6 +3685,9 @@ static struct option __record_options[] = { OPT_CALLBACK(0, "off-cpu-thresh", &record.opts, "ms", "Dump off-cpu samples if off-cpu time exceeds this threshold (in milliseconds). (Default: 500ms)", record__parse_off_cpu_thresh), + OPT_BOOLEAN_SET(0, "data-mmap", &record.opts.record_data_mmap, + &record.opts.record_data_mmap_set, + "Record mmap events for non-executable mappings"), OPT_END() }; @@ -4249,9 +4251,12 @@ int cmd_record(int argc, const char **argv) goto out_opts; } - /* For backward compatibility, -d implies --mem-info */ - if (rec->opts.sample_address) + /* For backward compatibility, -d implies --mem-info and --data-mmap */ + if (rec->opts.sample_address) { rec->opts.sample_data_src = true; + if (!rec->opts.record_data_mmap_set) + rec->opts.record_data_mmap = true; + } /* * Allow aliases to facilitate the lookup of symbols for address diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index add6b1c2aaf0..3b81f4b3dc49 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -448,7 +448,7 @@ static int report__setup_sample_type(struct report *rep) } } - callchain_param_setup(sample_type, perf_env__arch(perf_session__env(rep->session))); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL)); if (rep->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) { ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n" @@ -1271,12 +1271,18 @@ parse_percent_limit(const struct option *opt, const char *str, return 0; } +static int +report_parse_addr2line_config(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused) +{ + return addr2line_configure("addr2line.style", arg, NULL); +} + static int process_attr(const struct perf_tool *tool __maybe_unused, union perf_event *event, struct evlist **pevlist) { struct perf_session *session; - struct perf_env *env; u64 sample_type; int err; @@ -1290,8 +1296,7 @@ static int process_attr(const struct perf_tool *tool __maybe_unused, */ sample_type = evlist__combined_sample_type(*pevlist); session = (*pevlist)->session; - env = perf_session__env(session); - callchain_param_setup(sample_type, perf_env__arch(env)); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL)); return 0; } @@ -1447,6 +1452,9 @@ int cmd_report(int argc, const char **argv) "objdump binary to use for disassembly and annotations"), OPT_STRING(0, "addr2line", &addr2line_path, "path", "addr2line binary to use for line numbers"), + OPT_CALLBACK(0, "addr2line-style", NULL, "addr2line style", + "addr2line styles (libdw,llvm,libbfd,addr2line)", + report_parse_addr2line_config), OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, "Symbol demangling. Enabled by default, use --no-demangle to disable."), OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel, @@ -1727,7 +1735,8 @@ int cmd_report(int argc, const char **argv) sort_order = NULL; } - if (sort_order && strstr(sort_order, "type")) { + if ((sort_order && strstr(sort_order, "type")) || + (field_order && strstr(field_order, "type"))) { report.data_type = true; annotate_opts.annotate_src = false; diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index eca3b1c58c4b..3f509cfdd58c 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c @@ -28,6 +28,8 @@ #include "util/debug.h" #include "util/event.h" #include "util/util.h" +#include "util/synthetic-events.h" +#include "util/target.h" #include #include @@ -53,8 +55,10 @@ #define SYM_LEN 129 #define MAX_PID 1024000 #define MAX_PRIO 140 +#define SEP_LEN 100 static const char *cpu_list; +static struct perf_cpu_map *user_requested_cpus; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); struct sched_atom; @@ -236,6 +240,9 @@ struct perf_sched { volatile bool thread_funcs_exit; const char *prio_str; DECLARE_BITMAP(prio_bitmap, MAX_PRIO); + + struct perf_session *session; + struct perf_data *data; }; /* per thread run time data */ @@ -3734,6 +3741,993 @@ static void setup_sorting(struct perf_sched *sched, const struct option *options sort_dimension__add("pid", &sched->cmp_pid); } +static int process_synthesized_schedstat_event(const struct perf_tool *tool, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct perf_sched *sched = container_of(tool, struct perf_sched, tool); + + if (perf_data__write(sched->data, event, event->header.size) <= 0) { + pr_err("failed to write perf data, error: %m\n"); + return -1; + } + + sched->session->header.data_size += event->header.size; + return 0; +} + +static void sighandler(int sig __maybe_unused) +{ +} + +static int enable_sched_schedstats(int *reset) +{ + char path[PATH_MAX]; + FILE *fp; + char ch; + + snprintf(path, PATH_MAX, "%s/sys/kernel/sched_schedstats", procfs__mountpoint()); + fp = fopen(path, "w+"); + if (!fp) { + pr_err("Failed to open %s\n", path); + return -1; + } + + ch = getc(fp); + if (ch == '0') { + *reset = 1; + rewind(fp); + putc('1', fp); + fclose(fp); + } + return 0; +} + +static int disable_sched_schedstat(void) +{ + char path[PATH_MAX]; + FILE *fp; + + snprintf(path, PATH_MAX, "%s/sys/kernel/sched_schedstats", procfs__mountpoint()); + fp = fopen(path, "w"); + if (!fp) { + pr_err("Failed to open %s\n", path); + return -1; + } + + putc('0', fp); + fclose(fp); + return 0; +} + +/* perf.data or any other output file name used by stats subcommand (only). */ +const char *output_name; + +static int perf_sched__schedstat_record(struct perf_sched *sched, + int argc, const char **argv) +{ + struct perf_session *session; + struct target target = {}; + struct evlist *evlist; + int reset = 0; + int err = 0; + int fd; + struct perf_data data = { + .path = output_name, + .mode = PERF_DATA_MODE_WRITE, + }; + + signal(SIGINT, sighandler); + signal(SIGCHLD, sighandler); + signal(SIGTERM, sighandler); + + evlist = evlist__new(); + if (!evlist) + return -ENOMEM; + + session = perf_session__new(&data, &sched->tool); + if (IS_ERR(session)) { + pr_err("Perf session creation failed.\n"); + evlist__delete(evlist); + return PTR_ERR(session); + } + + session->evlist = evlist; + + sched->session = session; + sched->data = &data; + + fd = perf_data__fd(&data); + + /* + * Capture all important metadata about the system. Although they are + * not used by `perf sched stats` tool directly, they provide useful + * information about profiled environment. + */ + perf_header__set_feat(&session->header, HEADER_HOSTNAME); + perf_header__set_feat(&session->header, HEADER_OSRELEASE); + perf_header__set_feat(&session->header, HEADER_VERSION); + perf_header__set_feat(&session->header, HEADER_ARCH); + perf_header__set_feat(&session->header, HEADER_NRCPUS); + perf_header__set_feat(&session->header, HEADER_CPUDESC); + perf_header__set_feat(&session->header, HEADER_CPUID); + perf_header__set_feat(&session->header, HEADER_TOTAL_MEM); + perf_header__set_feat(&session->header, HEADER_CMDLINE); + perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_NUMA_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_CACHE); + perf_header__set_feat(&session->header, HEADER_MEM_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_HYBRID_TOPOLOGY); + perf_header__set_feat(&session->header, HEADER_CPU_DOMAIN_INFO); + + err = perf_session__write_header(session, evlist, fd, false); + if (err < 0) + goto out; + + /* + * `perf sched stats` does not support workload profiling (-p pid) + * since /proc/schedstat file contains cpu specific data only. Hence, a + * profile target is either set of cpus or systemwide, never a process. + * Note that, although `-- ` is supported, profile data are + * still cpu/systemwide. + */ + if (cpu_list) + target.cpu_list = cpu_list; + else + target.system_wide = true; + + if (argc) { + err = evlist__prepare_workload(evlist, &target, argv, false, NULL); + if (err) + goto out; + } + + err = evlist__create_maps(evlist, &target); + if (err < 0) + goto out; + + user_requested_cpus = evlist->core.user_requested_cpus; + + err = perf_event__synthesize_schedstat(&(sched->tool), + process_synthesized_schedstat_event, + user_requested_cpus); + if (err < 0) + goto out; + + err = enable_sched_schedstats(&reset); + if (err < 0) + goto out; + + if (argc) + evlist__start_workload(evlist); + + /* wait for signal */ + pause(); + + if (reset) { + err = disable_sched_schedstat(); + if (err < 0) + goto out; + } + + err = perf_event__synthesize_schedstat(&(sched->tool), + process_synthesized_schedstat_event, + user_requested_cpus); + if (err < 0) + goto out; + + err = perf_session__write_header(session, evlist, fd, true); + +out: + if (!err) + fprintf(stderr, "[ perf sched stats: Wrote samples to %s ]\n", data.path); + else + fprintf(stderr, "[ perf sched stats: Failed !! ]\n"); + + evlist__delete(evlist); + close(fd); + return err; +} + +struct schedstat_domain { + struct list_head domain_list; + struct perf_record_schedstat_domain *domain_data; +}; + +struct schedstat_cpu { + struct list_head cpu_list; + struct list_head domain_head; + struct perf_record_schedstat_cpu *cpu_data; +}; + +static struct list_head cpu_head = LIST_HEAD_INIT(cpu_head); +static struct schedstat_cpu *cpu_second_pass; +static struct schedstat_domain *domain_second_pass; +static bool after_workload_flag; +static bool verbose_field; + +static void store_schedstat_cpu_diff(struct schedstat_cpu *after_workload) +{ + struct perf_record_schedstat_cpu *before = cpu_second_pass->cpu_data; + struct perf_record_schedstat_cpu *after = after_workload->cpu_data; + __u16 version = after_workload->cpu_data->version; + +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) \ + (before->_ver._name = after->_ver._name - before->_ver._name) + + if (version == 15) { +#include + } else if (version == 16) { +#include + } else if (version == 17) { +#include + } + +#undef CPU_FIELD +} + +static void store_schedstat_domain_diff(struct schedstat_domain *after_workload) +{ + struct perf_record_schedstat_domain *before = domain_second_pass->domain_data; + struct perf_record_schedstat_domain *after = after_workload->domain_data; + __u16 version = after_workload->domain_data->version; + +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) \ + (before->_ver._name = after->_ver._name - before->_ver._name) + + if (version == 15) { +#include + } else if (version == 16) { +#include + } else if (version == 17) { +#include + } +#undef DOMAIN_FIELD +} + +#define PCT_CHNG(_x, _y) ((_x) ? ((double)((double)(_y) - (_x)) / (_x)) * 100 : 0.0) +static inline void print_cpu_stats(struct perf_record_schedstat_cpu *cs1, + struct perf_record_schedstat_cpu *cs2) +{ + printf("%-65s ", "DESC"); + if (!cs2) + printf("%12s %12s", "COUNT", "PCT_CHANGE"); + else + printf("%12s %11s %12s %14s %10s", "COUNT1", "COUNT2", "PCT_CHANGE", + "PCT_CHANGE1", "PCT_CHANGE2"); + + printf("\n"); + print_separator2(SEP_LEN, "", 0); + +#define CALC_PCT(_x, _y) ((_y) ? ((double)(_x) / (_y)) * 100 : 0.0) + +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) \ + do { \ + printf("%-65s: " _format, verbose_field ? _desc : #_name, \ + cs1->_ver._name); \ + if (!cs2) { \ + if (_is_pct) \ + printf(" ( %8.2lf%% )", \ + CALC_PCT(cs1->_ver._name, cs1->_ver._pct_of)); \ + } else { \ + printf("," _format " | %8.2lf%% |", cs2->_ver._name, \ + PCT_CHNG(cs1->_ver._name, cs2->_ver._name)); \ + if (_is_pct) \ + printf(" ( %8.2lf%%, %8.2lf%% )", \ + CALC_PCT(cs1->_ver._name, cs1->_ver._pct_of), \ + CALC_PCT(cs2->_ver._name, cs2->_ver._pct_of)); \ + } \ + printf("\n"); \ + } while (0) + + if (cs1->version == 15) { +#include + } else if (cs1->version == 16) { +#include + } else if (cs1->version == 17) { +#include + } + +#undef CPU_FIELD +#undef CALC_PCT +} + +static inline void print_domain_stats(struct perf_record_schedstat_domain *ds1, + struct perf_record_schedstat_domain *ds2, + __u64 jiffies1, __u64 jiffies2) +{ + printf("%-65s ", "DESC"); + if (!ds2) + printf("%12s %14s", "COUNT", "AVG_JIFFIES"); + else + printf("%12s %11s %12s %16s %12s", "COUNT1", "COUNT2", "PCT_CHANGE", + "AVG_JIFFIES1", "AVG_JIFFIES2"); + printf("\n"); + +#define DOMAIN_CATEGORY(_desc) \ + do { \ + size_t _len = strlen(_desc); \ + size_t _pre_dash_cnt = (SEP_LEN - _len) / 2; \ + size_t _post_dash_cnt = SEP_LEN - _len - _pre_dash_cnt; \ + print_separator2((int)_pre_dash_cnt, _desc, (int)_post_dash_cnt);\ + } while (0) + +#define CALC_AVG(_x, _y) ((_y) ? (long double)(_x) / (_y) : 0.0) + +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) \ + do { \ + printf("%-65s: " _format, verbose_field ? _desc : #_name, \ + ds1->_ver._name); \ + if (!ds2) { \ + if (_is_jiffies) \ + printf(" $ %11.2Lf $", \ + CALC_AVG(jiffies1, ds1->_ver._name)); \ + } else { \ + printf("," _format " | %8.2lf%% |", ds2->_ver._name, \ + PCT_CHNG(ds1->_ver._name, ds2->_ver._name)); \ + if (_is_jiffies) \ + printf(" $ %11.2Lf, %11.2Lf $", \ + CALC_AVG(jiffies1, ds1->_ver._name), \ + CALC_AVG(jiffies2, ds2->_ver._name)); \ + } \ + printf("\n"); \ + } while (0) + +#define DERIVED_CNT_FIELD(_name, _desc, _format, _x, _y, _z, _ver) \ + do { \ + __u32 t1 = ds1->_ver._x - ds1->_ver._y - ds1->_ver._z; \ + printf("*%-64s: " _format, verbose_field ? _desc : #_name, t1); \ + if (ds2) { \ + __u32 t2 = ds2->_ver._x - ds2->_ver._y - ds2->_ver._z; \ + printf("," _format " | %8.2lf%% |", t2, \ + PCT_CHNG(t1, t2)); \ + } \ + printf("\n"); \ + } while (0) + +#define DERIVED_AVG_FIELD(_name, _desc, _format, _x, _y, _z, _w, _ver) \ + do { \ + __u32 t1 = ds1->_ver._x - ds1->_ver._y - ds1->_ver._z; \ + printf("*%-64s: " _format, verbose_field ? _desc : #_name, \ + CALC_AVG(ds1->_ver._w, t1)); \ + if (ds2) { \ + __u32 t2 = ds2->_ver._x - ds2->_ver._y - ds2->_ver._z; \ + printf("," _format " | %8.2Lf%% |", \ + CALC_AVG(ds2->_ver._w, t2), \ + PCT_CHNG(CALC_AVG(ds1->_ver._w, t1), \ + CALC_AVG(ds2->_ver._w, t2))); \ + } \ + printf("\n"); \ + } while (0) + + if (ds1->version == 15) { +#include + } else if (ds1->version == 16) { +#include + } else if (ds1->version == 17) { +#include + } + +#undef DERIVED_AVG_FIELD +#undef DERIVED_CNT_FIELD +#undef DOMAIN_FIELD +#undef CALC_AVG +#undef DOMAIN_CATEGORY +} +#undef PCT_CHNG + +static void summarize_schedstat_cpu(struct schedstat_cpu *summary_cpu, + struct schedstat_cpu *cptr, + int cnt, bool is_last) +{ + struct perf_record_schedstat_cpu *summary_cs = summary_cpu->cpu_data, + *temp_cs = cptr->cpu_data; + +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) \ + do { \ + summary_cs->_ver._name += temp_cs->_ver._name; \ + if (is_last) \ + summary_cs->_ver._name /= cnt; \ + } while (0) + + if (cptr->cpu_data->version == 15) { +#include + } else if (cptr->cpu_data->version == 16) { +#include + } else if (cptr->cpu_data->version == 17) { +#include + } +#undef CPU_FIELD +} + +static void summarize_schedstat_domain(struct schedstat_domain *summary_domain, + struct schedstat_domain *dptr, + int cnt, bool is_last) +{ + struct perf_record_schedstat_domain *summary_ds = summary_domain->domain_data, + *temp_ds = dptr->domain_data; + +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) \ + do { \ + summary_ds->_ver._name += temp_ds->_ver._name; \ + if (is_last) \ + summary_ds->_ver._name /= cnt; \ + } while (0) + + if (dptr->domain_data->version == 15) { +#include + } else if (dptr->domain_data->version == 16) { +#include + } else if (dptr->domain_data->version == 17) { +#include + } +#undef DOMAIN_FIELD +} + +/* + * get_all_cpu_stats() appends the summary to the head of the list. + */ +static int get_all_cpu_stats(struct list_head *head) +{ + struct schedstat_cpu *cptr = list_first_entry(head, struct schedstat_cpu, cpu_list); + struct schedstat_cpu *summary_head = NULL; + struct perf_record_schedstat_domain *ds; + struct perf_record_schedstat_cpu *cs; + struct schedstat_domain *dptr, *tdptr; + bool is_last = false; + int cnt = 1; + int ret = 0; + + if (cptr) { + summary_head = zalloc(sizeof(*summary_head)); + if (!summary_head) + return -ENOMEM; + + summary_head->cpu_data = zalloc(sizeof(*cs)); + memcpy(summary_head->cpu_data, cptr->cpu_data, sizeof(*cs)); + + INIT_LIST_HEAD(&summary_head->domain_head); + + list_for_each_entry(dptr, &cptr->domain_head, domain_list) { + tdptr = zalloc(sizeof(*tdptr)); + if (!tdptr) + return -ENOMEM; + + tdptr->domain_data = zalloc(sizeof(*ds)); + if (!tdptr->domain_data) + return -ENOMEM; + + memcpy(tdptr->domain_data, dptr->domain_data, sizeof(*ds)); + list_add_tail(&tdptr->domain_list, &summary_head->domain_head); + } + } + + list_for_each_entry(cptr, head, cpu_list) { + if (list_is_first(&cptr->cpu_list, head)) + continue; + + if (list_is_last(&cptr->cpu_list, head)) + is_last = true; + + cnt++; + summarize_schedstat_cpu(summary_head, cptr, cnt, is_last); + tdptr = list_first_entry(&summary_head->domain_head, struct schedstat_domain, + domain_list); + + list_for_each_entry(dptr, &cptr->domain_head, domain_list) { + summarize_schedstat_domain(tdptr, dptr, cnt, is_last); + tdptr = list_next_entry(tdptr, domain_list); + } + } + + list_add(&summary_head->cpu_list, head); + return ret; +} + +static int show_schedstat_data(struct list_head *head1, struct cpu_domain_map **cd_map1, + struct list_head *head2, struct cpu_domain_map **cd_map2, + bool summary_only) +{ + struct schedstat_cpu *cptr1 = list_first_entry(head1, struct schedstat_cpu, cpu_list); + struct perf_record_schedstat_domain *ds1 = NULL, *ds2 = NULL; + struct perf_record_schedstat_cpu *cs1 = NULL, *cs2 = NULL; + struct schedstat_domain *dptr1 = NULL, *dptr2 = NULL; + struct schedstat_cpu *cptr2 = NULL; + __u64 jiffies1 = 0, jiffies2 = 0; + bool is_summary = true; + int ret = 0; + + printf("Description\n"); + print_separator2(SEP_LEN, "", 0); + printf("%-30s-> %s\n", "DESC", "Description of the field"); + printf("%-30s-> %s\n", "COUNT", "Value of the field"); + printf("%-30s-> %s\n", "PCT_CHANGE", "Percent change with corresponding base value"); + printf("%-30s-> %s\n", "AVG_JIFFIES", + "Avg time in jiffies between two consecutive occurrence of event"); + + print_separator2(SEP_LEN, "", 0); + printf("\n"); + + printf("%-65s: ", "Time elapsed (in jiffies)"); + jiffies1 = cptr1->cpu_data->timestamp; + printf("%11llu", jiffies1); + if (head2) { + cptr2 = list_first_entry(head2, struct schedstat_cpu, cpu_list); + jiffies2 = cptr2->cpu_data->timestamp; + printf(",%11llu", jiffies2); + } + printf("\n"); + + ret = get_all_cpu_stats(head1); + if (cptr2) { + ret = get_all_cpu_stats(head2); + cptr2 = list_first_entry(head2, struct schedstat_cpu, cpu_list); + } + + list_for_each_entry(cptr1, head1, cpu_list) { + struct cpu_domain_map *cd_info1 = NULL, *cd_info2 = NULL; + + cs1 = cptr1->cpu_data; + cd_info1 = cd_map1[cs1->cpu]; + if (cptr2) { + cs2 = cptr2->cpu_data; + cd_info2 = cd_map2[cs2->cpu]; + dptr2 = list_first_entry(&cptr2->domain_head, struct schedstat_domain, + domain_list); + } + + if (cs2 && cs1->cpu != cs2->cpu) { + pr_err("Failed because matching cpus not found for diff\n"); + return -1; + } + + if (cd_info2 && cd_info1->nr_domains != cd_info2->nr_domains) { + pr_err("Failed because nr_domains is not same for cpus\n"); + return -1; + } + + print_separator2(SEP_LEN, "", 0); + + if (is_summary) + printf("CPU: \n"); + else + printf("CPU: %d\n", cs1->cpu); + + print_separator2(SEP_LEN, "", 0); + print_cpu_stats(cs1, cs2); + print_separator2(SEP_LEN, "", 0); + + list_for_each_entry(dptr1, &cptr1->domain_head, domain_list) { + struct domain_info *dinfo1 = NULL, *dinfo2 = NULL; + + ds1 = dptr1->domain_data; + dinfo1 = cd_info1->domains[ds1->domain]; + if (dptr2) { + ds2 = dptr2->domain_data; + dinfo2 = cd_info2->domains[ds2->domain]; + } + + if (dinfo2 && dinfo1->domain != dinfo2->domain) { + pr_err("Failed because matching domain not found for diff\n"); + return -1; + } + + if (is_summary) { + if (dinfo1->dname) + printf("CPU: | DOMAIN: %s\n", + dinfo1->dname); + else + printf("CPU: | DOMAIN: %d\n", + dinfo1->domain); + } else { + if (dinfo1->dname) + printf("CPU: %d | DOMAIN: %s | DOMAIN_CPUS: ", + cs1->cpu, dinfo1->dname); + else + printf("CPU: %d | DOMAIN: %d | DOMAIN_CPUS: ", + cs1->cpu, dinfo1->domain); + + printf("%s\n", dinfo1->cpulist); + } + print_separator2(SEP_LEN, "", 0); + print_domain_stats(ds1, ds2, jiffies1, jiffies2); + print_separator2(SEP_LEN, "", 0); + + if (dptr2) + dptr2 = list_next_entry(dptr2, domain_list); + } + if (summary_only) + break; + + if (cptr2) + cptr2 = list_next_entry(cptr2, cpu_list); + + is_summary = false; + } + return ret; +} + +/* + * Creates a linked list of cpu_data and domain_data. Below represents the structure of the linked + * list where CPU0,CPU1,CPU2, ..., CPU(N-1) stores the cpu_data. Here N is the total number of cpus. + * Each of the CPU points to the list of domain_data. Here DOMAIN0, DOMAIN1, DOMAIN2, ... represents + * the domain_data. Here D0, D1, D2, ..., Dm are the number of domains in the respective cpus. + * + * +----------+ + * | CPU_HEAD | + * +----------+ + * | + * v + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | CPU0 | -> | DOMAIN0 | -> | DOMAIN1 | -> | DOMAIN2 | -> ... -> | DOMAIN(D0-1) | + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | + * v + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | CPU1 | -> | DOMAIN0 | -> | DOMAIN1 | -> | DOMAIN2 | -> ... -> | DOMAIN(D1-1) | + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | + * v + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | CPU2 | -> | DOMAIN0 | -> | DOMAIN1 | -> | DOMAIN2 | -> ... -> | DOMAIN(D2-1) | + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | + * v + * ... + * | + * v + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * | CPU(N-1) | -> | DOMAIN0 | -> | DOMAIN1 | -> | DOMAIN2 | -> ... -> | DOMAIN(Dm-1) | + * +----------+ +---------+ +---------+ +---------+ +--------------+ + * + * Each cpu as well as domain has 2 enties in the event list one before the workload starts and + * other after completion of the workload. The above linked list stores the diff of the cpu and + * domain statistics. + */ +static int perf_sched__process_schedstat(const struct perf_tool *tool __maybe_unused, + struct perf_session *session __maybe_unused, + union perf_event *event) +{ + struct perf_cpu this_cpu; + static __u32 initial_cpu; + + switch (event->header.type) { + case PERF_RECORD_SCHEDSTAT_CPU: + this_cpu.cpu = event->schedstat_cpu.cpu; + break; + case PERF_RECORD_SCHEDSTAT_DOMAIN: + this_cpu.cpu = event->schedstat_domain.cpu; + break; + default: + return 0; + } + + if (user_requested_cpus && !perf_cpu_map__has(user_requested_cpus, this_cpu)) + return 0; + + if (event->header.type == PERF_RECORD_SCHEDSTAT_CPU) { + struct schedstat_cpu *temp = zalloc(sizeof(*temp)); + + if (!temp) + return -ENOMEM; + + temp->cpu_data = zalloc(sizeof(*temp->cpu_data)); + if (!temp->cpu_data) + return -ENOMEM; + + memcpy(temp->cpu_data, &event->schedstat_cpu, sizeof(*temp->cpu_data)); + + if (!list_empty(&cpu_head) && temp->cpu_data->cpu == initial_cpu) + after_workload_flag = true; + + if (!after_workload_flag) { + if (list_empty(&cpu_head)) + initial_cpu = temp->cpu_data->cpu; + + list_add_tail(&temp->cpu_list, &cpu_head); + INIT_LIST_HEAD(&temp->domain_head); + } else { + if (temp->cpu_data->cpu == initial_cpu) { + cpu_second_pass = list_first_entry(&cpu_head, struct schedstat_cpu, + cpu_list); + cpu_second_pass->cpu_data->timestamp = + temp->cpu_data->timestamp - cpu_second_pass->cpu_data->timestamp; + } else { + cpu_second_pass = list_next_entry(cpu_second_pass, cpu_list); + } + domain_second_pass = list_first_entry(&cpu_second_pass->domain_head, + struct schedstat_domain, domain_list); + store_schedstat_cpu_diff(temp); + } + } else if (event->header.type == PERF_RECORD_SCHEDSTAT_DOMAIN) { + struct schedstat_cpu *cpu_tail; + struct schedstat_domain *temp = zalloc(sizeof(*temp)); + + if (!temp) + return -ENOMEM; + + temp->domain_data = zalloc(sizeof(*temp->domain_data)); + if (!temp->domain_data) + return -ENOMEM; + + memcpy(temp->domain_data, &event->schedstat_domain, sizeof(*temp->domain_data)); + + if (!after_workload_flag) { + cpu_tail = list_last_entry(&cpu_head, struct schedstat_cpu, cpu_list); + list_add_tail(&temp->domain_list, &cpu_tail->domain_head); + } else { + store_schedstat_domain_diff(temp); + domain_second_pass = list_next_entry(domain_second_pass, domain_list); + } + } + + return 0; +} + +static void free_schedstat(struct list_head *head) +{ + struct schedstat_domain *dptr, *n1; + struct schedstat_cpu *cptr, *n2; + + list_for_each_entry_safe(cptr, n2, head, cpu_list) { + list_for_each_entry_safe(dptr, n1, &cptr->domain_head, domain_list) { + list_del_init(&dptr->domain_list); + free(dptr); + } + list_del_init(&cptr->cpu_list); + free(cptr); + } +} + +static int perf_sched__schedstat_report(struct perf_sched *sched) +{ + struct cpu_domain_map **cd_map; + struct perf_session *session; + struct target target = {}; + struct perf_data data = { + .path = input_name, + .mode = PERF_DATA_MODE_READ, + }; + int err = 0; + + sched->tool.schedstat_cpu = perf_sched__process_schedstat; + sched->tool.schedstat_domain = perf_sched__process_schedstat; + + session = perf_session__new(&data, &sched->tool); + if (IS_ERR(session)) { + pr_err("Perf session creation failed.\n"); + return PTR_ERR(session); + } + + if (cpu_list) + target.cpu_list = cpu_list; + else + target.system_wide = true; + + err = evlist__create_maps(session->evlist, &target); + if (err < 0) + goto out; + + user_requested_cpus = session->evlist->core.user_requested_cpus; + + err = perf_session__process_events(session); + + if (!err) { + setup_pager(); + + if (list_empty(&cpu_head)) { + pr_err("Data is not available\n"); + err = -1; + goto out; + } + + cd_map = session->header.env.cpu_domain; + err = show_schedstat_data(&cpu_head, cd_map, NULL, NULL, false); + } + +out: + free_schedstat(&cpu_head); + perf_session__delete(session); + return err; +} + +static int perf_sched__schedstat_diff(struct perf_sched *sched, + int argc, const char **argv) +{ + struct cpu_domain_map **cd_map0 = NULL, **cd_map1 = NULL; + struct list_head cpu_head_ses0, cpu_head_ses1; + struct perf_session *session[2]; + struct perf_data data[2]; + int ret = 0, err = 0; + static const char *defaults[] = { + "perf.data.old", + "perf.data", + }; + + if (argc) { + if (argc == 1) + defaults[1] = argv[0]; + else if (argc == 2) { + defaults[0] = argv[0]; + defaults[1] = argv[1]; + } else { + pr_err("perf sched stats diff is not supported with more than 2 files.\n"); + goto out_ret; + } + } + + INIT_LIST_HEAD(&cpu_head_ses0); + INIT_LIST_HEAD(&cpu_head_ses1); + + sched->tool.schedstat_cpu = perf_sched__process_schedstat; + sched->tool.schedstat_domain = perf_sched__process_schedstat; + + data[0].path = defaults[0]; + data[0].mode = PERF_DATA_MODE_READ; + session[0] = perf_session__new(&data[0], &sched->tool); + if (IS_ERR(session[0])) { + ret = PTR_ERR(session[0]); + pr_err("Failed to open %s\n", data[0].path); + goto out_delete_ses0; + } + + err = perf_session__process_events(session[0]); + if (err) + goto out_delete_ses0; + + cd_map0 = session[0]->header.env.cpu_domain; + list_replace_init(&cpu_head, &cpu_head_ses0); + after_workload_flag = false; + + data[1].path = defaults[1]; + data[1].mode = PERF_DATA_MODE_READ; + session[1] = perf_session__new(&data[1], &sched->tool); + if (IS_ERR(session[1])) { + ret = PTR_ERR(session[1]); + pr_err("Failed to open %s\n", data[1].path); + goto out_delete_ses1; + } + + err = perf_session__process_events(session[1]); + if (err) + goto out_delete_ses1; + + cd_map1 = session[1]->header.env.cpu_domain; + list_replace_init(&cpu_head, &cpu_head_ses1); + after_workload_flag = false; + setup_pager(); + + if (list_empty(&cpu_head_ses1)) { + pr_err("Data is not available\n"); + ret = -1; + goto out_delete_ses1; + } + + if (list_empty(&cpu_head_ses0)) { + pr_err("Data is not available\n"); + ret = -1; + goto out_delete_ses0; + } + + show_schedstat_data(&cpu_head_ses0, cd_map0, &cpu_head_ses1, cd_map1, true); + +out_delete_ses1: + free_schedstat(&cpu_head_ses1); + if (!IS_ERR(session[1])) + perf_session__delete(session[1]); + +out_delete_ses0: + free_schedstat(&cpu_head_ses0); + if (!IS_ERR(session[0])) + perf_session__delete(session[0]); + +out_ret: + return ret; +} + +static int process_synthesized_event_live(const struct perf_tool *tool __maybe_unused, + union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + return perf_sched__process_schedstat(tool, NULL, event); +} + +static int perf_sched__schedstat_live(struct perf_sched *sched, + int argc, const char **argv) +{ + struct cpu_domain_map **cd_map = NULL; + struct target target = {}; + u32 __maybe_unused md; + struct evlist *evlist; + u32 nr = 0, sv; + int reset = 0; + int err = 0; + + signal(SIGINT, sighandler); + signal(SIGCHLD, sighandler); + signal(SIGTERM, sighandler); + + evlist = evlist__new(); + if (!evlist) + return -ENOMEM; + + /* + * `perf sched schedstat` does not support workload profiling (-p pid) + * since /proc/schedstat file contains cpu specific data only. Hence, a + * profile target is either set of cpus or systemwide, never a process. + * Note that, although `-- ` is supported, profile data are + * still cpu/systemwide. + */ + if (cpu_list) + target.cpu_list = cpu_list; + else + target.system_wide = true; + + if (argc) { + err = evlist__prepare_workload(evlist, &target, argv, false, NULL); + if (err) + goto out; + } + + err = evlist__create_maps(evlist, &target); + if (err < 0) + goto out; + + user_requested_cpus = evlist->core.user_requested_cpus; + + err = perf_event__synthesize_schedstat(&(sched->tool), + process_synthesized_event_live, + user_requested_cpus); + if (err < 0) + goto out; + + err = enable_sched_schedstats(&reset); + if (err < 0) + goto out; + + if (argc) + evlist__start_workload(evlist); + + /* wait for signal */ + pause(); + + if (reset) { + err = disable_sched_schedstat(); + if (err < 0) + goto out; + } + + err = perf_event__synthesize_schedstat(&(sched->tool), + process_synthesized_event_live, + user_requested_cpus); + if (err) + goto out; + + setup_pager(); + + if (list_empty(&cpu_head)) { + pr_err("Data is not available\n"); + err = -1; + goto out; + } + + nr = cpu__max_present_cpu().cpu; + cd_map = build_cpu_domain_map(&sv, &md, nr); + if (!cd_map) { + pr_err("Unable to generate cpu-domain relation info"); + goto out; + } + + show_schedstat_data(&cpu_head, cd_map, NULL, NULL, false); + free_cpu_domain_info(cd_map, sv, nr); +out: + free_schedstat(&cpu_head); + evlist__delete(evlist); + return err; +} + static bool schedstat_events_exposed(void) { /* @@ -3910,6 +4904,15 @@ int cmd_sched(int argc, const char **argv) OPT_BOOLEAN('P', "pre-migrations", &sched.pre_migrations, "Show pre-migration wait time"), OPT_PARENT(sched_options) }; + const struct option stats_options[] = { + OPT_STRING('i', "input", &input_name, "file", + "`stats report` with input filename"), + OPT_STRING('o', "output", &output_name, "file", + "`stats record` with output filename"), + OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), + OPT_BOOLEAN('v', "verbose", &verbose_field, "Show explanation for fields in the report"), + OPT_END() + }; const char * const latency_usage[] = { "perf sched latency []", @@ -3927,9 +4930,13 @@ int cmd_sched(int argc, const char **argv) "perf sched timehist []", NULL }; + const char *stats_usage[] = { + "perf sched stats {record|report} []", + NULL + }; const char *const sched_subcommands[] = { "record", "latency", "map", "replay", "script", - "timehist", NULL }; + "timehist", "stats", NULL }; const char *sched_usage[] = { NULL, NULL @@ -4027,6 +5034,31 @@ int cmd_sched(int argc, const char **argv) ret = symbol__validate_sym_arguments(); if (!ret) ret = perf_sched__timehist(&sched); + } else if (!strcmp(argv[0], "stats")) { + const char *const stats_subcommands[] = {"record", "report", NULL}; + + argc = parse_options_subcommand(argc, argv, stats_options, + stats_subcommands, + stats_usage, + PARSE_OPT_STOP_AT_NON_OPTION); + + if (argv[0] && !strcmp(argv[0], "record")) { + if (argc) + argc = parse_options(argc, argv, stats_options, + stats_usage, 0); + return perf_sched__schedstat_record(&sched, argc, argv); + } else if (argv[0] && !strcmp(argv[0], "report")) { + if (argc) + argc = parse_options(argc, argv, stats_options, + stats_usage, 0); + return perf_sched__schedstat_report(&sched); + } else if (argv[0] && !strcmp(argv[0], "diff")) { + if (argc) + argc = parse_options(argc, argv, stats_options, + stats_usage, 0); + return perf_sched__schedstat_diff(&sched, argc, argv); + } + return perf_sched__schedstat_live(&sched, argc, argv); } else { usage_with_options(sched_usage, sched_options); } diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 62e43d3c5ad7..7c743a303507 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -37,7 +37,6 @@ #include "ui/ui.h" #include "print_binary.h" #include "print_insn.h" -#include "archinsn.h" #include #include #include @@ -90,7 +89,6 @@ static bool print_flags; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); static int max_blocks; -static bool native_arch; static struct dlfilter *dlfilter; static int dlargc; static char **dlargv; @@ -717,7 +715,8 @@ static int perf_session__check_output_opt(struct perf_session *session) return 0; } -static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, const char *arch, +static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, + uint16_t e_machine, uint32_t e_flags, FILE *fp) { unsigned i = 0, r; @@ -730,7 +729,9 @@ static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, cons for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { u64 val = regs->regs[i++]; - printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, arch), val); + printed += fprintf(fp, "%5s:0x%"PRIx64" ", + perf_reg_name(r, e_machine, e_flags), + val); } return printed; @@ -787,23 +788,29 @@ tod_scnprintf(struct perf_script *script, char *buf, int buflen, } static int perf_sample__fprintf_iregs(struct perf_sample *sample, - struct perf_event_attr *attr, const char *arch, FILE *fp) + struct perf_event_attr *attr, + uint16_t e_machine, + uint32_t e_flags, + FILE *fp) { if (!sample->intr_regs) return 0; return perf_sample__fprintf_regs(perf_sample__intr_regs(sample), - attr->sample_regs_intr, arch, fp); + attr->sample_regs_intr, e_machine, e_flags, fp); } static int perf_sample__fprintf_uregs(struct perf_sample *sample, - struct perf_event_attr *attr, const char *arch, FILE *fp) + struct perf_event_attr *attr, + uint16_t e_machine, + uint32_t e_flags, + FILE *fp) { if (!sample->user_regs) return 0; return perf_sample__fprintf_regs(perf_sample__user_regs(sample), - attr->sample_regs_user, arch, fp); + attr->sample_regs_user, e_machine, e_flags, fp); } static int perf_sample__fprintf_start(struct perf_script *script, @@ -1618,7 +1625,7 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample, { int printed = 0; - script_fetch_insn(sample, thread, machine, native_arch); + perf_sample__fetch_insn(sample, thread, machine); if (PRINT_FIELD(INSNLEN)) printed += fprintf(fp, " ilen: %d", sample->insn_len); @@ -2418,7 +2425,7 @@ static void process_event(struct perf_script *script, struct evsel_script *es = evsel->priv; FILE *fp = es->fp; char str[PAGE_SIZE_NAME_LEN]; - const char *arch = perf_env__arch(machine->env); + uint32_t e_flags; if (output[type].fields == 0) return; @@ -2505,11 +2512,19 @@ static void process_event(struct perf_script *script, symbol_conf.bt_stop_list, fp); } - if (PRINT_FIELD(IREGS)) - perf_sample__fprintf_iregs(sample, attr, arch, fp); + if (PRINT_FIELD(IREGS)) { + perf_sample__fprintf_iregs(sample, attr, + thread__e_machine(thread, machine, &e_flags), + e_flags, + fp); + } - if (PRINT_FIELD(UREGS)) - perf_sample__fprintf_uregs(sample, attr, arch, fp); + if (PRINT_FIELD(UREGS)) { + perf_sample__fprintf_uregs(sample, attr, + thread__e_machine(thread, machine, &e_flags), + e_flags, + fp); + } if (PRINT_FIELD(BRSTACK)) perf_sample__fprintf_brstack(sample, thread, evsel, fp); @@ -2803,6 +2818,7 @@ static int process_attr(const struct perf_tool *tool, union perf_event *event, struct perf_script *scr = container_of(tool, struct perf_script, tool); struct evlist *evlist; struct evsel *evsel, *pos; + uint16_t e_machine; u64 sample_type; int err; @@ -2844,7 +2860,8 @@ static int process_attr(const struct perf_tool *tool, union perf_event *event, * on events sample_type. */ sample_type = evlist__combined_sample_type(evlist); - callchain_param_setup(sample_type, perf_env__arch(perf_session__env(scr->session))); + e_machine = perf_session__e_machine(evsel__session(evsel), /*e_flags=*/NULL); + callchain_param_setup(sample_type, e_machine); /* Enable fields for callchain entries */ if (symbol_conf.use_callchain && @@ -3819,7 +3836,7 @@ static void script__setup_sample_type(struct perf_script *script) struct perf_session *session = script->session; u64 sample_type = evlist__combined_sample_type(session->evlist); - callchain_param_setup(sample_type, perf_env__arch(session->machines.host.env)); + callchain_param_setup(sample_type, perf_session__e_machine(session, /*e_flags=*/NULL)); if (script->stitch_lbr && (callchain_param.record_mode != CALLCHAIN_LBR)) { pr_warning("Can't find LBR callchain. Switch off --stitch-lbr.\n" @@ -4017,7 +4034,6 @@ int cmd_script(int argc, const char **argv) .set = false, .default_no_sample = true, }; - struct utsname uts; char *script_path = NULL; const char *dlfilter_file = NULL; const char **__argv; @@ -4439,17 +4455,6 @@ int cmd_script(int argc, const char **argv) if (symbol__init(env) < 0) goto out_delete; - uname(&uts); - if (data.is_pipe) { /* Assume pipe_mode indicates native_arch */ - native_arch = true; - } else if (env->arch) { - if (!strcmp(uts.machine, env->arch)) - native_arch = true; - else if (!strcmp(uts.machine, "x86_64") && - !strcmp(env->arch, "i386")) - native_arch = true; - } - script.session = session; script__setup_sample_type(&script); @@ -4484,6 +4489,7 @@ int cmd_script(int argc, const char **argv) if (generate_script_lang) { struct stat perf_stat; int input; + char *filename = strdup("perf-script"); if (output_set_by_user()) { fprintf(stderr, @@ -4511,17 +4517,32 @@ int cmd_script(int argc, const char **argv) } scripting_ops = script_spec__lookup(generate_script_lang); + if (!scripting_ops && ends_with(generate_script_lang, ".py")) { + scripting_ops = script_spec__lookup("python"); + free(filename); + filename = strdup(generate_script_lang); + filename[strlen(filename) - 3] = '\0'; + } else if (!scripting_ops && ends_with(generate_script_lang, ".pl")) { + scripting_ops = script_spec__lookup("perl"); + free(filename); + filename = strdup(generate_script_lang); + filename[strlen(filename) - 3] = '\0'; + } if (!scripting_ops) { - fprintf(stderr, "invalid language specifier"); + fprintf(stderr, "invalid language specifier '%s'\n", generate_script_lang); err = -ENOENT; goto out_delete; } + if (!filename) { + err = -ENOMEM; + goto out_delete; + } #ifdef HAVE_LIBTRACEEVENT - err = scripting_ops->generate_script(session->tevent.pevent, - "perf-script"); + err = scripting_ops->generate_script(session->tevent.pevent, filename); #else - err = scripting_ops->generate_script(NULL, "perf-script"); + err = scripting_ops->generate_script(NULL, filename); #endif + free(filename); goto out_delete; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index ab40d85fb125..73c2ba7e3076 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -369,19 +369,11 @@ static int read_counter_cpu(struct evsel *counter, int cpu_map_idx) static int read_counters_with_affinity(void) { struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity; if (all_counters_use_bpf) return 0; - if (!target__has_cpu(&target) || target__has_per_thread(&target)) - affinity = NULL; - else if (affinity__setup(&saved_affinity) < 0) - return -1; - else - affinity = &saved_affinity; - - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { struct evsel *counter = evlist_cpu_itr.evsel; if (evsel__is_bpf(counter)) @@ -393,8 +385,6 @@ static int read_counters_with_affinity(void) if (!counter->err) counter->err = read_counter_cpu(counter, evlist_cpu_itr.cpu_map_idx); } - if (affinity) - affinity__cleanup(&saved_affinity); return 0; } @@ -793,7 +783,6 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) const bool forks = (argc > 0); bool is_pipe = STAT_RECORD ? perf_stat.data.is_pipe : false; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity = NULL; int err, open_err = 0; bool second_pass = false, has_supported_counters; @@ -805,14 +794,6 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) child_pid = evsel_list->workload.pid; } - if (!cpu_map__is_dummy(evsel_list->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) { - err = -1; - goto err_out; - } - affinity = &saved_affinity; - } - evlist__for_each_entry(evsel_list, counter) { counter->reset_group = false; if (bpf_counter__load(counter, &target)) { @@ -825,49 +806,48 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) evlist__reset_aggr_stats(evsel_list); - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { - counter = evlist_cpu_itr.evsel; + /* + * bperf calls evsel__open_per_cpu() in bperf__load(), so + * no need to call it again here. + */ + if (!target.use_bpf) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { + counter = evlist_cpu_itr.evsel; - /* - * bperf calls evsel__open_per_cpu() in bperf__load(), so - * no need to call it again here. - */ - if (target.use_bpf) - break; + if (counter->reset_group || !counter->supported) + continue; + if (evsel__is_bperf(counter)) + continue; - if (counter->reset_group || !counter->supported) - continue; - if (evsel__is_bperf(counter)) - continue; + while (true) { + if (create_perf_stat_counter(counter, &stat_config, + evlist_cpu_itr.cpu_map_idx) == 0) + break; - while (true) { - if (create_perf_stat_counter(counter, &stat_config, - evlist_cpu_itr.cpu_map_idx) == 0) - break; + open_err = errno; + /* + * Weak group failed. We cannot just undo this + * here because earlier CPUs might be in group + * mode, and the kernel doesn't support mixing + * group and non group reads. Defer it to later. + * Don't close here because we're in the wrong + * affinity. + */ + if ((open_err == EINVAL || open_err == EBADF) && + evsel__leader(counter) != counter && + counter->weak_group) { + evlist__reset_weak_group(evsel_list, counter, false); + assert(counter->reset_group); + counter->supported = true; + second_pass = true; + break; + } - open_err = errno; - /* - * Weak group failed. We cannot just undo this here - * because earlier CPUs might be in group mode, and the kernel - * doesn't support mixing group and non group reads. Defer - * it to later. - * Don't close here because we're in the wrong affinity. - */ - if ((open_err == EINVAL || open_err == EBADF) && - evsel__leader(counter) != counter && - counter->weak_group) { - evlist__reset_weak_group(evsel_list, counter, false); - assert(counter->reset_group); - counter->supported = true; - second_pass = true; - break; + if (stat_handle_error(counter, open_err) != COUNTER_RETRY) + break; } - - if (stat_handle_error(counter, open_err) != COUNTER_RETRY) - break; } } - if (second_pass) { /* * Now redo all the weak group after closing them, @@ -875,7 +855,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) */ /* First close errored or weak retry */ - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { counter = evlist_cpu_itr.evsel; if (!counter->reset_group && counter->supported) @@ -884,7 +864,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) perf_evsel__close_cpu(&counter->core, evlist_cpu_itr.cpu_map_idx); } /* Now reopen weak */ - evlist__for_each_cpu(evlist_cpu_itr, evsel_list, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evsel_list) { counter = evlist_cpu_itr.evsel; if (!counter->reset_group) @@ -893,17 +873,18 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) while (true) { pr_debug2("reopening weak %s\n", evsel__name(counter)); if (create_perf_stat_counter(counter, &stat_config, - evlist_cpu_itr.cpu_map_idx) == 0) + evlist_cpu_itr.cpu_map_idx) == 0) { + evlist_cpu_iterator__exit(&evlist_cpu_itr); break; - + } open_err = errno; - if (stat_handle_error(counter, open_err) != COUNTER_RETRY) + if (stat_handle_error(counter, open_err) != COUNTER_RETRY) { + evlist_cpu_iterator__exit(&evlist_cpu_itr); break; + } } } } - affinity__cleanup(affinity); - affinity = NULL; has_supported_counters = false; evlist__for_each_entry(evsel_list, counter) { @@ -937,9 +918,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) } if (evlist__apply_filters(evsel_list, &counter, &target)) { - pr_err("failed to set filter \"%s\" on event %s with %d (%s)\n", - counter->filter, evsel__name(counter), errno, - str_error_r(errno, msg, sizeof(msg))); + pr_err("failed to set filter \"%s\" on event %s: %m\n", + counter->filter, evsel__name(counter)); return -1; } @@ -1001,8 +981,8 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) } if (workload_exec_errno) { - const char *emsg = str_error_r(workload_exec_errno, msg, sizeof(msg)); - pr_err("Workload failed: %s\n", emsg); + errno = workload_exec_errno; + pr_err("Workload failed: %m\n"); err = -1; goto err_out; } @@ -1066,7 +1046,6 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) if (forks) evlist__cancel_workload(evsel_list); - affinity__cleanup(affinity); return err; } @@ -2447,6 +2426,7 @@ static int parse_tpebs_mode(const struct option *opt, const char *str, int cmd_stat(int argc, const char **argv) { struct opt_aggr_mode opt_mode = {}; + bool affinity = true, affinity_set = false; struct option stat_options[] = { OPT_BOOLEAN('T', "transaction", &transaction_run, "hardware transaction statistics"), @@ -2575,6 +2555,8 @@ int cmd_stat(int argc, const char **argv) "don't print 'summary' for CSV summary output"), OPT_BOOLEAN(0, "quiet", &quiet, "don't print any output, messages or warnings (useful with record)"), + OPT_BOOLEAN_SET(0, "affinity", &affinity, &affinity_set, + "enable (default) or disable affinity optimizations to reduce IPIs"), OPT_CALLBACK(0, "cputype", &evsel_list, "hybrid cpu type", "Only enable events on applying cpu with this type " "for hybrid platform (e.g. core or atom)", @@ -2632,6 +2614,9 @@ int cmd_stat(int argc, const char **argv) } else stat_config.csv_sep = DEFAULT_SEPARATOR; + if (affinity_set) + evsel_list->no_affinity = !affinity; + if (argc && strlen(argv[0]) > 2 && strstarts("record", argv[0])) { argc = __cmd_record(stat_options, &opt_mode, argc, argv); if (argc < 0) diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index baee1f695600..311d9da9896a 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -2616,12 +2616,10 @@ static struct syscall *trace__syscall_info(struct trace *trace, struct evsel *ev err = syscall__read_info(sc, trace); if (err && verbose > 0) { - char sbuf[STRERR_BUFSIZE]; - - fprintf(trace->output, "Problems reading syscall %d: %d (%s)", id, -err, - str_error_r(-err, sbuf, sizeof(sbuf))); + errno = -err; + fprintf(trace->output, "Problems reading syscall %d: %m", id); if (sc && sc->name) - fprintf(trace->output, "(%s)", sc->name); + fprintf(trace->output, " (%s)", sc->name); fputs(" information\n", trace->output); } return err ? NULL : sc; @@ -2791,7 +2789,7 @@ static int trace__sys_enter(struct trace *trace, struct evsel *evsel, struct thread_trace *ttrace; thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine = thread__e_machine(thread, trace->host); + e_machine = thread__e_machine(thread, trace->host, /*e_flags=*/NULL); sc = trace__syscall_info(trace, evsel, e_machine, id); if (sc == NULL) goto out_put; @@ -2870,7 +2868,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct evsel *evsel, thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine = thread__e_machine(thread, trace->host); + e_machine = thread__e_machine(thread, trace->host, /*e_flags=*/NULL); sc = trace__syscall_info(trace, evsel, e_machine, id); if (sc == NULL) goto out_put; @@ -2936,7 +2934,7 @@ static int trace__sys_exit(struct trace *trace, struct evsel *evsel, struct thread_trace *ttrace; thread = machine__findnew_thread(trace->host, sample->pid, sample->tid); - e_machine = thread__e_machine(thread, trace->host); + e_machine = thread__e_machine(thread, trace->host, /*e_flags=*/NULL); sc = trace__syscall_info(trace, evsel, e_machine, id); if (sc == NULL) goto out_put; @@ -3287,7 +3285,9 @@ static int trace__event_handler(struct trace *trace, struct evsel *evsel, if (evsel == trace->syscalls.events.bpf_output) { int id = perf_evsel__sc_tp_uint(evsel, id, sample); - int e_machine = thread ? thread__e_machine(thread, trace->host) : EM_HOST; + int e_machine = thread + ? thread__e_machine(thread, trace->host, /*e_flags=*/NULL) + : EM_HOST; struct syscall *sc = trace__syscall_info(trace, evsel, e_machine, id); if (sc) { @@ -4673,9 +4673,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv) out_error_apply_filters: fprintf(trace->output, - "Failed to set filter \"%s\" on event %s with %d (%s)\n", - evsel->filter, evsel__name(evsel), errno, - str_error_r(errno, errbuf, sizeof(errbuf))); + "Failed to set filter \"%s\" on event %s: %m\n", + evsel->filter, evsel__name(evsel)); goto out_delete_evlist; } out_error_mem: @@ -4683,7 +4682,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv) goto out_delete_evlist; out_errno: - fprintf(trace->output, "errno=%d,%s\n", errno, strerror(errno)); + fprintf(trace->output, "%m\n"); goto out_delete_evlist; } @@ -4919,7 +4918,7 @@ static size_t trace__fprintf_thread(FILE *fp, struct thread *thread, struct trac { size_t printed = 0; struct thread_trace *ttrace = thread__priv(thread); - int e_machine = thread__e_machine(thread, trace->host); + int e_machine = thread__e_machine(thread, trace->host, /*e_flags=*/NULL); double ratio; if (ttrace == NULL) @@ -5173,8 +5172,8 @@ static int trace__parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused) { struct trace *trace = (struct trace *)opt->value; - const char *s = str; - char *sep = NULL, *lists[2] = { NULL, NULL, }; + const char *s; + char *strd, *sep = NULL, *lists[2] = { NULL, NULL, }; int len = strlen(str) + 1, err = -1, list, idx; char *strace_groups_dir = system_path(STRACE_GROUPS_DIR); char group_name[PATH_MAX]; @@ -5183,13 +5182,17 @@ static int trace__parse_events_option(const struct option *opt, const char *str, if (strace_groups_dir == NULL) return -1; + s = strd = strdup(str); + if (strd == NULL) + return -1; + if (*s == '!') { ++s; trace->not_ev_qualifier = true; } while (1) { - if ((sep = strchr(s, ',')) != NULL) + if ((sep = strchr((char *)s, ',')) != NULL) *sep = '\0'; list = 0; @@ -5257,8 +5260,7 @@ static int trace__parse_events_option(const struct option *opt, const char *str, free(strace_groups_dir); free(lists[0]); free(lists[1]); - if (sep) - *sep = ','; + free(strd); return err; } diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index e0537f275da2..da3aca87457f 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh @@ -54,7 +54,6 @@ declare -a FILES=( "arch/s390/include/uapi/asm/kvm.h" "arch/s390/include/uapi/asm/sie.h" "arch/arm64/include/uapi/asm/kvm.h" - "arch/arm64/include/uapi/asm/unistd.h" "arch/alpha/include/uapi/asm/errno.h" "arch/mips/include/asm/errno.h" "arch/mips/include/uapi/asm/errno.h" diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt deleted file mode 100644 index e8d2762adade..000000000000 --- a/tools/perf/command-list.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -# List of known perf commands. -# command name category [deprecated] [common] -# -perf-annotate mainporcelain common -perf-archive mainporcelain common -perf-bench mainporcelain common -perf-buildid-cache mainporcelain common -perf-buildid-list mainporcelain common -perf-data mainporcelain common -perf-diff mainporcelain common -perf-c2c mainporcelain common -perf-config mainporcelain common -perf-evlist mainporcelain common -perf-ftrace mainporcelain common -perf-inject mainporcelain common -perf-iostat mainporcelain common -perf-kallsyms mainporcelain common -perf-kmem mainporcelain traceevent -perf-kvm mainporcelain common -perf-kwork mainporcelain traceevent -perf-list mainporcelain common -perf-lock mainporcelain traceevent -perf-mem mainporcelain common -perf-probe mainporcelain full -perf-record mainporcelain common -perf-report mainporcelain common -perf-sched mainporcelain traceevent -perf-script mainporcelain common -perf-stat mainporcelain common -perf-test mainporcelain common -perf-timechart mainporcelain traceevent -perf-top mainporcelain common -perf-trace mainporcelain audit -perf-version mainporcelain common -perf-daemon mainporcelain common diff --git a/tools/perf/jvmti/libjvmti.c b/tools/perf/jvmti/libjvmti.c index 82514e6532b8..87bfd4781003 100644 --- a/tools/perf/jvmti/libjvmti.c +++ b/tools/perf/jvmti/libjvmti.c @@ -142,7 +142,7 @@ copy_class_filename(const char * class_sign, const char * file_name, char * resu */ if (*class_sign == 'L') { size_t j, i = 0; - char *p = strrchr(class_sign, '/'); + const char *p = strrchr(class_sign, '/'); if (p) { /* drop the 'L' prefix and copy up to the final '/' */ for (i = 0; i < (size_t)(p - class_sign); i++) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 88c60ecf3395..f475a8664ffc 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -169,8 +169,8 @@ static int set_debug_file(const char *path) { debug_fp = fopen(path, "w"); if (!debug_fp) { - fprintf(stderr, "Open debug file '%s' failed: %s\n", - path, strerror(errno)); + fprintf(stderr, "Open debug file '%s' failed: %m\n", + path); return -1; } @@ -335,7 +335,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) { int status; struct stat st; - char sbuf[STRERR_BUFSIZE]; if (use_browser == -1) use_browser = check_browser_config(p->cmd); @@ -363,17 +362,15 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) status = 1; /* Check for ENOSPC and EIO errors.. */ if (fflush(stdout)) { - fprintf(stderr, "write failure on standard output: %s", - str_error_r(errno, sbuf, sizeof(sbuf))); + fprintf(stderr, "write failure on standard output: %m\n"); goto out; } if (ferror(stdout)) { - fprintf(stderr, "unknown write failure on standard output"); + fprintf(stderr, "unknown write failure on standard output\n"); goto out; } if (fclose(stdout)) { - fprintf(stderr, "close failed on standard output: %s", - str_error_r(errno, sbuf, sizeof(sbuf))); + fprintf(stderr, "close failed on standard output: %m\n"); goto out; } status = 0; @@ -459,7 +456,6 @@ int main(int argc, const char **argv) { int err, done_help = 0; const char *cmd; - char sbuf[STRERR_BUFSIZE]; perf_debug_setup(); @@ -573,8 +569,8 @@ int main(int argc, const char **argv) } if (cmd) { - fprintf(stderr, "Failed to run command '%s': %s\n", - cmd, str_error_r(errno, sbuf, sizeof(sbuf))); + fprintf(stderr, "Failed to run command '%s': %m\n", + cmd); } out: if (debug_fp) diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build index a46ab7b612df..dc5f94862a3b 100644 --- a/tools/perf/pmu-events/Build +++ b/tools/perf/pmu-events/Build @@ -1,52 +1,167 @@ -pmu-events-y += pmu-events.o -JSON = $(shell find pmu-events/arch -name '*.json' -o -name '*.csv') -JDIR_TEST = pmu-events/arch/test -JSON_TEST = $(shell [ -d $(JDIR_TEST) ] && \ - find $(JDIR_TEST) -name '*.json') -JEVENTS_PY = pmu-events/jevents.py -METRIC_PY = pmu-events/metric.py -METRIC_TEST_PY = pmu-events/metric_test.py EMPTY_PMU_EVENTS_C = pmu-events/empty-pmu-events.c +# pmu-events.c will be generated by jevents.py or copied from EMPTY_PMU_EVENTS_C PMU_EVENTS_C = $(OUTPUT)pmu-events/pmu-events.c -METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log -TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c -EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log -LEGACY_CACHE_PY = pmu-events/make_legacy_cache.py -LEGACY_CACHE_JSON = $(OUTPUT)pmu-events/arch/common/common/legacy-cache.json +pmu-events-y += pmu-events.o +# pmu-events.c file is generated in the OUTPUT directory so it needs a +# separate rule to depend on it properly +$(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C) + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c) + +# Message for $(call echo-cmd,cp), possibly remove the src file from +# the destination to save space in the build log. +quiet_cmd_cp = COPY $(patsubst %$<,%,$@) <- $< + +# --- NO_JEVENTS=1 build --- +ifeq ($(NO_JEVENTS),1) +$(PMU_EVENTS_C): $(EMPTY_PMU_EVENTS_C) + $(call rule_mkdir) + $(Q)$(call echo-cmd,cp)cp $< $@ +else +# --- Regular build --- + +# Setup the JEVENTS_ARCH and JEVENTS_MODEL ifeq ($(JEVENTS_ARCH),) JEVENTS_ARCH=$(SRCARCH) endif JEVENTS_MODEL ?= all -# -# Locate/process JSON files in pmu-events/arch/ -# directory and create tables in pmu-events.c. -# - -ifeq ($(NO_JEVENTS),1) -$(PMU_EVENTS_C): $(EMPTY_PMU_EVENTS_C) - $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)cp $< $@ +# The input json/csv files +SRC_DIR := pmu-events/arch +ifeq ($(JEVENTS_ARCH),all) +SRC_JSON := $(shell find $(SRC_DIR) -name '*.json' -o -name '*.csv') else -# Copy checked-in json to OUTPUT for generation if it's an out of source build -ifneq ($(OUTPUT),) -$(OUTPUT)pmu-events/arch/%: pmu-events/arch/% - $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)cp $< $@ +SRC_JSON := $(shell find $(SRC_DIR)/common $(SRC_DIR)/test $(SRC_DIR)/$(JEVENTS_ARCH) -name '*.json' -o -name '*.csv') endif +# Python to build the generic legacy cache events +LEGACY_CACHE_PY = pmu-events/make_legacy_cache.py +LEGACY_CACHE_JSON = $(OUTPUT)pmu-events/arch/common/common/legacy-cache.json +GEN_JSON = $(LEGACY_CACHE_JSON) + $(LEGACY_CACHE_JSON): $(LEGACY_CACHE_PY) $(call rule_mkdir) $(Q)$(call echo-cmd,gen)$(PYTHON) $(LEGACY_CACHE_PY) > $@ -GEN_JSON = $(patsubst %,$(OUTPUT)%,$(JSON)) $(LEGACY_CACHE_JSON) +# Python to generate architectural metrics +GEN_METRIC_DEPS := pmu-events/metric.py pmu-events/common_metrics.py +# Functions to extract the model from an extra-metrics.json or extra-metricgroups.json path. +model_name = $(shell echo $(1)|sed -e 's@.\+/\(.*\)/extra-metric.*\.json@\1@') +vendor_name = $(shell echo $(1)|sed -e 's@.\+/\(.*\)/[^/]*/extra-metric.*\.json@\1@') + +ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all)) +# Generate AMD Json +ZENS = $(shell ls -d pmu-events/arch/x86/amdzen*) +ZEN_METRICS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metrics.json) +ZEN_METRICGROUPS = $(foreach x,$(ZENS),$(OUTPUT)$(x)/extra-metricgroups.json) +GEN_JSON += $(ZEN_METRICS) $(ZEN_METRICGROUPS) + +$(ZEN_METRICS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ + +$(ZEN_METRICGROUPS): pmu-events/amd_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ + +endif + +ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),arm64 all)) +# Generate ARM Json +ARMS = $(shell ls -d pmu-events/arch/arm64/arm/*|grep -v cmn) +ARM_METRICS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metrics.json) +ARM_METRICGROUPS = $(foreach x,$(ARMS),$(OUTPUT)$(x)/extra-metricgroups.json) +GEN_JSON += $(ARM_METRICS) $(ARM_METRICGROUPS) + +$(ARM_METRICS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ + +$(ARM_METRICGROUPS): pmu-events/arm64_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call vendor_name,$@) $(call model_name,$@) pmu-events/arch > $@ + +endif + +ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all)) +# Generate Intel Json +INTELS = $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv) +INTEL_METRICS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metrics.json) +INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json) +GEN_JSON += $(INTEL_METRICS) $(INTEL_METRICGROUPS) + +$(INTEL_METRICS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< $(call model_name,$@) pmu-events/arch > $@ + +$(INTEL_METRICGROUPS): pmu-events/intel_metrics.py $(GEN_METRIC_DEPS) + $(call rule_mkdir) + $(Q)$(call echo-cmd,gen)$(PYTHON) $< -metricgroups $(call model_name,$@) pmu-events/arch > $@ + +endif + +OUT_DIR := $(OUTPUT)pmu-events/arch + +ifeq ($(OUTPUT),) +OUT_JSON := $(SRC_JSON) +ORPHAN_FILES := +else +# Things that need to be built in the OUTPUT directory. Note, ensure +# there is a slash after the directory name so that it matches what +# $(dir) gives in COPY_RULE. +OUT_JSON := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(SRC_JSON)) +OUT_DIRS := $(sort $(patsubst %/,%,$(dir $(OUT_JSON)))) + +# Things already in the OUTPUT directory +CUR_OUT_JSON := $(shell [ -d $(OUT_DIR) ] && find $(OUT_DIR) -type f) + +# Things in the OUTPUT directory but shouldn't be there as computed by +# OUT_JSON and GEN_JSON. +ORPHAN_FILES := $(filter-out $(OUT_JSON) $(GEN_JSON),$(CUR_OUT_JSON)) + +# Message for $(call echo-cmd,mkd). There is already a mkdir message +# but it assumes $@ is a file to mkdir the directory for. +quiet_cmd_mkd = MKDIR $@ + +$(OUT_DIRS): + $(Q)$(call echo-cmd,mkd)mkdir -p $@ + +# Explicitly generate rules to copy SRC_JSON files as $(dir) cannot +# apply to $@ in a dependency. Exclude from the copy rules any that +# look like they are copying generated json. This happens as a perf +# build within the tools/perf directory will leave generated json +# files within the tree, these then get picked up by SRC_JSON find. +define COPY_RULE +$(2): $(1) | $(3) + $$(Q)$$(call echo-cmd,cp)cp $(1) $(2) +endef +$(foreach src,$(SRC_JSON), \ + $(eval dest := $(patsubst $(SRC_DIR)/%,$(OUT_DIR)/%,$(src))) \ + $(eval ddir := $(patsubst %/,%,$(dir $(dest)))) \ + $(if $(filter $(dest),$(GEN_JSON)),, \ + $(eval $(call COPY_RULE,$(src),$(dest),$(ddir))) \ + ) \ +) + +endif # ifneq ($(OUTPUT),) + +JEVENTS_PY = pmu-events/jevents.py +METRIC_PY = pmu-events/metric.py + +# Rule to run the metric test. +METRIC_TEST_PY = pmu-events/metric_test.py +METRIC_TEST_LOG = $(OUTPUT)pmu-events/metric_test.log $(METRIC_TEST_LOG): $(METRIC_TEST_PY) $(METRIC_PY) $(call rule_mkdir) $(Q)$(call echo-cmd,test)$(PYTHON) $< 2> $@ || (cat $@ && false) -$(TEST_EMPTY_PMU_EVENTS_C): $(GEN_JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) +# Rule to create then ensure the empty-pmu-events.c is in sync. +TEST_EMPTY_PMU_EVENTS_C = $(OUTPUT)pmu-events/test-empty-pmu-events.c +EMPTY_PMU_EVENTS_TEST_LOG = $(OUTPUT)pmu-events/empty-pmu-events.log + +$(TEST_EMPTY_PMU_EVENTS_C): $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) $(call rule_mkdir) $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) none none $(OUTPUT)pmu-events/arch $@ @@ -54,36 +169,61 @@ $(EMPTY_PMU_EVENTS_TEST_LOG): $(EMPTY_PMU_EVENTS_C) $(TEST_EMPTY_PMU_EVENTS_C) $(call rule_mkdir) $(Q)$(call echo-cmd,test)diff -u $^ 2> $@ || (cat $@ && false) + +# Dependencies for jevents.py +JEVENTS_DEPS := $(OUT_JSON) $(GEN_JSON) $(JEVENTS_PY) $(METRIC_PY) $(EMPTY_PMU_EVENTS_TEST_LOG) $(METRIC_TEST_LOG) + +# Rules to run mypy if enabled. ifdef MYPY - PMU_EVENTS_PY_TESTS := $(wildcard *.py) - PMU_EVENTS_MYPY_TEST_LOGS := $(JEVENTS_PY_TESTS:%=%.mypy_log) -else - PMU_EVENTS_MYPY_TEST_LOGS := +define MYPY_RULE +$(2): $(1) + $$(Q)$$(call echo-cmd,test)mypy $(1) > $(2) || (cat $(2) && rm $(2) && false) +endef +$(foreach src,$(wildcard pmu-events/*.py), \ + $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(src))) \ + $(eval $(call MYPY_RULE,$(src),$(dest))) \ +) + +MYPY_INPUTS := $(wildcard pmu-events/*.py) +MYPY_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.mypy_log,$(MYPY_INPUTS)) +JEVENTS_DEPS += $(MYPY_OUTPUTS) endif -$(OUTPUT)%.mypy_log: % - $(call rule_mkdir) - $(Q)$(call echo-cmd,test)mypy "$<" > $@ || (cat $@ && rm $@ && false) - +# Rules to run pylint if enabled. ifdef PYLINT - PMU_EVENTS_PY_TESTS := $(wildcard *.py) - PMU_EVENTS_PYLINT_TEST_LOGS := $(JEVENTS_PY_TESTS:%=%.pylint_log) -else - PMU_EVENTS_PYLINT_TEST_LOGS := +define PYLINT_RULE +$(2): $(1) + $$(Q)$$(call echo-cmd,test)pylint $(1) > $(2) || (cat $(2) && rm $(2) && false) +endef +$(foreach src,$(wildcard pmu-events/*.py), \ + $(eval dest := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(src))) \ + $(eval $(call PYLINT_RULE,$(src),$(dest))) \ +) + +PYLINT_INPUTS := $(wildcard pmu-events/*.py) +PYLINT_OUTPUTS := $(patsubst pmu-events/%,$(OUTPUT)pmu-events/%.pylint_log,$(PYLINT_INPUTS)) +JEVENTS_DEPS += $(PYLINT_OUTPUTS) endif -$(OUTPUT)%.pylint_log: % - $(call rule_mkdir) - $(Q)$(call echo-cmd,test)pylint "$<" > $@ || (cat $@ && rm $@ && false) +# If there are orphaned files remove them. +ifneq ($(strip $(ORPHAN_FILES)),) +.PHONY: prune_orphans -$(PMU_EVENTS_C): $(GEN_JSON) $(JSON_TEST) $(JEVENTS_PY) $(METRIC_PY) $(METRIC_TEST_LOG) \ - $(EMPTY_PMU_EVENTS_TEST_LOG) $(PMU_EVENTS_MYPY_TEST_LOGS) $(PMU_EVENTS_PYLINT_TEST_LOGS) - $(call rule_mkdir) - $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) $(OUTPUT)pmu-events/arch $@ +# Message for $(call echo-cmd,rm). Generally cleaning files isn't part +# of a build step. +quiet_cmd_rm = RM $^ + +prune_orphans: $(ORPHAN_FILES) + # The list of files can be long. Use xargs to prevent issues. + $(Q)$(call echo-cmd,rm)echo "$^" | xargs rm -f + +JEVENTS_DEPS += prune_orphans endif -# pmu-events.c file is generated in the OUTPUT directory so it needs a -# separate rule to depend on it properly -$(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C) +# Finally, the rule to build pmu-events.c using jevents.py. All test +# and inputs are dependencies. +$(PMU_EVENTS_C): $(JEVENTS_DEPS) $(call rule_mkdir) - $(call if_changed_dep,cc_o_c) + $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) $(OUT_DIR) $@ + +endif # ifeq ($(NO_JEVENTS),1) diff --git a/tools/perf/pmu-events/amd_metrics.py b/tools/perf/pmu-events/amd_metrics.py new file mode 100755 index 000000000000..e2defaffde3e --- /dev/null +++ b/tools/perf/pmu-events/amd_metrics.py @@ -0,0 +1,492 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +import argparse +import math +import os +from typing import Optional +from common_metrics import Cycles +from metric import (d_ratio, has_event, max, Event, JsonEncodeMetric, + JsonEncodeMetricGroupDescriptions, Literal, LoadEvents, + Metric, MetricGroup, Select) + +# Global command line arguments. +_args = None +_zen_model: int = 1 +interval_sec = Event("duration_time") +ins = Event("instructions") +cycles = Event("cycles") +# Number of CPU cycles scaled for SMT. +smt_cycles = Select(cycles / 2, Literal("#smt_on"), cycles) + + +def AmdBr(): + def Total() -> MetricGroup: + br = Event("ex_ret_brn") + br_m_all = Event("ex_ret_brn_misp") + br_clr = Event("ex_ret_brn_cond_misp", + "ex_ret_msprd_brnch_instr_dir_msmtch", + "ex_ret_brn_resync") + + br_r = d_ratio(br, interval_sec) + ins_r = d_ratio(ins, br) + misp_r = d_ratio(br_m_all, br) + clr_r = d_ratio(br_clr, interval_sec) + + return MetricGroup("lpm_br_total", [ + Metric("lpm_br_total_retired", + "The number of branch instructions retired per second.", br_r, + "insn/s"), + Metric( + "lpm_br_total_mispred", + "The number of branch instructions retired, of any type, that were " + "not correctly predicted as a percentage of all branch instrucions.", + misp_r, "100%"), + Metric("lpm_br_total_insn_between_branches", + "The number of instructions divided by the number of branches.", + ins_r, "insn"), + Metric("lpm_br_total_insn_fe_resteers", + "The number of resync branches per second.", clr_r, "req/s") + ]) + + def Taken() -> MetricGroup: + br = Event("ex_ret_brn_tkn") + br_m_tk = Event("ex_ret_brn_tkn_misp") + br_r = d_ratio(br, interval_sec) + ins_r = d_ratio(ins, br) + misp_r = d_ratio(br_m_tk, br) + return MetricGroup("lpm_br_taken", [ + Metric("lpm_br_taken_retired", + "The number of taken branches that were retired per second.", + br_r, "insn/s"), + Metric( + "lpm_br_taken_mispred", + "The number of retired taken branch instructions that were " + "mispredicted as a percentage of all taken branches.", misp_r, + "100%"), + Metric( + "lpm_br_taken_insn_between_branches", + "The number of instructions divided by the number of taken branches.", + ins_r, "insn"), + ]) + + def Conditional() -> Optional[MetricGroup]: + global _zen_model + br = Event("ex_ret_brn_cond", "ex_ret_cond") + br_r = d_ratio(br, interval_sec) + ins_r = d_ratio(ins, br) + + metrics = [ + Metric("lpm_br_cond_retired", "Retired conditional branch instructions.", + br_r, "insn/s"), + Metric("lpm_br_cond_insn_between_branches", + "The number of instructions divided by the number of conditional " + "branches.", ins_r, "insn"), + ] + if _zen_model == 2: + br_m_cond = Event("ex_ret_cond_misp") + misp_r = d_ratio(br_m_cond, br) + metrics += [ + Metric("lpm_br_cond_mispred", + "Retired conditional branch instructions mispredicted as a " + "percentage of all conditional branches.", misp_r, "100%"), + ] + + return MetricGroup("lpm_br_cond", metrics) + + def Fused() -> MetricGroup: + br = Event("ex_ret_fused_instr", "ex_ret_fus_brnch_inst") + br_r = d_ratio(br, interval_sec) + ins_r = d_ratio(ins, br) + return MetricGroup("lpm_br_cond", [ + Metric("lpm_br_fused_retired", + "Retired fused branch instructions per second.", br_r, "insn/s"), + Metric( + "lpm_br_fused_insn_between_branches", + "The number of instructions divided by the number of fused " + "branches.", ins_r, "insn"), + ]) + + def Far() -> MetricGroup: + br = Event("ex_ret_brn_far") + br_r = d_ratio(br, interval_sec) + ins_r = d_ratio(ins, br) + return MetricGroup("lpm_br_far", [ + Metric("lpm_br_far_retired", "Retired far control transfers per second.", + br_r, "insn/s"), + Metric( + "lpm_br_far_insn_between_branches", + "The number of instructions divided by the number of far branches.", + ins_r, "insn"), + ]) + + return MetricGroup("lpm_br", [Total(), Taken(), Conditional(), Fused(), Far()], + description="breakdown of retired branch instructions") + + +def AmdCtxSw() -> MetricGroup: + cs = Event("context\\-switches") + metrics = [ + Metric("lpm_cs_rate", "Context switches per second", + d_ratio(cs, interval_sec), "ctxsw/s") + ] + + ev = Event("instructions") + metrics.append(Metric("lpm_cs_instr", "Instructions per context switch", + d_ratio(ev, cs), "instr/cs")) + + ev = Event("cycles") + metrics.append(Metric("lpm_cs_cycles", "Cycles per context switch", + d_ratio(ev, cs), "cycles/cs")) + + ev = Event("ls_dispatch.pure_ld", "ls_dispatch.ld_dispatch") + metrics.append(Metric("lpm_cs_loads", "Loads per context switch", + d_ratio(ev, cs), "loads/cs")) + + ev = Event("ls_dispatch.pure_st", "ls_dispatch.store_dispatch") + metrics.append(Metric("lpm_cs_stores", "Stores per context switch", + d_ratio(ev, cs), "stores/cs")) + + ev = Event("ex_ret_brn_tkn") + metrics.append(Metric("lpm_cs_br_taken", "Branches taken per context switch", + d_ratio(ev, cs), "br_taken/cs")) + + return MetricGroup("lpm_cs", metrics, + description=("Number of context switches per second, instructions " + "retired & core cycles between context switches")) + + +def AmdDtlb() -> Optional[MetricGroup]: + global _zen_model + if _zen_model >= 4: + return None + + d_dat = Event("ls_dc_accesses") if _zen_model <= 3 else None + d_h4k = Event("ls_l1_d_tlb_miss.tlb_reload_4k_l2_hit") + d_hcoal = Event( + "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_hit") if _zen_model >= 2 else 0 + d_h2m = Event("ls_l1_d_tlb_miss.tlb_reload_2m_l2_hit") + d_h1g = Event("ls_l1_d_tlb_miss.tlb_reload_1g_l2_hit") + + d_m4k = Event("ls_l1_d_tlb_miss.tlb_reload_4k_l2_miss") + d_mcoal = Event( + "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_miss") if _zen_model >= 2 else 0 + d_m2m = Event("ls_l1_d_tlb_miss.tlb_reload_2m_l2_miss") + d_m1g = Event("ls_l1_d_tlb_miss.tlb_reload_1g_l2_miss") + + d_w0 = Event("ls_tablewalker.dc_type0") if _zen_model <= 3 else None + d_w1 = Event("ls_tablewalker.dc_type1") if _zen_model <= 3 else None + walks = d_w0 + d_w1 + walks_r = d_ratio(walks, interval_sec) + ins_w = d_ratio(ins, walks) + l1 = d_dat + l1_r = d_ratio(l1, interval_sec) + l2_hits = d_h4k + d_hcoal + d_h2m + d_h1g + l2_miss = d_m4k + d_mcoal + d_m2m + d_m1g + l2_r = d_ratio(l2_hits + l2_miss, interval_sec) + l1_miss = l2_hits + l2_miss + walks + l1_hits = max(l1 - l1_miss, 0) + ins_l = d_ratio(ins, l1_miss) + + return MetricGroup("lpm_dtlb", [ + MetricGroup("lpm_dtlb_ov", [ + Metric("lpm_dtlb_ov_insn_bt_l1_miss", + "DTLB overview: instructions between l1 misses.", ins_l, + "insns"), + Metric("lpm_dtlb_ov_insn_bt_walks", + "DTLB overview: instructions between dtlb page table walks.", + ins_w, "insns"), + ]), + MetricGroup("lpm_dtlb_l1", [ + Metric("lpm_dtlb_l1_hits", + "DTLB L1 hits as percentage of all DTLB L1 accesses.", + d_ratio(l1_hits, l1), "100%"), + Metric("lpm_dtlb_l1_miss", + "DTLB L1 misses as percentage of all DTLB L1 accesses.", + d_ratio(l1_miss, l1), "100%"), + Metric("lpm_dtlb_l1_reqs", "DTLB L1 accesses per second.", l1_r, + "insns/s"), + ]), + MetricGroup("lpm_dtlb_l2", [ + Metric("lpm_dtlb_l2_hits", + "DTLB L2 hits as percentage of all DTLB L2 accesses.", + d_ratio(l2_hits, l2_hits + l2_miss), "100%"), + Metric("lpm_dtlb_l2_miss", + "DTLB L2 misses as percentage of all DTLB L2 accesses.", + d_ratio(l2_miss, l2_hits + l2_miss), "100%"), + Metric("lpm_dtlb_l2_reqs", "DTLB L2 accesses per second.", l2_r, + "insns/s"), + MetricGroup("lpm_dtlb_l2_4kb", [ + Metric( + "lpm_dtlb_l2_4kb_hits", + "DTLB L2 4kb page size hits as percentage of all DTLB L2 4kb " + "accesses.", d_ratio(d_h4k, d_h4k + d_m4k), "100%"), + Metric( + "lpm_dtlb_l2_4kb_miss", + "DTLB L2 4kb page size misses as percentage of all DTLB L2 4kb" + "accesses.", d_ratio(d_m4k, d_h4k + d_m4k), "100%") + ]), + MetricGroup("lpm_dtlb_l2_coalesced", [ + Metric( + "lpm_dtlb_l2_coal_hits", + "DTLB L2 coalesced page (16kb) hits as percentage of all DTLB " + "L2 coalesced accesses.", d_ratio(d_hcoal, + d_hcoal + d_mcoal), "100%"), + Metric( + "lpm_dtlb_l2_coal_miss", + "DTLB L2 coalesced page (16kb) misses as percentage of all " + "DTLB L2 coalesced accesses.", + d_ratio(d_mcoal, d_hcoal + d_mcoal), "100%") + ]), + MetricGroup("lpm_dtlb_l2_2mb", [ + Metric( + "lpm_dtlb_l2_2mb_hits", + "DTLB L2 2mb page size hits as percentage of all DTLB L2 2mb " + "accesses.", d_ratio(d_h2m, d_h2m + d_m2m), "100%"), + Metric( + "lpm_dtlb_l2_2mb_miss", + "DTLB L2 2mb page size misses as percentage of all DTLB L2 " + "accesses.", d_ratio(d_m2m, d_h2m + d_m2m), "100%") + ]), + MetricGroup("lpm_dtlb_l2_1g", [ + Metric( + "lpm_dtlb_l2_1g_hits", + "DTLB L2 1gb page size hits as percentage of all DTLB L2 1gb " + "accesses.", d_ratio(d_h1g, d_h1g + d_m1g), "100%"), + Metric( + "lpm_dtlb_l2_1g_miss", + "DTLB L2 1gb page size misses as percentage of all DTLB L2 " + "1gb accesses.", d_ratio(d_m1g, d_h1g + d_m1g), "100%") + ]), + ]), + MetricGroup("lpm_dtlb_walks", [ + Metric("lpm_dtlb_walks_reqs", "DTLB page table walks per second.", + walks_r, "walks/s"), + ]), + ], description="Data TLB metrics") + + +def AmdItlb(): + global _zen_model + l2h = Event("bp_l1_tlb_miss_l2_tlb_hit", "bp_l1_tlb_miss_l2_hit") + l2m = Event("l2_itlb_misses") + l2r = l2h + l2m + + itlb_l1_mg = None + l1m = l2r + if _zen_model <= 3: + l1r = Event("ic_fw32") + l1h = max(l1r - l1m, 0) + itlb_l1_mg = MetricGroup("lpm_itlb_l1", [ + Metric("lpm_itlb_l1_hits", + "L1 ITLB hits as a perecentage of L1 ITLB accesses.", + d_ratio(l1h, l1h + l1m), "100%"), + Metric("lpm_itlb_l1_miss", + "L1 ITLB misses as a perecentage of L1 ITLB accesses.", + d_ratio(l1m, l1h + l1m), "100%"), + Metric("lpm_itlb_l1_reqs", + "The number of 32B fetch windows transferred from IC pipe to DE " + "instruction decoder per second.", d_ratio( + l1r, interval_sec), + "windows/sec"), + ]) + + return MetricGroup("lpm_itlb", [ + MetricGroup("lpm_itlb_ov", [ + Metric("lpm_itlb_ov_insn_bt_l1_miss", + "Number of instructions between l1 misses", d_ratio( + ins, l1m), "insns"), + Metric("lpm_itlb_ov_insn_bt_l2_miss", + "Number of instructions between l2 misses", d_ratio( + ins, l2m), "insns"), + ]), + itlb_l1_mg, + MetricGroup("lpm_itlb_l2", [ + Metric("lpm_itlb_l2_hits", + "L2 ITLB hits as a percentage of all L2 ITLB accesses.", + d_ratio(l2h, l2r), "100%"), + Metric("lpm_itlb_l2_miss", + "L2 ITLB misses as a percentage of all L2 ITLB accesses.", + d_ratio(l2m, l2r), "100%"), + Metric("lpm_itlb_l2_reqs", "ITLB accesses per second.", + d_ratio(l2r, interval_sec), "accesses/sec"), + ]), + ], description="Instruction TLB breakdown") + + +def AmdLdSt() -> MetricGroup: + ldst_ld = Event("ls_dispatch.pure_ld", "ls_dispatch.ld_dispatch") + ldst_st = Event("ls_dispatch.pure_st", "ls_dispatch.store_dispatch") + ldst_ldc1 = Event(f"{ldst_ld}/cmask=1/") + ldst_stc1 = Event(f"{ldst_st}/cmask=1/") + ldst_ldc2 = Event(f"{ldst_ld}/cmask=2/") + ldst_stc2 = Event(f"{ldst_st}/cmask=2/") + ldst_ldc3 = Event(f"{ldst_ld}/cmask=3/") + ldst_stc3 = Event(f"{ldst_st}/cmask=3/") + ldst_cyc = Event("ls_not_halted_cyc") + + ld_rate = d_ratio(ldst_ld, interval_sec) + st_rate = d_ratio(ldst_st, interval_sec) + + ld_v1 = max(ldst_ldc1 - ldst_ldc2, 0) + ld_v2 = max(ldst_ldc2 - ldst_ldc3, 0) + ld_v3 = ldst_ldc3 + + st_v1 = max(ldst_stc1 - ldst_stc2, 0) + st_v2 = max(ldst_stc2 - ldst_stc3, 0) + st_v3 = ldst_stc3 + + return MetricGroup("lpm_ldst", [ + MetricGroup("lpm_ldst_total", [ + Metric("lpm_ldst_total_ld", "Number of loads dispatched per second.", + ld_rate, "insns/sec"), + Metric("lpm_ldst_total_st", "Number of stores dispatched per second.", + st_rate, "insns/sec"), + ]), + MetricGroup("lpm_ldst_percent_insn", [ + Metric("lpm_ldst_percent_insn_ld", + "Load instructions as a percentage of all instructions.", + d_ratio(ldst_ld, ins), "100%"), + Metric("lpm_ldst_percent_insn_st", + "Store instructions as a percentage of all instructions.", + d_ratio(ldst_st, ins), "100%"), + ]), + MetricGroup("lpm_ldst_ret_loads_per_cycle", [ + Metric( + "lpm_ldst_ret_loads_per_cycle_1", + "Load instructions retiring in 1 cycle as a percentage of all " + "unhalted cycles.", d_ratio(ld_v1, ldst_cyc), "100%"), + Metric( + "lpm_ldst_ret_loads_per_cycle_2", + "Load instructions retiring in 2 cycles as a percentage of all " + "unhalted cycles.", d_ratio(ld_v2, ldst_cyc), "100%"), + Metric( + "lpm_ldst_ret_loads_per_cycle_3", + "Load instructions retiring in 3 or more cycles as a percentage" + "of all unhalted cycles.", d_ratio(ld_v3, ldst_cyc), "100%"), + ]), + MetricGroup("lpm_ldst_ret_stores_per_cycle", [ + Metric( + "lpm_ldst_ret_stores_per_cycle_1", + "Store instructions retiring in 1 cycle as a percentage of all " + "unhalted cycles.", d_ratio(st_v1, ldst_cyc), "100%"), + Metric( + "lpm_ldst_ret_stores_per_cycle_2", + "Store instructions retiring in 2 cycles as a percentage of all " + "unhalted cycles.", d_ratio(st_v2, ldst_cyc), "100%"), + Metric( + "lpm_ldst_ret_stores_per_cycle_3", + "Store instructions retiring in 3 or more cycles as a percentage" + "of all unhalted cycles.", d_ratio(st_v3, ldst_cyc), "100%"), + ]), + MetricGroup("lpm_ldst_insn_bt", [ + Metric("lpm_ldst_insn_bt_ld", "Number of instructions between loads.", + d_ratio(ins, ldst_ld), "insns"), + Metric("lpm_ldst_insn_bt_st", "Number of instructions between stores.", + d_ratio(ins, ldst_st), "insns"), + ]) + ], description="Breakdown of load/store instructions") + + +def AmdUpc() -> Metric: + ops = Event("ex_ret_ops", "ex_ret_cops") + upc = d_ratio(ops, smt_cycles) + return Metric("lpm_upc", "Micro-ops retired per core cycle (higher is better)", + upc, "uops/cycle") + + +def Idle() -> Metric: + cyc = Event("msr/mperf/") + tsc = Event("msr/tsc/") + low = max(tsc - cyc, 0) + return Metric( + "lpm_idle", + "Percentage of total wallclock cycles where CPUs are in low power state (C1 or deeper sleep state)", + d_ratio(low, tsc), "100%") + + +def Rapl() -> MetricGroup: + """Processor socket power consumption estimate. + + Use events from the running average power limit (RAPL) driver. + """ + # Watts = joules/second + # Currently only energy-pkg is supported by AMD: + # https://lore.kernel.org/lkml/20220105185659.643355-1-eranian@google.com/ + pkg = Event("power/energy\\-pkg/") + cond_pkg = Select(pkg, has_event(pkg), math.nan) + scale = 2.3283064365386962890625e-10 + metrics = [ + Metric("lpm_cpu_power_pkg", "", + d_ratio(cond_pkg * scale, interval_sec), "Watts"), + ] + + return MetricGroup("lpm_cpu_power", metrics, + description="Processor socket power consumption estimates") + + +def UncoreL3(): + acc = Event("l3_lookup_state.all_coherent_accesses_to_l3", + "l3_lookup_state.all_l3_req_typs") + miss = Event("l3_lookup_state.l3_miss", + "l3_comb_clstr_state.request_miss") + acc = max(acc, miss) + hits = acc - miss + + return MetricGroup("lpm_l3", [ + Metric("lpm_l3_accesses", "L3 victim cache accesses", + d_ratio(acc, interval_sec), "accesses/sec"), + Metric("lpm_l3_hits", "L3 victim cache hit rate", + d_ratio(hits, acc), "100%"), + Metric("lpm_l3_miss", "L3 victim cache miss rate", d_ratio(miss, acc), + "100%"), + ], description="L3 cache breakdown per CCX") + + +def main() -> None: + global _args + global _zen_model + + def dir_path(path: str) -> str: + """Validate path is a directory for argparse.""" + if os.path.isdir(path): + return path + raise argparse.ArgumentTypeError( + f'\'{path}\' is not a valid directory') + + parser = argparse.ArgumentParser(description="AMD perf json generator") + parser.add_argument( + "-metricgroups", help="Generate metricgroups data", action='store_true') + parser.add_argument("model", help="e.g. amdzen[123]") + parser.add_argument( + 'events_path', + type=dir_path, + help='Root of tree containing architecture directories containing json files' + ) + _args = parser.parse_args() + + directory = f"{_args.events_path}/x86/{_args.model}/" + LoadEvents(directory) + + _zen_model = int(_args.model[6:]) + + all_metrics = MetricGroup("", [ + AmdBr(), + AmdCtxSw(), + AmdDtlb(), + AmdItlb(), + AmdLdSt(), + AmdUpc(), + Cycles(), + Idle(), + Rapl(), + UncoreL3(), + ]) + + if _args.metricgroups: + print(JsonEncodeMetricGroupDescriptions(all_metrics)) + else: + print(JsonEncodeMetric(all_metrics)) + + +if __name__ == '__main__': + main() diff --git a/tools/perf/pmu-events/arch/arm64/arm/cortex-a510/pmu.json b/tools/perf/pmu-events/arch/arm64/arm/cortex-a510/pmu.json deleted file mode 100644 index d8b7b9f9e5fa..000000000000 --- a/tools/perf/pmu-events/arch/arm64/arm/cortex-a510/pmu.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "ArchStdEvent": "PMU_OVFS" - }, - { - "ArchStdEvent": "PMU_HOVFS" - } -] diff --git a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json index 2416d9f8a83d..468cb085d879 100644 --- a/tools/perf/pmu-events/arch/arm64/common-and-microarch.json +++ b/tools/perf/pmu-events/arch/arm64/common-and-microarch.json @@ -432,24 +432,12 @@ "EventName": "TRB_WRAP", "BriefDescription": "Trace buffer current write pointer wrapped" }, - { - "PublicDescription": "PMU overflow, counters accessible to EL1 and EL0", - "EventCode": "0x400D", - "EventName": "PMU_OVFS", - "BriefDescription": "PMU overflow, counters accessible to EL1 and EL0" - }, { "PublicDescription": "Trace buffer Trigger Event", "EventCode": "0x400E", "EventName": "TRB_TRIG", "BriefDescription": "Trace buffer Trigger Event" }, - { - "PublicDescription": "PMU overflow, counters reserved for use by EL2", - "EventCode": "0x400F", - "EventName": "PMU_HOVFS", - "BriefDescription": "PMU overflow, counters reserved for use by EL2" - }, { "PublicDescription": "PE Trace Unit external output 0", "EventCode": "0x4010", diff --git a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/pmu.json b/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/pmu.json deleted file mode 100644 index 65bd6cdd0dd5..000000000000 --- a/tools/perf/pmu-events/arch/arm64/fujitsu/monaka/pmu.json +++ /dev/null @@ -1,10 +0,0 @@ -[ - { - "ArchStdEvent": "PMU_OVFS", - "BriefDescription": "This event counts the event generated each time one of the condition occurs described in Arm Architecture Reference Manual for A-profile architecture. This event is only for output to the trace unit." - }, - { - "ArchStdEvent": "PMU_HOVFS", - "BriefDescription": "This event counts the event generated each time an event is counted by an event counter and all of the condition occur described in Arm Architecture Reference Manual for A-profile architecture. This event is only for output to the trace unit." - } -] diff --git a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json index 7a5d1bf543f8..8d028a7c2777 100644 --- a/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json +++ b/tools/perf/pmu-events/arch/powerpc/power9/nest_metrics.json @@ -29,25 +29,25 @@ "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_RD_DISP_PORT23@", "MetricName" : "mcs01-read", "MetricGroup" : "memory-bandwidth", - "ScaleUnit": "6.1e-5MB" + "ScaleUnit": "6.1e-5MiB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_RD_DISP_PORT23@", "MetricName" : "mcs23-read", "MetricGroup" : "memory-bandwidth", - "ScaleUnit": "6.1e-5MB" + "ScaleUnit": "6.1e-5MiB" }, { "MetricExpr" : "nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT01@ + nest_mcs01_imc@PM_MCS01_128B_WR_DISP_PORT23@", "MetricName" : "mcs01-write", "MetricGroup" : "memory-bandwidth", - "ScaleUnit": "6.1e-5MB" + "ScaleUnit": "6.1e-5MiB" }, { "MetricExpr" : "nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT01@ + nest_mcs23_imc@PM_MCS23_128B_WR_DISP_PORT23@", "MetricName" : "mcs23-write", "MetricGroup" : "memory-bandwidth", - "ScaleUnit": "6.1e-5MB" + "ScaleUnit": "6.1e-5MiB" }, { "MetricExpr" : "nest_powerbus0_imc@PM_PB_CYC@", diff --git a/tools/perf/pmu-events/arch/riscv/mapfile.csv b/tools/perf/pmu-events/arch/riscv/mapfile.csv index d5eea7f9aa9a..87cfb0e0849f 100644 --- a/tools/perf/pmu-events/arch/riscv/mapfile.csv +++ b/tools/perf/pmu-events/arch/riscv/mapfile.csv @@ -21,5 +21,6 @@ 0x489-0x8000000000000[1-6]08-0x[9b][[:xdigit:]]+,v1,sifive/p650,core 0x5b7-0x0-0x0,v1,thead/c900-legacy,core 0x5b7-0x80000000090c0d00-0x2047000,v1,thead/c900-legacy,core +0x602-0x3-0x0,v1,openhwgroup/cva6,core 0x67e-0x80000000db0000[89]0-0x[[:xdigit:]]+,v1,starfive/dubhe-80,core 0x31e-0x8000000000008a45-0x[[:xdigit:]]+,v1,andes/ax45,core diff --git a/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/firmware.json b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/firmware.json new file mode 100644 index 000000000000..7149caec4f80 --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/firmware.json @@ -0,0 +1,68 @@ +[ + { + "ArchStdEvent": "FW_MISALIGNED_LOAD" + }, + { + "ArchStdEvent": "FW_MISALIGNED_STORE" + }, + { + "ArchStdEvent": "FW_ACCESS_LOAD" + }, + { + "ArchStdEvent": "FW_ACCESS_STORE" + }, + { + "ArchStdEvent": "FW_ILLEGAL_INSN" + }, + { + "ArchStdEvent": "FW_SET_TIMER" + }, + { + "ArchStdEvent": "FW_IPI_SENT" + }, + { + "ArchStdEvent": "FW_IPI_RECEIVED" + }, + { + "ArchStdEvent": "FW_FENCE_I_SENT" + }, + { + "ArchStdEvent": "FW_FENCE_I_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_SENT" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_ASID_SENT" + }, + { + "ArchStdEvent": "FW_SFENCE_VMA_ASID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_GVMA_VMID_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_RECEIVED" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_SENT" + }, + { + "ArchStdEvent": "FW_HFENCE_VVMA_ASID_RECEIVED" + } +] diff --git a/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/instructions.json b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/instructions.json new file mode 100644 index 000000000000..c38f6c97cf1f --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/instructions.json @@ -0,0 +1,47 @@ +[ + { + "EventName": "LOAD_INSTRUCTIONS_RETIRED", + "EventCode": "0x5", + "BriefDescription": "number of data memory load instructions retired" + }, + { + "EventName": "STORE_INSTRUCTIONS_RETIRED", + "EventCode": "0x6", + "BriefDescription": "number of data memory store instructions retired" + }, + { + "EventName": "EXCEPTIONS", + "EventCode": "0x7", + "BriefDescription": "valid exceptions encountered" + }, + { + "EventName": "EXCEPTION_HANDLER_RETURNS", + "EventCode": "0x8", + "BriefDescription": "return from an exception" + }, + { + "EventName": "BRANCH_INSTRUCTIONS_RETIRED", + "EventCode": "0x9", + "BriefDescription": "number of branch instructions encountered retired" + }, + { + "EventName": "CALL_INSTRUCTIONS_RETIRED", + "EventCode": "0xC", + "BriefDescription": "number of call instructions retired" + }, + { + "EventName": "RETURN_INSTRUCTIONS_RETIRED", + "EventCode": "0xD", + "BriefDescription": "number of return instructions retired" + }, + { + "EventName": "INTEGER_INSTRUCTIONS_RETIRED", + "EventCode": "0x14", + "BriefDescription": "number of integer instructions retired" + }, + { + "EventName": "FLOATING_POINT_INSTRUCTIONS_RETIRED", + "EventCode": "0x15", + "BriefDescription": "number of floating point instructions retired" + } +] diff --git a/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/memory.json b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/memory.json new file mode 100644 index 000000000000..c4f376a0ee4e --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/memory.json @@ -0,0 +1,42 @@ +[ + { + "EventName": "L1_I_CACHE_MISSES", + "EventCode": "0x1", + "BriefDescription": "number of misses in L1 I-Cache" + }, + { + "EventName": "L1_D_CACHE_MISSES", + "EventCode": "0x2", + "BriefDescription": "number of misses in L1 D-Cache" + }, + { + "EventName": "ITLB_MISSES", + "EventCode": "0x3", + "BriefDescription": "number of misses in ITLB" + }, + { + "EventName": "DTLB_MISSES", + "EventCode": "0x4", + "BriefDescription": "number of misses in DTLB" + }, + { + "EventName": "L1_I_CACHE_ACCESSES", + "EventCode": "0x10", + "BriefDescription": "number of accesses to instruction cache" + }, + { + "EventName": "L1_D_CACHE_ACCESSES", + "EventCode": "0x11", + "BriefDescription": "number of accesses to data cache" + }, + { + "EventName": "L1_CACHE_LINE_EVICTION", + "EventCode": "0x12", + "BriefDescription": "number of data cache line eviction" + }, + { + "EventName": "ITLB_FLUSH", + "EventCode": "0x13", + "BriefDescription": "number of ITLB flushes" + } +] diff --git a/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/microarch.json b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/microarch.json new file mode 100644 index 000000000000..104e6e8197da --- /dev/null +++ b/tools/perf/pmu-events/arch/riscv/openhwgroup/cva6/microarch.json @@ -0,0 +1,27 @@ +[ + { + "EventName": "BRANCH_MISPREDICTS", + "EventCode": "0xA", + "BriefDescription": "number of branch mispredictions" + }, + { + "EventName": "BRANCH_EXCEPTIONS", + "EventCode": "0xB", + "BriefDescription": "number of valid branch exceptions" + }, + { + "EventName": "MSB_FULL", + "EventCode": "0xE", + "BriefDescription": "scoreboard is full" + }, + { + "EventName": "INSTRUCTION_FETCH_EMPTY", + "EventCode": "0xF", + "BriefDescription": "number of invalid instructions in IF stage" + }, + { + "EventName": "PIPELINE_STALL", + "EventCode": "0x16", + "BriefDescription": "number of cycles the pipeline is stalled during read operands" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen5/load-store.json b/tools/perf/pmu-events/arch/x86/amdzen5/load-store.json index ff6627a77805..06bbaea15925 100644 --- a/tools/perf/pmu-events/arch/x86/amdzen5/load-store.json +++ b/tools/perf/pmu-events/arch/x86/amdzen5/load-store.json @@ -70,19 +70,19 @@ "EventName": "ls_mab_alloc.load_store_allocations", "EventCode": "0x41", "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for load-store allocations.", - "UMask": "0x3f" + "UMask": "0x07" }, { "EventName": "ls_mab_alloc.hardware_prefetcher_allocations", "EventCode": "0x41", "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for hardware prefetcher allocations.", - "UMask": "0x40" + "UMask": "0x08" }, { "EventName": "ls_mab_alloc.all_allocations", "EventCode": "0x41", "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for all types of allocations.", - "UMask": "0x7f" + "UMask": "0x0f" }, { "EventName": "ls_dmnd_fills_from_sys.local_l2", diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/branch-prediction.json b/tools/perf/pmu-events/arch/x86/amdzen6/branch-prediction.json new file mode 100644 index 000000000000..dd70069f68ed --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/branch-prediction.json @@ -0,0 +1,93 @@ +[ + { + "EventName": "bp_l1_tlb_miss_l2_tlb_hit", + "EventCode": "0x84", + "BriefDescription": "Instruction fetches that miss in the L1 ITLB but hit in the L2 ITLB." + }, + { + "EventName": "bp_l1_tlb_miss_l2_tlb_miss.if4k", + "EventCode": "0x85", + "BriefDescription": "Instruction fetches that miss in both the L1 and L2 ITLBs (page-table walks requested) for 4k pages.", + "UMask": "0x01" + }, + { + "EventName": "bp_l1_tlb_miss_l2_tlb_miss.if2m", + "EventCode": "0x85", + "BriefDescription": "Instruction fetches that miss in both the L1 and L2 ITLBs (page-table walks requested) for 2M pages.", + "UMask": "0x02" + }, + { + "EventName": "bp_l1_tlb_miss_l2_tlb_miss.if1g", + "EventCode": "0x85", + "BriefDescription": "Instruction fetches that miss in both the L1 and L2 ITLBs (page-table walks requested) for 1G pages.", + "UMask": "0x04" + }, + { + "EventName": "bp_l1_tlb_miss_l2_tlb_miss.coalesced_4k", + "EventCode": "0x85", + "BriefDescription": "Instruction fetches that miss in both the L1 and L2 ITLBs (page-table walks requested) for coalesced pages (16k pages created from four adjacent 4k pages).", + "UMask": "0x08" + }, + { + "EventName": "bp_l1_tlb_miss_l2_tlb_miss.all", + "EventCode": "0x85", + "BriefDescription": "Instruction fetches that miss in both the L1 and L2 ITLBs (page-table walks requested) for all page sizes.", + "UMask": "0x0f" + }, + { + "EventName": "bp_pipe_correct", + "EventCode": "0x8b", + "BriefDescription": "Branch predictor pipeline flushes due to internal conditions such as a second level prediction structure." + }, + { + "EventName": "bp_var_target_pred", + "EventCode": "0x8e", + "BriefDescription": "Indirect predictions (branch used the indirect predictor to make a prediction)." + }, + { + "EventName": "bp_early_redir", + "EventCode": "0x91", + "BriefDescription": "Early redirects sent to branch predictor. This happens when either the decoder or dispatch logic is able to detect that the branch predictor needs to be redirected." + }, + { + "EventName": "bp_l1_tlb_fetch_hit.if4k", + "EventCode": "0x94", + "BriefDescription": "Instruction fetches that hit in the L1 ITLB for 4k or coalesced pages (16k pages created from four adjacent 4k pages).", + "UMask": "0x01" + }, + { + "EventName": "bp_l1_tlb_fetch_hit.if2m", + "EventCode": "0x94", + "BriefDescription": "Instruction fetches that hit in the L1 ITLB for 2M pages.", + "UMask": "0x02" + }, + { + "EventName": "bp_l1_tlb_fetch_hit.if1g", + "EventCode": "0x94", + "BriefDescription": "Instruction fetches that hit in the L1 ITLB for 1G pages.", + "UMask": "0x04" + }, + { + "EventName": "bp_l1_tlb_fetch_hit.all", + "EventCode": "0x94", + "BriefDescription": "Instruction fetches that hit in the L1 ITLB for all page sizes.", + "UMask": "0x07" + }, + { + "EventName": "bp_fe_redir.resync", + "EventCode": "0x9f", + "BriefDescription": "Redirects of the pipeline frontend caused by resyncs. These are retire time pipeline restarts.", + "UMask": "0x01" + }, + { + "EventName": "bp_fe_redir.ex_redir", + "EventCode": "0x9f", + "BriefDescription": "Redirects of the pipeline frontend caused by mispredicts. These are used for branch direction correction and handling indirect branch target mispredicts.", + "UMask": "0x02" + }, + { + "EventName": "bp_fe_redir.all", + "EventCode": "0x9f", + "BriefDescription": "Redirects of the pipeline frontend caused by any reason." + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/decode.json b/tools/perf/pmu-events/arch/x86/amdzen6/decode.json new file mode 100644 index 000000000000..c5d37fbac948 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/decode.json @@ -0,0 +1,139 @@ +[ + { + "EventName": "de_op_queue_empty", + "EventCode": "0xa9", + "BriefDescription": "Cycles where the op queue is empty. Such cycles indicate that the frontend is not delivering instructions fast enough." + }, + { + "EventName": "de_src_op_disp.x86_decoder", + "EventCode": "0xaa", + "BriefDescription": "Ops dispatched from x86 decoder.", + "UMask": "0x01" + }, + { + "EventName": "de_src_op_disp.op_cache", + "EventCode": "0xaa", + "BriefDescription": "Ops dispatched from op cache.", + "UMask": "0x02" + }, + { + "EventName": "de_src_op_disp.all", + "EventCode": "0xaa", + "BriefDescription": "Ops dispatched from any source.", + "UMask": "0x07" + }, + { + "EventName": "de_dis_ops_from_decoder.any_fp", + "EventCode": "0xab", + "BriefDescription": "Ops dispatched from the decoder to a floating-point unit.", + "UMask": "0x04" + }, + { + "EventName": "de_dis_ops_from_decoder.any_int", + "EventCode": "0xab", + "BriefDescription": "Ops dispatched from the decoder to an integer unit.", + "UMask": "0x08" + }, + { + "EventName": "de_disp_stall_cycles_dynamic_tokens_part1.int_phy_reg_file_rsrc_stall", + "EventCode": "0xae", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to integer physical register file resource stalls.", + "UMask": "0x01" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part1.load_queue_rsrc_stall", + "EventCode": "0xae", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to load queue token stalls.", + "UMask": "0x02" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part1.store_queue_rsrc_stall", + "EventCode": "0xae", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to store queue token stalls.", + "UMask": "0x04" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part1.taken_brnch_buffer_rsrc", + "EventCode": "0xae", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to taken branch buffer resource stalls.", + "UMask": "0x10" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part1.fp_sch_rsrc_stall", + "EventCode": "0xae", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to floating-point non-schedulable queue token stalls.", + "UMask": "0x40" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq0", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 0 tokens.", + "UMask": "0x01" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq1", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 1 tokens.", + "UMask": "0x02" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq2", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 2 tokens.", + "UMask": "0x04" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq3", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 3 tokens.", + "UMask": "0x08" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq4", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 4 tokens.", + "UMask": "0x10" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.int_sq5", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of integer scheduler 5 tokens.", + "UMask": "0x20" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.ret_q", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to unavailability of retire queue tokens.", + "UMask": "0x80" + }, + { + "EventName": "de_dispatch_stall_cycle_dynamic_tokens_part2.all", + "EventCode": "0xaf", + "BriefDescription": "Cycles where a dispatch group is valid but does not get dispatched due to any token stalls.", + "UMask": "0xbf" + }, + { + "EventName": "de_no_dispatch_per_slot.no_ops_from_frontend", + "EventCode": "0x1a0", + "BriefDescription": "Dispatch slots in each cycle that were empty because the frontend did not supply ops.", + "UMask": "0x01" + }, + { + "EventName": "de_no_dispatch_per_slot.backend_stalls", + "EventCode": "0x1a0", + "BriefDescription": "Dispatch slots in each cycle that were unused because of backend stalls.", + "UMask": "0x1e" + }, + { + "EventName": "de_no_dispatch_per_slot.smt_contention", + "EventCode": "0x1a0", + "BriefDescription": "Dispatch slots in each cycle that were unused because the dispatch cycle was granted to the other SMT thread.", + "UMask": "0x60" + }, + { + "EventName": "de_additional_resource_stalls.dispatch_stalls", + "EventCode": "0x1a2", + "BriefDescription": "Counts additional cycles where dispatch is stalled due to a lack of dispatch resources.", + "UMask": "0x30" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/execution.json b/tools/perf/pmu-events/arch/x86/amdzen6/execution.json new file mode 100644 index 000000000000..1b80acc89b6f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/execution.json @@ -0,0 +1,192 @@ +[ + { + "EventName": "ex_ret_instr", + "EventCode": "0xc0", + "BriefDescription": "Retired instructions." + }, + { + "EventName": "ex_ret_ops", + "EventCode": "0xc1", + "BriefDescription": "Retired macro-ops." + }, + { + "EventName": "ex_ret_brn", + "EventCode": "0xc2", + "BriefDescription": "Retired branch instructions (all types of architectural control flow changes, including exceptions and interrupts)." + }, + { + "EventName": "ex_ret_brn_misp", + "EventCode": "0xc3", + "BriefDescription": "Retired branch instructions that were mispredicted." + }, + { + "EventName": "ex_ret_brn_tkn", + "EventCode": "0xc4", + "BriefDescription": "Retired taken branch instructions (all types of architectural control flow changes, including exceptions and interrupts)." + }, + { + "EventName": "ex_ret_brn_tkn_misp", + "EventCode": "0xc5", + "BriefDescription": "Retired taken branch instructions that were mispredicted." + }, + { + "EventName": "ex_ret_brn_far", + "EventCode": "0xc6", + "BriefDescription": "Retired far control transfers (far call, far jump, far return, IRET, SYSCALL and SYSRET, plus exceptions and interrupts). Far control transfers are not subject to branch prediction." + }, + { + "EventName": "ex_ret_near_ret", + "EventCode": "0xc8", + "BriefDescription": "Retired near returns (RET or RET Iw)." + }, + { + "EventName": "ex_ret_near_ret_mispred", + "EventCode": "0xc9", + "BriefDescription": "Retired near returns that were mispredicted. Each misprediction incurs the same penalty as that of a mispredicted conditional branch instruction." + }, + { + "EventName": "ex_ret_brn_ind_misp", + "EventCode": "0xca", + "BriefDescription": "Retired indirect branch instructions that were mispredicted (only EX mispredicts). Each misprediction incurs the same penalty as that of a mispredicted conditional branch instruction." + }, + { + "EventName": "ex_ret_brn_ind", + "EventCode": "0xcc", + "BriefDescription": "Retired indirect branch instructions." + }, + { + "EventName": "ex_ret_brn_cond", + "EventCode": "0xd1", + "BriefDescription": "Retired conditional branch instructions." + }, + { + "EventName": "ex_div_busy", + "EventCode": "0xd3", + "BriefDescription": "Cycles where the divider is busy." + }, + { + "EventName": "ex_div_count", + "EventCode": "0xd4", + "BriefDescription": "Divide ops executed." + }, + { + "EventName": "ex_no_retire.empty", + "EventCode": "0xd6", + "BriefDescription": "Cycles where the thread does not retire any ops due to a lack of valid ops in the retire queue (may be caused by front-end bottlenecks or pipeline redirects).", + "UMask": "0x01" + }, + { + "EventName": "ex_no_retire.not_complete", + "EventCode": "0xd6", + "BriefDescription": "Cycles where the thread does not retire any ops as the oldest retire slot is waiting to be marked as completed.", + "UMask": "0x02" + }, + { + "EventName": "ex_no_retire.other", + "EventCode": "0xd6", + "BriefDescription": "Cycles where the thread does not retire any ops due to other reasons (retire breaks, traps, faults, etc.).", + "UMask": "0x08" + }, + { + "EventName": "ex_no_retire.thread_not_selected", + "EventCode": "0xd6", + "BriefDescription": "Cycles where the thread does not retire any ops as thread arbitration did not select the current thread.", + "UMask": "0x10" + }, + { + "EventName": "ex_no_retire.load_not_complete", + "EventCode": "0xd6", + "BriefDescription": "Cycles where the thread does not retire any ops due to missing load completion.", + "UMask": "0xa2" + }, + { + "EventName": "ex_ret_ucode_instr", + "EventCode": "0x1c1", + "BriefDescription": "Retired microcoded instructions." + }, + { + "EventName": "ex_ret_ucode_ops", + "EventCode": "0x1c2", + "BriefDescription": "Retired microcode ops." + }, + { + "EventName": "ex_ret_brn_cond_misp", + "EventCode": "0x1c7", + "BriefDescription": "Retired conditional branch instructions that were mispredicted due to direction mismatch." + }, + { + "EventName": "ex_ret_brn_uncond_ind_near_misp", + "EventCode": "0x1c8", + "BriefDescription": "Retired unconditional indirect near branch instructions that were mispredicted." + }, + { + "EventName": "ex_ret_brn_uncond", + "EventCode": "0x1c9", + "BriefDescription": "Retired unconditional branch instructions." + }, + { + "EventName": "ex_tagged_ibs_ops.tagged", + "EventCode": "0x1cf", + "BriefDescription": "Execution IBS tagged ops.", + "UMask": "0x01" + }, + { + "EventName": "ex_tagged_ibs_ops.tagged_ret", + "EventCode": "0x1cf", + "BriefDescription": "Execution IBS tagged ops that retired.", + "UMask": "0x02" + }, + { + "EventName": "ex_tagged_ibs_ops.rollovers", + "EventCode": "0x1cf", + "BriefDescription": "Execution IBS periodic counter rollovers due to a previous tagged op not being IBS complete.", + "UMask": "0x04" + }, + { + "EventName": "ex_tagged_ibs_ops.filtered", + "EventCode": "0x1cf", + "BriefDescription": "Execution IBS tagged ops that retired but were discarded due to IBS filtering.", + "UMask": "0x08" + }, + { + "EventName": "ex_tagged_ibs_ops.valid", + "EventCode": "0x1cf", + "BriefDescription": "Execution IBS tagged ops that resulted in a valid sample and an IBS interrupt.", + "UMask": "0x10" + }, + { + "EventName": "ex_ret_fused_instr", + "EventCode": "0x1d0", + "BriefDescription": "Retired fused instructions." + }, + { + "EventName": "ex_mprof_ibs_ops.tagged", + "EventCode": "0x2c0", + "BriefDescription": "Memory Profiler IBS tagged ops.", + "UMask": "0x01" + }, + { + "EventName": "ex_mprof_ibs_ops.tagged_ret", + "EventCode": "0x2c0", + "BriefDescription": "Memory Profiler IBS tagged ops that retired.", + "UMask": "0x02" + }, + { + "EventName": "ex_mprof_ibs_ops.rollovers", + "EventCode": "0x2c0", + "BriefDescription": "Memory Profiler IBS periodic counter rollovers due to a previous tagged op not being IBS complete.", + "UMask": "0x04" + }, + { + "EventName": "ex_mprof_ibs_ops.filtered", + "EventCode": "0x2c0", + "BriefDescription": "Memory Profiler IBS tagged ops that retired but were discarded due to IBS filtering.", + "UMask": "0x08" + }, + { + "EventName": "ex_mprof_ibs_ops.valid", + "EventCode": "0x2c0", + "BriefDescription": "Memory Profiler IBS tagged ops that resulted in a valid sample and an IBS interrupt.", + "UMask": "0x10" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/floating-point.json b/tools/perf/pmu-events/arch/x86/amdzen6/floating-point.json new file mode 100644 index 000000000000..03cb039434de --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/floating-point.json @@ -0,0 +1,1106 @@ +[ + { + "EventName": "fp_ret_x87_fp_ops.add_sub_ops", + "EventCode": "0x02", + "BriefDescription": "Retired x87 floating-point add and subtract uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_ret_x87_fp_ops.mul_ops", + "EventCode": "0x02", + "BriefDescription": "Retired x87 floating-point multiply uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_ret_x87_fp_ops.div_sqrt_ops", + "EventCode": "0x02", + "BriefDescription": "Retired x87 floating-point divide and square root uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_ret_x87_fp_ops.all", + "EventCode": "0x02", + "BriefDescription": "Retired x87 floating-point uops of all types.", + "UMask": "0x07" + }, + { + "EventName": "fp_ret_sse_avx_ops.add_sub_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX add and subtract FLOPs.", + "UMask": "0x01" + }, + { + "EventName": "fp_ret_sse_avx_ops.mult_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX multiply FLOPs.", + "UMask": "0x02" + }, + { + "EventName": "fp_ret_sse_avx_ops.div_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX divide and square root FLOPs.", + "UMask": "0x04" + }, + { + "EventName": "fp_ret_sse_avx_ops.mac_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX multiply-accumulate FLOPs (each operation is counted as 2 FLOPs, bfloat operations are not included).", + "UMask": "0x08" + }, + { + "EventName": "fp_ret_sse_avx_ops.bfloat16_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX bfloat16 FLOPs.", + "UMask": "0x20" + }, + { + "EventName": "fp_ret_sse_avx_ops.scalar_single_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX scalar single-precision (FP32) FLOPs.", + "UMask": "0x40" + }, + { + "EventName": "fp_ret_sse_avx_ops.packed_single_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX packed single-precision (FP32) FLOPs.", + "UMask": "0x60" + }, + { + "EventName": "fp_ret_sse_avx_ops.scalar_double_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX scalar double-precision (FP64) FLOPs.", + "UMask": "0x80" + }, + { + "EventName": "fp_ret_sse_avx_ops.packed_double_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX packed double-precision (FP64) FLOPs.", + "UMask": "0xa0" + }, + { + "EventName": "fp_ret_sse_avx_ops.scalar_half_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX scalar half-precision (FP16) FLOPs.", + "UMask": "0xa0" + }, + { + "EventName": "fp_ret_sse_avx_ops.packed_half_flops", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX packed half-precision (FP16) FLOPs.", + "UMask": "0xa0" + }, + { + "EventName": "fp_ret_sse_avx_ops.all", + "EventCode": "0x03", + "BriefDescription": "Retired SSE and AVX FLOPs of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_ops_ret_by_width.x87", + "EventCode": "0x08", + "BriefDescription": "Retired x87 floating-point uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_ops_ret_by_width.mmx", + "EventCode": "0x08", + "BriefDescription": "Retired MMX floating-point uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_ops_ret_by_width.scalar", + "EventCode": "0x08", + "BriefDescription": "Retired scalar floating-point uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_ops_ret_by_width.pack_128", + "EventCode": "0x08", + "BriefDescription": "Retired packed 128-bit floating-point uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_ops_ret_by_width.pack_256", + "EventCode": "0x08", + "BriefDescription": "Retired packed 256-bit floating-point uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_ops_ret_by_width.pack_512", + "EventCode": "0x08", + "BriefDescription": "Retired packed 512-bit floating-point uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_ops_ret_by_width.all", + "EventCode": "0x08", + "BriefDescription": "Retired floating-point uops of all widths.", + "UMask": "0x3f" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_add", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point add uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_sub", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point subtract uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_mul", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point multiply uops.", + "UMask": "0x03" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_mac", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point multiply-accumulate uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_div", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point divide uops.", + "UMask": "0x05" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_sqrt", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point square root uops.", + "UMask": "0x06" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_cmp", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point compare uops.", + "UMask": "0x07" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_cvt", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point convert uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_blend", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point blend uops.", + "UMask": "0x09" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_move", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point move uops.", + "UMask": "0x0a" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_shuffle", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0x0b" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_bfloat", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point bfloat uops.", + "UMask": "0x0c" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_logical", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point move uops.", + "UMask": "0x0d" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_other", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point uops of other types.", + "UMask": "0x0e" + }, + { + "EventName": "fp_ops_ret_by_type.scalar_all", + "EventCode": "0x0a", + "BriefDescription": "Retired scalar floating-point uops of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_ops_ret_by_type.vector_add", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point add uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_ops_ret_by_type.vector_sub", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point subtract uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_ops_ret_by_type.vector_mul", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point multiply uops.", + "UMask": "0x30" + }, + { + "EventName": "fp_ops_ret_by_type.vector_mac", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point multiply-accumulate uops.", + "UMask": "0x40" + }, + { + "EventName": "fp_ops_ret_by_type.vector_div", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point divide uops.", + "UMask": "0x50" + }, + { + "EventName": "fp_ops_ret_by_type.vector_sqrt", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point square root uops.", + "UMask": "0x60" + }, + { + "EventName": "fp_ops_ret_by_type.vector_cmp", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point compare uops.", + "UMask": "0x70" + }, + { + "EventName": "fp_ops_ret_by_type.vector_cvt", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point convert uops.", + "UMask": "0x80" + }, + { + "EventName": "fp_ops_ret_by_type.vector_blend", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point blend uops.", + "UMask": "0x90" + }, + { + "EventName": "fp_ops_ret_by_type.vector_move", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point move uops.", + "UMask": "0xa0" + }, + { + "EventName": "fp_ops_ret_by_type.vector_shuffle", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0xb0" + }, + { + "EventName": "fp_ops_ret_by_type.vector_bfloat", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point bfloat uops.", + "UMask": "0xc0" + }, + { + "EventName": "fp_ops_ret_by_type.vector_logical", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point logical uops.", + "UMask": "0xd0" + }, + { + "EventName": "fp_ops_ret_by_type.vector_other", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point uops of other types.", + "UMask": "0xe0" + }, + { + "EventName": "fp_ops_ret_by_type.vector_all", + "EventCode": "0x0a", + "BriefDescription": "Retired vector floating-point uops of all types.", + "UMask": "0xf0" + }, + { + "EventName": "fp_ops_ret_by_type.all", + "EventCode": "0x0a", + "BriefDescription": "Retired floating-point uops of all types.", + "UMask": "0xff" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_add", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer add uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_sub", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer subtract uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_mul", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer multiply uops.", + "UMask": "0x03" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_mac", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer multiply-accumulate uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_aes", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer AES uops.", + "UMask": "0x05" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_sha", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer SHA uops.", + "UMask": "0x06" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_cmp", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer compare uops.", + "UMask": "0x07" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_cvt", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer convert or pack uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_shift", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer shift or rotate uops.", + "UMask": "0x09" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_mov", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer move uops.", + "UMask": "0x0a" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_shuffle", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0x0b" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_vnni", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer VNNI uops.", + "UMask": "0x0c" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_logical", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer logical uops.", + "UMask": "0x0d" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_other", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer multiply uops of other types.", + "UMask": "0x0e" + }, + { + "EventName": "fp_sse_avx_ops_ret.mmx_all", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX integer uops of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_add", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer add uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_sub", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer subtract uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_mul", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer multiply uops.", + "UMask": "0x30" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_mac", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer multiply-accumulate uops.", + "UMask": "0x40" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_aes", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer AES uops.", + "UMask": "0x50" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_sha", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer SHA uops.", + "UMask": "0x60" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_cmp", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer compare uops.", + "UMask": "0x70" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_cvt", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer convert or pack uops.", + "UMask": "0x80" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_shift", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer shift or rotate uops.", + "UMask": "0x90" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_mov", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer move uops.", + "UMask": "0xa0" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_shuffle", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0xb0" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_vnni", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer VNNI uops.", + "UMask": "0xc0" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_logical", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer logical uops.", + "UMask": "0xd0" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_other", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer uops of other types.", + "UMask": "0xe0" + }, + { + "EventName": "fp_sse_avx_ops_ret.sse_avx_all", + "EventCode": "0x0b", + "BriefDescription": "Retired SSE and AVX integer uops of all types.", + "UMask": "0xf0" + }, + { + "EventName": "fp_sse_avx_ops_ret.all", + "EventCode": "0x0b", + "BriefDescription": "Retired MMX, SSE and AVX integer uops of all types.", + "UMask": "0xff" + }, + { + "EventName": "fp_pack_ops_ret.fp128_add", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point add uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_pack_ops_ret.fp128_sub", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point subtract uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_pack_ops_ret.fp128_mul", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point multiply uops.", + "UMask": "0x03" + }, + { + "EventName": "fp_pack_ops_ret.fp128_mac", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point multiply-accumulate uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_pack_ops_ret.fp128_div", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point divide uops.", + "UMask": "0x05" + }, + { + "EventName": "fp_pack_ops_ret.fp128_sqrt", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point square root uops.", + "UMask": "0x06" + }, + { + "EventName": "fp_pack_ops_ret.fp128_cmp", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point compare uops.", + "UMask": "0x07" + }, + { + "EventName": "fp_pack_ops_ret.fp128_cvt", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point convert uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_pack_ops_ret.fp128_blend", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point blend uops.", + "UMask": "0x09" + }, + { + "EventName": "fp_pack_ops_ret.fp128_mov", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point move uops.", + "UMask": "0x0a" + }, + { + "EventName": "fp_pack_ops_ret.fp128_shuffle", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0x0b" + }, + { + "EventName": "fp_pack_ops_ret.fp128_bfloat", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point bfloat uops.", + "UMask": "0x0c" + }, + { + "EventName": "fp_pack_ops_ret.fp128_logical", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point logical uops.", + "UMask": "0x0d" + }, + { + "EventName": "fp_pack_ops_ret.fp128_other", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point uops of other types.", + "UMask": "0x0e" + }, + { + "EventName": "fp_pack_ops_ret.fp128_all", + "EventCode": "0x0c", + "BriefDescription": "Retired 128-bit packed floating-point uops of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_pack_ops_ret.fp256_add", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point add uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_pack_ops_ret.fp256_sub", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point subtract uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_pack_ops_ret.fp256_mul", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point multiply uops.", + "UMask": "0x30" + }, + { + "EventName": "fp_pack_ops_ret.fp256_mac", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point multiply-accumulate uops.", + "UMask": "0x40" + }, + { + "EventName": "fp_pack_ops_ret.fp256_div", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point divide uops.", + "UMask": "0x50" + }, + { + "EventName": "fp_pack_ops_ret.fp256_sqrt", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point square root uops.", + "UMask": "0x60" + }, + { + "EventName": "fp_pack_ops_ret.fp256_cmp", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point compare uops.", + "UMask": "0x70" + }, + { + "EventName": "fp_pack_ops_ret.fp256_cvt", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point convert uops.", + "UMask": "0x80" + }, + { + "EventName": "fp_pack_ops_ret.fp256_blend", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point blend uops.", + "UMask": "0x90" + }, + { + "EventName": "fp_pack_ops_ret.fp256_mov", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point move uops.", + "UMask": "0xa0" + }, + { + "EventName": "fp_pack_ops_ret.fp256_shuffle", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0xb0" + }, + { + "EventName": "fp_pack_ops_ret.fp256_logical", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point logical uops.", + "UMask": "0xd0" + }, + { + "EventName": "fp_pack_ops_ret.fp256_other", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point uops of other types.", + "UMask": "0xe0" + }, + { + "EventName": "fp_pack_ops_ret.fp256_all", + "EventCode": "0x0c", + "BriefDescription": "Retired 256-bit packed floating-point uops of all types.", + "UMask": "0xf0" + }, + { + "EventName": "fp_pack_ops_ret.fp_all", + "EventCode": "0x0c", + "BriefDescription": "Retired packed floating-point uops of all types.", + "UMask": "0xff" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_add", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer add uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_sub", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer subtract uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_mul", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer multiply uops.", + "UMask": "0x03" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_mac", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer multiply-accumulate uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_aes", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer AES uops.", + "UMask": "0x05" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_sha", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer SHA uops.", + "UMask": "0x06" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_cmp", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer compare uops.", + "UMask": "0x07" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_cvt", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer convert or pack uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_shift", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer shift or rotate uops.", + "UMask": "0x09" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_mov", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer move uops.", + "UMask": "0x0a" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_shuffle", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0x0b" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_vnni", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer VNNI ops.", + "UMask": "0x0c" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_logical", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer logical uops.", + "UMask": "0x0d" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_other", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer uops of other types.", + "UMask": "0x0e" + }, + { + "EventName": "fp_pack_int_ops_ret.int128_all", + "EventCode": "0x0d", + "BriefDescription": "Retired 128-bit packed integer uops of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_add", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer add uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_sub", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer subtract uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_mul", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer multiply uops.", + "UMask": "0x30" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_mac", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer multiply-accumulate uops.", + "UMask": "0x40" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_cmp", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer compare uops.", + "UMask": "0x70" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_shift", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer shift or rotate uops.", + "UMask": "0x90" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_mov", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer move uops.", + "UMask": "0xa0" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_shuffle", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0xb0" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_vnni", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer VNNI uops.", + "UMask": "0xc0" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_logical", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer logical uops.", + "UMask": "0xd0" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_other", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer uops of other types.", + "UMask": "0xe0" + }, + { + "EventName": "fp_pack_int_ops_ret.int256_all", + "EventCode": "0x0d", + "BriefDescription": "Retired 256-bit packed integer uops of all types.", + "UMask": "0xf0" + }, + { + "EventName": "fp_pack_int_ops_ret.int_all", + "EventCode": "0x0d", + "BriefDescription": "Retired packed integer uops of all types.", + "UMask": "0xff" + }, + { + "EventName": "fp_disp_faults.x87_fill_fault", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults for x87 fills.", + "UMask": "0x01" + }, + { + "EventName": "fp_disp_faults.xmm_fill_fault", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults for XMM fills.", + "UMask": "0x02" + }, + { + "EventName": "fp_disp_faults.ymm_fill_fault", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults for YMM fills.", + "UMask": "0x04" + }, + { + "EventName": "fp_disp_faults.ymm_spill_fault", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults for YMM spills.", + "UMask": "0x08" + }, + { + "EventName": "fp_disp_faults.sse_avx_all", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults of all types for SSE and AVX ops.", + "UMask": "0x0e" + }, + { + "EventName": "fp_disp_faults.all", + "EventCode": "0x0e", + "BriefDescription": "Floating-point dispatch faults of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_add", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point add uops.", + "UMask": "0x01" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_sub", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point subtract uops.", + "UMask": "0x02" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_mul", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point multiply uops.", + "UMask": "0x03" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_mac", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point multiply-accumulate uops.", + "UMask": "0x04" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_div", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point divide uops.", + "UMask": "0x05" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_sqrt", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point square root uops.", + "UMask": "0x06" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_cmp", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point compare uops.", + "UMask": "0x07" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_cvt", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point convert uops.", + "UMask": "0x08" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_blend", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point blend uops.", + "UMask": "0x09" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_mov", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point move uops.", + "UMask": "0x0a" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_shuffle", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0x0b" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_bfloat", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point bfloat uops.", + "UMask": "0x0c" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_logical", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point logical uops.", + "UMask": "0x0d" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_other", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point uops of other types.", + "UMask": "0x0e" + }, + { + "EventName": "fp_pack_512b_ops_ret.fp512_all", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed floating-point uops of all types.", + "UMask": "0x0f" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_add", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer add uops.", + "UMask": "0x10" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_sub", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer subtract uops.", + "UMask": "0x20" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_mul", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer multiply uops.", + "UMask": "0x30" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_mac", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer multiply-accumulate uops.", + "UMask": "0x40" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_aes", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer AES uops.", + "UMask": "0x50" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_sha", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer SHA uops.", + "UMask": "0x60" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_cmp", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer compare uops.", + "UMask": "0x70" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_cvt", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer convert or pack uops.", + "UMask": "0x80" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_shift", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer shift or rotate uops.", + "UMask": "0x90" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_mov", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer move uops.", + "UMask": "0xa0" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_shuffle", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer shuffle uops (may include instructions not necessarily thought of as including shuffles e.g. horizontal add, dot product, and certain MOV instructions).", + "UMask": "0xb0" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_vnni", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer VNNI uops.", + "UMask": "0xc0" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_logical", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer logical uops.", + "UMask": "0xd0" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_other", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer uops of other types.", + "UMask": "0xe0" + }, + { + "EventName": "fp_pack_512b_ops_ret.int512_all", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed integer uops of all types.", + "UMask": "0xf0" + }, + { + "EventName": "fp_pack_512b_ops_ret.512b_all", + "EventCode": "0x0f", + "BriefDescription": "Retired 512-bit packed uops of all types.", + "UMask": "0xff" + }, + { + "EventName": "fp_nsq_read_stalls.fp_prf", + "EventCode": "0x13", + "BriefDescription": "Cycles when reads of the NSQ and writes to the floating-point or SIMD schedulers are stalled due to insufficient free physical register file (FP-PRF) entries.", + "UMask": "0x0e" + }, + { + "EventName": "fp_nsq_read_stalls.k_prf", + "EventCode": "0x13", + "BriefDescription": "Cycles when reads of the NSQ and writes to the floating-point or SIMD schedulers are stalled due to insufficient free mask physical register file (K-PRF) entries.", + "UMask": "0x0e" + }, + { + "EventName": "fp_nsq_read_stalls.fp_sq", + "EventCode": "0x13", + "BriefDescription": "Cycles when reads of the NSQ and writes to the floating-point or SIMD schedulers are stalled due to insufficient free scheduler entries.", + "UMask": "0x0e" + }, + { + "EventName": "fp_nsq_read_stalls.all", + "EventCode": "0x13", + "BriefDescription": "Cycles when reads of the NSQ and writes to the floating-point or SIMD schedulers are stalled due to any reason.", + "UMask": "0x0e" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/inst-cache.json b/tools/perf/pmu-events/arch/x86/amdzen6/inst-cache.json new file mode 100644 index 000000000000..5ab6766f8940 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/inst-cache.json @@ -0,0 +1,120 @@ +[ + { + "EventName": "ic_cache_fill_l2", + "EventCode": "0x82", + "BriefDescription": "Instruction cache lines (64 bytes) fulfilled from the L2 cache." + }, + { + "EventName": "ic_cache_fill_sys", + "EventCode": "0x83", + "BriefDescription": "Instruction cache lines (64 bytes) fulfilled from system memory or another cache." + }, + { + "EventName": "ic_fetch_ibs_events.tagged", + "EventCode": "0x188", + "BriefDescription": "Fetch IBS tagged fetches. Not all tagged fetches result in a valid sample and an IBS interrupt.", + "UMask": "0x02" + }, + { + "EventName": "ic_fetch_ibs_events.filtered", + "EventCode": "0x188", + "BriefDescription": "Fetch IBS tagged fetches that were discarded due to IBS filtering.", + "UMask": "0x08" + }, + { + "EventName": "ic_fetch_ibs_events.valid", + "EventCode": "0x188", + "BriefDescription": "Fetch IBS tagged fetches that resulted in a valid sample and an IBS interrupt.", + "UMask": "0x10" + }, + { + "EventName": "op_cache_hit_miss.hit", + "EventCode": "0x28f", + "BriefDescription": "Op cache fetch hits.", + "UMask": "0x03" + }, + { + "EventName": "op_cache_hit_miss.miss", + "EventCode": "0x28f", + "BriefDescription": "Op cache fetch misses.", + "UMask": "0x04" + }, + { + "EventName": "op_cache_hit_miss.all", + "EventCode": "0x28f", + "BriefDescription": "Op cache fetches of all types.", + "UMask": "0x07" + }, + { + "EventName": "ic_fills_from_sys.local_l2", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from local L2 cache.", + "UMask": "0x01" + }, + { + "EventName": "ic_fills_from_sys.local_ccx", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "ic_fills_from_sys.local_all", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from local L2 cache, L3 cache or different L2 cache in the same CCX.", + "UMask": "0x03" + }, + { + "EventName": "ic_fills_from_sys.near_cache", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "ic_fills_from_sys.dram_io_near", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "ic_fills_from_sys.far_cache", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "ic_fills_from_sys.remote_cache", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from cache of another CCX in the same or a different NUMA node.", + "UMask": "0x14" + }, + { + "EventName": "ic_fills_from_sys.dram_io_far", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "ic_fills_from_sys.dram_io_all", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "ic_fills_from_sys.far_all", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from either cache of another CCX, DRAM or MMIO in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "ic_fills_from_sys.alt_mem", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "ic_fills_from_sys.all", + "EventCode": "0x29c", + "BriefDescription": "Instruction cache fills where data is returned from all types of sources.", + "UMask": "0xdf" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/l2-cache.json b/tools/perf/pmu-events/arch/x86/amdzen6/l2-cache.json new file mode 100644 index 000000000000..b0b2090fb920 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/l2-cache.json @@ -0,0 +1,326 @@ +[ + { + "EventName": "l2_request_g1.group2", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests of non-cacheable type (non-cached data and instructions reads, self-modifying code checks).", + "UMask": "0x01" + }, + { + "EventName": "l2_request_g1.l2_hwpf", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests from hardware prefetchers to prefetch directly into L2 (hit or miss).", + "UMask": "0x02" + }, + { + "EventName": "l2_request_g1.prefetch_l2_cmd", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests to prefetch directly into L2.", + "UMask": "0x04" + }, + { + "EventName": "l2_request_g1.cacheable_ic_read", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests for instruction cache reads.", + "UMask": "0x10" + }, + { + "EventName": "l2_request_g1.ls_rd_blk_c_s", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests for data cache shared reads.", + "UMask": "0x20" + }, + { + "EventName": "l2_request_g1.rd_blk_x", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests for data cache stores.", + "UMask": "0x40" + }, + { + "EventName": "l2_request_g1.rd_blk_l", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests for data cache reads (includes hardware and software prefetches).", + "UMask": "0x80" + }, + { + "EventName": "l2_request_g1.dc_all", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests of common types from data cache (includes prefetches).", + "UMask": "0xe0" + }, + { + "EventName": "l2_request_g1.no_pf_all", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests of common types not including prefetches.", + "UMask": "0xf1" + }, + { + "EventName": "l2_request_g1.all", + "EventCode": "0x60", + "BriefDescription": "L2 cache requests of all types.", + "UMask": "0xf7" + }, + { + "EventName": "l2_request_g2.ls_rd_sized_nc", + "EventCode": "0x61", + "BriefDescription": "L2 cache requests for non-coherent, non-cacheable LS sized reads.", + "UMask": "0x20" + }, + { + "EventName": "l2_request_g2.ls_rd_sized", + "EventCode": "0x61", + "BriefDescription": "L2 cache requests for coherent, non-cacheable LS sized reads.", + "UMask": "0x40" + }, + { + "EventName": "l2_request_g2.all", + "EventCode": "0x61", + "BriefDescription": "L2 cache requests of all rare types.", + "UMask": "0x40" + }, + { + "EventName": "l2_wcb_req.wcb_close", + "EventCode": "0x63", + "BriefDescription": "Write Combining Buffer (WCB) closures.", + "UMask": "0x20" + }, + { + "EventName": "l2_cache_req_stat.ic_fill_miss", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the instruction cache that result in L2 misses.", + "UMask": "0x01" + }, + { + "EventName": "l2_cache_req_stat.ic_fill_hit_s", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the instruction cache that result in L2 hits on non-modifiable lines.", + "UMask": "0x02" + }, + { + "EventName": "l2_cache_req_stat.ic_fill_hit_x", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the instruction cache that result in L2 hits on modifiable lines.", + "UMask": "0x04" + }, + { + "EventName": "l2_cache_req_stat.ic_hit_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the instruction cache that result in L2 hits.", + "UMask": "0x06" + }, + { + "EventName": "l2_cache_req_stat.ic_access_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the instruction cache that result in L2 accesses.", + "UMask": "0x07" + }, + { + "EventName": "l2_cache_req_stat.ls_rd_blk_c", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 misses.", + "UMask": "0x08" + }, + { + "EventName": "l2_cache_req_stat.ic_dc_miss_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache and the instruction cache that result in L2 misses.", + "UMask": "0x09" + }, + { + "EventName": "l2_cache_req_stat.ls_rd_blk_x", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) that result in data cache stores or L2 state change hits.", + "UMask": "0x10" + }, + { + "EventName": "l2_cache_req_stat.ls_rd_blk_l_hit_s", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 hits on non-modifiable lines.", + "UMask": "0x20" + }, + { + "EventName": "l2_cache_req_stat.ls_rd_blk_l_hit_x", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 hits on modifiable lines.", + "UMask": "0x40" + }, + { + "EventName": "l2_cache_req_stat.ls_rd_blk_cs", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 read hits on shared lines.", + "UMask": "0x80" + }, + { + "EventName": "l2_cache_req_stat.dc_hit_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 hits.", + "UMask": "0xf0" + }, + { + "EventName": "l2_cache_req_stat.ic_dc_hit_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache and the instruction cache that result in L2 hits.", + "UMask": "0xf6" + }, + { + "EventName": "l2_cache_req_stat.dc_access_in_l2", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache that result in L2 accesses.", + "UMask": "0xf8" + }, + { + "EventName": "l2_cache_req_stat.all", + "EventCode": "0x64", + "BriefDescription": "Core to L2 cache requests (not including L2 prefetch) from the data cache and the instruction cache that result in L2 accesses.", + "UMask": "0xff" + }, + { + "EventName": "l2_pf_hit_l2.l2_hwpf", + "EventCode": "0x70", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which hit in the L2 cache and are generated from L2 hardware prefetchers.", + "UMask": "0x1f" + }, + { + "EventName": "l2_pf_hit_l2.l1_dc_hwpf", + "EventCode": "0x70", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which hit in the L2 cache and are generated from L1 data hardware prefetchers.", + "UMask": "0xe0" + }, + { + "EventName": "l2_pf_hit_l2.l1_dc_l2_hwpf", + "EventCode": "0x70", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which hit in the L2 cache and are generated from L1 data and L2 hardware prefetchers.", + "UMask": "0xff" + }, + { + "EventName": "l2_pf_miss_l2_hit_l3.l2_hwpf", + "EventCode": "0x71", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 cache but hit in the L3 cache and are generated from L2 hardware prefetchers.", + "UMask": "0x1f" + }, + { + "EventName": "l2_pf_miss_l2_hit_l3.l1_dc_hwpf", + "EventCode": "0x71", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 cache but hit in the L3 cache and are generated from L1 data hardware prefetchers.", + "UMask": "0xe0" + }, + { + "EventName": "l2_pf_miss_l2_hit_l3.l1_dc_l2_hwpf", + "EventCode": "0x71", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 cache but hit in the L3 cache and are generated from L1 data and L2 hardware prefetchers.", + "UMask": "0xff" + }, + { + "EventName": "l2_pf_miss_l2_l3.l2_hwpf", + "EventCode": "0x72", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 as well as the L3 caches and are generated from L2 hardware prefetchers.", + "UMask": "0x1f" + }, + { + "EventName": "l2_pf_miss_l2_l3.l1_dc_hwpf", + "EventCode": "0x72", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 as well as the L3 caches and are generated from L1 data hardware prefetchers.", + "UMask": "0xe0" + }, + { + "EventName": "l2_pf_miss_l2_l3.l1_dc_l2_hwpf", + "EventCode": "0x72", + "BriefDescription": "L2 prefetches accepted by the L2 pipeline which miss the L2 as well as the L3 caches and are generated from L1 data and L2 hardware prefetchers.", + "UMask": "0xff" + }, + { + "EventName": "l2_fill_rsp_src.local_ccx", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "l2_fill_rsp_src.near_cache", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "l2_fill_rsp_src.dram_io_near", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "l2_fill_rsp_src.far_cache", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "l2_fill_rsp_src.dram_io_far", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "l2_fill_rsp_src.dram_io_all", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "l2_fill_rsp_src.far_all", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from either cache of another CCX, DRAM or MMIO in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "l2_fill_rsp_src.alt_mem", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "l2_fill_rsp_src.all", + "EventCode": "0x165", + "BriefDescription": "L2 cache fills where data is returned from all types of sources.", + "UMask": "0xde" + }, + { + "EventName": "l2_sys_bw.local_dram_fill", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for fill events that target the same NUMA node and return from DRAM in the same NUMA node.", + "UMask": "0x01" + }, + { + "EventName": "l2_sys_bw.remote_dram_fill", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for fill events that target a different NUMA node and return from DRAM in a different NUMA node.", + "UMask": "0x02" + }, + { + "EventName": "l2_sys_bw.nt_write", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for non-temporal write events that target all NUMA nodes.", + "UMask": "0x04" + }, + { + "EventName": "l2_sys_bw.local_scm_fill", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for fill events that target the same NUMA node and return from extension memory (CXL) in the same NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "l2_sys_bw.remote_scm_fill", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for fill events that target a different NUMA node and return from extension memory (CXL) in a different NUMA node.", + "UMask": "0x20" + }, + { + "EventName": "l2_sys_bw.victim", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for cache victim events that target all NUMA nodes.", + "UMask": "0x40" + }, + { + "EventName": "l2_sys_bw.all", + "EventCode": "0x175", + "BriefDescription": "System bandwidth utilization for all types of events (total utilization).", + "UMask": "0xff" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/l3-cache.json b/tools/perf/pmu-events/arch/x86/amdzen6/l3-cache.json new file mode 100644 index 000000000000..9b9804317da7 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/l3-cache.json @@ -0,0 +1,177 @@ +[ + { + "EventName": "l3_lookup_state.l3_miss", + "EventCode": "0x04", + "BriefDescription": "L3 cache misses.", + "UMask": "0x01", + "Unit": "L3PMC" + }, + { + "EventName": "l3_lookup_state.l3_hit", + "EventCode": "0x04", + "BriefDescription": "L3 cache hits.", + "UMask": "0xfe", + "Unit": "L3PMC" + }, + { + "EventName": "l3_lookup_state.all_coherent_accesses_to_l3", + "EventCode": "0x04", + "BriefDescription": "L3 cache requests for all coherent accesses.", + "UMask": "0xff", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.dram_near", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from DRAM in the same NUMA node.", + "UMask": "0x01", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.dram_far", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from DRAM in a different NUMA node.", + "UMask": "0x02", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.near_cache", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.far_cache", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x08", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.ext_near", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from extension memory (CXL) in the same NUMA node.", + "UMask": "0x10", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.ext_far", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from extension memory (CXL) in a different NUMA node.", + "UMask": "0x20", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency.all", + "EventCode": "0xac", + "BriefDescription": "Average sampled latency for L3 requests where data is returned from all types of sources.", + "UMask": "0x3f", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.dram_near", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from DRAM in the same NUMA node.", + "UMask": "0x01", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.dram_far", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from DRAM in a different NUMA node.", + "UMask": "0x02", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.near_cache", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.far_cache", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x08", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.ext_near", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from extension memory (CXL) in the same NUMA node.", + "UMask": "0x10", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.ext_far", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from extension memory (CXL) in a different NUMA node.", + "UMask": "0x20", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + }, + { + "EventName": "l3_xi_sampled_latency_requests.all", + "EventCode": "0xad", + "BriefDescription": "Average sampled L3 requests where data is returned from all types of sources.", + "UMask": "0x3f", + "EnAllCores": "0x1", + "EnAllSlices": "0x1", + "SliceId": "0x3", + "ThreadMask": "0x3", + "Unit": "L3PMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/load-store.json b/tools/perf/pmu-events/arch/x86/amdzen6/load-store.json new file mode 100644 index 000000000000..4291eb59426f --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/load-store.json @@ -0,0 +1,523 @@ +[ + { + "EventName": "ls_bad_status2.stli_other", + "EventCode": "0x24", + "BriefDescription": "Store-to-load conflicts (loads unable to complete due to a non-forwardable conflict with an older store).", + "UMask": "0x02" + }, + { + "EventName": "ls_locks.bus_lock", + "EventCode": "0x25", + "BriefDescription": "Retired lock instructions which caused a bus lock (non-cacheable or cache-misaligned lock).", + "UMask": "0x01" + }, + { + "EventName": "ls_locks.all", + "EventCode": "0x25", + "BriefDescription": "Retired lock instructions of all types.", + "UMask": "0x1f" + }, + { + "EventName": "ls_ret_cl_flush", + "EventCode": "0x26", + "BriefDescription": "Retired CLFLUSH instructions." + }, + { + "EventName": "ls_ret_cpuid", + "EventCode": "0x27", + "BriefDescription": "Retired CPUID instructions." + }, + { + "EventName": "ls_dispatch.pure_ld", + "EventCode": "0x29", + "BriefDescription": "Memory load operations dispatched to the load-store unit.", + "UMask": "0x01" + }, + { + "EventName": "ls_dispatch.pure_st", + "EventCode": "0x29", + "BriefDescription": "Memory store operations dispatched to the load-store unit.", + "UMask": "0x02" + }, + { + "EventName": "ls_dispatch.ld_st", + "EventCode": "0x29", + "BriefDescription": "Memory load-store operations (load from and store to the same memory address) dispatched to the load-store unit.", + "UMask": "0x04" + }, + { + "EventName": "ls_dispatch.all", + "EventCode": "0x29", + "BriefDescription": "Memory operations dispatched to the load-store unit of all types.", + "UMask": "0x07" + }, + { + "EventName": "ls_smi_rx", + "EventCode": "0x2b", + "BriefDescription": "System Management Interrupts (SMIs) received." + }, + { + "EventName": "ls_int_taken", + "EventCode": "0x2c", + "BriefDescription": "Interrupts taken." + }, + { + "EventName": "ls_stlf", + "EventCode": "0x35", + "BriefDescription": "Store-to-load-forward (STLF) hits." + }, + { + "EventName": "ls_st_commit_cancel.older_st_vis_dep", + "EventCode": "0x37", + "BriefDescription": "Store commits cancelled due to an older store, that the thread was waiting on to become globally visible, was unable to become globally visible.", + "UMask": "0x01" + }, + { + "EventName": "ls_mab_alloc.ls", + "EventCode": "0x41", + "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for load-store allocations.", + "UMask": "0x07" + }, + { + "EventName": "ls_mab_alloc.hwpf", + "EventCode": "0x41", + "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for hardware prefetcher allocations.", + "UMask": "0x08" + }, + { + "EventName": "ls_mab_alloc.all", + "EventCode": "0x41", + "BriefDescription": "Miss Address Buffer (MAB) entries allocated by a Load-Store (LS) pipe for all types of allocations.", + "UMask": "0x0f" + }, + { + "EventName": "ls_dmnd_fills_from_sys.local_l2", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from local L2 cache.", + "UMask": "0x01" + }, + { + "EventName": "ls_dmnd_fills_from_sys.local_ccx", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "ls_dmnd_fills_from_sys.local_all", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from local L2 cache, L3 cache or different L2 cache in the same CCX.", + "UMask": "0x03" + }, + { + "EventName": "ls_dmnd_fills_from_sys.near_cache", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "ls_dmnd_fills_from_sys.dram_io_near", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "ls_dmnd_fills_from_sys.far_cache", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "ls_dmnd_fills_from_sys.remote_cache", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from cache of another CCX in the same or a different NUMA node.", + "UMask": "0x14" + }, + { + "EventName": "ls_dmnd_fills_from_sys.dram_io_far", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "ls_dmnd_fills_from_sys.dram_io_all", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "ls_dmnd_fills_from_sys.far_all", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from either cache of another CCX, DRAM or MMIO in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "ls_dmnd_fills_from_sys.alt_mem", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "ls_dmnd_fills_from_sys.all", + "EventCode": "0x43", + "BriefDescription": "Demand data cache fills where data is returned from all types of sources.", + "UMask": "0xdf" + }, + { + "EventName": "ls_any_fills_from_sys.local_l2", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from local L2 cache.", + "UMask": "0x01" + }, + { + "EventName": "ls_any_fills_from_sys.local_ccx", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "ls_any_fills_from_sys.local_all", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from local L2 cache, L3 cache or different L2 cache in the same CCX.", + "UMask": "0x03" + }, + { + "EventName": "ls_any_fills_from_sys.near_cache", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "ls_any_fills_from_sys.dram_io_near", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "ls_any_fills_from_sys.far_cache", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "ls_any_fills_from_sys.remote_cache", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from cache of another CCX in the same or a different NUMA node.", + "UMask": "0x14" + }, + { + "EventName": "ls_any_fills_from_sys.dram_io_far", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "ls_any_fills_from_sys.dram_io_all", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "ls_any_fills_from_sys.far_all", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from either cache of another CCX, DRAM or MMIO when the address was in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "ls_any_fills_from_sys.alt_mem", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "ls_any_fills_from_sys.all", + "EventCode": "0x44", + "BriefDescription": "Any data cache fills where data is returned from all types of data sources.", + "UMask": "0xff" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_4k_l2_hit", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB hits for 4k pages.", + "UMask": "0x01" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_hit", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB hits for coalesced pages (16k pages created from four adjacent 4k pages).", + "UMask": "0x02" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_2m_l2_hit", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB hits for 2M pages.", + "UMask": "0x04" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_1g_l2_hit", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB hits for 1G pages.", + "UMask": "0x08" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_4k_l2_miss", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB misses (page-table walks requested) for 4k pages.", + "UMask": "0x10" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_coalesced_page_miss", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB misses (page-table walks requested) for coalesced pages (16k pages created from four adjacent 4k pages).", + "UMask": "0x20" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_2m_l2_miss", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB misses (page-table walks requested) for 2M pages.", + "UMask": "0x40" + }, + { + "EventName": "ls_l1_d_tlb_miss.tlb_reload_1g_l2_miss", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB misses (page-table walks requested) for 1G pages.", + "UMask": "0x80" + }, + { + "EventName": "ls_l1_d_tlb_miss.l2_miss_all", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses with L2 DTLB misses (page-table walks requested) for all page sizes.", + "UMask": "0xf0" + }, + { + "EventName": "ls_l1_d_tlb_miss.all", + "EventCode": "0x45", + "BriefDescription": "L1 DTLB misses for all page sizes.", + "UMask": "0xff" + }, + { + "EventName": "ls_misal_loads.ma64", + "EventCode": "0x47", + "BriefDescription": "64B misaligned (cacheline crossing) loads.", + "UMask": "0x01" + }, + { + "EventName": "ls_misal_loads.ma4k", + "EventCode": "0x47", + "BriefDescription": "4kB misaligned (page crossing) loads.", + "UMask": "0x02" + }, + { + "EventName": "ls_pref_instr_disp.prefetch", + "EventCode": "0x4b", + "BriefDescription": "Software prefetch instructions dispatched (speculative) of type PrefetchT0 (move data to all cache levels), T1 (move data to all cache levels except L1) and T2 (move data to all cache levels except L1 and L2).", + "UMask": "0x01" + }, + { + "EventName": "ls_pref_instr_disp.prefetch_w", + "EventCode": "0x4b", + "BriefDescription": "Software prefetch instructions dispatched (speculative) of type PrefetchW (move data to L1 cache and mark it modifiable).", + "UMask": "0x02" + }, + { + "EventName": "ls_pref_instr_disp.prefetch_nta", + "EventCode": "0x4b", + "BriefDescription": "Software prefetch instructions dispatched (speculative) of type PrefetchNTA (move data with minimum cache pollution i.e. non-temporal access).", + "UMask": "0x04" + }, + { + "EventName": "ls_pref_instr_disp.all", + "EventCode": "0x4b", + "BriefDescription": "Software prefetch instructions dispatched (speculative) of all types.", + "UMask": "0x07" + }, + { + "EventName": "wcb_close.full_line_64b", + "EventCode": "0x50", + "BriefDescription": "Events that caused a Write Combining Buffer (WCB) entry to close because all 64 bytes of the entry have been written to.", + "UMask": "0x01" + }, + { + "EventName": "ls_inef_sw_pref.dc_hit", + "EventCode": "0x52", + "BriefDescription": "Software prefetches that did not fetch data outside of the processor core as the PREFETCH instruction saw a data cache hit.", + "UMask": "0x01" + }, + { + "EventName": "ls_inef_sw_pref.mab_hit", + "EventCode": "0x52", + "BriefDescription": "Software prefetches that did not fetch data outside of the processor core as the PREFETCH instruction saw a match on an already allocated miss request (MAB).", + "UMask": "0x02" + }, + { + "EventName": "ls_inef_sw_pref.all", + "EventCode": "0x52", + "BriefDescript6ion": "Software prefetches that did not fetch data outside of the processor core for any reason.", + "UMask": "0x03" + }, + { + "EventName": "ls_sw_pf_dc_fills.local_l2", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from local L2 cache.", + "UMask": "0x01" + }, + { + "EventName": "ls_sw_pf_dc_fills.local_ccx", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "ls_sw_pf_dc_fills.local_all", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from local L2 cache, L3 cache or different L2 cache in the same CCX.", + "UMask": "0x03" + }, + { + "EventName": "ls_sw_pf_dc_fills.near_cache", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "ls_sw_pf_dc_fills.dram_io_near", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "ls_sw_pf_dc_fills.far_cache", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "ls_sw_pf_dc_fills.remote_cache", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from cache of another CCX in the same or a different NUMA node.", + "UMask": "0x14" + }, + { + "EventName": "ls_sw_pf_dc_fills.dram_io_far", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "ls_sw_pf_dc_fills.dram_io_all", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "ls_sw_pf_dc_fills.far_all", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from either cache of another CCX, DRAM or MMIO in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "ls_sw_pf_dc_fills.alt_mem", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "ls_sw_pf_dc_fills.all", + "EventCode": "0x59", + "BriefDescription": "Software prefetch data cache fills where data is returned from all types of data sources.", + "UMask": "0xdf" + }, + { + "EventName": "ls_hw_pf_dc_fills.local_l2", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from local L2 cache.", + "UMask": "0x01" + }, + { + "EventName": "ls_hw_pf_dc_fills.local_ccx", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from L3 cache or different L2 cache in the same CCX.", + "UMask": "0x02" + }, + { + "EventName": "ls_hw_pf_dc_fills.local_all", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from local L2 cache, L3 cache or different L2 cache in the same CCX.", + "UMask": "0x03" + }, + { + "EventName": "ls_hw_pf_dc_fills.near_cache", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from cache of another CCX in the same NUMA node.", + "UMask": "0x04" + }, + { + "EventName": "ls_hw_pf_dc_fills.dram_io_near", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from either DRAM or MMIO in the same NUMA node.", + "UMask": "0x08" + }, + { + "EventName": "ls_hw_pf_dc_fills.far_cache", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from cache of another CCX in a different NUMA node.", + "UMask": "0x10" + }, + { + "EventName": "ls_hw_pf_dc_fills.remote_cache", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from cache of another CCX in the same or a different NUMA node.", + "UMask": "0x14" + }, + { + "EventName": "ls_hw_pf_dc_fills.dram_io_far", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from either DRAM or MMIO in a different NUMA node.", + "UMask": "0x40" + }, + { + "EventName": "ls_hw_pf_dc_fills.dram_io_all", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from either DRAM or MMIO in the same or a different NUMA node.", + "UMask": "0x48" + }, + { + "EventName": "ls_hw_pf_dc_fills.far_all", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from either cache of another CCX, DRAM or MMIO in a different NUMA node.", + "UMask": "0x50" + }, + { + "EventName": "ls_hw_pf_dc_fills.alt_mem", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from extension memory (CXL).", + "UMask": "0x80" + }, + { + "EventName": "ls_hw_pf_dc_fills.all", + "EventCode": "0x5a", + "BriefDescription": "Hardware prefetch data cache fills where data is returned from all types of data sources.", + "UMask": "0xdf" + }, + { + "EventName": "ls_alloc_mab_count", + "EventCode": "0x5f", + "BriefDescription": "In-flight L1 data cache misses i.e. Miss Address Buffer (MAB) allocations each cycle." + }, + { + "EventName": "ls_not_halted_cyc", + "EventCode": "0x76", + "BriefDescription": "Core cycles where the thread is not in halted state." + }, + { + "EventName": "ls_tlb_flush.all", + "EventCode": "0x78", + "BriefDescription": "All TLB flushes.", + "UMask": "0xff" + }, + { + "EventName": "ls_not_halted_p0_cyc.p0_freq_cyc", + "EventCode": "0x120", + "BriefDescription": "Reference cycles (P0 frequency) where the thread is not in halted state.", + "UMask": "0x1" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/memory-controller.json b/tools/perf/pmu-events/arch/x86/amdzen6/memory-controller.json new file mode 100644 index 000000000000..649a60b09e1b --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/memory-controller.json @@ -0,0 +1,101 @@ +[ + { + "EventName": "umc_mem_clk", + "PublicDescription": "Memory clock (MEMCLK) cycles.", + "EventCode": "0x00", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_act_cmd.all", + "PublicDescription": "ACTIVATE commands sent.", + "EventCode": "0x05", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_act_cmd.rd", + "PublicDescription": "ACTIVATE commands sent for reads.", + "EventCode": "0x05", + "RdWrMask": "0x1", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_act_cmd.wr", + "PublicDescription": "ACTIVATE commands sent for writes.", + "EventCode": "0x05", + "RdWrMask": "0x2", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_pchg_cmd.all", + "PublicDescription": "PRECHARGE commands sent.", + "EventCode": "0x06", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_pchg_cmd.rd", + "PublicDescription": "PRECHARGE commands sent for reads.", + "EventCode": "0x06", + "RdWrMask": "0x1", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_pchg_cmd.wr", + "PublicDescription": "PRECHARGE commands sent for writes.", + "EventCode": "0x06", + "RdWrMask": "0x2", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_cas_cmd.all", + "PublicDescription": "CAS commands sent.", + "EventCode": "0x0a", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_cas_cmd.rd", + "PublicDescription": "CAS commands sent for reads.", + "EventCode": "0x0a", + "RdWrMask": "0x1", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_cas_cmd.wr", + "PublicDescription": "CAS commands sent for writes.", + "EventCode": "0x0a", + "RdWrMask": "0x2", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_data_slot_clks.all", + "PublicDescription": "Clock cycles where the data bus is utilized.", + "EventCode": "0x14", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_data_slot_clks.rd", + "PublicDescription": "Clock cycles where the data bus is utilized for reads.", + "EventCode": "0x14", + "RdWrMask": "0x1", + "PerPkg": "1", + "Unit": "UMCPMC" + }, + { + "EventName": "umc_data_slot_clks.wr", + "PublicDescription": "Clock cycles where the data bus is utilized for writes.", + "EventCode": "0x14", + "RdWrMask": "0x2", + "PerPkg": "1", + "Unit": "UMCPMC" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/pipeline.json b/tools/perf/pmu-events/arch/x86/amdzen6/pipeline.json new file mode 100644 index 000000000000..48c501d8a097 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/pipeline.json @@ -0,0 +1,99 @@ +[ + { + "MetricName": "total_dispatch_slots", + "BriefDescription": "Total dispatch slots (up to 8 instructions can be dispatched in each cycle).", + "MetricExpr": "8 * ls_not_halted_cyc", + "ScaleUnit": "1slots" + }, + { + "MetricName": "frontend_bound", + "BriefDescription": "Percentage of dispatch slots that remained unused because the frontend did not supply enough instructions/ops.", + "MetricExpr": "d_ratio(de_no_dispatch_per_slot.no_ops_from_frontend, total_dispatch_slots)", + "MetricGroup": "PipelineL1", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "bad_speculation", + "BriefDescription": "Percentage of dispatched ops that did not retire.", + "MetricExpr": "d_ratio(de_src_op_disp.all - ex_ret_ops, total_dispatch_slots)", + "MetricGroup": "PipelineL1", + "ScaleUnit": "100%ops" + }, + { + "MetricName": "backend_bound", + "BriefDescription": "Percentage of dispatch slots that remained unused because of backend stalls.", + "MetricExpr": "d_ratio(de_no_dispatch_per_slot.backend_stalls, total_dispatch_slots)", + "MetricGroup": "PipelineL1", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "smt_contention", + "BriefDescription": "Percentage of dispatch slots that remained unused because the other thread was selected.", + "MetricExpr": "d_ratio(de_no_dispatch_per_slot.smt_contention, total_dispatch_slots)", + "MetricGroup": "PipelineL1", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "retiring", + "BriefDescription": "Percentage of dispatch slots used by ops that retired.", + "MetricExpr": "d_ratio(ex_ret_ops, total_dispatch_slots)", + "MetricGroup": "PipelineL1", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "frontend_bound_by_latency", + "BriefDescription": "Percentage of dispatch slots that remained unused because of a latency bottleneck in the frontend (such as instruction cache or TLB misses).", + "MetricExpr": "d_ratio((8 * cpu@de_no_dispatch_per_slot.no_ops_from_frontend\\,cmask\\=0x8@), total_dispatch_slots)", + "MetricGroup": "PipelineL2;frontend_bound_group", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "frontend_bound_by_bandwidth", + "BriefDescription": "Percentage of dispatch slots that remained unused because of a bandwidth bottleneck in the frontend (such as decode or op cache fetch bandwidth).", + "MetricExpr": "d_ratio(de_no_dispatch_per_slot.no_ops_from_frontend - (8 * cpu@de_no_dispatch_per_slot.no_ops_from_frontend\\,cmask\\=0x8@), total_dispatch_slots)", + "MetricGroup": "PipelineL2;frontend_bound_group", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "bad_speculation_from_mispredicts", + "BriefDescription": "Percentage of dispatched ops that were flushed due to branch mispredicts.", + "MetricExpr": "d_ratio(bad_speculation * ex_ret_brn_misp, ex_ret_brn_misp + bp_fe_redir.resync)", + "MetricGroup": "PipelineL2;bad_speculation_group", + "ScaleUnit": "100%ops" + }, + { + "MetricName": "bad_speculation_from_pipeline_restarts", + "BriefDescription": "Percentage of dispatched ops that were flushed due to pipeline restarts (resyncs).", + "MetricExpr": "d_ratio(bad_speculation * bp_fe_redir.resync, ex_ret_brn_misp + bp_fe_redir.resync)", + "MetricGroup": "PipelineL2;bad_speculation_group", + "ScaleUnit": "100%ops" + }, + { + "MetricName": "backend_bound_by_memory", + "BriefDescription": "Percentage of dispatch slots that remained unused because of stalls due to the memory subsystem.", + "MetricExpr": "backend_bound * d_ratio(ex_no_retire.load_not_complete, ex_no_retire.not_complete)", + "MetricGroup": "PipelineL2;backend_bound_group", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "backend_bound_by_cpu", + "BriefDescription": "Percentage of dispatch slots that remained unused because of stalls not related to the memory subsystem.", + "MetricExpr": "backend_bound * (1 - d_ratio(ex_no_retire.load_not_complete, ex_no_retire.not_complete))", + "MetricGroup": "PipelineL2;backend_bound_group", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "retiring_from_fastpath", + "BriefDescription": "Percentage of dispatch slots used by fastpath ops that retired.", + "MetricExpr": "retiring * (1 - d_ratio(ex_ret_ucode_ops, ex_ret_ops))", + "MetricGroup": "PipelineL2;retiring_group", + "ScaleUnit": "100%slots" + }, + { + "MetricName": "retiring_from_microcode", + "BriefDescription": "Percentage of dispatch slots used by microcode ops that retired.", + "MetricExpr": "retiring * d_ratio(ex_ret_ucode_ops, ex_ret_ops)", + "MetricGroup": "PipelineL2;retiring_group", + "ScaleUnit": "100%slots" + } +] diff --git a/tools/perf/pmu-events/arch/x86/amdzen6/recommended.json b/tools/perf/pmu-events/arch/x86/amdzen6/recommended.json new file mode 100644 index 000000000000..2849a8c159f6 --- /dev/null +++ b/tools/perf/pmu-events/arch/x86/amdzen6/recommended.json @@ -0,0 +1,339 @@ +[ + { + "MetricName": "branch_misprediction_rate", + "BriefDescription": "Execution-time branch misprediction rate (non-speculative).", + "MetricExpr": "d_ratio(ex_ret_brn_misp, ex_ret_brn)", + "MetricGroup": "branch_prediction", + "ScaleUnit": "1per_branch" + }, + { + "MetricName": "all_data_cache_accesses_pti", + "BriefDescription": "All data cache accesses per thousand instructions.", + "MetricExpr": "ls_dispatch.all / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "all_l2_cache_accesses_pti", + "BriefDescription": "All L2 cache accesses per thousand instructions.", + "MetricExpr": "(l2_request_g1.no_pf_all + l2_pf_hit_l2.l2_hwpf + l2_pf_miss_l2_hit_l3.l2_hwpf + l2_pf_miss_l2_l3.l2_hwpf) / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_accesses_from_l1_ic_misses_pti", + "BriefDescription": "L2 cache accesses from L1 instruction cache misses (including prefetch) per thousand instructions.", + "MetricExpr": "l2_request_g1.cacheable_ic_read / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_accesses_from_l1_dc_misses_pti", + "BriefDescription": "L2 cache accesses from L1 data cache misses (including prefetch) per thousand instructions.", + "MetricExpr": "l2_request_g1.dc_all / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_accesses_from_l2_hwpf_pti", + "BriefDescription": "L2 cache accesses from L2 cache hardware prefetcher per thousand instructions.", + "MetricExpr": "(l2_pf_hit_l2.l1_dc_l2_hwpf + l2_pf_miss_l2_hit_l3.l1_dc_l2_hwpf + l2_pf_miss_l2_l3.l1_dc_l2_hwpf) / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "all_l2_cache_misses_pti", + "BriefDescription": "All L2 cache misses per thousand instructions.", + "MetricExpr": "(l2_cache_req_stat.ic_dc_miss_in_l2 + l2_pf_miss_l2_hit_l3.l2_hwpf + l2_pf_miss_l2_l3.l2_hwpf) / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_misses_from_l1_ic_miss_pti", + "BriefDescription": "L2 cache misses from L1 instruction cache misses per thousand instructions.", + "MetricExpr": "l2_cache_req_stat.ic_fill_miss / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_misses_from_l1_dc_miss_pti", + "BriefDescription": "L2 cache misses from L1 data cache misses per thousand instructions.", + "MetricExpr": "l2_cache_req_stat.ls_rd_blk_c / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_misses_from_l2_hwpf_pti", + "BriefDescription": "L2 cache misses from L2 cache hardware prefetcher per thousand instructions.", + "MetricExpr": "(l2_pf_miss_l2_hit_l3.l1_dc_l2_hwpf + l2_pf_miss_l2_l3.l1_dc_l2_hwpf) / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "all_l2_cache_hits_pti", + "BriefDescription": "All L2 cache hits per thousand instructions.", + "MetricExpr": "(l2_cache_req_stat.ic_dc_hit_in_l2 + l2_pf_hit_l2.l2_hwpf) / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_hits_from_l1_ic_miss_pti", + "BriefDescription": "L2 cache hits from L1 instruction cache misses per thousand instructions.", + "MetricExpr": "l2_cache_req_stat.ic_hit_in_l2 / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_hits_from_l1_dc_miss_pti", + "BriefDescription": "L2 cache hits from L1 data cache misses per thousand instructions.", + "MetricExpr": "l2_cache_req_stat.dc_hit_in_l2 / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_cache_hits_from_l2_hwpf_pti", + "BriefDescription": "L2 cache hits from L2 cache hardware prefetcher per thousand instructions.", + "MetricExpr": "l2_pf_hit_l2.l1_dc_l2_hwpf / instructions", + "MetricGroup": "l2_cache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l3_cache_accesses", + "BriefDescription": "L3 cache accesses.", + "MetricExpr": "l3_lookup_state.all_coherent_accesses_to_l3", + "MetricGroup": "l3_cache" + }, + { + "MetricName": "l3_misses", + "BriefDescription": "L3 misses (including cacheline state change requests).", + "MetricExpr": "l3_lookup_state.l3_miss", + "MetricGroup": "l3_cache" + }, + { + "MetricName": "l3_read_miss_latency", + "BriefDescription": "Average L3 read miss latency (in core clocks).", + "MetricExpr": "(l3_xi_sampled_latency.all * 10) / l3_xi_sampled_latency_requests.all", + "MetricGroup": "l3_cache", + "ScaleUnit": "1ns" + }, + { + "MetricName": "l3_read_miss_latency_for_local_dram", + "BriefDescription": "Average L3 read miss latency (in core clocks) for local DRAM.", + "MetricExpr": "(l3_xi_sampled_latency.dram_near * 10) / l3_xi_sampled_latency_requests.dram_near", + "MetricGroup": "l3_cache", + "ScaleUnit": "1ns" + }, + { + "MetricName": "l3_read_miss_latency_for_remote_dram", + "BriefDescription": "Average L3 read miss latency (in core clocks) for remote DRAM.", + "MetricExpr": "(l3_xi_sampled_latency.dram_far * 10) / l3_xi_sampled_latency_requests.dram_far", + "MetricGroup": "l3_cache", + "ScaleUnit": "1ns" + }, + { + "MetricName": "op_cache_fetch_miss_ratio", + "BriefDescription": "Op cache miss ratio for all fetches.", + "MetricExpr": "d_ratio(op_cache_hit_miss.miss, op_cache_hit_miss.all)", + "ScaleUnit": "100%" + }, + { + "MetricName": "l1_data_cache_fills_from_memory_pti", + "BriefDescription": "L1 data cache fills from DRAM or MMIO in any NUMA node per thousand instructions.", + "MetricExpr": "ls_any_fills_from_sys.dram_io_all / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_data_cache_fills_from_remote_node_pti", + "BriefDescription": "L1 data cache fills from a different NUMA node per thousand instructions.", + "MetricExpr": "ls_any_fills_from_sys.far_all / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_data_cache_fills_from_same_ccx_pti", + "BriefDescription": "L1 data cache fills from within the same CCX per thousand instructions.", + "MetricExpr": "ls_any_fills_from_sys.local_all / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_data_cache_fills_from_different_ccx_pti", + "BriefDescription": "L1 data cache fills from another CCX cache in any NUMA node per thousand instructions.", + "MetricExpr": "ls_any_fills_from_sys.remote_cache / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "all_l1_data_cache_fills_pti", + "BriefDescription": "All L1 data cache fills per thousand instructions.", + "MetricExpr": "ls_any_fills_from_sys.all / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_local_l2_pti", + "BriefDescription": "L1 demand data cache fills from local L2 cache per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.local_l2 / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_same_ccx_pti", + "BriefDescription": "L1 demand data cache fills from within the same CCX per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.local_ccx / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_near_cache_pti", + "BriefDescription": "L1 demand data cache fills from another CCX cache in the same NUMA node per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.near_cache / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_near_memory_pti", + "BriefDescription": "L1 demand data cache fills from DRAM or MMIO in the same NUMA node per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.dram_io_near / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_far_cache_pti", + "BriefDescription": "L1 demand data cache fills from another CCX cache in a different NUMA node per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.far_cache / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_demand_data_cache_fills_from_far_memory_pti", + "BriefDescription": "L1 demand data cache fills from DRAM or MMIO in a different NUMA node per thousand instructions.", + "MetricExpr": "ls_dmnd_fills_from_sys.dram_io_far / instructions", + "MetricGroup": "l1_dcache", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_itlb_misses_pti", + "BriefDescription": "L1 instruction TLB misses per thousand instructions.", + "MetricExpr": "(bp_l1_tlb_miss_l2_tlb_hit + bp_l1_tlb_miss_l2_tlb_miss.all) / instructions", + "MetricGroup": "tlb", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_itlb_misses_pti", + "BriefDescription": "L2 instruction TLB misses and instruction page walks per thousand instructions.", + "MetricExpr": "bp_l1_tlb_miss_l2_tlb_miss.all / instructions", + "MetricGroup": "tlb", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l1_dtlb_misses_pti", + "BriefDescription": "L1 data TLB misses per thousand instructions.", + "MetricExpr": "ls_l1_d_tlb_miss.all / instructions", + "MetricGroup": "tlb", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "l2_dtlb_misses_pti", + "BriefDescription": "L2 data TLB misses and data page walks per thousand instructions.", + "MetricExpr": "ls_l1_d_tlb_miss.l2_miss_all / instructions", + "MetricGroup": "tlb", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "all_tlbs_flushed_pti", + "BriefDescription": "All TLBs flushed per thousand instructions.", + "MetricExpr": "ls_tlb_flush.all / instructions", + "MetricGroup": "tlb", + "ScaleUnit": "1e3per_1k_instr" + }, + { + "MetricName": "macro_ops_dispatched", + "BriefDescription": "Macro-ops dispatched.", + "MetricExpr": "de_src_op_disp.all", + "MetricGroup": "decoder" + }, + { + "MetricName": "sse_avx_stalls", + "BriefDescription": "Mixed SSE/AVX stalls.", + "MetricExpr": "fp_disp_faults.sse_avx_all" + }, + { + "MetricName": "macro_ops_retired", + "BriefDescription": "Macro-ops retired.", + "MetricExpr": "ex_ret_ops" + }, + { + "MetricName": "umc_data_bus_utilization", + "BriefDescription": "Memory controller data bus utilization.", + "MetricExpr": "d_ratio(umc_data_slot_clks.all / 2, umc_mem_clk)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "100%" + }, + { + "MetricName": "umc_cas_cmd_rate", + "BriefDescription": "Memory controller CAS command rate.", + "MetricExpr": "d_ratio(umc_cas_cmd.all * 1000, umc_mem_clk)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1per_memclk" + }, + { + "MetricName": "umc_cas_cmd_read_ratio", + "BriefDescription": "Ratio of memory controller CAS commands for reads.", + "MetricExpr": "d_ratio(umc_cas_cmd.rd, umc_cas_cmd.all)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "100%" + }, + { + "MetricName": "umc_cas_cmd_write_ratio", + "BriefDescription": "Ratio of memory controller CAS commands for writes.", + "MetricExpr": "d_ratio(umc_cas_cmd.wr, umc_cas_cmd.all)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "100%" + }, + { + "MetricName": "umc_mem_read_bandwidth", + "BriefDescription": "Estimated memory read bandwidth.", + "MetricExpr": "(umc_cas_cmd.rd * 64) / 1e6 / duration_time", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1MB/s" + }, + { + "MetricName": "umc_mem_write_bandwidth", + "BriefDescription": "Estimated memory write bandwidth.", + "MetricExpr": "(umc_cas_cmd.wr * 64) / 1e6 / duration_time", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1MB/s" + }, + { + "MetricName": "umc_mem_bandwidth", + "BriefDescription": "Estimated combined memory bandwidth.", + "MetricExpr": "(umc_cas_cmd.all * 64) / 1e6 / duration_time", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1MB/s" + }, + { + "MetricName": "umc_activate_cmd_rate", + "BriefDescription": "Memory controller ACTIVATE command rate.", + "MetricExpr": "d_ratio(umc_act_cmd.all * 1000, umc_mem_clk)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1per_memclk" + }, + { + "MetricName": "umc_precharge_cmd_rate", + "BriefDescription": "Memory controller PRECHARGE command rate.", + "MetricExpr": "d_ratio(umc_pchg_cmd.all * 1000, umc_mem_clk)", + "MetricGroup": "memory_controller", + "PerPkg": "1", + "ScaleUnit": "1per_memclk" + } +] diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv index 3d0c57198056..149bbe7abaf5 100644 --- a/tools/perf/pmu-events/arch/x86/mapfile.csv +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv @@ -43,4 +43,5 @@ AuthenticAMD-23-([12][0-9A-F]|[0-9A-F]),v2,amdzen1,core AuthenticAMD-23-[[:xdigit:]]+,v1,amdzen2,core AuthenticAMD-25-([245][[:xdigit:]]|[[:xdigit:]]),v1,amdzen3,core AuthenticAMD-25-[[:xdigit:]]+,v1,amdzen4,core -AuthenticAMD-26-[[:xdigit:]]+,v1,amdzen5,core +AuthenticAMD-26-([12467][[:xdigit:]]|[[:xdigit:]]),v1,amdzen5,core +AuthenticAMD-26-[[:xdigit:]]+,v1,amdzen6,core diff --git a/tools/perf/pmu-events/arm64_metrics.py b/tools/perf/pmu-events/arm64_metrics.py new file mode 100755 index 000000000000..4ecda96d11fa --- /dev/null +++ b/tools/perf/pmu-events/arm64_metrics.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +import argparse +import os +from metric import (JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, LoadEvents, + MetricGroup) +from common_metrics import Cycles + +# Global command line arguments. +_args = None + + +def main() -> None: + global _args + + def dir_path(path: str) -> str: + """Validate path is a directory for argparse.""" + if os.path.isdir(path): + return path + raise argparse.ArgumentTypeError( + f'\'{path}\' is not a valid directory') + + parser = argparse.ArgumentParser(description="ARM perf json generator") + parser.add_argument( + "-metricgroups", help="Generate metricgroups data", action='store_true') + parser.add_argument("vendor", help="e.g. arm") + parser.add_argument("model", help="e.g. neoverse-n1") + parser.add_argument( + 'events_path', + type=dir_path, + help='Root of tree containing architecture directories containing json files' + ) + _args = parser.parse_args() + + directory = f"{_args.events_path}/arm64/{_args.vendor}/{_args.model}/" + LoadEvents(directory) + + all_metrics = MetricGroup("", [ + Cycles(), + ]) + + if _args.metricgroups: + print(JsonEncodeMetricGroupDescriptions(all_metrics)) + else: + print(JsonEncodeMetric(all_metrics)) + + +if __name__ == '__main__': + main() diff --git a/tools/perf/pmu-events/common_metrics.py b/tools/perf/pmu-events/common_metrics.py new file mode 100644 index 000000000000..fcdfb9d3e648 --- /dev/null +++ b/tools/perf/pmu-events/common_metrics.py @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +from metric import (d_ratio, Event, Metric, MetricGroup) + + +def Cycles() -> MetricGroup: + cyc_k = Event("cpu\\-cycles:kHh") # exclude user and guest + cyc_g = Event("cpu\\-cycles:G") # exclude host + cyc_u = Event("cpu\\-cycles:uH") # exclude kernel, hypervisor and guest + cyc = cyc_k + cyc_g + cyc_u + + return MetricGroup("lpm_cycles", [ + Metric("lpm_cycles_total", "Total number of cycles", cyc, "cycles"), + Metric("lpm_cycles_user", "User cycles as a percentage of all cycles", + d_ratio(cyc_u, cyc), "100%"), + Metric("lpm_cycles_kernel", "Kernel cycles as a percentage of all cycles", + d_ratio(cyc_k, cyc), "100%"), + Metric("lpm_cycles_guest", "Hypervisor guest cycles as a percentage of all cycles", + d_ratio(cyc_g, cyc), "100%"), + ], description="cycles breakdown per privilege level (users, kernel, guest)") diff --git a/tools/perf/pmu-events/intel_metrics.py b/tools/perf/pmu-events/intel_metrics.py new file mode 100755 index 000000000000..52035433b505 --- /dev/null +++ b/tools/perf/pmu-events/intel_metrics.py @@ -0,0 +1,1129 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) +import argparse +import json +import math +import os +import re +from typing import Optional +from common_metrics import Cycles +from metric import (d_ratio, has_event, max, source_count, CheckPmu, Event, + JsonEncodeMetric, JsonEncodeMetricGroupDescriptions, + Literal, LoadEvents, Metric, MetricConstraint, MetricGroup, + MetricRef, Select) + +# Global command line arguments. +_args = None +interval_sec = Event("duration_time") + + +def Idle() -> Metric: + cyc = Event("msr/mperf/") + tsc = Event("msr/tsc/") + low = max(tsc - cyc, 0) + return Metric( + "lpm_idle", + "Percentage of total wallclock cycles where CPUs are in low power state (C1 or deeper sleep state)", + d_ratio(low, tsc), "100%") + + +def Rapl() -> MetricGroup: + """Processor power consumption estimate. + + Use events from the running average power limit (RAPL) driver. + """ + # Watts = joules/second + pkg = Event("power/energy\\-pkg/") + cond_pkg = Select(pkg, has_event(pkg), math.nan) + cores = Event("power/energy\\-cores/") + cond_cores = Select(cores, has_event(cores), math.nan) + ram = Event("power/energy\\-ram/") + cond_ram = Select(ram, has_event(ram), math.nan) + gpu = Event("power/energy\\-gpu/") + cond_gpu = Select(gpu, has_event(gpu), math.nan) + psys = Event("power/energy\\-psys/") + cond_psys = Select(psys, has_event(psys), math.nan) + scale = 2.3283064365386962890625e-10 + metrics = [ + Metric("lpm_cpu_power_pkg", "", + d_ratio(cond_pkg * scale, interval_sec), "Watts"), + Metric("lpm_cpu_power_cores", "", + d_ratio(cond_cores * scale, interval_sec), "Watts"), + Metric("lpm_cpu_power_ram", "", + d_ratio(cond_ram * scale, interval_sec), "Watts"), + Metric("lpm_cpu_power_gpu", "", + d_ratio(cond_gpu * scale, interval_sec), "Watts"), + Metric("lpm_cpu_power_psys", "", + d_ratio(cond_psys * scale, interval_sec), "Watts"), + ] + + return MetricGroup("lpm_cpu_power", metrics, + description="Running Average Power Limit (RAPL) power consumption estimates") + + +def Smi() -> MetricGroup: + pmu = "" if CheckPmu("cpu_core") else "cpu" + aperf = Event('msr/aperf/') + cycles = Event('cycles') + smi_num = Event('msr/smi/') + smi_cycles = Select(Select((aperf - cycles) / aperf, smi_num > 0, 0), + has_event(aperf), + 0) + return MetricGroup('smi', [ + Metric('smi_num', 'Number of SMI interrupts.', + Select(smi_num, has_event(smi_num), 0), 'SMI#'), + # Note, the smi_cycles "Event" is really a reference to the metric. + Metric('smi_cycles', + 'Percentage of cycles spent in System Management Interrupts. ' + f'Requires /sys/bus/event_source/devices/{pmu}/freeze_on_smi to be 1.', + smi_cycles, '100%', threshold=(MetricRef('smi_cycles') > 0.10)) + ], description='System Management Interrupt metrics') + + +def Tsx() -> Optional[MetricGroup]: + pmu = "cpu_core" if CheckPmu("cpu_core") else "cpu" + cycles = Event('cycles') + cycles_in_tx = Event(f'{pmu}/cycles\\-t/') + cycles_in_tx_cp = Event(f'{pmu}/cycles\\-ct/') + try: + # Test if the tsx event is present in the json, prefer the + # sysfs version so that we can detect its presence at runtime. + transaction_start = Event("RTM_RETIRED.START") + transaction_start = Event(f'{pmu}/tx\\-start/') + except: + return None + + elision_start = None + try: + # Elision start isn't supported by all models, but we'll not + # generate the tsx_cycles_per_elision metric in that + # case. Again, prefer the sysfs encoding of the event. + elision_start = Event("HLE_RETIRED.START") + elision_start = Event(f'{pmu}/el\\-start/') + except: + pass + + return MetricGroup('transaction', [ + Metric('tsx_transactional_cycles', + 'Percentage of cycles within a transaction region.', + Select(cycles_in_tx / cycles, has_event(cycles_in_tx), 0), + '100%'), + Metric('tsx_aborted_cycles', 'Percentage of cycles in aborted transactions.', + Select(max(cycles_in_tx - cycles_in_tx_cp, 0) / cycles, + has_event(cycles_in_tx), + 0), + '100%'), + Metric('tsx_cycles_per_transaction', + 'Number of cycles within a transaction divided by the number of transactions.', + Select(cycles_in_tx / transaction_start, + has_event(cycles_in_tx), + 0), + "cycles / transaction"), + Metric('tsx_cycles_per_elision', + 'Number of cycles within a transaction divided by the number of elisions.', + Select(cycles_in_tx / elision_start, + has_event(elision_start), + 0), + "cycles / elision") if elision_start else None, + ], description="Breakdown of transactional memory statistics") + + +def IntelBr(): + ins = Event("instructions") + + def Total() -> MetricGroup: + br_all = Event("BR_INST_RETIRED.ALL_BRANCHES", "BR_INST_RETIRED.ANY") + br_m_all = Event("BR_MISP_RETIRED.ALL_BRANCHES", + "BR_INST_RETIRED.MISPRED", + "BR_MISP_EXEC.ANY") + br_clr = None + try: + br_clr = Event("BACLEARS.ANY", "BACLEARS.ALL") + except: + pass + + br_r = d_ratio(br_all, interval_sec) + ins_r = d_ratio(ins, br_all) + misp_r = d_ratio(br_m_all, br_all) + clr_r = d_ratio(br_clr, interval_sec) if br_clr else None + + return MetricGroup("lpm_br_total", [ + Metric("lpm_br_total_retired", + "The number of branch instructions retired per second.", br_r, + "insn/s"), + Metric( + "lpm_br_total_mispred", + "The number of branch instructions retired, of any type, that were " + "not correctly predicted as a percentage of all branch instrucions.", + misp_r, "100%"), + Metric("lpm_br_total_insn_between_branches", + "The number of instructions divided by the number of branches.", + ins_r, "insn"), + Metric("lpm_br_total_insn_fe_resteers", + "The number of resync branches per second.", clr_r, "req/s" + ) if clr_r else None + ]) + + def Taken() -> MetricGroup: + br_all = Event("BR_INST_RETIRED.ALL_BRANCHES", "BR_INST_RETIRED.ANY") + br_m_tk = None + try: + br_m_tk = Event("BR_MISP_RETIRED.NEAR_TAKEN", + "BR_MISP_RETIRED.TAKEN_JCC", + "BR_INST_RETIRED.MISPRED_TAKEN") + except: + pass + br_r = d_ratio(br_all, interval_sec) + ins_r = d_ratio(ins, br_all) + misp_r = d_ratio(br_m_tk, br_all) if br_m_tk else None + return MetricGroup("lpm_br_taken", [ + Metric("lpm_br_taken_retired", + "The number of taken branches that were retired per second.", + br_r, "insn/s"), + Metric( + "lpm_br_taken_mispred", + "The number of retired taken branch instructions that were " + "mispredicted as a percentage of all taken branches.", misp_r, + "100%") if misp_r else None, + Metric( + "lpm_br_taken_insn_between_branches", + "The number of instructions divided by the number of taken branches.", + ins_r, "insn"), + ]) + + def Conditional() -> Optional[MetricGroup]: + try: + br_cond = Event("BR_INST_RETIRED.COND", + "BR_INST_RETIRED.CONDITIONAL", + "BR_INST_RETIRED.TAKEN_JCC") + br_m_cond = Event("BR_MISP_RETIRED.COND", + "BR_MISP_RETIRED.CONDITIONAL", + "BR_MISP_RETIRED.TAKEN_JCC") + except: + return None + + br_cond_nt = None + br_m_cond_nt = None + try: + br_cond_nt = Event("BR_INST_RETIRED.COND_NTAKEN") + br_m_cond_nt = Event("BR_MISP_RETIRED.COND_NTAKEN") + except: + pass + br_r = d_ratio(br_cond, interval_sec) + ins_r = d_ratio(ins, br_cond) + misp_r = d_ratio(br_m_cond, br_cond) + taken_metrics = [ + Metric("lpm_br_cond_retired", "Retired conditional branch instructions.", + br_r, "insn/s"), + Metric("lpm_br_cond_insn_between_branches", + "The number of instructions divided by the number of conditional " + "branches.", ins_r, "insn"), + Metric("lpm_br_cond_mispred", + "Retired conditional branch instructions mispredicted as a " + "percentage of all conditional branches.", misp_r, "100%"), + ] + if not br_m_cond_nt: + return MetricGroup("lpm_br_cond", taken_metrics) + + br_r = d_ratio(br_cond_nt, interval_sec) + ins_r = d_ratio(ins, br_cond_nt) + misp_r = d_ratio(br_m_cond_nt, br_cond_nt) + + not_taken_metrics = [ + Metric("lpm_br_cond_retired", "Retired conditional not taken branch instructions.", + br_r, "insn/s"), + Metric("lpm_br_cond_insn_between_branches", + "The number of instructions divided by the number of not taken conditional " + "branches.", ins_r, "insn"), + Metric("lpm_br_cond_mispred", + "Retired not taken conditional branch instructions mispredicted as a " + "percentage of all not taken conditional branches.", misp_r, "100%"), + ] + return MetricGroup("lpm_br_cond", [ + MetricGroup("lpm_br_cond_nt", not_taken_metrics), + MetricGroup("lpm_br_cond_tkn", taken_metrics), + ]) + + def Far() -> Optional[MetricGroup]: + try: + br_far = Event("BR_INST_RETIRED.FAR_BRANCH") + except: + return None + + br_r = d_ratio(br_far, interval_sec) + ins_r = d_ratio(ins, br_far) + return MetricGroup("lpm_br_far", [ + Metric("lpm_br_far_retired", "Retired far control transfers per second.", + br_r, "insn/s"), + Metric( + "lpm_br_far_insn_between_branches", + "The number of instructions divided by the number of far branches.", + ins_r, "insn"), + ]) + + return MetricGroup("lpm_br", [Total(), Taken(), Conditional(), Far()], + description="breakdown of retired branch instructions") + + +def IntelCtxSw() -> MetricGroup: + cs = Event("context\\-switches") + metrics = [ + Metric("lpm_cs_rate", "Context switches per second", + d_ratio(cs, interval_sec), "ctxsw/s") + ] + + ev = Event("instructions") + metrics.append(Metric("lpm_cs_instr", "Instructions per context switch", + d_ratio(ev, cs), "instr/cs")) + + ev = Event("cycles") + metrics.append(Metric("lpm_cs_cycles", "Cycles per context switch", + d_ratio(ev, cs), "cycles/cs")) + + try: + ev = Event("MEM_INST_RETIRED.ALL_LOADS", "MEM_UOPS_RETIRED.ALL_LOADS") + metrics.append(Metric("lpm_cs_loads", "Loads per context switch", + d_ratio(ev, cs), "loads/cs")) + except: + pass + + try: + ev = Event("MEM_INST_RETIRED.ALL_STORES", + "MEM_UOPS_RETIRED.ALL_STORES") + metrics.append(Metric("lpm_cs_stores", "Stores per context switch", + d_ratio(ev, cs), "stores/cs")) + except: + pass + + try: + ev = Event("BR_INST_RETIRED.NEAR_TAKEN", "BR_INST_RETIRED.TAKEN_JCC") + metrics.append(Metric("lpm_cs_br_taken", "Branches taken per context switch", + d_ratio(ev, cs), "br_taken/cs")) + except: + pass + + try: + l2_misses = (Event("L2_RQSTS.DEMAND_DATA_RD_MISS") + + Event("L2_RQSTS.RFO_MISS") + + Event("L2_RQSTS.CODE_RD_MISS")) + try: + l2_misses += Event("L2_RQSTS.HWPF_MISS", + "L2_RQSTS.L2_PF_MISS", "L2_RQSTS.PF_MISS") + except: + pass + + metrics.append(Metric("lpm_cs_l2_misses", "L2 misses per context switch", + d_ratio(l2_misses, cs), "l2_misses/cs")) + except: + pass + + return MetricGroup("lpm_cs", metrics, + description=("Number of context switches per second, instructions " + "retired & core cycles between context switches")) + + +def IntelFpu() -> Optional[MetricGroup]: + cyc = Event("cycles") + try: + s_64 = Event("FP_ARITH_INST_RETIRED.SCALAR_SINGLE", + "SIMD_INST_RETIRED.SCALAR_SINGLE") + except: + return None + d_64 = Event("FP_ARITH_INST_RETIRED.SCALAR_DOUBLE", + "SIMD_INST_RETIRED.SCALAR_DOUBLE") + s_128 = Event("FP_ARITH_INST_RETIRED.128B_PACKED_SINGLE", + "SIMD_INST_RETIRED.PACKED_SINGLE") + + flop = s_64 + d_64 + 4 * s_128 + + d_128 = None + s_256 = None + d_256 = None + s_512 = None + d_512 = None + try: + d_128 = Event("FP_ARITH_INST_RETIRED.128B_PACKED_DOUBLE") + flop += 2 * d_128 + s_256 = Event("FP_ARITH_INST_RETIRED.256B_PACKED_SINGLE") + flop += 8 * s_256 + d_256 = Event("FP_ARITH_INST_RETIRED.256B_PACKED_DOUBLE") + flop += 4 * d_256 + s_512 = Event("FP_ARITH_INST_RETIRED.512B_PACKED_SINGLE") + flop += 16 * s_512 + d_512 = Event("FP_ARITH_INST_RETIRED.512B_PACKED_DOUBLE") + flop += 8 * d_512 + except: + pass + + f_assist = Event("ASSISTS.FP", "FP_ASSIST.ANY", "FP_ASSIST.S") + if f_assist in [ + "ASSISTS.FP", + "FP_ASSIST.S", + ]: + f_assist += "/cmask=1/" + + flop_r = d_ratio(flop, interval_sec) + flop_c = d_ratio(flop, cyc) + nmi_constraint = MetricConstraint.GROUPED_EVENTS + if f_assist.name == "ASSISTS.FP": # Icelake+ + nmi_constraint = MetricConstraint.NO_GROUP_EVENTS_NMI + + def FpuMetrics(group: str, fl: Optional[Event], mult: int, desc: str) -> Optional[MetricGroup]: + if not fl: + return None + + f = fl * mult + fl_r = d_ratio(f, interval_sec) + r_s = d_ratio(fl, interval_sec) + return MetricGroup(group, [ + Metric(f"{group}_of_total", desc + " floating point operations per second", + d_ratio(f, flop), "100%"), + Metric(f"{group}_flops", desc + " floating point operations per second", + fl_r, "flops/s"), + Metric(f"{group}_ops", desc + " operations per second", + r_s, "ops/s"), + ]) + + return MetricGroup("lpm_fpu", [ + MetricGroup("lpm_fpu_total", [ + Metric("lpm_fpu_total_flops", "Floating point operations per second", + flop_r, "flops/s"), + Metric("lpm_fpu_total_flopc", "Floating point operations per cycle", + flop_c, "flops/cycle", constraint=nmi_constraint), + ]), + MetricGroup("lpm_fpu_64", [ + FpuMetrics("lpm_fpu_64_single", s_64, 1, "64-bit single"), + FpuMetrics("lpm_fpu_64_double", d_64, 1, "64-bit double"), + ]), + MetricGroup("lpm_fpu_128", [ + FpuMetrics("lpm_fpu_128_single", s_128, + 4, "128-bit packed single"), + FpuMetrics("lpm_fpu_128_double", d_128, + 2, "128-bit packed double"), + ]), + MetricGroup("lpm_fpu_256", [ + FpuMetrics("lpm_fpu_256_single", s_256, + 8, "128-bit packed single"), + FpuMetrics("lpm_fpu_256_double", d_256, + 4, "128-bit packed double"), + ]), + MetricGroup("lpm_fpu_512", [ + FpuMetrics("lpm_fpu_512_single", s_512, + 16, "128-bit packed single"), + FpuMetrics("lpm_fpu_512_double", d_512, + 8, "128-bit packed double"), + ]), + Metric("lpm_fpu_assists", "FP assists as a percentage of cycles", + d_ratio(f_assist, cyc), "100%"), + ]) + + +def IntelIlp() -> MetricGroup: + tsc = Event("msr/tsc/") + c0 = Event("msr/mperf/") + low = tsc - c0 + inst_ret = Event("INST_RETIRED.ANY_P") + inst_ret_c = [Event(f"{inst_ret.name}/cmask={x}/") for x in range(1, 6)] + core_cycles = Event("CPU_CLK_UNHALTED.THREAD_P_ANY", + "CPU_CLK_UNHALTED.DISTRIBUTED", + "cycles") + ilp = [d_ratio(max(inst_ret_c[x] - inst_ret_c[x + 1], 0), core_cycles) + for x in range(0, 4)] + ilp.append(d_ratio(inst_ret_c[4], core_cycles)) + ilp0 = 1 + for x in ilp: + ilp0 -= x + return MetricGroup("lpm_ilp", [ + Metric("lpm_ilp_idle", "Lower power cycles as a percentage of all cycles", + d_ratio(low, tsc), "100%"), + Metric("lpm_ilp_inst_ret_0", + "Instructions retired in 0 cycles as a percentage of all cycles", + ilp0, "100%"), + Metric("lpm_ilp_inst_ret_1", + "Instructions retired in 1 cycles as a percentage of all cycles", + ilp[0], "100%"), + Metric("lpm_ilp_inst_ret_2", + "Instructions retired in 2 cycles as a percentage of all cycles", + ilp[1], "100%"), + Metric("lpm_ilp_inst_ret_3", + "Instructions retired in 3 cycles as a percentage of all cycles", + ilp[2], "100%"), + Metric("lpm_ilp_inst_ret_4", + "Instructions retired in 4 cycles as a percentage of all cycles", + ilp[3], "100%"), + Metric("lpm_ilp_inst_ret_5", + "Instructions retired in 5 or more cycles as a percentage of all cycles", + ilp[4], "100%"), + ]) + + +def IntelL2() -> Optional[MetricGroup]: + try: + DC_HIT = Event("L2_RQSTS.DEMAND_DATA_RD_HIT") + except: + return None + try: + DC_MISS = Event("L2_RQSTS.DEMAND_DATA_RD_MISS") + l2_dmnd_miss = DC_MISS + l2_dmnd_rd_all = DC_MISS + DC_HIT + except: + DC_ALL = Event("L2_RQSTS.ALL_DEMAND_DATA_RD") + l2_dmnd_miss = DC_ALL - DC_HIT + l2_dmnd_rd_all = DC_ALL + l2_dmnd_mrate = d_ratio(l2_dmnd_miss, interval_sec) + l2_dmnd_rrate = d_ratio(l2_dmnd_rd_all, interval_sec) + + DC_PFH = None + DC_PFM = None + l2_pf_all = None + l2_pf_mrate = None + l2_pf_rrate = None + try: + DC_PFH = Event("L2_RQSTS.PF_HIT") + DC_PFM = Event("L2_RQSTS.PF_MISS") + l2_pf_all = DC_PFH + DC_PFM + l2_pf_mrate = d_ratio(DC_PFM, interval_sec) + l2_pf_rrate = d_ratio(l2_pf_all, interval_sec) + except: + pass + + DC_RFOH = None + DC_RFOM = None + l2_rfo_all = None + l2_rfo_mrate = None + l2_rfo_rrate = None + try: + DC_RFOH = Event("L2_RQSTS.RFO_HIT") + DC_RFOM = Event("L2_RQSTS.RFO_MISS") + l2_rfo_all = DC_RFOH + DC_RFOM + l2_rfo_mrate = d_ratio(DC_RFOM, interval_sec) + l2_rfo_rrate = d_ratio(l2_rfo_all, interval_sec) + except: + pass + + DC_CH = None + try: + DC_CH = Event("L2_RQSTS.CODE_RD_HIT") + except: + pass + DC_CM = Event("L2_RQSTS.CODE_RD_MISS") + DC_IN = Event("L2_LINES_IN.ALL") + DC_OUT_NS = None + DC_OUT_S = None + l2_lines_out = None + l2_out_rate = None + wbn = None + isd = None + try: + DC_OUT_NS = Event("L2_LINES_OUT.NON_SILENT", + "L2_LINES_OUT.DEMAND_DIRTY", + "L2_LINES_IN.S") + DC_OUT_S = Event("L2_LINES_OUT.SILENT", + "L2_LINES_OUT.DEMAND_CLEAN", + "L2_LINES_IN.I") + if DC_OUT_S.name == "L2_LINES_OUT.SILENT" and ( + args.model.startswith("skylake") or + args.model == "cascadelakex"): + DC_OUT_S.name = "L2_LINES_OUT.SILENT/any/" + # bring is back to per-CPU + l2_s = Select(DC_OUT_S / 2, Literal("#smt_on"), DC_OUT_S) + l2_ns = DC_OUT_NS + l2_lines_out = l2_s + l2_ns + l2_out_rate = d_ratio(l2_lines_out, interval_sec) + nlr = max(l2_ns - DC_WB_U - DC_WB_D, 0) + wbn = d_ratio(nlr, interval_sec) + isd = d_ratio(l2_s, interval_sec) + except: + pass + DC_OUT_U = None + l2_pf_useless = None + l2_useless_rate = None + try: + DC_OUT_U = Event("L2_LINES_OUT.USELESS_HWPF") + l2_pf_useless = DC_OUT_U + l2_useless_rate = d_ratio(l2_pf_useless, interval_sec) + except: + pass + DC_WB_U = None + DC_WB_D = None + wbu = None + wbd = None + try: + DC_WB_U = Event("IDI_MISC.WB_UPGRADE") + DC_WB_D = Event("IDI_MISC.WB_DOWNGRADE") + wbu = d_ratio(DC_WB_U, interval_sec) + wbd = d_ratio(DC_WB_D, interval_sec) + except: + pass + + l2_lines_in = DC_IN + l2_code_all = (DC_CH + DC_CM) if DC_CH else None + l2_code_rate = d_ratio(l2_code_all, interval_sec) if DC_CH else None + l2_code_miss_rate = d_ratio(DC_CM, interval_sec) + l2_in_rate = d_ratio(l2_lines_in, interval_sec) + + return MetricGroup("lpm_l2", [ + MetricGroup("lpm_l2_totals", [ + Metric("lpm_l2_totals_in", "L2 cache total in per second", + l2_in_rate, "In/s"), + Metric("lpm_l2_totals_out", "L2 cache total out per second", + l2_out_rate, "Out/s") if l2_out_rate else None, + ]), + MetricGroup("lpm_l2_rd", [ + Metric("lpm_l2_rd_hits", "L2 cache data read hits", + d_ratio(DC_HIT, l2_dmnd_rd_all), "100%"), + Metric("lpm_l2_rd_hits", "L2 cache data read hits", + d_ratio(l2_dmnd_miss, l2_dmnd_rd_all), "100%"), + Metric("lpm_l2_rd_requests", "L2 cache data read requests per second", + l2_dmnd_rrate, "requests/s"), + Metric("lpm_l2_rd_misses", "L2 cache data read misses per second", + l2_dmnd_mrate, "misses/s"), + ]), + MetricGroup("lpm_l2_hwpf", [ + Metric("lpm_l2_hwpf_hits", "L2 cache hardware prefetcher hits", + d_ratio(DC_PFH, l2_pf_all), "100%"), + Metric("lpm_l2_hwpf_misses", "L2 cache hardware prefetcher misses", + d_ratio(DC_PFM, l2_pf_all), "100%"), + Metric("lpm_l2_hwpf_useless", "L2 cache hardware prefetcher useless prefetches per second", + l2_useless_rate, "100%") if l2_useless_rate else None, + Metric("lpm_l2_hwpf_requests", "L2 cache hardware prefetcher requests per second", + l2_pf_rrate, "100%"), + Metric("lpm_l2_hwpf_misses", "L2 cache hardware prefetcher misses per second", + l2_pf_mrate, "100%"), + ]) if DC_PFH else None, + MetricGroup("lpm_l2_rfo", [ + Metric("lpm_l2_rfo_hits", "L2 cache request for ownership (RFO) hits", + d_ratio(DC_RFOH, l2_rfo_all), "100%"), + Metric("lpm_l2_rfo_misses", "L2 cache request for ownership (RFO) misses", + d_ratio(DC_RFOM, l2_rfo_all), "100%"), + Metric("lpm_l2_rfo_requests", "L2 cache request for ownership (RFO) requests per second", + l2_rfo_rrate, "requests/s"), + Metric("lpm_l2_rfo_misses", "L2 cache request for ownership (RFO) misses per second", + l2_rfo_mrate, "misses/s"), + ]) if DC_RFOH else None, + MetricGroup("lpm_l2_code", [ + Metric("lpm_l2_code_hits", "L2 cache code hits", + d_ratio(DC_CH, l2_code_all), "100%") if DC_CH else None, + Metric("lpm_l2_code_misses", "L2 cache code misses", + d_ratio(DC_CM, l2_code_all), "100%") if DC_CH else None, + Metric("lpm_l2_code_requests", "L2 cache code requests per second", + l2_code_rate, "requests/s") if DC_CH else None, + Metric("lpm_l2_code_misses", "L2 cache code misses per second", + l2_code_miss_rate, "misses/s"), + ]), + MetricGroup("lpm_l2_evict", [ + MetricGroup("lpm_l2_evict_mef_lines", [ + Metric("lpm_l2_evict_mef_lines_l3_hot_lru", "L2 evictions M/E/F lines L3 hot LRU per second", + wbu, "HotLRU/s") if wbu else None, + Metric("lpm_l2_evict_mef_lines_l3_norm_lru", "L2 evictions M/E/F lines L3 normal LRU per second", + wbn, "NormLRU/s") if wbn else None, + Metric("lpm_l2_evict_mef_lines_dropped", "L2 evictions M/E/F lines dropped per second", + wbd, "dropped/s") if wbd else None, + Metric("lpm_l2_evict_is_lines_dropped", "L2 evictions I/S lines dropped per second", + isd, "dropped/s") if isd else None, + ]), + ]), + ], description="L2 data cache analysis") + + +def IntelMissLat() -> Optional[MetricGroup]: + try: + ticks = Event("UNC_CHA_CLOCKTICKS", "UNC_C_CLOCKTICKS") + data_rd_loc_occ = Event("UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD_LOCAL", + "UNC_CHA_TOR_OCCUPANCY.IA_MISS", + "UNC_C_TOR_OCCUPANCY.MISS_LOCAL_OPCODE", + "UNC_C_TOR_OCCUPANCY.MISS_OPCODE") + data_rd_loc_ins = Event("UNC_CHA_TOR_INSERTS.IA_MISS_DRD_LOCAL", + "UNC_CHA_TOR_INSERTS.IA_MISS", + "UNC_C_TOR_INSERTS.MISS_LOCAL_OPCODE", + "UNC_C_TOR_INSERTS.MISS_OPCODE") + data_rd_rem_occ = Event("UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD_REMOTE", + "UNC_CHA_TOR_OCCUPANCY.IA_MISS", + "UNC_C_TOR_OCCUPANCY.MISS_REMOTE_OPCODE", + "UNC_C_TOR_OCCUPANCY.NID_MISS_OPCODE") + data_rd_rem_ins = Event("UNC_CHA_TOR_INSERTS.IA_MISS_DRD_REMOTE", + "UNC_CHA_TOR_INSERTS.IA_MISS", + "UNC_C_TOR_INSERTS.MISS_REMOTE_OPCODE", + "UNC_C_TOR_INSERTS.NID_MISS_OPCODE") + except: + return None + + if (data_rd_loc_occ.name == "UNC_C_TOR_OCCUPANCY.MISS_LOCAL_OPCODE" or + data_rd_loc_occ.name == "UNC_C_TOR_OCCUPANCY.MISS_OPCODE"): + data_rd = 0x182 + for e in [data_rd_loc_occ, data_rd_loc_ins, data_rd_rem_occ, data_rd_rem_ins]: + e.name += f"/filter_opc={hex(data_rd)}/" + elif data_rd_loc_occ.name == "UNC_CHA_TOR_OCCUPANCY.IA_MISS": + # Demand Data Read - Full cache-line read requests from core for + # lines to be cached in S or E, typically for data + demand_data_rd = 0x202 + # LLC Prefetch Data - Uncore will first look up the line in the + # LLC; for a cache hit, the LRU will be updated, on a miss, the + # DRd will be initiated + llc_prefetch_data = 0x25a + local_filter = (f"/filter_opc0={hex(demand_data_rd)}," + f"filter_opc1={hex(llc_prefetch_data)}," + "filter_loc,filter_nm,filter_not_nm/") + remote_filter = (f"/filter_opc0={hex(demand_data_rd)}," + f"filter_opc1={hex(llc_prefetch_data)}," + "filter_rem,filter_nm,filter_not_nm/") + for e in [data_rd_loc_occ, data_rd_loc_ins]: + e.name += local_filter + for e in [data_rd_rem_occ, data_rd_rem_ins]: + e.name += remote_filter + else: + assert data_rd_loc_occ.name == "UNC_CHA_TOR_OCCUPANCY.IA_MISS_DRD_LOCAL", data_rd_loc_occ + + ticks_per_cha = ticks / source_count(data_rd_loc_ins) + loc_lat = interval_sec * 1e9 * data_rd_loc_occ / \ + (ticks_per_cha * data_rd_loc_ins) + ticks_per_cha = ticks / source_count(data_rd_rem_ins) + rem_lat = interval_sec * 1e9 * data_rd_rem_occ / \ + (ticks_per_cha * data_rd_rem_ins) + return MetricGroup("lpm_miss_lat", [ + Metric("lpm_miss_lat_loc", "Local to a socket miss latency in nanoseconds", + loc_lat, "ns"), + Metric("lpm_miss_lat_rem", "Remote to a socket miss latency in nanoseconds", + rem_lat, "ns"), + ]) + + +def IntelMlp() -> Optional[Metric]: + try: + l1d = Event("L1D_PEND_MISS.PENDING") + l1dc = Event("L1D_PEND_MISS.PENDING_CYCLES") + except: + return None + + l1dc = Select(l1dc / 2, Literal("#smt_on"), l1dc) + ml = d_ratio(l1d, l1dc) + return Metric("lpm_mlp", + "Miss level parallelism - number of outstanding load misses per cycle (higher is better)", + ml, "load_miss_pending/cycle") + + +def IntelPorts() -> Optional[MetricGroup]: + pipeline_events = json.load( + open(f"{_args.events_path}/x86/{_args.model}/pipeline.json")) + + core_cycles = Event("CPU_CLK_UNHALTED.THREAD_P_ANY", + "CPU_CLK_UNHALTED.DISTRIBUTED", + "cycles") + # Number of CPU cycles scaled for SMT. + smt_cycles = Select(core_cycles / 2, Literal("#smt_on"), core_cycles) + + metrics = [] + for x in pipeline_events: + if "EventName" in x and re.search("^UOPS_DISPATCHED.PORT", x["EventName"]): + name = x["EventName"] + port = re.search(r"(PORT_[0-9].*)", name).group(0).lower() + if name.endswith("_CORE"): + cyc = core_cycles + else: + cyc = smt_cycles + metrics.append(Metric(f"lpm_{port}", f"{port} utilization (higher is better)", + d_ratio(Event(name), cyc), "100%")) + if len(metrics) == 0: + return None + + return MetricGroup("lpm_ports", metrics, "functional unit (port) utilization -- " + "fraction of cycles each port is utilized (higher is better)") + + +def IntelSwpf() -> Optional[MetricGroup]: + ins = Event("instructions") + try: + s_ld = Event("MEM_INST_RETIRED.ALL_LOADS", + "MEM_UOPS_RETIRED.ALL_LOADS") + s_nta = Event("SW_PREFETCH_ACCESS.NTA") + s_t0 = Event("SW_PREFETCH_ACCESS.T0") + s_t1 = Event("SW_PREFETCH_ACCESS.T1_T2") + s_w = Event("SW_PREFETCH_ACCESS.PREFETCHW") + except: + return None + + all_sw = s_nta + s_t0 + s_t1 + s_w + swp_r = d_ratio(all_sw, interval_sec) + ins_r = d_ratio(ins, all_sw) + ld_r = d_ratio(s_ld, all_sw) + + return MetricGroup("lpm_swpf", [ + MetricGroup("lpm_swpf_totals", [ + Metric("lpm_swpf_totals_exec", "Software prefetch instructions per second", + swp_r, "swpf/s"), + Metric("lpm_swpf_totals_insn_per_pf", + "Average number of instructions between software prefetches", + ins_r, "insn/swpf"), + Metric("lpm_swpf_totals_loads_per_pf", + "Average number of loads between software prefetches", + ld_r, "loads/swpf"), + ]), + MetricGroup("lpm_swpf_bkdwn", [ + MetricGroup("lpm_swpf_bkdwn_nta", [ + Metric("lpm_swpf_bkdwn_nta_per_swpf", + "Software prefetch NTA instructions as a percent of all prefetch instructions", + d_ratio(s_nta, all_sw), "100%"), + Metric("lpm_swpf_bkdwn_nta_rate", + "Software prefetch NTA instructions per second", + d_ratio(s_nta, interval_sec), "insn/s"), + ]), + MetricGroup("lpm_swpf_bkdwn_t0", [ + Metric("lpm_swpf_bkdwn_t0_per_swpf", + "Software prefetch T0 instructions as a percent of all prefetch instructions", + d_ratio(s_t0, all_sw), "100%"), + Metric("lpm_swpf_bkdwn_t0_rate", + "Software prefetch T0 instructions per second", + d_ratio(s_t0, interval_sec), "insn/s"), + ]), + MetricGroup("lpm_swpf_bkdwn_t1_t2", [ + Metric("lpm_swpf_bkdwn_t1_t2_per_swpf", + "Software prefetch T1 or T2 instructions as a percent of all prefetch instructions", + d_ratio(s_t1, all_sw), "100%"), + Metric("lpm_swpf_bkdwn_t1_t2_rate", + "Software prefetch T1 or T2 instructions per second", + d_ratio(s_t1, interval_sec), "insn/s"), + ]), + MetricGroup("lpm_swpf_bkdwn_w", [ + Metric("lpm_swpf_bkdwn_w_per_swpf", + "Software prefetch W instructions as a percent of all prefetch instructions", + d_ratio(s_w, all_sw), "100%"), + Metric("lpm_swpf_bkdwn_w_rate", + "Software prefetch W instructions per second", + d_ratio(s_w, interval_sec), "insn/s"), + ]), + ]), + ], description="Software prefetch instruction breakdown") + + +def IntelLdSt() -> Optional[MetricGroup]: + if _args.model in [ + "bonnell", + "nehalemep", + "nehalemex", + "westmereep-dp", + "westmereep-sp", + "westmereex", + ]: + return None + LDST_LD = Event("MEM_INST_RETIRED.ALL_LOADS", "MEM_UOPS_RETIRED.ALL_LOADS") + LDST_ST = Event("MEM_INST_RETIRED.ALL_STORES", + "MEM_UOPS_RETIRED.ALL_STORES") + LDST_LDC1 = Event(f"{LDST_LD.name}/cmask=1/") + LDST_STC1 = Event(f"{LDST_ST.name}/cmask=1/") + LDST_LDC2 = Event(f"{LDST_LD.name}/cmask=2/") + LDST_STC2 = Event(f"{LDST_ST.name}/cmask=2/") + LDST_LDC3 = Event(f"{LDST_LD.name}/cmask=3/") + LDST_STC3 = Event(f"{LDST_ST.name}/cmask=3/") + ins = Event("instructions") + LDST_CYC = Event("CPU_CLK_UNHALTED.THREAD", + "CPU_CLK_UNHALTED.CORE_P", + "CPU_CLK_UNHALTED.THREAD_P") + LDST_PRE = None + try: + LDST_PRE = Event("LOAD_HIT_PREFETCH.SWPF", "LOAD_HIT_PRE.SW_PF") + except: + pass + LDST_AT = None + try: + LDST_AT = Event("MEM_INST_RETIRED.LOCK_LOADS") + except: + pass + cyc = LDST_CYC + + ld_rate = d_ratio(LDST_LD, interval_sec) + st_rate = d_ratio(LDST_ST, interval_sec) + pf_rate = d_ratio(LDST_PRE, interval_sec) if LDST_PRE else None + at_rate = d_ratio(LDST_AT, interval_sec) if LDST_AT else None + + ldst_ret_constraint = MetricConstraint.GROUPED_EVENTS + if LDST_LD.name == "MEM_UOPS_RETIRED.ALL_LOADS": + ldst_ret_constraint = MetricConstraint.NO_GROUP_EVENTS_NMI + + return MetricGroup("lpm_ldst", [ + MetricGroup("lpm_ldst_total", [ + Metric("lpm_ldst_total_loads", "Load/store instructions total loads", + ld_rate, "loads"), + Metric("lpm_ldst_total_stores", "Load/store instructions total stores", + st_rate, "stores"), + ]), + MetricGroup("lpm_ldst_prcnt", [ + Metric("lpm_ldst_prcnt_loads", "Percent of all instructions that are loads", + d_ratio(LDST_LD, ins), "100%"), + Metric("lpm_ldst_prcnt_stores", "Percent of all instructions that are stores", + d_ratio(LDST_ST, ins), "100%"), + ]), + MetricGroup("lpm_ldst_ret_lds", [ + Metric("lpm_ldst_ret_lds_1", "Retired loads in 1 cycle", + d_ratio(max(LDST_LDC1 - LDST_LDC2, 0), cyc), "100%", + constraint=ldst_ret_constraint), + Metric("lpm_ldst_ret_lds_2", "Retired loads in 2 cycles", + d_ratio(max(LDST_LDC2 - LDST_LDC3, 0), cyc), "100%", + constraint=ldst_ret_constraint), + Metric("lpm_ldst_ret_lds_3", "Retired loads in 3 or more cycles", + d_ratio(LDST_LDC3, cyc), "100%"), + ]), + MetricGroup("lpm_ldst_ret_sts", [ + Metric("lpm_ldst_ret_sts_1", "Retired stores in 1 cycle", + d_ratio(max(LDST_STC1 - LDST_STC2, 0), cyc), "100%", + constraint=ldst_ret_constraint), + Metric("lpm_ldst_ret_sts_2", "Retired stores in 2 cycles", + d_ratio(max(LDST_STC2 - LDST_STC3, 0), cyc), "100%", + constraint=ldst_ret_constraint), + Metric("lpm_ldst_ret_sts_3", "Retired stores in 3 more cycles", + d_ratio(LDST_STC3, cyc), "100%"), + ]), + Metric("lpm_ldst_ld_hit_swpf", "Load hit software prefetches per second", + pf_rate, "swpf/s") if pf_rate else None, + Metric("lpm_ldst_atomic_lds", "Atomic loads per second", + at_rate, "loads/s") if at_rate else None, + ], description="Breakdown of load/store instructions") + + +def UncoreCState() -> Optional[MetricGroup]: + try: + pcu_ticks = Event("UNC_P_CLOCKTICKS") + c0 = Event("UNC_P_POWER_STATE_OCCUPANCY.CORES_C0") + c3 = Event("UNC_P_POWER_STATE_OCCUPANCY.CORES_C3") + c6 = Event("UNC_P_POWER_STATE_OCCUPANCY.CORES_C6") + except: + return None + + num_cores = Literal("#num_cores") / Literal("#num_packages") + + max_cycles = pcu_ticks * num_cores + total_cycles = c0 + c3 + c6 + + # remove fused-off cores which show up in C6/C7. + c6 = Select(max(c6 - (total_cycles - max_cycles), 0), + total_cycles > max_cycles, + c6) + + return MetricGroup("lpm_cstate", [ + Metric("lpm_cstate_c0", "C-State cores in C0/C1", + d_ratio(c0, pcu_ticks), "cores"), + Metric("lpm_cstate_c3", "C-State cores in C3", + d_ratio(c3, pcu_ticks), "cores"), + Metric("lpm_cstate_c6", "C-State cores in C6/C7", + d_ratio(c6, pcu_ticks), "cores"), + ]) + + +def UncoreDir() -> Optional[MetricGroup]: + try: + m2m_upd = Event("UNC_M2M_DIRECTORY_UPDATE.ANY") + m2m_hits = Event("UNC_M2M_DIRECTORY_HIT.DIRTY_I") + # Turn the umask into a ANY rather than DIRTY_I filter. + m2m_hits.name += "/umask=0xFF,name=UNC_M2M_DIRECTORY_HIT.ANY/" + m2m_miss = Event("UNC_M2M_DIRECTORY_MISS.DIRTY_I") + # Turn the umask into a ANY rather than DIRTY_I filter. + m2m_miss.name += "/umask=0xFF,name=UNC_M2M_DIRECTORY_MISS.ANY/" + cha_upd = Event("UNC_CHA_DIR_UPDATE.HA") + # Turn the umask into a ANY rather than HA filter. + cha_upd.name += "/umask=3,name=UNC_CHA_DIR_UPDATE.ANY/" + except: + return None + + m2m_total = m2m_hits + m2m_miss + upd = m2m_upd + cha_upd # in cache lines + upd_r = upd / interval_sec + look_r = m2m_total / interval_sec + + scale = 64 / 1_000_000 # Cache lines to MB + return MetricGroup("lpm_dir", [ + Metric("lpm_dir_lookup_rate", "", + d_ratio(m2m_total, interval_sec), "requests/s"), + Metric("lpm_dir_lookup_hits", "", + d_ratio(m2m_hits, m2m_total), "100%"), + Metric("lpm_dir_lookup_misses", "", + d_ratio(m2m_miss, m2m_total), "100%"), + Metric("lpm_dir_update_requests", "", + d_ratio(m2m_upd + cha_upd, interval_sec), "requests/s"), + Metric("lpm_dir_update_bw", "", + d_ratio(m2m_upd + cha_upd, interval_sec), f"{scale}MB/s"), + ]) + + +def UncoreMem() -> Optional[MetricGroup]: + try: + loc_rds = Event("UNC_CHA_REQUESTS.READS_LOCAL", + "UNC_H_REQUESTS.READS_LOCAL") + rem_rds = Event("UNC_CHA_REQUESTS.READS_REMOTE", + "UNC_H_REQUESTS.READS_REMOTE") + loc_wrs = Event("UNC_CHA_REQUESTS.WRITES_LOCAL", + "UNC_H_REQUESTS.WRITES_LOCAL") + rem_wrs = Event("UNC_CHA_REQUESTS.WRITES_REMOTE", + "UNC_H_REQUESTS.WRITES_REMOTE") + except: + return None + + scale = 64 / 1_000_000 + return MetricGroup("lpm_mem", [ + MetricGroup("lpm_mem_local", [ + Metric("lpm_mem_local_read", "Local memory read bandwidth not including directory updates", + d_ratio(loc_rds, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_local_write", "Local memory write bandwidth not including directory updates", + d_ratio(loc_wrs, interval_sec), f"{scale}MB/s"), + ]), + MetricGroup("lpm_mem_remote", [ + Metric("lpm_mem_remote_read", "Remote memory read bandwidth not including directory updates", + d_ratio(rem_rds, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_remote_write", "Remote memory write bandwidth not including directory updates", + d_ratio(rem_wrs, interval_sec), f"{scale}MB/s"), + ]), + ], description="Memory Bandwidth breakdown local vs. remote (remote requests in). directory updates not included") + + +def UncoreMemBw() -> Optional[MetricGroup]: + mem_events = [] + try: + mem_events = json.load(open(f"{os.path.dirname(os.path.realpath(__file__))}" + f"/arch/x86/{args.model}/uncore-memory.json")) + except: + pass + + ddr_rds = 0 + ddr_wrs = 0 + ddr_total = 0 + for x in mem_events: + if "EventName" in x: + name = x["EventName"] + if re.search("^UNC_MC[0-9]+_RDCAS_COUNT_FREERUN", name): + ddr_rds += Event(name) + elif re.search("^UNC_MC[0-9]+_WRCAS_COUNT_FREERUN", name): + ddr_wrs += Event(name) + # elif re.search("^UNC_MC[0-9]+_TOTAL_REQCOUNT_FREERUN", name): + # ddr_total += Event(name) + + if ddr_rds == 0: + try: + ddr_rds = Event("UNC_M_CAS_COUNT.RD") + ddr_wrs = Event("UNC_M_CAS_COUNT.WR") + except: + return None + + ddr_total = ddr_rds + ddr_wrs + + pmm_rds = 0 + pmm_wrs = 0 + try: + pmm_rds = Event("UNC_M_PMM_RPQ_INSERTS") + pmm_wrs = Event("UNC_M_PMM_WPQ_INSERTS") + except: + pass + + pmm_total = pmm_rds + pmm_wrs + + scale = 64 / 1_000_000 + return MetricGroup("lpm_mem_bw", [ + MetricGroup("lpm_mem_bw_ddr", [ + Metric("lpm_mem_bw_ddr_read", "DDR memory read bandwidth", + d_ratio(ddr_rds, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_bw_ddr_write", "DDR memory write bandwidth", + d_ratio(ddr_wrs, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_bw_ddr_total", "DDR memory write bandwidth", + d_ratio(ddr_total, interval_sec), f"{scale}MB/s"), + ], description="DDR Memory Bandwidth"), + MetricGroup("lpm_mem_bw_pmm", [ + Metric("lpm_mem_bw_pmm_read", "PMM memory read bandwidth", + d_ratio(pmm_rds, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_bw_pmm_write", "PMM memory write bandwidth", + d_ratio(pmm_wrs, interval_sec), f"{scale}MB/s"), + Metric("lpm_mem_bw_pmm_total", "PMM memory write bandwidth", + d_ratio(pmm_total, interval_sec), f"{scale}MB/s"), + ], description="PMM Memory Bandwidth") if pmm_rds != 0 else None, + ], description="Memory Bandwidth") + + +def UncoreMemSat() -> Optional[Metric]: + try: + clocks = Event("UNC_CHA_CLOCKTICKS", "UNC_C_CLOCKTICKS") + sat = Event("UNC_CHA_DISTRESS_ASSERTED.VERT", "UNC_CHA_FAST_ASSERTED.VERT", + "UNC_C_FAST_ASSERTED") + except: + return None + + desc = ("Mesh Bandwidth saturation (% CBOX cycles with FAST signal asserted, " + "include QPI bandwidth saturation), lower is better") + if "UNC_CHA_" in sat.name: + desc = ("Mesh Bandwidth saturation (% CHA cycles with FAST signal asserted, " + "include UPI bandwidth saturation), lower is better") + return Metric("lpm_mem_sat", desc, d_ratio(sat, clocks), "100%") + + +def UncoreUpiBw() -> Optional[MetricGroup]: + try: + upi_rds = Event("UNC_UPI_RxL_FLITS.ALL_DATA") + upi_wrs = Event("UNC_UPI_TxL_FLITS.ALL_DATA") + except: + return None + + upi_total = upi_rds + upi_wrs + + # From "Uncore Performance Monitoring": When measuring the amount of + # bandwidth consumed by transmission of the data (i.e. NOT including + # the header), it should be .ALL_DATA / 9 * 64B. + scale = (64 / 9) / 1_000_000 + return MetricGroup("lpm_upi_bw", [ + Metric("lpm_upi_bw_read", "UPI read bandwidth", + d_ratio(upi_rds, interval_sec), f"{scale}MB/s"), + Metric("lpm_upi_bw_write", "DDR memory write bandwidth", + d_ratio(upi_wrs, interval_sec), f"{scale}MB/s"), + ], description="UPI Bandwidth") + + +def main() -> None: + global _args + + def dir_path(path: str) -> str: + """Validate path is a directory for argparse.""" + if os.path.isdir(path): + return path + raise argparse.ArgumentTypeError( + f'\'{path}\' is not a valid directory') + + parser = argparse.ArgumentParser(description="Intel perf json generator") + parser.add_argument( + "-metricgroups", help="Generate metricgroups data", action='store_true') + parser.add_argument("model", help="e.g. skylakex") + parser.add_argument( + 'events_path', + type=dir_path, + help='Root of tree containing architecture directories containing json files' + ) + _args = parser.parse_args() + + directory = f"{_args.events_path}/x86/{_args.model}/" + LoadEvents(directory) + + all_metrics = MetricGroup("", [ + Cycles(), + Idle(), + Rapl(), + Smi(), + Tsx(), + IntelBr(), + IntelCtxSw(), + IntelFpu(), + IntelIlp(), + IntelL2(), + IntelLdSt(), + IntelMissLat(), + IntelMlp(), + IntelPorts(), + IntelSwpf(), + UncoreCState(), + UncoreDir(), + UncoreMem(), + UncoreMemBw(), + UncoreMemSat(), + UncoreUpiBw(), + ]) + + if _args.metricgroups: + print(JsonEncodeMetricGroupDescriptions(all_metrics)) + else: + print(JsonEncodeMetric(all_metrics)) + + +if __name__ == '__main__': + main() diff --git a/tools/perf/pmu-events/metric.py b/tools/perf/pmu-events/metric.py index dd8fd06940e6..585454828c2f 100644 --- a/tools/perf/pmu-events/metric.py +++ b/tools/perf/pmu-events/metric.py @@ -3,10 +3,115 @@ import ast import decimal import json +import os import re from enum import Enum from typing import Dict, List, Optional, Set, Tuple, Union +all_pmus = set() +all_events = set() +experimental_events = set() +all_events_all_models = set() + +def LoadEvents(directory: str) -> None: + """Populate a global set of all known events for the purpose of validating Event names""" + global all_pmus + global all_events + global experimental_events + global all_events_all_models + all_events = { + "context\\-switches", + "cpu\\-cycles", + "cycles", + "duration_time", + "instructions", + "l2_itlb_misses", + } + for file in os.listdir(os.fsencode(directory)): + filename = os.fsdecode(file) + if filename.endswith(".json"): + try: + for x in json.load(open(f"{directory}/{filename}")): + if "Unit" in x: + all_pmus.add(x["Unit"]) + if "EventName" in x: + all_events.add(x["EventName"]) + if "Experimental" in x and x["Experimental"] == "1": + experimental_events.add(x["EventName"]) + elif "ArchStdEvent" in x: + all_events.add(x["ArchStdEvent"]) + except json.decoder.JSONDecodeError: + # The generated directory may be the same as the input, which + # causes partial json files. Ignore errors. + pass + all_events_all_models = all_events.copy() + for root, dirs, files in os.walk(directory + ".."): + for filename in files: + if filename.endswith(".json"): + try: + for x in json.load(open(f"{root}/{filename}")): + if "EventName" in x: + all_events_all_models.add(x["EventName"]) + elif "ArchStdEvent" in x: + all_events_all_models.add(x["ArchStdEvent"]) + except json.decoder.JSONDecodeError: + # The generated directory may be the same as the input, which + # causes partial json files. Ignore errors. + pass + + +def CheckPmu(name: str) -> bool: + return name in all_pmus + + +def CheckEvent(name: str) -> bool: + """Check the event name exists in the set of all loaded events""" + global all_events + if len(all_events) == 0: + # No events loaded so assume any event is good. + return True + + if ':' in name: + # Remove trailing modifier. + name = name[:name.find(':')] + elif '/' in name: + # Name could begin with a PMU or an event, for now assume it is good. + return True + + return name in all_events + +def CheckEveryEvent(*names: str) -> None: + """Check all the events exist in at least one json file""" + global all_events_all_models + if len(all_events_all_models) == 0: + assert len(names) == 1, f"Cannot determine valid events in {names}" + # No events loaded so assume any event is good. + return + + for name in names: + # Remove trailing modifier. + if ':' in name: + name = name[:name.find(':')] + elif '/' in name: + name = name[:name.find('/')] + if any([name.startswith(x) for x in ['amd', 'arm', 'cpu', 'msr', 'power']]): + continue + if name not in all_events_all_models: + raise Exception(f"Is {name} a named json event?") + + +def IsExperimentalEvent(name: str) -> bool: + global experimental_events + if ':' in name: + # Remove trailing modifier. + name = name[:name.find(':')] + elif '/' in name: + # Name could begin with a PMU or an event, for now assume it is not experimental. + return False + + return name in experimental_events + + class MetricConstraint(Enum): GROUPED_EVENTS = 0 NO_GROUP_EVENTS = 1 @@ -28,6 +133,10 @@ class Expression: """Returns a simplified version of self.""" raise NotImplementedError() + def HasExperimentalEvents(self) -> bool: + """Are experimental events used in the expression?""" + raise NotImplementedError() + def Equals(self, other) -> bool: """Returns true when two expressions are the same.""" raise NotImplementedError() @@ -195,6 +304,9 @@ class Operator(Expression): return Operator(self.operator, lhs, rhs) + def HasExperimentalEvents(self) -> bool: + return self.lhs.HasExperimentalEvents() or self.rhs.HasExperimentalEvents() + def Equals(self, other: Expression) -> bool: if isinstance(other, Operator): return self.operator == other.operator and self.lhs.Equals( @@ -243,6 +355,10 @@ class Select(Expression): return Select(true_val, cond, false_val) + def HasExperimentalEvents(self) -> bool: + return (self.cond.HasExperimentalEvents() or self.true_val.HasExperimentalEvents() or + self.false_val.HasExperimentalEvents()) + def Equals(self, other: Expression) -> bool: if isinstance(other, Select): return self.cond.Equals(other.cond) and self.false_val.Equals( @@ -291,6 +407,9 @@ class Function(Expression): return Function(self.fn, lhs, rhs) + def HasExperimentalEvents(self) -> bool: + return self.lhs.HasExperimentalEvents() or (self.rhs and self.rhs.HasExperimentalEvents()) + def Equals(self, other: Expression) -> bool: if isinstance(other, Function): result = self.fn == other.fn and self.lhs.Equals(other.lhs) @@ -317,9 +436,22 @@ def _FixEscapes(s: str) -> str: class Event(Expression): """An event in an expression.""" - def __init__(self, name: str, legacy_name: str = ''): - self.name = _FixEscapes(name) - self.legacy_name = _FixEscapes(legacy_name) + def __init__(self, *args: str): + error = "" + CheckEveryEvent(*args) + for name in args: + if CheckEvent(name): + self.name = _FixEscapes(name) + return + if error: + error += " or " + name + else: + error = name + global all_events + raise Exception(f"No event {error} in:\n{all_events}") + + def HasExperimentalEvents(self) -> bool: + return IsExperimentalEvent(self.name) def ToPerfJson(self): result = re.sub('/', '@', self.name) @@ -338,6 +470,31 @@ class Event(Expression): return self +class MetricRef(Expression): + """A metric reference in an expression.""" + + def __init__(self, name: str): + self.name = _FixEscapes(name) + + def ToPerfJson(self): + return self.name + + def ToPython(self): + return f'MetricRef(r"{self.name}")' + + def Simplify(self) -> Expression: + return self + + def HasExperimentalEvents(self) -> bool: + return False + + def Equals(self, other: Expression) -> bool: + return isinstance(other, MetricRef) and self.name == other.name + + def Substitute(self, name: str, expression: Expression) -> Expression: + return self + + class Constant(Expression): """A constant within the expression tree.""" @@ -358,6 +515,9 @@ class Constant(Expression): def Simplify(self) -> Expression: return self + def HasExperimentalEvents(self) -> bool: + return False + def Equals(self, other: Expression) -> bool: return isinstance(other, Constant) and self.value == other.value @@ -380,6 +540,9 @@ class Literal(Expression): def Simplify(self) -> Expression: return self + def HasExperimentalEvents(self) -> bool: + return False + def Equals(self, other: Expression) -> bool: return isinstance(other, Literal) and self.value == other.value @@ -442,6 +605,8 @@ class Metric: self.name = name self.description = description self.expr = expr.Simplify() + if self.expr.HasExperimentalEvents(): + self.description += " (metric should be considered experimental as it contains experimental events)." # Workraound valid_only_metric hiding certain metrics based on unit. scale_unit = scale_unit.replace('/sec', ' per sec') if scale_unit[0].isdigit(): diff --git a/tools/perf/scripts/python/Perf-Trace-Util/Context.c b/tools/perf/scripts/python/Perf-Trace-Util/Context.c index 60dcfe56d4d9..c19f44610983 100644 --- a/tools/perf/scripts/python/Perf-Trace-Util/Context.c +++ b/tools/perf/scripts/python/Perf-Trace-Util/Context.c @@ -93,7 +93,7 @@ static PyObject *perf_sample_insn(PyObject *obj, PyObject *args) if (c->sample->ip && !c->sample->insn_len && thread__maps(c->al->thread)) { struct machine *machine = maps__machine(thread__maps(c->al->thread)); - script_fetch_insn(c->sample, c->al->thread, machine, /*native_arch=*/true); + perf_sample__fetch_insn(c->sample, c->al->thread, machine); } if (!c->sample->insn_len) Py_RETURN_NONE; /* N.B. This is a return statement */ diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index bd6ffa8e4578..06507066213b 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -153,6 +153,11 @@ static struct test_workload *workloads[] = { &workload__datasym, &workload__landlock, &workload__traploop, + &workload__inlineloop, + +#ifdef HAVE_RUST_SUPPORT + &workload__code_with_type, +#endif }; #define workloads__for_each(workload) \ diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c index 80a1c941138d..e63790c61d53 100644 --- a/tools/perf/tests/dlfilter-test.c +++ b/tools/perf/tests/dlfilter-test.c @@ -30,7 +30,6 @@ #include "symbol.h" #include "synthetic-events.h" #include "util.h" -#include "archinsn.h" #include "dlfilter.h" #include "tests.h" #include "util/sample.h" diff --git a/tools/perf/tests/kallsyms-split.c b/tools/perf/tests/kallsyms-split.c index bbbc66957e5d..117ed3b70f63 100644 --- a/tools/perf/tests/kallsyms-split.c +++ b/tools/perf/tests/kallsyms-split.c @@ -148,6 +148,7 @@ static int test__kallsyms_split(struct test_suite *test __maybe_unused, ret = TEST_OK; out: + map__put(map); remove_proc_dir(0); machine__exit(&m); return ret; diff --git a/tools/perf/tests/make b/tools/perf/tests/make index 6641701e4828..6587dc326d1b 100644 --- a/tools/perf/tests/make +++ b/tools/perf/tests/make @@ -70,6 +70,7 @@ make_python_perf_so := $(python_perf_so) make_debug := DEBUG=1 make_nondistro := BUILD_NONDISTRO=1 make_extra_tests := EXTRA_TESTS=1 +make_no_jevents := NO_JEVENTS=1 make_jevents_all := JEVENTS_ARCH=all make_no_bpf_skel := BUILD_BPF_SKEL=0 make_gen_vmlinux_h := GEN_VMLINUX_H=1 @@ -83,9 +84,9 @@ make_no_demangle := NO_DEMANGLE=1 make_no_libelf := NO_LIBELF=1 make_no_libdw := NO_LIBDW=1 make_libunwind := LIBUNWIND=1 -make_no_libdw_dwarf_unwind := NO_LIBDW_DWARF_UNWIND=1 make_no_backtrace := NO_BACKTRACE=1 make_no_libcapstone := NO_CAPSTONE=1 +make_libcapstone_dlopen := LIBCAPSTONE_DLOPEN=1 make_no_libnuma := NO_LIBNUMA=1 make_no_libbionic := NO_LIBBIONIC=1 make_no_libbpf := NO_LIBBPF=1 @@ -120,9 +121,12 @@ make_static := LDFLAGS=-static NO_PERF_READ_VDSO32=1 NO_PERF_READ_VDSOX3 make_minimal := NO_LIBPYTHON=1 NO_GTK2=1 make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_BACKTRACE=1 make_minimal += NO_LIBNUMA=1 NO_LIBBIONIC=1 NO_LIBDW=1 -make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_LIBBPF=1 +make_minimal += NO_LIBBPF=1 make_minimal += NO_SDT=1 NO_JVMTI=1 NO_LIBZSTD=1 -make_minimal += NO_LIBCAP=1 NO_CAPSTONE=1 +make_minimal += NO_CAPSTONE=1 + +# binutils 2_42 and newer have bfd_thread_init() +new_libbfd := $(shell echo '#include ' | $(CC) -E -x c - | grep bfd_thread_init) # $(run) contains all available tests run := make_pure @@ -137,8 +141,11 @@ MAKE_F := $(MAKE) -f $(MK) endif run += make_python_perf_so run += make_debug +ifneq ($(new_libbfd),) run += make_nondistro +endif run += make_extra_tests +run += make_no_jevents run += make_jevents_all run += make_no_bpf_skel run += make_gen_vmlinux_h @@ -155,6 +162,7 @@ run += make_libunwind run += make_no_libdw_dwarf_unwind run += make_no_backtrace run += make_no_libcapstone +run += make_libcapstone_dlopen run += make_no_libnuma run += make_no_libbionic run += make_no_libbpf diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 128d21dc389f..1d3cc224fbc2 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -2609,8 +2609,8 @@ static int test_events(const struct evlist_test *events, int cnt) for (int i = 0; i < cnt; i++) { struct evlist_test e = events[i]; int test_ret; - const char *pos = e.name; - char buf[1024], *buf_pos = buf, *end; + const char *pos = e.name, *end; + char buf[1024], *buf_pos = buf; while ((end = strstr(pos, "default_core"))) { size_t len = end - pos; @@ -2627,7 +2627,7 @@ static int test_events(const struct evlist_test *events, int cnt) pr_debug("running test %d '%s'\n", i, e.name); test_ret = test_event(&e); if (test_ret != TEST_OK) { - pr_debug("Event test failure: test %d '%s'", i, e.name); + pr_debug("Event test failure: test %d '%s'\n", i, e.name); ret = combine_test_results(ret, test_ret); } } @@ -2764,7 +2764,7 @@ static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest test_ret = test_event(&e); if (test_ret != TEST_OK) { - pr_debug("Test PMU event failed for '%s'", name); + pr_debug("Test PMU event failed for '%s'\n", name); ret = combine_test_results(ret, test_ret); } @@ -2790,7 +2790,7 @@ static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest e.check = test__checkevent_pmu_events_mix; test_ret = test_event(&e); if (test_ret != TEST_OK) { - pr_debug("Test PMU event failed for '%s'", name); + pr_debug("Test PMU event failed for '%s'\n", name); ret = combine_test_results(ret, test_ret); } } diff --git a/tools/perf/tests/parse-metric.c b/tools/perf/tests/parse-metric.c index 6bbc209a5c6a..7c7f489a5eb0 100644 --- a/tools/perf/tests/parse-metric.c +++ b/tools/perf/tests/parse-metric.c @@ -41,6 +41,8 @@ static void load_runtime_stat(struct evlist *evlist, struct value *vals) count = find_value(evsel->name, vals); evsel->supported = true; evsel->stats->aggr->counts.val = count; + evsel->stats->aggr->counts.ena = 1; + evsel->stats->aggr->counts.run = 1; } } diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index cbded2c6faa4..0ebf2d7b2cb4 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -192,7 +192,6 @@ static int test__pmu_format(struct test_suite *test __maybe_unused, int subtest } if (attr.config2 != 0x0400000020041d07) { pr_err("Unexpected config2 value %llx\n", attr.config2); - goto err_out; } ret = TEST_OK; @@ -202,6 +201,97 @@ static int test__pmu_format(struct test_suite *test __maybe_unused, int subtest return ret; } +static int test__pmu_usr_chgs(struct test_suite *test __maybe_unused, int subtest __maybe_unused) +{ + const char *event = "perf-pmu-test/config=15,config1=4,krava02=170," + "krava03=1,krava11=27,krava12=1/"; + struct parse_events_terms terms; + struct parse_events_error err; + LIST_HEAD(config_terms); + struct evlist *evlist; + struct perf_pmu *pmu; + struct evsel *evsel; + int ret = TEST_FAIL; + char dir[PATH_MAX]; + u64 val; + + pmu = test_pmu_get(dir, sizeof(dir)); + if (!pmu) + return TEST_FAIL; + + evlist = evlist__new(); + if (evlist == NULL) { + pr_err("Failed allocation"); + goto err_out; + } + + parse_events_terms__init(&terms); + ret = parse_events(evlist, event, &err); + if (ret) { + pr_debug("failed to parse event '%s', err %d\n", event, ret); + parse_events_error__print(&err, event); + if (parse_events_error__contains(&err, "can't access trace events")) + ret = TEST_SKIP; + goto err_out; + } + evsel = evlist__first(evlist); + + /* + * Set via config=15, krava01 bits 0-1 + * Set via config1=4, krava11 bit 1 + * Set values: krava02=170, krava03=1, krava11=27, krava12=1 + * + * Test that already set values aren't overwritten. + */ + evsel__set_config_if_unset(evsel, "krava01", 16); + evsel__get_config_val(evsel, "krava01", &val); + TEST_ASSERT_EQUAL("krava01 overwritten", (int) val, (15 & 0b11)); + + evsel__set_config_if_unset(evsel, "krava11", 45); + evsel__get_config_val(evsel, "krava11", &val); + TEST_ASSERT_EQUAL("krava11 overwritten", (int) val, (27 | (4 << 1))); + + evsel__set_config_if_unset(evsel, "krava02", 32); + evsel__get_config_val(evsel, "krava02", &val); + TEST_ASSERT_EQUAL("krava02 overwritten", (int) val, 170); + + evsel__set_config_if_unset(evsel, "krava03", 0); + evsel__get_config_val(evsel, "krava03", &val); + TEST_ASSERT_EQUAL("krava03 overwritten", (int) val, 1); + + /* + * krava13 doesn't have any bits set by either krava13= or config1= + * but setting _any_ raw value for config1 implies that krava13 + * shouldn't be overwritten. So it's value should remain as 0. + */ + evsel__set_config_if_unset(evsel, "krava13", 5); + evsel__get_config_val(evsel, "krava13", &val); + TEST_ASSERT_EQUAL("krava13 overwritten", (int) val, 0); + + /* + * Unset values: krava21, krava22, krava23 + * + * Test that unset values are overwritten. + */ + evsel__set_config_if_unset(evsel, "krava21", 13905); + evsel__get_config_val(evsel, "krava21", &val); + TEST_ASSERT_EQUAL("krava21 not overwritten", (int) val, 13905); + + evsel__set_config_if_unset(evsel, "krava22", 11); + evsel__get_config_val(evsel, "krava22", &val); + TEST_ASSERT_EQUAL("krava22 not overwritten", (int) val, 11); + + evsel__set_config_if_unset(evsel, "krava23", 0); + evsel__get_config_val(evsel, "krava23", &val); + TEST_ASSERT_EQUAL("krava23 not overwritten", (int) val, 0); + ret = TEST_OK; +err_out: + parse_events_terms__exit(&terms); + evlist__delete(evlist); + test_pmu_put(dir, pmu); + return ret; +} + static int test__pmu_events(struct test_suite *test __maybe_unused, int subtest __maybe_unused) { char dir[PATH_MAX]; @@ -539,6 +629,7 @@ static struct test_case tests__pmu[] = { TEST_CASE("PMU name combining", name_len), TEST_CASE("PMU name comparison", name_cmp), TEST_CASE("PMU cmdline match", pmu_match), + TEST_CASE("PMU user config changes", pmu_usr_chgs), { .name = NULL, } }; diff --git a/tools/perf/tests/shell/addr2line_inlines.sh b/tools/perf/tests/shell/addr2line_inlines.sh new file mode 100755 index 000000000000..e8754ef2d7f2 --- /dev/null +++ b/tools/perf/tests/shell/addr2line_inlines.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# test addr2line inline unwinding +# SPDX-License-Identifier: GPL-2.0 + +set -e + +err=0 +test_dir=$(mktemp -d /tmp/perf-test-inline-addr2line.XXXXXXXXXX) +perf_data="${test_dir}/perf.data" +perf_script_txt="${test_dir}/perf_script.txt" + +cleanup() { + rm -rf "${test_dir}" + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT TERM INT + +test_fp() { + echo "Inline unwinding fp verification test" + # Record data. Currently only dwarf callchains support inlined functions. + perf record --call-graph fp -e task-clock:u -o "${perf_data}" -- perf test -w inlineloop 1 + + # Check output with inline (default) and srcline + perf script -i "${perf_data}" --fields +srcline > "${perf_script_txt}" + + # Expect the leaf and middle functions to occur on lines in the 20s, with + # the non-inlined parent function on a line in the 30s. + if grep -q "inlineloop.c:2. (inlined)" "${perf_script_txt}" && + grep -q "inlineloop.c:3.$" "${perf_script_txt}" + then + echo "Inline unwinding fp verification test [Success]" + else + echo "Inline unwinding fp verification test [Failed missing inlined functions]" + err=1 + fi +} + +test_dwarf() { + echo "Inline unwinding dwarf verification test" + # Record data. Currently only dwarf callchains support inlined functions. + perf record --call-graph dwarf -e task-clock:u -o "${perf_data}" -- perf test -w inlineloop 1 + + # Check output with inline (default) and srcline + perf script -i "${perf_data}" --fields +srcline > "${perf_script_txt}" + + # Expect the leaf and middle functions to occur on lines in the 20s, with + # the non-inlined parent function on a line in the 30s. + if grep -q "inlineloop.c:2. (inlined)" "${perf_script_txt}" && + grep -q "inlineloop.c:3.$" "${perf_script_txt}" + then + echo "Inline unwinding dwarf verification test [Success]" + else + echo "Inline unwinding dwarf verification test [Failed missing inlined functions]" + err=1 + fi +} + +test_lbr() { + echo "Inline unwinding LBR verification test" + if [ ! -f /sys/bus/event_source/devices/cpu/caps/branches ] && + [ ! -f /sys/bus/event_source/devices/cpu_core/caps/branches ] + then + echo "Skip: only x86 CPUs support LBR" + return + fi + + # Record data. Currently only dwarf callchains support inlined functions. + perf record --call-graph lbr -e cycles:u -o "${perf_data}" -- perf test -w inlineloop 1 + + # Check output with inline (default) and srcline + perf script -i "${perf_data}" --fields +srcline > "${perf_script_txt}" + + # Expect the leaf and middle functions to occur on lines in the 20s, with + # the non-inlined parent function on a line in the 30s. + if grep -q "inlineloop.c:2. (inlined)" "${perf_script_txt}" && + grep -q "inlineloop.c:3.$" "${perf_script_txt}" + then + echo "Inline unwinding lbr verification test [Success]" + else + echo "Inline unwinding lbr verification test [Failed missing inlined functions]" + err=1 + fi +} + +test_fp +test_dwarf +test_lbr + +cleanup +exit $err diff --git a/tools/perf/tests/shell/data_type_profiling.sh b/tools/perf/tests/shell/data_type_profiling.sh new file mode 100755 index 000000000000..2a7f8f7c42d0 --- /dev/null +++ b/tools/perf/tests/shell/data_type_profiling.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# perf data type profiling tests +# SPDX-License-Identifier: GPL-2.0 + +set -e + +# The logic below follows the same line as the annotate test, but looks for a +# data type profiling manifestation + +# Values in testtypes and testprogs should match +testtypes=("# data-type: struct Buf" "# data-type: struct _buf") +testprogs=("perf test -w code_with_type" "perf test -w datasym") + +err=0 +perfdata=$(mktemp /tmp/__perf_test.perf.data.XXXXX) +perfout=$(mktemp /tmp/__perf_test.perf.out.XXXXX) + +cleanup() { + rm -rf "${perfdata}" "${perfout}" + rm -rf "${perfdata}".old + + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup EXIT TERM INT + +test_basic_annotate() { + mode=$1 + runtime=$2 + + echo "${mode} ${runtime} perf annotate test" + + case "x${runtime}" in + "xRust") + if ! perf check feature -q rust + then + echo "Skip: code_with_type workload not built in 'perf test'" + return + fi + index=0 ;; + + "xC") + index=1 ;; + esac + + if [ "x${mode}" == "xBasic" ] + then + perf mem record -o "${perfdata}" ${testprogs[$index]} 2> /dev/null + else + perf mem record -o - ${testprogs[$index]} 2> /dev/null > "${perfdata}" + fi + if [ "x$?" != "x0" ] + then + echo "${mode} annotate [Failed: perf record]" + err=1 + return + fi + + # Generate the annotated output file + if [ "x${mode}" == "xBasic" ] + then + perf annotate --code-with-type -i "${perfdata}" --stdio --percent-limit 1 2> /dev/null > "${perfout}" + else + perf annotate --code-with-type -i - --stdio 2> /dev/null --percent-limit 1 < "${perfdata}" > "${perfout}" + fi + + # check if it has the target data type + if ! grep -q "${testtypes[$index]}" "${perfout}" + then + echo "${mode} annotate [Failed: missing target data type]" + cat "${perfout}" + err=1 + return + fi + echo "${mode} annotate test [Success]" +} + +test_basic_annotate Basic Rust +test_basic_annotate Pipe Rust +test_basic_annotate Basic C +test_basic_annotate Pipe C + +cleanup +exit $err diff --git a/tools/perf/tests/shell/evlist.sh b/tools/perf/tests/shell/evlist.sh index 140f099e75c1..8a22f4171c07 100755 --- a/tools/perf/tests/shell/evlist.sh +++ b/tools/perf/tests/shell/evlist.sh @@ -21,13 +21,13 @@ trap trap_cleanup EXIT TERM INT test_evlist_simple() { echo "Simple evlist test" - if ! perf record -e cycles -o "${perfdata}" true 2> /dev/null + if ! perf record -e cpu-clock -o "${perfdata}" true 2> /dev/null then echo "Simple evlist [Failed record]" err=1 return fi - if ! perf evlist -i "${perfdata}" | grep -q "cycles" + if ! perf evlist -i "${perfdata}" | grep -q "cpu-clock" then echo "Simple evlist [Failed to list event]" err=1 @@ -38,13 +38,14 @@ test_evlist_simple() { test_evlist_group() { echo "Group evlist test" - if ! perf record -e "{cycles,instructions}" -o "${perfdata}" true 2> /dev/null + if ! perf record -e "{cpu-clock,task-clock}" -o "${perfdata}" \ + -- perf test -w noploop 2> /dev/null then echo "Group evlist [Skipped event group recording failed]" return fi - if ! perf evlist -i "${perfdata}" -g | grep -q "{.*cycles.*,.*instructions.*}" + if ! perf evlist -i "${perfdata}" -g | grep -q "{.*cpu-clock.*,.*task-clock.*}" then echo "Group evlist [Failed to list event group]" err=1 diff --git a/tools/perf/tests/shell/inject-callchain.sh b/tools/perf/tests/shell/inject-callchain.sh new file mode 100755 index 000000000000..a1cba8010f95 --- /dev/null +++ b/tools/perf/tests/shell/inject-callchain.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# perf inject to convert DWARF callchains to regular ones +# SPDX-License-Identifier: GPL-2.0 + +if ! perf check feature -q dwarf; then + echo "SKIP: DWARF support is not available" + exit 2 +fi + +TESTDATA=$(mktemp /tmp/perf-test.XXXXXX) + +err=0 + +cleanup() +{ + trap - EXIT TERM INT + rm -f ${TESTDATA}* +} + +trap_cleanup() +{ + cleanup + exit 1 +} + +trap trap_cleanup EXIT TERM INT + +echo "recording data with DWARF callchain" +perf record -F 999 --call-graph dwarf -o "${TESTDATA}" -- perf test -w noploop + +echo "convert DWARF callchain using perf inject" +perf inject -i "${TESTDATA}" --convert-callchain -o "${TESTDATA}.new" + +perf report -i "${TESTDATA}" --no-children -q --percent-limit=1 > ${TESTDATA}.out +perf report -i "${TESTDATA}.new" --no-children -q --percent-limit=1 > ${TESTDATA}.new.out + +echo "compare the both result excluding inlined functions" +if diff -u "${TESTDATA}.out" "${TESTDATA}.new.out" | grep "^- " | grep -qv "(inlined)"; then + echo "Found some differences" + diff -u "${TESTDATA}.out" "${TESTDATA}.new.out" + err=1 +fi + +cleanup +exit $err diff --git a/tools/perf/tests/shell/kvm.sh b/tools/perf/tests/shell/kvm.sh index 2a399b83fe80..f88e859025c4 100755 --- a/tools/perf/tests/shell/kvm.sh +++ b/tools/perf/tests/shell/kvm.sh @@ -7,9 +7,10 @@ set -e err=0 perfdata=$(mktemp /tmp/__perf_kvm_test.perf.data.XXXXX) qemu_pid_file=$(mktemp /tmp/__perf_kvm_test.qemu.pid.XXXXX) +log_file=$(mktemp /tmp/__perf_kvm_test.live_log.XXXXX) cleanup() { - rm -f "${perfdata}" + rm -f "${perfdata}" "${log_file}" if [ -f "${qemu_pid_file}" ]; then if [ -s "${qemu_pid_file}" ]; then qemu_pid=$(cat "${qemu_pid_file}") @@ -96,6 +97,32 @@ test_kvm_buildid_list() { echo "perf kvm buildid-list test [Success]" } +test_kvm_stat_live() { + echo "Testing perf kvm stat live" + + # Run perf kvm live for 5 seconds, monitoring that PID + # Use sleep to keep stdin open but silent, preventing EOF loop or interactive spam + if ! sleep 10 | timeout 5s perf kvm stat live -p "${qemu_pid}" > "${log_file}" 2>&1; then + retval=$? + if [ $retval -ne 124 ] && [ $retval -ne 0 ]; then + echo "perf kvm stat live [Failed: perf kvm stat live failed to start or run (ret=$retval)]" + head -n 50 "${log_file}" + err=1 + return + fi + fi + + # Check for some sample data (percentage) + if ! grep -E -q "[0-9]+\.[0-9]+%" "${log_file}"; then + echo "perf kvm stat live [Failed: no sample percentage found]" + head -n 50 "${log_file}" + err=1 + return + fi + + echo "perf kvm stat live test [Success]" +} + setup_qemu() { # Find qemu if [ "$(uname -m)" = "x86_64" ]; then @@ -148,6 +175,7 @@ if [ $err -eq 0 ]; then test_kvm_stat test_kvm_record_report test_kvm_buildid_list + test_kvm_stat_live fi cleanup diff --git a/tools/perf/tests/shell/perf_sched_stats.sh b/tools/perf/tests/shell/perf_sched_stats.sh new file mode 100755 index 000000000000..2b1410b050d0 --- /dev/null +++ b/tools/perf/tests/shell/perf_sched_stats.sh @@ -0,0 +1,64 @@ +#!/bin/sh +# perf sched stats tests +# SPDX-License-Identifier: GPL-2.0 + +set -e + +err=0 +test_perf_sched_stats_record() { + echo "Basic perf sched stats record test" + if ! perf sched stats record true 2>&1 | \ + grep -E -q "[ perf sched stats: Wrote samples to perf.data ]" + then + echo "Basic perf sched stats record test [Failed]" + err=1 + return + fi + echo "Basic perf sched stats record test [Success]" +} + +test_perf_sched_stats_report() { + echo "Basic perf sched stats report test" + perf sched stats record true > /dev/null + if ! perf sched stats report 2>&1 | grep -E -q "Description" + then + echo "Basic perf sched stats report test [Failed]" + err=1 + rm perf.data + return + fi + rm perf.data + echo "Basic perf sched stats report test [Success]" +} + +test_perf_sched_stats_live() { + echo "Basic perf sched stats live mode test" + if ! perf sched stats true 2>&1 | grep -E -q "Description" + then + echo "Basic perf sched stats live mode test [Failed]" + err=1 + return + fi + echo "Basic perf sched stats live mode test [Success]" +} + +test_perf_sched_stats_diff() { + echo "Basic perf sched stats diff test" + perf sched stats record true > /dev/null + perf sched stats record true > /dev/null + if ! perf sched stats diff > /dev/null + then + echo "Basic perf sched stats diff test [Failed]" + err=1 + rm perf.data.old perf.data + return + fi + rm perf.data.old perf.data + echo "Basic perf sched stats diff test [Success]" +} + +test_perf_sched_stats_record +test_perf_sched_stats_report +test_perf_sched_stats_live +test_perf_sched_stats_diff +exit $err diff --git a/tools/perf/tests/shell/record.sh b/tools/perf/tests/shell/record.sh index 0f5841c479e7..7cb81cf3444a 100755 --- a/tools/perf/tests/shell/record.sh +++ b/tools/perf/tests/shell/record.sh @@ -260,7 +260,21 @@ test_uid() { test_leader_sampling() { echo "Basic leader sampling test" - if ! perf record -o "${perfdata}" -e "{cycles,cycles}:Su" -- \ + events="{cycles,cycles}:Su" + [ "$(uname -m)" = "s390x" ] && { + [ ! -d /sys/devices/cpum_sf ] && { + echo "No CPUMF [Skipped record]" + return + } + events="{cpum_sf/SF_CYCLES_BASIC/,cycles}:Su" + perf record -o "${perfdata}" -e "$events" -- perf test -w brstack 2> /dev/null + # Perf grouping might be unsupported, depends on version. + [ "$?" -ne 0 ] && { + echo "Grouping not support [Skipped record]" + return + } + } + if ! perf record -o "${perfdata}" -e "$events" -- \ perf test -w brstack 2> /dev/null then echo "Leader sampling [Failed record]" diff --git a/tools/perf/tests/shell/sched.sh b/tools/perf/tests/shell/sched.sh index b9b81eaf856e..b9637069adb1 100755 --- a/tools/perf/tests/shell/sched.sh +++ b/tools/perf/tests/shell/sched.sh @@ -53,7 +53,7 @@ start_noploops() { } cleanup_noploops() { - kill "$PID1" "$PID2" + kill "$PID1" "$PID2" || true } test_sched_record() { diff --git a/tools/perf/tests/shell/script_dlfilter.sh b/tools/perf/tests/shell/script_dlfilter.sh index 45c97d4a7d5f..aaed92bb7828 100755 --- a/tools/perf/tests/shell/script_dlfilter.sh +++ b/tools/perf/tests/shell/script_dlfilter.sh @@ -68,17 +68,17 @@ test_dlfilter() { fi # Build the dlfilter - if ! cc -c -I tools/perf/include -fpic -x c "${dlfilter_c}" -o "${dlfilter_so}.o" + if ! cc -c -I ${shelldir}/../../include -fpic -x c "${dlfilter_c}" -o "${dlfilter_so}.o" then - echo "Basic --dlfilter test [Failed to build dlfilter object]" - err=1 + echo "Basic --dlfilter test [Skip - failed to build dlfilter object]" + err=2 return fi if ! cc -shared -o "${dlfilter_so}" "${dlfilter_so}.o" then - echo "Basic --dlfilter test [Failed to link dlfilter shared object]" - err=1 + echo "Basic --dlfilter test [Skip - failed to link dlfilter shared object]" + err=2 return fi diff --git a/tools/perf/tests/shell/script_perl.sh b/tools/perf/tests/shell/script_perl.sh new file mode 100755 index 000000000000..b6d65b6fbda1 --- /dev/null +++ b/tools/perf/tests/shell/script_perl.sh @@ -0,0 +1,102 @@ +#!/bin/bash +# perf script perl tests +# SPDX-License-Identifier: GPL-2.0 + +set -e + +# set PERF_EXEC_PATH to find scripts in the source directory +perfdir=$(dirname "$0")/../.. +if [ -e "$perfdir/scripts/perl/Perf-Trace-Util" ]; then + export PERF_EXEC_PATH=$perfdir +fi + + +perfdata=$(mktemp /tmp/__perf_test_script_perl.perf.data.XXXXX) +generated_script=$(mktemp /tmp/__perf_test_script.XXXXX.pl) + +cleanup() { + rm -f "${perfdata}" + rm -f "${generated_script}" + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup TERM INT +trap cleanup EXIT + +check_perl_support() { + if perf check feature -q libperl; then + return 0 + fi + echo "perf script perl test [Skipped: no libperl support]" + return 2 +} + +test_script() { + local event_name=$1 + local expected_output=$2 + local record_opts=$3 + + echo "Testing event: $event_name" + + # Try to record. If this fails, it might be permissions or lack of support. + # We return 2 to indicate "skip this event" rather than "fail test". + if ! perf record -o "${perfdata}" -e "$event_name" $record_opts -- perf test -w thloop > /dev/null 2>&1; then + echo "perf script perl test [Skipped: failed to record $event_name]" + return 2 + fi + + echo "Generating perl script..." + if ! perf script -i "${perfdata}" -g "${generated_script}"; then + echo "perf script perl test [Failed: script generation for $event_name]" + return 1 + fi + + if [ ! -f "${generated_script}" ]; then + echo "perf script perl test [Failed: script not generated for $event_name]" + return 1 + fi + + echo "Executing perl script..." + output=$(perf script -i "${perfdata}" -s "${generated_script}" 2>&1) + + if echo "$output" | grep -q "$expected_output"; then + echo "perf script perl test [Success: $event_name triggered $expected_output]" + return 0 + else + echo "perf script perl test [Failed: $event_name did not trigger $expected_output]" + echo "Output was:" + echo "$output" | head -n 20 + return 1 + fi +} + +check_perl_support || exit 2 + +# Try tracepoint first +test_script "sched:sched_switch" "sched::sched_switch" "-c 1" && res=0 || res=$? + +if [ $res -eq 0 ]; then + exit 0 +elif [ $res -eq 1 ]; then + exit 1 +fi + +# If tracepoint skipped (res=2), try task-clock +# For generic events like task-clock, the generated script uses process_event() +# which dumps data using Data::Dumper. We check for "$VAR1" which is standard Dumper output. +test_script "task-clock" "\$VAR1" "-c 100" && res=0 || res=$? + +if [ $res -eq 0 ]; then + exit 0 +elif [ $res -eq 1 ]; then + exit 1 +fi + +# If both skipped +echo "perf script perl test [Skipped: Could not record tracepoint or task-clock]" +exit 2 diff --git a/tools/perf/tests/shell/script_python.sh b/tools/perf/tests/shell/script_python.sh new file mode 100755 index 000000000000..6bc66074a31f --- /dev/null +++ b/tools/perf/tests/shell/script_python.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# perf script python tests +# SPDX-License-Identifier: GPL-2.0 + +set -e + +# set PERF_EXEC_PATH to find scripts in the source directory +perfdir=$(dirname "$0")/../.. +if [ -e "$perfdir/scripts/python/Perf-Trace-Util" ]; then + export PERF_EXEC_PATH=$perfdir +fi + + +perfdata=$(mktemp /tmp/__perf_test_script_python.perf.data.XXXXX) +generated_script=$(mktemp /tmp/__perf_test_script.XXXXX.py) + +cleanup() { + rm -f "${perfdata}" + rm -f "${generated_script}" + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} +trap trap_cleanup TERM INT +trap cleanup EXIT + +check_python_support() { + if perf check feature -q libpython; then + return 0 + fi + echo "perf script python test [Skipped: no libpython support]" + return 2 +} + +test_script() { + local event_name=$1 + local expected_output=$2 + local record_opts=$3 + + echo "Testing event: $event_name" + + # Try to record. If this fails, it might be permissions or lack of + # support. Return 2 to indicate "skip this event" rather than "fail + # test". + if ! perf record -o "${perfdata}" -e "$event_name" $record_opts -- perf test -w thloop > /dev/null 2>&1; then + echo "perf script python test [Skipped: failed to record $event_name]" + return 2 + fi + + echo "Generating python script..." + if ! perf script -i "${perfdata}" -g "${generated_script}"; then + echo "perf script python test [Failed: script generation for $event_name]" + return 1 + fi + + if [ ! -f "${generated_script}" ]; then + echo "perf script python test [Failed: script not generated for $event_name]" + return 1 + fi + + # Perf script -g python doesn't generate process_event for generic + # events so append it manually to test that the callback works. + if ! grep -q "def process_event" "${generated_script}"; then + cat <> "${generated_script}" + +def process_event(param_dict): + print("param_dict: %s" % param_dict) +EOF + fi + + echo "Executing python script..." + output=$(perf script -i "${perfdata}" -s "${generated_script}" 2>&1) + + if echo "$output" | grep -q "$expected_output"; then + echo "perf script python test [Success: $event_name triggered $expected_output]" + return 0 + else + echo "perf script python test [Failed: $event_name did not trigger $expected_output]" + echo "Output was:" + echo "$output" | head -n 20 + return 1 + fi +} + +check_python_support || exit 2 + +# Try tracepoint first +test_script "sched:sched_switch" "sched__sched_switch" "-c 1" && res=0 || res=$? + +if [ $res -eq 0 ]; then + exit 0 +elif [ $res -eq 1 ]; then + exit 1 +fi + +# If tracepoint skipped (res=2), try task-clock +# For generic events like task-clock, the generated script uses process_event() +# which prints the param_dict. +test_script "task-clock" "param_dict" "-c 100" && res=0 || res=$? + +if [ $res -eq 0 ]; then + exit 0 +elif [ $res -eq 1 ]; then + exit 1 +fi + +# If both skipped +echo "perf script python test [Skipped: Could not record tracepoint or task-clock]" +exit 2 diff --git a/tools/perf/tests/shell/stat.sh b/tools/perf/tests/shell/stat.sh index 0b2f0f88ca16..4edb04039036 100755 --- a/tools/perf/tests/shell/stat.sh +++ b/tools/perf/tests/shell/stat.sh @@ -5,6 +5,21 @@ set -e err=0 +stat_output=$(mktemp /tmp/perf-stat-test-output.XXXXX) + +cleanup() { + rm -f "${stat_output}" + trap - EXIT TERM INT +} + +trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" + cleanup + exit 1 +} + +trap trap_cleanup EXIT TERM INT + test_default_stat() { echo "Basic stat command test" if ! perf stat true 2>&1 | grep -E -q "Performance counter stats for 'true':" @@ -233,7 +248,7 @@ test_hybrid() { fi # Run default Perf stat - cycles_events=$(perf stat -a -- sleep 0.1 2>&1 | grep -E "/cpu-cycles/[uH]*| cpu-cycles[:uH]* " -c) + cycles_events=$(perf stat -a -- sleep 0.1 2>&1 | grep -E "/cpu-cycles/[uH]*| cpu-cycles[:uH]* " | wc -l) # The expectation is that default output will have a cycles events on each # hybrid PMU. In situations with no cycles PMU events, like virtualized, this @@ -248,6 +263,226 @@ test_hybrid() { echo "hybrid test [Success]" } +test_stat_cpu() { + echo "stat -C test" + # Test the full online CPU list (ranges and lists) + online_cpus=$(cat /sys/devices/system/cpu/online) + if ! perf stat -C "$online_cpus" -a true > "${stat_output}" 2>&1 + then + echo "stat -C test [Failed - command failed for cpus $online_cpus]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "Performance counter stats for" "${stat_output}" + then + echo "stat -C test [Failed - missing output for cpus $online_cpus]" + cat "${stat_output}" + err=1 + return + fi + + # Test each individual online CPU + for cpu_dir in /sys/devices/system/cpu/cpu[0-9]*; do + cpu=${cpu_dir##*/cpu} + # Check if online + if [ -f "$cpu_dir/online" ] && [ "$(cat "$cpu_dir/online")" -eq 0 ] + then + continue + fi + + if ! perf stat -C "$cpu" -a true > "${stat_output}" 2>&1 + then + echo "stat -C test [Failed - command failed for cpu $cpu]" + cat "${stat_output}" + err=1 + return + fi + if ! grep -E -q "Performance counter stats for" "${stat_output}" + then + echo "stat -C test [Failed - missing output for cpu $cpu]" + cat "${stat_output}" + err=1 + return + fi + done + + # Test synthetic list and range if cpu0 and cpu1 are online + c0_online=0 + c1_online=0 + if [ -d "/sys/devices/system/cpu/cpu0" ] + then + if [ ! -f "/sys/devices/system/cpu/cpu0/online" ] || [ "$(cat /sys/devices/system/cpu/cpu0/online)" -eq 1 ] + then + c0_online=1 + fi + fi + if [ -d "/sys/devices/system/cpu/cpu1" ] + then + if [ ! -f "/sys/devices/system/cpu/cpu1/online" ] || [ "$(cat /sys/devices/system/cpu/cpu1/online)" -eq 1 ] + then + c1_online=1 + fi + fi + + if [ $c0_online -eq 1 ] && [ $c1_online -eq 1 ] + then + # Test list "0,1" + if ! perf stat -C "0,1" -a true > "${stat_output}" 2>&1 + then + echo "stat -C test [Failed - command failed for cpus 0,1]" + cat "${stat_output}" + err=1 + return + fi + if ! grep -E -q "Performance counter stats for" "${stat_output}" + then + echo "stat -C test [Failed - missing output for cpus 0,1]" + cat "${stat_output}" + err=1 + return + fi + + # Test range "0-1" + if ! perf stat -C "0-1" -a true > "${stat_output}" 2>&1 + then + echo "stat -C test [Failed - command failed for cpus 0-1]" + cat "${stat_output}" + err=1 + return + fi + if ! grep -E -q "Performance counter stats for" "${stat_output}" + then + echo "stat -C test [Failed - missing output for cpus 0-1]" + cat "${stat_output}" + err=1 + return + fi + fi + + echo "stat -C test [Success]" +} + +test_stat_no_aggr() { + echo "stat -A test" + if ! perf stat -A -a true > "${stat_output}" 2>&1 + then + echo "stat -A test [Failed - command failed]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "CPU" "${stat_output}" + then + echo "stat -A test [Failed - missing CPU column]" + cat "${stat_output}" + err=1 + return + fi + echo "stat -A test [Success]" +} + +test_stat_detailed() { + echo "stat -d test" + if ! perf stat -d true > "${stat_output}" 2>&1 + then + echo "stat -d test [Failed - command failed]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "Performance counter stats" "${stat_output}" + then + echo "stat -d test [Failed - missing output]" + cat "${stat_output}" + err=1 + return + fi + + if ! perf stat -dd true > "${stat_output}" 2>&1 + then + echo "stat -dd test [Failed - command failed]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "Performance counter stats" "${stat_output}" + then + echo "stat -dd test [Failed - missing output]" + cat "${stat_output}" + err=1 + return + fi + + if ! perf stat -ddd true > "${stat_output}" 2>&1 + then + echo "stat -ddd test [Failed - command failed]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "Performance counter stats" "${stat_output}" + then + echo "stat -ddd test [Failed - missing output]" + cat "${stat_output}" + err=1 + return + fi + + echo "stat -d test [Success]" +} + +test_stat_repeat() { + echo "stat -r test" + if ! perf stat -r 2 true > "${stat_output}" 2>&1 + then + echo "stat -r test [Failed - command failed]" + cat "${stat_output}" + err=1 + return + fi + + if ! grep -E -q "\([[:space:]]*\+-.*%[[:space:]]*\)" "${stat_output}" + then + echo "stat -r test [Failed - missing variance]" + cat "${stat_output}" + err=1 + return + fi + echo "stat -r test [Success]" +} + +test_stat_pid() { + echo "stat -p test" + sleep 1 & + pid=$! + if ! perf stat -p $pid > "${stat_output}" 2>&1 + then + echo "stat -p test [Failed - command failed]" + cat "${stat_output}" + err=1 + kill $pid 2>/dev/null || true + wait $pid 2>/dev/null || true + return + fi + + if ! grep -E -q "Performance counter stats" "${stat_output}" + then + echo "stat -p test [Failed - missing output]" + cat "${stat_output}" + err=1 + else + echo "stat -p test [Success]" + fi + kill $pid 2>/dev/null || true + wait $pid 2>/dev/null || true +} + test_default_stat test_null_stat test_offline_cpu_stat @@ -258,4 +493,11 @@ test_topdown_groups test_topdown_weak_groups test_cputype test_hybrid +test_stat_cpu +test_stat_no_aggr +test_stat_detailed +test_stat_repeat +test_stat_pid + +cleanup exit $err diff --git a/tools/perf/tests/shell/stat_all_metricgroups.sh b/tools/perf/tests/shell/stat_all_metricgroups.sh index 1400880ec01f..81bc7070b5ab 100755 --- a/tools/perf/tests/shell/stat_all_metricgroups.sh +++ b/tools/perf/tests/shell/stat_all_metricgroups.sh @@ -12,31 +12,32 @@ if ParanoidAndNotRoot 0 then system_wide_flag="" fi -err=0 + +err=3 +skip=0 for m in $(perf list --raw-dump metricgroups) do echo "Testing $m" result=$(perf stat -M "$m" $system_wide_flag sleep 0.01 2>&1) result_err=$? - if [[ $result_err -gt 0 ]] + if [[ $result_err -eq 0 ]] then + if [[ "$err" -ne 1 ]] + then + err=0 + fi + else if [[ "$result" =~ \ "Access to performance monitoring and observability operations is limited" ]] then echo "Permission failure" echo $result - if [[ $err -eq 0 ]] - then - err=2 # Skip - fi + skip=1 elif [[ "$result" =~ "in per-thread mode, enable system wide" ]] then echo "Permissions - need system wide mode" echo $result - if [[ $err -eq 0 ]] - then - err=2 # Skip - fi + skip=1 elif [[ "$m" == @(Default2|Default3|Default4) ]] then echo "Ignoring failures in $m that may contain unsupported legacy events" @@ -48,4 +49,9 @@ do fi done +if [[ "$err" -eq 3 && "$skip" -eq 1 ]] +then + err=2 +fi + exit $err diff --git a/tools/perf/tests/shell/stat_all_metrics.sh b/tools/perf/tests/shell/stat_all_metrics.sh index 3dabb39c7cc8..b582d23f28c9 100755 --- a/tools/perf/tests/shell/stat_all_metrics.sh +++ b/tools/perf/tests/shell/stat_all_metrics.sh @@ -15,7 +15,8 @@ then test_prog="perf test -w noploop" fi -err=0 +skip=0 +err=3 for m in $(perf list --raw-dump metrics); do echo "Testing $m" result=$(perf stat -M "$m" $system_wide_flag -- $test_prog 2>&1) @@ -23,6 +24,10 @@ for m in $(perf list --raw-dump metrics); do if [[ $result_err -eq 0 && "$result" =~ ${m:0:50} ]] then # No error result and metric shown. + if [[ "$err" -ne 1 ]] + then + err=0 + fi continue fi if [[ "$result" =~ "Cannot resolve IDs for" || "$result" =~ "No supported events found" ]] @@ -44,7 +49,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue elif [[ "$result" =~ "in per-thread mode, enable system wide" ]] @@ -53,7 +58,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue elif [[ "$result" =~ "" ]] @@ -68,7 +73,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue elif [[ "$result" =~ "" ]] @@ -77,7 +82,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue elif [[ "$result" =~ "FP_ARITH" || "$result" =~ "AMX" ]] @@ -86,7 +91,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue elif [[ "$result" =~ "PMM" ]] @@ -95,7 +100,7 @@ for m in $(perf list --raw-dump metrics); do echo $result if [[ $err -eq 0 ]] then - err=2 # Skip + skip=1 fi continue fi @@ -106,6 +111,10 @@ for m in $(perf list --raw-dump metrics); do if [[ $result_err -eq 0 && "$result" =~ ${m:0:50} ]] then # No error result and metric shown. + if [[ "$err" -ne 1 ]] + then + err=0 + fi continue fi echo "[Failed $m] has non-zero error '$result_err' or not printed in:" @@ -113,4 +122,10 @@ for m in $(perf list --raw-dump metrics); do err=1 done +# return SKIP only if no success returned +if [[ "$err" -eq 3 && "$skip" -eq 1 ]] +then + err=2 +fi + exit "$err" diff --git a/tools/perf/tests/shell/test_arm_coresight.sh b/tools/perf/tests/shell/test_arm_coresight.sh index 1c750b67d141..bbf89e944e7b 100755 --- a/tools/perf/tests/shell/test_arm_coresight.sh +++ b/tools/perf/tests/shell/test_arm_coresight.sh @@ -198,6 +198,58 @@ arm_cs_etm_basic_test() { arm_cs_report "CoreSight basic testing with '$*'" $err } +arm_cs_etm_test_cpu_list() { + echo "Testing sparse CPU list: $1" + perf record -o ${perfdata} -e cs_etm//u -C $1 \ + -- taskset --cpu-list $1 true > /dev/null 2>&1 + perf_script_branch_samples true + err=$? + arm_cs_report "CoreSight sparse CPUs with '$*'" $err +} + +arm_cs_etm_sparse_cpus_test() { + # Iterate for every ETM device + cpus=() + for dev in /sys/bus/event_source/devices/cs_etm/cpu*; do + # Canonicalize the path + dev=`readlink -f $dev` + + # Find the ETM device belonging to which CPU + cpus+=("$(cat $dev/cpu)") + done + + mapfile -t cpus < <(printf '%s\n' "${cpus[@]}" | sort -n) + total=${#cpus[@]} + + # Need more than 1 to test + if [ $total -le 1 ]; then + return 0 + fi + + half=$((total / 2)) + + # First half + first_half=$(IFS=,; echo "${cpus[*]:0:$half}") + arm_cs_etm_test_cpu_list $first_half + + # Second half + second_half=$(IFS=,; echo "${cpus[*]:$half}") + arm_cs_etm_test_cpu_list $second_half + + # Odd list is the same as halves unless >= 4 CPUs + if [ $total -lt 4 ]; then + return 0 + fi + + # Odd indices + odd_cpus=() + for ((i=1; i "$perfdata" + then + echo "Failed to record perf data" + err=1 + return + fi + + if ! perf data convert --to-ctf "$ctf_dir" --force -i "$perfdata" + then + echo "Perf Data Converter Command to CTF (Pipe mode) [FAILED]" + err=1 + return + fi + + if [ -d "${ctf_dir}" ] && [ "$(ls -A "${ctf_dir}")" ] + then + echo "Perf Data Converter Command to CTF (Pipe mode) [SUCCESS]" + else + echo "Perf Data Converter Command to CTF (Pipe mode) [FAILED]" + echo " Output directory empty or missing" + err=1 + fi +} + +check_babeltrace_support +test_ctf_converter_file +test_ctf_converter_pipe + +exit ${err} diff --git a/tools/perf/tests/shell/test_perf_data_converter_json.sh b/tools/perf/tests/shell/test_perf_data_converter_json.sh index c4f1b59d116f..35d81e39a26c 100755 --- a/tools/perf/tests/shell/test_perf_data_converter_json.sh +++ b/tools/perf/tests/shell/test_perf_data_converter_json.sh @@ -15,29 +15,42 @@ result=$(mktemp /tmp/__perf_test.output.json.XXXXX) cleanup() { - rm -f "${perfdata}" + rm -f "${perfdata}*" rm -f "${result}" trap - exit term int } trap_cleanup() { + echo "Unexpected signal in ${FUNCNAME[1]}" cleanup - exit ${err} + exit 1 } trap trap_cleanup exit term int test_json_converter_command() { - echo "Testing Perf Data Convertion Command to JSON" - perf record -o "$perfdata" -F 99 -g -- perf test -w noploop > /dev/null 2>&1 - perf data convert --to-json "$result" --force -i "$perfdata" >/dev/null 2>&1 + echo "Testing Perf Data Conversion Command to JSON" + perf record -o "$perfdata" -F 99 -g -- perf test -w noploop + perf data convert --to-json "$result" --force -i "$perfdata" if [ "$(cat ${result} | wc -l)" -gt "0" ] ; then echo "Perf Data Converter Command to JSON [SUCCESS]" else echo "Perf Data Converter Command to JSON [FAILED]" err=1 - exit + fi +} + +test_json_converter_pipe() +{ + echo "Testing Perf Data Conversion Command to JSON (Pipe mode)" + perf record -o - -F 99 -g -- perf test -w noploop > "$perfdata" + cat "$perfdata" | perf data convert --to-json "$result" --force -i - + if [ "$(cat ${result} | wc -l)" -gt "0" ] ; then + echo "Perf Data Converter Command to JSON (Pipe mode) [SUCCESS]" + else + echo "Perf Data Converter Command to JSON (Pipe mode) [FAILED]" + err=1 fi } @@ -50,16 +63,18 @@ validate_json_format() else echo "The file does not contain valid JSON format [FAILED]" err=1 - exit fi else echo "File not found [FAILED]" - err=2 - exit + err=1 fi } test_json_converter_command validate_json_format +test_json_converter_pipe +validate_json_format + +cleanup exit ${err} diff --git a/tools/perf/tests/subcmd-help.c b/tools/perf/tests/subcmd-help.c index 2280b4c0e5e7..9da96a16fd20 100644 --- a/tools/perf/tests/subcmd-help.c +++ b/tools/perf/tests/subcmd-help.c @@ -95,10 +95,36 @@ static int test__exclude_cmdnames(struct test_suite *test __maybe_unused, return TEST_OK; } +static int test__exclude_cmdnames_no_overlap(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + struct cmdnames cmds1 = {}; + struct cmdnames cmds2 = {}; + + add_cmdname(&cmds1, "read-vdso32", 11); + add_cmdname(&cmds2, "archive", 7); + + TEST_ASSERT_VAL("invalid original size", cmds1.cnt == 1); + TEST_ASSERT_VAL("invalid original size", cmds2.cnt == 1); + + exclude_cmds(&cmds1, &cmds2); + + TEST_ASSERT_VAL("invalid excluded size", cmds1.cnt == 1); + TEST_ASSERT_VAL("invalid excluded size", cmds2.cnt == 1); + + TEST_ASSERT_VAL("cannot find cmd", is_in_cmdlist(&cmds1, "read-vdso32") == 1); + TEST_ASSERT_VAL("wrong cmd", is_in_cmdlist(&cmds1, "archive") == 0); + + clean_cmdnames(&cmds1); + clean_cmdnames(&cmds2); + return TEST_OK; +} + static struct test_case tests__subcmd_help[] = { TEST_CASE("Load subcmd names", load_cmdnames), TEST_CASE("Uniquify subcmd names", uniq_cmdnames), TEST_CASE("Exclude duplicate subcmd names", exclude_cmdnames), + TEST_CASE("Exclude disjoint subcmd names", exclude_cmdnames_no_overlap), { .name = NULL, } }; diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 4a2ad7176fa0..b6e46975379c 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "tests.h" @@ -28,7 +29,7 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) { int i, err = -1; - volatile int tmp = 0; + volatile int tmp __maybe_unused = 0; u64 total_periods = 0; int nr_samples = 0; char sbuf[STRERR_BUFSIZE]; diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index cb67ddbd0375..f5f1238d1f7f 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -240,6 +240,11 @@ DECLARE_WORKLOAD(brstack); DECLARE_WORKLOAD(datasym); DECLARE_WORKLOAD(landlock); DECLARE_WORKLOAD(traploop); +DECLARE_WORKLOAD(inlineloop); + +#ifdef HAVE_RUST_SUPPORT +DECLARE_WORKLOAD(code_with_type); +#endif extern const char *dso_to_test; extern const char *test_objdump_path; diff --git a/tools/perf/tests/util.c b/tools/perf/tests/util.c index b273d287e164..bf2c5b133884 100644 --- a/tools/perf/tests/util.c +++ b/tools/perf/tests/util.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "tests.h" +#include "util/blake2s.h" #include "util/debug.h" -#include "util/sha1.h" #include #include @@ -17,45 +17,72 @@ static int test_strreplace(char needle, const char *haystack, return ret == 0; } -#define MAX_LEN 512 +/* Maximum data length tested by test_blake2s() */ +#define MAX_DATA_LEN 512 -/* Test sha1() for all lengths from 0 to MAX_LEN inclusively. */ -static int test_sha1(void) +/* + * Hash length tested by test_blake2s(). BLAKE2s supports variable-length + * hashes. However, the only user of BLAKE2s in 'perf' uses 20-byte hashes, + * matching the length of the ELF build ID field. So that's the length we test. + */ +#define HASH_LEN 20 + +/* Test the implementation of the BLAKE2s hash algorithm. */ +static int test_blake2s(void) { - u8 data[MAX_LEN]; - size_t digests_size = (MAX_LEN + 1) * SHA1_DIGEST_SIZE; - u8 *digests; - u8 digest_of_digests[SHA1_DIGEST_SIZE]; + u8 data[MAX_DATA_LEN]; + u8 hash[HASH_LEN]; + u8 hash2[HASH_LEN]; + struct blake2s_ctx main_ctx; /* - * The correctness of this value was verified by running this test with - * sha1() replaced by OpenSSL's SHA1(). + * This value was generated by the following Python code: + * + * import hashlib + * + * data = bytes(i % 256 for i in range(513)) + * h = hashlib.blake2s(digest_size=20) + * for i in range(513): + * h.update(hashlib.blake2s(data=data[:i], digest_size=20).digest()) + * print(h.hexdigest()) */ - static const u8 expected_digest_of_digests[SHA1_DIGEST_SIZE] = { - 0x74, 0xcd, 0x4c, 0xb9, 0xd8, 0xa6, 0xd5, 0x95, 0x22, 0x8b, - 0x7e, 0xd6, 0x8b, 0x7e, 0x46, 0x95, 0x31, 0x9b, 0xa2, 0x43, + static const u8 expected_hash_of_hashes[20] = { + 0xef, 0x9b, 0x13, 0x98, 0x78, 0x8e, 0x74, 0x59, 0x9c, 0xd5, + 0x0c, 0xf0, 0x33, 0x97, 0x79, 0x3d, 0x3e, 0xd0, 0x95, 0xa6 }; size_t i; - digests = malloc(digests_size); - TEST_ASSERT_VAL("failed to allocate digests", digests != NULL); - - /* Generate MAX_LEN bytes of data. */ - for (i = 0; i < MAX_LEN; i++) + /* Generate MAX_DATA_LEN bytes of data. */ + for (i = 0; i < MAX_DATA_LEN; i++) data[i] = i; - /* Calculate a SHA-1 for each length 0 through MAX_LEN inclusively. */ - for (i = 0; i <= MAX_LEN; i++) - sha1(data, i, &digests[i * SHA1_DIGEST_SIZE]); + blake2s_init(&main_ctx, sizeof(hash)); + for (i = 0; i <= MAX_DATA_LEN; i++) { + struct blake2s_ctx ctx; - /* Calculate digest of all digests calculated above. */ - sha1(digests, digests_size, digest_of_digests); + /* Compute the BLAKE2s hash of 'i' data bytes. */ + blake2s_init(&ctx, HASH_LEN); + blake2s_update(&ctx, data, i); + blake2s_final(&ctx, hash); - free(digests); + /* Verify that multiple updates produce the same result. */ + blake2s_init(&ctx, HASH_LEN); + blake2s_update(&ctx, data, i / 2); + blake2s_update(&ctx, &data[i / 2], i - (i / 2)); + blake2s_final(&ctx, hash2); + TEST_ASSERT_VAL("inconsistent BLAKE2s hashes", + memcmp(hash, hash2, HASH_LEN) == 0); - /* Check for the expected result. */ - TEST_ASSERT_VAL("wrong output from sha1()", - memcmp(digest_of_digests, expected_digest_of_digests, - SHA1_DIGEST_SIZE) == 0); + /* + * Pass the hash to another BLAKE2s context, so that we + * incrementally compute the hash of all the hashes. + */ + blake2s_update(&main_ctx, hash, HASH_LEN); + } + + /* Verify the hash of all the hashes. */ + blake2s_final(&main_ctx, hash); + TEST_ASSERT_VAL("wrong BLAKE2s hashes", + memcmp(hash, expected_hash_of_hashes, HASH_LEN) == 0); return 0; } @@ -68,7 +95,7 @@ static int test__util(struct test_suite *t __maybe_unused, int subtest __maybe_u TEST_ASSERT_VAL("replace long", test_strreplace('a', "abcabc", "longlong", "longlongbclonglongbc")); - return test_sha1(); + return test_blake2s(); } DEFINE_SUITE("util", util); diff --git a/tools/perf/tests/workloads/Build b/tools/perf/tests/workloads/Build index fb1012cc4fc3..2ef97f7affce 100644 --- a/tools/perf/tests/workloads/Build +++ b/tools/perf/tests/workloads/Build @@ -8,9 +8,16 @@ perf-test-y += brstack.o perf-test-y += datasym.o perf-test-y += landlock.o perf-test-y += traploop.o +perf-test-y += inlineloop.o + +ifeq ($(CONFIG_RUST_SUPPORT),y) + perf-test-y += code_with_type.o + perf-test-y += code_with_type.a +endif CFLAGS_sqrtloop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_leafloop.o = -g -O0 -fno-inline -fno-omit-frame-pointer -U_FORTIFY_SOURCE CFLAGS_brstack.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_datasym.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE CFLAGS_traploop.o = -g -O0 -fno-inline -U_FORTIFY_SOURCE +CFLAGS_inlineloop.o = -g -O2 diff --git a/tools/perf/tests/workloads/code_with_type.c b/tools/perf/tests/workloads/code_with_type.c new file mode 100644 index 000000000000..65d7be7dac24 --- /dev/null +++ b/tools/perf/tests/workloads/code_with_type.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include "../tests.h" + +extern void test_rs(uint count); + +static volatile sig_atomic_t done; + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +static int code_with_type(int argc, const char **argv) +{ + int sec = 1, num_loops = 100; + + pthread_setname_np(pthread_self(), "perf-code-with-type"); + if (argc > 0) + sec = atoi(argv[0]); + + if (argc > 1) + num_loops = atoi(argv[1]); + + signal(SIGINT, sighandler); + signal(SIGALRM, sighandler); + alarm(sec); + + /* + * Rust doesn't have signal management in the standard library. To + * not deal with any external crates, offload signal handling to the + * outside code. + */ + while (!done) { + test_rs(num_loops); + continue; + } + + return 0; +} + +DEFINE_WORKLOAD(code_with_type); diff --git a/tools/perf/tests/workloads/code_with_type.rs b/tools/perf/tests/workloads/code_with_type.rs new file mode 100644 index 000000000000..3dab39b22dd7 --- /dev/null +++ b/tools/perf/tests/workloads/code_with_type.rs @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +// We're going to look for this structure in the data type profiling report +#[allow(dead_code)] +struct Buf { + data1: u64, + data2: String, + data3: u64, +} + +#[no_mangle] +pub extern "C" fn test_rs(count: u32) { + let mut b = Buf { + data1: 0, + data2: String::from("data"), + data3: 0, + }; + + for _ in 1..count { + b.data1 += 1; + if b.data1 == 123 { + b.data1 += 1; + } + + b.data3 += b.data1; + } +} diff --git a/tools/perf/tests/workloads/inlineloop.c b/tools/perf/tests/workloads/inlineloop.c new file mode 100644 index 000000000000..bc82dfc7c410 --- /dev/null +++ b/tools/perf/tests/workloads/inlineloop.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include "../tests.h" + +static volatile int a; +static volatile sig_atomic_t done; + +static void sighandler(int sig __maybe_unused) +{ + done = 1; +} + +static inline void __attribute__((always_inline)) leaf(int b) +{ +again: + a += b; + if (!done) + goto again; +} + +static inline void __attribute__((always_inline)) middle(int b) +{ + leaf(b); +} + +static noinline void parent(int b) +{ + middle(b); +} + +static int inlineloop(int argc, const char **argv) +{ + int sec = 1; + + pthread_setname_np(pthread_self(), "perf-inlineloop"); + if (argc > 0) + sec = atoi(argv[0]); + + signal(SIGINT, sighandler); + signal(SIGALRM, sighandler); + alarm(sec); + + parent(sec); + + return 0; +} + +DEFINE_WORKLOAD(inlineloop); diff --git a/tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h b/tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h index 6e1d5b955aae..85253fc8e384 100644 --- a/tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h +++ b/tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h @@ -77,6 +77,7 @@ */ #define IRQ_WORK_VECTOR 0xf6 +/* IRQ vector for PMIs when running a guest with a mediated PMU. */ #define PERF_GUEST_MEDIATED_PMI_VECTOR 0xf5 #define DEFERRED_ERROR_VECTOR 0xf4 diff --git a/tools/perf/trace/beauty/include/uapi/linux/fs.h b/tools/perf/trace/beauty/include/uapi/linux/fs.h index 66ca526cf786..70b2b661f42c 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fs.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fs.h @@ -253,6 +253,7 @@ struct file_attr { #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ #define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */ #define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size allocator hint */ +#define FS_XFLAG_VERITY 0x00020000 /* fs-verity enabled */ #define FS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* the read-only stuff doesn't really belong here, but any other place is diff --git a/tools/perf/trace/beauty/include/uapi/linux/mount.h b/tools/perf/trace/beauty/include/uapi/linux/mount.h index 5d3f8c9e3a62..d9d86598d100 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/mount.h +++ b/tools/perf/trace/beauty/include/uapi/linux/mount.h @@ -61,7 +61,8 @@ /* * open_tree() flags. */ -#define OPEN_TREE_CLONE 1 /* Clone the target tree and attach the clone */ +#define OPEN_TREE_CLONE (1 << 0) /* Clone the target tree and attach the clone */ +#define OPEN_TREE_NAMESPACE (1 << 1) /* Clone the target tree into a new mount namespace */ #define OPEN_TREE_CLOEXEC O_CLOEXEC /* Close the file on execve() */ /* @@ -197,7 +198,10 @@ struct statmount { */ struct mnt_id_req { __u32 size; - __u32 mnt_ns_fd; + union { + __u32 mnt_ns_fd; + __u32 mnt_fd; + }; __u64 mnt_id; __u64 param; __u64 mnt_ns_id; @@ -232,4 +236,9 @@ struct mnt_id_req { #define LSMT_ROOT 0xffffffffffffffff /* root mount */ #define LISTMOUNT_REVERSE (1 << 0) /* List later mounts first */ +/* + * @flag bits for statmount(2) + */ +#define STATMOUNT_BY_FD 0x00000001U /* want mountinfo for given fd */ + #endif /* _UAPI_LINUX_MOUNT_H */ diff --git a/tools/perf/trace/beauty/include/uapi/linux/prctl.h b/tools/perf/trace/beauty/include/uapi/linux/prctl.h index 51c4e8c82b1e..55b0446fff9d 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/prctl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/prctl.h @@ -386,4 +386,41 @@ struct prctl_mm_map { # define PR_FUTEX_HASH_SET_SLOTS 1 # define PR_FUTEX_HASH_GET_SLOTS 2 +/* RSEQ time slice extensions */ +#define PR_RSEQ_SLICE_EXTENSION 79 +# define PR_RSEQ_SLICE_EXTENSION_GET 1 +# define PR_RSEQ_SLICE_EXTENSION_SET 2 +/* + * Bits for RSEQ_SLICE_EXTENSION_GET/SET + * PR_RSEQ_SLICE_EXT_ENABLE: Enable + */ +# define PR_RSEQ_SLICE_EXT_ENABLE 0x01 + +/* + * Get the current indirect branch tracking configuration for the current + * thread, this will be the value configured via PR_SET_INDIR_BR_LP_STATUS. + */ +#define PR_GET_INDIR_BR_LP_STATUS 80 + +/* + * Set the indirect branch tracking configuration. PR_INDIR_BR_LP_ENABLE will + * enable cpu feature for user thread, to track all indirect branches and ensure + * they land on arch defined landing pad instruction. + * x86 - If enabled, an indirect branch must land on an ENDBRANCH instruction. + * arch64 - If enabled, an indirect branch must land on a BTI instruction. + * riscv - If enabled, an indirect branch must land on an lpad instruction. + * PR_INDIR_BR_LP_DISABLE will disable feature for user thread and indirect + * branches will no more be tracked by cpu to land on arch defined landing pad + * instruction. + */ +#define PR_SET_INDIR_BR_LP_STATUS 81 +# define PR_INDIR_BR_LP_ENABLE (1UL << 0) + +/* + * Prevent further changes to the specified indirect branch tracking + * configuration. All bits may be locked via this call, including + * undefined bits. + */ +#define PR_LOCK_INDIR_BR_LP_STATUS 82 + #endif /* _LINUX_PRCTL_H */ diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 36aca8d6d003..ea17e6d29a7e 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c @@ -30,7 +30,7 @@ struct annotate_browser { struct rb_root entries; struct rb_node *curr_hot; struct annotation_line *selection; - struct arch *arch; + const struct arch *arch; /* * perf top can delete hist_entry anytime. Callers should make sure * its lifetime. @@ -601,7 +601,7 @@ static bool annotate_browser__callq(struct annotate_browser *browser, return true; } - target_ms.maps = ms->maps; + target_ms.thread = ms->thread; target_ms.map = ms->map; target_ms.sym = dl->ops.target.sym; annotation__unlock(notes); @@ -1198,7 +1198,7 @@ int __hist_entry__tui_annotate(struct hist_entry *he, struct map_symbol *ms, ui__warning("Annotation has no source code."); } } else { - err = evsel__get_arch(evsel, &browser.arch); + err = thread__get_arch(ms->thread, &browser.arch); if (err) { annotate_browser__symbol_annotate_error(&browser, err); return -1; diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index 08fecbe28a52..cfa6386e6e1d 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c @@ -3189,7 +3189,8 @@ static int evsel__hists_browse(struct evsel *evsel, int nr_events, const char *h case 'k': if (browser->selection != NULL) hists_browser__zoom_map(browser, - maps__machine(browser->selection->maps)->vmlinux_map); + maps__machine(thread__maps(browser->selection->thread) + )->vmlinux_map); continue; case 'V': verbose = (verbose + 1) % 4; diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 1c2a43e1dc68..bcccad7487a9 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -1,15 +1,17 @@ include $(srctree)/tools/scripts/Makefile.include include $(srctree)/tools/scripts/utilities.mak +perf-util-y += annotate-arch/ perf-util-y += arm64-frame-pointer-unwind-support.o perf-util-y += addr2line.o perf-util-y += addr_location.o perf-util-y += annotate.o +perf-util-y += blake2s.o perf-util-y += block-info.o perf-util-y += block-range.o perf-util-y += build-id.o perf-util-y += cacheline.o -perf-util-y += capstone.o +perf-util-$(CONFIG_LIBCAPSTONE) += capstone.o perf-util-y += config.o perf-util-y += copyfile.o perf-util-y += ctype.o @@ -43,7 +45,6 @@ perf-util-y += rbtree.o perf-util-y += libstring.o perf-util-y += bitmap.o perf-util-y += hweight.o -perf-util-y += sha1.o perf-util-y += smt.o perf-util-y += strbuf.o perf-util-y += string.o @@ -127,7 +128,8 @@ perf-util-y += spark.o perf-util-y += topdown.o perf-util-y += iostat.o perf-util-y += stream.o -perf-util-y += kvm-stat.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat.o +perf-util-y += kvm-stat-arch/ perf-util-y += lock-contention.o perf-util-y += auxtrace.o perf-util-y += intel-pt-decoder/ @@ -219,13 +221,12 @@ endif perf-util-$(CONFIG_LIBDW) += probe-finder.o perf-util-$(CONFIG_LIBDW) += dwarf-aux.o perf-util-$(CONFIG_LIBDW) += dwarf-regs.o -perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o -perf-util-$(CONFIG_LIBDW) += dwarf-regs-powerpc.o -perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-arch/ perf-util-$(CONFIG_LIBDW) += debuginfo.o perf-util-$(CONFIG_LIBDW) += annotate-data.o +perf-util-$(CONFIG_LIBDW) += libdw.o +perf-util-$(CONFIG_LIBDW) += unwind-libdw.o -perf-util-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o perf-util-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind-local.o perf-util-$(CONFIG_LIBUNWIND) += unwind-libunwind.o perf-util-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o @@ -418,20 +419,6 @@ $(OUTPUT)util/list_sort.o: ../lib/list_sort.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_o_c) -ifdef SHELLCHECK - SHELL_TESTS := generate-cmdlist.sh - SHELL_TEST_LOGS := $(SHELL_TESTS:%=%.shellcheck_log) -else - SHELL_TESTS := - SHELL_TEST_LOGS := -endif - -$(OUTPUT)%.shellcheck_log: % - $(call rule_mkdir) - $(Q)$(call echo-cmd,test)$(SHELLCHECK) "$<" > $@ || (cat $@ && rm $@ && false) - -perf-util-y += $(SHELL_TEST_LOGS) - PY_TESTS := setup.py ifdef MYPY MYPY_TEST_LOGS := $(PY_TESTS:%=%.mypy_log) diff --git a/tools/perf/util/addr2line.c b/tools/perf/util/addr2line.c index f2d94a3272d7..31c0391fffa3 100644 --- a/tools/perf/util/addr2line.c +++ b/tools/perf/util/addr2line.c @@ -18,8 +18,8 @@ #define MAX_INLINE_NEST 1024 -/* If addr2line doesn't return data for 1 second then timeout. */ -int addr2line_timeout_ms = 1 * 1000; +/* If addr2line doesn't return data for 5 seconds then timeout. */ +int addr2line_timeout_ms = 5 * 1000; static int filename_split(char *filename, unsigned int *line_nr) { @@ -90,16 +90,16 @@ static struct child_process *addr2line_subprocess_init(const char *addr2line_pat return a2l; } -enum a2l_style { +enum cmd_a2l_style { BROKEN, GNU_BINUTILS, LLVM, }; -static enum a2l_style addr2line_configure(struct child_process *a2l, const char *dso_name) +static enum cmd_a2l_style cmd_addr2line_configure(struct child_process *a2l, const char *dso_name) { static bool cached; - static enum a2l_style style; + static enum cmd_a2l_style style; if (!cached) { char buf[128]; @@ -149,7 +149,7 @@ static enum a2l_style addr2line_configure(struct child_process *a2l, const char } static int read_addr2line_record(struct io *io, - enum a2l_style style, + enum cmd_a2l_style style, const char *dso_name, u64 addr, bool first, @@ -298,7 +298,7 @@ int cmd__addr2line(const char *dso_name, u64 addr, char buf[128]; ssize_t written; struct io io = { .eof = false }; - enum a2l_style a2l_style; + enum cmd_a2l_style cmd_a2l_style; if (!a2l) { if (!filename__has_section(dso_name, ".debug_line")) @@ -314,8 +314,8 @@ int cmd__addr2line(const char *dso_name, u64 addr, pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name); goto out; } - a2l_style = addr2line_configure(a2l, dso_name); - if (a2l_style == BROKEN) + cmd_a2l_style = cmd_addr2line_configure(a2l, dso_name); + if (cmd_a2l_style == BROKEN) goto out; /* @@ -336,7 +336,7 @@ int cmd__addr2line(const char *dso_name, u64 addr, } io__init(&io, a2l->out, buf, sizeof(buf)); io.timeout_ms = addr2line_timeout_ms; - switch (read_addr2line_record(&io, a2l_style, dso_name, addr, /*first=*/true, + switch (read_addr2line_record(&io, cmd_a2l_style, dso_name, addr, /*first=*/true, &record_function, &record_filename, &record_line_nr)) { case -1: if (!symbol_conf.disable_add2line_warn) @@ -351,7 +351,7 @@ int cmd__addr2line(const char *dso_name, u64 addr, * binutils, also force a non-zero address as we're no longer * reading that record. */ - switch (read_addr2line_record(&io, a2l_style, dso_name, + switch (read_addr2line_record(&io, cmd_a2l_style, dso_name, /*addr=*/1, /*first=*/true, NULL, NULL, NULL)) { case -1: @@ -397,7 +397,7 @@ int cmd__addr2line(const char *dso_name, u64 addr, * as we're reading records beyond the first. */ while ((record_status = read_addr2line_record(&io, - a2l_style, + cmd_a2l_style, dso_name, /*addr=*/1, /*first=*/false, diff --git a/tools/perf/util/addr_location.c b/tools/perf/util/addr_location.c index 007a2f5df9a6..57e8217a00f9 100644 --- a/tools/perf/util/addr_location.c +++ b/tools/perf/util/addr_location.c @@ -7,7 +7,6 @@ void addr_location__init(struct addr_location *al) { al->thread = NULL; - al->maps = NULL; al->map = NULL; al->sym = NULL; al->srcline = NULL; @@ -24,22 +23,19 @@ void addr_location__init(struct addr_location *al) * The preprocess_sample method will return with reference counts for the * in it, when done using (and perhaps getting ref counts if needing to * keep a pointer to one of those entries) it must be paired with - * addr_location__put(), so that the refcounts can be decremented. + * addr_location__exit(), so that the refcounts can be decremented. */ void addr_location__exit(struct addr_location *al) { map__zput(al->map); thread__zput(al->thread); - maps__zput(al->maps); } void addr_location__copy(struct addr_location *dst, struct addr_location *src) { thread__put(dst->thread); - maps__put(dst->maps); map__put(dst->map); *dst = *src; dst->thread = thread__get(src->thread); - dst->maps = maps__get(src->maps); dst->map = map__get(src->map); } diff --git a/tools/perf/util/addr_location.h b/tools/perf/util/addr_location.h index 64b551025216..fdc4d3f3a68b 100644 --- a/tools/perf/util/addr_location.h +++ b/tools/perf/util/addr_location.h @@ -11,7 +11,6 @@ struct symbol; struct addr_location { struct thread *thread; - struct maps *maps; struct map *map; struct symbol *sym; const char *srcline; diff --git a/tools/perf/util/annotate-arch/Build b/tools/perf/util/annotate-arch/Build new file mode 100644 index 000000000000..23316743fdc5 --- /dev/null +++ b/tools/perf/util/annotate-arch/Build @@ -0,0 +1,11 @@ +perf-util-y += annotate-arc.o +perf-util-y += annotate-arm.o +perf-util-y += annotate-arm64.o +perf-util-y += annotate-csky.o +perf-util-y += annotate-loongarch.o +perf-util-y += annotate-mips.o +perf-util-y += annotate-x86.o +perf-util-y += annotate-powerpc.o +perf-util-y += annotate-riscv64.o +perf-util-y += annotate-s390.o +perf-util-y += annotate-sparc.o diff --git a/tools/perf/util/annotate-arch/annotate-arc.c b/tools/perf/util/annotate-arch/annotate-arc.c new file mode 100644 index 000000000000..170103e383a4 --- /dev/null +++ b/tools/perf/util/annotate-arch/annotate-arc.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../disasm.h" + +const struct arch *arch__new_arc(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) +{ + struct arch *arch = zalloc(sizeof(*arch)); + + if (!arch) + return NULL; + + arch->name = "arc"; + arch->id = *id; + arch->objdump.comment_char = ';'; + return arch; +} diff --git a/tools/perf/arch/arm/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-arm.c similarity index 59% rename from tools/perf/arch/arm/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-arm.c index 5e667b0f5512..afb413c80156 100644 --- a/tools/perf/arch/arm/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-arm.c @@ -1,20 +1,22 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include #include -#include #include -#include +#include "../annotate.h" +#include "../disasm.h" -struct arm_annotate { - regex_t call_insn, - jump_insn; +struct arch_arm { + struct arch arch; + regex_t call_insn; + regex_t jump_insn; }; -static struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const char *name) +static const struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const char *name) { - struct arm_annotate *arm = arch->priv; - struct ins_ops *ops; + struct arch_arm *arm = container_of(arch, struct arch_arm, arch); + const struct ins_ops *ops; regmatch_t match[2]; if (!regexec(&arm->call_insn, name, 2, match, 0)) @@ -28,39 +30,39 @@ static struct ins_ops *arm__associate_instruction_ops(struct arch *arch, const c return ops; } -static int arm__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - struct arm_annotate *arm; int err; + struct arch_arm *arm = zalloc(sizeof(*arm)); + struct arch *arch; - if (arch->initialized) - return 0; - - arm = zalloc(sizeof(*arm)); if (!arm) - return ENOMEM; + return NULL; + + arch = &arm->arch; + arch->name = "arm"; + arch->id = *id; + arch->objdump.comment_char = ';'; + arch->objdump.skip_functions_char = '+'; + arch->associate_instruction_ops = arm__associate_instruction_ops; #define ARM_CONDS "(cc|cs|eq|ge|gt|hi|le|ls|lt|mi|ne|pl|vc|vs)" err = regcomp(&arm->call_insn, "^blx?" ARM_CONDS "?$", REG_EXTENDED); if (err) goto out_free_arm; + err = regcomp(&arm->jump_insn, "^bx?" ARM_CONDS "?$", REG_EXTENDED); if (err) goto out_free_call; #undef ARM_CONDS - arch->initialized = true; - arch->priv = arm; - arch->associate_instruction_ops = arm__associate_instruction_ops; - arch->objdump.comment_char = ';'; - arch->objdump.skip_functions_char = '+'; - arch->e_machine = EM_ARM; - arch->e_flags = 0; - return 0; + return arch; out_free_call: regfree(&arm->call_insn); out_free_arm: free(arm); - return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; + errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; + return NULL; } diff --git a/tools/perf/arch/arm64/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-arm64.c similarity index 70% rename from tools/perf/arch/arm64/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-arm64.c index 16cb62d40bd9..33080fdca125 100644 --- a/tools/perf/arch/arm64/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-arm64.c @@ -1,16 +1,20 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include -#include #include +#include +#include +#include +#include "../annotate.h" +#include "../disasm.h" -struct arm64_annotate { - regex_t call_insn, - jump_insn; +struct arch_arm64 { + struct arch arch; + regex_t call_insn; + regex_t jump_insn; }; -static int arm64_mov__parse(struct arch *arch __maybe_unused, +static int arm64_mov__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused) @@ -60,18 +64,15 @@ static int arm64_mov__parse(struct arch *arch __maybe_unused, return -1; } -static int mov__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name); - -static struct ins_ops arm64_mov_ops = { +static const struct ins_ops arm64_mov_ops = { .parse = arm64_mov__parse, .scnprintf = mov__scnprintf, }; -static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) +static const struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const char *name) { - struct arm64_annotate *arm = arch->priv; - struct ins_ops *ops; + struct arch_arm64 *arm = container_of(arch, struct arch_arm64, arch); + const struct ins_ops *ops; regmatch_t match[2]; if (!regexec(&arm->jump_insn, name, 2, match, 0)) @@ -87,40 +88,40 @@ static struct ins_ops *arm64__associate_instruction_ops(struct arch *arch, const return ops; } -static int arm64__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - struct arm64_annotate *arm; int err; + struct arch_arm64 *arm = zalloc(sizeof(*arm)); + struct arch *arch; - if (arch->initialized) - return 0; - - arm = zalloc(sizeof(*arm)); if (!arm) - return ENOMEM; + return NULL; + + arch = &arm->arch; + arch->name = "arm64"; + arch->id = *id; + arch->objdump.comment_char = '/'; + arch->objdump.skip_functions_char = '+'; + arch->associate_instruction_ops = arm64__associate_instruction_ops; /* bl, blr */ err = regcomp(&arm->call_insn, "^blr?$", REG_EXTENDED); if (err) goto out_free_arm; + /* b, b.cond, br, cbz/cbnz, tbz/tbnz */ err = regcomp(&arm->jump_insn, "^[ct]?br?\\.?(cc|cs|eq|ge|gt|hi|hs|le|lo|ls|lt|mi|ne|pl|vc|vs)?n?z?$", REG_EXTENDED); if (err) goto out_free_call; - arch->initialized = true; - arch->priv = arm; - arch->associate_instruction_ops = arm64__associate_instruction_ops; - arch->objdump.comment_char = '/'; - arch->objdump.skip_functions_char = '+'; - arch->e_machine = EM_AARCH64; - arch->e_flags = 0; - return 0; + return arch; out_free_call: regfree(&arm->call_insn); out_free_arm: free(arm); - return SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; + errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_REGEXP; + return NULL; } diff --git a/tools/perf/arch/csky/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-csky.c similarity index 67% rename from tools/perf/arch/csky/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-csky.c index 14270311d215..d2b18e4ea2c9 100644 --- a/tools/perf/arch/csky/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-csky.c @@ -1,12 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. - +#include #include +#include +#include "../disasm.h" -static struct ins_ops *csky__associate_ins_ops(struct arch *arch, - const char *name) +static const struct ins_ops *csky__associate_ins_ops(struct arch *arch, + const char *name) { - struct ins_ops *ops = NULL; + const struct ins_ops *ops = NULL; /* catch all kind of jumps */ if (!strcmp(name, "bt") || @@ -38,16 +40,17 @@ static struct ins_ops *csky__associate_ins_ops(struct arch *arch, return ops; } -static int csky__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_csky(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - arch->initialized = true; + struct arch *arch = zalloc(sizeof(*arch)); + + if (!arch) + return NULL; + + arch->name = "csky"; + arch->id = *id; arch->objdump.comment_char = '/'; arch->associate_instruction_ops = csky__associate_ins_ops; - arch->e_machine = EM_CSKY; -#if defined(__CSKYABIV2__) - arch->e_flags = EF_CSKY_ABIV2; -#else - arch->e_flags = EF_CSKY_ABIV1; -#endif - return 0; + return arch; } diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-loongarch.c similarity index 59% rename from tools/perf/arch/loongarch/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-loongarch.c index 70262d5f1444..950f34e59e5c 100644 --- a/tools/perf/arch/loongarch/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-loongarch.c @@ -4,15 +4,23 @@ * * Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ +#include +#include +#include +#include +#include "../disasm.h" +#include "../map.h" +#include "../maps.h" +#include "../symbol.h" +#include "../thread.h" -static int loongarch_call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, - struct disasm_line *dl __maybe_unused) +static int loongarch_call__parse(const struct arch *arch, struct ins_operands *ops, + struct map_symbol *ms, + struct disasm_line *dl __maybe_unused) { char *c, *endptr, *tok, *name; struct map *map = ms->map; - struct addr_map_symbol target = { - .ms = { .map = map, }, - }; + struct addr_map_symbol target; c = strchr(ops->raw, '#'); if (c++ == NULL) @@ -38,27 +46,34 @@ static int loongarch_call__parse(struct arch *arch, struct ins_operands *ops, st if (ops->target.name == NULL) return -1; - target.addr = map__objdump_2mem(map, ops->target.addr); + target = (struct addr_map_symbol) { + .ms = { .map = map__get(map), }, + .addr = map__objdump_2mem(map, ops->target.addr), + }; - if (maps__find_ams(ms->maps, &target) == 0 && + if (maps__find_ams(thread__maps(ms->thread), &target) == 0 && map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; + addr_map_symbol__exit(&target); return 0; } -static struct ins_ops loongarch_call_ops = { +static const struct ins_ops loongarch_call_ops = { .parse = loongarch_call__parse, .scnprintf = call__scnprintf, + .is_call = true, }; -static int loongarch_jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, - struct disasm_line *dl __maybe_unused) +static int loongarch_jump__parse(const struct arch *arch, struct ins_operands *ops, + struct map_symbol *ms, + struct disasm_line *dl __maybe_unused) + { struct map *map = ms->map; struct symbol *sym = ms->sym; struct addr_map_symbol target = { - .ms = { .map = map, }, + .ms = { .map = map__get(map), }, }; const char *c = strchr(ops->raw, '#'); u64 start, end; @@ -78,9 +93,9 @@ static int loongarch_jump__parse(struct arch *arch, struct ins_operands *ops, st start = map__unmap_ip(map, sym->start); end = map__unmap_ip(map, sym->end); - ops->target.outside = target.addr < start || target.addr > end; + ops->target.outside = target.addr < start || target.addr >= end; - if (maps__find_ams(ms->maps, &target) == 0 && + if (maps__find_ams(thread__maps(ms->thread), &target) == 0 && map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; @@ -90,19 +105,20 @@ static int loongarch_jump__parse(struct arch *arch, struct ins_operands *ops, st } else { ops->target.offset_avail = false; } - + addr_map_symbol__exit(&target); return 0; } -static struct ins_ops loongarch_jump_ops = { +static const struct ins_ops loongarch_jump_ops = { .parse = loongarch_jump__parse, .scnprintf = jump__scnprintf, + .is_jump = true, }; static -struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name) +const struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name) { - struct ins_ops *ops = NULL; + const struct ins_ops *ops = NULL; if (!strcmp(name, "bl")) ops = &loongarch_call_ops; @@ -124,16 +140,17 @@ struct ins_ops *loongarch__associate_ins_ops(struct arch *arch, const char *name return ops; } -static -int loongarch__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - if (!arch->initialized) { - arch->associate_instruction_ops = loongarch__associate_ins_ops; - arch->initialized = true; - arch->objdump.comment_char = '#'; - arch->e_machine = EM_LOONGARCH; - arch->e_flags = 0; - } + struct arch *arch = zalloc(sizeof(*arch)); - return 0; + if (!arch) + return NULL; + + arch->name = "loongarch"; + arch->id = *id; + arch->associate_instruction_ops = loongarch__associate_ins_ops; + arch->objdump.comment_char = '#'; + return arch; } diff --git a/tools/perf/arch/mips/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-mips.c similarity index 59% rename from tools/perf/arch/mips/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-mips.c index b50b46c613d6..e8d1c6c7e9f3 100644 --- a/tools/perf/arch/mips/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-mips.c @@ -1,9 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "../disasm.h" static -struct ins_ops *mips__associate_ins_ops(struct arch *arch, const char *name) +const struct ins_ops *mips__associate_ins_ops(struct arch *arch, const char *name) { - struct ins_ops *ops = NULL; + const struct ins_ops *ops = NULL; if (!strncmp(name, "bal", 3) || !strncmp(name, "bgezal", 6) || @@ -33,16 +37,17 @@ struct ins_ops *mips__associate_ins_ops(struct arch *arch, const char *name) return ops; } -static -int mips__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_mips(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - if (!arch->initialized) { - arch->associate_instruction_ops = mips__associate_ins_ops; - arch->initialized = true; - arch->objdump.comment_char = '#'; - arch->e_machine = EM_MIPS; - arch->e_flags = 0; - } + struct arch *arch = zalloc(sizeof(*arch)); - return 0; + if (!arch) + return NULL; + + arch->name = "mips"; + arch->id = *id; + arch->objdump.comment_char = '#'; + arch->associate_instruction_ops = mips__associate_ins_ops; + return arch; } diff --git a/tools/perf/arch/powerpc/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-powerpc.c similarity index 73% rename from tools/perf/arch/powerpc/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-powerpc.c index ca567cfdcbdb..218207b52581 100644 --- a/tools/perf/arch/powerpc/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-powerpc.c @@ -1,10 +1,102 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include +#include +#include "../annotate-data.h" +#include "../debug.h" +#include "../disasm.h" -static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) +#define PPC_OP(op) (((op) >> 26) & 0x3F) +#define PPC_21_30(R) (((R) >> 1) & 0x3ff) +#define PPC_22_30(R) (((R) >> 1) & 0x1ff) + +#define MINUS_EXT_XO_FORM 234 +#define SUB_EXT_XO_FORM 232 +#define ADD_ZERO_EXT_XO_FORM 202 +#define SUB_ZERO_EXT_XO_FORM 200 + +static int arithmetic__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) +{ + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, + ops->raw); +} + +/* + * Sets the fields: multi_regs and "mem_ref". + * "mem_ref" is set for ops->source which is later used to + * fill the objdump->memory_ref-char field. This ops is currently + * used by powerpc and since binary instruction code is used to + * extract opcode, regs and offset, no other parsing is needed here. + * + * Dont set multi regs for 4 cases since it has only one operand + * for source: + * - Add to Minus One Extended XO-form ( Ex: addme, addmeo ) + * - Subtract From Minus One Extended XO-form ( Ex: subfme ) + * - Add to Zero Extended XO-form ( Ex: addze, addzeo ) + * - Subtract From Zero Extended XO-form ( Ex: subfze ) + */ +static int arithmetic__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops, + struct map_symbol *ms __maybe_unused, struct disasm_line *dl) +{ + int opcode = PPC_OP(dl->raw.raw_insn); + + ops->source.mem_ref = false; + if (opcode == 31) { + if ((opcode != MINUS_EXT_XO_FORM) && (opcode != SUB_EXT_XO_FORM) && + (opcode != ADD_ZERO_EXT_XO_FORM) && (opcode != SUB_ZERO_EXT_XO_FORM)) + ops->source.multi_regs = true; + } + + ops->target.mem_ref = false; + ops->target.multi_regs = false; + + return 0; +} + +static const struct ins_ops arithmetic_ops = { + .parse = arithmetic__parse, + .scnprintf = arithmetic__scnprintf, +}; + +static int load_store__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) +{ + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, + ops->raw); +} + +/* + * Sets the fields: multi_regs and "mem_ref". + * "mem_ref" is set for ops->source which is later used to + * fill the objdump->memory_ref-char field. This ops is currently + * used by powerpc and since binary instruction code is used to + * extract opcode, regs and offset, no other parsing is needed here + */ +static int load_store__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops, + struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused) +{ + ops->source.mem_ref = true; + ops->source.multi_regs = false; + /* opcode 31 is of X form */ + if (PPC_OP(dl->raw.raw_insn) == 31) + ops->source.multi_regs = true; + + ops->target.mem_ref = false; + ops->target.multi_regs = false; + + return 0; +} + +static const struct ins_ops load_store_ops = { + .parse = load_store__parse, + .scnprintf = load_store__scnprintf, +}; + +static const struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) { int i; - struct ins_ops *ops; + const struct ins_ops *ops; /* * - Interested only if instruction starts with 'b'. @@ -49,10 +141,6 @@ static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, con return ops; } -#define PPC_OP(op) (((op) >> 26) & 0x3F) -#define PPC_21_30(R) (((R) >> 1) & 0x3ff) -#define PPC_22_30(R) (((R) >> 1) & 0x1ff) - struct insn_offset { const char *name; int value; @@ -189,7 +277,7 @@ static int cmp_offset(const void *a, const void *b) return (val1->value - val2->value); } -static struct ins_ops *check_ppc_insn(struct disasm_line *dl) +const struct ins_ops *check_ppc_insn(struct disasm_line *dl) { int raw_insn = dl->raw.raw_insn; int opcode = PPC_OP(raw_insn); @@ -302,16 +390,21 @@ static void update_insn_state_powerpc(struct type_state *state, } #endif /* HAVE_LIBDW_SUPPORT */ -static int powerpc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - if (!arch->initialized) { - arch->initialized = true; - arch->associate_instruction_ops = powerpc__associate_instruction_ops; - arch->objdump.comment_char = '#'; - annotate_opts.show_asm_raw = true; - arch->e_machine = EM_PPC; - arch->e_flags = 0; - } + struct arch *arch = zalloc(sizeof(*arch)); - return 0; + if (!arch) + return NULL; + + arch->name = "powerpc"; + arch->id = *id; + arch->objdump.comment_char = '#'; + annotate_opts.show_asm_raw = true; + arch->associate_instruction_ops = powerpc__associate_instruction_ops; +#ifdef HAVE_LIBDW_SUPPORT + arch->update_insn_state = update_insn_state_powerpc; +#endif + return arch; } diff --git a/tools/perf/util/annotate-arch/annotate-riscv64.c b/tools/perf/util/annotate-arch/annotate-riscv64.c new file mode 100644 index 000000000000..29a988fca8c9 --- /dev/null +++ b/tools/perf/util/annotate-arch/annotate-riscv64.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "../disasm.h" + +static +const struct ins_ops *riscv64__associate_ins_ops(struct arch *arch, const char *name) +{ + const struct ins_ops *ops = NULL; + + if (!strncmp(name, "jal", 3) || + !strncmp(name, "jr", 2) || + !strncmp(name, "call", 4)) + ops = &call_ops; + else if (!strncmp(name, "ret", 3)) + ops = &ret_ops; + else if (name[0] == 'j' || name[0] == 'b') + ops = &jump_ops; + else + return NULL; + + arch__associate_ins_ops(arch, name, ops); + + return ops; +} + +const struct arch *arch__new_riscv64(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) +{ + struct arch *arch = zalloc(sizeof(*arch)); + + if (!arch) + return NULL; + + arch->name = "riscv"; + arch->id = *id; + arch->objdump.comment_char = '#'; + arch->associate_instruction_ops = riscv64__associate_ins_ops; + return arch; +} diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-s390.c similarity index 66% rename from tools/perf/arch/s390/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-s390.c index c61193f1e096..af9cabd0a586 100644 --- a/tools/perf/arch/s390/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-s390.c @@ -1,14 +1,22 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include +#include "../debug.h" +#include "../disasm.h" +#include "../map.h" +#include "../maps.h" +#include "../symbol.h" +#include "../thread.h" +#include "../annotate.h" +#include "../annotate-data.h" -static int s390_call__parse(struct arch *arch, struct ins_operands *ops, - struct map_symbol *ms, struct disasm_line *dl __maybe_unused) +static int s390_call__parse(const struct arch *arch, struct ins_operands *ops, + struct map_symbol *ms, + struct disasm_line *dl __maybe_unused) { char *endptr, *tok, *name; struct map *map = ms->map; - struct addr_map_symbol target = { - .ms = { .map = map, }, - }; + struct addr_map_symbol target; tok = strchr(ops->raw, ','); if (!tok) @@ -36,21 +44,27 @@ static int s390_call__parse(struct arch *arch, struct ins_operands *ops, if (ops->target.name == NULL) return -1; - target.addr = map__objdump_2mem(map, ops->target.addr); - if (maps__find_ams(ms->maps, &target) == 0 && + target = (struct addr_map_symbol) { + .ms = { .map = map__get(map), }, + .addr = map__objdump_2mem(map, ops->target.addr), + }; + + if (maps__find_ams(thread__maps(ms->thread), &target) == 0 && map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; + addr_map_symbol__exit(&target); return 0; } -static struct ins_ops s390_call_ops = { +static const struct ins_ops s390_call_ops = { .parse = s390_call__parse, .scnprintf = call__scnprintf, + .is_call = true, }; -static int s390_mov__parse(struct arch *arch __maybe_unused, +static int s390_mov__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused) @@ -99,14 +113,14 @@ static int s390_mov__parse(struct arch *arch __maybe_unused, } -static struct ins_ops s390_mov_ops = { +static const struct ins_ops s390_mov_ops = { .parse = s390_mov__parse, .scnprintf = mov__scnprintf, }; -static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name) +static const struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name) { - struct ins_ops *ops = NULL; + const struct ins_ops *ops = NULL; /* catch all kind of jumps */ if (strchr(name, 'j') || @@ -134,7 +148,7 @@ static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *na return ops; } -static int s390__cpuid_parse(struct arch *arch, char *cpuid) +static int s390__cpuid_parse(struct arch *arch, const char *cpuid) { unsigned int family; char model[16], model_c[16], cpumf_v[16], cpumf_a[16]; @@ -155,20 +169,22 @@ static int s390__cpuid_parse(struct arch *arch, char *cpuid) return -1; } -static int s390__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_s390(const struct e_machine_and_e_flags *id, const char *cpuid) { - int err = 0; + struct arch *arch = zalloc(sizeof(*arch)); - if (!arch->initialized) { - arch->initialized = true; - arch->associate_instruction_ops = s390__associate_ins_ops; - if (cpuid) { - if (s390__cpuid_parse(arch, cpuid)) - err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; + if (!arch) + return NULL; + + arch->name = "s390"; + arch->id = *id; + arch->associate_instruction_ops = s390__associate_ins_ops; + if (cpuid) { + if (s390__cpuid_parse(arch, cpuid)) { + errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; + return NULL; } - arch->e_machine = EM_S390; - arch->e_flags = 0; } - - return err; + arch->objdump.comment_char = '#'; + return arch; } diff --git a/tools/perf/arch/sparc/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-sparc.c similarity index 85% rename from tools/perf/arch/sparc/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-sparc.c index 68c31580ccfc..2f07bc7a56dd 100644 --- a/tools/perf/arch/sparc/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-sparc.c @@ -1,4 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include "../../util/disasm.h" static int is_branch_cond(const char *cond) { @@ -117,9 +121,9 @@ static int is_branch_float_cond(const char *cond) return 0; } -static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name) +static const struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const char *name) { - struct ins_ops *ops = NULL; + const struct ins_ops *ops = NULL; if (!strcmp(name, "call") || !strcmp(name, "jmp") || @@ -157,15 +161,17 @@ static struct ins_ops *sparc__associate_instruction_ops(struct arch *arch, const return ops; } -static int sparc__annotate_init(struct arch *arch, char *cpuid __maybe_unused) +const struct arch *arch__new_sparc(const struct e_machine_and_e_flags *id, + const char *cpuid __maybe_unused) { - if (!arch->initialized) { - arch->initialized = true; - arch->associate_instruction_ops = sparc__associate_instruction_ops; - arch->objdump.comment_char = '#'; - arch->e_machine = EM_SPARC; - arch->e_flags = 0; - } + struct arch *arch = zalloc(sizeof(*arch)); - return 0; + if (!arch) + return NULL; + + arch->name = "sparc"; + arch->id = *id; + arch->associate_instruction_ops = sparc__associate_instruction_ops; + arch->objdump.comment_char = '#'; + return arch; } diff --git a/tools/perf/arch/x86/annotate/instructions.c b/tools/perf/util/annotate-arch/annotate-x86.c similarity index 93% rename from tools/perf/arch/x86/annotate/instructions.c rename to tools/perf/util/annotate-arch/annotate-x86.c index 803f9351a3fb..eb9a649ca656 100644 --- a/tools/perf/arch/x86/annotate/instructions.c +++ b/tools/perf/util/annotate-arch/annotate-x86.c @@ -1,4 +1,16 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include "../annotate-data.h" +#include "../debug.h" +#include "../disasm.h" +#include "../dso.h" +#include "../map.h" +#include "../string2.h" // strstarts +#include "../symbol.h" + /* * x86 instruction nmemonic table to parse disasm lines for annotate. * This table is searched twice - one for exact match and another for @@ -7,7 +19,7 @@ * So this table should not have entries with the suffix unless it's * a complete different instruction than ones without the suffix. */ -static struct ins x86__instructions[] = { +static const struct ins x86__instructions[] = { { .name = "adc", .ops = &mov_ops, }, { .name = "add", .ops = &mov_ops, }, { .name = "addsd", .ops = &mov_ops, }, @@ -19,9 +31,9 @@ static struct ins x86__instructions[] = { { .name = "btr", .ops = &mov_ops, }, { .name = "bts", .ops = &mov_ops, }, { .name = "call", .ops = &call_ops, }, + { .name = "cmovae", .ops = &mov_ops, }, { .name = "cmovbe", .ops = &mov_ops, }, { .name = "cmove", .ops = &mov_ops, }, - { .name = "cmovae", .ops = &mov_ops, }, { .name = "cmp", .ops = &mov_ops, }, { .name = "cmpxch", .ops = &mov_ops, }, { .name = "cmpxchg", .ops = &mov_ops, }, @@ -73,23 +85,23 @@ static struct ins x86__instructions[] = { { .name = "movaps", .ops = &mov_ops, }, { .name = "movdqa", .ops = &mov_ops, }, { .name = "movdqu", .ops = &mov_ops, }, - { .name = "movsd", .ops = &mov_ops, }, - { .name = "movss", .ops = &mov_ops, }, { .name = "movsb", .ops = &mov_ops, }, - { .name = "movsw", .ops = &mov_ops, }, + { .name = "movsd", .ops = &mov_ops, }, { .name = "movsl", .ops = &mov_ops, }, + { .name = "movss", .ops = &mov_ops, }, + { .name = "movsw", .ops = &mov_ops, }, { .name = "movupd", .ops = &mov_ops, }, { .name = "movups", .ops = &mov_ops, }, { .name = "movzb", .ops = &mov_ops, }, - { .name = "movzw", .ops = &mov_ops, }, { .name = "movzl", .ops = &mov_ops, }, + { .name = "movzw", .ops = &mov_ops, }, { .name = "mulsd", .ops = &mov_ops, }, { .name = "mulss", .ops = &mov_ops, }, { .name = "nop", .ops = &nop_ops, }, { .name = "or", .ops = &mov_ops, }, { .name = "orps", .ops = &mov_ops, }, - { .name = "pand", .ops = &mov_ops, }, { .name = "paddq", .ops = &mov_ops, }, + { .name = "pand", .ops = &mov_ops, }, { .name = "pcmpeqb", .ops = &mov_ops, }, { .name = "por", .ops = &mov_ops, }, { .name = "rcl", .ops = &mov_ops, }, @@ -119,7 +131,7 @@ static struct ins x86__instructions[] = { { .name = "xorps", .ops = &mov_ops, }, }; -static bool amd__ins_is_fused(struct arch *arch, const char *ins1, +static bool amd__ins_is_fused(const struct arch *arch, const char *ins1, const char *ins2) { if (strstr(ins2, "jmp")) @@ -142,7 +154,7 @@ static bool amd__ins_is_fused(struct arch *arch, const char *ins1, return false; } -static bool intel__ins_is_fused(struct arch *arch, const char *ins1, +static bool intel__ins_is_fused(const struct arch *arch, const char *ins1, const char *ins2) { if (arch->family != 6 || arch->model < 0x1e || strstr(ins2, "jmp")) @@ -170,7 +182,7 @@ static bool intel__ins_is_fused(struct arch *arch, const char *ins1, return false; } -static int x86__cpuid_parse(struct arch *arch, char *cpuid) +static int x86__cpuid_parse(struct arch *arch, const char *cpuid) { unsigned int family, model, stepping; int ret; @@ -191,23 +203,6 @@ static int x86__cpuid_parse(struct arch *arch, char *cpuid) return -1; } -static int x86__annotate_init(struct arch *arch, char *cpuid) -{ - int err = 0; - - if (arch->initialized) - return 0; - - if (cpuid) { - if (x86__cpuid_parse(arch, cpuid)) - err = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; - } - arch->e_machine = EM_X86_64; - arch->e_flags = 0; - arch->initialized = true; - return err; -} - #ifdef HAVE_LIBDW_SUPPORT static void update_insn_state_x86(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, @@ -781,3 +776,45 @@ static void update_insn_state_x86(struct type_state *state, /* Case 4. memory to memory transfers (not handled for now) */ } #endif + +const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid) +{ + struct arch *arch = zalloc(sizeof(*arch)); + + if (!arch) + return NULL; + + arch->name = "x86"; + arch->id = *id; + if (cpuid) { + if (x86__cpuid_parse(arch, cpuid)) { + errno = SYMBOL_ANNOTATE_ERRNO__ARCH_INIT_CPUID_PARSING; + return NULL; + } + } + arch->instructions = x86__instructions; + arch->nr_instructions = ARRAY_SIZE(x86__instructions); +#ifndef NDEBUG + { + static bool sorted_check; + + if (!sorted_check) { + for (size_t i = 0; i < arch->nr_instructions - 1; i++) { + assert(strcmp(arch->instructions[i].name, + arch->instructions[i + 1].name) <= 0); + } + sorted_check = true; + } + } +#endif + arch->sorted_instructions = true; + arch->objdump.comment_char = '#'; + arch->objdump.register_char = '%'; + arch->objdump.memory_ref_char = '('; + arch->objdump.imm_char = '$'; + arch->insn_suffix = "bwlq"; +#ifdef HAVE_LIBDW_SUPPORT + arch->update_insn_state = update_insn_state_x86; +#endif + return arch; +} diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c index 07cf9c334be0..44fbd41e3845 100644 --- a/tools/perf/util/annotate-data.c +++ b/tools/perf/util/annotate-data.c @@ -160,12 +160,12 @@ bool has_reg_type(struct type_state *state, int reg) return (unsigned)reg < ARRAY_SIZE(state->regs); } -static void init_type_state(struct type_state *state, struct arch *arch) +static void init_type_state(struct type_state *state, const struct arch *arch) { memset(state, 0, sizeof(*state)); INIT_LIST_HEAD(&state->stack_vars); - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { state->regs[0].caller_saved = true; state->regs[1].caller_saved = true; state->regs[2].caller_saved = true; @@ -526,7 +526,7 @@ static enum type_match_result check_variable(struct data_loc_info *dloc, needs_pointer = false; else if (reg == dloc->fbreg || is_fbreg) needs_pointer = false; - else if (arch__is(dloc->arch, "x86") && reg == X86_REG_SP) + else if (arch__is_x86(dloc->arch) && reg == X86_REG_SP) needs_pointer = false; /* Get the type of the variable */ @@ -1071,7 +1071,7 @@ static void delete_var_types(struct die_var_type *var_types) /* should match to is_stack_canary() in util/annotate.c */ static void setup_stack_canary(struct data_loc_info *dloc) { - if (arch__is(dloc->arch, "x86")) { + if (arch__is_x86(dloc->arch)) { dloc->op->segment = INSN_SEG_X86_GS; dloc->op->imm = true; dloc->op->offset = 40; @@ -1311,7 +1311,7 @@ static enum type_match_result check_matching_type(struct type_state *state, /* Direct this-cpu access like "%gs:0x34740" */ if (dloc->op->segment == INSN_SEG_X86_GS && dloc->op->imm && - arch__is(dloc->arch, "x86")) { + arch__is_x86(dloc->arch)) { pr_debug_dtp("this-cpu var"); addr = dloc->op->offset; @@ -1397,7 +1397,7 @@ static enum type_match_result find_data_type_insn(struct data_loc_info *dloc, static int arch_supports_insn_tracking(struct data_loc_info *dloc) { - if ((arch__is(dloc->arch, "x86")) || (arch__is(dloc->arch, "powerpc"))) + if ((arch__is_x86(dloc->arch)) || (arch__is_powerpc(dloc->arch))) return 1; return 0; } diff --git a/tools/perf/util/annotate-data.h b/tools/perf/util/annotate-data.h index 869307c7f130..9b222869e42d 100644 --- a/tools/perf/util/annotate-data.h +++ b/tools/perf/util/annotate-data.h @@ -117,7 +117,7 @@ extern struct annotated_data_type canary_type; */ struct data_loc_info { /* These are input field, should be filled by caller */ - struct arch *arch; + const struct arch *arch; struct thread *thread; struct map_symbol *ms; u64 ip; diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index cc7764455faf..63f0ee9d4c03 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -44,6 +44,7 @@ #include "strbuf.h" #include #include +#include #include #include #include @@ -137,8 +138,10 @@ static int annotated_source__alloc_histograms(struct annotated_source *src, return -1; src->samples = hashmap__new(sym_hist_hash, sym_hist_equal, NULL); - if (src->samples == NULL) + if (IS_ERR(src->samples)) { zfree(&src->histograms); + src->samples = NULL; + } return src->histograms ? 0 : -1; } @@ -761,7 +764,7 @@ static int disasm_line__print(struct disasm_line *dl, u64 start, int addr_fmt_wi } static struct annotated_data_type * -__hist_entry__get_data_type(struct hist_entry *he, struct arch *arch, +__hist_entry__get_data_type(struct hist_entry *he, const struct arch *arch, struct debuginfo *dbg, struct disasm_line *dl, int *type_offset); @@ -980,47 +983,43 @@ void symbol__calc_percent(struct symbol *sym, struct evsel *evsel) annotation__calc_percent(notes, evsel, symbol__size(sym)); } -int evsel__get_arch(struct evsel *evsel, struct arch **parch) +int thread__get_arch(struct thread *thread, const struct arch **parch) { - struct perf_env *env = evsel__env(evsel); - const char *arch_name = perf_env__arch(env); - struct arch *arch; - int err; + const struct arch *arch; + struct machine *machine; + uint32_t e_flags; + uint16_t e_machine; - if (!arch_name) { + if (!thread) { *parch = NULL; + return -1; + } + + machine = maps__machine(thread__maps(thread)); + e_machine = thread__e_machine(thread, machine, &e_flags); + arch = arch__find(e_machine, e_flags, machine->env ? machine->env->cpuid : NULL); + if (arch == NULL) { + pr_err("%s: unsupported arch %d\n", __func__, e_machine); return errno; } + if (parch) + *parch = arch; - *parch = arch = arch__find(arch_name); - if (arch == NULL) { - pr_err("%s: unsupported arch %s\n", __func__, arch_name); - return ENOTSUP; - } - - if (arch->init) { - err = arch->init(arch, env ? env->cpuid : NULL); - if (err) { - pr_err("%s: failed to initialize %s arch priv area\n", - __func__, arch->name); - return err; - } - } return 0; } int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, - struct arch **parch) + const struct arch **parch) { struct symbol *sym = ms->sym; struct annotation *notes = symbol__annotation(sym); struct annotate_args args = { .options = &annotate_opts, }; - struct arch *arch = NULL; + const struct arch *arch = NULL; int err, nr; - err = evsel__get_arch(evsel, &arch); + err = thread__get_arch(ms->thread, &arch); if (err) return err; @@ -1031,7 +1030,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, return 0; args.arch = arch; - args.ms = *ms; + args.ms = ms; if (notes->src == NULL) { notes->src = annotated_source__new(); @@ -1268,7 +1267,7 @@ int hist_entry__annotate_printf(struct hist_entry *he, struct evsel *evsel) apd.addr_fmt_width = annotated_source__addr_fmt_width(¬es->src->source, notes->src->start); - evsel__get_arch(evsel, &apd.arch); + thread__get_arch(ms->thread, &apd.arch); apd.dbg = dso__debuginfo(dso); list_for_each_entry(pos, ¬es->src->source, node) { @@ -1373,7 +1372,7 @@ static int symbol__annotate_fprintf2(struct symbol *sym, FILE *fp, struct annotation_line *al; if (annotate_opts.code_with_type) { - evsel__get_arch(apd->evsel, &apd->arch); + thread__get_arch(apd->he->ms.thread, &apd->arch); apd->dbg = dso__debuginfo(map__dso(apd->he->ms.map)); } @@ -2204,7 +2203,7 @@ void annotation_line__write(struct annotation_line *al, struct annotation *notes } int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel, - struct arch **parch) + const struct arch **parch) { struct symbol *sym = ms->sym; struct annotation *notes = symbol__annotation(sym); @@ -2451,17 +2450,39 @@ int annotate_check_args(void) return 0; } +static int arch__dwarf_regnum(const struct arch *arch, const char *str) +{ + const char *p; + char *regname, *q; + int reg; + + p = strchr(str, arch->objdump.register_char); + if (p == NULL) + return -1; + + regname = strdup(p); + if (regname == NULL) + return -1; + + q = strpbrk(regname, ",) "); + if (q) + *q = '\0'; + + reg = get_dwarf_regnum(regname, arch->id.e_machine, arch->id.e_flags); + free(regname); + return reg; +} + /* * Get register number and access offset from the given instruction. * It assumes AT&T x86 asm format like OFFSET(REG). Maybe it needs * to revisit the format when it handles different architecture. * Fills @reg and @offset when return 0. */ -static int extract_reg_offset(struct arch *arch, const char *str, +static int extract_reg_offset(const struct arch *arch, const char *str, struct annotated_op_loc *op_loc) { char *p; - char *regname; if (arch->objdump.register_char == 0) return -1; @@ -2474,7 +2495,7 @@ static int extract_reg_offset(struct arch *arch, const char *str, * %gs:0x18(%rbx). In that case it should skip the part. */ if (*str == arch->objdump.register_char) { - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { /* FIXME: Handle other segment registers */ if (!strncmp(str, "%gs:", 4)) op_loc->segment = INSN_SEG_X86_GS; @@ -2486,31 +2507,14 @@ static int extract_reg_offset(struct arch *arch, const char *str, } op_loc->offset = strtol(str, &p, 0); - - p = strchr(p, arch->objdump.register_char); - if (p == NULL) + op_loc->reg1 = arch__dwarf_regnum(arch, p); + if (op_loc->reg1 == -1) return -1; - regname = strdup(p); - if (regname == NULL) - return -1; - - op_loc->reg1 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags); - free(regname); - /* Get the second register */ - if (op_loc->multi_regs) { - p = strchr(p + 1, arch->objdump.register_char); - if (p == NULL) - return -1; + if (op_loc->multi_regs) + op_loc->reg2 = arch__dwarf_regnum(arch, p + 1); - regname = strdup(p); - if (regname == NULL) - return -1; - - op_loc->reg2 = get_dwarf_regnum(regname, arch->e_machine, arch->e_flags); - free(regname); - } return 0; } @@ -2538,7 +2542,7 @@ static int extract_reg_offset(struct arch *arch, const char *str, * # dst_reg1 = rbx, dst_reg2 = rcx, dst_mem = 1 * # dst_multi_regs = 1, dst_offset = 8 */ -int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, +int annotate_get_insn_location(const struct arch *arch, struct disasm_line *dl, struct annotated_insn_loc *loc) { struct ins_operands *ops; @@ -2571,7 +2575,7 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, op_loc->reg2 = -1; if (insn_str == NULL) { - if (!arch__is(arch, "powerpc")) + if (!arch__is_powerpc(arch)) continue; } @@ -2580,7 +2584,7 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, * required fields for op_loc, ie reg1, reg2, offset from the * raw instruction. */ - if (arch__is(arch, "powerpc")) { + if (arch__is_powerpc(arch)) { op_loc->mem_ref = mem_ref; op_loc->multi_regs = multi_regs; get_powerpc_regs(dl->raw.raw_insn, !i, op_loc); @@ -2589,9 +2593,10 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, op_loc->multi_regs = multi_regs; extract_reg_offset(arch, insn_str, op_loc); } else { - char *s, *p = NULL; + const char *s = insn_str; + char *p = NULL; - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { /* FIXME: Handle other segment registers */ if (!strncmp(insn_str, "%gs:", 4)) { op_loc->segment = INSN_SEG_X86_GS; @@ -2603,18 +2608,14 @@ int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, } } - s = strdup(insn_str); - if (s == NULL) - return -1; - - if (*s == arch->objdump.register_char) - op_loc->reg1 = get_dwarf_regnum(s, arch->e_machine, arch->e_flags); + if (*s == arch->objdump.register_char) { + op_loc->reg1 = arch__dwarf_regnum(arch, s); + } else if (*s == arch->objdump.imm_char) { op_loc->offset = strtol(s + 1, &p, 0); if (p && p != s + 1) op_loc->imm = true; } - free(s); } } @@ -2673,9 +2674,9 @@ static struct annotated_item_stat *annotate_data_stat(struct list_head *head, return istat; } -static bool is_stack_operation(struct arch *arch, struct disasm_line *dl) +static bool is_stack_operation(const struct arch *arch, struct disasm_line *dl) { - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { if (!strncmp(dl->ins.name, "push", 4) || !strncmp(dl->ins.name, "pop", 3) || !strncmp(dl->ins.name, "call", 4) || @@ -2686,10 +2687,10 @@ static bool is_stack_operation(struct arch *arch, struct disasm_line *dl) return false; } -static bool is_stack_canary(struct arch *arch, struct annotated_op_loc *loc) +static bool is_stack_canary(const struct arch *arch, struct annotated_op_loc *loc) { /* On x86_64, %gs:40 is used for stack canary */ - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { if (loc->segment == INSN_SEG_X86_GS && loc->imm && loc->offset == 40) return true; @@ -2702,9 +2703,9 @@ static bool is_stack_canary(struct arch *arch, struct annotated_op_loc *loc) * Returns true if the instruction has a memory operand without * performing a load/store */ -static bool is_address_gen_insn(struct arch *arch, struct disasm_line *dl) +static bool is_address_gen_insn(const struct arch *arch, struct disasm_line *dl) { - if (arch__is(arch, "x86")) { + if (arch__is_x86(arch)) { if (!strncmp(dl->ins.name, "lea", 3)) return true; } @@ -2791,7 +2792,7 @@ void debuginfo_cache__delete(void) } static struct annotated_data_type * -__hist_entry__get_data_type(struct hist_entry *he, struct arch *arch, +__hist_entry__get_data_type(struct hist_entry *he, const struct arch *arch, struct debuginfo *dbg, struct disasm_line *dl, int *type_offset) { @@ -2847,7 +2848,7 @@ __hist_entry__get_data_type(struct hist_entry *he, struct arch *arch, } /* This CPU access in kernel - pretend PC-relative addressing */ - if (dso__kernel(map__dso(ms->map)) && arch__is(arch, "x86") && + if (dso__kernel(map__dso(ms->map)) && arch__is_x86(arch) && op_loc->segment == INSN_SEG_X86_GS && op_loc->imm) { dloc.var_addr = op_loc->offset; op_loc->reg1 = DWARF_REG_PC; @@ -2895,7 +2896,7 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he) { struct map_symbol *ms = &he->ms; struct evsel *evsel = hists_to_evsel(he->hists); - struct arch *arch; + const struct arch *arch; struct disasm_line *dl; struct annotated_data_type *mem_type; struct annotated_item_stat *istat; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index d4990bff29a7..696e36dbf013 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -202,7 +202,7 @@ struct annotation_write_ops { struct annotation_print_data { struct hist_entry *he; struct evsel *evsel; - struct arch *arch; + const struct arch *arch; struct debuginfo *dbg; /* save data type info keyed by al->offset */ struct hashmap *type_hash; @@ -441,10 +441,10 @@ void symbol__annotate_zero_histograms(struct symbol *sym); int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, - struct arch **parch); + const struct arch **parch); int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel, - struct arch **parch); + const struct arch **parch); enum symbol_disassemble_errno { SYMBOL_ANNOTATE_ERRNO__SUCCESS = 0, @@ -546,7 +546,7 @@ struct annotated_insn_loc { i++, op_loc++) /* Get detailed location info in the instruction */ -int annotate_get_insn_location(struct arch *arch, struct disasm_line *dl, +int annotate_get_insn_location(const struct arch *arch, struct disasm_line *dl, struct annotated_insn_loc *loc); /* Returns a data type from the sample instruction (if any) */ @@ -586,5 +586,5 @@ int annotation_br_cntr_entry(char **str, int br_cntr_nr, u64 *br_cntr, int num_aggr, struct evsel *evsel); int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header); -int evsel__get_arch(struct evsel *evsel, struct arch **parch); +int thread__get_arch(struct thread *thread, const struct arch **parch); #endif /* __PERF_ANNOTATE_H */ diff --git a/tools/perf/util/archinsn.h b/tools/perf/util/archinsn.h deleted file mode 100644 index 448cbb6b8d7e..000000000000 --- a/tools/perf/util/archinsn.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef INSN_H -#define INSN_H 1 - -struct perf_sample; -struct machine; -struct thread; - -void arch_fetch_insn(struct perf_sample *sample, - struct thread *thread, - struct machine *machine); - -#endif diff --git a/tools/perf/util/arm64-frame-pointer-unwind-support.c b/tools/perf/util/arm64-frame-pointer-unwind-support.c index 958afe8b821e..858ce2b01812 100644 --- a/tools/perf/util/arm64-frame-pointer-unwind-support.c +++ b/tools/perf/util/arm64-frame-pointer-unwind-support.c @@ -2,7 +2,6 @@ #include "arm64-frame-pointer-unwind-support.h" #include "callchain.h" #include "event.h" -#include "perf_regs.h" // SMPL_REG_MASK #include "unwind.h" #include @@ -15,6 +14,8 @@ struct entries { size_t length; }; +#define SMPL_REG_MASK(b) (1ULL << (b)) + static bool get_leaf_frame_caller_enabled(struct perf_sample *sample) { struct regs_dump *regs; diff --git a/tools/perf/util/blake2s.c b/tools/perf/util/blake2s.c new file mode 100644 index 000000000000..ce5d89a19376 --- /dev/null +++ b/tools/perf/util/blake2s.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* + * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. + * + * This is an implementation of the BLAKE2s hash and PRF functions. + * + * Information: https://blake2.net/ + */ + +#include "blake2s.h" +#include + +static inline u32 ror32(u32 v, int n) +{ + return (v >> n) | (v << (32 - n)); +} + +static inline void le32_to_cpu_array(u32 a[], size_t n) +{ + for (size_t i = 0; i < n; i++) + a[i] = le32_to_cpu((__force __le32)a[i]); +} + +static inline void cpu_to_le32_array(u32 a[], size_t n) +{ + for (size_t i = 0; i < n; i++) + a[i] = (__force u32)cpu_to_le32(a[i]); +} + +static const u8 blake2s_sigma[10][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, +}; + +static inline void blake2s_increment_counter(struct blake2s_ctx *ctx, u32 inc) +{ + ctx->t[0] += inc; + ctx->t[1] += (ctx->t[0] < inc); +} + +static void blake2s_compress(struct blake2s_ctx *ctx, + const u8 *data, size_t nblocks, u32 inc) +{ + u32 m[16]; + u32 v[16]; + int i; + + while (nblocks > 0) { + blake2s_increment_counter(ctx, inc); + memcpy(m, data, BLAKE2S_BLOCK_SIZE); + le32_to_cpu_array(m, ARRAY_SIZE(m)); + memcpy(v, ctx->h, 32); + v[ 8] = BLAKE2S_IV0; + v[ 9] = BLAKE2S_IV1; + v[10] = BLAKE2S_IV2; + v[11] = BLAKE2S_IV3; + v[12] = BLAKE2S_IV4 ^ ctx->t[0]; + v[13] = BLAKE2S_IV5 ^ ctx->t[1]; + v[14] = BLAKE2S_IV6 ^ ctx->f[0]; + v[15] = BLAKE2S_IV7 ^ ctx->f[1]; + +#define G(r, i, a, b, c, d) do { \ + a += b + m[blake2s_sigma[r][2 * i + 0]]; \ + d = ror32(d ^ a, 16); \ + c += d; \ + b = ror32(b ^ c, 12); \ + a += b + m[blake2s_sigma[r][2 * i + 1]]; \ + d = ror32(d ^ a, 8); \ + c += d; \ + b = ror32(b ^ c, 7); \ +} while (0) + +#define ROUND(r) do { \ + G(r, 0, v[0], v[ 4], v[ 8], v[12]); \ + G(r, 1, v[1], v[ 5], v[ 9], v[13]); \ + G(r, 2, v[2], v[ 6], v[10], v[14]); \ + G(r, 3, v[3], v[ 7], v[11], v[15]); \ + G(r, 4, v[0], v[ 5], v[10], v[15]); \ + G(r, 5, v[1], v[ 6], v[11], v[12]); \ + G(r, 6, v[2], v[ 7], v[ 8], v[13]); \ + G(r, 7, v[3], v[ 4], v[ 9], v[14]); \ +} while (0) + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + +#undef G +#undef ROUND + + for (i = 0; i < 8; ++i) + ctx->h[i] ^= v[i] ^ v[i + 8]; + + data += BLAKE2S_BLOCK_SIZE; + --nblocks; + } +} + +static inline void blake2s_set_lastblock(struct blake2s_ctx *ctx) +{ + ctx->f[0] = -1; +} + +void blake2s_update(struct blake2s_ctx *ctx, const u8 *in, size_t inlen) +{ + const size_t fill = BLAKE2S_BLOCK_SIZE - ctx->buflen; + + if (unlikely(!inlen)) + return; + if (inlen > fill) { + memcpy(ctx->buf + ctx->buflen, in, fill); + blake2s_compress(ctx, ctx->buf, 1, BLAKE2S_BLOCK_SIZE); + ctx->buflen = 0; + in += fill; + inlen -= fill; + } + if (inlen > BLAKE2S_BLOCK_SIZE) { + const size_t nblocks = DIV_ROUND_UP(inlen, BLAKE2S_BLOCK_SIZE); + + blake2s_compress(ctx, in, nblocks - 1, BLAKE2S_BLOCK_SIZE); + in += BLAKE2S_BLOCK_SIZE * (nblocks - 1); + inlen -= BLAKE2S_BLOCK_SIZE * (nblocks - 1); + } + memcpy(ctx->buf + ctx->buflen, in, inlen); + ctx->buflen += inlen; +} + +void blake2s_final(struct blake2s_ctx *ctx, u8 *out) +{ + blake2s_set_lastblock(ctx); + memset(ctx->buf + ctx->buflen, 0, + BLAKE2S_BLOCK_SIZE - ctx->buflen); /* Padding */ + blake2s_compress(ctx, ctx->buf, 1, ctx->buflen); + cpu_to_le32_array(ctx->h, ARRAY_SIZE(ctx->h)); + memcpy(out, ctx->h, ctx->outlen); + memset(ctx, 0, sizeof(*ctx)); +} diff --git a/tools/perf/util/blake2s.h b/tools/perf/util/blake2s.h new file mode 100644 index 000000000000..a1fe81a4bea8 --- /dev/null +++ b/tools/perf/util/blake2s.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright (C) 2015-2019 Jason A. Donenfeld . All Rights Reserved. + */ + +#ifndef _CRYPTO_BLAKE2S_H +#define _CRYPTO_BLAKE2S_H + +#include +#include + +#define BLAKE2S_BLOCK_SIZE 64 + +struct blake2s_ctx { + u32 h[8]; + u32 t[2]; + u32 f[2]; + u8 buf[BLAKE2S_BLOCK_SIZE]; + unsigned int buflen; + unsigned int outlen; +}; + +enum blake2s_iv { + BLAKE2S_IV0 = 0x6A09E667UL, + BLAKE2S_IV1 = 0xBB67AE85UL, + BLAKE2S_IV2 = 0x3C6EF372UL, + BLAKE2S_IV3 = 0xA54FF53AUL, + BLAKE2S_IV4 = 0x510E527FUL, + BLAKE2S_IV5 = 0x9B05688CUL, + BLAKE2S_IV6 = 0x1F83D9ABUL, + BLAKE2S_IV7 = 0x5BE0CD19UL, +}; + +static inline void __blake2s_init(struct blake2s_ctx *ctx, size_t outlen, + const void *key, size_t keylen) +{ + ctx->h[0] = BLAKE2S_IV0 ^ (0x01010000 | keylen << 8 | outlen); + ctx->h[1] = BLAKE2S_IV1; + ctx->h[2] = BLAKE2S_IV2; + ctx->h[3] = BLAKE2S_IV3; + ctx->h[4] = BLAKE2S_IV4; + ctx->h[5] = BLAKE2S_IV5; + ctx->h[6] = BLAKE2S_IV6; + ctx->h[7] = BLAKE2S_IV7; + ctx->t[0] = 0; + ctx->t[1] = 0; + ctx->f[0] = 0; + ctx->f[1] = 0; + ctx->buflen = 0; + ctx->outlen = outlen; + if (keylen) { + memcpy(ctx->buf, key, keylen); + memset(&ctx->buf[keylen], 0, BLAKE2S_BLOCK_SIZE - keylen); + ctx->buflen = BLAKE2S_BLOCK_SIZE; + } +} + +static inline void blake2s_init(struct blake2s_ctx *ctx, size_t outlen) +{ + __blake2s_init(ctx, outlen, NULL, 0); +} + +static inline void blake2s_init_key(struct blake2s_ctx *ctx, size_t outlen, + const void *key, size_t keylen) +{ + __blake2s_init(ctx, outlen, key, keylen); +} + +void blake2s_update(struct blake2s_ctx *ctx, const u8 *in, size_t inlen); + +void blake2s_final(struct blake2s_ctx *ctx, u8 *out); + +#endif /* _CRYPTO_BLAKE2S_H */ diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 2298cd396c42..67e7786bb878 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -733,7 +733,8 @@ kallsyms_process_symbol(void *data, const char *_name, char type __maybe_unused, u64 start) { char disp[KSYM_NAME_LEN]; - char *module, *name; + const char *module; + char *name; unsigned long id; int err = 0; @@ -787,11 +788,10 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, err = 0; break; } - pr_debug("%s: can't get next program: %s%s\n", - __func__, strerror(errno), - errno == EINVAL ? " -- kernel too old?" : ""); /* don't report error on old kernel or EPERM */ err = (errno == EINVAL || errno == EPERM) ? 0 : -1; + pr_debug("%s: can\'t get next program: %m%s\n", + __func__, errno == EINVAL ? " -- kernel too old?" : ""); break; } fd = bpf_prog_get_fd_by_id(id); @@ -824,10 +824,8 @@ int perf_event__synthesize_bpf_events(struct perf_session *session, .tool = session->tool, }; - if (kallsyms__parse(kallsyms_filename, &arg, kallsyms_process_symbol)) { - pr_err("%s: failed to synthesize bpf images: %s\n", - __func__, strerror(errno)); - } + if (kallsyms__parse(kallsyms_filename, &arg, kallsyms_process_symbol)) + pr_err("%s: failed to synthesize bpf images: %m\n", __func__); free(event); return err; diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c index 5a66dc8594aa..d6d2c9c190f7 100644 --- a/tools/perf/util/bpf-utils.c +++ b/tools/perf/util/bpf-utils.c @@ -123,7 +123,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) /* step 1: get array dimensions */ err = bpf_obj_get_info_by_fd(fd, &info, &info_len); if (err) { - pr_debug("can't get prog info: %s", strerror(errno)); + pr_debug("can't get prog info: %m\n"); return ERR_PTR(-EFAULT); } if (info.type >= __MAX_BPF_PROG_TYPE) @@ -186,7 +186,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays) /* step 5: call syscall again to get required arrays */ err = bpf_obj_get_info_by_fd(fd, &info_linear->info, &info_len); if (err) { - pr_debug("can't get prog info: %s", strerror(errno)); + pr_debug("can't get prog info: %m\n"); free(info_linear); return ERR_PTR(-EFAULT); } diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c index 7b5671f13c53..cbd7435579fe 100644 --- a/tools/perf/util/bpf_lock_contention.c +++ b/tools/perf/util/bpf_lock_contention.c @@ -42,7 +42,7 @@ static void check_slab_cache_iter(struct lock_contention *con) con->btf = btf__load_vmlinux_btf(); if (con->btf == NULL) { - pr_debug("BTF loading failed: %s\n", strerror(errno)); + pr_debug("BTF loading failed: %m\n"); return; } @@ -117,6 +117,9 @@ static void init_numa_data(struct lock_contention *con) long last = -1; int ret; + if (!con->btf) + return; + /* * 'struct zone' is embedded in 'struct pglist_data' as an array. * As we may not have full information of the struct zone in the diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 428e5350d7a2..8ff0898799ee 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -31,6 +31,7 @@ #include "callchain.h" #include "branch.h" #include "symbol.h" +#include "thread.h" #include "util.h" #include "../perf.h" @@ -1042,7 +1043,7 @@ merge_chain_branch(struct callchain_cursor *cursor, list_for_each_entry_safe(list, next_list, &src->val, list) { struct map_symbol ms = { - .maps = maps__get(list->ms.maps), + .thread = thread__get(list->ms.thread), .map = map__get(list->ms.map), }; callchain_cursor_append(cursor, list->ip, &ms, false, NULL, 0, 0, 0, list->srcline); @@ -1147,10 +1148,11 @@ int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *samp int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node, bool hide_unresolved) { - struct machine *machine = node->ms.maps ? maps__machine(node->ms.maps) : NULL; + struct machine *machine = NULL; + + if (node->ms.thread) + machine = maps__machine(thread__maps(node->ms.thread)); - maps__put(al->maps); - al->maps = maps__get(node->ms.maps); map__put(al->map); al->map = map__get(node->ms.map); al->sym = node->ms.sym; @@ -1163,7 +1165,7 @@ int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node * if (al->map == NULL) goto out; } - if (maps__equal(al->maps, machine__kernel_maps(machine))) { + if (maps__equal(thread__maps(al->thread), machine__kernel_maps(machine))) { if (machine__is_host(machine)) { al->cpumode = PERF_RECORD_MISC_KERNEL; al->level = 'k'; @@ -1679,7 +1681,7 @@ void callchain_cursor_reset(struct callchain_cursor *cursor) map_symbol__exit(&node->ms); } -void callchain_param_setup(u64 sample_type, const char *arch) +void callchain_param_setup(u64 sample_type, uint16_t e_machine) { if (symbol_conf.use_callchain || symbol_conf.cumulate_callchain) { if ((sample_type & PERF_SAMPLE_REGS_USER) && @@ -1701,7 +1703,7 @@ void callchain_param_setup(u64 sample_type, const char *arch) * erroneous entries. Always skipping the LR and starting from the FP * can result in missing entries. */ - if (callchain_param.record_mode == CALLCHAIN_FP && !strcmp(arch, "arm64")) + if (callchain_param.record_mode == CALLCHAIN_FP && e_machine == EM_AARCH64) dwarf_callchain_users = true; } diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 2a52af8c80ac..df54ddb8c0cb 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -303,7 +303,7 @@ int callchain_branch_counts(struct callchain_root *root, u64 *branch_count, u64 *predicted_count, u64 *abort_count, u64 *cycles_count); -void callchain_param_setup(u64 sample_type, const char *arch); +void callchain_param_setup(u64 sample_type, uint16_t e_machine); bool callchain_cnode_matched(struct callchain_node *base_cnode, struct callchain_node *pair_cnode); diff --git a/tools/perf/util/cap.c b/tools/perf/util/cap.c index 24a0ea7e6d97..ac6d1d9a523d 100644 --- a/tools/perf/util/cap.c +++ b/tools/perf/util/cap.c @@ -28,8 +28,7 @@ bool perf_cap__capable(int cap, bool *used_root) header.version == _LINUX_CAPABILITY_VERSION_1) continue; - pr_debug2("capget syscall failed (%s - %d) fall back on root check\n", - strerror(errno), errno); + pr_debug2("capget syscall failed (%m) fall back on root check\n"); *used_root = true; return geteuid() == 0; } diff --git a/tools/perf/util/capstone.c b/tools/perf/util/capstone.c index be5fd44b1f9d..25cf6e15ec27 100644 --- a/tools/perf/util/capstone.c +++ b/tools/perf/util/capstone.c @@ -11,20 +11,137 @@ #include "print_insn.h" #include "symbol.h" #include "thread.h" +#include #include #include +#include #include -#ifdef HAVE_LIBCAPSTONE_SUPPORT #include + +#ifdef LIBCAPSTONE_DLOPEN +static void *perf_cs_dll_handle(void) +{ + static bool dll_handle_init; + static void *dll_handle; + + if (!dll_handle_init) { + dll_handle_init = true; + dll_handle = dlopen("libcapstone.so", RTLD_LAZY); + if (!dll_handle) + pr_debug("dlopen failed for libcapstone.so\n"); + } + return dll_handle; +} #endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT +static enum cs_err perf_cs_open(enum cs_arch arch, enum cs_mode mode, csh *handle) +{ +#ifndef LIBCAPSTONE_DLOPEN + return cs_open(arch, mode, handle); +#else + static bool fn_init; + static enum cs_err (*fn)(enum cs_arch arch, enum cs_mode mode, csh *handle); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_open"); + if (!fn) + pr_debug("dlsym failed for cs_open\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(arch, mode, handle); +#endif +} + +static enum cs_err perf_cs_option(csh handle, enum cs_opt_type type, size_t value) +{ +#ifndef LIBCAPSTONE_DLOPEN + return cs_option(handle, type, value); +#else + static bool fn_init; + static enum cs_err (*fn)(csh handle, enum cs_opt_type type, size_t value); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_option"); + if (!fn) + pr_debug("dlsym failed for cs_option\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle, type, value); +#endif +} + +static size_t perf_cs_disasm(csh handle, const uint8_t *code, size_t code_size, + uint64_t address, size_t count, struct cs_insn **insn) +{ +#ifndef LIBCAPSTONE_DLOPEN + return cs_disasm(handle, code, code_size, address, count, insn); +#else + static bool fn_init; + static enum cs_err (*fn)(csh handle, const uint8_t *code, size_t code_size, + uint64_t address, size_t count, struct cs_insn **insn); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_disasm"); + if (!fn) + pr_debug("dlsym failed for cs_disasm\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle, code, code_size, address, count, insn); +#endif +} + +static void perf_cs_free(struct cs_insn *insn, size_t count) +{ +#ifndef LIBCAPSTONE_DLOPEN + cs_free(insn, count); +#else + static bool fn_init; + static void (*fn)(struct cs_insn *insn, size_t count); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_free"); + if (!fn) + pr_debug("dlsym failed for cs_free\n"); + fn_init = true; + } + if (!fn) + return; + fn(insn, count); +#endif +} + +static enum cs_err perf_cs_close(csh *handle) +{ +#ifndef LIBCAPSTONE_DLOPEN + return cs_close(handle); +#else + static bool fn_init; + static enum cs_err (*fn)(csh *handle); + + if (!fn_init) { + fn = dlsym(perf_cs_dll_handle(), "cs_close"); + if (!fn) + pr_debug("dlsym failed for cs_close\n"); + fn_init = true; + } + if (!fn) + return CS_ERR_HANDLE; + return fn(handle); +#endif +} + static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, bool disassembler_style) { - cs_arch arch; - cs_mode mode; + enum cs_arch arch; + enum cs_mode mode; if (machine__is(machine, "x86_64") && is64) { arch = CS_ARCH_X86; @@ -45,7 +162,7 @@ static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, return -1; } - if (cs_open(arch, mode, cs_handle) != CS_ERR_OK) { + if (perf_cs_open(arch, mode, cs_handle) != CS_ERR_OK) { pr_warning_once("cs_open failed\n"); return -1; } @@ -57,27 +174,25 @@ static int capstone_init(struct machine *machine, csh *cs_handle, bool is64, * is set via annotation args */ if (disassembler_style) - cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); + perf_cs_option(*cs_handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_ATT); /* * Resolving address operands to symbols is implemented * on x86 by investigating instruction details. */ - cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); + perf_cs_option(*cs_handle, CS_OPT_DETAIL, CS_OPT_ON); } return 0; } -#endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, +static size_t print_insn_x86(struct thread *thread, u8 cpumode, struct cs_insn *insn, int print_opts, FILE *fp) { struct addr_location al; size_t printed = 0; if (insn->detail && insn->detail->x86.op_count == 1) { - cs_x86_op *op = &insn->detail->x86.operands[0]; + struct cs_x86_op *op = &insn->detail->x86.operands[0]; addr_location__init(&al); if (op->type == X86_OP_IMM && @@ -95,7 +210,6 @@ static size_t print_insn_x86(struct thread *thread, u8 cpumode, cs_insn *insn, printed += fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); return printed; } -#endif ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, @@ -106,9 +220,8 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, uint64_t ip __maybe_unused, int *lenp __maybe_unused, int print_opts __maybe_unused, FILE *fp __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT size_t printed; - cs_insn *insn; + struct cs_insn *insn; csh cs_handle; size_t count; int ret; @@ -118,7 +231,7 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, if (ret < 0) return ret; - count = cs_disasm(cs_handle, code, code_size, ip, 1, &insn); + count = perf_cs_disasm(cs_handle, code, code_size, ip, 1, &insn); if (count > 0) { if (machine__normalized_is(machine, "x86")) printed = print_insn_x86(thread, cpumode, &insn[0], print_opts, fp); @@ -126,35 +239,31 @@ ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, printed = fprintf(fp, "%s %s", insn[0].mnemonic, insn[0].op_str); if (lenp) *lenp = insn->size; - cs_free(insn, count); + perf_cs_free(insn, count); } else { printed = -1; } - cs_close(&cs_handle); + perf_cs_close(&cs_handle); return printed; -#else - return -1; -#endif } -#ifdef HAVE_LIBCAPSTONE_SUPPORT -static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, +static void print_capstone_detail(struct cs_insn *insn, char *buf, size_t len, struct annotate_args *args, u64 addr) { int i; - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct symbol *sym; /* TODO: support more architectures */ - if (!arch__is(args->arch, "x86")) + if (!arch__is_x86(args->arch)) return; if (insn->detail == NULL) return; for (i = 0; i < insn->detail->x86.op_count; i++) { - cs_x86_op *op = &insn->detail->x86.operands[i]; + struct cs_x86_op *op = &insn->detail->x86.operands[i]; u64 orig_addr; if (op->type != X86_OP_MEM) @@ -195,9 +304,7 @@ static void print_capstone_detail(cs_insn *insn, char *buf, size_t len, break; } } -#endif -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct find_file_offset_data { u64 ip; u64 offset; @@ -214,15 +321,13 @@ static int find_file_offset(u64 start, u64 len, u64 pgoff, void *arg) } return 0; } -#endif int symbol__disassemble_capstone(const char *filename __maybe_unused, struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); u64 start = map__rip_2objdump(map, sym->start); u64 offset; @@ -235,7 +340,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, const u8 *buf; u64 buf_len; csh handle; - cs_insn *insn = NULL; + struct cs_insn *insn = NULL; char disasm_buf[512]; struct disasm_line *dl; bool disassembler_style = false; @@ -256,7 +361,7 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, args->line = disasm_buf; args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl == NULL) @@ -268,12 +373,13 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, !strcmp(args->options->disassembler_style, "att")) disassembler_style = true; - if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) + if (capstone_init(maps__machine(thread__maps(args->ms->thread)), &handle, is_64bit, + disassembler_style) < 0) goto err; needs_cs_close = true; - free_count = count = cs_disasm(handle, buf, buf_len, start, buf_len, &insn); + free_count = count = perf_cs_disasm(handle, buf, buf_len, start, buf_len, &insn); for (i = 0, offset = 0; i < count; i++) { int printed; @@ -312,9 +418,9 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, out: if (needs_cs_close) { - cs_close(&handle); + perf_cs_close(&handle); if (free_count > 0) - cs_free(insn, free_count); + perf_cs_free(insn, free_count); } free(code_buf); return count < 0 ? count : 0; @@ -334,18 +440,14 @@ int symbol__disassemble_capstone(const char *filename __maybe_unused, } count = -1; goto out; -#else - return -1; -#endif } int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, struct symbol *sym __maybe_unused, struct annotate_args *args __maybe_unused) { -#ifdef HAVE_LIBCAPSTONE_SUPPORT struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); struct nscookie nsc; u64 start = map__rip_2objdump(map, sym->start); @@ -382,7 +484,8 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, !strcmp(args->options->disassembler_style, "att")) disassembler_style = true; - if (capstone_init(maps__machine(args->ms.maps), &handle, is_64bit, disassembler_style) < 0) + if (capstone_init(maps__machine(thread__maps(args->ms->thread)), &handle, is_64bit, + disassembler_style) < 0) goto err; needs_cs_close = true; @@ -408,7 +511,7 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, args->line = disasm_buf; args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl == NULL) @@ -456,7 +559,7 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, out: if (needs_cs_close) - cs_close(&handle); + perf_cs_close(&handle); free(buf); return count < 0 ? count : 0; @@ -465,7 +568,4 @@ int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, close(fd); count = -1; goto out; -#else - return -1; -#endif } diff --git a/tools/perf/util/capstone.h b/tools/perf/util/capstone.h index 0f030ea034b6..7c0baaa01a73 100644 --- a/tools/perf/util/capstone.h +++ b/tools/perf/util/capstone.h @@ -6,6 +6,7 @@ #include #include #include +#include #include struct annotate_args; @@ -13,6 +14,7 @@ struct machine; struct symbol; struct thread; +#ifdef HAVE_LIBCAPSTONE_SUPPORT ssize_t capstone__fprintf_insn_asm(struct machine *machine, struct thread *thread, u8 cpumode, bool is64bit, const uint8_t *code, size_t code_size, uint64_t ip, int *lenp, int print_opts, FILE *fp); @@ -21,4 +23,35 @@ int symbol__disassemble_capstone(const char *filename, struct symbol *sym, int symbol__disassemble_capstone_powerpc(const char *filename, struct symbol *sym, struct annotate_args *args); +#else /* !HAVE_LIBCAPSTONE_SUPPORT */ +static inline ssize_t capstone__fprintf_insn_asm(struct machine *machine __maybe_unused, + struct thread *thread __maybe_unused, + u8 cpumode __maybe_unused, + bool is64bit __maybe_unused, + const uint8_t *code __maybe_unused, + size_t code_size __maybe_unused, + uint64_t ip __maybe_unused, + int *lenp __maybe_unused, + int print_opts __maybe_unused, + FILE *fp __maybe_unused) +{ + return -1; +} + +static inline int symbol__disassemble_capstone(const char *filename __maybe_unused, + struct symbol *sym __maybe_unused, + struct annotate_args *args __maybe_unused) +{ + return -1; +} + +static inline int symbol__disassemble_capstone_powerpc(const char *filename __maybe_unused, + struct symbol *sym __maybe_unused, + struct annotate_args *args __maybe_unused) +{ + return -1; +} + +#endif /* HAVE_LIBCAPSTONE_SUPPORT */ + #endif /* __PERF_CAPSTONE_H */ diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index e0219bc6330a..0452fbc6c085 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -20,6 +20,7 @@ #include "util/stat.h" /* perf_stat__set_big_num */ #include "util/evsel.h" /* evsel__hw_names, evsel__use_bpf_counters */ #include "util/addr2line.h" /* addr2line_timeout_ms */ +#include "srcline.h" #include "build-id.h" #include "debug.h" #include "config.h" @@ -519,6 +520,9 @@ int perf_default_config(const char *var, const char *value, if (strstarts(var, "stat.")) return perf_stat_config(var, value); + if (strstarts(var, "addr2line.")) + return addr2line_configure(var, value, dummy); + /* Add other config variables here. */ return 0; } diff --git a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c index 3050fe212666..212f17a3dc72 100644 --- a/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c +++ b/tools/perf/util/cs-etm-decoder/cs-etm-decoder.c @@ -549,7 +549,7 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq, /* * Process the PE_CONTEXT packets if we have a valid contextID or VMID. * If the kernel is running at EL2, the PID is traced in CONTEXTIDR_EL2 - * as VMID, Bit ETM_OPT_CTXTID2 is set in this case. + * as VMID, Format attribute 'contextid2' is set in this case. */ switch (cs_etm__get_pid_fmt(etmq)) { case CS_ETM_PIDFMT_CTXTID: diff --git a/tools/perf/util/cs-etm.c b/tools/perf/util/cs-etm.c index 25d56e0f1c07..8a639d2e51a4 100644 --- a/tools/perf/util/cs-etm.c +++ b/tools/perf/util/cs-etm.c @@ -6,7 +6,6 @@ * Author: Mathieu Poirier */ -#include #include #include #include @@ -195,7 +194,7 @@ int cs_etm__get_cpu(struct cs_etm_queue *etmq, u8 trace_chan_id, int *cpu) * CS_ETM_PIDFMT_CTXTID2: CONTEXTIDR_EL2 is traced. * CS_ETM_PIDFMT_NONE: No context IDs * - * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2 + * It's possible that the two format attributes 'contextid1' and 'contextid2' * are enabled at the same time when the session runs on an EL2 kernel. * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be * recorded in the trace data, the tool will selectively use @@ -211,15 +210,15 @@ static enum cs_etm_pid_fmt cs_etm__init_pid_fmt(u64 *metadata) if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) { val = metadata[CS_ETM_ETMCR]; /* CONTEXTIDR is traced */ - if (val & BIT(ETM_OPT_CTXTID)) + if (val & ETMCR_CTXTID) return CS_ETM_PIDFMT_CTXTID; } else { val = metadata[CS_ETMV4_TRCCONFIGR]; /* CONTEXTIDR_EL2 is traced */ - if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT))) + if (val & (TRCCONFIGR_VMID | TRCCONFIGR_VMIDOPT)) return CS_ETM_PIDFMT_CTXTID2; /* CONTEXTIDR_EL1 is traced */ - else if (val & BIT(ETM4_CFG_BIT_CTXTID)) + else if (val & TRCCONFIGR_CID) return CS_ETM_PIDFMT_CTXTID; } @@ -2915,29 +2914,21 @@ static int cs_etm__process_auxtrace_event(struct perf_session *session, return 0; } -static int cs_etm__setup_timeless_decoding(struct cs_etm_auxtrace *etm) +static void cs_etm__setup_timeless_decoding(struct cs_etm_auxtrace *etm) { - struct evsel *evsel; - struct evlist *evlist = etm->session->evlist; + /* Take first ETM as all options will be the same for all ETMs */ + u64 *metadata = etm->metadata[0]; /* Override timeless mode with user input from --itrace=Z */ if (etm->synth_opts.timeless_decoding) { etm->timeless_decoding = true; - return 0; + return; } - /* - * Find the cs_etm evsel and look at what its timestamp setting was - */ - evlist__for_each_entry(evlist, evsel) - if (cs_etm__evsel_is_auxtrace(etm->session, evsel)) { - etm->timeless_decoding = - !(evsel->core.attr.config & BIT(ETM_OPT_TS)); - return 0; - } - - pr_err("CS ETM: Couldn't find ETM evsel\n"); - return -EINVAL; + if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) + etm->timeless_decoding = !(metadata[CS_ETM_ETMCR] & ETMCR_TIMESTAMP_EN); + else + etm->timeless_decoding = !(metadata[CS_ETMV4_TRCCONFIGR] & TRCCONFIGR_TS); } /* @@ -3086,7 +3077,7 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o if (aux_offset >= auxtrace_event->offset && aux_offset + aux_size <= auxtrace_event->offset + auxtrace_event->size) { - struct cs_etm_queue *etmq = etm->queues.queue_array[auxtrace_event->idx].priv; + struct cs_etm_queue *etmq = cs_etm__get_queue(etm, auxtrace_event->cpu); /* * If this AUX event was inside this buffer somewhere, create a new auxtrace event @@ -3095,6 +3086,7 @@ static int cs_etm__queue_aux_fragment(struct perf_session *session, off_t file_o auxtrace_fragment.auxtrace = *auxtrace_event; auxtrace_fragment.auxtrace.size = aux_size; auxtrace_fragment.auxtrace.offset = aux_offset; + auxtrace_fragment.auxtrace.idx = etmq->queue_nr; file_offset += aux_offset - auxtrace_event->offset + auxtrace_event->header.size; pr_debug3("CS ETM: Queue buffer size: %#"PRI_lx64" offset: %#"PRI_lx64 @@ -3499,9 +3491,7 @@ int cs_etm__process_auxtrace_info_full(union perf_event *event, etm->auxtrace.evsel_is_auxtrace = cs_etm__evsel_is_auxtrace; session->auxtrace = &etm->auxtrace; - err = cs_etm__setup_timeless_decoding(etm); - if (err) - return err; + cs_etm__setup_timeless_decoding(etm); etm->tc.time_shift = tc->time_shift; etm->tc.time_mult = tc->time_mult; diff --git a/tools/perf/util/cs-etm.h b/tools/perf/util/cs-etm.h index a8caeea720aa..aa9bb4a32eca 100644 --- a/tools/perf/util/cs-etm.h +++ b/tools/perf/util/cs-etm.h @@ -230,6 +230,21 @@ struct cs_etm_packet_queue { /* CoreSight trace ID is currently the bottom 7 bits of the value */ #define CORESIGHT_TRACE_ID_VAL_MASK GENMASK(6, 0) +/* ETMv4 CONFIGR register bits */ +#define TRCCONFIGR_BB BIT(3) +#define TRCCONFIGR_CCI BIT(4) +#define TRCCONFIGR_CID BIT(6) +#define TRCCONFIGR_VMID BIT(7) +#define TRCCONFIGR_TS BIT(11) +#define TRCCONFIGR_RS BIT(12) +#define TRCCONFIGR_VMIDOPT BIT(15) + +/* ETMv3 ETMCR register bits */ +#define ETMCR_CYC_ACC BIT(12) +#define ETMCR_CTXTID BIT(14) +#define ETMCR_TIMESTAMP_EN BIT(28) +#define ETMCR_RETURN_STACK BIT(29) + int cs_etm__process_auxtrace_info(union perf_event *event, struct perf_session *session); void cs_etm_get_default_config(const struct perf_pmu *pmu, struct perf_event_attr *attr); diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c index 3d2e437e1354..ba1c8e48d495 100644 --- a/tools/perf/util/data-convert-bt.c +++ b/tools/perf/util/data-convert-bt.c @@ -34,6 +34,8 @@ #include "util.h" #include "clockid.h" #include "util/sample.h" +#include "util/time-utils.h" +#include "header.h" #ifdef HAVE_LIBTRACEEVENT #include @@ -91,9 +93,14 @@ struct convert { struct perf_tool tool; struct ctf_writer writer; + struct perf_time_interval *ptime_range; + int range_size; + int range_num; + u64 events_size; u64 events_count; u64 non_sample_count; + u64 skipped; /* Ordered events configured queue size. */ u64 queue_size; @@ -811,6 +818,11 @@ static int process_sample_event(const struct perf_tool *tool, if (WARN_ONCE(!priv, "Failed to setup all events.\n")) return 0; + if (perf_time__ranges_skip_sample(c->ptime_range, c->range_num, sample->time)) { + ++c->skipped; + return 0; + } + event_class = priv->event_class; /* update stats */ @@ -1327,7 +1339,8 @@ static void cleanup_events(struct perf_session *session) struct evsel_priv *priv; priv = evsel->priv; - bt_ctf_event_class_put(priv->event_class); + if (priv) + bt_ctf_event_class_put(priv->event_class); zfree(&evsel->priv); } @@ -1376,7 +1389,7 @@ static int ctf_writer__setup_env(struct ctf_writer *cw, #define ADD(__n, __v) \ do { \ - if (bt_ctf_writer_add_environment_field(writer, __n, __v)) \ + if (__v && bt_ctf_writer_add_environment_field(writer, __n, __v)) \ return -1; \ } while (0) @@ -1392,6 +1405,52 @@ do { \ return 0; } +static int process_feature_event(const struct perf_tool *tool, + struct perf_session *session, + union perf_event *event) +{ + struct convert *c = container_of(tool, struct convert, tool); + struct ctf_writer *cw = &c->writer; + struct perf_record_header_feature *fe = &event->feat; + + if (event->feat.feat_id < HEADER_LAST_FEATURE) { + int ret = perf_event__process_feature(session, event); + + if (ret) + return ret; + } + + switch (fe->feat_id) { + case HEADER_HOSTNAME: + if (session->header.env.hostname) { + return bt_ctf_writer_add_environment_field(cw->writer, "host", + session->header.env.hostname); + } + break; + case HEADER_OSRELEASE: + if (session->header.env.os_release) { + return bt_ctf_writer_add_environment_field(cw->writer, "release", + session->header.env.os_release); + } + break; + case HEADER_VERSION: + if (session->header.env.version) { + return bt_ctf_writer_add_environment_field(cw->writer, "version", + session->header.env.version); + } + break; + case HEADER_ARCH: + if (session->header.env.arch) { + return bt_ctf_writer_add_environment_field(cw->writer, "machine", + session->header.env.arch); + } + break; + default: + break; + } + return 0; +} + static int ctf_writer__setup_clock(struct ctf_writer *cw, struct perf_session *session, bool tod) @@ -1624,6 +1683,8 @@ int bt_convert__perf2ctf(const char *input, const char *path, c.tool.tracing_data = perf_event__process_tracing_data; c.tool.build_id = perf_event__process_build_id; c.tool.namespaces = perf_event__process_namespaces; + c.tool.attr = perf_event__process_attr; + c.tool.feature = process_feature_event; c.tool.ordering_requires_timestamps = true; if (opts->all) { @@ -1644,6 +1705,15 @@ int bt_convert__perf2ctf(const char *input, const char *path, if (IS_ERR(session)) return PTR_ERR(session); + if (opts->time_str) { + err = perf_time__parse_for_ranges(opts->time_str, session, + &c.ptime_range, + &c.range_size, + &c.range_num); + if (err < 0) + goto free_session; + } + /* CTF writer */ if (ctf_writer__init(cw, path, session, opts->tod)) goto free_session; @@ -1673,12 +1743,10 @@ int bt_convert__perf2ctf(const char *input, const char *path, else pr_err("Error during conversion.\n"); - fprintf(stderr, - "[ perf data convert: Converted '%s' into CTF data '%s' ]\n", + fprintf(stderr, "[ perf data convert: Converted '%s' into CTF data '%s' ]\n", data.path, path); - fprintf(stderr, - "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", + fprintf(stderr, "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", (double) c.events_size / 1024.0 / 1024.0, c.events_count); @@ -1687,6 +1755,14 @@ int bt_convert__perf2ctf(const char *input, const char *path, else fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count); + if (c.skipped) { + fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n", + c.skipped); + } + + if (c.ptime_range) + zfree(&c.ptime_range); + cleanup_events(session); perf_session__delete(session); ctf_writer__cleanup(cw); @@ -1696,6 +1772,9 @@ int bt_convert__perf2ctf(const char *input, const char *path, free_writer: ctf_writer__cleanup(cw); free_session: + if (c.ptime_range) + zfree(&c.ptime_range); + perf_session__delete(session); pr_err("Error during conversion setup.\n"); return err; diff --git a/tools/perf/util/data-convert-json.c b/tools/perf/util/data-convert-json.c index 9dc1e184cf3c..6a626322476a 100644 --- a/tools/perf/util/data-convert-json.c +++ b/tools/perf/util/data-convert-json.c @@ -25,6 +25,7 @@ #include "util/session.h" #include "util/symbol.h" #include "util/thread.h" +#include "util/time-utils.h" #include "util/tool.h" #ifdef HAVE_LIBTRACEEVENT @@ -35,13 +36,21 @@ struct convert_json { struct perf_tool tool; FILE *out; bool first; + struct perf_time_interval *ptime_range; + int range_size; + int range_num; + u64 events_count; + u64 skipped; }; // Outputs a JSON-encoded string surrounded by quotes with characters escaped. static void output_json_string(FILE *out, const char *s) { fputc('"', out); + if (!s) + goto out; + while (*s) { switch (*s) { @@ -65,6 +74,7 @@ static void output_json_string(FILE *out, const char *s) ++s; } +out: fputc('"', out); } @@ -165,6 +175,11 @@ static int process_sample_event(const struct perf_tool *tool, return -1; } + if (perf_time__ranges_skip_sample(c->ptime_range, c->range_num, sample->time)) { + ++c->skipped; + return 0; + } + ++c->events_count; if (c->first) @@ -311,6 +326,16 @@ static void output_headers(struct perf_session *session, struct convert_json *c) output_json_format(out, false, 2, "]"); } +static int process_feature_event(const struct perf_tool *tool __maybe_unused, + struct perf_session *session, + union perf_event *event) +{ + if (event->feat.feat_id < HEADER_LAST_FEATURE) + return perf_event__process_feature(session, event); + + return 0; +} + int bt_convert__perf2json(const char *input_name, const char *output_name, struct perf_data_convert_opts *opts __maybe_unused) { @@ -320,6 +345,10 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, struct convert_json c = { .first = true, .events_count = 0, + .ptime_range = NULL, + .range_size = 0, + .range_num = 0, + .skipped = 0, }; struct perf_data data = { .mode = PERF_DATA_MODE_READ, @@ -345,6 +374,8 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, c.tool.auxtrace_info = perf_event__process_auxtrace_info; c.tool.auxtrace = perf_event__process_auxtrace; c.tool.event_update = perf_event__process_event_update; + c.tool.attr = perf_event__process_attr; + c.tool.feature = process_feature_event; c.tool.ordering_requires_timestamps = true; if (opts->all) { @@ -382,6 +413,15 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, goto err_session_delete; } + if (opts->time_str) { + ret = perf_time__parse_for_ranges(opts->time_str, session, + &c.ptime_range, + &c.range_size, + &c.range_num); + if (ret < 0) + goto err_session_delete; + } + // The opening brace is printed manually because it isn't delimited from a // previous value (i.e. we don't want a leading newline) fputc('{', c.out); @@ -403,15 +443,23 @@ int bt_convert__perf2json(const char *input_name, const char *output_name, output_json_format(c.out, false, 0, "}"); fputc('\n', c.out); - fprintf(stderr, - "[ perf data convert: Converted '%s' into JSON data '%s' ]\n", - data.path, output_name); + fprintf(stderr, "[ perf data convert: Converted '%s' into JSON data '%s' ]\n", + data.path, output_name); fprintf(stderr, - "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", - (ftell(c.out)) / 1024.0 / 1024.0, c.events_count); + "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n", + (ftell(c.out)) / 1024.0 / 1024.0, c.events_count); + + if (c.skipped) { + fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n", + c.skipped); + } ret = 0; + + if (c.ptime_range) + zfree(&c.ptime_range); + err_session_delete: perf_session__delete(session); err_fclose: diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h index 1b4c5f598415..ee651fa680a1 100644 --- a/tools/perf/util/data-convert.h +++ b/tools/perf/util/data-convert.h @@ -8,6 +8,7 @@ struct perf_data_convert_opts { bool force; bool all; bool tod; + const char *time_str; }; #ifdef HAVE_LIBBABELTRACE_SUPPORT diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index 164eb45a0b36..90df41da1a32 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -213,17 +213,15 @@ static int check_backup(struct perf_data *data) ret = rm_rf_perf_data(oldname); if (ret) { - pr_err("Can't remove old data: %s (%s)\n", - ret == -2 ? - "Unknown file found" : strerror(errno), - oldname); + if (ret == -2) + pr_err("Can't remove old data: Unknown file found (%s)\n", oldname); + else + pr_err("Can't remove old data: %m (%s)\n", oldname); return -1; } if (rename(data->path, oldname)) { - pr_err("Can't move data: %s (%s to %s)\n", - strerror(errno), - data->path, oldname); + pr_err("Can't move data: %m (%s to %s)\n", data->path, oldname); return -1; } } @@ -246,14 +244,12 @@ static int open_file_read(struct perf_data *data) int flags = data->in_place_update ? O_RDWR : O_RDONLY; struct stat st; int fd; - char sbuf[STRERR_BUFSIZE]; fd = open(data->file.path, flags); if (fd < 0) { int err = errno; - pr_err("failed to open %s: %s", data->file.path, - str_error_r(err, sbuf, sizeof(sbuf))); + pr_err("failed to open %s: %m", data->file.path); if (err == ENOENT && !strcmp(data->file.path, "perf.data")) pr_err(" (try 'perf record' first)"); pr_err("\n"); @@ -285,15 +281,10 @@ static int open_file_read(struct perf_data *data) static int open_file_write(struct perf_data *data) { - int fd; - char sbuf[STRERR_BUFSIZE]; - - fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, - S_IRUSR|S_IWUSR); + int fd = open(data->file.path, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, S_IRUSR|S_IWUSR); if (fd < 0) - pr_err("failed to open %s : %s\n", data->file.path, - str_error_r(errno, sbuf, sizeof(sbuf))); + pr_err("failed to open %s : %m\n", data->file.path); return fd; } @@ -436,8 +427,8 @@ int perf_data__switch(struct perf_data *data, if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) { ret = -errno; - pr_debug("Failed to lseek to %zu: %s", - pos, strerror(errno)); + pr_debug("Failed to lseek to %zu: %m\n", + pos); goto out; } } diff --git a/tools/perf/util/db-export.c b/tools/perf/util/db-export.c index 8f52e8cefcf3..ae9a9065aab7 100644 --- a/tools/perf/util/db-export.c +++ b/tools/perf/util/db-export.c @@ -254,7 +254,6 @@ static struct call_path *call_path_from_sample(struct db_export *dbe, addr_location__init(&al); al.sym = node->ms.sym; al.map = map__get(node->ms.map); - al.maps = maps__get(thread__maps(thread)); al.addr = node->ip; al.thread = thread__get(thread); diff --git a/tools/perf/util/demangle-java.c b/tools/perf/util/demangle-java.c index ddf33d58bcd3..c3cb327ed562 100644 --- a/tools/perf/util/demangle-java.c +++ b/tools/perf/util/demangle-java.c @@ -158,7 +158,7 @@ char * java_demangle_sym(const char *str, int flags) { char *buf, *ptr; - char *p; + const char *p; size_t len, l1 = 0; if (!str) diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c index 50b9433f3f8e..9e0420e14be1 100644 --- a/tools/perf/util/disasm.c +++ b/tools/perf/util/disasm.c @@ -1,5 +1,9 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include +#ifndef EF_CSKY_ABIMASK +#define EF_CSKY_ABIMASK 0XF0000000 +#endif #include #include #include @@ -28,25 +32,21 @@ #include "namespaces.h" #include "srcline.h" #include "symbol.h" +#include "thread.h" #include "util.h" static regex_t file_lineno; /* These can be referred from the arch-dependent code */ -static struct ins_ops call_ops; -static struct ins_ops dec_ops; -static struct ins_ops jump_ops; -static struct ins_ops mov_ops; -static struct ins_ops nop_ops; -static struct ins_ops lock_ops; -static struct ins_ops ret_ops; -static struct ins_ops load_store_ops; -static struct ins_ops arithmetic_ops; - -static int jump__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name); -static int call__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name); +const struct ins_ops call_ops; +const struct ins_ops dec_ops; +const struct ins_ops jump_ops; +const struct ins_ops mov_ops; +const struct ins_ops nop_ops; +const struct ins_ops lock_ops; +const struct ins_ops ret_ops; +const struct ins_ops load_store_ops; +const struct ins_ops arithmetic_ops; static void ins__sort(struct arch *arch); static int disasm_line__parse(char *line, const char **namep, char **rawp); @@ -66,7 +66,8 @@ static int arch__grow_instructions(struct arch *arch) goto grow_from_non_allocated_table; new_nr_allocated = arch->nr_instructions_allocated + 128; - new_instructions = realloc(arch->instructions, new_nr_allocated * sizeof(struct ins)); + new_instructions = realloc((void *)arch->instructions, + new_nr_allocated * sizeof(struct ins)); if (new_instructions == NULL) return -1; @@ -81,11 +82,11 @@ static int arch__grow_instructions(struct arch *arch) if (new_instructions == NULL) return -1; - memcpy(new_instructions, arch->instructions, arch->nr_instructions); + memcpy(new_instructions, arch->instructions, arch->nr_instructions * sizeof(struct ins)); goto out_update_instructions; } -static int arch__associate_ins_ops(struct arch* arch, const char *name, struct ins_ops *ops) +int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops) { struct ins *ins; @@ -93,7 +94,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i arch__grow_instructions(arch)) return -1; - ins = &arch->instructions[arch->nr_instructions]; + ins = (struct ins *)&arch->instructions[arch->nr_instructions]; ins->name = strdup(name); if (!ins->name) return -1; @@ -105,130 +106,100 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i return 0; } -#include "arch/arc/annotate/instructions.c" -#include "arch/arm/annotate/instructions.c" -#include "arch/arm64/annotate/instructions.c" -#include "arch/csky/annotate/instructions.c" -#include "arch/loongarch/annotate/instructions.c" -#include "arch/mips/annotate/instructions.c" -#include "arch/x86/annotate/instructions.c" -#include "arch/powerpc/annotate/instructions.c" -#include "arch/riscv64/annotate/instructions.c" -#include "arch/s390/annotate/instructions.c" -#include "arch/sparc/annotate/instructions.c" - -static struct arch architectures[] = { - { - .name = "arc", - .init = arc__annotate_init, - }, - { - .name = "arm", - .init = arm__annotate_init, - }, - { - .name = "arm64", - .init = arm64__annotate_init, - }, - { - .name = "csky", - .init = csky__annotate_init, - }, - { - .name = "mips", - .init = mips__annotate_init, - .objdump = { - .comment_char = '#', - }, - }, - { - .name = "x86", - .init = x86__annotate_init, - .instructions = x86__instructions, - .nr_instructions = ARRAY_SIZE(x86__instructions), - .insn_suffix = "bwlq", - .objdump = { - .comment_char = '#', - .register_char = '%', - .memory_ref_char = '(', - .imm_char = '$', - }, -#ifdef HAVE_LIBDW_SUPPORT - .update_insn_state = update_insn_state_x86, -#endif - }, - { - .name = "powerpc", - .init = powerpc__annotate_init, -#ifdef HAVE_LIBDW_SUPPORT - .update_insn_state = update_insn_state_powerpc, -#endif - }, - { - .name = "riscv64", - .init = riscv64__annotate_init, - }, - { - .name = "s390", - .init = s390__annotate_init, - .objdump = { - .comment_char = '#', - }, - }, - { - .name = "sparc", - .init = sparc__annotate_init, - .objdump = { - .comment_char = '#', - }, - }, - { - .name = "loongarch", - .init = loongarch__annotate_init, - .objdump = { - .comment_char = '#', - }, - }, -}; - -static int arch__key_cmp(const void *name, const void *archp) +static int e_machine_and_eflags__cmp(const struct e_machine_and_e_flags *val1, + const struct e_machine_and_e_flags *val2) { - const struct arch *arch = archp; + if (val1->e_machine == val2->e_machine) { + if (val1->e_machine != EM_CSKY) + return 0; + if ((val1->e_flags & EF_CSKY_ABIMASK) < (val2->e_flags & EF_CSKY_ABIMASK)) + return -1; + return (val1->e_flags & EF_CSKY_ABIMASK) > (val2->e_flags & EF_CSKY_ABIMASK); + } + return val1->e_machine < val2->e_machine ? -1 : 1; +} - return strcmp(name, arch->name); +static int arch__key_cmp(const void *key, const void *archp) +{ + const struct arch *const *arch = archp; + + return e_machine_and_eflags__cmp(key, &(*arch)->id); } static int arch__cmp(const void *a, const void *b) { - const struct arch *aa = a; - const struct arch *ab = b; + const struct arch *const *aa = a; + const struct arch *const *ab = b; - return strcmp(aa->name, ab->name); + return e_machine_and_eflags__cmp(&(*aa)->id, &(*ab)->id); } -static void arch__sort(void) +const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const char *cpuid) { - const int nmemb = ARRAY_SIZE(architectures); + static const struct arch *(*const arch_new_fn[])(const struct e_machine_and_e_flags *id, + const char *cpuid) = { + [EM_386] = arch__new_x86, + [EM_ARC] = arch__new_arc, + [EM_ARM] = arch__new_arm, + [EM_AARCH64] = arch__new_arm64, + [EM_CSKY] = arch__new_csky, + [EM_LOONGARCH] = arch__new_loongarch, + [EM_MIPS] = arch__new_mips, + [EM_PPC64] = arch__new_powerpc, + [EM_PPC] = arch__new_powerpc, + [EM_RISCV] = arch__new_riscv64, + [EM_S390] = arch__new_s390, + [EM_SPARC] = arch__new_sparc, + [EM_SPARCV9] = arch__new_sparc, + [EM_X86_64] = arch__new_x86, + }; + static const struct arch **archs; + static size_t num_archs; + struct e_machine_and_e_flags key = { + .e_machine = e_machine, + .e_flags = e_flags, + }; + const struct arch *result = NULL, **tmp; - qsort(architectures, nmemb, sizeof(struct arch), arch__cmp); -} - -struct arch *arch__find(const char *name) -{ - const int nmemb = ARRAY_SIZE(architectures); - static bool sorted; - - if (!sorted) { - arch__sort(); - sorted = true; + if (num_archs > 0) { + tmp = bsearch(&key, archs, num_archs, sizeof(*archs), arch__key_cmp); + if (tmp) + result = *tmp; } - return bsearch(name, architectures, nmemb, sizeof(struct arch), arch__key_cmp); + if (result) + return result; + + if (e_machine >= ARRAY_SIZE(arch_new_fn) || arch_new_fn[e_machine] == NULL) { + errno = ENOTSUP; + return NULL; + } + + tmp = reallocarray(archs, num_archs + 1, sizeof(*archs)); + if (!tmp) + return NULL; + + result = arch_new_fn[e_machine](&key, cpuid); + if (!result) { + pr_err("%s: failed to initialize %s (%u) arch priv area\n", + __func__, result->name, e_machine); + free(tmp); + return NULL; + } + archs = tmp; + archs[num_archs++] = result; + qsort(archs, num_archs, sizeof(*archs), arch__cmp); + return result; } -bool arch__is(struct arch *arch, const char *name) +bool arch__is_x86(const struct arch *arch) { - return !strcmp(arch->name, name); + return arch->id.e_machine == EM_386 || arch->id.e_machine == EM_X86_64; +} + +bool arch__is_powerpc(const struct arch *arch) +{ + return arch->id.e_machine == EM_PPC || arch->id.e_machine == EM_PPC64; } static void ins_ops__delete(struct ins_operands *ops) @@ -241,14 +212,14 @@ static void ins_ops__delete(struct ins_operands *ops) zfree(&ops->target.name); } -static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); } -static int ins__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +int ins__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { if (ins->ops->scnprintf) return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); @@ -256,7 +227,7 @@ static int ins__scnprintf(struct ins *ins, char *bf, size_t size, return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); } -bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) +bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2) { if (!arch || !arch->ins_is_fused) return false; @@ -264,14 +235,12 @@ bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) return arch->ins_is_fused(arch, ins1, ins2); } -static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, +static int call__parse(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, struct disasm_line *dl __maybe_unused) { char *endptr, *tok, *name; struct map *map = ms->map; - struct addr_map_symbol target = { - .ms = { .map = map, }, - }; + struct addr_map_symbol target; ops->target.addr = strtoull(ops->raw, &endptr, 16); @@ -296,12 +265,16 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s if (ops->target.name == NULL) return -1; find_target: - target.addr = map__objdump_2mem(map, ops->target.addr); + target = (struct addr_map_symbol) { + .ms = { .map = map__get(map), }, + .addr = map__objdump_2mem(map, ops->target.addr), + }; - if (maps__find_ams(ms->maps, &target) == 0 && + if (maps__find_ams(thread__maps(ms->thread), &target) == 0 && map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; + addr_map_symbol__exit(&target); return 0; indirect_call: @@ -317,8 +290,8 @@ static int call__parse(struct arch *arch, struct ins_operands *ops, struct map_s goto find_target; } -static int call__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +int call__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { if (ops->target.sym) return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); @@ -332,14 +305,15 @@ static int call__scnprintf(struct ins *ins, char *bf, size_t size, return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr); } -static struct ins_ops call_ops = { +const struct ins_ops call_ops = { .parse = call__parse, .scnprintf = call__scnprintf, + .is_call = true, }; bool ins__is_call(const struct ins *ins) { - return ins->ops == &call_ops || ins->ops == &s390_call_ops || ins->ops == &loongarch_call_ops; + return ins->ops && ins->ops->is_call; } /* @@ -360,13 +334,13 @@ static inline const char *validate_comma(const char *c, struct ins_operands *ops return c; } -static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, +static int jump__parse(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, struct disasm_line *dl __maybe_unused) { struct map *map = ms->map; struct symbol *sym = ms->sym; struct addr_map_symbol target = { - .ms = { .map = map, }, + .ms = { .map = map__get(map), }, }; const char *c = strchr(ops->raw, ','); u64 start, end; @@ -410,7 +384,7 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s start = map__unmap_ip(map, sym->start); end = map__unmap_ip(map, sym->end); - ops->target.outside = target.addr < start || target.addr > end; + ops->target.outside = target.addr < start || target.addr >= end; /* * FIXME: things like this in _cpp_lex_token (gcc's cc1 program): @@ -430,7 +404,7 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s * Actual navigation will come next, with further understanding of how * the symbol searching and disassembly should be done. */ - if (maps__find_ams(ms->maps, &target) == 0 && + if (maps__find_ams(thread__maps(ms->thread), &target) == 0 && map__rip_2objdump(target.ms.map, map__map_ip(target.ms.map, target.addr)) == ops->target.addr) ops->target.sym = target.ms.sym; @@ -440,12 +414,12 @@ static int jump__parse(struct arch *arch, struct ins_operands *ops, struct map_s } else { ops->target.offset_avail = false; } - + addr_map_symbol__exit(&target); return 0; } -static int jump__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +int jump__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { const char *c; @@ -485,15 +459,16 @@ static void jump__delete(struct ins_operands *ops __maybe_unused) */ } -static struct ins_ops jump_ops = { +const struct ins_ops jump_ops = { .free = jump__delete, .parse = jump__parse, .scnprintf = jump__scnprintf, + .is_jump = true, }; bool ins__is_jump(const struct ins *ins) { - return ins->ops == &jump_ops || ins->ops == &loongarch_jump_ops; + return ins->ops && ins->ops->is_jump; } static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) @@ -523,7 +498,7 @@ static int comment__symbol(char *raw, char *comment, u64 *addrp, char **namep) return 0; } -static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, +static int lock__parse(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, struct disasm_line *dl __maybe_unused) { ops->locked.ops = zalloc(sizeof(*ops->locked.ops)); @@ -549,7 +524,7 @@ static int lock__parse(struct arch *arch, struct ins_operands *ops, struct map_s return 0; } -static int lock__scnprintf(struct ins *ins, char *bf, size_t size, +static int lock__scnprintf(const struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name) { int printed; @@ -577,7 +552,7 @@ static void lock__delete(struct ins_operands *ops) zfree(&ops->target.name); } -static struct ins_ops lock_ops = { +const struct ins_ops lock_ops = { .free = lock__delete, .parse = lock__parse, .scnprintf = lock__scnprintf, @@ -590,7 +565,7 @@ static struct ins_ops lock_ops = { * But it doesn't care segment selectors like %gs:0x5678(%rcx), so just check * the input string after 'memory_ref_char' if exists. */ -static bool check_multi_regs(struct arch *arch, const char *op) +static bool check_multi_regs(const struct arch *arch, const char *op) { int count = 0; @@ -611,8 +586,9 @@ static bool check_multi_regs(struct arch *arch, const char *op) return count > 1; } -static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms __maybe_unused, - struct disasm_line *dl __maybe_unused) +static int mov__parse(const struct arch *arch, struct ins_operands *ops, + struct map_symbol *ms __maybe_unused, + struct disasm_line *dl __maybe_unused) { char *s = strchr(ops->raw, ','), *target, *comment, prev; @@ -677,105 +653,22 @@ static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map_sy return -1; } -static int mov__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) +int mov__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name) { return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name, ops->source.name ?: ops->source.raw, ops->target.name ?: ops->target.raw); } -static struct ins_ops mov_ops = { +const struct ins_ops mov_ops = { .parse = mov__parse, .scnprintf = mov__scnprintf, }; -#define PPC_22_30(R) (((R) >> 1) & 0x1ff) -#define MINUS_EXT_XO_FORM 234 -#define SUB_EXT_XO_FORM 232 -#define ADD_ZERO_EXT_XO_FORM 202 -#define SUB_ZERO_EXT_XO_FORM 200 - -static int arithmetic__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) -{ - return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, - ops->raw); -} - -/* - * Sets the fields: multi_regs and "mem_ref". - * "mem_ref" is set for ops->source which is later used to - * fill the objdump->memory_ref-char field. This ops is currently - * used by powerpc and since binary instruction code is used to - * extract opcode, regs and offset, no other parsing is needed here. - * - * Dont set multi regs for 4 cases since it has only one operand - * for source: - * - Add to Minus One Extended XO-form ( Ex: addme, addmeo ) - * - Subtract From Minus One Extended XO-form ( Ex: subfme ) - * - Add to Zero Extended XO-form ( Ex: addze, addzeo ) - * - Subtract From Zero Extended XO-form ( Ex: subfze ) - */ -static int arithmetic__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, - struct map_symbol *ms __maybe_unused, struct disasm_line *dl) -{ - int opcode = PPC_OP(dl->raw.raw_insn); - - ops->source.mem_ref = false; - if (opcode == 31) { - if ((opcode != MINUS_EXT_XO_FORM) && (opcode != SUB_EXT_XO_FORM) \ - && (opcode != ADD_ZERO_EXT_XO_FORM) && (opcode != SUB_ZERO_EXT_XO_FORM)) - ops->source.multi_regs = true; - } - - ops->target.mem_ref = false; - ops->target.multi_regs = false; - - return 0; -} - -static struct ins_ops arithmetic_ops = { - .parse = arithmetic__parse, - .scnprintf = arithmetic__scnprintf, -}; - -static int load_store__scnprintf(struct ins *ins, char *bf, size_t size, - struct ins_operands *ops, int max_ins_name) -{ - return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, - ops->raw); -} - -/* - * Sets the fields: multi_regs and "mem_ref". - * "mem_ref" is set for ops->source which is later used to - * fill the objdump->memory_ref-char field. This ops is currently - * used by powerpc and since binary instruction code is used to - * extract opcode, regs and offset, no other parsing is needed here - */ -static int load_store__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, - struct map_symbol *ms __maybe_unused, struct disasm_line *dl __maybe_unused) -{ - ops->source.mem_ref = true; - ops->source.multi_regs = false; - /* opcode 31 is of X form */ - if (PPC_OP(dl->raw.raw_insn) == 31) - ops->source.multi_regs = true; - - ops->target.mem_ref = false; - ops->target.multi_regs = false; - - return 0; -} - -static struct ins_ops load_store_ops = { - .parse = load_store__parse, - .scnprintf = load_store__scnprintf, -}; - -static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops, struct map_symbol *ms __maybe_unused, - struct disasm_line *dl __maybe_unused) +static int dec__parse(const struct arch *arch __maybe_unused, struct ins_operands *ops, + struct map_symbol *ms __maybe_unused, + struct disasm_line *dl __maybe_unused) { char *target, *comment, *s, prev; @@ -802,29 +695,29 @@ static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops return 0; } -static int dec__scnprintf(struct ins *ins, char *bf, size_t size, +static int dec__scnprintf(const struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name) { return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.name ?: ops->target.raw); } -static struct ins_ops dec_ops = { +const struct ins_ops dec_ops = { .parse = dec__parse, .scnprintf = dec__scnprintf, }; -static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, +static int nop__scnprintf(const struct ins *ins __maybe_unused, char *bf, size_t size, struct ins_operands *ops __maybe_unused, int max_ins_name) { return scnprintf(bf, size, "%-*s", max_ins_name, "nop"); } -static struct ins_ops nop_ops = { +const struct ins_ops nop_ops = { .scnprintf = nop__scnprintf, }; -static struct ins_ops ret_ops = { +const struct ins_ops ret_ops = { .scnprintf = ins__raw_scnprintf, }; @@ -862,20 +755,21 @@ static void ins__sort(struct arch *arch) { const int nmemb = arch->nr_instructions; - qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); + qsort((void *)arch->instructions, nmemb, sizeof(struct ins), ins__cmp); } -static struct ins_ops *__ins__find(struct arch *arch, const char *name, struct disasm_line *dl) +static const struct ins_ops *__ins__find(const struct arch *arch, const char *name, + struct disasm_line *dl) { - struct ins *ins; + const struct ins *ins; const int nmemb = arch->nr_instructions; - if (arch__is(arch, "powerpc")) { + if (arch__is_powerpc(arch)) { /* * For powerpc, identify the instruction ops * from the opcode using raw_insn. */ - struct ins_ops *ops; + const struct ins_ops *ops; ops = check_ppc_insn(dl); if (ops) @@ -883,8 +777,8 @@ static struct ins_ops *__ins__find(struct arch *arch, const char *name, struct d } if (!arch->sorted_instructions) { - ins__sort(arch); - arch->sorted_instructions = true; + ins__sort((struct arch *)arch); + ((struct arch *)arch)->sorted_instructions = true; } ins = bsearch(name, arch->instructions, nmemb, sizeof(struct ins), ins__key_cmp); @@ -911,17 +805,18 @@ static struct ins_ops *__ins__find(struct arch *arch, const char *name, struct d return ins ? ins->ops : NULL; } -struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl) +const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl) { - struct ins_ops *ops = __ins__find(arch, name, dl); + const struct ins_ops *ops = __ins__find(arch, name, dl); if (!ops && arch->associate_instruction_ops) - ops = arch->associate_instruction_ops(arch, name); + ops = arch->associate_instruction_ops((struct arch *)arch, name); return ops; } -static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms) +static void disasm_line__init_ins(struct disasm_line *dl, const struct arch *arch, + struct map_symbol *ms) { dl->ins.ops = ins__find(arch, dl->ins.name, dl); @@ -1046,7 +941,7 @@ static size_t disasm_line_size(int nr) struct disasm_line *disasm_line__new(struct annotate_args *args) { struct disasm_line *dl = NULL; - struct annotation *notes = symbol__annotation(args->ms.sym); + struct annotation *notes = symbol__annotation(args->ms->sym); int nr = notes->src->nr_events; dl = zalloc(disasm_line_size(nr)); @@ -1058,13 +953,13 @@ struct disasm_line *disasm_line__new(struct annotate_args *args) goto out_delete; if (args->offset != -1) { - if (arch__is(args->arch, "powerpc")) { + if (arch__is_powerpc(args->arch)) { if (disasm_line__parse_powerpc(dl, args) < 0) goto out_free_line; } else if (disasm_line__parse(dl->al.line, &dl->ins.name, &dl->ops.raw) < 0) goto out_free_line; - disasm_line__init_ins(dl, args->arch, &args->ms); + disasm_line__init_ins(dl, args->arch, args->ms); } return dl; @@ -1119,7 +1014,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct annotate_args *args, char *parsed_line, int *line_nr, char **fileloc) { - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct annotation *notes = symbol__annotation(sym); struct disasm_line *dl; char *tmp; @@ -1151,7 +1046,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, args->line = parsed_line; args->line_nr = *line_nr; args->fileloc = *fileloc; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); (*line_nr)++; @@ -1169,12 +1064,14 @@ static int symbol__parse_objdump_line(struct symbol *sym, if (dl->ins.ops && ins__is_call(&dl->ins) && !dl->ops.target.sym) { struct addr_map_symbol target = { .addr = dl->ops.target.addr, - .ms = { .map = map, }, + .ms = { .map = map__get(map), }, }; - if (!maps__find_ams(args->ms.maps, &target) && + if (!maps__find_ams(thread__maps(args->ms->thread), &target) && target.ms.sym->start == target.al_addr) dl->ops.target.sym = target.ms.sym; + + addr_map_symbol__exit(&target); } annotation_line__add(&dl->al, ¬es->src->source); @@ -1338,7 +1235,7 @@ static int symbol__disassemble_raw(char *filename, struct symbol *sym, struct annotate_args *args) { struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); u64 start = map__rip_2objdump(map, sym->start); u64 end = map__rip_2objdump(map, sym->end); @@ -1375,7 +1272,7 @@ static int symbol__disassemble_raw(char *filename, struct symbol *sym, args->line = disasm_buf; args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl == NULL) @@ -1501,7 +1398,7 @@ static int symbol__disassemble_objdump(const char *filename, struct symbol *sym, struct annotate_args *args) { struct annotation_options *opts = &annotate_opts; - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); char *command; FILE *file; @@ -1644,7 +1541,7 @@ static int symbol__disassemble_objdump(const char *filename, struct symbol *sym, int symbol__disassemble(struct symbol *sym, struct annotate_args *args) { struct annotation_options *options = args->options; - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); char symfs_filename[PATH_MAX]; bool delete_extract = false; @@ -1690,7 +1587,7 @@ int symbol__disassemble(struct symbol *sym, struct annotate_args *args) * and typeoff, disassemble to mnemonic notation is not required in * case of powerpc. */ - if (arch__is(args->arch, "powerpc")) { + if (arch__is_powerpc(args->arch)) { extern const char *sort_order; if (sort_order && !strstr(sort_order, "sym")) { diff --git a/tools/perf/util/disasm.h b/tools/perf/util/disasm.h index d2cb555e4a3b..a6e478caf61a 100644 --- a/tools/perf/util/disasm.h +++ b/tools/perf/util/disasm.h @@ -17,21 +17,23 @@ struct data_loc_info; struct type_state; struct disasm_line; +struct e_machine_and_e_flags { + uint32_t e_flags; + uint16_t e_machine; +}; + struct arch { - const char *name; - struct ins *instructions; - size_t nr_instructions; - size_t nr_instructions_allocated; - struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); - bool sorted_instructions; - bool initialized; - const char *insn_suffix; - void *priv; - unsigned int model; - unsigned int family; - int (*init)(struct arch *arch, char *cpuid); - bool (*ins_is_fused)(struct arch *arch, const char *ins1, - const char *ins2); + /** @name: name such as "x86" or "powerpc". */ + const char *name; + const struct ins *instructions; + size_t nr_instructions; + size_t nr_instructions_allocated; + const char *insn_suffix; + unsigned int model; + unsigned int family; + /** @id: ELF machine and flags associated with arch. */ + struct e_machine_and_e_flags id; + bool sorted_instructions; struct { char comment_char; char skip_functions_char; @@ -39,20 +41,19 @@ struct arch { char memory_ref_char; char imm_char; } objdump; + bool (*ins_is_fused)(const struct arch *arch, const char *ins1, + const char *ins2); + const struct ins_ops *(*associate_instruction_ops)(struct arch *arch, const char *name); #ifdef HAVE_LIBDW_SUPPORT void (*update_insn_state)(struct type_state *state, struct data_loc_info *dloc, Dwarf_Die *cu_die, struct disasm_line *dl); #endif - /** @e_machine: ELF machine associated with arch. */ - unsigned int e_machine; - /** @e_flags: Optional ELF flags associated with arch. */ - unsigned int e_flags; }; struct ins { const char *name; - struct ins_ops *ops; + const struct ins_ops *ops; }; struct ins_operands { @@ -89,15 +90,17 @@ struct ins_operands { struct ins_ops { void (*free)(struct ins_operands *ops); - int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, + int (*parse)(const struct arch *arch, struct ins_operands *ops, struct map_symbol *ms, struct disasm_line *dl); - int (*scnprintf)(struct ins *ins, char *bf, size_t size, + int (*scnprintf)(const struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name); + bool is_jump; + bool is_call; }; struct annotate_args { - struct arch *arch; - struct map_symbol ms; + const struct arch *arch; + struct map_symbol *ms; struct annotation_options *options; s64 offset; char *line; @@ -105,23 +108,59 @@ struct annotate_args { char *fileloc; }; -struct arch *arch__find(const char *name); -bool arch__is(struct arch *arch, const char *name); +const struct arch *arch__find(uint16_t e_machine, uint32_t e_flags, const char *cpuid); +bool arch__is_x86(const struct arch *arch); +bool arch__is_powerpc(const struct arch *arch); -struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl); +extern const struct ins_ops call_ops; +extern const struct ins_ops dec_ops; +extern const struct ins_ops jump_ops; +extern const struct ins_ops mov_ops; +extern const struct ins_ops nop_ops; +extern const struct ins_ops lock_ops; +extern const struct ins_ops ret_ops; + +int arch__associate_ins_ops(struct arch *arch, const char *name, const struct ins_ops *ops); + +const struct arch *arch__new_arc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_arm(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_arm64(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_csky(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_loongarch(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_mips(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_powerpc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_riscv64(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_s390(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_sparc(const struct e_machine_and_e_flags *id, const char *cpuid); +const struct arch *arch__new_x86(const struct e_machine_and_e_flags *id, const char *cpuid); + +const struct ins_ops *ins__find(const struct arch *arch, const char *name, struct disasm_line *dl); bool ins__is_call(const struct ins *ins); bool ins__is_jump(const struct ins *ins); -bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); +bool ins__is_fused(const struct arch *arch, const char *ins1, const char *ins2); bool ins__is_ret(const struct ins *ins); bool ins__is_lock(const struct ins *ins); +const struct ins_ops *check_ppc_insn(struct disasm_line *dl); + struct disasm_line *disasm_line__new(struct annotate_args *args); void disasm_line__free(struct disasm_line *dl); int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name); +int ins__raw_scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int ins__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int call__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int jump__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); +int mov__scnprintf(const struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); + int symbol__disassemble(struct symbol *sym, struct annotate_args *args); char *expand_tabs(char *line, char **storage, size_t *storage_len); diff --git a/tools/perf/util/dlfilter.c b/tools/perf/util/dlfilter.c index c0afcbd954f8..dc31b5e7149e 100644 --- a/tools/perf/util/dlfilter.c +++ b/tools/perf/util/dlfilter.c @@ -234,8 +234,7 @@ static const __u8 *dlfilter__insn(void *ctx, __u32 *len) struct machine *machine = maps__machine(thread__maps(al->thread)); if (machine) - script_fetch_insn(d->sample, al->thread, machine, - /*native_arch=*/true); + perf_sample__fetch_insn(d->sample, al->thread, machine); } } diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c index 344e689567ee..b791e1b6b2cf 100644 --- a/tools/perf/util/dso.c +++ b/tools/perf/util/dso.c @@ -32,6 +32,7 @@ #include "string2.h" #include "vdso.h" #include "annotate-data.h" +#include "libdw.h" static const char * const debuglink_paths[] = { "%.0s%s", @@ -111,7 +112,7 @@ bool dso__is_object_file(const struct dso *dso) int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, - char *root_dir, char *filename, size_t size) + const char *root_dir, char *filename, size_t size) { char build_id_hex[SBUILD_ID_SIZE]; int ret = 0; @@ -539,16 +540,13 @@ static void close_first_dso(void); static int do_open(char *name) EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock) { - int fd; - char sbuf[STRERR_BUFSIZE]; - do { - fd = open(name, O_RDONLY|O_CLOEXEC); + int fd = open(name, O_RDONLY|O_CLOEXEC); + if (fd >= 0) return fd; - pr_debug("dso open failed: %s\n", - str_error_r(errno, sbuf, sizeof(sbuf))); + pr_debug("dso open failed: %m\n"); if (!dso__data_open_cnt || errno != EMFILE) break; @@ -563,20 +561,15 @@ char *dso__filename_with_chroot(const struct dso *dso, const char *filename) return filename_with_chroot(nsinfo__pid(dso__nsinfo_const(dso)), filename); } -static int __open_dso(struct dso *dso, struct machine *machine) - EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock) +static char *dso__get_filename(struct dso *dso, const char *root_dir, + bool *decomp) { - int fd = -EINVAL; - char *root_dir = (char *)""; char *name = malloc(PATH_MAX); - bool decomp = false; - if (!name) - return -ENOMEM; + *decomp = false; - mutex_lock(dso__lock(dso)); - if (machine) - root_dir = machine->root_dir; + if (name == NULL) + return NULL; if (dso__read_binary_type_filename(dso, dso__binary_type(dso), root_dir, name, PATH_MAX)) @@ -601,20 +594,38 @@ static int __open_dso(struct dso *dso, struct machine *machine) size_t len = sizeof(newpath); if (dso__decompress_kmodule_path(dso, name, newpath, len) < 0) { - fd = -(*dso__load_errno(dso)); + errno = *dso__load_errno(dso); goto out; } - decomp = true; + *decomp = true; strcpy(name, newpath); } + return name; - fd = do_open(name); +out: + free(name); + return NULL; +} + +static int __open_dso(struct dso *dso, struct machine *machine) + EXCLUSIVE_LOCKS_REQUIRED(_dso__data_open_lock) +{ + int fd = -EINVAL; + char *name; + bool decomp = false; + + mutex_lock(dso__lock(dso)); + + name = dso__get_filename(dso, machine ? machine->root_dir : "", &decomp); + if (name) + fd = do_open(name); + else + fd = -errno; if (decomp) unlink(name); -out: mutex_unlock(dso__lock(dso)); free(name); return fd; @@ -1097,7 +1108,6 @@ static int file_size(struct dso *dso, struct machine *machine) { int ret = 0; struct stat st; - char sbuf[STRERR_BUFSIZE]; mutex_lock(dso__data_open_lock()); @@ -1115,8 +1125,7 @@ static int file_size(struct dso *dso, struct machine *machine) if (fstat(dso__data(dso)->fd, &st) < 0) { ret = -errno; - pr_err("dso cache fstat failed: %s\n", - str_error_r(errno, sbuf, sizeof(sbuf))); + pr_err("dso cache fstat failed: %m\n"); dso__data(dso)->status = DSO_DATA_STATUS_ERROR; goto out; } @@ -1194,7 +1203,92 @@ ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, return data_read_write_offset(dso, machine, offset, data, size, true); } -uint16_t dso__e_machine(struct dso *dso, struct machine *machine) +static enum dso_swap_type dso_swap_type__from_elf_data(unsigned char eidata) +{ + static const unsigned int endian = 1; + + switch (eidata) { + case ELFDATA2LSB: + /* We are big endian, DSO is little endian. */ + return (*(unsigned char const *)&endian != 1) ? DSO_SWAP__YES : DSO_SWAP__NO; + case ELFDATA2MSB: + /* We are little endian, DSO is big endian. */ + return (*(unsigned char const *)&endian != 0) ? DSO_SWAP__YES : DSO_SWAP__NO; + default: + return DSO_SWAP__UNSET; + } +} + +/* Reads e_machine from fd, optionally caching data in dso. */ +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd, uint32_t *e_flags) +{ + uint16_t e_machine = EM_NONE; + unsigned char e_ident[EI_NIDENT]; + enum dso_swap_type swap_type; + bool need_e_flags; + + if (e_flags) + *e_flags = 0; + + { + _Static_assert(offsetof(Elf32_Ehdr, e_ident) == 0, "Unexpected offset"); + _Static_assert(offsetof(Elf64_Ehdr, e_ident) == 0, "Unexpected offset"); + } + if (pread(fd, &e_ident, sizeof(e_ident), 0) != sizeof(e_ident)) + return EM_NONE; // Read failed. + + if (memcmp(e_ident, ELFMAG, SELFMAG) != 0) + return EM_NONE; // Not an ELF file. + + if (e_ident[EI_CLASS] == ELFCLASSNONE || e_ident[EI_CLASS] >= ELFCLASSNUM) + return EM_NONE; // Bad ELF class (32 or 64-bit objects). + + if (e_ident[EI_VERSION] != EV_CURRENT) + return EM_NONE; // Bad ELF version. + + swap_type = dso_swap_type__from_elf_data(e_ident[EI_DATA]); + if (swap_type == DSO_SWAP__UNSET) + return EM_NONE; // Bad ELF data encoding. + + /* Cache the need for swapping. */ + if (optional_dso) { + assert(dso__needs_swap(optional_dso) == DSO_SWAP__UNSET || + dso__needs_swap(optional_dso) == swap_type); + dso__set_needs_swap(optional_dso, swap_type); + } + + { + _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); + _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); + } + if (pread(fd, &e_machine, sizeof(e_machine), 18) != sizeof(e_machine)) + return EM_NONE; // e_machine read failed. + + e_machine = DSO_SWAP_TYPE__SWAP(swap_type, uint16_t, e_machine); + if (e_machine >= EM_NUM) + return EM_NONE; // Bad ELF machine number. + +#ifdef NDEBUG + /* In production code the e_flags are only needed on CSKY. */ + need_e_flags = e_flags && e_machine == EM_CSKY; +#else + /* Debug code will always read the e_flags. */ + need_e_flags = e_flags != NULL; +#endif + if (need_e_flags) { + off_t offset = e_ident[EI_CLASS] == ELFCLASS32 + ? offsetof(Elf32_Ehdr, e_flags) + : offsetof(Elf64_Ehdr, e_flags); + + if (pread(fd, e_flags, sizeof(*e_flags), offset) != sizeof(*e_flags)) { + *e_flags = 0; + return EM_NONE; // e_flags read failed. + } + } + return e_machine; +} + +uint16_t dso__e_machine(struct dso *dso, struct machine *machine, uint32_t *e_flags) { uint16_t e_machine = EM_NONE; int fd; @@ -1214,6 +1308,8 @@ uint16_t dso__e_machine(struct dso *dso, struct machine *machine) case DSO_BINARY_TYPE__BPF_IMAGE: case DSO_BINARY_TYPE__OOL: case DSO_BINARY_TYPE__JAVA_JIT: + if (e_flags) + *e_flags = EF_HOST; return EM_HOST; case DSO_BINARY_TYPE__DEBUGLINK: case DSO_BINARY_TYPE__BUILD_ID_CACHE: @@ -1228,6 +1324,8 @@ uint16_t dso__e_machine(struct dso *dso, struct machine *machine) break; case DSO_BINARY_TYPE__NOT_FOUND: default: + if (e_flags) + *e_flags = 0; return EM_NONE; } @@ -1239,19 +1337,11 @@ uint16_t dso__e_machine(struct dso *dso, struct machine *machine) */ try_to_open_dso(dso, machine); fd = dso__data(dso)->fd; - if (fd >= 0) { - _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); - _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); - if (dso__needs_swap(dso) == DSO_SWAP__UNSET) { - unsigned char eidata; + if (fd >= 0) + e_machine = dso__read_e_machine(dso, fd, e_flags); + else if (e_flags) + *e_flags = 0; - if (pread(fd, &eidata, sizeof(eidata), EI_DATA) == sizeof(eidata)) - dso__swap_init(dso, eidata); - } - if (dso__needs_swap(dso) != DSO_SWAP__UNSET && - pread(fd, &e_machine, sizeof(e_machine), 18) == sizeof(e_machine)) - e_machine = DSO__SWAP(dso, uint16_t, e_machine); - } mutex_unlock(dso__data_open_lock()); return e_machine; } @@ -1605,6 +1695,7 @@ void dso__delete(struct dso *dso) auxtrace_cache__free(RC_CHK_ACCESS(dso)->auxtrace_cache); dso_cache__free(dso); dso__free_a2l(dso); + dso__free_libdw(dso); dso__free_symsrc_filename(dso); nsinfo__zput(RC_CHK_ACCESS(dso)->nsinfo); mutex_destroy(dso__lock(dso)); @@ -1635,28 +1726,13 @@ void dso__put(struct dso *dso) int dso__swap_init(struct dso *dso, unsigned char eidata) { - static unsigned int const endian = 1; + enum dso_swap_type type = dso_swap_type__from_elf_data(eidata); - dso__set_needs_swap(dso, DSO_SWAP__NO); - - switch (eidata) { - case ELFDATA2LSB: - /* We are big endian, DSO is little endian. */ - if (*(unsigned char const *)&endian != 1) - dso__set_needs_swap(dso, DSO_SWAP__YES); - break; - - case ELFDATA2MSB: - /* We are little endian, DSO is big endian. */ - if (*(unsigned char const *)&endian != 0) - dso__set_needs_swap(dso, DSO_SWAP__YES); - break; - - default: + dso__set_needs_swap(dso, type); + if (type == DSO_SWAP__UNSET) { pr_err("unrecognized DSO data encoding %d\n", eidata); return -EINVAL; } - return 0; } @@ -1771,10 +1847,8 @@ int dso__strerror_load(struct dso *dso, char *buf, size_t buflen) BUG_ON(buflen == 0); if (errnum >= 0) { - const char *err = str_error_r(errnum, buf, buflen); - - if (err != buf) - scnprintf(buf, buflen, "%s", err); + errno = errnum; + scnprintf(buf, buflen, "%m"); return 0; } @@ -1910,3 +1984,23 @@ const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, return __dso__read_symbol(dso, symfs_filename, start, len, out_buf, out_buf_len, is_64bit); } + +struct debuginfo *dso__debuginfo(struct dso *dso) +{ + char *name; + bool decomp = false; + struct debuginfo *dinfo = NULL; + + mutex_lock(dso__lock(dso)); + + name = dso__get_filename(dso, "", &decomp); + if (name) + dinfo = debuginfo__new(name); + + if (decomp) + unlink(name); + + mutex_unlock(dso__lock(dso)); + free(name); + return dinfo; +} diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h index f8ccb9816b89..ede691e9a249 100644 --- a/tools/perf/util/dso.h +++ b/tools/perf/util/dso.h @@ -160,12 +160,11 @@ enum dso_load_errno { __DSO_LOAD_ERRNO__END, }; -#define DSO__SWAP(dso, type, val) \ +#define DSO_SWAP_TYPE__SWAP(swap_type, type, val) \ ({ \ type ____r = val; \ - enum dso_swap_type ___dst = dso__needs_swap(dso); \ - BUG_ON(___dst == DSO_SWAP__UNSET); \ - if (___dst == DSO_SWAP__YES) { \ + BUG_ON(swap_type == DSO_SWAP__UNSET); \ + if (swap_type == DSO_SWAP__YES) { \ switch (sizeof(____r)) { \ case 2: \ ____r = bswap_16(val); \ @@ -183,6 +182,8 @@ enum dso_load_errno { ____r; \ }) +#define DSO__SWAP(dso, type, val) DSO_SWAP_TYPE__SWAP(dso__needs_swap(dso), type, val) + #define DSO__DATA_CACHE_SIZE 4096 #define DSO__DATA_CACHE_MASK ~(DSO__DATA_CACHE_SIZE - 1) @@ -268,10 +269,8 @@ DECLARE_RC_STRUCT(dso) { const char *short_name; const char *long_name; void *a2l; + void *libdw; char *symsrc_filename; -#if defined(__powerpc__) - void *dwfl; /* DWARF debug info */ -#endif struct nsinfo *nsinfo; struct auxtrace_cache *auxtrace_cache; union { /* Tool specific area */ @@ -334,6 +333,26 @@ static inline void dso__set_a2l(struct dso *dso, void *val) RC_CHK_ACCESS(dso)->a2l = val; } +static inline void *dso__libdw(const struct dso *dso) +{ + return RC_CHK_ACCESS(dso)->libdw; +} + +static inline void dso__set_libdw(struct dso *dso, void *val) +{ + RC_CHK_ACCESS(dso)->libdw = val; +} + +struct Dwfl; +#ifdef HAVE_LIBDW_SUPPORT +struct Dwfl *dso__libdw_dwfl(struct dso *dso); +#else +static inline struct Dwfl *dso__libdw_dwfl(struct dso *dso __maybe_unused) +{ + return NULL; +} +#endif + static inline unsigned int dso__a2l_fails(const struct dso *dso) { return RC_CHK_ACCESS(dso)->a2l_fails; @@ -766,7 +785,7 @@ int dso__kernel_module_get_build_id(struct dso *dso, const char *root_dir); char dso__symtab_origin(const struct dso *dso); int dso__read_binary_type_filename(const struct dso *dso, enum dso_binary_type type, - char *root_dir, char *filename, size_t size); + const char *root_dir, char *filename, size_t size); bool is_kernel_module(const char *pathname, int cpumode); bool dso__needs_decompress(struct dso *dso); int dso__decompress_kmodule_fd(struct dso *dso, const char *name); @@ -847,7 +866,8 @@ int dso__data_file_size(struct dso *dso, struct machine *machine); off_t dso__data_size(struct dso *dso, struct machine *machine); ssize_t dso__data_read_offset(struct dso *dso, struct machine *machine, u64 offset, u8 *data, ssize_t size); -uint16_t dso__e_machine(struct dso *dso, struct machine *machine); +uint16_t dso__read_e_machine(struct dso *optional_dso, int fd, uint32_t *e_flags); +uint16_t dso__e_machine(struct dso *dso, struct machine *machine, uint32_t *e_flags); ssize_t dso__data_read_addr(struct dso *dso, struct map *map, struct machine *machine, u64 addr, u8 *data, ssize_t size); @@ -915,14 +935,7 @@ u64 dso__findnew_global_type(struct dso *dso, u64 addr, u64 offset); bool perf_pid_map_tid(const char *dso_name, int *tid); bool is_perf_pid_map_name(const char *dso_name); -/* - * In the future, we may get debuginfo using build-ID (w/o path). - * Add this helper is for the smooth conversion. - */ -static inline struct debuginfo *dso__debuginfo(struct dso *dso) -{ - return debuginfo__new(dso__long_name(dso)); -} +struct debuginfo *dso__debuginfo(struct dso *dso); const u8 *dso__read_symbol(struct dso *dso, const char *symfs_filename, const struct map *map, const struct symbol *sym, diff --git a/tools/perf/util/dwarf-regs-arch/Build b/tools/perf/util/dwarf-regs-arch/Build new file mode 100644 index 000000000000..ceb68ae86fd8 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/Build @@ -0,0 +1,9 @@ +perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm64.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-arm.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-csky.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-loongarch.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-mips.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-powerpc.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-riscv.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-s390.o +perf-util-$(CONFIG_LIBDW) += dwarf-regs-x86.o diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm.c new file mode 100644 index 000000000000..42c6c0635612 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/arm/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum) +{ + if (perf_regnum < 0 || perf_regnum >= PERF_REG_ARM_MAX) + return -ENOENT; + + return perf_regnum; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c new file mode 100644 index 000000000000..593ca7d4fccc --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-arm64.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/arm64/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum) +{ + if (perf_regnum < 0 || perf_regnum >= PERF_REG_ARM64_MAX) + return -ENOENT; + + return perf_regnum; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c new file mode 100644 index 000000000000..cb44b774f8d9 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-csky.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. +// Mapping of DWARF debug register numbers into register names. + +#include +#include +#include +// Ensure the V2 perf reg definitions are included. +#undef __CSKYABIV2__ +#define __CSKYABIV2__ 1 +#include "../../../arch/csky/include/uapi/asm/perf_regs.h" + +#define CSKY_ABIV2_MAX_REGS 73 +static const char * const csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = { + /* r0 ~ r8 */ + "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3", + /* r9 ~ r15 */ + "%regs4", "%regs5", "%regs6", "%regs7", "%regs8", "%regs9", "%sp", + "%lr", + /* r16 ~ r23 */ + "%exregs0", "%exregs1", "%exregs2", "%exregs3", "%exregs4", + "%exregs5", "%exregs6", "%exregs7", + /* r24 ~ r31 */ + "%exregs8", "%exregs9", "%exregs10", "%exregs11", "%exregs12", + "%exregs13", "%exregs14", "%tls", + "%pc", NULL, NULL, NULL, "%hi", "%lo", NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "%epc", +}; + +#define CSKY_ABIV1_MAX_REGS 57 +static const char * const csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = { + /* r0 ~ r8 */ + "%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", + /* r9 ~ r15 */ + "%regs2", "%regs3", "%regs4", "%regs5", "%regs6", "%regs7", "%regs8", + "%lr", + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "%epc", +}; + +const char *__get_csky_regstr(unsigned int n, unsigned int flags) +{ + if (flags & EF_CSKY_ABIV2) + return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL; + + return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL; +} + +static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name) +{ + for (size_t i = 0; i < num_regstr; i++) { + if (regstr[i] && !strcmp(regstr[i], name)) + return i; + } + return -ENOENT; +} + +int __get_csky_regnum(const char *name, unsigned int flags) +{ + if (flags & EF_CSKY_ABIV2) + return __get_dwarf_regnum(csky_dwarf_regs_table_abiv2, CSKY_ABIV2_MAX_REGS, name); + + return __get_dwarf_regnum(csky_dwarf_regs_table_abiv1, CSKY_ABIV1_MAX_REGS, name); +} + +int __get_dwarf_regnum_for_perf_regnum_csky(int perf_regnum, unsigned int flags) +{ + static const int dwarf_csky_regnums[][2] = { + [PERF_REG_CSKY_TLS] = {-ENOENT, 31}, + [PERF_REG_CSKY_LR] = {15, 15}, + [PERF_REG_CSKY_PC] = {-ENOENT, 32}, + /* TODO: PERF_REG_CSKY_SR */ + [PERF_REG_CSKY_SP] = {0, 14}, + /* TODO: PERF_REG_CSKY_ORIG_A0 */ + [PERF_REG_CSKY_A0] = {2, 0}, + [PERF_REG_CSKY_A1] = {3, 1}, + [PERF_REG_CSKY_A2] = {4, 2}, + [PERF_REG_CSKY_A3] = {5, 3}, + [PERF_REG_CSKY_REGS0] = {6, 4}, + [PERF_REG_CSKY_REGS1] = {7, 5}, + [PERF_REG_CSKY_REGS2] = {8, 6}, + [PERF_REG_CSKY_REGS3] = {9, 7}, + [PERF_REG_CSKY_REGS4] = {10, 8}, + [PERF_REG_CSKY_REGS5] = {11, 9}, + [PERF_REG_CSKY_REGS6] = {12, 10}, + [PERF_REG_CSKY_REGS7] = {13, 11}, + [PERF_REG_CSKY_REGS8] = {14, 12}, + [PERF_REG_CSKY_REGS9] = {1, 13}, + [PERF_REG_CSKY_EXREGS0] = {-ENOENT, 16}, + [PERF_REG_CSKY_EXREGS1] = {-ENOENT, 17}, + [PERF_REG_CSKY_EXREGS2] = {-ENOENT, 18}, + [PERF_REG_CSKY_EXREGS3] = {-ENOENT, 19}, + [PERF_REG_CSKY_EXREGS4] = {-ENOENT, 20}, + [PERF_REG_CSKY_EXREGS5] = {-ENOENT, 21}, + [PERF_REG_CSKY_EXREGS6] = {-ENOENT, 22}, + [PERF_REG_CSKY_EXREGS7] = {-ENOENT, 23}, + [PERF_REG_CSKY_EXREGS8] = {-ENOENT, 24}, + [PERF_REG_CSKY_EXREGS9] = {-ENOENT, 25}, + [PERF_REG_CSKY_EXREGS10] = {-ENOENT, 26}, + [PERF_REG_CSKY_EXREGS11] = {-ENOENT, 27}, + [PERF_REG_CSKY_EXREGS12] = {-ENOENT, 28}, + [PERF_REG_CSKY_EXREGS13] = {-ENOENT, 29}, + [PERF_REG_CSKY_EXREGS14] = {-ENOENT, 30}, + /* TODO: PERF_REG_CSKY_HI */ + /* TODO: PERF_REG_CSKY_LO */ + /* TODO: PERF_REG_CSKY_DCSR */ + }; + int idx = 0; + + if (flags & EF_CSKY_ABIV2) + idx++; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_csky_regnums) || + dwarf_csky_regnums[perf_regnum][idx] == 0) + return -ENOENT; + + return dwarf_csky_regnums[perf_regnum][idx]; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-loongarch.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-loongarch.c new file mode 100644 index 000000000000..203077b740a0 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-loongarch.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_loongarch(int perf_regnum) +{ + if (perf_regnum < 0 || perf_regnum >= PERF_REG_LOONGARCH_MAX) + return -ENOENT; + + return perf_regnum; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-mips.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-mips.c new file mode 100644 index 000000000000..3bb916b45c66 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-mips.c @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/mips/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_mips(int perf_regnum) +{ + if (perf_regnum == PERF_REG_MIPS_PC) + return 37; + if (perf_regnum < 0 || perf_regnum >= PERF_REG_MIPS_MAX) + return -ENOENT; + + return perf_regnum; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c new file mode 100644 index 000000000000..51892a09725b --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-powerpc.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Mapping of DWARF debug register numbers into register names. + * + * Copyright (C) 2010 Ian Munsie, IBM Corporation. + */ +#include +#include +#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h" + +#define PPC_OP(op) (((op) >> 26) & 0x3F) +#define PPC_RA(a) (((a) >> 16) & 0x1f) +#define PPC_RT(t) (((t) >> 21) & 0x1f) +#define PPC_RB(b) (((b) >> 11) & 0x1f) +#define PPC_D(D) ((D) & 0xfffe) +#define PPC_DS(DS) ((DS) & 0xfffc) +#define OP_LD 58 +#define OP_STD 62 + +static int get_source_reg(u32 raw_insn) +{ + return PPC_RA(raw_insn); +} + +static int get_target_reg(u32 raw_insn) +{ + return PPC_RT(raw_insn); +} + +static int get_offset_opcode(u32 raw_insn) +{ + int opcode = PPC_OP(raw_insn); + + /* DS- form */ + if ((opcode == OP_LD) || (opcode == OP_STD)) + return PPC_DS(raw_insn); + else + return PPC_D(raw_insn); +} + +/* + * Fills the required fields for op_loc depending on if it + * is a source or target. + * D form: ins RT,D(RA) -> src_reg1 = RA, offset = D, dst_reg1 = RT + * DS form: ins RT,DS(RA) -> src_reg1 = RA, offset = DS, dst_reg1 = RT + * X form: ins RT,RA,RB -> src_reg1 = RA, src_reg2 = RB, dst_reg1 = RT + */ +void get_powerpc_regs(u32 raw_insn, int is_source, + struct annotated_op_loc *op_loc) +{ + if (is_source) + op_loc->reg1 = get_source_reg(raw_insn); + else + op_loc->reg1 = get_target_reg(raw_insn); + + if (op_loc->multi_regs) + op_loc->reg2 = PPC_RB(raw_insn); + + /* TODO: Implement offset handling for X Form */ + if ((op_loc->mem_ref) && (PPC_OP(raw_insn) != 31)) + op_loc->offset = get_offset_opcode(raw_insn); +} + +int __get_dwarf_regnum_for_perf_regnum_powerpc(int perf_regnum) +{ + static const int dwarf_powerpc_regnums[] = { + [PERF_REG_POWERPC_R0] = 0, + [PERF_REG_POWERPC_R1] = 1, + [PERF_REG_POWERPC_R2] = 2, + [PERF_REG_POWERPC_R3] = 3, + [PERF_REG_POWERPC_R4] = 4, + [PERF_REG_POWERPC_R5] = 5, + [PERF_REG_POWERPC_R6] = 6, + [PERF_REG_POWERPC_R7] = 7, + [PERF_REG_POWERPC_R8] = 8, + [PERF_REG_POWERPC_R9] = 9, + [PERF_REG_POWERPC_R10] = 10, + [PERF_REG_POWERPC_R11] = 11, + [PERF_REG_POWERPC_R12] = 12, + [PERF_REG_POWERPC_R13] = 13, + [PERF_REG_POWERPC_R14] = 14, + [PERF_REG_POWERPC_R15] = 15, + [PERF_REG_POWERPC_R16] = 16, + [PERF_REG_POWERPC_R17] = 17, + [PERF_REG_POWERPC_R18] = 18, + [PERF_REG_POWERPC_R19] = 19, + [PERF_REG_POWERPC_R20] = 20, + [PERF_REG_POWERPC_R21] = 21, + [PERF_REG_POWERPC_R22] = 22, + [PERF_REG_POWERPC_R23] = 23, + [PERF_REG_POWERPC_R24] = 24, + [PERF_REG_POWERPC_R25] = 25, + [PERF_REG_POWERPC_R26] = 26, + [PERF_REG_POWERPC_R27] = 27, + [PERF_REG_POWERPC_R28] = 28, + [PERF_REG_POWERPC_R29] = 29, + [PERF_REG_POWERPC_R30] = 30, + [PERF_REG_POWERPC_R31] = 31, + /* TODO: PERF_REG_POWERPC_NIP */ + [PERF_REG_POWERPC_MSR] = 66, + /* TODO: PERF_REG_POWERPC_ORIG_R3 */ + [PERF_REG_POWERPC_CTR] = 109, + [PERF_REG_POWERPC_LINK] = 108, /* Note, previously in perf encoded as 65? */ + [PERF_REG_POWERPC_XER] = 101, + /* TODO: PERF_REG_POWERPC_CCR */ + /* TODO: PERF_REG_POWERPC_SOFTE */ + /* TODO: PERF_REG_POWERPC_TRAP */ + /* TODO: PERF_REG_POWERPC_DAR */ + /* TODO: PERF_REG_POWERPC_DSISR */ + /* TODO: PERF_REG_POWERPC_SIER */ + /* TODO: PERF_REG_POWERPC_MMCRA */ + /* TODO: PERF_REG_POWERPC_MMCR0 */ + /* TODO: PERF_REG_POWERPC_MMCR1 */ + /* TODO: PERF_REG_POWERPC_MMCR2 */ + /* TODO: PERF_REG_POWERPC_MMCR3 */ + /* TODO: PERF_REG_POWERPC_SIER2 */ + /* TODO: PERF_REG_POWERPC_SIER3 */ + /* TODO: PERF_REG_POWERPC_PMC1 */ + /* TODO: PERF_REG_POWERPC_PMC2 */ + /* TODO: PERF_REG_POWERPC_PMC3 */ + /* TODO: PERF_REG_POWERPC_PMC4 */ + /* TODO: PERF_REG_POWERPC_PMC5 */ + /* TODO: PERF_REG_POWERPC_PMC6 */ + /* TODO: PERF_REG_POWERPC_SDAR */ + /* TODO: PERF_REG_POWERPC_SIAR */ + }; + + if (perf_regnum == 0) + return 0; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_powerpc_regnums) || + dwarf_powerpc_regnums[perf_regnum] == 0) + return -ENOENT; + + return dwarf_powerpc_regnums[perf_regnum]; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-riscv.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-riscv.c new file mode 100644 index 000000000000..090db51aba41 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-riscv.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/riscv/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_riscv(int perf_regnum) +{ + if (perf_regnum < 0 || perf_regnum >= PERF_REG_RISCV_MAX) + return -ENOENT; + + return perf_regnum; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-s390.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-s390.c new file mode 100644 index 000000000000..310a37451bdc --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-s390.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include "../../../arch/s390/include/uapi/asm/perf_regs.h" + +int __get_dwarf_regnum_for_perf_regnum_s390(int perf_regnum) +{ + static const int dwarf_s390_regnums[] = { + [PERF_REG_S390_R0] = 0, + [PERF_REG_S390_R1] = 1, + [PERF_REG_S390_R2] = 2, + [PERF_REG_S390_R3] = 3, + [PERF_REG_S390_R4] = 4, + [PERF_REG_S390_R5] = 5, + [PERF_REG_S390_R6] = 6, + [PERF_REG_S390_R7] = 7, + [PERF_REG_S390_R8] = 8, + [PERF_REG_S390_R9] = 9, + [PERF_REG_S390_R10] = 10, + [PERF_REG_S390_R11] = 11, + [PERF_REG_S390_R12] = 12, + [PERF_REG_S390_R13] = 13, + [PERF_REG_S390_R14] = 14, + [PERF_REG_S390_R15] = 15, + [PERF_REG_S390_FP0] = 16, + [PERF_REG_S390_FP1] = 20, + [PERF_REG_S390_FP2] = 17, + [PERF_REG_S390_FP3] = 21, + [PERF_REG_S390_FP4] = 18, + [PERF_REG_S390_FP5] = 22, + [PERF_REG_S390_FP6] = 19, + [PERF_REG_S390_FP7] = 23, + [PERF_REG_S390_FP8] = 24, + [PERF_REG_S390_FP9] = 28, + [PERF_REG_S390_FP10] = 25, + [PERF_REG_S390_FP11] = 29, + [PERF_REG_S390_FP12] = 26, + [PERF_REG_S390_FP13] = 30, + [PERF_REG_S390_FP14] = 27, + [PERF_REG_S390_FP15] = 31, + [PERF_REG_S390_MASK] = 64, + [PERF_REG_S390_PC] = 65, + }; + + if (perf_regnum == 0) + return 0; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_s390_regnums) || + dwarf_s390_regnums[perf_regnum] == 0) + return -ENOENT; + + return dwarf_s390_regnums[perf_regnum]; +} diff --git a/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c b/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c new file mode 100644 index 000000000000..cadef120aeb4 --- /dev/null +++ b/tools/perf/util/dwarf-regs-arch/dwarf-regs-x86.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * dwarf-regs.c : Mapping of DWARF debug register numbers into register names. + * Extracted from probe-finder.c + * + * Written by Masami Hiramatsu + */ + +#include /* for EINVAL */ +#include /* for strcmp */ +#include /* for ARRAY_SIZE */ +#include +#include "../../../arch/x86/include/uapi/asm/perf_regs.h" + +struct dwarf_regs_idx { + const char *name; + int dwarf_regnum; +}; + +static const struct dwarf_regs_idx i386_regidx_table[] = { + { "eax", 0 }, { "ax", 0 }, { "al", 0 }, + { "ecx", 1 }, { "cx", 1 }, { "cl", 1 }, + { "edx", 2 }, { "dx", 2 }, { "dl", 2 }, + { "ebx", 3 }, { "bx", 3 }, { "bl", 3 }, + { "esp", 4 }, { "sp", 4 }, { "$stack", 4}, + { "ebp", 5 }, { "bp", 5 }, + { "esi", 6 }, { "si", 6 }, + { "edi", 7 }, { "di", 7 }, + // 8 - Return Address RA + { "eflags", 9}, { "flags", 9}, + // 10 - reserved + { "st0", 11}, + { "st1", 12}, + { "st2", 13}, + { "st3", 14}, + { "st4", 15}, + { "st5", 16}, + { "st6", 17}, + { "st7", 18}, + // 19-20 - reserved + { "xmm0", 21}, + { "xmm1", 22}, + { "xmm2", 23}, + { "xmm3", 24}, + { "xmm4", 25}, + { "xmm5", 26}, + { "xmm6", 27}, + { "xmm7", 28}, + { "mm0", 29}, + { "mm1", 30}, + { "mm2", 31}, + { "mm3", 32}, + { "mm4", 33}, + { "mm5", 34}, + { "mm6", 35}, + { "mm7", 36}, + // 37-38 - unknown + { "mxcsr", 39}, // 128-bit Media Control and Status + { "es", 40}, + { "cs", 41}, + { "ss", 42}, + { "ds", 43}, + { "fs", 44}, + { "gs", 45}, + // 46-47 - reserved + { "tr", 48}, // Task Register + { "ldtr", 49}, // LDT Register + // 50-92 - reserved + { "fs.base", 92}, + { "gs.base", 93}, + // End of regular dwarf registers. + { "eip", DWARF_REG_PC }, { "ip", DWARF_REG_PC }, +}; + +static const struct dwarf_regs_idx x86_64_regidx_table[] = { + { "rax", 0 }, { "eax", 0 }, { "ax", 0 }, { "al", 0 }, + { "rdx", 1 }, { "edx", 1 }, { "dx", 1 }, { "dl", 1 }, + { "rcx", 2 }, { "ecx", 2 }, { "cx", 2 }, { "cl", 2 }, + { "rbx", 3 }, { "edx", 3 }, { "bx", 3 }, { "bl", 3 }, + { "rsi", 4 }, { "esi", 4 }, { "si", 4 }, { "sil", 4 }, + { "rdi", 5 }, { "edi", 5 }, { "di", 5 }, { "dil", 5 }, + { "rbp", 6 }, { "ebp", 6 }, { "bp", 6 }, { "bpl", 6 }, + { "rsp", 7 }, { "esp", 7 }, { "sp", 7 }, { "spl", 7 }, + { "r8", 8 }, { "r8d", 8 }, { "r8w", 8 }, { "r8b", 8 }, + { "r9", 9 }, { "r9d", 9 }, { "r9w", 9 }, { "r9b", 9 }, + { "r10", 10 }, { "r10d", 10 }, { "r10w", 10 }, { "r10b", 10 }, + { "r11", 11 }, { "r11d", 11 }, { "r11w", 11 }, { "r11b", 11 }, + { "r12", 12 }, { "r12d", 12 }, { "r12w", 12 }, { "r12b", 12 }, + { "r13", 13 }, { "r13d", 13 }, { "r13w", 13 }, { "r13b", 13 }, + { "r14", 14 }, { "r14d", 14 }, { "r14w", 14 }, { "r14b", 14 }, + { "r15", 15 }, { "r15d", 15 }, { "r15w", 15 }, { "r15b", 15 }, + // 16 - Return Address RA + { "xmm0", 17}, + { "xmm1", 18}, + { "xmm2", 19}, + { "xmm3", 20}, + { "xmm4", 21}, + { "xmm5", 22}, + { "xmm6", 23}, + { "xmm7", 24}, + { "xmm8", 25}, + { "xmm9", 26}, + { "xmm10", 27}, + { "xmm11", 28}, + { "xmm12", 29}, + { "xmm13", 30}, + { "xmm14", 31}, + { "xmm15", 32}, + { "st0", 33}, + { "st1", 34}, + { "st2", 35}, + { "st3", 36}, + { "st4", 37}, + { "st5", 38}, + { "st6", 39}, + { "st7", 40}, + { "mm0", 41}, + { "mm1", 42}, + { "mm2", 43}, + { "mm3", 44}, + { "mm4", 45}, + { "mm5", 46}, + { "mm6", 47}, + { "mm7", 48}, + { "rflags", 49}, { "eflags", 49}, { "flags", 49}, + { "es", 50}, + { "cs", 51}, + { "ss", 52}, + { "ds", 53}, + { "fs", 54}, + { "gs", 55}, + // 56-47 - reserved + { "fs.base", 58}, + { "gs.base", 59}, + // 60-61 - reserved + { "tr", 62}, // Task Register + { "ldtr", 63}, // LDT Register + { "mxcsr", 64}, // 128-bit Media Control and Status + { "fcw", 65}, // x87 Control Word + { "fsw", 66}, // x87 Status Word + // End of regular dwarf registers. + { "rip", DWARF_REG_PC }, { "eip", DWARF_REG_PC }, { "ip", DWARF_REG_PC }, +}; + +static int get_regnum(const struct dwarf_regs_idx *entries, size_t num_entries, const char *name) +{ + if (*name != '%') + return -EINVAL; + + name++; + for (size_t i = 0; i < num_entries; i++) { + if (!strcmp(entries[i].name, name)) + return entries[i].dwarf_regnum; + } + return -ENOENT; +} + +int __get_dwarf_regnum_i386(const char *name) +{ + return get_regnum(i386_regidx_table, ARRAY_SIZE(i386_regidx_table), name); +} + +int __get_dwarf_regnum_x86_64(const char *name) +{ + return get_regnum(x86_64_regidx_table, ARRAY_SIZE(x86_64_regidx_table), name); +} + +int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum) +{ + static const int dwarf_i386_regnums[] = { + [PERF_REG_X86_AX] = 0, + [PERF_REG_X86_BX] = 3, + [PERF_REG_X86_CX] = 1, + [PERF_REG_X86_DX] = 2, + [PERF_REG_X86_SI] = 6, + [PERF_REG_X86_DI] = 7, + [PERF_REG_X86_BP] = 5, + [PERF_REG_X86_SP] = 4, + [PERF_REG_X86_IP] = 8, + [PERF_REG_X86_FLAGS] = 9, + [PERF_REG_X86_CS] = 41, + [PERF_REG_X86_SS] = 42, + [PERF_REG_X86_DS] = 43, + [PERF_REG_X86_ES] = 40, + [PERF_REG_X86_FS] = 44, + [PERF_REG_X86_GS] = 45, + [PERF_REG_X86_XMM0] = 21, + [PERF_REG_X86_XMM1] = 22, + [PERF_REG_X86_XMM2] = 23, + [PERF_REG_X86_XMM3] = 24, + [PERF_REG_X86_XMM4] = 25, + [PERF_REG_X86_XMM5] = 26, + [PERF_REG_X86_XMM6] = 27, + [PERF_REG_X86_XMM7] = 28, + }; + + if (perf_regnum == 0) + return 0; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_i386_regnums) || + dwarf_i386_regnums[perf_regnum] == 0) + return -ENOENT; + + return dwarf_i386_regnums[perf_regnum]; +} + +int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum) +{ + static const int dwarf_x86_64_regnums[] = { + [PERF_REG_X86_AX] = 0, + [PERF_REG_X86_BX] = 3, + [PERF_REG_X86_CX] = 2, + [PERF_REG_X86_DX] = 1, + [PERF_REG_X86_SI] = 4, + [PERF_REG_X86_DI] = 5, + [PERF_REG_X86_BP] = 6, + [PERF_REG_X86_SP] = 7, + [PERF_REG_X86_IP] = 16, + [PERF_REG_X86_FLAGS] = 49, + [PERF_REG_X86_CS] = 51, + [PERF_REG_X86_SS] = 52, + [PERF_REG_X86_DS] = 53, + [PERF_REG_X86_ES] = 50, + [PERF_REG_X86_FS] = 54, + [PERF_REG_X86_GS] = 55, + [PERF_REG_X86_R8] = 8, + [PERF_REG_X86_R9] = 9, + [PERF_REG_X86_R10] = 10, + [PERF_REG_X86_R11] = 11, + [PERF_REG_X86_R12] = 12, + [PERF_REG_X86_R13] = 13, + [PERF_REG_X86_R14] = 14, + [PERF_REG_X86_R15] = 15, + [PERF_REG_X86_XMM0] = 17, + [PERF_REG_X86_XMM1] = 18, + [PERF_REG_X86_XMM2] = 19, + [PERF_REG_X86_XMM3] = 20, + [PERF_REG_X86_XMM4] = 21, + [PERF_REG_X86_XMM5] = 22, + [PERF_REG_X86_XMM6] = 23, + [PERF_REG_X86_XMM7] = 24, + [PERF_REG_X86_XMM8] = 25, + [PERF_REG_X86_XMM9] = 26, + [PERF_REG_X86_XMM10] = 27, + [PERF_REG_X86_XMM11] = 28, + [PERF_REG_X86_XMM12] = 29, + [PERF_REG_X86_XMM13] = 30, + [PERF_REG_X86_XMM14] = 31, + [PERF_REG_X86_XMM15] = 32, + }; + + if (perf_regnum == 0) + return 0; + + if (perf_regnum < 0 || perf_regnum > (int)ARRAY_SIZE(dwarf_x86_64_regnums) || + dwarf_x86_64_regnums[perf_regnum] == 0) + return -ENOENT; + + return dwarf_x86_64_regnums[perf_regnum]; +} diff --git a/tools/perf/util/dwarf-regs-csky.c b/tools/perf/util/dwarf-regs-csky.c deleted file mode 100644 index d38ef1f07f3e..000000000000 --- a/tools/perf/util/dwarf-regs-csky.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. -// Mapping of DWARF debug register numbers into register names. - -#include -#include - -#define CSKY_ABIV2_MAX_REGS 73 -const char *csky_dwarf_regs_table_abiv2[CSKY_ABIV2_MAX_REGS] = { - /* r0 ~ r8 */ - "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", "%regs2", "%regs3", - /* r9 ~ r15 */ - "%regs4", "%regs5", "%regs6", "%regs7", "%regs8", "%regs9", "%sp", - "%lr", - /* r16 ~ r23 */ - "%exregs0", "%exregs1", "%exregs2", "%exregs3", "%exregs4", - "%exregs5", "%exregs6", "%exregs7", - /* r24 ~ r31 */ - "%exregs8", "%exregs9", "%exregs10", "%exregs11", "%exregs12", - "%exregs13", "%exregs14", "%tls", - "%pc", NULL, NULL, NULL, "%hi", "%lo", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "%epc", -}; - -#define CSKY_ABIV1_MAX_REGS 57 -const char *csky_dwarf_regs_table_abiv1[CSKY_ABIV1_MAX_REGS] = { - /* r0 ~ r8 */ - "%sp", "%regs9", "%a0", "%a1", "%a2", "%a3", "%regs0", "%regs1", - /* r9 ~ r15 */ - "%regs2", "%regs3", "%regs4", "%regs5", "%regs6", "%regs7", "%regs8", - "%lr", - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - "%epc", -}; - -const char *get_csky_regstr(unsigned int n, unsigned int flags) -{ - if (flags & EF_CSKY_ABIV2) - return (n < CSKY_ABIV2_MAX_REGS) ? csky_dwarf_regs_table_abiv2[n] : NULL; - - return (n < CSKY_ABIV1_MAX_REGS) ? csky_dwarf_regs_table_abiv1[n] : NULL; -} diff --git a/tools/perf/util/dwarf-regs-powerpc.c b/tools/perf/util/dwarf-regs-powerpc.c deleted file mode 100644 index caf77a234c78..000000000000 --- a/tools/perf/util/dwarf-regs-powerpc.c +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Mapping of DWARF debug register numbers into register names. - * - * Copyright (C) 2010 Ian Munsie, IBM Corporation. - */ - -#include - -#define PPC_OP(op) (((op) >> 26) & 0x3F) -#define PPC_RA(a) (((a) >> 16) & 0x1f) -#define PPC_RT(t) (((t) >> 21) & 0x1f) -#define PPC_RB(b) (((b) >> 11) & 0x1f) -#define PPC_D(D) ((D) & 0xfffe) -#define PPC_DS(DS) ((DS) & 0xfffc) -#define OP_LD 58 -#define OP_STD 62 - -static int get_source_reg(u32 raw_insn) -{ - return PPC_RA(raw_insn); -} - -static int get_target_reg(u32 raw_insn) -{ - return PPC_RT(raw_insn); -} - -static int get_offset_opcode(u32 raw_insn) -{ - int opcode = PPC_OP(raw_insn); - - /* DS- form */ - if ((opcode == OP_LD) || (opcode == OP_STD)) - return PPC_DS(raw_insn); - else - return PPC_D(raw_insn); -} - -/* - * Fills the required fields for op_loc depending on if it - * is a source or target. - * D form: ins RT,D(RA) -> src_reg1 = RA, offset = D, dst_reg1 = RT - * DS form: ins RT,DS(RA) -> src_reg1 = RA, offset = DS, dst_reg1 = RT - * X form: ins RT,RA,RB -> src_reg1 = RA, src_reg2 = RB, dst_reg1 = RT - */ -void get_powerpc_regs(u32 raw_insn, int is_source, - struct annotated_op_loc *op_loc) -{ - if (is_source) - op_loc->reg1 = get_source_reg(raw_insn); - else - op_loc->reg1 = get_target_reg(raw_insn); - - if (op_loc->multi_regs) - op_loc->reg2 = PPC_RB(raw_insn); - - /* TODO: Implement offset handling for X Form */ - if ((op_loc->mem_ref) && (PPC_OP(raw_insn) != 31)) - op_loc->offset = get_offset_opcode(raw_insn); -} diff --git a/tools/perf/util/dwarf-regs-x86.c b/tools/perf/util/dwarf-regs-x86.c deleted file mode 100644 index 7a55c65e8da6..000000000000 --- a/tools/perf/util/dwarf-regs-x86.c +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * dwarf-regs.c : Mapping of DWARF debug register numbers into register names. - * Extracted from probe-finder.c - * - * Written by Masami Hiramatsu - */ - -#include /* for EINVAL */ -#include /* for strcmp */ -#include /* for ARRAY_SIZE */ -#include - -struct dwarf_regs_idx { - const char *name; - int idx; -}; - -static const struct dwarf_regs_idx x86_regidx_table[] = { - { "rax", 0 }, { "eax", 0 }, { "ax", 0 }, { "al", 0 }, - { "rdx", 1 }, { "edx", 1 }, { "dx", 1 }, { "dl", 1 }, - { "rcx", 2 }, { "ecx", 2 }, { "cx", 2 }, { "cl", 2 }, - { "rbx", 3 }, { "edx", 3 }, { "bx", 3 }, { "bl", 3 }, - { "rsi", 4 }, { "esi", 4 }, { "si", 4 }, { "sil", 4 }, - { "rdi", 5 }, { "edi", 5 }, { "di", 5 }, { "dil", 5 }, - { "rbp", 6 }, { "ebp", 6 }, { "bp", 6 }, { "bpl", 6 }, - { "rsp", 7 }, { "esp", 7 }, { "sp", 7 }, { "spl", 7 }, - { "r8", 8 }, { "r8d", 8 }, { "r8w", 8 }, { "r8b", 8 }, - { "r9", 9 }, { "r9d", 9 }, { "r9w", 9 }, { "r9b", 9 }, - { "r10", 10 }, { "r10d", 10 }, { "r10w", 10 }, { "r10b", 10 }, - { "r11", 11 }, { "r11d", 11 }, { "r11w", 11 }, { "r11b", 11 }, - { "r12", 12 }, { "r12d", 12 }, { "r12w", 12 }, { "r12b", 12 }, - { "r13", 13 }, { "r13d", 13 }, { "r13w", 13 }, { "r13b", 13 }, - { "r14", 14 }, { "r14d", 14 }, { "r14w", 14 }, { "r14b", 14 }, - { "r15", 15 }, { "r15d", 15 }, { "r15w", 15 }, { "r15b", 15 }, - { "rip", DWARF_REG_PC }, -}; - -int get_x86_regnum(const char *name) -{ - unsigned int i; - - if (*name != '%') - return -EINVAL; - - for (i = 0; i < ARRAY_SIZE(x86_regidx_table); i++) - if (!strcmp(x86_regidx_table[i].name, name + 1)) - return x86_regidx_table[i].idx; - return -ENOENT; -} diff --git a/tools/perf/util/dwarf-regs.c b/tools/perf/util/dwarf-regs.c index 28a1cfdf26d4..797f455eba0d 100644 --- a/tools/perf/util/dwarf-regs.c +++ b/tools/perf/util/dwarf-regs.c @@ -27,11 +27,11 @@ #include "../arch/mips/include/dwarf-regs-table.h" #include "../arch/loongarch/include/dwarf-regs-table.h" -#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL) - /* Return architecture dependent register string (for kprobe-tracer) */ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags) { + #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL) + if (machine == EM_NONE) { /* Generic arch - use host arch */ machine = EM_HOST; @@ -46,7 +46,7 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int case EM_AARCH64: return __get_dwarf_regstr(aarch64_regstr_tbl, n); case EM_CSKY: - return get_csky_regstr(n, flags); + return __get_csky_regstr(n, flags); case EM_SH: return __get_dwarf_regstr(sh_regstr_tbl, n); case EM_S390: @@ -69,22 +69,28 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int pr_err("ELF MACHINE %x is not supported.\n", machine); } return NULL; + + #undef __get_dwarf_regstr } -#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 -__weak int get_arch_regnum(const char *name __maybe_unused) +static int __get_dwarf_regnum(const char *const *regstr, size_t num_regstr, const char *name) { - return -ENOTSUP; + for (size_t i = 0; i < num_regstr; i++) { + if (regstr[i] && !strcmp(regstr[i], name)) + return i; + } + return -ENOENT; } -#endif /* Return DWARF register number from architecture register name */ -int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags __maybe_unused) +int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags) { char *regname = strdup(name); int reg = -1; char *p; + #define _get_dwarf_regnum(tbl, name) __get_dwarf_regnum(tbl, ARRAY_SIZE(tbl), name) + if (regname == NULL) return -EINVAL; @@ -98,19 +104,134 @@ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags machine = EM_HOST; } switch (machine) { -#if EM_HOST != EM_X86_64 && EM_HOST != EM_386 - case EM_HOST: - reg = get_arch_regnum(regname); - break; -#endif case EM_X86_64: - fallthrough; + reg = __get_dwarf_regnum_x86_64(name); + break; case EM_386: - reg = get_x86_regnum(regname); + reg = __get_dwarf_regnum_i386(name); + break; + case EM_ARM: + reg = _get_dwarf_regnum(arm_regstr_tbl, name); + break; + case EM_AARCH64: + reg = _get_dwarf_regnum(aarch64_regstr_tbl, name); + break; + case EM_CSKY: + reg = __get_csky_regnum(name, flags); + break; + case EM_SH: + reg = _get_dwarf_regnum(sh_regstr_tbl, name); + break; + case EM_S390: + reg = _get_dwarf_regnum(s390_regstr_tbl, name); + break; + case EM_PPC: + case EM_PPC64: + reg = _get_dwarf_regnum(powerpc_regstr_tbl, name); + break; + case EM_RISCV: + reg = _get_dwarf_regnum(riscv_regstr_tbl, name); + break; + case EM_SPARC: + case EM_SPARCV9: + reg = _get_dwarf_regnum(sparc_regstr_tbl, name); + break; + case EM_XTENSA: + reg = _get_dwarf_regnum(xtensa_regstr_tbl, name); + break; + case EM_MIPS: + reg = _get_dwarf_regnum(mips_regstr_tbl, name); + break; + case EM_LOONGARCH: + reg = _get_dwarf_regnum(loongarch_regstr_tbl, name); break; default: pr_err("ELF MACHINE %x is not supported.\n", machine); } free(regname); return reg; + + #undef _get_dwarf_regnum +} + +static int get_libdw_frame_nregs(unsigned int machine, unsigned int flags __maybe_unused) +{ + switch (machine) { + case EM_X86_64: + return 17; + case EM_386: + return 9; + case EM_ARM: + return 16; + case EM_AARCH64: + return 97; + case EM_CSKY: + return 38; + case EM_S390: + return 32; + case EM_PPC: + case EM_PPC64: + return 145; + case EM_RISCV: + return 66; + case EM_SPARC: + case EM_SPARCV9: + return 103; + case EM_LOONGARCH: + return 74; + case EM_MIPS: + return 71; + default: + return 0; + } +} + +int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine, + unsigned int flags, bool only_libdw_supported) +{ + int reg; + + switch (machine) { + case EM_X86_64: + reg = __get_dwarf_regnum_for_perf_regnum_x86_64(perf_regnum); + break; + case EM_386: + reg = __get_dwarf_regnum_for_perf_regnum_i386(perf_regnum); + break; + case EM_ARM: + reg = __get_dwarf_regnum_for_perf_regnum_arm(perf_regnum); + break; + case EM_AARCH64: + reg = __get_dwarf_regnum_for_perf_regnum_arm64(perf_regnum); + break; + case EM_CSKY: + reg = __get_dwarf_regnum_for_perf_regnum_csky(perf_regnum, flags); + break; + case EM_PPC: + case EM_PPC64: + reg = __get_dwarf_regnum_for_perf_regnum_powerpc(perf_regnum); + break; + case EM_RISCV: + reg = __get_dwarf_regnum_for_perf_regnum_riscv(perf_regnum); + break; + case EM_S390: + reg = __get_dwarf_regnum_for_perf_regnum_s390(perf_regnum); + break; + case EM_LOONGARCH: + reg = __get_dwarf_regnum_for_perf_regnum_loongarch(perf_regnum); + break; + case EM_MIPS: + reg = __get_dwarf_regnum_for_perf_regnum_mips(perf_regnum); + break; + default: + pr_err("ELF MACHINE %x is not supported.\n", machine); + return -ENOENT; + } + if (reg >= 0 && only_libdw_supported) { + int nregs = get_libdw_frame_nregs(machine, flags); + + if (reg >= nregs) + reg = -ENOENT; + } + return reg; } diff --git a/tools/perf/util/env.c b/tools/perf/util/env.c index f1626d2032cd..93d475a80f14 100644 --- a/tools/perf/util/env.c +++ b/tools/perf/util/env.c @@ -216,6 +216,34 @@ static void perf_env__purge_bpf(struct perf_env *env __maybe_unused) } #endif // HAVE_LIBBPF_SUPPORT +void free_cpu_domain_info(struct cpu_domain_map **cd_map, u32 schedstat_version, u32 nr) +{ + if (!cd_map) + return; + + for (u32 i = 0; i < nr; i++) { + if (!cd_map[i]) + continue; + + for (u32 j = 0; j < cd_map[i]->nr_domains; j++) { + struct domain_info *d_info = cd_map[i]->domains[j]; + + if (!d_info) + continue; + + if (schedstat_version >= 17) + zfree(&d_info->dname); + + zfree(&d_info->cpumask); + zfree(&d_info->cpulist); + zfree(&d_info); + } + zfree(&cd_map[i]->domains); + zfree(&cd_map[i]); + } + zfree(&cd_map); +} + void perf_env__exit(struct perf_env *env) { int i, j; @@ -265,6 +293,7 @@ void perf_env__exit(struct perf_env *env) zfree(&env->pmu_caps[i].pmu_name); } zfree(&env->pmu_caps); + free_cpu_domain_info(env->cpu_domain, env->schedstat_version, env->nr_cpus_avail); } void perf_env__init(struct perf_env *env) diff --git a/tools/perf/util/env.h b/tools/perf/util/env.h index 9977b85523a8..a4501cbca375 100644 --- a/tools/perf/util/env.h +++ b/tools/perf/util/env.h @@ -54,6 +54,19 @@ struct pmu_caps { char *pmu_name; }; +struct domain_info { + u32 domain; + char *dname; + char *cpumask; + char *cpulist; +}; + +struct cpu_domain_map { + u32 cpu; + u32 nr_domains; + struct domain_info **domains; +}; + typedef const char *(arch_syscalls__strerrno_t)(int err); struct perf_env { @@ -61,6 +74,9 @@ struct perf_env { char *os_release; char *version; char *arch; + /* e_machine expanded from 16 to 32-bits for alignment. */ + u32 e_machine; + u32 e_flags; int nr_cpus_online; int nr_cpus_avail; char *cpu_desc; @@ -70,6 +86,8 @@ struct perf_env { unsigned int max_branches; unsigned int br_cntr_nr; unsigned int br_cntr_width; + unsigned int schedstat_version; + unsigned int max_sched_domains; int kernel_is_64_bit; int nr_cmdline; @@ -92,6 +110,7 @@ struct perf_env { char **cpu_pmu_caps; struct cpu_topology_map *cpu; struct cpu_cache_level *caches; + struct cpu_domain_map **cpu_domain; int caches_cnt; u32 comp_ratio; u32 comp_ver; @@ -151,6 +170,7 @@ struct bpf_prog_info_node; struct btf_node; int perf_env__read_core_pmu_caps(struct perf_env *env); +void free_cpu_domain_info(struct cpu_domain_map **cd_map, u32 schedstat_version, u32 nr); void perf_env__exit(struct perf_env *env); int perf_env__kernel_is_64_bit(struct perf_env *env); diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 4c92cc1a952c..bc045fddf7d5 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -83,6 +83,8 @@ static const char *perf_event__names[] = { [PERF_RECORD_FINISHED_INIT] = "FINISHED_INIT", [PERF_RECORD_COMPRESSED2] = "COMPRESSED2", [PERF_RECORD_BPF_METADATA] = "BPF_METADATA", + [PERF_RECORD_SCHEDSTAT_CPU] = "SCHEDSTAT_CPU", + [PERF_RECORD_SCHEDSTAT_DOMAIN] = "SCHEDSTAT_DOMAIN", }; const char *perf_event__name(unsigned int id) @@ -571,6 +573,56 @@ size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *ma return ret; } +size_t perf_event__fprintf_schedstat_cpu(union perf_event *event, FILE *fp) +{ + struct perf_record_schedstat_cpu *cs = &event->schedstat_cpu; + size_t size = fprintf(fp, "\ncpu%u ", cs->cpu); + __u16 version = cs->version; + +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) \ + size += fprintf(fp, "%" PRIu64 " ", (uint64_t)cs->_ver._name) + + if (version == 15) { +#include + return size; + } else if (version == 16) { +#include + return size; + } else if (version == 17) { +#include + return size; + } +#undef CPU_FIELD + + return fprintf(fp, "Unsupported /proc/schedstat version %d.\n", + event->schedstat_cpu.version); +} + +size_t perf_event__fprintf_schedstat_domain(union perf_event *event, FILE *fp) +{ + struct perf_record_schedstat_domain *ds = &event->schedstat_domain; + __u16 version = ds->version; + size_t size = fprintf(fp, "\ndomain%u ", ds->domain); + +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) \ + size += fprintf(fp, "%" PRIu64 " ", (uint64_t)ds->_ver._name) + + if (version == 15) { +#include + return size; + } else if (version == 16) { +#include + return size; + } else if (version == 17) { +#include + return size; + } +#undef DOMAIN_FIELD + + return fprintf(fp, "Unsupported /proc/schedstat version %d.\n", + event->schedstat_domain.version); +} + size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp) { size_t ret = fprintf(fp, "PERF_RECORD_%s", @@ -646,7 +698,6 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, struct machine *machine = maps__machine(maps); bool load_map = false; - maps__zput(al->maps); map__zput(al->map); thread__zput(al->thread); al->thread = thread__get(thread); @@ -684,7 +735,6 @@ struct map *thread__find_map(struct thread *thread, u8 cpumode, u64 addr, return NULL; } - al->maps = maps__get(maps); al->map = maps__find(maps, al->addr); if (al->map != NULL) { /* diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 64c63b59d617..2ea83fdf8a03 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -392,6 +392,8 @@ size_t perf_event__fprintf_ksymbol(union perf_event *event, FILE *fp); size_t perf_event__fprintf_bpf(union perf_event *event, FILE *fp); size_t perf_event__fprintf_bpf_metadata(union perf_event *event, FILE *fp); size_t perf_event__fprintf_text_poke(union perf_event *event, struct machine *machine,FILE *fp); +size_t perf_event__fprintf_schedstat_cpu(union perf_event *event, FILE *fp); +size_t perf_event__fprintf_schedstat_domain(union perf_event *event, FILE *fp); size_t perf_event__fprintf(union perf_event *event, struct machine *machine, FILE *fp); int kallsyms__get_function_start(const char *kallsyms_filename, diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 03674d2cbd01..591bdf0b3e2a 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -359,36 +359,107 @@ int evlist__add_newtp(struct evlist *evlist, const char *sys, const char *name, } #endif -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affinity *affinity) +/* + * Should sched_setaffinity be used with evlist__for_each_cpu? Determine if + * migrating the thread will avoid possibly numerous IPIs. + */ +static bool evlist__use_affinity(struct evlist *evlist) { - struct evlist_cpu_iterator itr = { + struct evsel *pos; + struct perf_cpu_map *used_cpus = NULL; + bool ret = false; + + if (evlist->no_affinity || !evlist->core.user_requested_cpus || + cpu_map__is_dummy(evlist->core.user_requested_cpus)) + return false; + + evlist__for_each_entry(evlist, pos) { + struct perf_cpu_map *intersect; + + if (!perf_pmu__benefits_from_affinity(pos->pmu)) + continue; + + if (evsel__is_dummy_event(pos)) { + /* + * The dummy event is opened on all CPUs so assume >1 + * event with shared CPUs. + */ + ret = true; + break; + } + if (evsel__is_retire_lat(pos)) { + /* + * Retirement latency events are similar to tool ones in + * their implementation, and so don't require affinity. + */ + continue; + } + if (perf_cpu_map__is_empty(used_cpus)) { + /* First benefitting event, we want >1 on a common CPU. */ + used_cpus = perf_cpu_map__get(pos->core.cpus); + continue; + } + if ((pos->core.attr.read_format & PERF_FORMAT_GROUP) && + evsel__leader(pos) != pos) { + /* Skip members of the same sample group. */ + continue; + } + intersect = perf_cpu_map__intersect(used_cpus, pos->core.cpus); + if (!perf_cpu_map__is_empty(intersect)) { + /* >1 event with shared CPUs. */ + perf_cpu_map__put(intersect); + ret = true; + break; + } + perf_cpu_map__put(intersect); + perf_cpu_map__merge(&used_cpus, pos->core.cpus); + } + perf_cpu_map__put(used_cpus); + return ret; +} + +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evlist *evlist) +{ + *itr = (struct evlist_cpu_iterator){ .container = evlist, .evsel = NULL, .cpu_map_idx = 0, .evlist_cpu_map_idx = 0, .evlist_cpu_map_nr = perf_cpu_map__nr(evlist->core.all_cpus), .cpu = (struct perf_cpu){ .cpu = -1}, - .affinity = affinity, + .affinity = NULL, }; if (evlist__empty(evlist)) { /* Ensure the empty list doesn't iterate. */ - itr.evlist_cpu_map_idx = itr.evlist_cpu_map_nr; - } else { - itr.evsel = evlist__first(evlist); - if (itr.affinity) { - itr.cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0); - affinity__set(itr.affinity, itr.cpu.cpu); - itr.cpu_map_idx = perf_cpu_map__idx(itr.evsel->core.cpus, itr.cpu); - /* - * If this CPU isn't in the evsel's cpu map then advance - * through the list. - */ - if (itr.cpu_map_idx == -1) - evlist_cpu_iterator__next(&itr); - } + itr->evlist_cpu_map_idx = itr->evlist_cpu_map_nr; + return; } - return itr; + + if (evlist__use_affinity(evlist)) { + if (affinity__setup(&itr->saved_affinity) == 0) + itr->affinity = &itr->saved_affinity; + } + itr->evsel = evlist__first(evlist); + itr->cpu = perf_cpu_map__cpu(evlist->core.all_cpus, 0); + if (itr->affinity) + affinity__set(itr->affinity, itr->cpu.cpu); + itr->cpu_map_idx = perf_cpu_map__idx(itr->evsel->core.cpus, itr->cpu); + /* + * If this CPU isn't in the evsel's cpu map then advance + * through the list. + */ + if (itr->cpu_map_idx == -1) + evlist_cpu_iterator__next(itr); +} + +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr) +{ + if (!itr->affinity) + return; + + affinity__cleanup(itr->affinity); + itr->affinity = NULL; } void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr) @@ -418,14 +489,11 @@ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr) */ if (evlist_cpu_itr->cpu_map_idx == -1) evlist_cpu_iterator__next(evlist_cpu_itr); + } else { + evlist_cpu_iterator__exit(evlist_cpu_itr); } } -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu_itr) -{ - return evlist_cpu_itr->evlist_cpu_map_idx >= evlist_cpu_itr->evlist_cpu_map_nr; -} - static int evsel__strcmp(struct evsel *pos, char *evsel_name) { if (!evsel_name) @@ -453,19 +521,11 @@ static void __evlist__disable(struct evlist *evlist, char *evsel_name, bool excl { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity = NULL; bool has_imm = false; - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity = &saved_affinity; - } - /* Disable 'immediate' events last */ for (int imm = 0; imm <= 1; imm++) { - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos = evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -483,7 +543,6 @@ static void __evlist__disable(struct evlist *evlist, char *evsel_name, bool excl break; } - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -523,16 +582,8 @@ static void __evlist__enable(struct evlist *evlist, char *evsel_name, bool excl_ { struct evsel *pos; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity saved_affinity, *affinity = NULL; - // See explanation in evlist__close() - if (!cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - if (affinity__setup(&saved_affinity) < 0) - return; - affinity = &saved_affinity; - } - - evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { pos = evlist_cpu_itr.evsel; if (evsel__strcmp(pos, evsel_name)) continue; @@ -542,7 +593,6 @@ static void __evlist__enable(struct evlist *evlist, char *evsel_name, bool excl_ continue; evsel__enable_cpu(pos, evlist_cpu_itr.cpu_map_idx); } - affinity__cleanup(affinity); evlist__for_each_entry(evlist, pos) { if (evsel__strcmp(pos, evsel_name)) continue; @@ -1339,28 +1389,14 @@ void evlist__close(struct evlist *evlist) { struct evsel *evsel; struct evlist_cpu_iterator evlist_cpu_itr; - struct affinity affinity; - /* - * With perf record core.user_requested_cpus is usually NULL. - * Use the old method to handle this for now. - */ - if (!evlist->core.user_requested_cpus || - cpu_map__is_dummy(evlist->core.user_requested_cpus)) { - evlist__for_each_entry_reverse(evlist, evsel) - evsel__close(evsel); - return; - } - - if (affinity__setup(&affinity) < 0) - return; - - evlist__for_each_cpu(evlist_cpu_itr, evlist, &affinity) { + evlist__for_each_cpu(evlist_cpu_itr, evlist) { + if (evlist_cpu_itr.cpu_map_idx == 0 && evsel__is_retire_lat(evlist_cpu_itr.evsel)) + evsel__tpebs_close(evlist_cpu_itr.evsel); perf_evsel__close_cpu(&evlist_cpu_itr.evsel->core, evlist_cpu_itr.cpu_map_idx); } - affinity__cleanup(&affinity); evlist__for_each_entry_reverse(evlist, evsel) { perf_evsel__free_fd(&evsel->core); perf_evsel__free_id(&evsel->core); @@ -1614,14 +1650,14 @@ int evlist__parse_sample_timestamp(struct evlist *evlist, union perf_event *even int evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size) { int printed, value; - char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); switch (err) { case EACCES: case EPERM: + errno = err; printed = scnprintf(buf, size, - "Error:\t%s.\n" - "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting.", emsg); + "Error:\t%m.\n" + "Hint:\tCheck /proc/sys/kernel/perf_event_paranoid setting."); value = perf_event_paranoid(); @@ -1648,16 +1684,18 @@ int evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size if (first->core.attr.sample_freq < (u64)max_freq) goto out_default; + errno = err; printed = scnprintf(buf, size, - "Error:\t%s.\n" + "Error:\t%m.\n" "Hint:\tCheck /proc/sys/kernel/perf_event_max_sample_rate.\n" "Hint:\tThe current value is %d and %" PRIu64 " is being requested.", - emsg, max_freq, first->core.attr.sample_freq); + max_freq, first->core.attr.sample_freq); break; } default: out_default: - scnprintf(buf, size, "%s", emsg); + errno = err; + scnprintf(buf, size, "%m"); break; } @@ -1666,17 +1704,17 @@ int evlist__strerror_open(struct evlist *evlist, int err, char *buf, size_t size int evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size) { - char sbuf[STRERR_BUFSIZE], *emsg = str_error_r(err, sbuf, sizeof(sbuf)); int pages_attempted = evlist->core.mmap_len / 1024, pages_max_per_user, printed = 0; switch (err) { case EPERM: sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user); + errno = err; printed += scnprintf(buf + printed, size - printed, - "Error:\t%s.\n" + "Error:\t%m.\n" "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n" "Hint:\tTried using %zd kB.\n", - emsg, pages_max_per_user, pages_attempted); + pages_max_per_user, pages_attempted); if (pages_attempted >= pages_max_per_user) { printed += scnprintf(buf + printed, size - printed, @@ -1688,7 +1726,8 @@ int evlist__strerror_mmap(struct evlist *evlist, int err, char *buf, size_t size "Hint:\tTry using a smaller -m/--mmap-pages value."); break; default: - scnprintf(buf, size, "%s", emsg); + errno = err; + scnprintf(buf, size, "%m"); break; } @@ -1920,8 +1959,8 @@ static int evlist__parse_control_fifo(const char *str, int *ctl_fd, int *ctl_fd_ */ fd = open(s, O_RDWR | O_NONBLOCK | O_CLOEXEC); if (fd < 0) { - pr_err("Failed to open '%s'\n", s); ret = -errno; + pr_err("Failed to open '%s': %m\n", s); goto out_free; } *ctl_fd = fd; @@ -1931,7 +1970,7 @@ static int evlist__parse_control_fifo(const char *str, int *ctl_fd, int *ctl_fd_ /* O_RDWR | O_NONBLOCK means the other end need not be open */ fd = open(p, O_RDWR | O_NONBLOCK | O_CLOEXEC); if (fd < 0) { - pr_err("Failed to open '%s'\n", p); + pr_err("Failed to open '%s': %m\n", p); ret = -errno; goto out_free; } @@ -1945,7 +1984,8 @@ static int evlist__parse_control_fifo(const char *str, int *ctl_fd, int *ctl_fd_ int evlist__parse_control(const char *str, int *ctl_fd, int *ctl_fd_ack, bool *ctl_fd_close) { - char *comma = NULL, *endptr = NULL; + const char *comma = NULL; + char *endptr = NULL; *ctl_fd_close = false; @@ -2363,7 +2403,7 @@ int evlist__parse_event_enable_time(struct evlist *evlist, struct record_opts *o eet->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC); if (eet->timerfd == -1) { err = -errno; - pr_err("timerfd_create failed: %s\n", strerror(errno)); + pr_err("timerfd_create failed: %m\n"); goto free_eet_times; } @@ -2398,7 +2438,7 @@ static int event_enable_timer__set_timer(struct event_enable_timer *eet, int ms) if (timerfd_settime(eet->timerfd, 0, &its, NULL) < 0) { err = -errno; - pr_err("timerfd_settime failed: %s\n", strerror(errno)); + pr_err("timerfd_settime failed: %m\n"); } return err; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 911834ae7c2a..d17c3b57a409 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -10,6 +10,7 @@ #include #include #include +#include "affinity.h" #include "events_stats.h" #include "evsel.h" #include "rblist.h" @@ -58,6 +59,7 @@ struct event_enable_timer; struct evlist { struct perf_evlist core; bool enabled; + bool no_affinity; int id_pos; int is_pos; int nr_br_cntr; @@ -363,6 +365,8 @@ struct evlist_cpu_iterator { struct perf_cpu cpu; /** If present, used to set the affinity when switching between CPUs. */ struct affinity *affinity; + /** Maybe be used to hold affinity state prior to iterating. */ + struct affinity saved_affinity; }; /** @@ -370,22 +374,31 @@ struct evlist_cpu_iterator { * affinity, iterate over all CPUs and then the evlist * for each evsel on that CPU. When switching between * CPUs the affinity is set to the CPU to avoid IPIs - * during syscalls. + * during syscalls. The affinity is set up and removed + * automatically, if the loop is broken a call to + * evlist_cpu_iterator__exit is necessary. * @evlist_cpu_itr: the iterator instance. * @evlist: evlist instance to iterate. - * @affinity: NULL or used to set the affinity to the current CPU. */ -#define evlist__for_each_cpu(evlist_cpu_itr, evlist, affinity) \ - for ((evlist_cpu_itr) = evlist__cpu_begin(evlist, affinity); \ +#define evlist__for_each_cpu(evlist_cpu_itr, evlist) \ + for (evlist_cpu_iterator__init(&(evlist_cpu_itr), evlist); \ !evlist_cpu_iterator__end(&evlist_cpu_itr); \ evlist_cpu_iterator__next(&evlist_cpu_itr)) -/** Returns an iterator set to the first CPU/evsel of evlist. */ -struct evlist_cpu_iterator evlist__cpu_begin(struct evlist *evlist, struct affinity *affinity); +/** Setup an iterator set to the first CPU/evsel of evlist. */ +void evlist_cpu_iterator__init(struct evlist_cpu_iterator *itr, struct evlist *evlist); +/** + * Cleans up the iterator, automatically done by evlist_cpu_iterator__next when + * the end of the list is reached. Multiple calls are safe. + */ +void evlist_cpu_iterator__exit(struct evlist_cpu_iterator *itr); /** Move to next element in iterator, updating CPU, evsel and the affinity. */ void evlist_cpu_iterator__next(struct evlist_cpu_iterator *evlist_cpu_itr); /** Returns true when iterator is at the end of the CPUs and evlist. */ -bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu_itr); +static inline bool evlist_cpu_iterator__end(const struct evlist_cpu_iterator *evlist_cpu_itr) +{ + return evlist_cpu_itr->evlist_cpu_map_idx >= evlist_cpu_itr->evlist_cpu_map_nr; +} struct evsel *evlist__get_tracking_event(struct evlist *evlist); void evlist__set_tracking_event(struct evlist *evlist, struct evsel *tracking_evsel); diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9cd706f62793..f59228c1a39e 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -34,6 +34,7 @@ #include "callchain.h" #include "cgroup.h" #include "counts.h" +#include "dwarf-regs.h" #include "event.h" #include "evsel.h" #include "time-utils.h" @@ -648,8 +649,9 @@ struct tep_event *evsel__tp_format(struct evsel *evsel) if (IS_ERR(tp_format)) { int err = -PTR_ERR(evsel->tp_format); - pr_err("Error getting tracepoint format '%s' '%s'(%d)\n", - evsel__name(evsel), strerror(err), err); + errno = err; + pr_err("Error getting tracepoint format '%s': %m\n", + evsel__name(evsel)); return NULL; } evsel->tp_format = tp_format; @@ -1006,6 +1008,13 @@ int evsel__group_desc(struct evsel *evsel, char *buf, size_t size) return ret; } +uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags) +{ + struct perf_session *session = evsel__session(evsel); + + return perf_session__e_machine(session, e_flags); +} + static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, struct callchain_param *param) { @@ -1041,18 +1050,18 @@ static void __evsel__config_callchain(struct evsel *evsel, struct record_opts *o if (param->record_mode == CALLCHAIN_DWARF) { if (!function) { - const char *arch = perf_env__arch(evsel__env(evsel)); + uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL); evsel__set_sample_bit(evsel, REGS_USER); evsel__set_sample_bit(evsel, STACK_USER); if (opts->sample_user_regs && - DWARF_MINIMAL_REGS(arch) != arch__user_reg_mask()) { - attr->sample_regs_user |= DWARF_MINIMAL_REGS(arch); + DWARF_MINIMAL_REGS(e_machine) != perf_user_reg_mask(EM_HOST)) { + attr->sample_regs_user |= DWARF_MINIMAL_REGS(e_machine); pr_warning("WARNING: The use of --call-graph=dwarf may require all the user registers, " "specifying a subset with --user-regs may render DWARF unwinding unreliable, " "so the minimal registers set (IP, SP) is explicitly forced.\n"); } else { - attr->sample_regs_user |= arch__user_reg_mask(); + attr->sample_regs_user |= perf_user_reg_mask(EM_HOST); } attr->sample_stack_user = param->dump_size; attr->exclude_callchain_user = 1; @@ -1242,7 +1251,11 @@ static void evsel__apply_config_terms(struct evsel *evsel, case EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE: /* Already applied by auxtrace */ break; - case EVSEL__CONFIG_TERM_CFG_CHG: + case EVSEL__CONFIG_TERM_USR_CHG_CONFIG: + case EVSEL__CONFIG_TERM_USR_CHG_CONFIG1: + case EVSEL__CONFIG_TERM_USR_CHG_CONFIG2: + case EVSEL__CONFIG_TERM_USR_CHG_CONFIG3: + case EVSEL__CONFIG_TERM_USR_CHG_CONFIG4: break; case EVSEL__CONFIG_TERM_RATIO_TO_PREV: rtp_buf = term->val.str; @@ -1314,6 +1327,109 @@ struct evsel_config_term *__evsel__get_config_term(struct evsel *evsel, enum evs return found_term; } +/* + * Set @config_name to @val as long as the user hasn't already set or cleared it + * by passing a config term on the command line. + * + * @val is the value to put into the bits specified by @config_name rather than + * the bit pattern. It is shifted into position by this function, so to set + * something to true, pass 1 for val rather than a pre shifted value. + */ +void evsel__set_config_if_unset(struct evsel *evsel, const char *config_name, + u64 val) +{ + u64 user_bits = 0; + struct evsel_config_term *term = evsel__get_config_term(evsel, + USR_CHG_CONFIG); + struct perf_pmu_format *format = pmu_find_format(&evsel->pmu->format, + config_name); + int fbit; + __u64 *vp; + + if (!format) + return; + + switch (format->value) { + case PERF_PMU_FORMAT_VALUE_CONFIG: + term = evsel__get_config_term(evsel, USR_CHG_CONFIG); + vp = &evsel->core.attr.config; + break; + case PERF_PMU_FORMAT_VALUE_CONFIG1: + term = evsel__get_config_term(evsel, USR_CHG_CONFIG1); + vp = &evsel->core.attr.config1; + break; + case PERF_PMU_FORMAT_VALUE_CONFIG2: + term = evsel__get_config_term(evsel, USR_CHG_CONFIG2); + vp = &evsel->core.attr.config2; + break; + case PERF_PMU_FORMAT_VALUE_CONFIG3: + term = evsel__get_config_term(evsel, USR_CHG_CONFIG3); + vp = &evsel->core.attr.config3; + break; + case PERF_PMU_FORMAT_VALUE_CONFIG4: + term = evsel__get_config_term(evsel, USR_CHG_CONFIG4); + vp = &evsel->core.attr.config4; + break; + default: + pr_err("Unknown format value: %d\n", format->value); + return; + } + + if (!format) + return; + + if (term) + user_bits = term->val.cfg_chg; + + /* Do nothing if the user changed the value */ + for_each_set_bit(fbit, format->bits, PERF_PMU_FORMAT_BITS) + if ((1ULL << fbit) & user_bits) + return; + + /* Otherwise replace it */ + perf_pmu__format_pack(format->bits, val, vp, /*zero=*/true); +} + + +int evsel__get_config_val(const struct evsel *evsel, const char *config_name, + u64 *val) +{ + struct perf_pmu_format *format = pmu_find_format(&evsel->pmu->format, config_name); + + if (!format || bitmap_empty(format->bits, PERF_PMU_FORMAT_BITS)) { + pr_err("Unknown/empty format name: %s\n", config_name); + *val = 0; + return -EINVAL; + } + + switch (format->value) { + case PERF_PMU_FORMAT_VALUE_CONFIG: + *val = perf_pmu__format_unpack(format->bits, + evsel->core.attr.config); + return 0; + case PERF_PMU_FORMAT_VALUE_CONFIG1: + *val = perf_pmu__format_unpack(format->bits, + evsel->core.attr.config1); + return 0; + case PERF_PMU_FORMAT_VALUE_CONFIG2: + *val = perf_pmu__format_unpack(format->bits, + evsel->core.attr.config2); + return 0; + case PERF_PMU_FORMAT_VALUE_CONFIG3: + *val = perf_pmu__format_unpack(format->bits, + evsel->core.attr.config3); + return 0; + case PERF_PMU_FORMAT_VALUE_CONFIG4: + *val = perf_pmu__format_unpack(format->bits, + evsel->core.attr.config4); + return 0; + default: + pr_err("Unknown format value: %d\n", format->value); + *val = 0; + return -EINVAL; + } +} + void __weak arch_evsel__set_sample_weight(struct evsel *evsel) { evsel__set_sample_bit(evsel, WEIGHT); @@ -1445,10 +1561,11 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, attr->inherit_stat = 1; } - if (opts->sample_address) { + if (opts->sample_address) evsel__set_sample_bit(evsel, ADDR); + + if (opts->record_data_mmap) attr->mmap_data = track; - } /* * We don't allow user space callchains for function trace @@ -2771,8 +2888,8 @@ static int evsel__open_cpu(struct evsel *evsel, struct perf_cpu_map *cpus, PERF_EVENT_IOC_SET_BPF, bpf_fd); if (err && errno != EEXIST) { - pr_err("failed to attach bpf fd %d: %s\n", - bpf_fd, strerror(errno)); + pr_err("failed to attach bpf fd %d: %m\n", + bpf_fd); err = -EINVAL; goto out_close; } @@ -3863,7 +3980,6 @@ int evsel__open_strerror(struct evsel *evsel, struct target *target, int err, char *msg, size_t size) { struct perf_pmu *pmu; - char sbuf[STRERR_BUFSIZE]; int printed = 0, enforced = 0; int ret; @@ -3996,10 +4112,11 @@ int evsel__open_strerror(struct evsel *evsel, struct target *target, if (ret) return ret; + errno = err; return scnprintf(msg, size, - "The sys_perf_event_open() syscall returned with %d (%s) for event (%s).\n" - "\"dmesg | grep -i perf\" may provide additional information.\n", - err, str_error_r(err, sbuf, sizeof(sbuf)), evsel__name(evsel)); + "The sys_perf_event_open() syscall failed for event (%s): %m\n" + "\"dmesg | grep -i perf\" may provide additional information.\n", + evsel__name(evsel)); } struct perf_session *evsel__session(struct evsel *evsel) @@ -4097,6 +4214,17 @@ void evsel__set_leader(struct evsel *evsel, struct evsel *leader) evsel->core.leader = &leader->core; } +bool evsel__is_aux_event(const struct evsel *evsel) +{ + struct perf_pmu *pmu; + + if (evsel->needs_auxtrace_mmap) + return true; + + pmu = evsel__find_pmu(evsel); + return pmu && pmu->auxtrace; +} + int evsel__source_count(const struct evsel *evsel) { struct evsel *pos; diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a08130ff2e47..a3d754c029a0 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -546,6 +546,7 @@ static inline bool evsel__is_dummy_event(struct evsel *evsel) struct perf_session *evsel__session(struct evsel *evsel); struct perf_env *evsel__env(struct evsel *evsel); +uint16_t evsel__e_machine(struct evsel *evsel, uint32_t *e_flags); int evsel__store_ids(struct evsel *evsel, struct evlist *evlist); @@ -575,8 +576,10 @@ void evsel__uniquify_counter(struct evsel *counter); ((((src) >> (pos)) & ((1ull << (size)) - 1)) << (63 - ((pos) + (size) - 1))) u64 evsel__bitfield_swap_branch_flags(u64 value); -void evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel, - const char *config_name, u64 val); +int evsel__get_config_val(const struct evsel *evsel, const char *config_name, + u64 *val); +void evsel__set_config_if_unset(struct evsel *evsel, const char *config_name, + u64 val); bool evsel__is_offcpu_event(struct evsel *evsel); diff --git a/tools/perf/util/evsel_config.h b/tools/perf/util/evsel_config.h index bcd3a978f0c4..7b565d76c0bc 100644 --- a/tools/perf/util/evsel_config.h +++ b/tools/perf/util/evsel_config.h @@ -27,7 +27,11 @@ enum evsel_term_type { EVSEL__CONFIG_TERM_AUX_OUTPUT, EVSEL__CONFIG_TERM_AUX_ACTION, EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE, - EVSEL__CONFIG_TERM_CFG_CHG, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG1, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG2, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG3, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG4, EVSEL__CONFIG_TERM_RATIO_TO_PREV, }; @@ -50,6 +54,7 @@ struct evsel_config_term { u64 cfg_chg; char *str; int cpu; + u64 val; } val; bool weak; }; diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c index 10f1a03c2860..5521d00bff2c 100644 --- a/tools/perf/util/evsel_fprintf.c +++ b/tools/perf/util/evsel_fprintf.c @@ -185,8 +185,12 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment, if (print_dso && (!sym || !sym->inlined)) printed += map__fprintf_dsoname_dsoff(map, print_dsoff, addr, fp); - if (print_srcline) - printed += map__fprintf_srcline(map, addr, "\n ", fp); + if (print_srcline) { + if (node->srcline) + printed += fprintf(fp, "\n %s", node->srcline); + else + printed += map__fprintf_srcline(map, addr, "\n ", fp); + } if (sym && sym->inlined) printed += fprintf(fp, " (inlined)"); diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c index a1cd5196f4ec..14882def9704 100644 --- a/tools/perf/util/genelf.c +++ b/tools/perf/util/genelf.c @@ -18,8 +18,8 @@ #include #endif +#include "blake2s.h" #include "genelf.h" -#include "sha1.h" #include "../util/jitdump.h" #include @@ -51,7 +51,7 @@ static char shd_string_table[] = { static struct buildid_note { Elf_Note desc; /* descsz: size of build-id, must be multiple of 4 */ char name[4]; /* GNU\0 */ - u8 build_id[SHA1_DIGEST_SIZE]; + u8 build_id[20]; } bnote; static Elf_Sym symtab[]={ @@ -152,9 +152,28 @@ jit_add_eh_frame_info(Elf *e, void* unwinding, uint64_t unwinding_header_size, return 0; } +enum { + TAG_CODE = 0, + TAG_SYMTAB = 1, + TAG_STRSYM = 2, +}; + +/* + * Update the hash using the given data, also prepending a (tag, len) prefix to + * ensure that distinct input tuples reliably result in distinct hashes. + */ +static void blake2s_update_tagged(struct blake2s_ctx *ctx, int tag, + const void *data, size_t len) +{ + u64 prefix = ((u64)tag << 56) | len; + + blake2s_update(ctx, (const u8 *)&prefix, sizeof(prefix)); + blake2s_update(ctx, data, len); +} + /* * fd: file descriptor open for writing for the output file - * load_addr: code load address (could be zero, just used for buildid) + * load_addr: code load address (could be zero) * sym: function name (for native code - used as the symbol) * code: the native code * csize: the code size in bytes @@ -173,8 +192,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, Elf_Shdr *shdr; uint64_t eh_frame_base_offset; char *strsym = NULL; - void *build_id_data = NULL, *tmp; - int build_id_data_len; + struct blake2s_ctx ctx; int symlen; int retval = -1; @@ -253,13 +271,8 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC; shdr->sh_entsize = 0; - build_id_data = malloc(csize); - if (build_id_data == NULL) { - warnx("cannot allocate build-id data"); - goto error; - } - memcpy(build_id_data, code, csize); - build_id_data_len = csize; + blake2s_init(&ctx, sizeof(bnote.build_id)); + blake2s_update_tagged(&ctx, TAG_CODE, code, csize); /* * Setup .eh_frame_hdr and .eh_frame @@ -344,14 +357,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, shdr->sh_entsize = sizeof(Elf_Sym); shdr->sh_link = unwinding ? 6 : 4; /* index of .strtab section */ - tmp = realloc(build_id_data, build_id_data_len + sizeof(symtab)); - if (tmp == NULL) { - warnx("cannot allocate build-id data"); - goto error; - } - memcpy(tmp + build_id_data_len, symtab, sizeof(symtab)); - build_id_data = tmp; - build_id_data_len += sizeof(symtab); + blake2s_update_tagged(&ctx, TAG_SYMTAB, symtab, sizeof(symtab)); /* * setup symbols string table @@ -395,14 +401,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, shdr->sh_flags = 0; shdr->sh_entsize = 0; - tmp = realloc(build_id_data, build_id_data_len + symlen); - if (tmp == NULL) { - warnx("cannot allocate build-id data"); - goto error; - } - memcpy(tmp + build_id_data_len, strsym, symlen); - build_id_data = tmp; - build_id_data_len += symlen; + blake2s_update_tagged(&ctx, TAG_STRSYM, strsym, symlen); /* * setup build-id section @@ -422,7 +421,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, /* * build-id generation */ - sha1(build_id_data, build_id_data_len, bnote.build_id); + blake2s_final(&ctx, bnote.build_id); bnote.desc.namesz = sizeof(bnote.name); /* must include 0 termination */ bnote.desc.descsz = sizeof(bnote.build_id); bnote.desc.type = NT_GNU_BUILD_ID; @@ -467,7 +466,6 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, (void)elf_end(e); free(strsym); - free(build_id_data); return retval; } diff --git a/tools/perf/util/generate-cmdlist.sh b/tools/perf/util/generate-cmdlist.sh deleted file mode 100755 index 6a73c903d690..000000000000 --- a/tools/perf/util/generate-cmdlist.sh +++ /dev/null @@ -1,70 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: GPL-2.0 - -echo "/* Automatically generated by $0 */ -struct cmdname_help -{ - char name[16]; - char help[80]; -}; - -static struct cmdname_help common_cmds[] = {" - -sed -n -e 's/^perf-\([^ ]*\)[ ].* common.*/\1/p' command-list.txt | -sort | -while read cmd -do - sed -n ' - /^NAME/,/perf-'"$cmd"'/H - ${ - x - s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ - p - }' "Documentation/perf-$cmd.txt" -done - -echo "#ifdef HAVE_LIBELF_SUPPORT" -sed -n -e 's/^perf-\([^ ]*\)[ ].* full.*/\1/p' command-list.txt | -sort | -while read cmd -do - sed -n ' - /^NAME/,/perf-'"$cmd"'/H - ${ - x - s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ - p - }' "Documentation/perf-$cmd.txt" -done -echo "#endif /* HAVE_LIBELF_SUPPORT */" - -echo "#if defined(HAVE_LIBTRACEEVENT)" -sed -n -e 's/^perf-\([^ ]*\)[ ].* audit*/\1/p' command-list.txt | -sort | -while read cmd -do - sed -n ' - /^NAME/,/perf-'"$cmd"'/H - ${ - x - s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ - p - }' "Documentation/perf-$cmd.txt" -done -echo "#endif /* HAVE_LIBTRACEEVENT */" - -echo "#ifdef HAVE_LIBTRACEEVENT" -sed -n -e 's/^perf-\([^ ]*\)[ ].* traceevent.*/\1/p' command-list.txt | -sort | -while read cmd -do - sed -n ' - /^NAME/,/perf-'"$cmd"'/H - ${ - x - s/.*perf-'"$cmd"' - \(.*\)/ {"'"$cmd"'", "\1"},/ - p - }' "Documentation/perf-$cmd.txt" -done -echo "#endif /* HAVE_LIBTRACEEVENT */" -echo "};" diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f5cad377c99e..9142a8ba4019 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c @@ -76,6 +76,7 @@ static const u64 __perf_magic2 = 0x32454c4946524550ULL; static const u64 __perf_magic2_sw = 0x50455246494c4532ULL; #define PERF_MAGIC __perf_magic2 +#define DNAME_LEN 16 const char perf_version_string[] = PERF_VERSION; @@ -378,6 +379,21 @@ static int write_arch(struct feat_fd *ff, return do_write_string(ff, uts.machine); } +static int write_e_machine(struct feat_fd *ff, + struct evlist *evlist __maybe_unused) +{ + /* e_machine expanded from 16 to 32-bits for alignment. */ + uint32_t e_flags; + uint32_t e_machine = perf_session__e_machine(evlist->session, &e_flags); + int ret; + + ret = do_write(ff, &e_machine, sizeof(e_machine)); + if (ret) + return ret; + + return do_write(ff, &e_flags, sizeof(e_flags)); +} + static int write_version(struct feat_fd *ff, struct evlist *evlist __maybe_unused) { @@ -1614,6 +1630,161 @@ static int write_pmu_caps(struct feat_fd *ff, return 0; } +struct cpu_domain_map **build_cpu_domain_map(u32 *schedstat_version, u32 *max_sched_domains, u32 nr) +{ + char dname[DNAME_LEN], cpumask[MAX_NR_CPUS]; + struct domain_info *domain_info; + struct cpu_domain_map **cd_map; + char cpulist[MAX_NR_CPUS]; + char *line = NULL; + u32 cpu, domain; + u32 dcount = 0; + size_t len; + FILE *fp; + + fp = fopen("/proc/schedstat", "r"); + if (!fp) { + pr_err("Failed to open /proc/schedstat\n"); + return NULL; + } + + cd_map = zalloc(sizeof(*cd_map) * nr); + if (!cd_map) + goto out; + + while (getline(&line, &len, fp) > 0) { + int retval; + + if (strncmp(line, "version", 7) == 0) { + retval = sscanf(line, "version %d\n", schedstat_version); + if (retval != 1) + continue; + + } else if (strncmp(line, "cpu", 3) == 0) { + retval = sscanf(line, "cpu%u %*s", &cpu); + if (retval == 1) { + cd_map[cpu] = zalloc(sizeof(*cd_map[cpu])); + if (!cd_map[cpu]) + goto out_free_line; + cd_map[cpu]->cpu = cpu; + } else + continue; + + dcount = 0; + } else if (strncmp(line, "domain", 6) == 0) { + struct domain_info **temp_domains; + + dcount++; + temp_domains = realloc(cd_map[cpu]->domains, dcount * sizeof(domain_info)); + if (!temp_domains) + goto out_free_line; + else + cd_map[cpu]->domains = temp_domains; + + domain_info = zalloc(sizeof(*domain_info)); + if (!domain_info) + goto out_free_line; + + cd_map[cpu]->domains[dcount - 1] = domain_info; + + if (*schedstat_version >= 17) { + retval = sscanf(line, "domain%u %s %s %*s", &domain, dname, + cpumask); + if (retval != 3) + continue; + + domain_info->dname = strdup(dname); + if (!domain_info->dname) + goto out_free_line; + } else { + retval = sscanf(line, "domain%u %s %*s", &domain, cpumask); + if (retval != 2) + continue; + } + + domain_info->domain = domain; + if (domain > *max_sched_domains) + *max_sched_domains = domain; + + domain_info->cpumask = strdup(cpumask); + if (!domain_info->cpumask) + goto out_free_line; + + cpumask_to_cpulist(cpumask, cpulist); + domain_info->cpulist = strdup(cpulist); + if (!domain_info->cpulist) + goto out_free_line; + + cd_map[cpu]->nr_domains = dcount; + } + } + +out_free_line: + free(line); +out: + fclose(fp); + return cd_map; +} + +static int write_cpu_domain_info(struct feat_fd *ff, + struct evlist *evlist __maybe_unused) +{ + u32 max_sched_domains = 0, schedstat_version = 0; + struct cpu_domain_map **cd_map; + u32 i, j, nr, ret; + + nr = cpu__max_present_cpu().cpu; + + cd_map = build_cpu_domain_map(&schedstat_version, &max_sched_domains, nr); + if (!cd_map) + return -1; + + ret = do_write(ff, &schedstat_version, sizeof(u32)); + if (ret < 0) + goto out; + + max_sched_domains += 1; + ret = do_write(ff, &max_sched_domains, sizeof(u32)); + if (ret < 0) + goto out; + + for (i = 0; i < nr; i++) { + if (!cd_map[i]) + continue; + + ret = do_write(ff, &cd_map[i]->cpu, sizeof(u32)); + if (ret < 0) + goto out; + + ret = do_write(ff, &cd_map[i]->nr_domains, sizeof(u32)); + if (ret < 0) + goto out; + + for (j = 0; j < cd_map[i]->nr_domains; j++) { + ret = do_write(ff, &cd_map[i]->domains[j]->domain, sizeof(u32)); + if (ret < 0) + goto out; + if (schedstat_version >= 17) { + ret = do_write_string(ff, cd_map[i]->domains[j]->dname); + if (ret < 0) + goto out; + } + + ret = do_write_string(ff, cd_map[i]->domains[j]->cpumask); + if (ret < 0) + goto out; + + ret = do_write_string(ff, cd_map[i]->domains[j]->cpulist); + if (ret < 0) + goto out; + } + } + +out: + free_cpu_domain_info(cd_map, schedstat_version, nr); + return ret; +} + static void print_hostname(struct feat_fd *ff, FILE *fp) { fprintf(fp, "# hostname : %s\n", ff->ph->env.hostname); @@ -1629,6 +1800,12 @@ static void print_arch(struct feat_fd *ff, FILE *fp) fprintf(fp, "# arch : %s\n", ff->ph->env.arch); } +static void print_e_machine(struct feat_fd *ff, FILE *fp) +{ + fprintf(fp, "# e_machine : %u\n", ff->ph->env.e_machine); + fprintf(fp, "# e_flags : %u\n", ff->ph->env.e_flags); +} + static void print_cpudesc(struct feat_fd *ff, FILE *fp) { fprintf(fp, "# cpudesc : %s\n", ff->ph->env.cpu_desc); @@ -2247,6 +2424,39 @@ static void print_mem_topology(struct feat_fd *ff, FILE *fp) } } +static void print_cpu_domain_info(struct feat_fd *ff, FILE *fp) +{ + struct cpu_domain_map **cd_map = ff->ph->env.cpu_domain; + u32 nr = ff->ph->env.nr_cpus_avail; + struct domain_info *d_info; + u32 i, j; + + fprintf(fp, "# schedstat version : %u\n", ff->ph->env.schedstat_version); + fprintf(fp, "# Maximum sched domains : %u\n", ff->ph->env.max_sched_domains); + + for (i = 0; i < nr; i++) { + if (!cd_map[i]) + continue; + + fprintf(fp, "# cpu : %u\n", cd_map[i]->cpu); + fprintf(fp, "# nr_domains : %u\n", cd_map[i]->nr_domains); + + for (j = 0; j < cd_map[i]->nr_domains; j++) { + d_info = cd_map[i]->domains[j]; + if (!d_info) + continue; + + fprintf(fp, "# Domain : %u\n", d_info->domain); + + if (ff->ph->env.schedstat_version >= 17) + fprintf(fp, "# Domain name : %s\n", d_info->dname); + + fprintf(fp, "# Domain cpu map : %s\n", d_info->cpumask); + fprintf(fp, "# Domain cpu list : %s\n", d_info->cpulist); + } + } +} + static int __event_process_build_id(struct perf_record_header_build_id *bev, char *filename, struct perf_session *session) @@ -2423,6 +2633,17 @@ FEAT_PROCESS_STR_FUN(arch, arch); FEAT_PROCESS_STR_FUN(cpudesc, cpu_desc); FEAT_PROCESS_STR_FUN(cpuid, cpuid); +static int process_e_machine(struct feat_fd *ff, void *data __maybe_unused) +{ + int ret; + + ret = do_read_u32(ff, &ff->ph->env.e_machine); + if (ret) + return ret; + + return do_read_u32(ff, &ff->ph->env.e_flags); +} + #ifdef HAVE_LIBTRACEEVENT static int process_tracing_data(struct feat_fd *ff, void *data) { @@ -3388,6 +3609,93 @@ static int process_pmu_caps(struct feat_fd *ff, void *data __maybe_unused) return ret; } +static int process_cpu_domain_info(struct feat_fd *ff, void *data __maybe_unused) +{ + u32 schedstat_version, max_sched_domains, cpu, domain, nr_domains; + struct perf_env *env = &ff->ph->env; + char *dname, *cpumask, *cpulist; + struct cpu_domain_map **cd_map; + struct domain_info *d_info; + u32 nra, nr, i, j; + int ret; + + nra = env->nr_cpus_avail; + nr = env->nr_cpus_online; + + cd_map = zalloc(sizeof(*cd_map) * nra); + if (!cd_map) + return -1; + + env->cpu_domain = cd_map; + + ret = do_read_u32(ff, &schedstat_version); + if (ret) + return ret; + + env->schedstat_version = schedstat_version; + + ret = do_read_u32(ff, &max_sched_domains); + if (ret) + return ret; + + env->max_sched_domains = max_sched_domains; + + for (i = 0; i < nr; i++) { + if (do_read_u32(ff, &cpu)) + return -1; + + cd_map[cpu] = zalloc(sizeof(*cd_map[cpu])); + if (!cd_map[cpu]) + return -1; + + cd_map[cpu]->cpu = cpu; + + if (do_read_u32(ff, &nr_domains)) + return -1; + + cd_map[cpu]->nr_domains = nr_domains; + + cd_map[cpu]->domains = zalloc(sizeof(*d_info) * max_sched_domains); + if (!cd_map[cpu]->domains) + return -1; + + for (j = 0; j < nr_domains; j++) { + if (do_read_u32(ff, &domain)) + return -1; + + d_info = zalloc(sizeof(*d_info)); + if (!d_info) + return -1; + + assert(cd_map[cpu]->domains[domain] == NULL); + cd_map[cpu]->domains[domain] = d_info; + d_info->domain = domain; + + if (schedstat_version >= 17) { + dname = do_read_string(ff); + if (!dname) + return -1; + + d_info->dname = dname; + } + + cpumask = do_read_string(ff); + if (!cpumask) + return -1; + + d_info->cpumask = cpumask; + + cpulist = do_read_string(ff); + if (!cpulist) + return -1; + + d_info->cpulist = cpulist; + } + } + + return ret; +} + #define FEAT_OPR(n, func, __full_only) \ [HEADER_##n] = { \ .name = __stringify(n), \ @@ -3453,6 +3761,8 @@ const struct perf_header_feature_ops feat_ops[HEADER_LAST_FEATURE] = { FEAT_OPR(CLOCK_DATA, clock_data, false), FEAT_OPN(HYBRID_TOPOLOGY, hybrid_topology, true), FEAT_OPR(PMU_CAPS, pmu_caps, false), + FEAT_OPR(CPU_DOMAIN_INFO, cpu_domain_info, true), + FEAT_OPR(E_MACHINE, e_machine, false), }; struct header_print_data { diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index c058021c3150..cc40ac796f52 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h @@ -53,6 +53,8 @@ enum { HEADER_CLOCK_DATA, HEADER_HYBRID_TOPOLOGY, HEADER_PMU_CAPS, + HEADER_CPU_DOMAIN_INFO, + HEADER_E_MACHINE, HEADER_LAST_FEATURE, HEADER_FEAT_BITS = 256, }; @@ -210,4 +212,7 @@ char *get_cpuid_str(struct perf_cpu cpu); char *get_cpuid_allow_env_override(struct perf_cpu cpu); int strcmp_cpuid_str(const char *s1, const char *s2); + +struct cpu_domain_map **build_cpu_domain_map(u32 *schedstat_version, u32 *max_sched_domains, + u32 nr); #endif /* __PERF_HEADER_H */ diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index ef4b569f7df4..7ffaa3d9851b 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -251,7 +251,7 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h) if (h->cgroup) { const char *cgrp_name = "unknown"; - struct cgroup *cgrp = cgroup__find(maps__machine(h->ms.maps)->env, + struct cgroup *cgrp = cgroup__find(maps__machine(thread__maps(h->ms.thread))->env, h->cgroup); if (cgrp != NULL) cgrp_name = cgrp->name; @@ -536,7 +536,7 @@ static int hist_entry__init(struct hist_entry *he, memset(&he->stat, 0, sizeof(he->stat)); } - he->ms.maps = maps__get(he->ms.maps); + he->ms.thread = thread__get(he->ms.thread); he->ms.map = map__get(he->ms.map); if (he->branch_info) { @@ -552,9 +552,9 @@ static int hist_entry__init(struct hist_entry *he, memcpy(he->branch_info, template->branch_info, sizeof(*he->branch_info)); - he->branch_info->from.ms.maps = maps__get(he->branch_info->from.ms.maps); + he->branch_info->from.ms.thread = thread__get(he->branch_info->from.ms.thread); he->branch_info->from.ms.map = map__get(he->branch_info->from.ms.map); - he->branch_info->to.ms.maps = maps__get(he->branch_info->to.ms.maps); + he->branch_info->to.ms.thread = thread__get(he->branch_info->to.ms.thread); he->branch_info->to.ms.map = map__get(he->branch_info->to.ms.map); } @@ -810,7 +810,7 @@ __hists__add_entry(struct hists *hists, }, .cgroup = sample->cgroup, .ms = { - .maps = al->maps, + .thread = al->thread, .map = al->map, .sym = al->sym, }, @@ -890,7 +890,7 @@ struct hist_entry *hists__add_entry_block(struct hists *hists, .block_info = block_info, .hists = hists, .ms = { - .maps = al->maps, + .thread = al->thread, .map = al->map, .sym = al->sym, }, @@ -1020,8 +1020,8 @@ iter_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *al) if (iter->curr >= iter->total) return 0; - maps__put(al->maps); - al->maps = maps__get(bi[i].to.ms.maps); + thread__put(al->thread); + al->thread = thread__get(bi[i].to.ms.thread); map__put(al->map); al->map = map__get(bi[i].to.ms.map); al->sym = bi[i].to.ms.sym; @@ -1232,7 +1232,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter, .comm = thread__comm(al->thread), .ip = al->addr, .ms = { - .maps = al->maps, + .thread = al->thread, .map = al->map, .sym = al->sym, }, diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c index 279d6b1a47f0..fb3ffa8d32ad 100644 --- a/tools/perf/util/hwmon_pmu.c +++ b/tools/perf/util/hwmon_pmu.c @@ -161,7 +161,7 @@ bool parse_hwmon_filename(const char *filename, bool *alarm) { char fn_type[24]; - const char **elem; + const char * const *elem; const char *fn_item = NULL; size_t fn_item_len; diff --git a/tools/perf/util/include/dwarf-regs.h b/tools/perf/util/include/dwarf-regs.h index 6f1b9f6b2466..46a764cf322f 100644 --- a/tools/perf/util/include/dwarf-regs.h +++ b/tools/perf/util/include/dwarf-regs.h @@ -89,8 +89,6 @@ #define DWARF_REG_FB 0xd3affb /* random number */ #ifdef HAVE_LIBDW_SUPPORT -const char *get_csky_regstr(unsigned int n, unsigned int flags); - /** * get_dwarf_regstr() - Returns ftrace register string from DWARF regnum. * @n: DWARF register number. @@ -99,11 +97,23 @@ const char *get_csky_regstr(unsigned int n, unsigned int flags); */ const char *get_dwarf_regstr(unsigned int n, unsigned int machine, unsigned int flags); -int get_x86_regnum(const char *name); +const char *__get_csky_regstr(unsigned int n, unsigned int flags); +int __get_csky_regnum(const char *name, unsigned int flags); -#if !defined(__x86_64__) && !defined(__i386__) -int get_arch_regnum(const char *name); -#endif +int __get_dwarf_regnum_i386(const char *name); +int __get_dwarf_regnum_x86_64(const char *name); +int __get_dwarf_regnum_for_perf_regnum_i386(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_x86_64(int perf_regnum); + +int __get_dwarf_regnum_for_perf_regnum_arm(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_arm64(int perf_regnum); + +int __get_dwarf_regnum_for_perf_regnum_csky(int perf_regnum, unsigned int flags); +int __get_dwarf_regnum_for_perf_regnum_loongarch(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_powerpc(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_riscv(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_s390(int perf_regnum); +int __get_dwarf_regnum_for_perf_regnum_mips(int perf_regnum); /* * get_dwarf_regnum - Returns DWARF regnum from register name @@ -112,6 +122,12 @@ int get_arch_regnum(const char *name); */ int get_dwarf_regnum(const char *name, unsigned int machine, unsigned int flags); +/* + * get_dwarf_regnum - Returns DWARF regnum from perf register number. + */ +int get_dwarf_regnum_for_perf_regnum(int perf_regnum, unsigned int machine, unsigned int flags, + bool only_libdw_supported); + void get_powerpc_regs(u32 raw_insn, int is_source, struct annotated_op_loc *op_loc); #else /* HAVE_LIBDW_SUPPORT */ diff --git a/tools/perf/util/jitdump.c b/tools/perf/util/jitdump.c index f00814e37de9..e0ce8b904729 100644 --- a/tools/perf/util/jitdump.c +++ b/tools/perf/util/jitdump.c @@ -90,7 +90,8 @@ jit_emit_elf(struct jit_buf_desc *jd, saved_errno = errno; nsinfo__mountns_exit(&nsc); if (fd == -1) { - pr_warning("cannot create jit ELF %s: %s\n", filename, strerror(saved_errno)); + errno = saved_errno; + pr_warning("cannot create jit ELF %s: %m\n", filename); return -1; } @@ -757,7 +758,7 @@ jit_inject(struct jit_buf_desc *jd, const char *path) static int jit_detect(const char *mmap_name, pid_t pid, struct nsinfo *nsi, bool *in_pidns) { - char *p; + const char *p; char *end = NULL; pid_t pid2; diff --git a/tools/perf/util/kvm-stat-arch/Build b/tools/perf/util/kvm-stat-arch/Build new file mode 100644 index 000000000000..d84e55656e7a --- /dev/null +++ b/tools/perf/util/kvm-stat-arch/Build @@ -0,0 +1,6 @@ +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-arm64.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-loongarch.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-powerpc.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-riscv.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-s390.o +perf-util-$(CONFIG_LIBTRACEEVENT) += kvm-stat-x86.o diff --git a/tools/perf/arch/arm64/util/arm64_exception_types.h b/tools/perf/util/kvm-stat-arch/arm64_exception_types.h similarity index 100% rename from tools/perf/arch/arm64/util/arm64_exception_types.h rename to tools/perf/util/kvm-stat-arch/arm64_exception_types.h diff --git a/tools/perf/arch/powerpc/util/book3s_hcalls.h b/tools/perf/util/kvm-stat-arch/book3s_hcalls.h similarity index 100% rename from tools/perf/arch/powerpc/util/book3s_hcalls.h rename to tools/perf/util/kvm-stat-arch/book3s_hcalls.h diff --git a/tools/perf/arch/powerpc/util/book3s_hv_exits.h b/tools/perf/util/kvm-stat-arch/book3s_hv_exits.h similarity index 100% rename from tools/perf/arch/powerpc/util/book3s_hv_exits.h rename to tools/perf/util/kvm-stat-arch/book3s_hv_exits.h diff --git a/tools/perf/arch/arm64/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c similarity index 62% rename from tools/perf/arch/arm64/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c index 6611aa21cba9..c640dcd8af7c 100644 --- a/tools/perf/arch/arm64/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-arm64.c @@ -1,21 +1,17 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include "../../../util/evsel.h" -#include "../../../util/kvm-stat.h" +#include "../debug.h" +#include "../evsel.h" +#include "../kvm-stat.h" #include "arm64_exception_types.h" -#include "debug.h" define_exit_reasons_table(arm64_exit_reasons, kvm_arm_exception_type); define_exit_reasons_table(arm64_trap_exit_reasons, kvm_arm_exception_class); -const char *kvm_trap_exit_reason = "esr_ec"; -const char *vcpu_id_str = "id"; -const char *kvm_exit_reason = "ret"; -const char *kvm_entry_trace = "kvm:kvm_entry"; -const char *kvm_exit_trace = "kvm:kvm_exit"; +static const char *kvm_trap_exit_reason = "esr_ec"; -const char *kvm_events_tp[] = { +static const char * const __kvm_events_tp[] = { "kvm:kvm_entry", "kvm:kvm_exit", NULL, @@ -26,7 +22,7 @@ static void event_get_key(struct evsel *evsel, struct event_key *key) { key->info = 0; - key->key = evsel__intval(evsel, sample, kvm_exit_reason); + key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_AARCH64)); key->exit_reasons = arm64_exit_reasons; /* @@ -44,28 +40,28 @@ static bool event_begin(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { - return evsel__name_is(evsel, kvm_entry_trace); + return evsel__name_is(evsel, kvm_entry_trace(EM_AARCH64)); } static bool event_end(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { - if (evsel__name_is(evsel, kvm_exit_trace)) { + if (evsel__name_is(evsel, kvm_exit_trace(EM_AARCH64))) { event_get_key(evsel, sample, key); return true; } return false; } -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = event_begin, .is_end_event = event_end, .decode_key = exit_event_decode_key, .name = "VM-EXIT" }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events, @@ -73,12 +69,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = { { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { NULL, }; -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) +int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa = "arm64"; return 0; } + +const char * const *__kvm_events_tp_arm64(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_arm64(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_arm64(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/loongarch/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c similarity index 77% rename from tools/perf/arch/loongarch/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c index a7859a3a9a51..b802e516b138 100644 --- a/tools/perf/arch/loongarch/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-loongarch.c @@ -1,12 +1,13 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include "util/kvm-stat.h" -#include "util/parse-events.h" -#include "util/debug.h" -#include "util/evsel.h" -#include "util/evlist.h" -#include "util/pmus.h" +#include +#include "../kvm-stat.h" +#include "../parse-events.h" +#include "../debug.h" +#include "../evsel.h" +#include "../evlist.h" +#include "../pmus.h" #define LOONGARCH_EXCEPTION_INT 0 #define LOONGARCH_EXCEPTION_PIL 1 @@ -43,12 +44,8 @@ define_exit_reasons_table(loongarch_exit_reasons, loongarch_exception_type); -const char *vcpu_id_str = "vcpu_id"; -const char *kvm_exit_reason = "reason"; -const char *kvm_entry_trace = "kvm:kvm_enter"; -const char *kvm_reenter_trace = "kvm:kvm_reenter"; -const char *kvm_exit_trace = "kvm:kvm_exit"; -const char *kvm_events_tp[] = { +static const char *kvm_reenter_trace = "kvm:kvm_reenter"; +static const char * const __kvm_events_tp[] = { "kvm:kvm_enter", "kvm:kvm_reenter", "kvm:kvm_exit", @@ -74,7 +71,8 @@ static bool event_end(struct evsel *evsel, * kvm:kvm_enter means returning to vmm and then to guest * kvm:kvm_reenter means returning to guest immediately */ - return evsel__name_is(evsel, kvm_entry_trace) || evsel__name_is(evsel, kvm_reenter_trace); + return evsel__name_is(evsel, kvm_entry_trace(EM_LOONGARCH)) || + evsel__name_is(evsel, kvm_reenter_trace); } static void event_gspr_get_key(struct evsel *evsel, @@ -109,12 +107,12 @@ static void event_gspr_get_key(struct evsel *evsel, } } -static struct child_event_ops child_events[] = { +static const struct child_event_ops child_events[] = { { .name = "kvm:kvm_exit_gspr", .get_key = event_gspr_get_key }, { NULL, NULL }, }; -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = event_begin, .is_end_event = event_end, .child_ops = child_events, @@ -122,18 +120,33 @@ static struct kvm_events_ops exit_events = { .name = "VM-EXIT" }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events, }, { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { NULL, }; -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) +int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa = "loongarch64"; kvm->exit_reasons = loongarch_exit_reasons; return 0; } + +const char * const *__kvm_events_tp_loongarch(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_loongarch(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_loongarch(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c similarity index 78% rename from tools/perf/arch/powerpc/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c index c8357b571ccf..42182d70beb6 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-powerpc.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include "util/kvm-stat.h" -#include "util/parse-events.h" -#include "util/debug.h" -#include "util/evsel.h" -#include "util/evlist.h" -#include "util/pmus.h" +#include "../kvm-stat.h" +#include "../parse-events.h" +#include "../debug.h" +#include "../evsel.h" +#include "../evlist.h" +#include "../pmus.h" #include "book3s_hv_exits.h" #include "book3s_hcalls.h" @@ -13,15 +13,11 @@ #define NR_TPS 4 -const char *vcpu_id_str = "vcpu_id"; -const char *kvm_entry_trace = "kvm_hv:kvm_guest_enter"; -const char *kvm_exit_trace = "kvm_hv:kvm_guest_exit"; - define_exit_reasons_table(hv_exit_reasons, kvm_trace_symbol_exit); define_exit_reasons_table(hcall_reasons, kvm_trace_symbol_hcall); /* Tracepoints specific to ppc_book3s_hv */ -const char *ppc_book3s_hv_kvm_tp[] = { +static const char * const ppc_book3s_hv_kvm_tp[] = { "kvm_hv:kvm_guest_enter", "kvm_hv:kvm_guest_exit", "kvm_hv:kvm_hcall_enter", @@ -30,8 +26,7 @@ const char *ppc_book3s_hv_kvm_tp[] = { }; /* 1 extra placeholder for NULL */ -const char *kvm_events_tp[NR_TPS + 1]; -const char *kvm_exit_reason; +static const char *__kvm_events_tp[NR_TPS + 1]; static void hcall_event_get_key(struct evsel *evsel, struct perf_sample *sample, @@ -60,13 +55,13 @@ static bool hcall_event_end(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { - return (evsel__name_is(evsel, kvm_events_tp[3])); + return evsel__name_is(evsel, __kvm_events_tp[3]); } static bool hcall_event_begin(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { - if (evsel__name_is(evsel, kvm_events_tp[2])) { + if (evsel__name_is(evsel, __kvm_events_tp[2])) { hcall_event_get_key(evsel, sample, key); return true; } @@ -82,27 +77,27 @@ static void hcall_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", hcall_reason); } -static struct kvm_events_ops hcall_events = { +static const struct kvm_events_ops hcall_events = { .is_begin_event = hcall_event_begin, .is_end_event = hcall_event_end, .decode_key = hcall_event_decode_key, .name = "HCALL-EVENT", }; -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = exit_event_begin, .is_end_event = exit_event_end, .decode_key = exit_event_decode_key, .name = "VM-EXIT" }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events }, { .name = "hcall", .ops = &hcall_events }, { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { NULL, }; @@ -123,7 +118,7 @@ static int is_tracepoint_available(const char *str, struct evlist *evlist) static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, struct evlist *evlist) { - const char **events_ptr; + const char * const *events_ptr; int i, nr_tp = 0, err = -1; /* Check for book3s_hv tracepoints */ @@ -135,10 +130,9 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm, } for (i = 0; i < nr_tp; i++) - kvm_events_tp[i] = ppc_book3s_hv_kvm_tp[i]; + __kvm_events_tp[i] = ppc_book3s_hv_kvm_tp[i]; - kvm_events_tp[i] = NULL; - kvm_exit_reason = "trap"; + __kvm_events_tp[i] = NULL; kvm->exit_reasons = hv_exit_reasons; kvm->exit_reasons_isa = "HV"; @@ -157,12 +151,12 @@ static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm) return ppc__setup_book3s_hv(kvm, evlist); } -int setup_kvm_events_tp(struct perf_kvm_stat *kvm) +int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm) { return ppc__setup_kvm_tp(kvm); } -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) +int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm) { int ret; @@ -184,7 +178,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) * * Function to parse the arguments and return appropriate values. */ -int kvm_add_default_arch_event(int *argc, const char **argv) +int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv) { const char **tmp; bool event = false; @@ -217,3 +211,18 @@ int kvm_add_default_arch_event(int *argc, const char **argv) free(tmp); return 0; } + +const char * const *__kvm_events_tp_powerpc(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_powerpc(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_powerpc(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/riscv/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c similarity index 57% rename from tools/perf/arch/riscv/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c index 3ea7acb5e159..8d4d5d6ce720 100644 --- a/tools/perf/arch/riscv/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-riscv.c @@ -7,19 +7,14 @@ */ #include #include -#include "../../../util/evsel.h" -#include "../../../util/kvm-stat.h" +#include "../evsel.h" +#include "../kvm-stat.h" #include "riscv_trap_types.h" #include "debug.h" define_exit_reasons_table(riscv_exit_reasons, kvm_riscv_trap_class); -const char *vcpu_id_str = "id"; -const char *kvm_exit_reason = "scause"; -const char *kvm_entry_trace = "kvm:kvm_entry"; -const char *kvm_exit_trace = "kvm:kvm_exit"; - -const char *kvm_events_tp[] = { +static const char * const __kvm_events_tp[] = { "kvm:kvm_entry", "kvm:kvm_exit", NULL, @@ -29,8 +24,10 @@ static void event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { + int xlen = 64; // TODO: 32-bit support. + key->info = 0; - key->key = evsel__intval(evsel, sample, kvm_exit_reason) & ~CAUSE_IRQ_FLAG; + key->key = evsel__intval(evsel, sample, kvm_exit_reason(EM_RISCV)) & ~CAUSE_IRQ_FLAG(xlen); key->exit_reasons = riscv_exit_reasons; } @@ -38,28 +35,28 @@ static bool event_begin(struct evsel *evsel, struct perf_sample *sample __maybe_unused, struct event_key *key __maybe_unused) { - return evsel__name_is(evsel, kvm_entry_trace); + return evsel__name_is(evsel, kvm_entry_trace(EM_RISCV)); } static bool event_end(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { - if (evsel__name_is(evsel, kvm_exit_trace)) { + if (evsel__name_is(evsel, kvm_exit_trace(EM_RISCV))) { event_get_key(evsel, sample, key); return true; } return false; } -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = event_begin, .is_end_event = event_end, .decode_key = exit_event_decode_key, .name = "VM-EXIT" }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events, @@ -67,12 +64,27 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = { { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { NULL, }; -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid __maybe_unused) +int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm) { kvm->exit_reasons_isa = "riscv64"; return 0; } + +const char * const *__kvm_events_tp_riscv(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_riscv(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/s390/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-s390.c similarity index 77% rename from tools/perf/arch/s390/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-s390.c index 0aed92df51ba..7e29169f5bb0 100644 --- a/tools/perf/arch/s390/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-s390.c @@ -8,9 +8,9 @@ #include #include -#include "../../util/kvm-stat.h" -#include "../../util/evsel.h" -#include +#include "../kvm-stat.h" +#include "../evsel.h" +#include "../../../arch/s390/include/uapi/asm/sie.h" define_exit_reasons_table(sie_exit_reasons, sie_intercept_code); define_exit_reasons_table(sie_icpt_insn_codes, icpt_insn_codes); @@ -18,16 +18,11 @@ define_exit_reasons_table(sie_sigp_order_codes, sigp_order_codes); define_exit_reasons_table(sie_diagnose_codes, diagnose_codes); define_exit_reasons_table(sie_icpt_prog_codes, icpt_prog_codes); -const char *vcpu_id_str = "id"; -const char *kvm_exit_reason = "icptcode"; -const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter"; -const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit"; - static void event_icpt_insn_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { - unsigned long insn; + u64 insn; insn = evsel__intval(evsel, sample, "instruction"); key->key = icpt_insn_decoder(insn); @@ -58,7 +53,7 @@ static void event_icpt_prog_get_key(struct evsel *evsel, key->exit_reasons = sie_icpt_prog_codes; } -static struct child_event_ops child_events[] = { +static const struct child_event_ops child_events[] = { { .name = "kvm:kvm_s390_intercept_instruction", .get_key = event_icpt_insn_get_key }, { .name = "kvm:kvm_s390_handle_sigp", @@ -70,7 +65,7 @@ static struct child_event_ops child_events[] = { { NULL, NULL }, }; -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = exit_event_begin, .is_end_event = exit_event_end, .child_ops = child_events, @@ -78,7 +73,7 @@ static struct kvm_events_ops exit_events = { .name = "VM-EXIT" }; -const char *kvm_events_tp[] = { +static const char * const __kvm_events_tp[] = { "kvm:kvm_s390_sie_enter", "kvm:kvm_s390_sie_exit", "kvm:kvm_s390_intercept_instruction", @@ -88,17 +83,17 @@ const char *kvm_events_tp[] = { NULL, }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events }, { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { "Wait state", NULL, }; -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) +int __cpu_isa_init_s390(struct perf_kvm_stat *kvm, const char *cpuid) { if (strstr(cpuid, "IBM")) { kvm->exit_reasons = sie_exit_reasons; @@ -108,3 +103,18 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) return 0; } + +const char * const *__kvm_events_tp_s390(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_s390(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_s390(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/x86/util/kvm-stat.c b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c similarity index 86% rename from tools/perf/arch/x86/util/kvm-stat.c rename to tools/perf/util/kvm-stat-arch/kvm-stat-x86.c index bff36f9345ea..43275d25b6cb 100644 --- a/tools/perf/arch/x86/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat-arch/kvm-stat-x86.c @@ -1,29 +1,24 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include "../../../util/kvm-stat.h" -#include "../../../util/evsel.h" -#include "../../../util/env.h" -#include -#include -#include +#include "../kvm-stat.h" +#include "../evsel.h" +#include "../env.h" +#include "../../arch/x86/include/uapi/asm/svm.h" +#include "../../arch/x86/include/uapi/asm/vmx.h" +#include "../../arch/x86/include/uapi/asm/kvm.h" #include define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS); define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS); -static struct kvm_events_ops exit_events = { +static const struct kvm_events_ops exit_events = { .is_begin_event = exit_event_begin, .is_end_event = exit_event_end, .decode_key = exit_event_decode_key, .name = "VM-EXIT" }; -const char *vcpu_id_str = "vcpu_id"; -const char *kvm_exit_reason = "exit_reason"; -const char *kvm_entry_trace = "kvm:kvm_entry"; -const char *kvm_exit_trace = "kvm:kvm_exit"; - /* * For the mmio events, we treat: * the time of MMIO write: kvm_mmio(KVM_TRACE_MMIO_WRITE...) -> kvm_entry @@ -83,7 +78,7 @@ static void mmio_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, key->info == KVM_TRACE_MMIO_WRITE ? "W" : "R"); } -static struct kvm_events_ops mmio_events = { +static const struct kvm_events_ops mmio_events = { .is_begin_event = mmio_event_begin, .is_end_event = mmio_event_end, .decode_key = mmio_event_decode_key, @@ -127,7 +122,7 @@ static void ioport_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, key->info ? "POUT" : "PIN"); } -static struct kvm_events_ops ioport_events = { +static const struct kvm_events_ops ioport_events = { .is_begin_event = ioport_event_begin, .is_end_event = ioport_event_end, .decode_key = ioport_event_decode_key, @@ -171,14 +166,14 @@ static void msr_event_decode_key(struct perf_kvm_stat *kvm __maybe_unused, key->info ? "W" : "R"); } -static struct kvm_events_ops msr_events = { +static const struct kvm_events_ops msr_events = { .is_begin_event = msr_event_begin, .is_end_event = msr_event_end, .decode_key = msr_event_decode_key, .name = "MSR Access" }; -const char *kvm_events_tp[] = { +static const char * const __kvm_events_tp[] = { "kvm:kvm_entry", "kvm:kvm_exit", "kvm:kvm_mmio", @@ -187,7 +182,7 @@ const char *kvm_events_tp[] = { NULL, }; -struct kvm_reg_events_ops kvm_reg_events_ops[] = { +static const struct kvm_reg_events_ops __kvm_reg_events_ops[] = { { .name = "vmexit", .ops = &exit_events }, { .name = "mmio", .ops = &mmio_events }, { .name = "ioport", .ops = &ioport_events }, @@ -195,12 +190,12 @@ struct kvm_reg_events_ops kvm_reg_events_ops[] = { { NULL, NULL }, }; -const char * const kvm_skip_events[] = { +static const char * const __kvm_skip_events[] = { "HLT", NULL, }; -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) +int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid) { if (strstr(cpuid, "Intel")) { kvm->exit_reasons = vmx_exit_reasons; @@ -226,7 +221,7 @@ int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid) * So, to avoid this issue explicitly use "cycles" instead of "cycles:P" event * by default to sample guest on Intel platforms. */ -int kvm_add_default_arch_event(int *argc, const char **argv) +int __kvm_add_default_arch_event_x86(int *argc, const char **argv) { const char **tmp; bool event = false; @@ -262,3 +257,18 @@ int kvm_add_default_arch_event(int *argc, const char **argv) free(tmp); return ret; } + +const char * const *__kvm_events_tp_x86(void) +{ + return __kvm_events_tp; +} + +const struct kvm_reg_events_ops *__kvm_reg_events_ops_x86(void) +{ + return __kvm_reg_events_ops; +} + +const char * const *__kvm_skip_events_x86(void) +{ + return __kvm_skip_events; +} diff --git a/tools/perf/arch/riscv/util/riscv_trap_types.h b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h similarity index 96% rename from tools/perf/arch/riscv/util/riscv_trap_types.h rename to tools/perf/util/kvm-stat-arch/riscv_trap_types.h index 6cc71eb01fca..aa5d24fab4ee 100644 --- a/tools/perf/arch/riscv/util/riscv_trap_types.h +++ b/tools/perf/util/kvm-stat-arch/riscv_trap_types.h @@ -3,7 +3,7 @@ #define ARCH_PERF_RISCV_TRAP_TYPES_H /* Exception cause high bit - is an interrupt if set */ -#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) +#define CAUSE_IRQ_FLAG(xlen) (_AC(1, UL) << (xlen - 1)) /* Interrupt causes (minus the high bit) */ #define IRQ_S_SOFT 1 diff --git a/tools/perf/util/kvm-stat.c b/tools/perf/util/kvm-stat.c index 38ace736db5c..27f16810498c 100644 --- a/tools/perf/util/kvm-stat.c +++ b/tools/perf/util/kvm-stat.c @@ -2,20 +2,23 @@ #include "debug.h" #include "evsel.h" #include "kvm-stat.h" - -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#include bool kvm_exit_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_exit_trace); + uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL); + + return evsel__name_is(evsel, kvm_exit_trace(e_machine)); } void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, struct event_key *key) { + uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL); + key->info = 0; - key->key = evsel__intval(evsel, sample, kvm_exit_reason); + key->key = evsel__intval(evsel, sample, kvm_exit_reason(e_machine)); } @@ -32,7 +35,9 @@ bool exit_event_begin(struct evsel *evsel, bool kvm_entry_event(struct evsel *evsel) { - return evsel__name_is(evsel, kvm_entry_trace); + uint16_t e_machine = evsel__e_machine(evsel, /*e_flags=*/NULL); + + return evsel__name_is(evsel, kvm_entry_trace(e_machine)); } bool exit_event_end(struct evsel *evsel, @@ -67,4 +72,202 @@ void exit_event_decode_key(struct perf_kvm_stat *kvm, scnprintf(decode, KVM_EVENT_NAME_LEN, "%s", exit_reason); } -#endif +int setup_kvm_events_tp(struct perf_kvm_stat *kvm, uint16_t e_machine) +{ + switch (e_machine) { + case EM_PPC: + case EM_PPC64: + return __setup_kvm_events_tp_powerpc(kvm); + default: + return 0; + } +} + +int cpu_isa_init(struct perf_kvm_stat *kvm, uint16_t e_machine, const char *cpuid) +{ + switch (e_machine) { + case EM_AARCH64: + return __cpu_isa_init_arm64(kvm); + case EM_LOONGARCH: + return __cpu_isa_init_loongarch(kvm); + case EM_PPC: + case EM_PPC64: + return __cpu_isa_init_powerpc(kvm); + case EM_RISCV: + return __cpu_isa_init_riscv(kvm); + case EM_S390: + return __cpu_isa_init_s390(kvm, cpuid); + case EM_X86_64: + case EM_386: + return __cpu_isa_init_x86(kvm, cpuid); + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return -1; + } +} + +const char *vcpu_id_str(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + case EM_RISCV: + case EM_S390: + return "id"; + case EM_LOONGARCH: + case EM_PPC: + case EM_PPC64: + case EM_X86_64: + case EM_386: + return "vcpu_id"; + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const char *kvm_exit_reason(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + return "ret"; + case EM_LOONGARCH: + return "reason"; + case EM_PPC: + case EM_PPC64: + return "trap"; + case EM_RISCV: + return "scause"; + case EM_S390: + return "icptcode"; + case EM_X86_64: + case EM_386: + return "exit_reason"; + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const char *kvm_entry_trace(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + case EM_RISCV: + case EM_X86_64: + case EM_386: + return "kvm:kvm_entry"; + case EM_LOONGARCH: + return "kvm:kvm_enter"; + case EM_PPC: + case EM_PPC64: + return "kvm_hv:kvm_guest_enter"; + case EM_S390: + return "kvm:kvm_s390_sie_enter"; + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const char *kvm_exit_trace(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + case EM_LOONGARCH: + case EM_RISCV: + case EM_X86_64: + case EM_386: + return "kvm:kvm_exit"; + case EM_PPC: + case EM_PPC64: + return "kvm_hv:kvm_guest_exit"; + case EM_S390: + return "kvm:kvm_s390_sie_exit"; + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const char * const *kvm_events_tp(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + return __kvm_events_tp_arm64(); + case EM_LOONGARCH: + return __kvm_events_tp_loongarch(); + case EM_PPC: + case EM_PPC64: + return __kvm_events_tp_powerpc(); + case EM_RISCV: + return __kvm_events_tp_riscv(); + case EM_S390: + return __kvm_events_tp_s390(); + case EM_X86_64: + case EM_386: + return __kvm_events_tp_x86(); + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const struct kvm_reg_events_ops *kvm_reg_events_ops(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + return __kvm_reg_events_ops_arm64(); + case EM_LOONGARCH: + return __kvm_reg_events_ops_loongarch(); + case EM_PPC: + case EM_PPC64: + return __kvm_reg_events_ops_powerpc(); + case EM_RISCV: + return __kvm_reg_events_ops_riscv(); + case EM_S390: + return __kvm_reg_events_ops_s390(); + case EM_X86_64: + case EM_386: + return __kvm_reg_events_ops_x86(); + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +const char * const *kvm_skip_events(uint16_t e_machine) +{ + switch (e_machine) { + case EM_AARCH64: + return __kvm_skip_events_arm64(); + case EM_LOONGARCH: + return __kvm_skip_events_loongarch(); + case EM_PPC: + case EM_PPC64: + return __kvm_skip_events_powerpc(); + case EM_RISCV: + return __kvm_skip_events_riscv(); + case EM_S390: + return __kvm_skip_events_s390(); + case EM_X86_64: + case EM_386: + return __kvm_skip_events_x86(); + default: + pr_err("Unsupported kvm-stat host %d\n", e_machine); + return NULL; + } +} + +int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv) +{ + switch (e_machine) { + case EM_PPC: + case EM_PPC64: + return __kvm_add_default_arch_event_powerpc(argc, argv); + case EM_X86_64: + case EM_386: + return __kvm_add_default_arch_event_x86(argc, argv); + default: + return 0; + } +} diff --git a/tools/perf/util/kvm-stat.h b/tools/perf/util/kvm-stat.h index a356b839c2ee..4a998aaece5d 100644 --- a/tools/perf/util/kvm-stat.h +++ b/tools/perf/util/kvm-stat.h @@ -2,8 +2,6 @@ #ifndef __PERF_KVM_STAT_H #define __PERF_KVM_STAT_H -#ifdef HAVE_KVM_STAT_SUPPORT - #include "tool.h" #include "sort.h" #include "stat.h" @@ -67,7 +65,7 @@ struct kvm_events_ops { struct event_key *key); bool (*is_end_event)(struct evsel *evsel, struct perf_sample *sample, struct event_key *key); - struct child_event_ops *child_ops; + const struct child_event_ops *child_ops; void (*decode_key)(struct perf_kvm_stat *kvm, struct event_key *key, char *decode); const char *name; @@ -95,7 +93,7 @@ struct perf_kvm_stat { struct exit_reasons_table *exit_reasons; const char *exit_reasons_isa; - struct kvm_events_ops *events_ops; + const struct kvm_events_ops *events_ops; u64 total_time; u64 total_count; @@ -113,10 +111,10 @@ struct perf_kvm_stat { struct kvm_reg_events_ops { const char *name; - struct kvm_events_ops *ops; + const struct kvm_events_ops *ops; }; -#if defined(HAVE_KVM_STAT_SUPPORT) && defined(HAVE_LIBTRACEEVENT) +#ifdef HAVE_LIBTRACEEVENT void exit_event_get_key(struct evsel *evsel, struct perf_sample *sample, @@ -130,11 +128,9 @@ bool exit_event_end(struct evsel *evsel, void exit_event_decode_key(struct perf_kvm_stat *kvm, struct event_key *key, char *decode); -#endif bool kvm_exit_event(struct evsel *evsel); bool kvm_entry_event(struct evsel *evsel); -int setup_kvm_events_tp(struct perf_kvm_stat *kvm); #define define_exit_reasons_table(name, symbols) \ static struct exit_reasons_table name[] = { \ @@ -144,15 +140,60 @@ int setup_kvm_events_tp(struct perf_kvm_stat *kvm); /* * arch specific callbacks and data structures */ -int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid); +int setup_kvm_events_tp(struct perf_kvm_stat *kvm, uint16_t e_machine); +int __setup_kvm_events_tp_powerpc(struct perf_kvm_stat *kvm); -extern const char *kvm_events_tp[]; -extern struct kvm_reg_events_ops kvm_reg_events_ops[]; -extern const char * const kvm_skip_events[]; -extern const char *vcpu_id_str; -extern const char *kvm_exit_reason; -extern const char *kvm_entry_trace; -extern const char *kvm_exit_trace; +int cpu_isa_init(struct perf_kvm_stat *kvm, uint16_t e_machine, const char *cpuid); +int __cpu_isa_init_arm64(struct perf_kvm_stat *kvm); +int __cpu_isa_init_loongarch(struct perf_kvm_stat *kvm); +int __cpu_isa_init_powerpc(struct perf_kvm_stat *kvm); +int __cpu_isa_init_riscv(struct perf_kvm_stat *kvm); +int __cpu_isa_init_s390(struct perf_kvm_stat *kvm, const char *cpuid); +int __cpu_isa_init_x86(struct perf_kvm_stat *kvm, const char *cpuid); + +const char *vcpu_id_str(uint16_t e_machine); +const char *kvm_exit_reason(uint16_t e_machine); +const char *kvm_entry_trace(uint16_t e_machine); +const char *kvm_exit_trace(uint16_t e_machine); + +const char * const *kvm_events_tp(uint16_t e_machine); +const char * const *__kvm_events_tp_arm64(void); +const char * const *__kvm_events_tp_loongarch(void); +const char * const *__kvm_events_tp_powerpc(void); +const char * const *__kvm_events_tp_riscv(void); +const char * const *__kvm_events_tp_s390(void); +const char * const *__kvm_events_tp_x86(void); + +const struct kvm_reg_events_ops *kvm_reg_events_ops(uint16_t e_machine); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_arm64(void); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_loongarch(void); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_powerpc(void); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_riscv(void); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_s390(void); +const struct kvm_reg_events_ops *__kvm_reg_events_ops_x86(void); + +const char * const *kvm_skip_events(uint16_t e_machine); +const char * const *__kvm_skip_events_arm64(void); +const char * const *__kvm_skip_events_loongarch(void); +const char * const *__kvm_skip_events_powerpc(void); +const char * const *__kvm_skip_events_riscv(void); +const char * const *__kvm_skip_events_s390(void); +const char * const *__kvm_skip_events_x86(void); + +int kvm_add_default_arch_event(uint16_t e_machine, int *argc, const char **argv); +int __kvm_add_default_arch_event_powerpc(int *argc, const char **argv); +int __kvm_add_default_arch_event_x86(int *argc, const char **argv); + +#else /* !HAVE_LIBTRACEEVENT */ + +static inline int kvm_add_default_arch_event(uint16_t e_machine __maybe_unused, + int *argc __maybe_unused, + const char **argv __maybe_unused) +{ + return 0; +} + +#endif /* HAVE_LIBTRACEEVENT */ static inline struct kvm_info *kvm_info__get(struct kvm_info *ki) { @@ -186,11 +227,6 @@ static inline struct kvm_info *kvm_info__new(void) return ki; } -#else /* HAVE_KVM_STAT_SUPPORT */ -// We use this unconditionally in hists__findnew_entry() and hist_entry__delete() -#define kvm_info__zput(ki) do { } while (0) -#endif /* HAVE_KVM_STAT_SUPPORT */ - #define STRDUP_FAIL_EXIT(s) \ ({ char *_p; \ _p = strdup(s); \ @@ -201,5 +237,4 @@ static inline struct kvm_info *kvm_info__new(void) _p; \ }) -extern int kvm_add_default_arch_event(int *argc, const char **argv); #endif /* __PERF_KVM_STAT_H */ diff --git a/tools/perf/util/libbfd.c b/tools/perf/util/libbfd.c index 79f4528234a9..63ea3fb53e77 100644 --- a/tools/perf/util/libbfd.c +++ b/tools/perf/util/libbfd.c @@ -501,7 +501,7 @@ int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused, struct bpf_prog_info_node *info_node; int len = sym->end - sym->start; disassembler_ftype disassemble; - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct perf_bpil *info_linear; struct disassemble_info info; struct dso *dso = map__dso(map); @@ -612,7 +612,7 @@ int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused, args->line = strdup(srcline); args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl) { annotation_line__add(&dl->al, @@ -624,7 +624,7 @@ int symbol__disassemble_bpf_libbfd(struct symbol *sym __maybe_unused, args->line = buf + prev_buf_size; args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl) annotation_line__add(&dl->al, ¬es->src->source); diff --git a/tools/perf/util/libdw.c b/tools/perf/util/libdw.c new file mode 100644 index 000000000000..216977884103 --- /dev/null +++ b/tools/perf/util/libdw.c @@ -0,0 +1,172 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "dso.h" +#include "libdw.h" +#include "srcline.h" +#include "symbol.h" +#include "dwarf-aux.h" +#include +#include +#include + +static const Dwfl_Callbacks offline_callbacks = { + .find_debuginfo = dwfl_standard_find_debuginfo, + .section_address = dwfl_offline_section_address, + .find_elf = dwfl_build_id_find_elf, +}; + +void dso__free_libdw(struct dso *dso) +{ + Dwfl *dwfl = dso__libdw(dso); + + if (dwfl) { + dwfl_end(dwfl); + dso__set_libdw(dso, NULL); + } +} + +struct Dwfl *dso__libdw_dwfl(struct dso *dso) +{ + Dwfl *dwfl = dso__libdw(dso); + const char *dso_name; + Dwfl_Module *mod; + int fd; + + if (dwfl) + return dwfl; + + dso_name = dso__long_name(dso); + /* + * Initialize Dwfl session. + * We need to open the DSO file to report it to libdw. + */ + fd = open(dso_name, O_RDONLY); + if (fd < 0) + return NULL; + + dwfl = dwfl_begin(&offline_callbacks); + if (!dwfl) { + close(fd); + return NULL; + } + + /* + * If the report is successful, the file descriptor fd is consumed + * and closed by the Dwfl. If not, it is not closed. + */ + mod = dwfl_report_offline(dwfl, dso_name, dso_name, fd); + if (!mod) { + dwfl_end(dwfl); + close(fd); + return NULL; + } + + dwfl_report_end(dwfl, /*removed=*/NULL, /*arg=*/NULL); + dso__set_libdw(dso, dwfl); + + return dwfl; +} + +struct libdw_a2l_cb_args { + struct dso *dso; + struct symbol *sym; + struct inline_node *node; + char *leaf_srcline; + bool leaf_srcline_used; +}; + +static int libdw_a2l_cb(Dwarf_Die *die, void *_args) +{ + struct libdw_a2l_cb_args *args = _args; + struct symbol *inline_sym = new_inline_sym(args->dso, args->sym, dwarf_diename(die)); + const char *call_fname = die_get_call_file(die); + char *call_srcline = srcline__unknown; + struct inline_list *ilist; + + if (!inline_sym) + return -ENOMEM; + + /* Assign caller information to the parent. */ + if (call_fname) + call_srcline = srcline_from_fileline(call_fname, die_get_call_lineno(die)); + + list_for_each_entry(ilist, &args->node->val, list) { + if (args->leaf_srcline == ilist->srcline) + args->leaf_srcline_used = false; + else if (ilist->srcline != srcline__unknown) + free(ilist->srcline); + ilist->srcline = call_srcline; + call_srcline = NULL; + break; + } + if (call_srcline && call_srcline != srcline__unknown) + free(call_srcline); + + /* Add this symbol to the chain as the leaf. */ + if (!args->leaf_srcline_used) { + inline_list__append_tail(inline_sym, args->leaf_srcline, args->node); + args->leaf_srcline_used = true; + } else { + inline_list__append_tail(inline_sym, strdup(args->leaf_srcline), args->node); + } + return 0; +} + +int libdw__addr2line(u64 addr, char **file, unsigned int *line_nr, + struct dso *dso, bool unwind_inlines, + struct inline_node *node, struct symbol *sym) +{ + Dwfl *dwfl = dso__libdw_dwfl(dso); + Dwfl_Module *mod; + Dwfl_Line *dwline; + Dwarf_Addr bias; + const char *src; + int lineno = 0; + + if (!dwfl) + return 0; + + mod = dwfl_addrmodule(dwfl, addr); + if (!mod) + return 0; + + /* + * Get/ignore the dwarf information. Determine the bias, difference + * between the regular ELF addr2line addresses and those to use with + * libdw. + */ + if (!dwfl_module_getdwarf(mod, &bias)) + return 0; + + /* Find source line information for the address. */ + dwline = dwfl_module_getsrc(mod, addr + bias); + if (!dwline) + return 0; + + /* Get line information. */ + src = dwfl_lineinfo(dwline, /*addr=*/NULL, &lineno, /*col=*/NULL, /*mtime=*/NULL, + /*length=*/NULL); + + if (file) + *file = src ? strdup(src) : NULL; + if (line_nr) + *line_nr = lineno; + + /* Optionally unwind inline function call chain. */ + if (unwind_inlines && node) { + Dwarf_Addr unused_bias; + Dwarf_Die *cudie = dwfl_module_addrdie(mod, addr + bias, &unused_bias); + struct libdw_a2l_cb_args args = { + .dso = dso, + .sym = sym, + .node = node, + .leaf_srcline = srcline_from_fileline(src ?: "", lineno), + }; + + /* Walk from the parent down to the leaf. */ + cu_walk_functions_at(cudie, addr, libdw_a2l_cb, &args); + + if (!args.leaf_srcline_used) + free(args.leaf_srcline); + } + return 1; +} diff --git a/tools/perf/util/libdw.h b/tools/perf/util/libdw.h new file mode 100644 index 000000000000..b12094737415 --- /dev/null +++ b/tools/perf/util/libdw.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef PERF_LIBDW_H +#define PERF_LIBDW_H + +#include + +struct dso; +struct inline_node; +struct symbol; + +#ifdef HAVE_LIBDW_SUPPORT +/* + * libdw__addr2line - Convert address to source location using libdw + * @addr: Address to resolve + * @file: Pointer to return filename (caller must free) + * @line_nr: Pointer to return line number + * @dso: The dso struct + * @unwind_inlines: Whether to unwind inline function calls + * @node: Inline node list to append to + * @sym: The symbol associated with the address + * + * This function initializes a Dwfl context for the DSO if not already present, + * finds the source line information for the given address, and optionally + * resolves inline function call chains. + * + * Returns 1 on success (found), 0 on failure (not found). + */ +int libdw__addr2line(u64 addr, char **file, + unsigned int *line_nr, struct dso *dso, + bool unwind_inlines, struct inline_node *node, + struct symbol *sym); + +/* + * dso__free_libdw - Free libdw resources associated with the DSO + * @dso: The dso to free resources for + * + * This function cleans up the Dwfl context used for addr2line lookups. + */ +void dso__free_libdw(struct dso *dso); + +#else /* HAVE_LIBDW_SUPPORT */ + +static inline int libdw__addr2line(u64 addr __maybe_unused, char **file __maybe_unused, + unsigned int *line_nr __maybe_unused, + struct dso *dso __maybe_unused, + bool unwind_inlines __maybe_unused, + struct inline_node *node __maybe_unused, + struct symbol *sym __maybe_unused) +{ + return 0; +} + +static inline void dso__free_libdw(struct dso *dso __maybe_unused) +{ +} +#endif /* HAVE_LIBDW_SUPPORT */ + +#endif /* PERF_LIBDW_H */ diff --git a/tools/perf/util/llvm.c b/tools/perf/util/llvm.c index 2ebf1f5f65bf..0d126d233c01 100644 --- a/tools/perf/util/llvm.c +++ b/tools/perf/util/llvm.c @@ -118,7 +118,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, { #ifdef HAVE_LIBLLVM_SUPPORT struct annotation *notes = symbol__annotation(sym); - struct map *map = args->ms.map; + struct map *map = args->ms->map; struct dso *dso = map__dso(map); u64 start = map__rip_2objdump(map, sym->start); /* Malloc-ed buffer containing instructions read from disk. */ @@ -146,7 +146,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, return errno; init_llvm(); - if (arch__is(args->arch, "x86")) { + if (arch__is_x86(args->arch)) { const char *triplet = is_64bit ? "x86_64-pc-linux" : "i686-pc-linux"; disasm = LLVMCreateDisasm(triplet, &storage, /*tag_type=*/0, @@ -184,7 +184,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, args->line = disasm_buf; args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; dl = disasm_line__new(args); if (dl == NULL) @@ -242,7 +242,7 @@ int symbol__disassemble_llvm(const char *filename, struct symbol *sym, &line_storage_len); args->line_nr = 0; args->fileloc = NULL; - args->ms.sym = sym; + args->ms->sym = sym; llvm_addr2line(filename, pc, &args->fileloc, (unsigned int *)&args->line_nr, false, NULL); diff --git a/tools/perf/util/lzma.c b/tools/perf/util/lzma.c index c355757ed391..91b9b5171d1f 100644 --- a/tools/perf/util/lzma.c +++ b/tools/perf/util/lzma.c @@ -59,7 +59,7 @@ int lzma_decompress_stream_to_file(FILE *infile, int output_fd) strm.avail_in = fread(buf_in, 1, sizeof(buf_in), infile); if (ferror(infile)) { - pr_debug("lzma: read error: %s\n", strerror(errno)); + pr_debug("lzma: read error: %m\n"); goto err_lzma_end; } @@ -73,7 +73,7 @@ int lzma_decompress_stream_to_file(FILE *infile, int output_fd) ssize_t write_size = sizeof(buf_out) - strm.avail_out; if (writen(output_fd, buf_out, write_size) != write_size) { - pr_debug("lzma: write error: %s\n", strerror(errno)); + pr_debug("lzma: write error: %m\n"); goto err_lzma_end; } @@ -103,7 +103,7 @@ int lzma_decompress_to_file(const char *input, int output_fd) infile = fopen(input, "rb"); if (!infile) { - pr_debug("lzma: fopen failed on %s: '%s'\n", input, strerror(errno)); + pr_debug("lzma: fopen failed on %s: '%m'\n", input); return -1; } diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 841b711d970e..e76f8c86e62a 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -2016,7 +2016,7 @@ static void ip__resolve_ams(struct thread *thread, ams->addr = ip; ams->al_addr = al.addr; ams->al_level = al.level; - ams->ms.maps = maps__get(al.maps); + ams->ms.thread = thread__get(al.thread); ams->ms.sym = al.sym; ams->ms.map = map__get(al.map); ams->phys_addr = 0; @@ -2037,7 +2037,7 @@ static void ip__resolve_data(struct thread *thread, ams->addr = addr; ams->al_addr = al.addr; ams->al_level = al.level; - ams->ms.maps = maps__get(al.maps); + ams->ms.thread = thread__get(al.thread); ams->ms.sym = al.sym; ams->ms.map = map__get(al.map); ams->phys_addr = phys_addr; @@ -2090,6 +2090,59 @@ struct iterations { u64 cycles; }; +static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip, + bool branch, struct branch_flags *flags, int nr_loop_iter, + u64 iter_cycles, u64 branch_from) +{ + struct symbol *sym = ms->sym; + struct map *map = ms->map; + struct inline_node *inline_node; + struct inline_list *ilist; + struct dso *dso; + u64 addr; + int ret = 1; + struct map_symbol ilist_ms; + bool first = true; + + if (!symbol_conf.inline_name || !map || !sym) + return ret; + + addr = map__dso_map_ip(map, ip); + addr = map__rip_2objdump(map, addr); + dso = map__dso(map); + + inline_node = inlines__tree_find(dso__inlined_nodes(dso), addr); + if (!inline_node) { + inline_node = dso__parse_addr_inlines(dso, addr, sym); + if (!inline_node) + return ret; + inlines__tree_insert(dso__inlined_nodes(dso), inline_node); + } + + ilist_ms = (struct map_symbol) { + .thread = thread__get(ms->thread), + .map = map__get(map), + }; + list_for_each_entry(ilist, &inline_node->val, list) { + ilist_ms.sym = ilist->symbol; + if (first) { + ret = callchain_cursor_append(cursor, ip, &ilist_ms, + branch, flags, nr_loop_iter, + iter_cycles, branch_from, ilist->srcline); + } else { + ret = callchain_cursor_append(cursor, ip, &ilist_ms, false, + NULL, 0, 0, 0, ilist->srcline); + } + first = false; + + if (ret != 0) + return ret; + } + map_symbol__exit(&ilist_ms); + + return ret; +} + static int add_callchain_ip(struct thread *thread, struct callchain_cursor *cursor, struct symbol **parent, @@ -2167,9 +2220,14 @@ static int add_callchain_ip(struct thread *thread, iter_cycles = iter->cycles; } - ms.maps = maps__get(al.maps); + ms.thread = thread__get(al.thread); ms.map = map__get(al.map); ms.sym = al.sym; + + if (append_inlines(cursor, &ms, ip, branch, flags, nr_loop_iter, + iter_cycles, branch_from) == 0) + goto out; + srcline = callchain_srcline(&ms, al.addr); err = callchain_cursor_append(cursor, ip, &ms, branch, flags, nr_loop_iter, @@ -2325,7 +2383,7 @@ static void save_lbr_cursor_node(struct thread *thread, map_symbol__exit(&lbr_stitch->prev_lbr_cursor[idx].ms); memcpy(&lbr_stitch->prev_lbr_cursor[idx], cursor->curr, sizeof(struct callchain_cursor_node)); - lbr_stitch->prev_lbr_cursor[idx].ms.maps = maps__get(cursor->curr->ms.maps); + lbr_stitch->prev_lbr_cursor[idx].ms.thread = thread__get(cursor->curr->ms.thread); lbr_stitch->prev_lbr_cursor[idx].ms.map = map__get(cursor->curr->ms.map); lbr_stitch->prev_lbr_cursor[idx].valid = true; @@ -2365,8 +2423,14 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread, } if (callee) { - /* Add LBR ip from first entries.to */ - ip = entries[0].to; + /* + * Set the (first) leaf function's IP to sample->ip (the + * location of the sample) but if not recorded use entries.to + */ + if (sample->ip) + ip = sample->ip; + else + ip = entries[0].to; flags = &entries[0].flags; *branch_from = entries[0].from; err = add_callchain_ip(thread, cursor, parent, @@ -2419,8 +2483,14 @@ static int lbr_callchain_add_lbr_ip(struct thread *thread, } if (lbr_nr > 0) { - /* Add LBR ip from first entries.to */ - ip = entries[0].to; + /* + * Set the (first) leaf function's IP to sample->ip (the + * location of the sample) but if not recorded use entries.to + */ + if (sample->ip) + ip = sample->ip; + else + ip = entries[0].to; flags = &entries[0].flags; *branch_from = entries[0].from; err = add_callchain_ip(thread, cursor, parent, @@ -2538,7 +2608,8 @@ static bool has_stitched_lbr(struct thread *thread, memcpy(&stitch_node->cursor, &lbr_stitch->prev_lbr_cursor[i], sizeof(struct callchain_cursor_node)); - stitch_node->cursor.ms.maps = maps__get(lbr_stitch->prev_lbr_cursor[i].ms.maps); + stitch_node->cursor.ms.thread = + thread__get(lbr_stitch->prev_lbr_cursor[i].ms.thread); stitch_node->cursor.ms.map = map__get(lbr_stitch->prev_lbr_cursor[i].ms.map); if (callee) @@ -2888,49 +2959,6 @@ static int thread__resolve_callchain_sample(struct thread *thread, return 0; } -static int append_inlines(struct callchain_cursor *cursor, struct map_symbol *ms, u64 ip) -{ - struct symbol *sym = ms->sym; - struct map *map = ms->map; - struct inline_node *inline_node; - struct inline_list *ilist; - struct dso *dso; - u64 addr; - int ret = 1; - struct map_symbol ilist_ms; - - if (!symbol_conf.inline_name || !map || !sym) - return ret; - - addr = map__dso_map_ip(map, ip); - addr = map__rip_2objdump(map, addr); - dso = map__dso(map); - - inline_node = inlines__tree_find(dso__inlined_nodes(dso), addr); - if (!inline_node) { - inline_node = dso__parse_addr_inlines(dso, addr, sym); - if (!inline_node) - return ret; - inlines__tree_insert(dso__inlined_nodes(dso), inline_node); - } - - ilist_ms = (struct map_symbol) { - .maps = maps__get(ms->maps), - .map = map__get(map), - }; - list_for_each_entry(ilist, &inline_node->val, list) { - ilist_ms.sym = ilist->symbol; - ret = callchain_cursor_append(cursor, ip, &ilist_ms, false, - NULL, 0, 0, 0, ilist->srcline); - - if (ret != 0) - return ret; - } - map_symbol__exit(&ilist_ms); - - return ret; -} - static int unwind_entry(struct unwind_entry *entry, void *arg) { struct callchain_cursor *cursor = arg; @@ -2940,7 +2968,8 @@ static int unwind_entry(struct unwind_entry *entry, void *arg) if (symbol_conf.hide_unresolved && entry->ms.sym == NULL) return 0; - if (append_inlines(cursor, &entry->ms, entry->ip) == 0) + if (append_inlines(cursor, &entry->ms, entry->ip, /*branch=*/false, /*branch_flags=*/NULL, + /*nr_loop_iter=*/0, /*iter_cycles=*/0, /*branch_from=*/0) == 0) return 0; /* diff --git a/tools/perf/util/map_symbol.c b/tools/perf/util/map_symbol.c index 6ad2960bc289..11bc0a7f704c 100644 --- a/tools/perf/util/map_symbol.c +++ b/tools/perf/util/map_symbol.c @@ -2,10 +2,11 @@ #include "map_symbol.h" #include "maps.h" #include "map.h" +#include "thread.h" void map_symbol__exit(struct map_symbol *ms) { - maps__zput(ms->maps); + thread__zput(ms->thread); map__zput(ms->map); } @@ -16,7 +17,7 @@ void addr_map_symbol__exit(struct addr_map_symbol *ams) void map_symbol__copy(struct map_symbol *dst, struct map_symbol *src) { - dst->maps = maps__get(src->maps); + dst->thread = thread__get(src->thread); dst->map = map__get(src->map); dst->sym = src->sym; } diff --git a/tools/perf/util/map_symbol.h b/tools/perf/util/map_symbol.h index e370bb32ed47..7437e319f4a3 100644 --- a/tools/perf/util/map_symbol.h +++ b/tools/perf/util/map_symbol.h @@ -4,12 +4,13 @@ #include +struct thread; struct maps; struct map; struct symbol; struct map_symbol { - struct maps *maps; + struct thread *thread; struct map *map; struct symbol *sym; }; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index c321d4f4d846..4092211cff62 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -10,6 +10,7 @@ #include "thread.h" #include "ui/ui.h" #include "unwind.h" +#include "unwind-libdw.h" #include /* @@ -39,6 +40,9 @@ DECLARE_RC_STRUCT(maps) { #ifdef HAVE_LIBUNWIND_SUPPORT void *addr_space; const struct unwind_libunwind_ops *unwind_libunwind_ops; +#endif +#ifdef HAVE_LIBDW_SUPPORT + void *libdw_addr_space_dwfl; #endif refcount_t refcnt; /** @@ -203,6 +207,17 @@ void maps__set_unwind_libunwind_ops(struct maps *maps, const struct unwind_libun RC_CHK_ACCESS(maps)->unwind_libunwind_ops = ops; } #endif +#ifdef HAVE_LIBDW_SUPPORT +void *maps__libdw_addr_space_dwfl(const struct maps *maps) +{ + return RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl; +} + +void maps__set_libdw_addr_space_dwfl(struct maps *maps, void *dwfl) +{ + RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl = dwfl; +} +#endif static struct rw_semaphore *maps__lock(struct maps *maps) { @@ -218,6 +233,9 @@ static void maps__init(struct maps *maps, struct machine *machine) #ifdef HAVE_LIBUNWIND_SUPPORT RC_CHK_ACCESS(maps)->addr_space = NULL; RC_CHK_ACCESS(maps)->unwind_libunwind_ops = NULL; +#endif +#ifdef HAVE_LIBDW_SUPPORT + RC_CHK_ACCESS(maps)->libdw_addr_space_dwfl = NULL; #endif refcount_set(maps__refcnt(maps), 1); RC_CHK_ACCESS(maps)->nr_maps = 0; @@ -240,6 +258,9 @@ static void maps__exit(struct maps *maps) zfree(&maps_by_address); zfree(&maps_by_name); unwind__finish_access(maps); +#ifdef HAVE_LIBDW_SUPPORT + libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps)); +#endif } struct maps *maps__new(struct machine *machine) @@ -549,6 +570,9 @@ void maps__remove(struct maps *maps, struct map *map) __maps__remove(maps, map); check_invariants(maps); up_write(maps__lock(maps)); +#ifdef HAVE_LIBDW_SUPPORT + libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps)); +#endif } bool maps__empty(struct maps *maps) @@ -604,18 +628,26 @@ int maps__for_each_map(struct maps *maps, int (*cb)(struct map *map, void *data) void maps__remove_maps(struct maps *maps, bool (*cb)(struct map *map, void *data), void *data) { struct map **maps_by_address; + bool removed = false; down_write(maps__lock(maps)); maps_by_address = maps__maps_by_address(maps); for (unsigned int i = 0; i < maps__nr_maps(maps);) { - if (cb(maps_by_address[i], data)) + if (cb(maps_by_address[i], data)) { __maps__remove(maps, maps_by_address[i]); - else + removed = true; + } else { i++; + } } check_invariants(maps); up_write(maps__lock(maps)); + if (removed) { +#ifdef HAVE_LIBDW_SUPPORT + libdw__invalidate_dwfl(maps, maps__libdw_addr_space_dwfl(maps)); +#endif + } } struct symbol *maps__find_symbol(struct maps *maps, u64 addr, struct map **mapp) @@ -676,6 +708,7 @@ int maps__find_ams(struct maps *maps, struct addr_map_symbol *ams) if (ams->addr < map__start(ams->ms.map) || ams->addr >= map__end(ams->ms.map)) { if (maps == NULL) return -1; + map__put(ams->ms.map); ams->ms.map = maps__find(maps, ams->addr); if (ams->ms.map == NULL) return -1; diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h index d9aa62ed968a..20c52084ba9e 100644 --- a/tools/perf/util/maps.h +++ b/tools/perf/util/maps.h @@ -52,6 +52,10 @@ void maps__set_addr_space(struct maps *maps, void *addr_space); const struct unwind_libunwind_ops *maps__unwind_libunwind_ops(const struct maps *maps); void maps__set_unwind_libunwind_ops(struct maps *maps, const struct unwind_libunwind_ops *ops); #endif +#ifdef HAVE_LIBDW_SUPPORT +void *maps__libdw_addr_space_dwfl(const struct maps *maps); +void maps__set_libdw_addr_space_dwfl(struct maps *maps, void *dwfl); +#endif size_t maps__fprintf(struct maps *maps, FILE *fp); diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 25c75fdbfc52..46bf4dfeebc8 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -367,7 +367,7 @@ static int setup_metric_events(const char *pmu, struct hashmap *ids, static bool match_metric_or_groups(const char *metric_or_groups, const char *sought) { int len; - char *m; + const char *m; if (!sought) return false; @@ -450,11 +450,10 @@ static const char *code_characters = ",-=@"; static int encode_metric_id(struct strbuf *sb, const char *x) { - char *c; int ret = 0; for (; *x; x++) { - c = strchr(code_characters, *x); + const char *c = strchr(code_characters, *x); if (c) { ret = strbuf_addch(sb, '!'); if (ret) @@ -1563,8 +1562,6 @@ int metricgroup__parse_groups(struct evlist *perf_evlist, { const struct pmu_metrics_table *table = pmu_metrics_table__find(); - if (!table) - return -EINVAL; if (hardware_aware_grouping) pr_debug("Use hardware aware grouping instead of traditional metric grouping method\n"); @@ -1602,22 +1599,16 @@ static int metricgroup__has_metric_or_groups_callback(const struct pmu_metric *p bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups) { - const struct pmu_metrics_table *tables[2] = { - pmu_metrics_table__find(), - pmu_metrics_table__default(), - }; + const struct pmu_metrics_table *table = pmu_metrics_table__find(); struct metricgroup__has_metric_data data = { .pmu = pmu, .metric_or_groups = metric_or_groups, }; - for (size_t i = 0; i < ARRAY_SIZE(tables); i++) { - if (pmu_metrics_table__for_each_metric(tables[i], - metricgroup__has_metric_or_groups_callback, - &data)) - return true; - } - return false; + return pmu_metrics_table__for_each_metric(table, + metricgroup__has_metric_or_groups_callback, + &data) + ? true : false; } static int metricgroup__topdown_max_level_callback(const struct pmu_metric *pm, diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 000c89a1e50d..b9efb296bba5 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -30,7 +30,6 @@ #include "util/event.h" #include "util/bpf-filter.h" #include "util/stat.h" -#include "util/tool_pmu.h" #include "util/util.h" #include "tracepoint.h" #include @@ -230,12 +229,8 @@ __add_event(struct list_head *list, int *idx, if (pmu) { is_pmu_core = pmu->is_core; pmu_cpus = perf_cpu_map__get(pmu->cpus); - if (perf_cpu_map__is_empty(pmu_cpus)) { - if (perf_pmu__is_tool(pmu)) - pmu_cpus = tool_pmu__cpus(attr); - else - pmu_cpus = cpu_map__online(); - } + if (perf_cpu_map__is_empty(pmu_cpus)) + pmu_cpus = cpu_map__online(); } else { is_pmu_core = (attr->type == PERF_TYPE_HARDWARE || attr->type == PERF_TYPE_HW_CACHE); @@ -274,6 +269,7 @@ __add_event(struct list_head *list, int *idx, evsel->core.pmu_cpus = pmu_cpus; evsel->core.requires_cpu = pmu ? pmu->is_uncore : false; evsel->core.is_pmu_core = is_pmu_core; + evsel->core.reads_only_on_cpu_idx0 = perf_pmu__reads_only_on_cpu_idx0(attr); evsel->pmu = pmu; evsel->alternate_hw_config = alternate_hw_config; evsel->first_wildcard_match = first_wildcard_match; @@ -1119,105 +1115,107 @@ static int config_attr(struct perf_event_attr *attr, return 0; } +static struct evsel_config_term *add_config_term(enum evsel_term_type type, + struct list_head *head_terms, + bool weak) +{ + struct evsel_config_term *t; + + t = zalloc(sizeof(*t)); + if (!t) + return NULL; + + INIT_LIST_HEAD(&t->list); + t->type = type; + t->weak = weak; + list_add_tail(&t->list, head_terms); + + return t; +} + static int get_config_terms(const struct parse_events_terms *head_config, struct list_head *head_terms) { -#define ADD_CONFIG_TERM(__type, __weak) \ - struct evsel_config_term *__t; \ - \ - __t = zalloc(sizeof(*__t)); \ - if (!__t) \ - return -ENOMEM; \ - \ - INIT_LIST_HEAD(&__t->list); \ - __t->type = EVSEL__CONFIG_TERM_ ## __type; \ - __t->weak = __weak; \ - list_add_tail(&__t->list, head_terms) - -#define ADD_CONFIG_TERM_VAL(__type, __name, __val, __weak) \ -do { \ - ADD_CONFIG_TERM(__type, __weak); \ - __t->val.__name = __val; \ -} while (0) - -#define ADD_CONFIG_TERM_STR(__type, __val, __weak) \ -do { \ - ADD_CONFIG_TERM(__type, __weak); \ - __t->val.str = strdup(__val); \ - if (!__t->val.str) { \ - zfree(&__t); \ - return -ENOMEM; \ - } \ - __t->free_str = true; \ -} while (0) - struct parse_events_term *term; list_for_each_entry(term, &head_config->terms, list) { + struct evsel_config_term *new_term; + enum evsel_term_type new_type; + bool str_type = false; + u64 val; + switch (term->type_term) { case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: - ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_PERIOD; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: - ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_FREQ; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_TIME: - ADD_CONFIG_TERM_VAL(TIME, time, term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_TIME; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: - ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str, term->weak); + new_type = EVSEL__CONFIG_TERM_CALLGRAPH; + str_type = true; break; case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: - ADD_CONFIG_TERM_STR(BRANCH, term->val.str, term->weak); + new_type = EVSEL__CONFIG_TERM_BRANCH; + str_type = true; break; case PARSE_EVENTS__TERM_TYPE_STACKSIZE: - ADD_CONFIG_TERM_VAL(STACK_USER, stack_user, - term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_STACK_USER; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_INHERIT: - ADD_CONFIG_TERM_VAL(INHERIT, inherit, - term->val.num ? 1 : 0, term->weak); + new_type = EVSEL__CONFIG_TERM_INHERIT; + val = term->val.num ? 1 : 0; break; case PARSE_EVENTS__TERM_TYPE_NOINHERIT: - ADD_CONFIG_TERM_VAL(INHERIT, inherit, - term->val.num ? 0 : 1, term->weak); + new_type = EVSEL__CONFIG_TERM_INHERIT; + val = term->val.num ? 0 : 1; break; case PARSE_EVENTS__TERM_TYPE_MAX_STACK: - ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack, - term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_MAX_STACK; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: - ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events, - term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_MAX_EVENTS; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_OVERWRITE: - ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, - term->val.num ? 1 : 0, term->weak); + new_type = EVSEL__CONFIG_TERM_OVERWRITE; + val = term->val.num ? 1 : 0; break; case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: - ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite, - term->val.num ? 0 : 1, term->weak); + new_type = EVSEL__CONFIG_TERM_OVERWRITE; + val = term->val.num ? 0 : 1; break; case PARSE_EVENTS__TERM_TYPE_DRV_CFG: - ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str, term->weak); + new_type = EVSEL__CONFIG_TERM_DRV_CFG; + str_type = true; break; case PARSE_EVENTS__TERM_TYPE_PERCORE: - ADD_CONFIG_TERM_VAL(PERCORE, percore, - term->val.num ? true : false, term->weak); + new_type = EVSEL__CONFIG_TERM_PERCORE; + val = term->val.num ? true : false; break; case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: - ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output, - term->val.num ? 1 : 0, term->weak); + new_type = EVSEL__CONFIG_TERM_AUX_OUTPUT; + val = term->val.num ? 1 : 0; break; case PARSE_EVENTS__TERM_TYPE_AUX_ACTION: - ADD_CONFIG_TERM_STR(AUX_ACTION, term->val.str, term->weak); + new_type = EVSEL__CONFIG_TERM_AUX_ACTION; + str_type = true; break; case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: - ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size, - term->val.num, term->weak); + new_type = EVSEL__CONFIG_TERM_AUX_SAMPLE_SIZE; + val = term->val.num; break; case PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV: - ADD_CONFIG_TERM_STR(RATIO_TO_PREV, term->val.str, term->weak); + new_type = EVSEL__CONFIG_TERM_RATIO_TO_PREV; + str_type = true; break; case PARSE_EVENTS__TERM_TYPE_USER: case PARSE_EVENTS__TERM_TYPE_CONFIG: @@ -1232,74 +1230,106 @@ do { \ case PARSE_EVENTS__TERM_TYPE_RAW: case PARSE_EVENTS__TERM_TYPE_CPU: default: - break; + /* Don't add a new term for these ones */ + continue; + } + + new_term = add_config_term(new_type, head_terms, term->weak); + if (!new_term) + return -ENOMEM; + + if (str_type) { + new_term->val.str = strdup(term->val.str); + if (!new_term->val.str) { + zfree(&new_term); + return -ENOMEM; + } + new_term->free_str = true; + } else { + new_term->val.val = val; } } return 0; } -/* - * Add EVSEL__CONFIG_TERM_CFG_CHG where cfg_chg will have a bit set for - * each bit of attr->config that the user has changed. - */ -static int get_config_chgs(struct perf_pmu *pmu, struct parse_events_terms *head_config, - struct list_head *head_terms) +static int add_cfg_chg(const struct perf_pmu *pmu, + const struct parse_events_terms *head_config, + struct list_head *head_terms, + int format_type, + enum parse_events__term_type term_type, + enum evsel_term_type new_term_type) { struct parse_events_term *term; u64 bits = 0; int type; list_for_each_entry(term, &head_config->terms, list) { - switch (term->type_term) { - case PARSE_EVENTS__TERM_TYPE_USER: + if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) { type = perf_pmu__format_type(pmu, term->config); - if (type != PERF_PMU_FORMAT_VALUE_CONFIG) + if (type != format_type) continue; bits |= perf_pmu__format_bits(pmu, term->config); - break; - case PARSE_EVENTS__TERM_TYPE_CONFIG: + } else if (term->type_term == term_type) { bits = ~(u64)0; - break; - case PARSE_EVENTS__TERM_TYPE_CONFIG1: - case PARSE_EVENTS__TERM_TYPE_CONFIG2: - case PARSE_EVENTS__TERM_TYPE_CONFIG3: - case PARSE_EVENTS__TERM_TYPE_CONFIG4: - case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: - case PARSE_EVENTS__TERM_TYPE_LEGACY_CACHE_CONFIG: - case PARSE_EVENTS__TERM_TYPE_NAME: - case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD: - case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ: - case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: - case PARSE_EVENTS__TERM_TYPE_TIME: - case PARSE_EVENTS__TERM_TYPE_CALLGRAPH: - case PARSE_EVENTS__TERM_TYPE_STACKSIZE: - case PARSE_EVENTS__TERM_TYPE_NOINHERIT: - case PARSE_EVENTS__TERM_TYPE_INHERIT: - case PARSE_EVENTS__TERM_TYPE_MAX_STACK: - case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS: - case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE: - case PARSE_EVENTS__TERM_TYPE_OVERWRITE: - case PARSE_EVENTS__TERM_TYPE_DRV_CFG: - case PARSE_EVENTS__TERM_TYPE_PERCORE: - case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT: - case PARSE_EVENTS__TERM_TYPE_AUX_ACTION: - case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE: - case PARSE_EVENTS__TERM_TYPE_METRIC_ID: - case PARSE_EVENTS__TERM_TYPE_RAW: - case PARSE_EVENTS__TERM_TYPE_CPU: - case PARSE_EVENTS__TERM_TYPE_RATIO_TO_PREV: - default: - break; } } - if (bits) - ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits, false); + if (bits) { + struct evsel_config_term *new_term; + + new_term = add_config_term(new_term_type, head_terms, false); + if (!new_term) + return -ENOMEM; + new_term->val.cfg_chg = bits; + } -#undef ADD_CONFIG_TERM return 0; } +/* + * Add EVSEL__CONFIG_TERM_USR_CFG_CONFIGn where cfg_chg will have a bit set for + * each bit of attr->configN that the user has changed. + */ +static int get_config_chgs(const struct perf_pmu *pmu, + const struct parse_events_terms *head_config, + struct list_head *head_terms) +{ + int ret; + + ret = add_cfg_chg(pmu, head_config, head_terms, + PERF_PMU_FORMAT_VALUE_CONFIG, + PARSE_EVENTS__TERM_TYPE_CONFIG, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG); + if (ret) + return ret; + + ret = add_cfg_chg(pmu, head_config, head_terms, + PERF_PMU_FORMAT_VALUE_CONFIG1, + PARSE_EVENTS__TERM_TYPE_CONFIG1, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG1); + if (ret) + return ret; + + ret = add_cfg_chg(pmu, head_config, head_terms, + PERF_PMU_FORMAT_VALUE_CONFIG2, + PARSE_EVENTS__TERM_TYPE_CONFIG2, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG2); + if (ret) + return ret; + + ret = add_cfg_chg(pmu, head_config, head_terms, + PERF_PMU_FORMAT_VALUE_CONFIG3, + PARSE_EVENTS__TERM_TYPE_CONFIG3, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG3); + if (ret) + return ret; + + return add_cfg_chg(pmu, head_config, head_terms, + PERF_PMU_FORMAT_VALUE_CONFIG4, + PARSE_EVENTS__TERM_TYPE_CONFIG4, + EVSEL__CONFIG_TERM_USR_CHG_CONFIG4); +} + int parse_events_add_tracepoint(struct parse_events_state *parse_state, struct list_head *list, const char *sys, const char *event, @@ -1497,12 +1527,8 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state, return -ENOMEM; } - /* - * When using default config, record which bits of attr->config were - * changed by the user. - */ - if (pmu->perf_event_attr_init_default && - get_config_chgs(pmu, &parsed_terms, &config_terms)) { + /* Record which bits of attr->config were changed by the user. */ + if (get_config_chgs(pmu, &parsed_terms, &config_terms)) { parse_events_terms__exit(&parsed_terms); return -ENOMEM; } @@ -2220,12 +2246,12 @@ int __parse_events(struct evlist *evlist, const char *str, const char *pmu_filte evlist__splice_list_tail(evlist, &parse_state.list); if (ret2 && warn_if_reordered && !parse_state.wild_card_pmus) { + evlist__uniquify_evsel_names(evlist, &stat_config); pr_warning("WARNING: events were regrouped to match PMUs\n"); if (verbose > 0) { struct strbuf sb = STRBUF_INIT; - evlist__uniquify_evsel_names(evlist, &stat_config); evlist__format_evsels(evlist, &sb, 2048); pr_debug("evlist after sorting/fixing: '%s'\n", sb.buf); strbuf_release(&sb); diff --git a/tools/perf/util/parse-regs-options.c b/tools/perf/util/parse-regs-options.c index cda1c620968e..c93c2f0c8105 100644 --- a/tools/perf/util/parse-regs-options.c +++ b/tools/perf/util/parse-regs-options.c @@ -5,15 +5,54 @@ #include #include #include "util/debug.h" +#include #include #include "util/perf_regs.h" #include "util/parse-regs-options.h" +static void list_perf_regs(FILE *fp, uint64_t mask) +{ + const char *last_name = NULL; + + fprintf(fp, "available registers: "); + for (int reg = 0; reg < 64; reg++) { + const char *name; + + if (((1ULL << reg) & mask) == 0) + continue; + + name = perf_reg_name(reg, EM_HOST, EF_HOST); + if (name && (!last_name || strcmp(last_name, name))) + fprintf(fp, "%s%s", reg > 0 ? " " : "", name); + last_name = name; + } + fputc('\n', fp); +} + +static uint64_t name_to_perf_reg_mask(const char *to_match, uint64_t mask) +{ + uint64_t reg_mask = 0; + + for (int reg = 0; reg < 64; reg++) { + const char *name; + + if (((1ULL << reg) & mask) == 0) + continue; + + name = perf_reg_name(reg, EM_HOST, EF_HOST); + if (!name) + continue; + + if (!strcasecmp(to_match, name)) + reg_mask |= 1ULL << reg; + } + return reg_mask; +} + static int __parse_regs(const struct option *opt, const char *str, int unset, bool intr) { uint64_t *mode = (uint64_t *)opt->value; - const struct sample_reg *r = NULL; char *s, *os = NULL, *p; int ret = -1; uint64_t mask; @@ -27,56 +66,46 @@ __parse_regs(const struct option *opt, const char *str, int unset, bool intr) if (*mode) return -1; - if (intr) - mask = arch__intr_reg_mask(); - else - mask = arch__user_reg_mask(); + mask = intr ? perf_intr_reg_mask(EM_HOST) : perf_user_reg_mask(EM_HOST); /* str may be NULL in case no arg is passed to -I */ - if (str) { - /* because str is read-only */ - s = os = strdup(str); - if (!s) - return -1; + if (!str) { + *mode = mask; + return 0; + } - for (;;) { - p = strchr(s, ','); - if (p) - *p = '\0'; + /* because str is read-only */ + s = os = strdup(str); + if (!s) + return -1; - if (!strcmp(s, "?")) { - fprintf(stderr, "available registers: "); - for (r = arch__sample_reg_masks(); r->name; r++) { - if (r->mask & mask) - fprintf(stderr, "%s ", r->name); - } - fputc('\n', stderr); - /* just printing available regs */ - goto error; - } - for (r = arch__sample_reg_masks(); r->name; r++) { - if ((r->mask & mask) && !strcasecmp(s, r->name)) - break; - } - if (!r || !r->name) { - ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n", - s, intr ? "-I" : "--user-regs="); - goto error; - } + for (;;) { + uint64_t reg_mask; - *mode |= r->mask; + p = strchr(s, ','); + if (p) + *p = '\0'; - if (!p) - break; - - s = p + 1; + if (!strcmp(s, "?")) { + list_perf_regs(stderr, mask); + goto error; } + + reg_mask = name_to_perf_reg_mask(s, mask); + if (reg_mask == 0) { + ui__warning("Unknown register \"%s\", check man page or run \"perf record %s?\"\n", + s, intr ? "-I" : "--user-regs="); + goto error; + } + *mode |= reg_mask; + + if (!p) + break; + + s = p + 1; } ret = 0; - /* default to all possible regs */ - if (*mode == 0) - *mode = mask; error: free(os); return ret; diff --git a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c index 9dcda80d310f..6833d34dcbfd 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_aarch64.c @@ -1,7 +1,144 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include "../debug.h" +#include "../event.h" #include "../perf_regs.h" -#include "../../../arch/arm64/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/arm64/include/perf_regs.h" + +#define SMPL_REG_MASK(b) (1ULL << (b)) + +#ifndef HWCAP_SVE +#define HWCAP_SVE (1 << 22) +#endif + +/* %xNUM */ +#define SDT_OP_REGEX1 "^(x[1-2]?[0-9]|3[0-1])$" + +/* [sp], [sp, NUM] */ +#define SDT_OP_REGEX2 "^\\[sp(, )?([0-9]+)?\\]$" + +static regex_t sdt_op_regex1, sdt_op_regex2; + +static int sdt_init_op_regex(void) +{ + static int initialized; + int ret = 0; + + if (initialized) + return 0; + + ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED); + if (ret) + goto error; + + ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED); + if (ret) + goto free_regex1; + + initialized = 1; + return 0; + +free_regex1: + regfree(&sdt_op_regex1); +error: + pr_debug4("Regex compilation error.\n"); + return ret; +} + +/* + * SDT marker arguments on Arm64 uses %xREG or [sp, NUM], currently + * support these two formats. + */ +int __perf_sdt_arg_parse_op_arm64(char *old_op, char **new_op) +{ + int ret, new_len; + regmatch_t rm[5]; + + ret = sdt_init_op_regex(); + if (ret < 0) + return ret; + + if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) { + /* Extract xNUM */ + new_len = 2; /* % NULL */ + new_len += (int)(rm[1].rm_eo - rm[1].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%%%.*s", + (int)(rm[1].rm_eo - rm[1].rm_so), old_op + rm[1].rm_so); + } else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) { + /* [sp], [sp, NUM] or [sp,NUM] */ + new_len = 7; /* + ( % s p ) NULL */ + + /* If the argument is [sp], need to fill offset '0' */ + if (rm[2].rm_so == -1) + new_len += 1; + else + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + if (rm[2].rm_so == -1) + scnprintf(*new_op, new_len, "+0(%%sp)"); + else + scnprintf(*new_op, new_len, "+%.*s(%%sp)", + (int)(rm[2].rm_eo - rm[2].rm_so), + old_op + rm[2].rm_so); + } else { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + return SDT_ARG_VALID; +} + +uint64_t __perf_reg_mask_arm64(bool intr) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + .sample_type = PERF_SAMPLE_REGS_USER, + .disabled = 1, + .exclude_kernel = 1, + .sample_period = 1, + .sample_regs_user = PERF_REGS_MASK + }; + int fd; + + if (intr) + return PERF_REGS_MASK; + + if (getauxval(AT_HWCAP) & HWCAP_SVE) + attr.sample_regs_user |= SMPL_REG_MASK(PERF_REG_ARM64_VG); + + /* + * Check if the pmu supports perf extended regs, before + * returning the register mask to sample. Open the event + * on the perf process to check this. + */ + if (attr.sample_regs_user != PERF_REGS_MASK) { + event_attr_init(&attr); + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1, + /*group_fd=*/-1, /*flags=*/0); + if (fd != -1) { + close(fd); + return attr.sample_regs_user; + } + } + return PERF_REGS_MASK; +} const char *__perf_reg_name_arm64(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_arm.c b/tools/perf/util/perf-regs-arch/perf_regs_arm.c index e29d130a587a..184d6e248dfc 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_arm.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_arm.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/arm/include/uapi/asm/perf_regs.h" +#include "../../arch/arm/include/perf_regs.h" + +uint64_t __perf_reg_mask_arm(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} const char *__perf_reg_name_arm(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_csky.c b/tools/perf/util/perf-regs-arch/perf_regs_csky.c index 75b461ef2eba..16cbd8303acf 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_csky.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_csky.c @@ -1,10 +1,26 @@ // SPDX-License-Identifier: GPL-2.0 - +#include +#ifndef EF_CSKY_ABIMASK +#define EF_CSKY_ABIMASK 0XF0000000 +#endif +#ifndef EF_CSKY_ABIV2 +#define EF_CSKY_ABIV2 0X20000000 +#endif #include "../perf_regs.h" -#include "../../arch/csky/include/uapi/asm/perf_regs.h" +#undef __CSKYABIV2__ +#define __CSKYABIV2__ 1 // Always want the V2 register definitions. +#include "../../arch/csky/include/perf_regs.h" -const char *__perf_reg_name_csky(int id) +uint64_t __perf_reg_mask_csky(bool intr __maybe_unused) { + return PERF_REGS_MASK; +} + +const char *__perf_reg_name_csky(int id, uint32_t e_flags) +{ + if (id >= PERF_REG_CSKY_EXREGS0 && (e_flags & EF_CSKY_ABIMASK) == EF_CSKY_ABIV2) + return NULL; + switch (id) { case PERF_REG_CSKY_A0: return "a0"; @@ -40,7 +56,6 @@ const char *__perf_reg_name_csky(int id) return "lr"; case PERF_REG_CSKY_PC: return "pc"; -#if defined(__CSKYABIV2__) case PERF_REG_CSKY_EXREGS0: return "exregs0"; case PERF_REG_CSKY_EXREGS1: @@ -77,12 +92,9 @@ const char *__perf_reg_name_csky(int id) return "hi"; case PERF_REG_CSKY_LO: return "lo"; -#endif default: return NULL; } - - return NULL; } uint64_t __perf_reg_ip_csky(void) diff --git a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c index 043f97f4e3ac..478ee889afa1 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_loongarch.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/loongarch/include/uapi/asm/perf_regs.h" +#include "../../arch/loongarch/include/perf_regs.h" + +uint64_t __perf_reg_mask_loongarch(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} const char *__perf_reg_name_loongarch(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_mips.c b/tools/perf/util/perf-regs-arch/perf_regs_mips.c index 793178fc3c78..c5a475f6ec64 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_mips.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_mips.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/mips/include/uapi/asm/perf_regs.h" +#include "../../arch/mips/include/perf_regs.h" + +uint64_t __perf_reg_mask_mips(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} const char *__perf_reg_name_mips(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c index 08636bb09a3a..217a001ccd2e 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_powerpc.c @@ -1,7 +1,188 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include + +#include "../debug.h" +#include "../event.h" +#include "../header.h" #include "../perf_regs.h" -#include "../../../arch/powerpc/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/powerpc/util/utils_header.h" +#include "../../arch/powerpc/include/perf_regs.h" + +#include + +#define PVR_POWER9 0x004E +#define PVR_POWER10 0x0080 +#define PVR_POWER11 0x0082 + +/* REG or %rREG */ +#define SDT_OP_REGEX1 "^(%r)?([1-2]?[0-9]|3[0-1])$" + +/* -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) */ +#define SDT_OP_REGEX2 "^(\\-)?([0-9]+)\\((%r)?([1-2]?[0-9]|3[0-1])\\)$" + +static regex_t sdt_op_regex1, sdt_op_regex2; + +static int sdt_init_op_regex(void) +{ + static int initialized; + int ret = 0; + + if (initialized) + return 0; + + ret = regcomp(&sdt_op_regex1, SDT_OP_REGEX1, REG_EXTENDED); + if (ret) + goto error; + + ret = regcomp(&sdt_op_regex2, SDT_OP_REGEX2, REG_EXTENDED); + if (ret) + goto free_regex1; + + initialized = 1; + return 0; + +free_regex1: + regfree(&sdt_op_regex1); +error: + pr_debug4("Regex compilation error.\n"); + return ret; +} + +/* + * Parse OP and convert it into uprobe format, which is, +/-NUM(%gprREG). + * Possible variants of OP are: + * Format Example + * ------------------------- + * NUM(REG) 48(18) + * -NUM(REG) -48(18) + * NUM(%rREG) 48(%r18) + * -NUM(%rREG) -48(%r18) + * REG 18 + * %rREG %r18 + * iNUM i0 + * i-NUM i-1 + * + * SDT marker arguments on Powerpc uses %rREG form with -mregnames flag + * and REG form with -mno-regnames. Here REG is general purpose register, + * which is in 0 to 31 range. + */ +int __perf_sdt_arg_parse_op_powerpc(char *old_op, char **new_op) +{ + int ret, new_len; + regmatch_t rm[5]; + char prefix; + + /* Constant argument. Uprobe does not support it */ + if (old_op[0] == 'i') { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + ret = sdt_init_op_regex(); + if (ret < 0) + return ret; + + if (!regexec(&sdt_op_regex1, old_op, 3, rm, 0)) { + /* REG or %rREG --> %gprREG */ + + new_len = 5; /* % g p r NULL */ + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%%gpr%.*s", + (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so); + } else if (!regexec(&sdt_op_regex2, old_op, 5, rm, 0)) { + /* + * -NUM(REG) or NUM(REG) or -NUM(%rREG) or NUM(%rREG) --> + * +/-NUM(%gprREG) + */ + prefix = (rm[1].rm_so == -1) ? '+' : '-'; + + new_len = 8; /* +/- ( % g p r ) NULL */ + new_len += (int)(rm[2].rm_eo - rm[2].rm_so); + new_len += (int)(rm[4].rm_eo - rm[4].rm_so); + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%c%.*s(%%gpr%.*s)", prefix, + (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so, + (int)(rm[4].rm_eo - rm[4].rm_so), old_op + rm[4].rm_so); + } else { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + return SDT_ARG_VALID; +} + +/* + * mfspr is a POWERPC specific instruction, ensure it's only + * built and called on POWERPC by guarding with __powerpc64__ + * or __powerpc__. + */ +#if defined(__powerpc64__) && defined(__powerpc__) +uint64_t __perf_reg_mask_powerpc(bool intr) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + .sample_type = PERF_SAMPLE_REGS_INTR, + .precise_ip = 1, + .disabled = 1, + .exclude_kernel = 1, + }; + int fd; + u32 version; + u64 extended_mask = 0, mask = PERF_REGS_MASK; + + if (!intr) + return PERF_REGS_MASK; + + /* + * Get the PVR value to set the extended + * mask specific to platform. + */ + version = (((mfspr(SPRN_PVR)) >> 16) & 0xFFFF); + if (version == PVR_POWER9) + extended_mask = PERF_REG_PMU_MASK_300; + else if ((version == PVR_POWER10) || (version == PVR_POWER11)) + extended_mask = PERF_REG_PMU_MASK_31; + else + return mask; + + attr.sample_regs_intr = extended_mask; + attr.sample_period = 1; + event_attr_init(&attr); + + /* + * Check if the pmu supports perf extended regs, before + * returning the register mask to sample. Open the event + * on the perf process to check this. + */ + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1, + /*group_fd=*/-1, /*flags=*/0); + if (fd != -1) { + close(fd); + mask |= extended_mask; + } + return mask; +} +#else +uint64_t __perf_reg_mask_powerpc(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} +#endif const char *__perf_reg_name_powerpc(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c index 337b687c655d..5b5f21fcba8c 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_riscv.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_riscv.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/riscv/include/uapi/asm/perf_regs.h" +#include "../../arch/riscv/include/perf_regs.h" + +uint64_t __perf_reg_mask_riscv(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} const char *__perf_reg_name_riscv(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_s390.c b/tools/perf/util/perf-regs-arch/perf_regs_s390.c index d69bba881080..c61df24edf0f 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_s390.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_s390.c @@ -1,7 +1,12 @@ // SPDX-License-Identifier: GPL-2.0 #include "../perf_regs.h" -#include "../../../arch/s390/include/uapi/asm/perf_regs.h" +#include "../../arch/s390/include/perf_regs.h" + +uint64_t __perf_reg_mask_s390(bool intr __maybe_unused) +{ + return PERF_REGS_MASK; +} const char *__perf_reg_name_s390(int id) { diff --git a/tools/perf/util/perf-regs-arch/perf_regs_x86.c b/tools/perf/util/perf-regs-arch/perf_regs_x86.c index 708954a9d35d..b6d20522b4e8 100644 --- a/tools/perf/util/perf-regs-arch/perf_regs_x86.c +++ b/tools/perf/util/perf-regs-arch/perf_regs_x86.c @@ -1,7 +1,286 @@ // SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +#include "../debug.h" +#include "../event.h" +#include "../pmu.h" +#include "../pmus.h" #include "../perf_regs.h" -#include "../../../arch/x86/include/uapi/asm/perf_regs.h" +#include "../../perf-sys.h" +#include "../../arch/x86/include/perf_regs.h" + +struct sdt_name_reg { + const char *sdt_name; + const char *uprobe_name; +}; +#define SDT_NAME_REG(n, m) {.sdt_name = "%" #n, .uprobe_name = "%" #m} +#define SDT_NAME_REG_END {.sdt_name = NULL, .uprobe_name = NULL} + +static const struct sdt_name_reg sdt_reg_tbl[] = { + SDT_NAME_REG(eax, ax), + SDT_NAME_REG(rax, ax), + SDT_NAME_REG(al, ax), + SDT_NAME_REG(ah, ax), + SDT_NAME_REG(ebx, bx), + SDT_NAME_REG(rbx, bx), + SDT_NAME_REG(bl, bx), + SDT_NAME_REG(bh, bx), + SDT_NAME_REG(ecx, cx), + SDT_NAME_REG(rcx, cx), + SDT_NAME_REG(cl, cx), + SDT_NAME_REG(ch, cx), + SDT_NAME_REG(edx, dx), + SDT_NAME_REG(rdx, dx), + SDT_NAME_REG(dl, dx), + SDT_NAME_REG(dh, dx), + SDT_NAME_REG(esi, si), + SDT_NAME_REG(rsi, si), + SDT_NAME_REG(sil, si), + SDT_NAME_REG(edi, di), + SDT_NAME_REG(rdi, di), + SDT_NAME_REG(dil, di), + SDT_NAME_REG(ebp, bp), + SDT_NAME_REG(rbp, bp), + SDT_NAME_REG(bpl, bp), + SDT_NAME_REG(rsp, sp), + SDT_NAME_REG(esp, sp), + SDT_NAME_REG(spl, sp), + + /* rNN registers */ + SDT_NAME_REG(r8b, r8), + SDT_NAME_REG(r8w, r8), + SDT_NAME_REG(r8d, r8), + SDT_NAME_REG(r9b, r9), + SDT_NAME_REG(r9w, r9), + SDT_NAME_REG(r9d, r9), + SDT_NAME_REG(r10b, r10), + SDT_NAME_REG(r10w, r10), + SDT_NAME_REG(r10d, r10), + SDT_NAME_REG(r11b, r11), + SDT_NAME_REG(r11w, r11), + SDT_NAME_REG(r11d, r11), + SDT_NAME_REG(r12b, r12), + SDT_NAME_REG(r12w, r12), + SDT_NAME_REG(r12d, r12), + SDT_NAME_REG(r13b, r13), + SDT_NAME_REG(r13w, r13), + SDT_NAME_REG(r13d, r13), + SDT_NAME_REG(r14b, r14), + SDT_NAME_REG(r14w, r14), + SDT_NAME_REG(r14d, r14), + SDT_NAME_REG(r15b, r15), + SDT_NAME_REG(r15w, r15), + SDT_NAME_REG(r15d, r15), + SDT_NAME_REG_END, +}; + +/* + * Perf only supports OP which is in +/-NUM(REG) form. + * Here plus-minus sign, NUM and parenthesis are optional, + * only REG is mandatory. + * + * SDT events also supports indirect addressing mode with a + * symbol as offset, scaled mode and constants in OP. But + * perf does not support them yet. Below are few examples. + * + * OP with scaled mode: + * (%rax,%rsi,8) + * 10(%ras,%rsi,8) + * + * OP with indirect addressing mode: + * check_action(%rip) + * mp_+52(%rip) + * 44+mp_(%rip) + * + * OP with constant values: + * $0 + * $123 + * $-1 + */ +#define SDT_OP_REGEX "^([+\\-]?)([0-9]*)(\\(?)(%[a-z][a-z0-9]+)(\\)?)$" + +static regex_t sdt_op_regex; + +static int sdt_init_op_regex(void) +{ + static int initialized; + int ret = 0; + + if (initialized) + return 0; + + ret = regcomp(&sdt_op_regex, SDT_OP_REGEX, REG_EXTENDED); + if (ret < 0) { + pr_debug4("Regex compilation error.\n"); + return ret; + } + + initialized = 1; + return 0; +} + +/* + * Max x86 register name length is 5(ex: %r15d). So, 6th char + * should always contain NULL. This helps to find register name + * length using strlen, instead of maintaining one more variable. + */ +#define SDT_REG_NAME_SIZE 6 + +/* + * The uprobe parser does not support all gas register names; + * so, we have to replace them (ex. for x86_64: %rax -> %ax). + * Note: If register does not require renaming, just copy + * paste as it is, but don't leave it empty. + */ +static void sdt_rename_register(char *sdt_reg, int sdt_len, char *uprobe_reg) +{ + int i = 0; + + for (i = 0; sdt_reg_tbl[i].sdt_name != NULL; i++) { + if (!strncmp(sdt_reg_tbl[i].sdt_name, sdt_reg, sdt_len)) { + strcpy(uprobe_reg, sdt_reg_tbl[i].uprobe_name); + return; + } + } + + strncpy(uprobe_reg, sdt_reg, sdt_len); +} + +int __perf_sdt_arg_parse_op_x86(char *old_op, char **new_op) +{ + char new_reg[SDT_REG_NAME_SIZE] = {0}; + int new_len = 0, ret; + /* + * rm[0]: +/-NUM(REG) + * rm[1]: +/- + * rm[2]: NUM + * rm[3]: ( + * rm[4]: REG + * rm[5]: ) + */ + regmatch_t rm[6]; + /* + * Max prefix length is 2 as it may contains sign(+/-) + * and displacement 0 (Both sign and displacement 0 are + * optional so it may be empty). Use one more character + * to hold last NULL so that strlen can be used to find + * prefix length, instead of maintaining one more variable. + */ + char prefix[3] = {0}; + + ret = sdt_init_op_regex(); + if (ret < 0) + return ret; + + /* + * If unsupported OR does not match with regex OR + * register name too long, skip it. + */ + if (strchr(old_op, ',') || strchr(old_op, '$') || + regexec(&sdt_op_regex, old_op, 6, rm, 0) || + rm[4].rm_eo - rm[4].rm_so > SDT_REG_NAME_SIZE) { + pr_debug4("Skipping unsupported SDT argument: %s\n", old_op); + return SDT_ARG_SKIP; + } + + /* + * Prepare prefix. + * If SDT OP has parenthesis but does not provide + * displacement, add 0 for displacement. + * SDT Uprobe Prefix + * ----------------------------- + * +24(%rdi) +24(%di) + + * 24(%rdi) +24(%di) + + * %rdi %di + * (%rdi) +0(%di) +0 + * -80(%rbx) -80(%bx) - + */ + if (rm[3].rm_so != rm[3].rm_eo) { + if (rm[1].rm_so != rm[1].rm_eo) + prefix[0] = *(old_op + rm[1].rm_so); + else if (rm[2].rm_so != rm[2].rm_eo) + prefix[0] = '+'; + else + scnprintf(prefix, sizeof(prefix), "+0"); + } + + /* Rename register */ + sdt_rename_register(old_op + rm[4].rm_so, rm[4].rm_eo - rm[4].rm_so, + new_reg); + + /* Prepare final OP which should be valid for uprobe_events */ + new_len = strlen(prefix) + + (rm[2].rm_eo - rm[2].rm_so) + + (rm[3].rm_eo - rm[3].rm_so) + + strlen(new_reg) + + (rm[5].rm_eo - rm[5].rm_so) + + 1; /* NULL */ + + *new_op = zalloc(new_len); + if (!*new_op) + return -ENOMEM; + + scnprintf(*new_op, new_len, "%.*s%.*s%.*s%.*s%.*s", + strlen(prefix), prefix, + (int)(rm[2].rm_eo - rm[2].rm_so), old_op + rm[2].rm_so, + (int)(rm[3].rm_eo - rm[3].rm_so), old_op + rm[3].rm_so, + strlen(new_reg), new_reg, + (int)(rm[5].rm_eo - rm[5].rm_so), old_op + rm[5].rm_so); + + return SDT_ARG_VALID; +} + +uint64_t __perf_reg_mask_x86(bool intr) +{ + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + .sample_type = PERF_SAMPLE_REGS_INTR, + .sample_regs_intr = PERF_REG_EXTENDED_MASK, + .precise_ip = 1, + .disabled = 1, + .exclude_kernel = 1, + }; + int fd; + + if (!intr) + return PERF_REGS_MASK; + + /* + * In an unnamed union, init it here to build on older gcc versions + */ + attr.sample_period = 1; + + if (perf_pmus__num_core_pmus() > 1) { + struct perf_pmu *pmu = NULL; + __u64 type = PERF_TYPE_RAW; + + /* + * The same register set is supported among different hybrid PMUs. + * Only check the first available one. + */ + while ((pmu = perf_pmus__scan_core(pmu)) != NULL) { + type = pmu->type; + break; + } + attr.config |= type << PERF_PMU_TYPE_SHIFT; + } + + event_attr_init(&attr); + fd = sys_perf_event_open(&attr, /*pid=*/0, /*cpu=*/-1, + /*group_fd=*/-1, /*flags=*/0); + if (fd != -1) { + close(fd); + return (PERF_REG_EXTENDED_MASK | PERF_REGS_MASK); + } + + return PERF_REGS_MASK; +} const char *__perf_reg_name_x86(int id) { diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 44b90bbf2d07..5b8f34beb24e 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c @@ -1,59 +1,165 @@ // SPDX-License-Identifier: GPL-2.0 +#include #include #include +#include "dwarf-regs.h" #include "perf_regs.h" #include "util/sample.h" #include "debug.h" -int __weak arch_sdt_arg_parse_op(char *old_op __maybe_unused, - char **new_op __maybe_unused) +int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op) { - return SDT_ARG_SKIP; + int ret = SDT_ARG_SKIP; + + switch (e_machine) { + case EM_AARCH64: + ret = __perf_sdt_arg_parse_op_arm64(old_op, new_op); + break; + case EM_PPC: + case EM_PPC64: + ret = __perf_sdt_arg_parse_op_powerpc(old_op, new_op); + break; + case EM_386: + case EM_X86_64: + ret = __perf_sdt_arg_parse_op_x86(old_op, new_op); + break; + default: + pr_debug("Unknown ELF machine %d, standard arguments parse will be skipped.\n", + e_machine); + break; + } + + return ret; } -uint64_t __weak arch__intr_reg_mask(void) +uint64_t perf_intr_reg_mask(uint16_t e_machine) { - return 0; + uint64_t mask = 0; + + switch (e_machine) { + case EM_ARM: + mask = __perf_reg_mask_arm(/*intr=*/true); + break; + case EM_AARCH64: + mask = __perf_reg_mask_arm64(/*intr=*/true); + break; + case EM_CSKY: + mask = __perf_reg_mask_csky(/*intr=*/true); + break; + case EM_LOONGARCH: + mask = __perf_reg_mask_loongarch(/*intr=*/true); + break; + case EM_MIPS: + mask = __perf_reg_mask_mips(/*intr=*/true); + break; + case EM_PPC: + case EM_PPC64: + mask = __perf_reg_mask_powerpc(/*intr=*/true); + break; + case EM_RISCV: + mask = __perf_reg_mask_riscv(/*intr=*/true); + break; + case EM_S390: + mask = __perf_reg_mask_s390(/*intr=*/true); + break; + case EM_386: + case EM_X86_64: + mask = __perf_reg_mask_x86(/*intr=*/true); + break; + default: + pr_debug("Unknown ELF machine %d, interrupt sampling register mask will be empty.\n", + e_machine); + break; + } + + return mask; } -uint64_t __weak arch__user_reg_mask(void) +uint64_t perf_user_reg_mask(uint16_t e_machine) { - return 0; + uint64_t mask = 0; + + switch (e_machine) { + case EM_ARM: + mask = __perf_reg_mask_arm(/*intr=*/false); + break; + case EM_AARCH64: + mask = __perf_reg_mask_arm64(/*intr=*/false); + break; + case EM_CSKY: + mask = __perf_reg_mask_csky(/*intr=*/false); + break; + case EM_LOONGARCH: + mask = __perf_reg_mask_loongarch(/*intr=*/false); + break; + case EM_MIPS: + mask = __perf_reg_mask_mips(/*intr=*/false); + break; + case EM_PPC: + case EM_PPC64: + mask = __perf_reg_mask_powerpc(/*intr=*/false); + break; + case EM_RISCV: + mask = __perf_reg_mask_riscv(/*intr=*/false); + break; + case EM_S390: + mask = __perf_reg_mask_s390(/*intr=*/false); + break; + case EM_386: + case EM_X86_64: + mask = __perf_reg_mask_x86(/*intr=*/false); + break; + default: + pr_debug("Unknown ELF machine %d, user sampling register mask will be empty.\n", + e_machine); + break; + } + + return mask; } -static const struct sample_reg sample_reg_masks[] = { - SMPL_REG_END -}; - -const struct sample_reg * __weak arch__sample_reg_masks(void) -{ - return sample_reg_masks; -} - -const char *perf_reg_name(int id, const char *arch) +const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags) { const char *reg_name = NULL; - if (!strcmp(arch, "csky")) - reg_name = __perf_reg_name_csky(id); - else if (!strcmp(arch, "loongarch")) - reg_name = __perf_reg_name_loongarch(id); - else if (!strcmp(arch, "mips")) - reg_name = __perf_reg_name_mips(id); - else if (!strcmp(arch, "powerpc")) - reg_name = __perf_reg_name_powerpc(id); - else if (!strcmp(arch, "riscv")) - reg_name = __perf_reg_name_riscv(id); - else if (!strcmp(arch, "s390")) - reg_name = __perf_reg_name_s390(id); - else if (!strcmp(arch, "x86")) - reg_name = __perf_reg_name_x86(id); - else if (!strcmp(arch, "arm")) + switch (e_machine) { + case EM_ARM: reg_name = __perf_reg_name_arm(id); - else if (!strcmp(arch, "arm64")) + break; + case EM_AARCH64: reg_name = __perf_reg_name_arm64(id); + break; + case EM_CSKY: + reg_name = __perf_reg_name_csky(id, e_flags); + break; + case EM_LOONGARCH: + reg_name = __perf_reg_name_loongarch(id); + break; + case EM_MIPS: + reg_name = __perf_reg_name_mips(id); + break; + case EM_PPC: + case EM_PPC64: + reg_name = __perf_reg_name_powerpc(id); + break; + case EM_RISCV: + reg_name = __perf_reg_name_riscv(id); + break; + case EM_S390: + reg_name = __perf_reg_name_s390(id); + break; + case EM_386: + case EM_X86_64: + reg_name = __perf_reg_name_x86(id); + break; + default: + break; + } + if (reg_name) + return reg_name; - return reg_name ?: "unknown"; + pr_debug("Failed to find register %d for ELF machine type %u\n", id, e_machine); + return "unknown"; } int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) @@ -83,52 +189,60 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) return 0; } -uint64_t perf_arch_reg_ip(const char *arch) +uint64_t perf_arch_reg_ip(uint16_t e_machine) { - if (!strcmp(arch, "arm")) + switch (e_machine) { + case EM_ARM: return __perf_reg_ip_arm(); - else if (!strcmp(arch, "arm64")) + case EM_AARCH64: return __perf_reg_ip_arm64(); - else if (!strcmp(arch, "csky")) + case EM_CSKY: return __perf_reg_ip_csky(); - else if (!strcmp(arch, "loongarch")) + case EM_LOONGARCH: return __perf_reg_ip_loongarch(); - else if (!strcmp(arch, "mips")) + case EM_MIPS: return __perf_reg_ip_mips(); - else if (!strcmp(arch, "powerpc")) + case EM_PPC: + case EM_PPC64: return __perf_reg_ip_powerpc(); - else if (!strcmp(arch, "riscv")) + case EM_RISCV: return __perf_reg_ip_riscv(); - else if (!strcmp(arch, "s390")) + case EM_S390: return __perf_reg_ip_s390(); - else if (!strcmp(arch, "x86")) + case EM_386: + case EM_X86_64: return __perf_reg_ip_x86(); - - pr_err("Fail to find IP register for arch %s, returns 0\n", arch); - return 0; + default: + pr_err("Failed to find IP register for ELF machine type %u\n", e_machine); + return 0; + } } -uint64_t perf_arch_reg_sp(const char *arch) +uint64_t perf_arch_reg_sp(uint16_t e_machine) { - if (!strcmp(arch, "arm")) + switch (e_machine) { + case EM_ARM: return __perf_reg_sp_arm(); - else if (!strcmp(arch, "arm64")) + case EM_AARCH64: return __perf_reg_sp_arm64(); - else if (!strcmp(arch, "csky")) + case EM_CSKY: return __perf_reg_sp_csky(); - else if (!strcmp(arch, "loongarch")) + case EM_LOONGARCH: return __perf_reg_sp_loongarch(); - else if (!strcmp(arch, "mips")) + case EM_MIPS: return __perf_reg_sp_mips(); - else if (!strcmp(arch, "powerpc")) + case EM_PPC: + case EM_PPC64: return __perf_reg_sp_powerpc(); - else if (!strcmp(arch, "riscv")) + case EM_RISCV: return __perf_reg_sp_riscv(); - else if (!strcmp(arch, "s390")) + case EM_S390: return __perf_reg_sp_s390(); - else if (!strcmp(arch, "x86")) + case EM_386: + case EM_X86_64: return __perf_reg_sp_x86(); - - pr_err("Fail to find SP register for arch %s, returns 0\n", arch); - return 0; + default: + pr_err("Failed to find SP register for ELF machine type %u\n", e_machine); + return 0; + } } diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index f2d0736d65cc..7c04700bf837 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h @@ -7,62 +7,71 @@ struct regs_dump; -struct sample_reg { - const char *name; - uint64_t mask; -}; - -#define SMPL_REG_MASK(b) (1ULL << (b)) -#define SMPL_REG(n, b) { .name = #n, .mask = SMPL_REG_MASK(b) } -#define SMPL_REG2_MASK(b) (3ULL << (b)) -#define SMPL_REG2(n, b) { .name = #n, .mask = SMPL_REG2_MASK(b) } -#define SMPL_REG_END { .name = NULL } - enum { SDT_ARG_VALID = 0, SDT_ARG_SKIP, }; -int arch_sdt_arg_parse_op(char *old_op, char **new_op); -uint64_t arch__intr_reg_mask(void); -uint64_t arch__user_reg_mask(void); -const struct sample_reg *arch__sample_reg_masks(void); +int perf_sdt_arg_parse_op(uint16_t e_machine, char *old_op, char **new_op); +uint64_t perf_intr_reg_mask(uint16_t e_machine); +uint64_t perf_user_reg_mask(uint16_t e_machine); -const char *perf_reg_name(int id, const char *arch); +const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags); int perf_reg_value(u64 *valp, struct regs_dump *regs, int id); -uint64_t perf_arch_reg_ip(const char *arch); -uint64_t perf_arch_reg_sp(const char *arch); +uint64_t perf_arch_reg_ip(uint16_t e_machine); +uint64_t perf_arch_reg_sp(uint16_t e_machine); + +int __perf_sdt_arg_parse_op_arm64(char *old_op, char **new_op); +uint64_t __perf_reg_mask_arm64(bool intr); const char *__perf_reg_name_arm64(int id); uint64_t __perf_reg_ip_arm64(void); uint64_t __perf_reg_sp_arm64(void); + +uint64_t __perf_reg_mask_arm(bool intr); const char *__perf_reg_name_arm(int id); uint64_t __perf_reg_ip_arm(void); uint64_t __perf_reg_sp_arm(void); -const char *__perf_reg_name_csky(int id); + +uint64_t __perf_reg_mask_csky(bool intr); +const char *__perf_reg_name_csky(int id, uint32_t e_flags); uint64_t __perf_reg_ip_csky(void); uint64_t __perf_reg_sp_csky(void); + +uint64_t __perf_reg_mask_loongarch(bool intr); const char *__perf_reg_name_loongarch(int id); uint64_t __perf_reg_ip_loongarch(void); uint64_t __perf_reg_sp_loongarch(void); + +uint64_t __perf_reg_mask_mips(bool intr); const char *__perf_reg_name_mips(int id); uint64_t __perf_reg_ip_mips(void); uint64_t __perf_reg_sp_mips(void); + +int __perf_sdt_arg_parse_op_powerpc(char *old_op, char **new_op); +uint64_t __perf_reg_mask_powerpc(bool intr); const char *__perf_reg_name_powerpc(int id); uint64_t __perf_reg_ip_powerpc(void); uint64_t __perf_reg_sp_powerpc(void); + +uint64_t __perf_reg_mask_riscv(bool intr); const char *__perf_reg_name_riscv(int id); uint64_t __perf_reg_ip_riscv(void); uint64_t __perf_reg_sp_riscv(void); + +uint64_t __perf_reg_mask_s390(bool intr); const char *__perf_reg_name_s390(int id); uint64_t __perf_reg_ip_s390(void); uint64_t __perf_reg_sp_s390(void); + +int __perf_sdt_arg_parse_op_x86(char *old_op, char **new_op); +uint64_t __perf_reg_mask_x86(bool intr); const char *__perf_reg_name_x86(int id); uint64_t __perf_reg_ip_x86(void); uint64_t __perf_reg_sp_x86(void); -static inline uint64_t DWARF_MINIMAL_REGS(const char *arch) +static inline uint64_t DWARF_MINIMAL_REGS(uint16_t e_machine) { - return (1ULL << perf_arch_reg_ip(arch)) | (1ULL << perf_arch_reg_sp(arch)); + return (1ULL << perf_arch_reg_ip(e_machine)) | (1ULL << perf_arch_reg_sp(e_machine)); } #endif /* __PERF_REGS_H */ diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 01a21b6aa031..23337d2fa281 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -118,31 +118,6 @@ struct perf_pmu_alias { bool info_loaded; }; -/** - * struct perf_pmu_format - Values from a format file read from - * /devices/cpu/format/ held in struct perf_pmu. - * - * For example, the contents of /devices/cpu/format/event may be - * "config:0-7" and will be represented here as name="event", - * value=PERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set. - */ -struct perf_pmu_format { - /** @list: Element on list within struct perf_pmu. */ - struct list_head list; - /** @bits: Which config bits are set by this format value. */ - DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); - /** @name: The modifier/file name. */ - char *name; - /** - * @value : Which config value the format relates to. Supported values - * are from PERF_PMU_FORMAT_VALUE_CONFIG to - * PERF_PMU_FORMAT_VALUE_CONFIG_END. - */ - u16 value; - /** @loaded: Has the contents been loaded/parsed. */ - bool loaded; -}; - static int pmu_aliases_parse(struct perf_pmu *pmu); static struct perf_pmu_format *perf_pmu__new_format(struct list_head *list, char *name) @@ -1364,48 +1339,28 @@ void perf_pmu__warn_invalid_formats(struct perf_pmu *pmu) } } -bool evsel__is_aux_event(const struct evsel *evsel) -{ - struct perf_pmu *pmu; - - if (evsel->needs_auxtrace_mmap) - return true; - - pmu = evsel__find_pmu(evsel); - return pmu && pmu->auxtrace; -} - /* - * Set @config_name to @val as long as the user hasn't already set or cleared it - * by passing a config term on the command line. - * - * @val is the value to put into the bits specified by @config_name rather than - * the bit pattern. It is shifted into position by this function, so to set - * something to true, pass 1 for val rather than a pre shifted value. + * Unpacks a raw config[n] value using the sparse bitfield that defines a + * format attr. For example "config1:1,6-7,44" defines a 4 bit value across non + * contiguous bits and this function returns those 4 bits as a value. */ -#define field_prep(_mask, _val) (((_val) << (ffsll(_mask) - 1)) & (_mask)) -void evsel__set_config_if_unset(struct perf_pmu *pmu, struct evsel *evsel, - const char *config_name, u64 val) +u64 perf_pmu__format_unpack(unsigned long *format, u64 config_val) { - u64 user_bits = 0, bits; - struct evsel_config_term *term = evsel__get_config_term(evsel, CFG_CHG); + int val_bit = 0; + u64 res = 0; + int fmt_bit; - if (term) - user_bits = term->val.cfg_chg; + for_each_set_bit(fmt_bit, format, PERF_PMU_FORMAT_BITS) { + if (config_val & (1ULL << fmt_bit)) + res |= BIT_ULL(val_bit); - bits = perf_pmu__format_bits(pmu, config_name); - - /* Do nothing if the user changed the value */ - if (bits & user_bits) - return; - - /* Otherwise replace it */ - evsel->core.attr.config &= ~bits; - evsel->core.attr.config |= field_prep(bits, val); + val_bit++; + } + return res; } -static struct perf_pmu_format * -pmu_find_format(const struct list_head *formats, const char *name) +struct perf_pmu_format *pmu_find_format(const struct list_head *formats, + const char *name) { struct perf_pmu_format *format; @@ -1416,7 +1371,7 @@ pmu_find_format(const struct list_head *formats, const char *name) return NULL; } -__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name) +__u64 perf_pmu__format_bits(const struct perf_pmu *pmu, const char *name) { struct perf_pmu_format *format = pmu_find_format(&pmu->format, name); __u64 bits = 0; @@ -1431,7 +1386,7 @@ __u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name) return bits; } -int perf_pmu__format_type(struct perf_pmu *pmu, const char *name) +int perf_pmu__format_type(const struct perf_pmu *pmu, const char *name) { struct perf_pmu_format *format = pmu_find_format(&pmu->format, name); @@ -1446,8 +1401,8 @@ int perf_pmu__format_type(struct perf_pmu *pmu, const char *name) * Sets value based on the format definition (format parameter) * and unformatted value (value parameter). */ -static void pmu_format_value(unsigned long *format, __u64 value, __u64 *v, - bool zero) +void perf_pmu__format_pack(unsigned long *format, __u64 value, __u64 *v, + bool zero) { unsigned long fbit, vbit; @@ -1564,23 +1519,23 @@ static int pmu_config_term(const struct perf_pmu *pmu, switch (term->type_term) { case PARSE_EVENTS__TERM_TYPE_CONFIG: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - pmu_format_value(bits, term->val.num, &attr->config, zero); + perf_pmu__format_pack(bits, term->val.num, &attr->config, zero); break; case PARSE_EVENTS__TERM_TYPE_CONFIG1: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - pmu_format_value(bits, term->val.num, &attr->config1, zero); + perf_pmu__format_pack(bits, term->val.num, &attr->config1, zero); break; case PARSE_EVENTS__TERM_TYPE_CONFIG2: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - pmu_format_value(bits, term->val.num, &attr->config2, zero); + perf_pmu__format_pack(bits, term->val.num, &attr->config2, zero); break; case PARSE_EVENTS__TERM_TYPE_CONFIG3: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - pmu_format_value(bits, term->val.num, &attr->config3, zero); + perf_pmu__format_pack(bits, term->val.num, &attr->config3, zero); break; case PARSE_EVENTS__TERM_TYPE_CONFIG4: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); - pmu_format_value(bits, term->val.num, &attr->config4, zero); + perf_pmu__format_pack(bits, term->val.num, &attr->config4, zero); break; case PARSE_EVENTS__TERM_TYPE_LEGACY_HARDWARE_CONFIG: assert(term->type_val == PARSE_EVENTS__TERM_TYPE_NUM); @@ -1718,7 +1673,7 @@ static int pmu_config_term(const struct perf_pmu *pmu, */ } - pmu_format_value(format->bits, val, vp, zero); + perf_pmu__format_pack(format->bits, val, vp, zero); return 0; } @@ -2422,6 +2377,18 @@ bool perf_pmu__is_software(const struct perf_pmu *pmu) return false; } +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu) +{ + if (!pmu) + return true; /* Assume is core. */ + + /* + * All perf event PMUs should benefit from accessing the perf event + * contexts on the local CPU. + */ + return pmu->type <= PERF_PMU_TYPE_PE_END; +} + FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name) { char path[PATH_MAX]; @@ -2765,3 +2732,14 @@ const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config) } return NULL; } + +bool perf_pmu__reads_only_on_cpu_idx0(const struct perf_event_attr *attr) +{ + enum tool_pmu_event event; + + if (attr->type != PERF_PMU_TYPE_TOOL) + return false; + + event = (enum tool_pmu_event)attr->config; + return event != TOOL_PMU__EVENT_USER_TIME && event != TOOL_PMU__EVENT_SYSTEM_TIME; +} diff --git a/tools/perf/util/pmu.h b/tools/perf/util/pmu.h index 8f11bfe8ed6d..0d9f3c57e8e8 100644 --- a/tools/perf/util/pmu.h +++ b/tools/perf/util/pmu.h @@ -233,6 +233,31 @@ struct pmu_event_info { bool deprecated; }; +/** + * struct perf_pmu_format - Values from a format file read from + * /devices/cpu/format/ held in struct perf_pmu. + * + * For example, the contents of /devices/cpu/format/event may be + * "config:0-7" and will be represented here as name="event", + * value=PERF_PMU_FORMAT_VALUE_CONFIG and bits 0 to 7 will be set. + */ +struct perf_pmu_format { + /** @list: Element on list within struct perf_pmu. */ + struct list_head list; + /** @bits: Which config bits are set by this format value. */ + DECLARE_BITMAP(bits, PERF_PMU_FORMAT_BITS); + /** @name: The modifier/file name. */ + char *name; + /** + * @value : Which config value the format relates to. Supported values + * are from PERF_PMU_FORMAT_VALUE_CONFIG to + * PERF_PMU_FORMAT_VALUE_CONFIG_END. + */ + u16 value; + /** @loaded: Has the contents been loaded/parsed. */ + bool loaded; +}; + typedef int (*pmu_event_callback)(void *state, struct pmu_event_info *info); typedef int (*pmu_format_callback)(void *state, const char *name, int config, const unsigned long *bits); @@ -247,16 +272,21 @@ int perf_pmu__config_terms(const struct perf_pmu *pmu, struct parse_events_terms *terms, bool zero, bool apply_hardcoded, struct parse_events_error *error); -__u64 perf_pmu__format_bits(struct perf_pmu *pmu, const char *name); -int perf_pmu__format_type(struct perf_pmu *pmu, const char *name); +__u64 perf_pmu__format_bits(const struct perf_pmu *pmu, const char *name); +int perf_pmu__format_type(const struct perf_pmu *pmu, const char *name); int perf_pmu__check_alias(struct perf_pmu *pmu, struct parse_events_terms *head_terms, struct perf_pmu_info *info, bool *rewrote_terms, u64 *alternate_hw_config, struct parse_events_error *err); int perf_pmu__find_event(struct perf_pmu *pmu, const char *event, void *state, pmu_event_callback cb); +void perf_pmu__format_pack(unsigned long *format, __u64 value, __u64 *v, + bool zero); +struct perf_pmu_format *pmu_find_format(const struct list_head *formats, + const char *name); void perf_pmu_format__set_value(void *format, int config, unsigned long *bits); bool perf_pmu__has_format(const struct perf_pmu *pmu, const char *name); int perf_pmu__for_each_format(struct perf_pmu *pmu, void *state, pmu_format_callback cb); +u64 perf_pmu__format_unpack(unsigned long *format, u64 config_val); bool is_pmu_core(const char *name); bool perf_pmu__supports_legacy_cache(const struct perf_pmu *pmu); @@ -273,6 +303,7 @@ bool perf_pmu__name_no_suffix_match(const struct perf_pmu *pmu, const char *to_m * perf_sw_context in the kernel? */ bool perf_pmu__is_software(const struct perf_pmu *pmu); +bool perf_pmu__benefits_from_affinity(struct perf_pmu *pmu); FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name); FILE *perf_pmu__open_file_at(const struct perf_pmu *pmu, int dirfd, const char *name); @@ -320,6 +351,8 @@ void perf_pmu__delete(struct perf_pmu *pmu); const char *perf_pmu__name_from_config(struct perf_pmu *pmu, u64 config); bool perf_pmu__is_fake(const struct perf_pmu *pmu); +bool perf_pmu__reads_only_on_cpu_idx0(const struct perf_event_attr *attr); + static inline enum pmu_kind perf_pmu__kind(const struct perf_pmu *pmu) { __u32 type; diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index 8f3ed83853a9..cb27e2898aa0 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -86,7 +86,7 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state) strlist__for_each_entry(sdt_name, sdtlist) { bool show_detail = false; - char *bid = strchr(sdt_name->s, '@'); + char *bid = (char *)strchr(sdt_name->s, '@'); char *evt_name = NULL; if (bid) @@ -97,14 +97,9 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state) } else { next_sdt_name = strlist__next(sdt_name); if (next_sdt_name) { - char *bid2 = strchr(next_sdt_name->s, '@'); + const char *bid2 = strchrnul(next_sdt_name->s, '@'); - if (bid2) - *bid2 = '\0'; - if (strcmp(sdt_name->s, next_sdt_name->s) == 0) - show_detail = true; - if (bid2) - *bid2 = '@'; + show_detail = strncmp(sdt_name->s, next_sdt_name->s, bid2 - next_sdt_name->s) == 0; } } last_sdt_name = sdt_name->s; diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c index 5069fb61f48c..f78c3bc3d601 100644 --- a/tools/perf/util/probe-file.c +++ b/tools/perf/util/probe-file.c @@ -28,6 +28,7 @@ #include "session.h" #include "perf_regs.h" #include "string2.h" +#include "dwarf-regs.h" /* 4096 - 2 ('\n' + '\0') */ #define MAX_CMDLEN 4094 @@ -784,7 +785,7 @@ static int synthesize_sdt_probe_arg(struct strbuf *buf, int i, const char *arg) op = desc; } - ret = arch_sdt_arg_parse_op(op, &new_op); + ret = perf_sdt_arg_parse_op(EM_HOST, op, &new_op); if (ret < 0) goto error; diff --git a/tools/perf/util/record.h b/tools/perf/util/record.h index ea3a6c4657ee..93627c9a7338 100644 --- a/tools/perf/util/record.h +++ b/tools/perf/util/record.h @@ -40,6 +40,8 @@ struct record_opts { bool record_cgroup; bool record_switch_events; bool record_switch_events_set; + bool record_data_mmap; + bool record_data_mmap_set; bool all_kernel; bool all_user; bool kernel_callchains; diff --git a/tools/perf/util/sample.c b/tools/perf/util/sample.c index 605fee971f55..8f82aaf1aab6 100644 --- a/tools/perf/util/sample.c +++ b/tools/perf/util/sample.c @@ -1,9 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0 */ #include "sample.h" #include "debug.h" +#include "thread.h" +#include +#ifndef EM_CSKY +#define EM_CSKY 252 +#endif +#ifndef EM_LOONGARCH +#define EM_LOONGARCH 258 +#endif #include #include #include +#include "../../arch/x86/include/asm/insn.h" void perf_sample__init(struct perf_sample *sample, bool all) { @@ -41,3 +50,71 @@ struct regs_dump *perf_sample__intr_regs(struct perf_sample *sample) } return sample->intr_regs; } + +static int elf_machine_max_instruction_length(uint16_t e_machine) +{ + switch (e_machine) { + /* Fixed 4-byte (32-bit) architectures */ + case EM_AARCH64: + case EM_PPC: + case EM_PPC64: + case EM_MIPS: + case EM_SPARC: + case EM_SPARCV9: + case EM_ALPHA: + case EM_LOONGARCH: + case EM_PARISC: + case EM_SH: + return 4; + + /* Variable length or mixed-mode architectures */ + case EM_ARM: /* Variable due to Thumb/Thumb-2 */ + case EM_RISCV: /* Variable due to Compressed (C) extension */ + case EM_CSKY: /* Variable (16 or 32 bit) */ + case EM_ARC: /* Variable (ARCompact) */ + return 4; + case EM_S390: /* Variable (2, 4, or 6 bytes) */ + return 6; + case EM_68K: + return 10; + case EM_386: + case EM_X86_64: + return 15; + case EM_XTENSA: /* Variable (FLIX) */ + return 16; + default: + return MAX_INSN; + } +} + +void perf_sample__fetch_insn(struct perf_sample *sample, + struct thread *thread, + struct machine *machine) +{ + int ret, len; + bool is64bit = false; + uint16_t e_machine; + + if (!sample->ip || sample->insn_len != 0) + return; + + e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL); + len = elf_machine_max_instruction_length(e_machine); + len = thread__memcpy(thread, machine, sample->insn, + sample->ip, len, + &is64bit); + if (len <= 0) + return; + + sample->insn_len = len; + + if (e_machine == EM_386 || e_machine == EM_X86_64) { + /* Refine the x86 instruction length with the decoder. */ + struct insn insn; + + ret = insn_decode(&insn, sample->insn, len, + is64bit ? INSN_MODE_64 : INSN_MODE_32); + if (ret >= 0 && insn.length <= len) + sample->insn_len = insn.length; + } +} diff --git a/tools/perf/util/sample.h b/tools/perf/util/sample.h index a8307b20a9ea..3cce8dd202aa 100644 --- a/tools/perf/util/sample.h +++ b/tools/perf/util/sample.h @@ -5,6 +5,9 @@ #include #include +struct machine; +struct thread; + /* number of register is bound by the number of bits in regs_dump::mask (64) */ #define PERF_SAMPLE_REGS_CACHE_SIZE (8 * sizeof(u64)) @@ -127,6 +130,10 @@ void perf_sample__exit(struct perf_sample *sample); struct regs_dump *perf_sample__user_regs(struct perf_sample *sample); struct regs_dump *perf_sample__intr_regs(struct perf_sample *sample); +void perf_sample__fetch_insn(struct perf_sample *sample, + struct thread *thread, + struct machine *machine); + /* * raw_data is always 4 bytes from an 8-byte boundary, so subtract 4 to get * 8-byte alignment. diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index 6655c0bbe0d8..2b0df7bd9a46 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -50,6 +50,7 @@ #include "../thread-stack.h" #include "../trace-event.h" #include "../call-path.h" +#include "dwarf-regs.h" #include "map.h" #include "symbol.h" #include "thread_map.h" @@ -713,7 +714,8 @@ static void set_sample_datasrc_in_dict(PyObject *dict, _PyUnicode_FromString(decode)); } -static void regs_map(struct regs_dump *regs, uint64_t mask, const char *arch, char *bf, int size) +static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, uint32_t e_flags, + char *bf, int size) { unsigned int i = 0, r; int printed = 0; @@ -731,7 +733,7 @@ static void regs_map(struct regs_dump *regs, uint64_t mask, const char *arch, ch printed += scnprintf(bf + printed, size - printed, "%5s:0x%" PRIx64 " ", - perf_reg_name(r, arch), val); + perf_reg_name(r, e_machine, e_flags), val); } } @@ -739,10 +741,11 @@ static void regs_map(struct regs_dump *regs, uint64_t mask, const char *arch, ch static int set_regs_in_dict(PyObject *dict, struct perf_sample *sample, - struct evsel *evsel) + struct evsel *evsel, + uint16_t e_machine, + uint32_t e_flags) { struct perf_event_attr *attr = &evsel->core.attr; - const char *arch = perf_env__arch(evsel__env(evsel)); int size = (__sw_hweight64(attr->sample_regs_intr) * MAX_REG_SIZE) + 1; char *bf = NULL; @@ -752,7 +755,7 @@ static int set_regs_in_dict(PyObject *dict, if (!bf) return -1; - regs_map(sample->intr_regs, attr->sample_regs_intr, arch, bf, size); + regs_map(sample->intr_regs, attr->sample_regs_intr, e_machine, e_flags, bf, size); pydict_set_item_string_decref(dict, "iregs", _PyUnicode_FromString(bf)); @@ -764,7 +767,7 @@ static int set_regs_in_dict(PyObject *dict, if (!bf) return -1; } - regs_map(sample->user_regs, attr->sample_regs_user, arch, bf, size); + regs_map(sample->user_regs, attr->sample_regs_user, e_machine, e_flags, bf, size); pydict_set_item_string_decref(dict, "uregs", _PyUnicode_FromString(bf)); @@ -834,6 +837,8 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, PyObject *callchain) { PyObject *dict, *dict_sample, *brstack, *brstacksym; + uint16_t e_machine = EM_HOST; + uint32_t e_flags = EF_HOST; dict = PyDict_New(); if (!dict) @@ -920,7 +925,10 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, PyLong_FromUnsignedLongLong(sample->cyc_cnt)); } - if (set_regs_in_dict(dict, sample, evsel)) + if (al->thread) + e_machine = thread__e_machine(al->thread, /*machine=*/NULL, &e_flags); + + if (set_regs_in_dict(dict, sample, evsel, e_machine, e_flags)) Py_FatalError("Failed to setting regs in dict"); return dict; diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 4236503c8f6c..4b465abfa36c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -17,6 +17,7 @@ #include "map_symbol.h" #include "branch.h" #include "debug.h" +#include "dwarf-regs.h" #include "env.h" #include "evlist.h" #include "evsel.h" @@ -697,6 +698,20 @@ static void perf_event__time_conv_swap(union perf_event *event, } } +static void +perf_event__schedstat_cpu_swap(union perf_event *event __maybe_unused, + bool sample_id_all __maybe_unused) +{ + /* FIXME */ +} + +static void +perf_event__schedstat_domain_swap(union perf_event *event __maybe_unused, + bool sample_id_all __maybe_unused) +{ + /* FIXME */ +} + typedef void (*perf_event__swap_op)(union perf_event *event, bool sample_id_all); @@ -736,6 +751,8 @@ static perf_event__swap_op perf_event__swap_ops[] = { [PERF_RECORD_STAT_ROUND] = perf_event__stat_round_swap, [PERF_RECORD_EVENT_UPDATE] = perf_event__event_update_swap, [PERF_RECORD_TIME_CONV] = perf_event__time_conv_swap, + [PERF_RECORD_SCHEDSTAT_CPU] = perf_event__schedstat_cpu_swap, + [PERF_RECORD_SCHEDSTAT_DOMAIN] = perf_event__schedstat_domain_swap, [PERF_RECORD_HEADER_MAX] = NULL, }; @@ -841,6 +858,28 @@ static void callchain__lbr_callstack_printf(struct perf_sample *sample) } } +static const char *callchain_context_str(u64 ip) +{ + switch (ip) { + case PERF_CONTEXT_HV: + return " (PERF_CONTEXT_HV)"; + case PERF_CONTEXT_KERNEL: + return " (PERF_CONTEXT_KERNEL)"; + case PERF_CONTEXT_USER: + return " (PERF_CONTEXT_USER)"; + case PERF_CONTEXT_GUEST: + return " (PERF_CONTEXT_GUEST)"; + case PERF_CONTEXT_GUEST_KERNEL: + return " (PERF_CONTEXT_GUEST_KERNEL)"; + case PERF_CONTEXT_GUEST_USER: + return " (PERF_CONTEXT_GUEST_USER)"; + case PERF_CONTEXT_USER_DEFERRED: + return " (PERF_CONTEXT_USER_DEFERRED)"; + default: + return ""; + } +} + static void callchain__printf(struct evsel *evsel, struct perf_sample *sample) { @@ -853,8 +892,9 @@ static void callchain__printf(struct evsel *evsel, printf("... FP chain: nr:%" PRIu64 "\n", callchain->nr); for (i = 0; i < callchain->nr; i++) - printf("..... %2d: %016" PRIx64 "\n", - i, callchain->ips[i]); + printf("..... %2d: %016" PRIx64 "%s\n", + i, callchain->ips[i], + callchain_context_str(callchain->ips[i])); if (sample->deferred_callchain) printf("...... (deferred)\n"); @@ -919,7 +959,7 @@ static void branch_stack__printf(struct perf_sample *sample, } } -static void regs_dump__printf(u64 mask, u64 *regs, const char *arch) +static void regs_dump__printf(u64 mask, u64 *regs, uint16_t e_machine, uint32_t e_flags) { unsigned rid, i = 0; @@ -927,7 +967,7 @@ static void regs_dump__printf(u64 mask, u64 *regs, const char *arch) u64 val = regs[i++]; printf(".... %-5s 0x%016" PRIx64 "\n", - perf_reg_name(rid, arch), val); + perf_reg_name(rid, e_machine, e_flags), val); } } @@ -945,7 +985,8 @@ static inline const char *regs_dump_abi(struct regs_dump *d) return regs_abi[d->abi]; } -static void regs__printf(const char *type, struct regs_dump *regs, const char *arch) +static void regs__printf(const char *type, struct regs_dump *regs, + uint16_t e_machine, uint32_t e_flags) { u64 mask = regs->mask; @@ -954,10 +995,10 @@ static void regs__printf(const char *type, struct regs_dump *regs, const char *a mask, regs_dump_abi(regs)); - regs_dump__printf(mask, regs->regs, arch); + regs_dump__printf(mask, regs->regs, e_machine, e_flags); } -static void regs_user__printf(struct perf_sample *sample, const char *arch) +static void regs_user__printf(struct perf_sample *sample, uint16_t e_machine, uint32_t e_flags) { struct regs_dump *user_regs; @@ -967,10 +1008,10 @@ static void regs_user__printf(struct perf_sample *sample, const char *arch) user_regs = perf_sample__user_regs(sample); if (user_regs->regs) - regs__printf("user", user_regs, arch); + regs__printf("user", user_regs, e_machine, e_flags); } -static void regs_intr__printf(struct perf_sample *sample, const char *arch) +static void regs_intr__printf(struct perf_sample *sample, uint16_t e_machine, uint32_t e_flags) { struct regs_dump *intr_regs; @@ -980,7 +1021,7 @@ static void regs_intr__printf(struct perf_sample *sample, const char *arch) intr_regs = perf_sample__intr_regs(sample); if (intr_regs->regs) - regs__printf("intr", intr_regs, arch); + regs__printf("intr", intr_regs, e_machine, e_flags); } static void stack_user__printf(struct stack_dump *dump) @@ -1069,21 +1110,29 @@ char *get_page_size_name(u64 size, char *str) return str; } -static void dump_sample(struct evsel *evsel, union perf_event *event, - struct perf_sample *sample, const char *arch) +static void dump_sample(struct machine *machine, struct evsel *evsel, union perf_event *event, + struct perf_sample *sample) { u64 sample_type; char str[PAGE_SIZE_NAME_LEN]; + uint16_t e_machine = EM_NONE; + uint32_t e_flags = 0; if (!dump_trace) return; + sample_type = evsel->core.attr.sample_type; + + if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR)) { + struct thread *thread = machine__find_thread(machine, sample->pid, sample->pid); + + e_machine = thread__e_machine(thread, machine, &e_flags); + } + printf("(IP, 0x%x): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n", event->header.misc, sample->pid, sample->tid, sample->ip, sample->period, sample->addr); - sample_type = evsel->core.attr.sample_type; - if (evsel__has_callchain(evsel)) callchain__printf(evsel, sample); @@ -1091,10 +1140,10 @@ static void dump_sample(struct evsel *evsel, union perf_event *event, branch_stack__printf(sample, evsel); if (sample_type & PERF_SAMPLE_REGS_USER) - regs_user__printf(sample, arch); + regs_user__printf(sample, e_machine, e_flags); if (sample_type & PERF_SAMPLE_REGS_INTR) - regs_intr__printf(sample, arch); + regs_intr__printf(sample, e_machine, e_flags); if (sample_type & PERF_SAMPLE_STACK_USER) stack_user__printf(&sample->user_stack); @@ -1409,10 +1458,10 @@ static int machines__deliver_event(struct machines *machines, } if (machine == NULL) { ++evlist->stats.nr_unprocessable_samples; - dump_sample(evsel, event, sample, perf_env__arch(NULL)); + dump_sample(machine, evsel, event, sample); return 0; } - dump_sample(evsel, event, sample, perf_env__arch(machine->env)); + dump_sample(machine, evsel, event, sample); if (sample->deferred_callchain && tool->merge_deferred_callchains) { struct deferred_event *de = malloc(sizeof(*de)); size_t sz = event->header.size; @@ -1636,6 +1685,12 @@ static s64 perf_session__process_user_event(struct perf_session *session, case PERF_RECORD_BPF_METADATA: err = tool->bpf_metadata(tool, session, event); break; + case PERF_RECORD_SCHEDSTAT_CPU: + err = tool->schedstat_cpu(tool, session, event); + break; + case PERF_RECORD_SCHEDSTAT_DOMAIN: + err = tool->schedstat_domain(tool, session, event); + break; default: err = -EINVAL; break; @@ -2326,9 +2381,10 @@ reader__read_event(struct reader *rd, struct perf_session *session, if (size < sizeof(struct perf_event_header) || (skip = rd->process(session, event, rd->file_pos, rd->path)) < 0) { - pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%s]\n", + errno = -skip; + pr_err("%#" PRIx64 " [%#x]: failed to process type: %d [%m]\n", rd->file_offset + rd->head, event->header.size, - event->header.type, strerror(-skip)); + event->header.type); err = skip; goto out; } @@ -2620,7 +2676,7 @@ bool perf_session__has_switch_events(struct perf_session *session) int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u64 addr) { - char *bracket; + char *bracket, *name; struct ref_reloc_sym *ref; struct kmap *kmap; @@ -2628,13 +2684,13 @@ int map__set_kallsyms_ref_reloc_sym(struct map *map, const char *symbol_name, u6 if (ref == NULL) return -ENOMEM; - ref->name = strdup(symbol_name); + ref->name = name = strdup(symbol_name); if (ref->name == NULL) { free(ref); return -ENOMEM; } - bracket = strchr(ref->name, ']'); + bracket = strchr(name, ']'); if (bracket) *bracket = '\0'; @@ -2674,11 +2730,14 @@ size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp) size_t perf_session__fprintf(struct perf_session *session, FILE *fp) { - /* - * FIXME: Here we have to actually print all the machines in this - * session, not just the host... - */ - return machine__fprintf(&session->machines.host, fp); + size_t ret = machine__fprintf(&session->machines.host, fp); + + for (struct rb_node *nd = rb_first_cached(&session->machines.guests); nd; nd = rb_next(nd)) { + struct machine *pos = rb_entry(nd, struct machine, rb_node); + + ret += machine__fprintf(pos, fp); + } + return ret; } void perf_session__dump_kmaps(struct perf_session *session) @@ -2904,3 +2963,68 @@ struct perf_env *perf_session__env(struct perf_session *session) { return &session->header.env; } + +struct perf_session__e_machine_cb_args { + uint32_t e_flags; + uint16_t e_machine; +}; + +static int perf_session__e_machine_cb(struct thread *thread, void *_args) +{ + struct perf_session__e_machine_cb_args *args = _args; + + args->e_machine = thread__e_machine(thread, /*machine=*/NULL, &args->e_flags); + return args->e_machine != EM_NONE ? 1 : 0; +} + +/* + * Note, a machine may have mixed 32-bit and 64-bit processes and so mixed + * e_machines. Use thread__e_machine when this matters. + */ +uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags) +{ + struct perf_session__e_machine_cb_args args = { + .e_machine = EM_NONE, + }; + struct perf_env *env; + + if (!session) { + /* Default to assuming a host machine. */ + if (e_flags) + *e_flags = EF_HOST; + + return EM_HOST; + } + + env = perf_session__env(session); + if (env && env->e_machine != EM_NONE) { + if (e_flags) + *e_flags = env->e_flags; + + return env->e_machine; + } + + machines__for_each_thread(&session->machines, + perf_session__e_machine_cb, + &args); + + if (args.e_machine != EM_NONE) { + if (env) { + env->e_machine = args.e_machine; + env->e_flags = args.e_flags; + } + if (e_flags) + *e_flags = args.e_flags; + + return args.e_machine; + } + + /* + * Couldn't determine from the perf_env or current set of + * threads. Default to the host. + */ + if (e_flags) + *e_flags = EF_HOST; + + return EM_HOST; +} diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 22d3ff877e83..f05f0d4a6c23 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -211,5 +211,6 @@ int perf_event__process_finished_round(const struct perf_tool *tool, struct ordered_events *oe); struct perf_env *perf_session__env(struct perf_session *session); +uint16_t perf_session__e_machine(struct perf_session *session, uint32_t *e_flags); #endif /* __PERF_SESSION_H */ diff --git a/tools/perf/util/sha1.c b/tools/perf/util/sha1.c deleted file mode 100644 index 7032fa4ff3fd..000000000000 --- a/tools/perf/util/sha1.c +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * SHA-1 message digest algorithm - * - * Copyright 2025 Google LLC - */ -#include -#include -#include -#include - -#include "sha1.h" - -#define SHA1_BLOCK_SIZE 64 - -static const u32 sha1_K[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 }; - -#define SHA1_ROUND(i, a, b, c, d, e) \ - do { \ - if ((i) >= 16) \ - w[i] = rol32(w[(i) - 16] ^ w[(i) - 14] ^ w[(i) - 8] ^ \ - w[(i) - 3], \ - 1); \ - e += w[i] + rol32(a, 5) + sha1_K[(i) / 20]; \ - if ((i) < 20) \ - e += (b & (c ^ d)) ^ d; \ - else if ((i) < 40 || (i) >= 60) \ - e += b ^ c ^ d; \ - else \ - e += (c & d) ^ (b & (c ^ d)); \ - b = rol32(b, 30); \ - /* The new (a, b, c, d, e) is the old (e, a, b, c, d). */ \ - } while (0) - -#define SHA1_5ROUNDS(i) \ - do { \ - SHA1_ROUND((i) + 0, a, b, c, d, e); \ - SHA1_ROUND((i) + 1, e, a, b, c, d); \ - SHA1_ROUND((i) + 2, d, e, a, b, c); \ - SHA1_ROUND((i) + 3, c, d, e, a, b); \ - SHA1_ROUND((i) + 4, b, c, d, e, a); \ - } while (0) - -#define SHA1_20ROUNDS(i) \ - do { \ - SHA1_5ROUNDS((i) + 0); \ - SHA1_5ROUNDS((i) + 5); \ - SHA1_5ROUNDS((i) + 10); \ - SHA1_5ROUNDS((i) + 15); \ - } while (0) - -static void sha1_blocks(u32 h[5], const u8 *data, size_t nblocks) -{ - while (nblocks--) { - u32 a = h[0]; - u32 b = h[1]; - u32 c = h[2]; - u32 d = h[3]; - u32 e = h[4]; - u32 w[80]; - - for (int i = 0; i < 16; i++) - w[i] = get_unaligned_be32(&data[i * 4]); - SHA1_20ROUNDS(0); - SHA1_20ROUNDS(20); - SHA1_20ROUNDS(40); - SHA1_20ROUNDS(60); - - h[0] += a; - h[1] += b; - h[2] += c; - h[3] += d; - h[4] += e; - data += SHA1_BLOCK_SIZE; - } -} - -/* Calculate the SHA-1 message digest of the given data. */ -void sha1(const void *data, size_t len, u8 out[SHA1_DIGEST_SIZE]) -{ - u32 h[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, - 0xC3D2E1F0 }; - u8 final_data[2 * SHA1_BLOCK_SIZE] = { 0 }; - size_t final_len = len % SHA1_BLOCK_SIZE; - - sha1_blocks(h, data, len / SHA1_BLOCK_SIZE); - - memcpy(final_data, data + len - final_len, final_len); - final_data[final_len] = 0x80; - final_len = round_up(final_len + 9, SHA1_BLOCK_SIZE); - put_unaligned_be64((u64)len * 8, &final_data[final_len - 8]); - - sha1_blocks(h, final_data, final_len / SHA1_BLOCK_SIZE); - - for (int i = 0; i < 5; i++) - put_unaligned_be32(h[i], &out[i * 4]); -} diff --git a/tools/perf/util/sha1.h b/tools/perf/util/sha1.h deleted file mode 100644 index e92c9966e1d5..000000000000 --- a/tools/perf/util/sha1.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#include - -#define SHA1_DIGEST_SIZE 20 - -void sha1(const void *data, size_t len, u8 out[SHA1_DIGEST_SIZE]); diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index f3a565b0e230..42d5cd7ef4e2 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -1016,7 +1016,7 @@ static int hist_entry__cgroup_snprintf(struct hist_entry *he, const char *cgrp_name = "N/A"; if (he->cgroup) { - struct cgroup *cgrp = cgroup__find(maps__machine(he->ms.maps)->env, + struct cgroup *cgrp = cgroup__find(maps__machine(thread__maps(he->ms.thread))->env, he->cgroup); if (cgrp != NULL) cgrp_name = cgrp->name; @@ -2474,8 +2474,7 @@ struct sort_entry sort_type_offset = { /* --sort typecln */ -/* TODO: use actual value in the system */ -#define TYPE_CACHELINE_SIZE 64 +#define DEFAULT_CACHELINE_SIZE 64 static int64_t sort__typecln_sort(struct hist_entry *left, struct hist_entry *right) @@ -2484,6 +2483,10 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right) struct annotated_data_type *right_type = right->mem_type; int64_t left_cln, right_cln; int64_t ret; + int cln_size = cacheline_size(); + + if (cln_size == 0) + cln_size = DEFAULT_CACHELINE_SIZE; if (!left_type) { sort__type_init(left); @@ -2499,8 +2502,8 @@ sort__typecln_sort(struct hist_entry *left, struct hist_entry *right) if (ret) return ret; - left_cln = left->mem_type_off / TYPE_CACHELINE_SIZE; - right_cln = right->mem_type_off / TYPE_CACHELINE_SIZE; + left_cln = left->mem_type_off / cln_size; + right_cln = right->mem_type_off / cln_size; return left_cln - right_cln; } @@ -2508,9 +2511,13 @@ static int hist_entry__typecln_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width __maybe_unused) { struct annotated_data_type *he_type = he->mem_type; + int cln_size = cacheline_size(); + + if (cln_size == 0) + cln_size = DEFAULT_CACHELINE_SIZE; return repsep_snprintf(bf, size, "%s: cache-line %d", he_type->self.type_name, - he->mem_type_off / TYPE_CACHELINE_SIZE); + he->mem_type_off / cln_size); } struct sort_entry sort_type_cacheline = { @@ -3538,6 +3545,56 @@ static int add_dynamic_entry(struct evlist *evlist, const char *tok, return ret; } +static int __sort_dimension__update(struct sort_dimension *sd, + struct perf_hpp_list *list) +{ + if (sd->entry == &sort_parent && parent_pattern) { + int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED); + if (ret) { + char err[BUFSIZ]; + + regerror(ret, &parent_regex, err, sizeof(err)); + pr_err("Invalid regex: %s\n%s", parent_pattern, err); + return -EINVAL; + } + list->parent = 1; + } else if (sd->entry == &sort_sym) { + list->sym = 1; + /* + * perf diff displays the performance difference amongst + * two or more perf.data files. Those files could come + * from different binaries. So we should not compare + * their ips, but the name of symbol. + */ + if (sort__mode == SORT_MODE__DIFF) + sd->entry->se_collapse = sort__sym_sort; + + } else if (sd->entry == &sort_sym_offset) { + list->sym = 1; + } else if (sd->entry == &sort_dso) { + list->dso = 1; + } else if (sd->entry == &sort_socket) { + list->socket = 1; + } else if (sd->entry == &sort_thread) { + list->thread = 1; + } else if (sd->entry == &sort_comm) { + list->comm = 1; + } else if (sd->entry == &sort_type_offset) { + symbol_conf.annotate_data_member = true; + } else if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) { + list->sym = 1; + } else if (sd->entry == &sort_mem_dcacheline && cacheline_size() == 0) { + return -EINVAL; + } else if (sd->entry == &sort_mem_daddr_sym) { + list->sym = 1; + } + + if (sd->entry->se_collapse) + list->need_collapse = 1; + + return 0; +} + static int __sort_dimension__add(struct sort_dimension *sd, struct perf_hpp_list *list, int level) @@ -3548,8 +3605,8 @@ static int __sort_dimension__add(struct sort_dimension *sd, if (__sort_dimension__add_hpp_sort(sd, list, level) < 0) return -1; - if (sd->entry->se_collapse) - list->need_collapse = 1; + if (__sort_dimension__update(sd, list) < 0) + return -1; sd->taken = 1; @@ -3585,6 +3642,9 @@ static int __sort_dimension__add_output(struct perf_hpp_list *list, if (__sort_dimension__add_hpp_output(sd, list, level) < 0) return -1; + if (__sort_dimension__update(sd, list) < 0) + return -1; + sd->taken = 1; return 0; } @@ -3648,39 +3708,6 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, sort_dimension_add_dynamic_header(sd, env); } - if (sd->entry == &sort_parent && parent_pattern) { - int ret = regcomp(&parent_regex, parent_pattern, REG_EXTENDED); - if (ret) { - char err[BUFSIZ]; - - regerror(ret, &parent_regex, err, sizeof(err)); - pr_err("Invalid regex: %s\n%s", parent_pattern, err); - return -EINVAL; - } - list->parent = 1; - } else if (sd->entry == &sort_sym) { - list->sym = 1; - /* - * perf diff displays the performance difference amongst - * two or more perf.data files. Those files could come - * from different binaries. So we should not compare - * their ips, but the name of symbol. - */ - if (sort__mode == SORT_MODE__DIFF) - sd->entry->se_collapse = sort__sym_sort; - - } else if (sd->entry == &sort_dso) { - list->dso = 1; - } else if (sd->entry == &sort_socket) { - list->socket = 1; - } else if (sd->entry == &sort_thread) { - list->thread = 1; - } else if (sd->entry == &sort_comm) { - list->comm = 1; - } else if (sd->entry == &sort_type_offset) { - symbol_conf.annotate_data_member = true; - } - return __sort_dimension__add(sd, list, level); } @@ -3699,9 +3726,6 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, strlen(tok))) return -EINVAL; - if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) - list->sym = 1; - __sort_dimension__add(sd, list, level); return 0; } @@ -3715,12 +3739,6 @@ int sort_dimension__add(struct perf_hpp_list *list, const char *tok, if (sort__mode != SORT_MODE__MEMORY) return -EINVAL; - if (sd->entry == &sort_mem_dcacheline && cacheline_size() == 0) - return -EINVAL; - - if (sd->entry == &sort_mem_daddr_sym) - list->sym = 1; - __sort_dimension__add(sd, list, level); return 0; } diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 27c0966611ab..9be42f398440 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -6,9 +6,12 @@ #include "libbfd.h" #include "llvm.h" #include "symbol.h" +#include "libdw.h" +#include "debug.h" #include #include +#include bool srcline_full_filename; @@ -51,6 +54,25 @@ int inline_list__append(struct symbol *symbol, char *srcline, struct inline_node return 0; } +int inline_list__append_tail(struct symbol *symbol, char *srcline, struct inline_node *node) +{ + struct inline_list *ilist; + + ilist = zalloc(sizeof(*ilist)); + if (ilist == NULL) + return -1; + + ilist->symbol = symbol; + ilist->srcline = srcline; + + if (callchain_param.order == ORDER_CALLEE) + list_add(&ilist->list, &node->val); + else + list_add_tail(&ilist->list, &node->val); + + return 0; +} + /* basename version that takes a const input string */ static const char *gnu_basename(const char *path) { @@ -118,17 +140,95 @@ static int addr2line(const char *dso_name, u64 addr, char **file, unsigned int * struct dso *dso, bool unwind_inlines, struct inline_node *node, struct symbol *sym) { - int ret; + int ret = 0; - ret = llvm__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, node, sym); - if (ret > 0) - return ret; + if (symbol_conf.addr2line_style[0] == A2L_STYLE_UNKNOWN) { + int i = 0; - ret = libbfd__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, node, sym); - if (ret > 0) - return ret; + /* Default addr2line fallback order. */ +#ifdef HAVE_LIBDW_SUPPORT + symbol_conf.addr2line_style[i++] = A2L_STYLE_LIBDW; +#endif +#ifdef HAVE_LIBLLVM_SUPPORT + symbol_conf.addr2line_style[i++] = A2L_STYLE_LLVM; +#endif +#ifdef HAVE_LIBBFD_SUPPORT + symbol_conf.addr2line_style[i++] = A2L_STYLE_LIBBFD; +#endif + symbol_conf.addr2line_style[i++] = A2L_STYLE_CMD; + } - return cmd__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, node, sym); + for (size_t i = 0; i < ARRAY_SIZE(symbol_conf.addr2line_style); i++) { + switch (symbol_conf.addr2line_style[i]) { + case A2L_STYLE_LIBDW: + ret = libdw__addr2line(addr, file, line_nr, dso, unwind_inlines, + node, sym); + break; + case A2L_STYLE_LLVM: + ret = llvm__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, + node, sym); + break; + case A2L_STYLE_LIBBFD: + ret = libbfd__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, + node, sym); + break; + case A2L_STYLE_CMD: + ret = cmd__addr2line(dso_name, addr, file, line_nr, dso, unwind_inlines, + node, sym); + break; + case A2L_STYLE_UNKNOWN: + default: + break; + } + if (ret > 0) + return ret; + } + + return 0; +} + +int addr2line_configure(const char *var, const char *value, void *cb __maybe_unused) +{ + static const char * const a2l_style_names[] = { + [A2L_STYLE_LIBDW] = "libdw", + [A2L_STYLE_LLVM] = "llvm", + [A2L_STYLE_LIBBFD] = "libbfd", + [A2L_STYLE_CMD] = "addr2line", + NULL + }; + + char *s, *p, *saveptr; + size_t i = 0; + + if (strcmp(var, "addr2line.style")) + return 0; + + if (!value) + return -1; + + s = strdup(value); + if (!s) + return -1; + + p = strtok_r(s, ",", &saveptr); + while (p && i < ARRAY_SIZE(symbol_conf.addr2line_style)) { + bool found = false; + char *q = strim(p); + + for (size_t j = A2L_STYLE_LIBDW; j < MAX_A2L_STYLE; j++) { + if (!strcasecmp(q, a2l_style_names[j])) { + symbol_conf.addr2line_style[i++] = j; + found = true; + break; + } + } + if (!found) + pr_warning("Unknown addr2line style: %s\n", q); + p = strtok_r(NULL, ",", &saveptr); + } + + free(s); + return 0; } static struct inline_node *addr2inlines(const char *dso_name, u64 addr, diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h index c36f573cd339..7c37b3bf9ce7 100644 --- a/tools/perf/util/srcline.h +++ b/tools/perf/util/srcline.h @@ -57,9 +57,12 @@ struct inline_node *inlines__tree_find(struct rb_root_cached *tree, u64 addr); void inlines__tree_delete(struct rb_root_cached *tree); int inline_list__append(struct symbol *symbol, char *srcline, struct inline_node *node); +int inline_list__append_tail(struct symbol *symbol, char *srcline, struct inline_node *node); char *srcline_from_fileline(const char *file, unsigned int line); struct symbol *new_inline_sym(struct dso *dso, struct symbol *base_sym, const char *funcname); +int addr2line_configure(const char *var, const char *value, void *cb); + #endif /* PERF_SRCLINE_H */ diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index 6d02f84c5691..dc2b66855f6c 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -820,12 +820,6 @@ static void printout(struct perf_stat_config *config, struct outstate *os, } if (run == 0 || ena == 0 || counter->counts->scaled == -1) { - if (config->metric_only) { - pm(config, os, METRIC_THRESHOLD_UNKNOWN, /*format=*/NULL, - /*unit=*/NULL, /*val=*/0); - return; - } - ok = false; if (counter->supported) { @@ -848,33 +842,32 @@ static void printout(struct perf_stat_config *config, struct outstate *os, print_running(config, os, run, ena, /*before_metric=*/true); } - if (ok) { - if (!config->metric_only && counter->default_metricgroup && !counter->default_show_events) { - void *from = NULL; + if (!config->metric_only && counter->default_metricgroup && + !counter->default_show_events) { + void *from = NULL; - aggr_printout(config, os, os->evsel, os->id, os->aggr_nr); - /* Print out all the metricgroup with the same metric event. */ - do { - int num = 0; + aggr_printout(config, os, os->evsel, os->id, os->aggr_nr); + /* Print out all the metricgroup with the same metric event. */ + do { + int num = 0; - /* Print out the new line for the next new metricgroup. */ - if (from) { - if (config->json_output) - new_line_json(config, (void *)os); - else - __new_line_std_csv(config, os); - } + /* Print out the new line for the next new metricgroup. */ + if (from) { + if (config->json_output) + new_line_json(config, (void *)os); + else + __new_line_std_csv(config, os); + } - print_noise(config, os, counter, noise, /*before_metric=*/true); - print_running(config, os, run, ena, /*before_metric=*/true); - from = perf_stat__print_shadow_stats_metricgroup(config, counter, aggr_idx, - &num, from, &out); - } while (from != NULL); - } else { - perf_stat__print_shadow_stats(config, counter, aggr_idx, &out); - } + print_noise(config, os, counter, noise, + /*before_metric=*/true); + print_running(config, os, run, ena, + /*before_metric=*/true); + from = perf_stat__print_shadow_stats_metricgroup( + config, counter, aggr_idx, &num, from, &out); + } while (from != NULL); } else { - pm(config, os, METRIC_THRESHOLD_UNKNOWN, /*format=*/NULL, /*unit=*/NULL, /*val=*/0); + perf_stat__print_shadow_stats(config, counter, aggr_idx, &out); } if (!config->metric_only) { @@ -987,7 +980,7 @@ static void print_counter_aggrdata(struct perf_stat_config *config, ena = aggr->counts.ena; run = aggr->counts.run; - if (perf_stat__skip_metric_event(counter, ena, run)) + if (perf_stat__skip_metric_event(counter)) return; if (val == 0 && should_skip_zero_counter(config, counter, &id)) @@ -1397,21 +1390,12 @@ static void print_header(struct perf_stat_config *config, num_print_iv = 0; } -static int get_precision(double num) -{ - if (num > 1) - return 0; - - return lround(ceil(-log10(num))); -} - -static void print_table(struct perf_stat_config *config, - FILE *output, int precision, double avg) +static void print_table(struct perf_stat_config *config, FILE *output, double avg) { char tmp[64]; int idx, indent = 0; - scnprintf(tmp, 64, " %17.*f", precision, avg); + scnprintf(tmp, 64, " %17.9f", avg); while (tmp[indent] == ' ') indent++; @@ -1421,8 +1405,7 @@ static void print_table(struct perf_stat_config *config, double run = (double) config->walltime_run[idx] / NSEC_PER_SEC; int h, n = 1 + abs((int) (100.0 * (run - avg)/run) / 5); - fprintf(output, " %17.*f (%+.*f) ", - precision, run, precision, run - avg); + fprintf(output, " %17.9f (%+.9f) ", run, run - avg); for (h = 0; h < n; h++) fprintf(output, "#"); @@ -1462,17 +1445,11 @@ static void print_footer(struct perf_stat_config *config) } } else { double sd = stddev_stats(config->walltime_nsecs_stats) / NSEC_PER_SEC; - /* - * Display at most 2 more significant - * digits than the stddev inaccuracy. - */ - int precision = get_precision(sd) + 2; if (config->walltime_run_table) - print_table(config, output, precision, avg); + print_table(config, output, avg); - fprintf(output, " %17.*f +- %.*f seconds time elapsed", - precision, avg, precision, sd); + fprintf(output, " %17.9f +- %.9f seconds time elapsed", avg, sd); print_noise_pct(config, NULL, sd, avg, /*before_metric=*/false); } diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index 9c83f7d96caa..59d2cd4f2188 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -57,7 +57,6 @@ static int prepare_metric(struct perf_stat_config *config, bool is_tool_time = tool_pmu__is_time_event(config, metric_events[i], &tool_aggr_idx); struct perf_stat_evsel *ps = metric_events[i]->stats; - struct perf_stat_aggr *aggr; char *n; double val; @@ -82,8 +81,7 @@ static int prepare_metric(struct perf_stat_config *config, } } /* Time events are always on CPU0, the first aggregation index. */ - aggr = &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; - if (!aggr || !metric_events[i]->supported) { + if (!ps || !metric_events[i]->supported) { /* * Not supported events will have a count of 0, which * can be confusing in a metric. Explicitly set the @@ -93,11 +91,21 @@ static int prepare_metric(struct perf_stat_config *config, val = NAN; source_count = 0; } else { - val = aggr->counts.val; - if (is_tool_time) - val *= 1e-9; /* Convert time event nanoseconds to seconds. */ - if (!source_count) - source_count = evsel__source_count(metric_events[i]); + struct perf_stat_aggr *aggr = + &ps->aggr[is_tool_time ? tool_aggr_idx : aggr_idx]; + + if (aggr->counts.run == 0) { + val = NAN; + source_count = 0; + } else { + val = aggr->counts.val; + if (is_tool_time) { + /* Convert time event nanoseconds to seconds. */ + val *= 1e-9; + } + if (!source_count) + source_count = evsel__source_count(metric_events[i]); + } } n = strdup(evsel__metric_id(metric_events[i])); if (!n) @@ -335,14 +343,10 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, * perf_stat__skip_metric_event - Skip the evsel in the Default metricgroup, * if it's not running or not the metric event. */ -bool perf_stat__skip_metric_event(struct evsel *evsel, - u64 ena, u64 run) +bool perf_stat__skip_metric_event(struct evsel *evsel) { if (!evsel->default_metricgroup) return false; - if (!ena || !run) - return true; - return !metricgroup__lookup(&evsel->evlist->metric_events, evsel, false); } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index f986911c9296..4bced233d2fc 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -163,7 +163,7 @@ void perf_stat__print_shadow_stats(struct perf_stat_config *config, struct evsel *evsel, int aggr_idx, struct perf_stat_output_ctx *out); -bool perf_stat__skip_metric_event(struct evsel *evsel, u64 ena, u64 run); +bool perf_stat__skip_metric_event(struct evsel *evsel); void *perf_stat__print_shadow_stats_metricgroup(struct perf_stat_config *config, struct evsel *evsel, int aggr_idx, diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index 8a868cbeffae..50add72575e0 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c @@ -12,20 +12,16 @@ #include static -struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) +struct rb_node *strlist__node_new(struct rblist *rblist __maybe_unused, const void *entry) { const char *s = entry; struct rb_node *rc = NULL; - struct strlist *strlist = container_of(rblist, struct strlist, rblist); struct str_node *snode = malloc(sizeof(*snode)); if (snode != NULL) { - if (strlist->dupstr) { - s = strdup(s); - if (s == NULL) - goto out_delete; - } - snode->s = s; + snode->s = strdup(s); + if (snode->s == NULL) + goto out_delete; rc = &snode->rb_node; } @@ -36,20 +32,18 @@ struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) return NULL; } -static void str_node__delete(struct str_node *snode, bool dupstr) +static void str_node__delete(struct str_node *snode) { - if (dupstr) - zfree((char **)&snode->s); + zfree((char **)&snode->s); free(snode); } static -void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node) +void strlist__node_delete(struct rblist *rblist __maybe_unused, struct rb_node *rb_node) { - struct strlist *slist = container_of(rblist, struct strlist, rblist); struct str_node *snode = container_of(rb_node, struct str_node, rb_node); - str_node__delete(snode, slist->dupstr); + str_node__delete(snode); } static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) @@ -139,21 +133,25 @@ static int strlist__parse_list_entry(struct strlist *slist, const char *s, return err; } -static int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir) +static int strlist__parse_list(struct strlist *slist, const char *list, const char *subst_dir) { - char *sep; + char *sep, *s = strdup(list), *sdup = s; int err; + if (s == NULL) + return -ENOMEM; + while ((sep = strchr(s, ',')) != NULL) { *sep = '\0'; err = strlist__parse_list_entry(slist, s, subst_dir); - *sep = ','; if (err != 0) return err; s = sep + 1; } - return *s ? strlist__parse_list_entry(slist, s, subst_dir) : 0; + err = *s ? strlist__parse_list_entry(slist, s, subst_dir) : 0; + free(sdup); + return err; } struct strlist *strlist__new(const char *list, const struct strlist_config *config) @@ -161,12 +159,10 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf struct strlist *slist = malloc(sizeof(*slist)); if (slist != NULL) { - bool dupstr = true; bool file_only = false; const char *dirname = NULL; if (config) { - dupstr = !config->dont_dupstr; dirname = config->dirname; file_only = config->file_only; } @@ -176,7 +172,6 @@ struct strlist *strlist__new(const char *list, const struct strlist_config *conf slist->rblist.node_new = strlist__node_new; slist->rblist.node_delete = strlist__node_delete; - slist->dupstr = dupstr; slist->file_only = file_only; if (list && strlist__parse_list(slist, list, dirname) != 0) diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 7e82c71dcc42..3e9533e66ca9 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h @@ -14,7 +14,6 @@ struct str_node { struct strlist { struct rblist rblist; - bool dupstr; bool file_only; }; @@ -24,7 +23,6 @@ struct strlist { * found */ struct strlist_config { - bool dont_dupstr; bool file_only; const char *dirname; }; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index d1dcafa4b3b8..76912c62b6a0 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -1105,14 +1105,14 @@ static Elf *read_gnu_debugdata(struct dso *dso, Elf *elf, const char *name, int wrapped = fmemopen(scn_data->d_buf, scn_data->d_size, "r"); if (!wrapped) { - pr_debug("%s: fmemopen: %s\n", __func__, strerror(errno)); + pr_debug("%s: fmemopen: %m\n", __func__); *dso__load_errno(dso) = -errno; return NULL; } temp_fd = mkstemp(temp_filename); if (temp_fd < 0) { - pr_debug("%s: mkstemp: %s\n", __func__, strerror(errno)); + pr_debug("%s: mkstemp: %m\n", __func__); *dso__load_errno(dso) = -errno; fclose(wrapped); return NULL; @@ -1173,7 +1173,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name, Elf *embedded = read_gnu_debugdata(dso, elf, name, &new_fd); if (!embedded) - goto out_close; + goto out_elf_end; elf_end(elf); close(fd); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 814f960fa8f8..8662001e1e25 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -104,21 +104,10 @@ static enum dso_binary_type binary_type_symtab[] = { #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) -static bool symbol_type__filter(char __symbol_type) +static bool symbol_type__filter(char symbol_type) { - // Since 'U' == undefined and 'u' == unique global symbol, we can't use toupper there - // 'N' is for debugging symbols, 'n' is a non-data, non-code, non-debug read-only section. - // According to 'man nm'. - // 'N' first seen in: - // ffffffff9b35d130 N __pfx__RNCINvNtNtNtCsbDUBuN8AbD4_4core4iter8adapters3map12map_try_foldjNtCs6vVzKs5jPr6_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ - // a seemingly Rust mangled name - // Ditto for '1': - // root@x1:~# grep ' 1 ' /proc/kallsyms - // ffffffffb098bc00 1 __pfx__RNCINvNtNtNtCsfwaGRd4cjqE_4core4iter8adapters3map12map_try_foldjNtCskFudTml27HW_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ - // ffffffffb098bc10 1 _RNCINvNtNtNtCsfwaGRd4cjqE_4core4iter8adapters3map12map_try_foldjNtCskFudTml27HW_12drm_panic_qr7VersionuINtNtNtBa_3ops12control_flow11ControlFlowB10_ENcB10_0NCINvNvNtNtNtB8_6traits8iterator8Iterator4find5checkB10_NCNvMB12_B10_13from_segments0E0E0B12_ - char symbol_type = toupper(__symbol_type); - return symbol_type == 'T' || symbol_type == 'W' || symbol_type == 'D' || symbol_type == 'B' || - __symbol_type == 'u' || __symbol_type == 'l' || __symbol_type == 'N' || __symbol_type == '1'; + symbol_type = toupper(symbol_type); + return symbol_type == 'T' || symbol_type == 'W' || symbol_type == 'D' || symbol_type == 'B'; } static int prefix_underscores_count(const char *str) diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h index 7a80d2c14d9b..71bb17372a6c 100644 --- a/tools/perf/util/symbol_conf.h +++ b/tools/perf/util/symbol_conf.h @@ -9,6 +9,15 @@ struct strlist; struct intlist; +enum a2l_style { + A2L_STYLE_UNKNOWN = 0, + A2L_STYLE_LIBDW, + A2L_STYLE_LLVM, + A2L_STYLE_LIBBFD, + A2L_STYLE_CMD, +}; +#define MAX_A2L_STYLE (A2L_STYLE_CMD + 1) + struct symbol_conf { bool nanosecs; unsigned short priv_size; @@ -70,6 +79,7 @@ struct symbol_conf { *col_width_list_str, *bt_stop_list_str; const char *addr2line_path; + enum a2l_style addr2line_style[MAX_A2L_STYLE]; unsigned long time_quantum; struct strlist *dso_list, *comm_list, diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index 2ba9fa25e00a..ddf1cbda1902 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -703,6 +703,11 @@ static int perf_event__synthesize_modules_maps_cb(struct map *map, void *data) memcpy(event->mmap2.filename, dso__long_name(dso), dso__long_name_len(dso) + 1); + /* Clear stale build ID from previous module iteration */ + event->mmap2.header.misc &= ~PERF_RECORD_MISC_MMAP_BUILD_ID; + memset(event->mmap2.build_id, 0, sizeof(event->mmap2.build_id)); + event->mmap2.build_id_size = 0; + perf_record_mmap2__read_build_id(&event->mmap2, args->machine, false); } else { size = PERF_ALIGN(dso__long_name_len(dso) + 1, sizeof(u64)); @@ -2529,3 +2534,199 @@ int parse_synth_opt(char *synth) return ret; } + +static union perf_event *__synthesize_schedstat_cpu(struct io *io, __u16 version, + __u64 *cpu, __u64 timestamp) +{ + struct perf_record_schedstat_cpu *cs; + union perf_event *event; + size_t size; + char ch; + + size = sizeof(*cs); + size = PERF_ALIGN(size, sizeof(u64)); + event = zalloc(size); + + if (!event) + return NULL; + + cs = &event->schedstat_cpu; + cs->header.type = PERF_RECORD_SCHEDSTAT_CPU; + cs->header.size = size; + cs->timestamp = timestamp; + + if (io__get_char(io) != 'p' || io__get_char(io) != 'u') + goto out_cpu; + + if (io__get_dec(io, (__u64 *)cpu) != ' ') + goto out_cpu; + +#define CPU_FIELD(_type, _name, _desc, _format, _is_pct, _pct_of, _ver) \ + do { \ + __u64 _tmp; \ + ch = io__get_dec(io, &_tmp); \ + if (ch != ' ' && ch != '\n') \ + goto out_cpu; \ + cs->_ver._name = _tmp; \ + } while (0) + + if (version == 15) { +#include + } else if (version == 16) { +#include + } else if (version == 17) { +#include + } +#undef CPU_FIELD + + cs->cpu = *cpu; + cs->version = version; + + return event; +out_cpu: + free(event); + return NULL; +} + +static union perf_event *__synthesize_schedstat_domain(struct io *io, __u16 version, + __u64 cpu, __u64 timestamp) +{ + struct perf_record_schedstat_domain *ds; + union perf_event *event = NULL; + __u64 d_num; + size_t size; + char ch; + + if (io__get_char(io) != 'o' || io__get_char(io) != 'm' || io__get_char(io) != 'a' || + io__get_char(io) != 'i' || io__get_char(io) != 'n') + return NULL; + + ch = io__get_dec(io, &d_num); + if (version >= 17) { + /* Skip domain name as it can be extracted from perf header */ + while (io__get_char(io) != ' ') + continue; + } + + /* Skip cpumask as it can be extracted from perf header */ + while (io__get_char(io) != ' ') + continue; + + size = sizeof(*ds); + size = PERF_ALIGN(size, sizeof(u64)); + event = zalloc(size); + + ds = &event->schedstat_domain; + ds->header.type = PERF_RECORD_SCHEDSTAT_DOMAIN; + ds->header.size = size; + ds->version = version; + ds->timestamp = timestamp; + ds->domain = d_num; + +#define DOMAIN_FIELD(_type, _name, _desc, _format, _is_jiffies, _ver) \ + do { \ + __u64 _tmp; \ + ch = io__get_dec(io, &_tmp); \ + if (ch != ' ' && ch != '\n') \ + goto out_domain; \ + ds->_ver._name = _tmp; \ + } while (0) + + if (version == 15) { +#include + } else if (version == 16) { +#include + } else if (version == 17) { +#include + } +#undef DOMAIN_FIELD + + ds->cpu = cpu; + goto out; + +out_domain: + free(event); + event = NULL; +out: + return event; +} + +int perf_event__synthesize_schedstat(const struct perf_tool *tool, + perf_event__handler_t process, + struct perf_cpu_map *user_requested_cpus) +{ + char *line = NULL, path[PATH_MAX]; + union perf_event *event = NULL; + size_t line_len = 0; + char bf[BUFSIZ]; + __u64 timestamp; + __u64 cpu = -1; + __u16 version; + struct io io; + int ret = -1; + char ch; + + snprintf(path, PATH_MAX, "%s/schedstat", procfs__mountpoint()); + io.fd = open(path, O_RDONLY, 0); + if (io.fd < 0) { + pr_err("Failed to open %s. Possibly CONFIG_SCHEDSTAT is disabled.\n", path); + return -1; + } + io__init(&io, io.fd, bf, sizeof(bf)); + + if (io__getline(&io, &line, &line_len) < 0 || !line_len) + goto out; + + if (!strcmp(line, "version 15\n")) { + version = 15; + } else if (!strcmp(line, "version 16\n")) { + version = 16; + } else if (!strcmp(line, "version 17\n")) { + version = 17; + } else { + pr_err("Unsupported %s version: %s", path, line + 8); + goto out_free_line; + } + + if (io__getline(&io, &line, &line_len) < 0 || !line_len) + goto out_free_line; + timestamp = atol(line + 10); + + /* + * FIXME: Can be optimized a bit by not synthesizing domain samples + * for filtered out cpus. + */ + for (ch = io__get_char(&io); !io.eof; ch = io__get_char(&io)) { + struct perf_cpu this_cpu; + + if (ch == 'c') { + event = __synthesize_schedstat_cpu(&io, version, + &cpu, timestamp); + } else if (ch == 'd') { + event = __synthesize_schedstat_domain(&io, version, + cpu, timestamp); + } + if (!event) + goto out_free_line; + + this_cpu.cpu = cpu; + + if (user_requested_cpus && !perf_cpu_map__has(user_requested_cpus, this_cpu)) + continue; + + if (process(tool, event, NULL, NULL) < 0) { + free(event); + goto out_free_line; + } + + free(event); + } + + ret = 0; + +out_free_line: + free(line); +out: + close(io.fd); + return ret; +} diff --git a/tools/perf/util/synthetic-events.h b/tools/perf/util/synthetic-events.h index f8588b6cf11a..b0edad0c3100 100644 --- a/tools/perf/util/synthetic-events.h +++ b/tools/perf/util/synthetic-events.h @@ -128,4 +128,7 @@ int perf_event__synthesize_for_pipe(const struct perf_tool *tool, struct perf_data *data, perf_event__handler_t process); +int perf_event__synthesize_schedstat(const struct perf_tool *tool, + perf_event__handler_t process, + struct perf_cpu_map *user_requested_cpu); #endif // __PERF_SYNTHETIC_EVENTS_H diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index c6a0a27b12c2..c5ce741b0744 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c @@ -157,10 +157,10 @@ static int thread_stack__init(struct thread_stack *ts, struct thread *thread, if (thread__maps(thread) && maps__machine(thread__maps(thread))) { struct machine *machine = maps__machine(thread__maps(thread)); - const char *arch = perf_env__arch(machine->env); + uint16_t e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL); ts->kernel_start = machine__kernel_start(machine); - if (!strcmp(arch, "x86")) + if (e_machine == EM_X86_64 || e_machine == EM_386) ts->rstate = X86_RETPOLINE_POSSIBLE; } else { ts->kernel_start = 1ULL << 63; diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c index aa9c58bbf9d3..22be77225bb0 100644 --- a/tools/perf/util/thread.c +++ b/tools/perf/util/thread.c @@ -449,7 +449,7 @@ void thread__find_cpumode_addr_location(struct thread *thread, u64 addr, } } -static uint16_t read_proc_e_machine_for_pid(pid_t pid) +static uint16_t read_proc_e_machine_for_pid(pid_t pid, uint32_t *e_flags) { char path[6 /* "/proc/" */ + 11 /* max length of pid */ + 5 /* "/exe\0" */]; int fd; @@ -458,52 +458,71 @@ static uint16_t read_proc_e_machine_for_pid(pid_t pid) snprintf(path, sizeof(path), "/proc/%d/exe", pid); fd = open(path, O_RDONLY); if (fd >= 0) { - _Static_assert(offsetof(Elf32_Ehdr, e_machine) == 18, "Unexpected offset"); - _Static_assert(offsetof(Elf64_Ehdr, e_machine) == 18, "Unexpected offset"); - if (pread(fd, &e_machine, sizeof(e_machine), 18) != sizeof(e_machine)) - e_machine = EM_NONE; + e_machine = dso__read_e_machine(/*optional_dso=*/NULL, fd, e_flags); close(fd); } return e_machine; } -static int thread__e_machine_callback(struct map *map, void *machine) +struct thread__e_machine_callback_args { + struct machine *machine; + uint32_t e_flags; + uint16_t e_machine; +}; + +static int thread__e_machine_callback(struct map *map, void *_args) { + struct thread__e_machine_callback_args *args = _args; struct dso *dso = map__dso(map); - _Static_assert(0 == EM_NONE, "Unexpected EM_NONE"); if (!dso) - return EM_NONE; + return 0; // No dso, continue search. - return dso__e_machine(dso, machine); + args->e_machine = dso__e_machine(dso, args->machine, &args->e_flags); + return args->e_machine != EM_NONE ? 1 /* stop search */ : 0 /* continue search */; } -uint16_t thread__e_machine(struct thread *thread, struct machine *machine) +uint16_t thread__e_machine(struct thread *thread, struct machine *machine, uint32_t *e_flags) { pid_t tid, pid; uint16_t e_machine = RC_CHK_ACCESS(thread)->e_machine; + uint32_t local_e_flags = 0; + struct thread__e_machine_callback_args args = { + .machine = machine, + .e_flags = 0, + .e_machine = EM_NONE, + }; - if (e_machine != EM_NONE) + if (e_machine != EM_NONE) { + if (e_flags) + *e_flags = thread__e_flags(thread); return e_machine; + } + if (machine == NULL) { + struct maps *maps = thread__maps(thread); + + machine = maps__machine(maps); + } tid = thread__tid(thread); pid = thread__pid(thread); if (pid != tid) { struct thread *parent = machine__findnew_thread(machine, pid, pid); if (parent) { - e_machine = thread__e_machine(parent, machine); + e_machine = thread__e_machine(parent, machine, &local_e_flags); thread__put(parent); - thread__set_e_machine(thread, e_machine); - return e_machine; + goto out; } /* Something went wrong, fallback. */ } /* Reading on the PID thread. First try to find from the maps. */ - e_machine = maps__for_each_map(thread__maps(thread), - thread__e_machine_callback, - machine); - if (e_machine == EM_NONE) { + maps__for_each_map(thread__maps(thread), thread__e_machine_callback, &args); + + if (args.e_machine != EM_NONE) { + e_machine = args.e_machine; + local_e_flags = args.e_flags; + } else { /* Maps failed, perhaps we're live with map events disabled. */ bool is_live = machine->machines == NULL; @@ -517,12 +536,18 @@ uint16_t thread__e_machine(struct thread *thread, struct machine *machine) } /* Read from /proc/pid/exe if live. */ if (is_live) - e_machine = read_proc_e_machine_for_pid(pid); + e_machine = read_proc_e_machine_for_pid(pid, &local_e_flags); } - if (e_machine != EM_NONE) +out: + if (e_machine != EM_NONE) { thread__set_e_machine(thread, e_machine); - else + thread__set_e_flags(thread, local_e_flags); + } else { e_machine = EM_HOST; + local_e_flags = EF_HOST; + } + if (e_flags) + *e_flags = local_e_flags; return e_machine; } diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 310eaea344bb..f5792d3e8a16 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -60,6 +60,10 @@ DECLARE_RC_STRUCT(thread) { struct srccode_state srccode_state; bool filter; int filter_entry_depth; + /** + * @e_flags: The ELF EF_* associated with the thread. Valid if e_machine != EM_NONE. + */ + uint16_t e_flags; /** * @e_machine: The ELF EM_* associated with the thread. EM_NONE if not * computed. @@ -307,13 +311,23 @@ static inline void thread__set_filter_entry_depth(struct thread *thread, int dep RC_CHK_ACCESS(thread)->filter_entry_depth = depth; } -uint16_t thread__e_machine(struct thread *thread, struct machine *machine); +uint16_t thread__e_machine(struct thread *thread, struct machine *machine, uint32_t *e_flags); static inline void thread__set_e_machine(struct thread *thread, uint16_t e_machine) { RC_CHK_ACCESS(thread)->e_machine = e_machine; } +static inline uint32_t thread__e_flags(const struct thread *thread) +{ + return RC_CHK_ACCESS(thread)->e_flags; +} + +static inline void thread__set_e_flags(struct thread *thread, uint32_t e_flags) +{ + RC_CHK_ACCESS(thread)->e_flags = e_flags; +} + static inline bool thread__lbr_stitch_enable(const struct thread *thread) { diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index ca193c1374ed..48c70f149e92 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -164,19 +164,16 @@ static struct perf_thread_map *thread_map__new_by_pid_str(const char *pid_str) struct dirent **namelist = NULL; int i, j = 0; pid_t pid, prev_pid = INT_MAX; - char *end_ptr; struct str_node *pos; - struct strlist_config slist_config = { .dont_dupstr = true, }; - struct strlist *slist = strlist__new(pid_str, &slist_config); + struct strlist *slist = strlist__new(pid_str, NULL); if (!slist) return NULL; strlist__for_each_entry(pos, slist) { - pid = strtol(pos->s, &end_ptr, 10); + pid = strtol(pos->s, NULL, 10); - if (pid == INT_MIN || pid == INT_MAX || - (*end_ptr != '\0' && *end_ptr != ',')) + if (pid == INT_MIN || pid == INT_MAX) goto out_free_threads; if (pid == prev_pid) @@ -223,24 +220,21 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) struct perf_thread_map *threads = NULL, *nt; int ntasks = 0; pid_t tid, prev_tid = INT_MAX; - char *end_ptr; struct str_node *pos; - struct strlist_config slist_config = { .dont_dupstr = true, }; struct strlist *slist; /* perf-stat expects threads to be generated even if tid not given */ if (!tid_str) return perf_thread_map__new_dummy(); - slist = strlist__new(tid_str, &slist_config); + slist = strlist__new(tid_str, NULL); if (!slist) return NULL; strlist__for_each_entry(pos, slist) { - tid = strtol(pos->s, &end_ptr, 10); + tid = strtol(pos->s, NULL, 10); - if (tid == INT_MIN || tid == INT_MAX || - (*end_ptr != '\0' && *end_ptr != ',')) + if (tid == INT_MIN || tid == INT_MAX) goto out_free_threads; if (tid == prev_tid) diff --git a/tools/perf/util/time-utils.c b/tools/perf/util/time-utils.c index 1b91ccd4d523..d43c4577d7eb 100644 --- a/tools/perf/util/time-utils.c +++ b/tools/perf/util/time-utils.c @@ -325,7 +325,7 @@ static int percent_comma_split(struct perf_time_interval *ptime_buf, int num, } static int one_percent_convert(struct perf_time_interval *ptime_buf, - const char *ostr, u64 start, u64 end, char *c) + const char *ostr, u64 start, u64 end, const char *c) { char *str; int len = strlen(ostr), ret; @@ -358,7 +358,7 @@ static int one_percent_convert(struct perf_time_interval *ptime_buf, int perf_time__percent_parse_str(struct perf_time_interval *ptime_buf, int num, const char *ostr, u64 start, u64 end) { - char *c; + const char *c; /* * ostr example: diff --git a/tools/perf/util/tool.c b/tools/perf/util/tool.c index 27ba5849c74a..013c7839e2cf 100644 --- a/tools/perf/util/tool.c +++ b/tools/perf/util/tool.c @@ -253,7 +253,25 @@ static int perf_event__process_bpf_metadata_stub(const struct perf_tool *tool __ { if (dump_trace) perf_event__fprintf_bpf_metadata(event, stdout); + dump_printf(": unhandled!\n"); + return 0; +} +static int process_schedstat_cpu_stub(const struct perf_tool *tool __maybe_unused, + struct perf_session *perf_session __maybe_unused, + union perf_event *event) +{ + if (dump_trace) + perf_event__fprintf_schedstat_cpu(event, stdout); + dump_printf(": unhandled!\n"); + return 0; +} +static int process_schedstat_domain_stub(const struct perf_tool *tool __maybe_unused, + struct perf_session *perf_session __maybe_unused, + union perf_event *event) +{ + if (dump_trace) + perf_event__fprintf_schedstat_domain(event, stdout); dump_printf(": unhandled!\n"); return 0; } @@ -317,6 +335,8 @@ void perf_tool__init(struct perf_tool *tool, bool ordered_events) #endif tool->finished_init = process_event_op2_stub; tool->bpf_metadata = perf_event__process_bpf_metadata_stub; + tool->schedstat_cpu = process_schedstat_cpu_stub; + tool->schedstat_domain = process_schedstat_domain_stub; } bool perf_tool__compressed_is_stub(const struct perf_tool *tool) diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h index e96b69d25a5b..2d9a4b1ca9d0 100644 --- a/tools/perf/util/tool.h +++ b/tools/perf/util/tool.h @@ -81,7 +81,9 @@ struct perf_tool { stat_round, feature, finished_init, - bpf_metadata; + bpf_metadata, + schedstat_cpu, + schedstat_domain; event_op4 compressed; event_op3 auxtrace; bool ordered_events; diff --git a/tools/perf/util/tool_pmu.c b/tools/perf/util/tool_pmu.c index 37c4eae0bef1..6a9df3dc0e07 100644 --- a/tools/perf/util/tool_pmu.c +++ b/tools/perf/util/tool_pmu.c @@ -2,7 +2,6 @@ #include "cgroup.h" #include "counts.h" #include "cputopo.h" -#include "debug.h" #include "evsel.h" #include "pmu.h" #include "print-events.h" @@ -14,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -111,23 +109,6 @@ const char *evsel__tool_pmu_event_name(const struct evsel *evsel) return tool_pmu__event_to_str(evsel->core.attr.config); } -struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr) -{ - static struct perf_cpu_map *cpu0_map; - enum tool_pmu_event event = (enum tool_pmu_event)attr->config; - - if (event <= TOOL_PMU__EVENT_NONE || event >= TOOL_PMU__EVENT_MAX) { - pr_err("Invalid tool PMU event config %llx\n", attr->config); - return NULL; - } - if (event == TOOL_PMU__EVENT_USER_TIME || event == TOOL_PMU__EVENT_SYSTEM_TIME) - return cpu_map__online(); - - if (!cpu0_map) - cpu0_map = perf_cpu_map__new_int(0); - return perf_cpu_map__get(cpu0_map); -} - static bool read_until_char(struct io *io, char e) { int c; diff --git a/tools/perf/util/tool_pmu.h b/tools/perf/util/tool_pmu.h index ea343d1983d3..f1714001bc1d 100644 --- a/tools/perf/util/tool_pmu.h +++ b/tools/perf/util/tool_pmu.h @@ -46,7 +46,6 @@ bool tool_pmu__read_event(enum tool_pmu_event ev, u64 tool_pmu__cpu_slots_per_cycle(void); bool perf_pmu__is_tool(const struct perf_pmu *pmu); -struct perf_cpu_map *tool_pmu__cpus(struct perf_event_attr *attr); bool evsel__is_tool(const struct evsel *evsel); enum tool_pmu_event evsel__tool_event(const struct evsel *evsel); diff --git a/tools/perf/util/tp_pmu.c b/tools/perf/util/tp_pmu.c index eddb9807131a..c2be8c9f9084 100644 --- a/tools/perf/util/tp_pmu.c +++ b/tools/perf/util/tp_pmu.c @@ -192,7 +192,7 @@ bool tp_pmu__have_event(struct perf_pmu *pmu __maybe_unused, const char *name) char *dup_name, *colon; int id; - colon = strchr(name, ':'); + colon = strchr((char *)name, ':'); if (colon == NULL) return false; diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index c8755679281e..45774722f249 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -482,7 +482,7 @@ char *tracepoint_id_to_name(u64 config) static struct tracepoint_path *tracepoint_name_to_path(const char *name) { struct tracepoint_path *path = zalloc(sizeof(*path)); - char *str = strchr(name, ':'); + const char *str = strchr(name, ':'); if (path == NULL || str == NULL) { free(path); diff --git a/tools/perf/util/trace-event-scripting.c b/tools/perf/util/trace-event-scripting.c index 72abb28b7b5a..fa850e44cb46 100644 --- a/tools/perf/util/trace-event-scripting.c +++ b/tools/perf/util/trace-event-scripting.c @@ -13,7 +13,6 @@ #include #endif -#include "archinsn.h" #include "debug.h" #include "event.h" #include "trace-event.h" @@ -274,21 +273,6 @@ void setup_perl_scripting(void) #endif #endif -#if !defined(__i386__) && !defined(__x86_64__) -void arch_fetch_insn(struct perf_sample *sample __maybe_unused, - struct thread *thread __maybe_unused, - struct machine *machine __maybe_unused) -{ -} -#endif - -void script_fetch_insn(struct perf_sample *sample, struct thread *thread, - struct machine *machine, bool native_arch) -{ - if (sample->insn_len == 0 && native_arch) - arch_fetch_insn(sample, thread, machine); -} - static const struct { u32 flags; const char *name; diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h index 71e680bc3d4b..914d9b69ed62 100644 --- a/tools/perf/util/trace-event.h +++ b/tools/perf/util/trace-event.h @@ -116,9 +116,6 @@ extern unsigned int scripting_max_stack; struct scripting_ops *script_spec__lookup(const char *spec); int script_spec__for_each(int (*cb)(struct scripting_ops *ops, const char *spec)); -void script_fetch_insn(struct perf_sample *sample, struct thread *thread, - struct machine *machine, bool native_arch); - void setup_perl_scripting(void); void setup_python_scripting(void); diff --git a/tools/perf/util/units.c b/tools/perf/util/units.c index 4c6a86e1cb54..0bbacf5a29aa 100644 --- a/tools/perf/util/units.c +++ b/tools/perf/util/units.c @@ -12,7 +12,7 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags) struct parse_tag *i = tags; while (i->tag) { - char *s = strchr(str, i->tag); + const char *s = strchr(str, i->tag); if (s) { unsigned long int value; diff --git a/tools/perf/util/unwind-libdw.c b/tools/perf/util/unwind-libdw.c index ae70fb56a057..05e8e68bd49c 100644 --- a/tools/perf/util/unwind-libdw.c +++ b/tools/perf/util/unwind-libdw.c @@ -6,6 +6,7 @@ #include #include "debug.h" #include "dso.h" +#include #include "unwind.h" #include "unwind-libdw.h" #include "machine.h" @@ -19,6 +20,17 @@ #include "callchain.h" #include "util/env.h" +/* + * The dwfl thread argument passed to functions like memory_read. Memory has to + * be allocated to persist of multiple uses of the dwfl. + */ +struct dwfl_ui_thread_info { + /* Back link to the dwfl. */ + Dwfl *dwfl; + /* The current unwind info, only 1 is supported. */ + struct unwind_info *ui; +}; + static char *debuginfo_path; static int __find_debuginfo(Dwfl_Module *mod __maybe_unused, void **userdata, @@ -34,6 +46,19 @@ static int __find_debuginfo(Dwfl_Module *mod __maybe_unused, void **userdata, return -1; } +void libdw__invalidate_dwfl(struct maps *maps, void *arg) +{ + struct dwfl_ui_thread_info *dwfl_ui_ti = arg; + + if (!dwfl_ui_ti) + return; + + assert(dwfl_ui_ti->ui == NULL); + maps__set_libdw_addr_space_dwfl(maps, NULL); + dwfl_end(dwfl_ui_ti->dwfl); + free(dwfl_ui_ti); +} + static const Dwfl_Callbacks offline_callbacks = { .find_debuginfo = __find_debuginfo, .debuginfo_path = &debuginfo_path, @@ -136,8 +161,8 @@ static int entry(u64 ip, struct unwind_info *ui) } e->ip = ip; - e->ms.maps = al.maps; - e->ms.map = al.map; + e->ms.thread = thread__get(al.thread); + e->ms.map = map__get(al.map); e->ms.sym = al.sym; pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", @@ -186,8 +211,8 @@ static int access_dso_mem(struct unwind_info *ui, Dwarf_Addr addr, static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word *result, void *arg) { - struct unwind_info *ui = arg; - const char *arch = perf_env__arch(ui->machine->env); + struct dwfl_ui_thread_info *dwfl_ui_ti = arg; + struct unwind_info *ui = dwfl_ui_ti->ui; struct stack_dump *stack = &ui->sample->user_stack; u64 start, end; int offset; @@ -197,7 +222,7 @@ static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word * return false; ret = perf_reg_value(&start, ui->sample->user_regs, - perf_arch_reg_sp(arch)); + perf_arch_reg_sp(ui->e_machine)); if (ret) return false; @@ -225,10 +250,64 @@ static bool memory_read(Dwfl *dwfl __maybe_unused, Dwarf_Addr addr, Dwarf_Word * return true; } +static bool libdw_set_initial_registers(Dwfl_Thread *thread, void *arg) +{ + struct dwfl_ui_thread_info *dwfl_ui_ti = arg; + struct unwind_info *ui = dwfl_ui_ti->ui; + struct regs_dump *user_regs = perf_sample__user_regs(ui->sample); + Dwarf_Word *dwarf_regs; + int max_dwarf_reg = 0; + bool ret; + uint16_t e_machine = ui->e_machine; + int e_flags = ui->e_flags; + uint64_t ip_perf_reg = perf_arch_reg_ip(e_machine); + Dwarf_Word val = 0; + + + /* + * For every possible perf register in the bitmap determine the dwarf + * register and use to compute the max. + */ + for (int perf_reg = 0; perf_reg < 64; perf_reg++) { + if (user_regs->mask & (1ULL << perf_reg)) { + int dwarf_reg = + get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine, + e_flags, + /*only_libdw_supported=*/true); + if (dwarf_reg > max_dwarf_reg) + max_dwarf_reg = dwarf_reg; + } + } + + dwarf_regs = calloc(max_dwarf_reg + 1, sizeof(*dwarf_regs)); + if (!dwarf_regs) + return false; + + for (int perf_reg = 0; perf_reg < 64; perf_reg++) { + if (user_regs->mask & (1ULL << perf_reg)) { + int dwarf_reg = + get_dwarf_regnum_for_perf_regnum(perf_reg, e_machine, + e_flags, + /*only_libdw_supported=*/true); + if (dwarf_reg >= 0) { + val = 0; + if (perf_reg_value(&val, user_regs, perf_reg) == 0) + dwarf_regs[dwarf_reg] = val; + } + } + } + if (perf_reg_value(&val, user_regs, ip_perf_reg) == 0) + dwfl_thread_state_register_pc(thread, val); + + ret = dwfl_thread_state_registers(thread, 0, max_dwarf_reg + 1, dwarf_regs); + free(dwarf_regs); + return ret; +} + static const Dwfl_Thread_Callbacks callbacks = { - .next_thread = next_thread, - .memory_read = memory_read, - .set_initial_registers = libdw__arch_set_initial_registers, + .next_thread = next_thread, + .memory_read = memory_read, + .set_initial_registers = libdw_set_initial_registers, }; static int @@ -266,33 +345,54 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, int max_stack, bool best_effort) { - struct unwind_info *ui, ui_buf = { - .sample = data, - .thread = thread, - .machine = maps__machine((thread__maps(thread))), - .cb = cb, - .arg = arg, - .max_stack = max_stack, - .best_effort = best_effort - }; - const char *arch = perf_env__arch(ui_buf.machine->env); + struct maps *maps = thread__maps(thread); + struct machine *machine = maps__machine(maps); + uint32_t e_flags = 0; + uint16_t e_machine = thread__e_machine(thread, machine, &e_flags); + struct dwfl_ui_thread_info *dwfl_ui_ti; + static struct unwind_info *ui; + Dwfl *dwfl; Dwarf_Word ip; int err = -EINVAL, i; if (!data->user_regs || !data->user_regs->regs) return -EINVAL; - ui = zalloc(sizeof(ui_buf) + sizeof(ui_buf.entries[0]) * max_stack); + ui = zalloc(sizeof(*ui) + sizeof(ui->entries[0]) * max_stack); if (!ui) return -ENOMEM; - *ui = ui_buf; + *ui = (struct unwind_info){ + .sample = data, + .thread = thread, + .machine = machine, + .cb = cb, + .arg = arg, + .max_stack = max_stack, + .e_machine = e_machine, + .e_flags = e_flags, + .best_effort = best_effort + }; - ui->dwfl = dwfl_begin(&offline_callbacks); - if (!ui->dwfl) - goto out; + dwfl_ui_ti = maps__libdw_addr_space_dwfl(maps); + if (dwfl_ui_ti) { + dwfl = dwfl_ui_ti->dwfl; + } else { + dwfl_ui_ti = zalloc(sizeof(*dwfl_ui_ti)); + dwfl = dwfl_begin(&offline_callbacks); + if (!dwfl) + goto out; - err = perf_reg_value(&ip, data->user_regs, perf_arch_reg_ip(arch)); + dwfl_ui_ti->dwfl = dwfl; + maps__set_libdw_addr_space_dwfl(maps, dwfl_ui_ti); + } + assert(dwfl_ui_ti->ui == NULL); + assert(dwfl_ui_ti->dwfl == dwfl); + assert(dwfl_ui_ti == maps__libdw_addr_space_dwfl(maps)); + dwfl_ui_ti->ui = ui; + ui->dwfl = dwfl; + + err = perf_reg_value(&ip, data->user_regs, perf_arch_reg_ip(e_machine)); if (err) goto out; @@ -300,11 +400,12 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, if (err) goto out; - err = !dwfl_attach_state(ui->dwfl, EM_NONE, thread__tid(thread), &callbacks, ui); - if (err) - goto out; + dwfl_attach_state(dwfl, /*elf=*/NULL, thread__tid(thread), &callbacks, + /* Dwfl thread function argument*/dwfl_ui_ti); + // Ignore thread already attached error. - err = dwfl_getthread_frames(ui->dwfl, thread__tid(thread), frame_callback, ui); + err = dwfl_getthread_frames(dwfl, thread__tid(thread), frame_callback, + /* Dwfl frame function argument*/ui); if (err && ui->max_stack != max_stack) err = 0; @@ -325,7 +426,10 @@ int unwind__get_entries(unwind_entry_cb_t cb, void *arg, if (err) pr_debug("unwind: failed with '%s'\n", dwfl_errmsg(-1)); - dwfl_end(ui->dwfl); + for (i = 0; i < ui->idx; i++) + map_symbol__exit(&ui->entries[i].ms); + + dwfl_ui_ti->ui = NULL; free(ui); return 0; } diff --git a/tools/perf/util/unwind-libdw.h b/tools/perf/util/unwind-libdw.h index 8c88bc4f2304..6423bf5a2492 100644 --- a/tools/perf/util/unwind-libdw.h +++ b/tools/perf/util/unwind-libdw.h @@ -2,17 +2,17 @@ #ifndef __PERF_UNWIND_LIBDW_H #define __PERF_UNWIND_LIBDW_H -#include +#include #include "unwind.h" struct machine; struct perf_sample; struct thread; -bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg); +#ifdef HAVE_LIBDW_SUPPORT struct unwind_info { - Dwfl *dwfl; + void *dwfl; struct perf_sample *sample; struct machine *machine; struct thread *thread; @@ -20,8 +20,13 @@ struct unwind_info { void *arg; int max_stack; int idx; + uint32_t e_flags; + uint16_t e_machine; bool best_effort; struct unwind_entry entries[]; }; +void libdw__invalidate_dwfl(struct maps *maps, void *dwfl); +#endif + #endif /* __PERF_UNWIND_LIBDW_H */ diff --git a/tools/perf/util/unwind-libunwind-local.c b/tools/perf/util/unwind-libunwind-local.c index 0b037e7389a0..5b39ce21e333 100644 --- a/tools/perf/util/unwind-libunwind-local.c +++ b/tools/perf/util/unwind-libunwind-local.c @@ -572,7 +572,6 @@ static int access_mem(unw_addr_space_t __maybe_unused as, int __write, void *arg) { struct unwind_info *ui = arg; - const char *arch = perf_env__arch(ui->machine->env); struct stack_dump *stack = &ui->sample->user_stack; u64 start, end; int offset; @@ -585,7 +584,9 @@ static int access_mem(unw_addr_space_t __maybe_unused as, } ret = perf_reg_value(&start, perf_sample__user_regs(ui->sample), - perf_arch_reg_sp(arch)); + perf_arch_reg_sp(thread__e_machine(ui->thread, + ui->machine, + /*e_flags=*/NULL))); if (ret) return ret; @@ -667,7 +668,7 @@ static int entry(u64 ip, struct thread *thread, e.ms.sym = thread__find_symbol(thread, PERF_RECORD_MISC_USER, ip, &al); e.ip = ip; e.ms.map = al.map; - e.ms.maps = al.maps; + e.ms.thread = thread__get(al.thread); pr_debug("unwind: %s:ip = 0x%" PRIx64 " (0x%" PRIx64 ")\n", al.sym ? al.sym->name : "''", @@ -734,7 +735,7 @@ static void _unwind__finish_access(struct maps *maps) static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, void *arg, int max_stack) { - const char *arch = perf_env__arch(ui->machine->env); + uint16_t e_machine = thread__e_machine(ui->thread, ui->machine, /*e_flags=*/NULL); u64 val; unw_word_t ips[max_stack]; unw_addr_space_t addr_space; @@ -742,7 +743,7 @@ static int get_entries(struct unwind_info *ui, unwind_entry_cb_t cb, int ret, i = 0; ret = perf_reg_value(&val, perf_sample__user_regs(ui->sample), - perf_arch_reg_ip(arch)); + perf_arch_reg_ip(e_machine)); if (ret) return ret; diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 0f031eb80b4c..8b893de35f77 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0 +#include "perf.h" #include "util.h" #include "debug.h" #include "event.h" @@ -257,6 +258,54 @@ static int rm_rf_kcore_dir(const char *path) return 0; } +void cpumask_to_cpulist(char *cpumask, char *cpulist) +{ + int i, j, bm_size, nbits; + int len = strlen(cpumask); + unsigned long *bm; + char cpus[MAX_NR_CPUS]; + + for (i = 0; i < len; i++) { + if (cpumask[i] == ',') { + for (j = i; j < len; j++) + cpumask[j] = cpumask[j + 1]; + } + } + + len = strlen(cpumask); + bm_size = (len + 15) / 16; + nbits = bm_size * 64; + if (nbits <= 0) + return; + + bm = calloc(bm_size, sizeof(unsigned long)); + if (!bm) + goto free_bm; + + for (i = 0; i < bm_size; i++) { + char blk[17]; + int blklen = len > 16 ? 16 : len; + + strncpy(blk, cpumask + len - blklen, blklen); + blk[blklen] = '\0'; + bm[i] = strtoul(blk, NULL, 16); + cpumask[len - blklen] = '\0'; + len = strlen(cpumask); + } + + bitmap_scnprintf(bm, nbits, cpus, sizeof(cpus)); + strcpy(cpulist, cpus); + +free_bm: + free(bm); +} + +void print_separator2(int pre_dash_cnt, const char *s, int post_dash_cnt) +{ + printf("%.*s%s%.*s\n", pre_dash_cnt, graph_dotted_line, s, post_dash_cnt, + graph_dotted_line); +} + int rm_rf_perf_data(const char *path) { const char *pat[] = { diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 3423778e39a5..394dbfa944ac 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #ifndef __cplusplus #include @@ -48,6 +49,10 @@ bool sysctl__nmi_watchdog_enabled(void); int perf_tip(char **strp, const char *dirpath); +void cpumask_to_cpulist(char *cpumask, char *cpulist); + +void print_separator2(int pre_dash_cnt, const char *s, int post_dash_cnt); + #ifndef HAVE_SCHED_GETCPU_SUPPORT int sched_getcpu(void); #endif diff --git a/tools/power/cpupower/cpupower-service.conf b/tools/power/cpupower/cpupower-service.conf index 02eabe8e3614..abbb46967565 100644 --- a/tools/power/cpupower/cpupower-service.conf +++ b/tools/power/cpupower/cpupower-service.conf @@ -30,3 +30,8 @@ # its policy for the relative importance of performance versus energy savings to # the processor. See man CPUPOWER-SET(1) for additional details #PERF_BIAS= + +# Set the Energy Performance Preference +# Available options can be read from +# /sys/devices/system/cpu/cpufreq/policy0/energy_performance_available_preferences +#EPP= diff --git a/tools/power/cpupower/cpupower.sh b/tools/power/cpupower/cpupower.sh index a37dd4cfdb2b..6283e8bf275d 100644 --- a/tools/power/cpupower/cpupower.sh +++ b/tools/power/cpupower/cpupower.sh @@ -23,4 +23,10 @@ then cpupower set -b "$PERF_BIAS" > /dev/null || ESTATUS=1 fi +# apply Energy Performance Preference +if test -n "$EPP" +then + cpupower set -e "$EPP" > /dev/null || ESTATUS=1 +fi + exit $ESTATUS diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c index c2117e5650dd..550a942e72ce 100644 --- a/tools/power/cpupower/utils/cpupower-set.c +++ b/tools/power/cpupower/utils/cpupower-set.c @@ -124,7 +124,11 @@ int cmd_set(int argc, char **argv) } if (params.turbo_boost) { - ret = cpupower_set_turbo_boost(turbo_boost); + if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) + ret = cpupower_set_intel_turbo_boost(turbo_boost); + else + ret = cpupower_set_generic_turbo_boost(turbo_boost); + if (ret) fprintf(stderr, "Error setting turbo-boost\n"); } diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 82ea62bdf5a2..a3ad80b9c2c2 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -104,7 +104,7 @@ extern struct cpupower_cpu_info cpupower_cpu_info; /* cpuid and cpuinfo helpers **************************/ int cpufreq_has_generic_boost_support(bool *active); -int cpupower_set_turbo_boost(int turbo_boost); +int cpupower_set_generic_turbo_boost(int turbo_boost); /* X86 ONLY ****************************************/ #if defined(__i386__) || defined(__x86_64__) @@ -143,6 +143,7 @@ extern int decode_pstates(unsigned int cpu, int boost_states, int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, int *states); +int cpupower_set_intel_turbo_boost(int turbo_boost); /* AMD P-State stuff **************************/ bool cpupower_amd_pstate_enabled(void); @@ -189,6 +190,8 @@ static inline int cpupower_set_amd_pstate_mode(char *mode) static inline int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, int *states) { return -1; } +static inline int cpupower_set_intel_turbo_boost(int turbo_boost) +{ return -1; } static inline bool cpupower_amd_pstate_enabled(void) { return false; } diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c index 166dc1e470ea..eebfc79a4889 100644 --- a/tools/power/cpupower/utils/helpers/misc.c +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -19,6 +19,9 @@ int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, { int ret; unsigned long long val; + char linebuf[MAX_LINE_LEN]; + char path[SYSFS_PATH_MAX]; + char *endp; *support = *active = *states = 0; @@ -42,8 +45,42 @@ int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, } } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { amd_pstate_boost_init(cpu, support, active); - } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) { *support = *active = 1; + + snprintf(path, sizeof(path), PATH_TO_CPU "intel_pstate/no_turbo"); + + if (!is_valid_path(path)) + return 0; + + if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) + return -1; + + val = strtol(linebuf, &endp, 0); + if (endp == linebuf || errno == ERANGE) + return -1; + + *active = !val; + } + return 0; +} + +int cpupower_set_intel_turbo_boost(int turbo_boost) +{ + char path[SYSFS_PATH_MAX]; + char linebuf[2] = {}; + + snprintf(path, sizeof(path), PATH_TO_CPU "intel_pstate/no_turbo"); + + /* Fallback to generic solution when intel_pstate driver not running */ + if (!is_valid_path(path)) + return cpupower_set_generic_turbo_boost(turbo_boost); + + snprintf(linebuf, sizeof(linebuf), "%d", !turbo_boost); + + if (cpupower_write_sysfs(path, linebuf, 2) <= 0) + return -1; + return 0; } @@ -274,7 +311,7 @@ void print_speed(unsigned long speed, int no_rounding) } } -int cpupower_set_turbo_boost(int turbo_boost) +int cpupower_set_generic_turbo_boost(int turbo_boost) { char path[SYSFS_PATH_MAX]; char linebuf[2] = {}; diff --git a/tools/power/cpupower/utils/powercap-info.c b/tools/power/cpupower/utils/powercap-info.c index 3ea4486f1a0e..e53033488218 100644 --- a/tools/power/cpupower/utils/powercap-info.c +++ b/tools/power/cpupower/utils/powercap-info.c @@ -38,11 +38,11 @@ static int powercap_print_one_zone(struct powercap_zone *zone) printf(" (%s)\n", mode ? "enabled" : "disabled"); if (zone->has_power_uw) - printf(_("%sPower can be monitored in micro Jules\n"), + printf(_("%sPower can be monitored in micro Watts\n"), pr_prefix); if (zone->has_energy_uj) - printf(_("%sPower can be monitored in micro Watts\n"), + printf(_("%sPower can be monitored in micro Jules\n"), pr_prefix); printf("\n"); diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index 1551fcdbfd8a..344ede2f8546 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 @@ -111,10 +111,14 @@ The column name "all" can be used to enable all disabled-by-default built-in cou .PP \fB--no-perf\fP Disable all the uses of the perf API. .PP +\fB--force\fP Force turbostat to run on an unsupported platform (minimal defaults). +.PP \fB--interval seconds\fP overrides the default 5.0 second measurement interval. .PP \fB--num_iterations num\fP number of the measurement iterations. .PP +\fB--header_iterations num\fP print header every num iterations. +.PP \fB--out output_file\fP turbostat output is written to the specified output_file. The file is truncated if it already exists, and it is created if it does not exist. .PP @@ -159,15 +163,19 @@ The system configuration dump (if --quiet is not used) is followed by statistics .PP \fBSMI\fP The number of System Management Interrupts serviced CPU during the measurement interval. While this counter is actually per-CPU, SMI are triggered on all processors, so the number should be the same for all CPUs. .PP -\fBLLCkRPS\fP Last Level Cache Thousands of References Per Second. For CPUs with an L3 LLC, this is the number of references that CPU made to the L3 (and the number of misses that CPU made to it's L2). For CPUs with an L2 LLC, this is the number of references to the L2 (and the number of misses to the CPU's L1). The system summary row shows the sum for all CPUs. In both cases, the value displayed is the actual value divided by 1000 in the interest of usually fitting into 8 columns. +\fBLLCMRPS\fP Last Level Cache Millions of References Per Second. For CPUs with an L3 LLC, this is the number of references that CPU made to the L3 (and the number of misses that CPU made to it's L2). For CPUs with an L2 LLC, this is the number of references to the L2 (and the number of misses to the CPU's L1). The system summary row shows the sum for all CPUs. In both cases, the value displayed is the actual value divided by 1,000,000. If this value is large, then the LLC%hit column is significant. If this value is small, then the LLC%hit column is not significant. .PP -\fBLLC%hit\fP Last Level Cache Hit Rate %. Hit Rate Percent = 100.0 * (References - Misses)/References. The system summary row shows the weighted average for all CPUs (100.0 * (Sum_References - Sum_Misses)/Sum_References). +\fBLLC%hit\fP Last Level Cache Hit Rate %. Hit Rate Percent = 100.0 * Hits/References. The system summary row shows the weighted average for all CPUs (100.0 * Sum_Hits/Sum_References). +.PP +\fBL2MRPS\fP Level-2 Cache Millions of References Per Second. For CPUs with an L2 LLC, this is the same as LLC references. The system summary row shows the sum for all CPUs. In both cases, the value displayed is the actual value divided by 1,000,000. If this value is large, then the L2%hit column is significant. If this value is small, then the L2%hit column is not significant. +.PP +\fBL2%hit\fP Level-2 Cache Hit Rate %. Hit Rate Percent = 100.0 * Hits/References. The system summary row shows the weighted average for all CPUs (100.0 * (Sum_Hits)/Sum_References). .PP \fBC1, C2, C3...\fP The number times Linux requested the C1, C2, C3 idle state during the measurement interval. The system summary line shows the sum for all CPUs. These are C-state names as exported in /sys/devices/system/cpu/cpu*/cpuidle/state*/name. While their names are generic, their attributes are processor specific. They the system description section of output shows what MWAIT sub-states they are mapped to on each system. These counters are in the "cpuidle" group, which is disabled, by default. .PP -\fBC1+, C2+, C3+...\fP The idle governor idle state misprediction statistics. Inidcates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a deeper idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/below file. These counters are in the "cpuidle" group, which is disabled, by default. +\fBC1+, C2+, C3+...\fP The idle governor idle state misprediction statistics. Indicates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a deeper idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/below file. These counters are in the "cpuidle" group, which is disabled, by default. .PP -\fBC1-, C2-, C3-...\fP The idle governor idle state misprediction statistics. Inidcates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a shallower idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/above file. These counters are in the "cpuidle" group, which is disabled, by default. +\fBC1-, C2-, C3-...\fP The idle governor idle state misprediction statistics. Indicates the number times Linux requested the C1, C2, C3 idle state during the measurement interval, but should have requested a shallower idle state (if it exists and enabled). These statistics come from the /sys/devices/system/cpu/cpu*/cpuidle/state*/above file. These counters are in the "cpuidle" group, which is disabled, by default. .PP \fBC1%, C2%, C3%\fP The residency percentage that Linux requested C1, C2, C3.... The system summary is the average of all CPUs in the system. Note that these are software, reflecting what was requested. The hardware counters reflect what was actually achieved. These counters are in the "pct_idle" group, which is enabled by default. .PP @@ -197,7 +205,7 @@ The system configuration dump (if --quiet is not used) is followed by statistics .PP \fBGFX%C0\fP Percentage of time that at least one GFX compute engine is busy. .PP -\fBCPUGFX%\fP Percentage of time that at least one CPU is busy at the same time as at least one Graphics compute enginer is busy. +\fBCPUGFX%\fP Percentage of time that at least one CPU is busy at the same time as at least one Graphics compute engine is busy. .PP \fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. These numbers are from hardware residency counters. .PP @@ -559,6 +567,8 @@ If the upstream version isn't new enough, the development tree can be found here If the development tree doesn't work, please contact the author via chat, or via email with the word "turbostat" on the Subject line. +An old turbostat binary may run on unknown hardware by using "--force", +but results are unsupported. .SH FILES .ta .nf diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 5ad45c2ac5bd..1a2671c28209 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c @@ -3,7 +3,7 @@ * turbostat -- show CPU frequency and C-state residency * on modern Intel and AMD processors. * - * Copyright (c) 2025 Intel Corporation. + * Copyright (c) 2010 - 2026 Intel Corporation * Len Brown */ @@ -210,8 +210,10 @@ struct msr_counter bic[] = { { 0x0, "NMI", NULL, 0, 0, 0, NULL, 0 }, { 0x0, "CPU%c1e", NULL, 0, 0, 0, NULL, 0 }, { 0x0, "pct_idle", NULL, 0, 0, 0, NULL, 0 }, - { 0x0, "LLCkRPS", NULL, 0, 0, 0, NULL, 0 }, + { 0x0, "LLCMRPS", NULL, 0, 0, 0, NULL, 0 }, { 0x0, "LLC%hit", NULL, 0, 0, 0, NULL, 0 }, + { 0x0, "L2MRPS", NULL, 0, 0, 0, NULL, 0 }, + { 0x0, "L2%hit", NULL, 0, 0, 0, NULL, 0 }, }; /* n.b. bic_names must match the order in bic[], above */ @@ -281,8 +283,10 @@ enum bic_names { BIC_NMI, BIC_CPU_c1e, BIC_pct_idle, - BIC_LLC_RPS, + BIC_LLC_MRPS, BIC_LLC_HIT, + BIC_L2_MRPS, + BIC_L2_HIT, MAX_BIC }; @@ -294,12 +298,10 @@ void print_bic_set(char *s, cpu_set_t *set) printf("%s:", s); - for (i = 0; i <= MAX_BIC; ++i) { + for (i = 0; i < MAX_BIC; ++i) { - if (CPU_ISSET(i, set)) { - assert(i < MAX_BIC); + if (CPU_ISSET(i, set)) printf(" %s", bic[i].name); - } } putchar('\n'); } @@ -424,8 +426,10 @@ static void bic_groups_init(void) SET_BIC(BIC_pct_idle, &bic_group_idle); BIC_INIT(&bic_group_cache); - SET_BIC(BIC_LLC_RPS, &bic_group_cache); + SET_BIC(BIC_LLC_MRPS, &bic_group_cache); SET_BIC(BIC_LLC_HIT, &bic_group_cache); + SET_BIC(BIC_L2_MRPS, &bic_group_cache); + SET_BIC(BIC_L2_HIT, &bic_group_cache); BIC_INIT(&bic_group_other); SET_BIC(BIC_IRQ, &bic_group_other); @@ -482,6 +486,7 @@ FILE *outf; int *fd_percpu; int *fd_instr_count_percpu; int *fd_llc_percpu; +int *fd_l2_percpu; struct timeval interval_tv = { 5, 0 }; struct timespec interval_ts = { 5, 0 }; @@ -498,6 +503,7 @@ unsigned int list_header_only; unsigned int dump_only; unsigned int force_load; unsigned int cpuid_has_aperf_mperf; +unsigned int cpuid_has_hv; unsigned int has_aperf_access; unsigned int has_epb; unsigned int has_turbo; @@ -528,7 +534,7 @@ double rapl_dram_energy_units, rapl_energy_units, rapl_psys_energy_units; double rapl_joule_counter_range; unsigned int crystal_hz; unsigned long long tsc_hz; -int base_cpu; +int master_cpu; unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */ @@ -620,7 +626,7 @@ double slm_bclk(void) unsigned int i; double freq; - if (get_msr(base_cpu, MSR_FSB_FREQ, &msr)) + if (get_msr(master_cpu, MSR_FSB_FREQ, &msr)) fprintf(outf, "SLM BCLK: unknown\n"); i = msr & 0xf; @@ -1248,6 +1254,84 @@ static const struct platform_data turbostat_pdata[] = { { 0, NULL }, }; +struct { + unsigned int uniform; + unsigned int pcore; + unsigned int ecore; + unsigned int lcore; +} perf_pmu_types; + +/* + * Events are enumerated in https://github.com/intel/perfmon + * and tools/perf/pmu-events/arch/x86/.../cache.json + */ +struct perf_l2_events { + unsigned long long refs; /* L2_REQUEST.ALL */ + unsigned long long hits; /* L2_REQUEST.HIT */ +}; + +struct perf_model_support { + unsigned int vfm; + struct perf_l2_events first; + struct perf_l2_events second; + struct perf_l2_events third; +} *perf_model_support; + +/* Perf Cache Events */ +#define PCE(ext_umask, umask) (((unsigned long long) ext_umask) << 40 | umask << 8 | 0x24) + +/* + * Enumerate up to three perf CPU PMU's in a system. + * The first, second, and third columns are populated without skipping, describing + * pcore, ecore, lcore PMUs, in order, if present. (The associated PMU "type" field is + * read from sysfs in all cases.) Eg. + * + * non-hybrid: + * GNR: pcore, {}, {} + * ADL-N: ecore, {}, {} + * hybrid: + * MTL: pcore, ecore, {}% + * ARL-H: pcore, ecore, lcore + * LNL: ecore, ecore%%, {} + * + * % MTL physical lcore share architecture and PMU with ecore, and are thus not enumerated separately. + * %% LNL physical lcore is enumerated by perf as ecore + */ +static struct perf_model_support turbostat_perf_model_support[] = { + { INTEL_SAPPHIRERAPIDS_X, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, {}, {} }, + { INTEL_EMERALDRAPIDS_X, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, {}, {} }, + { INTEL_GRANITERAPIDS_X, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, {}, {} }, + { INTEL_GRANITERAPIDS_D, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, {}, {} }, + { INTEL_DIAMONDRAPIDS_X, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, {}, {} }, + + { INTEL_ATOM_GRACEMONT, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {}, {} }, /* ADL-N */ + { INTEL_ATOM_CRESTMONT_X, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {}, {} }, /* SRF */ + { INTEL_ATOM_CRESTMONT, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {}, {} }, /* GRR */ + { INTEL_ATOM_DARKMONT_X, { PCE(0x01, 0xFF), PCE(0x01, 0xBF)}, {}, {} }, /* CWF */ + + { INTEL_ALDERLAKE, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_ALDERLAKE, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_ALDERLAKE_L, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_RAPTORLAKE, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_RAPTORLAKE_P, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_RAPTORLAKE_S, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_METEORLAKE_L, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_METEORLAKE, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + { INTEL_ARROWLAKE_U, { PCE(0x00, 0xFF), PCE(0x00, 0xDF)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)}, {} }, + + { INTEL_LUNARLAKE_M, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x00, 0x07), PCE(0x00, 0x02)}, {} }, + { INTEL_ARROWLAKE_H, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x00, 0x07), PCE(0x00, 0x02)}, { PCE(0x00, 0x00), PCE(0x00, 0x02)} }, + { INTEL_ARROWLAKE, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x00, 0x07), PCE(0x00, 0x02)}, {} }, + + { INTEL_PANTHERLAKE_L, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x01, 0xFF), PCE(0x01, 0xBF)}, {} }, + { INTEL_WILDCATLAKE_L, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x01, 0xFF), PCE(0x01, 0xBF)}, {} }, + + { INTEL_NOVALAKE, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x01, 0xFF), PCE(0x01, 0xBF)}, {} }, + { INTEL_NOVALAKE_L, { PCE(0x00, 0xFF), PCE(0x00, 0x5F)}, { PCE(0x01, 0xFF), PCE(0x01, 0xBF)}, {} }, + + { 0, {}, {}, {} } +}; + static const struct platform_features *platform; void probe_platform_features(unsigned int family, unsigned int model) @@ -1291,6 +1375,21 @@ void probe_platform_features(unsigned int family, unsigned int model) exit(1); } +void init_perf_model_support(unsigned int family, unsigned int model) +{ + int i; + + if (!genuine_intel) + return; + + for (i = 0; turbostat_perf_model_support[i].vfm; i++) { + if (VFM_FAMILY(turbostat_perf_model_support[i].vfm) == family && VFM_MODEL(turbostat_perf_model_support[i].vfm) == model) { + perf_model_support = &turbostat_perf_model_support[i]; + return; + } + } +} + /* Model specific support End */ #define TJMAX_DEFAULT 100 @@ -1307,6 +1406,7 @@ char *progname; #define CPU_SUBSET_MAXCPUS 8192 /* need to use before probe... */ cpu_set_t *cpu_present_set, *cpu_possible_set, *cpu_effective_set, *cpu_allowed_set, *cpu_affinity_set, *cpu_subset; +cpu_set_t *perf_pcore_set, *perf_ecore_set, *perf_lcore_set; size_t cpu_present_setsize, cpu_possible_setsize, cpu_effective_setsize, cpu_allowed_setsize, cpu_affinity_setsize, cpu_subset_size; #define MAX_ADDED_THREAD_COUNTERS 24 #define MAX_ADDED_CORE_COUNTERS 8 @@ -2007,6 +2107,10 @@ struct llc_stats { unsigned long long references; unsigned long long misses; }; +struct l2_stats { + unsigned long long references; + unsigned long long hits; +}; struct thread_data { struct timeval tv_begin; struct timeval tv_end; @@ -2020,6 +2124,7 @@ struct thread_data { unsigned long long nmi_count; unsigned int smi_count; struct llc_stats llc; + struct l2_stats l2; unsigned int cpu_id; unsigned int apic_id; unsigned int x2apic_id; @@ -2028,25 +2133,24 @@ struct thread_data { unsigned long long counter[MAX_ADDED_THREAD_COUNTERS]; unsigned long long perf_counter[MAX_ADDED_THREAD_COUNTERS]; unsigned long long pmt_counter[PMT_MAX_ADDED_THREAD_COUNTERS]; -} *thread_even, *thread_odd; +}; struct core_data { - int base_cpu; + int first_cpu; unsigned long long c3; unsigned long long c6; unsigned long long c7; unsigned long long mc6_us; /* duplicate as per-core for now, even though per module */ unsigned int core_temp_c; struct rapl_counter core_energy; /* MSR_CORE_ENERGY_STAT */ - unsigned int core_id; unsigned long long core_throt_cnt; unsigned long long counter[MAX_ADDED_CORE_COUNTERS]; unsigned long long perf_counter[MAX_ADDED_CORE_COUNTERS]; unsigned long long pmt_counter[PMT_MAX_ADDED_CORE_COUNTERS]; -} *core_even, *core_odd; +}; struct pkg_data { - int base_cpu; + int first_cpu; unsigned long long pc2; unsigned long long pc3; unsigned long long pc6; @@ -2066,7 +2170,6 @@ struct pkg_data { long long sam_mc6_ms; unsigned int sam_mhz; unsigned int sam_act_mhz; - unsigned int package_id; struct rapl_counter energy_pkg; /* MSR_PKG_ENERGY_STATUS */ struct rapl_counter energy_dram; /* MSR_DRAM_ENERGY_STATUS */ struct rapl_counter energy_cores; /* MSR_PP0_ENERGY_STATUS */ @@ -2079,24 +2182,10 @@ struct pkg_data { unsigned long long counter[MAX_ADDED_PACKAGE_COUNTERS]; unsigned long long perf_counter[MAX_ADDED_PACKAGE_COUNTERS]; unsigned long long pmt_counter[PMT_MAX_ADDED_PACKAGE_COUNTERS]; -} *package_even, *package_odd; +}; -#define ODD_COUNTERS thread_odd, core_odd, package_odd -#define EVEN_COUNTERS thread_even, core_even, package_even - -#define GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no) \ - ((thread_base) + \ - ((pkg_no) * \ - topo.nodes_per_pkg * topo.cores_per_node * topo.threads_per_core) + \ - ((node_no) * topo.cores_per_node * topo.threads_per_core) + \ - ((core_no) * topo.threads_per_core) + \ - (thread_no)) - -#define GET_CORE(core_base, core_no, node_no, pkg_no) \ - ((core_base) + \ - ((pkg_no) * topo.nodes_per_pkg * topo.cores_per_node) + \ - ((node_no) * topo.cores_per_node) + \ - (core_no)) +#define ODD_COUNTERS odd.threads, odd.cores, odd.packages +#define EVEN_COUNTERS even.threads, even.cores, even.packages /* * The accumulated sum of MSR is defined as a monotonic @@ -2135,7 +2224,7 @@ off_t idx_to_offset(int idx) switch (idx) { case IDX_PKG_ENERGY: - if (valid_rapl_msrs & RAPL_AMD_F17H) + if (platform->plat_rapl_msrs & RAPL_AMD_F17H) offset = MSR_PKG_ENERGY_STAT; else offset = MSR_PKG_ENERGY_STATUS; @@ -2279,25 +2368,28 @@ static void free_sys_msr_counters(void) sys.added_package_counters -= free_msr_counters_(&sys.pp); } -struct system_summary { - struct thread_data threads; - struct core_data cores; - struct pkg_data packages; -} average; +struct counters { + struct thread_data *threads; + struct core_data *cores; + struct pkg_data *packages; +} average, even, odd; struct platform_counters { struct rapl_counter energy_psys; /* MSR_PLATFORM_ENERGY_STATUS */ } platform_counters_odd, platform_counters_even; +#define MAX_HT_ID 3 /* support SMT-4 */ + struct cpu_topology { - int physical_package_id; + int cpu_id; + int core_id; /* unique within a package */ + int package_id; int die_id; int l3_id; - int logical_cpu_id; int physical_node_id; int logical_node_id; /* 0-based count within the package */ - int physical_core_id; - int thread_id; + int ht_id; /* unique within a core */ + int ht_sibling_cpu_id[MAX_HT_ID + 1]; int type; cpu_set_t *put_ids; /* Processing Unit/Thread IDs */ } *cpus; @@ -2306,12 +2398,12 @@ struct topo_params { int num_packages; int num_die; int num_cpus; - int num_cores; + int num_cores; /* system wide */ int allowed_packages; int allowed_cpus; int allowed_cores; int max_cpu_num; - int max_core_id; + int max_core_id; /* within a package */ int max_package_id; int max_die_id; int max_l3_id; @@ -2343,6 +2435,7 @@ int cpu_is_not_allowed(int cpu) return !CPU_ISSET_S(cpu, cpu_allowed_setsize, cpu_allowed_set); } +#define GLOBAL_CORE_ID(core_id, pkg_id) (core_id + pkg_id * (topo.max_core_id + 1)) /* * run func(thread, core, package) in topology order * skip non-present cpus @@ -2353,27 +2446,38 @@ int cpu_is_not_allowed(int cpu) int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *), struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base) { - int retval, pkg_no, core_no, thread_no, node_no; + int cpu, retval; retval = 0; - for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { - for (node_no = 0; node_no < topo.nodes_per_pkg; node_no++) { - for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { - for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) { - struct thread_data *t; - struct core_data *c; + for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { + struct thread_data *t; + struct core_data *c; + struct pkg_data *p; - t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no); + int pkg_id = cpus[cpu].package_id; - if (cpu_is_not_allowed(t->cpu_id)) - continue; + if (cpu_is_not_allowed(cpu)) + continue; - c = GET_CORE(core_base, core_no, node_no, pkg_no); + if (cpus[cpu].ht_id > 0) /* skip HT sibling */ + continue; - retval |= func(t, c, &pkg_base[pkg_no]); - } - } + t = &thread_base[cpu]; + c = &core_base[GLOBAL_CORE_ID(cpus[cpu].core_id, pkg_id)]; + p = &pkg_base[pkg_id]; + + retval |= func(t, c, p); + + /* Handle HT sibling now */ + int i; + + for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */ + if (cpus[cpu].ht_sibling_cpu_id[i] <= 0) + continue; + t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]]; + + retval |= func(t, c, p); } } return retval; @@ -2381,12 +2485,12 @@ int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pk int is_cpu_first_thread_in_core(struct thread_data *t, struct core_data *c) { - return ((int)t->cpu_id == c->base_cpu || c->base_cpu < 0); + return ((int)t->cpu_id == c->first_cpu || c->first_cpu < 0); } int is_cpu_first_core_in_package(struct thread_data *t, struct pkg_data *p) { - return ((int)t->cpu_id == p->base_cpu || p->base_cpu < 0); + return ((int)t->cpu_id == p->first_cpu || p->first_cpu < 0); } int is_cpu_first_thread_in_package(struct thread_data *t, struct core_data *c, struct pkg_data *p) @@ -2439,8 +2543,10 @@ static void bic_disable_msr_access(void) static void bic_disable_perf_access(void) { CLR_BIC(BIC_IPC, &bic_enabled); - CLR_BIC(BIC_LLC_RPS, &bic_enabled); + CLR_BIC(BIC_LLC_MRPS, &bic_enabled); CLR_BIC(BIC_LLC_HIT, &bic_enabled); + CLR_BIC(BIC_L2_MRPS, &bic_enabled); + CLR_BIC(BIC_L2_HIT, &bic_enabled); } static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, int group_fd, unsigned long flags) @@ -2552,10 +2658,10 @@ unsigned int cpu_to_domain(const struct perf_counter_info *pc, int cpu) return cpu; case SCOPE_CORE: - return cpus[cpu].physical_core_id; + return cpus[cpu].core_id; case SCOPE_PACKAGE: - return cpus[cpu].physical_package_id; + return cpus[cpu].package_id; } __builtin_unreachable(); @@ -2629,8 +2735,7 @@ void help(void) " sets the Thermal Control Circuit temperature in\n" " degrees Celsius\n" " -h, --help\n" - " print this help message\n" - " -v, --version\n\t\tprint version information\n\nFor more help, run \"man turbostat\"\n"); + " print this help message\n -v, --version\n\t\tprint version information\n\nFor more help, run \"man turbostat\"\n"); } /* @@ -2813,12 +2918,18 @@ void print_header(char *delim) if (DO_BIC(BIC_SMI)) outp += sprintf(outp, "%sSMI", (printed++ ? delim : "")); - if (DO_BIC(BIC_LLC_RPS)) - outp += sprintf(outp, "%sLLCkRPS", (printed++ ? delim : "")); + if (DO_BIC(BIC_LLC_MRPS)) + outp += sprintf(outp, "%sLLCMRPS", (printed++ ? delim : "")); if (DO_BIC(BIC_LLC_HIT)) outp += sprintf(outp, "%sLLC%%hit", (printed++ ? delim : "")); + if (DO_BIC(BIC_L2_MRPS)) + outp += sprintf(outp, "%sL2MRPS", (printed++ ? delim : "")); + + if (DO_BIC(BIC_L2_HIT)) + outp += sprintf(outp, "%sL2%%hit", (printed++ ? delim : "")); + for (mp = sys.tp; mp; mp = mp->next) outp += print_name(mp->width, &printed, delim, mp->name, mp->type, mp->format); @@ -3001,29 +3112,37 @@ void print_header(char *delim) } /* - * pct() + * pct(numerator, denominator) * - * If absolute value is < 1.1, return percentage - * otherwise, return nan + * Return sanity checked percentage (100.0 * numerator/denominotor) * - * return value is appropriate for printing percentages with %f - * while flagging some obvious erroneous values. + * n < 0: nan + * d <= 0: nan + * n/d > 1.1: nan */ -double pct(double d) +double pct(double numerator, double denominator) { + double retval; - double abs = fabs(d); + if (numerator < 0) + return nan(""); - if (abs < 1.10) - return (100.0 * d); - return nan(""); + if (denominator <= 0) + return nan(""); + + retval = 100.0 * numerator / denominator; + + if (retval > 110.0) + return nan(""); + + return retval; } int dump_counters(PER_THREAD_PARAMS) { int i; struct msr_counter *mp; - struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even; + struct platform_counters *pplat_cnt = p == odd.packages ? &platform_counters_odd : &platform_counters_even; outp += sprintf(outp, "t %p, c %p, p %p\n", t, c, p); @@ -3046,7 +3165,11 @@ int dump_counters(PER_THREAD_PARAMS) outp += sprintf(outp, "LLC refs: %lld", t->llc.references); outp += sprintf(outp, "LLC miss: %lld", t->llc.misses); - outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses) / t->llc.references)); + outp += sprintf(outp, "LLC Hit%%: %.2f", pct((t->llc.references - t->llc.misses), t->llc.references)); + + outp += sprintf(outp, "L2 refs: %lld", t->l2.references); + outp += sprintf(outp, "L2 hits: %lld", t->l2.hits); + outp += sprintf(outp, "L2 Hit%%: %.2f", pct(t->l2.hits, t->l2.references)); for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { outp += sprintf(outp, "tADDED [%d] %8s msr0x%x: %08llX %s\n", i, mp->name, mp->msr_num, t->counter[i], mp->sp->path); @@ -3054,7 +3177,7 @@ int dump_counters(PER_THREAD_PARAMS) } if (c && is_cpu_first_thread_in_core(t, c)) { - outp += sprintf(outp, "core: %d\n", c->core_id); + outp += sprintf(outp, "core: %d\n", cpus[t->cpu_id].core_id); outp += sprintf(outp, "c3: %016llX\n", c->c3); outp += sprintf(outp, "c6: %016llX\n", c->c6); outp += sprintf(outp, "c7: %016llX\n", c->c7); @@ -3074,8 +3197,6 @@ int dump_counters(PER_THREAD_PARAMS) } if (p && is_cpu_first_core_in_package(t, p)) { - outp += sprintf(outp, "package: %d\n", p->package_id); - outp += sprintf(outp, "Weighted cores: %016llX\n", p->pkg_wtd_core_c0); outp += sprintf(outp, "Any cores: %016llX\n", p->pkg_any_core_c0); outp += sprintf(outp, "Any GFX: %016llX\n", p->pkg_any_gfxe_c0); @@ -3141,7 +3262,7 @@ void get_perf_llc_stats(int cpu, struct llc_stats *llc) actual_read_size = read(fd_llc_percpu[cpu], &r, expected_read_size); if (actual_read_size == -1) - err(-1, "%s(cpu%d,) %d,,%ld\n", __func__, cpu, fd_llc_percpu[cpu], expected_read_size); + err(-1, "%s(cpu%d,) %d,,%ld", __func__, cpu, fd_llc_percpu[cpu], expected_read_size); llc->references = r.llc.references; llc->misses = r.llc.misses; @@ -3149,6 +3270,26 @@ void get_perf_llc_stats(int cpu, struct llc_stats *llc) warn("%s: failed to read perf_data (req %zu act %zu)", __func__, expected_read_size, actual_read_size); } +void get_perf_l2_stats(int cpu, struct l2_stats *l2) +{ + struct read_format { + unsigned long long num_read; + struct l2_stats l2; + } r; + const ssize_t expected_read_size = sizeof(r); + ssize_t actual_read_size; + + actual_read_size = read(fd_l2_percpu[cpu], &r, expected_read_size); + + if (actual_read_size == -1) + err(-1, "%s(cpu%d,) %d,,%ld", __func__, cpu, fd_l2_percpu[cpu], expected_read_size); + + l2->references = r.l2.references; + l2->hits = r.l2.hits; + if (actual_read_size != expected_read_size) + warn("%s: cpu%d: failed to read(%d) perf_data (req %zu act %zu)", __func__, cpu, fd_l2_percpu[cpu], expected_read_size, actual_read_size); +} + /* * column formatting convention & formats */ @@ -3167,7 +3308,7 @@ int format_counters(PER_THREAD_PARAMS) char *delim = "\t"; int printed = 0; - if (t == &average.threads) { + if (t == average.threads) { pplat_cnt = count & 1 ? &platform_counters_odd : &platform_counters_even; ++count; } @@ -3181,7 +3322,7 @@ int format_counters(PER_THREAD_PARAMS) return 0; /*if not summary line and --cpu is used */ - if ((t != &average.threads) && (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset))) + if ((t != average.threads) && (cpu_subset && !CPU_ISSET_S(t->cpu_id, cpu_subset_size, cpu_subset))) return 0; if (DO_BIC(BIC_USEC)) { @@ -3201,7 +3342,7 @@ int format_counters(PER_THREAD_PARAMS) tsc = t->tsc * tsc_tweak; /* topo columns, print blanks on 1st (average) line */ - if (t == &average.threads) { + if (t == average.threads) { if (DO_BIC(BIC_Package)) outp += sprintf(outp, "%s-", (printed++ ? delim : "")); if (DO_BIC(BIC_Die)) @@ -3221,7 +3362,7 @@ int format_counters(PER_THREAD_PARAMS) } else { if (DO_BIC(BIC_Package)) { if (p) - outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->package_id); + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].package_id); else outp += sprintf(outp, "%s-", (printed++ ? delim : "")); } @@ -3245,7 +3386,7 @@ int format_counters(PER_THREAD_PARAMS) } if (DO_BIC(BIC_Core)) { if (c) - outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_id); + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].core_id); else outp += sprintf(outp, "%s-", (printed++ ? delim : "")); } @@ -3261,7 +3402,7 @@ int format_counters(PER_THREAD_PARAMS) outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), 1.0 / units * t->aperf / interval_float); if (DO_BIC(BIC_Busy)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->mperf, tsc)); if (DO_BIC(BIC_Bzy_MHz)) { if (has_base_hz) @@ -3297,13 +3438,18 @@ int format_counters(PER_THREAD_PARAMS) outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->smi_count); /* LLC Stats */ - if (DO_BIC(BIC_LLC_RPS) || DO_BIC(BIC_LLC_HIT)) { - if (DO_BIC(BIC_LLC_RPS)) - outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000); + if (DO_BIC(BIC_LLC_MRPS)) + outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->llc.references / interval_float / 1000000); - if (DO_BIC(BIC_LLC_HIT)) - outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses) / t->llc.references)); - } + if (DO_BIC(BIC_LLC_HIT)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct((t->llc.references - t->llc.misses), t->llc.references)); + + /* L2 Stats */ + if (DO_BIC(BIC_L2_MRPS)) + outp += sprintf(outp, "%s%.0f", (printed++ ? delim : ""), t->l2.references / interval_float / 1000000); + + if (DO_BIC(BIC_L2_HIT)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), pct(t->l2.hits, t->l2.references)); /* Added Thread Counters */ for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { @@ -3315,7 +3461,7 @@ int format_counters(PER_THREAD_PARAMS) if (mp->type == COUNTER_USEC) outp += print_float_value(&printed, delim, t->counter[i] / interval_float / 10000); else - outp += print_float_value(&printed, delim, pct(t->counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(t->counter[i], tsc)); } } @@ -3329,7 +3475,7 @@ int format_counters(PER_THREAD_PARAMS) if (pp->type == COUNTER_USEC) outp += print_float_value(&printed, delim, t->perf_counter[i] / interval_float / 10000); else - outp += print_float_value(&printed, delim, pct(t->perf_counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(t->perf_counter[i], tsc)); } } @@ -3343,34 +3489,34 @@ int format_counters(PER_THREAD_PARAMS) break; case PMT_TYPE_XTAL_TIME: - value_converted = pct(value_raw / crystal_hz / interval_float); + value_converted = pct(value_raw / crystal_hz, interval_float); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); break; case PMT_TYPE_TCORE_CLOCK: - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), value_converted); } } /* C1 */ if (DO_BIC(BIC_CPU_c1)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(t->c1, tsc)); /* print per-core data only for 1st thread in core */ if (!is_cpu_first_thread_in_core(t, c)) goto done; if (DO_BIC(BIC_CPU_c3)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c3, tsc)); if (DO_BIC(BIC_CPU_c6)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c6, tsc)); if (DO_BIC(BIC_CPU_c7)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->c7, tsc)); /* Mod%c6 */ if (DO_BIC(BIC_Mod_c6)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(c->mc6_us, tsc)); if (DO_BIC(BIC_CoreTmp)) outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), c->core_temp_c); @@ -3386,7 +3532,7 @@ int format_counters(PER_THREAD_PARAMS) else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) outp += print_decimal_value(mp->width, &printed, delim, c->counter[i]); else if (mp->format == FORMAT_PERCENT) - outp += print_float_value(&printed, delim, pct(c->counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(c->counter[i], tsc)); } /* Added perf Core counters */ @@ -3396,7 +3542,7 @@ int format_counters(PER_THREAD_PARAMS) else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) outp += print_decimal_value(pp->width, &printed, delim, c->perf_counter[i]); else if (pp->format == FORMAT_PERCENT) - outp += print_float_value(&printed, delim, pct(c->perf_counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(c->perf_counter[i], tsc)); } /* Added PMT Core counters */ @@ -3409,12 +3555,12 @@ int format_counters(PER_THREAD_PARAMS) break; case PMT_TYPE_XTAL_TIME: - value_converted = pct(value_raw / crystal_hz / interval_float); + value_converted = pct(value_raw / crystal_hz, interval_float); outp += print_float_value(&printed, delim, value_converted); break; case PMT_TYPE_TCORE_CLOCK: - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); outp += print_float_value(&printed, delim, value_converted); } } @@ -3470,39 +3616,39 @@ int format_counters(PER_THREAD_PARAMS) if (DO_BIC(BIC_Totl_c0)) outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), 100 * p->pkg_wtd_core_c0 / tsc); /* can exceed 100% */ if (DO_BIC(BIC_Any_c0)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_core_c0, tsc)); if (DO_BIC(BIC_GFX_c0)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_any_gfxe_c0, tsc)); if (DO_BIC(BIC_CPUGFX)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pkg_both_core_gfxe_c0, tsc)); if (DO_BIC(BIC_Pkgpc2)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc2, tsc)); if (DO_BIC(BIC_Pkgpc3)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc3, tsc)); if (DO_BIC(BIC_Pkgpc6)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc6, tsc)); if (DO_BIC(BIC_Pkgpc7)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc7, tsc)); if (DO_BIC(BIC_Pkgpc8)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc8, tsc)); if (DO_BIC(BIC_Pkgpc9)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc9, tsc)); if (DO_BIC(BIC_Pkgpc10)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10 / tsc)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->pc10, tsc)); if (DO_BIC(BIC_Diec6)) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz / interval_float)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->die_c6 / crystal_hz, interval_float)); if (DO_BIC(BIC_CPU_LPI)) { if (p->cpu_lpi >= 0) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0 / interval_float)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->cpu_lpi / 1000000.0, interval_float)); else outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); } if (DO_BIC(BIC_SYS_LPI)) { if (p->sys_lpi >= 0) - outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0 / interval_float)); + outp += sprintf(outp, "%s%.2f", (printed++ ? delim : ""), pct(p->sys_lpi / 1000000.0, interval_float)); else outp += sprintf(outp, "%s(neg)", (printed++ ? delim : "")); } @@ -3524,11 +3670,9 @@ int format_counters(PER_THREAD_PARAMS) if (DO_BIC(BIC_RAM_J)) outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->energy_dram, RAPL_UNIT_JOULES, interval_float)); if (DO_BIC(BIC_PKG__)) - outp += - sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_pkg_perf_status, RAPL_UNIT_WATTS, interval_float)); + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_pkg_perf_status, RAPL_UNIT_WATTS, interval_float)); if (DO_BIC(BIC_RAM__)) - outp += - sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_dram_perf_status, RAPL_UNIT_WATTS, interval_float)); + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&p->rapl_dram_perf_status, RAPL_UNIT_WATTS, interval_float)); /* UncMHz */ if (DO_BIC(BIC_UNCORE_MHZ)) outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->uncore_mhz); @@ -3542,7 +3686,7 @@ int format_counters(PER_THREAD_PARAMS) else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) outp += print_decimal_value(mp->width, &printed, delim, p->counter[i]); else if (mp->format == FORMAT_PERCENT) - outp += print_float_value(&printed, delim, pct(p->counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(p->counter[i], tsc)); } /* Added perf Package Counters */ @@ -3554,7 +3698,7 @@ int format_counters(PER_THREAD_PARAMS) else if (pp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) outp += print_decimal_value(pp->width, &printed, delim, p->perf_counter[i]); else if (pp->format == FORMAT_PERCENT) - outp += print_float_value(&printed, delim, pct(p->perf_counter[i] / tsc)); + outp += print_float_value(&printed, delim, pct(p->perf_counter[i], tsc)); } /* Added PMT Package Counters */ @@ -3567,22 +3711,20 @@ int format_counters(PER_THREAD_PARAMS) break; case PMT_TYPE_XTAL_TIME: - value_converted = pct(value_raw / crystal_hz / interval_float); + value_converted = pct(value_raw / crystal_hz, interval_float); outp += print_float_value(&printed, delim, value_converted); break; case PMT_TYPE_TCORE_CLOCK: - value_converted = pct(value_raw / tcore_clock_freq_hz / interval_float); + value_converted = pct(value_raw / tcore_clock_freq_hz, interval_float); outp += print_float_value(&printed, delim, value_converted); } } - if (DO_BIC(BIC_SysWatt) && (t == &average.threads)) - outp += sprintf(outp, fmt8, (printed++ ? delim : ""), - rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_WATTS, interval_float)); - if (DO_BIC(BIC_Sys_J) && (t == &average.threads)) - outp += sprintf(outp, fmt8, (printed++ ? delim : ""), - rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_JOULES, interval_float)); + if (DO_BIC(BIC_SysWatt) && (t == average.threads)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_WATTS, interval_float)); + if (DO_BIC(BIC_Sys_J) && (t == average.threads)) + outp += sprintf(outp, fmt8, (printed++ ? delim : ""), rapl_counter_get_value(&pplat_cnt->energy_psys, RAPL_UNIT_JOULES, interval_float)); done: if (*(outp - 1) != '\n') @@ -3620,7 +3762,7 @@ void format_all_counters(PER_THREAD_PARAMS) if ((!count || (header_iterations && !(count % header_iterations))) || !summary_only) print_header("\t"); - format_counters(&average.threads, &average.cores, &average.packages); + format_counters(average.threads, average.cores, average.packages); count++; @@ -3795,7 +3937,7 @@ int delta_thread(struct thread_data *new, struct thread_data *old, struct core_d /* check for TSC < 1 Mcycles over interval */ if (old->tsc < (1000 * 1000)) errx(-3, "Insanely slow TSC rate, TSC stops in idle?\n" - "You can disable all c-states by booting with \"idle=poll\"\n" "or just the deep ones with \"processor.max_cstate=1\""); + "You can disable all c-states by booting with \"idle=poll\"\nor just the deep ones with \"processor.max_cstate=1\""); old->c1 = new->c1 - old->c1; @@ -3846,12 +3988,18 @@ int delta_thread(struct thread_data *new, struct thread_data *old, struct core_d if (DO_BIC(BIC_SMI)) old->smi_count = new->smi_count - old->smi_count; - if (DO_BIC(BIC_LLC_RPS)) + if (DO_BIC(BIC_LLC_MRPS) || DO_BIC(BIC_LLC_HIT)) old->llc.references = new->llc.references - old->llc.references; if (DO_BIC(BIC_LLC_HIT)) old->llc.misses = new->llc.misses - old->llc.misses; + if (DO_BIC(BIC_L2_MRPS) || DO_BIC(BIC_L2_HIT)) + old->l2.references = new->l2.references - old->l2.references; + + if (DO_BIC(BIC_L2_HIT)) + old->l2.hits = new->l2.hits - old->l2.hits; + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) old->counter[i] = new->counter[i]; @@ -3932,6 +4080,9 @@ void clear_counters(PER_THREAD_PARAMS) t->llc.references = 0; t->llc.misses = 0; + t->l2.references = 0; + t->l2.hits = 0; + c->c3 = 0; c->c6 = 0; c->c7 = 0; @@ -3940,9 +4091,6 @@ void clear_counters(PER_THREAD_PARAMS) rapl_counter_clear(&c->core_energy); c->core_throt_cnt = 0; - t->llc.references = 0; - t->llc.misses = 0; - p->pkg_wtd_core_c0 = 0; p->pkg_any_core_c0 = 0; p->pkg_any_gfxe_c0 = 0; @@ -4018,75 +4166,78 @@ int sum_counters(PER_THREAD_PARAMS) /* copy un-changing apic_id's */ if (DO_BIC(BIC_APIC)) - average.threads.apic_id = t->apic_id; + average.threads->apic_id = t->apic_id; if (DO_BIC(BIC_X2APIC)) - average.threads.x2apic_id = t->x2apic_id; + average.threads->x2apic_id = t->x2apic_id; /* remember first tv_begin */ - if (average.threads.tv_begin.tv_sec == 0) - average.threads.tv_begin = procsysfs_tv_begin; + if (average.threads->tv_begin.tv_sec == 0) + average.threads->tv_begin = procsysfs_tv_begin; /* remember last tv_end */ - average.threads.tv_end = t->tv_end; + average.threads->tv_end = t->tv_end; - average.threads.tsc += t->tsc; - average.threads.aperf += t->aperf; - average.threads.mperf += t->mperf; - average.threads.c1 += t->c1; + average.threads->tsc += t->tsc; + average.threads->aperf += t->aperf; + average.threads->mperf += t->mperf; + average.threads->c1 += t->c1; - average.threads.instr_count += t->instr_count; + average.threads->instr_count += t->instr_count; - average.threads.irq_count += t->irq_count; - average.threads.nmi_count += t->nmi_count; - average.threads.smi_count += t->smi_count; + average.threads->irq_count += t->irq_count; + average.threads->nmi_count += t->nmi_count; + average.threads->smi_count += t->smi_count; - average.threads.llc.references += t->llc.references; - average.threads.llc.misses += t->llc.misses; + average.threads->llc.references += t->llc.references; + average.threads->llc.misses += t->llc.misses; + + average.threads->l2.references += t->l2.references; + average.threads->l2.hits += t->l2.hits; for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW) continue; - average.threads.counter[i] += t->counter[i]; + average.threads->counter[i] += t->counter[i]; } for (i = 0, pp = sys.perf_tp; pp; i++, pp = pp->next) { if (pp->format == FORMAT_RAW) continue; - average.threads.perf_counter[i] += t->perf_counter[i]; + average.threads->perf_counter[i] += t->perf_counter[i]; } for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) { - average.threads.pmt_counter[i] += t->pmt_counter[i]; + average.threads->pmt_counter[i] += t->pmt_counter[i]; } /* sum per-core values only for 1st thread in core */ if (!is_cpu_first_thread_in_core(t, c)) return 0; - average.cores.c3 += c->c3; - average.cores.c6 += c->c6; - average.cores.c7 += c->c7; - average.cores.mc6_us += c->mc6_us; + average.cores->c3 += c->c3; + average.cores->c6 += c->c6; + average.cores->c7 += c->c7; + average.cores->mc6_us += c->mc6_us; - average.cores.core_temp_c = MAX(average.cores.core_temp_c, c->core_temp_c); - average.cores.core_throt_cnt = MAX(average.cores.core_throt_cnt, c->core_throt_cnt); + average.cores->core_temp_c = MAX(average.cores->core_temp_c, c->core_temp_c); + average.cores->core_throt_cnt = MAX(average.cores->core_throt_cnt, c->core_throt_cnt); - rapl_counter_accumulate(&average.cores.core_energy, &c->core_energy); + rapl_counter_accumulate(&average.cores->core_energy, &c->core_energy); for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW) continue; - average.cores.counter[i] += c->counter[i]; + average.cores->counter[i] += c->counter[i]; } for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) { if (pp->format == FORMAT_RAW) continue; - average.cores.perf_counter[i] += c->perf_counter[i]; + average.cores->perf_counter[i] += c->perf_counter[i]; } for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) { - average.cores.pmt_counter[i] += c->pmt_counter[i]; + average.cores->pmt_counter[i] += c->pmt_counter[i]; } /* sum per-pkg values only for 1st core in pkg */ @@ -4094,63 +4245,63 @@ int sum_counters(PER_THREAD_PARAMS) return 0; if (DO_BIC(BIC_Totl_c0)) - average.packages.pkg_wtd_core_c0 += p->pkg_wtd_core_c0; + average.packages->pkg_wtd_core_c0 += p->pkg_wtd_core_c0; if (DO_BIC(BIC_Any_c0)) - average.packages.pkg_any_core_c0 += p->pkg_any_core_c0; + average.packages->pkg_any_core_c0 += p->pkg_any_core_c0; if (DO_BIC(BIC_GFX_c0)) - average.packages.pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0; + average.packages->pkg_any_gfxe_c0 += p->pkg_any_gfxe_c0; if (DO_BIC(BIC_CPUGFX)) - average.packages.pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0; + average.packages->pkg_both_core_gfxe_c0 += p->pkg_both_core_gfxe_c0; - average.packages.pc2 += p->pc2; + average.packages->pc2 += p->pc2; if (DO_BIC(BIC_Pkgpc3)) - average.packages.pc3 += p->pc3; + average.packages->pc3 += p->pc3; if (DO_BIC(BIC_Pkgpc6)) - average.packages.pc6 += p->pc6; + average.packages->pc6 += p->pc6; if (DO_BIC(BIC_Pkgpc7)) - average.packages.pc7 += p->pc7; - average.packages.pc8 += p->pc8; - average.packages.pc9 += p->pc9; - average.packages.pc10 += p->pc10; - average.packages.die_c6 += p->die_c6; + average.packages->pc7 += p->pc7; + average.packages->pc8 += p->pc8; + average.packages->pc9 += p->pc9; + average.packages->pc10 += p->pc10; + average.packages->die_c6 += p->die_c6; - average.packages.cpu_lpi = p->cpu_lpi; - average.packages.sys_lpi = p->sys_lpi; + average.packages->cpu_lpi = p->cpu_lpi; + average.packages->sys_lpi = p->sys_lpi; - rapl_counter_accumulate(&average.packages.energy_pkg, &p->energy_pkg); - rapl_counter_accumulate(&average.packages.energy_dram, &p->energy_dram); - rapl_counter_accumulate(&average.packages.energy_cores, &p->energy_cores); - rapl_counter_accumulate(&average.packages.energy_gfx, &p->energy_gfx); + rapl_counter_accumulate(&average.packages->energy_pkg, &p->energy_pkg); + rapl_counter_accumulate(&average.packages->energy_dram, &p->energy_dram); + rapl_counter_accumulate(&average.packages->energy_cores, &p->energy_cores); + rapl_counter_accumulate(&average.packages->energy_gfx, &p->energy_gfx); - average.packages.gfx_rc6_ms = p->gfx_rc6_ms; - average.packages.uncore_mhz = p->uncore_mhz; - average.packages.gfx_mhz = p->gfx_mhz; - average.packages.gfx_act_mhz = p->gfx_act_mhz; - average.packages.sam_mc6_ms = p->sam_mc6_ms; - average.packages.sam_mhz = p->sam_mhz; - average.packages.sam_act_mhz = p->sam_act_mhz; + average.packages->gfx_rc6_ms = p->gfx_rc6_ms; + average.packages->uncore_mhz = p->uncore_mhz; + average.packages->gfx_mhz = p->gfx_mhz; + average.packages->gfx_act_mhz = p->gfx_act_mhz; + average.packages->sam_mc6_ms = p->sam_mc6_ms; + average.packages->sam_mhz = p->sam_mhz; + average.packages->sam_act_mhz = p->sam_act_mhz; - average.packages.pkg_temp_c = MAX(average.packages.pkg_temp_c, p->pkg_temp_c); + average.packages->pkg_temp_c = MAX(average.packages->pkg_temp_c, p->pkg_temp_c); - rapl_counter_accumulate(&average.packages.rapl_pkg_perf_status, &p->rapl_pkg_perf_status); - rapl_counter_accumulate(&average.packages.rapl_dram_perf_status, &p->rapl_dram_perf_status); + rapl_counter_accumulate(&average.packages->rapl_pkg_perf_status, &p->rapl_pkg_perf_status); + rapl_counter_accumulate(&average.packages->rapl_dram_perf_status, &p->rapl_dram_perf_status); for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { if ((mp->format == FORMAT_RAW) && (topo.num_packages == 0)) - average.packages.counter[i] = p->counter[i]; + average.packages->counter[i] = p->counter[i]; else - average.packages.counter[i] += p->counter[i]; + average.packages->counter[i] += p->counter[i]; } for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) { if ((pp->format == FORMAT_RAW) && (topo.num_packages == 0)) - average.packages.perf_counter[i] = p->perf_counter[i]; + average.packages->perf_counter[i] = p->perf_counter[i]; else - average.packages.perf_counter[i] += p->perf_counter[i]; + average.packages->perf_counter[i] += p->perf_counter[i]; } for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) { - average.packages.pmt_counter[i] += p->pmt_counter[i]; + average.packages->pmt_counter[i] += p->pmt_counter[i]; } return 0; @@ -4167,117 +4318,117 @@ void compute_average(PER_THREAD_PARAMS) struct perf_counter_info *pp; struct pmt_counter *ppmt; - clear_counters(&average.threads, &average.cores, &average.packages); + clear_counters(average.threads, average.cores, average.packages); for_all_cpus(sum_counters, t, c, p); /* Use the global time delta for the average. */ - average.threads.tv_delta = tv_delta; + average.threads->tv_delta = tv_delta; - average.threads.tsc /= topo.allowed_cpus; - average.threads.aperf /= topo.allowed_cpus; - average.threads.mperf /= topo.allowed_cpus; - average.threads.instr_count /= topo.allowed_cpus; - average.threads.c1 /= topo.allowed_cpus; + average.threads->tsc /= topo.allowed_cpus; + average.threads->aperf /= topo.allowed_cpus; + average.threads->mperf /= topo.allowed_cpus; + average.threads->instr_count /= topo.allowed_cpus; + average.threads->c1 /= topo.allowed_cpus; - if (average.threads.irq_count > 9999999) + if (average.threads->irq_count > 9999999) sums_need_wide_columns = 1; - if (average.threads.nmi_count > 9999999) + if (average.threads->nmi_count > 9999999) sums_need_wide_columns = 1; - average.cores.c3 /= topo.allowed_cores; - average.cores.c6 /= topo.allowed_cores; - average.cores.c7 /= topo.allowed_cores; - average.cores.mc6_us /= topo.allowed_cores; + average.cores->c3 /= topo.allowed_cores; + average.cores->c6 /= topo.allowed_cores; + average.cores->c7 /= topo.allowed_cores; + average.cores->mc6_us /= topo.allowed_cores; if (DO_BIC(BIC_Totl_c0)) - average.packages.pkg_wtd_core_c0 /= topo.allowed_packages; + average.packages->pkg_wtd_core_c0 /= topo.allowed_packages; if (DO_BIC(BIC_Any_c0)) - average.packages.pkg_any_core_c0 /= topo.allowed_packages; + average.packages->pkg_any_core_c0 /= topo.allowed_packages; if (DO_BIC(BIC_GFX_c0)) - average.packages.pkg_any_gfxe_c0 /= topo.allowed_packages; + average.packages->pkg_any_gfxe_c0 /= topo.allowed_packages; if (DO_BIC(BIC_CPUGFX)) - average.packages.pkg_both_core_gfxe_c0 /= topo.allowed_packages; + average.packages->pkg_both_core_gfxe_c0 /= topo.allowed_packages; - average.packages.pc2 /= topo.allowed_packages; + average.packages->pc2 /= topo.allowed_packages; if (DO_BIC(BIC_Pkgpc3)) - average.packages.pc3 /= topo.allowed_packages; + average.packages->pc3 /= topo.allowed_packages; if (DO_BIC(BIC_Pkgpc6)) - average.packages.pc6 /= topo.allowed_packages; + average.packages->pc6 /= topo.allowed_packages; if (DO_BIC(BIC_Pkgpc7)) - average.packages.pc7 /= topo.allowed_packages; + average.packages->pc7 /= topo.allowed_packages; - average.packages.pc8 /= topo.allowed_packages; - average.packages.pc9 /= topo.allowed_packages; - average.packages.pc10 /= topo.allowed_packages; - average.packages.die_c6 /= topo.allowed_packages; + average.packages->pc8 /= topo.allowed_packages; + average.packages->pc9 /= topo.allowed_packages; + average.packages->pc10 /= topo.allowed_packages; + average.packages->die_c6 /= topo.allowed_packages; for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW) continue; if (mp->type == COUNTER_ITEMS) { - if (average.threads.counter[i] > 9999999) + if (average.threads->counter[i] > 9999999) sums_need_wide_columns = 1; continue; } - average.threads.counter[i] /= topo.allowed_cpus; + average.threads->counter[i] /= topo.allowed_cpus; } for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW) continue; if (mp->type == COUNTER_ITEMS) { - if (average.cores.counter[i] > 9999999) + if (average.cores->counter[i] > 9999999) sums_need_wide_columns = 1; } - average.cores.counter[i] /= topo.allowed_cores; + average.cores->counter[i] /= topo.allowed_cores; } for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { if (mp->format == FORMAT_RAW) continue; if (mp->type == COUNTER_ITEMS) { - if (average.packages.counter[i] > 9999999) + if (average.packages->counter[i] > 9999999) sums_need_wide_columns = 1; } - average.packages.counter[i] /= topo.allowed_packages; + average.packages->counter[i] /= topo.allowed_packages; } for (i = 0, pp = sys.perf_tp; pp; i++, pp = pp->next) { if (pp->format == FORMAT_RAW) continue; if (pp->type == COUNTER_ITEMS) { - if (average.threads.perf_counter[i] > 9999999) + if (average.threads->perf_counter[i] > 9999999) sums_need_wide_columns = 1; continue; } - average.threads.perf_counter[i] /= topo.allowed_cpus; + average.threads->perf_counter[i] /= topo.allowed_cpus; } for (i = 0, pp = sys.perf_cp; pp; i++, pp = pp->next) { if (pp->format == FORMAT_RAW) continue; if (pp->type == COUNTER_ITEMS) { - if (average.cores.perf_counter[i] > 9999999) + if (average.cores->perf_counter[i] > 9999999) sums_need_wide_columns = 1; } - average.cores.perf_counter[i] /= topo.allowed_cores; + average.cores->perf_counter[i] /= topo.allowed_cores; } for (i = 0, pp = sys.perf_pp; pp; i++, pp = pp->next) { if (pp->format == FORMAT_RAW) continue; if (pp->type == COUNTER_ITEMS) { - if (average.packages.perf_counter[i] > 9999999) + if (average.packages->perf_counter[i] > 9999999) sums_need_wide_columns = 1; } - average.packages.perf_counter[i] /= topo.allowed_packages; + average.packages->perf_counter[i] /= topo.allowed_packages; } for (i = 0, ppmt = sys.pmt_tp; ppmt; i++, ppmt = ppmt->next) { - average.threads.pmt_counter[i] /= topo.allowed_cpus; + average.threads->pmt_counter[i] /= topo.allowed_cpus; } for (i = 0, ppmt = sys.pmt_cp; ppmt; i++, ppmt = ppmt->next) { - average.cores.pmt_counter[i] /= topo.allowed_cores; + average.cores->pmt_counter[i] /= topo.allowed_cores; } for (i = 0, ppmt = sys.pmt_pp; ppmt; i++, ppmt = ppmt->next) { - average.packages.pmt_counter[i] /= topo.allowed_packages; + average.packages->pmt_counter[i] /= topo.allowed_packages; } } @@ -4645,7 +4796,7 @@ void write_rapl_counter(struct rapl_counter *rc, struct rapl_counter_info_t *rci int get_rapl_counters(int cpu, unsigned int domain, struct core_data *c, struct pkg_data *p) { - struct platform_counters *pplat_cnt = p == package_odd ? &platform_counters_odd : &platform_counters_even; + struct platform_counters *pplat_cnt = p == odd.packages ? &platform_counters_odd : &platform_counters_even; unsigned long long perf_data[NUM_RAPL_COUNTERS + 1]; struct rapl_counter_info_t *rci; @@ -5002,32 +5153,18 @@ unsigned long pmt_read_counter(struct pmt_counter *ppmt, unsigned int domain_id) /* Rapl domain enumeration helpers */ static inline int get_rapl_num_domains(void) { - int num_packages = topo.max_package_id + 1; - int num_cores_per_package; - int num_cores; - if (!platform->has_per_core_rapl) - return num_packages; + return topo.num_packages; - num_cores_per_package = topo.max_core_id + 1; - num_cores = num_cores_per_package * num_packages; - - return num_cores; + return topo.num_cores; } static inline int get_rapl_domain_id(int cpu) { - int nr_cores_per_package = topo.max_core_id + 1; - int rapl_core_id; - if (!platform->has_per_core_rapl) - return cpus[cpu].physical_package_id; + return cpus[cpu].package_id; - /* Compute the system-wide unique core-id for @cpu */ - rapl_core_id = cpus[cpu].physical_core_id; - rapl_core_id += cpus[cpu].physical_package_id * nr_cores_per_package; - - return rapl_core_id; + return GLOBAL_CORE_ID(cpus[cpu].core_id, cpus[cpu].package_id); } /* @@ -5058,9 +5195,12 @@ int get_counters(PER_THREAD_PARAMS) get_smi_aperf_mperf(cpu, t); - if (DO_BIC(BIC_LLC_RPS) || DO_BIC(BIC_LLC_HIT)) + if (DO_BIC(BIC_LLC_MRPS) || DO_BIC(BIC_LLC_HIT)) get_perf_llc_stats(cpu, &t->llc); + if (DO_BIC(BIC_L2_MRPS) || DO_BIC(BIC_L2_HIT)) + get_perf_l2_stats(cpu, &t->l2); + if (DO_BIC(BIC_IPC)) if (read(get_instr_count_fd(cpu), &t->instr_count, sizeof(long long)) != sizeof(long long)) return -4; @@ -5125,7 +5265,7 @@ int get_counters(PER_THREAD_PARAMS) return -10; for (i = 0, pp = sys.pmt_cp; pp; i++, pp = pp->next) - c->pmt_counter[i] = pmt_read_counter(pp, c->core_id); + c->pmt_counter[i] = pmt_read_counter(pp, cpus[t->cpu_id].core_id); /* collect package counters only for 1st core in package */ if (!is_cpu_first_core_in_package(t, p)) @@ -5166,7 +5306,7 @@ int get_counters(PER_THREAD_PARAMS) } if (DO_BIC(BIC_UNCORE_MHZ)) - p->uncore_mhz = get_legacy_uncore_mhz(p->package_id); + p->uncore_mhz = get_legacy_uncore_mhz(cpus[t->cpu_id].package_id); if (DO_BIC(BIC_GFX_rc6)) p->gfx_rc6_ms = gfx_info[GFX_rc6].val_ull; @@ -5190,9 +5330,9 @@ int get_counters(PER_THREAD_PARAMS) char *path = NULL; if (mp->msr_num == 0) { - path = find_sysfs_path_by_id(mp->sp, p->package_id); + path = find_sysfs_path_by_id(mp->sp, cpus[t->cpu_id].package_id); if (path == NULL) { - warnx("%s: package_id %d not found", __func__, p->package_id); + warnx("%s: package_id %d not found", __func__, cpus[t->cpu_id].package_id); return -10; } } @@ -5204,7 +5344,7 @@ int get_counters(PER_THREAD_PARAMS) return -10; for (i = 0, pp = sys.pmt_pp; pp; i++, pp = pp->next) - p->pmt_counter[i] = pmt_read_counter(pp, p->package_id); + p->pmt_counter[i] = pmt_read_counter(pp, cpus[t->cpu_id].package_id); done: gettimeofday(&t->tv_end, (struct timezone *)NULL); @@ -5293,7 +5433,7 @@ void probe_cst_limit(void) return; } - get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr); + get_msr(master_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr); pkg_cstate_limit = pkg_cstate_limits[msr & 0xF]; } @@ -5305,9 +5445,9 @@ static void dump_platform_info(void) if (!platform->has_nhm_msrs || no_msr) return; - get_msr(base_cpu, MSR_PLATFORM_INFO, &msr); + get_msr(master_cpu, MSR_PLATFORM_INFO, &msr); - fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", base_cpu, msr); + fprintf(outf, "cpu%d: MSR_PLATFORM_INFO: 0x%08llx\n", master_cpu, msr); ratio = (msr >> 40) & 0xFF; fprintf(outf, "%d * %.1f = %.1f MHz max efficiency frequency\n", ratio, bclk, ratio * bclk); @@ -5323,8 +5463,8 @@ static void dump_power_ctl(void) if (!platform->has_nhm_msrs || no_msr) return; - get_msr(base_cpu, MSR_IA32_POWER_CTL, &msr); - fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", base_cpu, msr, msr & 0x2 ? "EN" : "DIS"); + get_msr(master_cpu, MSR_IA32_POWER_CTL, &msr); + fprintf(outf, "cpu%d: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", master_cpu, msr, msr & 0x2 ? "EN" : "DIS"); /* C-state Pre-wake Disable (CSTATE_PREWAKE_DISABLE) */ if (platform->has_cst_prewake_bit) @@ -5338,9 +5478,9 @@ static void dump_turbo_ratio_limit2(void) unsigned long long msr; unsigned int ratio; - get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT2, &msr); + get_msr(master_cpu, MSR_TURBO_RATIO_LIMIT2, &msr); - fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", base_cpu, msr); + fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT2: 0x%08llx\n", master_cpu, msr); ratio = (msr >> 8) & 0xFF; if (ratio) @@ -5357,9 +5497,9 @@ static void dump_turbo_ratio_limit1(void) unsigned long long msr; unsigned int ratio; - get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &msr); + get_msr(master_cpu, MSR_TURBO_RATIO_LIMIT1, &msr); - fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, msr); + fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", master_cpu, msr); ratio = (msr >> 56) & 0xFF; if (ratio) @@ -5400,13 +5540,12 @@ static void dump_turbo_ratio_limits(int trl_msr_offset) unsigned long long msr, core_counts; int shift; - get_msr(base_cpu, trl_msr_offset, &msr); - fprintf(outf, "cpu%d: MSR_%sTURBO_RATIO_LIMIT: 0x%08llx\n", - base_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY_" : "", msr); + get_msr(master_cpu, trl_msr_offset, &msr); + fprintf(outf, "cpu%d: MSR_%sTURBO_RATIO_LIMIT: 0x%08llx\n", master_cpu, trl_msr_offset == MSR_SECONDARY_TURBO_RATIO_LIMIT ? "SECONDARY_" : "", msr); if (platform->trl_msrs & TRL_CORECOUNT) { - get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts); - fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", base_cpu, core_counts); + get_msr(master_cpu, MSR_TURBO_RATIO_LIMIT1, &core_counts); + fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT1: 0x%08llx\n", master_cpu, core_counts); } else { core_counts = 0x0807060504030201; } @@ -5428,8 +5567,8 @@ static void dump_atom_turbo_ratio_limits(void) unsigned long long msr; unsigned int ratio; - get_msr(base_cpu, MSR_ATOM_CORE_RATIOS, &msr); - fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF); + get_msr(master_cpu, MSR_ATOM_CORE_RATIOS, &msr); + fprintf(outf, "cpu%d: MSR_ATOM_CORE_RATIOS: 0x%08llx\n", master_cpu, msr & 0xFFFFFFFF); ratio = (msr >> 0) & 0x3F; if (ratio) @@ -5443,8 +5582,8 @@ static void dump_atom_turbo_ratio_limits(void) if (ratio) fprintf(outf, "%d * %.1f = %.1f MHz base frequency\n", ratio, bclk, ratio * bclk); - get_msr(base_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr); - fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", base_cpu, msr & 0xFFFFFFFF); + get_msr(master_cpu, MSR_ATOM_CORE_TURBO_RATIOS, &msr); + fprintf(outf, "cpu%d: MSR_ATOM_CORE_TURBO_RATIOS: 0x%08llx\n", master_cpu, msr & 0xFFFFFFFF); ratio = (msr >> 24) & 0x3F; if (ratio) @@ -5473,9 +5612,9 @@ static void dump_knl_turbo_ratio_limits(void) unsigned int cores[buckets_no]; unsigned int ratio[buckets_no]; - get_msr(base_cpu, MSR_TURBO_RATIO_LIMIT, &msr); + get_msr(master_cpu, MSR_TURBO_RATIO_LIMIT, &msr); - fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", base_cpu, msr); + fprintf(outf, "cpu%d: MSR_TURBO_RATIO_LIMIT: 0x%08llx\n", master_cpu, msr); /* * Turbo encoding in KNL is as follows: @@ -5525,9 +5664,9 @@ static void dump_cst_cfg(void) if (!platform->has_nhm_msrs || no_msr) return; - get_msr(base_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr); + get_msr(master_cpu, MSR_PKG_CST_CONFIG_CONTROL, &msr); - fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", base_cpu, msr); + fprintf(outf, "cpu%d: MSR_PKG_CST_CONFIG_CONTROL: 0x%08llx", master_cpu, msr); fprintf(outf, " (%s%s%s%s%slocked, pkg-cstate-limit=%d (%s)", (msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "", @@ -5550,12 +5689,12 @@ static void dump_config_tdp(void) { unsigned long long msr; - get_msr(base_cpu, MSR_CONFIG_TDP_NOMINAL, &msr); - fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", base_cpu, msr); + get_msr(master_cpu, MSR_CONFIG_TDP_NOMINAL, &msr); + fprintf(outf, "cpu%d: MSR_CONFIG_TDP_NOMINAL: 0x%08llx", master_cpu, msr); fprintf(outf, " (base_ratio=%d)\n", (unsigned int)msr & 0xFF); - get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr); - fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_CONFIG_TDP_LEVEL_1, &msr); + fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_1: 0x%08llx (", master_cpu, msr); if (msr) { fprintf(outf, "PKG_MIN_PWR_LVL1=%d ", (unsigned int)(msr >> 48) & 0x7FFF); fprintf(outf, "PKG_MAX_PWR_LVL1=%d ", (unsigned int)(msr >> 32) & 0x7FFF); @@ -5564,8 +5703,8 @@ static void dump_config_tdp(void) } fprintf(outf, ")\n"); - get_msr(base_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr); - fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_CONFIG_TDP_LEVEL_2, &msr); + fprintf(outf, "cpu%d: MSR_CONFIG_TDP_LEVEL_2: 0x%08llx (", master_cpu, msr); if (msr) { fprintf(outf, "PKG_MIN_PWR_LVL2=%d ", (unsigned int)(msr >> 48) & 0x7FFF); fprintf(outf, "PKG_MAX_PWR_LVL2=%d ", (unsigned int)(msr >> 32) & 0x7FFF); @@ -5574,15 +5713,15 @@ static void dump_config_tdp(void) } fprintf(outf, ")\n"); - get_msr(base_cpu, MSR_CONFIG_TDP_CONTROL, &msr); - fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_CONFIG_TDP_CONTROL, &msr); + fprintf(outf, "cpu%d: MSR_CONFIG_TDP_CONTROL: 0x%08llx (", master_cpu, msr); if ((msr) & 0x3) fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3); fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); fprintf(outf, ")\n"); - get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); - fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); + fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", master_cpu, msr); fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0xFF); fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); fprintf(outf, ")\n"); @@ -5598,38 +5737,38 @@ void print_irtl(void) return; if (platform->supported_cstates & PC3) { - get_msr(base_cpu, MSR_PKGC3_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC3_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC3_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } if (platform->supported_cstates & PC6) { - get_msr(base_cpu, MSR_PKGC6_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC6_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC6_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } if (platform->supported_cstates & PC7) { - get_msr(base_cpu, MSR_PKGC7_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC7_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC7_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } if (platform->supported_cstates & PC8) { - get_msr(base_cpu, MSR_PKGC8_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC8_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC8_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } if (platform->supported_cstates & PC9) { - get_msr(base_cpu, MSR_PKGC9_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC9_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC9_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } if (platform->supported_cstates & PC10) { - get_msr(base_cpu, MSR_PKGC10_IRTL, &msr); - fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", base_cpu, msr); + get_msr(master_cpu, MSR_PKGC10_IRTL, &msr); + fprintf(outf, "cpu%d: MSR_PKGC10_IRTL: 0x%08llx (", master_cpu, msr); fprintf(outf, "%svalid, %lld ns)\n", msr & (1 << 15) ? "" : "NOT", (msr & 0x3FF) * irtl_time_units[(msr >> 10) & 0x3]); } } @@ -5676,6 +5815,26 @@ void free_fd_llc_percpu(void) free(fd_llc_percpu); fd_llc_percpu = NULL; + + BIC_NOT_PRESENT(BIC_LLC_MRPS); + BIC_NOT_PRESENT(BIC_LLC_HIT); +} + +void free_fd_l2_percpu(void) +{ + if (!fd_l2_percpu) + return; + + for (int i = 0; i < topo.max_cpu_num + 1; ++i) { + if (fd_l2_percpu[i] != 0) + close(fd_l2_percpu[i]); + } + + free(fd_l2_percpu); + fd_l2_percpu = NULL; + + BIC_NOT_PRESENT(BIC_L2_MRPS); + BIC_NOT_PRESENT(BIC_L2_HIT); } void free_fd_cstate(void) @@ -5780,21 +5939,36 @@ void free_all_buffers(void) cpu_affinity_set = NULL; cpu_affinity_setsize = 0; - free(thread_even); - free(core_even); - free(package_even); + if (perf_pcore_set) { + CPU_FREE(perf_pcore_set); + perf_pcore_set = NULL; + } - thread_even = NULL; - core_even = NULL; - package_even = NULL; + if (perf_ecore_set) { + CPU_FREE(perf_ecore_set); + perf_ecore_set = NULL; + } - free(thread_odd); - free(core_odd); - free(package_odd); + if (perf_lcore_set) { + CPU_FREE(perf_lcore_set); + perf_lcore_set = NULL; + } - thread_odd = NULL; - core_odd = NULL; - package_odd = NULL; + free(even.threads); + free(even.cores); + free(even.packages); + + even.threads = NULL; + even.cores = NULL; + even.packages = NULL; + + free(odd.threads); + free(odd.cores); + free(odd.packages); + + odd.threads = NULL; + odd.cores = NULL; + odd.packages = NULL; free(output_buffer); output_buffer = NULL; @@ -5803,6 +5977,7 @@ void free_all_buffers(void) free_fd_percpu(); free_fd_instr_count_percpu(); free_fd_llc_percpu(); + free_fd_l2_percpu(); free_fd_msr(); free_fd_rapl_percpu(); free_fd_cstate(); @@ -5852,7 +6027,7 @@ int cpu_is_first_core_in_package(int cpu) return cpu == parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", cpu); } -int get_physical_package_id(int cpu) +int get_package_id(int cpu) { return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/physical_package_id", cpu); } @@ -5885,7 +6060,7 @@ void set_node_data(void) for (pkg = 0; pkg < topo.num_packages; pkg++) { lnode = 0; for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { - if (cpus[cpu].physical_package_id != pkg) + if (cpus[cpu].package_id != pkg) continue; /* find a cpu with an unset logical_node_id */ if (cpus[cpu].logical_node_id != -1) @@ -5898,7 +6073,7 @@ void set_node_data(void) * the logical_node_id */ for (cpux = cpu; cpux <= topo.max_cpu_num; cpux++) { - if ((cpus[cpux].physical_package_id == pkg) && (cpus[cpux].physical_node_id == node)) { + if ((cpus[cpux].package_id == pkg) && (cpus[cpux].physical_node_id == node)) { cpus[cpux].logical_node_id = lnode; cpu_count++; } @@ -5917,7 +6092,7 @@ int get_physical_node_id(struct cpu_topology *thiscpu) char path[80]; FILE *filep; int i; - int cpu = thiscpu->logical_cpu_id; + int cpu = thiscpu->cpu_id; for (i = 0; i <= topo.max_cpu_num; i++) { sprintf(path, "/sys/devices/system/cpu/cpu%d/node%i/cpulist", cpu, i); @@ -5986,20 +6161,20 @@ static int parse_cpu_str(char *cpu_str, cpu_set_t *cpu_set, int cpu_set_size) return 0; } -int get_thread_siblings(struct cpu_topology *thiscpu) +int set_thread_siblings(struct cpu_topology *thiscpu) { char path[80], character; FILE *filep; unsigned long map; int so, shift, sib_core; - int cpu = thiscpu->logical_cpu_id; + int cpu = thiscpu->cpu_id; int offset = topo.max_cpu_num + 1; size_t size; int thread_id = 0; thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1)); - if (thiscpu->thread_id < 0) - thiscpu->thread_id = thread_id++; + if (thiscpu->ht_id < 0) + thiscpu->ht_id = thread_id++; if (!thiscpu->put_ids) return -1; @@ -6021,10 +6196,15 @@ int get_thread_siblings(struct cpu_topology *thiscpu) if ((map >> shift) & 0x1) { so = shift + offset; sib_core = get_core_id(so); - if (sib_core == thiscpu->physical_core_id) { + if (sib_core == thiscpu->core_id) { CPU_SET_S(so, size, thiscpu->put_ids); - if ((so != cpu) && (cpus[so].thread_id < 0)) - cpus[so].thread_id = thread_id++; + if ((so != cpu) && (cpus[so].ht_id < 0)) { + cpus[so].ht_id = thread_id; + cpus[cpu].ht_sibling_cpu_id[thread_id] = so; + if (debug) + fprintf(stderr, "%s: cpu%d.ht_sibling_cpu_id[%d] = %d\n", __func__, cpu, thread_id, so); + thread_id += 1; + } } } } @@ -6045,30 +6225,40 @@ int for_all_cpus_2(int (func) (struct thread_data *, struct core_data *, struct core_data *core_base, struct pkg_data *pkg_base, struct thread_data *thread_base2, struct core_data *core_base2, struct pkg_data *pkg_base2) { - int retval, pkg_no, node_no, core_no, thread_no; + int cpu, retval; retval = 0; - for (pkg_no = 0; pkg_no < topo.num_packages; ++pkg_no) { - for (node_no = 0; node_no < topo.nodes_per_pkg; ++node_no) { - for (core_no = 0; core_no < topo.cores_per_node; ++core_no) { - for (thread_no = 0; thread_no < topo.threads_per_core; ++thread_no) { - struct thread_data *t, *t2; - struct core_data *c, *c2; + for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { + struct thread_data *t, *t2; + struct core_data *c, *c2; + struct pkg_data *p, *p2; - t = GET_THREAD(thread_base, thread_no, core_no, node_no, pkg_no); + if (cpu_is_not_allowed(cpu)) + continue; - if (cpu_is_not_allowed(t->cpu_id)) - continue; + if (cpus[cpu].ht_id > 0) /* skip HT sibling */ + continue; - t2 = GET_THREAD(thread_base2, thread_no, core_no, node_no, pkg_no); + t = &thread_base[cpu]; + t2 = &thread_base2[cpu]; + c = &core_base[GLOBAL_CORE_ID(cpus[cpu].core_id, cpus[cpu].package_id)]; + c2 = &core_base2[GLOBAL_CORE_ID(cpus[cpu].core_id, cpus[cpu].package_id)]; + p = &pkg_base[cpus[cpu].package_id]; + p2 = &pkg_base2[cpus[cpu].package_id]; - c = GET_CORE(core_base, core_no, node_no, pkg_no); - c2 = GET_CORE(core_base2, core_no, node_no, pkg_no); + retval |= func(t, c, p, t2, c2, p2); - retval |= func(t, c, &pkg_base[pkg_no], t2, c2, &pkg_base2[pkg_no]); - } - } + /* Handle HT sibling now */ + int i; + + for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */ + if (cpus[cpu].ht_sibling_cpu_id[i] <= 0) + continue; + t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]]; + t2 = &thread_base2[cpus[cpu].ht_sibling_cpu_id[i]]; + + retval |= func(t, c, p, t2, c2, p2); } } return retval; @@ -6125,7 +6315,7 @@ static int update_effective_str(bool startup) pos = fgets(buf, 1024, fp); if (!pos) - err(1, "%s: file read failed\n", PATH_EFFECTIVE_CPUS); + err(1, "%s: file read failed", PATH_EFFECTIVE_CPUS); fclose(fp); @@ -6142,7 +6332,7 @@ static void update_effective_set(bool startup) update_effective_str(startup); if (parse_cpu_str(cpu_effective_str, cpu_effective_set, cpu_effective_setsize)) - err(1, "%s: cpu str malformat %s\n", PATH_EFFECTIVE_CPUS, cpu_effective_str); + err(1, "%s: cpu str malformat %s", PATH_EFFECTIVE_CPUS, cpu_effective_str); } void linux_perf_init(void); @@ -6150,6 +6340,7 @@ void msr_perf_init(void); void rapl_perf_init(void); void cstate_perf_init(void); void perf_llc_init(void); +void perf_l2_init(void); void added_perf_counters_init(void); void pmt_init(void); @@ -6162,6 +6353,7 @@ void re_initialize(void) rapl_perf_init(); cstate_perf_init(); perf_llc_init(); + perf_l2_init(); added_perf_counters_init(); pmt_init(); fprintf(outf, "turbostat: re-initialized with num_cpus %d, allowed_cpus %d\n", topo.num_cpus, topo.allowed_cpus); @@ -6170,14 +6362,14 @@ void re_initialize(void) void set_max_cpu_num(void) { FILE *filep; - int base_cpu; + int current_cpu; unsigned long dummy; char pathname[64]; - base_cpu = sched_getcpu(); - if (base_cpu < 0) + current_cpu = sched_getcpu(); + if (current_cpu < 0) err(1, "cannot find calling cpu ID"); - sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", base_cpu); + sprintf(pathname, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", current_cpu); filep = fopen_or_die(pathname, "r"); topo.max_cpu_num = 0; @@ -6205,9 +6397,13 @@ int mark_cpu_present(int cpu) return 0; } -int init_thread_id(int cpu) +int clear_ht_id(int cpu) { - cpus[cpu].thread_id = -1; + int i; + + cpus[cpu].ht_id = -1; + for (i = 0; i <= MAX_HT_ID; ++i) + cpus[cpu].ht_sibling_cpu_id[i] = -1; return 0; } @@ -6740,7 +6936,7 @@ int probe_dev_msr(void) struct stat sb; char pathname[32]; - sprintf(pathname, "/dev/msr%d", base_cpu); + sprintf(pathname, "/dev/msr%d", master_cpu); return !stat(pathname, &sb); } @@ -6749,7 +6945,7 @@ int probe_dev_cpu_msr(void) struct stat sb; char pathname[32]; - sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); + sprintf(pathname, "/dev/cpu/%d/msr", master_cpu); return !stat(pathname, &sb); } @@ -6809,7 +7005,7 @@ int check_for_cap_sys_rawio(void) free_and_exit: if (cap_free(caps) == -1) - err(-6, "cap_free\n"); + err(-6, "cap_free"); return ret; } @@ -6826,7 +7022,7 @@ void check_msr_permission(void) failed += check_for_cap_sys_rawio(); /* test file permissions */ - sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", base_cpu); + sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", master_cpu); if (euidaccess(pathname, R_OK)) { failed++; } @@ -6855,7 +7051,7 @@ void probe_bclk(void) else return; - get_msr(base_cpu, MSR_PLATFORM_INFO, &msr); + get_msr(master_cpu, MSR_PLATFORM_INFO, &msr); base_ratio = (msr >> 8) & 0xFF; base_hz = base_ratio * bclk * 1000000; @@ -7006,16 +7202,16 @@ static void probe_intel_uncore_frequency_cluster(void) } for (i = uncore_max_id; i >= 0; --i) { int k, l; - int package_id, domain_id, cluster_id; + int unc_pkg_id, domain_id, cluster_id; char name_buf[16]; sprintf(path_base, "/sys/devices/system/cpu/intel_uncore_frequency/uncore%02d", i); if (access(path_base, R_OK)) - err(1, "%s: %s\n", __func__, path_base); + err(1, "%s: %s", __func__, path_base); sprintf(path, "%s/package_id", path_base); - package_id = read_sysfs_int(path); + unc_pkg_id = read_sysfs_int(path); sprintf(path, "%s/domain_id", path_base); domain_id = read_sysfs_int(path); @@ -7038,7 +7234,7 @@ static void probe_intel_uncore_frequency_cluster(void) */ if BIC_IS_ENABLED (BIC_UNCORE_MHZ) - add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, package_id); + add_counter(0, path, name_buf, 0, SCOPE_PACKAGE, COUNTER_K2M, FORMAT_AVERAGE, 0, unc_pkg_id); if (quiet) continue; @@ -7047,7 +7243,7 @@ static void probe_intel_uncore_frequency_cluster(void) k = read_sysfs_int(path); sprintf(path, "%s/max_freq_khz", path_base); l = read_sysfs_int(path); - fprintf(outf, "Uncore Frequency package%d domain%d cluster%d: %d - %d MHz ", package_id, domain_id, cluster_id, k / 1000, l / 1000); + fprintf(outf, "Uncore Frequency package%d domain%d cluster%d: %d - %d MHz ", unc_pkg_id, domain_id, cluster_id, k / 1000, l / 1000); sprintf(path, "%s/initial_min_freq_khz", path_base); k = read_sysfs_int(path); @@ -7202,7 +7398,7 @@ static void dump_sysfs_cstate_config(void) for (state = 0; state < 10; ++state) { - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", master_cpu, state); input = fopen(path, "r"); if (input == NULL) continue; @@ -7218,14 +7414,14 @@ static void dump_sysfs_cstate_config(void) remove_underbar(name_buf); - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", base_cpu, state); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", master_cpu, state); input = fopen(path, "r"); if (input == NULL) continue; if (!fgets(desc, sizeof(desc), input)) err(1, "%s: failed to read file", path); - fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc); + fprintf(outf, "cpu%d: %s: %s", master_cpu, name_buf, desc); fclose(input); } } @@ -7238,7 +7434,7 @@ static void dump_sysfs_pstate_config(void) FILE *input; int turbo; - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", base_cpu); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_driver", master_cpu); input = fopen(path, "r"); if (input == NULL) { fprintf(outf, "NSFOD %s\n", path); @@ -7248,7 +7444,7 @@ static void dump_sysfs_pstate_config(void) err(1, "%s: failed to read file", path); fclose(input); - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", base_cpu); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", master_cpu); input = fopen(path, "r"); if (input == NULL) { fprintf(outf, "NSFOD %s\n", path); @@ -7258,8 +7454,8 @@ static void dump_sysfs_pstate_config(void) err(1, "%s: failed to read file", path); fclose(input); - fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf); - fprintf(outf, "cpu%d: cpufreq governor: %s", base_cpu, governor_buf); + fprintf(outf, "cpu%d: cpufreq driver: %s", master_cpu, driver_buf); + fprintf(outf, "cpu%d: cpufreq governor: %s", master_cpu, governor_buf); sprintf(path, "/sys/devices/system/cpu/cpufreq/boost"); input = fopen(path, "r"); @@ -7521,7 +7717,7 @@ double get_tdp_intel(void) unsigned long long msr; if (valid_rapl_msrs & RAPL_PKG_POWER_INFO) - if (!get_msr(base_cpu, MSR_PKG_POWER_INFO, &msr)) + if (!get_msr(master_cpu, MSR_PKG_POWER_INFO, &msr)) return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; return get_quirk_tdp(); } @@ -7560,7 +7756,7 @@ void rapl_probe_intel(void) CLR_BIC(BIC_RAM__, &bic_enabled); /* units on package 0, verify later other packages match */ - if (get_msr(base_cpu, MSR_RAPL_POWER_UNIT, &msr)) + if (get_msr(master_cpu, MSR_RAPL_POWER_UNIT, &msr)) return; rapl_power_units = 1.0 / (1 << (msr & 0xF)); @@ -7608,7 +7804,7 @@ void rapl_probe_amd(void) if (!valid_rapl_msrs || no_msr) return; - if (get_msr(base_cpu, MSR_RAPL_PWR_UNIT, &msr)) + if (get_msr(master_cpu, MSR_RAPL_PWR_UNIT, &msr)) return; rapl_time_units = ldexp(1.0, -(msr >> 16 & 0xf)); @@ -7817,8 +8013,7 @@ int print_rapl(PER_THREAD_PARAMS) return -1; } - fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr, - rapl_power_units, rapl_energy_units, rapl_time_units); + fprintf(outf, "cpu%d: %s: 0x%08llx (%f Watts, %f Joules, %f sec.)\n", cpu, msr_name, msr, rapl_power_units, rapl_energy_units, rapl_time_units); if (valid_rapl_msrs & RAPL_PKG_POWER_INFO) { @@ -7850,8 +8045,7 @@ int print_rapl(PER_THREAD_PARAMS) return -9; fprintf(outf, "cpu%d: MSR_VR_CURRENT_CONFIG: 0x%08llx\n", cpu, msr); - fprintf(outf, "cpu%d: PKG Limit #4: %f Watts (%slocked)\n", - cpu, ((msr >> 0) & 0x1FFF) * rapl_power_units, (msr >> 31) & 1 ? "" : "UN"); + fprintf(outf, "cpu%d: PKG Limit #4: %f Watts (%slocked)\n", cpu, ((msr >> 0) & 0x1FFF) * rapl_power_units, (msr >> 31) & 1 ? "" : "UN"); } if (valid_rapl_msrs & RAPL_DRAM_POWER_INFO) { @@ -7919,7 +8113,7 @@ void probe_rapl_msrs(void) if (offset < 0) return; - ret = get_msr(base_cpu, offset, &msr_value); + ret = get_msr(master_cpu, offset, &msr_value); if (ret) { if (debug) fprintf(outf, "Can not read RAPL_PKG_ENERGY MSR(0x%llx)\n", (unsigned long long)offset); @@ -8004,7 +8198,7 @@ int set_temperature_target(PER_THREAD_PARAMS) if (!platform->has_nhm_msrs || no_msr) goto guess; - if (get_msr(base_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr)) + if (get_msr(master_cpu, MSR_IA32_TEMPERATURE_TARGET, &msr)) goto guess; tcc_default = (msr >> 16) & 0xFF; @@ -8013,7 +8207,7 @@ int set_temperature_target(PER_THREAD_PARAMS) int bits = platform->tcc_offset_bits; unsigned long long enabled = 0; - if (bits && !get_msr(base_cpu, MSR_PLATFORM_INFO, &enabled)) + if (bits && !get_msr(master_cpu, MSR_PLATFORM_INFO, &enabled)) enabled = (enabled >> 30) & 1; if (bits && enabled) { @@ -8148,9 +8342,12 @@ void decode_feature_control_msr(void) if (no_msr) return; - if (!get_msr(base_cpu, MSR_IA32_FEAT_CTL, &msr)) + if (quiet) + return; + + if (!get_msr(master_cpu, MSR_IA32_FEAT_CTL, &msr)) fprintf(outf, "cpu%d: MSR_IA32_FEATURE_CONTROL: 0x%08llx (%sLocked %s)\n", - base_cpu, msr, msr & FEAT_CTL_LOCKED ? "" : "UN-", msr & (1 << 18) ? "SGX" : ""); + master_cpu, msr, msr & FEAT_CTL_LOCKED ? "" : "UN-", msr & (1 << 18) ? "SGX" : ""); } void decode_misc_enable_msr(void) @@ -8163,9 +8360,9 @@ void decode_misc_enable_msr(void) if (!genuine_intel) return; - if (!get_msr(base_cpu, MSR_IA32_MISC_ENABLE, &msr)) + if (!get_msr(master_cpu, MSR_IA32_MISC_ENABLE, &msr)) fprintf(outf, "cpu%d: MSR_IA32_MISC_ENABLE: 0x%08llx (%sTCC %sEIST %sMWAIT %sPREFETCH %sTURBO)\n", - base_cpu, msr, + master_cpu, msr, msr & MSR_IA32_MISC_ENABLE_TM1 ? "" : "No-", msr & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP ? "" : "No-", msr & MSR_IA32_MISC_ENABLE_MWAIT ? "" : "No-", @@ -8182,11 +8379,10 @@ void decode_misc_feature_control(void) if (!platform->has_msr_misc_feature_control) return; - if (!get_msr(base_cpu, MSR_MISC_FEATURE_CONTROL, &msr)) + if (!get_msr(master_cpu, MSR_MISC_FEATURE_CONTROL, &msr)) fprintf(outf, "cpu%d: MSR_MISC_FEATURE_CONTROL: 0x%08llx (%sL2-Prefetch %sL2-Prefetch-pair %sL1-Prefetch %sL1-IP-Prefetch)\n", - base_cpu, msr, msr & (0 << 0) ? "No-" : "", msr & (1 << 0) ? "No-" : "", - msr & (2 << 0) ? "No-" : "", msr & (3 << 0) ? "No-" : ""); + master_cpu, msr, msr & (0 << 0) ? "No-" : "", msr & (1 << 0) ? "No-" : "", msr & (2 << 0) ? "No-" : "", msr & (3 << 0) ? "No-" : ""); } /* @@ -8206,9 +8402,9 @@ void decode_misc_pwr_mgmt_msr(void) if (!platform->has_msr_misc_pwr_mgmt) return; - if (!get_msr(base_cpu, MSR_MISC_PWR_MGMT, &msr)) + if (!get_msr(master_cpu, MSR_MISC_PWR_MGMT, &msr)) fprintf(outf, "cpu%d: MSR_MISC_PWR_MGMT: 0x%08llx (%sable-EIST_Coordination %sable-EPB %sable-OOB)\n", - base_cpu, msr, msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 1) ? "EN" : "DIS", msr & (1 << 8) ? "EN" : "DIS"); + master_cpu, msr, msr & (1 << 0) ? "DIS" : "EN", msr & (1 << 1) ? "EN" : "DIS", msr & (1 << 8) ? "EN" : "DIS"); } /* @@ -8227,13 +8423,11 @@ void decode_c6_demotion_policy_msr(void) if (!platform->has_msr_c6_demotion_policy_config) return; - if (!get_msr(base_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr)) - fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n", - base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); + if (!get_msr(master_cpu, MSR_CC6_DEMOTION_POLICY_CONFIG, &msr)) + fprintf(outf, "cpu%d: MSR_CC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-CC6-Demotion)\n", master_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); - if (!get_msr(base_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr)) - fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n", - base_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); + if (!get_msr(master_cpu, MSR_MC6_DEMOTION_POLICY_CONFIG, &msr)) + fprintf(outf, "cpu%d: MSR_MC6_DEMOTION_POLICY_CONFIG: 0x%08llx (%sable-MC6-Demotion)\n", master_cpu, msr, msr & (1 << 0) ? "EN" : "DIS"); } void print_dev_latency(void) @@ -8268,7 +8462,7 @@ static int has_perf_instr_count_access(void) if (no_perf) return 0; - fd = open_perf_counter(base_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, -1, 0); + fd = open_perf_counter(master_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_INSTRUCTIONS, -1, 0); if (fd != -1) close(fd); @@ -8321,25 +8515,126 @@ int add_rapl_perf_counter(int cpu, struct rapl_counter_info_t *rci, const struct return ret; } +char cpuset_buf[1024]; +int initialize_cpu_set_from_sysfs(cpu_set_t *cpu_set, char *sysfs_path, char *sysfs_file) +{ + FILE *fp; + char path[128]; + + if (snprintf(path, 128, "%s/%s", sysfs_path, sysfs_file) > 128) + err(-1, "%s %s", sysfs_path, sysfs_file); + + fp = fopen(path, "r"); + if (!fp) { + warn("open %s", path); + return -1; + } + if (fread(cpuset_buf, sizeof(char), 1024, fp) == 0) { + warn("read %s", sysfs_path); + goto err; + } + if (parse_cpu_str(cpuset_buf, cpu_set, cpu_possible_setsize)) { + warnx("%s: cpu str malformat %s\n", sysfs_path, cpu_effective_str); + goto err; + } + return 0; + +err: + fclose(fp); + return -1; +} + +void print_cpu_set(char *s, cpu_set_t *set) +{ + int i; + + assert(MAX_BIC < CPU_SETSIZE); + + printf("%s:", s); + + for (i = 0; i <= topo.max_cpu_num; ++i) + if (CPU_ISSET(i, set)) + printf(" %d", i); + putchar('\n'); +} + +void linux_perf_init_hybrid_cpus(void) +{ + char *perf_cpu_pcore_path = "/sys/devices/cpu_core"; + char *perf_cpu_ecore_path = "/sys/devices/cpu_atom"; + char *perf_cpu_lcore_path = "/sys/devices/cpu_lowpower"; + char path[128]; + + if (!access(perf_cpu_pcore_path, F_OK)) { + perf_pcore_set = CPU_ALLOC((topo.max_cpu_num + 1)); + if (perf_pcore_set == NULL) + err(3, "CPU_ALLOC"); + CPU_ZERO_S(cpu_possible_setsize, perf_pcore_set); + initialize_cpu_set_from_sysfs(perf_pcore_set, perf_cpu_pcore_path, "cpus"); + if (debug) + print_cpu_set("perf pcores", perf_pcore_set); + sprintf(path, "%s/%s", perf_cpu_pcore_path, "type"); + perf_pmu_types.pcore = snapshot_sysfs_counter(path); + } + + if (!access(perf_cpu_ecore_path, F_OK)) { + perf_ecore_set = CPU_ALLOC((topo.max_cpu_num + 1)); + if (perf_ecore_set == NULL) + err(3, "CPU_ALLOC"); + CPU_ZERO_S(cpu_possible_setsize, perf_ecore_set); + initialize_cpu_set_from_sysfs(perf_ecore_set, perf_cpu_ecore_path, "cpus"); + if (debug) + print_cpu_set("perf ecores", perf_ecore_set); + sprintf(path, "%s/%s", perf_cpu_ecore_path, "type"); + perf_pmu_types.ecore = snapshot_sysfs_counter(path); + } + + if (!access(perf_cpu_lcore_path, F_OK)) { + perf_lcore_set = CPU_ALLOC((topo.max_cpu_num + 1)); + if (perf_lcore_set == NULL) + err(3, "CPU_ALLOC"); + CPU_ZERO_S(cpu_possible_setsize, perf_lcore_set); + initialize_cpu_set_from_sysfs(perf_lcore_set, perf_cpu_lcore_path, "cpus"); + if (debug) + print_cpu_set("perf lcores", perf_lcore_set); + sprintf(path, "%s/%s", perf_cpu_lcore_path, "type"); + perf_pmu_types.lcore = snapshot_sysfs_counter(path); + } +} + /* - * Linux-perf manages the HW instructions-retired counter - * by enabling when requested, and hiding rollover + * Linux-perf related initialization */ void linux_perf_init(void) { + char path[128]; + char *perf_cpu_path = "/sys/devices/cpu"; + if (access("/proc/sys/kernel/perf_event_paranoid", F_OK)) return; + if (!access(perf_cpu_path, F_OK)) { + sprintf(path, "%s/%s", perf_cpu_path, "type"); + perf_pmu_types.uniform = snapshot_sysfs_counter(path); + } else { + linux_perf_init_hybrid_cpus(); + } + if (BIC_IS_ENABLED(BIC_IPC) && cpuid_has_aperf_mperf) { fd_instr_count_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); if (fd_instr_count_percpu == NULL) err(-1, "calloc fd_instr_count_percpu"); } - if (BIC_IS_ENABLED(BIC_LLC_RPS)) { + if (BIC_IS_ENABLED(BIC_LLC_MRPS) || BIC_IS_ENABLED(BIC_LLC_HIT)) { fd_llc_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); if (fd_llc_percpu == NULL) err(-1, "calloc fd_llc_percpu"); } + if (BIC_IS_ENABLED(BIC_L2_MRPS) || BIC_IS_ENABLED(BIC_L2_HIT)) { + fd_l2_percpu = calloc(topo.max_cpu_num + 1, sizeof(int)); + if (fd_l2_percpu == NULL) + err(-1, "calloc fd_l2_percpu"); + } } void rapl_perf_init(void) @@ -8397,7 +8692,7 @@ void rapl_perf_init(void) domain_visited[next_domain] = 1; - if ((cai->flags & RAPL_COUNTER_FLAG_PLATFORM_COUNTER) && (cpu != base_cpu)) + if ((cai->flags & RAPL_COUNTER_FLAG_PLATFORM_COUNTER) && (cpu != master_cpu)) continue; struct rapl_counter_info_t *rci = &rapl_counter_info_perdomain[next_domain]; @@ -8450,8 +8745,7 @@ void rapl_perf_init(void) /* Assumes msr_counter_info is populated */ static int has_amperf_access(void) { - return cpuid_has_aperf_mperf && msr_counter_arch_infos[MSR_ARCH_INFO_APERF_INDEX].present && - msr_counter_arch_infos[MSR_ARCH_INFO_MPERF_INDEX].present; + return cpuid_has_aperf_mperf && msr_counter_arch_infos[MSR_ARCH_INFO_APERF_INDEX].present && msr_counter_arch_infos[MSR_ARCH_INFO_MPERF_INDEX].present; } int *get_cstate_perf_group_fd(struct cstate_counter_info_t *cci, const char *group_name) @@ -8647,8 +8941,8 @@ void cstate_perf_init_(bool soft_c1) if (cpu_is_not_allowed(cpu)) continue; - const int core_id = cpus[cpu].physical_core_id; - const int pkg_id = cpus[cpu].physical_package_id; + const int core_id = cpus[cpu].core_id; + const int pkg_id = cpus[cpu].package_id; assert(core_id < cores_visited_elems); assert(pkg_id < pkg_visited_elems); @@ -8662,8 +8956,7 @@ void cstate_perf_init_(bool soft_c1) if (!per_core && pkg_visited[pkg_id]) continue; - const bool counter_needed = BIC_IS_ENABLED(cai->bic_number) || - (soft_c1 && (cai->flags & CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY)); + const bool counter_needed = BIC_IS_ENABLED(cai->bic_number) || (soft_c1 && (cai->flags & CSTATE_COUNTER_FLAG_SOFT_C1_DEPENDENCY)); const bool counter_supported = (platform->supported_cstates & cai->feature_mask); if (counter_needed && counter_supported) { @@ -8772,6 +9065,29 @@ void probe_pstates(void) for_all_cpus(print_perf_limit, ODD_COUNTERS); } +void dump_word_chars(unsigned int word) +{ + int i; + + for (i = 0; i < 4; ++i) + fprintf(outf, "%c", (word >> (i * 8)) & 0xFF); +} + +void dump_cpuid_hypervisor(void) +{ + unsigned int ebx = 0; + unsigned int ecx = 0; + unsigned int edx = 0; + + __cpuid(0x40000000, max_extended_level, ebx, ecx, edx); + + fprintf(outf, "Hypervisor: "); + dump_word_chars(ebx); + dump_word_chars(ecx); + dump_word_chars(edx); + fprintf(outf, "\n"); +} + void process_cpuid() { unsigned int eax, ebx, ecx, edx; @@ -8803,6 +9119,7 @@ void process_cpuid() model += ((fms >> 16) & 0xf) << 4; ecx_flags = ecx; edx_flags = edx; + cpuid_has_hv = ecx_flags & (1 << 31); if (!no_msr) { if (get_msr(sched_getcpu(), MSR_IA32_UCODE_REV, &ucode_patch)) @@ -8826,18 +9143,22 @@ void process_cpuid() fputc('\n', outf); fprintf(outf, "CPUID(0x80000000): max_extended_levels: 0x%x\n", max_extended_level); - fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", - ecx_flags & (1 << 0) ? "SSE3" : "-", - ecx_flags & (1 << 3) ? "MONITOR" : "-", - ecx_flags & (1 << 6) ? "SMX" : "-", - ecx_flags & (1 << 7) ? "EIST" : "-", - ecx_flags & (1 << 8) ? "TM2" : "-", - edx_flags & (1 << 4) ? "TSC" : "-", - edx_flags & (1 << 5) ? "MSR" : "-", - edx_flags & (1 << 22) ? "ACPI-TM" : "-", edx_flags & (1 << 28) ? "HT" : "-", edx_flags & (1 << 29) ? "TM" : "-"); + fprintf(outf, "CPUID(1): %sSSE3 %sMONITOR %sSMX %sEIST %sTM2 %sHV %sTSC %sMSR %sACPI-TM %sHT %sTM\n", + ecx_flags & (1 << 0) ? "" : "No-", + ecx_flags & (1 << 3) ? "" : "No-", + ecx_flags & (1 << 6) ? "" : "No-", + ecx_flags & (1 << 7) ? "" : "No-", + ecx_flags & (1 << 8) ? "" : "No-", + cpuid_has_hv ? "" : "No-", + edx_flags & (1 << 4) ? "" : "No-", + edx_flags & (1 << 5) ? "" : "No-", + edx_flags & (1 << 22) ? "" : "No-", edx_flags & (1 << 28) ? "" : "No-", edx_flags & (1 << 29) ? "" : "No-"); } + if (!quiet && cpuid_has_hv) + dump_cpuid_hypervisor(); probe_platform_features(family, model); + init_perf_model_support(family, model); if (!(edx_flags & (1 << 5))) errx(1, "CPUID: no MSR"); @@ -8887,7 +9208,7 @@ void process_cpuid() if (!quiet) decode_misc_enable_msr(); - if (max_level >= 0x7 && !quiet) { + if (max_level >= 0x7) { int has_sgx; ecx = 0; @@ -8896,9 +9217,10 @@ void process_cpuid() has_sgx = ebx & (1 << 2); - is_hybrid = edx & (1 << 15); + is_hybrid = !!(edx & (1 << 15)); - fprintf(outf, "CPUID(7): %sSGX %sHybrid\n", has_sgx ? "" : "No-", is_hybrid ? "" : "No-"); + if (!quiet) + fprintf(outf, "CPUID(7): %sSGX %sHybrid\n", has_sgx ? "" : "No-", is_hybrid ? "" : "No-"); if (has_sgx) decode_feature_control_msr(); @@ -8924,8 +9246,7 @@ void process_cpuid() if (crystal_hz) { tsc_hz = (unsigned long long)crystal_hz *ebx_tsc / eax_crystal; if (!quiet) - fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n", - tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal); + fprintf(outf, "TSC: %lld MHz (%d Hz * %d / %d / 1000000)\n", tsc_hz / 1000000, crystal_hz, ebx_tsc, eax_crystal); } } } @@ -9003,7 +9324,8 @@ void probe_pm_features(void) decode_misc_feature_control(); } -/* perf_llc_probe +/* + * has_perf_llc_access() * * return 1 on success, else 0 */ @@ -9014,7 +9336,7 @@ int has_perf_llc_access(void) if (no_perf) return 0; - fd = open_perf_counter(base_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, -1, PERF_FORMAT_GROUP); + fd = open_perf_counter(master_cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, -1, PERF_FORMAT_GROUP); if (fd != -1) close(fd); @@ -9032,22 +9354,22 @@ void perf_llc_init(void) if (no_perf) return; - if (!(BIC_IS_ENABLED(BIC_LLC_RPS) && BIC_IS_ENABLED(BIC_LLC_HIT))) + if (!(BIC_IS_ENABLED(BIC_LLC_MRPS) || BIC_IS_ENABLED(BIC_LLC_HIT))) return; + assert(fd_llc_percpu != 0); + for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { if (cpu_is_not_allowed(cpu)) continue; - assert(fd_llc_percpu != 0); fd_llc_percpu[cpu] = open_perf_counter(cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_REFERENCES, -1, PERF_FORMAT_GROUP); if (fd_llc_percpu[cpu] == -1) { warnx("%s: perf REFS: failed to open counter on cpu%d", __func__, cpu); free_fd_llc_percpu(); return; } - assert(fd_llc_percpu != 0); retval = open_perf_counter(cpu, PERF_TYPE_HARDWARE, PERF_COUNT_HW_CACHE_MISSES, fd_llc_percpu[cpu], PERF_FORMAT_GROUP); if (retval == -1) { warnx("%s: perf MISS: failed to open counter on cpu%d", __func__, cpu); @@ -9055,10 +9377,90 @@ void perf_llc_init(void) return; } } - BIC_PRESENT(BIC_LLC_RPS); + BIC_PRESENT(BIC_LLC_MRPS); BIC_PRESENT(BIC_LLC_HIT); } +void perf_l2_init(void) +{ + int cpu; + int retval; + + if (no_perf) + return; + if (!(BIC_IS_ENABLED(BIC_L2_MRPS) || BIC_IS_ENABLED(BIC_L2_HIT))) + return; + if (perf_model_support == NULL) + return; + + assert(fd_l2_percpu != 0); + + for (cpu = 0; cpu <= topo.max_cpu_num; ++cpu) { + + if (cpu_is_not_allowed(cpu)) + continue; + + if (!is_hybrid) { + fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP); + if (fd_l2_percpu[cpu] == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.refs); + free_fd_l2_percpu(); + return; + } + retval = open_perf_counter(cpu, perf_pmu_types.uniform, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP); + if (retval == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.uniform, perf_model_support->first.hits); + free_fd_l2_percpu(); + return; + } + continue; + } + if (perf_pcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_pcore_set)) { + fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.refs, -1, PERF_FORMAT_GROUP); + if (fd_l2_percpu[cpu] == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.refs); + free_fd_l2_percpu(); + return; + } + retval = open_perf_counter(cpu, perf_pmu_types.pcore, perf_model_support->first.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP); + if (retval == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->first.hits); + free_fd_l2_percpu(); + return; + } + } else if (perf_ecore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_ecore_set)) { + fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.refs, -1, PERF_FORMAT_GROUP); + if (fd_l2_percpu[cpu] == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.refs); + free_fd_l2_percpu(); + return; + } + retval = open_perf_counter(cpu, perf_pmu_types.ecore, perf_model_support->second.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP); + if (retval == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->second.hits); + free_fd_l2_percpu(); + return; + } + } else if (perf_lcore_set && CPU_ISSET_S(cpu, cpu_possible_setsize, perf_lcore_set)) { + fd_l2_percpu[cpu] = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.refs, -1, PERF_FORMAT_GROUP); + if (fd_l2_percpu[cpu] == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) REFS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.refs); + free_fd_l2_percpu(); + return; + } + retval = open_perf_counter(cpu, perf_pmu_types.lcore, perf_model_support->third.hits, fd_l2_percpu[cpu], PERF_FORMAT_GROUP); + if (retval == -1) { + err(-1, "%s(cpu%d, 0x%x, 0x%llx) HITS", __func__, cpu, perf_pmu_types.pcore, perf_model_support->third.hits); + free_fd_l2_percpu(); + return; + } + } else + err(-1, "%s: cpu%d: type %d", __func__, cpu, cpus[cpu].type); + } + BIC_PRESENT(BIC_L2_MRPS); + BIC_PRESENT(BIC_L2_HIT); +} + /* * in /dev/cpu/ return success for names that are numbers * ie. filter out ".", "..", "microcode". @@ -9071,33 +9473,6 @@ int dir_filter(const struct dirent *dirp) return 0; } -char *possible_file = "/sys/devices/system/cpu/possible"; -char possible_buf[1024]; - -int initialize_cpu_possible_set(void) -{ - FILE *fp; - - fp = fopen(possible_file, "r"); - if (!fp) { - warn("open %s", possible_file); - return -1; - } - if (fread(possible_buf, sizeof(char), 1024, fp) == 0) { - warn("read %s", possible_file); - goto err; - } - if (parse_cpu_str(possible_buf, cpu_possible_set, cpu_possible_setsize)) { - warnx("%s: cpu str malformat %s\n", possible_file, cpu_effective_str); - goto err; - } - return 0; - -err: - fclose(fp); - return -1; -} - void topology_probe(bool startup) { int i; @@ -9137,7 +9512,7 @@ void topology_probe(bool startup) err(3, "CPU_ALLOC"); cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set); - initialize_cpu_possible_set(); + initialize_cpu_set_from_sysfs(cpu_possible_set, "/sys/devices/system/cpu", "possible"); /* * Allocate and initialize cpu_effective_set @@ -9205,13 +9580,13 @@ void topology_probe(bool startup) cpu_affinity_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); CPU_ZERO_S(cpu_affinity_setsize, cpu_affinity_set); - for_all_proc_cpus(init_thread_id); + for_all_proc_cpus(clear_ht_id); for_all_proc_cpus(set_cpu_hybrid_type); /* * For online cpus - * find max_core_id, max_package_id + * find max_core_id, max_package_id, num_cores (per system) */ for (i = 0; i <= topo.max_cpu_num; ++i) { int siblings; @@ -9222,12 +9597,12 @@ void topology_probe(bool startup) continue; } - cpus[i].logical_cpu_id = i; + cpus[i].cpu_id = i; /* get package information */ - cpus[i].physical_package_id = get_physical_package_id(i); - if (cpus[i].physical_package_id > max_package_id) - max_package_id = cpus[i].physical_package_id; + cpus[i].package_id = get_package_id(i); + if (cpus[i].package_id > max_package_id) + max_package_id = cpus[i].package_id; /* get die information */ cpus[i].die_id = get_die_id(i); @@ -9245,18 +9620,18 @@ void topology_probe(bool startup) topo.max_node_num = cpus[i].physical_node_id; /* get core information */ - cpus[i].physical_core_id = get_core_id(i); - if (cpus[i].physical_core_id > max_core_id) - max_core_id = cpus[i].physical_core_id; + cpus[i].core_id = get_core_id(i); + if (cpus[i].core_id > max_core_id) + max_core_id = cpus[i].core_id; /* get thread information */ - siblings = get_thread_siblings(&cpus[i]); + siblings = set_thread_siblings(&cpus[i]); if (siblings > max_siblings) max_siblings = siblings; - if (cpus[i].thread_id == 0) + if (cpus[i].ht_id == 0) topo.num_cores++; } - topo.max_core_id = max_core_id; + topo.max_core_id = max_core_id; /* within a package */ topo.max_package_id = max_package_id; topo.cores_per_node = max_core_id + 1; @@ -9298,42 +9673,57 @@ void topology_probe(bool startup) continue; fprintf(outf, "cpu %d pkg %d die %d l3 %d node %d lnode %d core %d thread %d\n", - i, cpus[i].physical_package_id, cpus[i].die_id, cpus[i].l3_id, - cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].physical_core_id, cpus[i].thread_id); + i, cpus[i].package_id, cpus[i].die_id, cpus[i].l3_id, + cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].core_id, cpus[i].ht_id); } } -void allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_data **p) +void allocate_counters_1(struct counters *counters) +{ + counters->threads = calloc(1, sizeof(struct thread_data)); + if (counters->threads == NULL) + goto error; + + counters->cores = calloc(1, sizeof(struct core_data)); + if (counters->cores == NULL) + goto error; + + counters->packages = calloc(1, sizeof(struct pkg_data)); + if (counters->packages == NULL) + goto error; + + return; +error: + err(1, "calloc counters_1"); +} + +void allocate_counters(struct counters *counters) { int i; int num_cores = topo.cores_per_node * topo.nodes_per_pkg * topo.num_packages; int num_threads = topo.threads_per_core * num_cores; - *t = calloc(num_threads, sizeof(struct thread_data)); - if (*t == NULL) + counters->threads = calloc(num_threads, sizeof(struct thread_data)); + if (counters->threads == NULL) goto error; for (i = 0; i < num_threads; i++) - (*t)[i].cpu_id = -1; + (counters->threads)[i].cpu_id = -1; - *c = calloc(num_cores, sizeof(struct core_data)); - if (*c == NULL) + counters->cores = calloc(num_cores, sizeof(struct core_data)); + if (counters->cores == NULL) goto error; - for (i = 0; i < num_cores; i++) { - (*c)[i].core_id = -1; - (*c)[i].base_cpu = -1; - } + for (i = 0; i < num_cores; i++) + (counters->cores)[i].first_cpu = -1; - *p = calloc(topo.num_packages, sizeof(struct pkg_data)); - if (*p == NULL) + counters->packages = calloc(topo.num_packages, sizeof(struct pkg_data)); + if (counters->packages == NULL) goto error; - for (i = 0; i < topo.num_packages; i++) { - (*p)[i].package_id = i; - (*p)[i].base_cpu = -1; - } + for (i = 0; i < topo.num_packages; i++) + (counters->packages)[i].first_cpu = -1; return; error: @@ -9343,14 +9733,13 @@ void allocate_counters(struct thread_data **t, struct core_data **c, struct pkg_ /* * init_counter() * - * set FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE + * set t->cpu_id, FIRST_THREAD_IN_CORE and FIRST_CORE_IN_PACKAGE */ void init_counter(struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base, int cpu_id) { - int pkg_id = cpus[cpu_id].physical_package_id; + int pkg_id = cpus[cpu_id].package_id; int node_id = cpus[cpu_id].logical_node_id; - int core_id = cpus[cpu_id].physical_core_id; - int thread_id = cpus[cpu_id].thread_id; + int core_id = cpus[cpu_id].core_id; struct thread_data *t; struct core_data *c; @@ -9360,20 +9749,17 @@ void init_counter(struct thread_data *thread_base, struct core_data *core_base, if (node_id < 0) node_id = 0; - t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id); - c = GET_CORE(core_base, core_id, node_id, pkg_id); + t = &thread_base[cpu_id]; + c = &core_base[GLOBAL_CORE_ID(core_id, pkg_id)]; t->cpu_id = cpu_id; if (!cpu_is_not_allowed(cpu_id)) { - if (c->base_cpu < 0) - c->base_cpu = t->cpu_id; - if (pkg_base[pkg_id].base_cpu < 0) - pkg_base[pkg_id].base_cpu = t->cpu_id; + if (c->first_cpu < 0) + c->first_cpu = t->cpu_id; + if (pkg_base[pkg_id].first_cpu < 0) + pkg_base[pkg_id].first_cpu = t->cpu_id; } - - c->core_id = core_id; - pkg_base[pkg_id].package_id = pkg_id; } int initialize_counters(int cpu_id) @@ -9416,9 +9802,9 @@ void allocate_irq_buffers(void) int update_topo(PER_THREAD_PARAMS) { topo.allowed_cpus++; - if ((int)t->cpu_id == c->base_cpu) + if ((int)t->cpu_id == c->first_cpu) topo.allowed_cores++; - if ((int)t->cpu_id == p->base_cpu) + if ((int)t->cpu_id == p->first_cpu) topo.allowed_packages++; return 0; @@ -9437,23 +9823,24 @@ void setup_all_buffers(bool startup) topology_probe(startup); allocate_irq_buffers(); allocate_fd_percpu(); - allocate_counters(&thread_even, &core_even, &package_even); - allocate_counters(&thread_odd, &core_odd, &package_odd); + allocate_counters_1(&average); + allocate_counters(&even); + allocate_counters(&odd); allocate_output_buffer(); for_all_proc_cpus(initialize_counters); topology_update(); } -void set_base_cpu(void) +void set_master_cpu(void) { int i; for (i = 0; i < topo.max_cpu_num + 1; ++i) { if (cpu_is_not_allowed(i)) continue; - base_cpu = i; + master_cpu = i; if (debug > 1) - fprintf(outf, "base_cpu = %d\n", base_cpu); + fprintf(outf, "master_cpu = %d\n", master_cpu); return; } err(-ENODEV, "No valid cpus found"); @@ -9484,7 +9871,7 @@ void check_perf_access(void) if (!has_perf_instr_count_access()) no_perf = 1; - if (BIC_IS_ENABLED(BIC_LLC_RPS) || BIC_IS_ENABLED(BIC_LLC_HIT)) + if (BIC_IS_ENABLED(BIC_LLC_MRPS) || BIC_IS_ENABLED(BIC_LLC_HIT)) if (!has_perf_llc_access()) no_perf = 1; @@ -9967,8 +10354,7 @@ void pmt_init(void) if (BIC_IS_ENABLED(BIC_Diec6)) { pmt_add_counter(PMT_MTL_DC6_GUID, PMT_MTL_DC6_SEQ, "Die%c6", PMT_TYPE_XTAL_TIME, - PMT_COUNTER_MTL_DC6_LSB, PMT_COUNTER_MTL_DC6_MSB, PMT_COUNTER_MTL_DC6_OFFSET, - SCOPE_PACKAGE, FORMAT_DELTA, 0, PMT_OPEN_TRY); + PMT_COUNTER_MTL_DC6_LSB, PMT_COUNTER_MTL_DC6_MSB, PMT_COUNTER_MTL_DC6_OFFSET, SCOPE_PACKAGE, FORMAT_DELTA, 0, PMT_OPEN_TRY); } if (BIC_IS_ENABLED(BIC_CPU_c1e)) { @@ -10029,7 +10415,7 @@ void pmt_init(void) void turbostat_init() { setup_all_buffers(true); - set_base_cpu(); + set_master_cpu(); check_msr_access(); check_perf_access(); process_cpuid(); @@ -10040,13 +10426,14 @@ void turbostat_init() rapl_perf_init(); cstate_perf_init(); perf_llc_init(); + perf_l2_init(); added_perf_counters_init(); pmt_init(); for_all_cpus(get_cpu_type, ODD_COUNTERS); for_all_cpus(get_cpu_type, EVEN_COUNTERS); - if (BIC_IS_ENABLED(BIC_IPC) && has_aperf_access && get_instr_count_fd(base_cpu) != -1) + if (BIC_IS_ENABLED(BIC_IPC) && has_aperf_access && get_instr_count_fd(master_cpu) != -1) BIC_PRESENT(BIC_IPC); /* @@ -10145,7 +10532,7 @@ int get_and_dump_counters(void) void print_version() { - fprintf(outf, "turbostat version 2025.12.02 - Len Brown \n"); + fprintf(outf, "turbostat version 2026.02.14 - Len Brown \n"); } #define COMMAND_LINE_SIZE 2048 @@ -10767,8 +11154,7 @@ void parse_add_command_pmt(char *add_command) } if (direct_path && has_guid) { - printf("%s: path and guid+seq parameters are mutually exclusive\n" - "notice: passed guid=0x%x and path=%s\n", __func__, guid, direct_path); + printf("%s: path and guid+seq parameters are mutually exclusive\nnotice: passed guid=0x%x and path=%s\n", __func__, guid, direct_path); exit(1); } @@ -10863,7 +11249,7 @@ void probe_cpuidle_residency(void) for (state = 10; state >= 0; --state) { - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", master_cpu, state); input = fopen(path, "r"); if (input == NULL) continue; @@ -10912,7 +11298,7 @@ void probe_cpuidle_counts(void) for (state = 10; state >= 0; --state) { - sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", base_cpu, state); + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/name", master_cpu, state); input = fopen(path, "r"); if (input == NULL) continue; @@ -11041,7 +11427,7 @@ void cmdline(int argc, char **argv) * Parse some options early, because they may make other options invalid, * like adding the MSR counter with --add and at the same time using --no-msr. */ - while ((opt = getopt_long_only(argc, argv, "+MPn:", long_options, &option_index)) != -1) { + while ((opt = getopt_long_only(argc, argv, "+:MP", long_options, &option_index)) != -1) { switch (opt) { case 'M': no_msr = 1; @@ -11055,7 +11441,7 @@ void cmdline(int argc, char **argv) } optind = 0; - while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:o:qMST:v", long_options, &option_index)) != -1) { + while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMST:v", long_options, &option_index)) != -1) { switch (opt) { case 'a': parse_add_command(optarg); @@ -11098,7 +11484,6 @@ void cmdline(int argc, char **argv) } break; case 'h': - default: help(); exit(1); case 'i': @@ -11134,20 +11519,18 @@ void cmdline(int argc, char **argv) /* Parsed earlier */ break; case 'n': - num_iterations = strtod(optarg, NULL); + num_iterations = strtoul(optarg, NULL, 0); + errno = 0; - if (num_iterations <= 0) { - fprintf(outf, "iterations %d should be positive number\n", num_iterations); - exit(2); - } + if (errno || num_iterations == 0) + errx(-1, "invalid iteration count: %s", optarg); break; case 'N': - header_iterations = strtod(optarg, NULL); + header_iterations = strtoul(optarg, NULL, 0); + errno = 0; - if (header_iterations <= 0) { - fprintf(outf, "iterations %d should be positive number\n", header_iterations); - exit(2); - } + if (errno || header_iterations == 0) + errx(-1, "invalid header iteration count: %s", optarg); break; case 's': /* @@ -11170,6 +11553,9 @@ void cmdline(int argc, char **argv) print_version(); exit(0); break; + default: + help(); + exit(1); } } } diff --git a/tools/sched_ext/Kconfig b/tools/sched_ext/Kconfig new file mode 100644 index 000000000000..275bd97ae62b --- /dev/null +++ b/tools/sched_ext/Kconfig @@ -0,0 +1,61 @@ +# sched-ext mandatory options +# +CONFIG_BPF=y +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_DEBUG_INFO_BTF=y +CONFIG_BPF_JIT_ALWAYS_ON=y +CONFIG_BPF_JIT_DEFAULT_ON=y +CONFIG_SCHED_CLASS_EXT=y + +# Required by some rust schedulers (e.g. scx_p2dq) +# +CONFIG_KALLSYMS_ALL=y + +# Required on arm64 +# +# CONFIG_DEBUG_INFO_REDUCED is not set + +# LAVD tracks futex to give an additional time slice for futex holder +# (i.e., avoiding lock holder preemption) for better system-wide progress. +# LAVD first tries to use ftrace to trace futex function calls. +# If that is not available, it tries to use a tracepoint. +CONFIG_FUNCTION_TRACER=y + +# Enable scheduling debugging +# +CONFIG_SCHED_DEBUG=y + +# Enable extra scheduling features (for a better code coverage while testing +# the schedulers) +# +CONFIG_SCHED_AUTOGROUP=y +CONFIG_SCHED_CORE=y +CONFIG_SCHED_MC=y + +# Enable fully preemptible kernel for a better test coverage of the schedulers +# +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_DYNAMIC=y + +# Additional debugging information (useful to catch potential locking issues) +CONFIG_DEBUG_LOCKDEP=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_PROVE_LOCKING=y + +# Bpftrace headers (for additional debug info) +CONFIG_BPF_EVENTS=y +CONFIG_FTRACE_SYSCALLS=y +CONFIG_DYNAMIC_FTRACE=y +CONFIG_KPROBES=y +CONFIG_KPROBE_EVENTS=y +CONFIG_UPROBES=y +CONFIG_UPROBE_EVENTS=y +CONFIG_DEBUG_FS=y + +# Enable access to kernel configuration and headers at runtime +CONFIG_IKHEADERS=y +CONFIG_IKCONFIG_PROC=y +CONFIG_IKCONFIG=y diff --git a/tools/sched_ext/Makefile b/tools/sched_ext/Makefile index 47ad7444677e..21554f089692 100644 --- a/tools/sched_ext/Makefile +++ b/tools/sched_ext/Makefile @@ -122,6 +122,8 @@ BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH) \ -I../../include \ $(call get_sys_includes,$(CLANG)) \ -Wall -Wno-compare-distinct-pointer-types \ + -Wno-microsoft-anon-tag \ + -fms-extensions \ -O2 -mcpu=v3 # sort removes libbpf duplicates when not cross-building diff --git a/tools/sched_ext/README.md b/tools/sched_ext/README.md index 56a9d1557ac4..6e282bce453c 100644 --- a/tools/sched_ext/README.md +++ b/tools/sched_ext/README.md @@ -58,14 +58,8 @@ CONFIG_SCHED_CLASS_EXT=y CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y CONFIG_DEBUG_INFO_BTF=y -``` - -It's also recommended that you also include the following Kconfig options: - -``` CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_BPF_JIT_DEFAULT_ON=y -CONFIG_PAHOLE_HAS_BTF_TAG=y ``` There is a `Kconfig` file in this directory whose contents you can append to diff --git a/tools/sched_ext/include/scx/compat.h b/tools/sched_ext/include/scx/compat.h index 8b4897fc8b99..edccc99c7294 100644 --- a/tools/sched_ext/include/scx/compat.h +++ b/tools/sched_ext/include/scx/compat.h @@ -125,6 +125,7 @@ static inline long scx_hotplug_seq(void) { int fd; char buf[32]; + char *endptr; ssize_t len; long val; @@ -137,8 +138,10 @@ static inline long scx_hotplug_seq(void) buf[len] = 0; close(fd); - val = strtoul(buf, NULL, 10); - SCX_BUG_ON(val < 0, "invalid num hotplug events: %lu", val); + errno = 0; + val = strtoul(buf, &endptr, 10); + SCX_BUG_ON(errno == ERANGE || endptr == buf || + (*endptr != '\n' && *endptr != '\0'), "invalid num hotplug events: %ld", val); return val; } diff --git a/tools/sched_ext/scx_central.c b/tools/sched_ext/scx_central.c index 55931a4cd71c..710fa03376e2 100644 --- a/tools/sched_ext/scx_central.c +++ b/tools/sched_ext/scx_central.c @@ -50,11 +50,13 @@ int main(int argc, char **argv) __u64 seq = 0, ecode; __s32 opt; cpu_set_t *cpuset; + size_t cpuset_size; libbpf_set_print(libbpf_print_fn); signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(central_ops, scx_central); skel->rodata->central_cpu = 0; @@ -64,7 +66,7 @@ int main(int argc, char **argv) assert(skel->rodata->nr_cpu_ids > 0); assert(skel->rodata->nr_cpu_ids <= INT32_MAX); - while ((opt = getopt(argc, argv, "s:c:pvh")) != -1) { + while ((opt = getopt(argc, argv, "s:c:vh")) != -1) { switch (opt) { case 's': skel->rodata->slice_ns = strtoull(optarg, NULL, 0) * 1000; @@ -73,6 +75,7 @@ int main(int argc, char **argv) u32 central_cpu = strtoul(optarg, NULL, 0); if (central_cpu >= skel->rodata->nr_cpu_ids) { fprintf(stderr, "invalid central CPU id value, %u given (%u max)\n", central_cpu, skel->rodata->nr_cpu_ids); + scx_central__destroy(skel); return -1; } skel->rodata->central_cpu = (s32)central_cpu; @@ -106,9 +109,10 @@ int main(int argc, char **argv) */ cpuset = CPU_ALLOC(skel->rodata->nr_cpu_ids); SCX_BUG_ON(!cpuset, "Failed to allocate cpuset"); - CPU_ZERO_S(CPU_ALLOC_SIZE(skel->rodata->nr_cpu_ids), cpuset); - CPU_SET(skel->rodata->central_cpu, cpuset); - SCX_BUG_ON(sched_setaffinity(0, sizeof(*cpuset), cpuset), + cpuset_size = CPU_ALLOC_SIZE(skel->rodata->nr_cpu_ids); + CPU_ZERO_S(cpuset_size, cpuset); + CPU_SET_S(skel->rodata->central_cpu, cpuset_size, cpuset); + SCX_BUG_ON(sched_setaffinity(0, cpuset_size, cpuset), "Failed to affinitize to central CPU %d (max %d)", skel->rodata->central_cpu, skel->rodata->nr_cpu_ids - 1); CPU_FREE(cpuset); diff --git a/tools/sched_ext/scx_cpu0.c b/tools/sched_ext/scx_cpu0.c index 1e4fa4ab8da9..a6fba9978b9c 100644 --- a/tools/sched_ext/scx_cpu0.c +++ b/tools/sched_ext/scx_cpu0.c @@ -69,6 +69,7 @@ int main(int argc, char **argv) signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(cpu0_ops, scx_cpu0); skel->rodata->nr_cpus = libbpf_num_possible_cpus(); diff --git a/tools/sched_ext/scx_flatcg.c b/tools/sched_ext/scx_flatcg.c index cd85eb401179..d865c381589b 100644 --- a/tools/sched_ext/scx_flatcg.c +++ b/tools/sched_ext/scx_flatcg.c @@ -102,21 +102,27 @@ static float read_cpu_util(__u64 *last_sum, __u64 *last_idle) static void fcg_read_stats(struct scx_flatcg *skel, __u64 *stats) { - __u64 cnts[FCG_NR_STATS][skel->rodata->nr_cpus]; + __u64 *cnts; __u32 idx; + cnts = calloc(skel->rodata->nr_cpus, sizeof(__u64)); + if (!cnts) + return; + memset(stats, 0, sizeof(stats[0]) * FCG_NR_STATS); for (idx = 0; idx < FCG_NR_STATS; idx++) { int ret, cpu; ret = bpf_map_lookup_elem(bpf_map__fd(skel->maps.stats), - &idx, cnts[idx]); + &idx, cnts); if (ret < 0) continue; for (cpu = 0; cpu < skel->rodata->nr_cpus; cpu++) - stats[idx] += cnts[idx][cpu]; + stats[idx] += cnts[cpu]; } + + free(cnts); } int main(int argc, char **argv) @@ -135,6 +141,7 @@ int main(int argc, char **argv) signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(flatcg_ops, scx_flatcg); skel->rodata->nr_cpus = libbpf_num_possible_cpus(); diff --git a/tools/sched_ext/scx_pair.c b/tools/sched_ext/scx_pair.c index d3e97faa6334..2e509391f3da 100644 --- a/tools/sched_ext/scx_pair.c +++ b/tools/sched_ext/scx_pair.c @@ -53,10 +53,10 @@ int main(int argc, char **argv) signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(pair_ops, scx_pair); skel->rodata->nr_cpu_ids = libbpf_num_possible_cpus(); - assert(skel->rodata->nr_cpu_ids > 0); skel->rodata->pair_batch_dur_ns = __COMPAT_ENUM_OR_ZERO("scx_public_consts", "SCX_SLICE_DFL"); /* pair up the earlier half to the latter by default, override with -s */ @@ -76,6 +76,12 @@ int main(int argc, char **argv) } } + /* Stride must be positive to pair distinct CPUs. */ + if (stride <= 0) { + fprintf(stderr, "Invalid stride %d, must be positive\n", stride); + scx_pair__destroy(skel); + return -1; + } bpf_map__set_max_entries(skel->maps.pair_ctx, skel->rodata->nr_cpu_ids / 2); /* Resize arrays so their element count is equal to cpu count. */ diff --git a/tools/sched_ext/scx_sdt.c b/tools/sched_ext/scx_sdt.c index b0363363476d..a36405d8df30 100644 --- a/tools/sched_ext/scx_sdt.c +++ b/tools/sched_ext/scx_sdt.c @@ -51,9 +51,10 @@ int main(int argc, char **argv) signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(sdt_ops, scx_sdt); - while ((opt = getopt(argc, argv, "fvh")) != -1) { + while ((opt = getopt(argc, argv, "vh")) != -1) { switch (opt) { case 'v': verbose = true; diff --git a/tools/sched_ext/scx_simple.c b/tools/sched_ext/scx_simple.c index 06d4b13bf76b..c3b48611712b 100644 --- a/tools/sched_ext/scx_simple.c +++ b/tools/sched_ext/scx_simple.c @@ -71,6 +71,7 @@ int main(int argc, char **argv) signal(SIGINT, sigint_handler); signal(SIGTERM, sigint_handler); restart: + optind = 1; skel = SCX_OPS_OPEN(simple_ops, scx_simple); while ((opt = getopt(argc, argv, "fvh")) != -1) { diff --git a/tools/sched_ext/scx_userland.c b/tools/sched_ext/scx_userland.c index 10b31020f44f..3f2aba658b4a 100644 --- a/tools/sched_ext/scx_userland.c +++ b/tools/sched_ext/scx_userland.c @@ -54,6 +54,7 @@ static bool verbose; static volatile int exit_req; static int enqueued_fd, dispatched_fd; +static pthread_t stats_printer; static struct scx_userland *skel; static struct bpf_link *ops_link; @@ -156,9 +157,9 @@ static int dispatch_task(__s32 pid) err = bpf_map_update_elem(dispatched_fd, NULL, &pid, 0); if (err) { - nr_vruntime_failed++; + __atomic_add_fetch(&nr_vruntime_failed, 1, __ATOMIC_RELAXED); } else { - nr_vruntime_dispatches++; + __atomic_add_fetch(&nr_vruntime_dispatches, 1, __ATOMIC_RELAXED); } return err; @@ -201,8 +202,8 @@ static int vruntime_enqueue(const struct scx_userland_enqueued_task *bpf_task) return ENOENT; update_enqueued(curr, bpf_task); - nr_vruntime_enqueues++; - nr_curr_enqueued++; + __atomic_add_fetch(&nr_vruntime_enqueues, 1, __ATOMIC_RELAXED); + __atomic_add_fetch(&nr_curr_enqueued, 1, __ATOMIC_RELAXED); /* * Enqueue the task in a vruntime-sorted list. A more optimal data @@ -278,9 +279,9 @@ static void dispatch_batch(void) LIST_INSERT_HEAD(&vruntime_head, task, entries); break; } - nr_curr_enqueued--; + __atomic_sub_fetch(&nr_curr_enqueued, 1, __ATOMIC_RELAXED); } - skel->bss->nr_scheduled = nr_curr_enqueued; + skel->bss->nr_scheduled = __atomic_load_n(&nr_curr_enqueued, __ATOMIC_RELAXED); } static void *run_stats_printer(void *arg) @@ -305,9 +306,9 @@ static void *run_stats_printer(void *arg) printf("|-----------------------|\n"); printf("| VRUNTIME / USER |\n"); printf("|-----------------------|\n"); - printf("| enq: %10llu |\n", nr_vruntime_enqueues); - printf("| disp: %10llu |\n", nr_vruntime_dispatches); - printf("| failed: %10llu |\n", nr_vruntime_failed); + printf("| enq: %10llu |\n", __atomic_load_n(&nr_vruntime_enqueues, __ATOMIC_RELAXED)); + printf("| disp: %10llu |\n", __atomic_load_n(&nr_vruntime_dispatches, __ATOMIC_RELAXED)); + printf("| failed: %10llu |\n", __atomic_load_n(&nr_vruntime_failed, __ATOMIC_RELAXED)); printf("o-----------------------o\n"); printf("\n\n"); fflush(stdout); @@ -319,8 +320,6 @@ static void *run_stats_printer(void *arg) static int spawn_stats_thread(void) { - pthread_t stats_printer; - return pthread_create(&stats_printer, NULL, run_stats_printer, NULL); } @@ -375,6 +374,15 @@ static void pre_bootstrap(int argc, char **argv) static void bootstrap(char *comm) { + exit_req = 0; + min_vruntime = 0.0; + __atomic_store_n(&nr_vruntime_enqueues, 0, __ATOMIC_RELAXED); + __atomic_store_n(&nr_vruntime_dispatches, 0, __ATOMIC_RELAXED); + __atomic_store_n(&nr_vruntime_failed, 0, __ATOMIC_RELAXED); + __atomic_store_n(&nr_curr_enqueued, 0, __ATOMIC_RELAXED); + memset(tasks, 0, pid_max * sizeof(*tasks)); + LIST_INIT(&vruntime_head); + skel = SCX_OPS_OPEN(userland_ops, scx_userland); skel->rodata->num_possible_cpus = libbpf_num_possible_cpus(); @@ -428,6 +436,7 @@ int main(int argc, char **argv) exit_req = 1; bpf_link__destroy(ops_link); + pthread_join(stats_printer, NULL); ecode = UEI_REPORT(skel, uei); scx_userland__destroy(skel); diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include index ded48263dd5e..b5ecf137febc 100644 --- a/tools/scripts/Makefile.include +++ b/tools/scripts/Makefile.include @@ -94,6 +94,8 @@ LLVM_STRIP ?= llvm-strip # Some tools require bpftool SYSTEM_BPFTOOL ?= bpftool +RUSTC ?= rustc + ifeq ($(CC_NO_CLANG), 1) EXTRA_WARNINGS += -Wstrict-aliasing=3 diff --git a/tools/scripts/syscall.tbl b/tools/scripts/syscall.tbl index e74868be513c..7a42b32b6577 100644 --- a/tools/scripts/syscall.tbl +++ b/tools/scripts/syscall.tbl @@ -411,3 +411,4 @@ 468 common file_getattr sys_file_getattr 469 common file_setattr sys_file_setattr 470 common listns sys_listns +471 common rseq_slice_yield sys_rseq_slice_yield diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index 260d8d9aa1db..2998e1bc088b 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -346,8 +346,10 @@ class LinuxSourceTree: return self.validate_config(build_dir) def run_kernel(self, args: Optional[List[str]]=None, build_dir: str='', filter_glob: str='', filter: str='', filter_action: Optional[str]=None, timeout: Optional[int]=None) -> Iterator[str]: - if not args: - args = [] + # Copy to avoid mutating the caller-supplied list. exec_tests() reuses + # the same args across repeated run_kernel() calls (e.g. --run_isolated), + # so appending to the original would accumulate stale flags on each call. + args = list(args) if args else [] if filter_glob: args.append('kunit.filter_glob=' + filter_glob) if filter: diff --git a/tools/testing/kunit/kunit_tool_test.py b/tools/testing/kunit/kunit_tool_test.py index b67408147c1f..f6383884c599 100755 --- a/tools/testing/kunit/kunit_tool_test.py +++ b/tools/testing/kunit/kunit_tool_test.py @@ -503,6 +503,32 @@ class LinuxSourceTreeTest(unittest.TestCase): with open(kunit_kernel.get_outfile_path(build_dir), 'rt') as outfile: self.assertEqual(outfile.read(), 'hi\nbye\n', msg='Missing some output') + def test_run_kernel_args_not_mutated(self): + """Verify run_kernel() copies args so callers can reuse them.""" + start_calls = [] + + def fake_start(start_args, unused_build_dir): + start_calls.append(list(start_args)) + return subprocess.Popen(['printf', 'KTAP version 1\n'], + text=True, stdout=subprocess.PIPE) + + with tempfile.TemporaryDirectory('') as build_dir: + tree = kunit_kernel.LinuxSourceTree(build_dir, + kunitconfig_paths=[os.devnull]) + with mock.patch.object(tree._ops, 'start', side_effect=fake_start), \ + mock.patch.object(kunit_kernel.subprocess, 'call'): + kernel_args = ['mem=1G'] + for _ in tree.run_kernel(args=kernel_args, build_dir=build_dir, + filter_glob='suite.test1'): + pass + for _ in tree.run_kernel(args=kernel_args, build_dir=build_dir, + filter_glob='suite.test2'): + pass + self.assertEqual(kernel_args, ['mem=1G'], + 'run_kernel() should not modify caller args') + self.assertIn('kunit.filter_glob=suite.test1', start_calls[0]) + self.assertIn('kunit.filter_glob=suite.test2', start_calls[1]) + def test_build_reconfig_no_config(self): with tempfile.TemporaryDirectory('') as build_dir: with open(kunit_kernel.get_kunitconfig_path(build_dir), 'w') as f: diff --git a/tools/testing/memblock/internal.h b/tools/testing/memblock/internal.h index 0ab4b53bb4f3..009b97bbdd22 100644 --- a/tools/testing/memblock/internal.h +++ b/tools/testing/memblock/internal.h @@ -15,8 +15,7 @@ bool mirrored_kernelcore = false; struct page {}; -void memblock_free_pages(struct page *page, unsigned long pfn, - unsigned int order) +void memblock_free_pages(unsigned long pfn, unsigned int order) { } diff --git a/tools/testing/selftests/arm64/abi/hwcap.c b/tools/testing/selftests/arm64/abi/hwcap.c index 9d2df1f3e6bb..c2661a312fc9 100644 --- a/tools/testing/selftests/arm64/abi/hwcap.c +++ b/tools/testing/selftests/arm64/abi/hwcap.c @@ -475,8 +475,8 @@ static void sve2_sigill(void) static void sve2p1_sigill(void) { - /* BFADD Z0.H, Z0.H, Z0.H */ - asm volatile(".inst 0x65000000" : : : "z0"); + /* LD1Q {Z0.Q}, P0/Z, [Z0.D, X0] */ + asm volatile(".inst 0xC400A000" : : : "z0"); } static void sve2p2_sigill(void) diff --git a/tools/testing/selftests/arm64/signal/testcases/gcs_prot_none_fault.c b/tools/testing/selftests/arm64/signal/testcases/gcs_prot_none_fault.c new file mode 100644 index 000000000000..2259f454a202 --- /dev/null +++ b/tools/testing/selftests/arm64/signal/testcases/gcs_prot_none_fault.c @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 ARM Limited + */ + +#include +#include +#include + +#include +#include + +#include "test_signals_utils.h" +#include "testcases.h" + +static uint64_t *gcs_page; +static bool post_mprotect; + +#ifndef __NR_map_shadow_stack +#define __NR_map_shadow_stack 453 +#endif + +static bool alloc_gcs(struct tdescr *td) +{ + long page_size = sysconf(_SC_PAGE_SIZE); + + gcs_page = (void *)syscall(__NR_map_shadow_stack, 0, + page_size, 0); + if (gcs_page == MAP_FAILED) { + fprintf(stderr, "Failed to map %ld byte GCS: %d\n", + page_size, errno); + return false; + } + + return true; +} + +static int gcs_prot_none_fault_trigger(struct tdescr *td) +{ + /* Verify that the page is readable (ie, not completely unmapped) */ + fprintf(stderr, "Read value 0x%lx\n", gcs_page[0]); + + if (mprotect(gcs_page, sysconf(_SC_PAGE_SIZE), PROT_NONE) != 0) { + fprintf(stderr, "mprotect(PROT_NONE) failed: %d\n", errno); + return 0; + } + post_mprotect = true; + + /* This should trigger a fault if PROT_NONE is honoured for the GCS page */ + fprintf(stderr, "Read value after mprotect(PROT_NONE) 0x%lx\n", gcs_page[0]); + return 0; +} + +static int gcs_prot_none_fault_signal(struct tdescr *td, siginfo_t *si, + ucontext_t *uc) +{ + ASSERT_GOOD_CONTEXT(uc); + + /* A fault before mprotect(PROT_NONE) is unexpected. */ + if (!post_mprotect) + return 0; + + return 1; +} + +struct tdescr tde = { + .name = "GCS PROT_NONE fault", + .descr = "Read from GCS after mprotect(PROT_NONE) segfaults", + .feats_required = FEAT_GCS, + .timeout = 3, + .sig_ok = SIGSEGV, + .sanity_disabled = true, + .init = alloc_gcs, + .trigger = gcs_prot_none_fault_trigger, + .run = gcs_prot_none_fault_signal, +}; diff --git a/tools/testing/selftests/bpf/DENYLIST.asan b/tools/testing/selftests/bpf/DENYLIST.asan new file mode 100644 index 000000000000..d7fe372a2293 --- /dev/null +++ b/tools/testing/selftests/bpf/DENYLIST.asan @@ -0,0 +1,3 @@ +*arena* +task_local_data +uprobe_multi_test diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile index c6bf4dfb1495..d5acbeba0383 100644 --- a/tools/testing/selftests/bpf/Makefile +++ b/tools/testing/selftests/bpf/Makefile @@ -27,7 +27,11 @@ ifneq ($(wildcard $(GENHDR)),) endif BPF_GCC ?= $(shell command -v bpf-gcc;) +ifdef ASAN +SAN_CFLAGS ?= -fsanitize=address -fno-omit-frame-pointer +else SAN_CFLAGS ?= +endif SAN_LDFLAGS ?= $(SAN_CFLAGS) RELEASE ?= OPT_FLAGS ?= $(if $(RELEASE),-O2,-O0) @@ -326,8 +330,8 @@ $(DEFAULT_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/bpftool $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ ARCH= CROSS_COMPILE= CC="$(HOSTCC)" LD="$(HOSTLD)" \ - EXTRA_CFLAGS='-g $(OPT_FLAGS) $(EXTRA_CFLAGS)' \ - EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \ + EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)' \ + EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' \ OUTPUT=$(HOST_BUILD_DIR)/bpftool/ \ LIBBPF_OUTPUT=$(HOST_BUILD_DIR)/libbpf/ \ LIBBPF_DESTDIR=$(HOST_SCRATCH_DIR)/ \ @@ -338,8 +342,8 @@ $(CROSS_BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) \ $(BPFOBJ) | $(BUILD_DIR)/bpftool $(Q)$(MAKE) $(submake_extras) -C $(BPFTOOLDIR) \ ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) \ - EXTRA_CFLAGS='-g $(OPT_FLAGS) $(EXTRA_CFLAGS)' \ - EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \ + EXTRA_CFLAGS='-g $(OPT_FLAGS) $(SAN_CFLAGS) $(EXTRA_CFLAGS)' \ + EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' \ OUTPUT=$(BUILD_DIR)/bpftool/ \ LIBBPF_OUTPUT=$(BUILD_DIR)/libbpf/ \ LIBBPF_DESTDIR=$(SCRATCH_DIR)/ \ @@ -404,6 +408,8 @@ $(RESOLVE_BTFIDS): $(HOST_BPFOBJ) | $(HOST_BUILD_DIR)/resolve_btfids \ $(Q)$(MAKE) $(submake_extras) -C $(TOOLSDIR)/bpf/resolve_btfids \ CC="$(HOSTCC)" LD="$(HOSTLD)" AR="$(HOSTAR)" \ LIBBPF_INCLUDE=$(HOST_INCLUDE_DIR) \ + EXTRA_LDFLAGS='$(SAN_LDFLAGS) $(EXTRA_LDFLAGS)' \ + HOSTPKG_CONFIG=$(PKG_CONFIG) \ OUTPUT=$(HOST_BUILD_DIR)/resolve_btfids/ BPFOBJ=$(HOST_BPFOBJ) # Get Clang's default includes on this system, as opposed to those seen by @@ -723,7 +729,7 @@ $(VERIFICATION_CERT) $(PRIVATE_KEY): $(VERIFY_SIG_SETUP) # Generates a header with C array declaration, containing test_progs_verification_cert bytes $(VERIFY_SIG_HDR): $(VERIFICATION_CERT) $(Q)(echo "unsigned char test_progs_verification_cert[] = {"; \ - hexdump -v -e '12/1 " 0x%02x," "\n"' $< | sed 's/0x ,//g; $$s/,$$//'; \ + od -v -t 'xC' -w12 $< | sed 's/ \(\S\+\)/ 0x\1,/g;s/^\S\+/ /;$$d'; \ echo "};"; \ echo "unsigned int test_progs_verification_cert_len = $$(wc -c < $<);") > $@ diff --git a/tools/testing/selftests/bpf/benchs/bench_trigger.c b/tools/testing/selftests/bpf/benchs/bench_trigger.c index aeec9edd3851..f74b313d6ae4 100644 --- a/tools/testing/selftests/bpf/benchs/bench_trigger.c +++ b/tools/testing/selftests/bpf/benchs/bench_trigger.c @@ -230,8 +230,8 @@ static void trigger_fentry_setup(void) static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe) { LIBBPF_OPTS(bpf_kprobe_multi_opts, opts); - char **syms = NULL; - size_t cnt = 0; + struct bpf_link *link = NULL; + struct ksyms *ksyms = NULL; /* Some recursive functions will be skipped in * bpf_get_ksyms -> skip_entry, as they can introduce sufficient @@ -241,16 +241,18 @@ static void attach_ksyms_all(struct bpf_program *empty, bool kretprobe) * So, don't run the kprobe-multi-all and kretprobe-multi-all on * a debug kernel. */ - if (bpf_get_ksyms(&syms, &cnt, true)) { + if (bpf_get_ksyms(&ksyms, true)) { fprintf(stderr, "failed to get ksyms\n"); exit(1); } - opts.syms = (const char **) syms; - opts.cnt = cnt; + opts.syms = (const char **)ksyms->filtered_syms; + opts.cnt = ksyms->filtered_cnt; opts.retprobe = kretprobe; /* attach empty to all the kernel functions except bpf_get_numa_node_id. */ - if (!bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts)) { + link = bpf_program__attach_kprobe_multi_opts(empty, NULL, &opts); + free_kallsyms_local(ksyms); + if (!link) { fprintf(stderr, "failed to attach bpf_program__attach_kprobe_multi_opts to all\n"); exit(1); } diff --git a/tools/testing/selftests/bpf/bpf_util.h b/tools/testing/selftests/bpf/bpf_util.h index 4bc2d25f33e1..6cb56501a505 100644 --- a/tools/testing/selftests/bpf/bpf_util.h +++ b/tools/testing/selftests/bpf/bpf_util.h @@ -8,6 +8,7 @@ #include #include #include /* libbpf_num_possible_cpus */ +#include static inline unsigned int bpf_num_possible_cpus(void) { @@ -21,25 +22,43 @@ static inline unsigned int bpf_num_possible_cpus(void) return possible_cpus; } -/* Copy up to sz - 1 bytes from zero-terminated src string and ensure that dst - * is zero-terminated string no matter what (unless sz == 0, in which case - * it's a no-op). It's conceptually close to FreeBSD's strlcpy(), but differs - * in what is returned. Given this is internal helper, it's trivial to extend - * this, when necessary. Use this instead of strncpy inside libbpf source code. +/* + * Simplified strscpy() implementation. The kernel one is in lib/string.c */ -static inline void bpf_strlcpy(char *dst, const char *src, size_t sz) +static inline ssize_t sized_strscpy(char *dest, const char *src, size_t count) { - size_t i; + long res = 0; - if (sz == 0) - return; + if (count == 0) + return -E2BIG; - sz--; - for (i = 0; i < sz && src[i]; i++) - dst[i] = src[i]; - dst[i] = '\0'; + while (count > 1) { + char c; + + c = src[res]; + dest[res] = c; + if (!c) + return res; + res++; + count--; + } + + /* Force NUL-termination. */ + dest[res] = '\0'; + + /* Return E2BIG if the source didn't stop */ + return src[res] ? -E2BIG : res; } +#define __strscpy0(dst, src, ...) \ + sized_strscpy(dst, src, sizeof(dst)) +#define __strscpy1(dst, src, size) \ + sized_strscpy(dst, src, size) + +#undef strscpy /* Redefine the placeholder from tools/include/linux/string.h */ +#define strscpy(dst, src, ...) \ + CONCATENATE(__strscpy, COUNT_ARGS(__VA_ARGS__))(dst, src, __VA_ARGS__) + #define __bpf_percpu_val_align __attribute__((__aligned__(8))) #define BPF_DECLARE_PERCPU(type, name) \ diff --git a/tools/testing/selftests/bpf/bpftool_helpers.c b/tools/testing/selftests/bpf/bpftool_helpers.c index a5824945a4a5..929fc257f431 100644 --- a/tools/testing/selftests/bpf/bpftool_helpers.c +++ b/tools/testing/selftests/bpf/bpftool_helpers.c @@ -1,24 +1,37 @@ // SPDX-License-Identifier: GPL-2.0-only -#include "bpftool_helpers.h" #include #include #include +#include "bpf_util.h" +#include "bpftool_helpers.h" + #define BPFTOOL_PATH_MAX_LEN 64 #define BPFTOOL_FULL_CMD_MAX_LEN 512 #define BPFTOOL_DEFAULT_PATH "tools/sbin/bpftool" -static int detect_bpftool_path(char *buffer) +static int detect_bpftool_path(char *buffer, size_t size) { char tmp[BPFTOOL_PATH_MAX_LEN]; + const char *env_path; + + /* First, check if BPFTOOL environment variable is set */ + env_path = getenv("BPFTOOL"); + if (env_path && access(env_path, X_OK) == 0) { + strscpy(buffer, env_path, size); + return 0; + } else if (env_path) { + fprintf(stderr, "bpftool '%s' doesn't exist or is not executable\n", env_path); + return 1; + } /* Check default bpftool location (will work if we are running the * default flavor of test_progs) */ snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "./%s", BPFTOOL_DEFAULT_PATH); if (access(tmp, X_OK) == 0) { - strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN); + strscpy(buffer, tmp, size); return 0; } @@ -27,11 +40,11 @@ static int detect_bpftool_path(char *buffer) */ snprintf(tmp, BPFTOOL_PATH_MAX_LEN, "../%s", BPFTOOL_DEFAULT_PATH); if (access(tmp, X_OK) == 0) { - strncpy(buffer, tmp, BPFTOOL_PATH_MAX_LEN); + strscpy(buffer, tmp, size); return 0; } - /* Failed to find bpftool binary */ + fprintf(stderr, "Failed to detect bpftool path, use BPFTOOL env var to override\n"); return 1; } @@ -44,7 +57,7 @@ static int run_command(char *args, char *output_buf, size_t output_max_len) int ret; /* Detect and cache bpftool binary location */ - if (bpftool_path[0] == 0 && detect_bpftool_path(bpftool_path)) + if (bpftool_path[0] == 0 && detect_bpftool_path(bpftool_path, sizeof(bpftool_path))) return 1; ret = snprintf(command, BPFTOOL_FULL_CMD_MAX_LEN, "%s %s%s", diff --git a/tools/testing/selftests/bpf/cgroup_helpers.c b/tools/testing/selftests/bpf/cgroup_helpers.c index 20cede4db3ce..45cd0b479fe3 100644 --- a/tools/testing/selftests/bpf/cgroup_helpers.c +++ b/tools/testing/selftests/bpf/cgroup_helpers.c @@ -86,7 +86,7 @@ static int __enable_controllers(const char *cgroup_path, const char *controllers enable[len] = 0; close(fd); } else { - bpf_strlcpy(enable, controllers, sizeof(enable)); + strscpy(enable, controllers); } snprintf(path, sizeof(path), "%s/cgroup.subtree_control", cgroup_path); diff --git a/tools/testing/selftests/bpf/jit_disasm_helpers.c b/tools/testing/selftests/bpf/jit_disasm_helpers.c index febd6b12e372..364c557c5115 100644 --- a/tools/testing/selftests/bpf/jit_disasm_helpers.c +++ b/tools/testing/selftests/bpf/jit_disasm_helpers.c @@ -122,15 +122,15 @@ static int disasm_one_func(FILE *text_out, uint8_t *image, __u32 len) pc += cnt; } qsort(labels.pcs, labels.cnt, sizeof(*labels.pcs), cmp_u32); - for (i = 0; i < labels.cnt; ++i) - /* gcc is unable to infer upper bound for labels.cnt and assumes - * it to be U32_MAX. U32_MAX takes 10 decimal digits. - * snprintf below prints into labels.names[*], - * which has space only for two digits and a letter. - * To avoid truncation warning use (i % MAX_LOCAL_LABELS), - * which informs gcc about printed value upper bound. - */ - snprintf(labels.names[i], sizeof(labels.names[i]), "L%d", i % MAX_LOCAL_LABELS); + /* gcc is unable to infer upper bound for labels.cnt and + * assumes it to be U32_MAX. U32_MAX takes 10 decimal digits. + * snprintf below prints into labels.names[*], which has space + * only for two digits and a letter. To avoid truncation + * warning use (i < MAX_LOCAL_LABELS), which informs gcc about + * printed value upper bound. + */ + for (i = 0; i < labels.cnt && i < MAX_LOCAL_LABELS; ++i) + snprintf(labels.names[i], sizeof(labels.names[i]), "L%d", i); /* now print with labels */ labels.print_phase = true; diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 0a6a5561bed3..b82f572641b7 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -432,7 +432,7 @@ int make_sockaddr(int family, const char *addr_str, __u16 port, memset(addr, 0, sizeof(*sun)); sun->sun_family = family; sun->sun_path[0] = 0; - strcpy(sun->sun_path + 1, addr_str); + strscpy(sun->sun_path + 1, addr_str, sizeof(sun->sun_path) - 1); if (len) *len = offsetof(struct sockaddr_un, sun_path) + 1 + strlen(addr_str); return 0; @@ -581,8 +581,7 @@ int open_tuntap(const char *dev_name, bool need_mac) return -1; ifr.ifr_flags = IFF_NO_PI | (need_mac ? IFF_TAP : IFF_TUN); - strncpy(ifr.ifr_name, dev_name, IFNAMSIZ - 1); - ifr.ifr_name[IFNAMSIZ - 1] = '\0'; + strscpy(ifr.ifr_name, dev_name); err = ioctl(fd, TUNSETIFF, &ifr); if (!ASSERT_OK(err, "ioctl(TUNSETIFF)")) { diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c index 5225d69bf79b..c69080ca14f5 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c @@ -346,8 +346,7 @@ static void test_task_sleepable(void) close(finish_pipe[1]); test_data = malloc(sizeof(char) * 10); - strncpy(test_data, "test_data", 10); - test_data[9] = '\0'; + strscpy(test_data, "test_data", 10); test_data_long = malloc(sizeof(char) * 5000); for (int i = 0; i < 5000; ++i) { diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c index b7d1b52309d0..f829b6f09bc9 100644 --- a/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c +++ b/tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c @@ -281,7 +281,7 @@ static void test_dctcp_fallback(void) dctcp_skel = bpf_dctcp__open(); if (!ASSERT_OK_PTR(dctcp_skel, "dctcp_skel")) return; - strcpy(dctcp_skel->rodata->fallback_cc, "cubic"); + strscpy(dctcp_skel->rodata->fallback_cc, "cubic"); if (!ASSERT_OK(bpf_dctcp__load(dctcp_skel), "bpf_dctcp__load")) goto done; diff --git a/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c b/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c index 9015e2c2ab12..478a77cb67e6 100644 --- a/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c +++ b/tools/testing/selftests/bpf/prog_tests/cgrp_local_storage.c @@ -202,7 +202,7 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id) iter_fd = bpf_iter_create(bpf_link__fd(link)); if (!ASSERT_GE(iter_fd, 0, "iter_create")) - goto out; + goto out_link; /* trigger the program run */ (void)read(iter_fd, buf, sizeof(buf)); @@ -210,6 +210,8 @@ static void test_cgroup_iter_sleepable(int cgroup_fd, __u64 cgroup_id) ASSERT_EQ(skel->bss->cgroup_id, cgroup_id, "cgroup_id"); close(iter_fd); +out_link: + bpf_link__destroy(link); out: cgrp_ls_sleepable__destroy(skel); } diff --git a/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c b/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c index dd75ccb03770..469e92869523 100644 --- a/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c +++ b/tools/testing/selftests/bpf/prog_tests/ctx_rewrite.c @@ -308,8 +308,10 @@ static int find_field_offset(struct btf *btf, char *pattern, regmatch_t *matches return -1; } - strncpy(type_str, type, type_sz); - strncpy(field_str, field, field_sz); + memcpy(type_str, type, type_sz); + type_str[type_sz] = '\0'; + memcpy(field_str, field, field_sz); + field_str[field_sz] = '\0'; btf_id = btf__find_by_name(btf, type_str); if (btf_id < 0) { PRINT_FAIL("No BTF info for type %s\n", type_str); diff --git a/tools/testing/selftests/bpf/prog_tests/dynptr.c b/tools/testing/selftests/bpf/prog_tests/dynptr.c index b9f86cb91e81..5fda11590708 100644 --- a/tools/testing/selftests/bpf/prog_tests/dynptr.c +++ b/tools/testing/selftests/bpf/prog_tests/dynptr.c @@ -137,11 +137,14 @@ static void verify_success(const char *prog_name, enum test_setup_type setup_typ ); link = bpf_program__attach(prog); - if (!ASSERT_OK_PTR(link, "bpf_program__attach")) + if (!ASSERT_OK_PTR(link, "bpf_program__attach")) { + bpf_object__close(obj); goto cleanup; + } err = bpf_prog_test_run_opts(aux_prog_fd, &topts); bpf_link__destroy(link); + bpf_object__close(obj); if (!ASSERT_OK(err, "test_run")) goto cleanup; diff --git a/tools/testing/selftests/bpf/prog_tests/fd_array.c b/tools/testing/selftests/bpf/prog_tests/fd_array.c index c534b4d5f9da..3078d8264deb 100644 --- a/tools/testing/selftests/bpf/prog_tests/fd_array.c +++ b/tools/testing/selftests/bpf/prog_tests/fd_array.c @@ -412,8 +412,8 @@ static void check_fd_array_cnt__fd_array_too_big(void) ASSERT_EQ(prog_fd, -E2BIG, "prog should have been rejected with -E2BIG"); cleanup_fds: - while (i > 0) - Close(extra_fds[--i]); + while (i-- > 0) + Close(extra_fds[i]); } void test_fd_array_cnt(void) diff --git a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c index 08bae13248c4..fb4892681464 100644 --- a/tools/testing/selftests/bpf/prog_tests/flow_dissector.c +++ b/tools/testing/selftests/bpf/prog_tests/flow_dissector.c @@ -570,7 +570,7 @@ static int create_tap(const char *ifname) }; int fd, ret; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strscpy(ifr.ifr_name, ifname); fd = open("/dev/net/tun", O_RDWR); if (fd < 0) @@ -599,7 +599,7 @@ static int ifup(const char *ifname) struct ifreq ifr = {}; int sk, ret; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strscpy(ifr.ifr_name, ifname); sk = socket(PF_INET, SOCK_DGRAM, 0); if (sk < 0) diff --git a/tools/testing/selftests/bpf/prog_tests/htab_update.c b/tools/testing/selftests/bpf/prog_tests/htab_update.c index d0b405eb2966..ea1a6766fbe9 100644 --- a/tools/testing/selftests/bpf/prog_tests/htab_update.c +++ b/tools/testing/selftests/bpf/prog_tests/htab_update.c @@ -61,6 +61,7 @@ static void test_reenter_update(void) ASSERT_EQ(skel->bss->update_err, -EDEADLK, "no reentrancy"); out: + free(value); htab_update__destroy(skel); } diff --git a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c index 6e35e13c2022..399fe9103f83 100644 --- a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +++ b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c @@ -104,11 +104,8 @@ void test_kmem_cache_iter(void) if (!ASSERT_GE(iter_fd, 0, "iter_create")) goto destroy; - memset(buf, 0, sizeof(buf)); - while (read(iter_fd, buf, sizeof(buf)) > 0) { - /* Read out all contents */ - printf("%s", buf); - } + while (read(iter_fd, buf, sizeof(buf)) > 0) + ; /* Read out all contents */ /* Next reads should return 0 */ ASSERT_EQ(read(iter_fd, buf, sizeof(buf)), 0, "read"); diff --git a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c index 9caef222e528..f81dcd609ee9 100644 --- a/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/kprobe_multi_test.c @@ -456,25 +456,23 @@ static void test_kprobe_multi_bench_attach(bool kernel) { LIBBPF_OPTS(bpf_kprobe_multi_opts, opts); struct kprobe_multi_empty *skel = NULL; - char **syms = NULL; - size_t cnt = 0; + struct ksyms *ksyms = NULL; - if (!ASSERT_OK(bpf_get_ksyms(&syms, &cnt, kernel), "bpf_get_ksyms")) + if (!ASSERT_OK(bpf_get_ksyms(&ksyms, kernel), "bpf_get_ksyms")) return; skel = kprobe_multi_empty__open_and_load(); if (!ASSERT_OK_PTR(skel, "kprobe_multi_empty__open_and_load")) goto cleanup; - opts.syms = (const char **) syms; - opts.cnt = cnt; + opts.syms = (const char **)ksyms->filtered_syms; + opts.cnt = ksyms->filtered_cnt; do_bench_test(skel, &opts); cleanup: kprobe_multi_empty__destroy(skel); - if (syms) - free(syms); + free_kallsyms_local(ksyms); } static void test_kprobe_multi_bench_attach_addr(bool kernel) diff --git a/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c b/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c index 3bc730b7c7fa..1b25d5c5f8fb 100644 --- a/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c +++ b/tools/testing/selftests/bpf/prog_tests/lwt_seg6local.c @@ -117,7 +117,7 @@ void test_lwt_seg6local(void) const char *ns1 = NETNS_BASE "1"; const char *ns6 = NETNS_BASE "6"; struct nstoken *nstoken = NULL; - const char *foobar = "foobar"; + const char foobar[] = "foobar"; ssize_t bytes; int sfd, cfd; char buf[7]; diff --git a/tools/testing/selftests/bpf/prog_tests/map_kptr.c b/tools/testing/selftests/bpf/prog_tests/map_kptr.c index f372162c0280..03b46f17cf53 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_kptr.c +++ b/tools/testing/selftests/bpf/prog_tests/map_kptr.c @@ -118,15 +118,16 @@ static void test_map_kptr_success(bool test_run) static int kern_sync_rcu_tasks_trace(struct rcu_tasks_trace_gp *rcu) { - long gp_seq = READ_ONCE(rcu->bss->gp_seq); LIBBPF_OPTS(bpf_test_run_opts, opts); + int ret; - if (!ASSERT_OK(bpf_prog_test_run_opts(bpf_program__fd(rcu->progs.do_call_rcu_tasks_trace), - &opts), "do_call_rcu_tasks_trace")) + WRITE_ONCE(rcu->bss->done, 0); + ret = bpf_prog_test_run_opts(bpf_program__fd(rcu->progs.call_rcu_tasks_trace), &opts); + if (!ASSERT_OK(ret, "call_rcu_tasks_trace")) return -EFAULT; - if (!ASSERT_OK(opts.retval, "opts.retval == 0")) + if (!ASSERT_OK(opts.retval, "call_rcu_tasks_trace retval")) return -EFAULT; - while (gp_seq == READ_ONCE(rcu->bss->gp_seq)) + while (!READ_ONCE(rcu->bss->done)) sched_yield(); return 0; } @@ -159,8 +160,6 @@ void serial_test_map_kptr(void) skel = rcu_tasks_trace_gp__open_and_load(); if (!ASSERT_OK_PTR(skel, "rcu_tasks_trace_gp__open_and_load")) return; - if (!ASSERT_OK(rcu_tasks_trace_gp__attach(skel), "rcu_tasks_trace_gp__attach")) - goto end; if (test__start_subtest("success-map")) { test_map_kptr_success(true); @@ -180,7 +179,5 @@ void serial_test_map_kptr(void) test_map_kptr_success(true); } -end: rcu_tasks_trace_gp__destroy(skel); - return; } diff --git a/tools/testing/selftests/bpf/prog_tests/map_kptr_race.c b/tools/testing/selftests/bpf/prog_tests/map_kptr_race.c new file mode 100644 index 000000000000..506ed55e8528 --- /dev/null +++ b/tools/testing/selftests/bpf/prog_tests/map_kptr_race.c @@ -0,0 +1,218 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ +#include +#include + +#include "map_kptr_race.skel.h" + +static int get_map_id(int map_fd) +{ + struct bpf_map_info info = {}; + __u32 len = sizeof(info); + + if (!ASSERT_OK(bpf_map_get_info_by_fd(map_fd, &info, &len), "get_map_info")) + return -1; + return info.id; +} + +static int read_refs(struct map_kptr_race *skel) +{ + LIBBPF_OPTS(bpf_test_run_opts, opts); + int ret; + + ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.count_ref), &opts); + if (!ASSERT_OK(ret, "count_ref run")) + return -1; + if (!ASSERT_OK(opts.retval, "count_ref retval")) + return -1; + return skel->bss->num_of_refs; +} + +static void test_htab_leak(void) +{ + LIBBPF_OPTS(bpf_test_run_opts, opts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4), + .repeat = 1, + ); + struct map_kptr_race *skel, *watcher; + int ret, map_id; + + skel = map_kptr_race__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_and_load")) + return; + + ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_htab_leak), &opts); + if (!ASSERT_OK(ret, "test_htab_leak run")) + goto out_skel; + if (!ASSERT_OK(opts.retval, "test_htab_leak retval")) + goto out_skel; + + map_id = get_map_id(bpf_map__fd(skel->maps.race_hash_map)); + if (!ASSERT_GE(map_id, 0, "map_id")) + goto out_skel; + + watcher = map_kptr_race__open_and_load(); + if (!ASSERT_OK_PTR(watcher, "watcher open_and_load")) + goto out_skel; + + watcher->bss->target_map_id = map_id; + watcher->links.map_put = bpf_program__attach(watcher->progs.map_put); + if (!ASSERT_OK_PTR(watcher->links.map_put, "attach fentry")) + goto out_watcher; + watcher->links.htab_map_free = bpf_program__attach(watcher->progs.htab_map_free); + if (!ASSERT_OK_PTR(watcher->links.htab_map_free, "attach fexit")) + goto out_watcher; + + map_kptr_race__destroy(skel); + skel = NULL; + + kern_sync_rcu(); + + while (!READ_ONCE(watcher->bss->map_freed)) + sched_yield(); + + ASSERT_EQ(watcher->bss->map_freed, 1, "map_freed"); + ASSERT_EQ(read_refs(watcher), 2, "htab refcount"); + +out_watcher: + map_kptr_race__destroy(watcher); +out_skel: + map_kptr_race__destroy(skel); +} + +static void test_percpu_htab_leak(void) +{ + LIBBPF_OPTS(bpf_test_run_opts, opts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4), + .repeat = 1, + ); + struct map_kptr_race *skel, *watcher; + int ret, map_id; + + skel = map_kptr_race__open(); + if (!ASSERT_OK_PTR(skel, "open")) + return; + + skel->rodata->nr_cpus = libbpf_num_possible_cpus(); + if (skel->rodata->nr_cpus > 16) + skel->rodata->nr_cpus = 16; + + ret = map_kptr_race__load(skel); + if (!ASSERT_OK(ret, "load")) + goto out_skel; + + ret = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_percpu_htab_leak), &opts); + if (!ASSERT_OK(ret, "test_percpu_htab_leak run")) + goto out_skel; + if (!ASSERT_OK(opts.retval, "test_percpu_htab_leak retval")) + goto out_skel; + + map_id = get_map_id(bpf_map__fd(skel->maps.race_percpu_hash_map)); + if (!ASSERT_GE(map_id, 0, "map_id")) + goto out_skel; + + watcher = map_kptr_race__open_and_load(); + if (!ASSERT_OK_PTR(watcher, "watcher open_and_load")) + goto out_skel; + + watcher->bss->target_map_id = map_id; + watcher->links.map_put = bpf_program__attach(watcher->progs.map_put); + if (!ASSERT_OK_PTR(watcher->links.map_put, "attach fentry")) + goto out_watcher; + watcher->links.htab_map_free = bpf_program__attach(watcher->progs.htab_map_free); + if (!ASSERT_OK_PTR(watcher->links.htab_map_free, "attach fexit")) + goto out_watcher; + + map_kptr_race__destroy(skel); + skel = NULL; + + kern_sync_rcu(); + + while (!READ_ONCE(watcher->bss->map_freed)) + sched_yield(); + + ASSERT_EQ(watcher->bss->map_freed, 1, "map_freed"); + ASSERT_EQ(read_refs(watcher), 2, "percpu_htab refcount"); + +out_watcher: + map_kptr_race__destroy(watcher); +out_skel: + map_kptr_race__destroy(skel); +} + +static void test_sk_ls_leak(void) +{ + struct map_kptr_race *skel, *watcher; + int listen_fd = -1, client_fd = -1, map_id; + + skel = map_kptr_race__open_and_load(); + if (!ASSERT_OK_PTR(skel, "open_and_load")) + return; + + if (!ASSERT_OK(map_kptr_race__attach(skel), "attach")) + goto out_skel; + + listen_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0); + if (!ASSERT_GE(listen_fd, 0, "start_server")) + goto out_skel; + + client_fd = connect_to_fd(listen_fd, 0); + if (!ASSERT_GE(client_fd, 0, "connect_to_fd")) + goto out_skel; + + if (!ASSERT_EQ(skel->bss->sk_ls_leak_done, 1, "sk_ls_leak_done")) + goto out_skel; + + close(client_fd); + client_fd = -1; + close(listen_fd); + listen_fd = -1; + + map_id = get_map_id(bpf_map__fd(skel->maps.race_sk_ls_map)); + if (!ASSERT_GE(map_id, 0, "map_id")) + goto out_skel; + + watcher = map_kptr_race__open_and_load(); + if (!ASSERT_OK_PTR(watcher, "watcher open_and_load")) + goto out_skel; + + watcher->bss->target_map_id = map_id; + watcher->links.map_put = bpf_program__attach(watcher->progs.map_put); + if (!ASSERT_OK_PTR(watcher->links.map_put, "attach fentry")) + goto out_watcher; + watcher->links.sk_map_free = bpf_program__attach(watcher->progs.sk_map_free); + if (!ASSERT_OK_PTR(watcher->links.sk_map_free, "attach fexit")) + goto out_watcher; + + map_kptr_race__destroy(skel); + skel = NULL; + + kern_sync_rcu(); + + while (!READ_ONCE(watcher->bss->map_freed)) + sched_yield(); + + ASSERT_EQ(watcher->bss->map_freed, 1, "map_freed"); + ASSERT_EQ(read_refs(watcher), 2, "sk_ls refcount"); + +out_watcher: + map_kptr_race__destroy(watcher); +out_skel: + if (client_fd >= 0) + close(client_fd); + if (listen_fd >= 0) + close(listen_fd); + map_kptr_race__destroy(skel); +} + +void serial_test_map_kptr_race(void) +{ + if (test__start_subtest("htab_leak")) + test_htab_leak(); + if (test__start_subtest("percpu_htab_leak")) + test_percpu_htab_leak(); + if (test__start_subtest("sk_ls_leak")) + test_sk_ls_leak(); +} diff --git a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c index a043af9cd6d9..41441325e179 100644 --- a/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c +++ b/tools/testing/selftests/bpf/prog_tests/queue_stack_map.c @@ -28,9 +28,9 @@ static void test_queue_stack_map_by_type(int type) vals[i] = rand(); if (type == QUEUE) - strncpy(file, "./test_queue_map.bpf.o", sizeof(file)); + strscpy(file, "./test_queue_map.bpf.o"); else if (type == STACK) - strncpy(file, "./test_stack_map.bpf.o", sizeof(file)); + strscpy(file, "./test_stack_map.bpf.o"); else return; diff --git a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c index d93a0c7b1786..cb8dd2f63296 100644 --- a/tools/testing/selftests/bpf/prog_tests/reg_bounds.c +++ b/tools/testing/selftests/bpf/prog_tests/reg_bounds.c @@ -422,15 +422,69 @@ static bool is_valid_range(enum num_t t, struct range x) } } -static struct range range_improve(enum num_t t, struct range old, struct range new) +static struct range range_intersection(enum num_t t, struct range old, struct range new) { return range(t, max_t(t, old.a, new.a), min_t(t, old.b, new.b)); } +/* + * Result is precise when 'x' and 'y' overlap or form a continuous range, + * result is an over-approximation if 'x' and 'y' do not overlap. + */ +static struct range range_union(enum num_t t, struct range x, struct range y) +{ + if (!is_valid_range(t, x)) + return y; + if (!is_valid_range(t, y)) + return x; + return range(t, min_t(t, x.a, y.a), max_t(t, x.b, y.b)); +} + +/* + * This function attempts to improve x range intersecting it with y. + * range_cast(... to_t ...) looses precision for ranges that pass to_t + * min/max boundaries. To avoid such precision loses this function + * splits both x and y into halves corresponding to non-overflowing + * sub-ranges: [0, smin] and [smax, -1]. + * Final result is computed as follows: + * + * ((x ∩ [0, smax]) ∩ (y ∩ [0, smax])) ∪ + * ((x ∩ [smin,-1]) ∩ (y ∩ [smin,-1])) + * + * Precision might still be lost if final union is not a continuous range. + */ +static struct range range_refine_in_halves(enum num_t x_t, struct range x, + enum num_t y_t, struct range y) +{ + struct range x_pos, x_neg, y_pos, y_neg, r_pos, r_neg; + u64 smax, smin, neg_one; + + if (t_is_32(x_t)) { + smax = (u64)(u32)S32_MAX; + smin = (u64)(u32)S32_MIN; + neg_one = (u64)(u32)(s32)(-1); + } else { + smax = (u64)S64_MAX; + smin = (u64)S64_MIN; + neg_one = U64_MAX; + } + x_pos = range_intersection(x_t, x, range(x_t, 0, smax)); + x_neg = range_intersection(x_t, x, range(x_t, smin, neg_one)); + y_pos = range_intersection(y_t, y, range(x_t, 0, smax)); + y_neg = range_intersection(y_t, y, range(y_t, smin, neg_one)); + r_pos = range_intersection(x_t, x_pos, range_cast(y_t, x_t, y_pos)); + r_neg = range_intersection(x_t, x_neg, range_cast(y_t, x_t, y_neg)); + return range_union(x_t, r_pos, r_neg); + +} + static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, struct range y) { struct range y_cast; + if (t_is_32(x_t) == t_is_32(y_t)) + x = range_refine_in_halves(x_t, x, y_t, y); + y_cast = range_cast(y_t, x_t, y); /* If we know that @@ -444,7 +498,7 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, */ if (x_t == S64 && y_t == S32 && y_cast.a <= S32_MAX && y_cast.b <= S32_MAX && (s64)x.a >= S32_MIN && (s64)x.b <= S32_MAX) - return range_improve(x_t, x, y_cast); + return range_intersection(x_t, x, y_cast); /* the case when new range knowledge, *y*, is a 32-bit subregister * range, while previous range knowledge, *x*, is a full register @@ -462,25 +516,11 @@ static struct range range_refine(enum num_t x_t, struct range x, enum num_t y_t, x_swap = range(x_t, swap_low32(x.a, y_cast.a), swap_low32(x.b, y_cast.b)); if (!is_valid_range(x_t, x_swap)) return x; - return range_improve(x_t, x, x_swap); - } - - if (!t_is_32(x_t) && !t_is_32(y_t) && x_t != y_t) { - if (x_t == S64 && x.a > x.b) { - if (x.b < y.a && x.a <= y.b) - return range(x_t, x.a, y.b); - if (x.a > y.b && x.b >= y.a) - return range(x_t, y.a, x.b); - } else if (x_t == U64 && y.a > y.b) { - if (y.b < x.a && y.a <= x.b) - return range(x_t, y.a, x.b); - if (y.a > x.b && y.b >= x.a) - return range(x_t, x.a, y.b); - } + return range_intersection(x_t, x, x_swap); } /* otherwise, plain range cast and intersection works */ - return range_improve(x_t, x, y_cast); + return range_intersection(x_t, x, y_cast); } /* ======================= @@ -2091,7 +2131,7 @@ static struct subtest_case crafted_cases[] = { {U64, S64, {0, 0xffffffffULL}, {0x7fffffff, 0x7fffffff}}, {U64, U32, {0, 0x100000000}, {0, 0}}, - {U64, U32, {0xfffffffe, 0x100000000}, {0x80000000, 0x80000000}}, + {U64, U32, {0xfffffffe, 0x300000000}, {0x80000000, 0x80000000}}, {U64, S32, {0, 0xffffffff00000000ULL}, {0, 0}}, /* these are tricky cases where lower 32 bits allow to tighten 64 diff --git a/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c b/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c index e4dac529d424..77fe1bfb7504 100644 --- a/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c +++ b/tools/testing/selftests/bpf/prog_tests/setget_sockopt.c @@ -212,7 +212,7 @@ void test_setget_sockopt(void) if (!ASSERT_OK_PTR(skel, "open skel")) goto done; - strcpy(skel->rodata->veth, "binddevtest1"); + strscpy(skel->rodata->veth, "binddevtest1"); skel->rodata->veth_ifindex = if_nametoindex("binddevtest1"); if (!ASSERT_GT(skel->rodata->veth_ifindex, 0, "if_nametoindex")) goto done; diff --git a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c index 3eefdfed1db9..657d897958b6 100644 --- a/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c +++ b/tools/testing/selftests/bpf/prog_tests/skc_to_unix_sock.c @@ -34,7 +34,7 @@ void test_skc_to_unix_sock(void) memset(&sockaddr, 0, sizeof(sockaddr)); sockaddr.sun_family = AF_UNIX; - strncpy(sockaddr.sun_path, sock_path, strlen(sock_path)); + strscpy(sockaddr.sun_path, sock_path); sockaddr.sun_path[0] = '\0'; err = bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)); diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c index 256707e7d20d..dd3c757859f6 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c @@ -204,7 +204,7 @@ static void test_skmsg_helpers_with_link(enum bpf_map_type map_type) /* Fail since bpf_link for the same prog type has been created. */ link2 = bpf_program__attach_sockmap(prog_clone, map); if (!ASSERT_ERR_PTR(link2, "bpf_program__attach_sockmap")) { - bpf_link__detach(link2); + bpf_link__destroy(link2); goto out; } @@ -230,7 +230,7 @@ static void test_skmsg_helpers_with_link(enum bpf_map_type map_type) if (!ASSERT_OK(err, "bpf_link_update")) goto out; out: - bpf_link__detach(link); + bpf_link__destroy(link); test_skmsg_load_helpers__destroy(skel); } @@ -417,7 +417,7 @@ static void test_sockmap_skb_verdict_attach_with_link(void) if (!ASSERT_OK_PTR(link, "bpf_program__attach_sockmap")) goto out; - bpf_link__detach(link); + bpf_link__destroy(link); err = bpf_prog_attach(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT, 0); if (!ASSERT_OK(err, "bpf_prog_attach")) @@ -426,7 +426,7 @@ static void test_sockmap_skb_verdict_attach_with_link(void) /* Fail since attaching with the same prog/map has been done. */ link = bpf_program__attach_sockmap(prog, map); if (!ASSERT_ERR_PTR(link, "bpf_program__attach_sockmap")) - bpf_link__detach(link); + bpf_link__destroy(link); err = bpf_prog_detach2(bpf_program__fd(prog), map, BPF_SK_SKB_STREAM_VERDICT); if (!ASSERT_OK(err, "bpf_prog_detach2")) @@ -747,13 +747,13 @@ static void test_sockmap_skb_verdict_peek_with_link(void) test_sockmap_skb_verdict_peek_helper(map); ASSERT_EQ(pass->bss->clone_called, 1, "clone_called"); out: - bpf_link__detach(link); + bpf_link__destroy(link); test_sockmap_pass_prog__destroy(pass); } static void test_sockmap_unconnected_unix(void) { - int err, map, stream = 0, dgram = 0, zero = 0; + int err, map, stream = -1, dgram = -1, zero = 0; struct test_sockmap_pass_prog *skel; skel = test_sockmap_pass_prog__open_and_load(); @@ -764,22 +764,22 @@ static void test_sockmap_unconnected_unix(void) stream = xsocket(AF_UNIX, SOCK_STREAM, 0); if (stream < 0) - return; + goto out; dgram = xsocket(AF_UNIX, SOCK_DGRAM, 0); - if (dgram < 0) { - close(stream); - return; - } + if (dgram < 0) + goto out; err = bpf_map_update_elem(map, &zero, &stream, BPF_ANY); - ASSERT_ERR(err, "bpf_map_update_elem(stream)"); + if (!ASSERT_ERR(err, "bpf_map_update_elem(stream)")) + goto out; err = bpf_map_update_elem(map, &zero, &dgram, BPF_ANY); ASSERT_OK(err, "bpf_map_update_elem(dgram)"); - +out: close(stream); close(dgram); + test_sockmap_pass_prog__destroy(skel); } static void test_sockmap_many_socket(void) @@ -1027,7 +1027,7 @@ static void test_sockmap_skb_verdict_vsock_poll(void) if (xrecv_nonblock(conn, &buf, 1, 0) != 1) FAIL("xrecv_nonblock"); detach: - bpf_link__detach(link); + bpf_link__destroy(link); close: xclose(conn); xclose(peer); diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c index f1bdccc7e4e7..cc0c68bab907 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c +++ b/tools/testing/selftests/bpf/prog_tests/sockmap_listen.c @@ -899,7 +899,7 @@ static void test_msg_redir_to_listening_with_link(struct test_sockmap_listen *sk redir_to_listening(family, sotype, sock_map, verdict_map, REDIR_EGRESS); - bpf_link__detach(link); + bpf_link__destroy(link); } static void redir_partial(int family, int sotype, int sock_map, int parser_map) diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c index ba6b3ec1156a..53637431ec5d 100644 --- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c +++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c @@ -142,7 +142,7 @@ static int getsetsockopt(void) /* TCP_CONGESTION can extend the string */ - strcpy(buf.cc, "nv"); + strscpy(buf.cc, "nv"); err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv")); if (err) { log_err("Failed to call setsockopt(TCP_CONGESTION)"); diff --git a/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c b/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c index 4006879ca3fe..d42123a0fb16 100644 --- a/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c +++ b/tools/testing/selftests/bpf/prog_tests/struct_ops_private_stack.c @@ -54,9 +54,7 @@ static void test_private_stack_fail(void) } err = struct_ops_private_stack_fail__load(skel); - if (!ASSERT_ERR(err, "struct_ops_private_stack_fail__load")) - goto cleanup; - return; + ASSERT_ERR(err, "struct_ops_private_stack_fail__load"); cleanup: struct_ops_private_stack_fail__destroy(skel); diff --git a/tools/testing/selftests/bpf/prog_tests/task_local_data.h b/tools/testing/selftests/bpf/prog_tests/task_local_data.h index 0f86b9275cf9..8342e2fe5260 100644 --- a/tools/testing/selftests/bpf/prog_tests/task_local_data.h +++ b/tools/testing/selftests/bpf/prog_tests/task_local_data.h @@ -262,7 +262,7 @@ static tld_key_t __tld_create_key(const char *name, size_t size, bool dyn_data) if (!atomic_compare_exchange_strong(&tld_meta_p->cnt, &cnt, cnt + 1)) goto retry; - strncpy(tld_meta_p->metadata[i].name, name, TLD_NAME_LEN); + strscpy(tld_meta_p->metadata[i].name, name); atomic_store(&tld_meta_p->metadata[i].size, size); return (tld_key_t){(__s16)off}; } diff --git a/tools/testing/selftests/bpf/prog_tests/tc_opts.c b/tools/testing/selftests/bpf/prog_tests/tc_opts.c index dd7a138d8c3d..2955750ddada 100644 --- a/tools/testing/selftests/bpf/prog_tests/tc_opts.c +++ b/tools/testing/selftests/bpf/prog_tests/tc_opts.c @@ -1360,10 +1360,8 @@ static void test_tc_opts_dev_cleanup_target(int target) assert_mprog_count_ifindex(ifindex, target, 4); - ASSERT_OK(system("ip link del dev tcx_opts1"), "del veth"); - ASSERT_EQ(if_nametoindex("tcx_opts1"), 0, "dev1_removed"); - ASSERT_EQ(if_nametoindex("tcx_opts2"), 0, "dev2_removed"); - return; + goto cleanup; + cleanup3: err = bpf_prog_detach_opts(fd3, loopback, target, &optd); ASSERT_OK(err, "prog_detach"); diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c index 76d72a59365e..64fbda082309 100644 --- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c +++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c @@ -1095,7 +1095,7 @@ static int tun_open(char *name) ifr.ifr_flags = IFF_TUN | IFF_NO_PI; if (*name) - strncpy(ifr.ifr_name, name, IFNAMSIZ); + strscpy(ifr.ifr_name, name); err = ioctl(fd, TUNSETIFF, &ifr); if (!ASSERT_OK(err, "ioctl TUNSETIFF")) diff --git a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c index 273dd41ca09e..2a1ff821bc97 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_sysctl.c +++ b/tools/testing/selftests/bpf/prog_tests/test_sysctl.c @@ -27,6 +27,7 @@ struct sysctl_test { OP_EPERM, SUCCESS, } result; + struct bpf_object *obj; }; static struct sysctl_test tests[] = { @@ -1471,6 +1472,7 @@ static int load_sysctl_prog_file(struct sysctl_test *test) return -1; } + test->obj = obj; return prog_fd; } @@ -1573,6 +1575,7 @@ static int run_test_case(int cgfd, struct sysctl_test *test) /* Detaching w/o checking return code: best effort attempt. */ if (progfd != -1) bpf_prog_detach(cgfd, atype); + bpf_object__close(test->obj); close(progfd); printf("[%s]\n", err ? "FAIL" : "PASS"); return err; diff --git a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c index 0fe0a8f62486..7fc4d7dd70ef 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c +++ b/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c @@ -699,7 +699,7 @@ void test_tc_tunnel(void) return; if (!ASSERT_OK(setup(), "global setup")) - return; + goto out; for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) { cfg = &subtests_cfg[i]; @@ -711,4 +711,7 @@ void test_tc_tunnel(void) subtest_cleanup(cfg); } cleanup(); + +out: + test_tc_tunnel__destroy(skel); } diff --git a/tools/testing/selftests/bpf/prog_tests/test_veristat.c b/tools/testing/selftests/bpf/prog_tests/test_veristat.c index b38c16b4247f..9aff08ac55c0 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_veristat.c +++ b/tools/testing/selftests/bpf/prog_tests/test_veristat.c @@ -24,9 +24,9 @@ static struct fixture *init_fixture(void) /* for no_alu32 and cpuv4 veristat is in parent folder */ if (access("./veristat", F_OK) == 0) - strcpy(fix->veristat, "./veristat"); + strscpy(fix->veristat, "./veristat"); else if (access("../veristat", F_OK) == 0) - strcpy(fix->veristat, "../veristat"); + strscpy(fix->veristat, "../veristat"); else PRINT_FAIL("Can't find veristat binary"); diff --git a/tools/testing/selftests/bpf/prog_tests/test_xsk.c b/tools/testing/selftests/bpf/prog_tests/test_xsk.c index bab4a31621c7..7e38ec6e656b 100644 --- a/tools/testing/selftests/bpf/prog_tests/test_xsk.c +++ b/tools/testing/selftests/bpf/prog_tests/test_xsk.c @@ -2003,9 +2003,17 @@ int testapp_stats_tx_invalid_descs(struct test_spec *test) int testapp_stats_rx_full(struct test_spec *test) { - if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE)) + struct pkt_stream *tmp; + + tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE); + if (!tmp) return TEST_FAILURE; - test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); + test->ifobj_tx->xsk->pkt_stream = tmp; + + tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); + if (!tmp) + return TEST_FAILURE; + test->ifobj_rx->xsk->pkt_stream = tmp; test->ifobj_rx->xsk->rxqsize = DEFAULT_UMEM_BUFFERS; test->ifobj_rx->release_rx = false; @@ -2015,9 +2023,17 @@ int testapp_stats_rx_full(struct test_spec *test) int testapp_stats_fill_empty(struct test_spec *test) { - if (pkt_stream_replace(test, DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE)) + struct pkt_stream *tmp; + + tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS + DEFAULT_UMEM_BUFFERS / 2, MIN_PKT_SIZE); + if (!tmp) return TEST_FAILURE; - test->ifobj_rx->xsk->pkt_stream = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); + test->ifobj_tx->xsk->pkt_stream = tmp; + + tmp = pkt_stream_generate(DEFAULT_UMEM_BUFFERS, MIN_PKT_SIZE); + if (!tmp) + return TEST_FAILURE; + test->ifobj_rx->xsk->pkt_stream = tmp; test->ifobj_rx->use_fill_ring = false; test->ifobj_rx->validation_func = validate_fill_empty; diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c index 2ee17ef1dae2..56cbea280fbd 100644 --- a/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_multi_test.c @@ -62,8 +62,10 @@ static void release_child(struct child *child) return; close(child->go[1]); close(child->go[0]); - if (child->thread) + if (child->thread) { pthread_join(child->thread, NULL); + child->thread = 0; + } close(child->c2p[0]); close(child->c2p[1]); if (child->pid > 0) @@ -331,6 +333,8 @@ test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_multi { static struct child child; + memset(&child, 0, sizeof(child)); + /* no pid filter */ __test_attach_api(binary, pattern, opts, NULL); diff --git a/tools/testing/selftests/bpf/prog_tests/verifier_log.c b/tools/testing/selftests/bpf/prog_tests/verifier_log.c index 8337c6bc5b95..aaa2854974c0 100644 --- a/tools/testing/selftests/bpf/prog_tests/verifier_log.c +++ b/tools/testing/selftests/bpf/prog_tests/verifier_log.c @@ -47,7 +47,7 @@ static int load_prog(struct bpf_prog_load_opts *opts, bool expect_load_error) static void verif_log_subtest(const char *name, bool expect_load_error, int log_level) { LIBBPF_OPTS(bpf_prog_load_opts, opts); - char *exp_log, prog_name[16], op_name[32]; + char *exp_log, prog_name[24], op_name[32]; struct test_log_buf *skel; struct bpf_program *prog; size_t fixed_log_sz; diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c index fb952703653e..e8ea26464349 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_bonding.c @@ -610,6 +610,61 @@ static void test_xdp_bonding_features(struct skeletons *skeletons) system("ip link del bond"); } +/* + * Test that changing xmit_hash_policy to vlan+srcmac is rejected when a + * native XDP program is loaded on a bond in 802.3ad or balance-xor mode. + * These modes support XDP only when xmit_hash_policy != vlan+srcmac; freely + * changing the policy creates an inconsistency that triggers a WARNING in + * dev_xdp_uninstall() during device teardown. + */ +static void test_xdp_bonding_xmit_policy_compat(struct skeletons *skeletons) +{ + struct nstoken *nstoken = NULL; + int bond_ifindex = -1; + int xdp_fd, err; + + SYS(out, "ip netns add ns_xmit_policy"); + nstoken = open_netns("ns_xmit_policy"); + if (!ASSERT_OK_PTR(nstoken, "open ns_xmit_policy")) + goto out; + + /* 802.3ad with layer2+3 policy: native XDP is supported */ + SYS(out, "ip link add bond0 type bond mode 802.3ad xmit_hash_policy layer2+3"); + SYS(out, "ip link add veth0 type veth peer name veth0p"); + SYS(out, "ip link set veth0 master bond0"); + SYS(out, "ip link set bond0 up"); + + bond_ifindex = if_nametoindex("bond0"); + if (!ASSERT_GT(bond_ifindex, 0, "bond0 ifindex")) + goto out; + + xdp_fd = bpf_program__fd(skeletons->xdp_dummy->progs.xdp_dummy_prog); + if (!ASSERT_GE(xdp_fd, 0, "xdp_dummy fd")) + goto out; + + err = bpf_xdp_attach(bond_ifindex, xdp_fd, XDP_FLAGS_DRV_MODE, NULL); + if (!ASSERT_OK(err, "attach XDP to bond0")) + goto out; + + /* With XDP loaded, switching to vlan+srcmac must be rejected */ + err = system("ip link set bond0 type bond xmit_hash_policy vlan+srcmac 2>/dev/null"); + ASSERT_NEQ(err, 0, "vlan+srcmac change with XDP loaded should fail"); + + /* Detach XDP first, then the same change must succeed */ + ASSERT_OK(bpf_xdp_detach(bond_ifindex, XDP_FLAGS_DRV_MODE, NULL), + "detach XDP from bond0"); + + bond_ifindex = -1; + err = system("ip link set bond0 type bond xmit_hash_policy vlan+srcmac 2>/dev/null"); + ASSERT_OK(err, "vlan+srcmac change without XDP should succeed"); + +out: + if (bond_ifindex > 0) + bpf_xdp_detach(bond_ifindex, XDP_FLAGS_DRV_MODE, NULL); + close_netns(nstoken); + SYS_NOFAIL("ip netns del ns_xmit_policy"); +} + static int libbpf_debug_print(enum libbpf_print_level level, const char *format, va_list args) { @@ -677,6 +732,9 @@ void serial_test_xdp_bonding(void) test_case->xmit_policy); } + if (test__start_subtest("xdp_bonding_xmit_policy_compat")) + test_xdp_bonding_xmit_policy_compat(&skeletons); + if (test__start_subtest("xdp_bonding_redirect_multi")) test_xdp_bonding_redirect_multi(&skeletons); diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c b/tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c index 3f9146d83d79..325e0b64dc35 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_flowtable.c @@ -67,7 +67,7 @@ void test_xdp_flowtable(void) struct nstoken *tok = NULL; int iifindex, stats_fd; __u32 value, key = 0; - struct bpf_link *link; + struct bpf_link *link = NULL; if (SYS_NOFAIL("nft -v")) { fprintf(stdout, "Missing required nft tool\n"); @@ -160,6 +160,7 @@ void test_xdp_flowtable(void) ASSERT_GE(value, N_PACKETS - 2, "bpf_xdp_flow_lookup failed"); out: + bpf_link__destroy(link); xdp_flowtable__destroy(skel); if (tok) close_netns(tok); diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c b/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c index 19f92affc2da..5c31054ad4a4 100644 --- a/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c +++ b/tools/testing/selftests/bpf/prog_tests/xdp_metadata.c @@ -126,10 +126,10 @@ static int open_xsk(int ifindex, struct xsk *xsk) static void close_xsk(struct xsk *xsk) { - if (xsk->umem) - xsk_umem__delete(xsk->umem); if (xsk->socket) xsk_socket__delete(xsk->socket); + if (xsk->umem) + xsk_umem__delete(xsk->umem); munmap(xsk->umem_area, UMEM_SIZE); } diff --git a/tools/testing/selftests/bpf/progs/dmabuf_iter.c b/tools/testing/selftests/bpf/progs/dmabuf_iter.c index 13cdb11fdeb2..9cbb7442646e 100644 --- a/tools/testing/selftests/bpf/progs/dmabuf_iter.c +++ b/tools/testing/selftests/bpf/progs/dmabuf_iter.c @@ -48,7 +48,7 @@ int dmabuf_collector(struct bpf_iter__dmabuf *ctx) /* Buffers are not required to be named */ if (pname) { - if (bpf_probe_read_kernel(name, sizeof(name), pname)) + if (bpf_probe_read_kernel_str(name, sizeof(name), pname) < 0) return 1; /* Name strings can be provided by userspace */ diff --git a/tools/testing/selftests/bpf/progs/exceptions_assert.c b/tools/testing/selftests/bpf/progs/exceptions_assert.c index a01c2736890f..858af5988a38 100644 --- a/tools/testing/selftests/bpf/progs/exceptions_assert.c +++ b/tools/testing/selftests/bpf/progs/exceptions_assert.c @@ -18,43 +18,43 @@ return *(u64 *)num; \ } -__msg(": R0=0xffffffff80000000") +__msg("R{{.}}=0xffffffff80000000") check_assert(s64, ==, eq_int_min, INT_MIN); -__msg(": R0=0x7fffffff") +__msg("R{{.}}=0x7fffffff") check_assert(s64, ==, eq_int_max, INT_MAX); -__msg(": R0=0") +__msg("R{{.}}=0") check_assert(s64, ==, eq_zero, 0); -__msg(": R0=0x8000000000000000 R1=0x8000000000000000") +__msg("R{{.}}=0x8000000000000000") check_assert(s64, ==, eq_llong_min, LLONG_MIN); -__msg(": R0=0x7fffffffffffffff R1=0x7fffffffffffffff") +__msg("R{{.}}=0x7fffffffffffffff") check_assert(s64, ==, eq_llong_max, LLONG_MAX); -__msg(": R0=scalar(id=1,smax=0x7ffffffe)") +__msg("R{{.}}=scalar(id=1,smax=0x7ffffffe)") check_assert(s64, <, lt_pos, INT_MAX); -__msg(": R0=scalar(id=1,smax=-1,umin=0x8000000000000000,var_off=(0x8000000000000000; 0x7fffffffffffffff))") +__msg("R{{.}}=scalar(id=1,smax=-1,umin=0x8000000000000000,var_off=(0x8000000000000000; 0x7fffffffffffffff))") check_assert(s64, <, lt_zero, 0); -__msg(": R0=scalar(id=1,smax=0xffffffff7fffffff") +__msg("R{{.}}=scalar(id=1,smax=0xffffffff7fffffff") check_assert(s64, <, lt_neg, INT_MIN); -__msg(": R0=scalar(id=1,smax=0x7fffffff)") +__msg("R{{.}}=scalar(id=1,smax=0x7fffffff)") check_assert(s64, <=, le_pos, INT_MAX); -__msg(": R0=scalar(id=1,smax=0)") +__msg("R{{.}}=scalar(id=1,smax=0)") check_assert(s64, <=, le_zero, 0); -__msg(": R0=scalar(id=1,smax=0xffffffff80000000") +__msg("R{{.}}=scalar(id=1,smax=0xffffffff80000000") check_assert(s64, <=, le_neg, INT_MIN); -__msg(": R0=scalar(id=1,smin=umin=0x80000000,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") +__msg("R{{.}}=scalar(id=1,smin=umin=0x80000000,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") check_assert(s64, >, gt_pos, INT_MAX); -__msg(": R0=scalar(id=1,smin=umin=1,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") +__msg("R{{.}}=scalar(id=1,smin=umin=1,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") check_assert(s64, >, gt_zero, 0); -__msg(": R0=scalar(id=1,smin=0xffffffff80000001") +__msg("R{{.}}=scalar(id=1,smin=0xffffffff80000001") check_assert(s64, >, gt_neg, INT_MIN); -__msg(": R0=scalar(id=1,smin=umin=0x7fffffff,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") +__msg("R{{.}}=scalar(id=1,smin=umin=0x7fffffff,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") check_assert(s64, >=, ge_pos, INT_MAX); -__msg(": R0=scalar(id=1,smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") +__msg("R{{.}}=scalar(id=1,smin=0,umax=0x7fffffffffffffff,var_off=(0x0; 0x7fffffffffffffff))") check_assert(s64, >=, ge_zero, 0); -__msg(": R0=scalar(id=1,smin=0xffffffff80000000") +__msg("R{{.}}=scalar(id=1,smin=0xffffffff80000000") check_assert(s64, >=, ge_neg, INT_MIN); SEC("?tc") diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c index 180ba5098ca1..075a1180ec26 100644 --- a/tools/testing/selftests/bpf/progs/get_func_args_test.c +++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c @@ -167,7 +167,7 @@ int BPF_PROG(tp_test2) } __u64 test7_result = 0; -#if defined(bpf_target_x86) || defined(bpf_target_arm64) +#if defined(bpf_target_x86) || defined(bpf_target_arm64) || defined(bpf_target_riscv) SEC("fsession/bpf_fentry_test1") int BPF_PROG(test7) { diff --git a/tools/testing/selftests/bpf/progs/get_func_ip_test.c b/tools/testing/selftests/bpf/progs/get_func_ip_test.c index 43ff836a8ed8..45eaa54d1ac7 100644 --- a/tools/testing/selftests/bpf/progs/get_func_ip_test.c +++ b/tools/testing/selftests/bpf/progs/get_func_ip_test.c @@ -106,7 +106,7 @@ int BPF_URETPROBE(test8, int ret) __u64 test9_entry_result = 0; __u64 test9_exit_result = 0; -#if defined(bpf_target_x86) || defined(bpf_target_arm64) +#if defined(bpf_target_x86) || defined(bpf_target_arm64) || defined(bpf_target_riscv) SEC("fsession/bpf_fentry_test1") int BPF_PROG(test9, int a) { diff --git a/tools/testing/selftests/bpf/progs/map_kptr_race.c b/tools/testing/selftests/bpf/progs/map_kptr_race.c new file mode 100644 index 000000000000..f6f136cd8f60 --- /dev/null +++ b/tools/testing/selftests/bpf/progs/map_kptr_race.c @@ -0,0 +1,197 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */ +#include +#include +#include +#include "../test_kmods/bpf_testmod_kfunc.h" + +struct map_value { + struct prog_test_ref_kfunc __kptr *ref_ptr; +}; + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct map_value); + __uint(max_entries, 1); +} race_hash_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_HASH); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct map_value); + __uint(max_entries, 1); +} race_percpu_hash_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_SK_STORAGE); + __uint(map_flags, BPF_F_NO_PREALLOC); + __type(key, int); + __type(value, struct map_value); +} race_sk_ls_map SEC(".maps"); + +int num_of_refs; +int sk_ls_leak_done; +int target_map_id; +int map_freed; +const volatile int nr_cpus; + +SEC("tc") +int test_htab_leak(struct __sk_buff *skb) +{ + struct prog_test_ref_kfunc *p, *old; + struct map_value val = {}; + struct map_value *v; + int key = 0; + + if (bpf_map_update_elem(&race_hash_map, &key, &val, BPF_ANY)) + return 1; + + v = bpf_map_lookup_elem(&race_hash_map, &key); + if (!v) + return 2; + + p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); + if (!p) + return 3; + old = bpf_kptr_xchg(&v->ref_ptr, p); + if (old) + bpf_kfunc_call_test_release(old); + + bpf_map_delete_elem(&race_hash_map, &key); + + p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); + if (!p) + return 4; + old = bpf_kptr_xchg(&v->ref_ptr, p); + if (old) + bpf_kfunc_call_test_release(old); + + return 0; +} + +static int fill_percpu_kptr(struct map_value *v) +{ + struct prog_test_ref_kfunc *p, *old; + + p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); + if (!p) + return 1; + old = bpf_kptr_xchg(&v->ref_ptr, p); + if (old) + bpf_kfunc_call_test_release(old); + return 0; +} + +SEC("tc") +int test_percpu_htab_leak(struct __sk_buff *skb) +{ + struct map_value *v, *arr[16] = {}; + struct map_value val = {}; + int key = 0; + int err = 0; + + if (bpf_map_update_elem(&race_percpu_hash_map, &key, &val, BPF_ANY)) + return 1; + + for (int i = 0; i < nr_cpus; i++) { + v = bpf_map_lookup_percpu_elem(&race_percpu_hash_map, &key, i); + if (!v) + return 2; + arr[i] = v; + } + + bpf_map_delete_elem(&race_percpu_hash_map, &key); + + for (int i = 0; i < nr_cpus; i++) { + v = arr[i]; + err = fill_percpu_kptr(v); + if (err) + return 3; + } + + return 0; +} + +SEC("tp_btf/inet_sock_set_state") +int BPF_PROG(test_sk_ls_leak, struct sock *sk, int oldstate, int newstate) +{ + struct prog_test_ref_kfunc *p, *old; + struct map_value *v; + + if (newstate != BPF_TCP_SYN_SENT) + return 0; + + if (sk_ls_leak_done) + return 0; + + v = bpf_sk_storage_get(&race_sk_ls_map, sk, NULL, + BPF_SK_STORAGE_GET_F_CREATE); + if (!v) + return 0; + + p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); + if (!p) + return 0; + old = bpf_kptr_xchg(&v->ref_ptr, p); + if (old) + bpf_kfunc_call_test_release(old); + + bpf_sk_storage_delete(&race_sk_ls_map, sk); + + p = bpf_kfunc_call_test_acquire(&(unsigned long){0}); + if (!p) + return 0; + old = bpf_kptr_xchg(&v->ref_ptr, p); + if (old) + bpf_kfunc_call_test_release(old); + + sk_ls_leak_done = 1; + return 0; +} + +long target_map_ptr; + +SEC("fentry/bpf_map_put") +int BPF_PROG(map_put, struct bpf_map *map) +{ + if (target_map_id && map->id == (u32)target_map_id) + target_map_ptr = (long)map; + return 0; +} + +SEC("fexit/htab_map_free") +int BPF_PROG(htab_map_free, struct bpf_map *map) +{ + if (target_map_ptr && (long)map == target_map_ptr) + map_freed = 1; + return 0; +} + +SEC("fexit/bpf_sk_storage_map_free") +int BPF_PROG(sk_map_free, struct bpf_map *map) +{ + if (target_map_ptr && (long)map == target_map_ptr) + map_freed = 1; + return 0; +} + +SEC("syscall") +int count_ref(void *ctx) +{ + struct prog_test_ref_kfunc *p; + unsigned long arg = 0; + + p = bpf_kfunc_call_test_acquire(&arg); + if (!p) + return 1; + + num_of_refs = p->cnt.refs.counter; + + bpf_kfunc_call_test_release(p); + return 0; +} + +char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/profiler.h b/tools/testing/selftests/bpf/progs/profiler.h index 3bac4fdd4bdf..637fbf2c2652 100644 --- a/tools/testing/selftests/bpf/progs/profiler.h +++ b/tools/testing/selftests/bpf/progs/profiler.h @@ -169,7 +169,7 @@ enum bpf_function_id { profiler_bpf_sched_process_exec, profiler_bpf_sched_process_exit, profiler_bpf_sys_enter_kill, - profiler_bpf_do_filp_open_ret, + profiler_bpf_do_file_open_ret, profiler_bpf_sched_process_fork, profiler_bpf_vfs_link, profiler_bpf_vfs_symlink, diff --git a/tools/testing/selftests/bpf/progs/profiler.inc.h b/tools/testing/selftests/bpf/progs/profiler.inc.h index 813143b4985d..9044dd8aff11 100644 --- a/tools/testing/selftests/bpf/progs/profiler.inc.h +++ b/tools/testing/selftests/bpf/progs/profiler.inc.h @@ -751,11 +751,11 @@ int raw_tracepoint__sched_process_exec(struct bpf_raw_tracepoint_args* ctx) return 0; } -SEC("kretprobe/do_filp_open") -int kprobe_ret__do_filp_open(struct pt_regs* ctx) +SEC("kretprobe/do_file_open") +int kprobe_ret__do_file_open(struct pt_regs *ctx) { struct bpf_func_stats_ctx stats_ctx; - bpf_stats_enter(&stats_ctx, profiler_bpf_do_filp_open_ret); + bpf_stats_enter(&stats_ctx, profiler_bpf_do_file_open_ret); struct file* filp = (struct file*)PT_REGS_RC_CORE(ctx); diff --git a/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c b/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c index df4873558634..189c05c6abcc 100644 --- a/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c +++ b/tools/testing/selftests/bpf/progs/rcu_tasks_trace_gp.c @@ -1,36 +1,14 @@ // SPDX-License-Identifier: GPL-2.0 #include -#include #include +#include "../test_kmods/bpf_testmod_kfunc.h" -struct task_ls_map { - __uint(type, BPF_MAP_TYPE_TASK_STORAGE); - __uint(map_flags, BPF_F_NO_PREALLOC); - __type(key, int); - __type(value, int); -} task_ls_map SEC(".maps"); - -long gp_seq; +int done; SEC("syscall") -int do_call_rcu_tasks_trace(void *ctx) +int call_rcu_tasks_trace(void *ctx) { - struct task_struct *current; - int *v; - - current = bpf_get_current_task_btf(); - v = bpf_task_storage_get(&task_ls_map, current, NULL, BPF_LOCAL_STORAGE_GET_F_CREATE); - if (!v) - return 1; - /* Invoke call_rcu_tasks_trace */ - return bpf_task_storage_delete(&task_ls_map, current); -} - -SEC("kprobe/rcu_tasks_trace_postgp") -int rcu_tasks_trace_postgp(void *ctx) -{ - __sync_add_and_fetch(&gp_seq, 1); - return 0; + return bpf_kfunc_call_test_call_rcu_tasks_trace(&done); } char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/test_xdp_meta.c b/tools/testing/selftests/bpf/progs/test_xdp_meta.c index 0a0f371a2dec..fa73b17cb999 100644 --- a/tools/testing/selftests/bpf/progs/test_xdp_meta.c +++ b/tools/testing/selftests/bpf/progs/test_xdp_meta.c @@ -1,12 +1,12 @@ -#include -#include -#include -#include -#include +// SPDX-License-Identifier: GPL-2.0 +#include #include #include +#include + #include "bpf_kfuncs.h" +#include "bpf_tracing_net.h" #define META_SIZE 32 @@ -42,7 +42,7 @@ static bool check_metadata(const char *file, int line, __u8 *meta_have) if (!__builtin_memcmp(meta_have, meta_want, META_SIZE)) return true; - bpf_stream_printk(BPF_STREAM_STDERR, + bpf_stream_printk(BPF_STDERR, "FAIL:%s:%d: metadata mismatch\n" " have:\n %pI6\n %pI6\n" " want:\n %pI6\n %pI6\n", diff --git a/tools/testing/selftests/bpf/progs/verifier_bounds.c b/tools/testing/selftests/bpf/progs/verifier_bounds.c index 560531404bce..e526315c718a 100644 --- a/tools/testing/selftests/bpf/progs/verifier_bounds.c +++ b/tools/testing/selftests/bpf/progs/verifier_bounds.c @@ -1148,7 +1148,7 @@ l0_%=: r0 = 0; \ SEC("xdp") __description("bound check with JMP32_JSLT for crossing 32-bit signed boundary") __success __retval(0) -__flag(!BPF_F_TEST_REG_INVARIANTS) /* known invariants violation */ +__flag(BPF_F_TEST_REG_INVARIANTS) __naked void crossing_32_bit_signed_boundary_2(void) { asm volatile (" \ @@ -1863,4 +1863,178 @@ l1_%=: r0 = 1; \ : __clobber_all); } +/* This test covers the bounds deduction when the u64 range and the tnum + * overlap only at umax. After instruction 3, the ranges look as follows: + * + * 0 umin=0xe01 umax=0xf00 U64_MAX + * | [xxxxxxxxxxxxxx] | + * |----------------------------|------------------------------| + * | x x | tnum values + * + * The verifier can therefore deduce that the R0=0xf0=240. + */ +SEC("socket") +__description("bounds refinement with single-value tnum on umax") +__msg("3: (15) if r0 == 0xe0 {{.*}} R0=240") +__success __log_level(2) +__flag(BPF_F_TEST_REG_INVARIANTS) +__naked void bounds_refinement_tnum_umax(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + r0 |= 0xe0; \ + r0 &= 0xf0; \ + if r0 == 0xe0 goto +2; \ + if r0 == 0xf0 goto +1; \ + r10 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +/* This test covers the bounds deduction when the u64 range and the tnum + * overlap only at umin. After instruction 3, the ranges look as follows: + * + * 0 umin=0xe00 umax=0xeff U64_MAX + * | [xxxxxxxxxxxxxx] | + * |----------------------------|------------------------------| + * | x x | tnum values + * + * The verifier can therefore deduce that the R0=0xe0=224. + */ +SEC("socket") +__description("bounds refinement with single-value tnum on umin") +__msg("3: (15) if r0 == 0xf0 {{.*}} R0=224") +__success __log_level(2) +__flag(BPF_F_TEST_REG_INVARIANTS) +__naked void bounds_refinement_tnum_umin(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + r0 |= 0xe0; \ + r0 &= 0xf0; \ + if r0 == 0xf0 goto +2; \ + if r0 == 0xe0 goto +1; \ + r10 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +/* This test covers the bounds deduction when the only possible tnum value is + * in the middle of the u64 range. After instruction 3, the ranges look as + * follows: + * + * 0 umin=0x7cf umax=0x7df U64_MAX + * | [xxxxxxxxxxxx] | + * |----------------------------|------------------------------| + * | x x x x x | tnum values + * | +--- 0x7e0 + * +--- 0x7d0 + * + * Since the lower four bits are zero, the tnum and the u64 range only overlap + * in R0=0x7d0=2000. Instruction 5 is therefore dead code. + */ +SEC("socket") +__description("bounds refinement with single-value tnum in middle of range") +__msg("3: (a5) if r0 < 0x7cf {{.*}} R0=2000") +__success __log_level(2) +__naked void bounds_refinement_tnum_middle(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + if r0 & 0x0f goto +4; \ + if r0 > 0x7df goto +3; \ + if r0 < 0x7cf goto +2; \ + if r0 == 0x7d0 goto +1; \ + r10 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +/* This test cover the negative case for the tnum/u64 overlap. Since + * they contain the same two values (i.e., {0, 1}), we can't deduce + * anything more. + */ +SEC("socket") +__description("bounds refinement: several overlaps between tnum and u64") +__msg("2: (25) if r0 > 0x1 {{.*}} R0=scalar(smin=smin32=0,smax=umax=smax32=umax32=1,var_off=(0x0; 0x1))") +__failure __log_level(2) +__naked void bounds_refinement_several_overlaps(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + if r0 < 0 goto +3; \ + if r0 > 1 goto +2; \ + if r0 == 1 goto +1; \ + r10 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +/* This test cover the negative case for the tnum/u64 overlap. Since + * they overlap in the two values contained by the u64 range (i.e., + * {0xf, 0x10}), we can't deduce anything more. + */ +SEC("socket") +__description("bounds refinement: multiple overlaps between tnum and u64") +__msg("2: (25) if r0 > 0x10 {{.*}} R0=scalar(smin=umin=smin32=umin32=15,smax=umax=smax32=umax32=16,var_off=(0x0; 0x1f))") +__failure __log_level(2) +__naked void bounds_refinement_multiple_overlaps(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + if r0 < 0xf goto +3; \ + if r0 > 0x10 goto +2; \ + if r0 == 0x10 goto +1; \ + r10 = 0; \ + exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +SEC("socket") +__success +__flag(BPF_F_TEST_REG_INVARIANTS) +__naked void signed_unsigned_intersection32_case1(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + w0 &= 0xffffffff; \ + if w0 < 0x3 goto 1f; /* on fall-through u32 range [3..U32_MAX] */ \ + if w0 s> 0x1 goto 1f; /* on fall-through s32 range [S32_MIN..1] */ \ + if w0 s< 0x0 goto 1f; /* range can be narrowed to [S32_MIN..-1] */ \ + r10 = 0; /* thus predicting the jump. */ \ +1: exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + +SEC("socket") +__success +__flag(BPF_F_TEST_REG_INVARIANTS) +__naked void signed_unsigned_intersection32_case2(void *ctx) +{ + asm volatile(" \ + call %[bpf_get_prandom_u32]; \ + w0 &= 0xffffffff; \ + if w0 > 0x80000003 goto 1f; /* on fall-through u32 range [0..S32_MIN+3] */ \ + if w0 s< -3 goto 1f; /* on fall-through s32 range [-3..S32_MAX] */ \ + if w0 s> 5 goto 1f; /* on fall-through s32 range [-3..5] */ \ + if w0 <= 5 goto 1f; /* range can be narrowed to [0..5] */ \ + r10 = 0; /* thus predicting the jump */ \ +1: exit; \ +" : + : __imm(bpf_get_prandom_u32) + : __clobber_all); +} + char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c index 2ef346c827c2..7bf7dbfd237d 100644 --- a/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c +++ b/tools/testing/selftests/bpf/progs/verifier_linked_scalars.c @@ -363,4 +363,68 @@ void alu32_negative_offset(void) __sink(path[0]); } +void dummy_calls(void) +{ + bpf_iter_num_new(0, 0, 0); + bpf_iter_num_next(0); + bpf_iter_num_destroy(0); +} + +SEC("socket") +__success +__flag(BPF_F_TEST_STATE_FREQ) +int spurious_precision_marks(void *ctx) +{ + struct bpf_iter_num iter; + + asm volatile( + "r1 = %[iter];" + "r2 = 0;" + "r3 = 10;" + "call %[bpf_iter_num_new];" + "1:" + "r1 = %[iter];" + "call %[bpf_iter_num_next];" + "if r0 == 0 goto 4f;" + "r7 = *(u32 *)(r0 + 0);" + "r8 = *(u32 *)(r0 + 0);" + /* This jump can't be predicted and does not change r7 or r8 state. */ + "if r7 > r8 goto 2f;" + /* Branch explored first ties r2 and r7 as having the same id. */ + "r2 = r7;" + "goto 3f;" + "2:" + /* Branch explored second does not tie r2 and r7 but has a function call. */ + "call %[bpf_get_prandom_u32];" + "3:" + /* + * A checkpoint. + * When first branch is explored, this would inject linked registers + * r2 and r7 into the jump history. + * When second branch is explored, this would be a cache hit point, + * triggering propagate_precision(). + */ + "if r7 <= 42 goto +0;" + /* + * Mark r7 as precise using an if condition that is always true. + * When reached via the second branch, this triggered a bug in the backtrack_insn() + * because r2 (tied to r7) was propagated as precise to a call. + */ + "if r7 <= 0xffffFFFF goto +0;" + "goto 1b;" + "4:" + "r1 = %[iter];" + "call %[bpf_iter_num_destroy];" + : + : __imm_ptr(iter), + __imm(bpf_iter_num_new), + __imm(bpf_iter_num_next), + __imm(bpf_iter_num_destroy), + __imm(bpf_get_prandom_u32) + : __clobber_common, "r7", "r8" + ); + + return 0; +} + char _license[] SEC("license") = "GPL"; diff --git a/tools/testing/selftests/bpf/progs/verifier_scalar_ids.c b/tools/testing/selftests/bpf/progs/verifier_scalar_ids.c index 3072fee9a448..58c7704d61cd 100644 --- a/tools/testing/selftests/bpf/progs/verifier_scalar_ids.c +++ b/tools/testing/selftests/bpf/progs/verifier_scalar_ids.c @@ -40,6 +40,9 @@ __naked void linked_regs_bpf_k(void) */ "r3 = r10;" "r3 += r0;" + /* Mark r1 and r2 as alive. */ + "r1 = r1;" + "r2 = r2;" "r0 = 0;" "exit;" : @@ -73,6 +76,9 @@ __naked void linked_regs_bpf_x_src(void) */ "r4 = r10;" "r4 += r0;" + /* Mark r1 and r2 as alive. */ + "r1 = r1;" + "r2 = r2;" "r0 = 0;" "exit;" : @@ -106,6 +112,10 @@ __naked void linked_regs_bpf_x_dst(void) */ "r4 = r10;" "r4 += r3;" + /* Mark r1 and r2 as alive. */ + "r0 = r0;" + "r1 = r1;" + "r2 = r2;" "r0 = 0;" "exit;" : @@ -143,6 +153,9 @@ __naked void linked_regs_broken_link(void) */ "r3 = r10;" "r3 += r0;" + /* Mark r1 and r2 as alive. */ + "r1 = r1;" + "r2 = r2;" "r0 = 0;" "exit;" : @@ -156,16 +169,16 @@ __naked void linked_regs_broken_link(void) */ SEC("socket") __success __log_level(2) -__msg("12: (0f) r2 += r1") +__msg("17: (0f) r2 += r1") /* Current state */ -__msg("frame2: last_idx 12 first_idx 11 subseq_idx -1 ") -__msg("frame2: regs=r1 stack= before 11: (bf) r2 = r10") +__msg("frame2: last_idx 17 first_idx 14 subseq_idx -1 ") +__msg("frame2: regs=r1 stack= before 16: (bf) r2 = r10") __msg("frame2: parent state regs=r1 stack=") __msg("frame1: parent state regs= stack=") __msg("frame0: parent state regs= stack=") /* Parent state */ -__msg("frame2: last_idx 10 first_idx 10 subseq_idx 11 ") -__msg("frame2: regs=r1 stack= before 10: (25) if r1 > 0x7 goto pc+0") +__msg("frame2: last_idx 13 first_idx 13 subseq_idx 14 ") +__msg("frame2: regs=r1 stack= before 13: (25) if r1 > 0x7 goto pc+0") __msg("frame2: parent state regs=r1 stack=") /* frame1.r{6,7} are marked because mark_precise_scalar_ids() * looks for all registers with frame2.r1.id in the current state @@ -173,20 +186,20 @@ __msg("frame2: parent state regs=r1 stack=") __msg("frame1: parent state regs=r6,r7 stack=") __msg("frame0: parent state regs=r6 stack=") /* Parent state */ -__msg("frame2: last_idx 8 first_idx 8 subseq_idx 10") -__msg("frame2: regs=r1 stack= before 8: (85) call pc+1") +__msg("frame2: last_idx 9 first_idx 9 subseq_idx 13") +__msg("frame2: regs=r1 stack= before 9: (85) call pc+3") /* frame1.r1 is marked because of backtracking of call instruction */ __msg("frame1: parent state regs=r1,r6,r7 stack=") __msg("frame0: parent state regs=r6 stack=") /* Parent state */ -__msg("frame1: last_idx 7 first_idx 6 subseq_idx 8") -__msg("frame1: regs=r1,r6,r7 stack= before 7: (bf) r7 = r1") -__msg("frame1: regs=r1,r6 stack= before 6: (bf) r6 = r1") +__msg("frame1: last_idx 8 first_idx 7 subseq_idx 9") +__msg("frame1: regs=r1,r6,r7 stack= before 8: (bf) r7 = r1") +__msg("frame1: regs=r1,r6 stack= before 7: (bf) r6 = r1") __msg("frame1: parent state regs=r1 stack=") __msg("frame0: parent state regs=r6 stack=") /* Parent state */ -__msg("frame1: last_idx 4 first_idx 4 subseq_idx 6") -__msg("frame1: regs=r1 stack= before 4: (85) call pc+1") +__msg("frame1: last_idx 4 first_idx 4 subseq_idx 7") +__msg("frame1: regs=r1 stack= before 4: (85) call pc+2") __msg("frame0: parent state regs=r1,r6 stack=") /* Parent state */ __msg("frame0: last_idx 3 first_idx 1 subseq_idx 4") @@ -204,6 +217,7 @@ __naked void precision_many_frames(void) "r1 = r0;" "r6 = r0;" "call precision_many_frames__foo;" + "r6 = r6;" /* mark r6 as live */ "exit;" : : __imm(bpf_ktime_get_ns) @@ -220,6 +234,8 @@ void precision_many_frames__foo(void) "r6 = r1;" "r7 = r1;" "call precision_many_frames__bar;" + "r6 = r6;" /* mark r6 as live */ + "r7 = r7;" /* mark r7 as live */ "exit" ::: __clobber_all); } @@ -229,6 +245,8 @@ void precision_many_frames__bar(void) { asm volatile ( "if r1 > 7 goto +0;" + "r6 = 0;" /* mark r6 as live */ + "r7 = 0;" /* mark r7 as live */ /* force r1 to be precise, this eventually marks: * - bar frame r1 * - foo frame r{1,6,7} @@ -340,6 +358,8 @@ __naked void precision_two_ids(void) "r3 += r7;" /* force r9 to be precise, this also marks r8 */ "r3 += r9;" + "r6 = r6;" /* mark r6 as live */ + "r8 = r8;" /* mark r8 as live */ "exit;" : : __imm(bpf_ktime_get_ns) @@ -353,7 +373,7 @@ __flag(BPF_F_TEST_STATE_FREQ) * collect_linked_regs() can't tie more than 6 registers for a single insn. */ __msg("8: (25) if r0 > 0x7 goto pc+0 ; R0=scalar(id=1") -__msg("9: (bf) r6 = r6 ; R6=scalar(id=2") +__msg("14: (bf) r6 = r6 ; R6=scalar(id=2") /* check that r{0-5} are marked precise after 'if' */ __msg("frame0: regs=r0 stack= before 8: (25) if r0 > 0x7 goto pc+0") __msg("frame0: parent state regs=r0,r1,r2,r3,r4,r5 stack=:") @@ -372,6 +392,12 @@ __naked void linked_regs_too_many_regs(void) "r6 = r0;" /* propagate range for r{0-6} */ "if r0 > 7 goto +0;" + /* keep r{1-5} live */ + "r1 = r1;" + "r2 = r2;" + "r3 = r3;" + "r4 = r4;" + "r5 = r5;" /* make r6 appear in the log */ "r6 = r6;" /* force r0 to be precise, @@ -517,7 +543,7 @@ __naked void check_ids_in_regsafe_2(void) "*(u64*)(r10 - 8) = r1;" /* r9 = pointer to stack */ "r9 = r10;" - "r9 += -8;" + "r9 += -16;" /* r8 = ktime_get_ns() */ "call %[bpf_ktime_get_ns];" "r8 = r0;" @@ -538,6 +564,8 @@ __naked void check_ids_in_regsafe_2(void) "if r7 > 4 goto l2_%=;" /* Access memory at r9[r6] */ "r9 += r6;" + "r9 += r7;" + "r9 += r8;" "r0 = *(u8*)(r9 + 0);" "l2_%=:" "r0 = 0;" diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c index 186a25ab429a..e62c6b78657f 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include "bpf_testmod.h" @@ -885,6 +886,32 @@ __bpf_kfunc void bpf_kfunc_call_test_sleepable(void) { } +struct bpf_kfunc_rcu_tasks_trace_data { + struct rcu_head rcu; + int *done; +}; + +static void bpf_kfunc_rcu_tasks_trace_cb(struct rcu_head *rhp) +{ + struct bpf_kfunc_rcu_tasks_trace_data *data; + + data = container_of(rhp, struct bpf_kfunc_rcu_tasks_trace_data, rcu); + WRITE_ONCE(*data->done, 1); + kfree(data); +} + +__bpf_kfunc int bpf_kfunc_call_test_call_rcu_tasks_trace(int *done) +{ + struct bpf_kfunc_rcu_tasks_trace_data *data; + + data = kmalloc(sizeof(*data), GFP_ATOMIC); + if (!data) + return -ENOMEM; + data->done = done; + call_rcu_tasks_trace(&data->rcu, bpf_kfunc_rcu_tasks_trace_cb); + return 0; +} + __bpf_kfunc int bpf_kfunc_init_sock(struct init_sock_args *args) { int proto; @@ -1222,6 +1249,7 @@ BTF_ID_FLAGS(func, bpf_kfunc_call_test_destructive, KF_DESTRUCTIVE) BTF_ID_FLAGS(func, bpf_kfunc_call_test_static_unused_arg) BTF_ID_FLAGS(func, bpf_kfunc_call_test_offset) BTF_ID_FLAGS(func, bpf_kfunc_call_test_sleepable, KF_SLEEPABLE) +BTF_ID_FLAGS(func, bpf_kfunc_call_test_call_rcu_tasks_trace) BTF_ID_FLAGS(func, bpf_kfunc_init_sock, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_kfunc_close_sock, KF_SLEEPABLE) BTF_ID_FLAGS(func, bpf_kfunc_call_kernel_connect, KF_SLEEPABLE) diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h index d5c5454e257e..b393bf771131 100644 --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod_kfunc.h @@ -118,6 +118,7 @@ void bpf_kfunc_call_test_mem_len_fail2(__u64 *mem, int len) __ksym; void bpf_kfunc_call_test_destructive(void) __ksym; void bpf_kfunc_call_test_sleepable(void) __ksym; +int bpf_kfunc_call_test_call_rcu_tasks_trace(int *done) __ksym; void bpf_kfunc_call_test_offset(struct prog_test_ref_kfunc *p); struct prog_test_member *bpf_kfunc_call_memb_acquire(void); diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c index 02a85dda30e6..0929f4a7bda4 100644 --- a/tools/testing/selftests/bpf/test_progs.c +++ b/tools/testing/selftests/bpf/test_progs.c @@ -1261,14 +1261,8 @@ int get_bpf_max_tramp_links(void) return ret; } -#define MAX_BACKTRACE_SZ 128 -void crash_handler(int signum) +static void dump_crash_log(void) { - void *bt[MAX_BACKTRACE_SZ]; - size_t sz; - - sz = backtrace(bt, ARRAY_SIZE(bt)); - fflush(stdout); stdout = env.stdout_saved; stderr = env.stderr_saved; @@ -1277,12 +1271,32 @@ void crash_handler(int signum) env.test_state->error_cnt++; dump_test_log(env.test, env.test_state, true, false, NULL); } +} + +#define MAX_BACKTRACE_SZ 128 + +void crash_handler(int signum) +{ + void *bt[MAX_BACKTRACE_SZ]; + size_t sz; + + sz = backtrace(bt, ARRAY_SIZE(bt)); + + dump_crash_log(); + if (env.worker_id != -1) fprintf(stderr, "[%d]: ", env.worker_id); fprintf(stderr, "Caught signal #%d!\nStack trace:\n", signum); backtrace_symbols_fd(bt, sz, STDERR_FILENO); } +#ifdef __SANITIZE_ADDRESS__ +void __asan_on_error(void) +{ + dump_crash_log(); +} +#endif + void hexdump(const char *prefix, const void *buf, size_t len) { for (int i = 0; i < len; i++) { @@ -1799,7 +1813,7 @@ static int worker_main_send_subtests(int sock, struct test_state *state) msg.subtest_done.num = i; - strncpy(msg.subtest_done.name, subtest_state->name, MAX_SUBTEST_NAME); + strscpy(msg.subtest_done.name, subtest_state->name, MAX_SUBTEST_NAME); msg.subtest_done.error_cnt = subtest_state->error_cnt; msg.subtest_done.skipped = subtest_state->skipped; @@ -1944,13 +1958,15 @@ int main(int argc, char **argv) .parser = parse_arg, .doc = argp_program_doc, }; + int err, i; + +#ifndef __SANITIZE_ADDRESS__ struct sigaction sigact = { .sa_handler = crash_handler, .sa_flags = SA_RESETHAND, - }; - int err, i; - + }; sigaction(SIGSEGV, &sigact, NULL); +#endif env.stdout_saved = stdout; env.stderr_saved = stderr; diff --git a/tools/testing/selftests/bpf/test_verifier.c b/tools/testing/selftests/bpf/test_verifier.c index 27db34ecf3f5..a8ae03c57bba 100644 --- a/tools/testing/selftests/bpf/test_verifier.c +++ b/tools/testing/selftests/bpf/test_verifier.c @@ -1320,7 +1320,7 @@ static bool cmp_str_seq(const char *log, const char *exp) printf("FAIL\nTestcase bug\n"); return false; } - strncpy(needle, exp, len); + memcpy(needle, exp, len); needle[len] = 0; q = strstr(log, needle); if (!q) { diff --git a/tools/testing/selftests/bpf/testing_helpers.c b/tools/testing/selftests/bpf/testing_helpers.c index 16eb37e5bad6..66af0d13751a 100644 --- a/tools/testing/selftests/bpf/testing_helpers.c +++ b/tools/testing/selftests/bpf/testing_helpers.c @@ -212,6 +212,7 @@ int parse_test_list_file(const char *path, break; } + free(buf); fclose(f); return err; } diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c index eeaab7013ca2..0e63daf83ed5 100644 --- a/tools/testing/selftests/bpf/trace_helpers.c +++ b/tools/testing/selftests/bpf/trace_helpers.c @@ -24,12 +24,6 @@ #define TRACEFS_PIPE "/sys/kernel/tracing/trace_pipe" #define DEBUGFS_PIPE "/sys/kernel/debug/tracing/trace_pipe" -struct ksyms { - struct ksym *syms; - size_t sym_cap; - size_t sym_cnt; -}; - static struct ksyms *ksyms; static pthread_mutex_t ksyms_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -54,6 +48,8 @@ void free_kallsyms_local(struct ksyms *ksyms) if (!ksyms) return; + free(ksyms->filtered_syms); + if (!ksyms->syms) { free(ksyms); return; @@ -610,7 +606,7 @@ static int search_kallsyms_compare(const void *p1, const struct ksym *p2) return compare_name(p1, p2->name); } -int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel) +int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel) { size_t cap = 0, cnt = 0; char *name = NULL, *ksym_name, **syms = NULL; @@ -637,8 +633,10 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel) else f = fopen("/sys/kernel/debug/tracing/available_filter_functions", "r"); - if (!f) + if (!f) { + free_kallsyms_local(ksyms); return -EINVAL; + } map = hashmap__new(symbol_hash, symbol_equal, NULL); if (IS_ERR(map)) { @@ -679,15 +677,18 @@ int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel) syms[cnt++] = ksym_name; } - *symsp = syms; - *cntp = cnt; + ksyms->filtered_syms = syms; + ksyms->filtered_cnt = cnt; + *ksymsp = ksyms; error: free(name); fclose(f); hashmap__free(map); - if (err) + if (err) { free(syms); + free_kallsyms_local(ksyms); + } return err; } diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h index a5576b2dfc26..d5bf1433675d 100644 --- a/tools/testing/selftests/bpf/trace_helpers.h +++ b/tools/testing/selftests/bpf/trace_helpers.h @@ -23,7 +23,14 @@ struct ksym { long addr; char *name; }; -struct ksyms; + +struct ksyms { + struct ksym *syms; + size_t sym_cap; + size_t sym_cnt; + char **filtered_syms; + size_t filtered_cnt; +}; typedef int (*ksym_cmp_t)(const void *p1, const void *p2); typedef int (*ksym_search_cmp_t)(const void *p1, const struct ksym *p2); @@ -53,7 +60,7 @@ ssize_t get_rel_offset(uintptr_t addr); int read_build_id(const char *path, char *build_id, size_t size); -int bpf_get_ksyms(char ***symsp, size_t *cntp, bool kernel); +int bpf_get_ksyms(struct ksyms **ksymsp, bool kernel); int bpf_get_addrs(unsigned long **addrsp, size_t *cntp, bool kernel); #endif diff --git a/tools/testing/selftests/bpf/verifier/precise.c b/tools/testing/selftests/bpf/verifier/precise.c index 061d98f6e9bb..a9242103dc47 100644 --- a/tools/testing/selftests/bpf/verifier/precise.c +++ b/tools/testing/selftests/bpf/verifier/precise.c @@ -44,9 +44,9 @@ mark_precise: frame0: regs=r2 stack= before 23\ mark_precise: frame0: regs=r2 stack= before 22\ mark_precise: frame0: regs=r2 stack= before 20\ - mark_precise: frame0: parent state regs=r2,r9 stack=:\ + mark_precise: frame0: parent state regs=r2 stack=:\ mark_precise: frame0: last_idx 19 first_idx 10\ - mark_precise: frame0: regs=r2,r9 stack= before 19\ + mark_precise: frame0: regs=r2 stack= before 19\ mark_precise: frame0: regs=r9 stack= before 18\ mark_precise: frame0: regs=r8,r9 stack= before 17\ mark_precise: frame0: regs=r0,r9 stack= before 15\ @@ -107,9 +107,9 @@ mark_precise: frame0: parent state regs=r2 stack=:\ mark_precise: frame0: last_idx 20 first_idx 20\ mark_precise: frame0: regs=r2 stack= before 20\ - mark_precise: frame0: parent state regs=r2,r9 stack=:\ + mark_precise: frame0: parent state regs=r2 stack=:\ mark_precise: frame0: last_idx 19 first_idx 17\ - mark_precise: frame0: regs=r2,r9 stack= before 19\ + mark_precise: frame0: regs=r2 stack= before 19\ mark_precise: frame0: regs=r9 stack= before 18\ mark_precise: frame0: regs=r8,r9 stack= before 17\ mark_precise: frame0: parent state regs= stack=:", diff --git a/tools/testing/selftests/bpf/veristat.c b/tools/testing/selftests/bpf/veristat.c index 1be1e353d40a..75f85e0362f5 100644 --- a/tools/testing/selftests/bpf/veristat.c +++ b/tools/testing/selftests/bpf/veristat.c @@ -3378,6 +3378,8 @@ int main(int argc, char **argv) } } free(env.presets[i].atoms); + if (env.presets[i].value.type == ENUMERATOR) + free(env.presets[i].value.svalue); } free(env.presets); return -err; diff --git a/tools/testing/selftests/bpf/xdp_features.c b/tools/testing/selftests/bpf/xdp_features.c index 595c79141cf3..a27ed663967c 100644 --- a/tools/testing/selftests/bpf/xdp_features.c +++ b/tools/testing/selftests/bpf/xdp_features.c @@ -16,6 +16,7 @@ #include +#include "bpf_util.h" #include "xdp_features.skel.h" #include "xdp_features.h" @@ -212,7 +213,7 @@ static void set_env_default(void) env.feature.drv_feature = NETDEV_XDP_ACT_NDO_XMIT; env.feature.action = -EINVAL; env.ifindex = -ENODEV; - strcpy(env.ifname, "unknown"); + strscpy(env.ifname, "unknown"); make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_CTRL_PORT, &env.dut_ctrl_addr, NULL); make_sockaddr(AF_INET6, "::ffff:127.0.0.1", DUT_ECHO_PORT, diff --git a/tools/testing/selftests/bpf/xdp_hw_metadata.c b/tools/testing/selftests/bpf/xdp_hw_metadata.c index 3d8de0d4c96a..6db3b5555a22 100644 --- a/tools/testing/selftests/bpf/xdp_hw_metadata.c +++ b/tools/testing/selftests/bpf/xdp_hw_metadata.c @@ -550,7 +550,7 @@ static int rxq_num(const char *ifname) struct ifreq ifr = { .ifr_data = (void *)&ch, }; - strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1); + strscpy(ifr.ifr_name, ifname); int fd, ret; fd = socket(AF_UNIX, SOCK_DGRAM, 0); @@ -571,7 +571,7 @@ static void hwtstamp_ioctl(int op, const char *ifname, struct hwtstamp_config *c struct ifreq ifr = { .ifr_data = (void *)cfg, }; - strncpy(ifr.ifr_name, ifname, IF_NAMESIZE - 1); + strscpy(ifr.ifr_name, ifname); int fd, ret; fd = socket(AF_UNIX, SOCK_DGRAM, 0); diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh index 5dff3ad53867..a56f4153c64d 100755 --- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh +++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh @@ -196,7 +196,6 @@ test_add_proc() # P = set cpus.partition (0:member, 1:root, 2:isolated) # C = add cpu-list to cpuset.cpus # X = add cpu-list to cpuset.cpus.exclusive -# S

= use prefix in subtree_control # T = put a task into cgroup # CX = add cpu-list to both cpuset.cpus and cpuset.cpus.exclusive # O= = Write to CPU online file of @@ -209,44 +208,46 @@ test_add_proc() # sched-debug matching which includes offline CPUs and single-CPU partitions # while the second one is for matching cpuset.cpus.isolated. # -SETUP_A123_PARTITIONS="C1-3:P1:S+ C2-3:P1:S+ C3:P1" +SETUP_A123_PARTITIONS="C1-3:P1 C2-3:P1 C3:P1" TEST_MATRIX=( # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- - " C0-1 . . C2-3 S+ C4-5 . . 0 A2:0-1" + " C0-1 . . C2-3 . C4-5 . . 0 A2:0-1" " C0-1 . . C2-3 P1 . . . 0 " - " C0-1 . . C2-3 P1:S+ C0-1:P1 . . 0 " - " C0-1 . . C2-3 P1:S+ C1:P1 . . 0 " - " C0-1:S+ . . C2-3 . . . P1 0 " - " C0-1:P1 . . C2-3 S+ C1 . . 0 " - " C0-1:P1 . . C2-3 S+ C1:P1 . . 0 " - " C0-1:P1 . . C2-3 S+ C1:P1 . P1 0 " + " C0-1 . . C2-3 P1 C0-1:P1 . . 0 " + " C0-1 . . C2-3 P1 C1:P1 . . 0 " + " C0-1 . . C2-3 . . . P1 0 " + " C0-1:P1 . . C2-3 . C1 . . 0 " + " C0-1:P1 . . C2-3 . C1:P1 . . 0 " + " C0-1:P1 . . C2-3 . C1:P1 . P1 0 " " C0-1:P1 . . C2-3 C4-5 . . . 0 A1:4-5" - " C0-1:P1 . . C2-3 S+:C4-5 . . . 0 A1:4-5" " C0-1 . . C2-3:P1 . . . C2 0 " " C0-1 . . C2-3:P1 . . . C4-5 0 B1:4-5" - "C0-3:P1:S+ C2-3:P1 . . . . . . 0 A1:0-1|A2:2-3|XA2:2-3" - "C0-3:P1:S+ C2-3:P1 . . C1-3 . . . 0 A1:1|A2:2-3|XA2:2-3" - "C2-3:P1:S+ C3:P1 . . C3 . . . 0 A1:|A2:3|XA2:3 A1:P1|A2:P1" - "C2-3:P1:S+ C3:P1 . . C3 P0 . . 0 A1:3|A2:3 A1:P1|A2:P0" - "C2-3:P1:S+ C2:P1 . . C2-4 . . . 0 A1:3-4|A2:2" - "C2-3:P1:S+ C3:P1 . . C3 . . C0-2 0 A1:|B1:0-2 A1:P1|A2:P1" + " C0-3:P1 C2-3:P1 . . . . . . 0 A1:0-1|A2:2-3|XA2:2-3" + " C0-3:P1 C2-3:P1 . . C1-3 . . . 0 A1:1|A2:2-3|XA2:2-3" + " C2-3:P1 C3:P1 . . C3 . . . 0 A1:|A2:3|XA2:3 A1:P1|A2:P1" + " C2-3:P1 C3:P1 . . C3 P0 . . 0 A1:3|A2:3 A1:P1|A2:P0" + " C2-3:P1 C2:P1 . . C2-4 . . . 0 A1:3-4|A2:2" + " C2-3:P1 C3:P1 . . C3 . . C0-2 0 A1:|B1:0-2 A1:P1|A2:P1" "$SETUP_A123_PARTITIONS . C2-3 . . . 0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1" # CPU offlining cases: - " C0-1 . . C2-3 S+ C4-5 . O2=0 0 A1:0-1|B1:3" - "C0-3:P1:S+ C2-3:P1 . . O2=0 . . . 0 A1:0-1|A2:3" - "C0-3:P1:S+ C2-3:P1 . . O2=0 O2=1 . . 0 A1:0-1|A2:2-3" - "C0-3:P1:S+ C2-3:P1 . . O1=0 . . . 0 A1:0|A2:2-3" - "C0-3:P1:S+ C2-3:P1 . . O1=0 O1=1 . . 0 A1:0-1|A2:2-3" - "C2-3:P1:S+ C3:P1 . . O3=0 O3=1 . . 0 A1:2|A2:3 A1:P1|A2:P1" - "C2-3:P1:S+ C3:P2 . . O3=0 O3=1 . . 0 A1:2|A2:3 A1:P1|A2:P2" - "C2-3:P1:S+ C3:P1 . . O2=0 O2=1 . . 0 A1:2|A2:3 A1:P1|A2:P1" - "C2-3:P1:S+ C3:P2 . . O2=0 O2=1 . . 0 A1:2|A2:3 A1:P1|A2:P2" - "C2-3:P1:S+ C3:P1 . . O2=0 . . . 0 A1:|A2:3 A1:P1|A2:P1" - "C2-3:P1:S+ C3:P1 . . O3=0 . . . 0 A1:2|A2: A1:P1|A2:P1" - "C2-3:P1:S+ C3:P1 . . T:O2=0 . . . 0 A1:3|A2:3 A1:P1|A2:P-1" - "C2-3:P1:S+ C3:P1 . . . T:O3=0 . . 0 A1:2|A2:2 A1:P1|A2:P-1" + " C0-1 . . C2-3 . C4-5 . O2=0 0 A1:0-1|B1:3" + " C0-3:P1 C2-3:P1 . . O2=0 . . . 0 A1:0-1|A2:3" + " C0-3:P1 C2-3:P1 . . O2=0 O2=1 . . 0 A1:0-1|A2:2-3" + " C0-3:P1 C2-3:P1 . . O1=0 . . . 0 A1:0|A2:2-3" + " C0-3:P1 C2-3:P1 . . O1=0 O1=1 . . 0 A1:0-1|A2:2-3" + " C2-3:P1 C3:P1 . . O3=0 O3=1 . . 0 A1:2|A2:3 A1:P1|A2:P1" + " C2-3:P1 C3:P2 . . O3=0 O3=1 . . 0 A1:2|A2:3 A1:P1|A2:P2" + " C2-3:P1 C3:P1 . . O2=0 O2=1 . . 0 A1:2|A2:3 A1:P1|A2:P1" + " C2-3:P1 C3:P2 . . O2=0 O2=1 . . 0 A1:2|A2:3 A1:P1|A2:P2" + " C2-3:P1 C3:P1 . . O2=0 . . . 0 A1:|A2:3 A1:P1|A2:P1" + " C2-3:P1 C3:P1 . . O3=0 . . . 0 A1:2|A2: A1:P1|A2:P1" + " C2-3:P1 C3:P1 . . T:O2=0 . . . 0 A1:3|A2:3 A1:P1|A2:P-1" + " C2-3:P1 C3:P1 . . . T:O3=0 . . 0 A1:2|A2:2 A1:P1|A2:P-1" + " C2-3:P1 C3:P2 . . T:O2=0 . . . 0 A1:3|A2:3 A1:P1|A2:P-2" + " C1-3:P1 C3:P2 . . . T:O3=0 . . 0 A1:1-2|A2:1-2 A1:P1|A2:P-2 3|" + " C1-3:P1 C3:P2 . . . T:O3=0 O3=1 . 0 A1:1-2|A2:3 A1:P1|A2:P2 3" "$SETUP_A123_PARTITIONS . O1=0 . . . 0 A1:|A2:2|A3:3 A1:P1|A2:P1|A3:P1" "$SETUP_A123_PARTITIONS . O2=0 . . . 0 A1:1|A2:|A3:3 A1:P1|A2:P1|A3:P1" "$SETUP_A123_PARTITIONS . O3=0 . . . 0 A1:1|A2:2|A3: A1:P1|A2:P1|A3:P1" @@ -264,88 +265,87 @@ TEST_MATRIX=( # # Remote partition and cpuset.cpus.exclusive tests # - " C0-3:S+ C1-3:S+ C2-3 . X2-3 . . . 0 A1:0-3|A2:1-3|A3:2-3|XA1:2-3" - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3:P2 . . 0 A1:0-1|A2:2-3|A3:2-3 A1:P0|A2:P2 2-3" - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X3:P2 . . 0 A1:0-2|A2:3|A3:3 A1:P0|A2:P2 3" - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3 X2-3:P2 . 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3 X2-3:P2:C3 . 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" - " C0-3:S+ C1-3:S+ C2-3 C2-3 . . . P2 0 A1:0-1|A2:1|A3:1|B1:2-3 A1:P0|A3:P0|B1:P2" - " C0-3:S+ C1-3:S+ C2-3 C4-5 . . . P2 0 B1:4-5 B1:P2 4-5" - " C0-3:S+ C1-3:S+ C2-3 C4 X2-3 X2-3 X2-3:P2 P2 0 A3:2-3|B1:4 A3:P2|B1:P2 2-4" - " C0-3:S+ C1-3:S+ C2-3 C4 X2-3 X2-3 X2-3:P2:C1-3 P2 0 A3:2-3|B1:4 A3:P2|B1:P2 2-4" - " C0-3:S+ C1-3:S+ C2-3 C4 X1-3 X1-3:P2 P2 . 0 A2:1|A3:2-3 A2:P2|A3:P2 1-3" - " C0-3:S+ C1-3:S+ C2-3 C4 X2-3 X2-3 X2-3:P2 P2:C4-5 0 A3:2-3|B1:4-5 A3:P2|B1:P2 2-5" - " C4:X0-3:S+ X1-3:S+ X2-3 . . P2 . . 0 A1:4|A2:1-3|A3:1-3 A2:P2 1-3" - " C4:X0-3:S+ X1-3:S+ X2-3 . . . P2 . 0 A1:4|A2:4|A3:2-3 A3:P2 2-3" + " C0-3 C1-3 C2-3 . X2-3 . . . 0 A1:0-3|A2:1-3|A3:2-3|XA1:2-3" + " C0-3 C1-3 C2-3 . X2-3 X2-3:P2 . . 0 A1:0-1|A2:2-3|A3:2-3 A1:P0|A2:P2 2-3" + " C0-3 C1-3 C2-3 . X2-3 X3:P2 . . 0 A1:0-2|A2:3|A3:3 A1:P0|A2:P2 3" + " C0-3 C1-3 C2-3 . X2-3 X2-3 X2-3:P2 . 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" + " C0-3 C1-3 C2-3 . X2-3 X2-3 X2-3:P2:C3 . 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" + " C0-3 C1-3 C2-3 C2-3 . . . P2 0 A1:0-1|A2:1|A3:1|B1:2-3 A1:P0|A3:P0|B1:P2" + " C0-3 C1-3 C2-3 C4-5 . . . P2 0 B1:4-5 B1:P2 4-5" + " C0-3 C1-3 C2-3 C4 X2-3 X2-3 X2-3:P2 P2 0 A3:2-3|B1:4 A3:P2|B1:P2 2-4" + " C0-3 C1-3 C2-3 C4 X2-3 X2-3 X2-3:P2:C1-3 P2 0 A3:2-3|B1:4 A3:P2|B1:P2 2-4" + " C0-3 C1-3 C2-3 C4 X1-3 X1-3:P2 P2 . 0 A2:1|A3:2-3 A2:P2|A3:P2 1-3" + " C0-3 C1-3 C2-3 C4 X2-3 X2-3 X2-3:P2 P2:C4-5 0 A3:2-3|B1:4-5 A3:P2|B1:P2 2-5" + " C4:X0-3 X1-3 X2-3 . . P2 . . 0 A1:4|A2:1-3|A3:1-3 A2:P2 1-3" + " C4:X0-3 X1-3 X2-3 . . . P2 . 0 A1:4|A2:4|A3:2-3 A3:P2 2-3" # Nested remote/local partition tests - " C0-3:S+ C1-3:S+ C2-3 C4-5 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:|A3:2-3|B1:4-5 \ + " C0-3 C1-3 C2-3 C4-5 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:|A3:2-3|B1:4-5 \ A1:P0|A2:P1|A3:P2|B1:P1 2-3" - " C0-3:S+ C1-3:S+ C2-3 C4 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:|A3:2-3|B1:4 \ + " C0-3 C1-3 C2-3 C4 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:|A3:2-3|B1:4 \ A1:P0|A2:P1|A3:P2|B1:P1 2-4|2-3" - " C0-3:S+ C1-3:S+ C2-3 C4 X2-3 X2-3:P1 . P1 0 A1:0-1|A2:2-3|A3:2-3|B1:4 \ + " C0-3 C1-3 C2-3 C4 X2-3 X2-3:P1 . P1 0 A1:0-1|A2:2-3|A3:2-3|B1:4 \ A1:P0|A2:P1|A3:P0|B1:P1" - " C0-3:S+ C1-3:S+ C3 C4 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:2|A3:3|B1:4 \ + " C0-3 C1-3 C3 C4 X2-3 X2-3:P1 P2 P1 0 A1:0-1|A2:2|A3:3|B1:4 \ A1:P0|A2:P1|A3:P2|B1:P1 2-4|3" - " C0-4:S+ C1-4:S+ C2-4 . X2-4 X2-4:P2 X4:P1 . 0 A1:0-1|A2:2-3|A3:4 \ + " C0-4 C1-4 C2-4 . X2-4 X2-4:P2 X4:P1 . 0 A1:0-1|A2:2-3|A3:4 \ A1:P0|A2:P2|A3:P1 2-4|2-3" - " C0-4:S+ C1-4:S+ C2-4 . X2-4 X2-4:P2 X3-4:P1 . 0 A1:0-1|A2:2|A3:3-4 \ + " C0-4 C1-4 C2-4 . X2-4 X2-4:P2 X3-4:P1 . 0 A1:0-1|A2:2|A3:3-4 \ A1:P0|A2:P2|A3:P1 2" - " C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \ + " C0-4:X2-4 C1-4:X2-4:P2 C2-4:X4:P1 \ . . X5 . . 0 A1:0-4|A2:1-4|A3:2-4 \ A1:P0|A2:P-2|A3:P-1 ." - " C0-4:X2-4:S+ C1-4:X2-4:S+:P2 C2-4:X4:P1 \ + " C0-4:X2-4 C1-4:X2-4:P2 C2-4:X4:P1 \ . . . X1 . 0 A1:0-1|A2:2-4|A3:2-4 \ A1:P0|A2:P2|A3:P-1 2-4" # Remote partition offline tests - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3 X2-3:P2:O2=0 . 0 A1:0-1|A2:1|A3:3 A1:P0|A3:P2 2-3" - " C0-3:S+ C1-3:S+ C2-3 . X2-3 X2-3 X2-3:P2:O2=0 O2=1 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" - " C0-3:S+ C1-3:S+ C3 . X2-3 X2-3 P2:O3=0 . 0 A1:0-2|A2:1-2|A3: A1:P0|A3:P2 3" - " C0-3:S+ C1-3:S+ C3 . X2-3 X2-3 T:P2:O3=0 . 0 A1:0-2|A2:1-2|A3:1-2 A1:P0|A3:P-2 3|" + " C0-3 C1-3 C2-3 . X2-3 X2-3 X2-3:P2:O2=0 . 0 A1:0-1|A2:1|A3:3 A1:P0|A3:P2 2-3" + " C0-3 C1-3 C2-3 . X2-3 X2-3 X2-3:P2:O2=0 O2=1 0 A1:0-1|A2:1|A3:2-3 A1:P0|A3:P2 2-3" + " C0-3 C1-3 C3 . X2-3 X2-3 P2:O3=0 . 0 A1:0-2|A2:1-2|A3: A1:P0|A3:P2 3" + " C0-3 C1-3 C3 . X2-3 X2-3 T:P2:O3=0 . 0 A1:0-2|A2:1-2|A3:1-2 A1:P0|A3:P-2 3|" # An invalidated remote partition cannot self-recover from hotplug - " C0-3:S+ C1-3:S+ C2 . X2-3 X2-3 T:P2:O2=0 O2=1 0 A1:0-3|A2:1-3|A3:2 A1:P0|A3:P-2 ." + " C0-3 C1-3 C2 . X2-3 X2-3 T:P2:O2=0 O2=1 0 A1:0-3|A2:1-3|A3:2 A1:P0|A3:P-2 ." # cpus.exclusive.effective clearing test - " C0-3:S+ C1-3:S+ C2 . X2-3:X . . . 0 A1:0-3|A2:1-3|A3:2|XA1:" + " C0-3 C1-3 C2 . X2-3:X . . . 0 A1:0-3|A2:1-3|A3:2|XA1:" # Invalid to valid remote partition transition test - " C0-3:S+ C1-3 . . . X3:P2 . . 0 A1:0-3|A2:1-3|XA2: A2:P-2 ." - " C0-3:S+ C1-3:X3:P2 - . . X2-3 P2 . . 0 A1:0-2|A2:3|XA2:3 A2:P2 3" + " C0-3 C1-3 . . . X3:P2 . . 0 A1:0-3|A2:1-3|XA2: A2:P-2 ." + " C0-3 C1-3:X3:P2 . . X2-3 P2 . . 0 A1:0-2|A2:3|XA2:3 A2:P2 3" # Invalid to valid local partition direct transition tests - " C1-3:S+:P2 X4:P2 . . . . . . 0 A1:1-3|XA1:1-3|A2:1-3:XA2: A1:P2|A2:P-2 1-3" - " C1-3:S+:P2 X4:P2 . . . X3:P2 . . 0 A1:1-2|XA1:1-3|A2:3:XA2:3 A1:P2|A2:P2 1-3" - " C0-3:P2 . . C4-6 C0-4 . . . 0 A1:0-4|B1:5-6 A1:P2|B1:P0" - " C0-3:P2 . . C4-6 C0-4:C0-3 . . . 0 A1:0-3|B1:4-6 A1:P2|B1:P0 0-3" + " C1-3:P2 X4:P2 . . . . . . 0 A1:1-3|XA1:1-3|A2:1-3:XA2: A1:P2|A2:P-2 1-3" + " C1-3:P2 X4:P2 . . . X3:P2 . . 0 A1:1-2|XA1:1-3|A2:3:XA2:3 A1:P2|A2:P2 1-3" + " C0-3:P2 . . C4-6 C0-4 . . . 0 A1:0-4|B1:5-6 A1:P2|B1:P0" + " C0-3:P2 . . C4-6 C0-4:C0-3 . . . 0 A1:0-3|B1:4-6 A1:P2|B1:P0 0-3" # Local partition invalidation tests - " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ + " C0-3:X1-3:P2 C1-3:X2-3:P2 C2-3:X3:P2 \ . . . . . 0 A1:1|A2:2|A3:3 A1:P2|A2:P2|A3:P2 1-3" - " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ + " C0-3:X1-3:P2 C1-3:X2-3:P2 C2-3:X3:P2 \ . . X4 . . 0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3" - " C0-3:X1-3:S+:P2 C1-3:X2-3:S+:P2 C2-3:X3:P2 \ + " C0-3:X1-3:P2 C1-3:X2-3:P2 C2-3:X3:P2 \ . . C4:X . . 0 A1:1-3|A2:1-3|A3:2-3|XA2:|XA3: A1:P2|A2:P-2|A3:P-2 1-3" # Local partition CPU change tests - " C0-5:S+:P2 C4-5:S+:P1 . . . C3-5 . . 0 A1:0-2|A2:3-5 A1:P2|A2:P1 0-2" - " C0-5:S+:P2 C4-5:S+:P1 . . C1-5 . . . 0 A1:1-3|A2:4-5 A1:P2|A2:P1 1-3" + " C0-5:P2 C4-5:P1 . . . C3-5 . . 0 A1:0-2|A2:3-5 A1:P2|A2:P1 0-2" + " C0-5:P2 C4-5:P1 . . C1-5 . . . 0 A1:1-3|A2:4-5 A1:P2|A2:P1 1-3" # cpus_allowed/exclusive_cpus update tests - " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ + " C0-3:X2-3 C1-3:X2-3 C2-3:X2-3 \ . X:C4 . P2 . 0 A1:4|A2:4|XA2:|XA3:|A3:4 \ A1:P0|A3:P-2 ." - " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ + " C0-3:X2-3 C1-3:X2-3 C2-3:X2-3 \ . X1 . P2 . 0 A1:0-3|A2:1-3|XA1:1|XA2:|XA3:|A3:2-3 \ A1:P0|A3:P-2 ." - " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3 \ + " C0-3:X2-3 C1-3:X2-3 C2-3:X2-3 \ . . X3 P2 . 0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3 \ A1:P0|A3:P2 3" - " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \ + " C0-3:X2-3 C1-3:X2-3 C2-3:X2-3:P2 \ . . X3 . . 0 A1:0-2|A2:1-2|XA2:3|XA3:3|A3:3|XA3:3 \ A1:P0|A3:P2 3" - " C0-3:X2-3:S+ C1-3:X2-3:S+ C2-3:X2-3:P2 \ + " C0-3:X2-3 C1-3:X2-3 C2-3:X2-3:P2 \ . X4 . . . 0 A1:0-3|A2:1-3|A3:2-3|XA1:4|XA2:|XA3 \ A1:P0|A3:P-2" @@ -356,37 +356,37 @@ TEST_MATRIX=( # # Adding CPUs to partition root that are not in parent's # cpuset.cpus is allowed, but those extra CPUs are ignored. - "C2-3:P1:S+ C3:P1 . . . C2-4 . . 0 A1:|A2:2-3 A1:P1|A2:P1" + " C2-3:P1 C3:P1 . . . C2-4 . . 0 A1:|A2:2-3 A1:P1|A2:P1" # Taking away all CPUs from parent or itself if there are tasks # will make the partition invalid. - "C2-3:P1:S+ C3:P1 . . T C2-3 . . 0 A1:2-3|A2:2-3 A1:P1|A2:P-1" - " C3:P1:S+ C3 . . T P1 . . 0 A1:3|A2:3 A1:P1|A2:P-1" + " C2-3:P1 C3:P1 . . T C2-3 . . 0 A1:2-3|A2:2-3 A1:P1|A2:P-1" + " C3:P1 C3 . . T P1 . . 0 A1:3|A2:3 A1:P1|A2:P-1" "$SETUP_A123_PARTITIONS . T:C2-3 . . . 0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P-1|A3:P-1" "$SETUP_A123_PARTITIONS . T:C2-3:C1-3 . . . 0 A1:1|A2:2|A3:3 A1:P1|A2:P1|A3:P1" # Changing a partition root to member makes child partitions invalid - "C2-3:P1:S+ C3:P1 . . P0 . . . 0 A1:2-3|A2:3 A1:P0|A2:P-1" + " C2-3:P1 C3:P1 . . P0 . . . 0 A1:2-3|A2:3 A1:P0|A2:P-1" "$SETUP_A123_PARTITIONS . C2-3 P0 . . 0 A1:2-3|A2:2-3|A3:3 A1:P1|A2:P0|A3:P-1" # cpuset.cpus can contains cpus not in parent's cpuset.cpus as long # as they overlap. - "C2-3:P1:S+ . . . . C3-4:P1 . . 0 A1:2|A2:3 A1:P1|A2:P1" + " C2-3:P1 . . . . C3-4:P1 . . 0 A1:2|A2:3 A1:P1|A2:P1" # Deletion of CPUs distributed to child cgroup is allowed. - "C0-1:P1:S+ C1 . C2-3 C4-5 . . . 0 A1:4-5|A2:4-5" + " C0-1:P1 C1 . C2-3 C4-5 . . . 0 A1:4-5|A2:4-5" # To become a valid partition root, cpuset.cpus must overlap parent's # cpuset.cpus. - " C0-1:P1 . . C2-3 S+ C4-5:P1 . . 0 A1:0-1|A2:0-1 A1:P1|A2:P-1" + " C0-1:P1 . . C2-3 . C4-5:P1 . . 0 A1:0-1|A2:0-1 A1:P1|A2:P-1" # Enabling partition with child cpusets is allowed - " C0-1:S+ C1 . C2-3 P1 . . . 0 A1:0-1|A2:1 A1:P1" + " C0-1 C1 . C2-3 P1 . . . 0 A1:0-1|A2:1 A1:P1" # A partition root with non-partition root parent is invalid| but it # can be made valid if its parent becomes a partition root too. - " C0-1:S+ C1 . C2-3 . P2 . . 0 A1:0-1|A2:1 A1:P0|A2:P-2" - " C0-1:S+ C1:P2 . C2-3 P1 . . . 0 A1:0|A2:1 A1:P1|A2:P2 0-1|1" + " C0-1 C1 . C2-3 . P2 . . 0 A1:0-1|A2:1 A1:P0|A2:P-2" + " C0-1 C1:P2 . C2-3 P1 . . . 0 A1:0|A2:1 A1:P1|A2:P2 0-1|1" # A non-exclusive cpuset.cpus change will not invalidate its siblings partition. " C0-1:P1 . . C2-3 C0-2 . . . 0 A1:0-2|B1:3 A1:P1|B1:P0" @@ -398,23 +398,23 @@ TEST_MATRIX=( # Child partition root that try to take all CPUs from parent partition # with tasks will remain invalid. - " C1-4:P1:S+ P1 . . . . . . 0 A1:1-4|A2:1-4 A1:P1|A2:P-1" - " C1-4:P1:S+ P1 . . . C1-4 . . 0 A1|A2:1-4 A1:P1|A2:P1" - " C1-4:P1:S+ P1 . . T C1-4 . . 0 A1:1-4|A2:1-4 A1:P1|A2:P-1" + " C1-4:P1 P1 . . . . . . 0 A1:1-4|A2:1-4 A1:P1|A2:P-1" + " C1-4:P1 P1 . . . C1-4 . . 0 A1|A2:1-4 A1:P1|A2:P1" + " C1-4:P1 P1 . . T C1-4 . . 0 A1:1-4|A2:1-4 A1:P1|A2:P-1" # Clearing of cpuset.cpus with a preset cpuset.cpus.exclusive shouldn't # affect cpuset.cpus.exclusive.effective. - " C1-4:X3:S+ C1:X3 . . . C . . 0 A2:1-4|XA2:3" + " C1-4:X3 C1:X3 . . . C . . 0 A2:1-4|XA2:3" # cpuset.cpus can contain CPUs that overlap a sibling cpuset with cpus.exclusive # but creating a local partition out of it is not allowed. Similarly and change # in cpuset.cpus of a local partition that overlaps sibling exclusive CPUs will # invalidate it. - " CX1-4:S+ CX2-4:P2 . C5-6 . . . P1 0 A1:1|A2:2-4|B1:5-6|XB1:5-6 \ + " CX1-4 CX2-4:P2 . C5-6 . . . P1 0 A1:1|A2:2-4|B1:5-6|XB1:5-6 \ A1:P0|A2:P2:B1:P1 2-4" - " CX1-4:S+ CX2-4:P2 . C3-6 . . . P1 0 A1:1|A2:2-4|B1:5-6 \ + " CX1-4 CX2-4:P2 . C3-6 . . . P1 0 A1:1|A2:2-4|B1:5-6 \ A1:P0|A2:P2:B1:P-1 2-4" - " CX1-4:S+ CX2-4:P2 . C5-6 . . . P1:C3-6 0 A1:1|A2:2-4|B1:5-6 \ + " CX1-4 CX2-4:P2 . C5-6 . . . P1:C3-6 0 A1:1|A2:2-4|B1:5-6 \ A1:P0|A2:P2:B1:P-1 2-4" # When multiple partitions with conflicting cpuset.cpus are created, the @@ -426,14 +426,14 @@ TEST_MATRIX=( " C1-3:X1-3 . . C4-5 . . . C1-2 0 A1:1-3|B1:1-2" # cpuset.cpus can become empty with task in it as it inherits parent's effective CPUs - " C1-3:S+ C2 . . . T:C . . 0 A1:1-3|A2:1-3" + " C1-3 C2 . . . T:C . . 0 A1:1-3|A2:1-3" # old-A1 old-A2 old-A3 old-B1 new-A1 new-A2 new-A3 new-B1 fail ECPUs Pstate ISOLCPUS # ------ ------ ------ ------ ------ ------ ------ ------ ---- ----- ------ -------- # Failure cases: # A task cannot be added to a partition with no cpu - "C2-3:P1:S+ C3:P1 . . O2=0:T . . . 1 A1:|A2:3 A1:P1|A2:P1" + " C2-3:P1 C3:P1 . . O2=0:T . . . 1 A1:|A2:3 A1:P1|A2:P1" # Changes to cpuset.cpus.exclusive that violate exclusivity rule is rejected " C0-3 . . C4-5 X0-3 . . X3-5 1 A1:0-3|B1:4-5" @@ -465,31 +465,31 @@ REMOTE_TEST_MATRIX=( # old-p1 old-p2 old-c11 old-c12 old-c21 old-c22 # new-p1 new-p2 new-c11 new-c12 new-c21 new-c22 ECPUs Pstate ISOLCPUS # ------ ------ ------- ------- ------- ------- ----- ------ -------- - " X1-3:S+ X4-6:S+ X1-2 X3 X4-5 X6 \ + " X1-3 X4-6 X1-2 X3 X4-5 X6 \ . . P2 P2 P2 P2 c11:1-2|c12:3|c21:4-5|c22:6 \ c11:P2|c12:P2|c21:P2|c22:P2 1-6" - " CX1-4:S+ . X1-2:P2 C3 . . \ + " CX1-4 . X1-2:P2 C3 . . \ . . . C3-4 . . p1:3-4|c11:1-2|c12:3-4 \ p1:P0|c11:P2|c12:P0 1-2" - " CX1-4:S+ . X1-2:P2 . . . \ + " CX1-4 . X1-2:P2 . . . \ X2-4 . . . . . p1:1,3-4|c11:2 \ p1:P0|c11:P2 2" - " CX1-5:S+ . X1-2:P2 X3-5:P1 . . \ + " CX1-5 . X1-2:P2 X3-5:P1 . . \ X2-4 . . . . . p1:1,5|c11:2|c12:3-4 \ p1:P0|c11:P2|c12:P1 2" - " CX1-4:S+ . X1-2:P2 X3-4:P1 . . \ + " CX1-4 . X1-2:P2 X3-4:P1 . . \ . . X2 . . . p1:1|c11:2|c12:3-4 \ p1:P0|c11:P2|c12:P1 2" # p1 as member, will get its effective CPUs from its parent rtest - " CX1-4:S+ . X1-2:P2 X3-4:P1 . . \ + " CX1-4 . X1-2:P2 X3-4:P1 . . \ . . X1 CX2-4 . . p1:5-7|c11:1|c12:2-4 \ p1:P0|c11:P2|c12:P1 1" - " CX1-4:S+ X5-6:P1:S+ . . . . \ - . . X1-2:P2 X4-5:P1 . X1-7:P2 p1:3|c11:1-2|c12:4:c22:5-6 \ + " CX1-4 X5-6:P1 . . . . \ + . . X1-2:P2 X4-5:P1 . X1-7:P2 p1:3|c11:1-2|c12:4:c22:5-6 \ p1:P0|p2:P1|c11:P2|c12:P1|c22:P2 \ 1-2,4-6|1-2,5-6" # c12 whose cpuset.cpus CPUs are all granted to c11 will become invalid partition - " C1-5:P1:S+ . C1-4:P1 C2-3 . . \ + " C1-5:P1 . C1-4:P1 C2-3 . . \ . . . P1 . . p1:5|c11:1-4|c12:5 \ p1:P1|c11:P1|c12:P-1" ) @@ -530,7 +530,6 @@ set_ctrl_state() CGRP=$1 STATE=$2 SHOWERR=${3} - CTRL=${CTRL:=$CONTROLLER} HASERR=0 REDIRECT="2> $TMPMSG" [[ -z "$STATE" || "$STATE" = '.' ]] && return 0 @@ -540,15 +539,16 @@ set_ctrl_state() for CMD in $(echo $STATE | sed -e "s/:/ /g") do TFILE=$CGRP/cgroup.procs - SFILE=$CGRP/cgroup.subtree_control PFILE=$CGRP/cpuset.cpus.partition CFILE=$CGRP/cpuset.cpus XFILE=$CGRP/cpuset.cpus.exclusive - case $CMD in - S*) PREFIX=${CMD#?} - COMM="echo ${PREFIX}${CTRL} > $SFILE" + + # Enable cpuset controller if not enabled yet + [[ -f $CFILE ]] || { + COMM="echo +cpuset > $CGRP/../cgroup.subtree_control" eval $COMM $REDIRECT - ;; + } + case $CMD in X*) CPUS=${CMD#?} COMM="echo $CPUS > $XFILE" @@ -764,7 +764,7 @@ check_cgroup_states() # only CPUs in isolated partitions as well as those that are isolated at # boot time. # -# $1 - expected isolated cpu list(s) {,} +# $1 - expected isolated cpu list(s) {|} # - expected sched/domains value # - cpuset.cpus.isolated value = if not defined # @@ -773,6 +773,7 @@ check_isolcpus() EXPECTED_ISOLCPUS=$1 ISCPUS=${CGROUP2}/cpuset.cpus.isolated ISOLCPUS=$(cat $ISCPUS) + HKICPUS=$(cat /sys/devices/system/cpu/isolated) LASTISOLCPU= SCHED_DOMAINS=/sys/kernel/debug/sched/domains if [[ $EXPECTED_ISOLCPUS = . ]] @@ -810,6 +811,11 @@ check_isolcpus() ISOLCPUS= EXPECTED_ISOLCPUS=$EXPECTED_SDOMAIN + # + # The inverse of HK_TYPE_DOMAIN cpumask in $HKICPUS should match $ISOLCPUS + # + [[ "$ISOLCPUS" != "$HKICPUS" ]] && return 1 + # # Use the sched domain in debugfs to check isolated CPUs, if available # @@ -947,7 +953,6 @@ check_test_results() run_state_test() { TEST=$1 - CONTROLLER=cpuset CGROUP_LIST=". A1 A1/A2 A1/A2/A3 B1" RESET_LIST="A1/A2/A3 A1/A2 A1 B1" I=0 @@ -1003,7 +1008,6 @@ run_state_test() run_remote_state_test() { TEST=$1 - CONTROLLER=cpuset [[ -d rtest ]] || mkdir rtest cd rtest echo +cpuset > cgroup.subtree_control diff --git a/tools/testing/selftests/drivers/net/hw/devmem.py b/tools/testing/selftests/drivers/net/hw/devmem.py index 45c2d49d55b6..ee863e90d1e0 100755 --- a/tools/testing/selftests/drivers/net/hw/devmem.py +++ b/tools/testing/selftests/drivers/net/hw/devmem.py @@ -63,12 +63,29 @@ def check_tx_chunks(cfg) -> None: ksft_eq(socat.stdout.strip(), "hello\nworld") +def check_rx_hds(cfg) -> None: + """Test HDS splitting across payload sizes.""" + require_devmem(cfg) + + for size in [1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192]: + port = rand_port() + listen_cmd = f"{cfg.bin_local} -L -l -f {cfg.ifname} -s {cfg.addr} -p {port}" + + with bkg(listen_cmd, exit_wait=True) as ncdevmem: + wait_port_listen(port) + cmd(f"dd if=/dev/zero bs={size} count=1 2>/dev/null | " + + f"socat -b {size} -u - TCP{cfg.addr_ipver}:{cfg.baddr}:{port},nodelay", + host=cfg.remote, shell=True) + + ksft_eq(ncdevmem.ret, 0, f"HDS failed for payload size {size}") + + def main() -> None: with NetDrvEpEnv(__file__) as cfg: cfg.bin_local = path.abspath(path.dirname(__file__) + "/ncdevmem") cfg.bin_remote = cfg.remote.deploy(cfg.bin_local) - ksft_run([check_rx, check_tx, check_tx_chunks], + ksft_run([check_rx, check_tx, check_tx_chunks, check_rx_hds], args=(cfg, )) ksft_exit() diff --git a/tools/testing/selftests/drivers/net/hw/ncdevmem.c b/tools/testing/selftests/drivers/net/hw/ncdevmem.c index 16864c844108..e098d6534c3c 100644 --- a/tools/testing/selftests/drivers/net/hw/ncdevmem.c +++ b/tools/testing/selftests/drivers/net/hw/ncdevmem.c @@ -98,6 +98,7 @@ static unsigned int ifindex; static unsigned int dmabuf_id; static uint32_t tx_dmabuf_id; static int waittime_ms = 500; +static bool fail_on_linear; /* System state loaded by current_config_load() */ #define MAX_FLOWS 8 @@ -975,6 +976,11 @@ static int do_server(struct memory_buffer *mem) "SCM_DEVMEM_LINEAR. dmabuf_cmsg->frag_size=%u\n", dmabuf_cmsg->frag_size); + if (fail_on_linear) { + pr_err("received SCM_DEVMEM_LINEAR but --fail-on-linear (-L) set"); + goto err_close_client; + } + continue; } @@ -1398,8 +1404,11 @@ int main(int argc, char *argv[]) int is_server = 0, opt; int ret, err = 1; - while ((opt = getopt(argc, argv, "ls:c:p:v:q:t:f:z:")) != -1) { + while ((opt = getopt(argc, argv, "Lls:c:p:v:q:t:f:z:")) != -1) { switch (opt) { + case 'L': + fail_on_linear = true; + break; case 'l': is_server = 1; break; diff --git a/tools/testing/selftests/drivers/net/hw/rss_ctx.py b/tools/testing/selftests/drivers/net/hw/rss_ctx.py index ed7e405682f0..b9b7527c2c6b 100755 --- a/tools/testing/selftests/drivers/net/hw/rss_ctx.py +++ b/tools/testing/selftests/drivers/net/hw/rss_ctx.py @@ -4,13 +4,15 @@ import datetime import random import re +import time from lib.py import ksft_run, ksft_pr, ksft_exit from lib.py import ksft_eq, ksft_ne, ksft_ge, ksft_in, ksft_lt, ksft_true, ksft_raises from lib.py import NetDrvEpEnv from lib.py import EthtoolFamily, NetdevFamily from lib.py import KsftSkipEx, KsftFailEx +from lib.py import ksft_disruptive from lib.py import rand_port -from lib.py import ethtool, ip, defer, GenerateTraffic, CmdExitFailure +from lib.py import cmd, ethtool, ip, defer, GenerateTraffic, CmdExitFailure, wait_file def _rss_key_str(key): @@ -809,6 +811,98 @@ def test_rss_default_context_rule(cfg): 'noise' : (0, 1) }) +@ksft_disruptive +def test_rss_context_persist_ifupdown(cfg, pre_down=False): + """ + Test that RSS contexts and their associated ntuple filters persist across + an interface down/up cycle. + + """ + + require_ntuple(cfg) + + qcnt = len(_get_rx_cnts(cfg)) + if qcnt < 6: + try: + ethtool(f"-L {cfg.ifname} combined 6") + defer(ethtool, f"-L {cfg.ifname} combined {qcnt}") + except Exception as exc: + raise KsftSkipEx("Not enough queues for the test") from exc + + ethtool(f"-X {cfg.ifname} equal 2") + defer(ethtool, f"-X {cfg.ifname} default") + + ifup = defer(ip, f"link set dev {cfg.ifname} up") + if pre_down: + ip(f"link set dev {cfg.ifname} down") + + try: + ctx1_id = ethtool_create(cfg, "-X", "context new start 2 equal 2") + defer(ethtool, f"-X {cfg.ifname} context {ctx1_id} delete") + except CmdExitFailure as exc: + raise KsftSkipEx("Create context not supported with interface down") from exc + + ctx2_id = ethtool_create(cfg, "-X", "context new start 4 equal 2") + defer(ethtool, f"-X {cfg.ifname} context {ctx2_id} delete") + + port_ctx2 = rand_port() + flow = f"flow-type tcp{cfg.addr_ipver} dst-ip {cfg.addr} dst-port {port_ctx2} context {ctx2_id}" + ntuple_id = ethtool_create(cfg, "-N", flow) + defer(ethtool, f"-N {cfg.ifname} delete {ntuple_id}") + + if not pre_down: + ip(f"link set dev {cfg.ifname} down") + ifup.exec() + + wait_file(f"/sys/class/net/{cfg.ifname}/carrier", + lambda x: x.strip() == "1", deadline=20) + + remote_addr = cfg.remote_addr_v[cfg.addr_ipver] + for _ in range(10): + if cmd(f"ping -c 1 -W 1 {remote_addr}", fail=False).ret == 0: + break + time.sleep(1) + else: + raise KsftSkipEx("Cannot reach remote host after interface up") + + ctxs = cfg.ethnl.rss_get({'header': {'dev-name': cfg.ifname}}, dump=True) + + data1 = [c for c in ctxs if c.get('context') == ctx1_id] + ksft_eq(len(data1), 1, f"Context {ctx1_id} should persist after ifup") + + data2 = [c for c in ctxs if c.get('context') == ctx2_id] + ksft_eq(len(data2), 1, f"Context {ctx2_id} should persist after ifup") + + _ntuple_rule_check(cfg, ntuple_id, ctx2_id) + + cnts = _get_rx_cnts(cfg) + GenerateTraffic(cfg).wait_pkts_and_stop(20000) + cnts = _get_rx_cnts(cfg, prev=cnts) + + main_traffic = sum(cnts[0:2]) + ksft_ge(main_traffic, 18000, f"Main context traffic distribution: {cnts}") + ksft_lt(sum(cnts[2:6]), 500, f"Other context queues should be mostly empty: {cnts}") + + _send_traffic_check(cfg, port_ctx2, f"context {ctx2_id}", + {'target': (4, 5), + 'noise': (0, 1), + 'empty': (2, 3)}) + + +def test_rss_context_persist_create_and_ifdown(cfg): + """ + Create RSS contexts then cycle the interface down and up. + """ + test_rss_context_persist_ifupdown(cfg, pre_down=False) + + +def test_rss_context_persist_ifdown_and_create(cfg): + """ + Bring interface down first, then create RSS contexts and bring up. + """ + test_rss_context_persist_ifupdown(cfg, pre_down=True) + + def main() -> None: with NetDrvEpEnv(__file__, nsim_test=False) as cfg: cfg.context_cnt = None @@ -823,7 +917,9 @@ def main() -> None: test_rss_context_out_of_order, test_rss_context4_create_with_cfg, test_flow_add_context_missing, test_delete_rss_context_busy, test_rss_ntuple_addition, - test_rss_default_context_rule], + test_rss_default_context_rule, + test_rss_context_persist_create_and_ifdown, + test_rss_context_persist_ifdown_and_create], args=(cfg, )) ksft_exit() diff --git a/tools/testing/selftests/drivers/net/hw/toeplitz.py b/tools/testing/selftests/drivers/net/hw/toeplitz.py index d288c57894f6..cd7e080e6f84 100755 --- a/tools/testing/selftests/drivers/net/hw/toeplitz.py +++ b/tools/testing/selftests/drivers/net/hw/toeplitz.py @@ -19,6 +19,8 @@ from lib.py import ksft_variants, KsftNamedVariant, KsftSkipEx, KsftFailEx # "define" for the ID of the Toeplitz hash function ETH_RSS_HASH_TOP = 1 +# Must match RPS_MAX_CPUS in toeplitz.c +RPS_MAX_CPUS = 16 def _check_rps_and_rfs_not_configured(cfg): @@ -67,23 +69,24 @@ def _get_irq_cpus(cfg): return cpus -def _get_unused_cpus(cfg, count=2): +def _get_unused_rps_cpus(cfg, count=2): """ - Get CPUs that are not used by Rx queues. - Returns a list of at least 'count' CPU numbers. + Get CPUs that are not used by Rx queues for RPS. + Returns a list of at least 'count' CPU numbers within + the RPS_MAX_CPUS supported range. """ # Get CPUs used by Rx queues rx_cpus = set(_get_irq_cpus(cfg)) - # Get total number of CPUs - num_cpus = os.cpu_count() + # Get total number of CPUs, capped by RPS_MAX_CPUS + num_cpus = min(os.cpu_count(), RPS_MAX_CPUS) # Find unused CPUs unused_cpus = [cpu for cpu in range(num_cpus) if cpu not in rx_cpus] if len(unused_cpus) < count: - raise KsftSkipEx(f"Need at {count} CPUs not used by Rx queues, found {len(unused_cpus)}") + raise KsftSkipEx(f"Need at least {count} CPUs in range 0..{num_cpus - 1} not used by Rx queues, found {len(unused_cpus)}") return unused_cpus[:count] @@ -181,7 +184,7 @@ def test(cfg, proto_flag, ipver, grp): ksft_pr(f"RSS using CPUs: {irq_cpus}") elif grp == "rps": # Get CPUs not used by Rx queues and configure them for RPS - rps_cpus = _get_unused_cpus(cfg, count=2) + rps_cpus = _get_unused_rps_cpus(cfg, count=2) rps_mask = _configure_rps(cfg, rps_cpus) defer(_configure_rps, cfg, []) rx_cmd += ["-r", rps_mask] diff --git a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh index b6093bcf2b06..02dcdeb723be 100644 --- a/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh +++ b/tools/testing/selftests/drivers/net/lib/sh/lib_netcons.sh @@ -249,8 +249,8 @@ function listen_port_and_save_to() { SOCAT_MODE="UDP6-LISTEN" fi - # Just wait for 2 seconds - timeout 2 ip netns exec "${NAMESPACE}" \ + # Just wait for 3 seconds + timeout 3 ip netns exec "${NAMESPACE}" \ socat "${SOCAT_MODE}":"${PORT}",fork "${OUTPUT}" 2> /dev/null } diff --git a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh index 0441a18f098b..aac8ef490feb 100755 --- a/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh +++ b/tools/testing/selftests/drivers/net/mlxsw/tc_restrictions.sh @@ -317,7 +317,7 @@ police_limits_test() tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ flower skip_sw \ - action police rate 0.5kbit burst 1m conform-exceed drop/ok + action police rate 0.5kbit burst 2k conform-exceed drop/ok check_fail $? "Incorrect success to add police action with too low rate" tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ @@ -327,7 +327,7 @@ police_limits_test() tc filter add dev $swp1 ingress pref 1 proto ip handle 101 \ flower skip_sw \ - action police rate 1.5kbit burst 1m conform-exceed drop/ok + action police rate 1.5kbit burst 2k conform-exceed drop/ok check_err $? "Failed to add police action with low rate" tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower diff --git a/tools/testing/selftests/drivers/net/team/Makefile b/tools/testing/selftests/drivers/net/team/Makefile index 1340b3df9c31..45a3e7ad3dcb 100644 --- a/tools/testing/selftests/drivers/net/team/Makefile +++ b/tools/testing/selftests/drivers/net/team/Makefile @@ -5,6 +5,7 @@ TEST_PROGS := \ dev_addr_lists.sh \ options.sh \ propagation.sh \ + refleak.sh \ # end of TEST_PROGS TEST_INCLUDES := \ diff --git a/tools/testing/selftests/drivers/net/team/refleak.sh b/tools/testing/selftests/drivers/net/team/refleak.sh new file mode 100755 index 000000000000..ef08213ab964 --- /dev/null +++ b/tools/testing/selftests/drivers/net/team/refleak.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# shellcheck disable=SC2154 + +lib_dir=$(dirname "$0") +source "$lib_dir"/../../../net/lib.sh + +trap cleanup_all_ns EXIT + +# Test that there is no reference count leak and that dummy1 can be deleted. +# https://lore.kernel.org/netdev/4d69abe1-ca8d-4f0b-bcf8-13899b211e57@I-love.SAKURA.ne.jp/ +setup_ns ns1 ns2 +ip -n "$ns1" link add name team1 type team +ip -n "$ns1" link add name dummy1 mtu 1499 type dummy +ip -n "$ns1" link set dev dummy1 master team1 +ip -n "$ns1" link set dev dummy1 netns "$ns2" +ip -n "$ns2" link del dev dummy1 diff --git a/tools/testing/selftests/filesystems/nsfs/iterate_mntns.c b/tools/testing/selftests/filesystems/nsfs/iterate_mntns.c index 61e55dfbf121..e19ff8168baf 100644 --- a/tools/testing/selftests/filesystems/nsfs/iterate_mntns.c +++ b/tools/testing/selftests/filesystems/nsfs/iterate_mntns.c @@ -37,17 +37,20 @@ FIXTURE(iterate_mount_namespaces) { __u64 mnt_ns_id[MNT_NS_COUNT]; }; +static inline bool mntns_in_list(__u64 *mnt_ns_id, struct mnt_ns_info *info) +{ + for (int i = 0; i < MNT_NS_COUNT; i++) { + if (mnt_ns_id[i] == info->mnt_ns_id) + return true; + } + return false; +} + FIXTURE_SETUP(iterate_mount_namespaces) { for (int i = 0; i < MNT_NS_COUNT; i++) self->fd_mnt_ns[i] = -EBADF; - /* - * Creating a new user namespace let's us guarantee that we only see - * mount namespaces that we did actually create. - */ - ASSERT_EQ(unshare(CLONE_NEWUSER), 0); - for (int i = 0; i < MNT_NS_COUNT; i++) { struct mnt_ns_info info = {}; @@ -75,13 +78,15 @@ TEST_F(iterate_mount_namespaces, iterate_all_forward) fd_mnt_ns_cur = fcntl(self->fd_mnt_ns[0], F_DUPFD_CLOEXEC); ASSERT_GE(fd_mnt_ns_cur, 0); - for (;; count++) { + for (;;) { struct mnt_ns_info info = {}; int fd_mnt_ns_next; fd_mnt_ns_next = ioctl(fd_mnt_ns_cur, NS_MNT_GET_NEXT, &info); if (fd_mnt_ns_next < 0 && errno == ENOENT) break; + if (mntns_in_list(self->mnt_ns_id, &info)) + count++; ASSERT_GE(fd_mnt_ns_next, 0); ASSERT_EQ(close(fd_mnt_ns_cur), 0); fd_mnt_ns_cur = fd_mnt_ns_next; @@ -96,13 +101,15 @@ TEST_F(iterate_mount_namespaces, iterate_all_backwards) fd_mnt_ns_cur = fcntl(self->fd_mnt_ns[MNT_NS_LAST_INDEX], F_DUPFD_CLOEXEC); ASSERT_GE(fd_mnt_ns_cur, 0); - for (;; count++) { + for (;;) { struct mnt_ns_info info = {}; int fd_mnt_ns_prev; fd_mnt_ns_prev = ioctl(fd_mnt_ns_cur, NS_MNT_GET_PREV, &info); if (fd_mnt_ns_prev < 0 && errno == ENOENT) break; + if (mntns_in_list(self->mnt_ns_id, &info)) + count++; ASSERT_GE(fd_mnt_ns_prev, 0); ASSERT_EQ(close(fd_mnt_ns_cur), 0); fd_mnt_ns_cur = fd_mnt_ns_prev; @@ -125,7 +132,6 @@ TEST_F(iterate_mount_namespaces, iterate_forward) ASSERT_GE(fd_mnt_ns_next, 0); ASSERT_EQ(close(fd_mnt_ns_cur), 0); fd_mnt_ns_cur = fd_mnt_ns_next; - ASSERT_EQ(info.mnt_ns_id, self->mnt_ns_id[i]); } } @@ -144,7 +150,6 @@ TEST_F(iterate_mount_namespaces, iterate_backward) ASSERT_GE(fd_mnt_ns_prev, 0); ASSERT_EQ(close(fd_mnt_ns_cur), 0); fd_mnt_ns_cur = fd_mnt_ns_prev; - ASSERT_EQ(info.mnt_ns_id, self->mnt_ns_id[i]); } } diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index 16a119a4656c..4afaef01c22e 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -76,6 +76,9 @@ static inline void __kselftest_memset_safe(void *s, int c, size_t n) memset(s, c, n); } +#define KSELFTEST_PRIO_TEST_F 20000 +#define KSELFTEST_PRIO_XFAIL 20001 + #define TEST_TIMEOUT_DEFAULT 30 /* Utilities exposed to the test definitions */ @@ -465,7 +468,7 @@ static inline void __kselftest_memset_safe(void *s, int c, size_t n) fixture_name##_teardown(_metadata, self, variant); \ } \ static struct __test_metadata *_##fixture_name##_##test_name##_object; \ - static void __attribute__((constructor)) \ + static void __attribute__((constructor(KSELFTEST_PRIO_TEST_F))) \ _register_##fixture_name##_##test_name(void) \ { \ struct __test_metadata *object = mmap(NULL, sizeof(*object), \ @@ -880,7 +883,7 @@ struct __test_xfail { .fixture = &_##fixture_name##_fixture_object, \ .variant = &_##fixture_name##_##variant_name##_object, \ }; \ - static void __attribute__((constructor)) \ + static void __attribute__((constructor(KSELFTEST_PRIO_XFAIL))) \ _register_##fixture_name##_##variant_name##_##test_name##_xfail(void) \ { \ _##fixture_name##_##variant_name##_##test_name##_xfail.test = \ diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index fdec90e85467..dc68371f76a3 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -71,6 +71,7 @@ TEST_GEN_PROGS_x86 += x86/cpuid_test TEST_GEN_PROGS_x86 += x86/cr4_cpuid_sync_test TEST_GEN_PROGS_x86 += x86/dirty_log_page_splitting_test TEST_GEN_PROGS_x86 += x86/feature_msrs_test +TEST_GEN_PROGS_x86 += x86/evmcs_smm_controls_test TEST_GEN_PROGS_x86 += x86/exit_on_emulation_failure_test TEST_GEN_PROGS_x86 += x86/fastops_test TEST_GEN_PROGS_x86 += x86/fix_hypercall_test diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c index 618c937f3c90..cc329b57ce2e 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -80,7 +80,7 @@ static void test_mbind(int fd, size_t total_size) { const unsigned long nodemask_0 = 1; /* nid: 0 */ unsigned long nodemask = 0; - unsigned long maxnode = 8; + unsigned long maxnode = BITS_PER_TYPE(nodemask); int policy; char *mem; int ret; diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h index 4ebae4269e68..469a22122157 100644 --- a/tools/testing/selftests/kvm/include/x86/processor.h +++ b/tools/testing/selftests/kvm/include/x86/processor.h @@ -557,6 +557,11 @@ static inline uint64_t get_cr0(void) return cr0; } +static inline void set_cr0(uint64_t val) +{ + __asm__ __volatile__("mov %0, %%cr0" : : "r" (val) : "memory"); +} + static inline uint64_t get_cr3(void) { uint64_t cr3; @@ -566,6 +571,11 @@ static inline uint64_t get_cr3(void) return cr3; } +static inline void set_cr3(uint64_t val) +{ + __asm__ __volatile__("mov %0, %%cr3" : : "r" (val) : "memory"); +} + static inline uint64_t get_cr4(void) { uint64_t cr4; @@ -580,6 +590,19 @@ static inline void set_cr4(uint64_t val) __asm__ __volatile__("mov %0, %%cr4" : : "r" (val) : "memory"); } +static inline uint64_t get_cr8(void) +{ + uint64_t cr8; + + __asm__ __volatile__("mov %%cr8, %[cr8]" : [cr8]"=r"(cr8)); + return cr8; +} + +static inline void set_cr8(uint64_t val) +{ + __asm__ __volatile__("mov %0, %%cr8" : : "r" (val) : "memory"); +} + static inline void set_idt(const struct desc_ptr *idt_desc) { __asm__ __volatile__("lidt %0"::"m"(*idt_desc)); diff --git a/tools/testing/selftests/kvm/include/x86/smm.h b/tools/testing/selftests/kvm/include/x86/smm.h new file mode 100644 index 000000000000..19337c34f13e --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/smm.h @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-2.0-only +#ifndef SELFTEST_KVM_SMM_H +#define SELFTEST_KVM_SMM_H + +#include "kvm_util.h" + +#define SMRAM_SIZE 65536 +#define SMRAM_MEMSLOT ((1 << 16) | 1) +#define SMRAM_PAGES (SMRAM_SIZE / PAGE_SIZE) + +void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, + uint64_t smram_gpa, + const void *smi_handler, size_t handler_size); + +void inject_smi(struct kvm_vcpu *vcpu); + +#endif /* SELFTEST_KVM_SMM_H */ diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c index fab18e9be66c..23a44941e283 100644 --- a/tools/testing/selftests/kvm/lib/x86/processor.c +++ b/tools/testing/selftests/kvm/lib/x86/processor.c @@ -8,6 +8,7 @@ #include "kvm_util.h" #include "pmu.h" #include "processor.h" +#include "smm.h" #include "svm_util.h" #include "sev.h" #include "vmx.h" @@ -1444,3 +1445,28 @@ bool kvm_arch_has_default_irqchip(void) { return true; } + +void setup_smram(struct kvm_vm *vm, struct kvm_vcpu *vcpu, + uint64_t smram_gpa, + const void *smi_handler, size_t handler_size) +{ + vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, smram_gpa, + SMRAM_MEMSLOT, SMRAM_PAGES, 0); + TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, smram_gpa, + SMRAM_MEMSLOT) == smram_gpa, + "Could not allocate guest physical addresses for SMRAM"); + + memset(addr_gpa2hva(vm, smram_gpa), 0x0, SMRAM_SIZE); + memcpy(addr_gpa2hva(vm, smram_gpa) + 0x8000, smi_handler, handler_size); + vcpu_set_msr(vcpu, MSR_IA32_SMBASE, smram_gpa); +} + +void inject_smi(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_events events; + + vcpu_events_get(vcpu, &events); + events.smi.pending = 1; + events.flags |= KVM_VCPUEVENT_VALID_SMM; + vcpu_events_set(vcpu, &events); +} diff --git a/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c new file mode 100644 index 000000000000..af7c90103396 --- /dev/null +++ b/tools/testing/selftests/kvm/x86/evmcs_smm_controls_test.c @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026, Red Hat, Inc. + * + * Test that vmx_leave_smm() validates vmcs12 controls before re-entering + * nested guest mode on RSM. + */ +#include +#include +#include +#include +#include + +#include "test_util.h" +#include "kvm_util.h" +#include "smm.h" +#include "hyperv.h" +#include "vmx.h" + +#define SMRAM_GPA 0x1000000 +#define SMRAM_STAGE 0xfe + +#define SYNC_PORT 0xe + +#define STR(x) #x +#define XSTR(s) STR(s) + +/* + * SMI handler: runs in real-address mode. + * Reports SMRAM_STAGE via port IO, then does RSM. + */ +static uint8_t smi_handler[] = { + 0xb0, SMRAM_STAGE, /* mov $SMRAM_STAGE, %al */ + 0xe4, SYNC_PORT, /* in $SYNC_PORT, %al */ + 0x0f, 0xaa, /* rsm */ +}; + +static inline void sync_with_host(uint64_t phase) +{ + asm volatile("in $" XSTR(SYNC_PORT) ", %%al \n" + : "+a" (phase)); +} + +static void l2_guest_code(void) +{ + sync_with_host(1); + + /* After SMI+RSM with invalid controls, we should not reach here. */ + vmcall(); +} + +static void guest_code(struct vmx_pages *vmx_pages, + struct hyperv_test_pages *hv_pages) +{ +#define L2_GUEST_STACK_SIZE 64 + unsigned long l2_guest_stack[L2_GUEST_STACK_SIZE]; + + /* Set up Hyper-V enlightenments and eVMCS */ + wrmsr(HV_X64_MSR_GUEST_OS_ID, HYPERV_LINUX_OS_ID); + enable_vp_assist(hv_pages->vp_assist_gpa, hv_pages->vp_assist); + evmcs_enable(); + + GUEST_ASSERT(prepare_for_vmx_operation(vmx_pages)); + GUEST_ASSERT(load_evmcs(hv_pages)); + prepare_vmcs(vmx_pages, l2_guest_code, + &l2_guest_stack[L2_GUEST_STACK_SIZE]); + + GUEST_ASSERT(!vmlaunch()); + + /* L2 exits via vmcall if test fails */ + sync_with_host(2); +} + +int main(int argc, char *argv[]) +{ + vm_vaddr_t vmx_pages_gva = 0, hv_pages_gva = 0; + struct hyperv_test_pages *hv; + struct hv_enlightened_vmcs *evmcs; + struct kvm_vcpu *vcpu; + struct kvm_vm *vm; + struct kvm_regs regs; + int stage_reported; + + TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_VMX)); + TEST_REQUIRE(kvm_has_cap(KVM_CAP_NESTED_STATE)); + TEST_REQUIRE(kvm_has_cap(KVM_CAP_HYPERV_ENLIGHTENED_VMCS)); + TEST_REQUIRE(kvm_has_cap(KVM_CAP_X86_SMM)); + + vm = vm_create_with_one_vcpu(&vcpu, guest_code); + + setup_smram(vm, vcpu, SMRAM_GPA, smi_handler, sizeof(smi_handler)); + + vcpu_set_hv_cpuid(vcpu); + vcpu_enable_evmcs(vcpu); + vcpu_alloc_vmx(vm, &vmx_pages_gva); + hv = vcpu_alloc_hyperv_test_pages(vm, &hv_pages_gva); + vcpu_args_set(vcpu, 2, vmx_pages_gva, hv_pages_gva); + + vcpu_run(vcpu); + + /* L2 is running and syncs with host. */ + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + vcpu_regs_get(vcpu, ®s); + stage_reported = regs.rax & 0xff; + TEST_ASSERT(stage_reported == 1, + "Expected stage 1, got %d", stage_reported); + + /* Inject SMI while L2 is running. */ + inject_smi(vcpu); + vcpu_run(vcpu); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO); + vcpu_regs_get(vcpu, ®s); + stage_reported = regs.rax & 0xff; + TEST_ASSERT(stage_reported == SMRAM_STAGE, + "Expected SMM handler stage %#x, got %#x", + SMRAM_STAGE, stage_reported); + + /* + * Guest is now paused in the SMI handler, about to execute RSM. + * Hack the eVMCS page to set-up invalid pin-based execution + * control (PIN_BASED_VIRTUAL_NMIS without PIN_BASED_NMI_EXITING). + */ + evmcs = hv->enlightened_vmcs_hva; + evmcs->pin_based_vm_exec_control |= PIN_BASED_VIRTUAL_NMIS; + evmcs->hv_clean_fields = 0; + + /* + * Trigger copy_enlightened_to_vmcs12() via KVM_GET_NESTED_STATE, + * copying the invalid pin_based_vm_exec_control into cached_vmcs12. + */ + union { + struct kvm_nested_state state; + char state_[16384]; + } nested_state_buf; + + memset(&nested_state_buf, 0, sizeof(nested_state_buf)); + nested_state_buf.state.size = sizeof(nested_state_buf); + vcpu_nested_state_get(vcpu, &nested_state_buf.state); + + /* + * Resume the guest. The SMI handler executes RSM, which calls + * vmx_leave_smm(). nested_vmx_check_controls() should detect + * VIRTUAL_NMIS without NMI_EXITING and cause a triple fault. + */ + vcpu_run(vcpu); + TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_SHUTDOWN); + + kvm_vm_free(vm); + return 0; +} diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c index 86ad1c7d068f..8bd37a476f15 100644 --- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c +++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c @@ -13,6 +13,30 @@ #include "linux/psp-sev.h" #include "sev.h" +static void guest_sev_test_msr(uint32_t msr) +{ + uint64_t val = rdmsr(msr); + + wrmsr(msr, val); + GUEST_ASSERT(val == rdmsr(msr)); +} + +#define guest_sev_test_reg(reg) \ +do { \ + uint64_t val = get_##reg(); \ + \ + set_##reg(val); \ + GUEST_ASSERT(val == get_##reg()); \ +} while (0) + +static void guest_sev_test_regs(void) +{ + guest_sev_test_msr(MSR_EFER); + guest_sev_test_reg(cr0); + guest_sev_test_reg(cr3); + guest_sev_test_reg(cr4); + guest_sev_test_reg(cr8); +} #define XFEATURE_MASK_X87_AVX (XFEATURE_MASK_FP | XFEATURE_MASK_SSE | XFEATURE_MASK_YMM) @@ -24,6 +48,8 @@ static void guest_snp_code(void) GUEST_ASSERT(sev_msr & MSR_AMD64_SEV_ES_ENABLED); GUEST_ASSERT(sev_msr & MSR_AMD64_SEV_SNP_ENABLED); + guest_sev_test_regs(); + wrmsr(MSR_AMD64_SEV_ES_GHCB, GHCB_MSR_TERM_REQ); vmgexit(); } @@ -34,6 +60,8 @@ static void guest_sev_es_code(void) GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED); GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ES_ENABLED); + guest_sev_test_regs(); + /* * TODO: Add GHCB and ucall support for SEV-ES guests. For now, simply * force "termination" to signal "done" via the GHCB MSR protocol. @@ -47,6 +75,8 @@ static void guest_sev_code(void) GUEST_ASSERT(this_cpu_has(X86_FEATURE_SEV)); GUEST_ASSERT(rdmsr(MSR_AMD64_SEV) & MSR_AMD64_SEV_ENABLED); + guest_sev_test_regs(); + GUEST_DONE(); } diff --git a/tools/testing/selftests/kvm/x86/smm_test.c b/tools/testing/selftests/kvm/x86/smm_test.c index 55c88d664a94..ade8412bf94a 100644 --- a/tools/testing/selftests/kvm/x86/smm_test.c +++ b/tools/testing/selftests/kvm/x86/smm_test.c @@ -14,13 +14,11 @@ #include "test_util.h" #include "kvm_util.h" +#include "smm.h" #include "vmx.h" #include "svm_util.h" -#define SMRAM_SIZE 65536 -#define SMRAM_MEMSLOT ((1 << 16) | 1) -#define SMRAM_PAGES (SMRAM_SIZE / PAGE_SIZE) #define SMRAM_GPA 0x1000000 #define SMRAM_STAGE 0xfe @@ -113,18 +111,6 @@ static void guest_code(void *arg) sync_with_host(DONE); } -void inject_smi(struct kvm_vcpu *vcpu) -{ - struct kvm_vcpu_events events; - - vcpu_events_get(vcpu, &events); - - events.smi.pending = 1; - events.flags |= KVM_VCPUEVENT_VALID_SMM; - - vcpu_events_set(vcpu, &events); -} - int main(int argc, char *argv[]) { vm_vaddr_t nested_gva = 0; @@ -140,16 +126,7 @@ int main(int argc, char *argv[]) /* Create VM */ vm = vm_create_with_one_vcpu(&vcpu, guest_code); - vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS, SMRAM_GPA, - SMRAM_MEMSLOT, SMRAM_PAGES, 0); - TEST_ASSERT(vm_phy_pages_alloc(vm, SMRAM_PAGES, SMRAM_GPA, SMRAM_MEMSLOT) - == SMRAM_GPA, "could not allocate guest physical addresses?"); - - memset(addr_gpa2hva(vm, SMRAM_GPA), 0x0, SMRAM_SIZE); - memcpy(addr_gpa2hva(vm, SMRAM_GPA) + 0x8000, smi_handler, - sizeof(smi_handler)); - - vcpu_set_msr(vcpu, MSR_IA32_SMBASE, SMRAM_GPA); + setup_smram(vm, vcpu, SMRAM_GPA, smi_handler, sizeof(smi_handler)); if (kvm_has_cap(KVM_CAP_NESTED_STATE)) { if (kvm_cpu_has(X86_FEATURE_SVM)) diff --git a/tools/testing/selftests/memfd/memfd_test.c b/tools/testing/selftests/memfd/memfd_test.c index 5b993924cc3f..2ca07ea7202a 100644 --- a/tools/testing/selftests/memfd/memfd_test.c +++ b/tools/testing/selftests/memfd/memfd_test.c @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include #include #include @@ -39,6 +42,20 @@ F_SEAL_EXEC) #define MFD_NOEXEC_SEAL 0x0008U +union semun { + int val; + struct semid_ds *buf; + unsigned short int *array; + struct seminfo *__buf; +}; + +/* + * we use semaphores on nested wait tasks due the use of CLONE_NEWPID: the + * child will be PID 1 and can't send SIGSTOP to themselves due special + * treatment of the init task, so the SIGSTOP/SIGCONT synchronization + * approach can't be used here. + */ +#define SEM_KEY 0xdeadbeef /* * Default is not to test hugetlbfs @@ -1333,8 +1350,22 @@ static int sysctl_nested(void *arg) static int sysctl_nested_wait(void *arg) { - /* Wait for a SIGCONT. */ - kill(getpid(), SIGSTOP); + int sem = semget(SEM_KEY, 1, 0600); + struct sembuf sembuf; + + if (sem < 0) { + perror("semget:"); + abort(); + } + sembuf.sem_num = 0; + sembuf.sem_flg = 0; + sembuf.sem_op = 0; + + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + abort(); + } + return sysctl_nested(arg); } @@ -1355,7 +1386,9 @@ static void test_sysctl_sysctl2_failset(void) static int sysctl_nested_child(void *arg) { - int pid; + int pid, sem; + union semun semun; + struct sembuf sembuf; printf("%s nested sysctl 0\n", memfd_str); sysctl_assert_write("0"); @@ -1389,23 +1422,53 @@ static int sysctl_nested_child(void *arg) test_sysctl_sysctl2_failset); join_thread(pid); + sem = semget(SEM_KEY, 1, IPC_CREAT | 0600); + if (sem < 0) { + perror("semget:"); + return 1; + } + semun.val = 1; + sembuf.sem_op = -1; + sembuf.sem_flg = 0; + sembuf.sem_num = 0; + /* Verify that the rules are actually inherited after fork. */ printf("%s nested sysctl 0 -> 1 after fork\n", memfd_str); sysctl_assert_write("0"); + if (semctl(sem, 0, SETVAL, semun) < 0) { + perror("semctl:"); + return 1; + } + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, test_sysctl_sysctl1_failset); sysctl_assert_write("1"); - kill(pid, SIGCONT); + + /* Allow child to continue */ + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + return 1; + } join_thread(pid); printf("%s nested sysctl 0 -> 2 after fork\n", memfd_str); sysctl_assert_write("0"); + if (semctl(sem, 0, SETVAL, semun) < 0) { + perror("semctl:"); + return 1; + } + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, test_sysctl_sysctl2_failset); sysctl_assert_write("2"); - kill(pid, SIGCONT); + + /* Allow child to continue */ + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + return 1; + } join_thread(pid); /* @@ -1415,28 +1478,62 @@ static int sysctl_nested_child(void *arg) */ printf("%s nested sysctl 2 -> 1 after fork\n", memfd_str); sysctl_assert_write("2"); + + if (semctl(sem, 0, SETVAL, semun) < 0) { + perror("semctl:"); + return 1; + } + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, test_sysctl_sysctl2); sysctl_assert_write("1"); - kill(pid, SIGCONT); + + /* Allow child to continue */ + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + return 1; + } join_thread(pid); printf("%s nested sysctl 2 -> 0 after fork\n", memfd_str); sysctl_assert_write("2"); + + if (semctl(sem, 0, SETVAL, semun) < 0) { + perror("semctl:"); + return 1; + } + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, test_sysctl_sysctl2); sysctl_assert_write("0"); - kill(pid, SIGCONT); + + /* Allow child to continue */ + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + return 1; + } join_thread(pid); printf("%s nested sysctl 1 -> 0 after fork\n", memfd_str); sysctl_assert_write("1"); + + if (semctl(sem, 0, SETVAL, semun) < 0) { + perror("semctl:"); + return 1; + } + pid = spawn_thread(CLONE_NEWPID, sysctl_nested_wait, test_sysctl_sysctl1); sysctl_assert_write("0"); - kill(pid, SIGCONT); + /* Allow child to continue */ + if (semop(sem, &sembuf, 1) < 0) { + perror("semop:"); + return 1; + } join_thread(pid); + semctl(sem, 0, IPC_RMID); + return 0; } diff --git a/tools/testing/selftests/mm/.gitignore b/tools/testing/selftests/mm/.gitignore index c2a8586e51a1..83ad9454dd9d 100644 --- a/tools/testing/selftests/mm/.gitignore +++ b/tools/testing/selftests/mm/.gitignore @@ -12,6 +12,7 @@ map_hugetlb map_populate thuge-gen compaction_test +memory-failure migration mlock2-tests mrelease_test diff --git a/tools/testing/selftests/mm/Makefile b/tools/testing/selftests/mm/Makefile index 905f1e034963..7a5de4e9bf52 100644 --- a/tools/testing/selftests/mm/Makefile +++ b/tools/testing/selftests/mm/Makefile @@ -72,9 +72,10 @@ TEST_GEN_FILES += madv_populate TEST_GEN_FILES += map_fixed_noreplace TEST_GEN_FILES += map_hugetlb TEST_GEN_FILES += map_populate -ifneq (,$(filter $(ARCH),arm64 riscv riscv64 x86 x86_64)) +ifneq (,$(filter $(ARCH),arm64 riscv riscv64 x86 x86_64 loongarch32 loongarch64)) TEST_GEN_FILES += memfd_secret endif +TEST_GEN_FILES += memory-failure TEST_GEN_FILES += migration TEST_GEN_FILES += mkdirty TEST_GEN_FILES += mlock-random-test @@ -154,6 +155,7 @@ TEST_PROGS += ksft_ksm_numa.sh TEST_PROGS += ksft_madv_guard.sh TEST_PROGS += ksft_madv_populate.sh TEST_PROGS += ksft_memfd_secret.sh +TEST_PROGS += ksft_memory_failure.sh TEST_PROGS += ksft_migration.sh TEST_PROGS += ksft_mkdirty.sh TEST_PROGS += ksft_mlock.sh diff --git a/tools/testing/selftests/mm/config b/tools/testing/selftests/mm/config index deba93379c80..1dbe2b4558ab 100644 --- a/tools/testing/selftests/mm/config +++ b/tools/testing/selftests/mm/config @@ -11,3 +11,5 @@ CONFIG_ANON_VMA_NAME=y CONFIG_FTRACE=y CONFIG_PROFILING=y CONFIG_UPROBES=y +CONFIG_MEMORY_FAILURE=y +CONFIG_HWPOISON_INJECT=m diff --git a/tools/testing/selftests/mm/ksft_memory_failure.sh b/tools/testing/selftests/mm/ksft_memory_failure.sh new file mode 100755 index 000000000000..ae1614d4d49b --- /dev/null +++ b/tools/testing/selftests/mm/ksft_memory_failure.sh @@ -0,0 +1,4 @@ +#!/bin/sh -e +# SPDX-License-Identifier: GPL-2.0 + +./run_vmtests.sh -t memory-failure diff --git a/tools/testing/selftests/mm/memory-failure.c b/tools/testing/selftests/mm/memory-failure.c new file mode 100644 index 000000000000..3d9e0b9ffb41 --- /dev/null +++ b/tools/testing/selftests/mm/memory-failure.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Memory-failure functional tests. + * + * Author(s): Miaohe Lin + */ + +#include "../kselftest_harness.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "vm_util.h" + +enum inject_type { + MADV_HARD, + MADV_SOFT, +}; + +enum result_type { + MADV_HARD_ANON, + MADV_HARD_CLEAN_PAGECACHE, + MADV_HARD_DIRTY_PAGECACHE, + MADV_SOFT_ANON, + MADV_SOFT_CLEAN_PAGECACHE, + MADV_SOFT_DIRTY_PAGECACHE, +}; + +static jmp_buf signal_jmp_buf; +static siginfo_t siginfo; +const char *pagemap_proc = "/proc/self/pagemap"; +const char *kpageflags_proc = "/proc/kpageflags"; + +FIXTURE(memory_failure) +{ + unsigned long page_size; + unsigned long corrupted_size; + unsigned long pfn; + int pagemap_fd; + int kpageflags_fd; + bool triggered; +}; + +FIXTURE_VARIANT(memory_failure) +{ + enum inject_type type; + int (*inject)(FIXTURE_DATA(memory_failure) * self, void *vaddr); +}; + +static int madv_hard_inject(FIXTURE_DATA(memory_failure) * self, void *vaddr) +{ + return madvise(vaddr, self->page_size, MADV_HWPOISON); +} + +FIXTURE_VARIANT_ADD(memory_failure, madv_hard) +{ + .type = MADV_HARD, + .inject = madv_hard_inject, +}; + +static int madv_soft_inject(FIXTURE_DATA(memory_failure) * self, void *vaddr) +{ + return madvise(vaddr, self->page_size, MADV_SOFT_OFFLINE); +} + +FIXTURE_VARIANT_ADD(memory_failure, madv_soft) +{ + .type = MADV_SOFT, + .inject = madv_soft_inject, +}; + +static void sigbus_action(int signo, siginfo_t *si, void *args) +{ + memcpy(&siginfo, si, sizeof(siginfo_t)); + siglongjmp(signal_jmp_buf, 1); +} + +static int setup_sighandler(void) +{ + struct sigaction sa = { + .sa_sigaction = sigbus_action, + .sa_flags = SA_SIGINFO, + }; + + return sigaction(SIGBUS, &sa, NULL); +} + +FIXTURE_SETUP(memory_failure) +{ + memset(self, 0, sizeof(*self)); + + self->page_size = (unsigned long)sysconf(_SC_PAGESIZE); + + memset(&siginfo, 0, sizeof(siginfo)); + if (setup_sighandler()) + SKIP(return, "setup sighandler failed.\n"); + + self->pagemap_fd = open(pagemap_proc, O_RDONLY); + if (self->pagemap_fd == -1) + SKIP(return, "open %s failed.\n", pagemap_proc); + + self->kpageflags_fd = open(kpageflags_proc, O_RDONLY); + if (self->kpageflags_fd == -1) + SKIP(return, "open %s failed.\n", kpageflags_proc); +} + +static void teardown_sighandler(void) +{ + struct sigaction sa = { + .sa_handler = SIG_DFL, + .sa_flags = SA_SIGINFO, + }; + + sigaction(SIGBUS, &sa, NULL); +} + +FIXTURE_TEARDOWN(memory_failure) +{ + close(self->kpageflags_fd); + close(self->pagemap_fd); + teardown_sighandler(); +} + +static void prepare(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure) * self, + void *vaddr) +{ + self->pfn = pagemap_get_pfn(self->pagemap_fd, vaddr); + ASSERT_NE(self->pfn, -1UL); + + ASSERT_EQ(get_hardware_corrupted_size(&self->corrupted_size), 0); +} + +static bool check_memory(void *vaddr, unsigned long size) +{ + char buf[64]; + + memset(buf, 0xce, sizeof(buf)); + while (size >= sizeof(buf)) { + if (memcmp(vaddr, buf, sizeof(buf))) + return false; + size -= sizeof(buf); + vaddr += sizeof(buf); + } + + return true; +} + +static void check(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure) * self, + void *vaddr, enum result_type type, int setjmp) +{ + unsigned long size; + uint64_t pfn_flags; + + switch (type) { + case MADV_SOFT_ANON: + case MADV_HARD_CLEAN_PAGECACHE: + case MADV_SOFT_CLEAN_PAGECACHE: + case MADV_SOFT_DIRTY_PAGECACHE: + /* It is not expected to receive a SIGBUS signal. */ + ASSERT_EQ(setjmp, 0); + + /* The page content should remain unchanged. */ + ASSERT_TRUE(check_memory(vaddr, self->page_size)); + + /* The backing pfn of addr should have changed. */ + ASSERT_NE(pagemap_get_pfn(self->pagemap_fd, vaddr), self->pfn); + break; + case MADV_HARD_ANON: + case MADV_HARD_DIRTY_PAGECACHE: + /* The SIGBUS signal should have been received. */ + ASSERT_EQ(setjmp, 1); + + /* Check if siginfo contains correct SIGBUS context. */ + ASSERT_EQ(siginfo.si_signo, SIGBUS); + ASSERT_EQ(siginfo.si_code, BUS_MCEERR_AR); + ASSERT_EQ(1UL << siginfo.si_addr_lsb, self->page_size); + ASSERT_EQ(siginfo.si_addr, vaddr); + + /* XXX Check backing pte is hwpoison entry when supported. */ + ASSERT_TRUE(pagemap_is_swapped(self->pagemap_fd, vaddr)); + break; + default: + SKIP(return, "unexpected inject type %d.\n", type); + } + + /* Check if the value of HardwareCorrupted has increased. */ + ASSERT_EQ(get_hardware_corrupted_size(&size), 0); + ASSERT_EQ(size, self->corrupted_size + self->page_size / 1024); + + /* Check if HWPoison flag is set. */ + ASSERT_EQ(pageflags_get(self->pfn, self->kpageflags_fd, &pfn_flags), 0); + ASSERT_EQ(pfn_flags & KPF_HWPOISON, KPF_HWPOISON); +} + +static void cleanup(struct __test_metadata *_metadata, FIXTURE_DATA(memory_failure) * self, + void *vaddr) +{ + unsigned long size; + uint64_t pfn_flags; + + ASSERT_EQ(unpoison_memory(self->pfn), 0); + + /* Check if HWPoison flag is cleared. */ + ASSERT_EQ(pageflags_get(self->pfn, self->kpageflags_fd, &pfn_flags), 0); + ASSERT_NE(pfn_flags & KPF_HWPOISON, KPF_HWPOISON); + + /* Check if the value of HardwareCorrupted has decreased. */ + ASSERT_EQ(get_hardware_corrupted_size(&size), 0); + ASSERT_EQ(size, self->corrupted_size); +} + +TEST_F(memory_failure, anon) +{ + char *addr; + int ret; + + addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (addr == MAP_FAILED) + SKIP(return, "mmap failed, not enough memory.\n"); + memset(addr, 0xce, self->page_size); + + prepare(_metadata, self, addr); + + ret = sigsetjmp(signal_jmp_buf, 1); + if (!self->triggered) { + self->triggered = true; + ASSERT_EQ(variant->inject(self, addr), 0); + FORCE_READ(*addr); + } + + if (variant->type == MADV_HARD) + check(_metadata, self, addr, MADV_HARD_ANON, ret); + else + check(_metadata, self, addr, MADV_SOFT_ANON, ret); + + cleanup(_metadata, self, addr); + + ASSERT_EQ(munmap(addr, self->page_size), 0); +} + +static int prepare_file(const char *fname, unsigned long size) +{ + int fd; + + fd = open(fname, O_RDWR | O_CREAT, 0664); + if (fd >= 0) { + unlink(fname); + ftruncate(fd, size); + } + return fd; +} + +/* Borrowed from mm/gup_longterm.c. */ +static int get_fs_type(int fd) +{ + struct statfs fs; + int ret; + + do { + ret = fstatfs(fd, &fs); + } while (ret && errno == EINTR); + + return ret ? 0 : (int)fs.f_type; +} + +TEST_F(memory_failure, clean_pagecache) +{ + int fd; + char *addr; + int ret; + int fs_type; + + fd = prepare_file("./clean-page-cache-test-file", self->page_size); + if (fd < 0) + SKIP(return, "failed to open test file.\n"); + fs_type = get_fs_type(fd); + if (!fs_type || fs_type == TMPFS_MAGIC) + SKIP(return, "unsupported filesystem :%x\n", fs_type); + + addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + SKIP(return, "mmap failed, not enough memory.\n"); + memset(addr, 0xce, self->page_size); + fsync(fd); + + prepare(_metadata, self, addr); + + ret = sigsetjmp(signal_jmp_buf, 1); + if (!self->triggered) { + self->triggered = true; + ASSERT_EQ(variant->inject(self, addr), 0); + FORCE_READ(*addr); + } + + if (variant->type == MADV_HARD) + check(_metadata, self, addr, MADV_HARD_CLEAN_PAGECACHE, ret); + else + check(_metadata, self, addr, MADV_SOFT_CLEAN_PAGECACHE, ret); + + cleanup(_metadata, self, addr); + + ASSERT_EQ(munmap(addr, self->page_size), 0); + + ASSERT_EQ(close(fd), 0); +} + +TEST_F(memory_failure, dirty_pagecache) +{ + int fd; + char *addr; + int ret; + int fs_type; + + fd = prepare_file("./dirty-page-cache-test-file", self->page_size); + if (fd < 0) + SKIP(return, "failed to open test file.\n"); + fs_type = get_fs_type(fd); + if (!fs_type || fs_type == TMPFS_MAGIC) + SKIP(return, "unsupported filesystem :%x\n", fs_type); + + addr = mmap(0, self->page_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + SKIP(return, "mmap failed, not enough memory.\n"); + memset(addr, 0xce, self->page_size); + + prepare(_metadata, self, addr); + + ret = sigsetjmp(signal_jmp_buf, 1); + if (!self->triggered) { + self->triggered = true; + ASSERT_EQ(variant->inject(self, addr), 0); + FORCE_READ(*addr); + } + + if (variant->type == MADV_HARD) + check(_metadata, self, addr, MADV_HARD_DIRTY_PAGECACHE, ret); + else + check(_metadata, self, addr, MADV_SOFT_DIRTY_PAGECACHE, ret); + + cleanup(_metadata, self, addr); + + ASSERT_EQ(munmap(addr, self->page_size), 0); + + ASSERT_EQ(close(fd), 0); +} + +TEST_HARNESS_MAIN diff --git a/tools/testing/selftests/mm/run_vmtests.sh b/tools/testing/selftests/mm/run_vmtests.sh index 29be9038bfb0..afdcfd0d7cef 100755 --- a/tools/testing/selftests/mm/run_vmtests.sh +++ b/tools/testing/selftests/mm/run_vmtests.sh @@ -91,6 +91,8 @@ separated by spaces: test VMA merge cases behave as expected - rmap test rmap behaves as expected +- memory-failure + test memory-failure behaves as expected example: ./run_vmtests.sh -t "hmm mmap ksm" EOF @@ -527,6 +529,25 @@ CATEGORY="page_frag" run_test ./test_page_frag.sh nonaligned CATEGORY="rmap" run_test ./rmap +# Try to load hwpoison_inject if not present. +HWPOISON_DIR=/sys/kernel/debug/hwpoison/ +if [ ! -d "$HWPOISON_DIR" ]; then + if ! modprobe -q -R hwpoison_inject; then + echo "Module hwpoison_inject not found, skipping..." + else + modprobe hwpoison_inject > /dev/null 2>&1 + LOADED_MOD=1 + fi +fi + +if [ -d "$HWPOISON_DIR" ]; then + CATEGORY="memory-failure" run_test ./memory-failure +fi + +if [ -n "${LOADED_MOD}" ]; then + modprobe -r hwpoison_inject > /dev/null 2>&1 +fi + if [ "${HAVE_HUGEPAGES}" = 1 ]; then echo "$orig_nr_hugepgs" > /proc/sys/vm/nr_hugepages fi diff --git a/tools/testing/selftests/mm/vm_util.c b/tools/testing/selftests/mm/vm_util.c index d954bf91afd5..a6d4ff7dfdc0 100644 --- a/tools/testing/selftests/mm/vm_util.c +++ b/tools/testing/selftests/mm/vm_util.c @@ -723,3 +723,44 @@ int ksm_stop(void) close(ksm_fd); return ret == 1 ? 0 : -errno; } + +int get_hardware_corrupted_size(unsigned long *val) +{ + unsigned long size; + char *line = NULL; + size_t linelen = 0; + FILE *f = fopen("/proc/meminfo", "r"); + int ret = -1; + + if (!f) + return ret; + + while (getline(&line, &linelen, f) > 0) { + if (sscanf(line, "HardwareCorrupted: %12lu kB", &size) == 1) { + *val = size; + ret = 0; + break; + } + } + + free(line); + fclose(f); + return ret; +} + +int unpoison_memory(unsigned long pfn) +{ + int unpoison_fd, len; + char buf[32]; + ssize_t ret; + + unpoison_fd = open("/sys/kernel/debug/hwpoison/unpoison-pfn", O_WRONLY); + if (unpoison_fd < 0) + return -errno; + + len = sprintf(buf, "0x%lx\n", pfn); + ret = write(unpoison_fd, buf, len); + close(unpoison_fd); + + return ret > 0 ? 0 : -errno; +} diff --git a/tools/testing/selftests/mm/vm_util.h b/tools/testing/selftests/mm/vm_util.h index 522f7f9050f5..e9c4e24769c1 100644 --- a/tools/testing/selftests/mm/vm_util.h +++ b/tools/testing/selftests/mm/vm_util.h @@ -20,6 +20,7 @@ #define KPF_COMPOUND_HEAD BIT_ULL(15) #define KPF_COMPOUND_TAIL BIT_ULL(16) +#define KPF_HWPOISON BIT_ULL(19) #define KPF_THP BIT_ULL(22) /* * Ignore the checkpatch warning, we must read from x but don't want to do @@ -154,6 +155,8 @@ long ksm_get_full_scans(void); int ksm_use_zero_pages(void); int ksm_start(void); int ksm_stop(void); +int get_hardware_corrupted_size(unsigned long *val); +int unpoison_memory(unsigned long pfn); /* * On ppc64 this will only work with radix 2M hugepage size diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile index afdea6d95bde..605c54c0e8a3 100644 --- a/tools/testing/selftests/net/Makefile +++ b/tools/testing/selftests/net/Makefile @@ -15,6 +15,7 @@ TEST_PROGS := \ big_tcp.sh \ bind_bhash.sh \ bpf_offload.py \ + bridge_vlan_dump.sh \ broadcast_ether_dst.sh \ broadcast_pmtu.sh \ busy_poll_test.sh \ diff --git a/tools/testing/selftests/net/bridge_vlan_dump.sh b/tools/testing/selftests/net/bridge_vlan_dump.sh new file mode 100755 index 000000000000..ad66731d2a6f --- /dev/null +++ b/tools/testing/selftests/net/bridge_vlan_dump.sh @@ -0,0 +1,204 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Test bridge VLAN range grouping. VLANs are collapsed into a range entry in +# the dump if they have the same per-VLAN options. These tests verify that +# VLANs with different per-VLAN option values are not grouped together. + +# shellcheck disable=SC1091,SC2034,SC2154,SC2317 +source lib.sh + +ALL_TESTS=" + vlan_range_neigh_suppress + vlan_range_mcast_max_groups + vlan_range_mcast_n_groups + vlan_range_mcast_enabled +" + +setup_prepare() +{ + setup_ns NS + defer cleanup_all_ns + + ip -n "$NS" link add name br0 type bridge vlan_filtering 1 \ + vlan_default_pvid 0 mcast_snooping 1 mcast_vlan_snooping 1 + ip -n "$NS" link set dev br0 up + + ip -n "$NS" link add name dummy0 type dummy + ip -n "$NS" link set dev dummy0 master br0 + ip -n "$NS" link set dev dummy0 up +} + +vlan_range_neigh_suppress() +{ + RET=0 + + # Add two new consecutive VLANs for range grouping test + bridge -n "$NS" vlan add vid 10 dev dummy0 + defer bridge -n "$NS" vlan del vid 10 dev dummy0 + + bridge -n "$NS" vlan add vid 11 dev dummy0 + defer bridge -n "$NS" vlan del vid 11 dev dummy0 + + # Configure different neigh_suppress values and verify no range grouping + bridge -n "$NS" vlan set vid 10 dev dummy0 neigh_suppress on + check_err $? "Failed to set neigh_suppress for VLAN 10" + + bridge -n "$NS" vlan set vid 11 dev dummy0 neigh_suppress off + check_err $? "Failed to set neigh_suppress for VLAN 11" + + # Verify VLANs are not shown as a range, but individual entries exist + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_fail $? "VLANs with different neigh_suppress incorrectly grouped" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+10$|^\s+10$" + check_err $? "VLAN 10 individual entry not found" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+11$|^\s+11$" + check_err $? "VLAN 11 individual entry not found" + + # Configure same neigh_suppress value and verify range grouping + bridge -n "$NS" vlan set vid 11 dev dummy0 neigh_suppress on + check_err $? "Failed to set neigh_suppress for VLAN 11" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_err $? "VLANs with same neigh_suppress not grouped" + + log_test "VLAN range grouping with neigh_suppress" +} + +vlan_range_mcast_max_groups() +{ + RET=0 + + # Add two new consecutive VLANs for range grouping test + bridge -n "$NS" vlan add vid 10 dev dummy0 + defer bridge -n "$NS" vlan del vid 10 dev dummy0 + + bridge -n "$NS" vlan add vid 11 dev dummy0 + defer bridge -n "$NS" vlan del vid 11 dev dummy0 + + # Configure different mcast_max_groups values and verify no range grouping + bridge -n "$NS" vlan set vid 10 dev dummy0 mcast_max_groups 100 + check_err $? "Failed to set mcast_max_groups for VLAN 10" + + bridge -n "$NS" vlan set vid 11 dev dummy0 mcast_max_groups 200 + check_err $? "Failed to set mcast_max_groups for VLAN 11" + + # Verify VLANs are not shown as a range, but individual entries exist + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_fail $? "VLANs with different mcast_max_groups incorrectly grouped" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+10$|^\s+10$" + check_err $? "VLAN 10 individual entry not found" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+11$|^\s+11$" + check_err $? "VLAN 11 individual entry not found" + + # Configure same mcast_max_groups value and verify range grouping + bridge -n "$NS" vlan set vid 11 dev dummy0 mcast_max_groups 100 + check_err $? "Failed to set mcast_max_groups for VLAN 11" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_err $? "VLANs with same mcast_max_groups not grouped" + + log_test "VLAN range grouping with mcast_max_groups" +} + +vlan_range_mcast_n_groups() +{ + RET=0 + + # Add two new consecutive VLANs for range grouping test + bridge -n "$NS" vlan add vid 10 dev dummy0 + defer bridge -n "$NS" vlan del vid 10 dev dummy0 + + bridge -n "$NS" vlan add vid 11 dev dummy0 + defer bridge -n "$NS" vlan del vid 11 dev dummy0 + + # Add different numbers of multicast groups to each VLAN + bridge -n "$NS" mdb add dev br0 port dummy0 grp 239.1.1.1 vid 10 + check_err $? "Failed to add mdb entry to VLAN 10" + defer bridge -n "$NS" mdb del dev br0 port dummy0 grp 239.1.1.1 vid 10 + + bridge -n "$NS" mdb add dev br0 port dummy0 grp 239.1.1.2 vid 10 + check_err $? "Failed to add second mdb entry to VLAN 10" + defer bridge -n "$NS" mdb del dev br0 port dummy0 grp 239.1.1.2 vid 10 + + bridge -n "$NS" mdb add dev br0 port dummy0 grp 239.1.1.1 vid 11 + check_err $? "Failed to add mdb entry to VLAN 11" + defer bridge -n "$NS" mdb del dev br0 port dummy0 grp 239.1.1.1 vid 11 + + # Verify VLANs are not shown as a range due to different mcast_n_groups + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_fail $? "VLANs with different mcast_n_groups incorrectly grouped" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+10$|^\s+10$" + check_err $? "VLAN 10 individual entry not found" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+11$|^\s+11$" + check_err $? "VLAN 11 individual entry not found" + + # Add another group to VLAN 11 to match VLAN 10's count + bridge -n "$NS" mdb add dev br0 port dummy0 grp 239.1.1.2 vid 11 + check_err $? "Failed to add second mdb entry to VLAN 11" + defer bridge -n "$NS" mdb del dev br0 port dummy0 grp 239.1.1.2 vid 11 + + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_err $? "VLANs with same mcast_n_groups not grouped" + + log_test "VLAN range grouping with mcast_n_groups" +} + +vlan_range_mcast_enabled() +{ + RET=0 + + # Add two new consecutive VLANs for range grouping test + bridge -n "$NS" vlan add vid 10 dev br0 self + defer bridge -n "$NS" vlan del vid 10 dev br0 self + + bridge -n "$NS" vlan add vid 11 dev br0 self + defer bridge -n "$NS" vlan del vid 11 dev br0 self + + bridge -n "$NS" vlan add vid 10 dev dummy0 + defer bridge -n "$NS" vlan del vid 10 dev dummy0 + + bridge -n "$NS" vlan add vid 11 dev dummy0 + defer bridge -n "$NS" vlan del vid 11 dev dummy0 + + # Configure different mcast_snooping for bridge VLANs + # Port VLANs inherit BR_VLFLAG_MCAST_ENABLED from bridge VLANs + bridge -n "$NS" vlan global set dev br0 vid 10 mcast_snooping 1 + bridge -n "$NS" vlan global set dev br0 vid 11 mcast_snooping 0 + + # Verify port VLANs are not grouped due to different mcast_enabled + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_fail $? "VLANs with different mcast_enabled incorrectly grouped" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+10$|^\s+10$" + check_err $? "VLAN 10 individual entry not found" + + bridge -n "$NS" -d vlan show dev dummy0 | grep -Eq "^\S+\s+11$|^\s+11$" + check_err $? "VLAN 11 individual entry not found" + + # Configure same mcast_snooping and verify range grouping + bridge -n "$NS" vlan global set dev br0 vid 11 mcast_snooping 1 + + bridge -n "$NS" -d vlan show dev dummy0 | grep -q "10-11" + check_err $? "VLANs with same mcast_enabled not grouped" + + log_test "VLAN range grouping with mcast_enabled" +} + +# Verify the newest tested option is supported +if ! bridge vlan help 2>&1 | grep -q "neigh_suppress"; then + echo "SKIP: iproute2 too old, missing per-VLAN neighbor suppression support" + exit "$ksft_skip" +fi + +trap defer_scopes_cleanup EXIT +setup_prepare +tests_run + +exit "$EXIT_STATUS" diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index 21026b667667..6eb7f95e70e1 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -1672,6 +1672,17 @@ ipv4_withv6_fcnal() run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1" log_test $? 2 "IPv4 route with invalid IPv6 gateway" + + # Test IPv4 route with loopback IPv6 nexthop + # Regression test: loopback IPv6 nexthop was misclassified as reject + # route, skipping nhc_pcpu_rth_output allocation, causing panic when + # an IPv4 route references it and triggers __mkroute_output(). + run_cmd "$IP -6 nexthop add id 20 dev lo" + run_cmd "$IP ro add 172.20.20.0/24 nhid 20" + run_cmd "ip netns exec $me ping -c1 -W1 172.20.20.1" + log_test $? 1 "IPv4 route with loopback IPv6 nexthop (no crash)" + run_cmd "$IP ro del 172.20.20.0/24" + run_cmd "$IP nexthop del id 20" } ipv4_fcnal_runtime() diff --git a/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh b/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh index 3da9d93ab36f..625162fd7e8b 100755 --- a/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh +++ b/tools/testing/selftests/net/forwarding/bridge_mdb_max.sh @@ -28,6 +28,7 @@ ALL_TESTS=" test_8021d test_8021q test_8021qvs + test_mdb_count_warning " NUM_NETIFS=4 @@ -83,8 +84,6 @@ switch_create_8021q() { local br_flags=$1; shift - log_info "802.1q $br_flags${br_flags:+ }tests" - ip link add name br0 type bridge vlan_filtering 1 vlan_default_pvid 0 \ mcast_snooping 1 $br_flags \ mcast_igmp_version 3 mcast_mld_version 2 @@ -106,6 +105,7 @@ switch_create_8021q() switch_create_8021qvs() { + log_info "802.1q mcast_vlan_snooping 1 tests" switch_create_8021q "mcast_vlan_snooping 1" bridge vlan global set dev br0 vid 10 mcast_igmp_version 3 bridge vlan global set dev br0 vid 10 mcast_mld_version 2 @@ -1272,6 +1272,76 @@ test_8021qvs_toggle_vlan_snooping() test_toggle_vlan_snooping_permanent } +mdb_count_check_warn() +{ + local msg=$1; shift + + dmesg | grep -q "WARNING:.*br_multicast_port_ngroups_dec.*" + check_fail $? "$msg" +} + +test_mdb_count_mcast_vlan_snooping_flush() +{ + RET=0 + + # check if we already have a warning + mdb_count_check_warn "Check MDB entries count warning before test" + + bridge mdb add dev br0 port "$swp1" grp 239.0.0.1 permanent vid 10 + ip link set dev br0 down + ip link set dev br0 type bridge mcast_vlan_snooping 1 + bridge mdb flush dev br0 + + mdb_count_check_warn "Check MDB entries count warning after test" + + ip link set dev br0 type bridge mcast_vlan_snooping 0 + ip link set dev br0 up + + log_test "MDB count warning: mcast_vlan_snooping and MDB flush" +} + +test_mdb_count_mcast_snooping_flush() +{ + RET=0 + + # check if we already have a warning + mdb_count_check_warn "Check MDB entries count warning before test" + + bridge mdb add dev br0 port "$swp1" grp 239.0.0.1 permanent vid 10 + ip link set dev br0 type bridge mcast_snooping 0 + ip link set dev br0 type bridge mcast_vlan_snooping 1 + bridge mdb flush dev br0 + + mdb_count_check_warn "Check MDB entries count warning after test" + + ip link set dev br0 type bridge mcast_vlan_snooping 0 + ip link set dev br0 type bridge mcast_snooping 1 + + log_test "MDB count warning: mcast_snooping and MDB flush" +} + +test_mdb_count_vlan_state_flush() +{ + RET=0 + + # check if we already have a warning + mdb_count_check_warn "Check MDB entries count warning before test" + + bridge mdb add dev br0 port "$swp1" grp 239.0.0.1 permanent vid 10 + ip link set dev br0 down + bridge vlan set vid 10 dev "$swp1" state blocking + ip link set dev br0 type bridge mcast_vlan_snooping 1 + ip link set dev br0 up + bridge mdb flush dev br0 + + mdb_count_check_warn "Check MDB entries count warning after test" + + bridge vlan set vid 10 dev "$swp1" state forwarding + ip link set dev br0 type bridge mcast_vlan_snooping 0 + + log_test "MDB count warning: disabled vlan state and MDB flush" +} + # test groups test_8021d() @@ -1297,6 +1367,7 @@ test_8021q() { # Tests for vlan_filtering 1 mcast_vlan_snooping 0. + log_info "802.1q tests" switch_create_8021q setup_wait @@ -1334,6 +1405,21 @@ test_8021qvs() switch_destroy } +test_mdb_count_warning() +{ + # Tests for mdb_n_entries warning + + log_info "MDB count warning tests" + switch_create_8021q + setup_wait + + test_mdb_count_mcast_vlan_snooping_flush + test_mdb_count_mcast_snooping_flush + test_mdb_count_vlan_state_flush + + switch_destroy +} + if ! bridge link help 2>&1 | grep -q "mcast_max_groups"; then echo "SKIP: iproute2 too old, missing bridge \"mcast_max_groups\" support" exit $ksft_skip diff --git a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh index af008fbf2725..eb2d8034de9c 100755 --- a/tools/testing/selftests/net/forwarding/pedit_dsfield.sh +++ b/tools/testing/selftests/net/forwarding/pedit_dsfield.sh @@ -98,12 +98,20 @@ setup_prepare() h1_create h2_create switch_create + + if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then + sysctl_set net.bridge.bridge-nf-call-iptables 0 + fi } cleanup() { pre_cleanup + if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then + sysctl_restore net.bridge.bridge-nf-call-iptables + fi + switch_destroy h2_destroy h1_destroy diff --git a/tools/testing/selftests/net/forwarding/pedit_ip.sh b/tools/testing/selftests/net/forwarding/pedit_ip.sh index d14efb2d23b2..9235674627ab 100755 --- a/tools/testing/selftests/net/forwarding/pedit_ip.sh +++ b/tools/testing/selftests/net/forwarding/pedit_ip.sh @@ -91,12 +91,20 @@ setup_prepare() h1_create h2_create switch_create + + if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then + sysctl_set net.bridge.bridge-nf-call-iptables 0 + fi } cleanup() { pre_cleanup + if [ -f /proc/sys/net/bridge/bridge-nf-call-iptables ]; then + sysctl_restore net.bridge.bridge-nf-call-iptables + fi + switch_destroy h2_destroy h1_destroy diff --git a/tools/testing/selftests/net/forwarding/tc_actions.sh b/tools/testing/selftests/net/forwarding/tc_actions.sh index ea89e558672d..86edbc7e2489 100755 --- a/tools/testing/selftests/net/forwarding/tc_actions.sh +++ b/tools/testing/selftests/net/forwarding/tc_actions.sh @@ -223,7 +223,7 @@ mirred_egress_to_ingress_tcp_test() ip_proto icmp \ action drop - ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & + ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 > $mirred_e2i_tf2 & local rpid=$! ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 wait -n $rpid diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh index b43816dd998c..457f41d5e584 100755 --- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh +++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d.sh @@ -567,6 +567,21 @@ vxlan_encapped_ping_do() local inner_tos=$1; shift local outer_tos=$1; shift + local ipv4hdr=$(: + )"45:"$( : IP version + IHL + )"$inner_tos:"$( : IP TOS + )"00:54:"$( : IP total length + )"99:83:"$( : IP identification + )"40:00:"$( : IP flags + frag off + )"40:"$( : IP TTL + )"01:"$( : IP proto + )"CHECKSUM:"$( : IP header csum + )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 + )"c0:00:02:01"$( : IP daddr: 192.0.2.1 + ) + local checksum=$(payload_template_calc_checksum "$ipv4hdr") + ipv4hdr=$(payload_template_expand_checksum "$ipv4hdr" $checksum) + $MZ $dev -c $count -d 100msec -q \ -b $next_hop_mac -B $dest_ip \ -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(: @@ -577,16 +592,7 @@ vxlan_encapped_ping_do() )"$dest_mac:"$( : ETH daddr )"$(mac_get w2):"$( : ETH saddr )"08:00:"$( : ETH type - )"45:"$( : IP version + IHL - )"$inner_tos:"$( : IP TOS - )"00:54:"$( : IP total length - )"99:83:"$( : IP identification - )"40:00:"$( : IP flags + frag off - )"40:"$( : IP TTL - )"01:"$( : IP proto - )"00:00:"$( : IP header csum - )"c0:00:02:03:"$( : IP saddr: 192.0.2.3 - )"c0:00:02:01:"$( : IP daddr: 192.0.2.1 + )"$ipv4hdr:"$( : IPv4 header )"08:"$( : ICMP type )"00:"$( : ICMP code )"8b:f2:"$( : ICMP csum diff --git a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh index a603f7b0a08f..e642feeada0e 100755 --- a/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh +++ b/tools/testing/selftests/net/forwarding/vxlan_bridge_1d_ipv6.sh @@ -695,7 +695,7 @@ vxlan_encapped_ping_do() )"6"$( : IP version )"$inner_tos"$( : Traffic class )"0:00:00:"$( : Flow label - )"00:08:"$( : Payload length + )"00:03:"$( : Payload length )"3a:"$( : Next header )"04:"$( : Hop limit )"$saddr:"$( : IP saddr diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh index 0ec131b339bc..b40694573f4c 100644 --- a/tools/testing/selftests/net/lib.sh +++ b/tools/testing/selftests/net/lib.sh @@ -577,7 +577,7 @@ ip_link_has_flag() local flag=$1; shift local state=$(ip -j link show "$name" | - jq --arg flag "$flag" 'any(.[].flags.[]; . == $flag)') + jq --arg flag "$flag" 'any(.[].flags[]; . == $flag)') [[ $state == true ]] } diff --git a/tools/testing/selftests/net/mptcp/mptcp_join.sh b/tools/testing/selftests/net/mptcp/mptcp_join.sh index dc1f200aaa81..a3144d7298a5 100755 --- a/tools/testing/selftests/net/mptcp/mptcp_join.sh +++ b/tools/testing/selftests/net/mptcp/mptcp_join.sh @@ -104,6 +104,24 @@ CBPF_MPTCP_SUBOPTION_ADD_ADDR="14, 6 0 0 65535, 6 0 0 0" +# IPv4: TCP hdr of 48B, a first suboption of 12B (DACK8), the RM_ADDR suboption +# generated using "nfbpf_compile '(ip[32] & 0xf0) == 0xc0 && ip[53] == 0x0c && +# (ip[66] & 0xf0) == 0x40'" +CBPF_MPTCP_SUBOPTION_RM_ADDR="13, + 48 0 0 0, + 84 0 0 240, + 21 0 9 64, + 48 0 0 32, + 84 0 0 240, + 21 0 6 192, + 48 0 0 53, + 21 0 4 12, + 48 0 0 66, + 84 0 0 240, + 21 0 1 64, + 6 0 0 65535, + 6 0 0 0" + init_partial() { capout=$(mktemp) @@ -2608,6 +2626,19 @@ remove_tests() chk_rst_nr 0 0 fi + # signal+subflow with limits, remove + if reset "remove signal+subflow with limits"; then + pm_nl_set_limits $ns1 0 0 + pm_nl_add_endpoint $ns1 10.0.2.1 flags signal,subflow + pm_nl_set_limits $ns2 0 0 + addr_nr_ns1=-1 speed=slow \ + run_tests $ns1 $ns2 10.0.1.1 + chk_join_nr 0 0 0 + chk_add_nr 1 1 + chk_rm_nr 1 0 invert + chk_rst_nr 0 0 + fi + # addresses remove if reset "remove addresses"; then pm_nl_set_limits $ns1 3 3 @@ -4217,6 +4248,14 @@ endpoint_tests() chk_subflow_nr "after no reject" 3 chk_mptcp_info subflows 2 subflows 2 + # To make sure RM_ADDR are sent over a different subflow, but + # allow the rest to quickly and cleanly close the subflow + local ipt=1 + ip netns exec "${ns2}" ${iptables} -I OUTPUT -s "10.0.1.2" \ + -p tcp -m tcp --tcp-option 30 \ + -m bpf --bytecode \ + "$CBPF_MPTCP_SUBOPTION_RM_ADDR" \ + -j DROP || ipt=0 local i for i in $(seq 3); do pm_nl_del_endpoint $ns2 1 10.0.1.2 @@ -4229,6 +4268,7 @@ endpoint_tests() chk_subflow_nr "after re-add id 0 ($i)" 3 chk_mptcp_info subflows 3 subflows 3 done + [ ${ipt} = 1 ] && ip netns exec "${ns2}" ${iptables} -D OUTPUT 1 mptcp_lib_kill_group_wait $tests_pid @@ -4288,11 +4328,20 @@ endpoint_tests() chk_mptcp_info subflows 2 subflows 2 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 + # To make sure RM_ADDR are sent over a different subflow, but + # allow the rest to quickly and cleanly close the subflow + local ipt=1 + ip netns exec "${ns1}" ${iptables} -I OUTPUT -s "10.0.1.1" \ + -p tcp -m tcp --tcp-option 30 \ + -m bpf --bytecode \ + "$CBPF_MPTCP_SUBOPTION_RM_ADDR" \ + -j DROP || ipt=0 pm_nl_del_endpoint $ns1 42 10.0.1.1 sleep 0.5 chk_subflow_nr "after delete ID 0" 2 chk_mptcp_info subflows 2 subflows 2 chk_mptcp_info add_addr_signal 2 add_addr_accepted 2 + [ ${ipt} = 1 ] && ip netns exec "${ns1}" ${iptables} -D OUTPUT 1 pm_nl_add_endpoint $ns1 10.0.1.1 id 99 flags signal wait_mpj 4 diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh index 806aaa7d2d61..d11a8b949aab 100755 --- a/tools/testing/selftests/net/mptcp/simult_flows.sh +++ b/tools/testing/selftests/net/mptcp/simult_flows.sh @@ -237,10 +237,13 @@ run_test() for dev in ns2eth1 ns2eth2; do tc -n $ns2 qdisc del dev $dev root >/dev/null 2>&1 done - tc -n $ns1 qdisc add dev ns1eth1 root netem rate ${rate1}mbit $delay1 - tc -n $ns1 qdisc add dev ns1eth2 root netem rate ${rate2}mbit $delay2 - tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1 - tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2 + + # keep the queued pkts number low, or the RTT estimator will see + # increasing latency over time. + tc -n $ns1 qdisc add dev ns1eth1 root netem rate ${rate1}mbit $delay1 limit 50 + tc -n $ns1 qdisc add dev ns1eth2 root netem rate ${rate2}mbit $delay2 limit 50 + tc -n $ns2 qdisc add dev ns2eth1 root netem rate ${rate1}mbit $delay1 limit 50 + tc -n $ns2 qdisc add dev ns2eth2 root netem rate ${rate2}mbit $delay2 limit 50 # time is measured in ms, account for transfer size, aggregated link speed # and header overhead (10%) diff --git a/tools/testing/selftests/net/netfilter/nf_queue.c b/tools/testing/selftests/net/netfilter/nf_queue.c index 9e56b9d47037..116c0ca0eabb 100644 --- a/tools/testing/selftests/net/netfilter/nf_queue.c +++ b/tools/testing/selftests/net/netfilter/nf_queue.c @@ -18,6 +18,7 @@ struct options { bool count_packets; bool gso_enabled; + bool failopen; int verbose; unsigned int queue_num; unsigned int timeout; @@ -30,7 +31,7 @@ static struct options opts; static void help(const char *p) { - printf("Usage: %s [-c|-v [-vv] ] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p); + printf("Usage: %s [-c|-v [-vv] ] [-o] [-t timeout] [-q queue_num] [-Qdst_queue ] [ -d ms_delay ] [-G]\n", p); } static int parse_attr_cb(const struct nlattr *attr, void *data) @@ -236,6 +237,8 @@ struct mnl_socket *open_queue(void) flags = opts.gso_enabled ? NFQA_CFG_F_GSO : 0; flags |= NFQA_CFG_F_UID_GID; + if (opts.failopen) + flags |= NFQA_CFG_F_FAIL_OPEN; mnl_attr_put_u32(nlh, NFQA_CFG_FLAGS, htonl(flags)); mnl_attr_put_u32(nlh, NFQA_CFG_MASK, htonl(flags)); @@ -329,7 +332,7 @@ static void parse_opts(int argc, char **argv) { int c; - while ((c = getopt(argc, argv, "chvt:q:Q:d:G")) != -1) { + while ((c = getopt(argc, argv, "chvot:q:Q:d:G")) != -1) { switch (c) { case 'c': opts.count_packets = true; @@ -366,6 +369,9 @@ static void parse_opts(int argc, char **argv) case 'G': opts.gso_enabled = false; break; + case 'o': + opts.failopen = true; + break; case 'v': opts.verbose++; break; diff --git a/tools/testing/selftests/net/netfilter/nft_queue.sh b/tools/testing/selftests/net/netfilter/nft_queue.sh index 139bc1211878..ea766bdc5d04 100755 --- a/tools/testing/selftests/net/netfilter/nft_queue.sh +++ b/tools/testing/selftests/net/netfilter/nft_queue.sh @@ -591,6 +591,7 @@ EOF test_udp_gro_ct() { local errprefix="FAIL: test_udp_gro_ct:" + local timeout=5 ip netns exec "$nsrouter" conntrack -F 2>/dev/null @@ -630,10 +631,10 @@ table inet udpq { } } EOF - timeout 10 ip netns exec "$ns2" socat UDP-LISTEN:12346,fork,pf=ipv4 OPEN:"$TMPFILE1",trunc & + timeout "$timeout" ip netns exec "$ns2" socat UDP-LISTEN:12346,fork,pf=ipv4 OPEN:"$TMPFILE1",trunc & local rpid=$! - ip netns exec "$nsrouter" ./nf_queue -G -c -q 1 -t 2 > "$TMPFILE2" & + ip netns exec "$nsrouter" nice -n -19 ./nf_queue -G -c -q 1 -o -t 2 > "$TMPFILE2" & local nfqpid=$! ip netns exec "$nsrouter" ethtool -K "veth0" rx-udp-gro-forwarding on rx-gro-list on generic-receive-offload on @@ -643,8 +644,12 @@ EOF local bs=512 local count=$(((32 * 1024 * 1024) / bs)) - dd if=/dev/zero bs="$bs" count="$count" 2>/dev/null | for i in $(seq 1 16); do - timeout 5 ip netns exec "$ns1" \ + + local nprocs=$(nproc) + [ $nprocs -gt 1 ] && nprocs=$((nprocs - 1)) + + dd if=/dev/zero bs="$bs" count="$count" 2>/dev/null | for i in $(seq 1 $nprocs); do + timeout "$timeout" nice -n 19 ip netns exec "$ns1" \ socat -u -b 512 STDIN UDP-DATAGRAM:10.0.2.99:12346,reuseport,bind=0.0.0.0:55221 & done diff --git a/tools/testing/selftests/net/packetdrill/ksft_runner.sh b/tools/testing/selftests/net/packetdrill/ksft_runner.sh index b34e5cf0112e..0a97d5ae3469 100755 --- a/tools/testing/selftests/net/packetdrill/ksft_runner.sh +++ b/tools/testing/selftests/net/packetdrill/ksft_runner.sh @@ -13,6 +13,15 @@ declare -A ip_args=( -D TFO_COOKIE_ZERO=b7c12350a90dc8f5 -D CMSG_LEVEL_IP=SOL_IP -D CMSG_TYPE_RECVERR=IP_RECVERR" + [ipv4-mapped-ipv6]="--ip_version=ipv4-mapped-ipv6 + --local_ip=192.168.0.1 + --gateway_ip=192.168.0.1 + --netmask_ip=255.255.0.0 + --remote_ip=192.0.2.1 + -D TFO_COOKIE=3021b9d889017eeb + -D TFO_COOKIE_ZERO=b7c12350a90dc8f5 + -D CMSG_LEVEL_IP=SOL_IPV6 + -D CMSG_TYPE_RECVERR=IPV6_RECVERR" [ipv6]="--ip_version=ipv6 --mtu=1520 --local_ip=fd3d:0a0b:17d6::1 @@ -45,7 +54,7 @@ fi ip_versions=$(grep -E '^--ip_version=' $script | cut -d '=' -f 2) if [[ -z $ip_versions ]]; then - ip_versions="ipv4 ipv6" + ip_versions="ipv4 ipv6 ipv4-mapped-ipv6" elif [[ ! "$ip_versions" =~ ^ipv[46]$ ]]; then ktap_exit_fail_msg "Too many or unsupported --ip_version: $ip_versions" exit "$KSFT_FAIL" diff --git a/tools/testing/selftests/net/packetdrill/tcp_rcv_big_endseq.pkt b/tools/testing/selftests/net/packetdrill/tcp_rcv_big_endseq.pkt index 3848b419e68c..6c0f32c40f19 100644 --- a/tools/testing/selftests/net/packetdrill/tcp_rcv_big_endseq.pkt +++ b/tools/testing/selftests/net/packetdrill/tcp_rcv_big_endseq.pkt @@ -38,7 +38,7 @@ // If queue is empty, accept a packet even if its end_seq is above wup + rcv_wnd +0 < P. 4001:54001(50000) ack 1 win 257 - +0 > . 1:1(0) ack 54001 win 0 + * > . 1:1(0) ack 54001 win 0 // Check LINUX_MIB_BEYOND_WINDOW has been incremented 3 times. +0 `nstat | grep TcpExtBeyondWindow | grep -q " 3 "` diff --git a/tools/testing/selftests/net/packetdrill/tcp_rcv_toobig.pkt b/tools/testing/selftests/net/packetdrill/tcp_rcv_toobig.pkt deleted file mode 100644 index f575c0ff89da..000000000000 --- a/tools/testing/selftests/net/packetdrill/tcp_rcv_toobig.pkt +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - ---mss=1000 - -`./defaults.sh` - - 0 `nstat -n` - -// Establish a connection. - +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 - +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 - +0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [20000], 4) = 0 - +0 bind(3, ..., ...) = 0 - +0 listen(3, 1) = 0 - - +0 < S 0:0(0) win 32792 - +0 > S. 0:0(0) ack 1 win 18980 - +.1 < . 1:1(0) ack 1 win 257 - - +0 accept(3, ..., ...) = 4 - - +0 < P. 1:20001(20000) ack 1 win 257 - +.04 > . 1:1(0) ack 20001 win 18000 - - +0 setsockopt(4, SOL_SOCKET, SO_RCVBUF, [12000], 4) = 0 - +0 < P. 20001:80001(60000) ack 1 win 257 - +0 > . 1:1(0) ack 20001 win 18000 - - +0 read(4, ..., 20000) = 20000 -// A too big packet is accepted if the receive queue is empty - +0 < P. 20001:80001(60000) ack 1 win 257 - +0 > . 1:1(0) ack 80001 win 0 - diff --git a/tools/testing/selftests/net/packetdrill/tcp_rcv_zero_wnd_fin.pkt b/tools/testing/selftests/net/packetdrill/tcp_rcv_zero_wnd_fin.pkt new file mode 100644 index 000000000000..e245359a1a91 --- /dev/null +++ b/tools/testing/selftests/net/packetdrill/tcp_rcv_zero_wnd_fin.pkt @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +// Some TCP stacks send FINs even though the window is closed. We break +// a possible FIN/ACK loop by accepting the FIN. + +--mss=1000 + +`./defaults.sh` + +// Establish a connection. + +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [20000], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + + +0 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 + +0 < . 1:1(0) ack 1 win 257 + + +0 accept(3, ..., ...) = 4 + + +0 < P. 1:60001(60000) ack 1 win 257 + * > . 1:1(0) ack 60001 win 0 + + +0 < F. 60001:60001(0) ack 1 win 257 + +0 > . 1:1(0) ack 60002 win 0 diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 248c2b91fe42..5a5ff88321d5 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -28,6 +28,7 @@ ALL_TESTS=" kci_test_fdb_get kci_test_fdb_del kci_test_neigh_get + kci_test_neigh_update kci_test_bridge_parent_id kci_test_address_proto kci_test_enslave_bonding @@ -1160,6 +1161,60 @@ kci_test_neigh_get() end_test "PASS: neigh get" } +kci_test_neigh_update() +{ + dstip=10.0.2.4 + dstmac=de:ad:be:ef:13:37 + local ret=0 + + for proxy in "" "proxy" ; do + # add a neighbour entry without any flags + run_cmd ip neigh add $proxy $dstip dev "$devdummy" lladdr $dstmac nud permanent + run_cmd_grep $dstip ip neigh show $proxy + run_cmd_grep_fail "$dstip dev $devdummy .*\(managed\|use\|router\|extern\)" ip neigh show $proxy + + # set the extern_learn flag, but no other + run_cmd ip neigh change $proxy $dstip dev "$devdummy" extern_learn + run_cmd_grep "$dstip dev $devdummy .* extern_learn" ip neigh show $proxy + run_cmd_grep_fail "$dstip dev $devdummy .* \(managed\|use\|router\)" ip neigh show $proxy + + # flags are reset when not provided + run_cmd ip neigh change $proxy $dstip dev "$devdummy" + run_cmd_grep $dstip ip neigh show $proxy + run_cmd_grep_fail "$dstip dev $devdummy .* extern_learn" ip neigh show $proxy + + # add a protocol + run_cmd ip neigh change $proxy $dstip dev "$devdummy" protocol boot + run_cmd_grep "$dstip dev $devdummy .* proto boot" ip neigh show $proxy + + # protocol is retained when not provided + run_cmd ip neigh change $proxy $dstip dev "$devdummy" + run_cmd_grep "$dstip dev $devdummy .* proto boot" ip neigh show $proxy + + # change protocol + run_cmd ip neigh change $proxy $dstip dev "$devdummy" protocol static + run_cmd_grep "$dstip dev $devdummy .* proto static" ip neigh show $proxy + + # also check an extended flag for non-proxy neighs + if [ "$proxy" = "" ]; then + run_cmd ip neigh change $proxy $dstip dev "$devdummy" managed + run_cmd_grep "$dstip dev $devdummy managed" ip neigh show $proxy + + run_cmd ip neigh change $proxy $dstip dev "$devdummy" lladdr $dstmac + run_cmd_grep_fail "$dstip dev $devdummy managed" ip neigh show $proxy + fi + + run_cmd ip neigh del $proxy $dstip dev "$devdummy" + done + + if [ $ret -ne 0 ];then + end_test "FAIL: neigh update" + return 1 + fi + + end_test "PASS: neigh update" +} + kci_test_bridge_parent_id() { local ret=0 diff --git a/tools/testing/selftests/net/tun.c b/tools/testing/selftests/net/tun.c index 8a5cd5cb5472..cf106a49b55e 100644 --- a/tools/testing/selftests/net/tun.c +++ b/tools/testing/selftests/net/tun.c @@ -944,8 +944,8 @@ TEST_F(tun_vnet_udptnl, send_gso_packet) ASSERT_EQ(ret, off); ret = receive_gso_packet_from_tunnel(self, variant, &r_num_mss); - ASSERT_EQ(ret, variant->data_size); - ASSERT_EQ(r_num_mss, variant->r_num_mss); + EXPECT_EQ(ret, variant->data_size); + EXPECT_EQ(r_num_mss, variant->r_num_mss); } TEST_F(tun_vnet_udptnl, recv_gso_packet) @@ -955,18 +955,18 @@ TEST_F(tun_vnet_udptnl, recv_gso_packet) int ret, gso_type = VIRTIO_NET_HDR_GSO_UDP_L4; ret = send_gso_packet_into_tunnel(self, variant); - ASSERT_EQ(ret, variant->data_size); + EXPECT_EQ(ret, variant->data_size); memset(&vnet_hdr, 0, sizeof(vnet_hdr)); ret = receive_gso_packet_from_tun(self, variant, &vnet_hdr); - ASSERT_EQ(ret, variant->data_size); + EXPECT_EQ(ret, variant->data_size); if (!variant->no_gso) { - ASSERT_EQ(vh->gso_size, variant->gso_size); + EXPECT_EQ(vh->gso_size, variant->gso_size); gso_type |= (variant->tunnel_type & UDP_TUNNEL_OUTER_IPV4) ? (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4) : (VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6); - ASSERT_EQ(vh->gso_type, gso_type); + EXPECT_EQ(vh->gso_type, gso_type); } } diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore index 7283e8b07b75..80d4270a71ac 100644 --- a/tools/testing/selftests/powerpc/copyloops/.gitignore +++ b/tools/testing/selftests/powerpc/copyloops/.gitignore @@ -2,8 +2,8 @@ copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 -copyuser_p7_t0 -copyuser_p7_t1 +copyuser_p7 +copyuser_p7_vmx memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile index 42940f92d832..0c8efb0bddeb 100644 --- a/tools/testing/selftests/powerpc/copyloops/Makefile +++ b/tools/testing/selftests/powerpc/copyloops/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 TEST_GEN_PROGS := copyuser_64_t0 copyuser_64_t1 copyuser_64_t2 \ - copyuser_p7_t0 copyuser_p7_t1 \ + copyuser_p7 copyuser_p7_vmx \ memcpy_64_t0 memcpy_64_t1 memcpy_64_t2 \ memcpy_p7_t0 memcpy_p7_t1 copy_mc_64 \ copyuser_64_exc_t0 copyuser_64_exc_t1 copyuser_64_exc_t2 \ @@ -28,10 +28,15 @@ $(OUTPUT)/copyuser_64_t%: copyuser_64.S $(EXTRA_SOURCES) -D SELFTEST_CASE=$(subst copyuser_64_t,,$(notdir $@)) \ -o $@ $^ -$(OUTPUT)/copyuser_p7_t%: copyuser_power7.S $(EXTRA_SOURCES) +$(OUTPUT)/copyuser_p7: copyuser_power7.S $(EXTRA_SOURCES) $(CC) $(CPPFLAGS) $(CFLAGS) \ -D COPY_LOOP=test___copy_tofrom_user_power7 \ - -D SELFTEST_CASE=$(subst copyuser_p7_t,,$(notdir $@)) \ + -o $@ $^ + +$(OUTPUT)/copyuser_p7_vmx: copyuser_power7.S $(EXTRA_SOURCES) ../utils.c + $(CC) $(CPPFLAGS) $(CFLAGS) \ + -D COPY_LOOP=test___copy_tofrom_user_power7_vmx \ + -D VMX_TEST \ -o $@ $^ # Strictly speaking, we only need the memcpy_64 test cases for big-endian diff --git a/tools/testing/selftests/powerpc/copyloops/stubs.S b/tools/testing/selftests/powerpc/copyloops/stubs.S index ec8bcf2bf1c2..3a9cb8c9a3ee 100644 --- a/tools/testing/selftests/powerpc/copyloops/stubs.S +++ b/tools/testing/selftests/powerpc/copyloops/stubs.S @@ -1,13 +1,5 @@ #include -FUNC_START(enter_vmx_usercopy) - li r3,1 - blr - -FUNC_START(exit_vmx_usercopy) - li r3,0 - blr - FUNC_START(enter_vmx_ops) li r3,1 blr diff --git a/tools/testing/selftests/powerpc/copyloops/validate.c b/tools/testing/selftests/powerpc/copyloops/validate.c index 0f6873618552..fb822534fbe9 100644 --- a/tools/testing/selftests/powerpc/copyloops/validate.c +++ b/tools/testing/selftests/powerpc/copyloops/validate.c @@ -12,6 +12,10 @@ #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE) #define POISON 0xa5 +#ifdef VMX_TEST +#define VMX_COPY_THRESHOLD 3328 +#endif + unsigned long COPY_LOOP(void *to, const void *from, unsigned long size); static void do_one(char *src, char *dst, unsigned long src_off, @@ -81,8 +85,12 @@ int test_copy_loop(void) /* Fill with sequential bytes */ for (i = 0; i < BUFLEN; i++) fill[i] = i & 0xff; - +#ifdef VMX_TEST + /* Force sizes above kernel VMX threshold (3328) */ + for (len = VMX_COPY_THRESHOLD + 1; len < MAX_LEN; len++) { +#else for (len = 1; len < MAX_LEN; len++) { +#endif for (src_off = 0; src_off < MAX_OFFSET; src_off++) { for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) { do_one(src, dst, src_off, dst_off, len, @@ -96,5 +104,10 @@ int test_copy_loop(void) int main(void) { +#ifdef VMX_TEST + /* Skip if Altivec not present */ + SKIP_IF_MSG(!have_hwcap(PPC_FEATURE_HAS_ALTIVEC), "ALTIVEC not supported"); +#endif + return test_harness(test_copy_loop, str(COPY_LOOP)); } diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N index 07f5e0a70ae7..f943cdfb0a74 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-N @@ -2,7 +2,9 @@ CONFIG_RCU_TRACE=n CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_DYNAMIC=n +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n #CHECK#CONFIG_RCU_EXPERT=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T index c70cf0405f24..06e4d1030279 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-T @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U index bc9eeabaa1b1..71da6e3e9488 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U +++ b/tools/testing/selftests/rcutorture/configs/rcu/SRCU-U @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n @@ -7,4 +8,3 @@ CONFIG_PREEMPT_DYNAMIC=n CONFIG_RCU_TRACE=n CONFIG_DEBUG_LOCK_ALLOC=n CONFIG_DEBUG_OBJECTS_RCU_HEAD=n -CONFIG_PREEMPT_COUNT=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TASKS02 b/tools/testing/selftests/rcutorture/configs/rcu/TASKS02 index 2f9fcffff5ae..dd2bd4e08da4 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TASKS02 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TASKS02 @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY01 b/tools/testing/selftests/rcutorture/configs/rcu/TINY01 index 0953c52fcfd7..2be53bf60d65 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TINY01 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY01 @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n @@ -11,4 +12,3 @@ CONFIG_RCU_TRACE=n #CHECK#CONFIG_RCU_STALL_COMMON=n CONFIG_DEBUG_LOCK_ALLOC=n CONFIG_DEBUG_OBJECTS_RCU_HEAD=n -CONFIG_PREEMPT_COUNT=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TINY02 b/tools/testing/selftests/rcutorture/configs/rcu/TINY02 index 30439f6fc20e..be8860342ef7 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TINY02 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TINY02 @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 index 18efab346381..8fb124c28f28 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRACE01 @@ -1,7 +1,8 @@ CONFIG_SMP=y CONFIG_NR_CPUS=5 CONFIG_HOTPLUG_CPU=y -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE04 b/tools/testing/selftests/rcutorture/configs/rcu/TREE04 index 67caf4276bb0..ac857d5bcb22 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE04 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE04 @@ -1,10 +1,12 @@ CONFIG_SMP=y CONFIG_NR_CPUS=8 +CONFIG_PREEMPT_LAZY=y CONFIG_PREEMPT_NONE=n -CONFIG_PREEMPT_VOLUNTARY=y +CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n #CHECK#CONFIG_TREE_RCU=y +#CHECK#CONFIG_PREEMPT_RCU=n CONFIG_HZ_PERIODIC=n CONFIG_NO_HZ_IDLE=n CONFIG_NO_HZ_FULL=y diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE05 b/tools/testing/selftests/rcutorture/configs/rcu/TREE05 index 9f48c73709ec..61d15b1b54d1 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE05 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE05 @@ -1,6 +1,8 @@ CONFIG_SMP=y CONFIG_NR_CPUS=8 -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_DYNAMIC=n +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n #CHECK#CONFIG_TREE_RCU=y diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE06 b/tools/testing/selftests/rcutorture/configs/rcu/TREE06 index db27651de04b..0e090bb68a0f 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE06 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE06 @@ -1,9 +1,12 @@ CONFIG_SMP=y CONFIG_NR_CPUS=8 -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_DYNAMIC=n +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n #CHECK#CONFIG_TREE_RCU=y +#CHECK#CONFIG_PREEMPT_RCU=n CONFIG_HZ_PERIODIC=n CONFIG_NO_HZ_IDLE=y CONFIG_NO_HZ_FULL=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TREE10 b/tools/testing/selftests/rcutorture/configs/rcu/TREE10 index 420632b030dc..b2ce37861e71 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TREE10 +++ b/tools/testing/selftests/rcutorture/configs/rcu/TREE10 @@ -6,6 +6,7 @@ CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n #CHECK#CONFIG_TREE_RCU=y +CONFIG_PREEMPT_RCU=n CONFIG_HZ_PERIODIC=n CONFIG_NO_HZ_IDLE=y CONFIG_NO_HZ_FULL=n diff --git a/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL index 5d546efa68e8..696fba9968c6 100644 --- a/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL +++ b/tools/testing/selftests/rcutorture/configs/rcu/TRIVIAL @@ -1,6 +1,8 @@ CONFIG_SMP=y CONFIG_NR_CPUS=8 -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_DYNAMIC=n +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_HZ_PERIODIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcuscale/TINY b/tools/testing/selftests/rcutorture/configs/rcuscale/TINY index 0fa2dc086e10..c1a7d38823fb 100644 --- a/tools/testing/selftests/rcutorture/configs/rcuscale/TINY +++ b/tools/testing/selftests/rcutorture/configs/rcuscale/TINY @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/rcuscale/TRACE01 b/tools/testing/selftests/rcutorture/configs/rcuscale/TRACE01 index 0059592c7408..f3f1368b8386 100644 --- a/tools/testing/selftests/rcutorture/configs/rcuscale/TRACE01 +++ b/tools/testing/selftests/rcutorture/configs/rcuscale/TRACE01 @@ -1,5 +1,6 @@ CONFIG_SMP=y -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/refscale/NOPREEMPT b/tools/testing/selftests/rcutorture/configs/refscale/NOPREEMPT index 67f9d2998afd..1f215e17cbae 100644 --- a/tools/testing/selftests/rcutorture/configs/refscale/NOPREEMPT +++ b/tools/testing/selftests/rcutorture/configs/refscale/NOPREEMPT @@ -1,5 +1,6 @@ CONFIG_SMP=y -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/refscale/TINY b/tools/testing/selftests/rcutorture/configs/refscale/TINY index 759343980b80..9a11b578ff34 100644 --- a/tools/testing/selftests/rcutorture/configs/refscale/TINY +++ b/tools/testing/selftests/rcutorture/configs/refscale/TINY @@ -1,5 +1,6 @@ CONFIG_SMP=n -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/rcutorture/configs/scf/NOPREEMPT b/tools/testing/selftests/rcutorture/configs/scf/NOPREEMPT index 6133f54ce2a7..f9621e2770a4 100644 --- a/tools/testing/selftests/rcutorture/configs/scf/NOPREEMPT +++ b/tools/testing/selftests/rcutorture/configs/scf/NOPREEMPT @@ -1,5 +1,6 @@ CONFIG_SMP=y -CONFIG_PREEMPT_NONE=y +CONFIG_PREEMPT_LAZY=y +CONFIG_PREEMPT_NONE=n CONFIG_PREEMPT_VOLUNTARY=n CONFIG_PREEMPT=n CONFIG_PREEMPT_DYNAMIC=n diff --git a/tools/testing/selftests/sched_ext/Makefile b/tools/testing/selftests/sched_ext/Makefile index 2c601a7eaff5..006300ac6dff 100644 --- a/tools/testing/selftests/sched_ext/Makefile +++ b/tools/testing/selftests/sched_ext/Makefile @@ -93,6 +93,8 @@ BPF_CFLAGS = -g -D__TARGET_ARCH_$(SRCARCH) \ $(CLANG_SYS_INCLUDES) \ -Wall -Wno-compare-distinct-pointer-types \ -Wno-incompatible-function-pointer-types \ + -Wno-microsoft-anon-tag \ + -fms-extensions \ -O2 -mcpu=v3 # sort removes libbpf duplicates when not cross-building diff --git a/tools/testing/selftests/sched_ext/init_enable_count.c b/tools/testing/selftests/sched_ext/init_enable_count.c index 82c71653977b..44577e30e764 100644 --- a/tools/testing/selftests/sched_ext/init_enable_count.c +++ b/tools/testing/selftests/sched_ext/init_enable_count.c @@ -57,7 +57,8 @@ static enum scx_test_status run_test(bool global) char buf; close(pipe_fds[1]); - read(pipe_fds[0], &buf, 1); + if (read(pipe_fds[0], &buf, 1) < 0) + exit(1); close(pipe_fds[0]); exit(0); } diff --git a/tools/testing/selftests/sched_ext/peek_dsq.bpf.c b/tools/testing/selftests/sched_ext/peek_dsq.bpf.c index a3faf5bb49d6..784f2f6c1af9 100644 --- a/tools/testing/selftests/sched_ext/peek_dsq.bpf.c +++ b/tools/testing/selftests/sched_ext/peek_dsq.bpf.c @@ -58,14 +58,14 @@ static void record_peek_result(long pid) { u32 slot_key; long *slot_pid_ptr; - int ix; + u32 ix; if (pid <= 0) return; /* Find an empty slot or one with the same PID */ bpf_for(ix, 0, 10) { - slot_key = (pid + ix) % MAX_SAMPLES; + slot_key = ((u64)pid + ix) % MAX_SAMPLES; slot_pid_ptr = bpf_map_lookup_elem(&peek_results, &slot_key); if (!slot_pid_ptr) continue; diff --git a/tools/testing/selftests/sched_ext/rt_stall.c b/tools/testing/selftests/sched_ext/rt_stall.c index 015200f80f6e..81ea9b4883e5 100644 --- a/tools/testing/selftests/sched_ext/rt_stall.c +++ b/tools/testing/selftests/sched_ext/rt_stall.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "rt_stall.bpf.skel.h" #include "scx_test.h" #include "../kselftest.h" @@ -23,6 +22,30 @@ #define CORE_ID 0 /* CPU to pin tasks to */ #define RUN_TIME 5 /* How long to run the test in seconds */ +/* Signal the parent that setup is complete by writing to a pipe */ +static void signal_ready(int fd) +{ + char c = 1; + + if (write(fd, &c, 1) != 1) { + perror("write to ready pipe"); + exit(EXIT_FAILURE); + } + close(fd); +} + +/* Wait for a child to signal readiness via a pipe */ +static void wait_ready(int fd) +{ + char c; + + if (read(fd, &c, 1) != 1) { + perror("read from ready pipe"); + exit(EXIT_FAILURE); + } + close(fd); +} + /* Simple busy-wait function for test tasks */ static void process_func(void) { @@ -122,14 +145,24 @@ static bool sched_stress_test(bool is_ext) float ext_runtime, rt_runtime, actual_ratio; int ext_pid, rt_pid; + int ext_ready[2], rt_ready[2]; ksft_print_header(); ksft_set_plan(1); + if (pipe(ext_ready) || pipe(rt_ready)) { + perror("pipe"); + ksft_exit_fail(); + } + /* Create and set up a EXT task */ ext_pid = fork(); if (ext_pid == 0) { + close(ext_ready[0]); + close(rt_ready[0]); + close(rt_ready[1]); set_affinity(CORE_ID); + signal_ready(ext_ready[1]); process_func(); exit(0); } else if (ext_pid < 0) { @@ -140,8 +173,12 @@ static bool sched_stress_test(bool is_ext) /* Create an RT task */ rt_pid = fork(); if (rt_pid == 0) { + close(ext_ready[0]); + close(ext_ready[1]); + close(rt_ready[0]); set_affinity(CORE_ID); set_sched(SCHED_FIFO, 50); + signal_ready(rt_ready[1]); process_func(); exit(0); } else if (rt_pid < 0) { @@ -149,6 +186,17 @@ static bool sched_stress_test(bool is_ext) ksft_exit_fail(); } + /* + * Wait for both children to complete their setup (affinity and + * scheduling policy) before starting the measurement window. + * This prevents flaky failures caused by the RT child's setup + * time eating into the measurement period. + */ + close(ext_ready[1]); + close(rt_ready[1]); + wait_ready(ext_ready[0]); + wait_ready(rt_ready[0]); + /* Let the processes run for the specified time */ sleep(RUN_TIME); diff --git a/tools/testing/selftests/sched_ext/runner.c b/tools/testing/selftests/sched_ext/runner.c index 5748d2c69903..761c21f96404 100644 --- a/tools/testing/selftests/sched_ext/runner.c +++ b/tools/testing/selftests/sched_ext/runner.c @@ -166,6 +166,9 @@ int main(int argc, char **argv) enum scx_test_status status; struct scx_test *test = &__scx_tests[i]; + if (exit_req) + break; + if (list) { printf("%s\n", test->name); if (i == (__scx_num_tests - 1)) diff --git a/tools/testing/selftests/sched_ext/util.c b/tools/testing/selftests/sched_ext/util.c index e47769c91918..2111329ed289 100644 --- a/tools/testing/selftests/sched_ext/util.c +++ b/tools/testing/selftests/sched_ext/util.c @@ -60,11 +60,11 @@ int file_write_long(const char *path, long val) char buf[64]; int ret; - ret = sprintf(buf, "%lu", val); + ret = sprintf(buf, "%ld", val); if (ret < 0) return ret; - if (write_text(path, buf, sizeof(buf)) <= 0) + if (write_text(path, buf, ret) <= 0) return -1; return 0; diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json b/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json index 7d07c55bb668..33bb8f3ff8ed 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/ct.json @@ -505,5 +505,164 @@ "teardown": [ "$TC qdisc del dev $DEV1 ingress" ] + }, + { + "id": "8883", + "name": "Try to attach act_ct to an ets qdisc", + "category": [ + "actions", + "ct" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ct", + 0, + 1, + 255 + ], + "$TC qdisc add dev $DEV1 root handle 1: ets bands 2" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 parent 1: prio 1 protocol ip matchall action ct index 42", + "expExitCode": "2", + "verifyCmd": "$TC -j filter ls dev $DEV1 parent 1: prio 1 protocol ip", + "matchJSON": [], + "teardown": [ + "$TC qdisc del dev $DEV1 root" + ] + }, + { + "id": "3b10", + "name": "Attach act_ct to an ingress qdisc", + "category": [ + "actions", + "ct" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ct", + 0, + 1, + 255 + ], + "$TC qdisc add dev $DEV1 ingress" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 ingress prio 1 protocol ip matchall action ct index 42", + "expExitCode": "0", + "verifyCmd": "$TC -j filter ls dev $DEV1 ingress prio 1 protocol ip", + "matchJSON": [ + { + "kind": "matchall" + }, + { + "options": { + "actions": [ + { + "order": 1, + "kind": "ct", + "index": 42, + "ref": 1, + "bind": 1 + } + ] + } + } + ], + "teardown": [ + "$TC qdisc del dev $DEV1 ingress" + ] + }, + { + "id": "0337", + "name": "Attach act_ct to a clsact/egress qdisc", + "category": [ + "actions", + "ct" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ct", + 0, + 1, + 255 + ], + "$TC qdisc add dev $DEV1 clsact" + ], + "cmdUnderTest": "$TC filter add dev $DEV1 egress prio 1 protocol ip matchall action ct index 42", + "expExitCode": "0", + "verifyCmd": "$TC -j filter ls dev $DEV1 egress prio 1 protocol ip", + "matchJSON": [ + { + "kind": "matchall" + }, + { + "options": { + "actions": [ + { + "order": 1, + "kind": "ct", + "index": 42, + "ref": 1, + "bind": 1 + } + ] + } + } + ], + "teardown": [ + "$TC qdisc del dev $DEV1 clsact" + ] + }, + { + "id": "4f60", + "name": "Attach act_ct to a shared block", + "category": [ + "actions", + "ct" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ct", + 0, + 1, + 255 + ], + "$TC qdisc add dev $DEV1 ingress_block 21 clsact" + ], + "cmdUnderTest": "$TC filter add block 21 prio 1 protocol ip matchall action ct index 42", + "expExitCode": "0", + "verifyCmd": "$TC -j filter ls block 21 prio 1 protocol ip", + "matchJSON": [ + { + "kind": "matchall" + }, + { + "options": { + "actions": [ + { + "order": 1, + "kind": "ct", + "index": 42, + "ref": 1, + "bind": 1 + } + ] + } + } + ], + "teardown": [ + "$TC qdisc del dev $DEV1 ingress_block 21 clsact" + ] } ] diff --git a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json index f587a32e44c4..808aef4afe22 100644 --- a/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json +++ b/tools/testing/selftests/tc-testing/tc-tests/actions/ife.json @@ -1279,5 +1279,104 @@ "teardown": [ "$TC actions flush action ife" ] + }, + { + "id": "f2a0", + "name": "Update decode ife action with encode metadata", + "category": [ + "actions", + "ife" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ife", + 0, + 1, + 255 + ], + "$TC actions add action ife decode index 10" + ], + "cmdUnderTest": "$TC actions replace action ife encode use tcindex 1 index 10", + "expExitCode": "0", + "verifyCmd": "$TC -j actions get action ife index 10", + "matchJSON": [ + { + "total acts": 0 + }, + { + "actions": [ + { + "order": 1, + "kind": "ife", + "mode": "encode", + "control_action": { + "type": "pipe" + }, + "type": "0xed3e", + "tcindex": 1, + "index": 10, + "ref": 1, + "bind": 0, + "not_in_hw": true + } + ] + } + ], + "teardown": [ + "$TC actions flush action ife" + ] + }, + { + "id": "d352", + "name": "Update decode ife action into encode with multiple metadata", + "category": [ + "actions", + "ife" + ], + "plugins": { + "requires": "nsPlugin" + }, + "setup": [ + [ + "$TC actions flush action ife", + 0, + 1, + 255 + ], + "$TC actions add action ife decode index 10" + ], + "cmdUnderTest": "$TC actions replace action ife encode use tcindex 1 use mark 22 index 10", + "expExitCode": "0", + "verifyCmd": "$TC -j actions get action ife index 10", + "matchJSON": [ + { + "total acts": 0 + }, + { + "actions": [ + { + "order": 1, + "kind": "ife", + "mode": "encode", + "control_action": { + "type": "pipe" + }, + "type": "0xed3e", + "tcindex": 1, + "mark": 22, + "index": 10, + "ref": 1, + "bind": 0, + "not_in_hw": true + } + ] + } + ], + "teardown": [ + "$TC actions flush action ife" + ] } ] diff --git a/tools/testing/selftests/tc-testing/tdc_helper.py b/tools/testing/selftests/tc-testing/tdc_helper.py index 0440d252c4c5..bc447ca57333 100644 --- a/tools/testing/selftests/tc-testing/tdc_helper.py +++ b/tools/testing/selftests/tc-testing/tdc_helper.py @@ -38,10 +38,14 @@ def list_test_cases(testlist): def list_categories(testlist): - """ Show all categories that are present in a test case file. """ - categories = set(map(lambda x: x['category'], testlist)) + """Show all unique categories present in the test cases.""" + categories = set() + for t in testlist: + if 'category' in t: + categories.update(t['category']) + print("Available categories:") - print(", ".join(str(s) for s in categories)) + print(", ".join(sorted(categories))) print("") diff --git a/tools/testing/selftests/vsock/vmtest.sh b/tools/testing/selftests/vsock/vmtest.sh index dc8dbe74a6d0..86e338886b33 100755 --- a/tools/testing/selftests/vsock/vmtest.sh +++ b/tools/testing/selftests/vsock/vmtest.sh @@ -210,16 +210,21 @@ check_result() { } add_namespaces() { - local orig_mode - orig_mode=$(cat /proc/sys/net/vsock/child_ns_mode) + ip netns add "global-parent" 2>/dev/null + echo "global" | ip netns exec "global-parent" \ + tee /proc/sys/net/vsock/child_ns_mode &>/dev/null + ip netns add "local-parent" 2>/dev/null + echo "local" | ip netns exec "local-parent" \ + tee /proc/sys/net/vsock/child_ns_mode &>/dev/null - for mode in "${NS_MODES[@]}"; do - echo "${mode}" > /proc/sys/net/vsock/child_ns_mode - ip netns add "${mode}0" 2>/dev/null - ip netns add "${mode}1" 2>/dev/null - done - - echo "${orig_mode}" > /proc/sys/net/vsock/child_ns_mode + nsenter --net=/var/run/netns/global-parent \ + ip netns add "global0" 2>/dev/null + nsenter --net=/var/run/netns/global-parent \ + ip netns add "global1" 2>/dev/null + nsenter --net=/var/run/netns/local-parent \ + ip netns add "local0" 2>/dev/null + nsenter --net=/var/run/netns/local-parent \ + ip netns add "local1" 2>/dev/null } init_namespaces() { @@ -237,6 +242,8 @@ del_namespaces() { log_host "removed ns ${mode}0" log_host "removed ns ${mode}1" done + ip netns del "global-parent" &>/dev/null + ip netns del "local-parent" &>/dev/null } vm_ssh() { @@ -287,7 +294,7 @@ check_args() { } check_deps() { - for dep in vng ${QEMU} busybox pkill ssh ss socat; do + for dep in vng ${QEMU} busybox pkill ssh ss socat nsenter; do if [[ ! -x $(command -v "${dep}") ]]; then echo -e "skip: dependency ${dep} not found!\n" exit "${KSFT_SKIP}" @@ -1231,12 +1238,8 @@ test_ns_local_same_cid_ok() { } test_ns_host_vsock_child_ns_mode_ok() { - local orig_mode - local rc + local rc="${KSFT_PASS}" - orig_mode=$(cat /proc/sys/net/vsock/child_ns_mode) - - rc="${KSFT_PASS}" for mode in "${NS_MODES[@]}"; do local ns="${mode}0" @@ -1246,15 +1249,13 @@ test_ns_host_vsock_child_ns_mode_ok() { continue fi - if ! echo "${mode}" > /proc/sys/net/vsock/child_ns_mode; then - log_host "child_ns_mode should be writable to ${mode}" + if ! echo "${mode}" | ip netns exec "${ns}" \ + tee /proc/sys/net/vsock/child_ns_mode &>/dev/null; then rc="${KSFT_FAIL}" continue fi done - echo "${orig_mode}" > /proc/sys/net/vsock/child_ns_mode - return "${rc}" } diff --git a/tools/testing/vma/Makefile b/tools/testing/vma/Makefile index 66f3831a668f..e72b45dedda5 100644 --- a/tools/testing/vma/Makefile +++ b/tools/testing/vma/Makefile @@ -6,10 +6,13 @@ default: vma include ../shared/shared.mk -OFILES = $(SHARED_OFILES) vma.o maple-shim.o +OFILES = $(SHARED_OFILES) main.o shared.o maple-shim.o TARGETS = vma -vma.o: vma.c vma_internal.h ../../../mm/vma.c ../../../mm/vma_init.c ../../../mm/vma_exec.c ../../../mm/vma.h +# These can be varied to test different sizes. +CFLAGS += -DNUM_VMA_FLAG_BITS=128 -DNUM_MM_FLAG_BITS=128 + +main.o: main.c shared.c shared.h vma_internal.h tests/merge.c tests/mmap.c tests/vma.c ../../../mm/vma.c ../../../mm/vma_init.c ../../../mm/vma_exec.c ../../../mm/vma.h include/custom.h include/dup.h include/stubs.h vma: $(OFILES) $(CC) $(CFLAGS) -o $@ $(OFILES) $(LDLIBS) diff --git a/tools/testing/vma/include/custom.h b/tools/testing/vma/include/custom.h new file mode 100644 index 000000000000..802a76317245 --- /dev/null +++ b/tools/testing/vma/include/custom.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#pragma once + +/* + * Contains declarations that exist in the kernel which have been CUSTOMISED for + * testing purposes to faciliate userland VMA testing. + */ + +#ifdef CONFIG_MMU +extern unsigned long mmap_min_addr; +extern unsigned long dac_mmap_min_addr; +#else +#define mmap_min_addr 0UL +#define dac_mmap_min_addr 0UL +#endif + +#define VM_WARN_ON(_expr) (WARN_ON(_expr)) +#define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr)) +#define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr)) +#define VM_BUG_ON(_expr) (BUG_ON(_expr)) +#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr)) + +/* We hardcode this for now. */ +#define sysctl_max_map_count 0x1000000UL + +#define TASK_SIZE ((1ul << 47)-PAGE_SIZE) + +/* + * The shared stubs do not implement this, it amounts to an fprintf(STDERR,...) + * either way :) + */ +#define pr_warn_once pr_err + +#define pgtable_supports_soft_dirty() 1 + +struct anon_vma { + struct anon_vma *root; + struct rb_root_cached rb_root; + + /* Test fields. */ + bool was_cloned; + bool was_unlinked; +}; + +static inline void unlink_anon_vmas(struct vm_area_struct *vma) +{ + /* For testing purposes, indicate that the anon_vma was unlinked. */ + vma->anon_vma->was_unlinked = true; +} + +static inline void vma_start_write(struct vm_area_struct *vma) +{ + /* Used to indicate to tests that a write operation has begun. */ + vma->vm_lock_seq++; +} + +static inline __must_check +int vma_start_write_killable(struct vm_area_struct *vma) +{ + /* Used to indicate to tests that a write operation has begun. */ + vma->vm_lock_seq++; + return 0; +} + +static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src, + enum vma_operation operation) +{ + /* For testing purposes. We indicate that an anon_vma has been cloned. */ + if (src->anon_vma != NULL) { + dst->anon_vma = src->anon_vma; + dst->anon_vma->was_cloned = true; + } + + return 0; +} + +static inline int __anon_vma_prepare(struct vm_area_struct *vma) +{ + struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma)); + + if (!anon_vma) + return -ENOMEM; + + anon_vma->root = anon_vma; + vma->anon_vma = anon_vma; + + return 0; +} + +static inline int anon_vma_prepare(struct vm_area_struct *vma) +{ + if (likely(vma->anon_vma)) + return 0; + + return __anon_vma_prepare(vma); +} + +static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt) +{ + if (reset_refcnt) + refcount_set(&vma->vm_refcnt, 0); +} + +static inline vma_flags_t __mk_vma_flags(size_t count, const vma_flag_t *bits) +{ + vma_flags_t flags; + int i; + + /* + * For testing purposes: allow invalid bit specification so we can + * easily test. + */ + vma_flags_clear_all(&flags); + for (i = 0; i < count; i++) + if (bits[i] < NUM_VMA_FLAG_BITS) + vma_flag_set(&flags, bits[i]); + return flags; +} diff --git a/tools/testing/vma/include/dup.h b/tools/testing/vma/include/dup.h new file mode 100644 index 000000000000..3078ff1487d3 --- /dev/null +++ b/tools/testing/vma/include/dup.h @@ -0,0 +1,1320 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#pragma once + +/* Forward declarations to avoid header cycle. */ +struct vm_area_struct; +static inline void vma_start_write(struct vm_area_struct *vma); + +extern const struct vm_operations_struct vma_dummy_vm_ops; +extern unsigned long stack_guard_gap; +extern const struct vm_operations_struct vma_dummy_vm_ops; +extern unsigned long rlimit(unsigned int limit); +struct task_struct *get_current(void); + +#define MMF_HAS_MDWE 28 +#define current get_current() + +/* + * Define the task command name length as enum, then it can be visible to + * BPF programs. + */ +enum { + TASK_COMM_LEN = 16, +}; + +/* PARTIALLY implemented types. */ +struct mm_struct { + struct maple_tree mm_mt; + int map_count; /* number of VMAs */ + unsigned long total_vm; /* Total pages mapped */ + unsigned long locked_vm; /* Pages that have PG_mlocked set */ + unsigned long data_vm; /* VM_WRITE & ~VM_SHARED & ~VM_STACK */ + unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE & ~VM_STACK */ + unsigned long stack_vm; /* VM_STACK */ + + unsigned long def_flags; + + mm_flags_t flags; /* Must use mm_flags_* helpers to access */ +}; +struct address_space { + struct rb_root_cached i_mmap; + unsigned long flags; + atomic_t i_mmap_writable; +}; +struct file_operations { + int (*mmap)(struct file *, struct vm_area_struct *); + int (*mmap_prepare)(struct vm_area_desc *); +}; +struct file { + struct address_space *f_mapping; + const struct file_operations *f_op; +}; +struct anon_vma_chain { + struct anon_vma *anon_vma; + struct list_head same_vma; +}; +struct task_struct { + char comm[TASK_COMM_LEN]; + pid_t pid; + struct mm_struct *mm; + + /* Used for emulating ABI behavior of previous Linux versions: */ + unsigned int personality; +}; + +struct kref { + refcount_t refcount; +}; + +struct anon_vma_name { + struct kref kref; + /* The name needs to be at the end because it is dynamically sized. */ + char name[]; +}; + +/* + * Contains declarations that are DUPLICATED from kernel source in order to + * faciliate userland VMA testing. + * + * These must be kept in sync with kernel source. + */ + +#define VMA_LOCK_OFFSET 0x40000000 + +typedef struct { unsigned long v; } freeptr_t; + +#define VM_NONE 0x00000000 + +typedef int __bitwise vma_flag_t; + +#define ACCESS_PRIVATE(p, member) ((p)->member) + +#define DECLARE_VMA_BIT(name, bitnum) \ + VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum) +#define DECLARE_VMA_BIT_ALIAS(name, aliased) \ + VMA_ ## name ## _BIT = VMA_ ## aliased ## _BIT +enum { + DECLARE_VMA_BIT(READ, 0), + DECLARE_VMA_BIT(WRITE, 1), + DECLARE_VMA_BIT(EXEC, 2), + DECLARE_VMA_BIT(SHARED, 3), + /* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */ + DECLARE_VMA_BIT(MAYREAD, 4), /* limits for mprotect() etc. */ + DECLARE_VMA_BIT(MAYWRITE, 5), + DECLARE_VMA_BIT(MAYEXEC, 6), + DECLARE_VMA_BIT(MAYSHARE, 7), + DECLARE_VMA_BIT(GROWSDOWN, 8), /* general info on the segment */ +#ifdef CONFIG_MMU + DECLARE_VMA_BIT(UFFD_MISSING, 9),/* missing pages tracking */ +#else + /* nommu: R/O MAP_PRIVATE mapping that might overlay a file mapping */ + DECLARE_VMA_BIT(MAYOVERLAY, 9), +#endif /* CONFIG_MMU */ + /* Page-ranges managed without "struct page", just pure PFN */ + DECLARE_VMA_BIT(PFNMAP, 10), + DECLARE_VMA_BIT(MAYBE_GUARD, 11), + DECLARE_VMA_BIT(UFFD_WP, 12), /* wrprotect pages tracking */ + DECLARE_VMA_BIT(LOCKED, 13), + DECLARE_VMA_BIT(IO, 14), /* Memory mapped I/O or similar */ + DECLARE_VMA_BIT(SEQ_READ, 15), /* App will access data sequentially */ + DECLARE_VMA_BIT(RAND_READ, 16), /* App will not benefit from clustered reads */ + DECLARE_VMA_BIT(DONTCOPY, 17), /* Do not copy this vma on fork */ + DECLARE_VMA_BIT(DONTEXPAND, 18),/* Cannot expand with mremap() */ + DECLARE_VMA_BIT(LOCKONFAULT, 19),/* Lock pages covered when faulted in */ + DECLARE_VMA_BIT(ACCOUNT, 20), /* Is a VM accounted object */ + DECLARE_VMA_BIT(NORESERVE, 21), /* should the VM suppress accounting */ + DECLARE_VMA_BIT(HUGETLB, 22), /* Huge TLB Page VM */ + DECLARE_VMA_BIT(SYNC, 23), /* Synchronous page faults */ + DECLARE_VMA_BIT(ARCH_1, 24), /* Architecture-specific flag */ + DECLARE_VMA_BIT(WIPEONFORK, 25),/* Wipe VMA contents in child. */ + DECLARE_VMA_BIT(DONTDUMP, 26), /* Do not include in the core dump */ + DECLARE_VMA_BIT(SOFTDIRTY, 27), /* NOT soft dirty clean area */ + DECLARE_VMA_BIT(MIXEDMAP, 28), /* Can contain struct page and pure PFN pages */ + DECLARE_VMA_BIT(HUGEPAGE, 29), /* MADV_HUGEPAGE marked this vma */ + DECLARE_VMA_BIT(NOHUGEPAGE, 30),/* MADV_NOHUGEPAGE marked this vma */ + DECLARE_VMA_BIT(MERGEABLE, 31), /* KSM may merge identical pages */ + /* These bits are reused, we define specific uses below. */ + DECLARE_VMA_BIT(HIGH_ARCH_0, 32), + DECLARE_VMA_BIT(HIGH_ARCH_1, 33), + DECLARE_VMA_BIT(HIGH_ARCH_2, 34), + DECLARE_VMA_BIT(HIGH_ARCH_3, 35), + DECLARE_VMA_BIT(HIGH_ARCH_4, 36), + DECLARE_VMA_BIT(HIGH_ARCH_5, 37), + DECLARE_VMA_BIT(HIGH_ARCH_6, 38), + /* + * This flag is used to connect VFIO to arch specific KVM code. It + * indicates that the memory under this VMA is safe for use with any + * non-cachable memory type inside KVM. Some VFIO devices, on some + * platforms, are thought to be unsafe and can cause machine crashes + * if KVM does not lock down the memory type. + */ + DECLARE_VMA_BIT(ALLOW_ANY_UNCACHED, 39), +#ifdef CONFIG_PPC32 + DECLARE_VMA_BIT_ALIAS(DROPPABLE, ARCH_1), +#else + DECLARE_VMA_BIT(DROPPABLE, 40), +#endif + DECLARE_VMA_BIT(UFFD_MINOR, 41), + DECLARE_VMA_BIT(SEALED, 42), + /* Flags that reuse flags above. */ + DECLARE_VMA_BIT_ALIAS(PKEY_BIT0, HIGH_ARCH_0), + DECLARE_VMA_BIT_ALIAS(PKEY_BIT1, HIGH_ARCH_1), + DECLARE_VMA_BIT_ALIAS(PKEY_BIT2, HIGH_ARCH_2), + DECLARE_VMA_BIT_ALIAS(PKEY_BIT3, HIGH_ARCH_3), + DECLARE_VMA_BIT_ALIAS(PKEY_BIT4, HIGH_ARCH_4), +#if defined(CONFIG_X86_USER_SHADOW_STACK) + /* + * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of + * support core mm. + * + * These VMAs will get a single end guard page. This helps userspace + * protect itself from attacks. A single page is enough for current + * shadow stack archs (x86). See the comments near alloc_shstk() in + * arch/x86/kernel/shstk.c for more details on the guard size. + */ + DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_5), +#elif defined(CONFIG_ARM64_GCS) + /* + * arm64's Guarded Control Stack implements similar functionality and + * has similar constraints to shadow stacks. + */ + DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_6), +#endif + DECLARE_VMA_BIT_ALIAS(SAO, ARCH_1), /* Strong Access Ordering (powerpc) */ + DECLARE_VMA_BIT_ALIAS(GROWSUP, ARCH_1), /* parisc */ + DECLARE_VMA_BIT_ALIAS(SPARC_ADI, ARCH_1), /* sparc64 */ + DECLARE_VMA_BIT_ALIAS(ARM64_BTI, ARCH_1), /* arm64 */ + DECLARE_VMA_BIT_ALIAS(ARCH_CLEAR, ARCH_1), /* sparc64, arm64 */ + DECLARE_VMA_BIT_ALIAS(MAPPED_COPY, ARCH_1), /* !CONFIG_MMU */ + DECLARE_VMA_BIT_ALIAS(MTE, HIGH_ARCH_4), /* arm64 */ + DECLARE_VMA_BIT_ALIAS(MTE_ALLOWED, HIGH_ARCH_5),/* arm64 */ +#ifdef CONFIG_STACK_GROWSUP + DECLARE_VMA_BIT_ALIAS(STACK, GROWSUP), + DECLARE_VMA_BIT_ALIAS(STACK_EARLY, GROWSDOWN), +#else + DECLARE_VMA_BIT_ALIAS(STACK, GROWSDOWN), +#endif +}; + +#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT) +#define VM_READ INIT_VM_FLAG(READ) +#define VM_WRITE INIT_VM_FLAG(WRITE) +#define VM_EXEC INIT_VM_FLAG(EXEC) +#define VM_SHARED INIT_VM_FLAG(SHARED) +#define VM_MAYREAD INIT_VM_FLAG(MAYREAD) +#define VM_MAYWRITE INIT_VM_FLAG(MAYWRITE) +#define VM_MAYEXEC INIT_VM_FLAG(MAYEXEC) +#define VM_MAYSHARE INIT_VM_FLAG(MAYSHARE) +#define VM_GROWSDOWN INIT_VM_FLAG(GROWSDOWN) +#ifdef CONFIG_MMU +#define VM_UFFD_MISSING INIT_VM_FLAG(UFFD_MISSING) +#else +#define VM_UFFD_MISSING VM_NONE +#define VM_MAYOVERLAY INIT_VM_FLAG(MAYOVERLAY) +#endif +#define VM_PFNMAP INIT_VM_FLAG(PFNMAP) +#define VM_MAYBE_GUARD INIT_VM_FLAG(MAYBE_GUARD) +#define VM_UFFD_WP INIT_VM_FLAG(UFFD_WP) +#define VM_LOCKED INIT_VM_FLAG(LOCKED) +#define VM_IO INIT_VM_FLAG(IO) +#define VM_SEQ_READ INIT_VM_FLAG(SEQ_READ) +#define VM_RAND_READ INIT_VM_FLAG(RAND_READ) +#define VM_DONTCOPY INIT_VM_FLAG(DONTCOPY) +#define VM_DONTEXPAND INIT_VM_FLAG(DONTEXPAND) +#define VM_LOCKONFAULT INIT_VM_FLAG(LOCKONFAULT) +#define VM_ACCOUNT INIT_VM_FLAG(ACCOUNT) +#define VM_NORESERVE INIT_VM_FLAG(NORESERVE) +#define VM_HUGETLB INIT_VM_FLAG(HUGETLB) +#define VM_SYNC INIT_VM_FLAG(SYNC) +#define VM_ARCH_1 INIT_VM_FLAG(ARCH_1) +#define VM_WIPEONFORK INIT_VM_FLAG(WIPEONFORK) +#define VM_DONTDUMP INIT_VM_FLAG(DONTDUMP) +#ifdef CONFIG_MEM_SOFT_DIRTY +#define VM_SOFTDIRTY INIT_VM_FLAG(SOFTDIRTY) +#else +#define VM_SOFTDIRTY VM_NONE +#endif +#define VM_MIXEDMAP INIT_VM_FLAG(MIXEDMAP) +#define VM_HUGEPAGE INIT_VM_FLAG(HUGEPAGE) +#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE) +#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE) +#define VM_STACK INIT_VM_FLAG(STACK) +#ifdef CONFIG_STACK_GROWS_UP +#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY) +#else +#define VM_STACK_EARLY VM_NONE +#endif +#ifdef CONFIG_ARCH_HAS_PKEYS +#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT) +/* Despite the naming, these are FLAGS not bits. */ +#define VM_PKEY_BIT0 INIT_VM_FLAG(PKEY_BIT0) +#define VM_PKEY_BIT1 INIT_VM_FLAG(PKEY_BIT1) +#define VM_PKEY_BIT2 INIT_VM_FLAG(PKEY_BIT2) +#if CONFIG_ARCH_PKEY_BITS > 3 +#define VM_PKEY_BIT3 INIT_VM_FLAG(PKEY_BIT3) +#else +#define VM_PKEY_BIT3 VM_NONE +#endif /* CONFIG_ARCH_PKEY_BITS > 3 */ +#if CONFIG_ARCH_PKEY_BITS > 4 +#define VM_PKEY_BIT4 INIT_VM_FLAG(PKEY_BIT4) +#else +#define VM_PKEY_BIT4 VM_NONE +#endif /* CONFIG_ARCH_PKEY_BITS > 4 */ +#endif /* CONFIG_ARCH_HAS_PKEYS */ +#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS) +#define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK) +#else +#define VM_SHADOW_STACK VM_NONE +#endif +#if defined(CONFIG_PPC64) +#define VM_SAO INIT_VM_FLAG(SAO) +#elif defined(CONFIG_PARISC) +#define VM_GROWSUP INIT_VM_FLAG(GROWSUP) +#elif defined(CONFIG_SPARC64) +#define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI) +#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR) +#elif defined(CONFIG_ARM64) +#define VM_ARM64_BTI INIT_VM_FLAG(ARM64_BTI) +#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR) +#elif !defined(CONFIG_MMU) +#define VM_MAPPED_COPY INIT_VM_FLAG(MAPPED_COPY) +#endif +#ifndef VM_GROWSUP +#define VM_GROWSUP VM_NONE +#endif +#ifdef CONFIG_ARM64_MTE +#define VM_MTE INIT_VM_FLAG(MTE) +#define VM_MTE_ALLOWED INIT_VM_FLAG(MTE_ALLOWED) +#else +#define VM_MTE VM_NONE +#define VM_MTE_ALLOWED VM_NONE +#endif +#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR +#define VM_UFFD_MINOR INIT_VM_FLAG(UFFD_MINOR) +#else +#define VM_UFFD_MINOR VM_NONE +#endif +#ifdef CONFIG_64BIT +#define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED) +#define VM_SEALED INIT_VM_FLAG(SEALED) +#else +#define VM_ALLOW_ANY_UNCACHED VM_NONE +#define VM_SEALED VM_NONE +#endif +#if defined(CONFIG_64BIT) || defined(CONFIG_PPC32) +#define VM_DROPPABLE INIT_VM_FLAG(DROPPABLE) +#else +#define VM_DROPPABLE VM_NONE +#endif + +/* Bits set in the VMA until the stack is in its final location */ +#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY) + +#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) + +/* Common data flag combinations */ +#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_FLAGS_NON_EXEC (VM_READ | VM_WRITE | VM_MAYREAD | \ + VM_MAYWRITE | VM_MAYEXEC) +#define VM_DATA_FLAGS_EXEC (VM_READ | VM_WRITE | VM_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#ifndef VM_DATA_DEFAULT_FLAGS /* arch can override this */ +#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_EXEC +#endif + +#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ +#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS +#endif + +#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK) + +#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT) + +/* VMA basic access permission flags */ +#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC) + +/* + * Special vmas that are non-mergable, non-mlock()able. + */ +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) + +#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) +#define TASK_SIZE_LOW DEFAULT_MAP_WINDOW +#define TASK_SIZE_MAX DEFAULT_MAP_WINDOW +#define STACK_TOP TASK_SIZE_LOW +#define STACK_TOP_MAX TASK_SIZE_MAX + +/* This mask represents all the VMA flag bits used by mlock */ +#define VM_LOCKED_MASK (VM_LOCKED | VM_LOCKONFAULT) + +#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) + +#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \ + VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) + +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ + +#define CAP_IPC_LOCK 14 + +#define VM_STICKY (VM_SOFTDIRTY | VM_MAYBE_GUARD) + +#define VM_IGNORE_MERGE VM_STICKY + +#define VM_COPY_ON_FORK (VM_PFNMAP | VM_MIXEDMAP | VM_UFFD_WP | VM_MAYBE_GUARD) + +#define pgprot_val(x) ((x).pgprot) +#define __pgprot(x) ((pgprot_t) { (x) } ) + +#define for_each_vma(__vmi, __vma) \ + while (((__vma) = vma_next(&(__vmi))) != NULL) + +/* The MM code likes to work with exclusive end addresses */ +#define for_each_vma_range(__vmi, __vma, __end) \ + while (((__vma) = vma_find(&(__vmi), (__end))) != NULL) + +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) + +#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) + +#define test_and_set_bit(nr, addr) __test_and_set_bit(nr, addr) +#define test_and_clear_bit(nr, addr) __test_and_clear_bit(nr, addr) + +#define AS_MM_ALL_LOCKS 2 + +#define swap(a, b) \ + do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) + +/* + * Flags for bug emulation. + * + * These occupy the top three bytes. + */ +enum { + READ_IMPLIES_EXEC = 0x0400000, +}; + +struct vma_iterator { + struct ma_state mas; +}; + +#define VMA_ITERATOR(name, __mm, __addr) \ + struct vma_iterator name = { \ + .mas = { \ + .tree = &(__mm)->mm_mt, \ + .index = __addr, \ + .node = NULL, \ + .status = ma_start, \ + }, \ + } + +#define DEFINE_MUTEX(mutexname) \ + struct mutex mutexname = {} + +#define DECLARE_BITMAP(name, bits) \ + unsigned long name[BITS_TO_LONGS(bits)] + +#define EMPTY_VMA_FLAGS ((vma_flags_t){ }) + +/* What action should be taken after an .mmap_prepare call is complete? */ +enum mmap_action_type { + MMAP_NOTHING, /* Mapping is complete, no further action. */ + MMAP_REMAP_PFN, /* Remap PFN range. */ + MMAP_IO_REMAP_PFN, /* I/O remap PFN range. */ +}; + +/* + * Describes an action an mmap_prepare hook can instruct to be taken to complete + * the mapping of a VMA. Specified in vm_area_desc. + */ +struct mmap_action { + union { + /* Remap range. */ + struct { + unsigned long start; + unsigned long start_pfn; + unsigned long size; + pgprot_t pgprot; + } remap; + }; + enum mmap_action_type type; + + /* + * If specified, this hook is invoked after the selected action has been + * successfully completed. Note that the VMA write lock still held. + * + * The absolute minimum ought to be done here. + * + * Returns 0 on success, or an error code. + */ + int (*success_hook)(const struct vm_area_struct *vma); + + /* + * If specified, this hook is invoked when an error occurred when + * attempting the selection action. + * + * The hook can return an error code in order to filter the error, but + * it is not valid to clear the error here. + */ + int (*error_hook)(int err); + + /* + * This should be set in rare instances where the operation required + * that the rmap should not be able to access the VMA until + * completely set up. + */ + bool hide_from_rmap_until_complete :1; +}; + +/* Operations which modify VMAs. */ +enum vma_operation { + VMA_OP_SPLIT, + VMA_OP_MERGE_UNFAULTED, + VMA_OP_REMAP, + VMA_OP_FORK, +}; + +/* + * Describes a VMA that is about to be mmap()'ed. Drivers may choose to + * manipulate mutable fields which will cause those fields to be updated in the + * resultant VMA. + * + * Helper functions are not required for manipulating any field. + */ +struct vm_area_desc { + /* Immutable state. */ + const struct mm_struct *const mm; + struct file *const file; /* May vary from vm_file in stacked callers. */ + unsigned long start; + unsigned long end; + + /* Mutable fields. Populated with initial state. */ + pgoff_t pgoff; + struct file *vm_file; + union { + vm_flags_t vm_flags; + vma_flags_t vma_flags; + }; + pgprot_t page_prot; + + /* Write-only fields. */ + const struct vm_operations_struct *vm_ops; + void *private_data; + + /* Take further action? */ + struct mmap_action action; +}; + +struct vm_area_struct { + /* The first cache line has the info for VMA tree walking. */ + + union { + struct { + /* VMA covers [vm_start; vm_end) addresses within mm */ + unsigned long vm_start; + unsigned long vm_end; + }; + freeptr_t vm_freeptr; /* Pointer used by SLAB_TYPESAFE_BY_RCU */ + }; + + struct mm_struct *vm_mm; /* The address space we belong to. */ + pgprot_t vm_page_prot; /* Access permissions of this VMA. */ + + /* + * Flags, see mm.h. + * To modify use vm_flags_{init|reset|set|clear|mod} functions. + */ + union { + const vm_flags_t vm_flags; + vma_flags_t flags; + }; + +#ifdef CONFIG_PER_VMA_LOCK + /* + * Can only be written (using WRITE_ONCE()) while holding both: + * - mmap_lock (in write mode) + * - vm_refcnt bit at VMA_LOCK_OFFSET is set + * Can be read reliably while holding one of: + * - mmap_lock (in read or write mode) + * - vm_refcnt bit at VMA_LOCK_OFFSET is set or vm_refcnt > 1 + * Can be read unreliably (using READ_ONCE()) for pessimistic bailout + * while holding nothing (except RCU to keep the VMA struct allocated). + * + * This sequence counter is explicitly allowed to overflow; sequence + * counter reuse can only lead to occasional unnecessary use of the + * slowpath. + */ + unsigned int vm_lock_seq; +#endif + + /* + * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma + * list, after a COW of one of the file pages. A MAP_SHARED vma + * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack + * or brk vma (with NULL file) can only be in an anon_vma list. + */ + struct list_head anon_vma_chain; /* Serialized by mmap_lock & + * page_table_lock */ + struct anon_vma *anon_vma; /* Serialized by page_table_lock */ + + /* Function pointers to deal with this struct. */ + const struct vm_operations_struct *vm_ops; + + /* Information about our backing store: */ + unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE + units */ + struct file * vm_file; /* File we map to (can be NULL). */ + void * vm_private_data; /* was vm_pte (shared mem) */ + +#ifdef CONFIG_SWAP + atomic_long_t swap_readahead_info; +#endif +#ifndef CONFIG_MMU + struct vm_region *vm_region; /* NOMMU mapping region */ +#endif +#ifdef CONFIG_NUMA + struct mempolicy *vm_policy; /* NUMA policy for the VMA */ +#endif +#ifdef CONFIG_NUMA_BALANCING + struct vma_numab_state *numab_state; /* NUMA Balancing state */ +#endif +#ifdef CONFIG_PER_VMA_LOCK + /* Unstable RCU readers are allowed to read this. */ + refcount_t vm_refcnt; +#endif + /* + * For areas with an address space and backing store, + * linkage into the address_space->i_mmap interval tree. + * + */ + struct { + struct rb_node rb; + unsigned long rb_subtree_last; + } shared; +#ifdef CONFIG_ANON_VMA_NAME + /* + * For private and shared anonymous mappings, a pointer to a null + * terminated string containing the name given to the vma, or NULL if + * unnamed. Serialized by mmap_lock. Use anon_vma_name to access. + */ + struct anon_vma_name *anon_name; +#endif + struct vm_userfaultfd_ctx vm_userfaultfd_ctx; +} __randomize_layout; + +struct vm_operations_struct { + void (*open)(struct vm_area_struct * area); + /** + * @close: Called when the VMA is being removed from the MM. + * Context: User context. May sleep. Caller holds mmap_lock. + */ + void (*close)(struct vm_area_struct * area); + /* Called any time before splitting to check if it's allowed */ + int (*may_split)(struct vm_area_struct *area, unsigned long addr); + int (*mremap)(struct vm_area_struct *area); + /* + * Called by mprotect() to make driver-specific permission + * checks before mprotect() is finalised. The VMA must not + * be modified. Returns 0 if mprotect() can proceed. + */ + int (*mprotect)(struct vm_area_struct *vma, unsigned long start, + unsigned long end, unsigned long newflags); + vm_fault_t (*fault)(struct vm_fault *vmf); + vm_fault_t (*huge_fault)(struct vm_fault *vmf, unsigned int order); + vm_fault_t (*map_pages)(struct vm_fault *vmf, + pgoff_t start_pgoff, pgoff_t end_pgoff); + unsigned long (*pagesize)(struct vm_area_struct * area); + + /* notification that a previously read-only page is about to become + * writable, if an error is returned it will cause a SIGBUS */ + vm_fault_t (*page_mkwrite)(struct vm_fault *vmf); + + /* same as page_mkwrite when using VM_PFNMAP|VM_MIXEDMAP */ + vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf); + + /* called by access_process_vm when get_user_pages() fails, typically + * for use by special VMAs. See also generic_access_phys() for a generic + * implementation useful for any iomem mapping. + */ + int (*access)(struct vm_area_struct *vma, unsigned long addr, + void *buf, int len, int write); + + /* Called by the /proc/PID/maps code to ask the vma whether it + * has a special name. Returning non-NULL will also cause this + * vma to be dumped unconditionally. */ + const char *(*name)(struct vm_area_struct *vma); + +#ifdef CONFIG_NUMA + /* + * set_policy() op must add a reference to any non-NULL @new mempolicy + * to hold the policy upon return. Caller should pass NULL @new to + * remove a policy and fall back to surrounding context--i.e. do not + * install a MPOL_DEFAULT policy, nor the task or system default + * mempolicy. + */ + int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new); + + /* + * get_policy() op must add reference [mpol_get()] to any policy at + * (vma,addr) marked as MPOL_SHARED. The shared policy infrastructure + * in mm/mempolicy.c will do this automatically. + * get_policy() must NOT add a ref if the policy at (vma,addr) is not + * marked as MPOL_SHARED. vma policies are protected by the mmap_lock. + * If no [shared/vma] mempolicy exists at the addr, get_policy() op + * must return NULL--i.e., do not "fallback" to task or system default + * policy. + */ + struct mempolicy *(*get_policy)(struct vm_area_struct *vma, + unsigned long addr, pgoff_t *ilx); +#endif +#ifdef CONFIG_FIND_NORMAL_PAGE + /* + * Called by vm_normal_page() for special PTEs in @vma at @addr. This + * allows for returning a "normal" page from vm_normal_page() even + * though the PTE indicates that the "struct page" either does not exist + * or should not be touched: "special". + * + * Do not add new users: this really only works when a "normal" page + * was mapped, but then the PTE got changed to something weird (+ + * marked special) that would not make pte_pfn() identify the originally + * inserted page. + */ + struct page *(*find_normal_page)(struct vm_area_struct *vma, + unsigned long addr); +#endif /* CONFIG_FIND_NORMAL_PAGE */ +}; + +struct vm_unmapped_area_info { +#define VM_UNMAPPED_AREA_TOPDOWN 1 + unsigned long flags; + unsigned long length; + unsigned long low_limit; + unsigned long high_limit; + unsigned long align_mask; + unsigned long align_offset; + unsigned long start_gap; +}; + +struct pagetable_move_control { + struct vm_area_struct *old; /* Source VMA. */ + struct vm_area_struct *new; /* Destination VMA. */ + unsigned long old_addr; /* Address from which the move begins. */ + unsigned long old_end; /* Exclusive address at which old range ends. */ + unsigned long new_addr; /* Address to move page tables to. */ + unsigned long len_in; /* Bytes to remap specified by user. */ + + bool need_rmap_locks; /* Do rmap locks need to be taken? */ + bool for_stack; /* Is this an early temp stack being moved? */ +}; + +#define PAGETABLE_MOVE(name, old_, new_, old_addr_, new_addr_, len_) \ + struct pagetable_move_control name = { \ + .old = old_, \ + .new = new_, \ + .old_addr = old_addr_, \ + .old_end = (old_addr_) + (len_), \ + .new_addr = new_addr_, \ + .len_in = len_, \ + } + +static inline void vma_iter_invalidate(struct vma_iterator *vmi) +{ + mas_pause(&vmi->mas); +} + +static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) +{ + return __pgprot(pgprot_val(oldprot) | pgprot_val(newprot)); +} + +static inline pgprot_t vm_get_page_prot(vm_flags_t vm_flags) +{ + return __pgprot(vm_flags); +} + +static inline bool mm_flags_test(int flag, const struct mm_struct *mm) +{ + return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags)); +} + +/* + * Copy value to the first system word of VMA flags, non-atomically. + * + * IMPORTANT: This does not overwrite bytes past the first system word. The + * caller must account for this. + */ +static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value) +{ + *ACCESS_PRIVATE(flags, __vma_flags) = value; +} + +/* + * Copy value to the first system word of VMA flags ONCE, non-atomically. + * + * IMPORTANT: This does not overwrite bytes past the first system word. The + * caller must account for this. + */ +static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value) +{ + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + + WRITE_ONCE(*bitmap, value); +} + +/* Update the first system word of VMA flags setting bits, non-atomically. */ +static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value) +{ + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + + *bitmap |= value; +} + +/* Update the first system word of VMA flags clearing bits, non-atomically. */ +static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value) +{ + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + + *bitmap &= ~value; +} + +static inline void vma_flags_clear_all(vma_flags_t *flags) +{ + bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS); +} + +static inline void vma_flag_set(vma_flags_t *flags, vma_flag_t bit) +{ + unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); + + __set_bit((__force int)bit, bitmap); +} + +/* Use when VMA is not part of the VMA tree and needs no locking */ +static inline void vm_flags_init(struct vm_area_struct *vma, + vm_flags_t flags) +{ + vma_flags_clear_all(&vma->flags); + vma_flags_overwrite_word(&vma->flags, flags); +} + +/* + * Use when VMA is part of the VMA tree and modifications need coordination + * Note: vm_flags_reset and vm_flags_reset_once do not lock the vma and + * it should be locked explicitly beforehand. + */ +static inline void vm_flags_reset(struct vm_area_struct *vma, + vm_flags_t flags) +{ + vma_assert_write_locked(vma); + vm_flags_init(vma, flags); +} + +static inline void vm_flags_reset_once(struct vm_area_struct *vma, + vm_flags_t flags) +{ + vma_assert_write_locked(vma); + /* + * The user should only be interested in avoiding reordering of + * assignment to the first word. + */ + vma_flags_clear_all(&vma->flags); + vma_flags_overwrite_word_once(&vma->flags, flags); +} + +static inline void vm_flags_set(struct vm_area_struct *vma, + vm_flags_t flags) +{ + vma_start_write(vma); + vma_flags_set_word(&vma->flags, flags); +} + +static inline void vm_flags_clear(struct vm_area_struct *vma, + vm_flags_t flags) +{ + vma_start_write(vma); + vma_flags_clear_word(&vma->flags, flags); +} + +static inline vma_flags_t __mk_vma_flags(size_t count, const vma_flag_t *bits); + +#define mk_vma_flags(...) __mk_vma_flags(COUNT_ARGS(__VA_ARGS__), \ + (const vma_flag_t []){__VA_ARGS__}) + +static __always_inline bool vma_flags_test_mask(const vma_flags_t *flags, + vma_flags_t to_test) +{ + const unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_test = to_test.__vma_flags; + + return bitmap_intersects(bitmap_to_test, bitmap, NUM_VMA_FLAG_BITS); +} + +#define vma_flags_test(flags, ...) \ + vma_flags_test_mask(flags, mk_vma_flags(__VA_ARGS__)) + +static __always_inline bool vma_flags_test_all_mask(const vma_flags_t *flags, + vma_flags_t to_test) +{ + const unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_test = to_test.__vma_flags; + + return bitmap_subset(bitmap_to_test, bitmap, NUM_VMA_FLAG_BITS); +} + +#define vma_flags_test_all(flags, ...) \ + vma_flags_test_all_mask(flags, mk_vma_flags(__VA_ARGS__)) + +static __always_inline void vma_flags_set_mask(vma_flags_t *flags, vma_flags_t to_set) +{ + unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_set = to_set.__vma_flags; + + bitmap_or(bitmap, bitmap, bitmap_to_set, NUM_VMA_FLAG_BITS); +} + +#define vma_flags_set(flags, ...) \ + vma_flags_set_mask(flags, mk_vma_flags(__VA_ARGS__)) + +static __always_inline void vma_flags_clear_mask(vma_flags_t *flags, vma_flags_t to_clear) +{ + unsigned long *bitmap = flags->__vma_flags; + const unsigned long *bitmap_to_clear = to_clear.__vma_flags; + + bitmap_andnot(bitmap, bitmap, bitmap_to_clear, NUM_VMA_FLAG_BITS); +} + +#define vma_flags_clear(flags, ...) \ + vma_flags_clear_mask(flags, mk_vma_flags(__VA_ARGS__)) + +static inline bool vma_test_all_flags_mask(const struct vm_area_struct *vma, + vma_flags_t flags) +{ + return vma_flags_test_all_mask(&vma->flags, flags); +} + +#define vma_test_all_flags(vma, ...) \ + vma_test_all_flags_mask(vma, mk_vma_flags(__VA_ARGS__)) + +static inline bool is_shared_maywrite_vm_flags(vm_flags_t vm_flags) +{ + return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == + (VM_SHARED | VM_MAYWRITE); +} + +static inline void vma_set_flags_mask(struct vm_area_struct *vma, + vma_flags_t flags) +{ + vma_flags_set_mask(&vma->flags, flags); +} + +#define vma_set_flags(vma, ...) \ + vma_set_flags_mask(vma, mk_vma_flags(__VA_ARGS__)) + +static inline bool vma_desc_test_flags_mask(const struct vm_area_desc *desc, + vma_flags_t flags) +{ + return vma_flags_test_mask(&desc->vma_flags, flags); +} + +#define vma_desc_test_flags(desc, ...) \ + vma_desc_test_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + +static inline void vma_desc_set_flags_mask(struct vm_area_desc *desc, + vma_flags_t flags) +{ + vma_flags_set_mask(&desc->vma_flags, flags); +} + +#define vma_desc_set_flags(desc, ...) \ + vma_desc_set_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + +static inline void vma_desc_clear_flags_mask(struct vm_area_desc *desc, + vma_flags_t flags) +{ + vma_flags_clear_mask(&desc->vma_flags, flags); +} + +#define vma_desc_clear_flags(desc, ...) \ + vma_desc_clear_flags_mask(desc, mk_vma_flags(__VA_ARGS__)) + +static inline bool is_shared_maywrite(const vma_flags_t *flags) +{ + return vma_flags_test_all(flags, VMA_SHARED_BIT, VMA_MAYWRITE_BIT); +} + +static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) +{ + return is_shared_maywrite(&vma->flags); +} + +static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi) +{ + /* + * Uses mas_find() to get the first VMA when the iterator starts. + * Calling mas_next() could skip the first entry. + */ + return mas_find(&vmi->mas, ULONG_MAX); +} + +/* + * WARNING: to avoid racing with vma_mark_attached()/vma_mark_detached(), these + * assertions should be made either under mmap_write_lock or when the object + * has been isolated under mmap_write_lock, ensuring no competing writers. + */ +static inline void vma_assert_attached(struct vm_area_struct *vma) +{ + WARN_ON_ONCE(!refcount_read(&vma->vm_refcnt)); +} + +static inline void vma_assert_detached(struct vm_area_struct *vma) +{ + WARN_ON_ONCE(refcount_read(&vma->vm_refcnt)); +} + +static inline void vma_assert_write_locked(struct vm_area_struct *); +static inline void vma_mark_attached(struct vm_area_struct *vma) +{ + vma_assert_write_locked(vma); + vma_assert_detached(vma); + refcount_set_release(&vma->vm_refcnt, 1); +} + +static inline void vma_mark_detached(struct vm_area_struct *vma) +{ + vma_assert_write_locked(vma); + vma_assert_attached(vma); + /* We are the only writer, so no need to use vma_refcount_put(). */ + if (unlikely(!refcount_dec_and_test(&vma->vm_refcnt))) { + /* + * Reader must have temporarily raised vm_refcnt but it will + * drop it without using the vma since vma is write-locked. + */ + } +} + +static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm) +{ + memset(vma, 0, sizeof(*vma)); + vma->vm_mm = mm; + vma->vm_ops = &vma_dummy_vm_ops; + INIT_LIST_HEAD(&vma->anon_vma_chain); + vma->vm_lock_seq = UINT_MAX; +} + +/* + * These are defined in vma.h, but sadly vm_stat_account() is referenced by + * kernel/fork.c, so we have to these broadly available there, and temporarily + * define them here to resolve the dependency cycle. + */ +#define is_exec_mapping(flags) \ + ((flags & (VM_EXEC | VM_WRITE | VM_STACK)) == VM_EXEC) + +#define is_stack_mapping(flags) \ + (((flags & VM_STACK) == VM_STACK) || (flags & VM_SHADOW_STACK)) + +#define is_data_mapping(flags) \ + ((flags & (VM_WRITE | VM_SHARED | VM_STACK)) == VM_WRITE) + +static inline void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, + long npages) +{ + WRITE_ONCE(mm->total_vm, READ_ONCE(mm->total_vm)+npages); + + if (is_exec_mapping(flags)) + mm->exec_vm += npages; + else if (is_stack_mapping(flags)) + mm->stack_vm += npages; + else if (is_data_mapping(flags)) + mm->data_vm += npages; +} + +#undef is_exec_mapping +#undef is_stack_mapping +#undef is_data_mapping + +static inline void vm_unacct_memory(long pages) +{ + vm_acct_memory(-pages); +} + +static inline void mapping_allow_writable(struct address_space *mapping) +{ + atomic_inc(&mapping->i_mmap_writable); +} + +static inline +struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max) +{ + return mas_find(&vmi->mas, max - 1); +} + +static inline int vma_iter_clear_gfp(struct vma_iterator *vmi, + unsigned long start, unsigned long end, gfp_t gfp) +{ + __mas_set_range(&vmi->mas, start, end - 1); + mas_store_gfp(&vmi->mas, NULL, gfp); + if (unlikely(mas_is_err(&vmi->mas))) + return -ENOMEM; + + return 0; +} + +static inline void vma_set_anonymous(struct vm_area_struct *vma) +{ + vma->vm_ops = NULL; +} + +/* Declared in vma.h. */ +static inline void set_vma_from_desc(struct vm_area_struct *vma, + struct vm_area_desc *desc); + +static inline int __compat_vma_mmap(const struct file_operations *f_op, + struct file *file, struct vm_area_struct *vma) +{ + struct vm_area_desc desc = { + .mm = vma->vm_mm, + .file = file, + .start = vma->vm_start, + .end = vma->vm_end, + + .pgoff = vma->vm_pgoff, + .vm_file = vma->vm_file, + .vm_flags = vma->vm_flags, + .page_prot = vma->vm_page_prot, + + .action.type = MMAP_NOTHING, /* Default */ + }; + int err; + + err = f_op->mmap_prepare(&desc); + if (err) + return err; + + mmap_action_prepare(&desc.action, &desc); + set_vma_from_desc(vma, &desc); + return mmap_action_complete(&desc.action, vma); +} + +static inline int compat_vma_mmap(struct file *file, + struct vm_area_struct *vma) +{ + return __compat_vma_mmap(file->f_op, file, vma); +} + + +static inline void vma_iter_init(struct vma_iterator *vmi, + struct mm_struct *mm, unsigned long addr) +{ + mas_init(&vmi->mas, &mm->mm_mt, addr); +} + +static inline unsigned long vma_pages(struct vm_area_struct *vma) +{ + return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; +} + +static inline void mmap_assert_locked(struct mm_struct *); +static inline struct vm_area_struct *find_vma_intersection(struct mm_struct *mm, + unsigned long start_addr, + unsigned long end_addr) +{ + unsigned long index = start_addr; + + mmap_assert_locked(mm); + return mt_find(&mm->mm_mt, &index, end_addr - 1); +} + +static inline +struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr) +{ + return mtree_load(&mm->mm_mt, addr); +} + +static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi) +{ + return mas_prev(&vmi->mas, 0); +} + +static inline void vma_iter_set(struct vma_iterator *vmi, unsigned long addr) +{ + mas_set(&vmi->mas, addr); +} + +static inline bool vma_is_anonymous(struct vm_area_struct *vma) +{ + return !vma->vm_ops; +} + +/* Defined in vma.h, so temporarily define here to avoid circular dependency. */ +#define vma_iter_load(vmi) \ + mas_walk(&(vmi)->mas) + +static inline struct vm_area_struct * +find_vma_prev(struct mm_struct *mm, unsigned long addr, + struct vm_area_struct **pprev) +{ + struct vm_area_struct *vma; + VMA_ITERATOR(vmi, mm, addr); + + vma = vma_iter_load(&vmi); + *pprev = vma_prev(&vmi); + if (!vma) + vma = vma_next(&vmi); + return vma; +} + +#undef vma_iter_load + +static inline void vma_iter_free(struct vma_iterator *vmi) +{ + mas_destroy(&vmi->mas); +} + +static inline +struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi) +{ + return mas_next_range(&vmi->mas, ULONG_MAX); +} + +bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot); + +/* Update vma->vm_page_prot to reflect vma->vm_flags. */ +static inline void vma_set_page_prot(struct vm_area_struct *vma) +{ + vm_flags_t vm_flags = vma->vm_flags; + pgprot_t vm_page_prot; + + /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */ + vm_page_prot = pgprot_modify(vma->vm_page_prot, vm_get_page_prot(vm_flags)); + + if (vma_wants_writenotify(vma, vm_page_prot)) { + vm_flags &= ~VM_SHARED; + /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */ + vm_page_prot = pgprot_modify(vm_page_prot, vm_get_page_prot(vm_flags)); + } + /* remove_protection_ptes reads vma->vm_page_prot without mmap_lock */ + WRITE_ONCE(vma->vm_page_prot, vm_page_prot); +} + +static inline unsigned long stack_guard_start_gap(struct vm_area_struct *vma) +{ + if (vma->vm_flags & VM_GROWSDOWN) + return stack_guard_gap; + + /* See reasoning around the VM_SHADOW_STACK definition */ + if (vma->vm_flags & VM_SHADOW_STACK) + return PAGE_SIZE; + + return 0; +} + +static inline unsigned long vm_start_gap(struct vm_area_struct *vma) +{ + unsigned long gap = stack_guard_start_gap(vma); + unsigned long vm_start = vma->vm_start; + + vm_start -= gap; + if (vm_start > vma->vm_start) + vm_start = 0; + return vm_start; +} + +static inline unsigned long vm_end_gap(struct vm_area_struct *vma) +{ + unsigned long vm_end = vma->vm_end; + + if (vma->vm_flags & VM_GROWSUP) { + vm_end += stack_guard_gap; + if (vm_end < vma->vm_end) + vm_end = -PAGE_SIZE; + } + return vm_end; +} + +static inline bool vma_is_accessible(struct vm_area_struct *vma) +{ + return vma->vm_flags & VM_ACCESS_FLAGS; +} + +static inline bool mlock_future_ok(const struct mm_struct *mm, + vm_flags_t vm_flags, unsigned long bytes) +{ + unsigned long locked_pages, limit_pages; + + if (!(vm_flags & VM_LOCKED) || capable(CAP_IPC_LOCK)) + return true; + + locked_pages = bytes >> PAGE_SHIFT; + locked_pages += mm->locked_vm; + + limit_pages = rlimit(RLIMIT_MEMLOCK); + limit_pages >>= PAGE_SHIFT; + + return locked_pages <= limit_pages; +} + +static inline bool map_deny_write_exec(unsigned long old, unsigned long new) +{ + /* If MDWE is disabled, we have nothing to deny. */ + if (mm_flags_test(MMF_HAS_MDWE, current->mm)) + return false; + + /* If the new VMA is not executable, we have nothing to deny. */ + if (!(new & VM_EXEC)) + return false; + + /* Under MDWE we do not accept newly writably executable VMAs... */ + if (new & VM_WRITE) + return true; + + /* ...nor previously non-executable VMAs becoming executable. */ + if (!(old & VM_EXEC)) + return true; + + return false; +} + +static inline int mapping_map_writable(struct address_space *mapping) +{ + return atomic_inc_unless_negative(&mapping->i_mmap_writable) ? + 0 : -EPERM; +} + +/* Did the driver provide valid mmap hook configuration? */ +static inline bool can_mmap_file(struct file *file) +{ + bool has_mmap = file->f_op->mmap; + bool has_mmap_prepare = file->f_op->mmap_prepare; + + /* Hooks are mutually exclusive. */ + if (WARN_ON_ONCE(has_mmap && has_mmap_prepare)) + return false; + if (!has_mmap && !has_mmap_prepare) + return false; + + return true; +} + +static inline int vfs_mmap(struct file *file, struct vm_area_struct *vma) +{ + if (file->f_op->mmap_prepare) + return compat_vma_mmap(file, vma); + + return file->f_op->mmap(file, vma); +} + +static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc) +{ + return file->f_op->mmap_prepare(desc); +} + +static inline void vma_set_file(struct vm_area_struct *vma, struct file *file) +{ + /* Changing an anonymous vma with this is illegal */ + get_file(file); + swap(vma->vm_file, file); + fput(file); +} diff --git a/tools/testing/vma/include/stubs.h b/tools/testing/vma/include/stubs.h new file mode 100644 index 000000000000..947a3a0c2566 --- /dev/null +++ b/tools/testing/vma/include/stubs.h @@ -0,0 +1,428 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#pragma once + +/* + * Contains declarations that are STUBBED, that is that are rendered no-ops, in + * order to faciliate userland VMA testing. + */ + +/* Forward declarations. */ +struct mm_struct; +struct vm_area_struct; +struct vm_area_desc; +struct pagetable_move_control; +struct mmap_action; +struct file; +struct anon_vma; +struct anon_vma_chain; +struct address_space; +struct unmap_desc; + +#define __bitwise +#define __randomize_layout + +#define FIRST_USER_ADDRESS 0UL +#define USER_PGTABLES_CEILING 0UL + +#define vma_policy(vma) NULL + +#define down_write_nest_lock(sem, nest_lock) + +#define data_race(expr) expr + +#define ASSERT_EXCLUSIVE_WRITER(x) + +struct vm_userfaultfd_ctx {}; +struct mempolicy {}; +struct mmu_gather {}; +struct mutex {}; +struct vm_fault {}; + +static inline void userfaultfd_unmap_complete(struct mm_struct *mm, + struct list_head *uf) +{ +} + +static inline unsigned long move_page_tables(struct pagetable_move_control *pmc) +{ + return 0; +} + +static inline void free_pgd_range(struct mmu_gather *tlb, + unsigned long addr, unsigned long end, + unsigned long floor, unsigned long ceiling) +{ +} + +static inline int ksm_execve(struct mm_struct *mm) +{ + return 0; +} + +static inline void ksm_exit(struct mm_struct *mm) +{ +} + +static inline void vma_numab_state_init(struct vm_area_struct *vma) +{ +} + +static inline void vma_numab_state_free(struct vm_area_struct *vma) +{ +} + +static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma, + struct vm_area_struct *new_vma) +{ +} + +static inline void free_anon_vma_name(struct vm_area_struct *vma) +{ +} + +static inline void mmap_action_prepare(struct mmap_action *action, + struct vm_area_desc *desc) +{ +} + +static inline int mmap_action_complete(struct mmap_action *action, + struct vm_area_struct *vma) +{ + return 0; +} + +static inline void fixup_hugetlb_reservations(struct vm_area_struct *vma) +{ +} + +static inline bool shmem_file(struct file *file) +{ + return false; +} + +static inline vm_flags_t ksm_vma_flags(const struct mm_struct *mm, + const struct file *file, vm_flags_t vm_flags) +{ + return vm_flags; +} + +static inline void remap_pfn_range_prepare(struct vm_area_desc *desc, unsigned long pfn) +{ +} + +static inline int remap_pfn_range_complete(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn, unsigned long size, pgprot_t pgprot) +{ + return 0; +} + +static inline int do_munmap(struct mm_struct *, unsigned long, size_t, + struct list_head *uf) +{ + return 0; +} + +/* Currently stubbed but we may later wish to un-stub. */ +static inline void vm_acct_memory(long pages); + +static inline void mmap_assert_locked(struct mm_struct *mm) +{ +} + + +static inline void anon_vma_unlock_write(struct anon_vma *anon_vma) +{ +} + +static inline void i_mmap_unlock_write(struct address_space *mapping) +{ +} + +static inline int userfaultfd_unmap_prep(struct vm_area_struct *vma, + unsigned long start, + unsigned long end, + struct list_head *unmaps) +{ + return 0; +} + +static inline void mmap_write_downgrade(struct mm_struct *mm) +{ +} + +static inline void mmap_read_unlock(struct mm_struct *mm) +{ +} + +static inline void mmap_write_unlock(struct mm_struct *mm) +{ +} + +static inline int mmap_write_lock_killable(struct mm_struct *mm) +{ + return 0; +} + +static inline bool can_modify_mm(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ + return true; +} + +static inline void arch_unmap(struct mm_struct *mm, + unsigned long start, + unsigned long end) +{ +} + +static inline bool mpol_equal(struct mempolicy *a, struct mempolicy *b) +{ + return true; +} + +static inline void khugepaged_enter_vma(struct vm_area_struct *vma, + vm_flags_t vm_flags) +{ +} + +static inline bool mapping_can_writeback(struct address_space *mapping) +{ + return true; +} + +static inline bool is_vm_hugetlb_page(struct vm_area_struct *vma) +{ + return false; +} + +static inline bool vma_soft_dirty_enabled(struct vm_area_struct *vma) +{ + return false; +} + +static inline bool userfaultfd_wp(struct vm_area_struct *vma) +{ + return false; +} + +static inline void mmap_assert_write_locked(struct mm_struct *mm) +{ +} + +static inline void mutex_lock(struct mutex *lock) +{ +} + +static inline void mutex_unlock(struct mutex *lock) +{ +} + +static inline bool mutex_is_locked(struct mutex *lock) +{ + return true; +} + +static inline bool signal_pending(void *p) +{ + return false; +} + +static inline bool is_file_hugepages(struct file *file) +{ + return false; +} + +static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) +{ + return 0; +} + +static inline bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, + unsigned long npages) +{ + return true; +} + +static inline int shmem_zero_setup(struct vm_area_struct *vma) +{ + return 0; +} + + +static inline void vm_acct_memory(long pages) +{ +} + +static inline void vma_interval_tree_insert(struct vm_area_struct *vma, + struct rb_root_cached *rb) +{ +} + +static inline void vma_interval_tree_remove(struct vm_area_struct *vma, + struct rb_root_cached *rb) +{ +} + +static inline void flush_dcache_mmap_unlock(struct address_space *mapping) +{ +} + +static inline void anon_vma_interval_tree_insert(struct anon_vma_chain *avc, + struct rb_root_cached *rb) +{ +} + +static inline void anon_vma_interval_tree_remove(struct anon_vma_chain *avc, + struct rb_root_cached *rb) +{ +} + +static inline void uprobe_mmap(struct vm_area_struct *vma) +{ +} + +static inline void uprobe_munmap(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ +} + +static inline void i_mmap_lock_write(struct address_space *mapping) +{ +} + +static inline void anon_vma_lock_write(struct anon_vma *anon_vma) +{ +} + +static inline void vma_assert_write_locked(struct vm_area_struct *vma) +{ +} + +static inline void ksm_add_vma(struct vm_area_struct *vma) +{ +} + +static inline void perf_event_mmap(struct vm_area_struct *vma) +{ +} + +static inline bool vma_is_dax(struct vm_area_struct *vma) +{ + return false; +} + +static inline struct vm_area_struct *get_gate_vma(struct mm_struct *mm) +{ + return NULL; +} + +static inline bool arch_validate_flags(vm_flags_t flags) +{ + return true; +} + +static inline void vma_close(struct vm_area_struct *vma) +{ +} + +static inline int mmap_file(struct file *file, struct vm_area_struct *vma) +{ + return 0; +} + +static inline int is_hugepage_only_range(struct mm_struct *mm, + unsigned long addr, unsigned long len) +{ + return 0; +} + +static inline bool capable(int cap) +{ + return true; +} + +static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma) +{ + return NULL; +} + +static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, + struct vm_userfaultfd_ctx vm_ctx) +{ + return true; +} + +static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, + struct anon_vma_name *anon_name2) +{ + return true; +} + +static inline void might_sleep(void) +{ +} + +static inline void fput(struct file *file) +{ +} + +static inline void mpol_put(struct mempolicy *pol) +{ +} + +static inline void lru_add_drain(void) +{ +} + +static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm) +{ +} + +static inline void update_hiwater_rss(struct mm_struct *mm) +{ +} + +static inline void update_hiwater_vm(struct mm_struct *mm) +{ +} + +static inline void unmap_vmas(struct mmu_gather *tlb, struct unmap_desc *unmap) +{ +} + +static inline void free_pgtables(struct mmu_gather *tlb, struct unmap_desc *unmap) +{ +} + +static inline void mapping_unmap_writable(struct address_space *mapping) +{ +} + +static inline void flush_dcache_mmap_lock(struct address_space *mapping) +{ +} + +static inline void tlb_finish_mmu(struct mmu_gather *tlb) +{ +} + +static inline struct file *get_file(struct file *f) +{ + return f; +} + +static inline int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst) +{ + return 0; +} + +static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, + unsigned long start, + unsigned long end, + struct vm_area_struct *next) +{ +} + +static inline void hugetlb_split(struct vm_area_struct *, unsigned long) {} diff --git a/tools/testing/vma/main.c b/tools/testing/vma/main.c new file mode 100644 index 000000000000..49b09e97a51f --- /dev/null +++ b/tools/testing/vma/main.c @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shared.h" +/* + * Directly import the VMA implementation here. Our vma_internal.h wrapper + * provides userland-equivalent functionality for everything vma.c uses. + */ +#include "../../../mm/vma_init.c" +#include "../../../mm/vma_exec.c" +#include "../../../mm/vma.c" + +/* Tests are included directly so they can test static functions in mm/vma.c. */ +#include "tests/merge.c" +#include "tests/mmap.c" +#include "tests/vma.c" + +/* Helper functions which utilise static kernel functions. */ + +struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg) +{ + struct vm_area_struct *vma; + + vma = vma_merge_existing_range(vmg); + if (vma) + vma_assert_attached(vma); + return vma; +} + +int attach_vma(struct mm_struct *mm, struct vm_area_struct *vma) +{ + int res; + + res = vma_link(mm, vma); + if (!res) + vma_assert_attached(vma); + return res; +} + +/* Main test running which invokes tests/ *.c runners. */ +int main(void) +{ + int num_tests = 0, num_fail = 0; + + maple_tree_init(); + vma_state_init(); + + run_merge_tests(&num_tests, &num_fail); + run_mmap_tests(&num_tests, &num_fail); + run_vma_tests(&num_tests, &num_fail); + + printf("%d tests run, %d passed, %d failed.\n", + num_tests, num_tests - num_fail, num_fail); + + return num_fail == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tools/testing/vma/shared.c b/tools/testing/vma/shared.c new file mode 100644 index 000000000000..bda578cc3304 --- /dev/null +++ b/tools/testing/vma/shared.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shared.h" + + +bool fail_prealloc; +unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; +unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; +unsigned long stack_guard_gap = 256UL<vm_start = start; + vma->vm_end = end; + vma->vm_pgoff = pgoff; + vm_flags_reset(vma, vm_flags); + vma_assert_detached(vma); + + return vma; +} + +void detach_free_vma(struct vm_area_struct *vma) +{ + vma_mark_detached(vma); + vm_area_free(vma); +} + +struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm, + unsigned long start, unsigned long end, + pgoff_t pgoff, vm_flags_t vm_flags) +{ + struct vm_area_struct *vma = alloc_vma(mm, start, end, pgoff, vm_flags); + + if (vma == NULL) + return NULL; + + if (attach_vma(mm, vma)) { + detach_free_vma(vma); + return NULL; + } + + /* + * Reset this counter which we use to track whether writes have + * begun. Linking to the tree will have caused this to be incremented, + * which means we will get a false positive otherwise. + */ + vma->vm_lock_seq = UINT_MAX; + + return vma; +} + +void reset_dummy_anon_vma(void) +{ + dummy_anon_vma.was_cloned = false; + dummy_anon_vma.was_unlinked = false; +} + +int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi) +{ + struct vm_area_struct *vma; + int count = 0; + + fail_prealloc = false; + reset_dummy_anon_vma(); + + vma_iter_set(vmi, 0); + for_each_vma(*vmi, vma) { + detach_free_vma(vma); + count++; + } + + mtree_destroy(&mm->mm_mt); + mm->map_count = 0; + return count; +} + +bool vma_write_started(struct vm_area_struct *vma) +{ + int seq = vma->vm_lock_seq; + + /* We reset after each check. */ + vma->vm_lock_seq = UINT_MAX; + + /* The vma_start_write() stub simply increments this value. */ + return seq > -1; +} + +void __vma_set_dummy_anon_vma(struct vm_area_struct *vma, + struct anon_vma_chain *avc, struct anon_vma *anon_vma) +{ + vma->anon_vma = anon_vma; + INIT_LIST_HEAD(&vma->anon_vma_chain); + list_add(&avc->same_vma, &vma->anon_vma_chain); + avc->anon_vma = vma->anon_vma; +} + +void vma_set_dummy_anon_vma(struct vm_area_struct *vma, + struct anon_vma_chain *avc) +{ + __vma_set_dummy_anon_vma(vma, avc, &dummy_anon_vma); +} + +struct task_struct *get_current(void) +{ + return &__current; +} + +unsigned long rlimit(unsigned int limit) +{ + return (unsigned long)-1; +} + +void vma_set_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + pgoff_t pgoff) +{ + vma->vm_start = start; + vma->vm_end = end; + vma->vm_pgoff = pgoff; +} diff --git a/tools/testing/vma/shared.h b/tools/testing/vma/shared.h new file mode 100644 index 000000000000..6c64211cfa22 --- /dev/null +++ b/tools/testing/vma/shared.h @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include + +#include "generated/bit-length.h" +#include "maple-shared.h" +#include "vma_internal.h" +#include "../../../mm/vma.h" + +/* Simple test runner. Assumes local num_[fail, tests] counters. */ +#define TEST(name) \ + do { \ + (*num_tests)++; \ + if (!test_##name()) { \ + (*num_fail)++; \ + fprintf(stderr, "Test " #name " FAILED\n"); \ + } \ + } while (0) + +#define ASSERT_TRUE(_expr) \ + do { \ + if (!(_expr)) { \ + fprintf(stderr, \ + "Assert FAILED at %s:%d:%s(): %s is FALSE.\n", \ + __FILE__, __LINE__, __FUNCTION__, #_expr); \ + return false; \ + } \ + } while (0) + +#define ASSERT_FALSE(_expr) ASSERT_TRUE(!(_expr)) +#define ASSERT_EQ(_val1, _val2) ASSERT_TRUE((_val1) == (_val2)) +#define ASSERT_NE(_val1, _val2) ASSERT_TRUE((_val1) != (_val2)) + +#define IS_SET(_val, _flags) ((_val & _flags) == _flags) + +extern bool fail_prealloc; + +/* Override vma_iter_prealloc() so we can choose to fail it. */ +#define vma_iter_prealloc(vmi, vma) \ + (fail_prealloc ? -ENOMEM : mas_preallocate(&(vmi)->mas, (vma), GFP_KERNEL)) + +#define CONFIG_DEFAULT_MMAP_MIN_ADDR 65536 + +extern unsigned long mmap_min_addr; +extern unsigned long dac_mmap_min_addr; +extern unsigned long stack_guard_gap; + +extern const struct vm_operations_struct vma_dummy_vm_ops; +extern struct anon_vma dummy_anon_vma; +extern struct task_struct __current; + +/* + * Helper function which provides a wrapper around a merge existing VMA + * operation. + * + * Declared in main.c as uses static VMA function. + */ +struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg); + +/* + * Helper function to allocate a VMA and link it to the tree. + * + * Declared in main.c as uses static VMA function. + */ +int attach_vma(struct mm_struct *mm, struct vm_area_struct *vma); + +/* Helper function providing a dummy vm_ops->close() method.*/ +static inline void dummy_close(struct vm_area_struct *) +{ +} + +/* Helper function to simply allocate a VMA. */ +struct vm_area_struct *alloc_vma(struct mm_struct *mm, + unsigned long start, unsigned long end, + pgoff_t pgoff, vm_flags_t vm_flags); + +/* Helper function to detach and free a VMA. */ +void detach_free_vma(struct vm_area_struct *vma); + +/* Helper function to allocate a VMA and link it to the tree. */ +struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm, + unsigned long start, unsigned long end, + pgoff_t pgoff, vm_flags_t vm_flags); + +/* + * Helper function to reset the dummy anon_vma to indicate it has not been + * duplicated. + */ +void reset_dummy_anon_vma(void); + +/* + * Helper function to remove all VMAs and destroy the maple tree associated with + * a virtual address space. Returns a count of VMAs in the tree. + */ +int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi); + +/* Helper function to determine if VMA has had vma_start_write() performed. */ +bool vma_write_started(struct vm_area_struct *vma); + +void __vma_set_dummy_anon_vma(struct vm_area_struct *vma, + struct anon_vma_chain *avc, struct anon_vma *anon_vma); + +/* Provide a simple dummy VMA/anon_vma dummy setup for testing. */ +void vma_set_dummy_anon_vma(struct vm_area_struct *vma, + struct anon_vma_chain *avc); + +/* Helper function to specify a VMA's range. */ +void vma_set_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + pgoff_t pgoff); diff --git a/tools/testing/vma/vma.c b/tools/testing/vma/tests/merge.c similarity index 82% rename from tools/testing/vma/vma.c rename to tools/testing/vma/tests/merge.c index 93d21bc7e112..3708dc6945b0 100644 --- a/tools/testing/vma/vma.c +++ b/tools/testing/vma/tests/merge.c @@ -1,132 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-or-later -#include -#include -#include - -#include "generated/bit-length.h" - -#include "maple-shared.h" -#include "vma_internal.h" - -/* Include so header guard set. */ -#include "../../../mm/vma.h" - -static bool fail_prealloc; - -/* Then override vma_iter_prealloc() so we can choose to fail it. */ -#define vma_iter_prealloc(vmi, vma) \ - (fail_prealloc ? -ENOMEM : mas_preallocate(&(vmi)->mas, (vma), GFP_KERNEL)) - -#define CONFIG_DEFAULT_MMAP_MIN_ADDR 65536 - -unsigned long mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; -unsigned long dac_mmap_min_addr = CONFIG_DEFAULT_MMAP_MIN_ADDR; -unsigned long stack_guard_gap = 256UL<vm_start = start; - vma->vm_end = end; - vma->vm_pgoff = pgoff; - vm_flags_reset(vma, vm_flags); - vma_assert_detached(vma); - - return vma; -} - -/* Helper function to allocate a VMA and link it to the tree. */ -static int attach_vma(struct mm_struct *mm, struct vm_area_struct *vma) -{ - int res; - - res = vma_link(mm, vma); - if (!res) - vma_assert_attached(vma); - return res; -} - -static void detach_free_vma(struct vm_area_struct *vma) -{ - vma_mark_detached(vma); - vm_area_free(vma); -} - -/* Helper function to allocate a VMA and link it to the tree. */ -static struct vm_area_struct *alloc_and_link_vma(struct mm_struct *mm, - unsigned long start, - unsigned long end, - pgoff_t pgoff, - vm_flags_t vm_flags) -{ - struct vm_area_struct *vma = alloc_vma(mm, start, end, pgoff, vm_flags); - - if (vma == NULL) - return NULL; - - if (attach_vma(mm, vma)) { - detach_free_vma(vma); - return NULL; - } - - /* - * Reset this counter which we use to track whether writes have - * begun. Linking to the tree will have caused this to be incremented, - * which means we will get a false positive otherwise. - */ - vma->vm_lock_seq = UINT_MAX; - - return vma; -} - /* Helper function which provides a wrapper around a merge new VMA operation. */ static struct vm_area_struct *merge_new(struct vma_merge_struct *vmg) { @@ -146,20 +19,6 @@ static struct vm_area_struct *merge_new(struct vma_merge_struct *vmg) return vma; } -/* - * Helper function which provides a wrapper around a merge existing VMA - * operation. - */ -static struct vm_area_struct *merge_existing(struct vma_merge_struct *vmg) -{ - struct vm_area_struct *vma; - - vma = vma_merge_existing_range(vmg); - if (vma) - vma_assert_attached(vma); - return vma; -} - /* * Helper function which provides a wrapper around the expansion of an existing * VMA. @@ -173,8 +32,8 @@ static int expand_existing(struct vma_merge_struct *vmg) * Helper function to reset merge state the associated VMA iterator to a * specified new range. */ -static void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start, - unsigned long end, pgoff_t pgoff, vm_flags_t vm_flags) +void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start, + unsigned long end, pgoff_t pgoff, vm_flags_t vm_flags) { vma_iter_set(vmg->vmi, start); @@ -197,8 +56,8 @@ static void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start, /* Helper function to set both the VMG range and its anon_vma. */ static void vmg_set_range_anon_vma(struct vma_merge_struct *vmg, unsigned long start, - unsigned long end, pgoff_t pgoff, vm_flags_t vm_flags, - struct anon_vma *anon_vma) + unsigned long end, pgoff_t pgoff, vm_flags_t vm_flags, + struct anon_vma *anon_vma) { vmg_set_range(vmg, start, end, pgoff, vm_flags); vmg->anon_vma = anon_vma; @@ -211,10 +70,9 @@ static void vmg_set_range_anon_vma(struct vma_merge_struct *vmg, unsigned long s * VMA, link it to the maple tree and return it. */ static struct vm_area_struct *try_merge_new_vma(struct mm_struct *mm, - struct vma_merge_struct *vmg, - unsigned long start, unsigned long end, - pgoff_t pgoff, vm_flags_t vm_flags, - bool *was_merged) + struct vma_merge_struct *vmg, unsigned long start, + unsigned long end, pgoff_t pgoff, vm_flags_t vm_flags, + bool *was_merged) { struct vm_area_struct *merged; @@ -234,72 +92,6 @@ static struct vm_area_struct *try_merge_new_vma(struct mm_struct *mm, return alloc_and_link_vma(mm, start, end, pgoff, vm_flags); } -/* - * Helper function to reset the dummy anon_vma to indicate it has not been - * duplicated. - */ -static void reset_dummy_anon_vma(void) -{ - dummy_anon_vma.was_cloned = false; - dummy_anon_vma.was_unlinked = false; -} - -/* - * Helper function to remove all VMAs and destroy the maple tree associated with - * a virtual address space. Returns a count of VMAs in the tree. - */ -static int cleanup_mm(struct mm_struct *mm, struct vma_iterator *vmi) -{ - struct vm_area_struct *vma; - int count = 0; - - fail_prealloc = false; - reset_dummy_anon_vma(); - - vma_iter_set(vmi, 0); - for_each_vma(*vmi, vma) { - detach_free_vma(vma); - count++; - } - - mtree_destroy(&mm->mm_mt); - mm->map_count = 0; - return count; -} - -/* Helper function to determine if VMA has had vma_start_write() performed. */ -static bool vma_write_started(struct vm_area_struct *vma) -{ - int seq = vma->vm_lock_seq; - - /* We reset after each check. */ - vma->vm_lock_seq = UINT_MAX; - - /* The vma_start_write() stub simply increments this value. */ - return seq > -1; -} - -/* Helper function providing a dummy vm_ops->close() method.*/ -static void dummy_close(struct vm_area_struct *) -{ -} - -static void __vma_set_dummy_anon_vma(struct vm_area_struct *vma, - struct anon_vma_chain *avc, - struct anon_vma *anon_vma) -{ - vma->anon_vma = anon_vma; - INIT_LIST_HEAD(&vma->anon_vma_chain); - list_add(&avc->same_vma, &vma->anon_vma_chain); - avc->anon_vma = vma->anon_vma; -} - -static void vma_set_dummy_anon_vma(struct vm_area_struct *vma, - struct anon_vma_chain *avc) -{ - __vma_set_dummy_anon_vma(vma, avc, &dummy_anon_vma); -} - static bool test_simple_merge(void) { struct vm_area_struct *vma; @@ -1616,39 +1408,6 @@ static bool test_merge_extend(void) return true; } -static bool test_copy_vma(void) -{ - vm_flags_t vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE; - struct mm_struct mm = {}; - bool need_locks = false; - VMA_ITERATOR(vmi, &mm, 0); - struct vm_area_struct *vma, *vma_new, *vma_next; - - /* Move backwards and do not merge. */ - - vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vm_flags); - vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks); - ASSERT_NE(vma_new, vma); - ASSERT_EQ(vma_new->vm_start, 0); - ASSERT_EQ(vma_new->vm_end, 0x2000); - ASSERT_EQ(vma_new->vm_pgoff, 0); - vma_assert_attached(vma_new); - - cleanup_mm(&mm, &vmi); - - /* Move a VMA into position next to another and merge the two. */ - - vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vm_flags); - vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vm_flags); - vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks); - vma_assert_attached(vma_new); - - ASSERT_EQ(vma_new, vma_next); - - cleanup_mm(&mm, &vmi); - return true; -} - static bool test_expand_only_mode(void) { vm_flags_t vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE; @@ -1689,73 +1448,8 @@ static bool test_expand_only_mode(void) return true; } -static bool test_mmap_region_basic(void) +static void run_merge_tests(int *num_tests, int *num_fail) { - struct mm_struct mm = {}; - unsigned long addr; - struct vm_area_struct *vma; - VMA_ITERATOR(vmi, &mm, 0); - - current->mm = &mm; - - /* Map at 0x300000, length 0x3000. */ - addr = __mmap_region(NULL, 0x300000, 0x3000, - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, - 0x300, NULL); - ASSERT_EQ(addr, 0x300000); - - /* Map at 0x250000, length 0x3000. */ - addr = __mmap_region(NULL, 0x250000, 0x3000, - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, - 0x250, NULL); - ASSERT_EQ(addr, 0x250000); - - /* Map at 0x303000, merging to 0x300000 of length 0x6000. */ - addr = __mmap_region(NULL, 0x303000, 0x3000, - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, - 0x303, NULL); - ASSERT_EQ(addr, 0x303000); - - /* Map at 0x24d000, merging to 0x250000 of length 0x6000. */ - addr = __mmap_region(NULL, 0x24d000, 0x3000, - VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, - 0x24d, NULL); - ASSERT_EQ(addr, 0x24d000); - - ASSERT_EQ(mm.map_count, 2); - - for_each_vma(vmi, vma) { - if (vma->vm_start == 0x300000) { - ASSERT_EQ(vma->vm_end, 0x306000); - ASSERT_EQ(vma->vm_pgoff, 0x300); - } else if (vma->vm_start == 0x24d000) { - ASSERT_EQ(vma->vm_end, 0x253000); - ASSERT_EQ(vma->vm_pgoff, 0x24d); - } else { - ASSERT_FALSE(true); - } - } - - cleanup_mm(&mm, &vmi); - return true; -} - -int main(void) -{ - int num_tests = 0, num_fail = 0; - - maple_tree_init(); - vma_state_init(); - -#define TEST(name) \ - do { \ - num_tests++; \ - if (!test_##name()) { \ - num_fail++; \ - fprintf(stderr, "Test " #name " FAILED\n"); \ - } \ - } while (0) - /* Very simple tests to kick the tyres. */ TEST(simple_merge); TEST(simple_modify); @@ -1771,15 +1465,5 @@ int main(void) TEST(dup_anon_vma); TEST(vmi_prealloc_fail); TEST(merge_extend); - TEST(copy_vma); TEST(expand_only_mode); - - TEST(mmap_region_basic); - -#undef TEST - - printf("%d tests run, %d passed, %d failed.\n", - num_tests, num_tests - num_fail, num_fail); - - return num_fail == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tools/testing/vma/tests/mmap.c b/tools/testing/vma/tests/mmap.c new file mode 100644 index 000000000000..bded4ecbe5db --- /dev/null +++ b/tools/testing/vma/tests/mmap.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +static bool test_mmap_region_basic(void) +{ + struct mm_struct mm = {}; + unsigned long addr; + struct vm_area_struct *vma; + VMA_ITERATOR(vmi, &mm, 0); + + current->mm = &mm; + + /* Map at 0x300000, length 0x3000. */ + addr = __mmap_region(NULL, 0x300000, 0x3000, + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, + 0x300, NULL); + ASSERT_EQ(addr, 0x300000); + + /* Map at 0x250000, length 0x3000. */ + addr = __mmap_region(NULL, 0x250000, 0x3000, + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, + 0x250, NULL); + ASSERT_EQ(addr, 0x250000); + + /* Map at 0x303000, merging to 0x300000 of length 0x6000. */ + addr = __mmap_region(NULL, 0x303000, 0x3000, + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, + 0x303, NULL); + ASSERT_EQ(addr, 0x303000); + + /* Map at 0x24d000, merging to 0x250000 of length 0x6000. */ + addr = __mmap_region(NULL, 0x24d000, 0x3000, + VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE, + 0x24d, NULL); + ASSERT_EQ(addr, 0x24d000); + + ASSERT_EQ(mm.map_count, 2); + + for_each_vma(vmi, vma) { + if (vma->vm_start == 0x300000) { + ASSERT_EQ(vma->vm_end, 0x306000); + ASSERT_EQ(vma->vm_pgoff, 0x300); + } else if (vma->vm_start == 0x24d000) { + ASSERT_EQ(vma->vm_end, 0x253000); + ASSERT_EQ(vma->vm_pgoff, 0x24d); + } else { + ASSERT_FALSE(true); + } + } + + cleanup_mm(&mm, &vmi); + return true; +} + +static void run_mmap_tests(int *num_tests, int *num_fail) +{ + TEST(mmap_region_basic); +} diff --git a/tools/testing/vma/tests/vma.c b/tools/testing/vma/tests/vma.c new file mode 100644 index 000000000000..c54ffc954f11 --- /dev/null +++ b/tools/testing/vma/tests/vma.c @@ -0,0 +1,339 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +static bool compare_legacy_flags(vm_flags_t legacy_flags, vma_flags_t flags) +{ + const unsigned long legacy_val = legacy_flags; + /* The lower word should contain the precise same value. */ + const unsigned long flags_lower = flags.__vma_flags[0]; +#if NUM_VMA_FLAGS > BITS_PER_LONG + int i; + + /* All bits in higher flag values should be zero. */ + for (i = 1; i < NUM_VMA_FLAGS / BITS_PER_LONG; i++) { + if (flags.__vma_flags[i] != 0) + return false; + } +#endif + + static_assert(sizeof(legacy_flags) == sizeof(unsigned long)); + + return legacy_val == flags_lower; +} + +static bool test_copy_vma(void) +{ + vm_flags_t vm_flags = VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE; + struct mm_struct mm = {}; + bool need_locks = false; + VMA_ITERATOR(vmi, &mm, 0); + struct vm_area_struct *vma, *vma_new, *vma_next; + + /* Move backwards and do not merge. */ + + vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vm_flags); + vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks); + ASSERT_NE(vma_new, vma); + ASSERT_EQ(vma_new->vm_start, 0); + ASSERT_EQ(vma_new->vm_end, 0x2000); + ASSERT_EQ(vma_new->vm_pgoff, 0); + vma_assert_attached(vma_new); + + cleanup_mm(&mm, &vmi); + + /* Move a VMA into position next to another and merge the two. */ + + vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vm_flags); + vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vm_flags); + vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks); + vma_assert_attached(vma_new); + + ASSERT_EQ(vma_new, vma_next); + + cleanup_mm(&mm, &vmi); + return true; +} + +static bool test_vma_flags_unchanged(void) +{ + vma_flags_t flags = EMPTY_VMA_FLAGS; + vm_flags_t legacy_flags = 0; + int bit; + struct vm_area_struct vma; + struct vm_area_desc desc; + + + vma.flags = EMPTY_VMA_FLAGS; + desc.vma_flags = EMPTY_VMA_FLAGS; + + for (bit = 0; bit < BITS_PER_LONG; bit++) { + vma_flags_t mask = mk_vma_flags(bit); + + legacy_flags |= (1UL << bit); + + /* Individual flags. */ + vma_flags_set(&flags, bit); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags)); + + /* Via mask. */ + vma_flags_set_mask(&flags, mask); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags)); + + /* Same for VMA. */ + vma_set_flags(&vma, bit); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags)); + vma_set_flags_mask(&vma, mask); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags)); + + /* Same for VMA descriptor. */ + vma_desc_set_flags(&desc, bit); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags)); + vma_desc_set_flags_mask(&desc, mask); + ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags)); + } + + return true; +} + +static bool test_vma_flags_cleared(void) +{ + const vma_flags_t empty = EMPTY_VMA_FLAGS; + vma_flags_t flags; + int i; + + /* Set all bits high. */ + memset(&flags, 1, sizeof(flags)); + /* Try to clear. */ + vma_flags_clear_all(&flags); + /* Equal to EMPTY_VMA_FLAGS? */ + ASSERT_EQ(memcmp(&empty, &flags, sizeof(flags)), 0); + /* Make sure every unsigned long entry in bitmap array zero. */ + for (i = 0; i < sizeof(flags) / BITS_PER_LONG; i++) { + const unsigned long val = flags.__vma_flags[i]; + + ASSERT_EQ(val, 0); + } + + return true; +} + +/* + * Assert that VMA flag functions that operate at the system word level function + * correctly. + */ +static bool test_vma_flags_word(void) +{ + vma_flags_t flags = EMPTY_VMA_FLAGS; + const vma_flags_t comparison = + mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT, 64, 65); + + /* Set some custom high flags. */ + vma_flags_set(&flags, 64, 65); + /* Now overwrite the first word. */ + vma_flags_overwrite_word(&flags, VM_READ | VM_WRITE); + /* Ensure they are equal. */ + ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0); + + flags = EMPTY_VMA_FLAGS; + vma_flags_set(&flags, 64, 65); + + /* Do the same with the _once() equivalent. */ + vma_flags_overwrite_word_once(&flags, VM_READ | VM_WRITE); + ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0); + + flags = EMPTY_VMA_FLAGS; + vma_flags_set(&flags, 64, 65); + + /* Make sure we can set a word without disturbing other bits. */ + vma_flags_set(&flags, VMA_WRITE_BIT); + vma_flags_set_word(&flags, VM_READ); + ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0); + + flags = EMPTY_VMA_FLAGS; + vma_flags_set(&flags, 64, 65); + + /* Make sure we can clear a word without disturbing other bits. */ + vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT); + vma_flags_clear_word(&flags, VM_EXEC); + ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0); + + return true; +} + +/* Ensure that vma_flags_test() and friends works correctly. */ +static bool test_vma_flags_test(void) +{ + const vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT, + VMA_EXEC_BIT, 64, 65); + struct vm_area_struct vma; + struct vm_area_desc desc; + + vma.flags = flags; + desc.vma_flags = flags; + +#define do_test(...) \ + ASSERT_TRUE(vma_flags_test(&flags, __VA_ARGS__)); \ + ASSERT_TRUE(vma_desc_test_flags(&desc, __VA_ARGS__)) + +#define do_test_all_true(...) \ + ASSERT_TRUE(vma_flags_test_all(&flags, __VA_ARGS__)); \ + ASSERT_TRUE(vma_test_all_flags(&vma, __VA_ARGS__)) + +#define do_test_all_false(...) \ + ASSERT_FALSE(vma_flags_test_all(&flags, __VA_ARGS__)); \ + ASSERT_FALSE(vma_test_all_flags(&vma, __VA_ARGS__)) + + /* + * Testing for some flags that are present, some that are not - should + * pass. ANY flags matching should work. + */ + do_test(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT); + /* However, the ...test_all() variant should NOT pass. */ + do_test_all_false(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT); + /* But should pass for flags present. */ + do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65); + /* Also subsets... */ + do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64); + do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT); + do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT); + do_test_all_true(VMA_READ_BIT); + /* + * Check _mask variant. We don't need to test extensively as macro + * helper is the equivalent. + */ + ASSERT_TRUE(vma_flags_test_mask(&flags, flags)); + ASSERT_TRUE(vma_flags_test_all_mask(&flags, flags)); + + /* Single bits. */ + do_test(VMA_READ_BIT); + do_test(VMA_WRITE_BIT); + do_test(VMA_EXEC_BIT); +#if NUM_VMA_FLAG_BITS > 64 + do_test(64); + do_test(65); +#endif + + /* Two bits. */ + do_test(VMA_READ_BIT, VMA_WRITE_BIT); + do_test(VMA_READ_BIT, VMA_EXEC_BIT); + do_test(VMA_WRITE_BIT, VMA_EXEC_BIT); + /* Ordering shouldn't matter. */ + do_test(VMA_WRITE_BIT, VMA_READ_BIT); + do_test(VMA_EXEC_BIT, VMA_READ_BIT); + do_test(VMA_EXEC_BIT, VMA_WRITE_BIT); +#if NUM_VMA_FLAG_BITS > 64 + do_test(VMA_READ_BIT, 64); + do_test(VMA_WRITE_BIT, 64); + do_test(64, VMA_READ_BIT); + do_test(64, VMA_WRITE_BIT); + do_test(VMA_READ_BIT, 65); + do_test(VMA_WRITE_BIT, 65); + do_test(65, VMA_READ_BIT); + do_test(65, VMA_WRITE_BIT); +#endif + /* Three bits. */ + do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT); +#if NUM_VMA_FLAG_BITS > 64 + /* No need to consider every single permutation. */ + do_test(VMA_READ_BIT, VMA_WRITE_BIT, 64); + do_test(VMA_READ_BIT, VMA_WRITE_BIT, 65); + + /* Four bits. */ + do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64); + do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 65); + + /* Five bits. */ + do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65); +#endif + +#undef do_test +#undef do_test_all_true +#undef do_test_all_false + + return true; +} + +/* Ensure that vma_flags_clear() and friends works correctly. */ +static bool test_vma_flags_clear(void) +{ + vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT, + VMA_EXEC_BIT, 64, 65); + vma_flags_t mask = mk_vma_flags(VMA_EXEC_BIT, 64); + struct vm_area_struct vma; + struct vm_area_desc desc; + + vma.flags = flags; + desc.vma_flags = flags; + + /* Cursory check of _mask() variant, as the helper macros imply. */ + vma_flags_clear_mask(&flags, mask); + vma_flags_clear_mask(&vma.flags, mask); + vma_desc_clear_flags_mask(&desc, mask); + ASSERT_FALSE(vma_flags_test(&flags, VMA_EXEC_BIT, 64)); + ASSERT_FALSE(vma_flags_test(&vma.flags, VMA_EXEC_BIT, 64)); + ASSERT_FALSE(vma_desc_test_flags(&desc, VMA_EXEC_BIT, 64)); + /* Reset. */ + vma_flags_set(&flags, VMA_EXEC_BIT, 64); + vma_set_flags(&vma, VMA_EXEC_BIT, 64); + vma_desc_set_flags(&desc, VMA_EXEC_BIT, 64); + + /* + * Clear the flags and assert clear worked, then reset flags back to + * include specified flags. + */ +#define do_test_and_reset(...) \ + vma_flags_clear(&flags, __VA_ARGS__); \ + vma_flags_clear(&vma.flags, __VA_ARGS__); \ + vma_desc_clear_flags(&desc, __VA_ARGS__); \ + ASSERT_FALSE(vma_flags_test(&flags, __VA_ARGS__)); \ + ASSERT_FALSE(vma_flags_test(&vma.flags, __VA_ARGS__)); \ + ASSERT_FALSE(vma_desc_test_flags(&desc, __VA_ARGS__)); \ + vma_flags_set(&flags, __VA_ARGS__); \ + vma_set_flags(&vma, __VA_ARGS__); \ + vma_desc_set_flags(&desc, __VA_ARGS__) + + /* Single flags. */ + do_test_and_reset(VMA_READ_BIT); + do_test_and_reset(VMA_WRITE_BIT); + do_test_and_reset(VMA_EXEC_BIT); + do_test_and_reset(64); + do_test_and_reset(65); + + /* Two flags, in different orders. */ + do_test_and_reset(VMA_READ_BIT, VMA_WRITE_BIT); + do_test_and_reset(VMA_READ_BIT, VMA_EXEC_BIT); + do_test_and_reset(VMA_READ_BIT, 64); + do_test_and_reset(VMA_READ_BIT, 65); + do_test_and_reset(VMA_WRITE_BIT, VMA_READ_BIT); + do_test_and_reset(VMA_WRITE_BIT, VMA_EXEC_BIT); + do_test_and_reset(VMA_WRITE_BIT, 64); + do_test_and_reset(VMA_WRITE_BIT, 65); + do_test_and_reset(VMA_EXEC_BIT, VMA_READ_BIT); + do_test_and_reset(VMA_EXEC_BIT, VMA_WRITE_BIT); + do_test_and_reset(VMA_EXEC_BIT, 64); + do_test_and_reset(VMA_EXEC_BIT, 65); + do_test_and_reset(64, VMA_READ_BIT); + do_test_and_reset(64, VMA_WRITE_BIT); + do_test_and_reset(64, VMA_EXEC_BIT); + do_test_and_reset(64, 65); + do_test_and_reset(65, VMA_READ_BIT); + do_test_and_reset(65, VMA_WRITE_BIT); + do_test_and_reset(65, VMA_EXEC_BIT); + do_test_and_reset(65, 64); + + /* Three flags. */ + +#undef do_test_some_missing +#undef do_test_and_reset + + return true; +} + +static void run_vma_tests(int *num_tests, int *num_fail) +{ + TEST(copy_vma); + TEST(vma_flags_unchanged); + TEST(vma_flags_cleared); + TEST(vma_flags_word); + TEST(vma_flags_test); + TEST(vma_flags_clear); +} diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h index 7fa56dcc53a6..0e1121e2ef23 100644 --- a/tools/testing/vma/vma_internal.h +++ b/tools/testing/vma/vma_internal.h @@ -12,16 +12,18 @@ #ifndef __MM_VMA_INTERNAL_H #define __MM_VMA_INTERNAL_H -#define __private -#define __bitwise -#define __randomize_layout +#include #define CONFIG_MMU #define CONFIG_PER_VMA_LOCK -#include +#ifdef __CONCAT +#undef __CONCAT +#endif +#include #include +#include #include #include #include @@ -29,1839 +31,28 @@ #include #include -extern unsigned long stack_guard_gap; -#ifdef CONFIG_MMU -extern unsigned long mmap_min_addr; -extern unsigned long dac_mmap_min_addr; -#else -#define mmap_min_addr 0UL -#define dac_mmap_min_addr 0UL -#endif - -#define VM_WARN_ON(_expr) (WARN_ON(_expr)) -#define VM_WARN_ON_ONCE(_expr) (WARN_ON_ONCE(_expr)) -#define VM_WARN_ON_VMG(_expr, _vmg) (WARN_ON(_expr)) -#define VM_BUG_ON(_expr) (BUG_ON(_expr)) -#define VM_BUG_ON_VMA(_expr, _vma) (BUG_ON(_expr)) - -#define MMF_HAS_MDWE 28 - /* - * vm_flags in vm_area_struct, see mm_types.h. - * When changing, update also include/trace/events/mmflags.h + * DUPLICATE typedef definitions from kernel source that have to be declared + * ahead of all other headers. */ - -#define VM_NONE 0x00000000 - -/** - * typedef vma_flag_t - specifies an individual VMA flag by bit number. - * - * This value is made type safe by sparse to avoid passing invalid flag values - * around. - */ -typedef int __bitwise vma_flag_t; - -#define DECLARE_VMA_BIT(name, bitnum) \ - VMA_ ## name ## _BIT = ((__force vma_flag_t)bitnum) -#define DECLARE_VMA_BIT_ALIAS(name, aliased) \ - VMA_ ## name ## _BIT = VMA_ ## aliased ## _BIT -enum { - DECLARE_VMA_BIT(READ, 0), - DECLARE_VMA_BIT(WRITE, 1), - DECLARE_VMA_BIT(EXEC, 2), - DECLARE_VMA_BIT(SHARED, 3), - /* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */ - DECLARE_VMA_BIT(MAYREAD, 4), /* limits for mprotect() etc. */ - DECLARE_VMA_BIT(MAYWRITE, 5), - DECLARE_VMA_BIT(MAYEXEC, 6), - DECLARE_VMA_BIT(MAYSHARE, 7), - DECLARE_VMA_BIT(GROWSDOWN, 8), /* general info on the segment */ -#ifdef CONFIG_MMU - DECLARE_VMA_BIT(UFFD_MISSING, 9),/* missing pages tracking */ -#else - /* nommu: R/O MAP_PRIVATE mapping that might overlay a file mapping */ - DECLARE_VMA_BIT(MAYOVERLAY, 9), -#endif /* CONFIG_MMU */ - /* Page-ranges managed without "struct page", just pure PFN */ - DECLARE_VMA_BIT(PFNMAP, 10), - DECLARE_VMA_BIT(MAYBE_GUARD, 11), - DECLARE_VMA_BIT(UFFD_WP, 12), /* wrprotect pages tracking */ - DECLARE_VMA_BIT(LOCKED, 13), - DECLARE_VMA_BIT(IO, 14), /* Memory mapped I/O or similar */ - DECLARE_VMA_BIT(SEQ_READ, 15), /* App will access data sequentially */ - DECLARE_VMA_BIT(RAND_READ, 16), /* App will not benefit from clustered reads */ - DECLARE_VMA_BIT(DONTCOPY, 17), /* Do not copy this vma on fork */ - DECLARE_VMA_BIT(DONTEXPAND, 18),/* Cannot expand with mremap() */ - DECLARE_VMA_BIT(LOCKONFAULT, 19),/* Lock pages covered when faulted in */ - DECLARE_VMA_BIT(ACCOUNT, 20), /* Is a VM accounted object */ - DECLARE_VMA_BIT(NORESERVE, 21), /* should the VM suppress accounting */ - DECLARE_VMA_BIT(HUGETLB, 22), /* Huge TLB Page VM */ - DECLARE_VMA_BIT(SYNC, 23), /* Synchronous page faults */ - DECLARE_VMA_BIT(ARCH_1, 24), /* Architecture-specific flag */ - DECLARE_VMA_BIT(WIPEONFORK, 25),/* Wipe VMA contents in child. */ - DECLARE_VMA_BIT(DONTDUMP, 26), /* Do not include in the core dump */ - DECLARE_VMA_BIT(SOFTDIRTY, 27), /* NOT soft dirty clean area */ - DECLARE_VMA_BIT(MIXEDMAP, 28), /* Can contain struct page and pure PFN pages */ - DECLARE_VMA_BIT(HUGEPAGE, 29), /* MADV_HUGEPAGE marked this vma */ - DECLARE_VMA_BIT(NOHUGEPAGE, 30),/* MADV_NOHUGEPAGE marked this vma */ - DECLARE_VMA_BIT(MERGEABLE, 31), /* KSM may merge identical pages */ - /* These bits are reused, we define specific uses below. */ - DECLARE_VMA_BIT(HIGH_ARCH_0, 32), - DECLARE_VMA_BIT(HIGH_ARCH_1, 33), - DECLARE_VMA_BIT(HIGH_ARCH_2, 34), - DECLARE_VMA_BIT(HIGH_ARCH_3, 35), - DECLARE_VMA_BIT(HIGH_ARCH_4, 36), - DECLARE_VMA_BIT(HIGH_ARCH_5, 37), - DECLARE_VMA_BIT(HIGH_ARCH_6, 38), - /* - * This flag is used to connect VFIO to arch specific KVM code. It - * indicates that the memory under this VMA is safe for use with any - * non-cachable memory type inside KVM. Some VFIO devices, on some - * platforms, are thought to be unsafe and can cause machine crashes - * if KVM does not lock down the memory type. - */ - DECLARE_VMA_BIT(ALLOW_ANY_UNCACHED, 39), -#ifdef CONFIG_PPC32 - DECLARE_VMA_BIT_ALIAS(DROPPABLE, ARCH_1), -#else - DECLARE_VMA_BIT(DROPPABLE, 40), -#endif - DECLARE_VMA_BIT(UFFD_MINOR, 41), - DECLARE_VMA_BIT(SEALED, 42), - /* Flags that reuse flags above. */ - DECLARE_VMA_BIT_ALIAS(PKEY_BIT0, HIGH_ARCH_0), - DECLARE_VMA_BIT_ALIAS(PKEY_BIT1, HIGH_ARCH_1), - DECLARE_VMA_BIT_ALIAS(PKEY_BIT2, HIGH_ARCH_2), - DECLARE_VMA_BIT_ALIAS(PKEY_BIT3, HIGH_ARCH_3), - DECLARE_VMA_BIT_ALIAS(PKEY_BIT4, HIGH_ARCH_4), -#if defined(CONFIG_X86_USER_SHADOW_STACK) - /* - * VM_SHADOW_STACK should not be set with VM_SHARED because of lack of - * support core mm. - * - * These VMAs will get a single end guard page. This helps userspace - * protect itself from attacks. A single page is enough for current - * shadow stack archs (x86). See the comments near alloc_shstk() in - * arch/x86/kernel/shstk.c for more details on the guard size. - */ - DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_5), -#elif defined(CONFIG_ARM64_GCS) - /* - * arm64's Guarded Control Stack implements similar functionality and - * has similar constraints to shadow stacks. - */ - DECLARE_VMA_BIT_ALIAS(SHADOW_STACK, HIGH_ARCH_6), -#endif - DECLARE_VMA_BIT_ALIAS(SAO, ARCH_1), /* Strong Access Ordering (powerpc) */ - DECLARE_VMA_BIT_ALIAS(GROWSUP, ARCH_1), /* parisc */ - DECLARE_VMA_BIT_ALIAS(SPARC_ADI, ARCH_1), /* sparc64 */ - DECLARE_VMA_BIT_ALIAS(ARM64_BTI, ARCH_1), /* arm64 */ - DECLARE_VMA_BIT_ALIAS(ARCH_CLEAR, ARCH_1), /* sparc64, arm64 */ - DECLARE_VMA_BIT_ALIAS(MAPPED_COPY, ARCH_1), /* !CONFIG_MMU */ - DECLARE_VMA_BIT_ALIAS(MTE, HIGH_ARCH_4), /* arm64 */ - DECLARE_VMA_BIT_ALIAS(MTE_ALLOWED, HIGH_ARCH_5),/* arm64 */ -#ifdef CONFIG_STACK_GROWSUP - DECLARE_VMA_BIT_ALIAS(STACK, GROWSUP), - DECLARE_VMA_BIT_ALIAS(STACK_EARLY, GROWSDOWN), -#else - DECLARE_VMA_BIT_ALIAS(STACK, GROWSDOWN), -#endif -}; - -#define INIT_VM_FLAG(name) BIT((__force int) VMA_ ## name ## _BIT) -#define VM_READ INIT_VM_FLAG(READ) -#define VM_WRITE INIT_VM_FLAG(WRITE) -#define VM_EXEC INIT_VM_FLAG(EXEC) -#define VM_SHARED INIT_VM_FLAG(SHARED) -#define VM_MAYREAD INIT_VM_FLAG(MAYREAD) -#define VM_MAYWRITE INIT_VM_FLAG(MAYWRITE) -#define VM_MAYEXEC INIT_VM_FLAG(MAYEXEC) -#define VM_MAYSHARE INIT_VM_FLAG(MAYSHARE) -#define VM_GROWSDOWN INIT_VM_FLAG(GROWSDOWN) -#ifdef CONFIG_MMU -#define VM_UFFD_MISSING INIT_VM_FLAG(UFFD_MISSING) -#else -#define VM_UFFD_MISSING VM_NONE -#define VM_MAYOVERLAY INIT_VM_FLAG(MAYOVERLAY) -#endif -#define VM_PFNMAP INIT_VM_FLAG(PFNMAP) -#define VM_MAYBE_GUARD INIT_VM_FLAG(MAYBE_GUARD) -#define VM_UFFD_WP INIT_VM_FLAG(UFFD_WP) -#define VM_LOCKED INIT_VM_FLAG(LOCKED) -#define VM_IO INIT_VM_FLAG(IO) -#define VM_SEQ_READ INIT_VM_FLAG(SEQ_READ) -#define VM_RAND_READ INIT_VM_FLAG(RAND_READ) -#define VM_DONTCOPY INIT_VM_FLAG(DONTCOPY) -#define VM_DONTEXPAND INIT_VM_FLAG(DONTEXPAND) -#define VM_LOCKONFAULT INIT_VM_FLAG(LOCKONFAULT) -#define VM_ACCOUNT INIT_VM_FLAG(ACCOUNT) -#define VM_NORESERVE INIT_VM_FLAG(NORESERVE) -#define VM_HUGETLB INIT_VM_FLAG(HUGETLB) -#define VM_SYNC INIT_VM_FLAG(SYNC) -#define VM_ARCH_1 INIT_VM_FLAG(ARCH_1) -#define VM_WIPEONFORK INIT_VM_FLAG(WIPEONFORK) -#define VM_DONTDUMP INIT_VM_FLAG(DONTDUMP) -#ifdef CONFIG_MEM_SOFT_DIRTY -#define VM_SOFTDIRTY INIT_VM_FLAG(SOFTDIRTY) -#else -#define VM_SOFTDIRTY VM_NONE -#endif -#define VM_MIXEDMAP INIT_VM_FLAG(MIXEDMAP) -#define VM_HUGEPAGE INIT_VM_FLAG(HUGEPAGE) -#define VM_NOHUGEPAGE INIT_VM_FLAG(NOHUGEPAGE) -#define VM_MERGEABLE INIT_VM_FLAG(MERGEABLE) -#define VM_STACK INIT_VM_FLAG(STACK) -#ifdef CONFIG_STACK_GROWS_UP -#define VM_STACK_EARLY INIT_VM_FLAG(STACK_EARLY) -#else -#define VM_STACK_EARLY VM_NONE -#endif -#ifdef CONFIG_ARCH_HAS_PKEYS -#define VM_PKEY_SHIFT ((__force int)VMA_HIGH_ARCH_0_BIT) -/* Despite the naming, these are FLAGS not bits. */ -#define VM_PKEY_BIT0 INIT_VM_FLAG(PKEY_BIT0) -#define VM_PKEY_BIT1 INIT_VM_FLAG(PKEY_BIT1) -#define VM_PKEY_BIT2 INIT_VM_FLAG(PKEY_BIT2) -#if CONFIG_ARCH_PKEY_BITS > 3 -#define VM_PKEY_BIT3 INIT_VM_FLAG(PKEY_BIT3) -#else -#define VM_PKEY_BIT3 VM_NONE -#endif /* CONFIG_ARCH_PKEY_BITS > 3 */ -#if CONFIG_ARCH_PKEY_BITS > 4 -#define VM_PKEY_BIT4 INIT_VM_FLAG(PKEY_BIT4) -#else -#define VM_PKEY_BIT4 VM_NONE -#endif /* CONFIG_ARCH_PKEY_BITS > 4 */ -#endif /* CONFIG_ARCH_HAS_PKEYS */ -#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_ARM64_GCS) -#define VM_SHADOW_STACK INIT_VM_FLAG(SHADOW_STACK) -#else -#define VM_SHADOW_STACK VM_NONE -#endif -#if defined(CONFIG_PPC64) -#define VM_SAO INIT_VM_FLAG(SAO) -#elif defined(CONFIG_PARISC) -#define VM_GROWSUP INIT_VM_FLAG(GROWSUP) -#elif defined(CONFIG_SPARC64) -#define VM_SPARC_ADI INIT_VM_FLAG(SPARC_ADI) -#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR) -#elif defined(CONFIG_ARM64) -#define VM_ARM64_BTI INIT_VM_FLAG(ARM64_BTI) -#define VM_ARCH_CLEAR INIT_VM_FLAG(ARCH_CLEAR) -#elif !defined(CONFIG_MMU) -#define VM_MAPPED_COPY INIT_VM_FLAG(MAPPED_COPY) -#endif -#ifndef VM_GROWSUP -#define VM_GROWSUP VM_NONE -#endif -#ifdef CONFIG_ARM64_MTE -#define VM_MTE INIT_VM_FLAG(MTE) -#define VM_MTE_ALLOWED INIT_VM_FLAG(MTE_ALLOWED) -#else -#define VM_MTE VM_NONE -#define VM_MTE_ALLOWED VM_NONE -#endif -#ifdef CONFIG_HAVE_ARCH_USERFAULTFD_MINOR -#define VM_UFFD_MINOR INIT_VM_FLAG(UFFD_MINOR) -#else -#define VM_UFFD_MINOR VM_NONE -#endif -#ifdef CONFIG_64BIT -#define VM_ALLOW_ANY_UNCACHED INIT_VM_FLAG(ALLOW_ANY_UNCACHED) -#define VM_SEALED INIT_VM_FLAG(SEALED) -#else -#define VM_ALLOW_ANY_UNCACHED VM_NONE -#define VM_SEALED VM_NONE -#endif -#if defined(CONFIG_64BIT) || defined(CONFIG_PPC32) -#define VM_DROPPABLE INIT_VM_FLAG(DROPPABLE) -#else -#define VM_DROPPABLE VM_NONE -#endif - -/* Bits set in the VMA until the stack is in its final location */ -#define VM_STACK_INCOMPLETE_SETUP (VM_RAND_READ | VM_SEQ_READ | VM_STACK_EARLY) - -#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) - -/* Common data flag combinations */ -#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -#define VM_DATA_FLAGS_NON_EXEC (VM_READ | VM_WRITE | VM_MAYREAD | \ - VM_MAYWRITE | VM_MAYEXEC) -#define VM_DATA_FLAGS_EXEC (VM_READ | VM_WRITE | VM_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#ifndef VM_DATA_DEFAULT_FLAGS /* arch can override this */ -#define VM_DATA_DEFAULT_FLAGS VM_DATA_FLAGS_EXEC -#endif - -#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ -#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS -#endif - -#define VM_STARTGAP_FLAGS (VM_GROWSDOWN | VM_SHADOW_STACK) - -#define VM_STACK_FLAGS (VM_STACK | VM_STACK_DEFAULT_FLAGS | VM_ACCOUNT) - -/* VMA basic access permission flags */ -#define VM_ACCESS_FLAGS (VM_READ | VM_WRITE | VM_EXEC) - -/* - * Special vmas that are non-mergable, non-mlock()able. - */ -#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_PFNMAP | VM_MIXEDMAP) - -#define DEFAULT_MAP_WINDOW ((1UL << 47) - PAGE_SIZE) -#define TASK_SIZE_LOW DEFAULT_MAP_WINDOW -#define TASK_SIZE_MAX DEFAULT_MAP_WINDOW -#define STACK_TOP TASK_SIZE_LOW -#define STACK_TOP_MAX TASK_SIZE_MAX - -/* This mask represents all the VMA flag bits used by mlock */ -#define VM_LOCKED_MASK (VM_LOCKED | VM_LOCKONFAULT) - -#define TASK_EXEC ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) - -#define VM_DATA_FLAGS_TSK_EXEC (VM_READ | VM_WRITE | TASK_EXEC | \ - VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) - -#define RLIMIT_STACK 3 /* max stack size */ -#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ - -#define CAP_IPC_LOCK 14 - -/* - * Flags which should be 'sticky' on merge - that is, flags which, when one VMA - * possesses it but the other does not, the merged VMA should nonetheless have - * applied to it: - * - * VM_SOFTDIRTY - if a VMA is marked soft-dirty, that is has not had its - * references cleared via /proc/$pid/clear_refs, any merged VMA - * should be considered soft-dirty also as it operates at a VMA - * granularity. - */ -#define VM_STICKY (VM_SOFTDIRTY | VM_MAYBE_GUARD) - -/* - * VMA flags we ignore for the purposes of merge, i.e. one VMA possessing one - * of these flags and the other not does not preclude a merge. - * - * VM_STICKY - When merging VMAs, VMA flags must match, unless they are - * 'sticky'. If any sticky flags exist in either VMA, we simply - * set all of them on the merged VMA. - */ -#define VM_IGNORE_MERGE VM_STICKY - -/* - * Flags which should result in page tables being copied on fork. These are - * flags which indicate that the VMA maps page tables which cannot be - * reconsistuted upon page fault, so necessitate page table copying upon - * - * VM_PFNMAP / VM_MIXEDMAP - These contain kernel-mapped data which cannot be - * reasonably reconstructed on page fault. - * - * VM_UFFD_WP - Encodes metadata about an installed uffd - * write protect handler, which cannot be - * reconstructed on page fault. - * - * We always copy pgtables when dst_vma has uffd-wp - * enabled even if it's file-backed - * (e.g. shmem). Because when uffd-wp is enabled, - * pgtable contains uffd-wp protection information, - * that's something we can't retrieve from page cache, - * and skip copying will lose those info. - * - * VM_MAYBE_GUARD - Could contain page guard region markers which - * by design are a property of the page tables - * only and thus cannot be reconstructed on page - * fault. - */ -#define VM_COPY_ON_FORK (VM_PFNMAP | VM_MIXEDMAP | VM_UFFD_WP | VM_MAYBE_GUARD) - -#define FIRST_USER_ADDRESS 0UL -#define USER_PGTABLES_CEILING 0UL - -#define vma_policy(vma) NULL - -#define down_write_nest_lock(sem, nest_lock) - -#define pgprot_val(x) ((x).pgprot) -#define __pgprot(x) ((pgprot_t) { (x) } ) - -#define for_each_vma(__vmi, __vma) \ - while (((__vma) = vma_next(&(__vmi))) != NULL) - -/* The MM code likes to work with exclusive end addresses */ -#define for_each_vma_range(__vmi, __vma, __end) \ - while (((__vma) = vma_find(&(__vmi), (__end))) != NULL) - -#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) - -#define PHYS_PFN(x) ((unsigned long)((x) >> PAGE_SHIFT)) - -#define test_and_set_bit(nr, addr) __test_and_set_bit(nr, addr) -#define test_and_clear_bit(nr, addr) __test_and_clear_bit(nr, addr) - -#define TASK_SIZE ((1ul << 47)-PAGE_SIZE) - -#define AS_MM_ALL_LOCKS 2 - -/* We hardcode this for now. */ -#define sysctl_max_map_count 0x1000000UL - -#define pgoff_t unsigned long -typedef unsigned long pgprotval_t; -typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; -typedef unsigned long vm_flags_t; -typedef __bitwise unsigned int vm_fault_t; - -/* - * The shared stubs do not implement this, it amounts to an fprintf(STDERR,...) - * either way :) - */ -#define pr_warn_once pr_err - -#define data_race(expr) expr - -#define ASSERT_EXCLUSIVE_WRITER(x) - -#define pgtable_supports_soft_dirty() 1 - -/** - * swap - swap values of @a and @b - * @a: first value - * @b: second value - */ -#define swap(a, b) \ - do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) - -struct kref { - refcount_t refcount; -}; - -/* - * Define the task command name length as enum, then it can be visible to - * BPF programs. - */ -enum { - TASK_COMM_LEN = 16, -}; - -/* - * Flags for bug emulation. - * - * These occupy the top three bytes. - */ -enum { - READ_IMPLIES_EXEC = 0x0400000, -}; - -struct task_struct { - char comm[TASK_COMM_LEN]; - pid_t pid; - struct mm_struct *mm; - - /* Used for emulating ABI behavior of previous Linux versions: */ - unsigned int personality; -}; - -struct task_struct *get_current(void); -#define current get_current() - -struct anon_vma { - struct anon_vma *root; - struct rb_root_cached rb_root; - - /* Test fields. */ - bool was_cloned; - bool was_unlinked; -}; - -struct anon_vma_chain { - struct anon_vma *anon_vma; - struct list_head same_vma; -}; - -struct anon_vma_name { - struct kref kref; - /* The name needs to be at the end because it is dynamically sized. */ - char name[]; -}; - -struct vma_iterator { - struct ma_state mas; -}; - -#define VMA_ITERATOR(name, __mm, __addr) \ - struct vma_iterator name = { \ - .mas = { \ - .tree = &(__mm)->mm_mt, \ - .index = __addr, \ - .node = NULL, \ - .status = ma_start, \ - }, \ - } - -struct address_space { - struct rb_root_cached i_mmap; - unsigned long flags; - atomic_t i_mmap_writable; -}; - -struct vm_userfaultfd_ctx {}; -struct mempolicy {}; -struct mmu_gather {}; -struct mutex {}; -#define DEFINE_MUTEX(mutexname) \ - struct mutex mutexname = {} - -#define DECLARE_BITMAP(name, bits) \ - unsigned long name[BITS_TO_LONGS(bits)] - -#define NUM_MM_FLAG_BITS (64) +#define __private +/* NUM_MM_FLAG_BITS defined by test code. */ typedef struct { __private DECLARE_BITMAP(__mm_flags, NUM_MM_FLAG_BITS); } mm_flags_t; - -/* - * Opaque type representing current VMA (vm_area_struct) flag state. Must be - * accessed via vma_flags_xxx() helper functions. - */ -#define NUM_VMA_FLAG_BITS BITS_PER_LONG +/* NUM_VMA_FLAG_BITS defined by test code. */ typedef struct { DECLARE_BITMAP(__vma_flags, NUM_VMA_FLAG_BITS); } __private vma_flags_t; -struct mm_struct { - struct maple_tree mm_mt; - int map_count; /* number of VMAs */ - unsigned long total_vm; /* Total pages mapped */ - unsigned long locked_vm; /* Pages that have PG_mlocked set */ - unsigned long data_vm; /* VM_WRITE & ~VM_SHARED & ~VM_STACK */ - unsigned long exec_vm; /* VM_EXEC & ~VM_WRITE & ~VM_STACK */ - unsigned long stack_vm; /* VM_STACK */ - - unsigned long def_flags; - - mm_flags_t flags; /* Must use mm_flags_* helpers to access */ -}; - -struct vm_area_struct; - - -/* What action should be taken after an .mmap_prepare call is complete? */ -enum mmap_action_type { - MMAP_NOTHING, /* Mapping is complete, no further action. */ - MMAP_REMAP_PFN, /* Remap PFN range. */ - MMAP_IO_REMAP_PFN, /* I/O remap PFN range. */ -}; - -/* - * Describes an action an mmap_prepare hook can instruct to be taken to complete - * the mapping of a VMA. Specified in vm_area_desc. - */ -struct mmap_action { - union { - /* Remap range. */ - struct { - unsigned long start; - unsigned long start_pfn; - unsigned long size; - pgprot_t pgprot; - } remap; - }; - enum mmap_action_type type; - - /* - * If specified, this hook is invoked after the selected action has been - * successfully completed. Note that the VMA write lock still held. - * - * The absolute minimum ought to be done here. - * - * Returns 0 on success, or an error code. - */ - int (*success_hook)(const struct vm_area_struct *vma); - - /* - * If specified, this hook is invoked when an error occurred when - * attempting the selection action. - * - * The hook can return an error code in order to filter the error, but - * it is not valid to clear the error here. - */ - int (*error_hook)(int err); - - /* - * This should be set in rare instances where the operation required - * that the rmap should not be able to access the VMA until - * completely set up. - */ - bool hide_from_rmap_until_complete :1; -}; - -/* Operations which modify VMAs. */ -enum vma_operation { - VMA_OP_SPLIT, - VMA_OP_MERGE_UNFAULTED, - VMA_OP_REMAP, - VMA_OP_FORK, -}; - -/* - * Describes a VMA that is about to be mmap()'ed. Drivers may choose to - * manipulate mutable fields which will cause those fields to be updated in the - * resultant VMA. - * - * Helper functions are not required for manipulating any field. - */ -struct vm_area_desc { - /* Immutable state. */ - const struct mm_struct *const mm; - struct file *const file; /* May vary from vm_file in stacked callers. */ - unsigned long start; - unsigned long end; - - /* Mutable fields. Populated with initial state. */ - pgoff_t pgoff; - struct file *vm_file; - union { - vm_flags_t vm_flags; - vma_flags_t vma_flags; - }; - pgprot_t page_prot; - - /* Write-only fields. */ - const struct vm_operations_struct *vm_ops; - void *private_data; - - /* Take further action? */ - struct mmap_action action; -}; - -struct file_operations { - int (*mmap)(struct file *, struct vm_area_struct *); - int (*mmap_prepare)(struct vm_area_desc *); -}; - -struct file { - struct address_space *f_mapping; - const struct file_operations *f_op; -}; - -#define VMA_LOCK_OFFSET 0x40000000 - -typedef struct { unsigned long v; } freeptr_t; - -struct vm_area_struct { - /* The first cache line has the info for VMA tree walking. */ - - union { - struct { - /* VMA covers [vm_start; vm_end) addresses within mm */ - unsigned long vm_start; - unsigned long vm_end; - }; - freeptr_t vm_freeptr; /* Pointer used by SLAB_TYPESAFE_BY_RCU */ - }; - - struct mm_struct *vm_mm; /* The address space we belong to. */ - pgprot_t vm_page_prot; /* Access permissions of this VMA. */ - - /* - * Flags, see mm.h. - * To modify use vm_flags_{init|reset|set|clear|mod} functions. - */ - union { - const vm_flags_t vm_flags; - vma_flags_t flags; - }; - -#ifdef CONFIG_PER_VMA_LOCK - /* - * Can only be written (using WRITE_ONCE()) while holding both: - * - mmap_lock (in write mode) - * - vm_refcnt bit at VMA_LOCK_OFFSET is set - * Can be read reliably while holding one of: - * - mmap_lock (in read or write mode) - * - vm_refcnt bit at VMA_LOCK_OFFSET is set or vm_refcnt > 1 - * Can be read unreliably (using READ_ONCE()) for pessimistic bailout - * while holding nothing (except RCU to keep the VMA struct allocated). - * - * This sequence counter is explicitly allowed to overflow; sequence - * counter reuse can only lead to occasional unnecessary use of the - * slowpath. - */ - unsigned int vm_lock_seq; -#endif - - /* - * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma - * list, after a COW of one of the file pages. A MAP_SHARED vma - * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack - * or brk vma (with NULL file) can only be in an anon_vma list. - */ - struct list_head anon_vma_chain; /* Serialized by mmap_lock & - * page_table_lock */ - struct anon_vma *anon_vma; /* Serialized by page_table_lock */ - - /* Function pointers to deal with this struct. */ - const struct vm_operations_struct *vm_ops; - - /* Information about our backing store: */ - unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE - units */ - struct file * vm_file; /* File we map to (can be NULL). */ - void * vm_private_data; /* was vm_pte (shared mem) */ - -#ifdef CONFIG_SWAP - atomic_long_t swap_readahead_info; -#endif -#ifndef CONFIG_MMU - struct vm_region *vm_region; /* NOMMU mapping region */ -#endif -#ifdef CONFIG_NUMA - struct mempolicy *vm_policy; /* NUMA policy for the VMA */ -#endif -#ifdef CONFIG_NUMA_BALANCING - struct vma_numab_state *numab_state; /* NUMA Balancing state */ -#endif -#ifdef CONFIG_PER_VMA_LOCK - /* Unstable RCU readers are allowed to read this. */ - refcount_t vm_refcnt; -#endif - /* - * For areas with an address space and backing store, - * linkage into the address_space->i_mmap interval tree. - * - */ - struct { - struct rb_node rb; - unsigned long rb_subtree_last; - } shared; -#ifdef CONFIG_ANON_VMA_NAME - /* - * For private and shared anonymous mappings, a pointer to a null - * terminated string containing the name given to the vma, or NULL if - * unnamed. Serialized by mmap_lock. Use anon_vma_name to access. - */ - struct anon_vma_name *anon_name; -#endif - struct vm_userfaultfd_ctx vm_userfaultfd_ctx; -} __randomize_layout; - -struct vm_fault {}; - -struct vm_operations_struct { - void (*open)(struct vm_area_struct * area); - /** - * @close: Called when the VMA is being removed from the MM. - * Context: User context. May sleep. Caller holds mmap_lock. - */ - void (*close)(struct vm_area_struct * area); - /* Called any time before splitting to check if it's allowed */ - int (*may_split)(struct vm_area_struct *area, unsigned long addr); - int (*mremap)(struct vm_area_struct *area); - /* - * Called by mprotect() to make driver-specific permission - * checks before mprotect() is finalised. The VMA must not - * be modified. Returns 0 if mprotect() can proceed. - */ - int (*mprotect)(struct vm_area_struct *vma, unsigned long start, - unsigned long end, unsigned long newflags); - vm_fault_t (*fault)(struct vm_fault *vmf); - vm_fault_t (*huge_fault)(struct vm_fault *vmf, unsigned int order); - vm_fault_t (*map_pages)(struct vm_fault *vmf, - pgoff_t start_pgoff, pgoff_t end_pgoff); - unsigned long (*pagesize)(struct vm_area_struct * area); - - /* notification that a previously read-only page is about to become - * writable, if an error is returned it will cause a SIGBUS */ - vm_fault_t (*page_mkwrite)(struct vm_fault *vmf); - - /* same as page_mkwrite when using VM_PFNMAP|VM_MIXEDMAP */ - vm_fault_t (*pfn_mkwrite)(struct vm_fault *vmf); - - /* called by access_process_vm when get_user_pages() fails, typically - * for use by special VMAs. See also generic_access_phys() for a generic - * implementation useful for any iomem mapping. - */ - int (*access)(struct vm_area_struct *vma, unsigned long addr, - void *buf, int len, int write); - - /* Called by the /proc/PID/maps code to ask the vma whether it - * has a special name. Returning non-NULL will also cause this - * vma to be dumped unconditionally. */ - const char *(*name)(struct vm_area_struct *vma); - -#ifdef CONFIG_NUMA - /* - * set_policy() op must add a reference to any non-NULL @new mempolicy - * to hold the policy upon return. Caller should pass NULL @new to - * remove a policy and fall back to surrounding context--i.e. do not - * install a MPOL_DEFAULT policy, nor the task or system default - * mempolicy. - */ - int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new); - - /* - * get_policy() op must add reference [mpol_get()] to any policy at - * (vma,addr) marked as MPOL_SHARED. The shared policy infrastructure - * in mm/mempolicy.c will do this automatically. - * get_policy() must NOT add a ref if the policy at (vma,addr) is not - * marked as MPOL_SHARED. vma policies are protected by the mmap_lock. - * If no [shared/vma] mempolicy exists at the addr, get_policy() op - * must return NULL--i.e., do not "fallback" to task or system default - * policy. - */ - struct mempolicy *(*get_policy)(struct vm_area_struct *vma, - unsigned long addr, pgoff_t *ilx); -#endif -#ifdef CONFIG_FIND_NORMAL_PAGE - /* - * Called by vm_normal_page() for special PTEs in @vma at @addr. This - * allows for returning a "normal" page from vm_normal_page() even - * though the PTE indicates that the "struct page" either does not exist - * or should not be touched: "special". - * - * Do not add new users: this really only works when a "normal" page - * was mapped, but then the PTE got changed to something weird (+ - * marked special) that would not make pte_pfn() identify the originally - * inserted page. - */ - struct page *(*find_normal_page)(struct vm_area_struct *vma, - unsigned long addr); -#endif /* CONFIG_FIND_NORMAL_PAGE */ -}; - -struct vm_unmapped_area_info { -#define VM_UNMAPPED_AREA_TOPDOWN 1 - unsigned long flags; - unsigned long length; - unsigned long low_limit; - unsigned long high_limit; - unsigned long align_mask; - unsigned long align_offset; - unsigned long start_gap; -}; - -struct pagetable_move_control { - struct vm_area_struct *old; /* Source VMA. */ - struct vm_area_struct *new; /* Destination VMA. */ - unsigned long old_addr; /* Address from which the move begins. */ - unsigned long old_end; /* Exclusive address at which old range ends. */ - unsigned long new_addr; /* Address to move page tables to. */ - unsigned long len_in; /* Bytes to remap specified by user. */ - - bool need_rmap_locks; /* Do rmap locks need to be taken? */ - bool for_stack; /* Is this an early temp stack being moved? */ -}; - -#define PAGETABLE_MOVE(name, old_, new_, old_addr_, new_addr_, len_) \ - struct pagetable_move_control name = { \ - .old = old_, \ - .new = new_, \ - .old_addr = old_addr_, \ - .old_end = (old_addr_) + (len_), \ - .new_addr = new_addr_, \ - .len_in = len_, \ - } - -static inline void vma_iter_invalidate(struct vma_iterator *vmi) -{ - mas_pause(&vmi->mas); -} - -static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot) -{ - return __pgprot(pgprot_val(oldprot) | pgprot_val(newprot)); -} - -static inline pgprot_t vm_get_page_prot(vm_flags_t vm_flags) -{ - return __pgprot(vm_flags); -} - -static inline bool is_shared_maywrite(vm_flags_t vm_flags) -{ - return (vm_flags & (VM_SHARED | VM_MAYWRITE)) == - (VM_SHARED | VM_MAYWRITE); -} - -static inline bool vma_is_shared_maywrite(struct vm_area_struct *vma) -{ - return is_shared_maywrite(vma->vm_flags); -} - -static inline struct vm_area_struct *vma_next(struct vma_iterator *vmi) -{ - /* - * Uses mas_find() to get the first VMA when the iterator starts. - * Calling mas_next() could skip the first entry. - */ - return mas_find(&vmi->mas, ULONG_MAX); -} - -/* - * WARNING: to avoid racing with vma_mark_attached()/vma_mark_detached(), these - * assertions should be made either under mmap_write_lock or when the object - * has been isolated under mmap_write_lock, ensuring no competing writers. - */ -static inline void vma_assert_attached(struct vm_area_struct *vma) -{ - WARN_ON_ONCE(!refcount_read(&vma->vm_refcnt)); -} - -static inline void vma_assert_detached(struct vm_area_struct *vma) -{ - WARN_ON_ONCE(refcount_read(&vma->vm_refcnt)); -} - -static inline void vma_assert_write_locked(struct vm_area_struct *); -static inline void vma_mark_attached(struct vm_area_struct *vma) -{ - vma_assert_write_locked(vma); - vma_assert_detached(vma); - refcount_set_release(&vma->vm_refcnt, 1); -} - -static inline void vma_mark_detached(struct vm_area_struct *vma) -{ - vma_assert_write_locked(vma); - vma_assert_attached(vma); - /* We are the only writer, so no need to use vma_refcount_put(). */ - if (unlikely(!refcount_dec_and_test(&vma->vm_refcnt))) { - /* - * Reader must have temporarily raised vm_refcnt but it will - * drop it without using the vma since vma is write-locked. - */ - } -} - -extern const struct vm_operations_struct vma_dummy_vm_ops; - -extern unsigned long rlimit(unsigned int limit); - -static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm) -{ - memset(vma, 0, sizeof(*vma)); - vma->vm_mm = mm; - vma->vm_ops = &vma_dummy_vm_ops; - INIT_LIST_HEAD(&vma->anon_vma_chain); - vma->vm_lock_seq = UINT_MAX; -} - -/* - * These are defined in vma.h, but sadly vm_stat_account() is referenced by - * kernel/fork.c, so we have to these broadly available there, and temporarily - * define them here to resolve the dependency cycle. - */ - -#define is_exec_mapping(flags) \ - ((flags & (VM_EXEC | VM_WRITE | VM_STACK)) == VM_EXEC) - -#define is_stack_mapping(flags) \ - (((flags & VM_STACK) == VM_STACK) || (flags & VM_SHADOW_STACK)) - -#define is_data_mapping(flags) \ - ((flags & (VM_WRITE | VM_SHARED | VM_STACK)) == VM_WRITE) - -static inline void vm_stat_account(struct mm_struct *mm, vm_flags_t flags, - long npages) -{ - WRITE_ONCE(mm->total_vm, READ_ONCE(mm->total_vm)+npages); - - if (is_exec_mapping(flags)) - mm->exec_vm += npages; - else if (is_stack_mapping(flags)) - mm->stack_vm += npages; - else if (is_data_mapping(flags)) - mm->data_vm += npages; -} - -#undef is_exec_mapping -#undef is_stack_mapping -#undef is_data_mapping - -/* Currently stubbed but we may later wish to un-stub. */ -static inline void vm_acct_memory(long pages); -static inline void vm_unacct_memory(long pages) -{ - vm_acct_memory(-pages); -} - -static inline void mapping_allow_writable(struct address_space *mapping) -{ - atomic_inc(&mapping->i_mmap_writable); -} - -static inline void vma_set_range(struct vm_area_struct *vma, - unsigned long start, unsigned long end, - pgoff_t pgoff) -{ - vma->vm_start = start; - vma->vm_end = end; - vma->vm_pgoff = pgoff; -} - -static inline -struct vm_area_struct *vma_find(struct vma_iterator *vmi, unsigned long max) -{ - return mas_find(&vmi->mas, max - 1); -} - -static inline int vma_iter_clear_gfp(struct vma_iterator *vmi, - unsigned long start, unsigned long end, gfp_t gfp) -{ - __mas_set_range(&vmi->mas, start, end - 1); - mas_store_gfp(&vmi->mas, NULL, gfp); - if (unlikely(mas_is_err(&vmi->mas))) - return -ENOMEM; - - return 0; -} - -static inline void mmap_assert_locked(struct mm_struct *); -static inline struct vm_area_struct *find_vma_intersection(struct mm_struct *mm, - unsigned long start_addr, - unsigned long end_addr) -{ - unsigned long index = start_addr; - - mmap_assert_locked(mm); - return mt_find(&mm->mm_mt, &index, end_addr - 1); -} - -static inline -struct vm_area_struct *vma_lookup(struct mm_struct *mm, unsigned long addr) -{ - return mtree_load(&mm->mm_mt, addr); -} - -static inline struct vm_area_struct *vma_prev(struct vma_iterator *vmi) -{ - return mas_prev(&vmi->mas, 0); -} - -static inline void vma_iter_set(struct vma_iterator *vmi, unsigned long addr) -{ - mas_set(&vmi->mas, addr); -} - -static inline bool vma_is_anonymous(struct vm_area_struct *vma) -{ - return !vma->vm_ops; -} - -/* Defined in vma.h, so temporarily define here to avoid circular dependency. */ -#define vma_iter_load(vmi) \ - mas_walk(&(vmi)->mas) - -static inline struct vm_area_struct * -find_vma_prev(struct mm_struct *mm, unsigned long addr, - struct vm_area_struct **pprev) -{ - struct vm_area_struct *vma; - VMA_ITERATOR(vmi, mm, addr); - - vma = vma_iter_load(&vmi); - *pprev = vma_prev(&vmi); - if (!vma) - vma = vma_next(&vmi); - return vma; -} - -#undef vma_iter_load - -static inline void vma_iter_init(struct vma_iterator *vmi, - struct mm_struct *mm, unsigned long addr) -{ - mas_init(&vmi->mas, &mm->mm_mt, addr); -} - -/* Stubbed functions. */ - -static inline struct anon_vma_name *anon_vma_name(struct vm_area_struct *vma) -{ - return NULL; -} - -static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma, - struct vm_userfaultfd_ctx vm_ctx) -{ - return true; -} - -static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, - struct anon_vma_name *anon_name2) -{ - return true; -} - -static inline void might_sleep(void) -{ -} - -static inline unsigned long vma_pages(struct vm_area_struct *vma) -{ - return (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; -} - -static inline void fput(struct file *file) -{ -} - -static inline void mpol_put(struct mempolicy *pol) -{ -} - -static inline void lru_add_drain(void) -{ -} - -static inline void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm) -{ -} - -static inline void update_hiwater_rss(struct mm_struct *mm) -{ -} - -static inline void update_hiwater_vm(struct mm_struct *mm) -{ -} - -static inline void unmap_vmas(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *vma, unsigned long start_addr, - unsigned long end_addr, unsigned long tree_end) -{ -} - -static inline void free_pgtables(struct mmu_gather *tlb, struct ma_state *mas, - struct vm_area_struct *vma, unsigned long floor, - unsigned long ceiling, bool mm_wr_locked) -{ -} - -static inline void mapping_unmap_writable(struct address_space *mapping) -{ -} - -static inline void flush_dcache_mmap_lock(struct address_space *mapping) -{ -} - -static inline void tlb_finish_mmu(struct mmu_gather *tlb) -{ -} - -static inline struct file *get_file(struct file *f) -{ - return f; -} - -static inline int vma_dup_policy(struct vm_area_struct *src, struct vm_area_struct *dst) -{ - return 0; -} - -static inline int anon_vma_clone(struct vm_area_struct *dst, struct vm_area_struct *src, - enum vma_operation operation) -{ - /* For testing purposes. We indicate that an anon_vma has been cloned. */ - if (src->anon_vma != NULL) { - dst->anon_vma = src->anon_vma; - dst->anon_vma->was_cloned = true; - } - - return 0; -} - -static inline void vma_start_write(struct vm_area_struct *vma) -{ - /* Used to indicate to tests that a write operation has begun. */ - vma->vm_lock_seq++; -} - -static inline __must_check -int vma_start_write_killable(struct vm_area_struct *vma) -{ - /* Used to indicate to tests that a write operation has begun. */ - vma->vm_lock_seq++; - return 0; -} - -static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, - unsigned long start, - unsigned long end, - struct vm_area_struct *next) -{ -} - -static inline void hugetlb_split(struct vm_area_struct *, unsigned long) {} - -static inline void vma_iter_free(struct vma_iterator *vmi) -{ - mas_destroy(&vmi->mas); -} - -static inline -struct vm_area_struct *vma_iter_next_range(struct vma_iterator *vmi) -{ - return mas_next_range(&vmi->mas, ULONG_MAX); -} - -static inline void vm_acct_memory(long pages) -{ -} - -static inline void vma_interval_tree_insert(struct vm_area_struct *vma, - struct rb_root_cached *rb) -{ -} - -static inline void vma_interval_tree_remove(struct vm_area_struct *vma, - struct rb_root_cached *rb) -{ -} - -static inline void flush_dcache_mmap_unlock(struct address_space *mapping) -{ -} - -static inline void anon_vma_interval_tree_insert(struct anon_vma_chain *avc, - struct rb_root_cached *rb) -{ -} - -static inline void anon_vma_interval_tree_remove(struct anon_vma_chain *avc, - struct rb_root_cached *rb) -{ -} - -static inline void uprobe_mmap(struct vm_area_struct *vma) -{ -} - -static inline void uprobe_munmap(struct vm_area_struct *vma, - unsigned long start, unsigned long end) -{ -} - -static inline void i_mmap_lock_write(struct address_space *mapping) -{ -} - -static inline void anon_vma_lock_write(struct anon_vma *anon_vma) -{ -} - -static inline void vma_assert_write_locked(struct vm_area_struct *vma) -{ -} - -static inline void unlink_anon_vmas(struct vm_area_struct *vma) -{ - /* For testing purposes, indicate that the anon_vma was unlinked. */ - vma->anon_vma->was_unlinked = true; -} - -static inline void anon_vma_unlock_write(struct anon_vma *anon_vma) -{ -} - -static inline void i_mmap_unlock_write(struct address_space *mapping) -{ -} - -static inline int userfaultfd_unmap_prep(struct vm_area_struct *vma, - unsigned long start, - unsigned long end, - struct list_head *unmaps) -{ - return 0; -} - -static inline void mmap_write_downgrade(struct mm_struct *mm) -{ -} - -static inline void mmap_read_unlock(struct mm_struct *mm) -{ -} - -static inline void mmap_write_unlock(struct mm_struct *mm) -{ -} - -static inline int mmap_write_lock_killable(struct mm_struct *mm) -{ - return 0; -} - -static inline bool can_modify_mm(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ - return true; -} - -static inline void arch_unmap(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ -} - -static inline void mmap_assert_locked(struct mm_struct *mm) -{ -} - -static inline bool mpol_equal(struct mempolicy *a, struct mempolicy *b) -{ - return true; -} - -static inline void khugepaged_enter_vma(struct vm_area_struct *vma, - vm_flags_t vm_flags) -{ -} - -static inline bool mapping_can_writeback(struct address_space *mapping) -{ - return true; -} - -static inline bool is_vm_hugetlb_page(struct vm_area_struct *vma) -{ - return false; -} - -static inline bool vma_soft_dirty_enabled(struct vm_area_struct *vma) -{ - return false; -} - -static inline bool userfaultfd_wp(struct vm_area_struct *vma) -{ - return false; -} - -static inline void mmap_assert_write_locked(struct mm_struct *mm) -{ -} - -static inline void mutex_lock(struct mutex *lock) -{ -} - -static inline void mutex_unlock(struct mutex *lock) -{ -} - -static inline bool mutex_is_locked(struct mutex *lock) -{ - return true; -} - -static inline bool signal_pending(void *p) -{ - return false; -} - -static inline bool is_file_hugepages(struct file *file) -{ - return false; -} - -static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) -{ - return 0; -} - -static inline bool may_expand_vm(struct mm_struct *mm, vm_flags_t flags, - unsigned long npages) -{ - return true; -} - -static inline int shmem_zero_setup(struct vm_area_struct *vma) -{ - return 0; -} - -static inline void vma_set_anonymous(struct vm_area_struct *vma) -{ - vma->vm_ops = NULL; -} - -static inline void ksm_add_vma(struct vm_area_struct *vma) -{ -} - -static inline void perf_event_mmap(struct vm_area_struct *vma) -{ -} - -static inline bool vma_is_dax(struct vm_area_struct *vma) -{ - return false; -} - -static inline struct vm_area_struct *get_gate_vma(struct mm_struct *mm) -{ - return NULL; -} - -bool vma_wants_writenotify(struct vm_area_struct *vma, pgprot_t vm_page_prot); - -/* Update vma->vm_page_prot to reflect vma->vm_flags. */ -static inline void vma_set_page_prot(struct vm_area_struct *vma) -{ - vm_flags_t vm_flags = vma->vm_flags; - pgprot_t vm_page_prot; - - /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */ - vm_page_prot = pgprot_modify(vma->vm_page_prot, vm_get_page_prot(vm_flags)); - - if (vma_wants_writenotify(vma, vm_page_prot)) { - vm_flags &= ~VM_SHARED; - /* testing: we inline vm_pgprot_modify() to avoid clash with vma.h. */ - vm_page_prot = pgprot_modify(vm_page_prot, vm_get_page_prot(vm_flags)); - } - /* remove_protection_ptes reads vma->vm_page_prot without mmap_lock */ - WRITE_ONCE(vma->vm_page_prot, vm_page_prot); -} - -static inline bool arch_validate_flags(vm_flags_t flags) -{ - return true; -} - -static inline void vma_close(struct vm_area_struct *vma) -{ -} - -static inline int mmap_file(struct file *file, struct vm_area_struct *vma) -{ - return 0; -} - -static inline unsigned long stack_guard_start_gap(struct vm_area_struct *vma) -{ - if (vma->vm_flags & VM_GROWSDOWN) - return stack_guard_gap; - - /* See reasoning around the VM_SHADOW_STACK definition */ - if (vma->vm_flags & VM_SHADOW_STACK) - return PAGE_SIZE; - - return 0; -} - -static inline unsigned long vm_start_gap(struct vm_area_struct *vma) -{ - unsigned long gap = stack_guard_start_gap(vma); - unsigned long vm_start = vma->vm_start; - - vm_start -= gap; - if (vm_start > vma->vm_start) - vm_start = 0; - return vm_start; -} - -static inline unsigned long vm_end_gap(struct vm_area_struct *vma) -{ - unsigned long vm_end = vma->vm_end; - - if (vma->vm_flags & VM_GROWSUP) { - vm_end += stack_guard_gap; - if (vm_end < vma->vm_end) - vm_end = -PAGE_SIZE; - } - return vm_end; -} - -static inline int is_hugepage_only_range(struct mm_struct *mm, - unsigned long addr, unsigned long len) -{ - return 0; -} - -static inline bool vma_is_accessible(struct vm_area_struct *vma) -{ - return vma->vm_flags & VM_ACCESS_FLAGS; -} - -static inline bool capable(int cap) -{ - return true; -} - -static inline bool mlock_future_ok(const struct mm_struct *mm, - vm_flags_t vm_flags, unsigned long bytes) -{ - unsigned long locked_pages, limit_pages; - - if (!(vm_flags & VM_LOCKED) || capable(CAP_IPC_LOCK)) - return true; - - locked_pages = bytes >> PAGE_SHIFT; - locked_pages += mm->locked_vm; - - limit_pages = rlimit(RLIMIT_MEMLOCK); - limit_pages >>= PAGE_SHIFT; - - return locked_pages <= limit_pages; -} - -static inline int __anon_vma_prepare(struct vm_area_struct *vma) -{ - struct anon_vma *anon_vma = calloc(1, sizeof(struct anon_vma)); - - if (!anon_vma) - return -ENOMEM; - - anon_vma->root = anon_vma; - vma->anon_vma = anon_vma; - - return 0; -} - -static inline int anon_vma_prepare(struct vm_area_struct *vma) -{ - if (likely(vma->anon_vma)) - return 0; - - return __anon_vma_prepare(vma); -} - -static inline void userfaultfd_unmap_complete(struct mm_struct *mm, - struct list_head *uf) -{ -} - -#define ACCESS_PRIVATE(p, member) ((p)->member) - -#define bitmap_size(nbits) (ALIGN(nbits, BITS_PER_LONG) / BITS_PER_BYTE) - -static __always_inline void bitmap_zero(unsigned long *dst, unsigned int nbits) -{ - unsigned int len = bitmap_size(nbits); - - if (small_const_nbits(nbits)) - *dst = 0; - else - memset(dst, 0, len); -} - -static inline bool mm_flags_test(int flag, const struct mm_struct *mm) -{ - return test_bit(flag, ACCESS_PRIVATE(&mm->flags, __mm_flags)); -} - -/* Clears all bits in the VMA flags bitmap, non-atomically. */ -static inline void vma_flags_clear_all(vma_flags_t *flags) -{ - bitmap_zero(ACCESS_PRIVATE(flags, __vma_flags), NUM_VMA_FLAG_BITS); -} - -/* - * Copy value to the first system word of VMA flags, non-atomically. - * - * IMPORTANT: This does not overwrite bytes past the first system word. The - * caller must account for this. - */ -static inline void vma_flags_overwrite_word(vma_flags_t *flags, unsigned long value) -{ - *ACCESS_PRIVATE(flags, __vma_flags) = value; -} - -/* - * Copy value to the first system word of VMA flags ONCE, non-atomically. - * - * IMPORTANT: This does not overwrite bytes past the first system word. The - * caller must account for this. - */ -static inline void vma_flags_overwrite_word_once(vma_flags_t *flags, unsigned long value) -{ - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); - - WRITE_ONCE(*bitmap, value); -} - -/* Update the first system word of VMA flags setting bits, non-atomically. */ -static inline void vma_flags_set_word(vma_flags_t *flags, unsigned long value) -{ - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); - - *bitmap |= value; -} - -/* Update the first system word of VMA flags clearing bits, non-atomically. */ -static inline void vma_flags_clear_word(vma_flags_t *flags, unsigned long value) -{ - unsigned long *bitmap = ACCESS_PRIVATE(flags, __vma_flags); - - *bitmap &= ~value; -} - - -/* Use when VMA is not part of the VMA tree and needs no locking */ -static inline void vm_flags_init(struct vm_area_struct *vma, - vm_flags_t flags) -{ - vma_flags_clear_all(&vma->flags); - vma_flags_overwrite_word(&vma->flags, flags); -} - -/* - * Use when VMA is part of the VMA tree and modifications need coordination - * Note: vm_flags_reset and vm_flags_reset_once do not lock the vma and - * it should be locked explicitly beforehand. - */ -static inline void vm_flags_reset(struct vm_area_struct *vma, - vm_flags_t flags) -{ - vma_assert_write_locked(vma); - vm_flags_init(vma, flags); -} - -static inline void vm_flags_reset_once(struct vm_area_struct *vma, - vm_flags_t flags) -{ - vma_assert_write_locked(vma); - /* - * The user should only be interested in avoiding reordering of - * assignment to the first word. - */ - vma_flags_clear_all(&vma->flags); - vma_flags_overwrite_word_once(&vma->flags, flags); -} - -static inline void vm_flags_set(struct vm_area_struct *vma, - vm_flags_t flags) -{ - vma_start_write(vma); - vma_flags_set_word(&vma->flags, flags); -} - -static inline void vm_flags_clear(struct vm_area_struct *vma, - vm_flags_t flags) -{ - vma_start_write(vma); - vma_flags_clear_word(&vma->flags, flags); -} - -/* - * Denies creating a writable executable mapping or gaining executable permissions. - * - * This denies the following: - * - * a) mmap(PROT_WRITE | PROT_EXEC) - * - * b) mmap(PROT_WRITE) - * mprotect(PROT_EXEC) - * - * c) mmap(PROT_WRITE) - * mprotect(PROT_READ) - * mprotect(PROT_EXEC) - * - * But allows the following: - * - * d) mmap(PROT_READ | PROT_EXEC) - * mmap(PROT_READ | PROT_EXEC | PROT_BTI) - * - * This is only applicable if the user has set the Memory-Deny-Write-Execute - * (MDWE) protection mask for the current process. - * - * @old specifies the VMA flags the VMA originally possessed, and @new the ones - * we propose to set. - * - * Return: false if proposed change is OK, true if not ok and should be denied. - */ -static inline bool map_deny_write_exec(unsigned long old, unsigned long new) -{ - /* If MDWE is disabled, we have nothing to deny. */ - if (mm_flags_test(MMF_HAS_MDWE, current->mm)) - return false; - - /* If the new VMA is not executable, we have nothing to deny. */ - if (!(new & VM_EXEC)) - return false; - - /* Under MDWE we do not accept newly writably executable VMAs... */ - if (new & VM_WRITE) - return true; - - /* ...nor previously non-executable VMAs becoming executable. */ - if (!(old & VM_EXEC)) - return true; - - return false; -} - -static inline int mapping_map_writable(struct address_space *mapping) -{ - return atomic_inc_unless_negative(&mapping->i_mmap_writable) ? - 0 : -EPERM; -} - -static inline unsigned long move_page_tables(struct pagetable_move_control *pmc) -{ - return 0; -} - -static inline void free_pgd_range(struct mmu_gather *tlb, - unsigned long addr, unsigned long end, - unsigned long floor, unsigned long ceiling) -{ -} - -static inline int ksm_execve(struct mm_struct *mm) -{ - return 0; -} - -static inline void ksm_exit(struct mm_struct *mm) -{ -} - -static inline void vma_lock_init(struct vm_area_struct *vma, bool reset_refcnt) -{ - if (reset_refcnt) - refcount_set(&vma->vm_refcnt, 0); -} - -static inline void vma_numab_state_init(struct vm_area_struct *vma) -{ -} - -static inline void vma_numab_state_free(struct vm_area_struct *vma) -{ -} - -static inline void dup_anon_vma_name(struct vm_area_struct *orig_vma, - struct vm_area_struct *new_vma) -{ -} - -static inline void free_anon_vma_name(struct vm_area_struct *vma) -{ -} - -/* Declared in vma.h. */ -static inline void set_vma_from_desc(struct vm_area_struct *vma, - struct vm_area_desc *desc); - -static inline void mmap_action_prepare(struct mmap_action *action, - struct vm_area_desc *desc) -{ -} - -static inline int mmap_action_complete(struct mmap_action *action, - struct vm_area_struct *vma) -{ - return 0; -} - -static inline int __compat_vma_mmap(const struct file_operations *f_op, - struct file *file, struct vm_area_struct *vma) -{ - struct vm_area_desc desc = { - .mm = vma->vm_mm, - .file = file, - .start = vma->vm_start, - .end = vma->vm_end, - - .pgoff = vma->vm_pgoff, - .vm_file = vma->vm_file, - .vm_flags = vma->vm_flags, - .page_prot = vma->vm_page_prot, - - .action.type = MMAP_NOTHING, /* Default */ - }; - int err; - - err = f_op->mmap_prepare(&desc); - if (err) - return err; - - mmap_action_prepare(&desc.action, &desc); - set_vma_from_desc(vma, &desc); - return mmap_action_complete(&desc.action, vma); -} - -static inline int compat_vma_mmap(struct file *file, - struct vm_area_struct *vma) -{ - return __compat_vma_mmap(file->f_op, file, vma); -} - -/* Did the driver provide valid mmap hook configuration? */ -static inline bool can_mmap_file(struct file *file) -{ - bool has_mmap = file->f_op->mmap; - bool has_mmap_prepare = file->f_op->mmap_prepare; - - /* Hooks are mutually exclusive. */ - if (WARN_ON_ONCE(has_mmap && has_mmap_prepare)) - return false; - if (!has_mmap && !has_mmap_prepare) - return false; - - return true; -} - -static inline int vfs_mmap(struct file *file, struct vm_area_struct *vma) -{ - if (file->f_op->mmap_prepare) - return compat_vma_mmap(file, vma); - - return file->f_op->mmap(file, vma); -} - -static inline int vfs_mmap_prepare(struct file *file, struct vm_area_desc *desc) -{ - return file->f_op->mmap_prepare(desc); -} - -static inline void fixup_hugetlb_reservations(struct vm_area_struct *vma) -{ -} - -static inline void vma_set_file(struct vm_area_struct *vma, struct file *file) -{ - /* Changing an anonymous vma with this is illegal */ - get_file(file); - swap(vma->vm_file, file); - fput(file); -} - -static inline bool shmem_file(struct file *file) -{ - return false; -} - -static inline vm_flags_t ksm_vma_flags(const struct mm_struct *mm, - const struct file *file, vm_flags_t vm_flags) -{ - return vm_flags; -} - -static inline void remap_pfn_range_prepare(struct vm_area_desc *desc, unsigned long pfn) -{ -} - -static inline int remap_pfn_range_complete(struct vm_area_struct *vma, unsigned long addr, - unsigned long pfn, unsigned long size, pgprot_t pgprot) -{ - return 0; -} - -static inline int do_munmap(struct mm_struct *, unsigned long, size_t, - struct list_head *uf) -{ - return 0; -} +typedef unsigned long vm_flags_t; +#define pgoff_t unsigned long +typedef unsigned long pgprotval_t; +typedef struct pgprot { pgprotval_t pgprot; } pgprot_t; +typedef __bitwise unsigned int vm_fault_t; + +#include "include/stubs.h" +#include "include/dup.h" +#include "include/custom.h" #endif /* __MM_VMA_INTERNAL_H */ diff --git a/tools/usb/usbip/README b/tools/usb/usbip/README index 2fc021c0eae1..11971538f03e 100644 --- a/tools/usb/usbip/README +++ b/tools/usb/usbip/README @@ -241,8 +241,6 @@ Detach the imported device: [Checklist] - - See 'Debug Tips' on the project wiki. - - http://usbip.wiki.sourceforge.net/how-to-debug-usbip - usbip-host.ko must be bound to the target device. - See /sys/kernel/debug/usb/devices and find "Driver=..." lines of the device. - Target USB gadget must be bound to vudc diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig index 267c7369c765..794976b88c6f 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -5,6 +5,7 @@ config KVM_COMMON bool select EVENTFD select INTERVAL_TREE + select MMU_NOTIFIER select PREEMPT_NOTIFIERS config HAVE_KVM_PFNCACHE @@ -93,24 +94,16 @@ config HAVE_KVM_PM_NOTIFIER config KVM_GENERIC_HARDWARE_ENABLING bool -config KVM_GENERIC_MMU_NOTIFIER - select MMU_NOTIFIER - bool - config KVM_ELIDE_TLB_FLUSH_IF_YOUNG - depends on KVM_GENERIC_MMU_NOTIFIER bool config KVM_MMU_LOCKLESS_AGING - depends on KVM_GENERIC_MMU_NOTIFIER bool config KVM_GENERIC_MEMORY_ATTRIBUTES - depends on KVM_GENERIC_MMU_NOTIFIER bool config KVM_GUEST_MEMFD - depends on KVM_GENERIC_MMU_NOTIFIER select XARRAY_MULTI bool diff --git a/virt/kvm/binary_stats.c b/virt/kvm/binary_stats.c index eefca6c69f51..76ce697c773b 100644 --- a/virt/kvm/binary_stats.c +++ b/virt/kvm/binary_stats.c @@ -50,7 +50,7 @@ * Return: the number of bytes that has been successfully read */ ssize_t kvm_stats_read(char *id, const struct kvm_stats_header *header, - const struct _kvm_stats_desc *desc, + const struct kvm_stats_desc *desc, void *stats, size_t size_stats, char __user *user_buffer, size_t size, loff_t *offset) { diff --git a/virt/kvm/coalesced_mmio.c b/virt/kvm/coalesced_mmio.c index 375d6285475e..6b1d90161099 100644 --- a/virt/kvm/coalesced_mmio.c +++ b/virt/kvm/coalesced_mmio.c @@ -128,8 +128,7 @@ int kvm_vm_ioctl_register_coalesced_mmio(struct kvm *kvm, if (zone->pio != 1 && zone->pio != 0) return -EINVAL; - dev = kzalloc(sizeof(struct kvm_coalesced_mmio_dev), - GFP_KERNEL_ACCOUNT); + dev = kzalloc_obj(struct kvm_coalesced_mmio_dev, GFP_KERNEL_ACCOUNT); if (!dev) return -ENOMEM; diff --git a/virt/kvm/eventfd.c b/virt/kvm/eventfd.c index a369b20d47f0..0e8b8a2c5b79 100644 --- a/virt/kvm/eventfd.c +++ b/virt/kvm/eventfd.c @@ -382,7 +382,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) if (!kvm_arch_irqfd_allowed(kvm, args)) return -EINVAL; - irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL_ACCOUNT); + irqfd = kzalloc_obj(*irqfd, GFP_KERNEL_ACCOUNT); if (!irqfd) return -ENOMEM; @@ -430,8 +430,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args) } if (!irqfd->resampler) { - resampler = kzalloc(sizeof(*resampler), - GFP_KERNEL_ACCOUNT); + resampler = kzalloc_obj(*resampler, GFP_KERNEL_ACCOUNT); if (!resampler) { ret = -ENOMEM; mutex_unlock(&kvm->irqfds.resampler_lock); @@ -874,7 +873,7 @@ static int kvm_assign_ioeventfd_idx(struct kvm *kvm, if (IS_ERR(eventfd)) return PTR_ERR(eventfd); - p = kzalloc(sizeof(*p), GFP_KERNEL_ACCOUNT); + p = kzalloc_obj(*p, GFP_KERNEL_ACCOUNT); if (!p) { ret = -ENOMEM; goto fail; diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index 923c51a3a525..017d84a7adf3 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -568,7 +568,7 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) if (fd < 0) return fd; - f = kzalloc(sizeof(*f), GFP_KERNEL); + f = kzalloc_obj(*f); if (!f) { err = -ENOMEM; goto err_fd; diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 6ccabfd32287..462c70621247 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -183,7 +183,7 @@ int kvm_set_irq_routing(struct kvm *kvm, nr_rt_entries += 1; - new = kzalloc(struct_size(new, map, nr_rt_entries), GFP_KERNEL_ACCOUNT); + new = kzalloc_flex(*new, map, nr_rt_entries, GFP_KERNEL_ACCOUNT); if (!new) return -ENOMEM; @@ -194,7 +194,7 @@ int kvm_set_irq_routing(struct kvm *kvm, for (i = 0; i < nr; ++i) { r = -ENOMEM; - e = kzalloc(sizeof(*e), GFP_KERNEL_ACCOUNT); + e = kzalloc_obj(*e, GFP_KERNEL_ACCOUNT); if (!e) goto out; @@ -246,7 +246,7 @@ int kvm_init_irq_routing(struct kvm *kvm) struct kvm_irq_routing_table *new; int chip_size; - new = kzalloc(struct_size(new, map, 1), GFP_KERNEL_ACCOUNT); + new = kzalloc_flex(*new, map, 1, GFP_KERNEL_ACCOUNT); if (!new) return -ENOMEM; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 61dca8d37abc..9093251beb39 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -502,7 +502,6 @@ void kvm_destroy_vcpus(struct kvm *kvm) } EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_destroy_vcpus); -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER static inline struct kvm *mmu_notifier_to_kvm(struct mmu_notifier *mn) { return container_of(mn, struct kvm, mmu_notifier); @@ -901,15 +900,6 @@ static int kvm_init_mmu_notifier(struct kvm *kvm) return mmu_notifier_register(&kvm->mmu_notifier, current->mm); } -#else /* !CONFIG_KVM_GENERIC_MMU_NOTIFIER */ - -static int kvm_init_mmu_notifier(struct kvm *kvm) -{ - return 0; -} - -#endif /* CONFIG_KVM_GENERIC_MMU_NOTIFIER */ - #ifdef CONFIG_HAVE_KVM_PM_NOTIFIER static int kvm_pm_notifier_call(struct notifier_block *bl, unsigned long state, @@ -983,9 +973,9 @@ static void kvm_free_memslots(struct kvm *kvm, struct kvm_memslots *slots) kvm_free_memslot(kvm, memslot); } -static umode_t kvm_stats_debugfs_mode(const struct _kvm_stats_desc *pdesc) +static umode_t kvm_stats_debugfs_mode(const struct kvm_stats_desc *desc) { - switch (pdesc->desc.flags & KVM_STATS_TYPE_MASK) { + switch (desc->flags & KVM_STATS_TYPE_MASK) { case KVM_STATS_TYPE_INSTANT: return 0444; case KVM_STATS_TYPE_CUMULATIVE: @@ -1020,7 +1010,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, const char *fdname) struct dentry *dent; char dir_name[ITOA_MAX_LEN * 2]; struct kvm_stat_data *stat_data; - const struct _kvm_stats_desc *pdesc; + const struct kvm_stats_desc *pdesc; int i, ret = -ENOMEM; int kvm_debugfs_num_entries = kvm_vm_stats_header.num_desc + kvm_vcpu_stats_header.num_desc; @@ -1043,15 +1033,15 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, const char *fdname) return 0; kvm->debugfs_dentry = dent; - kvm->debugfs_stat_data = kcalloc(kvm_debugfs_num_entries, - sizeof(*kvm->debugfs_stat_data), - GFP_KERNEL_ACCOUNT); + kvm->debugfs_stat_data = kzalloc_objs(*kvm->debugfs_stat_data, + kvm_debugfs_num_entries, + GFP_KERNEL_ACCOUNT); if (!kvm->debugfs_stat_data) goto out_err; for (i = 0; i < kvm_vm_stats_header.num_desc; ++i) { pdesc = &kvm_vm_stats_desc[i]; - stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL_ACCOUNT); + stat_data = kzalloc_obj(*stat_data, GFP_KERNEL_ACCOUNT); if (!stat_data) goto out_err; @@ -1066,7 +1056,7 @@ static int kvm_create_vm_debugfs(struct kvm *kvm, const char *fdname) for (i = 0; i < kvm_vcpu_stats_header.num_desc; ++i) { pdesc = &kvm_vcpu_stats_desc[i]; - stat_data = kzalloc(sizeof(*stat_data), GFP_KERNEL_ACCOUNT); + stat_data = kzalloc_obj(*stat_data, GFP_KERNEL_ACCOUNT); if (!stat_data) goto out_err; @@ -1185,7 +1175,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) r = -ENOMEM; for (i = 0; i < KVM_NR_BUSES; i++) { rcu_assign_pointer(kvm->buses[i], - kzalloc(sizeof(struct kvm_io_bus), GFP_KERNEL_ACCOUNT)); + kzalloc_obj(struct kvm_io_bus, GFP_KERNEL_ACCOUNT)); if (!kvm->buses[i]) goto out_err_no_arch_destroy_vm; } @@ -1226,10 +1216,8 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname) out_err_no_debugfs: kvm_coalesced_mmio_free(kvm); out_no_coalesced_mmio: -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER if (kvm->mmu_notifier.ops) mmu_notifier_unregister(&kvm->mmu_notifier, current->mm); -#endif out_err_no_mmu_notifier: kvm_disable_virtualization(); out_err_no_disable: @@ -1292,7 +1280,6 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm->buses[i] = NULL; } kvm_coalesced_mmio_free(kvm); -#ifdef CONFIG_KVM_GENERIC_MMU_NOTIFIER mmu_notifier_unregister(&kvm->mmu_notifier, kvm->mm); /* * At this point, pending calls to invalidate_range_start() @@ -1311,9 +1298,6 @@ static void kvm_destroy_vm(struct kvm *kvm) kvm->mn_active_invalidate_count = 0; else WARN_ON(kvm->mmu_invalidate_in_progress); -#else - kvm_flush_shadow_all(kvm); -#endif kvm_arch_destroy_vm(kvm); kvm_destroy_devices(kvm); for (i = 0; i < kvm_arch_nr_memslot_as_ids(kvm); i++) { @@ -1944,7 +1928,7 @@ static int kvm_set_memslot(struct kvm *kvm, * invalidation needs to be reverted. */ if (change == KVM_MR_DELETE || change == KVM_MR_MOVE) { - invalid_slot = kzalloc(sizeof(*invalid_slot), GFP_KERNEL_ACCOUNT); + invalid_slot = kzalloc_obj(*invalid_slot, GFP_KERNEL_ACCOUNT); if (!invalid_slot) { mutex_unlock(&kvm->slots_arch_lock); return -ENOMEM; @@ -2117,7 +2101,7 @@ static int kvm_set_memory_region(struct kvm *kvm, return -EEXIST; /* Allocate a slot that will persist in the memslot. */ - new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); + new = kzalloc_obj(*new, GFP_KERNEL_ACCOUNT); if (!new) return -ENOMEM; @@ -4505,7 +4489,7 @@ static long kvm_vcpu_ioctl(struct file *filp, struct kvm_regs *kvm_regs; r = -ENOMEM; - kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); + kvm_regs = kzalloc_obj(struct kvm_regs); if (!kvm_regs) goto out; r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs); @@ -4532,7 +4516,7 @@ static long kvm_vcpu_ioctl(struct file *filp, break; } case KVM_GET_SREGS: { - kvm_sregs = kzalloc(sizeof(struct kvm_sregs), GFP_KERNEL); + kvm_sregs = kzalloc_obj(struct kvm_sregs); r = -ENOMEM; if (!kvm_sregs) goto out; @@ -4624,7 +4608,7 @@ static long kvm_vcpu_ioctl(struct file *filp, break; } case KVM_GET_FPU: { - fpu = kzalloc(sizeof(struct kvm_fpu), GFP_KERNEL); + fpu = kzalloc_obj(struct kvm_fpu); r = -ENOMEM; if (!fpu) goto out; @@ -4844,7 +4828,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, if (test) return 0; - dev = kzalloc(sizeof(*dev), GFP_KERNEL_ACCOUNT); + dev = kzalloc_obj(*dev, GFP_KERNEL_ACCOUNT); if (!dev) return -ENOMEM; @@ -4886,6 +4870,7 @@ static int kvm_ioctl_create_device(struct kvm *kvm, static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) { switch (arg) { + case KVM_CAP_SYNC_MMU: case KVM_CAP_USER_MEMORY: case KVM_CAP_USER_MEMORY2: case KVM_CAP_DESTROY_MEMORY_REGION_WORKS: @@ -6006,8 +5991,8 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr, if (bus->dev_count - bus->ioeventfd_count > NR_IOBUS_DEVS - 1) return -ENOSPC; - new_bus = kmalloc(struct_size(bus, range, bus->dev_count + 1), - GFP_KERNEL_ACCOUNT); + new_bus = kmalloc_flex(*bus, range, bus->dev_count + 1, + GFP_KERNEL_ACCOUNT); if (!new_bus) return -ENOMEM; @@ -6053,8 +6038,8 @@ int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, if (i == bus->dev_count) return 0; - new_bus = kmalloc(struct_size(bus, range, bus->dev_count - 1), - GFP_KERNEL_ACCOUNT); + new_bus = kmalloc_flex(*bus, range, bus->dev_count - 1, + GFP_KERNEL_ACCOUNT); if (new_bus) { memcpy(new_bus, bus, struct_size(bus, range, i)); new_bus->dev_count--; @@ -6186,11 +6171,11 @@ static int kvm_stat_data_get(void *data, u64 *val) switch (stat_data->kind) { case KVM_STAT_VM: r = kvm_get_stat_per_vm(stat_data->kvm, - stat_data->desc->desc.offset, val); + stat_data->desc->offset, val); break; case KVM_STAT_VCPU: r = kvm_get_stat_per_vcpu(stat_data->kvm, - stat_data->desc->desc.offset, val); + stat_data->desc->offset, val); break; } @@ -6208,11 +6193,11 @@ static int kvm_stat_data_clear(void *data, u64 val) switch (stat_data->kind) { case KVM_STAT_VM: r = kvm_clear_stat_per_vm(stat_data->kvm, - stat_data->desc->desc.offset); + stat_data->desc->offset); break; case KVM_STAT_VCPU: r = kvm_clear_stat_per_vcpu(stat_data->kvm, - stat_data->desc->desc.offset); + stat_data->desc->offset); break; } @@ -6326,7 +6311,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) active = kvm_active_vms; mutex_unlock(&kvm_lock); - env = kzalloc(sizeof(*env), GFP_KERNEL); + env = kzalloc_obj(*env); if (!env) return; @@ -6360,7 +6345,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) static void kvm_init_debug(void) { const struct file_operations *fops; - const struct _kvm_stats_desc *pdesc; + const struct kvm_stats_desc *pdesc; int i; kvm_debugfs_dir = debugfs_create_dir("kvm", NULL); @@ -6373,7 +6358,7 @@ static void kvm_init_debug(void) fops = &vm_stat_readonly_fops; debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc), kvm_debugfs_dir, - (void *)(long)pdesc->desc.offset, fops); + (void *)(long)pdesc->offset, fops); } for (i = 0; i < kvm_vcpu_stats_header.num_desc; ++i) { @@ -6384,7 +6369,7 @@ static void kvm_init_debug(void) fops = &vcpu_stat_readonly_fops; debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc), kvm_debugfs_dir, - (void *)(long)pdesc->desc.offset, fops); + (void *)(long)pdesc->offset, fops); } } diff --git a/virt/kvm/vfio.c b/virt/kvm/vfio.c index be50514bbd11..9f9acb66cc1e 100644 --- a/virt/kvm/vfio.c +++ b/virt/kvm/vfio.c @@ -166,7 +166,7 @@ static int kvm_vfio_file_add(struct kvm_device *dev, unsigned int fd) } } - kvf = kzalloc(sizeof(*kvf), GFP_KERNEL_ACCOUNT); + kvf = kzalloc_obj(*kvf, GFP_KERNEL_ACCOUNT); if (!kvf) { ret = -ENOMEM; goto out_unlock; @@ -364,7 +364,7 @@ static int kvm_vfio_create(struct kvm_device *dev, u32 type) if (tmp->ops == &kvm_vfio_ops) return -EBUSY; - kv = kzalloc(sizeof(*kv), GFP_KERNEL_ACCOUNT); + kv = kzalloc_obj(*kv, GFP_KERNEL_ACCOUNT); if (!kv) return -ENOMEM;